From 433d32f237cf09b47f05d0c92ec361a41b38412e Mon Sep 17 00:00:00 2001 From: Jeff Hutchinson Date: Wed, 15 Sep 2021 00:02:50 -0400 Subject: [PATCH 001/145] Implement better CPU Detection --- Engine/source/platform/platform.h | 47 +--- Engine/source/platform/platformCPU.cpp | 277 ++++----------------- Engine/source/platformWin32/winCPUInfo.cpp | 38 ++- 3 files changed, 88 insertions(+), 274 deletions(-) diff --git a/Engine/source/platform/platform.h b/Engine/source/platform/platform.h index 7158c5163..35cd1a687 100644 --- a/Engine/source/platform/platform.h +++ b/Engine/source/platform/platform.h @@ -55,50 +55,11 @@ /// @note These enums must be globally scoped so that they work with the inline assembly enum ProcessorType { - // x86 CPU_X86Compatible, - CPU_Intel_Unknown, - CPU_Intel_486, - CPU_Intel_Pentium, - CPU_Intel_PentiumMMX, - CPU_Intel_PentiumPro, - CPU_Intel_PentiumII, - CPU_Intel_PentiumCeleron, - CPU_Intel_PentiumIII, - CPU_Intel_Pentium4, - CPU_Intel_PentiumM, - CPU_Intel_Core, - CPU_Intel_Core2, - CPU_Intel_Corei7Xeon, // Core i7 or Xeon - CPU_AMD_K6, - CPU_AMD_K6_2, - CPU_AMD_K6_3, - CPU_AMD_Athlon, - CPU_AMD_Phenom, - CPU_AMD_PhenomII, - CPU_AMD_Bulldozer, - CPU_AMD_Unknown, - CPU_Cyrix_6x86, - CPU_Cyrix_MediaGX, - CPU_Cyrix_6x86MX, - CPU_Cyrix_GXm, ///< Media GX w/ MMX - CPU_Cyrix_Unknown, - - // PowerPC - CPU_PowerPC_Unknown, - CPU_PowerPC_601, - CPU_PowerPC_603, - CPU_PowerPC_603e, - CPU_PowerPC_603ev, - CPU_PowerPC_604, - CPU_PowerPC_604e, - CPU_PowerPC_604ev, - CPU_PowerPC_G3, - CPU_PowerPC_G4, - CPU_PowerPC_G4_7450, - CPU_PowerPC_G4_7455, - CPU_PowerPC_G4_7447, - CPU_PowerPC_G5, + CPU_ArmCompatible, + CPU_Intel, + CPU_AMD, + CPU_Apple }; /// Properties for CPU. diff --git a/Engine/source/platform/platformCPU.cpp b/Engine/source/platform/platformCPU.cpp index 4eaa33b8d..d0a852431 100644 --- a/Engine/source/platform/platformCPU.cpp +++ b/Engine/source/platform/platformCPU.cpp @@ -31,12 +31,11 @@ Signal Platform::SystemInfoReady; enum CPUFlags { // EDX Register flags - BIT_FPU = BIT(0), BIT_RDTSC = BIT(4), BIT_MMX = BIT(23), BIT_SSE = BIT(25), BIT_SSE2 = BIT(26), - BIT_3DNOW = BIT(31), + BIT_3DNOW = BIT(31), // only available for amd cpus in x86 // These use a different value for comparison than the above flags (ECX Register) BIT_SSE3 = BIT(0), @@ -47,241 +46,63 @@ enum CPUFlags // fill the specified structure with information obtained from asm code void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo, - char* vendor, U32 processor, U32 properties, U32 properties2) + char* vendor, char* brand, U32 processor, U32 properties, U32 properties2) { - Platform::SystemInfo.processor.properties |= (properties & BIT_FPU) ? CPU_PROP_FPU : 0; - Platform::SystemInfo.processor.properties |= (properties & BIT_RDTSC) ? CPU_PROP_RDTSC : 0; - Platform::SystemInfo.processor.properties |= (properties & BIT_MMX) ? CPU_PROP_MMX : 0; + // always assume FPU is available in 2021... + pInfo.properties |= CPU_PROP_FPU; + +#if defined(TORQUE_CPU_X86) || defined(TORQUE_CPU_X64) || defined(TORQUE_CPU_ARM64) + pInfo.properties |= CPU_PROP_LE; +#endif + +#if defined(TORQUE_CPU_X64) || defined(TORQUE_CPU_ARM64) + pInfo.properties |= CPU_PROP_64bit; +#endif + +#if defined(TORQUE_CPU_X86) || defined(TORQUE_CPU_X64) + pInfo.properties |= (properties & BIT_RDTSC) ? CPU_PROP_RDTSC : 0; + pInfo.properties |= (properties & BIT_MMX) ? CPU_PROP_MMX : 0; + pInfo.properties |= (properties & BIT_SSE) ? CPU_PROP_SSE : 0; + pInfo.properties |= (properties & BIT_SSE2) ? CPU_PROP_SSE2 : 0; + pInfo.properties |= (properties2 & BIT_SSE3) ? CPU_PROP_SSE3 : 0; + pInfo.properties |= (properties2 & BIT_SSE3xt) ? CPU_PROP_SSE3xt : 0; + pInfo.properties |= (properties2 & BIT_SSE4_1) ? CPU_PROP_SSE4_1 : 0; + pInfo.properties |= (properties2 & BIT_SSE4_2) ? CPU_PROP_SSE4_2 : 0; +#endif if (dStricmp(vendor, "GenuineIntel") == 0) { - pInfo.properties |= (properties & BIT_SSE) ? CPU_PROP_SSE : 0; - pInfo.properties |= (properties & BIT_SSE2) ? CPU_PROP_SSE2 : 0; - pInfo.properties |= (properties2 & BIT_SSE3) ? CPU_PROP_SSE3 : 0; - pInfo.properties |= (properties2 & BIT_SSE3xt) ? CPU_PROP_SSE3xt : 0; - pInfo.properties |= (properties2 & BIT_SSE4_1) ? CPU_PROP_SSE4_1 : 0; - pInfo.properties |= (properties2 & BIT_SSE4_2) ? CPU_PROP_SSE4_2 : 0; - - pInfo.type = CPU_Intel_Unknown; - // switch on processor family code - switch ((processor >> 8) & 0x0f) - { - case 4: - pInfo.type = CPU_Intel_486; - pInfo.name = StringTable->insert("Intel 486 class"); - break; - - // Pentium Family - case 5: - // switch on processor model code - switch ((processor >> 4) & 0xf) - { - case 1: - case 2: - case 3: - pInfo.type = CPU_Intel_Pentium; - pInfo.name = StringTable->insert("Intel Pentium"); - break; - case 4: - pInfo.type = CPU_Intel_PentiumMMX; - pInfo.name = StringTable->insert("Intel Pentium MMX"); - break; - default: - pInfo.type = CPU_Intel_Pentium; - pInfo.name = StringTable->insert( "Intel (unknown)" ); - break; - } - break; - - // Pentium Pro/II/II family - case 6: - { - U32 extendedModel = ( processor & 0xf0000 ) >> 16; - // switch on processor model code - switch ((processor >> 4) & 0xf) - { - case 1: - pInfo.type = CPU_Intel_PentiumPro; - pInfo.name = StringTable->insert("Intel Pentium Pro"); - break; - case 3: - case 5: - pInfo.type = CPU_Intel_PentiumII; - pInfo.name = StringTable->insert("Intel Pentium II"); - break; - case 6: - pInfo.type = CPU_Intel_PentiumCeleron; - pInfo.name = StringTable->insert("Intel Pentium Celeron"); - break; - case 7: - case 8: - case 11: - pInfo.type = CPU_Intel_PentiumIII; - pInfo.name = StringTable->insert("Intel Pentium III"); - break; - case 0xA: - if( extendedModel == 1) - { - pInfo.type = CPU_Intel_Corei7Xeon; - pInfo.name = StringTable->insert( "Intel Core i7 / Xeon" ); - } - else - { - pInfo.type = CPU_Intel_PentiumIII; - pInfo.name = StringTable->insert( "Intel Pentium III Xeon" ); - } - break; - case 0xD: - if( extendedModel == 1 ) - { - pInfo.type = CPU_Intel_Corei7Xeon; - pInfo.name = StringTable->insert( "Intel Core i7 / Xeon" ); - } - else - { - pInfo.type = CPU_Intel_PentiumM; - pInfo.name = StringTable->insert( "Intel Pentium/Celeron M" ); - } - break; - case 0xE: - pInfo.type = CPU_Intel_Core; - pInfo.name = StringTable->insert( "Intel Core" ); - break; - case 0xF: - pInfo.type = CPU_Intel_Core2; - pInfo.name = StringTable->insert( "Intel Core 2" ); - break; - default: - pInfo.type = CPU_Intel_PentiumPro; - pInfo.name = StringTable->insert( "Intel (unknown)" ); - break; - } - break; - } - - // Pentium4 Family - case 0xf: - pInfo.type = CPU_Intel_Pentium4; - pInfo.name = StringTable->insert( "Intel Pentium 4" ); - break; - - default: - pInfo.type = CPU_Intel_Unknown; - pInfo.name = StringTable->insert( "Intel (unknown)" ); - break; - } + pInfo.type = CPU_Intel; + pInfo.name = StringTable->insert(brand ? brand : "Intel (Unknown)"); } //-------------------------------------- + else if (dStricmp(vendor, "AuthenticAMD") == 0) + { + pInfo.name = StringTable->insert(brand ? brand : "AMD (unknown)"); + pInfo.type = CPU_AMD; + + // 3dnow! is only available in AMD cpus on x86. Otherwise its not reliably set. + pInfo.properties |= (properties & BIT_3DNOW) ? CPU_PROP_3DNOW : 0; + } + else if (dStricmp(vendor, "Apple") == 0) + { + pInfo.name = StringTable->insert(brand ? brand : "Apple (unknown)"); + pInfo.type = CPU_Apple; + } else - if (dStricmp(vendor, "AuthenticAMD") == 0) - { - // AthlonXP processors support SSE - pInfo.properties |= (properties & BIT_SSE) ? CPU_PROP_SSE : 0; - pInfo.properties |= ( properties & BIT_SSE2 ) ? CPU_PROP_SSE2 : 0; - pInfo.properties |= (properties & BIT_3DNOW) ? CPU_PROP_3DNOW : 0; - // Phenom and PhenomII support SSE3, SSE4a - pInfo.properties |= ( properties2 & BIT_SSE3 ) ? CPU_PROP_SSE3 : 0; - pInfo.properties |= ( properties2 & BIT_SSE4_1 ) ? CPU_PROP_SSE4_1 : 0; - // switch on processor family code - switch ((processor >> 8) & 0xf) - { - // K6 Family - case 5: - // switch on processor model code - switch ((processor >> 4) & 0xf) - { - case 0: - case 1: - case 2: - case 3: - pInfo.type = CPU_AMD_K6_3; - pInfo.name = StringTable->insert("AMD K5"); - break; - case 4: - case 5: - case 6: - case 7: - pInfo.type = CPU_AMD_K6; - pInfo.name = StringTable->insert("AMD K6"); - break; - case 8: - pInfo.type = CPU_AMD_K6_2; - pInfo.name = StringTable->insert("AMD K6-2"); - break; - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - pInfo.type = CPU_AMD_K6_3; - pInfo.name = StringTable->insert("AMD K6-3"); - break; - } - break; - - // Athlon Family - case 6: - pInfo.type = CPU_AMD_Athlon; - pInfo.name = StringTable->insert("AMD Athlon"); - break; - - // Phenom Family - case 15: - pInfo.type = CPU_AMD_Phenom; - pInfo.name = StringTable->insert("AMD Phenom"); - break; - - // Phenom II Family - case 16: - pInfo.type = CPU_AMD_PhenomII; - pInfo.name = StringTable->insert("AMD Phenom II"); - break; - - // Bulldozer Family - case 17: - pInfo.type = CPU_AMD_Bulldozer; - pInfo.name = StringTable->insert("AMD Bulldozer"); - break; - - default: - pInfo.type = CPU_AMD_Unknown; - pInfo.name = StringTable->insert("AMD (unknown)"); - break; - } - } - //-------------------------------------- - else - if (dStricmp(vendor, "CyrixInstead") == 0) - { - switch (processor) - { - case 0x520: - pInfo.type = CPU_Cyrix_6x86; - pInfo.name = StringTable->insert("Cyrix 6x86"); - break; - case 0x440: - pInfo.type = CPU_Cyrix_MediaGX; - pInfo.name = StringTable->insert("Cyrix Media GX"); - break; - case 0x600: - pInfo.type = CPU_Cyrix_6x86MX; - pInfo.name = StringTable->insert("Cyrix 6x86mx/MII"); - break; - case 0x540: - pInfo.type = CPU_Cyrix_GXm; - pInfo.name = StringTable->insert("Cyrix GXm"); - break; - default: - pInfo.type = CPU_Cyrix_Unknown; - pInfo.name = StringTable->insert("Cyrix (unknown)"); - break; - } - } + { +#if defined(TORQUE_CPU_X86) || defined(TORQUE_CPU_X64) + pInfo.name = StringTable->insert(brand ? brand : "x86 Compatible (unknown)"); + pInfo.type = CPU_X86Compatible; +#elif defined(TORQUE_CPU_ARM64) + pInfo.name = StringTable->insert(brand ? brand : "Arm Compatible (unknown)"); + pInfo.type = CPU_ArmCompatible; +#else +#error "Unknown CPU Architecture" +#endif + } // Get multithreading caps. - CPUInfo::EConfig config = CPUInfo::CPUCount( pInfo.numLogicalProcessors, pInfo.numAvailableCores, pInfo.numPhysicalProcessors ); pInfo.isHyperThreaded = CPUInfo::isHyperThreaded( config ); pInfo.isMultiCore = CPUInfo::isMultiCore( config ); diff --git a/Engine/source/platformWin32/winCPUInfo.cpp b/Engine/source/platformWin32/winCPUInfo.cpp index 4c836ad9e..3765f5c51 100644 --- a/Engine/source/platformWin32/winCPUInfo.cpp +++ b/Engine/source/platformWin32/winCPUInfo.cpp @@ -30,7 +30,7 @@ Platform::SystemInfo_struct Platform::SystemInfo; extern void PlatformBlitInit(); extern void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo, - char* vendor, U32 processor, U32 properties, U32 properties2); // platform/platformCPU.cc + char* vendor, char* brand, U32 processor, U32 properties, U32 properties2); // platform/platformCPU.cc void Processor::init() { @@ -45,7 +45,7 @@ void Processor::init() Platform::SystemInfo.processor.type = CPU_X86Compatible; Platform::SystemInfo.processor.name = StringTable->insert("Unknown x86 Compatible"); Platform::SystemInfo.processor.mhz = 0; - Platform::SystemInfo.processor.properties = CPU_PROP_C | CPU_PROP_LE; + Platform::SystemInfo.processor.properties = CPU_PROP_C; char vendor[0x20]; dMemset(vendor, 0, sizeof(vendor)); @@ -65,7 +65,31 @@ void Processor::init() properties = cpuInfo[3]; // edx properties2 = cpuInfo[2]; // ecx - SetProcessorInfo(Platform::SystemInfo.processor, vendor, processor, properties, properties2); + char brand[0x40]; + dMemset(brand, 0, sizeof(brand)); + S32 extendedInfo[4]; + __cpuid(extendedInfo, 0x80000000); + S32 numberExtendedIds = extendedInfo[0]; + + // Sets brand + if (numberExtendedIds >= 0x80000004) + { + int offset = 0; + for (int i = 0; i < 3; ++i) + { + S32 brandInfo[4]; + __cpuidex(brandInfo, 0x80000002 + i, 0); + + *reinterpret_cast(brand + offset + 0) = brandInfo[0]; + *reinterpret_cast(brand + offset + 4) = brandInfo[1]; + *reinterpret_cast(brand + offset + 8) = brandInfo[2]; + *reinterpret_cast(brand + offset + 12) = brandInfo[3]; + + offset += sizeof(S32) * 4; + } + } + + SetProcessorInfo(Platform::SystemInfo.processor, vendor, brand, processor, properties, properties2); // now calculate speed of processor... U32 nearmhz = 0; // nearest rounded mhz @@ -126,6 +150,14 @@ void Processor::init() Con::printf( " SSE detected" ); if( Platform::SystemInfo.processor.properties & CPU_PROP_SSE2 ) Con::printf( " SSE2 detected" ); + if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE3) + Con::printf( " SSE3 detected" ); + if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE3xt) + Con::printf( " SSE3ex detected "); + if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE4_1) + Con::printf( " SSE4.1 detected" ); + if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE4_2) + Con::printf( " SSE4.2 detected" ); if( Platform::SystemInfo.processor.isHyperThreaded ) Con::printf( " HT detected" ); if( Platform::SystemInfo.processor.properties & CPU_PROP_MP ) From 7cb306b65a3b5551b4ae4c80a001e27e3c162bcc Mon Sep 17 00:00:00 2001 From: Jeff Hutchinson Date: Sat, 25 Sep 2021 22:39:40 -0400 Subject: [PATCH 002/145] macos platform fixes for intel macs --- Engine/source/platform/platform.h | 6 +- Engine/source/platform/platformCPU.cpp | 53 +- Engine/source/platform/platformCPUCount.cpp | 657 ------------------ Engine/source/platform/platformCPUCount.h | 11 +- Engine/source/platform/threads/threadPool.cpp | 3 +- Engine/source/platformMac/macCPU.mm | 287 ++++---- 6 files changed, 132 insertions(+), 885 deletions(-) delete mode 100644 Engine/source/platform/platformCPUCount.cpp diff --git a/Engine/source/platform/platform.h b/Engine/source/platform/platform.h index 35cd1a687..4d8d22f3c 100644 --- a/Engine/source/platform/platform.h +++ b/Engine/source/platform/platform.h @@ -73,9 +73,10 @@ enum ProcessorProperties CPU_PROP_RDTSC = (1<<5), ///< Supports Read Time Stamp Counter op. CPU_PROP_SSE2 = (1<<6), ///< Supports SSE2 instruction set extension. CPU_PROP_SSE3 = (1<<7), ///< Supports SSE3 instruction set extension. - CPU_PROP_SSE3xt = (1<<8), ///< Supports extended SSE3 instruction set + CPU_PROP_SSE3ex = (1<<8), ///< Supports extended SSE3 instruction set CPU_PROP_SSE4_1 = (1<<9), ///< Supports SSE4_1 instruction set extension. - CPU_PROP_SSE4_2 = (1<<10), ///< Supports SSE4_2 instruction set extension. + CPU_PROP_SSE4_2 = (1<<10), ///< Supports SSE4_2 instruction set extension. + CPU_PROP_AVX = (1<<11), ///< Supports AVX256 instruction set extension. CPU_PROP_MP = (1<<11), ///< This is a multi-processor system. CPU_PROP_LE = (1<<12), ///< This processor is LITTLE ENDIAN. CPU_PROP_64bit = (1<<13), ///< This processor is 64-bit capable @@ -297,7 +298,6 @@ namespace Platform bool isHyperThreaded; U32 numLogicalProcessors; U32 numPhysicalProcessors; - U32 numAvailableCores; U32 properties; // CPU type specific enum } processor; }; diff --git a/Engine/source/platform/platformCPU.cpp b/Engine/source/platform/platformCPU.cpp index d0a852431..8449d1daa 100644 --- a/Engine/source/platform/platformCPU.cpp +++ b/Engine/source/platform/platformCPU.cpp @@ -28,48 +28,8 @@ Signal Platform::SystemInfoReady; -enum CPUFlags +void SetProcessoInfo(Platform::SystemInfo_struct::Processor& pInfo, char* vendor, char* brand) { - // EDX Register flags - BIT_RDTSC = BIT(4), - BIT_MMX = BIT(23), - BIT_SSE = BIT(25), - BIT_SSE2 = BIT(26), - BIT_3DNOW = BIT(31), // only available for amd cpus in x86 - - // These use a different value for comparison than the above flags (ECX Register) - BIT_SSE3 = BIT(0), - BIT_SSE3xt = BIT(9), - BIT_SSE4_1 = BIT(19), - BIT_SSE4_2 = BIT(20), -}; - -// fill the specified structure with information obtained from asm code -void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo, - char* vendor, char* brand, U32 processor, U32 properties, U32 properties2) -{ - // always assume FPU is available in 2021... - pInfo.properties |= CPU_PROP_FPU; - -#if defined(TORQUE_CPU_X86) || defined(TORQUE_CPU_X64) || defined(TORQUE_CPU_ARM64) - pInfo.properties |= CPU_PROP_LE; -#endif - -#if defined(TORQUE_CPU_X64) || defined(TORQUE_CPU_ARM64) - pInfo.properties |= CPU_PROP_64bit; -#endif - -#if defined(TORQUE_CPU_X86) || defined(TORQUE_CPU_X64) - pInfo.properties |= (properties & BIT_RDTSC) ? CPU_PROP_RDTSC : 0; - pInfo.properties |= (properties & BIT_MMX) ? CPU_PROP_MMX : 0; - pInfo.properties |= (properties & BIT_SSE) ? CPU_PROP_SSE : 0; - pInfo.properties |= (properties & BIT_SSE2) ? CPU_PROP_SSE2 : 0; - pInfo.properties |= (properties2 & BIT_SSE3) ? CPU_PROP_SSE3 : 0; - pInfo.properties |= (properties2 & BIT_SSE3xt) ? CPU_PROP_SSE3xt : 0; - pInfo.properties |= (properties2 & BIT_SSE4_1) ? CPU_PROP_SSE4_1 : 0; - pInfo.properties |= (properties2 & BIT_SSE4_2) ? CPU_PROP_SSE4_2 : 0; -#endif - if (dStricmp(vendor, "GenuineIntel") == 0) { pInfo.type = CPU_Intel; @@ -80,9 +40,6 @@ void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo, { pInfo.name = StringTable->insert(brand ? brand : "AMD (unknown)"); pInfo.type = CPU_AMD; - - // 3dnow! is only available in AMD cpus on x86. Otherwise its not reliably set. - pInfo.properties |= (properties & BIT_3DNOW) ? CPU_PROP_3DNOW : 0; } else if (dStricmp(vendor, "Apple") == 0) { @@ -92,18 +49,22 @@ void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo, else { #if defined(TORQUE_CPU_X86) || defined(TORQUE_CPU_X64) + pInfo.name = StringTable->insert(brand ? brand : "x86 Compatible (unknown)"); pInfo.type = CPU_X86Compatible; + #elif defined(TORQUE_CPU_ARM64) pInfo.name = StringTable->insert(brand ? brand : "Arm Compatible (unknown)"); pInfo.type = CPU_ArmCompatible; + #else #error "Unknown CPU Architecture" + #endif } - + // Get multithreading caps. - CPUInfo::EConfig config = CPUInfo::CPUCount( pInfo.numLogicalProcessors, pInfo.numAvailableCores, pInfo.numPhysicalProcessors ); + CPUInfo::EConfig config = CPUInfo::CPUCount( pInfo.numLogicalProcessors, pInfo.numPhysicalProcessors ); pInfo.isHyperThreaded = CPUInfo::isHyperThreaded( config ); pInfo.isMultiCore = CPUInfo::isMultiCore( config ); diff --git a/Engine/source/platform/platformCPUCount.cpp b/Engine/source/platform/platformCPUCount.cpp deleted file mode 100644 index a3fe99d67..000000000 --- a/Engine/source/platform/platformCPUCount.cpp +++ /dev/null @@ -1,657 +0,0 @@ -// Original code is: -// Copyright (c) 2005 Intel Corporation -// All Rights Reserved -// -// CPUCount.cpp : Detects three forms of hardware multi-threading support across IA-32 platform -// The three forms of HW multithreading are: Multi-processor, Multi-core, and -// HyperThreading Technology. -// This application enumerates all the logical processors enabled by OS and BIOS, -// determine the HW topology of these enabled logical processors in the system -// using information provided by CPUID instruction. -// A multi-processing system can support any combination of the three forms of HW -// multi-threading support. The relevant topology can be identified using a -// three level decomposition of the "initial APIC ID" into -// Package_id, core_id, and SMT_id. Such decomposition provides a three-level map of -// the topology of hardware resources and -// allow multi-threaded software to manage shared hardware resources in -// the platform to reduce resource contention - -// Multicore detection algorithm for processor and cache topology requires -// all leaf functions of CPUID instructions be available. System administrator -// must ensure BIOS settings is not configured to restrict CPUID functionalities. -//------------------------------------------------------------------------------------------------- - -#if defined(TORQUE_OS_LINUX) || defined(LINUX) - -// TODO GCC code don't compile on Release with optimizations, mover code to platform layer - -#else - -#include "platform/platform.h" -#include "platform/platformCPUCount.h" - -#if defined(TORQUE_OS_LINUX) || defined(TORQUE_OS_OSX) - -#ifdef TORQUE_OS_LINUX -// The Linux source code listing can be compiled using Linux kernel verison 2.6 -// or higher (e.g. RH 4AS-2.8 using GCC 3.4.4). -// Due to syntax variances of Linux affinity APIs with earlier kernel versions -// and dependence on glibc library versions, compilation on Linux environment -// with older kernels and compilers may require kernel patches or compiler upgrades. - -#include -#include -#include -#include -#define DWORD unsigned long -#elif defined( TORQUE_OS_WIN ) -#include -#elif defined( TORQUE_OS_MAC ) -# include -# include -#else -#error Not implemented on platform. -#endif -#include -#include - -namespace CPUInfo { - -#define HWD_MT_BIT 0x10000000 // EDX[28] Bit 28 is set if HT or multi-core is supported -#define NUM_LOGICAL_BITS 0x00FF0000 // EBX[23:16] Bit 16-23 in ebx contains the number of logical - // processors per physical processor when execute cpuid with - // eax set to 1 -#define NUM_CORE_BITS 0xFC000000 // EAX[31:26] Bit 26-31 in eax contains the number of cores minus one - // per physical processor when execute cpuid with - // eax set to 4. - - -#define INITIAL_APIC_ID_BITS 0xFF000000 // EBX[31:24] Bits 24-31 (8 bits) return the 8-bit unique - // initial APIC ID for the processor this code is running on. - - - #ifndef TORQUE_OS_MAC - static U32 CpuIDSupported(void); - static U32 find_maskwidth(unsigned int); - static U32 HWD_MTSupported(void); - static U32 MaxLogicalProcPerPhysicalProc(void); - static U32 MaxCorePerPhysicalProc(void); - static U8 GetAPIC_ID(void); - static U8 GetNzbSubID(U8, U8, U8); - #endif - - static char g_s3Levels[2048]; - -#ifndef TORQUE_OS_MAC - - // - // CpuIDSupported will return 0 if CPUID instruction is unavailable. Otherwise, it will return - // the maximum supported standard function. - // - static U32 CpuIDSupported(void) - { - U32 maxInputValue = 0; - // If CPUID instruction is supported -#ifdef TORQUE_COMPILER_GCC - try - { - // call cpuid with eax = 0 - asm - ( - "pushl %%ebx\n\t" - "xorl %%eax,%%eax\n\t" - "cpuid\n\t" - "popl %%ebx\n\t" - : "=a" (maxInputValue) - : - : "%ecx", "%edx" - ); - } - catch (...) - { - return(0); // cpuid instruction is unavailable - } -#elif defined( TORQUE_COMPILER_VISUALC ) - try - { - // call cpuid with eax = 0 - __asm - { - xor eax, eax - cpuid - mov maxInputValue, eax - } - } - catch (...) - { - // cpuid instruction is unavailable - } -#else -# error Not implemented. -#endif - - return maxInputValue; - } - - - - // - // Function returns the maximum cores per physical package. Note that the number of - // AVAILABLE cores per physical to be used by an application might be less than this - // maximum value. - // - - static U32 MaxCorePerPhysicalProc(void) - { - - U32 Regeax = 0; - - if (!HWD_MTSupported()) return (U32) 1; // Single core -#ifdef TORQUE_COMPILER_GCC - { - asm - ( - "pushl %ebx\n\t" - "xorl %eax, %eax\n\t" - "cpuid\n\t" - "cmpl $4, %eax\n\t" // check if cpuid supports leaf 4 - "jl .single_core\n\t" // Single core - "movl $4, %eax\n\t" - "movl $0, %ecx\n\t" // start with index = 0; Leaf 4 reports - "popl %ebx\n\t" - ); // at least one valid cache level - asm - ( - "cpuid" - : "=a" (Regeax) - : - : "%ecx", "%edx" - ); - asm - ( - "jmp .multi_core\n" - ".single_core:\n\t" - "xor %eax, %eax\n" - ".multi_core:" - ); - } -#elif defined( TORQUE_COMPILER_VISUALC ) - __asm - { - xor eax, eax - cpuid - cmp eax, 4 // check if cpuid supports leaf 4 - jl single_core // Single core - mov eax, 4 - mov ecx, 0 // start with index = 0; Leaf 4 reports - cpuid // at least one valid cache level - mov Regeax, eax - jmp multi_core - -single_core: - xor eax, eax - -multi_core: - - } -#else -# error Not implemented. -#endif - return (U32)((Regeax & NUM_CORE_BITS) >> 26)+1; - - } - - - - // - // The function returns 0 when the hardware multi-threaded bit is not set. - // - static U32 HWD_MTSupported(void) - { - - - U32 Regedx = 0; - - - if ((CpuIDSupported() >= 1)) - { -#ifdef TORQUE_COMPILER_GCC - asm - ( - "pushl %%ebx\n\t" - "movl $1,%%eax\n\t" - "cpuid\n\t" - "popl %%ebx\n\t" - : "=d" (Regedx) - : - : "%eax","%ecx" - ); -#elif defined( TORQUE_COMPILER_VISUALC ) - __asm - { - mov eax, 1 - cpuid - mov Regedx, edx - } -#else -# error Not implemented. -#endif - } - - return (Regedx & HWD_MT_BIT); - - - } - - - - // - // Function returns the maximum logical processors per physical package. Note that the number of - // AVAILABLE logical processors per physical to be used by an application might be less than this - // maximum value. - // - static U32 MaxLogicalProcPerPhysicalProc(void) - { - - U32 Regebx = 0; - - if (!HWD_MTSupported()) return (U32) 1; -#ifdef TORQUE_COMPILER_GCC - asm - ( - "movl $1,%%eax\n\t" - "cpuid" - : "=b" (Regebx) - : - : "%eax","%ecx","%edx" - ); -#elif defined( TORQUE_COMPILER_VISUALC ) - __asm - { - mov eax, 1 - cpuid - mov Regebx, ebx - } -#else -# error Not implemented. -#endif - return (unsigned int) ((Regebx & NUM_LOGICAL_BITS) >> 16); - - } - - - static U8 GetAPIC_ID(void) - { - - U32 Regebx = 0; -#ifdef TORQUE_COMPILER_GCC - asm - ( - "movl $1, %%eax\n\t" - "cpuid" - : "=b" (Regebx) - : - : "%eax","%ecx","%edx" - ); - -#elif defined( TORQUE_COMPILER_VISUALC ) - __asm - { - mov eax, 1 - cpuid - mov Regebx, ebx - } -#else -# error Not implemented. -#endif - - return (unsigned char) ((Regebx & INITIAL_APIC_ID_BITS) >> 24); - - } - - // - // Determine the width of the bit field that can represent the value count_item. - // - U32 find_maskwidth(U32 CountItem) - { - U32 MaskWidth, - count = CountItem; -#ifdef TORQUE_COMPILER_GCC - asm - ( -#ifdef __x86_64__ // define constant to compile - "push %%rcx\n\t" // under 64-bit Linux - "push %%rax\n\t" -#else - "pushl %%ecx\n\t" - "pushl %%eax\n\t" -#endif - // "movl $count, %%eax\n\t" //done by Assembler below - "xorl %%ecx, %%ecx" - // "movl %%ecx, MaskWidth\n\t" //done by Assembler below - : "=c" (MaskWidth) - : "a" (count) - // : "%ecx", "%eax" We don't list these as clobbered because we don't want the assembler - //to put them back when we are done - ); - asm - ( - "decl %%eax\n\t" - "bsrw %%ax,%%cx\n\t" - "jz next\n\t" - "incw %%cx\n\t" - // "movl %%ecx, MaskWidth\n" //done by Assembler below - : "=c" (MaskWidth) - : - ); - asm - ( - "next:\n\t" -#ifdef __x86_64__ - "pop %rax\n\t" - "pop %rcx" -#else - "popl %eax\n\t" - "popl %ecx" -#endif - ); - -#elif defined( TORQUE_COMPILER_VISUALC ) - __asm - { - mov eax, count - mov ecx, 0 - mov MaskWidth, ecx - dec eax - bsr cx, ax - jz next - inc cx - mov MaskWidth, ecx -next: - - } -#else -# error Not implemented. -#endif - return MaskWidth; - } - - - // - // Extract the subset of bit field from the 8-bit value FullID. It returns the 8-bit sub ID value - // - static U8 GetNzbSubID(U8 FullID, - U8 MaxSubIDValue, - U8 ShiftCount) - { - U32 MaskWidth; - U8 MaskBits; - - MaskWidth = find_maskwidth((U32) MaxSubIDValue); - MaskBits = (0xff << ShiftCount) ^ - ((U8) (0xff << (ShiftCount + MaskWidth))); - - return (FullID & MaskBits); - } - -#endif - - - // - // - // - EConfig CPUCount(U32& TotAvailLogical, U32& TotAvailCore, U32& PhysicalNum) - { - EConfig StatusFlag = CONFIG_UserConfigIssue; - - g_s3Levels[0] = 0; - TotAvailCore = 1; - PhysicalNum = 1; - - U32 numLPEnabled = 0; - S32 MaxLPPerCore = 1; - -#ifdef TORQUE_OS_MAC - - //FIXME: This isn't a proper port but more or less just some sneaky cheating - // to get around having to mess with yet another crap UNIX-style API. Seems - // like there isn't a way to do this that's working across all OSX incarnations - // and machine configurations anyway. - - S32 numCPUs; - S32 numPackages; - - // Get the number of CPUs. - - size_t len = sizeof( numCPUs ); - if( sysctlbyname( "hw.ncpu", &numCPUs, &len, 0, 0 ) == -1 ) - return CONFIG_UserConfigIssue; - - // Get the number of packages. - len = sizeof( numPackages ); - if( sysctlbyname( "hw.packages", &numPackages, &len, 0, 0 ) == -1 ) - return CONFIG_UserConfigIssue; - - TotAvailCore = numCPUs; - TotAvailLogical = numCPUs; - PhysicalNum = numPackages; -#else - - U32 dwAffinityMask; - S32 j = 0; - U8 apicID, PackageIDMask; - U8 tblPkgID[256], tblCoreID[256], tblSMTID[256]; - char tmp[256]; - -#ifdef TORQUE_OS_LINUX - //we need to make sure that this process is allowed to run on - //all of the logical processors that the OS itself can run on. - //A process could acquire/inherit affinity settings that restricts the - // current process to run on a subset of all logical processor visible to OS. - - // Linux doesn't easily allow us to look at the Affinity Bitmask directly, - // but it does provide an API to test affinity maskbits of the current process - // against each logical processor visible under OS. - S32 sysNumProcs = sysconf(_SC_NPROCESSORS_CONF); //This will tell us how many - //CPUs are currently enabled. - - //this will tell us which processors this process can run on. - cpu_set_t allowedCPUs; - sched_getaffinity(0, sizeof(allowedCPUs), &allowedCPUs); - - for (S32 i = 0; i < sysNumProcs; i++ ) - { - if ( CPU_ISSET(i, &allowedCPUs) == 0 ) - return CONFIG_UserConfigIssue; - } -#elif defined( TORQUE_OS_WIN ) - DWORD dwProcessAffinity, dwSystemAffinity; - GetProcessAffinityMask(GetCurrentProcess(), - &dwProcessAffinity, - &dwSystemAffinity); - if (dwProcessAffinity != dwSystemAffinity) // not all CPUs are enabled - return CONFIG_UserConfigIssue; -#else -# error Not implemented. -#endif - - // Assume that cores within a package have the SAME number of - // logical processors. Also, values returned by - // MaxLogicalProcPerPhysicalProc and MaxCorePerPhysicalProc do not have - // to be power of 2. - - MaxLPPerCore = MaxLogicalProcPerPhysicalProc() / MaxCorePerPhysicalProc(); - dwAffinityMask = 1; - -#ifdef TORQUE_OS_LINUX - cpu_set_t currentCPU; - while ( j < sysNumProcs ) - { - CPU_ZERO(¤tCPU); - CPU_SET(j, ¤tCPU); - if ( sched_setaffinity (0, sizeof(currentCPU), ¤tCPU) == 0 ) - { - sleep(0); // Ensure system to switch to the right CPU -#elif defined( TORQUE_OS_WIN ) - while (dwAffinityMask && dwAffinityMask <= dwSystemAffinity) - { - if (SetThreadAffinityMask(GetCurrentThread(), dwAffinityMask)) - { - Sleep(0); // Ensure system to switch to the right CPU -#else -# error Not implemented. -#endif - apicID = GetAPIC_ID(); - - - // Store SMT ID and core ID of each logical processor - // Shift vlaue for SMT ID is 0 - // Shift value for core ID is the mask width for maximum logical - // processors per core - - tblSMTID[j] = GetNzbSubID(apicID, MaxLPPerCore, 0); - U8 maxCorePPP = MaxCorePerPhysicalProc(); - U8 maskWidth = find_maskwidth(MaxLPPerCore); - tblCoreID[j] = GetNzbSubID(apicID, maxCorePPP, maskWidth); - - // Extract package ID, assume single cluster. - // Shift value is the mask width for max Logical per package - - PackageIDMask = (unsigned char) (0xff << - find_maskwidth(MaxLogicalProcPerPhysicalProc())); - - tblPkgID[j] = apicID & PackageIDMask; - sprintf(tmp," AffinityMask = %d; Initial APIC = %d; Physical ID = %d, Core ID = %d, SMT ID = %d\n", - dwAffinityMask, apicID, tblPkgID[j], tblCoreID[j], tblSMTID[j]); - dStrcat(g_s3Levels, tmp, 2048); - - numLPEnabled ++; // Number of available logical processors in the system. - - } // if - - j++; - dwAffinityMask = 1 << j; - } // while - - // restore the affinity setting to its original state -#ifdef TORQUE_OS_LINUX - sched_setaffinity (0, sizeof(allowedCPUs), &allowedCPUs); - sleep(0); -#elif defined( TORQUE_OS_WIN ) - SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinity); - Sleep(0); -#else -# error Not implemented. -#endif - TotAvailLogical = numLPEnabled; - - // - // Count available cores (TotAvailCore) in the system - // - U8 CoreIDBucket[256]; - DWORD ProcessorMask, pCoreMask[256]; - U32 i, ProcessorNum; - - CoreIDBucket[0] = tblPkgID[0] | tblCoreID[0]; - ProcessorMask = 1; - pCoreMask[0] = ProcessorMask; - - for (ProcessorNum = 1; ProcessorNum < numLPEnabled; ProcessorNum++) - { - ProcessorMask <<= 1; - for (i = 0; i < TotAvailCore; i++) - { - // Comparing bit-fields of logical processors residing in different packages - // Assuming the bit-masks are the same on all processors in the system. - if ((tblPkgID[ProcessorNum] | tblCoreID[ProcessorNum]) == CoreIDBucket[i]) - { - pCoreMask[i] |= ProcessorMask; - break; - } - - } // for i - - if (i == TotAvailCore) // did not match any bucket. Start a new one. - { - CoreIDBucket[i] = tblPkgID[ProcessorNum] | tblCoreID[ProcessorNum]; - pCoreMask[i] = ProcessorMask; - - TotAvailCore++; // Number of available cores in the system - - } - - } // for ProcessorNum - - - // - // Count physical processor (PhysicalNum) in the system - // - U8 PackageIDBucket[256]; - DWORD pPackageMask[256]; - - PackageIDBucket[0] = tblPkgID[0]; - ProcessorMask = 1; - pPackageMask[0] = ProcessorMask; - - for (ProcessorNum = 1; ProcessorNum < numLPEnabled; ProcessorNum++) - { - ProcessorMask <<= 1; - for (i = 0; i < PhysicalNum; i++) - { - // Comparing bit-fields of logical processors residing in different packages - // Assuming the bit-masks are the same on all processors in the system. - if (tblPkgID[ProcessorNum]== PackageIDBucket[i]) - { - pPackageMask[i] |= ProcessorMask; - break; - } - - } // for i - - if (i == PhysicalNum) // did not match any bucket. Start a new one. - { - PackageIDBucket[i] = tblPkgID[ProcessorNum]; - pPackageMask[i] = ProcessorMask; - - PhysicalNum++; // Total number of physical processors in the system - - } - - } // for ProcessorNum -#endif - - // - // Check to see if the system is multi-core - // Check if the system is hyper-threading - // - if (TotAvailCore > PhysicalNum) - { - // Multi-core - if (MaxLPPerCore == 1) - StatusFlag = CONFIG_MultiCoreAndHTNotCapable; - else if (numLPEnabled > TotAvailCore) - StatusFlag = CONFIG_MultiCoreAndHTEnabled; - else StatusFlag = CONFIG_MultiCoreAndHTDisabled; - - } - else - { - // Single-core - if (MaxLPPerCore == 1) - StatusFlag = CONFIG_SingleCoreAndHTNotCapable; - else if (numLPEnabled > TotAvailCore) - StatusFlag = CONFIG_SingleCoreHTEnabled; - else StatusFlag = CONFIG_SingleCoreHTDisabled; - - - } - - - - return StatusFlag; - } - -} // namespace CPUInfo -#endif - -#endif diff --git a/Engine/source/platform/platformCPUCount.h b/Engine/source/platform/platformCPUCount.h index 2ee07c2eb..d008201b3 100644 --- a/Engine/source/platform/platformCPUCount.h +++ b/Engine/source/platform/platformCPUCount.h @@ -29,13 +29,10 @@ namespace CPUInfo { enum EConfig { - CONFIG_UserConfigIssue, CONFIG_SingleCoreHTEnabled, - CONFIG_SingleCoreHTDisabled, CONFIG_SingleCoreAndHTNotCapable, CONFIG_MultiCoreAndHTNotCapable, CONFIG_MultiCoreAndHTEnabled, - CONFIG_MultiCoreAndHTDisabled, }; inline bool isMultiCore( EConfig config ) @@ -44,7 +41,6 @@ namespace CPUInfo { case CONFIG_MultiCoreAndHTNotCapable: case CONFIG_MultiCoreAndHTEnabled: - case CONFIG_MultiCoreAndHTDisabled: return true; default: @@ -65,11 +61,10 @@ namespace CPUInfo } } - EConfig CPUCount( U32& totalAvailableLogical, - U32& totalAvailableCores, - U32& numPhysical ); - + EConfig CPUCount( U32& totalAvailableLogical, U32& totalAvailableCores ); } // namespace CPUInfo +void SetProcessoInfo(Platform::SystemInfo_struct::Processor& pInfo, char* vendor, char* brand); + #endif // _TORQUE_PLATFORM_PLATFORMCOUNT_H_ diff --git a/Engine/source/platform/threads/threadPool.cpp b/Engine/source/platform/threads/threadPool.cpp index 86402522f..1cad50dda 100644 --- a/Engine/source/platform/threads/threadPool.cpp +++ b/Engine/source/platform/threads/threadPool.cpp @@ -322,10 +322,9 @@ ThreadPool::ThreadPool( const char* name, U32 numThreads ) // Platform::SystemInfo will not yet have been initialized. U32 numLogical = 0; - U32 numPhysical = 0; U32 numCores = 0; - CPUInfo::CPUCount( numLogical, numCores, numPhysical ); + CPUInfo::CPUCount( numLogical, numCores ); const U32 baseCount = getMax( numLogical, numCores ); mNumThreads = (baseCount > 0) ? baseCount : 2; diff --git a/Engine/source/platformMac/macCPU.mm b/Engine/source/platformMac/macCPU.mm index 24a1a8a62..8987cff75 100644 --- a/Engine/source/platformMac/macCPU.mm +++ b/Engine/source/platformMac/macCPU.mm @@ -35,15 +35,6 @@ // we now have to use NSProcessInfo #import -//recently removed in Xcode 8 - most likely don't need these anymore -#ifndef CPUFAMILY_INTEL_YONAH -#define CPUFAMILY_INTEL_YONAH 0x73d67300 -#endif - -#ifndef CPUFAMILY_INTEL_MEROM -#define CPUFAMILY_INTEL_MEROM 0x426f69ef -#endif - // Original code by Sean O'Brien (http://www.garagegames.com/community/forums/viewthread/81815). @@ -89,8 +80,58 @@ int _getSysCTLvalue(const char key[], T * dest) { Platform::SystemInfo_struct Platform::SystemInfo; -#define BASE_MHZ_SPEED 0 -//TODO update cpu list +#define BASE_MHZ_SPEED 1000 + +static void detectCpuFeatures(U32 &procflags) +{ + // Now we can directly query the system about a litany of "Optional" processor capabilities + // and determine the status by using BOTH the 'err' value and the 'lraw' value. If we request + // a non-existant feature from SYSCTL(), the 'err' result will be -1; 0 denotes it exists + // >>>> BUT <<<<< + // it may not be supported, only defined. Thus we need to check 'lraw' to determine if it's + // actually supported/implemented by the processor: 0 = no, 1 = yes, others are undefined. + + int err; + U32 lraw; + + // List of chip-specific features + err = _getSysCTLvalue("hw.optional.mmx", &lraw); + if ((err==0)&&(lraw==1)) + procflags |= CPU_PROP_MMX; + err = _getSysCTLvalue("hw.optional.sse", &lraw); + if ((err==0)&&(lraw==1)) + procflags |= CPU_PROP_SSE; + err = _getSysCTLvalue("hw.optional.sse2", &lraw); + if ((err==0)&&(lraw==1)) + procflags |= CPU_PROP_SSE2; + err = _getSysCTLvalue("hw.optional.sse3", &lraw); + if ((err==0)&&(lraw==1)) + procflags |= CPU_PROP_SSE3; + err = _getSysCTLvalue("hw.optional.supplementalsse3", &lraw); + if ((err==0)&&(lraw==1)) + procflags |= CPU_PROP_SSE3ex; + err = _getSysCTLvalue("hw.optional.sse4_1", &lraw); + if ((err==0)&&(lraw==1)) + procflags |= CPU_PROP_SSE4_1; + err = _getSysCTLvalue("hw.optional.sse4_2", &lraw); + if ((err==0)&&(lraw==1)) + procflags |= CPU_PROP_SSE4_2; + err = _getSysCTLvalue("hw.optional.avx1_0", &lraw); + if ((err==0)&&(lraw==1)) + procflags |= CPU_PROP_AVX; + + err = _getSysCTLvalue("hw.ncpu", &lraw); + if ((err==0)&&(lraw>1)) + procflags |= CPU_PROP_MP; + err = _getSysCTLvalue("hw.cpu64bit_capable", &lraw); + if ((err==0)&&(lraw==1)) + procflags |= CPU_PROP_64bit; + err = _getSysCTLvalue("hw.byteorder", &lraw); + if ((err==0)&&(lraw==1234)) + procflags |= CPU_PROP_LE; + +} + void Processor::init() { U32 procflags; @@ -98,178 +139,64 @@ void Processor::init() char buf[255]; U32 lraw; U64 llraw; - - Con::printf( "System & Processor Information:" ); - // Gestalt has been deprecated since Mac OSX Mountain Lion and has stopped working on - // Mac OSX Yosemite. we have to use NSProcessInfo now. // Availability: Mac OS 10.2 or greater. NSString *osVersionStr = [[NSProcessInfo processInfo] operatingSystemVersionString]; - Con::printf( " OSX Version: %s", [osVersionStr UTF8String]); - - err = _getSysCTLstring("kern.ostype", buf, sizeof(buf)); - if (err) - Con::printf( " Unable to determine OS type\n" ); - else - Con::printf( " Mac OS Kernel name: %s", buf); - - err = _getSysCTLstring("kern.osrelease", buf, sizeof(buf)); - if (err) - Con::printf( " Unable to determine OS release number\n" ); - else - Con::printf( " Mac OS Kernel version: %s", buf ); - + + S32 ramMB; err = _getSysCTLvalue("hw.memsize", &llraw); if (err) - Con::printf( " Unable to determine amount of physical RAM\n" ); + ramMB = 512; else - Con::printf( " Physical memory installed: %d MB", (llraw >> 20)); - - err = _getSysCTLvalue("hw.usermem", &lraw); - if (err) - Con::printf( " Unable to determine available user address space\n"); - else - Con::printf( " Addressable user memory: %d MB", (lraw >> 20)); - - //////////////////////////////// - // Values for the Family Type, CPU Type and CPU Subtype are defined in the - // SDK files for the Mach Kernel ==> mach/machine.h - //////////////////////////////// - - // CPU Family, Type, and Subtype - cpufam = 0; - cputype = 0; - cpusub = 0; - err = _getSysCTLvalue("hw.cpufamily", &lraw); - if (err) - Con::printf( " Unable to determine 'family' of CPU\n"); - else { - cpufam = (int) lraw; - err = _getSysCTLvalue("hw.cputype", &lraw); - if (err) - Con::printf( " Unable to determine CPU type\n"); - else { - cputype = (int) lraw; - err = _getSysCTLvalue("hw.cpusubtype", &lraw); - if (err) - Con::printf( " Unable to determine CPU subtype\n"); - else - cpusub = (int) lraw; - // If we've made it this far, - Con::printf( " Installed processor ID: Family 0x%08x Type %d Subtype %d",cpufam, cputype,cpusub); - } - } + ramMB = llraw >> 20; + char brandString[256]; + err = _getSysCTLstring("machdep.cpu.brand_string", brandString, sizeof(brandString)); + if (err) + brandString[0] = '\0'; + + char vendor[256]; + err = _getSysCTLstring("machdep.cpu.vendor", vendor, sizeof(vendor)); + if (err) + vendor[0] = '\0'; + // The Gestalt version was known to have issues with some Processor Upgrade cards // but it is uncertain whether this version has similar issues. err = _getSysCTLvalue("hw.cpufrequency", &llraw); if (err) { llraw = BASE_MHZ_SPEED; - Con::printf( " Unable to determine CPU Frequency. Defaulting to %d MHz\n", llraw); } else { llraw /= 1000000; - Con::printf( " Installed processor clock frequency: %d MHz", llraw); } Platform::SystemInfo.processor.mhz = (unsigned int)llraw; - // Here's one that the original version of this routine couldn't do -- number - // of processors (cores) - U32 ncpu = 1; - err = _getSysCTLvalue("hw.ncpu", &lraw); - if (err) - Con::printf( " Unable to determine number of processor cores\n"); - else - { - ncpu = lraw; - Con::printf( " Installed/available processor cores: %d", lraw); - } - - // Now use CPUFAM to determine and then store the processor type - // and 'friendly name' in GG-accessible structure. Note that since - // we have access to the Family code, the Type and Subtypes are useless. - // - // NOTE: Even this level of detail is almost assuredly not needed anymore - // and the Optional Capability flags (further down) should be more than enough. - switch(cpufam) - { - case CPUFAMILY_INTEL_YONAH: - Platform::SystemInfo.processor.type = CPU_Intel_Core; - if( ncpu == 2 ) - Platform::SystemInfo.processor.name = StringTable->insert("Intel Core Duo"); - else - Platform::SystemInfo.processor.name = StringTable->insert("Intel Core"); - break; - case CPUFAMILY_INTEL_PENRYN: - case CPUFAMILY_INTEL_MEROM: - Platform::SystemInfo.processor.type = CPU_Intel_Core2; - if( ncpu == 4 ) - Platform::SystemInfo.processor.name = StringTable->insert("Intel Core 2 Quad"); - else - Platform::SystemInfo.processor.name = StringTable->insert("Intel Core 2 Duo"); - break; - - case CPUFAMILY_INTEL_NEHALEM: - Platform::SystemInfo.processor.type = CPU_Intel_Core2; - Platform::SystemInfo.processor.name = StringTable->insert( "Intel 'Nehalem' Core Processor" ); - break; - - default: - // explain why we can't get the processor type. - Con::warnf( " Unknown Processor (family, type, subtype): 0x%x\t%d %d", cpufam, cputype, cpusub); - // for now, identify it as an x86 processor, because Apple is moving to Intel chips... - Platform::SystemInfo.processor.type = CPU_X86Compatible; - Platform::SystemInfo.processor.name = StringTable->insert("Unknown Processor, assuming x86 Compatible"); - break; - } - // Now we can directly query the system about a litany of "Optional" processor capabilities - // and determine the status by using BOTH the 'err' value and the 'lraw' value. If we request - // a non-existant feature from SYSCTL(), the 'err' result will be -1; 0 denotes it exists - // >>>> BUT <<<<< - // it may not be supported, only defined. Thus we need to check 'lraw' to determine if it's - // actually supported/implemented by the processor: 0 = no, 1 = yes, others are undefined. - procflags = 0; - // Seriously this one should be an Assert() - err = _getSysCTLvalue("hw.optional.floatingpoint", &lraw); - if ((err==0)&&(lraw==1)) procflags |= CPU_PROP_FPU; - // List of chip-specific features - err = _getSysCTLvalue("hw.optional.mmx", &lraw); - if ((err==0)&&(lraw==1)) procflags |= CPU_PROP_MMX; - err = _getSysCTLvalue("hw.optional.sse", &lraw); - if ((err==0)&&(lraw==1)) procflags |= CPU_PROP_SSE; - err = _getSysCTLvalue("hw.optional.sse2", &lraw); - if ((err==0)&&(lraw==1)) procflags |= CPU_PROP_SSE2; - err = _getSysCTLvalue("hw.optional.sse3", &lraw); - if ((err==0)&&(lraw==1)) procflags |= CPU_PROP_SSE3; - err = _getSysCTLvalue("hw.optional.supplementalsse3", &lraw); - if ((err==0)&&(lraw==1)) procflags |= CPU_PROP_SSE3xt; - err = _getSysCTLvalue("hw.optional.sse4_1", &lraw); - if ((err==0)&&(lraw==1)) procflags |= CPU_PROP_SSE4_1; - err = _getSysCTLvalue("hw.optional.sse4_2", &lraw); - if ((err==0)&&(lraw==1)) procflags |= CPU_PROP_SSE4_2; - - // Finally some architecture-wide settings - err = _getSysCTLvalue("hw.ncpu", &lraw); - if ((err==0)&&(lraw>1)) procflags |= CPU_PROP_MP; - err = _getSysCTLvalue("hw.cpu64bit_capable", &lraw); - if ((err==0)&&(lraw==1)) procflags |= CPU_PROP_64bit; - err = _getSysCTLvalue("hw.byteorder", &lraw); - if ((err==0)&&(lraw==1234)) procflags |= CPU_PROP_LE; - - Platform::SystemInfo.processor.properties = procflags; - - Con::printf( "%s, %2.2f GHz", Platform::SystemInfo.processor.name, F32( Platform::SystemInfo.processor.mhz ) / 1000.0 ); + procflags = CPU_PROP_FPU; + detectCpuFeatures(procflags); + + Platform::SystemInfo.processor.properties = procflags; + SetProcessoInfo(Platform::SystemInfo.processor, vendor, brandString); + + + Con::printf("System & Processor Information:"); + Con::printf(" MacOS Version: %s", [osVersionStr UTF8String]); + Con::printf(" Physical memory installed: %d MB", ramMB); + Con::printf(" Processor: %s", Platform::SystemInfo.processor.name); if (Platform::SystemInfo.processor.properties & CPU_PROP_MMX) - Con::printf( " MMX detected"); + Con::printf(" MMX detected"); if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE) - Con::printf( " SSE detected"); + Con::printf(" SSE detected"); if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE2) - Con::printf( " SSE2 detected"); + Con::printf(" SSE2 detected"); if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE3) - Con::printf( " SSE3 detected"); + Con::printf(" SSE3 detected"); + if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE3ex) + Con::printf(" SSE3ex detected"); if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE4_1) - Con::printf( " SSE4.1 detected"); + Con::printf(" SSE4.1 detected"); if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE4_2) - Con::printf( " SSE4.2 detected"); + Con::printf(" SSE4.2 detected"); + if (Platform::SystemInfo.processor.properties & CPU_PROP_AVX) + Con::printf(" AVX detected"); Con::printf( "" ); @@ -277,16 +204,38 @@ void Processor::init() Platform::SystemInfoReady.trigger(); } + namespace CPUInfo { - EConfig CPUCount(U32 &logical, U32 &numCores, U32 &numPhysical) { - // todo properly implement this - logical = [[NSProcessInfo processInfo] activeProcessorCount]; - numCores = [[NSProcessInfo processInfo] activeProcessorCount]; - numPhysical = [[NSProcessInfo processInfo] processorCount]; + EConfig CPUCount(U32 &logical, U32 &physical) { + U32 lraw; + int err; - // todo check for hyperthreading - if (numCores > 1) - return CONFIG_MultiCoreAndHTNotCapable; - return CONFIG_SingleCoreAndHTNotCapable; + err = _getSysCTLvalue("hw.physicalcpu", &lraw); + if (err == 0) + physical = lraw; + else + physical = 1; + + err = _getSysCTLvalue("hw.logicalcpu", &lraw); + if (err == 0) + { + logical = lraw; + } + else + { + // fallback to querying the number of cpus. If that fails, then assume same as number of cores + err = _getSysCTLvalue("hw.ncpu", &lraw); + if (err == 0) + logical = lraw; + else + logical = physical; + } + + const bool smtEnabled = logical > physical; + + if (physical == 1) + return smtEnabled ? CONFIG_SingleCoreHTEnabled : CONFIG_SingleCoreAndHTNotCapable; + + return smtEnabled ? CONFIG_MultiCoreAndHTEnabled : CONFIG_MultiCoreAndHTNotCapable; } } From 960ea2aa5a2e74f88e6452c200d692f434cde12c Mon Sep 17 00:00:00 2001 From: Jeff Hutchinson Date: Sat, 25 Sep 2021 22:53:34 -0400 Subject: [PATCH 003/145] Add support for Neon. --- Engine/source/platform/platform.h | 1 + Engine/source/platformMac/macCPU.mm | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Engine/source/platform/platform.h b/Engine/source/platform/platform.h index 4d8d22f3c..2944e596c 100644 --- a/Engine/source/platform/platform.h +++ b/Engine/source/platform/platform.h @@ -80,6 +80,7 @@ enum ProcessorProperties CPU_PROP_MP = (1<<11), ///< This is a multi-processor system. CPU_PROP_LE = (1<<12), ///< This processor is LITTLE ENDIAN. CPU_PROP_64bit = (1<<13), ///< This processor is 64-bit capable + CPU_PROP_NEON = (1<<14), ///< Supports the Arm Neon instruction set extension. }; /// Processor info manager. diff --git a/Engine/source/platformMac/macCPU.mm b/Engine/source/platformMac/macCPU.mm index 8987cff75..e961542e9 100644 --- a/Engine/source/platformMac/macCPU.mm +++ b/Engine/source/platformMac/macCPU.mm @@ -94,6 +94,11 @@ static void detectCpuFeatures(U32 &procflags) int err; U32 lraw; + // All Cpus have fpu + procflags = CPU_PROP_FPU; + +#if defined(TORQUE_CPU_X86) || defined(TORQUE_CPU_X64) + // List of chip-specific features err = _getSysCTLvalue("hw.optional.mmx", &lraw); if ((err==0)&&(lraw==1)) @@ -119,6 +124,12 @@ static void detectCpuFeatures(U32 &procflags) err = _getSysCTLvalue("hw.optional.avx1_0", &lraw); if ((err==0)&&(lraw==1)) procflags |= CPU_PROP_AVX; + +#elif defined(TORQUE_CPU_ARM64) + // All Apple Cpus have Neon + procflags |= CPU_PROP_NEON; + +#endif err = _getSysCTLvalue("hw.ncpu", &lraw); if ((err==0)&&(lraw>1)) @@ -129,12 +140,11 @@ static void detectCpuFeatures(U32 &procflags) err = _getSysCTLvalue("hw.byteorder", &lraw); if ((err==0)&&(lraw==1234)) procflags |= CPU_PROP_LE; - } void Processor::init() { - U32 procflags; + U32 procflags = 0; int err, cpufam, cputype, cpusub; char buf[255]; U32 lraw; @@ -170,7 +180,6 @@ void Processor::init() } Platform::SystemInfo.processor.mhz = (unsigned int)llraw; - procflags = CPU_PROP_FPU; detectCpuFeatures(procflags); Platform::SystemInfo.processor.properties = procflags; @@ -197,7 +206,9 @@ void Processor::init() Con::printf(" SSE4.2 detected"); if (Platform::SystemInfo.processor.properties & CPU_PROP_AVX) Con::printf(" AVX detected"); - + if (Platform::SystemInfo.processor.properties & CPU_PROP_NEON) + Con::printf(" Neon detected"); + Con::printf( "" ); // Trigger the signal From eb92a8927e37f782d785a2201b46d9c28b43689b Mon Sep 17 00:00:00 2001 From: Jeff Hutchinson Date: Sun, 26 Sep 2021 19:36:12 -0400 Subject: [PATCH 004/145] M1 Support for cpu detection --- Engine/source/platform/platform.h | 8 ++++---- Engine/source/platformMac/macCPU.mm | 15 +++++++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Engine/source/platform/platform.h b/Engine/source/platform/platform.h index 2944e596c..f8239f817 100644 --- a/Engine/source/platform/platform.h +++ b/Engine/source/platform/platform.h @@ -77,10 +77,10 @@ enum ProcessorProperties CPU_PROP_SSE4_1 = (1<<9), ///< Supports SSE4_1 instruction set extension. CPU_PROP_SSE4_2 = (1<<10), ///< Supports SSE4_2 instruction set extension. CPU_PROP_AVX = (1<<11), ///< Supports AVX256 instruction set extension. - CPU_PROP_MP = (1<<11), ///< This is a multi-processor system. - CPU_PROP_LE = (1<<12), ///< This processor is LITTLE ENDIAN. - CPU_PROP_64bit = (1<<13), ///< This processor is 64-bit capable - CPU_PROP_NEON = (1<<14), ///< Supports the Arm Neon instruction set extension. + CPU_PROP_MP = (1<<12), ///< This is a multi-processor system. + CPU_PROP_LE = (1<<13), ///< This processor is LITTLE ENDIAN. + CPU_PROP_64bit = (1<<14), ///< This processor is 64-bit capable + CPU_PROP_NEON = (1<<15), ///< Supports the Arm Neon instruction set extension. }; /// Processor info manager. diff --git a/Engine/source/platformMac/macCPU.mm b/Engine/source/platformMac/macCPU.mm index e961542e9..96cf068a9 100644 --- a/Engine/source/platformMac/macCPU.mm +++ b/Engine/source/platformMac/macCPU.mm @@ -81,6 +81,7 @@ int _getSysCTLvalue(const char key[], T * dest) { Platform::SystemInfo_struct Platform::SystemInfo; #define BASE_MHZ_SPEED 1000 +#define BASE_APPLE_SILICON_MHZ_SPEED 3200 static void detectCpuFeatures(U32 &procflags) { @@ -126,8 +127,10 @@ static void detectCpuFeatures(U32 &procflags) procflags |= CPU_PROP_AVX; #elif defined(TORQUE_CPU_ARM64) - // All Apple Cpus have Neon - procflags |= CPU_PROP_NEON; + + err = _getSysCTLvalue("hw.optional.neon", &lraw); + if ((err==0)&&(lraw==1)) + procflags |= CPU_PROP_NEON; #endif @@ -170,11 +173,15 @@ void Processor::init() if (err) vendor[0] = '\0'; - // The Gestalt version was known to have issues with some Processor Upgrade cards - // but it is uncertain whether this version has similar issues. + // Note: hw.cpufrequency seems to be missing on the M1. For Apple Silicon, + // we will assume the base frequency of the M1 which is 3.2ghz err = _getSysCTLvalue("hw.cpufrequency", &llraw); if (err) { +#if defined(TORQUE_CPU_ARM64) + llraw = BASE_APPLE_SILICON_MHZ_SPEED; +#else llraw = BASE_MHZ_SPEED; +#endif } else { llraw /= 1000000; } From 24e5db942be6a33c2946ba20d846249efb6e4540 Mon Sep 17 00:00:00 2001 From: Jeff Hutchinson Date: Sun, 26 Sep 2021 23:43:06 -0400 Subject: [PATCH 005/145] flush out windows cpu detection. --- Engine/source/platform/platform.h | 21 +- Engine/source/platform/platformCPUInfo.asm | 128 ------------ Engine/source/platformMac/macCPU.mm | 5 +- Engine/source/platformWin32/winCPUInfo.cpp | 192 ++++++++++-------- .../platformWin32/winPlatformCPUCount.cpp | 38 ++-- 5 files changed, 136 insertions(+), 248 deletions(-) delete mode 100644 Engine/source/platform/platformCPUInfo.asm diff --git a/Engine/source/platform/platform.h b/Engine/source/platform/platform.h index f8239f817..6073786b7 100644 --- a/Engine/source/platform/platform.h +++ b/Engine/source/platform/platform.h @@ -70,17 +70,16 @@ enum ProcessorProperties CPU_PROP_MMX = (1<<2), ///< Supports MMX instruction set extension. CPU_PROP_3DNOW = (1<<3), ///< Supports AMD 3dNow! instruction set extension. CPU_PROP_SSE = (1<<4), ///< Supports SSE instruction set extension. - CPU_PROP_RDTSC = (1<<5), ///< Supports Read Time Stamp Counter op. - CPU_PROP_SSE2 = (1<<6), ///< Supports SSE2 instruction set extension. - CPU_PROP_SSE3 = (1<<7), ///< Supports SSE3 instruction set extension. - CPU_PROP_SSE3ex = (1<<8), ///< Supports extended SSE3 instruction set - CPU_PROP_SSE4_1 = (1<<9), ///< Supports SSE4_1 instruction set extension. - CPU_PROP_SSE4_2 = (1<<10), ///< Supports SSE4_2 instruction set extension. - CPU_PROP_AVX = (1<<11), ///< Supports AVX256 instruction set extension. - CPU_PROP_MP = (1<<12), ///< This is a multi-processor system. - CPU_PROP_LE = (1<<13), ///< This processor is LITTLE ENDIAN. - CPU_PROP_64bit = (1<<14), ///< This processor is 64-bit capable - CPU_PROP_NEON = (1<<15), ///< Supports the Arm Neon instruction set extension. + CPU_PROP_SSE2 = (1<<5), ///< Supports SSE2 instruction set extension. + CPU_PROP_SSE3 = (1<<6), ///< Supports SSE3 instruction set extension. + CPU_PROP_SSE3ex = (1<<7), ///< Supports Supplemental SSE3 instruction set + CPU_PROP_SSE4_1 = (1<<8), ///< Supports SSE4_1 instruction set extension. + CPU_PROP_SSE4_2 = (1<<9), ///< Supports SSE4_2 instruction set extension. + CPU_PROP_AVX = (1<<10), ///< Supports AVX256 instruction set extension. + CPU_PROP_MP = (1<<11), ///< This is a multi-processor system. + CPU_PROP_LE = (1<<12), ///< This processor is LITTLE ENDIAN. + CPU_PROP_64bit = (1<<13), ///< This processor is 64-bit capable + CPU_PROP_NEON = (1<<14), ///< Supports the Arm Neon instruction set extension. }; /// Processor info manager. diff --git a/Engine/source/platform/platformCPUInfo.asm b/Engine/source/platform/platformCPUInfo.asm deleted file mode 100644 index bce39d220..000000000 --- a/Engine/source/platform/platformCPUInfo.asm +++ /dev/null @@ -1,128 +0,0 @@ -;----------------------------------------------------------------------------- -; Copyright (c) 2012 GarageGames, LLC -; -; Permission is hereby granted, free of charge, to any person obtaining a copy -; of this software and associated documentation files (the "Software"), to -; deal in the Software without restriction, including without limitation the -; rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -; sell copies of the Software, and to permit persons to whom the Software is -; furnished to do so, subject to the following conditions: -; -; The above copyright notice and this permission notice shall be included in -; all copies or substantial portions of the Software. -; -; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -; IN THE SOFTWARE. -;----------------------------------------------------------------------------- - - -segment .text - -; syntax: export_fn -%macro export_fn 1 - %ifidn __OUTPUT_FORMAT__, elf - ; No underscore needed for ELF object files - global %1 - %1: - %else - global _%1 - _%1: - %endif -%endmacro - -; push registers -%macro pushreg 0 -; pushad - push ebx - push ebp - push esi - push edi -%endmacro - -; pop registers -%macro popreg 0 - pop edi - pop esi - pop ebp - pop ebx -; popad -%endmacro - -; void detectX86CPUInfo(char *vendor, U32 *processor, U32 *properties); -export_fn detectX86CPUInfo - push ebp - mov ebp, esp - - pushreg - - push edx - push ecx - pushfd - pushfd ; save EFLAGS to stack - pop eax ; move EFLAGS into EAX - mov ebx, eax - xor eax, 0x200000 ; flip bit 21 - push eax - popfd ; restore EFLAGS - pushfd - pop eax - cmp eax, ebx - jz EXIT ; doesn't support CPUID instruction - - ; - ; get vendor information using CPUID eax == 0 - xor eax, eax - cpuid - - ; store the vendor tag (12 bytes in ebx, edx, ecx) in the first parameter, - ; which should be a char[13] - push eax ; save eax - mov eax, [ebp+8] ; store the char* address in eax - mov [eax], ebx ; move ebx into the first 4 bytes - add eax, 4 ; advance the char* 4 bytes - mov [eax], edx ; move edx into the next 4 bytes - add eax, 4 ; advance the char* 4 bytes - mov [eax], ecx ; move ecx into the last 4 bytes - pop eax ; restore eax - - ; get generic extended CPUID info - mov eax, 1 - cpuid ; eax=1, so cpuid queries feature information - - and eax, 0x0fff3fff - push ecx - mov ecx, [ebp+12] - mov [ecx], eax ; just store the model bits in processor param - mov ecx, [ebp+16] - mov [ecx], edx ; set properties param - pop ecx - - ; want to check for 3DNow(tm). - ; need to see if extended cpuid functions present. - mov eax, 0x80000000 - cpuid - cmp eax, 0x80000000 - jbe MAYBE_3DLATER - mov eax, 0x80000001 - cpuid - ; 3DNow if bit 31 set -> put bit in our properties - and edx, 0x80000000 - push eax - mov eax, [ebp+16] - or [eax], edx - pop eax -MAYBE_3DLATER: -EXIT: - popfd - pop ecx - pop edx - - popreg - - pop ebp - ret diff --git a/Engine/source/platformMac/macCPU.mm b/Engine/source/platformMac/macCPU.mm index 96cf068a9..d93bcf25f 100644 --- a/Engine/source/platformMac/macCPU.mm +++ b/Engine/source/platformMac/macCPU.mm @@ -96,7 +96,7 @@ static void detectCpuFeatures(U32 &procflags) U32 lraw; // All Cpus have fpu - procflags = CPU_PROP_FPU; + procflags = CPU_PROP_C | CPU_PROP_FPU; #if defined(TORQUE_CPU_X86) || defined(TORQUE_CPU_X64) @@ -215,6 +215,9 @@ void Processor::init() Con::printf(" AVX detected"); if (Platform::SystemInfo.processor.properties & CPU_PROP_NEON) Con::printf(" Neon detected"); + + if (Platform::SystemInfo.processor.properties & CPU_PROP_MP) + Con::printf(" MultiCore CPU detected [%i cores, %i logical]", Platform::SystemInfo.processor.numPhysicalProcessors, Platform::SystemInfo.processor.numLogicalProcessors); Con::printf( "" ); diff --git a/Engine/source/platformWin32/winCPUInfo.cpp b/Engine/source/platformWin32/winCPUInfo.cpp index 3765f5c51..f8ea9ab2d 100644 --- a/Engine/source/platformWin32/winCPUInfo.cpp +++ b/Engine/source/platformWin32/winCPUInfo.cpp @@ -24,49 +24,15 @@ #include "platformWin32/platformWin32.h" #include "console/console.h" #include "core/stringTable.h" +#include "platform/platformCPUCount.h" #include #include Platform::SystemInfo_struct Platform::SystemInfo; extern void PlatformBlitInit(); -extern void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo, - char* vendor, char* brand, U32 processor, U32 properties, U32 properties2); // platform/platformCPU.cc -void Processor::init() +static void getBrand(char* brand) { - // Reference: - // www.cyrix.com - // www.amd.com - // www.intel.com - // http://developer.intel.com/design/PentiumII/manuals/24512701.pdf - - Con::printf("Processor Init:"); - - Platform::SystemInfo.processor.type = CPU_X86Compatible; - Platform::SystemInfo.processor.name = StringTable->insert("Unknown x86 Compatible"); - Platform::SystemInfo.processor.mhz = 0; - Platform::SystemInfo.processor.properties = CPU_PROP_C; - - char vendor[0x20]; - dMemset(vendor, 0, sizeof(vendor)); - U32 properties = 0; - U32 processor = 0; - U32 properties2 = 0; - - S32 vendorInfo[4]; - __cpuid(vendorInfo, 0); - *reinterpret_cast(vendor) = vendorInfo[1]; // ebx - *reinterpret_cast(vendor + 4) = vendorInfo[3]; // edx - *reinterpret_cast(vendor + 8) = vendorInfo[2]; // ecx - - S32 cpuInfo[4]; - __cpuid(cpuInfo, 1); - processor = cpuInfo[0]; // eax - properties = cpuInfo[3]; // edx - properties2 = cpuInfo[2]; // ecx - - char brand[0x40]; - dMemset(brand, 0, sizeof(brand)); S32 extendedInfo[4]; __cpuid(extendedInfo, 0x80000000); S32 numberExtendedIds = extendedInfo[0]; @@ -88,12 +54,93 @@ void Processor::init() offset += sizeof(S32) * 4; } } +} - SetProcessorInfo(Platform::SystemInfo.processor, vendor, brand, processor, properties, properties2); +enum CpuFlags +{ + // EDX Register flags + BIT_MMX = BIT(23), + BIT_SSE = BIT(25), + BIT_SSE2 = BIT(26), + BIT_3DNOW = BIT(31), // only available for amd cpus in x86 -// now calculate speed of processor... - U32 nearmhz = 0; // nearest rounded mhz - U32 mhz = 0; // calculated value. + // These use a different value for comparison than the above flags (ECX Register) + BIT_SSE3 = BIT(0), + BIT_SSE3ex = BIT(9), + BIT_SSE4_1 = BIT(19), + BIT_SSE4_2 = BIT(20), + + BIT_XSAVE_RESTORE = BIT(27), + BIT_AVX = BIT(28), +}; + +static void detectCpuFeatures(Platform::SystemInfo_struct::Processor &processor) +{ + S32 cpuInfo[4]; + __cpuid(cpuInfo, 1); + U32 eax = cpuInfo[0]; // eax + U32 edx = cpuInfo[3]; // edx + U32 ecx = cpuInfo[2]; // ecx + + if (processor.type == ProcessorType::CPU_AMD) + processor.properties |= (edx & BIT_3DNOW) ? CPU_PROP_3DNOW : 0; + + processor.properties |= (edx & BIT_MMX) ? CPU_PROP_MMX : 0; + processor.properties |= (edx & BIT_SSE) ? CPU_PROP_SSE : 0; + processor.properties |= (edx & BIT_SSE2) ? CPU_PROP_SSE2 : 0; + processor.properties |= (ecx & BIT_SSE3) ? CPU_PROP_SSE3 : 0; + processor.properties |= (ecx & BIT_SSE3ex) ? CPU_PROP_SSE3ex : 0; + processor.properties |= (ecx & BIT_SSE4_1) ? CPU_PROP_SSE4_1 : 0; + processor.properties |= (ecx & BIT_SSE4_2) ? CPU_PROP_SSE4_2 : 0; + + // AVX detection requires that xsaverestore is supported + if (ecx & BIT_XSAVE_RESTORE && ecx & BIT_AVX) + { + bool supportsAVX = _xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6; + if (supportsAVX) + { + processor.properties |= CPU_PROP_AVX; + } + } + + if (processor.isMultiCore) + processor.properties |= CPU_PROP_MP; + +#ifdef TORQUE_CPU_X64 + processor.properties |= CPU_PROP_64bit; +#endif +} + +void Processor::init() +{ + // Reference: + // www.cyrix.com + // www.amd.com + // www.intel.com + // http://developer.intel.com/design/PentiumII/manuals/24512701.pdf + + Platform::SystemInfo.processor.type = CPU_X86Compatible; + Platform::SystemInfo.processor.name = StringTable->insert("Unknown x86 Compatible"); + Platform::SystemInfo.processor.mhz = 0; + Platform::SystemInfo.processor.properties = CPU_PROP_C | CPU_PROP_FPU | CPU_PROP_LE; + + char vendor[0x20]; + dMemset(vendor, 0, sizeof(vendor)); + + S32 vendorInfo[4]; + __cpuid(vendorInfo, 0); + *reinterpret_cast(vendor) = vendorInfo[1]; // ebx + *reinterpret_cast(vendor + 4) = vendorInfo[3]; // edx + *reinterpret_cast(vendor + 8) = vendorInfo[2]; // ecx + + char brand[0x40]; + dMemset(brand, 0, sizeof(brand)); + getBrand(brand); + + SetProcessoInfo(Platform::SystemInfo.processor, vendor, brand); + detectCpuFeatures(Platform::SystemInfo.processor); + + U32 mhz = 1000; // default if it can't be found LONG result; DWORD data = 0; @@ -107,64 +154,37 @@ void Processor::init() result = ::RegQueryValueExA (hKey, "~MHz",NULL, NULL,(LPBYTE)&data, &dataSize); if (result == ERROR_SUCCESS) - nearmhz = mhz = data; + mhz = data; ::RegCloseKey(hKey); } Platform::SystemInfo.processor.mhz = mhz; - if (mhz==0) - { - Con::printf(" %s, (Unknown) Mhz", Platform::SystemInfo.processor.name); - // stick SOMETHING in so it isn't ZERO. - Platform::SystemInfo.processor.mhz = 200; // seems a decent value. - } - else - { - if (nearmhz >= 1000) - Con::printf(" %s, ~%.2f Ghz", Platform::SystemInfo.processor.name, ((float)nearmhz)/1000.0f); - else - Con::printf(" %s, ~%d Mhz", Platform::SystemInfo.processor.name, nearmhz); - if (nearmhz != mhz) - { - if (mhz >= 1000) - Con::printf(" (timed at roughly %.2f Ghz)", ((float)mhz)/1000.0f); - else - Con::printf(" (timed at roughly %d Mhz)", mhz); - } - } - - if( Platform::SystemInfo.processor.numAvailableCores > 0 - || Platform::SystemInfo.processor.numPhysicalProcessors > 0 - || Platform::SystemInfo.processor.isHyperThreaded ) - Platform::SystemInfo.processor.properties |= CPU_PROP_MP; - - if (Platform::SystemInfo.processor.properties & CPU_PROP_FPU) - Con::printf( " FPU detected" ); + Con::printf("Processor Init:"); + Con::printf(" Processor: %s", Platform::SystemInfo.processor.name); if (Platform::SystemInfo.processor.properties & CPU_PROP_MMX) - Con::printf( " MMX detected" ); + Con::printf(" MMX detected" ); if (Platform::SystemInfo.processor.properties & CPU_PROP_3DNOW) - Con::printf( " 3DNow detected" ); + Con::printf(" 3DNow detected" ); if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE) - Con::printf( " SSE detected" ); - if( Platform::SystemInfo.processor.properties & CPU_PROP_SSE2 ) - Con::printf( " SSE2 detected" ); + Con::printf(" SSE detected" ); + if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE2) + Con::printf(" SSE2 detected" ); if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE3) - Con::printf( " SSE3 detected" ); - if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE3xt) - Con::printf( " SSE3ex detected "); + Con::printf(" SSE3 detected" ); + if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE3ex) + Con::printf(" SSE3ex detected "); if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE4_1) - Con::printf( " SSE4.1 detected" ); + Con::printf(" SSE4.1 detected" ); if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE4_2) - Con::printf( " SSE4.2 detected" ); - if( Platform::SystemInfo.processor.isHyperThreaded ) - Con::printf( " HT detected" ); - if( Platform::SystemInfo.processor.properties & CPU_PROP_MP ) - Con::printf( " MP detected [%i cores, %i logical, %i physical]", - Platform::SystemInfo.processor.numAvailableCores, - Platform::SystemInfo.processor.numLogicalProcessors, - Platform::SystemInfo.processor.numPhysicalProcessors ); + Con::printf(" SSE4.2 detected" ); + if (Platform::SystemInfo.processor.properties & CPU_PROP_AVX) + Con::printf(" AVX detected"); + + if (Platform::SystemInfo.processor.properties & CPU_PROP_MP) + Con::printf(" MultiCore CPU detected [%i cores, %i logical]", Platform::SystemInfo.processor.numPhysicalProcessors, Platform::SystemInfo.processor.numLogicalProcessors); + Con::printf(" "); PlatformBlitInit(); diff --git a/Engine/source/platformWin32/winPlatformCPUCount.cpp b/Engine/source/platformWin32/winPlatformCPUCount.cpp index e4a5d54d6..e4b113c67 100644 --- a/Engine/source/platformWin32/winPlatformCPUCount.cpp +++ b/Engine/source/platformWin32/winPlatformCPUCount.cpp @@ -26,6 +26,7 @@ #if defined( TORQUE_OS_WIN ) #include "platform/platformCPUCount.h" +#include "console/console.h" #include #include #include @@ -52,12 +53,10 @@ namespace CPUInfo { return bitSetCount; } - EConfig CPUCount( U32& TotAvailLogical, U32& TotAvailCore, U32& PhysicalNum ) + EConfig CPUCount( U32& TotAvailLogical, U32& TotAvailCore ) { - EConfig StatusFlag = CONFIG_UserConfigIssue; TotAvailLogical = 0; TotAvailCore = 0; - PhysicalNum = 0; PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL; DWORD returnLength = 0; @@ -68,42 +67,37 @@ namespace CPUInfo { rc = GetLogicalProcessorInformation( buffer, &returnLength ); + // if we fail, assume single threaded if( FALSE == rc ) { free( buffer ); - return StatusFlag; + Con::errorf("Unable to determine CPU Count, assuming 1 core"); + TotAvailCore = 1; + TotAvailLogical = 1; + return CONFIG_SingleCoreAndHTNotCapable; } +#pragma push +#pragma warning (disable: 6011) PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer; DWORD byteOffset = 0; while( byteOffset + sizeof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION ) <= returnLength ) { - switch( ptr->Relationship ) - { - - case RelationProcessorCore: + if (ptr->Relationship == RelationProcessorCore) + { TotAvailCore++; - - // A hyperthreaded core supplies more than one logical processor. - TotAvailLogical += CountSetBits( ptr->ProcessorMask ); - break; - - case RelationProcessorPackage: - // Logical processors share a physical package. - PhysicalNum++; - break; - - default: - break; + TotAvailLogical += CountSetBits(ptr->ProcessorMask); } + byteOffset += sizeof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION ); ptr++; - } + } free( buffer ); +#pragma pop - StatusFlag = CONFIG_SingleCoreAndHTNotCapable; + EConfig StatusFlag = CONFIG_SingleCoreAndHTNotCapable; if( TotAvailCore == 1 && TotAvailLogical > TotAvailCore ) StatusFlag = CONFIG_SingleCoreHTEnabled; From b70faae38fb154e7c0af97c2bd33c9027d011925 Mon Sep 17 00:00:00 2001 From: JeffR Date: Fri, 24 Dec 2021 17:26:45 -0600 Subject: [PATCH 006/145] Updates the handling of the baking of shape asset previews to generate them with support for view angle control to improve visibility, as well as supporting overriding of a material in the preview bake Also utilizes the updated bake handling to have material asset previews render as a sphere shape asset, overriding with the material asset's material, improving distinction of what is a material asset vs image asset Also updates the sphere preview mesh to be more generic and not only for reflection probes --- Engine/source/T3D/assets/ShapeAsset.cpp | 103 +++++++++++++--- Engine/source/T3D/assets/ShapeAsset.h | 2 +- .../source/T3D/lighting/reflectionProbe.cpp | 2 +- .../scripts/assetTypes/material.tscript | 16 +-- .../scripts/assetTypes/shape.tscript | 16 +-- .../resources/ReflectProbeSphere.asset.taml | 6 - .../tools/resources/ReflectProbeSphere.dae | 115 ------------------ .../resources/ReflectProbeSphere.tscript | 11 -- .../resources/previewSphereShape.asset.taml | 6 + .../tools/resources/previewSphereShape.dae | 101 +++++++++++++++ 10 files changed, 206 insertions(+), 172 deletions(-) delete mode 100644 Templates/BaseGame/game/tools/resources/ReflectProbeSphere.asset.taml delete mode 100644 Templates/BaseGame/game/tools/resources/ReflectProbeSphere.dae delete mode 100644 Templates/BaseGame/game/tools/resources/ReflectProbeSphere.tscript create mode 100644 Templates/BaseGame/game/tools/resources/previewSphereShape.asset.taml create mode 100644 Templates/BaseGame/game/tools/resources/previewSphereShape.dae diff --git a/Engine/source/T3D/assets/ShapeAsset.cpp b/Engine/source/T3D/assets/ShapeAsset.cpp index c532d2370..c145965a1 100644 --- a/Engine/source/T3D/assets/ShapeAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAsset.cpp @@ -51,6 +51,9 @@ #endif #include "util/imposterCapture.h" +#include "ts/tsShapeInstance.h" +#include "gfx/bitmap/imageUtils.h" + StringTableEntry ShapeAsset::smNoShapeAssetFallback = NULL; //----------------------------------------------------------------------------- @@ -560,25 +563,94 @@ ShapeAnimationAsset* ShapeAsset::getAnimation(S32 index) } #ifdef TORQUE_TOOLS -const char* ShapeAsset::generateCachedPreviewImage(S32 resolution) +const char* ShapeAsset::generateCachedPreviewImage(S32 resolution, String overrideMaterial) { if (!mShape) return ""; - TSLastDetail* dt = new TSLastDetail(mShape, - mFilePath, - 1, - 0, - 0, - false, - 0, - resolution); + // We're gonna render... make sure we can. + bool sceneBegun = GFX->canCurrentlyRender(); + if (!sceneBegun) + GFX->beginScene(); - dt->update(); + // We need to create our own instance to render with. + TSShapeInstance* shape = new TSShapeInstance(mShape, true); - delete dt; + if(overrideMaterial.isNotEmpty()) + shape->reSkin(overrideMaterial, mShape->materialList->getMaterialName(0)); - return mFilePath; + // Animate the shape once. + shape->animate(0); + + // So we don't have to change it everywhere. + const GFXFormat format = GFXFormatR8G8B8A8; + + GBitmap* imposter = NULL; + GBitmap* imposterNrml = NULL; + + ImposterCapture* imposterCap = new ImposterCapture(); + + static const MatrixF topXfm(EulerF(-M_PI_F / 2.0f, 0, 0)); + static const MatrixF bottomXfm(EulerF(M_PI_F / 2.0f, 0, 0)); + + MatrixF angMat; + + S32 mip = 0; + + PROFILE_START(ShapeAsset_generateCachedPreviewImage); + + //dMemset(destBmp.getWritableBits(mip), 0, destBmp.getWidth(mip) * destBmp.getHeight(mip) * GFXFormat_getByteSize(format)); + + F32 rotX = -(mDegToRad(60.0) - 0.5f * M_PI_F); + F32 rotZ = -(mDegToRad(45.0) - 0.5f * M_PI_F); + + // We capture the images in a particular order which must + // match the order expected by the imposter renderer. + + imposterCap->begin(shape, 0, resolution, mShape->mRadius, mShape->center); + + angMat.mul(MatrixF(EulerF(rotX, 0, 0)), + MatrixF(EulerF(0, 0, rotZ))); + + imposterCap->capture(angMat, &imposter, &imposterNrml); + + imposterCap->end(); + + PROFILE_END(); // ShapeAsset_generateCachedPreviewImage + + delete imposterCap; + delete shape; + + String dumpPath = String(mFilePath) + "_Preview.dds"; + + char* returnBuffer = Con::getReturnBuffer(dumpPath.length()); + dSprintf(returnBuffer, dumpPath.length(), "%s", dumpPath.c_str()); + + /*FileStream stream; + if (stream.open(dumpPath, Torque::FS::File::Write)) + destBmp.writeBitmap("png", stream); + stream.close();*/ + + DDSFile* ddsDest = DDSFile::createDDSFileFromGBitmap(imposter); + ImageUtil::ddsCompress(ddsDest, GFXFormatBC2); + + // Finally save the imposters to disk. + FileStream fs; + if (fs.open(returnBuffer, Torque::FS::File::Write)) + { + ddsDest->write(fs); + fs.close(); + } + + delete ddsDest; + delete imposter; + delete imposterNrml; + + // If we did a begin then end it now. + if (!sceneBegun) + GFX->endScene(); + + return returnBuffer; } #endif @@ -625,9 +697,12 @@ DefineEngineMethod(ShapeAsset, getStatusString, String, (), , "get status string #ifdef TORQUE_TOOLS -DefineEngineMethod(ShapeAsset, generateCachedPreviewImage, const char*, (S32 resolution), (256), "") +DefineEngineMethod(ShapeAsset, generateCachedPreviewImage, const char*, (S32 resolution, const char* overrideMaterialName), (256, ""), + "Generates a baked preview image of the given shapeAsset. Only really used for generating Asset Browser icons.\n" + "@param resolution Optional field for what resolution to bake the preview image at. Must be pow2\n" + "@param overrideMaterialName Optional field for overriding the material used when rendering the shape for the bake.") { - return object->generateCachedPreviewImage(resolution); + return object->generateCachedPreviewImage(resolution, overrideMaterialName); } DefineEngineStaticMethod(ShapeAsset, getAssetIdByFilename, const char*, (const char* filePath), (""), diff --git a/Engine/source/T3D/assets/ShapeAsset.h b/Engine/source/T3D/assets/ShapeAsset.h index 7288ec515..c94cd8384 100644 --- a/Engine/source/T3D/assets/ShapeAsset.h +++ b/Engine/source/T3D/assets/ShapeAsset.h @@ -191,7 +191,7 @@ public: static U32 getAssetById(StringTableEntry assetId, AssetPtr* shapeAsset); #ifdef TORQUE_TOOLS - const char* generateCachedPreviewImage(S32 resolution); + const char* generateCachedPreviewImage(S32 resolution, String overrideMaterial = ""); #endif protected: diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index 985f4871c..9361b05f1 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -798,7 +798,7 @@ void ReflectionProbe::createEditorResources() mEditorShape = NULL; - String shapeFile = "tools/resources/ReflectProbeSphere.dae"; + String shapeFile = "tools/resources/previewSphereShape.dae"; // Attempt to get the resource from the ResourceManager mEditorShape = ResourceManager::get().load(shapeFile); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index 4363209a5..d70c6a4a5 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript @@ -433,7 +433,7 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) %generatePreview = false; - %previewFilePath = %previewPath @ %assetDef.assetName @ "_Preview.png"; + %previewFilePath = %previewPath @ %assetDef.assetName @ "_Preview.dds"; if(!isFile(%previewFilePath)) { %generatePreview = true; @@ -457,17 +457,11 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) if(isObject(%assetDef.materialDefinitionName)) { - if(isFile(%assetDef.materialDefinitionName.getDiffuseMap(0))) - { - %difMap = %assetDef.materialDefinitionName.getDiffuseMap(0); - } - else if(%assetDef.materialDefinitionName.getDiffuseMapAsset(0) !$= "") - { - %imgAsset = AssetDatabase.acquireAsset(%assetDef.materialDefinitionName.getDiffuseMapAsset(0)); - %difMap = %imgAsset.getImagePath(); - } + %previewShapeDef = AssetDatabase.acquireAsset("ToolsModule:previewSphereShape"); + %generatedFilePath = %previewShapeDef.generateCachedPreviewImage(256, %assetDef.materialDefinitionName); - %success = saveScaledImage(%difMap, %previewFilePath); + pathCopy(%generatedFilePath, %previewFilePath); + fileDelete(%generatedFilePath); %previewAsset = new ImageAsset() { diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript index 89f981438..f497a2e55 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript @@ -258,7 +258,7 @@ function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData) %generatePreview = false; - %previewFilePath = %previewPath @ %assetDef.assetName @ "_Preview.png"; + %previewFilePath = %previewPath @ %assetDef.assetName @ "_Preview.dds"; if(!isFile(%previewFilePath) || (compareFileTimes(%assetDef.getShapeFile(), %previewFilePath) == 1)) { %generatePreview = true; @@ -272,21 +272,11 @@ function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData) //This is slightly hacky, but we're going to utilize the imposter/last detail system //to generate our previews for us and then clean up the unneeded bits - %oldImposterSetting = $TSLastDetail::dumpImposters; - $TSLastDetail::dumpImposters = true; %filePath = %assetDef.generateCachedPreviewImage(); - %imposterPath = %filePath @ ".imposter.png"; - pathCopy(%imposterPath, %previewFilePath); - - //cleanup - fileDelete(%imposterPath); - fileDelete(%filePath @ ".imposter.dds"); - fileDelete(%filePath @ ".imposter_normals.png"); - fileDelete(%filePath @ ".imposter_normals.dds"); - - $TSLastDetail::dumpImposters = %oldImposterSetting; + pathCopy(%filePath, %previewFilePath); + fileDelete(%filePath); //cleanup %previewAsset = new ImageAsset() { diff --git a/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.asset.taml b/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.asset.taml deleted file mode 100644 index dfdd62395..000000000 --- a/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.asset.taml +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.dae b/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.dae deleted file mode 100644 index b488de77a..000000000 --- a/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.dae +++ /dev/null @@ -1,115 +0,0 @@ - - - - - Anonymous - Collada Exporter for Blender 2.6+, by Juan Linietsky (juan@codenix.com) - - 2016-09-06T21:59:07Z - 2016-09-06T21:59:07Z - - Z_UP - - - - - - - - - - 0.0 0.0 0.0 1.0 - - - 0.0 0.0 0.0 1.0 - - - 0.3737608488464481 0.3737608488464481 0.3737608488464481 1.0 - - - 0.0 0.0 0.0 1.0 - - - 50 - - - 1.0 1.0 1.0 1.0 - - - 4.0 - - - - - - - 0 - - - - - - - - - - - - - - - - -0.49039262533187866 0.0 0.09754517674446106 -0.49039262533187866 0.09754519164562225 3.774895063202166e-08 -0.5 0.0 3.774895063202166e-08 -0.09754516184329987 0.0 0.49039262533187866 1.2401747184753731e-08 -6.234699867491145e-08 0.5 -0.09567085653543472 0.019030148163437843 0.49039262533187866 1.6292068494294654e-07 0.0 -0.5 -0.09754504263401031 0.0 -0.49039265513420105 -0.09567073732614517 0.019030125811696053 -0.49039265513420105 -0.4809698760509491 0.09567089378833771 -0.09754510223865509 -0.49039265513420105 0.0 -0.09754510223865509 -0.1876651495695114 0.03732895478606224 0.4619397521018982 -0.19134172797203064 0.0 0.4619397521018982 -0.4619397819042206 0.0 -0.19134163856506348 -0.4530637264251709 0.09012001007795334 -0.19134163856506348 -0.27778512239456177 0.0 0.41573479771614075 -0.2724475562572479 0.054193224757909775 0.41573479771614075 -0.4077465832233429 0.08110587298870087 -0.2777850925922394 -0.41573482751846313 0.0 -0.2777850925922394 -0.34675994515419006 0.06897487491369247 0.3535533845424652 -0.3535533845424652 0.0 0.3535533845424652 -0.3535533845424652 0.0 -0.3535533845424652 -0.34675994515419006 0.06897487491369247 -0.3535533845424652 -0.4077465832233429 0.08110587298870087 0.2777850925922394 -0.41573482751846313 0.0 0.2777850925922394 -0.27244752645492554 0.05419321730732918 -0.41573482751846313 -0.2777850925922394 0.0 -0.41573482751846313 -0.4530636966228485 0.09012000262737274 0.19134171307086945 -0.4619397521018982 0.0 0.19134171307086945 -0.18766506016254425 0.03732893615961075 -0.46193981170654297 -0.19134163856506348 0.0 -0.46193981170654297 -0.4809698462486267 0.09567088633775711 0.09754517674446106 -0.17677661776542664 0.07322333753108978 -0.46193981170654297 -0.4530636668205261 0.187665194272995 0.09754517674446106 -0.0901198536157608 0.03732893243432045 -0.49039265513420105 -0.4619397222995758 0.19134177267551422 3.774895063202166e-08 -0.09011997282505035 0.03732898086309433 0.49039262533187866 -0.4530636668205261 0.187665194272995 -0.09754510223865509 -0.1767767071723938 0.07322336733341217 0.4619397521018982 -0.4267766773700714 0.17677675187587738 -0.19134163856506348 -0.2566399574279785 0.10630382597446442 0.41573479771614075 -0.3840888440608978 0.1590948849916458 -0.2777850925922394 -0.32664069533348083 0.13529908657073975 0.3535533845424652 -0.32664069533348083 0.13529908657073975 -0.3535533845424652 -0.3840888440608978 0.1590948849916458 0.2777850925922394 -0.25663992762565613 0.10630381107330322 -0.41573482751846313 -0.426776647567749 0.1767767369747162 0.19134171307086945 -0.3840888440608978 0.2566400468349457 -0.19134163856506348 -0.34567081928253174 0.23096996545791626 -0.2777850925922394 -0.2939688563346863 0.19642382860183716 0.3535533845424652 -0.2939688563346863 0.19642382860183716 -0.3535533845424652 -0.34567081928253174 0.23096996545791626 0.2777850925922394 -0.23096981644630432 0.15432921051979065 -0.41573482751846313 -0.38408881425857544 0.2566400468349457 0.19134171307086945 -0.15909473598003387 0.10630381107330322 -0.46193981170654297 -0.40774649381637573 0.2724476158618927 0.09754517674446106 -0.08110571652650833 0.05419320985674858 -0.49039265513420105 -0.41573473811149597 0.27778521180152893 3.774895063202166e-08 -0.08110581338405609 0.05419328436255455 0.49039262533187866 -0.40774649381637573 0.2724476158618927 -0.09754510223865509 -0.15909481048583984 0.1063038557767868 0.4619397521018982 -0.2309698462486267 0.15432922542095184 0.41573479771614075 -0.06897471845149994 0.06897486746311188 -0.49039265513420105 -0.3467598557472229 0.3467600345611572 0.09754517674446106 -0.35355329513549805 0.35355350375175476 3.774895063202166e-08 -0.0689748004078865 0.06897496432065964 0.49039262533187866 -0.3467598557472229 0.3467600345611572 -0.09754510223865509 -0.1352989822626114 0.13529914617538452 0.4619397521018982 -0.32664069533348083 0.3266408145427704 -0.19134163856506348 -0.19642367959022522 0.19642384350299835 0.41573479771614075 -0.2939688265323639 0.2939690053462982 -0.2777850925922394 -0.24999994039535522 0.25000008940696716 0.3535533845424652 -0.24999994039535522 0.25000008940696716 -0.3535533845424652 -0.2939688265323639 0.2939690053462982 0.2777850925922394 -0.19642364978790283 0.19642382860183716 -0.41573482751846313 -0.32664066553115845 0.3266408145427704 0.19134171307086945 -0.1352989375591278 0.13529908657073975 -0.46193981170654297 -0.19642364978790283 0.2939690053462982 0.3535533845424652 -0.19642364978790283 0.2939690053462982 -0.3535533845424652 -0.23096978664398193 0.3456709682941437 0.2777850925922394 -0.15432903170585632 0.23096996545791626 -0.41573482751846313 -0.25663989782333374 0.3840889632701874 0.19134171307086945 -0.10630366206169128 0.159094899892807 -0.46193981170654297 -0.272447407245636 0.40774664282798767 0.09754517674446106 -0.054193053394556046 0.08110586553812027 -0.49039265513420105 -0.2777850031852722 0.4157349169254303 3.774895063202166e-08 -0.05419311672449112 0.08110596984624863 0.49039262533187866 -0.272447407245636 0.40774664282798767 -0.09754510223865509 -0.10630369931459427 0.15909495949745178 0.4619397521018982 -0.25663992762565613 0.3840889632701874 -0.19134163856506348 -0.1543290615081787 0.23096999526023865 0.41573479771614075 -0.23096978664398193 0.3456709682941437 -0.2777850925922394 -0.1913415789604187 0.46193987131118774 3.774895063202166e-08 -0.0373288132250309 0.09012012183666229 0.49039262533187866 -0.037328775972127914 0.09012000262737274 -0.49039265513420105 -0.1876649558544159 0.4530637562274933 -0.09754510223865509 -0.07322321087121964 0.17677684128284454 0.4619397521018982 -0.17677661776542664 0.4267767667770386 -0.19134163856506348 -0.10630366206169128 0.25664010643959045 0.41573479771614075 -0.1590946912765503 0.38408899307250977 -0.2777850925922394 -0.13529890775680542 0.3266408443450928 0.3535533845424652 -0.13529890775680542 0.3266408443450928 -0.3535533845424652 -0.1590946912765503 0.38408899307250977 0.2777850925922394 -0.1063036322593689 0.25664007663726807 -0.41573482751846313 -0.17677658796310425 0.4267767667770386 0.19134171307086945 -0.07322318851947784 0.17677676677703857 -0.46193981170654297 -0.1876649558544159 0.4530637562274933 0.09754517674446106 -0.08110568672418594 0.40774667263031006 -0.2777850925922394 -0.06897471100091934 0.3467600643634796 -0.3535533845424652 -0.08110568672418594 0.40774667263031006 0.2777850925922394 -0.05419303476810455 0.2724476456642151 -0.41573482751846313 -0.0901198536157608 0.4530637860298157 0.19134171307086945 -0.03732877969741821 0.1876652091741562 -0.46193981170654297 -0.0956706702709198 0.4809699058532715 0.09754517674446106 -0.019029967486858368 0.09567087888717651 -0.49039265513420105 -0.09754499793052673 0.4903927445411682 3.774895063202166e-08 -0.019029982388019562 0.09567100554704666 0.49039262533187866 -0.0956706702709198 0.4809699058532715 -0.09754510223865509 -0.03732878714799881 0.18766528367996216 0.4619397521018982 -0.09011988341808319 0.4530637860298157 -0.19134163856506348 -0.054193057119846344 0.2724476754665375 0.41573479771614075 -0.06897471100091934 0.3467600643634796 0.3535533845424652 1.6331796359736472e-07 0.09754530340433121 0.49039262533187866 1.5400473785120994e-07 0.09754518419504166 -0.49039265513420105 1.8939499568659812e-07 0.5000001192092896 3.774895063202166e-08 1.9684557628352195e-07 0.49039262533187866 -0.09754510223865509 1.595926732989028e-07 0.1913418471813202 0.4619397521018982 1.1488918971735984e-07 0.46193984150886536 -0.19134163856506348 1.558673830004409e-07 0.2777852416038513 0.41573479771614075 1.6704325389582664e-07 0.4157348871231079 -0.2777850925922394 1.595926732989028e-07 0.3535534739494324 0.3535533845424652 1.595926732989028e-07 0.3535534739494324 -0.3535533845424652 1.6704325389582664e-07 0.4157348871231079 0.2777850925922394 1.7076854419428855e-07 0.27778518199920654 -0.41573482751846313 1.3724093150813133e-07 0.46193984150886536 0.19134171307086945 1.5214209270197898e-07 0.19134177267551422 -0.46193981170654297 1.9684557628352195e-07 0.49039262533187866 0.09754517674446106 0.06897501647472382 0.3467600345611572 0.3535533845424652 0.08110601454973221 0.40774664282798767 0.2777850925922394 0.06897501647472382 0.3467600345611572 -0.3535533845424652 0.05419337376952171 0.2724476158618927 -0.41573482751846313 0.09012012928724289 0.4530637860298157 0.19134171307086945 0.03732908144593239 0.187665194272995 -0.46193981170654297 0.09567105025053024 0.4809698462486267 0.09754517674446106 0.01903027668595314 0.09567087888717651 -0.49039265513420105 0.09754537045955658 0.4903927445411682 3.774895063202166e-08 0.019030308350920677 0.09567099809646606 0.49039262533187866 0.09567105025053024 0.4809698462486267 -0.09754510223865509 0.03732910379767418 0.18766526877880096 0.4619397521018982 0.0901201069355011 0.4530637860298157 -0.19134163856506348 0.054193370044231415 0.2724476754665375 0.41573479771614075 0.08110601454973221 0.40774664282798767 -0.2777850925922394 0.18766531348228455 0.4530636668205261 -0.09754510223865509 0.07322350889444351 0.17677681148052216 0.4619397521018982 0.17677682638168335 0.4267767667770386 -0.19134163856506348 0.10630396008491516 0.25664007663726807 0.41573479771614075 0.15909501910209656 0.3840889036655426 -0.2777850925922394 0.1352992057800293 0.3266408145427704 0.3535533845424652 0.1352992057800293 0.3266408145427704 -0.3535533845424652 0.15909501910209656 0.3840889036655426 0.2777850925922394 0.10630396008491516 0.2566400170326233 -0.41573482751846313 0.17677685618400574 0.4267767667770386 0.19134171307086945 0.07322347909212112 0.1767767369747162 -0.46193981170654297 0.18766531348228455 0.4530636668205261 0.09754517674446106 0.03732908144593239 0.09011999517679214 -0.49039265513420105 0.19134193658828735 0.46193984150886536 3.774895063202166e-08 0.03732913359999657 0.0901200994849205 0.49039262533187866 0.19642391800880432 0.29396897554397583 -0.3535533845424652 0.1543293297290802 0.23096990585327148 -0.41573482751846313 0.25664013624191284 0.384088933467865 0.19134171307086945 0.10630394518375397 0.15909485518932343 -0.46193981170654297 0.27244770526885986 0.4077465236186981 0.09754517674446106 0.05419335886836052 0.08110585063695908 -0.49039265513420105 0.2777853310108185 0.4157348573207855 3.774895063202166e-08 0.05419342592358589 0.08110594004392624 0.49039262533187866 0.27244770526885986 0.4077465236186981 -0.09754510223865509 0.10630397498607635 0.1590949296951294 0.4619397521018982 0.25664013624191284 0.384088933467865 -0.19134163856506348 0.1543293446302414 0.23096996545791626 0.41573479771614075 0.2309700846672058 0.3456708788871765 -0.2777850925922394 0.19642391800880432 0.29396897554397583 0.3535533845424652 0.2309700846672058 0.3456708788871765 0.2777850925922394 0.32664090394973755 0.3266408145427704 -0.19134163856506348 0.1964239478111267 0.19642379879951477 0.41573479771614075 0.2939690947532654 0.29396888613700867 -0.2777850925922394 0.2500001788139343 0.2500000298023224 0.3535533845424652 0.2500001788139343 0.2500000298023224 -0.3535533845424652 0.2939690947532654 0.29396888613700867 0.2777850925922394 0.19642391800880432 0.1964237540960312 -0.41573482751846313 0.32664090394973755 0.3266408145427704 0.19134171307086945 0.1352992057800293 0.13529904186725616 -0.46193981170654297 0.346760094165802 0.3467599153518677 0.09754517674446106 0.06897501647472382 0.06897485256195068 -0.49039265513420105 0.3535536229610443 0.3535534143447876 3.774895063202166e-08 0.06897509843111038 0.06897492706775665 0.49039262533187866 0.346760094165802 0.3467599153518677 -0.09754510223865509 0.13529925048351288 0.13529911637306213 0.4619397521018982 0.15909498929977417 0.10630377382040024 -0.46193981170654297 0.38408905267715454 0.2566400468349457 0.19134171307086945 0.40774670243263245 0.27244749665260315 0.09754517674446106 0.08110600709915161 0.05419319495558739 -0.49039265513420105 0.41573503613471985 0.27778512239456177 3.774895063202166e-08 0.08110609650611877 0.054193247109651566 0.49039262533187866 0.40774670243263245 0.27244749665260315 -0.09754510223865509 0.15909504890441895 0.10630382597446442 0.4619397521018982 0.38408905267715454 0.2566400468349457 -0.19134163856506348 0.2309700846672058 0.15432918071746826 0.41573479771614075 0.34567102789878845 0.2309698611497879 -0.2777850925922394 0.2939690947532654 0.1964237540960312 0.3535533845424652 0.2939690947532654 0.1964237540960312 -0.3535533845424652 0.34567102789878845 0.2309698611497879 0.2777850925922394 0.23097005486488342 0.15432913601398468 -0.41573482751846313 0.1767769157886505 0.07322335243225098 0.4619397521018982 0.2566401958465576 0.10630379617214203 0.41573479771614075 0.42677685618400574 0.1767767369747162 -0.19134163856506348 0.38408902287483215 0.15909478068351746 -0.2777850925922394 0.32664090394973755 0.13529901206493378 0.3535533845424652 0.32664090394973755 0.13529901206493378 -0.3535533845424652 0.38408902287483215 0.15909478068351746 0.2777850925922394 0.25664013624191284 0.10630375146865845 -0.41573482751846313 0.42677685618400574 0.1767767369747162 0.19134171307086945 0.17677685618400574 0.0732233077287674 -0.46193981170654297 0.45306381583213806 0.18766507506370544 0.09754517674446106 0.09012014418840408 0.03732892498373985 -0.49039265513420105 0.4619399905204773 0.19134169816970825 3.774895063202166e-08 0.09012024104595184 0.03732895851135254 0.49039262533187866 0.45306381583213806 0.18766507506370544 -0.09754510223865509 0.45306387543678284 0.09012001007795334 0.19134171307086945 0.48096996545791626 0.09567080438137054 0.09754517674446106 0.18766529858112335 0.037328921258449554 -0.46193981170654297 0.09567102044820786 0.019030120223760605 -0.49039265513420105 0.49039286375045776 0.09754512459039688 3.774895063202166e-08 0.09567112475633621 0.0190301351249218 0.49039262533187866 0.48096996545791626 0.09567080438137054 -0.09754510223865509 0.18766535818576813 0.03732895106077194 0.4619397521018982 0.45306387543678284 0.09012001007795334 -0.19134163856506348 0.27244776487350464 0.05419321358203888 0.41573479771614075 0.40774667263031006 0.0811057835817337 -0.2777850925922394 0.3467601239681244 0.06897483021020889 0.3535533845424652 0.3467601239681244 0.06897483021020889 -0.3535533845424652 0.40774667263031006 0.0811057835817337 0.2777850925922394 0.27244770526885986 0.05419318005442619 -0.41573482751846313 0.4619399309158325 3.1784249898691996e-08 -0.19134163856506348 0.4157348573207855 -4.2721556070546285e-08 -0.2777850925922394 0.2777853310108185 1.3157798406382426e-08 0.41573479771614075 0.35355353355407715 -1.2919233682850972e-08 0.3535533845424652 0.35355353355407715 -1.2919233682850972e-08 -0.3535533845424652 0.4157348573207855 -4.2721556070546285e-08 0.2777850925922394 0.2777852416038513 -5.468653085927144e-09 -0.41573482751846313 0.4619399309158325 3.1784249898691996e-08 0.19134171307086945 0.19134186208248138 1.981927510996684e-09 -0.46193981170654297 0.49039268493652344 -4.2721556070546285e-08 0.09754517674446106 0.0975453183054924 1.981927510996684e-09 -0.49039265513420105 0.5000001788139343 -5.017213666747011e-08 3.774895063202166e-08 0.09754542261362076 -3.6060079366961872e-09 0.49039262533187866 0.49039268493652344 -4.2721556070546285e-08 -0.09754510223865509 0.19134192168712616 2.0608379003306254e-08 0.4619397521018982 0.09567101299762726 -0.019030114635825157 -0.49039265513420105 0.490392804145813 -0.09754522144794464 3.774895063202166e-08 0.09567110985517502 -0.019030140712857246 0.49039262533187866 0.4809699058532715 -0.09567087888717651 -0.09754510223865509 0.18766532838344574 -0.03732890635728836 0.4619397521018982 0.45306387543678284 -0.09011995047330856 -0.19134163856506348 0.27244776487350464 -0.05419318377971649 0.41573479771614075 0.4077466130256653 -0.08110586553812027 -0.2777850925922394 0.346760094165802 -0.06897486001253128 0.3535533845424652 0.346760094165802 -0.06897486001253128 -0.3535533845424652 0.4077466130256653 -0.08110586553812027 0.2777850925922394 0.2724476754665375 -0.05419318377971649 -0.41573482751846313 0.45306387543678284 -0.09011995047330856 0.19134171307086945 0.18766526877880096 -0.03732891008257866 -0.46193981170654297 0.4809699058532715 -0.09567087888717651 0.09754517674446106 0.2566401958465576 -0.10630376636981964 0.41573479771614075 0.32664087414741516 -0.13529902696609497 0.3535533845424652 0.32664087414741516 -0.13529902696609497 -0.3535533845424652 0.3840888738632202 -0.15909482538700104 0.2777850925922394 0.25664010643959045 -0.10630375146865845 -0.41573482751846313 0.42677685618400574 -0.17677666246891022 0.19134171307086945 0.17677681148052216 -0.0732232928276062 -0.46193981170654297 0.4530637264251709 -0.18766513466835022 0.09754517674446106 0.09012012183666229 -0.03732891008257866 -0.49039265513420105 0.46193990111351013 -0.19134178757667542 3.774895063202166e-08 0.09012021869421005 -0.03732895478606224 0.49039262533187866 0.4530637264251709 -0.18766513466835022 -0.09754510223865509 0.17677687108516693 -0.0732233002781868 0.4619397521018982 0.42677685618400574 -0.17677666246891022 -0.19134163856506348 0.3840888738632202 -0.15909482538700104 -0.2777850925922394 0.4157349169254303 -0.27778518199920654 3.774895063202166e-08 0.08110606670379639 -0.05419323593378067 0.49039262533187866 0.08110597729682922 -0.054193172603845596 -0.49039265513420105 0.4077465832233429 -0.27244752645492554 -0.09754510223865509 0.15909498929977417 -0.10630375891923904 0.4619397521018982 0.38408902287483215 -0.2566399574279785 -0.19134163856506348 0.2309700846672058 -0.15432915091514587 0.41573479771614075 0.3456708490848541 -0.2309698462486267 -0.2777850925922394 0.2939690351486206 -0.19642373919487 0.3535533845424652 0.2939690351486206 -0.19642373919487 -0.3535533845424652 0.3456708490848541 -0.2309698462486267 0.2777850925922394 0.23096999526023865 -0.1543291211128235 -0.41573482751846313 0.38408902287483215 -0.2566399574279785 0.19134171307086945 0.1590949296951294 -0.10630373656749725 -0.46193981170654297 0.4077465832233429 -0.27244752645492554 0.09754517674446106 0.25000011920928955 -0.25 -0.3535533845424652 0.25000011920928955 -0.25 0.3535533845424652 0.29396888613700867 -0.2939688265323639 0.2777850925922394 0.19642384350299835 -0.1964237093925476 -0.41573482751846313 0.32664087414741516 -0.32664069533348083 0.19134171307086945 0.13529913127422333 -0.13529899716377258 -0.46193981170654297 0.34675994515419006 -0.3467598855495453 0.09754517674446106 0.06897498667240143 -0.0689748227596283 -0.49039265513420105 0.3535534739494324 -0.35355344414711 3.774895063202166e-08 0.0689750611782074 -0.06897490471601486 0.49039262533187866 0.34675994515419006 -0.3467598855495453 -0.09754510223865509 0.1352991759777069 -0.13529902696609497 0.4619397521018982 0.32664087414741516 -0.32664069533348083 -0.19134163856506348 0.19642393290996552 -0.1964237540960312 0.41573479771614075 0.29396888613700867 -0.2939688265323639 -0.2777850925922394 0.05419332906603813 -0.08110581338405609 -0.49039265513420105 0.27244752645492554 -0.40774646401405334 -0.09754510223865509 0.10630390048027039 -0.15909482538700104 0.4619397521018982 0.25664013624191284 -0.3840888440608978 -0.19134163856506348 0.154329314827919 -0.2309698909521103 0.41573479771614075 0.2309698909521103 -0.34567075967788696 -0.2777850925922394 0.19642385840415955 -0.29396888613700867 0.3535533845424652 0.19642385840415955 -0.29396888613700867 -0.3535533845424652 0.2309698909521103 -0.34567075967788696 0.2777850925922394 0.15432924032211304 -0.2309698462486267 -0.41573482751846313 0.25664013624191284 -0.3840888440608978 0.19134171307086945 0.1063038557767868 -0.15909478068351746 -0.46193981170654297 0.27244752645492554 -0.40774646401405334 0.09754517674446106 0.27778518199920654 -0.41573482751846313 3.774895063202166e-08 0.05419338867068291 -0.08110590279102325 0.49039262533187866 0.106303870677948 -0.25663992762565613 -0.41573482751846313 0.17677685618400574 -0.4267766773700714 0.19134171307086945 0.07322340458631516 -0.17677663266658783 -0.46193981170654297 0.18766511976718903 -0.45306357741355896 0.09754517674446106 0.0373290590941906 -0.09011994302272797 -0.49039265513420105 0.19134177267551422 -0.4619397521018982 3.774895063202166e-08 0.03732910379767418 -0.09012004733085632 0.49039262533187866 0.18766511976718903 -0.45306357741355896 -0.09754510223865509 0.07322343438863754 -0.1767766773700714 0.4619397521018982 0.17677685618400574 -0.4267766773700714 -0.19134163856506348 0.10630391538143158 -0.2566399872303009 0.41573479771614075 0.15909484028816223 -0.3840887248516083 -0.2777850925922394 0.13529913127422333 -0.3266407251358032 0.3535533845424652 0.13529913127422333 -0.3266407251358032 -0.3535533845424652 0.15909484028816223 -0.3840887248516083 0.2777850925922394 0.019030287861824036 -0.09567093104124069 0.49039262533187866 0.03732905164361 -0.18766510486602783 0.4619397521018982 0.09012013673782349 -0.4530636966228485 -0.19134163856506348 0.05419333279132843 -0.2724475562572479 0.41573479771614075 0.08110587298870087 -0.40774640440940857 -0.2777850925922394 0.06897494196891785 -0.34675994515419006 0.3535533845424652 0.06897494196891785 -0.34675994515419006 -0.3535533845424652 0.08110587298870087 -0.40774640440940857 0.2777850925922394 0.05419331043958664 -0.27244749665260315 -0.41573482751846313 0.09012013673782349 -0.4530636966228485 0.19134171307086945 0.03732902929186821 -0.18766506016254425 -0.46193981170654297 0.09567087143659592 -0.48096969723701477 0.09754517674446106 0.019030267372727394 -0.09567081928253174 -0.49039265513420105 0.09754522144794464 -0.4903925955295563 3.774895063202166e-08 0.09567087143659592 -0.48096969723701477 -0.09754510223865509 1.595926732989028e-07 -0.4619397222995758 0.19134171307086945 1.297903509112075e-07 -0.2777850329875946 -0.41573482751846313 1.2606506061274558e-07 -0.19134162366390228 -0.46193981170654297 4.783396434504539e-08 -0.49039241671562195 0.09754517674446106 1.5773002814967185e-07 -0.09754512459039688 -0.49039265513420105 7.018570613581687e-08 -0.49999991059303284 3.774895063202166e-08 1.558673830004409e-07 -0.09754522889852524 0.49039262533187866 4.783396434504539e-08 -0.49039241671562195 -0.09754510223865509 1.4096622180659324e-07 -0.19134168326854706 0.4619397521018982 1.595926732989028e-07 -0.4619397222995758 -0.19134163856506348 1.4096622180659324e-07 -0.2777850925922394 0.41573479771614075 7.018570613581687e-08 -0.4157346189022064 -0.2777850925922394 9.253744792658836e-08 -0.3535533547401428 0.3535533845424652 9.253744792658836e-08 -0.3535533547401428 -0.3535533845424652 7.018570613581687e-08 -0.4157346189022064 0.2777850925922394 -0.09011981636285782 -0.4530636668205261 -0.19134163856506348 -0.05419304221868515 -0.27244752645492554 0.41573479771614075 -0.08110573142766953 -0.4077463448047638 -0.2777850925922394 -0.06897474825382233 -0.3467599153518677 0.3535533845424652 -0.06897474825382233 -0.3467599153518677 -0.3535533845424652 -0.08110573142766953 -0.4077463448047638 0.2777850925922394 -0.05419304221868515 -0.27244746685028076 -0.41573482751846313 -0.09011981636285782 -0.4530636668205261 0.19134171307086945 -0.037328772246837616 -0.18766504526138306 -0.46193981170654297 -0.09567076712846756 -0.4809696078300476 0.09754517674446106 -0.019029950723052025 -0.09567081928253174 -0.49039265513420105 -0.0975450798869133 -0.4903925061225891 3.774895063202166e-08 -0.019029973074793816 -0.0956709235906601 0.49039262533187866 -0.09567076712846756 -0.4809696078300476 -0.09754510223865509 -0.03732876852154732 -0.18766510486602783 0.4619397521018982 -0.10630360245704651 -0.25663986802101135 -0.41573482751846313 -0.07322314381599426 -0.17677660286426544 -0.46193981170654297 -0.17677652835845947 -0.426776647567749 0.19134171307086945 -0.18766498565673828 -0.453063428401947 0.09754517674446106 -0.03732874244451523 -0.09011994302272797 -0.49039265513420105 -0.1913416087627411 -0.46193960309028625 3.774895063202166e-08 -0.03732878342270851 -0.09012003988027573 0.49039262533187866 -0.18766498565673828 -0.453063428401947 -0.09754510223865509 -0.07322315126657486 -0.17677666246891022 0.4619397521018982 -0.17677652835845947 -0.426776647567749 -0.19134163856506348 -0.1063036173582077 -0.25663992762565613 0.41573479771614075 -0.1590946763753891 -0.3840886354446411 -0.2777850925922394 -0.1352989226579666 -0.32664066553115845 0.3535533845424652 -0.1352989226579666 -0.32664066553115845 -0.3535533845424652 -0.1590946763753891 -0.3840886354446411 0.2777850925922394 -0.10630360245704651 -0.15909478068351746 0.4619397521018982 -0.15432898700237274 -0.23096981644630432 0.41573479771614075 -0.2566398084163666 -0.38408881425857544 -0.19134163856506348 -0.23096969723701477 -0.345670610666275 -0.2777850925922394 -0.19642361998558044 -0.2939688265323639 0.3535533845424652 -0.19642361998558044 -0.2939688265323639 -0.3535533845424652 -0.23096969723701477 -0.345670610666275 0.2777850925922394 -0.15432895720005035 -0.23096975684165955 -0.41573482751846313 -0.2566398084163666 -0.38408881425857544 0.19134171307086945 -0.10630358010530472 -0.15909472107887268 -0.46193981170654297 -0.2724473476409912 -0.407746285200119 0.09754517674446106 -0.05419300124049187 -0.0811058059334755 -0.49039265513420105 -0.27778497338294983 -0.4157346189022064 3.774895063202166e-08 -0.05419306457042694 -0.08110588788986206 0.49039262533187866 -0.2724473476409912 -0.407746285200119 -0.09754510223865509 -0.3266405463218689 -0.32664069533348083 0.19134171307086945 -0.3467596769332886 -0.3467596769332886 0.09754517674446106 -0.06897465884685516 -0.0689748153090477 -0.49039265513420105 -0.3535532057285309 -0.3535531759262085 3.774895063202166e-08 -0.06897473335266113 -0.06897488236427307 0.49039262533187866 -0.3467596769332886 -0.3467596769332886 -0.09754510223865509 -0.13529884815216064 -0.1352989673614502 0.4619397521018982 -0.3266405463218689 -0.32664069533348083 -0.19134163856506348 -0.19642357528209686 -0.19642366468906403 0.41573479771614075 -0.29396867752075195 -0.29396864771842957 -0.2777850925922394 -0.24999986588954926 -0.24999992549419403 0.3535533845424652 -0.24999986588954926 -0.24999992549419403 -0.3535533845424652 -0.29396867752075195 -0.29396864771842957 0.2777850925922394 -0.19642353057861328 -0.19642361998558044 -0.41573482751846313 -0.13529881834983826 -0.1352989375591278 -0.46193981170654297 -0.3840886652469635 -0.25663992762565613 -0.19134163856506348 -0.34567058086395264 -0.2309696525335312 -0.2777850925922394 -0.29396873712539673 -0.19642364978790283 0.3535533845424652 -0.29396873712539673 -0.19642364978790283 -0.3535533845424652 -0.34567058086395264 -0.2309696525335312 0.2777850925922394 -0.2309696525335312 -0.15432903170585632 -0.41573482751846313 -0.3840886652469635 -0.25663992762565613 0.19134171307086945 -0.15909460186958313 -0.10630368441343307 -0.46193981170654297 -0.40774622559547424 -0.27244728803634644 0.09754517674446106 -0.08110564947128296 -0.0541931614279747 -0.49039265513420105 -0.41573455929756165 -0.27778491377830505 3.774895063202166e-08 -0.08110573142766953 -0.05419321358203888 0.49039262533187866 -0.40774622559547424 -0.27244728803634644 -0.09754510223865509 -0.15909463167190552 -0.10630370676517487 0.4619397521018982 -0.23096969723701477 -0.1543290615081787 0.41573479771614075 -0.09011978656053543 -0.037328895181417465 -0.49039265513420105 -0.4619394540786743 -0.19134151935577393 3.774895063202166e-08 -0.09011988341808319 -0.03732892870903015 0.49039262533187866 -0.45306330919265747 -0.18766489624977112 -0.09754510223865509 -0.17677649855613708 -0.07322325557470322 0.4619397521018982 -0.4267764687538147 -0.17677664756774902 -0.19134163856506348 -0.2566397786140442 -0.10630369186401367 0.41573479771614075 -0.38408854603767395 -0.15909460186958313 -0.2777850925922394 -0.3266405761241913 -0.1352989375591278 0.3535533845424652 -0.3266405761241913 -0.1352989375591278 -0.3535533845424652 -0.38408854603767395 -0.15909460186958313 0.2777850925922394 -0.2566397190093994 -0.10630366206169128 -0.41573482751846313 -0.4267764687538147 -0.17677664756774902 0.19134171307086945 -0.1767764687538147 -0.07322324067354202 -0.46193981170654297 -0.45306330919265747 -0.18766489624977112 0.09754517674446106 -0.34675976634025574 -0.06897476315498352 -0.3535533845424652 -0.34675976634025574 -0.06897476315498352 0.3535533845424652 -0.40774619579315186 -0.08110565692186356 0.2777850925922394 -0.27244725823402405 -0.054193101823329926 -0.41573482751846313 -0.4530634880065918 -0.09011993557214737 0.19134171307086945 -0.18766489624977112 -0.03732886165380478 -0.46193981170654297 -0.4809694290161133 -0.0956706702709198 0.09754517674446106 -0.0956706628203392 -0.019030101597309113 -0.49039265513420105 -0.49039226770401 -0.09754499047994614 3.774895063202166e-08 -0.09567075967788696 -0.019030112773180008 0.49039262533187866 -0.4809694290161133 -0.0956706702709198 -0.09754510223865509 -0.1876649260520935 -0.037328869104385376 0.4619397521018982 -0.4530634880065918 -0.09011993557214737 -0.19134163856506348 -0.2724473178386688 -0.05419312044978142 0.41573479771614075 -0.40774619579315186 -0.08110565692186356 -0.2777850925922394 - - - - - - - - - - -0.9809869527816772 0.0 0.19391460716724396 -0.9807733297348022 0.19507431983947754 0.0 -1.0 0.0 0.0 -0.20096439123153687 0.0 0.9795831441879272 0.0 0.0 1.0 -0.19708853960037231 0.039185766130685806 0.9795831441879272 0.0 0.0 -1.0 -0.20096439123153687 0.0 -0.9795831441879272 -0.19708853960037231 0.039185766130685806 -0.9795831441879272 -0.9621570706367493 0.191381573677063 -0.19391460716724396 -0.9809869527816772 0.0 -0.19391460716724396 -0.3804132342338562 0.07565538585186005 0.921689510345459 -0.3878597319126129 0.0 0.921689510345459 -0.9247413277626038 0.0 -0.3805353045463562 -0.9069795608520508 0.18039490282535553 -0.3805353045463562 -0.5597705245018005 0.0 0.8286385536193848 -0.5489974617958069 0.10919522494077682 0.8286385536193848 -0.8173161745071411 0.16257210075855255 -0.5527512431144714 -0.8333384394645691 0.0 -0.5527512431144714 -0.6964934468269348 0.13852351903915405 0.7040314674377441 -0.7101352214813232 0.0 0.7040314674377441 -0.7101352214813232 0.0 -0.7040314674377441 -0.6964934468269348 0.13852351903915405 -0.7040314674377441 -0.8173161745071411 0.16257210075855255 0.5527512431144714 -0.8333384394645691 0.0 0.5527512431144714 -0.5489974617958069 0.10919522494077682 -0.8286385536193848 -0.5597705245018005 0.0 -0.8286385536193848 -0.9069795608520508 0.18039490282535553 0.3805353045463562 -0.9247413277626038 0.0 0.3805353045463562 -0.3804132342338562 0.07565538585186005 -0.921689510345459 -0.3878597319126129 0.0 -0.921689510345459 -0.9621570706367493 0.191381573677063 0.19391460716724396 -0.3583483397960663 0.14841151237487793 -0.921689510345459 -0.9063386917114258 0.3754081726074219 0.19391460716724396 -0.18564409017562866 0.07690664380788803 -0.9795831441879272 -0.9238563179969788 0.382671594619751 0.0 -0.18564409017562866 0.07690664380788803 0.9795831441879272 -0.9063386917114258 0.3754081726074219 -0.19391460716724396 -0.3583483397960663 0.14841151237487793 0.921689510345459 -0.8543656468391418 0.35389262437820435 -0.3805353045463562 -0.5171361565589905 0.2142094224691391 0.8286385536193848 -0.7698904275894165 0.3188879191875458 -0.5527512431144714 -0.6560564041137695 0.2717368006706238 0.7040314674377441 -0.6560564041137695 0.2717368006706238 -0.7040314674377441 -0.7698904275894165 0.3188879191875458 0.5527512431144714 -0.5171361565589905 0.2142094224691391 -0.8286385536193848 -0.8543656468391418 0.35386210680007935 0.3805353045463562 -0.7689138650894165 0.5137485861778259 -0.3805353045463562 -0.6928922533988953 0.46296578645706177 -0.5527512431144714 -0.5904415845870972 0.39451277256011963 0.7040314674377441 -0.5904415845870972 0.39451277256011963 -0.7040314674377441 -0.6928922533988953 0.46296578645706177 0.5527512431144714 -0.46540728211402893 0.3109835982322693 -0.8286385536193848 -0.7689138650894165 0.5137485861778259 0.3805353045463562 -0.32248908281326294 0.2154911905527115 -0.921689510345459 -0.8156682252883911 0.5449995398521423 0.19391460716724396 -0.1670888364315033 0.1116367056965828 -0.9795831441879272 -0.8314462900161743 0.5555589199066162 0.0 -0.1670888364315033 0.1116367056965828 0.9795831441879272 -0.8156682252883911 0.5449995398521423 -0.19391460716724396 -0.32248908281326294 0.2154911905527115 0.921689510345459 -0.46540728211402893 0.3109835982322693 0.8286385536193848 -0.1420941799879074 0.1420941799879074 -0.9795831441879272 -0.6936551928520203 0.6936551928520203 0.19391460716724396 -0.7070833444595337 0.7070833444595337 0.0 -0.1420941799879074 0.1420941799879074 0.9795831441879272 -0.6936551928520203 0.6936551928520203 -0.19391460716724396 -0.27426984906196594 0.27426984906196594 0.921689510345459 -0.6538895964622498 0.6538895964622498 -0.3805353045463562 -0.395794540643692 0.395794540643692 0.8286385536193848 -0.5892513990402222 0.5892513990402222 -0.5527512431144714 -0.5021210312843323 0.5021210312843323 0.7040314674377441 -0.5021210312843323 0.5021210312843323 -0.7040314674377441 -0.5892513990402222 0.5892513990402222 0.5527512431144714 -0.395794540643692 0.395794540643692 -0.8286385536193848 -0.6538895964622498 0.6538895964622498 0.3805353045463562 -0.27426984906196594 0.27426984906196594 -0.921689510345459 -0.39451277256011963 0.5904415845870972 0.7040314674377441 -0.39451277256011963 0.5904415845870972 -0.7040314674377441 -0.46296578645706177 0.6928922533988953 0.5527512431144714 -0.3109835982322693 0.46540728211402893 -0.8286385536193848 -0.5137485861778259 0.7689138650894165 0.3805353045463562 -0.2154911905527115 0.32248908281326294 -0.921689510345459 -0.5449995398521423 0.8156682252883911 0.19391460716724396 -0.1116367056965828 0.1670888364315033 -0.9795831441879272 -0.5555589199066162 0.8314462900161743 0.0 -0.1116367056965828 0.1670888364315033 0.9795831441879272 -0.5449995398521423 0.8156682252883911 -0.19391460716724396 -0.2154911905527115 0.32248908281326294 0.921689510345459 -0.5137485861778259 0.7689138650894165 -0.3805353045463562 -0.3109835982322693 0.46540728211402893 0.8286385536193848 -0.46296578645706177 0.6928922533988953 -0.5527512431144714 -0.382671594619751 0.9238563179969788 0.0 -0.07690664380788803 0.18564409017562866 0.9795831441879272 -0.07690664380788803 0.18564409017562866 -0.9795831441879272 -0.3754081726074219 0.9063386917114258 -0.19391460716724396 -0.14841151237487793 0.3583483397960663 0.921689510345459 -0.35386210680007935 0.8543656468391418 -0.3805353045463562 -0.2142094224691391 0.5171361565589905 0.8286385536193848 -0.3188879191875458 0.7698904275894165 -0.5527512431144714 -0.2717368006706238 0.6560564041137695 0.7040314674377441 -0.2717368006706238 0.6560564041137695 -0.7040314674377441 -0.3188879191875458 0.7698904275894165 0.5527512431144714 -0.2142094224691391 0.5171361565589905 -0.8286385536193848 -0.35386210680007935 0.8543656468391418 0.3805353045463562 -0.14841151237487793 0.3583483397960663 -0.921689510345459 -0.3754081726074219 0.9063386917114258 0.19391460716724396 -0.16257210075855255 0.8173161745071411 -0.5527512431144714 -0.13852351903915405 0.6964934468269348 -0.7040314674377441 -0.16257210075855255 0.8173161745071411 0.5527512431144714 -0.10919522494077682 0.5489974617958069 -0.8286385536193848 -0.18039490282535553 0.9069795608520508 0.3805353045463562 -0.07565538585186005 0.3804132342338562 -0.921689510345459 -0.191381573677063 0.9621570706367493 0.19391460716724396 -0.039185766130685806 0.19708853960037231 -0.9795831441879272 -0.19507431983947754 0.9807733297348022 0.0 -0.039185766130685806 0.19708853960037231 0.9795831441879272 -0.191381573677063 0.9621570706367493 -0.19391460716724396 -0.07565538585186005 0.3804132342338562 0.921689510345459 -0.18039490282535553 0.9069795608520508 -0.3805353045463562 -0.10919522494077682 0.5489974617958069 0.8286385536193848 -0.13852351903915405 0.6964934468269348 0.7040314674377441 0.0 0.20096439123153687 0.9795831441879272 0.0 0.20096439123153687 -0.9795831441879272 0.0 1.0 0.0 0.0 0.9809869527816772 -0.19391460716724396 0.0 0.3878597319126129 0.921689510345459 0.0 0.9247413277626038 -0.3805353045463562 0.0 0.5597705245018005 0.8286385536193848 0.0 0.8333384394645691 -0.5527512431144714 0.0 0.7101352214813232 0.7040314674377441 0.0 0.7101352214813232 -0.7040314674377441 0.0 0.8333384394645691 0.5527512431144714 0.0 0.5597705245018005 -0.8286385536193848 0.0 0.9247413277626038 0.3805353045463562 0.0 0.3878597319126129 -0.921689510345459 0.0 0.9809869527816772 0.19391460716724396 0.13852351903915405 0.6964934468269348 0.7040314674377441 0.16257210075855255 0.8173161745071411 0.5527512431144714 0.13852351903915405 0.6964934468269348 -0.7040314674377441 0.10919522494077682 0.5489974617958069 -0.8286385536193848 0.18039490282535553 0.9069795608520508 0.3805353045463562 0.07565538585186005 0.3804132342338562 -0.921689510345459 0.191381573677063 0.9621570706367493 0.19391460716724396 0.039185766130685806 0.19708853960037231 -0.9795831441879272 0.19507431983947754 0.9807733297348022 0.0 0.039185766130685806 0.19708853960037231 0.9795831441879272 0.191381573677063 0.9621570706367493 -0.19391460716724396 0.07565538585186005 0.3804132342338562 0.921689510345459 0.18039490282535553 0.9069795608520508 -0.3805353045463562 0.10919522494077682 0.5489974617958069 0.8286385536193848 0.16257210075855255 0.8173161745071411 -0.5527512431144714 0.3754081726074219 0.9063386917114258 -0.19391460716724396 0.14841151237487793 0.3583483397960663 0.921689510345459 0.35386210680007935 0.8543656468391418 -0.3805353045463562 0.2142094224691391 0.5171361565589905 0.8286385536193848 0.3188879191875458 0.7698904275894165 -0.5527512431144714 0.2717368006706238 0.6560564041137695 0.7040314674377441 0.2717368006706238 0.6560564041137695 -0.7040314674377441 0.3188879191875458 0.7698904275894165 0.5527512431144714 0.2142094224691391 0.5171361565589905 -0.8286385536193848 0.35386210680007935 0.8543656468391418 0.3805353045463562 0.14841151237487793 0.3583483397960663 -0.921689510345459 0.3754081726074219 0.9063386917114258 0.19391460716724396 0.07690664380788803 0.18564409017562866 -0.9795831441879272 0.382671594619751 0.9238563179969788 0.0 0.07690664380788803 0.18564409017562866 0.9795831441879272 0.39451277256011963 0.5904415845870972 -0.7040314674377441 0.3109835982322693 0.46540728211402893 -0.8286385536193848 0.5137485861778259 0.7689138650894165 0.3805353045463562 0.2154911905527115 0.32248908281326294 -0.921689510345459 0.5449995398521423 0.8156682252883911 0.19391460716724396 0.1116367056965828 0.1670888364315033 -0.9795831441879272 0.5555589199066162 0.8314462900161743 0.0 0.1116367056965828 0.1670888364315033 0.9795831441879272 0.5449995398521423 0.8156682252883911 -0.19391460716724396 0.2154911905527115 0.32248908281326294 0.921689510345459 0.5137485861778259 0.7689138650894165 -0.3805353045463562 0.3109835982322693 0.46540728211402893 0.8286385536193848 0.46296578645706177 0.6928922533988953 -0.5527512431144714 0.39451277256011963 0.5904415845870972 0.7040314674377441 0.46296578645706177 0.6928922533988953 0.5527512431144714 0.6538895964622498 0.6538895964622498 -0.3805353045463562 0.395794540643692 0.395794540643692 0.8286385536193848 0.5892513990402222 0.5892513990402222 -0.5527512431144714 0.5021210312843323 0.5021210312843323 0.7040314674377441 0.5021210312843323 0.5021210312843323 -0.7040314674377441 0.5892513990402222 0.5892513990402222 0.5527512431144714 0.395794540643692 0.395794540643692 -0.8286385536193848 0.6538895964622498 0.6538895964622498 0.3805353045463562 0.27426984906196594 0.27426984906196594 -0.921689510345459 0.6936551928520203 0.6936551928520203 0.19391460716724396 0.1420941799879074 0.1420941799879074 -0.9795831441879272 0.7070833444595337 0.7070833444595337 0.0 0.1420941799879074 0.1420941799879074 0.9795831441879272 0.6936551928520203 0.6936551928520203 -0.19391460716724396 0.27426984906196594 0.27426984906196594 0.921689510345459 0.32248908281326294 0.2154911905527115 -0.921689510345459 0.7689138650894165 0.5137485861778259 0.3805353045463562 0.8156682252883911 0.5449995398521423 0.19391460716724396 0.1670888364315033 0.1116367056965828 -0.9795831441879272 0.8314462900161743 0.5555589199066162 0.0 0.1670888364315033 0.1116367056965828 0.9795831441879272 0.8156682252883911 0.5449995398521423 -0.19391460716724396 0.32248908281326294 0.2154911905527115 0.921689510345459 0.7689138650894165 0.5137485861778259 -0.3805353045463562 0.46540728211402893 0.3109835982322693 0.8286385536193848 0.6928922533988953 0.46296578645706177 -0.5527512431144714 0.5904415845870972 0.39451277256011963 0.7040314674377441 0.5904415845870972 0.39451277256011963 -0.7040314674377441 0.6928922533988953 0.46296578645706177 0.5527512431144714 0.46540728211402893 0.3109835982322693 -0.8286385536193848 0.3583483397960663 0.14841151237487793 0.921689510345459 0.5171361565589905 0.2142094224691391 0.8286385536193848 0.8543656468391418 0.35386210680007935 -0.3805353045463562 0.7698904275894165 0.3188879191875458 -0.5527512431144714 0.6560564041137695 0.2717368006706238 0.7040314674377441 0.6560564041137695 0.2717368006706238 -0.7040314674377441 0.7698904275894165 0.3188879191875458 0.5527512431144714 0.5171361565589905 0.2142094224691391 -0.8286385536193848 0.8543656468391418 0.35386210680007935 0.3805353045463562 0.3583483397960663 0.14841151237487793 -0.921689510345459 0.9063386917114258 0.3754081726074219 0.19391460716724396 0.18564409017562866 0.07690664380788803 -0.9795831441879272 0.9238563179969788 0.382671594619751 0.0 0.18564409017562866 0.07690664380788803 0.9795831441879272 0.9063386917114258 0.3754081726074219 -0.19391460716724396 0.9069795608520508 0.18039490282535553 0.3805353045463562 0.9621570706367493 0.191381573677063 0.19391460716724396 0.3804132342338562 0.07565538585186005 -0.921689510345459 0.19708853960037231 0.039185766130685806 -0.9795831441879272 0.9807733297348022 0.19507431983947754 0.0 0.19708853960037231 0.039185766130685806 0.9795831441879272 0.9621570706367493 0.191381573677063 -0.19391460716724396 0.3804132342338562 0.07565538585186005 0.921689510345459 0.9069795608520508 0.18039490282535553 -0.3805353045463562 0.5489974617958069 0.10919522494077682 0.8286385536193848 0.8173161745071411 0.16257210075855255 -0.5527512431144714 0.6964934468269348 0.13852351903915405 0.7040314674377441 0.6964934468269348 0.13852351903915405 -0.7040314674377441 0.8173161745071411 0.16257210075855255 0.5527512431144714 0.5489974617958069 0.10919522494077682 -0.8286385536193848 0.9247413277626038 0.0 -0.3805353045463562 0.8333384394645691 0.0 -0.5527512431144714 0.5597705245018005 0.0 0.8286385536193848 0.7101352214813232 0.0 0.7040314674377441 0.7101352214813232 0.0 -0.7040314674377441 0.8333384394645691 0.0 0.5527512431144714 0.5597705245018005 0.0 -0.8286385536193848 0.9247413277626038 0.0 0.3805353045463562 0.3878597319126129 0.0 -0.921689510345459 0.9809869527816772 0.0 0.19391460716724396 0.20096439123153687 0.0 -0.9795831441879272 1.0 0.0 0.0 0.20096439123153687 0.0 0.9795831441879272 0.9809869527816772 0.0 -0.19391460716724396 0.3878597319126129 0.0 0.921689510345459 0.19708853960037231 -0.039185766130685806 -0.9795831441879272 0.9807733297348022 -0.19507431983947754 0.0 0.19708853960037231 -0.039185766130685806 0.9795831441879272 0.9621570706367493 -0.191381573677063 -0.19391460716724396 0.3804132342338562 -0.07565538585186005 0.921689510345459 0.9069795608520508 -0.18039490282535553 -0.3805353045463562 0.5489974617958069 -0.10919522494077682 0.8286385536193848 0.8173161745071411 -0.16257210075855255 -0.5527512431144714 0.6964934468269348 -0.13852351903915405 0.7040314674377441 0.6964934468269348 -0.13852351903915405 -0.7040314674377441 0.8173161745071411 -0.16257210075855255 0.5527512431144714 0.5489974617958069 -0.10919522494077682 -0.8286385536193848 0.9069795608520508 -0.18039490282535553 0.3805353045463562 0.3804132342338562 -0.07565538585186005 -0.921689510345459 0.9621570706367493 -0.191381573677063 0.19391460716724396 0.5171361565589905 -0.2142094224691391 0.8286385536193848 0.6560564041137695 -0.2717368006706238 0.7040314674377441 0.6560564041137695 -0.2717368006706238 -0.7040314674377441 0.7698904275894165 -0.3188879191875458 0.5527512431144714 0.5171361565589905 -0.2142094224691391 -0.8286385536193848 0.8543656468391418 -0.35389262437820435 0.3805353045463562 0.3583483397960663 -0.14841151237487793 -0.921689510345459 0.9063386917114258 -0.3754081726074219 0.19391460716724396 0.18564409017562866 -0.07690664380788803 -0.9795831441879272 0.9238563179969788 -0.382671594619751 0.0 0.18564409017562866 -0.07690664380788803 0.9795831441879272 0.9063386917114258 -0.3754081726074219 -0.19391460716724396 0.3583483397960663 -0.14841151237487793 0.921689510345459 0.8543656468391418 -0.35386210680007935 -0.3805353045463562 0.7698904275894165 -0.3188879191875458 -0.5527512431144714 0.8314462900161743 -0.5555589199066162 0.0 0.1670888364315033 -0.1116367056965828 0.9795831441879272 0.1670888364315033 -0.1116367056965828 -0.9795831441879272 0.8156682252883911 -0.5449995398521423 -0.19391460716724396 0.32248908281326294 -0.2154911905527115 0.921689510345459 0.7689138650894165 -0.5137485861778259 -0.3805353045463562 0.46540728211402893 -0.3109835982322693 0.8286385536193848 0.6928922533988953 -0.46296578645706177 -0.5527512431144714 0.5904415845870972 -0.39451277256011963 0.7040314674377441 0.5904415845870972 -0.39451277256011963 -0.7040314674377441 0.6928922533988953 -0.46296578645706177 0.5527512431144714 0.46540728211402893 -0.3109835982322693 -0.8286385536193848 0.7689138650894165 -0.5137485861778259 0.3805353045463562 0.32248908281326294 -0.2154911905527115 -0.921689510345459 0.8156682252883911 -0.5449995398521423 0.19391460716724396 0.5021210312843323 -0.5021210312843323 -0.7040314674377441 0.5021210312843323 -0.5021210312843323 0.7040314674377441 0.5892513990402222 -0.5892513990402222 0.5527512431144714 0.395794540643692 -0.395794540643692 -0.8286385536193848 0.6538895964622498 -0.6538895964622498 0.3805353045463562 0.27426984906196594 -0.27426984906196594 -0.921689510345459 0.6936551928520203 -0.6936551928520203 0.19391460716724396 0.1420941799879074 -0.1420941799879074 -0.9795831441879272 0.7070833444595337 -0.7070833444595337 0.0 0.1420941799879074 -0.1420941799879074 0.9795831441879272 0.6936551928520203 -0.6936551928520203 -0.19391460716724396 0.27426984906196594 -0.27426984906196594 0.921689510345459 0.6538895964622498 -0.6538895964622498 -0.3805353045463562 0.395794540643692 -0.395794540643692 0.8286385536193848 0.5892513990402222 -0.5892513990402222 -0.5527512431144714 0.1116367056965828 -0.1670888364315033 -0.9795831441879272 0.5449995398521423 -0.8156682252883911 -0.19391460716724396 0.2154911905527115 -0.32248908281326294 0.921689510345459 0.5137485861778259 -0.7689138650894165 -0.3805353045463562 0.3109835982322693 -0.46540728211402893 0.8286385536193848 0.46296578645706177 -0.6928922533988953 -0.5527512431144714 0.39451277256011963 -0.5904415845870972 0.7040314674377441 0.39451277256011963 -0.5904415845870972 -0.7040314674377441 0.46296578645706177 -0.6928922533988953 0.5527512431144714 0.3109835982322693 -0.46540728211402893 -0.8286385536193848 0.5137485861778259 -0.7689138650894165 0.3805353045463562 0.2154911905527115 -0.32248908281326294 -0.921689510345459 0.5449995398521423 -0.8156682252883911 0.19391460716724396 0.5555589199066162 -0.8314462900161743 0.0 0.1116367056965828 -0.1670888364315033 0.9795831441879272 0.2142094224691391 -0.5171361565589905 -0.8286385536193848 0.35386210680007935 -0.8543656468391418 0.3805353045463562 0.14841151237487793 -0.3583483397960663 -0.921689510345459 0.3754081726074219 -0.9063386917114258 0.19391460716724396 0.07690664380788803 -0.18564409017562866 -0.9795831441879272 0.382671594619751 -0.9238563179969788 0.0 0.07687612622976303 -0.18564409017562866 0.9795831441879272 0.3754081726074219 -0.9063386917114258 -0.19391460716724396 0.14841151237487793 -0.3583483397960663 0.921689510345459 0.35386210680007935 -0.8543656468391418 -0.3805353045463562 0.2142094224691391 -0.5171361565589905 0.8286385536193848 0.3188879191875458 -0.7698904275894165 -0.5527512431144714 0.2717368006706238 -0.6560564041137695 0.7040314674377441 0.2717368006706238 -0.6560564041137695 -0.7040314674377441 0.3188879191875458 -0.7698904275894165 0.5527512431144714 0.039185766130685806 -0.19708853960037231 0.9795831441879272 0.07565538585186005 -0.3804132342338562 0.921689510345459 0.18039490282535553 -0.9069795608520508 -0.3805353045463562 0.10919522494077682 -0.5489974617958069 0.8286385536193848 0.16257210075855255 -0.8173161745071411 -0.5527512431144714 0.13852351903915405 -0.6964934468269348 0.7040314674377441 0.13852351903915405 -0.6964934468269348 -0.7040314674377441 0.16257210075855255 -0.8173161745071411 0.5527512431144714 0.10919522494077682 -0.5489974617958069 -0.8286385536193848 0.18039490282535553 -0.9069795608520508 0.3805353045463562 0.07565538585186005 -0.3804132342338562 -0.921689510345459 0.191381573677063 -0.9621570706367493 0.19391460716724396 0.039185766130685806 -0.19708853960037231 -0.9795831441879272 0.19507431983947754 -0.9807733297348022 0.0 0.191381573677063 -0.9621570706367493 -0.19391460716724396 0.0 -0.9247413277626038 0.3805353045463562 0.0 -0.5597705245018005 -0.8286385536193848 0.0 -0.3878597319126129 -0.921689510345459 0.0 -0.9809869527816772 0.19391460716724396 0.0 -0.20096439123153687 -0.9795831441879272 0.0 -1.0 0.0 0.0 -0.20096439123153687 0.9795831441879272 0.0 -0.9809869527816772 -0.19391460716724396 0.0 -0.3878597319126129 0.921689510345459 0.0 -0.9247413277626038 -0.3805353045463562 0.0 -0.5597705245018005 0.8286385536193848 0.0 -0.8333384394645691 -0.5527512431144714 0.0 -0.7101352214813232 0.7040314674377441 0.0 -0.7101352214813232 -0.7040314674377441 0.0 -0.8333384394645691 0.5527512431144714 -0.18039490282535553 -0.9069795608520508 -0.3805353045463562 -0.10919522494077682 -0.5489974617958069 0.8286385536193848 -0.16257210075855255 -0.8173161745071411 -0.5527512431144714 -0.13852351903915405 -0.6964934468269348 0.7040314674377441 -0.13852351903915405 -0.6964934468269348 -0.7040314674377441 -0.16257210075855255 -0.8173161745071411 0.5527512431144714 -0.10919522494077682 -0.5489974617958069 -0.8286385536193848 -0.18039490282535553 -0.9069795608520508 0.3805353045463562 -0.07565538585186005 -0.3804132342338562 -0.921689510345459 -0.191381573677063 -0.9621570706367493 0.19391460716724396 -0.039185766130685806 -0.19708853960037231 -0.9795831441879272 -0.19507431983947754 -0.9807733297348022 0.0 -0.039185766130685806 -0.19708853960037231 0.9795831441879272 -0.191381573677063 -0.9621570706367493 -0.19391460716724396 -0.07565538585186005 -0.3804132342338562 0.921689510345459 -0.2142094224691391 -0.5171361565589905 -0.8286385536193848 -0.14841151237487793 -0.3583483397960663 -0.921689510345459 -0.35389262437820435 -0.8543656468391418 0.3805353045463562 -0.3754081726074219 -0.9063386917114258 0.19391460716724396 -0.07690664380788803 -0.18564409017562866 -0.9795831441879272 -0.382671594619751 -0.9238563179969788 0.0 -0.07687612622976303 -0.18564409017562866 0.9795831441879272 -0.3754081726074219 -0.9063386917114258 -0.19391460716724396 -0.14841151237487793 -0.3583483397960663 0.921689510345459 -0.35386210680007935 -0.8543656468391418 -0.3805353045463562 -0.2142094224691391 -0.5171361565589905 0.8286385536193848 -0.3188879191875458 -0.7698904275894165 -0.5527512431144714 -0.2717368006706238 -0.6560564041137695 0.7040314674377441 -0.2717368006706238 -0.6560564041137695 -0.7040314674377441 -0.3188879191875458 -0.7698904275894165 0.5527512431144714 -0.2154911905527115 -0.32248908281326294 0.921689510345459 -0.3109835982322693 -0.46540728211402893 0.8286385536193848 -0.5137485861778259 -0.7689138650894165 -0.3805353045463562 -0.46296578645706177 -0.6928922533988953 -0.5527512431144714 -0.39451277256011963 -0.5904415845870972 0.7040314674377441 -0.39451277256011963 -0.5904415845870972 -0.7040314674377441 -0.46296578645706177 -0.6928922533988953 0.5527512431144714 -0.3109835982322693 -0.46540728211402893 -0.8286385536193848 -0.5137485861778259 -0.7689138650894165 0.3805353045463562 -0.2154911905527115 -0.32248908281326294 -0.921689510345459 -0.5449995398521423 -0.8156682252883911 0.19391460716724396 -0.1116367056965828 -0.1670888364315033 -0.9795831441879272 -0.5555589199066162 -0.8314462900161743 0.0 -0.1116367056965828 -0.1670888364315033 0.9795831441879272 -0.5449995398521423 -0.8156682252883911 -0.19391460716724396 -0.6538895964622498 -0.6538895964622498 0.3805353045463562 -0.6936551928520203 -0.6936551928520203 0.19391460716724396 -0.1420941799879074 -0.1420941799879074 -0.9795831441879272 -0.7070833444595337 -0.7070833444595337 0.0 -0.1420941799879074 -0.1420941799879074 0.9795831441879272 -0.6936551928520203 -0.6936551928520203 -0.19391460716724396 -0.27426984906196594 -0.27426984906196594 0.921689510345459 -0.6538895964622498 -0.6538895964622498 -0.3805353045463562 -0.395794540643692 -0.395794540643692 0.8286385536193848 -0.5892513990402222 -0.5892513990402222 -0.5527512431144714 -0.5021210312843323 -0.5021210312843323 0.7040314674377441 -0.5021210312843323 -0.5021210312843323 -0.7040314674377441 -0.5892513990402222 -0.5892513990402222 0.5527512431144714 -0.395794540643692 -0.395794540643692 -0.8286385536193848 -0.27426984906196594 -0.27426984906196594 -0.921689510345459 -0.7689138650894165 -0.5137485861778259 -0.3805353045463562 -0.6928922533988953 -0.46296578645706177 -0.5527512431144714 -0.5904415845870972 -0.39451277256011963 0.7040314674377441 -0.5904415845870972 -0.39451277256011963 -0.7040314674377441 -0.6928922533988953 -0.46296578645706177 0.5527512431144714 -0.46540728211402893 -0.3109835982322693 -0.8286385536193848 -0.7689138650894165 -0.5137485861778259 0.3805353045463562 -0.32248908281326294 -0.2154911905527115 -0.921689510345459 -0.8156682252883911 -0.5449995398521423 0.19391460716724396 -0.1670888364315033 -0.1116367056965828 -0.9795831441879272 -0.8314462900161743 -0.5555589199066162 0.0 -0.1670888364315033 -0.1116367056965828 0.9795831441879272 -0.8156682252883911 -0.5449995398521423 -0.19391460716724396 -0.32248908281326294 -0.2154911905527115 0.921689510345459 -0.46540728211402893 -0.3109835982322693 0.8286385536193848 -0.18564409017562866 -0.07690664380788803 -0.9795831441879272 -0.9238563179969788 -0.382671594619751 0.0 -0.18564409017562866 -0.07690664380788803 0.9795831441879272 -0.9063386917114258 -0.3754081726074219 -0.19391460716724396 -0.3583483397960663 -0.14841151237487793 0.921689510345459 -0.8543656468391418 -0.35386210680007935 -0.3805353045463562 -0.5171361565589905 -0.2142094224691391 0.8286385536193848 -0.7698904275894165 -0.3188879191875458 -0.5527512431144714 -0.6560564041137695 -0.2717368006706238 0.7040314674377441 -0.6560564041137695 -0.2717368006706238 -0.7040314674377441 -0.7698904275894165 -0.3188879191875458 0.5527512431144714 -0.5171361565589905 -0.2142094224691391 -0.8286385536193848 -0.8543656468391418 -0.35386210680007935 0.3805353045463562 -0.3583483397960663 -0.14841151237487793 -0.921689510345459 -0.9063386917114258 -0.3754081726074219 0.19391460716724396 -0.6964934468269348 -0.13852351903915405 -0.7040314674377441 -0.6964934468269348 -0.13852351903915405 0.7040314674377441 -0.8173161745071411 -0.16257210075855255 0.5527512431144714 -0.5489974617958069 -0.10919522494077682 -0.8286385536193848 -0.9069795608520508 -0.18039490282535553 0.3805353045463562 -0.3804132342338562 -0.07565538585186005 -0.921689510345459 -0.9621570706367493 -0.191381573677063 0.19391460716724396 -0.19708853960037231 -0.039185766130685806 -0.9795831441879272 -0.9807733297348022 -0.19507431983947754 0.0 -0.19708853960037231 -0.039185766130685806 0.9795831441879272 -0.9621570706367493 -0.191381573677063 -0.19391460716724396 -0.3804132342338562 -0.07565538585186005 0.921689510345459 -0.9069795608520508 -0.18039490282535553 -0.3805353045463562 -0.5489974617958069 -0.10919522494077682 0.8286385536193848 -0.8173161745071411 -0.16257210075855255 -0.5527512431144714 - - - - - - - - - - - - - - -

0 1 2 3 4 5 6 7 8 2 9 10 3 11 12 13 9 14 15 11 16 13 17 18 15 19 20 21 17 22 20 23 24 21 25 26 24 27 28 26 29 30 28 31 0 30 8 7 25 32 29 27 33 31 29 34 8 31 35 1 5 4 36 6 8 34 9 35 37 5 38 11 14 37 39 11 40 16 14 41 17 16 42 19 22 41 43 19 44 23 22 45 25 23 46 27 41 47 48 40 49 42 43 48 50 42 51 44 43 52 45 44 53 46 45 54 32 33 53 55 32 56 34 33 57 35 36 4 58 6 34 56 35 59 37 36 60 38 37 47 39 38 61 40 54 62 56 57 63 64 58 4 65 6 56 62 57 66 59 58 67 60 59 68 47 60 69 61 48 68 70 61 71 49 48 72 50 49 73 51 50 74 52 51 75 53 52 76 54 53 63 55 69 77 71 70 78 72 73 77 79 74 78 80 73 81 75 76 80 82 75 83 63 76 84 62 64 83 85 65 4 86 6 62 84 64 87 66 65 88 67 66 89 68 67 90 69 70 89 91 83 92 85 86 4 93 6 84 94 85 95 87 86 96 88 87 97 89 88 98 90 91 97 99 90 100 77 78 99 101 79 100 102 78 103 80 79 104 81 82 103 105 83 104 106 82 94 84 101 107 108 100 109 102 101 110 103 102 111 104 103 112 105 106 111 113 94 112 114 106 115 92 93 4 116 6 94 114 92 117 95 93 118 96 95 119 97 96 120 98 99 119 107 100 120 121 116 4 122 6 114 123 117 124 125 116 126 118 117 127 119 118 128 120 107 127 129 120 130 121 107 131 108 121 132 109 110 131 133 109 134 111 112 133 135 113 134 136 114 135 123 113 124 115 132 137 138 133 139 140 132 141 134 133 142 135 136 141 143 123 142 144 136 145 124 122 4 146 6 123 144 124 147 125 126 146 148 125 149 127 126 150 128 129 149 151 128 137 130 129 139 131 145 152 147 146 153 148 147 154 149 150 153 155 151 154 156 150 157 137 151 158 139 137 159 138 139 160 140 138 161 141 142 160 162 143 161 163 142 164 144 143 165 145 146 4 166 6 144 164 160 167 168 159 169 161 160 170 162 163 169 171 162 172 164 163 173 165 166 4 174 6 164 172 152 173 175 166 176 153 152 177 154 153 178 155 156 177 179 155 180 157 156 167 158 159 180 181 175 182 177 176 183 178 177 184 179 178 185 180 179 186 167 180 187 181 168 186 188 181 189 169 168 190 170 171 189 191 172 190 192 171 193 173 174 4 194 6 172 192 173 195 175 174 196 176 188 197 190 191 198 199 192 197 200 191 201 193 194 4 202 6 192 200 195 201 203 194 204 196 195 205 182 196 206 183 184 205 207 185 206 208 184 209 186 187 208 210 188 209 211 187 198 189 206 212 213 207 214 215 206 216 208 207 217 209 208 218 210 211 217 219 210 220 198 211 221 197 199 220 222 197 223 200 199 224 201 202 4 225 6 200 223 201 226 203 202 212 204 203 214 205 222 227 228 223 229 230 222 231 224 225 4 232 6 223 230 224 233 226 225 234 212 226 235 214 212 236 213 215 235 237 213 238 216 215 239 217 216 240 218 217 241 219 218 227 220 219 229 221 237 242 243 238 244 245 237 246 239 238 247 240 241 246 248 240 249 227 241 250 229 228 249 251 230 250 252 228 253 231 232 4 254 6 230 252 231 255 233 232 256 234 233 242 235 236 256 244 250 257 252 251 258 253 254 4 259 6 252 257 253 260 255 254 261 256 255 262 242 256 263 244 243 262 264 245 263 265 243 266 246 247 265 267 246 268 248 247 269 249 248 270 250 251 269 271 265 272 273 264 274 266 267 273 275 266 276 268 267 277 269 270 276 278 271 277 279 257 278 280 271 281 258 259 4 282 6 257 280 260 281 283 259 284 261 260 285 262 261 272 263 264 285 286 279 287 281 282 4 288 6 280 289 281 290 283 282 291 284 283 292 285 284 293 272 286 292 294 272 295 273 286 296 274 275 295 297 276 296 298 275 299 277 276 300 278 279 299 301 280 300 289 294 302 296 297 303 304 296 305 298 297 306 299 298 307 300 301 306 308 300 309 289 287 308 310 288 4 311 6 289 309 287 312 290 288 313 291 290 314 292 291 315 293 294 314 316 295 315 303 6 309 317 310 318 312 311 319 313 312 320 314 313 321 315 316 320 322 303 321 323 316 324 302 304 323 325 302 326 305 304 327 306 307 326 328 308 327 329 307 317 309 308 330 310 311 4 331 324 332 326 325 333 327 328 332 334 329 333 335 317 334 336 329 337 330 331 4 338 6 317 336 330 339 318 331 340 319 318 341 320 319 342 321 322 341 343 323 342 344 324 343 345 325 344 346 340 347 348 339 349 341 340 350 342 343 349 351 344 350 352 343 353 345 346 352 354 345 355 332 346 356 333 334 355 357 335 356 358 334 359 336 335 360 337 338 4 347 6 336 359 337 361 339 354 362 356 357 363 364 358 362 365 357 366 359 358 367 360 347 4 368 6 359 366 361 367 369 348 368 370 361 371 349 348 372 350 351 371 373 352 372 374 351 375 353 352 376 354 355 375 363 369 377 371 370 378 372 373 377 379 374 378 380 373 381 375 376 380 382 375 383 363 376 384 362 364 383 385 365 384 386 364 387 366 365 388 367 368 4 389 6 366 387 369 388 390 370 389 391 385 392 393 386 394 395 385 396 387 386 397 388 389 4 398 6 387 396 388 399 390 389 400 391 390 401 377 391 402 378 379 401 403 380 402 404 379 405 381 380 406 382 381 392 383 382 394 384 402 407 408 403 409 410 404 408 411 403 412 405 406 411 413 405 414 392 406 415 394 393 414 416 395 415 417 393 418 396 395 419 397 398 4 420 6 396 418 399 419 421 398 407 400 399 409 401 417 422 423 416 424 418 417 425 419 420 4 426 6 418 424 421 425 427 420 428 407 421 429 409 407 430 408 410 429 431 408 432 411 410 433 412 413 432 434 412 435 414 413 422 415 414 436 416 431 437 438 430 439 432 431 440 433 434 439 441 435 440 442 434 443 422 435 444 436 423 443 445 436 446 424 425 445 447 426 4 448 6 424 446 425 449 427 426 450 428 427 437 429 428 451 430 444 452 446 445 453 447 448 4 454 6 446 452 447 455 449 450 454 456 449 457 437 451 456 458 438 457 459 439 458 460 438 461 440 441 460 462 440 463 442 441 464 443 442 465 444 445 464 466 459 467 461 462 468 469 461 470 463 462 471 464 463 472 465 466 471 473 452 472 474 466 475 453 454 4 476 6 452 474 453 477 455 454 478 456 455 479 457 456 480 458 459 479 481 458 468 460 476 4 3 6 474 7 475 10 477 478 3 12 477 13 479 480 12 15 479 18 481 468 15 20 481 21 467 469 20 24 467 26 470 471 24 28 470 30 472 473 28 0 472 7 474 475 0 2 0 31 1 2 1 9 3 5 11 13 10 9 15 12 11 13 14 17 15 16 19 21 18 17 20 19 23 21 22 25 24 23 27 26 25 29 28 27 31 30 29 8 25 45 32 27 46 33 29 32 34 31 33 35 9 1 35 5 36 38 14 9 37 11 38 40 14 39 41 16 40 42 22 17 41 19 42 44 22 43 45 23 44 46 41 39 47 40 61 49 43 41 48 42 49 51 43 50 52 44 51 53 45 52 54 33 46 53 32 54 56 33 55 57 35 57 59 36 58 60 37 59 47 38 60 61 54 76 62 57 55 63 57 64 66 58 65 67 59 66 68 60 67 69 48 47 68 61 69 71 48 70 72 49 71 73 50 72 74 51 73 75 52 74 76 53 75 63 69 90 77 70 91 78 73 71 77 74 72 78 73 79 81 76 74 80 75 81 83 76 82 84 64 63 83 64 85 87 65 86 88 66 87 89 67 88 90 70 68 89 83 106 92 85 92 95 86 93 96 87 95 97 88 96 98 91 89 97 90 98 100 78 91 99 79 77 100 78 101 103 79 102 104 82 80 103 83 81 104 82 105 94 101 99 107 100 121 109 101 108 110 102 109 111 103 110 112 106 104 111 94 105 112 106 113 115 92 115 117 93 116 118 95 117 119 96 118 120 99 97 119 100 98 120 117 115 124 116 122 126 117 125 127 118 126 128 107 119 127 120 128 130 107 129 131 121 130 132 110 108 131 109 132 134 112 110 133 113 111 134 114 112 135 113 136 124 132 130 137 133 131 139 132 138 141 133 140 142 136 134 141 123 135 142 136 143 145 124 145 147 126 122 146 125 147 149 126 148 150 129 127 149 128 150 137 129 151 139 145 165 152 146 166 153 147 152 154 150 148 153 151 149 154 150 155 157 151 156 158 137 157 159 139 158 160 138 159 161 142 140 160 143 141 161 142 162 164 143 163 165 160 158 167 159 181 169 160 168 170 163 161 169 162 170 172 163 171 173 152 165 173 166 174 176 152 175 177 153 176 178 156 154 177 155 178 180 156 179 167 159 157 180 175 195 182 176 196 183 177 182 184 178 183 185 179 184 186 180 185 187 168 167 186 181 187 189 168 188 190 171 169 189 172 170 190 171 191 193 173 193 195 174 194 196 188 211 197 191 189 198 192 190 197 191 199 201 195 193 201 194 202 204 195 203 205 196 204 206 184 182 205 185 183 206 184 207 209 187 185 208 188 186 209 187 210 198 206 204 212 207 205 214 206 213 216 207 215 217 208 216 218 211 209 217 210 218 220 211 219 221 199 198 220 197 221 223 199 222 224 201 224 226 202 225 212 203 226 214 222 220 227 223 221 229 222 228 231 224 231 233 225 232 234 226 233 235 212 234 236 215 214 235 213 236 238 215 237 239 216 238 240 217 239 241 218 240 227 219 241 229 237 235 242 238 236 244 237 243 246 238 245 247 241 239 246 240 247 249 241 248 250 228 227 249 230 229 250 228 251 253 231 253 255 232 254 256 233 255 242 236 234 256 250 270 257 251 271 258 253 258 260 254 259 261 255 260 262 256 261 263 243 242 262 245 244 263 243 264 266 247 245 265 246 266 268 247 267 269 248 268 270 251 249 269 265 263 272 264 286 274 267 265 273 266 274 276 267 275 277 270 268 276 271 269 277 257 270 278 271 279 281 260 258 281 259 282 284 260 283 285 261 284 272 264 262 285 279 301 287 281 287 290 282 288 291 283 290 292 284 291 293 286 285 292 272 293 295 286 294 296 275 273 295 276 274 296 275 297 299 276 298 300 279 277 299 280 278 300 294 316 302 297 295 303 296 302 305 297 304 306 298 305 307 301 299 306 300 307 309 287 301 308 287 310 312 288 311 313 290 312 314 291 313 315 294 292 314 295 293 315 310 330 318 311 331 319 312 318 320 313 319 321 316 314 320 303 315 321 316 322 324 304 303 323 302 324 326 304 325 327 307 305 326 308 306 327 307 328 317 308 329 330 324 345 332 325 346 333 328 326 332 329 327 333 317 328 334 329 335 337 330 337 339 331 338 340 318 339 341 319 340 342 322 320 341 323 321 342 324 322 343 325 323 344 340 338 347 339 361 349 340 348 350 343 341 349 344 342 350 343 351 353 346 344 352 345 353 355 346 354 356 334 332 355 335 333 356 334 357 359 335 358 360 337 360 361 354 376 362 357 355 363 358 356 362 357 364 366 358 365 367 361 360 367 348 347 368 361 369 371 348 370 372 351 349 371 352 350 372 351 373 375 352 374 376 355 353 375 369 390 377 370 391 378 373 371 377 374 372 378 373 379 381 376 374 380 375 381 383 376 382 384 364 363 383 365 362 384 364 385 387 365 386 388 369 367 388 370 368 389 385 383 392 386 384 394 385 393 396 386 395 397 388 397 399 389 398 400 390 399 401 391 400 402 379 377 401 380 378 402 379 403 405 380 404 406 381 405 392 382 406 394 402 400 407 403 401 409 404 402 408 403 410 412 406 404 411 405 412 414 406 413 415 393 392 414 395 394 415 393 416 418 395 417 419 399 397 419 398 420 407 399 421 409 417 415 422 416 436 424 417 423 425 421 419 425 420 426 428 421 427 429 407 428 430 410 409 429 408 430 432 410 431 433 413 411 432 412 433 435 413 434 422 414 435 436 431 429 437 430 451 439 431 438 440 434 432 439 435 433 440 434 441 443 435 442 444 423 422 443 436 444 446 425 423 445 425 447 449 426 448 450 427 449 437 428 450 451 444 465 452 445 466 453 447 453 455 450 448 454 449 455 457 451 450 456 438 437 457 439 451 458 438 459 461 441 439 460 440 461 463 441 462 464 442 463 465 445 443 464 459 481 467 462 460 468 461 467 470 462 469 471 463 470 472 466 464 471 452 465 472 466 473 475 453 475 477 454 476 478 455 477 479 456 478 480 459 457 479 458 480 468 475 2 10 478 476 3 477 10 13 480 478 12 479 13 18 468 480 15 481 18 21 469 468 20 467 21 26 471 469 24 470 26 30 473 471 28 472 30 7 475 473 0

-
-
-
-
- - - - - - - - - - 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 - - - - - - - - - - - - - -
diff --git a/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.tscript b/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.tscript deleted file mode 100644 index 649009a49..000000000 --- a/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.tscript +++ /dev/null @@ -1,11 +0,0 @@ - -singleton TSShapeConstructor(ReflectProbeSpheredae) -{ - baseShapeAsset = "ToolsModule:ReflectProbeSphere"; - singleDetailSize = "0"; - flipUVCoords = "0"; - JoinIdenticalVerts = "0"; - reverseWindingOrder = "0"; - removeRedundantMats = "0"; - animFPS = "2"; -}; diff --git a/Templates/BaseGame/game/tools/resources/previewSphereShape.asset.taml b/Templates/BaseGame/game/tools/resources/previewSphereShape.asset.taml new file mode 100644 index 000000000..b58ba0be8 --- /dev/null +++ b/Templates/BaseGame/game/tools/resources/previewSphereShape.asset.taml @@ -0,0 +1,6 @@ + diff --git a/Templates/BaseGame/game/tools/resources/previewSphereShape.dae b/Templates/BaseGame/game/tools/resources/previewSphereShape.dae new file mode 100644 index 000000000..50afb94e9 --- /dev/null +++ b/Templates/BaseGame/game/tools/resources/previewSphereShape.dae @@ -0,0 +1,101 @@ + + + + + Blender User + Blender 3.0.0 commit date:2021-12-02, commit time:18:35, hash:f1cca3055776 + + 2021-12-24T16:51:50 + 2021-12-24T16:51:50 + + Z_UP + + + + + + + + 0 0 0 1 + + + 0.3737609 0.3737609 0.3737609 1 + + + 4 + + + + + + + + + + + + + + + + + -0.4903926 0 0.09754514 -0.4903926 0.09754514 0 -0.5 0 0 -0.09754514 0 0.4903926 0 0 0.5 -0.09567081 0.01903015 0.4903926 1.62921e-7 0 -0.5 -0.09754502 0 -0.4903926 -0.0956707 0.01903009 -0.4903926 -0.4809699 0.09567087 -0.09754508 -0.4903926 0 -0.09754508 -0.1876651 0.03732895 0.4619398 -0.1913417 0 0.4619398 -0.4619398 0 -0.1913416 -0.4530637 0.09012001 -0.1913416 -0.2777851 0 0.4157348 -0.2724475 0.05419319 0.4157348 -0.4077466 0.08110582 -0.2777851 -0.4157348 0 -0.2777851 -0.3467599 0.06897485 0.3535534 -0.3535534 0 0.3535534 -0.3535534 0 -0.3535534 -0.3467599 0.06897485 -0.3535534 -0.4077466 0.08110582 0.2777851 -0.4157348 0 0.2777851 -0.2724475 0.05419319 -0.4157348 -0.2777851 0 -0.4157348 -0.4530637 0.09011995 0.1913417 -0.4619398 0 0.1913417 -0.187665 0.03732889 -0.4619398 -0.1913416 0 -0.4619398 -0.4809699 0.09567087 0.09754514 -0.1767766 0.07322329 -0.4619398 -0.4530637 0.1876652 0.09754514 -0.09011983 0.03732889 -0.4903926 -0.4619398 0.1913418 0 -0.09011995 0.03732895 0.4903926 -0.4530637 0.1876652 -0.09754508 -0.1767767 0.07322335 0.4619398 -0.4267767 0.1767767 -0.1913416 -0.25664 0.1063038 0.4157348 -0.3840888 0.1590949 -0.2777851 -0.3266407 0.135299 0.3535534 -0.3266407 0.135299 -0.3535534 -0.3840888 0.1590949 0.2777851 -0.2566399 0.1063038 -0.4157348 -0.4267767 0.1767767 0.1913417 -0.3840888 0.25664 -0.1913416 -0.3456708 0.2309699 -0.2777851 -0.2939689 0.1964238 0.3535534 -0.2939689 0.1964238 -0.3535534 -0.3456708 0.2309699 0.2777851 -0.2309698 0.1543292 -0.4157348 -0.3840888 0.25664 0.1913417 -0.1590947 0.1063038 -0.4619398 -0.4077465 0.2724477 0.09754514 -0.0811057 0.05419319 -0.4903926 -0.4157347 0.2777852 0 -0.08110576 0.05419325 0.4903926 -0.4077465 0.2724477 -0.09754508 -0.1590948 0.1063038 0.4619398 -0.2309698 0.1543292 0.4157348 -0.06897467 0.06897485 -0.4903926 -0.3467599 0.34676 0.09754514 -0.3535533 0.3535535 0 -0.06897479 0.06897497 0.4903926 -0.3467599 0.34676 -0.09754508 -0.135299 0.1352991 0.4619398 -0.3266407 0.3266409 -0.1913416 -0.1964237 0.1964238 0.4157348 -0.2939688 0.293969 -0.2777851 -0.2499999 0.2500001 0.3535534 -0.2499999 0.2500001 -0.3535534 -0.2939688 0.293969 0.2777851 -0.1964236 0.1964238 -0.4157348 -0.3266407 0.3266409 0.1913417 -0.1352989 0.135299 -0.4619398 -0.1964236 0.293969 0.3535534 -0.1964236 0.293969 -0.3535534 -0.2309697 0.3456709 0.2777851 -0.154329 0.2309699 -0.4157348 -0.2566399 0.3840889 0.1913417 -0.1063036 0.1590949 -0.4619398 -0.2724474 0.4077466 0.09754514 -0.05419301 0.08110582 -0.4903926 -0.277785 0.415735 0 -0.05419307 0.08110594 0.4903926 -0.2724474 0.4077466 -0.09754508 -0.1063036 0.1590949 0.4619398 -0.2566399 0.3840889 -0.1913416 -0.154329 0.23097 0.4157348 -0.2309697 0.3456709 -0.2777851 -0.1913416 0.4619399 0 -0.03732877 0.09012007 0.4903926 -0.03732877 0.09011995 -0.4903926 -0.1876649 0.4530637 -0.09754508 -0.07322317 0.1767768 0.4619398 -0.1767766 0.4267768 -0.1913416 -0.1063036 0.2566401 0.4157348 -0.1590946 0.384089 -0.2777851 -0.1352989 0.3266409 0.3535534 -0.1352989 0.3266409 -0.3535534 -0.1590946 0.384089 0.2777851 -0.1063036 0.2566401 -0.4157348 -0.1767765 0.4267768 0.1913417 -0.07322317 0.1767767 -0.4619398 -0.1876649 0.4530637 0.09754514 -0.08110564 0.4077467 -0.2777851 -0.06897467 0.34676 -0.3535534 -0.08110564 0.4077467 0.2777851 -0.05419301 0.2724477 -0.4157348 -0.09011983 0.4530638 0.1913417 -0.03732877 0.1876652 -0.4619398 -0.09567064 0.4809699 0.09754514 -0.01902991 0.09567087 -0.4903926 -0.09754496 0.4903928 0 -0.01902997 0.09567099 0.4903926 -0.09567064 0.4809699 -0.09754508 -0.03732877 0.1876652 0.4619398 -0.09011983 0.4530638 -0.1913416 -0.05419301 0.2724477 0.4157348 -0.06897467 0.34676 0.3535534 1.63318e-7 0.09754526 0.4903926 1.54005e-7 0.09754514 -0.4903926 1.89395e-7 0.5000001 0 1.96846e-7 0.4903926 -0.09754508 1.59593e-7 0.1913418 0.4619398 0 0.4619398 -0.1913416 1.55867e-7 0.2777853 0.4157348 1.67043e-7 0.4157349 -0.2777851 1.59593e-7 0.3535535 0.3535534 1.59593e-7 0.3535535 -0.3535534 1.67043e-7 0.4157349 0.2777851 1.70769e-7 0.2777852 -0.4157348 1.37241e-7 0.4619398 0.1913417 1.52142e-7 0.1913418 -0.4619398 1.96846e-7 0.4903926 0.09754514 0.06897497 0.34676 0.3535534 0.081106 0.4077466 0.2777851 0.06897497 0.34676 -0.3535534 0.05419331 0.2724477 -0.4157348 0.09012013 0.4530638 0.1913417 0.03732907 0.1876652 -0.4619398 0.09567105 0.4809699 0.09754514 0.01903027 0.09567087 -0.4903926 0.09754532 0.4903928 0 0.01903027 0.09567099 0.4903926 0.09567105 0.4809699 -0.09754508 0.03732907 0.1876652 0.4619398 0.09012007 0.4530638 -0.1913416 0.05419331 0.2724477 0.4157348 0.081106 0.4077466 -0.2777851 0.1876653 0.4530637 -0.09754508 0.07322347 0.1767768 0.4619398 0.1767768 0.4267768 -0.1913416 0.1063039 0.2566401 0.4157348 0.159095 0.3840889 -0.2777851 0.1352992 0.3266409 0.3535534 0.1352992 0.3266409 -0.3535534 0.159095 0.3840889 0.2777851 0.1063039 0.25664 -0.4157348 0.1767768 0.4267768 0.1913417 0.07322347 0.1767767 -0.4619398 0.1876653 0.4530637 0.09754514 0.03732907 0.09011995 -0.4903926 0.1913419 0.4619398 0 0.03732913 0.09012007 0.4903926 0.1964239 0.293969 -0.3535534 0.1543293 0.2309699 -0.4157348 0.2566401 0.3840889 0.1913417 0.1063039 0.1590948 -0.4619398 0.2724477 0.4077466 0.09754514 0.05419331 0.08110582 -0.4903926 0.2777853 0.4157348 0 0.05419337 0.08110594 0.4903926 0.2724477 0.4077466 -0.09754508 0.1063039 0.1590949 0.4619398 0.2566401 0.3840889 -0.1913416 0.1543293 0.2309699 0.4157348 0.23097 0.3456709 -0.2777851 0.1964239 0.293969 0.3535534 0.23097 0.3456709 0.2777851 0.3266409 0.3266409 -0.1913416 0.196424 0.1964238 0.4157348 0.2939691 0.2939689 -0.2777851 0.2500002 0.25 0.3535534 0.2500002 0.25 -0.3535534 0.2939691 0.2939689 0.2777851 0.1964239 0.1964237 -0.4157348 0.3266409 0.3266409 0.1913417 0.1352992 0.135299 -0.4619398 0.3467601 0.3467599 0.09754514 0.06897497 0.06897485 -0.4903926 0.3535536 0.3535534 0 0.06897509 0.06897491 0.4903926 0.3467601 0.3467599 -0.09754508 0.1352992 0.1352991 0.4619398 0.1590949 0.1063038 -0.4619398 0.3840891 0.25664 0.1913417 0.4077467 0.2724475 0.09754514 0.081106 0.05419319 -0.4903926 0.415735 0.2777851 0 0.08110606 0.05419319 0.4903926 0.4077467 0.2724475 -0.09754508 0.159095 0.1063038 0.4619398 0.3840891 0.25664 -0.1913416 0.23097 0.1543291 0.4157348 0.345671 0.2309699 -0.2777851 0.2939691 0.1964237 0.3535534 0.2939691 0.1964237 -0.3535534 0.345671 0.2309699 0.2777851 0.23097 0.1543291 -0.4157348 0.1767769 0.07322335 0.4619398 0.2566402 0.1063038 0.4157348 0.4267768 0.1767767 -0.1913416 0.384089 0.1590948 -0.2777851 0.3266409 0.135299 0.3535534 0.3266409 0.135299 -0.3535534 0.384089 0.1590948 0.2777851 0.2566401 0.1063037 -0.4157348 0.4267768 0.1767767 0.1913417 0.1767768 0.07322329 -0.4619398 0.4530638 0.1876651 0.09754514 0.09012013 0.03732889 -0.4903926 0.46194 0.1913416 0 0.09012019 0.03732895 0.4903926 0.4530638 0.1876651 -0.09754508 0.4530639 0.09012001 0.1913417 0.48097 0.09567075 0.09754514 0.1876652 0.03732889 -0.4619398 0.09567099 0.01903009 -0.4903926 0.4903929 0.09754508 0 0.09567111 0.01903009 0.4903926 0.48097 0.09567075 -0.09754508 0.1876653 0.03732889 0.4619398 0.4530639 0.09012001 -0.1913416 0.2724478 0.05419319 0.4157348 0.4077467 0.08110576 -0.2777851 0.3467601 0.06897479 0.3535534 0.3467601 0.06897479 -0.3535534 0.4077467 0.08110576 0.2777851 0.2724477 0.05419313 -0.4157348 0.4619399 0 -0.1913416 0.4157348 0 -0.2777851 0.2777853 0 0.4157348 0.3535535 0 0.3535534 0.3535535 0 -0.3535534 0.4157348 0 0.2777851 0.2777853 0 -0.4157348 0.4619399 0 0.1913417 0.1913418 0 -0.4619398 0.4903926 0 0.09754514 0.09754532 0 -0.4903926 0.5000002 0 0 0.09754538 0 0.4903926 0.4903926 0 -0.09754508 0.1913419 0 0.4619398 0.09567099 -0.01903009 -0.4903926 0.4903928 -0.0975452 0 0.09567105 -0.01903009 0.4903926 0.4809699 -0.09567087 -0.09754508 0.1876653 -0.03732889 0.4619398 0.4530639 -0.09011989 -0.1913416 0.2724478 -0.05419313 0.4157348 0.4077466 -0.08110582 -0.2777851 0.3467601 -0.06897485 0.3535534 0.3467601 -0.06897485 -0.3535534 0.4077466 -0.08110582 0.2777851 0.2724477 -0.05419313 -0.4157348 0.4530639 -0.09011989 0.1913417 0.1876652 -0.03732889 -0.4619398 0.4809699 -0.09567087 0.09754514 0.2566402 -0.1063038 0.4157348 0.3266409 -0.135299 0.3535534 0.3266409 -0.135299 -0.3535534 0.3840889 -0.1590948 0.2777851 0.2566401 -0.1063037 -0.4157348 0.4267768 -0.1767767 0.1913417 0.1767768 -0.07322329 -0.4619398 0.4530637 -0.1876651 0.09754514 0.09012007 -0.03732889 -0.4903926 0.4619399 -0.1913418 0 0.09012019 -0.03732895 0.4903926 0.4530637 -0.1876651 -0.09754508 0.1767768 -0.07322329 0.4619398 0.4267768 -0.1767767 -0.1913416 0.3840889 -0.1590948 -0.2777851 0.415735 -0.2777852 0 0.08110606 -0.05419319 0.4903926 0.08110594 -0.05419313 -0.4903926 0.4077466 -0.2724475 -0.09754508 0.1590949 -0.1063038 0.4619398 0.384089 -0.25664 -0.1913416 0.23097 -0.1543291 0.4157348 0.3456709 -0.2309698 -0.2777851 0.293969 -0.1964237 0.3535534 0.293969 -0.1964237 -0.3535534 0.3456709 -0.2309698 0.2777851 0.23097 -0.1543291 -0.4157348 0.384089 -0.25664 0.1913417 0.1590949 -0.1063037 -0.4619398 0.4077466 -0.2724475 0.09754514 0.2500001 -0.25 -0.3535534 0.2500001 -0.25 0.3535534 0.2939689 -0.2939688 0.2777851 0.1964238 -0.1964237 -0.4157348 0.3266409 -0.3266407 0.1913417 0.1352991 -0.135299 -0.4619398 0.3467599 -0.3467599 0.09754514 0.06897497 -0.06897479 -0.4903926 0.3535535 -0.3535534 0 0.06897503 -0.06897491 0.4903926 0.3467599 -0.3467599 -0.09754508 0.1352992 -0.135299 0.4619398 0.3266409 -0.3266407 -0.1913416 0.1964239 -0.1964237 0.4157348 0.2939689 -0.2939688 -0.2777851 0.05419331 -0.08110576 -0.4903926 0.2724475 -0.4077464 -0.09754508 0.1063039 -0.1590948 0.4619398 0.2566401 -0.3840888 -0.1913416 0.1543293 -0.2309699 0.4157348 0.2309699 -0.3456708 -0.2777851 0.1964238 -0.2939689 0.3535534 0.1964238 -0.2939689 -0.3535534 0.2309699 -0.3456708 0.2777851 0.1543292 -0.2309698 -0.4157348 0.2566401 -0.3840888 0.1913417 0.1063038 -0.1590948 -0.4619398 0.2724475 -0.4077464 0.09754514 0.2777852 -0.4157348 0 0.05419337 -0.08110588 0.4903926 0.1063038 -0.2566399 -0.4157348 0.1767768 -0.4267767 0.1913417 0.07322341 -0.1767766 -0.4619398 0.1876651 -0.4530636 0.09754514 0.03732901 -0.09011989 -0.4903926 0.1913418 -0.4619398 0 0.03732907 -0.09012001 0.4903926 0.1876651 -0.4530636 -0.09754508 0.07322341 -0.1767767 0.4619398 0.1767768 -0.4267767 -0.1913416 0.1063039 -0.25664 0.4157348 0.1590948 -0.3840887 -0.2777851 0.1352991 -0.3266407 0.3535534 0.1352991 -0.3266407 -0.3535534 0.1590948 -0.3840887 0.2777851 0.01903027 -0.09567093 0.4903926 0.03732901 -0.1876651 0.4619398 0.09012013 -0.4530637 -0.1913416 0.05419331 -0.2724475 0.4157348 0.08110582 -0.4077464 -0.2777851 0.06897491 -0.3467599 0.3535534 0.06897491 -0.3467599 -0.3535534 0.08110582 -0.4077464 0.2777851 0.05419325 -0.2724475 -0.4157348 0.09012013 -0.4530637 0.1913417 0.03732901 -0.187665 -0.4619398 0.09567081 -0.4809697 0.09754514 0.01903027 -0.09567081 -0.4903926 0.0975452 -0.4903926 0 0.09567081 -0.4809697 -0.09754508 1.59593e-7 -0.4619398 0.1913417 1.2979e-7 -0.277785 -0.4157348 1.26065e-7 -0.1913416 -0.4619398 0 -0.4903924 0.09754514 1.5773e-7 -0.09754508 -0.4903926 0 -0.4999999 0 1.55867e-7 -0.0975452 0.4903926 0 -0.4903924 -0.09754508 1.40966e-7 -0.1913416 0.4619398 1.59593e-7 -0.4619398 -0.1913416 1.40966e-7 -0.2777851 0.4157348 0 -0.4157346 -0.2777851 0 -0.3535534 0.3535534 0 -0.3535534 -0.3535534 0 -0.4157346 0.2777851 -0.09011977 -0.4530637 -0.1913416 -0.05419301 -0.2724475 0.4157348 -0.0811057 -0.4077463 -0.2777851 -0.06897473 -0.3467599 0.3535534 -0.06897473 -0.3467599 -0.3535534 -0.0811057 -0.4077463 0.2777851 -0.05419301 -0.2724475 -0.4157348 -0.09011977 -0.4530637 0.1913417 -0.03732872 -0.187665 -0.4619398 -0.09567075 -0.4809696 0.09754514 -0.01902991 -0.09567081 -0.4903926 -0.09754508 -0.4903925 0 -0.01902997 -0.09567093 0.4903926 -0.09567075 -0.4809696 -0.09754508 -0.03732872 -0.1876651 0.4619398 -0.1063036 -0.2566398 -0.4157348 -0.07322311 -0.1767766 -0.4619398 -0.1767765 -0.4267767 0.1913417 -0.1876649 -0.4530634 0.09754514 -0.03732872 -0.09011989 -0.4903926 -0.1913416 -0.4619396 0 -0.03732877 -0.09012001 0.4903926 -0.1876649 -0.4530634 -0.09754508 -0.07322311 -0.1767767 0.4619398 -0.1767765 -0.4267767 -0.1913416 -0.1063036 -0.2566399 0.4157348 -0.1590946 -0.3840886 -0.2777851 -0.1352989 -0.3266407 0.3535534 -0.1352989 -0.3266407 -0.3535534 -0.1590946 -0.3840886 0.2777851 -0.1063036 -0.1590948 0.4619398 -0.154329 -0.2309698 0.4157348 -0.2566398 -0.3840888 -0.1913416 -0.2309697 -0.3456706 -0.2777851 -0.1964236 -0.2939688 0.3535534 -0.1964236 -0.2939688 -0.3535534 -0.2309697 -0.3456706 0.2777851 -0.154329 -0.2309697 -0.4157348 -0.2566398 -0.3840888 0.1913417 -0.1063035 -0.1590947 -0.4619398 -0.2724474 -0.4077463 0.09754514 -0.05419296 -0.08110576 -0.4903926 -0.277785 -0.4157346 0 -0.05419301 -0.08110588 0.4903926 -0.2724474 -0.4077463 -0.09754508 -0.3266406 -0.3266407 0.1913417 -0.3467597 -0.3467597 0.09754514 -0.06897461 -0.06897479 -0.4903926 -0.3535532 -0.3535532 0 -0.06897473 -0.06897485 0.4903926 -0.3467597 -0.3467597 -0.09754508 -0.1352988 -0.135299 0.4619398 -0.3266406 -0.3266407 -0.1913416 -0.1964235 -0.1964237 0.4157348 -0.2939687 -0.2939686 -0.2777851 -0.2499998 -0.2499999 0.3535534 -0.2499998 -0.2499999 -0.3535534 -0.2939687 -0.2939686 0.2777851 -0.1964235 -0.1964236 -0.4157348 -0.1352988 -0.1352989 -0.4619398 -0.3840886 -0.2566399 -0.1913416 -0.3456706 -0.2309696 -0.2777851 -0.2939687 -0.1964236 0.3535534 -0.2939687 -0.1964236 -0.3535534 -0.3456706 -0.2309696 0.2777851 -0.2309696 -0.154329 -0.4157348 -0.3840886 -0.2566399 0.1913417 -0.1590946 -0.1063036 -0.4619398 -0.4077462 -0.2724473 0.09754514 -0.08110564 -0.05419313 -0.4903926 -0.4157345 -0.2777849 0 -0.0811057 -0.05419319 0.4903926 -0.4077462 -0.2724473 -0.09754508 -0.1590946 -0.1063037 0.4619398 -0.2309697 -0.154329 0.4157348 -0.09011977 -0.03732889 -0.4903926 -0.4619395 -0.1913415 0 -0.09011983 -0.03732889 0.4903926 -0.4530633 -0.1876649 -0.09754508 -0.1767765 -0.07322323 0.4619398 -0.4267765 -0.1767766 -0.1913416 -0.2566398 -0.1063036 0.4157348 -0.3840885 -0.1590946 -0.2777851 -0.3266406 -0.1352989 0.3535534 -0.3266406 -0.1352989 -0.3535534 -0.3840885 -0.1590946 0.2777851 -0.2566397 -0.1063036 -0.4157348 -0.4267765 -0.1767766 0.1913417 -0.1767764 -0.07322323 -0.4619398 -0.4530633 -0.1876649 0.09754514 -0.3467597 -0.06897473 -0.3535534 -0.3467597 -0.06897473 0.3535534 -0.4077462 -0.08110564 0.2777851 -0.2724472 -0.05419307 -0.4157348 -0.4530635 -0.09011989 0.1913417 -0.1876649 -0.03732883 -0.4619398 -0.4809694 -0.09567064 0.09754514 -0.09567064 -0.01903009 -0.4903926 -0.4903923 -0.09754496 0 -0.09567075 -0.01903009 0.4903926 -0.4809694 -0.09567064 -0.09754508 -0.1876649 -0.03732883 0.4619398 -0.4530635 -0.09011989 -0.1913416 -0.2724473 -0.05419307 0.4157348 -0.4077462 -0.08110564 -0.2777851 + + + + + + + + + + -0.9810172 0 0.1939206 -0.9807879 0.1950772 0 -1 0 0 -0.2009674 0 0.979598 0 0 1 -0.1970922 0.03918647 0.9796015 0 0 -1 -0.2009674 0 -0.979598 -0.1970922 0.03918647 -0.9796015 -0.9621686 0.1913838 -0.1939169 -0.9810172 0 -0.1939206 -0.3804228 0.0756573 0.9217128 -0.3878701 0 0.9217141 -0.9247629 0 -0.3805441 -0.9069971 0.1803984 -0.3805426 -0.5597748 0 0.8286449 -0.5490075 0.1091972 0.8286537 -0.8173288 0.1625746 -0.5527598 -0.8333439 0 -0.5527549 -0.6965101 0.1385268 0.7040483 -0.7101522 0 0.7040483 -0.7101522 0 -0.7040483 -0.6965101 0.1385268 -0.7040483 -0.8173288 0.1625746 0.5527598 -0.8333439 0 0.5527549 -0.5490075 0.1091972 -0.8286537 -0.5597748 0 -0.8286449 -0.9069971 0.1803984 0.3805426 -0.9247629 0 0.3805441 -0.3804228 0.0756573 -0.9217128 -0.3878701 0 -0.9217141 -0.9621686 0.1913838 0.1939169 -0.3583571 0.1484152 -0.9217122 -0.9063459 0.3754112 0.1939162 -0.1856477 0.07690811 -0.979602 -0.9238803 0.3826816 0 -0.1856477 0.07690811 0.979602 -0.9063459 0.3754112 -0.1939162 -0.3583571 0.1484152 0.9217122 -0.854371 0.3538948 -0.3805376 -0.5171472 0.214214 0.8286563 -0.7699079 0.3188951 -0.5527638 -0.6560856 0.2717489 0.7040628 -0.6560856 0.2717489 -0.7040628 -0.7699079 0.3188951 0.5527638 -0.5171472 0.214214 -0.8286563 -0.8543801 0.3538681 0.3805418 -0.7689241 0.5137555 -0.3805404 -0.6929023 0.4629725 -0.5527593 -0.5904647 0.3945282 0.704059 -0.5904647 0.3945282 -0.704059 -0.6929023 0.4629725 0.5527593 -0.4654174 0.3109903 -0.8286566 -0.7689241 0.5137555 0.3805404 -0.3224976 0.2154968 -0.9217139 -0.8156918 0.5450153 0.1939202 -0.1670918 0.1116387 -0.9796006 -0.8314677 0.5555732 0 -0.1670918 0.1116387 0.9796006 -0.8156918 0.5450153 -0.1939202 -0.3224976 0.2154968 0.9217139 -0.4654174 0.3109903 0.8286566 -0.1420966 0.1420966 -0.9796006 -0.6936836 0.6936836 0.1939225 -0.7071068 0.7071068 0 -0.1420966 0.1420966 0.9796006 -0.6936836 0.6936836 -0.1939225 -0.2742754 0.2742754 0.9217082 -0.6539059 0.6539059 -0.3805448 -0.3958047 0.3958047 0.8286599 -0.5892608 0.5892608 -0.55276 -0.5021433 0.5021433 0.7040627 -0.5021433 0.5021433 -0.7040627 -0.5892608 0.5892608 0.55276 -0.3958047 0.3958047 -0.8286599 -0.6539059 0.6539059 0.3805448 -0.2742754 0.2742754 -0.9217082 -0.3945282 0.5904647 0.704059 -0.3945282 0.5904647 -0.704059 -0.4629725 0.6929023 0.5527593 -0.3109903 0.4654174 -0.8286566 -0.5137555 0.7689241 0.3805404 -0.2154968 0.3224976 -0.9217139 -0.5450153 0.8156918 0.1939202 -0.1116387 0.1670918 -0.9796006 -0.5555732 0.8314677 0 -0.1116387 0.1670918 0.9796006 -0.5450153 0.8156918 -0.1939202 -0.2154968 0.3224976 0.9217139 -0.5137555 0.7689241 -0.3805404 -0.3109903 0.4654174 0.8286566 -0.4629725 0.6929023 -0.5527593 -0.3826816 0.9238803 0 -0.07690811 0.1856477 0.979602 -0.07690811 0.1856477 -0.979602 -0.3754112 0.9063459 -0.1939162 -0.1484152 0.3583571 0.9217122 -0.3538681 0.8543801 -0.3805418 -0.214214 0.5171472 0.8286563 -0.3188951 0.7699079 -0.5527638 -0.2717489 0.6560856 0.7040628 -0.2717489 0.6560856 -0.7040628 -0.3188951 0.7699079 0.5527638 -0.214214 0.5171472 -0.8286563 -0.3538681 0.8543801 0.3805418 -0.1484152 0.3583571 -0.9217122 -0.3754112 0.9063459 0.1939162 -0.1625746 0.8173288 -0.5527598 -0.1385268 0.6965101 -0.7040483 -0.1625746 0.8173288 0.5527598 -0.1091972 0.5490075 -0.8286537 -0.1803984 0.9069971 0.3805426 -0.0756573 0.3804228 -0.9217128 -0.1913838 0.9621686 0.1939169 -0.03918647 0.1970922 -0.9796015 -0.1950772 0.9807879 0 -0.03918647 0.1970922 0.9796015 -0.1913838 0.9621686 -0.1939169 -0.0756573 0.3804228 0.9217128 -0.1803984 0.9069971 -0.3805426 -0.1091972 0.5490075 0.8286537 -0.1385268 0.6965101 0.7040483 0 0.2009674 0.979598 0 0.2009674 -0.979598 0 1 0 0 0.9810172 -0.1939206 0 0.3878701 0.9217141 0 0.9247629 -0.3805441 0 0.5597748 0.8286449 0 0.8333439 -0.5527549 0 0.7101522 0.7040483 0 0.7101522 -0.7040483 0 0.8333439 0.5527549 0 0.5597748 -0.8286449 0 0.9247629 0.3805441 0 0.3878701 -0.9217141 0 0.9810172 0.1939206 0.1385268 0.6965101 0.7040483 0.1625746 0.8173288 0.5527598 0.1385268 0.6965101 -0.7040483 0.1091972 0.5490075 -0.8286537 0.1803984 0.9069971 0.3805426 0.0756573 0.3804228 -0.9217128 0.1913838 0.9621686 0.1939169 0.03918647 0.1970922 -0.9796015 0.1950772 0.9807879 0 0.03918647 0.1970922 0.9796015 0.1913838 0.9621686 -0.1939169 0.0756573 0.3804228 0.9217128 0.1803984 0.9069971 -0.3805426 0.1091972 0.5490075 0.8286537 0.1625746 0.8173288 -0.5527598 0.3754112 0.9063459 -0.1939162 0.1484152 0.3583571 0.9217122 0.3538948 0.854371 -0.3805376 0.214214 0.5171472 0.8286563 0.3188951 0.7699079 -0.5527638 0.2717489 0.6560856 0.7040628 0.2717489 0.6560856 -0.7040628 0.3188951 0.7699079 0.5527638 0.214214 0.5171472 -0.8286563 0.3538948 0.854371 0.3805376 0.1484152 0.3583571 -0.9217122 0.3754112 0.9063459 0.1939162 0.07690811 0.1856477 -0.979602 0.3826816 0.9238803 0 0.07690811 0.1856477 0.979602 0.3945282 0.5904647 -0.704059 0.3109903 0.4654174 -0.8286566 0.5137555 0.7689241 0.3805404 0.2154968 0.3224976 -0.9217139 0.5450153 0.8156918 0.1939202 0.1116387 0.1670918 -0.9796006 0.5555732 0.8314677 0 0.1116387 0.1670918 0.9796006 0.5450153 0.8156918 -0.1939202 0.2154968 0.3224976 0.9217139 0.5137555 0.7689241 -0.3805404 0.3109903 0.4654174 0.8286566 0.4629725 0.6929023 -0.5527593 0.3945282 0.5904647 0.704059 0.4629725 0.6929023 0.5527593 0.6539059 0.6539059 -0.3805448 0.3958047 0.3958047 0.8286599 0.5892608 0.5892608 -0.55276 0.5021433 0.5021433 0.7040627 0.5021433 0.5021433 -0.7040627 0.5892608 0.5892608 0.55276 0.3958047 0.3958047 -0.8286599 0.6539059 0.6539059 0.3805448 0.2742754 0.2742754 -0.9217082 0.6936836 0.6936836 0.1939225 0.1420966 0.1420966 -0.9796006 0.7071068 0.7071068 0 0.1420966 0.1420966 0.9796006 0.6936836 0.6936836 -0.1939225 0.2742754 0.2742754 0.9217082 0.3224976 0.2154968 -0.9217139 0.7689241 0.5137555 0.3805404 0.8156918 0.5450153 0.1939202 0.1670918 0.1116387 -0.9796006 0.8314677 0.5555732 0 0.1670918 0.1116387 0.9796006 0.8156918 0.5450153 -0.1939202 0.3224976 0.2154968 0.9217139 0.7689241 0.5137555 -0.3805404 0.4654174 0.3109903 0.8286566 0.6929023 0.4629725 -0.5527593 0.5904647 0.3945282 0.704059 0.5904647 0.3945282 -0.704059 0.6929023 0.4629725 0.5527593 0.4654174 0.3109903 -0.8286566 0.3583571 0.1484152 0.9217122 0.5171472 0.214214 0.8286563 0.8543801 0.3538681 -0.3805418 0.7699079 0.3188951 -0.5527638 0.6560856 0.2717489 0.7040628 0.6560856 0.2717489 -0.7040628 0.7699079 0.3188951 0.5527638 0.5171472 0.214214 -0.8286563 0.8543801 0.3538681 0.3805418 0.3583571 0.1484152 -0.9217122 0.9063459 0.3754112 0.1939162 0.1856477 0.07690811 -0.979602 0.9238803 0.3826816 0 0.1856477 0.07690811 0.979602 0.9063459 0.3754112 -0.1939162 0.9069971 0.1803984 0.3805426 0.9621686 0.1913838 0.1939169 0.3804228 0.0756573 -0.9217128 0.1970922 0.03918647 -0.9796015 0.9807879 0.1950772 0 0.1970922 0.03918647 0.9796015 0.9621686 0.1913838 -0.1939169 0.3804228 0.0756573 0.9217128 0.9069971 0.1803984 -0.3805426 0.5490075 0.1091972 0.8286537 0.8173288 0.1625746 -0.5527598 0.6965101 0.1385268 0.7040483 0.6965101 0.1385268 -0.7040483 0.8173288 0.1625746 0.5527598 0.5490075 0.1091972 -0.8286537 0.9247629 0 -0.3805441 0.8333439 0 -0.5527549 0.5597748 0 0.8286449 0.7101522 0 0.7040483 0.7101522 0 -0.7040483 0.8333439 0 0.5527549 0.5597748 0 -0.8286449 0.9247629 0 0.3805441 0.3878701 0 -0.9217141 0.9810172 0 0.1939206 0.2009674 0 -0.979598 1 0 0 0.2009674 0 0.979598 0.9810172 0 -0.1939206 0.3878701 0 0.9217141 0.1970922 -0.03918647 -0.9796015 0.9807879 -0.1950772 0 0.1970922 -0.03918647 0.9796015 0.9621686 -0.1913838 -0.1939169 0.3804228 -0.0756573 0.9217128 0.9069971 -0.1803984 -0.3805426 0.5490075 -0.1091972 0.8286537 0.8173288 -0.1625746 -0.5527598 0.6965101 -0.1385268 0.7040483 0.6965101 -0.1385268 -0.7040483 0.8173288 -0.1625746 0.5527598 0.5490075 -0.1091972 -0.8286537 0.9069971 -0.1803984 0.3805426 0.3804228 -0.0756573 -0.9217128 0.9621686 -0.1913838 0.1939169 0.5171472 -0.214214 0.8286563 0.6560856 -0.2717489 0.7040628 0.6560856 -0.2717489 -0.7040628 0.7699079 -0.3188951 0.5527638 0.5171472 -0.214214 -0.8286563 0.8543801 -0.3538681 0.3805418 0.3583571 -0.1484152 -0.9217122 0.9063459 -0.3754112 0.1939162 0.1856477 -0.07690811 -0.979602 0.9238803 -0.3826816 0 0.1856477 -0.07690811 0.979602 0.9063459 -0.3754112 -0.1939162 0.3583571 -0.1484152 0.9217122 0.854371 -0.3538948 -0.3805376 0.7699079 -0.3188951 -0.5527638 0.8314677 -0.5555732 0 0.1670918 -0.1116387 0.9796006 0.1670918 -0.1116387 -0.9796006 0.8156918 -0.5450153 -0.1939202 0.3224976 -0.2154968 0.9217139 0.7689241 -0.5137555 -0.3805404 0.4654174 -0.3109903 0.8286566 0.6929023 -0.4629725 -0.5527593 0.5904647 -0.3945282 0.704059 0.5904647 -0.3945282 -0.704059 0.6929023 -0.4629725 0.5527593 0.4654174 -0.3109903 -0.8286566 0.7689241 -0.5137555 0.3805404 0.3224976 -0.2154968 -0.9217139 0.8156918 -0.5450153 0.1939202 0.5021433 -0.5021433 -0.7040627 0.5021433 -0.5021433 0.7040627 0.5892608 -0.5892608 0.55276 0.3958047 -0.3958047 -0.8286599 0.6539059 -0.6539059 0.3805448 0.2742754 -0.2742754 -0.9217082 0.6936836 -0.6936836 0.1939225 0.1420966 -0.1420966 -0.9796006 0.7071068 -0.7071068 0 0.1420966 -0.1420966 0.9796006 0.6936836 -0.6936836 -0.1939225 0.2742754 -0.2742754 0.9217082 0.6539059 -0.6539059 -0.3805448 0.3958047 -0.3958047 0.8286599 0.5892608 -0.5892608 -0.55276 0.1116387 -0.1670918 -0.9796006 0.5450153 -0.8156918 -0.1939202 0.2154968 -0.3224976 0.9217139 0.5137555 -0.7689241 -0.3805404 0.3109903 -0.4654174 0.8286566 0.4629725 -0.6929023 -0.5527593 0.3945282 -0.5904647 0.704059 0.3945282 -0.5904647 -0.704059 0.4629725 -0.6929023 0.5527593 0.3109903 -0.4654174 -0.8286566 0.5137555 -0.7689241 0.3805404 0.2154968 -0.3224976 -0.9217139 0.5450153 -0.8156918 0.1939202 0.5555732 -0.8314677 0 0.1116387 -0.1670918 0.9796006 0.214214 -0.5171472 -0.8286563 0.3538681 -0.8543801 0.3805418 0.1484152 -0.3583571 -0.9217122 0.3754112 -0.9063459 0.1939162 0.07690811 -0.1856477 -0.979602 0.3826816 -0.9238803 0 0.07687777 -0.1856481 0.9796043 0.3754112 -0.9063459 -0.1939162 0.1484152 -0.3583571 0.9217122 0.3538681 -0.8543801 -0.3805418 0.214214 -0.5171472 0.8286563 0.3188951 -0.7699079 -0.5527638 0.2717489 -0.6560856 0.7040628 0.2717489 -0.6560856 -0.7040628 0.3188951 -0.7699079 0.5527638 0.03918647 -0.1970922 0.9796015 0.0756573 -0.3804228 0.9217128 0.1803984 -0.9069971 -0.3805426 0.1091972 -0.5490075 0.8286537 0.1625746 -0.8173288 -0.5527598 0.1385268 -0.6965101 0.7040483 0.1385268 -0.6965101 -0.7040483 0.1625746 -0.8173288 0.5527598 0.1091972 -0.5490075 -0.8286537 0.1803984 -0.9069971 0.3805426 0.0756573 -0.3804228 -0.9217128 0.1913838 -0.9621686 0.1939169 0.03918647 -0.1970922 -0.9796015 0.1950772 -0.9807879 0 0.1913838 -0.9621686 -0.1939169 0 -0.9247629 0.3805441 0 -0.5597748 -0.8286449 0 -0.3878701 -0.9217141 0 -0.9810172 0.1939206 0 -0.2009674 -0.979598 0 -1 0 0 -0.2009674 0.979598 0 -0.9810172 -0.1939206 0 -0.3878701 0.9217141 0 -0.9247629 -0.3805441 0 -0.5597748 0.8286449 0 -0.8333439 -0.5527549 0 -0.7101522 0.7040483 0 -0.7101522 -0.7040483 0 -0.8333439 0.5527549 -0.1803984 -0.9069971 -0.3805426 -0.1091972 -0.5490075 0.8286537 -0.1625746 -0.8173288 -0.5527598 -0.1385268 -0.6965101 0.7040483 -0.1385268 -0.6965101 -0.7040483 -0.1625746 -0.8173288 0.5527598 -0.1091972 -0.5490075 -0.8286537 -0.1803984 -0.9069971 0.3805426 -0.0756573 -0.3804228 -0.9217128 -0.1913838 -0.9621686 0.1939169 -0.03918647 -0.1970922 -0.9796015 -0.1950772 -0.9807879 0 -0.03918647 -0.1970922 0.9796015 -0.1913838 -0.9621686 -0.1939169 -0.0756573 -0.3804228 0.9217128 -0.214214 -0.5171472 -0.8286563 -0.1484152 -0.3583571 -0.9217122 -0.3538681 -0.8543801 0.3805418 -0.3754112 -0.9063459 0.1939162 -0.07690811 -0.1856477 -0.979602 -0.3826816 -0.9238803 0 -0.07687777 -0.1856481 0.9796043 -0.3754112 -0.9063459 -0.1939162 -0.1484152 -0.3583571 0.9217122 -0.3538681 -0.8543801 -0.3805418 -0.214214 -0.5171472 0.8286563 -0.3188951 -0.7699079 -0.5527638 -0.2717489 -0.6560856 0.7040628 -0.2717489 -0.6560856 -0.7040628 -0.3188951 -0.7699079 0.5527638 -0.2154968 -0.3224976 0.9217139 -0.3109903 -0.4654174 0.8286566 -0.5137555 -0.7689241 -0.3805404 -0.4629725 -0.6929023 -0.5527593 -0.3945282 -0.5904647 0.704059 -0.3945282 -0.5904647 -0.704059 -0.4629725 -0.6929023 0.5527593 -0.3109903 -0.4654174 -0.8286566 -0.5137555 -0.7689241 0.3805404 -0.2154968 -0.3224976 -0.9217139 -0.5450153 -0.8156918 0.1939202 -0.1116387 -0.1670918 -0.9796006 -0.5555732 -0.8314677 0 -0.1116387 -0.1670918 0.9796006 -0.5450153 -0.8156918 -0.1939202 -0.6539059 -0.6539059 0.3805448 -0.6936836 -0.6936836 0.1939225 -0.1420966 -0.1420966 -0.9796006 -0.7071068 -0.7071068 0 -0.1420966 -0.1420966 0.9796006 -0.6936836 -0.6936836 -0.1939225 -0.2742754 -0.2742754 0.9217082 -0.6539059 -0.6539059 -0.3805448 -0.3958047 -0.3958047 0.8286599 -0.5892608 -0.5892608 -0.55276 -0.5021433 -0.5021433 0.7040627 -0.5021433 -0.5021433 -0.7040627 -0.5892608 -0.5892608 0.55276 -0.3958047 -0.3958047 -0.8286599 -0.2742754 -0.2742754 -0.9217082 -0.7689241 -0.5137555 -0.3805404 -0.6929023 -0.4629725 -0.5527593 -0.5904647 -0.3945282 0.704059 -0.5904647 -0.3945282 -0.704059 -0.6929023 -0.4629725 0.5527593 -0.4654174 -0.3109903 -0.8286566 -0.7689241 -0.5137555 0.3805404 -0.3224976 -0.2154968 -0.9217139 -0.8156918 -0.5450153 0.1939202 -0.1670918 -0.1116387 -0.9796006 -0.8314677 -0.5555732 0 -0.1670918 -0.1116387 0.9796006 -0.8156918 -0.5450153 -0.1939202 -0.3224976 -0.2154968 0.9217139 -0.4654174 -0.3109903 0.8286566 -0.1856477 -0.07690811 -0.979602 -0.9238803 -0.3826816 0 -0.1856477 -0.07690811 0.979602 -0.9063459 -0.3754112 -0.1939162 -0.3583571 -0.1484152 0.9217122 -0.8543801 -0.3538681 -0.3805418 -0.5171472 -0.214214 0.8286563 -0.7699079 -0.3188951 -0.5527638 -0.6560856 -0.2717489 0.7040628 -0.6560856 -0.2717489 -0.7040628 -0.7699079 -0.3188951 0.5527638 -0.5171472 -0.214214 -0.8286563 -0.8543801 -0.3538681 0.3805418 -0.3583571 -0.1484152 -0.9217122 -0.9063459 -0.3754112 0.1939162 -0.6965101 -0.1385268 -0.7040483 -0.6965101 -0.1385268 0.7040483 -0.8173288 -0.1625746 0.5527598 -0.5490075 -0.1091972 -0.8286537 -0.9069971 -0.1803984 0.3805426 -0.3804228 -0.0756573 -0.9217128 -0.9621686 -0.1913838 0.1939169 -0.1970922 -0.03918647 -0.9796015 -0.9807879 -0.1950772 0 -0.1970922 -0.03918647 0.9796015 -0.9621686 -0.1913838 -0.1939169 -0.3804228 -0.0756573 0.9217128 -0.9069971 -0.1803984 -0.3805426 -0.5490075 -0.1091972 0.8286537 -0.8173288 -0.1625746 -0.5527598 + + + + + + + + + + 0.9059244 0.648066 0.8793093 0.575425 0.9111002 0.5863247 0.5885478 0.9479513 0.492715 0.901747 0.6003652 0.9365409 0.9925565 0.09833276 0.9612628 0.1561555 0.9490643 0.1517305 0.9111002 0.5863247 0.8854812 0.5141399 0.9157391 0.5245054 0.5885478 0.9479513 0.7432609 0.92181 0.7778791 0.9406516 0.9202389 0.4626654 0.8854812 0.5141399 0.891547 0.4528335 0.8514901 0.8900356 0.7432609 0.92181 0.8089643 0.8738581 0.9202389 0.4626654 0.8979759 0.3915975 0.9249518 0.4008553 0.8514901 0.8900356 0.8377025 0.8171976 0.8776648 0.8314287 0.9303008 0.3391364 0.8979759 0.3915975 0.9053563 0.3305478 0.8776648 0.8314287 0.8537325 0.7578838 0.8910649 0.7708927 0.9303008 0.3391364 0.9146354 0.2698729 0.9369508 0.2776051 0.8910649 0.7708927 0.864425 0.6974942 0.8996179 0.7096431 0.9369508 0.2776051 0.9276896 0.2099514 0.9462066 0.2164527 0.8996179 0.7096431 0.8725281 0.63659 0.9059244 0.648066 0.9462066 0.2164527 0.9490643 0.1517305 0.9612628 0.1561555 0.9146354 0.2698729 0.9091555 0.2014223 0.9276896 0.2099514 0.864425 0.6974942 0.8400784 0.6222586 0.8725281 0.63659 0.9276896 0.2099514 0.9371914 0.1459214 0.9490643 0.1517305 0.8725281 0.63659 0.8481039 0.5616871 0.8793093 0.575425 0.6003652 0.9365409 0.492715 0.901747 0.6036882 0.9244517 0.9925565 0.09833276 0.9490643 0.1517305 0.9371914 0.1459214 0.8854812 0.5141399 0.8481039 0.5616871 0.8555443 0.5009738 0.6003652 0.9365409 0.716214 0.9029137 0.7432609 0.92181 0.891547 0.4528335 0.8555443 0.5009738 0.8629761 0.4402579 0.7432609 0.92181 0.7729267 0.8557598 0.8089643 0.8738581 0.891547 0.4528335 0.8709729 0.379678 0.8979759 0.3915975 0.8089643 0.8738581 0.801494 0.8004049 0.8377025 0.8171976 0.9053563 0.3305478 0.8709729 0.379678 0.8802902 0.3194179 0.8377025 0.8171976 0.8186983 0.7421017 0.8537325 0.7578838 0.9053563 0.3305478 0.8921813 0.2597874 0.9146354 0.2698729 0.8537325 0.7578838 0.8307024 0.6825021 0.864425 0.6974942 0.8709729 0.379678 0.8344583 0.4253514 0.8438495 0.3654333 0.7729267 0.8557598 0.7684796 0.7821101 0.801494 0.8004049 0.8802902 0.3194179 0.8438495 0.3654333 0.8549924 0.3060064 0.801494 0.8004049 0.7858012 0.7244532 0.8186983 0.7421017 0.8802902 0.3194179 0.8694851 0.2475308 0.8921813 0.2597874 0.8186983 0.7421017 0.7984084 0.6654416 0.8307024 0.6825021 0.8921813 0.2597874 0.8905657 0.1909774 0.9091555 0.2014223 0.8400784 0.6222586 0.7984084 0.6654416 0.8085606 0.6057375 0.9091555 0.2014223 0.9257678 0.1388037 0.9371914 0.1459214 0.8400784 0.6222586 0.8174625 0.545684 0.8481039 0.5616871 0.6036882 0.9244517 0.492715 0.901747 0.6018056 0.9123151 0.9925565 0.09833276 0.9371914 0.1459214 0.9257678 0.1388037 0.8481039 0.5616871 0.8258861 0.4854972 0.8555443 0.5009738 0.6036882 0.9244517 0.6929221 0.8844928 0.716214 0.9029137 0.8555443 0.5009738 0.8344583 0.4253514 0.8629761 0.4402579 0.716214 0.9029137 0.7415011 0.8368797 0.7729267 0.8557598 0.8905657 0.1909774 0.9149493 0.1304721 0.9257678 0.1388037 0.8174625 0.545684 0.7778562 0.5877237 0.7872828 0.5280401 0.6018056 0.9123151 0.492715 0.901747 0.5966135 0.9005175 0.9925565 0.09833276 0.9257678 0.1388037 0.9149493 0.1304721 0.8174625 0.545684 0.7963992 0.4682622 0.8258861 0.4854972 0.6018056 0.9123151 0.6716771 0.8668765 0.6929221 0.8844928 0.8258861 0.4854972 0.8058689 0.4085916 0.8344583 0.4253514 0.6929221 0.8844928 0.7132369 0.8180087 0.7415011 0.8368797 0.8438495 0.3654333 0.8058689 0.4085916 0.8164588 0.3492626 0.7415011 0.8368797 0.7379783 0.7631925 0.7684796 0.7821101 0.8438495 0.3654333 0.8292981 0.2906265 0.8549924 0.3060064 0.7684796 0.7821101 0.7547137 0.7057771 0.7858012 0.7244532 0.8549924 0.3060064 0.8463905 0.2333244 0.8694851 0.2475308 0.7858012 0.7244532 0.7673649 0.6470826 0.7984084 0.6654416 0.8694851 0.2475308 0.8718526 0.1787505 0.8905657 0.1909774 0.7984084 0.6654416 0.7778562 0.5877237 0.8085606 0.6057375 0.7132369 0.8180087 0.7093584 0.7443683 0.7379783 0.7631925 0.8164588 0.3492626 0.8029742 0.2736449 0.8292981 0.2906265 0.7547137 0.7057771 0.7093584 0.7443683 0.7250548 0.6868199 0.8463905 0.2333244 0.8029742 0.2736449 0.8226673 0.2174286 0.7547137 0.7057771 0.7373226 0.6281567 0.7673649 0.6470826 0.8718526 0.1787505 0.8226673 0.2174286 0.8529051 0.1648954 0.7673649 0.6470826 0.7477793 0.5689135 0.7778562 0.5877237 0.8718526 0.1787505 0.9049428 0.1210396 0.9149493 0.1304721 0.7872828 0.5280401 0.7477793 0.5689135 0.7574036 0.5094057 0.5966135 0.9005175 0.492715 0.901747 0.5892183 0.8893244 0.9925565 0.09833276 0.9149493 0.1304721 0.9049428 0.1210396 0.7872828 0.5280401 0.7669216 0.4498645 0.7963992 0.4682622 0.5966135 0.9005175 0.6516128 0.8503155 0.6716771 0.8668765 0.7963992 0.4682622 0.777029 0.3905105 0.8058689 0.4085916 0.6716771 0.8668765 0.687114 0.7997211 0.7132369 0.8180087 0.8164588 0.3492626 0.777029 0.3905105 0.7885947 0.3316226 0.7477793 0.5689135 0.7276275 0.4904417 0.7574036 0.5094057 0.5892183 0.8893244 0.492715 0.901747 0.5802933 0.8789367 0.9925565 0.09833276 0.9049428 0.1210396 0.8960399 0.1106414 0.7574036 0.5094057 0.7372524 0.4309325 0.7669216 0.4498645 0.5892183 0.8893244 0.6322468 0.8350224 0.6516128 0.8503155 0.7669216 0.4498645 0.7477135 0.3716894 0.777029 0.3905105 0.6516128 0.8503155 0.6624315 0.7824597 0.687114 0.7997211 0.7885947 0.3316226 0.7477135 0.3716894 0.7599906 0.3130286 0.687114 0.7997211 0.6820942 0.7262273 0.7093584 0.7443683 0.8029742 0.2736449 0.7599906 0.3130286 0.7757045 0.2554866 0.7250548 0.6868199 0.6820942 0.7262273 0.6964557 0.6682395 0.8029742 0.2736449 0.7979819 0.2001475 0.8226673 0.2174286 0.7250548 0.6868199 0.7080108 0.6093447 0.7373226 0.6281567 0.8529051 0.1648954 0.7979819 0.2001475 0.8335457 0.149583 0.7477793 0.5689135 0.7080108 0.6093447 0.718112 0.5499861 0.8529051 0.1648954 0.8960399 0.1106414 0.9049428 0.1210396 0.7757045 0.2554866 0.7303221 0.294062 0.747074 0.2366482 0.6820942 0.7262273 0.6685932 0.650616 0.6964557 0.6682395 0.7757045 0.2554866 0.771851 0.1818418 0.7979819 0.2001475 0.6964557 0.6682395 0.6791713 0.5912767 0.7080108 0.6093447 0.7979819 0.2001475 0.8134869 0.1330032 0.8335457 0.149583 0.718112 0.5499861 0.6791713 0.5912767 0.6886333 0.5315973 0.8960399 0.1106414 0.8134869 0.1330032 0.8886731 0.09943968 0.718112 0.5499861 0.6977451 0.4718118 0.7276275 0.4904417 0.5802933 0.8789367 0.492715 0.901747 0.5702692 0.869516 0.9925565 0.09833276 0.8960399 0.1106414 0.8886731 0.09943968 0.7276275 0.4904417 0.7071703 0.4121221 0.7372524 0.4309325 0.5802933 0.8789367 0.6132923 0.821187 0.6322468 0.8350224 0.7372524 0.4309325 0.7176637 0.3527587 0.7477135 0.3716894 0.6322468 0.8350224 0.6387079 0.7665851 0.6624315 0.7824597 0.7599906 0.3130286 0.7176637 0.3527587 0.7303221 0.294062 0.6820942 0.7262273 0.6387079 0.7665851 0.6557719 0.7092652 0.5702692 0.869516 0.492715 0.901747 0.5594361 0.8611971 0.9925565 0.09833276 0.8886731 0.09943968 0.8835193 0.08763581 0.7071703 0.4121221 0.6675595 0.4541771 0.6764574 0.3941132 0.5702692 0.869516 0.5945719 0.8089805 0.6132923 0.821187 0.7071703 0.4121221 0.6866088 0.3344001 0.7176637 0.3527587 0.6132923 0.821187 0.6156106 0.7524011 0.6387079 0.7665851 0.7303221 0.294062 0.6866088 0.3344001 0.6992201 0.2753812 0.6387079 0.7665851 0.6300765 0.6939069 0.6557719 0.7092652 0.7303221 0.294062 0.7165556 0.2177206 0.747074 0.2366482 0.6557719 0.7092652 0.6412011 0.6344648 0.6685932 0.650616 0.771851 0.1818418 0.7165556 0.2177206 0.7435711 0.1629553 0.6685932 0.650616 0.6505795 0.5745334 0.6791713 0.5912767 0.8134869 0.1330032 0.7435711 0.1629553 0.7922452 0.1153689 0.6886333 0.5315973 0.6505795 0.5745334 0.6591423 0.5143753 0.8886731 0.09943968 0.7922452 0.1153689 0.8835193 0.08763581 0.6886333 0.5315973 0.6675595 0.4541771 0.6977451 0.4718118 0.6412011 0.6344648 0.6047756 0.6805188 0.6140744 0.6202422 0.7435711 0.1629553 0.6835156 0.1994217 0.7121175 0.1440636 0.6412011 0.6344648 0.6220571 0.5596468 0.6505795 0.5745334 0.7435711 0.1629553 0.7689511 0.09693062 0.7922452 0.1153689 0.6591423 0.5143753 0.6220571 0.5596468 0.6294777 0.4989159 0.8835193 0.08763581 0.7689511 0.09693062 0.8816903 0.07549679 0.6591423 0.5143753 0.6369094 0.438188 0.6675595 0.4541771 0.5594361 0.8611971 0.492715 0.901747 0.5480003 0.8540929 0.9925565 0.09833276 0.8835193 0.08763581 0.8816903 0.07549679 0.6675595 0.4541771 0.644928 0.3776025 0.6764574 0.3941132 0.5945719 0.8089805 0.5480003 0.8540929 0.5759748 0.7985563 0.6764574 0.3941132 0.6542994 0.3173459 0.6866088 0.3344001 0.5945719 0.8089805 0.5929102 0.7401679 0.6156106 0.7524011 0.6992201 0.2753812 0.6542994 0.3173459 0.6663029 0.2577343 0.6156106 0.7524011 0.6047756 0.6805188 0.6300765 0.6939069 0.6992201 0.2753812 0.6835156 0.1994217 0.7165556 0.2177206 0.6369094 0.438188 0.6124644 0.3632876 0.644928 0.3776025 0.5480003 0.8540929 0.5574334 0.7900483 0.5759748 0.7985563 0.644928 0.3776025 0.6205583 0.3023672 0.6542994 0.3173459 0.5929102 0.7401679 0.5574334 0.7900483 0.570451 0.7301064 0.6663029 0.2577343 0.6205583 0.3023672 0.6312432 0.2419617 0.5929102 0.7401679 0.5797048 0.6694138 0.6047756 0.6805188 0.6663029 0.2577343 0.6472717 0.1826331 0.6835156 0.1994217 0.6047756 0.6805188 0.5870661 0.6083472 0.6140744 0.6202422 0.6835156 0.1994217 0.6760333 0.1259607 0.7121175 0.1440636 0.6140744 0.6202422 0.5934799 0.5470946 0.6220571 0.5596468 0.7689511 0.09693062 0.6760333 0.1259607 0.7418877 0.07801818 0.6294777 0.4989159 0.5934799 0.5470946 0.5995329 0.4857712 0.7689511 0.09693062 0.885091 0.06341117 0.8816903 0.07549679 0.6294777 0.4989159 0.6056935 0.4244693 0.6369094 0.438188 0.5480003 0.8540929 0.492715 0.901747 0.5361169 0.8482976 0.9925565 0.09833276 0.8816903 0.07549679 0.885091 0.06341117 0.6760333 0.1259607 0.6072647 0.1684171 0.6334344 0.1097899 0.5870661 0.6083472 0.5647808 0.537289 0.5934799 0.5470946 0.6760333 0.1259607 0.7072112 0.05916339 0.7418877 0.07801818 0.5995329 0.4857712 0.5647808 0.537289 0.5692661 0.4754315 0.7418877 0.07801818 0.8970212 0.05201429 0.885091 0.06341117 0.5995329 0.4857712 0.5738912 0.4135942 0.6056935 0.4244693 0.5361169 0.8482976 0.492715 0.901747 0.5239093 0.8438869 0.9925565 0.09833276 0.885091 0.06341117 0.8970212 0.05201429 0.6124644 0.3632876 0.5738912 0.4135942 0.579053 0.3518348 0.5361169 0.8482976 0.5389093 0.7835682 0.5574334 0.7900483 0.6124644 0.3632876 0.5853448 0.2902396 0.6205583 0.3023672 0.5574334 0.7900483 0.5481296 0.7223988 0.570451 0.7301064 0.6312432 0.2419617 0.5853448 0.2902396 0.5938816 0.2289718 0.570451 0.7301064 0.5547546 0.6608514 0.5797048 0.6694138 0.6312432 0.2419617 0.6072647 0.1684171 0.6472717 0.1826331 0.5870661 0.6083472 0.5547546 0.6608514 0.5600842 0.599116 0.579053 0.3518348 0.54882 0.2816787 0.5853448 0.2902396 0.5389093 0.7835682 0.5258811 0.7171856 0.5481296 0.7223988 0.5853448 0.2902396 0.5543729 0.2196655 0.5938816 0.2289718 0.5481296 0.7223988 0.5298588 0.6550331 0.5547546 0.6608514 0.5938816 0.2289718 0.5634034 0.1579628 0.6072647 0.1684171 0.5547546 0.6608514 0.5330832 0.5928134 0.5600842 0.599116 0.6334344 0.1097899 0.5634034 0.1579628 0.5825701 0.0971741 0.5600842 0.599116 0.5359469 0.5305616 0.5647808 0.537289 0.6334344 0.1097899 0.6550087 0.04154175 0.7072112 0.05916339 0.5692661 0.4754315 0.5359469 0.5305616 0.5387045 0.4683001 0.8970212 0.05201429 0.6550087 0.04154175 0.9226238 0.0424422 0.5692661 0.4754315 0.5415746 0.4060484 0.5738912 0.4135942 0.5239093 0.8438869 0.492715 0.901747 0.5114814 0.8409178 0.9925565 0.09833276 0.8970212 0.05201429 0.9226238 0.0424422 0.5738912 0.4135942 0.5448138 0.3438295 0.579053 0.3518348 0.5239093 0.8438869 0.5203842 0.7792032 0.5389093 0.7835682 0.5825701 0.0971741 0.5606263 0.02870553 0.6550087 0.04154175 0.5387045 0.4683001 0.5070113 0.5271458 0.5079368 0.4646666 0.9226238 0.0424422 0.5606263 0.02870553 0.9660401 0.03662568 0.5387045 0.4683001 0.5089053 0.4021884 0.5415746 0.4060484 0.5114814 0.8409178 0.492715 0.901747 0.4989255 0.8394287 0.9925565 0.09833276 0.9226238 0.0424422 0.9660401 0.03662568 0.5448138 0.3438295 0.5089053 0.4021884 0.5100055 0.3397141 0.5114814 0.8409178 0.5018534 0.7770128 0.5203842 0.7792032 0.5448138 0.3438295 0.5113775 0.2772482 0.54882 0.2816787 0.5203842 0.7792032 0.5036659 0.7145629 0.5258811 0.7171856 0.5543729 0.2196655 0.5113775 0.2772482 0.5133026 0.2147992 0.5298588 0.6550331 0.5036659 0.7145629 0.5049827 0.6520974 0.5543729 0.2196655 0.5165018 0.1523888 0.5634034 0.1579628 0.5330832 0.5928134 0.5049827 0.6520974 0.5060548 0.5896236 0.5825701 0.0971741 0.5165018 0.1523888 0.5236635 0.09009742 0.5330832 0.5928134 0.5070113 0.5271458 0.5359469 0.5305616 0.5036659 0.7145629 0.4833196 0.7770274 0.4814598 0.7145795 0.5133026 0.2147992 0.4736044 0.2772619 0.4716574 0.2148125 0.5036659 0.7145629 0.4801106 0.6521146 0.5049827 0.6520974 0.5133026 0.2147992 0.4684262 0.1524026 0.5165018 0.1523888 0.5049827 0.6520974 0.4790142 0.589641 0.5060548 0.5896236 0.5236635 0.09009742 0.4684262 0.1524026 0.4612001 0.09011387 0.5060548 0.5896236 0.4780379 0.5271627 0.5070113 0.5271458 0.5236635 0.09009742 0.4239621 0.02873963 0.5606263 0.02870553 0.5079368 0.4646666 0.4780379 0.5271627 0.4770951 0.4646827 0.5606263 0.02870553 1.019296 0.03663933 0.9660401 0.03662568 0.5079368 0.4646666 0.4761104 0.4022036 0.5089053 0.4021884 0.4989255 0.8394287 0.492715 0.901747 0.486328 0.8394391 0.9925565 0.09833276 0.9660401 0.03662568 1.019296 0.03663933 0.5089053 0.4021884 0.4749941 0.3397284 0.5100055 0.3397141 0.4989255 0.8394287 0.4833196 0.7770274 0.5018534 0.7770128 0.5100055 0.3397141 0.4736044 0.2772619 0.5113775 0.2772482 0.4770951 0.4646827 0.4491014 0.5306118 0.4463269 0.468348 0.01929616 0.03663933 0.3298254 0.04161161 0.06264001 0.04247719 0.4770951 0.4646827 0.4434411 0.4060937 0.4761104 0.4022036 0.486328 0.8394391 0.492715 0.901747 0.4737731 0.8409487 0.9925565 0.09833276 1.019296 0.03663933 1.06264 0.04247719 0.4761104 0.4022036 0.4401866 0.3438721 0.4749941 0.3397284 0.486328 0.8394391 0.4647885 0.7792469 0.4833196 0.7770274 0.4749941 0.3397284 0.4361638 0.281719 0.4736044 0.2772619 0.4833196 0.7770274 0.4592436 0.7172351 0.4814598 0.7145795 0.4716574 0.2148125 0.4361638 0.281719 0.4305911 0.2197046 0.4814598 0.7145795 0.4552333 0.6550847 0.4801106 0.6521146 0.4716574 0.2148125 0.4215336 0.1580027 0.4684262 0.1524026 0.4801106 0.6521146 0.4519847 0.5928651 0.4790142 0.589641 0.4684262 0.1524026 0.4023212 0.09721994 0.4612001 0.09011387 0.4790142 0.589641 0.4491014 0.5306118 0.4780379 0.5271627 0.4612001 0.09011387 0.3298254 0.04161161 0.4239621 0.02873963 0.4305911 0.2197046 0.3996422 0.2903048 0.3910893 0.2290341 0.4552333 0.6550847 0.436993 0.7224807 0.4303352 0.6609367 0.4305911 0.2197046 0.3776866 0.1684792 0.4215336 0.1580027 0.4552333 0.6550847 0.4249814 0.5992012 0.4519847 0.5928651 0.4023212 0.09721994 0.3776866 0.1684792 0.3514931 0.1098571 0.4519847 0.5928651 0.4202656 0.5373717 0.4491014 0.5306118 0.4023212 0.09721994 0.277736 0.05924415 0.3298254 0.04161161 0.4463269 0.468348 0.4202656 0.5373717 0.4157641 0.4755103 0.06264001 0.04247719 0.277736 0.05924415 0.08817166 0.05206078 0.4463269 0.468348 0.4111244 0.4136683 0.4434411 0.4060937 0.4737731 0.8409487 0.492715 0.901747 0.4613473 0.8439381 0.9925565 0.09833276 1.06264 0.04247719 1.088172 0.05206078 0.4434411 0.4060937 0.4059485 0.3519042 0.4401866 0.3438721 0.4737731 0.8409487 0.4462627 0.7836406 0.4647885 0.7792469 0.4401866 0.3438721 0.3996422 0.2903048 0.4361638 0.281719 0.4592436 0.7172351 0.4462627 0.7836406 0.436993 0.7224807 0.277736 0.05924415 0.1000552 0.06346303 0.08817166 0.05206078 0.4157641 0.4755103 0.3793213 0.4245703 0.4111244 0.4136683 0.4613473 0.8439381 0.492715 0.901747 0.449143 0.8483685 0.9925565 0.09833276 1.088172 0.05206078 1.100055 0.06346303 0.4111244 0.4136683 0.3725381 0.3633816 0.4059485 0.3519042 0.4613473 0.8439381 0.4277372 0.7901487 0.4462627 0.7836406 0.4059485 0.3519042 0.3644323 0.3024546 0.3996422 0.2903048 0.4462627 0.7836406 0.4146683 0.7302197 0.436993 0.7224807 0.3910893 0.2290341 0.3644323 0.3024546 0.3537352 0.2420439 0.4303352 0.6609367 0.4146683 0.7302197 0.4053811 0.6695316 0.3910893 0.2290341 0.3376945 0.1827127 0.3776866 0.1684792 0.4249814 0.5992012 0.4053811 0.6695316 0.3979957 0.6084646 0.3776866 0.1684792 0.3089248 0.1260416 0.3514931 0.1098571 0.4249814 0.5992012 0.3915634 0.5472081 0.4202656 0.5373717 0.3514931 0.1098571 0.2431051 0.07810217 0.277736 0.05924415 0.4157641 0.4755103 0.3915634 0.5472081 0.3854953 0.4858791 0.4053811 0.6695316 0.392204 0.7403113 0.3803044 0.6806673 0.3537352 0.2420439 0.3014633 0.1995143 0.3376945 0.1827127 0.3979957 0.6084646 0.3803044 0.6806673 0.370982 0.6203895 0.3376945 0.1827127 0.2728623 0.1441527 0.3089248 0.1260416 0.3979957 0.6084646 0.3629816 0.5597888 0.3915634 0.5472081 0.2431051 0.07810217 0.2728623 0.1441527 0.2160624 0.09701496 0.3854953 0.4858791 0.3629816 0.5597888 0.355547 0.4990501 0.1000552 0.06346303 0.2160624 0.09701496 0.1034273 0.07555043 0.3854953 0.4858791 0.3481036 0.4383131 0.3793213 0.4245703 0.449143 0.8483685 0.492715 0.901747 0.4372645 0.8541828 0.9925565 0.09833276 1.100055 0.06346303 1.103427 0.07555043 0.3725381 0.3633816 0.3481036 0.4383131 0.3400747 0.377718 0.449143 0.8483685 0.4091939 0.7986839 0.4277372 0.7901487 0.3725381 0.3633816 0.3306941 0.3174523 0.3644323 0.3024546 0.4277372 0.7901487 0.392204 0.7403113 0.4146683 0.7302197 0.3537352 0.2420439 0.3306941 0.3174523 0.3186824 0.2578327 0.355547 0.4990501 0.3174503 0.4543229 0.3481036 0.4383131 0.4372645 0.8541828 0.492715 0.901747 0.4258353 0.8613048 0.9925565 0.09833276 1.103427 0.07555043 1.10158 0.08768939 0.3481036 0.4383131 0.3085443 0.3942467 0.3400747 0.377718 0.4372645 0.8541828 0.3905939 0.809134 0.4091939 0.7986839 0.3400747 0.377718 0.2983864 0.3345217 0.3306941 0.3174523 0.4091939 0.7986839 0.3694965 0.7525728 0.392204 0.7403113 0.3186824 0.2578327 0.2983864 0.3345217 0.2857701 0.2754919 0.392204 0.7403113 0.3549953 0.6940838 0.3803044 0.6806673 0.3186824 0.2578327 0.2684326 0.217822 0.3014633 0.1995143 0.370982 0.6203895 0.3549953 0.6940838 0.3438475 0.6346392 0.2728623 0.1441527 0.2684326 0.217822 0.2414228 0.1630486 0.370982 0.6203895 0.3344526 0.5747007 0.3629816 0.5597888 0.2728623 0.1441527 0.1927784 0.1154518 0.2160624 0.09701496 0.355547 0.4990501 0.3344526 0.5747007 0.3258773 0.5145326 0.1034273 0.07555043 0.1927784 0.1154518 0.10158 0.08768939 0.2857701 0.2754919 0.2379202 0.2367545 0.2684326 0.217822 0.3438475 0.6346392 0.3292887 0.7094673 0.3164449 0.6508139 0.2684326 0.217822 0.2131515 0.1819364 0.2414228 0.1630486 0.3438475 0.6346392 0.3058518 0.5914652 0.3344526 0.5747007 0.2414228 0.1630486 0.1715415 0.1330838 0.1927784 0.1154518 0.3258773 0.5145326 0.3058518 0.5914652 0.2963792 0.5317736 0.1927784 0.1154518 0.09641396 0.09949165 0.10158 0.08768939 0.3174503 0.4543229 0.2963792 0.5317736 0.2872596 0.4719741 0.4258353 0.8613048 0.492715 0.901747 0.4150114 0.8696404 0.9925565 0.09833276 1.10158 0.08768939 1.096414 0.09949165 0.3174503 0.4543229 0.2778287 0.4122695 0.3085443 0.3942467 0.4258353 0.8613048 0.3718692 0.8213651 0.3905939 0.809134 0.3085443 0.3942467 0.2673314 0.3528915 0.2983864 0.3345217 0.3905939 0.809134 0.3463891 0.7667828 0.3694965 0.7525728 0.2857701 0.2754919 0.2673314 0.3528915 0.2546709 0.2941809 0.3549953 0.6940838 0.3463891 0.7667828 0.3292887 0.7094673 0.9925565 0.09833276 1.096414 0.09949165 1.089038 0.1106907 0.2872596 0.4719741 0.247742 0.4310891 0.2778287 0.4122695 0.4150114 0.8696404 0.3529083 0.8352231 0.3718692 0.8213651 0.2778287 0.4122695 0.2372796 0.3718289 0.2673314 0.3528915 0.3718692 0.8213651 0.3226514 0.7826805 0.3463891 0.7667828 0.2546709 0.2941809 0.2372796 0.3718289 0.225003 0.3131518 0.3292887 0.7094673 0.3226514 0.7826805 0.3029512 0.7264504 0.2546709 0.2941809 0.2092928 0.2555946 0.2379202 0.2367545 0.3164449 0.6508139 0.3029512 0.7264504 0.2885685 0.668456 0.2379202 0.2367545 0.1870253 0.2002409 0.2131515 0.1819364 0.3164449 0.6508139 0.2770006 0.6095497 0.3058518 0.5914652 0.1715415 0.1330838 0.1870253 0.2002409 0.1514846 0.1496599 0.2963792 0.5317736 0.2770006 0.6095497 0.2668911 0.5501763 0.1715415 0.1330838 0.08903849 0.1106907 0.09641396 0.09949165 0.2963792 0.5317736 0.2573703 0.4906155 0.2872596 0.4719741 0.4150114 0.8696404 0.492715 0.901747 0.4049999 0.8790763 0.2092928 0.2555946 0.162342 0.2175185 0.1870253 0.2002409 0.2885685 0.668456 0.2476739 0.6283716 0.2770006 0.6095497 0.1514846 0.1496599 0.162342 0.2175185 0.1321256 0.1649673 0.2668911 0.5501763 0.2476739 0.6283716 0.2372119 0.5691114 0.08903849 0.1106907 0.1321256 0.1649673 0.08012908 0.1210855 0.2668911 0.5501763 0.2275851 0.5095852 0.2573703 0.4906155 0.4049999 0.8790763 0.492715 0.901747 0.3960925 0.8894771 0.9925565 0.09833276 1.089038 0.1106907 1.080129 0.1210855 0.2573703 0.4906155 0.2180665 0.4500249 0.247742 0.4310891 0.4049999 0.8790763 0.3335328 0.8505368 0.3529083 0.8352231 0.247742 0.4310891 0.2079604 0.390652 0.2372796 0.3718289 0.3529083 0.8352231 0.2979491 0.799961 0.3226514 0.7826805 0.225003 0.3131518 0.2079604 0.390652 0.1963976 0.3317459 0.3029512 0.7264504 0.2979491 0.799961 0.2756667 0.7446073 0.2092928 0.2555946 0.1963976 0.3317459 0.182024 0.2737511 0.2885685 0.668456 0.2756667 0.7446073 0.2599516 0.6870493 0.3335328 0.8505368 0.3887225 0.9006809 0.3134537 0.867116 0.2180665 0.4500249 0.1791153 0.4087299 0.2079604 0.390652 0.3335328 0.8505368 0.2717982 0.8182626 0.2979491 0.799961 0.1963976 0.3317459 0.1791153 0.4087299 0.1685307 0.3493819 0.2756667 0.7446073 0.2717982 0.8182626 0.2470199 0.7634406 0.1963976 0.3317459 0.1556993 0.2907277 0.182024 0.2737511 0.2599516 0.6870493 0.2470199 0.7634406 0.23027 0.7060118 0.182024 0.2737511 0.1386191 0.2334085 0.162342 0.2175185 0.2599516 0.6870493 0.2176133 0.6473003 0.2476739 0.6283716 0.1321256 0.1649673 0.1386191 0.2334085 0.1131775 0.1788164 0.2372119 0.5691114 0.2176133 0.6473003 0.2071207 0.5879223 0.1321256 0.1649673 0.07011771 0.1305137 0.08012908 0.1210855 0.2372119 0.5691114 0.197695 0.5282186 0.2275851 0.5095852 0.3960925 0.8894771 0.492715 0.901747 0.3887225 0.9006809 0.9925565 0.09833276 1.080129 0.1210855 1.070118 0.1305137 0.2275851 0.5095852 0.1885811 0.4684205 0.2180665 0.4500249 0.23027 0.7060118 0.1865485 0.665653 0.2176133 0.6473003 0.1131775 0.1788164 0.1155236 0.2476066 0.09446328 0.1910358 0.2071207 0.5879223 0.1865485 0.665653 0.1764 0.6059286 0.1131775 0.1788164 0.05929529 0.1388404 0.07011771 0.1305137 0.2071207 0.5879223 0.1675031 0.5458543 0.197695 0.5282186 0.3887225 0.9006809 0.492715 0.901747 0.3835681 0.912486 0.9925565 0.09833276 1.070118 0.1305137 1.059295 0.1388404 0.1885811 0.4684205 0.1675031 0.5458543 0.1590852 0.4856469 0.3134537 0.867116 0.3835681 0.912486 0.292185 0.8847473 0.1885811 0.4684205 0.1505197 0.4254812 0.1791153 0.4087299 0.3134537 0.867116 0.243494 0.837141 0.2717982 0.8182626 0.1685307 0.3493819 0.1505197 0.4254812 0.1411362 0.3655441 0.2470199 0.7634406 0.243494 0.837141 0.2164838 0.7823588 0.1685307 0.3493819 0.1300031 0.3060992 0.1556993 0.2907277 0.2470199 0.7634406 0.199155 0.7246842 0.23027 0.7060118 0.1386191 0.2334085 0.1300031 0.3060992 0.1155236 0.2476066 0.1590852 0.4856469 0.1219953 0.4403737 0.1505197 0.4254812 0.292185 0.8847473 0.2120112 0.856019 0.243494 0.837141 0.1411362 0.3655441 0.1219953 0.4403737 0.1140086 0.379776 0.2164838 0.7823588 0.2120112 0.856019 0.1834254 0.8006429 0.1411362 0.3655441 0.1047028 0.3194993 0.1300031 0.3060992 0.199155 0.7246842 0.1834254 0.8006429 0.1662256 0.7423182 0.1300031 0.3060992 0.09282612 0.2598529 0.1155236 0.2476066 0.199155 0.7246842 0.1542308 0.6826973 0.1865485 0.665653 0.09446328 0.1910358 0.09282612 0.2598529 0.07587218 0.2014721 0.1764 0.6059286 0.1542308 0.6826973 0.1448646 0.6224332 0.09446328 0.1910358 0.04786872 0.1459523 0.05929529 0.1388404 0.1764 0.6059286 0.1368486 0.5618414 0.1675031 0.5458543 0.3835681 0.912486 0.492715 0.901747 0.3817437 0.9246256 0.9925565 0.09833276 1.059295 0.1388404 1.047869 0.1459523 0.1590852 0.4856469 0.1368486 0.5618414 0.1294175 0.5011084 0.292185 0.8847473 0.3817437 0.9246256 0.2688526 0.9031792 0.07587218 0.2014721 0.07037049 0.2699261 0.05733662 0.2099915 0.1448646 0.6224332 0.1204835 0.6976624 0.1123972 0.6367389 0.07587218 0.2014721 0.03599351 0.1517553 0.04786872 0.1459523 0.1448646 0.6224332 0.1056304 0.5755556 0.1368486 0.5618414 0.3817437 0.9246256 0.492715 0.901747 0.385161 0.9367107 0.9925565 0.09833276 1.047869 0.1459523 1.035994 0.1517553 0.1368486 0.5618414 0.09947144 0.514253 0.1294175 0.5011084 0.3817437 0.9246256 0.2417302 0.9220808 0.2688526 0.9031792 0.1294175 0.5011084 0.093418 0.45293 0.1219953 0.4403737 0.2688526 0.9031792 0.1758925 0.8741014 0.2120112 0.856019 0.1140086 0.379776 0.093418 0.45293 0.0870012 0.3916786 0.1834254 0.8006429 0.1758925 0.8741014 0.1471639 0.817411 0.1140086 0.379776 0.07963401 0.3306146 0.1047028 0.3194993 0.1834254 0.8006429 0.131156 0.7580731 0.1662256 0.7423182 0.1047028 0.3194993 0.07037049 0.2699261 0.09282612 0.2598529 0.1662256 0.7423182 0.1204835 0.6976624 0.1542308 0.6826973 0.1758925 0.8741014 0.2069531 0.9409168 0.1332573 0.8902431 0.0870012 0.3916786 0.06472045 0.4627382 0.06002157 0.4009161 0.1471639 0.817411 0.1332573 0.8902431 0.1071433 0.8316007 0.0870012 0.3916786 0.05468714 0.3391861 0.07963401 0.3306146 0.131156 0.7580731 0.1071433 0.8316007 0.09378856 0.7710414 0.07963401 0.3306146 0.04805356 0.2776444 0.07037049 0.2699261 0.131156 0.7580731 0.08526748 0.7097733 0.1204835 0.6976624 0.05733662 0.2099915 0.04805356 0.2776444 0.03881853 0.2164819 0.1123972 0.6367389 0.08526748 0.7097733 0.07898485 0.6481801 0.05733662 0.2099915 0.02379328 0.1561736 0.03599351 0.1517553 0.1123972 0.6367389 0.07382827 0.5864241 0.1056304 0.5755556 0.385161 0.9367107 0.492715 0.901747 0.3971338 0.9481052 0.9925565 0.09833276 1.035994 0.1517553 1.023793 0.1561736 0.09947144 0.514253 0.07382827 0.5864241 0.06920558 0.524591 0.385161 0.9367107 0.2069531 0.9409168 0.2417302 0.9220808 0.09947144 0.514253 0.06472045 0.4627382 0.093418 0.45293 0.07898485 0.6481801 0.04874467 0.7183161 0.04474818 0.6561728 0.03881853 0.2164819 0.0113722 0.1591499 0.02379328 0.1561736 0.07898485 0.6481801 0.04151457 0.5939623 0.07382827 0.5864241 0.3971338 0.9481052 0.492715 0.901747 0.4228305 0.9576696 0.9925565 0.09833276 1.023793 0.1561736 1.011372 0.1591499 0.06920558 0.524591 0.04151457 0.5939623 0.03864717 0.5317196 0.3971338 0.9481052 0.1545662 0.9585033 0.2069531 0.9409168 0.06920558 0.524591 0.03589004 0.4694672 0.06472045 0.4627382 0.2069531 0.9409168 0.08236718 0.9028213 0.1332573 0.8902431 0.06002157 0.4009161 0.03589004 0.4694672 0.03302448 0.4072239 0.1332573 0.8902431 0.06327778 0.8420249 0.1071433 0.8316007 0.06002157 0.4009161 0.02979582 0.3450124 0.05468714 0.3391861 0.09378856 0.7710414 0.06327778 0.8420249 0.05428034 0.7803239 0.05468714 0.3391861 0.02581018 0.2828674 0.04805356 0.2776444 0.09378856 0.7710414 0.04874467 0.7183161 0.08526748 0.7097733 0.04805356 0.2776444 0.02029967 0.2208569 0.03881853 0.2164819 0.03302448 0.4072239 0.006959736 0.4728841 0.006001472 0.4104183 0.08236718 0.9028213 0.01638609 0.8475685 0.06327778 0.8420249 0.03302448 0.4072239 0.00492531 0.3479555 0.02979582 0.3450124 0.05428034 0.7803239 0.01638609 0.8475685 0.01321828 0.785167 0.02581018 0.2828674 0.00492531 0.3479555 0.003600955 0.285499 0.05428034 0.7803239 0.01130914 0.7227291 0.04874467 0.7183161 0.02581018 0.2828674 0.001775324 0.2230563 0.02029967 0.2208569 0.04474818 0.6561728 0.01130914 0.7227291 0.009946048 0.6602758 1.0203 0.2208569 0.9988229 0.1606459 1.011372 0.1591499 0.04151457 0.5939623 0.009946048 0.6602758 0.008850932 0.5978149 0.4228305 0.9576696 0.492715 0.901747 0.4663997 0.9634672 0.9925565 0.09833276 1.011372 0.1591499 0.9988229 0.1606459 0.04151457 0.5939623 0.00788486 0.5353502 0.03864717 0.5317196 0.4228305 0.9576696 0.05996555 0.9712674 0.1545662 0.9585033 0.03864717 0.5317196 0.006959736 0.4728841 0.03589004 0.4694672 0.1545662 0.9585033 0.02346807 0.9098559 0.08236718 0.9028213 1.001775 0.2230563 0.9862315 0.1606423 0.9988229 0.1606459 1.009946 0.6602758 0.9760642 0.5977937 1.008851 0.5978149 0.4663997 0.9634672 0.492715 0.901747 0.5197656 0.9634217 0.9925565 0.09833276 0.9988229 0.1606459 0.9862315 0.1606423 1.008851 0.5978149 0.9770506 0.535332 1.007885 0.5353502 1.059966 0.9712674 0.5197656 0.9634217 0.9236539 0.9711539 1.007885 0.5353502 0.9779933 0.4728688 1.00696 0.4728841 1.023468 0.9098559 0.9236539 0.9711539 0.9610577 0.9098034 1.006001 0.4104183 0.9779933 0.4728688 0.9789676 0.4104056 1.016386 0.8475685 0.9610577 0.9098034 0.9683353 0.847529 1.006001 0.4104183 0.9800599 0.3479452 1.004925 0.3479555 1.013218 0.785167 0.9683353 0.847529 0.9715889 0.7851341 1.004925 0.3479555 0.9814017 0.2854908 1.003601 0.285499 1.013218 0.785167 0.9735478 0.7227008 1.011309 0.7227291 1.003601 0.285499 0.9832485 0.2230503 1.001775 0.2230563 1.009946 0.6602758 0.9735478 0.7227008 0.9749442 0.6602513 0.9789676 0.4104056 0.9551903 0.3449817 0.9800599 0.3479452 0.9715889 0.7851341 0.9214769 0.841912 0.9305438 0.7802285 0.9800599 0.3479452 0.9591931 0.2828431 0.9814017 0.2854908 0.9715889 0.7851341 0.9361224 0.7182335 0.9735478 0.7227008 0.9814017 0.2854908 0.9647247 0.2208389 0.9832485 0.2230503 0.9749442 0.6602513 0.9361224 0.7182335 0.9401488 0.6561009 0.9862315 0.1606423 0.9647247 0.2208389 0.9736827 0.1591389 0.9749442 0.6602513 0.9434052 0.5939 0.9760642 0.5977937 0.5197656 0.9634217 0.492715 0.901747 0.5630894 0.9575534 0.9925565 0.09833276 0.9862315 0.1606423 0.9736827 0.1591389 0.9760642 0.5977937 0.9462915 0.5316662 0.9770506 0.535332 0.5197656 0.9634217 0.8298811 0.9582708 0.9236539 0.9711539 0.9770506 0.535332 0.9490651 0.4694219 0.9779933 0.4728688 0.9236539 0.9711539 0.9022539 0.902677 0.9610577 0.9098034 0.9789676 0.4104056 0.9490651 0.4694219 0.951946 0.4071862 0.9610577 0.9098034 0.9214769 0.841912 0.9683353 0.847529 0.5630894 0.9575534 0.492715 0.901747 0.5885478 0.9479513 0.9925565 0.09833276 0.9736827 0.1591389 0.9612628 0.1561555 0.9434052 0.5939 0.9157391 0.5245054 0.9462915 0.5316662 0.8298811 0.9582708 0.5885478 0.9479513 0.7778791 0.9406516 0.9462915 0.5316662 0.9202389 0.4626654 0.9490651 0.4694219 0.9022539 0.902677 0.7778791 0.9406516 0.8514901 0.8900356 0.9490651 0.4694219 0.9249518 0.4008553 0.951946 0.4071862 0.9214769 0.841912 0.8514901 0.8900356 0.8776648 0.8314287 0.951946 0.4071862 0.9303008 0.3391364 0.9551903 0.3449817 0.9305438 0.7802285 0.8776648 0.8314287 0.8910649 0.7708927 0.9551903 0.3449817 0.9369508 0.2776051 0.9591931 0.2828431 0.9361224 0.7182335 0.8910649 0.7708927 0.8996179 0.7096431 0.9591931 0.2828431 0.9462066 0.2164527 0.9647247 0.2208389 0.9401488 0.6561009 0.8996179 0.7096431 0.9059244 0.648066 0.9647247 0.2208389 0.9612628 0.1561555 0.9736827 0.1591389 0.9434052 0.5939 0.9059244 0.648066 0.9111002 0.5863247 0.9059244 0.648066 0.8725281 0.63659 0.8793093 0.575425 0.9111002 0.5863247 0.8793093 0.575425 0.8854812 0.5141399 0.5885478 0.9479513 0.6003652 0.9365409 0.7432609 0.92181 0.9202389 0.4626654 0.9157391 0.5245054 0.8854812 0.5141399 0.8514901 0.8900356 0.7778791 0.9406516 0.7432609 0.92181 0.9202389 0.4626654 0.891547 0.4528335 0.8979759 0.3915975 0.8514901 0.8900356 0.8089643 0.8738581 0.8377025 0.8171976 0.9303008 0.3391364 0.9249518 0.4008553 0.8979759 0.3915975 0.8776648 0.8314287 0.8377025 0.8171976 0.8537325 0.7578838 0.9303008 0.3391364 0.9053563 0.3305478 0.9146354 0.2698729 0.8910649 0.7708927 0.8537325 0.7578838 0.864425 0.6974942 0.9369508 0.2776051 0.9146354 0.2698729 0.9276896 0.2099514 0.8996179 0.7096431 0.864425 0.6974942 0.8725281 0.63659 0.9462066 0.2164527 0.9276896 0.2099514 0.9490643 0.1517305 0.9146354 0.2698729 0.8921813 0.2597874 0.9091555 0.2014223 0.864425 0.6974942 0.8307024 0.6825021 0.8400784 0.6222586 0.9276896 0.2099514 0.9091555 0.2014223 0.9371914 0.1459214 0.8725281 0.63659 0.8400784 0.6222586 0.8481039 0.5616871 0.8854812 0.5141399 0.8793093 0.575425 0.8481039 0.5616871 0.6003652 0.9365409 0.6036882 0.9244517 0.716214 0.9029137 0.891547 0.4528335 0.8854812 0.5141399 0.8555443 0.5009738 0.7432609 0.92181 0.716214 0.9029137 0.7729267 0.8557598 0.891547 0.4528335 0.8629761 0.4402579 0.8709729 0.379678 0.8089643 0.8738581 0.7729267 0.8557598 0.801494 0.8004049 0.9053563 0.3305478 0.8979759 0.3915975 0.8709729 0.379678 0.8377025 0.8171976 0.801494 0.8004049 0.8186983 0.7421017 0.9053563 0.3305478 0.8802902 0.3194179 0.8921813 0.2597874 0.8537325 0.7578838 0.8186983 0.7421017 0.8307024 0.6825021 0.8709729 0.379678 0.8629761 0.4402579 0.8344583 0.4253514 0.7729267 0.8557598 0.7415011 0.8368797 0.7684796 0.7821101 0.8802902 0.3194179 0.8709729 0.379678 0.8438495 0.3654333 0.801494 0.8004049 0.7684796 0.7821101 0.7858012 0.7244532 0.8802902 0.3194179 0.8549924 0.3060064 0.8694851 0.2475308 0.8186983 0.7421017 0.7858012 0.7244532 0.7984084 0.6654416 0.8921813 0.2597874 0.8694851 0.2475308 0.8905657 0.1909774 0.8400784 0.6222586 0.8307024 0.6825021 0.7984084 0.6654416 0.9091555 0.2014223 0.8905657 0.1909774 0.9257678 0.1388037 0.8400784 0.6222586 0.8085606 0.6057375 0.8174625 0.545684 0.8481039 0.5616871 0.8174625 0.545684 0.8258861 0.4854972 0.6036882 0.9244517 0.6018056 0.9123151 0.6929221 0.8844928 0.8555443 0.5009738 0.8258861 0.4854972 0.8344583 0.4253514 0.716214 0.9029137 0.6929221 0.8844928 0.7415011 0.8368797 0.8905657 0.1909774 0.8718526 0.1787505 0.9149493 0.1304721 0.8174625 0.545684 0.8085606 0.6057375 0.7778562 0.5877237 0.8174625 0.545684 0.7872828 0.5280401 0.7963992 0.4682622 0.6018056 0.9123151 0.5966135 0.9005175 0.6716771 0.8668765 0.8258861 0.4854972 0.7963992 0.4682622 0.8058689 0.4085916 0.6929221 0.8844928 0.6716771 0.8668765 0.7132369 0.8180087 0.8438495 0.3654333 0.8344583 0.4253514 0.8058689 0.4085916 0.7415011 0.8368797 0.7132369 0.8180087 0.7379783 0.7631925 0.8438495 0.3654333 0.8164588 0.3492626 0.8292981 0.2906265 0.7684796 0.7821101 0.7379783 0.7631925 0.7547137 0.7057771 0.8549924 0.3060064 0.8292981 0.2906265 0.8463905 0.2333244 0.7858012 0.7244532 0.7547137 0.7057771 0.7673649 0.6470826 0.8694851 0.2475308 0.8463905 0.2333244 0.8718526 0.1787505 0.7984084 0.6654416 0.7673649 0.6470826 0.7778562 0.5877237 0.7132369 0.8180087 0.687114 0.7997211 0.7093584 0.7443683 0.8164588 0.3492626 0.7885947 0.3316226 0.8029742 0.2736449 0.7547137 0.7057771 0.7379783 0.7631925 0.7093584 0.7443683 0.8463905 0.2333244 0.8292981 0.2906265 0.8029742 0.2736449 0.7547137 0.7057771 0.7250548 0.6868199 0.7373226 0.6281567 0.8718526 0.1787505 0.8463905 0.2333244 0.8226673 0.2174286 0.7673649 0.6470826 0.7373226 0.6281567 0.7477793 0.5689135 0.8718526 0.1787505 0.8529051 0.1648954 0.9049428 0.1210396 0.7872828 0.5280401 0.7778562 0.5877237 0.7477793 0.5689135 0.7872828 0.5280401 0.7574036 0.5094057 0.7669216 0.4498645 0.5966135 0.9005175 0.5892183 0.8893244 0.6516128 0.8503155 0.7963992 0.4682622 0.7669216 0.4498645 0.777029 0.3905105 0.6716771 0.8668765 0.6516128 0.8503155 0.687114 0.7997211 0.8164588 0.3492626 0.8058689 0.4085916 0.777029 0.3905105 0.7477793 0.5689135 0.718112 0.5499861 0.7276275 0.4904417 0.7574036 0.5094057 0.7276275 0.4904417 0.7372524 0.4309325 0.5892183 0.8893244 0.5802933 0.8789367 0.6322468 0.8350224 0.7669216 0.4498645 0.7372524 0.4309325 0.7477135 0.3716894 0.6516128 0.8503155 0.6322468 0.8350224 0.6624315 0.7824597 0.7885947 0.3316226 0.777029 0.3905105 0.7477135 0.3716894 0.687114 0.7997211 0.6624315 0.7824597 0.6820942 0.7262273 0.8029742 0.2736449 0.7885947 0.3316226 0.7599906 0.3130286 0.7250548 0.6868199 0.7093584 0.7443683 0.6820942 0.7262273 0.8029742 0.2736449 0.7757045 0.2554866 0.7979819 0.2001475 0.7250548 0.6868199 0.6964557 0.6682395 0.7080108 0.6093447 0.8529051 0.1648954 0.8226673 0.2174286 0.7979819 0.2001475 0.7477793 0.5689135 0.7373226 0.6281567 0.7080108 0.6093447 0.8529051 0.1648954 0.8335457 0.149583 0.8960399 0.1106414 0.7757045 0.2554866 0.7599906 0.3130286 0.7303221 0.294062 0.6820942 0.7262273 0.6557719 0.7092652 0.6685932 0.650616 0.7757045 0.2554866 0.747074 0.2366482 0.771851 0.1818418 0.6964557 0.6682395 0.6685932 0.650616 0.6791713 0.5912767 0.7979819 0.2001475 0.771851 0.1818418 0.8134869 0.1330032 0.718112 0.5499861 0.7080108 0.6093447 0.6791713 0.5912767 0.8960399 0.1106414 0.8335457 0.149583 0.8134869 0.1330032 0.718112 0.5499861 0.6886333 0.5315973 0.6977451 0.4718118 0.7276275 0.4904417 0.6977451 0.4718118 0.7071703 0.4121221 0.5802933 0.8789367 0.5702692 0.869516 0.6132923 0.821187 0.7372524 0.4309325 0.7071703 0.4121221 0.7176637 0.3527587 0.6322468 0.8350224 0.6132923 0.821187 0.6387079 0.7665851 0.7599906 0.3130286 0.7477135 0.3716894 0.7176637 0.3527587 0.6820942 0.7262273 0.6624315 0.7824597 0.6387079 0.7665851 0.7071703 0.4121221 0.6977451 0.4718118 0.6675595 0.4541771 0.5702692 0.869516 0.5594361 0.8611971 0.5945719 0.8089805 0.7071703 0.4121221 0.6764574 0.3941132 0.6866088 0.3344001 0.6132923 0.821187 0.5945719 0.8089805 0.6156106 0.7524011 0.7303221 0.294062 0.7176637 0.3527587 0.6866088 0.3344001 0.6387079 0.7665851 0.6156106 0.7524011 0.6300765 0.6939069 0.7303221 0.294062 0.6992201 0.2753812 0.7165556 0.2177206 0.6557719 0.7092652 0.6300765 0.6939069 0.6412011 0.6344648 0.771851 0.1818418 0.747074 0.2366482 0.7165556 0.2177206 0.6685932 0.650616 0.6412011 0.6344648 0.6505795 0.5745334 0.8134869 0.1330032 0.771851 0.1818418 0.7435711 0.1629553 0.6886333 0.5315973 0.6791713 0.5912767 0.6505795 0.5745334 0.8886731 0.09943968 0.8134869 0.1330032 0.7922452 0.1153689 0.6886333 0.5315973 0.6591423 0.5143753 0.6675595 0.4541771 0.6412011 0.6344648 0.6300765 0.6939069 0.6047756 0.6805188 0.7435711 0.1629553 0.7165556 0.2177206 0.6835156 0.1994217 0.6412011 0.6344648 0.6140744 0.6202422 0.6220571 0.5596468 0.7435711 0.1629553 0.7121175 0.1440636 0.7689511 0.09693062 0.6591423 0.5143753 0.6505795 0.5745334 0.6220571 0.5596468 0.8835193 0.08763581 0.7922452 0.1153689 0.7689511 0.09693062 0.6591423 0.5143753 0.6294777 0.4989159 0.6369094 0.438188 0.6675595 0.4541771 0.6369094 0.438188 0.644928 0.3776025 0.5945719 0.8089805 0.5594361 0.8611971 0.5480003 0.8540929 0.6764574 0.3941132 0.644928 0.3776025 0.6542994 0.3173459 0.5945719 0.8089805 0.5759748 0.7985563 0.5929102 0.7401679 0.6992201 0.2753812 0.6866088 0.3344001 0.6542994 0.3173459 0.6156106 0.7524011 0.5929102 0.7401679 0.6047756 0.6805188 0.6992201 0.2753812 0.6663029 0.2577343 0.6835156 0.1994217 0.6369094 0.438188 0.6056935 0.4244693 0.6124644 0.3632876 0.5480003 0.8540929 0.5361169 0.8482976 0.5574334 0.7900483 0.644928 0.3776025 0.6124644 0.3632876 0.6205583 0.3023672 0.5929102 0.7401679 0.5759748 0.7985563 0.5574334 0.7900483 0.6663029 0.2577343 0.6542994 0.3173459 0.6205583 0.3023672 0.5929102 0.7401679 0.570451 0.7301064 0.5797048 0.6694138 0.6663029 0.2577343 0.6312432 0.2419617 0.6472717 0.1826331 0.6047756 0.6805188 0.5797048 0.6694138 0.5870661 0.6083472 0.6835156 0.1994217 0.6472717 0.1826331 0.6760333 0.1259607 0.6140744 0.6202422 0.5870661 0.6083472 0.5934799 0.5470946 0.7689511 0.09693062 0.7121175 0.1440636 0.6760333 0.1259607 0.6294777 0.4989159 0.6220571 0.5596468 0.5934799 0.5470946 0.7689511 0.09693062 0.7418877 0.07801818 0.885091 0.06341117 0.6294777 0.4989159 0.5995329 0.4857712 0.6056935 0.4244693 0.6760333 0.1259607 0.6472717 0.1826331 0.6072647 0.1684171 0.5870661 0.6083472 0.5600842 0.599116 0.5647808 0.537289 0.6760333 0.1259607 0.6334344 0.1097899 0.7072112 0.05916339 0.5995329 0.4857712 0.5934799 0.5470946 0.5647808 0.537289 0.7418877 0.07801818 0.7072112 0.05916339 0.8970212 0.05201429 0.5995329 0.4857712 0.5692661 0.4754315 0.5738912 0.4135942 0.6124644 0.3632876 0.6056935 0.4244693 0.5738912 0.4135942 0.5361169 0.8482976 0.5239093 0.8438869 0.5389093 0.7835682 0.6124644 0.3632876 0.579053 0.3518348 0.5853448 0.2902396 0.5574334 0.7900483 0.5389093 0.7835682 0.5481296 0.7223988 0.6312432 0.2419617 0.6205583 0.3023672 0.5853448 0.2902396 0.570451 0.7301064 0.5481296 0.7223988 0.5547546 0.6608514 0.6312432 0.2419617 0.5938816 0.2289718 0.6072647 0.1684171 0.5870661 0.6083472 0.5797048 0.6694138 0.5547546 0.6608514 0.579053 0.3518348 0.5448138 0.3438295 0.54882 0.2816787 0.5389093 0.7835682 0.5203842 0.7792032 0.5258811 0.7171856 0.5853448 0.2902396 0.54882 0.2816787 0.5543729 0.2196655 0.5481296 0.7223988 0.5258811 0.7171856 0.5298588 0.6550331 0.5938816 0.2289718 0.5543729 0.2196655 0.5634034 0.1579628 0.5547546 0.6608514 0.5298588 0.6550331 0.5330832 0.5928134 0.6334344 0.1097899 0.6072647 0.1684171 0.5634034 0.1579628 0.5600842 0.599116 0.5330832 0.5928134 0.5359469 0.5305616 0.6334344 0.1097899 0.5825701 0.0971741 0.6550087 0.04154175 0.5692661 0.4754315 0.5647808 0.537289 0.5359469 0.5305616 0.8970212 0.05201429 0.7072112 0.05916339 0.6550087 0.04154175 0.5692661 0.4754315 0.5387045 0.4683001 0.5415746 0.4060484 0.5738912 0.4135942 0.5415746 0.4060484 0.5448138 0.3438295 0.5239093 0.8438869 0.5114814 0.8409178 0.5203842 0.7792032 0.5825701 0.0971741 0.5236635 0.09009742 0.5606263 0.02870553 0.5387045 0.4683001 0.5359469 0.5305616 0.5070113 0.5271458 0.9226238 0.0424422 0.6550087 0.04154175 0.5606263 0.02870553 0.5387045 0.4683001 0.5079368 0.4646666 0.5089053 0.4021884 0.5448138 0.3438295 0.5415746 0.4060484 0.5089053 0.4021884 0.5114814 0.8409178 0.4989255 0.8394287 0.5018534 0.7770128 0.5448138 0.3438295 0.5100055 0.3397141 0.5113775 0.2772482 0.5203842 0.7792032 0.5018534 0.7770128 0.5036659 0.7145629 0.5543729 0.2196655 0.54882 0.2816787 0.5113775 0.2772482 0.5298588 0.6550331 0.5258811 0.7171856 0.5036659 0.7145629 0.5543729 0.2196655 0.5133026 0.2147992 0.5165018 0.1523888 0.5330832 0.5928134 0.5298588 0.6550331 0.5049827 0.6520974 0.5825701 0.0971741 0.5634034 0.1579628 0.5165018 0.1523888 0.5330832 0.5928134 0.5060548 0.5896236 0.5070113 0.5271458 0.5036659 0.7145629 0.5018534 0.7770128 0.4833196 0.7770274 0.5133026 0.2147992 0.5113775 0.2772482 0.4736044 0.2772619 0.5036659 0.7145629 0.4814598 0.7145795 0.4801106 0.6521146 0.5133026 0.2147992 0.4716574 0.2148125 0.4684262 0.1524026 0.5049827 0.6520974 0.4801106 0.6521146 0.4790142 0.589641 0.5236635 0.09009742 0.5165018 0.1523888 0.4684262 0.1524026 0.5060548 0.5896236 0.4790142 0.589641 0.4780379 0.5271627 0.5236635 0.09009742 0.4612001 0.09011387 0.4239621 0.02873963 0.5079368 0.4646666 0.5070113 0.5271458 0.4780379 0.5271627 0.5606263 0.02870553 0.4239621 0.02873963 1.019296 0.03663933 0.5079368 0.4646666 0.4770951 0.4646827 0.4761104 0.4022036 0.5089053 0.4021884 0.4761104 0.4022036 0.4749941 0.3397284 0.4989255 0.8394287 0.486328 0.8394391 0.4833196 0.7770274 0.5100055 0.3397141 0.4749941 0.3397284 0.4736044 0.2772619 0.4770951 0.4646827 0.4780379 0.5271627 0.4491014 0.5306118 0.01929616 0.03663933 0.4239621 0.02873963 0.3298254 0.04161161 0.4770951 0.4646827 0.4463269 0.468348 0.4434411 0.4060937 0.4761104 0.4022036 0.4434411 0.4060937 0.4401866 0.3438721 0.486328 0.8394391 0.4737731 0.8409487 0.4647885 0.7792469 0.4749941 0.3397284 0.4401866 0.3438721 0.4361638 0.281719 0.4833196 0.7770274 0.4647885 0.7792469 0.4592436 0.7172351 0.4716574 0.2148125 0.4736044 0.2772619 0.4361638 0.281719 0.4814598 0.7145795 0.4592436 0.7172351 0.4552333 0.6550847 0.4716574 0.2148125 0.4305911 0.2197046 0.4215336 0.1580027 0.4801106 0.6521146 0.4552333 0.6550847 0.4519847 0.5928651 0.4684262 0.1524026 0.4215336 0.1580027 0.4023212 0.09721994 0.4790142 0.589641 0.4519847 0.5928651 0.4491014 0.5306118 0.4612001 0.09011387 0.4023212 0.09721994 0.3298254 0.04161161 0.4305911 0.2197046 0.4361638 0.281719 0.3996422 0.2903048 0.4552333 0.6550847 0.4592436 0.7172351 0.436993 0.7224807 0.4305911 0.2197046 0.3910893 0.2290341 0.3776866 0.1684792 0.4552333 0.6550847 0.4303352 0.6609367 0.4249814 0.5992012 0.4023212 0.09721994 0.4215336 0.1580027 0.3776866 0.1684792 0.4519847 0.5928651 0.4249814 0.5992012 0.4202656 0.5373717 0.4023212 0.09721994 0.3514931 0.1098571 0.277736 0.05924415 0.4463269 0.468348 0.4491014 0.5306118 0.4202656 0.5373717 0.06264001 0.04247719 0.3298254 0.04161161 0.277736 0.05924415 0.4463269 0.468348 0.4157641 0.4755103 0.4111244 0.4136683 0.4434411 0.4060937 0.4111244 0.4136683 0.4059485 0.3519042 0.4737731 0.8409487 0.4613473 0.8439381 0.4462627 0.7836406 0.4401866 0.3438721 0.4059485 0.3519042 0.3996422 0.2903048 0.4592436 0.7172351 0.4647885 0.7792469 0.4462627 0.7836406 0.277736 0.05924415 0.2431051 0.07810217 0.1000552 0.06346303 0.4157641 0.4755103 0.3854953 0.4858791 0.3793213 0.4245703 0.4111244 0.4136683 0.3793213 0.4245703 0.3725381 0.3633816 0.4613473 0.8439381 0.449143 0.8483685 0.4277372 0.7901487 0.4059485 0.3519042 0.3725381 0.3633816 0.3644323 0.3024546 0.4462627 0.7836406 0.4277372 0.7901487 0.4146683 0.7302197 0.3910893 0.2290341 0.3996422 0.2903048 0.3644323 0.3024546 0.4303352 0.6609367 0.436993 0.7224807 0.4146683 0.7302197 0.3910893 0.2290341 0.3537352 0.2420439 0.3376945 0.1827127 0.4249814 0.5992012 0.4303352 0.6609367 0.4053811 0.6695316 0.3776866 0.1684792 0.3376945 0.1827127 0.3089248 0.1260416 0.4249814 0.5992012 0.3979957 0.6084646 0.3915634 0.5472081 0.3514931 0.1098571 0.3089248 0.1260416 0.2431051 0.07810217 0.4157641 0.4755103 0.4202656 0.5373717 0.3915634 0.5472081 0.4053811 0.6695316 0.4146683 0.7302197 0.392204 0.7403113 0.3537352 0.2420439 0.3186824 0.2578327 0.3014633 0.1995143 0.3979957 0.6084646 0.4053811 0.6695316 0.3803044 0.6806673 0.3376945 0.1827127 0.3014633 0.1995143 0.2728623 0.1441527 0.3979957 0.6084646 0.370982 0.6203895 0.3629816 0.5597888 0.2431051 0.07810217 0.3089248 0.1260416 0.2728623 0.1441527 0.3854953 0.4858791 0.3915634 0.5472081 0.3629816 0.5597888 0.1000552 0.06346303 0.2431051 0.07810217 0.2160624 0.09701496 0.3854953 0.4858791 0.355547 0.4990501 0.3481036 0.4383131 0.3725381 0.3633816 0.3793213 0.4245703 0.3481036 0.4383131 0.449143 0.8483685 0.4372645 0.8541828 0.4091939 0.7986839 0.3725381 0.3633816 0.3400747 0.377718 0.3306941 0.3174523 0.4277372 0.7901487 0.4091939 0.7986839 0.392204 0.7403113 0.3537352 0.2420439 0.3644323 0.3024546 0.3306941 0.3174523 0.355547 0.4990501 0.3258773 0.5145326 0.3174503 0.4543229 0.3481036 0.4383131 0.3174503 0.4543229 0.3085443 0.3942467 0.4372645 0.8541828 0.4258353 0.8613048 0.3905939 0.809134 0.3400747 0.377718 0.3085443 0.3942467 0.2983864 0.3345217 0.4091939 0.7986839 0.3905939 0.809134 0.3694965 0.7525728 0.3186824 0.2578327 0.3306941 0.3174523 0.2983864 0.3345217 0.392204 0.7403113 0.3694965 0.7525728 0.3549953 0.6940838 0.3186824 0.2578327 0.2857701 0.2754919 0.2684326 0.217822 0.370982 0.6203895 0.3803044 0.6806673 0.3549953 0.6940838 0.2728623 0.1441527 0.3014633 0.1995143 0.2684326 0.217822 0.370982 0.6203895 0.3438475 0.6346392 0.3344526 0.5747007 0.2728623 0.1441527 0.2414228 0.1630486 0.1927784 0.1154518 0.355547 0.4990501 0.3629816 0.5597888 0.3344526 0.5747007 0.1034273 0.07555043 0.2160624 0.09701496 0.1927784 0.1154518 0.2857701 0.2754919 0.2546709 0.2941809 0.2379202 0.2367545 0.3438475 0.6346392 0.3549953 0.6940838 0.3292887 0.7094673 0.2684326 0.217822 0.2379202 0.2367545 0.2131515 0.1819364 0.3438475 0.6346392 0.3164449 0.6508139 0.3058518 0.5914652 0.2414228 0.1630486 0.2131515 0.1819364 0.1715415 0.1330838 0.3258773 0.5145326 0.3344526 0.5747007 0.3058518 0.5914652 0.1927784 0.1154518 0.1715415 0.1330838 0.09641396 0.09949165 0.3174503 0.4543229 0.3258773 0.5145326 0.2963792 0.5317736 0.3174503 0.4543229 0.2872596 0.4719741 0.2778287 0.4122695 0.4258353 0.8613048 0.4150114 0.8696404 0.3718692 0.8213651 0.3085443 0.3942467 0.2778287 0.4122695 0.2673314 0.3528915 0.3905939 0.809134 0.3718692 0.8213651 0.3463891 0.7667828 0.2857701 0.2754919 0.2983864 0.3345217 0.2673314 0.3528915 0.3549953 0.6940838 0.3694965 0.7525728 0.3463891 0.7667828 0.2872596 0.4719741 0.2573703 0.4906155 0.247742 0.4310891 0.4150114 0.8696404 0.4049999 0.8790763 0.3529083 0.8352231 0.2778287 0.4122695 0.247742 0.4310891 0.2372796 0.3718289 0.3718692 0.8213651 0.3529083 0.8352231 0.3226514 0.7826805 0.2546709 0.2941809 0.2673314 0.3528915 0.2372796 0.3718289 0.3292887 0.7094673 0.3463891 0.7667828 0.3226514 0.7826805 0.2546709 0.2941809 0.225003 0.3131518 0.2092928 0.2555946 0.3164449 0.6508139 0.3292887 0.7094673 0.3029512 0.7264504 0.2379202 0.2367545 0.2092928 0.2555946 0.1870253 0.2002409 0.3164449 0.6508139 0.2885685 0.668456 0.2770006 0.6095497 0.1715415 0.1330838 0.2131515 0.1819364 0.1870253 0.2002409 0.2963792 0.5317736 0.3058518 0.5914652 0.2770006 0.6095497 0.1715415 0.1330838 0.1514846 0.1496599 0.08903849 0.1106907 0.2963792 0.5317736 0.2668911 0.5501763 0.2573703 0.4906155 0.2092928 0.2555946 0.182024 0.2737511 0.162342 0.2175185 0.2885685 0.668456 0.2599516 0.6870493 0.2476739 0.6283716 0.1514846 0.1496599 0.1870253 0.2002409 0.162342 0.2175185 0.2668911 0.5501763 0.2770006 0.6095497 0.2476739 0.6283716 0.08903849 0.1106907 0.1514846 0.1496599 0.1321256 0.1649673 0.2668911 0.5501763 0.2372119 0.5691114 0.2275851 0.5095852 0.2573703 0.4906155 0.2275851 0.5095852 0.2180665 0.4500249 0.4049999 0.8790763 0.3960925 0.8894771 0.3335328 0.8505368 0.247742 0.4310891 0.2180665 0.4500249 0.2079604 0.390652 0.3529083 0.8352231 0.3335328 0.8505368 0.2979491 0.799961 0.225003 0.3131518 0.2372796 0.3718289 0.2079604 0.390652 0.3029512 0.7264504 0.3226514 0.7826805 0.2979491 0.799961 0.2092928 0.2555946 0.225003 0.3131518 0.1963976 0.3317459 0.2885685 0.668456 0.3029512 0.7264504 0.2756667 0.7446073 0.3335328 0.8505368 0.3960925 0.8894771 0.3887225 0.9006809 0.2180665 0.4500249 0.1885811 0.4684205 0.1791153 0.4087299 0.3335328 0.8505368 0.3134537 0.867116 0.2717982 0.8182626 0.1963976 0.3317459 0.2079604 0.390652 0.1791153 0.4087299 0.2756667 0.7446073 0.2979491 0.799961 0.2717982 0.8182626 0.1963976 0.3317459 0.1685307 0.3493819 0.1556993 0.2907277 0.2599516 0.6870493 0.2756667 0.7446073 0.2470199 0.7634406 0.182024 0.2737511 0.1556993 0.2907277 0.1386191 0.2334085 0.2599516 0.6870493 0.23027 0.7060118 0.2176133 0.6473003 0.1321256 0.1649673 0.162342 0.2175185 0.1386191 0.2334085 0.2372119 0.5691114 0.2476739 0.6283716 0.2176133 0.6473003 0.1321256 0.1649673 0.1131775 0.1788164 0.07011771 0.1305137 0.2372119 0.5691114 0.2071207 0.5879223 0.197695 0.5282186 0.2275851 0.5095852 0.197695 0.5282186 0.1885811 0.4684205 0.23027 0.7060118 0.199155 0.7246842 0.1865485 0.665653 0.1131775 0.1788164 0.1386191 0.2334085 0.1155236 0.2476066 0.2071207 0.5879223 0.2176133 0.6473003 0.1865485 0.665653 0.1131775 0.1788164 0.09446328 0.1910358 0.05929529 0.1388404 0.2071207 0.5879223 0.1764 0.6059286 0.1675031 0.5458543 0.1885811 0.4684205 0.197695 0.5282186 0.1675031 0.5458543 0.3134537 0.867116 0.3887225 0.9006809 0.3835681 0.912486 0.1885811 0.4684205 0.1590852 0.4856469 0.1505197 0.4254812 0.3134537 0.867116 0.292185 0.8847473 0.243494 0.837141 0.1685307 0.3493819 0.1791153 0.4087299 0.1505197 0.4254812 0.2470199 0.7634406 0.2717982 0.8182626 0.243494 0.837141 0.1685307 0.3493819 0.1411362 0.3655441 0.1300031 0.3060992 0.2470199 0.7634406 0.2164838 0.7823588 0.199155 0.7246842 0.1386191 0.2334085 0.1556993 0.2907277 0.1300031 0.3060992 0.1590852 0.4856469 0.1294175 0.5011084 0.1219953 0.4403737 0.292185 0.8847473 0.2688526 0.9031792 0.2120112 0.856019 0.1411362 0.3655441 0.1505197 0.4254812 0.1219953 0.4403737 0.2164838 0.7823588 0.243494 0.837141 0.2120112 0.856019 0.1411362 0.3655441 0.1140086 0.379776 0.1047028 0.3194993 0.199155 0.7246842 0.2164838 0.7823588 0.1834254 0.8006429 0.1300031 0.3060992 0.1047028 0.3194993 0.09282612 0.2598529 0.199155 0.7246842 0.1662256 0.7423182 0.1542308 0.6826973 0.09446328 0.1910358 0.1155236 0.2476066 0.09282612 0.2598529 0.1764 0.6059286 0.1865485 0.665653 0.1542308 0.6826973 0.09446328 0.1910358 0.07587218 0.2014721 0.04786872 0.1459523 0.1764 0.6059286 0.1448646 0.6224332 0.1368486 0.5618414 0.1590852 0.4856469 0.1675031 0.5458543 0.1368486 0.5618414 0.292185 0.8847473 0.3835681 0.912486 0.3817437 0.9246256 0.07587218 0.2014721 0.09282612 0.2598529 0.07037049 0.2699261 0.1448646 0.6224332 0.1542308 0.6826973 0.1204835 0.6976624 0.07587218 0.2014721 0.05733662 0.2099915 0.03599351 0.1517553 0.1448646 0.6224332 0.1123972 0.6367389 0.1056304 0.5755556 0.1368486 0.5618414 0.1056304 0.5755556 0.09947144 0.514253 0.3817437 0.9246256 0.385161 0.9367107 0.2417302 0.9220808 0.1294175 0.5011084 0.09947144 0.514253 0.093418 0.45293 0.2688526 0.9031792 0.2417302 0.9220808 0.1758925 0.8741014 0.1140086 0.379776 0.1219953 0.4403737 0.093418 0.45293 0.1834254 0.8006429 0.2120112 0.856019 0.1758925 0.8741014 0.1140086 0.379776 0.0870012 0.3916786 0.07963401 0.3306146 0.1834254 0.8006429 0.1471639 0.817411 0.131156 0.7580731 0.1047028 0.3194993 0.07963401 0.3306146 0.07037049 0.2699261 0.1662256 0.7423182 0.131156 0.7580731 0.1204835 0.6976624 0.1758925 0.8741014 0.2417302 0.9220808 0.2069531 0.9409168 0.0870012 0.3916786 0.093418 0.45293 0.06472045 0.4627382 0.1471639 0.817411 0.1758925 0.8741014 0.1332573 0.8902431 0.0870012 0.3916786 0.06002157 0.4009161 0.05468714 0.3391861 0.131156 0.7580731 0.1471639 0.817411 0.1071433 0.8316007 0.07963401 0.3306146 0.05468714 0.3391861 0.04805356 0.2776444 0.131156 0.7580731 0.09378856 0.7710414 0.08526748 0.7097733 0.05733662 0.2099915 0.07037049 0.2699261 0.04805356 0.2776444 0.1123972 0.6367389 0.1204835 0.6976624 0.08526748 0.7097733 0.05733662 0.2099915 0.03881853 0.2164819 0.02379328 0.1561736 0.1123972 0.6367389 0.07898485 0.6481801 0.07382827 0.5864241 0.09947144 0.514253 0.1056304 0.5755556 0.07382827 0.5864241 0.385161 0.9367107 0.3971338 0.9481052 0.2069531 0.9409168 0.09947144 0.514253 0.06920558 0.524591 0.06472045 0.4627382 0.07898485 0.6481801 0.08526748 0.7097733 0.04874467 0.7183161 0.03881853 0.2164819 0.02029967 0.2208569 0.0113722 0.1591499 0.07898485 0.6481801 0.04474818 0.6561728 0.04151457 0.5939623 0.06920558 0.524591 0.07382827 0.5864241 0.04151457 0.5939623 0.3971338 0.9481052 0.4228305 0.9576696 0.1545662 0.9585033 0.06920558 0.524591 0.03864717 0.5317196 0.03589004 0.4694672 0.2069531 0.9409168 0.1545662 0.9585033 0.08236718 0.9028213 0.06002157 0.4009161 0.06472045 0.4627382 0.03589004 0.4694672 0.1332573 0.8902431 0.08236718 0.9028213 0.06327778 0.8420249 0.06002157 0.4009161 0.03302448 0.4072239 0.02979582 0.3450124 0.09378856 0.7710414 0.1071433 0.8316007 0.06327778 0.8420249 0.05468714 0.3391861 0.02979582 0.3450124 0.02581018 0.2828674 0.09378856 0.7710414 0.05428034 0.7803239 0.04874467 0.7183161 0.04805356 0.2776444 0.02581018 0.2828674 0.02029967 0.2208569 0.03302448 0.4072239 0.03589004 0.4694672 0.006959736 0.4728841 0.08236718 0.9028213 0.02346807 0.9098559 0.01638609 0.8475685 0.03302448 0.4072239 0.006001472 0.4104183 0.00492531 0.3479555 0.05428034 0.7803239 0.06327778 0.8420249 0.01638609 0.8475685 0.02581018 0.2828674 0.02979582 0.3450124 0.00492531 0.3479555 0.05428034 0.7803239 0.01321828 0.785167 0.01130914 0.7227291 0.02581018 0.2828674 0.003600955 0.285499 0.001775324 0.2230563 0.04474818 0.6561728 0.04874467 0.7183161 0.01130914 0.7227291 1.0203 0.2208569 1.001775 0.2230563 0.9988229 0.1606459 0.04151457 0.5939623 0.04474818 0.6561728 0.009946048 0.6602758 0.04151457 0.5939623 0.008850932 0.5978149 0.00788486 0.5353502 0.4228305 0.9576696 0.4663997 0.9634672 0.05996555 0.9712674 0.03864717 0.5317196 0.00788486 0.5353502 0.006959736 0.4728841 0.1545662 0.9585033 0.05996555 0.9712674 0.02346807 0.9098559 1.001775 0.2230563 0.9832485 0.2230503 0.9862315 0.1606423 1.009946 0.6602758 0.9749442 0.6602513 0.9760642 0.5977937 1.008851 0.5978149 0.9760642 0.5977937 0.9770506 0.535332 0.05996555 0.9712674 0.4663997 0.9634672 0.5197656 0.9634217 1.007885 0.5353502 0.9770506 0.535332 0.9779933 0.4728688 1.023468 0.9098559 1.059966 0.9712674 0.9236539 0.9711539 1.006001 0.4104183 1.00696 0.4728841 0.9779933 0.4728688 1.016386 0.8475685 1.023468 0.9098559 0.9610577 0.9098034 1.006001 0.4104183 0.9789676 0.4104056 0.9800599 0.3479452 1.013218 0.785167 1.016386 0.8475685 0.9683353 0.847529 1.004925 0.3479555 0.9800599 0.3479452 0.9814017 0.2854908 1.013218 0.785167 0.9715889 0.7851341 0.9735478 0.7227008 1.003601 0.285499 0.9814017 0.2854908 0.9832485 0.2230503 1.009946 0.6602758 1.011309 0.7227291 0.9735478 0.7227008 0.9789676 0.4104056 0.951946 0.4071862 0.9551903 0.3449817 0.9715889 0.7851341 0.9683353 0.847529 0.9214769 0.841912 0.9800599 0.3479452 0.9551903 0.3449817 0.9591931 0.2828431 0.9715889 0.7851341 0.9305438 0.7802285 0.9361224 0.7182335 0.9814017 0.2854908 0.9591931 0.2828431 0.9647247 0.2208389 0.9749442 0.6602513 0.9735478 0.7227008 0.9361224 0.7182335 0.9862315 0.1606423 0.9832485 0.2230503 0.9647247 0.2208389 0.9749442 0.6602513 0.9401488 0.6561009 0.9434052 0.5939 0.9760642 0.5977937 0.9434052 0.5939 0.9462915 0.5316662 0.5197656 0.9634217 0.5630894 0.9575534 0.8298811 0.9582708 0.9770506 0.535332 0.9462915 0.5316662 0.9490651 0.4694219 0.9236539 0.9711539 0.8298811 0.9582708 0.9022539 0.902677 0.9789676 0.4104056 0.9779933 0.4728688 0.9490651 0.4694219 0.9610577 0.9098034 0.9022539 0.902677 0.9214769 0.841912 0.9434052 0.5939 0.9111002 0.5863247 0.9157391 0.5245054 0.8298811 0.9582708 0.5630894 0.9575534 0.5885478 0.9479513 0.9462915 0.5316662 0.9157391 0.5245054 0.9202389 0.4626654 0.9022539 0.902677 0.8298811 0.9582708 0.7778791 0.9406516 0.9490651 0.4694219 0.9202389 0.4626654 0.9249518 0.4008553 0.9214769 0.841912 0.9022539 0.902677 0.8514901 0.8900356 0.951946 0.4071862 0.9249518 0.4008553 0.9303008 0.3391364 0.9305438 0.7802285 0.9214769 0.841912 0.8776648 0.8314287 0.9551903 0.3449817 0.9303008 0.3391364 0.9369508 0.2776051 0.9361224 0.7182335 0.9305438 0.7802285 0.8910649 0.7708927 0.9591931 0.2828431 0.9369508 0.2776051 0.9462066 0.2164527 0.9401488 0.6561009 0.9361224 0.7182335 0.8996179 0.7096431 0.9647247 0.2208389 0.9462066 0.2164527 0.9612628 0.1561555 0.9434052 0.5939 0.9401488 0.6561009 0.9059244 0.648066 + + + + + + + + + + + + + + +

0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 2 2 9 9 9 10 10 10 11 3 3 12 11 11 13 12 12 14 13 13 15 9 9 16 14 14 17 15 15 18 11 11 19 16 16 20 13 13 21 17 17 22 18 18 23 15 15 24 19 19 25 20 20 26 21 21 27 17 17 28 22 22 29 20 20 30 23 23 31 24 24 32 21 21 33 25 25 34 26 26 35 24 24 36 27 27 37 28 28 38 26 26 39 29 29 40 30 30 41 28 28 42 31 31 43 0 0 44 30 30 45 8 8 46 7 7 47 25 25 48 32 32 49 29 29 50 27 27 51 33 33 52 31 31 53 29 29 54 34 34 55 8 8 56 31 31 57 35 35 58 1 1 59 5 5 60 4 4 61 36 36 62 6 6 63 8 8 64 34 34 65 9 9 66 35 35 67 37 37 68 5 5 69 38 38 70 11 11 71 14 14 72 37 37 73 39 39 74 11 11 75 40 40 76 16 16 77 14 14 78 41 41 79 17 17 80 16 16 81 42 42 82 19 19 83 22 22 84 41 41 85 43 43 86 19 19 87 44 44 88 23 23 89 22 22 90 45 45 91 25 25 92 23 23 93 46 46 94 27 27 95 41 41 96 47 47 97 48 48 98 40 40 99 49 49 100 42 42 101 43 43 102 48 48 103 50 50 104 42 42 105 51 51 106 44 44 107 43 43 108 52 52 109 45 45 110 44 44 111 53 53 112 46 46 113 45 45 114 54 54 115 32 32 116 33 33 117 53 53 118 55 55 119 32 32 120 56 56 121 34 34 122 33 33 123 57 57 124 35 35 125 36 36 126 4 4 127 58 58 128 6 6 129 34 34 130 56 56 131 35 35 132 59 59 133 37 37 134 36 36 135 60 60 136 38 38 137 37 37 138 47 47 139 39 39 140 38 38 141 61 61 142 40 40 143 54 54 144 62 62 145 56 56 146 57 57 147 63 63 148 64 64 149 58 58 150 4 4 151 65 65 152 6 6 153 56 56 154 62 62 155 57 57 156 66 66 157 59 59 158 58 58 159 67 67 160 60 60 161 59 59 162 68 68 163 47 47 164 60 60 165 69 69 166 61 61 167 48 48 168 68 68 169 70 70 170 61 61 171 71 71 172 49 49 173 48 48 174 72 72 175 50 50 176 49 49 177 73 73 178 51 51 179 50 50 180 74 74 181 52 52 182 51 51 183 75 75 184 53 53 185 52 52 186 76 76 187 54 54 188 53 53 189 63 63 190 55 55 191 69 69 192 77 77 193 71 71 194 70 70 195 78 78 196 72 72 197 73 73 198 77 77 199 79 79 200 74 74 201 78 78 202 80 80 203 73 73 204 81 81 205 75 75 206 76 76 207 80 80 208 82 82 209 75 75 210 83 83 211 63 63 212 76 76 213 84 84 214 62 62 215 64 64 216 83 83 217 85 85 218 65 65 219 4 4 220 86 86 221 6 6 222 62 62 223 84 84 224 64 64 225 87 87 226 66 66 227 65 65 228 88 88 229 67 67 230 66 66 231 89 89 232 68 68 233 67 67 234 90 90 235 69 69 236 70 70 237 89 89 238 91 91 239 83 83 240 92 92 241 85 85 242 86 86 243 4 4 244 93 93 245 6 6 246 84 84 247 94 94 248 85 85 249 95 95 250 87 87 251 86 86 252 96 96 253 88 88 254 87 87 255 97 97 256 89 89 257 88 88 258 98 98 259 90 90 260 91 91 261 97 97 262 99 99 263 90 90 264 100 100 265 77 77 266 78 78 267 99 99 268 101 101 269 79 79 270 100 100 271 102 102 272 78 78 273 103 103 274 80 80 275 79 79 276 104 104 277 81 81 278 82 82 279 103 103 280 105 105 281 83 83 282 104 104 283 106 106 284 82 82 285 94 94 286 84 84 287 101 101 288 107 107 289 108 108 290 100 100 291 109 109 292 102 102 293 101 101 294 110 110 295 103 103 296 102 102 297 111 111 298 104 104 299 103 103 300 112 112 301 105 105 302 106 106 303 111 111 304 113 113 305 94 94 306 112 112 307 114 114 308 106 106 309 115 115 310 92 92 311 93 93 312 4 4 313 116 116 314 6 6 315 94 94 316 114 114 317 92 92 318 117 117 319 95 95 320 93 93 321 118 118 322 96 96 323 95 95 324 119 119 325 97 97 326 96 96 327 120 120 328 98 98 329 99 99 330 119 119 331 107 107 332 100 100 333 120 120 334 121 121 335 116 116 336 4 4 337 122 122 338 6 6 339 114 114 340 123 123 341 117 117 342 124 124 343 125 125 344 116 116 345 126 126 346 118 118 347 117 117 348 127 127 349 119 119 350 118 118 351 128 128 352 120 120 353 107 107 354 127 127 355 129 129 356 120 120 357 130 130 358 121 121 359 107 107 360 131 131 361 108 108 362 121 121 363 132 132 364 109 109 365 110 110 366 131 131 367 133 133 368 109 109 369 134 134 370 111 111 371 112 112 372 133 133 373 135 135 374 113 113 375 134 134 376 136 136 377 114 114 378 135 135 379 123 123 380 113 113 381 124 124 382 115 115 383 132 132 384 137 137 385 138 138 386 133 133 387 139 139 388 140 140 389 132 132 390 141 141 391 134 134 392 133 133 393 142 142 394 135 135 395 136 136 396 141 141 397 143 143 398 123 123 399 142 142 400 144 144 401 136 136 402 145 145 403 124 124 404 122 122 405 4 4 406 146 146 407 6 6 408 123 123 409 144 144 410 124 124 411 147 147 412 125 125 413 126 126 414 146 146 415 148 148 416 125 125 417 149 149 418 127 127 419 126 126 420 150 150 421 128 128 422 129 129 423 149 149 424 151 151 425 128 128 426 137 137 427 130 130 428 129 129 429 139 139 430 131 131 431 145 145 432 152 152 433 147 147 434 146 146 435 153 153 436 148 148 437 147 147 438 154 154 439 149 149 440 150 150 441 153 153 442 155 155 443 151 151 444 154 154 445 156 156 446 150 150 447 157 157 448 137 137 449 151 151 450 158 158 451 139 139 452 137 137 453 159 159 454 138 138 455 139 139 456 160 160 457 140 140 458 138 138 459 161 161 460 141 141 461 142 142 462 160 160 463 162 162 464 143 143 465 161 161 466 163 163 467 142 142 468 164 164 469 144 144 470 143 143 471 165 165 472 145 145 473 146 146 474 4 4 475 166 166 476 6 6 477 144 144 478 164 164 479 160 160 480 167 167 481 168 168 482 159 159 483 169 169 484 161 161 485 160 160 486 170 170 487 162 162 488 163 163 489 169 169 490 171 171 491 162 162 492 172 172 493 164 164 494 163 163 495 173 173 496 165 165 497 166 166 498 4 4 499 174 174 500 6 6 501 164 164 502 172 172 503 152 152 504 173 173 505 175 175 506 166 166 507 176 176 508 153 153 509 152 152 510 177 177 511 154 154 512 153 153 513 178 178 514 155 155 515 156 156 516 177 177 517 179 179 518 155 155 519 180 180 520 157 157 521 156 156 522 167 167 523 158 158 524 159 159 525 180 180 526 181 181 527 175 175 528 182 182 529 177 177 530 176 176 531 183 183 532 178 178 533 177 177 534 184 184 535 179 179 536 178 178 537 185 185 538 180 180 539 179 179 540 186 186 541 167 167 542 180 180 543 187 187 544 181 181 545 168 168 546 186 186 547 188 188 548 181 181 549 189 189 550 169 169 551 168 168 552 190 190 553 170 170 554 171 171 555 189 189 556 191 191 557 172 172 558 190 190 559 192 192 560 171 171 561 193 193 562 173 173 563 174 174 564 4 4 565 194 194 566 6 6 567 172 172 568 192 192 569 173 173 570 195 195 571 175 175 572 174 174 573 196 196 574 176 176 575 188 188 576 197 197 577 190 190 578 191 191 579 198 198 580 199 199 581 192 192 582 197 197 583 200 200 584 191 191 585 201 201 586 193 193 587 194 194 588 4 4 589 202 202 590 6 6 591 192 192 592 200 200 593 195 195 594 201 201 595 203 203 596 194 194 597 204 204 598 196 196 599 195 195 600 205 205 601 182 182 602 196 196 603 206 206 604 183 183 605 184 184 606 205 205 607 207 207 608 185 185 609 206 206 610 208 208 611 184 184 612 209 209 613 186 186 614 187 187 615 208 208 616 210 210 617 188 188 618 209 209 619 211 211 620 187 187 621 198 198 622 189 189 623 206 206 624 212 212 625 213 213 626 207 207 627 214 214 628 215 215 629 206 206 630 216 216 631 208 208 632 207 207 633 217 217 634 209 209 635 208 208 636 218 218 637 210 210 638 211 211 639 217 217 640 219 219 641 210 210 642 220 220 643 198 198 644 211 211 645 221 221 646 197 197 647 199 199 648 220 220 649 222 222 650 197 197 651 223 223 652 200 200 653 199 199 654 224 224 655 201 201 656 202 202 657 4 4 658 225 225 659 6 6 660 200 200 661 223 223 662 201 201 663 226 226 664 203 203 665 202 202 666 212 212 667 204 204 668 203 203 669 214 214 670 205 205 671 222 222 672 227 227 673 228 228 674 223 223 675 229 229 676 230 230 677 222 222 678 231 231 679 224 224 680 225 225 681 4 4 682 232 232 683 6 6 684 223 223 685 230 230 686 224 224 687 233 233 688 226 226 689 225 225 690 234 234 691 212 212 692 226 226 693 235 235 694 214 214 695 212 212 696 236 236 697 213 213 698 215 215 699 235 235 700 237 237 701 213 213 702 238 238 703 216 216 704 215 215 705 239 239 706 217 217 707 216 216 708 240 240 709 218 218 710 217 217 711 241 241 712 219 219 713 218 218 714 227 227 715 220 220 716 219 219 717 229 229 718 221 221 719 237 237 720 242 242 721 243 243 722 238 238 723 244 244 724 245 245 725 237 237 726 246 246 727 239 239 728 238 238 729 247 247 730 240 240 731 241 241 732 246 246 733 248 248 734 240 240 735 249 249 736 227 227 737 241 241 738 250 250 739 229 229 740 228 228 741 249 249 742 251 251 743 230 230 744 250 250 745 252 252 746 228 228 747 253 253 748 231 231 749 232 232 750 4 4 751 254 254 752 6 6 753 230 230 754 252 252 755 231 231 756 255 255 757 233 233 758 232 232 759 256 256 760 234 234 761 233 233 762 242 242 763 235 235 764 236 236 765 256 256 766 244 244 767 250 250 768 257 257 769 252 252 770 251 251 771 258 258 772 253 253 773 254 254 774 4 4 775 259 259 776 6 6 777 252 252 778 257 257 779 253 253 780 260 260 781 255 255 782 254 254 783 261 261 784 256 256 785 255 255 786 262 262 787 242 242 788 256 256 789 263 263 790 244 244 791 243 243 792 262 262 793 264 264 794 245 245 795 263 263 796 265 265 797 243 243 798 266 266 799 246 246 800 247 247 801 265 265 802 267 267 803 246 246 804 268 268 805 248 248 806 247 247 807 269 269 808 249 249 809 248 248 810 270 270 811 250 250 812 251 251 813 269 269 814 271 271 815 265 265 816 272 272 817 273 273 818 264 264 819 274 274 820 266 266 821 267 267 822 273 273 823 275 275 824 266 266 825 276 276 826 268 268 827 267 267 828 277 277 829 269 269 830 270 270 831 276 276 832 278 278 833 271 271 834 277 277 835 279 279 836 257 257 837 278 278 838 280 280 839 271 271 840 281 281 841 258 258 842 259 259 843 4 4 844 282 282 845 6 6 846 257 257 847 280 280 848 260 260 849 281 281 850 283 283 851 259 259 852 284 284 853 261 261 854 260 260 855 285 285 856 262 262 857 261 261 858 272 272 859 263 263 860 264 264 861 285 285 862 286 286 863 279 279 864 287 287 865 281 281 866 282 282 867 4 4 868 288 288 869 6 6 870 280 280 871 289 289 872 281 281 873 290 290 874 283 283 875 282 282 876 291 291 877 284 284 878 283 283 879 292 292 880 285 285 881 284 284 882 293 293 883 272 272 884 286 286 885 292 292 886 294 294 887 272 272 888 295 295 889 273 273 890 286 286 891 296 296 892 274 274 893 275 275 894 295 295 895 297 297 896 276 276 897 296 296 898 298 298 899 275 275 900 299 299 901 277 277 902 276 276 903 300 300 904 278 278 905 279 279 906 299 299 907 301 301 908 280 280 909 300 300 910 289 289 911 294 294 912 302 302 913 296 296 914 297 297 915 303 303 916 304 304 917 296 296 918 305 305 919 298 298 920 297 297 921 306 306 922 299 299 923 298 298 924 307 307 925 300 300 926 301 301 927 306 306 928 308 308 929 300 300 930 309 309 931 289 289 932 287 287 933 308 308 934 310 310 935 288 288 936 4 4 937 311 311 938 6 6 939 289 289 940 309 309 941 287 287 942 312 312 943 290 290 944 288 288 945 313 313 946 291 291 947 290 290 948 314 314 949 292 292 950 291 291 951 315 315 952 293 293 953 294 294 954 314 314 955 316 316 956 295 295 957 315 315 958 303 303 959 6 6 960 309 309 961 317 317 962 310 310 963 318 318 964 312 312 965 311 311 966 319 319 967 313 313 968 312 312 969 320 320 970 314 314 971 313 313 972 321 321 973 315 315 974 316 316 975 320 320 976 322 322 977 303 303 978 321 321 979 323 323 980 316 316 981 324 324 982 302 302 983 304 304 984 323 323 985 325 325 986 302 302 987 326 326 988 305 305 989 304 304 990 327 327 991 306 306 992 307 307 993 326 326 994 328 328 995 308 308 996 327 327 997 329 329 998 307 307 999 317 317 1000 309 309 1001 308 308 1002 330 330 1003 310 310 1004 311 311 1005 4 4 1006 331 331 1007 324 324 1008 332 332 1009 326 326 1010 325 325 1011 333 333 1012 327 327 1013 328 328 1014 332 332 1015 334 334 1016 329 329 1017 333 333 1018 335 335 1019 317 317 1020 334 334 1021 336 336 1022 329 329 1023 337 337 1024 330 330 1025 331 331 1026 4 4 1027 338 338 1028 6 6 1029 317 317 1030 336 336 1031 330 330 1032 339 339 1033 318 318 1034 331 331 1035 340 340 1036 319 319 1037 318 318 1038 341 341 1039 320 320 1040 319 319 1041 342 342 1042 321 321 1043 322 322 1044 341 341 1045 343 343 1046 323 323 1047 342 342 1048 344 344 1049 324 324 1050 343 343 1051 345 345 1052 325 325 1053 344 344 1054 346 346 1055 340 340 1056 347 347 1057 348 348 1058 339 339 1059 349 349 1060 341 341 1061 340 340 1062 350 350 1063 342 342 1064 343 343 1065 349 349 1066 351 351 1067 344 344 1068 350 350 1069 352 352 1070 343 343 1071 353 353 1072 345 345 1073 346 346 1074 352 352 1075 354 354 1076 345 345 1077 355 355 1078 332 332 1079 346 346 1080 356 356 1081 333 333 1082 334 334 1083 355 355 1084 357 357 1085 335 335 1086 356 356 1087 358 358 1088 334 334 1089 359 359 1090 336 336 1091 335 335 1092 360 360 1093 337 337 1094 338 338 1095 4 4 1096 347 347 1097 6 6 1098 336 336 1099 359 359 1100 337 337 1101 361 361 1102 339 339 1103 354 354 1104 362 362 1105 356 356 1106 357 357 1107 363 363 1108 364 364 1109 358 358 1110 362 362 1111 365 365 1112 357 357 1113 366 366 1114 359 359 1115 358 358 1116 367 367 1117 360 360 1118 347 347 1119 4 4 1120 368 368 1121 6 6 1122 359 359 1123 366 366 1124 361 361 1125 367 367 1126 369 369 1127 348 348 1128 368 368 1129 370 370 1130 361 361 1131 371 371 1132 349 349 1133 348 348 1134 372 372 1135 350 350 1136 351 351 1137 371 371 1138 373 373 1139 352 352 1140 372 372 1141 374 374 1142 351 351 1143 375 375 1144 353 353 1145 352 352 1146 376 376 1147 354 354 1148 355 355 1149 375 375 1150 363 363 1151 369 369 1152 377 377 1153 371 371 1154 370 370 1155 378 378 1156 372 372 1157 373 373 1158 377 377 1159 379 379 1160 374 374 1161 378 378 1162 380 380 1163 373 373 1164 381 381 1165 375 375 1166 376 376 1167 380 380 1168 382 382 1169 375 375 1170 383 383 1171 363 363 1172 376 376 1173 384 384 1174 362 362 1175 364 364 1176 383 383 1177 385 385 1178 365 365 1179 384 384 1180 386 386 1181 364 364 1182 387 387 1183 366 366 1184 365 365 1185 388 388 1186 367 367 1187 368 368 1188 4 4 1189 389 389 1190 6 6 1191 366 366 1192 387 387 1193 369 369 1194 388 388 1195 390 390 1196 370 370 1197 389 389 1198 391 391 1199 385 385 1200 392 392 1201 393 393 1202 386 386 1203 394 394 1204 395 395 1205 385 385 1206 396 396 1207 387 387 1208 386 386 1209 397 397 1210 388 388 1211 389 389 1212 4 4 1213 398 398 1214 6 6 1215 387 387 1216 396 396 1217 388 388 1218 399 399 1219 390 390 1220 389 389 1221 400 400 1222 391 391 1223 390 390 1224 401 401 1225 377 377 1226 391 391 1227 402 402 1228 378 378 1229 379 379 1230 401 401 1231 403 403 1232 380 380 1233 402 402 1234 404 404 1235 379 379 1236 405 405 1237 381 381 1238 380 380 1239 406 406 1240 382 382 1241 381 381 1242 392 392 1243 383 383 1244 382 382 1245 394 394 1246 384 384 1247 402 402 1248 407 407 1249 408 408 1250 403 403 1251 409 409 1252 410 410 1253 404 404 1254 408 408 1255 411 411 1256 403 403 1257 412 412 1258 405 405 1259 406 406 1260 411 411 1261 413 413 1262 405 405 1263 414 414 1264 392 392 1265 406 406 1266 415 415 1267 394 394 1268 393 393 1269 414 414 1270 416 416 1271 395 395 1272 415 415 1273 417 417 1274 393 393 1275 418 418 1276 396 396 1277 395 395 1278 419 419 1279 397 397 1280 398 398 1281 4 4 1282 420 420 1283 6 6 1284 396 396 1285 418 418 1286 399 399 1287 419 419 1288 421 421 1289 398 398 1290 407 407 1291 400 400 1292 399 399 1293 409 409 1294 401 401 1295 417 417 1296 422 422 1297 423 423 1298 416 416 1299 424 424 1300 418 418 1301 417 417 1302 425 425 1303 419 419 1304 420 420 1305 4 4 1306 426 426 1307 6 6 1308 418 418 1309 424 424 1310 421 421 1311 425 425 1312 427 427 1313 420 420 1314 428 428 1315 407 407 1316 421 421 1317 429 429 1318 409 409 1319 407 407 1320 430 430 1321 408 408 1322 410 410 1323 429 429 1324 431 431 1325 408 408 1326 432 432 1327 411 411 1328 410 410 1329 433 433 1330 412 412 1331 413 413 1332 432 432 1333 434 434 1334 412 412 1335 435 435 1336 414 414 1337 413 413 1338 422 422 1339 415 415 1340 414 414 1341 436 436 1342 416 416 1343 431 431 1344 437 437 1345 438 438 1346 430 430 1347 439 439 1348 432 432 1349 431 431 1350 440 440 1351 433 433 1352 434 434 1353 439 439 1354 441 441 1355 435 435 1356 440 440 1357 442 442 1358 434 434 1359 443 443 1360 422 422 1361 435 435 1362 444 444 1363 436 436 1364 423 423 1365 443 443 1366 445 445 1367 436 436 1368 446 446 1369 424 424 1370 425 425 1371 445 445 1372 447 447 1373 426 426 1374 4 4 1375 448 448 1376 6 6 1377 424 424 1378 446 446 1379 425 425 1380 449 449 1381 427 427 1382 426 426 1383 450 450 1384 428 428 1385 427 427 1386 437 437 1387 429 429 1388 428 428 1389 451 451 1390 430 430 1391 444 444 1392 452 452 1393 446 446 1394 445 445 1395 453 453 1396 447 447 1397 448 448 1398 4 4 1399 454 454 1400 6 6 1401 446 446 1402 452 452 1403 447 447 1404 455 455 1405 449 449 1406 450 450 1407 454 454 1408 456 456 1409 449 449 1410 457 457 1411 437 437 1412 451 451 1413 456 456 1414 458 458 1415 438 438 1416 457 457 1417 459 459 1418 439 439 1419 458 458 1420 460 460 1421 438 438 1422 461 461 1423 440 440 1424 441 441 1425 460 460 1426 462 462 1427 440 440 1428 463 463 1429 442 442 1430 441 441 1431 464 464 1432 443 443 1433 442 442 1434 465 465 1435 444 444 1436 445 445 1437 464 464 1438 466 466 1439 459 459 1440 467 467 1441 461 461 1442 462 462 1443 468 468 1444 469 469 1445 461 461 1446 470 470 1447 463 463 1448 462 462 1449 471 471 1450 464 464 1451 463 463 1452 472 472 1453 465 465 1454 466 466 1455 471 471 1456 473 473 1457 452 452 1458 472 472 1459 474 474 1460 466 466 1461 475 475 1462 453 453 1463 454 454 1464 4 4 1465 476 476 1466 6 6 1467 452 452 1468 474 474 1469 453 453 1470 477 477 1471 455 455 1472 454 454 1473 478 478 1474 456 456 1475 455 455 1476 479 479 1477 457 457 1478 456 456 1479 480 480 1480 458 458 1481 459 459 1482 479 479 1483 481 481 1484 458 458 1485 468 468 1486 460 460 1487 476 476 1488 4 4 1489 3 3 1490 6 6 1491 474 474 1492 7 7 1493 475 475 1494 10 10 1495 477 477 1496 478 478 1497 3 3 1498 12 12 1499 477 477 1500 13 13 1501 479 479 1502 480 480 1503 12 12 1504 15 15 1505 479 479 1506 18 18 1507 481 481 1508 468 468 1509 15 15 1510 20 20 1511 481 481 1512 21 21 1513 467 467 1514 469 469 1515 20 20 1516 24 24 1517 467 467 1518 26 26 1519 470 470 1520 471 471 1521 24 24 1522 28 28 1523 470 470 1524 30 30 1525 472 472 1526 473 473 1527 28 28 1528 0 0 1529 472 472 1530 7 7 1531 474 474 1532 475 475 1533 0 0 1534 2 2 1535 0 0 1536 31 31 1537 1 1 1538 2 2 1539 1 1 1540 9 9 1541 3 3 1542 5 5 1543 11 11 1544 13 13 1545 10 10 1546 9 9 1547 15 15 1548 12 12 1549 11 11 1550 13 13 1551 14 14 1552 17 17 1553 15 15 1554 16 16 1555 19 19 1556 21 21 1557 18 18 1558 17 17 1559 20 20 1560 19 19 1561 23 23 1562 21 21 1563 22 22 1564 25 25 1565 24 24 1566 23 23 1567 27 27 1568 26 26 1569 25 25 1570 29 29 1571 28 28 1572 27 27 1573 31 31 1574 30 30 1575 29 29 1576 8 8 1577 25 25 1578 45 45 1579 32 32 1580 27 27 1581 46 46 1582 33 33 1583 29 29 1584 32 32 1585 34 34 1586 31 31 1587 33 33 1588 35 35 1589 9 9 1590 1 1 1591 35 35 1592 5 5 1593 36 36 1594 38 38 1595 14 14 1596 9 9 1597 37 37 1598 11 11 1599 38 38 1600 40 40 1601 14 14 1602 39 39 1603 41 41 1604 16 16 1605 40 40 1606 42 42 1607 22 22 1608 17 17 1609 41 41 1610 19 19 1611 42 42 1612 44 44 1613 22 22 1614 43 43 1615 45 45 1616 23 23 1617 44 44 1618 46 46 1619 41 41 1620 39 39 1621 47 47 1622 40 40 1623 61 61 1624 49 49 1625 43 43 1626 41 41 1627 48 48 1628 42 42 1629 49 49 1630 51 51 1631 43 43 1632 50 50 1633 52 52 1634 44 44 1635 51 51 1636 53 53 1637 45 45 1638 52 52 1639 54 54 1640 33 33 1641 46 46 1642 53 53 1643 32 32 1644 54 54 1645 56 56 1646 33 33 1647 55 55 1648 57 57 1649 35 35 1650 57 57 1651 59 59 1652 36 36 1653 58 58 1654 60 60 1655 37 37 1656 59 59 1657 47 47 1658 38 38 1659 60 60 1660 61 61 1661 54 54 1662 76 76 1663 62 62 1664 57 57 1665 55 55 1666 63 63 1667 57 57 1668 64 64 1669 66 66 1670 58 58 1671 65 65 1672 67 67 1673 59 59 1674 66 66 1675 68 68 1676 60 60 1677 67 67 1678 69 69 1679 48 48 1680 47 47 1681 68 68 1682 61 61 1683 69 69 1684 71 71 1685 48 48 1686 70 70 1687 72 72 1688 49 49 1689 71 71 1690 73 73 1691 50 50 1692 72 72 1693 74 74 1694 51 51 1695 73 73 1696 75 75 1697 52 52 1698 74 74 1699 76 76 1700 53 53 1701 75 75 1702 63 63 1703 69 69 1704 90 90 1705 77 77 1706 70 70 1707 91 91 1708 78 78 1709 73 73 1710 71 71 1711 77 77 1712 74 74 1713 72 72 1714 78 78 1715 73 73 1716 79 79 1717 81 81 1718 76 76 1719 74 74 1720 80 80 1721 75 75 1722 81 81 1723 83 83 1724 76 76 1725 82 82 1726 84 84 1727 64 64 1728 63 63 1729 83 83 1730 64 64 1731 85 85 1732 87 87 1733 65 65 1734 86 86 1735 88 88 1736 66 66 1737 87 87 1738 89 89 1739 67 67 1740 88 88 1741 90 90 1742 70 70 1743 68 68 1744 89 89 1745 83 83 1746 106 106 1747 92 92 1748 85 85 1749 92 92 1750 95 95 1751 86 86 1752 93 93 1753 96 96 1754 87 87 1755 95 95 1756 97 97 1757 88 88 1758 96 96 1759 98 98 1760 91 91 1761 89 89 1762 97 97 1763 90 90 1764 98 98 1765 100 100 1766 78 78 1767 91 91 1768 99 99 1769 79 79 1770 77 77 1771 100 100 1772 78 78 1773 101 101 1774 103 103 1775 79 79 1776 102 102 1777 104 104 1778 82 82 1779 80 80 1780 103 103 1781 83 83 1782 81 81 1783 104 104 1784 82 82 1785 105 105 1786 94 94 1787 101 101 1788 99 99 1789 107 107 1790 100 100 1791 121 121 1792 109 109 1793 101 101 1794 108 108 1795 110 110 1796 102 102 1797 109 109 1798 111 111 1799 103 103 1800 110 110 1801 112 112 1802 106 106 1803 104 104 1804 111 111 1805 94 94 1806 105 105 1807 112 112 1808 106 106 1809 113 113 1810 115 115 1811 92 92 1812 115 115 1813 117 117 1814 93 93 1815 116 116 1816 118 118 1817 95 95 1818 117 117 1819 119 119 1820 96 96 1821 118 118 1822 120 120 1823 99 99 1824 97 97 1825 119 119 1826 100 100 1827 98 98 1828 120 120 1829 117 117 1830 115 115 1831 124 124 1832 116 116 1833 122 122 1834 126 126 1835 117 117 1836 125 125 1837 127 127 1838 118 118 1839 126 126 1840 128 128 1841 107 107 1842 119 119 1843 127 127 1844 120 120 1845 128 128 1846 130 130 1847 107 107 1848 129 129 1849 131 131 1850 121 121 1851 130 130 1852 132 132 1853 110 110 1854 108 108 1855 131 131 1856 109 109 1857 132 132 1858 134 134 1859 112 112 1860 110 110 1861 133 133 1862 113 113 1863 111 111 1864 134 134 1865 114 114 1866 112 112 1867 135 135 1868 113 113 1869 136 136 1870 124 124 1871 132 132 1872 130 130 1873 137 137 1874 133 133 1875 131 131 1876 139 139 1877 132 132 1878 138 138 1879 141 141 1880 133 133 1881 140 140 1882 142 142 1883 136 136 1884 134 134 1885 141 141 1886 123 123 1887 135 135 1888 142 142 1889 136 136 1890 143 143 1891 145 145 1892 124 124 1893 145 145 1894 147 147 1895 126 126 1896 122 122 1897 146 146 1898 125 125 1899 147 147 1900 149 149 1901 126 126 1902 148 148 1903 150 150 1904 129 129 1905 127 127 1906 149 149 1907 128 128 1908 150 150 1909 137 137 1910 129 129 1911 151 151 1912 139 139 1913 145 145 1914 165 165 1915 152 152 1916 146 146 1917 166 166 1918 153 153 1919 147 147 1920 152 152 1921 154 154 1922 150 150 1923 148 148 1924 153 153 1925 151 151 1926 149 149 1927 154 154 1928 150 150 1929 155 155 1930 157 157 1931 151 151 1932 156 156 1933 158 158 1934 137 137 1935 157 157 1936 159 159 1937 139 139 1938 158 158 1939 160 160 1940 138 138 1941 159 159 1942 161 161 1943 142 142 1944 140 140 1945 160 160 1946 143 143 1947 141 141 1948 161 161 1949 142 142 1950 162 162 1951 164 164 1952 143 143 1953 163 163 1954 165 165 1955 160 160 1956 158 158 1957 167 167 1958 159 159 1959 181 181 1960 169 169 1961 160 160 1962 168 168 1963 170 170 1964 163 163 1965 161 161 1966 169 169 1967 162 162 1968 170 170 1969 172 172 1970 163 163 1971 171 171 1972 173 173 1973 152 152 1974 165 165 1975 173 173 1976 166 166 1977 174 174 1978 176 176 1979 152 152 1980 175 175 1981 177 177 1982 153 153 1983 176 176 1984 178 178 1985 156 156 1986 154 154 1987 177 177 1988 155 155 1989 178 178 1990 180 180 1991 156 156 1992 179 179 1993 167 167 1994 159 159 1995 157 157 1996 180 180 1997 175 175 1998 195 195 1999 182 182 2000 176 176 2001 196 196 2002 183 183 2003 177 177 2004 182 182 2005 184 184 2006 178 178 2007 183 183 2008 185 185 2009 179 179 2010 184 184 2011 186 186 2012 180 180 2013 185 185 2014 187 187 2015 168 168 2016 167 167 2017 186 186 2018 181 181 2019 187 187 2020 189 189 2021 168 168 2022 188 188 2023 190 190 2024 171 171 2025 169 169 2026 189 189 2027 172 172 2028 170 170 2029 190 190 2030 171 171 2031 191 191 2032 193 193 2033 173 173 2034 193 193 2035 195 195 2036 174 174 2037 194 194 2038 196 196 2039 188 188 2040 211 211 2041 197 197 2042 191 191 2043 189 189 2044 198 198 2045 192 192 2046 190 190 2047 197 197 2048 191 191 2049 199 199 2050 201 201 2051 195 195 2052 193 193 2053 201 201 2054 194 194 2055 202 202 2056 204 204 2057 195 195 2058 203 203 2059 205 205 2060 196 196 2061 204 204 2062 206 206 2063 184 184 2064 182 182 2065 205 205 2066 185 185 2067 183 183 2068 206 206 2069 184 184 2070 207 207 2071 209 209 2072 187 187 2073 185 185 2074 208 208 2075 188 188 2076 186 186 2077 209 209 2078 187 187 2079 210 210 2080 198 198 2081 206 206 2082 204 204 2083 212 212 2084 207 207 2085 205 205 2086 214 214 2087 206 206 2088 213 213 2089 216 216 2090 207 207 2091 215 215 2092 217 217 2093 208 208 2094 216 216 2095 218 218 2096 211 211 2097 209 209 2098 217 217 2099 210 210 2100 218 218 2101 220 220 2102 211 211 2103 219 219 2104 221 221 2105 199 199 2106 198 198 2107 220 220 2108 197 197 2109 221 221 2110 223 223 2111 199 199 2112 222 222 2113 224 224 2114 201 201 2115 224 224 2116 226 226 2117 202 202 2118 225 225 2119 212 212 2120 203 203 2121 226 226 2122 214 214 2123 222 222 2124 220 220 2125 227 227 2126 223 223 2127 221 221 2128 229 229 2129 222 222 2130 228 228 2131 231 231 2132 224 224 2133 231 231 2134 233 233 2135 225 225 2136 232 232 2137 234 234 2138 226 226 2139 233 233 2140 235 235 2141 212 212 2142 234 234 2143 236 236 2144 215 215 2145 214 214 2146 235 235 2147 213 213 2148 236 236 2149 238 238 2150 215 215 2151 237 237 2152 239 239 2153 216 216 2154 238 238 2155 240 240 2156 217 217 2157 239 239 2158 241 241 2159 218 218 2160 240 240 2161 227 227 2162 219 219 2163 241 241 2164 229 229 2165 237 237 2166 235 235 2167 242 242 2168 238 238 2169 236 236 2170 244 244 2171 237 237 2172 243 243 2173 246 246 2174 238 238 2175 245 245 2176 247 247 2177 241 241 2178 239 239 2179 246 246 2180 240 240 2181 247 247 2182 249 249 2183 241 241 2184 248 248 2185 250 250 2186 228 228 2187 227 227 2188 249 249 2189 230 230 2190 229 229 2191 250 250 2192 228 228 2193 251 251 2194 253 253 2195 231 231 2196 253 253 2197 255 255 2198 232 232 2199 254 254 2200 256 256 2201 233 233 2202 255 255 2203 242 242 2204 236 236 2205 234 234 2206 256 256 2207 250 250 2208 270 270 2209 257 257 2210 251 251 2211 271 271 2212 258 258 2213 253 253 2214 258 258 2215 260 260 2216 254 254 2217 259 259 2218 261 261 2219 255 255 2220 260 260 2221 262 262 2222 256 256 2223 261 261 2224 263 263 2225 243 243 2226 242 242 2227 262 262 2228 245 245 2229 244 244 2230 263 263 2231 243 243 2232 264 264 2233 266 266 2234 247 247 2235 245 245 2236 265 265 2237 246 246 2238 266 266 2239 268 268 2240 247 247 2241 267 267 2242 269 269 2243 248 248 2244 268 268 2245 270 270 2246 251 251 2247 249 249 2248 269 269 2249 265 265 2250 263 263 2251 272 272 2252 264 264 2253 286 286 2254 274 274 2255 267 267 2256 265 265 2257 273 273 2258 266 266 2259 274 274 2260 276 276 2261 267 267 2262 275 275 2263 277 277 2264 270 270 2265 268 268 2266 276 276 2267 271 271 2268 269 269 2269 277 277 2270 257 257 2271 270 270 2272 278 278 2273 271 271 2274 279 279 2275 281 281 2276 260 260 2277 258 258 2278 281 281 2279 259 259 2280 282 282 2281 284 284 2282 260 260 2283 283 283 2284 285 285 2285 261 261 2286 284 284 2287 272 272 2288 264 264 2289 262 262 2290 285 285 2291 279 279 2292 301 301 2293 287 287 2294 281 281 2295 287 287 2296 290 290 2297 282 282 2298 288 288 2299 291 291 2300 283 283 2301 290 290 2302 292 292 2303 284 284 2304 291 291 2305 293 293 2306 286 286 2307 285 285 2308 292 292 2309 272 272 2310 293 293 2311 295 295 2312 286 286 2313 294 294 2314 296 296 2315 275 275 2316 273 273 2317 295 295 2318 276 276 2319 274 274 2320 296 296 2321 275 275 2322 297 297 2323 299 299 2324 276 276 2325 298 298 2326 300 300 2327 279 279 2328 277 277 2329 299 299 2330 280 280 2331 278 278 2332 300 300 2333 294 294 2334 316 316 2335 302 302 2336 297 297 2337 295 295 2338 303 303 2339 296 296 2340 302 302 2341 305 305 2342 297 297 2343 304 304 2344 306 306 2345 298 298 2346 305 305 2347 307 307 2348 301 301 2349 299 299 2350 306 306 2351 300 300 2352 307 307 2353 309 309 2354 287 287 2355 301 301 2356 308 308 2357 287 287 2358 310 310 2359 312 312 2360 288 288 2361 311 311 2362 313 313 2363 290 290 2364 312 312 2365 314 314 2366 291 291 2367 313 313 2368 315 315 2369 294 294 2370 292 292 2371 314 314 2372 295 295 2373 293 293 2374 315 315 2375 310 310 2376 330 330 2377 318 318 2378 311 311 2379 331 331 2380 319 319 2381 312 312 2382 318 318 2383 320 320 2384 313 313 2385 319 319 2386 321 321 2387 316 316 2388 314 314 2389 320 320 2390 303 303 2391 315 315 2392 321 321 2393 316 316 2394 322 322 2395 324 324 2396 304 304 2397 303 303 2398 323 323 2399 302 302 2400 324 324 2401 326 326 2402 304 304 2403 325 325 2404 327 327 2405 307 307 2406 305 305 2407 326 326 2408 308 308 2409 306 306 2410 327 327 2411 307 307 2412 328 328 2413 317 317 2414 308 308 2415 329 329 2416 330 330 2417 324 324 2418 345 345 2419 332 332 2420 325 325 2421 346 346 2422 333 333 2423 328 328 2424 326 326 2425 332 332 2426 329 329 2427 327 327 2428 333 333 2429 317 317 2430 328 328 2431 334 334 2432 329 329 2433 335 335 2434 337 337 2435 330 330 2436 337 337 2437 339 339 2438 331 331 2439 338 338 2440 340 340 2441 318 318 2442 339 339 2443 341 341 2444 319 319 2445 340 340 2446 342 342 2447 322 322 2448 320 320 2449 341 341 2450 323 323 2451 321 321 2452 342 342 2453 324 324 2454 322 322 2455 343 343 2456 325 325 2457 323 323 2458 344 344 2459 340 340 2460 338 338 2461 347 347 2462 339 339 2463 361 361 2464 349 349 2465 340 340 2466 348 348 2467 350 350 2468 343 343 2469 341 341 2470 349 349 2471 344 344 2472 342 342 2473 350 350 2474 343 343 2475 351 351 2476 353 353 2477 346 346 2478 344 344 2479 352 352 2480 345 345 2481 353 353 2482 355 355 2483 346 346 2484 354 354 2485 356 356 2486 334 334 2487 332 332 2488 355 355 2489 335 335 2490 333 333 2491 356 356 2492 334 334 2493 357 357 2494 359 359 2495 335 335 2496 358 358 2497 360 360 2498 337 337 2499 360 360 2500 361 361 2501 354 354 2502 376 376 2503 362 362 2504 357 357 2505 355 355 2506 363 363 2507 358 358 2508 356 356 2509 362 362 2510 357 357 2511 364 364 2512 366 366 2513 358 358 2514 365 365 2515 367 367 2516 361 361 2517 360 360 2518 367 367 2519 348 348 2520 347 347 2521 368 368 2522 361 361 2523 369 369 2524 371 371 2525 348 348 2526 370 370 2527 372 372 2528 351 351 2529 349 349 2530 371 371 2531 352 352 2532 350 350 2533 372 372 2534 351 351 2535 373 373 2536 375 375 2537 352 352 2538 374 374 2539 376 376 2540 355 355 2541 353 353 2542 375 375 2543 369 369 2544 390 390 2545 377 377 2546 370 370 2547 391 391 2548 378 378 2549 373 373 2550 371 371 2551 377 377 2552 374 374 2553 372 372 2554 378 378 2555 373 373 2556 379 379 2557 381 381 2558 376 376 2559 374 374 2560 380 380 2561 375 375 2562 381 381 2563 383 383 2564 376 376 2565 382 382 2566 384 384 2567 364 364 2568 363 363 2569 383 383 2570 365 365 2571 362 362 2572 384 384 2573 364 364 2574 385 385 2575 387 387 2576 365 365 2577 386 386 2578 388 388 2579 369 369 2580 367 367 2581 388 388 2582 370 370 2583 368 368 2584 389 389 2585 385 385 2586 383 383 2587 392 392 2588 386 386 2589 384 384 2590 394 394 2591 385 385 2592 393 393 2593 396 396 2594 386 386 2595 395 395 2596 397 397 2597 388 388 2598 397 397 2599 399 399 2600 389 389 2601 398 398 2602 400 400 2603 390 390 2604 399 399 2605 401 401 2606 391 391 2607 400 400 2608 402 402 2609 379 379 2610 377 377 2611 401 401 2612 380 380 2613 378 378 2614 402 402 2615 379 379 2616 403 403 2617 405 405 2618 380 380 2619 404 404 2620 406 406 2621 381 381 2622 405 405 2623 392 392 2624 382 382 2625 406 406 2626 394 394 2627 402 402 2628 400 400 2629 407 407 2630 403 403 2631 401 401 2632 409 409 2633 404 404 2634 402 402 2635 408 408 2636 403 403 2637 410 410 2638 412 412 2639 406 406 2640 404 404 2641 411 411 2642 405 405 2643 412 412 2644 414 414 2645 406 406 2646 413 413 2647 415 415 2648 393 393 2649 392 392 2650 414 414 2651 395 395 2652 394 394 2653 415 415 2654 393 393 2655 416 416 2656 418 418 2657 395 395 2658 417 417 2659 419 419 2660 399 399 2661 397 397 2662 419 419 2663 398 398 2664 420 420 2665 407 407 2666 399 399 2667 421 421 2668 409 409 2669 417 417 2670 415 415 2671 422 422 2672 416 416 2673 436 436 2674 424 424 2675 417 417 2676 423 423 2677 425 425 2678 421 421 2679 419 419 2680 425 425 2681 420 420 2682 426 426 2683 428 428 2684 421 421 2685 427 427 2686 429 429 2687 407 407 2688 428 428 2689 430 430 2690 410 410 2691 409 409 2692 429 429 2693 408 408 2694 430 430 2695 432 432 2696 410 410 2697 431 431 2698 433 433 2699 413 413 2700 411 411 2701 432 432 2702 412 412 2703 433 433 2704 435 435 2705 413 413 2706 434 434 2707 422 422 2708 414 414 2709 435 435 2710 436 436 2711 431 431 2712 429 429 2713 437 437 2714 430 430 2715 451 451 2716 439 439 2717 431 431 2718 438 438 2719 440 440 2720 434 434 2721 432 432 2722 439 439 2723 435 435 2724 433 433 2725 440 440 2726 434 434 2727 441 441 2728 443 443 2729 435 435 2730 442 442 2731 444 444 2732 423 423 2733 422 422 2734 443 443 2735 436 436 2736 444 444 2737 446 446 2738 425 425 2739 423 423 2740 445 445 2741 425 425 2742 447 447 2743 449 449 2744 426 426 2745 448 448 2746 450 450 2747 427 427 2748 449 449 2749 437 437 2750 428 428 2751 450 450 2752 451 451 2753 444 444 2754 465 465 2755 452 452 2756 445 445 2757 466 466 2758 453 453 2759 447 447 2760 453 453 2761 455 455 2762 450 450 2763 448 448 2764 454 454 2765 449 449 2766 455 455 2767 457 457 2768 451 451 2769 450 450 2770 456 456 2771 438 438 2772 437 437 2773 457 457 2774 439 439 2775 451 451 2776 458 458 2777 438 438 2778 459 459 2779 461 461 2780 441 441 2781 439 439 2782 460 460 2783 440 440 2784 461 461 2785 463 463 2786 441 441 2787 462 462 2788 464 464 2789 442 442 2790 463 463 2791 465 465 2792 445 445 2793 443 443 2794 464 464 2795 459 459 2796 481 481 2797 467 467 2798 462 462 2799 460 460 2800 468 468 2801 461 461 2802 467 467 2803 470 470 2804 462 462 2805 469 469 2806 471 471 2807 463 463 2808 470 470 2809 472 472 2810 466 466 2811 464 464 2812 471 471 2813 452 452 2814 465 465 2815 472 472 2816 466 466 2817 473 473 2818 475 475 2819 453 453 2820 475 475 2821 477 477 2822 454 454 2823 476 476 2824 478 478 2825 455 455 2826 477 477 2827 479 479 2828 456 456 2829 478 478 2830 480 480 2831 459 459 2832 457 457 2833 479 479 2834 458 458 2835 480 480 2836 468 468 2837 475 475 2838 2 2 2839 10 10 2840 478 478 2841 476 476 2842 3 3 2843 477 477 2844 10 10 2845 13 13 2846 480 480 2847 478 478 2848 12 12 2849 479 479 2850 13 13 2851 18 18 2852 468 468 2853 480 480 2854 15 15 2855 481 481 2856 18 18 2857 21 21 2858 469 469 2859 468 468 2860 20 20 2861 467 467 2862 21 21 2863 26 26 2864 471 471 2865 469 469 2866 24 24 2867 470 470 2868 26 26 2869 30 30 2870 473 473 2871 471 471 2872 28 28 2873 472 472 2874 30 30 2875 7 7 2876 475 475 2877 473 473 2878 0 0 2879

+
+
+
+
+ + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + + + +
\ No newline at end of file From cde1d68f78960905f10ae33fb93637e55efd0506 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sat, 25 Dec 2021 12:30:31 -0600 Subject: [PATCH 007/145] Fixes handling in the generic creator function to deal with commands formatted with "return " at the start AND without Fixes assignment of default material to convex shape when the toolbar button is pressed to create a 1u cube automatically. --- .../BaseGame/game/tools/convexEditor/convexEditorGui.tscript | 2 ++ .../game/tools/worldEditor/scripts/editors/creator.ed.tscript | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript index 253508d75..09215601a 100644 --- a/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript @@ -51,6 +51,8 @@ function ConvexEditorGui::onSleep( %this ) function ConvexEditorGui::createConvexBox( %this ) { %obj = genericCreateObject( "ConvexShape" ); + %obj.setMaterial(%this.materialName); //set whatever the editor has as it's default material to the new one + %this.handleDeselect(); %this.selectConvex( %obj ); %this.dropSelectionAtScreenCenter(); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript index 201347e2e..7ec1015a7 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript @@ -227,6 +227,10 @@ function ObjectCreator::createObject( %this, %cmd ) %this.setNewObjectGroup( getScene(0) ); pushInstantGroup(); + + if(startsWith(%cmd, "return ")) + %objId = eval(%cmd); + else %objId = eval("return " @ %cmd); popInstantGroup(); From 165459c90be228427a6d12ed9f5fcc40bd5fd8c0 Mon Sep 17 00:00:00 2001 From: Lukas Aldershaab Date: Sun, 2 Jan 2022 12:18:25 +0100 Subject: [PATCH 008/145] Improve tinyXml2 output formatting --- Engine/source/persistence/taml/fsTinyXml.cpp | 422 +++++++++++++------ Engine/source/persistence/taml/fsTinyXml.h | 25 ++ 2 files changed, 308 insertions(+), 139 deletions(-) diff --git a/Engine/source/persistence/taml/fsTinyXml.cpp b/Engine/source/persistence/taml/fsTinyXml.cpp index e0dc53572..09da8d16b 100644 --- a/Engine/source/persistence/taml/fsTinyXml.cpp +++ b/Engine/source/persistence/taml/fsTinyXml.cpp @@ -26,6 +26,182 @@ #include "console/console.h" + +// Re-implement private functionality in TinyXML2 + +static const char LINE_FEED = static_cast(0x0a); // all line endings are normalized to LF +static const char LF = LINE_FEED; +static const char CARRIAGE_RETURN = static_cast(0x0d); // CR gets filtered out +static const char CR = CARRIAGE_RETURN; +static const char SINGLE_QUOTE = '\''; +static const char DOUBLE_QUOTE = '\"'; + +struct Entity { + const char* pattern; + int length; + char value; +}; + +static const int NUM_ENTITIES = 5; +static const Entity entities[NUM_ENTITIES] = { + { "quot", 4, DOUBLE_QUOTE }, + { "amp", 3, '&' }, + { "apos", 4, SINGLE_QUOTE }, + { "lt", 2, '<' }, + { "gt", 2, '>' } +}; + +VfsXMLPrinter::VfsXMLPrinter(FileStream& stream, bool compact, int depth) + : XMLPrinter(NULL, compact, depth), + m_Stream(stream), + _depth(depth) +{ + for (int i = 0; i < ENTITY_RANGE; ++i) { + _entityFlag[i] = false; + _restrictedEntityFlag[i] = false; + } + for (int i = 0; i < NUM_ENTITIES; ++i) { + const char entityValue = entities[i].value; + const unsigned char flagIndex = static_cast(entityValue); + TIXMLASSERT(flagIndex < ENTITY_RANGE); + _entityFlag[flagIndex] = true; + } + _restrictedEntityFlag[static_cast('&')] = true; + _restrictedEntityFlag[static_cast('<')] = true; + _restrictedEntityFlag[static_cast('>')] = true; // not required, but consistency is nice +} + +VfsXMLPrinter::~VfsXMLPrinter() +{ + m_Stream.flush(); + m_Stream.close(); +} + +void VfsXMLPrinter::PrintString(const char* p, bool restricted) +{ + // Look for runs of bytes between entities to print. + const char* q = p; + + if (_processEntities) { + const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag; + while (*q) { + TIXMLASSERT(p <= q); + // Remember, char is sometimes signed. (How many times has that bitten me?) + if (*q > 0 && *q < ENTITY_RANGE) { + // Check for entities. If one is found, flush + // the stream up until the entity, write the + // entity, and keep looking. + if (flag[static_cast(*q)]) { + while (p < q) { + const size_t delta = q - p; + const int toPrint = (INT_MAX < delta) ? INT_MAX : static_cast(delta); + Write(p, toPrint); + p += toPrint; + } + bool entityPatternPrinted = false; + for (int i = 0; i < NUM_ENTITIES; ++i) { + if (entities[i].value == *q) { + Putc('&'); + Write(entities[i].pattern, entities[i].length); + Putc(';'); + entityPatternPrinted = true; + break; + } + } + if (!entityPatternPrinted) { + // TIXMLASSERT( entityPatternPrinted ) causes gcc -Wunused-but-set-variable in release + TIXMLASSERT(false); + } + ++p; + } + } + ++q; + TIXMLASSERT(p <= q); + } + // Flush the remaining string. This will be the entire + // string if an entity wasn't found. + if (p < q) { + const size_t delta = q - p; + const int toPrint = (INT_MAX < delta) ? INT_MAX : static_cast(delta); + Write(p, toPrint); + } + } + else { + Write(p); + } +} + +bool VfsXMLPrinter::VisitEnter(const tinyxml2::XMLDocument& doc) +{ + _processEntities = doc.ProcessEntities(); + return XMLPrinter::VisitEnter(doc); +} + +bool VfsXMLPrinter::VisitExit(const tinyxml2::XMLElement& element) +{ + _depth--; + return XMLPrinter::VisitExit(element); +} + + +// Add VFS friendly implementations of output functions + +void VfsXMLPrinter::Print(const char* format, ...) +{ + va_list va; + va_start(va, format); + + m_Stream.writeFormattedBuffer(format, va); + + va_end(va); +} + +void VfsXMLPrinter::Write(const char* data, size_t size) +{ + m_Stream.write(size, data); +} + +void VfsXMLPrinter::Putc(char ch) +{ + m_Stream.write(static_cast(ch)); +} + +// Overwrite Visitation of elements to add newlines before attributes + +bool VfsXMLPrinter::VisitEnter(const tinyxml2::XMLElement& element, const tinyxml2::XMLAttribute* attribute) +{ + const tinyxml2::XMLElement* parentElem = 0; + if (element.Parent()) { + parentElem = element.Parent()->ToElement(); + } + const bool compactMode = parentElem ? CompactMode(*parentElem) : CompactMode(element); + OpenElement(element.Name(), compactMode); + _depth++; + while (attribute) { + PushAttribute(attribute->Name(), attribute->Value(), compactMode); + attribute = attribute->Next(); + } + return true; +} + +void VfsXMLPrinter::PushAttribute(const char* name, const char* value, bool compactMode) +{ + TIXMLASSERT(_elementJustOpened); + if (compactMode) + { + Putc(' '); + } + else + { + Putc('\n'); + PrintSpace(_depth); + } + Write(name); + Write("=\""); + PrintString(value, false); + Putc('\"'); +} + bool VfsXMLDocument::LoadFile(const char* pFilename) { // Expand the file-path. @@ -61,6 +237,113 @@ bool VfsXMLDocument::LoadFile(const char* pFilename) return true; } +bool VfsXMLDocument::LoadFile(FileStream& stream) +{ + // Delete the existing data: + Clear(); + // Clear shadowed error + ClearError(); + //TODO: Can't clear location, investigate if this gives issues. + //doc.location.Clear(); + + // Get the file size, so we can pre-allocate the string. HUGE speed impact. + long length = stream.getStreamSize(); + + // Strange case, but good to handle up front. + if (length <= 0) + { + SetError(tinyxml2::XML_ERROR_EMPTY_DOCUMENT, 0, 0); + return false; + } + + // Subtle bug here. TinyXml did use fgets. But from the XML spec: + // 2.11 End-of-Line Handling + // + // + // ...the XML processor MUST behave as if it normalized all line breaks in external + // parsed entities (including the document entity) on input, before parsing, by translating + // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to + // a single #xA character. + // + // + // It is not clear fgets does that, and certainly isn't clear it works cross platform. + // Generally, you expect fgets to translate from the convention of the OS to the c/unix + // convention, and not work generally. + + /* + while( fgets( buf, sizeof(buf), file ) ) + { + data += buf; + } + */ + + char* buf = new char[length + 1]; + buf[0] = 0; + + if (!stream.read(length, buf)) + { + delete[] buf; + SetError(tinyxml2::XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, 0); + return false; + } + + // Process the buffer in place to normalize new lines. (See comment above.) + // Copies from the 'p' to 'q' pointer, where p can advance faster if + // a newline-carriage return is hit. + // + // Wikipedia: + // Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or + // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)... + // * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others + // * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS + // * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9 + + const char* p = buf; // the read head + char* q = buf; // the write head + const char CR = 0x0d; + const char LF = 0x0a; + + buf[length] = 0; + while (*p) + { + assert(p < (buf + length)); + assert(q <= (buf + length)); + assert(q <= p); + + if (*p == CR) + { + *q++ = LF; + p++; + if (*p == LF) + { + // check for CR+LF (and skip LF) + p++; + } + } + else + { + *q++ = *p++; + } + } + assert(q <= (buf + length)); + *q = 0; + + Parse(buf, length); + + delete[] buf; + return !Error(); +} + +bool VfsXMLDocument::SaveFile(FileStream& stream) +{ + // Clear any error from the last save, otherwise it will get reported + // for *this* call. + ClearError(); + VfsXMLPrinter printer(stream, false, 0); + Print(&printer); + return !Error(); +} + bool VfsXMLDocument::SaveFile(const char* pFilename) { // Expand the file-name into the file-path buffer. @@ -118,142 +401,3 @@ void VfsXMLDocument::SetError(tinyxml2::XMLError error, int lineNum, const char* _errorStr.SetStr(buffer); delete[] buffer; } - -VfsXMLPrinter::VfsXMLPrinter(FileStream& stream, bool compact, int depth) - : XMLPrinter(NULL, compact, depth), - m_Stream(stream) -{ -} - -VfsXMLPrinter::~VfsXMLPrinter() -{ - m_Stream.flush(); - m_Stream.close(); -} - -void VfsXMLPrinter::Print(const char* format, ...) -{ - va_list va; - va_start(va, format); - - m_Stream.writeFormattedBuffer(format, va); - - va_end(va); -} - -void VfsXMLPrinter::Write(const char* data, size_t size) -{ - m_Stream.write(size, data); -} - -void VfsXMLPrinter::Putc(char ch) -{ - m_Stream.write(static_cast(ch)); -} - -bool VfsXMLDocument::LoadFile(FileStream& stream) -{ - // Delete the existing data: - Clear(); - // Clear shadowed error - ClearError(); - //TODO: Can't clear location, investigate if this gives issues. - //doc.location.Clear(); - - // Get the file size, so we can pre-allocate the string. HUGE speed impact. - long length = stream.getStreamSize(); - - // Strange case, but good to handle up front. - if (length <= 0) - { - SetError(tinyxml2::XML_ERROR_EMPTY_DOCUMENT, 0, 0); - return false; - } - - // Subtle bug here. TinyXml did use fgets. But from the XML spec: - // 2.11 End-of-Line Handling - // - // - // ...the XML processor MUST behave as if it normalized all line breaks in external - // parsed entities (including the document entity) on input, before parsing, by translating - // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to - // a single #xA character. - // - // - // It is not clear fgets does that, and certainly isn't clear it works cross platform. - // Generally, you expect fgets to translate from the convention of the OS to the c/unix - // convention, and not work generally. - - /* - while( fgets( buf, sizeof(buf), file ) ) - { - data += buf; - } - */ - - char* buf = new char[length + 1]; - buf[0] = 0; - - if (!stream.read(length, buf)) - { - delete [] buf; - SetError(tinyxml2::XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, 0); - return false; - } - - // Process the buffer in place to normalize new lines. (See comment above.) - // Copies from the 'p' to 'q' pointer, where p can advance faster if - // a newline-carriage return is hit. - // - // Wikipedia: - // Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or - // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)... - // * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others - // * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS - // * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9 - - const char* p = buf; // the read head - char* q = buf; // the write head - const char CR = 0x0d; - const char LF = 0x0a; - - buf[length] = 0; - while (*p) - { - assert(p < (buf+length)); - assert(q <= (buf+length)); - assert(q <= p); - - if (*p == CR) - { - *q++ = LF; - p++; - if (*p == LF) - { - // check for CR+LF (and skip LF) - p++; - } - } - else - { - *q++ = *p++; - } - } - assert(q <= (buf+length)); - *q = 0; - - Parse(buf, length); - - delete [] buf; - return !Error(); -} - -bool VfsXMLDocument::SaveFile(FileStream& stream) -{ - // Clear any error from the last save, otherwise it will get reported - // for *this* call. - ClearError(); - VfsXMLPrinter printer(stream, false, 0); - Print(&printer); - return !Error(); -} diff --git a/Engine/source/persistence/taml/fsTinyXml.h b/Engine/source/persistence/taml/fsTinyXml.h index 2a83cb614..8c10463dc 100644 --- a/Engine/source/persistence/taml/fsTinyXml.h +++ b/Engine/source/persistence/taml/fsTinyXml.h @@ -40,10 +40,35 @@ public: VfsXMLPrinter(FileStream& stream, bool compact = false, int depth = 0); ~VfsXMLPrinter() override; + // Re-implement private functionality in TinyXML2 library, this is just a copy-paste job + void PrintString(const char*, bool restrictedEntitySet); // prints out, after detecting entities. + + virtual bool VisitEnter(const tinyxml2::XMLDocument& /*doc*/); + virtual bool VisitExit(const tinyxml2::XMLElement& element); + + // Add VFS friendly implementations of output functions void Print(const char* format, ...) override; void Write(const char* data, size_t size) override; + inline void Write(const char* data) { Write(data, strlen(data)); } void Putc(char ch) override; + + // Overwrite Visitation of elements to add newlines before attributes + virtual bool VisitEnter(const tinyxml2::XMLElement& element, const tinyxml2::XMLAttribute* attribute); + void PushAttribute(const char* name, const char* value, bool compactMode); + + // Accept a virtual FileStream instead of a FILE pointer FileStream& m_Stream; + + // Track private fields that are necessary for private functionality in TinyXML2 + int _depth; + bool _processEntities; + + enum { + ENTITY_RANGE = 64, + BUF_SIZE = 200 + }; + bool _entityFlag[ENTITY_RANGE]; + bool _restrictedEntityFlag[ENTITY_RANGE]; }; class VfsXMLDocument : public tinyxml2::XMLDocument From 5abd66dfa3101899f583a6ff3471ec97359269a2 Mon Sep 17 00:00:00 2001 From: Lukas Aldershaab Date: Mon, 3 Jan 2022 21:10:26 +0100 Subject: [PATCH 009/145] Split PrettyPrinting functionality from VFS printing --- Engine/source/persistence/taml/fsTinyXml.cpp | 254 ++++++++----------- Engine/source/persistence/taml/fsTinyXml.h | 107 +++++++- 2 files changed, 212 insertions(+), 149 deletions(-) diff --git a/Engine/source/persistence/taml/fsTinyXml.cpp b/Engine/source/persistence/taml/fsTinyXml.cpp index 09da8d16b..32eb5de38 100644 --- a/Engine/source/persistence/taml/fsTinyXml.cpp +++ b/Engine/source/persistence/taml/fsTinyXml.cpp @@ -26,49 +26,10 @@ #include "console/console.h" - -// Re-implement private functionality in TinyXML2 - -static const char LINE_FEED = static_cast(0x0a); // all line endings are normalized to LF -static const char LF = LINE_FEED; -static const char CARRIAGE_RETURN = static_cast(0x0d); // CR gets filtered out -static const char CR = CARRIAGE_RETURN; -static const char SINGLE_QUOTE = '\''; -static const char DOUBLE_QUOTE = '\"'; - -struct Entity { - const char* pattern; - int length; - char value; -}; - -static const int NUM_ENTITIES = 5; -static const Entity entities[NUM_ENTITIES] = { - { "quot", 4, DOUBLE_QUOTE }, - { "amp", 3, '&' }, - { "apos", 4, SINGLE_QUOTE }, - { "lt", 2, '<' }, - { "gt", 2, '>' } -}; - VfsXMLPrinter::VfsXMLPrinter(FileStream& stream, bool compact, int depth) : XMLPrinter(NULL, compact, depth), - m_Stream(stream), - _depth(depth) + m_Stream(stream) { - for (int i = 0; i < ENTITY_RANGE; ++i) { - _entityFlag[i] = false; - _restrictedEntityFlag[i] = false; - } - for (int i = 0; i < NUM_ENTITIES; ++i) { - const char entityValue = entities[i].value; - const unsigned char flagIndex = static_cast(entityValue); - TIXMLASSERT(flagIndex < ENTITY_RANGE); - _entityFlag[flagIndex] = true; - } - _restrictedEntityFlag[static_cast('&')] = true; - _restrictedEntityFlag[static_cast('<')] = true; - _restrictedEntityFlag[static_cast('>')] = true; // not required, but consistency is nice } VfsXMLPrinter::~VfsXMLPrinter() @@ -77,72 +38,6 @@ VfsXMLPrinter::~VfsXMLPrinter() m_Stream.close(); } -void VfsXMLPrinter::PrintString(const char* p, bool restricted) -{ - // Look for runs of bytes between entities to print. - const char* q = p; - - if (_processEntities) { - const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag; - while (*q) { - TIXMLASSERT(p <= q); - // Remember, char is sometimes signed. (How many times has that bitten me?) - if (*q > 0 && *q < ENTITY_RANGE) { - // Check for entities. If one is found, flush - // the stream up until the entity, write the - // entity, and keep looking. - if (flag[static_cast(*q)]) { - while (p < q) { - const size_t delta = q - p; - const int toPrint = (INT_MAX < delta) ? INT_MAX : static_cast(delta); - Write(p, toPrint); - p += toPrint; - } - bool entityPatternPrinted = false; - for (int i = 0; i < NUM_ENTITIES; ++i) { - if (entities[i].value == *q) { - Putc('&'); - Write(entities[i].pattern, entities[i].length); - Putc(';'); - entityPatternPrinted = true; - break; - } - } - if (!entityPatternPrinted) { - // TIXMLASSERT( entityPatternPrinted ) causes gcc -Wunused-but-set-variable in release - TIXMLASSERT(false); - } - ++p; - } - } - ++q; - TIXMLASSERT(p <= q); - } - // Flush the remaining string. This will be the entire - // string if an entity wasn't found. - if (p < q) { - const size_t delta = q - p; - const int toPrint = (INT_MAX < delta) ? INT_MAX : static_cast(delta); - Write(p, toPrint); - } - } - else { - Write(p); - } -} - -bool VfsXMLPrinter::VisitEnter(const tinyxml2::XMLDocument& doc) -{ - _processEntities = doc.ProcessEntities(); - return XMLPrinter::VisitEnter(doc); -} - -bool VfsXMLPrinter::VisitExit(const tinyxml2::XMLElement& element) -{ - _depth--; - return XMLPrinter::VisitExit(element); -} - // Add VFS friendly implementations of output functions @@ -166,42 +61,6 @@ void VfsXMLPrinter::Putc(char ch) m_Stream.write(static_cast(ch)); } -// Overwrite Visitation of elements to add newlines before attributes - -bool VfsXMLPrinter::VisitEnter(const tinyxml2::XMLElement& element, const tinyxml2::XMLAttribute* attribute) -{ - const tinyxml2::XMLElement* parentElem = 0; - if (element.Parent()) { - parentElem = element.Parent()->ToElement(); - } - const bool compactMode = parentElem ? CompactMode(*parentElem) : CompactMode(element); - OpenElement(element.Name(), compactMode); - _depth++; - while (attribute) { - PushAttribute(attribute->Name(), attribute->Value(), compactMode); - attribute = attribute->Next(); - } - return true; -} - -void VfsXMLPrinter::PushAttribute(const char* name, const char* value, bool compactMode) -{ - TIXMLASSERT(_elementJustOpened); - if (compactMode) - { - Putc(' '); - } - else - { - Putc('\n'); - PrintSpace(_depth); - } - Write(name); - Write("=\""); - PrintString(value, false); - Putc('\"'); -} - bool VfsXMLDocument::LoadFile(const char* pFilename) { // Expand the file-path. @@ -340,7 +199,8 @@ bool VfsXMLDocument::SaveFile(FileStream& stream) // for *this* call. ClearError(); VfsXMLPrinter printer(stream, false, 0); - Print(&printer); + PrettyXMLPrinter prettyPrinter(printer); + Print(&prettyPrinter); return !Error(); } @@ -401,3 +261,111 @@ void VfsXMLDocument::SetError(tinyxml2::XMLError error, int lineNum, const char* _errorStr.SetStr(buffer); delete[] buffer; } + + +// Overwrite Visitation of elements to add newlines before attributes +PrettyXMLPrinter::PrettyXMLPrinter(VfsXMLPrinter& innerPrinter, int depth) + : mInnerPrinter(innerPrinter), + _depth(depth) +{ + for (int i = 0; i < ENTITY_RANGE; ++i) { + _entityFlag[i] = false; + _restrictedEntityFlag[i] = false; + } + for (int i = 0; i < NUM_ENTITIES; ++i) { + const char entityValue = entities[i].value; + const unsigned char flagIndex = static_cast(entityValue); + TIXMLASSERT(flagIndex < ENTITY_RANGE); + _entityFlag[flagIndex] = true; + } + _restrictedEntityFlag[static_cast('&')] = true; + _restrictedEntityFlag[static_cast('<')] = true; + _restrictedEntityFlag[static_cast('>')] = true; // not required, but consistency is nice +} + +void PrettyXMLPrinter::PrintString(const char* p, bool restricted) +{ + // Look for runs of bytes between entities to print. + const char* q = p; + + if (_processEntities) { + const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag; + while (*q) { + TIXMLASSERT(p <= q); + // Remember, char is sometimes signed. (How many times has that bitten me?) + if (*q > 0 && *q < ENTITY_RANGE) { + // Check for entities. If one is found, flush + // the stream up until the entity, write the + // entity, and keep looking. + if (flag[static_cast(*q)]) { + while (p < q) { + const size_t delta = q - p; + const int toPrint = (INT_MAX < delta) ? INT_MAX : static_cast(delta); + mInnerPrinter.Write(p, toPrint); + p += toPrint; + } + bool entityPatternPrinted = false; + for (int i = 0; i < NUM_ENTITIES; ++i) { + if (entities[i].value == *q) { + mInnerPrinter.Putc('&'); + mInnerPrinter.Write(entities[i].pattern, entities[i].length); + mInnerPrinter.Putc(';'); + entityPatternPrinted = true; + break; + } + } + if (!entityPatternPrinted) { + // TIXMLASSERT( entityPatternPrinted ) causes gcc -Wunused-but-set-variable in release + TIXMLASSERT(false); + } + ++p; + } + } + ++q; + TIXMLASSERT(p <= q); + } + // Flush the remaining string. This will be the entire + // string if an entity wasn't found. + if (p < q) { + const size_t delta = q - p; + const int toPrint = (INT_MAX < delta) ? INT_MAX : static_cast(delta); + mInnerPrinter.Write(p, toPrint); + } + } + else { + mInnerPrinter.Write(p); + } +} + +bool PrettyXMLPrinter::VisitEnter(const tinyxml2::XMLElement& element, const tinyxml2::XMLAttribute* attribute) +{ + const tinyxml2::XMLElement* parentElem = 0; + if (element.Parent()) { + parentElem = element.Parent()->ToElement(); + } + const bool compactMode = parentElem ? mInnerPrinter.CompactMode(*parentElem) : mInnerPrinter.CompactMode(element); + mInnerPrinter.OpenElement(element.Name(), compactMode); + _depth++; + while (attribute) { + PushAttribute(attribute->Name(), attribute->Value(), compactMode); + attribute = attribute->Next(); + } + return true; +} + +void PrettyXMLPrinter::PushAttribute(const char* name, const char* value, bool compactMode) +{ + if (compactMode) + { + mInnerPrinter.Putc(' '); + } + else + { + mInnerPrinter.Putc('\n'); + mInnerPrinter.PrintSpace(_depth); + } + mInnerPrinter.Write(name); + mInnerPrinter.Write("=\""); + PrintString(value, false); + mInnerPrinter.Putc('\"'); +} diff --git a/Engine/source/persistence/taml/fsTinyXml.h b/Engine/source/persistence/taml/fsTinyXml.h index 8c10463dc..972e05794 100644 --- a/Engine/source/persistence/taml/fsTinyXml.h +++ b/Engine/source/persistence/taml/fsTinyXml.h @@ -41,19 +41,16 @@ public: ~VfsXMLPrinter() override; // Re-implement private functionality in TinyXML2 library, this is just a copy-paste job - void PrintString(const char*, bool restrictedEntitySet); // prints out, after detecting entities. - - virtual bool VisitEnter(const tinyxml2::XMLDocument& /*doc*/); - virtual bool VisitExit(const tinyxml2::XMLElement& element); + bool CompactMode(const tinyxml2::XMLElement& element) override { return tinyxml2::XMLPrinter::CompactMode(element); } // Add VFS friendly implementations of output functions void Print(const char* format, ...) override; void Write(const char* data, size_t size) override; inline void Write(const char* data) { Write(data, strlen(data)); } void Putc(char ch) override; + void PrintSpace(int depth) override { tinyxml2::XMLPrinter::PrintSpace(depth); } // Overwrite Visitation of elements to add newlines before attributes - virtual bool VisitEnter(const tinyxml2::XMLElement& element, const tinyxml2::XMLAttribute* attribute); void PushAttribute(const char* name, const char* value, bool compactMode); // Accept a virtual FileStream instead of a FILE pointer @@ -63,10 +60,12 @@ public: int _depth; bool _processEntities; - enum { + enum + { ENTITY_RANGE = 64, BUF_SIZE = 200 }; + bool _entityFlag[ENTITY_RANGE]; bool _restrictedEntityFlag[ENTITY_RANGE]; }; @@ -152,4 +151,100 @@ public: } }; +class PrettyXMLPrinter : public tinyxml2::XMLPrinter +{ + // Re-implement private functionality in TinyXML2 + static const char LINE_FEED = static_cast(0x0a); // all line endings are normalized to LF + static const char LF = LINE_FEED; + static const char CARRIAGE_RETURN = static_cast(0x0d); // CR gets filtered out + static const char CR = CARRIAGE_RETURN; + static const char SINGLE_QUOTE = '\''; + static const char DOUBLE_QUOTE = '\"'; + + struct Entity + { + const char* pattern; + int length; + char value; + }; + + static const int NUM_ENTITIES = 5; + static constexpr Entity entities[NUM_ENTITIES] = { + {"quot", 4, DOUBLE_QUOTE}, + {"amp", 3, '&'}, + {"apos", 4, SINGLE_QUOTE}, + {"lt", 2, '<'}, + {"gt", 2, '>'} + }; +public: + PrettyXMLPrinter(VfsXMLPrinter& innerPrinter, int depth = 0); + + /// Visit a document. + virtual bool VisitEnter(const tinyxml2::XMLDocument& doc) + { + _processEntities = doc.ProcessEntities(); + return mInnerPrinter.VisitEnter(doc); + } + + /// Visit a document. + virtual bool VisitExit(const tinyxml2::XMLDocument& doc) + { + return mInnerPrinter.VisitExit(doc); + } + + /// Visit an element. + virtual bool VisitEnter(const tinyxml2::XMLElement& element, const tinyxml2::XMLAttribute* firstAttribute); + /// Visit an element. + virtual bool VisitExit(const tinyxml2::XMLElement& element) + { + _depth--; + return mInnerPrinter.VisitExit(element); + } + + /// Visit a declaration. + virtual bool Visit(const tinyxml2::XMLDeclaration& declaration) + { + return mInnerPrinter.Visit(declaration); + } + + /// Visit a text node. + virtual bool Visit(const tinyxml2::XMLText& text) + { + return mInnerPrinter.Visit(text); + } + + /// Visit a comment node. + virtual bool Visit(const tinyxml2::XMLComment& comment) + { + return mInnerPrinter.Visit(comment); + } + + /// Visit an unknown node. + virtual bool Visit(const tinyxml2::XMLUnknown& unknown) + { + return mInnerPrinter.Visit(unknown); + } + + void PushAttribute(const char* name, const char* value, bool compactMode); + + // Re-implement private functionality in TinyXML2 library, this is just a copy-paste job + void PrintString(const char*, bool restrictedEntitySet); // prints out, after detecting entities. + VfsXMLPrinter& mInnerPrinter; + + // Track private fields that are necessary for private functionality in TinyXML2 + int _depth; + bool _processEntities; + bool _compactMode; + + enum + { + ENTITY_RANGE = 64, + BUF_SIZE = 200 + }; + + bool _entityFlag[ENTITY_RANGE]; + bool _restrictedEntityFlag[ENTITY_RANGE]; +}; + + #endif //_FSTINYXML_H_ From 3ef57168b200a6bbca4e9971afd21378594a8a48 Mon Sep 17 00:00:00 2001 From: Lukas Aldershaab Date: Mon, 3 Jan 2022 21:16:34 +0100 Subject: [PATCH 010/145] Cleanup fsTinyXml implementation --- Engine/source/persistence/taml/fsTinyXml.cpp | 22 +++++----- Engine/source/persistence/taml/fsTinyXml.h | 42 +++++++------------- 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/Engine/source/persistence/taml/fsTinyXml.cpp b/Engine/source/persistence/taml/fsTinyXml.cpp index 32eb5de38..961d96b0e 100644 --- a/Engine/source/persistence/taml/fsTinyXml.cpp +++ b/Engine/source/persistence/taml/fsTinyXml.cpp @@ -266,21 +266,21 @@ void VfsXMLDocument::SetError(tinyxml2::XMLError error, int lineNum, const char* // Overwrite Visitation of elements to add newlines before attributes PrettyXMLPrinter::PrettyXMLPrinter(VfsXMLPrinter& innerPrinter, int depth) : mInnerPrinter(innerPrinter), - _depth(depth) + mDepth(depth) { for (int i = 0; i < ENTITY_RANGE; ++i) { - _entityFlag[i] = false; - _restrictedEntityFlag[i] = false; + mEntityFlag[i] = false; + mRestrictedEntityFlag[i] = false; } for (int i = 0; i < NUM_ENTITIES; ++i) { const char entityValue = entities[i].value; const unsigned char flagIndex = static_cast(entityValue); TIXMLASSERT(flagIndex < ENTITY_RANGE); - _entityFlag[flagIndex] = true; + mEntityFlag[flagIndex] = true; } - _restrictedEntityFlag[static_cast('&')] = true; - _restrictedEntityFlag[static_cast('<')] = true; - _restrictedEntityFlag[static_cast('>')] = true; // not required, but consistency is nice + mRestrictedEntityFlag[static_cast('&')] = true; + mRestrictedEntityFlag[static_cast('<')] = true; + mRestrictedEntityFlag[static_cast('>')] = true; // not required, but consistency is nice } void PrettyXMLPrinter::PrintString(const char* p, bool restricted) @@ -288,8 +288,8 @@ void PrettyXMLPrinter::PrintString(const char* p, bool restricted) // Look for runs of bytes between entities to print. const char* q = p; - if (_processEntities) { - const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag; + if (mProcessEntities) { + const bool* flag = restricted ? mRestrictedEntityFlag : mEntityFlag; while (*q) { TIXMLASSERT(p <= q); // Remember, char is sometimes signed. (How many times has that bitten me?) @@ -345,7 +345,7 @@ bool PrettyXMLPrinter::VisitEnter(const tinyxml2::XMLElement& element, const tin } const bool compactMode = parentElem ? mInnerPrinter.CompactMode(*parentElem) : mInnerPrinter.CompactMode(element); mInnerPrinter.OpenElement(element.Name(), compactMode); - _depth++; + mDepth++; while (attribute) { PushAttribute(attribute->Name(), attribute->Value(), compactMode); attribute = attribute->Next(); @@ -362,7 +362,7 @@ void PrettyXMLPrinter::PushAttribute(const char* name, const char* value, bool c else { mInnerPrinter.Putc('\n'); - mInnerPrinter.PrintSpace(_depth); + mInnerPrinter.PrintSpace(mDepth); } mInnerPrinter.Write(name); mInnerPrinter.Write("=\""); diff --git a/Engine/source/persistence/taml/fsTinyXml.h b/Engine/source/persistence/taml/fsTinyXml.h index 972e05794..c4a0d55c2 100644 --- a/Engine/source/persistence/taml/fsTinyXml.h +++ b/Engine/source/persistence/taml/fsTinyXml.h @@ -40,34 +40,19 @@ public: VfsXMLPrinter(FileStream& stream, bool compact = false, int depth = 0); ~VfsXMLPrinter() override; - // Re-implement private functionality in TinyXML2 library, this is just a copy-paste job + // Re-implement protected functionality in TinyXML2 library, and make it public + // (This is a bit dirty, but it's necessary for the PrettyXMLPrinter) bool CompactMode(const tinyxml2::XMLElement& element) override { return tinyxml2::XMLPrinter::CompactMode(element); } + void PrintSpace(int depth) override { tinyxml2::XMLPrinter::PrintSpace(depth); } + inline void Write(const char* data) { Write(data, strlen(data)); } // Add VFS friendly implementations of output functions void Print(const char* format, ...) override; void Write(const char* data, size_t size) override; - inline void Write(const char* data) { Write(data, strlen(data)); } void Putc(char ch) override; - void PrintSpace(int depth) override { tinyxml2::XMLPrinter::PrintSpace(depth); } - - // Overwrite Visitation of elements to add newlines before attributes - void PushAttribute(const char* name, const char* value, bool compactMode); // Accept a virtual FileStream instead of a FILE pointer FileStream& m_Stream; - - // Track private fields that are necessary for private functionality in TinyXML2 - int _depth; - bool _processEntities; - - enum - { - ENTITY_RANGE = 64, - BUF_SIZE = 200 - }; - - bool _entityFlag[ENTITY_RANGE]; - bool _restrictedEntityFlag[ENTITY_RANGE]; }; class VfsXMLDocument : public tinyxml2::XMLDocument @@ -182,7 +167,7 @@ public: /// Visit a document. virtual bool VisitEnter(const tinyxml2::XMLDocument& doc) { - _processEntities = doc.ProcessEntities(); + mProcessEntities = doc.ProcessEntities(); return mInnerPrinter.VisitEnter(doc); } @@ -197,7 +182,7 @@ public: /// Visit an element. virtual bool VisitExit(const tinyxml2::XMLElement& element) { - _depth--; + mDepth--; return mInnerPrinter.VisitExit(element); } @@ -224,17 +209,20 @@ public: { return mInnerPrinter.Visit(unknown); } - + void PushAttribute(const char* name, const char* value, bool compactMode); // Re-implement private functionality in TinyXML2 library, this is just a copy-paste job void PrintString(const char*, bool restrictedEntitySet); // prints out, after detecting entities. + + // The inner printer we are wrapping, we only support VfsXMLPrinter based classes because + // stock tinyxml printer is very closed VfsXMLPrinter& mInnerPrinter; // Track private fields that are necessary for private functionality in TinyXML2 - int _depth; - bool _processEntities; - bool _compactMode; + int mDepth; + bool mProcessEntities; + bool mCompactMode; enum { @@ -242,8 +230,8 @@ public: BUF_SIZE = 200 }; - bool _entityFlag[ENTITY_RANGE]; - bool _restrictedEntityFlag[ENTITY_RANGE]; + bool mEntityFlag[ENTITY_RANGE]; + bool mRestrictedEntityFlag[ENTITY_RANGE]; }; From 15ef8b4fbea85ca0fafd228bd58dd768299e9aac Mon Sep 17 00:00:00 2001 From: JeffR Date: Mon, 3 Jan 2022 20:57:10 -0600 Subject: [PATCH 011/145] Cleaned up implementation of #712 Also updates other game classes like the shapebase to utilize the sound asset hooks properly. --- Engine/source/T3D/assets/SoundAsset.cpp | 13 +- Engine/source/T3D/fx/explosion.cpp | 9 +- Engine/source/T3D/gameBase/gameConnection.cpp | 83 +++++++------ Engine/source/T3D/gameBase/gameConnection.h | 4 +- .../T3D/gameBase/gameConnectionEvents.cpp | 104 +++++++++++++++- .../T3D/gameBase/gameConnectionEvents.h | 20 ++++ Engine/source/T3D/shapeBase.cpp | 62 ++++++---- Engine/source/T3D/shapeBase.h | 13 +- Engine/source/T3D/shapeImage.cpp | 62 ++++++---- Engine/source/sfx/sfxPlayList.cpp | 8 +- Engine/source/sfx/sfxProfile.cpp | 10 +- Engine/source/sfx/sfxSystem.cpp | 111 ++++-------------- 12 files changed, 312 insertions(+), 187 deletions(-) diff --git a/Engine/source/T3D/assets/SoundAsset.cpp b/Engine/source/T3D/assets/SoundAsset.cpp index 45f78bc48..06a30b7e4 100644 --- a/Engine/source/T3D/assets/SoundAsset.cpp +++ b/Engine/source/T3D/assets/SoundAsset.cpp @@ -218,6 +218,9 @@ bool SoundAsset::loadSound() { Con::errorf("SoundAsset::initializeAsset: Attempted to load file %s but it was not valid!", mSoundFile); mLoadedState = BadFileReference; + mSFXProfile.setDescription(NULL); + mSFXProfile.setSoundFileName(StringTable->insert(StringTable->EmptyString())); + mSFXProfile.setPreload(false); return false; } else @@ -257,7 +260,7 @@ StringTableEntry SoundAsset::getAssetIdByFileName(StringTableEntry fileName) if (fileName == StringTable->EmptyString()) return StringTable->EmptyString(); - StringTableEntry materialAssetId = ""; + StringTableEntry soundAssetId = StringTable->EmptyString(); AssetQuery query; U32 foundCount = AssetDatabase.findAssetType(&query, "SoundAsset"); @@ -268,7 +271,7 @@ StringTableEntry SoundAsset::getAssetIdByFileName(StringTableEntry fileName) SoundAsset* soundAsset = AssetDatabase.acquireAsset(query.mAssetList[i]); if (soundAsset && soundAsset->getSoundPath() == fileName) { - materialAssetId = soundAsset->getAssetId(); + soundAssetId = soundAsset->getAssetId(); AssetDatabase.releaseAsset(query.mAssetList[i]); break; } @@ -276,7 +279,7 @@ StringTableEntry SoundAsset::getAssetIdByFileName(StringTableEntry fileName) } } - return materialAssetId; + return soundAssetId; } U32 SoundAsset::getAssetById(StringTableEntry assetId, AssetPtr* soundAsset) @@ -330,8 +333,8 @@ DefineEngineMethod(SoundAsset, getSoundPath, const char*, (), , "") } DefineEngineMethod(SoundAsset, playSound, S32, (Point3F position), (Point3F::Zero), - "Gets the number of materials for this shape asset.\n" - "@return Material count.\n") + "Plays the sound for this asset.\n" + "@return (sound plays).\n") { if (object->getSfxProfile()) { diff --git a/Engine/source/T3D/fx/explosion.cpp b/Engine/source/T3D/fx/explosion.cpp index 88a5a9432..d73d1bc01 100644 --- a/Engine/source/T3D/fx/explosion.cpp +++ b/Engine/source/T3D/fx/explosion.cpp @@ -859,9 +859,6 @@ bool ExplosionData::preload(bool server, String &errorStr) if (Parent::preload(server, errorStr) == false) return false; - if (!server && !getSoundProfile()) - return false; - if( !server ) { @@ -870,12 +867,18 @@ bool ExplosionData::preload(bool server, String &errorStr) _setSound(getSound()); if (!getSoundProfile()) + { Con::errorf(ConsoleLogEntry::General, "SplashData::preload: Cant get an sfxProfile for splash."); + return false; + } } if (!particleEmitter && particleEmitterId != 0) if (Sim::findObject(particleEmitterId, particleEmitter) == false) + { Con::errorf(ConsoleLogEntry::General, "Error, unable to load particle emitter for explosion datablock"); + return false; + } } if (mExplosionShapeAsset.notNull()) { diff --git a/Engine/source/T3D/gameBase/gameConnection.cpp b/Engine/source/T3D/gameBase/gameConnection.cpp index f759a03da..0331e3764 100644 --- a/Engine/source/T3D/gameBase/gameConnection.cpp +++ b/Engine/source/T3D/gameBase/gameConnection.cpp @@ -1562,33 +1562,50 @@ void GameConnection::packetDropped(PacketNotify *note) //---------------------------------------------------------------------------- -void GameConnection::play2D(SFXProfile* profile) +void GameConnection::play2D(StringTableEntry assetId) { - postNetEvent(new Sim2DAudioEvent(profile)); + if (AssetDatabase.isDeclaredAsset(assetId)) + { + + AssetPtr tempSoundAsset; + tempSoundAsset = assetId; + + postNetEvent(new SimSoundAssetEvent(tempSoundAsset)); + + } } -void GameConnection::play3D(SFXProfile* profile, const MatrixF *transform) +void GameConnection::play3D(StringTableEntry assetId, const MatrixF *transform) { if ( !transform ) - play2D(profile); + play2D(assetId); - else if ( !mControlObject ) - postNetEvent(new Sim3DAudioEvent(profile,transform)); - - else + if (AssetDatabase.isDeclaredAsset(assetId)) { - // TODO: Maybe improve this to account for the duration - // of the sound effect and if the control object can get - // into hearing range within time? - // Only post the event if it's within audible range - // of the control object. - Point3F ear,pos; - transform->getColumn(3,&pos); - mControlObject->getTransform().getColumn(3,&ear); - if ((ear - pos).len() < profile->getDescription()->mMaxDistance) - postNetEvent(new Sim3DAudioEvent(profile,transform)); - } + AssetPtr tempSoundAsset; + tempSoundAsset = assetId; + + if (!mControlObject) + postNetEvent(new SimSoundAssetEvent(tempSoundAsset, transform)); + else + { + // TODO: Maybe improve this to account for the duration + // of the sound effect and if the control object can get + // into hearing range within time? + + // Only post the event if it's within audible range + // of the control object. + tempSoundAsset->getSfxDescription(); + Point3F ear, pos; + transform->getColumn(3, &pos); + mControlObject->getTransform().getColumn(3, &ear); + if ((ear - pos).len() < tempSoundAsset->getSfxDescription()->mMaxDistance) + postNetEvent(new SimSoundAssetEvent(tempSoundAsset, transform)); + } + + } + } void GameConnection::doneScopingScene() @@ -2010,49 +2027,49 @@ DefineEngineMethod( GameConnection, isControlObjectRotDampedCamera, bool, (),, return object->isControlObjectRotDampedCamera(); } -DefineEngineMethod( GameConnection, play2D, bool, (SFXProfile* profile),, +DefineEngineMethod( GameConnection, play2D, bool, (StringTableEntry assetId),, "@brief Used on the server to play a 2D sound that is not attached to any object.\n\n" - "@param profile The SFXProfile that defines the sound to play.\n\n" + "@param assetID The SoundAsset ID that defines the sound to play.\n" "@tsexample\n" - "function ServerPlay2D(%profile)\n" + "function ServerPlay2D(%assetId)\n" "{\n" - " // Play the given sound profile on every client.\n" + " // Play the given sound asset on every client.\n" " // The sounds will be transmitted as an event, not attached to any object.\n" " for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)\n" - " ClientGroup.getObject(%idx).play2D(%profile);\n" + " ClientGroup.getObject(%idx).play2D(%assetId);\n" "}\n" "@endtsexample\n\n") { - if(!profile) + if(assetId == StringTable->EmptyString()) return false; - object->play2D(profile); + object->play2D(assetId); return true; } -DefineEngineMethod( GameConnection, play3D, bool, (SFXProfile* profile, TransformF location),, +DefineEngineMethod( GameConnection, play3D, bool, (StringTableEntry assetId, TransformF location),, "@brief Used on the server to play a 3D sound that is not attached to any object.\n\n" - "@param profile The SFXProfile that defines the sound to play.\n" + "@param assetID The SoundAsset ID that defines the sound to play.\n" "@param location The position and orientation of the 3D sound given in the form of \"x y z ax ay az aa\".\n\n" "@tsexample\n" - "function ServerPlay3D(%profile,%transform)\n" + "function ServerPlay3D(%assetId,%transform)\n" "{\n" - " // Play the given sound profile at the given position on every client\n" + " // Play the given sound asset at the given position on every client\n" " // The sound will be transmitted as an event, not attached to any object.\n" " for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)\n" - " ClientGroup.getObject(%idx).play3D(%profile,%transform);\n" + " ClientGroup.getObject(%idx).play3D(%assetID,%transform);\n" "}\n" "@endtsexample\n\n") { - if(!profile) + if(assetId == StringTable->EmptyString()) return false; MatrixF mat = location.getMatrix(); - object->play3D(profile,&mat); + object->play3D(assetId,&mat); return true; } diff --git a/Engine/source/T3D/gameBase/gameConnection.h b/Engine/source/T3D/gameBase/gameConnection.h index c735fb62c..64cdb3cbd 100644 --- a/Engine/source/T3D/gameBase/gameConnection.h +++ b/Engine/source/T3D/gameBase/gameConnection.h @@ -352,8 +352,8 @@ public: /// @name Sound /// @{ - void play2D(SFXProfile *profile); - void play3D(SFXProfile *profile, const MatrixF *transform); + void play2D(StringTableEntry assetId); + void play3D(StringTableEntry assetId, const MatrixF *transform); /// @} /// @name Misc. diff --git a/Engine/source/T3D/gameBase/gameConnectionEvents.cpp b/Engine/source/T3D/gameBase/gameConnectionEvents.cpp index 4aff2ce64..d2c3badce 100644 --- a/Engine/source/T3D/gameBase/gameConnectionEvents.cpp +++ b/Engine/source/T3D/gameBase/gameConnectionEvents.cpp @@ -47,6 +47,7 @@ //-------------------------------------------------------------------------- IMPLEMENT_CO_CLIENTEVENT_V1(SimDataBlockEvent); +IMPLEMENT_CO_CLIENTEVENT_V1(SimSoundAssetEvent); IMPLEMENT_CO_CLIENTEVENT_V1(Sim2DAudioEvent); IMPLEMENT_CO_CLIENTEVENT_V1(Sim3DAudioEvent); IMPLEMENT_CO_CLIENTEVENT_V1(SetMissionCRCEvent); @@ -293,6 +294,104 @@ void SimDataBlockEvent::process(NetConnection *cptr) //---------------------------------------------------------------------------- +static F32 SoundPosAccuracy = 0.5; +static S32 SoundRotBits = 8; + +SimSoundAssetEvent::SimSoundAssetEvent(AssetPtr asset, const MatrixF* mat) +{ + // cant get here unless the asset is declared. + mAsset = asset; + + if (mat) + mTransform = *mat; +} + +void SimSoundAssetEvent::pack(NetConnection* con, BitStream* stream) +{ + NetStringHandle assetIdStr = mAsset->getAssetId(); + con->packNetStringHandleU(stream, assetIdStr); + + // only stream if this is a 3d sound asset. + if (mAsset->is3D()) + { + SFXDescription* ad = mAsset->getSfxDescription(); + if (stream->writeFlag(ad->mConeInsideAngle || ad->mConeOutsideAngle)) + { + QuatF q(mTransform); + q.normalize(); + + // LH - we can get a valid quat that's very slightly over 1 in and so + // this fails (barely) check against zero. So use some error- + AssertFatal((1.0 - ((q.x * q.x) + (q.y * q.y) + (q.z * q.z))) >= (0.0 - 0.001), + "QuatF::normalize() is broken in Sim3DAudioEvent"); + + stream->writeSignedFloat(q.x, SoundRotBits); + stream->writeSignedFloat(q.y, SoundRotBits); + stream->writeSignedFloat(q.z, SoundRotBits); + stream->writeFlag(q.w < 0.0); + } + + Point3F pos; + mTransform.getColumn(3, &pos); + stream->writeCompressedPoint(pos, SoundPosAccuracy); + } + +} + +void SimSoundAssetEvent::write(NetConnection* con, BitStream* stream) +{ + // Just do the normal pack... + pack(con, stream); +} + +void SimSoundAssetEvent::unpack(NetConnection* con, BitStream* stream) +{ + + StringTableEntry temp = StringTable->insert(con->unpackNetStringHandleU(stream).getString()); + if (AssetDatabase.isDeclaredAsset(temp)) + { + AssetPtr tempSoundAsset; + tempSoundAsset = temp; + + mAsset = temp; + } + + if (mAsset->is3D()) + { + if (stream->readFlag()) { + QuatF q; + q.x = stream->readSignedFloat(SoundRotBits); + q.y = stream->readSignedFloat(SoundRotBits); + q.z = stream->readSignedFloat(SoundRotBits); + F32 value = ((q.x * q.x) + (q.y * q.y) + (q.z * q.z)); + // #ifdef __linux + // Hmm, this should never happen, but it does... + if (value > 1.f) + value = 1.f; + // #endif + q.w = mSqrt(1.f - value); + if (stream->readFlag()) + q.w = -q.w; + q.setMatrix(&mTransform); + } + else + mTransform.identity(); + + Point3F pos; + stream->readCompressedPoint(&pos, SoundPosAccuracy); + mTransform.setColumn(3, pos); + } +} + +void SimSoundAssetEvent::process(NetConnection* con) +{ + + if (mAsset->is3D()) + SFX->playOnce(mAsset->getSfxProfile(), &mTransform); + else + SFX->playOnce(mAsset->getSfxProfile()); + +} Sim2DAudioEvent::Sim2DAudioEvent(SFXProfile *profile) { @@ -321,11 +420,6 @@ void Sim2DAudioEvent::process(NetConnection *) SFX->playOnce( mProfile ); } -//---------------------------------------------------------------------------- - -static F32 SoundPosAccuracy = 0.5; -static S32 SoundRotBits = 8; - Sim3DAudioEvent::Sim3DAudioEvent(SFXProfile *profile,const MatrixF* mat) { mProfile = profile; diff --git a/Engine/source/T3D/gameBase/gameConnectionEvents.h b/Engine/source/T3D/gameBase/gameConnectionEvents.h index b9652a940..ede198645 100644 --- a/Engine/source/T3D/gameBase/gameConnectionEvents.h +++ b/Engine/source/T3D/gameBase/gameConnectionEvents.h @@ -39,6 +39,9 @@ #include "core/stream/bitStream.h" #endif +#include "T3D/assets/SoundAsset.h" + + class QuitEvent : public SimEvent { @@ -102,6 +105,23 @@ class SimDataBlockEvent : public NetEvent DECLARE_CATEGORY( "Game Networking" ); }; +class SimSoundAssetEvent : public NetEvent +{ +private: + AssetPtr mAsset; + MatrixF mTransform; + +public: + typedef NetEvent Parent; + + SimSoundAssetEvent(AssetPtr asset = NULL, const MatrixF* mat = NULL); + void pack(NetConnection*, BitStream* bstream); + void write(NetConnection*, BitStream* bstream); + void unpack(NetConnection*, BitStream* bstream); + void process(NetConnection*); + DECLARE_CONOBJECT(SimSoundAssetEvent); +}; + class Sim2DAudioEvent: public NetEvent { private: diff --git a/Engine/source/T3D/shapeBase.cpp b/Engine/source/T3D/shapeBase.cpp index 4730ee6b7..dab20b693 100644 --- a/Engine/source/T3D/shapeBase.cpp +++ b/Engine/source/T3D/shapeBase.cpp @@ -1009,7 +1009,7 @@ ShapeBase::ShapeBase() for (i = 0; i < MaxSoundThreads; i++) { mSoundThread[i].play = false; - mSoundThread[i].profile = 0; + mSoundThread[i].asset = 0; mSoundThread[i].sound = 0; } @@ -2233,24 +2233,30 @@ void ShapeBase::applyImpulse(const Point3F&,const VectorF&) //---------------------------------------------------------------------------- -void ShapeBase::playAudio(U32 slot,SFXTrack* profile) +void ShapeBase::playAudio(U32 slot, StringTableEntry assetId) { AssertFatal( slot < MaxSoundThreads, "ShapeBase::playAudio() bad slot index" ); - Sound& st = mSoundThread[slot]; - if( profile && ( !st.play || st.profile != profile ) ) + if (AssetDatabase.isDeclaredAsset(assetId)) + { + AssetPtr tempSoundAsset; + tempSoundAsset = assetId; + + SoundThread& st = mSoundThread[slot]; + if (tempSoundAsset && (!st.play || st.asset != tempSoundAsset)) { setMaskBits(SoundMaskN << slot); st.play = true; - st.profile = profile; + st.asset = tempSoundAsset; updateAudioState(st); } + } } void ShapeBase::stopAudio(U32 slot) { AssertFatal( slot < MaxSoundThreads, "ShapeBase::stopAudio() bad slot index" ); - Sound& st = mSoundThread[slot]; + SoundThread& st = mSoundThread[slot]; if ( st.play ) { st.play = false; @@ -2263,7 +2269,7 @@ void ShapeBase::updateServerAudio() { // Timeout non-looping sounds for (S32 i = 0; i < MaxSoundThreads; i++) { - Sound& st = mSoundThread[i]; + SoundThread& st = mSoundThread[i]; if (st.play && st.timeout && st.timeout < Sim::getCurrentTime()) { clearMaskBits(SoundMaskN << i); st.play = false; @@ -2271,17 +2277,18 @@ void ShapeBase::updateServerAudio() } } -void ShapeBase::updateAudioState(Sound& st) +void ShapeBase::updateAudioState(SoundThread& st) { SFX_DELETE( st.sound ); - if ( st.play && st.profile ) + if ( st.play && st.asset ) { if ( isGhost() ) { - if ( Sim::findObject( SimObjectId((uintptr_t)st.profile), st.profile ) ) + // if asset is valid, play + if (st.asset->isAssetValid() ) { - st.sound = SFX->createSource( st.profile, &getTransform() ); + st.sound = SFX->createSource( st.asset->getSfxProfile() , &getTransform() ); if ( st.sound ) st.sound->play(); } @@ -2292,12 +2299,17 @@ void ShapeBase::updateAudioState(Sound& st) { // Non-looping sounds timeout on the server st.timeout = 0; - if ( !st.profile->getDescription()->mIsLooping ) + if ( !st.asset->getSfxDescription()->mIsLooping ) st.timeout = Sim::getCurrentTime() + sAudioTimeout; } } else + { + // st.sound was not stopped before. If this causes issues remove. st.play = false; + if (st.sound) + st.sound->stop(); + } } void ShapeBase::updateAudioPos() @@ -3122,13 +3134,15 @@ U32 ShapeBase::packUpdate(NetConnection *con, U32 mask, BitStream *stream) if (stream->writeFlag(mask & SoundMask)) { for (S32 i = 0; i < MaxSoundThreads; i++) { - Sound& st = mSoundThread[i]; + SoundThread& st = mSoundThread[i]; if (stream->writeFlag(mask & (SoundMaskN << i))) if (stream->writeFlag(st.play)) - stream->writeRangedU32(st.profile->getId(),DataBlockObjectIdFirst, - DataBlockObjectIdLast); + { + NetStringHandle assetIdStr = st.asset->getAssetId(); + con->packNetStringHandleU(stream, assetIdStr); } } + } if (stream->writeFlag(mask & ImageMask)) { for (S32 i = 0; i < MaxMountedImages; i++) @@ -3242,12 +3256,18 @@ void ShapeBase::unpackUpdate(NetConnection *con, BitStream *stream) { if ( stream->readFlag() ) { - Sound& st = mSoundThread[i]; + SoundThread& st = mSoundThread[i]; st.play = stream->readFlag(); if ( st.play ) { - st.profile = (SFXTrack*)(uintptr_t)stream->readRangedU32( DataBlockObjectIdFirst, - DataBlockObjectIdLast ); + StringTableEntry temp = StringTable->insert(con->unpackNetStringHandleU(stream).getString()); + if (AssetDatabase.isDeclaredAsset(temp)) + { + AssetPtr tempSoundAsset; + tempSoundAsset = temp; + + st.asset = temp; + } } if ( isProperlyAdded() ) @@ -3777,7 +3797,7 @@ DefineEngineMethod( ShapeBase, isHidden, bool, (),, } //---------------------------------------------------------------------------- -DefineEngineMethod( ShapeBase, playAudio, bool, ( S32 slot, SFXTrack* track ),, +DefineEngineMethod( ShapeBase, playAudio, bool, ( S32 slot, StringTableEntry assetId),, "@brief Attach a sound to this shape and start playing it.\n\n" "@param slot Audio slot index for the sound (valid range is 0 - 3)\n" // 3 = ShapeBase::MaxSoundThreads-1 @@ -3786,8 +3806,8 @@ DefineEngineMethod( ShapeBase, playAudio, bool, ( S32 slot, SFXTrack* track ),, "@see stopAudio()\n") { - if (track && slot >= 0 && slot < ShapeBase::MaxSoundThreads) { - object->playAudio(slot,track); + if (assetId && slot >= 0 && slot < ShapeBase::MaxSoundThreads) { + object->playAudio(slot, assetId); return true; } return false; diff --git a/Engine/source/T3D/shapeBase.h b/Engine/source/T3D/shapeBase.h index 920289385..6ef0fd985 100644 --- a/Engine/source/T3D/shapeBase.h +++ b/Engine/source/T3D/shapeBase.h @@ -265,6 +265,7 @@ struct ShapeBaseImageData: public GameBaseData { F32 emitterTime; ///< S32 emitterNode[MaxShapes]; ///< Node ID on the shape to emit from SoundAsset* sound; + SFXTrack* soundTrack; /// asset; ///< Asset on server SFXSource* sound; ///< Sound on client }; - Sound mSoundThread[MaxSoundThreads]; + SoundThread mSoundThread[MaxSoundThreads]; /// @} /// @name Scripted Animation Threads @@ -1114,7 +1115,7 @@ protected: /// Updates the audio state of the supplied sound /// @param st Sound - void updateAudioState(Sound& st); + void updateAudioState(SoundThread& st); /// Recalculates the spacial sound based on the current position of the object /// emitting the sound. @@ -1328,9 +1329,7 @@ public: /// Plays an audio sound from a mounted object /// @param slot Mount slot ID - /// @param track Audio track to play - void playAudio(U32 slot,SFXTrack* track); - void playAudio( U32 slot, SFXProfile* profile ) { playAudio( slot, ( SFXTrack* ) profile ); } + void playAudio(U32 slot, StringTableEntry assetId); /// Stops audio from a mounted object /// @param slot Mount slot ID diff --git a/Engine/source/T3D/shapeImage.cpp b/Engine/source/T3D/shapeImage.cpp index ee5d62476..88d5f837c 100644 --- a/Engine/source/T3D/shapeImage.cpp +++ b/Engine/source/T3D/shapeImage.cpp @@ -133,6 +133,7 @@ ShapeBaseImageData::StateData::StateData() spin = IgnoreSpin; recoil = NoRecoil; sound = NULL; + soundTrack = NULL; emitter = NULL; shapeSequence = NULL; shapeSequenceScale = true; @@ -372,6 +373,19 @@ bool ShapeBaseImageData::onAdd() //_setstateSound(getstateSound(i),i); s.sound = getstateSoundAsset(i); + if (s.sound == NULL && mstateSoundName[i] != StringTable->EmptyString()) + { + //ok, so we've got some sort of special-case here like a fallback or SFXPlaylist. So do the hook-up now + SFXTrack* sndTrack; + if (!Sim::findObject(mstateSoundName[i], sndTrack)) + { + Con::errorf("ShapeBaseImageData::onAdd() - attempted to find sound %s but failed!", mstateSoundName[i]); + } + else + { + s.soundTrack = sndTrack; + } + } s.script = stateScript[i]; s.emitter = stateEmitter[i]; s.emitterTime = stateEmitterTime[i]; @@ -2580,7 +2594,7 @@ bool ShapeBase::hasImageState(U32 imageSlot, const char* state) return false; } -void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force) +void ShapeBase::setImageState(U32 imageSlot, U32 newState, bool force) { if (!mMountedImageList[imageSlot].dataBlock) return; @@ -2611,12 +2625,12 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force) // Eject shell casing on every state change (client side only) ShapeBaseImageData::StateData& nextStateData = image.dataBlock->state[newState]; if (isGhost() && nextStateData.ejectShell) { - ejectShellCasing( imageSlot ); + ejectShellCasing(imageSlot); } // Shake camera on client. if (isGhost() && nextStateData.fire && image.dataBlock->shakeCamera) { - shakeCamera( imageSlot ); + shakeCamera(imageSlot); } // Server must animate the shape if it is a firestate... @@ -2632,12 +2646,12 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force) if (!force && image.state == &image.dataBlock->state[newState]) { image.delayTime = image.state->timeoutValue; if (image.state->script && !isGhost()) - scriptCallback(imageSlot,image.state->script); + scriptCallback(imageSlot, image.state->script); // If this is a flash sequence, we need to select a new position for the // animation if we're returning to that state... F32 randomPos = Platform::getRandom(); - for (U32 i=0; ishapeIsValid[i] || (i != imageShapeIndex && !image.doAnimateAllShapes)) continue; @@ -2665,7 +2679,7 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force) // Mount pending images if (image.nextImage != InvalidImagePtr && stateData.allowImageChange) { - setImage(imageSlot,image.nextImage,image.nextSkinNameHandle,image.nextLoaded); + setImage(imageSlot, image.nextImage, image.nextSkinNameHandle, image.nextLoaded); return; } @@ -2673,16 +2687,16 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force) // (the first key frame should be it's off state). // We need to do this across all image shapes to make sure we have no hold overs when switching // rendering shapes while in the middle of a state change. - for (U32 i=0; igetSequence()->isCyclic() && (stateData.sequenceNeverTransition || !(stateData.sequenceTransitionIn || lastState->sequenceTransitionOut))) { - image.shapeInstance[i]->setPos(image.animThread[i],0); - image.shapeInstance[i]->setTimeScale(image.animThread[i],0); + image.shapeInstance[i]->setPos(image.animThread[i], 0); + image.shapeInstance[i]->setTimeScale(image.animThread[i], 0); } if (image.flashThread[i]) { - image.shapeInstance[i]->setPos(image.flashThread[i],0); - image.shapeInstance[i]->setTimeScale(image.flashThread[i],0); + image.shapeInstance[i]->setPos(image.flashThread[i], 0); + image.shapeInstance[i]->setTimeScale(image.flashThread[i], 0); } } @@ -2695,10 +2709,10 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force) if (image.delayTime <= 0 || !stateData.waitForTimeout) { if ((ns = stateData.transition.loaded[image.loaded]) != -1) { - setImageState(imageSlot,ns); + setImageState(imageSlot, ns); return; } - for (U32 i=0; isound && lastState->sound->getSfxProfile()->getDescription()->mIsLooping) { - for(Vector::iterator i = image.mSoundSources.begin(); i != image.mSoundSources.end(); i++) + for (Vector::iterator i = image.mSoundSources.begin(); i != image.mSoundSources.end(); i++) SFX_DELETE((*i)); image.mSoundSources.clear(); } // Play sound - if( stateData.sound && isGhost() ) + if (isGhost()) + { + if (stateData.sound) { const Point3F& velocity = getVelocity(); - image.addSoundSource(SFX->createSource(stateData.sound->getSfxProfile(), &getRenderTransform(), &velocity )); + image.addSoundSource(SFX->createSource(stateData.sound->getSfxProfile(), &getRenderTransform(), &velocity)); + } + if (stateData.soundTrack) + { + const Point3F& velocity = getVelocity(); + image.addSoundSource(SFX->createSource(stateData.soundTrack, &getRenderTransform(), &velocity)); + } } // Play animation diff --git a/Engine/source/sfx/sfxPlayList.cpp b/Engine/source/sfx/sfxPlayList.cpp index 0e56d4607..ea186c125 100644 --- a/Engine/source/sfx/sfxPlayList.cpp +++ b/Engine/source/sfx/sfxPlayList.cpp @@ -352,15 +352,19 @@ bool SFXPlayList::preload( bool server, String& errorStr ) { for( U32 i = 0; i < NUM_SLOTS; ++ i ) { - _setTrack(getTrack(i),i); + StringTableEntry track = getTrack(i); + if (track != StringTable->EmptyString()) + { + _setTrack(getTrack(i), i); if (!getTrackProfile(i)) { Con::errorf("SFXPlayList::Preload() - unable to find sfxProfile for asset %s", mTrackAssetId[i]); return false; } - if( !sfxResolve( &mSlots.mState[ i ], errorStr ) ) + if (!sfxResolve(&mSlots.mState[i], errorStr)) return false; + } } } diff --git a/Engine/source/sfx/sfxProfile.cpp b/Engine/source/sfx/sfxProfile.cpp index 4cd6a8cdb..ab3bc44ab 100644 --- a/Engine/source/sfx/sfxProfile.cpp +++ b/Engine/source/sfx/sfxProfile.cpp @@ -35,6 +35,7 @@ #include "core/stream/bitStream.h" #include "core/resourceManager.h" #include "console/engineAPI.h" +#include "core/stream/fileStream.h" using namespace Torque; @@ -283,8 +284,13 @@ bool SFXProfile::_preloadBuffer() Resource& SFXProfile::getResource() { - if( !mResource && mFilename != StringTable->EmptyString()) - mResource = SFXResource::load( mFilename ); + char buf[1024]; + FileName fullFilename = String(Platform::makeFullPathName(mFilename, buf, sizeof(buf))); + + if (!mResource && SFXResource::exists(fullFilename)) + mResource = SFXResource::load(mFilename); + else + mResource = NULL; return mResource; } diff --git a/Engine/source/sfx/sfxSystem.cpp b/Engine/source/sfx/sfxSystem.cpp index 3d793995e..d23880bfd 100644 --- a/Engine/source/sfx/sfxSystem.cpp +++ b/Engine/source/sfx/sfxSystem.cpp @@ -1581,133 +1581,70 @@ DefineEngineFunction( sfxPlay, S32, ( const char * trackName, const char * point //----------------------------------------------------------------------------- static ConsoleDocFragment _sPlayOnce1( - "@brief Create a play-once source for the given @a track.\n\n" + "@brief Create a play-once source for the given @a asset.\n\n" "Once playback has finished, the source will be automatically deleted in the next sound system update.\n" "@param track The sound datablock.\n" "@return A newly created temporary source in \"Playing\" state or 0 if the operation failed.\n\n" "@ref SFXSource_playonce\n\n" "@ingroup SFX", NULL, - "SFXSource sfxPlayOnce( SFXTrack track );" + "SFXSource sfxPlayOnce( StringTableEntry assetID );" ); static ConsoleDocFragment _sPlayOnce2( - "@brief Create a play-once source for the given given @a track and position the source's 3D sound at the given coordinates " - "only if the track's description is set up for 3D sound).\n\n" + "@brief Create a play-once source for the given given @a asset and position the source's 3D sound at the given coordinates " + "only if the asset is set up for 3D sound).\n\n" "Once playback has finished, the source will be automatically deleted in the next sound system update.\n" - "@param track The sound datablock.\n" + "@param assetId The sound asset.\n" "@param x The X coordinate of the 3D sound position.\n" "@param y The Y coordinate of the 3D sound position.\n" "@param z The Z coordinate of the 3D sound position.\n" - "@param fadeInTime If >=0, this overrides the SFXDescription::fadeInTime value on the track's description.\n" + "@param fadeInTime If >=0, this overrides the SFXDescription::fadeInTime value on the asset's definition.\n" "@return A newly created temporary source in \"Playing\" state or 0 if the operation failed.\n\n" "@tsexample\n" - "// Immediately start playing the given track. Fade it in to full volume over 5 seconds.\n" - "sfxPlayOnce( MusicTrack, 0, 0, 0, 5.f );\n" + "// Immediately start playing the given asset. Fade it in to full volume over 5 seconds.\n" + "sfxPlayOnce( ExampleModule:MusicTrack, 0, 0, 0, 5.f );\n" "@endtsexample\n\n" "@ref SFXSource_playonce\n\n" "@ingroup SFX", NULL, - "SFXSource sfxPlayOnce( SFXTrack track, float x, float y, float z, float fadeInTime=-1 );" -); -static ConsoleDocFragment _sPlayOnce3( - "@brief Create a new temporary SFXProfile from the given @a description and @a filename, then create a play-once source " - "for it and start playback.\n\n" - "Once playback has finished, the source will be automatically deleted in the next sound system update. If not referenced " - "otherwise by then, the temporary SFXProfile will also be deleted.\n" - "@param description The description to use for playback.\n" - "@param filename Path to the sound file to play.\n" - "@return A newly created temporary source in \"Playing\" state or 0 if the operation failed.\n\n" - "@tsexample\n" - "// Play a sound effect file once.\n" - "sfxPlayOnce( AudioEffects, \"art/sound/weapons/Weapon_pickup\" );\n" - "@endtsexample\n\n" - "@ref SFXSource_playonce\n\n" - "@ingroup SFX", - NULL, - "SFXSource sfxPlayOnce( SFXDescription description, string filename );" -); -static ConsoleDocFragment _sPlayOnce4( - "@brief Create a new temporary SFXProfile from the given @a description and @a filename, then create a play-once source " - "for it and start playback. Position the source's 3D sound at the given coordinates (only if the description " - "is set up for 3D sound).\n\n" - "Once playback has finished, the source will be automatically deleted in the next sound system update. If not referenced " - "otherwise by then, the temporary SFXProfile will also be deleted.\n" - "@param description The description to use for playback.\n" - "@param filename Path to the sound file to play.\n" - "@param x The X coordinate of the 3D sound position.\n" - "@param y The Y coordinate of the 3D sound position.\n" - "@param z The Z coordinate of the 3D sound position.\n" - "@param fadeInTime If >=0, this overrides the SFXDescription::fadeInTime value on the track's description.\n" - "@return A newly created temporary source in \"Playing\" state or 0 if the operation failed.\n\n" - "@tsexample\n" - "// Play a sound effect file once using a 3D sound with a default falloff placed at the origin.\n" - "sfxPlayOnce( AudioDefault3D, \"art/sound/weapons/Weapon_pickup\", 0, 0, 0 );\n" - "@endtsexample\n\n" - "@ref SFXSource_playonce\n\n" - "@ingroup SFX", - NULL, - "SFXSource sfxPlayOnce( SFXDescription description, string filename, float x, float y, float z, float fadeInTime=-1 );" + "SFXSource sfxPlayOnce( StringTableEntry assetID, float x, float y, float z, float fadeInTime=-1 );" ); -DefineEngineFunction( sfxPlayOnce, S32, ( const char * sfxType, const char * arg0, const char * arg1, const char * arg2, const char * arg3, const char* arg4 ), ("", "", "", "", "-1.0f"), +DefineEngineFunction( sfxPlayOnce, S32, (StringTableEntry assetId, const char* arg0, const char * arg1, const char * arg2, const char * arg3 ), (StringTable->EmptyString(), "", "", "", "-1.0f"), "SFXSource sfxPlayOnce( ( SFXTrack track | SFXDescription description, string filename ) [, float x, float y, float z, float fadeInTime=-1 ] ) " "Create a new play-once source for the given profile or description+filename and start playback of the source.\n" "@hide" ) { SFXDescription* description = NULL; - SFXTrack* track = dynamic_cast< SFXTrack* >( Sim::findObject( sfxType ) ); - if( !track ) - { - description = dynamic_cast< SFXDescription* >( Sim::findObject( sfxType ) ); - if( !description ) + if (assetId == StringTable->EmptyString()) { - Con::errorf( "sfxPlayOnce - Unable to locate sound track/description '%s'", sfxType ); + Con::errorf( "sfxPlayOnce - Must Define a sound asset"); return 0; } - } SFXSource* source = NULL; - if( track ) + + if (AssetDatabase.isDeclaredAsset(assetId)) { - // In this overloaded use, arg0..arg2 are x, y, z, and arg3 is the fadeInTime. - if (String::isEmpty(arg0)) + + AssetPtr tempSoundAsset; + tempSoundAsset = assetId; + + if (String::isEmpty(arg0) || !tempSoundAsset->is3D()) { - source = SFX->playOnce( track ); + source = SFX->playOnce(tempSoundAsset->getSfxProfile()); } else { MatrixF transform; - transform.set( EulerF( 0, 0, 0 ), Point3F( dAtof( arg0 ), dAtof( arg1 ),dAtof( arg2 ) ) ); - source = SFX->playOnce( track, &transform, NULL, dAtof( arg3 ) ); - } + transform.set(EulerF(0, 0, 0), Point3F(dAtof(arg0), dAtof(arg1), dAtof(arg2))); + source = SFX->playOnce(tempSoundAsset->getSfxProfile(), &transform, NULL, dAtof(arg3)); } - else if( description ) - { - // In this overload, arg0 is the filename, arg1..arg3 are x, y, z, and arg4 is fadeInTime. - SFXProfile* tempProfile = new SFXProfile( description, StringTable->insert( arg0 ), true ); - if( !tempProfile->registerObject() ) - { - Con::errorf( "sfxPlayOnce - unable to create profile" ); - delete tempProfile; } else { - if (String::isEmpty(arg1)) - source = SFX->playOnce( tempProfile ); - else - { - MatrixF transform; - transform.set( EulerF( 0, 0, 0 ), Point3F( dAtof( arg1 ), dAtof( arg2 ),dAtof( arg3 ) ) ); - source = SFX->playOnce( tempProfile, &transform, NULL, dAtof( arg4 ) ); - } - - // Set profile to auto-delete when SFXSource releases its reference. - // Also add to root group so the profile will get deleted when the - // Sim system is shut down before the SFXSource has played out. - - tempProfile->setAutoDelete( true ); - Sim::getRootGroup()->addObject( tempProfile ); - } + Con::errorf("sfxPlayOnce - Could not locate assetId '%s'", assetId); + return 0; } if( !source ) From ecd35df7e9e92c48b177d96725218053510e92b4 Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 20 Jan 2022 01:14:43 -0600 Subject: [PATCH 012/145] Implementation of updated handling of Legacy Project importer to better seperate out importer versions as well as more explicit processing of incoming content --- Engine/source/T3D/assets/GUIAsset.cpp | 2 +- Engine/source/T3D/assets/ShapeAsset.cpp | 4 +- Engine/source/T3D/assets/assetImporter.cpp | 26 +- Engine/source/persistence/taml/taml.cpp | 5 + .../persistence/taml/taml_ScriptBinding.h | 6 +- .../tools/assetBrowser/assetImportConfigs.xml | 2 +- .../projectImporter/guis/projectImporter.gui | 1271 +++++--------- .../pre40/T3Dpre4ProjectImporter.tscript | 1376 +++++++++++++++ .../pre40/pre40ImporterGuis.asset.taml | 7 + .../importers/pre40/pre40ImporterGuis.gui | 129 ++ .../importers/pre40/pre40ImporterGuis.tscript | 92 + .../game/tools/projectImporter/main.tscript | 5 - .../pre40/T3Dpre4ProjectImporter.tscript | 1320 -------------- .../scripts/projectImporter.tscript | 1525 +++++++++++------ 14 files changed, 3107 insertions(+), 2663 deletions(-) create mode 100644 Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript create mode 100644 Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.asset.taml create mode 100644 Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.gui create mode 100644 Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript delete mode 100644 Templates/BaseGame/game/tools/projectImporter/scripts/pre40/T3Dpre4ProjectImporter.tscript diff --git a/Engine/source/T3D/assets/GUIAsset.cpp b/Engine/source/T3D/assets/GUIAsset.cpp index acef864db..a8f4fe0f3 100644 --- a/Engine/source/T3D/assets/GUIAsset.cpp +++ b/Engine/source/T3D/assets/GUIAsset.cpp @@ -102,7 +102,7 @@ void GUIAsset::initPersistFields() &setScriptFile, &getScriptFile, "Path to the script file for the gui"); addProtectedField("GUIFile", TypeAssetLooseFilePath, Offset(mGUIFile, GUIAsset), - &setScriptFile, &getScriptFile, "Path to the gui file"); + &setGUIFile, &getGUIFile, "Path to the gui file"); } //------------------------------------------------------------------------------ diff --git a/Engine/source/T3D/assets/ShapeAsset.cpp b/Engine/source/T3D/assets/ShapeAsset.cpp index c145965a1..fb3be2341 100644 --- a/Engine/source/T3D/assets/ShapeAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAsset.cpp @@ -623,8 +623,8 @@ const char* ShapeAsset::generateCachedPreviewImage(S32 resolution, String overri String dumpPath = String(mFilePath) + "_Preview.dds"; - char* returnBuffer = Con::getReturnBuffer(dumpPath.length()); - dSprintf(returnBuffer, dumpPath.length(), "%s", dumpPath.c_str()); + char* returnBuffer = Con::getReturnBuffer(128); + dSprintf(returnBuffer, 128, "%s", dumpPath.c_str()); /*FileStream stream; if (stream.open(dumpPath, Torque::FS::File::Write)) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index 7c0bda9ae..7bb109f02 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -2099,22 +2099,28 @@ void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 m String imgFileName = AssetImporter::findImagePath(testFilePath.getPath() + "/" + testFilePath.getFileName()); if (imgFileName.isNotEmpty()) filePath = imgFileName; + else + filePath = ""; //no luck, so we just won't try importing in the image } } matAssetItem = addImportingAsset("MaterialAsset", shapePathBase + "/" + matName, assetItem, matName); - AssetImportObject* imageAssetItem = addImportingAsset("ImageAsset", filePath, matAssetItem, ""); - String suffixType; - String suffix = parseImageSuffixes(imageAssetItem->assetName, &suffixType); - if (suffix.isNotEmpty()) + if (!filePath.isEmpty()) { - imageAssetItem->imageSuffixType = suffixType; - } - else - { - //we'll assume it's albedo - imageAssetItem->imageSuffixType = "Albedo"; + AssetImportObject* imageAssetItem = addImportingAsset("ImageAsset", filePath, matAssetItem, ""); + + String suffixType; + String suffix = parseImageSuffixes(imageAssetItem->assetName, &suffixType); + if (suffix.isNotEmpty()) + { + imageAssetItem->imageSuffixType = suffixType; + } + else + { + //we'll assume it's albedo + imageAssetItem->imageSuffixType = "Albedo"; + } } } else diff --git a/Engine/source/persistence/taml/taml.cpp b/Engine/source/persistence/taml/taml.cpp index b05b0d8bc..2bfd104b9 100644 --- a/Engine/source/persistence/taml/taml.cpp +++ b/Engine/source/persistence/taml/taml.cpp @@ -217,6 +217,11 @@ ImplementEnumType(_TamlFormatMode, FileStream stream; + if (StringTable->insert("c://.asset.taml") == StringTable->insert(mFilePathBuffer)) + { + bool asdfasdf = true; + } + // File opened? if (!stream.open(mFilePathBuffer, Torque::FS::File::Write)) { diff --git a/Engine/source/persistence/taml/taml_ScriptBinding.h b/Engine/source/persistence/taml/taml_ScriptBinding.h index 6e4a3ed09..841fadb8f 100644 --- a/Engine/source/persistence/taml/taml_ScriptBinding.h +++ b/Engine/source/persistence/taml/taml_ScriptBinding.h @@ -256,8 +256,10 @@ DefineEngineFunction(TamlWrite, bool, (SimObject* simObject, const char* filenam } else { - // No, so warn. - Con::warnf( "TamlWrite() - Setting binary compression is only valid for XML formatting." ); +#ifdef TORQUE_DEBUG + // No, so warn. + Con::warnf( "TamlWrite() - Setting binary compression is only valid for XML formatting." ); +#endif } // Turn-off auto-formatting. diff --git a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml index 8417b1fa4..faa7ab1e6 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml +++ b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml @@ -100,7 +100,7 @@ LOS - 1 + 0 0 FolderPrefix 1 diff --git a/Templates/BaseGame/game/tools/projectImporter/guis/projectImporter.gui b/Templates/BaseGame/game/tools/projectImporter/guis/projectImporter.gui index 480e71704..bed599d3e 100644 --- a/Templates/BaseGame/game/tools/projectImporter/guis/projectImporter.gui +++ b/Templates/BaseGame/game/tools/projectImporter/guis/projectImporter.gui @@ -45,25 +45,27 @@ $guiContent = new GuiControl(ProjectImportCtrl) { canSave = "1"; canSaveDynamicFields = "0"; - new GuiSplitContainer() { - orientation = "Vertical"; - splitterSize = "2"; - splitPoint = "152 100"; - fixedPanel = "FirstPanel"; - fixedSize = "100"; - docking = "None"; + new GuiScrollCtrl(ProejctImportPageContainer) { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; margin = "0 0 0 0"; padding = "0 0 0 0"; anchorTop = "1"; anchorBottom = "0"; anchorLeft = "1"; anchorRight = "0"; - position = "6 24"; - extent = "531 445"; - minExtent = "64 64"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiSolidDefaultProfile"; + position = "0 25"; + extent = "541 437"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiScrollProfile"; visible = "1"; active = "1"; tooltipProfile = "GuiToolTipProfile"; @@ -72,844 +74,497 @@ $guiContent = new GuiControl(ProjectImportCtrl) { canSave = "1"; canSaveDynamicFields = "0"; - new GuiPanel() { - docking = "Client"; + new GuiContainer(ProjectImportWizardPage0) { margin = "0 0 0 0"; padding = "0 0 0 0"; anchorTop = "1"; anchorBottom = "0"; anchorLeft = "1"; anchorRight = "0"; - position = "0 0"; - extent = "150 445"; - minExtent = "16 16"; - horizSizing = "right"; + position = "1 1"; + extent = "365 429"; + minExtent = "8 2"; + horizSizing = "width"; vertSizing = "bottom"; profile = "GuiDefaultProfile"; - visible = "1"; + visible = "0"; active = "1"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "1"; - internalName = "Panel1"; + internalName = "page0"; + hidden = "1"; canSave = "1"; canSaveDynamicFields = "0"; - new GuiScrollCtrl() { - willFirstRespond = "1"; - hScrollBar = "dynamic"; - vScrollBar = "dynamic"; - lockHorizScroll = "0"; - lockVertScroll = "0"; - constantThumbHeight = "0"; - childMargin = "0 0"; - mouseWheelScrollSpeed = "-1"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "0 0"; - extent = "150 445"; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Welcome! This project importer will assist you in importing in legacy projects into this build of Torque3D."; + useURLMouseCursor = "0"; + position = "23 21"; + extent = "328 28"; minExtent = "8 2"; - horizSizing = "width"; - vertSizing = "height"; - profile = "ToolsGuiScrollProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; visible = "1"; active = "1"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; - isContainer = "1"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "To continue, click Next."; + useURLMouseCursor = "0"; + position = "23 77"; + extent = "328 14"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; canSave = "1"; canSaveDynamicFields = "0"; - - new GuiTextListCtrl() { - columns = "0"; - fitParentWidth = "1"; - clipColumnText = "0"; - rowHeightPadding = "2"; - position = "1 1"; - extent = "135 128"; - minExtent = "8 2"; - horizSizing = "width"; - vertSizing = "height"; - profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "stepsList"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiControl() { - position = "1 1"; - extent = "150 445"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; }; }; - new GuiPanel() { - docking = "Client"; + new GuiContainer(ProjectImportWizardPage1) { margin = "0 0 0 0"; padding = "0 0 0 0"; anchorTop = "1"; anchorBottom = "0"; anchorLeft = "1"; anchorRight = "0"; - position = "154 0"; - extent = "377 445"; - minExtent = "16 16"; - horizSizing = "right"; + position = "1 1"; + extent = "539 429"; + minExtent = "8 2"; + horizSizing = "width"; vertSizing = "bottom"; profile = "GuiDefaultProfile"; - visible = "1"; + visible = "0"; active = "1"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "1"; - internalName = "panel2"; + internalName = "page1"; + hidden = "1"; canSave = "1"; canSaveDynamicFields = "0"; - new GuiScrollCtrl() { - willFirstRespond = "1"; - hScrollBar = "dynamic"; - vScrollBar = "dynamic"; - lockHorizScroll = "0"; - lockVertScroll = "0"; - constantThumbHeight = "0"; - childMargin = "0 0"; - mouseWheelScrollSpeed = "-1"; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "First, you must select what version of Torque3D the prior project\'s content is coming from."; + useURLMouseCursor = "0"; + position = "23 21"; + extent = "328 28"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; margin = "0 0 0 0"; padding = "0 0 0 0"; anchorTop = "1"; anchorBottom = "0"; anchorLeft = "1"; anchorRight = "0"; - position = "0 0"; - extent = "377 445"; + position = "138 104"; + extent = "268 18"; minExtent = "8 2"; - horizSizing = "width"; - vertSizing = "height"; - profile = "ToolsGuiScrollProfile"; - visible = "1"; + horizSizing = "center"; + vertSizing = "bottom"; + profile = "ToolsGuiPopUpMenuProfile"; + visible = "0"; active = "1"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "1"; + internalName = "previousContentVersionPopup"; + hidden = "1"; canSave = "1"; canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Now that that\'s selected, press Next to continue."; + useURLMouseCursor = "0"; + position = "23 181"; + extent = "328 14"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer(ProjectImportWizardPage2) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 1"; + extent = "538 429"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "page2"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; - new GuiContainer(ProjectImportWizardPage0) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "1 1"; - extent = "365 429"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "0"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "page0"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Next, where is the previous project\'s content?"; + useURLMouseCursor = "0"; + position = "23 21"; + extent = "328 14"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Now, point to the folder to be imported."; + useURLMouseCursor = "0"; + position = "123 221"; + extent = "328 14"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Find Folder"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "123 246"; + extent = "330 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "0"; + active = "1"; + command = "ProjectImportWindow.selectOGFolder();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "selectOriginalContentFolderBtn"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + position = "23 341"; + extent = "500 14"; + minExtent = "8 2"; + horizSizing = "center"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "targetImportingPath"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer(ProjectImportWizardPage3) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 1"; + extent = "539 429"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "page3"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "Welcome! This project importer will assist you in importing in legacy projects into this build of Torque3D."; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 21"; - extent = "328 28"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "To continue, click Next."; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 77"; - extent = "328 14"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiContainer(ProjectImportWizardPage1) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "1 1"; - extent = "365 429"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "0"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "page1"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Under normal circumstances, all game content in Torque3D is grouped together in packages named Modules. These are placed into the game\'s data/ directory, which the system automatically scans on start. "; + useURLMouseCursor = "0"; + position = "23 21"; + extent = "328 56"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "To port your legacy content, first we need a module to port the content into. Please provide a module name in the text field below, and the importer will create a new module folder for you."; + useURLMouseCursor = "0"; + position = "23 85"; + extent = "325 42"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "For your convenience, we\'ve pre-populated the field with the name of the folder you\'d selected to import, but you can change it to whatever you want the module to be!"; + useURLMouseCursor = "0"; + position = "119 157"; + extent = "325 42"; + minExtent = "8 2"; + horizSizing = "center"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 215"; + extent = "209 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "newModuleName"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer(ProjectImportWizardPage4) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 1"; + extent = "539 429"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "page4"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "First, you must select what version of Torque3D the prior project\'s content is coming from."; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 21"; - extent = "328 28"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl() { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "50 104"; - extent = "268 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "previousContentVersionPopup"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "Now that that\'s selected, press Next to continue."; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 181"; - extent = "328 14"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiContainer(ProjectImportWizardPage2) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "1 1"; - extent = "365 429"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "page2"; - canSave = "1"; - canSaveDynamicFields = "0"; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Before we run the actual import, we\'ll start by preprocessing the files so we know what we\'re working with. This may take a moment."; + useURLMouseCursor = "0"; + position = "23 21"; + extent = "328 42"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Done!"; + useURLMouseCursor = "0"; + position = "107 181"; + extent = "328 14"; + minExtent = "8 2"; + horizSizing = "center"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "preprocessCompleteText"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer(ProjectImportWizardFinalPage) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 1"; + extent = "539 429"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "Next, where is the previous project\'s content?"; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 21"; - extent = "328 14"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiRadioCtrl() { - text = "Existing folder in current project\'s data/ folder"; - groupNum = "-1"; - buttonType = "RadioButton"; - useMouseEvents = "0"; - position = "22 53"; - extent = "320 52"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiRadioProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "internalFolderBtn"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiRadioCtrl() { - text = "Existing folder not in the current project\'s data/ folder"; - groupNum = "-1"; - buttonType = "RadioButton"; - useMouseEvents = "0"; - position = "22 109"; - extent = "320 52"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiRadioProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "externalFolderBtn"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiRadioCtrl() { - text = "Core and Tools"; - groupNum = "-1"; - buttonType = "RadioButton"; - useMouseEvents = "0"; - position = "22 157"; - extent = "320 52"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiRadioProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "coreAndToolsBtn"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "Now, point to the folder to be imported."; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 221"; - extent = "328 14"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl() { - text = "Find Folder"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "19 246"; - extent = "330 30"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; - command = "ProjectImportWindow.selectOGFolder();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "selectOriginalContentFolderBtn"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 341"; - extent = "328 14"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "targetImportingPath"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiContainer(ProjectImportWizardPage3) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "1 1"; - extent = "365 429"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "0"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "page3"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "Under normal circumstances, all game content in Torque3D is grouped together in packages named Modules. These are placed into the game\'s data/ directory, which the system automatically scans on start. "; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 21"; - extent = "328 56"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "To port your legacy content, first we need a module to port the content into. Please provide a module name in the text field below, and the importer will create a new module folder for you."; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 85"; - extent = "325 42"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "For your convenience, we\'ve pre-populated the field with the name of the folder you\'d selected to import, but you can change it to whatever you want the module to be!"; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 157"; - extent = "325 42"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "79 215"; - extent = "209 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextEditProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "newModuleName"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiContainer(ProjectImportWizardPage4) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "1 1"; - extent = "365 429"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "0"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "page4"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 21"; - extent = "328 14"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "fileCopyText"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiContainer(ProjectImportWizardPage5) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "1 1"; - extent = "365 429"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "0"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "page5"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "Now we actually run the import of the files and content. This will process the original files into assets, and updating any references in scripts to utilize the new AssetIDs."; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 21"; - extent = "328 42"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "Processing..."; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "64 141"; - extent = "245 14"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "processingText"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiContainer(ProjectImportWizardPage6) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "1 1"; - extent = "365 429"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "0"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "page6"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "We\'ll now go through and process any script files to ensure they use the currently designated extension."; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 21"; - extent = "328 28"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "Processing..."; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "64 141"; - extent = "245 14"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "processingText"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiContainer(ProjectImportWizardPage7) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "1 1"; - extent = "365 429"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "0"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "page7"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - text = "And with that, your legacy project content has been imported in as a Torque3D 4.0 ready module!"; - useURLMouseCursor = "0"; - useTypeOverTime = "0"; - typeOverTimeSpeedMS = "10"; - typeoutSoundRate = "-1"; - position = "23 141"; - extent = "328 28"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "And with that, your legacy project content has been imported in as a Torque3D-ready module!"; + useURLMouseCursor = "0"; + position = "119 173"; + extent = "328 28"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; }; }; }; @@ -956,32 +611,6 @@ $guiContent = new GuiControl(ProjectImportCtrl) { canSave = "1"; canSaveDynamicFields = "0"; }; - new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:iconInformation_image"; - bitmapMode = "Centered"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "-187 555"; - extent = "22 22"; - minExtent = "8 2"; - horizSizing = "left"; - vertSizing = "bottom"; - profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; - command = "ImportAssetWindow.toggleLogWindow();"; - tooltipProfile = "GuiToolTipProfile"; - tooltip = "View Import Log"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; }; }; //--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript new file mode 100644 index 000000000..693d22a6c --- /dev/null +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript @@ -0,0 +1,1376 @@ +function T3Dpre4ProjectImporter::init() +{ + //register this importer option to the project importer listing + if(isObject(T3Dpre4ProjectImporter)) + T3Dpre4ProjectImporter.delete(); + + new ScriptObject(T3Dpre4ProjectImporter); + + //Now we register the importer so it shows in the listing + $ProjectImporter::importerList.add("Pre-4.0 T3D Project", T3Dpre4ProjectImporter); + + %result = AssetDatabase.acquireAsset("ToolsModule:pre40ImporterGuis"); +} + +T3Dpre4ProjectImporter::init(); //kick off the setup + +function T3Dpre4ProjectImporter::setupPages(%this) +{ + ProjectImportWindow.addImporterPage(Pre40ImporterPage0); + ProjectImportWindow.addImporterPage(Pre40ImporterPage1); + + ProjectImportWindow.refreshPage(); +} + +// +// +function T3Dpre4ProjectImporter::setupModule(%this) +{ + %newModuleName = $ProjectImporter::moduleName; + + projectImporterLog("Setup up Module named: " @ %newModuleName); + + %moduleFilePath = "data/" @ %newModuleName; + %moduleDefinitionFilePath = %moduleFilePath @ "/" @ %newModuleName @ ".module"; + %moduleScriptFilePath = %moduleFilePath @ "/" @ %newModuleName @ "." @ $TorqueScriptFileExtension; + + if(!isImportingFile($ProjectImporter::sourceContentFolder @ "/" @ %newModuleName @ ".module")) + { + %newModule = new ModuleDefinition() + { + ModuleId = %newModuleName; + versionId = 1; + ScriptFile = %newModuleName @ "." @ $TorqueScriptFileExtension; + CreateFunction="onCreate"; + DestroyFunction="onDestroy"; + Group = "Game"; + + new DeclaredAssets() + { + Extension = "asset.taml"; + Recurse = true; + }; + }; + + TAMLWrite(%newModule, %moduleDefinitionFilePath); + } + + //if we don't already have a incoming file that matches this, then we'll want to make a new one + if(!isImportingFile($ProjectImporter::sourceContentFolder @ "/" @ %newModuleName @ ".cs") && + !isImportingFile($ProjectImporter::sourceContentFolder @ "/" @ %newModuleName @ "." @ $TorqueScriptFileExtension)) + { + //Now generate the script file for it + %file = new FileObject(); + %templateFile = new FileObject(); + + %moduleTemplateCodeFilePath = AssetBrowser.templateFilesPath @ "module.tscript.template"; + + if(%file.openForWrite(%moduleScriptFilePath) && %templateFile.openForRead(%moduleTemplateCodeFilePath)) + { + while( !%templateFile.isEOF() ) + { + %line = %templateFile.readline(); + %line = strreplace( %line, "@@", %newModuleName ); + + %file.writeline(%line); + //projectImporterLog(%line); + } + + %file.close(); + %templateFile.close(); + } + else + { + %file.close(); + %templateFile.close(); + + projectImporterLog("CreateNewModule - Something went wrong and we couldn't write the script file!"); + } + } + + //force a refresh of our modules list + ModuleDatabase.ignoreLoadedGroups(true); + ModuleDatabase.scanModules( "data", false ); + %success = ModuleDatabase.loadExplicit(%newModuleName, 1); + ModuleDatabase.ignoreLoadedGroups(false); + + //force a reload of the Module lists + AssetBrowser.refresh(); +} + +/*function T3Dpre4ProjectImporter::copyFiles(%this) +{ + %currentPage = ProjectImportWindow.getCurrentPage(); + + %currentPage-->fileCopyText.setText("Beginning copy of files to new module folder now. This may take a few minutes..."); + Canvas.repaint(); + + %file = findFirstFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*", true); + + while( %file !$= "" ) + { + %filePath = filePath(%file); + %fileName = fileName(%file); + %fileBase = fileBase(%file); + %fileExt = fileExt(%file); + + if(endsWith(%fileName, ".asset.taml")) + { + %fileBase = strreplace(%fileBase, ".asset", ""); + %fileExt = ".asset.taml"; + } + + if(%fileExt $= ".dll" || %fileExt $= ".log" || %fileExt $= ".exe" || %fileExt $= ".manifest"|| %fileExt $= ".h" || + %fileExt $= ".cpp" || %fileExt $= ".so" || %fileExt $= ".do" || %fileExt $= ".lib" ||%fileExt $= ".exp") + { + %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); + continue; + } + + //filter out some unneeded folders + %slashCount = getTokenCount(%filePath, "/"); + %topFolder = getToken(%filePath, "/", %slashCount-1); + if(%topFolder $= "") + %topFolder = getToken(%filePath, "/", %slashCount-2); + + if(%topFolder $= "creator" || %topFolder $= "tools" || %topFolder $= "web") + { + %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); + continue; + } + + %targetFilePath = strReplace(%file, $ProjectImporter::sourceContentFolder, $ProjectImporter::modulePath); + + %sanitizedFilename = sanitizeString(%fileBase); + if(startsWith(%sanitizedFilename, "_")) + { + %sanitizedFilename = substr(%sanitizedFilename, 1, -1); + } + if(%sanitizedFilename !$= %fileBase) + { + %targetFilePath = filePath(%targetFilePath) @ "/" @ %sanitizedFilename @ %fileExt; + } + + %targetFolder = filePath(%targetFilePath); + + if(!isDirectory(%targetFolder)) + { + DirectoryHandler::createFolder(0, %targetFolder); + } + + if(!pathCopy(%file, %targetFilePath, false)) + { + projectImporterLog("Legacy Project Importer, failed to copy file: " @ %file @ " to destination: " @ %targetFilePath); + } + + %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); + } + + // + //Now that we've done that, we'll load and scan the module for asset defs + %file = findFirstFileMultiExpr( $ProjectImporter::modulePath @ "/*.asset.taml", true); + + while( %file !$= "" ) + { + %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%file).ModuleId; + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + + AssetDatabase.addDeclaredAsset(%moduleDef, %file); + + %file = findNextFileMultiExpr( $ProjectImporter::modulePath @ "/*.asset.taml" ); + } + // + + %currentPage-->fileCopyText.setValue("File copy done! Press Next to continue."); + + ProjectImportWindow-->nextButton.setActive(true); + Canvas.repaint(); +} + +function T3Dpre4ProjectImporter::processImportedFiles(%this) +{ + if($ProjectImporter::importMode $= "CoreAndTools") + { + $ProjectImporter::modulePath = "Core"; + %this.doImport(); + + $ProjectImporter::modulePath = "Tools"; + %this.doImport(); + } + else + { + %this.doImport(); + } + + %currentPage = ProjectImportWindow.getCurrentPage(); + + %currentPage-->processingText.setText("Processing of files done! Press Next to continue."); + ProjectImportWindow-->nextButton.setActive(true); + Canvas.repaint(); +}*/ + +function T3Dpre4ProjectImporter::doContentImport(%this) +{ + //Store off the current default import config + %this.defaultConfig = EditorSettings.value("Assets/AssetImporDefaultConfig", ""); + EditorSettings.setValue("Assets/AssetImporDefaultConfig", "LegacyProjectImport"); + + //Update asset content + beginImageImport(); + + %this.beginMaterialFilesImport(); + + beginShapeImport(); + beginTerrainImport(); + + %this.beginSoundProfilesImport(); +} + +function T3Dpre4ProjectImporter::doScriptImport(%this) +{ + beginLevelImport(); + beginGUIImport(); + + %this.beginScriptFilesImport(); + + %this.beginAssetAndModuleImport(); + + %this.writeImportingFiles(); + + EditorSettings.setValue("Assets/AssetImporDefaultConfig", %this.defaultConfig); +} + +function T3Dpre4ProjectImporter::writeImportingObject(%this, %arrayObj) +{ + if(!isObject(%arrayObj) || %arrayObj.skip) + return; + + for(%i=0; %i < %arrayObj.count(); %i++) + { + %objectLine = %arrayObj.getKey(%i); + if(isObject(%objectLine)) + { + if(%objectLine.skip == false) + { + %this.writeImportingObject(%objectLine); + } + } + else + { + $ProjectImporter::fileObject.writeLine(%objectLine); + } + } +} + +function T3Dpre4ProjectImporter::writeImportingFiles(%this) +{ + //First, we need to go through and process all loose image files. This will + //get us shape assets, and if the import config deigns, material assets. + %currentAddress = $ProjectImporter::modulePath; + + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + + if(!%rootFileSectionObject.skip && !%rootFileSectionObject.binaryFile) + { + %path = filePath(%rootFileSectionObject.fileDestination); + + if(!IsDirectory(%path)) + { + DirectoryHandler::createFolder(0, %path); + } + + if ( $ProjectImporter::fileObject.openForWrite( %rootFileSectionObject.fileDestination ) ) + { + %this.writeImportingObject(%rootFileSectionObject); + + $ProjectImporter::fileObject.close(); + } + } + + if($ProjectImporter::useExistingModule) + { + //clean up legact files if they've been renamed or whatnot + if(%file !$= %rootFileSectionObject.fileDestination) + { + fileDelete(%file); + } + } + } +} + +// +function T3Dpre4ProjectImporter::processMaterialObjects(%this, %arrayObj) +{ + if(!isObject(%arrayObj)) + return; + + //We only really care about materials for this + if(%arrayObj.elementType $= "function" || + (%arrayObj.elementType $= "Object" && %arrayObj.classType !$= "Material" && %arrayObj.classType !$= "CustomMaterial")) + { + return; + } + + for(%e=0; %e < %arrayObj.count(); %e++) + { + %lineObj = %arrayObj.getKey(%e); + if(isObject(%lineObj)) + { + if( %lineObj.elementType $= "Object") + { + if(%lineObj.classType $= "Material" || %lineObj.classType $= "CustomMaterial") + { + %materialName = %lineObj.objectName; + if(%materialName $= "") + { + %mapToName = findObjectField(%lineObj, "mapTo"); + %lineObj.objectName = %mapToName @ "_mat"; + } + + %sanitizedName = sanitizeString(%materialName); + if(startsWith(%sanitizedName, "_")) + { + %sanitizedName = getSubStr(%sanitizedName, 1, -1); + } + + projectImporterLog("processMaterialObjects() - beginning processing of material: " @ %sanitizedName); + + if(%lineObj.objectName !$= %sanitizedName) + renameObjectName(%lineObj, %sanitizedName); + + //Now, we process the fields to be asset-ified on our object + for(%l=0; %l < %lineObj.count(); %l++) + { + %objectCodeLine = %lineObj.getKey(%l); + if(!isObject(%objectCodeLine)) + { + %resultLine = T3Dpre4ProjectImporter.processMaterialLine(%objectCodeLine); + if(%resultLine !$= %objectCodeLine) + { + projectImporterLog(" processed line: " @ %resultLine @ " from: " @ %objectCodeLine); + %lineObj.setKey(%resultLine, %l); + } + } + } + + //This walks through the class heirarchy so in the event we get a + //class that has a shared common root class like with water or materials + //we can process with that class to cover the probability space + + %inheritanceList = getClassHierarchy(%lineObj.classType); + for (%classDepth = 0; %classDepth < getWordCount(%inheritanceList); %classDepth++) + { + %subclass = getWord(%inheritanceList, %classDepth); + %processFunction = "process" @ %subclass @ "Object"; + if(T3Dpre4ProjectImporter.isMethod(%processFunction)) + { + T3Dpre4ProjectImporter.call(%processFunction, %lineObj, %sanitizedName); + } + } + } + else if(%lineObj.classType $= "TerrainMaterial") + { + %intName = findObjectField(%lineObj, "internalName"); + %materialName = %intName @ "_terrainMat"; + + %sanitizedName = sanitizeString(%materialName); + if(startsWith(%sanitizedName, "_")) + { + %sanitizedName = getSubStr(%sanitizedName, 1, -1); + } + + if(%intName !$= %sanitizedName) + setObjectField(%lineObj, "internalName", %sanitizedName); + + //Now, we process the fields to be asset-ified on our object + for(%l=0; %l < %lineObj.count(); %l++) + { + %objectCodeLine = %lineObj.getKey(%l); + if(!isObject(%objectCodeLine)) + { + %resultLine = T3Dpre4ProjectImporter.processTerrainMaterialLine(%objectCodeLine); + if(%resultLine !$= %objectCodeLine) + { + projectImporterLog(" processed line: " @ %resultLine @ " from: " @ %objectCodeLine); + %lineObj.setKey(%resultLine, %l); + } + } + } + + //This walks through the class heirarchy so in the event we get a + //class that has a shared common root class like with water or materials + //we can process with that class to cover the probability space + + %inheritanceList = getClassHierarchy(%lineObj.classType); + for (%classDepth = 0; %classDepth < getWordCount(%inheritanceList); %classDepth++) + { + %subclass = getWord(%inheritanceList, %classDepth); + %processFunction = "process" @ %subclass @ "Object"; + if(T3Dpre4ProjectImporter.isMethod(%processFunction)) + { + T3Dpre4ProjectImporter.call(%processFunction, %lineObj, %sanitizedName); + } + } + } + else + { + continue; + } + /**/ + %oN = %lineObj.objectName; + + %lineObj.processed = true; + %lineObj.skip = true; + } + + //Recurse down as needed + %this.processMaterialObjects(%lineObj); + } + } +} + +function T3Dpre4ProjectImporter::beginMaterialFilesImport(%this) +{ + projectImporterLog("==========================================="); + projectImporterLog("Importing Material definitions"); + projectImporterLog("==========================================="); + + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + + $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/"; //give context to the file we're processing + + if(%rootFileSectionObject.binaryFile == true || %rootFileSectionObject.imported == true) + continue; + + %this.processMaterialObjects(%rootFileSectionObject); + } + + projectImporterLog("==========================================="); + projectImporterLog("Importing Material definitions finished"); + projectImporterLog("==========================================="); +} + +// +function T3Dpre4ProjectImporter::processSoundProfileObjects(%this, %arrayObj) +{ + if(!isObject(%arrayObj)) + return; + + //We only really care about materials for this + if((%arrayObj.elementType $= "Object" && %arrayObj.classType !$= "SFXProfile")) + { + return; + } + + for(%e=0; %e < %arrayObj.count(); %e++) + { + %lineObj = %arrayObj.getKey(%e); + if(isObject(%lineObj)) + { + if( %lineObj.elementType $= "Object") + { + if(%lineObj.classType $= "SFXProfile") + { + %profileName = %lineObj.objectName; + + %sanitizedName = sanitizeString(%profileName); + if(startsWith(%sanitizedName, "_")) + { + %sanitizedName = getSubStr(%sanitizedName, 1, -1); + } + + projectImporterLog("processSoundProfileObjects() - beginning processing of SFXProfile: " @ %sanitizedName); + + if(%lineObj.objectName !$= %sanitizedName) + renameObjectName(%lineObj, %sanitizedName); + + //This walks through the class heirarchy so in the event we get a + //class that has a shared common root class like with water or materials + //we can process with that class to cover the probability space + %inheritanceList = getClassHierarchy(%lineObj.classType); + for (%classDepth = 0; %classDepth < getWordCount(%inheritanceList); %classDepth++) + { + %subclass = getWord(%inheritanceList, %classDepth); + %processFunction = "process" @ %subclass @ "Object"; + if(T3Dpre4ProjectImporter.isMethod(%processFunction)) + { + T3Dpre4ProjectImporter.call(%processFunction, %lineObj, %sanitizedName); + } + } + + //Now, we process the fields to be asset-ified on our object + for(%l=0; %l < %lineObj.count(); %l++) + { + %objectCodeLine = %lineObj.getKey(%l); + if(!isObject(%objectCodeLine)) + { + %resultLine = T3Dpre4ProjectImporter.processSFXProfileLine(%objectCodeLine); + if(%resultLine !$= %objectCodeLine) + { + projectImporterLog(" processed line: " @ %resultLine @ " from: " @ %objectCodeLine); + %lineObj.setKey(%resultLine, %l); + } + } + } + } + else + { + continue; + } + + %lineObj.processed = true; + %lineObj.skip = true; + } + + //Recurse down as needed + %this.processSoundProfileObjects(%lineObj); + } + } +} + +function T3Dpre4ProjectImporter::beginSoundProfilesImport(%this) +{ + projectImporterLog("==========================================="); + projectImporterLog("Importing Sound Profiles"); + projectImporterLog("==========================================="); + + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + + $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/"; //give context to the file we're processing + + if(%rootFileSectionObject.binaryFile == true || %rootFileSectionObject.imported == true) + continue; + + %this.processSoundProfileObjects(%rootFileSectionObject); + } + + projectImporterLog("==========================================="); + projectImporterLog("Importing Sound Profiles finished"); + projectImporterLog("==========================================="); +} + +// +function T3Dpre4ProjectImporter::processScripts(%this, %arrayObj) +{ + if(!isObject(%arrayObj)) + return; + + //We only really care about materials for this + if((%arrayObj.elementType $= "Object" && (%arrayObj.classType $= "Material" || %arrayObj.classType $= "CustomMaterial" || %arrayObj.classType $= "TerrainMaterial"))) + { + return; + } + + for(%e=0; %e < %arrayObj.count(); %e++) + { + %lineObj = %arrayObj.getKey(%e); + if(isObject(%lineObj) && !%lineObj.skip) + { + if( %lineObj.elementType $= "Object") + { + %sanitizedName = sanitizeString(%lineObj.objectName); + if(startsWith(%sanitizedName, "_")) + { + %sanitizedName = getSubStr(%sanitizedName, 1, -1); + } + + if(%sanitizedName !$= "") + projectImporterLog("processScriptObjects() - beginning processing of object: " @ %lineObj.classType @ "(" @ %sanitizedName @ ")"); + else + projectImporterLog("processScriptObjects() - beginning processing of object: " @ %lineObj.classType @ "()"); + + if(%lineObj.objectName !$= %sanitizedName && %lineObj.objectName !$= "") + renameObjectName(%lineObj, %sanitizedName); + + //This walks through the class heirarchy so in the event we get a + //class that has a shared common root class like with water or materials + //we can process with that class to cover the probability space + + %inheritanceList = getClassHierarchy(%lineObj.classType); + for (%classDepth = 0; %classDepth < getWordCount(%inheritanceList); %classDepth++) + { + %subclass = getWord(%inheritanceList, %classDepth); + %processFunction = "process" @ %subclass @ "Object"; + + if(T3Dpre4ProjectImporter.isMethod(%processFunction)) + { + T3Dpre4ProjectImporter.call(%processFunction, %lineObj, %sanitizedName); + } + + //Now, we process the fields to be asset-ified on our object + for(%l=0; %l < %lineObj.count(); %l++) + { + %objectCodeLine = %lineObj.getKey(%l); + if(!isObject(%objectCodeLine)) + { + %processLineFunction = "process" @ %subclass @ "Line"; + if(T3Dpre4ProjectImporter.isMethod(%processLineFunction)) + { + %resultLine = T3Dpre4ProjectImporter.call(%processLineFunction, %objectCodeLine); + + if(%resultLine !$= %objectCodeLine) + { + projectImporterLog(" processed line: " @ %resultLine @ " from: " @ %objectCodeLine); + %lineObj.setKey(%resultLine, %l); + } + } + } + } + } + + %lineObj.processed = true; + } + else if(%lineObj.elementType $= "function") + { + //Now, we process the fields to be asset-ified on our object + for(%l=0; %l < %lineObj.count(); %l++) + { + %functionCodeLine = %lineObj.getKey(%l); + if(!isObject(%functionCodeLine)) + { + %resultLine = %functionCodeLine; + + if(strIsMatchExpr("*exec(*.cs*)*", %functionCodeLine) || strIsMatchExpr("*exec(*.tscript*)*", %functionCodeLine)) + { + %scriptExtRemovedLine = strReplace(%functionCodeLine, ".cs", ""); + %scriptExtRemovedLine = strReplace(%scriptExtRemovedLine, ".tscript", ""); + %resultLine = %scriptExtRemovedLine; + } + else if(strIsMatchExpr("*queueexec(*.cs*)*", %functionCodeLine) || strIsMatchExpr("*queueexec(*.tscript*)*", %functionCodeLine)) + { + %scriptExtRemovedLine = strReplace(%functionCodeLine, ".cs", ""); + %scriptExtRemovedLine = strReplace(%scriptExtRemovedLine, ".tscript", ""); + %resultLine = %scriptExtRemovedLine; + } + else if(strIsMatchExpr("*registerDatablock(*.cs*)*", %functionCodeLine) || strIsMatchExpr("*registerDatablock(*.tscript*)*", %functionCodeLine)) + { + %scriptExtRemovedLine = strReplace(%functionCodeLine, ".cs", ""); + %scriptExtRemovedLine = strReplace(%scriptExtRemovedLine, ".tscript", ""); + %resultLine = %scriptExtRemovedLine; + } + else if(strIsMatchExpr("*%this.addSequence(\"*);", %functionCodeLine)) + { + %resultLine = processLegacyShapeConstructorField(%functionCodeLine); + } + + if(%resultLine !$= %functionCodeLine) + { + %lineObj.setKey(%resultLine, %l); + } + } + } + + %lineObj.processed = true; + } + + //Recurse down as needed + %this.processScripts(%lineObj); + } + } +} + +function T3Dpre4ProjectImporter::beginScriptFilesImport(%this) +{ + //First, we need to go through and process all loose image files. This will + //get us shape assets, and if the import config deigns, material assets. + %currentAddress = $ProjectImporter::modulePath; + + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + //%file = %rootFileSectionObject.fileDestination; + + //if(%rootFileSectionObject.imported == true) + // continue; + + %filename = %rootFileSectionObject.fileName; + %fileExt = %rootFileSectionObject.fileExt; + %fileBase = %rootFileSectionObject.fileBase; + %filePath = filePath(%file); + + if(%fileExt !$= ".cs" && + %fileExt !$= ".tscript" && + %fileExt !$= ".mis" && + %fileExt !$= ".gui" && + %fileExt !$= ".prefab") + { + continue; + } + + $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/"; + + projectImporterLog("T3Dpre4ProjectImporter::beginScriptFilesImport() - Processing script file: " @ %file); + %this.processScripts(%rootFileSectionObject); + } + + projectImporterLog("Legacy Project Importer - Processing of imported code files done!"); +} + +// +function T3Dpre4ProjectImporter::processModuleFile(%this, %moduleObj) +{ + if(!isObject(%moduleObj)) + return; + + %moduleObj.echo(); + + //really, we only care here about ensuring the file extensions are cleaned up + for(%l=0; %l < %moduleObj.count(); %l++) + { + %line = %moduleObj.getKey(%l); + if(strIsMatchExpr("*.cs\"", %line)) + { + %resultLine = strReplace(%line, ".cs\"", "\""); + %moduleObj.setKey(%resultLine, %l); + } + } +} + +function T3Dpre4ProjectImporter::processAssetFile(%this, %assetObj) +{ + if(!isObject(%assetObj)) + return; + + %assetObj.echo(); + + //really, we only care here about ensuring the file extensions are cleaned up + for(%l=0; %l < %assetObj.count(); %l++) + { + %line = %assetObj.getKey(%l); + if(strIsMatchExpr("*.cs\"", %line)) + { + %resultLine = strReplace(%line, ".cs\"", "\""); + %assetObj.setKey(%resultLine, %l); + } + } +} + +function T3Dpre4ProjectImporter::beginAssetAndModuleImport(%this) +{ + //First, we need to go through and process all loose image files. This will + //get us shape assets, and if the import config deigns, material assets. + %currentAddress = $ProjectImporter::modulePath; + + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + + %filename = %rootFileSectionObject.fileName; + %fileExt = %rootFileSectionObject.fileExt; + %fileBase = %rootFileSectionObject.fileBase; + %filePath = filePath(%file); + + if(%fileExt $= ".module") + { + projectImporterLog("T3Dpre4ProjectImporter::beginAssetAndModuleImport() - processing file: " @ %file); + $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/"; + %this.processModuleFile(%rootFileSectionObject); + %rootFileSectionObject.processed = true; + } + else if(%fileExt $= ".asset.taml") + { + projectImporterLog("T3Dpre4ProjectImporter::beginAssetAndModuleImport() - processing file: " @ %file); + $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/"; + %this.processAssetFile(%rootFileSectionObject); + %rootFileSectionObject.processed = true; + } + } + + projectImporterLog("Legacy Project Importer - Processing of imported asset and module files done!"); +} + +//To implement a custom class to have it's fields processed, just utilize this template function +//and replace the class/field spaces as appropriate +/* +function T3Dpre4ProjectImporter::processLine(%this, %line) +{ + %outLine = processLegacyField(%line, "", ""); + + if(%outLine !$= %line) + return %outLine; + else + return %line; +} +*/ +//============================================================================== +// Misc Object Classes +//============================================================================== +function T3Dpre4ProjectImporter::genProcessor(%classType, %conversionMap) +{ + %stryng = "function T3Dpre4ProjectImporter::process" @%classType@ "Line(%this, %line){\n"; + %count = getWordCount(%conversionMap); + for (%i = 0; %i<%count; %i+=2) + { + %stryng = %stryng @ " %outLine = processLegacyField(%line,\""@ getWord(%conversionMap,%i)@ "\",\""@ getWord(%conversionMap,%i+1)@"\");\n"; + %stryng = %stryng @ " if(%outLine !$= %line) return %outLine;\n"; + } + %stryng = %stryng @ " return %line;\n}"; + eval(%stryng); +} + +T3Dpre4ProjectImporter::genProcessor("TSShapeConstructor", "baseShape baseShapeAsset shapeName shapeAsset"); +T3Dpre4ProjectImporter::genProcessor("BasicClouds", "texture textureAsset"); +T3Dpre4ProjectImporter::genProcessor("CloudLayer", "texture textureAsset"); +T3Dpre4ProjectImporter::genProcessor("DecalRoad", "material materialAsset"); +T3Dpre4ProjectImporter::genProcessor("MeshRoad", "topMaterial topMaterialAsset bottomMaterial bottomMaterialAsset sideMaterial sideMaterialAsset"); +T3Dpre4ProjectImporter::genProcessor("ScatterSky", "moonMat moonMatAsset"); +T3Dpre4ProjectImporter::genProcessor("Sun", "coronaMaterial coronaMaterialAsset"); +T3Dpre4ProjectImporter::genProcessor("VolumetricFog", "shape ShapeAsset texture textureAsset"); +T3Dpre4ProjectImporter::genProcessor("WaterObject", "rippleTex rippleTexAsset foamTex foamTexAsset depthGradientTex depthGradientTexAsset"); +T3Dpre4ProjectImporter::genProcessor("ConvexShape", "material materialAsset"); +T3Dpre4ProjectImporter::genProcessor("RenderMesh", "material materialAsset"); +T3Dpre4ProjectImporter::genProcessor("RenderShape", "shape shapeAsset"); +T3Dpre4ProjectImporter::genProcessor("GroundCover", "material materialAsset shape shapeAsset shapeFilename shapeAsset"); +T3Dpre4ProjectImporter::genProcessor("GroundPlane", "material materialAsset"); +T3Dpre4ProjectImporter::genProcessor("LevelInfo", "accuTexture accuTextureAsset"); +T3Dpre4ProjectImporter::genProcessor("TSStatic", "shape shapeAsset shapeName shapeAsset"); +T3Dpre4ProjectImporter::genProcessor("TSForestItemData", "shape shapeAsset shapeName shapeAsset shapeFile shapeAsset"); +T3Dpre4ProjectImporter::genProcessor("TerrainBlock", "terrainFile terrainAsset"); +T3Dpre4ProjectImporter::genProcessor("afxMagicMissileData", "projectileShape projectileShapeAsset projectileShapeName projectileShapeAsset sound projectileSoundAsset"); +T3Dpre4ProjectImporter::genProcessor("afxBillboardData", "texture textureAsset"); +T3Dpre4ProjectImporter::genProcessor("afxModelData", "shapeName shapeAsset shapeFile shapeAsset"); +T3Dpre4ProjectImporter::genProcessor("afxZodiacData", "texture textureAsset"); +T3Dpre4ProjectImporter::genProcessor("afxZodiacPlaneData", "texture textureAsset"); +T3Dpre4ProjectImporter::genProcessor("sfxEmitter", "track soundAsset filename soundAsset"); +T3Dpre4ProjectImporter::genProcessor("LightningData", "thunderSounds ThunderSoundAsset strikeSound StrikeSoundAsset"); +//============================================================================== +// Levels +//============================================================================== +function T3Dpre4ProjectImporter::processMissionGroupLine(%this, %line, %missionName) +{ + %outline = strreplace(%line, "SimGroup(MissionGroup)", "Scene(" @ %missionName @ ")"); + + if(%outLine !$= %line) + return %outLine; + else + return %line; +} + +function T3Dpre4ProjectImporter::processLevelInfoLine(%this, %line) +{ + %outline = strreplace(%line, "ScriptObject(MissionInfo)", "LevelInfo(theLevelInfo)"); + + if(%outLine !$= %line) + return %outLine; + else + return %line; +} + +function T3Dpre4ProjectImporter::processSkyLine(%this, %line) +{ + %outline = strreplace(%line, "Sky", "Skybox"); + + if(%outLine !$= %line) + return %outLine; + else + return %line; +} + +function T3Dpre4ProjectImporter::processWaterLine(%this, %line) +{ + %outline = strreplace(%line, "Water", "WaterPlane"); + + if(%outLine !$= %line) + return %outLine; + else + return %line; +} + +//============================================================================== +// GUIs +//============================================================================== +T3Dpre4ProjectImporter::genProcessor("GuiIconButtonCtrl", "bitmap bitmapAsset iconBitmap bitmapAsset"); +T3Dpre4ProjectImporter::genProcessor("GuiToolboxButtonCtrl", "normalBitmap normalBitmapAsset loweredBitmap loweredBitmapAsset hoverBitmap hoverBitmapAsset"); +T3Dpre4ProjectImporter::genProcessor("GuiBitmapCtrl", "bitmap bitmapAsset"); +T3Dpre4ProjectImporter::genProcessor("GuiMaterialCtrl", "material materialAsset"); +T3Dpre4ProjectImporter::genProcessor("GuiCursor", "bitmap bitmapAsset"); +T3Dpre4ProjectImporter::genProcessor("GuiChunkedBitmapCtrl", "bitmap bitmapAsset"); +T3Dpre4ProjectImporter::genProcessor("GuiProgressBitmap", "bitmap bitmapAsset"); +T3Dpre4ProjectImporter::genProcessor("GuiMissionArea", "handleBitmap handleBitmapAsset"); +T3Dpre4ProjectImporter::genProcessor("WorldEditor", "selectHandle selectHandleAsset defaultHandle defaultHandleAsset lockedHandle lockedHandleAsset"); +T3Dpre4ProjectImporter::genProcessor("GuiControlProfile", "bitmap bitmapAsset"); +T3Dpre4ProjectImporter::genProcessor("GuiMLTextCtrl", "deniedSound deniedSoundAsset"); + +function T3Dpre4ProjectImporter::processGuiBitmapButtonCtrlLine(%this, %line) +{ + %outLine = processGuiBitmapButtonCtrlField(%line, "bitmap", "bitmapAsset"); + if(%outLine !$= %line) return %outLine; + + return %line; +} + +//============================================================================== +// Datablocks +//============================================================================== +T3Dpre4ProjectImporter::genProcessor("ForestItemData", "shape shapeAsset"); +T3Dpre4ProjectImporter::genProcessor("CubeMapData", "cubemapFace cubeMapFaceAsset cubemap cubemapAsset cubeFace cubeMapFaceAsset"); +T3Dpre4ProjectImporter::genProcessor("DebrisData", "shape shapeAsset shapeFile shapeAsset"); +T3Dpre4ProjectImporter::genProcessor("DecalData", "material materialAsset"); +T3Dpre4ProjectImporter::genProcessor("ExplosionData", "explosionShape explosionShapeAsset"); +T3Dpre4ProjectImporter::genProcessor("ParticleData", "texture textureAsset textureName textureAsset textureExt textureExtAsset textureExtName textureExtAsset"); +T3Dpre4ProjectImporter::genProcessor("PrecipitationData", "drop dropAsset dropTexture dropAsset splash splashAsset splashTexture splashAsset soundProfile soundAsset"); +T3Dpre4ProjectImporter::genProcessor("SplashData", "texture textureAsset soundProfile SoundAsset"); +T3Dpre4ProjectImporter::genProcessor("LightFlareData", "flareTexture flareTextureAsset"); +T3Dpre4ProjectImporter::genProcessor("PhysicsDebrisData", "shape shapeAsset shapeFile shapeAsset"); +T3Dpre4ProjectImporter::genProcessor("PhysicsShapeData", "shape shapeAsset shapeName shapeAsset"); +T3Dpre4ProjectImporter::genProcessor("ProjectileData", "projectileShape projectileShapeAsset projectileShapeName projectileShapeAsset sound projectileSoundAsset"); +T3Dpre4ProjectImporter::genProcessor("ShapeBaseData", "shapeFile shapeAsset shape shapeAsset debrisShape debrisShapeAsset debrisShapeName debrisShapeAsset"); +T3Dpre4ProjectImporter::genProcessor("ShapeBaseImageData", "shape shapeAsset[0] shapeFP shapeAsset[1] shapeFile shapeAsset[0] shapeFileFP shapeAsset[1] stateSound stateSoundAsset"); +T3Dpre4ProjectImporter::genProcessor("ProximityMineData","armingSound ArmSoundAsset TriggerSound TriggerSoundAsset"); +T3Dpre4ProjectImporter::genProcessor("WheeledVehicleTire", "shape shapeAsset shapeFile shapeAsset"); +T3Dpre4ProjectImporter::genProcessor("WheeledVehicleData", "engineSound engineSoundAsset squealSound squealSoundAsset"); +T3Dpre4ProjectImporter::genProcessor("FlyingVehicleData", "engineSound engineSoundAsset jetSound jetSoundAsset"); +T3Dpre4ProjectImporter::genProcessor("HoverVehicleData", "engineSound engineSoundAsset jetSound jetSoundAsset floatSound floatSoundAsset"); + +//============================================================================== +// Datablocks - Long Lists +//============================================================================== +// - RigidShapeData +$rigidEntriesList = "softImpactSound softImpactSoundAsset hardImpactSound hardImpactSoundAsset"; +$rigidEntriesList = $rigidEntriesList SPC "exitingWater exitingWaterAsset impactWaterEasy impactWaterEasyAsset"; +$rigidEntriesList = $rigidEntriesList SPC "impactWaterMedium impactWaterMediumAsset impactWaterHard impactWaterHardAsset"; +$rigidEntriesList = $rigidEntriesList SPC "waterWakeSound waterWakeSoundAsset"; +T3Dpre4ProjectImporter::genProcessor("RigidShapeData",$rigidEntriesList); +// - PlayerData +$PlayerEntriesList = "shapeFP shapeFPAsset shapeNameFP shapeFPAsset"; +$PlayerEntriesList = $PlayerEntriesList SPC "FootSoftSound FootSoftAsset FootHardSound FootHardAsset FootMetalSound FootMetalAsset"; +$PlayerEntriesList = $PlayerEntriesList SPC "FootSnowSound FootSnowAsset FootShallowSound FootShallowSplashAsset"; +$PlayerEntriesList = $PlayerEntriesList SPC "FootWadingSound FootWadingAsset FootUnderwaterSound FootUnderWaterAsset"; +$PlayerEntriesList = $PlayerEntriesList SPC "FootBubblesSound FootBubblesAsset movingBubblesSound MoveBubblesAsset"; +$PlayerEntriesList = $PlayerEntriesList SPC "waterBreathSound WaterBreathAsset"; +$PlayerEntriesList = $PlayerEntriesList SPC "impactSoftSound ImpactSoftAsset impactHardSound impactHardAsset"; +$PlayerEntriesList = $PlayerEntriesList SPC "impactMetalSound ImpactMetalAsset impactSnowSound impactSnowAsset"; +$PlayerEntriesList = $PlayerEntriesList SPC "impactWaterEasy impactWaterEasyAsset impactWaterMedium impactWaterMediumAsset impactWaterHard impactWaterHardAsset"; +$PlayerEntriesList = $PlayerEntriesList SPC "exitingWater ExitWaterAsset"; +T3Dpre4ProjectImporter::genProcessor("PlayerData", $PlayerEntriesList); +// - Material +$MaterialEntriesList = "baseTex diffuseMapAsset diffuseMap diffuseMapAsset"; +$MaterialEntriesList = $MaterialEntriesList SPC "lightMap lightMapAsset toneMap toneMapAsset"; +$MaterialEntriesList = $MaterialEntriesList SPC "detailTex detailMapAsset detailMap detailMapAsset detailNormalMap detailNormalMapAsset"; +$MaterialEntriesList = $MaterialEntriesList SPC "overlayTex overlayMapAsset overlayMap overlayMapAsset"; +$MaterialEntriesList = $MaterialEntriesList SPC "bumpTex normalMapAsset normalMap normalMapAsset"; +$MaterialEntriesList = $MaterialEntriesList SPC "ormConfigMap ormConfigMapAsset roughMap roughMapAsset"; +$MaterialEntriesList = $MaterialEntriesList SPC "aoMap aoMapAsset metalMap metalMapAsset"; +$MaterialEntriesList = $MaterialEntriesList SPC "glowMap glowMapAsset"; +$MaterialEntriesList = $MaterialEntriesList SPC "customFootstepSound customFootstepSoundAsset customImpactSound customImpactSoundAsset"; +T3Dpre4ProjectImporter::genProcessor("Material", $MaterialEntriesList); +//============================================================================== +// Materials +//============================================================================== +function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %objectName) +{ + %matAsset = MaterialAsset::getAssetIdByMaterialName(%objectName); + + if(%matAsset $= "" || %matAsset $= "Core_Rendering:NoMaterial") + { + %assetName = %objectName; + + %moduleName = AssetBrowser.dirHandler.getModuleFromAddress($ProjectImporter::modulePath).ModuleId; + + %assetPath = $ProjectImporter::currentFilePath @ "/"; + + %tamlpath = %assetPath @ %assetName @ ".asset.taml"; + %scriptPath = %assetPath @ %assetName @ "." @ $TorqueScriptFileExtension;//%fileObject.fileDestination; + + if(isFile(%tamlpath)) + { + projectImporterLog("T3Dpre4ProjectImporter::processMaterialObject() - Failed to create as taml file already exists: " @ %fileObject.fileName); + return false; + } + + %asset = new MaterialAsset() + { + AssetName = %assetName; + versionId = 1; + shaderData = ""; + materialDefinitionName = %assetName; + scriptFile = fileBase(%scriptPath); + }; + + //Now we make our scripted definition "real", and append it to our asset + //so it is serialized. + /*%objectDefinition = ""; + for(%l=0; %l < %fileObject.count(); %l++) + { + %objectLine = %fileObject.getKey(%l); + if(!isObject(%objectLine)) + { + %objectDefinition = %objectDefinition @ %objectLine; + } + } + + eval(%objectDefinition); + + if(isObject(%objectName)) + { + %asset.add(%objectName); + }*/ + + if(!isDirectory(%assetPath)) + { + DirectoryHandler::createFolder(0, %assetPath); + } + + %success = false; + if(TamlWrite(%asset, %tamlpath)) + { + //now write the script file + if ( $ProjectImporter::fileObject.openForWrite( %scriptPath ) ) + { + for(%i=0; %i < %fileObject.count(); %i++) + { + %objectLine = %fileObject.getKey(%i); + if(isObject(%objectLine)) + { + %defineLine = %fileObject.getKey(0); + $ProjectImporter::fileObject.writeLine(%defineLine); + } + else + { + $ProjectImporter::fileObject.writeLine(%objectLine); + } + } + + $ProjectImporter::fileObject.close(); + } + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + + %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + } + + if(!%success) + return false; + } + + return false; +} + +function T3Dpre4ProjectImporter::processTerrainMaterialLine(%this, %line) +{ + %outLine = processLegacyField(%line, "diffuseMap", "diffuseMapAsset"); + if(%outLine !$= %line) return %outLine; + %outLine = processLegacyField(%line, "normalMap", "normalMapAsset"); + if(%outLine !$= %line) return %outLine; + %outLine = processLegacyField(%line, "detailMap", "detailMapAsset"); + if(%outLine !$= %line) return %outLine; + %outLine = processLegacyField(%line, "ORMConfigMap", "ORMConfigMapAsset"); + if(%outLine !$= %line) return %outLine; + %outLine = processLegacyField(%line, "macroMap", "macroMapAsset"); + if(%outLine !$= %line) return %outLine; + return %line; +} + +function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject, %objectName) +{ + %matAsset = TerrainMaterialAsset::getAssetIdByMaterialName(%objectName); + + if(%matAsset $= "" || %matAsset $= "Core_Rendering:noMaterial") + { + %assetName = %objectName; + + %moduleName = AssetBrowser.dirHandler.getModuleFromAddress($ProjectImporter::modulePath).ModuleId; + + %assetPath = $ProjectImporter::currentFilePath @ "/"; + + %tamlpath = %assetPath @ %assetName @ ".asset.taml"; + %scriptPath = %assetPath @ %assetName @ "." @ $TorqueScriptFileExtension;//%fileObject.fileDestination; + + if(isFile(%tamlpath)) + { + projectImporterLog("T3Dpre4ProjectImporter::processTerrainMaterialObject() - Failed to create as taml file already exists: " @ %fileObject.fileName); + return false; + } + + %asset = new TerrainMaterialAsset() + { + AssetName = %assetName; + versionId = 1; + shaderData = ""; + materialDefinitionName = %objectName; + scriptFile = fileName(%scriptPath); + }; + + %success = false; + if(TamlWrite(%asset, %tamlpath)) + { + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + + %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + } + + if(!%success) + return false; + } + + return false; +} +//============================================================================== +// PostEffects +//============================================================================== +T3Dpre4ProjectImporter::genProcessor("PostEffect", "texture textureAsset"); + +//============================================================================== +// Sounds +// Sounds are a little weird because there's so much data tied up in a given sound +// source. So our approach is find old SFXProfiles and process those into sound assets +// by cross-referencing the filename for existing asset definitions. +// Using existing SFXProfiles allows us to also injest the descriptions, giving us +// our meta-properties on the sound asset itself. +//============================================================================== +T3Dpre4ProjectImporter::genProcessor("SFXAmbience", "soundTrack soundTrackAsset"); +T3Dpre4ProjectImporter::genProcessor("SFXPlayList", "track trackAsset"); + +function T3Dpre4ProjectImporter::processSFXProfileLine(%this, %line) +{ + return %line; +} + +function T3Dpre4ProjectImporter::processSFXProfileObject(%this, %file, %objectName) +{ + %soundFilename = findObjectField(%file, "filename"); + + %soundFilename = sanitizeFilename(%soundFilename); + + if(fileExt(%soundFilename) $= "") + { + %soundFilename = testFilenameExtensions(%soundFilename); + } + + %soundAsset = SoundAsset::getAssetIdByFilename(%soundFilename); + + //Throw a warn that this file's already been claimed and move on + if(%soundAsset !$= "") + { + projectImporterLog("T3Dpre4ProjectImporter::processSFXProfileObject() - attempting to process SFXProfile " @ %objectName + @ " but its filename is already associated to another sound asset. Continuing, but be aware."); + } + + %assetName = %objectName; + + %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%soundFilename).ModuleId; + + %assetPath = filePath(%soundFilename) @ "/"; + + %tamlpath = %assetPath @ %assetName @ ".asset.taml"; + + if(isFile(%tamlpath)) + { + projectImporterLog("T3Dpre4ProjectImporter::processSFXProfileObject() - Failed to create as taml file already exists: " @ %soundFilename); + return false; + } + + %asset = new SoundAsset() + { + AssetName = %assetName; + versionId = 1; + shaderData = ""; + soundFile = fileBase(%soundFilename) @ fileExt(%soundFilename); + }; + + %descriptionName = findObjectField(%file, "description"); + + if(%descriptionName !$= "") + { + //Optimization, see if we already have this description by happenstance + if(isObject(%descriptionName)) + { + %asset.sourceGroup = %descriptionName.sourceGroup; + %asset.volume = %descriptionName.volume; + %asset.pitch = %descriptionName.pitch; + %asset.isLooping = %descriptionName.isLooping; + %asset.priority = %descriptionName.priority; + %asset.useHardware = %descriptionName.useHardware; + %asset.is3D = %descriptionName.is3D; + %asset.minDistance = %descriptionName.minDistance; + %asset.maxDistance = %descriptionName.maxDistance; + %asset.scatterDistance = %descriptionName.scatterDistance; + %asset.coneInsideAngle = %descriptionName.coneInsideAngle; + %asset.coneOutsideAngle = %descriptionName.coneOutsideAngle; + %asset.coneOutsideVolume = %descriptionName.coneOutsideVolume; + %asset.rolloffFactor = %descriptionName.rolloffFactor; + %asset.isStreaming = %descriptionName.isStreaming; + } + else + { + %objFileFinder = ""; + //first check our cache + if(isObject($ProjectImporter::SFXDescriptionCache) && + $ProjectImporter::SFXDescriptionCache.getIndexFromKey(%descriptionName) !$= "") + { + %key = $ProjectImporter::SFXDescriptionCache.getIndexFromKey(%descriptionName); + %objFileFinder = $ProjectImporter::SFXDescriptionCache.getValue(%key); + } + else + { + %objFileFinder = findObjectInFiles(%descriptionName); + } + + if(%objFileFinder !$= "") + { + %valueArray = new ArrayObject(); + + %fileObj = getField(%objFileFinder, 0); + + %valueArray.add("sourceGroup" SPC findObjectField(%fileObj, "sourceGroup")); + %valueArray.add("volume" SPC findObjectField(%fileObj, "volume")); + %valueArray.add("pitch" SPC findObjectField(%fileObj, "pitch")); + %valueArray.add("isLooping" SPC findObjectField(%fileObj, "isLooping")); + %valueArray.add("priority" SPC findObjectField(%fileObj, "priority")); + %valueArray.add("useHardware" SPC findObjectField(%fileObj, "useHardware")); + %valueArray.add("is3D" SPC findObjectField(%fileObj, "is3D")); + %valueArray.add("minDistance" SPC findObjectField(%fileObj, "minDistance")); + %valueArray.add("maxDistance" SPC findObjectField(%fileObj, "maxDistance")); + %valueArray.add("scatterDistance" SPC findObjectField(%fileObj, "scatterDistance")); + %valueArray.add("coneInsideAngle" SPC findObjectField(%fileObj, "coneInsideAngle")); + %valueArray.add("coneOutsideAngle" SPC findObjectField(%fileObj, "coneOutsideAngle")); + %valueArray.add("coneOutsideVolume" SPC findObjectField(%fileObj, "coneOutsideVolume")); + %valueArray.add("rolloffFactor" SPC findObjectField(%fileObj, "rolloffFactor")); + %valueArray.add("isStreaming" SPC findObjectField(%fileObj, "isStreaming")); + + if(isObject($ProjectImporter::SFXDescriptionCache)) + { + $ProjectImporter::SFXDescriptionCache.add(%descriptionName, %objFileFinder); + } + + for(%v=0; %v < %valueArray.Count(); %v++) + { + %varSet = %valueArray.getKey(%v); + %var = getWord(%varSet, 0); + %varVal = getWord(%varSet, 1); + + if(%varVal !$= "") + %asset.setFieldValue(%var, %varVal); + } + + %valueArray.delete(); + } + } + } + + %success = false; + if(TamlWrite(%asset, %tamlpath)) + { + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + + %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + } + + if(!%success) + return false; + + %file.skip = true; + + return true; +} + +function T3Dpre4ProjectImporter::processAudioProfileObject(%this, %file, %objectName) +{ + return %this.processSFXProfileObject(%file, %objectName); +} + +function T3Dpre4ProjectImporter::processSFXDescriptionObject(%this, %file, %objectName) +{ + //$ProjectImporter::ToRemoveObjectList.add(%objectName, %file TAB 0); + + return true; +} + +function T3Dpre4ProjectImporter::processAudioDescriptionObject(%this, %file, %objectName) +{ + $ProjectImporter::ToRemoveObjectList.add(%objectName, %file TAB 0); + + return true; +} + +//============================================================================== +// Misc Utility functions +//============================================================================== +//This is functionally identical to processLegacyField, but we have to special-snowflake our asset lookups +//due to it using suffix-based indirections +function processGuiBitmapButtonCtrlField(%line, %originalFieldName, %newFieldName) +{ + if(!strIsMatchExpr("*"@%originalFieldName@"=*\"*\";*", %line) && + !strIsMatchExpr("*"@%originalFieldName@"[*=*\"*\";*", %line) && + !strIsMatchExpr("*"@%originalFieldName@" *=*\"*\";*", %line)) + return %line; + + %outLine = strreplace(%line, %originalFieldName, %newFieldName); + + //get the value + %value = ""; + %pos = strpos(%outLine, "= \""); + if(%pos != -1) + { + %endPos = strpos(%outLine, "\";", %pos); + + %value = getSubStr(%outLine, %pos+3, %endPos-%pos-3); + } + else + { + %pos = strpos(%outLine, "=\""); + if(%pos != -1) + { + %endPos = strpos(%outLine, "\";", %pos); + + %value = getSubStr(%outLine, %pos+2, %endPos-%pos-2); + } + } + + if(%outLine !$= %line && %pos != -1 && %endPos != -1 && %value !$= "") + { + projectImporterLog("Legacy Project Importer - processing legacy field line: " @ %line); + + if(startsWith(%value, "$") || startsWith(%value, "#")) + { + //These are going to be texture/render targets, and we can leave them alone + return %line; + } + + %targetFilename = sanitizeFilename(%value); + + //If we still have nothing, then we fail it out + if(!isFile(%targetFilename)) + { + projectImporterLog("Legacy Project Importer - file described in line could not be found/is not valid"); + return %line; + } + + $ProjectImporter::assetQuery.clear(); + %foundAssets = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %targetFilename); + if(%foundAssets != 0) + { + %assetId = $ProjectImporter::assetQuery.getAsset(0); + projectImporterLog("Legacy Project Importer - processing of legacy field line's value: " @ %value @ " has found a matching AssetId: " @ %assetId); + } + + if(%assetId !$= "" && AssetDatabase.isDeclaredAsset(%assetId)) + { + //if (%assetId.getStatusString() $= "Ok") + %outLine = strReplace(%outLine, %value, %assetId); + //else + // error("Asset assignment failure:", %assetId, getStatusString()); + } + } + + if(%outLine !$= %line) + { + projectImporterLog("Legacy Project Importer - processing of legacy line: " @ %line @ " has been updated to: " @ %outLine); + return %outLine; + } + else + { + return %line; + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.asset.taml b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.asset.taml new file mode 100644 index 000000000..32d091f0c --- /dev/null +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.asset.taml @@ -0,0 +1,7 @@ + diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.gui b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.gui new file mode 100644 index 000000000..6cbd3eb5c --- /dev/null +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.gui @@ -0,0 +1,129 @@ +//--- OBJECT WRITE BEGIN --- +new GuiContainer(Pre40ImporterPage0) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 1"; + extent = "539 429"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Next, we'll import in content files, such as image, models and sounds."; + useURLMouseCursor = "0"; + position = "111 21"; + extent = "328 28"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Processing..."; + useURLMouseCursor = "0"; + position = "152 141"; + extent = "245 14"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "processingText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; +}; + +new GuiContainer(Pre40ImporterPage1) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 1"; + extent = "539 429"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Now, we'll import in script-based files such as guis, levels and scripts."; + useURLMouseCursor = "0"; + position = "111 21"; + extent = "328 28"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiMLTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Processing..."; + useURLMouseCursor = "0"; + position = "152 141"; + extent = "245 14"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "processingText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript new file mode 100644 index 000000000..4ad259602 --- /dev/null +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript @@ -0,0 +1,92 @@ +function Pre40ImporterPage0::openPage(%this) +{ + ProjectImportWindow-->nextButton.setActive(false); + %this-->processingText.setText("Processing..."); + Canvas.repaint(); + + //copy binary files over + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + if(%rootFileSectionObject.binaryFile == true) + { + %filePath = filePath(%file); + %fileName = %rootFileSectionObject.fileName; + %fileBase = %rootFileSectionObject.fileBase; + %fileExt = %rootFileSectionObject.fileExt; + + //filter out some unneeded folders + %slashCount = getTokenCount(%filePath, "/"); + %topFolder = getToken(%filePath, "/", %slashCount-1); + if(%topFolder $= "") + %topFolder = getToken(%filePath, "/", %slashCount-2); + + if(%topFolder $= "creator" || %topFolder $= "tools" || %topFolder $= "web") + { + %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); + continue; + } + + %targetFilePath = strReplace(%file, $ProjectImporter::sourceContentFolder, $ProjectImporter::modulePath); + + %sanitizedFilename = sanitizeString(%fileBase); + if(startsWith(%sanitizedFilename, "_")) + { + %sanitizedFilename = substr(%sanitizedFilename, 1, -1); + } + if(%sanitizedFilename !$= %fileBase) + { + %targetFilePath = filePath(%targetFilePath) @ "/" @ %sanitizedFilename @ %fileExt; + } + + %targetFolder = filePath(%targetFilePath); + + if(!isDirectory(%targetFolder)) + { + DirectoryHandler::createFolder(0, %targetFolder); + } + + if(!pathCopy(%file, %targetFilePath, false)) + { + $ProjectImporter::log.add("Legacy Project Importer, failed to copy file: " @ %file @ " to destination: " @ %targetFilePath); + continue; + } + + %rootFileSectionObject.localPath = %targetFilePath; + + //If it was an asset definition file, go ahead and register it + if(%rootFileSectionObject.isAssetFile) + { + %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%targetFilePath).ModuleId; + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + + AssetDatabase.addDeclaredAsset(%moduleDef, %targetFilePath); + } + } + } + + //Now, we need to do some initial importing processing + T3Dpre4ProjectImporter.doContentImport(); + + //Once that's done, update the text of the UI + %this-->processingText.setText("Done!"); + ProjectImportWindow-->nextButton.setActive(true); + Canvas.repaint(); +} + +function Pre40ImporterPage1::openPage(%this) +{ + ProjectImportWindow-->nextButton.setActive(false); + %this-->processingText.setText("Processing..."); + Canvas.repaint(); + + //Now, we need to do some initial importing processing + T3Dpre4ProjectImporter.doScriptImport(); + + //Once that's done, update the text of the UI + %this-->processingText.setText("Done!"); + ProjectImportWindow-->nextButton.setActive(true); + Canvas.repaint(); +} + diff --git a/Templates/BaseGame/game/tools/projectImporter/main.tscript b/Templates/BaseGame/game/tools/projectImporter/main.tscript index da7fd3a3b..b7e871f1c 100644 --- a/Templates/BaseGame/game/tools/projectImporter/main.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/main.tscript @@ -24,11 +24,6 @@ function initializeProjectImporter() echo(" % - Initializing Project Importer"); exec("./scripts/projectImporter." @ $TorqueScriptFileExtension); - - //Versioned actions - exec("./scripts/pre40/T3Dpre4ProjectImporter." @ $TorqueScriptFileExtension); - - exec("./guis/projectImporter.gui"); new ScriptObject( ProjectImporterPlugin ) diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/pre40/T3Dpre4ProjectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/pre40/T3Dpre4ProjectImporter.tscript deleted file mode 100644 index 041cabbc9..000000000 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/pre40/T3Dpre4ProjectImporter.tscript +++ /dev/null @@ -1,1320 +0,0 @@ -function T3Dpre4ProjectImporter::setupModule(%this) -{ - %newModuleName = $ProjectImporter::moduleName; - - $ProjectImporter::log.add("Creating a new Module named: " @ %newModuleName); - - %moduleFilePath = "data/" @ %newModuleName; - %moduleDefinitionFilePath = %moduleFilePath @ "/" @ %newModuleName @ ".module"; - %moduleScriptFilePath = %moduleFilePath @ "/" @ %newModuleName @ "." @ $TorqueScriptFileExtension; - - %newModule = new ModuleDefinition() - { - ModuleId = %newModuleName; - versionId = 1; - ScriptFile = %newModuleName @ "." @ $TorqueScriptFileExtension; - CreateFunction="onCreate"; - DestroyFunction="onDestroy"; - Group = "Game"; - - new DeclaredAssets() - { - Extension = "asset.taml"; - Recurse = true; - }; - }; - - TAMLWrite(%newModule, %moduleDefinitionFilePath); - - //Now generate the script file for it - %file = new FileObject(); - %templateFile = new FileObject(); - - %moduleTemplateCodeFilePath = AssetBrowser.templateFilesPath @ "module.tscript.template"; - - if(%file.openForWrite(%moduleScriptFilePath) && %templateFile.openForRead(%moduleTemplateCodeFilePath)) - { - while( !%templateFile.isEOF() ) - { - %line = %templateFile.readline(); - %line = strreplace( %line, "@@", %newModuleName ); - - %file.writeline(%line); - //$ProjectImporter::log.add(%line); - } - - %file.close(); - %templateFile.close(); - } - else - { - %file.close(); - %templateFile.close(); - - $ProjectImporter::log.add("CreateNewModule - Something went wrong and we couldn't write the script file!"); - } - - //force a refresh of our modules list - ModuleDatabase.ignoreLoadedGroups(true); - ModuleDatabase.scanModules( "data", false ); - %success = ModuleDatabase.loadExplicit(%newModuleName, 1); - ModuleDatabase.ignoreLoadedGroups(false); - - //force a reload of the Module lists - AssetBrowser.refresh(); -} - -function T3Dpre4ProjectImporter::copyFiles(%this) -{ - %currentPage = ProjectImportWindow.getCurrentPage(); - - %currentPage-->fileCopyText.setText("Beginning copy of files to new module folder now. This may take a few minutes..."); - Canvas.repaint(); - - %file = findFirstFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*", true); - - while( %file !$= "" ) - { - %filePath = filePath(%file); - %fileName = fileName(%file); - %fileBase = fileBase(%file); - %fileExt = fileExt(%file); - - if(endsWith(%fileName, ".asset.taml")) - { - %fileBase = strreplace(%fileBase, ".asset", ""); - %fileExt = ".asset.taml"; - } - - if(%fileExt $= ".dll" || %fileExt $= ".log" || %fileExt $= ".exe" || %fileExt $= ".manifest"|| %fileExt $= ".h" || - %fileExt $= ".cpp" || %fileExt $= ".so" || %fileExt $= ".do" || %fileExt $= ".lib" ||%fileExt $= ".exp") - { - %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); - continue; - } - - //filter out some unneeded folders - %slashCount = getTokenCount(%filePath, "/"); - %topFolder = getToken(%filePath, "/", %slashCount-1); - if(%topFolder $= "") - %topFolder = getToken(%filePath, "/", %slashCount-2); - - if(%topFolder $= "creator" || %topFolder $= "tools" || %topFolder $= "web") - { - %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); - continue; - } - - %targetFilePath = strReplace(%file, $ProjectImporter::sourceContentFolder, $ProjectImporter::modulePath); - - %sanitizedFilename = sanitizeString(%fileBase); - if(startsWith(%sanitizedFilename, "_")) - { - %sanitizedFilename = substr(%sanitizedFilename, 1, -1); - } - if(%sanitizedFilename !$= %fileBase) - { - %targetFilePath = filePath(%targetFilePath) @ "/" @ %sanitizedFilename @ %fileExt; - } - - %targetFolder = filePath(%targetFilePath); - - if(!isDirectory(%targetFolder)) - { - DirectoryHandler::createFolder(0, %targetFolder); - } - - if(!pathCopy(%file, %targetFilePath, false)) - { - $ProjectImporter::log.add("Legacy Project Importer, failed to copy file: " @ %file @ " to destination: " @ %targetFilePath); - } - - %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); - } - - // - //Now that we've done that, we'll load and scan the module for asset defs - %file = findFirstFileMultiExpr( $ProjectImporter::modulePath @ "/*.asset.taml", true); - - while( %file !$= "" ) - { - %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%file).ModuleId; - %moduleDef = ModuleDatabase.findModule(%moduleName, 1); - - AssetDatabase.addDeclaredAsset(%moduleDef, %file); - - %file = findNextFileMultiExpr( $ProjectImporter::modulePath @ "/*.asset.taml" ); - } - // - - %currentPage-->fileCopyText.setValue("File copy done! Press Next to continue."); - - ProjectImportWindow-->nextButton.setActive(true); - Canvas.repaint(); -} - -function T3Dpre4ProjectImporter::processImportedFiles(%this) -{ - if($ProjectImporter::importMode $= "CoreAndTools") - { - $ProjectImporter::modulePath = "Core"; - %this.doImport(); - - $ProjectImporter::modulePath = "Tools"; - %this.doImport(); - } - else - { - %this.doImport(); - } - - %currentPage = ProjectImportWindow.getCurrentPage(); - - %currentPage-->processingText.setText("Processing of files done! Press Next to continue."); - ProjectImportWindow-->nextButton.setActive(true); - Canvas.repaint(); -} - -function T3Dpre4ProjectImporter::doImport(%this) -{ - //Store off the current default import config - %defaultConfig = EditorSettings.value("Assets/AssetImporDefaultConfig", ""); - EditorSettings.setValue("Assets/AssetImporDefaultConfig", "LegacyProjectImport"); - - //Update asset content - beginImageImport(); - - %this.beginMaterialFilesImport(); - - beginShapeImport(); - beginTerrainImport(); - beginLevelImport(); - beginGUIImport(); - - %this.beginCodeFilesImport(); - - EditorSettings.setValue("Assets/AssetImporDefaultConfig", %defaultConfig); -} - -function T3Dpre4ProjectImporter::beginMaterialFilesImport(%this) -{ - %currentPage = ProjectImportWindow.getCurrentPage(); - - //First, wipe out any files inside the folder first - %file = findFirstFileMultiExpr( $ProjectImporter::modulePath @ "/*/materials.*", true); - - %objectClassStack = new ArrayObject(); - %fileOutputLines = new ArrayObject(); - - $ProjectImporter::log.add("Legacy Project Importer - Beginning processing of imported code files"); - - //Walk through and process all code files to update references - while( %file !$= "" ) - { - %fileWasChanged = false; - - %filename = fileName(%file); - %fileBase = fileBase(%file); - %fileExt = fileExt(%file); - %filePath = filePath(%file); - - $ProjectImporter::currentFilePath = %filePath @ "/"; - - %currentPage-->processingText.setText("Processing material script file: " @ %file); - Canvas.repaint(); - - if ( $ProjectImporter::fileObject.openForRead( %file ) ) - { - $ProjectImporter::log.add("Legacy Project Importer - Beginning process of file: " @ %file); - %lineNum = 0; - while ( !$ProjectImporter::fileObject.isEOF() ) - { - %line = $ProjectImporter::fileObject.readLine(); - %trimmedLine = trim(%line); - - if(strIsMatchExpr("*new*(*)*", %line) && strpos(%line, "::") == -1) - { - %className = findObjectClass(%line, "new"); - if (%className $= "") continue; - - if(%className !$= "Material" && %className !$= "CustomMaterial" && %className !$= "TerrainMaterial" && %className !$= "CubemapData") - { - %lineNum++; - %fileOutputLines.push_back(%line); - continue; - } - - %objectClassStack.push_back(%className); - - %objectName = findObjectName(%line, "new"); - - if(%objectName $= "" && %className $= "TerrainMaterial") - { - %intName = findObjectField("internalName"); - %objectName = %intName @ "_terrainMat"; - %line = strReplace(%line, "()", "(" @ %intName @ ")"); - - %fileWasChanged = true; - } - else if(%objectName $= "" && %className $= "Material") - { - %mapToName = findObjectField("mapTo"); - %objectName = %mapToName @ "_mat"; - %line = strReplace(%line, "()", "(" @ %mapToName @ ")"); - - %fileWasChanged = true; - } - - %sanitizedName = sanitizeString(%objectName); - if(startsWith(%sanitizedName, "_")) - { - %sanitizedName = substr(%sanitizedName, 1, -1); - } - if(%sanitizedName !$= %objectName) - { - %line = strReplace(%line, %objectName, %sanitizedName); - - %fileWasChanged = true; - } - - if(%objectClassStack.count() == 1) - { - %currentObjClass = %objectClassStack.getKey(%objectClassStack.count()-1); - - //we only process top-level objects directly - %inheritanceList = getClassHierarchy(%currentObjClass); - for (%classDepth =0; %classDepthprocessingText.setText("Processing file: " @ %file); - Canvas.repaint(); - - if ( $ProjectImporter::fileObject.openForRead( %file ) ) - { - $ProjectImporter::log.add("Legacy Project Importer - Beginning process of file: " @ %file); - %lineNum = 0; - while ( !$ProjectImporter::fileObject.isEOF() ) - { - %line = $ProjectImporter::fileObject.readLine(); - %trimmedLine = trim(%line); - - if(strIsMatchExpr("*new*(*)*", %line) && strpos(%line, "::") == -1) - { - %className = findObjectClass(%line, "new"); - if (%className $= "") continue; - - %objectClassStack.push_back(%className); - - %objectName = findObjectName(%line, "new"); - - if(strIsMatchExpr("*%guiContent*=*new*", %line)) - { - %line = strReplace(%line, "%guiContent", "$guiContent"); - %fileWasChanged = true; - } - - if(%objectName !$= "") - { - %sanitizedName = sanitizeString(%objectName); - if(startsWith(%sanitizedName, "_")) - { - %sanitizedName = substr(%sanitizedName, 1, -1); - } - if(%sanitizedName !$= %objectName) - { - %line = strReplace(%line, %objectName, %sanitizedName); - - %fileWasChanged = true; - } - - if(%objectClassStack.count() == 1) - { - %currentObjClass = %objectClassStack.getKey(%objectClassStack.count()-1); - - //we only process top-level objects directly - %inheritanceList = getClassHierarchy(%currentObjClass); - for (%classDepth =0; %classDepthprocessingText.setText("Processing material script file: " @ %file); - Canvas.repaint(); - - %targetFilePath = %filePath @ "/" @ %fileBase @ "." @ $TorqueScriptFileExtension; - if(!pathCopy(%file, %targetFilePath)) - { - $ProjectImporter::log.add("T3Dpre4ProjectImporter::processScriptExtensions() - Failed to create renamed script file for file: " @ %file); - } - else - { - if(!fileDelete(%file)) - { - $ProjectImporter::log.add("T3Dpre4ProjectImporter::processScriptExtensions() - Failed to remove old script file for rename: " @ %file); - } - } - - if($TorqueScriptFileExtension $= "tscript") - %file = findNextFileMultiExpr( $ProjectImporter::modulePath @ "/*/*.cs"); - else - %file = findNextFileMultiExpr( $ProjectImporter::modulePath @ "/*/*.tscript"); - } - - %currentPage = ProjectImportWindow.getCurrentPage(); - - %currentPage-->processingText.setText("Processing of script files done! Press Next to continue."); - ProjectImportWindow-->nextButton.setActive(true); - Canvas.repaint(); - - $ProjectImporter::log.add("Legacy Project Importer - Beginning processing of script files extensions complete"); -} - -//To implement a custom class to have it's fields processed, just utilize this template function -//and replace the class/field spaces as appropriate -/* -function T3Dpre4ProjectImporter::processLine(%this, %line) -{ - %outLine = processLegacyField(%line, "", ""); - - if(%outLine !$= %line) - return %outLine; - else - return %line; -} -*/ -//============================================================================== -// Misc Object Classes -//============================================================================== -function T3Dpre4ProjectImporter::genProcessor(%classType, %conversionMap) -{ - %stryng = "function T3Dpre4ProjectImporter::process" @%classType@ "Line(%this, %line){\n"; - %count = getWordCount(%conversionMap); - for (%i = 0; %i<%count; %i+=2) - { - %stryng = %stryng @ " %outLine = processLegacyField(%line,\""@ getWord(%conversionMap,%i)@ "\",\""@ getWord(%conversionMap,%i+1)@"\");\n"; - %stryng = %stryng @ " if(%outLine !$= %line) return %outLine;\n"; - } - %stryng = %stryng @ " return %line;\n}"; - eval(%stryng); -} - -T3Dpre4ProjectImporter::genProcessor("TSShapeConstructor", "baseShape baseShapeAsset shapeName shapeAsset"); -T3Dpre4ProjectImporter::genProcessor("BasicClouds", "texture textureAsset"); -T3Dpre4ProjectImporter::genProcessor("CloudLayer", "texture textureAsset"); -T3Dpre4ProjectImporter::genProcessor("DecalRoad", "material materialAsset"); -T3Dpre4ProjectImporter::genProcessor("MeshRoad", "topMaterial topMaterialAsset bottomMaterial bottomMaterialAsset sideMaterial sideMaterialAsset"); -T3Dpre4ProjectImporter::genProcessor("ScatterSky", "moonMat moonMatAsset"); -T3Dpre4ProjectImporter::genProcessor("Sun", "coronaMaterial coronaMaterialAsset"); -T3Dpre4ProjectImporter::genProcessor("VolumetricFog", "shape ShapeAsset texture textureAsset"); -T3Dpre4ProjectImporter::genProcessor("WaterObject", "rippleTex rippleTexAsset foamTex foamTexAsset depthGradientTex depthGradientTexAsset"); -T3Dpre4ProjectImporter::genProcessor("ConvexShape", "material materialAsset"); -T3Dpre4ProjectImporter::genProcessor("RenderMesh", "material materialAsset"); -T3Dpre4ProjectImporter::genProcessor("RenderShape", "shape shapeAsset"); -T3Dpre4ProjectImporter::genProcessor("GroundCover", "material materialAsset shape shapeAsset shapeFilename shapeAsset"); -T3Dpre4ProjectImporter::genProcessor("GroundPlane", "material materialAsset"); -T3Dpre4ProjectImporter::genProcessor("LevelInfo", "accuTexture accuTextureAsset"); -T3Dpre4ProjectImporter::genProcessor("TSStatic", "shape shapeAsset shapeName shapeAsset"); -T3Dpre4ProjectImporter::genProcessor("TSForestItemData", "shape shapeAsset shapeName shapeAsset shapeFile shapeAsset"); -T3Dpre4ProjectImporter::genProcessor("TerrainBlock", "terrainFile terrainAsset"); -T3Dpre4ProjectImporter::genProcessor("afxMagicMissileData", "projectileShape projectileShapeAsset projectileShapeName projectileShapeAsset sound projectileSoundAsset"); -T3Dpre4ProjectImporter::genProcessor("afxBillboardData", "texture textureAsset"); -T3Dpre4ProjectImporter::genProcessor("afxModelData", "shapeName shapeAsset shapeFile shapeAsset"); -T3Dpre4ProjectImporter::genProcessor("afxZodiacData", "texture textureAsset"); -T3Dpre4ProjectImporter::genProcessor("afxZodiacPlaneData", "texture textureAsset"); -T3Dpre4ProjectImporter::genProcessor("sfxEmitter", "track soundAsset filename soundAsset"); -T3Dpre4ProjectImporter::genProcessor("LightningData", "thunderSounds ThunderSoundAsset strikeSound StrikeSoundAsset"); -//============================================================================== -// Levels -//============================================================================== -function T3Dpre4ProjectImporter::processMissionGroupLine(%this, %line, %missionName) -{ - %outline = strreplace(%line, "SimGroup(MissionGroup)", "Scene(" @ %missionName @ ")"); - - if(%outLine !$= %line) - return %outLine; - else - return %line; -} - -function T3Dpre4ProjectImporter::processLevelInfoLine(%this, %line) -{ - %outline = strreplace(%line, "ScriptObject(MissionInfo)", "LevelInfo(theLevelInfo)"); - - if(%outLine !$= %line) - return %outLine; - else - return %line; -} - -function T3Dpre4ProjectImporter::processSkyLine(%this, %line) -{ - %outline = strreplace(%line, "Sky", "Skybox"); - - if(%outLine !$= %line) - return %outLine; - else - return %line; -} - -function T3Dpre4ProjectImporter::processWaterLine(%this, %line) -{ - %outline = strreplace(%line, "Water", "WaterPlane"); - - if(%outLine !$= %line) - return %outLine; - else - return %line; -} - -//============================================================================== -// GUIs -//============================================================================== -T3Dpre4ProjectImporter::genProcessor("GuiIconButtonCtrl", "bitmap bitmapAsset iconBitmap bitmapAsset"); -T3Dpre4ProjectImporter::genProcessor("GuiToolboxButtonCtrl", "normalBitmap normalBitmapAsset loweredBitmap loweredBitmapAsset hoverBitmap hoverBitmapAsset"); -T3Dpre4ProjectImporter::genProcessor("GuiBitmapCtrl", "bitmap bitmapAsset"); -T3Dpre4ProjectImporter::genProcessor("GuiMaterialCtrl", "material materialAsset"); -T3Dpre4ProjectImporter::genProcessor("GuiCursor", "bitmap bitmapAsset"); -T3Dpre4ProjectImporter::genProcessor("GuiChunkedBitmapCtrl", "bitmap bitmapAsset"); -T3Dpre4ProjectImporter::genProcessor("GuiProgressBitmap", "bitmap bitmapAsset"); -T3Dpre4ProjectImporter::genProcessor("GuiMissionArea", "handleBitmap handleBitmapAsset"); -T3Dpre4ProjectImporter::genProcessor("WorldEditor", "selectHandle selectHandleAsset defaultHandle defaultHandleAsset lockedHandle lockedHandleAsset"); -T3Dpre4ProjectImporter::genProcessor("GuiControlProfile", "bitmap bitmapAsset"); -T3Dpre4ProjectImporter::genProcessor("GuiMLTextCtrl", "deniedSound deniedSoundAsset"); - -function T3Dpre4ProjectImporter::processGuiBitmapButtonCtrlLine(%this, %line) -{ - %outLine = processGuiBitmapButtonCtrlField(%line, "bitmap", "bitmapAsset"); - if(%outLine !$= %line) return %outLine; - - return %line; -} - -//============================================================================== -// Datablocks -//============================================================================== -T3Dpre4ProjectImporter::genProcessor("ForestItemData", "shape shapeAsset"); -T3Dpre4ProjectImporter::genProcessor("CubeMapData", "cubemapFace cubeMapFaceAsset cubemap cubemapAsset cubeFace cubeMapFaceAsset"); -T3Dpre4ProjectImporter::genProcessor("DebrisData", "shape shapeAsset shapeFile shapeAsset"); -T3Dpre4ProjectImporter::genProcessor("DecalData", "material materialAsset"); -T3Dpre4ProjectImporter::genProcessor("ExplosionData", "explosionShape explosionShapeAsset"); -T3Dpre4ProjectImporter::genProcessor("ParticleData", "texture textureAsset textureName textureAsset textureExt textureExtAsset textureExtName textureExtAsset"); -T3Dpre4ProjectImporter::genProcessor("PrecipitationData", "drop dropAsset dropTexture dropAsset splash splashAsset splashTexture splashAsset soundProfile soundAsset"); -T3Dpre4ProjectImporter::genProcessor("SplashData", "texture textureAsset soundProfile SoundAsset"); -T3Dpre4ProjectImporter::genProcessor("LightFlareData", "flareTexture flareTextureAsset"); -T3Dpre4ProjectImporter::genProcessor("PhysicsDebrisData", "shape shapeAsset shapeFile shapeAsset"); -T3Dpre4ProjectImporter::genProcessor("PhysicsShapeData", "shape shapeAsset shapeName shapeAsset"); -T3Dpre4ProjectImporter::genProcessor("ProjectileData", "projectileShape projectileShapeAsset projectileShapeName projectileShapeAsset sound projectileSoundAsset"); -T3Dpre4ProjectImporter::genProcessor("ShapeBaseData", "shapeFile shapeAsset shape shapeAsset debrisShape debrisShapeAsset debrisShapeName debrisShapeAsset"); -T3Dpre4ProjectImporter::genProcessor("ShapeBaseImageData", "shape shapeAsset[0] shapeFP shapeAsset[1] shapeFile shapeAsset[0] shapeFileFP shapeAsset[1] stateSound stateSoundAsset"); -T3Dpre4ProjectImporter::genProcessor("ProximityMineData","armingSound ArmSoundAsset TriggerSound TriggerSoundAsset"); -T3Dpre4ProjectImporter::genProcessor("WheeledVehicleTire", "shape shapeAsset shapeFile shapeAsset"); -T3Dpre4ProjectImporter::genProcessor("WheeledVehicleData", "engineSound engineSoundAsset squealSound squealSoundAsset"); -T3Dpre4ProjectImporter::genProcessor("FlyingVehicleData", "engineSound engineSoundAsset jetSound jetSoundAsset"); -T3Dpre4ProjectImporter::genProcessor("HoverVehicleData", "engineSound engineSoundAsset jetSound jetSoundAsset floatSound floatSoundAsset"); - -//============================================================================== -// Datablocks - Long Lists -//============================================================================== -// - RigidShapeData -$rigidEntriesList = "softImpactSound softImpactSoundAsset hardImpactSound hardImpactSoundAsset"; -$rigidEntriesList = $rigidEntriesList SPC "exitingWater exitingWaterAsset impactWaterEasy impactWaterEasyAsset"; -$rigidEntriesList = $rigidEntriesList SPC "impactWaterMedium impactWaterMediumAsset impactWaterHard impactWaterHardAsset"; -$rigidEntriesList = $rigidEntriesList SPC "waterWakeSound waterWakeSoundAsset"; -T3Dpre4ProjectImporter::genProcessor("RigidShapeData",$rigidEntriesList); -// - PlayerData -$PlayerEntriesList = "shapeFP shapeFPAsset shapeNameFP shapeFPAsset"; -$PlayerEntriesList = $PlayerEntriesList SPC "FootSoftSound FootSoftAsset FootHardSound FootHardAsset FootMetalSound FootMetalAsset"; -$PlayerEntriesList = $PlayerEntriesList SPC "FootSnowSound FootSnowAsset FootShallowSound FootShallowSplashAsset"; -$PlayerEntriesList = $PlayerEntriesList SPC "FootWadingSound FootWadingAsset FootUnderwaterSound FootUnderWaterAsset"; -$PlayerEntriesList = $PlayerEntriesList SPC "FootBubblesSound FootBubblesAsset movingBubblesSound MoveBubblesAsset"; -$PlayerEntriesList = $PlayerEntriesList SPC "waterBreathSound WaterBreathAsset"; -$PlayerEntriesList = $PlayerEntriesList SPC "impactSoftSound ImpactSoftAsset impactHardSound impactHardAsset"; -$PlayerEntriesList = $PlayerEntriesList SPC "impactMetalSound ImpactMetalAsset impactSnowSound impactSnowAsset"; -$PlayerEntriesList = $PlayerEntriesList SPC "impactWaterEasy impactWaterEasyAsset impactWaterMedium impactWaterMediumAsset impactWaterHard impactWaterHardAsset"; -$PlayerEntriesList = $PlayerEntriesList SPC "exitingWater ExitWaterAsset"; -T3Dpre4ProjectImporter::genProcessor("PlayerData", $PlayerEntriesList); -// - Material -$MaterialEntriesList = "baseTex diffuseMapAsset diffuseMap diffuseMapAsset"; -$MaterialEntriesList = $MaterialEntriesList SPC "lightMap lightMapAsset toneMap toneMapAsset"; -$MaterialEntriesList = $MaterialEntriesList SPC "detailTex detailMapAsset detailMap detailMapAsset detailNormalMap detailNormalMapAsset"; -$MaterialEntriesList = $MaterialEntriesList SPC "overlayTex overlayMapAsset overlayMap overlayMapAsset"; -$MaterialEntriesList = $MaterialEntriesList SPC "bumpTex normalMapAsset normalMap normalMapAsset"; -$MaterialEntriesList = $MaterialEntriesList SPC "ormConfigMap ormConfigMapAsset roughMap roughMapAsset"; -$MaterialEntriesList = $MaterialEntriesList SPC "aoMap aoMapAsset metalMap metalMapAsset"; -$MaterialEntriesList = $MaterialEntriesList SPC "glowMap glowMapAsset"; -$MaterialEntriesList = $MaterialEntriesList SPC "customFootstepSound customFootstepSoundAsset customImpactSound customImpactSoundAsset"; -T3Dpre4ProjectImporter::genProcessor("Material", $MaterialEntriesList); -//============================================================================== -// Materials -//============================================================================== -function T3Dpre4ProjectImporter::processMaterialObject(%this, %file, %objectName) -{ - %matAsset = MaterialAsset::getAssetIdByMaterialName(%objectName); - - if(%matAsset $= "" || %matAsset $= "Core_Rendering:NoMaterial") - { - %assetName = %objectName; - - %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%file).ModuleId; - - %assetPath = filePath(%file) @ "/"; - - %tamlpath = %assetPath @ %assetName @ ".asset.taml"; - - if(isFile(%tamlpath)) - { - $ProjectImporter::log.add("T3Dpre4ProjectImporter::processMaterialObject() - Failed to create as taml file already exists: " @ %file); - return false; - } - - %asset = new MaterialAsset() - { - AssetName = %assetName; - versionId = 1; - shaderData = ""; - materialDefinitionName = %assetName; - scriptFile = fileBase(%file); - }; - - TamlWrite(%asset, %tamlpath); - - %moduleDef = ModuleDatabase.findModule(%moduleName, 1); - %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); - - if(!%success) - return false; - } - - return false; -} - -function T3Dpre4ProjectImporter::processTerrainMaterialLine(%this, %line) -{ - %outLine = processLegacyField(%line, "diffuseMap", "diffuseMapAsset"); - if(%outLine !$= %line) return %outLine; - %outLine = processLegacyField(%line, "normalMap", "normalMapAsset"); - if(%outLine !$= %line) return %outLine; - %outLine = processLegacyField(%line, "detailMap", "detailMapAsset"); - if(%outLine !$= %line) return %outLine; - %outLine = processLegacyField(%line, "ORMConfigMap", "ORMConfigMapAsset"); - if(%outLine !$= %line) return %outLine; - %outLine = processLegacyField(%line, "macroMap", "macroMapAsset"); - if(%outLine !$= %line) return %outLine; - return %line; -} - -function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %file, %objectName) -{ - %matAsset = TerrainMaterialAsset::getAssetIdByMaterialName(%objectName); - - if(%matAsset $= "" || %matAsset $= "Core_Rendering:noMaterial") - { - %assetName = %objectName; - - %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%file).ModuleId; - - %assetPath = filePath(%file) @ "/"; - - %tamlpath = %assetPath @ %assetName @ ".asset.taml"; - - if(isFile(%tamlpath)) - { - $ProjectImporter::log.add("T3Dpre4ProjectImporter::processTerrainMaterialObject() - Failed to create as taml file already exists: " @ %file); - return false; - } - - %asset = new TerrainMaterialAsset() - { - AssetName = %assetName; - versionId = 1; - shaderData = ""; - materialDefinitionName = %objectName; - scriptFile = fileName(%file); - }; - - TamlWrite(%asset, %tamlpath); - - %moduleDef = ModuleDatabase.findModule(%moduleName, 1); - %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); - - if(!%success) - return false; - } - - return false; -} -//============================================================================== -// PostEffects -//============================================================================== -T3Dpre4ProjectImporter::genProcessor("PostEffect", "texture textureAsset"); - -//============================================================================== -// Sounds -// Sounds are a little weird because there's so much data tied up in a given sound -// source. So our approach is find old SFXProfiles and process those into sound assets -// by cross-referencing the filename for existing asset definitions. -// Using existing SFXProfiles allows us to also injest the descriptions, giving us -// our meta-properties on the sound asset itself. -//============================================================================== -T3Dpre4ProjectImporter::genProcessor("SFXAmbience", "soundTrack soundTrackAsset"); -T3Dpre4ProjectImporter::genProcessor("SFXPlayList", "track trackAsset"); - -function T3Dpre4ProjectImporter::processSFXProfileLine(%this, %line) -{ - return %line; -} - -function T3Dpre4ProjectImporter::processSFXProfileObject(%this, %file, %objectName) -{ - %soundFilename = findObjectField("filename"); - - %soundFilename = sanitizeFilename(%soundFilename); - - %soundAsset = SoundAsset::getAssetIdByFilename(%soundFilename); - - //Throw a warn that this file's already been claimed and move on - if(%soundAsset !$= "") - { - $ProjectImporter::log.add("T3Dpre4ProjectImporter::processSFXProfileObject() - attempting to process SFXProfile " @ %objectName - @ " but its filename is already associated to another sound asset. Continuing, but be aware."); - } - - %assetName = %objectName; - - %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%soundFilename).ModuleId; - - %assetPath = filePath(%soundFilename) @ "/"; - - %tamlpath = %assetPath @ %assetName @ ".asset.taml"; - - if(isFile(%tamlpath)) - { - $ProjectImporter::log.add("T3Dpre4ProjectImporter::processSFXProfileObject() - Failed to create as taml file already exists: " @ %soundFilename); - return false; - } - - %asset = new SoundAsset() - { - AssetName = %assetName; - versionId = 1; - shaderData = ""; - soundFile = fileBase(%soundFilename) @ fileExt(%soundFilename); - }; - - %descriptionName = findObjectField("description"); - - if(%descriptionName !$= "") - { - //Optimization, see if we already have this description by happenstance - if(isObject(%descriptionName)) - { - %asset.sourceGroup = %descriptionName.sourceGroup; - %asset.volume = %descriptionName.volume; - %asset.pitch = %descriptionName.pitch; - %asset.isLooping = %descriptionName.isLooping; - %asset.priority = %descriptionName.priority; - %asset.useHardware = %descriptionName.useHardware; - %asset.is3D = %descriptionName.is3D; - %asset.minDistance = %descriptionName.minDistance; - %asset.maxDistance = %descriptionName.maxDistance; - %asset.scatterDistance = %descriptionName.scatterDistance; - %asset.coneInsideAngle = %descriptionName.coneInsideAngle; - %asset.coneOutsideAngle = %descriptionName.coneOutsideAngle; - %asset.coneOutsideVolume = %descriptionName.coneOutsideVolume; - %asset.rolloffFactor = %descriptionName.rolloffFactor; - %asset.isStreaming = %descriptionName.isStreaming; - } - else - { - %objFileFinder = ""; - //first check our cache - if(isObject($ProjectImporter::SFXDescriptionCache) && - $ProjectImporter::SFXDescriptionCache.getIndexFromKey(%descriptionName) !$= "") - { - %key = $ProjectImporter::SFXDescriptionCache.getIndexFromKey(%descriptionName); - %objFileFinder = $ProjectImporter::SFXDescriptionCache.getValue(%key); - } - else - { - %objFileFinder = findObjectInFiles(%descriptionName); - } - - if(%objFileFinder !$= "") - { - %valueArray = new ArrayObject(); - - %fileObj = getField(%objFileFinder, 0); - - %valueArray.add("sourceGroup" SPC findObjectField("sourceGroup", %fileObj)); - %valueArray.add("volume" SPC findObjectField("volume", %fileObj)); - %valueArray.add("pitch" SPC findObjectField("pitch", %fileObj)); - %valueArray.add("isLooping" SPC findObjectField("isLooping", %fileObj)); - %valueArray.add("priority" SPC findObjectField("priority", %fileObj)); - %valueArray.add("useHardware" SPC findObjectField("useHardware", %fileObj)); - %valueArray.add("is3D" SPC findObjectField("is3D", %fileObj)); - %valueArray.add("minDistance" SPC findObjectField("minDistance", %fileObj)); - %valueArray.add("maxDistance" SPC findObjectField("maxDistance", %fileObj)); - %valueArray.add("scatterDistance" SPC findObjectField("scatterDistance", %fileObj)); - %valueArray.add("coneInsideAngle" SPC findObjectField("coneInsideAngle", %fileObj)); - %valueArray.add("coneOutsideAngle" SPC findObjectField("coneOutsideAngle", %fileObj)); - %valueArray.add("coneOutsideVolume" SPC findObjectField("coneOutsideVolume", %fileObj)); - %valueArray.add("rolloffFactor" SPC findObjectField("rolloffFactor", %fileObj)); - %valueArray.add("isStreaming" SPC findObjectField("isStreaming", %fileObj)); - - if(isObject($ProjectImporter::SFXDescriptionCache)) - { - $ProjectImporter::SFXDescriptionCache.add(%descriptionName, %objFileFinder); - } - - for(%v=0; %v < %valueArray.Count(); %v++) - { - %varSet = %valueArray.getKey(%v); - %var = getWord(%varSet, 0); - %varVal = getWord(%varSet, 1); - - if(%varVal !$= "") - %asset.setFieldValue(%var, %varVal); - } - - %valueArray.delete(); - } - } - } - - TamlWrite(%asset, %tamlpath); - - %moduleDef = ModuleDatabase.findModule(%moduleName, 1); - %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); - - if(!%success) - return false; - - //Now mark the original SFXProfile for removal from the file as it's redundant - //now that we have the asset def - $ProjectImporter::ToRemoveObjectList.add(%objectName, %file TAB 0); - - return true; -} - -function T3Dpre4ProjectImporter::processAudioProfileObject(%this, %file, %objectName) - { - return %this.processSFXProfileObject(%file, %objectName); - } - -function T3Dpre4ProjectImporter::processSFXDescriptionObject(%this, %file, %objectName) - { - $ProjectImporter::ToRemoveObjectList.add(%objectName, %file TAB 0); - - return true; -} - -function T3Dpre4ProjectImporter::processAudioDescriptionObject(%this, %file, %objectName) -{ - $ProjectImporter::ToRemoveObjectList.add(%objectName, %file TAB 0); - - return true; -} - -//============================================================================== -// Misc Utility functions -//============================================================================== -//This is functionally identical to processLegacyField, but we have to special-snowflake our asset lookups -//due to it using suffix-based indirections -function processGuiBitmapButtonCtrlField(%line, %originalFieldName, %newFieldName) -{ - if(!strIsMatchExpr("*"@%originalFieldName@"=*\"*\";*", %line) && - !strIsMatchExpr("*"@%originalFieldName@"[*=*\"*\";*", %line) && - !strIsMatchExpr("*"@%originalFieldName@" *=*\"*\";*", %line)) - return %line; - - %outLine = strreplace(%line, %originalFieldName, %newFieldName); - - //get the value - %value = ""; - %pos = strpos(%outLine, "= \""); - if(%pos != -1) - { - %endPos = strpos(%outLine, "\";", %pos); - - %value = getSubStr(%outLine, %pos+3, %endPos-%pos-3); - } - else - { - %pos = strpos(%outLine, "=\""); - if(%pos != -1) - { - %endPos = strpos(%outLine, "\";", %pos); - - %value = getSubStr(%outLine, %pos+2, %endPos-%pos-2); - } - } - - if(%outLine !$= %line && %pos != -1 && %endPos != -1 && %value !$= "") - { - $ProjectImporter::log.add("Legacy Project Importer - processing legacy field line: " @ %line); - - if(startsWith(%value, "$") || startsWith(%value, "#")) - { - //These are going to be texture/render targets, and we can leave them alone - return %line; - } - - %targetFilename = sanitizeFilename(%value); - - //If we still have nothing, then we fail it out - if(!isFile(%targetFilename)) - { - $ProjectImporter::log.add("Legacy Project Importer - file described in line could not be found/is not valid"); - return %line; - } - - $ProjectImporter::assetQuery.clear(); - %foundAssets = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %targetFilename); - if(%foundAssets != 0) - { - %assetId = $ProjectImporter::assetQuery.getAsset(0); - $ProjectImporter::log.add("Legacy Project Importer - processing of legacy field line's value: " @ %value @ " has found a matching AssetId: " @ %assetId); - } - - if(%assetId !$= "" && AssetDatabase.isDeclaredAsset(%assetId)) - { - //if (%assetId.getStatusString() $= "Ok") - %outLine = strReplace(%outLine, %value, %assetId); - //else - // error("Asset assignment failure:", %assetId, getStatusString()); - } - } - - if(%outLine !$= %line) - { - $ProjectImporter::log.add("Legacy Project Importer - processing of legacy line: " @ %line @ " has been updated to: " @ %outLine); - return %outLine; - } - else - { - return %line; - } -} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index f00941776..8688df941 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -1,5 +1,7 @@ $ProjectImporter::rootDir = "tools"; +$ProjectImporter::writeToConsole = false; + function ProjectImporter::beginProjectImport() { Canvas.pushDialog(ProjectImportCtrl); @@ -15,20 +17,36 @@ function ProjectImportWindow::onWake(%this) else $ProjectImporter::log.empty(); + if(!isObject($ProjectImporter::importerList)) + $ProjectImporter::importerList = new ArrayObject(); + else + $ProjectImporter::importerList.empty(); + + //This array is for containing the importer pages for the wizard + if(!isObject($ProjectImporter::importerPageList)) + $ProjectImporter::importerPageList = new ArrayObject(); + else + $ProjectImporter::importerPageList.empty(); + %this.importStepNumber = 0; - %this-->stepsList.clear(); - %this-->stepsList.addRow(0, "Welcome"); - %this-->stepsList.addRow(1, "Previous Project Ver."); - %this-->stepsList.addRow(2, "Locate Previous Project Content"); - %this-->stepsList.addRow(3, "Set New Module Name"); - %this-->stepsList.addRow(4, "Copy Old Files"); - %this-->stepsList.addRow(5, "Update Script Extensions"); - %this-->stepsList.addRow(6, "Import"); - %this-->stepsList.addRow(7, "Done"); - %this.stepCount = %this-->stepsList.rowCount()-1; + ProejctImportPageContainer.callOnChildren("setHidden", true); - %this.showPage(0); + $ProjectImporter::importerPageList.add(ProjectImportWizardPage0); + $ProjectImporter::importerPageList.add(ProjectImportWizardPage1); + $ProjectImporter::importerPageList.add(ProjectImportWizardPage2); + $ProjectImporter::importerPageList.add(ProjectImportWizardPage3); + $ProjectImporter::importerPageList.add(ProjectImportWizardPage4); + + %this.setStep(0); + + //now we iterate over our importers to get them registered and set up + for( %file = findFirstFile( "tools/projectImporter/importers/*." @ $TorqueScriptFileExtension ); + %file !$= ""; + %file = findNextFile( "tools/projectImporter/importers/*." @ $TorqueScriptFileExtension )) + { + exec( %file ); + } } function ProjectImportWindow::previousStep(%this) @@ -38,12 +56,14 @@ function ProjectImportWindow::previousStep(%this) %this.importStepNumber--; + %this.pageChanged = true; + %this.showPage(%this.importStepNumber); } function ProjectImportWindow::nextStep(%this) { - if(%this.importStepNumber == %this.stepCount) + if(%this.importStepNumber == $ProjectImporter::importerPageList.count()) { Canvas.popDialog(ProjectImportCtrl); return; @@ -51,12 +71,14 @@ function ProjectImportWindow::nextStep(%this) %this.importStepNumber++; + %this.pageChanged = true; + %this.showPage(%this.importStepNumber); } function ProjectImportWindow::setStep(%this, %stepNum) { - if(%stepNum >= %this.stepCount) + if(%stepNum >= $ProjectImporter::importerPageList.count()) { Canvas.popDialog(ProjectImportCtrl); return; @@ -67,6 +89,8 @@ function ProjectImportWindow::setStep(%this, %stepNum) %this.importStepNumber = %stepNum; + %this.pageChanged = true; + %this.showPage(%this.importStepNumber); } @@ -95,27 +119,42 @@ function ProjectImportWindow::selectOGFolder(%this) %dlg.delete(); } +function ProjectImportWindow::refreshPage(%this) +{ + for(%i=0; %i < $ProjectImporter::importerPageList.count(); %i++) + { + %page = $ProjectImporter::importerPageList.getKey(%i); + %page.setHidden(true); + %page.callOnChildren("setHidden", true); + } + + %page = $ProjectImporter::importerPageList.getKey(%this.importStepNumber); + %page.setHidden(false); + %page.callOnChildren("setHidden", false); +} + function ProjectImportWindow::showPage(%this, %pageIndex) { - if(%pageIndex < 0 || %pageIndex > %this.stepCount) + if(%pageIndex < 0 || %pageIndex > $ProjectImporter::importerPageList.count()) return; %this.importStepNumber = %pageIndex; - %this-->stepsList.clearSelection(); - %this-->stepsList.setSelectedById(%this.importStepNumber); - for(%i=0; %i < %this-->stepsList.rowCount(); %i++) + %this.refreshPage(); + + if(%this.pageChanged) { - (ProjectImportWizardPage @ %i).setHidden(true); + //run page logic + %page = $ProjectImporter::importerPageList.getKey(%this.importStepNumber); + %page.openPage(); } - (ProjectImportWizardPage @ %this.importStepNumber).setHidden(false); - (ProjectImportWizardPage @ %this.importStepNumber).openPage(); + %this.pageChanged = false; } function ProjectImportWindow::getCurrentPage(%this) { - return (ProjectImportWizardPage @ %this.importStepNumber); + return $ProjectImporter::importerPageList.getKey(%this.importStepNumber); } function ProjectImportWizardPage0::openPage(%this) @@ -123,24 +162,19 @@ function ProjectImportWizardPage0::openPage(%this) ProjectImportWindow-->backButton.setHidden(true); } -function ProjectImportWizardPage0::processPage(%this) -{ -} - function ProjectImportWizardPage1::openPage(%this) { ProjectImportWindow-->backButton.setHidden(false); %this-->previousContentVersionPopup.clear(); - //this-->previousContentVersionPopup.add("Torque Game Engine"); - //%this-->previousContentVersionPopup.add("Torque Shader Engine"); - %this-->previousContentVersionPopup.add("Torque 3D Pre-4.0"); -} - -function ProjectImportWizardPage1::processPage(%this) -{ + + for(%i=0; %i < $ProjectImporter::importerList.count(); %i++) + { + %this-->previousContentVersionPopup.add($ProjectImporter::importerList.getKey(%i)); + } } +//Select destination folder function ProjectImportWizardPage2::openPage(%this) { %version = ProjectImportWizardPage1-->previousContentVersionPopup.getSelected(); @@ -151,45 +185,73 @@ function ProjectImportWizardPage2::openPage(%this) return; } - ProjectImportWizardPage2-->internalFolderBtn.setStateOn(false); - ProjectImportWizardPage2-->externalFolderBtn.setStateOn(false); - ProjectImportWizardPage2-->coreAndToolsBtn.setStateOn(false); $ProjectImporter::sourceContentFolder = ""; %this-->targetImportingPath.setText(""); Canvas.repaint(); //force it to refresh the page so we're up to date. - switch$(%version) - { - case 0: - $ProjectImporter::versionMode = "T3Dpre4Project"; - default: - $ProjectImporter::versionMode = "T3Dpre4Project"; - } + $ProjectImporter::versionMode = $ProjectImporter::importerList.getKey(%version); if(isObject($ProjectImporter::importTool)) $ProjectImporter::importTool.delete(); - $ProjectImporter::importTool = new ScriptObject($ProjectImporter::versionMode @ "Importer"); + $ProjectImporter::importTool = $ProjectImporter::importerList.getValue(%version); - if(isObject($ProjectImporter::SFXDescriptionCache)) - $ProjectImporter::SFXDescriptionCache.delete(); + //if(isObject($ProjectImporter::SFXDescriptionCache)) + // $ProjectImporter::SFXDescriptionCache.delete(); - $ProjectImporter::SFXDescriptionCache = new ArrayObject(); + //$ProjectImporter::SFXDescriptionCache = new ArrayObject(); - if(isObject($ProjectImporter::ToRemoveObjectList)) - $ProjectImporter::ToRemoveObjectList.delete(); + //if(isObject($ProjectImporter::ToRemoveObjectList)) + // $ProjectImporter::ToRemoveObjectList.delete(); - $ProjectImporter::ToRemoveObjectList = new ArrayObject(); -} - -function ProjectImportWizardPage2::processPage(%this) -{ + //$ProjectImporter::ToRemoveObjectList = new ArrayObject(); + + $ProjectImporter::importTool.setupPages(); //Have the importer register it's pages + + //And then add our final page + $ProjectImporter::importerPageList.add(ProjectImportWizardFinalPage); } function ProjectImportWizardPage3::openPage(%this) { - if(ProjectImportWizardPage2-->internalFolderBtn.isStateOn()) + %dataFullPath = makeFullPath("data/"); + %coreFullPath = makeFullPath("core/"); + %toolsFullPath = makeFullPath("tools/"); + if(startsWith(makeFullPath("data/"), $ProjectImporter::sourceContentFolder)) + { + %moduleDef = AssetBrowser.dirHandler.getModuleFromAddress(makeRelativePath($ProjectImporter::sourceContentFolder)); + if(isObject(%moduleDef)) + { + //already a valid module in place so just skip this step + $ProjectImporter::useExistingModule = true; + $ProjectImporter::moduleName = %moduleDef.moduleId; + $ProjectImporter::modulePath = "data/" @ $ProjectImporter::moduleName; + ProjectImportWindow.setStep(4); + } + } + else if(startsWith(makeFullPath("core/"), $ProjectImporter::sourceContentFolder) || + startsWith(makeFullPath("tools/"), $ProjectImporter::sourceContentFolder)) + { + ProjectImportWindow.setStep(5); + } + else + { + %slashCount = getTokenCount($ProjectImporter::sourceContentFolder, "/"); + %topFolder = getToken($ProjectImporter::sourceContentFolder, "/", %slashCount-1); + if(%topFolder $= "") + %topFolder = getToken($ProjectImporter::sourceContentFolder, "/", %slashCount-2); + + //clean up invalid characters and stuff + %topFolder = sanitizeString(%topFolder); + + $ProjectImporter::useExistingModule = false; + $ProjectImporter::moduleName = %topFolder; //preseed the module name + $ProjectImporter::modulePath = "data/" @ $ProjectImporter::moduleName; + + ProjectImportWizardPage3-->newModuleName.setText($ProjectImporter::moduleName); + } + /*if(ProjectImportWizardPage2-->internalFolderBtn.isStateOn()) { $ProjectImporter::importMode = "InternalFolder"; } @@ -246,15 +308,373 @@ function ProjectImportWizardPage3::openPage(%this) else if($ProjectImporter::importMode $= "CoreAndTools") { ProjectImportWindow.setStep(5); - } + }*/ } -function ProjectImportWizardPage3::processPage(%this) +// +function preprocessImportingFiles() { + //======================================================== + //BEGIN THE PREPROCESS + if(isObject($ProjectImporter::FileList)) + $ProjectImporter::FileList.delete(); + + $ProjectImporter::FileList = new ArrayObject(); + + %file = findFirstFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*", true); + + //First, we go through and tabulate all valid files we'll want to copy over into + //our destination point. We're not copying them yet, but we're building the list + while( %file !$= "" ) + { + %fileExt = fileExt(%file); + + if(%fileExt $= ".dll" || %fileExt $= ".log" || %fileExt $= ".exe" || %fileExt $= ".manifest"|| %fileExt $= ".h" || + %fileExt $= ".cpp" || %fileExt $= ".so" || %fileExt $= ".do" || %fileExt $= ".lib" ||%fileExt $= ".exp") + { + %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); + continue; + } + + %fileArrayObj = new ArrayObject(); + + %fileArrayObj.fileDestination = strreplace(%file, $ProjectImporter::sourceContentFolder, $ProjectImporter::modulePath); + %fileArrayObj.fileDestination = sanitizeFilename(%fileArrayObj.fileDestination); + + %fileArrayObj.imported = false; + + //if it was a cs file, we'll be changing the eventual destination extension to comply to + //our set script extension + if(fileExt(%fileArrayObj.fileDestination) $= ".cs") + { + %fileArrayObj.fileDestination = filePath(%fileArrayObj.fileDestination) @ "/" @ fileBase(%fileArrayObj.fileDestination) @ "." @ $TorqueScriptFileExtension; + } + + $ProjectImporter::FileList.add(%file, %fileArrayObj); + + %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); + } + + $ProjectImporter::fileElementStack = new ArrayObject(); + + //Now that we've got the list of files we consider to be valid to import, + //we'll preprocess them. This lets us 'understand' the contents and for + //script-type files, we can parse them to figure out object defines and the like + //which will simplify things when we actually apply any changes to update it to + //the new project format later + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + + %fileExt = fileExt(%file); + + %rootFileSectionObject.fileName = fileName(%file); + %rootFileSectionObject.fileBase = fileBase(%file); + %rootFileSectionObject.fileExt = %fileExt; + + if(endsWith(%file, ".asset.taml")) + { + %rootFileSectionObject.fileExt = ".asset.taml"; + %rootFileSectionObject.isAssetFile = true; + } + else if(%fileExt !$= ".cs" && %fileExt !$= ".tscript" && %fileExt !$= ".gui" && + %fileExt !$= ".mis" && %fileExt !$= ".prefab" && %fileExt !$= ".module") + { + //we don't do this for binary files, for...obvious reasons + + %rootFileSectionObject.binaryFile = true; + + if(isImageFormat(%fileExt)) + %rootFileSectionObject.isImageFile = true; + else if(isShapeFormat(%fileExt)) + %rootFileSectionObject.isShapeFile = true; + else if(isSoundFormat(%fileExt)) + %rootFileSectionObject.isSoundFile = true; + else if(%fileExt $= ".ter") + %rootFileSectionObject.isTerrainFile = true; + continue; + } + + %rootFileSectionObject.binaryFile = false; + %currentFileSectionObject = %rootFileSectionObject; + %insideFunction = false; + %insideObjectBlock = false; + %insideCommentBlock = false; + + if ( $ProjectImporter::fileObject.openForRead( %file ) ) + { + echo("Processing File: " @ %file); + echo("-------------------------------------"); + + while ( !$ProjectImporter::fileObject.isEOF() ) + { + %line = $ProjectImporter::fileObject.readLine(); + + if(strIsMatchExpr("*new*(*)*", %line) && !strIsMatchExpr("*\"*new*(*)*\"*", %line)) + { + %start = strpos(%line, "new "); + %end = strpos(%line, "(", %start); + + if(%start != -1 && %end != -1) + { + %className = getSubStr(%line, %start + 4, %end-%start-4); + } + + %nameEnd = strpos(%line, ")", %end); + + %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); + + %inheritanceSplit = strpos(%objectName, ":"); + if(%inheritanceSplit != -1) + { + %objectName = getSubStr(%objectName, 0, %inheritanceSplit); + } + + %parentFileSectionObject = %currentFileSectionObject; + + %currentFileSectionObject = new ArrayObject(); + %currentFileSectionObject.elementType = "object"; + %currentFileSectionObject.classType = %className; + %currentFileSectionObject.objectName = %objectName; + %currentFileSectionObject.fileName = %file; + %currentFileSectionObject.skip = false; + %currentFileSectionObject.fileDestination = %rootFileSectionObject.fileDestination; + %insideObjectBlock = true; + + %currentFileSectionObject.add(%line); + + %parentFileSectionObject.add(%currentFileSectionObject); + + //Now for a sanity check, see if we kill the object on the same line as we make it + //sometimes people try and be 'efficient' with their code linecount wise + if(strIsMatchExpr("*};*", %line)) + { + %currentFileSectionObject = %parentFileSectionObject; + + %insideFunction = false; + %insideObjectBlock = false; + + if(%currentFileSectionObject.elementType $= "function") + %insideFunction = true; + if(%currentFileSectionObject.elementType $= "object") + %insideObjectBlock = true; + } + } + else if(strIsMatchExpr("*datablock*(*)*", %line)) + { + %start = strpos(%line, "datablock "); + %end = strpos(%line, "(", %start); + + if(%start != -1 && %end != -1) + { + %className = getSubStr(%line, %start + 10, %end-%start-10); + } + + %nameEnd = strpos(%line, ")", %end); + + %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); + + %inheritanceSplit = strpos(%objectName, ":"); + if(%inheritanceSplit != -1) + { + %objectName = getSubStr(%objectName, 0, %inheritanceSplit); + } + + %parentFileSectionObject = %currentFileSectionObject; + + %currentFileSectionObject = new ArrayObject(); + %currentFileSectionObject.elementType = "object"; + %currentFileSectionObject.classType = %className; + %currentFileSectionObject.objectName = %objectName; + %currentFileSectionObject.fileName = %file; + %currentFileSectionObject.skip = false; + %currentFileSectionObject.fileDestination = %rootFileSectionObject.fileDestination; + %insideObjectBlock = true; + + %currentFileSectionObject.add(%line); + + %parentFileSectionObject.add(%currentFileSectionObject); + + //Now for a sanity check, see if we kill the object on the same line as we make it + //sometimes people try and be 'efficient' with their code linecount wise + if(strIsMatchExpr("*};*", %line)) + { + %currentFileSectionObject = %parentFileSectionObject; + + %insideFunction = false; + %insideObjectBlock = false; + + if(%currentFileSectionObject.elementType $= "function") + %insideFunction = true; + if(%currentFileSectionObject.elementType $= "object") + %insideObjectBlock = true; + } + } + else if(strIsMatchExpr("*singleton*(*)*", %line)) + { + %start = strpos(%line, "singleton "); + %end = strpos(%line, "(", %start); + + if(%start != -1 && %end != -1) + { + %className = getSubStr(%line, %start + 10, %end-%start-10); + } + + %nameEnd = strpos(%line, ")", %end); + + %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); + + %inheritanceSplit = strpos(%objectName, ":"); + if(%inheritanceSplit != -1) + { + %objectName = getSubStr(%objectName, 0, %inheritanceSplit); + } + + %parentFileSectionObject = %currentFileSectionObject; + + %currentFileSectionObject = new ArrayObject(); + %currentFileSectionObject.elementType = "object"; + %currentFileSectionObject.classType = %className; + %currentFileSectionObject.objectName = %objectName; + %currentFileSectionObject.fileName = %file; + %currentFileSectionObject.skip = false; + %currentFileSectionObject.fileDestination = %rootFileSectionObject.fileDestination; + %insideObjectBlock = true; + + %currentFileSectionObject.add(%line); + + %parentFileSectionObject.add(%currentFileSectionObject); + + //Now for a sanity check, see if we kill the object on the same line as we make it + //sometimes people try and be 'efficient' with their code linecount wise + if(strIsMatchExpr("*};*", %line)) + { + %currentFileSectionObject = %parentFileSectionObject; + + %insideFunction = false; + %insideObjectBlock = false; + + if(%currentFileSectionObject.elementType $= "function") + %insideFunction = true; + if(%currentFileSectionObject.elementType $= "object") + %insideObjectBlock = true; + } + } + else if(strIsMatchExpr("*function*(*)*", %line)) + { + %start = strpos(%line, "function "); + %end = strpos(%line, "(", %start); + + if(%start != -1 && %end != -1) + { + %functionName = getSubStr(%line, %start + 9, %end-%start-9); + } + + %parentFileSectionObject = %currentFileSectionObject; + + %currentFileSectionObject = new ArrayObject(); + %currentFileSectionObject.elementType = "function"; + %currentFileSectionObject.functionName = %functionName; + %currentFileSectionObject.fileDestination = %rootFileSectionObject.fileDestination; + %currentFileSectionObject.scopeDepth = 0; + + %insideFunction = true; + %insideObjectBlock = false; + + %currentFileSectionObject.add(%line); + + %parentFileSectionObject.add(%currentFileSectionObject); + + if(strIsMatchExpr("*{*", %line)) + { + %currentFileSectionObject.scopeDepth++; + } + if(strIsMatchExpr("*}*", %line)) + { + %currentFileSectionObject.scopeDepth--; + + if(%currentFileSectionObject.scopeDepth == 0) //we've fully backed out of the function scope, so resolve back to the parent + { + %currentFileSectionObject = %parentFileSectionObject; + + %insideFunction = false; + %insideObjectBlock = false; + + if(%currentFileSectionObject.elementType $= "function") + %insideFunction = true; + if(%currentFileSectionObject.elementType $= "object") + %insideObjectBlock = true; + } + } + } + else + { + %currentFileSectionObject.add(%line); + + if(%insideFunction && strIsMatchExpr("*{*", %line)) + { + %currentFileSectionObject.scopeDepth++; + } + if(%insideFunction && strIsMatchExpr("*}*", %line)) + { + %currentFileSectionObject.scopeDepth--; + + if(%currentFileSectionObject.scopeDepth == 0) //we've fully backed out of the function scope, so resolve back to the parent + { + %currentFileSectionObject = %parentFileSectionObject; + + %insideFunction = false; + %insideObjectBlock = false; + + if(%currentFileSectionObject.elementType $= "function") + %insideFunction = true; + if(%currentFileSectionObject.elementType $= "object") + %insideObjectBlock = true; + } + } + else if(%insideObjectBlock && strIsMatchExpr("*};*", %line) && !strIsMatchExpr("*\"*};*\";*", %line)) + { + %currentFileSectionObject = %parentFileSectionObject; + + %insideFunction = false; + %insideObjectBlock = false; + + if(%currentFileSectionObject.elementType $= "function") + %insideFunction = true; + if(%currentFileSectionObject.elementType $= "object") + %insideObjectBlock = true; + } + else if(!%insideFunction && !%insideObjectBlock) + { + if(strIsMatchExpr("*/\**", %line)) + { + %insideCommentBlock = true; + } + else if(%insideCommentBlock && strIsMatchExpr("*\*/*", %line)) + { + %insideCommentBlock = false; + } + else if(!%insideCommentBlock && !strIsMatchExpr("*//*", %line)) + { + %rootFileSectionObject.hasNonCommentFloatingCode = true; + } + } + } + } + } + + $ProjectImporter::fileObject.close(); + } } +// function ProjectImportWizardPage4::openPage(%this) { + ProjectImportWindow-->preprocessCompleteText.setHidden(true); + + Canvas.repaint(); + ProjectImportWindow-->backButton.setHidden(true); ProjectImportWindow-->nextButton.setActive(false); @@ -270,14 +690,10 @@ function ProjectImportWizardPage4::openPage(%this) %sourcePath = $ProjectImporter::sourceContentFolder; %targetPath = makeFullPath($ProjectImporter::modulePath); - //If the source path starts with the module target path at all, we're already that folder, or a subfolder in it, so skip filecopy - if(!startsWith(%sourcePath, %targetPath)) - $ProjectImporter::importTool.copyFiles(); - else - ProjectImportWindow.nextStep(); + preprocessImportingFiles(); //if we gen'd a new module setup, double check we didn't copy over a module script file under a legacy extension - if(!$ProjectImporter::useExistingModule) + /*if(!$ProjectImporter::useExistingModule) { %newModuleName = $ProjectImporter::moduleName; %moduleFilePath = "data/" @ %newModuleName; @@ -291,11 +707,12 @@ function ProjectImportWizardPage4::openPage(%this) fileDelete(%moduleFilePath @ "/" @ %newModuleName @ "." @ $TorqueScriptFileExtension); } } - } -} + }*/ -function ProjectImportWizardPage4::processPage(%this) -{ + ProjectImportWindow-->nextButton.setActive(true); + ProjectImportWindow-->preprocessCompleteText.setHidden(false); + + Canvas.repaint(); } function ProjectImportWizardPage5::openPage(%this) @@ -306,10 +723,6 @@ function ProjectImportWizardPage5::openPage(%this) $ProjectImporter::importTool.processImportedFiles(); } -function ProjectImportWizardPage5::processPage(%this) -{ -} - function ProjectImportWizardPage6::openPage(%this) { ProjectImportWindow-->nextButton.setActive(false); @@ -351,11 +764,7 @@ function ProjectImportWizardPage6::openPage(%this) } } -function ProjectImportWizardPage6::processPage(%this) -{ -} - -function ProjectImportWizardPage7::openPage(%this) +function ProjectImportWizardFinalPage::openPage(%this) { //writing console log %logFileObj = new FileObject(); @@ -375,11 +784,19 @@ function ProjectImportWizardPage7::openPage(%this) %logFileObj.delete(); } +// +function ProjectImportWindow::addImporterPage(%this, %page) +{ + ProejctImportPageContainer.add(%page); + $ProjectImporter::importerPageList.add(%page); +} +// + function beginProjectImport() { - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Beginning Project Import"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Beginning Project Import"); + projectImporterLog("==========================================="); $ProjectImporter::assetQuery = new AssetQuery(); $ProjectImporter::importer = new AssetImporter(); @@ -410,9 +827,9 @@ function beginProjectImport() $ProjectImporter::importer.delete(); $ProjectImporter::persistMgr.delete(); - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Finished Project Import"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Finished Project Import"); + projectImporterLog("==========================================="); AssetBrowser.refresh(); //update the AB just in case } @@ -478,7 +895,7 @@ function sanitizeFilename(%file) %targetFilename = %targetPath @ "/" @ %targetName @ %targetExt; } - if(!isFile(%targetFilename)) + /*if(!isFile(%targetFilename)) { %bitmapFile = %targetPath @ "/" @ %targetName @ "_n" @ %targetExt; if(isFile(%bitmapFile)) @@ -497,9 +914,22 @@ function sanitizeFilename(%file) return %file; } else - { + {*/ return %targetFilename; + //} +} + +function isImportingFile(%checkFile) +{ + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + + if(%file $= %checkFile) + return true; } + + return false; } function testFilenameExtensions(%filename) @@ -560,7 +990,7 @@ function processLegacyField(%line, %originalFieldName, %newFieldName) if(%outLine !$= %line && %pos != -1 && %endPos != -1 && %value !$= "") { - $ProjectImporter::log.add("Legacy Project Importer - processing legacy field line: " @ %line); + projectImporterLog("Legacy Project Importer - processing legacy field line: " @ %line); if(startsWith(%value, "$") || startsWith(%value, "#")) { @@ -570,6 +1000,12 @@ function processLegacyField(%line, %originalFieldName, %newFieldName) %targetFilename = sanitizeFilename(%value); + %fileExt = fileExt(%targetFilename); + if(%fileExt $= "") + { + %targetFilename = testFilenameExtensions(%targetFilename); + } + if(isObject(%targetFilename)) { //likely a material name, so handle it that way @@ -591,18 +1027,17 @@ function processLegacyField(%line, %originalFieldName, %newFieldName) { if(!isFile(%targetFilename)) { - if(%originalFieldName $= "soundProfile") + //We may just have a discrete name we need to look up instead + $ProjectImporter::assetQuery.clear(); + %foundAssets = AssetDatabase.findAssetName($ProjectImporter::assetQuery, %targetFilename); + if(%foundAssets != 0) { - $ProjectImporter::assetQuery.clear(); - %foundAssets = AssetDatabase.findAssetName($ProjectImporter::assetQuery, %targetFilename); - if(%foundAssets != 0) - { - %assetId = $ProjectImporter::assetQuery.getAsset(0); - } + %assetId = $ProjectImporter::assetQuery.getAsset(0); } else { - $ProjectImporter::log.add("Legacy Project Importer - file described in line could not be found/is not valid"); + //Ultimately, we didn't find it and need to cut our losses + projectImporterLog("Legacy Project Importer - file described in line could not be found/is not valid"); return %line; } } @@ -619,7 +1054,7 @@ function processLegacyField(%line, %originalFieldName, %newFieldName) if(%assetId !$= "" && AssetDatabase.isDeclaredAsset(%assetId)) { - $ProjectImporter::log.add("Legacy Project Importer - processing of legacy field line's value: " @ %value @ " has found a matching AssetId: " @ %assetId); + projectImporterLog("Legacy Project Importer - processing of legacy field line's value: " @ %value @ " has found a matching AssetId: " @ %assetId); //double check if this already had the quotes around the value or not if(!strIsMatchExpr("*\"*\"*", %originalValue)) @@ -634,7 +1069,7 @@ function processLegacyField(%line, %originalFieldName, %newFieldName) if(%outLine !$= %line) { - $ProjectImporter::log.add("Legacy Project Importer - processing of legacy line: " @ %line @ " has been updated to: " @ %outLine); + projectImporterLog("Legacy Project Importer - processing of legacy line: " @ %line @ " has been updated to: " @ %outLine); return %outLine; } else @@ -672,7 +1107,7 @@ function processLegacyShapeConstructorField(%line) if(%foundAssets != 0) { %assetId = $ProjectImporter::assetQuery.getAsset(0); - $ProjectImporter::log.add("Legacy Project Importer - processing of legacy shape constructor addSequence line's value: " @ %animSourcePath @ " has found a matching AssetId: " @ %assetId); + projectImporterLog("Legacy Project Importer - processing of legacy shape constructor addSequence line's value: " @ %animSourcePath @ " has found a matching AssetId: " @ %assetId); } if(%assetId !$= "" && AssetDatabase.isDeclaredAsset(%assetId)) @@ -685,7 +1120,7 @@ function processLegacyShapeConstructorField(%line) if(%outLine !$= %line) { - $ProjectImporter::log.add("Legacy Project Importer - processing of legacy shape constructor addSequence line: " @ %line @ " has been updated to: " @ %outLine); + projectImporterLog("Legacy Project Importer - processing of legacy shape constructor addSequence line: " @ %line @ " has been updated to: " @ %outLine); return %outLine; } else @@ -694,256 +1129,226 @@ function processLegacyShapeConstructorField(%line) } } -function findObjectClass(%line, %createWord) +function renameObjectName(%object, %newName) { - //we have a new object, add it to the stack - //substr to peel the class name - %start = strpos(%line, %createWord @ " "); - %end = strpos(%line, "(", %start); - %createLen = strlen(%createWord @ " "); - - if(%start != -1 && %end != -1) + for(%e=0; %e < %object.count(); %e++) { - %className = getSubStr(%line, %start + %createLen, %end-%start-%createLen); - - %className = trim(%className); - - return %className; - } - - return ""; -} - -function findObjectName(%line, %createWord) -{ - //we have a new object, add it to the stack - //substr to peel the class name - %start = strpos(%line, %createWord @ " "); - %end = strpos(%line, "(", %start); - - %nameEnd = strpos(%line, ")", %end); - - %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); - - if(%objectName !$= "") - { - if(strpos(%objectName, ":") != -1) + %objectLine = %object.getKey(%e); + if(!isObject(%objectLine)) { - %objectName = getSubStr(%objectName, 0, strpos(%objectName, ":")); - } - - if(strpos(%objectName, ",") != -1) - { - %objectName = getSubStr(%objectName, 0, strpos(%objectName, ",")); - } - - %objectName = trim(%objectName); - } - - return %objectName; -} - -function findObjectField(%fieldName, %fileObj) -{ - if(%fileObj $= "") - %fileObj = $ProjectImporter::fileObject; - - %value = ""; - %peekLineOffset = 0; - %peekLine = %fileObj.peekLine(%peekLineOffset); - while(!strIsMatchExpr("*};*", %peekLine) && - !strIsMatchExpr("*singleton*(*)*", %peekLine) && - !strIsMatchExpr("*new*(*)*", %peekLine) && - !strIsMatchExpr("*datablock*(*)*", %peekLine)&& - !strIsMatchExpr("\n", %peekLine) && - !strIsMatchExpr("\r", %peekLine)) - { - if(strpos(strlwr(%peekLine), strlwr(%fieldName)) != -1) - { - %value = ""; - %pos = strpos(%peekLine, "= \""); - if(%pos != -1) + if(strIsMatchExpr("*singleton*(*)*", %objectLine) && + strIsMatchExpr("*new*(*)*", %objectLine) && + strIsMatchExpr("*datablock*(*)*", %objectLine)) { - %endPos = strpos(%peekLine, "\";", %pos); - - %value = getSubStr(%peekLine, %pos+3, %endPos-%pos-3); - break; - } - - %pos = strpos(%peekLine, "=\""); - if(%pos != -1) - { - %endPos = strpos(%peekLine, "\";", %pos); - - %value = getSubStr(%peekLine, %pos+2, %endPos-%pos-2); - break; - } - - %pos = strpos(%peekLine, "= "); - if(%pos != -1) - { - %endPos = strpos(%peekLine, ";", %pos); - - %value = getSubStr(%peekLine, %pos+2, %endPos-%pos-2); - break; - } - - %pos = strpos(%peekLine, "="); - if(%pos != -1) - { - %endPos = strpos(%peekLine, ";", %pos); - - %value = getSubStr(%peekLine, %pos+2, %endPos-%pos-2); - break; + %newLine = strreplace(%object.objectName, %newName); + + echo("renameObjectName() - lines changed from:"); + echo(%objectLine); + echo("to:"); + echo(%newLine); + + %object.setKey(%newLine, %e); } } - - %peekLineOffset++; - %peekLine = %fileObj.peekLine(%peekLineOffset); - } - - return %value; -} - -function findObjectInFiles(%objectName) -{ - //First, wipe out any files inside the folder first - %file = findFirstFileMultiExpr( "*.*", true); - - %fileObj = new FileObject(); - - while( %file !$= "" ) - { - %filename = fileName(%file); - %fileBase = fileBase(%file); - %fileExt = fileExt(%file); - %filePath = filePath(%file); - - if ( %fileObj.openForRead( %file ) ) - { - %lineNum = 0; - while ( !%fileObj.isEOF() ) - { - %line = %fileObj.readLine(); - %trimmedLine = trim(%line); - - if(strIsMatchExpr("*new*(*)*", %line) && strpos(%line, "::") == -1) - { - %className = findObjectClass(%line, "new"); - if (%className $= "") continue; - - %objName = findObjectName(%line, "new"); - - if(%objectName $= %objName) - { - return %fileObj TAB %file TAB %lineNum; - } - } - else if(strIsMatchExpr("*datablock*(*)*", %line) && strpos(%line, "::") == -1) - { - %className = findObjectClass(%line, "datablock"); - if (%className $= "") continue; - - %objName = findObjectName(%line, "datablock"); - - if(%objectName $= %objName) - { - return %fileObj TAB %file TAB %lineNum; - } - } - else if(strIsMatchExpr("*singleton*(*)*", %line) && strpos(%line, "::") == -1) - { - %className = findObjectClass(%line, "singleton"); - if (%className $= "") continue; - - %objName = findObjectName(%line, "singleton"); - - if(%objectName $= %objName) - { - return %fileObj TAB %file TAB %lineNum; - } - } - - %lineNum++; - } - - %fileObj.close(); - } - else - { - $ProjectImporter::log.add("findObjectInFiles() - File not able to be opened: " @ %file); - } - - %file = findNextFileMultiExpr( "*.*" ); } - - %fileObj.delete(); - - return ""; } + +function findObjectField(%object, %fieldName) +{ + %return = ""; + for(%e=0; %e < %object.count(); %e++) + { + %objectLine = %object.getKey(%e); + if(!isObject(%objectLine)) + { + if(!strIsMatchExpr("*};*", %objectLine) && + !strIsMatchExpr("*singleton*(*)*", %objectLine) && + !strIsMatchExpr("*new*(*)*", %objectLine) && + !strIsMatchExpr("*datablock*(*)*", %objectLine)&& + !strIsMatchExpr("\n", %objectLine) && + !strIsMatchExpr("\r", %objectLine)) + { + if(strpos(strlwr(%objectLine), strlwr(%fieldName)) != -1) + { + %pos = strpos(%objectLine, "= \""); + if(%pos != -1) + { + %endPos = strpos(%objectLine, "\";", %pos); + + %return = getSubStr(%objectLine, %pos+3, %endPos-%pos-3); + break; + } + + %pos = strpos(%objectLine, "=\""); + if(%pos != -1) + { + %endPos = strpos(%objectLine, "\";", %pos); + + %return = getSubStr(%objectLine, %pos+2, %endPos-%pos-2); + break; + } + + %pos = strpos(%objectLine, "= "); + if(%pos != -1) + { + %endPos = strpos(%objectLine, ";", %pos); + + %return = getSubStr(%objectLine, %pos+2, %endPos-%pos-2); + break; + } + + %pos = strpos(%objectLine, "="); + if(%pos != -1) + { + %endPos = strpos(%objectLine, ";", %pos); + + %return = getSubStr(%objectLine, %pos+2, %endPos-%pos-2); + break; + } + } + } + } + } + + return %return; +} + +function setObjectField(%object, %fieldName, %newValue) +{ + for(%e=0; %e < %object.count(); %e++) + { + %objectLine = %object.getKey(%e); + if(!isObject(%objectLine)) + { + if(!strIsMatchExpr("*};*", %objectLine) && + !strIsMatchExpr("*singleton*(*)*", %objectLine) && + !strIsMatchExpr("*new*(*)*", %objectLine) && + !strIsMatchExpr("*datablock*(*)*", %objectLine)&& + !strIsMatchExpr("\n", %objectLine) && + !strIsMatchExpr("\r", %objectLine)) + { + if(strpos(strlwr(%objectLine), strlwr(%fieldName)) != -1) + { + %pos = strpos(%objectLine, "= \""); + if(%pos != -1) + { + %endPos = strpos(%objectLine, "\";", %pos); + + %value = getSubStr(%objectLine, %pos+3, %endPos-%pos-3); + %editedLine = strreplace(%objectLine, %value, %newValue); + %object.setKey(%editedLine, %e); + break; + } + + %pos = strpos(%objectLine, "=\""); + if(%pos != -1) + { + %endPos = strpos(%objectLine, "\";", %pos); + + %value = getSubStr(%objectLine, %pos+2, %endPos-%pos-2); + %editedLine = strreplace(%objectLine, %value, %newValue); + %object.setKey(%editedLine, %e); + break; + } + + %pos = strpos(%objectLine, "= "); + if(%pos != -1) + { + %endPos = strpos(%objectLine, ";", %pos); + + %value = getSubStr(%objectLine, %pos+2, %endPos-%pos-2); + %editedLine = strreplace(%objectLine, %value, %newValue); + %object.setKey(%editedLine, %e); + break; + } + + %pos = strpos(%objectLine, "="); + if(%pos != -1) + { + %endPos = strpos(%objectLine, ";", %pos); + + %value = getSubStr(%objectLine, %pos+2, %endPos-%pos-2); + %editedLine = strreplace(%objectLine, %value, %newValue); + %object.setKey(%editedLine, %e); + break; + } + } + } + } + } +} + +function projectImporterLog(%line) +{ + if($ProjectImporter::writeToConsole) + echo(%line); + + $ProjectImporter::log.add(%line); +} + //============================================================================== //Shape Importing //============================================================================== function beginShapeImport() { - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Importing 3D Shape files"); - $ProjectImporter::log.add("==========================================="); - //First, we need to go through and process all loose shape files. This will - //get us shape assets, material assets image, assets and animation assets. + projectImporterLog("==========================================="); + projectImporterLog("Importing 3D Shape files"); + projectImporterLog("==========================================="); + + //First, we need to go through and process all loose image files. This will + //get us shape assets, and if the import config deigns, material assets. %currentAddress = $ProjectImporter::modulePath; - //First, wipe out any files inside the folder first - %file = findFirstFileMultiExpr( %currentAddress @ "/*.*", true); - - while( %file !$= "" ) - { - if(endsWith(%file, "cached.dts")) - { - %file = findNextFileMultiExpr( %currentAddress @ "/*.*" ); - continue; - } - - %filename = fileName(%file); - %fileExt = fileExt(%file); - %filePath = filePath(%file); - - //Specific exclusions - if(endsWith(%filename, "cached.dts")) - { - %file = findNextFileMultiExpr( %currentAddress @ "/*.*" ); - continue; - } + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + %destinationPath = %rootFileSectionObject.fileDestination; + if(isFile(%file) && %rootFileSectionObject.isShapeFile == true && %rootFileSectionObject.imported == false) + { + if(!IsDirectory(filePath(%destinationPath))) + { + DirectoryHandler::createFolder(0, filePath(%destinationPath)); + } + + if(!pathCopy(%file, %destinationPath, false)) + { + projectImporterLog("ProjectImporter::beginShapeImport() - failed to copy shape: " @ %file @ + " to destination: " @ %destinationPath); + continue; + } + + if(endsWith(%destinationPath, "cached.dts")) + { + continue; + } - if(isShapeFormat(%fileExt)) - { $ProjectImporter::assetQuery.clear(); - %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %file); + %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %destinationPath); if(%assetsFound == 0) { - ProjectImportWizardPage5-->processingText.setText("Processing Shape Asset file: " @ %file); + //ProjectImportWizardPage5-->processingText.setText("Processing Shape Asset file: " @ %file); Canvas.repaint(); //No asset found associated to this fileas far as we can determine, so time to import it - - $ProjectImporter::log.add("Importing 3D Shape file: " @ %file); - %assetId = $ProjectImporter::importer.autoImportFile(%file); + projectImporterLog("Importing 3D Shape file: " @ %destinationPath); + %assetId = $ProjectImporter::importer.autoImportFile(%destinationPath); getImporterLogs(); if(%assetId !$= "") { - $ProjectImporter::log.add("Finished importing 3D Shape file, resulting in asset with an id of: " @ %assetId); - $ProjectImporter::log.add(""); + projectImporterLog("Finished importing 3D Shape file, resulting in asset with an id of: " @ %assetId); + projectImporterLog(""); + + %rootFileSectionObject.imported = true; } } } - - %file = findNextFileMultiExpr( %currentAddress @ "/*.*" ); } - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Finished Importing 3D Shape files"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Finished Importing 3D Shape files"); + projectImporterLog("==========================================="); } //============================================================================== @@ -952,56 +1357,62 @@ function beginShapeImport() //============================================================================== function beginImageImport() { - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Importing Image files"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Importing Image files"); + projectImporterLog("==========================================="); + //First, we need to go through and process all loose image files. This will //get us image assets, and if the import config deigns, material assets. %currentAddress = $ProjectImporter::modulePath; - //First, wipe out any files inside the folder first - %file = findFirstFileMultiExpr( %currentAddress @ "/*.*", true); - - while( %file !$= "" ) - { - %filename = fileName(%file); - %fileExt = fileExt(%file); - %filePath = filePath(%file); - - if(isImageFormat(%fileExt)) - { - if(%filename $= "skybox_1.png") + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + %destinationPath = %rootFileSectionObject.fileDestination; + if(isFile(%file) && %rootFileSectionObject.isImageFile == true && %rootFileSectionObject.imported == false) + { + if(!IsDirectory(filePath(%destinationPath))) { - %aefgadfg = true; + DirectoryHandler::createFolder(0, filePath(%destinationPath)); } + if(!pathCopy(%file, %destinationPath, false)) + { + projectImporterLog("ProjectImporter::beginImageImport() - failed to copy image: " @ %file @ + " to destination: " @ %destinationPath); + continue; + } + + projectImporterLog("Beginning of Import of Image file: " @ %file); + $ProjectImporter::assetQuery.clear(); - %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %file); + %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %destinationPath); if(%assetsFound == 0) { - ProjectImportWizardPage5-->processingText.setText("Processing Image Asset file: " @ %file); + //ProjectImportWizardPage5-->processingText.setText("Processing Image Asset file: " @ %file); Canvas.repaint(); //No asset found associated to this fileas far as we can determine, so time to import it - $ProjectImporter::log.add("Importing Image file: " @ %file); - %assetId = $ProjectImporter::importer.autoImportFile(%file); + projectImporterLog(" No Existing ImageAsset found. Continuing Import."); + %assetId = $ProjectImporter::importer.autoImportFile(%destinationPath); getImporterLogs(); if(%assetId !$= "") { - $ProjectImporter::log.add("Finished importing Image file, resulting in asset with an id of: " @ %assetId); - $ProjectImporter::log.add(""); + projectImporterLog("Finished importing Image file, resulting in asset with an id of: " @ %assetId); + projectImporterLog(""); + + %rootFileSectionObject.imported = true; } } } - - %file = findNextFileMultiExpr( %currentAddress @ "/*.*" ); } - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Finished Importing Image files"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Finished Importing Image files"); + projectImporterLog("==========================================="); } //============================================================================== @@ -1010,47 +1421,61 @@ function beginImageImport() //============================================================================== function beginTerrainImport() { - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Importing Terrain files"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Importing Terrain files"); + projectImporterLog("==========================================="); + //First, we need to go through and process all loose image files. This will + //get us shape assets, and if the import config deigns, material assets. %currentAddress = $ProjectImporter::modulePath; - //First, wipe out any files inside the folder first - %file = findFirstFileMultiExpr( %currentAddress @ "/*.*", true); - - while( %file !$= "" ) - { - %fileName = fileName(%file); - %fileExt = fileExt(%file); - %filePath = filePath(%file); - if(%fileExt $= ".ter") - { + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + %destinationPath = %rootFileSectionObject.fileDestination; + if(isFile(%file) && %rootFileSectionObject.isTerrainFile == true && %rootFileSectionObject.imported == false) + { + /*%filename = %rootFileSectionObject.fileName; + %fileExt = %rootFileSectionObject.fileExt; + %filePath = filePath(%file); + %sanitizedFile = sanitizeFilename(%file); if(%sanitizedFile !$= %file) { %file = %sanitizedFile; %fileName = fileName(%file); %filePath = filePath(%file); + }*/ + if(!IsDirectory(filePath(%destinationPath))) + { + DirectoryHandler::createFolder(0, filePath(%destinationPath)); + } + + if(!pathCopy(%file, %destinationPath, false)) + { + projectImporterLog("ProjectImporter::beginTerrainImport() - failed to copy terrain: " @ %file @ + " to destination: " @ %destinationPath); + continue; } $ProjectImporter::assetQuery.clear(); - %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %file); + %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %destinationPath); if(%assetsFound == 0) { - ProjectImportWizardPage5-->processingText.setText("Processing Terrain Asset file: " @ %file); + //ProjectImportWizardPage5-->processingText.setText("Processing Terrain Asset file: " @ %file); Canvas.repaint(); - $ProjectImporter::log.add("Importing Terrain file: " @ %file); + projectImporterLog("Importing Terrain file: " @ %destinationPath); - %moduleDef = AssetBrowser.dirHandler.getModuleFromAddress(%file); + %moduleDef = AssetBrowser.dirHandler.getModuleFromAddress(%destinationPath); %moduleName = %moduleDef.ModuleID; %modulePath = %moduleDef.ModulePath; //test import config here for forcing type suffixes - %assetName = fileBase(%file); + %assetName = fileBase(%destinationPath); - %assetPath = %filePath @ "/"; + %assetPath = filePath(%destinationPath) @ "/"; %tamlpath = %assetPath @ %assetName @ ".asset.taml"; @@ -1058,15 +1483,90 @@ function beginTerrainImport() { AssetName = %assetName; versionId = 1; - terrainFile = %fileName; + terrainFile = fileName(%destinationPath); }; if(TamlWrite(%asset, %tamlpath)) { AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); - $ProjectImporter::log.add("Finished importing Terrain file, resulting in asset with an id of: " @ %moduleName @ ":" @ %assetName); - $ProjectImporter::log.add(""); + projectImporterLog("Finished importing Terrain file, resulting in asset with an id of: " @ %moduleName @ ":" @ %assetName); + projectImporterLog(""); + + %rootFileSectionObject.imported = true; + } + } + } + } + + projectImporterLog("==========================================="); + projectImporterLog("Finished Importing Terrain files"); + projectImporterLog("==========================================="); +} +//============================================================================== + +//============================================================================== +//Sound Importing +//============================================================================== +function beginSoundImport() +{ + projectImporterLog("==========================================="); + projectImporterLog("Importing Sound files"); + projectImporterLog("==========================================="); + + //First, we need to go through and process all loose image files. This will + //get us shape assets, and if the import config deigns, material assets. + %currentAddress = $ProjectImporter::modulePath; + + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + %destinationPath = %rootFileSectionObject.fileDestination; + if(isFile(%file) && %rootFileSectionObject.isSoundFile == true && %rootFileSectionObject.imported == false) + { + /*%filename = %rootFileSectionObject.fileName; + %fileExt = %rootFileSectionObject.fileExt; + %filePath = filePath(%file); + + %sanitizedFile = sanitizeFilename(%file); + if(%sanitizedFile !$= %file) + { + %file = %sanitizedFile; + %fileName = fileName(%file); + %filePath = filePath(%file); + }*/ + if(!IsDirectory(filePath(%destinationPath))) + { + DirectoryHandler::createFolder(0, filePath(%destinationPath)); + } + + if(!pathCopy(%file, %destinationPath, false)) + { + projectImporterLog("ProjectImporter::beginSoundImport() - failed to copy sound: " @ %file @ + " to destination: " @ %destinationPath); + continue; + } + + $ProjectImporter::assetQuery.clear(); + %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %destinationPath); + if(%assetsFound == 0) + { + //ProjectImportWizardPage5-->processingText.setText("Processing Image Asset file: " @ %file); + Canvas.repaint(); + + //No asset found associated to this fileas far as we can determine, so time to import it + + projectImporterLog(" No Existing SoundAsset found. Continuing Import."); + %assetId = $ProjectImporter::importer.autoImportFile(%destinationPath); + getImporterLogs(); + + if(%assetId !$= "") + { + projectImporterLog("Finished importing Sound file, resulting in asset with an id of: " @ %assetId); + projectImporterLog(""); + + %rootFileSectionObject.imported = true; } } } @@ -1074,95 +1574,97 @@ function beginTerrainImport() %file = findNextFileMultiExpr( %currentAddress @ "/*.*" ); } - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Finished Importing Terrain files"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Finished Importing Sound files"); + projectImporterLog("==========================================="); } //============================================================================== -//============================================================================== -//Sound Importing -//============================================================================== - -//============================================================================== - //============================================================================== //Gui Importing //============================================================================== function beginGUIImport() { - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Importing GUIs"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Importing GUIs"); + projectImporterLog("==========================================="); + //First, we need to go through and process all loose image files. This will + //get us shape assets, and if the import config deigns, material assets. %currentAddress = $ProjectImporter::modulePath; - //First, wipe out any files inside the folder first - %file = findFirstFileMultiExpr( %currentAddress @ "/*.*", true); - - while( %file !$= "" ) - { - %fileName = fileName(%file); - %fileExt = fileExt(%file); - %filePath = filePath(%file); - if(%fileExt $= ".gui") - { + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + %destinationPath = %rootFileSectionObject.fileDestination; + if(isFile(%file) && %rootFileSectionObject.fileExt $= ".gui" && %rootFileSectionObject.imported == false) + { $ProjectImporter::assetQuery.clear(); - %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %file); + %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %destinationPath); if(%assetsFound == 0) { - ProjectImportWizardPage5-->processingText.setText("Processing GUI Asset file: " @ %file); + //ProjectImportWizardPage5-->processingText.setText("Processing GUI Asset file: " @ %file); Canvas.repaint(); - if ( $ProjectImporter::fileObject.openForRead( %file ) ) + %guiObjectName = ""; + + //find our root GUI item + for(%g = 0; %g < %rootFileSectionObject.count(); %g++) { - while ( !$ProjectImporter::fileObject.isEOF() ) + %fileElement = %rootFileSectionObject.getKey(%g); + if(%fileElement.elementType $= "Object") { - %line = $ProjectImporter::fileObject.readLine(); - - if(strIsMatchExpr("*new*(*)*", %line)) + %guiObjectName = %fileElement.objectName; + %delcareLine = %fileElement.getKey(0); + if(startsWith(%delcareLine, "%guiContent")) { - %start = strpos(%line, "new "); - %end = strpos(%line, "(", %start); - - if(%start != -1 && %end != -1) + %equalPos = strPos(%delcareLine, "="); + if(%equalPos != -1) { - %className = getSubStr(%line, %start + 4, %end-%start-4); + %declareSubStr = getSubStr(%delcareLine, %equalPos + 1); + + //update the line to remove the unneeded local var + %fileElement.setKey(%declareSubStr, 0); } - - %nameEnd = strpos(%line, ")", %end); - - %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); - - if(%objectName !$= "") - { - if(strpos(%objectName, ":") != -1) - { - %objectName = getSubStr(%objectName, 0, strpos(%objectName, ":")); - } - } - - processGUIntoAsset(%objectName, %file); - break; } + break; } } - $ProjectImporter::fileObject.close(); + if(%guiObjectName $= "") + { + projectImporterLog("ProjectImporter::beginGUIImport() - failed to find root GUI control in file: " @ %file); + continue; + } + + if(!IsDirectory(filePath(%destinationPath))) + { + DirectoryHandler::createFolder(0, filePath(%destinationPath)); + } + + if(!pathCopy(%file, %destinationPath, false)) + { + projectImporterLog("ProjectImporter::beginGUIImport() - failed to copy GUI: " @ %file @ + " to destination: " @ %destinationPath); + continue; + } + + processGUIntoAsset(%guiObjectName, %destinationPath); + + %rootFileSectionObject.imported = true; } } - - %file = findNextFileMultiExpr( %currentAddress @ "/*.*" ); } - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Finished Importing GUIs"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Finished Importing GUIs"); + projectImporterLog("==========================================="); } function processGUIntoAsset(%guiName, %file) { - $ProjectImporter::log.add("Processing GUI into asset: " @ %guiName @ ", file: " @ %file); + projectImporterLog("Processing GUI into asset: " @ %guiName @ ", file: " @ %file); %filePath = filePath(%file); %fileName = fileBase(%file); @@ -1177,9 +1679,9 @@ function processGUIntoAsset(%guiName, %file) %tamlpath = %assetPath @ %assetName @ ".asset.taml"; %scriptFile = ""; - if(isFile(%filePath @ "/" @ %fileName @ ".cs")) + if(isImportingFile(%filePath @ "/" @ %fileName @ ".tscript")) { - %scriptFile = %fileName @ ".cs"; + %scriptFile = %fileName @ ".tscript"; } %asset = new GUIAsset() @@ -1190,9 +1692,10 @@ function processGUIntoAsset(%guiName, %file) guiFile = fileName(%file); }; - TamlWrite(%asset, %tamlpath); - - AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + if(TamlWrite(%asset, %tamlpath)) + { + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + } return %tamlpath; } @@ -1209,9 +1712,9 @@ function processGUIntoAsset(%guiName, %file) //============================================================================== function beginPostFXImport() { - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Importing PostFXs"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Importing PostFXs"); + projectImporterLog("==========================================="); %count = PostFXManager.Count(); for(%i=0; %i < %count; %i++) @@ -1220,7 +1723,7 @@ function beginPostFXImport() if(isObject(%postEffect)) { - $ProjectImporter::log.add("Processing import of PostFX: " @ %postEffect.getName()); + projectImporterLog("Processing import of PostFX: " @ %postEffect.getName()); //$ProjectImporter::persistMgr.setDirty(%gui); } @@ -1228,9 +1731,9 @@ function beginPostFXImport() //$ProjectImporter::persistMgr.saveDirty(); - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Finished Importing PostFXs"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Finished Importing PostFXs"); + projectImporterLog("==========================================="); } //============================================================================== @@ -1239,36 +1742,50 @@ function beginPostFXImport() //============================================================================== function beginLevelImport() { - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Importing Level files"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Importing Level files"); + projectImporterLog("==========================================="); + //First, we need to go through and process all loose image files. This will + //get us shape assets, and if the import config deigns, material assets. %currentAddress = $ProjectImporter::modulePath; - //First, wipe out any files inside the folder first - %file = findFirstFileMultiExpr( %currentAddress @ "/*.*", true); - - while( %file !$= "" ) - { - %fileName = fileName(%file); - %fileExt = fileExt(%file); - %filePath = filePath(%file); - %fileBase = fileBase(%file); - - if(%fileExt $= ".mis") - { + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i); + %destinationPath = %rootFileSectionObject.fileDestination; + if(isFile(%file) && %rootFileSectionObject.fileExt $= ".mis" && %rootFileSectionObject.imported == false) + { + %fileName = fileName(%destinationPath); + %fileExt = fileExt(%destinationPath); + %fileBase = fileBase(%destinationPath); + %filePath = filePath(%destinationPath); + + if(!IsDirectory(filePath(%destinationPath))) + { + DirectoryHandler::createFolder(0, filePath(%destinationPath)); + } + + if(!pathCopy(%file, %destinationPath, false)) + { + projectImporterLog("ProjectImporter::beginLevelImport() - failed to copy level: " @ %file @ + " to destination: " @ %destinationPath); + continue; + } + %newAsset = false; $ProjectImporter::assetQuery.clear(); - %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %file); + %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, %destinationPath); if(%assetsFound == 0) { - ProjectImportWizardPage5-->processingText.setText("Processing Level Asset file: " @ %file); + //ProjectImportWizardPage5-->processingText.setText("Processing Level Asset file: " @ %file); Canvas.repaint(); - $ProjectImporter::log.add("Importing Level file: " @ %file); + projectImporterLog("Importing Level file: " @ %file); - %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%file).ModuleId; + %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%destinationPath).ModuleId; %assetName = %fileBase; @@ -1276,7 +1793,7 @@ function beginLevelImport() if(AssetDatabase.isDeclaredAsset(%moduleName @ ":" @ %assetName)) { - $ProjectImporter::log.add("Legacy Project Importer - trying to process a level into an asset that already exists"); + projectImporterLog("Legacy Project Importer - trying to process a level into an asset that already exists"); return false; } @@ -1301,24 +1818,28 @@ function beginLevelImport() } //Time to process the associated files - if(isFile(%filePath @ "/" @ %fileBase @ ".decal")) - { - %asset.decalsFile = %fileBase @ ".decal"; - } - if(isFile(%filePath @ "/" @ %fileBase @ ".forest")) - { - %asset.forestFile = %fileBase @ ".forest"; - } - if(isFile(%filePath @ "/" @ %fileBase @ ".nav")) - { - %asset.decalsFile = %fileBase @ ".nav"; - } - if(isFile(%filePath @ "/" @ %fileBase @ ".postfx.preset")) - { - %asset.postFXPresetFile = %fileBase @ ".postfx.preset"; - } - - if(isFile(%filePath @ "/" @ %fileBase @ ".png")) + if(isFile(%filePath @ "/" @ %fileBase @ ".decal")) + { + %asset.decalsFile = %fileBase @ ".decal"; + } + else if(isFile(%filePath @ "/" @ %fileBase @ "mis.decal")) + { + %asset.decalsFile = %fileBase @ "mis.decal"; + } + if(isFile(%filePath @ "/" @ %fileBase @ ".forest")) + { + %asset.forestFile = %fileBase @ ".forest"; + } + if(isFile(%filePath @ "/" @ %fileBase @ ".nav")) + { + %asset.decalsFile = %fileBase @ ".nav"; + } + if(isFile(%filePath @ "/" @ %fileBase @ ".postfx.preset")) + { + %asset.postFXPresetFile = %fileBase @ ".postfx.preset"; + } + + if(isFile(%filePath @ "/" @ %fileBase @ ".png")) %previewImageAsset = ImageAsset::getAssetIdByFilename(%filePath @ "/" @ %fileBase @ ".png"); else if(isFile(%filePath @ "/" @ %fileBase @ "_preview.png")) %previewImageAsset = ImageAsset::getAssetIdByFilename(%filePath @ "/" @ %fileBase @ "_preview.png"); @@ -1337,28 +1858,30 @@ function beginLevelImport() if(%previewImageAsset !$= "") { - %asset.addAssetDependencyField(previewImageAsset, %previewImageAsset); + %asset.addAssetDependencyField(previewImageAsset, %previewImageAsset); + } + + if(TamlWrite(%asset, %tamlpath)) + { + if(%newAsset) + { + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + + %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + } + else + { + %asset.refreshAsset(); } - - TamlWrite(%asset, %tamlpath); - - if(%newAsset) - { - %moduleDef = ModuleDatabase.findModule(%moduleName, 1); - %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); - } - else - { - %asset.refreshAsset(); } + + %rootFileSectionObject.imported = true; } - - %file = findNextFileMultiExpr( %currentAddress @ "/*.*" ); } - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Finished Importing Level files"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Finished Importing Level files"); + projectImporterLog("==========================================="); } //============================================================================== @@ -1397,9 +1920,9 @@ function ProjectImporter::deleteAssetDefinitions(%targetFolder) function doDeleteAssetDefinitions() { - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Deleting Asset Definitions"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Deleting Asset Definitions"); + projectImporterLog("==========================================="); %currentAddress = $deleteAssetDefsTargetFolder; @@ -1415,27 +1938,27 @@ function doDeleteAssetDefinitions() { if(fileDelete(%file)) { - $ProjectImporter::log.add("File: " @ %file @ " deleted successfully."); + projectImporterLog("File: " @ %file @ " deleted successfully."); } else { - $ProjectImporter::log.add("File: " @ %file @ " failed to delete."); + projectImporterLog("File: " @ %file @ " failed to delete."); } } %file = findNextFileMultiExpr( %currentAddress @ "/*.asset.taml" ); } - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Finished Deleting Asset Definitions"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Finished Deleting Asset Definitions"); + projectImporterLog("==========================================="); } function scanForDuplicateFiles(%toTestFile) { - $ProjectImporter::log.add("==========================================="); - $ProjectImporter::log.add("Scanning for duplicate files!"); - $ProjectImporter::log.add("==========================================="); + projectImporterLog("==========================================="); + projectImporterLog("Scanning for duplicate files!"); + projectImporterLog("==========================================="); //First, wipe out any files inside the folder first %file = findFirstFileMultiExpr( "*/*.*", true); @@ -1479,8 +2002,8 @@ function scanForDuplicateFiles(%toTestFile) if(%moduleName !$= "" && %testModuleName !$= "" && %moduleName $= %testModuleName) { //report the probable duplicate - $ProjectImporter::log.add("Probable duplicate asset detected!"); - $ProjectImporter::log.add("Files: " @ %file @ " and " @ %toTestFile @ " have matching names and exist within the same module!"); + projectImporterLog("Probable duplicate asset detected!"); + projectImporterLog("Files: " @ %file @ " and " @ %toTestFile @ " have matching names and exist within the same module!"); } } } @@ -1494,6 +2017,6 @@ function getImporterLogs() %lineCount = $ProjectImporter::importer.getActivityLogLineCount(); for(%i=0; %i < %lineCount; %i++) { - $ProjectImporter::log.add($ProjectImporter::importer.getActivityLogLine(%i)); + projectImporterLog($ProjectImporter::importer.getActivityLogLine(%i)); } } \ No newline at end of file From 728aa83481954fc43f52d387475c19352023a753 Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 20 Jan 2022 17:48:01 -0600 Subject: [PATCH 013/145] Comments and cleanup --- .../pre40/T3Dpre4ProjectImporter.tscript | 156 ++----- .../importers/pre40/pre40ImporterGuis.tscript | 7 + .../scripts/projectImporter.tscript | 421 ++++++++---------- 3 files changed, 222 insertions(+), 362 deletions(-) diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript index 693d22a6c..c494c5029 100644 --- a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript @@ -1,3 +1,7 @@ +//============================================================================== +// Initialization function that registers this importer to the main Project Importer +// allowing it to be selected/invoked in the main Project Importer wizard +//============================================================================== function T3Dpre4ProjectImporter::init() { //register this importer option to the project importer listing @@ -14,6 +18,10 @@ function T3Dpre4ProjectImporter::init() T3Dpre4ProjectImporter::init(); //kick off the setup +//============================================================================== +// Sets up and registers the pages for this particular version importer +// to the Project Importer for navigating through with the import process +//============================================================================== function T3Dpre4ProjectImporter::setupPages(%this) { ProjectImportWindow.addImporterPage(Pre40ImporterPage0); @@ -22,8 +30,9 @@ function T3Dpre4ProjectImporter::setupPages(%this) ProjectImportWindow.refreshPage(); } -// -// +//============================================================================== +// Sets up the target module +//============================================================================== function T3Dpre4ProjectImporter::setupModule(%this) { %newModuleName = $ProjectImporter::moduleName; @@ -98,117 +107,9 @@ function T3Dpre4ProjectImporter::setupModule(%this) AssetBrowser.refresh(); } -/*function T3Dpre4ProjectImporter::copyFiles(%this) -{ - %currentPage = ProjectImportWindow.getCurrentPage(); - - %currentPage-->fileCopyText.setText("Beginning copy of files to new module folder now. This may take a few minutes..."); - Canvas.repaint(); - - %file = findFirstFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*", true); - - while( %file !$= "" ) - { - %filePath = filePath(%file); - %fileName = fileName(%file); - %fileBase = fileBase(%file); - %fileExt = fileExt(%file); - - if(endsWith(%fileName, ".asset.taml")) - { - %fileBase = strreplace(%fileBase, ".asset", ""); - %fileExt = ".asset.taml"; - } - - if(%fileExt $= ".dll" || %fileExt $= ".log" || %fileExt $= ".exe" || %fileExt $= ".manifest"|| %fileExt $= ".h" || - %fileExt $= ".cpp" || %fileExt $= ".so" || %fileExt $= ".do" || %fileExt $= ".lib" ||%fileExt $= ".exp") - { - %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); - continue; - } - - //filter out some unneeded folders - %slashCount = getTokenCount(%filePath, "/"); - %topFolder = getToken(%filePath, "/", %slashCount-1); - if(%topFolder $= "") - %topFolder = getToken(%filePath, "/", %slashCount-2); - - if(%topFolder $= "creator" || %topFolder $= "tools" || %topFolder $= "web") - { - %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); - continue; - } - - %targetFilePath = strReplace(%file, $ProjectImporter::sourceContentFolder, $ProjectImporter::modulePath); - - %sanitizedFilename = sanitizeString(%fileBase); - if(startsWith(%sanitizedFilename, "_")) - { - %sanitizedFilename = substr(%sanitizedFilename, 1, -1); - } - if(%sanitizedFilename !$= %fileBase) - { - %targetFilePath = filePath(%targetFilePath) @ "/" @ %sanitizedFilename @ %fileExt; - } - - %targetFolder = filePath(%targetFilePath); - - if(!isDirectory(%targetFolder)) - { - DirectoryHandler::createFolder(0, %targetFolder); - } - - if(!pathCopy(%file, %targetFilePath, false)) - { - projectImporterLog("Legacy Project Importer, failed to copy file: " @ %file @ " to destination: " @ %targetFilePath); - } - - %file = findNextFileMultiExpr( $ProjectImporter::sourceContentFolder @ "/*.*" ); - } - - // - //Now that we've done that, we'll load and scan the module for asset defs - %file = findFirstFileMultiExpr( $ProjectImporter::modulePath @ "/*.asset.taml", true); - - while( %file !$= "" ) - { - %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%file).ModuleId; - %moduleDef = ModuleDatabase.findModule(%moduleName, 1); - - AssetDatabase.addDeclaredAsset(%moduleDef, %file); - - %file = findNextFileMultiExpr( $ProjectImporter::modulePath @ "/*.asset.taml" ); - } - // - - %currentPage-->fileCopyText.setValue("File copy done! Press Next to continue."); - - ProjectImportWindow-->nextButton.setActive(true); - Canvas.repaint(); -} - -function T3Dpre4ProjectImporter::processImportedFiles(%this) -{ - if($ProjectImporter::importMode $= "CoreAndTools") - { - $ProjectImporter::modulePath = "Core"; - %this.doImport(); - - $ProjectImporter::modulePath = "Tools"; - %this.doImport(); - } - else - { - %this.doImport(); - } - - %currentPage = ProjectImportWindow.getCurrentPage(); - - %currentPage-->processingText.setText("Processing of files done! Press Next to continue."); - ProjectImportWindow-->nextButton.setActive(true); - Canvas.repaint(); -}*/ - +//============================================================================== +// Import content file types such as images, sounds, materials, etc +//============================================================================== function T3Dpre4ProjectImporter::doContentImport(%this) { //Store off the current default import config @@ -226,6 +127,9 @@ function T3Dpre4ProjectImporter::doContentImport(%this) %this.beginSoundProfilesImport(); } +//============================================================================== +// Import script-based files like guis, levels and scripts +//============================================================================== function T3Dpre4ProjectImporter::doScriptImport(%this) { beginLevelImport(); @@ -240,6 +144,9 @@ function T3Dpre4ProjectImporter::doScriptImport(%this) EditorSettings.setValue("Assets/AssetImporDefaultConfig", %this.defaultConfig); } +//============================================================================== +// Writes out the importing file to the new destination +//============================================================================== function T3Dpre4ProjectImporter::writeImportingObject(%this, %arrayObj) { if(!isObject(%arrayObj) || %arrayObj.skip) @@ -301,7 +208,10 @@ function T3Dpre4ProjectImporter::writeImportingFiles(%this) } } -// +//============================================================================== +// Processes through the importing files for material definitions and generates +// the new assets into the destination module +//============================================================================== function T3Dpre4ProjectImporter::processMaterialObjects(%this, %arrayObj) { if(!isObject(%arrayObj)) @@ -456,7 +366,10 @@ function T3Dpre4ProjectImporter::beginMaterialFilesImport(%this) projectImporterLog("==========================================="); } -// +//============================================================================== +// Processes through the importing files for SFXProfile definitions and +// generates the new assest into the destination module +//============================================================================== function T3Dpre4ProjectImporter::processSoundProfileObjects(%this, %arrayObj) { if(!isObject(%arrayObj)) @@ -558,7 +471,11 @@ function T3Dpre4ProjectImporter::beginSoundProfilesImport(%this) projectImporterLog("==========================================="); } -// +//============================================================================== +// Processes through the importing files for scripted object definitions and +// updates their names and fields to be asset-compliant, converting filepaths +// to assetIds where valid +//============================================================================== function T3Dpre4ProjectImporter::processScripts(%this, %arrayObj) { if(!isObject(%arrayObj)) @@ -716,14 +633,15 @@ function T3Dpre4ProjectImporter::beginScriptFilesImport(%this) projectImporterLog("Legacy Project Importer - Processing of imported code files done!"); } -// +//============================================================================== +// Processes through the importing files for module and asset definitions and +// updates them to be compliant +//============================================================================== function T3Dpre4ProjectImporter::processModuleFile(%this, %moduleObj) { if(!isObject(%moduleObj)) return; - %moduleObj.echo(); - //really, we only care here about ensuring the file extensions are cleaned up for(%l=0; %l < %moduleObj.count(); %l++) { diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript index 4ad259602..816b5cf80 100644 --- a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript @@ -1,3 +1,7 @@ +//============================================================================== +// We first copy over binary files(images, shapes, sounds, etc) to the destination +// module, then run the processing/import on them to generate the assets +//============================================================================== function Pre40ImporterPage0::openPage(%this) { ProjectImportWindow-->nextButton.setActive(false); @@ -75,6 +79,9 @@ function Pre40ImporterPage0::openPage(%this) Canvas.repaint(); } +//============================================================================== +// This page actually invokes the processing of the script-based files and objects +//============================================================================== function Pre40ImporterPage1::openPage(%this) { ProjectImportWindow-->nextButton.setActive(false); diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index 8688df941..ab47a18a9 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -7,8 +7,24 @@ function ProjectImporter::beginProjectImport() Canvas.pushDialog(ProjectImportCtrl); } +//============================================================================== +// Wake-up and initial setup +//============================================================================== function ProjectImportWindow::onWake(%this) { + if(isObject($ProjectImporter::assetQuery)) + $ProjectImporter::assetQuery.delete(); + $ProjectImporter::assetQuery = new AssetQuery(); + + if(isObject($ProjectImporter::importer)) + $ProjectImporter::importer.delete(); + $ProjectImporter::importer = new AssetImporter(); + $ProjectImporter::importer.dumpLogs = false; //we handle the log dump outselves here + + if(isObject($ProjectImporter::persistMgr)) + $ProjectImporter::persistMgr.delete(); + $ProjectImporter::persistMgr = new PersistenceManager(); + if(!isObject($ProjectImporter::fileObject)) $ProjectImporter::fileObject = new FileObject(); @@ -49,6 +65,9 @@ function ProjectImportWindow::onWake(%this) } } +//============================================================================== +// Page Navigation +//============================================================================== function ProjectImportWindow::previousStep(%this) { if(%this.importStepNumber == 0) @@ -63,7 +82,7 @@ function ProjectImportWindow::previousStep(%this) function ProjectImportWindow::nextStep(%this) { - if(%this.importStepNumber == $ProjectImporter::importerPageList.count()) + if(%this.importStepNumber == $ProjectImporter::importerPageList.count()-1) { Canvas.popDialog(ProjectImportCtrl); return; @@ -157,11 +176,17 @@ function ProjectImportWindow::getCurrentPage(%this) return $ProjectImporter::importerPageList.getKey(%this.importStepNumber); } +//============================================================================== +// Welcome page +//============================================================================== function ProjectImportWizardPage0::openPage(%this) { ProjectImportWindow-->backButton.setHidden(true); } +//============================================================================== +// Select the specific version importer +//============================================================================== function ProjectImportWizardPage1::openPage(%this) { ProjectImportWindow-->backButton.setHidden(false); @@ -174,7 +199,9 @@ function ProjectImportWizardPage1::openPage(%this) } } -//Select destination folder +//============================================================================== +// Set Source Folder +//============================================================================== function ProjectImportWizardPage2::openPage(%this) { %version = ProjectImportWizardPage1-->previousContentVersionPopup.getSelected(); @@ -197,24 +224,21 @@ function ProjectImportWizardPage2::openPage(%this) $ProjectImporter::importTool = $ProjectImporter::importerList.getValue(%version); - //if(isObject($ProjectImporter::SFXDescriptionCache)) - // $ProjectImporter::SFXDescriptionCache.delete(); - - //$ProjectImporter::SFXDescriptionCache = new ArrayObject(); - - //if(isObject($ProjectImporter::ToRemoveObjectList)) - // $ProjectImporter::ToRemoveObjectList.delete(); - - //$ProjectImporter::ToRemoveObjectList = new ArrayObject(); - $ProjectImporter::importTool.setupPages(); //Have the importer register it's pages //And then add our final page $ProjectImporter::importerPageList.add(ProjectImportWizardFinalPage); } +//============================================================================== +// Prepwork for import and getting the target module name +//============================================================================== function ProjectImportWizardPage3::openPage(%this) { + projectImporterLog("==========================================="); + projectImporterLog("Beginning Project Import"); + projectImporterLog("==========================================="); + %dataFullPath = makeFullPath("data/"); %coreFullPath = makeFullPath("core/"); %toolsFullPath = makeFullPath("tools/"); @@ -251,67 +275,108 @@ function ProjectImportWizardPage3::openPage(%this) ProjectImportWizardPage3-->newModuleName.setText($ProjectImporter::moduleName); } - /*if(ProjectImportWizardPage2-->internalFolderBtn.isStateOn()) - { - $ProjectImporter::importMode = "InternalFolder"; - } - else if(ProjectImportWizardPage2-->externalFolderBtn.isStateOn()) - { - $ProjectImporter::importMode = "ExternalFolder"; - } - else if(ProjectImportWizardPage2-->coreAndToolsBtn.isStateOn()) - { - $ProjectImporter::importMode = "CoreAndTools"; - } - else - { - ProjectImportWindow.previousStep(); - toolsMessageBoxOK("Folder Type Required", "You must indicate if the folder is an internal or external folder."); - return; - } - - if($ProjectImporter::sourceContentFolder $= "" && $ProjectImporter::importMode !$= "CoreAndTools") - { - ProjectImportWindow.previousStep(); - toolsMessageBoxOK("Source Folder Required", "You must select the original folder to import files from."); - return; - } - - if($ProjectImporter::importMode $= "InternalFolder") - { - %moduleDef = AssetBrowser.dirHandler.getModuleFromAddress(makeRelativePath($ProjectImporter::sourceContentFolder)); - if(isObject(%moduleDef)) - { - //already a valid module in place so just skip this step - $ProjectImporter::useExistingModule = true; - $ProjectImporter::moduleName = %moduleDef.moduleId; - $ProjectImporter::modulePath = "data/" @ $ProjectImporter::moduleName; - ProjectImportWindow.setStep(4); - } - } - else if($ProjectImporter::importMode $= "ExternalFolder") - { - %slashCount = getTokenCount($ProjectImporter::sourceContentFolder, "/"); - %topFolder = getToken($ProjectImporter::sourceContentFolder, "/", %slashCount-1); - if(%topFolder $= "") - %topFolder = getToken($ProjectImporter::sourceContentFolder, "/", %slashCount-2); - - //clean up invalid characters and stuff - %topFolder = sanitizeString(%topFolder); - - $ProjectImporter::useExistingModule = false; - $ProjectImporter::moduleName = %topFolder; //preseed the module name - $ProjectImporter::modulePath = "data/" @ $ProjectImporter::moduleName; - - ProjectImportWizardPage3-->newModuleName.setText($ProjectImporter::moduleName); - } - else if($ProjectImporter::importMode $= "CoreAndTools") - { - ProjectImportWindow.setStep(5); - }*/ } -// +//============================================================================== +// Run the preprocessing of all incoming files +//============================================================================== +function ProjectImportWizardPage4::openPage(%this) +{ + ProjectImportWindow-->preprocessCompleteText.setHidden(true); + + Canvas.repaint(); + + ProjectImportWindow-->backButton.setHidden(true); + ProjectImportWindow-->nextButton.setActive(false); + + if(!$ProjectImporter::useExistingModule) + $ProjectImporter::moduleName = ProjectImportWizardPage3-->newModuleName.getText(); + + $ProjectImporter::modulePath = "data/" @ $ProjectImporter::moduleName; + + if(!$ProjectImporter::useExistingModule) + $ProjectImporter::importTool.setupModule(); + + //Do some sanity checking here to sidestep the copy if we're already in-place + %sourcePath = $ProjectImporter::sourceContentFolder; + %targetPath = makeFullPath($ProjectImporter::modulePath); + + preprocessImportingFiles(); + + //if we gen'd a new module setup, double check we didn't copy over a module script file under a legacy extension + /*if(!$ProjectImporter::useExistingModule) + { + %newModuleName = $ProjectImporter::moduleName; + %moduleFilePath = "data/" @ %newModuleName; + + if($TorqueScriptFileExtension !$= "cs") + { + %moduleScriptFilePath = %moduleFilePath @ "/" @ %newModuleName @ ".cs"; + if(isFile(%moduleScriptFilePath)) + { + //yep, that exists, so we'll assume it was the file we wanted, so remove the generated one + fileDelete(%moduleFilePath @ "/" @ %newModuleName @ "." @ $TorqueScriptFileExtension); + } + } + }*/ + + ProjectImportWindow-->nextButton.setActive(true); + ProjectImportWindow-->preprocessCompleteText.setHidden(false); + + Canvas.repaint(); +} + +//============================================================================== +// Write out the logs and clean up +//============================================================================== +function ProjectImportWizardFinalPage::openPage(%this) +{ + projectImporterLog("==========================================="); + projectImporterLog("Finished Project Import"); + projectImporterLog("==========================================="); + + //writing console log + %logFileObj = new FileObject(); + + %logFileName = "tools/logs/LegacyProjectImport_" @ getTimestamp() @ ".log"; + + if(%logFileObj.openForWrite(%logFileName)) + { + for(%i=0; %i < $ProjectImporter::log.count(); %i++) + { + %logFileObj.writeLine($ProjectImporter::log.getKey(%i)); + } + + %logFileObj.close(); + } + + %logFileObj.delete(); + + $ProjectImporter::assetQuery.delete(); + $ProjectImporter::importer.delete(); + $ProjectImporter::persistMgr.delete(); + + AssetBrowser.refresh(); //update the AB just in case +} + +//============================================================================== +// Registers a version importer's page for display in the wizard +//============================================================================== +function ProjectImportWindow::addImporterPage(%this, %page) +{ + ProejctImportPageContainer.add(%page); + $ProjectImporter::importerPageList.add(%page); +} + +//============================================================================== +// Utility functions needed for processing and importing files. These are common +// functions that'll pretty much be used regardless of version being targeted +//============================================================================== +//============================================================================== +// Runs through the files in the source directory and preprocessing them. +// All valid files are added to a list, and script-based files are pre-parsed +// so the importer can easily process their contents later +//============================================================================== function preprocessImportingFiles() { //======================================================== @@ -667,173 +732,11 @@ function preprocessImportingFiles() $ProjectImporter::fileObject.close(); } } -// - -function ProjectImportWizardPage4::openPage(%this) -{ - ProjectImportWindow-->preprocessCompleteText.setHidden(true); - - Canvas.repaint(); - - ProjectImportWindow-->backButton.setHidden(true); - ProjectImportWindow-->nextButton.setActive(false); - - if(!$ProjectImporter::useExistingModule) - $ProjectImporter::moduleName = ProjectImportWizardPage3-->newModuleName.getText(); - - $ProjectImporter::modulePath = "data/" @ $ProjectImporter::moduleName; - - if(!$ProjectImporter::useExistingModule) - $ProjectImporter::importTool.setupModule(); - - //Do some sanity checking here to sidestep the copy if we're already in-place - %sourcePath = $ProjectImporter::sourceContentFolder; - %targetPath = makeFullPath($ProjectImporter::modulePath); - - preprocessImportingFiles(); - - //if we gen'd a new module setup, double check we didn't copy over a module script file under a legacy extension - /*if(!$ProjectImporter::useExistingModule) - { - %newModuleName = $ProjectImporter::moduleName; - %moduleFilePath = "data/" @ %newModuleName; - - if($TorqueScriptFileExtension !$= "cs") - { - %moduleScriptFilePath = %moduleFilePath @ "/" @ %newModuleName @ ".cs"; - if(isFile(%moduleScriptFilePath)) - { - //yep, that exists, so we'll assume it was the file we wanted, so remove the generated one - fileDelete(%moduleFilePath @ "/" @ %newModuleName @ "." @ $TorqueScriptFileExtension); - } - } - }*/ - - ProjectImportWindow-->nextButton.setActive(true); - ProjectImportWindow-->preprocessCompleteText.setHidden(false); - - Canvas.repaint(); -} - -function ProjectImportWizardPage5::openPage(%this) -{ - ProjectImportWindow-->nextButton.setActive(false); - Canvas.repaint(); - - $ProjectImporter::importTool.processImportedFiles(); -} - -function ProjectImportWizardPage6::openPage(%this) -{ - ProjectImportWindow-->nextButton.setActive(false); - Canvas.repaint(); - - if($ProjectImporter::importMode $= "CoreAndTools") - { - $ProjectImporter::modulePath = "Core"; - $ProjectImporter::importTool.processScriptExtensions(); - - $ProjectImporter::modulePath = "Tools"; - $ProjectImporter::importTool.processScriptExtensions(); - } - else - { - $ProjectImporter::importTool.processScriptExtensions(); - } - - //All good? now go through and wipe any objects flagged in our files for deletion - %objRemovePM = new PersistenceManager(); - - for(%o = 0; %o < $ProjectImporter::ToRemoveObjectList.count(); %o++) - { - %name = $ProjectImporter::ToRemoveObjectList.getKey(%o); - %file = getField($ProjectImporter::ToRemoveObjectList.getValue(%o),0); - - if(%name !$= "" && isFile(%file)) - { - if(!isObject(%name)) - { - //spoof it - %tmpObj = new SimObject(%name); - %objRemovePM.setDirty(%name, %file); - } - %objRemovePM.removeObjectFromFile(%name, %file); - - %tmpObj.delete(); - } - } -} - -function ProjectImportWizardFinalPage::openPage(%this) -{ - //writing console log - %logFileObj = new FileObject(); - - %logFileName = "tools/logs/LegacyProjectImport_" @ getTimestamp() @ ".log"; - - if(%logFileObj.openForWrite(%logFileName)) - { - for(%i=0; %i < $ProjectImporter::log.count(); %i++) - { - %logFileObj.writeLine($ProjectImporter::log.getKey(%i)); - } - - %logFileObj.close(); - } - - %logFileObj.delete(); -} - -// -function ProjectImportWindow::addImporterPage(%this, %page) -{ - ProejctImportPageContainer.add(%page); - $ProjectImporter::importerPageList.add(%page); -} -// - -function beginProjectImport() -{ - projectImporterLog("==========================================="); - projectImporterLog("Beginning Project Import"); - projectImporterLog("==========================================="); - - $ProjectImporter::assetQuery = new AssetQuery(); - $ProjectImporter::importer = new AssetImporter(); - $ProjectImporter::importer.dumpLogs = false; //we handle the log dump outselves here - $ProjectImporter::persistMgr = new PersistenceManager(); - - //beginMaterialImport(); - - //beginTerrainMaterialImport(); - - //beginShapeImport(); - - beginImageImport(); - - beginDatablockImport(); - - beginGUIImport(); - - beginTerrainImport(); - - //postFX imports'll need to look up render target names and ensure assets for those exist - //otherwise they need to be generated - beginPostFXImport(); - - beginMiscObjectImport(); - - $ProjectImporter::assetQuery.delete(); - $ProjectImporter::importer.delete(); - $ProjectImporter::persistMgr.delete(); - - projectImporterLog("==========================================="); - projectImporterLog("Finished Project Import"); - projectImporterLog("==========================================="); - - AssetBrowser.refresh(); //update the AB just in case -} + +//============================================================================== +// Sanitized a filename so that it doesn't contain any invalid formatting/characters +//============================================================================== function sanitizeFilename(%file) { if(startsWith(%file, "./")) @@ -919,6 +822,9 @@ function sanitizeFilename(%file) //} } +//============================================================================== +// Checks if the file in question is part of our pre-scanned list of importing files +//============================================================================== function isImportingFile(%checkFile) { for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) @@ -932,6 +838,10 @@ function isImportingFile(%checkFile) return false; } +//============================================================================== +// Takes a filename lacking an extension and then checks common file extensions +// to see if we can find the actual file in question +//============================================================================== function testFilenameExtensions(%filename) { %ext = fileExt(%filename); @@ -966,6 +876,9 @@ function testFilenameExtensions(%filename) return %filename; } +//============================================================================== +// Parses a line from a script to replace the original field name with the new one +//============================================================================== function processLegacyField(%line, %originalFieldName, %newFieldName) { if(!strIsMatchExpr("*"@%originalFieldName@"=*;*", %line) && @@ -1078,6 +991,9 @@ function processLegacyField(%line, %originalFieldName, %newFieldName) } } +//============================================================================== +// Parses a line from a shape constructor file to asset-ify addSequence() calls +//============================================================================== function processLegacyShapeConstructorField(%line) { if(!strIsMatchExpr("*%this.addSequence(\"*);", %line)) @@ -1129,6 +1045,9 @@ function processLegacyShapeConstructorField(%line) } } +//============================================================================== +// Replaces the name of the object in the declaration line +//============================================================================== function renameObjectName(%object, %newName) { for(%e=0; %e < %object.count(); %e++) @@ -1153,6 +1072,9 @@ function renameObjectName(%object, %newName) } } +//============================================================================== +// Find the value of an object's field +//============================================================================== function findObjectField(%object, %fieldName) { %return = ""; @@ -1213,6 +1135,9 @@ function findObjectField(%object, %fieldName) return %return; } +//============================================================================== +// Sets the value of an object's field +//============================================================================== function setObjectField(%object, %fieldName, %newValue) { for(%e=0; %e < %object.count(); %e++) @@ -1278,6 +1203,10 @@ function setObjectField(%object, %fieldName, %newValue) } } +//============================================================================== +// Takes a string and adds it to the importer's log. Optionally can print the line +// directly to console for debugging purposes +//============================================================================== function projectImporterLog(%line) { if($ProjectImporter::writeToConsole) @@ -1701,12 +1630,6 @@ function processGUIntoAsset(%guiName, %file) } //============================================================================== -//============================================================================== -//Misc Object Type Converion -//============================================================================== - -//============================================================================== - //============================================================================== //PostFX conversion //============================================================================== @@ -1885,6 +1808,10 @@ function beginLevelImport() } //============================================================================== +//============================================================================== +// Cleas out existing *.asset.taml files from a target. Only really used for +// testing purposes currently. +//============================================================================== function deleteAssetDefinitions() { %dlg = new OpenFolderDialog() @@ -1954,6 +1881,10 @@ function doDeleteAssetDefinitions() projectImporterLog("==========================================="); } +//============================================================================== +// Tests a file in the game dir to see if there's a possible duplicate file that +// may cause an asset collision +//============================================================================== function scanForDuplicateFiles(%toTestFile) { projectImporterLog("==========================================="); @@ -2012,6 +1943,10 @@ function scanForDuplicateFiles(%toTestFile) } } +//============================================================================== +// Pulls the logs from the asset importer and adds it to the project importer's +// logs +//============================================================================== function getImporterLogs() { %lineCount = $ProjectImporter::importer.getActivityLogLineCount(); From ed13bdfdd297f34305de58d0e1b64e0bb4c3a1b5 Mon Sep 17 00:00:00 2001 From: JeffR Date: Fri, 21 Jan 2022 16:01:44 -0600 Subject: [PATCH 014/145] Changes the -> syntax check from exclusively checking simgroups to checking simsets, allowing both to be used --- Engine/source/console/compiledEval.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Engine/source/console/compiledEval.cpp b/Engine/source/console/compiledEval.cpp index c439f57bf..3a6aa76e5 100644 --- a/Engine/source/console/compiledEval.cpp +++ b/Engine/source/console/compiledEval.cpp @@ -1620,17 +1620,17 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa ++ip; // To skip the recurse flag if the object wasnt found if (curObject) { - SimGroup* group = dynamic_cast(curObject); - if (group) + SimSet* set = dynamic_cast(curObject); + if (set) { StringTableEntry intName = StringTable->insert(stack[_STK].getString()); bool recurse = code[ip - 1]; - SimObject* obj = group->findObjectByInternalName(intName, recurse); + SimObject* obj = set->findObjectByInternalName(intName, recurse); stack[_STK].setInt(obj ? obj->getId() : 0); } else { - Con::errorf(ConsoleLogEntry::Script, "%s: Attempt to use -> on non-group %s of class %s.", getFileLine(ip - 2), curObject->getName(), curObject->getClassName()); + Con::errorf(ConsoleLogEntry::Script, "%s: Attempt to use -> on non-set %s of class %s.", getFileLine(ip - 2), curObject->getName(), curObject->getClassName()); stack[_STK].setInt(0); } } From bed3be278c5d6395e34fb15b81b38a71bf25cc7e Mon Sep 17 00:00:00 2001 From: OTHGMars Date: Fri, 21 Jan 2022 19:47:41 -0500 Subject: [PATCH 015/145] GuiBitmapCtrl named texture fixes. Adds StringTableEntry when bitmap is set via setBitmapHandle. Prevents existing bitmap handles from being dropped in onWake (they are preserved in onSleep). --- Engine/source/gui/controls/guiBitmapCtrl.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Engine/source/gui/controls/guiBitmapCtrl.cpp b/Engine/source/gui/controls/guiBitmapCtrl.cpp index 82a106bcf..499311831 100644 --- a/Engine/source/gui/controls/guiBitmapCtrl.cpp +++ b/Engine/source/gui/controls/guiBitmapCtrl.cpp @@ -98,7 +98,8 @@ bool GuiBitmapCtrl::onWake() return false; setActive(true); - setBitmap(getBitmap()); + if (mBitmapName != StringTable->insert("texhandle")) + setBitmap(getBitmap()); return true; } @@ -152,7 +153,7 @@ void GuiBitmapCtrl::setBitmapHandle(GFXTexHandle handle, bool resize) { mBitmap = handle; - mBitmapName = String("texhandle"); + mBitmapName = StringTable->insert("texhandle"); // Resize the control to fit the bitmap if (resize) From eeff4d858a27e048eba6d3f6314f0aeafaa660d7 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sat, 22 Jan 2022 03:27:22 -0600 Subject: [PATCH 016/145] clean up ambiguous reference --- Engine/source/T3D/assets/assetImporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index 7bb109f02..de603d1fc 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -2100,7 +2100,7 @@ void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 m if (imgFileName.isNotEmpty()) filePath = imgFileName; else - filePath = ""; //no luck, so we just won't try importing in the image + filePath = Torque::Path(""); //no luck, so we just won't try importing in the image } } From 630285def638f98538925f30c8aaa7fca811621c Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 30 Jan 2022 11:50:16 -0600 Subject: [PATCH 017/145] Shifts handling of material and terrain material definitions to be written into the asset definition taml file instead of having an extra loose file Also updates importers to correctly handle this change Adds ability for taml XML serialization to properly assign array'd fields Adds 'inheritFrom' field to simobjects for when objects with parent objects are serialized AssetBase how inherits from SimGroup so it can have objects like material definitions embedded in them for save/load in the taml definition file Updated loading/handling logic in terrain material asset to be more similar to regular material assets --- Engine/source/T3D/assets/ImageAsset.cpp | 4 +- Engine/source/T3D/assets/MaterialAsset.cpp | 70 +++- Engine/source/T3D/assets/MaterialAsset.h | 4 + .../T3D/assets/TerrainMaterialAsset.cpp | 322 ++++++++++++++++-- .../source/T3D/assets/TerrainMaterialAsset.h | 53 ++- Engine/source/T3D/assets/assetImporter.cpp | 206 +++-------- Engine/source/assets/assetBase.h | 4 +- Engine/source/assets/assetDefinition.h | 4 +- Engine/source/console/simObject.cpp | 51 ++- Engine/source/console/simObject.h | 5 + .../source/materials/materialDefinition.cpp | 3 +- .../persistence/taml/xml/tamlXmlReader.cpp | 18 +- .../tools/assetBrowser/assetImportConfigs.xml | 3 +- .../assetBrowser/scripts/assetBrowser.tscript | 1 - .../scripts/assetTypes/material.tscript | 8 +- .../assetTypes/terrainMaterial.tscript | 58 ++-- .../scripts/materialEditor.ed.tscript | 18 +- .../pre40/T3Dpre4ProjectImporter.tscript | 166 ++++++--- .../scripts/projectImporter.tscript | 87 ++++- .../interfaces/terrainMaterialDlg.ed.tscript | 24 +- 20 files changed, 791 insertions(+), 318 deletions(-) diff --git a/Engine/source/T3D/assets/ImageAsset.cpp b/Engine/source/T3D/assets/ImageAsset.cpp index 2c5f9f341..d49cfbf85 100644 --- a/Engine/source/T3D/assets/ImageAsset.cpp +++ b/Engine/source/T3D/assets/ImageAsset.cpp @@ -58,7 +58,7 @@ StringTableEntry ImageAsset::smNoImageAssetFallback = NULL; IMPLEMENT_CONOBJECT(ImageAsset); -ConsoleType(ImageAssetPtr, TypeImageAssetPtr, const char*, ASSET_ID_FIELD_PREFIX) +ConsoleType(ImageAssetPtr, TypeImageAssetPtr, const char*, "") //----------------------------------------------------------------------------- @@ -85,7 +85,7 @@ ConsoleSetType(TypeImageAssetPtr) Con::warnf("(TypeImageAssetPtr) - Cannot set multiple args to a single asset."); } -ConsoleType(assetIdString, TypeImageAssetId, const char*, ASSET_ID_FIELD_PREFIX) +ConsoleType(assetIdString, TypeImageAssetId, const char*, "") ConsoleGetType(TypeImageAssetId) { diff --git a/Engine/source/T3D/assets/MaterialAsset.cpp b/Engine/source/T3D/assets/MaterialAsset.cpp index f2197cf01..6eb4ea200 100644 --- a/Engine/source/T3D/assets/MaterialAsset.cpp +++ b/Engine/source/T3D/assets/MaterialAsset.cpp @@ -154,8 +154,9 @@ void MaterialAsset::initPersistFields() Parent::initPersistFields(); //addField("shaderGraph", TypeRealString, Offset(mShaderGraphFile, MaterialAsset), ""); - addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, MaterialAsset), - &setScriptFile, &getScriptFile, "Path to the file containing the material definition."); + //addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, MaterialAsset), + // &setScriptFile, &getScriptFile, "Path to the file containing the material definition."); + addField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, MaterialAsset), ""); addField("materialDefinitionName", TypeString, Offset(mMatDefinitionName, MaterialAsset), "Name of the material definition this asset is for."); } @@ -173,7 +174,16 @@ void MaterialAsset::initializeAsset() return; } - if (Torque::FS::IsScriptFile(mScriptPath)) + if (mMatDefinitionName == StringTable->insert("DetailBlue")) + { + bool asdfsd = true; + } + + if (size() != 0 && mScriptPath == StringTable->EmptyString()) + { + mLoadedState = EmbeddedDefinition; + } + else if (Torque::FS::IsScriptFile(mScriptPath)) { if (!Sim::findObject(mMatDefinitionName)) { @@ -230,7 +240,6 @@ void MaterialAsset::setScriptFile(const char* pScriptFile) // Sanity! AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file."); - // Fetch image file. pScriptFile = StringTable->insert(pScriptFile, true); // Update. @@ -245,9 +254,28 @@ void MaterialAsset::setScriptFile(const char* pScriptFile) void MaterialAsset::loadMaterial() { if (mMaterialDefinition) - SAFE_DELETE(mMaterialDefinition); + { + mMaterialDefinition->safeDeleteObject(); + } - if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString()) + if (mLoadedState == EmbeddedDefinition) + { + if (size() != 0) + { + for (U32 i = 0; i < size(); i++) + { + mMaterialDefinition = dynamic_cast(getObject(i)); + if (mMaterialDefinition) + { + mLoadedState = Ok; + mMaterialDefinition->setInternalName(getAssetId()); + mMaterialDefinition->reload(); + return; + } + } + } + } + else if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString()) { Material* matDef; if (!Sim::findObject(mMatDefinitionName, matDef)) @@ -260,7 +288,7 @@ void MaterialAsset::loadMaterial() mMaterialDefinition = matDef; mLoadedState = Ok; - + mMaterialDefinition->setInternalName(getAssetId()); mMaterialDefinition->reload(); return; } @@ -296,11 +324,11 @@ U32 MaterialAsset::getAssetByMaterialName(StringTableEntry matName, AssetPtrmLoadedState == BadFileReference) { - Con::warnf("ShapeAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, and fallback asset reported error of Bad File Reference.", matName); + Con::warnf("MaterialAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, and fallback asset reported error of Bad File Reference.", matName); return AssetErrCode::BadFileReference; } - Con::warnf("ShapeAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, utilizing fallback asset", matName); + Con::warnf("MaterialAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, utilizing fallback asset", matName); (*matAsset)->mLoadedState = AssetErrCode::UsingFallback; return AssetErrCode::UsingFallback; @@ -388,6 +416,17 @@ U32 MaterialAsset::getAssetById(StringTableEntry assetId, AssetPtr MaterialAsset::findMaterialDefinitionByAssetId(StringTableEntry assetId) +{ + SimSet* matSet = MATMGR->getMaterialSet(); + if (matSet) + { + SimObjectPtr matDef = dynamic_cast(matSet->findObjectByInternalName(assetId)); + return matDef; + } + return nullptr; +} + #ifdef TORQUE_TOOLS DefineEngineStaticMethod(MaterialAsset, getAssetIdByMaterialName, const char*, (const char* materialName), (""), "Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n" @@ -396,6 +435,19 @@ DefineEngineStaticMethod(MaterialAsset, getAssetIdByMaterialName, const char*, ( return MaterialAsset::getAssetIdByMaterialName(StringTable->insert(materialName)); } +//MaterialAsset::findMaterialDefinitionByAssetId("Prototyping:Detail") +DefineEngineStaticMethod(MaterialAsset, findMaterialDefinitionByAssetId, S32, (const char* assetId), (""), + "Queries the MaterialSet to see if any MaterialDefinition exists that is associated to the provided assetId.\n" + "@return The MaterialDefinition Id associated to the assetId, if any") +{ + SimObjectPtr matDef = MaterialAsset::findMaterialDefinitionByAssetId(StringTable->insert(assetId)); + if (matDef.isNull()) + return SimObjectId(0); + else + return matDef->getId(); +} + + DefineEngineMethod(MaterialAsset, getScriptPath, const char*, (), , "Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n" "@return The AssetId of the associated asset, if any.") diff --git a/Engine/source/T3D/assets/MaterialAsset.h b/Engine/source/T3D/assets/MaterialAsset.h index a6dff23c8..561f02fe5 100644 --- a/Engine/source/T3D/assets/MaterialAsset.h +++ b/Engine/source/T3D/assets/MaterialAsset.h @@ -48,7 +48,9 @@ #include "sim/netConnection.h" #endif +#ifndef _GUI_INSPECTOR_TYPES_H_ #include "gui/editor/guiInspectorTypes.h" +#endif #include "materials/matTextureTarget.h" #include "materials/materialDefinition.h" @@ -75,6 +77,7 @@ public: { ScriptLoaded = AssetErrCode::Extended, DefinitionAlreadyExists, + EmbeddedDefinition, Extended }; @@ -108,6 +111,7 @@ public: /// AssetId of matching asset. static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName); static U32 getAssetById(StringTableEntry assetId, AssetPtr* materialAsset); + static SimObjectPtr findMaterialDefinitionByAssetId(StringTableEntry assetId); static U32 getAssetByMaterialName(StringTableEntry matName, AssetPtr* matAsset); /// Declare Console Object. diff --git a/Engine/source/T3D/assets/TerrainMaterialAsset.cpp b/Engine/source/T3D/assets/TerrainMaterialAsset.cpp index ee5a36004..3ef54d856 100644 --- a/Engine/source/T3D/assets/TerrainMaterialAsset.cpp +++ b/Engine/source/T3D/assets/TerrainMaterialAsset.cpp @@ -40,6 +40,10 @@ #include "assets/assetPtr.h" #endif +#include "T3D/assets/assetImporter.h" + +StringTableEntry TerrainMaterialAsset::smNoTerrainMaterialAssetFallback = NULL; + //----------------------------------------------------------------------------- IMPLEMENT_CONOBJECT(TerrainMaterialAsset); @@ -85,6 +89,35 @@ ConsoleSetType(TypeTerrainMaterialAssetPtr) Con::warnf("(TypeTerrainMaterialAssetPtr) - Cannot set multiple args to a single asset."); } + +ConsoleType(assetIdString, TypeTerrainMaterialAssetId, const char*, ASSET_ID_FIELD_PREFIX) + +ConsoleGetType(TypeTerrainMaterialAssetId) +{ + // Fetch asset Id. + return *((const char**)(dptr)); +} + +ConsoleSetType(TypeTerrainMaterialAssetId) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset Id. + StringTableEntry* assetId = (StringTableEntry*)(dptr); + + // Update asset value. + *assetId = StringTable->insert(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeTerrainMaterialAssetId) - Cannot set multiple args to a single asset."); +} //----------------------------------------------------------------------------- TerrainMaterialAsset::TerrainMaterialAsset() @@ -92,24 +125,41 @@ TerrainMaterialAsset::TerrainMaterialAsset() mScriptFile = StringTable->EmptyString(); mScriptPath = StringTable->EmptyString(); mMatDefinitionName = StringTable->EmptyString(); + mMaterialDefinition = nullptr; + mFXMaterialDefinition = nullptr; } //----------------------------------------------------------------------------- TerrainMaterialAsset::~TerrainMaterialAsset() { + if (mMaterialDefinition) + mMaterialDefinition->safeDeleteObject(); + if (mFXMaterialDefinition) + mFXMaterialDefinition->safeDeleteObject(); } //----------------------------------------------------------------------------- +void TerrainMaterialAsset::consoleInit() +{ + Parent::consoleInit(); + Con::addVariable("$Core::NoTerrainMaterialAssetFallback", TypeString, &smNoTerrainMaterialAssetFallback, + "The assetId of the material to display when the requested material asset is missing.\n" + "@ingroup GFX\n"); + + smNoTerrainMaterialAssetFallback = StringTable->insert(Con::getVariable("$Core::NoTerrainMaterialAssetFallback")); +} + void TerrainMaterialAsset::initPersistFields() { // Call parent. Parent::initPersistFields(); //addField("shaderGraph", TypeRealString, Offset(mShaderGraphFile, TerrainMaterialAsset), ""); - addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, TerrainMaterialAsset), - &setScriptFile, &getScriptFile, "Path to the file containing the material definition."); + //addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, TerrainMaterialAsset), + // &setScriptFile, &getScriptFile, "Path to the file containing the material definition."); + addField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, TerrainMaterialAsset), ""); addField("materialDefinitionName", TypeString, Offset(mMatDefinitionName, TerrainMaterialAsset), "Name of the material definition this asset is for."); } @@ -121,28 +171,71 @@ void TerrainMaterialAsset::initializeAsset() mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) - Con::executeFile(mScriptPath, false, false); + if (mMatDefinitionName == StringTable->EmptyString()) + { + mLoadedState = Failed; + return; + } + + if (mMatDefinitionName == StringTable->insert("DetailBlue")) + { + bool asdfsd = true; + } + + if (size() != 0 && mScriptPath == StringTable->EmptyString()) + { + mLoadedState = EmbeddedDefinition; + } + else if (Torque::FS::IsScriptFile(mScriptPath)) + { + if (!Sim::findObject(mMatDefinitionName)) + { + if (Con::executeFile(mScriptPath, false, false)) + { + mLoadedState = ScriptLoaded; + } + else + { + mLoadedState = Failed; + } + } + else + { + mLoadedState = DefinitionAlreadyExists; + } + } + + loadMaterial(); } void TerrainMaterialAsset::onAssetRefresh() { mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) - Con::executeFile(mScriptPath, false, false); - - if (mMatDefinitionName != StringTable->EmptyString()) + if (mMatDefinitionName == StringTable->EmptyString()) { - TerrainMaterial* matDef; - if (!Sim::findObject(mMatDefinitionName, matDef)) - { - Con::errorf("TerrainMaterialAsset: Unable to find the Material %s", mMatDefinitionName); + mLoadedState = Failed; return; } - //matDef->reload(); + if (Torque::FS::IsScriptFile(mScriptPath)) + { + //Since we're refreshing, we can assume that the file we're executing WILL have an existing definition. + //But that definition, whatever it is, is the 'correct' one, so we enable the Replace Existing behavior + //when the engine encounters a named object conflict. + String redefineBehaviorPrev = Con::getVariable("$Con::redefineBehavior"); + Con::setVariable("$Con::redefineBehavior", "replaceExisting"); + + if (Con::executeFile(mScriptPath, false, false)) + mLoadedState = ScriptLoaded; + else + mLoadedState = Failed; + + //And now that we've executed, switch back to the prior behavior + Con::setVariable("$Con::redefineBehavior", redefineBehaviorPrev.c_str()); } + + loadMaterial(); } void TerrainMaterialAsset::setScriptFile(const char* pScriptFile) @@ -152,10 +245,6 @@ void TerrainMaterialAsset::setScriptFile(const char* pScriptFile) pScriptFile = StringTable->insert(pScriptFile, true); - // Ignore no change, - if (pScriptFile == mScriptFile) - return; - // Update. mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile; @@ -165,41 +254,185 @@ void TerrainMaterialAsset::setScriptFile(const char* pScriptFile) //------------------------------------------------------------------------------ +void TerrainMaterialAsset::loadMaterial() +{ + if (mMaterialDefinition) + mMaterialDefinition->safeDeleteObject(); + if (mFXMaterialDefinition) + mFXMaterialDefinition->safeDeleteObject(); + + if (mLoadedState == EmbeddedDefinition) + { + if (size() != 0) + { + for (U32 i = 0; i < size(); i++) + { + mMaterialDefinition = dynamic_cast(getObject(i)); + if (mMaterialDefinition) + { + mLoadedState = Ok; + mMaterialDefinition->setInternalName(getAssetId()); + continue; + } + + //Otherwise, check if it's our FX material + mFXMaterialDefinition = dynamic_cast(getObject(i)); + if (mFXMaterialDefinition) + { + //mMaterialDefinition->setInternalName(getAssetId()); + mFXMaterialDefinition->reload(); + continue; + } + + } + } + } + else if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString()) + { + TerrainMaterial* matDef; + if (!Sim::findObject(mMatDefinitionName, matDef)) + { + Con::errorf("TerrainMaterialAsset: Unable to find the Material %s", mMatDefinitionName); + mLoadedState = BadFileReference; + return; + } + + mMaterialDefinition = matDef; + + mLoadedState = Ok; + mMaterialDefinition->setInternalName(getAssetId()); + return; + } + + mLoadedState = Failed; +} + +//------------------------------------------------------------------------------ + void TerrainMaterialAsset::copyTo(SimObject* object) { // Call to parent. Parent::copyTo(object); } -StringTableEntry TerrainMaterialAsset::getAssetIdByMaterialName(StringTableEntry matName) +//------------------------------------------------------------------------------ +U32 TerrainMaterialAsset::getAssetByMaterialName(StringTableEntry matName, AssetPtr* matAsset) { - StringTableEntry materialAssetId = StringTable->EmptyString(); - - AssetQuery* query = new AssetQuery(); - U32 foundCount = AssetDatabase.findAssetType(query, "TerrainMaterialAsset"); - if (foundCount == 0) + AssetQuery query; + U32 foundAssetcount = AssetDatabase.findAssetType(&query, "TerrainMaterialAsset"); + if (foundAssetcount == 0) { //Didn't work, so have us fall back to a placeholder asset - materialAssetId = StringTable->insert("Core_Rendering:noMaterial"); + matAsset->setAssetId(TerrainMaterialAsset::smNoTerrainMaterialAssetFallback); + + if (matAsset->isNull()) + { + //Well that's bad, loading the fallback failed. + Con::warnf("TerrainMaterialAsset::getAssetByMaterialName - Finding of asset associated with material name %s failed with no fallback asset", matName); + return AssetErrCode::Failed; + } + + //handle noshape not being loaded itself + if ((*matAsset)->mLoadedState == BadFileReference) + { + Con::warnf("TerrainMaterialAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, and fallback asset reported error of Bad File Reference.", matName); + return AssetErrCode::BadFileReference; + } + + Con::warnf("TerrainMaterialAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, utilizing fallback asset", matName); + + (*matAsset)->mLoadedState = AssetErrCode::UsingFallback; + return AssetErrCode::UsingFallback; } else + { + for (U32 i = 0; i < foundAssetcount; i++) + { + TerrainMaterialAsset* tMatAsset = AssetDatabase.acquireAsset(query.mAssetList[i]); + if (tMatAsset && tMatAsset->getMaterialDefinitionName() == matName) + { + matAsset->setAssetId(query.mAssetList[i]); + AssetDatabase.releaseAsset(query.mAssetList[i]); + return (*matAsset)->mLoadedState; + } + AssetDatabase.releaseAsset(query.mAssetList[i]); //cleanup if that's not the one we needed + } + } + + //Somehow we failed to bind an asset, so just use the fallback and mark the failure + matAsset->setAssetId(TerrainMaterialAsset::smNoTerrainMaterialAssetFallback); + (*matAsset)->mLoadedState = AssetErrCode::UsingFallback; + return AssetErrCode::UsingFallback; + +} + +StringTableEntry TerrainMaterialAsset::getAssetIdByMaterialName(StringTableEntry matName) +{ + if (matName == StringTable->EmptyString()) + return StringTable->EmptyString(); + + StringTableEntry materialAssetId = TerrainMaterialAsset::smNoTerrainMaterialAssetFallback; + + AssetQuery query; + U32 foundCount = AssetDatabase.findAssetType(&query, "TerrainMaterialAsset"); + if (foundCount != 0) { for (U32 i = 0; i < foundCount; i++) { - TerrainMaterialAsset* matAsset = AssetDatabase.acquireAsset(query->mAssetList[i]); + TerrainMaterialAsset* matAsset = AssetDatabase.acquireAsset(query.mAssetList[i]); if (matAsset && matAsset->getMaterialDefinitionName() == matName) { materialAssetId = matAsset->getAssetId(); - AssetDatabase.releaseAsset(query->mAssetList[i]); + AssetDatabase.releaseAsset(query.mAssetList[i]); break; } - AssetDatabase.releaseAsset(query->mAssetList[i]); + AssetDatabase.releaseAsset(query.mAssetList[i]); } } return materialAssetId; } +U32 TerrainMaterialAsset::getAssetById(StringTableEntry assetId, AssetPtr* materialAsset) +{ + (*materialAsset) = assetId; + if (materialAsset->notNull()) + { + return (*materialAsset)->mLoadedState; + } + else + { + //Didn't work, so have us fall back to a placeholder asset + materialAsset->setAssetId(TerrainMaterialAsset::smNoTerrainMaterialAssetFallback); + if (materialAsset->isNull()) + { + //Well that's bad, loading the fallback failed. + Con::warnf("TerrainMaterialAsset::getAssetById - Finding of asset with id %s failed with no fallback asset", assetId); + return AssetErrCode::Failed; + } + //handle noshape not being loaded itself + if ((*materialAsset)->mLoadedState == BadFileReference) + { + Con::warnf("TerrainMaterialAsset::getAssetById - Finding of asset with id %s failed, and fallback asset reported error of Bad File Reference.", assetId); + return AssetErrCode::BadFileReference; + } + Con::warnf("TerrainMaterialAsset::getAssetById - Finding of asset with id %s failed, utilizing fallback asset", assetId); + (*materialAsset)->mLoadedState = AssetErrCode::UsingFallback; + return AssetErrCode::UsingFallback; + } +} +SimObjectPtr TerrainMaterialAsset::findMaterialDefinitionByAssetId(StringTableEntry assetId) +{ + SimSet* terrainMatSet; + if (!Sim::findObject("TerrainMaterialSet", terrainMatSet)) + { + return nullptr; + } + + SimObjectPtr matDef = dynamic_cast(terrainMatSet->findObjectByInternalName(assetId)); + return matDef; +} + #ifdef TORQUE_TOOLS DefineEngineStaticMethod(TerrainMaterialAsset, getAssetIdByMaterialName, const char*, (const char* materialName), (""), "Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n" @@ -207,6 +440,26 @@ DefineEngineStaticMethod(TerrainMaterialAsset, getAssetIdByMaterialName, const c { return TerrainMaterialAsset::getAssetIdByMaterialName(StringTable->insert(materialName)); } + +//MaterialAsset::findMaterialDefinitionByAssetId("Prototyping:Detail") +DefineEngineStaticMethod(TerrainMaterialAsset, findMaterialDefinitionByAssetId, S32, (const char* assetId), (""), + "Queries the MaterialSet to see if any MaterialDefinition exists that is associated to the provided assetId.\n" + "@return The MaterialDefinition Id associated to the assetId, if any") +{ + SimObjectPtr matDef = TerrainMaterialAsset::findMaterialDefinitionByAssetId(StringTable->insert(assetId)); + if (matDef.isNull()) + return SimObjectId(0); + else + return matDef->getId(); +} + + +DefineEngineMethod(TerrainMaterialAsset, getScriptPath, const char*, (), , + "Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n" + "@return The AssetId of the associated asset, if any.") +{ + return object->getScriptPath(); +} #endif //----------------------------------------------------------------------------- // GuiInspectorTypeAssetId @@ -343,3 +596,18 @@ DefineEngineMethod(GuiInspectorTypeTerrainMaterialAssetPtr, setMaterialAsset, vo return object->setMaterialAsset(assetId); } + +IMPLEMENT_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetId); + +ConsoleDocClass(GuiInspectorTypeTerrainMaterialAssetId, + "@brief Inspector field type for Terrain Material Assets\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeTerrainMaterialAssetId::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeTerrainMaterialAssetId)->setInspectorFieldType("GuiInspectorTypeTerrainMaterialAssetId"); +} diff --git a/Engine/source/T3D/assets/TerrainMaterialAsset.h b/Engine/source/T3D/assets/TerrainMaterialAsset.h index e0a60e391..dfa3c3ef1 100644 --- a/Engine/source/T3D/assets/TerrainMaterialAsset.h +++ b/Engine/source/T3D/assets/TerrainMaterialAsset.h @@ -47,7 +47,13 @@ #include "gui/editor/guiInspectorTypes.h" #endif +#ifndef _TERRMATERIAL_H_ #include "terrain/terrMaterial.h" +#endif + +#ifndef _MATERIALDEFINITION_H_ +#include "materials/materialDefinition.h" +#endif //----------------------------------------------------------------------------- class TerrainMaterialAsset : public AssetBase @@ -58,23 +64,53 @@ class TerrainMaterialAsset : public AssetBase StringTableEntry mScriptPath; StringTableEntry mMatDefinitionName; + SimObjectPtr mMaterialDefinition; + + SimObjectPtr mFXMaterialDefinition; + +public: + static StringTableEntry smNoTerrainMaterialAssetFallback; + + enum TerrainMaterialAssetErrCode + { + ScriptLoaded = AssetErrCode::Extended, + DefinitionAlreadyExists, + EmbeddedDefinition, + Extended + }; + public: TerrainMaterialAsset(); virtual ~TerrainMaterialAsset(); + /// Set up some global script interface stuff. + static void consoleInit(); /// Engine. static void initPersistFields(); virtual void copyTo(SimObject* object); - static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName); + void loadMaterial(); StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; } + SimObjectPtr getMaterialDefinition() { return mMaterialDefinition; } void setScriptFile(const char* pScriptFile); inline StringTableEntry getScriptFile(void) const { return mScriptFile; }; inline StringTableEntry getScriptPath(void) const { return mScriptPath; }; + /// + /// Looks for any assets that uses the provided Material Definition name. + /// If none are found, attempts to auto-import the material definition if the + /// material definition exists. + /// + /// Material Definition name to look for + /// AssetId of matching asset. + static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName); + static U32 getAssetById(StringTableEntry assetId, AssetPtr* materialAsset); + static SimObjectPtr findMaterialDefinitionByAssetId(StringTableEntry assetId); + static U32 getAssetByMaterialName(StringTableEntry matName, AssetPtr* matAsset); + /// Declare Console Object. DECLARE_CONOBJECT(TerrainMaterialAsset); @@ -82,11 +118,16 @@ protected: virtual void initializeAsset(); virtual void onAssetRefresh(void); - static bool setScriptFile(void *obj, const char *index, const char *data) { static_cast(obj)->setScriptFile(data); return false; } + static bool setScriptFile(void *obj, const char *index, const char *data) + { + static_cast(obj)->setScriptFile(data); + return false; + } static const char* getScriptFile(void* obj, const char* data) { return static_cast(obj)->getScriptFile(); } }; DefineConsoleType(TypeTerrainMaterialAssetPtr, TerrainMaterialAsset) +DefineConsoleType(TypeMaterialAssetId, String) //----------------------------------------------------------------------------- // TypeAssetId GuiInspectorField Class @@ -107,6 +148,14 @@ public: virtual bool updateRects(); void setMaterialAsset(String assetId); }; +class GuiInspectorTypeTerrainMaterialAssetId : public GuiInspectorTypeTerrainMaterialAssetPtr +{ + typedef GuiInspectorTypeTerrainMaterialAssetPtr Parent; +public: + + DECLARE_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetId); + static void consoleInit(); +}; #endif // _ASSET_BASE_H_ diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index de603d1fc..f965bd42c 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -609,14 +609,32 @@ AssetImportObject* AssetImporter::addImportingAsset(String assetType, Torque::Pa assetImportObj->registerObject(); //sanitize - assetName.replace(' ', '_'); - assetName.replace('~', '_'); - assetName.replace('`', '_'); - assetName.replace('-', '_'); - assetName.replace('*', '_'); - assetName.replace('-', '_'); - assetName.replace('+', '_'); - assetName.replace('&', '_'); + String processedString = assetName; + + U32 start; + U32 end; + String firstNumber = String::GetFirstNumber(processedString, start, end); + if (!firstNumber.isEmpty() && processedString.startsWith(firstNumber.c_str())) + processedString = processedString.replace(firstNumber, ""); + + processedString = processedString.replace(" ", "_"); + + U32 len = processedString.length() + 1; + char* sanitizedStr = Con::getReturnBuffer(len); + dStrcpy(sanitizedStr, processedString.c_str(), len); + + U32 pos = dStrcspn(sanitizedStr, "-+*/%$&�=()[].?\\\"#,;!~<>|�^{}"); + while (pos < dStrlen(sanitizedStr)) + { + dStrcpy(sanitizedStr + pos, sanitizedStr + pos + 1, len - pos); + pos = dStrcspn(sanitizedStr, "-+*/%$&�=()[].?\\\"#,;!~<>|�^{}"); + } + + //If we did, indeed, modify the name, update it now + if (String(sanitizedStr) != assetName) + { + assetName = sanitizedStr; + } assetImportObj->assetType = assetType; assetImportObj->filePath = filePath; @@ -2725,8 +2743,6 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str()); String tamlPath = targetPath + "/" + assetName + ".asset.taml"; - String scriptName = assetItem->assetName + "." TORQUE_SCRIPT_EXTENSION; - String scriptPath = targetPath + "/" + scriptName; String originalPath = assetItem->filePath.getFullPath().c_str(); char qualifiedFromFile[2048]; @@ -2734,10 +2750,8 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); newAsset->setAssetName(assetName); - newAsset->setScriptFile(scriptName.c_str()); newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); newAsset->setDataField(StringTable->insert("materialDefinitionName"), nullptr, assetName); - //iterate through and write out the material maps dependencies S32 dependencySlotId = 0; @@ -2759,16 +2773,6 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) dependencySlotId++; } - Taml tamlWriter; - bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str()); - - if (!importSuccessful) - { - dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str()); - activityLog.push_back(importLogBuffer); - return ""; - } - //build the ORMConfig file if we're flagged to and have valid image maps if (activeImportConfig->CreateORMConfig) { @@ -2807,109 +2811,12 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) } } - FileObject* file = new FileObject(); - file->registerObject(); - - if (activeImportConfig->UseExistingMaterials && Platform::isFile(qualifiedFromFile)) + //If we're not using existing materials, or the material in question doesn't actually already exist, spool it up + if (!activeImportConfig->UseExistingMaterials || !Sim::findObject(assetName)) { - //Now write the script file containing our material out - //There's 2 ways to do this. If we're in-place importing an existing asset, we can see if the definition existed already, like in an old - //materials.tscript file. if it does, we can just find the object by name, and save it out to our new file - //If not, we'll just generate one - Material* existingMat = MATMGR->getMaterialDefinitionByName(assetName); - - //It's also possible that, for legacy models, the material hooks in via the material's mapTo field, and the material name is something completely different - //So we'll check for that as well if we didn't find it by name up above - if (existingMat == nullptr) - existingMat = MATMGR->getMaterialDefinitionByMapTo(assetName); - - if (existingMat == nullptr && assetItem->assetName != assetItem->cleanAssetName) - { - existingMat = MATMGR->getMaterialDefinitionByName(assetItem->cleanAssetName); - if (existingMat == nullptr) - existingMat = MATMGR->getMaterialDefinitionByMapTo(assetItem->cleanAssetName); - } - - if (existingMat) - { - PersistenceManager* persistMgr; - if (Sim::findObject("ImageAssetValidator", persistMgr)) - { - for (U32 i = 0; i < assetItem->childAssetItems.size(); i++) - { - AssetImportObject* childItem = assetItem->childAssetItems[i]; - - if (childItem->canImport() || childItem->assetType.compare("ImageAsset") != 0) - continue; - - String path = childItem->filePath.getFullFileName(); - - String mapFieldName = ""; - String assetFieldName = ""; - - ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(childItem->imageSuffixType); - - if (imageType == ImageAsset::ImageTypes::Albedo || childItem->imageSuffixType.isEmpty()) - { - mapFieldName = "DiffuseMap"; - } - else if (imageType == ImageAsset::ImageTypes::Normal) - { - mapFieldName = "NormalMap"; - } - else if (imageType == ImageAsset::ImageTypes::ORMConfig) - { - mapFieldName = "ORMConfig"; - } - else if (imageType == ImageAsset::ImageTypes::Metalness) - { - mapFieldName = "MetalMap"; - } - else if (imageType == ImageAsset::ImageTypes::AO) - { - mapFieldName = "AOMap"; - } - else if (imageType == ImageAsset::ImageTypes::Roughness) - { - mapFieldName = "RoughMap"; - } - - assetFieldName = mapFieldName + "Asset[0]"; - mapFieldName += "[0]"; - - //If there's already an existing image map file on the material definition in this slot, don't override it - if (!path.isEmpty()) - existingMat->writeField(mapFieldName.c_str(), path.c_str()); - - String targetAsset = targetModuleId + ":" + childItem->assetName; - - existingMat->writeField(assetFieldName.c_str(), targetAsset.c_str()); - } - - persistMgr->setDirty(existingMat); - } - else - { - Con::errorf("ImageAssetValidator not found!"); - } - } - else - { - dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Failed to find original material definition %s!", assetName); - activityLog.push_back(importLogBuffer); - return tamlPath; - } - } - else if (file->openForWrite(scriptPath.c_str())) - { - file->writeLine((U8*)"//--- OBJECT WRITE BEGIN ---"); - - char lineBuffer[1024]; - dSprintf(lineBuffer, 1024, "singleton Material(%s) {", assetName); - file->writeLine((U8*)lineBuffer); - - dSprintf(lineBuffer, 1024, " mapTo=\"%s\";", assetName); - file->writeLine((U8*)lineBuffer); + Material* newMat = new Material(); + newMat->registerObject(assetName); + newMat->mMapTo = assetName; bool hasRoughness = false; for (U32 i = 0; i < assetItem->childAssetItems.size(); i++) @@ -2919,63 +2826,58 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) if ((!childItem->canImport() && childItem->importStatus != AssetImportObject::UseForDependencies) || childItem->assetType.compare("ImageAsset") != 0) continue; - String mapFieldName = ""; - - String assetFieldName = ""; - ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(childItem->imageSuffixType); + String assetMapFillIn = targetModuleId + ":" + childItem->assetName; + StringTableEntry assetMapFillInStr = StringTable->insert(assetMapFillIn.c_str()); + if (imageType == ImageAsset::ImageTypes::Albedo || childItem->imageSuffixType.isEmpty()) { - mapFieldName = "DiffuseMap"; + newMat->mDiffuseMapAssetId[0] = assetMapFillInStr; } else if (imageType == ImageAsset::ImageTypes::Normal) { - mapFieldName = "NormalMap"; + newMat->mNormalMapAssetId[0] = assetMapFillInStr; } else if (imageType == ImageAsset::ImageTypes::ORMConfig) { - mapFieldName = "ORMConfigMap"; + newMat->mORMConfigMapAssetId[0] = assetMapFillInStr; } else if (imageType == ImageAsset::ImageTypes::Metalness) { - mapFieldName = "MetalMap"; + newMat->mMetalMapAssetId[0] = assetMapFillInStr; } else if (imageType == ImageAsset::ImageTypes::AO) { - mapFieldName = "AOMap"; + newMat->mAOMapAssetId[0] = assetMapFillInStr; } else if (imageType == ImageAsset::ImageTypes::Roughness) { - mapFieldName = "RoughMap"; + newMat->mRoughMapAssetId[0] = assetMapFillInStr; hasRoughness = true; } - - assetFieldName = mapFieldName + "Asset"; - assetFieldName += "[0]"; - - //String path = childItem->filePath.getFullFileName(); - //dSprintf(lineBuffer, 1024, " %s = \"%s\";", mapFieldName.c_str(), path.c_str()); - //file->writeLine((U8*)lineBuffer); - - dSprintf(lineBuffer, 1024, " %s = \"%s:%s\";", assetFieldName.c_str(), targetModuleId.c_str(), childItem->assetName.c_str()); - file->writeLine((U8*)lineBuffer); } if (hasRoughness) { - file->writeLine((U8*)" invertSmoothness = true;"); - + newMat->mInvertRoughness[0] = true; } - file->writeLine((U8*)"};"); - file->writeLine((U8*)"//--- OBJECT WRITE END ---"); - - file->close(); + newAsset->addObject(newMat); } - else + else { - dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset script file %s", scriptPath.c_str()); + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Set to use an existing material, so avoiding writing a material definition to new asset definition for material: %s", assetName); + activityLog.push_back(importLogBuffer); + return ""; + } + + Taml tamlWriter; + bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str()); + + if (!importSuccessful) + { + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str()); activityLog.push_back(importLogBuffer); return ""; } diff --git a/Engine/source/assets/assetBase.h b/Engine/source/assets/assetBase.h index d4efc6a8a..516376663 100644 --- a/Engine/source/assets/assetBase.h +++ b/Engine/source/assets/assetBase.h @@ -55,11 +55,11 @@ extern StringTableEntry assetAutoUnloadField; //#define ASSET_BASE_AUTOUNLOAD_FIELD "AssetAutoUnload" //----------------------------------------------------------------------------- -class AssetBase : public SimObject +class AssetBase : public SimGroup { friend class AssetManager; - typedef SimObject Parent; + typedef SimGroup Parent; protected: AssetManager* mpOwningAssetManager; diff --git a/Engine/source/assets/assetDefinition.h b/Engine/source/assets/assetDefinition.h index 0d3b1c964..fb5720394 100644 --- a/Engine/source/assets/assetDefinition.h +++ b/Engine/source/assets/assetDefinition.h @@ -35,8 +35,8 @@ #include "console/sim.h" #endif -#ifndef _SIMOBJECT_H_ -#include "console/simObject.h" +#ifndef _SIMSET_H_ +#include "console/simset.h" #endif #ifndef _CONSOLEOBJECT_H_ diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 3d485354c..8a54f7299 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -77,6 +77,7 @@ SimObject::SimObject() mObjectName = NULL; mOriginalName = NULL; mInternalName = NULL; + mInheritFrom = NULL; nextNameObject = nullptr; nextManagerNameObject = nullptr; nextIdObject = NULL; @@ -154,6 +155,9 @@ void SimObject::initPersistFields() addProtectedField( "name", TypeName, Offset(mObjectName, SimObject), &setProtectedName, &defaultProtectedGetFn, "Optional global name of this object." ); + + addProtectedField("inheritFrom", TypeString, Offset(mInheritFrom, SimObject), &setInheritFrom, &defaultProtectedGetFn, + "Optional Name of object to inherit from as a parent."); endGroup( "Ungrouped" ); @@ -1133,7 +1137,7 @@ const char *SimObject::getPrefixedDataField(StringTableEntry fieldName, const ch //----------------------------------------------------------------------------- -void SimObject::setPrefixedDataField(StringTableEntry fieldName, const char *array, const char *value) +void SimObject::setPrefixedDataField(StringTableEntry fieldName, const char *_array, const char *value) { // Sanity! AssertFatal(fieldName != NULL, "Cannot set object field value with NULL field name."); @@ -1142,7 +1146,7 @@ void SimObject::setPrefixedDataField(StringTableEntry fieldName, const char *arr // Set value without prefix if there's no value. if (*value == 0) { - setDataField(fieldName, NULL, value); + setDataField(fieldName, _array, value); return; } @@ -1156,7 +1160,7 @@ void SimObject::setPrefixedDataField(StringTableEntry fieldName, const char *arr if (fieldPrefix == StringTable->EmptyString()) { // No, so set the data field in the usual way. - setDataField(fieldName, NULL, value); + setDataField(fieldName, _array, value); return; } @@ -1167,23 +1171,23 @@ void SimObject::setPrefixedDataField(StringTableEntry fieldName, const char *arr if (dStrnicmp(value, fieldPrefix, fieldPrefixLength) != 0) { // No, so set the data field in the usual way. - setDataField(fieldName, NULL, value); + setDataField(fieldName, _array, value); return; } // Yes, so set the data excluding the prefix. - setDataField(fieldName, NULL, value + fieldPrefixLength); + setDataField(fieldName, _array, value + fieldPrefixLength); } //----------------------------------------------------------------------------- -const char *SimObject::getPrefixedDynamicDataField(StringTableEntry fieldName, const char *array, const S32 fieldType) +const char *SimObject::getPrefixedDynamicDataField(StringTableEntry fieldName, const char *_array, const S32 fieldType) { // Sanity! AssertFatal(fieldName != NULL, "Cannot get field value with NULL field name."); // Fetch field value. - const char* pFieldValue = getDataField(fieldName, array); + const char* pFieldValue = getDataField(fieldName, _array); // Sanity. AssertFatal(pFieldValue != NULL, "Field value cannot be NULL."); @@ -2235,10 +2239,10 @@ bool SimObject::setProtectedName(void *obj, const char *index, const char *data) { if (preventNameChanging) return false; - SimObject *object = static_cast(obj); - - if ( object->isProperlyAdded() ) - object->assignName( data ); + SimObject* object = static_cast(obj); + + if (object->isProperlyAdded()) + object->assignName(data); // always return false because we assign the name here return false; @@ -2246,6 +2250,31 @@ bool SimObject::setProtectedName(void *obj, const char *index, const char *data) //----------------------------------------------------------------------------- +bool SimObject::setInheritFrom(void* obj, const char* index, const char* data) +{ + SimObject* object = static_cast(obj); + + SimObject* parent; + if (Sim::findObject(data, parent)) + { + object->setCopySource(parent); + object->assignFieldsFrom(parent); + + // copy any substitution statements + SimDataBlock* parent_db = dynamic_cast(parent); + if (parent_db) + { + SimDataBlock* currentNewObject_db = dynamic_cast(object); + if (currentNewObject_db) + currentNewObject_db->copySubstitutionsFrom(parent_db); + } + } + + return true; +} + +//----------------------------------------------------------------------------- + void SimObject::inspectPreApply() { } diff --git a/Engine/source/console/simObject.h b/Engine/source/console/simObject.h index 9cef85f0f..05a9353dc 100644 --- a/Engine/source/console/simObject.h +++ b/Engine/source/console/simObject.h @@ -299,6 +299,8 @@ class SimObject: public ConsoleObject, public TamlCallbacks SimObject* nextManagerNameObject; SimObject* nextIdObject; + StringTableEntry mInheritFrom; + /// SimGroup we're contained in, if any. SimGroup* mGroup; @@ -380,6 +382,9 @@ class SimObject: public ConsoleObject, public TamlCallbacks // Object name protected set method static bool setProtectedName(void *object, const char *index, const char *data); + // Sets object to inherit default values from + static bool setInheritFrom(void* object, const char* index, const char* data); + public: inline void setProgenitorFile(const char* pFile) { mProgenitorFile = StringTable->insert(pFile); } inline StringTableEntry getProgenitorFile(void) const { return mProgenitorFile; } diff --git a/Engine/source/materials/materialDefinition.cpp b/Engine/source/materials/materialDefinition.cpp index 5d009004a..7b3d2c7de 100644 --- a/Engine/source/materials/materialDefinition.cpp +++ b/Engine/source/materials/materialDefinition.cpp @@ -516,7 +516,8 @@ bool Material::writeField(StringTableEntry fieldname, const char* value) fieldname == StringTable->insert("overlayTex") || fieldname == StringTable->insert("bumpTex") || fieldname == StringTable->insert("envTex") || - fieldname == StringTable->insert("colorMultiply")) + fieldname == StringTable->insert("colorMultiply") || + fieldname == StringTable->insert("internalName")) return false; return Parent::writeField(fieldname, value); diff --git a/Engine/source/persistence/taml/xml/tamlXmlReader.cpp b/Engine/source/persistence/taml/xml/tamlXmlReader.cpp index 320248b6f..fb8814260 100644 --- a/Engine/source/persistence/taml/xml/tamlXmlReader.cpp +++ b/Engine/source/persistence/taml/xml/tamlXmlReader.cpp @@ -293,8 +293,22 @@ void TamlXmlReader::parseAttributes( tinyxml2::XMLElement* pXmlElement, SimObjec attributeName == tamlNamedObjectName ) continue; - // Set the field. - pSimObject->setPrefixedDataField(attributeName, NULL, pAttribute->Value()); + //See if we have any sort of array index + S32 suffixNum; + String trimmedName = String::GetTrailingNumber(attributeName, suffixNum); + if (!trimmedName.equal(attributeName)) + { + char arrayIndexStr[32]; + dItoa(suffixNum, arrayIndexStr); + + // Set the field. + pSimObject->setPrefixedDataField(StringTable->insert(trimmedName.c_str()), arrayIndexStr, pAttribute->Value()); + } + else + { + // Set the field. + pSimObject->setPrefixedDataField(attributeName, NULL, pAttribute->Value()); + } } } diff --git a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml index faa7ab1e6..3cfa5da83 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml +++ b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml @@ -47,7 +47,7 @@ 0 1 1 - DefaultMaterial + DefaultMaterial,ColorEffect* 1 1 1 @@ -130,6 +130,7 @@ 1 1 1 + DefaultMaterial,ColorEffect* 1 1 1 diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index bd7c78f90..c385a5f0c 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript @@ -2444,7 +2444,6 @@ function AssetBrowserFilterTree::onControlDropped( %this, %payload, %position ) function AssetBrowserFilterTree::onDragDropped( %this ) { - %asdgadfhg =true; } function AssetBrowser::hasLooseFilesInDir(%this) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index d70c6a4a5..18305b920 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript @@ -8,7 +8,6 @@ function AssetBrowser::createMaterialAsset(%this) %assetPath = AssetBrowser.dirHandler.currentAddress @ "/"; %tamlpath = %assetPath @ %assetName @ ".asset.taml"; - %scriptPath = %assetPath @ %assetName @ "." @ $TorqueScriptFileExtension; %asset = new MaterialAsset() { @@ -16,13 +15,13 @@ function AssetBrowser::createMaterialAsset(%this) versionId = 1; materialDefinitionName = %assetName; scriptFile = %assetName @ "." @ $TorqueScriptFileExtension; + + new Material(%assetName) { + }; }; TamlWrite(%asset, %tamlpath); - %mat = new Material(%assetName); - %mat.save(%scriptPath); - %moduleDef = ModuleDatabase.findModule(%moduleName, 1); AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); @@ -42,6 +41,7 @@ function AssetBrowser::editMaterialAsset(%this, %assetDef) EditorGui.setEditor(MaterialEditorPlugin); + MaterialEditorGui.currentMaterialAsset = %assetDef.getAssetId(); MaterialEditorGui.currentMaterial = %assetDef.materialDefinitionName; MaterialEditorGui.setActiveMaterial( %assetDef.materialDefinitionName ); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript index 51bc88d54..ad1212e11 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript @@ -15,10 +15,37 @@ function AssetBrowser::createTerrainMaterialAsset(%this) { AssetName = %assetName; versionId = 1; - scriptFile = %assetName @ "." @ $TorqueScriptFileExtension; materialDefinitionName = %assetName; }; + %matDef = new TerrainMaterial(%assetName) + { + internalName = %moduleName @ ":" @ %assetName; + diffuseMap = ""; + detailMap = ""; + detailSize = "10"; + isManaged = "1"; + detailBrightness = "1"; + Enabled = "1"; + diffuseSize = "200"; + }; + + %fxMatDef = new Material("TerrainFX_" @ %assetName) + { + mapTo = %assetName; + footstepSoundId = 0; + terrainMaterials = "1"; + ShowDust = "1"; + showFootprints = "1"; + materialTag0 = "Terrain"; + effectColor[0] = "0.42 0.42 0 1"; + effectColor[1] = "0.42 0.42 0 1"; + impactSoundId = "0"; + }; + + %asset.add(%matDef); + %asset.add(%fxMatDef); + TamlWrite(%asset, %tamlpath); %moduleDef = ModuleDatabase.findModule(%moduleName, 1); @@ -28,35 +55,6 @@ function AssetBrowser::createTerrainMaterialAsset(%this) AssetBrowser.refresh(); - //AssetBrowserFilterTree.onSelect(%smItem); - - %file = new FileObject(); - %templateFile = new FileObject(); - - %templateFilePath = %this.templateFilesPath @ "terrainMaterial." @ $TorqueScriptFileExtension @ ".template"; - - if(%file.openForWrite(%scriptPath) && %templateFile.openForRead(%templateFilePath)) - { - while( !%templateFile.isEOF() ) - { - %line = %templateFile.readline(); - %line = strreplace( %line, "@", %assetName ); - - %file.writeline(%line); - //echo(%line); - } - - %file.close(); - %templateFile.close(); - } - else - { - %file.close(); - %templateFile.close(); - - warnf("CreateNewTerrainMaterialAsset - Something went wrong and we couldn't write thescript file!"); - } - //If we've got the terrain mat editor open, go ahead and update it all TerrainMaterialDlg.onWake(); diff --git a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript index 2af4b9795..882ec9dc2 100644 --- a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript @@ -269,6 +269,7 @@ function SubMaterialSelector::onSelect( %this ) } else { + MaterialEditorGui.currentMaterialAsset = %material; %assetDef = AssetDatabase.acquireAsset(%material); %material = %assetDef.materialDefinitionName; } @@ -1906,6 +1907,7 @@ function MaterialEditorGui::saveDialogDontSave( %this, %material ) if(AssetDatabase.isDeclaredAsset(%material)) { + MaterialEditorGui.currentMaterialAsset = %material; %material = AssetDatabase.acquireAsset(%material).materialDefinitionName; } @@ -1916,6 +1918,7 @@ function MaterialEditorGui::saveDialogSave( %this, %material ) { if(AssetDatabase.isDeclaredAsset(%material)) { + MaterialEditorGui.currentMaterialAsset = %material; %material = AssetDatabase.acquireAsset(%material).materialDefinitionName; } @@ -1945,8 +1948,18 @@ function MaterialEditorGui::save( %this ) if( %currentMaterial.isAutoGenerated() ) %currentMaterial.setAutoGenerated( false ); - // Save the material using the persistence manager - matEd_PersistMan.saveDirty(); + if(MaterialEditorGui.currentMaterialAsset !$= "") + { + MaterialEditorGui.copyMaterials( materialEd_previewMaterial, notDirtyMaterial ); + + %assetDef = AssetDatabase.acquireAsset(MaterialEditorGui.currentMaterialAsset); + %assetDef.saveAsset(); //write it out + } + else + { + // Save the material using the persistence manager + matEd_PersistMan.saveDirty(); + } // Clean up the Material Editor MaterialEditorGui.copyMaterials( materialEd_previewMaterial, notDirtyMaterial ); @@ -2211,6 +2224,7 @@ function MaterialEditorGui::changeMaterial(%this, %fromMaterial, %toMaterial) if(AssetDatabase.isDeclaredAsset(%toMaterial)) { %isMatAsset = true; + MaterialEditorGui.currentMaterialAsset = %toMaterial; %assetDef = AssetDatabase.acquireAsset(%toMaterial); %toMaterialDefinition = %assetDef.materialDefinitionName; %filename = %assetDef.getScriptPath(); diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript index c494c5029..e109d2f5e 100644 --- a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript @@ -200,7 +200,7 @@ function T3Dpre4ProjectImporter::writeImportingFiles(%this) if($ProjectImporter::useExistingModule) { //clean up legact files if they've been renamed or whatnot - if(%file !$= %rootFileSectionObject.fileDestination) + if(makeRelativePath(%file) !$= %rootFileSectionObject.fileDestination) { fileDelete(%file); } @@ -659,8 +659,6 @@ function T3Dpre4ProjectImporter::processAssetFile(%this, %assetObj) if(!isObject(%assetObj)) return; - %assetObj.echo(); - //really, we only care here about ensuring the file extensions are cleaned up for(%l=0; %l < %assetObj.count(); %l++) { @@ -691,6 +689,9 @@ function T3Dpre4ProjectImporter::beginAssetAndModuleImport(%this) if(%fileExt $= ".module") { + if(%rootFileSectionObject.skip) + continue; + projectImporterLog("T3Dpre4ProjectImporter::beginAssetAndModuleImport() - processing file: " @ %file); $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/"; %this.processModuleFile(%rootFileSectionObject); @@ -698,6 +699,9 @@ function T3Dpre4ProjectImporter::beginAssetAndModuleImport(%this) } else if(%fileExt $= ".asset.taml") { + if(%rootFileSectionObject.skip) + continue; + projectImporterLog("T3Dpre4ProjectImporter::beginAssetAndModuleImport() - processing file: " @ %file); $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/"; %this.processAssetFile(%rootFileSectionObject); @@ -913,12 +917,11 @@ function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %obje versionId = 1; shaderData = ""; materialDefinitionName = %assetName; - scriptFile = fileBase(%scriptPath); }; //Now we make our scripted definition "real", and append it to our asset //so it is serialized. - /*%objectDefinition = ""; + %objectDefinition = ""; for(%l=0; %l < %fileObject.count(); %l++) { %objectLine = %fileObject.getKey(%l); @@ -932,8 +935,14 @@ function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %obje if(isObject(%objectName)) { + //if we created it successfully, set up inheritance for serialization if needed + if(%fileObject.parentName !$= "") + { + %objectName.setFieldValue("inheritFrom",%fileObject.parentName); + } + %asset.add(%objectName); - }*/ + } if(!isDirectory(%assetPath)) { @@ -943,26 +952,6 @@ function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %obje %success = false; if(TamlWrite(%asset, %tamlpath)) { - //now write the script file - if ( $ProjectImporter::fileObject.openForWrite( %scriptPath ) ) - { - for(%i=0; %i < %fileObject.count(); %i++) - { - %objectLine = %fileObject.getKey(%i); - if(isObject(%objectLine)) - { - %defineLine = %fileObject.getKey(0); - $ProjectImporter::fileObject.writeLine(%defineLine); - } - else - { - $ProjectImporter::fileObject.writeLine(%objectLine); - } - } - - $ProjectImporter::fileObject.close(); - } - %moduleDef = ModuleDatabase.findModule(%moduleName, 1); %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); @@ -971,6 +960,43 @@ function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %obje if(!%success) return false; } + else + { + //process an existing material asset, if needbe + %assetDef = AssetDatabase.acquireAsset(%matAsset); + + %assetScriptPath = %assetDef.getScriptPath(); + + if(isFile(%assetScriptPath) && isObject(%objectName)) + { + //Regular material in a companion file, so we'll want to write it to the + //asset def file instead of the loose file + %assetDef.scriptFile = ""; //clear the old script path reference + %assetDef.add(%objectName); //child the definition to the asset def + + if(%fileObject.parentName !$= "") + { + %objectName.setFieldValue("inheritFrom",%fileObject.parentName); + } + + if(%assetDef.saveAsset()) + { + %fileObject.processed = true; + %fileObject.skip = true; //don't write the def back out to script, it's not needed now + + %assetFileObj = findFileInImporting(makeFullPath(AssetDatabase.getAssetFilePath(%matAsset))); + + echo(%assetFileObj.fileDestination); + %assetFileObj.processed = true; + %assetFileObj.skip = true; //this asset definition has been processed + //so nothing else need be done + } + else + { + projectImporterLog("T3Dpre4ProjectImporter::processMaterialObject() - failed to save out modified material asset for: " @ %matAsset); + } + } + } return false; } @@ -1017,9 +1043,36 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject versionId = 1; shaderData = ""; materialDefinitionName = %objectName; - scriptFile = fileName(%scriptPath); }; + //Now we make our scripted definition "real", and append it to our asset + //so it is serialized. + %objectDefinition = ""; + for(%l=0; %l < %fileObject.count(); %l++) + { + %objectLine = %fileObject.getKey(%l); + if(!isObject(%objectLine)) + { + %objectDefinition = %objectDefinition @ %objectLine; + } + } + + //Shift to object name, internal name will be used for assetID store + %objectDefinition.name = findObjectField(%fileObject, "internalName"); + + eval(%objectDefinition); + + if(isObject(%objectName)) + { + //if we created it successfully, set up inheritance for serialization if needed + if(%fileObject.parentName !$= "") + { + %objectName.setFieldValue("inheritFrom",%fileObject.parentName); + } + + %asset.add(%objectName); + } + %success = false; if(TamlWrite(%asset, %tamlpath)) { @@ -1031,6 +1084,43 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject if(!%success) return false; } + else + { + //process an existing material asset, if needbe + %assetDef = AssetDatabase.acquireAsset(%matAsset); + + %assetScriptPath = %assetDef.getScriptPath(); + + if(isFile(%assetScriptPath) && isObject(%objectName)) + { + //Regular material in a companion file, so we'll want to write it to the + //asset def file instead of the loose file + %assetDef.scriptFile = ""; //clear the old script path reference + %assetDef.add(%objectName); //child the definition to the asset def + + if(%fileObject.parentName !$= "") + { + %objectName.setFieldValue("inheritFrom",%fileObject.parentName); + } + + if(%assetDef.saveAsset()) + { + %fileObject.processed = true; + %fileObject.skip = true; //don't write the def back out to script, it's not needed now + + %assetFileObj = findFileInImporting(makeFullPath(AssetDatabase.getAssetFilePath(%matAsset))); + + echo(%assetFileObj.fileDestination); + %assetFileObj.processed = true; + %assetFileObj.skip = true; //this asset definition has been processed + //so nothing else need be done + } + else + { + projectImporterLog("T3Dpre4ProjectImporter::processTerrainMaterialObject() - failed to save out modified material asset for: " @ %matAsset); + } + } + } return false; } @@ -1122,25 +1212,12 @@ function T3Dpre4ProjectImporter::processSFXProfileObject(%this, %file, %objectNa } else { - %objFileFinder = ""; - //first check our cache - if(isObject($ProjectImporter::SFXDescriptionCache) && - $ProjectImporter::SFXDescriptionCache.getIndexFromKey(%descriptionName) !$= "") - { - %key = $ProjectImporter::SFXDescriptionCache.getIndexFromKey(%descriptionName); - %objFileFinder = $ProjectImporter::SFXDescriptionCache.getValue(%key); - } - else - { - %objFileFinder = findObjectInFiles(%descriptionName); - } + %fileObj = findObjectInFiles(%descriptionName); - if(%objFileFinder !$= "") + if(%fileObj !$= "") { %valueArray = new ArrayObject(); - %fileObj = getField(%objFileFinder, 0); - %valueArray.add("sourceGroup" SPC findObjectField(%fileObj, "sourceGroup")); %valueArray.add("volume" SPC findObjectField(%fileObj, "volume")); %valueArray.add("pitch" SPC findObjectField(%fileObj, "pitch")); @@ -1157,10 +1234,7 @@ function T3Dpre4ProjectImporter::processSFXProfileObject(%this, %file, %objectNa %valueArray.add("rolloffFactor" SPC findObjectField(%fileObj, "rolloffFactor")); %valueArray.add("isStreaming" SPC findObjectField(%fileObj, "isStreaming")); - if(isObject($ProjectImporter::SFXDescriptionCache)) - { - $ProjectImporter::SFXDescriptionCache.add(%descriptionName, %objFileFinder); - } + %fileObj.skip = true; for(%v=0; %v < %valueArray.Count(); %v++) { diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index ab47a18a9..e4156ff23 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -242,7 +242,7 @@ function ProjectImportWizardPage3::openPage(%this) %dataFullPath = makeFullPath("data/"); %coreFullPath = makeFullPath("core/"); %toolsFullPath = makeFullPath("tools/"); - if(startsWith(makeFullPath("data/"), $ProjectImporter::sourceContentFolder)) + if(startsWith($ProjectImporter::sourceContentFolder, makeFullPath("data/"))) { %moduleDef = AssetBrowser.dirHandler.getModuleFromAddress(makeRelativePath($ProjectImporter::sourceContentFolder)); if(isObject(%moduleDef)) @@ -254,8 +254,8 @@ function ProjectImportWizardPage3::openPage(%this) ProjectImportWindow.setStep(4); } } - else if(startsWith(makeFullPath("core/"), $ProjectImporter::sourceContentFolder) || - startsWith(makeFullPath("tools/"), $ProjectImporter::sourceContentFolder)) + else if(startsWith($ProjectImporter::sourceContentFolder, makeFullPath("core/")) || + startsWith($ProjectImporter::sourceContentFolder, makeFullPath("tools/"))) { ProjectImportWindow.setStep(5); } @@ -490,9 +490,11 @@ function preprocessImportingFiles() %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); + %parentName = ""; %inheritanceSplit = strpos(%objectName, ":"); if(%inheritanceSplit != -1) { + %parentName = getSubStr(%objectName, %inheritanceSplit + 1); %objectName = getSubStr(%objectName, 0, %inheritanceSplit); } @@ -502,6 +504,7 @@ function preprocessImportingFiles() %currentFileSectionObject.elementType = "object"; %currentFileSectionObject.classType = %className; %currentFileSectionObject.objectName = %objectName; + %currentFileSectionObject.parentName = %parentName; %currentFileSectionObject.fileName = %file; %currentFileSectionObject.skip = false; %currentFileSectionObject.fileDestination = %rootFileSectionObject.fileDestination; @@ -510,6 +513,7 @@ function preprocessImportingFiles() %currentFileSectionObject.add(%line); %parentFileSectionObject.add(%currentFileSectionObject); + %currentFileSectionObject.parentElement = %parentFileSectionObject; //Now for a sanity check, see if we kill the object on the same line as we make it //sometimes people try and be 'efficient' with their code linecount wise @@ -540,9 +544,11 @@ function preprocessImportingFiles() %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); + %parentName = ""; %inheritanceSplit = strpos(%objectName, ":"); if(%inheritanceSplit != -1) { + %parentName = getSubStr(%objectName, %inheritanceSplit + 1); %objectName = getSubStr(%objectName, 0, %inheritanceSplit); } @@ -552,6 +558,7 @@ function preprocessImportingFiles() %currentFileSectionObject.elementType = "object"; %currentFileSectionObject.classType = %className; %currentFileSectionObject.objectName = %objectName; + %currentFileSectionObject.parentName = %parentName; %currentFileSectionObject.fileName = %file; %currentFileSectionObject.skip = false; %currentFileSectionObject.fileDestination = %rootFileSectionObject.fileDestination; @@ -560,6 +567,7 @@ function preprocessImportingFiles() %currentFileSectionObject.add(%line); %parentFileSectionObject.add(%currentFileSectionObject); + %currentFileSectionObject.parentElement = %parentFileSectionObject; //Now for a sanity check, see if we kill the object on the same line as we make it //sometimes people try and be 'efficient' with their code linecount wise @@ -590,9 +598,11 @@ function preprocessImportingFiles() %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); + %parentName = ""; %inheritanceSplit = strpos(%objectName, ":"); if(%inheritanceSplit != -1) { + %parentName = getSubStr(%objectName, %inheritanceSplit + 1); %objectName = getSubStr(%objectName, 0, %inheritanceSplit); } @@ -602,6 +612,7 @@ function preprocessImportingFiles() %currentFileSectionObject.elementType = "object"; %currentFileSectionObject.classType = %className; %currentFileSectionObject.objectName = %objectName; + %currentFileSectionObject.parentName = %parentName; %currentFileSectionObject.fileName = %file; %currentFileSectionObject.skip = false; %currentFileSectionObject.fileDestination = %rootFileSectionObject.fileDestination; @@ -610,6 +621,7 @@ function preprocessImportingFiles() %currentFileSectionObject.add(%line); %parentFileSectionObject.add(%currentFileSectionObject); + %currentFileSectionObject.parentElement = %parentFileSectionObject; //Now for a sanity check, see if we kill the object on the same line as we make it //sometimes people try and be 'efficient' with their code linecount wise @@ -650,6 +662,7 @@ function preprocessImportingFiles() %currentFileSectionObject.add(%line); %parentFileSectionObject.add(%currentFileSectionObject); + %currentFileSectionObject.parentElement = %parentFileSectionObject; if(strIsMatchExpr("*{*", %line)) { @@ -838,6 +851,48 @@ function isImportingFile(%checkFile) return false; } +//============================================================================== +// Returns the file object of the file in question is part of our pre-scanned list of importing files +//============================================================================== +function findFileInImporting(%checkFile) +{ + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + + if(%file $= %checkFile) + return $ProjectImporter::FileList.getValue(%i); + } + + return ""; +} + +//============================================================================== +// Checks if the object in question is defined in any of our pre-scanned list of importing files +//============================================================================== +function findObjectInFiles(%objectName, %arrayObj) +{ + if(%arrayObj $= "") + %arrayObj = $ProjectImporter::FileList; + + for(%i=0; %i < %arrayObj.count(); %i++) + { + %objectLine = %arrayObj.getKey(%i); + if(isObject(%objectLine)) + { + if(%objectLine.objectName $= %objectName) + return %objectLine; + + //If this object isn't it, try recursing any children + %result = findObjectInFiles(%objectName, %objectLine); + if(%result !$= "") + return %result; + } + } + + return ""; +} + //============================================================================== // Takes a filename lacking an extension and then checks common file extensions // to see if we can find the actual file in question @@ -1215,6 +1270,32 @@ function projectImporterLog(%line) $ProjectImporter::log.add(%line); } +//============================================================================== +// Traverses the object delcaration stack backwards to find the root file object +//============================================================================== +function getParentFileObjectFromObject(%object) +{ + while(%object.parentElement !$= "") + { + %object = %object.parentElement; + } + + return %object; +} + +//============================================================================== +// Traverses the object delcaration stack backwards to find the root file object +//============================================================================== +function getParentFileObjectFromObject(%object) +{ + while(%object.parentElement !$= "") + { + %object = %object.parentElement; + } + + return %object; +} + //============================================================================== //Shape Importing //============================================================================== diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript index 5429008ea..b49cef39a 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript @@ -77,9 +77,6 @@ function TerrainMaterialDlg::showByObjectId( %this, %matObjectId, %onApplyCallba function TerrainMaterialDlg::onWake( %this ) { - if( !isObject( ETerrainMaterialPersistMan ) ) - new PersistenceManager( ETerrainMaterialPersistMan ); - if( !isObject( TerrainMaterialDlgNewGroup ) ) new SimGroup( TerrainMaterialDlgNewGroup ); if( !isObject( TerrainMaterialDlgDeleteGroup ) ) @@ -156,9 +153,6 @@ function TerrainMaterialDlg::dialogApply( %this ) // Make sure we save any changes to the current selection. %this.saveDirtyMaterial( %this.activeMat ); - // Save all changes. - ETerrainMaterialPersistMan.saveDirty(); - // Delete the snapshot. TerrainMaterialDlgSnapshot.delete(); @@ -191,10 +185,6 @@ function TerrainMaterialDlg::closeDialog( %this ) %this.restoreMaterials(); - // Clear the persistence manager state. - - ETerrainMaterialPersistMan.clearAll(); - // Delete all new object we have created. TerrainMaterialDlgNewGroup.clear(); @@ -599,17 +589,9 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %mat.isSRGB = %isSRGB; %mat.invertRoughness = %invertRoughness; - // Mark the material as dirty and needing saving. - - %fileName = %mat.getFileName(); - if( %fileName $= "" ) - { - error("TerrainMaterialDlg::saveDirtyMaterial() - terrain material doesn't have a fileName set to save to."); - return; - //%fileName = "data/terrains/materials." @ $TorqueScriptFileExtension; - } - - ETerrainMaterialPersistMan.setDirty( %mat, %fileName ); + //Save the material asset + %assetDef = AssetDatabase.acquireAsset(%mat.internalName); + %assetDef.saveAsset(); } //----------------------------------------------------------------------------- From 5e1eb80bc1ba469f839a7b6bac87ce35899be0f6 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 30 Jan 2022 19:14:36 -0600 Subject: [PATCH 018/145] Fixed handling issue where it would misparse lines that would contain new/singleton/datablock keywords fixed incorrect getSubStr function invoke --- .../importers/pre40/pre40ImporterGuis.tscript | 2 +- .../tools/projectImporter/scripts/projectImporter.tscript | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript index 816b5cf80..10b7fb96a 100644 --- a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript @@ -37,7 +37,7 @@ function Pre40ImporterPage0::openPage(%this) %sanitizedFilename = sanitizeString(%fileBase); if(startsWith(%sanitizedFilename, "_")) { - %sanitizedFilename = substr(%sanitizedFilename, 1, -1); + %sanitizedFilename = getSubstr(%sanitizedFilename, 1, -1); } if(%sanitizedFilename !$= %fileBase) { diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index e4156ff23..af600e8c3 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -476,7 +476,7 @@ function preprocessImportingFiles() { %line = $ProjectImporter::fileObject.readLine(); - if(strIsMatchExpr("*new*(*)*", %line) && !strIsMatchExpr("*\"*new*(*)*\"*", %line)) + if(strIsMatchExpr("* new*(*)*", %line)) { %start = strpos(%line, "new "); %end = strpos(%line, "(", %start); @@ -530,7 +530,7 @@ function preprocessImportingFiles() %insideObjectBlock = true; } } - else if(strIsMatchExpr("*datablock*(*)*", %line)) + else if(strIsMatchExpr("* datablock*(*)*", %line)) { %start = strpos(%line, "datablock "); %end = strpos(%line, "(", %start); @@ -584,7 +584,7 @@ function preprocessImportingFiles() %insideObjectBlock = true; } } - else if(strIsMatchExpr("*singleton*(*)*", %line)) + else if(strIsMatchExpr("* singleton*(*)*", %line)) { %start = strpos(%line, "singleton "); %end = strpos(%line, "(", %start); From b4e346aa3ff7556ed62b322e54c521d38a430c00 Mon Sep 17 00:00:00 2001 From: JeffR Date: Mon, 31 Jan 2022 20:57:57 -0600 Subject: [PATCH 019/145] Adjustments to save out code when writing fields such that if the TAML writer is marked as not writing defaults, it doesn't. And makes the regular simobject save out not write default values as the default behavior --- Engine/source/console/simObject.cpp | 12 ++++++++ Engine/source/persistence/taml/taml.cpp | 37 +++++++++++++++++++------ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 8a54f7299..1a76e23fe 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -304,6 +304,10 @@ bool SimObject::writeField(StringTableEntry fieldname, const char* value) void SimObject::writeFields(Stream &stream, U32 tabStop) { // Write static fields. + + // Create a default object of the same type + ConsoleObject* defaultConObject = ConsoleObject::create(getClassName()); + SimObject* defaultObject = dynamic_cast(defaultConObject); const AbstractClassRep::FieldList &list = getFieldList(); @@ -332,6 +336,11 @@ void SimObject::writeFields(Stream &stream, U32 tabStop) if (!writeField(f->pFieldname, valCopy)) continue; + //If the field hasn't been changed from the default value, then don't bother writing it out + const char* defaultValueCheck = defaultObject->getDataField(f->pFieldname, array); + if (dStricmp(defaultValueCheck, valCopy) == 0) + continue; + val = valCopy; U32 expandedBufferSize = ( nBufferSize * 2 ) + dStrlen(f->pFieldname) + 32; @@ -366,6 +375,9 @@ void SimObject::writeFields(Stream &stream, U32 tabStop) if(mFieldDictionary && mCanSaveFieldDictionary) mFieldDictionary->writeFields(this, stream, tabStop); + + // Cleanup our created default object + delete defaultConObject; } //----------------------------------------------------------------------------- diff --git a/Engine/source/persistence/taml/taml.cpp b/Engine/source/persistence/taml/taml.cpp index 2bfd104b9..782731a80 100644 --- a/Engine/source/persistence/taml/taml.cpp +++ b/Engine/source/persistence/taml/taml.cpp @@ -217,11 +217,6 @@ ImplementEnumType(_TamlFormatMode, FileStream stream; - if (StringTable->insert("c://.asset.taml") == StringTable->insert(mFilePathBuffer)) - { - bool asdfasdf = true; - } - // File opened? if (!stream.open(mFilePathBuffer, Torque::FS::File::Write)) { @@ -643,6 +638,19 @@ ImplementEnumType(_TamlFormatMode, // Fetch field count. const U32 fieldCount = fieldList.size(); + ConsoleObject* defaultConObject; + SimObject* defaultObject; + if (!getWriteDefaults()) + { + // Create a default object of the same type + defaultConObject = ConsoleObject::create(pSimObject->getClassName()); + defaultObject = dynamic_cast(defaultConObject); + + // ***Really*** shouldn't happen + if (!defaultObject) + return; + } + // Iterate fields. U8 arrayDepth = 0; TamlCustomNode* currentArrayNode = NULL; @@ -709,9 +717,6 @@ ImplementEnumType(_TamlFormatMode, if (!pFieldValue) pFieldValue = StringTable->EmptyString(); - if (pField->type == TypeBool) - pFieldValue = dAtob(pFieldValue) ? "true" : "false"; - U32 nBufferSize = dStrlen(pFieldValue) + 1; FrameTemp valueCopy(nBufferSize); dStrcpy((char *)valueCopy, pFieldValue, nBufferSize); @@ -720,9 +725,19 @@ ImplementEnumType(_TamlFormatMode, if (!pSimObject->writeField(fieldName, valueCopy)) continue; + if (!getWriteDefaults()) + { + //If the field hasn't been changed from the default value, then don't bother writing it out + if (dStricmp(defaultObject->getDataField(fieldName, indexBuffer), pFieldValue) == 0) + continue; + } + // Reassign field value. pFieldValue = valueCopy; + if (pField->type == TypeBool) + pFieldValue = dAtob(pFieldValue) ? "true" : "false"; + // Detect and collapse relative path information char fnBuf[1024]; if ((S32)pField->type == TypeFilename) @@ -741,6 +756,12 @@ ImplementEnumType(_TamlFormatMode, } } } + + if (!getWriteDefaults()) + { + // Cleanup our created default object + delete defaultConObject; + } } //----------------------------------------------------------------------------- From 696c2e2eec35df9dd39333cd258232ef02c768f8 Mon Sep 17 00:00:00 2001 From: JeffR Date: Wed, 2 Feb 2022 01:11:33 -0600 Subject: [PATCH 020/145] Add sanity check for default value results checking when filtering out default values Add additional utility functions for updating parsed object data in the project importer Adds logic to find and associate FX materials to their terrainMaterials and adding them to the terrian material asset if found on project importer --- Engine/source/console/simObject.cpp | 2 +- Engine/source/persistence/taml/taml.cpp | 3 +- .../pre40/T3Dpre4ProjectImporter.tscript | 139 +++++++++++++++++- .../scripts/projectImporter.tscript | 116 +++++++++++++-- 4 files changed, 242 insertions(+), 18 deletions(-) diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 1a76e23fe..3552f4dd1 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -338,7 +338,7 @@ void SimObject::writeFields(Stream &stream, U32 tabStop) //If the field hasn't been changed from the default value, then don't bother writing it out const char* defaultValueCheck = defaultObject->getDataField(f->pFieldname, array); - if (dStricmp(defaultValueCheck, valCopy) == 0) + if (defaultValueCheck != '\0' && dStricmp(defaultValueCheck, valCopy) == 0) continue; val = valCopy; diff --git a/Engine/source/persistence/taml/taml.cpp b/Engine/source/persistence/taml/taml.cpp index 782731a80..5200dcf28 100644 --- a/Engine/source/persistence/taml/taml.cpp +++ b/Engine/source/persistence/taml/taml.cpp @@ -728,7 +728,8 @@ ImplementEnumType(_TamlFormatMode, if (!getWriteDefaults()) { //If the field hasn't been changed from the default value, then don't bother writing it out - if (dStricmp(defaultObject->getDataField(fieldName, indexBuffer), pFieldValue) == 0) + const char* fieldData = defaultObject->getDataField(fieldName, indexBuffer); + if (fieldData != '\0' && dStricmp(fieldData, pFieldValue) == 0) continue; } diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript index e109d2f5e..c6ac5c2b2 100644 --- a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript @@ -892,6 +892,77 @@ T3Dpre4ProjectImporter::genProcessor("Material", $MaterialEntriesList); //============================================================================== function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %objectName) { + //first, lets do a bit of use-case checking. Materials are sometimes companion to + //a terrain material for effects and game physics behavior and may not be immediately + //obviously assocated. Lets check for that first before processing this as a regular material + %mapTo = findObjectField(%fileObject, "mapTo"); + if(%mapTo !$= "") + { + %terrainMatAsset = ""; + %terrainMat = ""; + if(isObject(%mapTo) && %mapTo.getClassName() $= "TerrainMaterial") + { + //If the terrain material already exists as a full object, look up it's + //asset to associate this FX material to it + %terrainMatAsset = TerrainMaterialAsset::getAssetIdByMaterialName(%mapTo.getName()); + + //Now we make our scripted definition "real", and append it to our asset + //so it is serialized. + %objectDefinition = ""; + for(%l=0; %l < %fileObject.count(); %l++) + { + %objectLine = %fileObject.getKey(%l); + if(!isObject(%objectLine)) + { + %objectDefinition = %objectDefinition @ %objectLine; + } + } + + eval(%objectDefinition); + + if(isObject(%objectName)) + { + %terrainMatAsset.add(%objectName); + + %terrainMatAsset.saveAsset(); + %fileObject.processed = true; + %fileObject.skip = true; //don't write the def back out to script, it's not needed now + } + + return false; + } + else + { + //No existing object, so probably incoming with the import, so lets go + //look for it + %terrMatList = getObjectsInFilesByClass("TerrainMaterial"); + for(%i=0; %i < getFieldCount(%terrMatList); %i++) + { + %terrainMatObj = getField(%terrMatList, %i); + if(%terrainMatObj.objectName $= %mapTo) + { + %terrainMat = %terrainMatObj; + } + else + { + %terrainObjIntName = findObjectField(%terrainMatObj, "internalName"); + if(%terrainObjIntName $= %mapTo) + { + %terrainMat = %terrainMatObj; + } + } + + if(%terrainMat !$= "") + { + //found it, not imported yet, so mark it for later + %terrainMat.FXMaterial = %fileObject; + + return false; + } + } + } + } + %matAsset = MaterialAsset::getAssetIdByMaterialName(%objectName); if(%matAsset $= "" || %matAsset $= "Core_Rendering:NoMaterial") @@ -1045,6 +1116,8 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject materialDefinitionName = %objectName; }; + renameObjectName(%fileObject, %objectName); + //Now we make our scripted definition "real", and append it to our asset //so it is serialized. %objectDefinition = ""; @@ -1057,9 +1130,6 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject } } - //Shift to object name, internal name will be used for assetID store - %objectDefinition.name = findObjectField(%fileObject, "internalName"); - eval(%objectDefinition); if(isObject(%objectName)) @@ -1072,6 +1142,69 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject %asset.add(%objectName); } + else + { + error("T3Dpre4ProjectImporter::processTerrainMaterialObject() - failed to parse terrainmat object: "); + echo(%objectDefinition); + } + + if(%fileObject.FXMaterial $= "") + { + //on the off-chance it exists, try scanning for FX materials associated + //to this terrain material + %fxMat = findObjectInFiles("TerrainFX_" @ %objectName); + if(%fxMat !$= "" && %objectName.classType $= "Material") + { + %fileObject.FXMaterial = %fxMat; + } + else + { + %fxMatList = getObjectsInFilesByClass("Material"); + for(%i=0; %i < getFieldCount(%fxMatList); %i++) + { + %fxMatObj = getField(%fxMatList, %i); + %fxMatObjMapTo = findObjectField(%fxMatObj, "mapTo"); + if(%fxMatObjMapTo $= %objectName) + { + %fileObject.FXMaterial = %fxMatObj; + break; + } + } + } + } + + if(%fileObject.FXMaterial !$= "") + { + //Ensure our mapto is up to date for any name sanitize/tweaks + setObjectField(%fileObject.FXMaterial, "mapTo", %objectName); + + //we associated to an FX material, so process that now + %objectDefinition = ""; + for(%l=0; %l < %fileObject.FXMaterial.count(); %l++) + { + %objectLine = %fileObject.FXMaterial.getKey(%l); + if(!isObject(%objectLine)) + { + %objectDefinition = %objectDefinition @ %objectLine; + } + } + + eval(%objectDefinition); + + if(isObject(%fileObject.FXMaterial.objectName)) + { + //if we created it successfully, set up inheritance for serialization if needed + if(%fileObject.FXMaterial.parentName !$= "") + { + %fileObject.FXMaterial.setFieldValue("inheritFrom",%fileObject.FXMaterial.parentName); + } + + %asset.add(%fileObject.FXMaterial.objectName); + } + + %fileObject.FXMaterial.processed = true; + %fileObject.FXMaterial.skip = true; + } %success = false; if(TamlWrite(%asset, %tamlpath)) diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index af600e8c3..2e98c9b03 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -870,11 +870,8 @@ function findFileInImporting(%checkFile) //============================================================================== // Checks if the object in question is defined in any of our pre-scanned list of importing files //============================================================================== -function findObjectInFiles(%objectName, %arrayObj) +function findObjectInFilesRecurse(%objectName, %arrayObj) { - if(%arrayObj $= "") - %arrayObj = $ProjectImporter::FileList; - for(%i=0; %i < %arrayObj.count(); %i++) { %objectLine = %arrayObj.getKey(%i); @@ -884,7 +881,7 @@ function findObjectInFiles(%objectName, %arrayObj) return %objectLine; //If this object isn't it, try recursing any children - %result = findObjectInFiles(%objectName, %objectLine); + %result = findObjectInFilesRecurse(%objectName, %objectLine); if(%result !$= "") return %result; } @@ -893,6 +890,65 @@ function findObjectInFiles(%objectName, %arrayObj) return ""; } +function findObjectInFiles(%objectName) +{ + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %objectLine = $ProjectImporter::FileList.getValue(%i); + if(isObject(%objectLine)) + { + if(%objectLine.objectName $= %objectName) + return %objectLine; + + //If this object isn't it, try recursing any children + %result = findObjectInFilesRecurse(%objectName, %objectLine); + if(%result !$= "") + return %result; + } + } + + return ""; +} + +//============================================================================== +// Checks if the object in question is defined in any of our pre-scanned list of importing files +//============================================================================== +function getObjectsInFilesByClassRecurse(%className, %arrayObj) +{ + for(%i=0; %i < %arrayObj.count(); %i++) + { + %objectLine = %arrayObj.getKey(%i); + if(isObject(%objectLine)) + { + if(%objectLine.classType $= %className) + $ProjectImporter::queryList = $ProjectImporter::queryList TAB %objectLine; + + //If this object isn't it, try recursing any children + getObjectsInFilesByClassRecurse(%className, %objectLine); + } + } +} + +function getObjectsInFilesByClass(%className) +{ + $ProjectImporter::queryList = ""; + + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %objectLine = $ProjectImporter::FileList.getValue(%i); + if(isObject(%objectLine)) + { + if(%objectLine.classType $= %className) + $ProjectImporter::queryList = $ProjectImporter::queryList TAB %objectLine; + + //If this object isn't it, try recursing any children + getObjectsInFilesByClassRecurse(%className, %objectLine); + } + } + + return ltrim($ProjectImporter::queryList); +} + //============================================================================== // Takes a filename lacking an extension and then checks common file extensions // to see if we can find the actual file in question @@ -1110,18 +1166,30 @@ function renameObjectName(%object, %newName) %objectLine = %object.getKey(%e); if(!isObject(%objectLine)) { - if(strIsMatchExpr("*singleton*(*)*", %objectLine) && - strIsMatchExpr("*new*(*)*", %objectLine) && + if(strIsMatchExpr("*singleton*(*)*", %objectLine) || + strIsMatchExpr("*new*(*)*", %objectLine) || strIsMatchExpr("*datablock*(*)*", %objectLine)) { - %newLine = strreplace(%object.objectName, %newName); - - echo("renameObjectName() - lines changed from:"); - echo(%objectLine); - echo("to:"); - echo(%newLine); + if(%object.objectName $= "") + { + %start = strpos(%objectLine, "("); + %end = strpos(%objectLine, ")", %start); + + %preString = getSubStr(%objectLine, 0, %start+1); + %postString = getSubStr(%objectLine, %end); + + %renamedString = %preString @ %newName @ %postString; + + %newLine = %renamedString; + } + else + { + %newLine = strreplace(%objectLine, %object.objectName, %newName); + } %object.setKey(%newLine, %e); + + %object.objectName = %newName; } } } @@ -1258,6 +1326,28 @@ function setObjectField(%object, %fieldName, %newValue) } } +//============================================================================== +// Inserts a new field to an object's block in the preprocessed data +//============================================================================== +function insertObjectLine(%object, %newLine) +{ + for(%e=0; %e < %object.count(); %e++) + { + %objectLine = %object.getKey(%e); + + if(strIsMatchExpr("*{*", %objectLine) || + strIsMatchExpr("*singleton*(*)*", %objectLine) || + strIsMatchExpr("*new*(*)*", %objectLine) || + strIsMatchExpr("*datablock*(*)*", %objectLine)) + { + continue; + } + + %object.insert(%newLine, "", %e); + return; + } +} + //============================================================================== // Takes a string and adds it to the importer's log. Optionally can print the line // directly to console for debugging purposes From 79eebdd5f3541b9608ad529fca209e425d6ed144 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sat, 12 Feb 2022 15:53:40 -0600 Subject: [PATCH 021/145] Cleaned and repacked work to update the probe bin and reflection probe behavior to clean and standardize it. --- .../T3D/lighting/boxEnvironmentProbe.cpp | 4 +- .../source/T3D/lighting/reflectionProbe.cpp | 45 +- Engine/source/T3D/lighting/reflectionProbe.h | 79 +- Engine/source/T3D/lighting/skylight.cpp | 4 +- .../T3D/lighting/sphereEnvironmentProbe.cpp | 77 +- .../T3D/lighting/sphereEnvironmentProbe.h | 4 - Engine/source/environment/scatterSky.cpp | 8 - .../source/renderInstance/renderProbeMgr.cpp | 810 +++++++++--------- Engine/source/renderInstance/renderProbeMgr.h | 437 ++++++---- .../shaderGen/GLSL/shaderFeatureGLSL.cpp | 147 ++-- .../shaderGen/HLSL/shaderFeatureHLSL.cpp | 70 +- Engine/source/shaderGen/shaderGenVars.cpp | 14 +- Engine/source/shaderGen/shaderGenVars.h | 10 +- .../reflectionProbeArrayPostFX.tscript | 2 + .../core/rendering/shaders/gl/lighting.glsl | 82 +- .../game/core/rendering/shaders/lighting.hlsl | 86 +- .../lighting/advanced/gl/pointLightP.glsl | 32 + .../advanced/gl/reflectionProbeArrayP.glsl | 64 +- .../lighting/advanced/gl/spotLightP.glsl | 35 + .../lighting/advanced/gl/vectorLightP.glsl | 33 +- .../lighting/advanced/pointLightP.hlsl | 9 +- .../advanced/reflectionProbeArrayP.hlsl | 63 +- .../shaders/lighting/advanced/spotLightP.hlsl | 9 +- .../lighting/advanced/vectorLightP.hlsl | 1 - 24 files changed, 1113 insertions(+), 1012 deletions(-) diff --git a/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp b/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp index a08691d1c..e532acd3c 100644 --- a/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp +++ b/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp @@ -77,7 +77,7 @@ ConsoleDocClass(BoxEnvironmentProbe, BoxEnvironmentProbe::BoxEnvironmentProbe() : ReflectionProbe() { mCaptureMask = REFLECTION_PROBE_CAPTURE_TYPEMASK; - mProbeShapeType = ProbeRenderInst::Box; + mProbeShapeType = ProbeInfo::Box; mAtten = 0.0; } @@ -158,7 +158,7 @@ void BoxEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream) void BoxEnvironmentProbe::updateProbeParams() { - mProbeShapeType = ProbeRenderInst::Box; + mProbeShapeType = ProbeInfo::Box; mProbeInfo.mAtten = mAtten; Parent::updateProbeParams(); diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index 9361b05f1..1715ac758 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -73,8 +73,8 @@ ConsoleDocClass(ReflectionProbe, ImplementEnumType(ReflectProbeType, "Type of mesh data available in a shape.\n" "@ingroup gameObjects") -{ ProbeRenderInst::Sphere, "Sphere", "Sphere shaped" }, -{ ProbeRenderInst::Box, "Box", "Box shape" } +{ ReflectionProbe::ProbeInfo::Sphere, "Sphere", "Sphere shaped" }, +{ ReflectionProbe::ProbeInfo::Box, "Box", "Box shape" } EndImplementEnumType; ImplementEnumType(ReflectionModeEnum, @@ -97,7 +97,7 @@ ReflectionProbe::ReflectionProbe() mTypeMask = LightObjectType | MarkerObjectType; - mProbeShapeType = ProbeRenderInst::Box; + mProbeShapeType = ProbeInfo::Box; mReflectionModeType = BakedCubemap; @@ -121,8 +121,6 @@ ReflectionProbe::ReflectionProbe() mRefreshRateMS = 200; mDynamicLastBakeMS = 0; - mMaxDrawDistance = 75; - mResourcesCreated = false; mPrefilterSize = 64; mPrefilterMipLevels = mLog2(F32(mPrefilterSize)); @@ -239,7 +237,7 @@ bool ReflectionProbe::_setRadius(void *object, const char *index, const char *da { ReflectionProbe* probe = reinterpret_cast(object); - if (probe->mProbeShapeType != ProbeRenderInst::Sphere) + if (probe->mProbeShapeType != ProbeInfo::Sphere) return false; probe->mObjScale = Point3F(probe->mRadius, probe->mRadius, probe->mRadius); @@ -291,7 +289,7 @@ bool ReflectionProbe::onAdd() if (!mPersistentId) mPersistentId = getOrCreatePersistentId(); - mProbeUniqueID = String::ToString(mPersistentId->getUUID().getHash()); + mProbeUniqueID = mPersistentId->getUUID().toString(); } // Refresh this object's material (if any) @@ -312,7 +310,7 @@ void ReflectionProbe::onRemove() { if (isClientObject()) { - PROBEMGR->unregisterProbe(mProbeInfo.mProbeIdx); + PROBEMGR->unregisterProbe(&mProbeInfo); } // Remove this object from the scene @@ -461,10 +459,10 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream) if (stream->readFlag()) // StaticDataMask { - U32 shapeType = ProbeRenderInst::Sphere; + U32 shapeType = ProbeInfo::Sphere; stream->read(&shapeType); - mProbeShapeType = (ProbeRenderInst::ProbeShapeType)shapeType; + mProbeShapeType = (ProbeInfo::ProbeShapeType)shapeType; stream->read(&mRadius); @@ -497,6 +495,8 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream) //----------------------------------------------------------------------------- void ReflectionProbe::updateProbeParams() { + mProbeInfo.mObject = this; + if (!mResourcesCreated) { if (!createClientResources()) @@ -507,12 +507,12 @@ void ReflectionProbe::updateProbeParams() mProbeInfo.mProbeShapeType = mProbeShapeType; - if (mProbeShapeType == ProbeRenderInst::Sphere) + if (mProbeShapeType == ProbeInfo::Sphere) mObjScale.set(mRadius, mRadius, mRadius); Box3F bounds; - if (mProbeShapeType == ProbeRenderInst::Skylight) + if (mProbeShapeType == ProbeInfo::Skylight) { mProbeInfo.mPosition = Point3F::Zero; mProbeInfo.mTransform = MatrixF::Identity; @@ -564,8 +564,6 @@ void ReflectionProbe::updateProbeParams() else processDynamicCubemap(); } - - PROBEMGR->updateProbes(); } void ReflectionProbe::processDynamicCubemap() @@ -575,7 +573,7 @@ void ReflectionProbe::processDynamicCubemap() void ReflectionProbe::processBakedCubemap() { - mProbeInfo.mIsEnabled = false; + //mProbeInfo.mIsEnabled = false; if ((mReflectionModeType != BakedCubemap) || mProbeUniqueID.isEmpty()) return; @@ -611,7 +609,7 @@ void ReflectionProbe::processBakedCubemap() if (mEnabled && mProbeInfo.mPrefilterCubemap->isInitialized() && mProbeInfo.mIrradianceCubemap->isInitialized()) { - mProbeInfo.mIsEnabled = true; + //mProbeInfo.mIsEnabled = true; mCubemapDirty = false; @@ -622,6 +620,11 @@ void ReflectionProbe::processBakedCubemap() mProbeInfo.mPrefilterCubemap.free(); mProbeInfo.mIrradianceCubemap.free(); } + else + { + //if we failed, disable + mProbeInfo.mIsEnabled = false; + } } void ReflectionProbe::processStaticCubemap() @@ -811,16 +814,16 @@ void ReflectionProbe::createEditorResources() void ReflectionProbe::prepRenderImage(SceneRenderState *state) { - if (!mEnabled || !RenderProbeMgr::smRenderReflectionProbes) + if (!mEnabled || (!RenderProbeMgr::smRenderReflectionProbes && Con::getVariable("$Probes::Capturing", "0") == "0")) return; Point3F distVec = getRenderPosition() - state->getCameraPosition(); F32 dist = distVec.len(); //Culling distance. Can be adjusted for performance options considerations via the scalar - if (dist > mMaxDrawDistance * Con::getFloatVariable("$pref::GI::ProbeDrawDistScale", 1.0)) + if (dist > RenderProbeMgr::smMaxProbeDrawDistance * Con::getFloatVariable("$pref::GI::ProbeDrawDistScale", 1.0)) { - mProbeInfo.mScore = mMaxDrawDistance; + mProbeInfo.mScore = RenderProbeMgr::smMaxProbeDrawDistance; return; } @@ -842,7 +845,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state) //mProbeInfo.mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f); - PROBEMGR->submitProbe(mProbeInfo); + PROBEMGR->submitProbe(&mProbeInfo); #ifdef TORQUE_TOOLS if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mPrefilterMap != nullptr) @@ -938,7 +941,7 @@ void ReflectionProbe::_onRenderViz(ObjectRenderInst *ri, ColorI color = ColorI(255, 0, 255, 63); const MatrixF worldToObjectXfm = mObjToWorld; - if (mProbeShapeType == ProbeRenderInst::Sphere) + if (mProbeShapeType == ProbeInfo::Sphere) { draw->drawSphere(desc, mRadius, getPosition(), color); } diff --git a/Engine/source/T3D/lighting/reflectionProbe.h b/Engine/source/T3D/lighting/reflectionProbe.h index 017cd21df..af6947338 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.h +++ b/Engine/source/T3D/lighting/reflectionProbe.h @@ -41,10 +41,6 @@ #include "renderInstance/renderPassManager.h" #endif -#ifndef RENDER_PROBE_MGR_H -#include "renderInstance/renderProbeMgr.h" -#endif - class BaseMatInstance; //----------------------------------------------------------------------------- @@ -74,6 +70,67 @@ public: DynamicCubemap = 5, }; + /// + /// This contains all the important data the Probe uses for rendering. + /// + struct ProbeInfo + { + bool mIsEnabled; + + MatrixF mTransform; + + ReflectionProbe* mObject; + + F32 mRadius; + + bool mDirty; + + Box3F mBounds; + Point3F mExtents; + Point3F mPosition; + Point3F mProbeRefOffset; + Point3F mProbeRefScale; + F32 mAtten; + + F32 mScore; + + GFXCubemapHandle mPrefilterCubemap; + GFXCubemapHandle mIrradianceCubemap; + + /// The priority of this light used for + /// light and shadow scoring. + F32 mPriority; + + enum ProbeShapeType + { + Box = 0, + Sphere = 1, + Skylight = 2 + }; + + ProbeShapeType mProbeShapeType; + + public: + + ProbeInfo() : mScore(0) {} + ~ProbeInfo() {} + + // Copies data passed in from light + void set(const ProbeInfo* probeInfo); + + // Accessors + const MatrixF& getTransform() const { return mTransform; } + void setTransform(const MatrixF& xfm) { mTransform = xfm; } + + Point3F getPosition() const { return mPosition; } + void setPosition(const Point3F& pos) { mPosition = pos; } + + void setPriority(F32 priority) { mPriority = priority; } + F32 getPriority() const { return mPriority; } + + void clear(); + }; + protected: // Networking masks @@ -124,7 +181,7 @@ protected: /// /// The shape of the probe /// - ProbeRenderInst::ProbeShapeType mProbeShapeType; + ProbeInfo::ProbeShapeType mProbeShapeType; /// /// This is effectively a packed cache of the probe data actually utilized for rendering. @@ -132,7 +189,7 @@ protected: /// When the manager goes to render it has the compacted data to read over more efficiently for setting up what probes should /// Actually render in that frame /// - ProbeRenderInst mProbeInfo; + ProbeInfo mProbeInfo; /// /// Used to dictate what sort of cubemap the probes use when using IBL @@ -166,14 +223,13 @@ protected: CubemapData *mStaticCubemap; GFXCubemapHandle mDynamicCubemap; - String cubeDescName; - U32 cubeDescId; - ReflectorDesc *reflectorDesc; + //String cubeDescName; + //U32 cubeDescId; + //ReflectorDesc *reflectorDesc; //Utilized in dynamic reflections //CubeReflector mCubeReflector; - ///Prevents us from saving out the cubemaps(for now) but allows us the full HDR range on the in-memory cubemap captures bool mUseHDRCaptures; //irridiance resources @@ -196,7 +252,6 @@ protected: U32 mDynamicLastBakeMS; U32 mRefreshRateMS; - F32 mMaxDrawDistance; bool mResourcesCreated; U32 mCaptureMask; @@ -313,7 +368,7 @@ public: void bake(); }; -typedef ProbeRenderInst::ProbeShapeType ReflectProbeType; +typedef ReflectionProbe::ProbeInfo::ProbeShapeType ReflectProbeType; DefineEnumType(ReflectProbeType); typedef ReflectionProbe::ReflectionModeType ReflectionModeEnum; diff --git a/Engine/source/T3D/lighting/skylight.cpp b/Engine/source/T3D/lighting/skylight.cpp index 36036100b..09d813050 100644 --- a/Engine/source/T3D/lighting/skylight.cpp +++ b/Engine/source/T3D/lighting/skylight.cpp @@ -148,7 +148,7 @@ void Skylight::unpackUpdate(NetConnection *conn, BitStream *stream) void Skylight::updateProbeParams() { - mProbeShapeType = ProbeRenderInst::Skylight; + mProbeShapeType = ProbeInfo::Skylight; Parent::updateProbeParams(); } @@ -167,7 +167,7 @@ void Skylight::prepRenderImage(SceneRenderState *state) // Get a handy pointer to our RenderPassmanager //RenderPassManager *renderPass = state->getRenderPass(); - PROBEMGR->submitProbe(mProbeInfo); + PROBEMGR->submitProbe(&mProbeInfo); #ifdef TORQUE_TOOLS if (Skylight::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr) diff --git a/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp b/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp index 54e97b19f..b3e0865a7 100644 --- a/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp +++ b/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp @@ -77,7 +77,7 @@ ConsoleDocClass(SphereEnvironmentProbe, SphereEnvironmentProbe::SphereEnvironmentProbe() : ReflectionProbe() { mCaptureMask = REFLECTION_PROBE_CAPTURE_TYPEMASK; - mProbeShapeType = ProbeRenderInst::Sphere; + mProbeShapeType = ProbeInfo::Sphere; } SphereEnvironmentProbe::~SphereEnvironmentProbe() @@ -144,83 +144,10 @@ void SphereEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream void SphereEnvironmentProbe::updateProbeParams() { - mProbeShapeType = ProbeRenderInst::Sphere; + mProbeShapeType = ProbeInfo::Sphere; Parent::updateProbeParams(); } -void SphereEnvironmentProbe::prepRenderImage(SceneRenderState *state) -{ - if (!mEnabled || !ReflectionProbe::smRenderPreviewProbes) - return; - -#ifdef TORQUE_TOOLS - if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr) - { - GFXTransformSaver saver; - - // Calculate the distance of this object from the camera - Point3F cameraOffset; - getRenderTransform().getColumn(3, &cameraOffset); - cameraOffset -= state->getDiffuseCameraPosition(); - F32 dist = cameraOffset.len(); - if (dist < 0.01f) - dist = 0.01f; - - // Set up the LOD for the shape - F32 invScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z)); - - mEditorShapeInst->setDetailFromDistance(state, dist * invScale); - - // Make sure we have a valid level of detail - if (mEditorShapeInst->getCurrentDetail() < 0) - return; - - BaseMatInstance* probePrevMat = mEditorShapeInst->getMaterialList()->getMaterialInst(0); - - setPreviewMatParameters(state, probePrevMat); - - // GFXTransformSaver is a handy helper class that restores - // the current GFX matrices to their original values when - // it goes out of scope at the end of the function - - // Set up our TS render state - TSRenderState rdata; - rdata.setSceneState(state); - rdata.setFadeOverride(1.0f); - - // We might have some forward lit materials - // so pass down a query to gather lights. - LightQuery query; - query.init(getWorldSphere()); - rdata.setLightQuery(&query); - - // Set the world matrix to the objects render transform - MatrixF mat = getRenderTransform(); - mat.scale(Point3F(1, 1, 1)); - GFX->setWorldMatrix(mat); - - // Animate the the shape - mEditorShapeInst->animate(); - - // Allow the shape to submit the RenderInst(s) for itself - mEditorShapeInst->render(rdata); - - saver.restore(); - } - - // If the light is selected or light visualization - // is enabled then register the callback. - const bool isSelectedInEditor = (gEditingMission && isSelected()); - if (isSelectedInEditor) - { - ObjectRenderInst *ri = state->getRenderPass()->allocInst(); - ri->renderDelegate.bind(this, &ReflectionProbe::_onRenderViz); - ri->type = RenderPassManager::RIT_Editor; - state->getRenderPass()->addInst(ri); - } -#endif -} - void SphereEnvironmentProbe::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat) { Parent::setPreviewMatParameters(renderState, mat); diff --git a/Engine/source/T3D/lighting/sphereEnvironmentProbe.h b/Engine/source/T3D/lighting/sphereEnvironmentProbe.h index dc3c9a1a6..3df0b98b5 100644 --- a/Engine/source/T3D/lighting/sphereEnvironmentProbe.h +++ b/Engine/source/T3D/lighting/sphereEnvironmentProbe.h @@ -98,10 +98,6 @@ public: // use the same Materials. //-------------------------------------------------------------------------- virtual void updateProbeParams(); - - // This is the function that allows this object to submit itself for rendering - void prepRenderImage(SceneRenderState *state); - void setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat); }; diff --git a/Engine/source/environment/scatterSky.cpp b/Engine/source/environment/scatterSky.cpp index 36ab28ecf..5de3bdd94 100644 --- a/Engine/source/environment/scatterSky.cpp +++ b/Engine/source/environment/scatterSky.cpp @@ -970,14 +970,6 @@ void ScatterSky::_render( ObjectRenderInst *ri, SceneRenderState *state, BaseMat xform *= GFX->getViewMatrix(); xform *= GFX->getWorldMatrix(); - if(state->isReflectPass()) - { - static MatrixF rotMat(EulerF(0.0, 0.0, M_PI_F)); - xform.mul(rotMat); - rotMat.set(EulerF(M_PI_F, 0.0, 0.0)); - xform.mul(rotMat); - } - mShaderConsts->setSafe( mModelViewProjSC, xform ); mShaderConsts->setSafe( mMiscSC, miscParams ); mShaderConsts->setSafe( mSphereRadiiSC, sphereRadii ); diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index bfbf65815..268bba5e5 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -20,13 +20,8 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- #include "renderProbeMgr.h" -#include "console/consoleTypes.h" -#include "scene/sceneObject.h" -#include "materials/materialManager.h" -#include "scene/sceneRenderState.h" #include "math/util/sphereMesh.h" #include "math/util/matrixSet.h" -#include "materials/processedMaterial.h" #include "renderInstance/renderDeferredMgr.h" #include "math/mPolyhedron.impl.h" #include "gfx/gfxTransformSaver.h" @@ -34,90 +29,60 @@ #include "gfx/gfxDebugEvent.h" #include "shaderGen/shaderGenVars.h" #include "materials/shaderData.h" - -#include "gfx/gfxTextureManager.h" #include "scene/reflectionManager.h" #include "postFx/postEffect.h" #include "T3D/lighting/reflectionProbe.h" #include "T3D/lighting/IBLUtilities.h" +#include "T3D/Scene.h" //For our cameraQuery setup #include "T3D/gameTSCtrl.h" -#include "T3D/Scene.h" #define TORQUE_GFX_VISUAL_DEBUG //renderdoc debugging IMPLEMENT_CONOBJECT(RenderProbeMgr); ConsoleDocClass( RenderProbeMgr, - "@brief A render bin which uses object callbacks for rendering.\n\n" - "This render bin gathers object render instances and calls its delegate " - "method to perform rendering. It is used infrequently for specialized " - "scene objects which perform custom rendering.\n\n" + "@brief This render bin handles the rendering of reflection probes to provide IBL\n" + "lighting for PBR\n\n" + "Probes when added to the scene, are registered to the Manager, and then during the steps\n" + "leading up to the frame being rendered, the probes submit to the Manager that they are ready to be rendered\n" + "resulting in them being added to the active list.\n" + "When the manager is invoked to render, it processes the active probe list and finds the best probes based on\n" + "settings like max probes per frame, probe score, etc to get the final list of probes to be submitted to the shader.\n\n" "@ingroup RenderBin\n" ); RenderProbeMgr *RenderProbeMgr::smProbeManager = NULL; +// This variable is a global toggle on if reflection probes should be rendered or not bool RenderProbeMgr::smRenderReflectionProbes = true; + +// This variable defines the maximum draw distance of a probe. F32 RenderProbeMgr::smMaxProbeDrawDistance = 100; + +// This variable defines the maximum number of probes that can be rendered in a single frame in deferred S32 RenderProbeMgr::smMaxProbesPerFrame = 8; -S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b) -{ - // Debug Profiling. - PROFILE_SCOPE(AdvancedLightBinManager_AscendingReflectProbeInfluence); - - // Fetch asset definitions. - const ProbeRenderInst* pReflectProbeA = (*(ProbeRenderInst**)a); - const ProbeRenderInst* pReflectProbeB = (*(ProbeRenderInst**)b); - //sort by score - return pReflectProbeA->mScore - pReflectProbeB->mScore; -} +S32 RenderProbeMgr::smProbeBakeResolution = 64; // // ProbeRenderInst::ProbeRenderInst() : - mIsEnabled(true), - mTransform(true), - mDirty(false), - mPriority(1.0f), - mScore(0.0f), - mPrefilterCubemap(NULL), - mIrradianceCubemap(NULL), - mRadius(1.0f), - mProbeRefOffset(0, 0, 0), - mProbeRefScale(1,1,1), - mAtten(0.0), mCubemapIndex(0), - mProbeIdx(0), - mProbeShapeType(Box) + mProbeInfo(nullptr) { } ProbeRenderInst::~ProbeRenderInst() { - if (mPrefilterCubemap && mPrefilterCubemap.isValid()) - { - mPrefilterCubemap.free(); - } - if (mIrradianceCubemap && mIrradianceCubemap.isValid()) - { - mIrradianceCubemap.free(); - } } -void ProbeRenderInst::set(const ProbeRenderInst *probeInfo) +void ProbeRenderInst::set(const ProbeRenderInst *probe) { - mTransform = probeInfo->mTransform; - mPrefilterCubemap = probeInfo->mPrefilterCubemap; - mIrradianceCubemap = probeInfo->mIrradianceCubemap; - mRadius = probeInfo->mRadius; - mProbeShapeType = probeInfo->mProbeShapeType; - mBounds = probeInfo->mBounds; - mScore = probeInfo->mScore; - mAtten = probeInfo->mAtten; + mCubemapIndex = probe->mCubemapIndex; + mProbeInfo = probe->mProbeInfo; } // @@ -125,16 +90,17 @@ void ProbeRenderInst::set(const ProbeRenderInst *probeInfo) ProbeShaderConstants::ProbeShaderConstants() : mInit(false), mShader(NULL), - mProbePositionSC(NULL), - mProbeRefPosSC(NULL), - mRefScaleSC(NULL), - mProbeConfigDataSC(NULL), - mProbeSpecularCubemapSC(NULL), - mProbeIrradianceCubemapSC(NULL), + mProbePositionArraySC(NULL), + mProbeRefPosArraySC(NULL), + mRefScaleArraySC(NULL), + mProbeConfigDataArraySC(NULL), + mProbeSpecularCubemapArraySC(NULL), + mProbeIrradianceCubemapArraySC(NULL), mProbeCountSC(NULL), mBRDFTextureMap(NULL), mSkylightCubemapIdxSC(NULL), - mWorldToObjArraySC(NULL) + mWorldToObjArraySC(NULL), + mMaxProbeDrawDistanceSC(NULL) { } @@ -159,29 +125,31 @@ void ProbeShaderConstants::init(GFXShader* shader) } //Reflection Probes - mProbePositionSC = shader->getShaderConstHandle(ShaderGenVars::probePosition); - mProbeRefPosSC = shader->getShaderConstHandle(ShaderGenVars::probeRefPos); - mRefScaleSC = shader->getShaderConstHandle(ShaderGenVars::refScale); + mProbePositionArraySC = shader->getShaderConstHandle(ShaderGenVars::probePositionArray); + mProbeRefPosArraySC = shader->getShaderConstHandle(ShaderGenVars::probeRefPosArray); + mRefScaleArraySC = shader->getShaderConstHandle(ShaderGenVars::refScaleArray); mWorldToObjArraySC = shader->getShaderConstHandle(ShaderGenVars::worldToObjArray); - mProbeConfigDataSC = shader->getShaderConstHandle(ShaderGenVars::probeConfigData); - mProbeSpecularCubemapSC = shader->getShaderConstHandle(ShaderGenVars::specularCubemapAR); - mProbeIrradianceCubemapSC = shader->getShaderConstHandle(ShaderGenVars::irradianceCubemapAR); + mProbeConfigDataArraySC = shader->getShaderConstHandle(ShaderGenVars::probeConfigDataArray); + mProbeSpecularCubemapArraySC = shader->getShaderConstHandle(ShaderGenVars::specularCubemapAR); + mProbeIrradianceCubemapArraySC = shader->getShaderConstHandle(ShaderGenVars::irradianceCubemapAR); mProbeCountSC = shader->getShaderConstHandle(ShaderGenVars::probeCount); mBRDFTextureMap = shader->getShaderConstHandle(ShaderGenVars::BRDFTextureMap); mSkylightCubemapIdxSC = shader->getShaderConstHandle(ShaderGenVars::skylightCubemapIdx); + mMaxProbeDrawDistanceSC = shader->getShaderConstHandle(ShaderGenVars::maxProbeDrawDistance); + mInit = true; } bool ProbeShaderConstants::isValid() { - if (mProbePositionSC->isValid() || - mProbeConfigDataSC->isValid() || - mRefScaleSC->isValid() || - mProbeSpecularCubemapSC->isValid() || - mProbeIrradianceCubemapSC->isValid()) + if (mProbePositionArraySC->isValid() || + mProbeConfigDataArraySC->isValid() || + mRefScaleArraySC->isValid() || + mProbeSpecularCubemapArraySC->isValid() || + mProbeIrradianceCubemapArraySC->isValid()) return true; return false; @@ -199,11 +167,9 @@ RenderProbeMgr::RenderProbeMgr() : RenderBinManager(RenderPassManager::RIT_Probes, 1.0f, 1.0f), mLastShader(nullptr), mLastConstants(nullptr), - mProbesDirty(false), mHasSkylight(false), mSkylightCubemapIdx(-1), mCubeMapCount(0), - mDefaultSkyLight(nullptr), mUseHDRCaptures(true) { mEffectiveProbeCount = 0; @@ -220,9 +186,6 @@ RenderProbeMgr::RenderProbeMgr() { mCubeMapSlots[i] = false; } - - mPrefilterSize = 64; - mPrefilterMipLevels = mLog2(F32(mPrefilterSize)) + 1; } RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder) @@ -231,17 +194,12 @@ RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 proce mCubeMapCount = 0; dMemset(mCubeMapSlots, false, sizeof(mCubeMapSlots)); mCubeSlotCount = PROBE_ARRAY_SLOT_BUFFER_SIZE; - mDefaultSkyLight = nullptr; mEffectiveProbeCount = 0; mHasSkylight = false; mSkylightCubemapIdx = -1; mLastConstants = nullptr; mMipCount = 0; - mProbesDirty = false; mUseHDRCaptures = true; - - mPrefilterSize = 64; - mPrefilterMipLevels = mLog2(F32(mPrefilterSize)) + 1; } RenderProbeMgr::~RenderProbeMgr() @@ -266,29 +224,10 @@ bool RenderProbeMgr::onAdd() mPrefilterArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); //pre-allocate a few slots - mIrradianceArray->init(PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_IRRAD_SIZE, PROBE_FORMAT); - mPrefilterArray->init(PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_PREFILTER_SIZE, PROBE_FORMAT); + mIrradianceArray->init(PROBE_ARRAY_SLOT_BUFFER_SIZE, RenderProbeMgr::smProbeBakeResolution, PROBE_FORMAT); + mPrefilterArray->init(PROBE_ARRAY_SLOT_BUFFER_SIZE, RenderProbeMgr::smProbeBakeResolution, PROBE_FORMAT); mCubeSlotCount = PROBE_ARRAY_SLOT_BUFFER_SIZE; - //create our own default default skylight - mDefaultSkyLight = new ProbeRenderInst; - mDefaultSkyLight->mProbeShapeType = ProbeRenderInst::Skylight; - mDefaultSkyLight->mIsEnabled = false; - - String defaultIrradMapPath = GFXTextureManager::getDefaultIrradianceCubemapPath(); - if (!mDefaultSkyLight->mIrradianceCubemap.set(defaultIrradMapPath)) - { - Con::errorf("RenderProbeMgr::onAdd: Failed to load default irradiance cubemap"); - return false; - } - - String defaultPrefilterPath = GFXTextureManager::getDefaultPrefilterCubemapPath(); - if (!mDefaultSkyLight->mPrefilterCubemap.set(defaultPrefilterPath)) - { - Con::errorf("RenderProbeMgr::onAdd: Failed to load default prefilter cubemap"); - return false; - } - String brdfTexturePath = GFXTextureManager::getBRDFTexturePath(); if (!mBRDFTexture.set(brdfTexturePath, &GFXTexturePersistentProfile, "BRDFTexture")) { @@ -316,22 +255,103 @@ void RenderProbeMgr::consoleInit() // Vars for debug rendering while the RoadEditor is open, only used if smEditorOpen is true. Con::addVariable("$pref::maxProbeDrawDistance", TypeF32, &RenderProbeMgr::smMaxProbeDrawDistance, "Max distance for reflection probes to render.\n"); Con::addVariable("$pref::MaxProbesPerFrame", TypeS32, &RenderProbeMgr::smMaxProbesPerFrame, "Max number of Environment Probes that can be rendered per-frame.\n"); + Con::addVariable("$pref::ReflectionProbes::BakeResolution", TypeS32, &RenderProbeMgr::smProbeBakeResolution, ""); + } -void RenderProbeMgr::registerProbe(ProbeRenderInst* newProbe) +//============================================================================= +// Utility functions for processing and setting up the probes for rendering +//============================================================================= +S32 QSORT_CALLBACK RenderProbeMgr::_probeScoreCmp(const ProbeRenderInst* a, const ProbeRenderInst* b) +{ + F32 diff = a->mProbeInfo->mScore - b->mProbeInfo->mScore; + return diff > 0 ? 1 : diff < 0 ? -1 : 0; +} +void RenderProbeMgr::getBestProbes(const Point3F& objPosition, ProbeDataSet* probeDataSet) +{ + PROFILE_SCOPE(ProbeManager_getBestProbes); + + //Array rendering + U32 probeCount = mActiveProbes.size(); + + Vector bestPickProbes; + bestPickProbes.setSize(probeDataSet->maxProbeCount); + bestPickProbes.fill(-1); + + mHasSkylight = false; + probeDataSet->skyLightIdx = -1; + + probeDataSet->effectiveProbeCount = 0; + for (U32 i = 0; i < probeCount; i++) + { + //Check if we've already got a skylight. If we do and we've otherwise filled to our max amounto of probes alloewed, then bail + if (mHasSkylight && probeDataSet->effectiveProbeCount >= probeDataSet->maxProbeCount) + break; + + const ProbeRenderInst& curEntry = mActiveProbes[i]; + + //Obviously, if the probe is marked as not enabled, we skip + if (!curEntry.mProbeInfo->mIsEnabled) + continue; + + if (curEntry.mProbeInfo->mProbeShapeType != ReflectionProbe::ProbeInfo::Skylight) + { + if (probeDataSet->effectiveProbeCount < probeDataSet->maxProbeCount) + { + bestPickProbes[probeDataSet->effectiveProbeCount] = i; + probeDataSet->effectiveProbeCount++; + } + } + else + { + probeDataSet->skyLightIdx = curEntry.mCubemapIndex; + mHasSkylight = true; + } + } + + //If we, for whatever reason, have nothing, bail now + if (mHasSkylight == false && probeDataSet->effectiveProbeCount == 0) + return; + + //Grab our best probe picks + for (U32 i = 0; i < bestPickProbes.size(); i++) + { + if (bestPickProbes[i] == -1) + continue; + + const ProbeRenderInst& curEntry = mActiveProbes[bestPickProbes[i]]; + probeDataSet->probeConfigArray[i] = Point4F(curEntry.mProbeInfo->mProbeShapeType, + curEntry.mProbeInfo->mRadius, + curEntry.mProbeInfo->mAtten, + curEntry.mCubemapIndex); + + MatrixF p2A = curEntry.mProbeInfo->mTransform; + probeDataSet->probeWorldToObjArray[i] = p2A; + p2A.inverse(); + probeDataSet->refScaleArray[i] = curEntry.mProbeInfo->mProbeRefScale / p2A.getScale(); + + Point3F probePos = curEntry.mProbeInfo->mObject->getPosition(); + Point3F refPos = probePos + curEntry.mProbeInfo->mProbeRefOffset * probeDataSet->refScaleArray[i].asPoint3F(); + + probeDataSet->probePositionArray[i] = Point4F(probePos.x, probePos.y, probePos.z, 0); + probeDataSet->probeRefPositionArray[i] = Point4F(refPos.x, refPos.y, refPos.z, 0); + + } +} + +void RenderProbeMgr::registerProbe(ReflectionProbe::ProbeInfo* newProbe) { //Can't have over the probe limit if (mRegisteredProbes.size() + 1 >= PROBE_MAX_COUNT) return; - mRegisteredProbes.push_back(newProbe); - - newProbe->mProbeIdx = mRegisteredProbes.size() - 1; + ProbeRenderInst newProbeRenderInst; + newProbeRenderInst.mProbeInfo = newProbe; const U32 cubeIndex = _findNextEmptyCubeSlot(); if (cubeIndex == INVALID_CUBE_SLOT) { - Con::warnf("RenderProbeMgr::addProbe: Invalid cubemap slot."); + Con::warnf("RenderProbeMgr::registerProbe() - Invalid cubemap slot."); return; } @@ -342,8 +362,8 @@ void RenderProbeMgr::registerProbe(ProbeRenderInst* newProbe) GFXCubemapArrayHandle irr = GFXCubemapArrayHandle(GFX->createCubemapArray()); GFXCubemapArrayHandle prefilter = GFXCubemapArrayHandle(GFX->createCubemapArray()); - irr->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_IRRAD_SIZE, PROBE_FORMAT); - prefilter->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_PREFILTER_SIZE, PROBE_FORMAT); + irr->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, RenderProbeMgr::smProbeBakeResolution, PROBE_FORMAT); + prefilter->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, RenderProbeMgr::smProbeBakeResolution, PROBE_FORMAT); mIrradianceArray->copyTo(irr); mPrefilterArray->copyTo(prefilter); @@ -355,50 +375,40 @@ void RenderProbeMgr::registerProbe(ProbeRenderInst* newProbe) mCubeSlotCount += PROBE_ARRAY_SLOT_BUFFER_SIZE; } - newProbe->mCubemapIndex = cubeIndex; + newProbeRenderInst.mCubemapIndex = cubeIndex; //mark cubemap slot as taken mCubeMapSlots[cubeIndex] = true; mCubeMapCount++; -#ifdef TORQUE_DEBUG - Con::warnf("RenderProbeMgr::registerProbe: Registered probe %u to cubeIndex %u", newProbe->mProbeIdx, cubeIndex); -#endif + mRegisteredProbes.push_back(newProbeRenderInst); - mProbesDirty = true; +#ifdef TORQUE_DEBUG + Con::warnf("RenderProbeMgr::registerProbe() - Registered probe %u to cubeIndex %u", newProbe->mObject->getId(), cubeIndex); +#endif } -void RenderProbeMgr::unregisterProbe(U32 probeIdx) +void RenderProbeMgr::unregisterProbe(ReflectionProbe::ProbeInfo* probeInfo) { - //Mostly for consolidation, but also lets us sanity check or prep any other data we need for rendering this in one place at time of flagging for render - if (probeIdx >= mRegisteredProbes.size()) + ProbeRenderInst* probe = findProbeInst(probeInfo); + if (probe == nullptr) return; - if (mRegisteredProbes[probeIdx]->mCubemapIndex == INVALID_CUBE_SLOT) + if (probe->mCubemapIndex == INVALID_CUBE_SLOT) return; //mark cubemap slot as available now - mCubeMapSlots[mRegisteredProbes[probeIdx]->mCubemapIndex] = false; + mCubeMapSlots[probe->mCubemapIndex] = false; mCubeMapCount--; - mRegisteredProbes.erase(probeIdx); - - //recalculate all the probe's indicies just to be sure - for (U32 i = 0; i < mRegisteredProbes.size(); i++) - { - mRegisteredProbes[i]->mProbeIdx = i; - } - - //rebuild our probe data - mProbesDirty = true; + mRegisteredProbes.erase(probe); } -void RenderProbeMgr::submitProbe(const ProbeRenderInst& newProbe) +void RenderProbeMgr::submitProbe(ReflectionProbe::ProbeInfo* probe) { - mActiveProbes.push_back(newProbe); + ProbeRenderInst* probeInst = findProbeInst(probe); + mActiveProbes.push_back(*probeInst); } -// -// PostEffect* RenderProbeMgr::getProbeArrayEffect() { if (!mProbeArrayEffect) @@ -407,40 +417,46 @@ PostEffect* RenderProbeMgr::getProbeArrayEffect() if (!mProbeArrayEffect) return nullptr; + + mProbeArrayEffect->setShaderConst("$numProbes", (S32)0); + mProbeArrayEffect->setShaderConst("$skylightCubemapIdx", (S32)-1); + + mProbeArrayEffect->setShaderConst("$cubeMips", (float)0); + mProbeArrayEffect->setShaderConst("$maxProbeDrawDistance", smMaxProbeDrawDistance); + } return mProbeArrayEffect; } -//remove -//Con::setIntVariable("lightMetrics::activeReflectionProbes", mReflectProbeBin.size()); -//Con::setIntVariable("lightMetrics::culledReflectProbes", 0/*mNumLightsCulled*/); -// - -void RenderProbeMgr::updateProbes() +void RenderProbeMgr::updateProbeTexture(ReflectionProbe::ProbeInfo* probeInfo) { - mProbesDirty = true; -} + //If we don't have a registered probe, there's no point in updating the cubemap array for it + ProbeRenderInst* probe = findProbeInst(probeInfo); + if (probe == nullptr) + return; -void RenderProbeMgr::updateProbeTexture(ProbeRenderInst* probeInfo) -{ - if (probeInfo->mIrradianceCubemap.isNull() || !probeInfo->mIrradianceCubemap->isInitialized()) + //Some basic sanity checking that we have valid cubemaps to work with + if (probeInfo->mIrradianceCubemap.isNull() || !probeInfo->mIrradianceCubemap->isInitialized() || + probeInfo->mIrradianceCubemap->getSize() != RenderProbeMgr::smProbeBakeResolution) { Con::errorf("RenderProbeMgr::updateProbeTexture() - tried to update a probe's texture with an invalid or uninitialized irradiance map!"); return; } - if (probeInfo->mPrefilterCubemap.isNull() || !probeInfo->mPrefilterCubemap->isInitialized()) + if (probeInfo->mPrefilterCubemap.isNull() || !probeInfo->mPrefilterCubemap->isInitialized() || + probeInfo->mPrefilterCubemap->getSize() != RenderProbeMgr::smProbeBakeResolution) { Con::errorf("RenderProbeMgr::updateProbeTexture() - tried to update a probe's texture with an invalid or uninitialized specular map!"); return; } - const U32 cubeIndex = probeInfo->mCubemapIndex; + //Run the update on the array pair with the probe's cubemaps and index + const U32 cubeIndex = probe->mCubemapIndex; mIrradianceArray->updateTexture(probeInfo->mIrradianceCubemap, cubeIndex); mPrefilterArray->updateTexture(probeInfo->mPrefilterCubemap, cubeIndex); #ifdef TORQUE_DEBUG - Con::warnf("UpdatedProbeTexture - probeIdx: %u on cubeIndex %u, Irrad validity: %d, Prefilter validity: %d", probeInfo->mProbeIdx, cubeIndex, + Con::warnf("UpdatedProbeTexture - probe id: %u on cubeIndex %u, Irrad validity: %d, Prefilter validity: %d", probeInfo->mObject->getId(), cubeIndex, probeInfo->mIrradianceCubemap->isInitialized(), probeInfo->mPrefilterCubemap->isInitialized()); #endif } @@ -450,21 +466,165 @@ void RenderProbeMgr::reloadTextures() U32 probeCount = mRegisteredProbes.size(); for (U32 i = 0; i < probeCount; i++) { - updateProbeTexture(mRegisteredProbes[i]); + updateProbeTexture(mRegisteredProbes[i].mProbeInfo); + } +} + +void RenderProbeMgr::bakeProbe(ReflectionProbe* probe) +{ + GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE); + + Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!"); + U32 startMSTime = Platform::getRealMilliseconds(); + + String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/"); + U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64); + U32 prefilterMipLevels = mLog2(F32(resolution)) + 1; + bool renderWithProbes = Con::getIntVariable("$pref::ReflectionProbes::RenderWithProbes", false); + + ReflectionProbe* clientProbe = nullptr; + + if (probe->isServerObject()) + clientProbe = static_cast(probe->getClientObject()); + else + return; + + if (clientProbe == nullptr) + return; + + String probePrefilterPath = clientProbe->getPrefilterMapPath(); + String probeIrradPath = clientProbe->getIrradianceMapPath(); + + if (clientProbe->mReflectionModeType != ReflectionProbe::DynamicCubemap) + { + //Prep our bake path + if (probePrefilterPath.isEmpty() || probeIrradPath.isEmpty()) + { + Con::errorf("RenderProbeMgr::bake() - Unable to bake our captures because probe doesn't have a path set"); + return; + } } - mProbesDirty = true; + // Save the current transforms so we can restore + // it for child control rendering below. + GFXTransformSaver saver; + + bool probeRenderState = RenderProbeMgr::smRenderReflectionProbes; + + F32 farPlane = 1000.0f; + + ReflectorDesc reflDesc; + reflDesc.texSize = resolution; + reflDesc.farDist = farPlane; + reflDesc.detailAdjust = 1; + reflDesc.objectTypeMask = probe->mProbeShapeType == ReflectionProbe::ProbeInfo::Skylight ? SKYLIGHT_CAPTURE_TYPEMASK : REFLECTION_PROBE_CAPTURE_TYPEMASK; + + CubeReflector cubeRefl; + cubeRefl.registerReflector(probe, &reflDesc); + + ReflectParams reflParams; + + //need to get the query somehow. Likely do some sort of get function to fetch from the guiTSControl that's active + CameraQuery query; //need to get the last cameraQuery + query.fov = 90; //90 degree slices for each of the 6 sides + query.nearPlane = 0.1f; + query.farPlane = farPlane; + query.headMatrix = MatrixF(); + query.cameraMatrix = clientProbe->getTransform(); + + Frustum culler; + culler.set(false, + query.fov, + 1.0f, + query.nearPlane, + query.farPlane, + query.cameraMatrix); + + S32 stereoTarget = GFX->getCurrentStereoTarget(); + + Point2I maxRes(2048, 2048); //basically a boundary so we don't go over this and break stuff + + reflParams.culler = culler; + reflParams.eyeId = stereoTarget; + reflParams.query = &query; + reflParams.startOfUpdateMs = startMSTime; + reflParams.viewportExtent = maxRes; + + if (!renderWithProbes) + RenderProbeMgr::smRenderReflectionProbes = false; + + GFXFormat reflectFormat; + + if (mUseHDRCaptures) + reflectFormat = GFXFormatR16G16B16A16F; + else + reflectFormat = GFXFormatR8G8B8A8; + const GFXFormat oldRefFmt = REFLECTMGR->getReflectFormat(); + REFLECTMGR->setReflectFormat(reflectFormat); + + cubeRefl.updateReflection(reflParams, clientProbe->getTransform().getPosition() + clientProbe->mProbeRefOffset); + + //Now, save out the maps + //create irridiance cubemap + if (cubeRefl.getCubemap()) + { + //Just to ensure we're prepped for the generation + clientProbe->createClientResources(); + + //Prep it with whatever resolution we've dictated for our bake + clientProbe->mIrridianceMap->mCubemap->initDynamic(resolution, reflectFormat); + clientProbe->mPrefilterMap->mCubemap->initDynamic(resolution, reflectFormat); + + GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false); + + IBLUtilities::GenerateIrradianceMap(renderTarget, cubeRefl.getCubemap(), clientProbe->mIrridianceMap->mCubemap); + IBLUtilities::GeneratePrefilterMap(renderTarget, cubeRefl.getCubemap(), prefilterMipLevels, clientProbe->mPrefilterMap->mCubemap); + + U32 endMSTime = Platform::getRealMilliseconds(); + F32 diffTime = F32(endMSTime - startMSTime); + Con::warnf("RenderProbeMgr::bake() - Finished Capture! Took %g milliseconds", diffTime); + Con::warnf("RenderProbeMgr::bake() - Beginning save now!"); + + IBLUtilities::SaveCubeMap(clientProbe->getIrradianceMapPath(), clientProbe->mIrridianceMap->mCubemap); + IBLUtilities::SaveCubeMap(clientProbe->getPrefilterMapPath(), clientProbe->mPrefilterMap->mCubemap); + } + else + { + Con::errorf("RenderProbeMgr::bake() - Didn't generate a valid scene capture cubemap, unable to generate prefilter and irradiance maps!"); + } + + if (!renderWithProbes) + RenderProbeMgr::smRenderReflectionProbes = probeRenderState; + + cubeRefl.unregisterReflector(); + + U32 endMSTime = Platform::getRealMilliseconds(); + F32 diffTime = F32(endMSTime - startMSTime); + + probe->setMaskBits(-1); + + Con::warnf("RenderProbeMgr::bake() - Finished bake! Took %g milliseconds", diffTime); + REFLECTMGR->setReflectFormat(oldRefFmt); } -void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state) +void RenderProbeMgr::bakeProbes() { - PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters); + Vector probes; - mProbeData = ProbeDataSet(smMaxProbesPerFrame); + Scene::getRootScene()->findObjectByType(probes); - getBestProbes(state->getCameraPosition(), &mProbeData); + for (U32 i = 0; i < probes.size(); i++) + { + if (probes[i]->isClientObject()) + continue; + + bakeProbe(probes[i]); + } } +//============================================================================= +// Forward Rendering functions +//============================================================================= ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuffer* buffer) { if (!buffer) @@ -510,16 +670,45 @@ ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuff return mLastConstants; } +void RenderProbeMgr::setProbeInfo(ProcessedMaterial *pmat, + const Material *mat, + const SceneData &sgData, + const SceneRenderState *state, + U32 pass, + GFXShaderConstBuffer *shaderConsts) +{ + // Skip this if we're rendering from the deferred bin. + if (sgData.binType == SceneData::DeferredBin) + return; + + PROFILE_SCOPE(ProbeManager_setProbeInfo); + + ProbeShaderConstants *psc = getProbeShaderConstants(shaderConsts); + + // NOTE: If you encounter a crash from this point forward + // while setting a shader constant its probably because the + // mConstantLookup has bad shaders/constants in it. + // + // This is a known crash bug that can occur if materials/shaders + // are reloaded and the light manager is not reset. + // + // We should look to fix this by clearing the table. + MatrixSet matSet = state->getRenderPass()->getMatrixSet(); + + // Update the forward shading light constants. + _update4ProbeConsts(sgData, matSet, psc, shaderConsts); +} + void RenderProbeMgr::setupSGData(SceneData& data, const SceneRenderState* state, LightInfo* light) { //ensure they're sorted for forward rendering mActiveProbes.sort(_probeScoreCmp); } -void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData, - MatrixSet &matSet, - ProbeShaderConstants *probeShaderConsts, - GFXShaderConstBuffer *shaderConsts) +void RenderProbeMgr::_update4ProbeConsts(const SceneData& sgData, + MatrixSet& matSet, + ProbeShaderConstants* probeShaderConsts, + GFXShaderConstBuffer* shaderConsts) { PROFILE_SCOPE(ProbeManager_Update4ProbeConsts); @@ -548,136 +737,46 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData, probeConfigAlignedArray[i] = probeSet.probeConfigArray[i]; } + if (probeSet.effectiveProbeCount != 0) + { shaderConsts->setSafe(probeShaderConsts->mProbeCountSC, (S32)probeSet.effectiveProbeCount); - shaderConsts->setSafe(probeShaderConsts->mProbePositionSC, probePositionAlignedArray); - shaderConsts->setSafe(probeShaderConsts->mProbeRefPosSC, probeRefPositionAlignedArray); + shaderConsts->setSafe(probeShaderConsts->mProbePositionArraySC, probePositionAlignedArray); + shaderConsts->setSafe(probeShaderConsts->mProbeRefPosArraySC, probeRefPositionAlignedArray); - if(probeShaderConsts->isValid()) - shaderConsts->set(probeShaderConsts->mWorldToObjArraySC, probeSet.probeWorldToObjArray.address(), probeSet.effectiveProbeCount, GFXSCT_Float4x4); + if (probeShaderConsts->isValid()) + shaderConsts->set(probeShaderConsts->mWorldToObjArraySC, probeSet.probeWorldToObjArray.address(), probeSet.probeWorldToObjArray.size(), GFXSCT_Float4x4); - shaderConsts->setSafe(probeShaderConsts->mRefScaleSC, refScaleAlignedArray); - shaderConsts->setSafe(probeShaderConsts->mProbeConfigDataSC, probeConfigAlignedArray); + shaderConsts->setSafe(probeShaderConsts->mRefScaleArraySC, refScaleAlignedArray); + shaderConsts->setSafe(probeShaderConsts->mProbeConfigDataArraySC, probeConfigAlignedArray); + } + + if (probeShaderConsts->mBRDFTextureMap->getSamplerRegister() != -1 && mBRDFTexture.isValid()) + GFX->setTexture(probeShaderConsts->mBRDFTextureMap->getSamplerRegister(), mBRDFTexture); shaderConsts->setSafe(probeShaderConsts->mSkylightCubemapIdxSC, (float)probeSet.skyLightIdx); - if(probeShaderConsts->mBRDFTextureMap->getSamplerRegister() != -1 && mBRDFTexture.isValid()) - GFX->setTexture(probeShaderConsts->mBRDFTextureMap->getSamplerRegister(), mBRDFTexture); + if (probeShaderConsts->mProbeSpecularCubemapArraySC->getSamplerRegister() != -1) + GFX->setCubeArrayTexture(probeShaderConsts->mProbeSpecularCubemapArraySC->getSamplerRegister(), mPrefilterArray); + if (probeShaderConsts->mProbeIrradianceCubemapArraySC->getSamplerRegister() != -1) + GFX->setCubeArrayTexture(probeShaderConsts->mProbeIrradianceCubemapArraySC->getSamplerRegister(), mIrradianceArray); - if(probeShaderConsts->mProbeSpecularCubemapSC->getSamplerRegister() != -1) - GFX->setCubeArrayTexture(probeShaderConsts->mProbeSpecularCubemapSC->getSamplerRegister(), mPrefilterArray); - if(probeShaderConsts->mProbeIrradianceCubemapSC->getSamplerRegister() != -1) - GFX->setCubeArrayTexture(probeShaderConsts->mProbeIrradianceCubemapSC->getSamplerRegister(), mIrradianceArray); + shaderConsts->setSafe(probeShaderConsts->mMaxProbeDrawDistanceSC, smMaxProbeDrawDistance); } } -S32 QSORT_CALLBACK RenderProbeMgr::_probeScoreCmp(const ProbeRenderInst* a, const ProbeRenderInst* b) +//============================================================================= +// Deferred Rendering Functions +//============================================================================= +void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState* state) { - F32 diff = a->getScore() - b->getScore(); - return diff > 0 ? 1 : diff < 0 ? -1 : 0; + PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters); + + mProbeData = ProbeDataSet(smMaxProbesPerFrame); + + getBestProbes(state->getCameraPosition(), &mProbeData); } -void RenderProbeMgr::getBestProbes(const Point3F& objPosition, ProbeDataSet* probeDataSet) -{ - PROFILE_SCOPE(ProbeManager_getBestProbes); - - //Array rendering - U32 probeCount = mActiveProbes.size(); - - Vector bestPickProbes; - bestPickProbes.setSize(probeDataSet->maxProbeCount); - bestPickProbes.fill(-1); - - probeDataSet->effectiveProbeCount = 0; - for (U32 i = 0; i < probeCount; i++) - { - if (probeDataSet->skyLightIdx != -1 && probeDataSet->effectiveProbeCount >= probeDataSet->maxProbeCount) - break; - - const ProbeRenderInst& curEntry = mActiveProbes[i]; - if (!curEntry.mIsEnabled) - continue; - - if (curEntry.mProbeShapeType != ProbeRenderInst::Skylight) - { - if (probeDataSet->effectiveProbeCount < probeDataSet->maxProbeCount) - { - bestPickProbes[probeDataSet->effectiveProbeCount] = i; - probeDataSet->effectiveProbeCount++; - } - } - else - { - probeDataSet->skyLightIdx = curEntry.mCubemapIndex; - } - } - - //Grab our best probe picks - for (U32 i = 0; i < bestPickProbes.size(); i++) - { - if (bestPickProbes[i] == -1) - continue; - - const ProbeRenderInst& curEntry = mActiveProbes[bestPickProbes[i]]; - - MatrixF p2A = curEntry.getTransform(); - p2A.inverse(); - probeDataSet->refScaleArray[i] = curEntry.mProbeRefScale / p2A.getScale(); - - Point3F probePos = curEntry.getPosition(); - Point3F refPos = probePos + curEntry.mProbeRefOffset * probeDataSet->refScaleArray[i].asPoint3F(); - probeDataSet->probeWorldToObjArray[i] = curEntry.getTransform(); - - probeDataSet->probePositionArray[i] = Point4F(probePos.x, probePos.y, probePos.z, 0); - probeDataSet->probeRefPositionArray[i] = Point4F(refPos.x, refPos.y, refPos.z, 0); - - probeDataSet->probeConfigArray[i] = Point4F(curEntry.mProbeShapeType, - curEntry.mRadius, - curEntry.mAtten, - curEntry.mCubemapIndex); - } -} - -void RenderProbeMgr::getProbeTextureData(ProbeTextureArrayData* probeTextureSet) -{ - probeTextureSet->BRDFTexture = mBRDFTexture; - probeTextureSet->prefilterArray = mPrefilterArray; - probeTextureSet->irradianceArray = mIrradianceArray; -} - -void RenderProbeMgr::setProbeInfo(ProcessedMaterial *pmat, - const Material *mat, - const SceneData &sgData, - const SceneRenderState *state, - U32 pass, - GFXShaderConstBuffer *shaderConsts) -{ - - // Skip this if we're rendering from the deferred bin. - if (sgData.binType == SceneData::DeferredBin) - return; - - PROFILE_SCOPE(ProbeManager_setProbeInfo); - - ProbeShaderConstants *psc = getProbeShaderConstants(shaderConsts); - - // NOTE: If you encounter a crash from this point forward - // while setting a shader constant its probably because the - // mConstantLookup has bad shaders/constants in it. - // - // This is a known crash bug that can occur if materials/shaders - // are reloaded and the light manager is not reset. - // - // We should look to fix this by clearing the table. - MatrixSet matSet = state->getRenderPass()->getMatrixSet(); - - // Update the forward shading light constants. - _update4ProbeConsts(sgData, matSet, psc, shaderConsts); -} - -//----------------------------------------------------------------------------- -// render objects -//----------------------------------------------------------------------------- void RenderProbeMgr::render( SceneRenderState *state ) { if (getProbeArrayEffect() == nullptr) @@ -695,7 +794,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) _setupPerFrameParameters(state); // Early out if nothing to draw. - if (!RenderProbeMgr::smRenderReflectionProbes || (!state->isDiffusePass() && !state->isReflectPass()) || (mProbeData.effectiveProbeCount == 0 && mProbeData.skyLightIdx == -1)) + if ((!RenderProbeMgr::smRenderReflectionProbes && Con::getVariable("$Probes::Capturing", "0") == "0") || (!mHasSkylight && mProbeData.effectiveProbeCount == 0)) { getProbeArrayEffect()->setSkip(true); mActiveProbes.clear(); @@ -717,7 +816,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) String useDebugContrib = Con::getVariable("$Probes::showProbeContrib", "0"); mProbeArrayEffect->setShaderMacro("DEBUGVIZ_CONTRIB", useDebugContrib); - if(mProbeData.skyLightIdx != -1 && mProbeData.effectiveProbeCount == 0) + if(mHasSkylight && mProbeData.effectiveProbeCount == 0) mProbeArrayEffect->setShaderMacro("SKYLIGHT_ONLY", "1"); else mProbeArrayEffect->setShaderMacro("SKYLIGHT_ONLY", "0"); @@ -725,6 +824,8 @@ void RenderProbeMgr::render( SceneRenderState *state ) String probePerFrame = Con::getVariable("$pref::MaxProbesPerFrame", "8"); mProbeArrayEffect->setShaderMacro("MAX_PROBES", probePerFrame); + String probeCapturing = Con::getVariable("$Probes::Capturing", "0"); + mProbeArrayEffect->setShaderMacro("CAPTURING", probeCapturing); //ssao mask if (AdvancedLightBinManager::smUseSSAOMask) { @@ -785,166 +886,17 @@ void RenderProbeMgr::render( SceneRenderState *state ) mProbeArrayEffect->setShaderConst("$worldToObjArray", mProbeData.probeWorldToObjArray); mProbeArrayEffect->setShaderConst("$refScaleArray", mProbeData.refScaleArray); mProbeArrayEffect->setShaderConst("$probeConfigData", mProbeData.probeConfigArray); + mProbeArrayEffect->setShaderConst("$maxProbeDrawDistance", smMaxProbeDrawDistance); // Make sure the effect is gonna render. getProbeArrayEffect()->setSkip(false); - - mActiveProbes.clear(); } -void RenderProbeMgr::bakeProbe(ReflectionProbe *probe) -{ - GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE); +//============================================================================= +// Console functions +//============================================================================= - Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!"); - U32 startMSTime = Platform::getRealMilliseconds(); - String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/"); - U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64); - U32 prefilterMipLevels = mLog2(F32(resolution)) + 1; - bool renderWithProbes = Con::getIntVariable("$pref::ReflectionProbes::RenderWithProbes", false); - - ReflectionProbe* clientProbe = nullptr; - - if (probe->isServerObject()) - clientProbe = static_cast(probe->getClientObject()); - else - return; - - if (clientProbe == nullptr) - return; - - String probePrefilterPath = clientProbe->getPrefilterMapPath(); - String probeIrradPath = clientProbe->getIrradianceMapPath(); - - if (clientProbe->mReflectionModeType != ReflectionProbe::DynamicCubemap) - { - //Prep our bake path - if (probePrefilterPath.isEmpty() || probeIrradPath.isEmpty()) - { - Con::errorf("RenderProbeMgr::bake() - Unable to bake our captures because probe doesn't have a path set"); - return; - } - } - - // Save the current transforms so we can restore - // it for child control rendering below. - GFXTransformSaver saver; - - bool probeRenderState = RenderProbeMgr::smRenderReflectionProbes; - - F32 farPlane = 1000.0f; - - ReflectorDesc reflDesc; - reflDesc.texSize = resolution; - reflDesc.farDist = farPlane; - reflDesc.detailAdjust = 1; - reflDesc.objectTypeMask = probe->mProbeShapeType == ProbeRenderInst::ProbeShapeType::Skylight ? SKYLIGHT_CAPTURE_TYPEMASK : REFLECTION_PROBE_CAPTURE_TYPEMASK; - - CubeReflector cubeRefl; - cubeRefl.registerReflector(probe, &reflDesc); - - ReflectParams reflParams; - - //need to get the query somehow. Likely do some sort of get function to fetch from the guiTSControl that's active - CameraQuery query; //need to get the last cameraQuery - query.fov = 90; //90 degree slices for each of the 6 sides - query.nearPlane = 0.1f; - query.farPlane = farPlane; - query.headMatrix = MatrixF(); - query.cameraMatrix = clientProbe->getTransform(); - - Frustum culler; - culler.set(false, - query.fov, - 1.0f, - query.nearPlane, - query.farPlane, - query.cameraMatrix); - - S32 stereoTarget = GFX->getCurrentStereoTarget(); - - Point2I maxRes(2048, 2048); //basically a boundary so we don't go over this and break stuff - - reflParams.culler = culler; - reflParams.eyeId = stereoTarget; - reflParams.query = &query; - reflParams.startOfUpdateMs = startMSTime; - reflParams.viewportExtent = maxRes; - - if (!renderWithProbes) - RenderProbeMgr::smRenderReflectionProbes = false; - - GFXFormat reflectFormat; - - if (mUseHDRCaptures) - reflectFormat = GFXFormatR16G16B16A16F; - else - reflectFormat = GFXFormatR8G8B8A8; - const GFXFormat oldRefFmt = REFLECTMGR->getReflectFormat(); - REFLECTMGR->setReflectFormat(reflectFormat); - - mProbeArrayEffect->setShaderConst("$CAPTURING", true); - cubeRefl.updateReflection(reflParams, clientProbe->getTransform().getPosition()+clientProbe->mProbeRefOffset); - mProbeArrayEffect->setShaderConst("$CAPTURING", false); - - //Now, save out the maps - //create irridiance cubemap - if (cubeRefl.getCubemap()) - { - //Just to ensure we're prepped for the generation - clientProbe->createClientResources(); - - //Prep it with whatever resolution we've dictated for our bake - clientProbe->mIrridianceMap->mCubemap->initDynamic(resolution, reflectFormat); - clientProbe->mPrefilterMap->mCubemap->initDynamic(resolution, reflectFormat); - - GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false); - - IBLUtilities::GenerateIrradianceMap(renderTarget, cubeRefl.getCubemap(), clientProbe->mIrridianceMap->mCubemap); - IBLUtilities::GeneratePrefilterMap(renderTarget, cubeRefl.getCubemap(), prefilterMipLevels, clientProbe->mPrefilterMap->mCubemap); - - U32 endMSTime = Platform::getRealMilliseconds(); - F32 diffTime = F32(endMSTime - startMSTime); - Con::warnf("RenderProbeMgr::bake() - Finished Capture! Took %g milliseconds", diffTime); - Con::warnf("RenderProbeMgr::bake() - Beginning save now!"); - - IBLUtilities::SaveCubeMap(clientProbe->getIrradianceMapPath(), clientProbe->mIrridianceMap->mCubemap); - IBLUtilities::SaveCubeMap(clientProbe->getPrefilterMapPath(), clientProbe->mPrefilterMap->mCubemap); - } - else - { - Con::errorf("RenderProbeMgr::bake() - Didn't generate a valid scene capture cubemap, unable to generate prefilter and irradiance maps!"); - } - - if (!renderWithProbes) - RenderProbeMgr::smRenderReflectionProbes = probeRenderState; - - cubeRefl.unregisterReflector(); - - U32 endMSTime = Platform::getRealMilliseconds(); - F32 diffTime = F32(endMSTime - startMSTime); - - probe->setMaskBits(-1); - - Con::warnf("RenderProbeMgr::bake() - Finished bake! Took %g milliseconds", diffTime); - REFLECTMGR->setReflectFormat(oldRefFmt); -} - -void RenderProbeMgr::bakeProbes() -{ - Vector probes; - - Scene::getRootScene()->findObjectByType(probes); - - for (U32 i = 0; i < probes.size(); i++) - { - if (probes[i]->isClientObject()) - continue; - - bakeProbe(probes[i]); - } -} DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()), "@brief Bakes the cubemaps for a reflection probe\n\n.") @@ -955,5 +907,7 @@ DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (n DefineEngineMethod(RenderProbeMgr, bakeProbes, void, (),, "@brief Iterates over all reflection probes in the scene and bakes their cubemaps\n\n.") { + Con::setVariable("$Probes::Capturing", "1"); object->bakeProbes(); + Con::setVariable("$Probes::Capturing", "0"); } diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index c9dbd69bd..3708f2e1e 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -39,7 +39,7 @@ #include "gfx/gfxVertexBuffer.h" #endif -#include "core/util/systemInterfaceList.h" +//#include "core/util/systemInterfaceList.h" #ifndef _MATERIALS_PROCESSEDSHADERMATERIAL_H_ #include "materials/processedShaderMaterial.h" @@ -52,52 +52,23 @@ #include "scene/reflector.h" #endif -static U32 MAXPROBECOUNT = 50; +#ifndef REFLECTIONPROBE_H +#include "T3D/lighting/reflectionProbe.h" +#endif class PostEffect; class ReflectionProbe; +/// +/// A simple container for a ReflectionProbe's ProbeInfo and index for it's associated +/// cubemaps in the cubemap array pair +/// struct ProbeRenderInst { - bool mIsEnabled; - - MatrixF mTransform; - - F32 mRadius; - - bool mDirty; - - Box3F mBounds; - Point3F mExtents; - Point3F mPosition; - Point3F mProbeRefOffset; - Point3F mProbeRefScale; - F32 mAtten; - - GFXCubemapHandle mPrefilterCubemap; - GFXCubemapHandle mIrradianceCubemap; - - /// The priority of this light used for - /// light and shadow scoring. - F32 mPriority; - - /// A temporary which holds the score used - /// when prioritizing lights for rendering. - F32 mScore; - - enum ProbeShapeType - { - Box = 0, ///< Sphere shaped - Sphere = 1, ///< Box-based shape - Skylight = 2 - }; - - ProbeShapeType mProbeShapeType; + ReflectionProbe::ProbeInfo* mProbeInfo; U32 mCubemapIndex; - U32 mProbeIdx; - public: ProbeRenderInst(); @@ -105,28 +76,11 @@ public: // Copies data passed in from light void set(const ProbeRenderInst *probeInfo); - - // Accessors - const MatrixF& getTransform() const { return mTransform; } - void setTransform(const MatrixF &xfm) { mTransform = xfm; } - - Point3F getPosition() const { return mPosition; } - void setPosition(const Point3F &pos) { mPosition = pos; } - - void setPriority(F32 priority) { mPriority = priority; } - F32 getPriority() const { return mPriority; } - - void setScore(F32 score) { mScore = score; } - F32 getScore() const { return mScore; } - - void clear(); - - inline bool operator ==(const ProbeRenderInst& b) const - { - return mProbeIdx == b.mProbeIdx; - } }; +/// +/// A container for all the shader consts needed for rendering probes in forward mode +/// struct ProbeShaderConstants { bool mInit; @@ -134,19 +88,21 @@ struct ProbeShaderConstants GFXShaderRef mShader; //Reflection Probes - GFXShaderConstHandle *mProbePositionSC; - GFXShaderConstHandle *mProbeRefPosSC; - GFXShaderConstHandle *mRefScaleSC; + GFXShaderConstHandle *mProbePositionArraySC; + GFXShaderConstHandle *mProbeRefPosArraySC; + GFXShaderConstHandle *mRefScaleArraySC; GFXShaderConstHandle *mWorldToObjArraySC; - GFXShaderConstHandle *mProbeConfigDataSC; - GFXShaderConstHandle *mProbeSpecularCubemapSC; - GFXShaderConstHandle *mProbeIrradianceCubemapSC; + GFXShaderConstHandle *mProbeConfigDataArraySC; + GFXShaderConstHandle *mProbeSpecularCubemapArraySC; + GFXShaderConstHandle *mProbeIrradianceCubemapArraySC; GFXShaderConstHandle *mProbeCountSC; GFXShaderConstHandle *mBRDFTextureMap; GFXShaderConstHandle *mSkylightCubemapIdxSC; + GFXShaderConstHandle* mMaxProbeDrawDistanceSC; + ProbeShaderConstants(); ~ProbeShaderConstants(); @@ -159,6 +115,10 @@ struct ProbeShaderConstants typedef Map ProbeConstantMap; +/// +/// A container for processed and packed probe data. This is made when we get the frame's +/// best probes, and is passed to the shader for actual rendering. +/// struct ProbeDataSet { Vector probePositionArray; @@ -198,18 +158,10 @@ struct ProbeDataSet probeWorldToObjArray.setSize(maxProbeCount); - skyLightIdx = -1; effectiveProbeCount = 0; } }; -struct ProbeTextureArrayData -{ - GFXTexHandle BRDFTexture; - GFXCubemapArrayHandle prefilterArray; - GFXCubemapArrayHandle irradianceArray; -}; - //************************************************************************** // RenderObjectMgr //************************************************************************** @@ -217,11 +169,6 @@ class RenderProbeMgr : public RenderBinManager { typedef RenderBinManager Parent; - Vector mRegisteredProbes; - - bool mProbesDirty; - - Vector mActiveProbes; public: //maximum number of allowed probes static const U32 PROBE_MAX_COUNT = 250; @@ -230,51 +177,161 @@ public: //number of slots to allocate at once in the cubemap array static const U32 PROBE_ARRAY_SLOT_BUFFER_SIZE = 10; - static const U32 PROBE_IRRAD_SIZE = 64; - static const U32 PROBE_PREFILTER_SIZE = 64; + //These dictate the default resolution size for the probe arrays static const GFXFormat PROBE_FORMAT = GFXFormatR16G16B16A16F;// GFXFormatR8G8B8A8;// when hdr fixed GFXFormatR16G16B16A16F; look into bc6h compression static const U32 INVALID_CUBE_SLOT = U32_MAX; static F32 smMaxProbeDrawDistance; static S32 smMaxProbesPerFrame; - + static S32 smProbeBakeResolution; + SceneRenderState *mState; private: - //Array rendering - U32 mEffectiveProbeCount; - S32 mMipCount; + /// + /// List of registered probes. These are not necessarily rendered in a given frame + /// but the Probe Manager is aware of them and they have cubemap array slots allocated + /// + Vector mRegisteredProbes; + /// + /// List of active probes. These are ones that are not only registered, but submitted by the probe itself as + /// ready to be rendered. Likely to be rendered in the current frame, settings-dependent. + /// + Vector mActiveProbes; + + /// + /// The PostEffect used to actually rendered the probes into the frame when in deferred mode + /// + SimObjectPtr mProbeArrayEffect; + + /// + /// Do we have a active skylight probe + /// bool mHasSkylight; + + /// + /// If we have a skylight, what's the array pair index for it? + /// S32 mSkylightCubemapIdx; - //number of cubemaps + /// + /// The 'effective' probe count. This tracks the number of probes that are actually going to be rendered + /// + U32 mEffectiveProbeCount; + // + //Array rendering + + /// + /// The number of mips the cubemap array has. Mips are used in the PBR calcs for handling roughness + /// + S32 mMipCount; + + /// + /// The number of cubemaps registered in our array pair + /// U32 mCubeMapCount; - //number of cubemap slots allocated + + /// + /// The number of allocated slots for the array pair. Rather than adding slots one at a time to the arrays + /// We allocate in chunks so we don't have to resize/rebuild the arrays as often + /// U32 mCubeSlotCount; - //array of cubemap slots, due to the editor these may be mixed around as probes are added and deleted + + /// + /// List indicating if a given allocated slot is actually in use. + /// Due to the editor these may be mixed around as probes are added and deleted + /// + /// bool mCubeMapSlots[PROBE_MAX_COUNT]; + /// + /// The prefilter cubemap array + /// GFXCubemapArrayHandle mPrefilterArray; + + /// + /// The irradiance cubemap array + /// GFXCubemapArrayHandle mIrradianceArray; //Utilized in forward rendering + + /// + /// This is used to look up already-made ProbeShaderConsts for a given shader + /// This allows us to avoid having to rebuild the consts each frame if it's a shader + /// we've already handled before. + /// ProbeConstantMap mConstantLookup; + + /// + /// The last shader we rendered(in forward mode). With this, we can shortcut the constant + /// lookup if the shader being processed and the last one are the same. + /// GFXShaderRef mLastShader; + + /// + /// THe previous shader constants. When used in conjunction with the mLastShader, we can skip + /// having to do a lookup to find an existing ProbeShaderConstants, saving overhead on batched + /// rendering + /// ProbeShaderConstants* mLastConstants; - // - SimObjectPtr mProbeArrayEffect; - - //Default skylight, used for shape editors, etc - ProbeRenderInst* mDefaultSkyLight; - + /// + /// The BRDF texture used in PBR math calculations + /// GFXTexHandle mBRDFTexture; + /// + /// Processed best probe selection list of the current frame when rendering in deferred mode. + /// ProbeDataSet mProbeData; - ///Prevents us from saving out the cubemaps(for now) but allows us the full HDR range on the in-memory cubemap captures + + /// + /// Allows us the full HDR range on the in-memory cubemap captures + /// bool mUseHDRCaptures; - U32 mPrefilterMipLevels; - U32 mPrefilterSize; +protected: + /// The current active light manager. + static RenderProbeMgr* smProbeManager; + + //============================================================================= + // Internal Management/Utility Functions + //============================================================================= + + /// + /// Simple utility function that finds the next free cubemap slot for the cubemap array + /// + /// U32 index of next available slot + U32 _findNextEmptyCubeSlot() + { + for (U32 i = 0; i < PROBE_MAX_COUNT; i++) + { + if (!mCubeMapSlots[i]) + return i; + } + return INVALID_CUBE_SLOT; + } + + /// + /// Utility function to quickly find a ProbeRenderInst in association to a + /// ReflectionProbe's ProbeInfo + /// + /// + /// Associated ProbeRederInst to param's probeInfo. Null if no matches found + ProbeRenderInst* findProbeInst(ReflectionProbe::ProbeInfo* probeInfo) + { + for (U32 i = 0; i < mRegisteredProbes.size(); i++) + { + auto asd = mRegisteredProbes[i]; + if (mRegisteredProbes[i].mProbeInfo == probeInfo) + { + return &mRegisteredProbes[i]; + } + } + + return nullptr; + } + public: RenderProbeMgr(); RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder); @@ -286,75 +343,139 @@ public: static void initPersistFields(); static void consoleInit(); + virtual void addElement(RenderInst* inst) {}; DECLARE_CONOBJECT(RenderProbeMgr); -protected: - /// The current active light manager. - static RenderProbeMgr *smProbeManager; - - /// This helper function sets the shader constansts - /// for the stock 4 light forward lighting code. - void _update4ProbeConsts(const SceneData &sgData, - MatrixSet &matSet, - ProbeShaderConstants *probeShaderConsts, - GFXShaderConstBuffer *shaderConsts); - - void _setupStaticParameters(); - void _setupPerFrameParameters(const SceneRenderState *state); - virtual void addElement(RenderInst* inst) {}; - virtual void render(SceneRenderState * state); - - ProbeShaderConstants* getProbeShaderConstants(GFXShaderConstBuffer* buffer); - - PostEffect* getProbeArrayEffect(); - - - U32 _findNextEmptyCubeSlot() - { - for (U32 i = 0; i < PROBE_MAX_COUNT; i++) - { - if (!mCubeMapSlots[i]) - return i; - } - return INVALID_CUBE_SLOT; - } - -public: - // RenderBinMgr - void updateProbes(); - - /// Returns the active LM. - static inline RenderProbeMgr* getProbeManager(); - - void registerProbe(ProbeRenderInst* newProbe); - void unregisterProbe(U32 probeIdx); - void submitProbe(const ProbeRenderInst& newProbe); - - static S32 QSORT_CALLBACK _probeScoreCmp(const ProbeRenderInst* a, const ProbeRenderInst* b); - - virtual void setProbeInfo(ProcessedMaterial *pmat, - const Material *mat, - const SceneData &sgData, - const SceneRenderState *state, - U32 pass, - GFXShaderConstBuffer *shaderConsts); - - void setupSGData(SceneData& data, const SceneRenderState* state, LightInfo* light); - - void updateProbeTexture(ProbeRenderInst* probeInfo); - - void reloadTextures(); - - /// Debug rendering + /// + /// Static flag used to indicate if probes should be rendered at all. Used for debugging + /// static bool smRenderReflectionProbes; - void bakeProbe(ReflectionProbe *probeInfo); + //============================================================================= + // Utility functions for processing and setting up the probes for rendering + //============================================================================= + + /// + /// Sorts probes based on their score values. These scores are calculated by the probes themselves based on size, distance from camera, etc + /// + static S32 QSORT_CALLBACK _probeScoreCmp(const ProbeRenderInst* a, const ProbeRenderInst* b); + + /// + /// Builds a dataset of the best probes to be rendered this frame. + /// + /// + /// + + void getBestProbes(const Point3F& objPosition, ProbeDataSet* probeDataSet); + + /// + /// This function adds a ReflectionProbe to the registered list and also allocates + /// a slot in the cubemap array pair for its use + /// + /// The probe info to be registered to the bin + void registerProbe(ReflectionProbe::ProbeInfo* probeInfo); + + /// + /// This function removes the ReflectionProbe from the registered list, and marks it's cubemap + /// array slots as unused, allowing them to be freed. + /// + /// The probe info to be un-registered to the bin + void unregisterProbe(ReflectionProbe::ProbeInfo* probeInfo); + + /// + /// This function is for registering a ReflectionProbe's probe info + /// as being rendered in the current frame. This is distinct from + /// registered probes in that registered probes are any 'real' probe + /// in the scene, but they may not necessarily render + /// Active(submmitted) probes are intended to actual be rendered this frame + /// + /// The ProbeInfo being submitted to be rendered + void submitProbe(ReflectionProbe::ProbeInfo* probe); + + /// + /// Gets the PostEffect used by the bin for rendering the probe array in deferred + /// + /// the PostEffect object + PostEffect* getProbeArrayEffect(); + + /// + /// Finds the associated cubemap array slot for the incoming ProbeInfo and updates the array's texture(s) from it + /// + /// + void updateProbeTexture(ReflectionProbe::ProbeInfo* probeInfo); + + /// + /// Forces an update for all registered probes' cubemaps + /// + void reloadTextures(); + + /// + /// Takes a reflection probe and runs the cubemap bake process on it, outputting the resulting files to disk + /// + void bakeProbe(ReflectionProbe* probe); + + /// + /// Runs the cubemap bake on all probes in the current scene + /// void bakeProbes(); - void getProbeTextureData(ProbeTextureArrayData* probeTextureSet); - S32 getSkylightIndex() { return mSkylightCubemapIdx; } - //accumulates the best fit of probes given the object position - void getBestProbes(const Point3F& objPosition, ProbeDataSet* probeDataSet); + /// + /// Returns the active Probe Manager. + /// + static inline RenderProbeMgr* getProbeManager(); + + //============================================================================= + // Forward Rendering functions + //============================================================================= + + /// + /// This function returns or builds a ProbeShaderConsts containing needed data for + /// rendering probes in forward mode + /// + /// The GFXShaderConstBuffer used to build or fetch the Probe Consts + ProbeShaderConstants* getProbeShaderConstants(GFXShaderConstBuffer* buffer); + + /// + /// Sets up the probe data required for doing a render in forward mode. + /// + virtual void setProbeInfo(ProcessedMaterial* pmat, + const Material* mat, + const SceneData& sgData, + const SceneRenderState* state, + U32 pass, + GFXShaderConstBuffer* shaderConsts); + + /// + /// Invoked as part of the setup in preperation to render an object in forward mode. Used to ensure the probes are + /// sorted ahead of render. + /// + /// + void setupSGData(SceneData& data, const SceneRenderState* state, LightInfo* light); + + /// + /// Sets up and binds all the shader const data required for rendering probes/IBL for a forward-rendered material. + /// + /// + void _update4ProbeConsts(const SceneData& sgData, + MatrixSet& matSet, + ProbeShaderConstants* probeShaderConsts, + GFXShaderConstBuffer* shaderConsts); + + //============================================================================= + // Deferred Rendering Functions + //============================================================================= + + /// + /// Ensures the probes are properly sorted before we render them in deferred mode + /// + void _setupPerFrameParameters(const SceneRenderState *state); + + /// + /// Renders the sorted probes list via a PostEffect to draw them into the buffer data in deferred mode. + /// + virtual void render(SceneRenderState * state); + + virtual void clear() { mActiveProbes.clear(); Parent::clear(); } }; RenderProbeMgr* RenderProbeMgr::getProbeManager() diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp index 69af7ef5c..94b457c75 100644 --- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp @@ -758,7 +758,7 @@ Var* ShaderFeatureGLSL::getWsView( Var *wsPosition, MultiLine *meta ) eyePos->constSortPos = cspPass; } - meta->addStatement( new GenOp( " @ = normalize( @ - @ );\r\n", + meta->addStatement( new GenOp( " @ = @ - @;\r\n", new DecOp( wsView ), eyePos, wsPosition ) ); } @@ -838,79 +838,66 @@ Var* ShaderFeatureGLSL::addOutDetailTexCoord( Vector &compon Var* ShaderFeatureGLSL::getSurface(Vector& componentList, MultiLine* meta, const MaterialFeatureData& fd) { - ShaderConnector* connectComp = dynamic_cast(componentList[C_CONNECTOR]); - - Var* diffuseColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget)); - - Var* ormConfig = (Var*)LangElement::find("ORMConfig"); - if (!ormConfig) - { - Var* metalness = (Var*)LangElement::find("metalness"); - if (!metalness) - { - metalness = new Var("metalness", "float"); - metalness->uniform = true; - metalness->constSortPos = cspPotentialPrimitive; - } - - Var* roughness = (Var*)LangElement::find("roughness"); - if (!roughness) - { - roughness = new Var("roughness", "float"); - roughness->uniform = true; - roughness->constSortPos = cspPotentialPrimitive; - } - - ormConfig = new Var("ORMConfig", "vec4"); - LangElement* colorDecl = new DecOp(ormConfig); - meta->addStatement(new GenOp(" @ = vec4(0.0,1.0,@,@);\r\n", colorDecl, roughness, metalness)); //reconstruct ormConfig, no ao darkening - } - - Var* normal = (Var*)LangElement::find("normal"); - if (!normal) - { - normal = new Var("normal", "vec3"); - meta->addStatement(new GenOp(" @;\r\n\n", new DecOp(normal))); - - Var* wsNormal = (Var*)LangElement::find("wsNormal"); - if (!fd.features[MFT_NormalMap]) - { - if (!wsNormal) - wsNormal = getInWorldNormal(componentList); - meta->addStatement(new GenOp(" @ = normalize( @ );\r\n\n", normal, wsNormal)); - } - else - { - meta->addStatement(new GenOp(" @ = normalize( @ );\r\n", normal, wsNormal)); - } - } - - Var* wsEyePos = (Var*)LangElement::find("eyePosWorld"); - - if (!wsEyePos) - { - wsEyePos = new Var("eyePosWorld", "vec3"); - wsEyePos->uniform = true; - wsEyePos->constSortPos = cspPass; - } - - Var* wsPosition = getInWsPosition(componentList); - Var* wsView = getWsView(wsPosition, meta); - - Var* surface = (Var*)LangElement::find("surface"); + Var *surface = (Var *)LangElement::find("surface"); if (!surface) { + Var* diffuseColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget)); + + Var* ormConfig = (Var*)LangElement::find("ORMConfig"); + if (!ormConfig) + { + Var* metalness = (Var*)LangElement::find("metalness"); + if (!metalness) + { + metalness = new Var("metalness", "float"); + metalness->uniform = true; + metalness->constSortPos = cspPotentialPrimitive; + } + + Var* roughness = (Var*)LangElement::find("roughness"); + if (!roughness) + { + roughness = new Var("roughness", "float"); + roughness->uniform = true; + roughness->constSortPos = cspPotentialPrimitive; + } + + ormConfig = new Var("ORMConfig", "vec4"); + LangElement* colorDecl = new DecOp(ormConfig); + meta->addStatement(new GenOp(" @ = vec4(0.0,1.0,@,@);\r\n", colorDecl, roughness, metalness)); //reconstruct ormConfig, no ao darkening + } + + Var* normal = (Var*)LangElement::find("normal"); + if (!normal) + { + normal = new Var("normal", "vec3"); + meta->addStatement(new GenOp(" @;\r\n\n", new DecOp(normal))); + + Var *wsNormal = (Var *)LangElement::find("wsNormal"); + if (!wsNormal) + wsNormal = getInWorldNormal(componentList); + + meta->addStatement(new GenOp(" @ = normalize( @ );\r\n", normal, wsNormal)); + } + + Var* wsEyePos = (Var*)LangElement::find("eyePosWorld"); + + if (!wsEyePos) + { + wsEyePos = new Var("eyePosWorld", "vec3"); + wsEyePos->uniform = true; + wsEyePos->constSortPos = cspPass; + } + + Var* wsPosition = getInWsPosition(componentList); + Var* wsView = getWsView(wsPosition, meta); + surface = new Var("surface", "Surface"); - meta->addStatement(new GenOp(" @ = createForwardSurface(@,@,@,@,@,@);\r\n\n", new DecOp(surface), diffuseColor, normal, ormConfig, + meta->addStatement(new GenOp(" @ = createForwardSurface(@,normalize(@),@,@,@,@);\r\n\n", new DecOp(surface), diffuseColor, normal, ormConfig, wsPosition, wsEyePos, wsView)); } - /*Var* surface = (Var*)LangElement::find("surface"); - if (!surface) - { - surface = new Var("surface", "float"); - }*/ return surface; } //**************************************************************************** @@ -3003,12 +2990,12 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList inRefPosArray->uniform = true; inRefPosArray->constSortPos = cspPotentialPrimitive; - Var * refScaleArray = new Var("inRefScale", "vec4"); + Var * refScaleArray = new Var("inRefScaleArray", "vec4"); refScaleArray->arraySize = MAX_FORWARD_PROBES; refScaleArray->uniform = true; refScaleArray->constSortPos = cspPotentialPrimitive; - Var * probeConfigData = new Var("inProbeConfigData", "vec4"); + Var * probeConfigData = new Var("inProbeConfigDataArray", "vec4"); probeConfigData->arraySize = MAX_FORWARD_PROBES; probeConfigData->uniform = true; probeConfigData->constSortPos = cspPotentialPrimitive; @@ -3026,12 +3013,12 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList BRDFTexture->sampler = true; BRDFTexture->constNum = Var::getTexUnitNum(); // used as texture unit num here - Var * specularCubemapAR = new Var("inSpecularCubemapAR", "samplerCubeArray"); + Var * specularCubemapAR = new Var("SpecularCubemapAR", "samplerCubeArray"); specularCubemapAR->uniform = true; specularCubemapAR->sampler = true; specularCubemapAR->constNum = Var::getTexUnitNum(); - Var * irradianceCubemapAR = new Var("inIrradianceCubemapAR", "samplerCubeArray"); + Var * irradianceCubemapAR = new Var("IrradianceCubemapAR", "samplerCubeArray"); irradianceCubemapAR->uniform = true; irradianceCubemapAR->sampler = true; irradianceCubemapAR->constNum = Var::getTexUnitNum(); @@ -3044,14 +3031,24 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList return; } + Var* eyePos = (Var*)LangElement::find("eyePosWorld"); + if (!eyePos) + { + eyePos = new Var; + eyePos->setType("vec3"); + eyePos->setName("eyePosWorld"); + eyePos->uniform = true; + eyePos->constSortPos = cspPotentialPrimitive; + } + Var *curColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget)); //Reflection vec - String computeForwardProbes = String(" @.rgb = computeForwardProbes(@,@,@,@,@,@,@,@,\r\n\t\t"); + String computeForwardProbes = String(" @.rgb = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t"); computeForwardProbes += String("@,@,\r\n\t\t"); computeForwardProbes += String("@,@).rgb; \r\n"); - meta->addStatement(new GenOp(computeForwardProbes.c_str(), curColor, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, + meta->addStatement(new GenOp(computeForwardProbes.c_str(), curColor, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, eyePos, skylightCubemapIdx, BRDFTexture, irradianceCubemapAR, specularCubemapAR)); @@ -3078,9 +3075,9 @@ void ReflectionProbeFeatGLSL::setTexData(Material::StageData& stageDat, passData.mSamplerNames[texIndex] = "BRDFTexture"; passData.mTexType[texIndex++] = Material::Standard; // assuming here that it is a scenegraph cubemap - passData.mSamplerNames[texIndex] = "inSpecularCubemapAR"; + passData.mSamplerNames[texIndex] = "SpecularCubemapAR"; passData.mTexType[texIndex++] = Material::SGCube; - passData.mSamplerNames[texIndex] = "inIrradianceCubemapAR"; + passData.mSamplerNames[texIndex] = "IrradianceCubemapAR"; passData.mTexType[texIndex++] = Material::SGCube; } } diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp index c53e939e0..a294f5f85 100644 --- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp @@ -764,7 +764,7 @@ Var* ShaderFeatureHLSL::getWsView( Var *wsPosition, MultiLine *meta ) eyePos->constSortPos = cspPass; } - meta->addStatement( new GenOp( " @ = normalize( @ - @ );\r\n", + meta->addStatement( new GenOp( " @ = @ - @;\r\n", new DecOp( wsView ), eyePos, wsPosition ) ); } @@ -844,14 +844,16 @@ Var* ShaderFeatureHLSL::addOutDetailTexCoord( Vector &compon Var* ShaderFeatureHLSL::getSurface(Vector& componentList, MultiLine* meta, const MaterialFeatureData& fd) { - ShaderConnector* connectComp = dynamic_cast(componentList[C_CONNECTOR]); + Var *surface = (Var *)LangElement::find("surface"); - Var* diffuseColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget)); + if (!surface) + { + Var *diffuseColor = (Var *)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget)); - Var* ormConfig = (Var*)LangElement::find("ORMConfig"); + Var *ormConfig = (Var *)LangElement::find("ORMConfig"); if (!ormConfig) { - Var* metalness = (Var*)LangElement::find("metalness"); + Var *metalness = (Var *)LangElement::find("metalness"); if (!metalness) { metalness = new Var("metalness", "float"); @@ -859,7 +861,7 @@ Var* ShaderFeatureHLSL::getSurface(Vector& componentList, Mult metalness->constSortPos = cspPotentialPrimitive; } - Var* roughness = (Var*)LangElement::find("roughness"); + Var *roughness = (Var *)LangElement::find("roughness"); if (!roughness) { roughness = new Var("roughness", "float"); @@ -868,30 +870,24 @@ Var* ShaderFeatureHLSL::getSurface(Vector& componentList, Mult } ormConfig = new Var("ORMConfig", "float4"); - LangElement* colorDecl = new DecOp(ormConfig); + LangElement *colorDecl = new DecOp(ormConfig); meta->addStatement(new GenOp(" @ = float4(0.0,1.0,@,@);\r\n", colorDecl, roughness, metalness)); //reconstruct matinfo, no ao darkening } - Var* normal = (Var*)LangElement::find("normal"); + Var *normal = (Var *)LangElement::find("normal"); if (!normal) { normal = new Var("normal", "float3"); meta->addStatement(new GenOp(" @;\r\n\n", new DecOp(normal))); - Var* wsNormal = (Var*)LangElement::find("wsNormal"); - if (!fd.features[MFT_NormalMap]) - { + Var *wsNormal = (Var *)LangElement::find("wsNormal"); if (!wsNormal) wsNormal = getInWorldNormal(componentList); - meta->addStatement(new GenOp(" @ = normalize( @ );\r\n\n", normal, wsNormal)); - } - else - { + meta->addStatement(new GenOp(" @ = normalize( @ );\r\n", normal, wsNormal)); } - } - Var* wsEyePos = (Var*)LangElement::find("eyePosWorld"); + Var *wsEyePos = (Var *)LangElement::find("eyePosWorld"); if (!wsEyePos) { @@ -900,15 +896,11 @@ Var* ShaderFeatureHLSL::getSurface(Vector& componentList, Mult wsEyePos->constSortPos = cspPass; } - Var* wsPosition = getInWsPosition(componentList); - Var* wsView = getWsView(wsPosition, meta); + Var *wsPosition = getInWsPosition(componentList); + Var *wsView = getWsView(wsPosition, meta); - Var* surface = (Var*)LangElement::find("surface"); - - if (!surface) - { surface = new Var("surface", "Surface"); - meta->addStatement(new GenOp(" @ = createForwardSurface(@,@,@,@,@,@);\r\n\n", new DecOp(surface), diffuseColor, normal, ormConfig, + meta->addStatement(new GenOp(" @ = createForwardSurface(@,normalize(@),@,@,@,@);\r\n\n", new DecOp(surface), diffuseColor, normal, ormConfig, wsPosition, wsEyePos, wsView)); } @@ -3076,12 +3068,12 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList inRefPosArray->uniform = true; inRefPosArray->constSortPos = cspPotentialPrimitive; - Var * refScaleArray = new Var("inRefScale", "float4"); + Var * refScaleArray = new Var("inRefScaleArray", "float4"); refScaleArray->arraySize = MAX_FORWARD_PROBES; refScaleArray->uniform = true; refScaleArray->constSortPos = cspPotentialPrimitive; - Var *probeConfigData = new Var("inProbeConfigData", "float4"); + Var *probeConfigData = new Var("inProbeConfigDataArray", "float4"); probeConfigData->arraySize = MAX_FORWARD_PROBES; probeConfigData->uniform = true; probeConfigData->constSortPos = cspPotentialPrimitive; @@ -3101,22 +3093,22 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList BRDFTextureTex->texture = true; BRDFTextureTex->constNum = BRDFTexture->constNum; - Var *specularCubemapAR = new Var("inSpecularCubemapAR", "SamplerState"); + Var *specularCubemapAR = new Var("SpecularCubemapAR", "SamplerState"); specularCubemapAR->uniform = true; specularCubemapAR->sampler = true; specularCubemapAR->constNum = Var::getTexUnitNum(); // used as texture unit num here - Var *specularCubemapARTex = new Var("texture_inSpecularCubemapAR", "TextureCubeArray"); + Var *specularCubemapARTex = new Var("texture_SpecularCubemapAR", "TextureCubeArray"); specularCubemapARTex->uniform = true; specularCubemapARTex->texture = true; specularCubemapARTex->constNum = specularCubemapAR->constNum; - Var *irradianceCubemapAR = new Var("inIrradianceCubemapAR", "SamplerState"); + Var *irradianceCubemapAR = new Var("IrradianceCubemapAR", "SamplerState"); irradianceCubemapAR->uniform = true; irradianceCubemapAR->sampler = true; irradianceCubemapAR->constNum = Var::getTexUnitNum(); // used as texture unit num here - Var *irradianceCubemapARTex = new Var("texture_inIrradianceCubemapAR", "TextureCubeArray"); + Var *irradianceCubemapARTex = new Var("texture_IrradianceCubemapAR", "TextureCubeArray"); irradianceCubemapARTex->uniform = true; irradianceCubemapARTex->texture = true; irradianceCubemapARTex->constNum = irradianceCubemapAR->constNum; @@ -3138,11 +3130,21 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList ibl = new Var("ibl", "float3"); } - String computeForwardProbes = String(" @ = computeForwardProbes(@,@,@,@,@,@,@,@,\r\n\t\t"); + Var* eyePos = (Var*)LangElement::find("eyePosWorld"); + if (!eyePos) + { + eyePos = new Var; + eyePos->setType("float3"); + eyePos->setName("eyePosWorld"); + eyePos->uniform = true; + eyePos->constSortPos = cspPass; + } + + String computeForwardProbes = String(" @ = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t"); computeForwardProbes += String("@,TORQUE_SAMPLER2D_MAKEARG(@),\r\n\t\t"); computeForwardProbes += String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@)).rgb; \r\n"); - meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, + meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, eyePos, skylightCubemapIdx, BRDFTexture, irradianceCubemapAR, specularCubemapAR)); @@ -3171,9 +3173,9 @@ void ReflectionProbeFeatHLSL::setTexData(Material::StageData &stageDat, passData.mSamplerNames[texIndex] = "BRDFTexture"; passData.mTexType[texIndex++] = Material::Standard; // assuming here that it is a scenegraph cubemap - passData.mSamplerNames[texIndex] = "inSpecularCubemapAR"; + passData.mSamplerNames[texIndex] = "SpecularCubemapAR"; passData.mTexType[texIndex++] = Material::SGCube; - passData.mSamplerNames[texIndex] = "inIrradianceCubemapAR"; + passData.mSamplerNames[texIndex] = "IrradianceCubemapAR"; passData.mTexType[texIndex++] = Material::SGCube; } } diff --git a/Engine/source/shaderGen/shaderGenVars.cpp b/Engine/source/shaderGen/shaderGenVars.cpp index 839a4c36b..e7e7296c1 100644 --- a/Engine/source/shaderGen/shaderGenVars.cpp +++ b/Engine/source/shaderGen/shaderGenVars.cpp @@ -80,17 +80,19 @@ const String ShaderGenVars::glowMul("$glowMul"); //Reflection Probes - Forward lit. not to be confused with the deferred handwritten vars //change to parity once we've got the same arrays used for both routes -const String ShaderGenVars::probePosition("$inProbePosArray"); -const String ShaderGenVars::probeRefPos("$inRefPosArray"); -const String ShaderGenVars::refScale("$inRefScale"); +const String ShaderGenVars::probePositionArray("$inProbePosArray"); +const String ShaderGenVars::probeRefPosArray("$inRefPosArray"); +const String ShaderGenVars::refScaleArray("$inRefScaleArray"); const String ShaderGenVars::worldToObjArray("$inWorldToObjArray"); -const String ShaderGenVars::probeConfigData("$inProbeConfigData"); -const String ShaderGenVars::specularCubemapAR("$inSpecularCubemapAR"); -const String ShaderGenVars::irradianceCubemapAR("$inIrradianceCubemapAR"); +const String ShaderGenVars::probeConfigDataArray("$inProbeConfigDataArray"); +const String ShaderGenVars::specularCubemapAR("$SpecularCubemapAR"); +const String ShaderGenVars::irradianceCubemapAR("$IrradianceCubemapAR"); const String ShaderGenVars::probeCount("$inNumProbes"); const String ShaderGenVars::BRDFTextureMap("$BRDFTexture"); +const String ShaderGenVars::maxProbeDrawDistance("$maxProbeDrawDistance"); + //Skylight const String ShaderGenVars::skylightCubemapIdx("$inSkylightCubemapIdx"); diff --git a/Engine/source/shaderGen/shaderGenVars.h b/Engine/source/shaderGen/shaderGenVars.h index 6c32d4522..c32d97c94 100644 --- a/Engine/source/shaderGen/shaderGenVars.h +++ b/Engine/source/shaderGen/shaderGenVars.h @@ -91,17 +91,19 @@ struct ShaderGenVars const static String glowMul; //Reflection Probes - const static String probePosition; - const static String probeRefPos; - const static String refScale; + const static String probePositionArray; + const static String probeRefPosArray; + const static String refScaleArray; const static String worldToObjArray; - const static String probeConfigData; + const static String probeConfigDataArray; const static String specularCubemapAR; const static String irradianceCubemapAR; const static String probeCount; const static String BRDFTextureMap; + const static String maxProbeDrawDistance; + //Skylight const static String skylightCubemapIdx; diff --git a/Templates/BaseGame/game/core/postFX/scripts/ReflectionProbes/reflectionProbeArrayPostFX.tscript b/Templates/BaseGame/game/core/postFX/scripts/ReflectionProbes/reflectionProbeArrayPostFX.tscript index c5811c34b..879ec5774 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/ReflectionProbes/reflectionProbeArrayPostFX.tscript +++ b/Templates/BaseGame/game/core/postFX/scripts/ReflectionProbes/reflectionProbeArrayPostFX.tscript @@ -15,4 +15,6 @@ singleton PostEffect( reflectionProbeArrayPostFX ) texture[0] = "#deferred"; texture[1] = "#color"; texture[2] = "#matinfo"; + + allowReflectPass = true; }; diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index 55d9866ce..57ee38190 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -23,6 +23,8 @@ #include "./torque.glsl" #include "./brdf.glsl" +uniform float maxProbeDrawDistance; + #ifndef TORQUE_SHADERGEN #line 27 // These are the uniforms used by most lighting shaders. @@ -330,7 +332,7 @@ float defineSphereSpaceInfluence(vec3 wsPosition, vec3 wsProbePosition, float ra { vec3 L = wsProbePosition.xyz - wsPosition; float contribution = 1.0 - length(L) / radius; - return contribution; + return saturate(contribution); } float getDistBoxToPoint(vec3 pt, vec3 extents) @@ -342,10 +344,9 @@ float getDistBoxToPoint(vec3 pt, vec3 extents) float defineBoxSpaceInfluence(vec3 wsPosition, mat4 worldToObj, float attenuation) { vec3 surfPosLS = tMul(worldToObj, vec4(wsPosition, 1.0)).xyz; - float atten = 1.0 - attenuation; float baseVal = 0.25; float dist = getDistBoxToPoint(surfPosLS, vec3(baseVal, baseVal, baseVal)); - return saturate(smoothstep(baseVal + 0.0001, atten*baseVal, dist)); + return saturate(smoothstep(baseVal, (baseVal-attenuation/2), dist)); } // Box Projected IBL Lighting @@ -367,9 +368,9 @@ vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 refSca } vec4 computeForwardProbes(Surface surface, - float cubeMips, int numProbes, mat4x4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES], - vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES], - float skylightCubemapIdx, sampler2D BRDFTexture, + float cubeMips, int numProbes, mat4x4 inWorldToObjArray[MAX_FORWARD_PROBES], vec4 inProbeConfigData[MAX_FORWARD_PROBES], + vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 inRefScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES], + vec3 wsEyePos, float skylightCubemapIdx, sampler2D BRDFTexture, samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR) { int i = 0; @@ -384,47 +385,37 @@ vec4 computeForwardProbes(Surface surface, for (i = 0; i < numProbes; ++i) { contribution[i] = 0; - - if (probeConfigData[i].r == 0) //box + float atten = 1.0-(length(wsEyePos-inProbePosArray[i].xyz)/maxProbeDrawDistance); + if (inProbeConfigData[i].r == 0) //box { - contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b); - if (contribution[i] > 0.0) - probehits++; + contribution[i] = defineBoxSpaceInfluence(surface.P, inWorldToObjArray[i], inProbeConfigData[i].b)*atten; } - else if (probeConfigData[i].r == 1) //sphere + else if (inProbeConfigData[i].r == 1) //sphere { - contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g); - if (contribution[i] > 0.0) - probehits++; + contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, inProbeConfigData[i].g)*atten; } - contribution[i] = max(contribution[i], 0); + if (contribution[i]>0.0) + probehits++; + else + contribution[i] = 0.0; blendSum += contribution[i]; - invBlendSum += (1.0f - contribution[i]); } - if (probehits > 1.0) + if (probehits > 1.0)//if we overlap { + invBlendSum = (probehits - blendSum)/(probehits-1); //grab the remainder for (i = 0; i < numProbes; i++) { - blendFactor[i] = ((contribution[i] / blendSum)) / probehits; - blendFactor[i] *= ((contribution[i]) / invBlendSum); - blendFactor[i] = saturate(blendFactor[i]); - blendFacSum += blendFactor[i]; + blendFactor[i] = contribution[i]/blendSum; //what % total is this instance + blendFactor[i] *= blendFactor[i] / invBlendSum; //what should we add to sum to 1 + blendFacSum += blendFactor[i]; //running tally of results } - // Normalize blendVal - if (blendFacSum == 0.0f) // Possible with custom weight - { - blendFacSum = 1.0f; - } - - float invBlendSumWeighted = 1.0f / blendFacSum; for (i = 0; i < numProbes; ++i) { - blendFactor[i] *= invBlendSumWeighted; - contribution[i] *= blendFactor[i]; + contribution[i] *= blendFactor[i]/blendFacSum; //normalize } } @@ -471,8 +462,8 @@ vec4 computeForwardProbes(Surface surface, float contrib = contribution[i]; if (contrib > 0.0f) { - float cubemapIdx = int(probeConfigData[i].a); - vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz); + float cubemapIdx = int(inProbeConfigData[i].a); + vec3 dir = boxProject(surface.P, surface.R, inWorldToObjArray[i], inRefScaleArray[i].xyz, inRefPosArray[i].xyz); irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib; specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib; @@ -491,8 +482,8 @@ vec4 computeForwardProbes(Surface surface, vec3 kD = 1.0f - F; kD *= 1.0f - surface.metalness; - float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex) - vec2 envBRDF = textureLod(BRDFTexture, vec2(dfgNdotV, surface.roughness),0).rg; + //float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex) + vec2 envBRDF = textureLod(BRDFTexture, vec2(surface.NdotV, surface.roughness),0).rg; specular *= F * envBRDF.x + surface.f90 * envBRDF.y; irradiance *= kD * surface.baseColor.rgb; @@ -504,13 +495,16 @@ vec4 computeForwardProbes(Surface surface, float horizonOcclusion = 1.3; float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); horizon *= horizon; - +#if CAPTURING == 1 + return vec4(mix(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0); +#else return vec4((irradiance + specular) * horizon, 0);//alpha writes disabled +#endif } vec4 debugVizForwardProbes(Surface surface, - float cubeMips, int numProbes, mat4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES], - vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES], + float cubeMips, int numProbes, mat4 inWorldToObjArray[MAX_FORWARD_PROBES], vec4 inProbeConfigData[MAX_FORWARD_PROBES], + vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 inRefScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES], float skylightCubemapIdx, sampler2D BRDFTexture, samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR, int showAtten, int showContrib, int showSpec, int showDiff) { @@ -527,15 +521,15 @@ vec4 debugVizForwardProbes(Surface surface, { contribution[i] = 0; - if (probeConfigData[i].r == 0) //box + if (inProbeConfigData[i].r == 0) //box { - contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b); + contribution[i] = defineBoxSpaceInfluence(surface.P, inWorldToObjArray[i], inProbeConfigData[i].b); if (contribution[i] > 0.0) probehits++; } - else if (probeConfigData[i].r == 1) //sphere + else if (inProbeConfigData[i].r == 1) //sphere { - contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g); + contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, inProbeConfigData[i].g); if (contribution[i] > 0.0) probehits++; } @@ -620,8 +614,8 @@ vec4 debugVizForwardProbes(Surface surface, float contrib = contribution[i]; if (contrib > 0.0f) { - float cubemapIdx = probeConfigData[i].a; - vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz); + float cubemapIdx = inProbeConfigData[i].a; + vec3 dir = boxProject(surface.P, surface.R, inWorldToObjArray[i], inRefScaleArray[i].xyz, inRefPosArray[i].xyz); irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib; specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib; diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index c91bd21a1..2a52e6eeb 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -24,6 +24,9 @@ #include "./brdf.hlsl" #include "./shaderModelAutoGen.hlsl" +//globals +uniform float3 eyePosWorld; +uniform float maxProbeDrawDistance; #ifndef TORQUE_SHADERGEN // These are the uniforms used by most lighting shaders. @@ -333,7 +336,7 @@ float defineSphereSpaceInfluence(float3 wsPosition, float3 wsProbePosition, floa { float3 L = wsProbePosition.xyz - wsPosition; float contribution = 1.0 - length(L) / radius; - return contribution; + return saturate(contribution); } float getDistBoxToPoint(float3 pt, float3 extents) @@ -345,10 +348,9 @@ float getDistBoxToPoint(float3 pt, float3 extents) float defineBoxSpaceInfluence(float3 wsPosition, float4x4 worldToObj, float attenuation) { float3 surfPosLS = mul(worldToObj, float4(wsPosition, 1.0)).xyz; - float atten = 1.0 - attenuation; float baseVal = 0.25; float dist = getDistBoxToPoint(surfPosLS, float3(baseVal, baseVal, baseVal)); - return saturate(smoothstep(baseVal + 0.0001, atten*baseVal, dist)); + return saturate(smoothstep(baseVal, (baseVal-attenuation/2), dist)); } // Box Projected IBL Lighting @@ -370,9 +372,9 @@ float3 boxProject(float3 wsPosition, float3 wsReflectVec, float4x4 worldToObj, f } float4 computeForwardProbes(Surface surface, - float cubeMips, int numProbes, float4x4 worldToObjArray[MAX_FORWARD_PROBES], float4 probeConfigData[MAX_FORWARD_PROBES], - float4 inProbePosArray[MAX_FORWARD_PROBES], float4 refScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES], - float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture), + float cubeMips, int numProbes, float4x4 inWorldToObjArray[MAX_FORWARD_PROBES], float4 inProbeConfigData[MAX_FORWARD_PROBES], + float4 inProbePosArray[MAX_FORWARD_PROBES], float4 inRefScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES], + float3 wsEyePos, float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture), TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR)) { int i = 0; @@ -384,50 +386,41 @@ float4 computeForwardProbes(Surface surface, float probehits = 0; //Set up our struct data float contribution[MAX_FORWARD_PROBES]; + //Process prooooobes for (i = 0; i < numProbes; ++i) { - contribution[i] = 0; - - if (probeConfigData[i].r == 0) //box + contribution[i] = 0.0; + float atten = 1.0-(length(wsEyePos-inProbePosArray[i].xyz)/maxProbeDrawDistance); + if (inProbeConfigData[i].r == 0) //box { - contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b); - if (contribution[i] > 0.0) - probehits++; + contribution[i] = defineBoxSpaceInfluence(surface.P, inWorldToObjArray[i], inProbeConfigData[i].b)*atten; } - else if (probeConfigData[i].r == 1) //sphere + else if (inProbeConfigData[i].r == 1) //sphere { - contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g); - if (contribution[i] > 0.0) - probehits++; + contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, inProbeConfigData[i].g)*atten; } - contribution[i] = max(contribution[i], 0); + if (contribution[i]>0.0) + probehits++; + else + contribution[i] = 0.0; blendSum += contribution[i]; - invBlendSum += (1.0f - contribution[i]); } - if (probehits > 1.0) + if (probehits > 1.0)//if we overlap { + invBlendSum = (probehits - blendSum)/(probehits-1); //grab the remainder for (i = 0; i < numProbes; i++) { - blendFactor[i] = ((contribution[i] / blendSum)) / probehits; - blendFactor[i] *= ((contribution[i]) / invBlendSum); - blendFactor[i] = saturate(blendFactor[i]); - blendFacSum += blendFactor[i]; + blendFactor[i] = contribution[i]/blendSum; //what % total is this instance + blendFactor[i] *= blendFactor[i] / invBlendSum; //what should we add to sum to 1 + blendFacSum += blendFactor[i]; //running tally of results } - // Normalize blendVal - if (blendFacSum == 0.0f) // Possible with custom weight - { - blendFacSum = 1.0f; - } - - float invBlendSumWeighted = 1.0f / blendFacSum; for (i = 0; i < numProbes; ++i) { - blendFactor[i] *= invBlendSumWeighted; - contribution[i] *= blendFactor[i]; + contribution[i] *= blendFactor[i]/blendFacSum; //normalize } } @@ -474,8 +467,8 @@ float4 computeForwardProbes(Surface surface, float contrib = contribution[i]; if (contrib > 0.0f) { - int cubemapIdx = probeConfigData[i].a; - float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz); + int cubemapIdx = inProbeConfigData[i].a; + float3 dir = boxProject(surface.P, surface.R, inWorldToObjArray[i], inRefScaleArray[i].xyz, inRefPosArray[i].xyz); irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib; specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib; @@ -494,8 +487,8 @@ float4 computeForwardProbes(Surface surface, float3 kD = 1.0f - F; kD *= 1.0f - surface.metalness; - float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex) - float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(dfgNdotV, surface.roughness,0,0)).rg; + //float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex) + float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.NdotV, surface.roughness,0,0)).rg; specular *= F * envBRDF.x + surface.f90 * envBRDF.y; irradiance *= kD * surface.baseColor.rgb; @@ -507,13 +500,16 @@ float4 computeForwardProbes(Surface surface, float horizonOcclusion = 1.3; float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); horizon *= horizon; - +#if CAPTURING == 1 + return float4(lerp(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0); +#else return float4((irradiance + specular) * horizon, 0);//alpha writes disabled +#endif } float4 debugVizForwardProbes(Surface surface, - float cubeMips, int numProbes, float4x4 worldToObjArray[MAX_FORWARD_PROBES], float4 probeConfigData[MAX_FORWARD_PROBES], - float4 inProbePosArray[MAX_FORWARD_PROBES], float4 refScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES], + float cubeMips, int numProbes, float4x4 inWorldToObjArray[MAX_FORWARD_PROBES], float4 inProbeConfigData[MAX_FORWARD_PROBES], + float4 inProbePosArray[MAX_FORWARD_PROBES], float4 inRefScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES], float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture), TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR), int showAtten, int showContrib, int showSpec, int showDiff) { @@ -530,15 +526,15 @@ float4 debugVizForwardProbes(Surface surface, { contribution[i] = 0; - if (probeConfigData[i].r == 0) //box + if (inProbeConfigData[i].r == 0) //box { - contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b); + contribution[i] = defineBoxSpaceInfluence(surface.P, inWorldToObjArray[i], inProbeConfigData[i].b); if (contribution[i] > 0.0) probehits++; } - else if (probeConfigData[i].r == 1) //sphere + else if (inProbeConfigData[i].r == 1) //sphere { - contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g); + contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, inProbeConfigData[i].g); if (contribution[i] > 0.0) probehits++; } @@ -623,8 +619,8 @@ float4 debugVizForwardProbes(Surface surface, float contrib = contribution[i]; if (contrib > 0.0f) { - int cubemapIdx = probeConfigData[i].a; - float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz); + int cubemapIdx = inProbeConfigData[i].a; + float3 dir = boxProject(surface.P, surface.R, inWorldToObjArray[i], inRefScaleArray[i].xyz, inRefPosArray[i].xyz); irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib; specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib; diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/pointLightP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/pointLightP.glsl index 429208a29..310a84a0a 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/pointLightP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/pointLightP.glsl @@ -196,6 +196,38 @@ void main() lightCol *= max(cookie.r, max(cookie.g, cookie.b)); #endif + #ifdef DIFFUSE_LIGHT_VIZ + float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); + vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; + + vec3 diffuse = BRDF_GetDebugDiffuse(surface,surfaceToLight) * factor; + vec3 final = max(0.0f, diffuse); + OUT_col = vec4(final, 0); + return + #endif + + #ifdef SPECULAR_LIGHT_VIZ + float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); + vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; + + vec3 diffuse = BRDF_GetDebugSpecular(surface,surfaceToLight) * factor; + vec3 final = max(0.0f, diffuse); + OUT_col = vec4(final, 0); + return + #endif + + #ifdef DETAIL_LIGHTING_VIZ + float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); + vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; + + vec3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor; + vec3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor; + + vec3 final = max(vec3(0.0f), diffuse + spec * surface.F); + OUT_col = vec4(final, 0); + return + #endif + //get punctual light contribution lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed); } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl index 8efe15c05..e7fa0e2f8 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl @@ -84,78 +84,57 @@ void main() { contribution[i] = 0; + float atten =1.0-(length(eyePosWorld-probePosArray[i].xyz)/maxProbeDrawDistance); if (probeConfigData[i].r == 0) //box { - contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b); - if (contribution[i]>0.0) - probehits++; + contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b)*atten; } else if (probeConfigData[i].r == 1) //sphere { - contribution[i] = defineSphereSpaceInfluence(surface.P, probePosArray[i].xyz, probeConfigData[i].g); + contribution[i] = defineSphereSpaceInfluence(surface.P, probePosArray[i].xyz, probeConfigData[i].g)*atten; + } + if (contribution[i]>0.0) probehits++; - } - - contribution[i] = max(contribution[i],0); + else + contribution[i] = 0; blendSum += contribution[i]; - invBlendSum += (1.0f - contribution[i]); } - // Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary. - // And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1). - // respect constraint B. - // Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary - // and respect constraint A. - if (probehits > 1.0) + if (probehits > 1.0)//if we overlap { + invBlendSum = (probehits - blendSum)/(probehits-1); //grab the remainder for (i = 0; i < numProbes; i++) { - blendFactor[i] = ((contribution[i] / blendSum)) / probehits; - blendFactor[i] *= ((contribution[i]) / invBlendSum); - blendFactor[i] = saturate(blendFactor[i]); - blendFacSum += blendFactor[i]; + blendFactor[i] = contribution[i]/blendSum; //what % total is this instance + blendFactor[i] *= blendFactor[i] / invBlendSum; //what should we add to sum to 1 + blendFacSum += blendFactor[i]; //running tally of results } - // Normalize blendVal - if (blendFacSum == 0.0f) // Possible with custom weight - { - blendFacSum = 1.0f; - } - - float invBlendSumWeighted = 1.0f / blendFacSum; for (i = 0; i < numProbes; ++i) { - blendFactor[i] *= invBlendSumWeighted; - contribution[i] *= blendFactor[i]; + contribution[i] *= blendFactor[i]/blendFacSum; //normalize } } #if DEBUGVIZ_ATTENUATION == 1 - float contribAlpha = 1; + float contribAlpha = 0; for (i = 0; i < numProbes; ++i) { - contribAlpha -= contribution[i]; + contribAlpha += contribution[i]; } - OUT_col = vec4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1); + OUT_col = vec4(contribAlpha,contribAlpha,contribAlpha, 1); return; #endif #if DEBUGVIZ_CONTRIB == 1 vec3 finalContribColor = vec3(0, 0, 0); - float contribAlpha = 1; for (i = 0; i < numProbes; ++i) { - finalContribColor += contribution[i] *probeContribColors[i].rgb; - contribAlpha -= contribution[i]; + finalContribColor += contribution[i] * vec3(fmod(i+1,2),fmod(i+1,3),fmod(i+1,4)); } - - //Skylight coloration for anything not covered by probes above - if(skylightCubemapIdx != -1) - finalContribColor += vec3(0, 1, 0) * contribAlpha; - OUT_col = vec4(finalContribColor, 1); return; #endif @@ -188,7 +167,7 @@ void main() } #endif - if (skylightCubemapIdx != -1 && alpha > 0.001) + if (skylightCubemapIdx != -1 && alpha >= 0.001) { irradiance = lerp(irradiance,textureLod(irradianceCubemapAR, vec4(surface.R, skylightCubemapIdx), 0).xyz,alpha); specular = lerp(specular,textureLod(specularCubemapAR, vec4(surface.R, skylightCubemapIdx), lod).xyz,alpha); @@ -220,6 +199,9 @@ void main() float horizonOcclusion = 1.3; float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); horizon *= horizon; - - OUT_col = vec4(irradiance + specular, 0);//alpha writes disabled +#if CAPTURING == 1 + OUT_col = vec4(mix(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0); +#else + OUT_col = vec4((irradiance + specular) * horizon, 0);//alpha writes disabled +#endif } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl index d73aaf25a..6c80cc1eb 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl @@ -122,6 +122,41 @@ void main() lightCol *= max(cookie.r, max(cookie.g, cookie.b)); #endif + #ifdef DIFFUSE_LIGHT_VIZ + float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); + vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; + + vec3 diffuse = BRDF_GetDebugDiffuse(surface,surfaceToLight) * factor; + vec3 final = max(0.0f, diffuse) * getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams ); + + OUT_col = vec4(final, 0); + return; + #endif + + #ifdef SPECULAR_LIGHT_VIZ + float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); + float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; + + vec3 diffuse = BRDF_GetDebugSpecular(surface,surfaceToLight) * factor; + vec3 final = max(0.0f, diffuse) * getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams ); + + OUT_col = vec4(final, 0); + return; + #endif + + #ifdef DETAIL_LIGHTING_VIZ + float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); + vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; + + vec3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor; + vec3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor; + + vec3 final = max(vec3(0.0f), diffuse + spec * surface.F) * getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams ); + + OUT_col = vec4(final, 0); + return; + #endif + //get Punctual light contribution lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed); //get spot angle attenuation diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/vectorLightP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/vectorLightP.glsl index 6ee55321c..0bfa6e0f0 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/vectorLightP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/vectorLightP.glsl @@ -216,7 +216,7 @@ void main() lightingColor = shadowed_colors.rgb; #endif - shadow = lerp( shadow, 1.0, saturate( fadeOutAmt ) ); + shadow = mix( shadow, 1.0, saturate( fadeOutAmt ) ); #ifdef PSSM_DEBUG_RENDER if ( fadeOutAmt > 1.0 ) @@ -225,6 +225,37 @@ void main() #endif //NO_SHADOW + #ifdef DIFFUSE_LIGHT_VIZ + vec3 factor = lightingColor.rgb * max(surfaceToLight.NdotL, 0) * shadow * lightBrightness; + vec3 diffuse = BRDF_GetDebugDiffuse(surface,surfaceToLight) * factor; + + vec3 final = max(0.0f, diffuse); + + OUT_col = vec4(final, 0); + return; + #endif + + #ifdef SPECULAR_LIGHT_VIZ + vec3 factor = lightingColor.rgb * max(surfaceToLight.NdotL, 0) * shadow * lightBrightness; + vec3 spec = BRDF_GetDebugSpecular(surface, surfaceToLight) * factor; + + vec3 final = max(0.0f, factor); + + OUT_col = vec4(final, 0); + return; + #endif + + #ifdef DETAIL_LIGHTING_VIZ + vec3 factor = lightingColor.rgb * max(surfaceToLight.NdotL, 0) * shadow * lightBrightness; + vec3 diffuse = BRDF_GetDebugDiffuse(surface,surfaceToLight) * factor; + vec3 spec = BRDF_GetDebugSpecular(surface,surfaceToLight) * factor; + + vec3 final = max(0.0f, diffuse + spec); + + OUT_col = vec4(final, 0); + return; + #endif + //get directional light contribution vec3 lighting = getDirectionalLight(surface, surfaceToLight, lightingColor.rgb, lightBrightness, shadow); diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl index faa7a01ae..05a29d66d 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl @@ -134,7 +134,6 @@ uniform float shadowSoftness; uniform float4x4 worldToCamera; uniform float3x3 worldToLightProj; -uniform float3 eyePosWorld; uniform float4x4 cameraToWorld; float4 main( ConvexConnectP IN ) : SV_TARGET @@ -218,12 +217,12 @@ float4 main( ConvexConnectP IN ) : SV_TARGET #ifdef DETAIL_LIGHTING_VIZ float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); - vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; + float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; - vec3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor; - vec3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor; + float3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor; + float3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor; - vec3 final = max(vec3(0.0f), diffuse + spec * surface.F); + float3 final = max(float3(0.0f), diffuse + spec * surface.F); return final; #endif diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl index cff06decf..83f435de8 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl @@ -12,7 +12,6 @@ TORQUE_UNIFORM_SAMPLER2D(BRDFTexture, 3); uniform float4 rtParams0; uniform float4 vsFarPlane; uniform float4x4 cameraToWorld; -uniform float3 eyePosWorld; //cubemap arrays require all the same size. so shared mips# value uniform float cubeMips; @@ -76,79 +75,58 @@ float4 main(PFXVertToPix IN) : SV_TARGET //Process prooooobes for (i = 0; i < numProbes; ++i) { - contribution[i] = 0; + contribution[i] = 0.0; + float atten =1.0-(length(eyePosWorld-probePosArray[i].xyz)/maxProbeDrawDistance); if (probeConfigData[i].r == 0) //box { - contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b); - if (contribution[i]>0.0) - probehits++; + contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b)*atten; } else if (probeConfigData[i].r == 1) //sphere { - contribution[i] = defineSphereSpaceInfluence(surface.P, probePosArray[i].xyz, probeConfigData[i].g); + contribution[i] = defineSphereSpaceInfluence(surface.P, probePosArray[i].xyz, probeConfigData[i].g)*atten; + } + if (contribution[i]>0.0) probehits++; - } - - contribution[i] = max(contribution[i],0); + else + contribution[i] = 0.0; blendSum += contribution[i]; - invBlendSum += (1.0f - contribution[i]); } - // Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary. - // And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1). - // respect constraint B. - // Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary - // and respect constraint A. - if (probehits > 1.0) + if (probehits > 1.0)//if we overlap { + invBlendSum = (probehits - blendSum)/(probehits-1); //grab the remainder for (i = 0; i < numProbes; i++) { - blendFactor[i] = ((contribution[i] / blendSum)) / probehits; - blendFactor[i] *= ((contribution[i]) / invBlendSum); - blendFactor[i] = saturate(blendFactor[i]); - blendFacSum += blendFactor[i]; + blendFactor[i] = contribution[i]/blendSum; //what % total is this instance + blendFactor[i] *= blendFactor[i] / invBlendSum; //what should we add to sum to 1 + blendFacSum += blendFactor[i]; //running tally of results } - // Normalize blendVal - if (blendFacSum == 0.0f) // Possible with custom weight - { - blendFacSum = 1.0f; - } - - float invBlendSumWeighted = 1.0f / blendFacSum; for (i = 0; i < numProbes; ++i) { - blendFactor[i] *= invBlendSumWeighted; - contribution[i] *= blendFactor[i]; + contribution[i] *= blendFactor[i]/blendFacSum; //normalize } } #if DEBUGVIZ_ATTENUATION == 1 - float contribAlpha = 1; + float contribAlpha = 0; for (i = 0; i < numProbes; ++i) { - contribAlpha -= contribution[i]; + contribAlpha += contribution[i]; } - return float4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1); + return float4(contribAlpha,contribAlpha,contribAlpha, 1); #endif #if DEBUGVIZ_CONTRIB == 1 float3 finalContribColor = float3(0, 0, 0); - float contribAlpha = 1; for (i = 0; i < numProbes; ++i) { - finalContribColor += contribution[i] *probeContribColors[i].rgb; - contribAlpha -= contribution[i]; + finalContribColor += contribution[i] * float3(fmod(i+1,2),fmod(i+1,3),fmod(i+1,4)); } - - //Skylight coloration for anything not covered by probes above - if(skylightCubemapIdx != -1) - finalContribColor += float3(0, 1, 0) * contribAlpha; - return float4(finalContribColor, 1); #endif } @@ -209,6 +187,9 @@ float4 main(PFXVertToPix IN) : SV_TARGET float horizonOcclusion = 1.3; float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); horizon *= horizon; - +#if CAPTURING == 1 + return float4(lerp(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0); +#else return float4((irradiance + specular) * horizon, 0);//alpha writes disabled +#endif } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl index 02e11570a..fb3d4aae0 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl @@ -67,7 +67,6 @@ uniform float4x4 worldToLightProj; uniform float4 lightParams; uniform float shadowSoftness; -uniform float3 eyePosWorld; uniform float4x4 cameraToWorld; uniform float4x4 worldToCamera; @@ -147,12 +146,12 @@ float4 main( ConvexConnectP IN ) : SV_TARGET #ifdef DETAIL_LIGHTING_VIZ float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); - vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; + float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; - vec3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor; - vec3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor; + float3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor; + float3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor; - vec3 final = max(vec3(0.0f), diffuse + spec * surface.F) * getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams ); + vec3 final = max(float3(0.0f), diffuse + spec * surface.F) * getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams ); return final; #endif diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/vectorLightP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/vectorLightP.hlsl index e3b9206d4..d99544dca 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/vectorLightP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/vectorLightP.hlsl @@ -42,7 +42,6 @@ uniform float4 lightColor; uniform float4 lightAmbient; uniform float shadowSoftness; -uniform float3 eyePosWorld; uniform float4 atlasXOffset; uniform float4 atlasYOffset; From c1a88ec423c7b1560cb4e55281ab65acccece3e0 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sat, 12 Feb 2022 17:32:30 -0600 Subject: [PATCH 022/145] Complied connect var data in GL to D3D for the wsPosition Made the use of ints for the cubemapIdx in the shaders consistent --- Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp | 4 ++-- .../BaseGame/game/core/rendering/shaders/gl/lighting.glsl | 2 +- .../shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp index 94b457c75..fded366a1 100644 --- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp @@ -2960,9 +2960,9 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList MultiLine * meta = new MultiLine; // Now the wsPosition and wsView. - Var *wsPosition = getInWsPosition(componentList); Var *worldToTangent = getInWorldToTangent(componentList); Var *wsNormal = getInWorldNormal(componentList); + Var *wsPosition = getInWsPosition(componentList); Var *wsView = getWsView(wsPosition, meta); //Reflection Probe WIP @@ -3038,7 +3038,7 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList eyePos->setType("vec3"); eyePos->setName("eyePosWorld"); eyePos->uniform = true; - eyePos->constSortPos = cspPotentialPrimitive; + eyePos->constSortPos = cspPass; } Var *curColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget)); diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index 57ee38190..11d9a3047 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -462,7 +462,7 @@ vec4 computeForwardProbes(Surface surface, float contrib = contribution[i]; if (contrib > 0.0f) { - float cubemapIdx = int(inProbeConfigData[i].a); + int cubemapIdx = int(inProbeConfigData[i].a); vec3 dir = boxProject(surface.P, surface.R, inWorldToObjArray[i], inRefScaleArray[i].xyz, inRefPosArray[i].xyz); irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib; diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl index e7fa0e2f8..736a5491d 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl @@ -157,7 +157,7 @@ void main() float contrib = contribution[i]; if (contrib > 0.0f) { - float cubemapIdx = probeConfigData[i].a; + int cubemapIdx = int(probeConfigData[i].a); vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, refPosArray[i].xyz); irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib; From e04f844240f48360279b9d7f6be9f67f92a47ba8 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 13 Feb 2022 19:24:01 -0600 Subject: [PATCH 023/145] Scaling correction to probes in deferred mode to improve parallax adjustment Ensure that probes are masked to be rendered during bake passes so they can contribute during a bake allowing multibakes Adjusted order of the connect data for the forward shaders to fix a mis-port issue --- Engine/source/T3D/objectTypes.h | 2 +- Engine/source/renderInstance/renderProbeMgr.cpp | 2 +- Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp | 2 +- Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Engine/source/T3D/objectTypes.h b/Engine/source/T3D/objectTypes.h index 9044205cd..bd21310fa 100644 --- a/Engine/source/T3D/objectTypes.h +++ b/Engine/source/T3D/objectTypes.h @@ -229,7 +229,7 @@ enum SceneObjectTypeMasks : U32 EnvironmentObjectType ), SKYLIGHT_CAPTURE_TYPEMASK = (EnvironmentObjectType), - REFLECTION_PROBE_CAPTURE_TYPEMASK = (StaticObjectType | StaticShapeObjectType) + REFLECTION_PROBE_CAPTURE_TYPEMASK = (StaticObjectType | StaticShapeObjectType | LightObjectType) }; #endif diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 268bba5e5..393ad899e 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -328,7 +328,7 @@ void RenderProbeMgr::getBestProbes(const Point3F& objPosition, ProbeDataSet* pro MatrixF p2A = curEntry.mProbeInfo->mTransform; probeDataSet->probeWorldToObjArray[i] = p2A; p2A.inverse(); - probeDataSet->refScaleArray[i] = curEntry.mProbeInfo->mProbeRefScale / p2A.getScale(); + probeDataSet->refScaleArray[i] = curEntry.mProbeInfo->mProbeRefScale / (p2A.getScale()*2); Point3F probePos = curEntry.mProbeInfo->mObject->getPosition(); Point3F refPos = probePos + curEntry.mProbeInfo->mProbeRefOffset * probeDataSet->refScaleArray[i].asPoint3F(); diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp index fded366a1..06d146c39 100644 --- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp @@ -2960,9 +2960,9 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList MultiLine * meta = new MultiLine; // Now the wsPosition and wsView. + Var *wsPosition = getInWsPosition(componentList); Var *worldToTangent = getInWorldToTangent(componentList); Var *wsNormal = getInWorldNormal(componentList); - Var *wsPosition = getInWsPosition(componentList); Var *wsView = getWsView(wsPosition, meta); //Reflection Probe WIP diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp index a294f5f85..7361e2eaf 100644 --- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp @@ -3038,9 +3038,9 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList MultiLine *meta = new MultiLine; // Now the wsPosition and wsView. + Var* wsPosition = getInWsPosition(componentList); Var* worldToTangent = getInWorldToTangent(componentList); Var *wsNormal = getInWorldNormal(componentList); - Var* wsPosition = getInWsPosition(componentList); Var *wsView = getWsView(wsPosition, meta); //Reflection Probe WIP From a0f8b29da7ede49baeee858f186ea73d57031302 Mon Sep 17 00:00:00 2001 From: JeffR Date: Mon, 14 Feb 2022 01:07:39 -0600 Subject: [PATCH 024/145] Improves logical checks for the default value so it's more sane and stable Allows creation of polyhedrons via constructor with a origin and vector format, allowing to have default polyhedron values on triggers and physical zones --- Engine/source/T3D/physicalZone.cpp | 7 ++++ Engine/source/T3D/trigger.cpp | 7 ++++ Engine/source/console/simObject.cpp | 2 +- Engine/source/math/mPolyhedron.h | 47 +++++++++++++++++++++++++ Engine/source/persistence/taml/taml.cpp | 2 +- 5 files changed, 63 insertions(+), 2 deletions(-) diff --git a/Engine/source/T3D/physicalZone.cpp b/Engine/source/T3D/physicalZone.cpp index f3028ee45..9603a4f34 100644 --- a/Engine/source/T3D/physicalZone.cpp +++ b/Engine/source/T3D/physicalZone.cpp @@ -114,6 +114,13 @@ PhysicalZone::PhysicalZone() force_mag = 0.0f; orient_force = false; fade_amt = 1.0f; + + //Default up a basic square + Point3F vecs[3] = { Point3F(1.0, 0.0, 0.0), + Point3F(0.0, -1.0, 0.0), + Point3F(0.0, 0.0, 1.0) }; + + mPolyhedron = Polyhedron(Point3F(-0.5, 0.5, 0.0), vecs); } PhysicalZone::~PhysicalZone() diff --git a/Engine/source/T3D/trigger.cpp b/Engine/source/T3D/trigger.cpp index 1d075d7c3..bcf85810b 100644 --- a/Engine/source/T3D/trigger.cpp +++ b/Engine/source/T3D/trigger.cpp @@ -173,6 +173,13 @@ Trigger::Trigger() mTripOnce = false; mTrippedBy = 0xFFFFFFFF; mTripCondition = ""; + + //Default up a basic square + Point3F vecs[3] = { Point3F(1.0, 0.0, 0.0), + Point3F(0.0, -1.0, 0.0), + Point3F(0.0, 0.0, 1.0) }; + + mTriggerPolyhedron = Polyhedron(Point3F(-0.5, 0.5, 0.0), vecs); } Trigger::~Trigger() diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 3552f4dd1..e76263fc7 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -338,7 +338,7 @@ void SimObject::writeFields(Stream &stream, U32 tabStop) //If the field hasn't been changed from the default value, then don't bother writing it out const char* defaultValueCheck = defaultObject->getDataField(f->pFieldname, array); - if (defaultValueCheck != '\0' && dStricmp(defaultValueCheck, valCopy) == 0) + if (defaultValueCheck && defaultValueCheck[0] != '\0' && dStricmp(defaultValueCheck, valCopy) == 0) continue; val = valCopy; diff --git a/Engine/source/math/mPolyhedron.h b/Engine/source/math/mPolyhedron.h index 4496b219c..e43a0822f 100644 --- a/Engine/source/math/mPolyhedron.h +++ b/Engine/source/math/mPolyhedron.h @@ -307,6 +307,53 @@ struct PolyhedronImpl : public Base this->mEdgeList = edges; } + PolyhedronImpl(Point3F origin, Point3F vecs[3]) + { + // This setup goes against conventions for Polyhedrons in that it a) sets up + // edges with CCW instead of CW order for face[0] and that it b) lets plane + // normals face outwards rather than inwards. + + mPointList.setSize(8); + mPointList[0] = origin; + mPointList[1] = origin + vecs[0]; + mPointList[2] = origin + vecs[1]; + mPointList[3] = origin + vecs[2]; + mPointList[4] = origin + vecs[0] + vecs[1]; + mPointList[5] = origin + vecs[0] + vecs[2]; + mPointList[6] = origin + vecs[1] + vecs[2]; + mPointList[7] = origin + vecs[0] + vecs[1] + vecs[2]; + + Point3F normal; + mPlaneList.setSize(6); + + mCross(vecs[2], vecs[0], &normal); + mPlaneList[0].set(origin, normal); + mCross(vecs[0], vecs[1], &normal); + mPlaneList[1].set(origin, normal); + mCross(vecs[1], vecs[2], &normal); + mPlaneList[2].set(origin, normal); + mCross(vecs[1], vecs[0], &normal); + mPlaneList[3].set(mPointList[7], normal); + mCross(vecs[2], vecs[1], &normal); + mPlaneList[4].set(mPointList[7], normal); + mCross(vecs[0], vecs[2], &normal); + mPlaneList[5].set(mPointList[7], normal); + + mEdgeList.setSize(12); + mEdgeList[0].vertex[0] = 0; mEdgeList[0].vertex[1] = 1; mEdgeList[0].face[0] = 0; mEdgeList[0].face[1] = 1; + mEdgeList[1].vertex[0] = 1; mEdgeList[1].vertex[1] = 5; mEdgeList[1].face[0] = 0; mEdgeList[1].face[1] = 4; + mEdgeList[2].vertex[0] = 5; mEdgeList[2].vertex[1] = 3; mEdgeList[2].face[0] = 0; mEdgeList[2].face[1] = 3; + mEdgeList[3].vertex[0] = 3; mEdgeList[3].vertex[1] = 0; mEdgeList[3].face[0] = 0; mEdgeList[3].face[1] = 2; + mEdgeList[4].vertex[0] = 3; mEdgeList[4].vertex[1] = 6; mEdgeList[4].face[0] = 3; mEdgeList[4].face[1] = 2; + mEdgeList[5].vertex[0] = 6; mEdgeList[5].vertex[1] = 2; mEdgeList[5].face[0] = 2; mEdgeList[5].face[1] = 5; + mEdgeList[6].vertex[0] = 2; mEdgeList[6].vertex[1] = 0; mEdgeList[6].face[0] = 2; mEdgeList[6].face[1] = 1; + mEdgeList[7].vertex[0] = 1; mEdgeList[7].vertex[1] = 4; mEdgeList[7].face[0] = 4; mEdgeList[7].face[1] = 1; + mEdgeList[8].vertex[0] = 4; mEdgeList[8].vertex[1] = 2; mEdgeList[8].face[0] = 1; mEdgeList[8].face[1] = 5; + mEdgeList[9].vertex[0] = 4; mEdgeList[9].vertex[1] = 7; mEdgeList[9].face[0] = 4; mEdgeList[9].face[1] = 5; + mEdgeList[10].vertex[0] = 5; mEdgeList[10].vertex[1] = 7; mEdgeList[10].face[0] = 3; mEdgeList[10].face[1] = 4; + mEdgeList[11].vertex[0] = 7; mEdgeList[11].vertex[1] = 6; mEdgeList[11].face[0] = 3; mEdgeList[11].face[1] = 5; + } + /// Return the AABB around the polyhedron. Box3F getBounds() const { diff --git a/Engine/source/persistence/taml/taml.cpp b/Engine/source/persistence/taml/taml.cpp index 5200dcf28..a623ba8b1 100644 --- a/Engine/source/persistence/taml/taml.cpp +++ b/Engine/source/persistence/taml/taml.cpp @@ -729,7 +729,7 @@ ImplementEnumType(_TamlFormatMode, { //If the field hasn't been changed from the default value, then don't bother writing it out const char* fieldData = defaultObject->getDataField(fieldName, indexBuffer); - if (fieldData != '\0' && dStricmp(fieldData, pFieldValue) == 0) + if (fieldData && fieldData[0] != '\0' && dStricmp(fieldData, pFieldValue) == 0) continue; } From 28bf6c5b8fa84f2b226606af5bf56cdab14fd4c0 Mon Sep 17 00:00:00 2001 From: JeffR Date: Mon, 14 Feb 2022 08:58:19 -0600 Subject: [PATCH 025/145] Ensures that the capturing flag is toggled regardless of how we invoke for a probe to bake(previously it was only done with the batch bake) --- Engine/source/renderInstance/renderProbeMgr.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 393ad899e..a6aedc1b9 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -477,6 +477,8 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe) Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!"); U32 startMSTime = Platform::getRealMilliseconds(); + Con::setVariable("$Probes::Capturing", "1"); + String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/"); U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64); U32 prefilterMipLevels = mLog2(F32(resolution)) + 1; @@ -596,6 +598,8 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe) if (!renderWithProbes) RenderProbeMgr::smRenderReflectionProbes = probeRenderState; + Con::setVariable("$Probes::Capturing", "0"); + cubeRefl.unregisterReflector(); U32 endMSTime = Platform::getRealMilliseconds(); @@ -907,7 +911,5 @@ DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (n DefineEngineMethod(RenderProbeMgr, bakeProbes, void, (),, "@brief Iterates over all reflection probes in the scene and bakes their cubemaps\n\n.") { - Con::setVariable("$Probes::Capturing", "1"); object->bakeProbes(); - Con::setVariable("$Probes::Capturing", "0"); } From 1f7d06542e76b1ab298061a4361d1b157bceaf36 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Mon, 14 Feb 2022 14:42:15 -0600 Subject: [PATCH 026/145] doublesided material renderfix as per the OG writeup, need to apply horizon trick strictly to the specular component --- .../BaseGame/game/core/rendering/shaders/gl/lighting.glsl | 6 +++--- .../BaseGame/game/core/rendering/shaders/lighting.hlsl | 6 +++--- .../shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl | 4 ++-- .../shaders/lighting/advanced/reflectionProbeArrayP.hlsl | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index 11d9a3047..185306beb 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -496,9 +496,9 @@ vec4 computeForwardProbes(Surface surface, float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); horizon *= horizon; #if CAPTURING == 1 - return vec4(mix(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0); + return vec4(mix(surface.baseColor.rgb,(irradiance + specular* horizon) ,surface.metalness/2),0); #else - return vec4((irradiance + specular) * horizon, 0);//alpha writes disabled + return vec4((irradiance + specular* horizon) , 0);//alpha writes disabled #endif } @@ -657,5 +657,5 @@ vec4 debugVizForwardProbes(Surface surface, float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); horizon *= horizon; - return vec4((irradiance + specular) * horizon, 0);//alpha writes disabled + return vec4((irradiance + specular* horizon) , 0);//alpha writes disabled } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index 2a52e6eeb..35b6d0fd3 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -501,9 +501,9 @@ float4 computeForwardProbes(Surface surface, float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); horizon *= horizon; #if CAPTURING == 1 - return float4(lerp(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0); + return float4(lerp(surface.baseColor.rgb,(irradiance + specular* horizon) ,surface.metalness/2),0); #else - return float4((irradiance + specular) * horizon, 0);//alpha writes disabled + return float4((irradiance + specular* horizon) , 0);//alpha writes disabled #endif } @@ -662,5 +662,5 @@ float4 debugVizForwardProbes(Surface surface, float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); horizon *= horizon; - return float4((irradiance + specular) * horizon, 0);//alpha writes disabled + return float4((irradiance + specular* horizon) , 0);//alpha writes disabled } \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl index 736a5491d..813597c95 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl @@ -200,8 +200,8 @@ void main() float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); horizon *= horizon; #if CAPTURING == 1 - OUT_col = vec4(mix(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0); + OUT_col = vec4(mix(surface.baseColor.rgb,(irradiance + specular* horizon) ,surface.metalness/2),0); #else - OUT_col = vec4((irradiance + specular) * horizon, 0);//alpha writes disabled + OUT_col = vec4((irradiance + specular* horizon) , 0);//alpha writes disabled #endif } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl index 83f435de8..1b49a5e41 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl @@ -188,8 +188,8 @@ float4 main(PFXVertToPix IN) : SV_TARGET float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); horizon *= horizon; #if CAPTURING == 1 - return float4(lerp(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0); + return float4(lerp(surface.baseColor.rgb,(irradiance + specular* horizon) ,surface.metalness/2),0); #else - return float4((irradiance + specular) * horizon, 0);//alpha writes disabled + return result = float4((irradiance + specular* horizon) , 0);//alpha writes disabled #endif } From 540e82b95c9cc4cb626b5824fc9eef3b882d45f9 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Mon, 14 Feb 2022 19:50:37 -0600 Subject: [PATCH 027/145] template mixins need this-> specified --- Engine/source/math/mPolyhedron.h | 58 ++++++++++++++++---------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/Engine/source/math/mPolyhedron.h b/Engine/source/math/mPolyhedron.h index e43a0822f..78beaa79f 100644 --- a/Engine/source/math/mPolyhedron.h +++ b/Engine/source/math/mPolyhedron.h @@ -313,45 +313,45 @@ struct PolyhedronImpl : public Base // edges with CCW instead of CW order for face[0] and that it b) lets plane // normals face outwards rather than inwards. - mPointList.setSize(8); - mPointList[0] = origin; - mPointList[1] = origin + vecs[0]; - mPointList[2] = origin + vecs[1]; - mPointList[3] = origin + vecs[2]; - mPointList[4] = origin + vecs[0] + vecs[1]; - mPointList[5] = origin + vecs[0] + vecs[2]; - mPointList[6] = origin + vecs[1] + vecs[2]; - mPointList[7] = origin + vecs[0] + vecs[1] + vecs[2]; + this->mPointList.setSize(8); + this->mPointList[0] = origin; + this->mPointList[1] = origin + vecs[0]; + this->mPointList[2] = origin + vecs[1]; + this->mPointList[3] = origin + vecs[2]; + this->mPointList[4] = origin + vecs[0] + vecs[1]; + this->mPointList[5] = origin + vecs[0] + vecs[2]; + this->mPointList[6] = origin + vecs[1] + vecs[2]; + this->mPointList[7] = origin + vecs[0] + vecs[1] + vecs[2]; Point3F normal; - mPlaneList.setSize(6); + this->mPlaneList.setSize(6); mCross(vecs[2], vecs[0], &normal); - mPlaneList[0].set(origin, normal); + this->mPlaneList[0].set(origin, normal); mCross(vecs[0], vecs[1], &normal); - mPlaneList[1].set(origin, normal); + this->mPlaneList[1].set(origin, normal); mCross(vecs[1], vecs[2], &normal); - mPlaneList[2].set(origin, normal); + this->mPlaneList[2].set(origin, normal); mCross(vecs[1], vecs[0], &normal); - mPlaneList[3].set(mPointList[7], normal); + this->mPlaneList[3].set(this->mPointList[7], normal); mCross(vecs[2], vecs[1], &normal); - mPlaneList[4].set(mPointList[7], normal); + this->mPlaneList[4].set(this->mPointList[7], normal); mCross(vecs[0], vecs[2], &normal); - mPlaneList[5].set(mPointList[7], normal); + this->mPlaneList[5].set(this->mPointList[7], normal); - mEdgeList.setSize(12); - mEdgeList[0].vertex[0] = 0; mEdgeList[0].vertex[1] = 1; mEdgeList[0].face[0] = 0; mEdgeList[0].face[1] = 1; - mEdgeList[1].vertex[0] = 1; mEdgeList[1].vertex[1] = 5; mEdgeList[1].face[0] = 0; mEdgeList[1].face[1] = 4; - mEdgeList[2].vertex[0] = 5; mEdgeList[2].vertex[1] = 3; mEdgeList[2].face[0] = 0; mEdgeList[2].face[1] = 3; - mEdgeList[3].vertex[0] = 3; mEdgeList[3].vertex[1] = 0; mEdgeList[3].face[0] = 0; mEdgeList[3].face[1] = 2; - mEdgeList[4].vertex[0] = 3; mEdgeList[4].vertex[1] = 6; mEdgeList[4].face[0] = 3; mEdgeList[4].face[1] = 2; - mEdgeList[5].vertex[0] = 6; mEdgeList[5].vertex[1] = 2; mEdgeList[5].face[0] = 2; mEdgeList[5].face[1] = 5; - mEdgeList[6].vertex[0] = 2; mEdgeList[6].vertex[1] = 0; mEdgeList[6].face[0] = 2; mEdgeList[6].face[1] = 1; - mEdgeList[7].vertex[0] = 1; mEdgeList[7].vertex[1] = 4; mEdgeList[7].face[0] = 4; mEdgeList[7].face[1] = 1; - mEdgeList[8].vertex[0] = 4; mEdgeList[8].vertex[1] = 2; mEdgeList[8].face[0] = 1; mEdgeList[8].face[1] = 5; - mEdgeList[9].vertex[0] = 4; mEdgeList[9].vertex[1] = 7; mEdgeList[9].face[0] = 4; mEdgeList[9].face[1] = 5; - mEdgeList[10].vertex[0] = 5; mEdgeList[10].vertex[1] = 7; mEdgeList[10].face[0] = 3; mEdgeList[10].face[1] = 4; - mEdgeList[11].vertex[0] = 7; mEdgeList[11].vertex[1] = 6; mEdgeList[11].face[0] = 3; mEdgeList[11].face[1] = 5; + this->mEdgeList.setSize(12); + this->mEdgeList[0].vertex[0] = 0; this->mEdgeList[0].vertex[1] = 1; this->mEdgeList[0].face[0] = 0; this->mEdgeList[0].face[1] = 1; + this->mEdgeList[1].vertex[0] = 1; this->mEdgeList[1].vertex[1] = 5; this->mEdgeList[1].face[0] = 0; this->mEdgeList[1].face[1] = 4; + this->mEdgeList[2].vertex[0] = 5; this->mEdgeList[2].vertex[1] = 3; this->mEdgeList[2].face[0] = 0; this->mEdgeList[2].face[1] = 3; + this->mEdgeList[3].vertex[0] = 3; this->mEdgeList[3].vertex[1] = 0; this->mEdgeList[3].face[0] = 0; this->mEdgeList[3].face[1] = 2; + this->mEdgeList[4].vertex[0] = 3; this->mEdgeList[4].vertex[1] = 6; this->mEdgeList[4].face[0] = 3; this->mEdgeList[4].face[1] = 2; + this->mEdgeList[5].vertex[0] = 6; this->mEdgeList[5].vertex[1] = 2; this->mEdgeList[5].face[0] = 2; this->mEdgeList[5].face[1] = 5; + this->mEdgeList[6].vertex[0] = 2; this->mEdgeList[6].vertex[1] = 0; this->mEdgeList[6].face[0] = 2; this->mEdgeList[6].face[1] = 1; + this->mEdgeList[7].vertex[0] = 1; this->mEdgeList[7].vertex[1] = 4; this->mEdgeList[7].face[0] = 4; this->mEdgeList[7].face[1] = 1; + this->mEdgeList[8].vertex[0] = 4; this->mEdgeList[8].vertex[1] = 2; this->mEdgeList[8].face[0] = 1; this->mEdgeList[8].face[1] = 5; + this->mEdgeList[9].vertex[0] = 4; this->mEdgeList[9].vertex[1] = 7; this->mEdgeList[9].face[0] = 4; this->mEdgeList[9].face[1] = 5; + this->mEdgeList[10].vertex[0] = 5; this->mEdgeList[10].vertex[1] = 7; this->mEdgeList[10].face[0] = 3; this->mEdgeList[10].face[1] = 4; + this->mEdgeList[11].vertex[0] = 7; this->mEdgeList[11].vertex[1] = 6; this->mEdgeList[11].face[0] = 3; this->mEdgeList[11].face[1] = 5; } /// Return the AABB around the polyhedron. From ed36cf2c5ce0f568577394588f59ae15b61d2307 Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 17 Feb 2022 18:04:31 -0600 Subject: [PATCH 028/145] Changes for BaseUI Update --- Engine/source/T3D/assets/MaterialAsset.cpp | 6 ++ Engine/source/T3D/assets/assetImporter.cpp | 87 ++++++++++++++----- Engine/source/T3D/assets/assetImporter.h | 32 +++++++ Engine/source/Verve/GUI/VEditorButton.cpp | 2 +- Engine/source/afx/ui/afxSpellButton.cpp | 2 +- Engine/source/console/simDictionary.cpp | 2 +- .../source/gui/buttons/guiBitmapButtonCtrl.h | 2 +- Engine/source/gui/buttons/guiBorderButton.cpp | 2 +- .../source/gui/buttons/guiButtonBaseCtrl.cpp | 22 ++++- Engine/source/gui/buttons/guiButtonBaseCtrl.h | 7 +- Engine/source/gui/buttons/guiButtonCtrl.cpp | 5 +- Engine/source/gui/buttons/guiCheckBoxCtrl.cpp | 2 +- .../source/gui/buttons/guiIconButtonCtrl.cpp | 4 +- .../gui/buttons/guiSwatchButtonCtrl.cpp | 2 +- .../gui/buttons/guiToggleButtonCtrl.cpp | 4 +- .../gui/buttons/guiToolboxButtonCtrl.cpp | 2 +- .../source/gui/controls/guiGradientCtrl.cpp | 4 +- Engine/source/gui/core/guiCanvas.cpp | 3 + Engine/source/gui/utility/guiInputCtrl.cpp | 10 ++- Engine/source/gui/utility/guiInputCtrl.h | 1 + 20 files changed, 156 insertions(+), 45 deletions(-) diff --git a/Engine/source/T3D/assets/MaterialAsset.cpp b/Engine/source/T3D/assets/MaterialAsset.cpp index 50e75ffa3..e51f9a709 100644 --- a/Engine/source/T3D/assets/MaterialAsset.cpp +++ b/Engine/source/T3D/assets/MaterialAsset.cpp @@ -319,6 +319,12 @@ U32 MaterialAsset::getAssetByMaterialName(StringTableEntry matName, AssetPtrsetAssetId(MaterialAsset::smNoMaterialAssetFallback); + (*matAsset)->mLoadedState = AssetErrCode::UsingFallback; + return AssetErrCode::UsingFallback; + } StringTableEntry MaterialAsset::getAssetIdByMaterialName(StringTableEntry matName) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index e9afcc479..8dc898dae 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -104,7 +104,9 @@ AssetImportConfig::AssetImportConfig() : importSounds(true), VolumeAdjust(false), PitchAdjust(false), - SoundsCompressed(false) + SoundsCompressed(false), + AlwaysAddSoundSuffix(false), + AddedSoundSuffix("_sound") { } @@ -316,6 +318,8 @@ void AssetImportConfig::loadImportConfig(Settings* configSettings, String config VolumeAdjust = dAtof(configSettings->value(String(configName + "/Sounds/VolumeAdjust").c_str())); PitchAdjust = dAtof(configSettings->value(String(configName + "/Sounds/PitchAdjust").c_str())); SoundsCompressed = dAtob(configSettings->value(String(configName + "/Sounds/Compressed").c_str())); + AlwaysAddSoundSuffix = dAtob(configSettings->value(String(configName + "/Sounds/AlwaysAddSoundSuffix").c_str())); + AddedSoundSuffix = configSettings->value(String(configName + "/Sounds/AddedSoundSuffix").c_str()); } void AssetImportConfig::CopyTo(AssetImportConfig* target) const @@ -406,6 +410,8 @@ void AssetImportConfig::CopyTo(AssetImportConfig* target) const target->VolumeAdjust = VolumeAdjust; target->PitchAdjust = PitchAdjust; target->SoundsCompressed = SoundsCompressed; + target->AlwaysAddSoundSuffix = AlwaysAddSoundSuffix; + target->AddedSoundSuffix = AddedSoundSuffix; } ConsoleDocClass(AssetImportObject, @@ -607,6 +613,7 @@ AssetImportObject* AssetImporter::addImportingAsset(String assetType, Torque::Pa assetName.replace('*', '_'); assetName.replace('-', '_'); assetName.replace('+', '_'); + assetName.replace('&', '_'); assetImportObj->assetType = assetType; assetImportObj->filePath = filePath; @@ -622,6 +629,14 @@ AssetImportObject* AssetImporter::addImportingAsset(String assetType, Torque::Pa assetImportObj->importStatus = AssetImportObject::NotProcessed; assetImportObj->generatedAsset = false; + //If the config is marked to always set the directory prefix, do that now + if (activeImportConfig->AddDirectoryPrefixToAssetName) + { + assetName = getFolderPrefixedName(assetImportObj); + assetImportObj->assetName = assetName; + assetImportObj->cleanAssetName = assetName; + } + if (parentItem != nullptr) { dSprintf(importLogBuffer, sizeof(importLogBuffer), "Added Child Importing Asset to %s", parentItem->assetName.c_str()); @@ -1976,6 +1991,12 @@ void AssetImporter::processSoundAsset(AssetImportObject* assetItem) dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Sound for Import: %s", assetItem->assetName.c_str()); activityLog.push_back(importLogBuffer); + if (activeImportConfig->AlwaysAddSoundSuffix) + { + assetItem->assetName += activeImportConfig->AddedSoundSuffix; + assetItem->cleanAssetName = assetItem->assetName; + } + assetItem->importStatus = AssetImportObject::Processed; } @@ -2165,7 +2186,49 @@ void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem) { //Set trailing number String renamedAssetName = assetItem->assetName; - renamedAssetName = Sim::getUniqueName(renamedAssetName.c_str()); + String renamedAssetId = assetItem->moduleName + ":" + renamedAssetName; + + String addedSuffix; + + if (assetItem->assetType == String("ShapeAsset")) + addedSuffix = activeImportConfig->AddedShapeSuffix; + else if (assetItem->assetType == String("MaterialAsset")) + addedSuffix = activeImportConfig->AddedMaterialSuffix; + else if (assetItem->assetType == String("ImageAsset")) + addedSuffix = activeImportConfig->AddedImageSuffix; + else if (assetItem->assetType == String("SoundAsset")) + addedSuffix = activeImportConfig->AddedSoundSuffix; + + //do the suffix if it isn't already on it + if (!renamedAssetName.endsWith(addedSuffix.c_str())) + { + renamedAssetName += addedSuffix; + renamedAssetId = assetItem->moduleName + ":" + renamedAssetName; + assetItem->assetName = renamedAssetName; + } + + //if still conflicted + //add the directory prefix + if (AssetDatabase.isDeclaredAsset(renamedAssetId.c_str())) + { + renamedAssetName = getFolderPrefixedName(assetItem); + renamedAssetId = assetItem->moduleName + ":" + renamedAssetName; + assetItem->assetName = renamedAssetName; + } + + bool appendedNumber = false; + U32 uniqueNumber = 0; + while (AssetDatabase.isDeclaredAsset(renamedAssetId.c_str())) + { + uniqueNumber++; + renamedAssetId = assetItem->moduleName + ":" + renamedAssetName + String::ToString(uniqueNumber); + appendedNumber = true; + } + + if (appendedNumber) + { + renamedAssetName += String::ToString(uniqueNumber); + } //Log it's renaming dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was renamed due to %s as part of the Import Configuration", assetItem->assetName.c_str(), humanReadableReason.c_str()); @@ -2186,25 +2249,7 @@ void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem) } else if (activeImportConfig->DuplicateAutoResolution == String("FolderPrefix")) { - String renamedAssetName = assetItem->assetName; - - //Set trailing number - S32 dirIndex = assetItem->filePath.getDirectoryCount() - 1; - while (dirIndex > -1) - { - renamedAssetName = assetItem->assetName; - String owningFolder = assetItem->filePath.getDirectory(dirIndex); - - renamedAssetName = owningFolder + "_" + renamedAssetName; - - if (AssetDatabase.isDeclaredAsset(renamedAssetName)) - { - dirIndex--; - continue; - } - - break; - } + String renamedAssetName = getFolderPrefixedName(assetItem); //Log it's renaming dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was renamed due to %s as part of the Import Configuration", assetItem->assetName.c_str(), humanReadableReason.c_str()); diff --git a/Engine/source/T3D/assets/assetImporter.h b/Engine/source/T3D/assets/assetImporter.h index b03c89c40..9505d00b1 100644 --- a/Engine/source/T3D/assets/assetImporter.h +++ b/Engine/source/T3D/assets/assetImporter.h @@ -409,6 +409,15 @@ public: /// bool SoundsCompressed; + /// When importing an image, this indicates if it should automatically add a standard suffix onto the name + /// + bool AlwaysAddSoundSuffix; + + /// + /// If AlwaysAddSoundSuffix is on, this is the suffix to be added + /// + String AddedSoundSuffix; + public: AssetImportConfig(); virtual ~AssetImportConfig(); @@ -934,4 +943,27 @@ public: // void setTargetModuleId(const String& moduleId) { targetModuleId = moduleId; } const String& getTargetModuleId() { return targetModuleId; } + + String getFolderPrefixedName(AssetImportObject* assetItem) + { + String renamedAssetName = assetItem->assetName; + S32 dirIndex = assetItem->filePath.getDirectoryCount() - 1; + while (dirIndex > -1) + { + renamedAssetName = assetItem->assetName; + String owningFolder = assetItem->filePath.getDirectory(dirIndex); + + renamedAssetName = owningFolder + "_" + renamedAssetName; + + if (AssetDatabase.isDeclaredAsset(renamedAssetName)) + { + dirIndex--; + continue; + } + + break; + } + + return renamedAssetName; + } }; diff --git a/Engine/source/Verve/GUI/VEditorButton.cpp b/Engine/source/Verve/GUI/VEditorButton.cpp index 3c32424b4..d86f86e3f 100644 --- a/Engine/source/Verve/GUI/VEditorButton.cpp +++ b/Engine/source/Verve/GUI/VEditorButton.cpp @@ -186,7 +186,7 @@ void VEditorButton::onRender( Point2I offset, const RectI& updateRect ) { RectI boundsRect( offset, getExtent() ); - if ( mDepressed || mStateOn || mMouseOver ) + if ( mDepressed || mStateOn || mHighlighted ) { renderFilledBorder( boundsRect, mProfile->mBorderColorHL, mProfile->mFillColorHL ); } diff --git a/Engine/source/afx/ui/afxSpellButton.cpp b/Engine/source/afx/ui/afxSpellButton.cpp index 632d2e652..76888a73a 100644 --- a/Engine/source/afx/ui/afxSpellButton.cpp +++ b/Engine/source/afx/ui/afxSpellButton.cpp @@ -221,7 +221,7 @@ void afxSpellButton::onRender(Point2I offset, const RectI& updateRect) if (mActive) { - if (mMouseOver) state = HILIGHT; + if (mHighlighted) state = HILIGHT; if (mDepressed || mStateOn) state = DEPRESSED; } else diff --git a/Engine/source/console/simDictionary.cpp b/Engine/source/console/simDictionary.cpp index 93491fd1c..8730a89dd 100644 --- a/Engine/source/console/simDictionary.cpp +++ b/Engine/source/console/simDictionary.cpp @@ -53,7 +53,7 @@ void SimNameDictionary::insert(SimObject* obj) SimObject* checkForDup = find(obj->getName()); if (checkForDup) - Con::warnf("Warning! You have a duplicate datablock name of %s. This can cause problems. You should rename one of them.", obj->getName()); + Con::warnf("Warning! You have a duplicate object name of %s. This can cause problems. You should rename one of them.", obj->getName()); Mutex::lockMutex(mutex); #ifndef USE_NEW_SIMDICTIONARY diff --git a/Engine/source/gui/buttons/guiBitmapButtonCtrl.h b/Engine/source/gui/buttons/guiBitmapButtonCtrl.h index 59e7825f1..846cdaedb 100644 --- a/Engine/source/gui/buttons/guiBitmapButtonCtrl.h +++ b/Engine/source/gui/buttons/guiBitmapButtonCtrl.h @@ -137,7 +137,7 @@ class GuiBitmapButtonCtrl : public GuiButtonCtrl if( mActive ) { if( mDepressed || mStateOn ) return DEPRESSED; - if( mMouseOver ) return HILIGHT; + if( mHighlighted ) return HILIGHT; return NORMAL; } else diff --git a/Engine/source/gui/buttons/guiBorderButton.cpp b/Engine/source/gui/buttons/guiBorderButton.cpp index 6efc5bc77..24f4a50f3 100644 --- a/Engine/source/gui/buttons/guiBorderButton.cpp +++ b/Engine/source/gui/buttons/guiBorderButton.cpp @@ -79,7 +79,7 @@ void GuiBorderButtonCtrl::onRender(Point2I offset, const RectI &updateRect) } } - if ( mMouseOver ) + if ( mHighlighted ) { RectI bounds( offset, getExtent() ); for ( S32 i=0; i < mProfile->mBorderThickness; i++ ) diff --git a/Engine/source/gui/buttons/guiButtonBaseCtrl.cpp b/Engine/source/gui/buttons/guiButtonBaseCtrl.cpp index 4621d5fea..b72f1b280 100644 --- a/Engine/source/gui/buttons/guiButtonBaseCtrl.cpp +++ b/Engine/source/gui/buttons/guiButtonBaseCtrl.cpp @@ -98,7 +98,7 @@ EndImplementEnumType; GuiButtonBaseCtrl::GuiButtonBaseCtrl() { mDepressed = false; - mMouseOver = false; + mHighlighted = false; mActive = true; static StringTableEntry sButton = StringTable->insert( "Button" ); mButtonText = sButton; @@ -288,14 +288,14 @@ void GuiButtonBaseCtrl::onMouseEnter(const GuiEvent &event) if(isMouseLocked()) { mDepressed = true; - mMouseOver = true; + mHighlighted = true; } else { if ( mActive && mProfile->mSoundButtonOver ) SFX->playOnce(mProfile->mSoundButtonOver); - mMouseOver = true; + mHighlighted = true; } } @@ -309,7 +309,7 @@ void GuiButtonBaseCtrl::onMouseLeave(const GuiEvent &) onMouseLeave_callback(); if( isMouseLocked() ) mDepressed = false; - mMouseOver = false; + mHighlighted = false; } //----------------------------------------------------------------------------- @@ -542,3 +542,17 @@ DefineEngineMethod( GuiButtonBaseCtrl, resetState, void, (),, { object->resetState(); } + +DefineEngineMethod(GuiButtonBaseCtrl, setHighlighted, void, (bool highlighted), (false), + "Reset the mousing state of the button.\n\n" + "This method should not generally be called.") +{ + object->setHighlighted(highlighted); +} + +DefineEngineMethod(GuiButtonBaseCtrl, isHighlighted, bool, (),, + "Reset the mousing state of the button.\n\n" + "This method should not generally be called.") +{ + return object->isHighlighted(); +} diff --git a/Engine/source/gui/buttons/guiButtonBaseCtrl.h b/Engine/source/gui/buttons/guiButtonBaseCtrl.h index 0e3be53a7..60f76ea4a 100644 --- a/Engine/source/gui/buttons/guiButtonBaseCtrl.h +++ b/Engine/source/gui/buttons/guiButtonBaseCtrl.h @@ -49,7 +49,7 @@ class GuiButtonBaseCtrl : public GuiControl StringTableEntry mButtonText; StringTableEntry mButtonTextID; bool mDepressed; - bool mMouseOver; + bool mHighlighted; bool mStateOn; S32 mButtonType; S32 mRadioGroup; @@ -95,7 +95,10 @@ class GuiButtonBaseCtrl : public GuiControl bool getStateOn() const { return mStateOn; } void setDepressed( bool depressed ) { mDepressed = depressed; } - void resetState() {mDepressed = false; mMouseOver = false;} + void resetState() {mDepressed = false; mHighlighted = false;} + + void setHighlighted(bool highlighted) { mHighlighted = highlighted; } + bool isHighlighted() { return mHighlighted; } void acceleratorKeyPress(U32 index); void acceleratorKeyRelease(U32 index); diff --git a/Engine/source/gui/buttons/guiButtonCtrl.cpp b/Engine/source/gui/buttons/guiButtonCtrl.cpp index c0d5f4e08..8996f87a9 100644 --- a/Engine/source/gui/buttons/guiButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiButtonCtrl.cpp @@ -83,7 +83,7 @@ bool GuiButtonCtrl::onWake() void GuiButtonCtrl::onRender(Point2I offset, const RectI& updateRect) { - bool highlight = mMouseOver; + bool highlight = mHighlighted; bool depressed = mDepressed; ColorI fontColor = mActive ? ( highlight ? mProfile->mFontColorHL : mProfile->mFontColor ) : mProfile->mFontColorNA; @@ -107,7 +107,7 @@ void GuiButtonCtrl::onRender(Point2I offset, indexMultiplier = 4; else if ( mDepressed || mStateOn ) indexMultiplier = 2; - else if ( mMouseOver ) + else if ( mHighlighted ) indexMultiplier = 3; renderSizableBitmapBordersFilled( boundsRect, indexMultiplier, mProfile ); @@ -123,3 +123,4 @@ void GuiButtonCtrl::onRender(Point2I offset, //render the children renderChildControls( offset, updateRect); } + diff --git a/Engine/source/gui/buttons/guiCheckBoxCtrl.cpp b/Engine/source/gui/buttons/guiCheckBoxCtrl.cpp index b7b47b57c..983709c7a 100644 --- a/Engine/source/gui/buttons/guiCheckBoxCtrl.cpp +++ b/Engine/source/gui/buttons/guiCheckBoxCtrl.cpp @@ -106,7 +106,7 @@ void GuiCheckBoxCtrl::onRender(Point2I offset, const RectI &updateRect) } ColorI backColor = mActive ? mProfile->mFillColor : mProfile->mFillColorNA; - ColorI fontColor = mActive ? (mMouseOver ? mProfile->mFontColorHL : mProfile->mFontColor) : mProfile->mFontColorNA; + ColorI fontColor = mActive ? (mHighlighted ? mProfile->mFontColorHL : mProfile->mFontColor) : mProfile->mFontColorNA; ColorI insideBorderColor = isFirstResponder() ? mProfile->mBorderColorHL : mProfile->mBorderColor; // just draw the check box and the text: diff --git a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp index c0fb939ff..a84623fa1 100644 --- a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp @@ -218,7 +218,7 @@ void GuiIconButtonCtrl::onRender(Point2I offset, const RectI& updateRect) void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect ) { - bool highlight = mMouseOver; + bool highlight = mHighlighted; bool depressed = mDepressed; ColorI fontColor = mActive ? (highlight ? mProfile->mFontColorHL : mProfile->mFontColor) : mProfile->mFontColorNA; @@ -236,7 +236,7 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect ) else renderSlightlyLoweredBox(boundsRect, mProfile); } - else if(mMouseOver && mActive) + else if(mHighlighted && mActive) { // If there is a bitmap array then render using it. // Otherwise use a standard fill. diff --git a/Engine/source/gui/buttons/guiSwatchButtonCtrl.cpp b/Engine/source/gui/buttons/guiSwatchButtonCtrl.cpp index 7db73a05e..dea3e8535 100644 --- a/Engine/source/gui/buttons/guiSwatchButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiSwatchButtonCtrl.cpp @@ -90,7 +90,7 @@ bool GuiSwatchButtonCtrl::onWake() void GuiSwatchButtonCtrl::onRender( Point2I offset, const RectI &updateRect ) { - bool highlight = mMouseOver; + bool highlight = mHighlighted; ColorI borderColor = mActive ? ( highlight ? mProfile->mBorderColorHL : mProfile->mBorderColor ) : mProfile->mBorderColorNA; diff --git a/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp b/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp index a2aaaa6c9..8dea6943c 100644 --- a/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp @@ -66,7 +66,7 @@ void GuiToggleButtonCtrl::onPreRender() void GuiToggleButtonCtrl::onRender(Point2I offset, const RectI& updateRect) { - bool highlight = mMouseOver; + bool highlight = mHighlighted; bool depressed = mDepressed; ColorI fontColor = mActive ? ( highlight ? mProfile->mFontColorHL : mProfile->mFontColor ) : mProfile->mFontColorNA; @@ -89,7 +89,7 @@ void GuiToggleButtonCtrl::onRender(Point2I offset, indexMultiplier = 4; else if ( mDepressed || mStateOn ) indexMultiplier = 2; - else if ( mMouseOver ) + else if ( mHighlighted ) indexMultiplier = 3; diff --git a/Engine/source/gui/buttons/guiToolboxButtonCtrl.cpp b/Engine/source/gui/buttons/guiToolboxButtonCtrl.cpp index 3f1b26f0c..9a9a63831 100644 --- a/Engine/source/gui/buttons/guiToolboxButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiToolboxButtonCtrl.cpp @@ -144,7 +144,7 @@ void GuiToolboxButtonCtrl::onRender(Point2I offset, const RectI& updateRect) RectI r(offset, getExtent()); if ( mDepressed || mStateOn ) renderStateRect( mLoweredBitmap , r ); - else if ( mMouseOver ) + else if ( mHighlighted ) renderStateRect( mHoverBitmap , r ); } diff --git a/Engine/source/gui/controls/guiGradientCtrl.cpp b/Engine/source/gui/controls/guiGradientCtrl.cpp index 112f3859d..3b5959ae8 100644 --- a/Engine/source/gui/controls/guiGradientCtrl.cpp +++ b/Engine/source/gui/controls/guiGradientCtrl.cpp @@ -99,7 +99,7 @@ bool GuiGradientSwatchCtrl::onWake() void GuiGradientSwatchCtrl::onRender( Point2I offset, const RectI &updateRect ) { - bool highlight = mMouseOver; + bool highlight = mHighlighted; ColorI borderColor = mActive ? ( highlight ? mProfile->mBorderColorHL : mProfile->mBorderColor ) : mProfile->mBorderColorNA; RectI renderRect( offset, getExtent() ); @@ -632,4 +632,4 @@ DefineEngineMethod(GuiGradientCtrl, getColor, LinearColorF, (S32 idx), , "Get co } return LinearColorF::ONE; -} \ No newline at end of file +} diff --git a/Engine/source/gui/core/guiCanvas.cpp b/Engine/source/gui/core/guiCanvas.cpp index 0b894f7c3..95f6213c2 100644 --- a/Engine/source/gui/core/guiCanvas.cpp +++ b/Engine/source/gui/core/guiCanvas.cpp @@ -706,6 +706,9 @@ bool GuiCanvas::processInputEvent(InputEventInfo &inputEvent) if (mCursorEnabled || mForceMouseToGUI || (mAlwaysHandleMouseButtons && inputEvent.objType == SI_BUTTON) ) { + if (inputEvent.objType != SI_AXIS && inputEvent.action == SI_MAKE) + bool asdfasdf = true; + return processMouseEvent(inputEvent); } break; diff --git a/Engine/source/gui/utility/guiInputCtrl.cpp b/Engine/source/gui/utility/guiInputCtrl.cpp index 907d861a9..4c56f9133 100644 --- a/Engine/source/gui/utility/guiInputCtrl.cpp +++ b/Engine/source/gui/utility/guiInputCtrl.cpp @@ -61,7 +61,8 @@ ConsoleDocClass( GuiInputCtrl, GuiInputCtrl::GuiInputCtrl() : mSendAxisEvents(false), mSendBreakEvents(false), - mSendModifierEvents(false) + mSendModifierEvents(false), + mIgnoreMouseEvents(false) { } @@ -76,6 +77,8 @@ void GuiInputCtrl::initPersistFields() "If true, break events for all devices will generate callbacks (Default false)."); addField("sendModifierEvents", TypeBool, Offset(mSendModifierEvents, GuiInputCtrl), "If true, Make events will be sent for modifier keys (Default false)."); + addField("ignoreMouseEvents", TypeBool, Offset(mIgnoreMouseEvents, GuiInputCtrl), + "If true, any events from mouse devices will be passed through."); endGroup("GuiInputCtrl"); Parent::initPersistFields(); @@ -97,7 +100,7 @@ bool GuiInputCtrl::onWake() if ( !Parent::onWake() ) return( false ); - if( !smDesignTime ) + if( !smDesignTime && !mIgnoreMouseEvents) mouseLock(); setFirstResponder(); @@ -151,6 +154,9 @@ IMPLEMENT_CALLBACK(GuiInputCtrl, onAxisEvent, void, (const char* device, const c //------------------------------------------------------------------------------ bool GuiInputCtrl::onInputEvent( const InputEventInfo &event ) { + if (mIgnoreMouseEvents && event.deviceType == MouseDeviceType) + return false; + char deviceString[32]; if ( event.action == SI_MAKE ) { diff --git a/Engine/source/gui/utility/guiInputCtrl.h b/Engine/source/gui/utility/guiInputCtrl.h index be60371f3..269569693 100644 --- a/Engine/source/gui/utility/guiInputCtrl.h +++ b/Engine/source/gui/utility/guiInputCtrl.h @@ -36,6 +36,7 @@ protected: bool mSendAxisEvents; bool mSendBreakEvents; bool mSendModifierEvents; + bool mIgnoreMouseEvents; public: From 40acf752385a87f93eb4b6f0938a9a14196ccc3f Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 17 Feb 2022 18:21:13 -0600 Subject: [PATCH 029/145] Template changes --- .../game/core/gui/scripts/profiles.tscript | 21 +- Templates/BaseGame/game/data/UI/UI.tscript | 2 +- .../game/data/UI/guis/OptionsDlg.asset.taml | 7 - .../game/data/UI/guis/joinServerMenu.gui | 270 +--- .../game/data/UI/guis/joinServerMenu.tscript | 35 +- .../BaseGame/game/data/UI/guis/mainMenu.gui | 210 ++- .../game/data/UI/guis/mainMenu.tscript | 16 +- .../BaseGame/game/data/UI/guis/optionsDlg.gui | 1432 ----------------- .../game/data/UI/guis/optionsMenu.gui | 547 ++++--- .../game/data/UI/guis/optionsMenu.tscript | 203 ++- .../game/data/UI/images/scrollBar.png | Bin 6643 -> 9187 bytes .../game/data/UI/scripts/controlsMenu.tscript | 2 +- .../data/UI/scripts/menuInputButtons.tscript | 341 ---- .../game/data/UI/scripts/profiles.tscript | 6 + 14 files changed, 762 insertions(+), 2330 deletions(-) delete mode 100644 Templates/BaseGame/game/data/UI/guis/OptionsDlg.asset.taml delete mode 100644 Templates/BaseGame/game/data/UI/guis/optionsDlg.gui delete mode 100644 Templates/BaseGame/game/data/UI/scripts/menuInputButtons.tscript diff --git a/Templates/BaseGame/game/core/gui/scripts/profiles.tscript b/Templates/BaseGame/game/core/gui/scripts/profiles.tscript index dd0ede04a..57156bbbe 100644 --- a/Templates/BaseGame/game/core/gui/scripts/profiles.tscript +++ b/Templates/BaseGame/game/core/gui/scripts/profiles.tscript @@ -26,6 +26,10 @@ if($Gui::fontCacheDirectory $= "") $Gui::fontCacheDirectory = expandFilename("data/cache/fonts"); } +$TextMediumEmphasisColor = "200 200 200"; +$TextHighEmphasisColor = "224 224 224"; +$TextDisabledColor = "108 108 108"; + // ---------------------------------------------------------------------------- // GuiDefaultProfile is a special profile that all other profiles inherit // defaults from. It must exist. @@ -137,13 +141,20 @@ new GuiControlProfile(GuiTextEditProfile) category = "Core"; }; -if(!isObject(GuiScrollProfile)) -new GuiControlProfile(GuiScrollProfile) +if(!isObject(GuiMenuScrollProfile)) +new GuiControlProfile(GuiMenuScrollProfile) { opaque = true; - fillcolor = "255 255 255"; - fontColor = "0 0 0"; - fontColorHL = "150 150 150"; + fontColor = $TextMediumEmphasisColor; + fontColorHL = $TextMediumEmphasisColor; + fontColorNA = $TextDisabledColor; + fontColorSEL = $TextMediumEmphasisColor; + fillColor = "40 40 40"; + fillColorHL = "56 56 56"; + fillColorNA = "40 40 40"; + borderColor = "87 87 87"; + borderColorNA = "0 0 0"; + borderColorHL = "255 255 255"; border = true; bitmapAsset = "Core_GUI:scrollBar_image"; hasBitmapArray = true; diff --git a/Templates/BaseGame/game/data/UI/UI.tscript b/Templates/BaseGame/game/data/UI/UI.tscript index e0b1670d0..5b8c1ee6a 100644 --- a/Templates/BaseGame/game/data/UI/UI.tscript +++ b/Templates/BaseGame/game/data/UI/UI.tscript @@ -36,7 +36,7 @@ function UI::initClient(%this) %this.queueExec("./scripts/profiles"); //Now gui files - %this.queueExec("./scripts/menuInputButtons"); + %this.queueExec("./scripts/menuInputHandling"); %this.queueExec("./guis/mainMenu"); %this.queueExec("./guis/mainMenu.gui"); diff --git a/Templates/BaseGame/game/data/UI/guis/OptionsDlg.asset.taml b/Templates/BaseGame/game/data/UI/guis/OptionsDlg.asset.taml deleted file mode 100644 index 21467cbc8..000000000 --- a/Templates/BaseGame/game/data/UI/guis/OptionsDlg.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/data/UI/guis/joinServerMenu.gui b/Templates/BaseGame/game/data/UI/guis/joinServerMenu.gui index 4343fe7ad..17a2c4435 100644 --- a/Templates/BaseGame/game/data/UI/guis/joinServerMenu.gui +++ b/Templates/BaseGame/game/data/UI/guis/joinServerMenu.gui @@ -14,19 +14,27 @@ $guiContent = new GuiControl(JoinServerMenu) { canSave = "1"; canSaveDynamicFields = "1"; returnGui = "MainMenuGui"; - - new GuiInputCtrl(JoinServerMenuInputHandler){ - profile = "GuiInputCtrlProfile"; - visible = "1"; - active = "1"; - position = "0 0"; - extent = "1024 768"; + + new GuiInputCtrl(JoinServerMenuInputHandler) { + sendAxisEvents = "1"; + sendBreakEvents = "1"; + sendModifierEvents = "0"; + ignoreMouseEvents = "1"; + lockMouse = "0"; + position = "-10 0"; + extent = "10 10"; minExtent = "8 2"; horizSizing = "width"; vertSizing = "height"; - sendBreakEvents="1"; + profile = "GuiInputCtrlProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; }; - new GuiControl(JoinServerWindow) { position = "48 56"; extent = "928 655"; @@ -46,7 +54,7 @@ $guiContent = new GuiControl(JoinServerMenu) { percent = "100"; vertical = "0"; flipClip = "0"; - bitmap = "data/ui/images/panel.png"; + BitmapAsset = "UI:panel_image"; color = "255 255 255 255"; position = "0 0"; extent = "927 40"; @@ -89,7 +97,7 @@ $guiContent = new GuiControl(JoinServerMenu) { percent = "100"; vertical = "0"; flipClip = "0"; - bitmap = "data/ui/images/panel_low.png"; + BitmapAsset = "UI:panel_low_image"; color = "255 255 255 255"; position = "0 40"; extent = "927 618"; @@ -105,58 +113,6 @@ $guiContent = new GuiControl(JoinServerMenu) { canSave = "1"; canSaveDynamicFields = "0"; }; - new GuiTextCtrl() { - text = "Player Name:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "12 47"; - extent = "109 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "MenuSubHeaderText"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; - text = "Visitor"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "124 47"; - extent = "144 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuTextEditProfile"; - visible = "1"; - active = "1"; - variable = "$pref::Player::Name"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; new GuiTextCtrl(JS_status) { text = "No servers found."; maxLength = "255"; @@ -166,7 +122,7 @@ $guiContent = new GuiControl(JoinServerMenu) { anchorBottom = "0"; anchorLeft = "1"; anchorRight = "0"; - position = "277 47"; + position = "392 47"; extent = "148 18"; minExtent = "8 8"; horizSizing = "right"; @@ -324,25 +280,30 @@ $guiContent = new GuiControl(JoinServerMenu) { canSave = "1"; canSaveDynamicFields = "0"; - new GuiTextListCtrl(JS_serverList) { - columns = "0 200 270 335 400"; - fitParentWidth = "1"; - clipColumnText = "0"; - rowHeightPadding = "2"; + new GuiStackControl(JoinServerList) { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "10"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "0"; + changeChildPosition = "1"; position = "1 1"; - extent = "888 8"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextArrayProfile"; + extent = "888 16"; + minExtent = "16 16"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; visible = "1"; active = "1"; - altCommand = "JoinServerDlg.join();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "1"; canSave = "1"; canSaveDynamicFields = "0"; + class = "MenuList"; }; }; new GuiControl(JS_queryStatus) { @@ -427,130 +388,9 @@ $guiContent = new GuiControl(JoinServerMenu) { canSaveDynamicFields = "0"; }; }; - new GuiButtonCtrl(JoinServerBackBtn) { - text = "Return to Menu"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "1"; - position = "0 583"; - extent = "160 33"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "0"; - active = "1"; - command = "Canvas.popDialog(JoinServerMenu);\n\nif(isObject(JoinServerMenu.returnGui) && JoinServerMenu.returnGui.isMethod(\"onReturnTo\")) JoinServerMenu.returnGui.onReturnTo();"; - accelerator = "escape"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl(JoinServerQryLanBtn) { - text = "Query Lan"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "1"; - position = "160 583"; - extent = "160 33"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "0"; - active = "1"; - command = "JoinServerMenu.queryLan();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl(JoinServerQryInternetBtn) { - text = "Query Internet"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "1"; - position = "320 583"; - extent = "160 33"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "0"; - active = "1"; - command = "JoinServerMenu.query();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl(JoinServerRefreshBtn) { - text = "Refresh Server"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "1"; - position = "480 583"; - extent = "160 33"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "0"; - active = "1"; - command = "JoinServerMenu.refresh();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl(JoinServerJoinBtn) { - text = "Join Server"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "1"; - position = "640 583"; - extent = "160 33"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "0"; - active = "0"; - command = "JoinServerMenu.join();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiControl() { - position = "189 652"; - extent = "646 130"; - minExtent = "8 2"; - horizSizing = "center"; - vertSizing = "top"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiControl(JoinServerButtonHolder) { - position = "109 711"; + position = "116 711"; extent = "791 40"; minExtent = "8 2"; horizSizing = "center"; @@ -567,7 +407,7 @@ $guiContent = new GuiControl(JoinServerMenu) { new GuiIconButtonCtrl() { buttonMargin = "4 4"; - iconBitmap = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_Enter"; + BitmapAsset = "UI:Keyboard_Black_Return_image"; iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; @@ -586,7 +426,7 @@ $guiContent = new GuiControl(JoinServerMenu) { profile = "GuiMenuButtonProfile"; visible = "1"; active = "1"; - command = "OptionsMenu.apply();"; + command = "JoinServerMenu.join();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; @@ -597,7 +437,7 @@ $guiContent = new GuiControl(JoinServerMenu) { }; new GuiIconButtonCtrl() { buttonMargin = "4 4"; - iconBitmap = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_Esc"; + BitmapAsset = "UI:Keyboard_Black_Escape_image"; iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; @@ -616,7 +456,7 @@ $guiContent = new GuiControl(JoinServerMenu) { profile = "GuiMenuButtonProfile"; visible = "1"; active = "1"; - command = "OptionsMenu.backOut();"; + command = "JoinServerMenu.backOut();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; @@ -627,14 +467,14 @@ $guiContent = new GuiControl(JoinServerMenu) { }; new GuiIconButtonCtrl() { buttonMargin = "4 4"; - iconBitmap = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_Enter"; + BitmapAsset = "UI:Keyboard_Black_Q_image"; iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; textLocation = "Right"; textMargin = "4"; autoSize = "0"; - text = "Prev Tab"; + text = "Query LAN"; groupNum = "-1"; buttonType = "PushButton"; useMouseEvents = "0"; @@ -644,28 +484,27 @@ $guiContent = new GuiControl(JoinServerMenu) { horizSizing = "right"; vertSizing = "bottom"; profile = "GuiMenuButtonProfile"; - visible = "0"; - active = "0"; - command = "OptionsMenu.prevTab();"; + visible = "1"; + active = "1"; + command = "JoinServerMenu.queryLan();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; internalName = "queryLANButton"; class = "MenuInputButton"; - hidden = "1"; canSave = "1"; canSaveDynamicFields = "0"; }; new GuiIconButtonCtrl() { buttonMargin = "4 4"; - iconBitmap = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_Esc"; + BitmapAsset = "UI:Keyboard_Black_E_image"; iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; textLocation = "Right"; textMargin = "4"; autoSize = "0"; - text = "Next Tab"; + text = "Query Online"; groupNum = "-1"; buttonType = "PushButton"; useMouseEvents = "0"; @@ -675,28 +514,27 @@ $guiContent = new GuiControl(JoinServerMenu) { horizSizing = "right"; vertSizing = "bottom"; profile = "GuiMenuButtonProfile"; - visible = "0"; - active = "0"; - command = "OptionsMenu.nextTab();"; + visible = "1"; + active = "1"; + command = "JoinServerMenu.query();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; internalName = "queryInternetButton"; class = "MenuInputButton"; - hidden = "1"; canSave = "1"; canSaveDynamicFields = "0"; }; new GuiIconButtonCtrl() { buttonMargin = "4 4"; - bitmapAsset = "UI:Keyboard_Black_R_image"; + BitmapAsset = "UI:Keyboard_Black_R_image"; iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; textLocation = "Right"; textMargin = "4"; autoSize = "0"; - text = "Reset"; + text = "Refresh"; groupNum = "-1"; buttonType = "PushButton"; useMouseEvents = "0"; @@ -708,7 +546,7 @@ $guiContent = new GuiControl(JoinServerMenu) { profile = "GuiMenuButtonProfile"; visible = "1"; active = "1"; - command = "OptionsMenu.resetToDefaults();"; + command = "JoinServerMenu.refresh();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; diff --git a/Templates/BaseGame/game/data/UI/guis/joinServerMenu.tscript b/Templates/BaseGame/game/data/UI/guis/joinServerMenu.tscript index e65e85e5d..b2f0eb8eb 100644 --- a/Templates/BaseGame/game/data/UI/guis/joinServerMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/joinServerMenu.tscript @@ -3,10 +3,12 @@ function JoinServerMenu::onWake() { // Double check the status. Tried setting this the control // inactive to start with, but that didn't seem to work. - JoinServerJoinBtn.setActive(JS_serverList.rowCount() > 0); + JoinServerJoinBtn.setActive(JoinServerList.getCount() > 0); JoinServerButtonHolder.setActive(); + JoinServerList.setAsActiveMenuList(); + JoinServerMenuInputHandler.setFirstResponder(); } @@ -16,7 +18,7 @@ function JoinServerButtonHolder::onWake(%this) %this-->backButton.set("btn_b", "Escape", "Back", "JoinServerMenu.backOut();"); %this-->refreshButton.set("btn_y", "R", "Refresh", "JoinServerMenu.refresh();"); %this-->queryLANButton.set("btn_a", "Q", "Query LAN", "JoinServerMenu.queryLan();"); - %this-->queryInternetButton.set("btn_x", "E", "Query Internet", "JoinServerMenu.query();"); + %this-->queryInternetButton.set("btn_x", "E", "Query Online", "JoinServerMenu.query();"); } function JoinServerMenuInputHandler::onInputEvent(%this, %device, %action, %state) @@ -110,23 +112,23 @@ function JoinServerMenu::update(%this) { // Copy the servers into the server list. JS_queryStatus.setVisible(false); - JS_serverList.clear(); + JoinServerList.clear(); %sc = getServerCount(); for( %i = 0; %i < %sc; %i ++ ) { setServerInfo(%i); - JS_serverList.addRow( %i, - $ServerInfo::Name TAB - $ServerInfo::Ping TAB - $ServerInfo::PlayerCount @ "/" @ $ServerInfo::MaxPlayers TAB - $ServerInfo::Version TAB - $ServerInfo::MissionName - ); + %serverBtn = new GuiButtonCtrl(){ + text = $ServerInfo::Name TAB + $ServerInfo::Ping TAB + $ServerInfo::PlayerCount @ "/" @ $ServerInfo::MaxPlayers TAB + $ServerInfo::Version TAB + $ServerInfo::MissionName; + profile = GuiJoinServerButtonProfile; + extent = JoinServerList.extent.x SPC 30; + }; + JoinServerList.add(%serverBtn); } - JS_serverList.sort(0); - JS_serverList.setSelectedRow(0); - JS_serverList.scrollVisible(0); - JoinServerJoinBtn.setActive(JS_serverList.rowCount() > 0); + JoinServerJoinBtn.setActive(JoinServerList.getCount() > 0); } //---------------------------------------- @@ -141,11 +143,9 @@ function onServerQueryStatus(%status, %msg, %value) switch$ (%status) { case "start": - JoinServerJoinBtn.setActive(false); - JoinServerQryInternetBtn.setActive(false); JS_statusText.setText(%msg); JS_statusBar.setValue(0); - JS_serverList.clear(); + JoinServerList.clear(); case "ping": JS_statusText.setText("Ping Servers"); @@ -156,7 +156,6 @@ function onServerQueryStatus(%status, %msg, %value) JS_statusBar.setValue(%value); case "done": - JoinServerQryInternetBtn.setActive(true); JS_queryStatus.setVisible(false); JS_status.setText(%msg); JoinServerMenu.update(); diff --git a/Templates/BaseGame/game/data/UI/guis/mainMenu.gui b/Templates/BaseGame/game/data/UI/guis/mainMenu.gui index f33c06b1d..4c6c13697 100644 --- a/Templates/BaseGame/game/data/UI/guis/mainMenu.gui +++ b/Templates/BaseGame/game/data/UI/guis/mainMenu.gui @@ -1,6 +1,6 @@ //--- OBJECT WRITE BEGIN --- $guiContent = new GuiChunkedBitmapCtrl(MainMenuGui) { - bitmapAsset = "UI:background_dark_image"; + BitmapAsset = "UI:background_dark_image"; useVariable = "0"; tile = "0"; position = "0 0"; @@ -19,15 +19,11 @@ $guiContent = new GuiChunkedBitmapCtrl(MainMenuGui) { Enabled = "1"; isDecoy = "0"; navigationIndex = "-1"; - + new GuiBitmapCtrl(MainMenuAppLogo) { - bitmapAsset = "UI:Torque_3D_logo_alt_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; + BitmapAsset = "UI:Torque_3D_logo_alt_image"; + color = "255 255 255 255"; + wrap = "0"; position = "550 30"; extent = "443 139"; minExtent = "8 2"; @@ -41,26 +37,179 @@ $guiContent = new GuiChunkedBitmapCtrl(MainMenuGui) { isContainer = "0"; canSave = "1"; canSaveDynamicFields = "1"; + autoFitExtents = "0"; + bitmapMode = "Stretched"; + groupNum = "-1"; + masked = "0"; navigationIndex = "-1"; + useModifiers = "0"; + useStates = "1"; }; - - new GuiGameListMenuCtrl(MainMenuButtonList) { - debugRender = "0"; - callbackOnInputs = "1"; - position = "292 103"; - extent = "439 561"; - minExtent = "8 2"; + new GuiStackControl(MainMenuButtonList) { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "15"; + dynamicSize = "0"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "312 111"; + extent = "400 477"; + minExtent = "16 16"; horizSizing = "center"; vertSizing = "center"; - profile = "DefaultListMenuProfile"; + profile = "GuiDefaultProfile"; visible = "1"; active = "1"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; - isContainer = "0"; - class = "UIMenuButtonList"; + isContainer = "1"; canSave = "1"; canSaveDynamicFields = "0"; + class = "MenuList"; + + new GuiButtonCtrl(MainMenuSinglePlayerBtn) { + text = "Single Player"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 0"; + extent = "400 55"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "openSinglePlayerMenu();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(MainMenuCreateSrvrBtn) { + text = "Create Server"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 70"; + extent = "400 55"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "openMultiPlayerMenu();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(MainMenuJoinSrvrBtn) { + text = "Join Server"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 140"; + extent = "400 55"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "openJoinServerMenu();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(MainMenuOptionBtn) { + text = "Options"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 210"; + extent = "400 55"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "openOptionsMenu();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(MainMenuWorldEditBtn) { + text = "Open World Editor"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 280"; + extent = "400 55"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "openWorldEditorBtn();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(MainMenuGuiEditBtn) { + text = "Open GUI Editor"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 350"; + extent = "400 55"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "openGUIEditorBtn();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(MainMenuExitBtn) { + text = "Exit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 420"; + extent = "400 55"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "exit();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; new GuiControl(MainMenuButtonHolder) { position = "189 711"; @@ -80,7 +229,7 @@ $guiContent = new GuiChunkedBitmapCtrl(MainMenuGui) { new GuiIconButtonCtrl() { buttonMargin = "4 4"; - iconBitmap = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_Enter"; + BitmapAsset = "UI:Keyboard_Black_Return_image"; iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; @@ -109,5 +258,26 @@ $guiContent = new GuiChunkedBitmapCtrl(MainMenuGui) { canSaveDynamicFields = "0"; }; }; + new GuiInputCtrl(MainMenuInputHandler) { + class = "MenuInputHandler"; + sendAxisEvents = "1"; + sendBreakEvents = "1"; + sendModifierEvents = "0"; + ignoreMouseEvents = "1"; + lockMouse = "0"; + position = "-50 0"; + extent = "10 10"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiInputCtrlProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; //--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/UI/guis/mainMenu.tscript b/Templates/BaseGame/game/data/UI/guis/mainMenu.tscript index f66551acd..0d830f176 100644 --- a/Templates/BaseGame/game/data/UI/guis/mainMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/mainMenu.tscript @@ -5,8 +5,9 @@ function MainMenuGui::onAdd(%this) function MainMenuGui::onWake(%this) { - MainMenuButtonList.hidden = false; + MainMenuButtonList.setAsActiveMenuList(); MainMenuButtonHolder.setActive(); + MainMenuInputHandler.setFirstResponder(); } function MainMenuGui::onSleep(%this) @@ -16,18 +17,7 @@ function MainMenuGui::onSleep(%this) function MainMenuButtonHolder::onWake(%this) { - %this-->goButton.set("btn_a", "Return", "Go", "MainMenuButtonList.activateRow();"); -} - -function MainMenuButtonList::onAdd(%this) -{ - MainMenuButtonList.addRow("Single Player", "openSinglePlayerMenu", 0); - MainMenuButtonList.addRow("Create Server", "openMultiPlayerMenu", 4, -15); - MainMenuButtonList.addRow("Join Server", "openJoinServerMenu", 4, -15); - MainMenuButtonList.addRow("Options", "openOptionsMenu", 6, -15); - MainMenuButtonList.addRow("Open World Editor", "openWorldEditorBtn", 6, -15); - MainMenuButtonList.addRow("Open GUI Editor", "openGUIEditorBtn", 6, -15); - MainMenuButtonList.addRow("Exit Game", "quit", 8, -15); + %this-->goButton.set("btn_a", "Return", "Go", "MainMenuButtonList.activate();"); } function openSinglePlayerMenu() diff --git a/Templates/BaseGame/game/data/UI/guis/optionsDlg.gui b/Templates/BaseGame/game/data/UI/guis/optionsDlg.gui deleted file mode 100644 index b2758c32c..000000000 --- a/Templates/BaseGame/game/data/UI/guis/optionsDlg.gui +++ /dev/null @@ -1,1432 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -$guiContent = new GuiControl(OptionsDlg) { - position = "0 0"; - extent = "1024 768"; - minExtent = "8 8"; - horizSizing = "width"; - vertSizing = "height"; - profile = "GuiOverlayProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "1"; - fixedAspectRatio = "0"; - - new GuiWindowCtrl() { - text = "Options"; - resizeWidth = "0"; - resizeHeight = "0"; - canMove = "1"; - canClose = "1"; - canMinimize = "0"; - canMaximize = "0"; - canCollapse = "0"; - closeCommand = "Canvas.popDialog(optionsDlg);"; - edgeSnap = "0"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "323 232"; - extent = "377 303"; - minExtent = "8 8"; - horizSizing = "center"; - vertSizing = "center"; - profile = "GuiWindowProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiButtonCtrl() { - text = "Done"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "306 271"; - extent = "60 23"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiButtonProfile"; - visible = "1"; - active = "1"; - command = "Canvas.popDialog(optionsDlg);"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiBitmapBorderCtrl() { - position = "9 55"; - extent = "358 210"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTabBorderProfile"; - visible = "0"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "OptControlsPane"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiScrollCtrl() { - willFirstRespond = "1"; - hScrollBar = "alwaysOff"; - vScrollBar = "alwaysOn"; - lockHorizScroll = "1"; - lockVertScroll = "0"; - constantThumbHeight = "0"; - childMargin = "0 0"; - mouseWheelScrollSpeed = "-1"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "5 24"; - extent = "347 152"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiScrollProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiTextListCtrl() { - columns = "0 160"; - fitParentWidth = "1"; - clipColumnText = "0"; - position = "1 1"; - extent = "329 780"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - altCommand = "OptionsDlg.doRemap();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "OptRemapList"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiTextCtrl() { - text = "Control Name"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "6 6"; - extent = "64 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Control Binding"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "165 6"; - extent = "72 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - - new GuiSliderCtrl(OptMouseSensitivity) { - range = "0.02 2"; - ticks = "10"; - value = "0.75"; - isContainer = "0"; - Profile = "GuiSliderProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "105 182"; - Extent = "244 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "OptMouseSetSensitivity(OptMouseSensitivity.value);"; - tooltipprofile = "GuiToolTipProfile"; - hovertime = "1000"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Mouse Sensitivity:"; - maxLength = "255"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - isContainer = "0"; - Profile = "GuiTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "15 182"; - Extent = "85 18"; - MinExtent = "8 8"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "GuiToolTipProfile"; - hovertime = "1000"; - canSaveDynamicFields = "0"; - }; - }; - new GuiBitmapBorderCtrl() { - position = "9 55"; - extent = "358 210"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTabBorderProfile"; - visible = "0"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "OptAudioPane"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiMLTextCtrl() { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - useURLMouseCursor = "0"; - position = "149 10"; - extent = "190 14"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMLTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptAudioInfo"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Audio Provider:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "16 16"; - extent = "75 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl(OptAudioProviderList) { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - text = "Null"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "101 15"; - extent = "240 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Audio Device:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "23 48"; - extent = "75 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl(OptAudioDeviceList) { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - text = "SFX Null Device"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "101 47"; - extent = "240 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiControl() { - position = "18 84"; - extent = "325 17"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiTextCtrl() { - text = "Master Volume"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "0 0"; - extent = "72 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiAutoSizeTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiSliderCtrl() { - range = "0 1"; - ticks = "0"; - snap = "0"; - value = "0.8"; - position = "85 1"; - extent = "240 14"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiSliderProfile"; - visible = "1"; - active = "1"; - altCommand = "OptAudioUpdateMasterVolume( $thisControl.value );"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptAudioVolumeMaster"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiControl() { - position = "9 115"; - extent = "334 17"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiTextCtrl() { - text = "Interface Volume"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "0 0"; - extent = "82 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiAutoSizeTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiSliderCtrl() { - range = "0 1"; - ticks = "0"; - snap = "0"; - value = "1"; - position = "94 2"; - extent = "240 13"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiSliderProfile"; - visible = "1"; - active = "1"; - altCommand = "OptAudioUpdateChannelVolume(AudioGui, $thisControl.value);"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptAudioVolumeShell"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiControl() { - position = "18 146"; - extent = "325 17"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiTextCtrl() { - text = "Effects Volume"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "0 0"; - extent = "74 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiAutoSizeTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiSliderCtrl() { - range = "0 1"; - ticks = "0"; - snap = "0"; - value = "1"; - position = "85 2"; - extent = "240 13"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiSliderProfile"; - visible = "1"; - active = "1"; - altCommand = "OptAudioUpdateChannelVolume(AudioEffect, $thisControl.value);"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptAudioVolumeSim"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiControl() { - position = "23 177"; - extent = "320 17"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiSliderCtrl() { - range = "0 1"; - ticks = "0"; - snap = "0"; - value = "1"; - position = "80 2"; - extent = "240 13"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiSliderProfile"; - visible = "1"; - active = "1"; - altCommand = "OptAudioUpdateChannelVolume(AudioMusic, $thisControl.value);"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptAudioVolumeMusic"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Music Volume"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "0 0"; - extent = "67 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiAutoSizeTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - }; - new GuiBitmapBorderCtrl() { - position = "9 55"; - extent = "358 210"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTabBorderProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "OptGraphicsPane"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiTextCtrl() { - text = "Display Driver:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "11 8"; - extent = "70 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Resolution:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "11 35"; - extent = "53 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiCheckBoxCtrl() { - text = "Fullscreen"; - groupNum = "-1"; - buttonType = "ToggleButton"; - useMouseEvents = "0"; - position = "11 62"; - extent = "85 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiCheckBoxProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptGraphicsFullscreenToggle"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl(OptGraphicsDriverMenu) { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - text = "ATI Radeon HD 5700 Series (D3D9)"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "88 8"; - extent = "258 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl() { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - text = "1024 x 768 (4:3)"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "67 35"; - extent = "127 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptGraphicsResolutionMenu"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Refresh:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "207 35"; - extent = "45 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl() { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - text = "60"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "252 35"; - extent = "49 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptRefreshSelectMenu"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Mesh Quality:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "21 91"; - extent = "62 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl() { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - text = "Low"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "90 91"; - extent = "78 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptMeshQualityPopup"; - class = "GraphicsQualityPopup"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl() { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - text = "Low"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "90 118"; - extent = "78 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptTextureQualityPopup"; - class = "GraphicsQualityPopup"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Texture Quality:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "11 118"; - extent = "77 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl() { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - text = "Low"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "90 143"; - extent = "78 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptLightingQualityPopup"; - class = "GraphicsQualityPopup"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Lighting Quality:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "11 143"; - extent = "73 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Effect Quality:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "191 91"; - extent = "73 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl() { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "263 91"; - extent = "78 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptEffectQualityPopup"; - class = "GraphicsQualityPopup"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Shader Quality:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "186 118"; - extent = "77 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl() { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - text = "Low"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "263 118"; - extent = "78 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptShaderQualityPopup"; - class = "GraphicsQualityPopup"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Particle Quality:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "186 156"; - extent = "73 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "0"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl() { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "263 156"; - extent = "78 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "0"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptParticleQualityPopup"; - class = "GraphicsQualityPopup"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Anisotropic Filtering:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "22 167"; - extent = "105 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl() { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - text = "Off"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "123 167"; - extent = "45 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptAnisotropicPopup"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiCheckBoxCtrl() { - text = "Vertical Sync"; - groupNum = "-1"; - buttonType = "ToggleButton"; - useMouseEvents = "0"; - position = "92 62"; - extent = "85 18"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiCheckBoxProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptGraphicsVSyncToggle"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl() { - text = "Auto Detect Quality"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "205 152"; - extent = "110 27"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiButtonProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._autoDetectQuality();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiPopUpMenuCtrl() { - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "263 62"; - extent = "78 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiPopUpMenuProfile"; - visible = "1"; - active = "1"; - command = "OptionsDlg._updateApplyState();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptAAQualityPopup"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Anti-aliasing"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "191 62"; - extent = "73 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiControl() { - position = "0 190"; - extent = "352 15"; - minExtent = "8 2"; - horizSizing = "width"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "GammaSliderContainer"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiSliderCtrl() { - range = "0.001 2.2"; - ticks = "0"; - snap = "0"; - value = "1"; - position = "76 -1"; - extent = "268 15"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiSliderProfile"; - visible = "1"; - active = "1"; - variable = "$pref::Video::Gamma"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Gamma:"; - maxLength = "255"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "22 -4"; - extent = "105 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - }; - new GuiControl() { - position = "9 55"; - extent = "357 208"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiWindowProfile"; - visible = "0"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "OptNetworkPane"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl() { - text = "Graphics"; - groupNum = "-1"; - buttonType = "RadioButton"; - useMouseEvents = "0"; - position = "9 33"; - extent = "117 23"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiButtonTabProfile"; - visible = "1"; - active = "1"; - command = "optionsDlg.setPane(Graphics);"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "OptGraphicsButton"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl() { - text = "Audio"; - groupNum = "-1"; - buttonType = "RadioButton"; - useMouseEvents = "0"; - position = "126 33"; - extent = "117 23"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiButtonTabProfile"; - visible = "1"; - active = "1"; - command = "optionsDlg.setPane(Audio);"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl() { - text = "Controls"; - groupNum = "-1"; - buttonType = "RadioButton"; - useMouseEvents = "0"; - position = "243 33"; - extent = "117 23"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiButtonTabProfile"; - visible = "1"; - active = "1"; - command = "optionsDlg.setPane(Controls);"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl() { - text = "Apply"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "241 271"; - extent = "60 23"; - minExtent = "8 8"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiButtonProfile"; - visible = "1"; - active = "0"; - command = "optionsDlg.applyGraphics();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "apply"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - new GuiControl(OptionsButtonHolder) { - position = "190 652"; - extent = "646 130"; - minExtent = "8 2"; - horizSizing = "center"; - vertSizing = "top"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; -}; -//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui b/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui index 9b76cb979..b7195557c 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui @@ -23,7 +23,7 @@ $guiContent = new GuiControl(OptionsMenu) { position = "48 56"; extent = "928 655"; minExtent = "8 2"; - horizSizing = "center"; + horizSizing = "aspectCenter"; vertSizing = "center"; profile = "GuiDefaultProfile"; visible = "1"; @@ -38,7 +38,27 @@ $guiContent = new GuiControl(OptionsMenu) { percent = "100"; vertical = "0"; flipClip = "0"; - bitmap = "data/ui/images/panel.png"; + BitmapAsset = "UI:panel_low_image"; + color = "255 255 255 255"; + position = "0 40"; + extent = "927 618"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapBarCtrl() { + percent = "100"; + vertical = "0"; + flipClip = "0"; + BitmapAsset = "UI:panel_image"; color = "255 255 255 255"; position = "0 0"; extent = "927 40"; @@ -77,179 +97,6 @@ $guiContent = new GuiControl(OptionsMenu) { canSave = "1"; canSaveDynamicFields = "0"; }; - new GuiBitmapBarCtrl() { - percent = "100"; - vertical = "0"; - flipClip = "0"; - bitmap = "data/ui/images/panel_low.png"; - color = "255 255 255 255"; - position = "0 40"; - extent = "927 618"; - minExtent = "8 2"; - horizSizing = "width"; - vertSizing = "bottom"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl() { - text = "Display"; - groupNum = "1"; - buttonType = "RadioButton"; - useMouseEvents = "0"; - position = "114 49"; - extent = "140 32"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "OptionsMenu.populateDisplaySettingsList();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "DisplayButton"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl() { - text = "Graphics"; - groupNum = "1"; - buttonType = "RadioButton"; - useMouseEvents = "0"; - position = "258 49"; - extent = "140 32"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "OptionsMenu.populateGraphicsSettingsList();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "GraphicsButton"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl() { - text = "Audio"; - groupNum = "1"; - buttonType = "RadioButton"; - useMouseEvents = "0"; - position = "402 49"; - extent = "140 32"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "OptionsMenu.populateAudioSettingsList();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "AudioButton"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl() { - text = "Keyboard + Mouse"; - groupNum = "1"; - buttonType = "RadioButton"; - useMouseEvents = "0"; - position = "547 49"; - extent = "140 32"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "OptionsMenu.populateKeyboardMouseSettingsList();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "KBMButton"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl() { - text = "Gamepad"; - groupNum = "1"; - buttonType = "RadioButton"; - useMouseEvents = "0"; - position = "691 49"; - extent = "140 32"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "OptionsMenu.populateGamepadSettingsList();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "gamepadButton"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiScrollCtrl() { - willFirstRespond = "1"; - hScrollBar = "alwaysOff"; - vScrollBar = "dynamic"; - lockHorizScroll = "1"; - lockVertScroll = "0"; - constantThumbHeight = "0"; - childMargin = "0 0"; - mouseWheelScrollSpeed = "-1"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "1 83"; - extent = "622 573"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuScrollProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiGameListMenuCtrl(OptionsMenuSettingsList) { - debugRender = "0"; - callbackOnInputs = "1"; - position = "1 1"; - extent = "621 510"; - minExtent = "8 2"; - horizSizing = "width"; - vertSizing = "bottom"; - profile = "DefaultListMenuProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - class = "UIMenuButtonList"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; new GuiTextCtrl(OptionName) { maxLength = "1024"; margin = "0 0 0 0"; @@ -258,10 +105,10 @@ $guiContent = new GuiControl(OptionsMenu) { anchorBottom = "0"; anchorLeft = "1"; anchorRight = "0"; - position = "635 94"; + position = "3 606"; extent = "293 17"; minExtent = "8 2"; - horizSizing = "right"; + horizSizing = "width"; vertSizing = "bottom"; profile = "MenuSubHeaderText"; visible = "1"; @@ -278,10 +125,10 @@ $guiContent = new GuiControl(OptionsMenu) { maxChars = "-1"; text = "This is a placeholder text for an option."; useURLMouseCursor = "0"; - position = "635 126"; + position = "3 625"; extent = "293 14"; minExtent = "8 2"; - horizSizing = "right"; + horizSizing = "width"; vertSizing = "bottom"; profile = "GuiMLTextProfile"; visible = "1"; @@ -292,24 +139,286 @@ $guiContent = new GuiControl(OptionsMenu) { canSave = "1"; canSaveDynamicFields = "0"; }; - }; - new GuiControl() { - position = "189 652"; - extent = "646 130"; - minExtent = "8 2"; - horizSizing = "center"; - vertSizing = "top"; - profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; + new GuiSplitContainer() { + orientation = "Vertical"; + splitterSize = "2"; + splitPoint = "250 100"; + fixedPanel = "FirstPanel"; + fixedSize = "250"; + docking = "None"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 48"; + extent = "928 555"; + minExtent = "64 64"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiMenuScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "248 555"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiOverlayProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "Panel1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl(OptionsMenuCategoryList) { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "10"; + dynamicSize = "0"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "0 0"; + extent = "248 555"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "MenuList"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl(OptionsMenuDisplayBtn) { + text = "Display"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 0"; + extent = "248 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "populateDisplaySettingsList();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(OptionsMenuGraphicsBtn) { + text = "Graphics"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 45"; + extent = "248 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "populateGraphicsSettingsList();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(OptionsMenuAudioBtn) { + text = "Audio"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 90"; + extent = "248 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "populateAudioSettingsList();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(OptionsMenuKBMBtn) { + text = "Keyboard & Mouse"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 135"; + extent = "248 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "populateKeyboardMouseSettingsList();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(OptionsMenuGamepadBtn) { + text = "Gamepad"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 180"; + extent = "248 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "populateGamepadSettingsList();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(OptionsMenuProfileBtn) { + text = "Profile"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 225"; + extent = "248 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "populateProfileSettingsList();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "252 0"; + extent = "676 555"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiOverlayProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "panel2"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "676 554"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiMenuScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl(OptionsMenuSettingsList) { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "5"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "0"; + changeChildPosition = "1"; + position = "1 1"; + extent = "661 30"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "MenuList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; }; new GuiControl(OptionsButtonHolder) { - position = "109 711"; + position = "116 711"; extent = "791 40"; minExtent = "8 2"; horizSizing = "center"; @@ -326,7 +435,7 @@ $guiContent = new GuiControl(OptionsMenu) { new GuiIconButtonCtrl() { buttonMargin = "4 4"; - iconBitmap = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_Enter"; + BitmapAsset = "UI:Keyboard_Black_Return_image"; iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; @@ -345,7 +454,7 @@ $guiContent = new GuiControl(OptionsMenu) { profile = "GuiMenuButtonProfile"; visible = "1"; active = "1"; - command = "ChooseLevelDlg.beginLevel();"; + command = "OptionsMenu.apply();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; @@ -356,7 +465,7 @@ $guiContent = new GuiControl(OptionsMenu) { }; new GuiIconButtonCtrl() { buttonMargin = "4 4"; - iconBitmap = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_Esc"; + BitmapAsset = "UI:Keyboard_Black_Escape_image"; iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; @@ -375,7 +484,7 @@ $guiContent = new GuiControl(OptionsMenu) { profile = "GuiMenuButtonProfile"; visible = "1"; active = "1"; - command = "ChooseLevelDlg.backOut();"; + command = "OptionsMenu.backOut();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; @@ -386,7 +495,7 @@ $guiContent = new GuiControl(OptionsMenu) { }; new GuiIconButtonCtrl() { buttonMargin = "4 4"; - iconBitmap = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_Enter"; + BitmapAsset = "UI:Switch_LB_image"; iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; @@ -403,19 +512,21 @@ $guiContent = new GuiControl(OptionsMenu) { horizSizing = "right"; vertSizing = "bottom"; profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; + visible = "0"; + active = "0"; + command = "OptionsMenu.prevTab();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; internalName = "prevTabButton"; class = "MenuInputButton"; + hidden = "1"; canSave = "1"; canSaveDynamicFields = "0"; }; new GuiIconButtonCtrl() { buttonMargin = "4 4"; - iconBitmap = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_Esc"; + BitmapAsset = "UI:Switch_RB_image"; iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; @@ -432,19 +543,21 @@ $guiContent = new GuiControl(OptionsMenu) { horizSizing = "right"; vertSizing = "bottom"; profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; + visible = "0"; + active = "0"; + command = "OptionsMenu.nextTab();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; internalName = "nextTabButton"; class = "MenuInputButton"; + hidden = "1"; canSave = "1"; canSaveDynamicFields = "0"; }; new GuiIconButtonCtrl() { buttonMargin = "4 4"; - iconBitmap = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_Esc"; + BitmapAsset = "UI:Keyboard_Black_R_image"; iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; @@ -463,6 +576,7 @@ $guiContent = new GuiControl(OptionsMenu) { profile = "GuiMenuButtonProfile"; visible = "1"; active = "1"; + command = "OptionsMenu.resetToDefaults();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; @@ -472,5 +586,26 @@ $guiContent = new GuiControl(OptionsMenu) { canSaveDynamicFields = "0"; }; }; + new GuiInputCtrl(OptionsMenuInputHandler) { + sendAxisEvents = "1"; + sendBreakEvents = "1"; + sendModifierEvents = "0"; + ignoreMouseEvents = "1"; + lockMouse = "0"; + position = "-50 0"; + extent = "10 10"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "GuiInputCtrlProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "MenuInputHandler"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; //--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript index 63488c8d7..eac532203 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript @@ -54,20 +54,22 @@ function OptionsMenu::onWake(%this) { MainMenuButtonList.hidden = true; - %this.pageTabIndex = 0; - %tab = %this.getTab(); - %tab.performClick(); + OptionsMenuCategoryList.setAsActiveMenuList(); OptionsButtonHolder.setActive(); + + OptionsMenuInputHandler.setFirstResponder(); } function OptionsButtonHolder::onWake(%this) { - %this-->prevTabButton.set("btn_l", "", "Prev Tab", "OptionsMenu.prevTab();", true); - %this-->nextTabButton.set("btn_r", "", "Next Tab", "OptionsMenu.nextTab();", true); + //%this-->prevTabButton.set("btn_l", "", "Prev Tab", "OptionsMenu.prevTab();", true); + %this-->nextTabButton.set("btn_a", "", "Select", "OptionsMenuList.activate();", true); %this-->resetButton.set("btn_back", "R", "Reset", "OptionsMenu.resetToDefaults();"); %this-->applyButton.set("btn_start", "Return", "Apply", "OptionsMenu.apply();"); %this-->backButton.set("btn_b", "Escape", "Back", "OptionsMenu.backOut();"); + + //OptionsMenuCategoryList.getObject(0).performClick(); } function OptionsMenu::apply(%this) @@ -78,7 +80,7 @@ function OptionsMenu::apply(%this) } else if(%this.pageTabIndex == 1) { - %this.applyGraphicsSettings(); + %this.applyGraphicsSettings(); } else if(%this.pageTabIndex == 2) { @@ -130,26 +132,24 @@ function OptionsMenuSettingsList::onChange(%this) if(%currentRowText $= "Display") { - OptionsMenuList.populateDisplaySettingsList(); + populateDisplaySettingsList(); } else if(%currentRowText $= "Graphics") { - OptionsMenuList.populateGraphicsSettingsList(); + populateGraphicsSettingsList(); } else if(%currentRowText $= "Audio") { - OptionsMenuList.populateAudioSettingsList(); + populateAudioSettingsList(); } else if(%currentRowText $= "Keyboard + Mouse") { - OptionsMenuList.populateKeyboardMouseSettingsList(); + populateKeyboardMouseSettingsList(); } else if(%currentRowText $= "Gamepad") { - OptionsMenuList.populateGamepadSettingsList(); + populateGamepadSettingsList(); } - - } function OptionsMenu::prevTab(%this) @@ -188,10 +188,9 @@ function OptionsMenu::getTab(%this) return %this-->DisplayButton; } -function OptionsMenu::populateDisplaySettingsList(%this) +function populateDisplaySettingsList() { - %this.pageTabIndex = 0; - OptionsMenuSettingsList.clearRows(); + OptionsMenuSettingsList.clear(); OptionName.setText(""); OptionDescription.setText(""); @@ -221,7 +220,7 @@ function OptionsMenu::populateDisplaySettingsList(%this) trim(%apiList); - OptionsMenuSettingsList.addOptionRow("Display API", %apiList, false, "", -1, -30, true, "The display API used for rendering.", %displayDevice); + OptionsMenuSettingsList.addOptionRow("Display API", %apiList, false, "", true, "The display API used for rendering.", %displayDevice); %numDevices = Canvas.getMonitorCount(); %devicesList = ""; @@ -235,7 +234,7 @@ function OptionsMenu::populateDisplaySettingsList(%this) } %selectedDevice = getField(%devicesList, $pref::Video::deviceId); - OptionsMenuSettingsList.addOptionRow("Display Device", %devicesList, false, "onDisplayModeChange", -1, -30, true, "The display devices the window should be on.", %selectedDevice); + OptionsMenuSettingsList.addOptionRow("Display Device", %devicesList, false, "onDisplayModeChange", true, "The display devices the window should be on.", %selectedDevice); if (%numDevices > 1) OptionsMenuSettingsList.setRowEnabled(1, true); @@ -243,10 +242,10 @@ function OptionsMenu::populateDisplaySettingsList(%this) OptionsMenuSettingsList.setRowEnabled(1, false); %mode = getField($Video::ModeTags, $pref::Video::deviceMode); - OptionsMenuSettingsList.addOptionRow("Window Mode", $Video::ModeTags, false, "onDisplayModeChange", -1, -30, true, "", %mode); + OptionsMenuSettingsList.addOptionRow("Window Mode", $Video::ModeTags, false, "onDisplayModeChange", true, "", %mode); %resolutionList = getScreenResolutionList($pref::Video::deviceId, $pref::Video::deviceMode); - OptionsMenuSettingsList.addOptionRow("Resolution", %resolutionList, false, "onDisplayResChange", -1, -30, true, "Resolution of the game window", _makePrettyResString( $pref::Video::mode )); + OptionsMenuSettingsList.addOptionRow("Resolution", %resolutionList, false, "onDisplayResChange", true, "Resolution of the game window", _makePrettyResString( $pref::Video::mode )); //If they're doing borderless, the window resolution must match the display resolution if(%mode !$= "Borderless") @@ -254,19 +253,17 @@ function OptionsMenu::populateDisplaySettingsList(%this) else OptionsMenuSettingsList.setRowEnabled(3, false); - OptionsMenuSettingsList.addOptionRow("VSync", "No\tYes", false, "", -1, -30, true, "", convertBoolToYesNo(!$pref::Video::disableVerticalSync)); + OptionsMenuSettingsList.addOptionRow("VSync", "No\tYes", false, "", true, "", convertBoolToYesNo(!$pref::Video::disableVerticalSync)); %refreshList = getScreenRefreshList($pref::Video::mode); - OptionsMenuSettingsList.addOptionRow("Refresh Rate", %refreshList, false, "", -1, -30, true, "", $pref::Video::RefreshRate); + OptionsMenuSettingsList.addOptionRow("Refresh Rate", %refreshList, false, "", true, "", $pref::Video::RefreshRate); //move to gameplay tab - OptionsMenuSettingsList.addSliderRow("Field of View", 75, 5, "65 100", "", -1, -30); + OptionsMenuSettingsList.addSliderRow("Field of View", 75, 5, "65 100", ""); - OptionsMenuSettingsList.addSliderRow("Brightness", 0.5, 0.1, "0 1", "", -1, -30); - OptionsMenuSettingsList.addSliderRow("Contrast", 0.5, 0.1, "0 1", "", -1, -30); - - OptionsMenuSettingsList.refresh(); + OptionsMenuSettingsList.addSliderRow("Brightness", 0.5, 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("Contrast", 0.5, 0.1, "0 1", ""); } function OptionsMenu::applyDisplaySettings(%this) @@ -290,10 +287,9 @@ function OptionsMenu::applyDisplaySettings(%this) export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false); } -function OptionsMenu::populateGraphicsSettingsList(%this) +function populateGraphicsSettingsList(%this) { - %this.pageTabIndex = 1; - OptionsMenuSettingsList.clearRows(); + OptionsMenuSettingsList.clear(); OptionName.setText(""); OptionDescription.setText(""); @@ -303,26 +299,24 @@ function OptionsMenu::populateGraphicsSettingsList(%this) %highMedLow = "Low\tMedium\tHigh"; %anisoFilter = "Off\t4\t8\t16"; %aaFilter = "Off\t1\t2\t4"; - OptionsMenuSettingsList.addOptionRow("Lighting Quality", getQualityLevels(LightingQualityList), false, "", -1, -30, true, "Amount and drawdistance of local lights", getCurrentQualityLevel(LightingQualityList)); - OptionsMenuSettingsList.addOptionRow("Shadow Quality", getQualityLevels(ShadowQualityList), false, "", -1, -30, true, "Shadow revolution quality", getCurrentQualityLevel(ShadowQualityList)); - OptionsMenuSettingsList.addOptionRow("Soft Shadow Quality", getQualityLevels(SoftShadowList), false, "", -1, -30, true, "Amount of softening applied to shadowmaps", getCurrentQualityLevel(SoftShadowList)); - OptionsMenuSettingsList.addOptionRow("Mesh Quality", getQualityLevels(MeshQualityGroup), false, "", -1, -30, true, "Fidelity of rendering of mesh objects", getCurrentQualityLevel(MeshQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Object Draw Distance", getQualityLevels(MeshDrawDistQualityGroup), false, "", -1, -30, true, "Dictates if and when static objects fade out in the distance", getCurrentQualityLevel(MeshDrawDistQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Texture Quality", getQualityLevels(TextureQualityGroup), false, "", -1, -30, true, "Fidelity of textures", getCurrentQualityLevel(TextureQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Terrain Quality", getQualityLevels(TerrainQualityGroup), false, "", -1, -30, true, "Quality level of terrain objects", getCurrentQualityLevel(TerrainQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Decal Lifetime", getQualityLevels(DecalLifetimeGroup), false, "", -1, -30, true, "How long decals are rendered", getCurrentQualityLevel(DecalLifetimeGroup)); - OptionsMenuSettingsList.addOptionRow("Ground Cover Density", getQualityLevels(GroundCoverDensityGroup), false, "", -1, -30, true, "Density of ground cover items, such as grass", getCurrentQualityLevel(GroundCoverDensityGroup)); - OptionsMenuSettingsList.addOptionRow("Shader Quality", getQualityLevels(ShaderQualityGroup), false, "", -1, -30, true, "Dictates the overall shader quality level, adjusting what features are enabled.", getCurrentQualityLevel(ShaderQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Anisotropic Filtering", %anisoFilter, false, "", -1, -30, true, "Amount of Anisotropic Filtering on textures, which dictates their sharpness at a distance", $pref::Video::defaultAnisotropy); - OptionsMenuSettingsList.addOptionRow("Anti-Aliasing", %aaFilter, false, "", -1, -30, true, "Amount of Post-Processing Anti-Aliasing applied to rendering", $pref::Video::AA); - OptionsMenuSettingsList.addOptionRow("Parallax", %onOffList, false, "", -1, -30, true, "Whether the surface parallax shader effect is enabled", convertBoolToOnOff(!$pref::Video::disableParallaxMapping)); - OptionsMenuSettingsList.addOptionRow("Water Reflections", %onOffList, false, "", -1, -30, true, "Whether water reflections are enabled", convertBoolToOnOff(!$pref::Water::disableTrueReflections)); - OptionsMenuSettingsList.addOptionRow("SSAO", %onOffList, false, "", -1, -30, true, "Whether Screen-Space Ambient Occlusion is enabled", convertBoolToOnOff($pref::PostFX::EnableSSAO)); - OptionsMenuSettingsList.addOptionRow("Depth of Field", %onOffList, false, "", -1, -30, true, "Whether the Depth of Field effect is enabled", convertBoolToOnOff($pref::PostFX::EnableDOF)); - OptionsMenuSettingsList.addOptionRow("Vignette", %onOffList, false, "", -1, -30, true, "Whether the vignette effect is enabled", convertBoolToOnOff($pref::PostFX::EnableVignette)); - OptionsMenuSettingsList.addOptionRow("Light Rays", %onOffList, false, "", -1, -30, true, "Whether the light rays effect is enabled", convertBoolToOnOff($pref::PostFX::EnableLightRays)); - - OptionsMenuSettingsList.refresh(); + OptionsMenuSettingsList.addOptionRow("Lighting Quality", getQualityLevels(LightingQualityList), false, "", true, "Amount and drawdistance of local lights", getCurrentQualityLevel(LightingQualityList)); + OptionsMenuSettingsList.addOptionRow("Shadow Quality", getQualityLevels(ShadowQualityList), false, "", true, "Shadow revolution quality", getCurrentQualityLevel(ShadowQualityList)); + OptionsMenuSettingsList.addOptionRow("Soft Shadow Quality", getQualityLevels(SoftShadowList), false, "", true, "Amount of softening applied to shadowmaps", getCurrentQualityLevel(SoftShadowList)); + OptionsMenuSettingsList.addOptionRow("Mesh Quality", getQualityLevels(MeshQualityGroup), false, "", true, "Fidelity of rendering of mesh objects", getCurrentQualityLevel(MeshQualityGroup)); + OptionsMenuSettingsList.addOptionRow("Object Draw Distance", getQualityLevels(MeshDrawDistQualityGroup), false, "", true, "Dictates if and when static objects fade out in the distance", getCurrentQualityLevel(MeshDrawDistQualityGroup)); + OptionsMenuSettingsList.addOptionRow("Texture Quality", getQualityLevels(TextureQualityGroup), false, "", true, "Fidelity of textures", getCurrentQualityLevel(TextureQualityGroup)); + OptionsMenuSettingsList.addOptionRow("Terrain Quality", getQualityLevels(TerrainQualityGroup), false, "", true, "Quality level of terrain objects", getCurrentQualityLevel(TerrainQualityGroup)); + OptionsMenuSettingsList.addOptionRow("Decal Lifetime", getQualityLevels(DecalLifetimeGroup), false, "", true, "How long decals are rendered", getCurrentQualityLevel(DecalLifetimeGroup)); + OptionsMenuSettingsList.addOptionRow("Ground Cover Density", getQualityLevels(GroundCoverDensityGroup), false, "", true, "Density of ground cover items, such as grass", getCurrentQualityLevel(GroundCoverDensityGroup)); + OptionsMenuSettingsList.addOptionRow("Shader Quality", getQualityLevels(ShaderQualityGroup), false, "", true, "Dictates the overall shader quality level, adjusting what features are enabled.", getCurrentQualityLevel(ShaderQualityGroup)); + OptionsMenuSettingsList.addOptionRow("Anisotropic Filtering", %anisoFilter, false, "", true, "Amount of Anisotropic Filtering on textures, which dictates their sharpness at a distance", $pref::Video::defaultAnisotropy); + OptionsMenuSettingsList.addOptionRow("Anti-Aliasing", %aaFilter, false, "", true, "Amount of Post-Processing Anti-Aliasing applied to rendering", $pref::Video::AA); + OptionsMenuSettingsList.addOptionRow("Parallax", %onOffList, false, "", true, "Whether the surface parallax shader effect is enabled", convertBoolToOnOff(!$pref::Video::disableParallaxMapping)); + OptionsMenuSettingsList.addOptionRow("Water Reflections", %onOffList, false, "", true, "Whether water reflections are enabled", convertBoolToOnOff(!$pref::Water::disableTrueReflections)); + OptionsMenuSettingsList.addOptionRow("SSAO", %onOffList, false, "", true, "Whether Screen-Space Ambient Occlusion is enabled", convertBoolToOnOff($pref::PostFX::EnableSSAO)); + OptionsMenuSettingsList.addOptionRow("Depth of Field", %onOffList, false, "", true, "Whether the Depth of Field effect is enabled", convertBoolToOnOff($pref::PostFX::EnableDOF)); + OptionsMenuSettingsList.addOptionRow("Vignette", %onOffList, false, "", true, "Whether the vignette effect is enabled", convertBoolToOnOff($pref::PostFX::EnableVignette)); + OptionsMenuSettingsList.addOptionRow("Light Rays", %onOffList, false, "", true, "Whether the light rays effect is enabled", convertBoolToOnOff($pref::PostFX::EnableLightRays)); } function OptionsMenu::applyGraphicsSettings(%this) @@ -439,10 +433,9 @@ function updateDisplaySettings() } } -function OptionsMenu::populateAudioSettingsList(%this) +function populateAudioSettingsList(%this) { - %this.pageTabIndex = 2; - OptionsMenuSettingsList.clearRows(); + OptionsMenuSettingsList.clear(); OptionName.setText(""); OptionDescription.setText(""); @@ -477,18 +470,15 @@ function OptionsMenu::populateAudioSettingsList(%this) else %audioDeviceList = %audioDeviceList @ "\t" @ %device; } - } - OptionsMenuSettingsList.addOptionRow("Audio Provider", %audioProviderList, false, "audioProviderChanged", -1, -15, true, "", $currentAudioProvider); - OptionsMenuSettingsList.addOptionRow("Audio Device", %audioDeviceList, false, "", -1, -15, true, $pref::SFX::device); + OptionsMenuSettingsList.addOptionRow("Audio Provider", %audioProviderList, false, "audioProviderChanged", true, "", $currentAudioProvider); + OptionsMenuSettingsList.addOptionRow("Audio Device", %audioDeviceList, false, "", true, $pref::SFX::device); - OptionsMenuSettingsList.addSliderRow("Master Volume", $pref::SFX::masterVolume, 0.1, "0 1", "", -1, -30); - OptionsMenuSettingsList.addSliderRow("GUI Volume", $pref::SFX::channelVolume[ $GuiAudioType], 0.1, "0 1", "", -1, -30); - OptionsMenuSettingsList.addSliderRow("Effects Volume", $pref::SFX::channelVolume[ $SimAudioType ], 0.1, "0 1", "", -1, -30); - OptionsMenuSettingsList.addSliderRow("Music Volume", $pref::SFX::channelVolume[ $MusicAudioType ], 0.1, "0 1", "", -1, -30); - - OptionsMenuSettingsList.refresh(); + OptionsMenuSettingsList.addSliderRow("Master Volume", $pref::SFX::masterVolume, 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("GUI Volume", $pref::SFX::channelVolume[ $GuiAudioType], 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("Effects Volume", $pref::SFX::channelVolume[ $SimAudioType ], 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("Music Volume", $pref::SFX::channelVolume[ $MusicAudioType ], 0.1, "0 1", ""); } function audioProviderChanged() @@ -498,7 +488,7 @@ function audioProviderChanged() $currentAudioProvider = %provider; //And now refresh the list to get the correct devices - OptionsMenu.populateAudioSettingsList(); + populateAudioSettingsList(); } function OptionsMenu::applyAudioSettings(%this) @@ -531,10 +521,9 @@ function OptionsMenu::applyAudioSettings(%this) } } -function OptionsMenu::populateKeyboardMouseSettingsList(%this) +function populateKeyboardMouseSettingsList(%this) { - %this.pageTabIndex = 3; - OptionsMenuSettingsList.clearRows(); + OptionsMenuSettingsList.clear(); OptionName.setText(""); OptionDescription.setText(""); @@ -542,13 +531,12 @@ function OptionsMenu::populateKeyboardMouseSettingsList(%this) $remapListDevice = "keyboard"; fillRemapList(); - OptionsMenuSettingsList.refresh(); + //OptionsMenuSettingsList.refresh(); } -function OptionsMenu::populateGamepadSettingsList(%this) +function populateGamepadSettingsList(%this) { - %this.pageTabIndex = 4; - OptionsMenuSettingsList.clearRows(); + OptionsMenuSettingsList.clear(); OptionName.setText(""); OptionDescription.setText(""); @@ -586,6 +574,69 @@ function OptionsMenu::backOut(%this) } } +function OptionsMenuSettingsList::setRowEnabled(%this, %row, %status) +{ + %option = %this.getObject(%row); + if(isObject(%option)) + { + %option.setEnabled(%status); + } +} + +function OptionsMenuSettingsList::addOptionRow(%this, %label, %optionsList, %wrapOptions, %callback, %enabled, %description, %defaultValue) +{ + if(%enabled $= "") + %enabled = true; + + %optionsRowSize = 30; + %optionColumnWidth = %this.extent.x - 450;//todo, calculate off longest option text? + + %option = new GuiGameSettingsCtrl() { + class = "MenuOptionsButton"; + profile = "GuiMenuButtonProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "0 0"; + extent = %this.extent.x SPC %optionsRowSize; + columnSplit = %optionColumnWidth; + useMouseEvents = true; + }; + + %option.setListSetting(%label, %optionsList, %wrapOptions, %callback, %enabled, %description, %defaultValue); + + %this.add(%option); +} + +function OptionsMenuSettingsList::addSliderRow(%this, %label, %defaultValue, %increment, %range, %callback, %enabled, %description) +{ + if(%enabled $= "") + %enabled = true; + + %optionsRowSize = 30; + %optionColumnWidth = %this.extent.x - 450;//todo, calculate off longest option text? + + %option = new GuiGameSettingsCtrl() { + class = "MenuOptionsButton"; + profile = "GuiMenuButtonProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "0 0"; + extent = %this.extent.x SPC %optionsRowSize; + columnSplit = %optionColumnWidth; + useMouseEvents = true; + }; + + %option.setSliderSetting(%label, %defaultValue, %increment, %range, %callback, %enabled, %description); + + %this.add(%option); +} + +// +function OptionsMenuCategoryList::onNavigate(%this, %index) +{ + %this.getObject(%index).performClick(); +} + function convertOptionToBool(%val) { if(%val $= "yes" || %val $= "on") @@ -685,4 +736,16 @@ function onDisplayResChange(%val) OptionsMenuSettingsList.setOptions(5, %refreshList); OptionsMenuSettingsList.selectOption(5, %newRate); +} + +function MenuOptionsButton::onMouseEnter(%this) +{ + OptionName.setText(%this.getLabel()); + OptionDescription.setText(%this.getToolTip()); +} + +function MenuOptionsButton::onMouseLeave(%this) +{ + OptionName.setText(""); + OptionDescription.setText(""); } \ No newline at end of file diff --git a/Templates/BaseGame/game/data/UI/images/scrollBar.png b/Templates/BaseGame/game/data/UI/images/scrollBar.png index 2699a7662781253fe3ba6bfd00468ba7a97e7ea3..4bd81576ba4217a429431e7806bf690f418ed775 100644 GIT binary patch literal 9187 zcmeHrXIN8Pw=O76I#NVXh*SX+l2AgBB1NQwbd+K$1PBR9D1y==Akq|6dXXv$3J6jZ z5RoE9svu23L=dD2(o{SF{r2`dci->a{XF;l+w*x=)|zv^;~itYYmB+FW~90484gw< zRysO54g-B%3))$hc4V_K(SBh7=S4a?9tnRdJBkIu7eFKtus9D4fO3(D0bu-aSUNht z;o@W*>1Zj(l^?5o@O>~MoU2iasQ)-aks!eBN`Y;T?hID=YMytVVxdE@)cY~qyXi;bApJ1^Y*cTRj&4yde?2>mSWz*G(3|&y<9K(!nF1Fc+-rZ-w&VfF|Iew+Asc?4_LWe_G8EQfduNn zhEY#by7uP{mrEHpKLzPG#;z(zo`mE+Uy4`NMBN)-omotuTH@WDs&xK5GZUcp-8dou z`ZdEm@MT|sTI_zapu$!x$(tpw5+ zF=0z>L6aN)^(V(Wxikxhk%eox3m`zrbCART3@z$s=Hg& zj9z3HVm3^hCB{OABSyQFblYLJlIco#f`q;9H7i^%=B5?thJ_)p*)k_T<$k|~JHBGD z$D-Zj9Im2bU}Uyb+SS-WzIJ^eK$IF0t5!8Q@vVVACPneSYtKECC$R@EVKboZMUOf) zTCT|fk3TCen{&JWu(XlM@FZafGdSimJ{4S%V5&iCD=bJ4Y>vAZR*A2-S{Q8mK0~{7 zTM=k`bzk#-^W-^APo8Mg7jAk@NKUJ#=NRcIjoEK*5{{s@imNPAc+DnI{Uj6 z=IzJj^W#cy=Jzcwz&DSS?LXIRJc`XY`W<=kA=Cl++|+#(gv1Y)~t&uwsK4?>nJ(*%3Z7KiN5jE z9$!*Ue^QOSc(|JOg20Y_+KJ-MbI3z&RT3N7h$Z3GR;Ah7Gd(zsYVVrbTsN=ITN%L- zn(krhZ6*Un9NvzQqW#mkb*)6_;z1u-nbBftKP9-Ve_wM9)!0+R`ry*nM@G2IO;RUg zsy-D~U$G%1$;FfkAl3m!p1Koim%IANtzS2?j%H`H@J28PCAY5Ie0`0^17` zvkD5!>ZXMU=|UfKFvMIEt>3twUJU}J*Gg+La zjz^g2Y^NMgEL8D?8ra@*$ZcpJKHDe+=pEgDF<8XpJvh~h&aT#%TWv2TJyPt$atq(X z@^T7XU~><5tg*ePp*CsxDj@*N6?bV1>A_-=}V1iHC ze{I3iP5b;&)=RUGCJrShXh2HII-0z``5&5>o%jv!OLz@xwk(ys7S!$cR$Rbcf6+i- zNWAi9wMX*0$JHgr5MR|hT@~Vj1~*+lFXoq+HZV!N?v_f)uVghy9g3L1#D{iu+&_$D zo$S8pGWBGBf7ek1PQxdtvnuK~_pC@GhdDZmx1N;EcG{3KOQIX_#4&w-xe6xw^@GK8rf&NnNX(^cR1F4Hn>boD*E`xOO9h@1ApZcf?r754F1)X8=Z4qbw=1=W#Yr zUM?}VbpCg4t}PuXfh-Fc)ZIgr)8)e%!BIh|-` z*phhvY8!B^5+i!zqqkXL&vux`aaSH=+jIt2*2)icT%Cgk(9VYA{pf5)mbL>f#s?9MEn^~`9fQ>o~;Y&vEW8F^<_@Wfsc%%EJ1@FAf z(4f|qRH;;Kf6K~U=jqah}J1cT&GwODP4D&^|9qV=hG;ZqWv|e4wjuN~L zRW<1od2;|ZE`QE-A^WyY>zvJ%9{q;mz@^aMNW zrNM6bqg5^4Ns6rTS3FWK7Kc@5yGM92Pj>6NC^N)Vchc+KPJ2j3_KJZzw)w86HO!oP zbhEA?hNN|c$Ya^$xZKQQ$$5ey{FYF)^t{aJiRWw7pk|d*o5D`w*|FgTlkMd9NfF3P zSJkq@RG(+i+rC0Sa_CkQnA^__otZ>J=ROM8=_Fgn2^{8{Nj%NwC_!kS|G0ybHohzo zm=+{#bT9}Ri(h=!ko$e?T(AYWV#>Tei&3xlf*!F$k1HJbfFBXsoViv+FS67eFBqP_ zW5h?t%jHv$(CEjequlJ2)ox5AKK46W)~2HV(oLwRQ8v5x-I!MOK1mA+d^^V5EM;BoX6*x`T- zL1+J=?Nzok@m+`O-lv0QYVKHP4*mm%05u*OmPNrF5r%* z3yMzo+#BquT-)5UdG46Bx2^@xoja|9GqXO1D2fxLrYcUxM)f^s5IehQanRPGd z5lcg>`kUveOi^PiX|3TB%|d>qb8_4rDOGB@xAaU`l3XV4eFGbxCE2|dRhox*8Qu!cW` zj>HIvYl|!9u%>*^eRn*3rM8;agq@6gn0nz&lL*s{mHR#0^4Q6RFN{r6@uJ>D(Y#<2 zWXtA5NaY((hz)P|$ZTf*g{7d#(B3@OypNL0>SM)Rdde3tgcV~MgV)wWBe^A#A+_M+ z;d5y9Ff+N#+f#O2I)OJ4i!Af+3czX9DmQ@=orG`L0GTdorc`d~RMqeU?e))Xnm}B0E#tj2px^k)lzoCnOozaaW&>KSc>2ntc z5+uEEmqSJc?K*PVt8OMQt=u46=_v>?CbXW^e%7Ia#IkjVp28Z}jMuQ;(2^=S{6VXsr=S=+bm_^9etw2(J@CdAz}f zA_>Au#bkU_RXxGyu<7PC@6OWO;$)i7S|B$2_#`s3p)*Q4TJg?>jZVA%=Px3U-0J)m zolyEcdK-IA;zoNm`;9FAMsCOp%R7M|tb4D<6}h*fJZd@pb5xx0yk8n(7A$oQGitV( zQnf8QGoYP(eN~b6JT-+`x3oT~t_^v(7s2xsh^TpRHp#Co?)#C{ z>Z~h-YT}iTIxIPo9*0q%w$g&fjBV*SRJp)f$(!z|-9XNW0 zckPrT(+?Fb2$P(Sc&qCSTU2Hz{m}YsI!LQWPQ2O7QY5hKD4T#VaX4mQN;@0;@jE+S zF^>}4Z*u#4(i;~-Hhn#0kGy)sBoJz&Ddz!o1kA-h@Ln^S4C5vg+a| z!q!}=Jsg+i#plMRju5t6`wJMfWl$p}A(EjrULHj}>utC9hdrg@so)?{;m=;hc5V}E z9)WC!4i1~`+w9-rypzwCG#6K2!^0gJ@)T0)aNrG*lD;ly+N+b|xL`>a%>dqK(%(Ac zl&>)RV)3=cEXdYAu{61^=yKT?vAib2%7kz1>>oOByZNIa2vzstur$)bhpK|r#nw3IJYDE#g&*A80 ztA0hk)~a~c6y$?Dx?$Y)lFFT_VjU3+ZyOAFG>+>B>wbN6KoFr8KnWTta%N;zMyRlq z#09K7;UBSifA}zcxK*%)_&BWe&5|-+u2ormxa{&6#811W`I27JR|ZJxdnHM~XtgAX z$?K=0!17N+*ez|5OC5=YZg&7x?et+BE}1gZJeTa{4h4YJ93P%7brfzsF7m`9k#Pje z>&Lx6yO=qnwz5e;YZ7#tg>ghQGWc9WDBo)du5wH5PmI)I$2k$ki_XSM8Yd9%9eXqY z!wLDk`5q&BDbW*Wlb1xdB(qd{XEZ$$Iv&45`akZZJ7JJ^+f0}@NqMX(kRzl})CI5_ z#r1h6m1{eJgA_DR-9b}F$G5XIhX5|Zk?SGUudwN&)({Uf)h~2(^kFz19diR6oqz3@ z&~{1EF5ghsZ#;FR$@zSq#knKHTDlTC-enVq-W|6-5gOKO=O8eKS#9t*FSLOB`>VH;fW=HhZ*LaMcYAI%h(IKr=obstZt2iuw3LLCa=R~T+z*Ja%&(SKHpUkX`%FIP~%FL1O;)Ag(6`}kICdhwQh zZsvgDz-7(NvEs97DU|q7udI!xG7UYtAE0hGyMc{TOob`kxB@ZH=Uaso_^W|`PR{AL z;2r$LyP6z>fM?U3;N{%N8doEYl($G8Kg}FM+y2S(fRYbu18-YC?!TV*;5H$cs&k=S zcW558v^c-GFs`t$6G-<≠-#^Uf3<9hWtZwt;15VyucH;6Vs90f_3j zO+O+6<&L2MkQf)7r@GkElX@`#4y`U`t7HN;A?jdUar*uwjHSP+70TZo1xJf%YOt#L zsnQ7W7zzU5hxhO#tNN*n?eVJ8u6Kv!#Q=K{io3d)oryU>hd{yr6hVq0Fz~b=&Ic-{ z!3t0#p|PqKx_ZATXgzf?R|kIN#01-$o@(?&2E)RyvL!m$#0!Y5-NkRAl zJ;~y`6hAq1F=P}8N2K5go`79W1d`xQQ5O@V%>#as(`Hep{b+-~9PIY@=*bkcyaBDF zNV^{zKpqMPs{p}JAQUeDyFG2z#N-caPx3DnX?n{0A&Bx25Lh0M|2GRV<+RVA{{GT} zY(?8gl()c;3Em_W=ClvSlOq1RQ=*4A`FEe*WX$f+UfdpNtUN8KJS9pP&-nI6%smhkEP;fl)eFuOP4FfE3AV!FF_sj>u51ux1tnz#2t*mC09OR7!2bl< zU`S+I-tMwOz#s^8Zw8H0)uVADX!(P~BU~`@L{FE!30l;uIwTB&LLgZY2p;NUyDOqQ+$U(f$Ho7v2^a8v&cr}i^3^=Y;Q(#7BWTVlL^_I|D< z9=JWJ0D!&vRYjn7Ra6%vBYZGFQ;MeJ&nc8E!qWvqTPS~3$-l;Nf0?i_Bn*i~1C^l| zC{Pg#0R!PM7zPN3!j!;ZMU;vX_`k7}30R6Rf`rj>p_LKsIn#=0?>PgG|H?C&y@dE9 z8edn;ZW4iMsY@eQ09!$nRh8hXP?*@yrwve(-(4F2b+>A}i-(Dc>hF4}?Jh2=2D=Go z=}jbh;4q|r*Xdt*^MAqpX8$Wk|0na`VLz>P2*iuDYIUWU`Fj3G_kRKW$zY5_VLZu% z{}lS~ke{;r_6DKF{Bw-;IcvtbcwhV?1g9`+R9%!lx1n0kp4ZCZy3BUAiB;AJhuc zmsV+~14Mm$G94Y~i`|3%mK>)rZIGE_U~-yynpK4Vr0^(@b02N5#MD4n%gS$fVG!XN z3KnFV=p`mDIziPF`lv5)qnSX6{XTrD%VLL)&t@`Sg4?Q>Sc5=ehR(y#LxVf^i$>>XkgrVK#b@B9%+1X?g5(tQtk`Qi$zLXvm$iPj3h9NH*nNzMbhl23D-6vsi+En*} I_Jz>@0&<~QH2?qr delta 6623 zcmV<586f84NAoj~BYzbAdQ@0+Qek%>aB^>EX>4U6ba`-PAZ2)IW&i+q+O3*dawD;o zMgOr1F9Gwg9E=gYgI>PR1z0LoS$2dwTB;H$GMV}ChC3i-_W%CRG5_Ez*;Y+VrRJ8i zeCJ8E@9RA}8}HBib>Dxl{_(o${_}?CrNCo&zvlfpzJK$2`u%|tKd+BJUpHlb z&Qm`p`n>V$gh5x<#nvat&xwM6ue;ChrhOvn`P*_n|HtRU_saHPe~*P^ti<_(H+}~f z?EUHAmBRbq`Cs_ygXcgZ<9P^)pE3N9KXcFQe@@`nv%m6Z=jZkCJ00d__H#h~D^H)- zUHUnHH%s3ma)18o%Km#q%R6tse|^i}Ijf$t-|BkIhIHl6qJAyqKI6c_qQm`I=DYAe z@x0vc#&@;dPO7$8>M(ZjOLLx#9~a$n-5s~@<8+e{qu;*p=>7EJzE(r=&CgqasBd?C zF`<>|-HvyPk=*az3b)R|Cc~l8zIkzF zeNI3yTsskr3sk^n7m~})7VnF5yv*k z11}UJg@4T0R0`B7R*WfT=B?5~-K3CWN-3w3YHF$HkYi3c=aPj}y@V1=D!G(WODnyG z8f&V#mRf78z4;b^v1D3qrPbD2?_9LU&bd0rcU~BNgb_y?d6ZE{8-3C~GtM;gEVIrw z`|>L+Ai%7=%BriazTKvkcHC*_U3T4V_d~CpaDU=SC!ccaX{Ucx&3(r9kE;D$x&K@> z_o<%;9rsnc-S&#!3sUs=JH6}yJ5)F&c|<8huxb}r?G0z zW4Kku46T>lIe%}?)ooj+$_yN*g$d7gVXxUX%Qq*dc!;T`vSvwVmE+1`IXRtEUC?_W z)J3j(D2e>%Qg;C94p=v4VFGPA+0iA4WSXsOfs*8e^?A&gT6-V-CZ`-j>h3Q@eUfIdf5f(01rVL3$@` z3qnFGJ?B13@H37)mk^T6w+zhp-OEg?dzLoi;f!PS9(FmjP;iy*J<07ej|pkkJb%L3 zy-(s8G?Oo}yHd~K><7Hhq=T!KxOsub?Xe6F%``(xmb5OnoAKokV>pxUJOl3GkkXZx z&y#i=L#m`7fRS)0wX+!Hb*G~HgQmTu;5y58bMmG|6i=#z3&v2$nLi)d3i#mz-0 zhB|MJ&+vMjJR>fmHOZmb<{oSEp??j^bUzYjXKI;(G2zK-Cv$rITu~WK?-VEA`j$Oc z$lICD^~PyEjKs?5uW(8RVd%~6qE?bRI)|3u=ZwSJwo50bOyU`=rIXosrpb&C@v-br zsO9xhW^x&W)K_nGf6jiMCQwoyAn8R4R68BLj?IQi&2#uTfQt~u2mv4{9Dk(alVEAi zHZ}(^SEXlC(bRG&&~b^yFkj4gF(8^RmEor5gjOb%np!JmWejw^zpmZGN_lmlE3YPE zi!;|~+yvlBZjSY!T5fB*H4(cs_UzN97&;55#e-Ah@j+Vzr0tWL6Us|LQ?p z(2XZ9CaU!@QrvrNDp)-j95&b9;Knewe1S{Oin>x)QQgo_0Z2kE%v;Wa&ao>1W&tl4 zWHSbKcz?<)!=1hgOnb+n0=#*7;!2g2tS~qHfncU-;x0^2bBxR?gnvOIKx&CHiX9n+ z&AdB9M*#R|*xbg=#LBm$#_5?T#$rV0+06TnWruQ-?_=%T)z!`W$WX02w9(bup~5bJ z$U_(?L7K;HI`#wxUwl5i z_$bWuom0ESOl=htYJa2)gDuHHN6f)2s;N4TWzV^g4(Y&remABH!kBO>-0b0r9^J0t zh*?Iek7>U)r5MBVkE)U=hzvxNNuz-&{^^Kmj9a^CqIQs@FW-05yB70JJ zI%>KV=`y&R>W~Q_8E|$-J|03@zE1 z83bW;A#BEy!GBbPi0ZHA%yUFvN}t#TeSv42%#$w~YMqo&{*o{>U%BE2qCiqm&6OZW z+(?84;5V2JJw);t3d-(QW6o9euaZ;#ud0_-f>YTMj#+J4G_;*)a(%dZ+Z9PfEXXOw zw-;p8C4Vqv4I?;re2j5%89aHd*ifTUR}D`3LQ7kgR`z`{@42)L%z(w>j!6?m5-xzQ*zAJAZdO#8rytVlZs$QwG!Ucu@mSnb7lLz?%_ zv<3`N)$-$9PMeRGZ!ao;2(;gkVm*fCbV`h9;DSx+cCRfCkT{M9eTBkE*seDZMFeq1l^j@Y_}iwu zvyGNBuTqDl3v$z=I30tH^37H#THNy33x7r*^t@9aUzgmT10t_BG2g^Vz&^bY`Wfw8 z2t^^>F-AcmXNlq}XURyk5gg=~iC0ZX>YpyfqJ02d-X984rt6K+pO4WQU;tqChajDHPd zg+dHu+{c1pDf@1&RGitRE2&^sq66f?DpCE%k@DIR( zs57jpZxs*+Ttuo^q<#ec<9pj7y^ z0n)-UObCgg->Ua((H!vh4#Zpg_@k~HQ`1+n&x1L4K!=Y8>03LjgsWCR437k}yMlSj zhS)ouoB+CgX9sB0Gnli!xsQA zU_~>{k1>>ChLYpN?s7gRaerMdQZBr3;=E~dPsdPW3G}xs0G}Nr=6DNRA7RBjHi-GR zZoaBnCB(C%S;0xlH#0qh^LHc{7N#MQTyq05Qv`y_1l1V(ygT`|LQmIV8g+ZbjMX8r zz%z*9;n9ka_C5wb0bcDyQ5(d=5<`SWQ5a*X9nRXn1P{;9aM(wN8Go@d2g&Q&jc7Gn zI=dpuLdA4b#6LTaB@H>GQ~bwPXaWHTj*;R(nc@7_?tqIyMm5xiR)#>qWc<=(G?bkI z)#L=3RER~9biJv5-CWwz_7VNc@D~I90ZW)N(1{3`ra17Zv;YdlBlI2i3NxG?ZHZ=+ z48oxkB~=ZC;a{mtzJGEKphiE9_^GNk*h9b*_jaN9&I0&zkKHjYSf^h8Y`=7}L94Ij zfL3I-8`C+48|j+3RG;D2tqdth`gM9bUWUA{mIby69kgoIT?sQO3+z*A0v3$O^ML7b zP;>zjft7|U#P_E<2aMyT`B8K5*8rK}zD~!i?C||uhB2ptIDalUQ(JVrg)ahAp;GsA zYmQ6Zz>oR@95y&S89>Mcu(HKrR$_;zWQw6e(q6PHNeK@{1lFB|lLhfnL(P(p4ts!* z!J}Gq=cS49-!x4Y%RnP(BHj)qjbywSejz`O2J_9By3@@HBpasnWO8mVYx6OYB+}j&{+kxngpdGwEAx5ExLY(3>>1$N29_-54^ty0c+PKF`qD zCAsxBYII_3pyVi$x-w!BN-IX(2_ZSJah0!40GMRSQFe|+NJxcG0I3jSi`xqld0y|i4>_HC(SB76-xGX(O^ zWaPlKByB2!rYKvG6yXn_bS#Eg7EBGOdMr*F3)u#ZvRt%I3<-IR^Ga$LbZcR3=1|KZC!|>C)CMW~a#9;K+cpqj$t{zK#SrHJoknMAWkw7EiaBc1 zlxV^6)qjv^cm}%q;szL*vcq{GMq317T8eqA5_G|GQqIngE1QaT+frI(G9MGBPd+kE zt-%@KJ8EvKC5(J4+&rHZrekoX9aZNJGlni^eN}MpA}vVS@%qfH$8mZtqir)epE`|Y zB4nVD638)Gf4gTDNFcUTL!q3gjYjQr)5B0*pMOO+tmXnu&;r`XL#Z1cT^Jf!fQuZ`rgU9ev^mOvrX9u#^mN*@AsC^*TpWAggrZu1i-~EZQWL-!!find~kqdI`E19ASndH@~Jf7 zkbfn}vyR2xB&1*b+Q4ISBw`XM&3Tvu3>n%Mu3Dla?Xw_Pt{D=WhO2^^9r70q$2UaN zy+B!Xg>|~!K|W@WXy|PHs)#uPD%$=)Lu+O(I1G0 z;d~XD?tmp`yy1FBw;J_+j5oI;yq`S z2nRUo-BI+KC(;>*z$3!6MLxkJM}MAfXXe4w4>GxfB5>fOsE_hsxvg2xs1J#iNiS)4 z{_TJ?4OE&mbgd19B_X@x)NKQ= zKz+LBBET3L#3ZkR8_L4_OVXEjnL#QOg&ad0`mtgUVS!)(gfwuOw(oEY3jPo zik=A$YrWUeoz3eWv`2#kzZE=H`@KOogdI~AwSQEQ#Xw+92xB@d6n||9f^oV(3#9t; zq&fTV_gV+VD+a)m48ij%@OpfFn@Gq)i! zoYb`sfJyX;AwOm(#3z#tOI1L^;w<^VzB_Z!67asz5@dMeG^;ha`?MI};ngHKx;q|*#>4(ll%uJv7aWNuw>Pu1S3 zY1;i+8s!=wYnWww&}Gpo7_9NxXfHxW57bKzCi%C|Is9zmEXKB8={sbXM0;sc_`j znryW|C9tFZ-OKY{n7=v^R00 zU>&KhXpo35bAMO_-N7aqP$+Urcfj>WP2fK%k<8IwAzk-k62Q4Vi@dkN#cM~K5O*8y zq7XgdDgO-D$EpEB#-%bbaoOJPsBGL3dSR=az3A?l+wZ0m_R>9E)(!}b=timo&APX2 zGknG;BK}(52QDetEV#62uePUqp4(^H>u)O}Cj;4-Hh;9F98PAcWFv%o`qKzcI_yLE zZX8uc)k;*5gzga4^^)|TQvYcG()<$|e*CPW>rYky00D$)LqkwWLqi~Na&Km7Y-Iod zc$|HaJxIeq9K~PLN<}IT77=mCP@OD@iind`u?QAQTcK44lS{v#Nkfw2;wZQl9Q;_U zI=DFN>VM!W2!bCVPL58BE>hzEl0u6Z503ls?%w0>9UwF+Of>`JfT~$WDjpNFxm7Xv ziXa9cU={(1nR+6}v_(bA4rW+RV2J!T!rE}gV4zrS^ z5T6r|8FWG7N3P2*zi}=)Ebz>*kx9)Hhl#~v2Y<^Q%u0qzJVhK)RE_e5tjh}LEzWAC z##;B}FAU|il{D9B4kL~wB#?v%88wtqfrTio8Yw1Hv>)^E4>|rMxny#c!N{?IDpW|0 zAN&t~cWV|VC)}h^4Cs2X?T-;4xC=Dvw*7r<+szZe{|sDdZGW`^%zTnwZ)=ewpl=(v zxI}Ji@*Z%x0}MXtk|8;gpQcbK0Pkn?O*x?d7U)@Xdu#3E^a03FSIalR!67hOr0jK% zcXxO8_V1Zie?M~3a;G;sJD-z7A~1jC2Nnh+C<(%ZP5=M`=Sf6CRCwC$oIP&BKoCX; z!x@s2GAX%&3!lNcfF<`xEBORSoB)XngfmdkrlgEZ%5Vons*REjyF0VSKWn~iAjE4u zdAu_Zd(7lYbfpN!B+qj(==*L*Z+T83^Il(G#PdGunr1{q$K#PbX|Y)Rygz@PPV9N} z`Ml8)O(>EPKWJ4|K|3tVGH70wWpYprDTURLQdkY?f=zr!k_&6XabZn38*IXX^1*7T z%jNRt)dy>Xy7l>87t?e){quUyG5h_;YPAa5$!4<&nz!HYkw<$QGqWs8M$@t=k`mYx z>5z`Z=rn{<^tERiEmdk&Z%&O%)qFOGvL%Mx%=*^?1<-+Fx`ly*Q;&T97t-tko z;tMfXR7@zYsF+YT_{4QSN^MHRNo`8Qxoj#4Sv-9xAM6SC)RjF=h$hl`SE4KI3HAg~ zfDSc}MwRfTc~mESX&!Bo@Ntd;6rcb_!bif#ISNpKjuI4?bXrOHhr@q?Jt0lgpM)PW z@A>IT4Ec3FV=(~~pa6y8-y`8mC!qsk^oyygs-X7FvMhtzGqWt?H4&PSA)}Z6(V;-z z1l5qzZiY4?<6cbqKE1RDwC&bRX9t9IvoV*K_S9CwACfVR$DW1= zYX#NzB!%TZ&?1G6|Eqrpx5?Eu@7`rJiKW)ZYfnRcrU~}cxjk`AiF4Pu=>cKelf;xd zzoZjI!Urfo0SZunjtkUpPj&4#rH>ETQ+)OmgE?W<0~DYD1t>rVXiwhjPIc|S#sqsB zn?32%!evigU3$c-2Pi-R3Q&N?W>3`Z9Xi;P-p2R%&)50fEcAbzXObk(En(FI6rcbF zC_o>?p3*dRZ?W4EXB*fP*PcR+D%7%U=7p~DURJ$Qik8czc;`h?P*D`!rl&T3<6e}W zI2*0k>!6))x7+qZuaqLC)W7$VaQ71W-YXL)+>+4$4tHyzw}smmdRw?3GW4DQFjb=x d8bjCkH-1^)Wxo$(c`^V1002ovPDHLkV1hvhrn~?E diff --git a/Templates/BaseGame/game/data/UI/scripts/controlsMenu.tscript b/Templates/BaseGame/game/data/UI/scripts/controlsMenu.tscript index 071902d99..b88efa0d6 100644 --- a/Templates/BaseGame/game/data/UI/scripts/controlsMenu.tscript +++ b/Templates/BaseGame/game/data/UI/scripts/controlsMenu.tscript @@ -176,7 +176,7 @@ function fillRemapList() OptionsMenuSettingsList.addKeybindRow(getField(%keyMap, 0), getButtonBitmap(%device, getField(%keyMap, 1)), "doKeyRemap", -1, -15, true, %description); } - OptionsMenuSettingsList.refresh(); + //OptionsMenuSettingsList.refresh(); //OptionsMenu.addRow( %i, %this.buildFullMapString( %i ) ); } diff --git a/Templates/BaseGame/game/data/UI/scripts/menuInputButtons.tscript b/Templates/BaseGame/game/data/UI/scripts/menuInputButtons.tscript deleted file mode 100644 index 3d4c76c90..000000000 --- a/Templates/BaseGame/game/data/UI/scripts/menuInputButtons.tscript +++ /dev/null @@ -1,341 +0,0 @@ -//============================================================================== -// Menu Input Buttons -// This file manages the Menu Input Buttons stuff -// Any time you have a GUI button that should be clickable AND map to a key input -// such as a gamepad button, or enter, etc, this stuff can be used -//============================================================================== -/* -Gamepad input reference for 360 controller -btn_a = A -btn_b = B -btn_x = X -btn_y = Y -btn_r = Right Bumper -btn_l = Right Bumper -upov = Dpad Up -dpov = Dpad Down -lpov = Dpad Left -rpov = Dpad Right -xaxis = Left Stick | + values = up, - values = down -yaxis = Left Stick | + values = up, - values = down -rxaxis = Right Stick | + values = up, - values = down -ryaxis = Right Stick | + values = up, - values = down -zaxis = Left Trigger -rzaxis = Right Trigger -btn_start = Start -btn_back = Back/Select -*/ - -/// This is used with the main UI menu lists, when a non-axis input event is called -/// such as pressing a button -/// It is called from the engine -function UIMenuButtonList::onInputEvent(%this, %device, %action, %state) -{ - if(%state) - $activeMenuButtonContainer.processInputs(%device, %action); -} - -/// This is used with the main UI menu lists, when an axis input event is called -/// such as moving a joystick -/// It is called from the engine -function UIMenuButtonList::onAxisEvent(%this, %device, %action, %axisVal) -{ - //Skip out of the value is too low as it could just be noise or miscalibrated defaults - if(%axisVal < 0.02) - return; - - $activeMenuButtonContainer.processAxisEvent(%device, %action); -} - -/// Sets the command and text for the specified button. If %text and %command -/// are left empty, the button will be disabled and hidden. -/// -/// \param %gamepadButton (string) The button to set for when using gamepad input. See the input map reference comment at the top of the file -/// \param %keyboardButton (string) The button to set for when using keyboard/mouse input. -/// \param %text (string) The text to display next to the A button graphic. -/// \param %command (string) The command executed when the A button is pressed. -/// \param %gamepadOnly (bool) If true, will only show the button when working in the gamepad input mode -function MenuInputButton::set(%this, %gamepadButton, %keyboardButton, %text, %command, %gamepadOnly) -{ - %set = (! ((%text $= "") && (%command $= ""))); - %this.setText(%text); - %this.setActive(%set); - %this.setVisible(%set); - - %this.gamepadButton = %gamepadButton; - %this.keyboardButton = %keyboardButton; - - if(%gamepadOnly $= "") - %gamepadOnly = false; - - %this.gamepadOnly = %gamepadOnly; - - %this.Command = %command; -} - -/// Refreshes the specific button, updating it's visbility status and the displayed input image -function MenuInputButton::refresh(%this) -{ - %set = (! ((%this.text $= "") && (%this.command $= ""))); - - //Special-case of where we're in keyboard+mouse mode, but the menubutton is gamepad only mode, so we early out - if(%this.gamepadOnly && $activeControllerType !$= "gamepad") - %set = false; - - %this.setActive(%set); - %this.setVisible(%set); - - if(!%this.isActive()) - return; - - if($activeControllerType $= "gamepad") - { - if(%this.gamepadButton !$= "") - { - %assetId = ""; - if($activeControllerName $= "PS4 Controller") - { - %assetId = "UI:PS4_"; - - if(%this.gamepadButton $= "btn_a") - %assetId = %assetId @ "Cross"; - else if(%this.gamepadButton $= "btn_b") - %assetId = %assetId @ "Circle"; - else if(%this.gamepadButton $= "btn_x") - %assetId = %assetId @ "Square"; - else if(%this.gamepadButton $= "btn_y") - %assetId = %assetId @ "Triangle"; - else if(%this.gamepadButton $= "btn_l") - %assetId = %assetId @ "L1"; - else if(%this.gamepadButton $= "zaxis") - %assetId = %assetId @ "L2"; - else if(%this.gamepadButton $= "btn_r") - %assetId = %assetId @ "R1"; - else if(%this.gamepadButton $= "rzaxis") - %assetId = %assetId @ "R2"; - else if(%this.gamepadButton $= "btn_start") - %assetId = %assetId @ "Options"; - else if(%this.gamepadButton $= "btn_back") - %assetId = %assetId @ "Share"; - } - else if($activeControllerName $= "Nintendo Switch Pro Controller") - { - %assetId = "UI:Switch_"; - - if(%this.gamepadButton $= "btn_a") - %assetId = %assetId @ "B"; - else if(%this.gamepadButton $= "btn_b") - %assetId = %assetId @ "A"; - else if(%this.gamepadButton $= "btn_x") - %assetId = %assetId @ "Y"; - else if(%this.gamepadButton $= "btn_y") - %assetId = %assetId @ "X"; - else if(%this.gamepadButton $= "btn_l") - %assetId = %assetId @ "LB"; - else if(%this.gamepadButton $= "zaxis") - %assetId = %assetId @ "LT"; - else if(%this.gamepadButton $= "btn_r") - %assetId = %assetId @ "RB"; - else if(%this.gamepadButton $= "rzaxis") - %assetId = %assetId @ "RT"; - else if(%this.gamepadButton $= "btn_start") - %assetId = %assetId @ "Plus"; - else if(%this.gamepadButton $= "btn_back") - %assetId = %assetId @ "Minus"; - } - else if($activeControllerName !$= "") - { - %assetId = "UI:Xbox_"; - - if(%this.gamepadButton $= "btn_a") - %assetId = %assetId @ "A"; - else if(%this.gamepadButton $= "btn_b") - %assetId = %assetId @ "B"; - else if(%this.gamepadButton $= "btn_x") - %assetId = %assetId @ "X"; - else if(%this.gamepadButton $= "btn_y") - %assetId = %assetId @ "Y"; - else if(%this.gamepadButton $= "btn_l") - %assetId = %assetId @ "LB"; - else if(%this.gamepadButton $= "zaxis") - %assetId = %assetId @ "LT"; - else if(%this.gamepadButton $= "btn_r") - %assetId = %assetId @ "RB"; - else if(%this.gamepadButton $= "rzaxis") - %assetId = %assetId @ "RT"; - else if(%this.gamepadButton $= "btn_start") - %assetId = %assetId @ "Menu"; - else if(%this.gamepadButton $= "btn_back") - %assetId = %assetId @ "Windows"; - } - } - } - else - { - if(%this.keyboardButton !$= "") - { - %assetId = "UI:Keyboard_Black_" @ %this.keyboardButton; - } - } - - %this.setBitmap(%assetId @ "_image"); - - return true; -} - -/// Refreshes a menu input container, updating the buttons inside it -function MenuInputButtonContainer::refresh(%this) -{ - %count = %this.getCount(); - for(%i=0; %i < %count; %i++) - { - %btn = %this.getObject(%i); - - %btn.refresh(); - } -} - -/// Sets the given MenuInputButtonContainer as the active one. This directs input events -/// to it's buttons, ensures it's visible, and auto-hides the old active container if it was set -function MenuInputButtonContainer::setActive(%this) -{ - if(isObject($activeMenuButtonContainer)) - $activeMenuButtonContainer.hidden = true; - - $activeMenuButtonContainer = %this; - $activeMenuButtonContainer.hidden = false; - $activeMenuButtonContainer.refresh(); -} - -/// Checks the input manager for if we have a gamepad active and gets it's name -/// If we have one, also sets the active input type to gamepad -function MenuInputButtonContainer::checkGamepad(%this) -{ - %controllerName = SDLInputManager::JoystickNameForIndex(0); - - $activeControllerName = %controllerName; - - if($activeControllerName $= "") - $activeControllerType = "K&M"; - else - $activeControllerType = "gamepad"; -} - -/// This is called by the earlier inputs callback that comes from the menu list -/// this allows us to first check what the input type is, and if the device is different -/// (such as going from keyboard and mouse to gamepad) we can refresh the buttons to update -/// the display -/// Then we process the input to see if it matches to any of the button maps for our -/// MenuInputButtons. If we have a match, we execute it's command. -function MenuInputButtonContainer::processInputs(%this, %device, %action) -{ - //check to see if our status has changed - %changed = false; - - %oldDevice = $activeControllerName; - - %deviceName = stripTrailingNumber(%device); - - if(%deviceName $= "keyboard" || %deviceName $= "mouse") - { - if($activeControllerName !$= "K&M") - %changed = true; - - $activeControllerName = "K&M"; - $activeControllerType = "K&M"; - Canvas.showCursor(); - } - else - { - if(%this.checkGamepad()) - { - Canvas.hideCursor(); - } - - if($activeControllerType !$= %oldDevice) - %changed = true; - } - - if(%changed) - %this.refresh(); - - //Now process the input for the button accelerator, if applicable - //Set up our basic buttons - for(%i=0; %i < %this.getCount(); %i++) - { - %btn = %this.getObject(%i); - - if(!%btn.isActive()) - continue; - - if($activeControllerType !$= "K&M") - { - if(%btn.gamepadButton $= %action) - { - eval(%btn.command); - } - } - else - { - if(%btn.keyboardButton $= %action) - { - eval(%btn.command); - } - } - } -} - -/// This is called by the earlier inputs callback that comes from the menu list -/// this allows us to first check what the input type is, and if the device is different -/// (such as going from keyboard and mouse to gamepad) we can refresh the buttons to update -/// the display -function MenuInputButtonContainer::processAxisEvent(%this, %device, %action, %axisVal) -{ - //check to see if our status has changed - %changed = false; - - %oldDevice = $activeControllerName; - - %deviceName = stripTrailingNumber(%device); - - if(%deviceName $= "mouse") - { - if($activeControllerName !$= "K&M") - %changed = true; - - $activeControllerName = "K&M"; - $activeControllerType = "K&M"; - Canvas.showCursor(); - } - else - { - if(%this.checkGamepad()) - { - Canvas.hideCursor(); - } - - if($activeControllerType !$= %oldDevice) - %changed = true; - } - - if(%changed) - %this.refresh(); -} - -// -// -function onSDLDeviceConnected(%sdlIndex, %deviceName, %deviceType) -{ - /*if(GamepadButtonsGui.checkGamepad()) - { - GamepadButtonsGui.hidden = false; - }*/ -} - -function onSDLDeviceDisconnected(%sdlIndex) -{ - /*if(!GamepadButtonsGui.checkGamepad()) - { - GamepadButtonsGui.hidden = true; - }*/ -} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/UI/scripts/profiles.tscript b/Templates/BaseGame/game/data/UI/scripts/profiles.tscript index c9dfed5b5..3aae4df2a 100644 --- a/Templates/BaseGame/game/data/UI/scripts/profiles.tscript +++ b/Templates/BaseGame/game/data/UI/scripts/profiles.tscript @@ -145,6 +145,12 @@ new GuiControlProfile( GuiBlankMenuButtonProfile ) category = "Core"; }; +if( !isObject( GuiJoinServerButtonProfile ) ) +new GuiControlProfile( GuiJoinServerButtonProfile : GuiMenuButtonProfile ) +{ + justify = "left"; +}; + if( !isObject( GuiMenuTextProfile ) ) new GuiControlProfile( GuiMenuTextProfile ) { From 01de818503eff34fdcfaa9cfe5725dfb68024f81 Mon Sep 17 00:00:00 2001 From: JeffR Date: Tue, 22 Feb 2022 20:12:39 -0600 Subject: [PATCH 030/145] Ran importer on UI module to ensure guis and images are converted to latest standards Updated all UI module controls to utilize a more standard structure with stack controls instead of the GameMenu ctrls, as well as more standardization of gamepad input handling --- .../data/ExampleModule/ExampleModule.tscript | 6 + Templates/BaseGame/game/data/UI/UI.module | 2 +- Templates/BaseGame/game/data/UI/UI.tscript | 2 +- .../data/UI/datablocks/guiSounds.asset.taml | 2 +- .../game/data/UI/datablocks/guiSounds.tscript | 2 +- .../data/UI/guis/ChooseLevelDlg.asset.taml | 6 +- .../data/UI/guis/GuiMusicPlayer.asset.taml | 6 +- .../data/UI/guis/IODropdownDlg.asset.taml | 5 +- .../data/UI/guis/JoinServerMenu.asset.taml | 6 +- .../game/data/UI/guis/LoadingGui.asset.taml | 5 +- .../game/data/UI/guis/MainMenuGui.asset.taml | 6 +- .../data/UI/guis/MessageBoxDlg.asset.taml | 5 +- .../data/UI/guis/NetGraphProfile.asset.taml | 7 - .../game/data/UI/guis/OptionsMenu.asset.taml | 6 +- .../game/data/UI/guis/PauseMenu.asset.taml | 6 +- .../game/data/UI/guis/ProfilerGui.asset.taml | 6 +- .../data/UI/guis/RemapConfirmDlg.asset.taml | 5 +- .../game/data/UI/guis/RemapDlg.asset.taml | 5 +- .../game/data/UI/guis/StartupGui.asset.taml | 6 +- .../game/data/UI/guis/chooseLevelDlg.gui | 4 +- .../data/UI/guis/controlsMenuSetting.taml | 102 --- .../game/data/UI/guis/joinServerMenu.gui | 2 +- .../game/data/UI/guis/joinServerMenu.tscript | 8 +- .../BaseGame/game/data/UI/guis/mainMenu.gui | 4 +- .../game/data/UI/guis/mainMenu.tscript | 3 +- .../game/data/UI/guis/messageBoxDlg.gui | 4 +- .../game/data/UI/guis/netGraphGui.gui | 2 +- .../game/data/UI/guis/optionsMenu.gui | 183 ------ .../game/data/UI/guis/optionsMenu.tscript | 581 ++++++++++++------ .../BaseGame/game/data/UI/guis/pauseMenu.gui | 49 +- .../game/data/UI/guis/pauseMenu.tscript | 49 +- .../game/data/UI/guis/profiler.tscript | 2 +- .../data/UI/guis/recordingsDlg.asset.taml | 5 +- .../BaseGame/game/data/UI/guis/startupGui.gui | 4 +- .../game/data/UI/guis/startupGui.tscript | 2 +- .../UI/images/Torque-3D-logo-shortcut.png | Bin 10728 -> 0 bytes .../game/data/UI/images/Torque-3D-logo-w.png | Bin 19328 -> 0 bytes .../game/data/UI/images/Torque-3D-logo.png | Bin 9063 -> 0 bytes .../data/UI/images/Torque-3D-logo_alt.png | Bin 11616 -> 0 bytes .../Torque_3D_logo_alt_image.asset.taml | 2 +- .../UI/images/Torque_3D_logo_image.asset.taml | 2 +- .../Torque_3D_logo_shortcut_image.asset.taml | 2 +- .../images/Torque_3D_logo_w_image.asset.taml | 2 +- .../game/data/UI/images/background-dark.png | Bin 5751 -> 0 bytes .../images/background_dark_image.asset.taml | 8 - .../game/data/UI/images/clear-btn_d.png | Bin 593 -> 0 bytes .../game/data/UI/images/clear-btn_h.png | Bin 595 -> 0 bytes .../game/data/UI/images/clear-btn_n.png | Bin 377 -> 0 bytes .../data/UI/images/collapse-toolbar_d.png | Bin 280 -> 0 bytes .../data/UI/images/collapse-toolbar_h.png | Bin 468 -> 0 bytes .../data/UI/images/collapse-toolbar_n.png | Bin 439 -> 0 bytes .../data/UI/images/dropdown-button-arrow.png | Bin 132 -> 0 bytes .../game/data/UI/images/dropdown-textEdit.png | Bin 390 -> 0 bytes .../game/data/UI/images/expand-toolbar_d.png | Bin 278 -> 0 bytes .../game/data/UI/images/expand-toolbar_h.png | Bin 468 -> 0 bytes .../game/data/UI/images/expand-toolbar_n.png | Bin 437 -> 0 bytes .../game/data/UI/images/group-border.png | Bin 1273 -> 0 bytes .../game/data/UI/images/inactive-overlay.png | Bin 131 -> 0 bytes .../game/data/UI/images/menu-button.png | Bin 3559 -> 0 bytes .../game/data/UI/images/next-button_d.png | Bin 279 -> 0 bytes .../game/data/UI/images/next-button_h.png | Bin 549 -> 0 bytes .../game/data/UI/images/next-button_n.png | Bin 484 -> 0 bytes .../game/data/UI/images/no-preview.png | Bin 34615 -> 0 bytes .../game/data/UI/images/previous-button_d.png | Bin 290 -> 0 bytes .../game/data/UI/images/previous-button_h.png | Bin 561 -> 0 bytes .../game/data/UI/images/previous-button_n.png | Bin 494 -> 0 bytes .../data/UI/images/selector-button-blank.png | Bin 744 -> 0 bytes .../data/UI/images/selector-button-dark.png | Bin 1942 -> 0 bytes .../images/selector-button-highlight-only.png | Bin 1613 -> 0 bytes .../game/data/UI/images/selector-button.png | Bin 4002 -> 0 bytes .../game/data/UI/images/separator-h.png | Bin 117 -> 0 bytes .../game/data/UI/images/separator-v.png | Bin 118 -> 0 bytes .../game/data/UI/images/slider - Copy.png | Bin 908 -> 0 bytes .../game/data/UI/images/slider-w-box.png | Bin 982 -> 0 bytes .../UI/images/slider___Copy_image.asset.taml | 8 - .../game/data/UI/images/tab-border.png | Bin 1203 -> 0 bytes .../game/data/UI/scripts/controlsMenu.tscript | 17 +- .../game/data/UI/scripts/cursors.tscript | 2 +- .../game/data/UI/scripts/utility.tscript | 114 ++-- .../scripts/projectImporter.tscript | 8 +- 80 files changed, 590 insertions(+), 673 deletions(-) delete mode 100644 Templates/BaseGame/game/data/UI/guis/NetGraphProfile.asset.taml delete mode 100644 Templates/BaseGame/game/data/UI/guis/controlsMenuSetting.taml delete mode 100644 Templates/BaseGame/game/data/UI/images/Torque-3D-logo-shortcut.png delete mode 100644 Templates/BaseGame/game/data/UI/images/Torque-3D-logo-w.png delete mode 100644 Templates/BaseGame/game/data/UI/images/Torque-3D-logo.png delete mode 100644 Templates/BaseGame/game/data/UI/images/Torque-3D-logo_alt.png delete mode 100644 Templates/BaseGame/game/data/UI/images/background-dark.png delete mode 100644 Templates/BaseGame/game/data/UI/images/background_dark_image.asset.taml delete mode 100644 Templates/BaseGame/game/data/UI/images/clear-btn_d.png delete mode 100644 Templates/BaseGame/game/data/UI/images/clear-btn_h.png delete mode 100644 Templates/BaseGame/game/data/UI/images/clear-btn_n.png delete mode 100644 Templates/BaseGame/game/data/UI/images/collapse-toolbar_d.png delete mode 100644 Templates/BaseGame/game/data/UI/images/collapse-toolbar_h.png delete mode 100644 Templates/BaseGame/game/data/UI/images/collapse-toolbar_n.png delete mode 100644 Templates/BaseGame/game/data/UI/images/dropdown-button-arrow.png delete mode 100644 Templates/BaseGame/game/data/UI/images/dropdown-textEdit.png delete mode 100644 Templates/BaseGame/game/data/UI/images/expand-toolbar_d.png delete mode 100644 Templates/BaseGame/game/data/UI/images/expand-toolbar_h.png delete mode 100644 Templates/BaseGame/game/data/UI/images/expand-toolbar_n.png delete mode 100644 Templates/BaseGame/game/data/UI/images/group-border.png delete mode 100644 Templates/BaseGame/game/data/UI/images/inactive-overlay.png delete mode 100644 Templates/BaseGame/game/data/UI/images/menu-button.png delete mode 100644 Templates/BaseGame/game/data/UI/images/next-button_d.png delete mode 100644 Templates/BaseGame/game/data/UI/images/next-button_h.png delete mode 100644 Templates/BaseGame/game/data/UI/images/next-button_n.png delete mode 100644 Templates/BaseGame/game/data/UI/images/no-preview.png delete mode 100644 Templates/BaseGame/game/data/UI/images/previous-button_d.png delete mode 100644 Templates/BaseGame/game/data/UI/images/previous-button_h.png delete mode 100644 Templates/BaseGame/game/data/UI/images/previous-button_n.png delete mode 100644 Templates/BaseGame/game/data/UI/images/selector-button-blank.png delete mode 100644 Templates/BaseGame/game/data/UI/images/selector-button-dark.png delete mode 100644 Templates/BaseGame/game/data/UI/images/selector-button-highlight-only.png delete mode 100644 Templates/BaseGame/game/data/UI/images/selector-button.png delete mode 100644 Templates/BaseGame/game/data/UI/images/separator-h.png delete mode 100644 Templates/BaseGame/game/data/UI/images/separator-v.png delete mode 100644 Templates/BaseGame/game/data/UI/images/slider - Copy.png delete mode 100644 Templates/BaseGame/game/data/UI/images/slider-w-box.png delete mode 100644 Templates/BaseGame/game/data/UI/images/slider___Copy_image.asset.taml delete mode 100644 Templates/BaseGame/game/data/UI/images/tab-border.png diff --git a/Templates/BaseGame/game/data/ExampleModule/ExampleModule.tscript b/Templates/BaseGame/game/data/ExampleModule/ExampleModule.tscript index 0b233dc61..0f540c0d8 100644 --- a/Templates/BaseGame/game/data/ExampleModule/ExampleModule.tscript +++ b/Templates/BaseGame/game/data/ExampleModule/ExampleModule.tscript @@ -81,6 +81,7 @@ function ExampleModule::initClient(%this) exec(%prefPath @ "/keybinds." @ $TorqueScriptFileExtension); %this.queueExec("./scripts/inputCommands"); + addOptionsMenuCategory("Example Options", "testExampleOptions();"); } //This is called when a game session client successfuly connects to a game server. @@ -105,4 +106,9 @@ function ExampleModule::onDestroyClientConnection(%this) { //This will pop the keybind, cleaning it up from the input stack, as it no longer applies ExampleMoveMap.pop(); +} + +function testExampleOptions() +{ + addListOption("Test Option", "This is a test option", $testOptionValue, "OptionA\tOptionB"); } \ No newline at end of file diff --git a/Templates/BaseGame/game/data/UI/UI.module b/Templates/BaseGame/game/data/UI/UI.module index 1ab3024a2..ed204d1b1 100644 --- a/Templates/BaseGame/game/data/UI/UI.module +++ b/Templates/BaseGame/game/data/UI/UI.module @@ -11,4 +11,4 @@ canSaveDynamicFields="true" Extension="asset.taml" Recurse="true" /> - \ No newline at end of file + diff --git a/Templates/BaseGame/game/data/UI/UI.tscript b/Templates/BaseGame/game/data/UI/UI.tscript index 5b8c1ee6a..cd645f86f 100644 --- a/Templates/BaseGame/game/data/UI/UI.tscript +++ b/Templates/BaseGame/game/data/UI/UI.tscript @@ -83,4 +83,4 @@ function UI::initClient(%this) function UI::onCreateClientConnection(%this){} -function UI::onDestroyClientConnection(%this){} \ No newline at end of file +function UI::onDestroyClientConnection(%this){} diff --git a/Templates/BaseGame/game/data/UI/datablocks/guiSounds.asset.taml b/Templates/BaseGame/game/data/UI/datablocks/guiSounds.asset.taml index 81e2a8e24..7e5a1cada 100644 --- a/Templates/BaseGame/game/data/UI/datablocks/guiSounds.asset.taml +++ b/Templates/BaseGame/game/data/UI/datablocks/guiSounds.asset.taml @@ -2,5 +2,5 @@ canSave="true" canSaveDynamicFields="true" AssetName="guiSounds" - scriptFile="@assetFile=guiSounds.cs" + scriptFile="@assetFile=guiSounds" VersionId="1" /> diff --git a/Templates/BaseGame/game/data/UI/datablocks/guiSounds.tscript b/Templates/BaseGame/game/data/UI/datablocks/guiSounds.tscript index 0aab47fb9..4eed5f78a 100644 --- a/Templates/BaseGame/game/data/UI/datablocks/guiSounds.tscript +++ b/Templates/BaseGame/game/data/UI/datablocks/guiSounds.tscript @@ -31,4 +31,4 @@ singleton SFXProfile(menuButtonHover) preload = true; description = AudioGui; fileName = "data/ui/sounds/buttonHover"; -}; \ No newline at end of file +}; diff --git a/Templates/BaseGame/game/data/UI/guis/ChooseLevelDlg.asset.taml b/Templates/BaseGame/game/data/UI/guis/ChooseLevelDlg.asset.taml index 2d6a987f0..9090ea1af 100644 --- a/Templates/BaseGame/game/data/UI/guis/ChooseLevelDlg.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/ChooseLevelDlg.asset.taml @@ -1,7 +1,5 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/GuiMusicPlayer.asset.taml b/Templates/BaseGame/game/data/UI/guis/GuiMusicPlayer.asset.taml index 7014d72a6..94601d7a3 100644 --- a/Templates/BaseGame/game/data/UI/guis/GuiMusicPlayer.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/GuiMusicPlayer.asset.taml @@ -1,7 +1,5 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/IODropdownDlg.asset.taml b/Templates/BaseGame/game/data/UI/guis/IODropdownDlg.asset.taml index b929c70b0..d1d0c8c8e 100644 --- a/Templates/BaseGame/game/data/UI/guis/IODropdownDlg.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/IODropdownDlg.asset.taml @@ -1,7 +1,4 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/JoinServerMenu.asset.taml b/Templates/BaseGame/game/data/UI/guis/JoinServerMenu.asset.taml index 0ca202e6d..85da0192a 100644 --- a/Templates/BaseGame/game/data/UI/guis/JoinServerMenu.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/JoinServerMenu.asset.taml @@ -1,7 +1,5 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/LoadingGui.asset.taml b/Templates/BaseGame/game/data/UI/guis/LoadingGui.asset.taml index 196bc91e7..fc8ac974c 100644 --- a/Templates/BaseGame/game/data/UI/guis/LoadingGui.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/LoadingGui.asset.taml @@ -1,7 +1,4 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/MainMenuGui.asset.taml b/Templates/BaseGame/game/data/UI/guis/MainMenuGui.asset.taml index 2fd6b7c72..cdd3c6635 100644 --- a/Templates/BaseGame/game/data/UI/guis/MainMenuGui.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/MainMenuGui.asset.taml @@ -1,7 +1,5 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/MessageBoxDlg.asset.taml b/Templates/BaseGame/game/data/UI/guis/MessageBoxDlg.asset.taml index 9b9d38995..14ff4ba60 100644 --- a/Templates/BaseGame/game/data/UI/guis/MessageBoxDlg.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/MessageBoxDlg.asset.taml @@ -1,7 +1,4 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/NetGraphProfile.asset.taml b/Templates/BaseGame/game/data/UI/guis/NetGraphProfile.asset.taml deleted file mode 100644 index 2ee15e4ea..000000000 --- a/Templates/BaseGame/game/data/UI/guis/NetGraphProfile.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/data/UI/guis/OptionsMenu.asset.taml b/Templates/BaseGame/game/data/UI/guis/OptionsMenu.asset.taml index a00b4c7d4..0488ea976 100644 --- a/Templates/BaseGame/game/data/UI/guis/OptionsMenu.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/OptionsMenu.asset.taml @@ -1,7 +1,5 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/PauseMenu.asset.taml b/Templates/BaseGame/game/data/UI/guis/PauseMenu.asset.taml index c3806430a..08a16f03d 100644 --- a/Templates/BaseGame/game/data/UI/guis/PauseMenu.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/PauseMenu.asset.taml @@ -1,7 +1,5 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/ProfilerGui.asset.taml b/Templates/BaseGame/game/data/UI/guis/ProfilerGui.asset.taml index 0e49346ab..09b400893 100644 --- a/Templates/BaseGame/game/data/UI/guis/ProfilerGui.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/ProfilerGui.asset.taml @@ -1,7 +1,5 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/RemapConfirmDlg.asset.taml b/Templates/BaseGame/game/data/UI/guis/RemapConfirmDlg.asset.taml index 1e3fb30aa..6fc8c874a 100644 --- a/Templates/BaseGame/game/data/UI/guis/RemapConfirmDlg.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/RemapConfirmDlg.asset.taml @@ -1,7 +1,4 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/RemapDlg.asset.taml b/Templates/BaseGame/game/data/UI/guis/RemapDlg.asset.taml index 6b1c4df9a..7ea99e19c 100644 --- a/Templates/BaseGame/game/data/UI/guis/RemapDlg.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/RemapDlg.asset.taml @@ -1,7 +1,4 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/StartupGui.asset.taml b/Templates/BaseGame/game/data/UI/guis/StartupGui.asset.taml index 656157f71..876b039a6 100644 --- a/Templates/BaseGame/game/data/UI/guis/StartupGui.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/StartupGui.asset.taml @@ -1,7 +1,5 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/chooseLevelDlg.gui b/Templates/BaseGame/game/data/UI/guis/chooseLevelDlg.gui index fc2ffc57e..775e910f0 100644 --- a/Templates/BaseGame/game/data/UI/guis/chooseLevelDlg.gui +++ b/Templates/BaseGame/game/data/UI/guis/chooseLevelDlg.gui @@ -36,7 +36,7 @@ $guiContent = new GuiControl(ChooseLevelDlg) { percent = "100"; vertical = "0"; flipClip = "0"; - bitmap = "data/ui/images/panel.png"; + bitmapAsset = "UI:panel_image"; color = "255 255 255 255"; position = "0 0"; extent = "927 40"; @@ -79,7 +79,7 @@ $guiContent = new GuiControl(ChooseLevelDlg) { percent = "100"; vertical = "0"; flipClip = "0"; - bitmap = "data/ui/images/panel_low.png"; + bitmapAsset = "UI:panel_low_image"; color = "255 255 255 255"; position = "0 40"; extent = "927 618"; diff --git a/Templates/BaseGame/game/data/UI/guis/controlsMenuSetting.taml b/Templates/BaseGame/game/data/UI/guis/controlsMenuSetting.taml deleted file mode 100644 index e2794ca4a..000000000 --- a/Templates/BaseGame/game/data/UI/guis/controlsMenuSetting.taml +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - diff --git a/Templates/BaseGame/game/data/UI/guis/joinServerMenu.gui b/Templates/BaseGame/game/data/UI/guis/joinServerMenu.gui index 17a2c4435..c812e624c 100644 --- a/Templates/BaseGame/game/data/UI/guis/joinServerMenu.gui +++ b/Templates/BaseGame/game/data/UI/guis/joinServerMenu.gui @@ -425,7 +425,7 @@ $guiContent = new GuiControl(JoinServerMenu) { vertSizing = "bottom"; profile = "GuiMenuButtonProfile"; visible = "1"; - active = "1"; + active = "0"; command = "JoinServerMenu.join();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; diff --git a/Templates/BaseGame/game/data/UI/guis/joinServerMenu.tscript b/Templates/BaseGame/game/data/UI/guis/joinServerMenu.tscript index b2f0eb8eb..1fe75bd46 100644 --- a/Templates/BaseGame/game/data/UI/guis/joinServerMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/joinServerMenu.tscript @@ -1,10 +1,6 @@ -function JoinServerMenu::onWake() +function JoinServerMenu::onWake(%this) { - // Double check the status. Tried setting this the control - // inactive to start with, but that didn't seem to work. - JoinServerJoinBtn.setActive(JoinServerList.getCount() > 0); - JoinServerButtonHolder.setActive(); JoinServerList.setAsActiveMenuList(); @@ -128,7 +124,7 @@ function JoinServerMenu::update(%this) JoinServerList.add(%serverBtn); } - JoinServerJoinBtn.setActive(JoinServerList.getCount() > 0); + JoinServerButtonHolder-->joinButton.setActive(JoinServerList.getCount() > 0); } //---------------------------------------- diff --git a/Templates/BaseGame/game/data/UI/guis/mainMenu.gui b/Templates/BaseGame/game/data/UI/guis/mainMenu.gui index 4c6c13697..6b1dad9ee 100644 --- a/Templates/BaseGame/game/data/UI/guis/mainMenu.gui +++ b/Templates/BaseGame/game/data/UI/guis/mainMenu.gui @@ -1,6 +1,6 @@ //--- OBJECT WRITE BEGIN --- $guiContent = new GuiChunkedBitmapCtrl(MainMenuGui) { - BitmapAsset = "UI:background_dark_image"; + BitmapAsset = "UI:backgrounddark_image"; useVariable = "0"; tile = "0"; position = "0 0"; @@ -203,7 +203,7 @@ $guiContent = new GuiChunkedBitmapCtrl(MainMenuGui) { profile = "GuiMenuButtonProfile"; visible = "1"; active = "1"; - command = "exit();"; + command = "quit();"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; diff --git a/Templates/BaseGame/game/data/UI/guis/mainMenu.tscript b/Templates/BaseGame/game/data/UI/guis/mainMenu.tscript index 0d830f176..c626c4952 100644 --- a/Templates/BaseGame/game/data/UI/guis/mainMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/mainMenu.tscript @@ -66,4 +66,5 @@ function MainMenuGui::onReturnTo(%this) MainMenuButtonList.hidden = false; MainMenuButtonList.setFirstResponder(); MainMenuButtonHolder.setActive(); -} \ No newline at end of file + MainMenuButtonList.setAsActiveMenuList(); +} diff --git a/Templates/BaseGame/game/data/UI/guis/messageBoxDlg.gui b/Templates/BaseGame/game/data/UI/guis/messageBoxDlg.gui index a78ae98d5..91207adff 100644 --- a/Templates/BaseGame/game/data/UI/guis/messageBoxDlg.gui +++ b/Templates/BaseGame/game/data/UI/guis/messageBoxDlg.gui @@ -34,7 +34,7 @@ $guiContent = new GuiControl(MessageBoxDlg) { percent = "100"; vertical = "0"; flipClip = "0"; - bitmap = "data/ui/images/panel.png"; + bitmapAsset = "UI:panel_image"; color = "255 255 255 255"; position = "0 0"; extent = "641 40"; @@ -77,7 +77,7 @@ $guiContent = new GuiControl(MessageBoxDlg) { percent = "100"; vertical = "0"; flipClip = "0"; - bitmap = "data/ui/images/panel_low.png"; + bitmapAsset = "UI:panel_low_image"; color = "255 255 255 255"; position = "0 40"; extent = "641 341"; diff --git a/Templates/BaseGame/game/data/UI/guis/netGraphGui.gui b/Templates/BaseGame/game/data/UI/guis/netGraphGui.gui index be8ba1233..9da782ba7 100644 --- a/Templates/BaseGame/game/data/UI/guis/netGraphGui.gui +++ b/Templates/BaseGame/game/data/UI/guis/netGraphGui.gui @@ -554,4 +554,4 @@ function NetGraph::updateNetworkSimulation(%this) } netSimulateLag( %latency, %packetLoss ); -} \ No newline at end of file +} diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui b/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui index b7195557c..a8fc2fb1e 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui @@ -213,127 +213,6 @@ $guiContent = new GuiControl(OptionsMenu) { class = "MenuList"; canSave = "1"; canSaveDynamicFields = "0"; - - new GuiButtonCtrl(OptionsMenuDisplayBtn) { - text = "Display"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "0 0"; - extent = "248 35"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "populateDisplaySettingsList();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl(OptionsMenuGraphicsBtn) { - text = "Graphics"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "0 45"; - extent = "248 35"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "populateGraphicsSettingsList();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl(OptionsMenuAudioBtn) { - text = "Audio"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "0 90"; - extent = "248 35"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "populateAudioSettingsList();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl(OptionsMenuKBMBtn) { - text = "Keyboard & Mouse"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "0 135"; - extent = "248 35"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "populateKeyboardMouseSettingsList();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl(OptionsMenuGamepadBtn) { - text = "Gamepad"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "0 180"; - extent = "248 35"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "populateGamepadSettingsList();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiButtonCtrl(OptionsMenuProfileBtn) { - text = "Profile"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "0 225"; - extent = "248 35"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "populateProfileSettingsList();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; }; }; new GuiPanel() { @@ -493,68 +372,6 @@ $guiContent = new GuiControl(OptionsMenu) { canSave = "1"; canSaveDynamicFields = "0"; }; - new GuiIconButtonCtrl() { - buttonMargin = "4 4"; - BitmapAsset = "UI:Switch_LB_image"; - iconLocation = "Left"; - sizeIconToButton = "1"; - makeIconSquare = "1"; - textLocation = "Right"; - textMargin = "4"; - autoSize = "0"; - text = "Prev Tab"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "0 0"; - extent = "140 40"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "0"; - active = "0"; - command = "OptionsMenu.prevTab();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "prevTabButton"; - class = "MenuInputButton"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiIconButtonCtrl() { - buttonMargin = "4 4"; - BitmapAsset = "UI:Switch_RB_image"; - iconLocation = "Left"; - sizeIconToButton = "1"; - makeIconSquare = "1"; - textLocation = "Right"; - textMargin = "4"; - autoSize = "0"; - text = "Next Tab"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "144 0"; - extent = "140 40"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "0"; - active = "0"; - command = "OptionsMenu.nextTab();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "nextTabButton"; - class = "MenuInputButton"; - hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; new GuiIconButtonCtrl() { buttonMargin = "4 4"; BitmapAsset = "UI:Keyboard_Black_R_image"; diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript index eac532203..48612b943 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript @@ -46,12 +46,67 @@ //headbob //FOV +function OptionsMenu::onAdd(%this) +{ + if(!isObject(%this.optionsCategories)) + { + %this.optionsCategories = new ArrayObject(); + } + + if(!isObject(%this.unappliedChanges)) + { + %this.unappliedChanges = new ArrayObject(); + } + + addOptionsMenuCategory("Display", "populateDisplaySettingsList();"); + addOptionsMenuCategory("Graphics", "populateGraphicsSettingsList();"); + addOptionsMenuCategory("Audio", "populateAudioSettingsList();"); + addOptionsMenuCategory("Keyboard & Mouse", "populateKeyboardMouseSettingsList();"); + addOptionsMenuCategory("Gamepad", "populateGamepadSettingsList();"); +} + function OptionsMenuSettingsList::onAdd(%this) { } +function OptionsMenuSettingsList::getOptionsList(%this, %index) +{ + +} + function OptionsMenu::onWake(%this) { + for(%i=0; %i < %this.optionsCategories.count(); %i++) + { + %catName = %this.optionsCategories.getKey(%i); + %callback = %this.optionsCategories.getValue(%i); + + %newCatButton = new GuiButtonCtrl() { + text = %catName; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 180"; + extent = "248 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = %callback; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + OptionsMenuCategoryList.add(%newCatButton); + } + + %this.unappliedChanges.empty(); + MainMenuButtonList.hidden = true; OptionsMenuCategoryList.setAsActiveMenuList(); @@ -63,8 +118,6 @@ function OptionsMenu::onWake(%this) function OptionsButtonHolder::onWake(%this) { - //%this-->prevTabButton.set("btn_l", "", "Prev Tab", "OptionsMenu.prevTab();", true); - %this-->nextTabButton.set("btn_a", "", "Select", "OptionsMenuList.activate();", true); %this-->resetButton.set("btn_back", "R", "Reset", "OptionsMenu.resetToDefaults();"); %this-->applyButton.set("btn_start", "Return", "Apply", "OptionsMenu.apply();"); %this-->backButton.set("btn_b", "Escape", "Back", "OptionsMenu.backOut();"); @@ -74,19 +127,81 @@ function OptionsButtonHolder::onWake(%this) function OptionsMenu::apply(%this) { - if(%this.pageTabIndex == 0) + //Now we run through our list of unapplied changes and... apply them. + %hasKeybindChanges = false; + %hasVideoChanges = false; + %hasPostFXChanges = false; + %hasAudioChanges = false; + for(%i=0; %i < %this.unappliedChanges.count(); %i++) { - %this.applyDisplaySettings(); + %targetVar = %this.unappliedChanges.getKey(%i); + %newValue = %this.unappliedChanges.getValue(%i); + + //First, lets just check through our action map names, see if any match + %wasKeybind = false; + for(%am=0; %am < ActionMapGroup.getCount(); %am++) + { + %actionMap = ActionMapGroup.getObject(%am); + + if(%actionMap == GlobalActionMap.getId()) + continue; + + %actionMapName = %actionMap.humanReadableName $= "" ? %actionMap.getName() : %actionMap.humanReadableName; + if(%actionMapName $= %targetVar) + { + %hasKeybindChanges = true; + %wasKeybind = true; + break; + } + } + + if(!%wasKeybind) + { + %currentValue = getVariable(%targetVar); + if(%currentValue !$= %newValue) + { + setVariable(%targetVar, %newValue); + + //now, lets check for special cases that need additional handling + //for updates + if ( %targetVar $= "$pref::Video::displayDevice" ) + { + MessageBoxOK( "Change requires restart", "Please restart the game for a display device change to take effect." ); + } + else if(startsWith(%targetVar, "$pref::Graphics::")) + { + //isolate the quality group name, like $pref::Graphics::LightingQuality + //we grab LightingQuality + %qualityGroupName = getSubStr(%targetVar, 17); + if(isObject(%qualityGroupName @ "List")) + { + //yep, it's a quality group, so apply it + (%qualityGroupName @ "List").applySetting(%newValue); + } + + if(%qualityGroupName $= "TextureQuality") + { + reloadTextures(); + } + } + else if(startsWith(%targetVar, "$pref::PostFX::")) + { + %hasPostFXChanges = true; + } + else if(startsWith(%targetVar, "$pref::Video::")) + { + %hasVideoChanges = true; + } + else if(startsWith(%targetVar, "$pref::SFX::")) + { + %hasAudioChanges = true; + } + } + } } - else if(%this.pageTabIndex == 1) - { - %this.applyGraphicsSettings(); - } - else if(%this.pageTabIndex == 2) - { - %this.applyAudioSettings(); - } - else if(%this.pageTabIndex == 3 || %this.pageTabIndex == 4) + + //If we had keybind changes, go ahead and save those out + if(%hasKeybindChanges) { %prefPath = getPrefpath(); @@ -108,8 +223,26 @@ function OptionsMenu::apply(%this) } } + if(%hasPostFXChanges) + { + updatePostFXSettings(); + } + + if(%hasVideoChanges) + { + updateDisplaySettings(); + } + + if(%hasAudioChanges) + { + updateAudioSettings(); + } + + //Finally, write our prefs to file %prefPath = getPrefpath(); export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false); + + OptionsMenu.unappliedChanges.empty(); } function OptionsMenu::resetToDefaults(%this) @@ -117,77 +250,9 @@ function OptionsMenu::resetToDefaults(%this) MessageBoxOKCancel("", "This will set the graphical settings back to the auto-detected defaults. Do you wish to continue?", "AutodetectGraphics();", ""); } -function OptionsMenuSettingsList::onChange(%this) -{ - %optionName = %this.getRowLabel(%this.getSelectedRow()); - %tooltipText = %this.getTooltip(%this.getSelectedRow()); - - OptionName.setText(%optionName); - OptionDescription.setText(%tooltipText); - return; - - OptionsMenuSettingsList.clearOptions(); - - %currentRowText = %this.getRowLabel(%this.getSelectedRow()); - - if(%currentRowText $= "Display") - { - populateDisplaySettingsList(); - } - else if(%currentRowText $= "Graphics") - { - populateGraphicsSettingsList(); - } - else if(%currentRowText $= "Audio") - { - populateAudioSettingsList(); - } - else if(%currentRowText $= "Keyboard + Mouse") - { - populateKeyboardMouseSettingsList(); - } - else if(%currentRowText $= "Gamepad") - { - populateGamepadSettingsList(); - } -} - -function OptionsMenu::prevTab(%this) -{ - %this.pageTabIndex--; - if(%this.pageTabIndex < 0) - %this.pageTabIndex = 4; - - %tabBtn = %this.getTab(); - %tabBtn.performClick(); -} - -function OptionsMenu::nextTab(%this) -{ - %this.pageTabIndex++; - if(%this.pageTabIndex > 4) - %this.pageTabIndex = 0; - - %tabBtn = %this.getTab(); - %tabBtn.performClick(); -} - -function OptionsMenu::getTab(%this) -{ - if(%this.pageTabIndex == 0) - return %this-->DisplayButton; - else if(%this.pageTabIndex == 1) - return %this-->GraphicsButton; - else if(%this.pageTabIndex == 2) - return %this-->AudioButton; - else if(%this.pageTabIndex == 3) - return %this-->KBMButton; - else if(%this.pageTabIndex == 4) - return %this-->GamepadButton; - else - return %this-->DisplayButton; -} - +// +// +// function populateDisplaySettingsList() { OptionsMenuSettingsList.clear(); @@ -220,7 +285,7 @@ function populateDisplaySettingsList() trim(%apiList); - OptionsMenuSettingsList.addOptionRow("Display API", %apiList, false, "", true, "The display API used for rendering.", %displayDevice); + OptionsMenuSettingsList.addOptionRow("Display API", "$pref::Video::DisplayAPI", %apiList, false, "", true, "The display API used for rendering.", %displayDevice); %numDevices = Canvas.getMonitorCount(); %devicesList = ""; @@ -234,7 +299,7 @@ function populateDisplaySettingsList() } %selectedDevice = getField(%devicesList, $pref::Video::deviceId); - OptionsMenuSettingsList.addOptionRow("Display Device", %devicesList, false, "onDisplayModeChange", true, "The display devices the window should be on.", %selectedDevice); + OptionsMenuSettingsList.addOptionRow("Display Device", "$pref::Video::deviceId", %devicesList, false, "", true, "The display devices the window should be on.", %selectedDevice); if (%numDevices > 1) OptionsMenuSettingsList.setRowEnabled(1, true); @@ -242,10 +307,10 @@ function populateDisplaySettingsList() OptionsMenuSettingsList.setRowEnabled(1, false); %mode = getField($Video::ModeTags, $pref::Video::deviceMode); - OptionsMenuSettingsList.addOptionRow("Window Mode", $Video::ModeTags, false, "onDisplayModeChange", true, "", %mode); + OptionsMenuSettingsList.addOptionRow("Window Mode", "$pref::Video::deviceMode", $Video::ModeTags, false, "", true, "", %mode); %resolutionList = getScreenResolutionList($pref::Video::deviceId, $pref::Video::deviceMode); - OptionsMenuSettingsList.addOptionRow("Resolution", %resolutionList, false, "onDisplayResChange", true, "Resolution of the game window", _makePrettyResString( $pref::Video::mode )); + OptionsMenuSettingsList.addOptionRow("Resolution", "$pref::Video::Resolution", %resolutionList, false, "onDisplayResChange", true, "Resolution of the game window", _makePrettyResString( $pref::Video::mode )); //If they're doing borderless, the window resolution must match the display resolution if(%mode !$= "Borderless") @@ -253,20 +318,20 @@ function populateDisplaySettingsList() else OptionsMenuSettingsList.setRowEnabled(3, false); - OptionsMenuSettingsList.addOptionRow("VSync", "No\tYes", false, "", true, "", convertBoolToYesNo(!$pref::Video::disableVerticalSync)); + OptionsMenuSettingsList.addOptionRow("VSync", "$pref::Video::disableVerticalSync", "No\tYes", false, "", true, "", convertBoolToYesNo(!$pref::Video::disableVerticalSync)); %refreshList = getScreenRefreshList($pref::Video::mode); - OptionsMenuSettingsList.addOptionRow("Refresh Rate", %refreshList, false, "", true, "", $pref::Video::RefreshRate); + OptionsMenuSettingsList.addOptionRow("Refresh Rate", "$pref::Video::RefreshRate", %refreshList, false, "", true, "", $pref::Video::RefreshRate); //move to gameplay tab - OptionsMenuSettingsList.addSliderRow("Field of View", 75, 5, "65 100", ""); + OptionsMenuSettingsList.addSliderRow("Field of View", "", 75, 5, "65 100", ""); - OptionsMenuSettingsList.addSliderRow("Brightness", 0.5, 0.1, "0 1", ""); - OptionsMenuSettingsList.addSliderRow("Contrast", 0.5, 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("Brightness", "", 0.5, 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("Contrast", "", 0.5, 0.1, "0 1", ""); } -function OptionsMenu::applyDisplaySettings(%this) +/*function OptionsMenu::applyDisplaySettings(%this) { %newDevice = OptionsMenuSettingsList.getCurrentOption(0); @@ -285,9 +350,12 @@ function OptionsMenu::applyDisplaySettings(%this) echo("Exporting client prefs"); %prefPath = getPrefpath(); export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false); -} +}*/ -function populateGraphicsSettingsList(%this) +// +// +// +function populateGraphicsSettingsList() { OptionsMenuSettingsList.clear(); @@ -299,90 +367,32 @@ function populateGraphicsSettingsList(%this) %highMedLow = "Low\tMedium\tHigh"; %anisoFilter = "Off\t4\t8\t16"; %aaFilter = "Off\t1\t2\t4"; - OptionsMenuSettingsList.addOptionRow("Lighting Quality", getQualityLevels(LightingQualityList), false, "", true, "Amount and drawdistance of local lights", getCurrentQualityLevel(LightingQualityList)); - OptionsMenuSettingsList.addOptionRow("Shadow Quality", getQualityLevels(ShadowQualityList), false, "", true, "Shadow revolution quality", getCurrentQualityLevel(ShadowQualityList)); - OptionsMenuSettingsList.addOptionRow("Soft Shadow Quality", getQualityLevels(SoftShadowList), false, "", true, "Amount of softening applied to shadowmaps", getCurrentQualityLevel(SoftShadowList)); - OptionsMenuSettingsList.addOptionRow("Mesh Quality", getQualityLevels(MeshQualityGroup), false, "", true, "Fidelity of rendering of mesh objects", getCurrentQualityLevel(MeshQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Object Draw Distance", getQualityLevels(MeshDrawDistQualityGroup), false, "", true, "Dictates if and when static objects fade out in the distance", getCurrentQualityLevel(MeshDrawDistQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Texture Quality", getQualityLevels(TextureQualityGroup), false, "", true, "Fidelity of textures", getCurrentQualityLevel(TextureQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Terrain Quality", getQualityLevels(TerrainQualityGroup), false, "", true, "Quality level of terrain objects", getCurrentQualityLevel(TerrainQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Decal Lifetime", getQualityLevels(DecalLifetimeGroup), false, "", true, "How long decals are rendered", getCurrentQualityLevel(DecalLifetimeGroup)); - OptionsMenuSettingsList.addOptionRow("Ground Cover Density", getQualityLevels(GroundCoverDensityGroup), false, "", true, "Density of ground cover items, such as grass", getCurrentQualityLevel(GroundCoverDensityGroup)); - OptionsMenuSettingsList.addOptionRow("Shader Quality", getQualityLevels(ShaderQualityGroup), false, "", true, "Dictates the overall shader quality level, adjusting what features are enabled.", getCurrentQualityLevel(ShaderQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Anisotropic Filtering", %anisoFilter, false, "", true, "Amount of Anisotropic Filtering on textures, which dictates their sharpness at a distance", $pref::Video::defaultAnisotropy); - OptionsMenuSettingsList.addOptionRow("Anti-Aliasing", %aaFilter, false, "", true, "Amount of Post-Processing Anti-Aliasing applied to rendering", $pref::Video::AA); - OptionsMenuSettingsList.addOptionRow("Parallax", %onOffList, false, "", true, "Whether the surface parallax shader effect is enabled", convertBoolToOnOff(!$pref::Video::disableParallaxMapping)); - OptionsMenuSettingsList.addOptionRow("Water Reflections", %onOffList, false, "", true, "Whether water reflections are enabled", convertBoolToOnOff(!$pref::Water::disableTrueReflections)); - OptionsMenuSettingsList.addOptionRow("SSAO", %onOffList, false, "", true, "Whether Screen-Space Ambient Occlusion is enabled", convertBoolToOnOff($pref::PostFX::EnableSSAO)); - OptionsMenuSettingsList.addOptionRow("Depth of Field", %onOffList, false, "", true, "Whether the Depth of Field effect is enabled", convertBoolToOnOff($pref::PostFX::EnableDOF)); - OptionsMenuSettingsList.addOptionRow("Vignette", %onOffList, false, "", true, "Whether the vignette effect is enabled", convertBoolToOnOff($pref::PostFX::EnableVignette)); - OptionsMenuSettingsList.addOptionRow("Light Rays", %onOffList, false, "", true, "Whether the light rays effect is enabled", convertBoolToOnOff($pref::PostFX::EnableLightRays)); + OptionsMenuSettingsList.addOptionRow("Lighting Quality", "$pref::Graphics::LightingQuality", getQualityLevels(LightingQualityList), false, "", true, "Amount and drawdistance of local lights", getCurrentQualityLevel(LightingQualityList)); + OptionsMenuSettingsList.addOptionRow("Shadow Quality", "$pref::Graphics::ShadowQuality", getQualityLevels(ShadowQualityList), false, "", true, "Shadow revolution quality", getCurrentQualityLevel(ShadowQualityList)); + OptionsMenuSettingsList.addOptionRow("Soft Shadow Quality", "$pref::Graphics::SoftShadowQuality", getQualityLevels(SoftShadowList), false, "", true, "Amount of softening applied to shadowmaps", getCurrentQualityLevel(SoftShadowList)); + OptionsMenuSettingsList.addOptionRow("Mesh Quality", "$pref::Graphics::MeshQuality", getQualityLevels(MeshQualityGroup), false, "", true, "Fidelity of rendering of mesh objects", getCurrentQualityLevel(MeshQualityGroup)); + OptionsMenuSettingsList.addOptionRow("Object Draw Distance", "$pref::Graphics::ObjectDrawDistance", getQualityLevels(MeshDrawDistQualityGroup), false, "", true, "Dictates if and when static objects fade out in the distance", getCurrentQualityLevel(MeshDrawDistQualityGroup)); + OptionsMenuSettingsList.addOptionRow("Texture Quality", "$pref::Graphics::TextureQuality", getQualityLevels(TextureQualityGroup), false, "", true, "Fidelity of textures", getCurrentQualityLevel(TextureQualityGroup)); + OptionsMenuSettingsList.addOptionRow("Terrain Quality", "$pref::Graphics::TerrainQuality", getQualityLevels(TerrainQualityGroup), false, "", true, "Quality level of terrain objects", getCurrentQualityLevel(TerrainQualityGroup)); + OptionsMenuSettingsList.addOptionRow("Decal Lifetime", "$pref::Graphics::DecalLifetime", getQualityLevels(DecalLifetimeGroup), false, "", true, "How long decals are rendered", getCurrentQualityLevel(DecalLifetimeGroup)); + OptionsMenuSettingsList.addOptionRow("Ground Cover Density", "$pref::Graphics::GroundCoverDensity", getQualityLevels(GroundCoverDensityGroup), false, "", true, "Density of ground cover items, such as grass", getCurrentQualityLevel(GroundCoverDensityGroup)); + OptionsMenuSettingsList.addOptionRow("Shader Quality", "$pref::Graphics::ShaderQuality", getQualityLevels(ShaderQualityGroup), false, "", true, "Dictates the overall shader quality level, adjusting what features are enabled.", getCurrentQualityLevel(ShaderQualityGroup)); + OptionsMenuSettingsList.addOptionRow("Anisotropic Filtering", "$pref::Video::defaultAnisotropy", %anisoFilter, false, "", true, "Amount of Anisotropic Filtering on textures, which dictates their sharpness at a distance", $pref::Video::defaultAnisotropy); + OptionsMenuSettingsList.addOptionRow("Anti-Aliasing", "$pref::Video::AA", %aaFilter, false, "", true, "Amount of Post-Processing Anti-Aliasing applied to rendering", $pref::Video::AA); + OptionsMenuSettingsList.addOptionRow("Parallax", "$pref::Video::disableParallaxMapping", %onOffList, false, "", true, "Whether the surface parallax shader effect is enabled", convertBoolToOnOff(!$pref::Video::disableParallaxMapping)); + OptionsMenuSettingsList.addOptionRow("Water Reflections", "$pref::Water::disableTrueReflections", %onOffList, false, "", true, "Whether water reflections are enabled", convertBoolToOnOff(!$pref::Water::disableTrueReflections)); + OptionsMenuSettingsList.addOptionRow("SSAO", "$pref::PostFX::EnableSSAO", %onOffList, false, "", true, "Whether Screen-Space Ambient Occlusion is enabled", convertBoolToOnOff($pref::PostFX::EnableSSAO)); + OptionsMenuSettingsList.addOptionRow("Depth of Field", "$pref::PostFX::EnableDOF", %onOffList, false, "", true, "Whether the Depth of Field effect is enabled", convertBoolToOnOff($pref::PostFX::EnableDOF)); + OptionsMenuSettingsList.addOptionRow("Vignette", "$pref::PostFX::EnableVignette", %onOffList, false, "", true, "Whether the vignette effect is enabled", convertBoolToOnOff($pref::PostFX::EnableVignette)); + OptionsMenuSettingsList.addOptionRow("Light Rays", "$pref::PostFX::EnableLightRays", %onOffList, false, "", true, "Whether the light rays effect is enabled", convertBoolToOnOff($pref::PostFX::EnableLightRays)); } -function OptionsMenu::applyGraphicsSettings(%this) -{ - LightingQualityList.applySetting(OptionsMenuSettingsList.getCurrentOption(0)); - ShadowQualityList.applySetting(OptionsMenuSettingsList.getCurrentOption(1)); - SoftShadowList.applySetting(OptionsMenuSettingsList.getCurrentOption(2)); - - MeshQualityGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(3)); - MeshDrawDistQualityGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(4)); - TextureQualityGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(5)); - TerrainQualityGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(6)); - DecalLifetimeGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(7)); - GroundCoverDensityGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(8)); - ShaderQualityGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(9)); - - //Update Textures - reloadTextures(); - - //Update lighting - // Set the light manager. This should do nothing - // if its already set or if its not compatible. - //setLightManager( $pref::lightManager ); - - $pref::PostFX::EnableSSAO = convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(14)); - $pref::PostFX::EnableDOF = convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(15)); - $pref::PostFX::EnableVignette = convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(16)); - $pref::PostFX::EnableLightRays = convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(17)); - - PostFXManager.settingsEffectSetEnabled(SSAOPostFx, $pref::PostFX::EnableSSAO); - PostFXManager.settingsEffectSetEnabled(DOFPostEffect, $pref::PostFX::EnableDOF); - PostFXManager.settingsEffectSetEnabled(LightRayPostFX, $pref::PostFX::EnableLightRays); - PostFXManager.settingsEffectSetEnabled(vignettePostFX, $pref::PostFX::EnableVignette); - - $pref::Video::disableParallaxMapping = !convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(12)); - - //water reflections - $pref::Water::disableTrueReflections = !convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(13)); - - // Check the anisotropic filtering. - %level = OptionsMenuSettingsList.getCurrentOption(10); - if ( %level != $pref::Video::defaultAnisotropy ) - { - $pref::Video::defaultAnisotropy = %level; - } - - %newFSAA = OptionsMenuSettingsList.getCurrentOption(11); - if (%newFSAA $= "off") - %newFSAA = 0; - if (%newFSAA !$= $pref::Video::AA) - { - $pref::Video::AA = %newFSAA; - configureCanvas(); - } - - echo("Exporting client prefs"); - %prefPath = getPrefpath(); - export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false); -} - function updateDisplaySettings() { //Update the display settings now - %deviceName = OptionsMenuSettingsList.getCurrentOption(1); + %deviceName = getDisplayDeviceName(); %newDeviceID = getWord(%deviceName, 0) - 1; - %deviceModeName = OptionsMenuSettingsList.getCurrentOption(2); + %deviceModeName = getField($Video::ModeTags, $pref::Video::deviceMode); %newDeviceMode = 0; foreach$(%modeName in $Video::ModeTags) { @@ -392,15 +402,15 @@ function updateDisplaySettings() %newDeviceMode++; } - %newRes = getWord(OptionsMenuSettingsList.getCurrentOption(3), 0) SPC getWord(OptionsMenuSettingsList.getCurrentOption(3), 2); + %newRes = $pref::Video::Resolution; %newBpp = 32; // ... its not 1997 anymore. %newFullScreen = %deviceModeName $= "Fullscreen" ? true : false; - %newRefresh = OptionsMenuSettingsList.getCurrentOption(5); - %newVsync = !convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(4)); + %newRefresh = $pref::Video::RefreshRate; + %newVsync = !$pref::Video::disableVerticalSync; %newFSAA = $pref::Video::AA; // Build the final mode string. - %newMode = %newRes SPC %newFullScreen SPC %newBpp SPC %newRefresh SPC %newFSAA; + %newMode = $pref::Video::Resolution SPC %newFullScreen SPC %newBpp SPC %newRefresh SPC %newFSAA; // Change the video mode. if ( %newMode !$= $pref::Video::mode || %newDeviceID != $pref::Video::deviceId || @@ -433,7 +443,18 @@ function updateDisplaySettings() } } -function populateAudioSettingsList(%this) +function updatePostFXSettings() +{ + PostFXManager.settingsEffectSetEnabled(SSAOPostFx, $pref::PostFX::EnableSSAO); + PostFXManager.settingsEffectSetEnabled(DOFPostEffect, $pref::PostFX::EnableDOF); + PostFXManager.settingsEffectSetEnabled(LightRayPostFX, $pref::PostFX::EnableLightRays); + PostFXManager.settingsEffectSetEnabled(vignettePostFX, $pref::PostFX::EnableVignette); +} + +// +// +// +function populateAudioSettingsList() { OptionsMenuSettingsList.clear(); @@ -472,13 +493,13 @@ function populateAudioSettingsList(%this) } } - OptionsMenuSettingsList.addOptionRow("Audio Provider", %audioProviderList, false, "audioProviderChanged", true, "", $currentAudioProvider); - OptionsMenuSettingsList.addOptionRow("Audio Device", %audioDeviceList, false, "", true, $pref::SFX::device); + OptionsMenuSettingsList.addOptionRow("Audio Provider", "$pref::SFX::AudioProvider", %audioProviderList, false, "audioProviderChanged", true, "", $currentAudioProvider); + OptionsMenuSettingsList.addOptionRow("Audio Device", "$pref::SFX::device", %audioDeviceList, false, "", true, $pref::SFX::device); - OptionsMenuSettingsList.addSliderRow("Master Volume", $pref::SFX::masterVolume, 0.1, "0 1", ""); - OptionsMenuSettingsList.addSliderRow("GUI Volume", $pref::SFX::channelVolume[ $GuiAudioType], 0.1, "0 1", ""); - OptionsMenuSettingsList.addSliderRow("Effects Volume", $pref::SFX::channelVolume[ $SimAudioType ], 0.1, "0 1", ""); - OptionsMenuSettingsList.addSliderRow("Music Volume", $pref::SFX::channelVolume[ $MusicAudioType ], 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("Master Volume", "$pref::SFX::masterVolume", $pref::SFX::masterVolume, 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("GUI Volume", "$pref::SFX::channelVolume[ $GuiAudioType]", $pref::SFX::channelVolume[ $GuiAudioType], 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("Effects Volume", "$pref::SFX::channelVolume[ $SimAudioType ]", $pref::SFX::channelVolume[ $SimAudioType ], 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("Music Volume", "$pref::SFX::channelVolume[ $MusicAudioType ]", $pref::SFX::channelVolume[ $MusicAudioType ], 0.1, "0 1", ""); } function audioProviderChanged() @@ -491,21 +512,21 @@ function audioProviderChanged() populateAudioSettingsList(); } -function OptionsMenu::applyAudioSettings(%this) +function updateAudioSettings() { - $pref::SFX::masterVolume = OptionsMenuSettingsList.getValue(2); + //$pref::SFX::masterVolume = OptionsMenuSettingsList.getValue(2); sfxSetMasterVolume( $pref::SFX::masterVolume ); - $pref::SFX::channelVolume[ $GuiAudioType ] = OptionsMenuSettingsList.getValue(3); - $pref::SFX::channelVolume[ $SimAudioType ] = OptionsMenuSettingsList.getValue(4); - $pref::SFX::channelVolume[ $MusicAudioType ] = OptionsMenuSettingsList.getValue(5); + //$pref::SFX::channelVolume[ $GuiAudioType ] = OptionsMenuSettingsList.getValue(3); + //$pref::SFX::channelVolume[ $SimAudioType ] = OptionsMenuSettingsList.getValue(4); + //$pref::SFX::channelVolume[ $MusicAudioType ] = OptionsMenuSettingsList.getValue(5); sfxSetChannelVolume( $GuiAudioType, $pref::SFX::channelVolume[ $GuiAudioType ] ); sfxSetChannelVolume( $SimAudioType, $pref::SFX::channelVolume[ $SimAudioType ] ); sfxSetChannelVolume( $MusicAudioType, $pref::SFX::channelVolume[ $MusicAudioType ] ); - $pref::SFX::provider = OptionsMenuSettingsList.getCurrentOption(0); - $pref::SFX::device = OptionsMenuSettingsList.getCurrentOption(1); + //$pref::SFX::provider = OptionsMenuSettingsList.getCurrentOption(0); + //$pref::SFX::device = OptionsMenuSettingsList.getCurrentOption(1); if ( !sfxCreateDevice( $pref::SFX::provider, $pref::SFX::device, @@ -521,7 +542,10 @@ function OptionsMenu::applyAudioSettings(%this) } } -function populateKeyboardMouseSettingsList(%this) +// +// +// +function populateKeyboardMouseSettingsList() { OptionsMenuSettingsList.clear(); @@ -534,7 +558,7 @@ function populateKeyboardMouseSettingsList(%this) //OptionsMenuSettingsList.refresh(); } -function populateGamepadSettingsList(%this) +function populateGamepadSettingsList() { OptionsMenuSettingsList.clear(); @@ -544,15 +568,30 @@ function populateGamepadSettingsList(%this) $remapListDevice = "gamepad"; fillRemapList(); - OptionsMenuSettingsList.refresh(); + OptionsMenuSettingsList.updateStack(); } +// +// +// function OptionsMenuList::activateRow(%this) { OptionsMenuSettingsList.setFirstResponder(); } function OptionsMenu::backOut(%this) +{ + if(%this.unappliedChanges.count() != 0) + { + MessageBoxOKCancel("Discard Changes?", "You have unapplied changes to your settings, do you wish to continue?", "OptionsMenu.doOptionsMenuBackOut();", ""); + } + else + { + %this.doOptionsMenuBackOut(); + } +} + +function OptionsMenu::doOptionsMenuBackOut(%this) { //save the settings and then back out if(OptionsMain.hidden == false) @@ -583,7 +622,7 @@ function OptionsMenuSettingsList::setRowEnabled(%this, %row, %status) } } -function OptionsMenuSettingsList::addOptionRow(%this, %label, %optionsList, %wrapOptions, %callback, %enabled, %description, %defaultValue) +function OptionsMenuSettingsList::addOptionRow(%this, %label, %targetPrefVar, %optionsList, %wrapOptions, %callback, %enabled, %description, %defaultValue) { if(%enabled $= "") %enabled = true; @@ -600,14 +639,27 @@ function OptionsMenuSettingsList::addOptionRow(%this, %label, %optionsList, %wra extent = %this.extent.x SPC %optionsRowSize; columnSplit = %optionColumnWidth; useMouseEvents = true; + previousBitmapAsset = "UI:previousOption_n_image"; + nextBitmapAsset = "UI:nextOption_n_image"; }; + %option.targetPrefVar = %targetPrefVar; //create a var-option association + + //now some override trickery, if we have a value cached for unapplied changes, swapsies the defaultValue out + //with the unapplied, allowing us to change options categories without losing changes + %unappliedPrefIndex = OptionsMenu.unappliedChanges.getIndexFromValue(%targetPrefVar); + if(%unappliedPrefIndex != -1) + { + %unappliedValue = OptionsMenu.unappliedChanges.getValue(%unappliedPrefIndex); + %defaultValue = %unappliedValue; + } + %option.setListSetting(%label, %optionsList, %wrapOptions, %callback, %enabled, %description, %defaultValue); %this.add(%option); } -function OptionsMenuSettingsList::addSliderRow(%this, %label, %defaultValue, %increment, %range, %callback, %enabled, %description) +function OptionsMenuSettingsList::addSliderRow(%this, %label, %targetPrefVar, %defaultValue, %increment, %range, %callback, %enabled, %description) { if(%enabled $= "") %enabled = true; @@ -626,11 +678,46 @@ function OptionsMenuSettingsList::addSliderRow(%this, %label, %defaultValue, %in useMouseEvents = true; }; + %option.targetPrefVar = %targetPrefVar; //create a var-option association + + //now some override trickery, if we have a value cached for unapplied changes, swapsies the defaultValue out + //with the unapplied, allowing us to change options categories without losing changes + %unappliedPrefIndex = OptionsMenu.unappliedChanges.getIndexFromValue(%targetPrefVar); + if(%unappliedPrefIndex != -1) + { + %unappliedValue = OptionsMenu.unappliedChanges.getValue(%unappliedPrefIndex); + %defaultValue = %unappliedValue; + } + %option.setSliderSetting(%label, %defaultValue, %increment, %range, %callback, %enabled, %description); %this.add(%option); } +function OptionsMenuSettingsList::addKeybindRow(%this, %label, %bitmapName, %callback, %enabled, %description) +{ + if(%enabled $= "") + %enabled = true; + + %optionsRowSize = 40; + %optionColumnWidth = %this.extent.x - 450; + + %option = new GuiGameSettingsCtrl() { + class = "MenuOptionsButton"; + profile = "GuiMenuButtonProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "0 0"; + extent = %this.extent.x SPC %optionsRowSize; + columnSplit = %optionColumnWidth; + useMouseEvents = true; + }; + + %option.setKeybindSetting(%label, %bitmapName, %callback, %enabled, %description); + + %this.add(%option); +} + // function OptionsMenuCategoryList::onNavigate(%this, %index) { @@ -738,6 +825,24 @@ function onDisplayResChange(%val) OptionsMenuSettingsList.selectOption(5, %newRate); } +function getDisplayDeviceName() +{ + %numDevices = Canvas.getMonitorCount(); + %devicesList = ""; + for(%i = 0; %i < %numDevices; %i++) + { + %device = (%i+1) @ " - " @ Canvas.getMonitorName(%i); + if(%i==0) + %devicesList = %device; + else + %devicesList = %devicesList @ "\t" @ %device; + } + + return getField(%devicesList, $pref::Video::deviceId); +} +// +// +// function MenuOptionsButton::onMouseEnter(%this) { OptionName.setText(%this.getLabel()); @@ -748,4 +853,84 @@ function MenuOptionsButton::onMouseLeave(%this) { OptionName.setText(""); OptionDescription.setText(""); -} \ No newline at end of file +} + +function MenuOptionsButton::onChange(%this) +{ + %optionMode = %this.getMode(); + %optionName = %this.getLabel(); + %tooltipText = %this.getTooltip(); + + %targetVar = %this.targetPrefVar; + + OptionName.setText(%optionName); + OptionDescription.setText(%tooltipText); + + %currentValue = %this.getCurrentOption(); + if(%currentValue !$= "") + { + if(%currentValue $= "yes" || %currentValue $= "on") + %saveReadyValue = 1; + else if(%currentValue $= "no" || %currentValue $= "off") + %saveReadyValue = 0; + else + %saveReadyValue = %currentValue; + + %prefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetVar); + if(%prefIndex == -1) + OptionsMenu.unappliedChanges.add(%targetVar, %saveReadyValue); + else + OptionsMenu.unappliedChanges.setValue(%saveReadyValue, %prefIndex); + } +} + +function OptionsMenu::onKeybindChanged(%this, %actionMap, %keybind) +{ + %prefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%actionMap); + if(%prefIndex == -1) + OptionsMenu.unappliedChanges.add(%actionMap, %keybind); + else + OptionsMenu.unappliedChanges.setValue(%keybind, %prefIndex); +} + +// +// Indicates what category the options item should be added into +// +function addOptionsMenuCategory(%categoryName, %selectCallback) +{ + OptionsMenu.optionsCategories.add(%categoryName, %selectCallback); +} + +function removeOptionsMenuCategory(%categoryName) +{ + %index = OptionsMenu.optionsCategories.getIndexFromKey(%categoryName); + if(%index != -1) + OptionsMenu.optionsCategories.erase(%index); +} + +function addListOption(%label, %description, %targetPrefVar, %optionsList, %wrapOptions, %callback, %enabled) +{ + if(%wrapOptions $= "") + %wrapOptions = false; + + if(%enabled $= "") + %enabled = true; + + OptionsMenuSettingsList.addOptionRow(%label, %targetPrefVar, %optionsList, %wrapOptions, %callback, %enabled, %description, %targetPrefVar); +} + +function addSliderOption(%label, %description, %targetPrefVar, %defaultValue, %increment, %range, %callback, %enabled) +{ + if(%enabled $= "") + %enabled = true; + + OptionsMenuSettingsList.addSliderRow(%label, %targetPrefVar, %defaultValue, %increment, %range, %callback, %enabled, %description); +} + +function addKeybindOption(%label, %description, %bitmapName, %callback, %enabled) +{ + if(%enabled $= "") + %enabled = true; + + OptionsMenuSettingsList.addSliderRow(%label, %bitmapName, %callback, %enabled, %description); +} diff --git a/Templates/BaseGame/game/data/UI/guis/pauseMenu.gui b/Templates/BaseGame/game/data/UI/guis/pauseMenu.gui index 77356fcdb..0ba6e7ce5 100644 --- a/Templates/BaseGame/game/data/UI/guis/pauseMenu.gui +++ b/Templates/BaseGame/game/data/UI/guis/pauseMenu.gui @@ -49,25 +49,31 @@ $guiContent = new GuiControl(PauseMenu) { isContainer = "1"; canSave = "1"; canSaveDynamicFields = "0"; - - new GuiGameListMenuCtrl(PauseMenuList) { - debugRender = "0"; - callbackOnInputs = "1"; - consumeKeyInputEvents = "1"; + + new GuiStackControl(PauseMenuList) { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "15"; + dynamicSize = "0"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; position = "0 0"; extent = "700 320"; - minExtent = "8 2"; - horizSizing = "width"; - vertSizing = "bottom"; - profile = "DefaultListMenuProfile"; + minExtent = "16 16"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; visible = "1"; active = "1"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; - isContainer = "0"; - class = "UIMenuButtonList"; + isContainer = "1"; canSave = "1"; canSaveDynamicFields = "0"; + class = "MenuList"; }; }; new GuiControl(PauseButtonHolder) { @@ -147,5 +153,26 @@ $guiContent = new GuiControl(PauseMenu) { canSaveDynamicFields = "0"; }; }; + new GuiInputCtrl(PauseMenuInputHandler) { + class = "MenuInputHandler"; + sendAxisEvents = "1"; + sendBreakEvents = "1"; + sendModifierEvents = "0"; + ignoreMouseEvents = "1"; + lockMouse = "0"; + position = "-50 0"; + extent = "10 10"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiInputCtrlProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; //--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/UI/guis/pauseMenu.tscript b/Templates/BaseGame/game/data/UI/guis/pauseMenu.tscript index 8d23b95d2..8751c16ef 100644 --- a/Templates/BaseGame/game/data/UI/guis/pauseMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/pauseMenu.tscript @@ -8,19 +8,21 @@ function PauseMenu::onWake(%this) } PauseMenuList.hidden = false; - PauseMenuList.setFirstResponder(); - PauseButtonHolder.setActive(); - PauseMenuList.clearRows(); + PauseMenuList.clear(); if($Tools::loaded && EditorIsActive()) { - PauseMenuList.addRow("Exit Editor", "fastLoadWorldEdit", -1, -30); + %this.addPauseMenuButton("Exit Editor", "fastLoadWorldEdit();"); } - PauseMenuList.addRow("Options", "openPauseMenuOptions", -1, -30); - PauseMenuList.addRow("Exit to Menu", "pauseMenuExitToMenu", -1, -30); - PauseMenuList.addRow("Exit to Desktop", "pauseMenuExitToDesktop", -1, -30); + %this.addPauseMenuButton("Options", "openPauseMenuOptions();"); + %this.addPauseMenuButton("Exit to Menu", "pauseMenuExitToMenu();"); + %this.addPauseMenuButton("Exit to Desktop", "pauseMenuExitToDesktop();"); + + PauseMenuList.setAsActiveMenuList(); + PauseButtonHolder.setActive(); + PauseMenuInputHandler.setFirstResponder(); } @@ -36,8 +38,9 @@ function PauseMenu::onSleep(%this) function PauseMenu::onReturnTo(%this) { PauseMenuList.hidden = false; - PauseMenuList.setFirstResponder(); + PauseMenuList.setAsActiveMenuList(); PauseButtonHolder.setActive(); + PauseMenuInputHandler.setFirstResponder(); } function openPauseMenuOptions() @@ -61,6 +64,32 @@ function pauseMenuExitToDesktop() function PauseButtonHolder::onWake(%this) { - %this-->goButton.set("btn_a", "Return", "OK", "PauseMenuList.activateRow();", true); + %this-->goButton.set("btn_a", "Return", "OK", "PauseMenuList.activate();", true); %this-->backButton.set("btn_b", "Escape", "Back", "Canvas.popDialog();"); -} \ No newline at end of file +} + +function PauseMenu::addPauseMenuButton(%this, %buttonText, %buttonCallback) +{ + %newButton = new GuiButtonCtrl() { + text = %buttonText; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 0"; + extent = "400 55"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = %buttonCallback; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + PauseMenuList.add(%newButton); +} diff --git a/Templates/BaseGame/game/data/UI/guis/profiler.tscript b/Templates/BaseGame/game/data/UI/guis/profiler.tscript index a13d7d9b5..56f88a189 100644 --- a/Templates/BaseGame/game/data/UI/guis/profiler.tscript +++ b/Templates/BaseGame/game/data/UI/guis/profiler.tscript @@ -363,4 +363,4 @@ function metrics( %expr ) } else $GameCanvas.popDialog(FrameOverlayGui); -} \ No newline at end of file +} diff --git a/Templates/BaseGame/game/data/UI/guis/recordingsDlg.asset.taml b/Templates/BaseGame/game/data/UI/guis/recordingsDlg.asset.taml index 7cc7b2168..2b0c337b5 100644 --- a/Templates/BaseGame/game/data/UI/guis/recordingsDlg.asset.taml +++ b/Templates/BaseGame/game/data/UI/guis/recordingsDlg.asset.taml @@ -1,7 +1,4 @@ + VersionId="1"/> diff --git a/Templates/BaseGame/game/data/UI/guis/startupGui.gui b/Templates/BaseGame/game/data/UI/guis/startupGui.gui index 647fc1b03..13f2460e3 100644 --- a/Templates/BaseGame/game/data/UI/guis/startupGui.gui +++ b/Templates/BaseGame/game/data/UI/guis/startupGui.gui @@ -35,7 +35,7 @@ $guiContent = new GuiFadeinBitmapCtrl(StartupGui) { Visible = "1"; tooltipprofile = "GuiToolTipProfile"; hovertime = "1000"; - bitmap = ""; + bitmapAsset = ""; wrap = "0"; command = "StartupGui.click();"; }; @@ -54,7 +54,7 @@ $guiContent = new GuiFadeinBitmapCtrl(StartupGui) { Visible = "1"; tooltipprofile = "GuiToolTipProfile"; hovertime = "1000"; - bitmap = ""; + bitmapAsset = ""; wrap = "0"; command = "StartupGui.click();"; }; diff --git a/Templates/BaseGame/game/data/UI/guis/startupGui.tscript b/Templates/BaseGame/game/data/UI/guis/startupGui.tscript index af673c819..a89226d70 100644 --- a/Templates/BaseGame/game/data/UI/guis/startupGui.tscript +++ b/Templates/BaseGame/game/data/UI/guis/startupGui.tscript @@ -32,7 +32,7 @@ function loadStartup() // A list of the splash screens and logos // to cycle through. Note that they have to // be in consecutive numerical order - StartupGui.bitmap[0] = "UI:background_dark_image"; + StartupGui.bitmap[0] = "UI:backgrounddark_image"; StartupGui.logo[0] = "UI:Torque_3D_logo_alt_image"; StartupGui.logoPos[0] = "178 251"; StartupGui.logoExtent[0] = "443 139"; diff --git a/Templates/BaseGame/game/data/UI/images/Torque-3D-logo-shortcut.png b/Templates/BaseGame/game/data/UI/images/Torque-3D-logo-shortcut.png deleted file mode 100644 index d993d4893f9112747e2099c1f111877db4064a86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10728 zcmZ8nWmFqov<=0zxJz*;6nB^4E`dUeyG!w+#a#jvDeggwyF+mZ?p}(!6@BUV-mkZ^ zlF7O=*N)9O`|e0}RXI#FQZxVnfTb1))(4+ecc(+DD>mF4GBVHs{h7#&{7tjU(Pe!Z&5X{q|SV z(+Fuwe!n#qKj>Zl3NDZdt_UrkIzX1qPTkR1>hnATqNkzzaXq`<`6o zOvll+_gvXkg?^59?W6m|lHFNd=W}Jp?Q#^hR3AVB1VY3>3hpsZGY(PdHs&BcRUg@9 zfExpNVM`E7tnV(60^VN>8kOos+qdlJ)zq4C5M#(Cjlv7S8PE6S@B=CU0$QcIb~ueD z)VrVN_k*Q6^et=6{ylb~<60t`^n-*Dj+NkWP8Pu-a(Q7i>W(JRHEnm&{1h^;en6J-_zS4ABU%xYu|MTs zO8HA*!9fg%V~{>nHvh|=DB_xiS_FRS1L5IZXu_$m0-b=2E&rLsHw!??lTK$)DK&M7 zUddsarKu?gF)B@KkyMAzNXd~}9v->nLem$iVkR(*y_xa&NHlpbrPiMsNMRdN7KIKf7X{df*RJK^!(~t43Y-Tp?!LP z?GN2~ekWJ>YUIys3xUip>c@y_uPL~N&$uCzCkHzvbG6t2i0Deh;#F1q)W2z;@!Slw zn{5C5JhDr9T%s1{IyUaoCy(ryYGExh4f^V7l?T@pBQmqT z53wKI$q$1j}x5))pm&76`Mj|`jg*4NIq#*{I#4%zTv4`!?lJV%JX8on} z9B%a6QyvOPl}{K}buC5*x|#^IDrBS>pN=opEonJ!7KY1O`{GiSTCtuLyLwn8JpH6$oZd|?l6mrUgdiYE$*c^Qs=bz6s$V(9jT#GxH z;%Q3L$}{OOXr@I1zbSFerSx;=fJMG}QP(+lWec*0d_1714#&@1(fimp#m^gVr>5B@ zf^vr{Uk4}-!Jg5u%o!x+eEYOT(jdTzZLa?h?12t*ax`WGwCAefJRjZSEo1)Z(B zWix5t7C;CB85}?IK(q(zyi%X&G z4Cuw;Hzt7f;NRaFxT zVUkjk$i@DFx0R)umd@^ToGEg=Fg5~#OoT4-f58gjx4FxQML}A&NG=81c0{*u?msqX zyWPxfV62g?kBjLZKravK7GLEfoCndqAD(F;-4VX2&GjdCK~J4EkRz3~6evYQ zILJ_k$V64)M0zPz9C_;;h65LBo-!nv%Yr+vv?Z-b2y=wVn8-4FTb+T{e2kPa#6Br| z&R`t4=HBs3VO`ttk9stx_h22Ld1CxgE`wD7?(LDI2VW!Y(9lW+#8w*R=bNM0Q>|m? zgp03IgyEg>c@S=fC6It%5xYBM*Nj0Zdy=w;4pswhfmZp6;VG?O0#vFyYAF^hY<6Mq z9e;~L_Qzp}tr0IVVQ#QuazVSBqt}b(j)X7L(_MFDcO>amDAB9700D)i-%_U#VjGGj z#oK3|!!BRQ&6J56YS6|uXia=^oQ~4~87=tQrW6}R!QH+S1N2zZWcXf!klJ6hw3KKd zYB{NYI~68Su$}Ore0XKiVICH;(LfFGH?lzlQQGp+@sXpvMwFuSSw%!*|~!ohNn(vD%34$e4)63G7PQV>WRlW_Z*f3rc)}Y)C^{|jpqD|lX4;^OlZ_mHEaeRr0Yo< z$J$Vg?K-{-D zj(4XyStbmZ8ugHq1_|sWy`0zv&)Pc5t5vh1Aim`j7Cc z{LCalW3<)3Ro0)Jd2M*#@f|s#WLl@Bnb4AHh(TuwM{kjUR_sJwhgBZLf0TQ;t@Ap; z_Cs*SPSTjBHtJVoAibq+xy)it2FIr{N<(K()bx5(ziTa^$k+@n*KwDrTu3Y|e`A|1 zACT&3RWH>oLBD}Wfd}#t4-A+rT+!`2B&L1`Cv}$jLVGUSv2R^I)HAp*@9B=Xtkmso z$23{I^{8)KPsZ+L+4>-WJuSj4QLYfNroTq=J*sVc>eVC=WbP_o^RZMn9{KG0} z)T#ww0nUTXkUdk!(Wu}{k&`W-xDYvTVs?aEaijj1{X146lVhUKB6mp;NJquolFG+g z$!vakk6NV~!MC!S@=mB(9Tk{6z*y;w&H_&C(A?oNA)H}4Av?7{@}YkvUC{wm-GcoK z`x=74NP4oO)vI-35a_#cr>Y4biQcJ9(B!PnD3*Cf4n?N(;ZZFFQsQH;)faTW7yM2{ z5#Ke2vc^aWe=9`=W%Br*N;aTbfFm@QIh4{FOZWG%&B738@@g0%^J*%xx`dU(;P`QQ z(1ZX5Wx_ml{4>V8G`{z}Lp`AsaiHd}_VUQgEQQEI8odrwG|5Im`f(#acPvWwfi z8kB0yk=EoQl(Xa>&++eEEh#WZFk8P284jWs z9!8zpY!9>KMIU;+W+DLm5+T%zgC~qk8?zUn4H>%2u$K<;#ObJfR?)wS#LlN4e=32Z zGH2fY-7))m5ue#~uG5C-7RP#NHt35sVIo5t`6xKpnoZwh77L|rPtj!X?B^K%j6{{T z%B?&v!UFH@#Uf}@cfCFpAqAQ%Q1B2d^g5oG>^Sb2SvZgD&8g_I5d9g-#q%Mn*HESh zHbtUBQT$(bH%w-a9Umq9G_o+~jfCzrgX}-krrE|Zmpn+fg{~kFnH&BDXNV_?1xdGP zuqzg^1(QC#h&gm;T{xXi8zibYQfidHxGpEC^{GKc`(Z&5?bTtj(>upOoBA@&)D$Gm zs5}AW7dV`#FgyXjD;msaIK37?fz-wQNUvh8f=6-rg<72387my`+$C+4G1k{`3P z?GYNzAB+n0eSO?CY*RfDtZr)8O0F?=k6nTVi-GjzLroO3u~Xo^VFA*E*VPq8)RoUv zt_u0r9uhak^098eP%7D`+HwHlTw6Hmu5qjaw%q<#g5%_{>AE+6QPR#I7~-?gE?qZx zYQX7wGgKSEsxyWixhsjG-X6at%N#C0f>%I0{opMiGq~-&O7e)ddr{7j z&Gh%^;MU3@?Q?>IPhUcP+%3!(k&}6p*shKU+B%_+g@0nFxf|wWIltZ$AJ@?vFJIe4A`J_6NvyK`}VMdGsi!qmmsa=|5lrPAQ z__R8g=69%j${uWno_z}|e{ADw9EgMCOmAzxO=NeM*!!OdeTu@7=Gj!^JFAgc2Y*ad zs{C1Nh5>&IFTe8iw5ROQFl=eskL@d#r!QE57RpTq9*(a zLdldt{Ea=V1U4DPAm2Td$26njUgAVb-@gScnq9Gcf(angzAPx*h3W&9vv3-O&8g@x zEaNx?8*Ti4CW%7UxD(omn5&XQ7?=uykl&(JIcd)FGlzF3KIWD|4jm%*W#LxgB^k;iVtGhYk}rErN>}+2CVE( zQhcXnEKt^}R{$yaww%Y*mb|qb#nYz>RpwQ;5>S#yr@TFo9uRA=dG-1F7b1%U% zjbgr}1v9&vQfg8izGA{q>JV&Lkt*iuf2mZNE|NKSxB67|#+bZYQd81@S*6Z9JNKjn zuxNKd-m17DVkoQvF|8giRQh6)Qw)I|P2b%np)If;H=KG(q2b(0Dn#1xnGM(|FU5-f zwW0;wqEg>J@C>esG<68zSqh;_Nu-t(7ce&nRnsH>?`H{6;E* z(@k?iPP)BPs_qmXKUJw7Q=#l*Y+|u4h&qHA*||G>sFyJC(*qGK;uDDd5^vzUFj}Z) z25$Su)^z}DG)&&A>?7g$cf#``(?rrzCckVX+{JJ<_I)>)(>$)V*MfViU9L6-ED?S; zuqF8Ip%8G)*o)a4W}-|u4J5a`bAtbPm5;A59{Xs#(^$dEOl{G7c(-BORG%{L9=lvW z89p3AxlIvm9W$JhD2AU+xD%hlVQEZ=yE$pan#_#1c6ve==tr^IGcs66@+h|G^o}oI z1x<3&XNHvl@j=L(oo|IDM1ENB8|t^LtM)ZJ%Xf*R>y(d{=)&nWgS?H6FBk*ITlH&K zFM4)6RQyiE8;W>aYu6e3)S+H$x%3UvhT*ouCdRdi+b(0VsMLHQ(At|m3>mitiP(nP z0_}&2rw^yS4lBy0p7)o@;7iP;<1xaOzIUz31ER5ZNIrxXqkSE+Kfyn?>j7PIC_!Q< zldRs<)}P{(Ja`&Q=Ip}A>77cnt3LEcAuSAFmr~i*1(g_!g3RRk)RM zo25})MrpTBejX4#A7PT3RWTsxOj0|5N%$8>yf#GlMa%l$la!(|_wmx)H_qj&SMw>R zf7YXEfk8Eyd0IU?C@sezc*?jIQsef(Q@R4zJVSSpMLuf_t44V${Fo!9jDf4wQ+`nP zJS0OZVr5a``-1&xha3v@^rF*J0m}qCEBnHVSL5SdX&^q?qczaANt6kUs_@~o^>k@Z zXx+A{0+-3Hx9z~>?MkUiS3TV7rQKIR;tPX?aa@5gPVtc+p;V#hx-PfIL~t?gBq{zH z*o6)U4LVFcmJga9z=pJ1NK^3v$iG}Q!6)WQEjbrp-8sH#-ujizF^t;4jCY=DLTH;B z$#-g!#S}%Cg8I>F+Iwk(9-K&!x1j^Nv8xK_J_*{+e913%zaDD4Y55B8f=+wQ5(P# zC)q~Dy!otyj196bdd7OhO@`2fW6g?Rezj)m;4n^j&fz<|0=(3t-#!Jqz9&i8^X>NJ z#UaU@WchXzuy`yVx{-v^%aa!&)#RA??PmU)WkQrZjmXECzi#9kGXjAyv?XTNcZ~c& zA=p)Ki&a@EKa*v){I{Xua-ms#-{it`Y47GVYGsdqpKpe?^|8d(peUBdtWW!Tb1>N8 zN(uw!gPtd;K$HjlMU};BxL6I8rj5H|lHQMYSogvdbg5GvnAB;O>*nxV5{S2tL(?Qphniy>i!ea*t}M5+#wMhm1HbG+^qg+*hWZ}8(K9P z`1MA1**;>geXd@JHXWasBpP9epa>}XzO6-cnMmy8=@vGSXbaS#aF+8udo6KO@ifEEu%<}Tdl zp3`Z^>e!$TiUZl(xz4mqRJ)k(8(^uhl*B&MsQEtPi z|JzlS%M2Le6YU#-E$AkUm>9PlmOO0x{X+|m#0HPq6u%EI-V850QQp{);ua!@SQuyt z1{CN3lncHJ_u>blOIB~CaJ7&Ch|>0j=wQG|RjwAnfV^9)iq1pFqZEUXxJq(K55l2U$OE+Zq1Kv`3T=TMO}+|3k=1@G+ zm3;>js`_n4#@Q#xm53c+R7?_G&%My12I!5Q;*c>GL2Q*!@^11V!S#9m`i-C>l4>+o zi>p-^nuOFoVBv2mOw2c1n22R9bnONRUwTyxe23n5L|x)rQ_^FsT;qG`~Z=j(Vl;_IVj`2~GwR%6w8bNaPQyUDVkH6`s%g?Pjo|TC75_s?lyxq zPds=1{E|uwu$Ni9?Gb9{Ev`X}q<2@FXTmW&mQL|-UNr1R;Mj%13}*X3dIXR*1E7EC z0v`cSynz97uarE0uNL4wBcF5OtnnULy~2>2O891ypq*ETp}V%e{wfKp96NM3OVd0< zOnR3OWg`=gScZvy3!mMn_@2lH>n)FB4x+5 zvp-5O4X?=h72*UZnaEFMbFMVYGpVR=JPMMB9TJih6#Ta*U^Q)ldNq<>w^;3kf`gOf`!{M39o>$o9;eeH)FDhk z<<+xeKKVW*JP0dq2M0a;z;QtVb>(YIr)Iu# zdB@FsmH|L3ZGC`qn|ie&rlL*aRcF*%gVh~4SWQto*GU+5UPcCZkwR;A=v6~5i#JvB z2qK#%_CQY`dep!QY^&9CaS_M}@3awKWSsB=C$s9UFVBcWV+-(fk`-PU1UGXj{QiwB z$H*z&+0_|GbiK>O_wG{#6v24Se7m6ucBqlNn+IeT7T+p7&3A>ULaHce$&iYs{+U+j zrH2cWX;)OHny5S$G#0REb$<&x@xyEwQOYyyK;10fT6x_68-@n-;fF3kOz;uR01q_n z+DWm}g(l^vy$m8mcS_4ILIY+S0%Z$s2qFB|etqY%ZfHVwmImRXat)Y)^9SZK1%T$@ z>@S-sS&^a{``VvcV%L=3J$5Y9v(lhUH#=m04S~=^>}z^V?r;i9qYtM_-o%1F^&XRz zG)Rd*FxXqeeRd+AKe{!w`Wh6bY7w7_BYgh}>5rJyB#AlCyNQqzjht03k*^u}hLirZ z6|fAJ9XB*C?p~4nPFCUh3B}Lxu#p% zC%GupzMd6sqPmR4*UfkA(?JLM1{tHBF48n*fe#G7Yn_saJ9iNXoYJ~a&n;MQ@dyt= zvB@z{zB^)fHrunpCtB@cry_wo$|H$OCg$pfuw$bYwze!`Wkiw9Lz(w-yv*c3#AxYiP(|Gg>#ahOh5IEPX~HL zs!HW!{vGV_!gHKIOX{4Qh*PJ1E`==L_N3c#K09w<_#>tOlwJ}V`1FXm&m%0=)_`+pyuTZ8hUYmsgU>^1 zd}n$gXmTn<)?l7M)4&Puk&}5e%Bf&Eq}7L;;6){MDJF=6h!6M!_|x5wM;sQ z|6-|buSGOI`uitGmq!Jh<1(7t-Sl{Tf3ZUf5P5yNQWVN^tjh8B!DwiG@hm7(p5Pfx zE#eIBA+}BnX-op1U-A*rSH1PVIRpW^>n6q8F2FfYbo6-OVjEgOE|VfUVBPx<#qa4N zrL^qq^;6_@fWkooTz%xbn=_WnF1PW*l`^IE*CA$(RLf-*+|R&Oj7W=)rMJ9JPt(c2Me=2A7m6Y7)3iMGQ;>{xt2JI zV@&9pR;I03BqvWxNYQh;!z=ylmPNcxHGG>_>p5F}%hAW=GM+knlw)$*mZanQN zdBVi8tlRZ42WIbjy3CU8rK53RiK>-ZpqS}Wvvd38aTqro2NMO)esfytwSvB;D$S58 zBctF`^A)WFkfHkVtm`!_pXu^KwAt%oo9;gqy*?`$JxnXXl$zuJaL{Jkpuha>p6_7$ zp)sjAFP8Q{ib*0yA%^*H#-Il@=8$x*gc&A}-Z(&DU-(;=6h(`iC3iNXP7#-_-q0?% zK&x!;J*rcfaEQ9jL)lmVMjJhunmRaqaB!VW6)WQ`z2yN@z-Tr7YbY z&B*uo=dX1Qe2XJF@ds!kOrBPm*QH|_%7-=#!Z5l|g!s~5y&E8Rg4Mgjsy+)v-9^pG zVjc!a`}6IJ=*CVg|GGMxVY?RqkeZtMer9IoyUJ{qOK$?mfzV7dW)34zjSP^)V8j$z5l;n@PgJmt-2MG2n+KmKU7`o zog5$k20ZOhy`J>F6@NNv+VFqO_CIU+`Lhk9co?d}95@=vNsJ-;1C*6xPBfB=9=WeM z8<$Es_;l*oCH#Ei6wr46OZ>&9E2oL)Z}t!TzL9@IGDTYovV$Y%Asd>94<3Op?JO#` z8JSTN_j?K#f7+_{e|_9QR&gr^!|VKG6yeayA6)w9Ok+3Ka?|D7hw}#9lp9ez^t|;y zFIX@N@MA^D=XPNKUp`+AMe*c=X*7Rhqkox{kI;Vnp;%l z0~!r8{l3;)bBm~wY@fp+s+aR{rw6yc)d5GJHXhQ0_NVzyOf3FUtvG304NA%w&)tyJ zg=Gn3poV@ob8c;GFXgeZn4>ohInT#do)C!8mK*e~?kN?*gpg37o5>Kq?NMuELZr?^=t~wqY8=E*VFaRC>&K@v$ ze&uP`u-w_w((;O$n};{|Pk8~I{?DyT%t&5O7r*ZOE~1TALBN?qZMSGX7?2Dzln~%T zXbrx>)SdU$IDgY=*Xzq;%!ZMX(W^QGSPwkE0sv@fX0UYi z+!QG9hKi-vtLy;RU0&V!pj!>&$Fak0b_c;X`#%e1jPLb8q0l2YECWS`GMFOo8a0+E z1YLKlqKVic9(OJ@Zfow05X_9b(FS|Iw6~)XkxG(J=1@Am~*KL}_`)QNW3LjR(c$L>&K_|@O1?5?NZ>}I&ogI@^4MkPf@9RFm8MEjX1b39Rw(wh!h z;_L4e-BTV2cY3>d?+nj}n@Ba^?M)^24m!L{Qx9xbyno{2koxs6`kyq^S=Ocd?B|7J zQHc9L!PVXHsLaS>m=}W=_MHMAS2W7MHXCHty|FUmf=yCj6a&AAP*Y@+(b(D9c{h{u za!tiL|7VxWdIh1FNpU7>bzdmT_poJUd{^k>oBw*SGevQsYi`};G$eEG6~ zf#w(!2WP8fUYyP>ASj|h_G>2W@j~a#KjFj3iU03HYjXdZ*4cLSfZEm%<75I9WK@Aw IQpVr@2Vh;nHvj+t diff --git a/Templates/BaseGame/game/data/UI/images/Torque-3D-logo-w.png b/Templates/BaseGame/game/data/UI/images/Torque-3D-logo-w.png deleted file mode 100644 index ec197dda39246e2f1f0a95f79d35a68aba584a01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19328 zcmV(yLFc}SP)#n#`spifFbNPtii zs`P{=EvOVxe29c59g!kW6zM2}4+SBFB8c#zG*c)KqzeLKqql_6qk^;u2?-#Opig<( z?@k`cySdpieRpr>{C*d*yR)-X&Ybg~GiS~K#km9=QchKoBuSDaNs@e&fGm#$9g-wT zk|arzlN2|Q%`QQPBuSDaNs>UqE}+4#z(nORk&`5p$$%UTmN2DcbV-t= z+?FK4hGQ8L$bn)j29%&ek|ZgcB}stc7-j`>(AbjkB$$vSNdg8*5?I)piGf1~5O6p% zsFGWz_`E$gGRNG zLDc-lsFEZ}@E`#~J_8r3uQIxoAObjO5UBzgL|Q5&Ny=ZKL4t++1uRrwVt!x&!vjY7 zTkR*IIs{ZmkReHuy_B~E4H8t?UMBNY#Jv0{fCB~{jYUHBb*7Uf`%o%RS#LR(eMc_v z0uro21PyoqHenEz1L%;-Ns=A=Un)e|Hj?;{Kh;T0ZM7c-YhYmqhM}=Ys19RxNs=T; zkmQ8+QyuzE)$Sc90z}XP2qz6*Cj$#f60}K0E!$a+Q3)ux0tr?if;WHwHevz^EF|Su z03wx@Y->68*ypR-k->NZ2^4SuIF|`4zRrobHqC|LO# zhyW2lV10OXpeiUI)$WWZ$7!6{G+H2p%9LieDA* z4G9+Vj}<_Y1P#6p4uB2DooHEW`$)ztlr2qKS}O$YQV0;x$tuM?-oQdCKM6kMj9hF# zfqd3ZPAW4GnW@^me6|1*R)GkTcY#fq(kfsfm6dM+1YhbyX-1bo#23b{2tZ*=>x3vE z!3snerDFvifM7(410t+Mq&Vy55~$b%B-o`NfX(u8O55d!lafW3QG_hCGoVmKb(obP z0@Vru2tbG^W~Ft^5dkcug~HiD!OnZm?X)f1DS!jmqz{}966_+wMF9%ifC zy%kh0aX3#&s6JSy{5CuG9to2^JlLYcb#% zyh;KHdwyGWNS#C}3t)r3@wM^g6n_=F$_5@={CUWBVPJwbBsC9f1PO>>vGie7PgaOj z#mrY_%#@Ps3tCi*(pjyvtnjIz1rNTuO%yn+yuA5edB1f3`?6wb3oh@25y2{Hgfxxqux@C(G+)F0l~Z_N)hmAdl6eX?d))ArxS5Wc!q^_!j@nH zATkdLkf8Nt0Ei%h#;<~vb%I8avjP@Y00}#rM^!=n$Fo0FfxO4l(g1AELpZ`)R16AH z+cSYf$2YIZ9dG_&VVw{OCWHbB+}#%_mIP7|fn)8!X#Fmg zU?qsawLn-MO_7CPlgc1JtH&3OV=S=~++!|K^HFQ-d8?N<%bIpOHa2HtoK9k6P9MMuVAEJP5NT4bo>u-~{EG7n0=xEKtkF%S7rlL8EdOItu49 z*fnf3%?Z3b_>093D!T&;+GQqR+7c=vtURej%Wh!87C-`b>43x(H zk^&0Wpn~Pnkrk({S_ue5S|muF?VSQ9EC&*(z7J*=2NDp0yUZbS5U7;QL@TUVI#t@) z+0yEm9IAlw@@N-Y5TP)51{k+H4uCfU7c2z2%0bBkM(>ceKM%kpdiy)g*%~Cy^L79e z#BD4RNC1TNy7zv&b!$$hs^%(7W@cvIT4w%7v%HzAc0C?Ecpy{(makA@GGkzY!rUSP z+1Sk@!4h@z_Lr~{0EwCXc|lHt8JB@g1y1o2B|;S6AmG&@Kxgm(jWj9-PyhnzU~!vtcW%lzkaBHKtRZ& zk3L$aNYSFzJQMx(*PqGv(=$?T|91PtwO_AYXxXaOeu4c%ldp;~E>XuLYB^LBS*{`g zA%O4>>ieiNfn}@@RqG}XM@tr4I&!0y|BpX@Pfxmf^?ZQ> z1+uPNw`-R`Q7^qdCgBS!^a7QPWDO)}15D}qM!12*E*}9BJvf`Tc+7A}(_0lsf(3Z6 z%MKA%PNO{hKu|%X=$HmHYtbqKpuqK^VAbA+?QrJQspo6dtoeGuf(47xekA$&^wVvjU4{{hiylPh_fU`rSKsFI@cPLV^jvVD0x{2Qc9XAc6DDSAhgCM&K34 z-_F(u*5Hb#=QFPzA6EEvkVLy>1r%ue6$Joj0STNLBumSeVcS3}#Po=n6H1gU*-}q2 z!sUy5ckd=&zji$(%lh!2|A64&;Ht%n6)OXmjs5)ms%lv%_V3+0=b1KbjFvo@`$yPO z*5AH$YyZu(v=fmL5j&QwSdmV^U%bEsFXu}v{$=fKNdhELoGpC`NW4tJ7Nkps4&eq zYu2dN2NdgsFhBu8M0mGub3K^($7q3L=F?iC&-Wzh%9W^!K|xWBzyyzXNqG=iwz(9067MLDKtcB=CrQithw?3#NgghfG$eKL z%+rPN4Hv}^B|p@*o+N#4Ru7lK-zaUOFc>dJW5s1M zDKXnoW)^mz+bP4d=FFMu4Ib%2lY){&-wm z7lg5-V2(W;S`Fmrk8Xh=l$o-iazysx%<|-o4M@c3VR0 z9c~(09mw3`Yz2@Ib-;~jBV_(3lVryN&fs7LI$R1lz`zl%xQY`M!~liO{&`#_XQqf< z2#S%kzg&prLHWLdSzlb`k5fmZa=8%xCas$p5H)*O!KfeVGgM2fk@XdO3|#u<;wzqU zb)Y{41Q9EuW6~)=M4qy*+prr0BdxDA3h7E@)+WQ%5oy>yEV1wPcvu4$C0au>% zBgc+8qf;K0;`^#epPB`xp$$}nqp(PKZ;;HM%mVzVUP>J&AeG)T)u4UN0?nE6SWdb* zk&%JrD^}>@`Eb+v4ev1o5xM@}uxWEf``DFpUL7*nJu82-2)x(3Z=W&4h7W(kr0gsL zL9yappr8kIGkqUgDF*iMcjBK@KIj@$Ik;O$(11J-TsFP;gLSU|>*%N|kCGeR$N^ zv04A$OiR0T_s(yr$;l~~H*ef{Z04Lfmlz^aQnbvoKUEV2iYn~%^2n2}Pp_V(`uFSK zxI)E>L1o;1;~x+ZY*gsC#*EJT|5{Sg+24NqE%o}f>z86;qK-zzuDpTyeKTQ-67f_; z039r5h&ZNw+7o0|1Af#4RI1kuS=D%M#&4>UH=3m$n9xguJZ}2-@892Zt^V@GOVK@g z_4V+{rP9ch4beVH*MM!H~*7Q zuIRKYi(N5U)Vt@)0k6M4{OP)N>poSyM2S)?>T&1x?bNep&;Ib~;{W^J4JuL$1jfGnBKZ zPp_&|uU@Qz7jwesZ$om=f{QMXir$=k4R>e^9{5UMH{YZafP3sMyT9MRzao3PWJY@W zjiP>juTWYLwO>%xud@G6JbQL!tvYpLNXIN;Ww=Iq&d;&`|xbUQr21j+;l zWk(Sz|B##~L(+#?&sh3MsERX)#d^IS_)!$J_2)eInmyU1$e!=N@A~a`-_P&fv*&B9 zKm;WB;4fU;t^8)qojc>|<;#<1eE4A<#n@>N*>O`Px7<*X8}(PJ7!*|NnYL}i=Pg(; z?bgkkb5}-3w^Hz(2~GVBdUo$#`pl_Q!&a_d^Rast)|C~AfCTeu-m+!4&tqagaew3W ze!Y8_QOKPpz3ZS!a0|3T?`NYZC_X)22km)T{7@W7T@J8_n(bUOQ`SiJ8#Q`#E=84e z^~wf95P@x#fD|7Ww=(F+=JT2fLj;O-v~ z@O)Zo>I6pRq_O(ao_k}O#w8d8h;p<AZQHu_`R~5}VP31J zpY8&cKF>PC<&n21PJH*urAw1~bnRM3!Q1(fr#_iFib6EGX9EGf`}G@g{o1u@UBf$< z!c>r&N(_R#BZm(5TfKJeJP5>i*TMabr=wS{To8Zk=zx~Zn-x*eoNlp&_QSX;v_I5c zBdAKoEI%hqP;i7cYTxDDt5hlIInNh1e6fBfsU?v_QNg8*zyA6&#|Nu+ojT14+lj;} z8!+r6E>yl^#f4{2pN_-?6M(W`SU6r%lijv|qL`so8wd*&0AV_Cnl@=t*sahfzR9(SSn&yu9`Z0*sx%QVh6%oZ@dw-{i_|*n>20q zyy!YKXw>+HZQHibgif^t3fvq(=e7pmZ2iRD*#RiZV0&`c0cA!{<2(wytXDZZHQ;v7 zG2_Rl5XvhO#gs)i({7&3{@XnZuP?Z-Se_`$(khX2uTH&sJG8*Wxie>;rvMWyEEHUU z1?sL1D;+M4Je>7BphbcRB9oh2QB{hFjGTxAAfT^9>Wv$h@7%eQdh_PZG|y*+3l}OJ z7+5x_Sg~ROsHS)L?OuKQ4y{|aZms&E4VI8Fn^j92X7!pmYu4L`j~p3$EI$4|F2BJg z5@_APdFl48TWRU{?xiLtU%!0+{_nZI>F@6!P`r5YQl(0l4npm3*oP6bXGb(?`sCtn zJzn0U(HAUZt>ESd7zsG5&fO59@KlAN6Wz}3+e30I^wj;7?S=w+@}&PYDe06OtY=vw z;PS?}(WA@EnmacIV>0OT1i{3aQ>UPXaeVf@nzd_B*s^is`A*^C=XLs?4z2fa@=|RkgmlX>V)*bNH;8x#MX5li!nk8c_eMuW$E{tzJ{9G|(9$vRl~-!D z3=3;mt$OvwX5Xn7658ry!g07ydKoL^o{^q@|3*skRUQrdH+O}~l`mh(D2-dl6<)Gr zN$&=Y8ZE=&)7Ype2qFffl;g*9=i=jz9gCay@%;Fs$Ko7Rq{?IpwR^YQZs0+{n zi51J1#!j64-Z`DR7=^Jm3WKfcq%jJO%~fIf6)P5)%OY{>W;%t8BL*3%H&SzfwqnJK z6*W;ZPO?%k?X!SVr6TX%y&LG~=NAgE;TF*kr%#{Y1`?Agl{*is1XbN}d?Z*LkBsv^ zt3#V?!^GXYbO|s65zs_F?fv&>z@-K+5MjmynrqcZjvc$-x?Q`CPd(LY%;AFvcN%2^ z74QDNdwZMY2{e=vZn;p_!VTYxPe}NE;NZar+O=)_!L?t1)orJK{rWXT$#cQHc@4}! z#N~^Z68rS-^0_(WhuZuIakK;6czlaHz>XlM3lwGj^B(c8k#!lGkJ@Ca}io;my1yKlb> zir9dAS#=*dcFZrHH-jrzu8h#;ijP0}WTX*@fL4g-o@+mO@{}p(SbrOu-kY^(v1(;>^invh)=SqSEUf+f zxpNyb9(3H!A8`YU`>zjsZJ{nWY7pAMtbpO2It2_IG{_J{Y}vSRRdAKc5gRsbP9p#h zhRPoTib}!3Gt7Wq|5sjl%?&zADQv^ED+)b$z;?FOQ83u`QFHGaGK*ECm;eezVZU9G z$@V(;#A4UuB}0Tdv?TFK%bn<@%qkN^s5N3`#D?+%AM3XDJmv_c@RwUa7yrSE_N z`^JtQ9bp6}1`Qc9s9}T9!ju97M~IRr#+-DUzub1~?CI0TwGx#s6IjtKzd3W~41zut zde37%|9sg?UAlaYX>s%S+i#kMX&^zSp#T61Zv&A6+OyK zpQS)IvLX=0a$u;uM1PM|8RtqD8x>XG^ZKEm2o0dXwNg5cTDNPL08a?bzJ`%WC%yOH z0GsiHtt=8Mqcld!Uu(URtnwOXBJgN~CXE{vfj$amAVL62&iZ@d;>A}Wn9zFxD%FS? zGuopFeKk|nQC2GHAyBy1j4VpJdiAPaU5xUZ{LVWyD_5=dgkAxnmM>r4f8fCV3i)!3 zVgev?UH9(WZ{OBUn^x(40B+lz_Wt{|5I_VRCrv0|?$b zSa^dLs)L@~phn^U>NPi3l|0w@-<0Ykoqxk0TLpt1tiu3 zX5fN{pJB5eufIC9;%GH0sfN&F~O>34X^=DB~ z!3-u)!2v~PWy7fh?y?JSp9K*<5r%cE@kEWvo;QyjJC=ed7g$@K9A%x*TH@%|qsIUX zK&2xr5_Up^RKUXJVrQ)|vPLZZ?6Z|eQgXryP2fJ+*a zr%Xv?H7i#L))-eTU$#Xrant6_TPWtHdRtI%<;t3X;NpezKkAj!J+s#h@%zQvwQJ&! zC){V;H^_hjf=jr~R4>!sefor9fJc(@p{7S!LeK*dlM#1*rjKc2nr6aMLF9;u>_zv zjN(`Ya6uMHIBAsanb?QwaS-I9$2!U`7DL7J&DUSIedLixi)7zOOiVnC$a}cfDXV}T zcY5Qkx02zhpqN$(yVo076_Cm(IFBYXx(oR8loE=^QRvZkHc-HI(6U? ztxr)jg7?7i-ihbV#l!d>-Y>%)KusDoEP6C9J{`C1)y)4GDOucO#0_UQ51npl_|x$H z1`QiloHA+B{}Ml3lJs7hgwZZtF7Pl-ft+WqtotrCJAGXmZ>g@fU}jT<-oIN;S+H8ZGPyAIqw zd0fHtATH#lx5tfpf=8wN{rw9ydGg5`b?em&)w4uEy72SQKYg}rd6L$%4(*@Q-HLl6 z;lz&w3Xdi_q%NR1bNY0m7Lb6{>BUYJ-9RFd@cV#rjF5(8MtzP{j!xm>z1=@%ymc)p z>8u+_OkoHPMMb~_JY~nB0|z?6vo&(85ogbC`D)j$3<~~YRcDn^JF1M^PB%a3D{=Sk z-GuCjmjR_pK~S-X04$L35EqbV#aSDqmI=L%2b>uO7fj^bgCUUhGQF9Wb?BCA2lLeC zFSqH2dUh-70FpA5t5BihjL68*R-t~lJTYq2$Q62nq+0dr`T*p@g`1RuS7ji0vhq9s z^Uu0vsa&}-3{I7ZD+n@kZ`s8yHlpF3!k|RKe?Q1638Y zxcNr0^hwKx<3O7Ae`sikE|A!_Z(kz8x44m>pG3)$CH$Q@P!}&+^!e6p+jW(2`SRs; z>osl0j2{)g@dc3InKEsf?($dJa^(UjlrYLxRn#3qtQ4Z%9O-!YKd@>;A@LbHv~OSJ zAH#>g>**VD?8wnIJHOtY&Y*2rY-_gzpJ3CxxpVhDc<>;n4J%iv(n2ARR%&@W@!bBY z5H&p!Qp?1TvkHW4(ug(S^R8eU+D#OX4>6X3{G zDEyMA&!8n@^_n#wdM;_C-AFmrA}nmPLblridk2T!>9IBf1w@v$B`a2>-@17-=P3B% zk3Sy90iX&a8X%!^cn4K!qgWuQ6fpq63{dEmU8QIrBS68by;=5~t$@z8q@=4uUww7z z;May7uvt0n4knyBBlJZu!D1JSAwWQ(%^Nl}e{1xp>BUQwsFHo}&h6X3^y$-QhJq08 z-6Dled!~d?zD`R`%{dAlE^mCddv~Z)$5=rF1wm2~U8h5XdpM4p3PriR8AgSk+?e0= zF1L4ia`{PkdWUNO6_yH}*6|g0+pn#d90G{1wr~4}F@RtVK5*9~Y112>{s}0)XB%@W zBp7}4W?EXVB`n}&X>@svHP2@*mn-}KoShyi$;mf3Oa?^GkV(Fg^Z&><-z@#^q<2RK zlrB@xGa>Yg_`ih<7wp>o4T*!LQQd^?EWm6N7Gu@0jBt75v*pXjXJ1#VUOfb|w27Qo z3Gd;y9l$9EukD|-yE<@yhFK$$Me53Z4u_U!uwMCcz{KXwn=ZdSaiV7aEnBvP+d>l= zwztthH3fHi+dpsJx_#3KVCgLnLE(P%@Zkfr6{{Z-5(*tRwVth8vu15{OiaR;+qb9T z0)f+~PbanS&_VOrq<7wVV%m%uBDd!14(2J7Ch6{cIeX^J71rNl09b|6ri~j9y#HT6 z5?x;k?XUXKDoJ4{Wtk@A9J9H>AcHFq;b?Ve^>kS~XEfGC>bf07bB1r3tqPTGs zBkE2LlspxMqvIl6-uUR_kIxq=TC^IxE?%NUhz0z^WakU-I1;oL3e^O?;((Pr?-nRf z0M`m)#H@Lg_n{+4bq8KRsZ#z5`|YlZ8Mx8<-b)=j>N zy$pd5NVhKH@E7YC9jG&N)c(b`4&3?ew-ebwB6~Zi6G3c2%E3)zd0@3o6qSjwEEQf+ zFI5u+rwb;Mu3R}=p;D#V-uYLoSg{rbIKmNZzyMffJqr&H*Nwip_lG@+lt7M(+^GF( zzX1bww|e^Nc6k(j_3AZXRLh580_#vUxHDtw^y!+;Gq3w`rmG^0pmcT~P>jtGHZ1)o2%@-&-T!+Ty(qo=q=w?AWnEXvkwG z?Wfs4*M9v~vu|oVQL{nA2BC!z%Epz~8Z~H8$UPfusP#FU+{$_lRmFz}Bw$*B-shU+nZ!m|`9ugH;?1&Gzi_ z(o6n9m4h`c5-_%e*TGeJ$^={hr%#A}#}iK6pEq~za;*=*Q%YlFVh1XCJ9o0~A3k{S zfL@*>-gvVihSFmNIC9a z<)E$Gwk$z<#Juz6=FK0TK6!E#j12*IWq7|2gHVMwY}oV5?c0~^+q0*W4Xg)t`7X2X zK!;1u>&G5@tO%p>2<-!xAi+Xvm0%H9f^-m?d3T#B%$)L{K7Cr(D)H)|L4BJweX=lu z62w*3rtKLU6&0pujesGh7ku(boGAkV7Z0a3&EJR-BeuYDX}#2c;43{fmLm+mv-!(y zsd^DTp;cnp(q%m@5QbT0kBNyH49lRE0B(8Quz7PT>9`CF3#&;vmXVda9)BSMe)Dnq zzg;fwrcfi zN^zX)A4tegm4B|X^?C8LmL2G_*{P^+P z^^SusU8YQsTVeG@uu9-sBn;ciNo;@3{^{ho$So?oYnp6{~%rFK4oZ;(zZ@{as zzUo%&Em8Sq{@l3@cJJKzlGbm-7hgPU2Kpd~==aJiy30)m_wV1eVbkU`l<|>zm5B10cqia1xrxB1&q%t zQF;8_3Tmm|635VC!+IiEaB|%nGGxdqz5KEiqFb?V-mu|W6w6R_OiW_K#*JIHZQuSS z?_YS=uD$l}-P==7S($+d2=GRX7_kXeDPFs#y<-UW{i@iQFa^&S2g!le^G4WHPw6^~ zZrQr!Dkjh1f*G865~%)LjtCXc3Q#Ouyg0dHP|$QYcwOfGtbK@`!pLlB7PU?n5ELw^A4cP$BPQ-LgQ4Q@+4JSudXAUbVB)Kt=qNRh{Fpm<1Ms?fB^BQ`Tk2?y6n`8 zrO>8byUtz1JNx5&$36SHyfQj^sZnL0s8y@s-hKOKyMan)4?vNp&E0ujU9oK0QX>n; z@L|JX*l!hDI$)kKZ=-K7Te4&+EF+FW`^TGa#_91I1e05~Zk;&t%{MC%@Rp%+{r=l; zJ3rI5ZMa^!zTLfhCjnoRST1Q~iONVWindm$6mnRX-kCi4mpL;dCwYU3F%!m5YuBbt z5sLQ7_mmyk5|XFCgp-KJakN_ZfXO|*XJ+pM#rPyTt+YAm-HIcmcfWo!v?{k^>C$&! z9Wvy!PW^yMI~c~ee|y}x%Kv=-{eK!+2D0f!O3LMg`1l{9W1^3(T)id@rDK{mYg%~F zz=5@!w`ke8O4X{3QNDBfn=twT=@CtV{ylh#c$lW@$8y)>rzQ%0o=yiwr!h6HEKN3 z2!dg~gm8JLq`&`YZ0)G3(R$X6zyADFGjNjeL_uc`<@HX%f_Z&?Tp)KFuZ&r_WaQW} z7Z5C@q7*9XSsOq>JC7sh-i)bJt3dDoeI-0()af#Tfs;%?gNo7DTRh~_Dz{u(tr#y| zqgb6-?>=OepS!y1x7im-SFS`=3<`=u0Kho)$Jq*v+GgAi?J_%E5)h=<3O{Xh0;g7Z zR^5}?3KS@S5=R1e@R}Y36ESPnMYoWfGG^Sk*Zl(mf{ikTyE@u;=+GbjmM&Xxz)GLp4gmWhk*`py_M^tEXoGOF$uYyZ`>TaT9yTV#z;ZP=zr z>4pp(Sk$3)R9FEC(z7^F0f!lwP!#>sIJJb6ssk3Z8|J_M6RJ+WMs+}ncRnLB^3whT z`=>-jN539ixyq9$4GtBL*0~*|1QpfFnCQiWUmF%jnuqSpj;&zT_$nniIZR8L zwQcuoc(W&){BY>V(fb%Y3zr0r{rJ;QHzvIE&TFWODmxuU+yp~{7L~DM#w=O8etjCE zV9{(}cyL_A^y!~YkBFFrVwv*fF_ydr>FD7@JBAG(e$1qwebEGNhhxcEO%heNyg1#c zag#MLSXFj{=R3Rr{d*2`s-shZf+_Xx(k)3Da7>}w zMPbx_EPN!i95r)2hl)~9DaOXG9IBC*={M&sSa7*)xpEVswZ_P&g*Cx%ZQHtKWu@TY z>245_s?hIpQ9kIjQYj4q_ae-V#+yQpn?_P z$a8P)nlGELHCJ^y~s-VFDQ?O%lo7w-4v=FJN)UHs(;t4@K|j)eI5?XUFf z`$qYS72h8-e*75|!EL$)6A?%tZ|Ov|MCiUB_S92fK*vGki0y(6x*%|D(zI!G-`>4O9FIG;otK3I zf+9EY`T+vgia|kBA&6lBG@UeKB|U|dx21xqe232H(9zPT{1#}Tgp@mm1neNr!EK==%$eQ?U8kmUc&Q>}^&9Xhmby?XU) zm-P3qT&{fiIw+lSGcE1Xy?b|WT>9nW*>Au3=FHR?GcGA~N8su)DiAOrfeq5;N#DEY z%K=@wbg5mdR_)pWrAh^%I2=L+3ms+k(q_eqm^g77q2k4D=l?omjvE);rfr)#<;zzH zdi?RnOS$cV) zc$Zd2nac9rJ9oBi+rIsX?CXmc&VO5_TJ?D}eW|MI*6bS(cWtav%;OM|0tuG8Ik5ZM zbH_&V_3K}hEmv-l!hgpGYFgxW<8@X%3YY*G&lE((j{+Dx@1uYj9FT+x8UR7t<gOe$;wB)G>B`EK{_&}Z7Votu4q?8uS#nlx>? zPr(bMMhhgEw3%oi!5U0xfd##1DDfs}ttU9h9uT$*D}jtVV^kR^3zcE{MOxfQ+DrF& zi)PIVZ``!$Jw3|=v?v9XD)lx80Kubg>;_6vqTiYU4b-Jm)*yn1b&Z!*B8PsxdUayC z3Kg1VUym3*e8_@Di&98=O#?`*q1oezpheKHNcgX7mg74BML>??ur z9&OY_9A6U6avwN!D1H3cF|+hf=L`rwbL!MTDCJ!hM`^EFRag)Y% zIVx?t5mCM1vc@BiJesp(0PMtcDHJ+#uto1ywY+%6CPqixa z!=AnONz9FcgbMC=0gJZ7{4S}}8qTSrq$Xq|{z8#?q-o4#FfzS5WXP$3g9lr|dyWMd z?uo*4p4SULp1+S^eA}j73)-yVNx+0zh*z!WW&#ZrSfF$yN@PsbK@BJdtBL@ONb?7R zga{zaA28}mGX;pP9AOL*_kTwiS@VR=s3_W;$Kh5aYv(i;PEr6tI_bcIh%@a)89mw6q-zmo;bsw&Q>VF2d#kCd@1cEI@^4S%8Uv zF#{8%mIPFVsd8do-Y6f(D#5~{z`H$pg96%q2AJOfg6fN^v{9qynmwnrLWlwrG@t_s zOu*e5FpdQLyJ(RjrCE&)lMwulr1z#w>FRlX>coj%lokioA~_-iNRXJ~%-&%QCiK#g zAXuOwa8QH)yc zw{F)ifq=iQTFSJYMFJH}pw85Rg1?NR=%l0R48Wi>Ny?#O<^vcq9VaHjs9mc`ClO}g9 zSg>HuiJzA*UD}|qTVfEgEUGyM3fj0MSbzxy!8(BgDD;#G>Rxb_ur9Q-TpWc1C>f83 z0%hq0OY3Y3IJK))Lekd{QzDJhN4tc9`)yi44j89LUDn7ohKiRcQ6&dR+)Gap%xkRk zNA;b+`tB$5=Lc4(RB1r=^6Y5AU8TieN#1*LIt20BXI zd)z=%EaFVy_K4O+x&wk=dKdB@CeLNTyLpqjVa^s=EJ6#N4@kEWvo-ZaGKc4KXRs|AXgbtRW4I7U4ytgVQW+o?#n~dzU}B^Nn1BKooB)Tlv#0p_37armQSNjb|$2%(PZ6 zGl)1(g`_+<{XyHN3Sqxu@yFLYcjej&=y@IkXSqyd!RgqcLy^F;Wt(ST-@1A8q_oEU zkFH<4_PU>+U#JJrI$tp;=yQaAU}=p|dAFC{qkW)&2~r0s+=Fyb1Pd=ACQ1swX0WG zWvmEj&qB(%HzOkACC`T^5)uwGm`pjrN@x1snNz2pcY~~Mp7*}py?drj%Fh&3xCB;; z>AqD0#HAvD2-4Xu4yeEdEI9e{uyF7M4=fcKtGduwI9SZ?MS(-RSW>LA*r@-7ytf3;mTF2wDVlnc(HTm0~i)&9##}vOnlwouUhT8 zb#wVeT)c38VW;r$^Mv&w>08qLvFq%zs-Xpd36kwwW+(jd02QoE^*qePJWSO*l>{n4 zq0PgN%RZu&u&?}h0|!*T$)U)Ih+MG+;JFL~`}Zpo(W(-ksaG_f@G@{R;x+Zx?HX>g1&j5->qyoiGCsxTbQ{84s-$gU5`{ z%9$c375x`5T?TkLF z?Bhm{E>r!98ac}vfBp4m#{2J2+07b2xLhtShfGl_SzTR}4I(_9E8$YryAvnQLJAQ zELWqj0x|&Gtx6G_R+&fKHa))dpbu2Z>zH8GLo0Ri>1uWzQMoov~v)ou%yEL0K7 z(kNf(SlPX2&(FL;#8+Q_Im*i~0@uHf_f8Ea`r68+4PIb^Hs(I5S(1g*rbsJj;8On;K;;@Xl(Njn{sMp zfs@ICiSxQip4v@ko{n0j?JH=1-^BMf0cRT8X@=*PICUM*eC`#Nb^Q;`jv7Gg5a(QRF^M>oOdl%R} zsd)yPhoM&@SL?3!V*4tb{byX%J#8OUUl#w8&%D)~Fi*vHeX#|wv$kUV?yEUSxpX5| zqV42Km8NXReUfFTFY_9jCS?J1DbBCVIiK=+{c>zY##DIr;pv^sGVg|{jX4aJFda-C z$gsx@d&BhXWqzJRcljMEeRRN$^<4ml3|Yc8_b^+X`bVSgY~>SI@A@SdYOfH6Xi%3N z^?&+edQ#R$I+(2?f;Oj-$zOi8zRyS@B_$*Pjk?>_3EOwRaJa!Ma=N&n$@tvd4J8Ck z!|NtT-hCMOlvlfcP z(ZN1^7V_bxjbEdgg8&#Hs(-4n_D|@Cl;z^arwODBPNr4~DdX|ae4gHSEB<|+yngLg zd{cqCMGWH%@HQ58VD7g0xQj<*+s4do6`u#e}7XQcfM6JEgzOq00hO_EIn1hYv|ih;!X(VOJhe>rTgu%6Yxr~>>5>@ zKAG$NqwmoAn&fm}q=YW?AAl(tv$LZsyqjWQ+z^dsqd_(mr#kX^sN;`sIcN`#wBpMF2- zJZl{yKl0+pLr(IsiLNbkM;KpXy0SG1(*W~L`P<;LY{vKCfh)5gD~fs48nG2{b-B=G zUK>8BO0EDXH<}JPJgOGosiRE>tNkEX*;lAS2>tu(rFanu5qKONOl) z&-$#@{2cB<+VEY%f&A7N$8f#5_QMi=so8$jCyPOKU;r=}JRC8$crTtIC9mO6g=;V@ z;nOB=<(>?Ilo$f(UP(iF!I!c8k!a?t`H2qPiPJ+RY|bxP;Pg}Io5`1%zaV4dY&|KiCAGwFwZZ=Zd{0r^AG zwO~c_=d!2C!3~!Y#ZWoUysX;G%j6NWExugJE($c$cbR*Hly4d-){VD0dem=mU_3F5 z5RnuYu+I5g_BRl2WdD?eN`l-auKZ0d+w=Tq*>z7?2DkNNOn#oV*1JR>BV1C^dCkz+o|4~?X3~+FeygAz6Qqy`M#{mY@e>Rq(JuO|@V=gV zOW=)~y#=ohxf-_F-71pv#93hpOgz86fM%V$u4kVlt0hQ$Sr1m>T*J1DUfEw4E^ccq zN8PuCk?SGk<10T-dv?+_-?M_$AA#h=ko1nAX|W#KQjhzyCG z@G~U5qu`5$4$%@gr#8xd%h>JVa$HwU15m$Aa8&oI6|p0dtRiARL9f=9t5uGzg3|sl zFGo9X*S~+UfW*}`5g9;oz;aGMa81`RxW%O0w@k zDzzn{)uO;F{RO#Lh%$vDqk(%Cs_F5lv2K&}Wy2Kd3nCci{_K=HSFJ`in@KTy6RABE%%Z0l=)_en51B`B5t8NYjF-}@hC!8@g)Z!9oYhcsT)&cAbOMv&PhZ6A3YDqy3gA8cX>{yfl#$DH2dcN z21>%~vyOf8d1CeYopp`nMGybk&5DIvgz_u2!(y|N^zLizjx}qF{D}Uz$4w+{FSCh~pAJ_yr|r(@75eNQ&IhYeCdy4CXq$z? zFrB&2$WoL_mbxqskJIS_~Y=x0p6KX{T@eyYDrdaog+nRokt1>jP&0KBvTyQ zW#BFhLT*=s;_%&)^P?)aopWiNm$SCyHdPwL*c=ysvZ62!x*hN4xEXF?;~6X`T}g<%&ymfvG~h|H*t4sA gAn>anHe~mMj)!uL3rfOt0ZT2AJ;~Xo!itvkAFNWCtpET3 diff --git a/Templates/BaseGame/game/data/UI/images/Torque-3D-logo.png b/Templates/BaseGame/game/data/UI/images/Torque-3D-logo.png deleted file mode 100644 index e31d42a688a7e560b17237ff60edbf9c0c00dc4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9063 zcmbVSg;!MF*B+!(U;wG1yOHi1kf9k$L`uK`=0%Wh5QdU&q*J)vzMy{GoxC-!;v6QQH^iV%+)4*&oVLR7&}006BG^&W|Xg?ipui(#V@tas|K zz<|I1uH25|MAR2tCskt?001BO??wZpXHud*V!J{#m9aO_Ffc?xA)nqf000aC2v|Yi zbLqrXDwamw{b|rk&FJ_lT(I!cRi%LfiBf(M(}V ztf4@qo#z7JZ-Fmr&~*br$AR6fwYr!;cTFM8W5NGn`@PXSKCJSup`RVQL_-KypH}J3 z?w6mEYiswf&-#OHE5<~ErxN< zw`n4cQB&-@dTv`sq=Y;X;6=iVoJ>vsdx%?*wnNhV;vTjTfHJi*#!p*^{G`0!VtyAduJ zh6XK_4Z6OAd_IC1o?IGwUA9_BLSNImdS>Z=VkBYb zYF+Qy5wxj3~dOq05M;>3B;arFkVlp6XaT(VVdQYlUUH!F= zqlvd*jNlgpp<>x>ow7rdr4zQu3du`qk0G%KTFNgts=Jtx=VqoV=g6u8@wKJIz1}Xx;dXLRf+QGg~7jj<^VzokQ#*f>>&AN!o zc!MB5i`S;CQLx{t0CP=zBPrcUo}ty0|K*u?Yx~l9ln;@ov7_HUa*r1NcD5)er`bdi zXlBc(Cy8W+-BUc#kh?h@)wjrfoZD(G3>{YSG-d3IO!J#A>Wr{Tv<&id(VrT^VV0!x ziK>$pm?0ME%{f;*)8#P;!jqWh7%q6uwMWf{8ysGbnF~tL0I^;OZ?eP+n+;<1RKw_S z8NGE$omELfvqHw+`U&ASyGP&evLm$RkDe_66_5A7_}L4vT@9fdf4Eq5k(g<3eBtNR z5lKMbqo6_E-7#*d&iKWnwrx!H+C}CsUEMX|iWw z5;JE}-Om8Btq^Y$3==g@cIfal@rgHuB`ImWyCk|3N717o*N@-zdD_6BKg36c4M&nJ z1?PBkU;5JZg@b^lS5EXClSRy5hBe)rP4)&xzR1Qy>DWO?rYWDG4cA>6#=en!%B15R zKD&DGh63EIkTf{ldPhSZYTFy9DrK8v+JvC0k8snQC5KlWKPC;orP1~)N?FkOF9*7stZeaPg9trjlP7oU;-4k46(!$M^I^a zGN%sOcAJ@T(l5rlc+(N*5AvXWQgl*4+#)UBKM~hCzL~84LRgf9O?5M-0N9*$<;M$- zf2jdU;-uaLSxIDifqmH3i;vAPIKqmJVM`>NhlOa)BsS-7Sawqe(6hpnTy%l~2SHIKB zrHty^)J6W+Z5R=i$lzvVZBxu$ddYPb#vFDkrc_SOm;_0N-UtIfL&A;iCv!*9TLmuZ z!d_BQ75vO5Mnag%+akhRO}t|x+e_c>>pX-?Z^H?V>oq_#JIChoU8i5`YGW8&9P5&t z*$@Zc0tz1Jq-bXnv*W%@-eQ$WdL*odC+ZnOJ&vS0^zZTqt@rnJUSVausq|@~ua;LC z;N;#D&^k??sB3t)#0+nrj?1bA#z)Pnh;70RyPbOdm~Od6A--;6C1PQp|9TsGA`38Z z6QD5%4Ep>thQ12USqgS+WUcOg0=ASF$6w-`%HWn>Z6k=!Afc`8WJULAg^tC1 zjFg_L#lyi5_6v1HR`uVkqn;%M1c~0!2$A6GG!dwzgZF1_3_f6f~hGS(@@*9JfO-e=oD$Y`b8mpiXeA^Rzpfc%b@D40o z$HkR-c`CZd*OJFkD2V7#8K@h-?!ow-1v64ffPXWCJGS@>KdYG-_{|b_eeN)kCT)<7LLpotFExil}{Gt3(+3GH$ahMbsw36A5l-*w}f;ed@XT#3N zo!;lGdnBALJhB6dLs;4Zc?MDxh#Ef4BKiI-b>(!|xjA`!ddu1qoMs~K%71DV92y^U z>~CrQZIXDwth>2vx=YgB6>kF(!6y<$_V7YBO5zultB+!MIwM@Y_1hEQKCY5E&X2Hw zLu6`rYE-_SGAON1^g?fV_=~QV_z-J3M+{I)1p+#AYO5>|ED?h%Yw6%Rm$7XakM2+4 zwdN1?s|774&RYv{KEjzKZ=iovkR zNo|HPKKqgJjfU}r%hNS?$NaO&{3*k*xA;OpVZ8F=a30t1;pSLLvlM&?#ah%GIc^-ZhO2>6pIgh&>1wL;k*zM8E zt-jhIHY*Dbzp2C|Fq%1!N-M zw>=Q0GGm9{f{!umG=e%z7&uTt7Lq$uibVn;yjhwyfm%Z1Rs;icNNBe*l=X?cw)6{< zn9n*Aq1in?Sv~NV&J@a@JlOVo0WTfgn$9qg@o^@=YZ>JOw>G8DiQh`}pbXI4ep7AuqJK5;K?3$ANA17>@N&AE>KvEDltp z?e0?Rizm*15z>s>GG@dShFkHa>Lm~zewLK_$O<6|xf3xunVYs7^AG=RH_^B}zW3iP zZp`Tyo`oL>eTcPHAK67gecz$=CHlp5UV9FA!eb6!t}|Qr~ekiQ7Z>#PDrd zuQ-?i+Ex^LqG;@34KvYW9L6`gi4NiCvJ6X0=3~{`2x1|dy{_j{g~yBgU2C1O0j>8@ z>%4n`e%89ALVHRWVdSeU**lab-YL&wMM5<_J5Ubxg2<3GI(-@~6&*ag07|!}rnSJ` zAtsa`2bJYSUNU|!Fu{(lyB#;~^$D^@VohZBQ4CLBx#8V%lRtVt$R5o`7ehd%N}pFd z))KIZ<``F+*qmUgP0jVMd72BP>!z~x`HC`s=!$E{uQDbn0pwD4X$6LLuGBqk8MfA> zl37rWgDO>}8rk}dE^6>Efs5oy^)H@FJ&z%6{1HAV6&o>&;hvTmQ6+seUT${c(l}~w zJ)a#DHj8X}t+tp7eNxpDAPf@@&T_Z|tF@T-=p@9%#Tb@SDsoL6W;DB(D?q*;YK;5f za0pL2N=vGHMrqoP}O^5w*>KKtzJ>Um~rT>^u}1YXS@d#9($rdkuG z|GD94=s=e$c=^H8Lh-~W?CP`RtwsM34v?`=_Uf9&2)Z#dM@Is~e!_J1!_~m~$W|oH z&?8ldAn$^^K19EwmrT5zCg@K)1>cqEqQlx*e-nLar_*nYup(>kaYm|PZ*o5hq$IE6 zoR_Y3Xfa^_)C%&{Sf|-+6i!McAAHqqJuk+)Vi;%i@IG{TbTnd{%ph55R&PxyN4Htq z=X&bHEA+L+PSwE3uqC_5*9$u5Kv)b1ik0uMX%G&d-5tD19pz}tdUkpS?BkYsbtGaqnFo| zQ3Od@pRqE)&zH>SFOaAswiO8HjLhAOf8G30jP4J!$!E(X=@y?LiA2-z`PJ*|CKnO0 zMbRi^!MdmZrw;b>Gm);FSB+%7@}qGYqGzr0tBK-J^~zeLRRww{c1_;z-^JrQkLhE5 z0>r+uma3EKd)cXFRyG5#u?=nk-6?xUd?>Nh8}&=GHt14*)^?(1vrMDLVXon;^p=OT zp%~rw`O9cE1;3LsP}KlU%C4Nw3U<*yjFcX|@h|&OIi!W7n@9CG^j(;yr(=B%`s+y; zkp*ATPK}YbpI%XCDb`i=5;n@iug3e~fOba|xa*RE2{kJ&5Nw3xaD7N6eC($>@N!Io zx%RI_CpmvBU?!2~qtq2*DwFio&sfwrWL-zAIl0`%=iHTk#onr!!{M+V2pg*t#)57ByK?6s$%S zFl8-`82f^jyuQpxu^{f&EU?{Ki{47~t)M1JuyBN9K2{?I$y;h zbj&rTU*|e!vZLCRMAfkC-S~Op*0rlmS?eU5c#E`q9s^Q+nApqnYN9i1#$af*mPI=Wja?<+8(QC-msXvE$4M7-s%XvH&n$$H_}^)d6N z*)Sr1Pl1IkfA`+I=gJ)$##iLORdh7PBE{{9kHgq#S)A!;Z~{fE)|4aWmTa;_o0*=wr|R-Pj{u!0m1-Uc4uC`&gFbKeL5ATvMv}9Vr1^ z22$Wf;;+A7T47NayuK~^yvnIICYoNk_kL4sk^^W4&$5{-waL40!OeCH0+B;KSR`Td ze_jCiwm6ibE^W9Ao_SpAYN{>!w+~$=qm^s3FCv$&7(NY!1GiSk?V?I^#>mOCZO+*t z%|ZgpnCJT-dYfUehldnyZgsFp)qfi4wQ_;}=(RNXP#mqfj9np4r#Z%gh2u`*{Id7B z6gZOmzeVidGsKVl3HNgeUe)V{+bCz&(Sdl=?{mgM9>TNN zqN-lWG%UT`(gLZ=x|g<0q4*ZU>DYa)NIxQ?6K&|8q_(cp_1*MtOjKlr(3}p7b6t37 z99}DfpI?5zGTrfh!&-OTY6XtpG{mWZe=ennQz7qZHiU1t>}*t9&?a+PLgk#)evvid z=@cM??Sw0(LA_x3PyFfmWc(52)9<5vXG>!PLTF2OYm zi6PsC>=^XtjhZHlUc6Jqn78){yO+}DMw-dR4P|h~KBJYdBPQuSXE=-$BxgU9cj7RA zNKgg%14H-)$#s;i=p$86;RH6$+PaY*RS);~`2J0453D-kh+EEnx<+2jE*^ldmc0)k z{)ybi;`E&a$@@b;3dR5W+N*c-GDp6Wnzxayx&R>vMOS;Ay0cW*+R(Do(b+H|fOhYr z11G6I2h9iWjkS4zEL$zR#z#f`VT{M)^bl{G{FDCI?8D5EUAjl1!>!{p=+I#7WS1JJ zoU&UL$~QH&>Ddzzypv2fH)rsC==l@A?a*7~yLzK$!_OJNW<(A5Pb?o}>g=V;(;ok! zFfu8$wF1{=*Kk=6uljj^GhGAxBu%QHz$OV3LYm_>Y-{i*tld?L=g|OiI1q*EwQHJ# zF?O2Nji!BtYmR7AJTG>=O?G_UAUH2RiW2E54mXA#RQ+3sp_@76LFXDA`I8Q>^*6g3 zHY7Eb3yJA``yWFi&Ps6^iVygh-K^7;0yd$1GUGj0tgZhb$f#da6d)-yxxWcu^3XV~ zgJ<`Imo$Zn(dZ#G9?y<#mD|@o1SWQbD-k5c<+t6uWyFB-9s{r7^2=mBrq>-U;}#XB zsgGG&z~a|yp_5EOg5UDaHa{$uE3rvx=l@jZ-7~edVMi?VtrGSf?Q@M#r||V$`h2a# zd1yywx}DjdQoXAD54(O7o~e_=&G_9>z2}7or@&DLKN_ARdymhyM|4FQ`s&?E*SjSj z``lI+;2;T!W;Rg=mefW59+VH>W{5gy!%@3&$MYW`aEBQk+#S-X+Df>6DGhxhFFwL9 z7C+|_)p#>|IJG=mV+{4H8)n%t3smYl&=`Lq>$h#~eQ)V9OSn%(0oTgVAJOpi<6-|g z1IXMpFbFw)pcpYB^u~gHes7sb5t#F_sosPqpSvE(TwJK<)^g&&9OhA~=Ydsf#qN9P zQ9V)u&#E^p)-$V3K%lnx@%#1YiT!f=ADn(JmAc9l!sM?NuQXGNNm&}Gd@7T&%F=6m z1&-(fn~Z_kimqjP^p={vsfBxH37RW@A4yXW0^d1u&C5JApbg}`wQ4!PnqpDH(S>kZ zvN1J^sBxa^s>}v$A^SPw0fEtIyZg9r5W)L2Yp{MG(;W)}go^R%^ z{kL(NT}u-9$Bn=o`n#GrwFlGo#CaCoBeMN{F-nrN=S*Q$dc-td%W*G_-4+v4Ij_bV z(EPUbg)ZJ+;*kuGR+5?FZCjZp|3jd0x@A+En2*ssb8e{Da@URlo)chL;!5t?BbB=W znb;2r(ZfpboG~)v}KVa&;2@T=KJ@rja{jOeJ#bHH9n}pQFtSl{^E>GyF_u-**t!-A-*aHxuevQ^9se zq>g(=Ju53DBS7%CGOLZ7K#3SO*qd;7Am*hH3avnU7|g;AEFCC1x@xMdm{ms;MEK<^ z@jKX(yOQm*I(H#`pIh1CkvJ1~Iz>ci z%lK)4Ioe=v7n&QYsAa%YmMlNu5i?K@`y6(4rW7mpmmUy+ah?Nq?c$Jom_{9rFuRLs zY5xY;_;#I1ALA`Nyxq?g0xnN~WQ%|+8@RWMw0-_`7DGNQ`&DvP^9}|-y8miVJXDQr zw5^;ht~efLYvC#t>yj*`2Rw>>D8I>-0hx0KbVV!!_nIsn9Y0o2tfSWmm59lqV2(%; z;mgK%*rxLD<~*ha;VVhga7Qz^+OEQ9jMk$~`tx!8RqDkXaz%Z=o-Ycp zfiG3fk%|Bf=wV4q7#)zYxVuN$M{l*P<80W7frx=q6{Cv7ZQA>*76>v!&${;sQ!Mig3y{@y>^rKo;o|5i}w@HE8zWm zOX&Je;qe|8IczZKzppbAMGvC(bz=IbG*)ds6-cPOxH0mX;RLk;zur_ zH>(V!uH(&D(01~Lya^xFf~Y<Y+i=DL= zp&6J}5Ce<)Zna)Iv$kS`RO+h?j`*Lx%Lpf&(46JPPR68CqZ-T^QW|H)9iAcM)lre}l62c>S=tkK_}^ zM&i%q=Lf&%@W9?V7LKz{_(2W;ZW6PG!G6Z6$+9+7D6sF(=f(|1R#X zh#g8yM`5LDcv4&s!RG56<9Z^G#gKSbUvHRn7wk5H3A(ua4UKq=Tss=vvJNrnj~lzb zFX?lK?+q*Ba`M~VtQZY?^zN}_{kH0Dvbz^VSs^wC`$lhi3Ix)8dhghk=+2%s8ShXW zNAH_pl7Q^W*0if&u|?;28M#~A`fepSjHDhFt{pn;l;D+z)Sul1Klr$<*Aa~I_G*55 zgo|Rz1m?~`YSJsctLH@|54g+IwaRKLex0j`hkB=@tQ*d!pk3)eLeC`TY0Eku{>UU} z5@?6SGHHc@Xm%U&{@Ja~_x9AH7LRnCX+Cbn_0hT`n(v}5SDI+J6L^;D){lI}?@XX> z%ToT*yhl+aUyHzw~jmDYEzVq7ti^85(2;0PJ^{M1Ya2$tfu{vz4 zQf14~YoMN9+*k`sZ?-#)!!&nWq6HbjZxBt}M+Mway|0`2$M1;9cUuw}+7x58nWT&H zqJvizIwYP8Q4LDd2%Wq%V^m5%O}$?Z>#brnoTg-18h=@f=1zcW`^J6k~CW! zDJ8m1H8z%Z!dRIM)vs9<+-*`5Rfsa`WiNBR0ZVZX%VIM52iAQrdyIc%01l~4y~FL4lM$djsS0VI zaqE3?(x^-Hu5~irzu&Jt$gW-SM<(H40=bPc8vljP`y~^Wjdor1a$(xg=;WJr#Ww|Q zKT4&vU^W7jMOYF&UY{~7sN6w%AES49*)nu)^pHp^6u-emS2LnwxZ;%dzdNdgf4qm# zz#b>s{;1F*1YN^dj{gx8(jq=b7AB}xaJq3Mz7#Tmu3P-C=;aXKP#Jqlr1VI|=?W0* zf20HfGW7>^ptz4Cs3)!aSH#}>XFP#LK}v#9O9pJyj}lHQIG(ht`k0}+7u|4d_&z27V?|J6u$syq>QT>~2$PKPCZjk7!IoG* z4Bq-n5E?YOgHcW}x5hsfh9%JoyD*EXhz$rSm}SqUeq!^#P73Lp&i2|B7ah%=23nid zp+t^)jHudDP=o+UtN-;3i`gi@%_ZIYS;pWz=zleR12>s%2(Y2r-g)KfL8kf{+!TXh zkHUujSC)v1#FX#W(q;gqD-Bn;y0kG#s};Oa5S1OJP82WW|Cv|{KhXL$+`!gT_ diff --git a/Templates/BaseGame/game/data/UI/images/Torque-3D-logo_alt.png b/Templates/BaseGame/game/data/UI/images/Torque-3D-logo_alt.png deleted file mode 100644 index 3836f1e7fc26b23ee299fa02570bbed343d2cb50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11616 zcmXY1bzD@>*Iq(W8bN86ZUI3;x;rJLVG$|m1%ag-B&AClM2V$YI+t!?X{2H4PG7$M z-hb|$J9lQzInSK=d}f|`A~n?&@Ng(_0001LZ!w=<=r&Sn zQUE}8j)kh!)zdefm7=y901!?H0K^aj01r>)Kyd)Ta36p|OaK79+X4VyjW!Pe`JM*j zvXzn1)coY+?&S8#$(c?`MuyJW)#;*(tk24F-E^gfG4K@q0|oBEluqp_QV%&)U!P^y#YkSugyqHz+* zOY-v<5_BV(q)p3HiS29i{6bq-&}zeNINM z+81(z#lNNa`t>!BwYm9CFd_f0wYkCf?v4(L7xcv+;T?3}$2zK<@Bv*l8jru38`+*f z#&%XTbOQizp8&=sMwwjlyML;raF;W1*Kzvj?rGs_4bZf({p`-IE~iTe=I0jR=6(J8 z+%*pX;P6zEmD2SxJup%EX|3RK(ID};;qIc{tbGM?R3~BHzuWPKRcwGRg~5Y4lA4)@ z5FetDowDclJe)G1k8zt{D#eO6&wIMO?q_j#Y)I$AORemiQ`)Zei{_sd0{zJF$UCC3J>lq4Y` zIy#C}M@T@VuPd<*epeC^*?$#uZ&A%Y2n$|acdgcFP?`9h3=|AGjsJD39YPe%d@b2Z zUG}|&|A{_78WXRs;)DN6g- z90#*(ryfP^WtC0noDFTOkag{!om)ENgbswf;e`>%wX}I;`^$N%9G;^D`1|>D$TE+dCQ~s+M1(ca;Yc=f2o(cR(2T zLY0FO4?&#f`4tDr34P|p`RT1PwnP3MAv8KnodV}+jx?|WBIbSEg;OZjI&2NkY?_n) z-nIq*jbA`!z||XGXi>?zRk|n8fe4+cgVNapg>5OeIxL{?k+hzxZXa5 z9f?P-tlZ^X;pa;wgmq#qy05Fb**P@#J@eOTFZk??IVnl_iST>rA;~(Z>U@7Oypu?2 z5At{x*xe47t9V@lhUz2{4P^=ykH?-9K5X`|>{*niBUeeKOs`h_{|0Z5=E7cPDBYf3 znfa{`r}J-1#;`oD_MET=yrT#-NM_)C%>l9c_K)|A*ao+g5o zISALIbSF6JJOp`aN@JFR{B(qr=)c5~*A5$t{&D5`FW--+vCRZuW4rn4F@ z*dcA*v$r06(&fa9%@t26y8h4EPwmJxJ^2kt^%<~;x@bwF=)8kBgev`ek~+8;D=wDF zm-E?OVLc=vyORG|CuC12_trgTO1_pXQ8N&WznJz3cTXJ(zrB^fNR2S|y%1GG^DPE) z#vt#AM@v)UaSTVu70QIZ>bV#$sKk^{ds|oaE>Ryx`}fM6#g+{|PZn1Cg0Tl1^sZ1{ zUidr>1B$lnK7LQXL`L;a0w&a$ZO<9BaV`a>qtmbLZaPAjl(ZBd;BjutQ=gFq@9=zj z4P*~~V|`+l8B($j6b@B}3q2UT^p@)(J??MSY z_?c3P9_PFh^TOCF_|ve0o+@={!GRonmTaay-eg#D8WDyMHe<|h3XyK`G~Q8B0p^pe z`-GpFt^T&ofa5C&&Tk)&(r)w*3u7=1;G=IT%PXn_`*v+A`G((kD~7o>WCjJb;A=jSZOgq?au8DT&XkFm2(;P$&bGS-cI z8akj7ha#2yT!-w0`y5=%-zzE!*&ME{O70?Sh^!V3S#-m?_-rnYX+c|u17(tIb+3A+ z_bYHCps1cFeHRvr^0%8T#?l_OXWm*~I{n-iuwbbV-+-b<(?m&LgrLGAzI?1qor}mr z=4_-xNUmGls6be~n_t^Rws`%msX1J`R7GR9Pb^o;G{bjQ>8 zr#FiOY~wZ=1NfJ9?eUUCr`h!Dgzp>B5$Ts9(qlDpuXYgd`mAl`oZV>TG#+n-s`3HBYn_j7;QQXn&%rhX%ClTgiR${ak zC=1!7U9F>=xr6XM1dT6D)Q3_IcB0Z;#WqY_9f?XgjCA4L_rOoHEo{PErwuCRl`Bz8*aG1u5K@nEABJ5Wq`F2-0qL|)Z4ItuI4c=xlXcNUd(D` zF2=TL+%P0&{_T3gd3gdG^RG$Nj``o8@g@s;QH5hRlz$gNn7vk4M$lJ|gjD4=hXt5| z+OABW=3aC1UQ$`57@hYep z$c#S>v7Uo3Tf^eBc?PHS2{uAlf0;a5uXM7swb~rX0UPw&s;@f2B3DV*#v!o;sf^8r z(a3X{e6>@mBlA<*E#R@&ai${hxnU_D%JJEbS=y!)sysje>g%^$JVSWw1rH*T$mS&m zqUkvWJs41MVTD!a*e5<=7MpiTgZ}zOF5DH^3Xx$BNO(RoIAZ4h*b^z zQg0y@Af4K8e7Xu^z&gqgJzoC466>j^K|T@M64ID&K3n}PuD{=qX;U=PaZMVm-iY7` zI9KPXgfysmN60?q*;XYavySC^kF|yMtqt19db>~&1((4Wc11UEteok z?pK5WkuUJwQd54LcNHv)lSb%W>D*YCYpT7HswYjgEGF!hQS{u&b*oxG@`gC4i$Dm? zX?6L+QW|vi{p)egO_BulGP)&u6;E$^Ghg8Qb~+PCY?CSUHRg zT8rr`C+?p@k>8yRWx9+$P{LR#3^THFOVS0PQ|;Wm$)N2h)nh>Fbp{}-jzhXy%=~GO z?^wqDahISz$XMD`-gxwK$lojc;C?AA@>u$6M|B+pgY*?W9XEIp&_QN(u}13=VuZ!J zPXtFY2V(DqqS^E?f0iFR_pEk}3PK2nst6B!veS`nSN@-)7Ka zG*oko=AGl-5A$m_tGP*?Z%v?c_PS7uC ztjQU$4khrAf+mIl8&rgpGcLi zHtSOR^R&V9vvu{kxoW#Ryt|vm4%yU}Rbb;`{CjzW`7=bp$A?_!!o5x(d_9``&6`fR z;wB|u;jrFVu(_|Ie#KV!?4h}!7;WPG09MzeD`pdkY;)b&X>j+^sphZm4<@i#y3iOD zCkyX#Ue1eTHc?Ta6DmwAk$o%ZbNtF)+`=XE>R*zU3OelF?z|6D|s{P59eWGv5`Q=G7Y|&YPH&Xi_lh@e-hH(%RrOm5P?WPmY5E9pm!pd#oKFtNo3^^lOk7-IBd3KU>V zu1E?$ZMq$xr!i6?AZ6un9Gm^Ze&K1qwM{_vN;ECbEt*7vs0Sd`5ei6HBBu(u!cKjD zV?ww?f}$Su=i3YmbA21n@WI~%PK)0nBKfIL6blwA2KxCOwT^_O$N?xky5@pYH7dp| zHPTwrd~K)ey>7+l)PggGO49LLx$joS6?XQu&=#l_#PQ*_0xDwAS`p?Ff^Xuc`tS>b z`i^?{UF+1_KZox_iC-QLOyRccj#fHqh$0|9W6RN2TGUGdgAzazW+HrR7mJgO&7w`m z;N;HHx|uo?@n;@unyF-|70-Cp(-0(i6%>?RUwn4v=K8A6z49c6lQc!$DW`qA-#vS! z-UHApWfbmMFVNVE!7*vSXvLX9>MFrUoeBwOc5}}=S(5HQF#qlfwsn065v$E0Sz42E z5ceSDdJ`LweNES(f*J4l=NSF%+XQ_5+K_4#-jMjrvFlP1uWD>Tk$e8PatvK`ZsE3qWCpLe1PM7Z}<)g%9&Ed)?q-qwX+5ci{#S;iPc=< zi|f-cBWRXt-u}dR%`VpOP8n#G*0)~gW&~^ zP5%%UO+;IyIwDirOFZr3JwPl1w z!@#*S{Cc*Phc>LdEy*|0C}-MUozm z3itTbKngzT{h}#6xoW+vjSyPUwu-y)01i8Bs=vCA&@>l>iD}~+#EU-@z7xRU03K)< z`StO}EA7?(6w6*ean4t-j18j8=O*NxeRGyjhHVwwDjADUlCh68PX@KohA_2W>F$#T zTI(PD~6(vy><=oZK>TTFO)L zCxb5JxJf!P64}Yr6pE>?I>(HF$p_dB>r+2+GlI0V0N(sxq*J8-8__u)<(!Su6K$Ze?^I9ZdoDNZsj?FA1p+Kj8<;C zbE)F-xFHQbSYp;1JMyteKjL6-(Qtuzj^c-rB7`K2Hdg329}Eaqa3=i2%OBSGQh38@W^?Tt+N zltfEn#&ZfoS`%ve^R7F5(Q4R2mO6Isql_rD=F?xwxF39}i1*y`yjqrh%k*^$d$*>9-T00tpXuK3 zlq6ZO!6;;N&)#o2!6P!F0zV(EhY3Eqr3qOc6=q3LO5w6}y)cVHa!$CoqkoLFE3j@p z#(7u*H4t>-B0}>`%pk65aXX{5>UAy^a@b>O%Iz(Wa-XM}1Ch?OJMBkvUt(j)$A#fD zCrnEdlh$IgB?;6iFB?cJtcUyZJ|`Tl|7?6RVoD+EnP)Rkwy zc=A?#NvFT+3(+nWWvW9G#Mo_NM#AsyE^T$pD**|J`_Crznyee?+>mfZD8IL%X}GD| z;`NLwm=5A=d=;*5T6glb6|-3p-yfDrnFRWx21>o4=M&Bv4;MoiL<2nNJyI*U#oUsz z)fz~(U1K0eDrt6&+NQE0NLO)zO;FO=JM}wHi6dakq5^T1>eXc3f?u_D`sXhXMO3nw zx=+-MtSeoUioVGOhRI&bMD@35H}^)tgB(|WhVLbdARD)7HX@~f$mREHM5WP4)zO!y z$3}L%yG8lUb4BKqkv)Uw7^2@TaoA>6!Fgxx7)GdJUt8_S*E-jTi5yn}{8_vdW2TO7RI{tVI&@hSWw`ZU^fV4rGh8k(3rKsJT)IM)s{J@h>o z)vAm>mVCZ4U*m)}`qHLFTZ!O+zQ0j5HGM}}4ot__N*DC3daYL~f$}u~5qHRPu$Zbd zly<>oRL^4mnQxFQ_bjkWW_eT7n7|(oRC0dV^xe>m=8dqXy0I`wjSrE&^@1GX(yrOG zCED**41Y=UY9=GAYY?L}@OBjUg1`#ofLkk$ihFeJD+F1mhBMNd(H&7_LfGkUd^6*7 zuKlW-?cHeLv5IWH;g&i!UzCTg;q!W|uQN4zP&Y2ypy&2V=R*;;X+B->R>$yiHh^>G%=JiFX4}-S|JJxW>XW6 z;_nT`hqPTcI%;BHc91SawMtL{8yy8wXm>*obe?x^YwX_fH$l)C#F? zdE~2m5UPWaCtK%{LCs99;sP7SN_|hvMDe`1~#VrxkcsM3^6B1}ZR&d>y$BD_zEY zA`A6)Nkkj6O^hJ~I1r=5LwXmk$`y@Gs^o2vLGlyPnTKe86?+!$1`}B5W1A|}X{Y<7 zJJ!)xfW3<-G(; zGAupOhqctSv6?V~o-R2lz%~r=gekL7`)^x zKfUfUcf9tz&7Kcn^snSX3z0b`FU#G}!r|51sj^mFEy7*%_El_V0HUKD+5`|?uVhY+OlS6zgk{KVqzJK;Y@l!>TXc(_>j zvX|F?_K2G2?T*qn>r8A?WfRQRsnU7S-i(rEk59J14qdfnQWut8PZ9oRgr1DDm7cVWJ6vl44#$ zEEjtAENUe5$Sc5Q%`>mJIR(*Msb|e`XB&&*^q8>V{1_Cf%EK51&}#$cKl5(h)(;tJ z;^X)|3a)yJ%P@+YZohFel1;e*{0W7I=oEd-DmMKu4z?Engg4gaNpB~xmG!3}(Ggc6 zrYUouvtDzyDGm1pcfh%{!~U<&|1ow`HtseISZ1x9d_h@;dyI;7q6~)Nha5%o-y0f; zvMWsm2+?QnOFPL%PrfF|#a?(vasH;ne9jUhoiJt|3J-Af$0Ndphh{x~AUP>*BSicR zcD6ddax7R-(AsQq60PtCt%HGxCHIdmv_z}#oIk;7hk7#&R@)=b33o00ohbGH8g6_8 z!kC-O2g{nV=2(6Nn~(|14UB$_vp;nvj4qFhUlBHycHqEiv!cweDXSPr(WL&EjjVFQ z=>H*VBxEkjSe=k%?;D=5{Acgo3)wFeYn`3j3@u~`YVdCQohPu}{-h4gyUc*Dg%`u% zbg?Hme|e$W^Mkh&Km4#yDk!A>+j#iIO!Y6GnRXS7*`uuHIgrclK0}H9bBN1kPq%`; z5p^c@H5bS<0~88}TWgf!3(O@($vOBC;u0-=b^h@qzD5iKlZu1Ckoq?7@$>JyaPg-6 z^lHD9-`*^u)Evmbp!0bz$!)D~Z(Ej%ccR;74N@3Ixp4Lv_09T`)@en=4OW#;*M5Bo zNg&I9cv0}tY0+LgM$qbHpo%(j?tCVeYFmI*fU_>*P+pmnErUMtag-bXcR#ih1n|&U zU6zjg_RBz!<{+VB`NzJ>Q10B2r~%VjvR{NR)rTFU$|KOwL__2!SH!q=`A7w!nCt2~ zzo0k|U7l>XpW5a1PS5*rd%tOOTyo|%SGa|#QtTO)@YI5CUc{f`N!gNfYNBO!plZ?B zk)*`Vu6>e**plgdO*uPs>Ow*dQ5Mp_wwCrOZQOrFxshtMuNPC)K3kjyNV^>-LLWQ- zu~5T5PX+Wtg4>3SKVBRhI(WhKF1A|B3OQv{N-YiMjhLAU%i8=LMOx(>v9qQZ1^g^k z56b;u7xH#Gau7C9J?64EP1vs~p0Gr(jt~an@yn58+Ec7aU3tD&@ETmJ{hN(OYEoQg zwy+}OKFDRp0!wRCuEXx+{9PO`Zi&QCIO6ZO-0ZF0cN6b7r=DlVAjuUpz$oa!qT=;x zU?-KLI>*8Tj^UKW@Nn}3Df`_NR{i1 zMtWhB`=5AGJn&`}z1+u7M)WYv9{Gy_sbzpo84l5s2o!a_@T36<75%xdp!Ix#2*u>E zFrJ#Q?^?5d3l(@gB=~blb?%(vt5d9BE{L2`$(a!4ijS>CoeC;M?q@S{Hs#V!#ShYy~&$DpKaxmX^;K`J!;>3YZ>b5#lht4FNRxtT%fB?;!Ed? zJS>fdz$&Q?SW&ZkKXf@`5Q4>d01gg=^)Ts5b*#{CG~OduN3cY zw=dD<(aqGLF^X+%C$9P^nxKFu+C`Qj;JHG41Uu;xGLkH%iJs^re=>Q#E$WrL=Z|=q zm2CC~Iq;p%=EV%nY^+vDI84mLck6ai;r7LUYNziM=v56eAWx*Lp|#3A+=3DKf^&im zB0So=dpX6o)kfu=ny3`gpwf@Y!w1bW#DVN8Jn4*n$N|!QHVAi%6Se4V%pi=C-Zazh zrfSa`tpCa;QCHFVTndD|rJAC`JkjAzz5Ev$sT@Fw=Bt%#ZEaXlRX&cayS&Js<2%h2 zW+DcqZI`<{FfCS6n1ZP2US|tnD!=j zvw~>tLvF#tL0NT!6fV1;1Oa`%Q~ z=70;WY~dtQm^q;~k^lbc)cgHxp-YT_g@4X#3hm_D2Z^7 z!(R?$NJAMi!Fz(*?hWNVFO_KjMU90Ti4}jAv%)!KOSIegvvzn?wg&pfi8z4}n`4-H z54z9!Jwo%JI?GPM{5lz9zGi_lQh`9odM1kcv);r343_<)I>BJGFjXL`8Sa%=n4>maRu2ECqmv{AAinZFCn%HNNIg$L z@ES(;7@h&v*oCb33s+D+@Q>za{^J=ru~xkR!Ut$S3UjC_lLUG}3Ov}2=SKYpb}1-C z^#3173zm7iy5}5e9%F8F<_oBO3Lj6>(&;V!@&u9X|2N^p(sYNSDd6c!)h4p18JYeN z7hbSpbDLUbTgn}d%>AEJ-?31IFvBTzGWhyWid@x}P2+8eWW4u4X~|8IE9cbTkFfQ2 z_5Q^xjvi*17NIJLJGQnXzf5!QGe7Y81b;q`|$Du(7IDj$!*Ei!~-`72!frH><~_`|Yc|4bSZz2t(? zm;G_g+lfw&?*p;WXpZ4vBpn;pq+$yaG5pgX(x6l1cb{&497vGlWA+z>e=dQh-}Tau zsS=j`151?+wI~Arc;x9q&`g^FR;CV5pX`?zCVo=>*-8RDO@Kl6$p>Y#LFrYm_H8hT z1qnxN1#7smHM;LfDF3A&JPMGgPUzvDl5C~FwP$=pfQV|kEtC5!1IDqThkd}1KmSif zxGQh&6&5=>T&EP9GGFhKT~tFaWDink1iI2Bnqd2u_*_PL{PV|vup<%VwzdC3Xk}EJ zb&z5orkM*-k2S1m(D+&8^pv4#(&&=rVXiZ*-UVnQq@C#lzi#lfO#7^d1kanrv$n77 zsQ--czFhNt|I0hd^xu%Wksafa%unv6G73M-uQ;m}{i`Jl`I2?p0UI3PP{u}mYPA|I z`EKGu##I_@&G2dE3**JV*h(n^C-|&=cR7AcdK{{RYoqym5&rT2GFprHusRt1Guii$-4n diff --git a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_alt_image.asset.taml b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_alt_image.asset.taml index b153f46bc..a0e71c485 100644 --- a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_alt_image.asset.taml +++ b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_alt_image.asset.taml @@ -2,7 +2,7 @@ canSave="true" canSaveDynamicFields="true" AssetName="Torque_3D_logo_alt_image" - imageFile="@assetFile=Torque-3D-logo_alt.png" + imageFile="@assetFile=Torque_3D_logo_alt.png" UseMips="true" isHDRImage="false" imageType="Albedo" /> diff --git a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_image.asset.taml b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_image.asset.taml index da6130ae8..2315a3908 100644 --- a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_image.asset.taml +++ b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_image.asset.taml @@ -2,7 +2,7 @@ canSave="true" canSaveDynamicFields="true" AssetName="Torque_3D_logo_image" - imageFile="@assetFile=Torque-3D-logo.png" + imageFile="@assetFile=Torque_3D_logo.png" UseMips="true" isHDRImage="false" imageType="Albedo" /> diff --git a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_shortcut_image.asset.taml b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_shortcut_image.asset.taml index f780d2f0d..233a8b4fd 100644 --- a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_shortcut_image.asset.taml +++ b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_shortcut_image.asset.taml @@ -2,7 +2,7 @@ canSave="true" canSaveDynamicFields="true" AssetName="Torque_3D_logo_shortcut_image" - imageFile="@assetFile=Torque-3D-logo-shortcut.png" + imageFile="@assetFile=Torque_3D_logo_shortcut.png" UseMips="true" isHDRImage="false" imageType="Albedo" /> diff --git a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_w_image.asset.taml b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_w_image.asset.taml index 7d6d2fc14..f7dd36579 100644 --- a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_w_image.asset.taml +++ b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_w_image.asset.taml @@ -2,7 +2,7 @@ canSave="true" canSaveDynamicFields="true" AssetName="Torque_3D_logo_w_image" - imageFile="@assetFile=Torque-3D-logo-w.png" + imageFile="@assetFile=Torque_3D_logo_w.png" UseMips="true" isHDRImage="false" imageType="Albedo" /> diff --git a/Templates/BaseGame/game/data/UI/images/background-dark.png b/Templates/BaseGame/game/data/UI/images/background-dark.png deleted file mode 100644 index 13b4bda55c7c7c5ebc87d54bf010a5c06c32cc28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5751 zcmeAS@N?(olHy`uVBq!ia0y~yU;#2&7&w@K)Q9>#R~Q(W?pK9GlmsP~D-;yvr)B1( zDwI?fq$;FVWTr7NRNQ(yJ#f-(1)jG1mahE`DlHEz5)zh~zxepOxpVT_WpiI{9Bv9I#?+kdw?Mc!cDDpK4dr}|{V&IObIM4p>g6Y)Ko^Y*WU@7C!{s5xps z7vDHvSM*e2`>)U)d(|VWdJ-$@8w31tXMb<)gZ@0{keYQFH(czMBs@q~> zn&;1NcI;VZ;H3P{>CyGM=RJzzSf@WccSz#J^j6h*-_HNqIhTE}(1%yHFQ514PTwuF zeDUoqk0$%w_WKpJf9a)Uwj| zw&2wQ&0pKH+REH@%}EmJb_!OW zGp4f5o~+|5R3W3FZt!_3_u3tm$DB8`oai-}#Ca~`Qq7uoH$Pncb?~A@@l4^LC7G>z zD%R;QF+6$J+KrK;ckN2O+LLp8>-B`!G%V1YDXbPzV;dW?^!KevMB z|EKfa>qCbBwB3z9oOeEUe&zi8N)rvs>bEg6Ffg`cIy(n=Iy=LXIxvCHshw!+ao9oT zX#8a_S1mp|#%hPf>sJr7 zIGW@Y{QCU5^nxD!pXAgn!Qc1$82$oym@D+;g2o_HiZN+ z#?F~lN_%HCKL4?+y?=dq;Jl}`@6KOb{lu5;hsz_&Wzu3F**<<*wzT-3I^X6=O9bW% z_e+*IK5}1oT5o@$o|VprGaDv)o)vEIJetIQTK0@ro0pBNOkhawr`9#6xt{Bu%UXIY z>iZLYo~K)`W<|dho=?2CWc} zKKVcVb>-P&YU+2E1n|75+W59#P+n?VEVPFvK^mK6y0hUhJ4T15>aoE7&$RF>c>?%UP zwoVoSmTZSTfZEuA*Z_zdfJzv6fH(n&8JK|>Wat4PMpc4a2CHUbjfH8(v=AnP-AxG~ z2M%#JkrMo%(7+xs)D0(Ey9vK*v8S5B<|Z0v9dN!QHJoVdChQS&0F()_+I)avw2T3U z4dDU`cMxLNoB%WxyA1XyqIKQ@nLpUvL~7mvm8-N4CsN&nHCN$@c)}?SQ}ZBm6ZQmr z02n!=WeiH>kseUEf)K@6cqk`;f}Df|MeDpXTE+n5gNQ&LWchit9diJbkqDRMgDpRU zoITjwL`3pOQ8L diff --git a/Templates/BaseGame/game/data/UI/images/clear-btn_d.png b/Templates/BaseGame/game/data/UI/images/clear-btn_d.png deleted file mode 100644 index 229c71e8bddaa102f495a3dba47004f9c65cd0d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 593 zcmV-X00s?QkPn?)w z6CVEP+t+W**N+`j{PO<2JW!f(R$hMapFe*XQ8a;^}fcc&U1q&WrzGUsRJ~|Nb$;HG%v9vf=yp@5~EJ%j{0ATbF1a6f`foz5TGU zkMHBZK=}_JKCu4%`b@n56}$ZWa=w55ESxrV$`TGP&c7%D0g8vBl`A{>#l#-3tgkQ2 zR8m^7wz;{KM@Z;(+3GdzvKks+{{Hz34m}oFOoJj$N=5Z+-m>NMzkdJ5{O|8yMqVD? zKm39MzuDN>{(%B$^X5%VKwbYCk<;G)|Nj|*als698ry$h&@!{I{AFfl{tFTZ1~u4K f&!0Y90T5sS_@w(H5qG>u00000NkvXXu0mjf2Ztbp diff --git a/Templates/BaseGame/game/data/UI/images/clear-btn_h.png b/Templates/BaseGame/game/data/UI/images/clear-btn_h.png deleted file mode 100644 index 5e67cb13b2b4a85172bfa47e74b66993f0b315a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 595 zcmV-Z0<8UsP)Z)GIKgXfZeFjXq_kgNUj7V-2Ju1S$m*D2rhp`p zl9Fcr{{5R5=;ZW=4s#>mglFXG_fcy{jGxe}m8#*ZI9GM_(p zPV4K}uWDReT(?V0OVju5+t&+J`X6r7>({RxLPA1j0TnU5ee;GTDJjwa)albT#>U3& zL4koCPoF;ZdGX=}>z_Y=nBbcJ{{71fH0}21PoJ2xva|ipoIP7*Vq(%dVZwyX5fPEM zf$}_W-n;>6Vum}9nVI=>M@NUoh4be%&z?P7X=ZBLvS8uDP2azNXPP-ylRQAAkeFdrZPpa1{=Gs2xW zapJ^25Y5TSd0R(E=N8C@o}O;)$f)S{??1kax3#zR@eA<(K?!mT3yaSa`unr^czN$E zUc7iJFaS<0UAAlz7dO|l>C>iXT3T9u1p0>&9^{~y21T5Oh2^KYbLX{x`t-3I=nMva zet|!dQj))bw*LbK(3UM*m>C%v|1%<|J&=2U{P@8N#BBfm{$pZgW%wAA<=LJelEZTKubwTGJIwqVjwiI($lj%e)b#h zSV}4U^((?ZzW5oeF0X{QG;0x_gI(Zp1%{y0u%eoqB*Be}+Z35ISogfn=j{1}M~e5r zom^~6`il#Z>bB`G@&P}3s^gaM{dn?`64>vd+uy zC)Ag|rg#ir`9=|JM=PFw+g^xf&*YE1hYH5v6--s@cbdf?FJvm;W#*#H1Rw9hgS0Vv4;mgMH;x)r;fhYuV;(S;&;;NSt=u63|? zz%6O(;J_d!D}&pg-rnB0C5=o>QFLPjLReThZb@}b%@L7I2uePB_z*;W0B5A7%a^0e egYzdqfB^t3O)Y)0 z9XimShOxs=YQDsp@gJb1gn_Zvu?5E&#SyLef*bddTyF3YCK)zo&)JhrF5V0V0e+4h z&!GoIxa##XdV>0jSi8!D*$CI(frpPId zoX)3*M|j)3>wnqT_NAKB=~QbCw1-x!H26BvM$lT86^U`fnQd^FLPPQqy@lE%w=B^f)Fy&H|PPw->A71`mp00RIT5=iSlljg+$0000< KMNUMnLSTYWrq$s9 diff --git a/Templates/BaseGame/game/data/UI/images/collapse-toolbar_n.png b/Templates/BaseGame/game/data/UI/images/collapse-toolbar_n.png deleted file mode 100644 index b36de3ae049d9743a09dc6fc26af740cf9841360..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 439 zcmV;o0Z9IdP)Ox_mJPyDg4SlUjSNW3W5uGwOEk!Lx4uX4pZl7UqAx0i=rnvSAdP_$$A20Su(H_ zvh10InGB}9^1v-*3Cso@F>PaL>L}8isTm_PeHKN5r}hODW+z|w`}Q5O#yHtL&*`VC zP~)7=kRBzVBuOw+YZy|xe)*kcR2>cgwbuTO8@Fkiwr+iIX4$!2->q9vYwhDG`qk=o zMb~kBVd5z4oUzQ=+;7}ZXk^2MX<21r!6szg-dfzih^e4%lbv7^R`VYwdnU3IbzN)k2xeK9 hJ@8zg^|AXCU;u#ob3iiM+rIz+002ovPDHLkV1m|A!NdRn diff --git a/Templates/BaseGame/game/data/UI/images/dropdown-button-arrow.png b/Templates/BaseGame/game/data/UI/images/dropdown-button-arrow.png deleted file mode 100644 index 8c420ab85dad8b5ee3ca92464665ae071a471732..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^EFjFm1|(O0oL2{=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%sd>6MhE&{2%E`$|abUXZ<1r^pL9db1gt1VxgHed#<;qq~ cW)1^}6XL9#0Z$iS1nOY$boFyt=akR{0H4Any8r+H diff --git a/Templates/BaseGame/game/data/UI/images/dropdown-textEdit.png b/Templates/BaseGame/game/data/UI/images/dropdown-textEdit.png deleted file mode 100644 index 3966efbb56239be59ee13cddceab917b144882b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 390 zcmV;10eSw3P)^?7l2ZX@QwNIJ_tdJyVq-O;hN*R;|Jf8oKt&?reAz#jswl zv@I};de2`VaYRw1b@G>k2y~N}rTzTSqF{8F^S*pfDsBZxV07vonVb4jntpET307*qoM6N<$f}R+y&Hw-a diff --git a/Templates/BaseGame/game/data/UI/images/expand-toolbar_d.png b/Templates/BaseGame/game/data/UI/images/expand-toolbar_d.png deleted file mode 100644 index 462929e95039217cc59fe50d6a95c2b7054ac0b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 278 zcmV+x0qOpUP)hgS0Vv4;mgMHsH*7Al-)#9Kh|`0|)U)I@mj4 zmz0y0VX$?;A?fYyjom>YT}CFR*d@cl!f^+Jx~ArcNG3!}K6>~NM125fq@~N3qsxQy cCqRG!07OkOz~-BXZ2$lO07*qoM6N<$f=)$pfdBvi diff --git a/Templates/BaseGame/game/data/UI/images/expand-toolbar_h.png b/Templates/BaseGame/game/data/UI/images/expand-toolbar_h.png deleted file mode 100644 index c33bcad6985b3862324279bc0f5457755b94f28f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 468 zcmV;_0W1EAP)qS?llb{VTLkjAsY;|aeyj=$>HXDkKfU1h$Gh(W#P&4TdW&oR`Nq&a3 zTN8um?Q=toI@keY`=EJd?T*CDZYvdgmA#wIqEGOnEJb$uEx-Uri&4ja71Rp=0000< KMNUMnLSTZ?xyoSx diff --git a/Templates/BaseGame/game/data/UI/images/expand-toolbar_n.png b/Templates/BaseGame/game/data/UI/images/expand-toolbar_n.png deleted file mode 100644 index 0af2f1bd13809d099ca3a5a5c9ba1dc42b6f66c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 437 zcmV;m0ZRUfP)4~o#5^Dg=ri|$!*BY zbpP3B?F$Y zwO%=>X`z&@9drv@g0dk;N^TmO`W3-u+KiE!MNwe&sko4$lziUp$nSm5RBnu=@2aBx z{tJ6eXN!gmYNct4`g&Fzw)&+;bvRI-=QzXGHr@KjvWz??HC?wpRyQl0+1YZdyi5{W zUN4=}-z_)f`gSe%?Dp<%8~-FuXmPb@UGQXjFw*+wZiCf_ZQoNiaUAu!c4K0>t=SF5 z!{LASY^7JJHJ)q5(e1RYDluRawr*}2FECOnsnf(0O2YO1qqJU$>_lDHiXEXW%d$tF f>$5J~UjYUHlxB7wIAEv(00000NkvXXu0mjf?KH=8 diff --git a/Templates/BaseGame/game/data/UI/images/group-border.png b/Templates/BaseGame/game/data/UI/images/group-border.png deleted file mode 100644 index 61234ae1fb3dee29eda38a371165d36b060ee426..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1273 zcmVRq)0SqBM&U{ zK~RE8k;)fTv@rNVFsUphN-&N10jmTOk|LETicKV_m54TpVAK!`|L<7|`4E(7K4ARB zDus5>J(HaE?!4W7v&qH}czMI@+&44#&Ye5=o}G2_O1ZzkpGs6d@8oj17WcW!E!8%I zG7SwXm(AMBn08BdCX>0T948-RoKK$0X0t6*Q&aiH#l^fexw~LXm>2UyPMmS3yc8^% zPN&txvs=#V2iKgriKmXs^9tJFqjWWIBOj#Opr!-61IK}Xx1-s?{L4G0_&?_ilXv4x zqfZ_btu8MwSK|-wsQY~v)cnk(&+H?8J(|C{sz$fn!M^&){#~l$>@n5f-deC_;MX2J zsxZHFtA)8SUGF$_vOr$N_B~qGz~m2~oD@4WwsorNs!FYtyCThVSEZ(BX4T=g^Lm1w z!FRq%(Y|`AS3jc65Sso~f)<#1w-6X-QZF0;z1&IJw>OAO*=w$5nIM949%2g^Yzljy(oWy)Hf= zKP~7s_`nZIkS{YqF~l(je$;4#Z=xBAo(3O1_wqgCBii5tJte9r;~AA?zGq4`(Ts_n zWQL)#a^A!gm6r6qM+nP?0Sc)kNm@4Xtw-=SGYrxowl6GaQ(5@5B&1Y;X$f*x_i`5k zxlG?JMp&eYe3Cfrf#}H=#@X;~|BtO`5XzBM3_XQWv3X-F3LkUd8np$mW$;ZD@}tlb z@grOWzKMePX$!hz`6y0z95fS#p0K!L8Eqx>`_a=%75$H%65feFik{-gOB_87-@a&t zo=kbNraT|vFoAMIeOeI8_0#*bHBgfWlms3M{F=|;vk&HAk-V?7qf70j+dSQteXuCB zxme0WXRY7zZQiQU6W{Gki*a6ad*$6z80sP_3%q+`TtsI83dY1J6eRh$8vuYoz-JP{ zd_mbs-aVmUVdndNBq%XE#kqTuz$8gP5_U;MoS^NwxEOTzWZpMPmn%SJ z?(zSC4+0292nh@kvId`u$uPqZCPNED8bgi@LmbC`Ql1P|ln1?_pHA~@{Z%BXuPKfW j%4_?bDUt6}KLr>7B{DrC{G$C100000NkvXXu0mjfaJE^D diff --git a/Templates/BaseGame/game/data/UI/images/inactive-overlay.png b/Templates/BaseGame/game/data/UI/images/inactive-overlay.png deleted file mode 100644 index feab83209cc442c5ad8dc73c2b86e0a8115c4743..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!foRZkbkkcwMLfBw9D?8~Obq{gPz9LVg>D`Q%4bP0l+XkKL$W0) diff --git a/Templates/BaseGame/game/data/UI/images/menu-button.png b/Templates/BaseGame/game/data/UI/images/menu-button.png deleted file mode 100644 index 3cfa036d8f5ec1d5458b0716efd2ea477cca0c6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3559 zcmXw+XH*l44#%qqWh=YvT0r)eB~$h+$R3K9077sF2cwE-f$I6Ia@lP>$8pT7Xdg|&C3=D&EmKGZR$`lF#_rjVQMSf1cG zh?Vs{JgjO98lRX9I8ZMpGN$D(cg4|yWM#Gr1BM+U_x~L1t&cullRR3652VcSP^l4? zNhd7o?|JE$$$nu%dk;B?m_M(2xm*r8Cpe)*Ov>_F%Y)DlgKYyN2XkdpZ-J=8UkP6z zjU(Ik`V^Rn@S3#pJyGAi?roxTLI_?mu#ku)NZ4R0x=laq;$b!pXtIEY9_W1iY_obC zcMfPFFxPZ5_BgEm*Iq4Wx8KX+7M3?DZzImGE0Ez;dJmkE7D?8NX*g}&`P{BB%_3%QXqvdF=QX= ziUmTOiaR$HMlTa%9eST~P2k~@0PQ_)>Hbg<2KjURPMGUvWAlpbO0`q#anDoGyK!xW zh6(a>p1{P(4)~q<@V7|^w0x4v8pu&Ii*Q8!Etr0vLr+Xzf?6!dIZ-Lw*4aochS|bU z2?cH53mTNJE(rQ8*RpCP)KGym5^iqVsnzQ*L!t2Yo@jJ~2Te*d2T_5dZMQRyCv2zn zjbj)mW|WdI^)5lEJXL=2go#Q@7N;^?|6UyHU&&(q&||~O`jN?z+z&>6L!_8aZ4=Pz zlzyIVdMTGA>vj4B=TmmldH$KBS1D4=$qHH)NZ~AD3mP2)(C=ryubaJ9AX8oN=qr3J zJlK{!tH2{m8bmwXCUn}fC>W$pc%nfpCg3}rM}(gKxrt9UC-yDaEOk2hd=PJmV5)dP zStV2_4HT-VR|yn9s6hd!d}dxo|%w}_eznQ4><-#H=v;&*&`qMg2i9;b|GnB#q3 zPr`i&azOKhf+nBN z-J&i^zIrLG-R3rNxW>WxDT^Kh@+cZ4prOfj=$}~Nc8D{uEu{}c`Y53c*jTBitGTLk znyj}cZK}UVEjn4)%jU~beKlI^3Auh|#TkX0wl3t+-jPwAi)k6=;+hrS@R*OSF$_e# zEPkxR=BD!;1yodw>Rd5Iv~PvUPLLd>{na}ysjPWK>V-vX0^8NX5KGRsG@Yj%BlN-) zZN1-<;zUUIR9JdJwc0Ga^`)J>4N15bA9h{sD6_5r$H)2OlSabc?e+9)YMw@%mp1Nl zgBh_R-S*#Z-hiomp+B`)h<6n;IT78Rgv(*gi_pXEM{dO>4V&XWgihK->h2}_wB>c4 z=|MCb&!?A-16D3yJiI>NhNu!_nW-7}1S6_Wi6~zx5pDIr97S)(dG7p`3mzi5;;!E7 zb-Pysslak*`s`7uLi-moDVr0_LuI=W7`Fg&=Vgs7I7d-lf*bV=DI!>hd9Qdotq$DG z`85Ug?KpL3XK7GhMwxKE8{Z>^_42ORbpcst!#1JNmXnM6o5O4O$0RQHcN6icK{Wi)SI$e>6*5fod zAQNw6klE8NXxii>Y6lr>KzEwt&$8P{7p0LWS@wb1!@&?O7~i7zu8k#pyDaL&A2#;FwH}<5GB4$4yUg*q zW8Kke@GQf0L}#r1I_y#j(h=1EOmufk0gNYS_;g`PleK@e;ZYgAwD&qE6xxxM4R}}E z>^Ld3>34>?=dBiyYP7nRcOW$LLB88UEegcQJr^C^B+$31^BDaJCMigGqxMFAND^d` z?Jkq3Dml_no1xOg&*xcF8b7Q3T>A#%MvT`gI2tP6o~9`frO+YOeC?CgN&)5Y~W?DdSzeEXS(eh<7}Yc{&4O6l0j zD59-Zqgk1uKK!lBz%{XfJToQ?h+Cqyz}5auKgo*L*a2ttS<*C&ZtWDbA_eJ67c+45&tk4e5CL zH?~@}3Q|83pl&vV;ck&wgp;oq*@dQB&v7Xo;m)~Ym$h#{q5{nt{B}l_;%^~MEB^A< zJ68`*CV!lnoZudr-Fml2hBxbdEFz@2^87Kz^npk-v?D`H8bVOV)Z9Wdf7A97Q1_k!vZHI zg@hb_drSVVeevzGPLGr@`BC(bWzIe8nK#rV=2?8lM<_FRYA2YPIZ2;olLJAc7Qfs+*wz@~Jv7aX!0KfN6XUVM+5uB@4_rBTOP%~f z$mE}0y8&}UZGM<57`ePV?dkq&Yj0c?a>`H$e-}j)l2OjjJiqIf@2y5!eAwCQjGsBo73o* zr%$o?U)`v1xS)1X^U8%FZLLra&K=D05#za$=hbp~1YIq!Th_GwQkiUHOp@$fhT+I+t|d*~C_Ly<(&S`wCOS zW{$6IA7`Ize)b5wSh3F#srdq`;yXs3z}qT;J@0Sbde<$hrF%!tlncU|#4Q#gCCV=H z<8FZV1Gyo#MhVe^7R9+(=`|&E>mW@`X0~-4Yo9E@zAWDqY&z}+-d=yLpe`NhD zn=ignNRbReJJ33*QI|d|t8M7dVci?_QYRHgvFrK~d77nw_Tq7cji?@nk`UZJx;bqU z2-bQez6=1yb-QOY&ZsUePR`ADx!GS_00LtIt8W_scdi~23Yd|e_LW}oTMHX`B~}K8<^+-*Ke?ri}TMj+=gAHRt>c8TR#7`Kixyst3j*N^EUk> za)`?&dm@v<+xC5&*puKXCw2tw+k4w$_p;Vyk2M4x1V~$#Ln@6&-97&xJ`n_)#QhVa z7_C<0q7Z+>lpmSz7CK>_)vGXa>P!DGQ13(&#lNvCGhE>MmxXXxP%)|f8~w84JXYzS zx}su(u>ALx|6!RR5)kD7FT{A9At4W5^4d?}aJ(b`pJoUIQ$CF8?;g;s8b$@+zbL4w ZSBpO8NK=0oeKjq>KnJS*AI-m_{|h>L*X{rS diff --git a/Templates/BaseGame/game/data/UI/images/next-button_d.png b/Templates/BaseGame/game/data/UI/images/next-button_d.png deleted file mode 100644 index 76c3ec0ffbfd0e390d18bf15b641406a1c963304..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^+&~=2!3HE*cE)T6Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JigtRsIEGZ*dUIWo&smX&Az+(=poWapSz@o$*? zhV8dl?=!aFoKn4xeZo2Nf4=Qb$;zCp)-ipVh!6ks%DPE^D{?9q{wDx9i9DW z-@5CHEdniu-!^_}`*}dN=v;ZVvUv|*i@L#DeRZC~n>o$)T~mbY?ZFzA*KO@H&DTlVp33;PS)Y-O Z!Sa~S%jms^DnL&#c)I$ztaD0e0szoGZ1VsB diff --git a/Templates/BaseGame/game/data/UI/images/next-button_h.png b/Templates/BaseGame/game/data/UI/images/next-button_h.png deleted file mode 100644 index f52f5fb4230f07e879e02d61472b07c57d07712c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 549 zcmV+=0^0qFP)0-qXkL_v~jv zlgT7TvAv7&%t^dYr_+a#hr^+@TrOWYNQ8?)a=v3urz2xpTz;W+6qyRv^uk~=B$Fa* zY7trZc?lJ%X2T_NO4CLKXgbTNCUvD{m}Vo^YPY~Tkd2ce$z(`A zSFm{3{j7pUGGsRDL1tMpV+>&!sySO(N(;fVWY6>Px?ZdKIygr@9z84;3mir8H9bcT zKSQ{#tA_9UkIBuZg(!-!TCLy*m)dh=+qMwLF?PEhHk&s@;`3dyZQCkM?RFd6?G_i? zH&3?FXf)96b}<|dg{B^9J^vSnF{HXe^vpq8OGKg(`@ zDPc4kq4(575CoTb2I&Kvq)6s=Hk-l!@S!1z#rXq!I-TG+j+$?6tXwP5KmRLDro?qz zvLl(u&>hLB$=P8+ zw(YFdb&VZ&3=k2N&8;vD6%z#@SPPD4Vq~7_lP=Gm!*~tPGFXzjSBY6BP=OAZn1#Yz zeMOAFs`Cm16Yd2fQ=s2N5ee+0alltX+9{%Ju=RO7?f|t1WmQ!f&x7^dJ=)Ck+zLbQ z8C%e;EK4{X{$aeYESPxc)^_`2^&U`(>ag;@-~WwZxO#4HMyn_aV}GbRTk76dt6?AK zsxC-Q@=mGD}pHXHn{a?_1VZvZ|8^e0u7drcunPkNJ1EWBngI a3oroff;ABVIBm%Q00000druqyUGAf z2ad>Nqx!;HkN3@2CKk@`8z`1Kjx@X;P?CBU}R*dAY(aWc}p1s?2xH~i<-Kr z`d^Lp_knvKk++8dk?1_^DDxYe1O90)i5XCFl>^$z^TI~!)xVe`qxRnIoshhPFo3FB z{hN+F{@cAk_VejMWw<2QQ=s~7%e=Man|?t=r-O&sB!j?PsmFOp0HcCkgCn@m#jA)N zpAhv@Ub4SQkMKGn`w2p_sxlQS`7T*r*a#%~4x8~;C{HZ}v}8H~`gtM8C;gpC=a>S# zWnZYIq*|)^J~?cv`EmGve-tHYX1+@~`7QfIylUBjDO?>&4O~=oEaWS#{e@ur(9s$y zg$t&_9FWfn>tEq6ZbdAbOn82PL_6b*rLID;+BejSM6s1d@D2EmQ|Hnp}CV-f-^{c-&9^nFionUgO z16jW~6Um|xqWG#?c3!Jv>r2p*cu6pk^H8?TTF@=>xKNOR(V~LZ%j2=eB=b4<5Jb|MfIgx zbOE~bftTAG#uCIunJP9s6;I3882`IfBdq+X$)(yHdh)LBfYvt&|J;JbFTmZ}8u?ER z)aLlm>Rfr)%jP^bQRe4yIqwO|43^VMDkqM{oHd@pm7iVnSsdX0vo2DAC7`}b%@LXo zV-qgmXaAZ2P}w$Vq~D0W&2Qn`|7^NIZ2{>0ihn}yKzE!3)+K~Hlz|39H!f>J!l9T* zrjTI4eE<(BZRFceW-bakY23U3ohhsE%(Jga%dWQncOi;wMB06mJa%((>RFo+afX-% zqFBW4=%QpcDrgXyvap~H8`E-E4xc~pzSST0& z3(>6D_w2RiBojRG9aJviQz0DrPa&aN68{;`QRD&O(b=rF!cgbFSG|MEh7+clixo4F zl-qLhKPQo6rcd9|aJ-Fp=8`_J<94hu!7Wk!x@$|9XY6&}rTx!G{1jtFC+=ie;Fb+_ zQIz7|cvdzDBf)l9AV;8v@c#@_Ct8rIAe1A?)u$rL3bEws{e=ag5ruD>1Ldjx&!_|D zyGboaaZFCRUYN=q-=*aHgTw@rBGFH8WBz9`{!l0RUN7`YRi_WXqEcbF!?yw(aG%iskio=3=J#y|2gctR3;M@B=lX z>(DdeB$~Y_mU7*8Te@O@@Vjd0|1K?1UA?!GW$NhV{B3^aeW4R^^vWG|LtEqhCZZbJ zTH$@Gc(eF;hF_w5;ePDi`>7PHWuPk8|F7e<`StmC<5`H$|AH88`(ip20Z=|1wp}dz zih7aoD(rRL@$VU``FCl8I^eTu{|5Oc0Txi|4KzbK*V12fTy&ver{( zcINo=M|Lneg|_z*TR`>nDk6gj=zPcP{{K#o3!Kw&Sb@G(_f-{noBY9P$o+;XBKR!# zPL?O~_LwLiH?D6sq5byb{cSnh8#@bA1iG`q>+Rk2$C*S&j_t3}cg*+v8@c=k$*}V9 z7;3%S(Zi!JFlxI-1L-3pf`K}&TQZAK%>)?aK-Y^&ePN83%NU;*7vcLAQdjYR_xJDJ zakNs4BA66{53_n+^yv&!MDft(@EIaNH}K`9IedlX@xC{u_fu!!-(a)1N7f3j{a>zR zOn5GoZ=_D%xmJ)oYJ;cf*1h+cY!psCYPWK0b#z-2SYP<+`kPbQ-R%LQIm1A!1=^UK z3>&X2)ok@V0S=O>3zAv>ztBJY^kG3EQsp{&PZ3n+L6IlV(G2e}Vq(TShd5%?0CVUDSBmbpc+HZKc(S4fj=DLpigG|uN^4ut9_wL**@c021v+HkNwRhxy z*@ylE0%JR8ZJF87p4;iRz5j+Cqu!O|pMwwE7qtE)6#i>2B_{iQlr`AH(!!7=|ITm> zV}tv->-Ajt>U0HDq#x(vduvDCySl!?>$6g2J{bXA*2u`nKs5QjPqWW^hha^V&%5_S z^OuPyh|u^&r-XPMqf;fH<9RS5CPmvltccTj`@Qoei&V5A?l3g0FHETQsm&M>=#dR= zyDz2v^OG5|1GF=F)BPHzBeZUe@Y643IFGnY$GO#N)tQXs}Tz1i~->m$5LF$k!x4Zkdi`gG*GJ_*_uOn;F5kT$TZ=}K1El#3; zG+UlGE}zF@FOm=`>GszUN0%YKw>t?xgrAny`MsVT8R~-2HpoMSFT=z`gt7nph6V~f zEwSxm%BO}j~vdiYU1xJbEgJ6}Ad;;6j3`qYh`&WlALPrIz#6PbsZ z#)T?- z6sSEe8AK*6=t3iHE84gq4^uHSh~;{Z6YYNp`+OfgJ14{G8*D{h@L<1mRiOS5B!*6= zobO8X*vO|m#waV$@!HeyIqm3t$4q{1JKDt50zrvxz-GaI$3;10bD3-OwR({1y=uw3 zz&2J;az`m|BYxiq;g5oga*&83tYx@ggAqif_?hL=kfL9$8Hw2yi^&%8L%;nlZ6Yuu zU|o=!nkwS`CYTR3FYERB4*B}}!QM5DuuHT8uI@feQz zdoEEyCD^C#`wI)lvYhE7z`M3t6d8-Q64e+N8Ql9ZyDF}xjDA|Vzq}!?dF`xNN=E>X zilmsjO8;}V$9ek#Ljt-lyx-1t_PdMXP9E2OY3GwHXw;v#<(-!DaF1DCeS@vQ$k#{s z?P0&Y_M5Ode6i=dl(6T;hNw@q#}%rcV-(G1%Ej-WY{zfU=lj^rEBdiJ&4dI5?URh5 zZtU0k`ejT$w*8Z3YZo`+GXGphmU%lQvl^D^*JHkz^4sd02w{; zH19wXOsOR?FMIFUbP@93$A~IR-AOE9OyT8w6B3(U8Ww%JpvCzuBGYQ#TbMFy8hz{e=8F<^lWSFT0-j z3euQ+j!+qN7Vt^R-?EWIb^uJiWzi2*63(uweD(~;@S`x(jfcJ8E&q1iik}jJH4VLA zD7_!h(l!F2lDl2 zGQ2&+w9NSTl>4gkv7_#N)w^C?fM&0_<_hTIBKvmHceaMdhQT%x=2%(Xl!j1+U6^)G z#d>&yT-L?8!sI$d?gjQdfqkj&ZQeBIsIT%%=Cfye=lF`b7B37asdhg4QiX zf0N;Sm$bT;HyqN{!@daRPO1RBmA)Cy1kL&F!#*#&KD+I1VT&c{lG8$Q`J5Q^RN3SF z()c6_?e}tRmgtZict*Hju5ItDDXDTH*7X=3edYS%1j?Y=-=W}wQdB!$qWC%W;SKqO z1ia^0>d+f))*M_i-Z3g11##MN{spaE3KgA;B42fAuLs6;PI&Y~fisjI@YQ3}kAXet ze4^Xz+!%|;@mo~Q@f(yJc}+FHO4a)zR!@7V{axmpxSSa`BG8sW`*U{yBK=8zy>JF5 zc(e$|kG2+zwp&skVwoiXOUluQ4o%zbsT(zb&#-Je>)RC@|6d_kq8%c!?{a@C$LR~~ z;dm%zqV9(xBA8?fo3iFcz@)^1r;T{Z1(Y1ua zm2yF*!Zb#Q_0nPPM|~DLSQx~uiMHAo*=~%Wfb8*34UI7IQ_0-Y7gG|e4lDK_3Dd)H zOU($^b`Vkz8$?|e?m!XX)8%@O=*{>qAeTn#Eh@N8cb~KK$%@?TGswB~vh&>vmd|na zcbzMqHTpO~Eutiojg!e^%p0tiHb^sAwzt}VjaIa(aj~R=AePy;Z10LAwn8UH(BY$Q zN4y<$>Ew2fd>CfZ%miVF^%0r~y=Im8%U|IedYH6A`m!FmYJ}t&D;egDI(9TrCmBhgnu!; zrZF+34eDeg?1Hht^6@4TK`Gg1!jvT6q8k|aNF&s3w*Lu>9?gRzG9HX>8F5bXV1HxT znn;V+M@L^wSG{wfA`DQzBx1JHm?x=P44A&>uV^NT+jcII$zKJ;Kv{93F>a&P22V1a z(SA#`V+7hG2Y9xtQ<_EEOs?ZXyn92mzObXk>3_=q5XS~e?I~wGBKd{3yQ2AH)%wX-z79KSW@0|5 zGDksTI`Jz%{@_r=8{-O_a-3A`1_*jK9pi{qQOig+*eY3FVIkgPJ2mK-mp2|Ef%W$x z5_RRVki3|?32fblhCAo`F}ME~qOcy6Y+)%lk6lq@-roNd7Uo+N2n zJibT3G0*;Bl7WsH>g6it>JNcN?(unMp~!1&B%1Z)m1$Yal@wD*96cXhQ?a|Cj-Vw4+E^;R@!n^rcQec13VPDa`*vaZ zPgCk9j4!H&|2a@axaB@$p4H2L~9 z%p~I5A?|MXH(CD&#P=bQTNjlxC@{rq1>ooFD=;KmcPdNACV{Wrc*$VDuNv~@CI*yd zr$z8zWG?8*ym!B!A6u{7(vCyS$% zH|BE^S@Zvd7p<5V*i!#X>ZCM%!e1+LdH-J++CCreLlq>pHAlOh)=aeD)=|PC<(sQ9 z(#H=`Gg?zz5V>`^KWv8lc~gMS7;{BmaOUnyo>9j6*V#3R&rTot+b}9+iQ>g!<&IR= zX!~W)I!gS0Bk<5Sa<0nG3ai5N$>J?L*OM2EFr`Jwe;Xe;+^yuhepkykteT{$Sz$aZ z>Xti1k@|YR>|Xey+#{qfJ8W^PEM zO55SNy)3NEVG0(5`_hU)5R@RgA81(kFE=74nR&(wiuY1s@0piZZ|IaU z5<}1Rh*=Z84+1u2_=OnejN>$r>Hz?GiN+#2(zy95I zQy22C9lxhllCdl8qmDt0)i0-En~#cTy(Flztbvc`>8r)a9t#b@AhtKfnfo;+UKFo? zL^?T12}`%;qM|=FZtrw8Yze$<1RoFN&{WgCbCX`NJx}&iL5`;nHQVoNZ_29+J&ttxMkduK z#0U@b3jloUk=aMm@9ua-ZhNmSC1}x+TE)1o(XO0Bvfmgnp%KnJyHNQ)S9JYq<@cxH zLHHp7TXgp^!Wp?K4sr?vc+UUjMpjs!UQ?`c%RWkYq3w3hH)>5)L{tZ{l<&Ro$K*xq zmvml~N>OIEzrW26vMeXZ+~3I9lx>-HF`Hq+YrLS)uops4QB4gq(eJa4|1e;VMLj_P#%YSbC|R9VD0tkYRvMmV`6xK!e1Q_;KEF|3;w~(D)NT z5#CvHpf@GQjwQ`Szm(~8%JjDt6wc+T-K$OP(h9+|{2}I znxu_eU$2;a+TEgT4^GdwvvOq;!&i&iIA2W<)3>S4Y)(6x8Fjj`hYd1SI7r&zHAd8T8=NvL=28f)~Wp~20I9Q1x>f3*S6kQN8l<=Vxi4EJfo#N#EVzW3#@H$dsI=o}M8x|3RLU58?JnoKc z_zPdmyoldd^riy38~43m*=6KI_3inyYAdMTClB^~-tV(GZP@HF>x~l(GW)n|ErFy8 z@i2D8`u^>LRWKFE1Smlnc54h0{(~o9)?I8R_I@jl?ZZRzj1C9m2+vzFiSgZBD1=Dp zC|*o!0NYg`b9()zuhV82gPz-ksB87>W=Nw?(RN|L5AUNH(rm}`MmuCJ+TUx(29GS# zIyS)u*-%39)e*PLn-fodG2W3A!@a*Zc!iQ5_*k0)S#!0W_Z6WOEbGrzmiJQs5ocw0Xpu( z1VhVSpz9=$(|i9_lG5`HGA1JX0{l+Ii5p4KfbCwX zGSIw+no~`Rh)yvz%VRESEmtr|mSoEWV8(TihO74X@X&ATVsFJFv*eA#CTfgWHW7uQ zc=F;zm?{u|_LU54`VYn!$phqOjuUM%m!R#Y`iC-kv}}|efcPP^k6@}3iCA{Febu|S zm*PmjBTSI=uzz0(LiDf{#-d-%XRn>C2f_bM{MH7r4rHqc?rzOfpL<4jpL3ThJfvebS=1g}fC*5armvQ{} z7z~}vk7Cutru*%N%4<@f{XbHiPlCn+%j@I9NF)Ye8m>-#Z>f_hTVR9ByL8nS&8z_S zXf{|P$mVxdQxO#)WvqN~4&a{;G*v_FFFI7T8p7*TrhlMlm*gF@RA6;#*Fh1Q*qWOkWfpzU$Pe;$bK z$);l$*nPIv%%=yEZI>lbcZV)A+JnMEuyqJoGNf>k4oP)dj|@q-kUqfAIl6qN)K}za zrEsIG5R&>p({aQQzq$e=q*Rl8chk>Fys{l#c$y;0oz%*0y`umyzG2X7Qj}y?cp)o0E zHmg3y7E$$~+ztd7{5xXBGkmQpKzHSML!S*l4GPa#hwpqn!nyd(gCla6lKJ>!;pS-jY>a=L)*cp_aL_&* z9+Y>geZW=C{JlBWkCBK;mz5BuNWg)G9>*VtMq%#Q^ zrUGesy-@WMW2${Gw7O*V-t1IVAjF{fmoQS8M~o9iEzX2~fKQ2rK+xn7TQA&tIkhV$ zTLo1&-gc*Qb{$jteCN{gsmXB%3B*KTAWFw4ApaUz(wQ_1vcBr@@YA|Yf{kx_0ykE6 zJ8!;BcL(r}kEPTu8FQ)SvE$VQ9}H}8@4_yJd~`~%$vH{gd~|}~O+yI9vcrK=+fS5G z_+kpLL~N$i_eP=HS+>PS*kJV^nJknd4Iix7Wa^x&-s!kfisG<8jdi2T=f3mZ%%%Oj zJ-xCK2-J=$U1J*_ufFUe!{i9RU4pDvD7~9}*r`N> zA4`91cRss#Z&u!~N{H;6%H_LseQjj^=QR=4Z}=&lXKJxJCx00RV%V+E%7YegIA`69 z7*~gjsBGi3J0?Zp#3NML0=I`*=X^qBvqIk|+`lz0MS)C&&;VaCiMa9e@GJo28ZfIF z+YtyV3g!v?M`RhvOafz>$!CAp6IA&4So7LwtD{X8^XUf{0tH&j0a44II;>>5^(V>K zX#3ozYhIt%4NByW2;ey)C4Gm;GsK6N1^Zcv%hHxVYV~CS@jYX=aLm!JwUVEQm7PjM zu(C(Qvi|S-%b46iOty|DQRi`2)@Mq}C~wRnBj3&CL~1_ZuT~Pg#-7g^*x_~s4DwH( zJ|I0>wRtOcfR;gozv}2b7hH9r#d4t>Q+1|*i;ZQ=Mb`aEYC0o;kcGsH1i)Z&LDl^bFiGpcBnSl+@JX#}*TPYte;h^<58;=M|i;$J2*ZF8?<-YB` zh}7;+gnys;4J^0<#q0!H+^_cJXBRgcgoa&5#lU;O7O_++6(1;F(xpK>{a6LdnPH;s zDv#i+fu>(RH?6Kw9+LgE>C$<*Ls zXWDZ)F(JXtRZI1i$P-(Qggb;ML`re0gW7~yoCY>cS?hGPp{yLvXnZQZ`f$R~K5dvM zmpeJScmTzpNZ0%%#YtIGENy5-=tkL3Ni58jVn`BIoOE0XXORX5$F`f_2vPBot@{%L z{kfx%6ecoTWgF@=&O6M`=fSw8KLyjBrVebCik*?RV5XTUAu#DYY!DT6m%Fo<==>>s zeFM%3TU~o=(Zuf7Sc@ITE`l&@qpk)veFE$6^>0@rBA*Fn8dn=mS6%*LMMz*^O&wTw z38{1bSr&RD!9y~a>-Nh{!lCV8pFP*S_MZ7nfreYnR$CJW9#L}d9|#j%$-9umD`u3j z=Fa%4FjJ|c^}NTc=l*&d!O7WwzgjPlAOj%eCGqo`{7*9sX z$RNnlMYPlZbuG{9&>XVX|Bj$(*~o$CRiP&tkcv>~yNE>N4lY z;q=}|aE&hoGcs(_Fi~k6>iT~Tu>A6O($}UNJa67WCGGiiNEl5nP}js~zwhDl2`3JU zhUALMvNU*4o0!Z2GQ9hf(Gbb^i`P$moftG!+G~HqI+lSB1UjglSX556(o1;)hG{dE zY7I5|BCJ)|D6GvNT+)IbcSq0boi5gbr0`)=`Tk(LQITj!N(f_mWYywL6bb<5bc(vcMc_aWh{My9F@8y|FNwL5+`F}m$Rep zRy(+H{2_%ZIS7qy-ZTW0!T`OgdMOevY=^O-X2gF=zkgy8<_q0Gz#VR%QrwK?uiQK` zu^uRbLb}0$f7XzP=i>p94$#w0Qdk%nT$olvBrI)&aO82g?q!}cYspm)ZSR^L$Q)l4 zxpCNZ1qqPv3i?i+tHldU1IYkpKWQ7n=t?=1NQ-{0{EJp*Qb|3%zF>)-1N3<_TPGzQ z>DVS;v2FFzx^dHHxG7r_-x^}>AjShK`XG(mpxiO64k9~rTeFS2V6LnfNVF%;rMc9L#y%C#XZig^s3-V(HDWh5 z5wrTyo>WzXkQ#XCfyB)WEAhFs5E9TOI!6W%Zb~`JBxAhZZG?e6as|&|e+}b~{KR#R z=|BKiS`a)S0=F!P^p@awrgw3ED8Wvzsal)4=$yaWY$9vPJl?KSUkTQIjvS~wG}jew zhqdp3Z(mLg!)y)RfLXJ(0Nu`)Vx)$R92gI3RU zpNWXrK6iJa^Ib#>7zQluoRfhO7@KA35cUw>X`iGyDA?q} zu?};pZla@%t$$FCmu_GZM znR_A!xryfk>J1U7il6+76-}fHmXB0XsD#NFl-|_YKNRHm)^Ep2olmpEgxj!DKIV$< zkmFVSx$FB`Ptz_M1V%I7aI)6bAA!HUMhuXVb^}Cv_;aL!*S`LQTw*jIQpeKQ4e%?{ z8J5ZJ0O`bLwe_u>>QPqGW;E_j_5NgjS#y4FIQUC+)vb=86CmnC$033C(R!ve*(5)* z&gSTdzjO0d9T^)(OoEkM@LeND*Ws*`U4x!5&MFQGd*S%2zE&k7I^Ib?p<;XJy@){F)GB7xG^1*Ev>6g_^#m8pC)46=WmJjp>{p8z42lfnTy)%aIEd*7#q zLCq+L;5^srPPB-<)f$##5&FQZIFtG$zy(4RN6nU)1fBXX1{_Q6DDHGHa7;+7VEaR0 zz7F}k*_I|QHF#OxpDkqy6z5MkNh6$c9`L_=4bE@qRGOEwFd7n>+Tv4F*Gv|xz>;S~ zxZr^J2(fH-TWEofyV@6;AT8&W49=ncRx9W^m{FL9-QS<&QA4o9|56U?YFDv9SE3;nJu0(3fFbN3kN$)#Su0X!Sfu<#4x!@g|0-9 z52Ovu8f5IRj7EVp#+noHt6Rnb&6EU!5d@MED^2ckg>L!5f||}rWRW? zg%J8mPtSwUd8dV^AZeH)FOA2XsH?;W8CWOEuc2}>?222z3=Ists4>V;PeXwXCvPEU zOwX<~Wc}1)S^-nbuv1fgkd(ErCzfy-20$xO|L9vD?q(DJEhu;uE6IN}K|T?Y2B%}d zO&n&h?yt;Nek24$R>Pc+g`s&A<-W)%Ien;OnmSQVhQ35SXB zF?>;z=PRNKHilyvNCz+6Cl3qL%O_|Kim@0=2B{NAk$+7e4El$UJRX@efkS-+2w*JS zPbh67iJ3BPn;@Yf?HcU31#5h4fi&8A+>;B?Y=hsX%8O_h&U!OS*md(uF{i`)!ihc> z@8(F-q(Qg=79gNaaNr);RELnkA#5ryjHV@sb@4BDN<`UbK~<}XW`8TCC?s|aY{T~X z3WQLsL)Xn9RR+aBE46IS6G9#g4AZonDiH?ncK`CBv< z2kDYYdK_!$I8*6|n6g3` z)44KH&c-BJ@`ftm_C!U7HJ61muoi=`=+Y{(^I^pDkVq&c_hprvGP=! zY7>g3)MCS|mgp(CVx-hm`HLLU@Nbrpq#uOS7lVf4nqn+Fc+ppI!vpJ*(>YgbI5-Yp zP{xgMptKy(*&hU<7N0Wg{y?QWAA=*#z1GjHd5G)XPYt=!`{Mnwb>7UmHvj_reOSa0 zOaZpXz`)t5)S^nFCeUENQ8>MC&Y($fI6>pq%ta9z{$VmLZ1NxJ_Hcp~6j`?&2MLI) zAc7VRg;v!pJ*z6^Crs8r29fudp#^VGd-o#OiRZ8?Pe&_fKvhX)X7PluIk*1EHkBe; zoUtRHs4NC@DUWJ_vbNn%jPa(k8|ix_{7e~^fO2FQ_ZT`tha|v*IEqVKYUEHWIM`ulahjDEL0fxg&+wt(yWF*a{OOP z5$it+NK~JC4pLmmSIai1tFgx4&9mJB9v}T93UbwPGptQ~vkB8;n*g6~PPw>Ap8%jD ziDB{@OO8_d>-BK$qMMyKta55Py$VB1(M&Y7u%sXbD-`j2>7+u(Ju9ABH#q#;^lT>D zoSqP6OnDiJ9Gzj(tvl`az|W^(?Mm-cE2-a7-j3UA&8=t4xWsnN2my{J)u+abu>g-Q zXPox@sQfo(dCx=pf&AK@$-4%&i0m=dtpybF!Tyl&8yL3npytuUGe&VIElmIg%+p3Z zl3iHa1;ay{Z2vYEwK|Dt-{l~S5yapaaoy+orj#i`^>M{+9YNF((A2aM?UZsMr!&R= z5f8rzM$3l+aeVb+Kp0kd$5gG)!?ogK{)A*k4m5;S4zV-Wf9Uc~d-BKzWKbh8*i&NY z#QYh|CfKv0`weAzQsj%a>Mf1hRWNa=fz)Nq6OHS-ey6)B<74B=XKwFnhlgTtTC)|I zyUSjCIOUzh+Ic#gD>64ID5MlP(Y8*`p^nRUy);ySa**TwEdGytK9ka}W;&U`iddu?PPKsh|lRdcE#*4ii}tLG{3}&Yq^@0vr_l)ThZH5r>LQg6?psG`f7aRODc3Ok~!DJ=?=xe zN&--gs7|U0#aP42h?uc_Pxcf>udZ)Ux3a3=jHhH|6%LydSZ^+2n( zyXBzk{i>)all8~(Q{03{g{87(bGLGMGz7%778Sz+AY0~H4v;NzsOg(EMX-o^y_i_C zTs(dO0_Jp3k|=I-lM?o|a&8miPAq`$>KC;%ji+%5#i1LW49x~KAhh&n8_*(gMC~0Z z?nh_~4dDg%;&@hj`bZ%L*OY@3+xG1ctlEHVh5zlYa*Mm$#6L`8Gk^D-> z%T6f%`HQ$+@f`MiMV~N(xWt5?<%W3** zgO>vyy!MSOPdc!EdYUVRAUSV=jR)@n>{nWehO4Z0N(SbcS(HDHsoXbg;YKRA^Jn=< z#X7p4X}WdVq$4{aKtSMz&WJPCpjjjn4|r$-Q1SYZ_R%kS3c?380hIm}ScT3phGDIQ zZ@2pczVzOHOi|rDLOQ9bqn*b(D{}O$nG+@dEEF0Q$EVvR3V(p6fUp3j@{yO|iyWjR z1V@!wOw`}81=rn#G1{iZYG(1M$Yo5y+MauID&HQYX{^!98s*@&OiJ2b1-J4Tjx>~4(qn5mV8#j9QCV{P7Nmwz=z_gQI6OE_!-*?QKdL)LP|#2G4`J`5b=EGimt)4||rA;_T|mT!DQtio5Gd zp6io&I(F%r)FI>eT@F96k}v~;7F&to+idB`^Bt>g8f8X0%V(4|P>))bRek#W9YW!a zCDeVTpL&h8VzuBIiyuB;&Wx9ED^kG|x#J2obvILj8nP_>6RDNEk-#|%68Qr+ptV)# zovZH%x?gEZl4Vsizv-r}?vZG#t>(a1=N8wqKX0^ov~kaempA1y3!T&OLB zLiT&((DX}huo4S(?k~Ae=GdOSo83&(3bk)qQkGS%_C=_b?nnUD-Uj)lEc0zDCBib_-(*?yUrB&d$7kn*p6U{{}rT&*7 z)Dhk_KHg3f>-}*HDi>JYAA!BG+Qi!Dz?qm_?xtCMC7sens=p;Z++Nro%UFR9n8-HB zt@vV(reo+mK_>;R17&%>CO5l0`CD-jLE(#FoI&w`vR_dFg*+ynBx}K6jfZ4};7UGM zH={d9Q#v%`Q4s<{p;+F+z|kF1k9{v;xMl_d@rqCmW8(zWK;xvj*N!SEFk=!yt5^FJ zqi2Tmf+{Rz*cb|YQKWm*$pT`0(6X0xnbAc+c60fJjTI*chqp?ntzBYXpV_q|f(nmS zr?!#x3IEmgkeaTiaE09aS9nn|EkvOz8CeqOa2qY1J#Sltiw z__@K8uE++N@Fb0KZ{2l!8r*1;k;SreT{=0VHT_kNL=wW~ey6(+&$eogwxu2tAYE)U zd%%bnb#Or%WeamRiz?O}82EF3L$L_3vjrVgms_*X6C)*$FA<7wSMEz55i?zumjI%^ zM@wTSv@blHK7G3pT|l6-EH*bu4Yf_B7-RU_ z+KfJfRL3O4Xm9+fg6iHL%t09@Vm(=*#!@DWO4Z>xk`iH*x~aV zOH3$DFi?z1fu))bgINpZUK2rer4Hxkz}+jrQ+0=~*00hA1?ybf-B7d!lCgPGJ8l2d z#hRH9y?5W~!|F>o=L1I#xcFnKW@X_W6brP%>ZTHBnho&Hx8XdB^9?vAE)I;HRBySC zHI^_#qV@*I67~sjY753*R`>VF1okmX7!xYi;q&MAkt{Xvw3rSHu;80*y6XYJUfnI%{+>Y9z%Aw`nB<{4a-zM8$&fvi7}^Gr4y9k)mSa&8T|(a zR|qvsO(Por)v^ic=$noS56$SHA9I#*+`zzEuw2yIY{M4dc=;DH%9NK8}{bvj8GX0?rw! z0;1jO{VugodD*r&w9kTOD5h1b7$ts# z{vgS9ehap#607k>!^5n-@9GHKjE5`Msi8;R6E!p6$aW-Pvml$(Tra}0=;jATi80`JM+ugp8OdSL zkc~Il+L$5?{^wqL!EB0xoRAH9=aZW@Q!>sA=B|iaClyihNs?+pA!=43ugf6S>M>!x z^t3PkYVGVDI1q`#(KHb9eSc-~@Gqdo3+7J98KL}5t7v9kq-?2qbZ6BgOcCQgH!}Jp zorMC>IV>MFgd1>WF?8({K}RO0VA8WqVU@GbOTxbj#kHY_6H^HuIke~%FGz{WA#`Xa zc!e7UeY?f-T*b`JD)w@}dc>nzII=V`X`Y@ZsXjIVX!JO3_TX4c#bhnjnpm4QxIUk* z)Hb7$=`aU3{jT0jM+kUTPlE;SI#?zbR92s9?9ja%UTB+MsG|$@j0{q9`*eY7qJU!k zkTZ?ZW@`nZvdW#LU(7#^pz~P5vzqvn^?40*ihuRMcL3tnGgQ0!6Sx&G`@XRd4N8=z z0h%;BhLT`O{4tn*>`n4Y_Y3LnhFAKl5eL=$n@vwr>y`R0hwWzxf9Qri{Bu*G>0?|% zS&7kYcb!p)*v5T)d}LSAj*_9J=`gCZaG4WvFU*+ppG~&YkJ|HK0KY~fdUU5@7bZ~X z{FYbo9eY8`Oz@11F%kVT5v2(-gZZd{JexSZGW{y{X+P?Oo|cKSuY|RYMc7Gfj#L1L z6)MI<%&QoT`+(UTm8V<~NUgE%5R>D{5!bNm@wQ&DmIryNLB52C7&V&xy@)iLdA6m$+ z$-vUq)_UE$wg73$Qg0uojr-6C*SUT}X{x+>()ij*8l4EHoPf+g;6==t&g2@uc=FFT zm8D40$P=O#x1}`0`&&R59JPX(UT%dJV|lu1n42!L0aG1WyM7_P#5mYHu8fIO=5>?l5BGK> ziI^ag6fCzGzez=XNqQeW(@_*OGy;ycTc58GKi-LLf^chPb9>)!Q|fr`?xM2djms^=^3I>t(O>m#GVHNAL*rSx8cDVorH%KUDpf)}AsCDC z!)QzCIeJN$_gqi&4Sk|lf%?p&Q}zQ}+>29>J^f>nKow)?Pf`^91*GbuTy;HTx<#iB zxH*PP`Vp;9@v{_REVp8DSYml!3Fop)Ev-ETQznX`8j@3(-sBuTDcWf#aCNqyIz#W# z|6pz4XvZfNIxXt@oNhfBpS8Q3F-Do720_AH(&y!9vhwhceP$*kamddbVjzkxubC9o zi9Q%31yC)voS(8l)N)LvS_!x-lST^z4~V|bCG@gK*s5|=QrMVG-S($Vw4e6kq^u}; zU<=U*rHuLh88^FGxy{;q$x-NKr>nw2fg3|T0U!sFeWl6Y@9zT$XDG0I1y@zM?QJ(B znDFtbK|?s^@W%H^_He%{Nd220m>b!x@;dFe=Bc+@82tcfwv~zUe-B$kU1q7$=o&mP z`D7q2T7V^bC1;`EJz^!tu`;=p!}y0fxwSD-GtPB`5{(8UPrf?a01x&!=%~cPtMR6h z<1kGg47@DUZ9lB08nhG}&+vZ|*GSEd_XbU+oNeF#KyJ;d}Y19ytKZyUh}zQ%$`BPV5_AG!Jzz&ugMUGj9S9gmC6sF zKdGupE}!1BXKr#bx43meQ52)cVh8tQJg#K3fL01cs~&^94UVO*Kacr7A(V6H^s&kk z*gA_&=yWj%mo9diVQh=skyb$;GM!1R8WEyThcPC4 z@JB17&c<`TwHUoZF0f_1TwA)f_S|=0i>b<%E#ttp_TRb)VJtGc!?w9k)i|cMd>W^h z=+<1N--U#_6e(Yy4SM>DP;K{bDcxEBEX*9Du*tTVHG*zO8iGf=#kTA?QQ^MqbkBO} zwy-6Igf5kXx_cuup=3a98UAj43~~<*#uv=EQmIQN+2C8m|sbt1l5lFkgW#9oEC(S z7HwPzR<1}dcp@H4jAa3~R+cM3xO~cbyrM!od*vD`1{Yp&%c2yvUU~W4#6*7Q&Y9_% z0${76$YKaM93WPJRsk)#0_He6ph!Kg4+_%X@FGea;gm06DOfi{JY86)uo@%VX?Uyn z#v_md4$EWL#&L1XzK-Z0Dh4Q~Y@i5rk}+0hN)Y^I}Nm-LpSM3MJ0<_VXW;S!CH zkzBWIl29zT723Q{BwRkm%{n(}6vbvVLXi*`Dk5Hk%0hKbPbAdI$y}k3US3{bS*dtQ z4O|run(j$2;7_eCaKzg8TDb-rAXlN785_&qa?6%tDO)V2DQv;PB$BawKCY^Y6Ro;k z@*AwDLU_=kqj03Z1Ar&A(M3Y48rKVj3|%a5G+O1=YRs_H1%{6mY*PU%v1Mnpxy3{V zQjAU@&S)4RU2;%hvMeD7#mOLevclY zu>vrzD%!mub3o2k17ldjqgNOhJfS`a%1B6<9m8o0p-NvBgp~C1t>;u zEcgkxyK1#c_epQDAWfc% ztcK4#Z1F**)W2Hj*#F|Zwf>$htdCMf*UR#7MNh^<}R?ngv zjMIPFrWqdTEh{U7q!d1%Y+~F;T2iDzF1FL^el1{;xTJ_AWtlGM+Fjq5uRZiCJVb8I zGVI&JT0G^hwD~WZ*Dn?``Fsjs>)N$-r#qmLwZ#0*${<4PUy(CLF%_%is}P+#cMZ1Z zzWe(29n&*2g`00)fKU-geb?&Kj*q1`BbU$-wHJ&YFnbyRLLq;9nSh@VrCk7CFc~QA zs@IzaikaW}&6Z{@1X_tL4z`#T1Qw0ASXQ1-X`{|%5G*AoJrg0Wuc9-36*J5EIQ zq5#twBaA9R^JbT-1 zTc;-TQ_}_dS3oW)NOa!KT~r{B3R-O-HVp$pg#%d5$dUe>n=4WL0>D~duNm&(dcEFa z#Dq;ar(BbUvAkdT|V>>`{x zRb7|8PZ96YBNZwl!5l(&gCX8!&>1Sq5_wiMZUunwMKU>=2iRJ=R=IR(&Gn83bTff0 zY(Wq~t0XWizXTVIwY4g2XU|+Im9i|u<#k)*(YNpG1s6sRp1KQT zVN?5YC^Yj0kqEuX0J*Bw2EZ1wq=OcI=~AAa&P1M%NbNAlZ?GfJ?HVVtz7TTnrNkQE*Rdad9<=xIdS~#ODE3da><)++A=#=+`fG( zkx-E(<3gKa^r-I-yAQTLwCK#9uJ-SkXm?UYi5b~nf?Tkb%T?fCwOW&j10;85Br3d| zCVy?!q|Bn&99PN(#RpNHSp14{KRK9n9eZDgkl;zZhTLCSEEnj0z7M4~4IA1ZP}LSDmVr?-$> zBUt2CVvU^gF`B7E!i}`$tQh29~YXe!*@a$@1;VE2@LcwJX{TQmM zs47X-!wuJHG}qVb0B1050LU~$t%xm>Ks6BjVj^-logyh!TJvZ)B;g$dRa0$tm5% z{^W&F((mhaohGfMxd!w%lS#$n@%8oE%1Sjv*ovzd_l#Ejtxew+Zk02qufTTf*x9l1 z?5+D3C#Uk$(?xn-bj><=2-d~)?i8(pbP^feW;y*>#|&B45c-J46eh2yi;NI3wt#ZA zbYNk2O(VC$DD@wc9AKOoZmxNS{Ny0i%v(ss*~~j?eFTIOgd8q~it>`8<$cOb1O@w6 z#Cb7Gxp}7s)u{4mG;~c9S{e= zmh_&O5Odf7xk|S! zozt5zb0BO46f^Ryn&pp*oR$f^jzOr%K}eFzOSt2e-ja2v$VEtHS8F>H^9Z@vLLheh z4l6Dmwvda4OF%B9OBpUf4@r+H!QJin;^q!E1S!u*Vn5n%hfipDBgU7b*m}`~T=8 zSu!0iNDVt+@uWSORAI~K({SfCo2|8Sty*hP&aX46vgDH9mT)0=9fMTm!=$8ECovH| zH1780Dja#UX5_FBq@gCOQnU#W!pc^vWtR2!u-=Fi7N8SA&^VMy3qYMF}{g zrRDYKpFauP+}zmQeCftLbK?_Px~d3&1>_nIFyJ5Rn;W6R0^-pCEN8$-^YpbEtz;zM ztAJv3ok%fYi)Md>&WQ%9Fztd=@hd4*g(hGefkIrNkF&B`;yWx(boUNKLSGyo%Vx^; zq!!kEL@W?4zJT01m}b*doJ!0>V~w@3=x)Y@61uLE%AQ;ggsMGlUjUDb7ZW1U`x^>2qlWTt&De1 zz&jH2d^ZiKi8!_k1|9i$Z6KJ1#MT=;a;>e^*Vf)Xb@J_EF#|#39q-<;{e~$D=>)knJ+R~) z_l#^p?bndQ(*`1xwDU~@Sk9OcI2R2V0l5g_()C8Yg%t(_qJJr8(2S7a1!#MUatc+} zctToF6#6H+#)*sy@gbfSf7%4fJHzFyQbexhKGp${lug4pX@!$AVQkbnb8|+)PSPjm z`>hLeqpF)tY9vcZ}`sH9X-G zEsq(I(GljcOo;oCdnKcb_|werdnD%DWw}aIRKEtJlfQl$^S^g4DY668 zHR8_BYyq(q=;>SoGFE+Pza!?OM=Z&KX?-!&(0PX7ACfBpPZjB87{jz)k8?rX~WHILPU*VN{&H;)CLzn4^^~C zQ(Y`zga?gAlg(4cR_q|lbgJ@fK}I=?mvxNfSTB_~Glwi*z~x+0w3ZGW87?>EVxc98 zZ>U(!+?T}`ZJ!KwbFda>h(|8uzOrd2@-?HvF`r9LOe89m%<^&tz7M=xjoF3XgU>a4 z^_1mYWc3RdmSOw;_utsQeR6ubxc8>{LLm*HOa-X)yat9=eS(Q$;81Ou)Fw~5_YyDy z=K|P*->k3KtJMY#7!{K-VVZ$=T}IXK&(&bwg>X4a6cLh_6lL|P zfhA^4!xabEi;R5zBetzmSyEm|K?$5oXuY8jjVM-C-LQWk4hqF$8eog6%h6Hl?Jk8N(#pAiF4#ua)>-CrI|vN>(V8x$~k2dT#jGLaJ3~|Ccc?s zQA!^Sw;T(__@K|UPQ`q^4!fnW&eJR7FnG$DOem?Ok(x5>l}*^nCdbCISFe^=SF8T8 zwXtl=6}kA_JbZz@`NrF@z4*eZiOKv;H*cAm%uml0D5z0l-ZOmY8wF2jqfPrdJx)CW zEPgO;M6;t?9=5iY(t zkdtuH9g_7yE`dd?y$mg>E@~Rg{p*~}!U~D`!bF~bF)$Bw((M8m(1)v2(a8PimK%EDMZBdBw$=!CEfi9gduEZy8v|*mwH2IJm}>H!DcVt z7sIYV6djYfk5QJAx)LtRm1wmy33ISrC#)MiChQPZ=RuLJ6tFqW!-!0{umWMVl1M1J z>1m_0V_-L2DwUX>i^IeQ-g@oYIx%a+eF+k~&by;v)-I+mu8yu=T>}Vy{k4mQLi*14 z?%KI?8W?&q8K)H&eFcQBcfR57eIY_>1X%w01!T0G$(2evRp=})tygOe059FhV*t58 zZe`MT=Ez!PWLbHMJqc!nqEj1F!KF2ZZmF~sIWcdj9}NJ}5ZC7eF=ofF z*D1(~Qgs=&5E2L%o5^Yn*pmW3NoveW#UswJj8|jO2@GrtU~6m)g2eTe6%uQ=P04Ry zZmZ4xfX$`ht5?ggq3@x^#fjOu((c`}V`CXY%o{Dk%}ooUG94}IG$*gKQ=Y*fMfk6^N~BzCmK! z^cGh7I6vD`B+MAB(ew3B3IKlWS}|t0;=5X+gZ3hYg{I2dW~56>_R; zaw-oOcHJ;UrvYQN($K6WInz1x6h3!gkNcpZtUuGF--Mld1T0Do%A^ZRuJcVM{JZ42E3P zyBUxRKzVX9f6FZk@CICkfLP` zT?R#1jiW?DQDX|3V^$ra6O!zzMZ_;|S}aVr@sS=s&3`2l>dZ`W9D>9ZU|a1Pj)_5H zFPesKCRN~s8sGEj%9S!~FTM0up^)0UcOGC1@GBNm;&HODID|cK1_o7378B&j5n%Ow zP=8bi7?EKQ0FlC4xdzP3G>xFMT(LS23hQ~g(+vV4#B(&+=vmiWO%8diQfJEz%Tcq< ztz$Z13)vzsBV0`;F#wj=(-?AL5qfn8Y}v&@m~*K&q#<#m>Y!B2td^@w*VfAAn*V*g zVM6&%-V}4R3|JMw)-%uiD4C2;OyqX&nVp*}&CZr+RS=cVTqk6Te|dm5Xc1s-#Gs0# zsVTIwQfaj`qx!l^7m^6)k~+@wO(-0Miz?=M9~)A3(<1UK8h7%|9BDoa^NI#XS0URA zj0$&Xpq4k>Ff}(fcEgUTd_D!Y2PIsgAeRpiY?PKF;LD|F zS$draur_GGY@`n+C$-hpN@cyivP!&JSn0K0tIQEAO^UO4`z=F_1$$r$RD+)pqdr{| zx_hxDKfZ^n9V&{1i$*knrAeZ?QmA5{NfvZnOt~W=(=YfLvRD^8GF(zSSX2K%7GaBp zbS|45U$0%ewnlCHgWTvF?)?%Rx!}VAczX5K^RPYlTw=$LX<%DBc21{Kaq5QT<$KW! zC=5ANd7@Rsu!do%sxmf~g>Af=gMe{)xdQyCY{?10w>~%u`}+x8u9@lS zLO!3iI{mbq>HZ)P&Y~g-jT7M&L}x6=FPfBcMU*^;vcpEC^YuMgXBjla zNm%WgAzha^n&f)LQGVzHB3)> zQyhRuFE7hZ!1h8#Qr1a^E!XrGoh|V=Ss8?Qw8ffV=yp1cGt6QvhBXeeRrt)=#ts#& zavcU|^l0r=nDKv_Szg3pCW3@x>U3`blT*Ro6i0wHVuM+=)M^bH5G`F>gD>HA zlI_y$R2L?_2#xhYQ{Y470;uo14g3<`EMm1VwjbmZD0_{3~zT9e60L2WiQCpHq?;S(M9Ht2ne9;UQg~4-wiheS9@M-)J+hY( zO*q2>;bK7|ytYtC=klq_dM==SP3Y;ZfNZPBcf(v{3XGEa+r(c~i^cTbz4Ji3wrm-L zZzdSM3+Q_!Q>f=!Lg&jPz}gG}BgU!e=~yu`ATzcta^X-RO%Jb8Bad9CPhW-&plavNX<~7+Ylf0>YK1B~7k7s&VW!DC z)j&jmHS)u7_)AO7&l&^#*nOD(@bnd%7d5{Aj@;Hj?-K-F(FR04Fc^WvGuFA$jgmz@s!9a9XF5LSWML5 zfQp3-Y?Vq5*cM=SrBV+*Re0nI;^)^jY=zjRk(Z&au2x@u=^Sjpwx*^Edv2TqsG6B6 zW->`*DMt5SS`9HRg}N;yi~wtM0ai-~hQ-e#*EJ%ljmYJQT^FF$`g*;*TB%eU^vjkS zbs1ez6;)N}*RRui-cBE3zOu*WS}aK9Z2Y*@Lq^kV`MaQrmtadUS#=;6=iRIe6^mAo z%JOQOk@}*M(Zoc~5S^~U&rssT;Y@F_{V;^RbZG^)mtTGhPHF45Nr;zs@0o-9A)8Io zqD8N+KO0i*?6s2!uts~3Dl^ioT4(*%siC|7pk+X%5=qh*m9i(-h>sc*!g!DW^E<2X=fGxy(Njs3s&SB}6SQhgUtF7fXGHhnRX!Om^ z!MU%kRY`hlrBV+jyd3a)V(4#WMvKPHaq{Hbu$?$@c6z1=p(4bLa6#bv3~nSUL+!|; z$`xNadbt-+$~%eN8b&`J)FB=eAWRQhS7xNE;!{&`V?S`4YE@ud&Bj`}#!^bumY$`m z?4D!xmpEpyg~aBgR)!vlJy{WtCc14!Y9bPAsDT98myKL}B*@-~pWZrOF>V5=9i|#= zi}YtJmWYE5gogmx*RHNrs*Pat%CpmbpV$@(6}%Mg$bn^_eDiJCip9+Mc0$B-bv(#wK)cmqgIR0Ug?_F&G%v=sphh3GMNM9T3Ipls7q@= zyQnn+RxqFHV)K=Wp)lrF^pG7q+R$Ty8Rsx=ur-9Gon?!F2#dpy1lbZ2PUHSL{foQ#?%;m&B8B@fUyO0 zczvw~)0iZ>S_G{~8lP)2rb}$gLNTGUtOZ-lSKf*qkudEYettp?qq&I4SvlxJmkpa$ zi8PSML9QB{BU}(8C*$c8T)yHemv`$&uj2vwZ}q8Hqar!b|L8(4pW3}=7JffB zSDKnGP`L~<_F-q;W6G zkJV~}bhUwav89zQgM^rhg$5O(buyN|D6PJ#W(23({>Tz+@%eIv;h435UCeOtj?Y-A zh2-*X5)QJQ7Pbi&&C084tW?V8^Ql^`Nns0urnYIU0kf_C5iUlZ;bVr=f9|`lBcl`y z0>-_2=O-s~GqXi{1>l>kcPlPAc+~y473(b&0oJGvLw*HZUFYM$F3<{40q9jM=8__1 zaU3fHqP=4c(}*hRdadb(-HjO%vWgidp2AK$2dmBpBhHgSyt%CuzRBLOB|x>S2)UwY z8@ZScLwC4_>2i__vl47wXBjRETd<#WCTTcX=OH?#CN?xCYG-1zNsx=rb5$yJ*e+aH z%48CA^J7~VC*WtXn2yI|)F77^qjnbb`G$T{_cMlR5nzorW-%SP(2c&65m&KMg%hYf z9_<|q8{DT?udcP4tqL){sTz3>-4J1!Wz`fDTyy6_FKe+0kZ=l2z=Z_Z;%A0{T+9Lx ziB*rhb%d1`!!{gZcJ*w+Wu&*_adl!cKQ@+GCuXOWPj39pANUHkl;KXXbQDrK2_pzrF;yk=ex@sbCE}w>NYN}CQt1VqyTPxQZf!yT>3R`_zRg|Jd zYUOnwv0SZI>!iO9U178=QccHXgk92GoT-D(tvU*D z!?*UqE^Cfl9*tp`^(D^-h1lX&n*HT3D#Uc&_*u6I*Z7!PEM_X}H8@A$T)`Ccx)kb; zZm1|li-6i!ua=+tZW$QXmM!CRbEUy=8=2pHk*L^gzx*yEa~RL<_xd|JvO zWW`eGfi1R$m_8nhoC})-)0!wk0S<5UWvA&$Zl3&;G{wlKCMWZN%QT}Gq@B-ZN^(iy z1s^Z1xPJcmlZt|O7)96HwoO9Vn9d}OINDa~NpWANnXd@2Mm2lYXb7GmT8DxLY*gXI zV%R_S^N9+5R`db6CJh5$81-87>b3IPT5V;yf(-SOZs;~8e`hSliIkNI&0_f|61lbE zP!y~5T4-iLkxMA+(ZoI%(pzAxOO82Ql8Y4I881&HNQSF4maQ7Sj#gIIr6t9oN^VGOR7qL9u2tms+~rih6Aur|qnSx*J-T#LZY7*<@x z>2wVBK(7MMw?tB%oh`wG@@f?TXk~eQwOp;N*PB|4iXseEDspy; z6f3zaHN`-dQM@%@b&fqDt`8coGDQeU4T9t)#TMCfHcOf_Sob1O%HHL46t`e&!vE5ocE>!|w` zCV$POQ?iuHr;yP>7H(53V5}`KRY>D&jW`_>xDk6_>wJ|W=Tk4L;VqvmWM+k#!pc&I zF_y&Us$pdg2%^m^uBJ?iA1wnY1EA}Y`Aw@h7T8Q#b`+xEZ0D$QMLR|`OFs!PjuvBN`pDl zgfX+lK`eRCw6Ai}5Wl48kYDgiigd>1aw*sVyvpSo?Q&GBH3EL78wgvdKQ{u8T<{e| zOBW$vgp;KKU zD^#T2ueqXYE?35xsq%yiW*`JU@7Zk93>bBx!&3xUBMDec&_GA<4!|+hP>L!Y&?}!Xp-m6ub_P;j ze^pflLMnIwKO2qKl`CbM@LFA|k`7iaje!^9;D!B4*O4xoI1A6UBn}GZP)WA;l0{xv zXiv?#He=f~P|AE^yGqf3V=9K2$^&2lYyo&xs~xN=Zg{8|I&w+03oaDZMgZ-CYX+g> z%xn?D#)KI##%bww1X!atFcxl|;0_HirBg}b%HV=lU1cx)CsNxf))vu#3Ie>&&yN`} zt-%bxe7Ouifr6D+E0*#TQM**#&OUK)!UcsOD`f$HX_5;j z>d*>M{X@t;1&lDRUM<7Vx8GhlapLTjE#ud&#v{NQz0qiBEaMKhZouv*M9L61l%l%F zjgE)$WL*z69#{huLPA?+wpI&liMR0!i>PldT}W(p zeeT@V%6cpUtdUG$31leP%^i=^-l({{JF>gm(Vt}LdLW+VgJr53gAKlW0lBDp;Nr#Q z%6ffewPNZasHz_GHqCZhFrkEyHQ2CHS6GU`xsq%?y0n{`amC&yA>(0-1(3RJb#LV# zNkT1`P3Cf`$$E3WQio7+ZLJzmIzJ4A3-z-M2y@YT1Xv?B>UE7b?bCzKZK4zq*y{D>+FG5KE7og`AzWA-aI{EA1X!cT zu(Yl`MM<|o-S+l(xuJ14B&)}T!X5$9gGSkWUC8~LSB7I) zJm+FxDwV1&m&yMVL6o-bS=_ys6Xtu|=kG{r8V{SP<86vU|| zIB^3D741f|$ffwvCR}2kOX6I%c`QRN<5_AoM5cB^3>|JY+6xVg`p2yDYlZ8ci z#V!aTumKB63*HA3{$atQNUFpp99 zefx30{?57Qo-;WWot$7(e}KXjG`3hgc)5U8NkUO&tf2|>y<&h>Z2sPY;>-x8%|B}L zM1g=G3ku6q8YPNp^@ox1Xq3%mi^yJ49t!uY9;i~LRA;7)q*0AeB`aiy_vMXTN|Hn_ zT23kon84fAbONiAGnd!vnblBTU&mr{(bOL(j8>yWlp*snL+V|?sxXlU#gm$-z6Rp; ziawv19YVVR+fZR+g++D;^NlP383|+>8mh50H_wX4lhaeN>my;D^u`~?DU)bCk@Rqm z^-78`m6pfZwKD0l)!wS97N!!@nuwN@1zY@i6y&O@VPlJEInWl!3ssj)b&gsIXVCuT z0#+pn=oPOLnjuX-ujsXDp0mLO9fOy?q#52#pDVi<>5Rdkzj1aA{!ReDWXUIY8u6BuLgE5Q55*Z8KRI$GQv+4lG5PCcy!QTU0pSI zF7xMNfnLKbt;I`@`a8tpRQ zioDQPTN}Xdtj3z==Ejihh7N`6+O?3tl5WI7zGzC2B)d>4#;l}v4x`9LSWKPKLj;QR z(o(d=Y;@xja43XJ$Vxau;6>-Ctqp>9LEA-xp(iqb)bKPK9Irry(Nzg6UPQqHTT1DJ zxif&;GC?QrKw)0@QM(2Ti(yy>CE4u1#u`yhgDlANMWA^l63LN~aZn%1iOtl;RF*St zFp=||;L}x+!l>^SFKENqXD8s`Z%g*4h(-@t9^5KlFyP1ETVe@-*LZlE$d^G%t|C7e zE?~K$RSEh0xOwRnMQzUvV3~aDtYcO&Mt3ta3QNzhbelmL+bQBRBphN<>aSf71HXV; zW1~~NUlk*^qACELDr&Q+9yAm=gQQ*By%aTT!s7XeOAz$4&vH)l zq87FU)f{Xo?QaSst*r~x)dlc|fM-RfV-pjR>FF40yOtEjQX-cNSQR7jcq(q68I4W0 zUKQ$lRp_L`TrX}Z2MWu9hylE?EMCka;mn^u8{mcI@}*JS1QxfC1{~ACnoI3$VpXT(NkHX#<8)fE%vCqxFhwDYvnWzw^hs%uzm;>N}rXox^A23yg%9Az+( zVCjvd0`N=7F+@#eP9lH7xk{7ZZxQK8`>a=Fu4z->rXoem6Fl!Pe ziNa`LJNikUZi6{%FZfK@4I#Zo<+0T=8idR1)iwbi+y zlvAK9Q9!83RdwmoW`Rx5jzf9GwOkrz_~r46QTC-auWSnG_^3RzF-(!iZ~|36p-QN(shT4PeVv|)0k#Og7@V01QC}D%a{;Tu6hKKE zQe0mjWTCID5D=>*tFTZrMHJ6euc)S@NhxCu3imMu?VP6 zJm~@bNxLPgMuJQ<<Qd>l z1)+686Fq(Kujxn(5O!m9f}HGu7sQ^tJ`ZhC%v%}o5kzeq8$AauE!)b1E#(a(*BNYM z?_QO!D&Qw4iWoG-gaouAH-rvE&!IgL2{qDQ(=GyzC+CqcA-${nP>l2Y5(8-{XbxfRff!erE;0D@Y4AGMVZ?> zI#&%3537wFI?7^+X^7+i`dY10Dw{7rO$|%Vir*zmKXvDwt#{qMu&r&;J#Dw$xv~|Y zHhXprG&N|8QF;DgQl2@KOk`ZWQZuVXRm^&iM^v)=WOj(@TtsQFvGj&?MN~%2AQ-?a znMlfcntpClqaOd2R+8j#e!C7#pN9^w{PFe{rxY^aC{}lm|F4I!v4RfCNEXGqNoG7Juq#EE_%Blq!X?V{7DctI1V1xhz>I7!J`pS>dKb?3&U0q#( zDqxn4faRQ=J9iEs1+)T`Gd|zi`n~V|W09|Wu8%zhld+8oSh2eg4V?*vLlva-6)=~u zNX#n19Z(cKGJ!!BE^MO44_~|i`~pagjZTKc%p4Yvrw5)TLHW*Q&+^HoCn~t6a+Sz( zr;yZ9B@$^AqtOEo8+@#$fo~bMDCukx$Q5A@YOICw%z;$22}f*LPdxF&@6Mek%%WcE z1T0$Bs%A>4okiXU`WC6Ow&;o1Tb%nev^)z3 zSnz-UI|9uOzyXpqIywmzGUK+I4mapgo2w-C)N4V|x5_JoOAvJ8rb_A$uavfeG3NU7m;b}FJ6v)Pj)#eaX8^f+{zh(rLhjHw57rNYcoIF=v)N1+n@eej`&$vi}Rzw~Ec zrkb%r#wpMooJC`(LU|}?8XK1G;ZWjmIDafot+_zdMh(zlE1H_UT@f@uF>ldL$i65% zw(xj(=gz(d9_YgI=%d}o29GE;jE{%=`}-bxc+D5?@95s}g(F7~rPQ=b!)xwc{r)fB z+xqxdyVk76(%1LA^78Sg?Y>qztxqtlHhb6C?{OU)=b|h4t7x!6!^lCoE_9CdQwvzlTwlv*$_sPhk^lrZEe8ol|0Vf7tkwUM6QlXpn#tI+uwYM1pxQX zyFWJuI7J2r2hqv@{E5fuFP#N7{OqUy^1y~}{6%kv=0!DQ3;tpww&0N04jkmU52||f zku7}Xxenj3VFOx=@=8fG7$~L?J(R&-rB%F954Qr>OVER2{9Xb?v>fL`v9VBC_o6_g zpL=fGl`F#o1IOQa=k$xcyH1^YY@qoWfmCr|wA z3=$AWCqEZYFw08PaKX@|xw&y6Gl$Q?($=9LUna@z52=u5DGv5ph34nba-VQ2P$=ggzV_LW;<*|3xQdv2iJ&V-}&~ph)DtOPQCS} zauXoB7xnLNzJ2*JL#z7w2K1b^w)V##|Epuijy(8B8~^jaegPmm@Y?H*vuF8yVtae% zQ%`L_`jY{G6dk*3=N>=_R+cSWzH#GbVAj{ZwiSO-RY!YjI~Jw2{kvbH@<5_Z8@Igo z-p_k_wuZx@fdK&4OY7EkQ!#8@zHIr^+n(CAX>&t;gUKH2v`T3H6s{vhE&;J3lh!S_ zG+*E}(ihbzt_dt5WI2LK4jJ7w z9hEQ(D?ALLm!iXKOy&SMl=i|_*QK`R>S zm+NrCI~2g_fLy>YREXLDShymr;9`yKZr}O#3LFK>2B;!SpN8M%x+vfm^u8@yy0c3H zt+4A)zqBFOdFQvZDxI@se#_ajXRz{_&n#cJZvA6hzY5HH`swZbThY>z!QA?WhOlf( zhq{Mf1+7ThJ30Ys*tLFLckz}ZV+1jd9A5%1R-ra58*kU_*|o}F#i);`cJ=CLES4m% z`{9c>#wQ|PPs+n^6CTjc0anmY^N z+VtC@@@y@Q*z^opbc3FFgt+OGg z8J0_(N)Kd82v$K3$C^kal_xbkd}DGV;_;^bUcNj!IT=;pj730=#`#G_f;@WYmAx($ zqdPC25?m5U4Ilt8q4ZBe3Xl}O81@1MKD%Ohk*7lqfCB>ng+PzP*>%~C@!=p@Xe16t zC8Yh~>QEKvRkrmimq5p)5rZ{doq#_xhjeyye)Q1+)dVX0g^7u9_Aa2+NB?sHB&&d4 z3QZ8OHE`(Y{{4H6OOlfK{`;y&c4p|z@bED0GD$|t$Bt9Ej-%x)z?!NmpWpALWznL! zD?Zz@Y}tHTy1JIEUHj>K?_L2HudC$d>S@-JDh zupXDgLwHJa8DJBnPw_@5ev}Pb7!VC8mP;SBgpXu6Cw#=OX7CQkLYkef>!$JHq}$?f z1?(Q!&`m>o*EHvhJU01TDy1HuCtQtxLi3K|5J#Dvjbl%b4zPP>P4q7@p zm*8(FR=DN1+vYYj1pR)gbaM%z7+#b`VLDK$XhdJpwsPrlR#n1RU->a=R=f~+>%L+h z0?-t8I1c1T28godGDXqpNRcGG2IS#Z5V|Sn0%j@a(yb(skox*|z4qGvZQD|c+vnHb zzkPek=b*QD*TCT)J^A$>`g{NV>z{wFFW+6Nhi(XEP&Qh%?B2a6?~U#0*$UV?apLuT z`(7pt1zK&|v{|8G1BVZ`cdSBfhY$axuuwDkqQAQ#w?6q22>2*c7%#WZpB;}U-g-MK zKKbO6|Mb1@y0@v!B@~K<$K%vnlS$^TlJ)KK27}(bL4|at-{@=+Et#xDeba_$Z1^b5 z!ey`T=*{3b`bm;+KJ%={y$cl~X5MwXj4bwKUCmvIaR!~@A)`EPO)gs5A}(N6k{HCm zQYMkvRi|E2OPg)JMq#GS-bJ3>HQBp>brT7NxH8bBC}C<=)(NQu-9{|4uIq9c7qDEJ zalpz%m9)LbXV+(mO-MONR$-K+c(^ftT1yQq(uU>2s0&y(({u7@Qx9l5L+&BD{3J{F z(3#S|N_pB+f{3dUx`1^Pi82>d_uaRg_C_kSFWKa5S#a;Q7e*~rR^+K&hUEg*&4yXI zcX8d%Faemgu3J1hI6e;GGAtLcTq$R?(oa0$6+NC3u@Xz%%l1=Ov}c1WE?~I~tK?nO zd9Bdc+5Hpw_*`)T>yw6720jf2d(8u!Lr_qFR#>i{pDyIMfaQuEy(Mo~Dwvo^l2o+A zq*QvwVLpam@fT9jDC`23D^B%5P5v(3{-E>I| z8?V9=^tl22T)=Y08pHB>Y>zu!ioROF;iXZaN;Wme)dyX`y6HqtvLx!cxtmG~oeMik zHe6__8(Y1KGFSIpa^?coO{fwwl4V_ia;_Iz*sKdN1-H#EGnPwyT)=Y0L5Ah^7Lwe- zmY6g8q(*mC(Ru1&hGCftdFZ}YE?~Lhm;%KBORpmqKAE}58btHN%T6`QWJXnc8J25w zF9%^sD8Bj3v+j+k2uUP7(-EJP)b=y4H|h0C#?VoK`Xh>FI(@Mu%hXvMRQDtY>U6~^ c`F{Zh02Zk_W8a}ZW&i*H07*qoM6N<$f(4Iw9smFU diff --git a/Templates/BaseGame/game/data/UI/images/previous-button_d.png b/Templates/BaseGame/game/data/UI/images/previous-button_d.png deleted file mode 100644 index 688b3034593019b560c95d56ca9ad50633a1d800..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 290 zcmV+-0p0$IP)aLQWp}M-VW=GgSOtJO1OWsQ!>dPPUAR&lL*PV&z_HIo(bxiQo zG};(LQc4m+6k(jEjJ36vwAQ4Q+D*=|s;Zp)s}5;NiF@#a(PGS)F=NIkUe^`Jecxkv zS(e-o9)BL_eXU0B$9lCDhj0MLO$6qS*o3}t8TfCx>}q<#)g6KIH2DOD=f(ZiAb^zpyn zi5)f=3~mA3^Qa@I>5M1#`~A9Y+gB5((3 zy3Q2IOpqltj~r`OQ*qL)SfWmr$+)hfTDpz0?$jW9A znJJRv70iF?ezt;2GRTc;khLUPhNfxoeP8r3h{ls-8II%Nd9@OKJpLV-Xa}A&o6T`J zI4SalX4iGGUazs;zQX_TfVHg+=hoVTjm&s{2v?w?ly z*zfl+&4gw~WTf37V)v$tcDs#Qt(E{W`NC?cXTyDWF&d48=QKzEmifXSk4MnKPknMc zb1NV@$+2JAWC|R|1$QJB8FEKb+GN=OF;Pu&sb7pz%GFO|)dJg)641pwaK zh{1KW@K4h;sFYfamcsxM<0y(26Sjjr)t45dZ)H07*qoM6N<$f@y!$IRF3v diff --git a/Templates/BaseGame/game/data/UI/images/selector-button-blank.png b/Templates/BaseGame/game/data/UI/images/selector-button-blank.png deleted file mode 100644 index e965b3af6f2b9a269f2d363f6118060aaaacfe23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 744 zcmVP)OT4`WyUtC~=@hx+zySvwaKHgKA>83`kd%_BYOLNgO(Uv$2b*)@|Eg9YW@7fI zT~!q^i<8!-Y2N9)S2Rgnw#U*CJ*lmP+UI&jej#f@hhX^j%SM~?LF zi?zW-dhDh9K8FR%|AW1+Pd7{fT$3IAR&V6+TZaPUw@w9!-|CGXdJee7;UfF3q}2_F z-|E$KyQ*vs6_t}znHa6W?Ga9$rG&H;mg0WQq!gDq*w&w<$RMR-QTF zp5X9X$D|d%wE|28zjYYM_QYn*#rUnC;P6`qMiswx)bfSjir571FWj#7x87#*oU@1w z+uvGBam@&64A{^k=j;-))qZO&*qHn9Tm5kCB=ITlrQvKh0|K};_P1&c*wXu3jc4w^ zg=2r~8qq_QY(Sd1r diff --git a/Templates/BaseGame/game/data/UI/images/selector-button-dark.png b/Templates/BaseGame/game/data/UI/images/selector-button-dark.png deleted file mode 100644 index 84ee7e6f30f4eef5b3d2a1440495b16cf3b21f65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1942 zcmV;H2Wj|;P)8q_5Xb+!B=4lN z?AVBUt4(v4I!KilFko1|=NMX_fAf_Dp%{Bd??cV_-NM*!htZK;>r#7p~|{Ne^@a0X{^24`@3%UfLYq9}?% zS(YUc0Ym`s8-N8a_S1ei{}Rq+I3HfC<+3chy;v+JM05_f+~+~;ekD7XTeDn%ssL2Z zxhhz$1mFNv3>Kk}wg#7F*-pRT_mjzF#;)&&Vf6rJ0E*DR3t%4pZfy&?n;dMqHVz?z z%0~|PmCZY1{V&C}hu7_`jiWAJdb@Kj9jyal-Z`be6=WMY&xbFxN&)I@xi&jQr99BB zuqbT{&MDVki^uy8^Q+pB_g}k1IPuy2SC&gzlOL4`0Ja8~t?{?>ZNrsozDUt_nDdS= zR^2qqX$!CKF!Y~xRPs`B-_B8qzrjY>*dlxjz?6MoBzBdp!SRUW6gP41TG`d$49?&T z&fpC0BMmlxe?v~jK;P`U3Pkl0aC*OU?#jkUhD=1{5-;MEzN{hpqRY3XT5%@@oUed# z0!n_4-;0Kqzf@GzKF4QD$UFhYAMDvV_Iq{)fSwY7#{P;`0c1s>V%HE6IS!aNfN>BG zlZn1qcF>B3JqA;SguD_tZ*ABkV6Mz73FR3SKRlajg9O|z11iN4pHm@Ge9RM8O9AEK zC|F-ia5T69gPDiKCrScRK&hnl@`N{f1t>!G!nt5@x7myF34e=$K)z)ixv zG&m9-U0X`z62XVG$6$8DQ0+2E0Js-hcP;NbqNSFe6j;G)-N?4`~vr_43aDw2g5(mf8gP7BxV1%QQe@aIpwa=`V+t#0Dl8`7mg1APQoz>OV0wp!YiA;w$^dy=+gSi zaAxAU4kAWNMI>@rDLTT%`J0RA#w!7=^NGA7wfXlt!u8m_GU27JDK&J7NLPkTU0SZh zgf3yZTHfj!U^8?VKQwE(R5s`vGAh@Qb!{RYb*r*Euf_2z&Ksz4ue?8L!%9j3NMeKT z(n=P6$ds{W0N(&ZN@B9;2)7XT)6zz2D&%O^ijl*tBixMLOS58aDWQbrBwUOpy0ke1 z#Yn=nA>wdy)2(=_e` zlW^1HgM)+nZK%R^#|(};M=73vY0haWp-iR+YToMHGY~zg<*m*=1<|(wBu2W&;e09} zXUY;oxpR(}LP^XypC}nQCXw;K4G%vH$BCHua?UO18?Q2Puvnhr)gW0yh;y;W zAhcS^J2q#h3~Z`dYL!FqQfQedxKwP%=rIVb%Jg1TnfMTDo|-IJ^EY-%1R~*zV37!+ z)#u&|=bDKk;zDr-O2Ij;6qQ&5XUqvcBr2OHiOOb~h)(KdSK$;;YP6LC$7{kT3AodS znsB99jCjdEZwNN4M8K(4(@zs{XNhV$C87~shfu5sVM)&(Aa#goLWh`LL5F~5wVLIW zHBbJheoDcaH3XL{6`YjJl&6F<0l7;1nm2^yP07=G+E>E`s;DN)tSkH1Q4LLRZEHEx zTVZ;u>8+->E}>0tHN6!dt=@`@->mZXG_gZG6W<>ua+1yHtsMgm(_6d1eWH3RfFDHk z7=QGQEA;;e(_7m$(_7m%(_1%@j+)-OPBXo=Z8N>KZTp1vRscVDh)TYL>8;)1uB5l- zB1@NgYaUF^BZ)3;Exk2Ywh*~|$SnP#$XlNQc%tO3PXVO#*4q4HUc2Nmy%nann%-)9 zD*)45FV9I$!7;tH=>pSRQyKosW_oKAoawEmx0>Es_eRrO6)+wRncix8YXrOFoO?bT z4qpIQ`+e(pJU%3%#|=4&s<(P&t~Khd9PFxXI2^uk&OHw=w;S%)7hcbwe-5;+-nuRr z2gHS>xxkO zK~#9!?V7!A+(r<9XZH4_lO1;{)3^%U9NUyeo*@X}D)2KHd5XZ#5Tr7YPuaArv!Y5A6&q^H5 z;T+E49PX6iZoBES&5wxfy&r{Q9uXK#sm*_XnF!+u)-Ue6!_Maqrp+NDiU=#?@1?{qg3|xuRBTP*Z=lQ{1u44S0txiA0xR@^H$}BuqR#y;raA2 z=dJu2|9R091eak$bLuS`6M;~K-(=jy5S@iz&Ml~3d`Z}vd3)N z1kf@Gl7Q?0M#H8o7`{2+nNTya>l}=4Qck0;TA9=|FuoUT2L`t?;LaIL!!|OhwOzCS zPkOQ7krF7Rmx<};$lxvvn_Hz1uM{ow0F- z4uh0h(7+^|CRz=0s^o$aI#5ghLr-Og}jDDh|QDsAhHN90$LYP;G>kPTksyx|2IWnCWcY zCb*q&j#euXdAB?m^(wc)ZrzIb5{TY(>Q=-TK=gBhxDocnCCH`7Js2V)%2p_soRvLf zmFLX(gHiEcv5J3ZsI}2lD!WX?RLj5CN(+IPb{RtJm0U5K-4C$01IXBOd^N`D(Hd|v zpkFiTXew+<$5&Jy*bc~28rIgz5L$okTItW#!r{y_HWol+zc#Sz3s$LT2u*TZ;}~p9 zA>;s#IRzD(d89Z?U=SMIO;1l)J@`uvYb`70UZ{1`cZLRbMmJr?w6e{KkV1;|f(X_; zyzC8|t9#}U-AqKAL-YVjN0D)_E+m(lWYjvPIKkn6pg@u$9b`$QRWtNXzz5I1N;fD@ z(-(f)p&)ub=kwO%B(2lHHk-|BB6?n^Z=38-)z3A*6a5jhfuCxUS9qQK5sp4`Mhzs=l6(mHYt@W!@T$;fOYG-2uSOX0v&H3{|>s)Vwt)Edg!b znx}qSB6>a+kX2tkZ}oYr&s)Lgtv+v6Y|iJcJ#~uDTMcO!LA3QRjk*e}kFbyE00000 LNkvXXu0mjfl=J=< diff --git a/Templates/BaseGame/game/data/UI/images/selector-button.png b/Templates/BaseGame/game/data/UI/images/selector-button.png deleted file mode 100644 index cd0780068892795e6329d713f48e84fa9f1df8d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4002 zcmV;T4_)wyP)L`g(JRCwC#TwSbPMHOB%XP?{K+frI- z3jKpZBw}L3h4Y&qe11`09;j={b7dF@4^3ZpXFPUJH4i5A-lSN6%Bgp}nz{>}*Qo5DrnM_Us{T zg8A8VrWo>>h&Wcz<4!Qj&du zr2t9>1Oia40CWg21eOGt_0biPC^8Uh*2j*L$ds!!^kyDKO!P8>x*ua)d>LaXW2MDF zw}O7P4087Bn5)w>-bPouX2B`-c?OCu`LJ34IM%G89A_1%wn2fOma|Emi%|>J~h?r=z2q@?SEPLjW zhrV{^gZJ)LN^PTU>KFIjb2zqrVfzs&*z6jS}w}UqLcuwE7A3kyvUU>Oc`1^m3-j4u(i@(WTDO|1Gz2fGEc8qKQ zkqXY<%zr=FyX)?6!i$GHaNqA=gXgjFD?fX!2b*u-b>n8B7kTwhukXdC-?3HdSFsM} z)We#RlFg#Xw-RFn?1y(w0{j4M9bT^er_UUMZ|%ATsGoa5#l}-L`gjpIn@;CKli_uZ zn};z}@_#?~^b~Z z@K;M%I;<2-2feseOy^RoRs=@Z+6h^$!z;&!b7HV@mK}Z7O+Ey3 z=O;8=$>3t{b*b>J!52hyoI%0G{Cl1F9mqb+Ns$ECZ?0PAbfTzbidEH&-TQJbnALp% zDpq=!k$4l91am5MjZ$-`wyzlVx(?hBVod>yg1l(Fl9*f0<5A<8kn8Qel4rj=2@|Ww zVQzk*XJFs{wZ|)7$#u*d;T~}jdc!HP*6CZ(YGv=D>%EmcTr)8?QXTVzshyr9SDpHW zZc)DlaZ$w(5HKcKZ9+VXq7Wb)IQVB1eLaVbB(m`G?LqWaM1ZLDg6J{_iS$FOE^fVb zqd4-)DSdqyw_^KYY`-qhsXPFf0t$7^LCWwZez%kesyhrskzg*Vcd{n+87>ADFyL1m z1TjIZJ&yq60HZnMER{rwfQ+^Itv&U*+&mDOs$p%Yy)~8%(g85V7>bEC4|GW-5{bI@ z1c!-MCpLc-C~?6UE0~G!B7`91>!)ivRIxhdL?S&ZBH5ul!JMiQT@SF@gmthm`Z1^& zLn^Wwq0f%c11wyavd`&C3|P#C3T;=BaFLR_7PA;x-SH1I&brT{Nr^}Gvj#(-;KVxi z0jdUA^+TV1t>}*nT{`EjJnQb?=(deQy?jddEG*tGMi6PO&Uqj@cI2c>fc6<(X4R_- zr%iZa70340FQ4w(PtgZ(76YZj+=ecJ2&N9@&nj_(gU@8tl>nOmT(kMv{A0}t0TvOE zSppabCEY~QgEIHp)nwGPIfsC7SD|)6*o6V41h<#=?dW&Hk_?*Wk8WQfFs)sU07_sQ zB(l^pZMu8OQ; zD45U;oMQ-A@&@&jRo5!P_GKd=!P)~3#6Y# z%dB$ufMv^=7h!8{7f2be5Uz}GP1>=h7;B_sB+3N`>|74({`b=U+dFT)eg`bhZ7}^F zpL$qE{G_>kQ~TytO`Ms%;R}EG*zLPtDjBfsDr8TYRcq~E%hb%63*4N&am^fCBm&YY z(k;UlGPM?!`?8O6xct4jv*~?uCH}MNZ_JME-}vR-FI<+vhih8!(drhQ zLnAng%+6CmWQ$mqq%$|fVy3H`p#`cfdn69jw=rbS=o^BZAjWpyx7R#==+GgUbai<7 z_D!2MnZIv6_~^bn=D)Q2kF-F@v{0SXy+(7WO>Wy-l&&!@O-W^|Vq&G0+U{6@B-#lQ zB{4=5Z{EDw4CL$ZqV|&~Pr~FRLdAa6f0cqoEDIe8?KbJ6wFoVq6WY54?UbPuc zy!#FuKmLwkZfa@@I^UlD$@(^&TA#t`bs5Z{{>@CF{-LRvMUykz#+6OF=X5U50+(Gl zBWzY}Vf8L^qBX{tJ8n`+cNh{sC6PgU$G*H#mE3NJe%}^Otd(=IjGGa^(v{Uavr81v zH7kXxI+fDx)G`H5R3m^wm3wnmSX=77oARiWIS|2L1~ZSBIuyEV^E|*9Gjc%YN?>jg zIOfVlQ2As@u(x`#+FinVx~dD%>>5>5CMtEWsS{yvoB0=ZexaSm?n;7rHp#=_u9sqU z&x+aY9Lr(O`+#md?rn!bRCVL$4D!f|brvaR24yZbUO5kA%>ORyNgIgLuj0{CG_~O8 zPGC#5SH>&n5xu#WXxi0xb{n+Wq`kWx(Sn*&aS@({6+WhrZhQt7(rH)g^cfeMHeKPI zKQo|>0cg-XMvWMdI_lqY<54kDnQ-%U<5?Zg&xw*|!&a*cj0Vlg{H+*iDggIn% zK6Bo%uwF@#d41D7ry)u`>o}1v;Q;gF5(6EK3DEW4Kpw7{82eKl^Mt9Lo-=>niv6(v z9F0TcInj3f;_!2Gy~`?TA#XmMO{2~k0mHZxHJDtTF$z{NCNMFC@o)*qe9sqTYCEzljOR z^>*JP)B~(+N5oZl~U8-3YL*k_N(*CN-(goVh~_@WJ> zCt`8yW1kZH?*51VQ5d)W>eJ%kd;h8T5)cG6i>%E$9h*h=tat@1poop0Vdo`eFn3`h zfz=shb66_WT5Fr8qNQ&0CRm$D-O=q#Ovgw3sN|<&5&yb2oN*C9=_?fiHcxHN-gS&i z4rM^CV~4?B2~A2s+FY8=1`(^$rVvb|j+3`sXy=}BJEeuzb(Xgu`USIz03_JF;{i*Be;BtnQ{Ij4rr-?xr>HGfmx zfNQ`t;2LlZxQh_nsNW}i1y)#cqO^Jw~+R3LoF+DwfdgyI?*pH|Yu$ynbc?Uah zeG@nM&qX$V)9!O62M-=RIxN6Z#JXj~?-Sl~A#`qR#P1Ux8(yp{*x4NAJFIWQ`lh+r zbEeSC`Fmb?J3a6E4K-KueZm*i&Rri_@%07*qo IM6N<$f{4Jk(*OVf diff --git a/Templates/BaseGame/game/data/UI/images/separator-h.png b/Templates/BaseGame/game/data/UI/images/separator-h.png deleted file mode 100644 index 339c0fbe039e8b5cbdd085230594099c26928157..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Ed0V0oZ{G0)#BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%iF>*@hE&{2%E-w0@&CWQFtY@YFPFjrhT;U4EtAg|X#kZl Nc)I$ztaD0e0sy9+AwB>A diff --git a/Templates/BaseGame/game/data/UI/images/separator-v.png b/Templates/BaseGame/game/data/UI/images/separator-v.png deleted file mode 100644 index 6a0f873612cef214add9a2f88ed72dbafe92174c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 118 zcmeAS@N?(olHy`uVBq!ia0vp^GC<74!2~3aY}VEQQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JiX=Q;978H@CFNvfBrGsX`1Ak2{Z(F84g-d-`&k-}TiGQ5 P)i8Lv`njxgN@xNAx)CBs diff --git a/Templates/BaseGame/game/data/UI/images/slider - Copy.png b/Templates/BaseGame/game/data/UI/images/slider - Copy.png deleted file mode 100644 index 92fee1e9c13401f0b9fb319b14ebd267b7c1c8a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 908 zcmV;719SX|P)BsNz zeu<3YC~{d@T`O@7=Bqd8zh+r&1N$TtpK!GELCNikCSDYg%%{_tjFWkfZXnes>n;@ zqR|aj)!gZHXh8b=y;^A;kRu8#6pO{!Mvtd3L02hDKJM?<79kE%E?3>4B+0?(MwHD# znh=bupw`5N2ruq9KZs6u_7))i@#~}<;40XaEJtI*eV$Cj55Bf2ineZ<81cX|$A?-K ziRQ$vUFqvirBbh8IBB!lrWT$p@_Epw4{y{Jk<89s7(yreE_ZXgJAlQLOs#F|`{D~e zk1JU{!ht}*1pQDv9-m=Z)*TLqIgIfHJjnm+Zki*YSv0N&+<5q!9OI!(a(m|ZDWCi2 z+7hQAJOK~#FZBQBsFq0$xe508a5Ng7>+0%qd%a%d^ZA(i`uZ`3VWtE40bY>a7M7V# zB!+jkHs_9=>37>2j-V5r7a4n=; z!uTf4JA}`P;v1uD=Z~Jdb2XVYA zW9_{!_Y>&<@ydWoCaW7|c%=l304u9lXbBBDP18sKV$fMbp11YLDqKf%e#(kCvbjnH z0IY2MSwNH|Nr;Cm_2f`8%fP&(pfq1j&P&EykrGAGkevASCV(r$>yDU`^BZRlB!U6C zWJs>$^wwoAh)RXbi7W=16Mq@GgpA26$sz+uYE0GPzMbJE%h#`yBRq)9| zM)ez$XR{;UB9VaZPe36jlnmZKpDj2gSsD4W{t>WPgB5pU{)$x*B(ajOltDF2!h9-! iq)BbrE0*;C1Q-Ck2#=cQD4UW100001gDw+ diff --git a/Templates/BaseGame/game/data/UI/images/slider-w-box.png b/Templates/BaseGame/game/data/UI/images/slider-w-box.png deleted file mode 100644 index d9ef04961a30ad99f1e8871ef1f292b8a58d99f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 982 zcmV;{11bE8P)P001Qj1^@s6w^2g10000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#cu7P-RCwCFR!vM3K@@(oZI`u_7W)HS z_z46E5)-2a4+bql1U-1bs3#7@MD)a635mu~6G-Gn0+OI7O^h)fNi@NO!AOt<2?u@- z9*T%*X=%IvU1wGbyW4iRJ=m8_JMZl``|W!(^UWYsCMfWq4Q+02T9P!k*TKfx&%D0b zIAV74Q(YCX9ALy)joJOZchpx&6vet?Mob}N^dtoU6${^z1Pb{oBc|v~N>Z->n@DC( z^dn?hhVAVwNE{p-MuM=syre-K`>u)#Xl!f(o6S~Sxwf`8L6&6j`TR#QZC~prlSvid z+}u(e$w530ZEfwknBO1B>68EU^)=Huvgcc$9*%OPjCcpe23-4*Ecl4pS?Z!vATK~Iiu<8eTHFFyaGybOBf*v0#((zSZ!Ussc*KV zOSc(IBP*p4NV1{K&1b;)3K*lE;}RUd_RdRpkQHcQ{vA+^sH8cEioJZbKQB(*d>ETm zuGaa}MSa=Fv8LiO$#h;y@AHDD?T@o!>D`6mNv2*6_aqXDx41j*a=9k%Ha_7s%C58F zFXwu=WDCZkai-igF-SdCvFG!V4BWm>!3*e*>_?`8!JubxadCuYS^C-62cdY{%V|mO zPrfEv*U!cyQ>QNWdN!6mk8mtUKTi&Y8cr}=J`yS#jShsv;o0u)ZhuWp4fOW*GG4ED z6l>Dt*u#5hb>-U;I2DTx9PIAQwsqd{y8?C4-gT3yI9WaFU@BB>UKK8*>A7oteeO!E zq@o~z9iMO)Iy!(tXb3;o>AT`6pKHBx%T2qhfX53+u`y74whPk8o`uzwE162EM<|a8 zw7SIcYMIM%i)G?$iUZ2&2bNcK>ca7I7FI{%a5zA~1PCEZ@l)(h;K<%ZdJU70*H7+D zBuN4uf3=Z>TqcahOA4g;Y!Y6wSi+(x<|H9;qX{^~k}4v-QVOC4iG*J!WFkKE!Y<#Qq8}0K%2(y+C}?TL1t607*qoM6N<$ Eg3Ob{L;wH) diff --git a/Templates/BaseGame/game/data/UI/images/slider___Copy_image.asset.taml b/Templates/BaseGame/game/data/UI/images/slider___Copy_image.asset.taml deleted file mode 100644 index 3a460e432..000000000 --- a/Templates/BaseGame/game/data/UI/images/slider___Copy_image.asset.taml +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/Templates/BaseGame/game/data/UI/images/tab-border.png b/Templates/BaseGame/game/data/UI/images/tab-border.png deleted file mode 100644 index 6703924d48fb96552fe11a91696f7c282aea3439..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1203 zcmV;k1WfyhP)s+T@)zO{{b^^V< z=wH7wY(L{2P71F802ipY7kw@qE$vBN%q#5`37@CZ`H-O1-w@Umr|4D%f4*L^Nt+hhLK_6p2Z z%jmzE=C=LL3e%yyDGwhjj6U6g3bP`N-;PET+g?oxjXD4|r+B4=CaKr15}L$b?q6b0 zh8~SA%A;{SQ}t+Cpt=UfVlxhaEO#3>tT*c#8_eR@?>5%(PLkvwCV9zbSc8!+a4ONV zR-+KOJO_Zt7V|Std?$P6?aK-C`OA{+V;uY;3(0FXgFHquf);&@Yc?a<)A*xjHOZUF z9OEwblp3gHGX%+c&yuRyjAl==LJ=%0nk$@AZ@u)S6zSP8LLos?q-QfZ^*VWDa!G;yi`d#otZB4azuR)9UhD?F)aac|0iuXn*Eh1*_F zk5@SQ_F3yW*%QGMWE}P+4H9G+d(!r(D?=_|4>u*qe>cw_ShR}v@)e(9wdwjG#i_h1~oIT;xGv>0sd%EOptRemapText.setValue( "Re-bind \"" @ %name @ "\" to..." ); OptRemapInputCtrl.index = %rowIndex; Canvas.pushDialog( RemapDlg ); + + //Let the options menu know + %actionMap = $RemapActionMap[%rowIndex]; + + OptionsMenu.onKeybindChanged(%actionMap, %name); } function ControlsMenuRebindButton::onClick(%this) @@ -327,4 +334,4 @@ function redoMapping( %device, %actionMap, %action, %cmd, %oldIndex, %newIndex ) %actionMap.bind( %device, %action, %cmd ); fillRemapList(); -} \ No newline at end of file +} diff --git a/Templates/BaseGame/game/data/UI/scripts/cursors.tscript b/Templates/BaseGame/game/data/UI/scripts/cursors.tscript index d8aa31eeb..ba81636f7 100644 --- a/Templates/BaseGame/game/data/UI/scripts/cursors.tscript +++ b/Templates/BaseGame/game/data/UI/scripts/cursors.tscript @@ -37,4 +37,4 @@ else renderOffset = "0 0"; bitmapName = "data/ui/images/defaultCursor"; }; -} \ No newline at end of file +} diff --git a/Templates/BaseGame/game/data/UI/scripts/utility.tscript b/Templates/BaseGame/game/data/UI/scripts/utility.tscript index 357a6a182..e73d1c080 100644 --- a/Templates/BaseGame/game/data/UI/scripts/utility.tscript +++ b/Templates/BaseGame/game/data/UI/scripts/utility.tscript @@ -10,117 +10,123 @@ function getButtonBitmap(%device, %button) %device = "Xbox"; } - %path = ""; + %assetId = ""; if(%device $= "PS4") { - %path = "data/ui/images/inputs/PS4/PS4_"; + %assetId = "UI:PS4_"; if(%button $= "A" || %button $= "btn_a") - %path = %path @ "Cross"; + %assetId = %assetId @ "Cross"; else if(%button $= "B" || %button $= "btn_b") - %path = %path @ "Circle"; + %assetId = %assetId @ "Circle"; else if(%button $= "X" || %button $= "btn_x") - %path = %path @ "Square"; + %assetId = %assetId @ "Square"; else if(%button $= "Y" || %button $= "btn_y") - %path = %path @ "Triangle"; + %assetId = %assetId @ "Triangle"; else if(%button $= "LB") - %path = %path @ "L1"; + %assetId = %assetId @ "L1"; else if(%button $= "LT") - %path = %path @ "L2"; + %assetId = %assetId @ "L2"; else if(%button $= "RB") - %path = %path @ "R1"; + %assetId = %assetId @ "R1"; else if(%button $= "RT") - %path = %path @ "R2"; + %assetId = %assetId @ "R2"; else if(%button $= "thumbrx" || %button $= "thumbry") - %path = %path @ "Right_Stick"; + %assetId = %assetId @ "Right_Stick"; else if(%button $= "thumblx" || %button $= "thumbly") - %path = %path @ "Left_Stick"; + %assetId = %assetId @ "Left_Stick"; else if(%button $= "start") - %path = %path @ "Options"; + %assetId = %assetId @ "Options"; else if(%button $= "back") - %path = %path @ "Share"; + %assetId = %assetId @ "Share"; else if(%button $= "dpadu") - %path = %path @ "Dpad_Up"; + %assetId = %assetId @ "Dpad_Up"; else if(%button $= "dpadd") - %path = %path @ "Dpad_Down"; + %assetId = %assetId @ "Dpad_Down"; else if(%button $= "dpadl") - %path = %path @ "Dpad_Left"; + %assetId = %assetId @ "Dpad_Left"; else if(%button $= "dpadr") - %path = %path @ "Dpad_Right"; + %assetId = %assetId @ "Dpad_Right"; + + %assetId = %assetId @ "_image"; } else if(%device $= "Switch") { - %path = "data/ui/images/inputs/Switch/Switch_"; + %assetId = "UI:Switch_"; if(%button $= "A" || %button $= "btn_a") - %path = %path @ "B"; + %assetId = %assetId @ "B"; else if(%button $= "B" || %button $= "btn_b") - %path = %path @ "A"; + %assetId = %assetId @ "A"; else if(%button $= "X" || %button $= "btn_x") - %path = %path @ "Y"; + %assetId = %assetId @ "Y"; else if(%button $= "Y" || %button $= "btn_y") - %path = %path @ "X"; + %assetId = %assetId @ "X"; else if(%button $= "LB") - %path = %path @ "LB"; + %assetId = %assetId @ "LB"; else if(%button $= "LT") - %path = %path @ "LT"; + %assetId = %assetId @ "LT"; else if(%button $= "RB") - %path = %path @ "RB"; + %assetId = %assetId @ "RB"; else if(%button $= "RT") - %path = %path @ "RT"; + %assetId = %assetId @ "RT"; else if(%button $= "thumbrx" || %button $= "thumbry") - %path = %path @ "Right_Stick"; + %assetId = %assetId @ "Right_Stick"; else if(%button $= "thumblx" || %button $= "thumbly") - %path = %path @ "Left_Stick"; + %assetId = %assetId @ "Left_Stick"; else if(%button $= "start") - %path = %path @ "Plus"; + %assetId = %assetId @ "Plus"; else if(%button $= "back") - %path = %path @ "Minus"; + %assetId = %assetId @ "Minus"; else if(%button $= "dpadu") - %path = %path @ "Dpad_Up"; + %assetId = %assetId @ "Dpad_Up"; else if(%button $= "dpadd") - %path = %path @ "Dpad_Down"; + %assetId = %assetId @ "Dpad_Down"; else if(%button $= "dpadl") - %path = %path @ "Dpad_Left"; + %assetId = %assetId @ "Dpad_Left"; else if(%button $= "dpadr") - %path = %path @ "Dpad_Right"; + %assetId = %assetId @ "Dpad_Right"; + + %assetId = %assetId @ "_image"; } else if(%device $= "Keyboard" || %device $= "Mouse") { - %pathBase = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_"; - %path = %pathBase @ %button @ ".png"; - if(!isFile(%path)) - %path = %pathBase @ "Blank"; + %assetId = "UI:Keyboard_Black_" @ %button @ "_image"; } else if(%device !$= "") { - %path = "data/ui/images/inputs/Xbox/Xbox_"; + %assetId = "UI:Xbox_"; if(%button $= "btn_a") - %path = %path @ "B"; + %assetId = %assetId @ "B"; else if(%button $= "btn_b") - %path = %path @ "A"; + %assetId = %assetId @ "A"; else if(%button $= "btn_x") - %path = %path @ "Y"; + %assetId = %assetId @ "Y"; else if(%button $= "btn_y") - %path = %path @ "X"; + %assetId = %assetId @ "X"; else if(%button $= "thumbrx" || %button $= "thumbry") - %path = %path @ "Right_Stick"; + %assetId = %assetId @ "Right_Stick"; else if(%button $= "thumblx" || %button $= "thumbly") - %path = %path @ "Left_Stick"; + %assetId = %assetId @ "Left_Stick"; else if(%button $= "start") - %path = %path @ "Menu"; + %assetId = %assetId @ "Menu"; else if(%button $= "back") - %path = %path @ "Windows"; + %assetId = %assetId @ "Windows"; else if(%button $= "dpadu") - %path = %path @ "Dpad_Up"; + %assetId = %assetId @ "Dpad_Up"; else if(%button $= "dpadd") - %path = %path @ "Dpad_Down"; + %assetId = %assetId @ "Dpad_Down"; else if(%button $= "dpadl") - %path = %path @ "Dpad_Left"; + %assetId = %assetId @ "Dpad_Left"; else if(%button $= "dpadr") - %path = %path @ "Dpad_Right"; + %assetId = %assetId @ "Dpad_Right"; + + %assetId = %assetId @ "_image"; } - return %path; -} \ No newline at end of file + if(!AssetDatabase.isDeclaredAsset(%assetId)) + %assetId = "UI:Keyboard_Black_Blank_image"; + + return %assetId; +} diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index 2e98c9b03..c149cf3f2 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -1743,7 +1743,9 @@ function beginGUIImport() DirectoryHandler::createFolder(0, filePath(%destinationPath)); } - if(!pathCopy(%file, %destinationPath, false)) + //Check if we need to even copy in the first place. If we do, ensure + //the copy actually worked + if((makeRelativePath(%file) !$= %destinationPath) && !pathCopy(%file, %destinationPath, false)) { projectImporterLog("ProjectImporter::beginGUIImport() - failed to copy GUI: " @ %file @ " to destination: " @ %destinationPath); @@ -1779,9 +1781,9 @@ function processGUIntoAsset(%guiName, %file) %tamlpath = %assetPath @ %assetName @ ".asset.taml"; %scriptFile = ""; - if(isImportingFile(%filePath @ "/" @ %fileName @ ".tscript")) + if(isImportingFile(makeFullPath(%filePath @ "/" @ %fileName @ "." @ $TorqueScriptFileExtension))) { - %scriptFile = %fileName @ ".tscript"; + %scriptFile = %fileName; } %asset = new GUIAsset() From 938e4930ae1f49cb47f8b27d5bbe4d44637263b8 Mon Sep 17 00:00:00 2001 From: JeffR Date: Tue, 22 Feb 2022 23:28:28 -0600 Subject: [PATCH 031/145] Git didn't properly actually commit new files. --- .../gui/controls/guiGameSettingsCtrl.cpp | 1121 +++++++++++++++++ .../source/gui/controls/guiGameSettingsCtrl.h | 313 +++++ .../game/data/UI/guis/NetGraphGui.asset.taml | 4 + .../game/data/UI/images/Torque_3D_logo.png | Bin 0 -> 9063 bytes .../data/UI/images/Torque_3D_logo_alt.png | Bin 0 -> 11616 bytes .../UI/images/Torque_3D_logo_shortcut.png | Bin 0 -> 10728 bytes .../game/data/UI/images/Torque_3D_logo_w.png | Bin 0 -> 19328 bytes .../game/data/UI/images/backgrounddark.png | Bin 0 -> 5751 bytes .../UI/images/backgrounddark_image.asset.taml | 3 + .../game/data/UI/images/clearbtn_d.png | Bin 0 -> 593 bytes .../UI/images/clearbtn_d_image.asset.taml | 3 + .../game/data/UI/images/clearbtn_h.png | Bin 0 -> 595 bytes .../UI/images/clearbtn_h_image.asset.taml | 3 + .../game/data/UI/images/clearbtn_n.png | Bin 0 -> 377 bytes .../UI/images/clearbtn_n_image.asset.taml | 3 + .../game/data/UI/images/collapsetoolbar_d.png | Bin 0 -> 280 bytes .../images/collapsetoolbar_d_image.asset.taml | 3 + .../game/data/UI/images/collapsetoolbar_h.png | Bin 0 -> 468 bytes .../images/collapsetoolbar_h_image.asset.taml | 3 + .../game/data/UI/images/collapsetoolbar_n.png | Bin 0 -> 439 bytes .../images/collapsetoolbar_n_image.asset.taml | 3 + .../data/UI/images/dropdownbuttonarrow.png | Bin 0 -> 132 bytes .../dropdownbuttonarrow_image.asset.taml | 3 + .../game/data/UI/images/dropdowntextEdit.png | Bin 0 -> 390 bytes .../images/dropdowntextEdit_image.asset.taml | 3 + .../game/data/UI/images/expandtoolbar_d.png | Bin 0 -> 278 bytes .../images/expandtoolbar_d_image.asset.taml | 3 + .../game/data/UI/images/expandtoolbar_h.png | Bin 0 -> 468 bytes .../images/expandtoolbar_h_image.asset.taml | 3 + .../game/data/UI/images/expandtoolbar_n.png | Bin 0 -> 437 bytes .../images/expandtoolbar_n_image.asset.taml | 3 + .../game/data/UI/images/groupborder.png | Bin 0 -> 1273 bytes .../UI/images/groupborder_image.asset.taml | 3 + .../game/data/UI/images/inactiveoverlay.png | Bin 0 -> 131 bytes .../images/inactiveoverlay_image.asset.taml | 3 + .../game/data/UI/images/menubutton.png | Bin 0 -> 3559 bytes .../UI/images/menubutton_image.asset.taml | 3 + .../game/data/UI/images/nextOption_n.png | Bin 0 -> 8517 bytes .../UI/images/nextOption_n_image.asset.taml | 8 + .../game/data/UI/images/nextbutton_d.png | Bin 0 -> 279 bytes .../UI/images/nextbutton_d_image.asset.taml | 3 + .../game/data/UI/images/nextbutton_h.png | Bin 0 -> 549 bytes .../UI/images/nextbutton_h_image.asset.taml | 3 + .../game/data/UI/images/nextbutton_n.png | Bin 0 -> 484 bytes .../UI/images/nextbutton_n_image.asset.taml | 3 + .../game/data/UI/images/nopreview.png | Bin 0 -> 34615 bytes .../data/UI/images/nopreview_image.asset.taml | 3 + .../game/data/UI/images/previousOption_n.png | Bin 0 -> 8194 bytes .../images/previousOption_n_image.asset.taml | 8 + .../game/data/UI/images/previousbutton_d.png | Bin 0 -> 290 bytes .../images/previousbutton_d_image.asset.taml | 3 + .../game/data/UI/images/previousbutton_h.png | Bin 0 -> 561 bytes .../images/previousbutton_h_image.asset.taml | 3 + .../game/data/UI/images/previousbutton_n.png | Bin 0 -> 494 bytes .../images/previousbutton_n_image.asset.taml | 3 + .../game/data/UI/images/selectorbutton.png | Bin 0 -> 4002 bytes .../UI/images/selectorbutton_image.asset.taml | 3 + .../data/UI/images/selectorbuttonblank.png | Bin 0 -> 744 bytes .../selectorbuttonblank_image.asset.taml | 3 + .../data/UI/images/selectorbuttondark.png | Bin 0 -> 1942 bytes .../selectorbuttondark_image.asset.taml | 3 + .../UI/images/selectorbuttonhighlightonly.png | Bin 0 -> 1613 bytes ...lectorbuttonhighlightonly_image.asset.taml | 3 + .../game/data/UI/images/separatorh.png | Bin 0 -> 117 bytes .../UI/images/separatorh_image.asset.taml | 3 + .../game/data/UI/images/separatorv.png | Bin 0 -> 118 bytes .../UI/images/separatorv_image.asset.taml | 3 + .../game/data/UI/images/sliderwbox.png | Bin 0 -> 982 bytes .../UI/images/sliderwbox_image.asset.taml | 3 + .../game/data/UI/images/tabborder.png | Bin 0 -> 1203 bytes .../data/UI/images/tabborder_image.asset.taml | 3 + .../data/UI/scripts/menuInputHandling.tscript | 510 ++++++++ 72 files changed, 2054 insertions(+) create mode 100644 Engine/source/gui/controls/guiGameSettingsCtrl.cpp create mode 100644 Engine/source/gui/controls/guiGameSettingsCtrl.h create mode 100644 Templates/BaseGame/game/data/UI/guis/NetGraphGui.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/Torque_3D_logo.png create mode 100644 Templates/BaseGame/game/data/UI/images/Torque_3D_logo_alt.png create mode 100644 Templates/BaseGame/game/data/UI/images/Torque_3D_logo_shortcut.png create mode 100644 Templates/BaseGame/game/data/UI/images/Torque_3D_logo_w.png create mode 100644 Templates/BaseGame/game/data/UI/images/backgrounddark.png create mode 100644 Templates/BaseGame/game/data/UI/images/backgrounddark_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/clearbtn_d.png create mode 100644 Templates/BaseGame/game/data/UI/images/clearbtn_d_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/clearbtn_h.png create mode 100644 Templates/BaseGame/game/data/UI/images/clearbtn_h_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/clearbtn_n.png create mode 100644 Templates/BaseGame/game/data/UI/images/clearbtn_n_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/collapsetoolbar_d.png create mode 100644 Templates/BaseGame/game/data/UI/images/collapsetoolbar_d_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/collapsetoolbar_h.png create mode 100644 Templates/BaseGame/game/data/UI/images/collapsetoolbar_h_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/collapsetoolbar_n.png create mode 100644 Templates/BaseGame/game/data/UI/images/collapsetoolbar_n_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/dropdownbuttonarrow.png create mode 100644 Templates/BaseGame/game/data/UI/images/dropdownbuttonarrow_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/dropdowntextEdit.png create mode 100644 Templates/BaseGame/game/data/UI/images/dropdowntextEdit_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/expandtoolbar_d.png create mode 100644 Templates/BaseGame/game/data/UI/images/expandtoolbar_d_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/expandtoolbar_h.png create mode 100644 Templates/BaseGame/game/data/UI/images/expandtoolbar_h_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/expandtoolbar_n.png create mode 100644 Templates/BaseGame/game/data/UI/images/expandtoolbar_n_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/groupborder.png create mode 100644 Templates/BaseGame/game/data/UI/images/groupborder_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/inactiveoverlay.png create mode 100644 Templates/BaseGame/game/data/UI/images/inactiveoverlay_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/menubutton.png create mode 100644 Templates/BaseGame/game/data/UI/images/menubutton_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/nextOption_n.png create mode 100644 Templates/BaseGame/game/data/UI/images/nextOption_n_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/nextbutton_d.png create mode 100644 Templates/BaseGame/game/data/UI/images/nextbutton_d_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/nextbutton_h.png create mode 100644 Templates/BaseGame/game/data/UI/images/nextbutton_h_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/nextbutton_n.png create mode 100644 Templates/BaseGame/game/data/UI/images/nextbutton_n_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/nopreview.png create mode 100644 Templates/BaseGame/game/data/UI/images/nopreview_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/previousOption_n.png create mode 100644 Templates/BaseGame/game/data/UI/images/previousOption_n_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/previousbutton_d.png create mode 100644 Templates/BaseGame/game/data/UI/images/previousbutton_d_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/previousbutton_h.png create mode 100644 Templates/BaseGame/game/data/UI/images/previousbutton_h_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/previousbutton_n.png create mode 100644 Templates/BaseGame/game/data/UI/images/previousbutton_n_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/selectorbutton.png create mode 100644 Templates/BaseGame/game/data/UI/images/selectorbutton_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/selectorbuttonblank.png create mode 100644 Templates/BaseGame/game/data/UI/images/selectorbuttonblank_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/selectorbuttondark.png create mode 100644 Templates/BaseGame/game/data/UI/images/selectorbuttondark_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly.png create mode 100644 Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/separatorh.png create mode 100644 Templates/BaseGame/game/data/UI/images/separatorh_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/separatorv.png create mode 100644 Templates/BaseGame/game/data/UI/images/separatorv_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/sliderwbox.png create mode 100644 Templates/BaseGame/game/data/UI/images/sliderwbox_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/images/tabborder.png create mode 100644 Templates/BaseGame/game/data/UI/images/tabborder_image.asset.taml create mode 100644 Templates/BaseGame/game/data/UI/scripts/menuInputHandling.tscript diff --git a/Engine/source/gui/controls/guiGameSettingsCtrl.cpp b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp new file mode 100644 index 000000000..1b6516e4a --- /dev/null +++ b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp @@ -0,0 +1,1121 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "guiGameSettingsCtrl.h" + +#include "console/consoleTypes.h" +#include "console/engineAPI.h" +#include "gfx/gfxDrawUtil.h" +#include "gui/containers/guiScrollCtrl.h" +#include "core/strings/stringUnit.h" +#include "gui/core/guiDefaultControlRender.h" + +//----------------------------------------------------------------------------- +// GuiGameSettingsCtrl +//----------------------------------------------------------------------------- + +GuiGameSettingsCtrl::GuiGameSettingsCtrl() : + mLabel(StringTable->EmptyString()), + mScriptCallback(StringTable->EmptyString()), + mTooltip(StringTable->EmptyString()), + mEnabled(true), + mSelected(false), + mSelectedOption(0), + mWrapOptions(false), + mMode(Mode::Default), + mValue(0), + mStepSize(1), + mRange(Point2F(0, 1)), + mCallbackOnInputs(false), + mConsumeKeyInputEvents(false), + mArrowSize(30), + mColumnSplit(250), + mRightPad(20) +{ + VECTOR_SET_ASSOCIATION(mOptions); + + // initialize the control callbacks + mCallbackOnA = StringTable->EmptyString(); + mCallbackOnB = mCallbackOnA; + mCallbackOnX = mCallbackOnA; + mCallbackOnY = mCallbackOnA; + + INIT_ASSET(KeybindBitmap); + INIT_ASSET(PreviousBitmap); + INIT_ASSET(NextBitmap); +} + +GuiGameSettingsCtrl::~GuiGameSettingsCtrl() +{ + mOptions.clear(); +} + +void GuiGameSettingsCtrl::onMouseMove(const GuiEvent& event) +{ + //check if we're inside an arrow/slider/etc and kick a highlight action + Parent::onMouseMove(event); +} + +void GuiGameSettingsCtrl::onMouseUp(const GuiEvent& event) +{ + Parent::onMouseUp(event); + + if (isEnabled()) + { + if (mMode == Mode::Default) + { + activate(); + } + else if (mMode == Mode::OptionList) + { + S32 xPos = globalToLocalCoord(event.mousePoint).x; + clickOption(xPos); + } + else if (mMode == Mode::Slider) + { + S32 xPos = globalToLocalCoord(event.mousePoint).x; + clickSlider(xPos); + } + else if (mMode == Mode::Keybind) + { + S32 xPos = globalToLocalCoord(event.mousePoint).x; + clickKeybind(xPos); + } + } +} + +void GuiGameSettingsCtrl::onRender(Point2I offset, const RectI &updateRect) +{ + GFXDrawUtil* drawUtil = GFX->getDrawUtil(); + + F32 xScale = (float) getWidth(); + + S32 height = getHeight(); + + Point2I currentOffset = offset; + Point2I extent = getExtent(); + Point2I textOffset(mProfile->mTextOffset.x * xScale, mProfile->mTextOffset.y); + Point2I textExtent(mColumnSplit, height); + Point2I iconExtent, iconOffset(0.0f, 0.0f); + + bool highlight = mHighlighted; + bool depressed = mDepressed; + + ColorI fontColor = mActive ? (highlight ? mProfile->mFontColorHL : mProfile->mFontColor) : mProfile->mFontColorNA; + ColorI fillColor = mActive ? (highlight ? mProfile->mFillColorHL : mProfile->mFillColor) : mProfile->mFillColorNA; + ColorI borderColor = mActive ? (highlight ? mProfile->mBorderColorHL : mProfile->mBorderColor) : mProfile->mBorderColorNA; + + RectI boundsRect(offset, getExtent()); + + if (!mHasTheme) + { + if (mProfile->mBorder != 0) + renderFilledBorder(boundsRect, borderColor, fillColor, mProfile->mBorderThickness); + else + GFX->getDrawUtil()->drawRectFill(boundsRect, fillColor); + } + else + { + S32 indexMultiplier = 1; + + if (!mActive) + indexMultiplier = 4; + else if (mDepressed || mStateOn) + indexMultiplier = 2; + else if (mHighlighted) + indexMultiplier = 3; + + renderSizableBitmapBordersFilled(boundsRect, indexMultiplier, mProfile); + } + + // render the text + drawUtil->setBitmapModulation(fontColor); + renderJustifiedText(currentOffset + textOffset, textExtent, mLabel); + + if (mMode == Mode::OptionList) + { + onRenderListOption(currentOffset); + } + else if (mMode == Mode::Slider) + { + onRenderSliderOption(currentOffset); + } + else if (mMode == Mode::Keybind) + { + onRenderKeybindOption(currentOffset); + } + + renderChildControls(offset, updateRect); +} + +void GuiGameSettingsCtrl::onRenderListOption(Point2I currentOffset) +{ + F32 xScale = (float)getWidth(); + + S32 height = getHeight(); + + GFXDrawUtil* drawer = GFX->getDrawUtil(); + + Point2I arrowOffset; + + S32 arrowOffsetY = 0; + + bool hasOptions = (mOptions.size() > 0) && mSelectedOption > -1; + if (hasOptions) + { + if (mPreviousBitmapAsset.notNull()) + { + // render the left arrow + bool arrowOnL = (isSelected() || isHighlighted()) && (mWrapOptions || (mSelectedOption > 0)); + arrowOffset.x = currentOffset.x + mColumnSplit; + arrowOffset.y = currentOffset.y + arrowOffsetY; + + drawer->clearBitmapModulation(); + drawer->drawBitmapStretch(mPreviousBitmap, RectI(arrowOffset, Point2I(mArrowSize, mArrowSize)), GFXBitmapFlip_None, GFXTextureFilterLinear, false); + } + else + { + // render the left arrow + bool arrowOnL = (isSelected() || isHighlighted()) && (mWrapOptions || (mSelectedOption > 0)); + arrowOffset.x = currentOffset.x + mColumnSplit; + arrowOffset.y = currentOffset.y + height/2; + + drawer->clearBitmapModulation(); + + drawer->drawLine(arrowOffset, Point2I(arrowOffset.x + mArrowSize, currentOffset.y), ColorI::WHITE); + drawer->drawLine(arrowOffset, Point2I(arrowOffset.x + mArrowSize, currentOffset.y + height), ColorI::WHITE); + } + + if (mNextBitmapAsset.notNull()) + { + // render the right arrow + bool arrowOnR = (isSelected() || isHighlighted()) && (mWrapOptions || (mSelectedOption < mOptions.size() - 1)); + arrowOffset.x = currentOffset.x + getWidth() - mRightPad - mArrowSize; + arrowOffset.y = currentOffset.y + arrowOffsetY; + + drawer->clearBitmapModulation(); + drawer->drawBitmapStretch(mNextBitmap, RectI(arrowOffset, Point2I(mArrowSize, mArrowSize)), GFXBitmapFlip_None, GFXTextureFilterLinear, false); + } + else + { + // render the left arrow + bool arrowOnL = (isSelected() || isHighlighted()) && (mWrapOptions || (mSelectedOption > 0)); + arrowOffset.x = currentOffset.x + getWidth() - mRightPad; + arrowOffset.y = currentOffset.y + height / 2; + + drawer->clearBitmapModulation(); + + drawer->drawLine(arrowOffset, Point2I(arrowOffset.x - mArrowSize, currentOffset.y), ColorI::WHITE); + drawer->drawLine(arrowOffset, Point2I(arrowOffset.x - mArrowSize, currentOffset.y + height), ColorI::WHITE); + } + + // get the appropriate font color + ColorI fontColor; + if (!mEnabled) + { + fontColor = mProfile->mFontColorNA; + } + else if (isSelected()) + { + fontColor = mProfile->mFontColorSEL; + } + else if (isHighlighted()) + { + fontColor = mProfile->mFontColorHL; + } + else + { + fontColor = mProfile->mFontColor; + } + + // calculate text to be at the center between the arrows + GFont* font = mProfile->mFont; + StringTableEntry text = mOptions[mSelectedOption].mDisplayText; + S32 textWidth = font->getStrWidth(text); + S32 columnWidth = xScale - mRightPad - mColumnSplit; + S32 columnCenter = mColumnSplit + (columnWidth >> 1); + S32 textStartX = columnCenter - (textWidth >> 1); + Point2I textOffset(textStartX, 0); + + // render the option text itself + Point2I textExtent(columnWidth, height); + drawer->setBitmapModulation(fontColor); + renderJustifiedText(currentOffset + Point2I(mColumnSplit, 0), textExtent, text); + } +} + +void GuiGameSettingsCtrl::onRenderSliderOption(Point2I currentOffset) +{ + F32 xScale = (float)getWidth(); + + S32 height = getHeight(); + + S32 arrowOffsetY = 0; + + GFXDrawUtil* drawer = GFX->getDrawUtil(); + + Point2I arrowOffset; + S32 columnSplit = mColumnSplit; + + + + /*if (mPreviousBitmapAsset.notNull()) + { + // render the left arrow + bool arrowOnL = (isSelected() || isHighlighted()) && (mWrapOptions || (mSelectedOption > 0)); + arrowOffset.x = currentOffset.x + columnSplit; + arrowOffset.y = currentOffset.y + arrowOffsetY; + + drawer->clearBitmapModulation(); + drawer->drawBitmapStretch(mPreviousBitmap, RectI(arrowOffset, Point2I(mArrowSize, mArrowSize)), GFXBitmapFlip_None, GFXTextureFilterLinear, false); + } + else + { + // render the left arrow + bool arrowOnL = (isSelected() || isHighlighted()) && (mWrapOptions || (mSelectedOption > 0)); + arrowOffset.x = currentOffset.x + mColumnSplit; + arrowOffset.y = currentOffset.y + height / 2; + + drawer->clearBitmapModulation(); + + drawer->drawLine(arrowOffset, Point2I(arrowOffset.x + mArrowSize, currentOffset.y), ColorI::WHITE); + drawer->drawLine(arrowOffset, Point2I(arrowOffset.x + mArrowSize, currentOffset.y + height), ColorI::WHITE); + } + + if (mNextBitmapAsset.notNull()) + { + // render the right arrow + bool arrowOnR = (isSelected() || isHighlighted()) && (mWrapOptions || (mSelectedOption < mOptions.size() - 1)); + arrowOffset.x = currentOffset.x + mRightPad * xScale - mArrowSize; + arrowOffset.y = currentOffset.y + arrowOffsetY; + + drawer->clearBitmapModulation(); + drawer->drawBitmapStretch(mNextBitmap, RectI(arrowOffset, Point2I(mArrowSize, mArrowSize)), GFXBitmapFlip_None, GFXTextureFilterLinear, false); + } + else + { + // render the left arrow + bool arrowOnL = (isSelected() || isHighlighted()) && (mWrapOptions || (mSelectedOption > 0)); + arrowOffset.x = currentOffset.x + getWidth() - mRightPad; + arrowOffset.y = currentOffset.y + height / 2; + + drawer->clearBitmapModulation(); + + drawer->drawLine(arrowOffset, Point2I(arrowOffset.x - mArrowSize, currentOffset.y), ColorI::WHITE); + drawer->drawLine(arrowOffset, Point2I(arrowOffset.x - mArrowSize, currentOffset.y + height), ColorI::WHITE); + }*/ + + //Draw the slider bar + + RectI sliderRect; + + S32 sliderOffset = 5; + + RectI optionRect; + + sliderRect.point.x = currentOffset.x + columnSplit + mArrowSize; + sliderRect.point.y = currentOffset.y + sliderOffset; + + sliderRect.extent.x = (currentOffset.x + getWidth() - mRightPad - mArrowSize) - sliderRect.point.x; + sliderRect.extent.y = height - sliderOffset*2; + + optionRect = sliderRect; + + S32 textWidth = sliderRect.extent.x * 0.3; + sliderRect.extent.x -= textWidth; + + //Now adjust the bar to match-to our value + + S32 barStart = sliderRect.point.x; + S32 barEnd = sliderRect.point.x + sliderRect.extent.x; + + S32 xPosFill = (((mValue - mRange.x) * (barEnd - barStart)) / (mRange.y - mRange.x)) + barStart; + + RectI fillRect = sliderRect; + fillRect.extent.x = xPosFill - sliderRect.point.x; + + ColorI barColor; + ColorI barOutlineColor; + if (isSelected()) + { + barColor = mProfile->mFontColor; + barOutlineColor = mProfile->mFontColorSEL; + } + else + { + barColor = mProfile->mFontColor; + barOutlineColor = mProfile->mFontColorHL; + } + + drawer->drawRectFill(fillRect, barColor); + + drawer->drawRect(sliderRect, barOutlineColor); + + // get the appropriate font color + ColorI fontColor; + if (!mEnabled) + { + fontColor = mProfile->mFontColorNA; + } + else if (isSelected()) + { + fontColor = mProfile->mFontColorSEL; + } + else if (isHighlighted()) + { + fontColor = mProfile->mFontColorHL; + } + else + { + fontColor = mProfile->mFontColor; + } + + // calculate text to be at the center between the arrows + GFont* font = mProfile->mFont; + + char stringVal[32]; + dSprintf(stringVal, 32, "%f", mValue); + + S32 stringWidth = font->getStrWidth(stringVal); + Point2I textOffset(sliderRect.point.x + sliderRect.extent.x, 0); + + // render the option text itself + Point2I textExtent(textWidth, height); + + RectI textRect = optionRect; + textRect.point.x = sliderRect.point.x + sliderRect.extent.x; + textRect.extent.x = optionRect.extent.x * 0.3; + + drawer->setBitmapModulation(fontColor); + renderJustifiedText(textRect.point, textRect.extent, stringVal); + + //drawer->drawRectFill(textRect, ColorI::RED); +} + +void GuiGameSettingsCtrl::onRenderKeybindOption(Point2I currentOffset) +{ + F32 xScale = (float)getWidth(); + S32 columnSplit = mColumnSplit; + + S32 height = getHeight(); + + GFXDrawUtil* drawer = GFX->getDrawUtil(); + //drawer->drawBitmap(mBitmap, ) + + Point2I button; + button.x = currentOffset.x + columnSplit + (columnSplit / 2.5)/* + (optionWidth / 2)*/; + button.y = currentOffset.y; + + Point2I buttonSize; + buttonSize.x = height; + buttonSize.y = height; + + if (mKeybindBitmapAsset.notNull()) + { + RectI rect(button, buttonSize); + drawer->clearBitmapModulation(); + drawer->drawBitmapStretch(mKeybindBitmap, rect, GFXBitmapFlip_None, GFXTextureFilterLinear, false); + } + + //drawer->drawRectFill(button, ColorI::BLUE); +} + +void GuiGameSettingsCtrl::set(const char* label, const char* callback, bool useHighlightIcon, bool enabled, S32 mode, const char* tooltip) +{ + mScriptCallback = (dStrlen(callback) > 0) ? StringTable->insert(callback, true) : NULL; + mEnabled = enabled; + mMode = (Mode)mode; + mTooltip = StringTable->insert(tooltip); + mLabel = StringTable->insert(label, true); +} + +void GuiGameSettingsCtrl::setListSetting(const char* label, const char* optionsList, bool wrapOptions, const char* callback, bool enabled, const char* tooltip, const char* defaultValue) +{ + static StringTableEntry DELIM = StringTable->insert("\t", true); + + Vector options(__FILE__, __LINE__); + + S32 defaultOption = 0; + + S32 count = StringUnit::getUnitCount(optionsList, DELIM); + for (S32 i = 0; i < count; ++i) + { + OptionEntry e; + const char* option = StringUnit::getUnit(optionsList, i, DELIM); + e.mDisplayText = StringTable->insert(option, true); + e.mKeyString = e.mDisplayText; + options.push_back(e); + + if (String::compare(option, defaultValue) == 0) + defaultOption = options.size() - 1; + } + mOptions = options; + bool hasOptions = mOptions.size() > 0; + mSelectedOption = (hasOptions) ? defaultOption : NO_OPTION; + mWrapOptions = wrapOptions; + set(label, callback, true, (hasOptions) ? enabled : false, Mode::OptionList, tooltip); +} + +void GuiGameSettingsCtrl::setSliderSetting(const char* label, F32 defaultValue, F32 increments, Point2F range, const char* callback, bool enabled, const char* tooltip) +{ + static StringTableEntry DELIM = StringTable->insert("\t", true); + + mValue = defaultValue; + mStepSize = increments; + mRange = range; + + set(label, callback, true, enabled, Mode::Slider, tooltip); +} + +void GuiGameSettingsCtrl::setKeybindSetting(const char* label, const char* bitmapName, const char* callback, bool enabled, const char* tooltip) +{ + static StringTableEntry DELIM = StringTable->insert("\t", true); + + _setKeybindBitmap(StringTable->insert(bitmapName)); + + //if(mBitmap != StringTable->EmptyString()) + // mBitmapTex.set(mBitmap, &GFXDefaultGUIProfile, avar("%s() - mTextureObject (line %d)", __FUNCTION__, __LINE__)); + + set(label, callback, true, enabled, Mode::Keybind, tooltip); +} + +bool GuiGameSettingsCtrl::onAdd() +{ + if( !Parent::onAdd() ) + return false; + + return true; +} + +bool GuiGameSettingsCtrl::onWake() +{ + if( !Parent::onWake() ) + return false; + + return true; +} +void GuiGameSettingsCtrl::activate() +{ + if(isSelected() && isEnabled() && (mScriptCallback != StringTable->EmptyString())) + { + setThisControl(); + if (Con::isFunction(mScriptCallback)) + { + Con::executef(mScriptCallback); + } + } +} + +void GuiGameSettingsCtrl::setSelected() +{ + if (!isEnabled()) + return; + + mSelected = true; +} + +bool GuiGameSettingsCtrl::isEnabled() const +{ + return mEnabled; +} + +void GuiGameSettingsCtrl::setEnabled(bool enabled) +{ + mEnabled = enabled; +} + +void GuiGameSettingsCtrl::doScriptCommand(StringTableEntry command) +{ + if (command && command[0]) + { + setThisControl(); + Con::evaluate(command, false, __FILE__); + } +} + +void GuiGameSettingsCtrl::setThisControl() +{ + smThisControl = this; +} + +StringTableEntry GuiGameSettingsCtrl::getLabel() const +{ + return mLabel; +} + +void GuiGameSettingsCtrl::setLabel( const char * label) +{ + mLabel = StringTable->insert(label, true); +} + +void GuiGameSettingsCtrl::clear() +{ + mOptions.clear(); +} + +//----------------------------------------------------------------------------- +// Console stuff (GuiGameSettingsCtrl) +//----------------------------------------------------------------------------- + +StringTableEntry GuiGameSettingsCtrl::getCurrentOption() const +{ + if (mSelectedOption != NO_OPTION && !mOptions.empty()) + { + return mOptions[mSelectedOption].mDisplayText; + } + + return StringTable->insert("", false); +} + +StringTableEntry GuiGameSettingsCtrl::getCurrentOptionKey() const +{ + if (mSelectedOption != NO_OPTION) + { + return mOptions[mSelectedOption].mKeyString; + } + + return StringTable->insert("", false); +} + +S32 GuiGameSettingsCtrl::getCurrentOptionIndex() const +{ + if (mSelectedOption != NO_OPTION) + { + return mSelectedOption; + } + + return S32(-1); +} + +bool GuiGameSettingsCtrl::selectOption(const char* theOption) +{ + for (Vector::iterator anOption = mOptions.begin(); anOption < mOptions.end(); ++anOption) + { + if (String::compare((*anOption).mDisplayText, theOption) == 0) + { + S32 newIndex = anOption - mOptions.begin(); + mSelectedOption = newIndex; + return true; + } + } + + return false; +} + +bool GuiGameSettingsCtrl::selectOptionByKey(const char* optionKey) +{ + for (Vector::iterator anOption = mOptions.begin(); anOption < mOptions.end(); ++anOption) + { + if (String::compare((*anOption).mKeyString, optionKey) == 0) + { + S32 newIndex = anOption - mOptions.begin(); + mSelectedOption = newIndex; + return true; + } + } + + return false; +} + +bool GuiGameSettingsCtrl::selectOptionByIndex(S32 optionIndex) +{ + if (optionIndex < mOptions.size() && optionIndex >= 0) + { + mSelectedOption = optionIndex; + return true; + } + + return false; +} + +void GuiGameSettingsCtrl::setOptions(const char* optionsList) +{ + static StringTableEntry DELIM = StringTable->insert("\t", true); + + S32 count = StringUnit::getUnitCount(optionsList, DELIM); + mOptions.setSize(count); + for (S32 i = 0; i < count; ++i) + { + const char* option = StringUnit::getUnit(optionsList, i, DELIM); + OptionEntry e; + e.mDisplayText = StringTable->insert(option, true); + e.mKeyString = e.mDisplayText; + mOptions[i] = e; + } + + if (mSelectedOption >= mOptions.size()) + { + mSelectedOption = mOptions.size() - 1; + } +} + +void GuiGameSettingsCtrl::addOption(const char* displayText, const char* keyText) +{ + OptionEntry e; + e.mDisplayText = StringTable->insert(displayText, true); + e.mKeyString = (keyText[0] == '\0') ? e.mDisplayText : StringTable->insert(keyText, true); + + mOptions.push_back(e); +} + +void GuiGameSettingsCtrl::clickOption(S32 xPos) +{ + F32 xScale = (float)getWidth(); + + S32 leftArrowX1 = mColumnSplit; + S32 leftArrowX2 = leftArrowX1 + mArrowSize; + + S32 rightArrowX2 = getWidth() - mRightPad; + S32 rightArrowX1 = rightArrowX2 - mArrowSize; + + if ((leftArrowX1 <= xPos) && (xPos <= leftArrowX2)) + { + changeOption(-1); + } + else if ((rightArrowX1 <= xPos) && (xPos <= rightArrowX2)) + { + changeOption(1); + } +} + +void GuiGameSettingsCtrl::changeOption(S32 delta) +{ + S32 optionCount = mOptions.size(); + + S32 newSelection = mSelectedOption + delta; + if (optionCount == 0) + { + newSelection = NO_OPTION; + } + else if (!mWrapOptions) + { + newSelection = mClamp(newSelection, 0, optionCount - 1); + } + else if (newSelection < 0) + { + newSelection = optionCount - 1; + } + else if (newSelection >= optionCount) + { + newSelection = 0; + } + mSelectedOption = newSelection; + + if (mMode == GuiGameSettingsCtrl::Slider) + { + mValue += mStepSize * delta; + + mValue = mRound(mValue / mStepSize) * mStepSize; + + if (mValue < mRange.x) + mValue = mRange.x; + if (mValue > mRange.y) + mValue = mRange.y; + } + + static StringTableEntry LEFT = StringTable->insert("LEFT", true); + static StringTableEntry RIGHT = StringTable->insert("RIGHT", true); + + onChange_callback(); + + if (mScriptCallback != NULL && (mSelectedOption != NO_OPTION && mMode != GuiGameSettingsCtrl::Slider)) + { + setThisControl(); + StringTableEntry direction = NULL; + if (delta < 0) + { + direction = LEFT; + } + else if (delta > 0) + { + direction = RIGHT; + } + if ((direction != NULL) && (Con::isFunction(mScriptCallback))) + { + Con::executef(mScriptCallback, direction); + } + } +} +IMPLEMENT_CONOBJECT(GuiGameSettingsCtrl); + +void GuiGameSettingsCtrl::clickSlider(S32 xPos) +{ + F32 xScale = (float)getWidth(); + + S32 leftArrowX1 = mColumnSplit; + S32 leftArrowX2 = leftArrowX1 + mArrowSize; + + S32 rightArrowX2 = getWidth() - mRightPad; + S32 rightArrowX1 = rightArrowX2 - mArrowSize; + + S32 sliderWidth = rightArrowX1 - leftArrowX2; + sliderWidth *= 0.6; //remove the number text spacing + + /*if ((leftArrowX1 <= xPos) && (xPos <= leftArrowX2)) + { + mValue -= mStepSize; + + mValue = mRound(mValue / mStepSize) * mStepSize; + + if (mValue < mRange.x) + mValue = mRange.x; + + } + else if ((rightArrowX1 <= xPos) && (xPos <= rightArrowX2)) + { + //F32 snap = mValue % mStepSize; + //mValue.y -= snap; + + mValue += mStepSize; + + mValue = mRound(mValue / mStepSize) * mStepSize; + + if (mValue > mRange.y) + mValue = mRange.y; + } + else + {*/ + //see if we clicked on the sliderbar itself + S32 barStart = leftArrowX2; + S32 barEnd = barStart + sliderWidth; + + if (xPos >= barStart && xPos <= barEnd) + { + //find the position + F32 newValue = (((xPos - barStart) * (mRange.y - mRange.x)) / (barEnd - barStart)) + mRange.x; + + newValue = mRound(newValue / mStepSize) * mStepSize; + + mValue = newValue; + } + //} + + onChange_callback(); +} + +void GuiGameSettingsCtrl::clickKeybind(S32 xPos) +{ + S32 columnSplit = mColumnSplit; + + S32 height = getHeight(); + + Point2I button; + button.x = columnSplit + (columnSplit / 2.5)/* + (optionWidth / 2)*/; + button.y = 0; + + Point2I buttonSize; + buttonSize.x = height; + buttonSize.y = height; + + RectI rect(button, buttonSize); + + onChange_callback(); + + if (rect.pointInRect(Point2I(xPos, getHeight()/2))) + { + if (mScriptCallback != StringTable->EmptyString()) + { + Con::executef(mScriptCallback, this); + } + } +} + +F32 GuiGameSettingsCtrl::getValue() +{ + return mValue; +} + +void GuiGameSettingsCtrl::setValue(F32 value) +{ + mValue = value; +} + +const char* GuiGameSettingsCtrl::getTooltip() +{ + return mTooltip; +} + +ConsoleDocClass( GuiGameSettingsCtrl, + "@brief A base class for cross platform menu controls that are gamepad friendly.\n\n" + + "This class is used to build row-based menu GUIs that can be easily navigated " + "using the keyboard, mouse or gamepad. The desired row can be selected using " + "the mouse, or by navigating using the Up and Down buttons.\n\n" + + "@tsexample\n\n" + "new GuiGameSettingsCtrl()\n" + "{\n" + " debugRender = \"0\";\n" + " callbackOnA = \"applyOptions();\";\n" + " callbackOnB = \"Canvas.setContent(MainMenuGui);\";\n" + " callbackOnX = \"\";\n" + " callbackOnY = \"revertOptions();\";\n" + " //Properties not specific to this control have been omitted from this example.\n" + "};\n" + "@endtsexample\n\n" + + "@see GuiGameSettingsProfile\n\n" + + "@ingroup GuiGame" +); + +IMPLEMENT_CALLBACK( GuiGameSettingsCtrl, onChange, void, (), (), + "Called when the setting's value changes." ); + +IMPLEMENT_CALLBACK(GuiGameSettingsCtrl, onInputEvent, void, (const char* device, const char* action, bool state), + (device, action, state), + "@brief Callback that occurs when an input is triggered on this control\n\n" + "@param device The device type triggering the input, such as keyboard, mouse, etc\n" + "@param action The actual event occuring, such as a key or button\n" + "@param state True if the action is being pressed, false if it is being release\n\n"); + +IMPLEMENT_CALLBACK(GuiGameSettingsCtrl, onAxisEvent, void, (const char* device, const char* action, F32 axisValue), + (device, action, axisValue), + "@brief Callback that occurs when an axis event is triggered on this control\n\n" + "@param device The device type triggering the input, such as mouse, joystick, gamepad, etc\n" + "@param action The ActionMap code for the axis\n" + "@param axisValue The current value of the axis\n\n"); + +void GuiGameSettingsCtrl::initPersistFields() +{ + INITPERSISTFIELD_IMAGEASSET(KeybindBitmap, GuiGameSettingsCtrl, "Bitmap used to display the bound key for this keybind option."); + INITPERSISTFIELD_IMAGEASSET(PreviousBitmap, GuiGameSettingsCtrl, "Bitmap used for the previous button when in list mode."); + INITPERSISTFIELD_IMAGEASSET(NextBitmap, GuiGameSettingsCtrl, "Bitmap used for the next button when in list mode."); + + addField("arrowSize", TypeS32, Offset(mArrowSize, GuiGameSettingsCtrl), + "Size of the arrow buttons' extents"); + + addField("columnSplit", TypeS32, Offset(mColumnSplit, GuiGameSettingsCtrl), + "Position of the split between the leftside label and the rightside setting parts"); + + addField("rightPad", TypeS32, Offset(mRightPad, GuiGameSettingsCtrl), + "Padding between the rightmost edge of the control and right arrow."); + + addField("callbackOnA", TypeString, Offset(mCallbackOnA, GuiGameSettingsCtrl), + "Script callback when the 'A' button is pressed. 'A' inputs are Keyboard: A, Return, Space; Gamepad: A, Start" ); + + addField("callbackOnB", TypeString, Offset(mCallbackOnB, GuiGameSettingsCtrl), + "Script callback when the 'B' button is pressed. 'B' inputs are Keyboard: B, Esc, Backspace, Delete; Gamepad: B, Back" ); + + addField("callbackOnX", TypeString, Offset(mCallbackOnX, GuiGameSettingsCtrl), + "Script callback when the 'X' button is pressed. 'X' inputs are Keyboard: X; Gamepad: X" ); + + addField("callbackOnY", TypeString, Offset(mCallbackOnY, GuiGameSettingsCtrl), + "Script callback when the 'Y' button is pressed. 'Y' inputs are Keyboard: Y; Gamepad: Y" ); + + addField("callbackOnInputs", TypeBool, Offset(mCallbackOnInputs, GuiGameSettingsCtrl), + "Script callback when any inputs are detected, even if they aren't the regular 4 face buttons. Useful for secondary/speciality handling of menu navigation."); + + addField("consumeKeyInputEvents", TypeBool, Offset(mConsumeKeyInputEvents, GuiGameSettingsCtrl), + "When callbackOnInputs is active, this indicates if the input event should be consumed, or allowed 'through' to let other things respond to the event as well."); + + + Parent::initPersistFields(); +} + +DefineEngineMethod( GuiGameSettingsCtrl, isEnabled, bool, (),, + "Determines if the control is enabled or disabled.\n\n" + "@return True if the control is enabled. False if the control is not enabled." ) +{ + return object->isEnabled(); +} + +DefineEngineMethod( GuiGameSettingsCtrl, setEnabled, void, ( bool enabled ),, + "Sets the control's enabled status according to the given parameters.\n\n" + "@param enabled Indicate true to enable the control or false to disable it." ) +{ + object->setEnabled( enabled ); +} + +DefineEngineMethod( GuiGameSettingsCtrl, activate, void, (),, + "Activates the control. The script callback of the control will be called (if it has one)." ) +{ + object->activate(); +} + +DefineEngineMethod(GuiGameSettingsCtrl, getLabel, const char *, (),, + "Gets the label displayed.\n\n" + "@return The label." ) +{ + return object->getLabel(); +} + +DefineEngineMethod(GuiGameSettingsCtrl, setLabel, void, ( const char* label ),, + "Sets the label.\n\n" + "@param label Text to set as the label.\n" ) +{ + object->setLabel(label ); +} + +DefineEngineMethod( GuiGameSettingsCtrl, setSelected, void, (),, + "Sets the control as selected. Can only select enabled controls." ) +{ + object->setSelected(); +} + +DefineEngineMethod( GuiGameSettingsCtrl, getSelected, bool, (),, + "Gets if the control is currently selected.\n\n" + "@return if the control is selected." ) +{ + return object->isSelected(); +} + +DefineEngineMethod(GuiGameSettingsCtrl, clear, void, (), , + "Clears the current options.\n\n") +{ + return object->clear(); +} + +DefineEngineMethod(GuiGameSettingsCtrl, getMode, S32, (), , + "Gets this control's options mode.\n\n") +{ + GuiGameSettingsCtrl::Mode mode = object->getMode(); + if (mode == GuiGameSettingsCtrl::Mode::OptionList) + return 0; + else if (mode == GuiGameSettingsCtrl::Mode::Slider) + return 1; + else if (mode == GuiGameSettingsCtrl::Mode::Keybind) + return 2; + else + return -1; +} + +DefineEngineMethod(GuiGameSettingsCtrl, setListSetting, void, + (const char* label, const char* options, bool wrapOptions, const char* callback, bool enabled, const char* tooltip, const char* defaultValue), + (true, "", ""), + "Sets this setting to a list.\n\n" + "@param label The text to display as a label.\n" + "@param options A tab separated list of options.\n" + "@param wrapOptions Specify true to allow options to wrap at each end or false to prevent wrapping.\n" + "@param callback Name of a script function to use as a callback when this control is activated.\n" + "@param enabled [optional] If this control is initially enabled.") +{ + object->setListSetting(label, options, wrapOptions, callback, enabled, tooltip, defaultValue); +} + +DefineEngineMethod(GuiGameSettingsCtrl, setSliderSetting, void, +(const char* label, F32 defaultValue, F32 increment, Point2F range, const char* callback, bool enabled, const char* tooltip), +(true, ""), +"Sets this setting to a slider.\n\n" +"@param label The text to display as a label.\n" +"@param options A tab separated list of options.\n" +"@param wrapOptions Specify true to allow options to wrap at each end or false to prevent wrapping.\n" +"@param callback Name of a script function to use as a callback when this control is activated.\n" +"@param enabled [optional] If this control is initially enabled.") +{ + object->setSliderSetting(label, defaultValue, increment, range, callback, enabled, tooltip); +} + +DefineEngineMethod(GuiGameSettingsCtrl, setKeybindSetting, void, +(const char* label, const char* bitmapName, const char* callback, bool enabled, const char* tooltip), +(true, ""), +"Sets this setting to a keybind.\n\n" +"@param label The text to display as a label.\n" +"@param options A tab separated list of options.\n" +"@param wrapOptions Specify true to allow options to wrap at each end or false to prevent wrapping.\n" +"@param callback Name of a script function to use as a callback when this control is activated.\n" +"@param enabled [optional] If this control is initially enabled.") +{ + object->setKeybindSetting(label, bitmapName, callback, enabled, tooltip); +} + +DefineEngineMethod(GuiGameSettingsCtrl, getCurrentOption, const char*, (), , + "Gets the text for the currently selected option .\n\n" + "@return A string representing the text currently displayed as the selected option. If there is no such displayed text then the empty string is returned.") +{ + return object->getCurrentOption(); +} + +DefineEngineMethod(GuiGameSettingsCtrl, getCurrentOptionKey, const char*, (), , + "Gets the key string for the currently selected option.\n\n" + "@return The key (or id) that was assigned to the selected option. If there is no selected option then the empty string is returned.") +{ + return object->getCurrentOptionKey(); +} + +DefineEngineMethod(GuiGameSettingsCtrl, getCurrentOptionIndex, S32, (), , + "Gets the index into the option list for the currently selected option.\n\n" + "@return The index of the selected option. If there is no selected option then -1 is returned.") +{ + return object->getCurrentOptionIndex(); +} + +DefineEngineMethod(GuiGameSettingsCtrl, selectOption, bool, (const char* option), , + "Set the control's current option to the one specified\n\n" + "@param option The option to be made active.\n" + "@return True if the control contained the option and was set, false otherwise.") +{ + return object->selectOption(option); +} + +DefineEngineMethod(GuiGameSettingsCtrl, selectOptionByKey, bool, (const char* optionKey), , + "Set the control's current option to the one with the specified key.\n\n" + "@param optionKey The key string that was assigned to the option to be made active.\n" + "@return True if the control contained the key and the option and was set, false otherwise.") +{ + return object->selectOptionByKey(optionKey); +} + +DefineEngineMethod(GuiGameSettingsCtrl, selectOptionByIndex, bool, (S32 optionIndex), , + "Set the control's current option to the one at the specified index.\n\n" + "@param optionIndex The index of the option to be made active.\n" + "@return True if the index was valid and the option and was set, false otherwise.") +{ + return object->selectOptionByIndex(optionIndex); +} + +DefineEngineMethod(GuiGameSettingsCtrl, setOptions, void, (const char* optionsList), , + "Sets the list of options on the given control.\n\n" + "@param optionsList A tab separated list of options for the control.") +{ + object->setOptions(optionsList); +} + +DefineEngineMethod(GuiGameSettingsCtrl, addOption, void, (const char* displayText, const char* keyText), (""), + "Adds an option to the list of options on the given control.\n\n" + "@param displayText The text to display for this option.\n" + "@param keyText [Optional] The id string to associate with this value. " + "If unset, the id will be the same as the display text.\n") +{ + object->addOption(displayText, keyText); +} + +DefineEngineMethod(GuiGameSettingsCtrl, getValue, F32, (), , + "Sets the list of options on the given control.\n\n" + "@param optionsList A tab separated list of options for the control.") +{ + return object->getValue(); +} + +DefineEngineMethod(GuiGameSettingsCtrl, setValue, void, (F32 value), , + "Sets the list of options on the given control.\n\n" + "@param optionsList A tab separated list of options for the control.") +{ + object->setValue(value); +} + +DefineEngineMethod(GuiGameSettingsCtrl, getTooltip, const char*, (), , + "Sets the list of options on the given control.\n\n" + "@param optionsList A tab separated list of options for the control.") +{ + return object->getTooltip(); +} diff --git a/Engine/source/gui/controls/guiGameSettingsCtrl.h b/Engine/source/gui/controls/guiGameSettingsCtrl.h new file mode 100644 index 000000000..d8aac95e8 --- /dev/null +++ b/Engine/source/gui/controls/guiGameSettingsCtrl.h @@ -0,0 +1,313 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef _GuiGameSettingsCtrl_H_ +#define _GuiGameSettingsCtrl_H_ + +#include "gui/buttons/guiButtonCtrl.h" +#include "T3D/assets/ImageAsset.h" + +/// \class GuiGameSettingsCtrl +/// A base class for cross platform menu controls that are gamepad friendly. +class GuiGameSettingsCtrl : public GuiButtonCtrl +{ +public: + typedef GuiButtonCtrl Parent; + + enum Mode + { + Default = 0, + OptionList, + Slider, + Keybind, + Text + }; + +protected: + + /// \struct OptionEntry + /// Display text and ID key for each entry in an option. + struct OptionEntry + { + StringTableEntry mDisplayText; ///< The text that is displayed for the option + StringTableEntry mKeyString; ///< Key value that is associated with this option + OptionEntry() : mDisplayText(StringTable->EmptyString()), mKeyString(StringTable->EmptyString()) {} + virtual ~OptionEntry() {} + }; + + + StringTableEntry mLabel; ///< Text to display in the control as a label + StringTableEntry mScriptCallback; ///< Script callback when control is activated + StringTableEntry mTooltip; ///< A descriptive tooltip message for what the control is + + Mode mMode; + + //List options + Vector mOptions; ///< Collection of options available to display + S32 mSelectedOption; ///< Index into mOptions pointing at the selected option + bool mWrapOptions; ///< Determines if options should "wrap around" at the ends + + //Slider option + F32 mValue; ///< When working as a slider, this contains the value + F32 mStepSize; ///< When working as a slider, this is the increment levels in the range + Point2F mRange; ///< When working as a slider, this sets our min/max range + + //Keybind option + DECLARE_IMAGEASSET(GuiGameSettingsCtrl, KeybindBitmap, changeBitmap, GFXDefaultGUIProfile); + DECLARE_ASSET_SETGET(GuiGameSettingsCtrl, KeybindBitmap); + + DECLARE_IMAGEASSET(GuiGameSettingsCtrl, PreviousBitmap, changeBitmap, GFXDefaultGUIProfile); + DECLARE_ASSET_SETGET(GuiGameSettingsCtrl, PreviousBitmap); + + DECLARE_IMAGEASSET(GuiGameSettingsCtrl, NextBitmap, changeBitmap, GFXDefaultGUIProfile); + DECLARE_ASSET_SETGET(GuiGameSettingsCtrl, NextBitmap); + + S32 mArrowSize; + S32 mColumnSplit; //Padding between the leftmost edge of the control, and the left side of the 'option'. + S32 mRightPad; + + bool mEnabled; + bool mSelected; + +public: + void changeBitmap() {} + + /// Sets the control as selected . Only controls that are enabled can be selected. + virtual void setSelected(); + + /// Determines if the specified control is enabled or disabled. + /// + /// \return True if the specified control is enabled. False if the control is not + /// enabled + virtual bool isEnabled() const; + + /// Sets a control's enabled status according to the given parameters. + /// + /// \param enabled Indicate true to enable the control or false to disable it. + virtual void setEnabled(bool enabled); + + /// Gets the label displayed on the control. + /// + /// \return The label for the control. + virtual StringTableEntry getLabel() const; + + /// Sets the label on the control. + /// + /// \param label Text to set as the label. + virtual void setLabel(const char * label); + + /// Sets the control to a List setting. + /// + /// \param label The text to display on the control as a label. + /// \param optionsList A tab separated list of options for the control. + /// \param wrapOptions Specify true to allow options to wrap at the ends or + /// false to prevent wrapping. + /// \param callback [optional] Name of a script function to use as a callback + /// when this control is activated. Default NULL means no callback. + /// \param enabled [optional] If this control is initially enabled. Default true. + void setListSetting(const char* label, const char* optionsList, bool wrapOptions, const char* callback,bool enabled, const char* tooltip = "", const char* defaultValue = ""); + + /// Sets the control to a Slider setting + /// + /// \param label The text to display on the control as a label. + /// \param defaultValue A float indicating the slider's default value + /// \param increments A float indicating the incremental values the slider snaps along between it's range + /// \param range A Point2F that indicates the minimum and maximum value range + /// \param callback [optional] Name of a script function to use as a callback + /// when this control is activated. Default NULL means no callback. + /// \param enabled [optional] If this control is initially enabled. Default true. + void setSliderSetting(const char* label, F32 defaultValue, F32 increments, Point2F range, const char* callback, bool enabled, const char* tooltip = ""); + + /// Sets the control to a Keybind setting + /// + /// \param label The text to display on the control as a label. + /// \param bitmapAssetId The assetId for the button display image + /// \param range A Point2F that indicates the minimum and maximum value range + /// \param callback [optional] Name of a script function to use as a callback + /// when this control is activated. Default NULL means no callback. + /// \param enabled [optional] If this control is initially enabled. Default true. + void setKeybindSetting(const char* label, const char* bitmapAssetId, const char* callback, bool enabled, const char* tooltip); + + /// Gets the text for the currently selected option of the control. + /// + /// \return A string representing the text currently displayed as the selected + /// option on the control. If there is no such displayed text then the empty + /// string is returned. + StringTableEntry getCurrentOption() const; + + /// Gets the key string for the currently selected option of the control + /// + /// \return The key (or id) that was assigned to the selected option on the + /// control. If there is no selected option then the empty string is returned. + StringTableEntry getCurrentOptionKey() const; + + /// Gets the index into the option list for the currently selected option of the control. + /// + /// \return The index of the selected option on the control. If there is no + /// selected option then -1 is returned. + S32 getCurrentOptionIndex() const; + + /// Attempts to set the control to the specified selected option. The option + /// will only be set if the option exists in the control. + /// + /// \param option The option to be made active. + /// \return True if the control contained the option and was set, false otherwise. + bool selectOption(const char* option); + + /// Attempts to set the control to the option with the specified key. The + /// option will only be set if the key exists in the control. + /// + /// \param optionKey The key string that was assigned to the option to be made active. + /// \return True if the control contained the key and the option and was set, false otherwise. + bool selectOptionByKey(const char* optionKey); + + /// Attempts to set the control to the option at the specified index. The option + /// will only be set if the index is valid. + /// + /// \param optionIndex The index of the option to be made active. + /// \return True if the index was valid and the option and was set, false otherwise. + bool selectOptionByIndex(S32 optionIndex); + + /// Sets the list of options on the control. + /// + /// \param optionsList A tab separated list of options for the control. + void setOptions(const char* optionsList); + + /// Adds an option to the list of options on the control. + /// + /// \param displayText The text to display for this option. + /// \param keyText The id string to associate with this value. If NULL the + /// id will be the same as the display text. + void addOption(const char* displayText, const char* keyText); + + /// Activates the control. The script callback of the control will + /// be called (if it has one). + virtual void activate(); + + /// Gets the value + /// + F32 getValue(); + + /// Sets the value + /// + /// \param value The new value to be set. + void setValue(F32 value); + + Mode getMode() { return mMode; } + + /// Gets the tooltip + const char* getTooltip(); + + GuiGameSettingsCtrl(); + ~GuiGameSettingsCtrl(); + + void onRender(Point2I offset, const RectI &updateRect); + + void onRenderListOption(Point2I currentOffset); + void onRenderSliderOption(Point2I currentOffset); + + void onRenderKeybindOption(Point2I currentOffset); + + /// Callback when the object is registered with the sim. + /// + /// \return True if the profile was successfully added, false otherwise. + bool onAdd(); + + /// Callback when the control wakes up. + bool onWake(); + + void clear(); + + virtual void onMouseMove(const GuiEvent& event); + virtual void onMouseUp(const GuiEvent& event); + + DECLARE_CONOBJECT(GuiGameSettingsCtrl); + DECLARE_CATEGORY( "Gui Game" ); + DECLARE_DESCRIPTION( "Base class for cross platform menu controls that are gamepad friendly." ); + + /// Initializes fields accessible through the console. + static void initPersistFields(); + + static const S32 NO_OPTION = -1; ///< Indicates there is no option + +protected: + /// Sets up the option + /// + /// \param label The text to display on the control as a label. + /// \param callback Name of a script function to use as a callback when this + /// control is activated. + /// \param enabled [optional] If this control is initially enabled. Default true. + virtual void set(const char* label, const char* callback, bool useHighlightIcon = true, bool enabled = true, S32 mode = 0, const char* tooltip = ""); + + /// Sets the script variable $ThisControl to reflect this control. + virtual void setThisControl(); + + /// @name Callbacks + /// @{ + DECLARE_CALLBACK( void, onChange, () ); + + DECLARE_CALLBACK(void, onInputEvent, (const char* device, const char* action, bool state)); + + DECLARE_CALLBACK(void, onAxisEvent, (const char* device, const char* action, F32 axisValue)); + /// @} + + /// Evaluates some script. If the command is empty then nothing is evaluated. + /// + /// \param command The script to evaluate. + void doScriptCommand(StringTableEntry command); + + StringTableEntry mCallbackOnA; ///< Script callback when the 'A' button is pressed + StringTableEntry mCallbackOnB; ///< Script callback when the 'B' button is pressed + StringTableEntry mCallbackOnX; ///< Script callback when the 'X' button is pressed + StringTableEntry mCallbackOnY; ///< Script callback when the 'Y' button is pressed + +private: + /// Performs a click on the current option. The x position is used to + /// determine if the left or right arrow were clicked. If one was clicked, the + /// option will be changed. If neither was clicked, the option is unaffected. + /// This method should only be called when there is an actively selected control. + /// + /// \param xPos The x position of the the click, relative to the control. + void clickOption(S32 xPos); + + /// Changes the option on the currently selected control. + /// + /// \param delta The amount to change the option selection by. Typically this + /// will be 1 or -1. + void changeOption(S32 delta); + + /// Performs a click on the current slider control. The x position is used to + /// determine if the left or right arrow were clicked, or if it landed somewhere on the sliderbar. + /// If one was clicked, the option will be changed. If neither was clicked, the option is unaffected. + /// This method should only be called when there is an actively selected control. + /// + /// \param xPos The x position of the the click, relative to the control. + void clickSlider(S32 xPos); + + void clickKeybind(S32 xPos); + +private: + bool mCallbackOnInputs; + bool mConsumeKeyInputEvents; +}; + +#endif diff --git a/Templates/BaseGame/game/data/UI/guis/NetGraphGui.asset.taml b/Templates/BaseGame/game/data/UI/guis/NetGraphGui.asset.taml new file mode 100644 index 000000000..c73e44804 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/guis/NetGraphGui.asset.taml @@ -0,0 +1,4 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo.png b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e31d42a688a7e560b17237ff60edbf9c0c00dc4d GIT binary patch literal 9063 zcmbVSg;!MF*B+!(U;wG1yOHi1kf9k$L`uK`=0%Wh5QdU&q*J)vzMy{GoxC-!;v6QQH^iV%+)4*&oVLR7&}006BG^&W|Xg?ipui(#V@tas|K zz<|I1uH25|MAR2tCskt?001BO??wZpXHud*V!J{#m9aO_Ffc?xA)nqf000aC2v|Yi zbLqrXDwamw{b|rk&FJ_lT(I!cRi%LfiBf(M(}V ztf4@qo#z7JZ-Fmr&~*br$AR6fwYr!;cTFM8W5NGn`@PXSKCJSup`RVQL_-KypH}J3 z?w6mEYiswf&-#OHE5<~ErxN< zw`n4cQB&-@dTv`sq=Y;X;6=iVoJ>vsdx%?*wnNhV;vTjTfHJi*#!p*^{G`0!VtyAduJ zh6XK_4Z6OAd_IC1o?IGwUA9_BLSNImdS>Z=VkBYb zYF+Qy5wxj3~dOq05M;>3B;arFkVlp6XaT(VVdQYlUUH!F= zqlvd*jNlgpp<>x>ow7rdr4zQu3du`qk0G%KTFNgts=Jtx=VqoV=g6u8@wKJIz1}Xx;dXLRf+QGg~7jj<^VzokQ#*f>>&AN!o zc!MB5i`S;CQLx{t0CP=zBPrcUo}ty0|K*u?Yx~l9ln;@ov7_HUa*r1NcD5)er`bdi zXlBc(Cy8W+-BUc#kh?h@)wjrfoZD(G3>{YSG-d3IO!J#A>Wr{Tv<&id(VrT^VV0!x ziK>$pm?0ME%{f;*)8#P;!jqWh7%q6uwMWf{8ysGbnF~tL0I^;OZ?eP+n+;<1RKw_S z8NGE$omELfvqHw+`U&ASyGP&evLm$RkDe_66_5A7_}L4vT@9fdf4Eq5k(g<3eBtNR z5lKMbqo6_E-7#*d&iKWnwrx!H+C}CsUEMX|iWw z5;JE}-Om8Btq^Y$3==g@cIfal@rgHuB`ImWyCk|3N717o*N@-zdD_6BKg36c4M&nJ z1?PBkU;5JZg@b^lS5EXClSRy5hBe)rP4)&xzR1Qy>DWO?rYWDG4cA>6#=en!%B15R zKD&DGh63EIkTf{ldPhSZYTFy9DrK8v+JvC0k8snQC5KlWKPC;orP1~)N?FkOF9*7stZeaPg9trjlP7oU;-4k46(!$M^I^a zGN%sOcAJ@T(l5rlc+(N*5AvXWQgl*4+#)UBKM~hCzL~84LRgf9O?5M-0N9*$<;M$- zf2jdU;-uaLSxIDifqmH3i;vAPIKqmJVM`>NhlOa)BsS-7Sawqe(6hpnTy%l~2SHIKB zrHty^)J6W+Z5R=i$lzvVZBxu$ddYPb#vFDkrc_SOm;_0N-UtIfL&A;iCv!*9TLmuZ z!d_BQ75vO5Mnag%+akhRO}t|x+e_c>>pX-?Z^H?V>oq_#JIChoU8i5`YGW8&9P5&t z*$@Zc0tz1Jq-bXnv*W%@-eQ$WdL*odC+ZnOJ&vS0^zZTqt@rnJUSVausq|@~ua;LC z;N;#D&^k??sB3t)#0+nrj?1bA#z)Pnh;70RyPbOdm~Od6A--;6C1PQp|9TsGA`38Z z6QD5%4Ep>thQ12USqgS+WUcOg0=ASF$6w-`%HWn>Z6k=!Afc`8WJULAg^tC1 zjFg_L#lyi5_6v1HR`uVkqn;%M1c~0!2$A6GG!dwzgZF1_3_f6f~hGS(@@*9JfO-e=oD$Y`b8mpiXeA^Rzpfc%b@D40o z$HkR-c`CZd*OJFkD2V7#8K@h-?!ow-1v64ffPXWCJGS@>KdYG-_{|b_eeN)kCT)<7LLpotFExil}{Gt3(+3GH$ahMbsw36A5l-*w}f;ed@XT#3N zo!;lGdnBALJhB6dLs;4Zc?MDxh#Ef4BKiI-b>(!|xjA`!ddu1qoMs~K%71DV92y^U z>~CrQZIXDwth>2vx=YgB6>kF(!6y<$_V7YBO5zultB+!MIwM@Y_1hEQKCY5E&X2Hw zLu6`rYE-_SGAON1^g?fV_=~QV_z-J3M+{I)1p+#AYO5>|ED?h%Yw6%Rm$7XakM2+4 zwdN1?s|774&RYv{KEjzKZ=iovkR zNo|HPKKqgJjfU}r%hNS?$NaO&{3*k*xA;OpVZ8F=a30t1;pSLLvlM&?#ah%GIc^-ZhO2>6pIgh&>1wL;k*zM8E zt-jhIHY*Dbzp2C|Fq%1!N-M zw>=Q0GGm9{f{!umG=e%z7&uTt7Lq$uibVn;yjhwyfm%Z1Rs;icNNBe*l=X?cw)6{< zn9n*Aq1in?Sv~NV&J@a@JlOVo0WTfgn$9qg@o^@=YZ>JOw>G8DiQh`}pbXI4ep7AuqJK5;K?3$ANA17>@N&AE>KvEDltp z?e0?Rizm*15z>s>GG@dShFkHa>Lm~zewLK_$O<6|xf3xunVYs7^AG=RH_^B}zW3iP zZp`Tyo`oL>eTcPHAK67gecz$=CHlp5UV9FA!eb6!t}|Qr~ekiQ7Z>#PDrd zuQ-?i+Ex^LqG;@34KvYW9L6`gi4NiCvJ6X0=3~{`2x1|dy{_j{g~yBgU2C1O0j>8@ z>%4n`e%89ALVHRWVdSeU**lab-YL&wMM5<_J5Ubxg2<3GI(-@~6&*ag07|!}rnSJ` zAtsa`2bJYSUNU|!Fu{(lyB#;~^$D^@VohZBQ4CLBx#8V%lRtVt$R5o`7ehd%N}pFd z))KIZ<``F+*qmUgP0jVMd72BP>!z~x`HC`s=!$E{uQDbn0pwD4X$6LLuGBqk8MfA> zl37rWgDO>}8rk}dE^6>Efs5oy^)H@FJ&z%6{1HAV6&o>&;hvTmQ6+seUT${c(l}~w zJ)a#DHj8X}t+tp7eNxpDAPf@@&T_Z|tF@T-=p@9%#Tb@SDsoL6W;DB(D?q*;YK;5f za0pL2N=vGHMrqoP}O^5w*>KKtzJ>Um~rT>^u}1YXS@d#9($rdkuG z|GD94=s=e$c=^H8Lh-~W?CP`RtwsM34v?`=_Uf9&2)Z#dM@Is~e!_J1!_~m~$W|oH z&?8ldAn$^^K19EwmrT5zCg@K)1>cqEqQlx*e-nLar_*nYup(>kaYm|PZ*o5hq$IE6 zoR_Y3Xfa^_)C%&{Sf|-+6i!McAAHqqJuk+)Vi;%i@IG{TbTnd{%ph55R&PxyN4Htq z=X&bHEA+L+PSwE3uqC_5*9$u5Kv)b1ik0uMX%G&d-5tD19pz}tdUkpS?BkYsbtGaqnFo| zQ3Od@pRqE)&zH>SFOaAswiO8HjLhAOf8G30jP4J!$!E(X=@y?LiA2-z`PJ*|CKnO0 zMbRi^!MdmZrw;b>Gm);FSB+%7@}qGYqGzr0tBK-J^~zeLRRww{c1_;z-^JrQkLhE5 z0>r+uma3EKd)cXFRyG5#u?=nk-6?xUd?>Nh8}&=GHt14*)^?(1vrMDLVXon;^p=OT zp%~rw`O9cE1;3LsP}KlU%C4Nw3U<*yjFcX|@h|&OIi!W7n@9CG^j(;yr(=B%`s+y; zkp*ATPK}YbpI%XCDb`i=5;n@iug3e~fOba|xa*RE2{kJ&5Nw3xaD7N6eC($>@N!Io zx%RI_CpmvBU?!2~qtq2*DwFio&sfwrWL-zAIl0`%=iHTk#onr!!{M+V2pg*t#)57ByK?6s$%S zFl8-`82f^jyuQpxu^{f&EU?{Ki{47~t)M1JuyBN9K2{?I$y;h zbj&rTU*|e!vZLCRMAfkC-S~Op*0rlmS?eU5c#E`q9s^Q+nApqnYN9i1#$af*mPI=Wja?<+8(QC-msXvE$4M7-s%XvH&n$$H_}^)d6N z*)Sr1Pl1IkfA`+I=gJ)$##iLORdh7PBE{{9kHgq#S)A!;Z~{fE)|4aWmTa;_o0*=wr|R-Pj{u!0m1-Uc4uC`&gFbKeL5ATvMv}9Vr1^ z22$Wf;;+A7T47NayuK~^yvnIICYoNk_kL4sk^^W4&$5{-waL40!OeCH0+B;KSR`Td ze_jCiwm6ibE^W9Ao_SpAYN{>!w+~$=qm^s3FCv$&7(NY!1GiSk?V?I^#>mOCZO+*t z%|ZgpnCJT-dYfUehldnyZgsFp)qfi4wQ_;}=(RNXP#mqfj9np4r#Z%gh2u`*{Id7B z6gZOmzeVidGsKVl3HNgeUe)V{+bCz&(Sdl=?{mgM9>TNN zqN-lWG%UT`(gLZ=x|g<0q4*ZU>DYa)NIxQ?6K&|8q_(cp_1*MtOjKlr(3}p7b6t37 z99}DfpI?5zGTrfh!&-OTY6XtpG{mWZe=ennQz7qZHiU1t>}*t9&?a+PLgk#)evvid z=@cM??Sw0(LA_x3PyFfmWc(52)9<5vXG>!PLTF2OYm zi6PsC>=^XtjhZHlUc6Jqn78){yO+}DMw-dR4P|h~KBJYdBPQuSXE=-$BxgU9cj7RA zNKgg%14H-)$#s;i=p$86;RH6$+PaY*RS);~`2J0453D-kh+EEnx<+2jE*^ldmc0)k z{)ybi;`E&a$@@b;3dR5W+N*c-GDp6Wnzxayx&R>vMOS;Ay0cW*+R(Do(b+H|fOhYr z11G6I2h9iWjkS4zEL$zR#z#f`VT{M)^bl{G{FDCI?8D5EUAjl1!>!{p=+I#7WS1JJ zoU&UL$~QH&>Ddzzypv2fH)rsC==l@A?a*7~yLzK$!_OJNW<(A5Pb?o}>g=V;(;ok! zFfu8$wF1{=*Kk=6uljj^GhGAxBu%QHz$OV3LYm_>Y-{i*tld?L=g|OiI1q*EwQHJ# zF?O2Nji!BtYmR7AJTG>=O?G_UAUH2RiW2E54mXA#RQ+3sp_@76LFXDA`I8Q>^*6g3 zHY7Eb3yJA``yWFi&Ps6^iVygh-K^7;0yd$1GUGj0tgZhb$f#da6d)-yxxWcu^3XV~ zgJ<`Imo$Zn(dZ#G9?y<#mD|@o1SWQbD-k5c<+t6uWyFB-9s{r7^2=mBrq>-U;}#XB zsgGG&z~a|yp_5EOg5UDaHa{$uE3rvx=l@jZ-7~edVMi?VtrGSf?Q@M#r||V$`h2a# zd1yywx}DjdQoXAD54(O7o~e_=&G_9>z2}7or@&DLKN_ARdymhyM|4FQ`s&?E*SjSj z``lI+;2;T!W;Rg=mefW59+VH>W{5gy!%@3&$MYW`aEBQk+#S-X+Df>6DGhxhFFwL9 z7C+|_)p#>|IJG=mV+{4H8)n%t3smYl&=`Lq>$h#~eQ)V9OSn%(0oTgVAJOpi<6-|g z1IXMpFbFw)pcpYB^u~gHes7sb5t#F_sosPqpSvE(TwJK<)^g&&9OhA~=Ydsf#qN9P zQ9V)u&#E^p)-$V3K%lnx@%#1YiT!f=ADn(JmAc9l!sM?NuQXGNNm&}Gd@7T&%F=6m z1&-(fn~Z_kimqjP^p={vsfBxH37RW@A4yXW0^d1u&C5JApbg}`wQ4!PnqpDH(S>kZ zvN1J^sBxa^s>}v$A^SPw0fEtIyZg9r5W)L2Yp{MG(;W)}go^R%^ z{kL(NT}u-9$Bn=o`n#GrwFlGo#CaCoBeMN{F-nrN=S*Q$dc-td%W*G_-4+v4Ij_bV z(EPUbg)ZJ+;*kuGR+5?FZCjZp|3jd0x@A+En2*ssb8e{Da@URlo)chL;!5t?BbB=W znb;2r(ZfpboG~)v}KVa&;2@T=KJ@rja{jOeJ#bHH9n}pQFtSl{^E>GyF_u-**t!-A-*aHxuevQ^9se zq>g(=Ju53DBS7%CGOLZ7K#3SO*qd;7Am*hH3avnU7|g;AEFCC1x@xMdm{ms;MEK<^ z@jKX(yOQm*I(H#`pIh1CkvJ1~Iz>ci z%lK)4Ioe=v7n&QYsAa%YmMlNu5i?K@`y6(4rW7mpmmUy+ah?Nq?c$Jom_{9rFuRLs zY5xY;_;#I1ALA`Nyxq?g0xnN~WQ%|+8@RWMw0-_`7DGNQ`&DvP^9}|-y8miVJXDQr zw5^;ht~efLYvC#t>yj*`2Rw>>D8I>-0hx0KbVV!!_nIsn9Y0o2tfSWmm59lqV2(%; z;mgK%*rxLD<~*ha;VVhga7Qz^+OEQ9jMk$~`tx!8RqDkXaz%Z=o-Ycp zfiG3fk%|Bf=wV4q7#)zYxVuN$M{l*P<80W7frx=q6{Cv7ZQA>*76>v!&${;sQ!Mig3y{@y>^rKo;o|5i}w@HE8zWm zOX&Je;qe|8IczZKzppbAMGvC(bz=IbG*)ds6-cPOxH0mX;RLk;zur_ zH>(V!uH(&D(01~Lya^xFf~Y<Y+i=DL= zp&6J}5Ce<)Zna)Iv$kS`RO+h?j`*Lx%Lpf&(46JPPR68CqZ-T^QW|H)9iAcM)lre}l62c>S=tkK_}^ zM&i%q=Lf&%@W9?V7LKz{_(2W;ZW6PG!G6Z6$+9+7D6sF(=f(|1R#X zh#g8yM`5LDcv4&s!RG56<9Z^G#gKSbUvHRn7wk5H3A(ua4UKq=Tss=vvJNrnj~lzb zFX?lK?+q*Ba`M~VtQZY?^zN}_{kH0Dvbz^VSs^wC`$lhi3Ix)8dhghk=+2%s8ShXW zNAH_pl7Q^W*0if&u|?;28M#~A`fepSjHDhFt{pn;l;D+z)Sul1Klr$<*Aa~I_G*55 zgo|Rz1m?~`YSJsctLH@|54g+IwaRKLex0j`hkB=@tQ*d!pk3)eLeC`TY0Eku{>UU} z5@?6SGHHc@Xm%U&{@Ja~_x9AH7LRnCX+Cbn_0hT`n(v}5SDI+J6L^;D){lI}?@XX> z%ToT*yhl+aUyHzw~jmDYEzVq7ti^85(2;0PJ^{M1Ya2$tfu{vz4 zQf14~YoMN9+*k`sZ?-#)!!&nWq6HbjZxBt}M+Mway|0`2$M1;9cUuw}+7x58nWT&H zqJvizIwYP8Q4LDd2%Wq%V^m5%O}$?Z>#brnoTg-18h=@f=1zcW`^J6k~CW! zDJ8m1H8z%Z!dRIM)vs9<+-*`5Rfsa`WiNBR0ZVZX%VIM52iAQrdyIc%01l~4y~FL4lM$djsS0VI zaqE3?(x^-Hu5~irzu&Jt$gW-SM<(H40=bPc8vljP`y~^Wjdor1a$(xg=;WJr#Ww|Q zKT4&vU^W7jMOYF&UY{~7sN6w%AES49*)nu)^pHp^6u-emS2LnwxZ;%dzdNdgf4qm# zz#b>s{;1F*1YN^dj{gx8(jq=b7AB}xaJq3Mz7#Tmu3P-C=;aXKP#Jqlr1VI|=?W0* zf20HfGW7>^ptz4Cs3)!aSH#}>XFP#LK}v#9O9pJyj}lHQIG(ht`k0}+7u|4d_&z27V?|J6u$syq>QT>~2$PKPCZjk7!IoG* z4Bq-n5E?YOgHcW}x5hsfh9%JoyD*EXhz$rSm}SqUeq!^#P73Lp&i2|B7ah%=23nid zp+t^)jHudDP=o+UtN-;3i`gi@%_ZIYS;pWz=zleR12>s%2(Y2r-g)KfL8kf{+!TXh zkHUujSC)v1#FX#W(q;gqD-Bn;y0kG#s};Oa5S1OJP82WW|Cv|{KhXL$+`!gT_ literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_alt.png b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_alt.png new file mode 100644 index 0000000000000000000000000000000000000000..3836f1e7fc26b23ee299fa02570bbed343d2cb50 GIT binary patch literal 11616 zcmXY1bzD@>*Iq(W8bN86ZUI3;x;rJLVG$|m1%ag-B&AClM2V$YI+t!?X{2H4PG7$M z-hb|$J9lQzInSK=d}f|`A~n?&@Ng(_0001LZ!w=<=r&Sn zQUE}8j)kh!)zdefm7=y901!?H0K^aj01r>)Kyd)Ta36p|OaK79+X4VyjW!Pe`JM*j zvXzn1)coY+?&S8#$(c?`MuyJW)#;*(tk24F-E^gfG4K@q0|oBEluqp_QV%&)U!P^y#YkSugyqHz+* zOY-v<5_BV(q)p3HiS29i{6bq-&}zeNINM z+81(z#lNNa`t>!BwYm9CFd_f0wYkCf?v4(L7xcv+;T?3}$2zK<@Bv*l8jru38`+*f z#&%XTbOQizp8&=sMwwjlyML;raF;W1*Kzvj?rGs_4bZf({p`-IE~iTe=I0jR=6(J8 z+%*pX;P6zEmD2SxJup%EX|3RK(ID};;qIc{tbGM?R3~BHzuWPKRcwGRg~5Y4lA4)@ z5FetDowDclJe)G1k8zt{D#eO6&wIMO?q_j#Y)I$AORemiQ`)Zei{_sd0{zJF$UCC3J>lq4Y` zIy#C}M@T@VuPd<*epeC^*?$#uZ&A%Y2n$|acdgcFP?`9h3=|AGjsJD39YPe%d@b2Z zUG}|&|A{_78WXRs;)DN6g- z90#*(ryfP^WtC0noDFTOkag{!om)ENgbswf;e`>%wX}I;`^$N%9G;^D`1|>D$TE+dCQ~s+M1(ca;Yc=f2o(cR(2T zLY0FO4?&#f`4tDr34P|p`RT1PwnP3MAv8KnodV}+jx?|WBIbSEg;OZjI&2NkY?_n) z-nIq*jbA`!z||XGXi>?zRk|n8fe4+cgVNapg>5OeIxL{?k+hzxZXa5 z9f?P-tlZ^X;pa;wgmq#qy05Fb**P@#J@eOTFZk??IVnl_iST>rA;~(Z>U@7Oypu?2 z5At{x*xe47t9V@lhUz2{4P^=ykH?-9K5X`|>{*niBUeeKOs`h_{|0Z5=E7cPDBYf3 znfa{`r}J-1#;`oD_MET=yrT#-NM_)C%>l9c_K)|A*ao+g5o zISALIbSF6JJOp`aN@JFR{B(qr=)c5~*A5$t{&D5`FW--+vCRZuW4rn4F@ z*dcA*v$r06(&fa9%@t26y8h4EPwmJxJ^2kt^%<~;x@bwF=)8kBgev`ek~+8;D=wDF zm-E?OVLc=vyORG|CuC12_trgTO1_pXQ8N&WznJz3cTXJ(zrB^fNR2S|y%1GG^DPE) z#vt#AM@v)UaSTVu70QIZ>bV#$sKk^{ds|oaE>Ryx`}fM6#g+{|PZn1Cg0Tl1^sZ1{ zUidr>1B$lnK7LQXL`L;a0w&a$ZO<9BaV`a>qtmbLZaPAjl(ZBd;BjutQ=gFq@9=zj z4P*~~V|`+l8B($j6b@B}3q2UT^p@)(J??MSY z_?c3P9_PFh^TOCF_|ve0o+@={!GRonmTaay-eg#D8WDyMHe<|h3XyK`G~Q8B0p^pe z`-GpFt^T&ofa5C&&Tk)&(r)w*3u7=1;G=IT%PXn_`*v+A`G((kD~7o>WCjJb;A=jSZOgq?au8DT&XkFm2(;P$&bGS-cI z8akj7ha#2yT!-w0`y5=%-zzE!*&ME{O70?Sh^!V3S#-m?_-rnYX+c|u17(tIb+3A+ z_bYHCps1cFeHRvr^0%8T#?l_OXWm*~I{n-iuwbbV-+-b<(?m&LgrLGAzI?1qor}mr z=4_-xNUmGls6be~n_t^Rws`%msX1J`R7GR9Pb^o;G{bjQ>8 zr#FiOY~wZ=1NfJ9?eUUCr`h!Dgzp>B5$Ts9(qlDpuXYgd`mAl`oZV>TG#+n-s`3HBYn_j7;QQXn&%rhX%ClTgiR${ak zC=1!7U9F>=xr6XM1dT6D)Q3_IcB0Z;#WqY_9f?XgjCA4L_rOoHEo{PErwuCRl`Bz8*aG1u5K@nEABJ5Wq`F2-0qL|)Z4ItuI4c=xlXcNUd(D` zF2=TL+%P0&{_T3gd3gdG^RG$Nj``o8@g@s;QH5hRlz$gNn7vk4M$lJ|gjD4=hXt5| z+OABW=3aC1UQ$`57@hYep z$c#S>v7Uo3Tf^eBc?PHS2{uAlf0;a5uXM7swb~rX0UPw&s;@f2B3DV*#v!o;sf^8r z(a3X{e6>@mBlA<*E#R@&ai${hxnU_D%JJEbS=y!)sysje>g%^$JVSWw1rH*T$mS&m zqUkvWJs41MVTD!a*e5<=7MpiTgZ}zOF5DH^3Xx$BNO(RoIAZ4h*b^z zQg0y@Af4K8e7Xu^z&gqgJzoC466>j^K|T@M64ID&K3n}PuD{=qX;U=PaZMVm-iY7` zI9KPXgfysmN60?q*;XYavySC^kF|yMtqt19db>~&1((4Wc11UEteok z?pK5WkuUJwQd54LcNHv)lSb%W>D*YCYpT7HswYjgEGF!hQS{u&b*oxG@`gC4i$Dm? zX?6L+QW|vi{p)egO_BulGP)&u6;E$^Ghg8Qb~+PCY?CSUHRg zT8rr`C+?p@k>8yRWx9+$P{LR#3^THFOVS0PQ|;Wm$)N2h)nh>Fbp{}-jzhXy%=~GO z?^wqDahISz$XMD`-gxwK$lojc;C?AA@>u$6M|B+pgY*?W9XEIp&_QN(u}13=VuZ!J zPXtFY2V(DqqS^E?f0iFR_pEk}3PK2nst6B!veS`nSN@-)7Ka zG*oko=AGl-5A$m_tGP*?Z%v?c_PS7uC ztjQU$4khrAf+mIl8&rgpGcLi zHtSOR^R&V9vvu{kxoW#Ryt|vm4%yU}Rbb;`{CjzW`7=bp$A?_!!o5x(d_9``&6`fR z;wB|u;jrFVu(_|Ie#KV!?4h}!7;WPG09MzeD`pdkY;)b&X>j+^sphZm4<@i#y3iOD zCkyX#Ue1eTHc?Ta6DmwAk$o%ZbNtF)+`=XE>R*zU3OelF?z|6D|s{P59eWGv5`Q=G7Y|&YPH&Xi_lh@e-hH(%RrOm5P?WPmY5E9pm!pd#oKFtNo3^^lOk7-IBd3KU>V zu1E?$ZMq$xr!i6?AZ6un9Gm^Ze&K1qwM{_vN;ECbEt*7vs0Sd`5ei6HBBu(u!cKjD zV?ww?f}$Su=i3YmbA21n@WI~%PK)0nBKfIL6blwA2KxCOwT^_O$N?xky5@pYH7dp| zHPTwrd~K)ey>7+l)PggGO49LLx$joS6?XQu&=#l_#PQ*_0xDwAS`p?Ff^Xuc`tS>b z`i^?{UF+1_KZox_iC-QLOyRccj#fHqh$0|9W6RN2TGUGdgAzazW+HrR7mJgO&7w`m z;N;HHx|uo?@n;@unyF-|70-Cp(-0(i6%>?RUwn4v=K8A6z49c6lQc!$DW`qA-#vS! z-UHApWfbmMFVNVE!7*vSXvLX9>MFrUoeBwOc5}}=S(5HQF#qlfwsn065v$E0Sz42E z5ceSDdJ`LweNES(f*J4l=NSF%+XQ_5+K_4#-jMjrvFlP1uWD>Tk$e8PatvK`ZsE3qWCpLe1PM7Z}<)g%9&Ed)?q-qwX+5ci{#S;iPc=< zi|f-cBWRXt-u}dR%`VpOP8n#G*0)~gW&~^ zP5%%UO+;IyIwDirOFZr3JwPl1w z!@#*S{Cc*Phc>LdEy*|0C}-MUozm z3itTbKngzT{h}#6xoW+vjSyPUwu-y)01i8Bs=vCA&@>l>iD}~+#EU-@z7xRU03K)< z`StO}EA7?(6w6*ean4t-j18j8=O*NxeRGyjhHVwwDjADUlCh68PX@KohA_2W>F$#T zTI(PD~6(vy><=oZK>TTFO)L zCxb5JxJf!P64}Yr6pE>?I>(HF$p_dB>r+2+GlI0V0N(sxq*J8-8__u)<(!Su6K$Ze?^I9ZdoDNZsj?FA1p+Kj8<;C zbE)F-xFHQbSYp;1JMyteKjL6-(Qtuzj^c-rB7`K2Hdg329}Eaqa3=i2%OBSGQh38@W^?Tt+N zltfEn#&ZfoS`%ve^R7F5(Q4R2mO6Isql_rD=F?xwxF39}i1*y`yjqrh%k*^$d$*>9-T00tpXuK3 zlq6ZO!6;;N&)#o2!6P!F0zV(EhY3Eqr3qOc6=q3LO5w6}y)cVHa!$CoqkoLFE3j@p z#(7u*H4t>-B0}>`%pk65aXX{5>UAy^a@b>O%Iz(Wa-XM}1Ch?OJMBkvUt(j)$A#fD zCrnEdlh$IgB?;6iFB?cJtcUyZJ|`Tl|7?6RVoD+EnP)Rkwy zc=A?#NvFT+3(+nWWvW9G#Mo_NM#AsyE^T$pD**|J`_Crznyee?+>mfZD8IL%X}GD| z;`NLwm=5A=d=;*5T6glb6|-3p-yfDrnFRWx21>o4=M&Bv4;MoiL<2nNJyI*U#oUsz z)fz~(U1K0eDrt6&+NQE0NLO)zO;FO=JM}wHi6dakq5^T1>eXc3f?u_D`sXhXMO3nw zx=+-MtSeoUioVGOhRI&bMD@35H}^)tgB(|WhVLbdARD)7HX@~f$mREHM5WP4)zO!y z$3}L%yG8lUb4BKqkv)Uw7^2@TaoA>6!Fgxx7)GdJUt8_S*E-jTi5yn}{8_vdW2TO7RI{tVI&@hSWw`ZU^fV4rGh8k(3rKsJT)IM)s{J@h>o z)vAm>mVCZ4U*m)}`qHLFTZ!O+zQ0j5HGM}}4ot__N*DC3daYL~f$}u~5qHRPu$Zbd zly<>oRL^4mnQxFQ_bjkWW_eT7n7|(oRC0dV^xe>m=8dqXy0I`wjSrE&^@1GX(yrOG zCED**41Y=UY9=GAYY?L}@OBjUg1`#ofLkk$ihFeJD+F1mhBMNd(H&7_LfGkUd^6*7 zuKlW-?cHeLv5IWH;g&i!UzCTg;q!W|uQN4zP&Y2ypy&2V=R*;;X+B->R>$yiHh^>G%=JiFX4}-S|JJxW>XW6 z;_nT`hqPTcI%;BHc91SawMtL{8yy8wXm>*obe?x^YwX_fH$l)C#F? zdE~2m5UPWaCtK%{LCs99;sP7SN_|hvMDe`1~#VrxkcsM3^6B1}ZR&d>y$BD_zEY zA`A6)Nkkj6O^hJ~I1r=5LwXmk$`y@Gs^o2vLGlyPnTKe86?+!$1`}B5W1A|}X{Y<7 zJJ!)xfW3<-G(; zGAupOhqctSv6?V~o-R2lz%~r=gekL7`)^x zKfUfUcf9tz&7Kcn^snSX3z0b`FU#G}!r|51sj^mFEy7*%_El_V0HUKD+5`|?uVhY+OlS6zgk{KVqzJK;Y@l!>TXc(_>j zvX|F?_K2G2?T*qn>r8A?WfRQRsnU7S-i(rEk59J14qdfnQWut8PZ9oRgr1DDm7cVWJ6vl44#$ zEEjtAENUe5$Sc5Q%`>mJIR(*Msb|e`XB&&*^q8>V{1_Cf%EK51&}#$cKl5(h)(;tJ z;^X)|3a)yJ%P@+YZohFel1;e*{0W7I=oEd-DmMKu4z?Engg4gaNpB~xmG!3}(Ggc6 zrYUouvtDzyDGm1pcfh%{!~U<&|1ow`HtseISZ1x9d_h@;dyI;7q6~)Nha5%o-y0f; zvMWsm2+?QnOFPL%PrfF|#a?(vasH;ne9jUhoiJt|3J-Af$0Ndphh{x~AUP>*BSicR zcD6ddax7R-(AsQq60PtCt%HGxCHIdmv_z}#oIk;7hk7#&R@)=b33o00ohbGH8g6_8 z!kC-O2g{nV=2(6Nn~(|14UB$_vp;nvj4qFhUlBHycHqEiv!cweDXSPr(WL&EjjVFQ z=>H*VBxEkjSe=k%?;D=5{Acgo3)wFeYn`3j3@u~`YVdCQohPu}{-h4gyUc*Dg%`u% zbg?Hme|e$W^Mkh&Km4#yDk!A>+j#iIO!Y6GnRXS7*`uuHIgrclK0}H9bBN1kPq%`; z5p^c@H5bS<0~88}TWgf!3(O@($vOBC;u0-=b^h@qzD5iKlZu1Ckoq?7@$>JyaPg-6 z^lHD9-`*^u)Evmbp!0bz$!)D~Z(Ej%ccR;74N@3Ixp4Lv_09T`)@en=4OW#;*M5Bo zNg&I9cv0}tY0+LgM$qbHpo%(j?tCVeYFmI*fU_>*P+pmnErUMtag-bXcR#ih1n|&U zU6zjg_RBz!<{+VB`NzJ>Q10B2r~%VjvR{NR)rTFU$|KOwL__2!SH!q=`A7w!nCt2~ zzo0k|U7l>XpW5a1PS5*rd%tOOTyo|%SGa|#QtTO)@YI5CUc{f`N!gNfYNBO!plZ?B zk)*`Vu6>e**plgdO*uPs>Ow*dQ5Mp_wwCrOZQOrFxshtMuNPC)K3kjyNV^>-LLWQ- zu~5T5PX+Wtg4>3SKVBRhI(WhKF1A|B3OQv{N-YiMjhLAU%i8=LMOx(>v9qQZ1^g^k z56b;u7xH#Gau7C9J?64EP1vs~p0Gr(jt~an@yn58+Ec7aU3tD&@ETmJ{hN(OYEoQg zwy+}OKFDRp0!wRCuEXx+{9PO`Zi&QCIO6ZO-0ZF0cN6b7r=DlVAjuUpz$oa!qT=;x zU?-KLI>*8Tj^UKW@Nn}3Df`_NR{i1 zMtWhB`=5AGJn&`}z1+u7M)WYv9{Gy_sbzpo84l5s2o!a_@T36<75%xdp!Ix#2*u>E zFrJ#Q?^?5d3l(@gB=~blb?%(vt5d9BE{L2`$(a!4ijS>CoeC;M?q@S{Hs#V!#ShYy~&$DpKaxmX^;K`J!;>3YZ>b5#lht4FNRxtT%fB?;!Ed? zJS>fdz$&Q?SW&ZkKXf@`5Q4>d01gg=^)Ts5b*#{CG~OduN3cY zw=dD<(aqGLF^X+%C$9P^nxKFu+C`Qj;JHG41Uu;xGLkH%iJs^re=>Q#E$WrL=Z|=q zm2CC~Iq;p%=EV%nY^+vDI84mLck6ai;r7LUYNziM=v56eAWx*Lp|#3A+=3DKf^&im zB0So=dpX6o)kfu=ny3`gpwf@Y!w1bW#DVN8Jn4*n$N|!QHVAi%6Se4V%pi=C-Zazh zrfSa`tpCa;QCHFVTndD|rJAC`JkjAzz5Ev$sT@Fw=Bt%#ZEaXlRX&cayS&Js<2%h2 zW+DcqZI`<{FfCS6n1ZP2US|tnD!=j zvw~>tLvF#tL0NT!6fV1;1Oa`%Q~ z=70;WY~dtQm^q;~k^lbc)cgHxp-YT_g@4X#3hm_D2Z^7 z!(R?$NJAMi!Fz(*?hWNVFO_KjMU90Ti4}jAv%)!KOSIegvvzn?wg&pfi8z4}n`4-H z54z9!Jwo%JI?GPM{5lz9zGi_lQh`9odM1kcv);r343_<)I>BJGFjXL`8Sa%=n4>maRu2ECqmv{AAinZFCn%HNNIg$L z@ES(;7@h&v*oCb33s+D+@Q>za{^J=ru~xkR!Ut$S3UjC_lLUG}3Ov}2=SKYpb}1-C z^#3173zm7iy5}5e9%F8F<_oBO3Lj6>(&;V!@&u9X|2N^p(sYNSDd6c!)h4p18JYeN z7hbSpbDLUbTgn}d%>AEJ-?31IFvBTzGWhyWid@x}P2+8eWW4u4X~|8IE9cbTkFfQ2 z_5Q^xjvi*17NIJLJGQnXzf5!QGe7Y81b;q`|$Du(7IDj$!*Ei!~-`72!frH><~_`|Yc|4bSZz2t(? zm;G_g+lfw&?*p;WXpZ4vBpn;pq+$yaG5pgX(x6l1cb{&497vGlWA+z>e=dQh-}Tau zsS=j`151?+wI~Arc;x9q&`g^FR;CV5pX`?zCVo=>*-8RDO@Kl6$p>Y#LFrYm_H8hT z1qnxN1#7smHM;LfDF3A&JPMGgPUzvDl5C~FwP$=pfQV|kEtC5!1IDqThkd}1KmSif zxGQh&6&5=>T&EP9GGFhKT~tFaWDink1iI2Bnqd2u_*_PL{PV|vup<%VwzdC3Xk}EJ zb&z5orkM*-k2S1m(D+&8^pv4#(&&=rVXiZ*-UVnQq@C#lzi#lfO#7^d1kanrv$n77 zsQ--czFhNt|I0hd^xu%Wksafa%unv6G73M-uQ;m}{i`Jl`I2?p0UI3PP{u}mYPA|I z`EKGu##I_@&G2dE3**JV*h(n^C-|&=cR7AcdK{{RYoqym5&rT2GFprHusRt1Guii$-4n literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_shortcut.png b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_shortcut.png new file mode 100644 index 0000000000000000000000000000000000000000..d993d4893f9112747e2099c1f111877db4064a86 GIT binary patch literal 10728 zcmZ8nWmFqov<=0zxJz*;6nB^4E`dUeyG!w+#a#jvDeggwyF+mZ?p}(!6@BUV-mkZ^ zlF7O=*N)9O`|e0}RXI#FQZxVnfTb1))(4+ecc(+DD>mF4GBVHs{h7#&{7tjU(Pe!Z&5X{q|SV z(+Fuwe!n#qKj>Zl3NDZdt_UrkIzX1qPTkR1>hnATqNkzzaXq`<`6o zOvll+_gvXkg?^59?W6m|lHFNd=W}Jp?Q#^hR3AVB1VY3>3hpsZGY(PdHs&BcRUg@9 zfExpNVM`E7tnV(60^VN>8kOos+qdlJ)zq4C5M#(Cjlv7S8PE6S@B=CU0$QcIb~ueD z)VrVN_k*Q6^et=6{ylb~<60t`^n-*Dj+NkWP8Pu-a(Q7i>W(JRHEnm&{1h^;en6J-_zS4ABU%xYu|MTs zO8HA*!9fg%V~{>nHvh|=DB_xiS_FRS1L5IZXu_$m0-b=2E&rLsHw!??lTK$)DK&M7 zUddsarKu?gF)B@KkyMAzNXd~}9v->nLem$iVkR(*y_xa&NHlpbrPiMsNMRdN7KIKf7X{df*RJK^!(~t43Y-Tp?!LP z?GN2~ekWJ>YUIys3xUip>c@y_uPL~N&$uCzCkHzvbG6t2i0Deh;#F1q)W2z;@!Slw zn{5C5JhDr9T%s1{IyUaoCy(ryYGExh4f^V7l?T@pBQmqT z53wKI$q$1j}x5))pm&76`Mj|`jg*4NIq#*{I#4%zTv4`!?lJV%JX8on} z9B%a6QyvOPl}{K}buC5*x|#^IDrBS>pN=opEonJ!7KY1O`{GiSTCtuLyLwn8JpH6$oZd|?l6mrUgdiYE$*c^Qs=bz6s$V(9jT#GxH z;%Q3L$}{OOXr@I1zbSFerSx;=fJMG}QP(+lWec*0d_1714#&@1(fimp#m^gVr>5B@ zf^vr{Uk4}-!Jg5u%o!x+eEYOT(jdTzZLa?h?12t*ax`WGwCAefJRjZSEo1)Z(B zWix5t7C;CB85}?IK(q(zyi%X&G z4Cuw;Hzt7f;NRaFxT zVUkjk$i@DFx0R)umd@^ToGEg=Fg5~#OoT4-f58gjx4FxQML}A&NG=81c0{*u?msqX zyWPxfV62g?kBjLZKravK7GLEfoCndqAD(F;-4VX2&GjdCK~J4EkRz3~6evYQ zILJ_k$V64)M0zPz9C_;;h65LBo-!nv%Yr+vv?Z-b2y=wVn8-4FTb+T{e2kPa#6Br| z&R`t4=HBs3VO`ttk9stx_h22Ld1CxgE`wD7?(LDI2VW!Y(9lW+#8w*R=bNM0Q>|m? zgp03IgyEg>c@S=fC6It%5xYBM*Nj0Zdy=w;4pswhfmZp6;VG?O0#vFyYAF^hY<6Mq z9e;~L_Qzp}tr0IVVQ#QuazVSBqt}b(j)X7L(_MFDcO>amDAB9700D)i-%_U#VjGGj z#oK3|!!BRQ&6J56YS6|uXia=^oQ~4~87=tQrW6}R!QH+S1N2zZWcXf!klJ6hw3KKd zYB{NYI~68Su$}Ore0XKiVICH;(LfFGH?lzlQQGp+@sXpvMwFuSSw%!*|~!ohNn(vD%34$e4)63G7PQV>WRlW_Z*f3rc)}Y)C^{|jpqD|lX4;^OlZ_mHEaeRr0Yo< z$J$Vg?K-{-D zj(4XyStbmZ8ugHq1_|sWy`0zv&)Pc5t5vh1Aim`j7Cc z{LCalW3<)3Ro0)Jd2M*#@f|s#WLl@Bnb4AHh(TuwM{kjUR_sJwhgBZLf0TQ;t@Ap; z_Cs*SPSTjBHtJVoAibq+xy)it2FIr{N<(K()bx5(ziTa^$k+@n*KwDrTu3Y|e`A|1 zACT&3RWH>oLBD}Wfd}#t4-A+rT+!`2B&L1`Cv}$jLVGUSv2R^I)HAp*@9B=Xtkmso z$23{I^{8)KPsZ+L+4>-WJuSj4QLYfNroTq=J*sVc>eVC=WbP_o^RZMn9{KG0} z)T#ww0nUTXkUdk!(Wu}{k&`W-xDYvTVs?aEaijj1{X146lVhUKB6mp;NJquolFG+g z$!vakk6NV~!MC!S@=mB(9Tk{6z*y;w&H_&C(A?oNA)H}4Av?7{@}YkvUC{wm-GcoK z`x=74NP4oO)vI-35a_#cr>Y4biQcJ9(B!PnD3*Cf4n?N(;ZZFFQsQH;)faTW7yM2{ z5#Ke2vc^aWe=9`=W%Br*N;aTbfFm@QIh4{FOZWG%&B738@@g0%^J*%xx`dU(;P`QQ z(1ZX5Wx_ml{4>V8G`{z}Lp`AsaiHd}_VUQgEQQEI8odrwG|5Im`f(#acPvWwfi z8kB0yk=EoQl(Xa>&++eEEh#WZFk8P284jWs z9!8zpY!9>KMIU;+W+DLm5+T%zgC~qk8?zUn4H>%2u$K<;#ObJfR?)wS#LlN4e=32Z zGH2fY-7))m5ue#~uG5C-7RP#NHt35sVIo5t`6xKpnoZwh77L|rPtj!X?B^K%j6{{T z%B?&v!UFH@#Uf}@cfCFpAqAQ%Q1B2d^g5oG>^Sb2SvZgD&8g_I5d9g-#q%Mn*HESh zHbtUBQT$(bH%w-a9Umq9G_o+~jfCzrgX}-krrE|Zmpn+fg{~kFnH&BDXNV_?1xdGP zuqzg^1(QC#h&gm;T{xXi8zibYQfidHxGpEC^{GKc`(Z&5?bTtj(>upOoBA@&)D$Gm zs5}AW7dV`#FgyXjD;msaIK37?fz-wQNUvh8f=6-rg<72387my`+$C+4G1k{`3P z?GYNzAB+n0eSO?CY*RfDtZr)8O0F?=k6nTVi-GjzLroO3u~Xo^VFA*E*VPq8)RoUv zt_u0r9uhak^098eP%7D`+HwHlTw6Hmu5qjaw%q<#g5%_{>AE+6QPR#I7~-?gE?qZx zYQX7wGgKSEsxyWixhsjG-X6at%N#C0f>%I0{opMiGq~-&O7e)ddr{7j z&Gh%^;MU3@?Q?>IPhUcP+%3!(k&}6p*shKU+B%_+g@0nFxf|wWIltZ$AJ@?vFJIe4A`J_6NvyK`}VMdGsi!qmmsa=|5lrPAQ z__R8g=69%j${uWno_z}|e{ADw9EgMCOmAzxO=NeM*!!OdeTu@7=Gj!^JFAgc2Y*ad zs{C1Nh5>&IFTe8iw5ROQFl=eskL@d#r!QE57RpTq9*(a zLdldt{Ea=V1U4DPAm2Td$26njUgAVb-@gScnq9Gcf(angzAPx*h3W&9vv3-O&8g@x zEaNx?8*Ti4CW%7UxD(omn5&XQ7?=uykl&(JIcd)FGlzF3KIWD|4jm%*W#LxgB^k;iVtGhYk}rErN>}+2CVE( zQhcXnEKt^}R{$yaww%Y*mb|qb#nYz>RpwQ;5>S#yr@TFo9uRA=dG-1F7b1%U% zjbgr}1v9&vQfg8izGA{q>JV&Lkt*iuf2mZNE|NKSxB67|#+bZYQd81@S*6Z9JNKjn zuxNKd-m17DVkoQvF|8giRQh6)Qw)I|P2b%np)If;H=KG(q2b(0Dn#1xnGM(|FU5-f zwW0;wqEg>J@C>esG<68zSqh;_Nu-t(7ce&nRnsH>?`H{6;E* z(@k?iPP)BPs_qmXKUJw7Q=#l*Y+|u4h&qHA*||G>sFyJC(*qGK;uDDd5^vzUFj}Z) z25$Su)^z}DG)&&A>?7g$cf#``(?rrzCckVX+{JJ<_I)>)(>$)V*MfViU9L6-ED?S; zuqF8Ip%8G)*o)a4W}-|u4J5a`bAtbPm5;A59{Xs#(^$dEOl{G7c(-BORG%{L9=lvW z89p3AxlIvm9W$JhD2AU+xD%hlVQEZ=yE$pan#_#1c6ve==tr^IGcs66@+h|G^o}oI z1x<3&XNHvl@j=L(oo|IDM1ENB8|t^LtM)ZJ%Xf*R>y(d{=)&nWgS?H6FBk*ITlH&K zFM4)6RQyiE8;W>aYu6e3)S+H$x%3UvhT*ouCdRdi+b(0VsMLHQ(At|m3>mitiP(nP z0_}&2rw^yS4lBy0p7)o@;7iP;<1xaOzIUz31ER5ZNIrxXqkSE+Kfyn?>j7PIC_!Q< zldRs<)}P{(Ja`&Q=Ip}A>77cnt3LEcAuSAFmr~i*1(g_!g3RRk)RM zo25})MrpTBejX4#A7PT3RWTsxOj0|5N%$8>yf#GlMa%l$la!(|_wmx)H_qj&SMw>R zf7YXEfk8Eyd0IU?C@sezc*?jIQsef(Q@R4zJVSSpMLuf_t44V${Fo!9jDf4wQ+`nP zJS0OZVr5a``-1&xha3v@^rF*J0m}qCEBnHVSL5SdX&^q?qczaANt6kUs_@~o^>k@Z zXx+A{0+-3Hx9z~>?MkUiS3TV7rQKIR;tPX?aa@5gPVtc+p;V#hx-PfIL~t?gBq{zH z*o6)U4LVFcmJga9z=pJ1NK^3v$iG}Q!6)WQEjbrp-8sH#-ujizF^t;4jCY=DLTH;B z$#-g!#S}%Cg8I>F+Iwk(9-K&!x1j^Nv8xK_J_*{+e913%zaDD4Y55B8f=+wQ5(P# zC)q~Dy!otyj196bdd7OhO@`2fW6g?Rezj)m;4n^j&fz<|0=(3t-#!Jqz9&i8^X>NJ z#UaU@WchXzuy`yVx{-v^%aa!&)#RA??PmU)WkQrZjmXECzi#9kGXjAyv?XTNcZ~c& zA=p)Ki&a@EKa*v){I{Xua-ms#-{it`Y47GVYGsdqpKpe?^|8d(peUBdtWW!Tb1>N8 zN(uw!gPtd;K$HjlMU};BxL6I8rj5H|lHQMYSogvdbg5GvnAB;O>*nxV5{S2tL(?Qphniy>i!ea*t}M5+#wMhm1HbG+^qg+*hWZ}8(K9P z`1MA1**;>geXd@JHXWasBpP9epa>}XzO6-cnMmy8=@vGSXbaS#aF+8udo6KO@ifEEu%<}Tdl zp3`Z^>e!$TiUZl(xz4mqRJ)k(8(^uhl*B&MsQEtPi z|JzlS%M2Le6YU#-E$AkUm>9PlmOO0x{X+|m#0HPq6u%EI-V850QQp{);ua!@SQuyt z1{CN3lncHJ_u>blOIB~CaJ7&Ch|>0j=wQG|RjwAnfV^9)iq1pFqZEUXxJq(K55l2U$OE+Zq1Kv`3T=TMO}+|3k=1@G+ zm3;>js`_n4#@Q#xm53c+R7?_G&%My12I!5Q;*c>GL2Q*!@^11V!S#9m`i-C>l4>+o zi>p-^nuOFoVBv2mOw2c1n22R9bnONRUwTyxe23n5L|x)rQ_^FsT;qG`~Z=j(Vl;_IVj`2~GwR%6w8bNaPQyUDVkH6`s%g?Pjo|TC75_s?lyxq zPds=1{E|uwu$Ni9?Gb9{Ev`X}q<2@FXTmW&mQL|-UNr1R;Mj%13}*X3dIXR*1E7EC z0v`cSynz97uarE0uNL4wBcF5OtnnULy~2>2O891ypq*ETp}V%e{wfKp96NM3OVd0< zOnR3OWg`=gScZvy3!mMn_@2lH>n)FB4x+5 zvp-5O4X?=h72*UZnaEFMbFMVYGpVR=JPMMB9TJih6#Ta*U^Q)ldNq<>w^;3kf`gOf`!{M39o>$o9;eeH)FDhk z<<+xeKKVW*JP0dq2M0a;z;QtVb>(YIr)Iu# zdB@FsmH|L3ZGC`qn|ie&rlL*aRcF*%gVh~4SWQto*GU+5UPcCZkwR;A=v6~5i#JvB z2qK#%_CQY`dep!QY^&9CaS_M}@3awKWSsB=C$s9UFVBcWV+-(fk`-PU1UGXj{QiwB z$H*z&+0_|GbiK>O_wG{#6v24Se7m6ucBqlNn+IeT7T+p7&3A>ULaHce$&iYs{+U+j zrH2cWX;)OHny5S$G#0REb$<&x@xyEwQOYyyK;10fT6x_68-@n-;fF3kOz;uR01q_n z+DWm}g(l^vy$m8mcS_4ILIY+S0%Z$s2qFB|etqY%ZfHVwmImRXat)Y)^9SZK1%T$@ z>@S-sS&^a{``VvcV%L=3J$5Y9v(lhUH#=m04S~=^>}z^V?r;i9qYtM_-o%1F^&XRz zG)Rd*FxXqeeRd+AKe{!w`Wh6bY7w7_BYgh}>5rJyB#AlCyNQqzjht03k*^u}hLirZ z6|fAJ9XB*C?p~4nPFCUh3B}Lxu#p% zC%GupzMd6sqPmR4*UfkA(?JLM1{tHBF48n*fe#G7Yn_saJ9iNXoYJ~a&n;MQ@dyt= zvB@z{zB^)fHrunpCtB@cry_wo$|H$OCg$pfuw$bYwze!`Wkiw9Lz(w-yv*c3#AxYiP(|Gg>#ahOh5IEPX~HL zs!HW!{vGV_!gHKIOX{4Qh*PJ1E`==L_N3c#K09w<_#>tOlwJ}V`1FXm&m%0=)_`+pyuTZ8hUYmsgU>^1 zd}n$gXmTn<)?l7M)4&Puk&}5e%Bf&Eq}7L;;6){MDJF=6h!6M!_|x5wM;sQ z|6-|buSGOI`uitGmq!Jh<1(7t-Sl{Tf3ZUf5P5yNQWVN^tjh8B!DwiG@hm7(p5Pfx zE#eIBA+}BnX-op1U-A*rSH1PVIRpW^>n6q8F2FfYbo6-OVjEgOE|VfUVBPx<#qa4N zrL^qq^;6_@fWkooTz%xbn=_WnF1PW*l`^IE*CA$(RLf-*+|R&Oj7W=)rMJ9JPt(c2Me=2A7m6Y7)3iMGQ;>{xt2JI zV@&9pR;I03BqvWxNYQh;!z=ylmPNcxHGG>_>p5F}%hAW=GM+knlw)$*mZanQN zdBVi8tlRZ42WIbjy3CU8rK53RiK>-ZpqS}Wvvd38aTqro2NMO)esfytwSvB;D$S58 zBctF`^A)WFkfHkVtm`!_pXu^KwAt%oo9;gqy*?`$JxnXXl$zuJaL{Jkpuha>p6_7$ zp)sjAFP8Q{ib*0yA%^*H#-Il@=8$x*gc&A}-Z(&DU-(;=6h(`iC3iNXP7#-_-q0?% zK&x!;J*rcfaEQ9jL)lmVMjJhunmRaqaB!VW6)WQ`z2yN@z-Tr7YbY z&B*uo=dX1Qe2XJF@ds!kOrBPm*QH|_%7-=#!Z5l|g!s~5y&E8Rg4Mgjsy+)v-9^pG zVjc!a`}6IJ=*CVg|GGMxVY?RqkeZtMer9IoyUJ{qOK$?mfzV7dW)34zjSP^)V8j$z5l;n@PgJmt-2MG2n+KmKU7`o zog5$k20ZOhy`J>F6@NNv+VFqO_CIU+`Lhk9co?d}95@=vNsJ-;1C*6xPBfB=9=WeM z8<$Es_;l*oCH#Ei6wr46OZ>&9E2oL)Z}t!TzL9@IGDTYovV$Y%Asd>94<3Op?JO#` z8JSTN_j?K#f7+_{e|_9QR&gr^!|VKG6yeayA6)w9Ok+3Ka?|D7hw}#9lp9ez^t|;y zFIX@N@MA^D=XPNKUp`+AMe*c=X*7Rhqkox{kI;Vnp;%l z0~!r8{l3;)bBm~wY@fp+s+aR{rw6yc)d5GJHXhQ0_NVzyOf3FUtvG304NA%w&)tyJ zg=Gn3poV@ob8c;GFXgeZn4>ohInT#do)C!8mK*e~?kN?*gpg37o5>Kq?NMuELZr?^=t~wqY8=E*VFaRC>&K@v$ ze&uP`u-w_w((;O$n};{|Pk8~I{?DyT%t&5O7r*ZOE~1TALBN?qZMSGX7?2Dzln~%T zXbrx>)SdU$IDgY=*Xzq;%!ZMX(W^QGSPwkE0sv@fX0UYi z+!QG9hKi-vtLy;RU0&V!pj!>&$Fak0b_c;X`#%e1jPLb8q0l2YECWS`GMFOo8a0+E z1YLKlqKVic9(OJ@Zfow05X_9b(FS|Iw6~)XkxG(J=1@Am~*KL}_`)QNW3LjR(c$L>&K_|@O1?5?NZ>}I&ogI@^4MkPf@9RFm8MEjX1b39Rw(wh!h z;_L4e-BTV2cY3>d?+nj}n@Ba^?M)^24m!L{Qx9xbyno{2koxs6`kyq^S=Ocd?B|7J zQHc9L!PVXHsLaS>m=}W=_MHMAS2W7MHXCHty|FUmf=yCj6a&AAP*Y@+(b(D9c{h{u za!tiL|7VxWdIh1FNpU7>bzdmT_poJUd{^k>oBw*SGevQsYi`};G$eEG6~ zf#w(!2WP8fUYyP>ASj|h_G>2W@j~a#KjFj3iU03HYjXdZ*4cLSfZEm%<75I9WK@Aw IQpVr@2Vh;nHvj+t literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_w.png b/Templates/BaseGame/game/data/UI/images/Torque_3D_logo_w.png new file mode 100644 index 0000000000000000000000000000000000000000..ec197dda39246e2f1f0a95f79d35a68aba584a01 GIT binary patch literal 19328 zcmV(yLFc}SP)#n#`spifFbNPtii zs`P{=EvOVxe29c59g!kW6zM2}4+SBFB8c#zG*c)KqzeLKqql_6qk^;u2?-#Opig<( z?@k`cySdpieRpr>{C*d*yR)-X&Ybg~GiS~K#km9=QchKoBuSDaNs@e&fGm#$9g-wT zk|arzlN2|Q%`QQPBuSDaNs>UqE}+4#z(nORk&`5p$$%UTmN2DcbV-t= z+?FK4hGQ8L$bn)j29%&ek|ZgcB}stc7-j`>(AbjkB$$vSNdg8*5?I)piGf1~5O6p% zsFGWz_`E$gGRNG zLDc-lsFEZ}@E`#~J_8r3uQIxoAObjO5UBzgL|Q5&Ny=ZKL4t++1uRrwVt!x&!vjY7 zTkR*IIs{ZmkReHuy_B~E4H8t?UMBNY#Jv0{fCB~{jYUHBb*7Uf`%o%RS#LR(eMc_v z0uro21PyoqHenEz1L%;-Ns=A=Un)e|Hj?;{Kh;T0ZM7c-YhYmqhM}=Ys19RxNs=T; zkmQ8+QyuzE)$Sc90z}XP2qz6*Cj$#f60}K0E!$a+Q3)ux0tr?if;WHwHevz^EF|Su z03wx@Y->68*ypR-k->NZ2^4SuIF|`4zRrobHqC|LO# zhyW2lV10OXpeiUI)$WWZ$7!6{G+H2p%9LieDA* z4G9+Vj}<_Y1P#6p4uB2DooHEW`$)ztlr2qKS}O$YQV0;x$tuM?-oQdCKM6kMj9hF# zfqd3ZPAW4GnW@^me6|1*R)GkTcY#fq(kfsfm6dM+1YhbyX-1bo#23b{2tZ*=>x3vE z!3snerDFvifM7(410t+Mq&Vy55~$b%B-o`NfX(u8O55d!lafW3QG_hCGoVmKb(obP z0@Vru2tbG^W~Ft^5dkcug~HiD!OnZm?X)f1DS!jmqz{}966_+wMF9%ifC zy%kh0aX3#&s6JSy{5CuG9to2^JlLYcb#% zyh;KHdwyGWNS#C}3t)r3@wM^g6n_=F$_5@={CUWBVPJwbBsC9f1PO>>vGie7PgaOj z#mrY_%#@Ps3tCi*(pjyvtnjIz1rNTuO%yn+yuA5edB1f3`?6wb3oh@25y2{Hgfxxqux@C(G+)F0l~Z_N)hmAdl6eX?d))ArxS5Wc!q^_!j@nH zATkdLkf8Nt0Ei%h#;<~vb%I8avjP@Y00}#rM^!=n$Fo0FfxO4l(g1AELpZ`)R16AH z+cSYf$2YIZ9dG_&VVw{OCWHbB+}#%_mIP7|fn)8!X#Fmg zU?qsawLn-MO_7CPlgc1JtH&3OV=S=~++!|K^HFQ-d8?N<%bIpOHa2HtoK9k6P9MMuVAEJP5NT4bo>u-~{EG7n0=xEKtkF%S7rlL8EdOItu49 z*fnf3%?Z3b_>093D!T&;+GQqR+7c=vtURej%Wh!87C-`b>43x(H zk^&0Wpn~Pnkrk({S_ue5S|muF?VSQ9EC&*(z7J*=2NDp0yUZbS5U7;QL@TUVI#t@) z+0yEm9IAlw@@N-Y5TP)51{k+H4uCfU7c2z2%0bBkM(>ceKM%kpdiy)g*%~Cy^L79e z#BD4RNC1TNy7zv&b!$$hs^%(7W@cvIT4w%7v%HzAc0C?Ecpy{(makA@GGkzY!rUSP z+1Sk@!4h@z_Lr~{0EwCXc|lHt8JB@g1y1o2B|;S6AmG&@Kxgm(jWj9-PyhnzU~!vtcW%lzkaBHKtRZ& zk3L$aNYSFzJQMx(*PqGv(=$?T|91PtwO_AYXxXaOeu4c%ldp;~E>XuLYB^LBS*{`g zA%O4>>ieiNfn}@@RqG}XM@tr4I&!0y|BpX@Pfxmf^?ZQ> z1+uPNw`-R`Q7^qdCgBS!^a7QPWDO)}15D}qM!12*E*}9BJvf`Tc+7A}(_0lsf(3Z6 z%MKA%PNO{hKu|%X=$HmHYtbqKpuqK^VAbA+?QrJQspo6dtoeGuf(47xekA$&^wVvjU4{{hiylPh_fU`rSKsFI@cPLV^jvVD0x{2Qc9XAc6DDSAhgCM&K34 z-_F(u*5Hb#=QFPzA6EEvkVLy>1r%ue6$Joj0STNLBumSeVcS3}#Po=n6H1gU*-}q2 z!sUy5ckd=&zji$(%lh!2|A64&;Ht%n6)OXmjs5)ms%lv%_V3+0=b1KbjFvo@`$yPO z*5AH$YyZu(v=fmL5j&QwSdmV^U%bEsFXu}v{$=fKNdhELoGpC`NW4tJ7Nkps4&eq zYu2dN2NdgsFhBu8M0mGub3K^($7q3L=F?iC&-Wzh%9W^!K|xWBzyyzXNqG=iwz(9067MLDKtcB=CrQithw?3#NgghfG$eKL z%+rPN4Hv}^B|p@*o+N#4Ru7lK-zaUOFc>dJW5s1M zDKXnoW)^mz+bP4d=FFMu4Ib%2lY){&-wm z7lg5-V2(W;S`Fmrk8Xh=l$o-iazysx%<|-o4M@c3VR0 z9c~(09mw3`Yz2@Ib-;~jBV_(3lVryN&fs7LI$R1lz`zl%xQY`M!~liO{&`#_XQqf< z2#S%kzg&prLHWLdSzlb`k5fmZa=8%xCas$p5H)*O!KfeVGgM2fk@XdO3|#u<;wzqU zb)Y{41Q9EuW6~)=M4qy*+prr0BdxDA3h7E@)+WQ%5oy>yEV1wPcvu4$C0au>% zBgc+8qf;K0;`^#epPB`xp$$}nqp(PKZ;;HM%mVzVUP>J&AeG)T)u4UN0?nE6SWdb* zk&%JrD^}>@`Eb+v4ev1o5xM@}uxWEf``DFpUL7*nJu82-2)x(3Z=W&4h7W(kr0gsL zL9yappr8kIGkqUgDF*iMcjBK@KIj@$Ik;O$(11J-TsFP;gLSU|>*%N|kCGeR$N^ zv04A$OiR0T_s(yr$;l~~H*ef{Z04Lfmlz^aQnbvoKUEV2iYn~%^2n2}Pp_V(`uFSK zxI)E>L1o;1;~x+ZY*gsC#*EJT|5{Sg+24NqE%o}f>z86;qK-zzuDpTyeKTQ-67f_; z039r5h&ZNw+7o0|1Af#4RI1kuS=D%M#&4>UH=3m$n9xguJZ}2-@892Zt^V@GOVK@g z_4V+{rP9ch4beVH*MM!H~*7Q zuIRKYi(N5U)Vt@)0k6M4{OP)N>poSyM2S)?>T&1x?bNep&;Ib~;{W^J4JuL$1jfGnBKZ zPp_&|uU@Qz7jwesZ$om=f{QMXir$=k4R>e^9{5UMH{YZafP3sMyT9MRzao3PWJY@W zjiP>juTWYLwO>%xud@G6JbQL!tvYpLNXIN;Ww=Iq&d;&`|xbUQr21j+;l zWk(Sz|B##~L(+#?&sh3MsERX)#d^IS_)!$J_2)eInmyU1$e!=N@A~a`-_P&fv*&B9 zKm;WB;4fU;t^8)qojc>|<;#<1eE4A<#n@>N*>O`Px7<*X8}(PJ7!*|NnYL}i=Pg(; z?bgkkb5}-3w^Hz(2~GVBdUo$#`pl_Q!&a_d^Rast)|C~AfCTeu-m+!4&tqagaew3W ze!Y8_QOKPpz3ZS!a0|3T?`NYZC_X)22km)T{7@W7T@J8_n(bUOQ`SiJ8#Q`#E=84e z^~wf95P@x#fD|7Ww=(F+=JT2fLj;O-v~ z@O)Zo>I6pRq_O(ao_k}O#w8d8h;p<AZQHu_`R~5}VP31J zpY8&cKF>PC<&n21PJH*urAw1~bnRM3!Q1(fr#_iFib6EGX9EGf`}G@g{o1u@UBf$< z!c>r&N(_R#BZm(5TfKJeJP5>i*TMabr=wS{To8Zk=zx~Zn-x*eoNlp&_QSX;v_I5c zBdAKoEI%hqP;i7cYTxDDt5hlIInNh1e6fBfsU?v_QNg8*zyA6&#|Nu+ojT14+lj;} z8!+r6E>yl^#f4{2pN_-?6M(W`SU6r%lijv|qL`so8wd*&0AV_Cnl@=t*sahfzR9(SSn&yu9`Z0*sx%QVh6%oZ@dw-{i_|*n>20q zyy!YKXw>+HZQHibgif^t3fvq(=e7pmZ2iRD*#RiZV0&`c0cA!{<2(wytXDZZHQ;v7 zG2_Rl5XvhO#gs)i({7&3{@XnZuP?Z-Se_`$(khX2uTH&sJG8*Wxie>;rvMWyEEHUU z1?sL1D;+M4Je>7BphbcRB9oh2QB{hFjGTxAAfT^9>Wv$h@7%eQdh_PZG|y*+3l}OJ z7+5x_Sg~ROsHS)L?OuKQ4y{|aZms&E4VI8Fn^j92X7!pmYu4L`j~p3$EI$4|F2BJg z5@_APdFl48TWRU{?xiLtU%!0+{_nZI>F@6!P`r5YQl(0l4npm3*oP6bXGb(?`sCtn zJzn0U(HAUZt>ESd7zsG5&fO59@KlAN6Wz}3+e30I^wj;7?S=w+@}&PYDe06OtY=vw z;PS?}(WA@EnmacIV>0OT1i{3aQ>UPXaeVf@nzd_B*s^is`A*^C=XLs?4z2fa@=|RkgmlX>V)*bNH;8x#MX5li!nk8c_eMuW$E{tzJ{9G|(9$vRl~-!D z3=3;mt$OvwX5Xn7658ry!g07ydKoL^o{^q@|3*skRUQrdH+O}~l`mh(D2-dl6<)Gr zN$&=Y8ZE=&)7Ype2qFffl;g*9=i=jz9gCay@%;Fs$Ko7Rq{?IpwR^YQZs0+{n zi51J1#!j64-Z`DR7=^Jm3WKfcq%jJO%~fIf6)P5)%OY{>W;%t8BL*3%H&SzfwqnJK z6*W;ZPO?%k?X!SVr6TX%y&LG~=NAgE;TF*kr%#{Y1`?Agl{*is1XbN}d?Z*LkBsv^ zt3#V?!^GXYbO|s65zs_F?fv&>z@-K+5MjmynrqcZjvc$-x?Q`CPd(LY%;AFvcN%2^ z74QDNdwZMY2{e=vZn;p_!VTYxPe}NE;NZar+O=)_!L?t1)orJK{rWXT$#cQHc@4}! z#N~^Z68rS-^0_(WhuZuIakK;6czlaHz>XlM3lwGj^B(c8k#!lGkJ@Ca}io;my1yKlb> zir9dAS#=*dcFZrHH-jrzu8h#;ijP0}WTX*@fL4g-o@+mO@{}p(SbrOu-kY^(v1(;>^invh)=SqSEUf+f zxpNyb9(3H!A8`YU`>zjsZJ{nWY7pAMtbpO2It2_IG{_J{Y}vSRRdAKc5gRsbP9p#h zhRPoTib}!3Gt7Wq|5sjl%?&zADQv^ED+)b$z;?FOQ83u`QFHGaGK*ECm;eezVZU9G z$@V(;#A4UuB}0Tdv?TFK%bn<@%qkN^s5N3`#D?+%AM3XDJmv_c@RwUa7yrSE_N z`^JtQ9bp6}1`Qc9s9}T9!ju97M~IRr#+-DUzub1~?CI0TwGx#s6IjtKzd3W~41zut zde37%|9sg?UAlaYX>s%S+i#kMX&^zSp#T61Zv&A6+OyK zpQS)IvLX=0a$u;uM1PM|8RtqD8x>XG^ZKEm2o0dXwNg5cTDNPL08a?bzJ`%WC%yOH z0GsiHtt=8Mqcld!Uu(URtnwOXBJgN~CXE{vfj$amAVL62&iZ@d;>A}Wn9zFxD%FS? zGuopFeKk|nQC2GHAyBy1j4VpJdiAPaU5xUZ{LVWyD_5=dgkAxnmM>r4f8fCV3i)!3 zVgev?UH9(WZ{OBUn^x(40B+lz_Wt{|5I_VRCrv0|?$b zSa^dLs)L@~phn^U>NPi3l|0w@-<0Ykoqxk0TLpt1tiu3 zX5fN{pJB5eufIC9;%GH0sfN&F~O>34X^=DB~ z!3-u)!2v~PWy7fh?y?JSp9K*<5r%cE@kEWvo;QyjJC=ed7g$@K9A%x*TH@%|qsIUX zK&2xr5_Up^RKUXJVrQ)|vPLZZ?6Z|eQgXryP2fJ+*a zr%Xv?H7i#L))-eTU$#Xrant6_TPWtHdRtI%<;t3X;NpezKkAj!J+s#h@%zQvwQJ&! zC){V;H^_hjf=jr~R4>!sefor9fJc(@p{7S!LeK*dlM#1*rjKc2nr6aMLF9;u>_zv zjN(`Ya6uMHIBAsanb?QwaS-I9$2!U`7DL7J&DUSIedLixi)7zOOiVnC$a}cfDXV}T zcY5Qkx02zhpqN$(yVo076_Cm(IFBYXx(oR8loE=^QRvZkHc-HI(6U? ztxr)jg7?7i-ihbV#l!d>-Y>%)KusDoEP6C9J{`C1)y)4GDOucO#0_UQ51npl_|x$H z1`QiloHA+B{}Ml3lJs7hgwZZtF7Pl-ft+WqtotrCJAGXmZ>g@fU}jT<-oIN;S+H8ZGPyAIqw zd0fHtATH#lx5tfpf=8wN{rw9ydGg5`b?em&)w4uEy72SQKYg}rd6L$%4(*@Q-HLl6 z;lz&w3Xdi_q%NR1bNY0m7Lb6{>BUYJ-9RFd@cV#rjF5(8MtzP{j!xm>z1=@%ymc)p z>8u+_OkoHPMMb~_JY~nB0|z?6vo&(85ogbC`D)j$3<~~YRcDn^JF1M^PB%a3D{=Sk z-GuCjmjR_pK~S-X04$L35EqbV#aSDqmI=L%2b>uO7fj^bgCUUhGQF9Wb?BCA2lLeC zFSqH2dUh-70FpA5t5BihjL68*R-t~lJTYq2$Q62nq+0dr`T*p@g`1RuS7ji0vhq9s z^Uu0vsa&}-3{I7ZD+n@kZ`s8yHlpF3!k|RKe?Q1638Y zxcNr0^hwKx<3O7Ae`sikE|A!_Z(kz8x44m>pG3)$CH$Q@P!}&+^!e6p+jW(2`SRs; z>osl0j2{)g@dc3InKEsf?($dJa^(UjlrYLxRn#3qtQ4Z%9O-!YKd@>;A@LbHv~OSJ zAH#>g>**VD?8wnIJHOtY&Y*2rY-_gzpJ3CxxpVhDc<>;n4J%iv(n2ARR%&@W@!bBY z5H&p!Qp?1TvkHW4(ug(S^R8eU+D#OX4>6X3{G zDEyMA&!8n@^_n#wdM;_C-AFmrA}nmPLblridk2T!>9IBf1w@v$B`a2>-@17-=P3B% zk3Sy90iX&a8X%!^cn4K!qgWuQ6fpq63{dEmU8QIrBS68by;=5~t$@z8q@=4uUww7z z;May7uvt0n4knyBBlJZu!D1JSAwWQ(%^Nl}e{1xp>BUQwsFHo}&h6X3^y$-QhJq08 z-6Dled!~d?zD`R`%{dAlE^mCddv~Z)$5=rF1wm2~U8h5XdpM4p3PriR8AgSk+?e0= zF1L4ia`{PkdWUNO6_yH}*6|g0+pn#d90G{1wr~4}F@RtVK5*9~Y112>{s}0)XB%@W zBp7}4W?EXVB`n}&X>@svHP2@*mn-}KoShyi$;mf3Oa?^GkV(Fg^Z&><-z@#^q<2RK zlrB@xGa>Yg_`ih<7wp>o4T*!LQQd^?EWm6N7Gu@0jBt75v*pXjXJ1#VUOfb|w27Qo z3Gd;y9l$9EukD|-yE<@yhFK$$Me53Z4u_U!uwMCcz{KXwn=ZdSaiV7aEnBvP+d>l= zwztthH3fHi+dpsJx_#3KVCgLnLE(P%@Zkfr6{{Z-5(*tRwVth8vu15{OiaR;+qb9T z0)f+~PbanS&_VOrq<7wVV%m%uBDd!14(2J7Ch6{cIeX^J71rNl09b|6ri~j9y#HT6 z5?x;k?XUXKDoJ4{Wtk@A9J9H>AcHFq;b?Ve^>kS~XEfGC>bf07bB1r3tqPTGs zBkE2LlspxMqvIl6-uUR_kIxq=TC^IxE?%NUhz0z^WakU-I1;oL3e^O?;((Pr?-nRf z0M`m)#H@Lg_n{+4bq8KRsZ#z5`|YlZ8Mx8<-b)=j>N zy$pd5NVhKH@E7YC9jG&N)c(b`4&3?ew-ebwB6~Zi6G3c2%E3)zd0@3o6qSjwEEQf+ zFI5u+rwb;Mu3R}=p;D#V-uYLoSg{rbIKmNZzyMffJqr&H*Nwip_lG@+lt7M(+^GF( zzX1bww|e^Nc6k(j_3AZXRLh580_#vUxHDtw^y!+;Gq3w`rmG^0pmcT~P>jtGHZ1)o2%@-&-T!+Ty(qo=q=w?AWnEXvkwG z?Wfs4*M9v~vu|oVQL{nA2BC!z%Epz~8Z~H8$UPfusP#FU+{$_lRmFz}Bw$*B-shU+nZ!m|`9ugH;?1&Gzi_ z(o6n9m4h`c5-_%e*TGeJ$^={hr%#A}#}iK6pEq~za;*=*Q%YlFVh1XCJ9o0~A3k{S zfL@*>-gvVihSFmNIC9a z<)E$Gwk$z<#Juz6=FK0TK6!E#j12*IWq7|2gHVMwY}oV5?c0~^+q0*W4Xg)t`7X2X zK!;1u>&G5@tO%p>2<-!xAi+Xvm0%H9f^-m?d3T#B%$)L{K7Cr(D)H)|L4BJweX=lu z62w*3rtKLU6&0pujesGh7ku(boGAkV7Z0a3&EJR-BeuYDX}#2c;43{fmLm+mv-!(y zsd^DTp;cnp(q%m@5QbT0kBNyH49lRE0B(8Quz7PT>9`CF3#&;vmXVda9)BSMe)Dnq zzg;fwrcfi zN^zX)A4tegm4B|X^?C8LmL2G_*{P^+P z^^SusU8YQsTVeG@uu9-sBn;ciNo;@3{^{ho$So?oYnp6{~%rFK4oZ;(zZ@{as zzUo%&Em8Sq{@l3@cJJKzlGbm-7hgPU2Kpd~==aJiy30)m_wV1eVbkU`l<|>zm5B10cqia1xrxB1&q%t zQF;8_3Tmm|635VC!+IiEaB|%nGGxdqz5KEiqFb?V-mu|W6w6R_OiW_K#*JIHZQuSS z?_YS=uD$l}-P==7S($+d2=GRX7_kXeDPFs#y<-UW{i@iQFa^&S2g!le^G4WHPw6^~ zZrQr!Dkjh1f*G865~%)LjtCXc3Q#Ouyg0dHP|$QYcwOfGtbK@`!pLlB7PU?n5ELw^A4cP$BPQ-LgQ4Q@+4JSudXAUbVB)Kt=qNRh{Fpm<1Ms?fB^BQ`Tk2?y6n`8 zrO>8byUtz1JNx5&$36SHyfQj^sZnL0s8y@s-hKOKyMan)4?vNp&E0ujU9oK0QX>n; z@L|JX*l!hDI$)kKZ=-K7Te4&+EF+FW`^TGa#_91I1e05~Zk;&t%{MC%@Rp%+{r=l; zJ3rI5ZMa^!zTLfhCjnoRST1Q~iONVWindm$6mnRX-kCi4mpL;dCwYU3F%!m5YuBbt z5sLQ7_mmyk5|XFCgp-KJakN_ZfXO|*XJ+pM#rPyTt+YAm-HIcmcfWo!v?{k^>C$&! z9Wvy!PW^yMI~c~ee|y}x%Kv=-{eK!+2D0f!O3LMg`1l{9W1^3(T)id@rDK{mYg%~F zz=5@!w`ke8O4X{3QNDBfn=twT=@CtV{ylh#c$lW@$8y)>rzQ%0o=yiwr!h6HEKN3 z2!dg~gm8JLq`&`YZ0)G3(R$X6zyADFGjNjeL_uc`<@HX%f_Z&?Tp)KFuZ&r_WaQW} z7Z5C@q7*9XSsOq>JC7sh-i)bJt3dDoeI-0()af#Tfs;%?gNo7DTRh~_Dz{u(tr#y| zqgb6-?>=OepS!y1x7im-SFS`=3<`=u0Kho)$Jq*v+GgAi?J_%E5)h=<3O{Xh0;g7Z zR^5}?3KS@S5=R1e@R}Y36ESPnMYoWfGG^Sk*Zl(mf{ikTyE@u;=+GbjmM&Xxz)GLp4gmWhk*`py_M^tEXoGOF$uYyZ`>TaT9yTV#z;ZP=zr z>4pp(Sk$3)R9FEC(z7^F0f!lwP!#>sIJJb6ssk3Z8|J_M6RJ+WMs+}ncRnLB^3whT z`=>-jN539ixyq9$4GtBL*0~*|1QpfFnCQiWUmF%jnuqSpj;&zT_$nniIZR8L zwQcuoc(W&){BY>V(fb%Y3zr0r{rJ;QHzvIE&TFWODmxuU+yp~{7L~DM#w=O8etjCE zV9{(}cyL_A^y!~YkBFFrVwv*fF_ydr>FD7@JBAG(e$1qwebEGNhhxcEO%heNyg1#c zag#MLSXFj{=R3Rr{d*2`s-shZf+_Xx(k)3Da7>}w zMPbx_EPN!i95r)2hl)~9DaOXG9IBC*={M&sSa7*)xpEVswZ_P&g*Cx%ZQHtKWu@TY z>245_s?hIpQ9kIjQYj4q_ae-V#+yQpn?_P z$a8P)nlGELHCJ^y~s-VFDQ?O%lo7w-4v=FJN)UHs(;t4@K|j)eI5?XUFf z`$qYS72h8-e*75|!EL$)6A?%tZ|Ov|MCiUB_S92fK*vGki0y(6x*%|D(zI!G-`>4O9FIG;otK3I zf+9EY`T+vgia|kBA&6lBG@UeKB|U|dx21xqe232H(9zPT{1#}Tgp@mm1neNr!EK==%$eQ?U8kmUc&Q>}^&9Xhmby?XU) zm-P3qT&{fiIw+lSGcE1Xy?b|WT>9nW*>Au3=FHR?GcGA~N8su)DiAOrfeq5;N#DEY z%K=@wbg5mdR_)pWrAh^%I2=L+3ms+k(q_eqm^g77q2k4D=l?omjvE);rfr)#<;zzH zdi?RnOS$cV) zc$Zd2nac9rJ9oBi+rIsX?CXmc&VO5_TJ?D}eW|MI*6bS(cWtav%;OM|0tuG8Ik5ZM zbH_&V_3K}hEmv-l!hgpGYFgxW<8@X%3YY*G&lE((j{+Dx@1uYj9FT+x8UR7t<gOe$;wB)G>B`EK{_&}Z7Votu4q?8uS#nlx>? zPr(bMMhhgEw3%oi!5U0xfd##1DDfs}ttU9h9uT$*D}jtVV^kR^3zcE{MOxfQ+DrF& zi)PIVZ``!$Jw3|=v?v9XD)lx80Kubg>;_6vqTiYU4b-Jm)*yn1b&Z!*B8PsxdUayC z3Kg1VUym3*e8_@Di&98=O#?`*q1oezpheKHNcgX7mg74BML>??ur z9&OY_9A6U6avwN!D1H3cF|+hf=L`rwbL!MTDCJ!hM`^EFRag)Y% zIVx?t5mCM1vc@BiJesp(0PMtcDHJ+#uto1ywY+%6CPqixa z!=AnONz9FcgbMC=0gJZ7{4S}}8qTSrq$Xq|{z8#?q-o4#FfzS5WXP$3g9lr|dyWMd z?uo*4p4SULp1+S^eA}j73)-yVNx+0zh*z!WW&#ZrSfF$yN@PsbK@BJdtBL@ONb?7R zga{zaA28}mGX;pP9AOL*_kTwiS@VR=s3_W;$Kh5aYv(i;PEr6tI_bcIh%@a)89mw6q-zmo;bsw&Q>VF2d#kCd@1cEI@^4S%8Uv zF#{8%mIPFVsd8do-Y6f(D#5~{z`H$pg96%q2AJOfg6fN^v{9qynmwnrLWlwrG@t_s zOu*e5FpdQLyJ(RjrCE&)lMwulr1z#w>FRlX>coj%lokioA~_-iNRXJ~%-&%QCiK#g zAXuOwa8QH)yc zw{F)ifq=iQTFSJYMFJH}pw85Rg1?NR=%l0R48Wi>Ny?#O<^vcq9VaHjs9mc`ClO}g9 zSg>HuiJzA*UD}|qTVfEgEUGyM3fj0MSbzxy!8(BgDD;#G>Rxb_ur9Q-TpWc1C>f83 z0%hq0OY3Y3IJK))Lekd{QzDJhN4tc9`)yi44j89LUDn7ohKiRcQ6&dR+)Gap%xkRk zNA;b+`tB$5=Lc4(RB1r=^6Y5AU8TieN#1*LIt20BXI zd)z=%EaFVy_K4O+x&wk=dKdB@CeLNTyLpqjVa^s=EJ6#N4@kEWvo-ZaGKc4KXRs|AXgbtRW4I7U4ytgVQW+o?#n~dzU}B^Nn1BKooB)Tlv#0p_37armQSNjb|$2%(PZ6 zGl)1(g`_+<{XyHN3Sqxu@yFLYcjej&=y@IkXSqyd!RgqcLy^F;Wt(ST-@1A8q_oEU zkFH<4_PU>+U#JJrI$tp;=yQaAU}=p|dAFC{qkW)&2~r0s+=Fyb1Pd=ACQ1swX0WG zWvmEj&qB(%HzOkACC`T^5)uwGm`pjrN@x1snNz2pcY~~Mp7*}py?drj%Fh&3xCB;; z>AqD0#HAvD2-4Xu4yeEdEI9e{uyF7M4=fcKtGduwI9SZ?MS(-RSW>LA*r@-7ytf3;mTF2wDVlnc(HTm0~i)&9##}vOnlwouUhT8 zb#wVeT)c38VW;r$^Mv&w>08qLvFq%zs-Xpd36kwwW+(jd02QoE^*qePJWSO*l>{n4 zq0PgN%RZu&u&?}h0|!*T$)U)Ih+MG+;JFL~`}Zpo(W(-ksaG_f@G@{R;x+Zx?HX>g1&j5->qyoiGCsxTbQ{84s-$gU5`{ z%9$c375x`5T?TkLF z?Bhm{E>r!98ac}vfBp4m#{2J2+07b2xLhtShfGl_SzTR}4I(_9E8$YryAvnQLJAQ zELWqj0x|&Gtx6G_R+&fKHa))dpbu2Z>zH8GLo0Ri>1uWzQMoov~v)ou%yEL0K7 z(kNf(SlPX2&(FL;#8+Q_Im*i~0@uHf_f8Ea`r68+4PIb^Hs(I5S(1g*rbsJj;8On;K;;@Xl(Njn{sMp zfs@ICiSxQip4v@ko{n0j?JH=1-^BMf0cRT8X@=*PICUM*eC`#Nb^Q;`jv7Gg5a(QRF^M>oOdl%R} zsd)yPhoM&@SL?3!V*4tb{byX%J#8OUUl#w8&%D)~Fi*vHeX#|wv$kUV?yEUSxpX5| zqV42Km8NXReUfFTFY_9jCS?J1DbBCVIiK=+{c>zY##DIr;pv^sGVg|{jX4aJFda-C z$gsx@d&BhXWqzJRcljMEeRRN$^<4ml3|Yc8_b^+X`bVSgY~>SI@A@SdYOfH6Xi%3N z^?&+edQ#R$I+(2?f;Oj-$zOi8zRyS@B_$*Pjk?>_3EOwRaJa!Ma=N&n$@tvd4J8Ck z!|NtT-hCMOlvlfcP z(ZN1^7V_bxjbEdgg8&#Hs(-4n_D|@Cl;z^arwODBPNr4~DdX|ae4gHSEB<|+yngLg zd{cqCMGWH%@HQ58VD7g0xQj<*+s4do6`u#e}7XQcfM6JEgzOq00hO_EIn1hYv|ih;!X(VOJhe>rTgu%6Yxr~>>5>@ zKAG$NqwmoAn&fm}q=YW?AAl(tv$LZsyqjWQ+z^dsqd_(mr#kX^sN;`sIcN`#wBpMF2- zJZl{yKl0+pLr(IsiLNbkM;KpXy0SG1(*W~L`P<;LY{vKCfh)5gD~fs48nG2{b-B=G zUK>8BO0EDXH<}JPJgOGosiRE>tNkEX*;lAS2>tu(rFanu5qKONOl) z&-$#@{2cB<+VEY%f&A7N$8f#5_QMi=so8$jCyPOKU;r=}JRC8$crTtIC9mO6g=;V@ z;nOB=<(>?Ilo$f(UP(iF!I!c8k!a?t`H2qPiPJ+RY|bxP;Pg}Io5`1%zaV4dY&|KiCAGwFwZZ=Zd{0r^AG zwO~c_=d!2C!3~!Y#ZWoUysX;G%j6NWExugJE($c$cbR*Hly4d-){VD0dem=mU_3F5 z5RnuYu+I5g_BRl2WdD?eN`l-auKZ0d+w=Tq*>z7?2DkNNOn#oV*1JR>BV1C^dCkz+o|4~?X3~+FeygAz6Qqy`M#{mY@e>Rq(JuO|@V=gV zOW=)~y#=ohxf-_F-71pv#93hpOgz86fM%V$u4kVlt0hQ$Sr1m>T*J1DUfEw4E^ccq zN8PuCk?SGk<10T-dv?+_-?M_$AA#h=ko1nAX|W#KQjhzyCG z@G~U5qu`5$4$%@gr#8xd%h>JVa$HwU15m$Aa8&oI6|p0dtRiARL9f=9t5uGzg3|sl zFGo9X*S~+UfW*}`5g9;oz;aGMa81`RxW%O0w@k zDzzn{)uO;F{RO#Lh%$vDqk(%Cs_F5lv2K&}Wy2Kd3nCci{_K=HSFJ`in@KTy6RABE%%Z0l=)_en51B`B5t8NYjF-}@hC!8@g)Z!9oYhcsT)&cAbOMv&PhZ6A3YDqy3gA8cX>{yfl#$DH2dcN z21>%~vyOf8d1CeYopp`nMGybk&5DIvgz_u2!(y|N^zLizjx}qF{D}Uz$4w+{FSCh~pAJ_yr|r(@75eNQ&IhYeCdy4CXq$z? zFrB&2$WoL_mbxqskJIS_~Y=x0p6KX{T@eyYDrdaog+nRokt1>jP&0KBvTyQ zW#BFhLT*=s;_%&)^P?)aopWiNm$SCyHdPwL*c=ysvZ62!x*hN4xEXF?;~6X`T}g<%&ymfvG~h|H*t4sA gAn>anHe~mMj)!uL3rfOt0ZT2AJ;~Xo!itvkAFNWCtpET3 literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/backgrounddark.png b/Templates/BaseGame/game/data/UI/images/backgrounddark.png new file mode 100644 index 0000000000000000000000000000000000000000..13b4bda55c7c7c5ebc87d54bf010a5c06c32cc28 GIT binary patch literal 5751 zcmeAS@N?(olHy`uVBq!ia0y~yU;#2&7&w@K)Q9>#R~Q(W?pK9GlmsP~D-;yvr)B1( zDwI?fq$;FVWTr7NRNQ(yJ#f-(1)jG1mahE`DlHEz5)zh~zxepOxpVT_WpiI{9Bv9I#?+kdw?Mc!cDDpK4dr}|{V&IObIM4p>g6Y)Ko^Y*WU@7C!{s5xps z7vDHvSM*e2`>)U)d(|VWdJ-$@8w31tXMb<)gZ@0{keYQFH(czMBs@q~> zn&;1NcI;VZ;H3P{>CyGM=RJzzSf@WccSz#J^j6h*-_HNqIhTE}(1%yHFQ514PTwuF zeDUoqk0$%w_WKpJf9a)Uwj| zw&2wQ&0pKH+REH@%}EmJb_!OW zGp4f5o~+|5R3W3FZt!_3_u3tm$DB8`oai-}#Ca~`Qq7uoH$Pncb?~A@@l4^LC7G>z zD%R;QF+6$J+KrK;ckN2O+LLp8>-B`!G%V1YDXbPzV;dW?^!KevMB z|EKfa>qCbBwB3z9oOeEUe&zi8N)rvs>bEg6Ffg`cIy(n=Iy=LXIxvCHshw!+ao9oT zX#8a_S1mp|#%hPf>sJr7 zIGW@Y{QCU5^nxD!pXAgn!Qc1$82$oym@D+;g2o_HiZN+ z#?F~lN_%HCKL4?+y?=dq;Jl}`@6KOb{lu5;hsz_&Wzu3F**<<*wzT-3I^X6=O9bW% z_e+*IK5}1oT5o@$o|VprGaDv)o)vEIJetIQTK0@ro0pBNOkhawr`9#6xt{Bu%UXIY z>iZLYo~K)`W<|dho=?2CWc} zKKVcVb>-P&YU+2E1n|75+W59#P+n?VEVPFvK^mK6y0hUhJ4T15>aoE7&$RF>c>?%UP zwoVoSmTZSTfZEuA*Z_zdfJzv6fH(n&8JK|>Wat4PMpc4a2CHUbjfH8(v=AnP-AxG~ z2M%#JkrMo%(7+xs)D0(Ey9vK*v8S5B<|Z0v9dN!QHJoVdChQS&0F()_+I)avw2T3U z4dDU`cMxLNoB%WxyA1XyqIKQ@nLpUvL~7mvm8-N4CsN&nHCN$@c)}?SQ}ZBm6ZQmr z02n!=WeiH>kseUEf)K@6cqk`;f}Df|MeDpXTE+n5gNQ&LWchit9diJbkqDRMgDpRU zoITjwL`3pOQ8L diff --git a/Templates/BaseGame/game/data/UI/images/clearbtn_d.png b/Templates/BaseGame/game/data/UI/images/clearbtn_d.png new file mode 100644 index 0000000000000000000000000000000000000000..229c71e8bddaa102f495a3dba47004f9c65cd0d4 GIT binary patch literal 593 zcmV-X00s?QkPn?)w z6CVEP+t+W**N+`j{PO<2JW!f(R$hMapFe*XQ8a;^}fcc&U1q&WrzGUsRJ~|Nb$;HG%v9vf=yp@5~EJ%j{0ATbF1a6f`foz5TGU zkMHBZK=}_JKCu4%`b@n56}$ZWa=w55ESxrV$`TGP&c7%D0g8vBl`A{>#l#-3tgkQ2 zR8m^7wz;{KM@Z;(+3GdzvKks+{{Hz34m}oFOoJj$N=5Z+-m>NMzkdJ5{O|8yMqVD? zKm39MzuDN>{(%B$^X5%VKwbYCk<;G)|Nj|*als698ry$h&@!{I{AFfl{tFTZ1~u4K f&!0Y90T5sS_@w(H5qG>u00000NkvXXu0mjf2Ztbp literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/clearbtn_d_image.asset.taml b/Templates/BaseGame/game/data/UI/images/clearbtn_d_image.asset.taml new file mode 100644 index 000000000..ef78852ae --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/clearbtn_d_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/clearbtn_h.png b/Templates/BaseGame/game/data/UI/images/clearbtn_h.png new file mode 100644 index 0000000000000000000000000000000000000000..5e67cb13b2b4a85172bfa47e74b66993f0b315a2 GIT binary patch literal 595 zcmV-Z0<8UsP)Z)GIKgXfZeFjXq_kgNUj7V-2Ju1S$m*D2rhp`p zl9Fcr{{5R5=;ZW=4s#>mglFXG_fcy{jGxe}m8#*ZI9GM_(p zPV4K}uWDReT(?V0OVju5+t&+J`X6r7>({RxLPA1j0TnU5ee;GTDJjwa)albT#>U3& zL4koCPoF;ZdGX=}>z_Y=nBbcJ{{71fH0}21PoJ2xva|ipoIP7*Vq(%dVZwyX5fPEM zf$}_W-n;>6Vum}9nVI=>M@NUoh4be%&z?P7X=ZBLvS8uDP2azNXPP-ylRQAAkeFdrZPpa1{=Gs2xW zapJ^25Y5TSd0R(E=N8C@o}O;)$f)S{??1kax3#zR@eA<(K?!mT3yaSa`unr^czN$E zUc7iJFaS<0UAAlz7dO|l>C>iXT3T9u1p0>&9^{~y21T5Oh2^KYbLX{x`t-3I=nMva zet|!dQj))bw*LbK(3UM*m>C%v|1%<|J&=2U{P@8N#BBfm{$pZgW% diff --git a/Templates/BaseGame/game/data/UI/images/clearbtn_n.png b/Templates/BaseGame/game/data/UI/images/clearbtn_n.png new file mode 100644 index 0000000000000000000000000000000000000000..ecb13a8d661317f38d3e4214fff3f0312b7b8af0 GIT binary patch literal 377 zcmV-<0fzpGP)wAA<=LJelEZTKubwTGJIwqVjwiI($lj%e)b#h zSV}4U^((?ZzW5oeF0X{QG;0x_gI(Zp1%{y0u%eoqB*Be}+Z35ISogfn=j{1}M~e5r zom^~6`il#Z>bB`G@&P}3s^gaM{dn?`64>vd+uy zC)Ag|rg#ir`9=|JM=PFw+g^xf&*YE1hYH5v6--s@cbdf?FJvm;W#*#H1Rw9 diff --git a/Templates/BaseGame/game/data/UI/images/collapsetoolbar_d.png b/Templates/BaseGame/game/data/UI/images/collapsetoolbar_d.png new file mode 100644 index 0000000000000000000000000000000000000000..984a63853c4fd48dd65049cdda3025de63842420 GIT binary patch literal 280 zcmV+z0q6dSP)hgS0Vv4;mgMH;x)r;fhYuV;(S;&;;NSt=u63|? zz%6O(;J_d!D}&pg-rnB0C5=o>QFLPjLReThZb@}b%@L7I2uePB_z*;W0B5A7%a^0e egYzdqfB^t3O) diff --git a/Templates/BaseGame/game/data/UI/images/collapsetoolbar_h.png b/Templates/BaseGame/game/data/UI/images/collapsetoolbar_h.png new file mode 100644 index 0000000000000000000000000000000000000000..7e3de8387148c02f13b1e7f24f984de37feccf69 GIT binary patch literal 468 zcmV;_0W1EAP)Y)0 z9XimShOxs=YQDsp@gJb1gn_Zvu?5E&#SyLef*bddTyF3YCK)zo&)JhrF5V0V0e+4h z&!GoIxa##XdV>0jSi8!D*$CI(frpPId zoX)3*M|j)3>wnqT_NAKB=~QbCw1-x!H26BvM$lT86^U`fnQd^FLPPQqy@lE%w=B^f)Fy&H|PPw->A71`mp00RIT5=iSlljg+$0000< KMNUMnLSTYWrq$s9 literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/collapsetoolbar_h_image.asset.taml b/Templates/BaseGame/game/data/UI/images/collapsetoolbar_h_image.asset.taml new file mode 100644 index 000000000..231201217 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/collapsetoolbar_h_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/collapsetoolbar_n.png b/Templates/BaseGame/game/data/UI/images/collapsetoolbar_n.png new file mode 100644 index 0000000000000000000000000000000000000000..b36de3ae049d9743a09dc6fc26af740cf9841360 GIT binary patch literal 439 zcmV;o0Z9IdP)Ox_mJPyDg4SlUjSNW3W5uGwOEk!Lx4uX4pZl7UqAx0i=rnvSAdP_$$A20Su(H_ zvh10InGB}9^1v-*3Cso@F>PaL>L}8isTm_PeHKN5r}hODW+z|w`}Q5O#yHtL&*`VC zP~)7=kRBzVBuOw+YZy|xe)*kcR2>cgwbuTO8@Fkiwr+iIX4$!2->q9vYwhDG`qk=o zMb~kBVd5z4oUzQ=+;7}ZXk^2MX<21r!6szg-dfzih^e4%lbv7^R`VYwdnU3IbzN)k2xeK9 hJ@8zg^|AXCU;u#ob3iiM+rIz+002ovPDHLkV1m|A!NdRn literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/collapsetoolbar_n_image.asset.taml b/Templates/BaseGame/game/data/UI/images/collapsetoolbar_n_image.asset.taml new file mode 100644 index 000000000..9e7afd9c4 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/collapsetoolbar_n_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/dropdownbuttonarrow.png b/Templates/BaseGame/game/data/UI/images/dropdownbuttonarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..8c420ab85dad8b5ee3ca92464665ae071a471732 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^EFjFm1|(O0oL2{=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%sd>6MhE&{2%E`$|abUXZ<1r^pL9db1gt1VxgHed#<;qq~ cW)1^}6XL9#0Z$iS1nOY$boFyt=akR{0H4Any8r+H literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/dropdownbuttonarrow_image.asset.taml b/Templates/BaseGame/game/data/UI/images/dropdownbuttonarrow_image.asset.taml new file mode 100644 index 000000000..24976a2d6 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/dropdownbuttonarrow_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/dropdowntextEdit.png b/Templates/BaseGame/game/data/UI/images/dropdowntextEdit.png new file mode 100644 index 0000000000000000000000000000000000000000..3966efbb56239be59ee13cddceab917b144882b9 GIT binary patch literal 390 zcmV;10eSw3P)^?7l2ZX@QwNIJ_tdJyVq-O;hN*R;|Jf8oKt&?reAz#jswl zv@I};de2`VaYRw1b@G>k2y~N}rTzTSqF{8F^S*pfDsBZxV07vonVb4jntpET307*qoM6N<$f}R+y&Hw-a literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/dropdowntextEdit_image.asset.taml b/Templates/BaseGame/game/data/UI/images/dropdowntextEdit_image.asset.taml new file mode 100644 index 000000000..7006d8448 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/dropdowntextEdit_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/expandtoolbar_d.png b/Templates/BaseGame/game/data/UI/images/expandtoolbar_d.png new file mode 100644 index 0000000000000000000000000000000000000000..462929e95039217cc59fe50d6a95c2b7054ac0b8 GIT binary patch literal 278 zcmV+x0qOpUP)hgS0Vv4;mgMHsH*7Al-)#9Kh|`0|)U)I@mj4 zmz0y0VX$?;A?fYyjom>YT}CFR*d@cl!f^+Jx~ArcNG3!}K6>~NM125fq@~N3qsxQy cCqRG!07OkOz~-BXZ2$lO07*qoM6N<$f=)$pfdBvi literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/expandtoolbar_d_image.asset.taml b/Templates/BaseGame/game/data/UI/images/expandtoolbar_d_image.asset.taml new file mode 100644 index 000000000..45a7de130 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/expandtoolbar_d_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/expandtoolbar_h.png b/Templates/BaseGame/game/data/UI/images/expandtoolbar_h.png new file mode 100644 index 0000000000000000000000000000000000000000..c33bcad6985b3862324279bc0f5457755b94f28f GIT binary patch literal 468 zcmV;_0W1EAP)qS?llb{VTLkjAsY;|aeyj=$>HXDkKfU1h$Gh(W#P&4TdW&oR`Nq&a3 zTN8um?Q=toI@keY`=EJd?T*CDZYvdgmA#wIqEGOnEJb$uEx-Uri&4ja71Rp=0000< KMNUMnLSTZ?xyoSx literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/expandtoolbar_h_image.asset.taml b/Templates/BaseGame/game/data/UI/images/expandtoolbar_h_image.asset.taml new file mode 100644 index 000000000..003d65496 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/expandtoolbar_h_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/expandtoolbar_n.png b/Templates/BaseGame/game/data/UI/images/expandtoolbar_n.png new file mode 100644 index 0000000000000000000000000000000000000000..0af2f1bd13809d099ca3a5a5c9ba1dc42b6f66c5 GIT binary patch literal 437 zcmV;m0ZRUfP)4~o#5^Dg=ri|$!*BY zbpP3B?F$Y zwO%=>X`z&@9drv@g0dk;N^TmO`W3-u+KiE!MNwe&sko4$lziUp$nSm5RBnu=@2aBx z{tJ6eXN!gmYNct4`g&Fzw)&+;bvRI-=QzXGHr@KjvWz??HC?wpRyQl0+1YZdyi5{W zUN4=}-z_)f`gSe%?Dp<%8~-FuXmPb@UGQXjFw*+wZiCf_ZQoNiaUAu!c4K0>t=SF5 z!{LASY^7JJHJ)q5(e1RYDluRawr*}2FECOnsnf(0O2YO1qqJU$>_lDHiXEXW%d$tF f>$5J~UjYUHlxB7wIAEv(00000NkvXXu0mjf?KH=8 literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/expandtoolbar_n_image.asset.taml b/Templates/BaseGame/game/data/UI/images/expandtoolbar_n_image.asset.taml new file mode 100644 index 000000000..f3b62bd23 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/expandtoolbar_n_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/groupborder.png b/Templates/BaseGame/game/data/UI/images/groupborder.png new file mode 100644 index 0000000000000000000000000000000000000000..61234ae1fb3dee29eda38a371165d36b060ee426 GIT binary patch literal 1273 zcmVRq)0SqBM&U{ zK~RE8k;)fTv@rNVFsUphN-&N10jmTOk|LETicKV_m54TpVAK!`|L<7|`4E(7K4ARB zDus5>J(HaE?!4W7v&qH}czMI@+&44#&Ye5=o}G2_O1ZzkpGs6d@8oj17WcW!E!8%I zG7SwXm(AMBn08BdCX>0T948-RoKK$0X0t6*Q&aiH#l^fexw~LXm>2UyPMmS3yc8^% zPN&txvs=#V2iKgriKmXs^9tJFqjWWIBOj#Opr!-61IK}Xx1-s?{L4G0_&?_ilXv4x zqfZ_btu8MwSK|-wsQY~v)cnk(&+H?8J(|C{sz$fn!M^&){#~l$>@n5f-deC_;MX2J zsxZHFtA)8SUGF$_vOr$N_B~qGz~m2~oD@4WwsorNs!FYtyCThVSEZ(BX4T=g^Lm1w z!FRq%(Y|`AS3jc65Sso~f)<#1w-6X-QZF0;z1&IJw>OAO*=w$5nIM949%2g^Yzljy(oWy)Hf= zKP~7s_`nZIkS{YqF~l(je$;4#Z=xBAo(3O1_wqgCBii5tJte9r;~AA?zGq4`(Ts_n zWQL)#a^A!gm6r6qM+nP?0Sc)kNm@4Xtw-=SGYrxowl6GaQ(5@5B&1Y;X$f*x_i`5k zxlG?JMp&eYe3Cfrf#}H=#@X;~|BtO`5XzBM3_XQWv3X-F3LkUd8np$mW$;ZD@}tlb z@grOWzKMePX$!hz`6y0z95fS#p0K!L8Eqx>`_a=%75$H%65feFik{-gOB_87-@a&t zo=kbNraT|vFoAMIeOeI8_0#*bHBgfWlms3M{F=|;vk&HAk-V?7qf70j+dSQteXuCB zxme0WXRY7zZQiQU6W{Gki*a6ad*$6z80sP_3%q+`TtsI83dY1J6eRh$8vuYoz-JP{ zd_mbs-aVmUVdndNBq%XE#kqTuz$8gP5_U;MoS^NwxEOTzWZpMPmn%SJ z?(zSC4+0292nh@kvId`u$uPqZCPNED8bgi@LmbC`Ql1P|ln1?_pHA~@{Z%BXuPKfW j%4_?bDUt6}KLr>7B{DrC{G$C100000NkvXXu0mjfaJE^D literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/groupborder_image.asset.taml b/Templates/BaseGame/game/data/UI/images/groupborder_image.asset.taml new file mode 100644 index 000000000..2038044f6 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/groupborder_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/inactiveoverlay.png b/Templates/BaseGame/game/data/UI/images/inactiveoverlay.png new file mode 100644 index 0000000000000000000000000000000000000000..feab83209cc442c5ad8dc73c2b86e0a8115c4743 GIT binary patch literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!foRZkbkkcwMLfBw9D?8~Obq{gPz9LVg>D`Q%4bP0l+XkKL$W0) literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/inactiveoverlay_image.asset.taml b/Templates/BaseGame/game/data/UI/images/inactiveoverlay_image.asset.taml new file mode 100644 index 000000000..f992cbfb6 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/inactiveoverlay_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/menubutton.png b/Templates/BaseGame/game/data/UI/images/menubutton.png new file mode 100644 index 0000000000000000000000000000000000000000..3cfa036d8f5ec1d5458b0716efd2ea477cca0c6d GIT binary patch literal 3559 zcmXw+XH*l44#%qqWh=YvT0r)eB~$h+$R3K9077sF2cwE-f$I6Ia@lP>$8pT7Xdg|&C3=D&EmKGZR$`lF#_rjVQMSf1cG zh?Vs{JgjO98lRX9I8ZMpGN$D(cg4|yWM#Gr1BM+U_x~L1t&cullRR3652VcSP^l4? zNhd7o?|JE$$$nu%dk;B?m_M(2xm*r8Cpe)*Ov>_F%Y)DlgKYyN2XkdpZ-J=8UkP6z zjU(Ik`V^Rn@S3#pJyGAi?roxTLI_?mu#ku)NZ4R0x=laq;$b!pXtIEY9_W1iY_obC zcMfPFFxPZ5_BgEm*Iq4Wx8KX+7M3?DZzImGE0Ez;dJmkE7D?8NX*g}&`P{BB%_3%QXqvdF=QX= ziUmTOiaR$HMlTa%9eST~P2k~@0PQ_)>Hbg<2KjURPMGUvWAlpbO0`q#anDoGyK!xW zh6(a>p1{P(4)~q<@V7|^w0x4v8pu&Ii*Q8!Etr0vLr+Xzf?6!dIZ-Lw*4aochS|bU z2?cH53mTNJE(rQ8*RpCP)KGym5^iqVsnzQ*L!t2Yo@jJ~2Te*d2T_5dZMQRyCv2zn zjbj)mW|WdI^)5lEJXL=2go#Q@7N;^?|6UyHU&&(q&||~O`jN?z+z&>6L!_8aZ4=Pz zlzyIVdMTGA>vj4B=TmmldH$KBS1D4=$qHH)NZ~AD3mP2)(C=ryubaJ9AX8oN=qr3J zJlK{!tH2{m8bmwXCUn}fC>W$pc%nfpCg3}rM}(gKxrt9UC-yDaEOk2hd=PJmV5)dP zStV2_4HT-VR|yn9s6hd!d}dxo|%w}_eznQ4><-#H=v;&*&`qMg2i9;b|GnB#q3 zPr`i&azOKhf+nBN z-J&i^zIrLG-R3rNxW>WxDT^Kh@+cZ4prOfj=$}~Nc8D{uEu{}c`Y53c*jTBitGTLk znyj}cZK}UVEjn4)%jU~beKlI^3Auh|#TkX0wl3t+-jPwAi)k6=;+hrS@R*OSF$_e# zEPkxR=BD!;1yodw>Rd5Iv~PvUPLLd>{na}ysjPWK>V-vX0^8NX5KGRsG@Yj%BlN-) zZN1-<;zUUIR9JdJwc0Ga^`)J>4N15bA9h{sD6_5r$H)2OlSabc?e+9)YMw@%mp1Nl zgBh_R-S*#Z-hiomp+B`)h<6n;IT78Rgv(*gi_pXEM{dO>4V&XWgihK->h2}_wB>c4 z=|MCb&!?A-16D3yJiI>NhNu!_nW-7}1S6_Wi6~zx5pDIr97S)(dG7p`3mzi5;;!E7 zb-Pysslak*`s`7uLi-moDVr0_LuI=W7`Fg&=Vgs7I7d-lf*bV=DI!>hd9Qdotq$DG z`85Ug?KpL3XK7GhMwxKE8{Z>^_42ORbpcst!#1JNmXnM6o5O4O$0RQHcN6icK{Wi)SI$e>6*5fod zAQNw6klE8NXxii>Y6lr>KzEwt&$8P{7p0LWS@wb1!@&?O7~i7zu8k#pyDaL&A2#;FwH}<5GB4$4yUg*q zW8Kke@GQf0L}#r1I_y#j(h=1EOmufk0gNYS_;g`PleK@e;ZYgAwD&qE6xxxM4R}}E z>^Ld3>34>?=dBiyYP7nRcOW$LLB88UEegcQJr^C^B+$31^BDaJCMigGqxMFAND^d` z?Jkq3Dml_no1xOg&*xcF8b7Q3T>A#%MvT`gI2tP6o~9`frO+YOeC?CgN&)5Y~W?DdSzeEXS(eh<7}Yc{&4O6l0j zD59-Zqgk1uKK!lBz%{XfJToQ?h+Cqyz}5auKgo*L*a2ttS<*C&ZtWDbA_eJ67c+45&tk4e5CL zH?~@}3Q|83pl&vV;ck&wgp;oq*@dQB&v7Xo;m)~Ym$h#{q5{nt{B}l_;%^~MEB^A< zJ68`*CV!lnoZudr-Fml2hBxbdEFz@2^87Kz^npk-v?D`H8bVOV)Z9Wdf7A97Q1_k!vZHI zg@hb_drSVVeevzGPLGr@`BC(bWzIe8nK#rV=2?8lM<_FRYA2YPIZ2;olLJAc7Qfs+*wz@~Jv7aX!0KfN6XUVM+5uB@4_rBTOP%~f z$mE}0y8&}UZGM<57`ePV?dkq&Yj0c?a>`H$e-}j)l2OjjJiqIf@2y5!eAwCQjGsBo73o* zr%$o?U)`v1xS)1X^U8%FZLLra&K=D05#za$=hbp~1YIq!Th_GwQkiUHOp@$fhT+I+t|d*~C_Ly<(&S`wCOS zW{$6IA7`Ize)b5wSh3F#srdq`;yXs3z}qT;J@0Sbde<$hrF%!tlncU|#4Q#gCCV=H z<8FZV1Gyo#MhVe^7R9+(=`|&E>mW@`X0~-4Yo9E@zAWDqY&z}+-d=yLpe`NhD zn=ignNRbReJJ33*QI|d|t8M7dVci?_QYRHgvFrK~d77nw_Tq7cji?@nk`UZJx;bqU z2-bQez6=1yb-QOY&ZsUePR`ADx!GS_00LtIt8W_scdi~23Yd|e_LW}oTMHX`B~}K8<^+-*Ke?ri}TMj+=gAHRt>c8TR#7`Kixyst3j*N^EUk> za)`?&dm@v<+xC5&*puKXCw2tw+k4w$_p;Vyk2M4x1V~$#Ln@6&-97&xJ`n_)#QhVa z7_C<0q7Z+>lpmSz7CK>_)vGXa>P!DGQ13(&#lNvCGhE>MmxXXxP%)|f8~w84JXYzS zx}su(u>ALx|6!RR5)kD7FT{A9At4W5^4d?}aJ(b`pJoUIQ$CF8?;g;s8b$@+zbL4w ZSBpO8NK=0oeKjq>KnJS*AI-m_{|h>L*X{rS literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/menubutton_image.asset.taml b/Templates/BaseGame/game/data/UI/images/menubutton_image.asset.taml new file mode 100644 index 000000000..467c7443f --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/menubutton_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/nextOption_n.png b/Templates/BaseGame/game/data/UI/images/nextOption_n.png new file mode 100644 index 0000000000000000000000000000000000000000..ba710b061a2c7c64ceade2461ae2c37051578189 GIT binary patch literal 8517 zcmeHMc|4SB`=1b!EFqmxW0ECiA7f^$V{9Y)S_;kbU@S9ZmTV=7(jtnKt%&xLoJ3Sw zPm7AIEyz}qkWzHCyw41k&gpdC^ZWeX|BlZy!*gHX>wDkVa$nc|Jhr&G*w2w$AP0d! z=1?7MJiy;f(MMJq{N{G=_JTm<>SMi@3p{91P%e)X#0m$Xf*39U1)^C&5J>c+!M!VX z^^g>7KcCwgAkjx7N|EhG6=L77gC5VL02fc3I93)6|4?>`~WYem&r!YEr9Rh$Q7Z!<<-^C;D)6ko4t zD;GZQuPB^ITO^%vSCe=@Zf8ZI>Y|>mPlI-A^X~i}YC5J@UVH6L_gD@8>Mwrto$g=H zw|?Ckwf0WtOO=K*krzG7W>aqG*~dQ|AAh)hsJ}{4bKESh&$4D{WVCz7=E6mfj}3ni zq-}nE`ZEG~A;3MQF1u$yt^C#1>y{J4nuC2WZwv*MC`2{Kd0L+3S-x_8E-TAKndiD1I24NG;?W-J!ht*l*aP2EVv` zlXmcvRWqSoZ5Hr7>o>+}ewf%ZBiE{Q6?-V08ymAXeQp5V(4U|esJSQTv+Vo&QGCL- zz15|A)2%MGraK_o~n}U_1#BKV4h_z?Hmo^^Id1RmY=?M12rn4 zw4}KyA*guPa^jvjyGdc-}2<@>^-VF9%-U=6L*Md52xD`P;T- zr!Kthu;0IUhg7PX$%~MpH1soOL$=;o-Bwp=9micpw#RV&7$)LM@KbLe|A@E7Elo$L zg^m#U-wC0x>GQErz_&zRIQi!pBA1RwugMaUR#i167p@p*eQSqsgk4}&O z>OnkQ8*X4VqCt~i~FZn2Ec9%W8OSGz1?T4jqXl6P1~E1HG-HJ;(piS~HWe7q#SM$7Yzcn~pNK3f2 z*JE?>BO$_ENVw^=u~%~2C30ESCgo-GUaZ}cp6a^ptz`MrROxK>=Zm!3gV(QpQ`xRH zw=TiT-yC+OdqYInRm;kcondBXgK{ID#E1T;F34@iw&&`b8{}Jb?H*AwVO@!|ZGEM2 z8;RMbe@FMeIx7+urM-#CQs-cl9|Ry{fZEHL<=VM;)@CfF{VBH?-*>y5%&(V*>4Cu17ckYmuY~5(3vX$io zTyt!I1s;8+OViGGQ?5PUbEqJ`b*K>$v%qp8A+nlur0i8z862bVNzT+*f3^4g0}t}c zdsXIm9%z<*O?f0-|641Pa4yQ~7biEm`;*v&1=w>9$E`M&>PgHp=M6g6Ri76Qs}SKs zTN^s#&y(w|?SyxFYTJJGo|DbHq?B~gU{ts!B{)d9j8rDE0@AYKfr-=c)>xj813vZK z>+BfUO)e4EGmk1QoOwVg!1}rSqSpn7ZIu@V&Wy)BB`duU)BE8ho#PGCV)TrXwd5V;U|jx$~rN*;p28 zy+N#tYP70`O4%8C?Hf6!&mYiA3dRrKPtf=!pV7vE`KrO)icV$rZTGs@ZDK%$U-94B zdCU~3JT>%U9yM3t;JmeiXzJan4=r}^M3aekxlL~L?lUnBlHM6oK95*J(?<=OZu#;H z8g}XE1Bm^q3b!8STpLKtJl|}IfIgZVMh@0IVwq`|5_T*pB~yE)R@f|TGr5xe*zkAF zrBDGs73-{!rS_Aw+pm6aUI zRLhbX!ePQD9Fd8L@WVpyCnw)Ewx!On{blo6gmAyNMxN1g+fjclG&cK$^n{00Dn6Vf zu|!Y1@90*WtZmMF{3J&|=8Qjk9?)tryx&03Y9Ut&)LW|6RF9sk3wtuaxE!zPQ0M$A zS$?ku5UEe$`uzHe-%LVR3Nk#CD0i=CzCG|DwMp`VYDaiDV(Y^c3nQX@E7W;j9%!>K)IWtw$F5;V;!hH#Y-2KCv|%1-C6G) z^ZVWBV-3csHU07-3S0K$YtBSwbNl$SCrr=u$CHEOcUmiU3j!gZmk4hg+gb%j?R4_9 z3O!;2=o+rbH!93#Hyt@9t1`>f{yh1!yw-0_S7s`=Sx49Vkj&=Y=_k(V`3DdFT9BB& z^`oCk=-G(^%1w`?{v$1%h>#PS`1-W2)o60kIjh}TvptH>ZaCL}aziida?urwD`x*4^+LaXwcZ+6f$53^K3HMTEO~hB@8x7li%0PpDc9raCu_6FZ%fY)IrM6kAr_%ET-n4%i+F z^#&w$mR^uZJdC(wv^^~=M3uhYU$(u%uuCtw{^QI`7AUW{K_DQ{mzLa7FHF`qpOxr( z@)ymbltH@*1mHli*x9640jV-42_y~NUQ4T1XAL3O?_jP=&J zpRSTB`aSmU7C}3%y>K8D$7X1pswls5T`hMsaq;f%V~umxz(evew*y}3T-=Zqv;Zet z96DmV8s&E%JE%-C+wYb?Vb1>0s^s@ffA`Igi>^cIS~D_=G9Zu{$t()RjY^?>IopCK z+Prl;%^j{M_l(C$5 zTmf;fic~3=*eR2eo11Z9TjqF8aXsv}jXm+_tH&ziWTJDu56w64NjQ)bOHx+nz4yNS zc`Ia-vYo67410zdgr40xB2-ii9HyJqer(&nSVvu6I$Elmc&J}@M0(`Tp`(!VObj2hH(H($)E!^9-1taKYW37sZ)vYIaa%(3G64vq0`*DXUPJbQQD^q#T!hD4|v z^iljP%klP;?s++aU5SweW7o?p>>!^J^`XmK#!ds}E|4c!?!h%5%5_l_)YzgT+q8sF z5uM#tMbx-UPZdzFinmmSEVIbzpesjP7IAJ%cCCb#J{xW6xX~|}ey}8qldzGp`i#xP z0mSgoz|i0m?BJ((NHv~!&4OLn1A(Y4V1W-C%blG_3{C`s#^lfeM05lfd>Da1%q*k1 zG)5R8fYO0r7TX*)TwMc$vY6&DUt?#KGnWE{upDA}fM=|W7b7-|L1e-#E#%CiNgzQ4 zAfQ2`Bf{ByQnWct%u53Q77Zg|P%%UhW)55K>;|Q9cmNcKz#&j@+i2Dr49r3fYQ|#* zkvwedrYOKWb6AK#z$GD(QBhHdC@g}*3r3=eL?RM}L1Hj)5CP}Mum!YeIGev%L@~)> z1MnF<7FWRHu%RMO8l58)n8RS896Ch~N*T7%;Na8*qI)qtU%*6C!5bWC4+ubFP$&W% zg@I#;$m#l^)Y8igy51#VMX`2Tq&qWF@?Zd7v^27wY2i$~nTX@VdQF9O{6 zEH;x9#s4PqVnqO+0-DH8Xgt;!k3kbqXbh2nH6eTh`2ajVxc@|~XcPjC5lfg1k{!rN z1NQ+df))%Qx$I!EKooEig%i%1diYe4=s!WocI1I6u zCKt{W3ny!>H7yu9iADYl{3j;Q5Ka{PzvKA^{mMe-38FZ>Fjt-{JrrOFe$MkF@K+`e zu*>lUycp`=81)C78R&UuXOaV`%i+aLo8J?NoV=TKPdH25bf8di`6tmBlexyHtpS+g z2!dXo6fr_*>|g-wvr{$l%Q))?HNrTEj=}>dIvk6_px`tb&KOQ-G8yn7Iz5PJLdW4u zP(k0b^Ep9+C>jqS2ZIT34kL?tKGf|?MTLTAGySQ3Zt%TgR0ts2#M6@W`>dJ_{#4`r z-&o5;)9EN<6BHZ^05~`<2t$Aq0UQ%!U=Jt#C5$2AO*;mHCQpum$4l_Eiu`(9o!YBl z=KL>zrfR_datbK)-%0+FfB$vYzwY`+9{5M#f3xdfcl{#|{3Gzc+4cYCF1c?nyZ|KyvctgM%^xsT1$zz)kRlrzO>f>;?YU{xR9v#$Dd(el|Kuifiqbpu1ED zzQ5MCYo*sG=hgMeK(C?`uA!!1ARYzkp+S8#$b$y?(7GGKH=t)SHMUz0CqyObtsF|Y wB)j47F9M`@j@|5DWjmFpTARMOpkaH-DtEZm{G#;}pm!luTNj%W>(z<>0S&_o-v9sr literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/nextOption_n_image.asset.taml b/Templates/BaseGame/game/data/UI/images/nextOption_n_image.asset.taml new file mode 100644 index 000000000..55cce3fdb --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/nextOption_n_image.asset.taml @@ -0,0 +1,8 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/nextbutton_d.png b/Templates/BaseGame/game/data/UI/images/nextbutton_d.png new file mode 100644 index 0000000000000000000000000000000000000000..76c3ec0ffbfd0e390d18bf15b641406a1c963304 GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^+&~=2!3HE*cE)T6Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JigtRsIEGZ*dUIWo&smX&Az+(=poWapSz@o$*? zhV8dl?=!aFoKn4xeZo2Nf4=Qb$;zCp)-ipVh!6ks%DPE^D{?9q{wDx9i9DW z-@5CHEdniu-!^_}`*}dN=v;ZVvUv|*i@L#DeRZC~n>o$)T~mbY?ZFzA*KO@H&DTlVp33;PS)Y-O Z!Sa~S%jms^DnL&#c)I$ztaD0e0szoGZ1VsB literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/nextbutton_d_image.asset.taml b/Templates/BaseGame/game/data/UI/images/nextbutton_d_image.asset.taml new file mode 100644 index 000000000..6c616a75a --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/nextbutton_d_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/nextbutton_h.png b/Templates/BaseGame/game/data/UI/images/nextbutton_h.png new file mode 100644 index 0000000000000000000000000000000000000000..f52f5fb4230f07e879e02d61472b07c57d07712c GIT binary patch literal 549 zcmV+=0^0qFP)0-qXkL_v~jv zlgT7TvAv7&%t^dYr_+a#hr^+@TrOWYNQ8?)a=v3urz2xpTz;W+6qyRv^uk~=B$Fa* zY7trZc?lJ%X2T_NO4CLKXgbTNCUvD{m}Vo^YPY~Tkd2ce$z(`A zSFm{3{j7pUGGsRDL1tMpV+>&!sySO(N(;fVWY6>Px?ZdKIygr@9z84;3mir8H9bcT zKSQ{#tA_9UkIBuZg(!-!TCLy*m)dh=+qMwLF?PEhHk&s@;`3dyZQCkM?RFd6?G_i? zH&3?FXf)96b}<|dg{B^9J^vSnF{HXe^vpq8OGKg(`@ zDPc4kq4(575CoTb2I&Kvq)6s=Hk-l!@S!1z#rXq!I-TG+j+$?6tXwP5KmRLDro?qz zvLl(u&>hLB$ diff --git a/Templates/BaseGame/game/data/UI/images/nextbutton_n.png b/Templates/BaseGame/game/data/UI/images/nextbutton_n.png new file mode 100644 index 0000000000000000000000000000000000000000..203133732e50b1df6bbd9506cec49f44385cf9be GIT binary patch literal 484 zcmV=P8+ zw(YFdb&VZ&3=k2N&8;vD6%z#@SPPD4Vq~7_lP=Gm!*~tPGFXzjSBY6BP=OAZn1#Yz zeMOAFs`Cm16Yd2fQ=s2N5ee+0alltX+9{%Ju=RO7?f|t1WmQ!f&x7^dJ=)Ck+zLbQ z8C%e;EK4{X{$aeYESPxc)^_`2^&U`(>ag;@-~WwZxO#4HMyn_aV}GbRTk76dt6?AK zsxC-Q@=mGD}pHXHn{a?_1VZvZ|8^e0u7drcunPkNJ1EWBngI a3oroff;ABVIBm%Q0000 diff --git a/Templates/BaseGame/game/data/UI/images/nopreview.png b/Templates/BaseGame/game/data/UI/images/nopreview.png new file mode 100644 index 0000000000000000000000000000000000000000..fccdc858bc36d7e390f8f1b75f9604f8855ce112 GIT binary patch literal 34615 zcmXV%bx<1(_wR9ccc-*KaVuINxD+YU;O-D8?(XhV+$Csmx8m+l+}+(S&-=T7WHOW4 z+3X(up3j~QQ&N;dM0druqyUGAf z2ad>Nqx!;HkN3@2CKk@`8z`1Kjx@X;P?CBU}R*dAY(aWc}p1s?2xH~i<-Kr z`d^Lp_knvKk++8dk?1_^DDxYe1O90)i5XCFl>^$z^TI~!)xVe`qxRnIoshhPFo3FB z{hN+F{@cAk_VejMWw<2QQ=s~7%e=Man|?t=r-O&sB!j?PsmFOp0HcCkgCn@m#jA)N zpAhv@Ub4SQkMKGn`w2p_sxlQS`7T*r*a#%~4x8~;C{HZ}v}8H~`gtM8C;gpC=a>S# zWnZYIq*|)^J~?cv`EmGve-tHYX1+@~`7QfIylUBjDO?>&4O~=oEaWS#{e@ur(9s$y zg$t&_9FWfn>tEq6ZbdAbOn82PL_6b*rLID;+BejSM6s1d@D2EmQ|Hnp}CV-f-^{c-&9^nFionUgO z16jW~6Um|xqWG#?c3!Jv>r2p*cu6pk^H8?TTF@=>xKNOR(V~LZ%j2=eB=b4<5Jb|MfIgx zbOE~bftTAG#uCIunJP9s6;I3882`IfBdq+X$)(yHdh)LBfYvt&|J;JbFTmZ}8u?ER z)aLlm>Rfr)%jP^bQRe4yIqwO|43^VMDkqM{oHd@pm7iVnSsdX0vo2DAC7`}b%@LXo zV-qgmXaAZ2P}w$Vq~D0W&2Qn`|7^NIZ2{>0ihn}yKzE!3)+K~Hlz|39H!f>J!l9T* zrjTI4eE<(BZRFceW-bakY23U3ohhsE%(Jga%dWQncOi;wMB06mJa%((>RFo+afX-% zqFBW4=%QpcDrgXyvap~H8`E-E4xc~pzSST0& z3(>6D_w2RiBojRG9aJviQz0DrPa&aN68{;`QRD&O(b=rF!cgbFSG|MEh7+clixo4F zl-qLhKPQo6rcd9|aJ-Fp=8`_J<94hu!7Wk!x@$|9XY6&}rTx!G{1jtFC+=ie;Fb+_ zQIz7|cvdzDBf)l9AV;8v@c#@_Ct8rIAe1A?)u$rL3bEws{e=ag5ruD>1Ldjx&!_|D zyGboaaZFCRUYN=q-=*aHgTw@rBGFH8WBz9`{!l0RUN7`YRi_WXqEcbF!?yw(aG%iskio=3=J#y|2gctR3;M@B=lX z>(DdeB$~Y_mU7*8Te@O@@Vjd0|1K?1UA?!GW$NhV{B3^aeW4R^^vWG|LtEqhCZZbJ zTH$@Gc(eF;hF_w5;ePDi`>7PHWuPk8|F7e<`StmC<5`H$|AH88`(ip20Z=|1wp}dz zih7aoD(rRL@$VU``FCl8I^eTu{|5Oc0Txi|4KzbK*V12fTy&ver{( zcINo=M|Lneg|_z*TR`>nDk6gj=zPcP{{K#o3!Kw&Sb@G(_f-{noBY9P$o+;XBKR!# zPL?O~_LwLiH?D6sq5byb{cSnh8#@bA1iG`q>+Rk2$C*S&j_t3}cg*+v8@c=k$*}V9 z7;3%S(Zi!JFlxI-1L-3pf`K}&TQZAK%>)?aK-Y^&ePN83%NU;*7vcLAQdjYR_xJDJ zakNs4BA66{53_n+^yv&!MDft(@EIaNH}K`9IedlX@xC{u_fu!!-(a)1N7f3j{a>zR zOn5GoZ=_D%xmJ)oYJ;cf*1h+cY!psCYPWK0b#z-2SYP<+`kPbQ-R%LQIm1A!1=^UK z3>&X2)ok@V0S=O>3zAv>ztBJY^kG3EQsp{&PZ3n+L6IlV(G2e}Vq(TShd5%?0CVUDSBmbpc+HZKc(S4fj=DLpigG|uN^4ut9_wL**@c021v+HkNwRhxy z*@ylE0%JR8ZJF87p4;iRz5j+Cqu!O|pMwwE7qtE)6#i>2B_{iQlr`AH(!!7=|ITm> zV}tv->-Ajt>U0HDq#x(vduvDCySl!?>$6g2J{bXA*2u`nKs5QjPqWW^hha^V&%5_S z^OuPyh|u^&r-XPMqf;fH<9RS5CPmvltccTj`@Qoei&V5A?l3g0FHETQsm&M>=#dR= zyDz2v^OG5|1GF=F)BPHzBeZUe@Y643IFGnY$GO#N)tQXs}Tz1i~->m$5LF$k!x4Zkdi`gG*GJ_*_uOn;F5kT$TZ=}K1El#3; zG+UlGE}zF@FOm=`>GszUN0%YKw>t?xgrAny`MsVT8R~-2HpoMSFT=z`gt7nph6V~f zEwSxm%BO}j~vdiYU1xJbEgJ6}Ad;;6j3`qYh`&WlALPrIz#6PbsZ z#)T?- z6sSEe8AK*6=t3iHE84gq4^uHSh~;{Z6YYNp`+OfgJ14{G8*D{h@L<1mRiOS5B!*6= zobO8X*vO|m#waV$@!HeyIqm3t$4q{1JKDt50zrvxz-GaI$3;10bD3-OwR({1y=uw3 zz&2J;az`m|BYxiq;g5oga*&83tYx@ggAqif_?hL=kfL9$8Hw2yi^&%8L%;nlZ6Yuu zU|o=!nkwS`CYTR3FYERB4*B}}!QM5DuuHT8uI@feQz zdoEEyCD^C#`wI)lvYhE7z`M3t6d8-Q64e+N8Ql9ZyDF}xjDA|Vzq}!?dF`xNN=E>X zilmsjO8;}V$9ek#Ljt-lyx-1t_PdMXP9E2OY3GwHXw;v#<(-!DaF1DCeS@vQ$k#{s z?P0&Y_M5Ode6i=dl(6T;hNw@q#}%rcV-(G1%Ej-WY{zfU=lj^rEBdiJ&4dI5?URh5 zZtU0k`ejT$w*8Z3YZo`+GXGphmU%lQvl^D^*JHkz^4sd02w{; zH19wXOsOR?FMIFUbP@93$A~IR-AOE9OyT8w6B3(U8Ww%JpvCzuBGYQ#TbMFy8hz{e=8F<^lWSFT0-j z3euQ+j!+qN7Vt^R-?EWIb^uJiWzi2*63(uweD(~;@S`x(jfcJ8E&q1iik}jJH4VLA zD7_!h(l!F2lDl2 zGQ2&+w9NSTl>4gkv7_#N)w^C?fM&0_<_hTIBKvmHceaMdhQT%x=2%(Xl!j1+U6^)G z#d>&yT-L?8!sI$d?gjQdfqkj&ZQeBIsIT%%=Cfye=lF`b7B37asdhg4QiX zf0N;Sm$bT;HyqN{!@daRPO1RBmA)Cy1kL&F!#*#&KD+I1VT&c{lG8$Q`J5Q^RN3SF z()c6_?e}tRmgtZict*Hju5ItDDXDTH*7X=3edYS%1j?Y=-=W}wQdB!$qWC%W;SKqO z1ia^0>d+f))*M_i-Z3g11##MN{spaE3KgA;B42fAuLs6;PI&Y~fisjI@YQ3}kAXet ze4^Xz+!%|;@mo~Q@f(yJc}+FHO4a)zR!@7V{axmpxSSa`BG8sW`*U{yBK=8zy>JF5 zc(e$|kG2+zwp&skVwoiXOUluQ4o%zbsT(zb&#-Je>)RC@|6d_kq8%c!?{a@C$LR~~ z;dm%zqV9(xBA8?fo3iFcz@)^1r;T{Z1(Y1ua zm2yF*!Zb#Q_0nPPM|~DLSQx~uiMHAo*=~%Wfb8*34UI7IQ_0-Y7gG|e4lDK_3Dd)H zOU($^b`Vkz8$?|e?m!XX)8%@O=*{>qAeTn#Eh@N8cb~KK$%@?TGswB~vh&>vmd|na zcbzMqHTpO~Eutiojg!e^%p0tiHb^sAwzt}VjaIa(aj~R=AePy;Z10LAwn8UH(BY$Q zN4y<$>Ew2fd>CfZ%miVF^%0r~y=Im8%U|IedYH6A`m!FmYJ}t&D;egDI(9TrCmBhgnu!; zrZF+34eDeg?1Hht^6@4TK`Gg1!jvT6q8k|aNF&s3w*Lu>9?gRzG9HX>8F5bXV1HxT znn;V+M@L^wSG{wfA`DQzBx1JHm?x=P44A&>uV^NT+jcII$zKJ;Kv{93F>a&P22V1a z(SA#`V+7hG2Y9xtQ<_EEOs?ZXyn92mzObXk>3_=q5XS~e?I~wGBKd{3yQ2AH)%wX-z79KSW@0|5 zGDksTI`Jz%{@_r=8{-O_a-3A`1_*jK9pi{qQOig+*eY3FVIkgPJ2mK-mp2|Ef%W$x z5_RRVki3|?32fblhCAo`F}ME~qOcy6Y+)%lk6lq@-roNd7Uo+N2n zJibT3G0*;Bl7WsH>g6it>JNcN?(unMp~!1&B%1Z)m1$Yal@wD*96cXhQ?a|Cj-Vw4+E^;R@!n^rcQec13VPDa`*vaZ zPgCk9j4!H&|2a@axaB@$p4H2L~9 z%p~I5A?|MXH(CD&#P=bQTNjlxC@{rq1>ooFD=;KmcPdNACV{Wrc*$VDuNv~@CI*yd zr$z8zWG?8*ym!B!A6u{7(vCyS$% zH|BE^S@Zvd7p<5V*i!#X>ZCM%!e1+LdH-J++CCreLlq>pHAlOh)=aeD)=|PC<(sQ9 z(#H=`Gg?zz5V>`^KWv8lc~gMS7;{BmaOUnyo>9j6*V#3R&rTot+b}9+iQ>g!<&IR= zX!~W)I!gS0Bk<5Sa<0nG3ai5N$>J?L*OM2EFr`Jwe;Xe;+^yuhepkykteT{$Sz$aZ z>Xti1k@|YR>|Xey+#{qfJ8W^PEM zO55SNy)3NEVG0(5`_hU)5R@RgA81(kFE=74nR&(wiuY1s@0piZZ|IaU z5<}1Rh*=Z84+1u2_=OnejN>$r>Hz?GiN+#2(zy95I zQy22C9lxhllCdl8qmDt0)i0-En~#cTy(Flztbvc`>8r)a9t#b@AhtKfnfo;+UKFo? zL^?T12}`%;qM|=FZtrw8Yze$<1RoFN&{WgCbCX`NJx}&iL5`;nHQVoNZ_29+J&ttxMkduK z#0U@b3jloUk=aMm@9ua-ZhNmSC1}x+TE)1o(XO0Bvfmgnp%KnJyHNQ)S9JYq<@cxH zLHHp7TXgp^!Wp?K4sr?vc+UUjMpjs!UQ?`c%RWkYq3w3hH)>5)L{tZ{l<&Ro$K*xq zmvml~N>OIEzrW26vMeXZ+~3I9lx>-HF`Hq+YrLS)uops4QB4gq(eJa4|1e;VMLj_P#%YSbC|R9VD0tkYRvMmV`6xK!e1Q_;KEF|3;w~(D)NT z5#CvHpf@GQjwQ`Szm(~8%JjDt6wc+T-K$OP(h9+|{2}I znxu_eU$2;a+TEgT4^GdwvvOq;!&i&iIA2W<)3>S4Y)(6x8Fjj`hYd1SI7r&zHAd8T8=NvL=28f)~Wp~20I9Q1x>f3*S6kQN8l<=Vxi4EJfo#N#EVzW3#@H$dsI=o}M8x|3RLU58?JnoKc z_zPdmyoldd^riy38~43m*=6KI_3inyYAdMTClB^~-tV(GZP@HF>x~l(GW)n|ErFy8 z@i2D8`u^>LRWKFE1Smlnc54h0{(~o9)?I8R_I@jl?ZZRzj1C9m2+vzFiSgZBD1=Dp zC|*o!0NYg`b9()zuhV82gPz-ksB87>W=Nw?(RN|L5AUNH(rm}`MmuCJ+TUx(29GS# zIyS)u*-%39)e*PLn-fodG2W3A!@a*Zc!iQ5_*k0)S#!0W_Z6WOEbGrzmiJQs5ocw0Xpu( z1VhVSpz9=$(|i9_lG5`HGA1JX0{l+Ii5p4KfbCwX zGSIw+no~`Rh)yvz%VRESEmtr|mSoEWV8(TihO74X@X&ATVsFJFv*eA#CTfgWHW7uQ zc=F;zm?{u|_LU54`VYn!$phqOjuUM%m!R#Y`iC-kv}}|efcPP^k6@}3iCA{Febu|S zm*PmjBTSI=uzz0(LiDf{#-d-%XRn>C2f_bM{MH7r4rHqc?rzOfpL<4jpL3ThJfvebS=1g}fC*5armvQ{} z7z~}vk7Cutru*%N%4<@f{XbHiPlCn+%j@I9NF)Ye8m>-#Z>f_hTVR9ByL8nS&8z_S zXf{|P$mVxdQxO#)WvqN~4&a{;G*v_FFFI7T8p7*TrhlMlm*gF@RA6;#*Fh1Q*qWOkWfpzU$Pe;$bK z$);l$*nPIv%%=yEZI>lbcZV)A+JnMEuyqJoGNf>k4oP)dj|@q-kUqfAIl6qN)K}za zrEsIG5R&>p({aQQzq$e=q*Rl8chk>Fys{l#c$y;0oz%*0y`umyzG2X7Qj}y?cp)o0E zHmg3y7E$$~+ztd7{5xXBGkmQpKzHSML!S*l4GPa#hwpqn!nyd(gCla6lKJ>!;pS-jY>a=L)*cp_aL_&* z9+Y>geZW=C{JlBWkCBK;mz5BuNWg)G9>*VtMq%#Q^ zrUGesy-@WMW2${Gw7O*V-t1IVAjF{fmoQS8M~o9iEzX2~fKQ2rK+xn7TQA&tIkhV$ zTLo1&-gc*Qb{$jteCN{gsmXB%3B*KTAWFw4ApaUz(wQ_1vcBr@@YA|Yf{kx_0ykE6 zJ8!;BcL(r}kEPTu8FQ)SvE$VQ9}H}8@4_yJd~`~%$vH{gd~|}~O+yI9vcrK=+fS5G z_+kpLL~N$i_eP=HS+>PS*kJV^nJknd4Iix7Wa^x&-s!kfisG<8jdi2T=f3mZ%%%Oj zJ-xCK2-J=$U1J*_ufFUe!{i9RU4pDvD7~9}*r`N> zA4`91cRss#Z&u!~N{H;6%H_LseQjj^=QR=4Z}=&lXKJxJCx00RV%V+E%7YegIA`69 z7*~gjsBGi3J0?Zp#3NML0=I`*=X^qBvqIk|+`lz0MS)C&&;VaCiMa9e@GJo28ZfIF z+YtyV3g!v?M`RhvOafz>$!CAp6IA&4So7LwtD{X8^XUf{0tH&j0a44II;>>5^(V>K zX#3ozYhIt%4NByW2;ey)C4Gm;GsK6N1^Zcv%hHxVYV~CS@jYX=aLm!JwUVEQm7PjM zu(C(Qvi|S-%b46iOty|DQRi`2)@Mq}C~wRnBj3&CL~1_ZuT~Pg#-7g^*x_~s4DwH( zJ|I0>wRtOcfR;gozv}2b7hH9r#d4t>Q+1|*i;ZQ=Mb`aEYC0o;kcGsH1i)Z&LDl^bFiGpcBnSl+@JX#}*TPYte;h^<58;=M|i;$J2*ZF8?<-YB` zh}7;+gnys;4J^0<#q0!H+^_cJXBRgcgoa&5#lU;O7O_++6(1;F(xpK>{a6LdnPH;s zDv#i+fu>(RH?6Kw9+LgE>C$<*Ls zXWDZ)F(JXtRZI1i$P-(Qggb;ML`re0gW7~yoCY>cS?hGPp{yLvXnZQZ`f$R~K5dvM zmpeJScmTzpNZ0%%#YtIGENy5-=tkL3Ni58jVn`BIoOE0XXORX5$F`f_2vPBot@{%L z{kfx%6ecoTWgF@=&O6M`=fSw8KLyjBrVebCik*?RV5XTUAu#DYY!DT6m%Fo<==>>s zeFM%3TU~o=(Zuf7Sc@ITE`l&@qpk)veFE$6^>0@rBA*Fn8dn=mS6%*LMMz*^O&wTw z38{1bSr&RD!9y~a>-Nh{!lCV8pFP*S_MZ7nfreYnR$CJW9#L}d9|#j%$-9umD`u3j z=Fa%4FjJ|c^}NTc=l*&d!O7WwzgjPlAOj%eCGqo`{7*9sX z$RNnlMYPlZbuG{9&>XVX|Bj$(*~o$CRiP&tkcv>~yNE>N4lY z;q=}|aE&hoGcs(_Fi~k6>iT~Tu>A6O($}UNJa67WCGGiiNEl5nP}js~zwhDl2`3JU zhUALMvNU*4o0!Z2GQ9hf(Gbb^i`P$moftG!+G~HqI+lSB1UjglSX556(o1;)hG{dE zY7I5|BCJ)|D6GvNT+)IbcSq0boi5gbr0`)=`Tk(LQITj!N(f_mWYywL6bb<5bc(vcMc_aWh{My9F@8y|FNwL5+`F}m$Rep zRy(+H{2_%ZIS7qy-ZTW0!T`OgdMOevY=^O-X2gF=zkgy8<_q0Gz#VR%QrwK?uiQK` zu^uRbLb}0$f7XzP=i>p94$#w0Qdk%nT$olvBrI)&aO82g?q!}cYspm)ZSR^L$Q)l4 zxpCNZ1qqPv3i?i+tHldU1IYkpKWQ7n=t?=1NQ-{0{EJp*Qb|3%zF>)-1N3<_TPGzQ z>DVS;v2FFzx^dHHxG7r_-x^}>AjShK`XG(mpxiO64k9~rTeFS2V6LnfNVF%;rMc9L#y%C#XZig^s3-V(HDWh5 z5wrTyo>WzXkQ#XCfyB)WEAhFs5E9TOI!6W%Zb~`JBxAhZZG?e6as|&|e+}b~{KR#R z=|BKiS`a)S0=F!P^p@awrgw3ED8Wvzsal)4=$yaWY$9vPJl?KSUkTQIjvS~wG}jew zhqdp3Z(mLg!)y)RfLXJ(0Nu`)Vx)$R92gI3RU zpNWXrK6iJa^Ib#>7zQluoRfhO7@KA35cUw>X`iGyDA?q} zu?};pZla@%t$$FCmu_GZM znR_A!xryfk>J1U7il6+76-}fHmXB0XsD#NFl-|_YKNRHm)^Ep2olmpEgxj!DKIV$< zkmFVSx$FB`Ptz_M1V%I7aI)6bAA!HUMhuXVb^}Cv_;aL!*S`LQTw*jIQpeKQ4e%?{ z8J5ZJ0O`bLwe_u>>QPqGW;E_j_5NgjS#y4FIQUC+)vb=86CmnC$033C(R!ve*(5)* z&gSTdzjO0d9T^)(OoEkM@LeND*Ws*`U4x!5&MFQGd*S%2zE&k7I^Ib?p<;XJy@){F)GB7xG^1*Ev>6g_^#m8pC)46=WmJjp>{p8z42lfnTy)%aIEd*7#q zLCq+L;5^srPPB-<)f$##5&FQZIFtG$zy(4RN6nU)1fBXX1{_Q6DDHGHa7;+7VEaR0 zz7F}k*_I|QHF#OxpDkqy6z5MkNh6$c9`L_=4bE@qRGOEwFd7n>+Tv4F*Gv|xz>;S~ zxZr^J2(fH-TWEofyV@6;AT8&W49=ncRx9W^m{FL9-QS<&QA4o9|56U?YFDv9SE3;nJu0(3fFbN3kN$)#Su0X!Sfu<#4x!@g|0-9 z52Ovu8f5IRj7EVp#+noHt6Rnb&6EU!5d@MED^2ckg>L!5f||}rWRW? zg%J8mPtSwUd8dV^AZeH)FOA2XsH?;W8CWOEuc2}>?222z3=Ists4>V;PeXwXCvPEU zOwX<~Wc}1)S^-nbuv1fgkd(ErCzfy-20$xO|L9vD?q(DJEhu;uE6IN}K|T?Y2B%}d zO&n&h?yt;Nek24$R>Pc+g`s&A<-W)%Ien;OnmSQVhQ35SXB zF?>;z=PRNKHilyvNCz+6Cl3qL%O_|Kim@0=2B{NAk$+7e4El$UJRX@efkS-+2w*JS zPbh67iJ3BPn;@Yf?HcU31#5h4fi&8A+>;B?Y=hsX%8O_h&U!OS*md(uF{i`)!ihc> z@8(F-q(Qg=79gNaaNr);RELnkA#5ryjHV@sb@4BDN<`UbK~<}XW`8TCC?s|aY{T~X z3WQLsL)Xn9RR+aBE46IS6G9#g4AZonDiH?ncK`CBv< z2kDYYdK_!$I8*6|n6g3` z)44KH&c-BJ@`ftm_C!U7HJ61muoi=`=+Y{(^I^pDkVq&c_hprvGP=! zY7>g3)MCS|mgp(CVx-hm`HLLU@Nbrpq#uOS7lVf4nqn+Fc+ppI!vpJ*(>YgbI5-Yp zP{xgMptKy(*&hU<7N0Wg{y?QWAA=*#z1GjHd5G)XPYt=!`{Mnwb>7UmHvj_reOSa0 zOaZpXz`)t5)S^nFCeUENQ8>MC&Y($fI6>pq%ta9z{$VmLZ1NxJ_Hcp~6j`?&2MLI) zAc7VRg;v!pJ*z6^Crs8r29fudp#^VGd-o#OiRZ8?Pe&_fKvhX)X7PluIk*1EHkBe; zoUtRHs4NC@DUWJ_vbNn%jPa(k8|ix_{7e~^fO2FQ_ZT`tha|v*IEqVKYUEHWIM`ulahjDEL0fxg&+wt(yWF*a{OOP z5$it+NK~JC4pLmmSIai1tFgx4&9mJB9v}T93UbwPGptQ~vkB8;n*g6~PPw>Ap8%jD ziDB{@OO8_d>-BK$qMMyKta55Py$VB1(M&Y7u%sXbD-`j2>7+u(Ju9ABH#q#;^lT>D zoSqP6OnDiJ9Gzj(tvl`az|W^(?Mm-cE2-a7-j3UA&8=t4xWsnN2my{J)u+abu>g-Q zXPox@sQfo(dCx=pf&AK@$-4%&i0m=dtpybF!Tyl&8yL3npytuUGe&VIElmIg%+p3Z zl3iHa1;ay{Z2vYEwK|Dt-{l~S5yapaaoy+orj#i`^>M{+9YNF((A2aM?UZsMr!&R= z5f8rzM$3l+aeVb+Kp0kd$5gG)!?ogK{)A*k4m5;S4zV-Wf9Uc~d-BKzWKbh8*i&NY z#QYh|CfKv0`weAzQsj%a>Mf1hRWNa=fz)Nq6OHS-ey6)B<74B=XKwFnhlgTtTC)|I zyUSjCIOUzh+Ic#gD>64ID5MlP(Y8*`p^nRUy);ySa**TwEdGytK9ka}W;&U`iddu?PPKsh|lRdcE#*4ii}tLG{3}&Yq^@0vr_l)ThZH5r>LQg6?psG`f7aRODc3Ok~!DJ=?=xe zN&--gs7|U0#aP42h?uc_Pxcf>udZ)Ux3a3=jHhH|6%LydSZ^+2n( zyXBzk{i>)all8~(Q{03{g{87(bGLGMGz7%778Sz+AY0~H4v;NzsOg(EMX-o^y_i_C zTs(dO0_Jp3k|=I-lM?o|a&8miPAq`$>KC;%ji+%5#i1LW49x~KAhh&n8_*(gMC~0Z z?nh_~4dDg%;&@hj`bZ%L*OY@3+xG1ctlEHVh5zlYa*Mm$#6L`8Gk^D-> z%T6f%`HQ$+@f`MiMV~N(xWt5?<%W3** zgO>vyy!MSOPdc!EdYUVRAUSV=jR)@n>{nWehO4Z0N(SbcS(HDHsoXbg;YKRA^Jn=< z#X7p4X}WdVq$4{aKtSMz&WJPCpjjjn4|r$-Q1SYZ_R%kS3c?380hIm}ScT3phGDIQ zZ@2pczVzOHOi|rDLOQ9bqn*b(D{}O$nG+@dEEF0Q$EVvR3V(p6fUp3j@{yO|iyWjR z1V@!wOw`}81=rn#G1{iZYG(1M$Yo5y+MauID&HQYX{^!98s*@&OiJ2b1-J4Tjx>~4(qn5mV8#j9QCV{P7Nmwz=z_gQI6OE_!-*?QKdL)LP|#2G4`J`5b=EGimt)4||rA;_T|mT!DQtio5Gd zp6io&I(F%r)FI>eT@F96k}v~;7F&to+idB`^Bt>g8f8X0%V(4|P>))bRek#W9YW!a zCDeVTpL&h8VzuBIiyuB;&Wx9ED^kG|x#J2obvILj8nP_>6RDNEk-#|%68Qr+ptV)# zovZH%x?gEZl4Vsizv-r}?vZG#t>(a1=N8wqKX0^ov~kaempA1y3!T&OLB zLiT&((DX}huo4S(?k~Ae=GdOSo83&(3bk)qQkGS%_C=_b?nnUD-Uj)lEc0zDCBib_-(*?yUrB&d$7kn*p6U{{}rT&*7 z)Dhk_KHg3f>-}*HDi>JYAA!BG+Qi!Dz?qm_?xtCMC7sens=p;Z++Nro%UFR9n8-HB zt@vV(reo+mK_>;R17&%>CO5l0`CD-jLE(#FoI&w`vR_dFg*+ynBx}K6jfZ4};7UGM zH={d9Q#v%`Q4s<{p;+F+z|kF1k9{v;xMl_d@rqCmW8(zWK;xvj*N!SEFk=!yt5^FJ zqi2Tmf+{Rz*cb|YQKWm*$pT`0(6X0xnbAc+c60fJjTI*chqp?ntzBYXpV_q|f(nmS zr?!#x3IEmgkeaTiaE09aS9nn|EkvOz8CeqOa2qY1J#Sltiw z__@K8uE++N@Fb0KZ{2l!8r*1;k;SreT{=0VHT_kNL=wW~ey6(+&$eogwxu2tAYE)U zd%%bnb#Or%WeamRiz?O}82EF3L$L_3vjrVgms_*X6C)*$FA<7wSMEz55i?zumjI%^ zM@wTSv@blHK7G3pT|l6-EH*bu4Yf_B7-RU_ z+KfJfRL3O4Xm9+fg6iHL%t09@Vm(=*#!@DWO4Z>xk`iH*x~aV zOH3$DFi?z1fu))bgINpZUK2rer4Hxkz}+jrQ+0=~*00hA1?ybf-B7d!lCgPGJ8l2d z#hRH9y?5W~!|F>o=L1I#xcFnKW@X_W6brP%>ZTHBnho&Hx8XdB^9?vAE)I;HRBySC zHI^_#qV@*I67~sjY753*R`>VF1okmX7!xYi;q&MAkt{Xvw3rSHu;80*y6XYJUfnI%{+>Y9z%Aw`nB<{4a-zM8$&fvi7}^Gr4y9k)mSa&8T|(a zR|qvsO(Por)v^ic=$noS56$SHA9I#*+`zzEuw2yIY{M4dc=;DH%9NK8}{bvj8GX0?rw! z0;1jO{VugodD*r&w9kTOD5h1b7$ts# z{vgS9ehap#607k>!^5n-@9GHKjE5`Msi8;R6E!p6$aW-Pvml$(Tra}0=;jATi80`JM+ugp8OdSL zkc~Il+L$5?{^wqL!EB0xoRAH9=aZW@Q!>sA=B|iaClyihNs?+pA!=43ugf6S>M>!x z^t3PkYVGVDI1q`#(KHb9eSc-~@Gqdo3+7J98KL}5t7v9kq-?2qbZ6BgOcCQgH!}Jp zorMC>IV>MFgd1>WF?8({K}RO0VA8WqVU@GbOTxbj#kHY_6H^HuIke~%FGz{WA#`Xa zc!e7UeY?f-T*b`JD)w@}dc>nzII=V`X`Y@ZsXjIVX!JO3_TX4c#bhnjnpm4QxIUk* z)Hb7$=`aU3{jT0jM+kUTPlE;SI#?zbR92s9?9ja%UTB+MsG|$@j0{q9`*eY7qJU!k zkTZ?ZW@`nZvdW#LU(7#^pz~P5vzqvn^?40*ihuRMcL3tnGgQ0!6Sx&G`@XRd4N8=z z0h%;BhLT`O{4tn*>`n4Y_Y3LnhFAKl5eL=$n@vwr>y`R0hwWzxf9Qri{Bu*G>0?|% zS&7kYcb!p)*v5T)d}LSAj*_9J=`gCZaG4WvFU*+ppG~&YkJ|HK0KY~fdUU5@7bZ~X z{FYbo9eY8`Oz@11F%kVT5v2(-gZZd{JexSZGW{y{X+P?Oo|cKSuY|RYMc7Gfj#L1L z6)MI<%&QoT`+(UTm8V<~NUgE%5R>D{5!bNm@wQ&DmIryNLB52C7&V&xy@)iLdA6m$+ z$-vUq)_UE$wg73$Qg0uojr-6C*SUT}X{x+>()ij*8l4EHoPf+g;6==t&g2@uc=FFT zm8D40$P=O#x1}`0`&&R59JPX(UT%dJV|lu1n42!L0aG1WyM7_P#5mYHu8fIO=5>?l5BGK> ziI^ag6fCzGzez=XNqQeW(@_*OGy;ycTc58GKi-LLf^chPb9>)!Q|fr`?xM2djms^=^3I>t(O>m#GVHNAL*rSx8cDVorH%KUDpf)}AsCDC z!)QzCIeJN$_gqi&4Sk|lf%?p&Q}zQ}+>29>J^f>nKow)?Pf`^91*GbuTy;HTx<#iB zxH*PP`Vp;9@v{_REVp8DSYml!3Fop)Ev-ETQznX`8j@3(-sBuTDcWf#aCNqyIz#W# z|6pz4XvZfNIxXt@oNhfBpS8Q3F-Do720_AH(&y!9vhwhceP$*kamddbVjzkxubC9o zi9Q%31yC)voS(8l)N)LvS_!x-lST^z4~V|bCG@gK*s5|=QrMVG-S($Vw4e6kq^u}; zU<=U*rHuLh88^FGxy{;q$x-NKr>nw2fg3|T0U!sFeWl6Y@9zT$XDG0I1y@zM?QJ(B znDFtbK|?s^@W%H^_He%{Nd220m>b!x@;dFe=Bc+@82tcfwv~zUe-B$kU1q7$=o&mP z`D7q2T7V^bC1;`EJz^!tu`;=p!}y0fxwSD-GtPB`5{(8UPrf?a01x&!=%~cPtMR6h z<1kGg47@DUZ9lB08nhG}&+vZ|*GSEd_XbU+oNeF#KyJ;d}Y19ytKZyUh}zQ%$`BPV5_AG!Jzz&ugMUGj9S9gmC6sF zKdGupE}!1BXKr#bx43meQ52)cVh8tQJg#K3fL01cs~&^94UVO*Kacr7A(V6H^s&kk z*gA_&=yWj%mo9diVQh=skyb$;GM!1R8WEyThcPC4 z@JB17&c<`TwHUoZF0f_1TwA)f_S|=0i>b<%E#ttp_TRb)VJtGc!?w9k)i|cMd>W^h z=+<1N--U#_6e(Yy4SM>DP;K{bDcxEBEX*9Du*tTVHG*zO8iGf=#kTA?QQ^MqbkBO} zwy-6Igf5kXx_cuup=3a98UAj43~~<*#uv=EQmIQN+2C8m|sbt1l5lFkgW#9oEC(S z7HwPzR<1}dcp@H4jAa3~R+cM3xO~cbyrM!od*vD`1{Yp&%c2yvUU~W4#6*7Q&Y9_% z0${76$YKaM93WPJRsk)#0_He6ph!Kg4+_%X@FGea;gm06DOfi{JY86)uo@%VX?Uyn z#v_md4$EWL#&L1XzK-Z0Dh4Q~Y@i5rk}+0hN)Y^I}Nm-LpSM3MJ0<_VXW;S!CH zkzBWIl29zT723Q{BwRkm%{n(}6vbvVLXi*`Dk5Hk%0hKbPbAdI$y}k3US3{bS*dtQ z4O|run(j$2;7_eCaKzg8TDb-rAXlN785_&qa?6%tDO)V2DQv;PB$BawKCY^Y6Ro;k z@*AwDLU_=kqj03Z1Ar&A(M3Y48rKVj3|%a5G+O1=YRs_H1%{6mY*PU%v1Mnpxy3{V zQjAU@&S)4RU2;%hvMeD7#mOLevclY zu>vrzD%!mub3o2k17ldjqgNOhJfS`a%1B6<9m8o0p-NvBgp~C1t>;u zEcgkxyK1#c_epQDAWfc% ztcK4#Z1F**)W2Hj*#F|Zwf>$htdCMf*UR#7MNh^<}R?ngv zjMIPFrWqdTEh{U7q!d1%Y+~F;T2iDzF1FL^el1{;xTJ_AWtlGM+Fjq5uRZiCJVb8I zGVI&JT0G^hwD~WZ*Dn?``Fsjs>)N$-r#qmLwZ#0*${<4PUy(CLF%_%is}P+#cMZ1Z zzWe(29n&*2g`00)fKU-geb?&Kj*q1`BbU$-wHJ&YFnbyRLLq;9nSh@VrCk7CFc~QA zs@IzaikaW}&6Z{@1X_tL4z`#T1Qw0ASXQ1-X`{|%5G*AoJrg0Wuc9-36*J5EIQ zq5#twBaA9R^JbT-1 zTc;-TQ_}_dS3oW)NOa!KT~r{B3R-O-HVp$pg#%d5$dUe>n=4WL0>D~duNm&(dcEFa z#Dq;ar(BbUvAkdT|V>>`{x zRb7|8PZ96YBNZwl!5l(&gCX8!&>1Sq5_wiMZUunwMKU>=2iRJ=R=IR(&Gn83bTff0 zY(Wq~t0XWizXTVIwY4g2XU|+Im9i|u<#k)*(YNpG1s6sRp1KQT zVN?5YC^Yj0kqEuX0J*Bw2EZ1wq=OcI=~AAa&P1M%NbNAlZ?GfJ?HVVtz7TTnrNkQE*Rdad9<=xIdS~#ODE3da><)++A=#=+`fG( zkx-E(<3gKa^r-I-yAQTLwCK#9uJ-SkXm?UYi5b~nf?Tkb%T?fCwOW&j10;85Br3d| zCVy?!q|Bn&99PN(#RpNHSp14{KRK9n9eZDgkl;zZhTLCSEEnj0z7M4~4IA1ZP}LSDmVr?-$> zBUt2CVvU^gF`B7E!i}`$tQh29~YXe!*@a$@1;VE2@LcwJX{TQmM zs47X-!wuJHG}qVb0B1050LU~$t%xm>Ks6BjVj^-logyh!TJvZ)B;g$dRa0$tm5% z{^W&F((mhaohGfMxd!w%lS#$n@%8oE%1Sjv*ovzd_l#Ejtxew+Zk02qufTTf*x9l1 z?5+D3C#Uk$(?xn-bj><=2-d~)?i8(pbP^feW;y*>#|&B45c-J46eh2yi;NI3wt#ZA zbYNk2O(VC$DD@wc9AKOoZmxNS{Ny0i%v(ss*~~j?eFTIOgd8q~it>`8<$cOb1O@w6 z#Cb7Gxp}7s)u{4mG;~c9S{e= zmh_&O5Odf7xk|S! zozt5zb0BO46f^Ryn&pp*oR$f^jzOr%K}eFzOSt2e-ja2v$VEtHS8F>H^9Z@vLLheh z4l6Dmwvda4OF%B9OBpUf4@r+H!QJin;^q!E1S!u*Vn5n%hfipDBgU7b*m}`~T=8 zSu!0iNDVt+@uWSORAI~K({SfCo2|8Sty*hP&aX46vgDH9mT)0=9fMTm!=$8ECovH| zH1780Dja#UX5_FBq@gCOQnU#W!pc^vWtR2!u-=Fi7N8SA&^VMy3qYMF}{g zrRDYKpFauP+}zmQeCftLbK?_Px~d3&1>_nIFyJ5Rn;W6R0^-pCEN8$-^YpbEtz;zM ztAJv3ok%fYi)Md>&WQ%9Fztd=@hd4*g(hGefkIrNkF&B`;yWx(boUNKLSGyo%Vx^; zq!!kEL@W?4zJT01m}b*doJ!0>V~w@3=x)Y@61uLE%AQ;ggsMGlUjUDb7ZW1U`x^>2qlWTt&De1 zz&jH2d^ZiKi8!_k1|9i$Z6KJ1#MT=;a;>e^*Vf)Xb@J_EF#|#39q-<;{e~$D=>)knJ+R~) z_l#^p?bndQ(*`1xwDU~@Sk9OcI2R2V0l5g_()C8Yg%t(_qJJr8(2S7a1!#MUatc+} zctToF6#6H+#)*sy@gbfSf7%4fJHzFyQbexhKGp${lug4pX@!$AVQkbnb8|+)PSPjm z`>hLeqpF)tY9vcZ}`sH9X-G zEsq(I(GljcOo;oCdnKcb_|werdnD%DWw}aIRKEtJlfQl$^S^g4DY668 zHR8_BYyq(q=;>SoGFE+Pza!?OM=Z&KX?-!&(0PX7ACfBpPZjB87{jz)k8?rX~WHILPU*VN{&H;)CLzn4^^~C zQ(Y`zga?gAlg(4cR_q|lbgJ@fK}I=?mvxNfSTB_~Glwi*z~x+0w3ZGW87?>EVxc98 zZ>U(!+?T}`ZJ!KwbFda>h(|8uzOrd2@-?HvF`r9LOe89m%<^&tz7M=xjoF3XgU>a4 z^_1mYWc3RdmSOw;_utsQeR6ubxc8>{LLm*HOa-X)yat9=eS(Q$;81Ou)Fw~5_YyDy z=K|P*->k3KtJMY#7!{K-VVZ$=T}IXK&(&bwg>X4a6cLh_6lL|P zfhA^4!xabEi;R5zBetzmSyEm|K?$5oXuY8jjVM-C-LQWk4hqF$8eog6%h6Hl?Jk8N(#pAiF4#ua)>-CrI|vN>(V8x$~k2dT#jGLaJ3~|Ccc?s zQA!^Sw;T(__@K|UPQ`q^4!fnW&eJR7FnG$DOem?Ok(x5>l}*^nCdbCISFe^=SF8T8 zwXtl=6}kA_JbZz@`NrF@z4*eZiOKv;H*cAm%uml0D5z0l-ZOmY8wF2jqfPrdJx)CW zEPgO;M6;t?9=5iY(t zkdtuH9g_7yE`dd?y$mg>E@~Rg{p*~}!U~D`!bF~bF)$Bw((M8m(1)v2(a8PimK%EDMZBdBw$=!CEfi9gduEZy8v|*mwH2IJm}>H!DcVt z7sIYV6djYfk5QJAx)LtRm1wmy33ISrC#)MiChQPZ=RuLJ6tFqW!-!0{umWMVl1M1J z>1m_0V_-L2DwUX>i^IeQ-g@oYIx%a+eF+k~&by;v)-I+mu8yu=T>}Vy{k4mQLi*14 z?%KI?8W?&q8K)H&eFcQBcfR57eIY_>1X%w01!T0G$(2evRp=})tygOe059FhV*t58 zZe`MT=Ez!PWLbHMJqc!nqEj1F!KF2ZZmF~sIWcdj9}NJ}5ZC7eF=ofF z*D1(~Qgs=&5E2L%o5^Yn*pmW3NoveW#UswJj8|jO2@GrtU~6m)g2eTe6%uQ=P04Ry zZmZ4xfX$`ht5?ggq3@x^#fjOu((c`}V`CXY%o{Dk%}ooUG94}IG$*gKQ=Y*fMfk6^N~BzCmK! z^cGh7I6vD`B+MAB(ew3B3IKlWS}|t0;=5X+gZ3hYg{I2dW~56>_R; zaw-oOcHJ;UrvYQN($K6WInz1x6h3!gkNcpZtUuGF--Mld1T0Do%A^ZRuJcVM{JZ42E3P zyBUxRKzVX9f6FZk@CICkfLP` zT?R#1jiW?DQDX|3V^$ra6O!zzMZ_;|S}aVr@sS=s&3`2l>dZ`W9D>9ZU|a1Pj)_5H zFPesKCRN~s8sGEj%9S!~FTM0up^)0UcOGC1@GBNm;&HODID|cK1_o7378B&j5n%Ow zP=8bi7?EKQ0FlC4xdzP3G>xFMT(LS23hQ~g(+vV4#B(&+=vmiWO%8diQfJEz%Tcq< ztz$Z13)vzsBV0`;F#wj=(-?AL5qfn8Y}v&@m~*K&q#<#m>Y!B2td^@w*VfAAn*V*g zVM6&%-V}4R3|JMw)-%uiD4C2;OyqX&nVp*}&CZr+RS=cVTqk6Te|dm5Xc1s-#Gs0# zsVTIwQfaj`qx!l^7m^6)k~+@wO(-0Miz?=M9~)A3(<1UK8h7%|9BDoa^NI#XS0URA zj0$&Xpq4k>Ff}(fcEgUTd_D!Y2PIsgAeRpiY?PKF;LD|F zS$draur_GGY@`n+C$-hpN@cyivP!&JSn0K0tIQEAO^UO4`z=F_1$$r$RD+)pqdr{| zx_hxDKfZ^n9V&{1i$*knrAeZ?QmA5{NfvZnOt~W=(=YfLvRD^8GF(zSSX2K%7GaBp zbS|45U$0%ewnlCHgWTvF?)?%Rx!}VAczX5K^RPYlTw=$LX<%DBc21{Kaq5QT<$KW! zC=5ANd7@Rsu!do%sxmf~g>Af=gMe{)xdQyCY{?10w>~%u`}+x8u9@lS zLO!3iI{mbq>HZ)P&Y~g-jT7M&L}x6=FPfBcMU*^;vcpEC^YuMgXBjla zNm%WgAzha^n&f)LQGVzHB3)> zQyhRuFE7hZ!1h8#Qr1a^E!XrGoh|V=Ss8?Qw8ffV=yp1cGt6QvhBXeeRrt)=#ts#& zavcU|^l0r=nDKv_Szg3pCW3@x>U3`blT*Ro6i0wHVuM+=)M^bH5G`F>gD>HA zlI_y$R2L?_2#xhYQ{Y470;uo14g3<`EMm1VwjbmZD0_{3~zT9e60L2WiQCpHq?;S(M9Ht2ne9;UQg~4-wiheS9@M-)J+hY( zO*q2>;bK7|ytYtC=klq_dM==SP3Y;ZfNZPBcf(v{3XGEa+r(c~i^cTbz4Ji3wrm-L zZzdSM3+Q_!Q>f=!Lg&jPz}gG}BgU!e=~yu`ATzcta^X-RO%Jb8Bad9CPhW-&plavNX<~7+Ylf0>YK1B~7k7s&VW!DC z)j&jmHS)u7_)AO7&l&^#*nOD(@bnd%7d5{Aj@;Hj?-K-F(FR04Fc^WvGuFA$jgmz@s!9a9XF5LSWML5 zfQp3-Y?Vq5*cM=SrBV+*Re0nI;^)^jY=zjRk(Z&au2x@u=^Sjpwx*^Edv2TqsG6B6 zW->`*DMt5SS`9HRg}N;yi~wtM0ai-~hQ-e#*EJ%ljmYJQT^FF$`g*;*TB%eU^vjkS zbs1ez6;)N}*RRui-cBE3zOu*WS}aK9Z2Y*@Lq^kV`MaQrmtadUS#=;6=iRIe6^mAo z%JOQOk@}*M(Zoc~5S^~U&rssT;Y@F_{V;^RbZG^)mtTGhPHF45Nr;zs@0o-9A)8Io zqD8N+KO0i*?6s2!uts~3Dl^ioT4(*%siC|7pk+X%5=qh*m9i(-h>sc*!g!DW^E<2X=fGxy(Njs3s&SB}6SQhgUtF7fXGHhnRX!Om^ z!MU%kRY`hlrBV+jyd3a)V(4#WMvKPHaq{Hbu$?$@c6z1=p(4bLa6#bv3~nSUL+!|; z$`xNadbt-+$~%eN8b&`J)FB=eAWRQhS7xNE;!{&`V?S`4YE@ud&Bj`}#!^bumY$`m z?4D!xmpEpyg~aBgR)!vlJy{WtCc14!Y9bPAsDT98myKL}B*@-~pWZrOF>V5=9i|#= zi}YtJmWYE5gogmx*RHNrs*Pat%CpmbpV$@(6}%Mg$bn^_eDiJCip9+Mc0$B-bv(#wK)cmqgIR0Ug?_F&G%v=sphh3GMNM9T3Ipls7q@= zyQnn+RxqFHV)K=Wp)lrF^pG7q+R$Ty8Rsx=ur-9Gon?!F2#dpy1lbZ2PUHSL{foQ#?%;m&B8B@fUyO0 zczvw~)0iZ>S_G{~8lP)2rb}$gLNTGUtOZ-lSKf*qkudEYettp?qq&I4SvlxJmkpa$ zi8PSML9QB{BU}(8C*$c8T)yHemv`$&uj2vwZ}q8Hqar!b|L8(4pW3}=7JffB zSDKnGP`L~<_F-q;W6G zkJV~}bhUwav89zQgM^rhg$5O(buyN|D6PJ#W(23({>Tz+@%eIv;h435UCeOtj?Y-A zh2-*X5)QJQ7Pbi&&C084tW?V8^Ql^`Nns0urnYIU0kf_C5iUlZ;bVr=f9|`lBcl`y z0>-_2=O-s~GqXi{1>l>kcPlPAc+~y473(b&0oJGvLw*HZUFYM$F3<{40q9jM=8__1 zaU3fHqP=4c(}*hRdadb(-HjO%vWgidp2AK$2dmBpBhHgSyt%CuzRBLOB|x>S2)UwY z8@ZScLwC4_>2i__vl47wXBjRETd<#WCTTcX=OH?#CN?xCYG-1zNsx=rb5$yJ*e+aH z%48CA^J7~VC*WtXn2yI|)F77^qjnbb`G$T{_cMlR5nzorW-%SP(2c&65m&KMg%hYf z9_<|q8{DT?udcP4tqL){sTz3>-4J1!Wz`fDTyy6_FKe+0kZ=l2z=Z_Z;%A0{T+9Lx ziB*rhb%d1`!!{gZcJ*w+Wu&*_adl!cKQ@+GCuXOWPj39pANUHkl;KXXbQDrK2_pzrF;yk=ex@sbCE}w>NYN}CQt1VqyTPxQZf!yT>3R`_zRg|Jd zYUOnwv0SZI>!iO9U178=QccHXgk92GoT-D(tvU*D z!?*UqE^Cfl9*tp`^(D^-h1lX&n*HT3D#Uc&_*u6I*Z7!PEM_X}H8@A$T)`Ccx)kb; zZm1|li-6i!ua=+tZW$QXmM!CRbEUy=8=2pHk*L^gzx*yEa~RL<_xd|JvO zWW`eGfi1R$m_8nhoC})-)0!wk0S<5UWvA&$Zl3&;G{wlKCMWZN%QT}Gq@B-ZN^(iy z1s^Z1xPJcmlZt|O7)96HwoO9Vn9d}OINDa~NpWANnXd@2Mm2lYXb7GmT8DxLY*gXI zV%R_S^N9+5R`db6CJh5$81-87>b3IPT5V;yf(-SOZs;~8e`hSliIkNI&0_f|61lbE zP!y~5T4-iLkxMA+(ZoI%(pzAxOO82Ql8Y4I881&HNQSF4maQ7Sj#gIIr6t9oN^VGOR7qL9u2tms+~rih6Aur|qnSx*J-T#LZY7*<@x z>2wVBK(7MMw?tB%oh`wG@@f?TXk~eQwOp;N*PB|4iXseEDspy; z6f3zaHN`-dQM@%@b&fqDt`8coGDQeU4T9t)#TMCfHcOf_Sob1O%HHL46t`e&!vE5ocE>!|w` zCV$POQ?iuHr;yP>7H(53V5}`KRY>D&jW`_>xDk6_>wJ|W=Tk4L;VqvmWM+k#!pc&I zF_y&Us$pdg2%^m^uBJ?iA1wnY1EA}Y`Aw@h7T8Q#b`+xEZ0D$QMLR|`OFs!PjuvBN`pDl zgfX+lK`eRCw6Ai}5Wl48kYDgiigd>1aw*sVyvpSo?Q&GBH3EL78wgvdKQ{u8T<{e| zOBW$vgp;KKU zD^#T2ueqXYE?35xsq%yiW*`JU@7Zk93>bBx!&3xUBMDec&_GA<4!|+hP>L!Y&?}!Xp-m6ub_P;j ze^pflLMnIwKO2qKl`CbM@LFA|k`7iaje!^9;D!B4*O4xoI1A6UBn}GZP)WA;l0{xv zXiv?#He=f~P|AE^yGqf3V=9K2$^&2lYyo&xs~xN=Zg{8|I&w+03oaDZMgZ-CYX+g> z%xn?D#)KI##%bww1X!atFcxl|;0_HirBg}b%HV=lU1cx)CsNxf))vu#3Ie>&&yN`} zt-%bxe7Ouifr6D+E0*#TQM**#&OUK)!UcsOD`f$HX_5;j z>d*>M{X@t;1&lDRUM<7Vx8GhlapLTjE#ud&#v{NQz0qiBEaMKhZouv*M9L61l%l%F zjgE)$WL*z69#{huLPA?+wpI&liMR0!i>PldT}W(p zeeT@V%6cpUtdUG$31leP%^i=^-l({{JF>gm(Vt}LdLW+VgJr53gAKlW0lBDp;Nr#Q z%6ffewPNZasHz_GHqCZhFrkEyHQ2CHS6GU`xsq%?y0n{`amC&yA>(0-1(3RJb#LV# zNkT1`P3Cf`$$E3WQio7+ZLJzmIzJ4A3-z-M2y@YT1Xv?B>UE7b?bCzKZK4zq*y{D>+FG5KE7og`AzWA-aI{EA1X!cT zu(Yl`MM<|o-S+l(xuJ14B&)}T!X5$9gGSkWUC8~LSB7I) zJm+FxDwV1&m&yMVL6o-bS=_ys6Xtu|=kG{r8V{SP<86vU|| zIB^3D741f|$ffwvCR}2kOX6I%c`QRN<5_AoM5cB^3>|JY+6xVg`p2yDYlZ8ci z#V!aTumKB63*HA3{$atQNUFpp99 zefx30{?57Qo-;WWot$7(e}KXjG`3hgc)5U8NkUO&tf2|>y<&h>Z2sPY;>-x8%|B}L zM1g=G3ku6q8YPNp^@ox1Xq3%mi^yJ49t!uY9;i~LRA;7)q*0AeB`aiy_vMXTN|Hn_ zT23kon84fAbONiAGnd!vnblBTU&mr{(bOL(j8>yWlp*snL+V|?sxXlU#gm$-z6Rp; ziawv19YVVR+fZR+g++D;^NlP383|+>8mh50H_wX4lhaeN>my;D^u`~?DU)bCk@Rqm z^-78`m6pfZwKD0l)!wS97N!!@nuwN@1zY@i6y&O@VPlJEInWl!3ssj)b&gsIXVCuT z0#+pn=oPOLnjuX-ujsXDp0mLO9fOy?q#52#pDVi<>5Rdkzj1aA{!ReDWXUIY8u6BuLgE5Q55*Z8KRI$GQv+4lG5PCcy!QTU0pSI zF7xMNfnLKbt;I`@`a8tpRQ zioDQPTN}Xdtj3z==Ejihh7N`6+O?3tl5WI7zGzC2B)d>4#;l}v4x`9LSWKPKLj;QR z(o(d=Y;@xja43XJ$Vxau;6>-Ctqp>9LEA-xp(iqb)bKPK9Irry(Nzg6UPQqHTT1DJ zxif&;GC?QrKw)0@QM(2Ti(yy>CE4u1#u`yhgDlANMWA^l63LN~aZn%1iOtl;RF*St zFp=||;L}x+!l>^SFKENqXD8s`Z%g*4h(-@t9^5KlFyP1ETVe@-*LZlE$d^G%t|C7e zE?~K$RSEh0xOwRnMQzUvV3~aDtYcO&Mt3ta3QNzhbelmL+bQBRBphN<>aSf71HXV; zW1~~NUlk*^qACELDr&Q+9yAm=gQQ*By%aTT!s7XeOAz$4&vH)l zq87FU)f{Xo?QaSst*r~x)dlc|fM-RfV-pjR>FF40yOtEjQX-cNSQR7jcq(q68I4W0 zUKQ$lRp_L`TrX}Z2MWu9hylE?EMCka;mn^u8{mcI@}*JS1QxfC1{~ACnoI3$VpXT(NkHX#<8)fE%vCqxFhwDYvnWzw^hs%uzm;>N}rXox^A23yg%9Az+( zVCjvd0`N=7F+@#eP9lH7xk{7ZZxQK8`>a=Fu4z->rXoem6Fl!Pe ziNa`LJNikUZi6{%FZfK@4I#Zo<+0T=8idR1)iwbi+y zlvAK9Q9!83RdwmoW`Rx5jzf9GwOkrz_~r46QTC-auWSnG_^3RzF-(!iZ~|36p-QN(shT4PeVv|)0k#Og7@V01QC}D%a{;Tu6hKKE zQe0mjWTCID5D=>*tFTZrMHJ6euc)S@NhxCu3imMu?VP6 zJm~@bNxLPgMuJQ<<Qd>l z1)+686Fq(Kujxn(5O!m9f}HGu7sQ^tJ`ZhC%v%}o5kzeq8$AauE!)b1E#(a(*BNYM z?_QO!D&Qw4iWoG-gaouAH-rvE&!IgL2{qDQ(=GyzC+CqcA-${nP>l2Y5(8-{XbxfRff!erE;0D@Y4AGMVZ?> zI#&%3537wFI?7^+X^7+i`dY10Dw{7rO$|%Vir*zmKXvDwt#{qMu&r&;J#Dw$xv~|Y zHhXprG&N|8QF;DgQl2@KOk`ZWQZuVXRm^&iM^v)=WOj(@TtsQFvGj&?MN~%2AQ-?a znMlfcntpClqaOd2R+8j#e!C7#pN9^w{PFe{rxY^aC{}lm|F4I!v4RfCNEXGqNoG7Juq#EE_%Blq!X?V{7DctI1V1xhz>I7!J`pS>dKb?3&U0q#( zDqxn4faRQ=J9iEs1+)T`Gd|zi`n~V|W09|Wu8%zhld+8oSh2eg4V?*vLlva-6)=~u zNX#n19Z(cKGJ!!BE^MO44_~|i`~pagjZTKc%p4Yvrw5)TLHW*Q&+^HoCn~t6a+Sz( zr;yZ9B@$^AqtOEo8+@#$fo~bMDCukx$Q5A@YOICw%z;$22}f*LPdxF&@6Mek%%WcE z1T0$Bs%A>4okiXU`WC6Ow&;o1Tb%nev^)z3 zSnz-UI|9uOzyXpqIywmzGUK+I4mapgo2w-C)N4V|x5_JoOAvJ8rb_A$uavfeG3NU7m;b}FJ6v)Pj)#eaX8^f+{zh(rLhjHw57rNYcoIF=v)N1+n@eej`&$vi}Rzw~Ec zrkb%r#wpMooJC`(LU|}?8XK1G;ZWjmIDafot+_zdMh(zlE1H_UT@f@uF>ldL$i65% zw(xj(=gz(d9_YgI=%d}o29GE;jE{%=`}-bxc+D5?@95s}g(F7~rPQ=b!)xwc{r)fB z+xqxdyVk76(%1LA^78Sg?Y>qztxqtlHhb6C?{OU)=b|h4t7x!6!^lCoE_9CdQwvzlTwlv*$_sPhk^lrZEe8ol|0Vf7tkwUM6QlXpn#tI+uwYM1pxQX zyFWJuI7J2r2hqv@{E5fuFP#N7{OqUy^1y~}{6%kv=0!DQ3;tpww&0N04jkmU52||f zku7}Xxenj3VFOx=@=8fG7$~L?J(R&-rB%F954Qr>OVER2{9Xb?v>fL`v9VBC_o6_g zpL=fGl`F#o1IOQa=k$xcyH1^YY@qoWfmCr|wA z3=$AWCqEZYFw08PaKX@|xw&y6Gl$Q?($=9LUna@z52=u5DGv5ph34nba-VQ2P$=ggzV_LW;<*|3xQdv2iJ&V-}&~ph)DtOPQCS} zauXoB7xnLNzJ2*JL#z7w2K1b^w)V##|Epuijy(8B8~^jaegPmm@Y?H*vuF8yVtae% zQ%`L_`jY{G6dk*3=N>=_R+cSWzH#GbVAj{ZwiSO-RY!YjI~Jw2{kvbH@<5_Z8@Igo z-p_k_wuZx@fdK&4OY7EkQ!#8@zHIr^+n(CAX>&t;gUKH2v`T3H6s{vhE&;J3lh!S_ zG+*E}(ihbzt_dt5WI2LK4jJ7w z9hEQ(D?ALLm!iXKOy&SMl=i|_*QK`R>S zm+NrCI~2g_fLy>YREXLDShymr;9`yKZr}O#3LFK>2B;!SpN8M%x+vfm^u8@yy0c3H zt+4A)zqBFOdFQvZDxI@se#_ajXRz{_&n#cJZvA6hzY5HH`swZbThY>z!QA?WhOlf( zhq{Mf1+7ThJ30Ys*tLFLckz}ZV+1jd9A5%1R-ra58*kU_*|o}F#i);`cJ=CLES4m% z`{9c>#wQ|PPs+n^6CTjc0anmY^N z+VtC@@@y@Q*z^opbc3FFgt+OGg z8J0_(N)Kd82v$K3$C^kal_xbkd}DGV;_;^bUcNj!IT=;pj730=#`#G_f;@WYmAx($ zqdPC25?m5U4Ilt8q4ZBe3Xl}O81@1MKD%Ohk*7lqfCB>ng+PzP*>%~C@!=p@Xe16t zC8Yh~>QEKvRkrmimq5p)5rZ{doq#_xhjeyye)Q1+)dVX0g^7u9_Aa2+NB?sHB&&d4 z3QZ8OHE`(Y{{4H6OOlfK{`;y&c4p|z@bED0GD$|t$Bt9Ej-%x)z?!NmpWpALWznL! zD?Zz@Y}tHTy1JIEUHj>K?_L2HudC$d>S@-JDh zupXDgLwHJa8DJBnPw_@5ev}Pb7!VC8mP;SBgpXu6Cw#=OX7CQkLYkef>!$JHq}$?f z1?(Q!&`m>o*EHvhJU01TDy1HuCtQtxLi3K|5J#Dvjbl%b4zPP>P4q7@p zm*8(FR=DN1+vYYj1pR)gbaM%z7+#b`VLDK$XhdJpwsPrlR#n1RU->a=R=f~+>%L+h z0?-t8I1c1T28godGDXqpNRcGG2IS#Z5V|Sn0%j@a(yb(skox*|z4qGvZQD|c+vnHb zzkPek=b*QD*TCT)J^A$>`g{NV>z{wFFW+6Nhi(XEP&Qh%?B2a6?~U#0*$UV?apLuT z`(7pt1zK&|v{|8G1BVZ`cdSBfhY$axuuwDkqQAQ#w?6q22>2*c7%#WZpB;}U-g-MK zKKbO6|Mb1@y0@v!B@~K<$K%vnlS$^TlJ)KK27}(bL4|at-{@=+Et#xDeba_$Z1^b5 z!ey`T=*{3b`bm;+KJ%={y$cl~X5MwXj4bwKUCmvIaR!~@A)`EPO)gs5A}(N6k{HCm zQYMkvRi|E2OPg)JMq#GS-bJ3>HQBp>brT7NxH8bBC}C<=)(NQu-9{|4uIq9c7qDEJ zalpz%m9)LbXV+(mO-MONR$-K+c(^ftT1yQq(uU>2s0&y(({u7@Qx9l5L+&BD{3J{F z(3#S|N_pB+f{3dUx`1^Pi82>d_uaRg_C_kSFWKa5S#a;Q7e*~rR^+K&hUEg*&4yXI zcX8d%Faemgu3J1hI6e;GGAtLcTq$R?(oa0$6+NC3u@Xz%%l1=Ov}c1WE?~I~tK?nO zd9Bdc+5Hpw_*`)T>yw6720jf2d(8u!Lr_qFR#>i{pDyIMfaQuEy(Mo~Dwvo^l2o+A zq*QvwVLpam@fT9jDC`23D^B%5P5v(3{-E>I| z8?V9=^tl22T)=Y08pHB>Y>zu!ioROF;iXZaN;Wme)dyX`y6HqtvLx!cxtmG~oeMik zHe6__8(Y1KGFSIpa^?coO{fwwl4V_ia;_Iz*sKdN1-H#EGnPwyT)=Y0L5Ah^7Lwe- zmY6g8q(*mC(Ru1&hGCftdFZ}YE?~Lhm;%KBORpmqKAE}58btHN%T6`QWJXnc8J25w zF9%^sD8Bj3v+j+k2uUP7(-EJP)b=y4H|h0C#?VoK`Xh>FI(@Mu%hXvMRQDtY>U6~^ c`F{Zh02Zk_W8a}ZW&i*H07*qoM6N<$f(4Iw9smFU literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/nopreview_image.asset.taml b/Templates/BaseGame/game/data/UI/images/nopreview_image.asset.taml new file mode 100644 index 000000000..cda718e30 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/nopreview_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/previousOption_n.png b/Templates/BaseGame/game/data/UI/images/previousOption_n.png new file mode 100644 index 0000000000000000000000000000000000000000..3a9df0efa941a19848237264182e8e839e95d74e GIT binary patch literal 8194 zcmeHMc|276`yXu>TgcKaHI21pR%4qCVaUWFp%JNB&M=sznUSFg(Tx%cWlOSjix#B9 zmFz7l5em_@qz$)K^nR^a)M<9!1k>Kt76 zB7u|nDg7b&sT-bVx_uN8_SGDF@**@v_))!gU*)h;(vsf{#%E6)?wfxTrSXtpx%d2l z({Pnjl}5#mH^oQpWNGU^=^d;}tZx!ssIF9BtY7tOXy%0T%MJZzZ{LsS&7uQybSp0C z?yj~N7;vKPu&RiEv6QB|Q|E^E7}C>XclNejqdOrMH+vgy-rVNxQ~Qkau!)`$yrrVa z=7VYY`edImgZkmDfhSt|Pmk?*AF5U@@F4hF9zJ!fUuJ#z;>S(7-oB0tSLk*EG3TEj zH0ykFPqe=8z0U7@x)p|{H*MHWd>uW{>Y|9L{PQpM03y_|I>xgl^=(SL`p2V@s$~sn>j2tiZ@D2CfT)#v+-u!CI+SLof_FEWUH@|k<(>EimL01mS zD_pTLsH{EsPF}0i%CVB5&U;%e2fLCEI9UumJbo|mzVIJ7)_%LJsX9aWJc2P?FuL2aNzP0<^-72Oj)@>)H9 zPwr!NOSX?+(UNX%R`J;+!Gc)qseI}77LsDJg4#*#_K}W8-63s)F(aXtv=$nBPF+q& zu5?@6omQN^tS%r+J1K3s60+6ZE{W1%)!Awg@0e0vV4r<5hq&bSol2Y|v0M8zJ@~=! zRodl%_;N1cnq8q!_BB8&QSh94&FG#pzq|YHql+oG6z5kZ?L(N2wVYdVC=J@>y>ZQn zu(5`kcwtv>@u2R?^Au5mkH5A`&Zw?ok;QTM*IQ*;?6*A)P-_0kcU{l0OZ2em0+sH$ zuVb@-kJoc2y6S&jzw)92%rSS|Xz5EQ+}vkbDn(gZUdOkM5*{pq;sdruQpiJaUhcby z^JO&oJLiA9&Sx$<=Xm%yDz_AqzK5E2uO(+bF(W}RkYb~`x8}sQTErUfyw`0Lw#u3} zM2o2kJM+(uKFuq0yx$Qn-vPuqq(IZyrJ0%m8)i!I8p>Yl~t$NN3F*JKUrxMLrw5*`ga zzEODKknH%JWHtWz5~f+?#FBtBg2n0|P$lDQdbcM!Woe+b5d_uw<=F1Q$R#JdAB=lm z3A<_+eE;a)Em4Wt5oaFh>{qWvmzJNha)^2rM24?=>E=tk9>ar`y52!=&r7dQ-6-pw zbaI1Y)Iq>I)Mt6C{bG;p?1mc0x+BLIR9TvBI1+Xuz<;R+60d*U6uPBwrpdAXkqTJfPg5m%RqFM0v!Ho2hkftFGtTxuAOL zc^wn0Ho*?&jhxFXUJ0#5sjMob(AwTmM&6tqz-x&J_v#mETixYjztb zX(cVaOnM+PnCD+$kl!5QEG2DR+hIL+0D6v4c^7V{oqKw8d&(c3;$}X5NQXgGuu2-iS$nMjSEo3)YEc6WLTXz{hhK|6R(!77JaUkBF z5q8W@=SVb(nSNGzgq_eK74`n+c02Q$m>vzzk)Xq9cdOuK>MBaH&Zl%$y3LkZ9IEF) z^>Z*%)+->zXObMMIRQw1s4e+Ed+=p?x~Aatg-39`g0Ma5J^HHeqWzL~&3IBP`?kn< zK~W{v`HtV)BQ`}fdM8Uvu^kn%xf`qIMqWU!l@%K9zACTJR!yn$`zh4X!q^G+Pf^L6z|>h zsPolam(dTZpINha{@%N{=sA(5F$UM7{-}S!-MsxYW>k>$wxaRESgaCFdF^d?<8~Kn zUcW0M!e$`4AUSq+L1%{D^93Cp#u{N-9EZ*!#ohOB+(VvmR+Et)&R@P-gRJ1Er21iP zjr5vJYBJQ6C5sNW%-IqjcQy#wBvg)^`%qiSYgvdsU}=?g^>JEv+3cfB<}@25+a=hi zc$`ZWdO=XB=D6^Ao^B$xw6RxSP8_W3VE5~mM6a2Yx_P95(DdrqO_!dH*>GcxdN!g| z!;~LNd$fi1Uq^Rkcg33c+<9-f?x`i^^6sKc@RkGZra@H zbavJ0wMy26R6?m?wn?t#+1vA$#w)57n{RwYc~wL3^NLR`Mf(&}I<*W($#yg4lNprV z8!sj1$JgCB@S!QH^=D;l`=+_?v#w{fjkMKj8&#Ub1zb1%#oOBM*hcLK*1KlD&N1Iv zq|8&wTh!@&GoW|WqIbocC9?glju}0^dXeshA6e}Q38RIoJA&l(b9IVMOWbGObXXio zUgV~5@qYhe15QSx3u-4)XUmdzIM%YpNJvsf?EC&Ghpe8JA@9!N%Y&c4L<9sD4Sk3< zI(6{%N5!nLqt2tggg2yYY<+_^^ia4SWlJe1$Gkn`%{otybj?Wh%t+whG2$ZFh`ZB8(H zmS+9t3fqy|P~6DN3`P6;X2U4f$LBG!!}PXiuXBzMr#9Pm@5rk+c)>7xS==NOQgz*F zJfZd7rZaORDq`eyvP;=cMip*&mchix zbv_GHQra{|Gr#t}CtF)bLw=5ER=-)nBfV#Ho;4R7-_onU?@Wn-YPM>^BcWCQ>QfGi z)mxBvpAMxd6EY6#@0%-^k4&vNloAvpN;h4$eA&=8f#S8y^QOz&@d14Ys?ije^;qv? zX3?`!6N%6nI=9zasp-+qp2*X*Zwv2fu=JZ)H@N?@yOeg*41X6`SNQLiZ|NT|1_8d_h>RxlYydx&eJCGT7wY6j4-KH3G2oUKP;(I;1YiR~Don%<$E3yg|R$Br!aY!9;;pNwz*+>1q<$<+F@94!$flPa+}ap3cdjf9B%_ z@dG713_1!31lXV@0uUMV6~Fk4*=LEbtPxZGvJsviSI8Ckae3dC`Aq(cppeD<8$Dvm zU)VvjzOCU?U?nz75&%!+(u2gtk%$C1xPoM`7PvBO|&ai-R$hE_I4 zI74e2V~m-R@icJ~MT zj7%8QAe{LuuuQ3e|L2{EsI?Sbt(v3>t~SN+=9E-VVg1f_1=RQ+)vxkK-#L zhy#wd;RbT~>%i^<5a7ljn9&!K3rhq9Qiz~p&Lk=ZJ-JtjpoHrA4eIBdn8YS?86foJ zCdHx0gU$nkM-?{;&=!e0$-1}%1B1lN?i?1l*~#5YNR%%$0^9`b4rnwA+|1N=BrKla zWdYL!Z^H+uLVyU~AT}CR;hNEK@wr^iOc07g)@Yf8rK5Q<(Wwo5VYE=@KtZZk!<@PWD=BsxNAi z7xg{nzaXvi;|6p7JDe}9pHZy%!eA~xz?tt%^9Sg{@8f)n`7@F$IOPOFehBFwjQSIw zIp}#Z8E+5Da`_?C^sfW9Og>GzCy*r>Ixv`|{o|?h$y^gqw*r$@40?HzME9d|d;xII zPW8x7>#T3|2qPv9Z497k2tza$ji6F-V2@xh=m;i_#xygb;czBsrX)W;qYJo9VK9{s zSowkpPk>vAXFkm3Q%8k?XETGTI$!#=V6Yz`F5+oP`gK-K27hYs{%@?M15`5x)d)ZU z#%44G4mg3jxQJpU^p& z^Ii4dV4Os7WYNLS|6SeFSti3Z?HCA}Jh=uQFTv9)>hp1Rs#d|w`CtA_^??7S3K;B% zl7HpjAMX0$u7Bl$f5rSGyMDOqUwPnPG5^S}|2KC*zr64QIN<3!7<`?j+J4>(d=)l_ z=CGOw34knsK%`rXOTZObp1r340+CY{-%^nDOigf6T1X<>N)JI7sjB1F`4T(97oMv~ zL@PJ&KhE7&~3w9kDtY}c0upIB&CuVF;Be*3MRd? z=gid{mnl)!mMc-ymMxjDEnT9eJ$r`stZ!VoQC^X_e2*Tg(SQU7zw1$fKhalU=mCnsM%Q z1NHbEis3HW70oy`@L_Kb1+|M-t{K-(Gf)r6*-j~p;g`D298%r&$pNi>uV!C|BUXiO SI$;mG7ecaiBA&9|9Q7YrM`J?( literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/previousOption_n_image.asset.taml b/Templates/BaseGame/game/data/UI/images/previousOption_n_image.asset.taml new file mode 100644 index 000000000..9b7fb0568 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/previousOption_n_image.asset.taml @@ -0,0 +1,8 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/previousbutton_d.png b/Templates/BaseGame/game/data/UI/images/previousbutton_d.png new file mode 100644 index 0000000000000000000000000000000000000000..688b3034593019b560c95d56ca9ad50633a1d800 GIT binary patch literal 290 zcmV+-0p0$IP)aLQWp}M-VW=GgSOtJO1OWsQ!>dPPUAR&lL*PV&z_HIo(bxiQo zG};(LQc4m+6k(jEjJ36vwAQ4Q+D*=|s;Zp)s}5;NiF@#a(PGS)F=NIkUe^`Jecxkv zS(e-o9) diff --git a/Templates/BaseGame/game/data/UI/images/previousbutton_h.png b/Templates/BaseGame/game/data/UI/images/previousbutton_h.png new file mode 100644 index 0000000000000000000000000000000000000000..26cf0e8c67dd87290ea60c90d31cb755df60b7bd GIT binary patch literal 561 zcmV-10?z%3P)BL_eXU0B$9lCDhj0MLO$6qS*o3}t8TfCx>}q<#)g6KIH2DOD=f(ZiAb^zpyn zi5)f=3~mA3^Qa@I>5M1#`~A9Y+gB5((3 zy3Q2IOpqltj~r`OQ*qL)SfWmr$+)hfTDpz0?$jW9A znJJRv70iF?ezt;2GRTc;khLUPhNfxoeP8r3h{ls-8II%Nd9@OKJpLV-Xa}A&o6T`J zI4SalX4iGGUazs;zQX_TfVHg+=hoVTjm&s{2v?w?ly z*zfl+&4gw~WTf37V)v$tcDs#Qt(E{W`NC?cXTyDWF&d48=QKzEmifXSk4MnKPknMc zb1NV@$+2JAWC|R|1$QJB8FEKb+GN=OF;Pu&sb7pz%GFO|)dJ diff --git a/Templates/BaseGame/game/data/UI/images/previousbutton_n.png b/Templates/BaseGame/game/data/UI/images/previousbutton_n.png new file mode 100644 index 0000000000000000000000000000000000000000..c0b9f4662c6767a69f24d83f3b532a363e36a43b GIT binary patch literal 494 zcmVg)641pwaK zh{1KW@K4h;sFYfamcsxM<0y(26Sjjr)t45dZ)H07*qoM6N<$f@y!$IRF3v literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/previousbutton_n_image.asset.taml b/Templates/BaseGame/game/data/UI/images/previousbutton_n_image.asset.taml new file mode 100644 index 000000000..0c793bc45 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/previousbutton_n_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/selectorbutton.png b/Templates/BaseGame/game/data/UI/images/selectorbutton.png new file mode 100644 index 0000000000000000000000000000000000000000..cd0780068892795e6329d713f48e84fa9f1df8d8 GIT binary patch literal 4002 zcmV;T4_)wyP)L`g(JRCwC#TwSbPMHOB%XP?{K+frI- z3jKpZBw}L3h4Y&qe11`09;j={b7dF@4^3ZpXFPUJH4i5A-lSN6%Bgp}nz{>}*Qo5DrnM_Us{T zg8A8VrWo>>h&Wcz<4!Qj&du zr2t9>1Oia40CWg21eOGt_0biPC^8Uh*2j*L$ds!!^kyDKO!P8>x*ua)d>LaXW2MDF zw}O7P4087Bn5)w>-bPouX2B`-c?OCu`LJ34IM%G89A_1%wn2fOma|Emi%|>J~h?r=z2q@?SEPLjW zhrV{^gZJ)LN^PTU>KFIjb2zqrVfzs&*z6jS}w}UqLcuwE7A3kyvUU>Oc`1^m3-j4u(i@(WTDO|1Gz2fGEc8qKQ zkqXY<%zr=FyX)?6!i$GHaNqA=gXgjFD?fX!2b*u-b>n8B7kTwhukXdC-?3HdSFsM} z)We#RlFg#Xw-RFn?1y(w0{j4M9bT^er_UUMZ|%ATsGoa5#l}-L`gjpIn@;CKli_uZ zn};z}@_#?~^b~Z z@K;M%I;<2-2feseOy^RoRs=@Z+6h^$!z;&!b7HV@mK}Z7O+Ey3 z=O;8=$>3t{b*b>J!52hyoI%0G{Cl1F9mqb+Ns$ECZ?0PAbfTzbidEH&-TQJbnALp% zDpq=!k$4l91am5MjZ$-`wyzlVx(?hBVod>yg1l(Fl9*f0<5A<8kn8Qel4rj=2@|Ww zVQzk*XJFs{wZ|)7$#u*d;T~}jdc!HP*6CZ(YGv=D>%EmcTr)8?QXTVzshyr9SDpHW zZc)DlaZ$w(5HKcKZ9+VXq7Wb)IQVB1eLaVbB(m`G?LqWaM1ZLDg6J{_iS$FOE^fVb zqd4-)DSdqyw_^KYY`-qhsXPFf0t$7^LCWwZez%kesyhrskzg*Vcd{n+87>ADFyL1m z1TjIZJ&yq60HZnMER{rwfQ+^Itv&U*+&mDOs$p%Yy)~8%(g85V7>bEC4|GW-5{bI@ z1c!-MCpLc-C~?6UE0~G!B7`91>!)ivRIxhdL?S&ZBH5ul!JMiQT@SF@gmthm`Z1^& zLn^Wwq0f%c11wyavd`&C3|P#C3T;=BaFLR_7PA;x-SH1I&brT{Nr^}Gvj#(-;KVxi z0jdUA^+TV1t>}*nT{`EjJnQb?=(deQy?jddEG*tGMi6PO&Uqj@cI2c>fc6<(X4R_- zr%iZa70340FQ4w(PtgZ(76YZj+=ecJ2&N9@&nj_(gU@8tl>nOmT(kMv{A0}t0TvOE zSppabCEY~QgEIHp)nwGPIfsC7SD|)6*o6V41h<#=?dW&Hk_?*Wk8WQfFs)sU07_sQ zB(l^pZMu8OQ; zD45U;oMQ-A@&@&jRo5!P_GKd=!P)~3#6Y# z%dB$ufMv^=7h!8{7f2be5Uz}GP1>=h7;B_sB+3N`>|74({`b=U+dFT)eg`bhZ7}^F zpL$qE{G_>kQ~TytO`Ms%;R}EG*zLPtDjBfsDr8TYRcq~E%hb%63*4N&am^fCBm&YY z(k;UlGPM?!`?8O6xct4jv*~?uCH}MNZ_JME-}vR-FI<+vhih8!(drhQ zLnAng%+6CmWQ$mqq%$|fVy3H`p#`cfdn69jw=rbS=o^BZAjWpyx7R#==+GgUbai<7 z_D!2MnZIv6_~^bn=D)Q2kF-F@v{0SXy+(7WO>Wy-l&&!@O-W^|Vq&G0+U{6@B-#lQ zB{4=5Z{EDw4CL$ZqV|&~Pr~FRLdAa6f0cqoEDIe8?KbJ6wFoVq6WY54?UbPuc zy!#FuKmLwkZfa@@I^UlD$@(^&TA#t`bs5Z{{>@CF{-LRvMUykz#+6OF=X5U50+(Gl zBWzY}Vf8L^qBX{tJ8n`+cNh{sC6PgU$G*H#mE3NJe%}^Otd(=IjGGa^(v{Uavr81v zH7kXxI+fDx)G`H5R3m^wm3wnmSX=77oARiWIS|2L1~ZSBIuyEV^E|*9Gjc%YN?>jg zIOfVlQ2As@u(x`#+FinVx~dD%>>5>5CMtEWsS{yvoB0=ZexaSm?n;7rHp#=_u9sqU z&x+aY9Lr(O`+#md?rn!bRCVL$4D!f|brvaR24yZbUO5kA%>ORyNgIgLuj0{CG_~O8 zPGC#5SH>&n5xu#WXxi0xb{n+Wq`kWx(Sn*&aS@({6+WhrZhQt7(rH)g^cfeMHeKPI zKQo|>0cg-XMvWMdI_lqY<54kDnQ-%U<5?Zg&xw*|!&a*cj0Vlg{H+*iDggIn% zK6Bo%uwF@#d41D7ry)u`>o}1v;Q;gF5(6EK3DEW4Kpw7{82eKl^Mt9Lo-=>niv6(v z9F0TcInj3f;_!2Gy~`?TA#XmMO{2~k0mHZxHJDtTF$z{NCNMFC@o)*qe9sqTYCEzljOR z^>*JP)B~(+N5oZl~U8-3YL*k_N(*CN-(goVh~_@WJ> zCt`8yW1kZH?*51VQ5d)W>eJ%kd;h8T5)cG6i>%E$9h*h=tat@1poop0Vdo`eFn3`h zfz=shb66_WT5Fr8qNQ&0CRm$D-O=q#Ovgw3sN|<&5&yb2oN*C9=_?fiHcxHN-gS&i z4rM^CV~4?B2~A2s+FY8=1`(^$rVvb|j+3`sXy=}BJEeuzb(Xgu`USIz03_JF;{i*Be;BtnQ{Ij4rr-?xr>HGfmx zfNQ`t;2LlZxQh_nsNW}i1y)#cqO^Jw~+R3LoF+DwfdgyI?*pH|Yu$ynbc?Uah zeG@nM&qX$V)9!O62M-=RIxN6Z#JXj~?-Sl~A#`qR#P1Ux8(yp{*x4NAJFIWQ`lh+r zbEeSC`Fmb?J3a6E4K-KueZm*i&Rri_@%07*qo IM6N<$f{4Jk(*OVf literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/selectorbutton_image.asset.taml b/Templates/BaseGame/game/data/UI/images/selectorbutton_image.asset.taml new file mode 100644 index 000000000..f53884267 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/selectorbutton_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/selectorbuttonblank.png b/Templates/BaseGame/game/data/UI/images/selectorbuttonblank.png new file mode 100644 index 0000000000000000000000000000000000000000..e965b3af6f2b9a269f2d363f6118060aaaacfe23 GIT binary patch literal 744 zcmVP)OT4`WyUtC~=@hx+zySvwaKHgKA>83`kd%_BYOLNgO(Uv$2b*)@|Eg9YW@7fI zT~!q^i<8!-Y2N9)S2Rgnw#U*CJ*lmP+UI&jej#f@hhX^j%SM~?LF zi?zW-dhDh9K8FR%|AW1+Pd7{fT$3IAR&V6+TZaPUw@w9!-|CGXdJee7;UfF3q}2_F z-|E$KyQ*vs6_t}znHa6W?Ga9$rG&H;mg0WQq!gDq*w&w<$RMR-QTF zp5X9X$D|d%wE|28zjYYM_QYn*#rUnC;P6`qMiswx)bfSjir571FWj#7x87#*oU@1w z+uvGBam@&64A{^k=j;-))qZO&*qHn9Tm5kCB=ITlrQvKh0|K};_P1&c*wXu3jc4w^ zg=2r~8qq_QY(Sd1r literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/selectorbuttonblank_image.asset.taml b/Templates/BaseGame/game/data/UI/images/selectorbuttonblank_image.asset.taml new file mode 100644 index 000000000..c3f212a24 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/selectorbuttonblank_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/selectorbuttondark.png b/Templates/BaseGame/game/data/UI/images/selectorbuttondark.png new file mode 100644 index 0000000000000000000000000000000000000000..84ee7e6f30f4eef5b3d2a1440495b16cf3b21f65 GIT binary patch literal 1942 zcmV;H2Wj|;P)8q_5Xb+!B=4lN z?AVBUt4(v4I!KilFko1|=NMX_fAf_Dp%{Bd??cV_-NM*!htZK;>r#7p~|{Ne^@a0X{^24`@3%UfLYq9}?% zS(YUc0Ym`s8-N8a_S1ei{}Rq+I3HfC<+3chy;v+JM05_f+~+~;ekD7XTeDn%ssL2Z zxhhz$1mFNv3>Kk}wg#7F*-pRT_mjzF#;)&&Vf6rJ0E*DR3t%4pZfy&?n;dMqHVz?z z%0~|PmCZY1{V&C}hu7_`jiWAJdb@Kj9jyal-Z`be6=WMY&xbFxN&)I@xi&jQr99BB zuqbT{&MDVki^uy8^Q+pB_g}k1IPuy2SC&gzlOL4`0Ja8~t?{?>ZNrsozDUt_nDdS= zR^2qqX$!CKF!Y~xRPs`B-_B8qzrjY>*dlxjz?6MoBzBdp!SRUW6gP41TG`d$49?&T z&fpC0BMmlxe?v~jK;P`U3Pkl0aC*OU?#jkUhD=1{5-;MEzN{hpqRY3XT5%@@oUed# z0!n_4-;0Kqzf@GzKF4QD$UFhYAMDvV_Iq{)fSwY7#{P;`0c1s>V%HE6IS!aNfN>BG zlZn1qcF>B3JqA;SguD_tZ*ABkV6Mz73FR3SKRlajg9O|z11iN4pHm@Ge9RM8O9AEK zC|F-ia5T69gPDiKCrScRK&hnl@`N{f1t>!G!nt5@x7myF34e=$K)z)ixv zG&m9-U0X`z62XVG$6$8DQ0+2E0Js-hcP;NbqNSFe6j;G)-N?4`~vr_43aDw2g5(mf8gP7BxV1%QQe@aIpwa=`V+t#0Dl8`7mg1APQoz>OV0wp!YiA;w$^dy=+gSi zaAxAU4kAWNMI>@rDLTT%`J0RA#w!7=^NGA7wfXlt!u8m_GU27JDK&J7NLPkTU0SZh zgf3yZTHfj!U^8?VKQwE(R5s`vGAh@Qb!{RYb*r*Euf_2z&Ksz4ue?8L!%9j3NMeKT z(n=P6$ds{W0N(&ZN@B9;2)7XT)6zz2D&%O^ijl*tBixMLOS58aDWQbrBwUOpy0ke1 z#Yn=nA>wdy)2(=_e` zlW^1HgM)+nZK%R^#|(};M=73vY0haWp-iR+YToMHGY~zg<*m*=1<|(wBu2W&;e09} zXUY;oxpR(}LP^XypC}nQCXw;K4G%vH$BCHua?UO18?Q2Puvnhr)gW0yh;y;W zAhcS^J2q#h3~Z`dYL!FqQfQedxKwP%=rIVb%Jg1TnfMTDo|-IJ^EY-%1R~*zV37!+ z)#u&|=bDKk;zDr-O2Ij;6qQ&5XUqvcBr2OHiOOb~h)(KdSK$;;YP6LC$7{kT3AodS znsB99jCjdEZwNN4M8K(4(@zs{XNhV$C87~shfu5sVM)&(Aa#goLWh`LL5F~5wVLIW zHBbJheoDcaH3XL{6`YjJl&6F<0l7;1nm2^yP07=G+E>E`s;DN)tSkH1Q4LLRZEHEx zTVZ;u>8+->E}>0tHN6!dt=@`@->mZXG_gZG6W<>ua+1yHtsMgm(_6d1eWH3RfFDHk z7=QGQEA;;e(_7m$(_7m%(_1%@j+)-OPBXo=Z8N>KZTp1vRscVDh)TYL>8;)1uB5l- zB1@NgYaUF^BZ)3;Exk2Ywh*~|$SnP#$XlNQc%tO3PXVO#*4q4HUc2Nmy%nann%-)9 zD*)45FV9I$!7;tH=>pSRQyKosW_oKAoawEmx0>Es_eRrO6)+wRncix8YXrOFoO?bT z4qpIQ`+e(pJU%3%#|=4&s<(P&t~Khd9PFxXI2^uk&OHw=w;S%)7hcbwe-5;+-nuRr z2gHS>xx diff --git a/Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly.png b/Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly.png new file mode 100644 index 0000000000000000000000000000000000000000..77e01fc741fbc30a882dd268ebb9c5da313f87a7 GIT binary patch literal 1613 zcmV-T2D15yP)kO zK~#9!?V7!A+(r<9XZH4_lO1;{)3^%U9NUyeo*@X}D)2KHd5XZ#5Tr7YPuaArv!Y5A6&q^H5 z;T+E49PX6iZoBES&5wxfy&r{Q9uXK#sm*_XnF!+u)-Ue6!_Maqrp+NDiU=#?@1?{qg3|xuRBTP*Z=lQ{1u44S0txiA0xR@^H$}BuqR#y;raA2 z=dJu2|9R091eak$bLuS`6M;~K-(=jy5S@iz&Ml~3d`Z}vd3)N z1kf@Gl7Q?0M#H8o7`{2+nNTya>l}=4Qck0;TA9=|FuoUT2L`t?;LaIL!!|OhwOzCS zPkOQ7krF7Rmx<};$lxvvn_Hz1uM{ow0F- z4uh0h(7+^|CRz=0s^o$aI#5ghLr-Og}jDDh|QDsAhHN90$LYP;G>kPTksyx|2IWnCWcY zCb*q&j#euXdAB?m^(wc)ZrzIb5{TY(>Q=-TK=gBhxDocnCCH`7Js2V)%2p_soRvLf zmFLX(gHiEcv5J3ZsI}2lD!WX?RLj5CN(+IPb{RtJm0U5K-4C$01IXBOd^N`D(Hd|v zpkFiTXew+<$5&Jy*bc~28rIgz5L$okTItW#!r{y_HWol+zc#Sz3s$LT2u*TZ;}~p9 zA>;s#IRzD(d89Z?U=SMIO;1l)J@`uvYb`70UZ{1`cZLRbMmJr?w6e{KkV1;|f(X_; zyzC8|t9#}U-AqKAL-YVjN0D)_E+m(lWYjvPIKkn6pg@u$9b`$QRWtNXzz5I1N;fD@ z(-(f)p&)ub=kwO%B(2lHHk-|BB6?n^Z=38-)z3A*6a5jhfuCxUS9qQK5sp4`Mhzs=l6(mHYt@W!@T$;fOYG-2uSOX0v&H3{|>s)Vwt)Edg!b znx}qSB6>a+kX2tkZ}oYr&s)Lgtv+v6Y|iJcJ#~uDTMcO!LA3QRjk*e}kFbyE00000 LNkvXXu0mjfl=J=< literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly_image.asset.taml b/Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly_image.asset.taml new file mode 100644 index 000000000..e359450c4 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/separatorh.png b/Templates/BaseGame/game/data/UI/images/separatorh.png new file mode 100644 index 0000000000000000000000000000000000000000..339c0fbe039e8b5cbdd085230594099c26928157 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Ed0V0oZ{G0)#BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%iF>*@hE&{2%E-w0@&CWQFtY@YFPFjrhT;U4EtAg|X#kZl Nc)I$ztaD0e0sy9+AwB>A literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/separatorh_image.asset.taml b/Templates/BaseGame/game/data/UI/images/separatorh_image.asset.taml new file mode 100644 index 000000000..213addd3a --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/separatorh_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/separatorv.png b/Templates/BaseGame/game/data/UI/images/separatorv.png new file mode 100644 index 0000000000000000000000000000000000000000..6a0f873612cef214add9a2f88ed72dbafe92174c GIT binary patch literal 118 zcmeAS@N?(olHy`uVBq!ia0vp^GC<74!2~3aY}VEQQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JiX=Q;978H@CFNvfBrGsX`1Ak2{Z(F84g-d-`&k-}TiGQ5 P)i8Lv`njxgN@xNAx)CBs literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/separatorv_image.asset.taml b/Templates/BaseGame/game/data/UI/images/separatorv_image.asset.taml new file mode 100644 index 000000000..6a14f9e54 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/separatorv_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/sliderwbox.png b/Templates/BaseGame/game/data/UI/images/sliderwbox.png new file mode 100644 index 0000000000000000000000000000000000000000..d9ef04961a30ad99f1e8871ef1f292b8a58d99f0 GIT binary patch literal 982 zcmV;{11bE8P)P001Qj1^@s6w^2g10000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#cu7P-RCwCFR!vM3K@@(oZI`u_7W)HS z_z46E5)-2a4+bql1U-1bs3#7@MD)a635mu~6G-Gn0+OI7O^h)fNi@NO!AOt<2?u@- z9*T%*X=%IvU1wGbyW4iRJ=m8_JMZl``|W!(^UWYsCMfWq4Q+02T9P!k*TKfx&%D0b zIAV74Q(YCX9ALy)joJOZchpx&6vet?Mob}N^dtoU6${^z1Pb{oBc|v~N>Z->n@DC( z^dn?hhVAVwNE{p-MuM=syre-K`>u)#Xl!f(o6S~Sxwf`8L6&6j`TR#QZC~prlSvid z+}u(e$w530ZEfwknBO1B>68EU^)=Huvgcc$9*%OPjCcpe23-4*Ecl4pS?Z!vATK~Iiu<8eTHFFyaGybOBf*v0#((zSZ!Ussc*KV zOSc(IBP*p4NV1{K&1b;)3K*lE;}RUd_RdRpkQHcQ{vA+^sH8cEioJZbKQB(*d>ETm zuGaa}MSa=Fv8LiO$#h;y@AHDD?T@o!>D`6mNv2*6_aqXDx41j*a=9k%Ha_7s%C58F zFXwu=WDCZkai-igF-SdCvFG!V4BWm>!3*e*>_?`8!JubxadCuYS^C-62cdY{%V|mO zPrfEv*U!cyQ>QNWdN!6mk8mtUKTi&Y8cr}=J`yS#jShsv;o0u)ZhuWp4fOW*GG4ED z6l>Dt*u#5hb>-U;I2DTx9PIAQwsqd{y8?C4-gT3yI9WaFU@BB>UKK8*>A7oteeO!E zq@o~z9iMO)Iy!(tXb3;o>AT`6pKHBx%T2qhfX53+u`y74whPk8o`uzwE162EM<|a8 zw7SIcYMIM%i)G?$iUZ2&2bNcK>ca7I7FI{%a5zA~1PCEZ@l)(h;K<%ZdJU70*H7+D zBuN4uf3=Z>TqcahOA4g;Y!Y6wSi+(x<|H9;qX{^~k}4v-QVOC4iG*J!WFkKE!Y<#Qq8}0K%2(y+C}?TL1t607*qoM6N<$ Eg3Ob{L;wH) literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/data/UI/images/sliderwbox_image.asset.taml b/Templates/BaseGame/game/data/UI/images/sliderwbox_image.asset.taml new file mode 100644 index 000000000..14abf8088 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/sliderwbox_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/tabborder.png b/Templates/BaseGame/game/data/UI/images/tabborder.png new file mode 100644 index 0000000000000000000000000000000000000000..6703924d48fb96552fe11a91696f7c282aea3439 GIT binary patch literal 1203 zcmV;k1WfyhP)s+T@)zO{{b^^V< z=wH7wY(L{2P71F802ipY7kw@qE$vBN%q#5`37@CZ`H-O1-w@Umr|4D%f4*L^Nt+hhLK_6p2Z z%jmzE=C=LL3e%yyDGwhjj6U6g3bP`N-;PET+g?oxjXD4|r+B4=CaKr15}L$b?q6b0 zh8~SA%A;{SQ}t+Cpt=UfVlxhaEO#3>tT*c#8_eR@?>5%(PLkvwCV9zbSc8!+a4ONV zR-+KOJO_Zt7V|Std?$P6?aK-C`OA{+V;uY;3(0FXgFHquf);&@Yc?a<)A*xjHOZUF z9OEwblp3gHGX%+c&yuRyjAl==LJ=%0nk$@AZ@u)S6zSP8LLos?q-QfZ^*VWDa!G;yi`d#otZB4azuR)9UhD?F)aac|0iuXn*Eh1*_F zk5@SQ_F3yW*%QGMWE}P+4H9G+d(!r(D?=_|4>u*qe>cw_ShR}v@)e(9wdwjG#i_h1~oIT;xGv>0sd%E diff --git a/Templates/BaseGame/game/data/UI/scripts/menuInputHandling.tscript b/Templates/BaseGame/game/data/UI/scripts/menuInputHandling.tscript new file mode 100644 index 000000000..074bb3675 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/scripts/menuInputHandling.tscript @@ -0,0 +1,510 @@ +//============================================================================== +// Menu Input Buttons +// This file manages the Menu Input Buttons stuff +// Any time you have a GUI button that should be clickable AND map to a key input +// such as a gamepad button, or enter, etc, this stuff can be used +//============================================================================== +/* +Gamepad input reference for 360 controller +btn_a = A +btn_b = B +btn_x = X +btn_y = Y +btn_r = Right Bumper +btn_l = Right Bumper +upov = Dpad Up +dpov = Dpad Down +lpov = Dpad Left +rpov = Dpad Right +xaxis = Left Stick | + values = up, - values = down +yaxis = Left Stick | + values = up, - values = down +rxaxis = Right Stick | + values = up, - values = down +ryaxis = Right Stick | + values = up, - values = down +zaxis = Left Trigger +rzaxis = Right Trigger +btn_start = Start +btn_back = Back/Select +*/ + +/// This is used with the main UI menu lists, when a non-axis input event is called +/// such as pressing a button +/// It is called from the engine +function UIMenuButtonList::onInputEvent(%this, %device, %action, %state) +{ + if(%state) + $activeMenuButtonContainer.processInputs(%device, %action); +} + +/// This is used with the main UI menu lists, when an axis input event is called +/// such as moving a joystick +/// It is called from the engine +function UIMenuButtonList::onAxisEvent(%this, %device, %action, %axisVal) +{ + //Skip out of the value is too low as it could just be noise or miscalibrated defaults + if(%axisVal < 0.02) + return; + + $activeMenuButtonContainer.processAxisEvent(%device, %action); +} + +/// Sets the command and text for the specified button. If %text and %command +/// are left empty, the button will be disabled and hidden. +/// +/// \param %gamepadButton (string) The button to set for when using gamepad input. See the input map reference comment at the top of the file +/// \param %keyboardButton (string) The button to set for when using keyboard/mouse input. +/// \param %text (string) The text to display next to the A button graphic. +/// \param %command (string) The command executed when the A button is pressed. +/// \param %gamepadOnly (bool) If true, will only show the button when working in the gamepad input mode +function MenuInputButton::set(%this, %gamepadButton, %keyboardButton, %text, %command, %gamepadOnly) +{ + %set = (! ((%text $= "") && (%command $= ""))); + %this.setText(%text); + %this.setActive(%set); + %this.setVisible(%set); + + %this.gamepadButton = %gamepadButton; + %this.keyboardButton = %keyboardButton; + + if(%gamepadOnly $= "") + %gamepadOnly = false; + + %this.gamepadOnly = %gamepadOnly; + + %this.Command = %command; +} + +/// Refreshes the specific button, updating it's visbility status and the displayed input image +function MenuInputButton::refresh(%this) +{ + %set = (! ((%this.text $= "") && (%this.command $= ""))); + + //Special-case of where we're in keyboard+mouse mode, but the menubutton is gamepad only mode, so we early out + if(%this.gamepadOnly && $activeControllerType !$= "gamepad") + %set = false; + + %this.setActive(%set); + %this.setVisible(%set); + + if(!%this.isActive()) + return; + + if($activeControllerType $= "gamepad") + { + if(%this.gamepadButton !$= "") + { + %assetId = ""; + if($activeControllerName $= "PS4 Controller") + { + %assetId = "UI:PS4_"; + + if(%this.gamepadButton $= "btn_a") + %assetId = %assetId @ "Cross"; + else if(%this.gamepadButton $= "btn_b") + %assetId = %assetId @ "Circle"; + else if(%this.gamepadButton $= "btn_x") + %assetId = %assetId @ "Square"; + else if(%this.gamepadButton $= "btn_y") + %assetId = %assetId @ "Triangle"; + else if(%this.gamepadButton $= "btn_l") + %assetId = %assetId @ "L1"; + else if(%this.gamepadButton $= "zaxis") + %assetId = %assetId @ "L2"; + else if(%this.gamepadButton $= "btn_r") + %assetId = %assetId @ "R1"; + else if(%this.gamepadButton $= "rzaxis") + %assetId = %assetId @ "R2"; + else if(%this.gamepadButton $= "btn_start") + %assetId = %assetId @ "Options"; + else if(%this.gamepadButton $= "btn_back") + %assetId = %assetId @ "Share"; + } + else if($activeControllerName $= "Nintendo Switch Pro Controller") + { + %assetId = "UI:Switch_"; + + if(%this.gamepadButton $= "btn_a") + %assetId = %assetId @ "B"; + else if(%this.gamepadButton $= "btn_b") + %assetId = %assetId @ "A"; + else if(%this.gamepadButton $= "btn_x") + %assetId = %assetId @ "Y"; + else if(%this.gamepadButton $= "btn_y") + %assetId = %assetId @ "X"; + else if(%this.gamepadButton $= "btn_l") + %assetId = %assetId @ "LB"; + else if(%this.gamepadButton $= "zaxis") + %assetId = %assetId @ "LT"; + else if(%this.gamepadButton $= "btn_r") + %assetId = %assetId @ "RB"; + else if(%this.gamepadButton $= "rzaxis") + %assetId = %assetId @ "RT"; + else if(%this.gamepadButton $= "btn_start") + %assetId = %assetId @ "Plus"; + else if(%this.gamepadButton $= "btn_back") + %assetId = %assetId @ "Minus"; + } + else if($activeControllerName !$= "") + { + %assetId = "UI:Xbox_"; + + if(%this.gamepadButton $= "btn_a") + %assetId = %assetId @ "A"; + else if(%this.gamepadButton $= "btn_b") + %assetId = %assetId @ "B"; + else if(%this.gamepadButton $= "btn_x") + %assetId = %assetId @ "X"; + else if(%this.gamepadButton $= "btn_y") + %assetId = %assetId @ "Y"; + else if(%this.gamepadButton $= "btn_l") + %assetId = %assetId @ "LB"; + else if(%this.gamepadButton $= "zaxis") + %assetId = %assetId @ "LT"; + else if(%this.gamepadButton $= "btn_r") + %assetId = %assetId @ "RB"; + else if(%this.gamepadButton $= "rzaxis") + %assetId = %assetId @ "RT"; + else if(%this.gamepadButton $= "btn_start") + %assetId = %assetId @ "Menu"; + else if(%this.gamepadButton $= "btn_back") + %assetId = %assetId @ "Windows"; + } + } + } + else + { + if(%this.keyboardButton !$= "") + { + %assetId = "UI:Keyboard_Black_" @ %this.keyboardButton; + } + } + + %this.setBitmap(%assetId @ "_image"); + + return true; +} + +/// Refreshes a menu input container, updating the buttons inside it +function MenuInputButtonContainer::refresh(%this) +{ + %count = %this.getCount(); + for(%i=0; %i < %count; %i++) + { + %btn = %this.getObject(%i); + + %btn.refresh(); + } +} + +/// Sets the given MenuInputButtonContainer as the active one. This directs input events +/// to it's buttons, ensures it's visible, and auto-hides the old active container if it was set +function MenuInputButtonContainer::setActive(%this) +{ + if(isObject($activeMenuButtonContainer)) + $activeMenuButtonContainer.hidden = true; + + $activeMenuButtonContainer = %this; + $activeMenuButtonContainer.hidden = false; + $activeMenuButtonContainer.refresh(); +} + +/// Checks the input manager for if we have a gamepad active and gets it's name +/// If we have one, also sets the active input type to gamepad +function MenuInputButtonContainer::checkGamepad(%this) +{ + %controllerName = SDLInputManager::JoystickNameForIndex(0); + + $activeControllerName = %controllerName; + + if($activeControllerName $= "") + $activeControllerType = "K&M"; + else + $activeControllerType = "gamepad"; +} + +/// This is called by the earlier inputs callback that comes from the menu list +/// this allows us to first check what the input type is, and if the device is different +/// (such as going from keyboard and mouse to gamepad) we can refresh the buttons to update +/// the display +/// Then we process the input to see if it matches to any of the button maps for our +/// MenuInputButtons. If we have a match, we execute it's command. +function MenuInputButtonContainer::processInputs(%this, %device, %action) +{ + //check to see if our status has changed + %changed = false; + + %oldDevice = $activeControllerName; + + %deviceName = stripTrailingNumber(%device); + + if(%deviceName $= "keyboard" || %deviceName $= "mouse") + { + if($activeControllerName !$= "K&M") + %changed = true; + + $activeControllerName = "K&M"; + $activeControllerType = "K&M"; + Canvas.showCursor(); + } + else + { + if(%this.checkGamepad()) + { + Canvas.hideCursor(); + } + + if($activeControllerType !$= %oldDevice) + %changed = true; + } + + if(%changed) + %this.refresh(); + + //Now process the input for the button accelerator, if applicable + //Set up our basic buttons + for(%i=0; %i < %this.getCount(); %i++) + { + %btn = %this.getObject(%i); + + if(!%btn.isActive()) + continue; + + if($activeControllerType !$= "K&M") + { + if(%btn.gamepadButton $= %action) + { + eval(%btn.command); + } + } + else + { + if(%btn.keyboardButton $= %action) + { + eval(%btn.command); + } + } + } +} + +/// This is called by the earlier inputs callback that comes from the menu list +/// this allows us to first check what the input type is, and if the device is different +/// (such as going from keyboard and mouse to gamepad) we can refresh the buttons to update +/// the display +function MenuInputButtonContainer::processAxisEvent(%this, %device, %action, %axisVal) +{ + //check to see if our status has changed + %changed = false; + + %oldDevice = $activeControllerName; + + %deviceName = stripTrailingNumber(%device); + + if(%deviceName $= "mouse") + { + if($activeControllerName !$= "K&M") + %changed = true; + + $activeControllerName = "K&M"; + $activeControllerType = "K&M"; + Canvas.showCursor(); + } + else + { + if(%this.checkGamepad()) + { + Canvas.hideCursor(); + } + + if($activeControllerType !$= %oldDevice) + %changed = true; + } + + if(%changed) + %this.refresh(); +} + +// +// +function onSDLDeviceConnected(%sdlIndex, %deviceName, %deviceType) +{ + /*if(GamepadButtonsGui.checkGamepad()) + { + GamepadButtonsGui.hidden = false; + }*/ +} + +function onSDLDeviceDisconnected(%sdlIndex) +{ + /*if(!GamepadButtonsGui.checkGamepad()) + { + GamepadButtonsGui.hidden = true; + }*/ +} + +//============================================================================== +// Menu Input processing +// These functions manage the Menu input processing in general +// Whenever a MenuInputHandler consumes an input event, it'll process them here +// This'll let the active menu list be navigated, as well as buttons be processed +// and ultimately handled by the Input Buttons above +//============================================================================== +function MenuInputHandler::onAxisEvent(%this, %device, %action, %value) +{ + //this is to force a refresh of the menu + if(%value == 1 || %value == -1) + $activeMenuButtonContainer.processInputs(%device, %action); + + if(startsWith(%device, "mouse")) + return; + + if((%action $= "upov" && %value > 0) || (%action $= "yaxis" && %value == -1)) + { + $activeMenuList.navigateUp(); + } + + if((%action $= "dpov" && %value > 0) || (%action $= "yaxis" && %value == 1)) + { + $activeMenuList.navigateDown(); + } + + //How we deal with the left and right navigation is dependant on the mode of the + //menu list + if($activeMenuListMode $= "Settings") + { + if((%action $= "lpov" && %value > 0) || (%action $= "xaxis" && %value == -1)) + { + echo("Options menu nudged left!"); + //$activeMenuList.navigateLeft(); + } + + if((%action $= "rpov" && %value > 0) || (%action $= "xaxis" && %value == -1)) + { + echo("Options menu nudged right!"); + //$activeMenuList.navigateRight(); + } + } + else + { + if((%action $= "lpov" && %value > 0) || (%action $= "xaxis" && %value == -1)) + { + $activeMenuList.navigateLeft(); + } + + if((%action $= "rpov" && %value > 0) || (%action $= "xaxis" && %value == -1)) + { + $activeMenuList.navigateRight(); + } + } +} + +function MenuInputHandler::onInputEvent(%this, %device, %action, %state) +{ + if(%action $= "upov" || %action $= "dpov" || %action $= "lpov" || %action $= "rpov") + { + %this.onAxisEvent(%device, %action, %state); + return; + } + + if(%state) + $activeMenuButtonContainer.processInputs(%device, %action); +} + +//============================================================================== +// Menu List processing +// These functions manage the navigation and activation of the Menu Lists +//============================================================================== + +function MenuList::setAsActiveMenuList(%this, %startPosition, %menuMode) +{ + if(%startPosition $= "") + %startPosition = "0 0"; + + if(%menuMode $= "") + %menuMode = "Menu"; + + $activeMenuList = %this; + $activeMenuList.hidden = false; + $activeMenuListPosition = %startPosition; + $activeMenuListMode = %menuMode; + + %this.refresh(); +} + + +function MenuList::activate(%this) +{ + //check for a highlighted element + if($activeMenuListPosition.y > -1 && $activeMenuListPosition < $activeMenuList.getCount()) + { + %btn = $activeMenuList.getObject($activeMenuListPosition.y); + %btn.performClick(); + } +} + +function MenuList::refresh(%this) +{ + %selectedObject = 0; + for(%i=0; %i < $activeMenuList.getCount(); %i++) + { + %btn = $activeMenuList.getObject(%i); + + %isSelected = %i == $activeMenuListPosition.y; + + %btn.setHighlighted(%isSelected); + + if(%isSelected) + %selectedObject = %i; + } + + if($activeMenuList.isMethod("onNavigate")) + $activeMenuList.onNavigate($activeMenuListPosition.y); + + %parent = $activeMenuList.getParent(); + if(%parent.getClassName() $= "GuiScrollCtrl") + { + %parent.scrollToObject(%selectedObject); + } +} + +function MenuList::navigateUp(%this) +{ + $activeMenuListPosition.y -= 1; + if($activeMenuListPosition.y < 0) + $activeMenuListPosition.y = 0; + + %this.refresh(); +} + +function MenuList::navigateDown(%this) +{ + $activeMenuListPosition.y += 1; + if($activeMenuListPosition.y >= $activeMenuList.getCount()) + $activeMenuListPosition.y = $activeMenuList.getCount()-1; + + %this.refresh(); +} + +function MenuList::navigateLeft() +{ + echo("Menu list navigated left!"); + + //Atm, we're only handling specific control types, namely options entries, but + //this could readily be expanded upon to handle grids like for inventory screens + //or the like + + %btn = $activeMenuList.getObject($activeMenuListPosition.y); + if(%btn.getClassName() $= "GuiGameSettingsCtrl" && %btn.isEnabled()) + { + warnf("MenuList::navigateLeft() - actioned the option" @ %btn @ " to the left"); + } +} + +function MenuList::navigateRight() +{ + echo("Menu list navigated right!"); + + %btn = $activeMenuList.getObject($activeMenuListPosition.y); + if(%btn.getClassName() $= "GuiGameSettingsCtrl" && %btn.isEnabled()) + { + warnf("MenuList::navigateLeft() - actioned the option" @ %btn @ " to the left"); + } +} From 725e2b1575ffafc04cdc57df8ed30bb454663eb1 Mon Sep 17 00:00:00 2001 From: JeffR Date: Tue, 22 Feb 2022 23:39:52 -0600 Subject: [PATCH 032/145] Typo'd assetId correction --- Templates/BaseGame/game/data/UI/guis/loadingGui.gui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Templates/BaseGame/game/data/UI/guis/loadingGui.gui b/Templates/BaseGame/game/data/UI/guis/loadingGui.gui index 83357901c..f232a2af9 100644 --- a/Templates/BaseGame/game/data/UI/guis/loadingGui.gui +++ b/Templates/BaseGame/game/data/UI/guis/loadingGui.gui @@ -1,6 +1,6 @@ //--- OBJECT WRITE BEGIN --- $guiContent = new GuiChunkedBitmapCtrl(LoadingGui) { - bitmapAsset = "UI:background_dark_image"; + bitmapAsset = "UI:backgrounddark_image"; useVariable = "0"; tile = "0"; position = "0 0"; From 9b4acda7bd942e9b2e8e4cc7173e5c20aad32ce8 Mon Sep 17 00:00:00 2001 From: JeffR Date: Wed, 23 Feb 2022 00:29:00 -0600 Subject: [PATCH 033/145] Missed clearing the options categories in options menu onWake --- Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript index 48612b943..23a09236e 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript @@ -76,6 +76,8 @@ function OptionsMenuSettingsList::getOptionsList(%this, %index) function OptionsMenu::onWake(%this) { + OptionsMenuCategoryList.clear(); + for(%i=0; %i < %this.optionsCategories.count(); %i++) { %catName = %this.optionsCategories.getKey(%i); From 8d8432115b105deff608c809e56ac9f979e57f43 Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 24 Feb 2022 00:48:00 -0600 Subject: [PATCH 034/145] Adjusts formatting when parsing for object and function definitions in the project importer to be more accurate Adds handling for progrommatic new object delcarations where the class type is defined via () encapsulated code so the project import doesn't mangle it. --- .../scripts/projectImporter.tscript | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index c149cf3f2..f7b86be34 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -476,7 +476,7 @@ function preprocessImportingFiles() { %line = $ProjectImporter::fileObject.readLine(); - if(strIsMatchExpr("* new*(*)*", %line)) + if(strIsMatchExpr("*new *(*)*", %line)) { %start = strpos(%line, "new "); %end = strpos(%line, "(", %start); @@ -486,6 +486,14 @@ function preprocessImportingFiles() %className = getSubStr(%line, %start + 4, %end-%start-4); } + if(%className $= "") + { + //we clearly have some unusual formatting, potentially a progromattic + //object block creation going on here. so we'll just skip it and move on + %currentFileSectionObject.add(%line); + continue; + } + %nameEnd = strpos(%line, ")", %end); %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); @@ -530,7 +538,7 @@ function preprocessImportingFiles() %insideObjectBlock = true; } } - else if(strIsMatchExpr("* datablock*(*)*", %line)) + else if(strIsMatchExpr("*datablock *(*)*", %line)) { %start = strpos(%line, "datablock "); %end = strpos(%line, "(", %start); @@ -584,7 +592,7 @@ function preprocessImportingFiles() %insideObjectBlock = true; } } - else if(strIsMatchExpr("* singleton*(*)*", %line)) + else if(strIsMatchExpr("*singleton *(*)*", %line)) { %start = strpos(%line, "singleton "); %end = strpos(%line, "(", %start); @@ -638,7 +646,7 @@ function preprocessImportingFiles() %insideObjectBlock = true; } } - else if(strIsMatchExpr("*function*(*)*", %line)) + else if(strIsMatchExpr("*function *(*)*", %line)) { %start = strpos(%line, "function "); %end = strpos(%line, "(", %start); From 7659b51ac93a04fb1c8f16b3eb94fa23a98c2822 Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 24 Feb 2022 01:33:14 -0600 Subject: [PATCH 035/145] Added trimming of parsed object names to ensure whitespace before and after isn't accidentally processed as invalid characters Also made the classname validity check happen on the other creation keyword types Added logic so when processing an importing material definition that already has an asset, can handle it if the scriptPath doesn't have the extension in it already. --- .../pre40/T3Dpre4ProjectImporter.tscript | 6 +++++ .../scripts/projectImporter.tscript | 24 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript index c6ac5c2b2..abbe166e0 100644 --- a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript @@ -1038,6 +1038,12 @@ function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %obje %assetScriptPath = %assetDef.getScriptPath(); + if(fileExt(%assetScriptPath) $= "") + { + //try the default extension + %assetScriptPath = %assetScriptPath @ "." @ $TorqueScriptFileExtension; + } + if(isFile(%assetScriptPath) && isObject(%objectName)) { //Regular material in a companion file, so we'll want to write it to the diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index f7b86be34..13797d2a2 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -488,7 +488,7 @@ function preprocessImportingFiles() if(%className $= "") { - //we clearly have some unusual formatting, potentially a progromattic + //we clearly have some unusual formatting, potentially a programmatic //object block creation going on here. so we'll just skip it and move on %currentFileSectionObject.add(%line); continue; @@ -506,6 +506,8 @@ function preprocessImportingFiles() %objectName = getSubStr(%objectName, 0, %inheritanceSplit); } + %objectName = trim(%objectName); + %parentFileSectionObject = %currentFileSectionObject; %currentFileSectionObject = new ArrayObject(); @@ -548,6 +550,14 @@ function preprocessImportingFiles() %className = getSubStr(%line, %start + 10, %end-%start-10); } + if(%className $= "") + { + //we clearly have some unusual formatting, potentially a programmatic + //object block creation going on here. so we'll just skip it and move on + %currentFileSectionObject.add(%line); + continue; + } + %nameEnd = strpos(%line, ")", %end); %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); @@ -560,6 +570,8 @@ function preprocessImportingFiles() %objectName = getSubStr(%objectName, 0, %inheritanceSplit); } + %objectName = trim(%objectName); + %parentFileSectionObject = %currentFileSectionObject; %currentFileSectionObject = new ArrayObject(); @@ -602,6 +614,14 @@ function preprocessImportingFiles() %className = getSubStr(%line, %start + 10, %end-%start-10); } + if(%className $= "") + { + //we clearly have some unusual formatting, potentially a programmatic + //object block creation going on here. so we'll just skip it and move on + %currentFileSectionObject.add(%line); + continue; + } + %nameEnd = strpos(%line, ")", %end); %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); @@ -614,6 +634,8 @@ function preprocessImportingFiles() %objectName = getSubStr(%objectName, 0, %inheritanceSplit); } + %objectName = trim(%objectName); + %parentFileSectionObject = %currentFileSectionObject; %currentFileSectionObject = new ArrayObject(); From b8b94fdec90863c8c58148fee3095f2d42eddd00 Mon Sep 17 00:00:00 2001 From: JeffR Date: Fri, 25 Feb 2022 00:03:33 -0600 Subject: [PATCH 036/145] Standardizes project import copy behavior to validate if we're in-place importing to avoid erroring out needlessly with a new utility function Fixed wrong variable preventing ImportConfig Editor from refreshing when selecting different configs Standardized DefaultImportConfig's settings against Legacy Import setting, specifically collision resolution behavior and appending _mat suffix to materials --- .../tools/assetBrowser/assetImportConfigs.xml | 648 ++++++++++++------ .../assetBrowser/scripts/assetBrowser.tscript | 4 +- .../scripts/assetImportConfigEditor.tscript | 6 +- .../importers/pre40/pre40ImporterGuis.tscript | 7 +- .../scripts/projectImporter.tscript | 57 +- 5 files changed, 467 insertions(+), 255 deletions(-) diff --git a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml index 3cfa5da83..5c91b3d2a 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml +++ b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml @@ -1,243 +1,459 @@ - - - 2 - Seconds - 1 - 1 + + + 2 + Seconds + 1 + 1 - - Col - CollisionMesh - 1 - 1 - CollisionMesh - LOS + + Col + CollisionMesh + 1 + 1 + CollisionMesh + LOS - - 0 - 0 - AutoPrune - AutoPrune - 1 - 0 + + 0 + 0 + AutoPrune + FolderPrefix + 1 + 0 - - _image - 1 - _AO,_AMBIENT,_AMBIENTOCCLUSION - _COMP,_COMPOSITE,_PBR,-COMP,-COMPOSITE,-PBR,_ORM,-ORM,_C - 1 - _ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL - 0 - N/A - 1 - 0 - _METAL,_MET,_METALNESS,_METALLIC,_M - _NORMAL,_NORM,_N - _ROUGH,_ROUGHNESS,_R - 1.0 - _SMOOTH,_SMOOTHNESS,_S - Bilinear - 1 + + _image + 1 + _AO,_AMBIENT,_AMBIENTOCCLUSION + _COMP,_COMPOSITE,_PBR,-COMP,-COMPOSITE,-PBR,_ORM,-ORM,_C + 1 + _ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL + 0 + N/A + 1 + 0 + _METAL,_MET,_METALNESS,_METALLIC,_M + _NORMAL,_NORM,_N + _ROUGH,_ROUGHNESS,_R + 1.0 + _SMOOTH,_SMOOTHNESS,_S + Bilinear + 1 - - _mat - 0 - 1 - 1 - DefaultMaterial,ColorEffect* - 1 - 1 - 1 - 1 + + _mat + 1 + 1 + 1 + DefaultMaterial,ColorEffect* + 1 + 1 + 1 + 1 - - _shape - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - TrailingNumber - 0 - 0 - 1 - 0 - Z_AXIS + + _shape + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + TrailingNumber + 0 + 0 + 1 + 0 + Z_AXIS - - 0 - 1.0 - 1.0 + + 0 + 1.0 + 1.0 - - - 2 - Seconds - 1 - 1 + + + 2 + Seconds + 1 + 1 - - Col - CollisionMesh - 1 - 1 - CollisionMesh - LOS + + Col + CollisionMesh + 1 + 1 + CollisionMesh + LOS - - 0 - 0 - FolderPrefix - 1 - 0 + + 0 + 0 + FolderPrefix + 1 + 0 - - _image - 1 - _AO,_AMBIENT,_AMBIENTOCCLUSION - _COMP,_COMPOSITE - 1 - _ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL - 0 - N/A - 1 - 0 - _METAL,_MET,_METALNESS,_METALLIC - _NORMAL,_NORM - _ROUGH,_ROUGHNESS - 1.0 - _SMOOTH,_SMOOTHNESS - Bilinear - 1 + + _image + 1 + _AO,_AMBIENT,_AMBIENTOCCLUSION + _COMP,_COMPOSITE + 1 + _ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL + 0 + N/A + 1 + 0 + _METAL,_MET,_METALNESS,_METALLIC + _NORMAL,_NORM + _ROUGH,_ROUGHNESS + 1.0 + _SMOOTH,_SMOOTHNESS + Bilinear + 1 - - _mat - 1 - 1 - 1 - DefaultMaterial,ColorEffect* - 1 - 1 - 1 + + _mat + 1 + 1 + DefaultMaterial,ColorEffect* + 1 + 1 + 1 + 1 - - _shape - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - TrailingNumber - 0 - 0 - 1 - 0 - Z_AXIS + + _shape + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + TrailingNumber + 0 + 0 + 1 + 0 + Z_AXIS - - 0 - 1.0 - 1.0 + + 0 + 1.0 + 1.0 - - - 2 - Seconds - 1 - 1 + + + 2 + Seconds + 1 + 1 - - Col - CollisionMesh - 1 - 1 - CollisionMesh - LOS + + Col + CollisionMesh + 1 + 1 + CollisionMesh + LOS - - 0 - 0 - AutoPrune - 1 - 0 + + 0 + 0 + AutoPrune + 1 + 0 - - _AO,_AMBIENT,_AMBIENTOCCLUSION - 1 - _ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL - 1 - N/A - 0 - _METAL,_MET,_METALNESS,_METALLIC - _NORMAL,_NORM - _COMP,_COMPOSITE,_PBR,-COMP,-COMPOSITE,-PBR,_ORM,-ORM - _ROUGH,_ROUGHNESS - 1.0 - _SMOOTH,_SMOOTHNESS - Bilinear - 1 + + _AO,_AMBIENT,_AMBIENTOCCLUSION + 1 + _ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL + 1 + N/A + 0 + _METAL,_MET,_METALNESS,_METALLIC + _NORMAL,_NORM + _COMP,_COMPOSITE,_PBR,-COMP,-COMPOSITE,-PBR,_ORM,-ORM + _ROUGH,_ROUGHNESS + 1.0 + _SMOOTH,_SMOOTHNESS + Bilinear + 1 - - 1 - 1 - 1 - 1 - 1 + + 1 + 1 + 1 + 1 + 1 - - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - TrailingNumber - 0 - 0 - 1 - 0 - Z_AXIS + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + TrailingNumber + 0 + 0 + 1 + 0 + Z_AXIS - - 0 - 1.0 - 1.0 + + 0 + 1.0 + 1.0 diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index c385a5f0c..7d0c1e3da 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript @@ -2491,8 +2491,10 @@ function AssetBrowser::autoImportSimpleLooseFiles(%this) while( %file !$= "" ) { - if(!strIsMatchExpr("*.asset.taml", %file) && !strIsMatchExpr("*.taml", %file) && !strIsMatchExpr("*.cached.dts", %file)) + if(!strIsMatchExpr("*.asset.taml", %file) && !strIsMatchExpr("*.taml", %file) && !strIsMatchExpr("*.cached.dts", %file) + && !strIsMatchExpr("*.cs", %file) && !strIsMatchExpr("*.tscript", %file) && !strIsMatchExpr("*.module", %file)) { + %aq.clear(); %assetsFound = AssetDatabase.findAssetLooseFile(%aq, %file); if(%assetsFound == 0) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfigEditor.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfigEditor.tscript index 929c1ddfe..d664cfa05 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfigEditor.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfigEditor.tscript @@ -33,8 +33,8 @@ function AssetImportConfigEditor::apply(%this) function AssetImportConfigList::onSelect( %this, %id, %text ) { - ImportOptionsConfigList.clearFields(); - ImportOptionsConfigList.setAutoUpdate(false); //we don't want to be updating every time we add a field in here + AssetImportConfigEditorInspector.clearFields(); + AssetImportConfigEditorInspector.setAutoUpdate(false); //we don't want to be updating every time we add a field in here %this.currentConfig = %text; @@ -46,7 +46,7 @@ function AssetImportConfigList::onSelect( %this, %id, %text ) %this.populateConfigListByGroup("Animations"); //%this.populateConfigListByGroup("Collision"); - ImportOptionsConfigList.update(); + AssetImportConfigEditorInspector.update(); } function AssetImportConfigList::populateConfigListByGroup(%this, %groupName) diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript index 10b7fb96a..4835889e8 100644 --- a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript @@ -46,12 +46,7 @@ function Pre40ImporterPage0::openPage(%this) %targetFolder = filePath(%targetFilePath); - if(!isDirectory(%targetFolder)) - { - DirectoryHandler::createFolder(0, %targetFolder); - } - - if(!pathCopy(%file, %targetFilePath, false)) + if(!copyFileToDestination(%file, %targetFilePath)) { $ProjectImporter::log.add("Legacy Project Importer, failed to copy file: " @ %file @ " to destination: " @ %targetFilePath); continue; diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index 13797d2a2..eccb3b0f6 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -373,6 +373,28 @@ function ProjectImportWindow::addImporterPage(%this, %page) // functions that'll pretty much be used regardless of version being targeted //============================================================================== //============================================================================== +// Takes a source file and attempts to copy it to the destination path. +// If the paths are the same, we just exit out with a success indicator +//============================================================================== +function copyFileToDestination(%sourceFile, %destinationFile) +{ + %fullSourcePath = makeFullPath(%sourceFile); + %fullDestPath = makeFullPath(%destinationFile); + + if(!IsDirectory(filePath(%fullDestPath))) + { + DirectoryHandler::createFolder(0, filePath(%fullDestPath)); + } + + if(%fullSourcePath $= %fullDestPath) + return true; //no need to copy, we're already here! + + if(!pathCopy(%fullSourcePath, %fullDestPath, false)) + return false; + + return true; +} +//============================================================================== // Runs through the files in the source directory and preprocessing them. // All valid files are added to a list, and script-based files are pre-parsed // so the importer can easily process their contents later @@ -1436,12 +1458,7 @@ function beginShapeImport() %destinationPath = %rootFileSectionObject.fileDestination; if(isFile(%file) && %rootFileSectionObject.isShapeFile == true && %rootFileSectionObject.imported == false) { - if(!IsDirectory(filePath(%destinationPath))) - { - DirectoryHandler::createFolder(0, filePath(%destinationPath)); - } - - if(!pathCopy(%file, %destinationPath, false)) + if(!copyFileToDestination(%file, %destinationPath)) { projectImporterLog("ProjectImporter::beginShapeImport() - failed to copy shape: " @ %file @ " to destination: " @ %destinationPath); @@ -1502,12 +1519,7 @@ function beginImageImport() %destinationPath = %rootFileSectionObject.fileDestination; if(isFile(%file) && %rootFileSectionObject.isImageFile == true && %rootFileSectionObject.imported == false) { - if(!IsDirectory(filePath(%destinationPath))) - { - DirectoryHandler::createFolder(0, filePath(%destinationPath)); - } - - if(!pathCopy(%file, %destinationPath, false)) + if(!copyFileToDestination(%file, %destinationPath)) { projectImporterLog("ProjectImporter::beginImageImport() - failed to copy image: " @ %file @ " to destination: " @ %destinationPath); @@ -1577,12 +1589,8 @@ function beginTerrainImport() %fileName = fileName(%file); %filePath = filePath(%file); }*/ - if(!IsDirectory(filePath(%destinationPath))) - { - DirectoryHandler::createFolder(0, filePath(%destinationPath)); - } - if(!pathCopy(%file, %destinationPath, false)) + if(!copyFileToDestination(%file, %destinationPath)) { projectImporterLog("ProjectImporter::beginTerrainImport() - failed to copy terrain: " @ %file @ " to destination: " @ %destinationPath); @@ -1666,12 +1674,8 @@ function beginSoundImport() %fileName = fileName(%file); %filePath = filePath(%file); }*/ - if(!IsDirectory(filePath(%destinationPath))) - { - DirectoryHandler::createFolder(0, filePath(%destinationPath)); - } - if(!pathCopy(%file, %destinationPath, false)) + if(!copyFileToDestination(%file, %destinationPath)) { projectImporterLog("ProjectImporter::beginSoundImport() - failed to copy sound: " @ %file @ " to destination: " @ %destinationPath); @@ -1775,7 +1779,7 @@ function beginGUIImport() //Check if we need to even copy in the first place. If we do, ensure //the copy actually worked - if((makeRelativePath(%file) !$= %destinationPath) && !pathCopy(%file, %destinationPath, false)) + if(!copyFileToDestination(%file, %destinationPath)) { projectImporterLog("ProjectImporter::beginGUIImport() - failed to copy GUI: " @ %file @ " to destination: " @ %destinationPath); @@ -1888,12 +1892,7 @@ function beginLevelImport() %fileBase = fileBase(%destinationPath); %filePath = filePath(%destinationPath); - if(!IsDirectory(filePath(%destinationPath))) - { - DirectoryHandler::createFolder(0, filePath(%destinationPath)); - } - - if(!pathCopy(%file, %destinationPath, false)) + if(!copyFileToDestination(%file, %destinationPath)) { projectImporterLog("ProjectImporter::beginLevelImport() - failed to copy level: " @ %file @ " to destination: " @ %destinationPath); From 7fe85ab7d5b24086d367b981cdd8df8c3e027929 Mon Sep 17 00:00:00 2001 From: JeffR Date: Fri, 25 Feb 2022 16:55:05 -0600 Subject: [PATCH 037/145] Fixes saveScaledImage to handle DDS format files, since DDS's go through a separate resource loader --- Engine/source/gfx/bitmap/gBitmap.cpp | 52 ++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/Engine/source/gfx/bitmap/gBitmap.cpp b/Engine/source/gfx/bitmap/gBitmap.cpp index b7045d129..97e891fcf 100644 --- a/Engine/source/gfx/bitmap/gBitmap.cpp +++ b/Engine/source/gfx/bitmap/gBitmap.cpp @@ -32,6 +32,7 @@ #include "console/console.h" #include "platform/profiler.h" #include "console/engineAPI.h" +#include "gfx/bitmap/ddsFile.h" using namespace Torque; @@ -1362,30 +1363,48 @@ DefineEngineFunction( getBitmapInfo, String, ( const char *filename ),, } DefineEngineFunction(saveScaledImage, bool, (const char* bitmapSource, const char* bitmapDest, S32 resolutionSize), ("", "", 512), - "Returns image info in the following format: width TAB height TAB bytesPerPixel TAB format. " - "It will return an empty string if the file is not found.\n" - "@ingroup Rendering\n") + "Loads an image from the source path, and scales it down to the target resolution before" + "Saving it out to the destination path.\n") { - Resource image = GBitmap::load(bitmapSource); - if (!image) - return false; + bool isDDS = false; - Torque::Path sourcePath = Torque::Path(bitmapSource); - - /*if (String("dds").equal(sourcePath.getExtension(), String::NoCase)) + //First, gotta check the extension, as we have some extra work to do if it's + //a DDS file + const char* ret = dStrrchr(bitmapSource, '.'); + if (ret) { - dds = DDSFile::load(correctPath, scalePower); + if (String::ToLower(ret) == String(".dds")) + isDDS = true; + } + else + { + return false; //no extension? bail out + } + + GBitmap* image; + if (isDDS) + { + Resource dds = DDSFile::load(bitmapSource, 0); if (dds != NULL) { + image = new GBitmap(); if (!dds->decompressToGBitmap(image)) { delete image; image = NULL; - return false; } } - }*/ - if (isPow2(image->getWidth())&& isPow2(image->getHeight())) + } + else + { + image = GBitmap::load(bitmapSource); + } + + if (!image) + return false; + Torque::Path sourcePath = Torque::Path(bitmapSource); + + if (isPow2(image->getWidth()) && isPow2(image->getHeight())) image->extrudeMipLevels(); U32 mipCount = image->getNumMipLevels(); @@ -1396,9 +1415,14 @@ DefineEngineFunction(saveScaledImage, bool, (const char* bitmapSource, const cha image->chopTopMips(mipCount - targetMips); } + //TODO: support different format targets, for now we just force + //to png for simplicity + Torque::Path destinationPath = Torque::Path(bitmapDest); + destinationPath.setExtension("png"); + // Open up the file on disk. FileStream fs; - if (!fs.open(bitmapDest, Torque::FS::File::Write)) + if (!fs.open(destinationPath.getFullPath(), Torque::FS::File::Write)) { Con::errorf("saveScaledImage() - Failed to open output file '%s'!", bitmapDest); return false; From 3e4cc0a5c6ea062ba443600c1235ad3f6752d87b Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 6 Mar 2022 13:18:06 -0600 Subject: [PATCH 038/145] fix probe baking typo --- .../shaders/lighting/advanced/reflectionProbeArrayP.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl index 1b49a5e41..d9314329e 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl @@ -190,6 +190,6 @@ float4 main(PFXVertToPix IN) : SV_TARGET #if CAPTURING == 1 return float4(lerp(surface.baseColor.rgb,(irradiance + specular* horizon) ,surface.metalness/2),0); #else - return result = float4((irradiance + specular* horizon) , 0);//alpha writes disabled + return float4((irradiance + specular* horizon) , 0);//alpha writes disabled #endif } From f1f73e41bd0bb324c1e8b0cc2d617243761e8162 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 6 Mar 2022 22:55:05 -0600 Subject: [PATCH 039/145] Fixes handlong of loading non-DDS images to better handle pointer references with the GBitmap resources. Also adds a sanity check for the source or dest strings so they can't be empty strings --- Engine/source/gfx/bitmap/gBitmap.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Engine/source/gfx/bitmap/gBitmap.cpp b/Engine/source/gfx/bitmap/gBitmap.cpp index 97e891fcf..ebd3741b1 100644 --- a/Engine/source/gfx/bitmap/gBitmap.cpp +++ b/Engine/source/gfx/bitmap/gBitmap.cpp @@ -1368,6 +1368,11 @@ DefineEngineFunction(saveScaledImage, bool, (const char* bitmapSource, const cha { bool isDDS = false; + if (bitmapSource == 0 || bitmapSource[0] == '\0' || bitmapDest == 0 || bitmapDest[0] == '\0') + { + return false; + } + //First, gotta check the extension, as we have some extra work to do if it's //a DDS file const char* ret = dStrrchr(bitmapSource, '.'); @@ -1381,7 +1386,7 @@ DefineEngineFunction(saveScaledImage, bool, (const char* bitmapSource, const cha return false; //no extension? bail out } - GBitmap* image; + GBitmap* image = NULL; if (isDDS) { Resource dds = DDSFile::load(bitmapSource, 0); @@ -1397,7 +1402,8 @@ DefineEngineFunction(saveScaledImage, bool, (const char* bitmapSource, const cha } else { - image = GBitmap::load(bitmapSource); + Resource resImage = GBitmap::load(bitmapSource); + image = new GBitmap(*resImage); } if (!image) From 1d5a36c4c078ee5da58fedce1ddeff33ec8a2f2d Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Tue, 8 Mar 2022 19:50:36 +0000 Subject: [PATCH 040/145] Spheres for Skies -Added: SkySphere a full sphere skyBox -Change: ScatterSky now renders a dome instead of the top face of a cubeSphere -Change: Creator now has skySphere TODO: Simplify sphere creation PossibleMethod: Add the sphere creation functions to one place to be shared around. --- Engine/source/environment/scatterSky.cpp | 167 +++-- Engine/source/environment/scatterSky.h | 21 + Engine/source/environment/skySphere.cpp | 645 ++++++++++++++++++ Engine/source/environment/skySphere.h | 172 +++++ .../assetBrowser/scripts/creator.tscript | 1 + .../scripts/editors/creator.ed.tscript | 1 + 6 files changed, 966 insertions(+), 41 deletions(-) create mode 100644 Engine/source/environment/skySphere.cpp create mode 100644 Engine/source/environment/skySphere.h diff --git a/Engine/source/environment/scatterSky.cpp b/Engine/source/environment/scatterSky.cpp index 5de3bdd94..12071d558 100644 --- a/Engine/source/environment/scatterSky.cpp +++ b/Engine/source/environment/scatterSky.cpp @@ -758,73 +758,146 @@ bool ScatterSky::_initShader() return true; } +void ScatterSky::clearVectors() +{ + tmpVertices.clear(); + vertsVec.clear(); +} + +void ScatterSky::addVertex(Point3F vert) +{ + vertsVec.push_back(vert.x); + vertsVec.push_back(vert.y); + vertsVec.push_back(vert.z); +} + +void ScatterSky::BuildFinalVert() +{ + U32 count = vertsVec.size(); + U32 i, j; + for (i = 0, j = 0; i < count; i += 3, j += 2) + { + FinalVertexData temp; + temp.pos.set(Point3F(vertsVec[i], vertsVec[i + 1], vertsVec[i + 2])); + + finalVertData.push_back(temp); + } +} + void ScatterSky::_initVBIB() { + U32 rings = 18; + U32 height = 9; + U32 radius = 10; + + F32 x, y, z, xy; // vertex position + + F32 ringStep = M_2PI / rings; + F32 heightStep = M_HALFPI / height; // M_PI for full sphere. + F32 ringAng, heightAng; + + //clear vecs + clearVectors(); + + for (U32 i = 0; i <= height; ++i) + { + heightAng = M_PI / 2 - (F32)i * heightStep; + xy = radius * mCos(heightAng); + z = radius * mSin(heightAng); + + for (U32 j = 0; j <= rings; ++j) + { + SphereVertex vert; + ringAng = j * ringStep; + x = xy * mCos(ringAng); + y = xy * mSin(ringAng); + vert.pos.set(Point3F(x, y, z)); + + tmpVertices.push_back(vert); + } + } + + SphereVertex v1, v2, v3, v4; + U32 vi1, vi2 = 0; + + for (U32 i = 0; i < height; ++i) + { + vi1 = i * (rings + 1); + vi2 = (i + 1) * (rings + 1); + + for (U32 j = 0; j < rings; ++j, ++vi1, ++vi2) + { + v1 = tmpVertices[vi1]; + v2 = tmpVertices[vi2]; + v3 = tmpVertices[vi1 + 1]; + v4 = tmpVertices[vi2 + 1]; + + // 1st = triangle. + if (i == 0) + { + // verts for tri. + addVertex(v1.pos); + addVertex(v2.pos); + addVertex(v4.pos); + } + /* UNCOMMENT WHEN FULL SPHERE + else if (i == (height - 1)) + { + // verts for tri. + addVertex(v1.pos); + addVertex(v2.pos); + addVertex(v3.pos); + }*/ + else + { + // verts for quad. + addVertex(v1.pos); + addVertex(v2.pos); + addVertex(v3.pos); + + addVertex(v3.pos); + addVertex(v4.pos); + addVertex(v2.pos); + } + } + } + + BuildFinalVert(); + // Vertex Buffer... - U32 vertStride = 50; - U32 strideMinusOne = vertStride - 1; - mVertCount = vertStride * vertStride; - mPrimCount = strideMinusOne * strideMinusOne * 2; - - Point3F vertScale( 16.0f, 16.0f, 4.0f ); - - F32 zOffset = -( mCos( mSqrt( 1.0f ) ) + 0.01f ); + mVertCount = finalVertData.size(); + mPrimCount = mVertCount / 3; mVB.set( GFX, mVertCount, GFXBufferTypeStatic ); GFXVertexP *pVert = mVB.lock(); if(!pVert) return; - for ( U32 y = 0; y < vertStride; y++ ) + for ( U32 i = 0; i < mVertCount; i++ ) { - F32 v = ( (F32)y / (F32)strideMinusOne - 0.5f ) * 2.0f; - - for ( U32 x = 0; x < vertStride; x++ ) - { - F32 u = ( (F32)x / (F32)strideMinusOne - 0.5f ) * 2.0f; - - F32 sx = u; - F32 sy = v; - F32 sz = (mCos( mSqrt( sx*sx + sy*sy ) ) * 1.0f) + zOffset; - //F32 sz = 1.0f; - pVert->point.set( sx, sy, sz ); - pVert->point *= vertScale; + pVert->point.set(finalVertData[i].pos); pVert->point.normalize(); pVert->point *= 200000.0f; - pVert++; - } } mVB.unlock(); // Primitive Buffer... - mPrimBuffer.set( GFX, mPrimCount * 3, mPrimCount, GFXBufferTypeStatic ); + mPrimBuffer.set( GFX, mVertCount, mPrimCount, GFXBufferTypeStatic ); U16 *pIdx = NULL; mPrimBuffer.lock(&pIdx); U32 curIdx = 0; - for ( U32 y = 0; y < strideMinusOne; y++ ) + for ( U32 i = 0, k = 0; i < mPrimCount; i++, k+=3 ) { - for ( U32 x = 0; x < strideMinusOne; x++ ) - { - U32 offset = x + y * vertStride; - - pIdx[curIdx] = offset; + pIdx[curIdx] = k; curIdx++; - pIdx[curIdx] = offset + 1; + pIdx[curIdx] = k + 1; curIdx++; - pIdx[curIdx] = offset + vertStride + 1; + pIdx[curIdx] = k + 2; curIdx++; - - pIdx[curIdx] = offset; - curIdx++; - pIdx[curIdx] = offset + vertStride + 1; - curIdx++; - pIdx[curIdx] = offset + vertStride; - curIdx++; - } } mPrimBuffer.unlock(); @@ -963,13 +1036,25 @@ void ScatterSky::_render( ObjectRenderInst *ri, SceneRenderState *state, BaseMat Point3F camPos2 = state->getCameraPosition(); MatrixF xfm(true); - xfm.setPosition(camPos2 - Point3F(0, 0, mZOffset)); + xfm.setPosition(Point3F( + camPos2.x, + camPos2.y, + mZOffset) ); + GFX->multWorld(xfm); MatrixF xform(proj);//GFX->getProjectionMatrix()); xform *= GFX->getViewMatrix(); xform *= GFX->getWorldMatrix(); + if(state->isReflectPass()) + { + static MatrixF rotMat(EulerF(0.0, 0.0, M_PI_F)); + xform.mul(rotMat); + rotMat.set(EulerF(M_PI_F, 0.0, 0.0)); + xform.mul(rotMat); + } + mShaderConsts->setSafe( mModelViewProjSC, xform ); mShaderConsts->setSafe( mMiscSC, miscParams ); mShaderConsts->setSafe( mSphereRadiiSC, sphereRadii ); diff --git a/Engine/source/environment/scatterSky.h b/Engine/source/environment/scatterSky.h index 0633e9e23..e544e64a5 100644 --- a/Engine/source/environment/scatterSky.h +++ b/Engine/source/environment/scatterSky.h @@ -104,6 +104,27 @@ public: /// F32 getElevation() const { return mSunElevation; } + struct SphereVertex + { + Point3F pos; + }; + + Vector tmpVertices; + Vector vertsVec; + + struct FinalVertexData + { + Point3F pos; + }; + + Vector finalVertData; + + void addVertex(Point3F vert); + + void BuildFinalVert(); + + void clearVectors(); + protected: void _render( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ); diff --git a/Engine/source/environment/skySphere.cpp b/Engine/source/environment/skySphere.cpp new file mode 100644 index 000000000..9f52c660c --- /dev/null +++ b/Engine/source/environment/skySphere.cpp @@ -0,0 +1,645 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "platform/platform.h" +#include "environment/skySphere.h" + +#include "console/consoleTypes.h" +#include "console/engineAPI.h" +#include "scene/sceneRenderState.h" +#include "renderInstance/renderPassManager.h" +#include "gfx/primBuilder.h" +#include "gfx/gfxTransformSaver.h" +#include "core/stream/fileStream.h" +#include "core/stream/bitStream.h" +#include "materials/materialManager.h" +#include "materials/materialFeatureTypes.h" +#include "materials/sceneData.h" +#include "T3D/gameFunctions.h" +#include "renderInstance/renderBinManager.h" +#include "materials/processedMaterial.h" +#include "gfx/gfxDebugEvent.h" +#include "math/util/matrixSet.h" + +IMPLEMENT_CO_NETOBJECT_V1(SkySphere); + +ConsoleDocClass(SkySphere, + "@brief Represents the sky with an artist-created spherical map.\n\n" + + "SkySphere is not a directional light and should be used in conjunction with a Sun object.\n\n" + + "@ingroup Atmosphere" +); + +SkySphere::SkySphere() +{ + mTypeMask |= EnvironmentObjectType | StaticObjectType; + mNetFlags.set(Ghostable | ScopeAlways); + + INIT_ASSET(Material); + mMatInstance = NULL; + + mIsVBDirty = false; + mPrimCount = 0; + mFogBandHeight = 0; + mFogPrimCount = 0; + + mMatrixSet = reinterpret_cast(dMalloc_aligned(sizeof(MatrixSet), 16)); + constructInPlace(mMatrixSet); + + mFogBandMat = NULL; + mFogBandMatInst = NULL; +} + +SkySphere::~SkySphere() +{ + dFree_aligned(mMatrixSet); + + if (mMatInstance) + SAFE_DELETE(mMatInstance); + + SAFE_DELETE(mFogBandMatInst); + + if (mFogBandMat) + { + mFogBandMat->deleteObject(); + mFogBandMat = NULL; + } +} + +bool SkySphere::onAdd() +{ + if (!Parent::onAdd()) + return false; + + setGlobalBounds(); + resetWorldBox(); + + addToScene(); + + if (isClientObject()) + { + _initRender(); + _updateMaterial(); + } + + return true; +} + +void SkySphere::onRemove() +{ + removeFromScene(); + Parent::onRemove(); +} + +void SkySphere::initPersistFields() +{ + addGroup("Sky Sphere"); + + INITPERSISTFIELD_MATERIALASSET(Material, SkySphere, "The name of a cubemap material for the sky box."); + + addField("fogBandHeight", TypeF32, Offset(mFogBandHeight, SkySphere), + "The height (0-1) of the fog band from the horizon to the top of the SkySphere."); + + endGroup("Sky Sphere"); + + Parent::initPersistFields(); +} + +void SkySphere::inspectPostApply() +{ + Parent::inspectPostApply(); + _updateMaterial(); +} + +U32 SkySphere::packUpdate(NetConnection* conn, U32 mask, BitStream* stream) +{ + U32 retMask = Parent::packUpdate(conn, mask, stream); + + PACK_ASSET(conn, Material); + + stream->write(mFogBandHeight); + + return retMask; +} + +void SkySphere::unpackUpdate(NetConnection* conn, BitStream* stream) +{ + Parent::unpackUpdate(conn, stream); + + StringTableEntry oldMatName = getMaterial(); + UNPACK_ASSET(conn, Material); + if (oldMatName != getMaterial()) + { + _updateMaterial(); + } + + F32 bandHeight = 0; + stream->read(&bandHeight); + + // If this flag has changed + // we need to update the vertex buffer. + if ( bandHeight != mFogBandHeight) + { + mFogBandHeight = bandHeight; + mIsVBDirty = true; + _initRender(); + } +} + +void SkySphere::prepRenderImage(SceneRenderState* state) +{ + PROFILE_SCOPE(SkySphere_prepRenderImage); + + if (state->isShadowPass() || + mVB.isNull() || + mFogBandVB.isNull() || + !mMatInstance) + return; + + mMatrixSet->setSceneView(GFX->getWorldMatrix()); + mMatrixSet->setSceneProjection(GFX->getProjectionMatrix()); + + ObjectRenderInst* ri = state->getRenderPass()->allocInst(); + ri->renderDelegate.bind(this, &SkySphere::_renderObject); + ri->type = RenderPassManager::RIT_Sky; + ri->defaultKey = 10; + ri->defaultKey2 = 0; + state->getRenderPass()->addInst(ri); +} + +void SkySphere::_renderObject(ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* mi) +{ + GFXDEBUGEVENT_SCOPE(SkySphere_RenderObject, ColorI::WHITE); + + GFXTransformSaver saver; + GFX->setVertexBuffer(mVB); + + MatrixF worldMat = MatrixF::Identity; + worldMat.setPosition(Point3F( + state->getCameraPosition().x, + state->getCameraPosition().y, + state->getCameraPosition().z)); + + SceneData sgData; + sgData.init(state); + sgData.objTrans = &worldMat; + + mMatrixSet->restoreSceneViewProjection(); + mMatrixSet->setWorld(worldMat); + if (state->isReflectPass()) + mMatrixSet->setProjection(state->getSceneManager()->getNonClipProjection()); + + while (mMatInstance->setupPass(state, sgData)) + { + mMatInstance->setTransforms(*mMatrixSet, state); + mMatInstance->setSceneInfo(state, sgData); + + GFX->drawPrimitive(GFXTriangleList, 0, mPrimCount); + } + + // Draw render band. + if (mFogBandHeight > 0 && mFogBandMatInst) + { + const FogData& fog = state->getSceneManager()->getFogData(); + if (mLastFogColor != fog.color) + { + mLastFogColor = fog.color; + _initRender(); + } + + // Just need it to follow the camera... no rotation. + MatrixF camPosMat(MatrixF::Identity); + camPosMat.setPosition(worldMat.getPosition()); + sgData.objTrans = &camPosMat; + mMatrixSet->setWorld(*sgData.objTrans); + + while (mFogBandMatInst->setupPass(state, sgData)) + { + mFogBandMatInst->setTransforms(*mMatrixSet, state); + mFogBandMatInst->setSceneInfo(state, sgData); + + GFX->setVertexBuffer(mFogBandVB); + GFX->drawPrimitive(GFXTriangleList, 0, mFogPrimCount); + } + } +} + +void SkySphere::clearVectors() +{ + tmpVertices.clear(); + finalFogVertex.clear(); + tempFogVertex.clear(); + colVec.clear(); + fogVerts.clear(); + vertsVec.clear(); + normsVec.clear(); + texCoordVec.clear(); + finalVertData.clear(); +} + +void SkySphere::addVertex(Point3F vert) +{ + vertsVec.push_back(vert.x); + vertsVec.push_back(vert.y); + vertsVec.push_back(vert.z); +} + +void SkySphere::addNormal(Point3F nor) +{ + normsVec.push_back(nor.x); + normsVec.push_back(nor.y); + normsVec.push_back(nor.z); +} + +void SkySphere::addTexcoord(F32 s, F32 t) +{ + texCoordVec.push_back(s); + texCoordVec.push_back(t); +} + +void SkySphere::addColor(ColorI col) +{ + colVec.push_back(col); +} + +void SkySphere::BuildFinalVert() +{ + U32 count = vertsVec.size(); + U32 i, j; + for (i = 0, j = 0; i < count; i += 3, j += 2) + { + FinalVertexData temp; + temp.pos.set(Point3F(vertsVec[i], vertsVec[i + 1], vertsVec[i + 2])); + temp.nor.set(Point3F(normsVec[i], normsVec[i + 1], normsVec[i + 2])); + temp.s = texCoordVec[j]; + temp.t = texCoordVec[j+1]; + + finalVertData.push_back(temp); + } +} + +void SkySphere::BuildFinalFogVert() +{ + U32 count = vertsVec.size(); + U32 i, j; + for (i = 0, j = 0; i < count; i+=3, j++ ) + { + FogVertex temp; + temp.pos.set(Point3F(vertsVec[i], vertsVec[i + 1], vertsVec[i + 2])); + temp.col = colVec[j]; + + finalFogVertex.push_back(temp); + } +} + +void SkySphere::_initRender() +{ + U32 rings = 32; + U32 height = 16; + U32 radius = 1; + + F32 x, y, z, xy; // vertex position + F32 nx, ny, nz, lengthInv = 1.0f / radius; // normal + F32 s, t; // texCoord + + F32 ringStep = M_2PI / rings; + F32 heightStep = M_PI / height; // M_HALFPI for dome. + F32 ringAng, heightAng; + + //clear vecs + clearVectors(); + + for (U32 i = 0; i <= height; ++i) + { + heightAng = M_PI / 2 - (F32)i * heightStep; + F32 xy = radius * mCos(heightAng); + F32 z = radius * mSin(heightAng); + + for (U32 j = 0; j <= rings; ++j) + { + SphereVertex vert; + ringAng = j * ringStep; + x = xy * mCos(ringAng); + y = xy * mSin(ringAng); + vert.pos.set(Point3F(x,y,z)); + + nx = x * lengthInv; + ny = y * lengthInv; + nz = z * lengthInv; + vert.nor.set(Point3F(nx, ny, nz)); + + s = (F32)j / rings; + t = (F32)i / height; + vert.s = s; + vert.t = t; + + tmpVertices.push_back(vert); + } + } + + SphereVertex v1, v2, v3, v4; + U32 vi1, vi2 = 0; + + for (U32 i = 0; i < height; ++i) + { + vi1 = i * (rings + 1); + vi2 = (i + 1) * (rings + 1); + + for (U32 j = 0; j < rings; ++j, ++vi1, ++vi2) + { + v1 = tmpVertices[vi1]; + v2 = tmpVertices[vi2]; + v3 = tmpVertices[vi1 + 1]; + v4 = tmpVertices[vi2 + 1]; + + // 1st = triangle. + if (i == 0) + { + // verts for tri. + addVertex(v1.pos); + addVertex(v2.pos); + addVertex(v4.pos); + + // texcoords for tri. + addTexcoord(v1.s, v1.t); + addTexcoord(v2.s, v2.t); + addTexcoord(v4.s, v4.t); + + // normals for tri. + addNormal(v1.nor); + addNormal(v2.nor); + addNormal(v4.nor); + } + else if (i == (height - 1)) + { + // verts for tri. + addVertex(v1.pos); + addVertex(v2.pos); + addVertex(v3.pos); + + // texcoords for tri. + addTexcoord(v1.s, v1.t); + addTexcoord(v2.s, v2.t); + addTexcoord(v3.s, v3.t); + + // normals for quad. + addNormal(v1.nor); + addNormal(v2.nor); + addNormal(v3.nor); + } + else + { + // verts for quad. + addVertex(v1.pos); + addVertex(v2.pos); + addVertex(v3.pos); + + addVertex(v3.pos); + addVertex(v4.pos); + addVertex(v2.pos); + + // texcoords for quad. + addTexcoord(v1.s, v1.t); + addTexcoord(v2.s, v2.t); + addTexcoord(v3.s, v3.t); + + addTexcoord(v3.s, v3.t); + addTexcoord(v4.s, v4.t); + addTexcoord(v2.s, v2.t); + + // normals for quad. + addNormal(v1.nor); + addNormal(v2.nor); + addNormal(v3.nor); + + addNormal(v3.nor); + addNormal(v4.nor); + addNormal(v2.nor); + } + } + } + + BuildFinalVert(); + + GFXVertexPNT* tmpVerts = NULL; + U32 vertCount = finalVertData.size(); + tmpVerts = new GFXVertexPNT[(vertCount)]; + mPrimCount = vertCount / 3; + + for (U32 i = 0; i < vertCount; i++) + { + tmpVerts[i].point.set(finalVertData[i].pos); + tmpVerts[i].normal.set(finalVertData[i].nor); + tmpVerts[i].texCoord.set(finalVertData[i].s, finalVertData[i].t); + } + + if (mVB.isNull() || mIsVBDirty) + { + mVB.set(GFX, vertCount, GFXBufferTypeStatic); + mIsVBDirty = false; + } + + GFXVertexPNT* vertPtr = mVB.lock(); + if (!vertPtr) + { + delete[] tmpVerts; + return; + } + + dMemcpy(vertPtr, tmpVerts, sizeof(GFXVertexPNT) * vertCount); + + mVB.unlock(); + + // Clean up temp verts. + delete[] tmpVerts; + + // Grab the fog color. + ColorI fogColor(mLastFogColor.red * 255, mLastFogColor.green * 255, mLastFogColor.blue * 255); + ColorI fogColorAlpha(mLastFogColor.red * 255, mLastFogColor.green * 255, mLastFogColor.blue * 255, 0); + + clearVectors(); + + U32 stepCount = 16; + F32 cylStep = M_2PI / stepCount; + F32 cylAngle; + F32 cylRadius = 10; + + for (U32 i = 0; i <= stepCount; ++i) + { + cylAngle = (F32)i * cylStep; + fogVerts.push_back(mCos(cylAngle)); + fogVerts.push_back(mSin(cylAngle)); + } + + for (U32 i = 0; i < 2; ++i) + { + for (U32 j = 0, k = 0; j <= stepCount; ++j, k += 2) + { + FogVertex temp; + F32 ux = fogVerts[k]; + F32 uy = fogVerts[k+1]; + + if (i > 0) + { + temp.pos.set(Point3F((ux * cylRadius), (uy * cylRadius), mFogBandHeight)); + temp.col = fogColorAlpha; + } + else + { + temp.pos.set(Point3F((ux * cylRadius), (uy * cylRadius), -mFogBandHeight)); + temp.col = fogColor; + } + + tempFogVertex.push_back(temp); + } + } + + FogVertex f1, f2, f3, f4; + U32 k1 = 0; + U32 k2 = stepCount + 1; + + for (U32 i = 0; i < stepCount; ++i, ++k1, ++k2) + { + f1 = tempFogVertex[k1]; + f2 = tempFogVertex[k1 + 1]; + f3 = tempFogVertex[k2]; + f4 = tempFogVertex[k2 + 1]; + addVertex(f3.pos); + addVertex(f2.pos); + addVertex(f4.pos); + addColor(f3.col); + addColor(f2.col); + addColor(f4.col); + addVertex(f1.pos); + addVertex(f2.pos); + addVertex(f3.pos); + addColor(f1.col); + addColor(f2.col); + addColor(f3.col); + } + + BuildFinalFogVert(); + + U32 fogVertCount = finalFogVertex.size(); + mFogPrimCount = fogVertCount / 3; + + if (mFogBandVB.isNull()) + mFogBandVB.set(GFX, fogVertCount, GFXBufferTypeStatic); + + GFXVertexPC* bandVertPtr = mFogBandVB.lock(); + if (!bandVertPtr) return; + + for (U32 i = 0; i < fogVertCount; i++) + { + bandVertPtr[i].point.set(finalFogVertex[i].pos); + bandVertPtr[i].color.set(finalFogVertex[i].col); + } + + mFogBandVB.unlock(); + + SAFE_DELETE(mFogBandMatInst); + if (mFogBandMat) + { + mFogBandMat->deleteObject(); + mFogBandMat = NULL; + } + + // Setup the material for this imposter. + mFogBandMat = MATMGR->allocateAndRegister(String::EmptyString); + mFogBandMat->mAutoGenerated = true; + mFogBandMat->mTranslucent = true; + mFogBandMat->mVertColor[0] = true; + mFogBandMat->mDoubleSided = true; + mFogBandMat->mEmissive[0] = true; + + FeatureSet features = MATMGR->getDefaultFeatures(); + features.addFeature(MFT_isBackground); + mFogBandMatInst = mFogBandMat->createMatInstance(); + mFogBandMatInst->init(features, getGFXVertexFormat()); +} + +void SkySphere::onStaticModified(const char* slotName, const char* newValue) +{ + Parent::onStaticModified(slotName, newValue); + + if (dStricmp(slotName, "material") == 0) + setMaskBits(0xFFFFFFFF); +} + +void SkySphere::_initMaterial() +{ + if (mMatInstance) + SAFE_DELETE(mMatInstance); + + if (mMaterial) + mMatInstance = mMaterial->createMatInstance(); + else + mMatInstance = MATMGR->createMatInstance("WarningMaterial"); + + // We want to disable culling and z write. + GFXStateBlockDesc desc; + desc.setCullMode(GFXCullNone); + desc.setBlend(true); + desc.setZReadWrite(true, false); + desc.zFunc = GFXCmpLessEqual; + mMatInstance->addStateBlockDesc(desc); + + // Also disable lighting on the skysphere material by default. + FeatureSet features = MATMGR->getDefaultFeatures(); + features.removeFeature(MFT_RTLighting); + features.removeFeature(MFT_Visibility); + features.addFeature(MFT_isBackground); + + // Now initialize the material. + mMatInstance->init(features, getGFXVertexFormat()); +} + +void SkySphere::_updateMaterial() +{ + if (!getMaterialResource().isValid()) + { + //If our materialDef isn't valid, try setting it + _setMaterial(getMaterial()); + } + + if (getMaterialResource().isValid()) + { + _initMaterial(); + } +} + +BaseMatInstance* SkySphere::_getMaterialInstance() +{ + if (!mMaterial || !mMatInstance || mMatInstance->getMaterial() != mMaterial) + _initMaterial(); + + if (!mMatInstance) + return NULL; + + return mMatInstance; +} + +DefineEngineMethod(SkySphere, postApply, void, (), , "") +{ + object->inspectPostApply(); +} diff --git a/Engine/source/environment/skySphere.h b/Engine/source/environment/skySphere.h new file mode 100644 index 000000000..37a6fbd12 --- /dev/null +++ b/Engine/source/environment/skySphere.h @@ -0,0 +1,172 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef _SKYSPHERE_H_ +#define _SKYSPHERE_H_ + +#ifndef _SCENEOBJECT_H_ +#include "scene/sceneObject.h" +#endif + +#ifndef _GFXDEVICE_H_ +#include "gfx/gfxDevice.h" +#endif + +#ifndef _CUBEMAPDATA_H_ +#include "gfx/sim/cubemapData.h" +#endif + +#ifndef _MATERIALLIST_H_ +#include "materials/materialList.h" +#endif + +#ifndef _GFXVERTEXBUFFER_H_ +#include "gfx/gfxVertexBuffer.h" +#endif + +#ifndef _GFXPRIMITIVEBUFFER_H_ +#include "gfx/gfxPrimitiveBuffer.h" +#endif + +#include "T3D/assets/MaterialAsset.h" + +struct SkyMatParams +{ + void init(BaseMatInstance* matInst) {}; +}; + +class MatrixSet; + +class SkySphere : public SceneObject +{ + typedef SceneObject Parent; + +public: + + SkySphere(); + virtual ~SkySphere(); + + DECLARE_CONOBJECT(SkySphere); + + // SimObject + void onStaticModified(const char* slotName, const char* newValue); + + // ConsoleObject + virtual bool onAdd(); + virtual void onRemove(); + static void initPersistFields(); + virtual void inspectPostApply(); + + // NetObject + virtual U32 packUpdate(NetConnection* conn, U32 mask, BitStream* stream); + virtual void unpackUpdate(NetConnection* conn, BitStream* stream); + + // SceneObject + void prepRenderImage(SceneRenderState* state); + + /// Our render delegate. + void _renderObject(ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* mi); + + void clearVectors(); + + void addVertex(Point3F vert); + + void addNormal(Point3F nor); + + void addTexcoord(F32 s, F32 t); + + void addColor(ColorI col); + + void BuildFinalVert(); + + void BuildFinalFogVert(); + + /// Prepares rendering structures and geometry. + void _initRender(); + + struct SphereVertex + { + Point3F pos; + Point3F nor; + F32 s, t; + }; + + Vector tmpVertices; + Vector vertsVec; + Vector texCoordVec; + Vector normsVec; + + struct FinalVertexData + { + Point3F pos; + Point3F nor; + F32 s; + F32 t; + }; + + Vector finalVertData; + + struct FogVertex + { + // might need normals for smoothing. + Point3F pos; + ColorI col; + }; + + Vector finalFogVertex; + Vector tempFogVertex; + Vector colVec; + Vector fogVerts; + +protected: + + // Material + DECLARE_MATERIALASSET(SkySphere, Material); + DECLARE_ASSET_NET_SETGET(SkySphere, Material, -1); + + BaseMatInstance* mMatInstance; + SkyMatParams mMatParamHandle; + + GFXVertexBufferHandle mVB; + + GFXVertexBufferHandle mFogBandVB; + Material* mFogBandMat; + BaseMatInstance* mFogBandMatInst; + + LinearColorF mLastFogColor; + + bool mIsVBDirty; + U32 mPrimCount; + + MatrixSet* mMatrixSet; + + F32 mFogBandHeight; + U32 mFogPrimCount; + + void _updateMaterial(); + void _initMaterial(); + + BaseMatInstance* _getMaterialInstance(); + +}; + +#endif diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/creator.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/creator.tscript index 26bc7202b..803a5933a 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/creator.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/creator.tscript @@ -26,6 +26,7 @@ function AssetBrowser::loadCreatorClasses(%this) %this.addCreatorClass( "RibbonNode", "Ribbon Emitter" ); %this.addCreatorClass( "ScatterSky", "Scatter Sky" ); %this.addCreatorClass( "SkyBox", "Sky Box" ); + %this.addCreatorClass( "SkySphere", "Sky Sphere" ); %this.addCreatorClass( "SFXEmitter", "Sound Emitter" ); %this.addCreatorClass( "TerrainBlock", "Terrain Block" ); %this.addCreatorClass( "VolumetricFog", "Volumetric Fog" ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript index 7ec1015a7..9524a7849 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript @@ -37,6 +37,7 @@ function ObjectCreator::init( %this ) // Removed Prefab as there doesn't really seem to be a point in creating a blank one //%this.registerMissionObject( "Prefab", "Prefab" ); %this.registerMissionObject( "SkyBox", "Sky Box" ); + %this.registerMissionObject( "SkySphere", "Sky Sphere" ); %this.registerMissionObject( "CloudLayer", "Cloud Layer" ); %this.registerMissionObject( "BasicClouds", "Basic Clouds" ); %this.registerMissionObject( "ScatterSky", "Scatter Sky" ); From bbf92846c21f5abc45d7989d6bed098df373d1a4 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Tue, 8 Mar 2022 19:52:47 +0000 Subject: [PATCH 041/145] Update scatterSky.cpp --- Engine/source/environment/scatterSky.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Engine/source/environment/scatterSky.cpp b/Engine/source/environment/scatterSky.cpp index 12071d558..8b5f69a7b 100644 --- a/Engine/source/environment/scatterSky.cpp +++ b/Engine/source/environment/scatterSky.cpp @@ -1047,14 +1047,6 @@ void ScatterSky::_render( ObjectRenderInst *ri, SceneRenderState *state, BaseMat xform *= GFX->getViewMatrix(); xform *= GFX->getWorldMatrix(); - if(state->isReflectPass()) - { - static MatrixF rotMat(EulerF(0.0, 0.0, M_PI_F)); - xform.mul(rotMat); - rotMat.set(EulerF(M_PI_F, 0.0, 0.0)); - xform.mul(rotMat); - } - mShaderConsts->setSafe( mModelViewProjSC, xform ); mShaderConsts->setSafe( mMiscSC, miscParams ); mShaderConsts->setSafe( mSphereRadiiSC, sphereRadii ); From 382ee60d8616331564b7cb125e4fda55c85e102d Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Tue, 8 Mar 2022 20:18:47 +0000 Subject: [PATCH 042/145] Sky Sorting -Change: ScatterSky is always drawn behind other sky objects (since it has sun and moon) --- Engine/source/environment/scatterSky.cpp | 4 ++-- Engine/source/environment/skyBox.cpp | 2 +- Engine/source/environment/skySphere.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Engine/source/environment/scatterSky.cpp b/Engine/source/environment/scatterSky.cpp index 8b5f69a7b..e7472973b 100644 --- a/Engine/source/environment/scatterSky.cpp +++ b/Engine/source/environment/scatterSky.cpp @@ -651,7 +651,7 @@ void ScatterSky::prepRenderImage( SceneRenderState *state ) ObjectRenderInst *ri = renderPass->allocInst(); ri->renderDelegate.bind( this, &ScatterSky::_render ); ri->type = RenderPassManager::RIT_Sky; - ri->defaultKey = 10; + ri->defaultKey = 15; ri->defaultKey2 = 0; renderPass->addInst(ri); @@ -700,7 +700,7 @@ void ScatterSky::prepRenderImage( SceneRenderState *state ) moonRI->renderDelegate.bind( this, &ScatterSky::_renderMoon ); moonRI->type = RenderPassManager::RIT_Sky; // Render after sky objects and before CloudLayer! - moonRI->defaultKey = 5; + moonRI->defaultKey = 10; moonRI->defaultKey2 = 0; renderPass->addInst(moonRI); } diff --git a/Engine/source/environment/skyBox.cpp b/Engine/source/environment/skyBox.cpp index 468ecb8dd..8bd378272 100644 --- a/Engine/source/environment/skyBox.cpp +++ b/Engine/source/environment/skyBox.cpp @@ -645,4 +645,4 @@ BaseMatInstance* SkyBox::_getMaterialInstance() DefineEngineMethod( SkyBox, postApply, void, (), , "") { object->inspectPostApply(); -} \ No newline at end of file +} diff --git a/Engine/source/environment/skySphere.cpp b/Engine/source/environment/skySphere.cpp index 9f52c660c..a367b8854 100644 --- a/Engine/source/environment/skySphere.cpp +++ b/Engine/source/environment/skySphere.cpp @@ -182,7 +182,7 @@ void SkySphere::prepRenderImage(SceneRenderState* state) ObjectRenderInst* ri = state->getRenderPass()->allocInst(); ri->renderDelegate.bind(this, &SkySphere::_renderObject); ri->type = RenderPassManager::RIT_Sky; - ri->defaultKey = 10; + ri->defaultKey = 9; ri->defaultKey2 = 0; state->getRenderPass()->addInst(ri); } From 4d336e9ecfdfcb039bd6e461270f667b16ae531c Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 8 Mar 2022 17:52:42 -0600 Subject: [PATCH 043/145] ensure MissionCleanup exists before .mis load --- .../clientServer/scripts/server/levelLoad.tscript | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/levelLoad.tscript b/Templates/BaseGame/game/core/clientServer/scripts/server/levelLoad.tscript index 9bb2457ac..86e0d8b5f 100644 --- a/Templates/BaseGame/game/core/clientServer/scripts/server/levelLoad.tscript +++ b/Templates/BaseGame/game/core/clientServer/scripts/server/levelLoad.tscript @@ -86,6 +86,13 @@ function loadMissionStage2() // Create the mission group off the ServerGroup $instantGroup = ServerGroup; + // Mission cleanup group. This is where run time components will reside. The MissionCleanup + // group will be added to the ServerGroup. + new SimGroup( MissionCleanup ); + + // Make the MissionCleanup group the place where all new objects will automatically be added. + $instantGroup = MissionCleanup; + // Make sure the mission exists %file = $Server::MissionFile; @@ -120,12 +127,6 @@ function loadMissionStage2() if( isObject( theLevelInfo ) ) $Server::MissionName = theLevelInfo.levelName; - // Mission cleanup group. This is where run time components will reside. The MissionCleanup - // group will be added to the ServerGroup. - new SimGroup( MissionCleanup ); - - // Make the MissionCleanup group the place where all new objects will automatically be added. - $instantGroup = MissionCleanup; %hasGameMode = callGamemodeFunction("onCreateGame"); From 8dcd74ff1832fe83e2dfebb7641098caea6b3834 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Wed, 9 Mar 2022 18:21:47 -0600 Subject: [PATCH 044/145] point baseline fog color at the right target hen in deferred mode --- Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp | 2 ++ Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp index 06d146c39..831808c76 100644 --- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp @@ -2318,6 +2318,8 @@ void FogFeatGLSL::processPix( Vector &componentList, // Get the out color. Var *color = (Var*) LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget)); + if (fd.features[MFT_isDeferred]) + color = (Var *)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1)); if ( !color ) { color = new Var; diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp index 7361e2eaf..d4e3acda4 100644 --- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp @@ -2396,6 +2396,8 @@ void FogFeatHLSL::processPix( Vector &componentList, // Get the out color. Var *color = (Var*) LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget)); + if (fd.features[MFT_isDeferred]) + color = (Var *)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1)); if ( !color ) { color = new Var; From 23b908da56c9369446dcd99d23287538c8691d0e Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 15 Mar 2022 19:26:37 -0500 Subject: [PATCH 045/145] crashfix and projection fix for spotlights with cookies --- .../lighting/advanced/gl/spotLightP.glsl | 24 +++++++------- .../shaders/lighting/advanced/spotLightP.hlsl | 31 +++++++++---------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl index 6c80cc1eb..5d0079afa 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl @@ -96,6 +96,8 @@ void main() if(dist < lightRange) { SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L); + vec3 lightCol = lightColor.rgb; + #ifdef NO_SHADOW float shadowed = 1.0; #else @@ -107,20 +109,18 @@ void main() //distance to light in shadow map space float distToLight = pxlPosLightProj.z / lightRange; float shadowed = softShadow_filter(shadowMap, ssPos.xy/ssPos.w, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y); + #ifdef USE_COOKIE_TEX + // Lookup the cookie sample. + vec4 cookie = texture(cookieMap, shadowCoord); + // Multiply the light with the cookie tex. + lightCol *= cookie.rgb; + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + lightCol *= max(cookie.r, max(cookie.g, cookie.b)); + #endif #endif - vec3 lightCol = lightColor.rgb; - #ifdef USE_COOKIE_TEX - - // Lookup the cookie sample. - vec4 cookie = texture(cookieMap, tMul(worldToLightProj, -surfaceToLight.L)); - // Multiply the light with the cookie tex. - lightCol *= cookie.rgb; - // Use a maximum channel luminance to attenuate - // the lighting else we get specular in the dark - // regions of the cookie texture. - lightCol *= max(cookie.r, max(cookie.g, cookie.b)); - #endif #ifdef DIFFUSE_LIGHT_VIZ float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl index fb3d4aae0..15b4b4e37 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl @@ -43,7 +43,7 @@ TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1); #ifdef USE_COOKIE_TEX /// The texture for cookie rendering. -TORQUE_UNIFORM_SAMPLER2D(cookieMap, 3); +TORQUE_UNIFORM_SAMPLER2D(cookieMap, 2); #endif TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 5); @@ -101,6 +101,8 @@ float4 main( ConvexConnectP IN ) : SV_TARGET if(dist < lightRange) { SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L); + float3 lightCol = lightColor.rgb; + #ifdef NO_SHADOW float shadowed = 1.0; #else @@ -108,23 +110,20 @@ float4 main( ConvexConnectP IN ) : SV_TARGET float4 pxlPosLightProj = mul( worldToLightProj, float4( surface.P, 1 ) ); float2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 ); shadowCoord.y = 1.0f - shadowCoord.y; - - //distance to light in shadow map space + //distance to light in shadow map space float distToLight = pxlPosLightProj.z / lightRange; float shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap), ssPos.xy, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y); - #endif - - float3 lightCol = lightColor.rgb; - #ifdef USE_COOKIE_TEX - // Lookup the cookie sample. - float4 cookie = TORQUE_TEXCUBE(cookieMap, mul(worldToLightProj, -surfaceToLight.L)); - // Multiply the light with the cookie tex. - lightCol *= cookie.rgb; - // Use a maximum channel luminance to attenuate - // the lighting else we get specular in the dark - // regions of the cookie texture. - lightCol *= max(cookie.r, max(cookie.g, cookie.b)); - #endif + #ifdef USE_COOKIE_TEX + // Lookup the cookie sample. + float4 cookie = TORQUE_TEX2D(cookieMap, shadowCoord); + // Multiply the light with the cookie tex. + lightCol *= cookie.rgb; + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + lightCol *= max(cookie.r, max(cookie.g, cookie.b)); + #endif + #endif #ifdef DIFFUSE_LIGHT_VIZ float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); From 1496ffac6ec9f0b37d38475db5747aee27695b67 Mon Sep 17 00:00:00 2001 From: JeffR Date: Tue, 15 Mar 2022 21:10:55 -0500 Subject: [PATCH 046/145] Adds a systemCommand console utility function, which invokes the standard system() function call, and also has an optional callback return parameter. --- Engine/source/console/consoleFunctions.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Engine/source/console/consoleFunctions.cpp b/Engine/source/console/consoleFunctions.cpp index a4b50cfcc..099f7090d 100644 --- a/Engine/source/console/consoleFunctions.cpp +++ b/Engine/source/console/consoleFunctions.cpp @@ -2859,3 +2859,21 @@ DefineEngineFunction(getTimestamp, const char*, (), , return returnBuffer; } + +#ifdef TORQUE_TOOLS +DefineEngineFunction(systemCommand, S32, (const char* commandLineAction, const char* callBackFunction), , "", "") +{ + if (commandLineAction != "") + { + S32 result = system(commandLineAction); + + if (callBackFunction != "" && callBackFunction[0]) + { + if (Con::isFunction(callBackFunction)) + Con::executef(callBackFunction, result); + } + } + + return -1; +} +#endif From b36776d56748c024a35d067faca4c8ab532bf65b Mon Sep 17 00:00:00 2001 From: JeffR Date: Tue, 15 Mar 2022 21:17:37 -0500 Subject: [PATCH 047/145] Tweaks handling of "invisible" files, files which start with a ., effectively making them have no filename and only an extension. This allows the engine to actually process and work with such files. --- Engine/source/console/fileSystemFunctions.cpp | 9 +++++++++ Engine/source/core/volume.cpp | 4 ---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index eea26a984..010147af2 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -395,6 +395,15 @@ DefineEngineFunction(isFile, bool, ( const char* fileName ),, Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), cleanfilename.c_str()); Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer)); + + if (givenPath.getFileName().isEmpty() && givenPath.getExtension().isNotEmpty()) + { + //specially named or hidden files, like .gitignore parse incorrectly due to having + //"no" filename, so we adjust that + givenPath.setFileName(String(".") + givenPath.getExtension()); + givenPath.setExtension(""); + } + return Torque::FS::IsFile(givenPath); } diff --git a/Engine/source/core/volume.cpp b/Engine/source/core/volume.cpp index d056ee331..c3243623a 100644 --- a/Engine/source/core/volume.cpp +++ b/Engine/source/core/volume.cpp @@ -750,10 +750,6 @@ S32 MountSystem::findByPattern( const Path &inBasePath, const String &inFilePatt while ( dir->read( &attrs ) ) { - // skip hidden files - if ( attrs.name.c_str()[0] == '.' ) - continue; - String name( attrs.name ); if ( (attrs.flags & FileNode::Directory) && inRecursive ) From 532200ff4337aaca3f4dbcb9d9b6d10de3aaa2ca Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 17 Mar 2022 00:03:22 -0500 Subject: [PATCH 048/145] Changes the creation of new materials in the material editor to go through the new asset interface, which ensures the creation is standardized across the board. --- .../scripts/assetTypes/material.tscript | 1 - .../scripts/materialEditor.ed.tscript | 36 ++++--------------- 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index 18305b920..3ea2a285b 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript @@ -14,7 +14,6 @@ function AssetBrowser::createMaterialAsset(%this) AssetName = %assetName; versionId = 1; materialDefinitionName = %assetName; - scriptFile = %assetName @ "." @ $TorqueScriptFileExtension; new Material(%assetName) { }; diff --git a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript index 882ec9dc2..56ac83a96 100644 --- a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript @@ -1971,39 +1971,15 @@ function MaterialEditorGui::save( %this ) function MaterialEditorGui::createNewMaterial( %this ) { - AssetBrowser_SelectModule.showDialog("MaterialEditorGui.pickedNewMaterialTargetModule"); - AssetBrowser_SelectModuleWindow.selectWindow(); + AssetBrowser.setupCreateNewAsset("MaterialAsset", AssetBrowser.selectedModule, "MaterialEditorGui.onCreateNewMaterialAsset"); } -function MaterialEditorGui::pickedNewMaterialTargetModule( %this, %module ) +function MaterialEditorGui::onCreateNewMaterialAsset(%this, %newAssetId) { - %moduleDef = ModuleDatabase.findModule(%module); - PE_EmitterEditor.targetModule = %module; - MaterialEditorGui.defaultMaterialFile = %moduleDef.ModulePath @ "/scripts/managedData/materials." @ $TorqueScriptFileExtension; - - if(!isDirectory(filePath(MaterialEditorGui.defaultMaterialFile))) - { - AssetBrowser.dirHandler.createFolder(filePath(MaterialEditorGui.defaultMaterialFile)); - } - - %action = %this.createUndo(ActionCreateNewMaterial, "Create New Material"); - %action.object = ""; - - %material = getUniqueName( "newMaterial" ); - new Material(%material) - { - mapTo = "unmapped_mat"; - parentGroup = RootGroup; - }; - - %action.newMaterial = %material.getId(); - %action.oldMaterial = MaterialEditorGui.currentMaterial; - - MaterialEditorGui.submitUndo( %action ); - - MaterialEditorGui.currentObject = ""; - MaterialEditorGui.setMode(); - MaterialEditorGui.prepareActiveMaterial( %material.getId(), true ); + //get the new asset definition + %assetDef = AssetDatabase.acquireAsset(%newAssetId); + if(isObject(%assetDef)) + AssetBrowser.editMaterialAsset(%assetDef); } function MaterialEditorGui::deleteMaterial( %this ) From 2c999008f1f134509bc3798e6ee6a32661aac612 Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 17 Mar 2022 02:43:18 -0500 Subject: [PATCH 049/145] Fixes and cleans up various issues and error spam for core and tools folders Also: Fixes error spam about CreatorIconArray Fixes error spam about duplicate uses of various materials Converts a number of materials to be packed into the mat assets for cleanliness and preventing unwanted duplicate exec's Removed some extraneous misconvert '.asset.taml' files Fixes 'cannot compile shader' error when trying to use the viz modes Fixed a some instances of guiControlProfiles not being actually defined Fixed some instances of guiControlProfiles being duplicated --- .../materials/BasicRibbonMat.asset.taml | 7 + .../materials/BasicRibbonMat.tscript | 27 ++ .../DefaultDecalRoadMaterial.asset.taml | 11 +- .../DefaultRoadMaterialOther.asset.taml | 11 +- .../DefaultRoadMaterialTop.asset.taml | 11 +- .../materials/TexturedRibbonMat.asset.taml | 2 +- .../materials/TexturedRibbonMat.tscript | 29 ++ .../gameObjects/materials/materials.tscript | 78 ---- .../gameObjects/shapes/CameraMat.asset.taml | 17 +- .../core/gameObjects/shapes/Green.asset.taml | 7 - .../shapes/OctahedronMat.asset.taml | 16 +- .../core/gameObjects/shapes/green.tscript | 196 -------- .../core/gameObjects/shapes/materials.tscript | 95 ---- .../gameObjects/shapes/noshape.asset.taml | 1 + .../shapes/noshape_NoShape.asset.taml | 7 - .../shapes/noshapetext_lambert1.asset.taml | 7 - .../shapes/noshapetext_noshape_mat.asset.taml | 7 - .../game/core/gui/scripts/profiles.tscript | 8 + .../scripts/AL_ConvexLightState.asset.taml | 7 - .../AL_DefaultDeferredMaterial.asset.taml | 7 - .../AL_DefaultShadowMaterial.asset.taml | 7 - .../AL_ParticlePointLightShader.asset.taml | 7 - .../scripts/AL_SpotLightShader.asset.taml | 7 - .../scripts/BL_ProjectedShadowRPM.asset.taml | 7 - .../scripts/IrradianceShader.asset.taml | 7 - .../images/WarningMaterial.asset.taml | 14 + .../core/rendering/images/materials.tscript | 32 -- .../Blank_sky/BlankSkyMat.asset.taml | 2 +- ...{materials.tscript => BlankSkyMat.tscript} | 0 .../{ => NightSkybox}/NightSkyMat.asset.taml | 2 +- .../materials/NightSkybox/NightSkyMat.tscript | 15 + .../NightSkybox_1.asset.taml | 0 .../{ => NightSkybox}/NightSkybox_1.png | Bin .../NightSkybox_2.asset.taml | 0 .../{ => NightSkybox}/NightSkybox_2.png | Bin .../NightSkybox_3.asset.taml | 0 .../{ => NightSkybox}/NightSkybox_3.png | Bin .../NightSkybox_4.asset.taml | 0 .../{ => NightSkybox}/NightSkybox_4.png | Bin .../NightSkybox_5.asset.taml | 0 .../{ => NightSkybox}/NightSkybox_5.png | Bin .../NightSkybox_6.asset.taml | 0 .../{ => NightSkybox}/NightSkybox_6.png | Bin .../rendering/materials/NoMaterial.asset.taml | 12 +- .../rendering/materials/NoMaterial.tscript | 6 - .../rendering/materials/materials.tscript | 65 --- .../materials/moon_noglow.asset.taml | 15 +- .../materials/moon_noglowMat.asset.taml | 14 + .../materials/moon_wcoronaMat.asset.taml | 18 + .../rendering/materials/moon_wglow.asset.taml | 15 +- .../materials/moon_wglowMat.asset.taml | 14 + .../core/rendering/shapes/materials.tscript | 16 - .../rendering/shapes/noShapeMat.asset.taml | 18 + .../core/rendering/shapes/noshape.asset.taml | 1 + .../game/tools/base/images/Black.asset.taml | 11 +- .../game/tools/base/images/Gray.asset.taml | 11 +- .../game/tools/base/images/White.asset.taml | 11 +- .../game/tools/base/images/materials.tscript | 67 --- .../OccluderProxyMaterial.asset.taml | 7 - .../PortalProxyMaterial.asset.taml | 7 - .../TriggerProxyMaterial.asset.taml | 7 - .../convexEditor/ZoneProxyMaterial.asset.taml | 7 - .../tools/convexEditor/convexEditor.tscript | 7 - .../images/OccluderProxyMaterial.asset.taml | 14 + .../images/PortalProxyMaterial.asset.taml | 14 + .../images/TriggerProxyMaterial.asset.taml | 14 + .../images/ZoneProxyMaterial.asset.taml | 14 + .../game/tools/convexEditor/main.tscript | 1 - .../game/tools/convexEditor/materials.tscript | 39 -- .../game/tools/datablockEditor/.asset.taml | 6 - Templates/BaseGame/game/tools/gui/.asset.taml | 6 - .../game/tools/gui/profiles.ed.tscript | 24 +- Templates/BaseGame/game/tools/main.tscript | 1 - .../game/tools/materialEditor/gui/.asset.taml | 6 - .../meshRoadEditor/meshRoadEditor.tscript | 7 - .../game/tools/navEditor/navEditor.tscript | 7 - .../ReflectProbePreviewMat.asset.taml | 18 + .../game/tools/resources/materials.tscript | 8 - .../tools/riverEditor/riverEditor.tscript | 10 +- .../game/tools/roadEditor/roadEditor.tscript | 7 - .../game/tools/shapeEditor/gui/.asset.taml | 6 - .../game/tools/worldEditor/gui/.asset.taml | 6 - .../gui/AL_ShadowVizOverlayCtrl.asset.taml | 2 +- .../game/tools/worldEditor/main.tscript | 3 - .../worldEditor/scripts/EditorGui.ed.tscript | 2 +- .../scripts/editors/creator.ed.tscript | 422 ------------------ .../shaders/Viz_SurfacePropertiesP.hlsl | 1 - 87 files changed, 373 insertions(+), 1245 deletions(-) create mode 100644 Templates/BaseGame/game/core/gameObjects/materials/BasicRibbonMat.asset.taml create mode 100644 Templates/BaseGame/game/core/gameObjects/materials/BasicRibbonMat.tscript create mode 100644 Templates/BaseGame/game/core/gameObjects/materials/TexturedRibbonMat.tscript delete mode 100644 Templates/BaseGame/game/core/gameObjects/materials/materials.tscript delete mode 100644 Templates/BaseGame/game/core/gameObjects/shapes/Green.asset.taml delete mode 100644 Templates/BaseGame/game/core/gameObjects/shapes/green.tscript delete mode 100644 Templates/BaseGame/game/core/gameObjects/shapes/materials.tscript delete mode 100644 Templates/BaseGame/game/core/gameObjects/shapes/noshape_NoShape.asset.taml delete mode 100644 Templates/BaseGame/game/core/gameObjects/shapes/noshapetext_lambert1.asset.taml delete mode 100644 Templates/BaseGame/game/core/gameObjects/shapes/noshapetext_noshape_mat.asset.taml delete mode 100644 Templates/BaseGame/game/core/lighting/scripts/AL_ConvexLightState.asset.taml delete mode 100644 Templates/BaseGame/game/core/lighting/scripts/AL_DefaultDeferredMaterial.asset.taml delete mode 100644 Templates/BaseGame/game/core/lighting/scripts/AL_DefaultShadowMaterial.asset.taml delete mode 100644 Templates/BaseGame/game/core/lighting/scripts/AL_ParticlePointLightShader.asset.taml delete mode 100644 Templates/BaseGame/game/core/lighting/scripts/AL_SpotLightShader.asset.taml delete mode 100644 Templates/BaseGame/game/core/lighting/scripts/BL_ProjectedShadowRPM.asset.taml delete mode 100644 Templates/BaseGame/game/core/lighting/scripts/IrradianceShader.asset.taml create mode 100644 Templates/BaseGame/game/core/rendering/images/WarningMaterial.asset.taml delete mode 100644 Templates/BaseGame/game/core/rendering/images/materials.tscript rename Templates/BaseGame/game/core/rendering/materials/Blank_sky/{materials.tscript => BlankSkyMat.tscript} (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkyMat.asset.taml (76%) create mode 100644 Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkyMat.tscript rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_1.asset.taml (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_1.png (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_2.asset.taml (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_2.png (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_3.asset.taml (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_3.png (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_4.asset.taml (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_4.png (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_5.asset.taml (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_5.png (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_6.asset.taml (100%) rename Templates/BaseGame/game/core/rendering/materials/{ => NightSkybox}/NightSkybox_6.png (100%) delete mode 100644 Templates/BaseGame/game/core/rendering/materials/NoMaterial.tscript delete mode 100644 Templates/BaseGame/game/core/rendering/materials/materials.tscript create mode 100644 Templates/BaseGame/game/core/rendering/materials/moon_noglowMat.asset.taml create mode 100644 Templates/BaseGame/game/core/rendering/materials/moon_wcoronaMat.asset.taml create mode 100644 Templates/BaseGame/game/core/rendering/materials/moon_wglowMat.asset.taml delete mode 100644 Templates/BaseGame/game/core/rendering/shapes/materials.tscript create mode 100644 Templates/BaseGame/game/core/rendering/shapes/noShapeMat.asset.taml delete mode 100644 Templates/BaseGame/game/tools/base/images/materials.tscript delete mode 100644 Templates/BaseGame/game/tools/convexEditor/OccluderProxyMaterial.asset.taml delete mode 100644 Templates/BaseGame/game/tools/convexEditor/PortalProxyMaterial.asset.taml delete mode 100644 Templates/BaseGame/game/tools/convexEditor/TriggerProxyMaterial.asset.taml delete mode 100644 Templates/BaseGame/game/tools/convexEditor/ZoneProxyMaterial.asset.taml create mode 100644 Templates/BaseGame/game/tools/convexEditor/images/OccluderProxyMaterial.asset.taml create mode 100644 Templates/BaseGame/game/tools/convexEditor/images/PortalProxyMaterial.asset.taml create mode 100644 Templates/BaseGame/game/tools/convexEditor/images/TriggerProxyMaterial.asset.taml create mode 100644 Templates/BaseGame/game/tools/convexEditor/images/ZoneProxyMaterial.asset.taml delete mode 100644 Templates/BaseGame/game/tools/convexEditor/materials.tscript delete mode 100644 Templates/BaseGame/game/tools/datablockEditor/.asset.taml delete mode 100644 Templates/BaseGame/game/tools/gui/.asset.taml delete mode 100644 Templates/BaseGame/game/tools/materialEditor/gui/.asset.taml create mode 100644 Templates/BaseGame/game/tools/resources/ReflectProbePreviewMat.asset.taml delete mode 100644 Templates/BaseGame/game/tools/resources/materials.tscript delete mode 100644 Templates/BaseGame/game/tools/shapeEditor/gui/.asset.taml delete mode 100644 Templates/BaseGame/game/tools/worldEditor/gui/.asset.taml diff --git a/Templates/BaseGame/game/core/gameObjects/materials/BasicRibbonMat.asset.taml b/Templates/BaseGame/game/core/gameObjects/materials/BasicRibbonMat.asset.taml new file mode 100644 index 000000000..1a26742d6 --- /dev/null +++ b/Templates/BaseGame/game/core/gameObjects/materials/BasicRibbonMat.asset.taml @@ -0,0 +1,7 @@ + diff --git a/Templates/BaseGame/game/core/gameObjects/materials/BasicRibbonMat.tscript b/Templates/BaseGame/game/core/gameObjects/materials/BasicRibbonMat.tscript new file mode 100644 index 000000000..ec38f71f4 --- /dev/null +++ b/Templates/BaseGame/game/core/gameObjects/materials/BasicRibbonMat.tscript @@ -0,0 +1,27 @@ +singleton ShaderData( BasicRibbonShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/ribbons/basicRibbonShaderV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/ribbons/basicRibbonShaderP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/ribbons/gl/basicRibbonShaderV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/ribbons/gl/basicRibbonShaderP.glsl"; + + samplerNames[0] = "$ribTex"; + + pixVersion = 2.0; +}; + +singleton CustomMaterial( BasicRibbonMat ) +{ + shader = BasicRibbonShader; + version = 2.0; + + emissive[0] = true; + + doubleSided = true; + translucent = true; + BlendOp = AddAlpha; + translucentBlendOp = AddAlpha; + + preload = true; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/core/gameObjects/materials/DefaultDecalRoadMaterial.asset.taml b/Templates/BaseGame/game/core/gameObjects/materials/DefaultDecalRoadMaterial.asset.taml index 08f5506ba..94de6281a 100644 --- a/Templates/BaseGame/game/core/gameObjects/materials/DefaultDecalRoadMaterial.asset.taml +++ b/Templates/BaseGame/game/core/gameObjects/materials/DefaultDecalRoadMaterial.asset.taml @@ -2,6 +2,13 @@ canSave="true" canSaveDynamicFields="true" AssetName="DefaultDecalRoadMaterial" - scriptFile="@assetFile=materials.tscript" materialDefinitionName="DefaultDecalRoadMaterial" - VersionId="1" /> + VersionId="1"> + + + + + + diff --git a/Templates/BaseGame/game/core/gameObjects/materials/DefaultRoadMaterialOther.asset.taml b/Templates/BaseGame/game/core/gameObjects/materials/DefaultRoadMaterialOther.asset.taml index 77164a8b5..d46bd21e3 100644 --- a/Templates/BaseGame/game/core/gameObjects/materials/DefaultRoadMaterialOther.asset.taml +++ b/Templates/BaseGame/game/core/gameObjects/materials/DefaultRoadMaterialOther.asset.taml @@ -2,6 +2,13 @@ canSave="true" canSaveDynamicFields="true" AssetName="DefaultRoadMaterialOther" - scriptFile="@assetFile=materials.tscript" materialDefinitionName="DefaultRoadMaterialOther" - VersionId="1" /> + VersionId="1"> + + + + + + diff --git a/Templates/BaseGame/game/core/gameObjects/materials/DefaultRoadMaterialTop.asset.taml b/Templates/BaseGame/game/core/gameObjects/materials/DefaultRoadMaterialTop.asset.taml index 14a1a15cd..397359da2 100644 --- a/Templates/BaseGame/game/core/gameObjects/materials/DefaultRoadMaterialTop.asset.taml +++ b/Templates/BaseGame/game/core/gameObjects/materials/DefaultRoadMaterialTop.asset.taml @@ -2,6 +2,13 @@ canSave="true" canSaveDynamicFields="true" AssetName="DefaultRoadMaterialTop" - scriptFile="@assetFile=materials.tscript" materialDefinitionName="DefaultRoadMaterialTop" - VersionId="1" /> + VersionId="1"> + + + + + + diff --git a/Templates/BaseGame/game/core/gameObjects/materials/TexturedRibbonMat.asset.taml b/Templates/BaseGame/game/core/gameObjects/materials/TexturedRibbonMat.asset.taml index 930268299..952588c7b 100644 --- a/Templates/BaseGame/game/core/gameObjects/materials/TexturedRibbonMat.asset.taml +++ b/Templates/BaseGame/game/core/gameObjects/materials/TexturedRibbonMat.asset.taml @@ -2,6 +2,6 @@ canSave="true" canSaveDynamicFields="true" AssetName="TexturedRibbonMat" - scriptFile="@assetFile=materials.tscript" + scriptFile="@assetFile=TexturedRibbonMat.tscript" materialDefinitionName="TexturedRibbonMat" VersionId="1" /> diff --git a/Templates/BaseGame/game/core/gameObjects/materials/TexturedRibbonMat.tscript b/Templates/BaseGame/game/core/gameObjects/materials/TexturedRibbonMat.tscript new file mode 100644 index 000000000..a04ee9ac4 --- /dev/null +++ b/Templates/BaseGame/game/core/gameObjects/materials/TexturedRibbonMat.tscript @@ -0,0 +1,29 @@ +singleton ShaderData( TexturedRibbonShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/ribbons/texRibbonShaderV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/ribbons/texRibbonShaderP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/ribbons/gl/texRibbonShaderV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/ribbons/gl/texRibbonShaderP.glsl"; + + samplerNames[0] = "$ribTex"; + + pixVersion = 2.0; +}; + +singleton CustomMaterial( TexturedRibbonMat ) +{ + shader = TexturedRibbonShader; + version = 2.0; + + emissive[0] = true; + + doubleSided = true; + translucent = true; + BlendOp = AddAlpha; + translucentBlendOp = AddAlpha; + + sampler["ribTex"] = "core/gameObjects/images/ribTex.png"; + + preload = true; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/core/gameObjects/materials/materials.tscript b/Templates/BaseGame/game/core/gameObjects/materials/materials.tscript deleted file mode 100644 index 27ab97d94..000000000 --- a/Templates/BaseGame/game/core/gameObjects/materials/materials.tscript +++ /dev/null @@ -1,78 +0,0 @@ -singleton ShaderData( BasicRibbonShader ) -{ - DXVertexShaderFile = $Core::CommonShaderPath @ "/ribbons/basicRibbonShaderV.hlsl"; - DXPixelShaderFile = $Core::CommonShaderPath @ "/ribbons/basicRibbonShaderP.hlsl"; - - OGLVertexShaderFile = $Core::CommonShaderPath @ "/ribbons/gl/basicRibbonShaderV.glsl"; - OGLPixelShaderFile = $Core::CommonShaderPath @ "/ribbons/gl/basicRibbonShaderP.glsl"; - - samplerNames[0] = "$ribTex"; - - pixVersion = 2.0; -}; - -singleton CustomMaterial( BasicRibbonMat ) -{ - shader = BasicRibbonShader; - version = 2.0; - - emissive[0] = true; - - doubleSided = true; - translucent = true; - BlendOp = AddAlpha; - translucentBlendOp = AddAlpha; - - preload = true; -}; - -singleton ShaderData( TexturedRibbonShader ) -{ - DXVertexShaderFile = $Core::CommonShaderPath @ "/ribbons/texRibbonShaderV.hlsl"; - DXPixelShaderFile = $Core::CommonShaderPath @ "/ribbons/texRibbonShaderP.hlsl"; - - OGLVertexShaderFile = $Core::CommonShaderPath @ "/ribbons/gl/texRibbonShaderV.glsl"; - OGLPixelShaderFile = $Core::CommonShaderPath @ "/ribbons/gl/texRibbonShaderP.glsl"; - - samplerNames[0] = "$ribTex"; - - pixVersion = 2.0; -}; - -singleton CustomMaterial( TexturedRibbonMat ) -{ - shader = TexturedRibbonShader; - version = 2.0; - - emissive[0] = true; - - doubleSided = true; - translucent = true; - BlendOp = AddAlpha; - translucentBlendOp = AddAlpha; - - sampler["ribTex"] = "core/gameObjects/images/ribTex.png"; - - preload = true; -}; - -singleton Material(DefaultDecalRoadMaterial) -{ - diffuseMapAsset[0] = "Core_GameObjects:defaultRoadTextureTop_image"; - mapTo = "unmapped_mat"; - materialTag0 = "RoadAndPath"; -}; - -singleton Material(DefaultRoadMaterialTop) -{ - mapTo = "unmapped_mat"; - diffuseMapAsset[0] = "Core_GameObjects:defaultRoadTextureTop_image"; - materialTag0 = "RoadAndPath"; -}; - -singleton Material(DefaultRoadMaterialOther) -{ - mapTo = "unmapped_mat"; - diffuseMapAsset[0] = "Core_GameObjects:defaultRoadTextureOther_image"; - materialTag0 = "RoadAndPath"; -}; diff --git a/Templates/BaseGame/game/core/gameObjects/shapes/CameraMat.asset.taml b/Templates/BaseGame/game/core/gameObjects/shapes/CameraMat.asset.taml index 2b85211c6..60c126d02 100644 --- a/Templates/BaseGame/game/core/gameObjects/shapes/CameraMat.asset.taml +++ b/Templates/BaseGame/game/core/gameObjects/shapes/CameraMat.asset.taml @@ -2,6 +2,19 @@ canSave="true" canSaveDynamicFields="true" AssetName="CameraMat" - scriptFile="@assetFile=materials.tscript" materialDefinitionName="CameraMat" - VersionId="1" /> + VersionId="1"> + + + + + + diff --git a/Templates/BaseGame/game/core/gameObjects/shapes/Green.asset.taml b/Templates/BaseGame/game/core/gameObjects/shapes/Green.asset.taml deleted file mode 100644 index 4eaaebab9..000000000 --- a/Templates/BaseGame/game/core/gameObjects/shapes/Green.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/core/gameObjects/shapes/OctahedronMat.asset.taml b/Templates/BaseGame/game/core/gameObjects/shapes/OctahedronMat.asset.taml index 95227b6bb..9a877ebce 100644 --- a/Templates/BaseGame/game/core/gameObjects/shapes/OctahedronMat.asset.taml +++ b/Templates/BaseGame/game/core/gameObjects/shapes/OctahedronMat.asset.taml @@ -2,6 +2,18 @@ canSave="true" canSaveDynamicFields="true" AssetName="OctahedronMat" - scriptFile="@assetFile=materials.tscript" materialDefinitionName="OctahedronMat" - VersionId="1" /> + VersionId="1"> + + + + + + diff --git a/Templates/BaseGame/game/core/gameObjects/shapes/green.tscript b/Templates/BaseGame/game/core/gameObjects/shapes/green.tscript deleted file mode 100644 index 9ea7a7bd0..000000000 --- a/Templates/BaseGame/game/core/gameObjects/shapes/green.tscript +++ /dev/null @@ -1,196 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -new Material(OctahedronMat) { - mapTo = "green"; - diffuseColor[0] = "0 1 0 1"; - diffuseColor[1] = "1 1 1 1"; - diffuseColor[2] = "1 1 1 1"; - diffuseColor[3] = "1 1 1 1"; - DiffuseMap[0] = "core/gameObjects/images/camera"; - diffuseMapSRGB[0] = "1"; - diffuseMapSRGB[1] = "1"; - diffuseMapSRGB[2] = "1"; - diffuseMapSRGB[3] = "1"; - detailScale[0] = "2 2"; - detailScale[1] = "2 2"; - detailScale[2] = "2 2"; - detailScale[3] = "2 2"; - detailNormalMapStrength[0] = "1"; - detailNormalMapStrength[1] = "1"; - detailNormalMapStrength[2] = "1"; - detailNormalMapStrength[3] = "1"; - roughness[0] = "1"; - roughness[1] = "1"; - roughness[2] = "1"; - roughness[3] = "1"; - metalness[0] = "0"; - metalness[1] = "0"; - metalness[2] = "0"; - metalness[3] = "0"; - glowMul[0] = "0"; - glowMul[1] = "0"; - glowMul[2] = "0"; - glowMul[3] = "0"; - accuEnabled[0] = "0"; - accuEnabled[1] = "0"; - accuEnabled[2] = "0"; - accuEnabled[3] = "0"; - accuScale[0] = "1"; - accuScale[1] = "1"; - accuScale[2] = "1"; - accuScale[3] = "1"; - accuDirection[0] = "1"; - accuDirection[1] = "1"; - accuDirection[2] = "1"; - accuDirection[3] = "1"; - accuStrength[0] = "0.6"; - accuStrength[1] = "0.6"; - accuStrength[2] = "0.6"; - accuStrength[3] = "0.6"; - accuCoverage[0] = "0.9"; - accuCoverage[1] = "0.9"; - accuCoverage[2] = "0.9"; - accuCoverage[3] = "0.9"; - accuSpecular[0] = "16"; - accuSpecular[1] = "16"; - accuSpecular[2] = "16"; - accuSpecular[3] = "16"; - isSRGB[0] = "0"; - isSRGB[1] = "0"; - isSRGB[2] = "0"; - isSRGB[3] = "0"; - invertRoughness[0] = "0"; - invertRoughness[1] = "0"; - invertRoughness[2] = "0"; - invertRoughness[3] = "0"; - roughnessChan[0] = "0"; - roughnessChan[1] = "0"; - roughnessChan[2] = "0"; - roughnessChan[3] = "0"; - AOChan[0] = "1"; - AOChan[1] = "1"; - AOChan[2] = "1"; - AOChan[3] = "1"; - metalChan[0] = "2"; - metalChan[1] = "2"; - metalChan[2] = "2"; - metalChan[3] = "2"; - glow[0] = "0"; - glow[1] = "0"; - glow[2] = "0"; - glow[3] = "0"; - parallaxScale[0] = "0"; - parallaxScale[1] = "0"; - parallaxScale[2] = "0"; - parallaxScale[3] = "0"; - useAnisotropic[0] = "1"; - useAnisotropic[1] = "1"; - useAnisotropic[2] = "1"; - useAnisotropic[3] = "1"; - vertLit[0] = "0"; - vertLit[1] = "0"; - vertLit[2] = "0"; - vertLit[3] = "0"; - vertColor[0] = "0"; - vertColor[1] = "0"; - vertColor[2] = "0"; - vertColor[3] = "0"; - minnaertConstant[0] = "-1"; - minnaertConstant[1] = "-1"; - minnaertConstant[2] = "-1"; - minnaertConstant[3] = "-1"; - subSurface[0] = "0"; - subSurface[1] = "0"; - subSurface[2] = "0"; - subSurface[3] = "0"; - subSurfaceColor[0] = "1 0.2 0.2 1"; - subSurfaceColor[1] = "1 0.2 0.2 1"; - subSurfaceColor[2] = "1 0.2 0.2 1"; - subSurfaceColor[3] = "1 0.2 0.2 1"; - subSurfaceRolloff[0] = "0.2"; - subSurfaceRolloff[1] = "0.2"; - subSurfaceRolloff[2] = "0.2"; - subSurfaceRolloff[3] = "0.2"; - emissive[0] = "0"; - emissive[1] = "0"; - emissive[2] = "0"; - emissive[3] = "0"; - foreground[0] = "0"; - foreground[1] = "0"; - foreground[2] = "0"; - foreground[3] = "0"; - doubleSided = "0"; - animFlags[0] = "0x00000000"; - animFlags[1] = "0x00000000"; - animFlags[2] = "0x00000000"; - animFlags[3] = "0x00000000"; - scrollDir[0] = "0 0"; - scrollDir[1] = "0 0"; - scrollDir[2] = "0 0"; - scrollDir[3] = "0 0"; - scrollSpeed[0] = "0"; - scrollSpeed[1] = "0"; - scrollSpeed[2] = "0"; - scrollSpeed[3] = "0"; - rotSpeed[0] = "0"; - rotSpeed[1] = "0"; - rotSpeed[2] = "0"; - rotSpeed[3] = "0"; - rotPivotOffset[0] = "0 0"; - rotPivotOffset[1] = "0 0"; - rotPivotOffset[2] = "0 0"; - rotPivotOffset[3] = "0 0"; - waveType[0] = "Sin"; - waveType[1] = "Sin"; - waveType[2] = "Sin"; - waveType[3] = "Sin"; - waveFreq[0] = "0"; - waveFreq[1] = "0"; - waveFreq[2] = "0"; - waveFreq[3] = "0"; - waveAmp[0] = "0"; - waveAmp[1] = "0"; - waveAmp[2] = "0"; - waveAmp[3] = "0"; - sequenceFramePerSec[0] = "0"; - sequenceFramePerSec[1] = "0"; - sequenceFramePerSec[2] = "0"; - sequenceFramePerSec[3] = "0"; - sequenceSegmentSize[0] = "0"; - sequenceSegmentSize[1] = "0"; - sequenceSegmentSize[2] = "0"; - sequenceSegmentSize[3] = "0"; - cellIndex[0] = "0 0"; - cellIndex[1] = "0 0"; - cellIndex[2] = "0 0"; - cellIndex[3] = "0 0"; - cellLayout[0] = "0 0"; - cellLayout[1] = "0 0"; - cellLayout[2] = "0 0"; - cellLayout[3] = "0 0"; - cellSize[0] = "0"; - cellSize[1] = "0"; - cellSize[2] = "0"; - cellSize[3] = "0"; - bumpAtlas[0] = "0"; - bumpAtlas[1] = "0"; - bumpAtlas[2] = "0"; - bumpAtlas[3] = "0"; - castShadows = "0"; - planarReflection = "0"; - translucent = "1"; - translucentBlendOp = "PreMul"; - translucentZWrite = "0"; - alphaTest = "0"; - alphaRef = "1"; - dynamicCubemap = "0"; - showFootprints = "1"; - showDust = "0"; - effectColor[0] = "0 0 0 0"; - effectColor[1] = "0 0 0 0"; - footstepSoundId = "-1"; - impactSoundId = "-1"; - ImpactFXIndex = "-1"; - canSave = "1"; - canSaveDynamicFields = "1"; -}; -//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/core/gameObjects/shapes/materials.tscript b/Templates/BaseGame/game/core/gameObjects/shapes/materials.tscript deleted file mode 100644 index 1ff2dc498..000000000 --- a/Templates/BaseGame/game/core/gameObjects/shapes/materials.tscript +++ /dev/null @@ -1,95 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -singleton Material(OctahedronMat) -{ - mapTo = "green"; - - diffuseMapAsset[0] = "Core_GameObjects:camera_image"; - - translucent = "1"; - translucentBlendOp = "PreMul"; - emissive = "0"; - castShadows = "0"; - - diffuseColor[0] = "0 1 0 1"; -}; - -//--- camera.dts MATERIALS BEGIN --- -singleton Material(CameraMat) -{ - mapTo = "pasted__phongE1"; - - diffuseMapAsset[0] = "Core_GameObjects:camera_image"; - - diffuseColor[0] = "0 0.627451 1 1"; - specular[0] = "1 1 1 1"; - specularPower[0] = 211; - pixelSpecular[0] = 1; - emissive[0] = 1; - - doubleSided = 1; - translucent = true; - translucentBlendOp = "LerpAlpha"; - castShadows = false; - materialTag0 = "Miscellaneous"; -}; - -//--- camera.dts MATERIALS END --- - -//--- noshapetext.dae MATERIALS BEGIN --- -singleton Material(noshapetext_lambert1) -{ - mapTo = "lambert1"; - - diffuseMapAsset[0] = ""; - - diffuseColor[0] = "0.4 0.4 0.4 1"; - specular[0] = "1 1 1 1"; - specularPower[0] = 8; - pixelSpecular[0] = false; - emissive[0] = true; - - doubleSided = false; - translucent = false; - translucentBlendOp = "None"; -}; - -singleton Material(noshapetext_noshape_mat) -{ - mapTo = "noshape_mat"; - - diffuseMapAsset[0] = ""; - - diffuseColor[0] = "0.4 0.3504 0.363784 0.33058"; - specular[0] = "1 1 1 1"; - specularPower[0] = 8; - pixelSpecular[0] = false; - emissive[0] = true; - - doubleSided = false; - translucent = true; - translucentBlendOp = "None"; -}; - -//--- noshapetext.dae MATERIALS END --- - diff --git a/Templates/BaseGame/game/core/gameObjects/shapes/noshape.asset.taml b/Templates/BaseGame/game/core/gameObjects/shapes/noshape.asset.taml index aec6b87ba..82726bd6c 100644 --- a/Templates/BaseGame/game/core/gameObjects/shapes/noshape.asset.taml +++ b/Templates/BaseGame/game/core/gameObjects/shapes/noshape.asset.taml @@ -3,4 +3,5 @@ canSaveDynamicFields="true" AssetName="noshape" fileName="@assetFile=noshape.dts" + materialSlot0="@asset=Core_Rendering:noShapeMat" constuctorFileName="@assetFile=noshape.tscript" /> diff --git a/Templates/BaseGame/game/core/gameObjects/shapes/noshape_NoShape.asset.taml b/Templates/BaseGame/game/core/gameObjects/shapes/noshape_NoShape.asset.taml deleted file mode 100644 index 140cfb8dd..000000000 --- a/Templates/BaseGame/game/core/gameObjects/shapes/noshape_NoShape.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/core/gameObjects/shapes/noshapetext_lambert1.asset.taml b/Templates/BaseGame/game/core/gameObjects/shapes/noshapetext_lambert1.asset.taml deleted file mode 100644 index 03690b6fe..000000000 --- a/Templates/BaseGame/game/core/gameObjects/shapes/noshapetext_lambert1.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/core/gameObjects/shapes/noshapetext_noshape_mat.asset.taml b/Templates/BaseGame/game/core/gameObjects/shapes/noshapetext_noshape_mat.asset.taml deleted file mode 100644 index 1fec80c57..000000000 --- a/Templates/BaseGame/game/core/gameObjects/shapes/noshapetext_noshape_mat.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/core/gui/scripts/profiles.tscript b/Templates/BaseGame/game/core/gui/scripts/profiles.tscript index 57156bbbe..f09e1d542 100644 --- a/Templates/BaseGame/game/core/gui/scripts/profiles.tscript +++ b/Templates/BaseGame/game/core/gui/scripts/profiles.tscript @@ -245,3 +245,11 @@ new GuiControlProfile( GuiSliderProfile ) bitmapAsset = "Core_GUI:slider_image"; category = "Core"; }; + +// +if(!isObject(GuiScrollProfile)) +new GuiControlProfile(GuiScrollProfile) +{ + bitmapAsset = "Core_GUI:scrollBar_image"; + category = "Core"; +}; diff --git a/Templates/BaseGame/game/core/lighting/scripts/AL_ConvexLightState.asset.taml b/Templates/BaseGame/game/core/lighting/scripts/AL_ConvexLightState.asset.taml deleted file mode 100644 index 1c3b81a5a..000000000 --- a/Templates/BaseGame/game/core/lighting/scripts/AL_ConvexLightState.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/core/lighting/scripts/AL_DefaultDeferredMaterial.asset.taml b/Templates/BaseGame/game/core/lighting/scripts/AL_DefaultDeferredMaterial.asset.taml deleted file mode 100644 index b5567f4b1..000000000 --- a/Templates/BaseGame/game/core/lighting/scripts/AL_DefaultDeferredMaterial.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/core/lighting/scripts/AL_DefaultShadowMaterial.asset.taml b/Templates/BaseGame/game/core/lighting/scripts/AL_DefaultShadowMaterial.asset.taml deleted file mode 100644 index 5e1bd8133..000000000 --- a/Templates/BaseGame/game/core/lighting/scripts/AL_DefaultShadowMaterial.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/core/lighting/scripts/AL_ParticlePointLightShader.asset.taml b/Templates/BaseGame/game/core/lighting/scripts/AL_ParticlePointLightShader.asset.taml deleted file mode 100644 index 3cf0aef47..000000000 --- a/Templates/BaseGame/game/core/lighting/scripts/AL_ParticlePointLightShader.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/core/lighting/scripts/AL_SpotLightShader.asset.taml b/Templates/BaseGame/game/core/lighting/scripts/AL_SpotLightShader.asset.taml deleted file mode 100644 index e521008e8..000000000 --- a/Templates/BaseGame/game/core/lighting/scripts/AL_SpotLightShader.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/core/lighting/scripts/BL_ProjectedShadowRPM.asset.taml b/Templates/BaseGame/game/core/lighting/scripts/BL_ProjectedShadowRPM.asset.taml deleted file mode 100644 index 0911fb3fd..000000000 --- a/Templates/BaseGame/game/core/lighting/scripts/BL_ProjectedShadowRPM.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/core/lighting/scripts/IrradianceShader.asset.taml b/Templates/BaseGame/game/core/lighting/scripts/IrradianceShader.asset.taml deleted file mode 100644 index a525eecbb..000000000 --- a/Templates/BaseGame/game/core/lighting/scripts/IrradianceShader.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/core/rendering/images/WarningMaterial.asset.taml b/Templates/BaseGame/game/core/rendering/images/WarningMaterial.asset.taml new file mode 100644 index 000000000..0fb53d08c --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/images/WarningMaterial.asset.taml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/images/materials.tscript b/Templates/BaseGame/game/core/rendering/images/materials.tscript deleted file mode 100644 index 48d7bb61e..000000000 --- a/Templates/BaseGame/game/core/rendering/images/materials.tscript +++ /dev/null @@ -1,32 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -singleton Material( Empty ) -{ -}; - -singleton Material(WarningMaterial) { - detailMapAsset[0] = "Core_Rendering:missingTexture_image"; - diffuseColor[0] = "25 16 0"; - emissive[0] = false; - translucent = false; -}; diff --git a/Templates/BaseGame/game/core/rendering/materials/Blank_sky/BlankSkyMat.asset.taml b/Templates/BaseGame/game/core/rendering/materials/Blank_sky/BlankSkyMat.asset.taml index e6c3bb76b..6fa2808fb 100644 --- a/Templates/BaseGame/game/core/rendering/materials/Blank_sky/BlankSkyMat.asset.taml +++ b/Templates/BaseGame/game/core/rendering/materials/Blank_sky/BlankSkyMat.asset.taml @@ -2,6 +2,6 @@ canSave="true" canSaveDynamicFields="true" AssetName="BlankSkyMat" - scriptFile="@assetFile=materials.tscript" + scriptFile="@assetFile=BlankSkyMat.tscript" materialDefinitionName="BlankSkyMat" VersionId="1" /> diff --git a/Templates/BaseGame/game/core/rendering/materials/Blank_sky/materials.tscript b/Templates/BaseGame/game/core/rendering/materials/Blank_sky/BlankSkyMat.tscript similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/Blank_sky/materials.tscript rename to Templates/BaseGame/game/core/rendering/materials/Blank_sky/BlankSkyMat.tscript diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkyMat.asset.taml b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkyMat.asset.taml similarity index 76% rename from Templates/BaseGame/game/core/rendering/materials/NightSkyMat.asset.taml rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkyMat.asset.taml index 318f83ca2..02261e337 100644 --- a/Templates/BaseGame/game/core/rendering/materials/NightSkyMat.asset.taml +++ b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkyMat.asset.taml @@ -2,6 +2,6 @@ canSave="true" canSaveDynamicFields="true" AssetName="NightSkyMat" - scriptFile="@assetFile=materials.tscript" + scriptFile="@assetFile=NightSkyMat.tscript" materialDefinitionName="NightSkyMat" VersionId="1" /> diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkyMat.tscript b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkyMat.tscript new file mode 100644 index 000000000..47ccfa7a5 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkyMat.tscript @@ -0,0 +1,15 @@ +singleton CubemapData( NightCubemap ) +{ + cubeMapFaceAsset[0] = "Core_Rendering:NightSkybox_1"; + cubeMapFaceAsset[1] = "Core_Rendering:NightSkybox_2"; + cubeMapFaceAsset[2] = "Core_Rendering:NightSkybox_3"; + cubeMapFaceAsset[3] = "Core_Rendering:NightSkybox_4"; + cubeMapFaceAsset[4] = "Core_Rendering:NightSkybox_5"; + cubeMapFaceAsset[5] = "Core_Rendering:NightSkybox_6"; +}; + +singleton Material( NightSkyMat ) +{ + cubemap = NightCubemap; + materialTag0 = "Skies"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_1.asset.taml b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_1.asset.taml similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_1.asset.taml rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_1.asset.taml diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_1.png b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_1.png similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_1.png rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_1.png diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_2.asset.taml b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_2.asset.taml similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_2.asset.taml rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_2.asset.taml diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_2.png b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_2.png similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_2.png rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_2.png diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_3.asset.taml b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_3.asset.taml similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_3.asset.taml rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_3.asset.taml diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_3.png b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_3.png similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_3.png rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_3.png diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_4.asset.taml b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_4.asset.taml similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_4.asset.taml rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_4.asset.taml diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_4.png b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_4.png similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_4.png rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_4.png diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_5.asset.taml b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_5.asset.taml similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_5.asset.taml rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_5.asset.taml diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_5.png b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_5.png similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_5.png rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_5.png diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_6.asset.taml b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_6.asset.taml similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_6.asset.taml rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_6.asset.taml diff --git a/Templates/BaseGame/game/core/rendering/materials/NightSkybox_6.png b/Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_6.png similarity index 100% rename from Templates/BaseGame/game/core/rendering/materials/NightSkybox_6.png rename to Templates/BaseGame/game/core/rendering/materials/NightSkybox/NightSkybox_6.png diff --git a/Templates/BaseGame/game/core/rendering/materials/NoMaterial.asset.taml b/Templates/BaseGame/game/core/rendering/materials/NoMaterial.asset.taml index 918d7099b..5ee1c0deb 100644 --- a/Templates/BaseGame/game/core/rendering/materials/NoMaterial.asset.taml +++ b/Templates/BaseGame/game/core/rendering/materials/NoMaterial.asset.taml @@ -2,5 +2,13 @@ canSave="true" canSaveDynamicFields="true" AssetName="NoMaterial" - scriptFile="@assetFile=NoMaterial" - materialDefinitionName="NoMaterial" /> + materialDefinitionName="NoMaterial"> + + + + + + diff --git a/Templates/BaseGame/game/core/rendering/materials/NoMaterial.tscript b/Templates/BaseGame/game/core/rendering/materials/NoMaterial.tscript deleted file mode 100644 index fc6fb1d4f..000000000 --- a/Templates/BaseGame/game/core/rendering/materials/NoMaterial.tscript +++ /dev/null @@ -1,6 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -singleton Material(NoMaterial) { - mapTo="NoMaterial"; - DiffuseMapAsset[0] = "Core_Rendering:warnMat_image"; -}; -//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/core/rendering/materials/materials.tscript b/Templates/BaseGame/game/core/rendering/materials/materials.tscript deleted file mode 100644 index 3943b491b..000000000 --- a/Templates/BaseGame/game/core/rendering/materials/materials.tscript +++ /dev/null @@ -1,65 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -//--- OBJECT WRITE BEGIN --- - -singleton CubemapData( NightCubemap ) -{ - cubeMapFaceAsset[0] = "Core_Rendering:NightSkybox_1"; - cubeMapFaceAsset[1] = "Core_Rendering:NightSkybox_2"; - cubeMapFaceAsset[2] = "Core_Rendering:NightSkybox_3"; - cubeMapFaceAsset[3] = "Core_Rendering:NightSkybox_4"; - cubeMapFaceAsset[4] = "Core_Rendering:NightSkybox_5"; - cubeMapFaceAsset[5] = "Core_Rendering:NightSkybox_6"; -}; - -singleton Material( NightSkyMat ) -{ - cubemap = NightCubemap; - materialTag0 = "Skies"; -}; - -singleton Material(moon_noglow) { - mapTo="moon_noglow"; - DiffuseMapAsset = "Core_Rendering:moon_noglow_image"; - emissive = true; - translucent = true; - vertColor[ 0 ] = true; -}; - -singleton Material(moon_wglow) { - mapTo="moon_wglow"; - DiffuseMapAsset = "Core_Rendering:moon_wglow_image"; - emissive = true; - translucent = true; - vertColor[ 0 ] = true; -}; - -singleton Material(moon_wcorona) { - mapTo="moon_wcorona"; - DiffuseMapAsset = "Core_Rendering:moon_wcorona_image"; - emissive = true; - translucent = true; - vertColor[ 0 ] = true; -}; - -//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/core/rendering/materials/moon_noglow.asset.taml b/Templates/BaseGame/game/core/rendering/materials/moon_noglow.asset.taml index 372a4037b..76e9d5d00 100644 --- a/Templates/BaseGame/game/core/rendering/materials/moon_noglow.asset.taml +++ b/Templates/BaseGame/game/core/rendering/materials/moon_noglow.asset.taml @@ -2,6 +2,17 @@ canSave="true" canSaveDynamicFields="true" AssetName="moon_noglow" - scriptFile="@assetFile=moon_noglow.tscript" materialDefinitionName="moon_noglow" - imageMap0="@Asset=Core_Rendering:moon_noglow_image"/> + VersionId="1"> + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/materials/moon_noglowMat.asset.taml b/Templates/BaseGame/game/core/rendering/materials/moon_noglowMat.asset.taml new file mode 100644 index 000000000..afb79ab61 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/materials/moon_noglowMat.asset.taml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/materials/moon_wcoronaMat.asset.taml b/Templates/BaseGame/game/core/rendering/materials/moon_wcoronaMat.asset.taml new file mode 100644 index 000000000..2db4a12c1 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/materials/moon_wcoronaMat.asset.taml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/materials/moon_wglow.asset.taml b/Templates/BaseGame/game/core/rendering/materials/moon_wglow.asset.taml index 846b4c6d3..a37a06a6d 100644 --- a/Templates/BaseGame/game/core/rendering/materials/moon_wglow.asset.taml +++ b/Templates/BaseGame/game/core/rendering/materials/moon_wglow.asset.taml @@ -2,6 +2,17 @@ canSave="true" canSaveDynamicFields="true" AssetName="moon_wglow" - scriptFile="@assetFile=moon_wglow.tscript" materialDefinitionName="moon_wglow" - imageMap0="@Asset=Core_Rendering:moon_wglow_image"/> + VersionId="1"> + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/materials/moon_wglowMat.asset.taml b/Templates/BaseGame/game/core/rendering/materials/moon_wglowMat.asset.taml new file mode 100644 index 000000000..afb79ab61 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/materials/moon_wglowMat.asset.taml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shapes/materials.tscript b/Templates/BaseGame/game/core/rendering/shapes/materials.tscript deleted file mode 100644 index 0fd1ca716..000000000 --- a/Templates/BaseGame/game/core/rendering/shapes/materials.tscript +++ /dev/null @@ -1,16 +0,0 @@ -//--- noshape.dts MATERIALS BEGIN --- -singleton Material(noshape_NoShape) -{ - mapTo = "NoShape"; - - diffuseMapAsset[0] = ""; - diffuseColor[0] = "0.8 0.003067 0 .8"; - emissive[0] = 0; - doubleSided = false; - translucent = 1; - translucentBlendOp = "LerpAlpha"; - castShadows = false; - materialTag0 = "WorldEditor"; -}; - -//--- noshape.dts MATERIALS END --- diff --git a/Templates/BaseGame/game/core/rendering/shapes/noShapeMat.asset.taml b/Templates/BaseGame/game/core/rendering/shapes/noShapeMat.asset.taml new file mode 100644 index 000000000..0a2fb3cb1 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shapes/noShapeMat.asset.taml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/Templates/BaseGame/game/core/rendering/shapes/noshape.asset.taml b/Templates/BaseGame/game/core/rendering/shapes/noshape.asset.taml index cf670d251..000c68d9d 100644 --- a/Templates/BaseGame/game/core/rendering/shapes/noshape.asset.taml +++ b/Templates/BaseGame/game/core/rendering/shapes/noshape.asset.taml @@ -3,4 +3,5 @@ canSaveDynamicFields="true" AssetName="noshape" fileName="@assetFile=noshape.dts" + materialSlot0="@asset=Core_Rendering:NoShapeMat" VersionId="1" /> diff --git a/Templates/BaseGame/game/tools/base/images/Black.asset.taml b/Templates/BaseGame/game/tools/base/images/Black.asset.taml index b8cf9af8a..a419f0f87 100644 --- a/Templates/BaseGame/game/tools/base/images/Black.asset.taml +++ b/Templates/BaseGame/game/tools/base/images/Black.asset.taml @@ -2,6 +2,13 @@ canSave="true" canSaveDynamicFields="true" AssetName="Black" - scriptFile="@assetFile=materials.tscript" materialDefinitionName="Black" - VersionId="1" /> + VersionId="1"> + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/base/images/Gray.asset.taml b/Templates/BaseGame/game/tools/base/images/Gray.asset.taml index 358ce1109..83ae65616 100644 --- a/Templates/BaseGame/game/tools/base/images/Gray.asset.taml +++ b/Templates/BaseGame/game/tools/base/images/Gray.asset.taml @@ -2,6 +2,13 @@ canSave="true" canSaveDynamicFields="true" AssetName="Gray" - scriptFile="@assetFile=materials.tscript" materialDefinitionName="Gray" - VersionId="1" /> + VersionId="1"> + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/base/images/White.asset.taml b/Templates/BaseGame/game/tools/base/images/White.asset.taml index 062281c3e..1ef43d42c 100644 --- a/Templates/BaseGame/game/tools/base/images/White.asset.taml +++ b/Templates/BaseGame/game/tools/base/images/White.asset.taml @@ -2,6 +2,13 @@ canSave="true" canSaveDynamicFields="true" AssetName="White" - scriptFile="@assetFile=materials.tscript" materialDefinitionName="White" - VersionId="1" /> + VersionId="1"> + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/base/images/materials.tscript b/Templates/BaseGame/game/tools/base/images/materials.tscript deleted file mode 100644 index b1525a317..000000000 --- a/Templates/BaseGame/game/tools/base/images/materials.tscript +++ /dev/null @@ -1,67 +0,0 @@ -//----------------------------------------------------------------------------- -// Torque -// Copyright GarageGames, LLC 2011 -//----------------------------------------------------------------------------- - -singleton Material(White) -{ - diffuseMapAsset[0] = "ToolsModule:white_image"; -}; - -singleton Material(Gray) -{ - diffuseMapAsset[0] = "ToolsModule:gray_image"; -}; - -singleton Material(Black) -{ - diffuseMapAsset[0] = "ToolsModule:black_image"; -}; - -singleton Material(Grid_512_Black) -{ - diffuseMapAsset[0] = "ToolsModule:512_black_image"; -}; - -singleton Material(Grid_512_ForestGreen) -{ - diffuseMapAsset[0] = "ToolsModule:512_forestgreen_image"; -}; - -singleton Material(Grid_512_ForestGreen_Lines) -{ - diffuseMapAsset[0] = "ToolsModule:512_forestgreen_lines_image"; -}; - -singleton Material(Grid_512_Green) -{ - diffuseMapAsset[0] = "ToolsModule:512_green_image"; -}; - -singleton Material(Grid_512_Grey) -{ - diffuseMapAsset[0] = "ToolsModule:512_grey_image"; -}; - -singleton Material(Grid_512_Grey_Base) -{ - diffuseMapAsset[0] = "ToolsModule:512_grey_base_image"; -}; - -singleton Material(Grid_512_Orange) -{ - diffuseMapAsset[0] = "ToolsModule:512_orange_image"; - translucent = "0"; - translucentBlendOp = "PreMul"; - mapTo = "512_orange.png"; -}; - -singleton Material(Grid_512_Orange_Lines) -{ - diffuseMapAsset[0] = "ToolsModule:512_orange_lines_image"; -}; - -singleton Material(Grid_512_Red) -{ - diffuseMapAsset[0] = "ToolsModule:512_red_image"; -}; diff --git a/Templates/BaseGame/game/tools/convexEditor/OccluderProxyMaterial.asset.taml b/Templates/BaseGame/game/tools/convexEditor/OccluderProxyMaterial.asset.taml deleted file mode 100644 index 3e9048f43..000000000 --- a/Templates/BaseGame/game/tools/convexEditor/OccluderProxyMaterial.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/tools/convexEditor/PortalProxyMaterial.asset.taml b/Templates/BaseGame/game/tools/convexEditor/PortalProxyMaterial.asset.taml deleted file mode 100644 index ac08480eb..000000000 --- a/Templates/BaseGame/game/tools/convexEditor/PortalProxyMaterial.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/tools/convexEditor/TriggerProxyMaterial.asset.taml b/Templates/BaseGame/game/tools/convexEditor/TriggerProxyMaterial.asset.taml deleted file mode 100644 index ac5eea347..000000000 --- a/Templates/BaseGame/game/tools/convexEditor/TriggerProxyMaterial.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/tools/convexEditor/ZoneProxyMaterial.asset.taml b/Templates/BaseGame/game/tools/convexEditor/ZoneProxyMaterial.asset.taml deleted file mode 100644 index efde833a2..000000000 --- a/Templates/BaseGame/game/tools/convexEditor/ZoneProxyMaterial.asset.taml +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditor.tscript b/Templates/BaseGame/game/tools/convexEditor/convexEditor.tscript index 859667bc1..deb211fbf 100644 --- a/Templates/BaseGame/game/tools/convexEditor/convexEditor.tscript +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditor.tscript @@ -44,10 +44,3 @@ singleton GuiControlProfile (GuiDisabledTextEditProfile) canKeyFocus = false; category = "Editor"; }; - -singleton GuiControlProfile (GuiSimpleBorderProfile) -{ - opaque = false; - border = 1; - category = "Editor"; -}; diff --git a/Templates/BaseGame/game/tools/convexEditor/images/OccluderProxyMaterial.asset.taml b/Templates/BaseGame/game/tools/convexEditor/images/OccluderProxyMaterial.asset.taml new file mode 100644 index 000000000..afb79ab61 --- /dev/null +++ b/Templates/BaseGame/game/tools/convexEditor/images/OccluderProxyMaterial.asset.taml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/convexEditor/images/PortalProxyMaterial.asset.taml b/Templates/BaseGame/game/tools/convexEditor/images/PortalProxyMaterial.asset.taml new file mode 100644 index 000000000..dafb6a648 --- /dev/null +++ b/Templates/BaseGame/game/tools/convexEditor/images/PortalProxyMaterial.asset.taml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/convexEditor/images/TriggerProxyMaterial.asset.taml b/Templates/BaseGame/game/tools/convexEditor/images/TriggerProxyMaterial.asset.taml new file mode 100644 index 000000000..ba793c53f --- /dev/null +++ b/Templates/BaseGame/game/tools/convexEditor/images/TriggerProxyMaterial.asset.taml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/Templates/BaseGame/game/tools/convexEditor/images/ZoneProxyMaterial.asset.taml b/Templates/BaseGame/game/tools/convexEditor/images/ZoneProxyMaterial.asset.taml new file mode 100644 index 000000000..80f575f30 --- /dev/null +++ b/Templates/BaseGame/game/tools/convexEditor/images/ZoneProxyMaterial.asset.taml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/convexEditor/main.tscript b/Templates/BaseGame/game/tools/convexEditor/main.tscript index 3930f5b11..7d04d55c8 100644 --- a/Templates/BaseGame/game/tools/convexEditor/main.tscript +++ b/Templates/BaseGame/game/tools/convexEditor/main.tscript @@ -29,7 +29,6 @@ function initializeConvexEditor() exec( "./convexEditorToolbar.ed.gui" ); exec( "./convexEditorGui." @ $TorqueScriptFileExtension ); exec( "./convexEditorSidebarGui.gui" ); - exec( "./materials." @ $TorqueScriptFileExtension ); ConvexEditorGui.setVisible( false ); ConvexEditorOptionsWindow.setVisible( false ); diff --git a/Templates/BaseGame/game/tools/convexEditor/materials.tscript b/Templates/BaseGame/game/tools/convexEditor/materials.tscript deleted file mode 100644 index bd2e37c17..000000000 --- a/Templates/BaseGame/game/tools/convexEditor/materials.tscript +++ /dev/null @@ -1,39 +0,0 @@ -singleton Material( ZoneProxyMaterial ) -{ - mapTo = "ZoneProxyMaterial"; - diffuseMapAsset[0] = "ToolsModule:zoneProxyImage_image"; - materialTag0 = "TestMaterial"; - translucent = true; - translucentBlendOp = "LerpAlpha"; - castShadows = false; -}; - -singleton Material( TriggerProxyMaterial ) -{ - mapTo = "TriggerProxyMaterial"; - diffuseMapAsset[0] = "ToolsModule:triggerProxyImage_image"; - materialTag0 = "TestMaterial"; - translucent = true; - translucentBlendOp = "PreMul"; - castShadows = false; -}; - -singleton Material( PortalProxyMaterial ) -{ - mapTo = "PortalProxyMaterial"; - diffuseMapAsset[0] = "ToolsModule:portalProxyImage_image"; - materialTag0 = "TestMaterial"; - translucent = true; - translucentBlendOp = "PreMul"; - castShadows = false; -}; - -singleton Material( OccluderProxyMaterial ) -{ - mapTo = "OccluderProxyMaterial"; - diffuseMapAsset[0] = "ToolsModule:occluderProxyImage_image"; - materialTag0 = "TestMaterial"; - translucent = true; - translucentBlendOp = "PreMul"; - castShadows = false; -}; diff --git a/Templates/BaseGame/game/tools/datablockEditor/.asset.taml b/Templates/BaseGame/game/tools/datablockEditor/.asset.taml deleted file mode 100644 index fd3c1a4cb..000000000 --- a/Templates/BaseGame/game/tools/datablockEditor/.asset.taml +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/Templates/BaseGame/game/tools/gui/.asset.taml b/Templates/BaseGame/game/tools/gui/.asset.taml deleted file mode 100644 index 5995b2ea7..000000000 --- a/Templates/BaseGame/game/tools/gui/.asset.taml +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/Templates/BaseGame/game/tools/gui/profiles.ed.tscript b/Templates/BaseGame/game/tools/gui/profiles.ed.tscript index 492423e3d..2b2cec671 100644 --- a/Templates/BaseGame/game/tools/gui/profiles.ed.tscript +++ b/Templates/BaseGame/game/tools/gui/profiles.ed.tscript @@ -698,22 +698,6 @@ new GuiControlProfile( ToolsGuiFormProfile : ToolsGuiTextProfile ) // ---------------------------------------------------------------------------- -singleton GuiControlProfile( GuiEditorClassProfile ) -{ - opaque = true; - fillColor = "232 232 232"; - border = 1; - borderColor = "42 42 42 140"; - borderColorHL = "127 127 127"; - fontColor = "215 215 215"; - fontColorHL = "50 50 50"; - fixedExtent = true; - justify = "center"; - bitmapAsset = "ToolsModule:scrollBar_image"; - hasBitmapArray = true; - category = "Editor"; -}; - singleton GuiControlProfile( GuiBackFillProfile ) { opaque = true; @@ -1246,3 +1230,11 @@ singleton GuiControlProfile (IconDropdownProfile) fillColor = EditorSettings.value("Theme/headerColor"); }; + +// +singleton GuiControlProfile (GuiSimpleBorderProfile) +{ + opaque = false; + border = 1; + category = "Editor"; +}; diff --git a/Templates/BaseGame/game/tools/main.tscript b/Templates/BaseGame/game/tools/main.tscript index 218d7d88d..b44a27f99 100644 --- a/Templates/BaseGame/game/tools/main.tscript +++ b/Templates/BaseGame/game/tools/main.tscript @@ -82,7 +82,6 @@ function onStart() // Common GUI stuff. exec( "./gui/cursors.ed." @ $TorqueScriptFileExtension ); exec( "./gui/messageBoxes/messageBox.ed." @ $TorqueScriptFileExtension ); - exec( "./editorClasses/gui/panels/navPanelProfiles.ed." @ $TorqueScriptFileExtension ); // Make sure we get editor profiles before any GUI's // BUG: these dialogs are needed earlier in the init sequence, and should be moved to diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/.asset.taml b/Templates/BaseGame/game/tools/materialEditor/gui/.asset.taml deleted file mode 100644 index 5711ba647..000000000 --- a/Templates/BaseGame/game/tools/materialEditor/gui/.asset.taml +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditor.tscript b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditor.tscript index 112562d82..eee393d87 100644 --- a/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditor.tscript +++ b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditor.tscript @@ -43,11 +43,4 @@ singleton GuiControlProfile (GuiDisabledTextEditProfile) tab = false; canKeyFocus = false; category = "Editor"; -}; - -singleton GuiControlProfile (GuiSimpleBorderProfile) -{ - opaque = false; - border = 1; - category = "Editor"; }; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/navEditor/navEditor.tscript b/Templates/BaseGame/game/tools/navEditor/navEditor.tscript index 8fc2b15ba..bbe6fe8b0 100644 --- a/Templates/BaseGame/game/tools/navEditor/navEditor.tscript +++ b/Templates/BaseGame/game/tools/navEditor/navEditor.tscript @@ -351,10 +351,3 @@ singleton GuiControlProfile(NavEditorProfile) fillColor = "192 192 192 192"; category = "Editor"; }; - -singleton GuiControlProfile(GuiSimpleBorderProfile) -{ - opaque = false; - border = 1; - category = "Editor"; -}; diff --git a/Templates/BaseGame/game/tools/resources/ReflectProbePreviewMat.asset.taml b/Templates/BaseGame/game/tools/resources/ReflectProbePreviewMat.asset.taml new file mode 100644 index 000000000..e136ff6b4 --- /dev/null +++ b/Templates/BaseGame/game/tools/resources/ReflectProbePreviewMat.asset.taml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/resources/materials.tscript b/Templates/BaseGame/game/tools/resources/materials.tscript deleted file mode 100644 index 2ba9fec86..000000000 --- a/Templates/BaseGame/game/tools/resources/materials.tscript +++ /dev/null @@ -1,8 +0,0 @@ -singleton Material(ReflectProbePreviewMat) -{ - mapTo = "ReflectProbePreviewMat"; - diffuseColor[0] = "1 1 1 1"; - roughness[0] = "0"; - metalness[0] = "1"; - translucentBlendOp = "None"; -}; diff --git a/Templates/BaseGame/game/tools/riverEditor/riverEditor.tscript b/Templates/BaseGame/game/tools/riverEditor/riverEditor.tscript index 83da8b85c..944bafed2 100644 --- a/Templates/BaseGame/game/tools/riverEditor/riverEditor.tscript +++ b/Templates/BaseGame/game/tools/riverEditor/riverEditor.tscript @@ -26,12 +26,4 @@ singleton GuiControlProfile( RiverEditorProfile ) opaque = true; fillColor = "192 192 192 192"; category = "Editor"; -}; - -singleton GuiControlProfile (GuiSimpleBorderProfile) -{ - opaque = false; - border = 1; - category = "Editor"; -}; - \ No newline at end of file +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/roadEditor/roadEditor.tscript b/Templates/BaseGame/game/tools/roadEditor/roadEditor.tscript index 0822050b0..0bfe5ef43 100644 --- a/Templates/BaseGame/game/tools/roadEditor/roadEditor.tscript +++ b/Templates/BaseGame/game/tools/roadEditor/roadEditor.tscript @@ -28,13 +28,6 @@ singleton GuiControlProfile( RoadEditorProfile ) category = "Editor"; }; -singleton GuiControlProfile (GuiSimpleBorderProfile) -{ - opaque = false; - border = 1; - category = "Editor"; -}; - singleton GuiCursor(RoadEditorMoveCursor) { hotSpot = "4 4"; diff --git a/Templates/BaseGame/game/tools/shapeEditor/gui/.asset.taml b/Templates/BaseGame/game/tools/shapeEditor/gui/.asset.taml deleted file mode 100644 index 8bf949aa2..000000000 --- a/Templates/BaseGame/game/tools/shapeEditor/gui/.asset.taml +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/.asset.taml b/Templates/BaseGame/game/tools/worldEditor/gui/.asset.taml deleted file mode 100644 index 36b7991fa..000000000 --- a/Templates/BaseGame/game/tools/worldEditor/gui/.asset.taml +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/AL_ShadowVizOverlayCtrl.asset.taml b/Templates/BaseGame/game/tools/worldEditor/gui/AL_ShadowVizOverlayCtrl.asset.taml index ab14cd613..4c92556c3 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/AL_ShadowVizOverlayCtrl.asset.taml +++ b/Templates/BaseGame/game/tools/worldEditor/gui/AL_ShadowVizOverlayCtrl.asset.taml @@ -2,6 +2,6 @@ canSave="true" canSaveDynamicFields="true" AssetName="AL_ShadowVizOverlayCtrl" - scriptFile="@assetFile=shadowViz.gui" + scriptFile="@assetFile=shadowViz.tscript" GUIFile="@assetFile=shadowViz.gui" VersionId="1" /> diff --git a/Templates/BaseGame/game/tools/worldEditor/main.tscript b/Templates/BaseGame/game/tools/worldEditor/main.tscript index 0d975d380..ef0dfdc05 100644 --- a/Templates/BaseGame/game/tools/worldEditor/main.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/main.tscript @@ -68,10 +68,7 @@ function initializeWorldEditor() exec("./scripts/cameraCommands.ed." @ $TorqueScriptFileExtension); exec("./scripts/probeBake.ed." @ $TorqueScriptFileExtension); exec("./scripts/visibility/visibilityLayer.ed." @ $TorqueScriptFileExtension); - exec("./scripts/visibility/lightViz." @ $TorqueScriptFileExtension); - exec("./scripts/visibility/shadowViz." @ $TorqueScriptFileExtension); exec("./scripts/visibility/probeViz." @ $TorqueScriptFileExtension); - exec("./scripts/visibility/miscViz." @ $TorqueScriptFileExtension); exec("tools/gui/postFxEditor." @ $TorqueScriptFileExtension ); exec("tools/gui/renderTargetVisualizer.ed." @ $TorqueScriptFileExtension); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript index 1ba706257..ef1b9292b 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript @@ -216,7 +216,7 @@ function EditorGui::init(%this) ETerrainEditor.init(); //Creator.init(); - ObjectCreator.init(); + //ObjectCreator.init(); ObjectBuilderGui.init(); %this.setMenuDefaultState(); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript index 9524a7849..fc047c19b 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript @@ -20,104 +20,8 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- - -function ObjectCreator::init( %this ) -{ - // Just so we can recall this method for testing changes - // without restarting. - if ( isObject( %this.array ) ) - %this.array.delete(); - - %this.array = new ArrayObject(); - %this.array.caseSensitive = true; - %this.setListView( true ); - - %this.beginGroup( "Environment" ); - - // Removed Prefab as there doesn't really seem to be a point in creating a blank one - //%this.registerMissionObject( "Prefab", "Prefab" ); - %this.registerMissionObject( "SkyBox", "Sky Box" ); - %this.registerMissionObject( "SkySphere", "Sky Sphere" ); - %this.registerMissionObject( "CloudLayer", "Cloud Layer" ); - %this.registerMissionObject( "BasicClouds", "Basic Clouds" ); - %this.registerMissionObject( "ScatterSky", "Scatter Sky" ); - %this.registerMissionObject( "Sun", "Basic Sun" ); - %this.registerMissionObject( "Lightning" ); - %this.registerMissionObject( "WaterBlock", "Water Block" ); - %this.registerMissionObject( "SFXEmitter", "Sound Emitter" ); - %this.registerMissionObject( "Precipitation" ); - %this.registerMissionObject( "ParticleEmitterNode", "Particle Emitter" ); - %this.registerMissionObject( "VolumetricFog", "Volumetric Fog" ); - %this.registerMissionObject( "RibbonNode", "Ribbon" ); - - // Legacy features. Users should use Ground Cover and the Forest Editor. - //%this.registerMissionObject( "fxShapeReplicator", "Shape Replicator" ); - //%this.registerMissionObject( "fxFoliageReplicator", "Foliage Replicator" ); - - %this.registerMissionObject( "PointLight", "Point Light" ); - %this.registerMissionObject( "SpotLight", "Spot Light" ); - - %this.registerMissionObject( "BoxEnvironmentProbe", "Box Environment Probe" ); - %this.registerMissionObject( "SphereEnvironmentProbe", "Sphere Environment Probe" ); - %this.registerMissionObject( "Skylight", "Skylight" ); - - %this.registerMissionObject( "GroundCover", "Ground Cover" ); - %this.registerMissionObject( "TerrainBlock", "Terrain Block" ); - %this.registerMissionObject( "GroundPlane", "Ground Plane" ); - %this.registerMissionObject( "WaterPlane", "Water Plane" ); - %this.registerMissionObject( "PxCloth", "Cloth" ); - %this.registerMissionObject( "ForestWindEmitter", "Wind Emitter" ); - - %this.registerMissionObject( "DustEmitter", "Dust Emitter" ); - %this.registerMissionObject( "DustSimulation", "Dust Simulation" ); - %this.registerMissionObject( "DustEffecter", "Dust Effecter" ); - - %this.endGroup(); - - %this.beginGroup( "Level" ); - - %this.registerMissionObject( "MissionArea", "Mission Area" ); - %this.registerMissionObject( "Path" ); - %this.registerMissionObject( "Marker", "Path Node" ); - %this.registerMissionObject( "Trigger" ); - %this.registerMissionObject( "PhysicalZone", "Physical Zone" ); - %this.registerMissionObject( "Camera" ); - %this.registerMissionObject( "LevelInfo", "Level Info" ); - %this.registerMissionObject( "TimeOfDay", "Time of Day" ); - %this.registerMissionObject( "Zone", "Zone" ); - %this.registerMissionObject( "Portal", "Zone Portal" ); - %this.registerMissionObject( "SpawnSphere", "Player Spawn Sphere", "PlayerDropPoint" ); - %this.registerMissionObject( "SpawnSphere", "Observer Spawn Sphere", "ObserverDropPoint" ); - %this.registerMissionObject( "SpawnSphere", "General Spawn Sphere", "GeneralDropPoint" ); - %this.registerMissionObject( "SFXSpace", "Sound Space" ); - %this.registerMissionObject( "OcclusionVolume", "Occlusion Volume" ); - %this.registerMissionObject( "AccumulationVolume", "Accumulation Volume" ); - %this.registerMissionObject("NavMesh", "Navigation mesh"); - %this.registerMissionObject("NavPath", "Path"); - %this.registerMissionObject( "Entity", "Entity" ); - %this.registerMissionObject( "NotesObject", "Note" ); - - %this.endGroup(); - - %this.beginGroup( "System" ); - - %this.registerMissionObject( "SimGroup" ); - - %this.endGroup(); - - %this.beginGroup( "ExampleObjects" ); - - %this.registerMissionObject( "RenderObjectExample" ); - %this.registerMissionObject( "RenderMeshExample" ); - %this.registerMissionObject( "RenderShapeExample" ); - - %this.endGroup(); -} - function ObjectCreator::onWake( %this ) { - CreatorTabBook.selectPage( 0 ); - CreatorTabBook.onTabSelected( "Scripted" ); } function ObjectCreator::beginGroup( %this, %group ) @@ -159,8 +63,6 @@ function ObjectCreator::registerMissionObject( %this, %class, %name, %buildfunc, %args.val[0] = %class; %args.val[1] = %name; %args.val[2] = %buildfunc; - - %this.array.push_back( %group, %args ); } function ObjectCreator::getNewObjectGroup( %this ) @@ -271,330 +173,6 @@ function ObjectCreator::onObjectCreated( %this, %objId ) EWorldEditor.dropSelection( true ); } -function CreatorTabBook::onTabSelected( %this, %text, %idx ) -{ - if ( %this.isAwake() ) - { - ObjectCreator.tab = %text; - ObjectCreator.navigate( "" ); - } -} - -function ObjectCreator::navigate( %this, %address ) -{ - CreatorIconArray.frozen = true; - CreatorIconArray.clear(); - CreatorPopupMenu.clear(); - - if ( %this.tab $= "Scripted" ) - { - %category = getWord( %address, 1 ); - %dataGroup = "DataBlockGroup"; - - for ( %i = 0; %i < %dataGroup.getCount(); %i++ ) - { - %obj = %dataGroup.getObject(%i); - // echo ("Obj: " @ %obj.getName() @ " - " @ %obj.category ); - - if ( %obj.category $= "" && %obj.category == 0 ) - continue; - - // Add category to popup menu if not there already - if ( CreatorPopupMenu.findText( %obj.category ) == -1 ) - CreatorPopupMenu.add( %obj.category ); - - if ( %address $= "" ) - { - %ctrl = %this.findIconCtrl( %obj.category ); - if ( %ctrl == -1 ) - { - %this.addFolderIcon( %obj.category ); - } - } - else if ( %address $= %obj.category ) - { - %ctrl = %this.findIconCtrl( %obj.getName() ); - if ( %ctrl == -1 ) - %this.addShapeIcon( %obj ); - } - } - } - - if ( %this.tab $= "Meshes" ) - { - %fullPath = findFirstFileMultiExpr( getFormatExtensions() ); - - while ( %fullPath !$= "" ) - { - if (strstr(%fullPath, "cached.dts") != -1) - { - %fullPath = findNextFileMultiExpr( getFormatExtensions() ); - continue; - } - - %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); - %splitPath = strreplace( %fullPath, " ", "_" ); - %splitPath = strreplace( %splitPath, "/", " " ); - if( getWord(%splitPath, 0) $= "tools" ) - { - %fullPath = findNextFileMultiExpr( getFormatExtensions() ); - continue; - } - - %dirCount = getWordCount( %splitPath ) - 1; - - %pathFolders = getWords( %splitPath, 0, %dirCount - 1 ); - - // Add this file's path (parent folders) to the - // popup menu if it isn't there yet. - %temp = strreplace( %pathFolders, " ", "/" ); - %temp = strreplace( %temp, "_", " " ); - %r = CreatorPopupMenu.findText( %temp ); - if ( %r == -1 ) - { - CreatorPopupMenu.add( %temp ); - } - - // Is this file in the current folder? - if ( stricmp( %pathFolders, %address ) == 0 ) - { - %this.addStaticIcon( %fullPath ); - } - // Then is this file in a subfolder we need to add - // a folder icon for? - else - { - %wordIdx = 0; - %add = false; - - if ( %address $= "" ) - { - %add = true; - %wordIdx = 0; - } - else - { - for ( ; %wordIdx < %dirCount; %wordIdx++ ) - { - %temp = getWords( %splitPath, 0, %wordIdx ); - if ( stricmp( %temp, %address ) == 0 ) - { - %add = true; - %wordIdx++; - break; - } - } - } - - if ( %add == true ) - { - %folder = getWord( %splitPath, %wordIdx ); - - %ctrl = %this.findIconCtrl( %folder ); - if ( %ctrl == -1 ) - %this.addFolderIcon( %folder ); - } - } - - %fullPath = findNextFileMultiExpr( getFormatExtensions() ); - } - } - - if ( %this.tab $= "Level" ) - { - // Add groups to popup menu - %array = %this.array; - %array.sortk(); - - %count = %array.count(); - - if ( %count > 0 ) - { - %lastGroup = ""; - - for ( %i = 0; %i < %count; %i++ ) - { - %group = %array.getKey( %i ); - - if ( %group !$= %lastGroup ) - { - CreatorPopupMenu.add( %group ); - - if ( %address $= "" ) - %this.addFolderIcon( %group ); - } - - if ( %address $= %group ) - { - %args = %array.getValue( %i ); - %class = %args.val[0]; - %name = %args.val[1]; - %func = %args.val[2]; - - %this.addMissionObjectIcon( %class, %name, %func ); - } - - %lastGroup = %group; - } - } - } - - if ( %this.tab $= "Prefabs" ) - { - %expr = "*.prefab"; - %fullPath = findFirstFile( %expr ); - - while ( %fullPath !$= "" ) - { - %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); - %splitPath = strreplace( %fullPath, " ", "_" ); - %splitPath = strreplace( %splitPath, "/", " " ); - if( getWord(%splitPath, 0) $= "tools" ) - { - %fullPath = findNextFile( %expr ); - continue; - } - - %dirCount = getWordCount( %splitPath ) - 1; - - %pathFolders = getWords( %splitPath, 0, %dirCount - 1 ); - - // Add this file's path (parent folders) to the - // popup menu if it isn't there yet. - %temp = strreplace( %pathFolders, " ", "/" ); - %temp = strreplace( %temp, "_", " " ); - %r = CreatorPopupMenu.findText( %temp ); - if ( %r == -1 ) - { - CreatorPopupMenu.add( %temp ); - } - - // Is this file in the current folder? - if ( (%dirCount == 0 && %address $= "") || stricmp( %pathFolders, %address ) == 0 ) - { - %this.addPrefabIcon( %fullPath ); - } - // Then is this file in a subfolder we need to add - // a folder icon for? - else - { - %wordIdx = 0; - %add = false; - - if ( %address $= "" ) - { - %add = true; - %wordIdx = 0; - } - else - { - for ( ; %wordIdx < %dirCount; %wordIdx++ ) - { - %temp = getWords( %splitPath, 0, %wordIdx ); - if ( stricmp( %temp, %address ) == 0 ) - { - %add = true; - %wordIdx++; - break; - } - } - } - - if ( %add == true ) - { - %folder = getWord( %splitPath, %wordIdx ); - - %ctrl = %this.findIconCtrl( %folder ); - if ( %ctrl == -1 ) - %this.addFolderIcon( %folder ); - } - } - - %fullPath = findNextFile( %expr ); - } - } - - CreatorIconArray.sort( "alphaIconCompare" ); - - for ( %i = 0; %i < CreatorIconArray.getCount(); %i++ ) - { - CreatorIconArray.getObject(%i).autoSize = false; - } - - CreatorIconArray.frozen = false; - CreatorIconArray.refresh(); - - // Recalculate the array for the parent guiScrollCtrl - CreatorIconArray.getParent().computeSizes(); - - %this.address = %address; - - CreatorPopupMenu.sort(); - - %str = strreplace( %address, " ", "/" ); - %r = CreatorPopupMenu.findText( %str ); - if ( %r != -1 ) - CreatorPopupMenu.setSelected( %r, false ); - else - CreatorPopupMenu.setText( %str ); - CreatorPopupMenu.tooltip = %str; -} - -function ObjectCreator::navigateDown( %this, %folder ) -{ - if ( %this.address $= "" ) - %address = %folder; - else - %address = %this.address SPC %folder; - - // Because this is called from an IconButton::onClick command - // we have to wait a tick before actually calling navigate, else - // we would delete the button out from under itself. - %this.schedule( 1, "navigate", %address ); -} - -function ObjectCreator::navigateUp( %this ) -{ - %count = getWordCount( %this.address ); - - if ( %count == 0 ) - return; - - if ( %count == 1 ) - %address = ""; - else - %address = getWords( %this.address, 0, %count - 2 ); - - %this.navigate( %address ); -} - -function ObjectCreator::setListView( %this, %noupdate ) -{ - //CreatorIconArray.clear(); - //CreatorIconArray.setVisible( false ); - - CreatorIconArray.setVisible( true ); - %this.contentCtrl = CreatorIconArray; - %this.isList = true; - - if ( %noupdate == true ) - %this.navigate( %this.address ); -} - -//function ObjectCreator::setIconView( %this ) -//{ - //echo( "setIconView" ); - // - //CreatorIconStack.clear(); - //CreatorIconStack.setVisible( false ); - // - //CreatorIconArray.setVisible( true ); - //%this.contentCtrl = CreatorIconArray; - //%this.isList = false; - // - //%this.navigate( %this.address ); -//} - function ObjectCreator::findIconCtrl( %this, %name ) { for ( %i = 0; %i < %this.contentCtrl.getCount(); %i++ ) diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/visibility/shaders/Viz_SurfacePropertiesP.hlsl b/Templates/BaseGame/game/tools/worldEditor/scripts/visibility/shaders/Viz_SurfacePropertiesP.hlsl index b489519a7..519de284e 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/visibility/shaders/Viz_SurfacePropertiesP.hlsl +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/visibility/shaders/Viz_SurfacePropertiesP.hlsl @@ -33,7 +33,6 @@ TORQUE_UNIFORM_SAMPLER2D(backbufferTex, 4); TORQUE_UNIFORM_SAMPLER2D(glowBuffer, 5); uniform float mode; -uniform float3 eyePosWorld; uniform float4x4 cameraToWorld; float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 From 87ea262ef020bbfd5d367504a80dcba64e5ea29b Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 17 Mar 2022 03:09:11 -0500 Subject: [PATCH 050/145] Fixes handling of the setEditor commands so that the dropdown Editors menubar entry properly works --- .../worldEditor/scripts/menuHandlers.ed.tscript | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript index a2ea3b015..c0beb15f7 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript @@ -910,10 +910,18 @@ function EditorMenuEditPaste() function EditorToolsMenu::onSelectItem(%this, %id) { - %toolName = getField( %this.item[%id], 2 ); + %tool = getField( %this.item[%id], 2 ); - %paletteName = ""; - EditorGui.setEditor(%toolName, %paletteName ); + if(isObject(%tool)) + { + %paletteName = ""; + EditorGui.setEditor(%tool, %paletteName ); + } + else + { + //it's an embedded command, so we'll just execute it + eval(%tool); + } %this.checkRadioItem(0, %this.getItemCount(), %id); return true; From d883575d0fe0f7230c2584c9d9e60a3c5ef48176 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Thu, 17 Mar 2022 17:38:41 -0500 Subject: [PATCH 051/145] fix compilation flaws --- Engine/source/assets/assetDefinition.h | 2 +- Engine/source/console/consoleFunctions.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine/source/assets/assetDefinition.h b/Engine/source/assets/assetDefinition.h index fb5720394..1a2a2ba1b 100644 --- a/Engine/source/assets/assetDefinition.h +++ b/Engine/source/assets/assetDefinition.h @@ -36,7 +36,7 @@ #endif #ifndef _SIMSET_H_ -#include "console/simset.h" +#include "console/simSet.h" #endif #ifndef _CONSOLEOBJECT_H_ diff --git a/Engine/source/console/consoleFunctions.cpp b/Engine/source/console/consoleFunctions.cpp index 099f7090d..4b43518e5 100644 --- a/Engine/source/console/consoleFunctions.cpp +++ b/Engine/source/console/consoleFunctions.cpp @@ -2861,7 +2861,7 @@ DefineEngineFunction(getTimestamp, const char*, (), , } #ifdef TORQUE_TOOLS -DefineEngineFunction(systemCommand, S32, (const char* commandLineAction, const char* callBackFunction), , "", "") +DefineEngineFunction(systemCommand, S32, (const char* commandLineAction, const char* callBackFunction), (""), "") { if (commandLineAction != "") { From 8cea8ec01149e475b8dcf9d90bf60594d3691412 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sat, 19 Mar 2022 13:03:33 -0500 Subject: [PATCH 052/145] extended callonModules hooks for baseline playgui used for the noticeSystem chathud injection sample --- .../game/data/gameUI/GUIs/playGui.tscript | 71 +------------------ 1 file changed, 3 insertions(+), 68 deletions(-) diff --git a/Templates/BaseGame/game/data/gameUI/GUIs/playGui.tscript b/Templates/BaseGame/game/data/gameUI/GUIs/playGui.tscript index 2f175c025..82ce8a552 100644 --- a/Templates/BaseGame/game/data/gameUI/GUIs/playGui.tscript +++ b/Templates/BaseGame/game/data/gameUI/GUIs/playGui.tscript @@ -32,31 +32,17 @@ function PlayGui::onWake(%this) $enableDirectInput = "1"; activateDirectInput(); - - // Message hud dialog - if ( isObject( MainChatHud ) ) - { - Canvas.pushDialog( MainChatHud ); - chatHud.attach(HudMessageVector); - } // just update the action map here if(isObject(moveMap)) moveMap.push(); - - // hack city - these controls are floating around and need to be clamped - if ( isFunction( "refreshCenterTextCtrl" ) ) - schedule(0, 0, "refreshCenterTextCtrl"); - if ( isFunction( "refreshBottomTextCtrl" ) ) - schedule(0, 0, "refreshBottomTextCtrl"); callOnModules("Playgui_onWake"); } function PlayGui::onSleep(%this) { - if ( isObject( MainChatHud ) ) - Canvas.popDialog( MainChatHud ); + callOnModules("Playgui_onSleep"); // pop the keymaps if(isObject(moveMap)) @@ -65,60 +51,9 @@ function PlayGui::onSleep(%this) function PlayGui::clearHud( %this ) { + callOnModules("Playgui_clearHud"); Canvas.popDialog( MainChatHud ); while ( %this.getCount() > 0 ) %this.getObject( 0 ).delete(); -} - -//----------------------------------------------------------------------------- - -function refreshBottomTextCtrl() -{ - BottomPrintText.position = "0 0"; -} - -function refreshCenterTextCtrl() -{ - CenterPrintText.position = "0 0"; -} - -/*function PlayGui::onRightMouseDown(%this) -{ - %this.nocursor = true; - Canvas.checkCursor(); -} - -function PlayGui::onRightMouseUp(%this) -{ - %this.nocursor = false; - Canvas.checkCursor(); -}*/ - -/*function PlayGui::onInputEvent(%this, %device, %action, %state) -{ - if(%device $= "mouse0" && %action $= "button1") - { - if(%state == 1) - { - %this.nocursor = true; - Canvas.checkCursor(); - } - else - { - %this.nocursor = false; - Canvas.checkCursor(); - } - } - else if(%device $= "keyboard") - { - if(%action $= "w") - moveforward(%state); - else if(%action $= "a") - moveleft(%state); - else if(%action $= "s") - movebackward(%state); - else if(%action $= "d") - moveright(%state); - } -}*/ \ No newline at end of file +} \ No newline at end of file From b3342ff7e6709eaee86b3bf311d635270a8104ff Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 20 Mar 2022 03:17:31 -0500 Subject: [PATCH 053/145] Adds handling for import of files marked as ShapeAnimationAsset Adds filetype handling of dsqs for importing Improves logic checks to prevent incorrectly redundantly processing incoming assets for collisions, which could mark all assets as colliding instead of all but the first. Adds better handling for assets marked as for dependency usage when importing Improves rules for writing originalFilePath only if it's actually from an external directory, and the file actually exists to prevent polluting in redundant or garbage data Fixes issue where MaterialEditor was not tracking the currently material assetId if the material was changed via the dropdown selector Adds a sanity check to shapeAnimationAsset load so if the resource does not load properly it doesn't hard crash but instead logs the error and returns safely. --- .../source/T3D/assets/ShapeAnimationAsset.cpp | 2 +- Engine/source/T3D/assets/assetImporter.cpp | 117 ++++++++++++++++-- Engine/source/T3D/assets/assetImporter.h | 18 ++- .../tools/assetBrowser/assetImportConfigs.xml | 2 +- .../assetBrowser/scripts/assetImport.tscript | 3 +- .../scripts/assetTypes/image.tscript | 7 +- .../scripts/assetTypes/material.tscript | 8 +- .../scripts/assetTypes/shape.tscript | 7 +- .../scripts/materialEditor.ed.tscript | 10 ++ .../scripts/projectImporter.tscript | 3 + 10 files changed, 160 insertions(+), 17 deletions(-) diff --git a/Engine/source/T3D/assets/ShapeAnimationAsset.cpp b/Engine/source/T3D/assets/ShapeAnimationAsset.cpp index 50d668a1f..f7e1b6aa5 100644 --- a/Engine/source/T3D/assets/ShapeAnimationAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAnimationAsset.cpp @@ -151,7 +151,7 @@ void ShapeAnimationAsset::initializeAsset(void) mSourceShape = ResourceManager::get().load(mFilePath); - if (!mSourceShape->addSequence("ambient", "", mAnimationName, mStartFrame, mEndFrame, mPadRotation, mPadTransforms)) + if (!mSourceShape || !mSourceShape->addSequence("ambient", "", mAnimationName, mStartFrame, mEndFrame, mPadRotation, mPadTransforms)) { Con::errorf("ShapeAnimationAsset::initializeAsset - Unable to do initial setup of the animation clip named %s for asset %s", mAnimationName, getAssetName()); return; diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index f965bd42c..932874fbd 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -79,6 +79,8 @@ AssetImportConfig::AssetImportConfig() : SeparateAnimationPrefix(""), animTiming("FrameCount"), animFPS(false), + AlwaysAddShapeAnimationSuffix(true), + AddedShapeAnimationSuffix("_anim"), GenerateCollisions(false), GenCollisionType(""), CollisionMeshPrefix(""), @@ -190,6 +192,8 @@ void AssetImportConfig::initPersistFields() addField("SeparateAnimationPrefix", TypeRealString, Offset(SeparateAnimationPrefix, AssetImportConfig), "If separating animations out from a source file, what prefix should be added to the names for grouping association"); addField("animTiming", TypeRealString, Offset(animTiming, AssetImportConfig), "Defines the animation timing for the given animation sequence. Options are FrameTime, Seconds, Milliseconds"); addField("animFPS", TypeBool, Offset(animFPS, AssetImportConfig), "The FPS of the animation sequence"); + addField("AlwaysAddShapeAnimationSuffix", TypeBool, Offset(AlwaysAddShapeAnimationSuffix, AssetImportConfig), "When importing a shape animation, this indicates if it should automatically add a standard suffix onto the name"); + addField("AddedShapeAnimationSuffix", TypeString, Offset(AddedShapeAnimationSuffix, AssetImportConfig), " If AlwaysAddShapeAnimationSuffix is on, this is the suffix to be added"); endGroup("Animation"); addGroup("Collision"); @@ -287,6 +291,8 @@ void AssetImportConfig::loadImportConfig(Settings* configSettings, String config SeparateAnimationPrefix = configSettings->value(String(configName + "/Animations/SeparateAnimationPrefix").c_str()); animTiming = configSettings->value(String(configName + "/Animations/animTiming").c_str()); animFPS = dAtof(configSettings->value(String(configName + "/Animations/animFPS").c_str())); + AlwaysAddShapeAnimationSuffix = dAtob(configSettings->value(String(configName + "/Animations/AlwaysAddShapeAnimationSuffix").c_str())); + AddedShapeAnimationSuffix = configSettings->value(String(configName + "/Animations/AddedShapeAnimationSuffix").c_str()); //Collisions GenerateCollisions = dAtob(configSettings->value(String(configName + "/Collision/GenerateCollisions").c_str())); @@ -379,6 +385,8 @@ void AssetImportConfig::CopyTo(AssetImportConfig* target) const target->SeparateAnimationPrefix = SeparateAnimationPrefix; target->animTiming = animTiming; target->animFPS = animFPS; + target->AlwaysAddShapeAnimationSuffix = AlwaysAddShapeAnimationSuffix; + target->AddedShapeAnimationSuffix = AddedShapeAnimationSuffix; //Collisions target->GenerateCollisions = GenerateCollisions; @@ -1531,13 +1539,15 @@ void AssetImporter::processImportAssets(AssetImportObject* assetItem) { processMaterialAsset(item); } - /*else if (item->assetType == String("ShapeAnimationAsset")) - ShapeAnimationAsset::prepareAssetForImport(this, item);*/ + else if (item->assetType == String("ShapeAnimationAsset")) + { + processShapeAnimationAsset(item); + } else { String processCommand = "process"; processCommand += item->assetType; - if(isMethod(processCommand.c_str())) + if (isMethod(processCommand.c_str())) Con::executef(this, processCommand.c_str(), item); } @@ -2048,6 +2058,73 @@ void AssetImporter::processShapeAsset(AssetImportObject* assetItem) assetItem->importStatus = AssetImportObject::Processed; } +void AssetImporter::processShapeAnimationAsset(AssetImportObject* assetItem) +{ + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Shape Animation for Import: %s", assetItem->assetName.c_str()); + activityLog.push_back(importLogBuffer); + + String filePath = assetItem->filePath.getFullPath(); + String fileName = assetItem->filePath.getFileName(); + String fileExt = assetItem->filePath.getExtension(); + + if (assetItem->shapeInfo == nullptr) + { + GuiTreeViewCtrl* shapeInfo = new GuiTreeViewCtrl(); + shapeInfo->registerObject(); + + if (fileExt.compare("dae") == 0) + { + enumColladaForImport(filePath, shapeInfo, false); + } + else if (fileExt.compare("dts") == 0 || fileExt.compare("dsq") == 0) + { + enumDTSForImport(filePath, shapeInfo); + } + else + { + // Check if a cached DTS is available => no need to import the source file + // if we can load the DTS instead + + AssimpShapeLoader loader; + loader.fillGuiTreeView(filePath.c_str(), shapeInfo); + } + + assetItem->shapeInfo = shapeInfo; + } + + if (activeImportConfig->AlwaysAddShapeAnimationSuffix) + { + assetItem->assetName += activeImportConfig->AddedShapeAnimationSuffix; + assetItem->cleanAssetName = assetItem->assetName; + } + + S32 animCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_animCount"), nullptr)); + + dSprintf(importLogBuffer, sizeof(importLogBuffer), " Shape Animation Info: Anim Count: %i", animCount); + activityLog.push_back(importLogBuffer); + + AssetImportConfig* cachedConfig = new AssetImportConfig();; + cachedConfig->registerObject(); + activeImportConfig->CopyTo(cachedConfig); + + if (!activeImportConfig->UseManualShapeConfigRules) + { + //Try and load a sis file if it exists for this format + activeImportConfig->loadSISFile(assetItem->filePath); + } + + if (activeImportConfig->ImportAnimations && animCount > 0) + { + + } + + //restore the cached version just in case we loaded a sis file + cachedConfig->CopyTo(activeImportConfig); + cachedConfig->deleteObject(); + + assetItem->importStatus = AssetImportObject::Processed; +} + void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 materialItemId) { String matName = assetItem->shapeInfo->getItemText(materialItemId); @@ -2188,9 +2265,20 @@ bool AssetImporter::validateAssets() void AssetImporter::validateAsset(AssetImportObject* assetItem) { - if (assetItem->importStatus == AssetImportObject::Skipped || assetItem->importStatus == AssetImportObject::NotProcessed) + if (assetItem->importStatus == AssetImportObject::Skipped || assetItem->importStatus == AssetImportObject::NotProcessed + || assetItem->importStatus == AssetImportObject::UseForDependencies) return; + //If this item's already been marked as being in error, don't bother with it. It knows what it did. + //This avoids running collision checks on an item already known to have a collision, which could erroneously + //mark the original, not-colliding item as colliding with this item, invaliding both + if (assetItem->status == String("Error") || assetItem->statusType.isNotEmpty()) + { + importIssues = true; + return; + } + + //Runm this item against our other importing assets and check for any collisions if (checkAssetForCollision(assetItem)) { importIssues = true; @@ -2294,7 +2382,7 @@ bool AssetImporter::checkAssetForCollision(AssetImportObject* assetItemToCheck, { AssetImportObject* importingAsset = itemList[i]; - if (importingAsset->importStatus == AssetImportObject::Skipped) + if (importingAsset->importStatus == AssetImportObject::Skipped || importingAsset->importStatus == AssetImportObject::UseForDependencies) continue; if ((assetItemToCheck->assetName.compare(importingAsset->assetName) == 0) && (assetItemToCheck->getId() != importingAsset->getId())) @@ -2584,6 +2672,10 @@ void AssetImporter::importAssets(AssetImportObject* assetItem) { assetPath = importMaterialAsset(item); } + else if (item->assetType == String("ShapeAnimationAsset")) + { + assetPath = importShapeAnimationAsset(item); + } else { finalImportedAssetPath = String::EmptyString; @@ -2625,7 +2717,7 @@ void AssetImporter::importAssets(AssetImportObject* assetItem) else { //Any special-case post-reg stuff here - if (item->assetType == String("ShapeAsset")) + if (item->assetType == String("ShapeAsset") || item->assetType == String("ShapeAnimationAsset")) { //forcefully update it's shape constructor TSShapeConstructor* tss = TSShapeConstructor::findShapeConstructorByAssetId(assetId); @@ -2692,7 +2784,7 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem) //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } @@ -2750,7 +2842,12 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); newAsset->setAssetName(assetName); + + if (!isReimport && Platform::isFile(qualifiedFromFile)) + { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); + } + newAsset->setDataField(StringTable->insert("materialDefinitionName"), nullptr, assetName); //iterate through and write out the material maps dependencies @@ -2930,7 +3027,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } @@ -3205,7 +3302,7 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem) //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } @@ -3261,7 +3358,7 @@ Torque::Path AssetImporter::importShapeAnimationAsset(AssetImportObject* assetIt //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } diff --git a/Engine/source/T3D/assets/assetImporter.h b/Engine/source/T3D/assets/assetImporter.h index 6605ebe8f..4e2fc53aa 100644 --- a/Engine/source/T3D/assets/assetImporter.h +++ b/Engine/source/T3D/assets/assetImporter.h @@ -261,6 +261,16 @@ public: /// F32 animFPS; + /// + /// When importing a shape animation, this indicates if it should automatically add a standard suffix onto the name + /// + bool AlwaysAddShapeAnimationSuffix; + + /// + /// If AlwaysAddShapeAnimationSuffix is on, this is the suffix to be added + /// + String AddedShapeAnimationSuffix; + // //Collision /// @@ -800,11 +810,17 @@ public: void processMaterialAsset(AssetImportObject* assetItem); /// - /// Process a specific AssetImportObject that is an ShapeAsset type to prepare it for importing + /// Process a specific AssetImportObject that is an ShapeAnimationAsset type to prepare it for importing /// @param assetItem, The AssetImportObject to process /// void processShapeAsset(AssetImportObject* assetItem); + /// + /// Process a specific AssetImportObject that is an ShapeAsset type to prepare it for importing + /// @param assetItem, The AssetImportObject to process + /// + void processShapeAnimationAsset(AssetImportObject* assetItem); + /// /// Process a specific ShapeAsset AssetImportObject with a material id in order to parse and handle the materials listed in the shape file /// @param assetItem, The AssetImportObject to process diff --git a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml index 5c91b3d2a..285c9d235 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml +++ b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml @@ -195,7 +195,7 @@ 0 FolderPrefix + name="DuplicateAutoResolution">AutoPrune 1 Date: Sun, 20 Mar 2022 16:17:06 -0500 Subject: [PATCH 054/145] Adjusts handling so if a file being processed for importing is not actually imported as a new, successful asset it does not return an id, allowing tooling to only worry about actual new assets. Adds utility functions to TerrainBlock to be able to replace names of materials in the terrain file, mostly used for importing legacy files Adjusts terrainblock save asset logic to be able to save on a non-networked terrainblock such as when loaded temporarily on the server, for tooling purposes. Changes handling of not-found terrain materials when loading a terrain block so it will create a dummy terrain material with the same name as the not-found, but set the texture as the Warning image, instead of thrashing the original material names data Adds logic for testing newly imported terrain files' materials and if needbe, replacing them with the new terrain material asset ids. Adds logic in the project importer for if a would-be level asset's name already exists, we attempt to slap a "Level" suffix onto it to sidestep collisions. Changed LegacyImport config to try always adding shape suffix to help minimize probable naming collisions. Fixed handling of mission file's MissionGroup defines by specially checking for MissionGroup objects and processing the line into a Scene() declaration instead. --- Engine/source/T3D/assets/assetImporter.cpp | 5 +- Engine/source/terrain/terrData.cpp | 48 +++++++++++++++- Engine/source/terrain/terrData.h | 13 +++++ Engine/source/terrain/terrMaterial.cpp | 27 +++++---- .../tools/assetBrowser/assetImportConfigs.xml | 2 +- .../pre40/T3Dpre4ProjectImporter.tscript | 49 +++++++++++++--- .../scripts/projectImporter.tscript | 56 ++++++++++++++++++- 7 files changed, 176 insertions(+), 24 deletions(-) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index f965bd42c..a3d1a4e21 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -2534,7 +2534,10 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath, String typ dumpActivityLog(); - if (hasIssues) + if (hasIssues || + assetItem->importStatus == AssetImportObject::Skipped || + assetItem->importStatus == AssetImportObject::UseForDependencies || + assetItem->importStatus == AssetImportObject::Error) { return StringTable->EmptyString(); } diff --git a/Engine/source/terrain/terrData.cpp b/Engine/source/terrain/terrData.cpp index 532e0cc19..29523e609 100644 --- a/Engine/source/terrain/terrData.cpp +++ b/Engine/source/terrain/terrData.cpp @@ -480,16 +480,21 @@ bool TerrainBlock::saveAsset() AssetDatabase.findAssetType(pAssetQuery, "TerrainMaterialAsset"); - TerrainBlock* clientTerr = static_cast(getClientObject()); + TerrainBlock* terr = static_cast(getClientObject()); + if (!terr) + { + Con::warnf("No active client terrain while trying to save asset. Could be a server action, but should check to be sure!"); + terr = this; + } for (U32 i = 0; i < pAssetQuery->mAssetList.size(); i++) { //Acquire it so we can check it for matches AssetPtr terrMatAsset = pAssetQuery->mAssetList[i]; - for (U32 m = 0; m < clientTerr->mFile->mMaterials.size(); m++) + for (U32 m = 0; m < terr->mFile->mMaterials.size(); m++) { - StringTableEntry intMatName = clientTerr->mFile->mMaterials[m]->getInternalName(); + StringTableEntry intMatName = terr->mFile->mMaterials[m]->getInternalName(); StringTableEntry assetMatDefName = terrMatAsset->getMaterialDefinitionName(); if (assetMatDefName == intMatName) @@ -1456,6 +1461,25 @@ void TerrainBlock::getUtilizedAssets(Vector* usedAssetsList) // Console Methods //----------------------------------------------------------------------------- +bool TerrainBlock::renameTerrainMaterial(StringTableEntry oldMatName, StringTableEntry newMatName) +{ + TerrainMaterial* newMat = TerrainMaterial::findOrCreate(newMatName); + if (!newMat) + return false; + + U32 terrainMaterialCount = mFile->mMaterials.size(); + for (U32 i = 0; i < terrainMaterialCount; i++) + { + if (mFile->mMaterials[i]->getInternalName() == oldMatName) + { + TerrainMaterial* oldMat = mFile->mMaterials[i]; + mFile->mMaterials[i] = newMat; + } + } + + return true; +} + DefineEngineMethod( TerrainBlock, save, bool, ( const char* fileName),, "@brief Saves the terrain block's terrain file to the specified file name.\n\n" @@ -1623,3 +1647,21 @@ DefineEngineMethod(TerrainBlock, setTerrain, bool, (const char* terrain), , "Ter { return object->_setTerrain(StringTable->insert(terrain)); } + +DefineEngineMethod(TerrainBlock, getTerrainMaterialCount, S32, (), , "Gets the number of terrain materials for this block") +{ + return object->getTerrainMaterialCount(); +} + +DefineEngineMethod(TerrainBlock, getTerrainMaterialName, const char*, (S32 index), , "Gets the number of terrain materials for this block") +{ + if (index < 0 || index >= object->getTerrainMaterialCount()) + return StringTable->EmptyString(); + + return object->getTerrainMaterialName(index); +} + +DefineEngineMethod(TerrainBlock, renameTerrainMaterial, bool, (const char* oldMaterialName, const char* newMaterialName), , "Updates the terrain material from the original to the new name in the file. Mostly used for import/conversions.") +{ + return object->renameTerrainMaterial(StringTable->insert(oldMaterialName), StringTable->insert(newMaterialName)); +} diff --git a/Engine/source/terrain/terrData.h b/Engine/source/terrain/terrData.h index cc1479004..07a023371 100644 --- a/Engine/source/terrain/terrData.h +++ b/Engine/source/terrain/terrData.h @@ -522,6 +522,19 @@ public: return true; } + bool renameTerrainMaterial(StringTableEntry oldMatName, StringTableEntry newMatName); + S32 getTerrainMaterialCount() { + if (mFile) + return mFile->mMaterials.size(); + return 0; + } + + StringTableEntry getTerrainMaterialName(S32 index) { + if (mFile) + return mFile->mMaterials[index]->getInternalName(); + + return StringTable->EmptyString(); + } protected: bool mUpdateBasetex; bool mIgnoreZodiacs; diff --git a/Engine/source/terrain/terrMaterial.cpp b/Engine/source/terrain/terrMaterial.cpp index fa3b21f0a..289c9a16f 100644 --- a/Engine/source/terrain/terrMaterial.cpp +++ b/Engine/source/terrain/terrMaterial.cpp @@ -30,6 +30,8 @@ #include "console/persistenceManager.h" #endif +#include "T3D/assets/TerrainMaterialAsset.h" + #include @@ -166,6 +168,18 @@ TerrainMaterial* TerrainMaterial::findOrCreate( const char *nameOrPath ) if ( mat ) return mat; + StringTableEntry assetId = TerrainMaterialAsset::getAssetIdByMaterialName(nameOrPath); + if (assetId != StringTable->EmptyString()) + { + TerrainMaterialAsset* terrMatAsset = AssetDatabase.acquireAsset(assetId); + if (terrMatAsset) + { + mat = terrMatAsset->getMaterialDefinition(); + if (mat) + return mat; + } + } + // We didn't find it... so see if its a path to a // file. If it is lets assume its the texture. if ( GBitmap::sFindFiles( nameOrPath, NULL ) ) @@ -178,15 +192,9 @@ TerrainMaterial* TerrainMaterial::findOrCreate( const char *nameOrPath ) return mat; } - // Ok... return a debug material then. - mat = dynamic_cast( set->findObjectByInternalName( StringTable->insert( "warning_material" ) ) ); - if ( !mat ) - { - // This shouldn't happen.... the warning_texture should - // have already been defined in script, but we put this - // fallback here just in case it gets "lost". + // Ok... return a placeholder material then. mat = new TerrainMaterial(); - mat->setInternalName( "warning_material" ); + mat->setInternalName(nameOrPath); mat->_setDiffuseMap(GFXTextureManager::getWarningTexturePath()); mat->mDiffuseSize = 500; mat->_setDetailMap(StringTable->EmptyString()); @@ -195,8 +203,7 @@ TerrainMaterial* TerrainMaterial::findOrCreate( const char *nameOrPath ) mat->mMacroSize = 200; mat->registerObject(); - Sim::getRootGroup()->addObject( mat ); - } + Sim::getRootGroup()->addObject(mat); return mat; } diff --git a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml index 5c91b3d2a..b74012fb2 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml +++ b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml @@ -110,7 +110,7 @@ 0 0 + name="AlwaysAddShapeSuffix">1 0 Date: Sun, 20 Mar 2022 16:42:21 -0500 Subject: [PATCH 055/145] Made renaming of terrain materials on importing terrainblocks to use the full assetId, as it should --- .../game/tools/projectImporter/scripts/projectImporter.tscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index 76051b570..f8a50e797 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -1661,7 +1661,7 @@ function beginTerrainImport() if(%terrMatAssetId !$= "") { //Ok, success, lets run the rename - if(%terrBlock.renameTerrainMaterial(%terrMatName, %terrMatName @ "_terrainMat")) + if(%terrBlock.renameTerrainMaterial(%terrMatName, %terrMatAssetId)) %matNamesChanged = true; } } From 26142746393e9478b2c498d25c059da496e6ce64 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Wed, 23 Mar 2022 01:43:08 -0500 Subject: [PATCH 056/145] update sdl to https://github.com/libsdl-org/SDL 22March 2022 --- Engine/lib/sdl/{.hgignore => .gitignore} | 71 +- Engine/lib/sdl/.hgtags | 40 - Engine/lib/sdl/Android.mk | 24 +- Engine/lib/sdl/BUGS.txt | 8 +- Engine/lib/sdl/CMakeLists.txt | 1701 +- Engine/lib/sdl/INSTALL.txt | 19 +- Engine/lib/sdl/{COPYING.txt => LICENSE.txt} | 4 +- Engine/lib/sdl/Makefile.in | 12 +- Engine/lib/sdl/Makefile.minimal | 25 +- Engine/lib/sdl/Makefile.os2 | 223 +- Engine/lib/sdl/Makefile.pandora | 12 +- Engine/lib/sdl/Makefile.psp | 96 - Engine/lib/sdl/Makefile.wiz | 80 - Engine/lib/sdl/{README.txt => README.md} | 10 +- Engine/lib/sdl/SDL2.spec.in | 2 +- Engine/lib/sdl/SDL2Config.cmake | 120 +- Engine/lib/sdl/TODO.txt | 2 +- .../lib/sdl/VisualC-WinRT/SDL2-WinRT.nuspec | 23 - .../lib/sdl/VisualC-WinRT/SDL2-WinRT.targets | 38 - .../SDL2main-WinRT-NonXAML.nuspec | 22 - .../SDL2main-WinRT-NonXAML.targets | 10 - .../tests/loopwave/Assets/Logo.png | Bin 801 -> 0 bytes .../tests/loopwave/Assets/SmallLogo.png | Bin 329 -> 0 bytes .../tests/loopwave/Assets/SplashScreen.png | Bin 2146 -> 0 bytes .../tests/loopwave/Assets/StoreLogo.png | Bin 429 -> 0 bytes .../tests/loopwave/Package.appxmanifest | 42 - .../loopwave/loopwave_VS2012_TemporaryKey.pfx | Bin 2504 -> 0 bytes .../tests/testthread/Assets/Logo.png | Bin 801 -> 0 bytes .../tests/testthread/Assets/SmallLogo.png | Bin 329 -> 0 bytes .../tests/testthread/Assets/SplashScreen.png | Bin 2146 -> 0 bytes .../tests/testthread/Assets/StoreLogo.png | Bin 429 -> 0 bytes .../tests/testthread/Package.appxmanifest | 42 - .../testthread_VS2012_TemporaryKey.pfx | Bin 2504 -> 0 bytes Engine/lib/sdl/VisualC.html | 146 - Engine/lib/sdl/WhatsNew.txt | 112 + Engine/lib/sdl/Xcode-iOS/Demos/Info.plist | 4 + .../sdl/Xcode-iOS/Demos/src/accelerometer.c | 2 +- .../lib/sdl/Xcode-iOS/Demos/src/fireworks.c | 12 +- Engine/lib/sdl/Xcode-iOS/Demos/src/mixer.c | 2 +- Engine/lib/sdl/Xcode-iOS/Demos/src/touch.c | 38 +- .../SDL iOS Application/Default-568h@2x.png | Bin 83791 -> 0 bytes .../Template/SDL iOS Application/Default.png | Bin 18383 -> 0 bytes .../Template/SDL iOS Application/Icon.png | Bin 2409 -> 0 bytes .../Template/SDL iOS Application/Info.plist | 28 - .../TemplateIcon.icns | Bin 34248 -> 0 bytes .../TemplateInfo.plist | 10 - .../project.pbxproj | 500 - .../Template/SDL iOS Application/main.c | 100 - Engine/lib/sdl/Xcode/SDL/Info-Framework.plist | 4 +- .../Xcode/SDL/SDL.xcodeproj/project.pbxproj | 1332 +- Engine/lib/sdl/Xcode/SDL/hidapi/Info.plist | 22 - .../SDL/pkg-support/resources/License.txt | 2 +- Engine/lib/sdl/acinclude/alsa.m4 | 11 +- Engine/lib/sdl/acinclude/esd.m4 | 68 +- Engine/lib/sdl/acinclude/libtool.m4 | 2628 +- Engine/lib/sdl/acinclude/ltoptions.m4 | 127 +- Engine/lib/sdl/acinclude/ltsugar.m4 | 7 +- Engine/lib/sdl/acinclude/ltversion.m4 | 12 +- Engine/lib/sdl/acinclude/lt~obsolete.m4 | 7 +- Engine/lib/sdl/acinclude/pkg.m4 | 275 + Engine/lib/sdl/acinclude/pkg_config.m4 | 133 - .../lib/sdl/android-project/app/build.gradle | 8 +- .../android-project/app/jni/src/Android.mk | 2 +- .../app/src/main/AndroidManifest.xml | 16 +- .../app/HIDDeviceBLESteamController.java | 6 +- .../java/org/libsdl/app/HIDDeviceManager.java | 67 +- .../main/java/org/libsdl/app/SDLActivity.java | 263 +- .../java/org/libsdl/app/SDLAudioManager.java | 4 + .../org/libsdl/app/SDLControllerManager.java | 38 +- Engine/lib/sdl/android-project/build.gradle | 6 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 53636 -> 54213 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 +- Engine/lib/sdl/autogen.sh | 18 +- .../lib/sdl/build-scripts/checker-buildbot.sh | 2 +- .../{g++-fat.sh => clang++-fat.sh} | 59 +- .../{gcc-fat.sh => clang-fat.sh} | 93 +- .../sdl/build-scripts/codechecker-buildbot.sh | 59 + Engine/lib/sdl/build-scripts/config.guess | 1611 +- Engine/lib/sdl/build-scripts/config.sub | 3022 +- Engine/lib/sdl/build-scripts/config.sub.patch | 72 - .../sdl/build-scripts/emscripten-buildbot.sh | 2 +- Engine/lib/sdl/build-scripts/fnsince.pl | 174 + .../sdl/build-scripts/git-pre-push-hook.pl | 80 + Engine/lib/sdl/build-scripts/install-sh | 414 +- Engine/lib/sdl/build-scripts/iosbuild.sh | 190 - Engine/lib/sdl/build-scripts/ltmain.sh | 5631 +- Engine/lib/sdl/build-scripts/mkinstalldirs | 26 +- Engine/lib/sdl/build-scripts/os2-buildbot.sh | 7 +- Engine/lib/sdl/build-scripts/showrev.sh | 8 +- .../lib/sdl/build-scripts/update-copyright.sh | 2 +- Engine/lib/sdl/build-scripts/updaterev.sh | 5 +- Engine/lib/sdl/build-scripts/wikiheaders.pl | 1258 + Engine/lib/sdl/build-scripts/winrtbuild.ps1 | 2 +- Engine/lib/sdl/cmake/macros.cmake | 66 +- Engine/lib/sdl/cmake/sdlchecks.cmake | 720 +- Engine/lib/sdl/configure | 5390 +- Engine/lib/sdl/configure.ac | 1575 +- Engine/lib/sdl/debian/changelog | 150 - Engine/lib/sdl/debian/compat | 1 - Engine/lib/sdl/debian/control | 76 - Engine/lib/sdl/debian/copyright | 351 - Engine/lib/sdl/debian/docs | 4 - Engine/lib/sdl/debian/libsdl2-dev.install | 9 - Engine/lib/sdl/debian/libsdl2-dev.manpages | 1 - Engine/lib/sdl/debian/libsdl2.install | 1 - Engine/lib/sdl/debian/rules | 54 - Engine/lib/sdl/debian/sdl2-config.1 | 86 - Engine/lib/sdl/debian/source/format | 1 - Engine/lib/sdl/debian/watch | 2 - Engine/lib/sdl/docs/README-android.md | 93 +- Engine/lib/sdl/docs/README-dynapi.md | 42 +- Engine/lib/sdl/docs/README-git.md | 19 + Engine/lib/sdl/docs/README-hg.md | 22 +- Engine/lib/sdl/docs/README-ios.md | 79 +- Engine/lib/sdl/docs/README-kmsbsd.md | 27 + Engine/lib/sdl/docs/README-linux.md | 38 +- Engine/lib/sdl/docs/README-macos.md | 286 + Engine/lib/sdl/docs/README-macosx.md | 240 - Engine/lib/sdl/docs/README-os2.md | 44 +- Engine/lib/sdl/docs/README-psp.md | 35 +- Engine/lib/sdl/docs/README-raspberrypi.md | 54 +- Engine/lib/sdl/docs/README-riscos.md | 41 + Engine/lib/sdl/docs/README-visualc.md | 114 + Engine/lib/sdl/docs/README-vita.md | 30 + Engine/lib/sdl/docs/README-winrt.md | 55 +- Engine/lib/sdl/docs/README.md | 16 +- Engine/lib/sdl/include/SDL.h | 122 +- Engine/lib/sdl/include/SDL_assert.h | 131 +- Engine/lib/sdl/include/SDL_atomic.h | 170 +- Engine/lib/sdl/include/SDL_audio.h | 1259 +- Engine/lib/sdl/include/SDL_bits.h | 17 +- Engine/lib/sdl/include/SDL_blendmode.h | 101 +- Engine/lib/sdl/include/SDL_clipboard.h | 37 +- Engine/lib/sdl/include/SDL_config.h | 6 +- Engine/lib/sdl/include/SDL_config.h.cmake | 95 +- Engine/lib/sdl/include/SDL_config.h.in | 63 +- Engine/lib/sdl/include/SDL_config_android.h | 12 +- .../lib/sdl/include/SDL_config_emscripten.h | 216 + Engine/lib/sdl/include/SDL_config_iphoneos.h | 10 +- Engine/lib/sdl/include/SDL_config_macosx.h | 18 +- Engine/lib/sdl/include/SDL_config_minimal.h | 5 +- Engine/lib/sdl/include/SDL_config_os2.h | 57 +- Engine/lib/sdl/include/SDL_config_pandora.h | 7 +- Engine/lib/sdl/include/SDL_config_psp.h | 165 - Engine/lib/sdl/include/SDL_config_windows.h | 65 +- Engine/lib/sdl/include/SDL_config_winrt.h | 35 +- Engine/lib/sdl/include/SDL_config_wiz.h | 149 - Engine/lib/sdl/include/SDL_copying.h | 2 +- Engine/lib/sdl/include/SDL_cpuinfo.h | 400 +- Engine/lib/sdl/include/SDL_egl.h | 1186 +- Engine/lib/sdl/include/SDL_endian.h | 157 +- Engine/lib/sdl/include/SDL_error.h | 89 +- Engine/lib/sdl/include/SDL_events.h | 481 +- Engine/lib/sdl/include/SDL_filesystem.h | 121 +- Engine/lib/sdl/include/SDL_gamecontroller.h | 711 +- Engine/lib/sdl/include/SDL_gesture.h | 42 +- Engine/lib/sdl/include/SDL_haptic.h | 514 +- Engine/lib/sdl/include/SDL_hidapi.h | 451 + Engine/lib/sdl/include/SDL_hints.h | 2560 +- Engine/lib/sdl/include/SDL_joystick.h | 707 +- Engine/lib/sdl/include/SDL_keyboard.h | 246 +- Engine/lib/sdl/include/SDL_keycode.h | 12 +- Engine/lib/sdl/include/SDL_loadso.h | 50 +- Engine/lib/sdl/include/SDL_locale.h | 66 +- Engine/lib/sdl/include/SDL_log.h | 231 +- Engine/lib/sdl/include/SDL_main.h | 89 +- Engine/lib/sdl/include/SDL_messagebox.h | 93 +- Engine/lib/sdl/include/SDL_metal.h | 59 +- Engine/lib/sdl/include/SDL_misc.h | 34 +- Engine/lib/sdl/include/SDL_mouse.h | 358 +- Engine/lib/sdl/include/SDL_mutex.h | 352 +- Engine/lib/sdl/include/SDL_name.h | 2 +- Engine/lib/sdl/include/SDL_opengl.h | 2 +- Engine/lib/sdl/include/SDL_opengles.h | 2 +- Engine/lib/sdl/include/SDL_opengles2.h | 4 +- Engine/lib/sdl/include/SDL_pixels.h | 233 +- Engine/lib/sdl/include/SDL_platform.h | 41 +- Engine/lib/sdl/include/SDL_power.h | 33 +- Engine/lib/sdl/include/SDL_quit.h | 2 +- Engine/lib/sdl/include/SDL_rect.h | 234 +- Engine/lib/sdl/include/SDL_render.h | 1669 +- Engine/lib/sdl/include/SDL_revision.h | 2 +- Engine/lib/sdl/include/SDL_revision.h.cmake | 6 + Engine/lib/sdl/include/SDL_rwops.h | 638 +- Engine/lib/sdl/include/SDL_scancode.h | 2 +- Engine/lib/sdl/include/SDL_sensor.h | 118 +- Engine/lib/sdl/include/SDL_shape.h | 65 +- Engine/lib/sdl/include/SDL_stdinc.h | 126 +- Engine/lib/sdl/include/SDL_surface.h | 710 +- Engine/lib/sdl/include/SDL_system.h | 446 +- Engine/lib/sdl/include/SDL_syswm.h | 70 +- Engine/lib/sdl/include/SDL_test.h | 2 +- Engine/lib/sdl/include/SDL_test_assert.h | 4 +- Engine/lib/sdl/include/SDL_test_common.h | 29 +- Engine/lib/sdl/include/SDL_test_compare.h | 2 +- Engine/lib/sdl/include/SDL_test_crc32.h | 2 +- Engine/lib/sdl/include/SDL_test_font.h | 6 +- Engine/lib/sdl/include/SDL_test_fuzzer.h | 54 +- Engine/lib/sdl/include/SDL_test_harness.h | 12 +- Engine/lib/sdl/include/SDL_test_images.h | 2 +- Engine/lib/sdl/include/SDL_test_log.h | 2 +- Engine/lib/sdl/include/SDL_test_md5.h | 2 +- Engine/lib/sdl/include/SDL_test_memory.h | 2 +- Engine/lib/sdl/include/SDL_test_random.h | 4 +- Engine/lib/sdl/include/SDL_thread.h | 328 +- Engine/lib/sdl/include/SDL_timer.h | 151 +- Engine/lib/sdl/include/SDL_touch.h | 64 +- Engine/lib/sdl/include/SDL_types.h | 2 +- Engine/lib/sdl/include/SDL_version.h | 118 +- Engine/lib/sdl/include/SDL_video.h | 1712 +- Engine/lib/sdl/include/SDL_vulkan.h | 235 +- Engine/lib/sdl/include/begin_code.h | 23 +- Engine/lib/sdl/include/close_code.h | 2 +- Engine/lib/sdl/sdl2-config.cmake.in | 72 +- Engine/lib/sdl/sdl2.m4 | 42 +- Engine/lib/sdl/sdl2.pc.in | 2 +- Engine/lib/sdl/src/SDL.c | 96 +- Engine/lib/sdl/src/SDL_assert.c | 2 +- Engine/lib/sdl/src/SDL_assert_c.h | 2 +- Engine/lib/sdl/src/SDL_dataqueue.c | 4 +- Engine/lib/sdl/src/SDL_dataqueue.h | 2 +- Engine/lib/sdl/src/SDL_error.c | 2 +- Engine/lib/sdl/src/SDL_error_c.h | 2 +- Engine/lib/sdl/src/SDL_hints.c | 2 +- Engine/lib/sdl/src/SDL_hints_c.h | 2 +- Engine/lib/sdl/src/SDL_internal.h | 7 +- Engine/lib/sdl/src/SDL_log.c | 15 +- Engine/lib/sdl/src/atomic/SDL_atomic.c | 28 +- Engine/lib/sdl/src/atomic/SDL_spinlock.c | 30 +- Engine/lib/sdl/src/audio/SDL_audio.c | 225 +- Engine/lib/sdl/src/audio/SDL_audio_c.h | 2 +- Engine/lib/sdl/src/audio/SDL_audiocvt.c | 523 +- Engine/lib/sdl/src/audio/SDL_audiodev.c | 12 +- Engine/lib/sdl/src/audio/SDL_audiodev_c.h | 2 +- Engine/lib/sdl/src/audio/SDL_audiotypecvt.c | 2 +- Engine/lib/sdl/src/audio/SDL_mixer.c | 120 +- Engine/lib/sdl/src/audio/SDL_sysaudio.h | 30 +- Engine/lib/sdl/src/audio/SDL_wave.c | 10 +- Engine/lib/sdl/src/audio/SDL_wave.h | 4 +- Engine/lib/sdl/src/audio/aaudio/SDL_aaudio.c | 462 + Engine/lib/sdl/src/audio/aaudio/SDL_aaudio.h | 53 + .../sdl/src/audio/aaudio/SDL_aaudiofuncs.h | 80 + .../lib/sdl/src/audio/alsa/SDL_alsa_audio.c | 450 +- .../lib/sdl/src/audio/alsa/SDL_alsa_audio.h | 2 +- .../sdl/src/audio/android/SDL_androidaudio.c | 27 +- .../sdl/src/audio/android/SDL_androidaudio.h | 2 +- Engine/lib/sdl/src/audio/arts/SDL_artsaudio.c | 40 +- Engine/lib/sdl/src/audio/arts/SDL_artsaudio.h | 2 +- .../sdl/src/audio/coreaudio/SDL_coreaudio.h | 2 +- .../sdl/src/audio/coreaudio/SDL_coreaudio.m | 97 +- .../src/audio/directsound/SDL_directsound.c | 53 +- .../src/audio/directsound/SDL_directsound.h | 2 +- Engine/lib/sdl/src/audio/disk/SDL_diskaudio.c | 68 +- Engine/lib/sdl/src/audio/disk/SDL_diskaudio.h | 4 +- Engine/lib/sdl/src/audio/dsp/SDL_dspaudio.c | 29 +- Engine/lib/sdl/src/audio/dsp/SDL_dspaudio.h | 2 +- .../lib/sdl/src/audio/dummy/SDL_dummyaudio.c | 19 +- .../lib/sdl/src/audio/dummy/SDL_dummyaudio.h | 4 +- .../audio/emscripten/SDL_emscriptenaudio.c | 57 +- .../audio/emscripten/SDL_emscriptenaudio.h | 2 +- Engine/lib/sdl/src/audio/esd/SDL_esdaudio.c | 16 +- Engine/lib/sdl/src/audio/esd/SDL_esdaudio.h | 2 +- .../sdl/src/audio/fusionsound/SDL_fsaudio.c | 41 +- .../sdl/src/audio/fusionsound/SDL_fsaudio.h | 2 +- .../lib/sdl/src/audio/haiku/SDL_haikuaudio.cc | 33 +- .../lib/sdl/src/audio/haiku/SDL_haikuaudio.h | 2 +- Engine/lib/sdl/src/audio/jack/SDL_jackaudio.c | 15 +- Engine/lib/sdl/src/audio/jack/SDL_jackaudio.h | 2 +- Engine/lib/sdl/src/audio/nacl/SDL_naclaudio.c | 16 +- Engine/lib/sdl/src/audio/nacl/SDL_naclaudio.h | 2 +- Engine/lib/sdl/src/audio/nas/SDL_nasaudio.c | 80 +- Engine/lib/sdl/src/audio/nas/SDL_nasaudio.h | 2 +- .../sdl/src/audio/netbsd/SDL_netbsdaudio.c | 137 +- .../sdl/src/audio/netbsd/SDL_netbsdaudio.h | 2 +- .../lib/sdl/src/audio/openslES/SDL_openslES.c | 112 +- .../lib/sdl/src/audio/openslES/SDL_openslES.h | 2 +- Engine/lib/sdl/src/audio/os2/SDL_os2audio.c | 90 +- Engine/lib/sdl/src/audio/os2/SDL_os2audio.h | 2 +- Engine/lib/sdl/src/audio/paudio/SDL_paudio.c | 82 +- Engine/lib/sdl/src/audio/paudio/SDL_paudio.h | 2 +- .../lib/sdl/src/audio/pipewire/SDL_pipewire.c | 1276 + .../lib/sdl/src/audio/pipewire/SDL_pipewire.h | 47 + Engine/lib/sdl/src/audio/psp/SDL_pspaudio.c | 104 +- Engine/lib/sdl/src/audio/psp/SDL_pspaudio.h | 2 +- .../sdl/src/audio/pulseaudio/SDL_pulseaudio.c | 157 +- .../sdl/src/audio/pulseaudio/SDL_pulseaudio.h | 8 +- Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.c | 127 +- Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.h | 5 +- .../lib/sdl/src/audio/sndio/SDL_sndioaudio.c | 35 +- .../lib/sdl/src/audio/sndio/SDL_sndioaudio.h | 2 +- Engine/lib/sdl/src/audio/sun/SDL_sunaudio.c | 15 +- Engine/lib/sdl/src/audio/sun/SDL_sunaudio.h | 2 +- Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.c | 183 + Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.h | 45 + Engine/lib/sdl/src/audio/wasapi/SDL_wasapi.c | 167 +- Engine/lib/sdl/src/audio/wasapi/SDL_wasapi.h | 5 +- .../sdl/src/audio/wasapi/SDL_wasapi_win32.c | 34 +- .../sdl/src/audio/wasapi/SDL_wasapi_winrt.cpp | 29 +- Engine/lib/sdl/src/audio/winmm/SDL_winmm.c | 44 +- Engine/lib/sdl/src/audio/winmm/SDL_winmm.h | 2 +- Engine/lib/sdl/src/core/android/SDL_android.c | 114 +- Engine/lib/sdl/src/core/android/SDL_android.h | 7 +- .../lib/sdl/src/core/android/keyinfotable.h | 2 +- .../src/core/freebsd/SDL_evdev_kbd_freebsd.c | 28 +- Engine/lib/sdl/src/core/linux/SDL_dbus.c | 31 +- Engine/lib/sdl/src/core/linux/SDL_dbus.h | 2 +- Engine/lib/sdl/src/core/linux/SDL_evdev.c | 42 +- Engine/lib/sdl/src/core/linux/SDL_evdev.h | 2 +- .../src/core/linux/SDL_evdev_capabilities.c | 51 +- .../src/core/linux/SDL_evdev_capabilities.h | 5 +- Engine/lib/sdl/src/core/linux/SDL_evdev_kbd.c | 8 +- Engine/lib/sdl/src/core/linux/SDL_evdev_kbd.h | 2 +- .../linux/SDL_evdev_kbd_default_accents.h | 2 +- .../core/linux/SDL_evdev_kbd_default_keymap.h | 2 +- Engine/lib/sdl/src/core/linux/SDL_fcitx.c | 7 +- Engine/lib/sdl/src/core/linux/SDL_fcitx.h | 2 +- Engine/lib/sdl/src/core/linux/SDL_ibus.c | 11 +- Engine/lib/sdl/src/core/linux/SDL_ibus.h | 2 +- Engine/lib/sdl/src/core/linux/SDL_ime.c | 10 +- Engine/lib/sdl/src/core/linux/SDL_ime.h | 2 +- .../lib/sdl/src/core/linux/SDL_threadprio.c | 6 +- Engine/lib/sdl/src/core/linux/SDL_udev.c | 156 +- Engine/lib/sdl/src/core/linux/SDL_udev.h | 3 +- Engine/lib/sdl/src/core/openbsd/SDL_wscons.h | 27 + .../lib/sdl/src/core/openbsd/SDL_wscons_kbd.c | 841 + .../sdl/src/core/openbsd/SDL_wscons_mouse.c | 134 + Engine/lib/sdl/src/core/os2/SDL_os2.c | 4 +- Engine/lib/sdl/src/core/os2/SDL_os2.h | 11 +- .../lib/sdl/src/core/os2/geniconv/geniconv.c | 118 +- .../lib/sdl/src/core/os2/geniconv/geniconv.h | 24 +- Engine/lib/sdl/src/core/os2/geniconv/makefile | 2 +- Engine/lib/sdl/src/core/os2/geniconv/os2cp.c | 81 +- Engine/lib/sdl/src/core/os2/geniconv/os2cp.h | 2 +- .../lib/sdl/src/core/os2/geniconv/os2iconv.c | 82 +- .../lib/sdl/src/core/os2/geniconv/sys2utf8.c | 102 +- Engine/lib/sdl/src/core/os2/geniconv/test.c | 2 +- Engine/lib/sdl/src/core/os2/iconv2.lbc | 4 + Engine/lib/sdl/src/core/unix/SDL_poll.c | 29 +- Engine/lib/sdl/src/core/unix/SDL_poll.h | 7 +- Engine/lib/sdl/src/core/windows/SDL_directx.h | 2 +- Engine/lib/sdl/src/core/windows/SDL_hid.c | 4 +- Engine/lib/sdl/src/core/windows/SDL_hid.h | 2 +- Engine/lib/sdl/src/core/windows/SDL_windows.c | 90 +- Engine/lib/sdl/src/core/windows/SDL_windows.h | 31 +- Engine/lib/sdl/src/core/windows/SDL_xinput.c | 10 +- Engine/lib/sdl/src/core/windows/SDL_xinput.h | 2 +- .../src/core/winrt/SDL_winrtapp_common.cpp | 2 +- .../sdl/src/core/winrt/SDL_winrtapp_common.h | 2 +- .../src/core/winrt/SDL_winrtapp_direct3d.cpp | 86 +- .../src/core/winrt/SDL_winrtapp_direct3d.h | 2 +- .../sdl/src/core/winrt/SDL_winrtapp_xaml.cpp | 4 +- .../sdl/src/core/winrt/SDL_winrtapp_xaml.h | 2 +- Engine/lib/sdl/src/cpuinfo/SDL_cpuinfo.c | 232 +- Engine/lib/sdl/src/dynapi/SDL_dynapi.c | 10 +- Engine/lib/sdl/src/dynapi/SDL_dynapi.h | 6 +- .../lib/sdl/src/dynapi/SDL_dynapi_overrides.h | 78 +- Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h | 90 +- Engine/lib/sdl/src/dynapi/gendynapi.pl | 22 +- .../lib/sdl/src/events/SDL_clipboardevents.c | 2 +- .../sdl/src/events/SDL_clipboardevents_c.h | 2 +- Engine/lib/sdl/src/events/SDL_displayevents.c | 2 +- .../lib/sdl/src/events/SDL_displayevents_c.h | 2 +- Engine/lib/sdl/src/events/SDL_dropevents.c | 2 +- Engine/lib/sdl/src/events/SDL_dropevents_c.h | 2 +- Engine/lib/sdl/src/events/SDL_events.c | 389 +- Engine/lib/sdl/src/events/SDL_events_c.h | 2 +- Engine/lib/sdl/src/events/SDL_gesture.c | 8 +- Engine/lib/sdl/src/events/SDL_gesture_c.h | 2 +- Engine/lib/sdl/src/events/SDL_keyboard.c | 68 +- Engine/lib/sdl/src/events/SDL_keyboard_c.h | 2 +- Engine/lib/sdl/src/events/SDL_mouse.c | 266 +- Engine/lib/sdl/src/events/SDL_mouse_c.h | 14 +- Engine/lib/sdl/src/events/SDL_quit.c | 4 +- Engine/lib/sdl/src/events/SDL_sysevents.h | 2 +- Engine/lib/sdl/src/events/SDL_touch.c | 19 +- Engine/lib/sdl/src/events/SDL_touch_c.h | 3 +- Engine/lib/sdl/src/events/SDL_windowevents.c | 10 +- .../lib/sdl/src/events/SDL_windowevents_c.h | 2 +- Engine/lib/sdl/src/events/blank_cursor.h | 2 +- Engine/lib/sdl/src/events/default_cursor.h | 3 +- .../sdl/src/{video/x11 => events}/imKStoUCS.c | 7 +- .../sdl/src/{video/x11 => events}/imKStoUCS.h | 2 +- Engine/lib/sdl/src/events/scancodes_darwin.h | 2 +- Engine/lib/sdl/src/events/scancodes_linux.h | 2 +- Engine/lib/sdl/src/events/scancodes_windows.h | 2 +- Engine/lib/sdl/src/events/scancodes_xfree86.h | 2 +- Engine/lib/sdl/src/file/SDL_rwops.c | 259 +- .../src/file/cocoa/SDL_rwopsbundlesupport.h | 2 +- .../src/file/cocoa/SDL_rwopsbundlesupport.m | 2 +- .../filesystem/android/SDL_sysfilesystem.c | 2 +- .../src/filesystem/cocoa/SDL_sysfilesystem.m | 2 +- .../src/filesystem/dummy/SDL_sysfilesystem.c | 2 +- .../filesystem/emscripten/SDL_sysfilesystem.c | 13 +- .../src/filesystem/haiku/SDL_sysfilesystem.cc | 2 +- .../src/filesystem/nacl/SDL_sysfilesystem.c | 2 +- .../src/filesystem/os2/SDL_sysfilesystem.c | 32 +- .../src/filesystem/psp/SDL_sysfilesystem.c | 79 + .../src/filesystem/riscos/SDL_sysfilesystem.c | 210 + .../src/filesystem/unix/SDL_sysfilesystem.c | 100 +- .../src/filesystem/vita/SDL_sysfilesystem.c | 95 + .../filesystem/windows/SDL_sysfilesystem.c | 28 +- .../filesystem/winrt/SDL_sysfilesystem.cpp | 2 +- Engine/lib/sdl/src/haptic/SDL_haptic.c | 2 +- Engine/lib/sdl/src/haptic/SDL_haptic_c.h | 2 +- Engine/lib/sdl/src/haptic/SDL_syshaptic.h | 2 +- .../sdl/src/haptic/android/SDL_syshaptic.c | 4 +- .../lib/sdl/src/haptic/darwin/SDL_syshaptic.c | 4 +- .../sdl/src/haptic/darwin/SDL_syshaptic_c.h | 2 +- .../lib/sdl/src/haptic/dummy/SDL_syshaptic.c | 2 +- .../lib/sdl/src/haptic/linux/SDL_syshaptic.c | 19 +- .../sdl/src/haptic/windows/SDL_dinputhaptic.c | 64 +- .../src/haptic/windows/SDL_dinputhaptic_c.h | 6 +- .../src/haptic/windows/SDL_windowshaptic.c | 18 +- .../src/haptic/windows/SDL_windowshaptic_c.h | 2 +- .../sdl/src/haptic/windows/SDL_xinputhaptic.c | 19 +- .../src/haptic/windows/SDL_xinputhaptic_c.h | 6 +- Engine/lib/sdl/src/hidapi/SDL_hidapi.c | 1129 +- Engine/lib/sdl/src/hidapi/SDL_hidapi_c.h | 35 + Engine/lib/sdl/src/hidapi/android/hid.cpp | 297 +- Engine/lib/sdl/src/hidapi/hidapi/hidapi.h | 73 +- Engine/lib/sdl/src/hidapi/ios/hid.m | 121 +- Engine/lib/sdl/src/hidapi/libusb/hid.c | 272 +- Engine/lib/sdl/src/hidapi/linux/hid.c | 67 +- Engine/lib/sdl/src/hidapi/linux/hid.cpp | 333 - Engine/lib/sdl/src/hidapi/mac/hid.c | 103 +- Engine/lib/sdl/src/hidapi/windows/hid.c | 154 +- .../lib/sdl/src/joystick/SDL_gamecontroller.c | 238 +- .../sdl/src/joystick/SDL_gamecontrollerdb.h | 84 +- Engine/lib/sdl/src/joystick/SDL_joystick.c | 412 +- Engine/lib/sdl/src/joystick/SDL_joystick_c.h | 14 +- Engine/lib/sdl/src/joystick/SDL_sysjoystick.h | 24 +- .../src/joystick/android/SDL_sysjoystick.c | 30 +- .../src/joystick/android/SDL_sysjoystick_c.h | 2 +- .../sdl/src/joystick/bsd/SDL_bsdjoystick.c | 33 +- Engine/lib/sdl/src/joystick/controller_type.h | 86 +- .../src/joystick/darwin/SDL_iokitjoystick.c | 53 +- .../src/joystick/darwin/SDL_iokitjoystick_c.h | 2 +- .../sdl/src/joystick/dummy/SDL_sysjoystick.c | 17 +- .../src/joystick/emscripten/SDL_sysjoystick.c | 17 +- .../joystick/emscripten/SDL_sysjoystick_c.h | 2 +- .../src/joystick/haiku/SDL_haikujoystick.cc | 15 +- .../src/joystick/hidapi/SDL_hidapi_gamecube.c | 436 +- .../sdl/src/joystick/hidapi/SDL_hidapi_luna.c | 463 + .../sdl/src/joystick/hidapi/SDL_hidapi_ps4.c | 278 +- .../sdl/src/joystick/hidapi/SDL_hidapi_ps5.c | 460 +- .../src/joystick/hidapi/SDL_hidapi_rumble.c | 11 +- .../src/joystick/hidapi/SDL_hidapi_rumble.h | 2 +- .../src/joystick/hidapi/SDL_hidapi_stadia.c | 331 + .../src/joystick/hidapi/SDL_hidapi_steam.c | 257 +- .../src/joystick/hidapi/SDL_hidapi_switch.c | 401 +- .../src/joystick/hidapi/SDL_hidapi_xbox360.c | 74 +- .../src/joystick/hidapi/SDL_hidapi_xbox360w.c | 56 +- .../src/joystick/hidapi/SDL_hidapi_xboxone.c | 253 +- .../src/joystick/hidapi/SDL_hidapijoystick.c | 510 +- .../joystick/hidapi/SDL_hidapijoystick_c.h | 23 +- .../hidapi/steam/controller_constants.h | 2 +- .../hidapi/steam/controller_structs.h | 37 + .../src/joystick/iphoneos/SDL_mfijoystick.m | 521 +- .../src/joystick/iphoneos/SDL_mfijoystick_c.h | 3 +- .../sdl/src/joystick/linux/SDL_sysjoystick.c | 638 +- .../src/joystick/linux/SDL_sysjoystick_c.h | 8 +- .../sdl/src/joystick/os2/SDL_os2joystick.c | 799 + .../sdl/src/joystick/psp/SDL_sysjoystick.c | 135 +- .../lib/sdl/src/joystick/sort_controllers.py | 2 +- .../src/joystick/steam/SDL_steamcontroller.c | 2 +- .../src/joystick/steam/SDL_steamcontroller.h | 2 +- Engine/lib/sdl/src/joystick/usb_ids.h | 73 +- .../joystick/virtual/SDL_virtualjoystick.c | 41 +- .../joystick/virtual/SDL_virtualjoystick_c.h | 2 +- .../sdl/src/joystick/vita/SDL_sysjoystick.c | 425 + .../src/joystick/windows/SDL_dinputjoystick.c | 725 +- .../joystick/windows/SDL_dinputjoystick_c.h | 3 +- .../sdl/src/joystick/windows/SDL_mmjoystick.c | 452 - .../joystick/windows/SDL_rawinputjoystick.c | 230 +- .../joystick/windows/SDL_rawinputjoystick_c.h | 2 +- .../windows/SDL_windows_gaming_input.c | 334 +- .../joystick/windows/SDL_windowsjoystick.c | 195 +- .../joystick/windows/SDL_windowsjoystick_c.h | 4 +- .../src/joystick/windows/SDL_xinputjoystick.c | 31 +- .../joystick/windows/SDL_xinputjoystick_c.h | 3 +- Engine/lib/sdl/src/libm/math_libm.h | 2 +- Engine/lib/sdl/src/libm/math_private.h | 2 +- .../lib/sdl/src/loadso/dlopen/SDL_sysloadso.c | 2 +- .../lib/sdl/src/loadso/dummy/SDL_sysloadso.c | 2 +- Engine/lib/sdl/src/loadso/os2/SDL_sysloadso.c | 4 +- .../sdl/src/loadso/windows/SDL_sysloadso.c | 4 +- Engine/lib/sdl/src/locale/SDL_locale.c | 4 +- Engine/lib/sdl/src/locale/SDL_syslocale.h | 2 +- .../sdl/src/locale/android/SDL_syslocale.c | 2 +- .../lib/sdl/src/locale/dummy/SDL_syslocale.c | 2 +- .../sdl/src/locale/emscripten/SDL_syslocale.c | 2 +- .../lib/sdl/src/locale/haiku/SDL_syslocale.cc | 2 +- .../lib/sdl/src/locale/macosx/SDL_syslocale.m | 2 +- .../lib/sdl/src/locale/unix/SDL_syslocale.c | 2 +- .../sdl/src/locale/windows/SDL_syslocale.c | 12 +- .../lib/sdl/src/locale/winrt/SDL_syslocale.c | 2 +- .../lib/sdl/src/main/dummy/SDL_dummy_main.c | 3 - Engine/lib/sdl/src/main/haiku/SDL_BApp.h | 53 +- Engine/lib/sdl/src/main/haiku/SDL_BeApp.cc | 2 +- Engine/lib/sdl/src/main/haiku/SDL_BeApp.h | 2 +- Engine/lib/sdl/src/main/nacl/SDL_nacl_main.c | 2 +- Engine/lib/sdl/src/main/psp/SDL_psp_main.c | 19 +- .../lib/sdl/src/main/uikit/SDL_uikit_main.c | 2 + .../sdl/src/main/windows/SDL_windows_main.c | 23 +- Engine/lib/sdl/src/main/windows/version.rc | 10 +- Engine/lib/sdl/src/misc/SDL_sysurl.h | 2 +- Engine/lib/sdl/src/misc/SDL_url.c | 2 +- Engine/lib/sdl/src/misc/android/SDL_sysurl.c | 2 +- Engine/lib/sdl/src/misc/dummy/SDL_sysurl.c | 2 +- .../lib/sdl/src/misc/emscripten/SDL_sysurl.c | 37 + Engine/lib/sdl/src/misc/haiku/SDL_sysurl.cc | 2 +- Engine/lib/sdl/src/misc/ios/SDL_sysurl.m | 2 +- Engine/lib/sdl/src/misc/macosx/SDL_sysurl.m | 10 +- Engine/lib/sdl/src/misc/riscos/SDL_sysurl.c | 2 +- Engine/lib/sdl/src/misc/unix/SDL_sysurl.c | 9 +- Engine/lib/sdl/src/misc/vita/SDL_sysurl.c | 44 + Engine/lib/sdl/src/misc/windows/SDL_sysurl.c | 4 +- Engine/lib/sdl/src/misc/winrt/SDL_sysurl.cpp | 8 +- Engine/lib/sdl/src/power/SDL_power.c | 5 +- Engine/lib/sdl/src/power/SDL_syspower.h | 3 +- .../lib/sdl/src/power/android/SDL_syspower.c | 2 +- .../sdl/src/power/emscripten/SDL_syspower.c | 2 +- Engine/lib/sdl/src/power/haiku/SDL_syspower.c | 6 +- Engine/lib/sdl/src/power/linux/SDL_syspower.c | 77 +- .../lib/sdl/src/power/macosx/SDL_syspower.c | 2 +- Engine/lib/sdl/src/power/psp/SDL_syspower.c | 2 +- Engine/lib/sdl/src/power/uikit/SDL_syspower.h | 2 +- Engine/lib/sdl/src/power/uikit/SDL_syspower.m | 2 +- Engine/lib/sdl/src/power/vita/SDL_syspower.c | 68 + .../lib/sdl/src/power/windows/SDL_syspower.c | 2 +- .../lib/sdl/src/power/winrt/SDL_syspower.cpp | 2 +- Engine/lib/sdl/src/render/SDL_d3dmath.c | 2 +- Engine/lib/sdl/src/render/SDL_d3dmath.h | 2 +- Engine/lib/sdl/src/render/SDL_render.c | 1916 +- Engine/lib/sdl/src/render/SDL_sysrender.h | 59 +- Engine/lib/sdl/src/render/SDL_yuv_sw.c | 41 +- Engine/lib/sdl/src/render/SDL_yuv_sw_c.h | 10 +- .../sdl/src/render/direct3d/SDL_render_d3d.c | 462 +- .../sdl/src/render/direct3d/SDL_shaders_d3d.c | 2 +- .../sdl/src/render/direct3d/SDL_shaders_d3d.h | 2 +- .../src/render/direct3d11/SDL_render_d3d11.c | 550 +- .../render/direct3d11/SDL_render_winrt.cpp | 2 +- .../src/render/direct3d11/SDL_render_winrt.h | 2 +- .../src/render/direct3d11/SDL_shaders_d3d11.c | 12 +- .../src/render/direct3d11/SDL_shaders_d3d11.h | 4 +- .../sdl/src/render/metal/SDL_render_metal.m | 515 +- .../src/render/metal/SDL_shaders_metal.metal | 25 +- .../src/render/metal/SDL_shaders_metal_ios.h | 3426 +- .../metal/SDL_shaders_metal_iphonesimulator.h | 3842 +- .../src/render/metal/SDL_shaders_metal_osx.h | 3454 +- .../src/render/metal/SDL_shaders_metal_tvos.h | 3426 +- .../metal/SDL_shaders_metal_tvsimulator.h | 3929 +- .../lib/sdl/src/render/opengl/SDL_glfuncs.h | 26 +- .../lib/sdl/src/render/opengl/SDL_render_gl.c | 815 +- .../sdl/src/render/opengl/SDL_shaders_gl.c | 60 +- .../sdl/src/render/opengl/SDL_shaders_gl.h | 10 +- .../sdl/src/render/opengles/SDL_glesfuncs.h | 7 +- .../sdl/src/render/opengles/SDL_render_gles.c | 357 +- .../sdl/src/render/opengles2/SDL_gles2funcs.h | 3 +- .../src/render/opengles2/SDL_render_gles2.c | 999 +- .../src/render/opengles2/SDL_shaders_gles2.c | 423 +- .../src/render/opengles2/SDL_shaders_gles2.h | 56 +- .../lib/sdl/src/render/psp/SDL_render_psp.c | 834 +- .../src/render/software/SDL_blendfillrect.c | 6 +- .../src/render/software/SDL_blendfillrect.h | 2 +- .../sdl/src/render/software/SDL_blendline.c | 4 +- .../sdl/src/render/software/SDL_blendline.h | 2 +- .../sdl/src/render/software/SDL_blendpoint.c | 6 +- .../sdl/src/render/software/SDL_blendpoint.h | 2 +- Engine/lib/sdl/src/render/software/SDL_draw.h | 10 +- .../sdl/src/render/software/SDL_drawline.c | 10 +- .../sdl/src/render/software/SDL_drawline.h | 2 +- .../sdl/src/render/software/SDL_drawpoint.c | 6 +- .../sdl/src/render/software/SDL_drawpoint.h | 2 +- .../sdl/src/render/software/SDL_render_sw.c | 435 +- .../sdl/src/render/software/SDL_render_sw_c.h | 2 +- .../lib/sdl/src/render/software/SDL_rotate.c | 234 +- .../lib/sdl/src/render/software/SDL_rotate.h | 8 +- .../sdl/src/render/software/SDL_triangle.c | 888 + .../sdl/src/render/software/SDL_triangle.h | 42 + .../src/render/vitagxm/SDL_render_vita_gxm.c | 1042 + .../vitagxm/SDL_render_vita_gxm_memory.c | 117 + .../vitagxm/SDL_render_vita_gxm_memory.h | 40 + .../vitagxm/SDL_render_vita_gxm_shaders.h | 280 + .../vitagxm/SDL_render_vita_gxm_tools.c | 1239 + .../vitagxm/SDL_render_vita_gxm_tools.h | 70 + .../vitagxm/SDL_render_vita_gxm_types.h | 201 + .../src/render/vitagxm/shader_src/clear_f.cg | 4 + .../src/render/vitagxm/shader_src/clear_v.cg | 4 + .../src/render/vitagxm/shader_src/color_f.cg | 4 + .../src/render/vitagxm/shader_src/color_v.cg | 13 + .../render/vitagxm/shader_src/texture_f.cg | 4 + .../render/vitagxm/shader_src/texture_v.cg | 14 + Engine/lib/sdl/src/sensor/SDL_sensor.c | 7 +- Engine/lib/sdl/src/sensor/SDL_sensor_c.h | 2 +- Engine/lib/sdl/src/sensor/SDL_syssensor.h | 3 +- .../src/sensor/android/SDL_androidsensor.c | 2 +- .../src/sensor/android/SDL_androidsensor.h | 2 +- .../sensor/coremotion/SDL_coremotionsensor.h | 2 +- .../sensor/coremotion/SDL_coremotionsensor.m | 2 +- .../sdl/src/sensor/dummy/SDL_dummysensor.c | 2 +- .../sdl/src/sensor/dummy/SDL_dummysensor.h | 2 +- .../lib/sdl/src/sensor/vita/SDL_vitasensor.c | 219 + .../lib/sdl/src/sensor/vita/SDL_vitasensor.h | 30 + .../src/sensor/windows/SDL_windowssensor.c | 14 +- .../src/sensor/windows/SDL_windowssensor.h | 2 +- Engine/lib/sdl/src/stdlib/SDL_crc32.c | 2 +- Engine/lib/sdl/src/stdlib/SDL_getenv.c | 16 +- Engine/lib/sdl/src/stdlib/SDL_iconv.c | 97 +- Engine/lib/sdl/src/stdlib/SDL_malloc.c | 7 +- Engine/lib/sdl/src/stdlib/SDL_qsort.c | 2 +- Engine/lib/sdl/src/stdlib/SDL_stdlib.c | 83 +- Engine/lib/sdl/src/stdlib/SDL_string.c | 382 +- Engine/lib/sdl/src/stdlib/SDL_strtokr.c | 7 +- Engine/lib/sdl/src/test/SDL_test_assert.c | 4 +- Engine/lib/sdl/src/test/SDL_test_common.c | 597 +- Engine/lib/sdl/src/test/SDL_test_compare.c | 2 +- Engine/lib/sdl/src/test/SDL_test_crc32.c | 2 +- Engine/lib/sdl/src/test/SDL_test_font.c | 62 +- Engine/lib/sdl/src/test/SDL_test_fuzzer.c | 2 +- Engine/lib/sdl/src/test/SDL_test_harness.c | 43 +- Engine/lib/sdl/src/test/SDL_test_imageBlit.c | 2 +- .../sdl/src/test/SDL_test_imageBlitBlend.c | 2 +- Engine/lib/sdl/src/test/SDL_test_imageFace.c | 2 +- .../sdl/src/test/SDL_test_imagePrimitives.c | 2 +- .../src/test/SDL_test_imagePrimitivesBlend.c | 2 +- Engine/lib/sdl/src/test/SDL_test_log.c | 2 +- Engine/lib/sdl/src/test/SDL_test_md5.c | 2 +- Engine/lib/sdl/src/test/SDL_test_memory.c | 7 +- Engine/lib/sdl/src/test/SDL_test_random.c | 5 +- Engine/lib/sdl/src/thread/SDL_systhread.h | 2 +- Engine/lib/sdl/src/thread/SDL_thread.c | 8 +- Engine/lib/sdl/src/thread/SDL_thread_c.h | 4 +- .../lib/sdl/src/thread/generic/SDL_syscond.c | 53 +- .../sdl/src/thread/generic/SDL_syscond_c.h | 42 + .../lib/sdl/src/thread/generic/SDL_sysmutex.c | 8 +- .../sdl/src/thread/generic/SDL_sysmutex_c.h | 2 +- .../lib/sdl/src/thread/generic/SDL_syssem.c | 8 +- .../sdl/src/thread/generic/SDL_systhread.c | 2 +- .../sdl/src/thread/generic/SDL_systhread_c.h | 2 +- .../lib/sdl/src/thread/generic/SDL_systls.c | 2 +- Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c | 8 +- Engine/lib/sdl/src/thread/os2/SDL_syssem.c | 8 +- Engine/lib/sdl/src/thread/os2/SDL_systhread.c | 2 +- .../lib/sdl/src/thread/os2/SDL_systhread_c.h | 2 +- Engine/lib/sdl/src/thread/os2/SDL_systls.c | 2 +- Engine/lib/sdl/src/thread/os2/SDL_systls_c.h | 2 +- Engine/lib/sdl/src/thread/psp/SDL_syscond.c | 8 +- Engine/lib/sdl/src/thread/psp/SDL_sysmutex.c | 108 +- .../lib/sdl/src/thread/psp/SDL_sysmutex_c.h | 2 +- Engine/lib/sdl/src/thread/psp/SDL_syssem.c | 14 +- Engine/lib/sdl/src/thread/psp/SDL_systhread.c | 10 +- .../lib/sdl/src/thread/psp/SDL_systhread_c.h | 2 +- .../lib/sdl/src/thread/pthread/SDL_syscond.c | 10 +- .../lib/sdl/src/thread/pthread/SDL_sysmutex.c | 8 +- .../sdl/src/thread/pthread/SDL_sysmutex_c.h | 2 +- .../lib/sdl/src/thread/pthread/SDL_syssem.c | 10 +- .../sdl/src/thread/pthread/SDL_systhread.c | 43 +- .../sdl/src/thread/pthread/SDL_systhread_c.h | 2 +- .../lib/sdl/src/thread/pthread/SDL_systls.c | 2 +- .../lib/sdl/src/thread/stdcpp/SDL_syscond.cpp | 17 +- .../sdl/src/thread/stdcpp/SDL_sysmutex.cpp | 13 +- .../sdl/src/thread/stdcpp/SDL_sysmutex_c.h | 2 +- .../sdl/src/thread/stdcpp/SDL_systhread.cpp | 8 +- .../sdl/src/thread/stdcpp/SDL_systhread_c.h | 2 +- Engine/lib/sdl/src/thread/vita/SDL_syscond.c | 224 + Engine/lib/sdl/src/thread/vita/SDL_sysmutex.c | 149 + .../lib/sdl/src/thread/vita/SDL_sysmutex_c.h | 23 + Engine/lib/sdl/src/thread/vita/SDL_syssem.c | 162 + .../lib/sdl/src/thread/vita/SDL_systhread.c | 138 + .../lib/sdl/src/thread/vita/SDL_systhread_c.h | 26 + .../sdl/src/thread/windows/SDL_syscond_cv.c | 299 + .../lib/sdl/src/thread/windows/SDL_sysmutex.c | 259 +- .../sdl/src/thread/windows/SDL_sysmutex_c.h | 74 + .../lib/sdl/src/thread/windows/SDL_syssem.c | 378 +- .../sdl/src/thread/windows/SDL_systhread.c | 6 +- .../sdl/src/thread/windows/SDL_systhread_c.h | 2 +- .../lib/sdl/src/thread/windows/SDL_systls.c | 2 +- Engine/lib/sdl/src/timer/SDL_timer.c | 124 +- Engine/lib/sdl/src/timer/SDL_timer_c.h | 2 +- Engine/lib/sdl/src/timer/dummy/SDL_systimer.c | 6 +- Engine/lib/sdl/src/timer/haiku/SDL_systimer.c | 8 +- Engine/lib/sdl/src/timer/os2/SDL_systimer.c | 42 +- Engine/lib/sdl/src/timer/psp/SDL_systimer.c | 19 +- Engine/lib/sdl/src/timer/unix/SDL_systimer.c | 44 +- Engine/lib/sdl/src/timer/vita/SDL_systimer.c | 89 + .../lib/sdl/src/timer/windows/SDL_systimer.c | 68 +- Engine/lib/sdl/src/video/SDL_RLEaccel.c | 16 +- Engine/lib/sdl/src/video/SDL_RLEaccel_c.h | 2 +- Engine/lib/sdl/src/video/SDL_blit.c | 6 +- Engine/lib/sdl/src/video/SDL_blit.h | 50 +- Engine/lib/sdl/src/video/SDL_blit_0.c | 85 +- Engine/lib/sdl/src/video/SDL_blit_1.c | 2 +- Engine/lib/sdl/src/video/SDL_blit_A.c | 91 +- Engine/lib/sdl/src/video/SDL_blit_N.c | 75 +- Engine/lib/sdl/src/video/SDL_blit_auto.c | 1682 +- Engine/lib/sdl/src/video/SDL_blit_auto.h | 2 +- Engine/lib/sdl/src/video/SDL_blit_copy.c | 4 +- Engine/lib/sdl/src/video/SDL_blit_copy.h | 2 +- Engine/lib/sdl/src/video/SDL_blit_slow.c | 84 +- Engine/lib/sdl/src/video/SDL_blit_slow.h | 2 +- Engine/lib/sdl/src/video/SDL_bmp.c | 57 +- Engine/lib/sdl/src/video/SDL_clipboard.c | 2 +- Engine/lib/sdl/src/video/SDL_egl.c | 312 +- Engine/lib/sdl/src/video/SDL_egl_c.h | 9 +- Engine/lib/sdl/src/video/SDL_fillrect.c | 46 +- Engine/lib/sdl/src/video/SDL_pixels.c | 14 +- Engine/lib/sdl/src/video/SDL_pixels_c.h | 2 +- Engine/lib/sdl/src/video/SDL_rect.c | 493 +- Engine/lib/sdl/src/video/SDL_rect_c.h | 2 +- Engine/lib/sdl/src/video/SDL_rect_impl.h | 444 + Engine/lib/sdl/src/video/SDL_shape.c | 2 +- .../lib/sdl/src/video/SDL_shape_internals.h | 2 +- Engine/lib/sdl/src/video/SDL_stretch.c | 1140 +- Engine/lib/sdl/src/video/SDL_surface.c | 394 +- Engine/lib/sdl/src/video/SDL_sysvideo.h | 26 +- Engine/lib/sdl/src/video/SDL_video.c | 825 +- .../lib/sdl/src/video/SDL_vulkan_internal.h | 10 +- Engine/lib/sdl/src/video/SDL_vulkan_utils.c | 338 +- Engine/lib/sdl/src/video/SDL_yuv.c | 4 +- Engine/lib/sdl/src/video/SDL_yuv_c.h | 2 +- .../src/video/android/SDL_androidclipboard.c | 2 +- .../src/video/android/SDL_androidclipboard.h | 2 +- .../sdl/src/video/android/SDL_androidevents.c | 39 +- .../sdl/src/video/android/SDL_androidevents.h | 2 +- .../lib/sdl/src/video/android/SDL_androidgl.c | 6 +- .../lib/sdl/src/video/android/SDL_androidgl.h | 2 +- .../src/video/android/SDL_androidkeyboard.c | 2 +- .../src/video/android/SDL_androidkeyboard.h | 2 +- .../src/video/android/SDL_androidmessagebox.c | 2 +- .../src/video/android/SDL_androidmessagebox.h | 2 +- .../sdl/src/video/android/SDL_androidmouse.c | 6 +- .../sdl/src/video/android/SDL_androidmouse.h | 2 +- .../sdl/src/video/android/SDL_androidtouch.c | 2 +- .../sdl/src/video/android/SDL_androidtouch.h | 2 +- .../sdl/src/video/android/SDL_androidvideo.c | 50 +- .../sdl/src/video/android/SDL_androidvideo.h | 5 +- .../sdl/src/video/android/SDL_androidvulkan.c | 2 +- .../sdl/src/video/android/SDL_androidvulkan.h | 2 +- .../sdl/src/video/android/SDL_androidwindow.c | 12 +- .../sdl/src/video/android/SDL_androidwindow.h | 4 +- .../sdl/src/video/cocoa/SDL_cocoaclipboard.h | 2 +- .../sdl/src/video/cocoa/SDL_cocoaclipboard.m | 10 +- .../lib/sdl/src/video/cocoa/SDL_cocoaevents.h | 4 +- .../lib/sdl/src/video/cocoa/SDL_cocoaevents.m | 107 +- .../sdl/src/video/cocoa/SDL_cocoakeyboard.h | 4 +- .../sdl/src/video/cocoa/SDL_cocoakeyboard.m | 19 +- .../sdl/src/video/cocoa/SDL_cocoamessagebox.h | 2 +- .../sdl/src/video/cocoa/SDL_cocoamessagebox.m | 29 +- .../sdl/src/video/cocoa/SDL_cocoametalview.h | 3 +- .../sdl/src/video/cocoa/SDL_cocoametalview.m | 26 +- .../lib/sdl/src/video/cocoa/SDL_cocoamodes.h | 2 +- .../lib/sdl/src/video/cocoa/SDL_cocoamodes.m | 69 +- .../lib/sdl/src/video/cocoa/SDL_cocoamouse.h | 3 +- .../lib/sdl/src/video/cocoa/SDL_cocoamouse.m | 84 +- .../sdl/src/video/cocoa/SDL_cocoamousetap.m | 286 - .../lib/sdl/src/video/cocoa/SDL_cocoaopengl.h | 2 +- .../lib/sdl/src/video/cocoa/SDL_cocoaopengl.m | 4 +- .../sdl/src/video/cocoa/SDL_cocoaopengles.h | 2 +- .../sdl/src/video/cocoa/SDL_cocoaopengles.m | 5 +- .../lib/sdl/src/video/cocoa/SDL_cocoashape.h | 2 +- .../lib/sdl/src/video/cocoa/SDL_cocoashape.m | 2 +- .../lib/sdl/src/video/cocoa/SDL_cocoavideo.h | 2 +- .../lib/sdl/src/video/cocoa/SDL_cocoavideo.m | 20 +- .../lib/sdl/src/video/cocoa/SDL_cocoavulkan.h | 2 +- .../lib/sdl/src/video/cocoa/SDL_cocoavulkan.m | 2 +- .../lib/sdl/src/video/cocoa/SDL_cocoawindow.h | 15 +- .../lib/sdl/src/video/cocoa/SDL_cocoawindow.m | 425 +- .../sdl/src/video/directfb/SDL_DirectFB_WM.c | 19 +- .../sdl/src/video/directfb/SDL_DirectFB_WM.h | 2 +- .../sdl/src/video/directfb/SDL_DirectFB_dyn.c | 2 +- .../sdl/src/video/directfb/SDL_DirectFB_dyn.h | 2 +- .../src/video/directfb/SDL_DirectFB_events.c | 33 +- .../src/video/directfb/SDL_DirectFB_events.h | 2 +- .../src/video/directfb/SDL_DirectFB_modes.c | 2 +- .../src/video/directfb/SDL_DirectFB_modes.h | 2 +- .../src/video/directfb/SDL_DirectFB_mouse.c | 4 +- .../src/video/directfb/SDL_DirectFB_mouse.h | 2 +- .../src/video/directfb/SDL_DirectFB_opengl.c | 4 +- .../src/video/directfb/SDL_DirectFB_opengl.h | 2 +- .../src/video/directfb/SDL_DirectFB_render.c | 223 +- .../src/video/directfb/SDL_DirectFB_render.h | 2 +- .../src/video/directfb/SDL_DirectFB_shape.c | 4 +- .../src/video/directfb/SDL_DirectFB_shape.h | 2 +- .../src/video/directfb/SDL_DirectFB_video.c | 8 +- .../src/video/directfb/SDL_DirectFB_video.h | 6 +- .../src/video/directfb/SDL_DirectFB_vulkan.c | 2 +- .../src/video/directfb/SDL_DirectFB_vulkan.h | 2 +- .../src/video/directfb/SDL_DirectFB_window.c | 29 +- .../src/video/directfb/SDL_DirectFB_window.h | 5 +- .../lib/sdl/src/video/dummy/SDL_nullevents.c | 2 +- .../sdl/src/video/dummy/SDL_nullevents_c.h | 2 +- .../sdl/src/video/dummy/SDL_nullframebuffer.c | 12 +- .../src/video/dummy/SDL_nullframebuffer_c.h | 2 +- .../lib/sdl/src/video/dummy/SDL_nullvideo.c | 4 +- .../lib/sdl/src/video/dummy/SDL_nullvideo.h | 2 +- .../video/emscripten/SDL_emscriptenevents.c | 32 +- .../video/emscripten/SDL_emscriptenevents.h | 2 +- .../emscripten/SDL_emscriptenframebuffer.c | 13 +- .../emscripten/SDL_emscriptenframebuffer.h | 2 +- .../video/emscripten/SDL_emscriptenmouse.c | 2 +- .../video/emscripten/SDL_emscriptenmouse.h | 2 +- .../video/emscripten/SDL_emscriptenopengles.c | 2 +- .../video/emscripten/SDL_emscriptenopengles.h | 2 +- .../video/emscripten/SDL_emscriptenvideo.c | 43 +- .../video/emscripten/SDL_emscriptenvideo.h | 2 +- Engine/lib/sdl/src/video/haiku/SDL_BApp.h | 431 + Engine/lib/sdl/src/video/haiku/SDL_BWin.h | 422 +- .../lib/sdl/src/video/haiku/SDL_bclipboard.cc | 2 +- .../lib/sdl/src/video/haiku/SDL_bclipboard.h | 2 +- Engine/lib/sdl/src/video/haiku/SDL_bevents.cc | 2 +- Engine/lib/sdl/src/video/haiku/SDL_bevents.h | 2 +- .../sdl/src/video/haiku/SDL_bframebuffer.cc | 152 +- .../sdl/src/video/haiku/SDL_bframebuffer.h | 2 +- .../lib/sdl/src/video/haiku/SDL_bkeyboard.cc | 2 +- .../lib/sdl/src/video/haiku/SDL_bkeyboard.h | 2 +- .../sdl/src/video/haiku/SDL_bmessagebox.cc | 2 +- .../lib/sdl/src/video/haiku/SDL_bmessagebox.h | 2 +- Engine/lib/sdl/src/video/haiku/SDL_bmodes.cc | 6 +- Engine/lib/sdl/src/video/haiku/SDL_bmodes.h | 2 +- Engine/lib/sdl/src/video/haiku/SDL_bopengl.cc | 38 +- Engine/lib/sdl/src/video/haiku/SDL_bopengl.h | 2 +- Engine/lib/sdl/src/video/haiku/SDL_bvideo.cc | 134 +- Engine/lib/sdl/src/video/haiku/SDL_bvideo.h | 2 +- Engine/lib/sdl/src/video/haiku/SDL_bwindow.cc | 11 +- Engine/lib/sdl/src/video/haiku/SDL_bwindow.h | 5 +- Engine/lib/sdl/src/video/khronos/EGL/egl.h | 89 +- Engine/lib/sdl/src/video/khronos/EGL/eglext.h | 276 +- .../sdl/src/video/khronos/EGL/eglplatform.h | 95 +- .../sdl/src/video/khronos/KHR/khrplatform.h | 26 +- .../lib/sdl/src/video/kmsdrm/SDL_kmsdrmdyn.c | 4 +- .../lib/sdl/src/video/kmsdrm/SDL_kmsdrmdyn.h | 3 +- .../sdl/src/video/kmsdrm/SDL_kmsdrmevents.c | 7 +- .../sdl/src/video/kmsdrm/SDL_kmsdrmevents.h | 3 +- .../sdl/src/video/kmsdrm/SDL_kmsdrmmouse.c | 627 +- .../sdl/src/video/kmsdrm/SDL_kmsdrmmouse.h | 19 +- .../sdl/src/video/kmsdrm/SDL_kmsdrmopengles.c | 355 +- .../sdl/src/video/kmsdrm/SDL_kmsdrmopengles.h | 7 +- .../lib/sdl/src/video/kmsdrm/SDL_kmsdrmsym.h | 61 +- .../sdl/src/video/kmsdrm/SDL_kmsdrmvideo.c | 2107 +- .../sdl/src/video/kmsdrm/SDL_kmsdrmvideo.h | 137 +- .../sdl/src/video/kmsdrm/SDL_kmsdrmvulkan.c | 269 +- .../sdl/src/video/kmsdrm/SDL_kmsdrmvulkan.h | 8 +- .../kmsdrm_legacy/SDL_kmsdrm_legacy_dyn.c | 167 - .../kmsdrm_legacy/SDL_kmsdrm_legacy_mouse.c | 502 - .../SDL_kmsdrm_legacy_opengles.c | 152 - .../SDL_kmsdrm_legacy_opengles.h | 48 - .../kmsdrm_legacy/SDL_kmsdrm_legacy_sym.h | 99 - .../kmsdrm_legacy/SDL_kmsdrm_legacy_video.c | 934 - .../kmsdrm_legacy/SDL_kmsdrm_legacy_video.h | 132 - .../lib/sdl/src/video/nacl/SDL_naclevents.c | 2 +- .../lib/sdl/src/video/nacl/SDL_naclevents_c.h | 2 +- Engine/lib/sdl/src/video/nacl/SDL_naclglue.c | 2 +- .../lib/sdl/src/video/nacl/SDL_naclopengles.c | 6 +- .../lib/sdl/src/video/nacl/SDL_naclopengles.h | 2 +- Engine/lib/sdl/src/video/nacl/SDL_naclvideo.c | 2 +- Engine/lib/sdl/src/video/nacl/SDL_naclvideo.h | 2 +- .../lib/sdl/src/video/nacl/SDL_naclwindow.c | 5 +- .../lib/sdl/src/video/nacl/SDL_naclwindow.h | 2 +- .../src/video/offscreen/SDL_offscreenevents.c | 2 +- .../video/offscreen/SDL_offscreenevents_c.h | 2 +- .../offscreen/SDL_offscreenframebuffer.c | 10 +- .../offscreen/SDL_offscreenframebuffer_c.h | 2 +- .../src/video/offscreen/SDL_offscreenopengl.c | 8 +- .../src/video/offscreen/SDL_offscreenopengl.h | 2 +- .../src/video/offscreen/SDL_offscreenvideo.c | 2 +- .../src/video/offscreen/SDL_offscreenvideo.h | 2 +- .../src/video/offscreen/SDL_offscreenwindow.c | 2 +- .../src/video/offscreen/SDL_offscreenwindow.h | 2 +- .../src/video/os2/{my_gradd.h => SDL_gradd.h} | 6 +- Engine/lib/sdl/src/video/os2/SDL_os2dive.c | 14 +- .../lib/sdl/src/video/os2/SDL_os2messagebox.c | 72 +- .../lib/sdl/src/video/os2/SDL_os2messagebox.h | 2 +- Engine/lib/sdl/src/video/os2/SDL_os2mouse.c | 2 +- Engine/lib/sdl/src/video/os2/SDL_os2mouse.h | 2 +- Engine/lib/sdl/src/video/os2/SDL_os2output.h | 2 +- Engine/lib/sdl/src/video/os2/SDL_os2util.c | 11 +- Engine/lib/sdl/src/video/os2/SDL_os2util.h | 2 +- Engine/lib/sdl/src/video/os2/SDL_os2video.c | 69 +- Engine/lib/sdl/src/video/os2/SDL_os2video.h | 2 +- Engine/lib/sdl/src/video/os2/SDL_os2vman.c | 17 +- .../lib/sdl/src/video/pandora/SDL_pandora.c | 11 +- .../lib/sdl/src/video/pandora/SDL_pandora.h | 3 +- .../src/video/pandora/SDL_pandora_events.c | 2 +- .../src/video/pandora/SDL_pandora_events.h | 2 +- Engine/lib/sdl/src/video/psp/SDL_pspevents.c | 3 +- .../lib/sdl/src/video/psp/SDL_pspevents_c.h | 2 +- Engine/lib/sdl/src/video/psp/SDL_pspgl.c | 2 +- Engine/lib/sdl/src/video/psp/SDL_pspgl_c.h | 2 +- Engine/lib/sdl/src/video/psp/SDL_pspmouse.c | 2 +- Engine/lib/sdl/src/video/psp/SDL_pspmouse_c.h | 2 +- Engine/lib/sdl/src/video/psp/SDL_pspvideo.c | 19 +- Engine/lib/sdl/src/video/psp/SDL_pspvideo.h | 3 +- Engine/lib/sdl/src/video/qnx/gl.c | 6 +- .../sdl/src/video/raspberry/SDL_rpievents.c | 2 +- .../sdl/src/video/raspberry/SDL_rpievents_c.h | 2 +- .../sdl/src/video/raspberry/SDL_rpimouse.c | 2 +- .../sdl/src/video/raspberry/SDL_rpimouse.h | 2 +- .../sdl/src/video/raspberry/SDL_rpiopengles.c | 2 +- .../sdl/src/video/raspberry/SDL_rpiopengles.h | 2 +- .../sdl/src/video/raspberry/SDL_rpivideo.c | 8 +- .../sdl/src/video/raspberry/SDL_rpivideo.h | 3 +- .../SDL_riscosdefs.h} | 48 +- .../sdl/src/video/riscos/SDL_riscosevents.c | 178 + .../SDL_riscosevents_c.h} | 19 +- .../src/video/riscos/SDL_riscosframebuffer.c | 126 + .../SDL_riscosframebuffer_c.h} | 28 +- .../src/video/riscos/SDL_riscosmessagebox.c | 68 + .../SDL_riscosmessagebox.h} | 14 +- .../sdl/src/video/riscos/SDL_riscosmodes.c | 315 + .../sdl/src/video/riscos/SDL_riscosmodes.h | 33 + .../sdl/src/video/riscos/SDL_riscosvideo.c | 124 + .../SDL_riscosvideo.h} | 26 +- .../sdl/src/video/riscos/SDL_riscoswindow.c | 78 + .../sdl/src/video/riscos/SDL_riscoswindow.h | 42 + .../sdl/src/video/riscos/scancodes_riscos.h | 158 + Engine/lib/sdl/src/video/sdlgenblit.pl | 125 +- .../src/video/uikit/SDL_uikitappdelegate.h | 2 +- .../src/video/uikit/SDL_uikitappdelegate.m | 2 +- .../sdl/src/video/uikit/SDL_uikitclipboard.h | 2 +- .../sdl/src/video/uikit/SDL_uikitclipboard.m | 2 +- .../lib/sdl/src/video/uikit/SDL_uikitevents.h | 3 +- .../lib/sdl/src/video/uikit/SDL_uikitevents.m | 107 +- .../sdl/src/video/uikit/SDL_uikitmessagebox.h | 2 +- .../sdl/src/video/uikit/SDL_uikitmessagebox.m | 4 +- .../sdl/src/video/uikit/SDL_uikitmetalview.h | 3 +- .../sdl/src/video/uikit/SDL_uikitmetalview.m | 10 +- .../lib/sdl/src/video/uikit/SDL_uikitmodes.h | 2 +- .../lib/sdl/src/video/uikit/SDL_uikitmodes.m | 2 +- .../sdl/src/video/uikit/SDL_uikitopengles.h | 2 +- .../sdl/src/video/uikit/SDL_uikitopengles.m | 6 +- .../sdl/src/video/uikit/SDL_uikitopenglview.h | 2 +- .../sdl/src/video/uikit/SDL_uikitopenglview.m | 2 +- .../lib/sdl/src/video/uikit/SDL_uikitvideo.h | 2 +- .../lib/sdl/src/video/uikit/SDL_uikitvideo.m | 16 +- .../lib/sdl/src/video/uikit/SDL_uikitview.h | 2 +- .../lib/sdl/src/video/uikit/SDL_uikitview.m | 4 +- .../src/video/uikit/SDL_uikitviewcontroller.h | 2 +- .../src/video/uikit/SDL_uikitviewcontroller.m | 15 +- .../lib/sdl/src/video/uikit/SDL_uikitvulkan.h | 2 +- .../lib/sdl/src/video/uikit/SDL_uikitvulkan.m | 2 +- .../lib/sdl/src/video/uikit/SDL_uikitwindow.h | 4 +- .../lib/sdl/src/video/uikit/SDL_uikitwindow.m | 36 +- Engine/lib/sdl/src/video/uikit/keyinfotable.h | 2 +- .../sdl/src/video/vita/SDL_vitaframebuffer.c | 116 + .../sdl/src/video/vita/SDL_vitaframebuffer.h | 27 + Engine/lib/sdl/src/video/vita/SDL_vitagl.c | 235 + Engine/lib/sdl/src/video/vita/SDL_vitagl_c.h | 57 + .../lib/sdl/src/video/vita/SDL_vitagl_pvr.c | 103 + .../lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h | 35 + .../lib/sdl/src/video/vita/SDL_vitakeyboard.c | 203 + .../lib/sdl/src/video/vita/SDL_vitakeyboard.h | 33 + .../sdl/src/video/vita/SDL_vitamessagebox.c | 150 + .../sdl/src/video/vita/SDL_vitamessagebox.h | 33 + Engine/lib/sdl/src/video/vita/SDL_vitamouse.c | 94 + .../lib/sdl/src/video/vita/SDL_vitamouse_c.h | 33 + Engine/lib/sdl/src/video/vita/SDL_vitatouch.c | 194 + Engine/lib/sdl/src/video/vita/SDL_vitatouch.h | 35 + Engine/lib/sdl/src/video/vita/SDL_vitavideo.c | 601 + Engine/lib/sdl/src/video/vita/SDL_vitavideo.h | 115 + .../src/video/vivante/SDL_vivanteopengles.c | 2 +- .../src/video/vivante/SDL_vivanteopengles.h | 2 +- .../src/video/vivante/SDL_vivanteplatform.c | 2 +- .../src/video/vivante/SDL_vivanteplatform.h | 2 +- .../sdl/src/video/vivante/SDL_vivantevideo.c | 2 +- .../sdl/src/video/vivante/SDL_vivantevideo.h | 2 +- .../sdl/src/video/vivante/SDL_vivantevulkan.c | 2 +- .../sdl/src/video/vivante/SDL_vivantevulkan.h | 2 +- .../src/video/wayland/SDL_waylandclipboard.c | 80 +- .../src/video/wayland/SDL_waylandclipboard.h | 2 +- .../video/wayland/SDL_waylanddatamanager.c | 25 +- .../video/wayland/SDL_waylanddatamanager.h | 2 +- .../sdl/src/video/wayland/SDL_waylanddyn.c | 8 +- .../sdl/src/video/wayland/SDL_waylanddyn.h | 70 +- .../sdl/src/video/wayland/SDL_waylandevents.c | 938 +- .../src/video/wayland/SDL_waylandevents_c.h | 70 +- .../src/video/wayland/SDL_waylandkeyboard.c | 154 + .../src/video/wayland/SDL_waylandkeyboard.h | 42 + .../src/video/wayland/SDL_waylandmessagebox.c | 195 + .../src/video/wayland/SDL_waylandmessagebox.h | 33 + .../sdl/src/video/wayland/SDL_waylandmouse.c | 274 +- .../sdl/src/video/wayland/SDL_waylandmouse.h | 4 +- .../src/video/wayland/SDL_waylandopengles.c | 132 +- .../src/video/wayland/SDL_waylandopengles.h | 6 +- .../sdl/src/video/wayland/SDL_waylandsym.h | 93 +- .../sdl/src/video/wayland/SDL_waylandtouch.c | 14 +- .../sdl/src/video/wayland/SDL_waylandtouch.h | 3 +- .../sdl/src/video/wayland/SDL_waylandvideo.c | 454 +- .../sdl/src/video/wayland/SDL_waylandvideo.h | 53 +- .../sdl/src/video/wayland/SDL_waylandvulkan.c | 2 +- .../sdl/src/video/wayland/SDL_waylandvulkan.h | 2 +- .../sdl/src/video/wayland/SDL_waylandwindow.c | 1521 +- .../sdl/src/video/wayland/SDL_waylandwindow.h | 64 +- Engine/lib/sdl/src/video/windows/SDL_msctf.h | 2 +- Engine/lib/sdl/src/video/windows/SDL_vkeys.h | 2 +- .../src/video/windows/SDL_windowsclipboard.c | 2 +- .../src/video/windows/SDL_windowsclipboard.h | 2 +- .../sdl/src/video/windows/SDL_windowsevents.c | 737 +- .../sdl/src/video/windows/SDL_windowsevents.h | 5 +- .../video/windows/SDL_windowsframebuffer.c | 2 +- .../video/windows/SDL_windowsframebuffer.h | 2 +- .../src/video/windows/SDL_windowskeyboard.c | 311 +- .../src/video/windows/SDL_windowskeyboard.h | 4 +- .../src/video/windows/SDL_windowsmessagebox.c | 20 +- .../src/video/windows/SDL_windowsmessagebox.h | 2 +- .../sdl/src/video/windows/SDL_windowsmodes.c | 85 +- .../sdl/src/video/windows/SDL_windowsmodes.h | 2 +- .../sdl/src/video/windows/SDL_windowsmouse.c | 88 +- .../sdl/src/video/windows/SDL_windowsmouse.h | 4 +- .../sdl/src/video/windows/SDL_windowsopengl.c | 2 +- .../sdl/src/video/windows/SDL_windowsopengl.h | 2 +- .../src/video/windows/SDL_windowsopengles.c | 5 +- .../src/video/windows/SDL_windowsopengles.h | 2 +- .../sdl/src/video/windows/SDL_windowsshape.c | 2 +- .../sdl/src/video/windows/SDL_windowsshape.h | 2 +- .../src/video/windows/SDL_windowstaskdialog.h | 2 +- .../sdl/src/video/windows/SDL_windowsvideo.c | 58 +- .../sdl/src/video/windows/SDL_windowsvideo.h | 15 +- .../sdl/src/video/windows/SDL_windowsvulkan.c | 2 +- .../sdl/src/video/windows/SDL_windowsvulkan.h | 2 +- .../sdl/src/video/windows/SDL_windowswindow.c | 360 +- .../sdl/src/video/windows/SDL_windowswindow.h | 14 +- Engine/lib/sdl/src/video/windows/wmmsg.h | 4 +- .../sdl/src/video/winrt/SDL_winrtevents.cpp | 2 +- .../sdl/src/video/winrt/SDL_winrtevents_c.h | 4 +- .../sdl/src/video/winrt/SDL_winrtgamebar.cpp | 4 +- .../src/video/winrt/SDL_winrtgamebar_cpp.h | 2 +- .../sdl/src/video/winrt/SDL_winrtkeyboard.cpp | 2 +- .../src/video/winrt/SDL_winrtmessagebox.cpp | 2 +- .../sdl/src/video/winrt/SDL_winrtmessagebox.h | 2 +- .../sdl/src/video/winrt/SDL_winrtmouse.cpp | 2 +- .../sdl/src/video/winrt/SDL_winrtmouse_c.h | 2 +- .../sdl/src/video/winrt/SDL_winrtopengles.cpp | 2 +- .../sdl/src/video/winrt/SDL_winrtopengles.h | 2 +- .../src/video/winrt/SDL_winrtpointerinput.cpp | 63 +- .../sdl/src/video/winrt/SDL_winrtvideo.cpp | 102 +- .../sdl/src/video/winrt/SDL_winrtvideo_cpp.h | 2 +- .../lib/sdl/src/video/x11/SDL_x11clipboard.c | 82 +- .../lib/sdl/src/video/x11/SDL_x11clipboard.h | 16 +- Engine/lib/sdl/src/video/x11/SDL_x11dyn.c | 6 +- Engine/lib/sdl/src/video/x11/SDL_x11dyn.h | 6 +- Engine/lib/sdl/src/video/x11/SDL_x11events.c | 524 +- Engine/lib/sdl/src/video/x11/SDL_x11events.h | 4 +- .../sdl/src/video/x11/SDL_x11framebuffer.c | 4 +- .../sdl/src/video/x11/SDL_x11framebuffer.h | 2 +- .../lib/sdl/src/video/x11/SDL_x11keyboard.c | 12 +- .../lib/sdl/src/video/x11/SDL_x11keyboard.h | 2 +- .../lib/sdl/src/video/x11/SDL_x11messagebox.c | 50 +- .../lib/sdl/src/video/x11/SDL_x11messagebox.h | 2 +- Engine/lib/sdl/src/video/x11/SDL_x11modes.c | 93 +- Engine/lib/sdl/src/video/x11/SDL_x11modes.h | 2 +- Engine/lib/sdl/src/video/x11/SDL_x11mouse.c | 31 +- Engine/lib/sdl/src/video/x11/SDL_x11mouse.h | 2 +- Engine/lib/sdl/src/video/x11/SDL_x11opengl.c | 41 +- Engine/lib/sdl/src/video/x11/SDL_x11opengl.h | 3 +- .../lib/sdl/src/video/x11/SDL_x11opengles.c | 2 +- .../lib/sdl/src/video/x11/SDL_x11opengles.h | 2 +- Engine/lib/sdl/src/video/x11/SDL_x11shape.c | 10 +- Engine/lib/sdl/src/video/x11/SDL_x11shape.h | 2 +- Engine/lib/sdl/src/video/x11/SDL_x11sym.h | 30 +- Engine/lib/sdl/src/video/x11/SDL_x11touch.c | 2 +- Engine/lib/sdl/src/video/x11/SDL_x11touch.h | 2 +- Engine/lib/sdl/src/video/x11/SDL_x11video.c | 56 +- Engine/lib/sdl/src/video/x11/SDL_x11video.h | 9 +- Engine/lib/sdl/src/video/x11/SDL_x11vulkan.c | 2 +- Engine/lib/sdl/src/video/x11/SDL_x11vulkan.h | 2 +- Engine/lib/sdl/src/video/x11/SDL_x11window.c | 316 +- Engine/lib/sdl/src/video/x11/SDL_x11window.h | 17 +- Engine/lib/sdl/src/video/x11/SDL_x11xfixes.c | 206 + Engine/lib/sdl/src/video/x11/SDL_x11xfixes.h | 41 + Engine/lib/sdl/src/video/x11/SDL_x11xinput2.c | 46 +- Engine/lib/sdl/src/video/x11/SDL_x11xinput2.h | 4 +- Engine/lib/sdl/src/video/x11/edid-parse.c | 10 +- Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb.c | 2 +- .../sdl/src/video/yuv2rgb/yuv_rgb_sse_func.h | 16 +- Engine/lib/sdl/test/CMakeLists.txt | 217 +- Engine/lib/sdl/test/Makefile.in | 65 +- Engine/lib/sdl/test/Makefile.os2 | 54 +- Engine/lib/sdl/test/README | 2 + Engine/lib/sdl/test/acinclude.m4 | 48 +- Engine/lib/sdl/test/autogen.sh | 17 +- Engine/lib/sdl/test/checkkeys.c | 16 +- Engine/lib/sdl/test/checkkeysthreads.c | 285 + Engine/lib/sdl/test/configure | 282 +- Engine/lib/sdl/test/configure.ac | 57 +- Engine/lib/sdl/test/controllermap.c | 56 +- Engine/lib/sdl/test/loopwave.c | 2 +- Engine/lib/sdl/test/loopwavequeue.c | 2 +- Engine/lib/sdl/test/testatomic.c | 28 +- Engine/lib/sdl/test/testaudiocapture.c | 2 +- Engine/lib/sdl/test/testaudiohotplug.c | 2 +- Engine/lib/sdl/test/testaudioinfo.c | 2 +- Engine/lib/sdl/test/testautomation.c | 2 +- Engine/lib/sdl/test/testautomation_audio.c | 20 +- .../lib/sdl/test/testautomation_clipboard.c | 15 +- Engine/lib/sdl/test/testautomation_events.c | 12 +- Engine/lib/sdl/test/testautomation_hints.c | 106 +- Engine/lib/sdl/test/testautomation_keyboard.c | 62 +- Engine/lib/sdl/test/testautomation_main.c | 8 +- Engine/lib/sdl/test/testautomation_mouse.c | 23 +- Engine/lib/sdl/test/testautomation_pixels.c | 28 +- Engine/lib/sdl/test/testautomation_platform.c | 73 +- Engine/lib/sdl/test/testautomation_rect.c | 60 +- Engine/lib/sdl/test/testautomation_render.c | 137 +- Engine/lib/sdl/test/testautomation_rwops.c | 46 +- Engine/lib/sdl/test/testautomation_sdltest.c | 9 +- Engine/lib/sdl/test/testautomation_stdlib.c | 32 + Engine/lib/sdl/test/testautomation_video.c | 228 +- Engine/lib/sdl/test/testbounds.c | 2 +- Engine/lib/sdl/test/testcustomcursor.c | 4 +- Engine/lib/sdl/test/testdisplayinfo.c | 2 +- Engine/lib/sdl/test/testdraw2.c | 35 +- Engine/lib/sdl/test/testdrawchessboard.c | 6 +- Engine/lib/sdl/test/testdropfile.c | 2 +- Engine/lib/sdl/test/testerror.c | 2 +- Engine/lib/sdl/test/testevdev.c | 2 +- Engine/lib/sdl/test/testfile.c | 2 +- Engine/lib/sdl/test/testfilesystem.c | 2 +- Engine/lib/sdl/test/testgamecontroller.c | 213 +- Engine/lib/sdl/test/testgeometry.c | 303 + Engine/lib/sdl/test/testgesture.c | 9 +- Engine/lib/sdl/test/testgl2.c | 6 +- Engine/lib/sdl/test/testgles.c | 2 +- Engine/lib/sdl/test/testgles2.c | 20 +- Engine/lib/sdl/test/testgles2_sdf.c | 805 + .../lib/sdl/test/testgles2_sdf_img_normal.bmp | Bin 0 -> 68122 bytes Engine/lib/sdl/test/testgles2_sdf_img_sdf.bmp | Bin 0 -> 72202 bytes Engine/lib/sdl/test/testhaptic.c | 24 +- Engine/lib/sdl/test/testhotplug.c | 2 +- Engine/lib/sdl/test/testiconv.c | 12 +- Engine/lib/sdl/test/testime.c | 8 +- Engine/lib/sdl/test/testintersections.c | 2 +- Engine/lib/sdl/test/testjoystick.c | 39 +- Engine/lib/sdl/test/testkeys.c | 2 +- Engine/lib/sdl/test/testloadso.c | 4 +- Engine/lib/sdl/test/testlocale.c | 2 +- Engine/lib/sdl/test/testlock.c | 2 +- Engine/lib/sdl/test/testmessage.c | 18 +- Engine/lib/sdl/test/testmouse.c | 197 + Engine/lib/sdl/test/testmultiaudio.c | 20 +- Engine/lib/sdl/test/testnative.c | 4 +- Engine/lib/sdl/test/testnative.h | 2 +- Engine/lib/sdl/test/testnativeos2.c | 46 +- Engine/lib/sdl/test/testnativew32.c | 2 +- Engine/lib/sdl/test/testnativex11.c | 2 +- Engine/lib/sdl/test/testoffscreen.c | 2 +- Engine/lib/sdl/test/testoverlay2.c | 3 +- Engine/lib/sdl/test/testplatform.c | 43 +- Engine/lib/sdl/test/testpower.c | 6 +- Engine/lib/sdl/test/testqsort.c | 6 +- Engine/lib/sdl/test/testrelative.c | 8 +- Engine/lib/sdl/test/testrendercopyex.c | 2 +- Engine/lib/sdl/test/testrendertarget.c | 4 +- Engine/lib/sdl/test/testresample.c | 2 +- Engine/lib/sdl/test/testrumble.c | 10 +- Engine/lib/sdl/test/testscale.c | 4 +- Engine/lib/sdl/test/testsem.c | 248 +- Engine/lib/sdl/test/testsensor.c | 8 +- Engine/lib/sdl/test/testshader.c | 2 +- Engine/lib/sdl/test/testshape.c | 2 +- Engine/lib/sdl/test/testsprite2.c | 221 +- Engine/lib/sdl/test/testspriteminimal.c | 10 +- Engine/lib/sdl/test/teststreaming.c | 6 +- Engine/lib/sdl/test/testsurround.c | 200 + Engine/lib/sdl/test/testthread.c | 2 +- Engine/lib/sdl/test/testtimer.c | 24 +- Engine/lib/sdl/test/testurl.c | 2 +- Engine/lib/sdl/test/testver.c | 10 +- Engine/lib/sdl/test/testviewport.c | 8 +- Engine/lib/sdl/test/testvulkan.c | 848 +- Engine/lib/sdl/test/testwm2.c | 144 +- Engine/lib/sdl/test/testyuv.c | 2 +- Engine/lib/sdl/test/testyuv_cvt.c | 8 +- Engine/lib/sdl/test/testyuv_cvt.h | 2 +- Engine/lib/sdl/test/torturethread.c | 2 +- .../lib/sdl/test/unifont-13.0.06-license.txt | 90 + Engine/lib/sdl/test/unifont-13.0.06.hex | 57086 ++++++++++++++++ Engine/lib/sdl/visualtest/Makefile.in | 7 + Engine/lib/sdl/visualtest/README.txt | 2 +- Engine/lib/sdl/visualtest/acinclude.m4 | 84 +- Engine/lib/sdl/visualtest/autogen.sh | 17 +- Engine/lib/sdl/visualtest/compile | 1 - Engine/lib/sdl/visualtest/config.h | 23 - Engine/lib/sdl/visualtest/config.h.in | 22 - Engine/lib/sdl/visualtest/configure | 1095 +- Engine/lib/sdl/visualtest/configure.ac | 41 + Engine/lib/sdl/visualtest/configure.in | 166 - Engine/lib/sdl/visualtest/depcomp | 1 - .../SDL_visualtest_action_configparser.h | 4 +- .../SDL_visualtest_exhaustive_variator.h | 2 +- .../include/SDL_visualtest_parsehelper.h | 2 +- .../include/SDL_visualtest_process.h | 6 +- .../include/SDL_visualtest_random_variator.h | 2 +- .../include/SDL_visualtest_rwhelper.h | 2 +- .../include/SDL_visualtest_screenshot.h | 2 +- .../include/SDL_visualtest_sut_configparser.h | 2 +- .../include/SDL_visualtest_variator_common.h | 2 +- .../include/SDL_visualtest_variators.h | 2 +- Engine/lib/sdl/visualtest/install-sh | 1 - Engine/lib/sdl/visualtest/missing | 1 - .../sdl/visualtest/src/action_configparser.c | 19 +- .../sdl/visualtest/src/harness_argparser.c | 10 +- .../sdl/visualtest/src/linux/linux_process.c | 25 +- Engine/lib/sdl/visualtest/src/mischelper.c | 4 +- Engine/lib/sdl/visualtest/src/parsehelper.c | 8 +- Engine/lib/sdl/visualtest/src/rwhelper.c | 4 +- Engine/lib/sdl/visualtest/src/screenshot.c | 8 +- .../lib/sdl/visualtest/src/sut_configparser.c | 4 +- Engine/lib/sdl/visualtest/src/testharness.c | 19 +- .../lib/sdl/visualtest/src/variator_common.c | 6 +- .../sdl/visualtest/src/variator_exhaustive.c | 5 +- .../lib/sdl/visualtest/src/variator_random.c | 8 +- Engine/lib/sdl/visualtest/src/variators.c | 6 +- .../visualtest/src/windows/windows_process.c | 13 +- .../src/windows/windows_screenshot.c | 12 +- Engine/lib/sdl/visualtest/stamp-h1 | 1 - Engine/lib/sdl/visualtest/unittest/testquit.c | 2 +- .../idle-inhibit-unstable-v1.xml | 83 + ...keyboard-shortcuts-inhibit-unstable-v1.xml | 143 + ...org-kde-kwin-server-decoration-manager.xml | 94 - .../text-input-unstable-v3.xml | 452 + Engine/lib/sdl/wayland-protocols/wayland.xml | 212 +- .../wayland-protocols/xdg-activation-v1.xml | 186 + .../xdg-shell-unstable-v6.xml | 1044 - .../lib/sdl/wayland-protocols/xdg-shell.xml | 198 +- 1225 files changed, 148950 insertions(+), 51674 deletions(-) rename Engine/lib/sdl/{.hgignore => .gitignore} (80%) delete mode 100644 Engine/lib/sdl/.hgtags rename Engine/lib/sdl/{COPYING.txt => LICENSE.txt} (90%) delete mode 100644 Engine/lib/sdl/Makefile.psp delete mode 100644 Engine/lib/sdl/Makefile.wiz rename Engine/lib/sdl/{README.txt => README.md} (71%) delete mode 100644 Engine/lib/sdl/VisualC-WinRT/SDL2-WinRT.nuspec delete mode 100644 Engine/lib/sdl/VisualC-WinRT/SDL2-WinRT.targets delete mode 100644 Engine/lib/sdl/VisualC-WinRT/SDL2main-WinRT-NonXAML.nuspec delete mode 100644 Engine/lib/sdl/VisualC-WinRT/SDL2main-WinRT-NonXAML.targets delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/loopwave/Assets/Logo.png delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/loopwave/Assets/SmallLogo.png delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/loopwave/Assets/SplashScreen.png delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/loopwave/Assets/StoreLogo.png delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/loopwave/Package.appxmanifest delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/loopwave/loopwave_VS2012_TemporaryKey.pfx delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/testthread/Assets/Logo.png delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/testthread/Assets/SmallLogo.png delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/testthread/Assets/SplashScreen.png delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/testthread/Assets/StoreLogo.png delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/testthread/Package.appxmanifest delete mode 100644 Engine/lib/sdl/VisualC-WinRT/tests/testthread/testthread_VS2012_TemporaryKey.pfx delete mode 100644 Engine/lib/sdl/VisualC.html delete mode 100644 Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/Default-568h@2x.png delete mode 100644 Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/Default.png delete mode 100644 Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/Icon.png delete mode 100644 Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/Info.plist delete mode 100644 Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns delete mode 100644 Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist delete mode 100644 Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/project.pbxproj delete mode 100644 Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/main.c delete mode 100644 Engine/lib/sdl/Xcode/SDL/hidapi/Info.plist create mode 100644 Engine/lib/sdl/acinclude/pkg.m4 delete mode 100644 Engine/lib/sdl/acinclude/pkg_config.m4 rename Engine/lib/sdl/build-scripts/{g++-fat.sh => clang++-fat.sh} (52%) mode change 100755 => 100644 rename Engine/lib/sdl/build-scripts/{gcc-fat.sh => clang-fat.sh} (53%) mode change 100755 => 100644 create mode 100644 Engine/lib/sdl/build-scripts/codechecker-buildbot.sh delete mode 100644 Engine/lib/sdl/build-scripts/config.sub.patch create mode 100644 Engine/lib/sdl/build-scripts/fnsince.pl create mode 100644 Engine/lib/sdl/build-scripts/git-pre-push-hook.pl delete mode 100755 Engine/lib/sdl/build-scripts/iosbuild.sh create mode 100644 Engine/lib/sdl/build-scripts/wikiheaders.pl delete mode 100644 Engine/lib/sdl/debian/changelog delete mode 100644 Engine/lib/sdl/debian/compat delete mode 100644 Engine/lib/sdl/debian/control delete mode 100644 Engine/lib/sdl/debian/copyright delete mode 100644 Engine/lib/sdl/debian/docs delete mode 100644 Engine/lib/sdl/debian/libsdl2-dev.install delete mode 100644 Engine/lib/sdl/debian/libsdl2-dev.manpages delete mode 100644 Engine/lib/sdl/debian/libsdl2.install delete mode 100755 Engine/lib/sdl/debian/rules delete mode 100644 Engine/lib/sdl/debian/sdl2-config.1 delete mode 100644 Engine/lib/sdl/debian/source/format delete mode 100644 Engine/lib/sdl/debian/watch create mode 100644 Engine/lib/sdl/docs/README-git.md create mode 100644 Engine/lib/sdl/docs/README-kmsbsd.md create mode 100644 Engine/lib/sdl/docs/README-macos.md delete mode 100644 Engine/lib/sdl/docs/README-macosx.md create mode 100644 Engine/lib/sdl/docs/README-riscos.md create mode 100644 Engine/lib/sdl/docs/README-visualc.md create mode 100644 Engine/lib/sdl/docs/README-vita.md create mode 100644 Engine/lib/sdl/include/SDL_config_emscripten.h delete mode 100644 Engine/lib/sdl/include/SDL_config_psp.h delete mode 100644 Engine/lib/sdl/include/SDL_config_wiz.h create mode 100644 Engine/lib/sdl/include/SDL_hidapi.h create mode 100644 Engine/lib/sdl/include/SDL_revision.h.cmake create mode 100644 Engine/lib/sdl/src/audio/aaudio/SDL_aaudio.c create mode 100644 Engine/lib/sdl/src/audio/aaudio/SDL_aaudio.h create mode 100644 Engine/lib/sdl/src/audio/aaudio/SDL_aaudiofuncs.h create mode 100644 Engine/lib/sdl/src/audio/pipewire/SDL_pipewire.c create mode 100644 Engine/lib/sdl/src/audio/pipewire/SDL_pipewire.h create mode 100644 Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.c create mode 100644 Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.h create mode 100644 Engine/lib/sdl/src/core/openbsd/SDL_wscons.h create mode 100644 Engine/lib/sdl/src/core/openbsd/SDL_wscons_kbd.c create mode 100644 Engine/lib/sdl/src/core/openbsd/SDL_wscons_mouse.c create mode 100644 Engine/lib/sdl/src/core/os2/iconv2.lbc rename Engine/lib/sdl/src/{video/x11 => events}/imKStoUCS.c (99%) rename Engine/lib/sdl/src/{video/x11 => events}/imKStoUCS.h (96%) create mode 100644 Engine/lib/sdl/src/filesystem/psp/SDL_sysfilesystem.c create mode 100644 Engine/lib/sdl/src/filesystem/riscos/SDL_sysfilesystem.c create mode 100644 Engine/lib/sdl/src/filesystem/vita/SDL_sysfilesystem.c create mode 100644 Engine/lib/sdl/src/hidapi/SDL_hidapi_c.h delete mode 100644 Engine/lib/sdl/src/hidapi/linux/hid.cpp create mode 100644 Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_luna.c create mode 100644 Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_stadia.c create mode 100644 Engine/lib/sdl/src/joystick/os2/SDL_os2joystick.c create mode 100644 Engine/lib/sdl/src/joystick/vita/SDL_sysjoystick.c delete mode 100644 Engine/lib/sdl/src/joystick/windows/SDL_mmjoystick.c create mode 100644 Engine/lib/sdl/src/misc/emscripten/SDL_sysurl.c create mode 100644 Engine/lib/sdl/src/misc/vita/SDL_sysurl.c create mode 100644 Engine/lib/sdl/src/power/vita/SDL_syspower.c create mode 100644 Engine/lib/sdl/src/render/software/SDL_triangle.c create mode 100644 Engine/lib/sdl/src/render/software/SDL_triangle.h create mode 100644 Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm.c create mode 100644 Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.c create mode 100644 Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.h create mode 100644 Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_shaders.h create mode 100644 Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.c create mode 100644 Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.h create mode 100644 Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_types.h create mode 100644 Engine/lib/sdl/src/render/vitagxm/shader_src/clear_f.cg create mode 100644 Engine/lib/sdl/src/render/vitagxm/shader_src/clear_v.cg create mode 100644 Engine/lib/sdl/src/render/vitagxm/shader_src/color_f.cg create mode 100644 Engine/lib/sdl/src/render/vitagxm/shader_src/color_v.cg create mode 100644 Engine/lib/sdl/src/render/vitagxm/shader_src/texture_f.cg create mode 100644 Engine/lib/sdl/src/render/vitagxm/shader_src/texture_v.cg create mode 100644 Engine/lib/sdl/src/sensor/vita/SDL_vitasensor.c create mode 100644 Engine/lib/sdl/src/sensor/vita/SDL_vitasensor.h create mode 100644 Engine/lib/sdl/src/thread/generic/SDL_syscond_c.h create mode 100644 Engine/lib/sdl/src/thread/vita/SDL_syscond.c create mode 100644 Engine/lib/sdl/src/thread/vita/SDL_sysmutex.c create mode 100644 Engine/lib/sdl/src/thread/vita/SDL_sysmutex_c.h create mode 100644 Engine/lib/sdl/src/thread/vita/SDL_syssem.c create mode 100644 Engine/lib/sdl/src/thread/vita/SDL_systhread.c create mode 100644 Engine/lib/sdl/src/thread/vita/SDL_systhread_c.h create mode 100644 Engine/lib/sdl/src/thread/windows/SDL_syscond_cv.c create mode 100644 Engine/lib/sdl/src/thread/windows/SDL_sysmutex_c.h create mode 100644 Engine/lib/sdl/src/timer/vita/SDL_systimer.c create mode 100644 Engine/lib/sdl/src/video/SDL_rect_impl.h delete mode 100644 Engine/lib/sdl/src/video/cocoa/SDL_cocoamousetap.m create mode 100644 Engine/lib/sdl/src/video/haiku/SDL_BApp.h delete mode 100644 Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_dyn.c delete mode 100644 Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_mouse.c delete mode 100644 Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_opengles.c delete mode 100644 Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_opengles.h delete mode 100644 Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_sym.h delete mode 100644 Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_video.c delete mode 100644 Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_video.h rename Engine/lib/sdl/src/video/os2/{my_gradd.h => SDL_gradd.h} (99%) rename Engine/lib/sdl/src/video/{kmsdrm_legacy/SDL_kmsdrm_legacy_dyn.h => riscos/SDL_riscosdefs.h} (55%) create mode 100644 Engine/lib/sdl/src/video/riscos/SDL_riscosevents.c rename Engine/lib/sdl/src/video/{cocoa/SDL_cocoamousetap.h => riscos/SDL_riscosevents_c.h} (70%) create mode 100644 Engine/lib/sdl/src/video/riscos/SDL_riscosframebuffer.c rename Engine/lib/sdl/src/video/{kmsdrm_legacy/SDL_kmsdrm_legacy_mouse.h => riscos/SDL_riscosframebuffer_c.h} (65%) create mode 100644 Engine/lib/sdl/src/video/riscos/SDL_riscosmessagebox.c rename Engine/lib/sdl/src/video/{kmsdrm_legacy/SDL_kmsdrm_legacy_events.h => riscos/SDL_riscosmessagebox.h} (76%) create mode 100644 Engine/lib/sdl/src/video/riscos/SDL_riscosmodes.c create mode 100644 Engine/lib/sdl/src/video/riscos/SDL_riscosmodes.h create mode 100644 Engine/lib/sdl/src/video/riscos/SDL_riscosvideo.c rename Engine/lib/sdl/src/video/{kmsdrm_legacy/SDL_kmsdrm_legacy_events.c => riscos/SDL_riscosvideo.h} (71%) create mode 100644 Engine/lib/sdl/src/video/riscos/SDL_riscoswindow.c create mode 100644 Engine/lib/sdl/src/video/riscos/SDL_riscoswindow.h create mode 100644 Engine/lib/sdl/src/video/riscos/scancodes_riscos.h create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.c create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.h create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitagl.c create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitagl_c.h create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr.c create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitakeyboard.c create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitakeyboard.h create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitamessagebox.c create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitamessagebox.h create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitamouse.c create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitamouse_c.h create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitatouch.c create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitatouch.h create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitavideo.c create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitavideo.h create mode 100644 Engine/lib/sdl/src/video/wayland/SDL_waylandkeyboard.c create mode 100644 Engine/lib/sdl/src/video/wayland/SDL_waylandkeyboard.h create mode 100644 Engine/lib/sdl/src/video/wayland/SDL_waylandmessagebox.c create mode 100644 Engine/lib/sdl/src/video/wayland/SDL_waylandmessagebox.h create mode 100644 Engine/lib/sdl/src/video/x11/SDL_x11xfixes.c create mode 100644 Engine/lib/sdl/src/video/x11/SDL_x11xfixes.h create mode 100644 Engine/lib/sdl/test/checkkeysthreads.c create mode 100644 Engine/lib/sdl/test/testgeometry.c create mode 100644 Engine/lib/sdl/test/testgles2_sdf.c create mode 100644 Engine/lib/sdl/test/testgles2_sdf_img_normal.bmp create mode 100644 Engine/lib/sdl/test/testgles2_sdf_img_sdf.bmp create mode 100644 Engine/lib/sdl/test/testmouse.c create mode 100644 Engine/lib/sdl/test/testsurround.c create mode 100644 Engine/lib/sdl/test/unifont-13.0.06-license.txt create mode 100644 Engine/lib/sdl/test/unifont-13.0.06.hex delete mode 100644 Engine/lib/sdl/visualtest/compile delete mode 100644 Engine/lib/sdl/visualtest/config.h delete mode 100644 Engine/lib/sdl/visualtest/config.h.in create mode 100644 Engine/lib/sdl/visualtest/configure.ac delete mode 100644 Engine/lib/sdl/visualtest/configure.in delete mode 100644 Engine/lib/sdl/visualtest/depcomp delete mode 100644 Engine/lib/sdl/visualtest/install-sh delete mode 100644 Engine/lib/sdl/visualtest/missing delete mode 100644 Engine/lib/sdl/visualtest/stamp-h1 create mode 100644 Engine/lib/sdl/wayland-protocols/idle-inhibit-unstable-v1.xml create mode 100644 Engine/lib/sdl/wayland-protocols/keyboard-shortcuts-inhibit-unstable-v1.xml delete mode 100644 Engine/lib/sdl/wayland-protocols/org-kde-kwin-server-decoration-manager.xml create mode 100644 Engine/lib/sdl/wayland-protocols/text-input-unstable-v3.xml create mode 100644 Engine/lib/sdl/wayland-protocols/xdg-activation-v1.xml delete mode 100644 Engine/lib/sdl/wayland-protocols/xdg-shell-unstable-v6.xml diff --git a/Engine/lib/sdl/.hgignore b/Engine/lib/sdl/.gitignore similarity index 80% rename from Engine/lib/sdl/.hgignore rename to Engine/lib/sdl/.gitignore index 3e3f68fd6..fd27cb76a 100644 --- a/Engine/lib/sdl/.hgignore +++ b/Engine/lib/sdl/.gitignore @@ -1,4 +1,3 @@ -syntax:glob aclocal.m4 autom4te* config.cache @@ -9,11 +8,35 @@ Makefile Makefile.rules sdl2-config sdl2-config.cmake +sdl2-config-version.cmake sdl2.pc SDL2.spec build gen Build +buildbot + +*.so +*.so.* +*.dll +*.exe +*.o +*.obj +*.lib +*.a +*.la +*.dSYM +*,e1f +*,ff8 +*.lnk +*.err +*.exp +*.map +*.orig +*~ +*.swp +*.tmp +*.rej # for CMake CMakeFiles/ @@ -21,10 +44,6 @@ CMakeCache.txt cmake_install.cmake cmake_uninstall.cmake SDL2ConfigVersion.cmake -*.a -*.la -*.so -*.so.* .ninja_* *.ninja @@ -33,12 +52,6 @@ SDL2ConfigVersion.cmake cmake-build-* # for Xcode -*.orig -*.swp -*.tmp -*.rej -*~ -*.o *.mode1* *.perspective* *.pbxuser @@ -48,24 +61,31 @@ xcuserdata *.xcworkspace # for Visual C++ +.vs Debug Release *.user *.ncb *.suo *.sdf +VisualC/tests/controllermap/axis.bmp +VisualC/tests/controllermap/button.bmp +VisualC/tests/controllermap/controllermap.bmp +VisualC/tests/controllermap/controllermap_back.bmp VisualC/tests/loopwave/sample.wav VisualC/tests/testautomation/CompareSurfaces0001_Reference.bmp VisualC/tests/testautomation/CompareSurfaces0001_TestOutput.bmp VisualC/tests/testgamecontroller/axis.bmp VisualC/tests/testgamecontroller/button.bmp VisualC/tests/testgamecontroller/controllermap.bmp +VisualC/tests/testgamecontroller/controllermap_back.bmp VisualC/tests/testoverlay2/moose.dat VisualC/tests/testrendertarget/icon.bmp VisualC/tests/testrendertarget/sample.bmp VisualC/tests/testscale/icon.bmp VisualC/tests/testscale/sample.bmp VisualC/tests/testsprite2/icon.bmp +VisualC/tests/testyuv/testyuv.bmp VisualC/visualtest/icon.bmp VisualC/visualtest/testquit.actions VisualC/visualtest/testquit.config @@ -79,14 +99,8 @@ VisualC/visualtest/testsprite2_sample.parameters # for Android android-project/local.properties -test/aclocal.m4 -test/autom4te* -test/config.cache -test/config.log -test/config.status -test/Makefile -test/SDL2.dll test/checkkeys +test/checkkeysthreads test/controllermap test/loopwave test/loopwavequeue @@ -102,9 +116,11 @@ test/testdraw2 test/testdrawchessboard test/testdropfile test/testerror +test/testevdev test/testfile test/testfilesystem test/testgamecontroller +test/testgeometry test/testgesture test/testgl2 test/testgles @@ -118,8 +134,10 @@ test/testintersections test/testjoystick test/testkeys test/testloadso +test/testlocale test/testlock test/testmessage +test/testmouse test/testmultiaudio test/testnative test/testoverlay2 @@ -139,17 +157,22 @@ test/testshape test/testsprite2 test/testspriteminimal test/teststreaming +test/testsurround test/testthread test/testtimer +test/testurl test/testver test/testviewport test/testvulkan test/testwm2 test/testyuv test/torturethread -test/*.exe -test/*,e1f -test/*,ff8 -test/*.dSYM -buildbot -test/buildbot + +builddir/ +debian/*.debhelper.log +debian/*.substvars +debian/*.tar.gz +debian/.debhelper/ +debian/files +debian/libsdl*/ +debian/tmp/ diff --git a/Engine/lib/sdl/.hgtags b/Engine/lib/sdl/.hgtags deleted file mode 100644 index 1d0b38c22..000000000 --- a/Engine/lib/sdl/.hgtags +++ /dev/null @@ -1,40 +0,0 @@ -0afe0e38e02cf2048e93582f01c52fbb91d3c7bb release-1.2.7 -230b156829ed13b31134d96f689c917981f57b84 release-1.2.5 -27cab50ec9c746e886ce0f3fdaa0b0cdc55a594f release-1.2.11 -2fe3fbd2bff50165b3cad33bf40d70b3bb3c9fd0 release-1.2.3 -3c052d3bcc76c899dfd4846be76243a78e8c7180 release-1.2.4 -3c5eed71a3320962551af3b3dfbee0c99fcf0086 release-1.2.10 -4867f7f7dd3426d1dbbeef48b3f3b3aa19590cc4 release-1.2.12 -6e28dae59e3baf4447c83e833a8d2ac912536f5b release-1.2.1 -7c2589fb8d4df54c6faabd3faebd0c0e73f67879 release-1.2.13 -86de11faf082881ad9b73a1a1d78733ca07f8db8 release-1.2.6 -bb051fa871aa0b53ea57df56a446cec3bb85924c release-1.2.2 -cfcb2e1c36ebe9809577adf768b0ec53e8768af9 release-1.2.8 -e044e7c70a50a2f54d14ee20d0933e904e5853b6 release-1.2.9 -f14cf9d71233934811774f941d0de121d5f96ccf release-1.2.14 -39c22a953456f6c9e2c8993c8ff973824104102a pre-touch-removal -ccf5fbfa2afabab429ad911308f362201a94d810 macosx_10_4_supported -d6a8fa507a45d9de7258e51585eab3e45c415149 release-2.0.0 -a8bd63b33636715f2cf6e7d36ab7201acbd478fe release-2.0.1 -a8bd63b33636715f2cf6e7d36ab7201acbd478fe release-2.0.1 -715a01415ac9305b9f8ec72b99fcf8cc9dd64dde release-2.0.1 -715a01415ac9305b9f8ec72b99fcf8cc9dd64dde release-2.0.1 -9ec71e56071cc80eda6691a3f8719ed5395dfcfb release-2.0.1 -9ec71e56071cc80eda6691a3f8719ed5395dfcfb release-2.0.1 -0000000000000000000000000000000000000000 release-2.0.1 -0000000000000000000000000000000000000000 release-2.0.1 -b9663c77f5c95ebf05f3c18e80619caae8ae1460 release-2.0.1 -be2102f000d0d2d9bab75e9703a1d503d0f6bb33 release-2.0.2 -f285b9487756ff681f76c85644222c03a7bfa1c7 release-2.0.3 -f285b9487756ff681f76c85644222c03a7bfa1c7 release-2.0.3 -704a0bfecf754e4e1383f83c7d5118b00cae26ea release-2.0.3 -e12c387305129c847b3928a123300b113782fe3f release-2.0.4 -007dfe83abf81b1ff5df40186f65e8e64987b825 release-2.0.5 -8df7a59b55283aa09889522369a2b32674c048de release-2.0.6 -2088cd828335797d73d151e3288d899f77204862 release-2.0.7 -f1084c419f33610cf274e309a8b2798d2ae665c7 release-2.0.8 -8feb5da6f2fb75703bde2c06813375af984a57f0 release-2.0.9 -bc90ce38f1e27ace54b83bebf987993002504f7f release-2.0.10 -78d0bb6f3b8f9b8f2a76cb357a407bc7ace57234 release-2.0.12 -78d0bb6f3b8f9b8f2a76cb357a407bc7ace57234 release-2.0.12 -355a4f94a782747a990b2fedaebc7bebd280e153 release-2.0.12 diff --git a/Engine/lib/sdl/Android.mk b/Engine/lib/sdl/Android.mk index 0d2916766..4308d40f9 100755 --- a/Engine/lib/sdl/Android.mk +++ b/Engine/lib/sdl/Android.mk @@ -20,6 +20,7 @@ LOCAL_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/src/audio/*.c) \ $(wildcard $(LOCAL_PATH)/src/audio/android/*.c) \ $(wildcard $(LOCAL_PATH)/src/audio/dummy/*.c) \ + $(wildcard $(LOCAL_PATH)/src/audio/aaudio/*.c) \ $(wildcard $(LOCAL_PATH)/src/audio/openslES/*.c) \ $(LOCAL_PATH)/src/atomic/SDL_atomic.c.arm \ $(LOCAL_PATH)/src/atomic/SDL_spinlock.c.arm \ @@ -30,6 +31,8 @@ LOCAL_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/src/file/*.c) \ $(wildcard $(LOCAL_PATH)/src/haptic/*.c) \ $(wildcard $(LOCAL_PATH)/src/haptic/android/*.c) \ + $(wildcard $(LOCAL_PATH)/src/hidapi/*.c) \ + $(wildcard $(LOCAL_PATH)/src/hidapi/android/*.cpp) \ $(wildcard $(LOCAL_PATH)/src/joystick/*.c) \ $(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \ $(wildcard $(LOCAL_PATH)/src/joystick/hidapi/*.c) \ @@ -56,8 +59,6 @@ LOCAL_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/src/video/yuv2rgb/*.c) \ $(wildcard $(LOCAL_PATH)/src/test/*.c)) -LOCAL_SHARED_LIBRARIES := hidapi - LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES LOCAL_CFLAGS += \ -Wall -Wextra \ @@ -77,7 +78,6 @@ LOCAL_CFLAGS += \ # Warnings we haven't fixed (yet) LOCAL_CFLAGS += -Wno-unused-parameter -Wno-sign-compare - LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid @@ -120,22 +120,4 @@ LOCAL_MODULE_FILENAME := libSDL2main include $(BUILD_STATIC_LIBRARY) -########################### -# -# hidapi library -# -########################### - -include $(CLEAR_VARS) - -LOCAL_CPPFLAGS += -std=c++11 - -LOCAL_SRC_FILES := src/hidapi/android/hid.cpp - -LOCAL_MODULE := libhidapi -LOCAL_LDLIBS := -llog - -include $(BUILD_SHARED_LIBRARY) - $(call import-module,android/cpufeatures) - diff --git a/Engine/lib/sdl/BUGS.txt b/Engine/lib/sdl/BUGS.txt index a8e6b952e..b1463e777 100644 --- a/Engine/lib/sdl/BUGS.txt +++ b/Engine/lib/sdl/BUGS.txt @@ -1,7 +1,7 @@ -Bugs are now managed in the SDL bug tracker, here: +Bugs are now managed in the SDL issue tracker, here: - https://bugzilla.libsdl.org/ + https://github.com/libsdl-org/SDL/issues You may report bugs there, and search to see if a given issue has already been reported, discussed, and maybe even fixed. @@ -11,6 +11,6 @@ You may also find help at the SDL forums/mailing list: https://discourse.libsdl.org/ -Bug reports are welcome here, but we really appreciate if you use Bugzilla, as - bugs discussed on the mailing list may be forgotten or missed. +Bug reports are welcome here, but we really appreciate if you use the issue + tracker, as bugs discussed on the mailing list may be forgotten or missed. diff --git a/Engine/lib/sdl/CMakeLists.txt b/Engine/lib/sdl/CMakeLists.txt index b9b9eb620..59bacf0f5 100644 --- a/Engine/lib/sdl/CMakeLists.txt +++ b/Engine/lib/sdl/CMakeLists.txt @@ -1,22 +1,34 @@ -if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) - message(FATAL_ERROR "Prevented in-tree built. Please create a build directory outside of the SDL source code and call cmake from there") +if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) + message(FATAL_ERROR "Prevented in-tree build. Please create a build directory outside of the SDL source code and run \"cmake -S ${CMAKE_SOURCE_DIR} -B .\" from there") endif() cmake_minimum_required(VERSION 3.0.0) project(SDL2 C CXX) -if(WINDOWS_STORE) - enable_language(CXX) - cmake_minimum_required(VERSION 3.11) - add_definitions(-DSDL_BUILDING_WINRT=1 -ZW) - link_libraries( - -nodefaultlib:vccorlib$<$:d> - -nodefaultlib:msvcrt$<$:d> - vccorlib$<$:d>.lib - msvcrt$<$:d>.lib - ) +if (HAIKU) + set(LINKER_LANGUAGE CXX) endif() +# This is a virtual "library" that just exists to collect up compiler and +# linker options that used to be global to this CMake project. When you +# specify it as part of a real library's target_link_libraries(), that +# library will also gain all those build options too. This is meant to +# modularize old calls to the global add_definitions and include_directories, +# etc. See https://github.com/libsdl-org/SDL/issues/4150 +add_library(sdl-build-options INTERFACE) + +if(WINDOWS_STORE) + cmake_minimum_required(VERSION 3.11.0) + target_compile_definitions(sdl-build-options INTERFACE "-DSDL_BUILDING_WINRT=1") + target_compile_options(sdl-build-options INTERFACE "-ZW") +endif() + +# Build in parallel under Visual Studio. Not enabled by default. +if(MSVC) + target_compile_options(sdl-build-options INTERFACE "/MP") +endif(MSVC) + + # !!! FIXME: this should probably do "MACOSX_RPATH ON" as a target property # !!! FIXME: for the SDL2 shared library (so you get an # !!! FIXME: install_name ("soname") of "@rpath/libSDL-whatever.dylib" @@ -34,6 +46,7 @@ include(CheckSymbolExists) include(CheckCSourceCompiles) include(CheckCSourceRuns) include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) include(CheckTypeSize) include(CheckStructHasMember) include(CMakeDependentOption) @@ -53,12 +66,12 @@ include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake) # set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0. set(SDL_MAJOR_VERSION 2) set(SDL_MINOR_VERSION 0) -set(SDL_MICRO_VERSION 14) -set(SDL_INTERFACE_AGE 0) -set(SDL_BINARY_AGE 14) +set(SDL_MICRO_VERSION 21) +set(SDL_INTERFACE_AGE 3) +set(SDL_BINARY_AGE 21) set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}") # the following should match the versions in Xcode project file: -set(DYLIB_CURRENT_VERSION 15.0.0) +set(DYLIB_CURRENT_VERSION 19.3.0) set(DYLIB_COMPATIBILITY_VERSION 1.0.0) # Set defaults preventing destination file conflicts @@ -131,8 +144,12 @@ elseif(APPLE) set(MACOSX TRUE) elseif(CMAKE_SYSTEM_NAME MATCHES ".*tvOS.*") set(TVOS TRUE) + elseif(CMAKE_SYSTEM_NAME MATCHES ".*iOS.*") + # !!! FIXME: remove the version check when we start requiring >= 3.14.0 + if(CMAKE_VERSION VERSION_LESS 3.14) + set(IOS TRUE) + endif() endif() - # TODO: iOS? elseif(CMAKE_SYSTEM_NAME MATCHES "BeOS.*") message_error("BeOS support has been removed as of SDL 2.0.2.") elseif(CMAKE_SYSTEM_NAME MATCHES "Haiku.*") @@ -152,22 +169,19 @@ else() set(UNIX_OR_MAC_SYS OFF) endif() -if (UNIX_OR_MAC_SYS AND NOT EMSCRIPTEN) # JavaScript does not yet have threading support, so disable pthreads when building for Emscripten. +# Emscripten pthreads work, but you need to have a non-pthread fallback build +# for systems without support. It's not currently enough to not use +# pthread functions in a pthread-build; it won't start up on unsupported +# browsers. As such, you have to explicitly enable it on Emscripten builds +# for the time being. This default with change to ON once this becomes +# commonly supported in browsers or the Emscripten teams makes a single +# binary work everywhere. +if (UNIX_OR_MAC_SYS AND NOT EMSCRIPTEN) set(SDL_PTHREADS_ENABLED_BY_DEFAULT ON) else() set(SDL_PTHREADS_ENABLED_BY_DEFAULT OFF) endif() -# Default option knobs -if(APPLE OR ARCH_64) - if(NOT "${CMAKE_OSX_ARCHITECTURES}" MATCHES "arm") - set(OPT_DEF_SSEMATH ON) - endif() -endif() -if(UNIX OR MINGW OR MSYS) - set(OPT_DEF_LIBC ON) -endif() - # The hidraw support doesn't catch Xbox, PS4 and Nintendo controllers, # so we'll just use libusb when it's available. libusb does not support iOS, # so we default to yes on iOS. @@ -177,9 +191,6 @@ if((WINDOWS AND NOT WINDOWS_STORE) OR IOS OR TVOS OR ANDROID) else() set(HIDAPI_SKIP_LIBUSB FALSE) endif() -if (HIDAPI_SKIP_LIBUSB) - set(OPT_DEF_HIDAPI ON) -endif() # On the other hand, *BSD specifically uses libusb only, so we make a special # case just for them. @@ -190,12 +201,17 @@ else() endif() # Compiler info -if(CMAKE_COMPILER_IS_GNUCC) - set(USE_GCC TRUE) - set(OPT_DEF_ASM TRUE) -elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") +if(CMAKE_C_COMPILER_ID MATCHES "Clang") set(USE_CLANG TRUE) set(OPT_DEF_ASM TRUE) + # Visual Studio 2019 v16.2 added support for Clang/LLVM. + # Check if a Visual Studio project is being generated with the Clang toolset. + if(MSVC) + set(MSVC_CLANG TRUE) + endif() +elseif(CMAKE_COMPILER_IS_GNUCC) + set(USE_GCC TRUE) + set(OPT_DEF_ASM TRUE) elseif(MSVC_VERSION GREATER 1400) # VisualStudio 8.0+ set(OPT_DEF_ASM TRUE) #set(CMAKE_C_FLAGS "/ZI /WX- / @@ -207,24 +223,27 @@ if(USE_GCC OR USE_CLANG) set(OPT_DEF_GCC_ATOMICS ON) endif() -# Default flags, if not set otherwise -if("$ENV{CFLAGS}" STREQUAL "") - if(CMAKE_BUILD_TYPE STREQUAL "") - if(USE_GCC OR USE_CLANG) - set(CMAKE_C_FLAGS "-g -O3") - endif() +# Default option knobs +if(APPLE OR ARCH_64 OR MSVC_CLANG) + if(NOT "${CMAKE_OSX_ARCHITECTURES}" MATCHES "arm") + set(OPT_DEF_SSEMATH ON) endif() -else() - set(CMAKE_C_FLAGS "$ENV{CFLAGS}") - list(APPEND EXTRA_CFLAGS "$ENV{CFLAGS}") endif() -if(NOT ("$ENV{CFLAGS}" STREQUAL "")) # Hackish, but does the trick on Win32 - list(APPEND EXTRA_LDFLAGS "$ENV{LDFLAGS}") +if(UNIX OR MINGW OR MSYS OR (USE_CLANG AND NOT WINDOWS) OR VITA OR PSP) + set(OPT_DEF_LIBC ON) +endif() + +if(NOT ("$ENV{CFLAGS}" STREQUAL "")) + if(CMAKE_VERSION VERSION_LESS 3.11.0) + message(WARNING "SDL's CMakeLists.txt no longer checks the CFLAGS environment.") + message(WARNING "Please use CMake's CMAKE_C_FLAGS and CMAKE_BUILD_TYPE variables directly.") + message(WARNING "Or upgrade to CMake >= 3.11.0, which respects the CFLAGS environment var.") + endif() endif() if(MSVC) - option(FORCE_STATIC_VCRT "Force /MT for static VC runtimes" OFF) - if(FORCE_STATIC_VCRT) + option(SDL_FORCE_STATIC_VCRT "Force /MT for static VC runtimes" OFF) + if(SDL_FORCE_STATIC_VCRT) foreach(flag_var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) @@ -234,12 +253,23 @@ if(MSVC) endforeach() endif() - # Make sure /RTC1 is disabled, otherwise it will use functions from the CRT - foreach(flag_var - CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) - string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}") - endforeach(flag_var) + if(NOT SDL_LIBC) + # Make sure /RTC1 is disabled, otherwise it will use functions from the CRT + foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) + string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}") + endforeach(flag_var) + endif() + + if(MSVC_CLANG) + # clang-cl treats /W4 as '-Wall -Wextra' -- we don't need -Wextra + foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) + string(REGEX REPLACE "/W4" "/W3" ${flag_var} "${${flag_var}}") + endforeach(flag_var) + endif() endif() # Those are used for pkg-config and friends, so that the SDL2.pc, sdl2-config, @@ -261,9 +291,9 @@ set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) if(CYGWIN) # We build SDL on cygwin without the UNIX emulation layer - include_directories("-I/usr/include/mingw") + target_include_directories(sdl-build-options INTERFACE "/usr/include/mingw") set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -mno-cygwin") - check_c_source_compiles("int main(int argc, char **argv) {}" + check_c_source_compiles("int main(int argc, char **argv) { return 0; }" HAVE_GCC_NO_CYGWIN) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) if(HAVE_GCC_NO_CYGWIN) @@ -273,13 +303,16 @@ if(CYGWIN) set(SDL_CFLAGS "${SDL_CFLAGS} -I/usr/include/mingw") endif() -add_definitions(-DUSING_GENERATED_CONFIG_H) # General includes -include_directories(${SDL2_BINARY_DIR}/include ${SDL2_SOURCE_DIR}/include) -if(USE_GCC OR USE_CLANG) +target_compile_definitions(sdl-build-options INTERFACE "-DUSING_GENERATED_CONFIG_H") +target_include_directories(sdl-build-options BEFORE INTERFACE "${SDL2_BINARY_DIR}/include") +target_include_directories(sdl-build-options INTERFACE "${SDL2_SOURCE_DIR}/include") +# Note: The clang toolset for Visual Studio does not support the '-idirafter' option. +if(USE_GCC OR (USE_CLANG AND NOT MSVC_CLANG)) + # !!! FIXME: do we _need_ to mess with CMAKE_C_FLAGS here? set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -idirafter \"${SDL2_SOURCE_DIR}/src/video/khronos\"") else() - include_directories(${SDL2_SOURCE_DIR}/src/video/khronos) + target_include_directories(sdl-build-options INTERFACE "${SDL2_SOURCE_DIR}/src/video/khronos") endif() # All these ENABLED_BY_DEFAULT vars will default to ON if not specified, so @@ -288,14 +321,21 @@ set(OPT_DEF_ASM TRUE) if(EMSCRIPTEN) # Set up default values for the currently supported set of subsystems: # Emscripten/Javascript does not have assembly support, a dynamic library - # loading architecture, low-level CPU inspection or multithreading. + # loading architecture, or low-level CPU inspection. + + # SDL_THREADS_ENABLED_BY_DEFAULT now defaults to ON, but pthread support might be disabled by default. + # !!! FIXME: most of these subsystems should default to ON if there are dummy implementations to be used. + set(OPT_DEF_ASM FALSE) set(SDL_SHARED_ENABLED_BY_DEFAULT OFF) set(SDL_ATOMIC_ENABLED_BY_DEFAULT OFF) - set(SDL_THREADS_ENABLED_BY_DEFAULT OFF) set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF) set(SDL_CPUINFO_ENABLED_BY_DEFAULT OFF) - set(SDL_DLOPEN_ENABLED_BY_DEFAULT OFF) +endif() + +if(VITA OR PSP) + set(SDL_SHARED_ENABLED_BY_DEFAULT OFF) + set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF) endif() # When defined, respect CMake's BUILD_SHARED_LIBS setting: @@ -317,9 +357,11 @@ if (NOT DEFINED SDL_SHARED_ENABLED_BY_DEFAULT) endif() endif() +set(LONGESTOPTIONNAME 0) # set_option and friends will change this. + set(SDL_SUBSYSTEMS - Atomic Audio Video Render Events Joystick Haptic Power Threads Timers - File Loadso CPUinfo Filesystem Dlopen Sensor Locale) + Atomic Audio Video Render Events Joystick Haptic Hidapi Power Threads Timers + File Loadso CPUinfo Filesystem Sensor Locale Misc) foreach(_SUB ${SDL_SUBSYSTEMS}) string(TOUPPER ${_SUB} _OPT) if (NOT DEFINED SDL_${_OPT}_ENABLED_BY_DEFAULT) @@ -328,77 +370,86 @@ foreach(_SUB ${SDL_SUBSYSTEMS}) option(SDL_${_OPT} "Enable the ${_SUB} subsystem" ${SDL_${_OPT}_ENABLED_BY_DEFAULT}) endforeach() -option_string(ASSERTIONS "Enable internal sanity checks (auto/disabled/release/enabled/paranoid)" "auto") -#set_option(DEPENDENCY_TRACKING "Use gcc -MMD -MT dependency tracking" ON) -set_option(LIBC "Use the system C library" ${OPT_DEF_LIBC}) -set_option(GCC_ATOMICS "Use gcc builtin atomics" ${OPT_DEF_GCC_ATOMICS}) -set_option(ASSEMBLY "Enable assembly routines" ${OPT_DEF_ASM}) -set_option(SSEMATH "Allow GCC to use SSE floating point math" ${OPT_DEF_SSEMATH}) -set_option(MMX "Use MMX assembly routines" ${OPT_DEF_ASM}) -set_option(3DNOW "Use 3Dnow! MMX assembly routines" ${OPT_DEF_ASM}) -set_option(SSE "Use SSE assembly routines" ${OPT_DEF_ASM}) -set_option(SSE2 "Use SSE2 assembly routines" ${OPT_DEF_SSEMATH}) -set_option(SSE3 "Use SSE3 assembly routines" ${OPT_DEF_SSEMATH}) -set_option(ALTIVEC "Use Altivec assembly routines" ${OPT_DEF_ASM}) -set_option(ARMSIMD "use SIMD assembly blitters on ARM" OFF) -set_option(ARMNEON "use NEON assembly blitters on ARM" OFF) -set_option(DISKAUDIO "Support the disk writer audio driver" ON) -set_option(DUMMYAUDIO "Support the dummy audio driver" ON) -set_option(VIDEO_DIRECTFB "Use DirectFB video driver" OFF) -dep_option(DIRECTFB_SHARED "Dynamically load directfb support" ON "VIDEO_DIRECTFB" OFF) -set_option(VIDEO_DUMMY "Use dummy video driver" ON) -set_option(VIDEO_OPENGL "Include OpenGL support" ON) -set_option(VIDEO_OPENGLES "Include OpenGL ES support" ON) -set_option(PTHREADS "Use POSIX threads for multi-threading" ${SDL_PTHREADS_ENABLED_BY_DEFAULT}) -dep_option(PTHREADS_SEM "Use pthread semaphores" ON "PTHREADS" OFF) -set_option(SDL_DLOPEN "Use dlopen for shared object loading" ${SDL_DLOPEN_ENABLED_BY_DEFAULT}) -dep_option(OSS "Support the OSS audio API" ON "UNIX_SYS OR RISCOS" OFF) -set_option(ALSA "Support the ALSA audio API" ${UNIX_SYS}) -dep_option(ALSA_SHARED "Dynamically load ALSA audio support" ON "ALSA" OFF) -set_option(JACK "Support the JACK audio API" ${UNIX_SYS}) -dep_option(JACK_SHARED "Dynamically load JACK audio support" ON "JACK" OFF) -set_option(ESD "Support the Enlightened Sound Daemon" ${UNIX_SYS}) -dep_option(ESD_SHARED "Dynamically load ESD audio support" ON "ESD" OFF) -set_option(PULSEAUDIO "Use PulseAudio" ${UNIX_SYS}) -dep_option(PULSEAUDIO_SHARED "Dynamically load PulseAudio support" ON "PULSEAUDIO" OFF) -set_option(ARTS "Support the Analog Real Time Synthesizer" ${UNIX_SYS}) -dep_option(ARTS_SHARED "Dynamically load aRts audio support" ON "ARTS" OFF) -set_option(NAS "Support the NAS audio API" ${UNIX_SYS}) -set_option(NAS_SHARED "Dynamically load NAS audio API" ${UNIX_SYS}) -set_option(SNDIO "Support the sndio audio API" ${UNIX_SYS}) -dep_option(SNDIO_SHARED "Dynamically load the sndio audio API" ${UNIX_SYS} ON "SNDIO" OFF) -set_option(FUSIONSOUND "Use FusionSound audio driver" OFF) -dep_option(FUSIONSOUND_SHARED "Dynamically load fusionsound audio support" ON "FUSIONSOUND" OFF) -set_option(LIBSAMPLERATE "Use libsamplerate for audio rate conversion" ${UNIX_SYS}) -dep_option(LIBSAMPLERATE_SHARED "Dynamically load libsamplerate" ON "LIBSAMPLERATE" OFF) -set_option(RPATH "Use an rpath when linking SDL" ${UNIX_SYS}) -set_option(CLOCK_GETTIME "Use clock_gettime() instead of gettimeofday()" OFF) -set_option(VIDEO_X11 "Use X11 video driver" ${UNIX_SYS}) -set_option(VIDEO_WAYLAND "Use Wayland video driver" ${UNIX_SYS}) -dep_option(WAYLAND_SHARED "Dynamically load Wayland support" ON "VIDEO_WAYLAND" OFF) -dep_option(VIDEO_WAYLAND_QT_TOUCH "QtWayland server support for Wayland video driver" ON "VIDEO_WAYLAND" OFF) -set_option(VIDEO_RPI "Use Raspberry Pi video driver" ${UNIX_SYS}) -dep_option(X11_SHARED "Dynamically load X11 support" ON "VIDEO_X11" OFF) -set(SDL_X11_OPTIONS Xcursor Xinerama XInput Xrandr Xscrnsaver XShape Xvm) +# Allow some projects to be built conditionally. +set_option(SDL2_DISABLE_SDL2MAIN "Disable building/installation of SDL2main" OFF) +set_option(SDL2_DISABLE_UNINSTALL "Disable uninstallation of SDL2" OFF) + +option_string(SDL_ASSERTIONS "Enable internal sanity checks (auto/disabled/release/enabled/paranoid)" "auto") +#set_option(SDL_DEPENDENCY_TRACKING "Use gcc -MMD -MT dependency tracking" ON) +set_option(SDL_LIBC "Use the system C library" ${OPT_DEF_LIBC}) +set_option(SDL_GCC_ATOMICS "Use gcc builtin atomics" ${OPT_DEF_GCC_ATOMICS}) +set_option(SDL_ASSEMBLY "Enable assembly routines" ${OPT_DEF_ASM}) +set_option(SDL_SSEMATH "Allow GCC to use SSE floating point math" ${OPT_DEF_SSEMATH}) +set_option(SDL_MMX "Use MMX assembly routines" ${OPT_DEF_ASM}) +set_option(SDL_3DNOW "Use 3Dnow! MMX assembly routines" ${OPT_DEF_ASM}) +set_option(SDL_SSE "Use SSE assembly routines" ${OPT_DEF_ASM}) +set_option(SDL_SSE2 "Use SSE2 assembly routines" ${OPT_DEF_SSEMATH}) +set_option(SDL_SSE3 "Use SSE3 assembly routines" ${OPT_DEF_SSEMATH}) +set_option(SDL_ALTIVEC "Use Altivec assembly routines" ${OPT_DEF_ASM}) +set_option(SDL_ARMSIMD "use SIMD assembly blitters on ARM" OFF) +set_option(SDL_ARMNEON "use NEON assembly blitters on ARM" OFF) +set_option(SDL_DISKAUDIO "Support the disk writer audio driver" ON) +set_option(SDL_DUMMYAUDIO "Support the dummy audio driver" ON) +set_option(SDL_DIRECTFB "Use DirectFB video driver" OFF) +dep_option(SDL_DIRECTFB_SHARED "Dynamically load directfb support" ON "SDL_DIRECTFB" OFF) +set_option(SDL_DUMMYVIDEO "Use dummy video driver" ON) +set_option(SDL_OPENGL "Include OpenGL support" ON) +set_option(SDL_OPENGLES "Include OpenGL ES support" ON) +set_option(SDL_PTHREADS "Use POSIX threads for multi-threading" ${SDL_PTHREADS_ENABLED_BY_DEFAULT}) +dep_option(SDL_PTHREADS_SEM "Use pthread semaphores" ON "SDL_PTHREADS" OFF) +dep_option(SDL_OSS "Support the OSS audio API" ON "UNIX_SYS OR RISCOS" OFF) +set_option(SDL_ALSA "Support the ALSA audio API" ${UNIX_SYS}) +dep_option(SDL_ALSA_SHARED "Dynamically load ALSA audio support" ON "SDL_ALSA" OFF) +set_option(SDL_JACK "Support the JACK audio API" ${UNIX_SYS}) +dep_option(SDL_JACK_SHARED "Dynamically load JACK audio support" ON "SDL_JACK" OFF) +set_option(SDL_ESD "Support the Enlightened Sound Daemon" ${UNIX_SYS}) +dep_option(SDL_ESD_SHARED "Dynamically load ESD audio support" ON "SDL_ESD" OFF) +set_option(SDL_PIPEWIRE "Use Pipewire audio" ${UNIX_SYS}) +dep_option(SDL_PIPEWIRE_SHARED "Dynamically load Pipewire support" ON "SDL_PIPEWIRE" OFF) +set_option(SDL_PULSEAUDIO "Use PulseAudio" ${UNIX_SYS}) +dep_option(SDL_PULSEAUDIO_SHARED "Dynamically load PulseAudio support" ON "SDL_PULSEAUDIO" OFF) +set_option(SDL_ARTS "Support the Analog Real Time Synthesizer" ${UNIX_SYS}) +dep_option(SDL_ARTS_SHARED "Dynamically load aRts audio support" ON "SDL_ARTS" OFF) +set_option(SDL_NAS "Support the NAS audio API" ${UNIX_SYS}) +dep_option(SDL_NAS_SHARED "Dynamically load NAS audio support" ON "SDL_NAS" OFF) +set_option(SDL_SNDIO "Support the sndio audio API" ${UNIX_SYS}) +dep_option(SDL_SNDIO_SHARED "Dynamically load the sndio audio API" ${UNIX_SYS} ON "SDL_SNDIO" OFF) +set_option(SDL_FUSIONSOUND "Use FusionSound audio driver" OFF) +dep_option(SDL_FUSIONSOUND_SHARED "Dynamically load fusionsound audio support" ON "SDL_FUSIONSOUND" OFF) +set_option(SDL_LIBSAMPLERATE "Use libsamplerate for audio rate conversion" ${UNIX_SYS}) +dep_option(SDL_LIBSAMPLERATE_SHARED "Dynamically load libsamplerate" ON "SDL_LIBSAMPLERATE" OFF) +set_option(SDL_RPATH "Use an rpath when linking SDL" ${UNIX_SYS}) +set_option(SDL_CLOCK_GETTIME "Use clock_gettime() instead of gettimeofday()" ${UNIX_SYS}) +set_option(SDL_X11 "Use X11 video driver" ${UNIX_SYS}) +dep_option(SDL_X11_SHARED "Dynamically load X11 support" ON "SDL_X11" OFF) +set(SDL_X11_OPTIONS Xcursor Xdbe Xinerama XInput Xfixes Xrandr Xscrnsaver XShape Xvm) foreach(_SUB ${SDL_X11_OPTIONS}) - string(TOUPPER "VIDEO_X11_${_SUB}" _OPT) - dep_option(${_OPT} "Enable ${_SUB} support" ON "VIDEO_X11" OFF) + string(TOUPPER "SDL_X11_${_SUB}" _OPT) + dep_option(${_OPT} "Enable ${_SUB} support" ON "SDL_X11" OFF) endforeach() -set_option(VIDEO_COCOA "Use Cocoa video driver" ${APPLE}) -set_option(DIRECTX "Use DirectX for Windows audio/video" ${WINDOWS}) -set_option(WASAPI "Use the Windows WASAPI audio driver" ${WINDOWS}) -set_option(RENDER_D3D "Enable the Direct3D render driver" ${WINDOWS}) -set_option(RENDER_METAL "Enable the Metal render driver" ${APPLE}) -set_option(VIDEO_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS}) -dep_option(VIDEO_VULKAN "Enable Vulkan support" ON "ANDROID OR APPLE OR LINUX OR WINDOWS" OFF) -set_option(VIDEO_METAL "Enable Metal support" ${APPLE}) -set_option(VIDEO_KMSDRM "Use KMS DRM video driver" ${UNIX_SYS}) -dep_option(KMSDRM_SHARED "Dynamically load KMS DRM support" ON "VIDEO_KMSDRM" OFF) -set_option(VIDEO_OFFSCREEN "Use offscreen video driver" OFF) -option_string(BACKGROUNDING_SIGNAL "number to use for magic backgrounding signal or 'OFF'" "OFF") -option_string(FOREGROUNDING_SIGNAL "number to use for magic foregrounding signal or 'OFF'" "OFF") -set_option(HIDAPI "Use HIDAPI for low level joystick drivers" ${OPT_DEF_HIDAPI}) -set_option(JOYSTICK_VIRTUAL "Enable the virtual-joystick driver" ON) +set_option(SDL_WAYLAND "Use Wayland video driver" ${UNIX_SYS}) +dep_option(SDL_WAYLAND_SHARED "Dynamically load Wayland support" ON "SDL_WAYLAND" OFF) +dep_option(SDL_WAYLAND_LIBDECOR "Use client-side window decorations on Wayland" ON "SDL_WAYLAND" OFF) +dep_option(SDL_WAYLAND_LIBDECOR_SHARED "Dynamically load libdecor support" ON "SDL_WAYLAND_LIBDECOR" OFF) +dep_option(SDL_WAYLAND_QT_TOUCH "QtWayland server support for Wayland video driver" ON "SDL_WAYLAND" OFF) +set_option(SDL_RPI "Use Raspberry Pi video driver" ${UNIX_SYS}) +set_option(SDL_COCOA "Use Cocoa video driver" ${APPLE}) +set_option(SDL_DIRECTX "Use DirectX for Windows audio/video" ${WINDOWS}) +set_option(SDL_XINPUT "Use Xinput for Windows" ${WINDOWS}) +set_option(SDL_WASAPI "Use the Windows WASAPI audio driver" ${WINDOWS}) +set_option(SDL_RENDER_D3D "Enable the Direct3D render driver" ${WINDOWS}) +set_option(SDL_RENDER_METAL "Enable the Metal render driver" ${APPLE}) +set_option(SDL_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS}) +dep_option(SDL_VULKAN "Enable Vulkan support" ON "ANDROID OR APPLE OR LINUX OR WINDOWS" OFF) +set_option(SDL_METAL "Enable Metal support" ${APPLE}) +set_option(SDL_KMSDRM "Use KMS DRM video driver" ${UNIX_SYS}) +dep_option(SDL_KMSDRM_SHARED "Dynamically load KMS DRM support" ON "SDL_KMSDRM" OFF) +set_option(SDL_OFFSCREEN "Use offscreen video driver" OFF) +option_string(SDL_BACKGROUNDING_SIGNAL "number to use for magic backgrounding signal or 'OFF'" OFF) +option_string(SDL_FOREGROUNDING_SIGNAL "number to use for magic foregrounding signal or 'OFF'" OFF) +set_option(SDL_HIDAPI_JOYSTICK "Use HIDAPI for low level joystick drivers" ON) +set_option(SDL_VIRTUAL_JOYSTICK "Enable the virtual-joystick driver" ON) +set_option(SDL_ASAN "Use AddressSanitizer to detect memory errors" OFF) set(SDL_SHARED ${SDL_SHARED_ENABLED_BY_DEFAULT} CACHE BOOL "Build a shared version of the library") set(SDL_STATIC ${SDL_STATIC_ENABLED_BY_DEFAULT} CACHE BOOL "Build a static version of the library") @@ -406,6 +457,11 @@ set(SDL_STATIC ${SDL_STATIC_ENABLED_BY_DEFAULT} CACHE BOOL "Build a static versi dep_option(SDL_STATIC_PIC "Static version of the library should be built with Position Independent Code" OFF "SDL_STATIC" OFF) set_option(SDL_TEST "Build the test directory" OFF) +if(VITA) + set_option(VIDEO_VITA_PIB "Build with PSVita piglet gles2 support" OFF) + set_option(VIDEO_VITA_PVR "Build with PSVita PVR gles/gles2 support" OFF) +endif() + # General source files file(GLOB SOURCE_FILES ${SDL2_SOURCE_DIR}/src/*.c @@ -415,7 +471,9 @@ file(GLOB SOURCE_FILES ${SDL2_SOURCE_DIR}/src/dynapi/*.c ${SDL2_SOURCE_DIR}/src/events/*.c ${SDL2_SOURCE_DIR}/src/file/*.c + ${SDL2_SOURCE_DIR}/src/joystick/*.c ${SDL2_SOURCE_DIR}/src/haptic/*.c + ${SDL2_SOURCE_DIR}/src/hidapi/*.c ${SDL2_SOURCE_DIR}/src/libm/*.c ${SDL2_SOURCE_DIR}/src/locale/*.c ${SDL2_SOURCE_DIR}/src/misc/*.c @@ -430,34 +488,38 @@ file(GLOB SOURCE_FILES ${SDL2_SOURCE_DIR}/src/video/yuv2rgb/*.c) -if(ASSERTIONS STREQUAL "auto") +if(SDL_ASSERTIONS STREQUAL "auto") # Do nada - use optimization settings to determine the assertion level -elseif(ASSERTIONS STREQUAL "disabled") +elseif(SDL_ASSERTIONS STREQUAL "disabled") set(SDL_DEFAULT_ASSERT_LEVEL 0) -elseif(ASSERTIONS STREQUAL "release") +elseif(SDL_ASSERTIONS STREQUAL "release") set(SDL_DEFAULT_ASSERT_LEVEL 1) -elseif(ASSERTIONS STREQUAL "enabled") +elseif(SDL_ASSERTIONS STREQUAL "enabled") set(SDL_DEFAULT_ASSERT_LEVEL 2) -elseif(ASSERTIONS STREQUAL "paranoid") +elseif(SDL_ASSERTIONS STREQUAL "paranoid") set(SDL_DEFAULT_ASSERT_LEVEL 3) else() message_error("unknown assertion level") endif() -set(HAVE_ASSERTIONS ${ASSERTIONS}) +set(HAVE_ASSERTIONS ${SDL_ASSERTIONS}) -if(NOT BACKGROUNDING_SIGNAL STREQUAL "OFF") - add_definitions("-DSDL_BACKGROUNDING_SIGNAL=${BACKGROUNDING_SIGNAL}") +if(NOT SDL_BACKGROUNDING_SIGNAL STREQUAL "OFF") + target_compile_definitions(sdl-build-options INTERFACE "-DSDL_BACKGROUNDING_SIGNAL=${SDL_BACKGROUNDING_SIGNAL}") endif() -if(NOT FOREGROUNDING_SIGNAL STREQUAL "OFF") - add_definitions("-DSDL_FOREGROUNDING_SIGNAL=${FOREGROUNDING_SIGNAL}") +if(NOT SDL_FOREGROUNDING_SIGNAL STREQUAL "OFF") + target_compile_definitions(sdl-build-options INTERFACE "-DSDL_FOREGROUNDING_SIGNAL=${SDL_FOREGROUNDING_SIGNAL}") endif() # Compiler option evaluation if(USE_GCC OR USE_CLANG) # Check for -Wall first, so later things can override pieces of it. + # Note: clang-cl treats -Wall as -Weverything (which is very loud), + # /W3 as -Wall, and /W4 as -Wall -Wextra. So: /W3 is enough. check_c_compiler_flag(-Wall HAVE_GCC_WALL) - if(HAVE_GCC_WALL) + if(MSVC_CLANG) + list(APPEND EXTRA_CFLAGS "/W3") + elseif(HAVE_GCC_WALL) list(APPEND EXTRA_CFLAGS "-Wall") if(HAIKU) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-multichar") @@ -483,10 +545,10 @@ if(USE_GCC OR USE_CLANG) #if !defined(__GNUC__) || __GNUC__ < 3 #error Dependency tracking requires GCC 3.0 or newer #endif - int main(int argc, char **argv) { }" HAVE_DEPENDENCY_TRACKING) + int main(int argc, char **argv) { return 0; }" HAVE_DEPENDENCY_TRACKING) endif() - if(GCC_ATOMICS) + if(SDL_GCC_ATOMICS) check_c_source_compiles("int main(int argc, char **argv) { int a; void *x, *y, *z; @@ -494,17 +556,19 @@ if(USE_GCC OR USE_CLANG) __sync_lock_test_and_set(&x, y); __sync_fetch_and_add(&a, 1); __sync_bool_compare_and_swap(&a, 5, 10); - __sync_bool_compare_and_swap(&x, y, z); }" HAVE_GCC_ATOMICS) + __sync_bool_compare_and_swap(&x, y, z); + return 0; }" HAVE_GCC_ATOMICS) if(NOT HAVE_GCC_ATOMICS) check_c_source_compiles("int main(int argc, char **argv) { int a; __sync_lock_test_and_set(&a, 1); - __sync_lock_release(&a); }" HAVE_GCC_SYNC_LOCK_TEST_AND_SET) + __sync_lock_release(&a); + return 0; }" HAVE_GCC_SYNC_LOCK_TEST_AND_SET) endif() endif() set(CMAKE_REQUIRED_FLAGS "-mpreferred-stack-boundary=2") - check_c_source_compiles("int x = 0; int main(int argc, char **argv) {}" + check_c_source_compiles("int x = 0; int main(int argc, char **argv) { return 0; }" HAVE_GCC_PREFERRED_STACK_BOUNDARY) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) @@ -513,7 +577,7 @@ if(USE_GCC OR USE_CLANG) #if !defined(__GNUC__) || __GNUC__ < 4 #error SDL only uses visibility attributes in GCC 4 or newer #endif - int main(int argc, char **argv) {}" HAVE_GCC_FVISIBILITY) + int main(int argc, char **argv) { return 0; }" HAVE_GCC_FVISIBILITY) if(HAVE_GCC_FVISIBILITY) list(APPEND EXTRA_CFLAGS "-fvisibility=hidden") endif() @@ -528,23 +592,32 @@ if(USE_GCC OR USE_CLANG) list(APPEND EXTRA_LDFLAGS "-Wl,-undefined,error") list(APPEND EXTRA_LDFLAGS "-Wl,-compatibility_version,${DYLIB_COMPATIBILITY_VERSION}") list(APPEND EXTRA_LDFLAGS "-Wl,-current_version,${DYLIB_CURRENT_VERSION}") - else() + elseif(NOT OPENBSD) set(CMAKE_REQUIRED_FLAGS "-Wl,--no-undefined") check_c_compiler_flag("" HAVE_NO_UNDEFINED) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) - if(HAVE_NO_UNDEFINED) + if(HAVE_NO_UNDEFINED AND NOT (USE_CLANG AND WINDOWS)) list(APPEND EXTRA_LDFLAGS "-Wl,--no-undefined") endif() endif() + + # Force color diagnostics when one of these conditions are met + if(DEFINED ENV{CI} OR DEFINED ENV{USE_CCACHE} OR CMAKE_GENERATOR MATCHES Ninja) + if(EMSCRIPTEN OR (USE_GCC AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9)) + list(APPEND EXTRA_CFLAGS -fdiagnostics-color=always) + elseif(USE_CLANG AND NOT CMAKE_C_COMPILER_ID MATCHES AppleClang) + list(APPEND EXTRA_CFLAGS -fcolor-diagnostics) + endif() + endif() endif() -if(ASSEMBLY) +if(SDL_ASSEMBLY) if(USE_GCC OR USE_CLANG) set(SDL_ASSEMBLY_ROUTINES 1) # TODO: Those all seem to be quite GCC specific - needs to be # reworked for better compiler support set(HAVE_ASSEMBLY TRUE) - if(MMX) + if(SDL_MMX) set(CMAKE_REQUIRED_FLAGS "-mmmx") check_c_source_compiles(" #ifdef __MINGW32__ @@ -560,14 +633,14 @@ if(ASSEMBLY) #ifndef __MMX__ #error Assembler CPP flag not enabled #endif - int main(int argc, char **argv) { }" HAVE_MMX) + int main(int argc, char **argv) { return 0; }" HAVE_MMX) if(HAVE_MMX) list(APPEND EXTRA_CFLAGS "-mmmx") endif() set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) endif() - if(3DNOW) + if(SDL_3DNOW) set(CMAKE_REQUIRED_FLAGS "-m3dnow") check_c_source_compiles(" #include @@ -577,6 +650,7 @@ if(ASSEMBLY) int main(int argc, char **argv) { void *p = 0; _m_prefetch(p); + return 0; }" HAVE_3DNOW) if(HAVE_3DNOW) list(APPEND EXTRA_CFLAGS "-m3dnow") @@ -584,7 +658,7 @@ if(ASSEMBLY) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) endif() - if(SSE) + if(SDL_SSE) set(CMAKE_REQUIRED_FLAGS "-msse") check_c_source_compiles(" #ifdef __MINGW32__ @@ -600,14 +674,14 @@ if(ASSEMBLY) #ifndef __SSE__ #error Assembler CPP flag not enabled #endif - int main(int argc, char **argv) { }" HAVE_SSE) + int main(int argc, char **argv) { return 0; }" HAVE_SSE) if(HAVE_SSE) list(APPEND EXTRA_CFLAGS "-msse") endif() set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) endif() - if(SSE2) + if(SDL_SSE2) set(CMAKE_REQUIRED_FLAGS "-msse2") check_c_source_compiles(" #ifdef __MINGW32__ @@ -623,14 +697,14 @@ if(ASSEMBLY) #ifndef __SSE2__ #error Assembler CPP flag not enabled #endif - int main(int argc, char **argv) { }" HAVE_SSE2) + int main(int argc, char **argv) { return 0; }" HAVE_SSE2) if(HAVE_SSE2) list(APPEND EXTRA_CFLAGS "-msse2") endif() set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) endif() - if(SSE3) + if(SDL_SSE3) set(CMAKE_REQUIRED_FLAGS "-msse3") check_c_source_compiles(" #ifdef __MINGW32__ @@ -646,40 +720,41 @@ if(ASSEMBLY) #ifndef __SSE3__ #error Assembler CPP flag not enabled #endif - int main(int argc, char **argv) { }" HAVE_SSE3) + int main(int argc, char **argv) { return 0; }" HAVE_SSE3) if(HAVE_SSE3) list(APPEND EXTRA_CFLAGS "-msse3") endif() set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) endif() - if(NOT SSEMATH) - if(SSE OR SSE2 OR SSE3) + if(NOT SDL_SSEMATH) + if(SDL_SSE OR SDL_SSE2 OR SDL_SSE3) if(USE_GCC) check_c_compiler_flag(-mfpmath=387 HAVE_FP_387) if(HAVE_FP_387) list(APPEND EXTRA_CFLAGS "-mfpmath=387") endif() endif() - set(HAVE_SSEMATH TRUE) endif() + else() + set(HAVE_SSEMATH TRUE) endif() check_include_file("immintrin.h" HAVE_IMMINTRIN_H) - if(ALTIVEC) + if(SDL_ALTIVEC) set(CMAKE_REQUIRED_FLAGS "-maltivec") check_c_source_compiles(" #include vector unsigned int vzero() { return vec_splat_u32(0); } - int main(int argc, char **argv) { }" HAVE_ALTIVEC_H_HDR) + int main(int argc, char **argv) { return 0; }" HAVE_ALTIVEC_H_HDR) check_c_source_compiles(" vector unsigned int vzero() { return vec_splat_u32(0); } - int main(int argc, char **argv) { }" HAVE_ALTIVEC) + int main(int argc, char **argv) { return 0; }" HAVE_ALTIVEC) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) if(HAVE_ALTIVEC OR HAVE_ALTIVEC_H_HDR) set(HAVE_ALTIVEC TRUE) # if only HAVE_ALTIVEC_H_HDR is set @@ -691,7 +766,7 @@ if(ASSEMBLY) endif() endif() - if(ARMSIMD) + if(SDL_ARMSIMD) set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -x assembler-with-cpp") check_c_source_compiles(" @@ -717,7 +792,7 @@ if(ASSEMBLY) endif() endif() - if(ARMNEON) + if(SDL_ARMNEON) set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -x assembler-with-cpp") check_c_source_compiles(" @@ -755,18 +830,14 @@ if(ASSEMBLY) set(HAVE_SSE TRUE) set(HAVE_SSE2 TRUE) set(HAVE_SSE3 TRUE) + check_include_file("immintrin.h" HAVE_IMMINTRIN_H) set(SDL_ASSEMBLY_ROUTINES 1) endif() -# TODO: -#else() -# if(USE_GCC OR USE_CLANG) -# list(APPEND EXTRA_CFLAGS "-mno-sse" "-mno-sse2" "-mno-sse3" "-mno-mmx") -# endif() endif() # TODO: Can't deactivate on FreeBSD? w/o LIBC, SDL_stdinc.h can't define # anything. -if(LIBC) +if(SDL_LIBC) if(WINDOWS AND NOT MINGW) set(HAVE_LIBC TRUE) foreach(_HEADER stdio.h string.h wchar.h ctype.h math.h limits.h) @@ -777,28 +848,26 @@ if(LIBC) set(HAVE_SIGNAL_H 1) foreach(_FN malloc calloc realloc free qsort abs memset memcpy memmove memcmp - wcslen wcsdup wcsstr wcscmp wcsncmp _wcsicmp _wcsnicmp + wcslen _wcsdup wcsdup wcsstr wcscmp wcsncmp _wcsicmp _wcsnicmp strlen _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _ultoa strtol strtoul strtoll strtod atoi atof strcmp strncmp - _stricmp _strnicmp strtok_s sscanf + _stricmp _strnicmp sscanf acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf - log logf log10 log10f pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf - trunc truncf) + log logf log10 log10f lround lroundf pow powf round roundf scalbn scalbnf + sin sinf sqrt sqrtf tan tanf trunc truncf) string(TOUPPER ${_FN} _UPPER) set(HAVE_${_UPPER} 1) endforeach() - if(NOT CYGWIN AND NOT MINGW) - set(HAVE_ALLOCA 1) - endif() + set(HAVE_ALLOCA 1) set(HAVE_M_PI 1) - add_definitions(-D_USE_MATH_DEFINES) # needed for M_PI + target_compile_definitions(sdl-build-options INTERFACE "-D_USE_MATH_DEFINES") # needed for M_PI set(STDC_HEADERS 1) else() set(HAVE_LIBC TRUE) check_include_file(sys/types.h HAVE_SYS_TYPES_H) foreach(_HEADER - stdio.h stdlib.h stddef.h stdarg.h malloc.h memory.h string.h limits.h + stdio.h stdlib.h stddef.h stdarg.h malloc.h memory.h string.h limits.h float.h strings.h wchar.h inttypes.h stdint.h ctype.h math.h iconv.h signal.h libunwind.h) string(TOUPPER "HAVE_${_HEADER}" _UPPER) string(REPLACE "." "_" _HAVE_H ${_UPPER}) @@ -812,14 +881,14 @@ if(LIBC) # TODO: refine the mprotect check check_c_source_compiles("#include #include - int main() { }" HAVE_MPROTECT) + int main(void) { return 0; }" HAVE_MPROTECT) foreach(_FN strtod malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove memcmp strlen strlcpy strlcat - _strrev _strupr _strlwr strchr strrchr strstr strtok_r itoa _ltoa - _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull + _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r + itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp - wcscmp wcsdup wcslcat wcslcpy wcslen wcsncmp wcsstr + wcscmp _wcsdup wcsdup wcslcat wcslcpy wcslen wcsncmp wcsstr wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp sscanf vsscanf vsnprintf fopen64 fseeko fseeko64 _Exit ) @@ -843,23 +912,27 @@ if(LIBC) foreach(_FN atan atan2 atanf atan2f ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf log logf log10 log10f - pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf acos acosf - asin asinf trunc truncf) + lround lroundf pow powf round roundf scalbn scalbnf sin sinf sqrt + sqrtf tan tanf acos acosf asin asinf trunc truncf) string(TOUPPER ${_FN} _UPPER) set(_HAVEVAR "HAVE_${_UPPER}") check_symbol_exists("${_FN}" "math.h" ${_HAVEVAR}) endforeach() set(CMAKE_REQUIRED_LIBRARIES) - list(APPEND EXTRA_LIBS m) + if(NOT VITA) + list(APPEND EXTRA_LIBS m) + endif() endif() check_library_exists(iconv iconv_open "" HAVE_LIBICONV) - check_library_exists(c iconv_open "" HAVE_BUILTIN_ICONV) - if(HAVE_BUILTIN_ICONV) - set(HAVE_ICONV 1) - elseif(HAVE_LIBICONV) + if(HAVE_LIBICONV) list(APPEND EXTRA_LIBS iconv) set(HAVE_ICONV 1) + else() + check_library_exists(c iconv_open "" HAVE_BUILTIN_ICONV) + if(HAVE_BUILTIN_ICONV) + set(HAVE_ICONV 1) + endif() endif() if(NOT APPLE) @@ -892,10 +965,6 @@ foreach(_SUB ${SDL_SUBSYSTEMS}) set(SDL_${_OPT}_DISABLED 1) endif() endforeach() -if(SDL_JOYSTICK) - file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES}) -endif() if(SDL_HAPTIC) if(NOT SDL_JOYSTICK) # Haptic requires some private functions from the joystick subsystem. @@ -904,37 +973,44 @@ if(SDL_HAPTIC) endif() -# TODO: in configure.ac, the test for LOADSO and SDL_DLOPEN is a bit weird: -# if LOADSO is not wanted, SDL_LOADSO_DISABLED is set -# If however on Unix or APPLE dlopen() is detected via CheckDLOPEN(), -# SDL_LOADSO_DISABLED will not be set, regardless of the LOADSO settings - # General SDL subsystem options, valid for all platforms if(SDL_AUDIO) # CheckDummyAudio/CheckDiskAudio - valid for all platforms - if(DUMMYAUDIO) + if(SDL_DUMMYAUDIO) set(SDL_AUDIO_DRIVER_DUMMY 1) file(GLOB DUMMYAUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/dummy/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${DUMMYAUDIO_SOURCES}) set(HAVE_DUMMYAUDIO TRUE) + set(HAVE_SDL_AUDIO TRUE) endif() - if(DISKAUDIO) + if(SDL_DISKAUDIO) set(SDL_AUDIO_DRIVER_DISK 1) file(GLOB DISKAUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/disk/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${DISKAUDIO_SOURCES}) set(HAVE_DISKAUDIO TRUE) + set(HAVE_SDL_AUDIO TRUE) endif() endif() -if(SDL_DLOPEN) +if(UNIX OR APPLE) # Relevant for Unix/Darwin only - if(UNIX OR APPLE) - CheckDLOPEN() + set(DYNAPI_NEEDS_DLOPEN 1) + CheckDLOPEN() + if(SDL_LOADSO AND HAVE_DLOPEN) + set(SDL_LOADSO_DLOPEN 1) + file(GLOB DLOPEN_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/dlopen/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${DLOPEN_SOURCES}) + set(HAVE_SDL_LOADSO TRUE) endif() endif() +if(UNIX OR APPLE OR HAIKU OR RISCOS) + CheckO_CLOEXEC() +endif() + if(SDL_JOYSTICK) - if(JOYSTICK_VIRTUAL) + if(SDL_VIRTUAL_JOYSTICK) + set(HAVE_VIRTUAL_JOYSTICK TRUE) set(SDL_JOYSTICK_VIRTUAL 1) file(GLOB JOYSTICK_VIRTUAL_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/virtual/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_VIRTUAL_SOURCES}) @@ -942,18 +1018,18 @@ if(SDL_JOYSTICK) endif() if(SDL_VIDEO) - if(VIDEO_DUMMY) + if(SDL_DUMMYVIDEO) set(SDL_VIDEO_DRIVER_DUMMY 1) file(GLOB VIDEO_DUMMY_SOURCES ${SDL2_SOURCE_DIR}/src/video/dummy/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${VIDEO_DUMMY_SOURCES}) - set(HAVE_VIDEO_DUMMY TRUE) + set(HAVE_DUMMYVIDEO TRUE) set(HAVE_SDL_VIDEO TRUE) endif() - if(VIDEO_OFFSCREEN) + if(SDL_OFFSCREEN) set(SDL_VIDEO_DRIVER_OFFSCREEN 1) file(GLOB VIDEO_OFFSCREEN_SOURCES ${SDL2_SOURCE_DIR}/src/video/offscreen/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${VIDEO_OFFSCREEN_SOURCES}) - set(HAVE_VIDEO_OFFSCREEN TRUE) + set(HAVE_OFFSCREEN TRUE) set(HAVE_SDL_VIDEO TRUE) endif() endif() @@ -963,9 +1039,11 @@ if(ANDROID) file(GLOB ANDROID_CORE_SOURCES ${SDL2_SOURCE_DIR}/src/core/android/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_CORE_SOURCES} ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c) - file(GLOB ANDROID_MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/android/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_MISC_SOURCES}) - set(HAVE_SDL_MISC TRUE) + if(SDL_MISC) + file(GLOB ANDROID_MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/android/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() # SDL_spinlock.c Needs to be compiled in ARM mode. # There seems to be no better way currently to set the ARM mode. @@ -983,6 +1061,18 @@ if(ANDROID) set(SDL_AUDIO_DRIVER_ANDROID 1) file(GLOB ANDROID_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/android/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_AUDIO_SOURCES}) + + set(SDL_AUDIO_DRIVER_OPENSLES 1) + file(GLOB OPENSLES_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/openslES/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${OPENSLES_AUDIO_SOURCES}) + + find_library(ANDROID_OPENSLES_LIBRARY OpenSLES) + list(APPEND EXTRA_LIBS ${ANDROID_DL_LIBRARY} ${ANDROID_OPENSLES_LIBRARY}) + + set(SDL_AUDIO_DRIVER_AAUDIO 1) + file(GLOB AAUDIO_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/aaudio/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${AAUDIO_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) endif() if(SDL_FILESYSTEM) @@ -997,8 +1087,10 @@ if(ANDROID) set(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_HAPTIC_SOURCES}) set(HAVE_SDL_HAPTIC TRUE) endif() - if(SDL_JOYSTICK) + if(SDL_HIDAPI) CheckHIDAPI() + endif() + if(SDL_JOYSTICK) set(SDL_JOYSTICK_ANDROID 1) file(GLOB ANDROID_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/android/*.c ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_JOYSTICK_SOURCES}) @@ -1046,16 +1138,12 @@ if(ANDROID) find_library(ANDROID_LOG_LIBRARY log) find_library(ANDROID_LIBRARY_LIBRARY android) list(APPEND EXTRA_LIBS ${ANDROID_DL_LIBRARY} ${ANDROID_LOG_LIBRARY} ${ANDROID_LIBRARY_LIBRARY}) - add_definitions(-DGL_GLEXT_PROTOTYPES) - - if (HAVE_HIDAPI) - list(APPEND EXTRA_LIBS hidapi) - endif() + target_compile_definitions(sdl-build-options INTERFACE "-DGL_GLEXT_PROTOTYPES") #enable gles - if(VIDEO_OPENGLES) + if(SDL_OPENGLES) set(SDL_VIDEO_OPENGL_EGL 1) - set(HAVE_VIDEO_OPENGLES TRUE) + set(HAVE_OPENGLES TRUE) set(SDL_VIDEO_OPENGL_ES 1) set(SDL_VIDEO_RENDER_OGL_ES 1) set(SDL_VIDEO_OPENGL_ES2 1) @@ -1066,18 +1154,17 @@ if(ANDROID) list(APPEND EXTRA_LIBS ${OpenGLES1_LIBRARY} ${OpenGLES2_LIBRARY}) endif() - CHECK_C_SOURCE_COMPILES(" - #if defined(__ARM_ARCH) && __ARM_ARCH < 7 - #error Vulkan doesn't work on this configuration - #endif - int main() - { - return 0; - } - " VULKAN_PASSED_ANDROID_CHECKS) - if(NOT VULKAN_PASSED_ANDROID_CHECKS) - set(VIDEO_VULKAN OFF) - message(STATUS "Vulkan doesn't work on this configuration") + if(SDL_VULKAN) + CHECK_C_SOURCE_COMPILES(" + #if defined(__ARM_ARCH) && __ARM_ARCH < 7 + #error Vulkan doesn't work on this configuration + #endif + int main(int argc, char **argv) { return 0; } + " VULKAN_PASSED_ANDROID_CHECKS) + if(VULKAN_PASSED_ANDROID_CHECKS) + set(SDL_VIDEO_VULKAN 1) + set(HAVE_VULKAN TRUE) + endif() endif() endif() @@ -1086,7 +1173,13 @@ if(ANDROID) elseif(EMSCRIPTEN) # Hide noisy warnings that intend to aid mostly during initial stages of porting a new # project. Uncomment at will for verbose cross-compiling -I/../ path info. - add_definitions(-Wno-warn-absolute-paths) + target_compile_options(sdl-build-options INTERFACE "-Wno-warn-absolute-paths") + + if(SDL_MISC) + file(GLOB EMSRIPTEN_MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/emscripten/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${EMSRIPTEN_MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() if(SDL_AUDIO) set(SDL_AUDIO_DRIVER_EMSCRIPTEN 1) file(GLOB EM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/emscripten/*.c) @@ -1122,7 +1215,7 @@ elseif(EMSCRIPTEN) set(SOURCE_FILES ${SOURCE_FILES} ${TIMER_SOURCES}) set(HAVE_SDL_TIMERS TRUE) - if(CLOCK_GETTIME) + if(SDL_CLOCK_GETTIME) set(HAVE_CLOCK_GETTIME 1) endif() endif() @@ -1133,15 +1226,17 @@ elseif(EMSCRIPTEN) set(HAVE_SDL_VIDEO TRUE) #enable gles - if(VIDEO_OPENGLES) + if(SDL_OPENGLES) set(SDL_VIDEO_OPENGL_EGL 1) - set(HAVE_VIDEO_OPENGLES TRUE) + set(HAVE_OPENGLES TRUE) set(SDL_VIDEO_OPENGL_ES2 1) set(SDL_VIDEO_RENDER_OGL_ES2 1) endif() endif() -elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) + CheckPTHREAD() + +elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS AND NOT HAIKU) if(SDL_AUDIO) if(SYSV5 OR SOLARIS OR HPUX) set(SDL_AUDIO_DRIVER_SUNAUDIO 1) @@ -1162,6 +1257,7 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) CheckOSS() CheckALSA() CheckJACK() + CheckPipewire() CheckPulseAudio() CheckESD() CheckARTS() @@ -1176,36 +1272,52 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) CheckRPI() CheckX11() CheckDirectFB() - CheckOpenGLX11() - CheckOpenGLESX11() + # Need to check for EGL first because KMSDRM and Wayland depends on it. + CheckEGL() + CheckKMSDRM() + CheckGLX() + CheckOpenGL() + CheckOpenGLES() CheckWayland() CheckVivante() - CheckKMSDRM() + # FIXME: implement CheckVulkan() + if(SDL_VULKAN) + set(SDL_VIDEO_VULKAN 1) + set(HAVE_VULKAN TRUE) + endif() endif() if(UNIX) file(GLOB CORE_UNIX_SOURCES ${SDL2_SOURCE_DIR}/src/core/unix/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${CORE_UNIX_SOURCES}) - endif() - if(LINUX) check_c_source_compiles(" #include #ifndef EVIOCGNAME #error EVIOCGNAME() ioctl not available #endif - int main(int argc, char** argv) {}" HAVE_INPUT_EVENTS) + int main(int argc, char** argv) { return 0; }" HAVE_INPUT_EVENTS) - check_c_source_compiles(" - #include - #include - - int main(int argc, char **argv) - { - struct kbentry kbe; - kbe.kb_table = KG_CTRL; - ioctl(0, KDGKBENT, &kbe); - }" HAVE_INPUT_KD) + if(LINUX) + check_c_source_compiles(" + #include + #include + int main(int argc, char **argv) { + struct kbentry kbe; + kbe.kb_table = KG_CTRL; + ioctl(0, KDGKBENT, &kbe); + return 0; + }" HAVE_INPUT_KD) + elseif(FREEBSD) + check_c_source_compiles(" + #include + #include + int main(int argc, char **argv) { + accentmap_t accTable; + ioctl(0, KDENABIO, 1); + return 0; + }" HAVE_INPUT_KBIO) + endif() if(HAVE_INPUT_EVENTS) set(SDL_INPUT_LINUXEV 1) @@ -1222,10 +1334,15 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) set(SDL_INPUT_LINUXKD 1) endif() + if(HAVE_INPUT_KBIO) + set(SDL_INPUT_FBSDKBIO 1) + endif() + check_include_file("libudev.h" HAVE_LIBUDEV_H) check_include_file("sys/inotify.h" HAVE_SYS_INOTIFY_H) check_symbol_exists(inotify_init "sys/inotify.h" HAVE_INOTIFY_INIT) check_symbol_exists(inotify_init1 "sys/inotify.h" HAVE_INOTIFY_INIT1) + if(HAVE_SYS_INOTIFY_H AND HAVE_INOTIFY_INIT) set(HAVE_INOTIFY 1) endif() @@ -1234,7 +1351,7 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) pkg_search_module(DBUS dbus-1 dbus) if(DBUS_FOUND) set(HAVE_DBUS_DBUS_H TRUE) - include_directories(${DBUS_INCLUDE_DIRS}) + target_include_directories(sdl-build-options INTERFACE "${DBUS_INCLUDE_DIRS}") list(APPEND EXTRA_LIBS ${DBUS_LIBRARIES}) # Fcitx need only dbus. set(HAVE_FCITX TRUE) @@ -1243,18 +1360,27 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) pkg_search_module(IBUS ibus-1.0 ibus) if(IBUS_FOUND) set(HAVE_IBUS_IBUS_H TRUE) - include_directories(${IBUS_INCLUDE_DIRS}) + target_include_directories(sdl-build-options INTERFACE "${IBUS_INCLUDE_DIRS}") list(APPEND EXTRA_LIBS ${IBUS_LIBRARIES}) endif() if (HAVE_IBUS_IBUS_H OR HAVE_FCITX) - set(SDL_USE_IME TRUE) - add_definitions(-DSDL_USE_IME) # !!! FIXME: why isn't this a definition and not in SDL_config.h.cmake? + set(SDL_USE_IME 1) endif() + + if(FREEBSD AND NOT HAVE_INOTIFY) + pkg_search_module(INOTIFY libinotify) + if(INOTIFY_FOUND) + set(HAVE_INOTIFY 1) + target_include_directories(sdl-build-options INTERFACE "${INOTIFY_INCLUDE_DIRS}") + list(APPEND EXTRA_LIBS ${INOTIFY_LIBRARIES}) + endif() + endif() + if(HAVE_LIBUNWIND_H) # We've already found the header, so REQUIRE the lib to be present pkg_search_module(UNWIND REQUIRED libunwind) - pkg_search_module(UNWIND_GENERIC REQUIRED libunwind-generic) + pkg_search_module(UNWIND_GENERIC libunwind-generic) list(APPEND EXTRA_LIBS ${UNWIND_LIBRARIES} ${UNWIND_GENERIC_LIBRARIES}) endif() endif() @@ -1284,6 +1410,10 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) set(SOURCE_FILES ${SOURCE_FILES} "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_kbd.c") endif() + if(HAVE_INPUT_KBIO) + set(SOURCE_FILES ${SOURCE_FILES} "${SDL2_SOURCE_DIR}/src/core/freebsd/SDL_evdev_kbd_freebsd.c") + endif() + # Always compiled for Linux, unconditionally: set(SOURCE_FILES ${SOURCE_FILES} "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_capabilities.c") set(SOURCE_FILES ${SOURCE_FILES} "${SDL2_SOURCE_DIR}/src/core/linux/SDL_threadprio.c") @@ -1291,11 +1421,14 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) # src/core/unix/*.c is included in a generic if(UNIX) section, elsewhere. endif() + if(SDL_HIDAPI) + CheckHIDAPI() + endif() + if(SDL_JOYSTICK) if(FREEBSD OR NETBSD OR OPENBSD OR BSDI) CheckUSBHID() endif() - CheckHIDAPI() if(LINUX AND NOT ANDROID) set(SDL_JOYSTICK_LINUX 1) file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/linux/*.c ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c) @@ -1306,7 +1439,7 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) CheckPTHREAD() - if(CLOCK_GETTIME) + if(SDL_CLOCK_GETTIME) check_library_exists(rt clock_gettime "" FOUND_CLOCK_GETTIME) if(FOUND_CLOCK_GETTIME) list(APPEND EXTRA_LIBS rt) @@ -1324,9 +1457,11 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_LINUX_VERSION_H") endif() - file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/unix/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) - set(HAVE_SDL_MISC TRUE) + if(SDL_MISC) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/unix/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() if(SDL_POWER) if(LINUX) @@ -1358,7 +1493,7 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) endif() set(SDL_RLD_FLAGS "") - if(RPATH AND SDL_SHARED) + if(SDL_RPATH AND SDL_SHARED) if(BSDI OR FREEBSD OR LINUX OR NETBSD) set(CMAKE_REQUIRED_FLAGS "-Wl,--enable-new-dtags") check_c_compiler_flag("" HAVE_ENABLE_NEW_DTAGS) @@ -1380,7 +1515,7 @@ elseif(WINDOWS) check_c_source_compiles(" #include - int main(int argc, char **argv) { }" HAVE_WIN32_CC) + int main(int argc, char **argv) { return 0; }" HAVE_WIN32_CC) file(GLOB CORE_SOURCES ${SDL2_SOURCE_DIR}/src/core/windows/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${CORE_SOURCES}) @@ -1390,7 +1525,7 @@ elseif(WINDOWS) list(APPEND SOURCE_FILES ${WINRT_SOURCE_FILES}) endif() - if(MSVC) + if(MSVC AND NOT SDL_LIBC) # Prevent codegen that would use the VC runtime libraries. set_property(DIRECTORY . APPEND PROPERTY COMPILE_OPTIONS "/GS-") if(NOT ARCH_64) @@ -1398,42 +1533,28 @@ elseif(WINDOWS) endif() endif() - file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/windows/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) - set(HAVE_SDL_MISC TRUE) + if(SDL_MISC) + if(WINDOWS_STORE) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/winrt/*.cpp) + else() + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/windows/*.c) + endif() + set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() # Check for DirectX - if(DIRECTX) + if(SDL_DIRECTX) if(DEFINED MSVC_VERSION AND NOT ${MSVC_VERSION} LESS 1700) set(USE_WINSDK_DIRECTX TRUE) endif() - if(NOT CMAKE_COMPILER_IS_MINGW AND NOT USE_WINSDK_DIRECTX) + if(NOT MINGW AND NOT USE_WINSDK_DIRECTX) if("$ENV{DXSDK_DIR}" STREQUAL "") message_error("DIRECTX requires the \$DXSDK_DIR environment variable to be set") endif() set(CMAKE_REQUIRED_FLAGS "/I\"$ENV{DXSDK_DIR}\\Include\"") endif() - if(HAVE_WIN32_CC) - # xinput.h may need windows.h, but doesn't include it itself. - check_c_source_compiles(" - #include - #include - int main(int argc, char **argv) { }" HAVE_XINPUT_H) - check_c_source_compiles(" - #include - #include - XINPUT_GAMEPAD_EX x1; - int main(int argc, char **argv) { }" HAVE_XINPUT_GAMEPAD_EX) - check_c_source_compiles(" - #include - #include - XINPUT_STATE_EX s1; - int main(int argc, char **argv) { }" HAVE_XINPUT_STATE_EX) - else() - check_include_file(xinput.h HAVE_XINPUT_H) - endif() - check_include_file(d3d9.h HAVE_D3D_H) check_include_file(d3d11_1.h HAVE_D3D11_H) check_include_file(ddraw.h HAVE_DDRAW_H) @@ -1445,38 +1566,68 @@ elseif(WINDOWS) check_include_file(dxgi.h HAVE_DXGI_H) if(HAVE_D3D_H OR HAVE_D3D11_H OR HAVE_DDRAW_H OR HAVE_DSOUND_H OR HAVE_DINPUT_H) set(HAVE_DIRECTX TRUE) - if(NOT CMAKE_COMPILER_IS_MINGW AND NOT USE_WINSDK_DIRECTX) + if(NOT MINGW AND NOT USE_WINSDK_DIRECTX) # TODO: change $ENV{DXSDL_DIR} to get the path from the include checks - link_directories($ENV{DXSDK_DIR}\\lib\\${PROCESSOR_ARCH}) - include_directories($ENV{DXSDK_DIR}\\Include) + target_link_directories(sdl-build-options INTERFACE "$$ENV{DXSDK_DIR}\\lib\\${PROCESSOR_ARCH}") + target_include_directories(sdl-build-options INTERFACE "$ENV{DXSDK_DIR}\\Include") endif() endif() set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) endif() + if(SDL_XINPUT) + # xinput.h may need windows.h, but does not include it itself. + check_c_source_compiles(" + #include + #include + int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_H) + check_c_source_compiles(" + #include + #include + XINPUT_GAMEPAD_EX x1; + int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_GAMEPAD_EX) + check_c_source_compiles(" + #include + #include + XINPUT_STATE_EX s1; + int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_STATE_EX) + check_c_source_compiles(" + #define COBJMACROS + #include + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2 *s2; + int main(int argc, char **argv) { return 0; }" HAVE_WINDOWS_GAMING_INPUT_H) + endif() + # headers needed elsewhere + check_include_file(tpcshrd.h HAVE_TPCSHRD_H) check_include_file(mmdeviceapi.h HAVE_MMDEVICEAPI_H) check_include_file(audioclient.h HAVE_AUDIOCLIENT_H) check_include_file(sensorsapi.h HAVE_SENSORSAPI_H) if(SDL_AUDIO) if(NOT WINDOWS_STORE) - set(SDL_AUDIO_DRIVER_WINMM 1) - file(GLOB WINMM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/winmm/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${WINMM_AUDIO_SOURCES}) + set(SDL_AUDIO_DRIVER_WINMM 1) + file(GLOB WINMM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/winmm/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${WINMM_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) endif() - set(HAVE_SDL_AUDIO TRUE) if(HAVE_DSOUND_H AND NOT WINDOWS_STORE) set(SDL_AUDIO_DRIVER_DSOUND 1) file(GLOB DSOUND_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/directsound/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${DSOUND_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) endif() - if(WASAPI AND HAVE_AUDIOCLIENT_H AND HAVE_MMDEVICEAPI_H AND NOT WINDOWS_STORE) + if(SDL_WASAPI AND HAVE_AUDIOCLIENT_H AND HAVE_MMDEVICEAPI_H) set(SDL_AUDIO_DRIVER_WASAPI 1) + set(HAVE_WASAPI TRUE) file(GLOB WASAPI_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/wasapi/*.c) + if(WINDOWS_STORE) + list(APPEND WASAPI_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/wasapi/SDL_wasapi_winrt.cpp) + endif() set(SOURCE_FILES ${SOURCE_FILES} ${WASAPI_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) endif() endif() @@ -1488,21 +1639,21 @@ elseif(WINDOWS) if(WINDOWS_STORE) set(SDL_VIDEO_DRIVER_WINRT 1) file(GLOB WIN_VIDEO_SOURCES - ${SDL2_SOURCE_DIR}/src/video/winrt/*.c + ${SDL2_SOURCE_DIR}/src/video/winrt/*.c ${SDL2_SOURCE_DIR}/src/video/winrt/*.cpp ${SDL2_SOURCE_DIR}/src/render/direct3d11/*.cpp ) else() - set(SDL_VIDEO_DRIVER_WINDOWS 1) - file(GLOB WIN_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/windows/*.c) + set(SDL_VIDEO_DRIVER_WINDOWS 1) + file(GLOB WIN_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/windows/*.c) endif() set(SOURCE_FILES ${SOURCE_FILES} ${WIN_VIDEO_SOURCES}) - if(RENDER_D3D AND HAVE_D3D_H AND NOT WINDOWS_STORE) + if(SDL_RENDER_D3D AND HAVE_D3D_H AND NOT WINDOWS_STORE) set(SDL_VIDEO_RENDER_D3D 1) set(HAVE_RENDER_D3D TRUE) endif() - if(RENDER_D3D AND HAVE_D3D11_H) + if(SDL_RENDER_D3D AND HAVE_D3D11_H) set(SDL_VIDEO_RENDER_D3D11 1) set(HAVE_RENDER_D3D TRUE) endif() @@ -1510,17 +1661,19 @@ elseif(WINDOWS) endif() if(SDL_THREADS) + set(SDL_THREAD_GENERIC_COND_SUFFIX 1) set(SDL_THREAD_WINDOWS 1) set(SOURCE_FILES ${SOURCE_FILES} + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syscond.c + ${SDL2_SOURCE_DIR}/src/thread/windows/SDL_syscond_cv.c ${SDL2_SOURCE_DIR}/src/thread/windows/SDL_sysmutex.c ${SDL2_SOURCE_DIR}/src/thread/windows/SDL_syssem.c ${SDL2_SOURCE_DIR}/src/thread/windows/SDL_systhread.c - ${SDL2_SOURCE_DIR}/src/thread/windows/SDL_systls.c - ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syscond.c) + ${SDL2_SOURCE_DIR}/src/thread/windows/SDL_systls.c) set(HAVE_SDL_THREADS TRUE) endif() - if(SDL_SENSOR AND HAVE_SENSORSAPI_H) + if(SDL_SENSOR AND HAVE_SENSORSAPI_H AND NOT WINDOWS_STORE) set(SDL_SENSOR_WINDOWS 1) set(HAVE_SDL_SENSORS TRUE) file(GLOB WINDOWS_SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/windows/*.c) @@ -1539,7 +1692,11 @@ elseif(WINDOWS) endif() if(SDL_LOCALE) - file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/windows/*.c) + if(WINDOWS_STORE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/winrt/*.c) + else() + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/windows/*.c) + endif() set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) set(HAVE_SDL_LOCALE TRUE) endif() @@ -1560,8 +1717,15 @@ elseif(WINDOWS) list(APPEND EXTRA_LIBS user32 gdi32 winmm imm32 ole32 oleaut32 version uuid advapi32 setupapi shell32) endif() - # TODO: in configure.ac the check for timers is set on - # cygwin | mingw32* - does this include mingw32CE? + if(WINDOWS_STORE) + list(APPEND EXTRA_LIBS + -nodefaultlib:vccorlib$<$:d> + -nodefaultlib:msvcrt$<$:d> + vccorlib$<$:d>.lib + msvcrt$<$:d>.lib + ) + endif() + if(SDL_TIMERS) set(SDL_TIMER_WINDOWS 1) file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/windows/*.c) @@ -1580,43 +1744,54 @@ elseif(WINDOWS) set(SOURCE_FILES ${SOURCE_FILES} ${CORE_SOURCES}) if(SDL_VIDEO) - if(VIDEO_OPENGL AND NOT WINDOWS_STORE) + if(SDL_OPENGL AND NOT WINDOWS_STORE) set(SDL_VIDEO_OPENGL 1) set(SDL_VIDEO_OPENGL_WGL 1) set(SDL_VIDEO_RENDER_OGL 1) - set(HAVE_VIDEO_OPENGL TRUE) + set(HAVE_OPENGL TRUE) endif() - if(VIDEO_OPENGLES) + if(SDL_OPENGLES) set(SDL_VIDEO_OPENGL_EGL 1) set(SDL_VIDEO_OPENGL_ES2 1) set(SDL_VIDEO_RENDER_OGL_ES2 1) - set(HAVE_VIDEO_OPENGLES TRUE) + set(HAVE_OPENGLES TRUE) + endif() + + if(SDL_VULKAN) + set(SDL_VIDEO_VULKAN 1) + set(HAVE_VULKAN TRUE) endif() endif() - if(SDL_JOYSTICK) + if(SDL_HIDAPI) CheckHIDAPI() - # TODO: Remove this hid.c block when SDL_hidapi.c is supported on Windows! - if(HAVE_HIDAPI) - set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/windows/hid.c) - endif() + endif() + + if(SDL_JOYSTICK) file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/windows/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES}) + + if(NOT WINDOWS_STORE) + set(SDL_JOYSTICK_RAWINPUT 1) + endif() if(HAVE_DINPUT_H) set(SDL_JOYSTICK_DINPUT 1) list(APPEND EXTRA_LIBS dinput8) endif() if(HAVE_XINPUT_H) - set(SDL_JOYSTICK_XINPUT 1) - endif() - if(NOT HAVE_DINPUT_H AND NOT HAVE_XINPUT_H) - set(SDL_JOYSTICK_WINMM 1) + if(NOT WINDOWS_STORE) + set(SDL_JOYSTICK_XINPUT 1) + set(HAVE_XINPUT TRUE) + endif() + if(HAVE_WINDOWS_GAMING_INPUT_H) + set(SDL_JOYSTICK_WGI 1) + endif() endif() set(HAVE_SDL_JOYSTICK TRUE) if(SDL_HAPTIC) - if(HAVE_DINPUT_H OR HAVE_XINPUT_H) + if((HAVE_DINPUT_H OR HAVE_XINPUT_H) AND NOT WINDOWS_STORE) file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/windows/*.c) if(HAVE_DINPUT_H) set(SDL_HAPTIC_DINPUT 1) @@ -1638,8 +1813,11 @@ elseif(WINDOWS) if(MINGW OR CYGWIN) list(APPEND EXTRA_LIBS mingw32) list(APPEND EXTRA_LDFLAGS "-mwindows") - set(SDL_CFLAGS "${SDL_CFLAGS} -Dmain=SDL_main") - list(APPEND SDL_LIBS "-lmingw32" "-lSDL2main" "-mwindows") + list(APPEND SDL_LIBS "-lmingw32" "-mwindows") + if(NOT SDL2_DISABLE_SDL2MAIN) + set(SDL_CFLAGS "${SDL_CFLAGS} -Dmain=SDL_main") + list(APPEND SDL_LIBS "-lSDL2main") + endif(NOT SDL2_DISABLE_SDL2MAIN) endif() elseif(APPLE) @@ -1654,29 +1832,32 @@ elseif(APPLE) set(SDL_FRAMEWORK_CARBON 1) endif() set(SDL_FRAMEWORK_FOUNDATION 1) + set(SDL_FRAMEWORK_COREVIDEO 1) # Requires the darwin file implementation if(SDL_FILE) file(GLOB EXTRA_SOURCES ${SDL2_SOURCE_DIR}/src/file/cocoa/*.m) set(SOURCE_FILES ${EXTRA_SOURCES} ${SOURCE_FILES}) - # !!! FIXME: modern CMake doesn't need "LANGUAGE C" for Objective-C. - set_source_files_properties(${EXTRA_SOURCES} PROPERTIES LANGUAGE C) set(HAVE_SDL_FILE TRUE) - # !!! FIXME: why is COREVIDEO inside this if() block? - set(SDL_FRAMEWORK_COREVIDEO 1) - else() - message_error("SDL_FILE must be enabled to build on MacOS X") endif() - file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/macosx/*.m) - set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) - set(HAVE_SDL_MISC TRUE) + if(IOS OR TVOS) + file(GLOB SDLMAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/uikit/*.c) + endif() + + if(SDL_MISC) + if(IOS OR TVOS) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/ios/*.m) + else() + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/macosx/*.m) + endif() + set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() if(SDL_AUDIO) set(SDL_AUDIO_DRIVER_COREAUDIO 1) file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/coreaudio/*.m) - # !!! FIXME: modern CMake doesn't need "LANGUAGE C" for Objective-C. - set_source_files_properties(${AUDIO_SOURCES} PROPERTIES LANGUAGE C) set(SOURCE_FILES ${SOURCE_FILES} ${AUDIO_SOURCES}) set(HAVE_SDL_AUDIO TRUE) set(SDL_FRAMEWORK_COREAUDIO 1) @@ -1684,30 +1865,52 @@ elseif(APPLE) set(SDL_FRAMEWORK_AVFOUNDATION 1) endif() - if(SDL_JOYSTICK) + if(SDL_HIDAPI) CheckHIDAPI() - if(HAVE_HIDAPI) - if(IOS OR TVOS) - set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/ios/hid.m) - set(SDL_FRAMEWORK_COREBLUETOOTH 1) - endif() - endif() + endif() + + if(SDL_JOYSTICK) + file(GLOB MFI_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m) if(IOS OR TVOS) - file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c) + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c) set(SDL_JOYSTICK_MFI 1) if(IOS) set(SDL_FRAMEWORK_COREMOTION 1) endif() set(SDL_FRAMEWORK_GAMECONTROLLER 1) - set(HAVE_SDL_SENSORS 1) + set(SDL_FRAMEWORK_COREHAPTICS 1) else() - file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/darwin/*.c ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m) - # FIXME: add checks for SDL_JOYSTICK_MFI??? + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/darwin/*.c) + set_source_files_properties(${MFI_JOYSTICK_SOURCES} PROPERTIES COMPILE_FLAGS -fobjc-weak) + check_objc_source_compiles(" + #include + #include + #import + #import + #if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 + #error GameController framework doesn't work on this configuration + #endif + #if TARGET_CPU_X86 + #error GameController framework doesn't work on this configuration + #endif + int main() { return 0; }" HAVE_FRAMEWORK_GAMECONTROLLER) + check_objc_source_compiles(" + #include + #include + #import + #import + int main() { return 0; }" HAVE_FRAMEWORK_COREHAPTICS) + if(HAVE_FRAMEWORK_GAMECONTROLLER AND HAVE_FRAMEWORK_COREHAPTICS) + # Only enable MFI if we also have CoreHaptics to ensure rumble works + set(SDL_JOYSTICK_MFI 1) + set(SDL_FRAMEWORK_GAMECONTROLLER 1) + set(SDL_FRAMEWORK_COREHAPTICS 1) + endif() set(SDL_JOYSTICK_IOKIT 1) set(SDL_FRAMEWORK_IOKIT 1) set(SDL_FRAMEWORK_FF 1) endif() - set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES}) + set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES} ${MFI_JOYSTICK_SOURCES}) set(HAVE_SDL_JOYSTICK TRUE) endif() @@ -1723,9 +1926,6 @@ elseif(APPLE) endif() set(SOURCE_FILES ${SOURCE_FILES} ${HAPTIC_SOURCES}) set(HAVE_SDL_HAPTIC TRUE) - if(NOT SDL_JOYSTICK) - message(FATAL_ERROR "SDL_HAPTIC requires SDL_JOYSTICK to be enabled") - endif() endif() if(SDL_POWER) @@ -1757,8 +1957,6 @@ elseif(APPLE) if(SDL_FILESYSTEM) set(SDL_FILESYSTEM_COCOA 1) file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/cocoa/*.m) - # !!! FIXME: modern CMake doesn't need "LANGUAGE C" for Objective-C. - set_source_files_properties(${FILESYSTEM_SOURCES} PROPERTIES LANGUAGE C) set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES}) set(HAVE_SDL_FILESYSTEM TRUE) endif() @@ -1783,17 +1981,18 @@ elseif(APPLE) set(SDL_IPHONE_LAUNCHSCREEN 1) file(GLOB UIKITVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/uikit/*.m) set(SOURCE_FILES ${SOURCE_FILES} ${UIKITVIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) else() CheckCOCOA() - if(VIDEO_OPENGL) + if(SDL_OPENGL) set(SDL_VIDEO_OPENGL 1) set(SDL_VIDEO_OPENGL_CGL 1) set(SDL_VIDEO_RENDER_OGL 1) - set(HAVE_VIDEO_OPENGL TRUE) + set(HAVE_OPENGL TRUE) endif() endif() - if(VIDEO_OPENGLES) + if(SDL_OPENGLES) if(IOS OR TVOS) set(SDL_FRAMEWORK_OPENGLES 1) set(SDL_VIDEO_OPENGL_ES 1) @@ -1803,47 +2002,38 @@ elseif(APPLE) endif() set(SDL_VIDEO_OPENGL_ES2 1) set(SDL_VIDEO_RENDER_OGL_ES2 1) - set(HAVE_VIDEO_OPENGLES TRUE) + set(HAVE_OPENGLES TRUE) endif() - if(VIDEO_VULKAN OR VIDEO_METAL OR RENDER_METAL) - set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -ObjC") - check_c_source_compiles(" + if(SDL_VULKAN OR SDL_METAL OR SDL_RENDER_METAL) + check_objc_source_compiles(" #include #import #import - #if TARGET_OS_SIMULATOR || (!TARGET_CPU_X86_64 && !TARGET_CPU_ARM64) + #if (!TARGET_CPU_X86_64 && !TARGET_CPU_ARM64) #error Metal doesn't work on this configuration #endif - int main() - { - return 0; - } - " HAVE_FRAMEWORK_METAL) - set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + int main(int argc, char **argv) { return 0; }" HAVE_FRAMEWORK_METAL) if(HAVE_FRAMEWORK_METAL) set(SDL_FRAMEWORK_METAL 1) set(SDL_FRAMEWORK_QUARTZCORE 1) - else() - set(VIDEO_VULKAN 0) - set(VIDEO_METAL 0) - set(RENDER_METAL 0) + if(SDL_VULKAN) + set(SDL_VIDEO_VULKAN 1) + set(HAVE_VULKAN TRUE) + endif() + if(SDL_METAL) + set(SDL_VIDEO_METAL 1) + set(HAVE_METAL TRUE) + endif() + if(SDL_RENDER_METAL) + file(GLOB RENDER_METAL_SOURCES ${SDL2_SOURCE_DIR}/src/render/metal/*.m) + set(SOURCE_FILES ${SOURCE_FILES} ${RENDER_METAL_SOURCES}) + set(SDL_VIDEO_RENDER_METAL 1) + set(HAVE_RENDER_METAL TRUE) + endif() endif() endif() - - if(VIDEO_METAL) - set(SDL_VIDEO_METAL 1) - set(HAVE_VIDEO_METAL TRUE) - endif() - - if(RENDER_METAL) - file(GLOB RENDER_METAL_SOURCES ${SDL2_SOURCE_DIR}/src/render/metal/*.m) - set(SOURCE_FILES ${SOURCE_FILES} ${RENDER_METAL_SOURCES}) - set(SDL_VIDEO_RENDER_METAL 1) - set(HAVE_RENDER_METAL TRUE) - endif() endif() # Actually load the frameworks at the end so we don't duplicate include. @@ -1897,7 +2087,9 @@ elseif(APPLE) endif() if(SDL_FRAMEWORK_GAMECONTROLLER) find_library(GAMECONTROLLER GameController) - list(APPEND EXTRA_LIBS ${GAMECONTROLLER}) + if(GAMECONTROLLER) + list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,GameController") + endif() endif() if(SDL_FRAMEWORK_METAL) if(IOS OR TVOS) @@ -1923,34 +2115,58 @@ elseif(APPLE) find_library(UIKIT UIKit) list(APPEND EXTRA_LIBS ${UIKIT}) endif() + if(SDL_FRAMEWORK_COREHAPTICS) + find_library(COREHAPTICS CoreHaptics) + if(COREHAPTICS) + list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,CoreHaptics") + endif() + endif() CheckPTHREAD() elseif(HAIKU) - file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/haiku/*.cc) - set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) - set(HAVE_SDL_MISC TRUE) + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_HAIKU 1) + file(GLOB HAIKU_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/haiku/*.cc) + set(SOURCE_FILES ${SOURCE_FILES} ${HAIKU_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_HAIKU 1) + file(GLOB HAIKU_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/haiku/*.cc) + set(SOURCE_FILES ${SOURCE_FILES} ${HAIKU_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + + if(SDL_MISC) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/haiku/*.cc) + set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() if(SDL_VIDEO) set(SDL_VIDEO_DRIVER_HAIKU 1) - file(GLOB HAIKUVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/haiku/*.c) + file(GLOB HAIKUVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/haiku/*.cc) set(SOURCE_FILES ${SOURCE_FILES} ${HAIKUVIDEO_SOURCES}) set(HAVE_SDL_VIDEO TRUE) - if(VIDEO_OPENGL) + if(SDL_OPENGL) # TODO: Use FIND_PACKAGE(OpenGL) instead set(SDL_VIDEO_OPENGL 1) - set(SDL_VIDEO_OPENGL_BGL 1) + set(SDL_VIDEO_OPENGL_HAIKU 1) set(SDL_VIDEO_RENDER_OGL 1) list(APPEND EXTRA_LIBS GL) - set(HAVE_VIDEO_OPENGL TRUE) + set(HAVE_OPENGL TRUE) endif() endif() - set(SDL_FILESYSTEM_HAIKU 1) - file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/haiku/*.cc) - set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES}) - set(HAVE_SDL_FILESYSTEM TRUE) + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_HAIKU 1) + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/haiku/*.cc) + set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() if(SDL_TIMERS) set(SDL_TIMER_HAIKU 1) @@ -1959,18 +2175,45 @@ elseif(HAIKU) set(HAVE_SDL_TIMERS TRUE) endif() + if(SDL_POWER) + set(SDL_POWER_HAIKU 1) + file(GLOB HAIKU_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/haiku/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${HAIKU_POWER_SOURCES}) + set(HAVE_SDL_POWER TRUE) + endif() + if(SDL_LOCALE) file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/haiku/*.cc) set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) set(HAVE_SDL_LOCALE TRUE) endif() + file(GLOB MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/haiku/*.cc) + set(SOURCE_FILES ${SOURCE_FILES} ${MAIN_SOURCES}) + CheckPTHREAD() + list(APPEND EXTRA_LIBS root be media game device textencoding) elseif(RISCOS) - file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/riscos/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) - set(HAVE_SDL_MISC TRUE) + if(SDL_MISC) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/riscos/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() + + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_RISCOS 1) + file(GLOB RISCOSVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/riscos/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${RISCOSVIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + endif() + + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_RISCOS 1) + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/riscos/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() if(SDL_TIMERS) set(SDL_TIMER_UNIX 1) @@ -1978,7 +2221,7 @@ elseif(RISCOS) set(SOURCE_FILES ${SOURCE_FILES} ${TIMER_SOURCES}) set(HAVE_SDL_TIMERS TRUE) - if(CLOCK_GETTIME) + if(SDL_CLOCK_GETTIME) set(HAVE_CLOCK_GETTIME 1) endif() endif() @@ -1988,11 +2231,302 @@ elseif(RISCOS) if(SDL_AUDIO) CheckOSS() endif() + +elseif(VITA) + # SDL_spinlock.c Needs to be compiled in ARM mode. + check_c_compiler_flag(-marm HAVE_ARM_MODE) + if(HAVE_ARM_MODE) + set_source_files_properties(${SDL2_SOURCE_DIR}/src/atomic/SDL_spinlock.c PROPERTIES COMPILE_FLAGS -marm) + endif() + + if(SDL_MISC) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/vita/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() + + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_VITA 1) + file(GLOB VITA_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/vita/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${VITA_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_VITA 1) + file(GLOB VITA_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/vita/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${VITA_FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_VITA 1) + file(GLOB VITA_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/vita/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${VITA_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + if(SDL_POWER) + set(SDL_POWER_VITA 1) + file(GLOB VITA_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/vita/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${VITA_POWER_SOURCES}) + set(HAVE_SDL_POWER TRUE) + endif() + if(SDL_THREADS) + set(SDL_THREAD_VITA 1) + set(SOURCE_FILES ${SOURCE_FILES} + ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_sysmutex.c + ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_syssem.c + ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_systhread.c + ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_syscond.c + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c) + set(HAVE_SDL_THREADS TRUE) + endif() + if(SDL_TIMERS) + set(SDL_TIMER_VITA 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/vita/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + if(SDL_SENSOR) + set(SDL_SENSOR_VITA 1) + set(HAVE_SDL_SENSORS TRUE) + file(GLOB VITA_SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/vita/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${VITA_SENSOR_SOURCES}) + endif() + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_VITA 1) + file(GLOB VITA_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/vita/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${VITA_VIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + + if(VIDEO_VITA_PIB) + check_include_file(pib.h HAVE_PIGS_IN_BLANKET_H) + + if(HAVE_PIGS_IN_BLANKET_H) + set(SDL_VIDEO_OPENGL_ES2 1) + list(APPEND EXTRA_LIBS + pib + ) + set(HAVE_VITA_PIB ON) + set(SDL_VIDEO_VITA_PIB 1) + else() + set(HAVE_VITA_PIB OFF) + endif() + endif() + + if(VIDEO_VITA_PVR) + check_include_file(gpu_es4/psp2_pvr_hint.h HAVE_PVR_H) + if(HAVE_PVR_H) + target_compile_definitions(sdl-build-options INTERFACE "-D__psp2__") + set(SDL_VIDEO_OPENGL_EGL 1) + set(HAVE_OPENGLES TRUE) + set(SDL_VIDEO_OPENGL_ES 1) + set(SDL_VIDEO_RENDER_OGL_ES 1) + set(SDL_VIDEO_OPENGL_ES2 1) + set(SDL_VIDEO_RENDER_OGL_ES2 1) + + list(APPEND EXTRA_LIBS + libgpu_es4_ext_stub_weak + libIMGEGL_stub_weak + ) + set(HAVE_VITA_PVR ON) + set(SDL_VIDEO_VITA_PVR 1) + else() + set(HAVE_VITA_PVR OFF) + endif() + endif() + + set(SDL_VIDEO_RENDER_VITA_GXM 1) + + list(APPEND EXTRA_LIBS + SceGxm_stub + SceDisplay_stub + SceCtrl_stub + SceAppMgr_stub + SceAudio_stub + SceSysmodule_stub + SceDisplay_stub + SceCtrl_stub + SceIofilemgr_stub + SceCommonDialog_stub + SceTouch_stub + SceHid_stub + SceMotion_stub + ScePower_stub + SceProcessmgr_stub + m + ) + if(HAVE_VITA_PIB) + list(PREPEND EXTRA_LIBS + pib + libScePiglet_stub + SceShaccCg_stub + taihen_stub + ) + endif() + if(HAVE_VITA_PVR) + list(PREPEND EXTRA_LIBS + SceIme_stub + ) + endif() + endif() + +# set(HAVE_ARMSIMD TRUE) +# set(SDL_ARM_SIMD_BLITTERS 1) +# file(GLOB ARMSIMD_SOURCES ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-simd*.S) +# set(SOURCE_FILES ${SOURCE_FILES} ${ARMSIMD_SOURCES}) + +# set(HAVE_ARMNEON TRUE) +# set(SDL_ARM_NEON_BLITTERS 1) +# file(GLOB ARMNEON_SOURCES ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-neon*.S) +# set(SOURCE_FILES ${SOURCE_FILES} ${ARMNEON_SOURCES}) + +# set_property(SOURCE ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-simd-asm.S PROPERTY LANGUAGE C) +# set_property(SOURCE ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-neon-asm.S PROPERTY LANGUAGE C) + + target_compile_definitions(sdl-build-options INTERFACE "-D__VITA__") + target_compile_definitions(sdl-build-options INTERFACE "-Dmemcpy=sceClibMemcpy") + target_compile_definitions(sdl-build-options INTERFACE "-Dmemset=sceClibMemset") + target_compile_definitions(sdl-build-options INTERFACE "-Dmemmove=sceClibMemmove") + target_compile_definitions(sdl-build-options INTERFACE "-Dmemcmp=sceClibMemcmp") + +# CheckPTHREAD() + +elseif(PSP) + file(GLOB PSP_MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/psp/*.c) + set(SDLMAIN_SOURCES ${SDLMAIN_SOURCES} ${PSP_MAIN_SOURCES}) + + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_PSP 1) + file(GLOB PSP_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/psp/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${PSP_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_PSP 1) + file(GLOB PSP_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/psp/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${PSP_FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_PSP 1) + file(GLOB PSP_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/psp/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${PSP_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + if(SDL_POWER) + set(SDL_POWER_PSP 1) + file(GLOB PSP_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/psp/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${PSP_POWER_SOURCES}) + set(HAVE_SDL_POWER TRUE) + endif() + if(SDL_THREADS) + set(SDL_THREAD_PSP 1) + file(GLOB PSP_THREAD_SOURCES ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c ${SDL2_SOURCE_DIR}/src/thread/psp/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${PSP_THREAD_SOURCES}) + set(HAVE_SDL_THREADS TRUE) + endif() + if(SDL_TIMERS) + set(SDL_TIMER_PSP 1) + file(GLOB PSP_TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/psp/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${PSP_TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_PSP 1) + set(SDL_VIDEO_RENDER_PSP 1) + file(GLOB PSP_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/psp/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${PSP_VIDEO_SOURCES}) + set(SDL_VIDEO_OPENGL 1) + set(HAVE_SDL_VIDEO TRUE) + endif() + + list(APPEND EXTRA_LIBS + psppower + pspctrl + psphprm + pspge + pspgu + pspdisplay + pspvfpu + pspaudio + pspvram + GL + ) + +elseif(OS2) + list(APPEND EXTRA_CFLAGS "-DOS2EMX_PLAIN_CHAR") + + file(GLOB CORE_SOURCES ${SDL2_SOURCE_DIR}/src/core/os2/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${CORE_SOURCES}) + if(NOT (HAVE_ICONV AND HAVE_ICONV_H)) + file(GLOB CORE_SOURCES ${SDL2_SOURCE_DIR}/src/core/os2/geniconv/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${CORE_SOURCES}) + endif() + + if(SDL_THREADS) + set(SDL_THREAD_OS2 1) + file(GLOB OS2_THREAD_SOURCES ${SDL2_SOURCE_DIR}/src/thread/os2/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${OS2_THREAD_SOURCES}) + set(HAVE_SDL_THREADS TRUE) + endif() + + if(SDL_TIMERS) + set(SDL_TIMER_UNIX 1) + file(GLOB OS2_TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/os2/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${OS2_TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + + if(SDL_LOADSO) + set(SDL_LOADSO_OS2 1) + file(GLOB OS2_LOADSO_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/os2/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${OS2_LOADSO_SOURCES}) + set(HAVE_SDL_LOADSO TRUE) + endif() + + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_OS2 1) + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/os2/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/unix/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_OS2 1) + file(GLOB OS2_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/os2/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${OS2_VIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + endif() + + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_OS2 1) + file(GLOB OS2_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/os2/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${OS2_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + list(APPEND EXTRA_LIBS mmpm2) + endif() + + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_OS2 1) + file(GLOB OS2_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/os2/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${OS2_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + + if(SDL_HIDAPI) + CheckHIDAPI() + endif() endif() -if(VIDEO_VULKAN) - set(SDL_VIDEO_VULKAN 1) - set(HAVE_VIDEO_VULKAN TRUE) +if(HAVE_VULKAN AND NOT SDL_LOADSO) + message(STATUS "Vulkan support is available, but disabled because there's no loadso.") + set(HAVE_VULKAN FALSE) + set(SDL_VIDEO_VULKAN 0) endif() # Dummies @@ -2003,12 +2537,20 @@ endif() # so it always adds a dummy, without checking, if it was actually requested. # This leads to missing internal references on building, since the # src/X/*.c does not get included. +if(NOT HAVE_SDL_AUDIO) + set(SDL_AUDIO_DRIVER_DUMMY 1) + file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/dummy/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${AUDIO_SOURCES}) +endif() +if(NOT HAVE_SDL_VIDEO) + set(SDL_VIDEO_DRIVER_DUMMY 1) + file(GLOB VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/dummy/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${VIDEO_SOURCES}) +endif() if(NOT HAVE_SDL_JOYSTICK) set(SDL_JOYSTICK_DUMMY 1) - if(SDL_JOYSTICK AND NOT APPLE) # results in unresolved symbols on OSX - file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/dummy/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES}) - endif() + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/dummy/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES}) endif() if(NOT HAVE_SDL_HAPTIC) set(SDL_HAPTIC_DUMMY 1) @@ -2021,24 +2563,24 @@ if(NOT HAVE_SDL_SENSORS) set(SOURCE_FILES ${SOURCE_FILES} ${SENSORS_SOURCES}) endif() if(NOT HAVE_SDL_LOADSO) - set(SDL_LOADSO_DISABLED 1) + set(SDL_LOADSO_DUMMY 1) file(GLOB LOADSO_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/dummy/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${LOADSO_SOURCES}) endif() if(NOT HAVE_SDL_FILESYSTEM) - set(SDL_FILESYSTEM_DISABLED 1) + set(SDL_FILESYSTEM_DUMMY 1) file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/dummy/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES}) endif() if(NOT HAVE_SDL_LOCALE) - set(SDL_LOCALE_DISABLED 1) + set(SDL_LOCALE_DUMMY 1) file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/dummy/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) endif() if(NOT HAVE_SDL_MISC) - set(SDL_MISC_DISABLED 1) - file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/misc/dummy/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) + set(SDL_MISC_DUMMY 1) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/dummy/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) endif() # We always need to have threads and timers around @@ -2048,7 +2590,7 @@ if(NOT HAVE_SDL_THREADS) set(SOURCE_FILES ${SOURCE_FILES} ${THREADS_SOURCES}) endif() if(NOT HAVE_SDL_TIMERS) - set(SDL_TIMERS_DISABLED 1) + set(SDL_TIMER_DUMMY 1) file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/dummy/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${TIMER_SOURCES}) endif() @@ -2081,17 +2623,42 @@ listtostr(EXTRA_CFLAGS _EXTRA_CFLAGS) set(EXTRA_CFLAGS ${_EXTRA_CFLAGS}) # Compat helpers for the configuration files -if(NOT CMAKE_HOST_WIN32) - # TODO: we need a Windows script, too - execute_process(COMMAND sh ${SDL2_SOURCE_DIR}/build-scripts/updaterev.sh - WORKING_DIRECTORY ${SDL2_BINARY_DIR}) +find_package(Git) +if(Git_FOUND) + execute_process(COMMAND + "${GIT_EXECUTABLE}" remote get-url origin + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE GIT_URL_STATUS + OUTPUT_VARIABLE GIT_URL + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + + execute_process(COMMAND + "${GIT_EXECUTABLE}" rev-list --max-count=1 HEAD~.. + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE GIT_REVISION_STATUS + OUTPUT_VARIABLE GIT_REVISION + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(GIT_URL_STATUS EQUAL 0 OR GIT_REVISION_STATUS EQUAL 0) + set(SDL_REVISION "${GIT_URL}@${GIT_REVISION}") + else() + set(SDL_REVISION "") + endif() +else() + set(SDL_REVISION "") endif() -if(NOT WINDOWS OR CYGWIN) + +configure_file("${SDL2_SOURCE_DIR}/include/SDL_revision.h.cmake" + "${SDL2_BINARY_DIR}/include/SDL_revision.h") + +if(NOT WINDOWS OR CYGWIN OR MINGW) + set(prefix ${CMAKE_INSTALL_PREFIX}) + set(exec_prefix "\${prefix}") - set(libdir "\${exec_prefix}/lib${LIB_SUFFIX}") - set(bindir "\${exec_prefix}/bin") - set(includedir "\${prefix}/include") + set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}") + set(bindir "${CMAKE_INSTALL_FULL_BINDIR}") + set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}") if(SDL_STATIC) set(ENABLE_STATIC_TRUE "") set(ENABLE_STATIC_FALSE "#") @@ -2100,24 +2667,34 @@ if(NOT WINDOWS OR CYGWIN) set(ENABLE_STATIC_FALSE "") endif() if(SDL_SHARED) - set(PKG_CONFIG_LIBS_PRIV " + set(PKGCONFIG_LIBS_PRIV " Libs.private:") set(ENABLE_SHARED_TRUE "") set(ENABLE_SHARED_FALSE "#") else() - set(PKG_CONFIG_LIBS_PRIV "") + set(PKGCONFIG_LIBS_PRIV "") set(ENABLE_SHARED_TRUE "#") set(ENABLE_SHARED_FALSE "") endif() # Clean up the different lists - listtostr(EXTRA_LIBS _EXTRA_LIBS "-l") - set(SDL_STATIC_LIBS ${EXTRA_LDFLAGS} ${_EXTRA_LIBS}) - list(REMOVE_DUPLICATES SDL_STATIC_LIBS) - listtostr(SDL_STATIC_LIBS _SDL_STATIC_LIBS) - set(SDL_STATIC_LIBS ${_SDL_STATIC_LIBS}) - listtostr(SDL_LIBS _SDL_LIBS) - set(SDL_LIBS ${_SDL_LIBS}) + if (VITA) + listtostrrev(EXTRA_LIBS _EXTRA_LIBS "-l") + set(SDL_STATIC_LIBS ${SDL_LIBS} ${EXTRA_LDFLAGS} ${_EXTRA_LIBS}) + list(REMOVE_DUPLICATES SDL_STATIC_LIBS) + listtostrrev(SDL_STATIC_LIBS _SDL_STATIC_LIBS) + set(SDL_STATIC_LIBS ${_SDL_STATIC_LIBS}) + listtostrrev(SDL_LIBS _SDL_LIBS) + set(SDL_LIBS ${_SDL_LIBS}) + else() + listtostr(EXTRA_LIBS _EXTRA_LIBS "-l") + set(SDL_STATIC_LIBS ${SDL_LIBS} ${EXTRA_LDFLAGS} ${_EXTRA_LIBS}) + list(REMOVE_DUPLICATES SDL_STATIC_LIBS) + listtostr(SDL_STATIC_LIBS _SDL_STATIC_LIBS) + set(SDL_STATIC_LIBS ${_SDL_STATIC_LIBS}) + listtostr(SDL_LIBS _SDL_LIBS) + set(SDL_LIBS ${_SDL_LIBS}) + endif() # MESSAGE(STATUS "SDL_LIBS: ${SDL_LIBS}") # MESSAGE(STATUS "SDL_STATIC_LIBS: ${SDL_STATIC_LIBS}") @@ -2132,6 +2709,71 @@ Libs.private:") "${SDL2_BINARY_DIR}/SDL2.spec" @ONLY) endif() +macro(check_add_debug_flag FLAG SUFFIX) + check_c_compiler_flag(${FLAG} HAS_C_FLAG_${SUFFIX}) + if (HAS_C_FLAG_${SUFFIX}) + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAG}") + endif() + + check_cxx_compiler_flag(${FLAG} HAS_CXX_${SUFFIX}) + if (HAS_CXX_${SUFFIX}) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}") + endif() +endmacro() + +macro(asan_check_add_debug_flag ASAN_FLAG) + check_add_debug_flag("-fsanitize=${ASAN_FLAG}" "${ASAN_FLAG}") + if(HAS_C_${ASAN_FLAG} OR HAS_CXX_${ASAN_FLAG}) + set(HAVE_ASAN ON) + endif() +endmacro() + +macro(asan_check_add_debug_flag2 ASAN_FLAG) + # for some sanitize flags we have to manipulate the CMAKE_REQUIRED_LIBRARIES: + # http://cmake.3232098.n2.nabble.com/CHECK-CXX-COMPILER-FLAG-doesn-t-give-correct-result-for-fsanitize-address-tp7600216p7600217.html + + set(FLAG "-fsanitize=${ASAN_FLAG}") + + set (STORED_REQLIBS ${CMAKE_REQUIRED_LIBRARIES}) + set (CMAKE_REQUIRED_LIBRARIES "${FLAG};asan") + check_c_compiler_flag (${FLAG} HAS_C_FLAG_${ASAN_FLAG}) + check_cxx_compiler_flag (${FLAG} HAS_CXX_FLAG_${ASAN_FLAG}) + set (CMAKE_REQUIRED_LIBRARIES ${STORED_REQLIBS}) + + if (HAS_C_FLAG_${ASAN_FLAG}) + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAG}") + endif() + + if (HAS_CXX_${ASAN_FLAG}) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}") + endif() + + if(HAS_C_${ASAN_FLAG} OR HAS_CXX_${ASAN_FLAG}) + set(HAVE_ASAN ON) + endif() +endmacro() + +# enable AddressSanitizer if supported +if (SDL_ASAN) + asan_check_add_debug_flag2("address") + asan_check_add_debug_flag("bool") + asan_check_add_debug_flag("bounds") + asan_check_add_debug_flag("enum") + asan_check_add_debug_flag("float-cast-overflow") + asan_check_add_debug_flag("float-divide-by-zero") + asan_check_add_debug_flag("nonnull-attribute") + asan_check_add_debug_flag("returns-nonnull-attribute") + asan_check_add_debug_flag("signed-integer-overflow") + asan_check_add_debug_flag("undefined") + asan_check_add_debug_flag("vla-bound") + asan_check_add_debug_flag("leak") + # The object size sanitizer has no effect on unoptimized builds on Clang, + # but causes warnings. + if((NOT USE_CLANG) OR ("${CMAKE_BUILD_TYPE}" STREQUAL "")) + asan_check_add_debug_flag("object-size") + endif() +endif() + ##### Info output ##### message(STATUS "") message(STATUS "SDL2 was configured with the following options:") @@ -2139,6 +2781,7 @@ message(STATUS "") message(STATUS "Platform: ${CMAKE_SYSTEM}") message(STATUS "64-bit: ${ARCH_64}") message(STATUS "Compiler: ${CMAKE_C_COMPILER}") +message(STATUS "Revision: ${SDL_REVISION}") message(STATUS "") message(STATUS "Subsystems:") foreach(_SUB ${SDL_SUBSYSTEMS}) @@ -2149,13 +2792,17 @@ message(STATUS "") message(STATUS "Options:") list(SORT ALLOPTIONS) foreach(_OPT ${ALLOPTIONS}) - # Longest option is VIDEO_X11_XSCREENSAVER = 22 characters # Get the padding string(LENGTH ${_OPT} _OPTLEN) - math(EXPR _PADLEN "23 - ${_OPTLEN}") + math(EXPR _PADLEN "(${LONGESTOPTIONNAME} + 1) - ${_OPTLEN}") string(RANDOM LENGTH ${_PADLEN} ALPHABET " " _PADDING) message_tested_option(${_OPT} ${_PADDING}) endforeach() +if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + message(STATUS "") + message(STATUS " CMAKE_C_FLAGS_DEBUG: ${CMAKE_C_FLAGS_DEBUG}") + message(STATUS " CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") +endif() message(STATUS "") message(STATUS " CFLAGS: ${CMAKE_C_FLAGS}") message(STATUS " EXTRA_CFLAGS: ${EXTRA_CFLAGS}") @@ -2181,7 +2828,7 @@ if(WARN_ABOUT_ARM_SIMD_ASM_MIT) message(STATUS "uses code licensed under the MIT license. If this is a") message(STATUS "problem, please disable that code by rerunning CMake with:") message(STATUS "") - message(STATUS " -DARMSIMD=OFF") + message(STATUS " -DSDL_ARMSIMD=OFF") endif() if(WARN_ABOUT_ARM_NEON_ASM_MIT) @@ -2190,28 +2837,36 @@ if(WARN_ABOUT_ARM_NEON_ASM_MIT) message(STATUS "uses code licensed under the MIT license. If this is a") message(STATUS "problem, please disable that code by rerunning CMake with:") message(STATUS "") - message(STATUS " -DARMNEON=OFF") + message(STATUS " -DSDL_ARMNEON=OFF") endif() # Ensure that the extra cflags are used at compile time set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") -# Always build SDLmain -if(NOT WINDOWS_STORE) -add_library(SDL2main STATIC ${SDLMAIN_SOURCES}) -target_include_directories(SDL2main PUBLIC "$" $ $) -set(_INSTALL_LIBS "SDL2main") -if (NOT ANDROID) - set_target_properties(SDL2main PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}") -endif() +if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN) + # Build SDLmain + add_library(SDL2main STATIC ${SDLMAIN_SOURCES}) + # alias target for in-tree builds + add_library(SDL2::SDL2main ALIAS SDL2main) + target_include_directories(SDL2main BEFORE PRIVATE "${SDL2_BINARY_DIR}/include") + target_include_directories(SDL2main PUBLIC "$" $ $) + if (NOT ANDROID) + set_target_properties(SDL2main PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}") + endif() endif() -if (ANDROID AND HAVE_HIDAPI) - set(_INSTALL_LIBS ${_INSTALL_LIBS} "hidapi") +if(ANDROID) + target_include_directories(sdl-build-options INTERFACE "${ANDROID_NDK}/sources/android/cpufeatures") +endif() + +if(IOS OR TVOS) + target_compile_options(sdl-build-options INTERFACE "-fobjc-arc") endif() if(SDL_SHARED) add_library(SDL2 SHARED ${SOURCE_FILES} ${VERSION_SOURCES}) + # alias target for in-tree builds + add_library(SDL2::SDL2 ALIAS SDL2) if(APPLE) set_target_properties(SDL2 PROPERTIES MACOSX_RPATH 1 @@ -2219,58 +2874,46 @@ if(SDL_SHARED) elseif(UNIX AND NOT ANDROID) set_target_properties(SDL2 PROPERTIES VERSION ${LT_VERSION} - SOVERSION ${LT_REVISION} + SOVERSION ${LT_MAJOR} OUTPUT_NAME "SDL2-${LT_RELEASE}") else() if(WINDOWS OR CYGWIN) set_target_properties(SDL2 PROPERTIES DEFINE_SYMBOL DLL_EXPORT) + elseif(OS2) + set_target_properties(SDL2 PROPERTIES + DEFINE_SYMBOL BUILD_SDL) endif() set_target_properties(SDL2 PROPERTIES VERSION ${SDL_VERSION} SOVERSION ${LT_REVISION} OUTPUT_NAME "SDL2") endif() - if(MSVC AND NOT LIBC) + # Note: The clang toolset for Visual Studio does not support /NODEFAULTLIB. + if(MSVC AND NOT SDL_LIBC AND NOT MSVC_CLANG) # Don't try to link with the default set of libraries. - set_target_properties(SDL2 PROPERTIES LINK_FLAGS_RELEASE "/NODEFAULTLIB") - set_target_properties(SDL2 PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB") + if(NOT WINDOWS_STORE) + set_target_properties(SDL2 PROPERTIES LINK_FLAGS_RELEASE "/NODEFAULTLIB") + set_target_properties(SDL2 PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB") + endif() set_target_properties(SDL2 PROPERTIES STATIC_LIBRARY_FLAGS "/NODEFAULTLIB") endif() - set(_INSTALL_LIBS "SDL2" ${_INSTALL_LIBS}) target_link_libraries(SDL2 PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS}) - target_include_directories(SDL2 PUBLIC "$" $ $) - if(ANDROID) - target_include_directories(SDL2 PRIVATE ${ANDROID_NDK}/sources/android/cpufeatures) - else() + target_include_directories(SDL2 BEFORE PRIVATE "${SDL2_BINARY_DIR}/include") + target_include_directories(SDL2 PUBLIC "$;$;$") + # This picks up all the compiler options and such we've accumulated up to here. + target_link_libraries(SDL2 PRIVATE $) + if(NOT ANDROID) set_target_properties(SDL2 PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}") endif() - if(IOS OR TVOS) - set_property(TARGET SDL2 APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc") - target_compile_definitions(SDL2 PRIVATE IOS_DYLIB=1) - endif() -endif() - -if(ANDROID) - if(HAVE_HIDAPI) - add_library(hidapi SHARED ${SDL2_SOURCE_DIR}/src/hidapi/android/hid.cpp) - endif() - - if(MSVC AND NOT LIBC) - # Don't try to link with the default set of libraries. - set_target_properties(hidapi PROPERTIES LINK_FLAGS_RELEASE "/NODEFAULTLIB") - set_target_properties(hidapi PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB") - set_target_properties(hidapi PROPERTIES STATIC_LIBRARY_FLAGS "/NODEFAULTLIB") - endif() - if(HAVE_HIDAPI) - target_link_libraries(hidapi log) - endif() endif() if(SDL_STATIC) set (BUILD_SHARED_LIBS FALSE) add_library(SDL2-static STATIC ${SOURCE_FILES}) - if (NOT SDL_SHARED OR NOT WIN32) + # alias target for in-tree builds + add_library(SDL2::SDL2-static ALIAS SDL2-static) + if (NOT SDL_SHARED OR NOT WIN32 OR MINGW) set_target_properties(SDL2-static PROPERTIES OUTPUT_NAME "SDL2") # Note: Apparently, OUTPUT_NAME must really be unique; even when # CMAKE_IMPORT_LIBRARY_SUFFIX or the like are given. Otherwise @@ -2278,46 +2921,61 @@ if(SDL_STATIC) # clobbered, when the suffix is realized via subsequent rename. endif() set_target_properties(SDL2-static PROPERTIES POSITION_INDEPENDENT_CODE ${SDL_STATIC_PIC}) - if(MSVC AND NOT LIBC) + # Note: The clang toolset for Visual Studio does not support /NODEFAULTLIB. + if(MSVC AND NOT SDL_LIBC AND NOT MSVC_CLANG) set_target_properties(SDL2-static PROPERTIES LINK_FLAGS_RELEASE "/NODEFAULTLIB") set_target_properties(SDL2-static PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB") set_target_properties(SDL2-static PROPERTIES STATIC_LIBRARY_FLAGS "/NODEFAULTLIB") endif() # TODO: Win32 platforms keep the same suffix .lib for import and static # libraries - do we need to consider this? - set(_INSTALL_LIBS "SDL2-static" ${_INSTALL_LIBS}) - target_link_libraries(SDL2-static ${EXTRA_LIBS} ${EXTRA_LDFLAGS}) + target_link_libraries(SDL2-static PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS}) + target_include_directories(SDL2-static BEFORE PRIVATE "${SDL2_BINARY_DIR}/include") target_include_directories(SDL2-static PUBLIC "$" $ $) - if(ANDROID) - target_include_directories(SDL2-static PRIVATE ${ANDROID_NDK}/sources/android/cpufeatures) - else() + # This picks up all the compiler options and such we've accumulated up to here. + target_link_libraries(SDL2-static PRIVATE $) + if(NOT ANDROID) set_target_properties(SDL2-static PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}") endif() - if(IOS OR TVOS) - set_property(TARGET SDL2-static APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc") - endif() endif() ##### Tests ##### if(SDL_TEST) + include_directories(BEFORE "${SDL2_BINARY_DIR}/include") + include_directories(AFTER "${SDL2_SOURCE_DIR}/include") file(GLOB TEST_SOURCES ${SDL2_SOURCE_DIR}/src/test/*.c) add_library(SDL2_test STATIC ${TEST_SOURCES}) - add_subdirectory(test) endif() ##### Installation targets ##### -install(TARGETS ${_INSTALL_LIBS} EXPORT SDL2Targets - LIBRARY DESTINATION "lib${LIB_SUFFIX}" - ARCHIVE DESTINATION "lib${LIB_SUFFIX}" - RUNTIME DESTINATION bin) +if(SDL_SHARED) + install(TARGETS SDL2 EXPORT SDL2Targets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") +endif() + +if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN) + install(TARGETS SDL2main EXPORT SDL2mainTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") +endif() + +if(SDL_STATIC) + install(TARGETS SDL2-static EXPORT SDL2staticTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") +endif() ##### Export files ##### -if (WINDOWS) +if (WINDOWS AND NOT MINGW) set(PKG_PREFIX "cmake") else () - set(PKG_PREFIX "lib${LIB_SUFFIX}/cmake/SDL2") + set(PKG_PREFIX "${CMAKE_INSTALL_LIBDIR}/cmake/SDL2") endif () include(CMakePackageConfigHelpers) @@ -2326,11 +2984,30 @@ write_basic_package_version_file("${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake" COMPATIBILITY AnyNewerVersion ) -install(EXPORT SDL2Targets - FILE SDL2Targets.cmake - NAMESPACE SDL2:: - DESTINATION ${PKG_PREFIX} -) +if(SDL_SHARED) + install(EXPORT SDL2Targets + FILE SDL2Targets.cmake + NAMESPACE SDL2:: + DESTINATION ${PKG_PREFIX} + ) +endif() + +if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN) + install(EXPORT SDL2mainTargets + FILE SDL2mainTargets.cmake + NAMESPACE SDL2:: + DESTINATION ${PKG_PREFIX} + ) +endif() + +if(SDL_STATIC) + install(EXPORT SDL2staticTargets + FILE SDL2staticTargets.cmake + NAMESPACE SDL2:: + DESTINATION ${PKG_PREFIX} + ) +endif() + install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/SDL2Config.cmake @@ -2346,7 +3023,7 @@ foreach(_FNAME ${BIN_INCLUDE_FILES}) list(REMOVE_ITEM INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/${_INCNAME}) endforeach() list(APPEND INCLUDE_FILES ${BIN_INCLUDE_FILES}) -install(FILES ${INCLUDE_FILES} DESTINATION include/SDL2) +install(FILES ${INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SDL2) string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_BUILD_TYPE) if (UPPER_BUILD_TYPE MATCHES DEBUG) @@ -2355,16 +3032,16 @@ else() set(SOPOSTFIX "") endif() -if(NOT (WINDOWS OR CYGWIN)) +if(NOT (WINDOWS OR CYGWIN) OR MINGW) if(SDL_SHARED) set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc. get_target_property(SONAME SDL2 OUTPUT_NAME) - if(NOT ANDROID) + if(NOT ANDROID AND NOT MINGW AND NOT OS2) install(CODE " execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL2${SOPOSTFIX}${SOEXT}\" WORKING_DIRECTORY \"${SDL2_BINARY_DIR}\")") - install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "lib${LIB_SUFFIX}") + install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}") endif() endif() if(FREEBSD) @@ -2372,15 +3049,16 @@ if(NOT (WINDOWS OR CYGWIN)) install(FILES ${SDL2_BINARY_DIR}/sdl2.pc DESTINATION "libdata/pkgconfig") else() install(FILES ${SDL2_BINARY_DIR}/sdl2.pc - DESTINATION "lib${LIB_SUFFIX}/pkgconfig") + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") endif() - install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION bin) + install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION "${CMAKE_INSTALL_BINDIR}") # TODO: what about the .spec file? Is it only needed for RPM creation? - install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/aclocal") + install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/aclocal") endif() ##### Uninstall target ##### +if(NOT SDL2_DISABLE_UNINSTALL) if(NOT TARGET uninstall) configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" @@ -2390,3 +3068,4 @@ if(NOT TARGET uninstall) add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) endif() +endif(NOT SDL2_DISABLE_UNINSTALL) diff --git a/Engine/lib/sdl/INSTALL.txt b/Engine/lib/sdl/INSTALL.txt index 9ee4ef538..5856e2875 100644 --- a/Engine/lib/sdl/INSTALL.txt +++ b/Engine/lib/sdl/INSTALL.txt @@ -2,16 +2,16 @@ To compile and install SDL: 1. Windows with Visual Studio: - * Read VisualC.html + * Read ./docs/README-visualc.md Windows with gcc, either native or cross-compiling: - * Read the FAQ at https://wiki.libsdl.org/moin.fcg/FAQWindows + * Read the FAQ at https://wiki.libsdl.org/FAQWindows * Run './configure; make; make install' - Mac OS X with Xcode: + macOS with Xcode: * Read docs/README-macosx.md - Mac OS X from the command line: + macOS from the command line: * Run './configure; make; make install' Linux and other UNIX systems: @@ -29,12 +29,13 @@ To compile and install SDL: 2. Look at the example programs in ./test, and check out the online documentation at https://wiki.libsdl.org/ - 3. Join the SDL developer mailing list by sending E-mail to - sdl-request@libsdl.org - and put "subscribe" in the subject of the message. + 3. Join the SDL developer discussions, sign up on + https://discourse.libsdl.org/ + and go to the development forum + https://discourse.libsdl.org/c/sdl-development/6 - Or alternatively you can use the web interface: - https://www.libsdl.org/mailing-list.php + 4. Sign up for the announcement list through the web interface: + https://www.libsdl.org/mailing-list.php That's it! Sam Lantinga diff --git a/Engine/lib/sdl/COPYING.txt b/Engine/lib/sdl/LICENSE.txt similarity index 90% rename from Engine/lib/sdl/COPYING.txt rename to Engine/lib/sdl/LICENSE.txt index 0e2bef3fc..728a3d708 100644 --- a/Engine/lib/sdl/COPYING.txt +++ b/Engine/lib/sdl/LICENSE.txt @@ -1,6 +1,4 @@ - -Simple DirectMedia Layer -Copyright (C) 1997-2020 Sam Lantinga +Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/Makefile.in b/Engine/lib/sdl/Makefile.in index 57871bedf..81c56fd3a 100644 --- a/Engine/lib/sdl/Makefile.in +++ b/Engine/lib/sdl/Makefile.in @@ -29,6 +29,8 @@ INSTALL = @INSTALL@ AR = @AR@ RANLIB = @RANLIB@ RC = @RC@ +LINKER = @LINKER@ +LIBTOOLLINKERTAG = @LIBTOOLLINKERTAG@ TARGET = libSDL2.la OBJECTS = @OBJECTS@ @@ -43,10 +45,11 @@ SDLTEST_TARGET = libSDL2_test.la SDLTEST_OBJECTS = @SDLTEST_OBJECTS@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ +WAYLAND_SCANNER_CODE_MODE = @WAYLAND_SCANNER_CODE_MODE@ INSTALL_SDL2_CONFIG = @INSTALL_SDL2_CONFIG@ -SRC_DIST = *.txt acinclude Android.mk autogen.sh android-project build-scripts cmake cmake_uninstall.cmake.in configure configure.ac debian docs include Makefile.* sdl2-config.cmake.in sdl2-config-version.cmake.in sdl2-config.in sdl2.m4 sdl2.pc.in SDL2.spec.in SDL2Config.cmake src test VisualC.html VisualC VisualC-WinRT Xcode Xcode-iOS wayland-protocols +SRC_DIST = *.md *.txt acinclude Android.mk autogen.sh android-project build-scripts cmake cmake_uninstall.cmake.in configure configure.ac docs include Makefile.* sdl2-config.cmake.in sdl2-config-version.cmake.in sdl2-config.in sdl2.m4 sdl2.pc.in SDL2.spec.in SDL2Config.cmake src test VisualC VisualC-WinRT Xcode Xcode-iOS wayland-protocols GEN_DIST = SDL2.spec ifneq ($V,1) @@ -77,6 +80,7 @@ HDRS = \ SDL_gamecontroller.h \ SDL_gesture.h \ SDL_haptic.h \ + SDL_hidapi.h \ SDL_hints.h \ SDL_joystick.h \ SDL_keyboard.h \ @@ -151,13 +155,13 @@ update-revision: .PHONY: all update-revision install install-bin install-hdrs install-lib install-data uninstall uninstall-bin uninstall-hdrs uninstall-lib uninstall-data clean distclean dist $(OBJECTS:.lo=.d) $(objects)/$(TARGET): $(GEN_HEADERS) $(GEN_OBJECTS) $(OBJECTS) $(VERSION_OBJECTS) - $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(OBJECTS) $(GEN_OBJECTS) $(VERSION_OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS) + $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=$(LIBTOOLLINKERTAG) --mode=link $(LINKER) -o $@ $(OBJECTS) $(GEN_OBJECTS) $(VERSION_OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS) $(objects)/$(SDLMAIN_TARGET): $(SDLMAIN_OBJECTS) - $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -static -o $@ $(SDLMAIN_OBJECTS) -rpath $(libdir) + $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=$(LIBTOOLLINKERTAG) --mode=link $(LINKER) -static -o $@ $(SDLMAIN_OBJECTS) -rpath $(libdir) $(objects)/$(SDLTEST_TARGET): $(SDLTEST_OBJECTS) - $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -static -o $@ $(SDLTEST_OBJECTS) -rpath $(libdir) + $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=$(LIBTOOLLINKERTAG) --mode=link $(LINKER) -static -o $@ $(SDLTEST_OBJECTS) -rpath $(libdir) install: all install-bin install-hdrs install-lib install-data install-bin: diff --git a/Engine/lib/sdl/Makefile.minimal b/Engine/lib/sdl/Makefile.minimal index 7f0264974..97ce201ea 100644 --- a/Engine/lib/sdl/Makefile.minimal +++ b/Engine/lib/sdl/Makefile.minimal @@ -5,9 +5,12 @@ CFLAGS = -g -O2 $(INCLUDE) AR = ar RANLIB = ranlib -TARGET = libSDL.a +TARGET = libSDL2.a +TESTTARGET = libSDL2_test.a + SOURCES = \ src/*.c \ + src/atomic/*.c \ src/audio/*.c \ src/audio/dummy/*.c \ src/cpuinfo/*.c \ @@ -15,30 +18,44 @@ SOURCES = \ src/file/*.c \ src/haptic/*.c \ src/haptic/dummy/*.c \ + src/hidapi/*.c \ src/joystick/*.c \ src/joystick/dummy/*.c \ src/loadso/dummy/*.c \ src/power/*.c \ src/filesystem/dummy/*.c \ + src/locale/*.c \ + src/locale/dummy/*.c \ + src/misc/*.c \ + src/misc/dummy/*.c \ src/render/*.c \ src/render/software/*.c \ src/sensor/*.c \ src/sensor/dummy/*.c \ src/stdlib/*.c \ + src/libm/*.c \ src/thread/*.c \ src/thread/generic/*.c \ src/timer/*.c \ src/timer/dummy/*.c \ src/video/*.c \ + src/video/yuv2rgb/*.c \ src/video/dummy/*.c \ -OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g') +TSOURCES = src/test/*.c -all: $(TARGET) +OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g') +TOBJECTS= $(shell echo $(TSOURCES) | sed -e 's,\.c,\.o,g') + +all: $(TARGET) $(TESTTARGET) $(TARGET): $(OBJECTS) $(AR) crv $@ $^ $(RANLIB) $@ +$(TESTTARGET): $(TOBJECTS) + $(AR) crv $@ $^ + $(RANLIB) $@ + clean: - rm -f $(TARGET) $(OBJECTS) + rm -f $(TARGET) $(TESTTARGET) $(OBJECTS) $(TOBJECTS) diff --git a/Engine/lib/sdl/Makefile.os2 b/Engine/lib/sdl/Makefile.os2 index 412e91b58..eb34494c5 100644 --- a/Engine/lib/sdl/Makefile.os2 +++ b/Engine/lib/sdl/Makefile.os2 @@ -1,10 +1,22 @@ # Open Watcom makefile to build SDL2.dll for OS/2 # wmake -f Makefile.os2 +# +# If you have GNU libiconv installed (iconv2.dll), you +# can compile against it by specifying LIBICONV=1, e.g.: +# wmake -f Makefile.os2 LIBICONV=1 +# +# If you have libusb-1.0 installed (usb100.dll, libusb.h), you +# can compile hidapi joystick support against it (experimental) +# by specifying HIDAPI=1, e.g.: +# wmake -f Makefile.os2 HIDAPI=1 LIBNAME = SDL2 -VERSION = 2.0.14 +VERSION = 2.0.21 DESCRIPTION = Simple DirectMedia Layer 2 +LIBICONV=0 +ICONVLIB=$(LIBICONV_LIB) + LIBHOME = . DLLFILE = $(LIBHOME)/$(LIBNAME).dll LIBFILE = $(LIBHOME)/$(LIBNAME).lib @@ -12,32 +24,41 @@ LNKFILE = $(LIBNAME).lnk INCPATH = -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h" INCPATH+= -Iinclude -INCPATH+= -I"src/core/os2" -I"src/core/os2/geniconv" - -LIBM = libm.lib -LIBS = mmpm2.lib libuls.lib libconv.lib $(LIBM) - -CFLAGS = -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier -ei -# max warnings: -CFLAGS+= -wx -# newer OpenWatcom versions enable W303 by default -CFLAGS+= -wcd=303 -# building dll: -CFLAGS+= -bd -# the include paths : -CFLAGS+= $(INCPATH) -# building SDL itself (for DECLSPEC): -CFLAGS+= -DBUILD_SDL +LIBM = SDL2libm.lib +TLIB = SDL2test.lib +LIBS = mmpm2.lib $(LIBM) +CFLAGS = -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oeatxhn -ei # Debug options: # - debug messages from OS/2 related code to stdout: #CFLAGS+= -DOS2DEBUG # - debug messages from OS/2 code via SDL_LogDebug(): #CFLAGS+= -DOS2DEBUG=2 -MSRCS= e_atan2.c e_exp.c e_fmod.c e_log10.c e_log.c e_pow.c e_rem_pio2.c e_sqrt.c & - k_cos.c k_rem_pio2.c k_sin.c k_tan.c & - s_atan.c s_copysign.c s_cos.c s_fabs.c s_floor.c s_scalbn.c s_sin.c s_tan.c +# max warnings: +CFLAGS+= -wx +# newer OpenWatcom versions enable W303 by default +CFLAGS+= -wcd=303 +# the include paths : +CFLAGS+= $(INCPATH) +CFLAGS_STATIC=$(CFLAGS) +# building dll: +CFLAGS_DLL =$(CFLAGS) +CFLAGS_DLL+= -bd +# iconv: +LIBICONV_LIB=iconv2.lib +!ifeq LIBICONV 1 +CFLAGS_DLL+= -DHAVE_ICONV=1 -DHAVE_ICONV_H=1 +LIBS+= $(ICONVLIB) +!else +LIBS+= libuls.lib libconv.lib +!endif +# hidapi (libusb): +!ifeq HIDAPI 1 +CFLAGS_DLL+= -DHAVE_LIBUSB_H=1 +!endif +# building SDL itself (for DECLSPEC): +CFLAGS_DLL+= -DBUILD_SDL SRCS = SDL.c SDL_assert.c SDL_error.c SDL_log.c SDL_dataqueue.c SDL_hints.c SRCS+= SDL_getenv.c SDL_iconv.c SDL_malloc.c SDL_qsort.c SDL_stdlib.c SDL_string.c SDL_strtokr.c SDL_crc32.c @@ -47,10 +68,10 @@ SRCS+= SDL_audio.c SDL_audiocvt.c SDL_audiodev.c SDL_audiotypecvt.c SDL_mixer.c SRCS+= SDL_events.c SDL_quit.c SDL_keyboard.c SDL_mouse.c SDL_windowevents.c & SDL_clipboardevents.c SDL_dropevents.c SDL_displayevents.c SDL_gesture.c & SDL_sensor.c SDL_touch.c -SRCS+= SDL_haptic.c SDL_gamecontroller.c SDL_joystick.c +SRCS+= SDL_haptic.c SDL_hidapi.c SDL_gamecontroller.c SDL_joystick.c SRCS+= SDL_render.c yuv_rgb.c SDL_yuv.c SDL_yuv_sw.c SDL_blendfillrect.c & SDL_blendline.c SDL_blendpoint.c SDL_drawline.c SDL_drawpoint.c & - SDL_render_sw.c SDL_rotate.c + SDL_render_sw.c SDL_rotate.c SDL_triangle.c SRCS+= SDL_blit.c SDL_blit_0.c SDL_blit_1.c SDL_blit_A.c SDL_blit_auto.c & SDL_blit_copy.c SDL_blit_N.c SDL_blit_slow.c SDL_fillrect.c SDL_bmp.c & SDL_pixels.c SDL_rect.c SDL_RLEaccel.c SDL_shape.c SDL_stretch.c & @@ -60,15 +81,18 @@ SRCS+= SDL_syscond.c SDL_sysmutex.c SDL_syssem.c SDL_systhread.c SDL_systls.c SRCS+= SDL_systimer.c SRCS+= SDL_sysloadso.c SRCS+= SDL_sysfilesystem.c -SRCS+= SDL_syshaptic.c SDL_sysjoystick.c -SRCS+= SDL_virtualjoystick.c +SRCS+= SDL_os2joystick.c SDL_syshaptic.c SDL_sysjoystick.c SDL_virtualjoystick.c +SRCS+= SDL_hidapijoystick.c SDL_hidapi_rumble.c SDL_hidapi_gamecube.c SDL_hidapi_luna.c SDL_hidapi_ps4.c SDL_hidapi_ps5.c SDL_hidapi_stadia.c SDL_hidapi_switch.c SDL_hidapi_xbox360.c SDL_hidapi_xbox360w.c SDL_hidapi_xboxone.c SDL_hidapi_steam.c SRCS+= SDL_dummyaudio.c SDL_diskaudio.c SRCS+= SDL_nullvideo.c SDL_nullframebuffer.c SDL_nullevents.c SRCS+= SDL_dummysensor.c SRCS+= SDL_locale.c SDL_syslocale.c SRCS+= SDL_url.c SDL_sysurl.c -SRCS+= SDL_os2.c geniconv.c os2cp.c os2iconv.c sys2utf8.c +SRCS+= SDL_os2.c +!ifeq LIBICONV 0 +SRCS+= geniconv.c os2cp.c os2iconv.c sys2utf8.c +!endif SRCS+= SDL_os2audio.c SRCS+= SDL_os2video.c SDL_os2util.c SDL_os2dive.c SDL_os2vman.c & SDL_os2mouse.c SDL_os2messagebox.c @@ -76,19 +100,22 @@ SRCS+= SDL_os2video.c SDL_os2util.c SDL_os2dive.c SDL_os2vman.c & SRCS+= SDL_dynapi.c OBJS = $(SRCS:.c=.obj) -MOBJS= $(MSRCS:.c=.obj) .extensions: .extensions: .lib .dll .obj .c .asm .c: ./src;./src/dynapi;./src/audio;./src/cpuinfo;./src/events;./src/file;./src/haptic;./src/joystick;./src/power;./src/render;./src/render/software;./src/sensor;./src/stdlib;./src/thread;./src/timer;./src/video;./src/video/yuv2rgb;./src/atomic;./src/audio/disk; .c: ./src/haptic/dummy;./src/joystick/dummy;./src/joystick/virtual;./src/audio/dummy;./src/video/dummy;./src/sensor/dummy; -.c: ./src/core/os2;./src/core/os2/geniconv;./src/audio/os2;./src/loadso/os2;./src/filesystem/os2;./src/thread/os2;./src/timer/os2;./src/video/os2; -.c: ./src/locale/;./src/locale/unix;./src/misc;./src/misc/dummy +.c: ./src/core/os2;./src/audio/os2;./src/loadso/os2;./src/filesystem/os2;./src/joystick/os2;./src/thread/os2;./src/timer/os2;./src/video/os2; +.c: ./src/core/os2/geniconv; +.c: ./src/locale/;./src/locale/unix;./src/misc;./src/misc/dummy;./src/joystick/hidapi;./src/hidapi -all: $(DLLFILE) $(LIBFILE) .symbolic +all: $(DLLFILE) $(LIBFILE) $(TLIB) .symbolic -$(DLLFILE): $(OBJS) $(LIBM) $(LNKFILE) +build_dll: .symbolic + @echo * Compiling dll objects + +$(DLLFILE): build_dll $(OBJS) $(LIBM) $(LIBICONV_LIB) $(LNKFILE) @echo * Linking: $@ wlink @$(LNKFILE) @@ -97,36 +124,132 @@ $(LIBFILE): $(DLLFILE) wlib -q -b -n -c -pa -s -t -zld -ii -io $* $(DLLFILE) .c.obj: - wcc386 $(CFLAGS) -fo=$^@ $< + wcc386 $(CFLAGS_DLL) -fo=$^@ $< SDL_syscond.obj: "src/thread/generic/SDL_syscond.c" - wcc386 $(CFLAGS) -fo=$^@ $< - + wcc386 $(CFLAGS_DLL) -fo=$^@ $< SDL_cpuinfo.obj: SDL_cpuinfo.c - wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $< - -SDL_rwops.obj: SDL_rwops.c - wcc386 $(CFLAGS) -wcd=136 -fo=$^@ $< - + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< SDL_wave.obj: SDL_wave.c - wcc386 $(CFLAGS) -wcd=124 -fo=$^@ $< - + wcc386 $(CFLAGS_DLL) -wcd=124 -fo=$^@ $< SDL_blendfillrect.obj: SDL_blendfillrect.c - wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $< - + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< SDL_blendline.obj: SDL_blendline.c - wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $< - + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< SDL_blendpoint.obj: SDL_blendpoint.c - wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $< - + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< SDL_RLEaccel.obj: SDL_RLEaccel.c - wcc386 $(CFLAGS) -wcd=201 -fo=$^@ $< + wcc386 $(CFLAGS_DLL) -wcd=201 -fo=$^@ $< +# c99 mode needed because of structs with flexible array members in libusb.h +SDL_hidapi.obj: SDL_hidapi.c + wcc386 $(CFLAGS_DLL) -za99 -fo=$^@ $< + +$(LIBICONV_LIB): "src/core/os2/iconv2.lbc" + @echo * Creating: $@ + wlib -q -b -n -c -pa -s -t -zld -ii -io $@ @$< + +# SDL2libm +MSRCS= e_atan2.c e_exp.c e_fmod.c e_log10.c e_log.c e_pow.c e_rem_pio2.c e_sqrt.c & + k_cos.c k_rem_pio2.c k_sin.c k_tan.c & + s_atan.c s_copysign.c s_cos.c s_fabs.c s_floor.c s_scalbn.c s_sin.c s_tan.c +MOBJS= $(MSRCS:.c=.obj) .c: ./src/libm; -$(LIBM): $(MOBJS) +e_atan2.obj: e_atan2.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_exp.obj: e_exp.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_fmod.obj: e_fmod.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_log10.obj: e_log10.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_log.obj: e_log.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_pow.obj: e_pow.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_rem_pio2.obj: e_rem_pio2.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_sqrt.obj: e_sqrt.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_cos.obj: k_cos.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_rem_pio2.obj: k_rem_pio2.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_sin.obj: k_sin.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_tan.obj: k_tan.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_atan.obj: s_atan.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_copysign.obj: s_copysign.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_cos.obj: s_cos.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_fabs.obj: s_fabs.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_floor.obj: s_floor.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_scalbn.obj: s_scalbn.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_sin.obj: s_sin.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_tan.obj: s_tan.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< + +build_libm: .symbolic + @echo * Compiling libm objects +$(LIBM): build_libm $(MOBJS) + @echo * Creating: $@ wlib -q -b -n -c -pa -s -t -zld -ii -io $@ $(MOBJS) +# SDL2test +TSRCS = SDL_test_assert.c SDL_test_common.c SDL_test_compare.c & + SDL_test_crc32.c SDL_test_font.c SDL_test_fuzzer.c SDL_test_harness.c & + SDL_test_imageBlit.c SDL_test_imageBlitBlend.c SDL_test_imageFace.c & + SDL_test_imagePrimitives.c SDL_test_imagePrimitivesBlend.c & + SDL_test_log.c SDL_test_md5.c SDL_test_random.c SDL_test_memory.c +TOBJS= $(TSRCS:.c=.obj) + +.c: ./src/test; +SDL_test_assert.obj: SDL_test_assert.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_common.obj: SDL_test_common.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_compare.obj: SDL_test_compare.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_crc32.obj: SDL_test_crc32.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_font.obj: SDL_test_font.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_fuzzer.obj: SDL_test_fuzzer.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_harness.obj: SDL_test_harness.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageBlit.obj: SDL_test_imageBlit.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageBlitBlend.obj: SDL_test_imageBlitBlend.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageFace.obj: SDL_test_imageFace.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imagePrimitives.obj: SDL_test_imagePrimitives.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imagePrimitivesBlend.obj: SDL_test_imagePrimitivesBlend.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_log.obj: SDL_test_log.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_md5.obj: SDL_test_md5.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_random.obj: SDL_test_random.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_memory.obj: SDL_test_memory.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< + +build_tlib: .symbolic + @echo * Compiling testlib objects +$(TLIB): build_tlib $(TOBJS) + @echo * Creating: $@ + wlib -q -b -n -c -pa -s -t -zld -ii -io $@ $(TOBJS) + $(LNKFILE): @echo * Creating linker file: $@ @%create $@ @@ -144,14 +267,16 @@ $(LNKFILE): @%append $@ OPTION SHOWDEAD clean: .SYMBOLIC - @ echo * Clean: $(LIBNAME) + @echo * Clean: $(LIBNAME) @if exist *.obj rm *.obj @if exist *.err rm *.err @if exist $(LNKFILE) rm $(LNKFILE) @if exist $(LIBM) rm $(LIBM) + @if exist $(LIBICONV_LIB) rm $(LIBICONV_LIB) distclean: .SYMBOLIC clean @if exist $(LIBHOME)/*.exp rm $(LIBHOME)/*.exp @if exist $(LIBHOME)/*.map rm $(LIBHOME)/*.map @if exist $(LIBFILE) rm $(LIBFILE) @if exist $(DLLFILE) rm $(DLLFILE) + @if exist $(TLIB) rm $(TLIB) diff --git a/Engine/lib/sdl/Makefile.pandora b/Engine/lib/sdl/Makefile.pandora index f4cb66848..fe2249979 100644 --- a/Engine/lib/sdl/Makefile.pandora +++ b/Engine/lib/sdl/Makefile.pandora @@ -10,7 +10,7 @@ CFLAGS = -O3 -march=armv7-a -mcpu=cortex-a8 -mtune=cortex-a8 -mfloat-abi=softfp -mfpu=neon -ftree-vectorize -ffast-math -fomit-frame-pointer -fno-strict-aliasing -fsingle-precision-constant \ -I./include -I$(PNDSDK)/usr/include -TARGET = libSDL.a +TARGET = libSDL2.a SOURCES = ./src/*.c \ @@ -25,9 +25,14 @@ SOURCES = ./src/filesystem/unix/*.c \ ./src/haptic/*.c \ ./src/haptic/linux/*.c \ + ./src/hidapi/*.c \ ./src/joystick/*.c \ ./src/joystick/linux/*.c \ ./src/loadso/dlopen/*.c \ + ./src/locale/*.c \ + ./src/locale/unix/*.c \ + ./src/misc/*.c \ + ./src/misc/unix/*.c \ ./src/power/*.c \ ./src/sensor/*.c \ ./src/sensor/dummy/*.c \ @@ -40,11 +45,10 @@ SOURCES = ./src/timer/*.c \ ./src/timer/unix/*.c \ ./src/video/*.c \ + ./src/video/yuv2rgb/*.c \ ./src/video/dummy/*.c \ - ./src/video/pandora/SDL_pandora.o \ - ./src/video/pandora/SDL_pandora_events.o \ ./src/video/x11/*.c \ - + ./src/video/pandora/*.c OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g') diff --git a/Engine/lib/sdl/Makefile.psp b/Engine/lib/sdl/Makefile.psp deleted file mode 100644 index 16c540023..000000000 --- a/Engine/lib/sdl/Makefile.psp +++ /dev/null @@ -1,96 +0,0 @@ -TARGET_LIB = libSDL2.a -OBJS= src/SDL.o \ - src/SDL_assert.o \ - src/SDL_error.o \ - src/SDL_hints.o \ - src/SDL_log.o \ - src/atomic/SDL_atomic.o \ - src/atomic/SDL_spinlock.o \ - src/audio/SDL_audio.o \ - src/audio/SDL_audiocvt.o \ - src/audio/SDL_audiodev.o \ - src/audio/SDL_audiotypecvt.o \ - src/audio/SDL_mixer.o \ - src/audio/SDL_wave.o \ - src/audio/psp/SDL_pspaudio.o \ - src/cpuinfo/SDL_cpuinfo.o \ - src/events/SDL_clipboardevents.o \ - src/events/SDL_dropevents.o \ - src/events/SDL_events.o \ - src/events/SDL_gesture.o \ - src/events/SDL_keyboard.o \ - src/events/SDL_mouse.o \ - src/events/SDL_quit.o \ - src/events/SDL_touch.o \ - src/events/SDL_windowevents.o \ - src/file/SDL_rwops.o \ - src/haptic/SDL_haptic.o \ - src/haptic/dummy/SDL_syshaptic.o \ - src/joystick/SDL_joystick.o \ - src/joystick/SDL_gamecontroller.o \ - src/joystick/psp/SDL_sysjoystick.o \ - src/power/SDL_power.o \ - src/power/psp/SDL_syspower.o \ - src/filesystem/dummy/SDL_sysfilesystem.o \ - src/render/SDL_render.o \ - src/render/SDL_yuv_sw.o \ - src/render/psp/SDL_render_psp.o \ - src/render/software/SDL_blendfillrect.o \ - src/render/software/SDL_blendline.o \ - src/render/software/SDL_blendpoint.o \ - src/render/software/SDL_drawline.o \ - src/render/software/SDL_drawpoint.o \ - src/render/software/SDL_render_sw.o \ - src/render/software/SDL_rotate.o \ - src/sensor/SDL_sensor.o \ - src/sensor/dummy/SDL_dummysensor.o \ - src/stdlib/SDL_getenv.o \ - src/stdlib/SDL_iconv.o \ - src/stdlib/SDL_malloc.o \ - src/stdlib/SDL_qsort.o \ - src/stdlib/SDL_stdlib.o \ - src/stdlib/SDL_string.o \ - src/stdlib/SDL_strtokr.o \ - src/thread/SDL_thread.o \ - src/thread/generic/SDL_systls.o \ - src/thread/psp/SDL_syssem.o \ - src/thread/psp/SDL_systhread.o \ - src/thread/psp/SDL_sysmutex.o \ - src/thread/psp/SDL_syscond.o \ - src/timer/SDL_timer.o \ - src/timer/psp/SDL_systimer.o \ - src/video/SDL_RLEaccel.o \ - src/video/SDL_blit.o \ - src/video/SDL_blit_0.o \ - src/video/SDL_blit_1.o \ - src/video/SDL_blit_A.o \ - src/video/SDL_blit_N.o \ - src/video/SDL_blit_auto.o \ - src/video/SDL_blit_copy.o \ - src/video/SDL_blit_slow.o \ - src/video/SDL_bmp.o \ - src/video/SDL_clipboard.o \ - src/video/SDL_fillrect.o \ - src/video/SDL_pixels.o \ - src/video/SDL_rect.o \ - src/video/SDL_stretch.o \ - src/video/SDL_surface.o \ - src/video/SDL_video.o \ - src/video/psp/SDL_pspevents.o \ - src/video/psp/SDL_pspvideo.o \ - src/video/psp/SDL_pspgl.o \ - src/video/psp/SDL_pspmouse.o - -INCDIR = ./include -CFLAGS = -g -O2 -G0 -Wall -D__PSP__ -DHAVE_OPENGL -CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti -ASFLAGS = $(CFLAGS) - -LIBDIR = -LIBS = -lGL -lGLU -lglut -lz \ - -lpspvfpu -lpsphprm -lpspsdk -lpspctrl -lpspumd -lpsprtc -lpsppower -lpspgum -lpspgu -lpspaudiolib -lpspaudio -lpsphttp -lpspssl -lpspwlan \ - -lpspnet_adhocmatching -lpspnet_adhoc -lpspnet_adhocctl -lm -lpspvram - -PSPSDK=$(shell psp-config --pspsdk-path) -include $(PSPSDK)/lib/build.mak - diff --git a/Engine/lib/sdl/Makefile.wiz b/Engine/lib/sdl/Makefile.wiz deleted file mode 100644 index 8ed58ee76..000000000 --- a/Engine/lib/sdl/Makefile.wiz +++ /dev/null @@ -1,80 +0,0 @@ -# Makefile to build the pandora SDL library -WIZSDK = /mythtv/media/devel/toolchains/openwiz/arm-openwiz-linux-gnu - -AR = $(WIZSDK)/bin/arm-openwiz-linux-gnu-ar -RANLIB = $(WIZSDK)/bin/arm-openwiz-linux-gnu-ranlib -CC = $(WIZSDK)/bin/arm-openwiz-linux-gnu-gcc -CXX = $(WIZSDK)/bin/arm-openwiz-linux-gnu-g++ -STRIP = $(WIZSDK)/bin/arm-openwiz-linux-gnu-strip - -CFLAGS = -Wall -fPIC -I./include -I$(WIZSDK)/include -DWIZ_GLES_LITE - -TARGET_STATIC = libSDL2.a -TARGET_SHARED = libSDL2.so - -SOURCES = \ - ./src/*.c \ - ./src/audio/*.c \ - ./src/audio/disk/*.c \ - ./src/audio/dsp/*.c \ - ./src/audio/dummy/*.c \ - ./src/cpuinfo/*.c \ - ./src/events/*.c \ - ./src/file/*.c \ - ./src/haptic/*.c \ - ./src/haptic/linux/*.c \ - ./src/joystick/*.c \ - ./src/joystick/linux/*.c \ - ./src/loadso/dlopen/*.c \ - ./src/sensor/*.c \ - ./src/sensor/dummy/*.c \ - ./src/stdlib/*.c \ - ./src/thread/*.c \ - ./src/thread/pthread/SDL_syscond.c \ - ./src/thread/pthread/SDL_sysmutex.c \ - ./src/thread/pthread/SDL_syssem.c \ - ./src/thread/pthread/SDL_systhread.c \ - ./src/timer/*.c \ - ./src/timer/unix/*.c \ - ./src/video/*.c \ - ./src/video/dummy/*.c \ - ./src/video/pandora/*.c \ - - -OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g') - -all: config_copy $(TARGET_STATIC) $(TARGET_SHARED) - -$(TARGET_STATIC): $(OBJECTS) - $(AR) crv $@ $^ - $(RANLIB) $@ - -$(TARGET_SHARED): - $(CC) -shared -Wl,-soname,$(TARGET_SHARED).0 -o $(TARGET_SHARED).0.0.1 $(OBJECTS) - ln -s $(TARGET_SHARED).0.0.1 $(TARGET_SHARED).0 - ln -s $(TARGET_SHARED).0 $(TARGET_SHARED) - -config_copy: - cp include/SDL_config_wiz.h include/SDL_config.h - -clean: - rm -f $(TARGET_STATIC) $(TARGET_SHARED)* $(OBJECTS) - -install: - mkdir -p $(WIZSDK)/lib - mkdir -p $(WIZSDK)/include/SDL2 - cp -f $(TARGET_STATIC) $(WIZSDK)/lib - cp -f $(TARGET_SHARED).0.0.1 $(WIZSDK)/lib - rm -f $(WIZSDK)/lib/$(TARGET_SHARED).0 $(WIZSDK)/lib/$(TARGET_SHARED) - ln -s $(WIZSDK)/lib/$(TARGET_SHARED).0.0.1 $(WIZSDK)/lib/$(TARGET_SHARED).0 - ln -s $(WIZSDK)/lib/$(TARGET_SHARED).0 $(WIZSDK)/lib/$(TARGET_SHARED) - - cp $(TARGET_STATIC) ../../toolchain/libs - cp $(TARGET_SHARED).0.0.1 ../../toolchain/libs - rm -f ../../toolchain/libs/$(TARGET_SHARED).0 ../../toolchain/libs/$(TARGET_SHARED) - ln -s ../../toolchain/libs/$(TARGET_SHARED).0.0.1 ../../toolchain/libs/$(TARGET_SHARED).0 - ln -s ../../toolchain/libs/$(TARGET_SHARED).0 ../../toolchain/libs/$(TARGET_SHARED) - - cp $(TARGET_SHARED).0.0.1 ../nehe_demos/build/$(TARGET_SHARED).0 - cp -f include/*.h $(WIZSDK)/include/SDL2/ - cp -f include/*.h ../../toolchain/include/SDL2/ diff --git a/Engine/lib/sdl/README.txt b/Engine/lib/sdl/README.md similarity index 71% rename from Engine/lib/sdl/README.txt rename to Engine/lib/sdl/README.md index 431ba0e74..d1719bb6f 100644 --- a/Engine/lib/sdl/README.txt +++ b/Engine/lib/sdl/README.md @@ -1,11 +1,6 @@ - Simple DirectMedia Layer +# Simple DirectMedia Layer (SDL) Version 2.0 - (SDL) - - Version 2.0 - ---- https://www.libsdl.org/ Simple DirectMedia Layer is a cross-platform development library designed @@ -18,4 +13,5 @@ More extensive documentation is available in the docs directory, starting with README.md Enjoy! - Sam Lantinga (slouken@libsdl.org) + +Sam Lantinga (slouken@libsdl.org) diff --git a/Engine/lib/sdl/SDL2.spec.in b/Engine/lib/sdl/SDL2.spec.in index eee5e5d83..812d2d861 100644 --- a/Engine/lib/sdl/SDL2.spec.in +++ b/Engine/lib/sdl/SDL2.spec.in @@ -63,7 +63,7 @@ rm -rf $RPM_BUILD_ROOT %files %{__defattr} -%doc README*.txt COPYING.txt CREDITS.txt BUGS.txt +%doc README*.txt LICENSE.txt CREDITS.txt BUGS.txt %{_libdir}/lib*.%{__soext}.* %files devel diff --git a/Engine/lib/sdl/SDL2Config.cmake b/Engine/lib/sdl/SDL2Config.cmake index 4a5f64602..3e4ebe1e8 100644 --- a/Engine/lib/sdl/SDL2Config.cmake +++ b/Engine/lib/sdl/SDL2Config.cmake @@ -1 +1,119 @@ -include("${CMAKE_CURRENT_LIST_DIR}/SDL2Targets.cmake") +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2Targets.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/SDL2Targets.cmake") +endif() +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2mainTargets.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/SDL2mainTargets.cmake") +endif() +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2staticTargets.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/SDL2staticTargets.cmake") +endif() + +# on static-only builds create an alias +if(NOT TARGET SDL2::SDL2 AND TARGET SDL2::SDL2-static) + if(CMAKE_VERSION VERSION_LESS "3.18") + # Aliasing local targets is not supported on CMake < 3.18, so make it global. + set_target_properties(SDL2::SDL2-static PROPERTIES IMPORTED_GLOBAL TRUE) + endif() + add_library(SDL2::SDL2 ALIAS SDL2::SDL2-static) +endif() + +# provide ${SDL2_LIBRARIES}, ${SDL2_INCLUDE_DIRS} etc, like sdl2-config.cmake does, +# for compatibility between SDL2 built with autotools and SDL2 built with CMake + +# the following seems to work on Windows for both MSVC and MINGW+MSYS and with both SDL2Config/Target.cmake +# from vcpkg and from building myself with cmake from latest git +# AND on Linux when building SDL2 (tested current git) with CMake + +# the headers are easy - but note that this adds both .../include/ and .../include/SDL2/ +# while the SDL2_INCLUDE_DIRS of sdl2-config.cmake only add ...include/SDL2/ +# But at least if building worked with sdl2-config.cmake it will also work with this. +get_target_property(SDL2_INCLUDE_DIRS SDL2::SDL2 INTERFACE_INCLUDE_DIRECTORIES) + +# get the paths to the files to link against (.lib or .dll.a on Windows, .so or .a on Unix, ...) for both SDL2 and SDL2main + +# for the "normal"/release build they could be in lots of different properties.. +set(relprops IMPORTED_IMPLIB_RELEASE IMPORTED_IMPLIB_NOCONFIG IMPORTED_IMPLIB IMPORTED_IMPLIB_MINSIZEREL IMPORTED_IMPLIB_RELWITHDEBINFO + IMPORTED_LOCATION_RELEASE IMPORTED_LOCATION_NOCONFIG IMPORTED_LOCATION IMPORTED_LOCATION_MINSIZEREL IMPORTED_LOCATION_RELWITHDEBINFO) + +# fewer possibilities for debug builds +set(dbgprops IMPORTED_IMPLIB_DEBUG IMPORTED_LOCATION_DEBUG) + +foreach(prop ${relprops}) + get_target_property(sdl2implib SDL2::SDL2 ${prop}) + if(sdl2implib) + #message("set sdl2implib from ${prop}") + break() + endif() +endforeach() + +foreach(prop ${relprops}) + get_target_property(sdl2mainimplib SDL2::SDL2main ${prop}) + if(sdl2mainimplib) + #message("set sdl2mainimplib from ${prop}") + break() + endif() +endforeach() + +foreach(prop ${dbgprops}) + get_target_property(sdl2implibdbg SDL2::SDL2 ${prop}) + if(sdl2implibdbg) + #message("set sdl2implibdbg from ${prop}") + break() + endif() +endforeach() + +foreach(prop ${dbgprops}) + get_target_property(sdl2mainimplibdbg SDL2::SDL2main ${prop}) + if(sdl2mainimplibdbg) + #message("set sdl2mainimplibdbg from ${prop}") + break() + endif() +endforeach() + +if( sdl2implib AND sdl2mainimplib AND sdl2implibdbg AND sdl2mainimplibdbg ) + # we have both release and debug builds of SDL2 and SDL2main, so use this ugly + # generator expression in SDL2_LIBRARIES to support both in MSVC, depending on build type configured there + set(SDL2_LIBRARIES $,${sdl2mainimplibdbg},${sdl2mainimplib}> $,${sdl2implibdbg},${sdl2implib}>) +else() + if( (NOT sdl2implib) AND sdl2implibdbg ) # if we only have a debug version of the lib + set(sdl2implib ${sdl2implibdbg}) + endif() + if( (NOT sdl2mainimplib) AND sdl2mainimplibdbg ) # if we only have a debug version of the lib + set(sdl2mainimplib ${sdl2mainimplibdbg}) + endif() + + if( sdl2implib AND sdl2mainimplib ) + set(SDL2_LIBRARIES ${sdl2mainimplib} ${sdl2implib}) + elseif(WIN32 OR APPLE) # I think these platforms have a non-dummy SDLmain? + message(FATAL_ERROR, "SDL2::SDL2 and/or SDL2::SDL2main don't seem to contain any kind of IMPORTED_IMPLIB* or IMPORTED_LOCATION*") + elseif(sdl2implib) # on other platforms just libSDL2 will hopefully do? + set(SDL2_LIBRARIES ${sdl2implib}) + message(STATUS, "No SDL2main lib not found, I hope you don't need it..") + else() + message(FATAL_ERROR, "SDL2::SDL2 doesn't seem to contain any kind of lib to link against in IMPORTED_IMPLIB* or IMPORTED_LOCATION*") + endif() + + # TODO: should something like INTERFACE_LINK_LIBRARIES be appended? or wherever -mwindows and things like that + # might be defined (if they were defined by the CMake build at all; autotools has @SDL_RLD_FLAGS@ @SDL_LIBS@)? + # LINK_DEPENDS? LINK_FLAGS? + +endif() + +get_filename_component(SDL2_LIBDIR ${sdl2implib} PATH) + +# NOTE: SDL2_LIBRARIES now looks like "c:/path/to/SDL2main.lib;c:/path/to/SDL2.lib" +# which is different to what it looks like when coming from sdl2-config.cmake +# (there it's more like "-L${SDL2_LIBDIR} -lSDL2main -lSDL2" - and also -lmingw32 and -mwindows) +# This seems to work with both MSVC and MinGW though, while the other only worked with MinGW +# On Linux it looks like "/tmp/sdl2inst/lib/libSDL2main.a;/tmp/sdl2inst/lib/libSDL2-2.0.so.0.14.1" which also seems to work + +# the exec prefix is one level up from lib/ - TODO: really, always? at least on Linux there's /usr/lib/x86_64-bla-blub/libSDL2-asdf.so.0 .. +get_filename_component(SDL2_EXEC_PREFIX ${SDL2_LIBDIR} PATH) +set(SDL2_PREFIX ${SDL2_EXEC_PREFIX}) # TODO: could this be somewhere else? parent dir of include or sth? + +unset(sdl2implib) +unset(sdl2mainimplib) +unset(sdl2implibdbg) +unset(sdl2mainimplibdbg) +unset(relprops) +unset(dbgprops) diff --git a/Engine/lib/sdl/TODO.txt b/Engine/lib/sdl/TODO.txt index 0cd6c4db4..456a8ae3c 100644 --- a/Engine/lib/sdl/TODO.txt +++ b/Engine/lib/sdl/TODO.txt @@ -1,5 +1,5 @@ Future work roadmap: - * http://wiki.libsdl.org/moin.cgi/Roadmap + * http://wiki.libsdl.org/Roadmap * Check 1.2 revisions: 3554 - Need to resolve semantics for locking keys on different platforms diff --git a/Engine/lib/sdl/VisualC-WinRT/SDL2-WinRT.nuspec b/Engine/lib/sdl/VisualC-WinRT/SDL2-WinRT.nuspec deleted file mode 100644 index 3a663d59e..000000000 --- a/Engine/lib/sdl/VisualC-WinRT/SDL2-WinRT.nuspec +++ /dev/null @@ -1,23 +0,0 @@ - - - - SDL2-WinRT - 2.0.4-Unofficial - Sam Lantinga - David Ludwig - http://libsdl.org/license.php - http://libsdl.org - false - Unofficial pre-release of LibSDL2, built for WinRT platforms - Copyright 2015 - SDL2 SDL LibSDL OpenGL C C++ nativepackage - - - - - - - - - - diff --git a/Engine/lib/sdl/VisualC-WinRT/SDL2-WinRT.targets b/Engine/lib/sdl/VisualC-WinRT/SDL2-WinRT.targets deleted file mode 100644 index 51cddb785..000000000 --- a/Engine/lib/sdl/VisualC-WinRT/SDL2-WinRT.targets +++ /dev/null @@ -1,38 +0,0 @@ - - - - - WinRT81 - WinPhone80 - WinPhone81 - UWP - - $(MSBuildThisFileDirectory)..\..\bin\$(LibSDL2-DeviceType)\$(Platform) - - - - - - - - - $(LibSDL2-BinPath);%(AdditionalLibraryDirectories) - SDL2.lib;%(AdditionalDependencies) - - - - - - $(MSBuildThisFileDirectory)..\..\include;%(AdditionalIncludeDirectories) - - - - - - LibSDL2Binaries - $(ProjectName) - %(Filename)%(Extension) - - - - diff --git a/Engine/lib/sdl/VisualC-WinRT/SDL2main-WinRT-NonXAML.nuspec b/Engine/lib/sdl/VisualC-WinRT/SDL2main-WinRT-NonXAML.nuspec deleted file mode 100644 index 491c32386..000000000 --- a/Engine/lib/sdl/VisualC-WinRT/SDL2main-WinRT-NonXAML.nuspec +++ /dev/null @@ -1,22 +0,0 @@ - - - - SDL2main-WinRT-NonXAML - 2.0.4-Unofficial - Sam Lantinga - David Ludwig - http://libsdl.org/license.php - http://libsdl.org - false - WinMain() function for SDL2 + WinRT + CoreWindow (non-XAML) apps - Copyright 2015 - SDL2 SDL LibSDL OpenGL C C++ nativepackage - - - - - - - - - diff --git a/Engine/lib/sdl/VisualC-WinRT/SDL2main-WinRT-NonXAML.targets b/Engine/lib/sdl/VisualC-WinRT/SDL2main-WinRT-NonXAML.targets deleted file mode 100644 index 4dede303e..000000000 --- a/Engine/lib/sdl/VisualC-WinRT/SDL2main-WinRT-NonXAML.targets +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - true - - - - diff --git a/Engine/lib/sdl/VisualC-WinRT/tests/loopwave/Assets/Logo.png b/Engine/lib/sdl/VisualC-WinRT/tests/loopwave/Assets/Logo.png deleted file mode 100644 index e26771cb33a49bbef824aa333737181b0a5b09a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 801 zcmeAS@N?(olHy`uVBq!ia0vp^(?FPm4M^HB7Cr(}k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=1foIEGZ*dUJQLud<^=L*gE#63Ho!PGzwUb%GPK6&5iF zt!p@aGNX}6(PVh|N)M-?0RNcTbjaWgEU8noxUax-n>&3Ay)#!y&O11y2sKEF zt72@XC1)RvT6Xw=y_`Ce)`nGULLL^lI$kwi^E+dQT7YeXY4GvlRR%kj1x$VZi%Bdd zz}2Giy=-_$h+v#(S+};)DuE4EM?_^qB_eDeo@&q%StD1F>L|*0ZC2sb-}llSMTM?O z6{b3iid~yk@VE7q7Wb+P8?H5IYp?pSVcLE~18m#ygK20HL@6W5woI~Fjlw$fX1U{xQA5a+t0 zH$WNIb=fNpWHo}M9#;K6eszDZKty_|-?j4iocj5#zotrWc;@;w`H@=mjsvS2wXX0_ zY}l$4@^sE?UcC)ji*L=Z&}P!xaL&2((OQlj2dv~pV-ifAS;ZsH1{`D!GY%yys5WH)f>ZLo5m%6XjuXdbKMR7MEHSyb{m!_{Afji&MT$_sz7 z>1{~MlIFe28FRN(GC_~;#Jp4ADipP+9hh|P#-&`vO-Upt3jE0@YLh(^55uYWl9g)Z RA3>Rb!PC{xWt~$(69A&hN*MqE diff --git a/Engine/lib/sdl/VisualC-WinRT/tests/loopwave/Assets/SmallLogo.png b/Engine/lib/sdl/VisualC-WinRT/tests/loopwave/Assets/SmallLogo.png deleted file mode 100644 index 1eb0d9d528c42f132872e8af4dc563081b0b9aff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 329 zcmV-P0k-~$P)q$gGRCwC#*X;?zAP@%N+|i#I!$mrh zlQ>KU$Rdu>|JH&931_?y6Djl{gb>4nCV5pzDJ?S!mq|4ZejKj%i@j$H{#ML~2Y{DF z$=}bKPaz+UGt{v(4CTQQXym}&iW8{s!ew~XIE7NLjQpy#I2S$rous$~?f%DHT#B*+ zq=#!zc5=0FEqWFpB%UE(L807on!pidHPLgYO}XEgorrg;PB=8ipgQ5u5`&g_MQaRd zaU7Ao8XQMuuN21-s0PPTs1%38x_Yl3Fs-|Y4!C-;M-8g@n*v@1|s#GQ665=9@Rxy?u0YW0&WN+~=RXpPbVXXL4m7Aq=E6I0%{06TwRn=U9d8>exk> zD-Z%M3DNQ`bTLSEF=%NFyoHcAkD*CiXqljo*0E?o$GiDC4q}}|%*0WghLlK#npw?hecrM}Mw?`E(z5C8< z8&*b^!{>5?4aT89vdrgBgSc-x6JZD3F^l#*G(@OO*^1D%Eu7?HAy<3kTLqW9N{^#6vso zVQwY48q7)m{~xQ64RV7{E7Y=&T~?^05Ky`5oNQ8bLgFCPq9co^R09BVRS1OAmH;hU zC#q(N!gNqm!zU#%sv{r5mm-Uv8b-~a1F-;p^>)pnXfKge4s9?;;MFIr*fixPG}NBA z6_G5BEmeO6XXh(emkciB{7tA;iwC2^s^VzyU_h0@ae84ACMY`cIDEju=<`q|2QAEv zW_)W|i|9aknqdmS=#w73eW_csQ$8IhT^vY1^1;X3&J0{%*tcQq!gJpr3w?TJc~@5= zKV5sM{$3k>b#S$@CTkhIF*{v*u(F&$&Yq1naHxt8Mz2N%7aQ3(^VNRZahk1||7?Bl z*idzO_u)FhRj4cPzDO>YA>>lxAGaciEiX8Xzp1SVPv91};$OG3cC&8!v3{Jq^kH@8 UTIccK;hzT5*3#}uZuEx!0OwrBv;Y7A diff --git a/Engine/lib/sdl/VisualC-WinRT/tests/loopwave/Assets/StoreLogo.png b/Engine/lib/sdl/VisualC-WinRT/tests/loopwave/Assets/StoreLogo.png deleted file mode 100644 index dcb672712c6823a0c91548ded70a8acb85536b4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 429 zcmV;e0aE^nP)NtYJa1l)bQ5qwGXpZbs7%2oRMd4y35$s&66(fxhNg8W02!vSn zdlrL2h^Fx+3=$z;kK{0D#MyeJ8WRWZcLSf(PcQ_mLOhrmC}O-tX^0c>5`YvCUZVsc zG-6#78ubjJ5nA;OX&^K(q=i6ZNE3m?kTwE^AqxZoLskfB3|S&1F=UO9!cY$g2@Lgu z;9{sJ1P9|X2L`r1#Gs8R{E^$PRrMaC86q| - - - - - - loopwave_VS2012_WinRT - David - Assets\StoreLogo.png - - - - 6.2.1 - 6.2.1 - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Engine/lib/sdl/VisualC-WinRT/tests/loopwave/loopwave_VS2012_TemporaryKey.pfx b/Engine/lib/sdl/VisualC-WinRT/tests/loopwave/loopwave_VS2012_TemporaryKey.pfx deleted file mode 100644 index 3c07b779f56405e71431543ad8e28b5bbb995690..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2504 zcmY+Ec{tQ-8^?cR#xSxQM3zCxgpA!B3CX^fec$(WM6U=9hHPQ%jj}s zUSkr9#Kg&@4)3pXz3(~K`Qv_`@BMl1`@Zgfo-YQE7-WDzF?d7*9C3kQKsaQBFhR=k zh;SGl5e#B~44(1mUr&tNFg)WXh}XcNz)$_JizQkWALyej1ZjV{}>$34r4~O zzT(_zQ6VxgFipYmum!R4@3eomc+?d6L!Kf~t$1h?NUv@Zk&~3YQ5tYuZ*N!eXK( zJjE1cw7SS8YK#jb-63v+o!CvjWh->q#Eeg6&{7IF)%hc5pjs{zoq(O4e~`DM!CsEhx1yRL zy5{a=!}5zyM4Nk2SGE*4mMT%$z0Kh0M2mXonnQ6fQyv!$XMV#M9?}(ljOvP8RCe!|>f2((*_S@pleL@dAN*ga_Lz=vFNGQ zS<1T;m1bhOA$y0?3@+t}o11k;P}{th;w?dSp*E0vvo%Mw*L?8e0?Zfl;zC3c^AUK~JPdvO;^Q!-(!77_a<6=QPD;HTM0a+$Hb?8~U7k4?@@>dMhSaN0Ihn}!FqEf(&V zXn*?n+;i8RZ;R~99&AP|rWBG?c2Rwo1~Jck^~V``tV= z#z1yb{f!*C$fh6;@x@BCM9nYw3GOA^fJwVSVz^IS>4xn{bBqVEY1G_(-NjsxW)hzx z?zo=JUx|u7$Uyf)wj0KJt@S3}hQ^=Fj_g(y7V0W8U#Q6={YufNzHY3z>FJnI>vAec zf8Z58?bGEWtvYfZqR=L#yPeHT$g=#pc4~S1k0Ki1bEib?^yAD4k2~UVpV16?3$I3n^MteaiNEEfj`!NjfrSZk}u%5w~``Gd`b# zMbDe;eSLe$MDr?HwHyDRM{epC4Pz_cOAXf#IJ6PojX0m@(dw^Z?AX5gz15g0N2jdJ!NW&p82ws&7B5xsL2ABf= zU<(ci1tP%k0d4>&;5vBzBq4w=nCXBz8VCbfD465GVPSyZUtK7`;;*_WF!KV}!eQ`G z-@i9!f|ui=b|A81fB@iS`p*mGUzQL5Y583=eYlV6xaUvHPryS_2|8B|%VlHD+=|*< zlotPtPFb|gp?fc;W#qeBpe6esG+J7Q%CYr{DaVc~kb8i%$)_ak&JXoN7x*j<)o`XQ z8#L+RwXJo2Wivx)LjTTYi^@{9TG+F&Pld4v@oYF@G?&YG|Dkl`R++GXhCBkVMY#0^J30Qt=0R7S3;{F zJL%^13O3J;WpdmYg-)#8`}*)vz{l-FL92NVDUrT|xymV7~3EzxmP{``)6jtNF2nd!S+CRI$h>9;&oP~k>ktmxVE#z zq)IGv^}+|1ZYQ!v7Giw%fP%GAF%^p|{?e}_BV~M)du!f*ak&0~)bV|yaSvhbQ2C^! zM6HOM^`l|P6~-rJzSUD)RydxZ&c-ZR$^6BTA417`*_yY}GEUEWZ4S-j{0v_cR$J`+CZwm-mh0 z{Sx+lBV*qY*L)#gYWWP?QAr&tSj{oM1c^(^U#k=gQ0IgMVPhUfZG0r^(d!XvBCaqG zlc6{y7|C-PqmB{9Fu@t6*`W-AFys>Yl`q$?us-|chdhcMb*VSG+^8_5X>E=8(>Iky ToyCz)S?HfgOO(BupC9bM?VoGZ diff --git a/Engine/lib/sdl/VisualC-WinRT/tests/testthread/Assets/Logo.png b/Engine/lib/sdl/VisualC-WinRT/tests/testthread/Assets/Logo.png deleted file mode 100644 index e26771cb33a49bbef824aa333737181b0a5b09a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 801 zcmeAS@N?(olHy`uVBq!ia0vp^(?FPm4M^HB7Cr(}k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=1foIEGZ*dUJQLud<^=L*gE#63Ho!PGzwUb%GPK6&5iF zt!p@aGNX}6(PVh|N)M-?0RNcTbjaWgEU8noxUax-n>&3Ay)#!y&O11y2sKEF zt72@XC1)RvT6Xw=y_`Ce)`nGULLL^lI$kwi^E+dQT7YeXY4GvlRR%kj1x$VZi%Bdd zz}2Giy=-_$h+v#(S+};)DuE4EM?_^qB_eDeo@&q%StD1F>L|*0ZC2sb-}llSMTM?O z6{b3iid~yk@VE7q7Wb+P8?H5IYp?pSVcLE~18m#ygK20HL@6W5woI~Fjlw$fX1U{xQA5a+t0 zH$WNIb=fNpWHo}M9#;K6eszDZKty_|-?j4iocj5#zotrWc;@;w`H@=mjsvS2wXX0_ zY}l$4@^sE?UcC)ji*L=Z&}P!xaL&2((OQlj2dv~pV-ifAS;ZsH1{`D!GY%yys5WH)f>ZLo5m%6XjuXdbKMR7MEHSyb{m!_{Afji&MT$_sz7 z>1{~MlIFe28FRN(GC_~;#Jp4ADipP+9hh|P#-&`vO-Upt3jE0@YLh(^55uYWl9g)Z RA3>Rb!PC{xWt~$(69A&hN*MqE diff --git a/Engine/lib/sdl/VisualC-WinRT/tests/testthread/Assets/SmallLogo.png b/Engine/lib/sdl/VisualC-WinRT/tests/testthread/Assets/SmallLogo.png deleted file mode 100644 index 1eb0d9d528c42f132872e8af4dc563081b0b9aff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 329 zcmV-P0k-~$P)q$gGRCwC#*X;?zAP@%N+|i#I!$mrh zlQ>KU$Rdu>|JH&931_?y6Djl{gb>4nCV5pzDJ?S!mq|4ZejKj%i@j$H{#ML~2Y{DF z$=}bKPaz+UGt{v(4CTQQXym}&iW8{s!ew~XIE7NLjQpy#I2S$rous$~?f%DHT#B*+ zq=#!zc5=0FEqWFpB%UE(L807on!pidHPLgYO}XEgorrg;PB=8ipgQ5u5`&g_MQaRd zaU7Ao8XQMuuN21-s0PPTs1%38x_Yl3Fs-|Y4!C-;M-8g@n*v@1|s#GQ665=9@Rxy?u0YW0&WN+~=RXpPbVXXL4m7Aq=E6I0%{06TwRn=U9d8>exk> zD-Z%M3DNQ`bTLSEF=%NFyoHcAkD*CiXqljo*0E?o$GiDC4q}}|%*0WghLlK#npw?hecrM}Mw?`E(z5C8< z8&*b^!{>5?4aT89vdrgBgSc-x6JZD3F^l#*G(@OO*^1D%Eu7?HAy<3kTLqW9N{^#6vso zVQwY48q7)m{~xQ64RV7{E7Y=&T~?^05Ky`5oNQ8bLgFCPq9co^R09BVRS1OAmH;hU zC#q(N!gNqm!zU#%sv{r5mm-Uv8b-~a1F-;p^>)pnXfKge4s9?;;MFIr*fixPG}NBA z6_G5BEmeO6XXh(emkciB{7tA;iwC2^s^VzyU_h0@ae84ACMY`cIDEju=<`q|2QAEv zW_)W|i|9aknqdmS=#w73eW_csQ$8IhT^vY1^1;X3&J0{%*tcQq!gJpr3w?TJc~@5= zKV5sM{$3k>b#S$@CTkhIF*{v*u(F&$&Yq1naHxt8Mz2N%7aQ3(^VNRZahk1||7?Bl z*idzO_u)FhRj4cPzDO>YA>>lxAGaciEiX8Xzp1SVPv91};$OG3cC&8!v3{Jq^kH@8 UTIccK;hzT5*3#}uZuEx!0OwrBv;Y7A diff --git a/Engine/lib/sdl/VisualC-WinRT/tests/testthread/Assets/StoreLogo.png b/Engine/lib/sdl/VisualC-WinRT/tests/testthread/Assets/StoreLogo.png deleted file mode 100644 index dcb672712c6823a0c91548ded70a8acb85536b4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 429 zcmV;e0aE^nP)NtYJa1l)bQ5qwGXpZbs7%2oRMd4y35$s&66(fxhNg8W02!vSn zdlrL2h^Fx+3=$z;kK{0D#MyeJ8WRWZcLSf(PcQ_mLOhrmC}O-tX^0c>5`YvCUZVsc zG-6#78ubjJ5nA;OX&^K(q=i6ZNE3m?kTwE^AqxZoLskfB3|S&1F=UO9!cY$g2@Lgu z;9{sJ1P9|X2L`r1#Gs8R{E^$PRrMaC86q| - - - - - - testthread_VS2012_WinRT - David - Assets\StoreLogo.png - - - - 6.2.1 - 6.2.1 - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Engine/lib/sdl/VisualC-WinRT/tests/testthread/testthread_VS2012_TemporaryKey.pfx b/Engine/lib/sdl/VisualC-WinRT/tests/testthread/testthread_VS2012_TemporaryKey.pfx deleted file mode 100644 index 97fd1e190077fd22da37b95fd53038fdd2ab7917..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2504 zcmY+Fc|4SB8^@nnj2VNngel8d$8IbUDqEJsG%<*X7>p(Rl2n|rMZ(FxWh-lT5rb?U z`e{L_Yf%YaJ}$-CI~$w zn~HLRQ&ILHzJsUIZU3u8HxH-MeFE_eI3^J2|E*$VfIzdU@I5>gzK!QbF#I2bn=`|a z2Meza2ENVKL!tCTa4LLAwDUt<9ul$t6S@~LT!$@7>n7VbeD5>WH>~pcDUHn zlayc96V#zEv@4QDw5z`S-KTNxiRO@oUFf7;%vvi@#QYWF6j*!?v-7wD&o$hk;roGR zjVwc(buh=hjXpjIMx<<{%^Y6t;Y%(WtKrf6Q7ILB1sg>6keMq~_0aU>co<)N$@tue z7lc{7#PByhuXTc-tn2m4`*%!>M)phlXv){rqO+Jxu93xky1%~lG&fmNvs7B|8auXG zvobleSVn&Jt=x!dyYE)9uh)B?N%C8+SyMN)TEK4MN-D7=hb2HE+~1D-4V7PH0M>oo z`nk!ycXLlauis`4kCXW0=R$yashJxKC<9DMECSqCp9IM$y^C;DR6Fn|3 z`D~?XTvl0oHsXorb?9h^%EOn1Q|;U>A4WH3maBEYgsIMBKFLJ<$kEhtQIq%-9oR^^ zRId}j=Z ztB_n?+GI*(OmVZg_YuN;iuq?IRQ%+Y#D&I7{*#?93!J$^>6~NFXZXc5a~ndGQ#o~h z=um6x+l}n|7TKCJ!^Qx{WEK`rwbeV-Axe0?jrT+85372MU^Dy_4N8DulZ&l0#5 zESf2+biT)6aQsuhx2|sck1`h4&eBKyvw}x=kEQ)eI~5WF=d46tE3?ok6#ge$ch?;V zGFpst-)WW)R#J_6c;mClViQbSnd0Z1&AZ9? zDEa;Q4#qc=4!kH*eXO`t>hkiJh5}@73x`F9?mGw&PkhvkC&bAG+91~4xJ0&YPX=KX zW85b1keHkKLQPGYghOas%Ffg&5QaD5 zl)0tBJszHh(_Jp*NVCixwywqI#V23Zq85pieP`{7quGfWr|Rie!$W+uhOOIq^%9CSCflir`Wpg+UbWtJ-IY0QTE>{Xj#~2cZWX|ID%YG`dO48P~KU-UzdON_W~L7Zep5rCuN@^KPa%e zpl!Y2v#sBX&&slq=%M4nSLX1?ziMKY`p$B;zB)oa6iGxEn0Et*9j^_-3^dHeQN^sM zkkb|zZ`t4a@oazFB1E}(V6sYnbvjZaq zFjfL*DX@YEi7gn}gDMA*!5#%b7Ocww%Anfetq>>)1OyJDDzQLhiM#~B5O4xpy#RN> z8ypUR4}b-X!TA?)102Cj3ycE*50JToxfghd2SE926&4`=)#nFhWbjBYJQe2n_s!`M z*;Lp~5Rsq|02IT2Dv*C!J>r+ud)TPkZ1d+S{IdFBDhwM9Ep%FFyML8uRDBDgGRb{n zLd|rjInPFLJBYt^6LDzDYn#T$ZDh!;yKbtk@~4ch>OP8d?8?}<+Q0!;jIpr)`m3XQ zA=KA-7Rk1qQ?3jSQrV5u^S<(K?{9G7oF%=+Go%%B1w$xf1(E}DNBJ12sWq>J<<0bL zN1-@}4&+bC?pzwF7gM9DrzWT!l(r?7?S|bfZ7rqm*{=%Zeipp|S-Qa-V997E8F4DI zBuI39(@sshW%{lmt6mUtTAriqC%x4iElzB9q;u1ar+&qeg;mg{IM?rCaiynPJDee7(K^96l3M}x1H z9raTVWc@bRDpXLPbJDjLPn`l*lD)dp%VTltd#{VxJ_bycoi5po(LbeoQ`N#Y`C34+MiiCZe z6xCdI`g9Hg)YX-ij25hG2VbZSL>_uoy6$nLRCezMC-J$bQIfkB&QTX%R*}vQXYac{ z>#SGuWp7QxB%B$8>L2{B5!xW2G49Y>9`l(PF-#a&jtPnEQid|Pz=!NXyRNF{NqYrJ4tebnsJS9q zMw$s+7n{Ng&0uvq*0^<2&(3s}ekRO%>+WG?z zpBgWp2}Y8k&G%gxu3gc_#@rN-bK4lKYd5n@fAmD)_(WoGXv#M@%Aco#G<(n2UNiI= zIT5dl=fl$@=p>k7(6ey%@NpTL30h#0FtS8ZdqP3%o$%x}I6MFRdaI~^b<*0;3@V!E S`-p?_$L3!@7-%tneg6fLkX32` diff --git a/Engine/lib/sdl/VisualC.html b/Engine/lib/sdl/VisualC.html deleted file mode 100644 index 0631832e8..000000000 --- a/Engine/lib/sdl/VisualC.html +++ /dev/null @@ -1,146 +0,0 @@ - - - Using SDL with Microsoft Visual C++ - - -

- Using SDL with Microsoft Visual C++ -

-

- by Lion Kimbro and additions by - James Turk -

-

- You can either use the precompiled libraries from the SDL Download web site , or you can build SDL yourself. -

-

- Building SDL -

-

- Go into the VisualC directory and double-click on the Visual Studio solution for your version of Visual Studio, e.g. SDL_VS2008.sln This should open up the IDE. -

-

- There are different solution files for the various - versions of the IDE. Please use the appropriate version - 2008, 2010, 2012 or 2013. -

-

- Build the .dll and .lib files. -

-

- This is done by right clicking on each project in turn (Projects are listed in - the Workspace panel in the FileView tab), and selecting "Build". -

-

- You may get a few warnings, but you should not get any errors. You do have to - have at least the DirectX 9 SDK installed, however. The latest - version of DirectX can be downloaded from Microsoft. -

-

- Later, we will refer to the following .lib and .dll files that have just been - generated: -

-
    -
  • SDL2.dll
  • -
  • SDL2.lib
  • -
  • SDL2main.lib
  • -
-

- Search for these using the Windows Find (Windows-F) utility inside the VisualC directory. -

-

- Creating a Project with SDL -

-

- Create a project as a Win32 Application. -

-

- Create a C++ file for your project. -

-

- Set the C runtime to "Multi-threaded DLL" in the menu: Project|Settings|C/C++ - tab|Code Generation|Runtime Library . -

-

- Add the SDL include directory to your list of includes in the - menu: Project|Settings|C/C++ tab|Preprocessor|Additional include directories - . -
- VC7 Specific: Instead of doing this I find it easier to - add the include and library directories to the list that VC7 keeps. Do this by - selecting Tools|Options|Projects|VC++ Directories and under the "Show - Directories For:" dropbox select "Include Files", and click the "New Directory - Icon" and add the [SDLROOT]\include directory (e.g. If you installed to - c:\SDL\ add c:\SDL\include). Proceed to change the - dropbox selection to "Library Files" and add [SDLROOT]\lib. -

-

- The "include directory" I am referring to is the include folder - within the main SDL directory (the one that this HTML file located within). -

-

- Now we're going to use the files that we had created earlier in the Build SDL - step. -

-

- Copy the following files into your Project directory: -

-
    -
  • SDL2.dll
  • -
-

- Add the following files to your project (It is not necessary to copy them to - your project directory): -

-
    -
  • SDL2.lib
  • -
  • SDL2main.lib
  • -
-

- (To add them to your project, right click on your project, and select "Add - files to project") -

-

Instead of adding the files to your project it is more - desirable to add them to the linker options: Project|Properties|Linker|Command - Line and type the names of the libraries to link with in the "Additional - Options:" box.  Note: This must be done for each build - configuration (e.g. Release,Debug).

-

- SDL 101, First Day of Class -

-

- Now create the basic body of your project. The body of your program should take - the following form: -


-#include "SDL.h"
-
-int main( int argc, char* argv[] )
-{
-  // Body of the program goes here.
-  return 0;
-}
-			
-

-

- That's it! -

-

- I hope that this document has helped you get through the most difficult part of - using the SDL: installing it. Suggestions for improvements to this document - should be sent to the writers of this document. -

-

- Thanks to Paulus Esterhazy (pesterhazy@gmx.net), for the work on VC++ port. -

-

- This document was originally called "VisualC.txt", and was written by - Sam Lantinga. -

-

- Later, it was converted to HTML and expanded into the document that you see - today by Lion Kimbro. -

-

Minor Fixes and Visual C++ 7 Information (In Green) was added by James Turk -

- - diff --git a/Engine/lib/sdl/WhatsNew.txt b/Engine/lib/sdl/WhatsNew.txt index 651cfc1c3..33382ecea 100644 --- a/Engine/lib/sdl/WhatsNew.txt +++ b/Engine/lib/sdl/WhatsNew.txt @@ -1,6 +1,118 @@ This is a list of major changes in SDL's version history. +--------------------------------------------------------------------------- +2.0.22: +--------------------------------------------------------------------------- + +General: +* Added the hint SDL_HINT_JOYSTICK_ROG_CHAKRAM to control whether ROG Chakram mice show up as joysticks + + +--------------------------------------------------------------------------- +2.0.20: +--------------------------------------------------------------------------- + +General: +* SDL_RenderGeometryRaw() takes a pointer to SDL_Color, not int. You can cast color data in SDL_PIXELFORMAT_RGBA32 format (SDL_PIXELFORMAT_ABGR8888 on little endian systems) for this parameter. +* Improved accuracy of horizontal and vertical line drawing when using OpenGL or OpenGLES +* Added the hint SDL_HINT_RENDER_LINE_METHOD to control the method of line drawing used, to select speed, correctness, and compatibility. + +Windows: +* Fixed size of custom cursors + +Linux: +* Fixed hotplug controller detection, broken in 2.0.18 + + +--------------------------------------------------------------------------- +2.0.18: +--------------------------------------------------------------------------- + +General: +* The SDL wiki documentation and development headers are automatically kept in sync +* Each function has information about in which version of SDL it was introduced +* SDL-specific CMake options are now prefixed with 'SDL_'. Be sure to update your CMake build scripts accordingly! +* Added the hint SDL_HINT_APP_NAME to let SDL know the name of your application for various places it might show up in system information +* Added SDL_RenderGeometry() and SDL_RenderGeometryRaw() to allow rendering of arbitrary shapes using the SDL 2D render API +* Added SDL_SetTextureUserData() and SDL_GetTextureUserData() to associate application data with an SDL texture +* Added SDL_RenderWindowToLogical() and SDL_RenderLogicalToWindow() to convert between window coordinates and logical render coordinates +* Added SDL_RenderSetVSync() to change whether a renderer present is synchronized with vblank at runtime +* Added SDL_PremultiplyAlpha() to premultiply alpha on a block of SDL_PIXELFORMAT_ARGB8888 pixels +* Added a window event SDL_WINDOWEVENT_DISPLAY_CHANGED which is sent when a window changes what display it's centered on +* Added SDL_GetWindowICCProfile() to query a window's ICC profile, and a window event SDL_WINDOWEVENT_ICCPROF_CHANGED that is sent when it changes +* Added the hint SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY to allow EGL windows to be transparent instead of opaque +* SDL_WaitEvent() has been redesigned to use less CPU in most cases +* Added SDL_SetWindowMouseRect() and SDL_GetWindowMouseRect() to confine the mouse cursor to an area of a window +* You can now read precise mouse wheel motion using 'preciseX' and 'preciseY' event fields +* Added SDL_GameControllerHasRumble() and SDL_GameControllerHasRumbleTriggers() to query whether a game controller supports rumble +* Added SDL_JoystickHasRumble() and SDL_JoystickHasRumbleTriggers() to query whether a joystick supports rumble +* SDL's hidapi implementation is now available as a public API in SDL_hidapi.h + +Windows: +* Improved relative mouse motion over Windows Remote Desktop +* Added the hint SDL_HINT_IME_SHOW_UI to show native UI components instead of hiding them (defaults off) + +Windows/UWP: +* WGI is used instead of XInput for better controller support in UWP apps + +Linux: +* Added the hint SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME to set the activity that's displayed by the system when the screensaver is disabled +* Added the hint SDL_HINT_LINUX_JOYSTICK_CLASSIC to control whether /dev/input/js* or /dev/input/event* are used as joystick devices +* Added the hint SDL_HINT_JOYSTICK_DEVICE to allow the user to specify devices that will be opened in addition to the normal joystick detection +* Added SDL_LinuxSetThreadPriorityAndPolicy() for more control over a thread priority on Linux + +Android: +* Added support for audio output and capture using AAudio on Android 8.1 and newer +* Steam Controller support is disabled by default, and can be enabled by setting the hint SDL_HINT_JOYSTICK_HIDAPI_STEAM to "1" before calling SDL_Init() + +Apple Arcade: +* Added SDL_GameControllerGetAppleSFSymbolsNameForButton() and SDL_GameControllerGetAppleSFSymbolsNameForAxis() to support Apple Arcade titles + +iOS: +* Added documentation that the UIApplicationSupportsIndirectInputEvents key must be set to true in your application's Info.plist in order to get real Bluetooth mouse events. +* Steam Controller support is disabled by default, and can be enabled by setting the hint SDL_HINT_JOYSTICK_HIDAPI_STEAM to "1" before calling SDL_Init() + + +--------------------------------------------------------------------------- +2.0.16: +--------------------------------------------------------------------------- +General: +* Added SDL_FlashWindow() to get a user's attention +* Added SDL_GetAudioDeviceSpec() to get the preferred audio format of a device +* Added SDL_SetWindowAlwaysOnTop() to dynamically change the SDL_WINDOW_ALWAYS_ON_TOP flag for a window +* Added SDL_SetWindowKeyboardGrab() to support grabbing the keyboard independently of the mouse +* Added SDL_SoftStretchLinear() to do bilinear scaling between 32-bit software surfaces +* Added SDL_UpdateNVTexture() to update streaming NV12/21 textures +* Added SDL_GameControllerSendEffect() and SDL_JoystickSendEffect() to allow sending custom trigger effects to the DualSense controller +* Added SDL_GameControllerGetSensorDataRate() to get the sensor data rate for PlayStation and Nintendo Switch controllers +* Added support for the Amazon Luna game controller +* Added rumble support for the Google Stadia controller using the HIDAPI driver +* Added SDL_GameControllerType constants for the Amazon Luna and Google Stadia controllers +* Added analog rumble for Nintendo Switch Pro controllers using the HIDAPI driver +* Reduced CPU usage when using SDL_WaitEvent() and SDL_WaitEventTimeout() + +Windows: +* Added SDL_SetWindowsMessageHook() to set a function that is called for all Windows messages +* Added SDL_RenderGetD3D11Device() to get the D3D11 device used by the SDL renderer + +Linux: +* Greatly improved Wayland support +* Added support for audio output and capture using Pipewire +* Added the hint SDL_HINT_AUDIO_INCLUDE_MONITORS to control whether PulseAudio recording should include monitor devices +* Added the hint SDL_HINT_AUDIO_DEVICE_STREAM_ROLE to describe the role of your application for audio control panels + +Android: +* Added SDL_AndroidShowToast() to show a lightweight notification + +iOS: +* Added support for mouse relative mode on iOS 14.1 and newer +* Added support for the Xbox Series X controller + +tvOS: +* Added support for the Xbox Series X controller + + --------------------------------------------------------------------------- 2.0.14: --------------------------------------------------------------------------- diff --git a/Engine/lib/sdl/Xcode-iOS/Demos/Info.plist b/Engine/lib/sdl/Xcode-iOS/Demos/Info.plist index fbbaf7f93..aa7b5f6e0 100644 --- a/Engine/lib/sdl/Xcode-iOS/Demos/Info.plist +++ b/Engine/lib/sdl/Xcode-iOS/Demos/Info.plist @@ -16,6 +16,8 @@ 6.0 CFBundleName ${PRODUCT_NAME} + CFBundleShortVersionString + 1.0.0 CFBundlePackageType APPL CFBundleSignature @@ -28,5 +30,7 @@ iOS Launch Screen UISupportedInterfaceOrientations + UIApplicationSupportsIndirectInputEvents + diff --git a/Engine/lib/sdl/Xcode-iOS/Demos/src/accelerometer.c b/Engine/lib/sdl/Xcode-iOS/Demos/src/accelerometer.c index 2cc0123c2..925aee4e3 100644 --- a/Engine/lib/sdl/Xcode-iOS/Demos/src/accelerometer.c +++ b/Engine/lib/sdl/Xcode-iOS/Demos/src/accelerometer.c @@ -58,7 +58,7 @@ render(SDL_Renderer *renderer, int w, int h, double deltaTime) ay * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT * deltaMilliseconds; - speed = sqrt(shipData.vx * shipData.vx + shipData.vy * shipData.vy); + speed = SDL_sqrt(shipData.vx * shipData.vx + shipData.vy * shipData.vy); if (speed > 0) { /* compensate for friction */ diff --git a/Engine/lib/sdl/Xcode-iOS/Demos/src/fireworks.c b/Engine/lib/sdl/Xcode-iOS/Demos/src/fireworks.c index 2c4f621f1..600d20bbb 100644 --- a/Engine/lib/sdl/Xcode-iOS/Demos/src/fireworks.c +++ b/Engine/lib/sdl/Xcode-iOS/Demos/src/fireworks.c @@ -109,7 +109,7 @@ stepParticles(double deltaTime) } } else { float speed = - sqrt(curr->xvel * curr->xvel + curr->yvel * curr->yvel); + SDL_sqrt(curr->xvel * curr->xvel + curr->yvel * curr->yvel); /* if wind resistance is not powerful enough to stop us completely, then apply winde resistance, otherwise just stop us completely */ if (WIND_RESISTANCE * deltaMilliseconds < speed) { @@ -194,15 +194,15 @@ explodeEmitter(struct particle *emitter) /* come up with a random angle and speed for new particle */ float theta = randomFloat(0, 2.0f * 3.141592); float exponent = 3.0f; - float speed = randomFloat(0.00, powf(0.17, exponent)); - speed = powf(speed, 1.0f / exponent); + float speed = randomFloat(0.00, SDL_powf(0.17, exponent)); + speed = SDL_powf(speed, 1.0f / exponent); /* select the particle at the end of our array */ struct particle *p = &particles[num_active_particles]; /* set the particles properties */ - p->xvel = speed * cos(theta); - p->yvel = speed * sin(theta); + p->xvel = speed * SDL_cos(theta); + p->yvel = speed * SDL_sin(theta); p->x = emitter->x + emitter->xvel; p->y = emitter->y + emitter->yvel; p->isActive = 1; @@ -297,7 +297,7 @@ spawnEmitterParticle(GLfloat x, GLfloat y) p->y = screen_h; /* set velocity so that terminal point is (x,y) */ p->xvel = 0; - p->yvel = -sqrt(2 * ACCEL * (screen_h - y)); + p->yvel = -SDL_sqrt(2 * ACCEL * (screen_h - y)); /* set other attributes */ p->size = 10 * pointSizeScale; p->type = emitter; diff --git a/Engine/lib/sdl/Xcode-iOS/Demos/src/mixer.c b/Engine/lib/sdl/Xcode-iOS/Demos/src/mixer.c index 14945ad33..18e33f134 100644 --- a/Engine/lib/sdl/Xcode-iOS/Demos/src/mixer.c +++ b/Engine/lib/sdl/Xcode-iOS/Demos/src/mixer.c @@ -111,7 +111,7 @@ loadSound(const char *file, struct sound *s) if (SDL_ConvertAudio(&cvt) == -1) { /* convert the sound */ fatalError("could not convert .wav"); } - SDL_free(s->buffer); /* free the original (unconverted) buffer */ + SDL_free(s->buffer); /* Free the original (unconverted) buffer */ s->buffer = cvt.buf; /* point sound buffer to converted buffer */ s->length = cvt.len_cvt; /* set sound buffer's new length */ } diff --git a/Engine/lib/sdl/Xcode-iOS/Demos/src/touch.c b/Engine/lib/sdl/Xcode-iOS/Demos/src/touch.c index 470b9d1bd..918240b82 100644 --- a/Engine/lib/sdl/Xcode-iOS/Demos/src/touch.c +++ b/Engine/lib/sdl/Xcode-iOS/Demos/src/touch.c @@ -21,7 +21,7 @@ void drawLine(SDL_Renderer *renderer, float startx, float starty, float dx, float dy) { - float distance = sqrt(dx * dx + dy * dy); /* length of line segment (pythagoras) */ + float distance = SDL_sqrt(dx * dx + dy * dy); /* length of line segment (pythagoras) */ int iterations = distance / PIXELS_PER_ITERATION + 1; /* number of brush sprites to draw for the line */ float dx_prime = dx / iterations; /* x-shift per iteration */ float dy_prime = dy / iterations; /* y-shift per iteration */ @@ -81,6 +81,7 @@ main(int argc, char *argv[]) SDL_Event event; SDL_Window *window; /* main window */ SDL_Renderer *renderer; + SDL_Texture *target; int done; /* does user want to quit? */ int w, h; @@ -100,29 +101,38 @@ main(int argc, char *argv[]) initializeTexture(renderer); /* fill canvass initially with all black */ + target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, h); + SDL_SetRenderTarget(renderer, target); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); + SDL_SetRenderTarget(renderer, NULL); done = 0; - while (!done && SDL_WaitEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - done = 1; - break; - case SDL_MOUSEMOTION: - state = SDL_GetMouseState(&x, &y); /* get its location */ - SDL_GetRelativeMouseState(&dx, &dy); /* find how much the mouse moved */ - if (state & SDL_BUTTON_LMASK) { /* is the mouse (touch) down? */ - drawLine(renderer, x - dx, y - dy, dx, dy); /* draw line segment */ - SDL_RenderPresent(renderer); + while (!done) { + while (SDL_PollEvent(&event) == 1) { + switch (event.type) { + case SDL_QUIT: + done = 1; + break; + case SDL_MOUSEMOTION: + state = SDL_GetMouseState(&x, &y); /* get its location */ + SDL_GetRelativeMouseState(&dx, &dy); /* find how much the mouse moved */ + if (state & SDL_BUTTON_LMASK) { /* is the mouse (touch) down? */ + SDL_SetRenderTarget(renderer, target); + drawLine(renderer, x - dx, y - dy, dx, dy); /* draw line segment */ + SDL_SetRenderTarget(renderer, NULL); + } + break; } - break; } + + SDL_RenderCopy(renderer, target, NULL, NULL); + SDL_RenderPresent(renderer); } /* cleanup */ SDL_DestroyTexture(brush); + SDL_DestroyTexture(target); SDL_Quit(); return 0; diff --git a/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/Default-568h@2x.png b/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/Default-568h@2x.png deleted file mode 100644 index eaea96e9e0acc43f7db73c6cbcb8b6165dc6a0be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83791 zcmeFYRa9H;w>3^_ixt=4P-td$0YhwdR~_KGAP9l?d=?@Gvki2vn36bTBY5KVo1! zamB#`KJky=0NychU6l<7*ZO_z>GuMdLO05*9T+p&<1`I}-*56NZX{ z+*{xI-Nm_N6Lj|G#lf8WvcqeNH{o#@D#UA?IyZ_xr(%tyOSjxUO9`zWesNdlI8plk8@mo`Pj-1K+8GRz6Y zQO}>TA&#>y?poVt1baaWz-v9ne1|v+c(G%|{QC5dYsi_}^Xjzq{;zcEtbB0`Z^Nx&IXcsEp+>_QN&ytx#h8+TVX$2h`y* zteYR-zwT+OwK-Jfajtc!fI(_O*bBUm&!0aJV8tY5i}03xlAC_k-;ltH8!hlL9AZ41 zOUw?BvWE7?zgAFC6uJ*p!H*U=?MnBS{XP-@gF>29oC;YNMHU8`1H(#*+5c;)X6f5K zsE2mepTCiw*UTzOW*9Sd)Lg#4WpR+AM}O+xE%E*LH*(>B{oFIcy8~hTIG}@tsO+~k zIi}WP3H^q_{``4W(WhJi*65D(&#VH%{*Ta9nU`*z_m!9@WUr;z=$|eykdSL*kdu(i zZ9Mw(U6xsew3EFM)pz&L96^5#&;0))k*L)uPUjfR1cXh$jkLdcXYCo~%(SF%Gf7X$&}s&rQsK~-6KZDMH`2-feQJOF z@42f}W+1PcXeM)-o8kOlw@v@-;$og-@pzUAYeLNw5FeV|M&$XAe#4P;f#~>@w6LiCAC8dO|{pgL1#$t|EG19tt?Az2|($CCd zdegZ1IF`8wH%?9>(aGzu<6IT|4V^@X#;6@I$nr;O?3b9QKs-^6lMdFZS9DiSsYbQ8 zIptzunW`3~P!%zTdMB=t_|)*y8AX!BMA8V7Qq8mx|75+QNOa>{wbz3MQsIHA-h6A< zikU-P5K7T`@@m49WNX;yWP?lLx5o{AjS^4b_n8LG$bzxI4UK(W}d%hbX1_I z6rww0=Lt0>4aBlugQB&8N1PhA|`HB!gZ(jBSf5uuG&Zfrg&4OWZ zmUFXZah6B}%58=(1_tM&V{&R|FPb+@6ls+gi!UlNFCK@X>^NNy@D)xCmYv?X)T*pK znen17Pl*(gSF!N5G>`QV`#Xu0se`yZgwn8~`{rbG?im)_DKIwP$E!YOb(>GT>mBE` z<@e^1&vk7{>USRppfh{!5i2?FpKeOgWdg4A;nzxw4099>5aVn>cG2I z`NU<1#d9l=)#z077>jqYwUZi)CTJ>VV#16@4ducdik!~BwGx4p9M9wmT z+5BdvDg(dKDdLrk+Rp^Gw2?QQl<73(RU!UKbKAItyO~!0?ob_Ott8MIE3=A)dJ>j8 zR$iyuZga4@Gk5t>eEThZY%#5Z`DZVpQSdRP|@nQ{Nn= zT9fZ4oMuq-5}iUljv%vd>ccD6Hm;`p;CcvBk7uj7a~TnQgIAvIA8FGZEBy_ftCDNP zdpMa-bTq{#qXc?=DffHcCR?wl?^Gc!W57+2x)yhCZ;dr?=3=g--oWTRTa2aDOhE!d zz_j=c7exhqB$ry|?HJIAm={3;Zg;MAhQyTE0^)z%(Zh6WH#zOZxsy)f+0YWY6SO*W7YD zEzWDw3hcCt^{o_v2=$lp0`Po;eggSubmJF1Kh>T<8jSbx?gCns>3yIdsd(y>oUFZX z`qBNq4Ah7MgMQSk=!Qj(d!zF7Nk6)3HdVw|g}*zR`U~yukEg9lRJhcZ4K=P|wjY9H zOBFp>5pwcP{f-XbdUsEsl-=NH2cDeZeM<1J9$7a?!N>d9oNb8&zSL>xIlg=y4Ud0t zLS4)N8s|j(*Ok;piAK-{){q{2q*UU7yF@T}ORhv6#w1FY!!7il%TCqc(czMB^1-S9 z>Gh-H9j{T-roq^9_~vlWQ;9_x$`!Ea+;FRql(R7j~qQ~uh6ty~05sL~e$m8vycW168a{a^*uaT|{ zWwx9@krv?@`=jk(`Ph-m#skdLB3*T}f6d24u-k)KV3CtCfZGBcy5Dv?N2qIaQT%*2 zWF-x(d}Km}@HjMad9yq?f?>BT5gu61O*rVwP!I@X!cjb@Qx6NKM0ojRk%`F`WzT%u zB?u3MUESRPNj5bik!oG=0z+FJ)Mt=7Vo=b%;{r#YHmY6X-VQ`Z8kYL_9xVvQ?m%)R zWJVNTXvyS*@-P~x!r%h4sXcntBSS7(s~h#BZr5w?MC-m9EM#etIr~*ehM6@4*?r9> zbb+^a|McNKsgKSx;XZ7{hPkfIGBdP2$ZTF{p}^iok>o|pEyG1?Y|>OGd&T+}|~o#iN=|QcA1Tgf#}$5oI*uAst-d1YvvPmU|MT>B>*n7$Ytz6x;c|G>@8kKGao&;6~l0o?HTN)9Py51kKv%0 z__~S>qkj$`dQ+?yRq>O&swK!PyI@3A+rk%h%*k~|NHiSh;T~*){q~WoPb}&)Etg}9 z_cbP(m)G_BmZFTOl$1?ne%~r><}BzX;-4LxF1x-u0W70zhBG~2{f3r`?(x48)w*PK zIhh-Wq0}}-FTwnhD$HqW^`bG)p^yp)?J|+8Q>+Q^#p-I0la}>1N1)QxhJ4{#Tqt{t zeZ>2}Bcd+_KD((i!#BojUz}@cRD~=*xw+5~l$0J_zXY8KB?I^WiHT-1Ua?!RNpPXA z#5~};baHNFUPfYZhM>(&=7g7f`JlCsI`o}DZ$;f)?&97mHnYJ>BQFfKWEI>N=3YVNbAZ{sX%MyL@!ADXf-nQVi znrg<>X^rK^z1M>Fi;1hpwbr~QjU5N3(j&vCU@a-nEG5l_zS~{l)I%^#_gzgWCeheX7 z;G36y1J#Hd`%yOLJ+Ft#p`0Y`w}*^Pplm z#6@Mr7B$?NZ}GR8dx%X=M3klwQniI6G;apN;jy!Mvd*kVGdy4s_0Tw6OU|s@oI!dciz^nXlXHTyGSMw;`+-p|beh4u-N|f_JtUVM z16DIq`V!H4Oxf(=p z7&s!r|44H}+k==QX2ne_E23xp1@U1${MN>nr!3n^b)aD={AHhR3%!U!#9C-=>M2{G<%X&$Lr zu2zH$K(HtL%O%F|Js3e?Z)oe*30)$>>(2*XsKKIBMN8Z3{JGWMW10)b4D>zAiInFp z|CF5WU;dbhcik#Y0WgSh7rni=(%;rAF`>c79~Eb!zE@GlA322cLw|}HpWc~W9#3C9 z7Tw`lo8{Nz(cz)ETIj$PEbIDN43HH6OSx{FtUt|^B)zz7n{4Ts?Dqe*yy`U8h*HJm zYAUKrw5{n{N6^lYkK4t*M-UYbkt;tS>)VbsO#1Cx@VhIr*Nxj3HArJT!l0e>=j^d*d(EqQs&QH2 zfxKH`e0}H@eJMGVjGNd*@+kVHx z{Swobq~x0?Xm>|qmqL^R@q3y^%A38M5Y;2jrTDGWDYtWM53<- zT!IlpF4+ZR4yeZMzppedV1Wz`t$j(gCu4=8{LM;Dy2`|_OCTb%4z;*xQ6yVZxMN|I6>7{Om@N(swz{397< zPe@&|TNRp-FHrV_K2#g+&HN4KKe1fJf;Md`3mC36MF~=)A@4L{{7~ z)Eh3UbU1sW*Lw+|^*>WnSQLHosJt~WrRT0%STYh9B~GZ3@|Nlc#^v_b&7*(8ddS6$ ztc6!KOa zj+W_ktWeP1!`tt)q;4SPRY8jm#_357mL3P6y5rC34M0dd*#0!AJNf z*fs!%?b`O?wL}uSw4BqB=_b?3xJTJ88JOkIp^t9P1+=Fr-GM8VBmR8b#g~I-Yrm47 zp_=h-DcE|v94B{QCsR+~I`Z~$gAedH=Jt>0w@+#$g8(w(cRds@q{k5oDX0wvmCO>S zlcRCM7e1pV|f6dZHa{BZ5q z)XK1@31`BepsEF{DiPczOg!81ym1XoTxggZn?b_~SlwQU;c*!Gndsm3 zdB*j>#|?$am+Cx+T1<=X)HF*&1%NlYnT{$5XAkD`^*E}e)J41WOG8^j??Nc`e#p82 zC)vbjxp|{r52sH4wL#TvJ-&6xczO%xs*-GZptxm-Axzc|Le7mxO--0!D3YHKB+{$v zx>s*~O3v@%9}d+3_;{ora!dde+Rp+n7l)VXT-~-#uh%`Oc`(TuW0_qoN?s+g0^&pc zLD z3^dluRk-ZP5zC2{R2qK_^*JT}E2w~#P)Nhb_Q(pIXvA16BXvH_KaD*9^0ndwkbFa( z3VDw`nkLQC`xlEK)8lZr2 zxn#4Xon2BbUvc)u4=0cKe%6LU=DJm0ffNl=&#>ung}d5eo8k=~p)qBoSKomRWjQ4{ zW+nlSSu=;^QZIx+`U)4fNnhh8TUryUf2sWFExR)B5XP_SN*CbTtZA_1K=uN+4s!IT z0}x21CnzwMBN;!pc=(0FrEW;m%6K?$2TD&Bnr*Fw800`lCuq|bs3xqWi-k_eR6OY&VH1V zd~(YfWjODY$hz%d@vMTo3lK4@UHHt9lzkWRx*S_`!S#FB&l_vwc<#HFAD{(O8gvwX zu?rJ)eJ@dsx0hn==!1}B?gJB5MkaufTDqo&@638ONq6#(KO$>XJ8tCmsMh_0cU6OR znCb(q!FDM>sIJqtwJd(x>*`w7smr!GE1L*oTB3t#8V>-l65i?_tT@)Abd%4%HswQ! z`zeY~TDT|?;GL5_#j&?*SNdC?0Ri7e9VOQx7y6j&l*ey}UgKSH1GL@YXB4{8e)jIi zGxx&-r@E#~ZDo*x=XKC+@Nb*yaM^UcYHXyY^arXpu2n0yfu zJ*A5VR0!EiR5?H|=^CL*a2%0x_tw$Ug?r#=V&Fd+CP{k2fr&uqE9nu+u z?{0olQeYlzV}KM%ic}B}%m3F4F#2J$XGSZ2a`T}6=vdlh+rf}B+$0rH-(@nf+JcfT zht=bRWc2d%I0Pg`~@hoX+geleW!JJm17 zh)cP2!X9I!@pZ2BJ8S(x8>#ENj~`kO0VRYGapHTpC50hMN!`~I|4NjWr?)sos~j@< z!`oGav{k`3i1Q3%rEC>&Dwc;`C?{9+lj&4vqZ-^14p7L7MMP3nz$_ zq13@CJF~))GUY8EVS&@A^*j}ao)W_IRuBeR^5JxbT9$Z73KR5P!G&+Aii7f4>h?E@ zCWCAz3)?>Gp2dT8AX`>?)3#{&LSuvob9%ZS9I}Bmqd(o~Z`(D7xpzyxgwl6EZF4m)0&Y;w&Jdl7wiJ^x;Y`7rpHdaaeWvf{?4Gef4X% z%xo3>CC0CgrgYV5TC)xUpq(9BFR7UhHz%OhYRS4M*wiBm3N&t+y6c?xg?53F4*AJ2 zZQ5@TL#qp8LDseZk_Rwpa>@xf<5>cGxE)TnHSe2l7oG`dlM4w6^hTp1{dV(Ez&!=6 zpHKre2`CGFb(MR24BiLVLSN$znrxl#yJ?pff2Qx^y1#}ARG|U_FM8WU={shnXZu$9*V!M6*%n&4VPwIlC+Nelj}P0+w-`cO z`gN_OzQtpmRopRG3q_vyUrA)JmF{km7sYZrDr&YK2VX>`upNJB=}n;Oc7#296i zN&B)In_@O*!^X=p(Ke*Crr_$2jGqIq*5!_=dG1?mG0i{`Chtu)0BIbU3gya~iB05se9yuy-85QTAd;#l z*5GX!?l|NqjHIXQ>+sqgTeh8R61jwZV^zVy4qex@MNa4#I3A)F`7|lju|B zDl4Z}!u7S>Je^Yk{VLiV3F`Ciw-Kz7-1gRk4=S&0wWt2IXZJbsuO9GcDBB_aylN&f zs+~EK2v-);{}k6j4}$p^(~pE;QoyQjfIYBcjN`1C4OlR0;#W8!4q4=AoY(n zOX!6n#_nm5sqYy%*N$=XFV{Jcd=~2@r#0a|eDf$0cCuG4)6sD!5!21i8)Z8y;-jwXqh54Uh!;D4+mka)hjVoz zm#Y{@hvwqahSuKxpZc^I*l^@|-@jj*luQE$nTHm~4ozl40Le&>_)|(mY+?z8aDJfX z_r4}T{MIgA@gJqvA~T}wR{3-g*&RJc5=;;z%cMdI%oK?}$;H`9BxRj1SDkyd??Ta) zHFX2ack70PBM5iTU|CqUXcRBiiPLmujbv*xBgTkb{M}EiH~ZHC_11|a{y>K@54yr` z&!d%SmGN#>nLeqArMwt{p&|t`M|gw35I=cjPMpLlP`0yXT|Fr&!w3KHJz>ao?GNil z3uVOa6~^q|x!=Z~kDV|Q46Al@XofzTal4wPVnhXKg=COj(0`XT2&}ATG)w~FZ+Aig zO|b}Bw75s2sC|tkl67@=80kgccX`k_P-OnwiymO}CZh6y5WXR}E|}4Aq+SF~?k0Ax zJ{Zqyq=qqk-9Y5r3p&zz1)q%5-kzt3HP%!p(DigNUE9;u`(Q6<9lHuao$uZyeb-IE zKG!(vIta-G3hWa`-~8K4m!;O=-)9Bynu6fnASZ58%Z9cV#rhdbNOecb&QMoI%3kR) zbPj2}X_)#N)C&-=PTBi4pWBt@52)GI#{g1E0uA*8c0W!vMr;Vl@6ktK2UepESO3%cz8XAqiw6wxB z1b79{CxnE)a8mfUt)`W~@AlwfkPz0Gp71=(A^7N)1;~9Xog0p)*Y{;VAD-n${j8*U zSp0B@3lF(`RLItg^UV%yVQEZRDR3GD_ik1yM&=)2hb1Hsvkg?l8(0jF9Ht(*(x;hB zcX=&dXzmzp%eNk2cX6QjV}P;NY~><#P3X~rCk=Pnkj}6z$L2}c9koluCsq}ul9#>3 zw{v3c{WI-{IQlN!C*wP|zWXWlhRY>IUhm30sFWVNTpXS5Hx+72X_0c%0!>%5-)$W8e}XD#ZU@g^@bYlGZ+5=B4(4}Cl{%idsV7UI zj|Ian=c@VK%$8Y`E#Cn{R=1>_dT+C__~-t2GCj?rqz$wV7_ay5pXpa7Sbo!ER>42p zG?R-;nLcX2A@_93v|x^fgdSkOjWuMD6&!guJGhsgvdB^8=$o3NZ8=<^a6+!Gvk;xE zQ?-8_u(}#SK2vb()Fq<(6S`dd$hCTG{WfK%CLoB^(iOBfm7V%D+ZlcnKYWrFax2ny zz1{`Y9||LB@`QJRMQd)P=d&4F+ho&oo&f;_i=++Nu&@8CUjsO;EK_q^A}q3I2W_MZh@nMIry?|pIgC6Np|PF&9@I{W=q43py|PEj*^;> zKK!YNhr_w3(pPWIfdlU3*?S*nIG42S%F4a{zx`J)e*jQJi^WnKeIbcM`c#HS$Zj_$ zshOU-QfUDRJHu_agY&@PtJ~tYgHP{oxA~G;Nz4+5toT8CVt0XoUIm_}W2@LQcxQD7-ooKNx+Bc>&OoMLd*y2Y8WhF;^ONV_6 z`sX~T4Bi{}1tU98q+}j?`2N^k_@Tz}s1d7U`9ix56oaO?AAvm9%x=z-=`I-yW}+S^ z8TuJbvwYc^A9#@Y;d!zfwwK{g)8!)Mg?*g_FiZaiR$cy_b=raQ`KX!kh1J0ackyI4$;d3Mg#=j8@V zLxV8a`qsaaklpP4>$Uk&?|~6BV_{Ia9xzv31rw$|jpf?OYHj$PaiR|n*rrh{rUk4B zTUQ-9Ac}=HTPr~ZH17vgW7_iO`km6OtaLOa6fF+o8q&+xC_*+%Hh)fEbW>N5A)rRk zJJ}?#Xp#ccJJB5tiPn2;Q_c)%Uo9=y?H1tnoZ^!i4C^D*=A?9$j(7j5+&X3h@ro02 zfv>IhF|ZiB0t)i+jR(IWM^(r-=={unB}PNrJM?Z(F>5sS-DY>MnK5O^`3T=}cDb~i z=ng?$-uzgYOSNX}6f?|Xx5I)!S?QLu0JBy#y0Rl`wW!A}t7a>x&r=`t`qW>h)H&X! zxa-=6tWPuYWT@bI&nv@nWPBPA21!J0j5pP-7K&3wr-jQ0K-{8;jtb8BX`x3*J z*JNXcucg|$IOZ7?((n&E!Iv;N(Q&S| zAy{)hhZ#OpIB^s1=`RZr`J$Po6qcaRyMDDa@nLgEOS-dhXy$Uj#dK{$3^9HYcIxQu z=j!@CGUbdQ_-@TH5EUB_Um~Vy57CkJ&M|J)BF7UgEF-LQB_; z={%ztbx!=1N$M-+zK~0;hhdlC3(iKT)S+jw!p7NhSChGm>Y~Y_sW9d!i!xrw;cW)~ z2VXPT9qI-BVJk5PZK>#xW2S;O6b;+2hdk0I*X3Tnij}>_1A5AYafwP1>gyh_aUA7h z4t#pON1*2wtkNjFQZ*xxSCX`qpuXsut`7^*<3%46PS*zLP>=oF5WRX~fN=-#HWa+2 z3toOHU{y_x2N-@#U_f<=&jI%Wh6F(%s0A}b{noAVBB!oOnUgLDn4NZ-9*`M~w&jad zP#9_!fJJfyaaRT*rX`+VcyYQsUtck`fGiKYh%NB}8nU=oQ2V`1ZS;hF-6IUa6$>dS zj({Kw-}V>Csy;33Eta}o5y%PH;2AY(ctxz}8}_?~wuq#D=aE?b*V~D5)0N1OBM591 zL5LK1rwZU%T3T9lP0gh_aqzLo$NIL9QGs6p{$iOzx@ZbFU1k%FV2}ABHcwt;O4_S}*Bw}^)n>jf_EiV{pPwQI!NF%j}=eUa3rP4~o`V_?L zPtMt!c`#_q+^oY=&PwUILX=MO)$7w$#k%iryNGl+s3P)1%t6&tc4L1%Rj^n>0Jq0L zB_5gO6!O=>jXVs`zf4U4-UX6xohw}Y`-l2TC%b09KQHjuoqAbR06AKh+e+N;7Dowv zq0330o+;inr}oUGu@0Y=ag67F6pL-R`P0}IthMEVal8@&peUgURC;{#i(G4hLj5IL z3_!-Ay7_!m!Da^3nXm+Qm91-;E2jt(Q8ixFs^7k=aK+pHqph&M^vt=w-BU24Rj`A$ zh_9lm^65)z&4b;SHWkPGnie@XcbQWDYwWs~Q|6N2b(ocwFXrsLIrLvuWoXShO^J1=}QL+J<&Sl+XP@Z=hfsSGLBy9Hb^-LzT;Q|2jx(i24`;6 z#;r!dcdWsl>o`Qg`>b^k%Ooq`%zExvz_pUW#kDS-R-Tom_2I48tj__?icRZ)UUjYI zyuCtEh{mg*38+5{_y8s6rd9SixAT?=%Lx`3&E0fywn?gV@YAQ5F;49zNn#^YM>|Ma$REwPcPl5UsbA4@Zo_qX6xDziXC6gd6H}ES{O! z<;3FKmL8v;Bl?}|vx{x_4XQ=G+f5zlgL_w={?cDd0S8)Ipr~4{&iA+dMUS#O(4ePZ zV#M2S&WbJ<9xGiUWc^a%vKM%cw8o4_)Ue~mtU4p3zJ460r=L^0lS&-L4-lwS}cC>qK0rM(DdCPyZl*0>LI2hjubSX6`M6r|Y1Hn}=(c zt8F2^U>iC3?*I*}1|p8b9@3z{YL+M~lMI5+yUp7PnQb>SPMoZt+^JE zQpn~2fCQkHnzUBF`e~4>$B{H-6KOmL2;hK-RMdV9j?b1FeYnYopX{n_zrK^3SgM!w z5_M|rz|m?aD8ed5tdBLfV*E%)2-yF^03t^-LU^W_IdxX*$*fcGig$;EErL}5fb>)D z8H~XXlK;*oLr&t`{~Z_>JbUA9ZJryB0!v*Ca%>U}A6_Xj&_PpafH^O2M8On6FK2-k z1BOor`QeXL<^HAAeaa+rV6qKToHT~e4ZReII2(}ws)`=(svqz2-DcWlzDr;z6qPvQ zm-S&`t@cFC#K@%2YnT2)>lwFDL%ZQ5Qabp2T>L)MMS8eRVCwPyD2DPprcLz{%@wvf zKwW>mfH7utRqo0iNXrv{zBHE@-t*&4(Mdcqvi`n9EnBvSVa!1RB(QY5I-n}H%`u_; zfTw6BwB!n(H+lJf_jvif#|JDSJH(e00vHFR)I^i1)sKc4k6*T&eC4D#wvvu_C{SM3 zs%JBqo9*4(upcRHgzLR&tQ)sbqd zNMyHpqO;BcSa?3WhVR?OQPHQAVg;G?7n5}yX?Ul1ADN(A*m6cnjD0o8_kptAZo6_C z&Y{spDeAo&9!gcGpArg26q^qJIQfvbyuc&v!KEGHMYMT^mrDmmWmHxXUOVG|EY*Z- z7PT+-I$5Dl;smxI*Sw_*Or|s^FGRW%D87j)sFA#8=RR*h5{;SgN-k)0gXBSdz#hI1 zg1=&pL`yjNkctb+s&T;cbvSi+sQk9$gifzza&`zGchk%MqvXdpZA?P}(@aO$2m#%N zv*7ujQ>K42;KHqGdS8{NB$L+R1)SZXpEh? zysG9qk-g7s2SE8ZaEF%(07C#vpy5n`-p%DB*Bfqzxv};{)9mLLmnPvWQCy^hv^@EUm$=k~Bb?()GzooXcL_uWfXi_!PSmMuv|Ul2Nj))9!* zfL31D8P){Tb}hsK5j-pZ=8YI@C9|gUxmXMeB#Yw>%_0Xaqgs0eGw`u(3URs;QsN{^ zO&Lo(?b|Jjbi)BoA^3wIRr* zK7w?r7LXR`L<5clBjk7VjREC4_cLS_F19qc7QjhDgLHu*6EM5Bs2*b&u)NO`lbIod14^9hd$ja>qPm^_JErer4iguTO@=JKC7}RgD7icJ8koV! z9_%|uirT;k;9F5!QdU=1~$9olsRh>ea zf>vr+94b0~QwsqU%@ZMAz<72S4EQj^j#Q~P*XF*2UORht&p3x#zkv+F7@$GU+p!@ca z+YRM<(d%4~+Ntg1_;%kMvOdCUz*Je0IV$xf_9>us?PPj!7IgOAKwZR%l)M>y|G4N9 zDO}-y5R^_kG79&v)?m?Gs@CV%`}!DQLwI3|=Z1*YpEu}+wyM|p6J2uxNf4}9IqxOo zG%=&wzf;d{hg@XT3ldt<@mFP>uaE?Mzf!Howl54#kt>(0;!N~+Y8PV~w4BI`tykEH zlOKKzJk7BXBrr=5r1s%|?m(g_P(6X7lj09@%!MU){4j4aY=F##J$=D=gDX~Li`cq| z4roV=^_-ZHT1F)U?|8N0+`EEYhY1&xoWX+K^`s&Z!4<#-PqtDvilKN$C z+w%mQHbvuUUpit|Y$O-yS#dg7Kcy43f5=D-u^0J^!NNk08GA*y7z}S?Toy#x66j%E z$|)BkS&~(D64|)KVf*mhxg+};$p)A-7+y+Wf9DyiBnve#m|GheQj_vtzBiX%X?4(l zk+|p@@9vaY>K_Z3S(Me2rfCck+)Mzp<(4JGe_#!a+_$4?5}f_&79S5*jT6uAUDe+n zh7lv{Dj~6^vcHKw#p~mlc@JH+NTOF9Qb;#m5z5c2@ez>OvrD<{@&ji?maUy1gkhFN zURli>GL}p@EK3pr(Z#V`VbV<#k-DPE9jv%z z7YnAgE$|goI>WGw#HECSPr_|(*lhZ|-+-LPDSF#wJ+h03j4y6QDw-p{EluejN=^>6LgKpcR-6O0_X+V&ay$y z-4S8B6oiOLc8cS!pzRSJMA9iu4HnhU1al;3b$FO#ETJk*PDxcjmD%00;@h+g0P^%V zPE;2q0#FR^Z=KQdH`6)mZ>^eAdGYLhZYGg?#vwJp0g^q>K`^Y6 zJG09}h}?ZH9)xLSup-kW>;2#d_>1>*30(tva-IUSKLDTd9j>!%cQRDRDs~3Su3sP1 z=$Du8;xscfs$(UCn(pqE(me1Ba}hoG|m*>lr^l91>Vy>F2FK4kLb0AwvSlw8mfrqDR?)Jwo)TL>CuwT_ z{flK0eUBmDC5x0o%Ww2H+B7f0=W?D(Cfljbh})Gqg86IIUo0U~khy0==a%b+e6#3x z@w=B;{CkCtG$1Tu;wOSHBWT#-8CI&{!3hVqTQ5E_#jF(Gw{Crs^oY%B_l+xm_*z3G5n1~P;{tB6Yk!Hax_9j3-0v|q`!~Ucv5T?kigghe^uLyV#F3>5_qg{8(WD>5> z2#btAur~L~_C_xLKodJLhhpa8O62qnuW?cpQu=PqI;%>m(-gYs{LcHL{PVgj;dU_2 z{{FTczPcQQ!tQ_5d!~a~@Xf*xaHNG*lsB>7Y_}y``w4z*`DaELe=%wugdvLquJNJz z;Cq~CAgguSV?_BXf5}Nmy1n1ORgS&+s3zDBW8l(0g1n=WCqnhL zYB-(Fzy(eXI{=U&Vh(hb>e*o^>)yeq+!N4?jJQ)5!By0V{=^eg(DAsWn1Mm@L4)lg z)sr`zJ?mRIEGh2GQ)*A;`X{sf+HQ7ZZ&%@g$urB1pU~Lk79UI~9_W`Zj)EQ@E2~+7 zFoGo-Xk%agA$Uv@TR)#V(9xP4ct1g;%RzCi82y3cb?egF@fos4lJ_gI-B-mWHw?RG z)9EQVb5|tPLZ)xaHQc?D*bRfDo&z)1gI(wKn6H=-JoTrC=K+{yLrSh*+cjCTKLWds z81Kc4;@X#K&U{q{kiDq8#&VoootQlLMAe_OK5=9bWn>Y|_50k1aYZ46A(u;9zMDN_ z4Xzt6i>GKJ%3dqH;rR4M(TX1@Im$NTLy~F1f>l0acOqgn)i@R4w)7tMq@ppu>)SHd6NS|(5tarb1P;|%5vdksbR>!2J@%PkrkH*9K zZ&~!c_$Vreq2QVq59Ak(_lapeQZ^`MX0(0iaS`k|yog~lQHTx1NhSBOY+E_+A4MAF zh(dGF*dtXNQ)yR^myH>OhxD0h!vEI`07{Pt)se~jVi3_0-F1^rN4t8xNB#ZF&+?!t z3tPAk@8ZhNhim+ZG8A?q+HSPc&g*&Q@kLfR$5Q>p7DOlwElBh($iMpY?a2Fuped)tr#dn)^~A%3oSTGci+nhSe(HM2)|_YIJf}kce(k zUclD+2|rJQj(~t@=cRJSRRP8Il(Gg+s67oJMh2gszgTJv3`<-ky?}!|ix?Z>N{B48 zA3ColzF{T)h#ki!DVS{9E-Dj}i@5L2b>V;R-7)4RtY@TtppxIvf zB&^YO7Ral$*l`x55HDjmTK7{7dBF9QyJ{|-xr@)!6h@drP0cyxS!cXFJq&pA0 z{FW(qYX6U$^mmPH5n$`45xsy5aANZ#YsW-$wh6dFu8`8k!bzVSLqN z{>N(u9)_zC`}a`+v?+vWKf~&v>{sJjv0_b{2qLikS%1v~)`T3{jbEBPYGA`CdpNC%t^%d%wC^=tTITVq#U*D^fs zPa%7rP){Ej2uQLzy>)xvk92Sj?>=tSN}$U}57+M^u}mooWuJe<1D=rC!McHkgzOtJ zy7yYonR6KVMWp-AjD@6b)@VTyqxaHebh0h*t{b1~01GH8^5R7;NuhJ@Hceq!KCOQe zC*@IOVYCLTs}f1)uDTi#?xcw4QynaW)Pbed(;|Ovi|gq*(k<1~ z%3^f!^W(>Pvwfd)5HjJgew@wRrG$eNq~=xHHk&!oeoh+B@be1?6<*>qZEl5jqf#N+ zc4bTJ&>ekeejy>HzB6`xPWAnzoU_yCj_ur0Nj&a>gc=nwJ8^fyO#FJePaI?=VxzlMI}7lR@WBj*br|>ySps>F~WQ=suI0 zcJ%tUvb0zxBj(-?zBpHh35W`Iw+(0$?k@JUEuy}th3CY{)NLo3e*sZoGS{Sg;$aof z7%ZY5CeE+Ddk46LL(3eMse$lh-Doka8i$;`x;>v5!pIMkbF(#1bZ8xG7V073ZBb%T zo~LLR+DyySIwxl4C&+gH`495UPS`jRVq#K46-0U4^FdavdTLcjORB$nmiXpEeZ|{k zdfG87;0Dhev=$&E=Av$%{xUw~+Kqb%rutLCQ?Jb{DD^1sIm<@S04H@#g~~Oq8QofV zzdOGs;zqK^F zGvyweyFs9c#_jR?2BVGXTh1b)z2~;nkLRp1{4r-CR&Vek24840EFl&;1$BODB;iXQ z@_sJc-cniVh7$dxJX1{0oH+R`s3RwapWT{_0x~RiF*%=3x*`(T*g~R4axTe&P@m{NK{k}B@uneL6ekOtl~re==M}Jotdu3`klzwK zTuTVX0f0H8naMTd!XmH2p8vM&=Z{re?7Q(0^n;{N{(+Np}-4 zPsBQ!G`4n!^?4Jmd+f%(B-V(>atQq1Ij0+Wwaw+yYrmp?xxSCoCdZud;t!ZFNYk4E zdYF7SiOf&dt`xkYc>48Kp+2zNDO2Rdo{iIY(t@o2L(^4;qb@{bS zBn_{-v<;f;c19z@MEvuG{OP8s#M(J1ZXe#s0n&B1_ z7bM{&bR(T=vy68r#lwl{=gE0S0O|dzvQcGy;!+bp$ycAF6`2UtOQv~!)|i#*jCtNm zN`@1US=XHe=mo&xCb+Qt`s;c>FDD5ntO%v$64>Pw;_DJK`K+fNhv4IE;Po8Zj31`` zPK3GtY>%(JZE5W+YGH#s1RPhv^<1*WwlqAcE4!^(SWj>8H+%<1`j0!bqJGGxsnKPH z&DnI9@>KlCV~09aa+7+;Wp;AfG4czO-VGCKY8vZXhrCyZBvNn%)_Q5kPWeSO^B;J( zSrL-27$W3eFo+4~B#%<(Z*0j`g;WzqqN^57lgce+8riueK(j?^bWDt`!=`HH3(jSv zgTA5l+WkWwDDzNuRJ3x^+5)ENDrKV?Q&h1@*LON=xkF;qV^`w$-MINZ}% z#TS?`Hd4P7d7XL?WgKDN0-m^|c5bXgG8v`uD8B*Od|eu%$Ll#kp@E|?Meq=nm^V@V z*{$Wm_A&ztBqliRuI=3!qxSG9S2JFLrb5m{A8qAuF{VS-D|+?OAPFwD6m!bGDg}ag^n>tfA%gc1hR#HH*sDEB$S(X!^9&kUf}yb z^~|DzD2CHbQss;DILd5tY}yldvgcgBaUa1dE_$!o?Bo?Jv&NX;ET}L{<+c8TC6Ee& z;3&U-it^=MU46$v2S;LJ{#)-;6Oxpr{YGSCN6h-n(cxXUvZeI3*KApZT0;(7e_@{~ z1-s_HOMR%e;itTA~ZuyJDZhiuT?ArcX}M$Vr&e%EA|-rZPbCJ1XQcj~AlM zhytMn&*~7| zpfL%$Oi?5nCPd>)A|q|Nun~rGyxyR?qVMjEV`Lby+Q~5ASoYeCWfbef_0`v9*L}3q z0x-Z18JK)I+n~KZU)?o`j8Vy9=Zn+U#un#coMdNr#5hHjH1$xjDYitITf4Ie&gN8R z)hBY-6+rRp(Wn8_0Q0G|Ka6BHF$@~++)E4DT>ASZzYXuho5KFFBqW8Ix%b>1HJUCv z^*Vp!^GP29R_^8Fp%44QPj3=cXX;wMy*hKlB}K2ms`-~-5xJsuP*>_L6U$MCo3>zU@}N{qsj@Nz2>xtjG}hR@bV zLvP2;>y)%7sKqx>7f+j;^xd?*Mw)1Smne>__u-5=*op5Fkj&Kz`rS+aJp4mzVvy|L zwtQN3@d=O`&D`K0ZEoM(pBx%t8#irI`y35z81fTCNl8!dIxu^veUN(B&n$J(R982QI!Lf2i!t-iA)=NoJ zY89qeXXptL0#{>Z1Dgoo?2!y}%kDcBY?b^1VI4B`WWCfU0j`|Oa!<8oAtiO&ytO7= z)V=`6zOTmkV}yX%nN66jEM{phx zUKM1ZNyb|p(@XIossQ!p+a$u3)<5UltdpkBC!R4F&m~rj+M{)eDnEzHmHi%1t;e2s z-XIX+AY(Am_hKGx9u(6)tQNi^DOI5)8o<)S56NV})dL0f`Q|a}EQ7M8ODSe?bf)c$ zn4U!dqIuTD7?;_yB%aV$^t`RBt9MV_ro7x5_pH6vD^Sj0_ zE$KZc;xg)!ucpqA?T`L_r4aCnTzQx(yg4YOXs@smCB_X_6og@eVy<_=mEq|Mi;B81 zuM2(`m7OGR>0weS5|6OJ#g6+{B;hJau4!`ZY6xsfk`*AcLvc-on5bslDS7(3VAj=Y zPLM@R_`Apghgl7OSWR9$+RQng>aTR8-zL?OFw_2J(o2UW`KS1u;&ZA!NTznN{o#nG zDBQgu#-b{Xdn$oc8WJ!cgWe(Zc;Xcn-!*+98~jBtQvWuocE7T@al~SKW%K#5=lXWr z=jQdpO}+zHs&zU6axp%P@$?aUW#zNjp%{%HQ_$Y6!?q6K&pqSq->vZAv{OOU%iqUB zD>ozSw>>^x@(Gg{=lY5vLXnDN;3`gU(SORpXvoc@;dd0@|obFkzq z>m@zbT4QUwH+VW&7(Ka&(f#*tD$O*tJ<=;gjOjGM7Z_JNPQ>W^nF`g+O}@8V&-ExY zh>TR+Zy*qoBg2S#l3t$b`0!8B$reX3OC*^6G2BtA)=qNIO_=SlTAbDQ(wun>=``&| z`?F(<+RKq!CHdHl(fFE~@yELRuU|7Mx}|u*mB(3{y0xRJ!O`XTnUt}k{0|xB-ihbO zIz~pNl8m&8S=97_+IX`Su-XKsepO>TRAP8K4g&|xH!P|6(?cq;aPwNJXW z1xon>j|B?SB(ASTyT<=13?yF^W(CrD?mmtTTce7GuV@w^CTFj#xeJlc&_X(z^6~;h zy_ctM@gO~K=nGiBo9Bj=Ra+$pX*vX@USupChe-GVm1C*uigrcw%idsZ}>b2-z-y5` zmkpMtxIG=}ddKX}y=c9=eeHVEYT&5FhFT(9Z0e$Axp24Xi1=#Ps#?LkH%S*2Nvs=z zcL9vNu^3gZr`{{8J;(X=sB~h%e-?FVTwAl!--@=EtwF1|1JUxY(S#$KI@WTw??rvL zZx>TE3pU-+6V8a?9}FQsf}wobXbLilecP^Q|`$%ECo4}k_tPnBy`)LM?0rYtD3>wg;y^q@j+JD;VRe3Fki8((Y_t@fISOMeuA681#Z5%Y z3?qIl5t^tw_yqAQ3kzJWnP-){I$k^W+~oAUJpaPZ4Gq(1sDkL3_m;=HsHy3!YYMw& z3g3a6W3~6$a`7#04$%#KMs&pW%ix7c%B9(c^D52Q!w&?}Rv23vhcB~_En|kpdQGG~ zRd!Nqhn1IikTAu<;uY~nE9B02-y9(&rp<_a;Y(hQUVW?hP&{X(Vlmw6?d)}!&7coI ztsvRCxL1#^D)Z2}a?dA<=lMLBl%lRSpEs32t<8>sICJj0X0olWp}yYsuvC7Uuj__B zilyLdO?1=xrDj>LNb5nQ)<-5^6Gh>24-V76e2nduW#U&to!QV)_{-+r7lvt_wA#mE zt*%$Z9F{2ZlkD=e@91VT>CpZ+jY9r3_FuuHiZxr;A$eEj;q#fsn#El zSvyC?-(SyN-nZ|kwvLzQ<|tJIA=bUm_Ta;k?mgMPv%I(=&B7uSWAwbi@sZ$pYqV|f zKU9}-gWU1$9_F+Y`6RoVcKQ0PH^EY0EVWoLIx5*hbm&qGU6**?s~r@W{Vvl6i+yy! zfntQ7EN7_9&T@~GGGz(hz56fH$mq+53jl0Y4Uc^W!w3_ z?vM3509)+?&IKEZS~T_+xe&XtU~SMhLe=K%`Jwyz=Jj*;v90ZjVGf?!z;+RLYGAgZ zW!_olqD=8Jmjxe|ZcTs_oL}BDCwgb=Sgx!gjjPWu>ylJ)l4B}qRMB8`uSn5lm|;=Z zp8F#!E+e)bxn8m-n~COz)f=5;{RrlOPt*6t-|LH{#eYCLd=tzArrguwpk-`XDepc7 ztnAg-ml1|R5P_|1JdWde%IC^yBvW80%X^>L+xZDv3!M<4cFK?}8Gb435z&7N^WNrZ zZSSW=*{P?1GTBE<^j?BjWMpr7vn(#e^pAc@bc_`DJ^wY5PRX=c?Y!4y^`#$VlE9+a zu{A3*;*&Gm$XFp@Nlit^%$ppwc=m1%Q^sJ7s2%KcCTE|;;qt$knsaK4TmCvVoC=TH z(Y?sm%bzxcqWK>j2sx`<1`{>d*4Es(7?R*8l z=i;C7a%JP_wtQ=0*eQi~WI^M#P(n4a%Shog+s+Pa{nE`M?75) zbz1Yd&tD}Ek8iVJrDwNg@AHXm(#SAP4Mr_|p-_`9C8dVA=heTuWOZ%7Czpoddd-&Dl#tN-P?q`E=e6{uoiAIzjkF zQ;gT86jfoHW1n9?q!N_s-qF2?ylcPv#w;W_!6X&m;AcogmK^+NM*-}(Mbl}@`|^O} zg31^YSv&#TJ6OBoZYpdT|5(O(D%#0>cp8^nNc}Olr%?Ky`!v?OLu6CSozlA^Hew&1 zFOWkHGYOC#=bo)68=ViM&j*wsi*4LzphC=}LXP&0kMx3TkAd^;ynO5F#TPq4O6{4P z?w_c^%n|^hEZe`jZCadD5M)YtB6?S0l>`e$C!T=Uo?#+<3HEUC2?hSQ=1N56yz3rR zM~=>?#Zw`a>OB4yFxSKOAsV^yKMIrva(|9sgnmZH`0CuWv1iXcquF3>mb<)yoa7ICNCTi8-X^5TgKMs{ppXiu)3 zUoxzxnNyo4NaS#$Z{22_;oI}dRYmXAD>AD|CdrG<{6;4i+p#1>B($`?+woTYI6;@A zP|Zi-@aF4PWWxQ3yYmm!AK3o-LQ>d)uB~5M<~lg!&v;+YMal*VBp66ANQMv<$A55H zL$lFt?rC_bYF5i1HxvnLE}YQ|jR^^fy3|PKM*hqS%-%C_p(=ufrL+=6P^`O~ z0^&KL&k;#@TH1W)6VvS#C!6icX~4nU`%H0GK$Ps)AipVjA1u?|)I&e@mSD~;0vc{y z619Enh4ZW|!$2roY?v;uFm7_`fXoL9-MdGnxy(e^3FJq%1(BrXtHK=F^a80Wod}E{xQ+vuzaS~^KvXuP-P(%~lJ^v&9WF=C-Ri31e)Z8n|tfhhh( zpFPvX!_vNOvgv&c^WjfajWfISX0~z-m{j~~A*wRnd+t%jCFHulzV2=7D~FJ{AkZj4 z=`lWKEn)& znvP1H)7TlH{@-H0nS1O0;<2!G4Z#^b&VxmH;nTY_=9;6To0@uO``< zUY&0o^ht>SWW4;K%*4T=Wek?BxHyii$G-t`qpY@T1Nc1FqxMdFm=;s+xWr@c-!cTw z72Lrnp{WH9M;RsQf==EzPzYyLjRe$B|5>2;qpK>#6D}%Y9#6OkR8uREb+vp z-N_-3-We*f)A^S4yl0a!jQ9$>vy8x(GWaja;U@!jTHiYuw{S~KfQ7Igrd8BW-*Yv2_e?Koq$nBoIx{V-aV zkv=uFPmh7)aZLoz*2CD3w9aI=Yl02!H%mZzH7Y{bH{8YyHKt?hgFUz-LyTIL1p}B{ zkV+HY(wGuD{VU#H;B$B_kC&|+mKzIIbh%p!NH@06=N3??60i;aW8`Ni_#@ib6i5l) zyxAXm%Q9}swd2S~>f|5G7}QSS(`9w{5wM~d(jx-|v^=r!Y@S!Qa$u=lLwIDfD9h4tB zbg>Qv+yQo0?5JZ5V#0@@wOgU{h&PMPf}_iVc&6go^SqkWUmdAPEu-2BYF-(dP}a9n z{;qEhhcegR$u=R$^&Oq!L{lt&-yyj3i`n)_%fYbZzn)l(j&B$@B)VAj3noMctE}@I zzWws0? z51)$No7VFGDw{#&&cFYEEdUsyJ~B&CCm9ss^F$IMi;BOP%vKipG>d9y83DZOlrb5C zVank(<{A5SCJpwF+}pqklrcDyqNx_8G5+3;Qivyavqan_!-(3UduY@6Raepz* zQ-cf4)Zi9Z z=_DAhtX%SbuSQY}tB8n{a>238vKUPq9x4${^^xk`uShsd^f}OtiJ1ve{bQ%hqb@Z9 zjH`y-u|aOOTW?RrTg!!TGO@tmu^dcl`A-k+U*?Bj_e#wQzUu*+5@9Cpj1*mcck4L* zst8bb?Qid_3JSK>%cmguUDsm%RDjp=XBWRpR-|>#q%9T^SDf2?KTn>NerW0NW9c!9 ztI*el*?gEmwV+_PUT2TrH+PeubPY@ysimKl3CXN)BFwMVVk!*v!j;~O@<1rJwT5@~+`}iJIRZhVw5$wQz zEB;a>X~?V~uS|p5PD7*!qu2wLI3(^b>WU!BJ@r&pMLT*x$O7j}&*#_WCv}mAc2l`rLJl&+(EgsRZx8#);!r0l9=k_lmF)R>ou%T<@X!huJ> zm%{>D21<4WI6X~<&dpD1_WFj&(fd%Fnq5Z$zA`|kf7TeWTIj0Cfn-~yBp2Z1JFoZW z?jpcKqkM!33JwP3(|O%K{FJb40vI@$hwUxgGl2@D;AqJ1e#8?RkY_=XS_a$E&^P0Z zUH7FrK?I}E`o?%b8s?@|%re(L+|d|rdv}6Uf%T}=5g${GsMEerG{tP^&5rGthV=Gp zF@ez-k~lfeumc+x6lnm!e~ytfArb&XpzY}ZzKq1MCU0*K*M&GlBNaK?K#6hV_gg%i z{obq0>r3~5?r!=k%4JHPpH_A+chwim2(kNE5bA05h}`x0RaiC{@$IV@Sjk5V*Bk3I zW42#Z>z@^vk<=RLCG!D3lLT3E(b}3QE;qDnA3_K7d7PSvWw=Q2!4$hB80qXazU=YJ7NmfiGazCzA^52pU=;#$ z_6~C?UlI?MACV~ra3BcjxKAb`m(daiy$%UJJHFrh_g4rXwW^sloMH-^WALBOhkwj7 z1xHk3Vf*g&nUsaDv}See@i#gmP3!+q;AMWw7v>e10k*tF=S$#nT_&f06fW(|HJF7R1MYPE4(r@A*2`;Ab!=758r_$`fQFe#h;2rUA&Dm)?;f$o zjUXI~scmNyUNVvDz3?aG2;h}A+KmJ&)sv6xjXDidScfou#}9KG+5nTyy=3uiwvw!c zUX$(1p|Ast^yRQKu;h_UX?&jx`cK&vBU5e9i%rL>SLHAWPL@A=b4lJ$kN$m~Z|+Tg z-_P1^0#6ZB+}X|};k@N+|HU8MHiTmPv!jFE1}I3uK3WSl@r{Cb*w%zK2fvWKVQ{rB$#V(D|`-*$C<%*lITyD)xM{AJ} z4oLx`HM-p~mG(ESw9ks3An*uT&waAZOup^#?_bT*@r{2qnp&;SX`UltN8?Q1$WW$0 zTr&RptkViu2fH{^PHL9g!z*gWB-sT_dtoj=L#9>q0OU#bcU&2l<{7f8HelOqJ?7-l zlB5EFnuC>j>fnq`MWf0>BAj`u$jn8igq-M8&hv^Xf+F;CiDUq>DkZ1fIOdcA*1eGm zRDef*Q;^Xb1?o6HaD;E`Gke`j{h*g>8j_tHkwuAP(R|V53z3&S+74jOLzP!yVXrIUA zF2_%rDaecnEY?Q#&@K)PjgJsUzOsm8DSP>)jx(X9;>uyZ&UV=K2BQ?_VfK<;!+Sv~ zqTnGmRv^BjMFImrN*Mi|)@Yl>E5>|~*6c}5sSEW8Tz(}@?sI*Wr{Gl=&w+6BF6Yge z<(0stzRub`yf+ap5_Q?Ogf0qv8R4osNcZ~3g9ymK;B13bWYB$6kPC>X@HC9Y(TqHm z`scX2Mg6=y7-l(nNBjiw1U#SZ0AdJKSo~jF#ziNqJs>j$lu%}p;pu`}5BX3EtIrZ= zy5^iV{N*pjC*SMvUSq1-EJi~-D6ywKN7kOchcIn8^woa`TWIek@KSV+_48lVHZvEK zK$#OLvX|xyno0oJv}1FyAovHdFh-GO3s6jpjhv%r=C68dee2~)rlO6Cy0|Tb^Ei}^ zJ!vN3<29#$(+r@~y>Im*k{E@ozV^B%KmcOx9Z76%J`K&ozMnmpp7VACvsnJ79SDut zQsQGA{rs5GR^54@#gs_0FBE0K|8g^ghjn(-S?IPsfgf#k-m{PdfNgm`qI<)qm5J!xN^M!P-AE)WOkMkl$*|01-pu4e6y2kPtcs7N+nbCpyq52Fi5@uITdQ^sGX*yRHB zm$TLSl=^r-Fv2l7S#-j;JuSMI$ElDsq*H$h_Wl#=oU zdJYZ@=KN28w3vhT-K(|Pq6yrGSXm5q_yA)M1YcU|nNSWiUCjazKzhqb#$TOuEO1Wa zb2d!*?;bwU=t7=Kq+6oy__XdH{%;wp4T-}am_uOh%X++AVQ;JUhwT){JUQ(@_ee35 z3H?S{;E1a@^(Z-{F&Jjkp5)g4d&J`Hh@?cdnkW?^cik@d~O|d z0imp5$Y`XHF25Y$X3CF+>Z=pnV;*ddWj~^0NL79zRTQpqbFwL2)6F1whkji=9--Vuc^Eb+qtu#YORG0`||+a+8Mc&T*>C z&7Z2~dbsXQWty{U5>wdn5Wx6cp4rrwUs7i)*v6I`3x+Eb`^c)o7zrn_3S$_N3`r>f z0Ufnv_iXQ7esHp_q9e*7U}W@C^2rOCI6U{$HecNFgJ;Rvgx%j32n#)&olTUeP}Vav z46HcC84xo9EAo;cP3?>=b>1fkk|6Q80O9fOhzvw!=kEscY$xZUzZJ_Eu`8rpr;=e`jE85hu zI|cMo3Je$LqWm{uT7MZm4Io@u?MToJgoy}cb=r{yhrB_LLC@XQU}++-Rv+9uDqrvH zdQqpSX=zi!hS57a# z{zIp7ERW!k#sV!yEaEo8MkXMiSvT2cJIy8ZCXgmYEoGCz$b*v2w}nVien^N^Wuz}V z#zUfpO4~=bc%hsm`h9lDl2F~@14?Bgx*P9yfER&wYR?-2E~<-`rqF zGs;=F?%c8pxVhwtxG2NKc^p?-^%Gs2MQ&WyO=5hT#t;C4HfHNA(gCO3H%9>8e%W@e z*?9KGJ-n{x9!{p~hLFI@x;5fGmk;QsL_VR_tAy3a3!Fze>Sb*lYaa%Qo*!bg;>8GOf%6M%yE_k8)MC69abUDZ|8_qI~2u{ z>DDNfZyE2n6v&G-f6j@BT?}O{8Yc0P?yjXN-aR~obG9rwHk`WSL)dZiCi9O9ci@s2 zi>bNdu%xQ=#oHhw9XwEn_=%g6d}QQxI-oN7Lb=H=><;X!P|9pYwD{)hikjU}S&Iv! zL1F<@)OsrP2Kz&9;hTPoW{*RH)M?7NHtTmc0fjLR2dk}yXAp7A-C0TOU3b3PASW!G zowCjh=Iqq2BD=%G!N;13t_eh#xFjtsu-wT{@tn z?PkWONAp-`oAP1V=IjQs5I%@95cT{T!tU52OhO_=Z7M2mbyUG-SFEh}e1s}Ol^`m+ z>qccHeu8zlAU0y>t)oY4ry*;E2MO3mI-9?B0rub}o?;&UP$9EBU&b_rGW?tQq)dIo zB5`b)z|fqHVPli;CZ_qyuE#~jE>Ce=46)?fpORti)PW)Zx-GNW8+k?3xH0^;bi&$& zW-ignoGQMa=Tu2BPXRu4%$DWl;GVEl>0dk%93Ruv#J`mv<4L@a63)3&-+CX~2>zLA zy`lTQo(ryXVSEJ*zLB9$AlTh9Vp=l!ccVTmTig$Hw;R zLNS_rF~UF-DO;RLx@0MP-97MQCrq7sDzhLX6LI(QgbgN#ESSrYW zcBd&xycH~Vc>|@akQ+A%pYZxLpDK^g?0q05%LTcrOtu~1;dCW zVk6}^ZQlTMS|>te0oxNoBYTd$|4Bmn3wKo#plKBigOj-vjD)Cq&>mgE6k(wF@Lb*AQ*A%rXK< zP4t|ZM%dMU9~51EF(r{*%Y0&9|%N)-7;KLip>`4)lhf=tbcrM*`r~V%DwmuHM^t=yYI~my| z4TN49Wt3w3r(2zN7gDSN@&@<$OHj_#u0l!Ow^QZ~vfzPkta_U`VyH>q$-7Q28m4-7 zbX0?xXrLZA_-8+{)D{MZW>L!0_KCYW#2JGZc1-Kp~PVn^*sXluS_4v* zY$Dh<09WNB$MOSAp=8JazWoRr_Xy2lO(rqo5PLng=(`0-f+Yt z*)2`iUN8^iL@$f3Q{=;Uj^RM6zo=>GS;JC*SaI6~C_Zb>kI#A*Q~}1UIKUImR_OXWzdA2}xZX=%U1u;tJn)8Z%=>tlC3Y z2i*UYsc@7x+xdY`8|2BF;UHqg(im0&I}&!It0WS`38W?;m745Y;%UO?(OAq!BytcD zn<>VB38A+A71Or-OU0(LQpdolwC9aYbEiv|SBmP2Cn3l)kVEA6mVZp;R%V8x|L1w_ zml{3mqBQ|tN_Nn6%J!>NEW~j>;~bLW<#rxVy13tKhRS%H*bKhJPX(wtT95z$Z=D1W zKK}9=Vn0z3Dc$90YnE(TmNR$7!@Y69B&!*2qt~}mXQBs9A1{{{sIrosnY`!LwIJ;1 z7@fAJE_@Fsh2^K~Nh5Y!H!$ye8y`P5flJ7}%NII(0$35G6Amdkm?G{Eg>0j@Wa;w8 zlmp@I_VWxSXIr(5kjeKgqr|G7NQU?Od zbRYj`E>+=wBb5q3EOC1nXn0{TiFw~! zWNp`ZKRN_*h%=3G+456ZTq2Xth%tx3cJR*{uvi}}4~Yr|(OamW4fl}2!;y=Qq7tWT z%%T?a(YXPsKTX4n6B_s%`_x`PlZc9RWb5DN!APM*GX1vsfYHnbC*to-(M=+@KNZCF z`cD37lk$<*=OL<)*Xe?)?Q%bBTL~-O*wK;EIpri5-)>Q;%mP7vQs@lvE?2Z^{Vc;o zXG8a)MA*o!W}YxlMY{jA6Xk=u-e}JaHN-zQniQwKsrrM2&jo^o9bx16x($oC;pDZV zKFlnNw9YuWQE>3QJOfOJK+!&JRs)b=Zdkci2b{TpYBd$f*Q-2f+bljlP}H+n=N>JxB7E^g%hj&jwA5 z+1Nldr(X|Dge(X*ak>h*d}UZ|obTu+!c;w}bJX#%PY}4X$?j|x{xcAoGh z-3-}{q<;X$`hNXO&lu-kqarPtzq57I&-s-vKQR1mEUT(i$xR*|w`-BNc?iHg-x0+F z!xpfrLHyZoz2ql>2@2*`8oqzaQvM6D0Kk9pXHO%lcvl^`B7w%I;+L#4An&oyZnz&if5m>!ej#}R%)ZiC16Zwe3HQI_6iL!pu z?e!0fxMJTLb3wa+{#ft7n&brqCPh=Eg72H9gI0P-W`AAczIX33r`Db*bRWs{WbOTw z-}gMa>=82Kq+`&WVyE>M+MEW^qm1B;tjL?HT2rd=hXW^#f``+bkII53f)#`Aj z<=Yj~Yh)B~9_5c-$92<9%RI$wTIOB;aelm-=9iZe4P}%Np#+&I6CLk>|NfOl6R>JD zeUs%bGhX`XJ+G14U+{e+b>icoBKCBNnY-WJ6}{p*vw9KlWhs19A4 z^l*{nFx=ZhKQi%;?Um#VFC`dWznqPZAiC2E|3*Y%%}_+b&}s19FCmU4c*>GkBJoRK zNH@Zh++YE3+P|I>wzVyb+OdgrD>&<3rxfNyCROvlDS5+lTyu_Rkph(G_ataU1^xUU zSf>}V4o>RB7B1QtS&a z%3iw)5T{(+G0E2YN7v^OFcnp_f;850%rLpr&d>gs3#28=U+Xn zfhoJ#Fh_CsTp&rbSTx^UFT_(yJ<)U^Z)EIZ|6vO*96?U*)y>_b@LI`=$A^h8<&@2$ zWA}wVH>8VR3r<~{P68`Z2}TTP66lknUz7l{l^Fn21Qysq5Lj z@CiR_T|cNxUG6HSAKy};UO3mpskh^@zeIt%o1A%G%*uO#L_Nk=GA*~f*bt+Azp|Mo z>>6LIh4<#pWA?W(ZyKvsck0(i!+&9tq^xjyI=TL|XbAp9p;FV&-rSvb+L-9*r#nh) z=d)Gil@=>7^htEM1S(cW_+6)Qajj+1zDWc^i3vabU}~_E__>!A!q4;{I?%=N zyLpqDOpf_So`3#Li83EvO)S;C>3DtoqbawhBK96Zt+w;VaEzcA>ld{LpGIePk*@b4 zA8g*E)i|4qMjGcXt(As?ip!L~SGWr2t^Jc!gNDI9zsEZ{PDWfVWM1QMo!f9h{u!J1@dhiydbtdx`A%Il zsl1yyP-gv4ELH71Jrl2;92PKCZ7&lsLiI&f6Y1i9!Z`R+dchrQY`=qER<}SIP3#q~ z2|r;<7H!364ew|SA2WWHzapbx&}BrrD#-C2?f;m?Mm7pBuolciVI=)cZGKLYIon_k z2Tp4dV%zhWgjBJH{qJ5#sT&u3UCswWq3ex?P*ivRg`NG~yq21jt6F2e1^a4l6X`C4 zPdT4Ba9+oaoqA;{b3_*~_vH}n&A)h?f=593vHe^iJRjWkVW7cXlNtuoh%b2$o=6Wv z!3S=RKkcjRP1jiL>|Fk48hw?KG_o(DLsNESl_~g1+Rcft9+$cd_=0hi-@SQ{I9VHj zX0bChzY52(l0lgB;XWj!owkwb`@iolOMOnNS|Bmkd<=zUAzSUI0;3Aa*E?6a!W!Oy zpUft%r=j+C@Fq}4R02IR5;E9Av{!xEOaBkDU2a<$uZ&elmr?%Sx5m&6a+ypTLis8g zAN22j;J`gdP_*CH6r=E2=`$`-hrB|G5tE9sv(;lHLp!z8Cj6?XHop*7R(x^oJh3nt zy?x7axSPkDCK{JF*EVO@R=|jsTsxfY2a{Q={&ypuc^W1V5=}v?%edyQGpj)m*X4`F zz?f+Y3}tp%e>1xvYxaDU&QeZ7KhFFyvn4X;Y%&-}vu z{a@-^(%Y#oi=S0JUMBn;?~C%x?o!SU+;4zDFnVLQEbq|EwVxJsauivJRtc9HZav4& z#mGnJRu9|PJ~|%>1}d=44w<41W4ryy`ih*MiE>rwwL((fP)6!Hetr3`o}$2rR+c6_ zho#TrHCvvP9V|I9#F`o!n~ck)Asx_Z;M?8=@S=WZX{ea_`Xe5>){GTh^R@?kA9~I3 z-lQpKNyy8T?N{~Q8}*)(L6$9+22>gcw>Kc^V>U}8qwk28jFPU5ot z>|!)koyyGT3lv?d3>hfrP_UO?gGR1GnO-uy&)-V{zWI4me!Ns4MNC#)JsiKbAnYLM zi^)o}0Xju7DsFbZ?x)UP#-xa-^5MnY#}qNjC(Cr6nf;DPC;GDeU%GQBtubbEUDcnE z8NwTWtlAZgU_@YANg8O-nfiSC3apuUcfgIX<`{q!Za5r+crw6O$*@~pcV+tcj$8X`VKzkM3Il0t)!Nd5s zF>C$Bzu(XyeQ)Z;@EXEEGih69dErzT&HhXLkEz}-wZQC3g&pdUKkr3(YSNg&4w>CgL~ zH&HD4YOIsL;qUalEt23UZGz0i_`DnqxBxAQTG=)fZdF~}=LucPNq8@pzW|Pnz$My;}^2A-DhVHiuDQRaagy${c_4NoP(x zbnlQ#lCBj?Q=&X<=D2U6VPVCh?3VQ5JB>23O2LLS&dxt~o*WZ|2mZWB`Z`qU9r~|1 z5T*edbbAb?PbQ`CsX%Fi@kIXzLf!iCR2YYlx}K}0f3YWOXLWKiT7fscB3*{`L{nZw zK>@nP>`$wm(#&?ktgy>M-SU^cAEISdHKP-}1mg$3YRyO_5|)u4Ai(>Ie_2Ig)S96s zn5=hQk`cNbPg9?m`aBF_{*VKAE1II;;LjKiST+ZxR4wjT`NJrWW2B}5^A?I<|K!#)w2qFUZ_*JKfE~WMoY3;7BTT) zC9=NARxW+VCGdIA)?W-!EHd(oo+jpHj#jZUZ1f1R+NFAYa`Gd?cQn@vhibndbur4< ztw)WlE##%Ybf(2BwEoy>(cd5O$}8rNSy>&>i{=I!vPXZ%%S!AZ@kV4?vhAGbt>R`+?! zn2&m1ZcR$8 zgVFqq;elog8?r_{ug^DLZt8sq*j@WHSWQGqF7?&OJ;`y{l`n`mfZ~ZP)^=VnudOa3 zaf_waXw6Nivic-wk`Ng#@`G;#Uo&=|Q|;!>;!@pNf0K24rIo;_%?>4j%&YJO^VLiq9G+kv>)ZN#m zyBVZGy1QZM?i>jTMY>xW>5%SDK^SC6DWzK)q(MqbnxXUkJ^!`dFMe<-j(6@ovG+dv zR9WVnC&O7VkmBfP)3s*S{&={Uh&+#}hDfJ|855bcC^v-$N1;9eVfUeC6?Y@!QkoBnsD z{VA|fwwUx4)qIVq8jNkgsveXrH?{*NLF^Ww6;PxsGm1c%g6ml4ggo6PxsQ5h5zbx> zVonTw)vMv-mm=Ti!z7sXUiQ$m`>NLwJ7c38bu9YLxGmq};g&k^qD-W;iapAH+;`2! z656fMsbDq_$z;lHWV>&dpm34evpbKYk7LzhxTXR3HXjF^1>zfLPNmE2LDCguWH3Ur zHZWsK@V-G=hZ|OXkNfM*5oepS^T%eFmx0^Xh>hGUhyi{ke*=pA{$wWjbsL9^?DI)-<^u~WR(VkE)t2V~kH{1K zxfIA37OZ$wG+PBh(cS1nS9MhAL+{xq6K%y@BQew7uGza<*ce%Du$~ z``u@voed-jHv)*;q<(z7rrYg4M)S4~%pm6%dUHaR0+lKeob@_*_{oV=HBDKiHrZtg+*sn)t!lX60i?QA{`EzF~ z&S4j|S_iGI1`J*OcS-6Sx=2^t-PS(UlJ1Lw+k1))h3QcU)hMf8tyPPDk47 zY`8-Io5_6Nm7!TLsg%2fGnZxpm=FbV!JEwxw<3-SYrvz7z7oo>c>pSKZX^DNG&u() zp*AJG2qUSX-DAM%E7im7UNz|K->B!~uVT!l{~(6f4&8`8&CCAfY2}t)vdMQ5sfU5E zhvs#~EmuH#(uMx(Mv_)h*WTI1a_xc!E0TULcd7DTv*il|f-iTbF8$l+0R)5~1zDgR zIxBiP`@HHk{wfuddbWX5rq;#?2=RI_3fV(L1Wm}n=>g7Vkrs<>1gq;S2aHdwv3Ag2 zXA#qhuhKr)3ri zbbnd^2Wv$iCGt-I!pg@h8qcX})a;p$_b%f@A7JeZ?oTPvy%_MQ^U43>LFsn$MTw6d zAuf2k%N8b;xII0$^b3{azURhG?y37eIR-k6ZGz&Dh}g~gN?sHYvE6+$u1}Y~Kb~}( zD?d~nyh5v$CsK^dz#`UH{FOn`dAixoJ))3*lK5)NJ*X$mrA+j@yxcgi>fi^{PJ79& z``DFMyEQcvPh+Z&CVylJkPeE^N00_QNM;)d2>?q6E3gt!YVB&UZ#@Ee2I;exxGYR8 zJj4xQwuy|Upx?(dt{f|TNGT?=IUxf|C>k2C#hb%p85tRo7RegdgK`!xZ;bF5Va%e9 zNITkWv^@8VgwimLC$mmYP4%@ZsZlo&PCc91FmySr>E5_UbeGLFIho`Nm<9|C1Rlx1 zUGiTVU?lRN+C^s6#pt%^Q~_@Pc^Kcb6}{G5^~{RP1DC(O-+I;4Mc@+3fzmq5E!3pO zsjW7nimPtpOr{O*h5jo)y!ihR1mXFX(q!bymKanRz$}*l^`}aoRjMigH|5o2nf0@rv;$~}MTEUcD;?ni-1Jw}NWTHbGZm>UDCUse zxs8)cbIHP}k;~!d_zRUg75*m$u#$zg#8Zb^;N^AAs@GLH0D@#^&Jm!X^J?Zn-zW2+ zHGlH1QHDTNn6{dB8w73j;Qzd64s^J?SFM&wIO9AiIUWKQo8Al6qtgKDGw@`eAQ#ST zsS!;0@&-JKkNW4(Ec7OL7XqP6Q$;WMA}(txdTx9LPWsMq4-{QWStS$Ar2JbSg1`T<8HGkKsq7ZmxT%M1 zuNh@hH<@C3eUNm$rtn}#=LJrLnfQy|IXUv{tG66u{u)fGmhkqS%jUi8Y<9f`qN^ZU zT`Yv+3U*wn_b3RHdaMm&SB6eo`x~q)fBq!AH%T}@R6%!ne&fx#LYEWcK9pd15vje} z10_)hPMWNOJgo0iwNM5RUm>t^m3sqNMCfkzwYnqHRNvqH`&p@|z@{It^^bViS^zkf z@2h^ZbKicvV~hLtdW65iT4Y%)OlAX3pA(1@BBqvSJ*2NIs=U5`PgZ5owPI`U)>Wv- zupF47dEQVj`up)^+k)TM38Y9EvYA;8=>33ksUs)J6t!2Geuo=+5XilMfZe2Za_@I# zkOE3XyBJj|EB7s8vL8NzS(a)EUuPh&NM(QenN> z-lLhOfVkp4Ov;hYA%rvA-*gnk+6t?(5>U+*uunZ-Y^(QqK=r8mV;|??Rzhu6=IAEH zK$zq{z(jh14ovrk+>FznPZWmtf4H|lzAD^9L^?j^YHDdANE+(>wSJB?CEKy!E;*As zShHX%r!mX=2HN;-6NQfKS;s~!Q32uX8zhxc_siGn1nVF(r#4?M2_K8@Ly7B)`)f%m zDgXHTSR`b5hU^MdB$d(#*4UKbJ+Yt4FjA+J1FL-RpwY#j!9p#jEs>73t=Ssvvg5pz zKc#@p2o%hbdKrOyQ%>~2B&MD_(Dm6*R80PTrWA6Wkk>*1=e`!PQl-z(n3|p+ONIHo z;j-wB5*l4<3KnvFbG`ZS&V(6=rOA!w^_=Ll4VC0QvOT<9rjzm@R0Bok3P-CM)m;86 z{e?)d^zCVDmqNW89ycNSS)j6T!Pe}@_4w_!z#C=lIsgEqvIU3&x87y_7kvT+FEgN5 zoLXDcV$YBv2;WR zJx8LjZ~M(eJWi<>kda_}!lI^~_^mYMY6<66NIPn{7-|Qh!;MN7h7uzRob7ekf}}Qu zsn*6ynM?+X73FMw&>i(f|GR;}+X{{YyHPqd`o!b>?(;@T{2_PNbas&1PShFn^(T7u z;RXfqoZ_g+eY%!3|X3-e~)uQ)wLj>U+JD~+A)e4^X zjznuaru28~Na8jC;xuqJ`ri=&7$JNqz-4oIinX@0K8>X?C;?cAjosHwDUb1$pBgl9 zfap1S#jEjo-Zb+qpw#v^`7nX!AUY7f!$U#^HHFs$@d+m}82y{YYG+0K;3THOrWS$E}sHU!a1;L%v`{9^j; zz`WxTX<08c4 zbdB5cL<0gp4HXg2zT~OT@$zY4Lv&+?F5l7rzBxxlR85~2B2iUKRqMBRwcncgJby7T zjoExE-krFHzUaAu5sekM)U?G&!96Aiag~tak&h z`v4DF>ssx-f=cJ&{>2(?Z$!^&j6w zkcK=9M<>xJ&O$(n%&!)Ph0EOw-cdut#dUE6??DiyOlt*QoS=~PzKii2cdF>m^R@5C zWIpU;u^+2cRRbK%L=*?V*y$s(t~| z1`s9@guj{f{6SV0b@NRQ{lI{Om%z^}+B-Gu`;MHX`8AWSLV7ZG}be z0Ub)hPS6_X;bBErOWNo8nym}XL!-_nbj1{2O^)9mE(ix?iW?oW0l@H`XKl_cim;n^ zM{{Pyf9%k=q?rfWvxog?%az{vgmL&!`6@5!F!93>sD%{Kg{l?)AmB~ou%v_ak_TzJt3?ecIlvNh|iIjOpS>=F8-(X z3Zl>U0@p_e1K(iSCZ}o|UE-t|IPC=f8hcycIgI9KC#*Wjyl4|czV4N=WAT}p2`+s6 zqM_zZ(6Q^Yo@QtY}qf!rSta{3Rt%vUJ#{hXZto0pcGu%T(A+shX#G^ zSMbdJKCnFC;klii@v#dbk2V1JTf&RzlfCyTKGExZ=1DaCNXFQG|M*r|$sv1(*|Af{ z5xq;N4>sjIr!pjcs;#F73mDaghpCku>Tw(943k#nF!$oDP-#MdIuodN^3S2`=YY{0 z>g?CT!=Q~@@D(hEF?P5CtZ9YURRLAoHXj90`qA6l;nWz`7(1w%qk882E+@dlwN(JW z;si-jH?{2UJ55e6WjZ2A)&?87NkWA_+|xub8BJn;D&JZBjgzL=rdDnfVOlsJpb=aRF z^zi|QOuVHZJ0C!cA+>SKsNzVd{I-AkVIWnDsJ-_#f>2LG>yb(^lM;Ou=zYsnSct9k zRB>hL0q_ zH#@J7R|BeyL^E_YLr33EN-Qm`gxMZ+n;v-3WAf}=?x@Goz+vk%blj=U4!7W#Yd@C) zNs_j&se<+kxry_gWvpC%*mkRLC#{w@+Nr%g7NhxuqR>~}9-NmOS)2vLOm01%*hCnV`Y$7BotHt5# z*?kB{KKTkv_*SFsIB;#GMb zC{kfG@Kj@J|J+~*l|^xWzGZ<43!JZB3WyAmM&`^H3&@mg-!tm7->muzxtm#AS^oR7 z!GrK=W{Jx*f1BVDwfWa_V)$_@SrmCwV*I-g=RvfZ5Y_&$`4pPw7}N@47CSf^r4eta zQJD@jnFpYD9RUPoXJeD@np(W~`6Id*zu>Qa0|0YLW~}d_1}V~cy*4reBk*v>PJUaw z?Tn@$HLd%ZB*gJxGz|o(a!G)KoXs4a$=6H+icAtz44I76a8?xj~H#-KIux~&6rxKm!4&9K@RhECgm-FaH(z|NgycAl*ye=2kpZ2Y3VwG;wN-4mLRDC(CWL zy121oaAo{6_ylyF!Uc>Kj&{&6PF1-6U zbX0!@ft-PhdN%n0Y-5Wr;rWji5ufB%deP>h-v+C6;3H~b$j(*N?S*^HNjiH7OF$RG zVza!udg3_cg8Sb5xKXBJn;tgptXPyZV@e_r$4v4_6J&eB9=Ou$%t!!7h?NotvVK7! zJD{3}^cCw>)2Z`AiP9atHDxoAjIm@fz>12huM4zhR@3b@K$#pu02?XFFW9>=EV@nX zr!>eyPMv27H3Eo1ele05(ku?h#ekYH^aEL>#CQ1 zC|qYvnarO6DW+t@QXO4N+48=y70@r_m(-L4tVeEnN5SQl*VNp!oVGH@fdLZ2sL$EY z?$2!#Wo~9!an>KAjy?N$tH_uWw<9)mWEPNl3uA^BkByJ~b47LWs+wGVn z$yH#p)N)|JMTe!jiV<6bqdJsI9@7 zbF{~U>YpBNDr+e#KeV(2n3Jt2u6B^w%dVxL=wkGBlPrQfb$m0PCS_Vh!UJghBR6N_ zNQ7bR>Ez+1xca~xTXVn9&aS7u@O%POY?i`0t=rTP4+7uShoE)kbn8s77SFZv!+K|l zDWXDTu6b#Z3depgXI;@xoJI(u*f{L`o}8GtEJLYrKbMu|a*lfgM6Bqespt7&i} zhMxac&_F-oLOnxST9?M?{e_ z)Mlw+(v1gDtOM%*$1PU630Ep6n9_pxjG72ID5_>=q+p49p zpkv+Eqwgt6yWojj&_F)DnqE=GHm*nt6GycBi_Mgnpv5mNrdVThc9QZQs~oEt82n4@ zSZq#U90issoh>pll%-{72C1RVpBg@;S;ziYNtk%{*!`@iFYSs3NM-;L@Aw`I^pI~j zk1N;!0yu*hB_Pz;^5@V?u=(OL2gJbuil!ubEYUHd>Dj9nE7}IsG6okvm*JSaW&9M1 z1-7=v!ijqmMr2Pixh%h}Q7Usv9I-=j^PDAcsXK`c%}dVjuJr4Zl3@0m_I~YHf!ro9 za2SSB7rib8ci0mX0zAAgbo0}pzpnBNj`CdH;`M|q&Ha*Re7sh1^>Qr3qG!r8!7k0* ztKF!GEAPX0F4B7ICknJErE~C0P=O>!(cG&5%a4ya^)&{g{9RmT1rF@cGW*qzLxRU# zv0hCIPbQ%v9iul|vCaZWP*E|nTql?DFAYYcHqq6%9sx>j-prR&_xk{eb8r$Dsj;Ye zcWAXiAJ#ioFGn$Mt+nCjEHkj2wwYpvu65g{Zlxo8DPyUMUUr>_Q8O%S`spCn;xT7i z_x622i-QsFI%Kw?o|@$wUVFm7iak_>rio28rmg*4aUN0ANWI9-`jMy&FHq0gb#L6C zv4@j8bL8URr;gN3D7AM9fpAQfDYgBJl3|aFy4Cc^W+J%EWqx+s_Eeq(wd}&s(C?;?s0%bz{ z_xoHK{ignT=hu~!{%S+v<_JwsbpBz~oUq;Q>vHDGq^h7#vehp2xsN32V1N0MJi+zX zmr4UiD$2b62B)8jb%+aotWs`zqB{@1U(W*KN@F-xRV;kRdWX%^|xMTHR z6Eei9qyoYxmC_gxR_(8b-w46FD2XUFON>H&Uv!`mBxM3w;hm@Ge!L5|g_bl5?&1p) zt-mdeG_{$Cn|2x!Y?X#CPNe5+HY+}IRd|%6&GNDvpY}N;mz`3Xg)f(g+zY(;W$9s)E2^xzpaUmYpmu`_ z3H&aV@MJgN(<2#^9zXS*(Hf3lVB$l#C}kCXr2~Kj(Y?^lQ-)ajs;MmF)Gru|Pe>^v zR{L(q=SC~;6Dpm87n>kZ+*8i&l=KL*e-wP$_Plzhtq>qiW9N6r&>Px=Dn7jP%^xZZ zNibYrjb+rrSDj!x_XvdDeJ%V1+XG_IPAYD-@%&trwTXelZa|ngT|Xk9q>hr2SL<+6 zj9x;WQ?vt@9igFvO&RXLcJmKCH9w3|kn#1(627sA*1=#^tZ~2X3RF{L=tpe*N(j!t zq@(|l9oyCt+=<5<{#To6@7No;ea)n&wOm;n_r4;@6sM{6BP&PM{USvSW&Mw4Vx3SR z%N(}|z6v%Ef>T2?{>48HNS70zJW%_7UEgDfA2H& zD2XS8AdtGFKsrT7e81`PHBzHjbNg8uXIGFIOi*R1)u46KHU~uxGM)%3^IGA}?^sN1 zEwxS@LXjuiKXQ!KA;S+>0a1G!a&RV$%`P{tf)ya`fwb*NH$DT7H=)*5AXEhDKI#QP zi~?B~a5}I1Sp47xK?c=x+h`1tZ7J*S$2gl$e3l4;xSt)l*T)hJEyC<`N`5Xq=!c`o z%0NJ=v5Te1A%qC|42-%cg#R=+G$ChRTyC%2E6RCSbsomN*JO|ey~AbkS6n_R_cc+p zI}q%v3OSWbxQ%I8spjrFVj@+>QT+OY(fGyW-{W96w}yk;>&ZP7S5TMlZx$c3$#PR6 z3J>gzgT{m;vpx1p(EK(|nc2!5N9Pg3% ze9`ZY9Cz08H1wmGFj(!oL-CNH{|||Se|9V|$KN=4BY|vFE?!Q#d3h7}lYjk!F~sHm zjH!Bzdap%k*KfB2v%~B{(lXFPzxO0-eRWQZy7>#{{msq-g8YNe;m9B?CZcmP$+ZG6 zpC(iiY*nOnSG(MKPa_$-v!F>YydSUyG9xHCb17>+Dc2P1u4_6JO}pz}SlVxwWRQiK zvd`-4q+(t;hQzjd4??sGJAx1Gw9iKKO43VnD_shpXi^xYUVu;KrUzWMdLxARS8?F1S`hwZOShVIg#5TJT) zEAG0<4?_Vekm&hH*daXzJ=EkQHc=gC)^seJmsvSm8a;VY5v5GI$@ckI3&7fV&Tz5i z13q<-%>||Rxr0FIUTuewf1h; zH{`6`p2C2i#`fyhj%jBwQz|Rq_b*-Z28bbq2=VlBkyMeEvD80q&R5k}T2Gae^jJZ< zAaYvTq4P!m0h{?6^N|@Q$-tw;yxW!9;OJB7Tm3}bq%u|_LsJjJqL+*$kG^@1$~l~w zkxwk_arBwaBElV>BuGf5j3umCtXOgM3~Goszu`fQx~1h}>YlWfc3nfjAmQb|hx~&KMWYN>W`uX?+EptY^ehtOr!}^P+)I;o# zDY^fWOx3&wa4`;?#<`?^bg^o2aIS2!Om>ZIPj-xLZ16(Ap{&*4klm1IAw>Lq@pWUp zqklcUvNU3Q(oVC|%$76HM#+17%V^0*biP>H5d0b89f-Da@p@MRd^Ys~{PIh9aFAu` z`^{?u$JuM!Qk8mxt(~GS)esAw9Ivo~A2;=$3&Cp2Nul(!`Qv(=5Q+;xiA)#g{aJb< z$eMvlm`D+k&Z$Vy;OG!(vlOEN^zXXh8Og>(7+D!j%=gw#9(|^Tv##LaqNu{7=h`Z82c6Qii=KWhGJ5y!NREj>;y#_2kzMQ?a zP}xLkDGH1}(zw|H1_vN=Ca#;>Y5syq(p`hdQ#4}Y8I}fo%pe>QphT|qKN_`!)_f>XZxmKwH9!r zLKzP(2htAZ6;DI42^0`@({(c1dMwPSexAGb+MnKAvS88I8^veCKCB3jC`_pxoH)rZ zc&qL3Kj7m5)Cl7Bu~>Ja*#jAMUNO@`|8Bye-Kdb~(_9waD1XI!x@!LFOfE$tBpHe% zRa~NG>m^U32I?Wj)b#*gy0fan6FSweyfrjQ_WgaclI=?LGz>IJgh_|P4Ka)di_OF_ zT}5&O#lc+KKDD;b@lvnVPhSM);Vi91a^XWF0{`?3hCtCzk*qNm;D9t8 zW3f<!2<227n|B7ljnG+;q!chgRw|t zAR-V#wgb6}S&2pzoXp9o6ab|Ts}`SHIaaOH%ES}C6KWb^52U%0ei>VF|4O&=9xyqlO;TV5j+tt%iy5Ee?I3Q&k&j5s4HA>H_@Old&s z14Qd%{fa3HoKe7Dt<;EZQ3J>CQL#Tc0TnbK;FFN4=ny4aWjf%46r=>vRbkv}P5cbZ zz$a42rH+Pje_$t9dCUhrqC!+>aj0B1W^=#aR(Y`Am9b+8Fv~0I+G#}7c2zAk%frM* zT?0>O{)>ltRVZcKX@L(9_;3-6Ct+pu=z7l20QH~X#XfQRR6XfAQh~ebcj&$9@id3~ znv(-@!6VR;s85jcgzUhINEZYUJh|^*VP)602+oCj0z#0#!&AJ4huf`q?q>KwsmB|(StMKT z)I&Z1CBdsfhf%UupU62XnkYZc%ga@L{sZ+shoY1bHBz6Disft(W`K-%FHS)Ex>bZO z%Z2&t46hmcoJn`pCD;H`_NH1FTP#zc%z-R$KdQR*zCp8uGC2v#4xFpCiBYEJIB&ff z3#jsjlK#4Zv5bx1B)iM|wbhc=M#Sra<*5A!sSyRLGk5u^H#Mkj<^m3l?2(}>@hTd# zQ{E)1spqCyRdV%+?Fy=;Vrfd>0<<0w_qj9JvzzBCBZRGISmWescHd?1VlEhBddkdJ zLh^S;_y?$XFXV2wl^Hshr-GjA_24(nxtvMjrrolUEar|K^%!GbwoQv#IBR z4Nb^Bla=aL-g-!KmU+PE1@jO}P5rySLoVCfAA@4fN5B^M;V&qFy}gawD6Zl8%i}@U zHit!5l5(MMV)!Xd2~*Y%c2Qf_{3=;7Kt2?>>%KjF-_~@qs0SvZO6HA!`^wHa`0fn+uGtb zw$bn;se$#!*_Powb+6`@i;}$BP3`C7(=*^t)7(hkvI37IcEIcTq3DqiAk-c&WA|>a zk@3^Cm~P=OkEgA`)?DA`j26G6kv+eQHbXKh3V;j)Pj3I?5cV7zU+}oH&O11=lLsjZ zLad=We_6D_eb}{5+j9#ac|`@|8P!D-M|bjs0kQ}DwB@*%nXoMia9IvDgD*E3u4gyE zCx#u){8y@wJ{4j8x7S4{rhmV+EH}+yukuwonlt3qR0K{+tu2@ zbnMKVM%x#<&Znnn-=iv0GU}q&G)d;`--TdEWf&d@A;ZA%UOc0?qT?+Z*_P8jlWl)`6X)wPFbE_&7OK z2>HEIo^*!F8IbX|x?Z|Mv}Gl8Sjn&b9|k&PwCV@u1gLb%C;8L zH5+}d)L`vi#5ciz-}wJnsWM3DzIlry)4bj4`G!Fo4e2l%o7VSwpa@=oPP4m|6`W|j z)X1JczJx>D@uVc>F{Js;qA`_$VLR{<~Xop?kj7 zeqrJH*}(N}WAJvu@Hq?^V*{p$@h{G{C(qWrD}h8@aYb3ctlY{+|4Ju~9Zz_cE1&CUV*DzjAJoiw&BXdn|Y|UvamauxY(p<^alj zY|JFf?>@`-KT;V}L@v z>oq!Xc<|3jImL?R_PmUWlEymFiAohRvZrp87;c{vpQtIQ@ZBPC2lshj``H!9MB^J% z7<0L@01`Rp`X|ZSq!K#zLA$eili`2LZZhToeCplPmz{vh++UKkov0|Gu~kTAABYXu zA?86(&d+@zPZk6OVmpu5qoXA1pDBHFvDE4pa+>#Z;L6w1*`zGp1j z7su!{Tl-TO%F$8oSWE<{$yS9eoIq)J-pf%7|Idpiq3|Rz>M0LjG%*}H%+iz9b85DS zQZcJ46}W=?^LlXQ=hK9FV3^Mdz>jIt6Atm>L@5tefkrV(WjYBAwAFX8fFse+&;q)E z^`ED*;K>g+f5PK6HMabuT)P^hr|aFH&jA~h#bHrpw4}`}j@NOoN5NM|97ob_*;yf- z1uwU*!Ji9He9ZlVBrIM|l6()ow*YVBos}2W4N2yyad2q*cr_Jd|4K;vMgYGBYkSnAc|4e0tPi05 zK&)?65y`0fU*~|n;&Us~_2gIy?ah<$fdiug+bKgu@4W(3OL{)^+>j_v83bSSH~#$Y ziQlsBh1>P=wo8ehaGUbxDI0j$@Bb_{7NtyM9yw&3r|?}A)wc z=YzL50%AF~r=fj_=t7TDfZRs%0l&faMK<_Gy~z6bU&i0h*1tXw<3@hsdFc}&U`ipi z2nvslWxKeeuMkVCAOQ1tYZ?^|I9BXTp6T*{MuFE*eI(_ZT_4Lf$b8{jsICr+Enh46 zWS{K;`18Bv#er@MCgLda|_eT9EZ4MQd%)8x*Y+~C`ZRjo4&xHm~leZqGUYn?< z&B08*0JR0?a_#lM;;C@_l6sDhQkeuaMxXgX#w9{oju;H1DjK`kflmR_mJ26OmseNG zs!Rt5PG8H*bILo`z8Np!%kbyOya9nU>2xc@lqn9Qws+@HNmf}gsnQq{atU-EI z|42`ta_dWva@B7Ks^#zaf+WWOu?SLiw(E3-!6zi#=3P;{POr=$(}I9bhO&2c!Q7ke zz#vsV8r|>w`$D}_v`F)*mFh>9>MWiC_@jNI{%!Q$-Ot&kD{ z6I1HlL5lBh{>TH#4;Z%rhT`=br@V26oZ6}yG&n0thP;3Zq1E8J9DZtXUoj}!>d^a6vo|fQ&hY$F= z?2xl_;|@!5%6T&xec=SgSSnGkbYOUiIY(tG)zQ+*E59lbu+VC|{)K&DF(c0jE30D9 z@gmZM=w5EvQWXt1hOE<_f&0&bV@roO>IrH59*wV$Lb4W`J5UqDLD*9A1SpAA6dRF- z&F3YQwVPoi>UYx&+Ghz5!DHPivblMUt4}HT(`!pw^#+>-k`F+)i?Gt%5y=?mwA7T6 zc>RjTZ;QOp_g>Ko5V*{?T|?E4o4qhIt${o$3%t8{i*sA&OWzdxN1Ki~jjSl@4e4fRm)*W@VQSWCbYw?4OyjxM!Mc8u8u=TvDCNZ1CMLA3Pc< ztXtNGz}4afwru0B^&gREPJ4b|^w_vfzvnv&Tc~KH3}@ju4Jm@OY9l#DiDH2UwIb-X zmj?p^*+6N$ubl1iKN7Ex%_0@VlIwd{BI}!T&aT_b!f{X!K+jt50x%72TSTxQ_x!mH zn_vDt1a|KE?L*a+-(tI)0c<)}B)?GK>x#o8X+aszibjV%3XpMyi4bdM*n*Iz^*gti z`g1lDkMV@bCZ{}DqHyrug7o;;(+*-yeW2_i6%`j8+bokeO6{+o);0G(<^oSDrbZlO z=n#-o&}=S|n(rh4FbGtvZyEay;OaEL*Y=Q@hj4p9Jb5nN`Ir=+sQpd?Pulmd`@Csg zK9E?PR>Y16W^RJOv>uw|;u0ogG}Q70@A!*sp*oBiYCqRgBv_?Jh=A`s=CEGJwtj4K zeL3`fuGI`1ce@*I$YVg)$d#dM&&_5i@NG^$Uz{!pLx6X8)-9g|pHGzh32a}+8sI^$9j(vF=X_`Kiq8y~@bx*B82**%5$FS5n5Fg)nKLbIfF0E7nsx!b}UT-a~Wy#_0 z#MC&b`etiKHPe=gMZmG4)QWkaa3_{JOVlHaQ@xaeDTPQ;4@EWkwf|{t%gSgKd`Rl1 z^8pJ>0yY2Cgz=N-N>xC}O>JOT*UQ((rL4|GD7&e6NG!4KH_v&3A-4L@;ugPpKnNhjInd8=`rlO1HJ6RyT<=s;*fMr-2Mg(&HN*R zetbOJ3SAHlzNacY^*kHKwAmv?0JdNM^xYsBu*6hMQDq@MT5gMc*?W1CH<$E^H<0E0 z7knIYrzrJ!_Jja_=&gP%3wf>;-4Pv|7>DoFhGbbhA8m86kEg2U^@P%RX>wlAC*Y)M zETU}Ih$Q+KPCgqZo$t6x_WivC=ZPe`?G+yXrqtw4nsmDuQ{*-;+?crqWeryN-nSVp z2Cclge+Z})$s=p;RLL#3uJ1ZiN?3(K30PI)D;m6KS#Q?r!>__ox#KlItF&I;W9C;K zro`OW=q`{Gcaw=whrI?|`>v1IdU&25ZEx3rRjhbaU@DSB>}rY9x#u2+A-|m|zRrvB zufDfEKkgn~pO3mIiD-pnV)6_4}9eMAojuM|6bPL_BPKvIv-4|fAy@L90eiy3It`gzDA zID_YL#}Gg@MRO}Ia)xNEM+c|(1?Z%&M)2X0UH9zh=3)`stw7wB)hZNMuF^a9@{)S4 zO1fBNks6k93O(e_tN)yZQvA{d3gHmH6K`-ZTTNH`X5^*C)#pAA`@pFZb}S zf!MS?j4%STS^Mu)ozH*qSu=hWv;KvXKhJBwpgeU*(*Mh^^L^B(-EIjv#r`w}d)$0B z9R8vuAS4mZsSYfrU4L15ArA0yCiz>XN1P}nLJ;W@RHV>rvvAF|+UP2h`mMMME0Kdj z_GI-(nli0lva9qJXNChVD5D#{a^aAXD3&$phf(9rec@2@>$BVOkUNf){=`?_!J}V@ zUfrCm0MK@8UTx4J+pisVz-6)>@8h~V{<`12SZ8fl%$^_kWv1Hnryw4F4BYdi*BY>f zt+GljluNX%A3HKl@voU^_jbJft4wRN*F0YEwAkp0eY4t@7pa#MTSZ=ByC>>*4=#5g zVS~C~1{D=ORB4}iNl=7l z((0&;cA`45fU77whdMtduyH_hoqs`u`4gXuc*JynjUz?T?QkCs{<;Ta^FK+RN;5Wy(9TNb0lwO7BRC>41B_$j1gIOh6rM z+9FW*(5by)Q6$sMPy^fp+u0~@fJbG|d1vX7>royC!z?{}u(&0%c)tIr1EHfXsiufd zEa=yWiFsddP@-3ZxtD3ja{fQgG&_nbKb4&Ud7|!7eo0O`jA(HSMaoo+EmEU0JZz5yJ+w~ z&hP%jYrNS7Z#Sf$CTP#mEp9Ctcj&En0Mmzh4dO|7wgoG|OkmJI2y4zR);kloX|&H8 zbHJVw2)#9RRTr6o>yj@X5EUMs(VD=Gk#68~!%aEazf)r9Eu%q*Q2&tpSCP@A6+mOe`vV6}9 zC4mc-s&$b0E9|j3 zL*jF~sMe+j{0}_tR~5~JAzvuurL8)Rw(g#4r`F%@t0nzDsFp`kY#>lC6&-(XsPW>8WuC^1Wf?bW3p!Av4B9MeCTFXT@wYyn- zniXMIP+SWol~E;yzM7hA_zX=o7s{IMC{zeQra;z`0s`~K;{cylp_H<>4IUWZ30tDT zghDqkjmagIk?_0=7}T#+@pVD zk$5ze9k`%~X8K~@yYzH)p?iG%;QqA-m+i;$`b0K(VszvPLX{=Vm(vHhdE5H~Xi z?~YN5hM*4lh6BM=l&h$iTejo)PmI$s?ICX`5`L&Xik42>U5sI)i-p*S1#)X@OMSK` z+s}PvpM{mQ=OnDio)jKhkwsL}+4E8IdrBara8jMGkXVNmVHnW4?R(ke=nuL)LX4_Sa zs)BF1B_mfU3m2JG^M|lWYkB#EJ~OJ`!iFkv4;Ka7Gplmi9Eof8$$svyHno(e0*e9( zQKWJ!8ofu+0JIs}ek95$+stUZb<{R$0G*p~EceJ!s#ct7F0FKYt79yyyF(%|BUM;! z7N6+mrZ6Tsc^F3)7o!lc9;V}~9ZgNolm8a@F%Ak2&ZCxn?aquu>X;U`($;*jh2ox} zZ$Ra^@@J+Y=cXNr7{xG007!$+xk`^01)XC$%u$RO0NJh3IZveckOF&vf16le{qog1 zCrGh$?!x!#`}Sk>`h8GhhYyG$kGVj@ZAHudk!#4>$0by+O^$$D>5Jr~?d(3r3V@?? z{5Ov-7W|LuyGemZIXgv(LB{lV`J=Utf{_EUFZ;%`nrWfWG#5)$PndkHo)Gc>_P{8$?J%w4vw&{2a#y&+?>iU%X%^mZBF1H~2X*)bP67iAgax?e zTAnEcO%_~vbc9ie^~z$)M;42_dHq^fUc7;KKkfTi@0>E#vxZd5Qy+ivJedV=P2=+}uD5K7 z8bD+-8EIYyLIy>;9yEq*PNwShSDS-4R$5$89w%j?#EEZ0Mss5Wsc&7hp8i9?v}Je!X|^R-O)#AtLg zlsJai1xAs9!cS4)*$+r$41)m#ao;wYOrO_6?j?m?O^1|ef|JotI>OCXgb_DdrG~T% zwwIpJvkQ2dw`GnN8!+V;FdjG7mRuF-GU`Tb^jZriL&KGC4_P`Bwp(vyWta;rhnh7_ zJNc(caEVFgSDKyvPNfi|aG`Ui@q|1{0D~UEyR)=kS&9xG2XFgv)`NEaf^Q#z-OEK! zApEr!9*6W+tQ?F;efi%1qvF(}Edgu9w7 zI+ezuyOEOa9Ln$VzVG*wKg_xJ+_TT#Yp=al!+?#(PKH96#umc#?p5cxZ1Bk7WM~A$DJme{KK`fkA2N;9SV&1Utq<%0&EW?L2USbT(aCqYk`pP= zdnk9G2hP00IRmOIDe7EmRGU>fRsqQwfwQU%mBaE2sd^6-2Q{nY*21bRpwtAv5OlhZlew#kk{pQ31ptH!*4E*OGUh zG1XT}9DgCYCX3p`-_n|T!V(X(KGCsWTx}wSa&I}?=Lyb>Yv&%(22JtMfJr5W)Spng zGK;4#Qu%$z=Z!jk-@n2iM@%=@Q!#QDgFmhP`VaUGg9_K9bwcPnu_t|;1|_fKrQfB& z>)mYuC+N`aj*ZqzJ2KtA(wotLtCZYa!oVzPo7VwB8XRbAylZwekOBc!li0)h8}(b? z@m7!hlFO&qK`s!KVOctIwy^f*Uj4@U6@{2IM3faxM9j*<4@TRs>gwy56d$yc-y0Rv z=tm~4tqt%NOz#&OeGhjqfXQf{pYNY<@T5IIFXjVN zDJJ#64>NDZy05u;-w&p{6Z`J|d7VIa)p<{bG-}{Rn!d~Zv-5>}XqXt#%pa~EU(DPd zIMoF3hLNn!0n;Gl+bmJ<&m9u4q}73oiS6U4DMNZKa)^)<6&UdcX=-u@Y^QHC!&sPR%k*)&fIJQ$ zXPBGkM*$SVPLJ?^XQuy1lr_^$nOskHzN99uzis#SjDrLnlLGE{G#GK5E#BbYTbR}4 zf-=n-gj=MSXseGaxB|gzTrK7=BjlMDjLog)-5V9(#JFAOG^Z-Lnnb#C+~RDJh$@ts}|I zT020p4vi2BJr1+>1APS@!CANFuUFdg=HA1mRKf(Zv)E@R&%HV4k_+b@Cv0V|0wL?n zJUH1#f}V;^K|QFPeW2$EuKAik?$%MG&EGeujHSOJD>toTiDLi6z2mVljCe2tD1UqNmgiP6nzZXa&4uuko>S zwlxQ=eJ&DTGHcu451IzXgxV7(-IIm?OKou@YNo(n9;V(#70`Z=B*99hjx2o`tKAl^$|gt1*9vFlIs5}%~N#fzI(Sm=W4u0 z^SS3lO)UQ36ywSBT;Q9GoU+Hs3E0!`xQshyPd}L|Qif2EItewN{JLK4zc>&E%!u=i z%D4o0x+x#7JD=%ysnG8pGUK6&dq64Lz70{MOOOMwh7rna@wn~8>MEjC>{PttVd_V$ z>X6H3kKLH(Zcf35YAVZby>?Tg&P3~1x_HGpL{ zq5^|`-#a6N&zeomzI6hEjH+&%JC0cBT1j63larn^~2u@EALnYA$Ck*{$ z`0FuGkr^oV>Du+`C~l5_;^`o%0aTL9{5(B3ASL(&ORO92lu44C_4;*GSh%wx-5a77 zIAH!qLP5HI{7|L(<6}P&AR40G@wiOsa?q2ml9sdY3#4f0V}ahaUOrLzzdEGl6X8nH zYzRHriSA_}b+C9Q8%oe0Acq4E@av}--|Fpby<5OKKdOhFY?0(Fiv-l6wH2BPJ#H6Whlb;s~by;0*uBaasQN2)TB2ctn``bke| z7p>s0ZdCaGd;YN)a}t2{Vs1!>&)Z<5YvEZy1=fM}?&`qmJmRvF^xYr# z;A2-{{yq4F(bU4r`M-WJ3E9CGT|M|k0YvX7^#*^K19uTy4+7Gy>Rf{0O+&{2E zw(sj}r=MdVIQ)Tp?g4j25~2#2QLBSo$>G~oE9iJ`nurcI*{+70KX*r)Z&e?n5F45R z$LL~67+AJ39Yj6EUfV67#mXJvk+);6Vd-MDd9^cQs}qE;NaXa3o>48zM3Uxa?Ygo0 zxxa4J>S9QfH;3=32RMAdgcP?5_JJgy1)5I11xEM*Fh&QFKW^)}n;D*%@|k`>&T4h* zr3AdtsBFSsP_9;rC6y{$36OhD*8Cw6M1wBR;242+R}dAmgO`<_EeoTgBjws90I*6% zV{JBVCTY>Sj1n$k{-3=F-J9vv8)1%izpuz}eD9T@x1FaI|F{cjB?rm@y@DtGi)@-S z6~N9$1!0}9RiII^(M)res9YLO9tvN-qXzW@tJ0{NwyVz?p`wVOE@z0Ugxk~MGx&Kd zLH7%oF*8cW+>99*Y@`Sr2*rlIx@82jd$@+92FfTX*k|3#boSU%6mEi|%74?n;S~uN zKF5;&Jx$iJPdkVYSdOGP<$JsaY~1WRY!LbC5Vf*d7YfLr>rP9AHK}bm0L@$OkeL)6 z&N$ZF@)|ZJj=A1Fl-L1Ytr&}amqx#>sWGN@cW@*Lw5c;yJdY@(6W`;6uH=wMh)21hOJzH^j}VWLZ$P=)%4 z;}?oh1lUul`@lqC^d!2brof*-qiyDak_(Mom4?&nxEH>9Xm zT+HTQ7+Ki}6al87@a%C`rXvHuSFs2VP~V3Q(*fRs6}-Zz;y(}WQMNP)kz{ZTbFHRa z1K+rfX|%gn;_=j}b^&^~Q9YdI)K7vty566RxykM~?E%@H+Nb8`#HHfu;GT1!Yo zpxw$bR6+fQ(qnY>n6w8!0@bx=H;5a0+cDaCd)+x|8gSVft2~^?vX``TG#!7(8Gx1iPKY5GqsCL40O z)bk+e4^gX?a3+WhhXD{i|6=an&ifyV1!UovP2 zw9Re5Q`S4Idm2;Do}UDYJHBa<2XJ+Mns2OVyLlj&{S9A<2ToWFRqZiPa+V zsEMcwc)LUjG{zZg>+yB!J z>I@{$iPHLwFM>3Zt#GWrzU#OVndFqiVbE)}ap}Da({)@;a#(h(KWTd=t*zTUvwnLM z^eKOz?(U6Z{P-y#yF!I0Xt%3Xu%R9>eNKi-aW-K%07AB3wQt=0O7frf3?!c|PB8Sv zZA1_QNC1icRci+ae(v((BG#8HPrK5c`wvn!Gp}&-E8A@or2epVJz-ydoO`nHerGa%(hplI7*Fm8?>gxbE~cqw}1 ziC##&t8bSPdwd7hNeoBtPUzzj`gZiorG6BYK4nC_^j%WrO+)h@q^U!;eVhtCuJ@v% z?&8j9*4nqdgY7dhYLhdG^hTSC@*K}->h>2hky+aG@9%Nev?iLw_gOJcLhwcjr3_}Z z>40e>oyQI~MTuBnq?devZ1D=d)d$$P7NIubIKynK$`l_>f?E;oU*zoSE@!l#$>HCV z0Lb*!dw5bUSE=Nw8Wt1FR#JNS%9_(xo|*M&6nMQ;CVAE zy@Ads{O4kRyx|02O3H1^-G<#~0t2eFmt4ZWx-w-+2wvJWqIKahY!mVOtP8(6m*zrZ zOG-YZC=g~0>lA$^WvBK?V#~K@87xxnNGR;=jMNhRe7xKQ@gQlYEuLgwWPJuXLnB*mW>y4VP_v2@}BKH z`0Gz*ZmiGM*_J1-kS$9qYZmO}`c66s^gR`V7_ajaNOE(m-MoU-3;wW#`eYJ>nGd9Z zIdm$i`D|-%{d8uiTS~abG8tb>tA~7$S|E!<1CxQ@4oh!i>X*#hbMgqOPP$ebhOyU> z2&Cs2M+qAjJ0!>2c7~`;^$igtQdqlmXU`wr3c|0h(Mz9wo7u}=ZCAGozv_6YzNS6t z$^@&h_|qwq-#kUgY}nycZ)vK6P46R%VdgKk)sS}Jc{J!%{2)}HtGfspy-vjI+Uy@S zIUo=Hw&lMc#DR{Yfsx4*+Mc-04ggCd#GSWJ07xuer6QWPl_PZRv81sO_k7y#`6w2X z?!Mf_!G6m>9mYQ)l>>53=3~u#5F6p^1-p*BrT?JWf-&33fh4y3O2YJ<4q>E(jz@2! zQOLld%(Rw=v847iQ!j_C=;}n$&Z>RAzmvwC8%1q8`1)XZxZC?sN|zq4G~7`v`8`ak zt9FND(-}Dhd1{bs(v6wrB^(wx8A27?SDOBYja`A17l?vL#%#f>8cyG+&`)rT=NQ9* z)WtdvC`FI}`{BL|CC(;hMdCB)t*kmB;8%kop&rZ>miGYtyBY^1Rsc|cX|rGcI@asW zCpH9~6PDzx9Ao&}9g_78KYTXP0}xD?2@A)^hzYaCkD%s0FCG9aZA2*(8>rBkHo1zD zd4XaZ((p}dzs~5oC6PoLRs$N(UUmzULQDq<#kTxdoPEgt^6kqx2(=SbUN2MHabb{P zt=_+9!dU#z>$uUHj7EV?QE8YcodZ^F(0?QI=T5wzkC(2;GtkRvaVQws*!eCM_XZp1 zqQ>D4_Gg*s&Gb@&CKGh#leRCiu|KmZ(qu5mhl$J0S?@Dd)m`aj;J=d0fOg;3 zI{@~ltp1JA0v7yB8P@XMK!+pH=sEDP7uTE4^8N8&pY=6uB`7hFq*!G@cTnJ~X3B@pD_LR8ZHfKY zl!KB-l2lg%kf&*N$!HR0K<`?@KX-G|rG5{82_Y#c+uK*^eIYKV%C0P!`t$lZKxG&V z^Hk=VrT!GH)K!aK_@&pgTK72vwc>=~Ua)`RwK$9UD(8P%R;2og)&9Z|#t^EW2JDDi z%tX_g5Ib9l9SdNb%O>gJg{YPLTn)6>&im?hePyKHs8@{>#1vA|*%@MA5xN-TPL4r# z?oA+TGr9wb3JZM8B=c?}?9fq{KRb3g3;)R6-Lbkt4QF-Oz}=h#N1}-%cHTO?w#2-R zIQ|&bq+hUJ>%Y`bns0DT5rQoC!G{a!lv9xwq#WogNwtx@^L3!)0AA%1gglcB+w(WH zeXVF5_*k!6Ja357G4M3tQ|VdRh2xGjHhJ-%I|5|6*=1rgDVz!zt48S1C7HC#hlYsl zz=o*e0|RQ5w4s5ggRKnj@s;f&RZZ6hw@uf2b>s7-u!adC2e*n%3&h5U_14uKtCeLe zBF*GtmoMIZj56E_$j}HQvNP z#QHx=_5&S*0+4r??VCn+S?I{WR{4C?wX?kr_^hNIU?UbtP1EV?5tjS#B{C6%38qjW z8I*e6sqW$bP@;+90V)xC|6lCu4UrI_%`p_99+e4S7g}^PGJuXbJ9vNS`|pmV5x-|!h0UzRP1 zAwH?I-RzyK^k>21QTx6Gm;y%&^{M{Xj?#&e8Or&sb3}GQtYaXg#z098Hto^>T&5() z6u>F(wMa+$N%|b2t>N2+H_)e64s3EWYhYmU9GS$pVo_(-0SWe3L#C=*zdPS?t#B1r{~&+`leHtsuUBef?z|upn3C+ODls-mjpCN-ngm>B zs7Oaal?RiU%6?_4_ZDrfO|LPMw${hrTP(5I3Q6^h4(!V|udHtse!SV!yh~5d?)GdI z+)eXFvWx7pR(J0m8y$vtg3P2HPa6QJYarD7eS$LZDcTB-7`{8*@4!8qCwMM`%&c`6 z0{WU3JyEY|WnwEV{w2D%xtx$Njv8C#8@=h6Fp`}-_e|(=P?r+JPaL(X1#;7OUQT4< zx_}=9aIq`?HeRU>_aMm|z$`239r!>w7)Ho}4iDw$B?JB)39wdFbcrS|k^cNQ+X5~Z zY#%w|)XQeZcz7mo56?~vLHJCdKx51_otNwr!n@_*F;^qUMf}U4MLw6sl6t)enKC27 z#Lh-)jYXJ$4Jfoj0vhJjw|R_)C;QCue^*TDuC)(hk5&Eg?}Rz%WWt>663vZnf!w55 z&0oD{iv|3LWl{Ieh~#0i7JH_ebn{4LalSDy#iC59#wdn=Yf-RW8lkqTC;~Wrr1e>wZPe!u|YE6BuNun%?u_?4%g)ygCKoa`x<^1bIut znrA*h^6-Cq^L%JH&FA!wYfgZT7)P7i*V93LBR)X1eB2fc@Wa=BnT!~bY%q#?P#W^Z zufM=&l08)91L?7{UxO7X=R^JBO^j)$}hltVAJDE7@2=nhY-_wjU zXMcF#p~>9V#ww3YI5vO!{v$vrzl>$~32RpD;@xQJ^tAfl z2IbjLk=FSZS5Ok$d*1imzq(8LgYB{aWP(l}XtO@WhJPJ_*p>R-4*e=?$e?~uR0Y_# zj?bhjbtB`)ziF}$U3kl5dfa29rD7gpfk=XS`#6o_s|J3*N;G{Kpdbib-T>9)boc`8 zwd}LtA;79~>FC|lfe^Ft0a~A@K(>SHaQs4bhl*DU}9s#d$eIQfGYX4bWBX6MmQXh62kUKbNhhnyx-KuUyA?Ehl zVADQE`JK7Y^dkF%AwGQyTm=&YqquigWR($HGO1zsx%Yv^{;fG0rat=fj4C4NhV~yOFRunQ?hEI*?3q94wQH#Fi&s%gL?_bA01)*!29N#snepS<- z4a#eX3MRSQFoKYR0lf$)+-|_QNI^R+xvy&pB~Ipzwzd!ssbb+Xght~;y{SzvLZj5K z2N%T=0UT)S?u`GAmfHcbgAyGGr--T4p497Ale1Ybq}&{X2oihO3Pn3^yYcI@6^R{& zz?jFc8XtR!!_2KR*iGDx#|cZy6pX0eK5g0Y>#SDruenXO@PLT)W}3io;b@vr)M
  • Bj1^{|UM1A*C zr}s<$25fF2T`M;mC>8eV6+^u9fX3n$t)gf$bkJ1k8APN`*WbcZ#;{3VcyXLX4MrD2 zwUZ#ljE)}i%vcj61W!M4*@EV)>-6S?SxUw2aNd zyx|*7F$E)RHg3j3=PxaHbI<~9#w`vB0h|Q zqEf@TN`lM-rVObcW-Wf>1D|#FqdZmkp#}8&Cnu_VW;` zq7@GpVM+`P<2PmI+HsK3r#R`;k8Wm4Id2pZW2vb$GNf6>^PTMt#)6`Rd#qeNRRzj5g_~$nUl!eosFPk zOGs!*Pu*V<)fOfHZ%7`YqLMG5WkDCG=@}!ik}uG57`Z68|eO; z@4L&ASUX$2zZTtcGgv&);$XFXk4#qHqYg#k1) zRc>rDv$RRgfUCh2M;tE!VLe~#$z98aW%`Fc1yc54s0%1DlDpP{q67ope4+Dig#7un z*l4-WRqvM_9$pZ2;~Dbbv7_3DoqPISR;$4xeAnk2i@tD6#so@8n0eH3%xxzXUT}2A z&ji^1q+1}--m7S~MAe;(5@lhI9lH1jDk^LVqfth>9xXzk0!||IP>$0zdAf~H(bS#z z+x*s1fXl|!*8>cJF5KgyM8xY)=em0Cey=gI76}ZI;k?h-*M)AF~-O z(u|F<7#;c=NU~iEUC5tgARh9PC2aXcHH#Tc>XZ|y?Y>z#QW$IYJbUhw6Tk197#m9k zgXJfGA7)x$>fK#?`d*vI=K@3YajV8(adSgPWV+ zEsb=WLivhm6e%gSNicBldoT>23~(X=Is?(hRgy}lw!E1Z#k=U8e98zbZsv$POh>)R z{@b;n+jC}=RZF4MOW&XGF@@&r42ipV9t%G>Z$r^D;w z{E$j-4;{6t8I-C~nc>}0d`qWHs1JJ&7MKWrDRxpeYX|^fwQS~OezM=RG^h16|K|$U zNgz=-GMLb7iz$t6$~*Z zDveDh7dCd{N~?$6E0TBxBUpN>WA0x_?EV6K0PXSfTb`wwK#@!tKYcwW&B`ekBi#ea z<5z1*bYnbmMhw!X)G@S)P9VCHN^PY*8!c5eNzjA&$>kn`%Y?J8dk1 z!}?{Og+K%S=10$b;V|hUPN3pSCnj?L@ro1swEdF@%P%KGzLS%VLpo5lLX}Lh&hh<9 zt87MZJR@7O1g|o6+Ar|MjZHL=zBQucY{yubc4n{OB+|JE+xm)bwICdurEAv4lDYI} zlk@nTq-ZAo$S$Y>3KV{#IUF=G3g{X6iFHonV0KRm=Bo__*f~8xM4uXA~ z$pmL8kDIfC)a^`0f?$qVi*(hR{>0jLvT?2EcyOvj)=r%!DPMp)A9(>pHE#sd;w-L3 zreEpEDBylEE4$|bP{9&Asn8Rw)3v(x2HHqkh)M$iCfmm0hr)RSE!Q+Uuyn!7Svm_} zdR5&CEg!XHxWw-w4kz=s3R+?`8Bzvt65+NeC6?$|yB#{vb9oIlo)_Bc>yiAx>*NEK z5S1$pvAI~=!_Fl80K~oNH*th6tIz<34s^4|9Dev3;!c~i1*p9(_Q7o6qQp+ZN zC0t;l2C(Kv3pFYv)up63d5@p~dJxZAeyO9i>J5FfUHzwN1Yd;+ zp0U#Y4vAIWd?+Jtj)%I_(l;>n?0B^?TiL;n`XoKW82D{<)U##Nu*Pki$+6u*pt_jU zD|x+Y^z;Uu@x{f^ZR^SJf5z+7Vk*y;&YXQ^<|8%y#%=1Hs7!*r?G%B<+ioXGK=RVV z9{aiJR8E~yq|M~7Q(xw~qmn zm;A1-(U#kA7dyv{aJN($1YyyhU&y_{2>?O!;m89~(6)4irNovGOl1JE zS8$R(Qe(1s_jV^*Np&HQkzT5J5&+1*3j-S<$PdtSUWAEL$>p+9KQDoslc2$@do;M7 zG6%$I;d5Ca-NFDck%8!*n@#L#gEx|zqzA0uuN#Kj{&fiLux{!E%v=VrD-FGWFEW~% z{-W<=w9;@YfF=QalL997a@_*u(*-iGm>x*t_i(4{IA@*4q6kPc$MO1IchrHrhT)3h zl=*&!f~qK@FEMBahhPU$D$l4yAOY~2hhdT@>@7ZQj6qI;ok~yrRvJLg@Gr{K4w*>* z*a867XtuU+KqB*&eR#Hs-`KKcsRvhbqNLAkrhv~W0nEduEIvy>kgl?AfN-@1_Xay_ zQ7z9Da)EKQQwznlp%~^stXttEpWXVCI2o`DC=;BV{;+NNy|5NUq@WGZDf`QQq`4TS zwO%=H90&ciyx){v=?5l}K(mD!5Ow%WdKSp-VhOdB9jeKui_wM0Q-0hk*sEW&TRz^Y z{lctky0L!Hngo?fey&8mi)&}FRG)9EAFk}MGfZbY^Hyn?&`!X4bN=pV7Fi!}3bSI< z1hjM221?}V4{l_hx-Hj&f)*1&&%y?xmGDsUB#L)k%}e@r2U&_+LgBx$w?H!fZ!SJ6 zIT{-q?a-hV0bv*=*Pvbg$9&iM^KtP?2fdQdq^~9Pp_)BUyZONH`j_V4j_JMst>4*F z@U;^_yM2ejr0Z}Hyv4K{{74ARZu>-ev-!hL^p2Zyo9}U+!|nbI3?NK@H<9m4J`yJo zQqQq@CjOY_fps@V5kyo3zQFV9lQ7ntZ}R#YD8yH5?L--YvN7qdRe^KQggDEgB?2UU z_JE6ZlZ!bP5Gc)&TJoo`d|{<8wYRYQN5|@YsT?M=rsbkpM%)8)iGniw$jnzZo+e>K zM!Rz0xgySaXZ;@{#T{a{CRj>pg!;qDi_r=jZ zr4H0to!}AO+yEHTBK_sj{P5pPhk>Fucp=U^j(U7UNX3mT0q+;Hq2U(koxW!Rf5}95 z1H@C{{LWUs^F+qZ)fUC6n@aeD!^Mk>QqINYCQRWK_J<&OO4(J4FzO&GEwYGP|M_-n z3jc;mYCBBkwDk0OxoE|y8xYs@wM?O`_wU98L_%Ga58Knc4y7z0XjH&72MgI~S*OO8 z=;Hi2MF^f|uynxI1(ifA+aN&fqciDjnDXfo6L|?-1B}?U4QK?a5vH@`t}Q4_S3tl^8+D=`Sr1XILy7DL`pG)`EE{3!@oW!dDQ2|sLcSj9z`kXs-s z><)C)UsMgImJ~F%DC1J85U*M(T5(*v`%i;Th_+oeiteeLSF^ zeIL}8??4lF?DsB-V=dCmo~yxmBA1us_d@LOEUD=?Ze1r=Yxpm#8tIuCl7Wni5*$b4 z-U&h_W$Ac(v~D#T^ylRL#q(|_?Rfo{%sP8|&`7euK_-efmwJXzDOAkYjGT?J8g2qN zJDa~TLnCQwg%NQE?SlY4{Rb9(fT>3>aM$kh4~>rG58wlS;Jzlaztf6`-zqk6JbEHy z6qgnRS8M#r`LU_dLzyf}k{dv7yQsi?%uMy}$8Hzg78Jnt1sGKtFM2spdy!L?=KMxX z8aB=o7X|`KuJowZfTzpfChV!l+TP3Pztk7g75FNK)-~NxxX)3}MmvZZQ8J#a`or^q>}ak9_DdofFedMr0>_omPLwBI-ba|9t3Kbr&B>qLQ=h+wG)`&ox3K09qRFm+k zS^1Pz%aoL^byCCc4+~aIxp^E;fGLQ&I|+u8L&gHNx5QofB$+HgAvH=1voq^|t`bYq z2v#y?G&ck+Z4x&=>NCMe$#$e?wQRPdjmUB>oIC2QgcGevm&abCXfF>=71Kcyn?TN{ zyCXGZ%tlxC=>PpEPF0W~`S79vLSnPHAnwOS6sHrTP&{;hpC$M5rMPV8aeKnwLm9l( zldlmf6Ac5h6dg5;0Z*+vi3BygV8(1<|s}WZppo!3dVU7onU+69nsbKs`>2z>kAT7H(0=<42U3 z>FcmD0$mj4SN)gGT$<}=Q{=q{$-1M^WY*2}oU9Uq3iq`$)MQQf{~3S`A8V)d*favB zu4~ya+eHSV$)}I%kxLr2^!#%y%0!1H@eT=H4MDk-QCbjH_Te2D%KgYNvFb7hTb8Lk zPXl#~*zLQY79NM~QV$EvrpDSeg&q(VbIVMb%0uEO4kQ;)vi=9w-ud_9vz+mcy&QGf zWaiYaJn2O-PKhGuZ~3d@mTrk&bNl@8GQ?&QS^F-L01!sM&6R{yRVW!}`~gmq)?1vT zx%$h0ACEgWw#xVK<2zNe{T%#gF~XpqXq0QrWX07FoYeI$8QG&9jF$;LUtH$@S@5h0 zb^4F+Et5u(A|&5?0^y{o`taa7lJ2JHmW)ofb{Qa?GStlNzO52C+87|Z;B*?$3@!YL zODL7U&ZI%mYkx~909`itm+Wr*j>POGu}n<_D-VwD9$D2?y?IkP;eO=h+yXUDoDPo` zZoTa(`$AJtsPL$6`-)oCirmY?SdV2Rq5EFf%A6GwkbaAlS4&oJ!h2tN*kH%aZ@IMV zUJB~>Rl#Ka(UW5z7h!(>(PTT!b~dK+CMw>F|DOxsj&=w3*6I8^dZ0}nUOr<_R-v_d zm!EPZ${TlhjODn^fII6trOEQGv9!poCNBVbJxAe(7b*D3hlVFZ**AzuGRZQN3rEtN zZaO3X-Ll%Wd@u&)lj60RHa#a!`*-8| z+vKpeN7Ykim{YLB)#*l6LrUpLOPCkACIMw#M?{Kw1_j~Se~!7IIrLSM0?M%Jf||!EsoE8J+2gVtCuFpW+^Cn%2PN@Rw)kjz^1@27jrb$vQF}xsGJ6Y>J80((0A= zv}3>XBi=3QO)exx>hInyZarf)|^&Z=Opom{Vlcxb!z*7+0_YL2b4*jTh@p#e9zJas>U2dp!# zSDbI(UY4<4F|QOo_Ex6fD{6)*XeqnUqRgPowmSl6;d@ZKjI4}ynU=LsgP)%tm~*U@ zl>1{DB+nGSUs4!yx`~98t9|Xzl~OO_gjz4c{*I7MO(41JJdUu3$(UHNB}k)-_%-l~ zj(NoM_!YX!YqBFd_!aDFU@fYFDjSQTP@Rkd{(!X+955wGt_dzIPmZaU z=+gY?(i)qhOIpGzy?T?1SzHH~8Mf5l)}-o1IUyAt1yvmdg}~d;7}5Dvqy2l4rKN#f zh_x<*$0jX=Nk!oUYJMA4!tqPYkPkt4Ea;N+u(FPvBA9l~*KKi>$1nCcrjn^GGA#1u z8&5w#QEvNStGyq|T0Z?Yy2~oft|5qH(A!luehGX?dieX9JUiHG9@a&rR+Uj%T`_Av zcwyaKl#^4tWYjUe#)S20*>`lOX~pY$rO6VtR&Su9v$RP6x%Ds^n}ZA_-UcUyr?B)} zmXob*T|r_^`JOUIAcWgM$ggq#4{?7jNU^z2`eQIezc;`HnT7a9`5&IoIxs`?!ki3E zS+c?IH&;S;TSbo*{yZgj%1nh;J65_;Oe25bAg1N*!kdoPFyx1Uj}v0{n! z0GIN71R&?S;PC8+!hKQ~mB!@tlm*by2yYNqGTgjKp(eX!*F331krcL95WxRTfZ{ zqfj-Om66RJqg#@Sp1h8B4c;l5U0fK;x6+TYG;}*Cih8L0B?{8#RBYwQs*-lUopSUc zqo}a8tt|IjD5E9aUF?uFCAzP@Lx6EoV_sasV)mGc(~sz%p{TCBRB2EdJAc?z)*2k) z?&h2%`&`4TC0s>b?l3K<`L>VjER+eyrt0|EE-K}$q4;s;Xrs+0#hB1Y(dIUPOdxdX z7S9&+PW6$4mEWoOtpfTdA3?oNS1Iq6yYEMUsvl3LGAKjL@a0i!DU2;cs0yLGm!soM zGHvM)ae321U1h*mSz}PB{Z}fQP*Hh^=%Z6U`MDX<` zQN7t!-qn&d{K`OBxBZ1|TuJG;f_AEban5#W)sk0R{DfW&+oTqCuBNG~eEU{XG}1_y zLI>~JXGXxtplU&1JfSidBUCNIPA;O1GpUVAryI9Ee`0EHJc2jYm#nHjw9t-$2h$0W zV3}SEl7w4-`|3Vr=mJ*rnl^Ogs@#Z*chwyF0;}tX8RFIW(D_Zmz83 z6TPV)Sx#y0bK9#N#?Je!z=uI9o(=RP5kG`?gc{OqM>kLE2@vnnPr{ zL3@x^MPy%Hkd;!Zf-%piZa3DZ?;w6mWuYo>!OFvJx^rHpOUaitryu=O^?e*idK~03 z`O)ERHn>-IgZHEc4Q36u2;X^|iCPVHfY6lG5}1>A@OO9yUt#e9Y9hZ&cCd-?tVz&q z){>jKBRq4X$jk^*rJee($E*Kf?u)}BY(2ujA*9F(1a*)X@ii3jRSXq@_t}4DiBqHX zRHfxHwT%1V$&ql}Th8jJz3J^}`l4UMu1AA84Ng3y&(Z|LgjQLM=#1B=c!LCB^S3&b zrJ1q><(F&LK(u-zX1GAf9wv2wNBds{7|d0&57CD&9{b7_Td23PWtA$_m&oc=j<@5A zmbV@UOR?%!B_BunZ6Qp)X{hQ;rk2a}?~%cI!C+YBVZ~JD*+emcjltg{?U+%{k~vfJ zI{!m5ip$FhV&^mC%GO5{-A>~|cP-jX^rNOEFe+I@qB8-4*S*Kh$nc>!#O5Lu{4uZc z^GfaQZ{N#QEHXA?E3!ckpQoH;JYkzLbGG)bsx^7Qi|k~QCrI8&$1prVB|LzgdDCc! zb(>%58vohnLsj!7=n@c4LO7Gsy`H7-{{?sQl`_F1>_5*ydFs5TCS9hJx5Ll6Xj*5xMoxju3azt!bQGzzi0fnFaUvlb&+vSE zF%Ug{yE5N7X}e>46!M}REHb?pcO_Ws(H*)!m%Up^C}EIqSN^$8=k7-nD*>5|tYQ6u z6zt!^U=6Dxv~|KG(m^9{eptXxpUF_9IOH$(mHl{@_@N*~t+?M{ z@-qhltUc1a$8lvFFChQ&vuELO(aTfYiNGS#u-#`N)~PvixBlQ)bG?>@DZmvWna)PaiK^JB#tK( zvUM#|+4=b3mwlhZH^?~=r!UUb4W8rx4>AS(n4h}jTPb8NR$W>Y?v7T60NzJ4Q~LVw-X#tW z?*6F(?ehHu@-CL5A*#*p>+fdht)BuAN3~h#g#3L?QU1ddN*Un;O@g)AHmw&MLa1yn zmmR^GnB8g-=H;EXWt~%n%iEU&STs1=fmPMu`k>0P{PI!*Zril{K^ex_BB5>^-U61bNc>79?@nYSTJPqpV7w#W-J6=*wi#fMw zrrL|_mRQmir?RBJ=gAzt2)F#!N(+B)ExJGAGOq>MK3SP^xG#AXe)zoVGQgE<0YX}G z>mQxLS7EBSJvvs99>_vylpc{(9}t)Ej)D|+e1}=Uv}^rNnu6z!_l;nqWVXXSkkI-m z$nUVGVY*Qm+BgW{pnv-LYQ*yZ&RnWc1*bwMjL0XDpG$qwST^fcaQoA4Ua;>*82;O8}%)SX{Hb>wwWT*(q@#q=;?H#`n4ZLG;C zwV%{2UeT&wD_c3ycHq^9+?MkM0+T0X!yoEPN-t@7kS2LT$9^Axt0qT7{cWV|<$z_y z=G|wdNiA~eB=doWL!HvNBZ1kAd12}?(l-)jT&{0Fo;MlKjz50v4{&t=ncW!_)?GX6 zJX@&&U0xIL%o%C~H|Na<(gT4AczcBBP~b{sI-9;ojw8R6(NyM;fcg01a@^ag<5KkhAkVhx4;Msg(K9RRvr&XtX`Inru z-Fd>c2H{89}Meo#Lh6 zQqk4*>BxYmb}f zP72Dd&CYC-D{?0>-Nj`_z;CsCIzpyg87F?42O!vLK*}{7=(3sD`In2Rx7-Apks-He zw>)5tah}=Locks4mY_-nmAeixWaeO=B@HnsH-BT^%r4U}x7zcgj@L`clY+wGz7|NY zs=>;IgkERRsy2tRukJi!x)YU;wKkWj;MQuUMJ_GKEm_4(oxLS!_c0l5-f?&xy0k{q z`~YL)PTvC&0x$WT<*)niZKIhR^S$j?)@COjc+!dG^;X2Dg}bcLv;r^?<00;W-XT7R zB#-HSpD=Lx>hjkezU>X-Cf9=X+q-7Sdi;#9S3Da5N%AG%bFlwofVBA>rsX`+z1d^7 z#-SohwFP!TWOPaBcu7F6Z>M?ZXg>%3q4qUS!7ALT_3hF}Au^u9?e9F!<&3Oqh>P>& z(|{Plu)*4}1EfVpgd<|1z+^IeO_WtLC2+@I{M+=~iUoe1*}j^V2v!^%-EuNz!!lp- zv6Z^98as>ovsS$t$Hkf3`hAc7s>a=hOi1FfFIV642tU+XABKkZ^75=Oe&RsDJ!yiS zf`Uh|Gen7>P&Ej8#KFE1?-`5fMPS8;qlwI_A`P@2&YiE8{&B|xk%`BI7nf|8X;f9L zIF=hY6czesTc>+Nw}Y;-YS}cyjo{iN#R;R#+k$O<;?Gb8#eUYF;hK|_ulbfwX98I~ zW|v%pHN)yxCq;O2fcvX1y&ychq9cc8Js^F|SkODyatgyNkc*&OJ+~rDa$2l)YSmU$ zb6qls%?an@HdJz^>t~}S9c1E{2NWg$v2IhOo;REcDEcmHKz=2r!W)y!ZE}||yS~@k zFzfg;YoGlxtN%R(&d7mxS~veLF7PsJ`_L{zpM$6R=lmeQUuQS6^QIl%vG%Hpl59No z(L}`mU%SWsThrpeYXiZ9w&NbM`$+k&j(zd>A++H%(fZI-$s2{V-3)IR4 zP15FVnEvK?h9t$v3EB|x}34wLOn4|UZ39o?C{PZ!w(3Ch2f6_cAe zDMpAUb&5IHL-y}^`d*Pgu0wf}OYE3(-GLh<`7*FK#7&^FUM2bDB?{H|bX@z@>#e(v zJ!Mn#6s6o3=HK{1TkC=i>Xj|TWeeB_4(P1IYV|gG_S|ZdxYi03`^c6w zS?jDDXzzI(zM}4 zu}$Yv(u}Xvt6=@-T7f+|<;k}~-OYK?S7=%(nbX{OK;dCLHl?|)+MWsNlwG}9Yi_w; zFa$$Ju$$q9sTH$`>p+U2|JUAk05#RE?V_lt2>5+c1VK=ms1&7138;L6ND~l{5{fh- z6e*!YY=Bb22PjBK1BtXCU4j%vh)6FXK!AvV5JEx;p#+lL&AI=XIdkruZ|?c$&Odkl z`I&)X_MWx&+G{=QEzkR|cMm9U)Z@jAg>+X=T9J8h&DZPn*Y{}8ZmafN*8KL3#<^p@ z{%L*hdcJrmiOYNY$tQ_>!`ySbE?W_*lJ-W~mtQ3|{WR4!98Hi-qQ<(s=OK?m=%rTs zuCg~S`<;?S%l(12w#Od*c?b>KFPY&4+g1nH>d!4aZ> zio_pw)sGa^@NbQIKd&n7y^GU-Uj=Bib{ia^-cvtGyb{-6Z@=$&vbZ3f(s$ltfy+{} zdEszs_KnFa(dDBXcKk+-Djb>_a`>vWr#QGAzW&}L6M@_!rxIUj$;5hJNLbi?KApW6 zqrRepKVxaZWxVTc%{`l}MI2CVOSnSA+OuA@Kj z={OTh+OK|mxkinZ@R{MU#W%ouRo%Pi4+E-I=SJz;>)|o)&`&y#HGIBn;6LTV<0REx zd+$-YT~s*U;xqK#H;s$);Md&Ybbc`X^*XR{fG>u77*VR4EmEeYV(tH(PtUNcGv1m* zElDiqX@jzMPTaV+9tjgN)QGr$w-5R%Xo?z<$Z_E0m?qMz^xnnNyO-Z9Ch^C0Jz&@& z-g;NOovHF3iv1cehv}O5Je`ZMoqu{+ne=Gjgd`6xD*0Y?@<=rB506c=o1`IsL&&L6 z>P0`CA$jc3P<}QUZ8NrdUX|Yv>O|Ixv#u_?qksH_Kv4ZU8nH`lF<^}y5vylggvUtW zt8foh=nZB5qc0))_bvdD*c(_bQ>;Ee)L)-;9IPLzM8b%(kCA+W%S(;W7;_@4YX{@I z!z>*oM|4g%k@Ebn-C?gYY)Tz2`V8J)**5V zF9O-d{KVu04+^Nu6?BuFh%6CG(}Kl(uA2)>+Ges43sD8bcB8LGR*w7xXMR)affEV5 zuJx{68LDe)hUxHfsJN&)Rlv+VzvE5V&b5rawoIwlkr5-qgdDhqZ2wewd;FkzutvU$ zpJ|k-8`&l~Sj@ZX2S9KX*#e5>>}AOGb=zn2pDtULj;7-sD#k~aR1pzhX-x+|ycLU_ z?UW(L58(^lvjX#^Hr&r>CV27aKIS;8eE{*aOC`Nz%oJ&#u#?O9UhHP401g`2h)T8| z5{q?t6)fa?zX6~w()mLNr>jeEW@oZ?zc>y z5Lu5XT?Bwa`DF0fWK;rZM^G8DH^!gt=n4-)mjq7x#u6`I-w+gS?5mHyRp3o64AUdu&zMgR{9F7mQJ!S}k`U zCRpfY7aegLGSCwKE&1m)+p=HRmR97v3sHr_&CKL|3GFl@2U;JHi~zFCV^9 zgcL8K#)?1~rD}RsB2T<~i{b;?Q|u0x*8G+^8VOVDRaMv%7OSW^-;vOMdme}pO#6mX zS{~F{qoW+=r(@*ps_*Zf-8Q}zS3Kxloho5(X|wfZBUI*XzY0Mz8a>rqHg+`)nh3bl zDtuB9;of7|8hg8M8r3!A1Z)bpud~2$5qCX6u9Z^&MZ-r%+OG_j)}7gC zYGvx>PazI-FLW6h#JQb5zIWY3@$Shwa%ZedIZ`~B?g@7-AsHn6`~W(C8oT~%6L~<` zu(3cQX(HOGcq0HVP$xKttsvKy-vu$5BDorRDcakQW0-_i@0}^W?+^wzHJ<%mCSX%FFJaHR)g-UDFJ19EP2QD0SNS{B_X;KXJ4xBi)&t#YUKj3YExfrn zAG9R*>z;xPn{sIZXY=TFKe9CWetnvPmSeL_Wk!p~5VWBShS&_!XbvF2P*W8rqP(iS z2-UBGf&#^wRKMHwEX-XCfiNt_?|V0z=eamcwNUGJT(9qI=+?xldn z^X0XoPlfszp?$ldmtQ;BdrVtM89|BW$}g<8TyabZ`JpqV!cz33IWAJVFYL+3pIulg zPbSa}r|tIg(JR%y_S}LBL)=b`-z)5@ZkqFZkLGIF)rJ{DqThODRUCMGp{yq3$h*F& z+&mYwRleJ#O0eKbyWc!+zD&8VflYPIsz|NhTyzg4fbqDARLqwP7R}QmoGIl4oil@@ z;WmEn7yGbk5A!^``}Gy2clHVR^g#7-$`u)v{KeB3$SssEM%70xACvNc%iUMqk_kH} zQHXcS9(^Nz-5Flu>1HhHDei*!{Fl5I;)JhR47vMP}q#_ zmU~~;eX`2!rPJ=4D>Djjd?@*Y({D!1BlK+n$ww)1B?S5!X~^z4EijsI0-U(X=-TV` z`r~M6dy94&Zetj4p!_h}E5UvqC}XG^rR6k6n(T2AL0%qyMUiR_2V>36N(!SCO1u`Y z@j`Z2=c3S6+^4q}jv{V5iX630&%mnR5Ul&4uS4@j8<-d1 zR=&?gN@TT?A&!Mr5rtKlN{sl$B#e>!9~Gnq>eGR7w<@nJ(hJM-Yj-BV&?9lAjP*CA z83eb56yTtMsF~xg{Om_Ky7}jwsqk)-z>51c&;EhDP~G=f>x#k2#vppNO^bz5hP-9V z{d@fS6!I11l8m7L=Gb$>?`Gg}zb~zteGduso%#k)HYk)VZsSyznwmPwONcsGsaFv6 zF@zZDPv6*($@7+R`iB3lNS5#S94#V0U)%FKcmTG_rx)erCfRCeb3$3{VBdnz>*E@9 z{`DofYfJL;s(1S!g}Ih;o|jIvyWP`{rmAOm!Jchs=*HYLi(n*qyOYIDB<1>F^*8Q& zb#nl+Wtoa^`S$52Cb9qxPLS>}FPAtmUo0L+_qcj>EL*{}Dc#L72_UWN}5-POsxCC-teG;hBQXg~B`b(U*t_YPEC z`lG{guOes6t7_-&o805f>#y(JIx|{niLkbu?uB&bj$h2^o+=KN883V%M@*YFgsDv3 zJsm2w@^N;}IKM1alwe_YW&8;t$8>g6F#WN58Q|-_`Xq7pqAJ0^4h_B$`!P01Lq;okcTq{|aa3a%1= zZdmwII*an4GQ+E@y2o1RWl>L}bi1+cHDjYV_bw&lSeM*a701rwnkAV2?*TWWoqOa& zS~3rhZk8i&`$x!JdEJ3xa*ZZ+f=ATsch*li{Q=}z>D-GKLiT!;fDgRZx==K6-m1cB z3B~UKpWli~B4w-PX%CpFR@Y0vRhs@o2aY-`-GhWmhv%a%7&8_ze(2eiWYp2%^!QI* zAs0Nalz|oAHwPf&TLZF*nm#Tqzk;GB{BQqZd8$K#mA|YEp z18`PJo4zTsSuB%&|JpCF->yMKQFmJM8ooZfh3c!8_2T|qu4RDbNz|%D;5Oy`aQCU2 zPLtHlH2N#Gp1JUu`x!o$;!}WP1@ZjNIO}JO-n;JLaJNlbX zl}MLFpRe2ZcU?CZh5D*o)hx|DV}>A2qT5g#P_Jym1u;Sz`C7%&ft^p6v_O3xyeByh z1Rwt5BjoqyNUr`cgjq?FE;jsfff9JqQ&M4R;&m29rgli;Pb2&(8JEF3sPuHcw?1>{ z5{e>D0-mYW)=kxCbFDWn95yfV9?pDQwCOy>S8QEY72?}`!7uZ}iy?5b%jr;`i!VDf z8zJh*sjo-D+PK>F=iOg(wqK0S4fk4tu^z}MwL{py=K?&R?TQCAaXMpbmyl224W)sQ zSw}joo$ul8v<XK+& z>fVNt{+~c4zoR%G#&N_4u~kijmHar!CNe@_I>oXniwL*i0o0&{5p&$n)yY?!NYr7*fBsS#E(7(%DJ8JVD~ckBV*P-Q&EuP(Yj;-ayKn4uhUkkNB^=Wmw)wd zKmoDgL0LpuL3x&+N>`s`Nt0k!YPnNdYVvJc!}m%&wi#1*gu3q40$x`!iL_;EaRvXfVta^K}N1^Qw<9w5=YvV`^E?w71{4|N9f4_+Pi6S5fM zHH-Ulq2$VGWFFtUYqpV#@m>7Y?sivAB=dk;l`1);#YC6vNT|Xs^y8BqSTmOPjkbZTBqI~}=qX?>INaWYa`ii;4lh-*8t={Vj z5%$zlsTus@Q(>caXKW+wcNKFxUbpH&MAy4NCaW4<_6jGqQ`1A_=I4lAyuX(9RCiWi zjT}#byN4#<6uzTb=_c)8eL!H?_+~LKU`KYI=PJ_@aV=wEx69NQ(R^Nk@Nrn9E<1UQ z5iWi?_efsyt%-w>sGL$L?*I@F~}ML5FV3 zRgcEl1?oiJCm#HBnCW7-{&w~H9k_27R7@Zcy}skdY0zi*y|z{nTdM$oK4jqT82T8V zD)@VG(@lHCGZK2Bk2L#UHCD7(GTxl57x19y3Np!O)-y+4C>ELfCAw5M9`(_rQ>Aa> zY-8fFCuZC2BWKN3Pe5OLbTt9p``Fx))0iZ)6G_oSw_!dCNsOxzq`(A{kF0y+TZgnqIj-x+AJfoOhYpCP^Rqr$&;jS0?uR}_@Mwi{ie5%#FZTY5rY{C~hc{vVU=OCD0 z@4;lb)luGkX#OlkNJ^vJrsnFKj-HW0&Ay*{h5(-ocUT@XzCSsaBXJ|J=84~zH8@wB zQWD%cM8D};pg~nYw~G543g*x8E8X5(gT1W0!#ZWk8+H1e;pH5_Oy!-II^r_oZJ%+d ztu|xkqlqkK^>hO=Yj#8P3p^yq_Q3qw4fh9+dL9(lYhDkD!ycQmsc-*LFMTd-?_u8H z;1wBid`_(aM2JgVe6G4pJ?2oq%84v%wKTjVQMSDhaRh+l&x+_^L0&C`Q_qxq zDEicLuQw*Lo@}_LsplE%>b(BErfga6m-hT^`E#K-`FCxt#%d6Q)ka9ZNmyB z&yb`!>6yM)zJ!X|dfz%^kQVn7P5?7)*3V1fcQcXY9}$u-ulPycc(wVJr~Lyi4}tq# zQ68Ee+gc=Tzpw}#tM^rIS@2t+97DWEpwNR*ZLLZ`3aKW0{pf+GwD#s5=vA6%e!=6K zc2+`v3xipk`lC9pCO|Yac~YYuhx7fa!lPkoakiMId0C4z^1#l}M(~n+!O%GG2XaX8 zlnT-Z03C-9*GyGS$lD_859w*Y>3i+Ha0z__sQ@SawEplNSzhC1tmln0H=gJ;M7o%Y zoM?J#;dy`QsQ(nIiO_EH(Z}HZ8S%F2ZV}|5H#U>0odXwZ?ep7v@9g>6Z660=5r@8A zuy|uC;Q1w3*+}q9we#s)=42mz1IyX>L2i#6Dv8Im+_A~!CaR@sF2RoyQa}4hr4DNB zH|2PYI%oasAjdwoIXHk7;oty}3jEo>_wQZ=#K69J0rUoFc;H{)y*W7kGZ+77F#l=} z|6k0^-&Xnmmu33zI+#Z8|0MSRdF%XrBO13W#_ZZqBE|yjA{GNQcRwY5)T`HP#r$|6 z4^jzF>eGNNVZUufN3$ThLyrBCHJjQ$O&ELl7%AdbBjC#b$%qx$nb7l( z^NveCZd3dIr9jG8^z1zEIIsJR|6VIrYxfhktmy8z6!vdhU+ZOZyKDNPz2B&(_XWwA ztyt8L=~HmAz#lr3SN0{shZ;>v`pR(9lj%{CFlRI4i|ll_7^gGJHAsl#`U4^;V`)M+ zx0qY8$vQxk{9cj|znsPSA1#%0Ktb16qL}8Bzj1_k8z12OM={lA`b_n4o9TJD>r~)E zG^2YSPg;lgjeb`p*M%@YJe3$I7v{`XhFp&quPtz7ebIw%-`MR6$n|AK+kjzBtf(#= zW(U5zG2nVh)w%=->X!W3U)JC-G6enwX>AU{T~P$xG!U(Bz1%&4BsPXH|71mxR57b* z5GcDn1wzLpuSYp00(oTbc7ir~JeS{wwvryo=juk5!LXq*fi0%Hoo4P?NEZ23C~3-H z!{a;6@zJ0FV@#-}!n*=Jth1)mJWH=!WHheqGG>YB(ZjGtixl*I1l9(P!|(v5T`oab zleQ7l=eQPuavpcND6M$4DaATFy-bH_1S@RK3d5vw)p=0#d6JX7KYtpx!*pv?ny?mm zs~N7fLe?Bcy^oSj23ZQxEsCuO7R!jtaPmS<;D%8?!asjAb(E5a zzK{^yw*wn2aRNco#Z0BTl#1}5_I4QSD6^ql+h=J-xB7Lg5w2E-L%CU;n5|ML+S4Nd z@anfXPTxw^VHU5D?RBRytoBOK(qYDQrVi4fFK^R5W;>Bcer4I(V%6Gz)g+HrVF?{c zIhSP4*RDy^$-}t_Gf%NUy!%Rb_J%)$nP^^?b z4Ys0vaAc;u?fX_HgS=GWakLyK60zGFZ4GN$kCSJBj6$B1khS^4ZI=7U z<-M42UX1;goqu(&w?NCXU&mPy#Qwlphp+Camd%P`_7*7OA!ge}*(UyWt+ZvDLiW`? z3Z^>>wDp5YU&;iT8Hffx&XBjgHlyvrPXdYW4%J4=RN6L}SB8=0EaO^ZfjCPcb8E!0 zTd=GFHA1i1JsaU*(9CQX5w3WTa)_`vn|=)r{b|s0&1+lvL`kLR5+MM9Hd(J=r@)Ju zAJP04pSRs**k0hCtqGJ>hK{7hljaq*@9k3R$~3vc#Up}W!y|U%?ImFx`T6%bk1iMX zZBHxGn-bBBni>5~jE2zW8~)K0BiZsT;E9V*TOCRi_xe-nyeV;`Ykxx=Xf}RdG!W)i z>{|ow7hIzdPQhDudkx4;Y^!OLB3Na{lMjTk@Qhj!Vvrhz>fy<7D|)-r-VN~`7!V76 zqq(EoKY+M28Z1_DWuPpjnN5kHm@7Usarbz#{Y#6A>+fs2tINWP3t)%7d(SevGRXWA zow35+sXD%syOb=WDD%VXg`BhV8IZv6!v^_QC&g=2X2QFVmwa+VM@e>{9#Lf!wX92) zDrECYTb&|}@N0=N0Z87+(HKids;()U`h2icF?xv^LDX_;8kg8YTecJu_jcAttJ?V{ z%!F8bJtmISJzX#|G;ci??HUh)I5F3o3W&>gjrJ>_%>1KPQ1;}NK=g23$m+}NgH(!~ zS8(~o_CIx?>uZc3Fa2MUO`FGm<8A{!^8Xk((T@0L$nW^PP}iZ<=|XT`nUYOdLh z;?w^0peA$oS4tm6vw43Tvbj)Z5X9F5yHqqcEXD(37Z!BJfMr{~x;3R3?I0e_Ca4Ls zq(~K&(OJAYk5yFdMXYJubDAR6YMLf(9MgE14NIFXxXK` z1Av7z1_!kSR>VZk%umfwf>6enINXlMerjP6#ew%;Fsj7qrJ!@yuZruED4M_A4fYSt zcv2hU`xxJ4QO(c73Z|M+D(WYEBd|-p-7EOyhN)rb@)@V?(ANpEUhHH*1XL=ruK+bhs{>JSLe^k-xro$+~h_T%iTXKX3Ci9d(AS)cO+vZOHfz zi+(KhJ77M2kZj!kerBZck!z)U;=Z^d{3L5^w>8Tq>3}0}$(H#rR&JK&?wNu?SM@#X z%)Bjm`8VoJyU1DfhdzFDq-uyCRg<~Qxj8h$MQP}O&E`1KewUw!%YJO{-SsYJ4EfhnqyZM*7aIFBzccoANJWAv{@N5POBv=(88}A0Q9_8LK!Onf+wkqGT&8{ z&dVBNTYm0!#gmHPa=8&lY{ZcLQ*0= zTTh+suHMLSbz&5O)Wl;}a)2{L4U1Q2QIuy&x$B?UA9wnwSk{}0$Yqn^ksPGPony`m zUlp94xq`4$d?9%{8@9VXbSP-|F_o7;bei@<5X_?PiVt?!I8@GW=@bFKkDN$&x7=3rPt zl9O%&L5jYKgsgoD2cuAy7dvQCK)UfQ&E37k;P#48-E*+nfp7QmBrv#fcQx{;7J_mb^XYPoY!$%ZE5EK6E6a+ddjRtJu`Yu??hUGBWvC4SpDA zz84r~*7zRC7e2y>gc8p^9Rl|lqdw3eAivbO0n4CnGF#om?3;+fHwtv!KccsR-#*_D9 zVWk1Hc^*wZSL^Y9EWW^yyg4mUPH zSN9|RO6W-+JTTXF_1Zug^h_K9M)>yrS6_CO6<#&wl|b7tchlo1Vm(O#=O~{ItoPSb ziCV49#gG9J%~&gDc2(YBaxgG6x&=(Dyr?f{kOHjw;6wh-leH91KHU}^Y*s8(x0ZIO zEnv%N!L_=W8o7AI(RiPOf&Xla4q4G;rsQP$)1k@4uK_<|B8?+ji0rzi?Nx*6Eo-q4 zE7V~Y$X?{$CNZ)BHbD%V|5&Y|RSgQYpM*w4>Hd%pm{OZW?VGXrZt*FXAnRnJ)4K{U zk{GtCk2zZm#^y(^&PiKRKcOP|DXNOFX+b6$fLvH&A8b*%sXHfk7u#LGzRcAJ2Z8=W_!TvOO4xer7B}rp#|N(o;QiO=d&~)Y z%+owqd(CwXE|ZAqsyh|r4L~9QV|F>cR9ndoPV^&i7tqSl!`&;)>!Oj5DHe#<0da;TF($&HKEvppe+1nKc_Jiw_WOs+ty?pINpK-yLmUOOQ6~nhJTLI|{=*;N!M*V=z-0k2 z877{aT*?XT7Ta2)d9og%B9`~Di&t z4t%=xrO=-G%S^&C|2OMbXLoV=Yt2qRA+A_Pa(l#9yxDLlY?ELJbF5TX58vVYM5cpL z;@~QMY|HK`yViiP8rZA=eyY?J&VHkKt?=c%+Mcy1|F08t4Cy+ zF}?&n6Fe=hIGouEt&cOf1lHZ1G+i3cE$NVAGx`OGE)mi0@Udz!XW8kTgNJpV-Esis~?}B%?cuIs2I)qjM+qLH6gduw<1%bm|Qaa z2Vk2AB1!(Otj-YVJ^}UPSm>(xO8!98W`TSERLGz}>kd4y@ukbvg!9ehSBi@bLagYa zZUy`5yFng27vYi>w(2Tx=Zt=h*=RfIYSJuE-PA+9O}#>4{|tQ?oOZpzdHOP7{n`Lo z=K^J;UUVtMpDW?Jkd1UFwqY;)W+!Z?10TFtvpF?K)YZO<%xtCePerpO(^*l2d*j)F zV@Z#&OsRBKpV5`^l+$j@4`1-%2H>q1L|03XHRp5hAD1PG6)fY%LoZ6Z{Jm44jrVVbFHPV;lgFGzZAVh0C=QU;2aeb+u=8_iY(3 zKu{Ce>sVFW;Z)!qNu^}}eak}GYg=m`~#$Da|V<^i(siR`4@N_36G z!b?c0vTMT69^0eZ`)cGoHEqy6!u=QC$Ho}f*T>@ zsl+`|Y_?Wp9N<#iu8f@Lrf2aL6k4*GhbZ-KGlE1USg0TW(m%XTurEh?SP3}hJh$5- ziXBy;Ej%m$Wh^dcYTG!mHVhg4mea+zXbZIpT98NA8>Yhx;`H_F`p+8C8&jBMnRZ`U zLOp#_Zxg@fA7vHM7w&C zcS2+iVK?#{#0keMAnGSbTDo49lDWE`$mw0UtNP9^uf`+s@RrK>v$iFG?Qn{?=^edS z)Zn{m^ff(NgJU?1?aU*=q0MvvtXj>@se*@jI)IrAU8`*A6XVo2Q968r!%Q!9lIDyj zb#N~PqV}n$w!Y;QA*U%QBRpQTE$`qyeM&$moq*01@*z6`q|ow{;oE|4tT_VhVn^$7|LXk( zKb-He{hfm(i;ys6GI^4Ay=GO*|1I1*y`$BlcN#e`r`le}XgE#{Ht3}0CGgF`1d zLhjl)gqH0yC8P|km7GoYI~`A_=}4O;OIh*C2Uq&@j_yyU*1Pz#;1VL6ei6KrVqX_Q zIZ`pDR1PJ_1K^MNeyg`Y*^+Cy#yDQAwg6y%XbmO)SN?ZcAmn=a0U+4$KQ#2ein#o@ zo0-26+kd0`|F0rUt87Ars|Y}%bKGFs6WVVaQUo?X#}Obl#d(zDF@T*m0Q9G?b8wva zKQB82$W(gF@vmp<>v%h%Ozu(H4Lz?5SM*c4z_Af5~eU|>k?SFCkFIw$S`F};L zzZk+luKqs_<-e@eKLGHbhVak${Kwn>eye{1`#*N}7oh+5Tm406f3a2m^Q|BU(x18N Vcxl*tzAtZQkcXxLPgvElp`vSq;VFN4@G{IeiE$(i?f^G=zvccVT;r4q{ z_ui|!dRJFhSGCl#GyCu9?wRTNP0M~$SCz+nPx>AS2?D5QX-v$~oqQ&Th z4iEA6&Q-y{0|^No@jp7=E2PY9Vnic~t+a|X5>j1!;G;$o;xo0Cf~E=*l0O3y($_E~ zr27}d`#utq7dH~pfjJVAXgU%SkxQc4pd1pCJU~%aTHAN&Xw}Dfe)jq8nTO8 zj&{V?*SCVxyC$0(aRi&!szwXv!5x_P90fF1zs{ANg+Q*Jz+w99n zSeSwh{Qav}>(BryFD}}3?7Y+6Yl%m4WflO^*P(ZxzP|d3^csn}7YPZC8wm%&2nvGv zSExuI|DSarA!GbsKk+|z{D<;?8{>b|@&An8|G@MAhTeY{=6~VfKLq}(l>hHK{v$L( zVgDKYeei>xMZo`if8RH|Yh#9hcToScZsT&Xb&(|eQ^J*$PSFHIXBEaUcG>8^n z@b~(Q_mTZ11OygM`v2uSAs;t9`$)j*fyR~0(Ks9Jt%L5=%x^>MY1vq5@N;^!QLR!f zeB<#Lq&I}aq^*fjDV5ID2nf>fb2*~Xuw4l8W{DkUFj;z&QT91_pL`yt4)!d3#^K ze>My5k=ng`r}QQ3N;`F%y7%Sk=1s!CfACKG>Cx+DRicz+y;gBasb5hr;ZzG^<98O? zaM%x8Fmqv)rVL9VSUnC$Wfn&URin{hf=19IP+1!~=~Qzv%OX(jXYGq-^W3+4mQDY-)yC9qR$u+8qcH^DE>yU*vi;O4lIU@9>7w^k>;CCEgSKUU z_>vszhB2nkQ35*CT9C20U!>x?X-D}QNurtF(OetnsV;0Snr>`Uu8UeVk1 zj4AB($ZoPpn9Tbb3N%OszR8`xG(K@9NK0`U6Xo|fY2o={(IwVG5ir)2v)s~bI03r( z4$kPAPmoJ;qwwwax{95Waz!QsBsBmQX+^ z#>BjqHa!`bn)tJnG4JaSPy4FMTvs3W4qwYjb?&s}kPm07pf;~btr5q*$!$oF6NeJu zr%Yx)s>~PQF{))ueLVCc_F!j=4xP2!5^2say9$GX_V_NID_jCyXWN}{+C+cVJ1V(X z=yKpusOrsizkXx;o~GAs@n9lIeogAJB99m~D=uPe%`Ab3(09^a@E&--_f0D<|A+TU zC`&P!&ryfPucZD{U&raWuJ0|Pf5kZk1w<6JnzCVS^7RQ{GQGo5(=|n}Cl*_t4%_IM zE~*H%J~?RDV$ktJ7LPId(_=pjdyLJwkO-bkbujg~x91aI=n`cP$^w73?C9SpTWtO) zTI@65h(>ocX!DqnfOZQ9VGS)Xe>+p2u?%tKA$eEqLCCr90fS$5o4&vO$q9}OZ=O&P z%2FX~J~HU`|KtZ4B*5Qzng$?vyy^ftROx!)nQ8?2eYVP)HP$y4JwKlxmU^n6-VX`T zJaiO1#2#xAzk7N)0om+a2#}E(Cbd?(>u4JXUk=!|*ih6PaGc@HSfIb5(ZIn#b$f34 zTtfms>!WLPRkJs7D^KzdWY|{C<8r0tIz5{@ir@p)sYd(=mG=8ZSK|m3wQI<*sFH=x zlvU|op1fZCbn5H*9J~8?eS&uTldwzTcoVTr!3*q+xNo*M_CxvH)h88PR&fXk<`v&P ztsFL_!Y{IB-|tuH5jGUm{yf@w%r$8D=Ua(0v~J08>9W|^sOV^MNb2Kdmn&=iX$@V2 zOB*PTqTANdBXA=Bv{I_|5!{vIcb2Q(C3pLEx-V)nLfs zv}{d1P94ie9xq|=h#c}U>3!`mEbC^HTt=}9g9uj!9+E$HeC-RbFZ>W^4(662rjz|q z@}<7gw^K50`SARn01z&&1*X?HLq&#B2D^>L!*SXSi3mv(r$oc;P^^wT+q{n#cW)oF zRLSm&pusB*FHy7J%q4~o@-bact z2}vD(^qwoo4lUFKQAd$DewV#*#}e}j|nms8QY=1r)*Wxf7yB@`Cn$tLk zl_Qrh&U`-49ZR`)4jtlg51Hmk(ehg#(BYl5!5{wM97-L2sWoc%R5<)gb9|HamTGd+ zsNLrBuRxE}N?jU`JufM7$#dutI!g8NJnUZ42Um#|BmmY?x%7vFzkj4=uCV{8@${U( z4CCOe5cWTsne2*0k5=Ltk_*#jv)W14tXORHhTRCg+}@+Bt-StG;YIT0OEmjSvs2y} z%q4AYtGD3O@p5z3OVdizy?;gUswwP&W@rI+UEF9V2^#V+5iK#>O8Hq#Us6mj`B1YQ zY}j_*QG6Jz|6DOf#+?A6LdNm6ksFs&z=bCAyu<@|M1q#4s2c0nJ)<{j!A0}&fpQ#)uoAy^CRfx8o9rh zTG}!jn^M?n7duDO;30Ia=ixA;DB{+~FAxGT*-FX8_B_!cJHfFno zb4>y){SOZMFJU3BQw49;B8;KUSRN4xitx@DgdShYGB{UD8)mZN>eXJHY5)|r-e7PCTwZG zF3%XN>_k9@#!5a$F(OiOs=NFf*;rdM-ofxOjew!SNeP}U;dOgFUjyIi;t|5Q@P|i3 z1pmqZdp;N9%!C_y`j*WTwI=s5#RFr;SS24Eaer2O1DjRuJsdgY|a=tTx zsOW3q%%w`t>EsWoz=wxMmX}=L$Eb)W*Tyl0hn=FdBV7+_{Y#?(-q`;AXZI;qG^3m@ z6%zKbFJK%Ql2jHpE-BYN1=u@o0Hw=Bg&%u=uCNzLs)6ZjLw_<8D_eLwkJ|AlE~Tr}}VDyw24M*dQ)?uB%h-2W^x7 zFz>kJCM<^SY(w!SC(*LOP)BE$Z`@7!zvPn z$LD?1XYxMl!6p@8{kD>D?tX67G}}c|{Sz}i-&_Yuq6+5s3{mPz?*M4WQl1Ls4U$WS z=&t%vP4*|j6X+xr`yVI2O<^nV2f>3*Cm(F)*XSPnfFGF@x30td-*Ofdgpk<0XeNbu-oc`U{FTVw|QjxRj$8?<^_mswA1~l6_aR=Y-vbbG+ka8~zm}pZ!1Wz)KsyH{ngbe_n;v znNn*-hep>soffEw-SS{q;e_AWXh?`Q?=RCe0A(C21{N05qu91z^_AI{HfQ-9*BE>y zi8Ya2ZrlJhPDvY1xp?; z=k*7>lk#@qaullp%OUD-4_cpDCfJz8{kLX1PgCEC6WKR-pQiKN9h@BhHEe<^IA4&d zV^A$zcKNNFC;@lxMy7F^+g+K(POlcXAQBuHw0S-ytt*>Y=uN&s-7uz$r52~@kFR5K z4(7Z1ch_qw6J*e=LUt?SU%dRgq^cIL`bRMnndzB^R>dnpd6XF@eACK|pOONVmP!}~ zWg`evbY>jS8EstMGG71EB{F0ZNQjANXJ?sKOTBrU@^gnrw?SHmKh+}MhU&AbJ+N|i zwZY!w_N!4f)%PENw=``?XV}Nd$1-D4D+UKHjlI|Q%TEJ&eaHWu^fPv!uZ1#-bd1^X z0l<-VhM12}B&cbrpS~W-IyU?k$_wBY6`$F@@C^zXu)!6=-k&^Yr$MnmfS1cl2S0b9 zQ);hn#h01u*CpK|pYb`NejsA2uG<*ROpl8zt(qXaY)M=Fmt4d~f%kTsq?fo$;*HhQ z2%^&nU~muDhXa7om1oG0-HugdZ2qf9i7B zyKOsiNKIp}_*p4w%51ow>enzW+Vk*`Kf#-h95vd|=3r2i@`EZj;&H4K+S3y)mR3v{id6-t(v zBZ-}044bmn?*QI5Sy55EoQdxlPfgruUhSfJ!RCZ~dGe6&t+rmEUG&s~?FGn02xNz*i@Ql< z7R=32V354Lyg_Ox4mDse5t7n(U50CQt_>|=4G@14CzXs@l!Z`?%Cj(l?J{*W4VUr} z>vYs^)qNzi9CVxml*L^YpR3zw5!m=}nXij=H(K z@5(D>wStD(BUm^&%Uy-Z{J-MLAa3>RK@X#1T2z8jh0BL@m`CMx3srf6_tTYcV#rpL zHm@HYvMrQY#_EwVkmn_e`lyw*+T!;hbk!Qv#O!QbE-0_&4l9yQJFZ&>sn)s6Y9M8Z zN!uJCrnBZJ$qlg5En5CrIKD4ew(}}gcFJBry7zz-dWoti>O;PLueC2AW6bFTL#wU! za{pB*Qo~_(rrL8t@l9^U)GRK+t;~dcI8{e@4gN1{=-T>Uj<^=g>FQmvP12PbHV8$4 ztxHyeK2uIXN20y{UQ1hZDIK};aJ~bU>9TGDpN-9mFb49H8dKIt5zlb?;LSJ+a@++E z<_5`=O(kh)>zcx}&iLcNi%yJTuaI@I^&`qzeaj`2WzmLO8yg#k8Wur%$g?jsGYt+M zxhBgw<6KWCyI$y^hwZ!aQ1{4~U6EXveroy4s}B)!znQ4Xa>HazK zUPDJ^6fW2A)&A5`;&M^C&!zR75xDMctEM&c_D%dHA6nbNcj@v}#0|jxqjf^i)0_vk z7jzsAy$&_3e(V?%1qjeNY$#_}+Cl*J2hx$++TlYs4xbs}UhtnYZZX-4>T-zp)=Wmy zJpd~$O`4cb-vu2{iA5$P|Hyq_hVPCSgweo0Ehb(>No^7U%DEUeqDq-!`zik`B}D3z*C zOPSYqpHFxH<;?NN0W)R>(hK0cDsmdLXmV&4m0t|0aU8E+Rde!+Tf4rTggyF{Ca3DP zs^&^|_zgc}8a2d|OBrbHFmw2n$tKB$z=TV%AdAt3HhI5Y@L!pBJ6A~IG|qW`=8mvf z`q>DMoy`&GaqijAwG|KfD*b_H2qNcA{+px9HGyJrnEL#I6<+*O}~tT zeP*uCwwyt^0*qFKoT( zu$gPh%9EU>kK+eu#aG7(J??%%yHXZByb3ZW`-xqVYB&3dq{#%bxHPi5DJ3Ku=n9EA zRAdBHWCE6ZI;J%*3*V;Y6Y>lj9pMnnWeU!OK5F+SjSd@;8+BFF{vI;G;PxWZMR=yS z^hoqy4nBzjKYseEcx~a8w+)xEAYsllUxeTOWN#Vs_b@y)ouR!X&QJD8w?04Sx84U~qYnpl*Ggry7 z`sf-y!tn%tCzd9)$uN>2$zs#+>J*XAIN!94nV(==#`U)QQiGNR;(zCNoaf%P>27|V zxe;AzZ)pBi3|4Rf*~nwv@~Sg%8rrRz(yI@qXg1DG)oV)do1$WbrD&BEs$v`XADjvk z4Tm^#T$baZFBb2JTGVt){XYeKjf%2WK+@kk~>d$~r@O01?qFMJ*k*CCUpzeKSs7o#fXJ`z5w0_%aXEwqj&>qEzYJ~ZHg3GApwi7@6(=LHbjl)4 z%Oc|U}v0Y;#xzi*7hUd{2VXb1$c&Th9mKqYvCr=ra~)CguAb5#1xiY`ZE{T>r` z=I-#KHCfS~@+;aA=1Dqg^`lQzaGL4=9t4&iQ;`A(wTjpc|QfhHQl$bd!ST&?M7F(`z^~ zzp^nveb+g{j4PWL3@aiVlF9(Jmp!{=NS+rDRejz2eI|vqZsN_E=5rMU-Ts#&X#DFg zRSM^5wr#ZuUhoKcPEJk9<>0g-PR%wOGc$PjQ0OM^Aecd_^c5;pZZKyl$Z6VD4*mVO z3+k%u{tQXHAjM`Zhoq)vf6a&x_~_qUcJv@dwchHHw`lz_je9Tu_vpU>7pIHiZUJVI zVYR!!XL|Y$eGKZC6j=B1u8P3N&sFbg1R2-o5DTXdau^+2|WHz5ag=~0*`O5?5mRJ`_ zuZnYiv)%d4y0C#(o9$uVNcdaOY1PcRGRT#qe>mKNf99#c0KLZv9TP$Hi7MA zDy4|G`&jjB00WR6O2SpZ1rHtN3p=~|l0-`%mI4bVZT2NBLdc<7H8s=ZpU z_E$x17LH%cLDW4`t;EzRI0X~QOqfZYN-g(j0R z=HkA5Wfo0s0G;-fwh9BJ1Xtw~aRWQux6oPp>cNgzhQ=5X$HL;CjOe1fy&C-`o`L_V}y0yF^iTwJP3duCcU`no+qj0 z4%u+DP&5dZK0gVP$J)vMt}|=RZ*0j_^&y!m)3u@CMiM{pc=0Qq0 zbz5KemyF4ZMeL91&2F!M8^ctcUBPSWX~RaFuCrcW!=ArFsbn$Ny2BzNnlY2}`8>2} z2;isaNNHwN<0V4GSBp{9V#rclI!Q=1#zhULRw9W=k?muSmMa4D$Pu&DADrJmNgHTr zOVEV&#uQR3re%sEc4?W}?V)`@RJcX@n9g)Rv6xBj+Nx;h?I`G=YBvK&tZRNC+M8Lz zqx{LmF;Cd%LE0IH4pTx%>e2z#Qns4 z=|5!qsAqTV1LAOs=)0f(bu~R&ah>LPwsmFfkL2|Ty=l&^q_Tbgx!bJ0JHHH{Zibz8 z<&?#WWWf9<*X>}+8`tfgu;`U$6+?Y}yQKGL04iBRSi5P}k(b}I*!CtT#osJt{~S&= z8~+QR1~bL7hD}lR)sBW9zeiXNBAO@bA0DHbH9NyoH!;k8H$HyxAv|X@8o9US* z_)4YLH^gPVId$I3%s|IZrhNFAgs1G(_Eg0QdDp=n?7O z`M4WtWgeT8`&F(H(y$O#zrxZGblJKPL2RxreK0ug_dxJ=aFQ49KLyBg;l2RN@iQ!nCfOFOfD zPKxHnZJ;%sh$>Imd!{L_d*=F$a-#3__h2;%{$`Iz{@;IrZikq!iP#Ox zp^feOH7IfMwY0{5tQP92%eK}(8JPtBASJW`U42{OmjE^)#|cp_?O*RY>EA2APTx>v zxqd(vA71tD&)3U)*0U_4FrH%47?T#6aV8UOe0=S*wov24q%Z~K-#c&?GFf)n+|to~ z3_rXGt0$!by5JI(Fq2l1fBN;h`oM(fvm}ChaVRF)jKe~{DU)jM{n7IFq2TFS+imUG z>8_t?r?Mg=`0nXds>R!@1OEM7jegV{`&hMa5c~SVG6?HgppCy$O|{c0sX(Wb9NTZT zPu!2krNX&z?|sn-i)$83|1hCC1BKH`MPw+1RGRn=atNh~Xes^dNQdrNjy_@msstUK zl<%EzEZ>4UtdDQHB5x@~ciaQ?;|WkgY93Q5(_5e)DA(afLqe>kT1xva|e! zE=y`?!yY`i7W*t5hD;0?$LmF)yvew({j~vo_7aW$_B8xFQKN(FxA@Uz(*IzEpAzwY z@eD;nEMmXOVI*3pzqI?K9YToO<>#9v+MA2PCyRMqzJn26kqJPG@ewI4*{kC;zj)Zf z5=28?Nk=6K2+$Hx#20H;+|SIAyeXkc`zxu92sGTSB+r~Um1nE#d6|n9qgh2*pycvp z#TMv#G^9t>;uz^iaY!=Odpyo%IB6CZ{W{n*(8f>k4?IB?pGv0%2ZlfhGBNvd;cru` zO|zDG+r8K#)I-&`O^+dR--8v?7-9>XXgalD0ZNE-c=<#!pUxrK$_ztsZ}?jZG! zSsOmHR9hZ_^82#o2%&!>oA@*asW3}gvftPEX{j7{4@NTIAh;Z-{&jsJGo<88&$`(M zt8t!6<_ozne9I#)o1#99w@+Wk zY$tcks$QHBkoF_dvZ}&M==^SvckgV=n&+ogUH32jxnEy>{M6t$%eBt_d|$ZBsvT~S zy1nC8mmuNUGoszXfcf_HEfQ#bj-rE*!+`O9Xzncfs1*F=gN&>+vDiauyDAsT9o408 z5HU?ypL$po%~QzNk`H0hkUo<5zWhq&_grU%)W+58Cc5|{%;=#XadrNU1@fc;Zt7rp zL2!;SUiPuQkt$PA^?MI$9CDvS4i3Dm`F@5vuFf;$fr~;knu>X+V5f(pgq>jc*aL^O zfp=S{o{7*+n26cB@DXVToa#1X)gM}KVaQC6Gmh^@wk(kbyCt<8+bjm zJhXBw4Ecl%qj6k;G2Z4S`O#k`jJRT{`e)ij7|~5Zb!`(*F8L>!r!ZB z|H0zAVU{zw7j!T}v=;2}Fx)vpyv%Mt-Ms1{mHqM?@8#rgfs?xK0O_%Sj<%+5I%tQh z*{nFZThi+0`M9GEN37qx?H4c>E$DuKBte{;v)aJZ=239MlJ&%|yEK^NNo}{I8K83C~AE(l5Xw1~&h%tCB9+)L1eTc+5 z>hO7)YU**Gbj(}paq$7G_hl5OI0zBo69StR4?#LUNmJj=T)ju4y%OmOb2$K=KQ)}L z;y(F%eM$RH40@7%ZpU1X9veF%bV#VqpjgUz0mw>!Oq|tp>R2z_s`nym-X_T26lvD# zh|OIUwWfl4bcj1G|IAd8>yi5IwGq`v-Q<+h=``ORXXK+)=sBSy!TUEces`OQDCK7< zLt3g%86-7xrSN(Bajg=u&eE9A8toHAjoY>fAQ)V!Kn8Jk&#hLmtF?E4-WAyG(f;tcv@h`~x-y&l8meMW+bwq{fd;ztZ>LOM)&IeZm0@i;KfQ z*n4hI*s#)e?{`gOl%mpr#amY-9@+y30FPMIcNXJrM`V1G85c|AjWhI-WAH0lGAKsNhG$;BTpzL zcg)@lt47gyOXGYWu@fYff5jd8~=Pdz%(REULF1S!p+J#8F+mtlGnonOF>8oU!0G5@q*I%tndlavj6K+lXOYS z)%0!tH^Sn={(MlBr(6BF0dJ$|@LcG+?Y;hlif9aL4_N=KL}3=#Ma< z9De!1#&efX&CBx%DDE;jx%=|jSQeM*o0vCM`o&N{4&Sn);qxGNUf1x&(TgNpGd1O) zraC8!d!a?1Xy7uk!Gn!8JBo-nVpE?G_rnKEqo@1FL}_FA<>)SD*Gmh~Oq_3jtuT}i zMisd8A9ZBRSl%w3dU#jfdG3tS)llqtwAXZ$tpBJQD-plXKez}zEO2pl157W$o(;s)x6L57NZ%R`@Jgg!o&A6plmFs8Ip)QhsOyaD8 zBbjD3WGhe{JouoG6kC0}@4caQlO045R&;MAZ}PHS&$ZL@V)%#Z&UJDg0-=d5r0ef_ z_?Pnq`qXi!MV zY=$ZT#C`Z52fF(gJEci^PH1#=Bq;MrzC^mm^M#(>_2YfW8b+Wq8J*7yB;)l*-?ZK& zsQK|R-6l^l*P(ucwMrRL#o)NNu0T75gZk%kP!->g*7u^Dh&4H_b2|CV^&u>>r2mtw z;i0t#KC|4|ytDl*kedO&PWh%zTmuJ(<~Fti`0vc&;DqAVAMPV@adEC?3prKaJ-^p= z5eb~mSIz?b7OBzm8qY%jO|HfNH(VX?}d4%Tz4? zw08MfM_=2qDbs~i(DiU9N3G{h)!Fp<5c(odhcB}F$(c;#WDYk|j$Xr@`*Nx?JW3rz ztzLS1H)X|iOEuB8!L64Ivj(uSyGJalfXlR{3XTH7AO2<7rCj9A{(ySJm_gTcDK`+y++bf+KD$_Xq?8co(*CY)A z*j+*WOK}{0e^ z*+RdSp>=Q6u=jwg2_GqwrjwRIwmI5(Iz(a!P62QmD{YyK2rp-@UB@)|)jJf3ni&(A zHdZx{#s6|uZ9VXGI&JNNdsjA>hyCa0;pS~DTfguybyBq7c+NdMqJsVobCRgA=b(<; z)73ZuG9jl$AWpIOK8w4$L02&P5OKM^i5kh(TcG=STD~*@Zj#al*-=I-yqa8=^EwP% zjCTnAaJPjpLq<)?zAw{UYcJ-Ug}+HDFM7l9a&rSuFTAoU<>29=_r67*b~|lZ5r!3L*$h>-luA5Zu?0mY z5HQdXe}BB%GuHXkY%qRPc1D%2-|#unT#&SiMlc?R zBaSt zjXzUw(wVz#^*8(+qD-Vz4L-c7Sha7+WLgyxJe}G9;?ni1OG ze$Ul$L#Y%SQzsWeMz5GCTd_D(XVNayn3q=VJZ~%O9s{o3LxVH!(QDMof&Jj!9E2ippXXB1W{Dwtqex=Nk@Q5X`7MF&9yD26CUK5U4LzgRLTvG6ZtAqfI zZk=RszLf9q94UW;O(?tN%#HJXEl=m6)GK#0MFxIH^=aPmN6x}vYcJv(&?@j_2%j0 zZ{K3=a{m7Ebxs9@_m}HAn zGgKM_gLe?w$f?Q6r&8G*Z1!^Ynt{fRW5=s0Ueq`kCC&C0f@E)`YnRzW%>V3rlF^UY z3p_r(YFW18CuS#1D*1sp@l^9f9Qa9>elkQxhT{{Y*iZ=n6>S45d&&aBryT`pVC`l*69%1J%1g8RjpArXQ~8XQ(oUct%}*A{>v{cv!D@7 z1xCiVyWFd>?M!CyAWk5-*w`rfBercoQ1?#Vgl6IgAOPXJ6wCsAIP`9U&CE*$pRe9C z7D-NEX(?F)J}X9%FR)cz#GZ`q>nUhx=fY0N`9vFa60?s5$x6uUyquNtHlI_i zqU0d%h^zRNUApUVl~>lvP#Qv-gV;Dbi-T zRVL6{< zXsP~k-T#|ah^s=JB3W|_8%39C;3ga4}1#&|jgdP%+F9 zp()Wqb;ZgZ5ZU7bheF9IDS9`0Isq3TvoJX{4S)uZ9Q^TSAEe{b9l!e>QC=cUHF#?S z>M);rp8$2i2|ujfhhO~^VA+-(*JOPzMl-?cB z6~pph!Ig*PYQ1<6Pf{3pAD#MKhIRHH%4g?~_APIyycV-9VL~Ce{?+W<6wOD&&-}LN z7hN@#sIW*m(CR+Lf|1ZpG=7`lcQmVx7&R*00JpM6TZ{#F*m;}4yC~XN=E46Gl8i3o zW)JYnGu693_~NM0->Jggo2;oaO&noCtdIUKn2A^XpQYNHCZpK&a&h;=6@M^<$5cgQ zmhjy~4aGuF$auWt)~mUe1`T|Gj*cQ^ycb{4TBE+%TIZUxZ%CHQ#xr`~Cev$C6Ar<1vXuC)Op7;%|qj;lG_vpHS{ zu?t~a{lhL}6FL#|to*1e5DzpQl*c+)W#nBcVYb&P|ICsC%z(A3W*m3;?BkP?{`Cdj z%B_FfzPt~WCZVxzGBAibPXXh&@7djie3DoFmqRNH^P{Bundh(J+Wc$tCL_+$Q5&t_ z5+DMC)K)S_{cW5{b~X`Z7#J3~$@(MfUtr?wLya?l77kvxUS<7=w{v}eLm}+RE_CZD zO(PSvD-3p<)yI*G+9pP|QYtI7Z*)&ZP0>lQGaMTLBj^;O$K2T;J2vy}={jdi4Ok#bXkRFamfNf%8)yD8 zx@yYeVVt!Ip^Ic=B@BONc~=*y&u-(pN0xSvp60ZW3Sc>2X}*^5F|Ii!EWu6mU>Dl; zJsHuum+Z;g6^^h77W!#KuyjCDqOGe9wzHJEj6Ys3K``bY#Gv9$8#%r2DY^=QWO9_$ z{`n)fH0%p3*efVq_XnN$L;-Q+6g1@Hh_4Y4+jQ#r>8tw zDmD!xRA|EFlZZUe2FJQZ$M@)%xQD)=PwKBbux#j*GVB2i&`Y3d4ZR}%8)$KpI~J;3 z^54aekW+*diX>0#nKK5=~*(TWL!4)hTNJ&m6j$IY}raDCA zsZI08TftzKNrsF=!-Gqeb8I&@zuaXI7B{mbSx*>o;lPoR3$x}Yj%6%bbR;A_)5X9{ z8iw&@an;Apo!;hgaI$c+aB$TybFd`=Nvsgw?XZl4m`7q%bn((WkpXi#UHqmC1tG{6 zL{I<~c2@g`@Y}n(3CqGF+RcbhUn}&gf;d~25uUz4$vB*l-3gnd5$iP3=9NBh3l?nL*u4N}9wZuk8k4uP)OK?C9yZ?jwY;@Jf)U~zi9S|7u6?*6) zoI`-cG!$heqWHl{H>Q7|%zYR!QgMggghNiYD{zf1Z~gT0Va{dAR9n}gDHB%)8JZ$y zf;bZnR|Rr*Mc}waQMCTmjb-GI<*ZVyFN#qmU%;BQ(K6cB*7|l)rfLxvgviF9P{R-k zqy}3Xocl@y=dDv=pgz4q0J6(R6KAuEov8v{EjKrfsM+3ga_D&|H5&4|cAf}8qf7EX zgFn80peIQi{`8JT+=%%syU<>I7y=pMb<{@WyJ3Wp1f9Lrh&^ljkw5z24y>!djl=oH zTRCBa*@Re_0fEMR9TTVtRN4iH;Pum6-_8(o^;ASzoQ}>X;&Oq%HX{d4Qk6?vS9eE*(_Zintez5w?Gc%t3N9@r zTpBP=9L}h@BR}b9JSoK_q#Fas)i_t7J zHYT$MBvDJVbSQIMjI`uktc*vn3XFot;t&c{sa$oYwNp*R)N(x)v@*L6&gQi>ZUBBA*jgpx_*sRgT$W;?V8f#sJbc7~z}X$K3uwAl9VaS-Ut{^GU6NaGsO`+U%IJ3`_A(h>UAr53UTc zMXJ?Ov+B_rkCVfk2H5U)yixU7>)oLEu%1z+JkMNrd zd$@Eu+G*dJDt7!A?wL4r$xzA_gg;)G-GLe2S=3Ynur?Rc{)31ddk`gd?PN+`b|h6Nz@ zLv&?XW(foWDXTBE%Y@h)0vj3(MFO95MAKYj>zL0VC2s6^7_6jIkiRAzmwUgsjJc6N zv-F#5Y_JqRe^l3LvWKgrP_ZI3gP1-%6lwf7xx0S3X|hw+yrdYYiue{_LSzh9u_0|8 z9ejW;zQlrmTGeySXm$l@v8>DXUk^U2Nxj|*owTWNErvg*s%J82dj0k6P&e}7gJV}j zZSj9nNoL+5_K|wE%-22!#wTMg9f1@PCjS^cY{A0h4>H_g*E$UkfB1*eEf70-xPH9t zXFW#0_A^yF@2mem>dF7lG5$X)H2?3V>Hlj5I-+j;|F&?Qp8;bfl+>uluZ6=apTo=i zQ%5bXkHnYH6v8f>e-GvtpEKRgQl$}P@0e(BTk=N^=NpPH_v~A-)sg?(FAca_@mt;e zs&Eecc=}LZjFtT`$7Jx<<9X6&O=Q2AO3(2Q)-qw#+IX5koc4gz(vLfm;ZcdR5F!gEw=MOxvj`5lz`V0h^7(CmG^y zp0h+0oY1IqHRH1!sp^F@STtr5Q+)2tf`pD)Ha}4AdSGXpNHvoeCL6rD-UC4h(-wSr zav%+NyRYfte4yr$+^I1e+`Q-wc+YS~AgflhYM*<*WxYE!J6Tk5TYY~NK@)^4qqY9< z(_iMwQiMm+=6QUV>u&O3aJ4i1^L39v@KtS+Sg4AmXWG-G=_{jNm%GHVcLIE(ghJvuy4E?Jhs=w@%OoVUg;nsu3?cf}I1$rwl@0j&^FFuV)?SZ+ zI6~CPy!$|%O;G>$?u3;9HkmU2=j;D6-aTL5dX+Gx;L|-MRWG;x&ks6CD0ib5LRlr3 zgq%5uiPYivKepX@_7tFnKu5oN>`=AhOT*vDlable|EjP5lpfCxEQ-{Ol`Zx67o0z8 z)&BVtxAyD9xj|nh_}9J`w%uhMU$tb_ggpwAtLlTU9h7N5UF_%>^_4mM;imJkK!G{j zSr>nKAGWT(>8Ku7yJJ_nd&`A>ZL>dxvs&cB_x4=vHno+wEVp}kmC^Hm`>f{9oVX_a zNB`9~JL}^a=@1IuvpP84_YkBjvS$=pK)_pOsov(b%K2X%MHmluk|Er0`$(EtK ze!wy-vi$jy>8sotR-dx{yWXev_2gCWOLo{yUUp^%Fh$?b&-uUqOZdg?ufM#lW90sB z`u{@<==-bb*}XenpWOdX$;y1<>1kFUn*LcbgueLoP29Wbc)y(4=c6Y%7J}mUd6Ca7 zqs6N_SI-6||K`JGt1JJ!NCcYjxA17&EBkN2)b@2n_*NUBrfts?&VkbJ%b3vnmcYcb zrrC1q)UH+GGr#}#+nU*b*SP%QCHt@kj8hKy1}D{=S>J6p18C+|>B+#%^{@0I`_<=x zN-b&oEOu7?wKP_)1g7ri=WF8rcVE?hXdFMs2I!|Kbw~cIG*z9gw>4Tt#3B|x}JU} zt^ycdU&M^IG%n=gm0GtlzxGqQcHQr61IIzGGSXco^y63!VE!aO#)}8NV z^wnZM;6WI84?RIWSp?^iBRD0{P8LBNtb!(idVmPjRj}hg5Cy)%0iq94q3qBTw3-Fs y0(6PC-8hbmAu{C9!h!Mt0>>xF@*lJR00009a7bBm000XU z000XU0RWnu7ytkO1ZP1_K>z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ^-$_J4RCwC#nt4!F*BQXiId^;e$|fMlrlP2zxEmK# zj0@J?u@jqUJGIudsWn4YlBsFjvN*=LO=Q%V*j5s2#JCX~Yt*;Sxj1u@IPiyR8^K`j^%isdklbri$$4#%|4Y| zSYG9jWd%aW^Q_%sj*SW*Iv{ak>I*TQ!Zz>Nv-2N0dYz_Givqy2tl4A;4Gu_7j2|^5 zIlyjd`m;w*=KcBoOsz&B6hH_ztXR|~CgPzC7~`u&CE=k#W|Qgur|kV+duz?swV7E? zr&|zshGl$56TOn7)_J+;=H7i@@7$A7iW3-y>E1QAva0&KbA^3-_jpJSWUT(^FYjhz zLd<3(fY9re00js^Sy3cO<~UX`>Sb900Pq|KbQ+yjqtj}%8UbUXVoV5O7-Tf)j0RnK zm1D`<8>am_qu$wYP?lksdn!7u2BF8uzyP~llGUOc#cg>Yx8TYLnOS_j>W|e-~V)6lesV=eX?s zM;GX|AFq3pK~GgM5Q0MnBo!21{%r4|8I#7g4v_QBS+D3dnT?nbtwz|j`R#6&Q%y4mV`4TM)~{HIAo4}g{v#(}dvoobifWC(8!e`tyAO{WIcV0T z(NCY#X0x^M>am{Ji@J7>YbAs#@798Q-w8qpK+F6#8})DeVa}edD=7tpkS3u|U2gH7 zB1lUelJ(JYomPV}fe^AByMEhlN-085TeYJiI=q!WuehY7va+%j0E@{0CdO)%3NnkU)fB+xIbj6XRc+lIjt?006BQ zWFP#R64Ek+2J}vV2vQ0l1U%2){Gn{&vULWXwnI=rLf7aQM+_L3GB7+e=n*ZA8#!q6 zCwqO)6ur{LYsKx=Mh+j(udXal9Wf{}GP0QmMh@vSHf5l*wvJLtDd0KIWY7Z$Zs7@Aj5NGWXw!1LVp zwQo$CkmB-)PM1efRZ1y>kmp!~UTZSy>*`$@D>g1zy5?Szv{}CqY8v#aircF_^E?+E z9B`+!tiImaGOL0DtY2(foxS~?Y2$|n*{zDI);rxUk4Pv50B{^@u$Z>~{mXL~uIaRz zw$0QzU7{p6a6)J`8{6v|6JuQMaMrtAj+z>_)i=^c4@nz6q}ow??fYB#7q1^Xou6~; z3?`Ie5P}e^`0%ka48yc-Cb!^@h*0(2T0+_i2~m``?K&Xv8~{L;<*10zg!pJl zmfHoOfA8*NQ<4ojUQyI$01KC`do5#)qqhEjovGu7+bkwburDJmW`nP7H8zc=5#{!H zf4k(pi`R+;fd>Fc9`Br)<9Uv2kp>!pe=>j`@i7xpdh2yO&kM~$NLBEM8$SK#w|TG3 z7(X^;U|dwV?*tW9jq;w`J2=Eji;Ao<=ClnT8-e9OTMFDa~eJ2mk-R$cUWbmJZkR?` z=5B5M#Fx_vrGyYw#T>^P^*R7Rozoo_61a8E60=d?8~_3U<}ZG)MOJ&{j!Mvjw+GD@0MEga8Nt1*)p@92?#tXy(sG{b|8V zW|N`8_>YwyHr9SY;H_q3mzap@X(=<(Mm8=3J{8ogIkY@1Vwkq)rC#0QdL(y6K#d6R z(63KY>l>NNEnX?QdHH(Dow6!Xk`O|HHcR&|QHcqit!Cr@cT3)%b7bG)96-VRxvwPk zOnAsn{7i`?$!Bu&KH2rTqN-_QMo*uV*7{2MY)Z!JEm`}H4DTBS03AB8|I~@&AGi}g zgQBXqva$@zB36`?VS{E(o!m4}p7jvAeW!Ha!JOif5|(9ChP{xQGQ35ddPY4U$;#Y6 zuIdzO)AMRYRdqyo*!VG{8rR6j1|WnGN*RP;I}P-0i`(r!lbfG^{z6TaEoD&831dbN z9@tN()jsykT#E@-RaHtU%d#x{llX0W))&XXiD z#@OqXWJMtuE2?_8#u?KooMjo7Wo1R>xd-~kBT53#K?o#C7DX|A`KH*&ki_`NimGY= zfZb*d2@VPm3kwPic=Y>=r>a7fQm~y&aA*B@#yUo%uG}vaf+U-`8@k!czdzMj*F~(SyWm!=a zMNw6?rp_gBEJV}gpv5|`ST0$00000NkvXXu0mjff{t_O diff --git a/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/Info.plist b/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/Info.plist deleted file mode 100644 index b8089dca2..000000000 --- a/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/Info.plist +++ /dev/null @@ -1,28 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - ${PRODUCT_NAME} - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - Icon - CFBundleIdentifier - com.yourcompany.${PRODUCT_NAME:identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - LSRequiresIPhoneOS - - - diff --git a/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns b/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns deleted file mode 100644 index 4500ce2bbd0e598176a3fa6c4fad8ecf466b7b05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34248 zcmeI52V4|a+vsO!3uS?55)DOc6n&GJqKN{6RAXYIX&RHfnlHxKOQINinJpA)0*Ywt zu^X^OjScKrQ9zU?ih_ddF1u{+=X=g9%MPS`_r3SNzQ22aJ21?g@;r0ObISbpS)D#< zPCP**T%8_2Xdpq5xdcizbF2?aTbdG|@tULsC6&mMh}w#69QSJKupq;Xk2w5ofM#*mV z;gV9bQYDv3C6CIB%C%^J$t|NosZ_`$%`&Y)q1#__Rn;t!NTo8FlxpU-?k+7yxOb3dvq4jpw1nNe*@_14`fL&KJTlJ-ITAw4P-mtWkF{-|K>N$c^P zJ?P=KUzs(#lczacQf5}E6;ST_ifi|D?KNwWNdB+Y47%-4YgV#((T2>qiOs3^p=OqY zwVNW(R*pNnX70qB$YO2WTY6{zH{!{)kE%34-NH zbUL`no7Zo!AM190#D9t`$bOiR$h{63O!h;EDEEdA>B9eb_%Q-=YdZ``z<<)Qd~R18 zA3m}lwXO4}&%(pg^~EiSWm4vvy4-76R3=}FtU1WVjOJfaEJcJ3?9$&jORNhl%e9$c6=fDpq2&YwTijI359**xufi|`?z zV6%uHZV)UM!T$jj5hTGTenm#4erNm2%g`E+^3rmyAjNOTj-RbZsO8A9Ty^2yK}8WhsisonbN>4JNBaVDy9GXf_)3Mhhz5E2==a+ZH3E(FAdN z%G}*zf*&hFrc2jW?$;p=oo>+zbbe}uT%wd|B$_A9<;So7d`*oE8a39w$fOo(e6=ct zq`tBI@vXbnH7yp4R;kvsqIp*o3w5nxrH4wbQR~!toldV-v4cx9In zV&wg#oVM2bz5~h-(p>2|!i@5}#a{9o3D$Z|i>=if*|qP81@%?FaeAZ-3EJHEecD>@ zTv%EJ9b5kO>s>tu9_kyTx9Xz$<_3&tvsT>++FI2}Q8dCQ{`D9Wy4`2+$sQll)>^xC z>UEj;?uTa-vQaOs9x(LM(P(aFwQt;&D;K2LTBSR{S_KWg`8{6hvZAEBPgk!#E70|q ze7n3v9)h8%8L@W-w$_HD>$eu8)>CH+FF!>{eyX7G?5So*ub8C!qqTZ~wf_A5oi=Nw zj3jNX-E7us0BbGFPpN9NRs$p(^ag>so5>6lnH8C?-bgyw*;u8@7L8Q%R8n#3`nDTt zr0-;`(uSsc^`#Xx_i1C*v>U5PNvYg5YVE&ntgbd=l|PdRn+b`yxhpnT+wb!;R_mV| zE3AqHo)|jXs^!@usnx7ds0?7MX1NO6s?j#NE=Kofh7Jy$bMw>Du_I@nNB81pgRQEi zw5={h{~WmHZ1$(eV@GB!3mbUu!N7@NtBsY|Rt1gGBP$Wo-X8X?8J&1{!p*QrV5`OY z#bB%G>w(b|S2aEio1jPPF|qrjCW5V6QRP*zhsCIR?gswGIItYsYE$9v{Boqa zRCJ~I8A7cWi>_R~B!l#-nNaXQ&a4)+XSUr|VQMwO!ez4ADonE$RCQ!^jonrSMi$dl z&9`r69_?(ZElRnjMbjj$K7V6x@gGdJRrd5*bwhbo?SoG9sz}LG;fYnN7U)QID|22= zQBd-PPLnF0N%4HywS7{h4HR3bu$d)krX+kYR|##abjH7)SZC2YBaSPa=hA zlVH@DLr4DNI9T`vK}>@__>04Y5(#1wGMNA3&?6y1OoqMVUmPYRcBVVq=l^f}_#PSU z8~x5#0}>I$l)oDv2?P;1b>eq_aZH@{7BPK3elvJig-14Xn5hv-5X0mjlfLkJkMB$6 zi2Snc{yN-`ZM(nbyrN+Ys9?W)vy_Ol9-glOU>DF>_)vY1+gjw!X#3>){uip=|Mv(Lpl-hZj67C zAYI%jzK6S;3x{C67@htYp)08bkHddu;MAk0Bt+~N6D&Vv4q}^bJW`}E+;^pGWcOlpz8%+s_b&w_WB3=8dauI2&eYT1rD?;q2LkWI{7tgJa z0t>G8VsnZ2s>KeW4T!bj=VXSA5Rt9XM1mKG@8;^}Ap+4rS~SaxBzhExn3C+m&83FK z4zjEngviU?ljL*{>er_WNw`t%3P2T?!{PE=J;Yw@7r0%{LMz&fz7dgkFGF1%wk<$p z37;?Y>c;1dIZ&riN-Flx2w-u&+DapUhrAH^-tefw{a;|YioHm#Uk$v#+4XHg6bjTK{r_i2WzweEX5sfy+Z zy;$V9Rmjzt*`=EtH!ZE_u^6$X6A4d|7mL{4K?%EP+UDCLMu8|q8sBsQH3XH4csHlg z9ZM^Dl!#cfNZee5vAb`e3-&1e8~Zz|c#fYm}*^S_O zqeQkTuLHbx)TA@Qa5xG3d3ipKB$s^f|OUz)3vrcoN>B#*|>4Nl> zy$H6Jws|)hxmrtezJBus7U7zJds|;@H$v#W)pYN<-DsEJirh?T?|hxM5skBJNJBis z-R(18W5GlNJzaT+AwP92P^S-;c=;5 z2{iH!cXvFM>|{(OprmTSvV~h6ok$^GWfwlH$AT)TxMnyWc-+C(n{8@ZgotCgG~U%+ zh^Mw#`_#sAeRVr>Juq)c{O?Rn?v-6UyxfSFKL4dgFF#tW#W zbH5GcvtW)RdEM^WCtbeZiexcs<+g0(W)Q?LoL9lrN`h9(i_a%nFTFYPtFh5RJPw}T zUTeW>MP39;K#(NQ6Q*%jkE8Um0FfRk1QC{r_^l-;ew;s7sO_v!;Bd^>z}|HRrB>f6UXzunL3xsJ$@gyCD%UB z9M2jnT#dL_r++tV(hlbQpM>1aPf7|8|C)dNYMtRWJZJjk8I$I>GV|0U-m^vDO`ANa zgt_oMMm*JuNi(K>dz!hRJw&egVN=9YX3hL|2Xnc6fZSUB2_jl?1!sa4aJUFQZL*?O5ERl; z@Yxg48n>q0ISZD~`{^dmz=aI7CP3a-QKAJt`+_sQ?V1Ny%Hm~3YGf%|8NX!F+_VSC znrLC8F?gPWk1(zvv)N)cQx?k11F!V%rOOvC{7sLN&20~WLR~@SW)GzCCOAKemoLn&Le^D`)FLD_5#}^F zbKp#dbB(Es*<^y(ucyC{?(x2OMf!OiN`!cU$)U3dWt!MVz0N2y5k@hbkiobPP7!?i z=V_@slq$|hPE0-7iY&%dhTLV8ZFJG8)LN6tXgX+o0qqFSuKYD4B_lOy-RWjz$uP3f z=eS{@+?SEqKwd4tG)3q&) z7`g)!H)QC1O$MD_Z!nt8E63itbz=Y4&6~Gx-*>V?W-{wjK`=qbMxV8n_#zVM2<=*( z2dGjtKWf;YA(yLll!4S53<5n{XGBIyPZ>PT&1#cg)AFSHa!*3IpZdjR*P#nF3X|E8 z%TRU!WoQXqigpk@UZZHPtEsHI-*9%qla?0vh*MX+v;jUulQlmp>p8XZ>e=59<>jwU z$p7ukwaTYzlS%)x)={bpC_zhTarof?)_OX+$VlyXU9eO=A{x{C5UWp~QT?$$lL z|LCbiq0t)*dfhJ?$AiyXv(-j}xd!wF)8$b+U?5b5uCZCh4k%1PG}h zo>K83VAJmo`pqhp5`I*al7u@7u9S+Sgb1Zb#fK}tqqBf2rBLO8V>-kofCx*agy(`J z7ZTw&p)H`aJqIlLtVyP9tJNPug+^H`+xkhH1r-|eS_wq~Bc{M0Q?M;`I=wDaWv85N zwin}!PS(OUecV>4GrDapgzOlcnT*)eTA7S(wC7=jI0SK8E2U&4eC|$3+3*=Q1PG~6 z<_Zz?XYsN`DNjb8#x;+7D z+E0WiCL@BS$_a@aucH4B5ccPgNYV7<$uqgJ2q2NBGbDPjW!ih8Z@vEd+aYmZQ3oEt zKDIGCX$^1Pw!AYXPff5JtH}_qA+xp`0TRiM89PEE?~+-sdi(Y28xR;6(6_h0kMBP| zU;hN5o87&Wd|Z8fdj!1k-h$HridesS34O?y2dXeCx?SJe2^Fam0(}Bff?WgsyTz)| z?SP<^V3(kPUOqiO++~K{>F<8RV6sny8l$3zol#NK=17yc2>s0e$-P4HSWB7%iF=O!^MI1bc9YB>VENG9z=F2d%THyC~Q_ zsE7Z6p%H`o`}y{v+7*DRp8ozld-Vwv2ebS2>~|S*+jRjdx>wX06_p1B2!p!?^qPFU zzEvfwKC&p(uV-*uX$0_)exH3c?z52*{d{|igUOx)AHZ9ST_2#L8|OQtBFY=uDX8ym zKt(MFKKAjq)k_de2ENt^s7PJ8A>0=<`HnHdn;ApXmY(^{9WFd(jK46LhOrIj=QDO%!( zTWbWoX4=aEq^M-yeddN8H0Xz64L!#KDY6#KNEpoZo#l`R&QqFqu`?+e=PwTC_IP{pjxtP&m>Mh}_XG`nLRIbM z2Mu>-t$)aT-+_i)35Mnx;O84SZ0gTtxc}Rg0BcBv{^AA(lrwa=eaabkx)UiX?j4u} zl41apIWdH0=O2X9IY1>~K; zKw&V)dwaVEcvV;L{P|2r1kS~WieBnb>1JE&hH3Q`doHqo-4tL?&I!FBy%>frj$U|O)-oqzZa6y`WM6AVy&6ObYb1{-VNDUbU7fO;*3P9Y9fWFBtsXpq|&N>;-@!xX&Mk5R72(d9jaR z42sqy3fD7LaP9|q&u)O}{#*~NB(UF;dv+x-81nk|#WP7hV7Hvd3w}_4K}K5g${#)o@P!$U?DcxJeZ~!VJ2g3zm9`&qqU5D3 z7FRK~lAx6e<_Gxsy&5-u`jjzYy}+<|J)`7Utti;V*W262$FElqOufAWPt%J6)H=u~ z*_-vkXh21(@`6RnmaOWCia;lb2KM&%>(R3h*3zeU5j}Qbneq=fLN8O9!7TqT0TtZ{ z@B7Bo+vD8P0Z`k3pdc#PH7F>cx3Blx z2~wDYZocA^=tueTe0=<09hKRDHw7JFu63 z4`_n{adUoYgwj8pku-}pXTi$!?FA2EcXDfT<}B8f3}8h!=FR$P_C6*D!mOz2?&Xt5 zj};WxV^;Jy{)hNE%azPLz>1m$v*-OV`wnyI!K^58_WXG>&oP%YU`5A1`YG+lpXSfl z$6PRh6{!Y!cl&7Bf;qo-W<}$Cg1%caC!e{Az^v%Zk_j`G{Peq>6~Vsw8WIBt!e^qD zjr~}%+XxXINV9Tq97aUXHZ52oT(bN&0+7VE^*D%MMX46>rrg;^hcGG1v~;s#Unu}Y z*AkWrRxZk}104_}v_m33W;mGfU_2xS_9LSC4`C6Qxi$hM0!9RPsTdVm=q$-Vj$TL_ zv~b%>p?Jm0-woiUjk%Hw&Tm6cP#PN<(!SZvBt zI~Hm@HU8~!DdIJkbcl&|+K`amxCJm!CY%(YAP>vqqgg3y($lieD3N8AiDxvK+8=L& zL29+m4ukSO+*EaNP3D@c^o?hw9bpil9Rp7*m$vF!X$)jR>L`By?A-Nh*X%C-D-85# zx7>z-j9c_C)2>uT#r+HUOXB8k-mvY&eVw%v2+Gy*fdNUM);G22upG5Rh&IgWp_0iNJu?Y5AA|sbr0h?w%{VP2KV@E=d7t&$!k?Q2vBFr!(=`M z#;ppXHCaKnDq7Dl$V`DjsNi5=1J1ZM;Dbqy*gZ8>mQ0MZVkqnG^+ z-^rxe4k1g2YZ9FJn$yCQwY0QDAO_%p&S8XrN}UD_1NepjLSutAT>Om-90fu6O99Oh z$lPu0hyH6PK5U%LCPm4BuC(dFB4WTn|1;6uh%D#DOQ-^ml`@vqCj9W&~Kk)y|a^JCVj$FK*LY)|@yw=4g|<%(w*^3-h>{z7ic z!;q(?uruVTphkoY9TpWG6B8X386FxoV&^2B%@w>U3?<(k ztp>znzV`>jqgfXl8j}*|8WaBR1P!_u6Pps}5*srtH2nJ`81bAB6ULEIUurPosq2h* zq*DjSWW@2JK38GE)p6{IAwPi6O1lssp8Whyh(|puBq5H7p`wTw5r~eZMYH0_u#a!T z-r4@R4TxQQ;7(`6lR8)w=N>yWeB>8jel~n)XcX1108~YUher&Hj7f+iBZl9ChP0~! z!c%#*GvTR@juFOniy5}$T%$^(s4GYv6BZHIRu}<1WB808=gge++ma9)&n0RusnyIn_~1S@Pa8rWV+)nqOZhFj}fctNxm1Q1VYUM+K<4H^tzVhs_q0P)z10MexO$DyJ) zZYX>_?vQ4yj~rGoH}4>B{;y#oXu8y9u=sX)*jC?(j1|Ul!+<~Ab!r4?h#aeCYN%YcrH=WQ0u7l3hUOYQG&JU`WqT{ZmK{m}5^RJH z&OMySEf}kSC@86`CH$jtvvtdJx<5d+1k8b10kcimSI9}w) zCmp2k$I(U4YkxLKpU%m-=#U1&)3|S1Y-m_yOmZA|NGemDbv**NTme)1!rHZm9MYKZ z)a0$4Fgz?YG68qCv9fI#G(p4f4Ta8&jjCvu2f}0C{muNfJ30^^&x@D{Z#VW4gaOaGlq5#!!4s%1Iz-R}fahvBRuVJ3>At-bFcf}|j>hxINya>a z%OOk_?QwJh0G_({qQgGU0S6LNHwTZph)LFpHZ@8NcuJ{AP(+5!w$E#F{x|bhES>emFt96L#MktsDT;Fm3keAg4I35< zGjC)prvB%lKUlG$$sw$_rU2kkSD#xZSdp${mK5s*(U{2ap+h60pfoO#k+ z^C?Vss`d%K8x=E*Zh(>B2oFkNv8!K6B?w$7;i|072a4)pV{&&%rhv6{3-F!dh4G8$ z<}s&#;5!ycP4R`ovscO+jlg&67tLQ3FX+s7Bnk5t&W|r=t~;3Tq|9Bk@W%_x^$hsV z*~!US^Or21lgC_mf$yk42^lhB<&t^%o%zn}u-G{(;tzG^JB8HDpH?h6^#{I#9e%J6 zPzsy^8|R_0J5VNs#hCHHj{ufxx8`k2g$XMJC7mgc5WvnR3md-l1sI30u4>~wsc=oO zbhX0QH!U|)s6_Gdb&n8cJt8~nf%h5OAqdzG?e>#lCIQ(9u|rTAP@fF5Cnh+w#}B>$ z<>BXkylSU7ag|7X(tyN&N_h06hJ;fYt3;b>8H5Mk;)+nVi8Pzc$L(mR>CEg=(=w8C zi}Vh(1Mhc52nbCI4R5eh%~pUr*>HlVkNNTOoQ!o@tJf9+gZZPUkKO@ytiON1zxqh- z+T5J1E$9CLcd}_OAGu7aQyKRdfE{5^AFKN7H-_hK+_*k>-)+@jc>2^IwjmyaajX6% z{AD>~Ywe{&iQ`vp+q~mc?H>qF65yIt9i?|uOB)-W$+Zdz_Q-)qaNN-+>3V@jlL7nv zfVr|5ZhLbxLfIuh%OJ@+$&OYGt z<7+UOWExC*8f&kQ9<=u0zJ2@ij$f%&m`n!jE0oR9bpdU%JNrDYt*NPPxJEU#$blkg z>()2fNKeJ5iB&f)o;iNxx9zz{Pn<8VZqfj!$pVs+z(6$@(6%~qUcU3b=&_| z*@_cQB5z(Ed5tW5;%~FzOKj+z~<) zK1DRd!4L>L_E2gPynSpT><$Exwg82Qwn<{gd=Ju!rg0^LM1D(2%WQwYDAy+>=2gA8xC{=Gx=d z=GxQd-GjN#D)82UphBJn0Zf1}{lWe{32+J&Y@BEVLkz#2PLv1ycI4L>K09Z0nC#@i zxw?fVldW(0QwN@od`0_yIu%nM3HTI&!;b(?tO}fc2sn9=)DCw}{zrXwI(iKKZ+P&`r@#6c^@o2H<4?Za z>5Ou=fU^buoh=ac>GM85>A|Rv+uaThea|H@$?<&B|K4+XWQT{ubK1Yw&Uvk-L(+2z z2>9SNX*)P?!dJka_aXLlKHu5?bPG7`&pG~{_w<9D^N(}>b zoLj)T{yNuR=lbhhf1T^EbN}JwPtSSrg~vJ9U+4PkTz{SGuXFu%uD{Op*SY>a?-p?G zKb-py=l;XF|8VXQdaPB{x`;X_{0?z%1 zbN}Joe>nFa&i#jT|KZ$!Jnz-l$v>R?561qZ?)lqaBIEmSZO(8A b$mf1IYH#m`|IBszq&e`P=n)<<3WE4=D!jsj diff --git a/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist b/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist deleted file mode 100644 index 498e37d4f..000000000 --- a/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Description - This project builds an SDL based project for iPhone OS using C or Objective-C. It includes everything you need to get up and running with SDL on iPhone. - CFBundleIconFile - Icon.png - - diff --git a/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/project.pbxproj b/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/project.pbxproj deleted file mode 100644 index 8e54e04f7..000000000 --- a/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/project.pbxproj +++ /dev/null @@ -1,500 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD14FF0DC6FC520079059D /* OpenGLES.framework */; }; - 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD15070DC6FC5B0079059D /* QuartzCore.framework */; }; - 945C4F53195AF17F00DBBF61 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 945C4F52195AF17F00DBBF61 /* Default-568h@2x.png */; }; - F3A497AC2555F0BD00E92A8B /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A497AB2555F0BD00E92A8B /* CoreHaptics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - F3A497AD2555F0C000E92A8B /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A4978F2555F07100E92A8B /* libSDL2.a */; }; - F3A497B02555F0FF00E92A8B /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A497AF2555F0FF00E92A8B /* Metal.framework */; }; - F3A497B32555F11600E92A8B /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A497B22555F11600E92A8B /* AVFoundation.framework */; }; - FA8B4B97196703B400F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4B96196703B400F8EB7C /* CoreMotion.framework */; }; - FAE0E9651BAF967F0098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9641BAF967F0098DFA4 /* GameController.framework */; }; - FD779EDE0E26BA1200F39101 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FD779EDD0E26BA1200F39101 /* CoreAudio.framework */; }; - FD77A07D0E26BD8C00F39101 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = FD77A07C0E26BD8C00F39101 /* Icon.png */; }; - FD77A07F0E26BDA900F39101 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = FD77A07E0E26BDA900F39101 /* Default.png */; }; - FD77A0850E26BDB800F39101 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FD77A0840E26BDB800F39101 /* AudioToolbox.framework */; }; - FD77A09D0E26BDE500F39101 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A09C0E26BDE500F39101 /* main.c */; }; - FDB8BFC60E5A0F6A00980157 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB8BFC50E5A0F6A00980157 /* CoreGraphics.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - F3A497862555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = BECDF66C0761BA81005FE872; - remoteInfo = Framework; - }; - F3A497882555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A7D88B5423E2437C00DCD162; - remoteInfo = "Framework-iOS"; - }; - F3A4978A2555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A7D88D1523E24BED00DCD162; - remoteInfo = "Framework-tvOS"; - }; - F3A4978C2555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = BECDF6B30761BA81005FE872; - remoteInfo = "Static Library"; - }; - F3A4978E2555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A7D88E5423E24D3B00DCD162; - remoteInfo = "Static Library-iOS"; - }; - F3A497902555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A769B23D23E259AE00872273; - remoteInfo = "Static Library-tvOS"; - }; - F3A497922555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = DB31407717554B71006C0E22; - remoteInfo = "Shared Library"; - }; - F3A497942555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A75FCEB323E25AB700529352; - remoteInfo = "Shared Library-iOS"; - }; - F3A497962555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A75FD06C23E25AC700529352; - remoteInfo = "Shared Library-tvOS"; - }; - F3A497982555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = BECDF6BE0761BA81005FE872; - remoteInfo = "Standard DMG"; - }; - F3A4979A2555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A75FDB8C23E4C74400529352; - remoteInfo = hidapi; - }; - F3A4979C2555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A75FDB4923E399AC00529352; - remoteInfo = "hidapi-iOS"; - }; - F3A4979E2555F07100E92A8B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 944A65681957463F0094A81E /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A75FDB6E23E3A2C900529352; - remoteInfo = "hidapi-tvOS"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "___PROJECTNAME___.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - 28FD14FF0DC6FC520079059D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; - 28FD15070DC6FC5B0079059D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 944A65681957463F0094A81E /* SDL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL.xcodeproj; path = ../../../Xcode/SDL/SDL.xcodeproj; sourceTree = ""; }; - 945C4F52195AF17F00DBBF61 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; - F3A497AB2555F0BD00E92A8B /* CoreHaptics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreHaptics.framework; path = System/Library/Frameworks/CoreHaptics.framework; sourceTree = SDKROOT; }; - F3A497AF2555F0FF00E92A8B /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; - F3A497B22555F11600E92A8B /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; - FA8B4B96196703B400F8EB7C /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; - FAE0E9641BAF967F0098DFA4 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; - FD779EDD0E26BA1200F39101 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; - FD77A07C0E26BD8C00F39101 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; - FD77A07E0E26BDA900F39101 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; - FD77A0840E26BDB800F39101 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; - FD77A09C0E26BDE500F39101 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; - FDB8BFC50E5A0F6A00980157 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F3A497AD2555F0C000E92A8B /* libSDL2.a in Frameworks */, - FD77A0850E26BDB800F39101 /* AudioToolbox.framework in Frameworks */, - F3A497B32555F11600E92A8B /* AVFoundation.framework in Frameworks */, - 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, - FD779EDE0E26BA1200F39101 /* CoreAudio.framework in Frameworks */, - FDB8BFC60E5A0F6A00980157 /* CoreGraphics.framework in Frameworks */, - F3A497AC2555F0BD00E92A8B /* CoreHaptics.framework in Frameworks */, - FA8B4B97196703B400F8EB7C /* CoreMotion.framework in Frameworks */, - FAE0E9651BAF967F0098DFA4 /* GameController.framework in Frameworks */, - F3A497B02555F0FF00E92A8B /* Metal.framework in Frameworks */, - 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */, - 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */, - 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 19C28FACFE9D520D11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */, - ); - name = Products; - sourceTree = ""; - }; - 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { - isa = PBXGroup; - children = ( - 945C4F52195AF17F00DBBF61 /* Default-568h@2x.png */, - 29B97315FDCFA39411CA2CEA /* Sources */, - 29B97317FDCFA39411CA2CEA /* Resources */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, - 19C28FACFE9D520D11CA2CBB /* Products */, - ); - name = CustomTemplate; - sourceTree = ""; - }; - 29B97315FDCFA39411CA2CEA /* Sources */ = { - isa = PBXGroup; - children = ( - 944A65681957463F0094A81E /* SDL.xcodeproj */, - FD77A09C0E26BDE500F39101 /* main.c */, - ); - name = Sources; - sourceTree = ""; - }; - 29B97317FDCFA39411CA2CEA /* Resources */ = { - isa = PBXGroup; - children = ( - FD77A07E0E26BDA900F39101 /* Default.png */, - FD77A07C0E26BD8C00F39101 /* Icon.png */, - 8D1107310486CEB800E47090 /* Info.plist */, - ); - name = Resources; - sourceTree = ""; - }; - 29B97323FDCFA39411CA2CEA /* Frameworks */ = { - isa = PBXGroup; - children = ( - F3A497B22555F11600E92A8B /* AVFoundation.framework */, - F3A497AF2555F0FF00E92A8B /* Metal.framework */, - F3A497AB2555F0BD00E92A8B /* CoreHaptics.framework */, - FAE0E9641BAF967F0098DFA4 /* GameController.framework */, - FA8B4B96196703B400F8EB7C /* CoreMotion.framework */, - FDB8BFC50E5A0F6A00980157 /* CoreGraphics.framework */, - FD77A0840E26BDB800F39101 /* AudioToolbox.framework */, - FD779EDD0E26BA1200F39101 /* CoreAudio.framework */, - 28FD15070DC6FC5B0079059D /* QuartzCore.framework */, - 28FD14FF0DC6FC520079059D /* OpenGLES.framework */, - 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, - 1D30AB110D05D00D00671497 /* Foundation.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - F3A497772555F07100E92A8B /* Products */ = { - isa = PBXGroup; - children = ( - F3A497872555F07100E92A8B /* SDL2.framework */, - F3A497892555F07100E92A8B /* SDL2.framework */, - F3A4978B2555F07100E92A8B /* SDL2.framework */, - F3A4978D2555F07100E92A8B /* libSDL2.a */, - F3A4978F2555F07100E92A8B /* libSDL2.a */, - F3A497912555F07100E92A8B /* libSDL2.a */, - F3A497932555F07100E92A8B /* libSDL2.dylib */, - F3A497952555F07100E92A8B /* libSDL2.dylib */, - F3A497972555F07100E92A8B /* libSDL2.dylib */, - F3A497992555F07100E92A8B /* SDL2 */, - F3A4979B2555F07100E92A8B /* hidapi.framework */, - F3A4979D2555F07100E92A8B /* hidapi.framework */, - F3A4979F2555F07100E92A8B /* hidapi.framework */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */; - buildPhases = ( - 1D60588D0D05DD3D006BFB54 /* Resources */, - 1D60588E0D05DD3D006BFB54 /* Sources */, - 1D60588F0D05DD3D006BFB54 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "___PROJECTNAME___"; - productName = "___PROJECTNAME___"; - productReference = 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0510; - }; - buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = F3A497772555F07100E92A8B /* Products */; - ProjectRef = 944A65681957463F0094A81E /* SDL.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - F3A497872555F07100E92A8B /* SDL2.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = SDL2.framework; - remoteRef = F3A497862555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A497892555F07100E92A8B /* SDL2.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = SDL2.framework; - remoteRef = F3A497882555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A4978B2555F07100E92A8B /* SDL2.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = SDL2.framework; - remoteRef = F3A4978A2555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A4978D2555F07100E92A8B /* libSDL2.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSDL2.a; - remoteRef = F3A4978C2555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A4978F2555F07100E92A8B /* libSDL2.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSDL2.a; - remoteRef = F3A4978E2555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A497912555F07100E92A8B /* libSDL2.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSDL2.a; - remoteRef = F3A497902555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A497932555F07100E92A8B /* libSDL2.dylib */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.dylib"; - path = libSDL2.dylib; - remoteRef = F3A497922555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A497952555F07100E92A8B /* libSDL2.dylib */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.dylib"; - path = libSDL2.dylib; - remoteRef = F3A497942555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A497972555F07100E92A8B /* libSDL2.dylib */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.dylib"; - path = libSDL2.dylib; - remoteRef = F3A497962555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A497992555F07100E92A8B /* SDL2 */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = SDL2; - remoteRef = F3A497982555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A4979B2555F07100E92A8B /* hidapi.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = hidapi.framework; - remoteRef = F3A4979A2555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A4979D2555F07100E92A8B /* hidapi.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = hidapi.framework; - remoteRef = F3A4979C2555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3A4979F2555F07100E92A8B /* hidapi.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = hidapi.framework; - remoteRef = F3A4979E2555F07100E92A8B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 1D60588D0D05DD3D006BFB54 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - FD77A07D0E26BD8C00F39101 /* Icon.png in Resources */, - FD77A07F0E26BDA900F39101 /* Default.png in Resources */, - 945C4F53195AF17F00DBBF61 /* Default-568h@2x.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 1D60588E0D05DD3D006BFB54 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - FD77A09D0E26BDE500F39101 /* main.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 1D6058940D05DD3E006BFB54 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = ""; - INFOPLIST_FILE = Info.plist; - LIBRARY_SEARCH_PATHS = "$(inherited)"; - PRODUCT_NAME = "___PROJECTNAME___"; - USER_HEADER_SEARCH_PATHS = ../../../include; - }; - name = Debug; - }; - 1D6058950D05DD3E006BFB54 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = ""; - INFOPLIST_FILE = Info.plist; - LIBRARY_SEARCH_PATHS = "$(inherited)"; - PRODUCT_NAME = "___PROJECTNAME___"; - USER_HEADER_SEARCH_PATHS = ../../../include; - }; - name = Release; - }; - C01FCF4F08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - GCC_C_LANGUAGE_STANDARD = c99; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = ""; - PREBINDING = NO; - SDKROOT = iphoneos; - }; - name = Debug; - }; - C01FCF5008A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - GCC_C_LANGUAGE_STANDARD = c99; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - OTHER_CFLAGS = ""; - PREBINDING = NO; - SDKROOT = iphoneos; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1D6058940D05DD3E006BFB54 /* Debug */, - 1D6058950D05DD3E006BFB54 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4F08A954540054247B /* Debug */, - C01FCF5008A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; -} diff --git a/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/main.c b/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/main.c deleted file mode 100644 index 52fd9a49a..000000000 --- a/Engine/lib/sdl/Xcode-iOS/Template/SDL iOS Application/main.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * rectangles.c - * written by Holmes Futrell - * use however you want - */ - -#include "SDL.h" -#include -#include -#include - -#define SCREEN_WIDTH 320 -#define SCREEN_HEIGHT 480 - -int -randomInt(int min, int max) -{ - return min + rand() % (max - min + 1); -} - -void -render(SDL_Renderer *renderer) -{ - - SDL_Rect rect; - Uint8 r, g, b; - - /* Clear the screen */ - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderClear(renderer); - - /* Come up with a random rectangle */ - rect.w = randomInt(64, 128); - rect.h = randomInt(64, 128); - rect.x = randomInt(0, SCREEN_WIDTH); - rect.y = randomInt(0, SCREEN_HEIGHT); - - /* Come up with a random color */ - r = randomInt(50, 255); - g = randomInt(50, 255); - b = randomInt(50, 255); - SDL_SetRenderDrawColor(renderer, r, g, b, 255); - - /* Fill the rectangle in the color */ - SDL_RenderFillRect(renderer, &rect); - - /* update screen */ - SDL_RenderPresent(renderer); -} - -int -main(int argc, char *argv[]) -{ - - SDL_Window *window; - SDL_Renderer *renderer; - int done; - SDL_Event event; - - /* initialize SDL */ - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - printf("Could not initialize SDL\n"); - return 1; - } - - /* seed random number generator */ - srand(time(NULL)); - - /* create window and renderer */ - window = - SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, - SDL_WINDOW_OPENGL); - if (!window) { - printf("Could not initialize Window\n"); - return 1; - } - - renderer = SDL_CreateRenderer(window, -1, 0); - if (!renderer) { - printf("Could not create renderer\n"); - return 1; - } - - /* Enter render loop, waiting for user to quit */ - done = 0; - while (!done) { - while (SDL_PollEvent(&event)) { - if (event.type == SDL_QUIT) { - done = 1; - } - } - render(renderer); - SDL_Delay(1); - } - - /* shutdown SDL */ - SDL_Quit(); - - return 0; -} diff --git a/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist b/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist index ee9ddd564..19049bd46 100644 --- a/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist +++ b/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist @@ -19,10 +19,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.14 + 2.0.21 CFBundleSignature SDLX CFBundleVersion - 2.0.14 + 2.0.21 diff --git a/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj index 3ec037324..cd8affb60 100644 --- a/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -93,6 +93,24 @@ 75E09169241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; 75E0916A241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; 75E0916B241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; + A1626A3E2617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A3F2617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A402617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A412617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A422617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A432617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A442617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A452617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A462617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A522617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A532617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A542617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A552617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A562617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A572617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A582617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A592617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A5A2617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; }; A75FCCFD23E25AB700529352 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; }; @@ -107,7 +125,6 @@ A75FCD0723E25AB700529352 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; A75FCD0823E25AB700529352 /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CA1595D4D800BBD41B /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD0923E25AB700529352 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A75FCD0A23E25AB700529352 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; A75FCD0B23E25AB700529352 /* SDL_shaders_metal_osx.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_osx.h */; }; A75FCD0C23E25AB700529352 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; A75FCD0D23E25AB700529352 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; @@ -123,19 +140,15 @@ A75FCD1723E25AB700529352 /* SDL_clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CD1595D4D800BBD41B /* SDL_clipboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD1823E25AB700529352 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; A75FCD1923E25AB700529352 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; - A75FCD1A23E25AB700529352 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; A75FCD1B23E25AB700529352 /* SDL_config.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CF1595D4D800BBD41B /* SDL_config.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD1C23E25AB700529352 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A75FCD1D23E25AB700529352 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; A75FCD1F23E25AB700529352 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; A75FCD2023E25AB700529352 /* SDL_copying.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D01595D4D800BBD41B /* SDL_copying.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD2123E25AB700529352 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; A75FCD2223E25AB700529352 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; A75FCD2323E25AB700529352 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */; }; - A75FCD2423E25AB700529352 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; A75FCD2523E25AB700529352 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; A75FCD2623E25AB700529352 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; - A75FCD2723E25AB700529352 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; A75FCD2823E25AB700529352 /* SDL_cpuinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D11595D4D800BBD41B /* SDL_cpuinfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD2923E25AB700529352 /* SDL_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D21595D4D800BBD41B /* SDL_endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD2A23E25AB700529352 /* SDL_error.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D31595D4D800BBD41B /* SDL_error.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -144,7 +157,6 @@ A75FCD2D23E25AB700529352 /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD2E23E25AB700529352 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; A75FCD3023E25AB700529352 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; - A75FCD3123E25AB700529352 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; A75FCD3223E25AB700529352 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; A75FCD3323E25AB700529352 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; A75FCD3423E25AB700529352 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; @@ -158,7 +170,6 @@ A75FCD3C23E25AB700529352 /* SDL_hints.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D71595D4D800BBD41B /* SDL_hints.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD3D23E25AB700529352 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; A75FCD3E23E25AB700529352 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; - A75FCD3F23E25AB700529352 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; A75FCD4023E25AB700529352 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; A75FCD4123E25AB700529352 /* SDL_joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D91595D4D800BBD41B /* SDL_joystick.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD4223E25AB700529352 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; @@ -168,16 +179,12 @@ A75FCD4623E25AB700529352 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; A75FCD4723E25AB700529352 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; A75FCD4823E25AB700529352 /* SDL_keycode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DB1595D4D800BBD41B /* SDL_keycode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCD4923E25AB700529352 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; A75FCD4A23E25AB700529352 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; A75FCD4B23E25AB700529352 /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */; }; - A75FCD4C23E25AB700529352 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A75FCD4D23E25AB700529352 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; A75FCD4E23E25AB700529352 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; A75FCD4F23E25AB700529352 /* SDL_loadso.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DC1595D4D800BBD41B /* SDL_loadso.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD5023E25AB700529352 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; A75FCD5123E25AB700529352 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; - A75FCD5223E25AB700529352 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; A75FCD5323E25AB700529352 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; A75FCD5423E25AB700529352 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; A75FCD5523E25AB700529352 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; @@ -201,9 +208,7 @@ A75FCD6723E25AB700529352 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; A75FCD6823E25AB700529352 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; A75FCD6923E25AB700529352 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; - A75FCD6A23E25AB700529352 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; A75FCD6B23E25AB700529352 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; - A75FCD6C23E25AB700529352 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; A75FCD6D23E25AB700529352 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; A75FCD6E23E25AB700529352 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; A75FCD6F23E25AB700529352 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; @@ -213,7 +218,6 @@ A75FCD7323E25AB700529352 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; A75FCD7423E25AB700529352 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; A75FCD7523E25AB700529352 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; - A75FCD7623E25AB700529352 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; A75FCD7723E25AB700529352 /* SDL_name.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E11595D4D800BBD41B /* SDL_name.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD7823E25AB700529352 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; A75FCD7923E25AB700529352 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; @@ -231,14 +235,12 @@ A75FCD8623E25AB700529352 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; A75FCD8723E25AB700529352 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */; }; A75FCD8823E25AB700529352 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; - A75FCD8923E25AB700529352 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; A75FCD8A23E25AB700529352 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; A75FCD8B23E25AB700529352 /* SDL_gamecontrollerdb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamecontrollerdb.h */; }; A75FCD8C23E25AB700529352 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; A75FCD8D23E25AB700529352 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; A75FCD8E23E25AB700529352 /* SDL_pixels.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E51595D4D800BBD41B /* SDL_pixels.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD8F23E25AB700529352 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; - A75FCD9023E25AB700529352 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; A75FCD9123E25AB700529352 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; A75FCD9223E25AB700529352 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; A75FCD9323E25AB700529352 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; @@ -252,7 +254,6 @@ A75FCD9B23E25AB700529352 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; A75FCD9D23E25AB700529352 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; A75FCD9E23E25AB700529352 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; - A75FCD9F23E25AB700529352 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; A75FCDA023E25AB700529352 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; A75FCDA123E25AB700529352 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; A75FCDA223E25AB700529352 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; @@ -267,7 +268,6 @@ A75FCDAB23E25AB700529352 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; A75FCDAC23E25AB700529352 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; A75FCDAD23E25AB700529352 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; - A75FCDAE23E25AB700529352 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; A75FCDAF23E25AB700529352 /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EB1595D4D800BBD41B /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCDB023E25AB700529352 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; A75FCDB123E25AB700529352 /* SDL_rwops.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EC1595D4D800BBD41B /* SDL_rwops.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -319,10 +319,8 @@ A75FCDE123E25AB700529352 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; A75FCDE223E25AB700529352 /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F7195606770073DCDF /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCDE323E25AB700529352 /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F6195606770073DCDF /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCDE423E25AB700529352 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; A75FCDE523E25AB700529352 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; A75FCDE623E25AB700529352 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; - A75FCDE723E25AB700529352 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; A75FCDE923E25AB700529352 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; A75FCDEA23E25AB700529352 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; A75FCDEB23E25AB700529352 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; @@ -335,19 +333,16 @@ A75FCDF223E25AB700529352 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; A75FCDF323E25AB700529352 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; A75FCDF423E25AB700529352 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; - A75FCDF523E25AB700529352 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; A75FCDF623E25AB700529352 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; A75FCDF723E25AB700529352 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; A75FCDF823E25AB700529352 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; A75FCDF923E25AB700529352 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; A75FCDFA23E25AB700529352 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; - A75FCDFB23E25AB700529352 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; A75FCDFC23E25AB700529352 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61B23E2513D00DCD162 /* SDL_uikitmessagebox.m */; }; A75FCDFD23E25AB700529352 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; A75FCDFE23E25AB700529352 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; A75FCDFF23E25AB700529352 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; A75FCE0023E25AB700529352 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; - A75FCE0123E25AB700529352 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; A75FCE0223E25AB700529352 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; A75FCE0323E25AB700529352 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; A75FCE0423E25AB700529352 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; @@ -362,14 +357,12 @@ A75FCE0D23E25AB700529352 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; A75FCE0E23E25AB700529352 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */; }; A75FCE0F23E25AB700529352 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; - A75FCE1023E25AB700529352 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; A75FCE1123E25AB700529352 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; A75FCE1223E25AB700529352 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; A75FCE1323E25AB700529352 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; A75FCE1423E25AB700529352 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; A75FCE1523E25AB700529352 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; A75FCE1623E25AB700529352 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; - A75FCE1723E25AB700529352 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; A75FCE1823E25AB700529352 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; A75FCE1923E25AB700529352 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; A75FCE1A23E25AB700529352 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */; }; @@ -380,7 +373,6 @@ A75FCE1F23E25AB700529352 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; A75FCE2023E25AB700529352 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; A75FCE2123E25AB700529352 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; - A75FCE2223E25AB700529352 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; A75FCE2323E25AB700529352 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; A75FCE2423E25AB700529352 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; A75FCE2523E25AB700529352 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61C23E2513D00DCD162 /* SDL_uikitevents.m */; }; @@ -410,15 +402,10 @@ A75FCE3D23E25AB700529352 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; A75FCE3E23E25AB700529352 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; A75FCE3F23E25AB700529352 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; - A75FCE4023E25AB700529352 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; A75FCE4123E25AB700529352 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A75FCE4223E25AB700529352 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; A75FCE4323E25AB700529352 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; - A75FCE4423E25AB700529352 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; A75FCE4523E25AB700529352 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; A75FCE4623E25AB700529352 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; - A75FCE4723E25AB700529352 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A75FCE4823E25AB700529352 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; A75FCE4923E25AB700529352 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; A75FCE4A23E25AB700529352 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; A75FCE4B23E25AB700529352 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; @@ -433,7 +420,6 @@ A75FCE5423E25AB700529352 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; A75FCE5523E25AB700529352 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; A75FCE5623E25AB700529352 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; - A75FCE5723E25AB700529352 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; A75FCE5823E25AB700529352 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; A75FCE5923E25AB700529352 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; A75FCE5A23E25AB700529352 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; @@ -447,7 +433,6 @@ A75FCE6323E25AB700529352 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; A75FCE6423E25AB700529352 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; A75FCE6523E25AB700529352 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */; }; - A75FCE6623E25AB700529352 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; A75FCE6723E25AB700529352 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; A75FCE6823E25AB700529352 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; A75FCE6A23E25AB700529352 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94023E2514000DCD162 /* SDL_gesture.c */; }; @@ -458,7 +443,6 @@ A75FCE6F23E25AB700529352 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; A75FCE7023E25AB700529352 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; A75FCE7123E25AB700529352 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; - A75FCE7223E25AB700529352 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; A75FCE7323E25AB700529352 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; A75FCE7523E25AB700529352 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; A75FCE7623E25AB700529352 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; @@ -466,7 +450,6 @@ A75FCE7823E25AB700529352 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; A75FCE7923E25AB700529352 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; A75FCE7A23E25AB700529352 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; - A75FCE7B23E25AB700529352 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; A75FCE7C23E25AB700529352 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; A75FCE7D23E25AB700529352 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; A75FCE7E23E25AB700529352 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; @@ -487,22 +470,18 @@ A75FCE8D23E25AB700529352 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */; }; A75FCE8E23E25AB700529352 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; A75FCE8F23E25AB700529352 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; - A75FCE9023E25AB700529352 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; A75FCE9123E25AB700529352 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; A75FCE9223E25AB700529352 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; A75FCE9323E25AB700529352 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; A75FCE9423E25AB700529352 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; A75FCE9523E25AB700529352 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; A75FCE9623E25AB700529352 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; - A75FCE9723E25AB700529352 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; A75FCE9823E25AB700529352 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; - A75FCE9923E25AB700529352 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; A75FCE9A23E25AB700529352 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; A75FCE9B23E25AB700529352 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; A75FCE9C23E25AB700529352 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; A75FCE9D23E25AB700529352 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; A75FCE9F23E25AB700529352 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; - A75FCEA023E25AB700529352 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; A75FCEA123E25AB700529352 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; A75FCEA223E25AB700529352 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; A75FCEA323E25AB700529352 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; @@ -525,7 +504,6 @@ A75FCEC023E25AC700529352 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; A75FCEC123E25AC700529352 /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CA1595D4D800BBD41B /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEC223E25AC700529352 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A75FCEC323E25AC700529352 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; A75FCEC423E25AC700529352 /* SDL_shaders_metal_osx.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_osx.h */; }; A75FCEC523E25AC700529352 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; A75FCEC623E25AC700529352 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; @@ -541,19 +519,15 @@ A75FCED023E25AC700529352 /* SDL_clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CD1595D4D800BBD41B /* SDL_clipboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCED123E25AC700529352 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; A75FCED223E25AC700529352 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; - A75FCED323E25AC700529352 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; A75FCED423E25AC700529352 /* SDL_config.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CF1595D4D800BBD41B /* SDL_config.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCED523E25AC700529352 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A75FCED623E25AC700529352 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; A75FCED823E25AC700529352 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; A75FCED923E25AC700529352 /* SDL_copying.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D01595D4D800BBD41B /* SDL_copying.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEDA23E25AC700529352 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; A75FCEDB23E25AC700529352 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; A75FCEDC23E25AC700529352 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */; }; - A75FCEDD23E25AC700529352 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; A75FCEDE23E25AC700529352 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; A75FCEDF23E25AC700529352 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; - A75FCEE023E25AC700529352 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; A75FCEE123E25AC700529352 /* SDL_cpuinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D11595D4D800BBD41B /* SDL_cpuinfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEE223E25AC700529352 /* SDL_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D21595D4D800BBD41B /* SDL_endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEE323E25AC700529352 /* SDL_error.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D31595D4D800BBD41B /* SDL_error.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -562,7 +536,6 @@ A75FCEE623E25AC700529352 /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEE723E25AC700529352 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; A75FCEE923E25AC700529352 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; - A75FCEEA23E25AC700529352 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; A75FCEEB23E25AC700529352 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; A75FCEEC23E25AC700529352 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; A75FCEED23E25AC700529352 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; @@ -576,7 +549,6 @@ A75FCEF523E25AC700529352 /* SDL_hints.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D71595D4D800BBD41B /* SDL_hints.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEF623E25AC700529352 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; A75FCEF723E25AC700529352 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; - A75FCEF823E25AC700529352 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; A75FCEF923E25AC700529352 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; A75FCEFA23E25AC700529352 /* SDL_joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D91595D4D800BBD41B /* SDL_joystick.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEFB23E25AC700529352 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; @@ -586,16 +558,12 @@ A75FCEFF23E25AC700529352 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; A75FCF0023E25AC700529352 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; A75FCF0123E25AC700529352 /* SDL_keycode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DB1595D4D800BBD41B /* SDL_keycode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCF0223E25AC700529352 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; A75FCF0323E25AC700529352 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; A75FCF0423E25AC700529352 /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */; }; - A75FCF0523E25AC700529352 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A75FCF0623E25AC700529352 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; A75FCF0723E25AC700529352 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; A75FCF0823E25AC700529352 /* SDL_loadso.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DC1595D4D800BBD41B /* SDL_loadso.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF0923E25AC700529352 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; A75FCF0A23E25AC700529352 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; - A75FCF0B23E25AC700529352 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; A75FCF0C23E25AC700529352 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; A75FCF0D23E25AC700529352 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; A75FCF0E23E25AC700529352 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; @@ -619,9 +587,7 @@ A75FCF2023E25AC700529352 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; A75FCF2123E25AC700529352 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; A75FCF2223E25AC700529352 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; - A75FCF2323E25AC700529352 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; A75FCF2423E25AC700529352 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; - A75FCF2523E25AC700529352 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; A75FCF2623E25AC700529352 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; A75FCF2723E25AC700529352 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; A75FCF2823E25AC700529352 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; @@ -631,7 +597,6 @@ A75FCF2C23E25AC700529352 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; A75FCF2D23E25AC700529352 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; A75FCF2E23E25AC700529352 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; - A75FCF2F23E25AC700529352 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; A75FCF3023E25AC700529352 /* SDL_name.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E11595D4D800BBD41B /* SDL_name.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF3123E25AC700529352 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; A75FCF3223E25AC700529352 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; @@ -649,14 +614,12 @@ A75FCF3F23E25AC700529352 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; A75FCF4023E25AC700529352 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */; }; A75FCF4123E25AC700529352 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; - A75FCF4223E25AC700529352 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; A75FCF4323E25AC700529352 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; A75FCF4423E25AC700529352 /* SDL_gamecontrollerdb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamecontrollerdb.h */; }; A75FCF4523E25AC700529352 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; A75FCF4623E25AC700529352 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; A75FCF4723E25AC700529352 /* SDL_pixels.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E51595D4D800BBD41B /* SDL_pixels.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF4823E25AC700529352 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; - A75FCF4923E25AC700529352 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; A75FCF4A23E25AC700529352 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; A75FCF4B23E25AC700529352 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; A75FCF4C23E25AC700529352 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; @@ -670,7 +633,6 @@ A75FCF5423E25AC700529352 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; A75FCF5623E25AC700529352 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; A75FCF5723E25AC700529352 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; - A75FCF5823E25AC700529352 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; A75FCF5923E25AC700529352 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; A75FCF5A23E25AC700529352 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; A75FCF5B23E25AC700529352 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; @@ -685,7 +647,6 @@ A75FCF6423E25AC700529352 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; A75FCF6523E25AC700529352 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; A75FCF6623E25AC700529352 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; - A75FCF6723E25AC700529352 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; A75FCF6823E25AC700529352 /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EB1595D4D800BBD41B /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF6923E25AC700529352 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; A75FCF6A23E25AC700529352 /* SDL_rwops.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EC1595D4D800BBD41B /* SDL_rwops.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -737,10 +698,8 @@ A75FCF9A23E25AC700529352 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; A75FCF9B23E25AC700529352 /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F7195606770073DCDF /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF9C23E25AC700529352 /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F6195606770073DCDF /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCF9D23E25AC700529352 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; A75FCF9E23E25AC700529352 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; A75FCF9F23E25AC700529352 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; - A75FCFA023E25AC700529352 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; A75FCFA223E25AC700529352 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; A75FCFA323E25AC700529352 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; A75FCFA423E25AC700529352 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; @@ -753,19 +712,16 @@ A75FCFAB23E25AC700529352 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; A75FCFAC23E25AC700529352 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; A75FCFAD23E25AC700529352 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; - A75FCFAE23E25AC700529352 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; A75FCFAF23E25AC700529352 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; A75FCFB023E25AC700529352 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; A75FCFB123E25AC700529352 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; A75FCFB223E25AC700529352 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; A75FCFB323E25AC700529352 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; - A75FCFB423E25AC700529352 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; A75FCFB523E25AC700529352 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61B23E2513D00DCD162 /* SDL_uikitmessagebox.m */; }; A75FCFB623E25AC700529352 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; A75FCFB723E25AC700529352 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; A75FCFB823E25AC700529352 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; A75FCFB923E25AC700529352 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; - A75FCFBA23E25AC700529352 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; A75FCFBB23E25AC700529352 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; A75FCFBC23E25AC700529352 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; A75FCFBD23E25AC700529352 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; @@ -780,14 +736,12 @@ A75FCFC623E25AC700529352 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; A75FCFC723E25AC700529352 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */; }; A75FCFC823E25AC700529352 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; - A75FCFC923E25AC700529352 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; A75FCFCA23E25AC700529352 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; A75FCFCB23E25AC700529352 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; A75FCFCC23E25AC700529352 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; A75FCFCD23E25AC700529352 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; A75FCFCE23E25AC700529352 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; A75FCFCF23E25AC700529352 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; - A75FCFD023E25AC700529352 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; A75FCFD123E25AC700529352 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; A75FCFD223E25AC700529352 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; A75FCFD323E25AC700529352 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */; }; @@ -798,7 +752,6 @@ A75FCFD823E25AC700529352 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; A75FCFD923E25AC700529352 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; A75FCFDA23E25AC700529352 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; - A75FCFDB23E25AC700529352 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; A75FCFDC23E25AC700529352 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; A75FCFDD23E25AC700529352 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; A75FCFDE23E25AC700529352 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61C23E2513D00DCD162 /* SDL_uikitevents.m */; }; @@ -828,15 +781,10 @@ A75FCFF623E25AC700529352 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; A75FCFF723E25AC700529352 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; A75FCFF823E25AC700529352 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; - A75FCFF923E25AC700529352 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; A75FCFFA23E25AC700529352 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A75FCFFB23E25AC700529352 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; A75FCFFC23E25AC700529352 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; - A75FCFFD23E25AC700529352 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; A75FCFFE23E25AC700529352 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; A75FCFFF23E25AC700529352 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; - A75FD00023E25AC700529352 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A75FD00123E25AC700529352 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; A75FD00223E25AC700529352 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; A75FD00323E25AC700529352 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; A75FD00423E25AC700529352 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; @@ -851,7 +799,6 @@ A75FD00D23E25AC700529352 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; A75FD00E23E25AC700529352 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; A75FD00F23E25AC700529352 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; - A75FD01023E25AC700529352 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; A75FD01123E25AC700529352 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; A75FD01223E25AC700529352 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; A75FD01323E25AC700529352 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; @@ -865,7 +812,6 @@ A75FD01C23E25AC700529352 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; A75FD01D23E25AC700529352 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; A75FD01E23E25AC700529352 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */; }; - A75FD01F23E25AC700529352 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; A75FD02023E25AC700529352 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; A75FD02123E25AC700529352 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; A75FD02323E25AC700529352 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94023E2514000DCD162 /* SDL_gesture.c */; }; @@ -876,7 +822,6 @@ A75FD02823E25AC700529352 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; A75FD02923E25AC700529352 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; A75FD02A23E25AC700529352 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; - A75FD02B23E25AC700529352 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; A75FD02C23E25AC700529352 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; A75FD02E23E25AC700529352 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; A75FD02F23E25AC700529352 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; @@ -884,7 +829,6 @@ A75FD03123E25AC700529352 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; A75FD03223E25AC700529352 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; A75FD03323E25AC700529352 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; - A75FD03423E25AC700529352 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; A75FD03523E25AC700529352 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; A75FD03623E25AC700529352 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; A75FD03723E25AC700529352 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; @@ -905,22 +849,18 @@ A75FD04623E25AC700529352 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */; }; A75FD04723E25AC700529352 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; A75FD04823E25AC700529352 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; - A75FD04923E25AC700529352 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; A75FD04A23E25AC700529352 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; A75FD04B23E25AC700529352 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; A75FD04C23E25AC700529352 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; A75FD04D23E25AC700529352 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; A75FD04E23E25AC700529352 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; A75FD04F23E25AC700529352 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; - A75FD05023E25AC700529352 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; A75FD05123E25AC700529352 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; - A75FD05223E25AC700529352 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; A75FD05323E25AC700529352 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; A75FD05423E25AC700529352 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; A75FD05523E25AC700529352 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; A75FD05623E25AC700529352 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; A75FD05823E25AC700529352 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; - A75FD05923E25AC700529352 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; A75FD05A23E25AC700529352 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; A75FD05B23E25AC700529352 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; A75FD05C23E25AC700529352 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; @@ -941,8 +881,6 @@ A75FDAF923E35ED500529352 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDAF523E35EC400529352 /* SDL_config_iphoneos.h */; }; A75FDAFA23E35ED600529352 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDAF523E35EC400529352 /* SDL_config_iphoneos.h */; }; A75FDAFB23E35ED700529352 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDAF523E35EC400529352 /* SDL_config_iphoneos.h */; }; - A75FDB5323E39D1C00529352 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; - A75FDB5523E39DAC00529352 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAC323E28BA700529352 /* CoreBluetooth.framework */; }; A75FDB5823E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; A75FDB5923E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; A75FDB5A23E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; @@ -952,33 +890,6 @@ A75FDB5E23E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; A75FDB5F23E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; A75FDB6023E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; - A75FDB6123E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FDB6423E3A2C900529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FDB6623E3A2C900529352 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; - A75FDB6823E3A2C900529352 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAC323E28BA700529352 /* CoreBluetooth.framework */; }; - A75FDB8223E4C74400529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FDB9323E4C8DB00529352 /* hid.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDB9223E4C8DB00529352 /* hid.c */; }; - A75FDB9423E4C91300529352 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; }; - A75FDB9523E4C93600529352 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; - A75FDB9A23E4CAEF00529352 /* hidapi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB8C23E4C74400529352 /* hidapi.framework */; }; - A75FDB9B23E4CAEF00529352 /* hidapi.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB8C23E4C74400529352 /* hidapi.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - A75FDB9D23E4CAFA00529352 /* hidapi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB4923E399AC00529352 /* hidapi.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - A75FDBA023E4CAFF00529352 /* hidapi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB6E23E3A2C900529352 /* hidapi.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - A75FDBA823E4CB7000529352 /* LICENSE-bsd.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA323E4CB6F00529352 /* LICENSE-bsd.txt */; }; - A75FDBA923E4CB7000529352 /* LICENSE-bsd.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA323E4CB6F00529352 /* LICENSE-bsd.txt */; }; - A75FDBAA23E4CB7000529352 /* LICENSE-bsd.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA323E4CB6F00529352 /* LICENSE-bsd.txt */; }; - A75FDBAB23E4CB7000529352 /* AUTHORS.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA423E4CB6F00529352 /* AUTHORS.txt */; }; - A75FDBAC23E4CB7000529352 /* AUTHORS.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA423E4CB6F00529352 /* AUTHORS.txt */; }; - A75FDBAD23E4CB7000529352 /* AUTHORS.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA423E4CB6F00529352 /* AUTHORS.txt */; }; - A75FDBAE23E4CB7000529352 /* LICENSE-orig.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA523E4CB6F00529352 /* LICENSE-orig.txt */; }; - A75FDBAF23E4CB7000529352 /* LICENSE-orig.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA523E4CB6F00529352 /* LICENSE-orig.txt */; }; - A75FDBB023E4CB7000529352 /* LICENSE-orig.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA523E4CB6F00529352 /* LICENSE-orig.txt */; }; - A75FDBB123E4CB7000529352 /* LICENSE-gpl3.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA623E4CB6F00529352 /* LICENSE-gpl3.txt */; }; - A75FDBB223E4CB7000529352 /* LICENSE-gpl3.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA623E4CB6F00529352 /* LICENSE-gpl3.txt */; }; - A75FDBB323E4CB7000529352 /* LICENSE-gpl3.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA623E4CB6F00529352 /* LICENSE-gpl3.txt */; }; - A75FDBB423E4CB7000529352 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA723E4CB6F00529352 /* LICENSE.txt */; }; - A75FDBB523E4CB7000529352 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA723E4CB6F00529352 /* LICENSE.txt */; }; - A75FDBB623E4CB7000529352 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA723E4CB6F00529352 /* LICENSE.txt */; }; A75FDBB723E4CBC700529352 /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 00794D3F09D0C461003FC8A1 /* License.txt */; }; A75FDBB823E4CBC700529352 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = F59C710300D5CB5801000001 /* ReadMe.txt */; }; A75FDBB923E4CBC700529352 /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 00794D3F09D0C461003FC8A1 /* License.txt */; }; @@ -1009,7 +920,6 @@ A769B08D23E259AE00872273 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60D23E2513D00DCD162 /* SDL_shape_internals.h */; }; A769B08E23E259AE00872273 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; A769B09023E259AE00872273 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A769B09123E259AE00872273 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; A769B09223E259AE00872273 /* SDL_shaders_metal_osx.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_osx.h */; }; A769B09323E259AE00872273 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; A769B09423E259AE00872273 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; @@ -1021,21 +931,16 @@ A769B09D23E259AE00872273 /* SDL_haptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5C623E2513D00DCD162 /* SDL_haptic_c.h */; }; A769B09F23E259AE00872273 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; A769B0A023E259AE00872273 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; - A769B0A123E259AE00872273 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; A769B0A323E259AE00872273 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A769B0A423E259AE00872273 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; A769B0A623E259AE00872273 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; A769B0A823E259AE00872273 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; A769B0A923E259AE00872273 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; A769B0AA23E259AE00872273 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */; }; - A769B0AB23E259AE00872273 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; A769B0AC23E259AE00872273 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; A769B0AD23E259AE00872273 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; - A769B0AE23E259AE00872273 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; A769B0B323E259AE00872273 /* SDL_blendfillrect.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */; }; A769B0B523E259AE00872273 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; A769B0B623E259AE00872273 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; - A769B0B723E259AE00872273 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; A769B0B823E259AE00872273 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; A769B0B923E259AE00872273 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; A769B0BA23E259AE00872273 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; @@ -1046,22 +951,17 @@ A769B0C123E259AE00872273 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; A769B0C323E259AE00872273 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; A769B0C423E259AE00872273 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; - A769B0C523E259AE00872273 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; A769B0C623E259AE00872273 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; A769B0C823E259AE00872273 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; A769B0CA23E259AE00872273 /* SDL_uikitevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62D23E2513D00DCD162 /* SDL_uikitevents.h */; }; A769B0CB23E259AE00872273 /* SDL_gesture_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93023E2514000DCD162 /* SDL_gesture_c.h */; }; A769B0CC23E259AE00872273 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; A769B0CD23E259AE00872273 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; - A769B0CF23E259AE00872273 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; A769B0D023E259AE00872273 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; A769B0D123E259AE00872273 /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */; }; - A769B0D223E259AE00872273 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A769B0D323E259AE00872273 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; A769B0D423E259AE00872273 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; A769B0D623E259AE00872273 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; A769B0D723E259AE00872273 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; - A769B0D823E259AE00872273 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; A769B0D923E259AE00872273 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; A769B0DA23E259AE00872273 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; A769B0DB23E259AE00872273 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; @@ -1083,16 +983,13 @@ A769B0EF23E259AE00872273 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; A769B0F023E259AE00872273 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; A769B0F123E259AE00872273 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; - A769B0F223E259AE00872273 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; A769B0F323E259AE00872273 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; - A769B0F423E259AE00872273 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; A769B0F523E259AE00872273 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; A769B0F623E259AE00872273 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; A769B0F723E259AE00872273 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; A769B0FB23E259AE00872273 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; A769B0FC23E259AE00872273 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; A769B0FD23E259AE00872273 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; - A769B0FE23E259AE00872273 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; A769B10023E259AE00872273 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; A769B10123E259AE00872273 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; A769B10223E259AE00872273 /* math_private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A91B23E2514000DCD162 /* math_private.h */; }; @@ -1105,13 +1002,11 @@ A769B10C23E259AE00872273 /* SDL_nullevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60B23E2513D00DCD162 /* SDL_nullevents_c.h */; }; A769B10D23E259AE00872273 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; A769B10E23E259AE00872273 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; - A769B10F23E259AE00872273 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; A769B11023E259AE00872273 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; A769B11123E259AE00872273 /* SDL_gamecontrollerdb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamecontrollerdb.h */; }; A769B11223E259AE00872273 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; A769B11323E259AE00872273 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; A769B11523E259AE00872273 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; - A769B11723E259AE00872273 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; A769B11823E259AE00872273 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; A769B11A23E259AE00872273 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; A769B11B23E259AE00872273 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; @@ -1123,7 +1018,6 @@ A769B12323E259AE00872273 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; A769B12523E259AE00872273 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; A769B12623E259AE00872273 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; - A769B12723E259AE00872273 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; A769B12823E259AE00872273 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; A769B12923E259AE00872273 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; A769B12A23E259AE00872273 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; @@ -1135,7 +1029,6 @@ A769B13323E259AE00872273 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; A769B13423E259AE00872273 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; A769B13523E259AE00872273 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; - A769B13623E259AE00872273 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; A769B13823E259AE00872273 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; A769B13B23E259AE00872273 /* SDL_cocoaclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */; }; A769B13C23E259AE00872273 /* SDL_cocoamodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69123E2513E00DCD162 /* SDL_cocoamodes.h */; }; @@ -1168,10 +1061,8 @@ A769B16123E259AE00872273 /* usb_ids.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CB23E2513E00DCD162 /* usb_ids.h */; }; A769B16323E259AE00872273 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; }; A769B16923E259AE00872273 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; - A769B16C23E259AE00872273 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; A769B16D23E259AE00872273 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; A769B16E23E259AE00872273 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; - A769B16F23E259AE00872273 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; A769B17123E259AE00872273 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; A769B17223E259AE00872273 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; A769B17323E259AE00872273 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; @@ -1184,19 +1075,16 @@ A769B17A23E259AE00872273 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; A769B17B23E259AE00872273 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; A769B17C23E259AE00872273 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; - A769B17D23E259AE00872273 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; A769B17E23E259AE00872273 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; A769B17F23E259AE00872273 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; A769B18023E259AE00872273 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; A769B18123E259AE00872273 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; A769B18223E259AE00872273 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; - A769B18423E259AE00872273 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; A769B18523E259AE00872273 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61B23E2513D00DCD162 /* SDL_uikitmessagebox.m */; }; A769B18623E259AE00872273 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; A769B18723E259AE00872273 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; A769B18823E259AE00872273 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; A769B18923E259AE00872273 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; - A769B18A23E259AE00872273 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; A769B18B23E259AE00872273 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; A769B18C23E259AE00872273 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; A769B18D23E259AE00872273 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; @@ -1211,14 +1099,12 @@ A769B19623E259AE00872273 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; A769B19723E259AE00872273 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */; }; A769B19823E259AE00872273 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; - A769B19923E259AE00872273 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; A769B19A23E259AE00872273 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; A769B19B23E259AE00872273 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; A769B19C23E259AE00872273 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; A769B19D23E259AE00872273 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; A769B19E23E259AE00872273 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; A769B19F23E259AE00872273 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; - A769B1A023E259AE00872273 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; A769B1A123E259AE00872273 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; A769B1A223E259AE00872273 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; A769B1A323E259AE00872273 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */; }; @@ -1229,7 +1115,6 @@ A769B1A823E259AE00872273 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; A769B1A923E259AE00872273 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; A769B1AA23E259AE00872273 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; - A769B1AB23E259AE00872273 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; A769B1AC23E259AE00872273 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; A769B1AD23E259AE00872273 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; A769B1AE23E259AE00872273 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61C23E2513D00DCD162 /* SDL_uikitevents.m */; }; @@ -1260,15 +1145,10 @@ A769B1C723E259AE00872273 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; A769B1C823E259AE00872273 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; A769B1C923E259AE00872273 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; - A769B1CA23E259AE00872273 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; A769B1CB23E259AE00872273 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A769B1CC23E259AE00872273 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; A769B1CD23E259AE00872273 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; - A769B1CE23E259AE00872273 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; A769B1CF23E259AE00872273 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; A769B1D023E259AE00872273 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; - A769B1D123E259AE00872273 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A769B1D223E259AE00872273 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; A769B1D323E259AE00872273 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; A769B1D423E259AE00872273 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; A769B1D523E259AE00872273 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; @@ -1283,7 +1163,6 @@ A769B1DE23E259AE00872273 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; A769B1DF23E259AE00872273 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; A769B1E023E259AE00872273 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; - A769B1E123E259AE00872273 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; A769B1E223E259AE00872273 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; A769B1E423E259AE00872273 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; A769B1E523E259AE00872273 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; @@ -1298,7 +1177,6 @@ A769B1EF23E259AE00872273 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; A769B1F023E259AE00872273 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; A769B1F123E259AE00872273 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */; }; - A769B1F223E259AE00872273 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; A769B1F323E259AE00872273 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; A769B1F423E259AE00872273 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; A769B1F623E259AE00872273 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94023E2514000DCD162 /* SDL_gesture.c */; }; @@ -1309,7 +1187,6 @@ A769B1FB23E259AE00872273 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; A769B1FC23E259AE00872273 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; A769B1FD23E259AE00872273 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; - A769B1FE23E259AE00872273 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; A769B1FF23E259AE00872273 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; A769B20123E259AE00872273 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; A769B20223E259AE00872273 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; @@ -1317,7 +1194,6 @@ A769B20423E259AE00872273 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; A769B20523E259AE00872273 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; A769B20623E259AE00872273 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; - A769B20723E259AE00872273 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; A769B20823E259AE00872273 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; A769B20923E259AE00872273 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; A769B20A23E259AE00872273 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; @@ -1337,22 +1213,18 @@ A769B21823E259AE00872273 /* SDL_uikitmetalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62E23E2513D00DCD162 /* SDL_uikitmetalview.m */; }; A769B21923E259AE00872273 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; A769B21A23E259AE00872273 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; - A769B21B23E259AE00872273 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; A769B21C23E259AE00872273 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; A769B21D23E259AE00872273 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; A769B21E23E259AE00872273 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; A769B21F23E259AE00872273 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; A769B22023E259AE00872273 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; A769B22123E259AE00872273 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; - A769B22223E259AE00872273 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; A769B22323E259AE00872273 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; - A769B22423E259AE00872273 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; A769B22523E259AE00872273 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; A769B22623E259AE00872273 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; A769B22723E259AE00872273 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; A769B22823E259AE00872273 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; A769B22923E259AE00872273 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; - A769B22A23E259AE00872273 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; A769B22B23E259AE00872273 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; A769B22C23E259AE00872273 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; A769B22D23E259AE00872273 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; @@ -2062,12 +1934,6 @@ A7D8AEBB23E2514100DCD162 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; A7D8AEBC23E2514100DCD162 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; A7D8AEBD23E2514100DCD162 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; - A7D8AEBE23E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; - A7D8AEBF23E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; - A7D8AEC023E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; - A7D8AEC123E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; - A7D8AEC223E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; - A7D8AEC323E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; A7D8AEC423E2514100DCD162 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; A7D8AEC523E2514100DCD162 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; A7D8AEC623E2514100DCD162 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; @@ -2152,12 +2018,6 @@ A7D8AF1523E2514100DCD162 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; A7D8AF1623E2514100DCD162 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; A7D8AF1723E2514100DCD162 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; - A7D8AF1823E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; - A7D8AF1923E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; - A7D8AF1A23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; - A7D8AF1B23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; - A7D8AF1C23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; - A7D8AF1D23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; A7D8AF1E23E2514100DCD162 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; A7D8AF1F23E2514100DCD162 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; A7D8AF2023E2514100DCD162 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; @@ -2182,228 +2042,6 @@ A7D8B14323E2514200DCD162 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; A7D8B14423E2514200DCD162 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; A7D8B14523E2514200DCD162 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; - A7D8B14623E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14723E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14823E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14923E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14A23E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14B23E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14C23E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B14D23E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B14E23E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B14F23E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B15023E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B15123E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B15223E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15323E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15423E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15523E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15623E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15723E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15823E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15923E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15A23E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15B23E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15C23E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15D23E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15E23E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B15F23E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B16023E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B16123E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B16223E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B16323E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B16423E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16523E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16623E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16723E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16823E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16923E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16A23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B16B23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B16C23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B16D23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B16E23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B16F23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B17023E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17123E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17223E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17323E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17423E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17523E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17623E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17723E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17823E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17923E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17A23E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17B23E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17C23E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B17D23E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B17E23E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B17F23E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B18023E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B18123E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B18223E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18323E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18423E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18523E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18623E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18723E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18823E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18923E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18A23E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18B23E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18C23E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18D23E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18E23E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B18F23E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B19023E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B19123E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B19223E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B19323E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B19423E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19523E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19623E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19723E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19823E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19923E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19A23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B19B23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B19C23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B19D23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B19E23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B19F23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B1A023E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A123E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A223E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A323E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A423E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A523E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A623E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1A723E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1A823E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1A923E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1AA23E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1AB23E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1AC23E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1AD23E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1AE23E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1AF23E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1B023E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1B123E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1B223E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B323E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B423E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B523E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B623E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B723E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B823E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1B923E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1BA23E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1BB23E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1BC23E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1BD23E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1BE23E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1BF23E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1C023E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1C123E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1C223E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1C323E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1C423E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1C523E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1C623E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1C723E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1C823E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1C923E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1CA23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1CB23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1CC23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1CD23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1CE23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1CF23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1D023E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D123E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D223E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D323E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D423E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D523E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D623E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1D723E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1D823E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1D923E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1DA23E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1DB23E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1DC23E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1DD23E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1DE23E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1DF23E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1E023E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1E123E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1E223E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E323E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E423E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E523E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E623E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E723E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E823E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1E923E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1EA23E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1EB23E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1EC23E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1ED23E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1EE23E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1EF23E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1F023E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1F123E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1F223E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1F323E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1F423E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1F523E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1F623E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1F723E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1F823E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1F923E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1FA23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B1FB23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B1FC23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B1FD23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B1FE23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B1FF23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B20023E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20123E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20223E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20323E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20423E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20523E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20623E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20723E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20823E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20923E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20A23E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20B23E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20C23E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B20D23E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B20E23E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B20F23E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B21023E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B21123E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B21223E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21323E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21423E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21523E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21623E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21723E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21823E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21923E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21A23E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21B23E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21C23E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21D23E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21E23E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A7D8B21F23E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A7D8B22023E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A7D8B22123E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A7D8B22223E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A7D8B22323E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; A7D8B22423E2514200DCD162 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; A7D8B22523E2514200DCD162 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; A7D8B22623E2514200DCD162 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; @@ -3728,9 +3366,8 @@ DB31408D17554D3C006C0E22 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFA89C106B4BA100758660 /* ForceFeedback.framework */; }; F3631C6424884ACF004F28EA /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26792462701100718109 /* SDL_locale.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3631C652488534E004F28EA /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26792462701100718109 /* SDL_locale.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F376F6192559B29300CFC0BC /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6182559B29300CFC0BC /* OpenGLES.framework */; }; + F376F6192559B29300CFC0BC /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6182559B29300CFC0BC /* OpenGLES.framework */; platformFilter = ios; }; F376F61B2559B2AF00CFC0BC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F61A2559B2AF00CFC0BC /* UIKit.framework */; }; - F376F6262559B30000CFC0BC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F61A2559B2AF00CFC0BC /* UIKit.framework */; }; F376F6322559B31D00CFC0BC /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6312559B31D00CFC0BC /* GameController.framework */; }; F376F6332559B33D00CFC0BC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; }; F376F63E2559B35200CFC0BC /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDABF23E28B8000529352 /* CoreMotion.framework */; }; @@ -3739,17 +3376,14 @@ F376F6552559B4E300CFC0BC /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; F376F6762559B4E500CFC0BC /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; F376F68D2559B4E900CFC0BC /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; - F376F6CD2559B54500CFC0BC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6CC2559B54500CFC0BC /* UIKit.framework */; }; F376F6D92559B59600CFC0BC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6D82559B59600CFC0BC /* AudioToolbox.framework */; }; F376F6DB2559B5A000CFC0BC /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6DA2559B5A000CFC0BC /* AVFoundation.framework */; }; F376F6DD2559B5A900CFC0BC /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6DC2559B5A900CFC0BC /* OpenGLES.framework */; }; F376F6DF2559B5BA00CFC0BC /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6DE2559B5BA00CFC0BC /* GameController.framework */; }; F376F6EC2559B5DA00CFC0BC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6CC2559B54500CFC0BC /* UIKit.framework */; }; F376F6F82559B5EC00CFC0BC /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6F72559B5EC00CFC0BC /* CoreGraphics.framework */; }; - F376F70D2559B6A000CFC0BC /* hidapi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB4923E399AC00529352 /* hidapi.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; F376F70E2559B6B800CFC0BC /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6182559B29300CFC0BC /* OpenGLES.framework */; }; F376F70F2559B6BF00CFC0BC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F61A2559B2AF00CFC0BC /* UIKit.framework */; }; - F376F71A2559B70B00CFC0BC /* hidapi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB6E23E3A2C900529352 /* hidapi.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; F376F71B2559B71C00CFC0BC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6D82559B59600CFC0BC /* AudioToolbox.framework */; }; F376F71C2559B72900CFC0BC /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6DA2559B5A000CFC0BC /* AVFoundation.framework */; }; F376F71D2559B73200CFC0BC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6CC2559B54500CFC0BC /* UIKit.framework */; }; @@ -3763,6 +3397,27 @@ F376F7332559B79B00CFC0BC /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6DE2559B5BA00CFC0BC /* GameController.framework */; }; F37DC5F325350EBC0002E6F7 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; F37DC5F525350ECC0002E6F7 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F425350ECC0002E6F7 /* CoreHaptics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + F38233852738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F38233862738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F38233872738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F382338B2738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F382338C2738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F382338D2738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F382338E2738EBEC00F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F382338F2738EBEF00F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F38233902738EBF000F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F38233912738EBF100F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F38233922738EBF300F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F38233932738EBF300F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F38233942738EC1400F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F38233952738EC1500F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F38233962738EC1600F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F38233972738EC1600F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F38233982738EC1800F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F38233992738EC1800F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F382339A2738ED5600F7F527 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAC323E28BA700529352 /* CoreBluetooth.framework */; }; + F382339C2738ED6600F7F527 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F382339B2738ED6600F7F527 /* CoreBluetooth.framework */; }; + F382339D2738EE3F00F7F527 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F382339B2738ED6600F7F527 /* CoreBluetooth.framework */; }; F3928194258603F1003191A7 /* SDL_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4F252BB2BE005D5928 /* SDL_misc.h */; settings = {ATTRIBUTES = (Public, ); }; }; F392819F25860422003191A7 /* SDL_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4F252BB2BE005D5928 /* SDL_misc.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3942659253579B400B03694 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; @@ -3796,13 +3451,13 @@ F395C1A22569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; F395C1A32569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; F395C1A42569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; - F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; F395C1B22569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; F395C1B32569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; - F395C1B42569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1B42569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; F395C1B52569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; F395C1B62569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; - F395C1B72569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1B72569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; F395C1B82569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; F395C1B92569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; F395C1BA2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; @@ -3814,6 +3469,15 @@ F395C1C02569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; F395C1C12569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; F395C1C22569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; + F3984CD025BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD125BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD225BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD325BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD425BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD525BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD625BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD725BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD825BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; F3A4909E2554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; F3A4909F2554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; F3A490A02554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; @@ -3829,6 +3493,15 @@ F3ADAB912576F0B400A6B1D9 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */; }; F3ADAB922576F0B400A6B1D9 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */; }; F3ADAB932576F0B400A6B1D9 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */; }; + F3F07D5A269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D5B269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D5C269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D5D269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D5E269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D5F269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D60269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D61269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D62269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; FA24348B21D41FFB00B8918A /* SDL_metal.h in Headers */ = {isa = PBXBuildFile; fileRef = FA24348A21D41FFB00B8918A /* SDL_metal.h */; settings = {ATTRIBUTES = (Public, ); }; }; FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; }; FA73671F19A54144004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; }; @@ -3842,13 +3515,6 @@ remoteGlobalIDString = BECDF5FE0761BA81005FE872; remoteInfo = "Framework (Upgraded)"; }; - F3190016240CA3BA00ED104F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = A75FDB8023E4C74400529352; - remoteInfo = hidapi; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -3858,7 +3524,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - A75FDB9B23E4CAEF00529352 /* hidapi.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -3907,6 +3572,8 @@ 5C2EF7001FC9EF0F003F5197 /* SDL_egl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_egl.h; sourceTree = ""; }; 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_virtualjoystick.c; sourceTree = ""; }; 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_virtualjoystick_c.h; sourceTree = ""; }; + A1626A3D2617006A003F1973 /* SDL_triangle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_triangle.c; sourceTree = ""; }; + A1626A512617008C003F1973 /* SDL_triangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_triangle.h; sourceTree = ""; }; A7381E931D8B69C300B177DD /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; A7381E951D8B69D600B177DD /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; A75FCEB323E25AB700529352 /* libSDL2.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libSDL2.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -3919,11 +3586,7 @@ A75FDAC123E28B9600529352 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; A75FDAC323E28BA700529352 /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = System/Library/Frameworks/CoreBluetooth.framework; sourceTree = SDKROOT; }; A75FDAF523E35EC400529352 /* SDL_config_iphoneos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_config_iphoneos.h; sourceTree = ""; }; - A75FDB4923E399AC00529352 /* hidapi.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = hidapi.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - A75FDB4C23E399AC00529352 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; A75FDB5723E39E6100529352 /* hidapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hidapi.h; path = hidapi/hidapi.h; sourceTree = ""; }; - A75FDB6E23E3A2C900529352 /* hidapi.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = hidapi.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - A75FDB8C23E4C74400529352 /* hidapi.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = hidapi.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A75FDB9223E4C8DB00529352 /* hid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hid.c; sourceTree = ""; }; A75FDBA323E4CB6F00529352 /* LICENSE-bsd.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "LICENSE-bsd.txt"; sourceTree = ""; }; A75FDBA423E4CB6F00529352 /* AUTHORS.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AUTHORS.txt; sourceTree = ""; }; @@ -4042,7 +3705,6 @@ A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoavideo.m; sourceTree = ""; }; A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoametalview.h; sourceTree = ""; }; A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoamouse.m; sourceTree = ""; }; - A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoamousetap.h; sourceTree = ""; }; A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoaevents.m; sourceTree = ""; }; A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoaclipboard.h; sourceTree = ""; }; A7D8A68B23E2513E00DCD162 /* SDL_cocoamessagebox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoamessagebox.m; sourceTree = ""; }; @@ -4057,48 +3719,10 @@ A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoamessagebox.h; sourceTree = ""; }; A7D8A69523E2513E00DCD162 /* SDL_cocoaclipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoaclipboard.m; sourceTree = ""; }; A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoaevents.h; sourceTree = ""; }; - A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoamousetap.m; sourceTree = ""; }; A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoamouse.h; sourceTree = ""; }; A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoametalview.m; sourceTree = ""; }; A7D8A6B623E2513E00DCD162 /* SDL_egl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_egl.c; sourceTree = ""; }; A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_blit_1.c; sourceTree = ""; }; - A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11touch.h; sourceTree = ""; }; - A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11messagebox.h; sourceTree = ""; }; - A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11modes.c; sourceTree = ""; }; - A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11opengl.c; sourceTree = ""; }; - A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11vulkan.c; sourceTree = ""; }; - A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11shape.h; sourceTree = ""; }; - A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11xinput2.c; sourceTree = ""; }; - A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11opengles.h; sourceTree = ""; }; - A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11mouse.c; sourceTree = ""; }; - A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11dyn.c; sourceTree = ""; }; - A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11framebuffer.c; sourceTree = ""; }; - A7D8A70723E2513E00DCD162 /* SDL_x11window.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11window.c; sourceTree = ""; }; - A7D8A70823E2513E00DCD162 /* SDL_x11video.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11video.c; sourceTree = ""; }; - A7D8A70923E2513E00DCD162 /* imKStoUCS.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = imKStoUCS.c; sourceTree = ""; }; - A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11events.c; sourceTree = ""; }; - A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11clipboard.c; sourceTree = ""; }; - A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11keyboard.c; sourceTree = ""; }; - A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11sym.h; sourceTree = ""; }; - A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11opengl.h; sourceTree = ""; }; - A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11modes.h; sourceTree = ""; }; - A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11messagebox.c; sourceTree = ""; }; - A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11touch.c; sourceTree = ""; }; - A7D8A71223E2513E00DCD162 /* edid-parse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "edid-parse.c"; sourceTree = ""; }; - A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11xinput2.h; sourceTree = ""; }; - A7D8A71423E2513E00DCD162 /* edid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = edid.h; sourceTree = ""; }; - A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11vulkan.h; sourceTree = ""; }; - A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11shape.c; sourceTree = ""; }; - A7D8A71723E2513E00DCD162 /* SDL_x11window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11window.h; sourceTree = ""; }; - A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11framebuffer.h; sourceTree = ""; }; - A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11dyn.h; sourceTree = ""; }; - A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11mouse.h; sourceTree = ""; }; - A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11opengles.c; sourceTree = ""; }; - A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11keyboard.h; sourceTree = ""; }; - A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11clipboard.h; sourceTree = ""; }; - A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11events.h; sourceTree = ""; }; - A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imKStoUCS.h; sourceTree = ""; }; - A7D8A72023E2513E00DCD162 /* SDL_x11video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11video.h; sourceTree = ""; }; A7D8A72323E2513E00DCD162 /* gl2ext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl2ext.h; sourceTree = ""; }; A7D8A72423E2513E00DCD162 /* gl2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl2.h; sourceTree = ""; }; A7D8A72523E2513E00DCD162 /* gl2platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl2platform.h; sourceTree = ""; }; @@ -4369,14 +3993,18 @@ F376F7272559B77100CFC0BC /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/CoreAudio.framework; sourceTree = DEVELOPER_DIR; }; F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreHaptics.framework; path = System/Library/Frameworks/CoreHaptics.framework; sourceTree = SDKROOT; }; F37DC5F425350ECC0002E6F7 /* CoreHaptics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreHaptics.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/CoreHaptics.framework; sourceTree = DEVELOPER_DIR; }; + F38233842738EB8600F7F527 /* SDL_hidapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_hidapi.h; sourceTree = ""; }; + F382339B2738ED6600F7F527 /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS15.0.sdk/System/Library/Frameworks/CoreBluetooth.framework; sourceTree = DEVELOPER_DIR; }; F3950CD7212BC88D00F51292 /* SDL_sensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sensor.h; sourceTree = ""; }; F395BF6425633B2400942BFF /* SDL_crc32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_crc32.c; sourceTree = ""; }; F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_iokitjoystick_c.h; sourceTree = ""; }; F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_iokitjoystick.c; sourceTree = ""; }; F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_mfijoystick.m; sourceTree = ""; }; F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_mfijoystick_c.h; sourceTree = ""; }; + F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_stadia.c; sourceTree = ""; }; F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_ps5.c; sourceTree = ""; }; F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_sysurl.m; sourceTree = ""; }; + F3F07D59269640160074468B /* SDL_hidapi_luna.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_luna.c; sourceTree = ""; }; F59C710300D5CB5801000001 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; F59C710600D5CB5801000001 /* SDL.info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SDL.info; sourceTree = ""; }; F5A2EF3900C6A39A01000001 /* BUGS.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = BUGS.txt; path = ../../BUGS.txt; sourceTree = SOURCE_ROOT; }; @@ -4389,7 +4017,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F376F70D2559B6A000CFC0BC /* hidapi.framework in Frameworks */, A75FCEAE23E25AB700529352 /* AudioToolbox.framework in Frameworks */, A75FDABA23E28A7A00529352 /* AVFoundation.framework in Frameworks */, A75FCEA723E25AB700529352 /* CoreAudio.framework in Frameworks */, @@ -4412,10 +4039,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F376F71A2559B70B00CFC0BC /* hidapi.framework in Frameworks */, F376F71B2559B71C00CFC0BC /* AudioToolbox.framework in Frameworks */, F376F71C2559B72900CFC0BC /* AVFoundation.framework in Frameworks */, F376F7282559B77100CFC0BC /* CoreAudio.framework in Frameworks */, + F382339D2738EE3F00F7F527 /* CoreBluetooth.framework in Frameworks */, F376F7262559B76800CFC0BC /* CoreFoundation.framework in Frameworks */, F376F7242559B76100CFC0BC /* CoreGraphics.framework in Frameworks */, F394265A253579D200B03694 /* CoreHaptics.framework in Frameworks */, @@ -4428,33 +4055,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - A75FDB4623E399AC00529352 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB5523E39DAC00529352 /* CoreBluetooth.framework in Frameworks */, - F376F6262559B30000CFC0BC /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB6723E3A2C900529352 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB6823E3A2C900529352 /* CoreBluetooth.framework in Frameworks */, - F376F6CD2559B54500CFC0BC /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB8523E4C74400529352 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB9523E4C93600529352 /* CoreFoundation.framework in Frameworks */, - A75FDB9423E4C91300529352 /* IOKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; A769B22E23E259AE00872273 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -4466,10 +4066,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A75FDB9D23E4CAFA00529352 /* hidapi.framework in Frameworks */, F376F6332559B33D00CFC0BC /* AudioToolbox.framework in Frameworks */, F376F6402559B38A00CFC0BC /* AVFoundation.framework in Frameworks */, A7D88B4C23E2437C00DCD162 /* CoreAudio.framework in Frameworks */, + F382339A2738ED5600F7F527 /* CoreBluetooth.framework in Frameworks */, A7D88B4D23E2437C00DCD162 /* CoreFoundation.framework in Frameworks */, F376F63F2559B37300CFC0BC /* CoreGraphics.framework in Frameworks */, F37DC5F325350EBC0002E6F7 /* CoreHaptics.framework in Frameworks */, @@ -4488,10 +4088,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A75FDBA023E4CAFF00529352 /* hidapi.framework in Frameworks */, F376F6DB2559B5A000CFC0BC /* AVFoundation.framework in Frameworks */, F376F6D92559B59600CFC0BC /* AudioToolbox.framework in Frameworks */, A7D88D0723E24BED00DCD162 /* CoreAudio.framework in Frameworks */, + F382339C2738ED6600F7F527 /* CoreBluetooth.framework in Frameworks */, A7D88D0823E24BED00DCD162 /* CoreFoundation.framework in Frameworks */, F376F6F82559B5EC00CFC0BC /* CoreGraphics.framework in Frameworks */, F37DC5F525350ECC0002E6F7 /* CoreHaptics.framework in Frameworks */, @@ -4520,7 +4120,6 @@ 564624381FF821DA0074AC87 /* Metal.framework in Frameworks */, 564624361FF821C20074AC87 /* QuartzCore.framework in Frameworks */, A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */, - A75FDB9A23E4CAEF00529352 /* hidapi.framework in Frameworks */, 00D0D0D810675E46004B05EF /* Carbon.framework in Frameworks */, 007317A40858DECD00B2BC32 /* Cocoa.framework in Frameworks */, A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */, @@ -4584,6 +4183,7 @@ A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */, AA7557D51595D4D800BBD41B /* SDL_gesture.h */, AA7557D61595D4D800BBD41B /* SDL_haptic.h */, + F38233842738EB8600F7F527 /* SDL_hidapi.h */, AA7557D71595D4D800BBD41B /* SDL_hints.h */, AA7557D91595D4D800BBD41B /* SDL_joystick.h */, AA7557DA1595D4D800BBD41B /* SDL_keyboard.h */, @@ -4647,9 +4247,6 @@ A769B23D23E259AE00872273 /* libSDL2.a */, A75FCEB323E25AB700529352 /* libSDL2.dylib */, A75FD06C23E25AC700529352 /* libSDL2.dylib */, - A75FDB4923E399AC00529352 /* hidapi.framework */, - A75FDB6E23E3A2C900529352 /* hidapi.framework */, - A75FDB8C23E4C74400529352 /* hidapi.framework */, ); name = Products; sourceTree = ""; @@ -4661,7 +4258,6 @@ F59C70FC00D5CB5801000001 /* pkg-support */, 0153844A006D81B07F000001 /* Public Headers */, 08FB77ACFE841707C02AAC07 /* Library Source */, - A75FDB4A23E399AC00529352 /* hidapi */, 034768DDFF38A45A11DB9C8B /* Products */, BECDF66B0761BA81005FE872 /* Info-Framework.plist */, 564624341FF821B70074AC87 /* Frameworks */, @@ -4736,6 +4332,7 @@ 564624341FF821B70074AC87 /* Frameworks */ = { isa = PBXGroup; children = ( + F382339B2738ED6600F7F527 /* CoreBluetooth.framework */, F376F7272559B77100CFC0BC /* CoreAudio.framework */, F376F7252559B76800CFC0BC /* CoreFoundation.framework */, F376F7212559B74900CFC0BC /* Metal.framework */, @@ -4806,14 +4403,6 @@ path = ios; sourceTree = ""; }; - A75FDB4A23E399AC00529352 /* hidapi */ = { - isa = PBXGroup; - children = ( - A75FDB4C23E399AC00529352 /* Info.plist */, - ); - path = hidapi; - sourceTree = ""; - }; A75FDB9123E4C8B800529352 /* mac */ = { isa = PBXGroup; children = ( @@ -4952,7 +4541,6 @@ A7D8A72123E2513E00DCD162 /* khronos */, A7D8A5EC23E2513D00DCD162 /* offscreen */, A7D8A61823E2513D00DCD162 /* uikit */, - A7D8A6FB23E2513E00DCD162 /* x11 */, A7D8A76C23E2513E00DCD162 /* yuv2rgb */, A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */, A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */, @@ -5072,8 +4660,6 @@ A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */, A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */, A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */, - A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */, - A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */, A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */, A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */, A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */, @@ -5090,50 +4676,6 @@ path = cocoa; sourceTree = ""; }; - A7D8A6FB23E2513E00DCD162 /* x11 */ = { - isa = PBXGroup; - children = ( - A7D8A71223E2513E00DCD162 /* edid-parse.c */, - A7D8A71423E2513E00DCD162 /* edid.h */, - A7D8A70923E2513E00DCD162 /* imKStoUCS.c */, - A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */, - A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */, - A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */, - A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */, - A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */, - A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */, - A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */, - A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */, - A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */, - A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */, - A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */, - A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */, - A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */, - A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */, - A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */, - A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */, - A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */, - A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */, - A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */, - A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */, - A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */, - A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */, - A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */, - A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */, - A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */, - A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */, - A7D8A70823E2513E00DCD162 /* SDL_x11video.c */, - A7D8A72023E2513E00DCD162 /* SDL_x11video.h */, - A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */, - A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */, - A7D8A70723E2513E00DCD162 /* SDL_x11window.c */, - A7D8A71723E2513E00DCD162 /* SDL_x11window.h */, - A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */, - A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */, - ); - path = x11; - sourceTree = ""; - }; A7D8A72123E2513E00DCD162 /* khronos */ = { isa = PBXGroup; children = ( @@ -5292,10 +4834,12 @@ isa = PBXGroup; children = ( A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */, + F3F07D59269640160074468B /* SDL_hidapi_luna.c */, A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */, F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */, A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */, A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */, + F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */, A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */, A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */, A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */, @@ -5523,6 +5067,8 @@ A7D8A8EF23E2514000DCD162 /* software */ = { isa = PBXGroup; children = ( + A1626A512617008C003F1973 /* SDL_triangle.h */, + A1626A3D2617006A003F1973 /* SDL_triangle.c */, A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */, A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */, A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */, @@ -5680,7 +5226,6 @@ A75FCD0723E25AB700529352 /* SDL_glfuncs.h in Headers */, A75FCD0823E25AB700529352 /* SDL_atomic.h in Headers */, A75FCD0923E25AB700529352 /* SDL_rect_c.h in Headers */, - A75FCD0A23E25AB700529352 /* SDL_x11xinput2.h in Headers */, A75FCD0B23E25AB700529352 /* SDL_shaders_metal_osx.h in Headers */, A75FCD0C23E25AB700529352 /* SDL_shaders_metal_ios.h in Headers */, A75FCD0D23E25AB700529352 /* SDL_offscreenwindow.h in Headers */, @@ -5696,19 +5241,16 @@ A75FCD1723E25AB700529352 /* SDL_clipboard.h in Headers */, A75FCD1823E25AB700529352 /* SDL_dataqueue.h in Headers */, A75FCD1923E25AB700529352 /* SDL_error_c.h in Headers */, - A75FCD1A23E25AB700529352 /* SDL_x11events.h in Headers */, A75FCD1B23E25AB700529352 /* SDL_config.h in Headers */, A75FCD1C23E25AB700529352 /* SDL_d3dmath.h in Headers */, - A75FCD1D23E25AB700529352 /* SDL_x11window.h in Headers */, A75FCD1F23E25AB700529352 /* SDL_egl_c.h in Headers */, A75FCD2023E25AB700529352 /* SDL_copying.h in Headers */, A75FCD2123E25AB700529352 /* yuv_rgb.h in Headers */, A75FCD2223E25AB700529352 /* SDL_dummyaudio.h in Headers */, + F382338C2738EB8600F7F527 /* SDL_hidapi.h in Headers */, A75FCD2323E25AB700529352 /* SDL_uikitmessagebox.h in Headers */, - A75FCD2423E25AB700529352 /* SDL_x11messagebox.h in Headers */, A75FCD2523E25AB700529352 /* SDL_thread_c.h in Headers */, A75FCD2623E25AB700529352 /* SDL_cocoamessagebox.h in Headers */, - A75FCD2723E25AB700529352 /* SDL_x11shape.h in Headers */, A75FCD2823E25AB700529352 /* SDL_cpuinfo.h in Headers */, A75FCD2923E25AB700529352 /* SDL_endian.h in Headers */, A75FCD2A23E25AB700529352 /* SDL_error.h in Headers */, @@ -5717,7 +5259,6 @@ A75FCD2D23E25AB700529352 /* SDL_gamecontroller.h in Headers */, A75FCD2E23E25AB700529352 /* SDL_hidapijoystick_c.h in Headers */, A75FCD3023E25AB700529352 /* SDL_pixels_c.h in Headers */, - A75FCD3123E25AB700529352 /* SDL_x11modes.h in Headers */, A75FCD3223E25AB700529352 /* SDL_joystick_c.h in Headers */, F395C19A2569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, A75FCD3323E25AB700529352 /* vk_sdk_platform.h in Headers */, @@ -5734,7 +5275,6 @@ A75FCD3C23E25AB700529352 /* SDL_hints.h in Headers */, A75FCD3D23E25AB700529352 /* SDL_blit_slow.h in Headers */, A75FCD3E23E25AB700529352 /* SDL_yuv_sw_c.h in Headers */, - A75FCD3F23E25AB700529352 /* SDL_x11opengl.h in Headers */, A75FCD4023E25AB700529352 /* SDL_windowevents_c.h in Headers */, A75FCD4123E25AB700529352 /* SDL_joystick.h in Headers */, A75FCD4223E25AB700529352 /* SDL_cocoavideo.h in Headers */, @@ -5745,17 +5285,13 @@ A75FCD4623E25AB700529352 /* SDL_shaders_gl.h in Headers */, A75FCD4723E25AB700529352 /* SDL_systhread_c.h in Headers */, A75FCD4823E25AB700529352 /* SDL_keycode.h in Headers */, - A75FCD4923E25AB700529352 /* SDL_x11keyboard.h in Headers */, 5616CA63252BB35F005D5928 /* SDL_sysurl.h in Headers */, A75FCD4A23E25AB700529352 /* SDL_cocoakeyboard.h in Headers */, A75FCD4B23E25AB700529352 /* SDL_uikitvulkan.h in Headers */, - A75FCD4C23E25AB700529352 /* SDL_x11framebuffer.h in Headers */, - A75FCD4D23E25AB700529352 /* SDL_x11video.h in Headers */, A75FCD4E23E25AB700529352 /* vulkan.hpp in Headers */, A75FCD4F23E25AB700529352 /* SDL_loadso.h in Headers */, A75FCD5023E25AB700529352 /* gl2ext.h in Headers */, A75FCD5123E25AB700529352 /* SDL_clipboardevents_c.h in Headers */, - A75FCD5223E25AB700529352 /* SDL_x11touch.h in Headers */, A75FCD5323E25AB700529352 /* SDL_syshaptic_c.h in Headers */, A75FCD5423E25AB700529352 /* SDL_hints_c.h in Headers */, A75FCD5523E25AB700529352 /* SDL_audiodev_c.h in Headers */, @@ -5779,9 +5315,8 @@ A75FCD6723E25AB700529352 /* SDL_wave.h in Headers */, A75FCD6823E25AB700529352 /* SDL_cocoaopengl.h in Headers */, A75FCD6923E25AB700529352 /* yuv_rgb_sse_func.h in Headers */, - A75FCD6A23E25AB700529352 /* imKStoUCS.h in Headers */, A75FCD6B23E25AB700529352 /* SDL_offscreenevents_c.h in Headers */, - A75FCD6C23E25AB700529352 /* SDL_x11sym.h in Headers */, + A1626A592617008D003F1973 /* SDL_triangle.h in Headers */, A75FCD6D23E25AB700529352 /* SDL_coreaudio.h in Headers */, A75FCD6E23E25AB700529352 /* SDL_draw.h in Headers */, A75FCD6F23E25AB700529352 /* SDL_drawline.h in Headers */, @@ -5792,7 +5327,6 @@ A75FCD7423E25AB700529352 /* scancodes_xfree86.h in Headers */, A75FCD7523E25AB700529352 /* SDL_syspower.h in Headers */, A75FDAFA23E35ED600529352 /* SDL_config_iphoneos.h in Headers */, - A75FCD7623E25AB700529352 /* SDL_x11clipboard.h in Headers */, A75FCD7723E25AB700529352 /* SDL_name.h in Headers */, A75FCD7823E25AB700529352 /* eglext.h in Headers */, A75FCD7923E25AB700529352 /* SDL_events_c.h in Headers */, @@ -5810,14 +5344,12 @@ A75FCD8623E25AB700529352 /* SDL_sysjoystick.h in Headers */, A75FCD8723E25AB700529352 /* SDL_steamcontroller.h in Headers */, A75FCD8823E25AB700529352 /* scancodes_linux.h in Headers */, - A75FCD8923E25AB700529352 /* SDL_x11dyn.h in Headers */, A75FCD8A23E25AB700529352 /* SDL_touch_c.h in Headers */, A75FCD8B23E25AB700529352 /* SDL_gamecontrollerdb.h in Headers */, A75FCD8C23E25AB700529352 /* SDL_cocoavulkan.h in Headers */, A75FCD8D23E25AB700529352 /* gl2platform.h in Headers */, A75FCD8E23E25AB700529352 /* SDL_pixels.h in Headers */, A75FCD8F23E25AB700529352 /* vk_layer.h in Headers */, - A75FCD9023E25AB700529352 /* SDL_cocoamousetap.h in Headers */, A75FCD9123E25AB700529352 /* vk_platform.h in Headers */, A75FCD9223E25AB700529352 /* SDL_cocoametalview.h in Headers */, A75FCD9323E25AB700529352 /* SDL_cocoaopengles.h in Headers */, @@ -5831,7 +5363,6 @@ A75FCD9B23E25AB700529352 /* SDL_offscreenopengl.h in Headers */, A75FCD9D23E25AB700529352 /* scancodes_darwin.h in Headers */, A75FCD9E23E25AB700529352 /* controller_type.h in Headers */, - A75FCD9F23E25AB700529352 /* SDL_x11opengles.h in Headers */, A75FCDA023E25AB700529352 /* SDL_uikitclipboard.h in Headers */, A75FCDA123E25AB700529352 /* vulkan_xlib.h in Headers */, A75FCDA223E25AB700529352 /* SDL_uikitwindow.h in Headers */, @@ -5847,7 +5378,6 @@ 75E0916A241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A75FCDAC23E25AB700529352 /* SDL_RLEaccel_c.h in Headers */, A75FCDAD23E25AB700529352 /* eglplatform.h in Headers */, - A75FCDAE23E25AB700529352 /* edid.h in Headers */, A75FCDAF23E25AB700529352 /* SDL_revision.h in Headers */, A75FCDB023E25AB700529352 /* SDL_systhread.h in Headers */, A75FCDB123E25AB700529352 /* SDL_rwops.h in Headers */, @@ -5900,10 +5430,8 @@ A75FCDE123E25AB700529352 /* SDL_sysvideo.h in Headers */, A75FCDE223E25AB700529352 /* SDL_opengles2_gl2platform.h in Headers */, A75FCDE323E25AB700529352 /* SDL_opengles2_gl2ext.h in Headers */, - A75FCDE423E25AB700529352 /* SDL_x11mouse.h in Headers */, A75FCDE523E25AB700529352 /* SDL_dynapi_overrides.h in Headers */, A75FCDE623E25AB700529352 /* SDL_cocoawindow.h in Headers */, - A75FCDE723E25AB700529352 /* SDL_x11vulkan.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5923,7 +5451,6 @@ A75FCEC023E25AC700529352 /* SDL_glfuncs.h in Headers */, A75FCEC123E25AC700529352 /* SDL_atomic.h in Headers */, A75FCEC223E25AC700529352 /* SDL_rect_c.h in Headers */, - A75FCEC323E25AC700529352 /* SDL_x11xinput2.h in Headers */, A75FCEC423E25AC700529352 /* SDL_shaders_metal_osx.h in Headers */, A75FCEC523E25AC700529352 /* SDL_shaders_metal_ios.h in Headers */, A75FCEC623E25AC700529352 /* SDL_offscreenwindow.h in Headers */, @@ -5939,19 +5466,16 @@ A75FCED023E25AC700529352 /* SDL_clipboard.h in Headers */, A75FCED123E25AC700529352 /* SDL_dataqueue.h in Headers */, A75FCED223E25AC700529352 /* SDL_error_c.h in Headers */, - A75FCED323E25AC700529352 /* SDL_x11events.h in Headers */, A75FCED423E25AC700529352 /* SDL_config.h in Headers */, A75FCED523E25AC700529352 /* SDL_d3dmath.h in Headers */, - A75FCED623E25AC700529352 /* SDL_x11window.h in Headers */, A75FCED823E25AC700529352 /* SDL_egl_c.h in Headers */, A75FCED923E25AC700529352 /* SDL_copying.h in Headers */, A75FCEDA23E25AC700529352 /* yuv_rgb.h in Headers */, A75FCEDB23E25AC700529352 /* SDL_dummyaudio.h in Headers */, + F382338D2738EB8600F7F527 /* SDL_hidapi.h in Headers */, A75FCEDC23E25AC700529352 /* SDL_uikitmessagebox.h in Headers */, - A75FCEDD23E25AC700529352 /* SDL_x11messagebox.h in Headers */, A75FCEDE23E25AC700529352 /* SDL_thread_c.h in Headers */, A75FCEDF23E25AC700529352 /* SDL_cocoamessagebox.h in Headers */, - A75FCEE023E25AC700529352 /* SDL_x11shape.h in Headers */, A75FCEE123E25AC700529352 /* SDL_cpuinfo.h in Headers */, A75FCEE223E25AC700529352 /* SDL_endian.h in Headers */, A75FCEE323E25AC700529352 /* SDL_error.h in Headers */, @@ -5960,7 +5484,6 @@ A75FCEE623E25AC700529352 /* SDL_gamecontroller.h in Headers */, A75FCEE723E25AC700529352 /* SDL_hidapijoystick_c.h in Headers */, A75FCEE923E25AC700529352 /* SDL_pixels_c.h in Headers */, - A75FCEEA23E25AC700529352 /* SDL_x11modes.h in Headers */, A75FCEEB23E25AC700529352 /* SDL_joystick_c.h in Headers */, F395C19B2569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, A75FCEEC23E25AC700529352 /* vk_sdk_platform.h in Headers */, @@ -5977,7 +5500,6 @@ A75FCEF523E25AC700529352 /* SDL_hints.h in Headers */, A75FCEF623E25AC700529352 /* SDL_blit_slow.h in Headers */, A75FCEF723E25AC700529352 /* SDL_yuv_sw_c.h in Headers */, - A75FCEF823E25AC700529352 /* SDL_x11opengl.h in Headers */, A75FCEF923E25AC700529352 /* SDL_windowevents_c.h in Headers */, A75FCEFA23E25AC700529352 /* SDL_joystick.h in Headers */, A75FCEFB23E25AC700529352 /* SDL_cocoavideo.h in Headers */, @@ -5988,17 +5510,13 @@ A75FCEFF23E25AC700529352 /* SDL_shaders_gl.h in Headers */, A75FCF0023E25AC700529352 /* SDL_systhread_c.h in Headers */, A75FCF0123E25AC700529352 /* SDL_keycode.h in Headers */, - A75FCF0223E25AC700529352 /* SDL_x11keyboard.h in Headers */, 5616CA66252BB361005D5928 /* SDL_sysurl.h in Headers */, A75FCF0323E25AC700529352 /* SDL_cocoakeyboard.h in Headers */, A75FCF0423E25AC700529352 /* SDL_uikitvulkan.h in Headers */, - A75FCF0523E25AC700529352 /* SDL_x11framebuffer.h in Headers */, - A75FCF0623E25AC700529352 /* SDL_x11video.h in Headers */, A75FCF0723E25AC700529352 /* vulkan.hpp in Headers */, A75FCF0823E25AC700529352 /* SDL_loadso.h in Headers */, A75FCF0923E25AC700529352 /* gl2ext.h in Headers */, A75FCF0A23E25AC700529352 /* SDL_clipboardevents_c.h in Headers */, - A75FCF0B23E25AC700529352 /* SDL_x11touch.h in Headers */, A75FCF0C23E25AC700529352 /* SDL_syshaptic_c.h in Headers */, A75FCF0D23E25AC700529352 /* SDL_hints_c.h in Headers */, A75FCF0E23E25AC700529352 /* SDL_audiodev_c.h in Headers */, @@ -6022,9 +5540,8 @@ A75FCF2023E25AC700529352 /* SDL_wave.h in Headers */, A75FCF2123E25AC700529352 /* SDL_cocoaopengl.h in Headers */, A75FCF2223E25AC700529352 /* yuv_rgb_sse_func.h in Headers */, - A75FCF2323E25AC700529352 /* imKStoUCS.h in Headers */, A75FCF2423E25AC700529352 /* SDL_offscreenevents_c.h in Headers */, - A75FCF2523E25AC700529352 /* SDL_x11sym.h in Headers */, + A1626A5A2617008D003F1973 /* SDL_triangle.h in Headers */, A75FCF2623E25AC700529352 /* SDL_coreaudio.h in Headers */, A75FCF2723E25AC700529352 /* SDL_draw.h in Headers */, A75FCF2823E25AC700529352 /* SDL_drawline.h in Headers */, @@ -6035,7 +5552,6 @@ A75FCF2D23E25AC700529352 /* scancodes_xfree86.h in Headers */, A75FCF2E23E25AC700529352 /* SDL_syspower.h in Headers */, A75FDAFB23E35ED700529352 /* SDL_config_iphoneos.h in Headers */, - A75FCF2F23E25AC700529352 /* SDL_x11clipboard.h in Headers */, A75FCF3023E25AC700529352 /* SDL_name.h in Headers */, A75FCF3123E25AC700529352 /* eglext.h in Headers */, A75FCF3223E25AC700529352 /* SDL_events_c.h in Headers */, @@ -6053,14 +5569,12 @@ A75FCF3F23E25AC700529352 /* SDL_sysjoystick.h in Headers */, A75FCF4023E25AC700529352 /* SDL_steamcontroller.h in Headers */, A75FCF4123E25AC700529352 /* scancodes_linux.h in Headers */, - A75FCF4223E25AC700529352 /* SDL_x11dyn.h in Headers */, A75FCF4323E25AC700529352 /* SDL_touch_c.h in Headers */, A75FCF4423E25AC700529352 /* SDL_gamecontrollerdb.h in Headers */, A75FCF4523E25AC700529352 /* SDL_cocoavulkan.h in Headers */, A75FCF4623E25AC700529352 /* gl2platform.h in Headers */, A75FCF4723E25AC700529352 /* SDL_pixels.h in Headers */, A75FCF4823E25AC700529352 /* vk_layer.h in Headers */, - A75FCF4923E25AC700529352 /* SDL_cocoamousetap.h in Headers */, A75FCF4A23E25AC700529352 /* vk_platform.h in Headers */, A75FCF4B23E25AC700529352 /* SDL_cocoametalview.h in Headers */, A75FCF4C23E25AC700529352 /* SDL_cocoaopengles.h in Headers */, @@ -6074,7 +5588,6 @@ A75FCF5423E25AC700529352 /* SDL_offscreenopengl.h in Headers */, A75FCF5623E25AC700529352 /* scancodes_darwin.h in Headers */, A75FCF5723E25AC700529352 /* controller_type.h in Headers */, - A75FCF5823E25AC700529352 /* SDL_x11opengles.h in Headers */, A75FCF5923E25AC700529352 /* SDL_uikitclipboard.h in Headers */, A75FCF5A23E25AC700529352 /* vulkan_xlib.h in Headers */, A75FCF5B23E25AC700529352 /* SDL_uikitwindow.h in Headers */, @@ -6090,7 +5603,6 @@ 75E0916B241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A75FCF6523E25AC700529352 /* SDL_RLEaccel_c.h in Headers */, A75FCF6623E25AC700529352 /* eglplatform.h in Headers */, - A75FCF6723E25AC700529352 /* edid.h in Headers */, A75FCF6823E25AC700529352 /* SDL_revision.h in Headers */, A75FCF6923E25AC700529352 /* SDL_systhread.h in Headers */, A75FCF6A23E25AC700529352 /* SDL_rwops.h in Headers */, @@ -6143,34 +5655,8 @@ A75FCF9A23E25AC700529352 /* SDL_sysvideo.h in Headers */, A75FCF9B23E25AC700529352 /* SDL_opengles2_gl2platform.h in Headers */, A75FCF9C23E25AC700529352 /* SDL_opengles2_gl2ext.h in Headers */, - A75FCF9D23E25AC700529352 /* SDL_x11mouse.h in Headers */, A75FCF9E23E25AC700529352 /* SDL_dynapi_overrides.h in Headers */, A75FCF9F23E25AC700529352 /* SDL_cocoawindow.h in Headers */, - A75FCFA023E25AC700529352 /* SDL_x11vulkan.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB4423E399AC00529352 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB6123E39E6100529352 /* hidapi.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB6323E3A2C900529352 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB6423E3A2C900529352 /* hidapi.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB8123E4C74400529352 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB8223E4C74400529352 /* hidapi.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6184,7 +5670,6 @@ A769B08D23E259AE00872273 /* SDL_shape_internals.h in Headers */, A769B08E23E259AE00872273 /* SDL_glfuncs.h in Headers */, A769B09023E259AE00872273 /* SDL_rect_c.h in Headers */, - A769B09123E259AE00872273 /* SDL_x11xinput2.h in Headers */, A769B09223E259AE00872273 /* SDL_shaders_metal_osx.h in Headers */, A769B09323E259AE00872273 /* SDL_shaders_metal_ios.h in Headers */, A769B09423E259AE00872273 /* SDL_offscreenwindow.h in Headers */, @@ -6196,21 +5681,16 @@ A769B09D23E259AE00872273 /* SDL_haptic_c.h in Headers */, A769B09F23E259AE00872273 /* SDL_dataqueue.h in Headers */, A769B0A023E259AE00872273 /* SDL_error_c.h in Headers */, - A769B0A123E259AE00872273 /* SDL_x11events.h in Headers */, A769B0A323E259AE00872273 /* SDL_d3dmath.h in Headers */, - A769B0A423E259AE00872273 /* SDL_x11window.h in Headers */, A769B0A623E259AE00872273 /* SDL_egl_c.h in Headers */, A769B0A823E259AE00872273 /* yuv_rgb.h in Headers */, A769B0A923E259AE00872273 /* SDL_dummyaudio.h in Headers */, A769B0AA23E259AE00872273 /* SDL_uikitmessagebox.h in Headers */, - A769B0AB23E259AE00872273 /* SDL_x11messagebox.h in Headers */, A769B0AC23E259AE00872273 /* SDL_thread_c.h in Headers */, A769B0AD23E259AE00872273 /* SDL_cocoamessagebox.h in Headers */, - A769B0AE23E259AE00872273 /* SDL_x11shape.h in Headers */, A769B0B323E259AE00872273 /* SDL_blendfillrect.h in Headers */, A769B0B523E259AE00872273 /* SDL_hidapijoystick_c.h in Headers */, A769B0B623E259AE00872273 /* SDL_pixels_c.h in Headers */, - A769B0B723E259AE00872273 /* SDL_x11modes.h in Headers */, A769B0B823E259AE00872273 /* SDL_joystick_c.h in Headers */, F395C1982569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, A769B0B923E259AE00872273 /* vk_sdk_platform.h in Headers */, @@ -6224,7 +5704,6 @@ A769B0C123E259AE00872273 /* SDL_cocoamouse.h in Headers */, A769B0C323E259AE00872273 /* SDL_blit_slow.h in Headers */, A769B0C423E259AE00872273 /* SDL_yuv_sw_c.h in Headers */, - A769B0C523E259AE00872273 /* SDL_x11opengl.h in Headers */, A769B0C623E259AE00872273 /* SDL_windowevents_c.h in Headers */, A769B0C823E259AE00872273 /* SDL_cocoavideo.h in Headers */, 5605721C2473688D00B46B66 /* SDL_syslocale.h in Headers */, @@ -6232,16 +5711,12 @@ A769B0CB23E259AE00872273 /* SDL_gesture_c.h in Headers */, A769B0CC23E259AE00872273 /* SDL_shaders_gl.h in Headers */, A769B0CD23E259AE00872273 /* SDL_systhread_c.h in Headers */, - A769B0CF23E259AE00872273 /* SDL_x11keyboard.h in Headers */, A769B0D023E259AE00872273 /* SDL_cocoakeyboard.h in Headers */, 5616CA5D252BB35E005D5928 /* SDL_sysurl.h in Headers */, A769B0D123E259AE00872273 /* SDL_uikitvulkan.h in Headers */, - A769B0D223E259AE00872273 /* SDL_x11framebuffer.h in Headers */, - A769B0D323E259AE00872273 /* SDL_x11video.h in Headers */, A769B0D423E259AE00872273 /* vulkan.hpp in Headers */, A769B0D623E259AE00872273 /* gl2ext.h in Headers */, A769B0D723E259AE00872273 /* SDL_clipboardevents_c.h in Headers */, - A769B0D823E259AE00872273 /* SDL_x11touch.h in Headers */, A769B0D923E259AE00872273 /* SDL_syshaptic_c.h in Headers */, A769B0DA23E259AE00872273 /* SDL_hints_c.h in Headers */, A769B0DB23E259AE00872273 /* SDL_audiodev_c.h in Headers */, @@ -6262,10 +5737,9 @@ A769B0ED23E259AE00872273 /* SDL_drawpoint.h in Headers */, A769B0EF23E259AE00872273 /* SDL_wave.h in Headers */, A769B0F023E259AE00872273 /* SDL_cocoaopengl.h in Headers */, + A1626A572617008D003F1973 /* SDL_triangle.h in Headers */, A769B0F123E259AE00872273 /* yuv_rgb_sse_func.h in Headers */, - A769B0F223E259AE00872273 /* imKStoUCS.h in Headers */, A769B0F323E259AE00872273 /* SDL_offscreenevents_c.h in Headers */, - A769B0F423E259AE00872273 /* SDL_x11sym.h in Headers */, A769B0F523E259AE00872273 /* SDL_coreaudio.h in Headers */, A769B0F623E259AE00872273 /* SDL_draw.h in Headers */, A769B0F723E259AE00872273 /* SDL_drawline.h in Headers */, @@ -6273,7 +5747,6 @@ A769B0FC23E259AE00872273 /* scancodes_xfree86.h in Headers */, A769B0FD23E259AE00872273 /* SDL_syspower.h in Headers */, A75FDAF923E35ED500529352 /* SDL_config_iphoneos.h in Headers */, - A769B0FE23E259AE00872273 /* SDL_x11clipboard.h in Headers */, A769B10023E259AE00872273 /* eglext.h in Headers */, A769B10123E259AE00872273 /* SDL_events_c.h in Headers */, A769B10223E259AE00872273 /* math_private.h in Headers */, @@ -6286,13 +5759,11 @@ A769B10C23E259AE00872273 /* SDL_nullevents_c.h in Headers */, A769B10D23E259AE00872273 /* SDL_sysjoystick.h in Headers */, A769B10E23E259AE00872273 /* scancodes_linux.h in Headers */, - A769B10F23E259AE00872273 /* SDL_x11dyn.h in Headers */, A769B11023E259AE00872273 /* SDL_touch_c.h in Headers */, A769B11123E259AE00872273 /* SDL_gamecontrollerdb.h in Headers */, A769B11223E259AE00872273 /* SDL_cocoavulkan.h in Headers */, A769B11323E259AE00872273 /* gl2platform.h in Headers */, A769B11523E259AE00872273 /* vk_layer.h in Headers */, - A769B11723E259AE00872273 /* SDL_cocoamousetap.h in Headers */, A769B11823E259AE00872273 /* vk_platform.h in Headers */, A769B11A23E259AE00872273 /* SDL_cocoametalview.h in Headers */, A769B11B23E259AE00872273 /* SDL_cocoaopengles.h in Headers */, @@ -6304,7 +5775,6 @@ A769B12323E259AE00872273 /* SDL_offscreenopengl.h in Headers */, A769B12523E259AE00872273 /* scancodes_darwin.h in Headers */, A769B12623E259AE00872273 /* controller_type.h in Headers */, - A769B12723E259AE00872273 /* SDL_x11opengles.h in Headers */, A769B12823E259AE00872273 /* SDL_uikitclipboard.h in Headers */, A769B12923E259AE00872273 /* vulkan_xlib.h in Headers */, A769B12A23E259AE00872273 /* SDL_uikitwindow.h in Headers */, @@ -6317,7 +5787,6 @@ A769B13423E259AE00872273 /* SDL_RLEaccel_c.h in Headers */, 75E09168241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A769B13523E259AE00872273 /* eglplatform.h in Headers */, - A769B13623E259AE00872273 /* edid.h in Headers */, A769B13823E259AE00872273 /* SDL_systhread.h in Headers */, A769B13B23E259AE00872273 /* SDL_cocoaclipboard.h in Headers */, A769B13C23E259AE00872273 /* SDL_cocoamodes.h in Headers */, @@ -6351,10 +5820,8 @@ A769B16123E259AE00872273 /* usb_ids.h in Headers */, A769B16323E259AE00872273 /* SDL_gles2funcs.h in Headers */, A769B16923E259AE00872273 /* SDL_sysvideo.h in Headers */, - A769B16C23E259AE00872273 /* SDL_x11mouse.h in Headers */, A769B16D23E259AE00872273 /* SDL_dynapi_overrides.h in Headers */, A769B16E23E259AE00872273 /* SDL_cocoawindow.h in Headers */, - A769B16F23E259AE00872273 /* SDL_x11vulkan.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6388,7 +5855,6 @@ A7D8AEB323E2514100DCD162 /* SDL_cocoametalview.h in Headers */, A7D8AEF523E2514100DCD162 /* SDL_cocoamodes.h in Headers */, A7D8AF1F23E2514100DCD162 /* SDL_cocoamouse.h in Headers */, - A7D8AEBF23E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, A7D8AEDD23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, A7D8AEEF23E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, A7D8AE8323E2514100DCD162 /* SDL_cocoashape.h in Headers */, @@ -6452,6 +5918,7 @@ F3928194258603F1003191A7 /* SDL_misc.h in Headers */, A7D88A3A23E2437C00DCD162 /* SDL_mouse.h in Headers */, A7D8BB1C23E2514500DCD162 /* SDL_mouse_c.h in Headers */, + F38233862738EB8600F7F527 /* SDL_hidapi.h in Headers */, A7D88A3B23E2437C00DCD162 /* SDL_mutex.h in Headers */, A7D88A3C23E2437C00DCD162 /* SDL_name.h in Headers */, A7D8ABFE23E2514100DCD162 /* SDL_nullevents_c.h in Headers */, @@ -6540,23 +6007,6 @@ A7D8AD1E23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, A7D8B86D23E2514400DCD162 /* SDL_wave.h in Headers */, A7D8BBAC23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, - A7D8B20D23E2514200DCD162 /* SDL_x11clipboard.h in Headers */, - A7D8B1F523E2514200DCD162 /* SDL_x11dyn.h in Headers */, - A7D8B21323E2514200DCD162 /* SDL_x11events.h in Headers */, - A7D8B1EF23E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8B20723E2514200DCD162 /* SDL_x11keyboard.h in Headers */, - A7D8B14D23E2514200DCD162 /* SDL_x11messagebox.h in Headers */, - A7D8B1B923E2514200DCD162 /* SDL_x11modes.h in Headers */, - A7D8B1FB23E2514200DCD162 /* SDL_x11mouse.h in Headers */, - A7D8B1B323E2514200DCD162 /* SDL_x11opengl.h in Headers */, - A7D8B17123E2514200DCD162 /* SDL_x11opengles.h in Headers */, - A7D8B16523E2514200DCD162 /* SDL_x11shape.h in Headers */, - A7D8B1AD23E2514200DCD162 /* SDL_x11sym.h in Headers */, - A7D8B14723E2514200DCD162 /* SDL_x11touch.h in Headers */, - A7D8B21F23E2514200DCD162 /* SDL_x11video.h in Headers */, - A7D8B1DD23E2514200DCD162 /* SDL_x11vulkan.h in Headers */, - A7D8B1E923E2514200DCD162 /* SDL_x11window.h in Headers */, - A7D8B1D123E2514200DCD162 /* SDL_x11xinput2.h in Headers */, A7D8B3B123E2514200DCD162 /* SDL_yuv_c.h in Headers */, A7D8B9CC23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, A7D88A1623E2437C00DCD162 /* begin_code.h in Headers */, @@ -6564,7 +6014,6 @@ A7D88A1823E2437C00DCD162 /* close_code.h in Headers */, A7D8B5B823E2514300DCD162 /* controller_type.h in Headers */, A7D8BB4C23E2514500DCD162 /* default_cursor.h in Headers */, - A7D8B1D723E2514200DCD162 /* edid.h in Headers */, A7D8B23D23E2514200DCD162 /* egl.h in Headers */, A7D8B24323E2514200DCD162 /* eglext.h in Headers */, A7D8B24923E2514200DCD162 /* eglplatform.h in Headers */, @@ -6572,7 +6021,6 @@ A7D8B22523E2514200DCD162 /* gl2ext.h in Headers */, A7D8B23123E2514200DCD162 /* gl2platform.h in Headers */, A75FDB5923E39E6100529352 /* hidapi.h in Headers */, - A7D8B21923E2514200DCD162 /* imKStoUCS.h in Headers */, A7D8ACA023E2514100DCD162 /* keyinfotable.h in Headers */, A7D8B23723E2514200DCD162 /* khrplatform.h in Headers */, A7D8BB0423E2514500DCD162 /* math_libm.h in Headers */, @@ -6582,6 +6030,7 @@ A7D8BB2223E2514500DCD162 /* scancodes_windows.h in Headers */, A7D8BBA023E2514500DCD162 /* scancodes_xfree86.h in Headers */, A7D8B57023E2514300DCD162 /* usb_ids.h in Headers */, + A1626A532617008D003F1973 /* SDL_triangle.h in Headers */, A7D8B25523E2514200DCD162 /* vk_icd.h in Headers */, A7D8B24F23E2514200DCD162 /* vk_layer.h in Headers */, A7D8B26723E2514200DCD162 /* vk_platform.h in Headers */, @@ -6636,7 +6085,6 @@ A7D8AEB423E2514100DCD162 /* SDL_cocoametalview.h in Headers */, A7D8AEF623E2514100DCD162 /* SDL_cocoamodes.h in Headers */, A7D8AF2023E2514100DCD162 /* SDL_cocoamouse.h in Headers */, - A7D8AEC023E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, A7D8AEDE23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, A7D8AEF023E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, A7D8AE8423E2514100DCD162 /* SDL_cocoashape.h in Headers */, @@ -6700,6 +6148,7 @@ F392819F25860422003191A7 /* SDL_misc.h in Headers */, A7D88BF323E24BED00DCD162 /* SDL_mouse.h in Headers */, A7D8BB1D23E2514500DCD162 /* SDL_mouse_c.h in Headers */, + F38233872738EB8600F7F527 /* SDL_hidapi.h in Headers */, A7D88BF423E24BED00DCD162 /* SDL_mutex.h in Headers */, A7D88BF523E24BED00DCD162 /* SDL_name.h in Headers */, A7D8ABFF23E2514100DCD162 /* SDL_nullevents_c.h in Headers */, @@ -6788,23 +6237,6 @@ A7D8AD1F23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, A7D8B86E23E2514400DCD162 /* SDL_wave.h in Headers */, A7D8BBAD23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, - A7D8B20E23E2514200DCD162 /* SDL_x11clipboard.h in Headers */, - A7D8B1F623E2514200DCD162 /* SDL_x11dyn.h in Headers */, - A7D8B21423E2514200DCD162 /* SDL_x11events.h in Headers */, - A7D8B1F023E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8B20823E2514200DCD162 /* SDL_x11keyboard.h in Headers */, - A7D8B14E23E2514200DCD162 /* SDL_x11messagebox.h in Headers */, - A7D8B1BA23E2514200DCD162 /* SDL_x11modes.h in Headers */, - A7D8B1FC23E2514200DCD162 /* SDL_x11mouse.h in Headers */, - A7D8B1B423E2514200DCD162 /* SDL_x11opengl.h in Headers */, - A7D8B17223E2514200DCD162 /* SDL_x11opengles.h in Headers */, - A7D8B16623E2514200DCD162 /* SDL_x11shape.h in Headers */, - A7D8B1AE23E2514200DCD162 /* SDL_x11sym.h in Headers */, - A7D8B14823E2514200DCD162 /* SDL_x11touch.h in Headers */, - A7D8B22023E2514200DCD162 /* SDL_x11video.h in Headers */, - A7D8B1DE23E2514200DCD162 /* SDL_x11vulkan.h in Headers */, - A7D8B1EA23E2514200DCD162 /* SDL_x11window.h in Headers */, - A7D8B1D223E2514200DCD162 /* SDL_x11xinput2.h in Headers */, A7D8B3B223E2514200DCD162 /* SDL_yuv_c.h in Headers */, A7D8B9CD23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, A7D88BCC23E24BED00DCD162 /* begin_code.h in Headers */, @@ -6812,7 +6244,6 @@ A7D88BCE23E24BED00DCD162 /* close_code.h in Headers */, A7D8B5B923E2514300DCD162 /* controller_type.h in Headers */, A7D8BB4D23E2514500DCD162 /* default_cursor.h in Headers */, - A7D8B1D823E2514200DCD162 /* edid.h in Headers */, A7D8B23E23E2514200DCD162 /* egl.h in Headers */, A7D8B24423E2514200DCD162 /* eglext.h in Headers */, A7D8B24A23E2514200DCD162 /* eglplatform.h in Headers */, @@ -6820,7 +6251,6 @@ A7D8B22623E2514200DCD162 /* gl2ext.h in Headers */, A7D8B23223E2514200DCD162 /* gl2platform.h in Headers */, A75FDB5A23E39E6100529352 /* hidapi.h in Headers */, - A7D8B21A23E2514200DCD162 /* imKStoUCS.h in Headers */, A7D8ACA123E2514100DCD162 /* keyinfotable.h in Headers */, A7D8B23823E2514200DCD162 /* khrplatform.h in Headers */, A7D8BB0523E2514500DCD162 /* math_libm.h in Headers */, @@ -6830,6 +6260,7 @@ A7D8BB2323E2514500DCD162 /* scancodes_windows.h in Headers */, A7D8BBA123E2514500DCD162 /* scancodes_xfree86.h in Headers */, A7D8B57123E2514300DCD162 /* usb_ids.h in Headers */, + A1626A542617008D003F1973 /* SDL_triangle.h in Headers */, A7D8B25623E2514200DCD162 /* vk_icd.h in Headers */, A7D8B25023E2514200DCD162 /* vk_layer.h in Headers */, A7D8B26823E2514200DCD162 /* vk_platform.h in Headers */, @@ -6864,7 +6295,6 @@ A7D8AC0D23E2514100DCD162 /* SDL_shape_internals.h in Headers */, A7D8BA7D23E2514400DCD162 /* SDL_glfuncs.h in Headers */, A7D8AC0723E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8B1D423E2514200DCD162 /* SDL_x11xinput2.h in Headers */, A7D8B99F23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, A7D8B99023E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, A7D8AB8923E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, @@ -6876,21 +6306,16 @@ A7D8AAC023E2514100DCD162 /* SDL_haptic_c.h in Headers */, A7D8A94923E2514000DCD162 /* SDL_dataqueue.h in Headers */, A7D8A96123E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8B21623E2514200DCD162 /* SDL_x11events.h in Headers */, A7D8B98423E2514400DCD162 /* SDL_d3dmath.h in Headers */, - A7D8B1EC23E2514200DCD162 /* SDL_x11window.h in Headers */, A7D8ABDD23E2514100DCD162 /* SDL_egl_c.h in Headers */, A7D8B3D823E2514300DCD162 /* yuv_rgb.h in Headers */, A7D8B79823E2514400DCD162 /* SDL_dummyaudio.h in Headers */, A7D8AC9723E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */, - A7D8B15023E2514200DCD162 /* SDL_x11messagebox.h in Headers */, A7D8B3F023E2514300DCD162 /* SDL_thread_c.h in Headers */, A7D8AF0A23E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8B16823E2514200DCD162 /* SDL_x11shape.h in Headers */, A7D8BA0523E2514400DCD162 /* SDL_blendfillrect.h in Headers */, A7D8B55B23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, A7D8B2C423E2514200DCD162 /* SDL_pixels_c.h in Headers */, - A7D8B1BC23E2514200DCD162 /* SDL_x11modes.h in Headers */, A7D8B58B23E2514300DCD162 /* SDL_joystick_c.h in Headers */, F395C1972569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, A7D8B2B223E2514200DCD162 /* vk_sdk_platform.h in Headers */, @@ -6904,7 +6329,6 @@ A7D8AF2223E2514100DCD162 /* SDL_cocoamouse.h in Headers */, A7D8ADF023E2514100DCD162 /* SDL_blit_slow.h in Headers */, A7D8B9CF23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, - A7D8B1B623E2514200DCD162 /* SDL_x11opengl.h in Headers */, A7D8BBAF23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, A7D8AF0423E2514100DCD162 /* SDL_cocoavideo.h in Headers */, 5605721A2473688C00B46B66 /* SDL_syslocale.h in Headers */, @@ -6912,16 +6336,12 @@ A7D8BB3D23E2514500DCD162 /* SDL_gesture_c.h in Headers */, A7D8BA7723E2514400DCD162 /* SDL_shaders_gl.h in Headers */, A7D8B42C23E2514300DCD162 /* SDL_systhread_c.h in Headers */, - A7D8B20A23E2514200DCD162 /* SDL_x11keyboard.h in Headers */, A7D8AE9223E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, 5616CA5A252BB35D005D5928 /* SDL_sysurl.h in Headers */, A7D8ACE523E2514100DCD162 /* SDL_uikitvulkan.h in Headers */, - A7D8B1F223E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8B22223E2514200DCD162 /* SDL_x11video.h in Headers */, A7D8B27023E2514200DCD162 /* vulkan.hpp in Headers */, A7D8B22823E2514200DCD162 /* gl2ext.h in Headers */, A7D8BB7323E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8B14A23E2514200DCD162 /* SDL_x11touch.h in Headers */, A7D8AAE423E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, A7D8B94E23E2514400DCD162 /* SDL_hints_c.h in Headers */, A7D8B7B623E2514400DCD162 /* SDL_audiodev_c.h in Headers */, @@ -6942,10 +6362,9 @@ A7D8B9F323E2514400DCD162 /* SDL_drawpoint.h in Headers */, A7D8B87023E2514400DCD162 /* SDL_wave.h in Headers */, A7D8AEE023E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, + A1626A562617008D003F1973 /* SDL_triangle.h in Headers */, A7D8B3CC23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8B21C23E2514200DCD162 /* imKStoUCS.h in Headers */, A7D8AB5F23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8B1B023E2514200DCD162 /* SDL_x11sym.h in Headers */, A7D8B8D023E2514400DCD162 /* SDL_coreaudio.h in Headers */, A7D8BA1D23E2514400DCD162 /* SDL_draw.h in Headers */, A7D8BA0B23E2514400DCD162 /* SDL_drawline.h in Headers */, @@ -6953,7 +6372,6 @@ A7D8BBA323E2514500DCD162 /* scancodes_xfree86.h in Headers */, A7D8B5D923E2514300DCD162 /* SDL_syspower.h in Headers */, A75FDAF823E35ED500529352 /* SDL_config_iphoneos.h in Headers */, - A7D8B21023E2514200DCD162 /* SDL_x11clipboard.h in Headers */, A7D8B24623E2514200DCD162 /* eglext.h in Headers */, A7D8BBA923E2514500DCD162 /* SDL_events_c.h in Headers */, A7D8BAC523E2514500DCD162 /* math_private.h in Headers */, @@ -6966,13 +6384,11 @@ A7D8AC0123E2514100DCD162 /* SDL_nullevents_c.h in Headers */, A7D8B58523E2514300DCD162 /* SDL_sysjoystick.h in Headers */, A7D8BB6123E2514500DCD162 /* scancodes_linux.h in Headers */, - A7D8B1F823E2514200DCD162 /* SDL_x11dyn.h in Headers */, A7D8BB6723E2514500DCD162 /* SDL_touch_c.h in Headers */, A7D8B4B023E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, A7D8AEEC23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, A7D8B23423E2514200DCD162 /* gl2platform.h in Headers */, A7D8B25223E2514200DCD162 /* vk_layer.h in Headers */, - A7D8AEC223E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, A7D8B26A23E2514200DCD162 /* vk_platform.h in Headers */, A7D8AEB623E2514100DCD162 /* SDL_cocoametalview.h in Headers */, A7D8AEF223E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, @@ -6984,7 +6400,6 @@ A7D8AB7D23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */, A7D8BB5523E2514500DCD162 /* scancodes_darwin.h in Headers */, A7D8B5BB23E2514300DCD162 /* controller_type.h in Headers */, - A7D8B17423E2514200DCD162 /* SDL_x11opengles.h in Headers */, A7D8AC7923E2514100DCD162 /* SDL_uikitclipboard.h in Headers */, A7D8B2A023E2514200DCD162 /* vulkan_xlib.h in Headers */, A7D8AC9D23E2514100DCD162 /* SDL_uikitwindow.h in Headers */, @@ -6997,7 +6412,6 @@ A7D8B3A223E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, 75E09167241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A7D8B24C23E2514200DCD162 /* eglplatform.h in Headers */, - A7D8B1DA23E2514200DCD162 /* edid.h in Headers */, A7D8B3EA23E2514300DCD162 /* SDL_systhread.h in Headers */, A7D8AECE23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, A7D8AEF823E2514100DCD162 /* SDL_cocoamodes.h in Headers */, @@ -7031,10 +6445,8 @@ A7D8B57323E2514300DCD162 /* usb_ids.h in Headers */, A7D8BA5923E2514400DCD162 /* SDL_gles2funcs.h in Headers */, A7D8AC4323E2514100DCD162 /* SDL_sysvideo.h in Headers */, - A7D8B1FE23E2514200DCD162 /* SDL_x11mouse.h in Headers */, A7D8AB1423E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, A7D8AEFE23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - A7D8B1E023E2514200DCD162 /* SDL_x11vulkan.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7068,7 +6480,6 @@ A7D8AEB223E2514100DCD162 /* SDL_cocoametalview.h in Headers */, A7D8AEF423E2514100DCD162 /* SDL_cocoamodes.h in Headers */, A7D8AF1E23E2514100DCD162 /* SDL_cocoamouse.h in Headers */, - A7D8AEBE23E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, A7D8AEDC23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, A7D8AEEE23E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, A7D8AE8223E2514100DCD162 /* SDL_cocoashape.h in Headers */, @@ -7132,6 +6543,7 @@ 5616CA50252BB2BE005D5928 /* SDL_misc.h in Headers */, AA75582A1595D4D800BBD41B /* SDL_mouse.h in Headers */, A7D8BB1B23E2514500DCD162 /* SDL_mouse_c.h in Headers */, + F38233852738EB8600F7F527 /* SDL_hidapi.h in Headers */, AA75582C1595D4D800BBD41B /* SDL_mutex.h in Headers */, AA75582E1595D4D800BBD41B /* SDL_name.h in Headers */, A7D8ABFD23E2514100DCD162 /* SDL_nullevents_c.h in Headers */, @@ -7220,23 +6632,6 @@ A7D8AD1D23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, A7D8B86C23E2514400DCD162 /* SDL_wave.h in Headers */, A7D8BBAB23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, - A7D8B20C23E2514200DCD162 /* SDL_x11clipboard.h in Headers */, - A7D8B1F423E2514200DCD162 /* SDL_x11dyn.h in Headers */, - A7D8B21223E2514200DCD162 /* SDL_x11events.h in Headers */, - A7D8B1EE23E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8B20623E2514200DCD162 /* SDL_x11keyboard.h in Headers */, - A7D8B14C23E2514200DCD162 /* SDL_x11messagebox.h in Headers */, - A7D8B1B823E2514200DCD162 /* SDL_x11modes.h in Headers */, - A7D8B1FA23E2514200DCD162 /* SDL_x11mouse.h in Headers */, - A7D8B1B223E2514200DCD162 /* SDL_x11opengl.h in Headers */, - A7D8B17023E2514200DCD162 /* SDL_x11opengles.h in Headers */, - A7D8B16423E2514200DCD162 /* SDL_x11shape.h in Headers */, - A7D8B1AC23E2514200DCD162 /* SDL_x11sym.h in Headers */, - A7D8B14623E2514200DCD162 /* SDL_x11touch.h in Headers */, - A7D8B21E23E2514200DCD162 /* SDL_x11video.h in Headers */, - A7D8B1DC23E2514200DCD162 /* SDL_x11vulkan.h in Headers */, - A7D8B1E823E2514200DCD162 /* SDL_x11window.h in Headers */, - A7D8B1D023E2514200DCD162 /* SDL_x11xinput2.h in Headers */, A7D8B3B023E2514200DCD162 /* SDL_yuv_c.h in Headers */, A7D8B9CB23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, AA7557FA1595D4D800BBD41B /* begin_code.h in Headers */, @@ -7244,7 +6639,6 @@ AA7557FC1595D4D800BBD41B /* close_code.h in Headers */, A7D8B5B723E2514300DCD162 /* controller_type.h in Headers */, A7D8BB4B23E2514500DCD162 /* default_cursor.h in Headers */, - A7D8B1D623E2514200DCD162 /* edid.h in Headers */, A7D8B23C23E2514200DCD162 /* egl.h in Headers */, A7D8B24223E2514200DCD162 /* eglext.h in Headers */, A7D8B24823E2514200DCD162 /* eglplatform.h in Headers */, @@ -7252,7 +6646,6 @@ A7D8B22423E2514200DCD162 /* gl2ext.h in Headers */, A7D8B23023E2514200DCD162 /* gl2platform.h in Headers */, A75FDB5823E39E6100529352 /* hidapi.h in Headers */, - A7D8B21823E2514200DCD162 /* imKStoUCS.h in Headers */, A7D8BBD123E2574800DCD162 /* keyinfotable.h in Headers */, A7D8B23623E2514200DCD162 /* khrplatform.h in Headers */, A7D8BB0323E2514500DCD162 /* math_libm.h in Headers */, @@ -7262,6 +6655,7 @@ A7D8BB2123E2514500DCD162 /* scancodes_windows.h in Headers */, A7D8BB9F23E2514500DCD162 /* scancodes_xfree86.h in Headers */, A7D8B56F23E2514300DCD162 /* usb_ids.h in Headers */, + A1626A522617008D003F1973 /* SDL_triangle.h in Headers */, A7D8B25423E2514200DCD162 /* vk_icd.h in Headers */, A7D8B24E23E2514200DCD162 /* vk_layer.h in Headers */, A7D8B26623E2514200DCD162 /* vk_platform.h in Headers */, @@ -7294,7 +6688,6 @@ A7D8AC0C23E2514100DCD162 /* SDL_shape_internals.h in Headers */, A7D8BA7C23E2514400DCD162 /* SDL_glfuncs.h in Headers */, A7D8AC0623E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8B1D323E2514200DCD162 /* SDL_x11xinput2.h in Headers */, 75E09166241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A7D8B99E23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, A7D8B98F23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, @@ -7304,20 +6697,15 @@ A7D8AABF23E2514100DCD162 /* SDL_haptic_c.h in Headers */, A7D8A94823E2514000DCD162 /* SDL_dataqueue.h in Headers */, A7D8A96023E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8B21523E2514200DCD162 /* SDL_x11events.h in Headers */, A7D8B98323E2514400DCD162 /* SDL_d3dmath.h in Headers */, - A7D8B1EB23E2514200DCD162 /* SDL_x11window.h in Headers */, A7D8ABDC23E2514100DCD162 /* SDL_egl_c.h in Headers */, A7D8B3D723E2514300DCD162 /* yuv_rgb.h in Headers */, A7D8B79723E2514400DCD162 /* SDL_dummyaudio.h in Headers */, - A7D8B14F23E2514200DCD162 /* SDL_x11messagebox.h in Headers */, A7D8B3EF23E2514300DCD162 /* SDL_thread_c.h in Headers */, A7D8AF0923E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8B16723E2514200DCD162 /* SDL_x11shape.h in Headers */, A7D8BA0423E2514400DCD162 /* SDL_blendfillrect.h in Headers */, A7D8B55A23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, A7D8B2C323E2514200DCD162 /* SDL_pixels_c.h in Headers */, - A7D8B1BB23E2514200DCD162 /* SDL_x11modes.h in Headers */, A7D8B58A23E2514300DCD162 /* SDL_joystick_c.h in Headers */, A75FDB5B23E39E6100529352 /* hidapi.h in Headers */, A7D8B2B123E2514200DCD162 /* vk_sdk_platform.h in Headers */, @@ -7330,21 +6718,16 @@ A7D8ADEF23E2514100DCD162 /* SDL_blit_slow.h in Headers */, A7D8B9CE23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, A7D8BBFD23E2574800DCD162 /* SDL_uikitvideo.h in Headers */, - A7D8B1B523E2514200DCD162 /* SDL_x11opengl.h in Headers */, A7D8BBAE23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, A7D8AF0323E2514100DCD162 /* SDL_cocoavideo.h in Headers */, A7D8BB3C23E2514500DCD162 /* SDL_gesture_c.h in Headers */, A7D8BBEF23E2574800DCD162 /* SDL_uikitclipboard.h in Headers */, A7D8BA7623E2514400DCD162 /* SDL_shaders_gl.h in Headers */, A7D8B42B23E2514300DCD162 /* SDL_systhread_c.h in Headers */, - A7D8B20923E2514200DCD162 /* SDL_x11keyboard.h in Headers */, A7D8AE9123E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, - A7D8B1F123E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8B22123E2514200DCD162 /* SDL_x11video.h in Headers */, A7D8B26F23E2514200DCD162 /* vulkan.hpp in Headers */, A7D8B22723E2514200DCD162 /* gl2ext.h in Headers */, A7D8BB7223E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8B14923E2514200DCD162 /* SDL_x11touch.h in Headers */, A7D8AAE323E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, A7D8B94D23E2514400DCD162 /* SDL_hints_c.h in Headers */, A7D8B7B523E2514400DCD162 /* SDL_audiodev_c.h in Headers */, @@ -7364,9 +6747,7 @@ A7D8B86F23E2514400DCD162 /* SDL_wave.h in Headers */, A7D8AEDF23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, A7D8B3CB23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8B21B23E2514200DCD162 /* imKStoUCS.h in Headers */, A7D8AB5E23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8B1AF23E2514200DCD162 /* SDL_x11sym.h in Headers */, A7D8B8CF23E2514400DCD162 /* SDL_coreaudio.h in Headers */, A7D8BA1C23E2514400DCD162 /* SDL_draw.h in Headers */, A7D8BA0A23E2514400DCD162 /* SDL_drawline.h in Headers */, @@ -7375,7 +6756,6 @@ A7D8B3B323E2514200DCD162 /* SDL_yuv_c.h in Headers */, A7D8BBA223E2514500DCD162 /* scancodes_xfree86.h in Headers */, A7D8B5D823E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8B20F23E2514200DCD162 /* SDL_x11clipboard.h in Headers */, A7D8BC0523E2574800DCD162 /* SDL_uikitwindow.h in Headers */, A7D8B24523E2514200DCD162 /* eglext.h in Headers */, A7D8BBF123E2574800DCD162 /* SDL_uikitevents.h in Headers */, @@ -7393,14 +6773,13 @@ A7D8AC0023E2514100DCD162 /* SDL_nullevents_c.h in Headers */, A7D8B58423E2514300DCD162 /* SDL_sysjoystick.h in Headers */, A7D8BB6023E2514500DCD162 /* scancodes_linux.h in Headers */, - A7D8B1F723E2514200DCD162 /* SDL_x11dyn.h in Headers */, A7D8BB6623E2514500DCD162 /* SDL_touch_c.h in Headers */, A7D8B4AF23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, A7D8AEEB23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, A7D8B23323E2514200DCD162 /* gl2platform.h in Headers */, A7D8B25123E2514200DCD162 /* vk_layer.h in Headers */, - A7D8AEC123E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, A7D8B26923E2514200DCD162 /* vk_platform.h in Headers */, + A1626A552617008D003F1973 /* SDL_triangle.h in Headers */, A7D8BBF323E2574800DCD162 /* SDL_uikitmessagebox.h in Headers */, A7D8AEB523E2514100DCD162 /* SDL_cocoametalview.h in Headers */, A7D8AEF123E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, @@ -7414,7 +6793,6 @@ A7D8BBCB23E2561600DCD162 /* SDL_steamcontroller.h in Headers */, A7D8BB5423E2514500DCD162 /* scancodes_darwin.h in Headers */, A7D8B5BA23E2514300DCD162 /* controller_type.h in Headers */, - A7D8B17323E2514200DCD162 /* SDL_x11opengles.h in Headers */, A7D8B29F23E2514200DCD162 /* vulkan_xlib.h in Headers */, A7D8B25D23E2514200DCD162 /* vulkan_vi.h in Headers */, A7D8B29923E2514200DCD162 /* vulkan_mir.h in Headers */, @@ -7426,7 +6804,6 @@ A7D8B39B23E2514200DCD162 /* SDL_blit_copy.h in Headers */, A7D8B3A123E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, A7D8B24B23E2514200DCD162 /* eglplatform.h in Headers */, - A7D8B1D923E2514200DCD162 /* edid.h in Headers */, A7D8BC0123E2574800DCD162 /* SDL_uikitviewcontroller.h in Headers */, A7D8B3E923E2514300DCD162 /* SDL_systhread.h in Headers */, A7D8AECD23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, @@ -7462,10 +6839,8 @@ A7D8BA5823E2514400DCD162 /* SDL_gles2funcs.h in Headers */, A75FDBC823EA380300529352 /* SDL_hidapi_rumble.h in Headers */, A7D8AC4223E2514100DCD162 /* SDL_sysvideo.h in Headers */, - A7D8B1FD23E2514200DCD162 /* SDL_x11mouse.h in Headers */, A7D8AB1323E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, A7D8AEFD23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - A7D8B1DF23E2514200DCD162 /* SDL_x11vulkan.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7486,7 +6861,6 @@ DB313FCB17554B71006C0E22 /* SDL_atomic.h in Headers */, 75E09169241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A7D8AC0823E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8B1D523E2514200DCD162 /* SDL_x11xinput2.h in Headers */, A7D8B9A023E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, A7D8B99123E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, A7D8AB8A23E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, @@ -7502,20 +6876,17 @@ DB313FCE17554B71006C0E22 /* SDL_clipboard.h in Headers */, A7D8A94A23E2514000DCD162 /* SDL_dataqueue.h in Headers */, A7D8A96223E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8B21723E2514200DCD162 /* SDL_x11events.h in Headers */, DB313FD017554B71006C0E22 /* SDL_config.h in Headers */, A7D8B98523E2514400DCD162 /* SDL_d3dmath.h in Headers */, - A7D8B1ED23E2514200DCD162 /* SDL_x11window.h in Headers */, DB313FCF17554B71006C0E22 /* SDL_config_macosx.h in Headers */, A7D8ABDE23E2514100DCD162 /* SDL_egl_c.h in Headers */, DB313FD117554B71006C0E22 /* SDL_copying.h in Headers */, + F382338B2738EB8600F7F527 /* SDL_hidapi.h in Headers */, A7D8B3D923E2514300DCD162 /* yuv_rgb.h in Headers */, A7D8B79923E2514400DCD162 /* SDL_dummyaudio.h in Headers */, A7D8AC9823E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */, - A7D8B15123E2514200DCD162 /* SDL_x11messagebox.h in Headers */, A7D8B3F123E2514300DCD162 /* SDL_thread_c.h in Headers */, A7D8AF0B23E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8B16923E2514200DCD162 /* SDL_x11shape.h in Headers */, DB313FD217554B71006C0E22 /* SDL_cpuinfo.h in Headers */, DB313FD317554B71006C0E22 /* SDL_endian.h in Headers */, DB313FD417554B71006C0E22 /* SDL_error.h in Headers */, @@ -7526,7 +6897,6 @@ A7D8B55C23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, F395C1992569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, A7D8B2C523E2514200DCD162 /* SDL_pixels_c.h in Headers */, - A7D8B1BD23E2514200DCD162 /* SDL_x11modes.h in Headers */, A7D8B58C23E2514300DCD162 /* SDL_joystick_c.h in Headers */, A7D8B2B323E2514200DCD162 /* vk_sdk_platform.h in Headers */, A7D8BB4A23E2514500DCD162 /* blank_cursor.h in Headers */, @@ -7540,7 +6910,6 @@ DB313FD817554B71006C0E22 /* SDL_hints.h in Headers */, A7D8ADF123E2514100DCD162 /* SDL_blit_slow.h in Headers */, A7D8B9D023E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, - A7D8B1B723E2514200DCD162 /* SDL_x11opengl.h in Headers */, A7D8BBB023E2514500DCD162 /* SDL_windowevents_c.h in Headers */, DB313FD917554B71006C0E22 /* SDL_joystick.h in Headers */, A7D8AF0523E2514100DCD162 /* SDL_cocoavideo.h in Headers */, @@ -7550,16 +6919,12 @@ A7D8BA7823E2514400DCD162 /* SDL_shaders_gl.h in Headers */, A7D8B42D23E2514300DCD162 /* SDL_systhread_c.h in Headers */, DB313FDB17554B71006C0E22 /* SDL_keycode.h in Headers */, - A7D8B20B23E2514200DCD162 /* SDL_x11keyboard.h in Headers */, A7D8AE9323E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, A7D8ACE623E2514100DCD162 /* SDL_uikitvulkan.h in Headers */, - A7D8B1F323E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8B22323E2514200DCD162 /* SDL_x11video.h in Headers */, A7D8B27123E2514200DCD162 /* vulkan.hpp in Headers */, DB313FDC17554B71006C0E22 /* SDL_loadso.h in Headers */, A7D8B22923E2514200DCD162 /* gl2ext.h in Headers */, A7D8BB7423E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8B14B23E2514200DCD162 /* SDL_x11touch.h in Headers */, A7D8AAE523E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, A7D8B94F23E2514400DCD162 /* SDL_hints_c.h in Headers */, A7D8B7B723E2514400DCD162 /* SDL_audiodev_c.h in Headers */, @@ -7583,10 +6948,9 @@ A7D8B87123E2514400DCD162 /* SDL_wave.h in Headers */, A7D8AEE123E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, A7D8B3CD23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8B21D23E2514200DCD162 /* imKStoUCS.h in Headers */, 5605721B2473688D00B46B66 /* SDL_syslocale.h in Headers */, A7D8AB6023E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8B1B123E2514200DCD162 /* SDL_x11sym.h in Headers */, + A1626A582617008D003F1973 /* SDL_triangle.h in Headers */, A7D8B8D123E2514400DCD162 /* SDL_coreaudio.h in Headers */, A7D8BA1E23E2514400DCD162 /* SDL_draw.h in Headers */, A7D8BA0C23E2514400DCD162 /* SDL_drawline.h in Headers */, @@ -7596,7 +6960,6 @@ A7D8B3B523E2514200DCD162 /* SDL_yuv_c.h in Headers */, A7D8BBA423E2514500DCD162 /* scancodes_xfree86.h in Headers */, A7D8B5DA23E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8B21123E2514200DCD162 /* SDL_x11clipboard.h in Headers */, DB313FE117554B71006C0E22 /* SDL_name.h in Headers */, A7D8B24723E2514200DCD162 /* eglext.h in Headers */, A7D8BBAA23E2514500DCD162 /* SDL_events_c.h in Headers */, @@ -7614,14 +6977,12 @@ A7D8B58623E2514300DCD162 /* SDL_sysjoystick.h in Headers */, A7D8BBCF23E2561600DCD162 /* SDL_steamcontroller.h in Headers */, A7D8BB6223E2514500DCD162 /* scancodes_linux.h in Headers */, - A7D8B1F923E2514200DCD162 /* SDL_x11dyn.h in Headers */, A7D8BB6823E2514500DCD162 /* SDL_touch_c.h in Headers */, A7D8B4B123E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, A7D8AEED23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, A7D8B23523E2514200DCD162 /* gl2platform.h in Headers */, DB313FE517554B71006C0E22 /* SDL_pixels.h in Headers */, A7D8B25323E2514200DCD162 /* vk_layer.h in Headers */, - A7D8AEC323E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, A7D8B26B23E2514200DCD162 /* vk_platform.h in Headers */, A7D8AEB723E2514100DCD162 /* SDL_cocoametalview.h in Headers */, A7D8AEF323E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, @@ -7635,7 +6996,6 @@ A7D8AB7E23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */, A7D8BB5623E2514500DCD162 /* scancodes_darwin.h in Headers */, A7D8B5BC23E2514300DCD162 /* controller_type.h in Headers */, - A7D8B17523E2514200DCD162 /* SDL_x11opengles.h in Headers */, A7D8AC7A23E2514100DCD162 /* SDL_uikitclipboard.h in Headers */, A7D8B2A123E2514200DCD162 /* vulkan_xlib.h in Headers */, A7D8AC9E23E2514100DCD162 /* SDL_uikitwindow.h in Headers */, @@ -7650,7 +7010,6 @@ A7D8B39D23E2514200DCD162 /* SDL_blit_copy.h in Headers */, A7D8B3A323E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, A7D8B24D23E2514200DCD162 /* eglplatform.h in Headers */, - A7D8B1DB23E2514200DCD162 /* edid.h in Headers */, DB313FEB17554B71006C0E22 /* SDL_revision.h in Headers */, A7D8B3EB23E2514300DCD162 /* SDL_systhread.h in Headers */, DB313FEC17554B71006C0E22 /* SDL_rwops.h in Headers */, @@ -7705,10 +7064,8 @@ A7D8AC4423E2514100DCD162 /* SDL_sysvideo.h in Headers */, AAC07104195606770073DCDF /* SDL_opengles2_gl2platform.h in Headers */, AAC07101195606770073DCDF /* SDL_opengles2_gl2ext.h in Headers */, - A7D8B1FF23E2514200DCD162 /* SDL_x11mouse.h in Headers */, A7D8AB1523E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, A7D8AEFF23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - A7D8B1E123E2514200DCD162 /* SDL_x11vulkan.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7755,60 +7112,6 @@ productReference = A75FD06C23E25AC700529352 /* libSDL2.dylib */; productType = "com.apple.product-type.library.dynamic"; }; - A75FDB4823E399AC00529352 /* hidapi-iOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = A75FDB5023E399AC00529352 /* Build configuration list for PBXNativeTarget "hidapi-iOS" */; - buildPhases = ( - A75FDB4423E399AC00529352 /* Headers */, - A75FDB4523E399AC00529352 /* Sources */, - A75FDB4623E399AC00529352 /* Frameworks */, - A75FDB4723E399AC00529352 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "hidapi-iOS"; - productName = hidapi; - productReference = A75FDB4923E399AC00529352 /* hidapi.framework */; - productType = "com.apple.product-type.framework"; - }; - A75FDB6223E3A2C900529352 /* hidapi-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = A75FDB6B23E3A2C900529352 /* Build configuration list for PBXNativeTarget "hidapi-tvOS" */; - buildPhases = ( - A75FDB6323E3A2C900529352 /* Headers */, - A75FDB6523E3A2C900529352 /* Sources */, - A75FDB6723E3A2C900529352 /* Frameworks */, - A75FDB6A23E3A2C900529352 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "hidapi-tvOS"; - productName = hidapi; - productReference = A75FDB6E23E3A2C900529352 /* hidapi.framework */; - productType = "com.apple.product-type.framework"; - }; - A75FDB8023E4C74400529352 /* hidapi */ = { - isa = PBXNativeTarget; - buildConfigurationList = A75FDB8923E4C74400529352 /* Build configuration list for PBXNativeTarget "hidapi" */; - buildPhases = ( - A75FDB8123E4C74400529352 /* Headers */, - A75FDB8323E4C74400529352 /* Sources */, - A75FDB8523E4C74400529352 /* Frameworks */, - A75FDB8823E4C74400529352 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = hidapi; - productName = hidapi; - productReference = A75FDB8C23E4C74400529352 /* hidapi.framework */; - productType = "com.apple.product-type.framework"; - }; A769B08223E259AE00872273 /* Static Library-tvOS */ = { isa = PBXNativeTarget; buildConfigurationList = A769B23A23E259AE00872273 /* Build configuration list for PBXNativeTarget "Static Library-tvOS" */; @@ -7820,7 +7123,7 @@ ); buildRules = ( ); - comments = "This produces libsdl.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; + comments = "This produces libSDL.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; dependencies = ( ); name = "Static Library-tvOS"; @@ -7882,7 +7185,7 @@ ); buildRules = ( ); - comments = "This produces libsdl.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; + comments = "This produces libSDL.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; dependencies = ( ); name = "Static Library-iOS"; @@ -7923,7 +7226,7 @@ ); buildRules = ( ); - comments = "This produces libsdl.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; + comments = "This produces libSDL.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; dependencies = ( ); name = "Static Library"; @@ -7941,7 +7244,6 @@ buildRules = ( ); dependencies = ( - F3190017240CA3BA00ED104F /* PBXTargetDependency */, BECDF6C60761BA81005FE872 /* PBXTargetDependency */, ); name = "Standard DMG"; @@ -7977,11 +7279,6 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1130; - TargetAttributes = { - A75FDB4823E399AC00529352 = { - CreatedOnToolsVersion = 11.3.1; - }; - }; }; buildConfigurationList = 0073178E0858DB0500B2BC32 /* Build configuration list for PBXProject "SDL" */; compatibilityVersion = "Xcode 3.2"; @@ -8007,50 +7304,11 @@ A75FCCFB23E25AB700529352 /* Shared Library-iOS */, A75FCEB423E25AC700529352 /* Shared Library-tvOS */, BECDF6BB0761BA81005FE872 /* Standard DMG */, - A75FDB8023E4C74400529352 /* hidapi */, - A75FDB4823E399AC00529352 /* hidapi-iOS */, - A75FDB6223E3A2C900529352 /* hidapi-tvOS */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - A75FDB4723E399AC00529352 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDBB223E4CB7000529352 /* LICENSE-gpl3.txt in Resources */, - A75FDBA923E4CB7000529352 /* LICENSE-bsd.txt in Resources */, - A75FDBAC23E4CB7000529352 /* AUTHORS.txt in Resources */, - A75FDBB523E4CB7000529352 /* LICENSE.txt in Resources */, - A75FDBAF23E4CB7000529352 /* LICENSE-orig.txt in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB6A23E3A2C900529352 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDBB323E4CB7000529352 /* LICENSE-gpl3.txt in Resources */, - A75FDBAA23E4CB7000529352 /* LICENSE-bsd.txt in Resources */, - A75FDBAD23E4CB7000529352 /* AUTHORS.txt in Resources */, - A75FDBB623E4CB7000529352 /* LICENSE.txt in Resources */, - A75FDBB023E4CB7000529352 /* LICENSE-orig.txt in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB8823E4C74400529352 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDBB123E4CB7000529352 /* LICENSE-gpl3.txt in Resources */, - A75FDBA823E4CB7000529352 /* LICENSE-bsd.txt in Resources */, - A75FDBAB23E4CB7000529352 /* AUTHORS.txt in Resources */, - A75FDBB423E4CB7000529352 /* LICENSE.txt in Resources */, - A75FDBAE23E4CB7000529352 /* LICENSE-orig.txt in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; A7D88ABE23E2437C00DCD162 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -8157,20 +7415,18 @@ A75FCDF223E25AB700529352 /* SDL_render_metal.m in Sources */, A75FCDF323E25AB700529352 /* SDL_clipboard.c in Sources */, A75FCDF423E25AB700529352 /* SDL_cocoaevents.m in Sources */, - A75FCDF523E25AB700529352 /* SDL_x11messagebox.c in Sources */, A75FCDF623E25AB700529352 /* SDL_audiocvt.c in Sources */, A75FCDF723E25AB700529352 /* SDL_shape.c in Sources */, A75FCDF823E25AB700529352 /* SDL_rotate.c in Sources */, A75FCDF923E25AB700529352 /* SDL_coremotionsensor.m in Sources */, A75FDAB123E2795C00529352 /* SDL_hidapi_steam.c in Sources */, A75FCDFA23E25AB700529352 /* SDL_touch.c in Sources */, - A75FCDFB23E25AB700529352 /* SDL_x11events.c in Sources */, + A1626A452617006A003F1973 /* SDL_triangle.c in Sources */, A75FCDFC23E25AB700529352 /* SDL_uikitmessagebox.m in Sources */, A75FCDFD23E25AB700529352 /* SDL_thread.c in Sources */, A75FCDFE23E25AB700529352 /* SDL_hidapi_xbox360w.c in Sources */, A75FCDFF23E25AB700529352 /* SDL_atomic.c in Sources */, A75FCE0023E25AB700529352 /* SDL_displayevents.c in Sources */, - A75FCE0123E25AB700529352 /* SDL_cocoamousetap.m in Sources */, A75FCE0223E25AB700529352 /* SDL_log.c in Sources */, A75FCE0323E25AB700529352 /* SDL_cocoaopengl.m in Sources */, A75FCE0423E25AB700529352 /* SDL_offscreenframebuffer.c in Sources */, @@ -8185,14 +7441,13 @@ A75FCE0D23E25AB700529352 /* SDL_systimer.c in Sources */, A75FCE0E23E25AB700529352 /* SDL_uikitclipboard.m in Sources */, A75FCE0F23E25AB700529352 /* SDL_render_sw.c in Sources */, - A75FCE1023E25AB700529352 /* SDL_x11video.c in Sources */, A75FCE1123E25AB700529352 /* SDL_syssem.c in Sources */, A75FCE1223E25AB700529352 /* SDL_hidapi_xbox360.c in Sources */, A75FCE1323E25AB700529352 /* SDL_coreaudio.m in Sources */, A75FCE1423E25AB700529352 /* SDL_blendline.c in Sources */, + F38233982738EC1800F7F527 /* hid.m in Sources */, A75FCE1523E25AB700529352 /* SDL_blit_A.c in Sources */, A75FCE1623E25AB700529352 /* SDL_d3dmath.c in Sources */, - A75FCE1723E25AB700529352 /* SDL_x11mouse.c in Sources */, A75FCE1823E25AB700529352 /* SDL_nullvideo.c in Sources */, A75FCE1923E25AB700529352 /* SDL_offscreenevents.c in Sources */, A75FCE1A23E25AB700529352 /* SDL_uikitview.m in Sources */, @@ -8203,7 +7458,7 @@ A75FCE1F23E25AB700529352 /* s_copysign.c in Sources */, A75FCE2023E25AB700529352 /* SDL_haptic.c in Sources */, A75FCE2123E25AB700529352 /* SDL_uikitvulkan.m in Sources */, - A75FCE2223E25AB700529352 /* SDL_x11modes.c in Sources */, + F3984CD725BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, 75E09161241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A75FCE2323E25AB700529352 /* SDL_cocoametalview.m in Sources */, A75FCE2423E25AB700529352 /* SDL_audiotypecvt.c in Sources */, @@ -8227,6 +7482,7 @@ A75FCE3523E25AB700529352 /* SDL_error.c in Sources */, A75FCE3623E25AB700529352 /* SDL_blit.c in Sources */, A75FCE3723E25AB700529352 /* SDL_rwops.c in Sources */, + F38233922738EBF300F7F527 /* SDL_hidapi.c in Sources */, A75FCE3823E25AB700529352 /* SDL_uikitviewcontroller.m in Sources */, A75FCE3923E25AB700529352 /* s_cos.c in Sources */, A75FCE3A23E25AB700529352 /* SDL_yuv_sw.c in Sources */, @@ -8235,15 +7491,10 @@ A75FCE3D23E25AB700529352 /* SDL_hints.c in Sources */, A75FCE3E23E25AB700529352 /* SDL_hidapi_ps4.c in Sources */, A75FCE3F23E25AB700529352 /* SDL_pixels.c in Sources */, - A75FCE4023E25AB700529352 /* SDL_x11clipboard.c in Sources */, A75FCE4123E25AB700529352 /* SDL_sysloadso.c in Sources */, - A75FCE4223E25AB700529352 /* SDL_x11xinput2.c in Sources */, A75FCE4323E25AB700529352 /* SDL_syspower.c in Sources */, - A75FCE4423E25AB700529352 /* SDL_x11touch.c in Sources */, A75FCE4523E25AB700529352 /* SDL_iconv.c in Sources */, A75FCE4623E25AB700529352 /* s_fabs.c in Sources */, - A75FCE4723E25AB700529352 /* SDL_x11shape.c in Sources */, - A75FCE4823E25AB700529352 /* imKStoUCS.c in Sources */, A75FCE4923E25AB700529352 /* SDL_shaders_metal.metal in Sources */, F395C1B82569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A75FCE4A23E25AB700529352 /* SDL_uikitwindow.m in Sources */, @@ -8260,7 +7511,6 @@ A75FCE5423E25AB700529352 /* SDL_events.c in Sources */, A75FCE5523E25AB700529352 /* SDL_blit_0.c in Sources */, A75FCE5623E25AB700529352 /* k_tan.c in Sources */, - A75FCE5723E25AB700529352 /* SDL_x11vulkan.c in Sources */, A75FCE5823E25AB700529352 /* SDL_diskaudio.c in Sources */, A75FCE5923E25AB700529352 /* SDL_egl.c in Sources */, A75FCE5A23E25AB700529352 /* SDL_RLEaccel.c in Sources */, @@ -8275,7 +7525,6 @@ A75FCE6323E25AB700529352 /* SDL_string.c in Sources */, A75FCE6423E25AB700529352 /* SDL_render_gl.c in Sources */, A75FCE6523E25AB700529352 /* SDL_uikitopengles.m in Sources */, - A75FCE6623E25AB700529352 /* SDL_x11opengles.c in Sources */, A75FCE6723E25AB700529352 /* SDL_cocoamodes.m in Sources */, A75FCE6823E25AB700529352 /* k_rem_pio2.c in Sources */, A75FCE6A23E25AB700529352 /* SDL_gesture.c in Sources */, @@ -8286,7 +7535,6 @@ A75FCE6F23E25AB700529352 /* SDL_surface.c in Sources */, A75FCE7023E25AB700529352 /* SDL_hidapi_xboxone.c in Sources */, A75FCE7123E25AB700529352 /* SDL_blit_auto.c in Sources */, - A75FCE7223E25AB700529352 /* SDL_x11keyboard.c in Sources */, A75FCE7323E25AB700529352 /* SDL_keyboard.c in Sources */, A75FCE7523E25AB700529352 /* SDL_rect.c in Sources */, A75FCE7623E25AB700529352 /* SDL_cocoaopengles.m in Sources */, @@ -8295,7 +7543,6 @@ A75FCE7823E25AB700529352 /* SDL_hidapi_switch.c in Sources */, A75FCE7923E25AB700529352 /* SDL_strtokr.c in Sources */, A75FCE7A23E25AB700529352 /* SDL_clipboardevents.c in Sources */, - A75FCE7B23E25AB700529352 /* SDL_x11framebuffer.c in Sources */, A75FCE7C23E25AB700529352 /* k_cos.c in Sources */, A75FCE7D23E25AB700529352 /* SDL_hidapijoystick.c in Sources */, A75FCE7E23E25AB700529352 /* SDL_malloc.c in Sources */, @@ -8309,6 +7556,7 @@ A75FCE8623E25AB700529352 /* SDL_cocoawindow.m in Sources */, A75FCE8723E25AB700529352 /* SDL_sysmutex.c in Sources */, A75FCE8823E25AB700529352 /* SDL_syshaptic.c in Sources */, + F3F07D61269640160074468B /* SDL_hidapi_luna.c in Sources */, A75FCE8923E25AB700529352 /* SDL_rwopsbundlesupport.m in Sources */, A75FCE8A23E25AB700529352 /* SDL_video.c in Sources */, A75FCE8B23E25AB700529352 /* SDL_offscreenopengl.c in Sources */, @@ -8316,7 +7564,6 @@ A75FCE8D23E25AB700529352 /* SDL_steamcontroller.c in Sources */, A75FCE8E23E25AB700529352 /* SDL_shaders_gles2.c in Sources */, A75FCE8F23E25AB700529352 /* SDL_blit_1.c in Sources */, - A75FCE9023E25AB700529352 /* SDL_x11dyn.c in Sources */, A75FCE9123E25AB700529352 /* SDL_mouse.c in Sources */, A75FCE9223E25AB700529352 /* e_rem_pio2.c in Sources */, A75FCE9323E25AB700529352 /* SDL_dataqueue.c in Sources */, @@ -8324,15 +7571,12 @@ A75FCE9423E25AB700529352 /* SDL_sysjoystick.c in Sources */, A75FCE9523E25AB700529352 /* SDL_cpuinfo.c in Sources */, A75FCE9623E25AB700529352 /* SDL_sensor.c in Sources */, - A75FCE9723E25AB700529352 /* SDL_x11window.c in Sources */, A75FCE9823E25AB700529352 /* k_sin.c in Sources */, - A75FCE9923E25AB700529352 /* edid-parse.c in Sources */, A75FCE9A23E25AB700529352 /* SDL_systimer.c in Sources */, A75FCE9B23E25AB700529352 /* SDL_drawpoint.c in Sources */, A75FCE9C23E25AB700529352 /* e_sqrt.c in Sources */, A75FCE9D23E25AB700529352 /* SDL_cocoavideo.m in Sources */, A75FCE9F23E25AB700529352 /* SDL.c in Sources */, - A75FCEA023E25AB700529352 /* SDL_x11opengl.c in Sources */, A75FCEA123E25AB700529352 /* SDL_cocoavulkan.m in Sources */, A75FCEA223E25AB700529352 /* SDL_uikitappdelegate.m in Sources */, A75FCEA323E25AB700529352 /* SDL_offscreenwindow.c in Sources */, @@ -8358,20 +7602,18 @@ A75FCFAB23E25AC700529352 /* SDL_render_metal.m in Sources */, A75FCFAC23E25AC700529352 /* SDL_clipboard.c in Sources */, A75FCFAD23E25AC700529352 /* SDL_cocoaevents.m in Sources */, - A75FCFAE23E25AC700529352 /* SDL_x11messagebox.c in Sources */, A75FCFAF23E25AC700529352 /* SDL_audiocvt.c in Sources */, A75FCFB023E25AC700529352 /* SDL_shape.c in Sources */, A75FCFB123E25AC700529352 /* SDL_rotate.c in Sources */, A75FCFB223E25AC700529352 /* SDL_coremotionsensor.m in Sources */, A75FDAB223E2795C00529352 /* SDL_hidapi_steam.c in Sources */, A75FCFB323E25AC700529352 /* SDL_touch.c in Sources */, - A75FCFB423E25AC700529352 /* SDL_x11events.c in Sources */, + A1626A462617006A003F1973 /* SDL_triangle.c in Sources */, A75FCFB523E25AC700529352 /* SDL_uikitmessagebox.m in Sources */, A75FCFB623E25AC700529352 /* SDL_thread.c in Sources */, A75FCFB723E25AC700529352 /* SDL_hidapi_xbox360w.c in Sources */, A75FCFB823E25AC700529352 /* SDL_atomic.c in Sources */, A75FCFB923E25AC700529352 /* SDL_displayevents.c in Sources */, - A75FCFBA23E25AC700529352 /* SDL_cocoamousetap.m in Sources */, A75FCFBB23E25AC700529352 /* SDL_log.c in Sources */, A75FCFBC23E25AC700529352 /* SDL_cocoaopengl.m in Sources */, A75FCFBD23E25AC700529352 /* SDL_offscreenframebuffer.c in Sources */, @@ -8386,14 +7628,13 @@ A75FCFC623E25AC700529352 /* SDL_systimer.c in Sources */, A75FCFC723E25AC700529352 /* SDL_uikitclipboard.m in Sources */, A75FCFC823E25AC700529352 /* SDL_render_sw.c in Sources */, - A75FCFC923E25AC700529352 /* SDL_x11video.c in Sources */, A75FCFCA23E25AC700529352 /* SDL_syssem.c in Sources */, A75FCFCB23E25AC700529352 /* SDL_hidapi_xbox360.c in Sources */, A75FCFCC23E25AC700529352 /* SDL_coreaudio.m in Sources */, A75FCFCD23E25AC700529352 /* SDL_blendline.c in Sources */, + F38233992738EC1800F7F527 /* hid.m in Sources */, A75FCFCE23E25AC700529352 /* SDL_blit_A.c in Sources */, A75FCFCF23E25AC700529352 /* SDL_d3dmath.c in Sources */, - A75FCFD023E25AC700529352 /* SDL_x11mouse.c in Sources */, A75FCFD123E25AC700529352 /* SDL_nullvideo.c in Sources */, A75FCFD223E25AC700529352 /* SDL_offscreenevents.c in Sources */, A75FCFD323E25AC700529352 /* SDL_uikitview.m in Sources */, @@ -8404,7 +7645,7 @@ A75FCFD823E25AC700529352 /* s_copysign.c in Sources */, A75FCFD923E25AC700529352 /* SDL_haptic.c in Sources */, A75FCFDA23E25AC700529352 /* SDL_uikitvulkan.m in Sources */, - A75FCFDB23E25AC700529352 /* SDL_x11modes.c in Sources */, + F3984CD825BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, 75E09162241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A75FCFDC23E25AC700529352 /* SDL_cocoametalview.m in Sources */, A75FCFDD23E25AC700529352 /* SDL_audiotypecvt.c in Sources */, @@ -8428,6 +7669,7 @@ A75FCFEE23E25AC700529352 /* SDL_error.c in Sources */, A75FCFEF23E25AC700529352 /* SDL_blit.c in Sources */, A75FCFF023E25AC700529352 /* SDL_rwops.c in Sources */, + F38233932738EBF300F7F527 /* SDL_hidapi.c in Sources */, A75FCFF123E25AC700529352 /* SDL_uikitviewcontroller.m in Sources */, A75FCFF223E25AC700529352 /* s_cos.c in Sources */, A75FCFF323E25AC700529352 /* SDL_yuv_sw.c in Sources */, @@ -8436,15 +7678,10 @@ A75FCFF623E25AC700529352 /* SDL_hints.c in Sources */, A75FCFF723E25AC700529352 /* SDL_hidapi_ps4.c in Sources */, A75FCFF823E25AC700529352 /* SDL_pixels.c in Sources */, - A75FCFF923E25AC700529352 /* SDL_x11clipboard.c in Sources */, A75FCFFA23E25AC700529352 /* SDL_sysloadso.c in Sources */, - A75FCFFB23E25AC700529352 /* SDL_x11xinput2.c in Sources */, A75FCFFC23E25AC700529352 /* SDL_syspower.c in Sources */, - A75FCFFD23E25AC700529352 /* SDL_x11touch.c in Sources */, A75FCFFE23E25AC700529352 /* SDL_iconv.c in Sources */, A75FCFFF23E25AC700529352 /* s_fabs.c in Sources */, - A75FD00023E25AC700529352 /* SDL_x11shape.c in Sources */, - A75FD00123E25AC700529352 /* imKStoUCS.c in Sources */, A75FD00223E25AC700529352 /* SDL_shaders_metal.metal in Sources */, F395C1B92569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A75FD00323E25AC700529352 /* SDL_uikitwindow.m in Sources */, @@ -8461,7 +7698,6 @@ A75FD00D23E25AC700529352 /* SDL_events.c in Sources */, A75FD00E23E25AC700529352 /* SDL_blit_0.c in Sources */, A75FD00F23E25AC700529352 /* k_tan.c in Sources */, - A75FD01023E25AC700529352 /* SDL_x11vulkan.c in Sources */, A75FD01123E25AC700529352 /* SDL_diskaudio.c in Sources */, A75FD01223E25AC700529352 /* SDL_egl.c in Sources */, A75FD01323E25AC700529352 /* SDL_RLEaccel.c in Sources */, @@ -8476,7 +7712,6 @@ A75FD01C23E25AC700529352 /* SDL_string.c in Sources */, A75FD01D23E25AC700529352 /* SDL_render_gl.c in Sources */, A75FD01E23E25AC700529352 /* SDL_uikitopengles.m in Sources */, - A75FD01F23E25AC700529352 /* SDL_x11opengles.c in Sources */, A75FD02023E25AC700529352 /* SDL_cocoamodes.m in Sources */, A75FD02123E25AC700529352 /* k_rem_pio2.c in Sources */, A75FD02323E25AC700529352 /* SDL_gesture.c in Sources */, @@ -8487,7 +7722,6 @@ A75FD02823E25AC700529352 /* SDL_surface.c in Sources */, A75FD02923E25AC700529352 /* SDL_hidapi_xboxone.c in Sources */, A75FD02A23E25AC700529352 /* SDL_blit_auto.c in Sources */, - A75FD02B23E25AC700529352 /* SDL_x11keyboard.c in Sources */, A75FD02C23E25AC700529352 /* SDL_keyboard.c in Sources */, A75FD02E23E25AC700529352 /* SDL_rect.c in Sources */, A75FD02F23E25AC700529352 /* SDL_cocoaopengles.m in Sources */, @@ -8496,7 +7730,6 @@ A75FD03123E25AC700529352 /* SDL_hidapi_switch.c in Sources */, A75FD03223E25AC700529352 /* SDL_strtokr.c in Sources */, A75FD03323E25AC700529352 /* SDL_clipboardevents.c in Sources */, - A75FD03423E25AC700529352 /* SDL_x11framebuffer.c in Sources */, A75FD03523E25AC700529352 /* k_cos.c in Sources */, A75FD03623E25AC700529352 /* SDL_hidapijoystick.c in Sources */, A75FD03723E25AC700529352 /* SDL_malloc.c in Sources */, @@ -8510,6 +7743,7 @@ A75FD03F23E25AC700529352 /* SDL_cocoawindow.m in Sources */, A75FD04023E25AC700529352 /* SDL_sysmutex.c in Sources */, A75FD04123E25AC700529352 /* SDL_syshaptic.c in Sources */, + F3F07D62269640160074468B /* SDL_hidapi_luna.c in Sources */, A75FD04223E25AC700529352 /* SDL_rwopsbundlesupport.m in Sources */, A75FD04323E25AC700529352 /* SDL_video.c in Sources */, A75FD04423E25AC700529352 /* SDL_offscreenopengl.c in Sources */, @@ -8517,7 +7751,6 @@ A75FD04623E25AC700529352 /* SDL_steamcontroller.c in Sources */, A75FD04723E25AC700529352 /* SDL_shaders_gles2.c in Sources */, A75FD04823E25AC700529352 /* SDL_blit_1.c in Sources */, - A75FD04923E25AC700529352 /* SDL_x11dyn.c in Sources */, A75FD04A23E25AC700529352 /* SDL_mouse.c in Sources */, A75FD04B23E25AC700529352 /* e_rem_pio2.c in Sources */, A75FD04C23E25AC700529352 /* SDL_dataqueue.c in Sources */, @@ -8525,45 +7758,18 @@ A75FD04D23E25AC700529352 /* SDL_sysjoystick.c in Sources */, A75FD04E23E25AC700529352 /* SDL_cpuinfo.c in Sources */, A75FD04F23E25AC700529352 /* SDL_sensor.c in Sources */, - A75FD05023E25AC700529352 /* SDL_x11window.c in Sources */, A75FD05123E25AC700529352 /* k_sin.c in Sources */, - A75FD05223E25AC700529352 /* edid-parse.c in Sources */, A75FD05323E25AC700529352 /* SDL_systimer.c in Sources */, A75FD05423E25AC700529352 /* SDL_drawpoint.c in Sources */, A75FD05523E25AC700529352 /* e_sqrt.c in Sources */, A75FD05623E25AC700529352 /* SDL_cocoavideo.m in Sources */, A75FD05823E25AC700529352 /* SDL.c in Sources */, - A75FD05923E25AC700529352 /* SDL_x11opengl.c in Sources */, A75FD05A23E25AC700529352 /* SDL_cocoavulkan.m in Sources */, A75FD05B23E25AC700529352 /* SDL_uikitappdelegate.m in Sources */, A75FD05C23E25AC700529352 /* SDL_offscreenwindow.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - A75FDB4523E399AC00529352 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB5323E39D1C00529352 /* hid.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB6523E3A2C900529352 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB6623E3A2C900529352 /* hid.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB8323E4C74400529352 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB9323E4C8DB00529352 /* hid.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; A769B17023E259AE00872273 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -8581,19 +7787,16 @@ A769B17A23E259AE00872273 /* SDL_render_metal.m in Sources */, A769B17B23E259AE00872273 /* SDL_clipboard.c in Sources */, A769B17C23E259AE00872273 /* SDL_cocoaevents.m in Sources */, - A769B17D23E259AE00872273 /* SDL_x11messagebox.c in Sources */, A769B17E23E259AE00872273 /* SDL_audiocvt.c in Sources */, A769B17F23E259AE00872273 /* SDL_shape.c in Sources */, A769B18023E259AE00872273 /* SDL_rotate.c in Sources */, A769B18123E259AE00872273 /* SDL_coremotionsensor.m in Sources */, A769B18223E259AE00872273 /* SDL_touch.c in Sources */, - A769B18423E259AE00872273 /* SDL_x11events.c in Sources */, A769B18523E259AE00872273 /* SDL_uikitmessagebox.m in Sources */, A769B18623E259AE00872273 /* SDL_thread.c in Sources */, A769B18723E259AE00872273 /* SDL_hidapi_xbox360w.c in Sources */, A769B18823E259AE00872273 /* SDL_atomic.c in Sources */, A769B18923E259AE00872273 /* SDL_displayevents.c in Sources */, - A769B18A23E259AE00872273 /* SDL_cocoamousetap.m in Sources */, A769B18B23E259AE00872273 /* SDL_log.c in Sources */, A769B18C23E259AE00872273 /* SDL_cocoaopengl.m in Sources */, A769B18D23E259AE00872273 /* SDL_offscreenframebuffer.c in Sources */, @@ -8608,14 +7811,12 @@ A769B19623E259AE00872273 /* SDL_systimer.c in Sources */, A769B19723E259AE00872273 /* SDL_uikitclipboard.m in Sources */, A769B19823E259AE00872273 /* SDL_render_sw.c in Sources */, - A769B19923E259AE00872273 /* SDL_x11video.c in Sources */, A769B19A23E259AE00872273 /* SDL_syssem.c in Sources */, A769B19B23E259AE00872273 /* SDL_hidapi_xbox360.c in Sources */, A769B19C23E259AE00872273 /* SDL_coreaudio.m in Sources */, A769B19D23E259AE00872273 /* SDL_blendline.c in Sources */, A769B19E23E259AE00872273 /* SDL_blit_A.c in Sources */, A769B19F23E259AE00872273 /* SDL_d3dmath.c in Sources */, - A769B1A023E259AE00872273 /* SDL_x11mouse.c in Sources */, A769B1A123E259AE00872273 /* SDL_nullvideo.c in Sources */, A769B1A223E259AE00872273 /* SDL_offscreenevents.c in Sources */, A769B1A323E259AE00872273 /* SDL_uikitview.m in Sources */, @@ -8626,7 +7827,6 @@ A769B1A823E259AE00872273 /* s_copysign.c in Sources */, A769B1A923E259AE00872273 /* SDL_haptic.c in Sources */, A769B1AA23E259AE00872273 /* SDL_uikitvulkan.m in Sources */, - A769B1AB23E259AE00872273 /* SDL_x11modes.c in Sources */, A769B1AC23E259AE00872273 /* SDL_cocoametalview.m in Sources */, A769B1AD23E259AE00872273 /* SDL_audiotypecvt.c in Sources */, A769B1AE23E259AE00872273 /* SDL_uikitevents.m in Sources */, @@ -8640,6 +7840,7 @@ A769B1B523E259AE00872273 /* SDL_cocoakeyboard.m in Sources */, A769B1B623E259AE00872273 /* SDL_dynapi.c in Sources */, A769B1B723E259AE00872273 /* SDL_shaders_gl.c in Sources */, + F38233912738EBF100F7F527 /* SDL_hidapi.c in Sources */, A769B1B823E259AE00872273 /* e_log.c in Sources */, A769B1B923E259AE00872273 /* SDL_cocoamessagebox.m in Sources */, A769B1BA23E259AE00872273 /* SDL_blendfillrect.c in Sources */, @@ -8659,15 +7860,10 @@ F3A490A32554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A769B1C823E259AE00872273 /* SDL_hidapi_ps4.c in Sources */, A769B1C923E259AE00872273 /* SDL_pixels.c in Sources */, - A769B1CA23E259AE00872273 /* SDL_x11clipboard.c in Sources */, A769B1CB23E259AE00872273 /* SDL_sysloadso.c in Sources */, - A769B1CC23E259AE00872273 /* SDL_x11xinput2.c in Sources */, A769B1CD23E259AE00872273 /* SDL_syspower.c in Sources */, - A769B1CE23E259AE00872273 /* SDL_x11touch.c in Sources */, A769B1CF23E259AE00872273 /* SDL_iconv.c in Sources */, A769B1D023E259AE00872273 /* s_fabs.c in Sources */, - A769B1D123E259AE00872273 /* SDL_x11shape.c in Sources */, - A769B1D223E259AE00872273 /* imKStoUCS.c in Sources */, A769B1D323E259AE00872273 /* SDL_shaders_metal.metal in Sources */, 5616CA5E252BB35E005D5928 /* SDL_url.c in Sources */, A769B1D423E259AE00872273 /* SDL_uikitwindow.m in Sources */, @@ -8683,7 +7879,6 @@ A769B1DE23E259AE00872273 /* SDL_events.c in Sources */, A769B1DF23E259AE00872273 /* SDL_blit_0.c in Sources */, A769B1E023E259AE00872273 /* k_tan.c in Sources */, - A769B1E123E259AE00872273 /* SDL_x11vulkan.c in Sources */, A769B1E223E259AE00872273 /* SDL_diskaudio.c in Sources */, A769B1E423E259AE00872273 /* SDL_egl.c in Sources */, A769B1E523E259AE00872273 /* SDL_RLEaccel.c in Sources */, @@ -8691,6 +7886,7 @@ A769B1E823E259AE00872273 /* SDL_bmp.c in Sources */, 75E0915F241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A769B1E923E259AE00872273 /* SDL_uikit_main.c in Sources */, + F3F07D5F269640160074468B /* SDL_hidapi_luna.c in Sources */, A769B1EA23E259AE00872273 /* SDL_stdlib.c in Sources */, A769B1EB23E259AE00872273 /* SDL_dummyaudio.c in Sources */, A769B1EC23E259AE00872273 /* SDL_fillrect.c in Sources */, @@ -8699,7 +7895,6 @@ A769B1EF23E259AE00872273 /* SDL_string.c in Sources */, A769B1F023E259AE00872273 /* SDL_render_gl.c in Sources */, A769B1F123E259AE00872273 /* SDL_uikitopengles.m in Sources */, - A769B1F223E259AE00872273 /* SDL_x11opengles.c in Sources */, A769B1F323E259AE00872273 /* SDL_cocoamodes.m in Sources */, A769B1F423E259AE00872273 /* k_rem_pio2.c in Sources */, A769B1F623E259AE00872273 /* SDL_gesture.c in Sources */, @@ -8711,17 +7906,16 @@ F395BF6A25633B2400942BFF /* SDL_crc32.c in Sources */, A769B1FC23E259AE00872273 /* SDL_hidapi_xboxone.c in Sources */, A769B1FD23E259AE00872273 /* SDL_blit_auto.c in Sources */, - A769B1FE23E259AE00872273 /* SDL_x11keyboard.c in Sources */, A769B1FF23E259AE00872273 /* SDL_keyboard.c in Sources */, 560572132473688200B46B66 /* SDL_locale.c in Sources */, A769B20123E259AE00872273 /* SDL_rect.c in Sources */, A769B20223E259AE00872273 /* SDL_cocoaopengles.m in Sources */, A769B20323E259AE00872273 /* SDL_qsort.c in Sources */, A769B20423E259AE00872273 /* SDL_hidapi_switch.c in Sources */, + F3984CD525BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A769B20523E259AE00872273 /* SDL_strtokr.c in Sources */, 5605720B2473687A00B46B66 /* SDL_syslocale.m in Sources */, A769B20623E259AE00872273 /* SDL_clipboardevents.c in Sources */, - A769B20723E259AE00872273 /* SDL_x11framebuffer.c in Sources */, A769B20823E259AE00872273 /* k_cos.c in Sources */, A769B20923E259AE00872273 /* SDL_hidapijoystick.c in Sources */, A769B20A23E259AE00872273 /* SDL_malloc.c in Sources */, @@ -8740,28 +7934,26 @@ A769B21523E259AE00872273 /* SDL_rwopsbundlesupport.m in Sources */, A769B21623E259AE00872273 /* SDL_video.c in Sources */, A769B21723E259AE00872273 /* SDL_offscreenopengl.c in Sources */, + F38233972738EC1600F7F527 /* hid.m in Sources */, A769B21823E259AE00872273 /* SDL_uikitmetalview.m in Sources */, A769B21923E259AE00872273 /* SDL_shaders_gles2.c in Sources */, A769B21A23E259AE00872273 /* SDL_blit_1.c in Sources */, - A769B21B23E259AE00872273 /* SDL_x11dyn.c in Sources */, A769B21C23E259AE00872273 /* SDL_mouse.c in Sources */, A769B21D23E259AE00872273 /* e_rem_pio2.c in Sources */, A769B21E23E259AE00872273 /* SDL_dataqueue.c in Sources */, A769B21F23E259AE00872273 /* SDL_sysjoystick.c in Sources */, A769B22023E259AE00872273 /* SDL_cpuinfo.c in Sources */, A769B22123E259AE00872273 /* SDL_sensor.c in Sources */, - A769B22223E259AE00872273 /* SDL_x11window.c in Sources */, A769B22323E259AE00872273 /* k_sin.c in Sources */, - A769B22423E259AE00872273 /* edid-parse.c in Sources */, A769B22523E259AE00872273 /* SDL_systimer.c in Sources */, A769B22623E259AE00872273 /* SDL_drawpoint.c in Sources */, F395C1B62569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A769B22723E259AE00872273 /* e_sqrt.c in Sources */, A769B22823E259AE00872273 /* SDL_cocoavideo.m in Sources */, A769B22923E259AE00872273 /* SDL.c in Sources */, - A769B22A23E259AE00872273 /* SDL_x11opengl.c in Sources */, A769B22B23E259AE00872273 /* SDL_cocoavulkan.m in Sources */, A769B22C23E259AE00872273 /* SDL_uikitappdelegate.m in Sources */, + A1626A432617006A003F1973 /* SDL_triangle.c in Sources */, A769B22D23E259AE00872273 /* SDL_offscreenwindow.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -8784,19 +7976,17 @@ A7D8AE7723E2514100DCD162 /* SDL_clipboard.c in Sources */, 75E0915B241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A7D8AEC523E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1BF23E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86723E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AB23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9F623E2514400DCD162 /* SDL_rotate.c in Sources */, A7D8A97623E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, A7D8BB8E23E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19B23E2514200DCD162 /* SDL_x11events.c in Sources */, A7D8AC5223E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */, A7D8B3F323E2514300DCD162 /* SDL_thread.c in Sources */, + A1626A3F2617006A003F1973 /* SDL_triangle.c in Sources */, A7D8B55E23E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, A7D8A95823E2514000DCD162 /* SDL_atomic.c in Sources */, A7D8BB2823E2514500DCD162 /* SDL_displayevents.c in Sources */, - A7D8AF1923E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, A7D8AB2623E2514100DCD162 /* SDL_log.c in Sources */, A7D8AE8923E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, A7D8AB7423E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, @@ -8811,14 +8001,13 @@ A7D8AB3823E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8ACAC23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, A7D8BA1423E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B18F23E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42323E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53A23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D323E2514400DCD162 /* SDL_coreaudio.m in Sources */, A7D8BA2023E2514400DCD162 /* SDL_blendline.c in Sources */, A7D8ADF323E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BA3823E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17723E2514200DCD162 /* SDL_x11mouse.c in Sources */, + F38233942738EC1400F7F527 /* hid.m in Sources */, A7D8ABEC23E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6823E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ACA623E2514100DCD162 /* SDL_uikitview.m in Sources */, @@ -8829,9 +8018,9 @@ A7D8BA9823E2514400DCD162 /* s_copysign.c in Sources */, A7D8AAB723E2514100DCD162 /* SDL_haptic.c in Sources */, A7D8AC8E23E2514100DCD162 /* SDL_uikitvulkan.m in Sources */, - A7D8B15323E2514200DCD162 /* SDL_x11modes.c in Sources */, A7D8AF2523E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86123E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, + F3984CD125BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A7D8AC5823E2514100DCD162 /* SDL_uikitevents.m in Sources */, A7D8ACB823E2514100DCD162 /* SDL_uikitmodes.m in Sources */, A7D8AD3323E2514100DCD162 /* SDL_blit_N.c in Sources */, @@ -8855,21 +8044,17 @@ A7D8BA9223E2514400DCD162 /* s_cos.c in Sources */, A7D8B4D123E2514300DCD162 /* SDL_steamcontroller.c in Sources */, A7D8B9D223E2514400DCD162 /* SDL_yuv_sw.c in Sources */, + F382338E2738EBEC00F7F527 /* SDL_hidapi.c in Sources */, A7D8B76B23E2514300DCD162 /* SDL_wave.c in Sources */, A7D8BAD423E2514500DCD162 /* s_tan.c in Sources */, A7D8AA6623E2514000DCD162 /* SDL_hints.c in Sources */, A7D8B54023E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD6F23E2514100DCD162 /* SDL_pixels.c in Sources */, 5616CA52252BB35A005D5928 /* SDL_url.c in Sources */, - A7D8B1A123E2514200DCD162 /* SDL_x11clipboard.c in Sources */, A7D8B75F23E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B16B23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F423E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B1C523E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95123E2514400DCD162 /* SDL_iconv.c in Sources */, A7D8BA9E23E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E323E2514200DCD162 /* SDL_x11shape.c in Sources */, - A7D8B19523E2514200DCD162 /* imKStoUCS.c in Sources */, A7D8B99323E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, A7D8AC4C23E2514100DCD162 /* SDL_uikitwindow.m in Sources */, A7D8B97B23E2514400DCD162 /* SDL_render.c in Sources */, @@ -8886,7 +8071,6 @@ A7D8ADE723E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0A23E2514500DCD162 /* k_tan.c in Sources */, A75FDBCF23EA380300529352 /* SDL_hidapi_rumble.c in Sources */, - A7D8B15F23E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A7D8B8A923E2514400DCD162 /* SDL_diskaudio.c in Sources */, A7D8AFC123E2514200DCD162 /* SDL_egl.c in Sources */, A7D8AC3423E2514100DCD162 /* SDL_RLEaccel.c in Sources */, @@ -8901,7 +8085,6 @@ A7D8BA8023E2514400DCD162 /* SDL_render_gl.c in Sources */, F3ADAB8E2576F0B400A6B1D9 /* SDL_sysurl.m in Sources */, A7D8AC8223E2514100DCD162 /* SDL_uikitopengles.m in Sources */, - A7D8B20123E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9523E2514100DCD162 /* SDL_cocoamodes.m in Sources */, A7D8BAA423E2514400DCD162 /* k_rem_pio2.c in Sources */, A7D8BB9A23E2514500DCD162 /* SDL_gesture.c in Sources */, @@ -8912,7 +8095,6 @@ A7D8AC2E23E2514100DCD162 /* SDL_surface.c in Sources */, A7D8B54C23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2423E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1A723E2514200DCD162 /* SDL_x11keyboard.c in Sources */, A7D8BB6A23E2514500DCD162 /* SDL_keyboard.c in Sources */, A7D8ACE823E2514100DCD162 /* SDL_rect.c in Sources */, A7D8AE9B23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, @@ -8920,7 +8102,6 @@ A7D8B55223E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96323E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7623E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18323E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, A7D8BAB623E2514400DCD162 /* k_cos.c in Sources */, A7D8B54623E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97523E2514400DCD162 /* SDL_malloc.c in Sources */, @@ -8937,13 +8118,13 @@ A7D8B5CA23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, A7D8AC1023E2514100DCD162 /* SDL_video.c in Sources */, 560572062473687700B46B66 /* SDL_syslocale.m in Sources */, + F3F07D5B269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8AB5623E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, A7D8ACC423E2514100DCD162 /* SDL_uikitmetalview.m in Sources */, A7D8BA5C23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, A7D8B14123E2514200DCD162 /* SDL_blit_1.c in Sources */, 5605720F2473688000B46B66 /* SDL_locale.c in Sources */, F3A4909F2554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, - A7D8B17D23E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1623E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADA23E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB1023E2514500DCD162 /* SDL_dataqueue.c in Sources */, @@ -8951,16 +8132,13 @@ F395C19D2569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, A7D8B3E123E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99423E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18923E2514200DCD162 /* SDL_x11window.c in Sources */, A75FDAAD23E2795C00529352 /* SDL_hidapi_steam.c in Sources */, A7D8BAAA23E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CB23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4A23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA2623E2514400DCD162 /* SDL_drawpoint.c in Sources */, A7D8BAF823E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEAD23E2514100DCD162 /* SDL_cocoavideo.m in Sources */, A7D8A94C23E2514000DCD162 /* SDL.c in Sources */, - A7D8B15923E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8AEA123E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AC6423E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */, A7D8AB6223E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, @@ -8985,19 +8163,17 @@ A7D8AE7823E2514100DCD162 /* SDL_clipboard.c in Sources */, 75E0915C241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A7D8AEC623E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1C023E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86823E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AC23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9F723E2514400DCD162 /* SDL_rotate.c in Sources */, A7D8A97723E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, A7D8BB8F23E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19C23E2514200DCD162 /* SDL_x11events.c in Sources */, A7D8AC5323E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */, A7D8B3F423E2514300DCD162 /* SDL_thread.c in Sources */, + A1626A402617006A003F1973 /* SDL_triangle.c in Sources */, A7D8B55F23E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, A7D8A95923E2514000DCD162 /* SDL_atomic.c in Sources */, A7D8BB2923E2514500DCD162 /* SDL_displayevents.c in Sources */, - A7D8AF1A23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, A7D8AB2723E2514100DCD162 /* SDL_log.c in Sources */, A7D8AE8A23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, A7D8AB7523E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, @@ -9012,14 +8188,13 @@ A7D8AB3923E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8ACAD23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, A7D8BA1523E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B19023E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42423E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53B23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D423E2514400DCD162 /* SDL_coreaudio.m in Sources */, A7D8BA2123E2514400DCD162 /* SDL_blendline.c in Sources */, A7D8ADF423E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BA3923E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17823E2514200DCD162 /* SDL_x11mouse.c in Sources */, + F38233952738EC1500F7F527 /* hid.m in Sources */, A7D8ABED23E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6923E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ACA723E2514100DCD162 /* SDL_uikitview.m in Sources */, @@ -9030,9 +8205,9 @@ A7D8BA9923E2514400DCD162 /* s_copysign.c in Sources */, A7D8AAB823E2514100DCD162 /* SDL_haptic.c in Sources */, A7D8AC8F23E2514100DCD162 /* SDL_uikitvulkan.m in Sources */, - A7D8B15423E2514200DCD162 /* SDL_x11modes.c in Sources */, A7D8AF2623E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86223E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, + F3984CD225BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A7D8AC5923E2514100DCD162 /* SDL_uikitevents.m in Sources */, A7D8ACB923E2514100DCD162 /* SDL_uikitmodes.m in Sources */, A7D8AD3423E2514100DCD162 /* SDL_blit_N.c in Sources */, @@ -9056,21 +8231,17 @@ A7D8BA9323E2514400DCD162 /* s_cos.c in Sources */, A7D8B4D223E2514300DCD162 /* SDL_steamcontroller.c in Sources */, A7D8B9D323E2514400DCD162 /* SDL_yuv_sw.c in Sources */, + F382338F2738EBEF00F7F527 /* SDL_hidapi.c in Sources */, A7D8B76C23E2514300DCD162 /* SDL_wave.c in Sources */, A7D8BAD523E2514500DCD162 /* s_tan.c in Sources */, A7D8AA6723E2514000DCD162 /* SDL_hints.c in Sources */, A7D8B54123E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD7023E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B1A223E2514200DCD162 /* SDL_x11clipboard.c in Sources */, 5616CA55252BB35B005D5928 /* SDL_url.c in Sources */, A7D8B76023E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B16C23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F523E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B1C623E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95223E2514400DCD162 /* SDL_iconv.c in Sources */, A7D8BA9F23E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E423E2514200DCD162 /* SDL_x11shape.c in Sources */, - A7D8B19623E2514200DCD162 /* imKStoUCS.c in Sources */, A7D8B99423E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, A7D8AC4D23E2514100DCD162 /* SDL_uikitwindow.m in Sources */, A7D8B97C23E2514400DCD162 /* SDL_render.c in Sources */, @@ -9086,7 +8257,6 @@ A7D8BB5923E2514500DCD162 /* SDL_events.c in Sources */, A7D8ADE823E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0B23E2514500DCD162 /* k_tan.c in Sources */, - A7D8B16023E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A75FDBD023EA380300529352 /* SDL_hidapi_rumble.c in Sources */, A7D8B8AA23E2514400DCD162 /* SDL_diskaudio.c in Sources */, A7D8AFC223E2514200DCD162 /* SDL_egl.c in Sources */, @@ -9102,7 +8272,6 @@ A7D8BA8123E2514400DCD162 /* SDL_render_gl.c in Sources */, F3ADAB8F2576F0B400A6B1D9 /* SDL_sysurl.m in Sources */, A7D8AC8323E2514100DCD162 /* SDL_uikitopengles.m in Sources */, - A7D8B20223E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9623E2514100DCD162 /* SDL_cocoamodes.m in Sources */, A7D8BAA523E2514400DCD162 /* k_rem_pio2.c in Sources */, A7D8BB9B23E2514500DCD162 /* SDL_gesture.c in Sources */, @@ -9113,7 +8282,6 @@ A7D8AC2F23E2514100DCD162 /* SDL_surface.c in Sources */, A7D8B54D23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2523E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1A823E2514200DCD162 /* SDL_x11keyboard.c in Sources */, A7D8BB6B23E2514500DCD162 /* SDL_keyboard.c in Sources */, A7D8ACE923E2514100DCD162 /* SDL_rect.c in Sources */, A7D8AE9C23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, @@ -9121,7 +8289,6 @@ A7D8B55323E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96423E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7723E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18423E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, A7D8BAB723E2514400DCD162 /* k_cos.c in Sources */, A7D8B54723E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97623E2514400DCD162 /* SDL_malloc.c in Sources */, @@ -9138,13 +8305,13 @@ A7D8B5CB23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, A7D8AC1123E2514100DCD162 /* SDL_video.c in Sources */, 560572072473687800B46B66 /* SDL_syslocale.m in Sources */, + F3F07D5C269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8AB5723E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, A7D8ACC523E2514100DCD162 /* SDL_uikitmetalview.m in Sources */, A7D8BA5D23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, A7D8B14223E2514200DCD162 /* SDL_blit_1.c in Sources */, 560572102473688000B46B66 /* SDL_locale.c in Sources */, F3A490A02554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, - A7D8B17E23E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1723E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADB23E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB1123E2514500DCD162 /* SDL_dataqueue.c in Sources */, @@ -9152,16 +8319,13 @@ F395C19E2569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, A7D8B3E223E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99523E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18A23E2514200DCD162 /* SDL_x11window.c in Sources */, A75FDAAE23E2795C00529352 /* SDL_hidapi_steam.c in Sources */, A7D8BAAB23E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CC23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4B23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA2723E2514400DCD162 /* SDL_drawpoint.c in Sources */, A7D8BAF923E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEAE23E2514100DCD162 /* SDL_cocoavideo.m in Sources */, A7D8A94D23E2514000DCD162 /* SDL.c in Sources */, - A7D8B15A23E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8AEA223E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AC6523E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */, A7D8AB6323E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, @@ -9185,19 +8349,16 @@ A7D8B98A23E2514400DCD162 /* SDL_render_metal.m in Sources */, A7D8AE7A23E2514100DCD162 /* SDL_clipboard.c in Sources */, A7D8AEC823E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1C223E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86A23E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AE23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9F923E2514400DCD162 /* SDL_rotate.c in Sources */, A7D8A97923E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, A7D8BB9123E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19E23E2514200DCD162 /* SDL_x11events.c in Sources */, A7D8AC5523E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */, A7D8B3F623E2514300DCD162 /* SDL_thread.c in Sources */, A7D8B56123E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, A7D8A95B23E2514000DCD162 /* SDL_atomic.c in Sources */, A7D8BB2B23E2514500DCD162 /* SDL_displayevents.c in Sources */, - A7D8AF1C23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, A7D8AB2923E2514100DCD162 /* SDL_log.c in Sources */, A7D8AE8C23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, A7D8AB7723E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, @@ -9212,14 +8373,12 @@ A7D8AB3B23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8ACAF23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, A7D8BA1723E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B19223E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42623E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53D23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D623E2514400DCD162 /* SDL_coreaudio.m in Sources */, A7D8BA2323E2514400DCD162 /* SDL_blendline.c in Sources */, A7D8ADF623E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BA3B23E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17A23E2514200DCD162 /* SDL_x11mouse.c in Sources */, A7D8ABEF23E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6B23E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ACA923E2514100DCD162 /* SDL_uikitview.m in Sources */, @@ -9230,7 +8389,6 @@ A7D8BA9B23E2514400DCD162 /* s_copysign.c in Sources */, A7D8AABA23E2514100DCD162 /* SDL_haptic.c in Sources */, A7D8AC9123E2514100DCD162 /* SDL_uikitvulkan.m in Sources */, - A7D8B15623E2514200DCD162 /* SDL_x11modes.c in Sources */, A7D8AF2823E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86423E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, A7D8AC5B23E2514100DCD162 /* SDL_uikitevents.m in Sources */, @@ -9244,6 +8402,7 @@ A7D8AEDA23E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */, A7D8AB1A23E2514100DCD162 /* SDL_dynapi.c in Sources */, A7D8BA8923E2514400DCD162 /* SDL_shaders_gl.c in Sources */, + F38233902738EBF000F7F527 /* SDL_hidapi.c in Sources */, A7D8BAF523E2514500DCD162 /* e_log.c in Sources */, A7D8AED423E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */, A7D8BA2F23E2514400DCD162 /* SDL_blendfillrect.c in Sources */, @@ -9263,15 +8422,10 @@ F3A490A22554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A7D8B54323E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD7223E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B1A423E2514200DCD162 /* SDL_x11clipboard.c in Sources */, A7D8B76223E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B16E23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F723E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B1C823E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95423E2514400DCD162 /* SDL_iconv.c in Sources */, A7D8BAA123E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E623E2514200DCD162 /* SDL_x11shape.c in Sources */, - A7D8B19823E2514200DCD162 /* imKStoUCS.c in Sources */, A7D8B99623E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, 5616CA5B252BB35D005D5928 /* SDL_url.c in Sources */, A7D8AC4F23E2514100DCD162 /* SDL_uikitwindow.m in Sources */, @@ -9287,7 +8441,6 @@ A7D8BB5B23E2514500DCD162 /* SDL_events.c in Sources */, A7D8ADEA23E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0D23E2514500DCD162 /* k_tan.c in Sources */, - A7D8B16223E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A7D8B8AC23E2514400DCD162 /* SDL_diskaudio.c in Sources */, A7D8AFC423E2514200DCD162 /* SDL_egl.c in Sources */, A7D8AC3723E2514100DCD162 /* SDL_RLEaccel.c in Sources */, @@ -9295,6 +8448,7 @@ A7D8B3DE23E2514300DCD162 /* SDL_bmp.c in Sources */, 75E0915E241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A7D8BC0723E2590800DCD162 /* SDL_uikit_main.c in Sources */, + F3F07D5E269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8B97223E2514400DCD162 /* SDL_stdlib.c in Sources */, A7D8B79E23E2514400DCD162 /* SDL_dummyaudio.c in Sources */, A7D8B3A823E2514200DCD162 /* SDL_fillrect.c in Sources */, @@ -9303,7 +8457,6 @@ A7D8B96023E2514400DCD162 /* SDL_string.c in Sources */, A7D8BA8323E2514400DCD162 /* SDL_render_gl.c in Sources */, A7D8AC8523E2514100DCD162 /* SDL_uikitopengles.m in Sources */, - A7D8B20423E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9823E2514100DCD162 /* SDL_cocoamodes.m in Sources */, A7D8BAA723E2514400DCD162 /* k_rem_pio2.c in Sources */, A7D8BB9D23E2514500DCD162 /* SDL_gesture.c in Sources */, @@ -9315,17 +8468,16 @@ F395BF6925633B2400942BFF /* SDL_crc32.c in Sources */, A7D8B54F23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2723E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1AA23E2514200DCD162 /* SDL_x11keyboard.c in Sources */, A7D8BB6D23E2514500DCD162 /* SDL_keyboard.c in Sources */, 560572122473688200B46B66 /* SDL_locale.c in Sources */, A7D8ACEB23E2514100DCD162 /* SDL_rect.c in Sources */, A7D8AE9E23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, A7D8B96C23E2514400DCD162 /* SDL_qsort.c in Sources */, A7D8B55523E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, + F3984CD425BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A7D8B96623E2514400DCD162 /* SDL_strtokr.c in Sources */, 560572092473687900B46B66 /* SDL_syslocale.m in Sources */, A7D8BB7923E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18623E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, A7D8BAB923E2514400DCD162 /* k_cos.c in Sources */, A7D8B54923E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97823E2514400DCD162 /* SDL_malloc.c in Sources */, @@ -9344,28 +8496,26 @@ A7D8B5CD23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, A7D8AC1323E2514100DCD162 /* SDL_video.c in Sources */, A7D8AB5923E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, + F38233962738EC1600F7F527 /* hid.m in Sources */, A7D8ACC723E2514100DCD162 /* SDL_uikitmetalview.m in Sources */, A7D8BA5F23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, A7D8B14423E2514200DCD162 /* SDL_blit_1.c in Sources */, - A7D8B18023E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1923E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADD23E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB1323E2514500DCD162 /* SDL_dataqueue.c in Sources */, A7D8B4B623E2514300DCD162 /* SDL_sysjoystick.c in Sources */, A7D8B3E423E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99723E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18C23E2514200DCD162 /* SDL_x11window.c in Sources */, A7D8BAAD23E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CE23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4D23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA2923E2514400DCD162 /* SDL_drawpoint.c in Sources */, F395C1B52569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A7D8BAFB23E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEB023E2514100DCD162 /* SDL_cocoavideo.m in Sources */, A7D8A94F23E2514000DCD162 /* SDL.c in Sources */, - A7D8B15C23E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8AEA423E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AC6723E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */, + A1626A422617006A003F1973 /* SDL_triangle.c in Sources */, A7D8AB6523E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -9388,7 +8538,6 @@ A7D8B98623E2514400DCD162 /* SDL_render_metal.m in Sources */, A7D8AE7623E2514100DCD162 /* SDL_clipboard.c in Sources */, A7D8AEC423E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1BE23E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86623E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AA23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9F523E2514400DCD162 /* SDL_rotate.c in Sources */, @@ -9396,13 +8545,12 @@ 5616CA4E252BB2A6005D5928 /* SDL_sysurl.m in Sources */, A7D8A97523E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, A7D8BB8D23E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19A23E2514200DCD162 /* SDL_x11events.c in Sources */, + A1626A3E2617006A003F1973 /* SDL_triangle.c in Sources */, A7D8B3F223E2514300DCD162 /* SDL_thread.c in Sources */, A7D8B55D23E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, A7D8A95723E2514000DCD162 /* SDL_atomic.c in Sources */, A75FDBCE23EA380300529352 /* SDL_hidapi_rumble.c in Sources */, A7D8BB2723E2514500DCD162 /* SDL_displayevents.c in Sources */, - A7D8AF1823E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, A7D8AB2523E2514100DCD162 /* SDL_log.c in Sources */, A7D8AE8823E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, A7D8AB7323E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, @@ -9416,7 +8564,6 @@ A7D8B4EE23E2514300DCD162 /* SDL_gamecontroller.c in Sources */, A7D8AB3723E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA1323E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B18E23E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42223E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53923E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D223E2514400DCD162 /* SDL_coreaudio.m in Sources */, @@ -9425,7 +8572,6 @@ A7D8ADF223E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BBDD23E2574800DCD162 /* SDL_uikitmodes.m in Sources */, A7D8BA3723E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17623E2514200DCD162 /* SDL_x11mouse.c in Sources */, 75E0915A241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A7D8ABEB23E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6723E2514100DCD162 /* SDL_offscreenevents.c in Sources */, @@ -9436,8 +8582,8 @@ A7D8BBE923E2574800DCD162 /* SDL_uikitvulkan.m in Sources */, A7D8ABCD23E2514100DCD162 /* SDL_blit_slow.c in Sources */, A7D8BA9723E2514400DCD162 /* s_copysign.c in Sources */, + F3984CD025BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A7D8AAB623E2514100DCD162 /* SDL_haptic.c in Sources */, - A7D8B15223E2514200DCD162 /* SDL_x11modes.c in Sources */, A7D8AF2423E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86023E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, A7D8BBC523E2561500DCD162 /* SDL_steamcontroller.c in Sources */, @@ -9469,17 +8615,12 @@ A7D8AA6523E2514000DCD162 /* SDL_hints.c in Sources */, A7D8B53F23E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD6E23E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B1A023E2514200DCD162 /* SDL_x11clipboard.c in Sources */, A7D8B75E23E2514300DCD162 /* SDL_sysloadso.c in Sources */, A7D8BBD723E2574800DCD162 /* SDL_uikitevents.m in Sources */, - A7D8B16A23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F323E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B1C423E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95023E2514400DCD162 /* SDL_iconv.c in Sources */, A7D8BA9D23E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E223E2514200DCD162 /* SDL_x11shape.c in Sources */, F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */, - A7D8B19423E2514200DCD162 /* imKStoUCS.c in Sources */, A7D8B99223E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, A7D8B97A23E2514400DCD162 /* SDL_render.c in Sources */, A7D8ABD323E2514100DCD162 /* SDL_stretch.c in Sources */, @@ -9492,7 +8633,6 @@ A7D8BB5723E2514500DCD162 /* SDL_events.c in Sources */, A7D8ADE623E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0923E2514500DCD162 /* k_tan.c in Sources */, - A7D8B15E23E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A7D8B8A823E2514400DCD162 /* SDL_diskaudio.c in Sources */, 566E26CF246274CC00718109 /* SDL_syslocale.m in Sources */, A7D8AFC023E2514200DCD162 /* SDL_egl.c in Sources */, @@ -9507,7 +8647,6 @@ A7D8A96923E2514000DCD162 /* SDL_dummysensor.c in Sources */, A7D8B95C23E2514400DCD162 /* SDL_string.c in Sources */, A7D8BA7F23E2514400DCD162 /* SDL_render_gl.c in Sources */, - A7D8B20023E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9423E2514100DCD162 /* SDL_cocoamodes.m in Sources */, A7D8BAA323E2514400DCD162 /* k_rem_pio2.c in Sources */, A7D8BB9923E2514500DCD162 /* SDL_gesture.c in Sources */, @@ -9518,7 +8657,6 @@ A7D8AC2D23E2514100DCD162 /* SDL_surface.c in Sources */, A7D8B54B23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2323E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1A623E2514200DCD162 /* SDL_x11keyboard.c in Sources */, F3A4909E2554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A7D8BB6923E2514500DCD162 /* SDL_keyboard.c in Sources */, A7D8ACE723E2514100DCD162 /* SDL_rect.c in Sources */, @@ -9527,7 +8665,6 @@ A7D8B55123E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96223E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7523E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18223E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, A7D8BAB523E2514400DCD162 /* k_cos.c in Sources */, A7D8B54523E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97423E2514400DCD162 /* SDL_malloc.c in Sources */, @@ -9541,6 +8678,7 @@ A7D8AEA623E2514100DCD162 /* SDL_cocoawindow.m in Sources */, A7D8B43A23E2514300DCD162 /* SDL_sysmutex.c in Sources */, A7D8AAB023E2514100DCD162 /* SDL_syshaptic.c in Sources */, + F3F07D5A269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8BBD523E2574800DCD162 /* SDL_uikitclipboard.m in Sources */, A7D8B5C923E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, A7D8AC0F23E2514100DCD162 /* SDL_video.c in Sources */, @@ -9548,7 +8686,6 @@ A7D8BA5B23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, A7D8B14023E2514200DCD162 /* SDL_blit_1.c in Sources */, A7D8BBDB23E2574800DCD162 /* SDL_uikitmetalview.m in Sources */, - A7D8B17C23E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1523E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BAD923E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB0F23E2514500DCD162 /* SDL_dataqueue.c in Sources */, @@ -9556,15 +8693,12 @@ A7D8B4B223E2514300DCD162 /* SDL_sysjoystick.c in Sources */, A7D8B3E023E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99323E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18823E2514200DCD162 /* SDL_x11window.c in Sources */, A7D8BAA923E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CA23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4923E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA2523E2514400DCD162 /* SDL_drawpoint.c in Sources */, A7D8BAF723E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEAC23E2514100DCD162 /* SDL_cocoavideo.m in Sources */, A7D8A94B23E2514000DCD162 /* SDL.c in Sources */, - A7D8B15823E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8AEA023E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AB6123E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, 566E26D8246274CC00718109 /* SDL_locale.c in Sources */, @@ -9589,21 +8723,19 @@ A7D8B98923E2514400DCD162 /* SDL_render_metal.m in Sources */, A7D8AE7923E2514100DCD162 /* SDL_clipboard.c in Sources */, A7D8AEC723E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1C123E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86923E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AD23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9F823E2514400DCD162 /* SDL_rotate.c in Sources */, A7D8A97823E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, A7D8BB9023E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19D23E2514200DCD162 /* SDL_x11events.c in Sources */, A7D8B3F523E2514300DCD162 /* SDL_thread.c in Sources */, A7D8B56023E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, + A1626A412617006A003F1973 /* SDL_triangle.c in Sources */, 5616CA59252BB35C005D5928 /* SDL_sysurl.m in Sources */, A7D8A95A23E2514000DCD162 /* SDL_atomic.c in Sources */, A75FDBD123EA380300529352 /* SDL_hidapi_rumble.c in Sources */, A7D8BB2A23E2514500DCD162 /* SDL_displayevents.c in Sources */, A7D8BBFC23E2574800DCD162 /* SDL_uikitopenglview.m in Sources */, - A7D8AF1B23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, A7D8AB2823E2514100DCD162 /* SDL_log.c in Sources */, A7D8BC0223E2574800DCD162 /* SDL_uikitviewcontroller.m in Sources */, A7D8AE8B23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, @@ -9619,7 +8751,6 @@ A7D8B4F123E2514300DCD162 /* SDL_gamecontroller.c in Sources */, A7D8AB3A23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA1623E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B19123E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42523E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53C23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D523E2514400DCD162 /* SDL_coreaudio.m in Sources */, @@ -9627,7 +8758,6 @@ A7D8BC0623E2574800DCD162 /* SDL_uikitwindow.m in Sources */, A7D8ADF523E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BA3A23E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17923E2514200DCD162 /* SDL_x11mouse.c in Sources */, A7D8ABEE23E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6A23E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ABF423E2514100DCD162 /* SDL_nullevents.c in Sources */, @@ -9636,7 +8766,7 @@ A7D8ABD023E2514100DCD162 /* SDL_blit_slow.c in Sources */, A7D8BA9A23E2514400DCD162 /* s_copysign.c in Sources */, A7D8AAB923E2514100DCD162 /* SDL_haptic.c in Sources */, - A7D8B15523E2514200DCD162 /* SDL_x11modes.c in Sources */, + F3984CD325BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A7D8AF2723E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86323E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, A7D8AD3523E2514100DCD162 /* SDL_blit_N.c in Sources */, @@ -9666,17 +8796,12 @@ A7D8AA6823E2514000DCD162 /* SDL_hints.c in Sources */, A7D8B54223E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD7123E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B1A323E2514200DCD162 /* SDL_x11clipboard.c in Sources */, A7D8B76123E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B16D23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F623E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B1C723E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95323E2514400DCD162 /* SDL_iconv.c in Sources */, 560572112473688100B46B66 /* SDL_locale.c in Sources */, A7D8BAA023E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E523E2514200DCD162 /* SDL_x11shape.c in Sources */, A7D8BC0423E2574800DCD162 /* SDL_uikitvulkan.m in Sources */, - A7D8B19723E2514200DCD162 /* imKStoUCS.c in Sources */, A7D8B99523E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, A7D8B97D23E2514400DCD162 /* SDL_render.c in Sources */, F395C1B42569C6A000942BFF /* SDL_mfijoystick.m in Sources */, @@ -9692,7 +8817,6 @@ A7D8ADE923E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0C23E2514500DCD162 /* k_tan.c in Sources */, A7D8BBF223E2574800DCD162 /* SDL_uikitevents.m in Sources */, - A7D8B16123E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A7D8BBB923E2560500DCD162 /* SDL_steamcontroller.c in Sources */, A7D8B8AB23E2514400DCD162 /* SDL_diskaudio.c in Sources */, A7D8AFC323E2514200DCD162 /* SDL_egl.c in Sources */, @@ -9707,7 +8831,6 @@ A7D8A96C23E2514000DCD162 /* SDL_dummysensor.c in Sources */, A7D8B95F23E2514400DCD162 /* SDL_string.c in Sources */, A7D8BA8223E2514400DCD162 /* SDL_render_gl.c in Sources */, - A7D8B20323E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9723E2514100DCD162 /* SDL_cocoamodes.m in Sources */, A7D8BAA623E2514400DCD162 /* k_rem_pio2.c in Sources */, A7D8BB9C23E2514500DCD162 /* SDL_gesture.c in Sources */, @@ -9718,7 +8841,6 @@ A7D8AC3023E2514100DCD162 /* SDL_surface.c in Sources */, A7D8B54E23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2623E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1A923E2514200DCD162 /* SDL_x11keyboard.c in Sources */, A7D8BB6C23E2514500DCD162 /* SDL_keyboard.c in Sources */, A7D8ACEA23E2514100DCD162 /* SDL_rect.c in Sources */, A7D8BC0023E2574800DCD162 /* SDL_uikitview.m in Sources */, @@ -9727,7 +8849,6 @@ A7D8B55423E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96523E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7823E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18523E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, A7D8BAB823E2514400DCD162 /* k_cos.c in Sources */, A7D8B54823E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97723E2514400DCD162 /* SDL_malloc.c in Sources */, @@ -9742,6 +8863,7 @@ A7D8BB8423E2514500DCD162 /* SDL_quit.c in Sources */, A7D8AEA923E2514100DCD162 /* SDL_cocoawindow.m in Sources */, A7D8B43D23E2514300DCD162 /* SDL_sysmutex.c in Sources */, + F3F07D5D269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8AAB323E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8B5CC23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, A7D8AC1223E2514100DCD162 /* SDL_video.c in Sources */, @@ -9749,7 +8871,6 @@ A7D8BA5E23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, 5605720A2473687900B46B66 /* SDL_syslocale.m in Sources */, A7D8B14323E2514200DCD162 /* SDL_blit_1.c in Sources */, - A7D8B17F23E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1823E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADC23E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB1223E2514500DCD162 /* SDL_dataqueue.c in Sources */, @@ -9757,15 +8878,12 @@ F395C19F2569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, A7D8B3E323E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99623E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18B23E2514200DCD162 /* SDL_x11window.c in Sources */, A7D8BAAC23E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CD23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4C23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA2823E2514400DCD162 /* SDL_drawpoint.c in Sources */, A7D8BAFA23E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEAF23E2514100DCD162 /* SDL_cocoavideo.m in Sources */, A7D8A94E23E2514000DCD162 /* SDL.c in Sources */, - A7D8B15B23E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8BBF823E2574800DCD162 /* SDL_uikitmodes.m in Sources */, A7D8AEA323E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AB6423E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, @@ -9789,21 +8907,19 @@ A7D8B98B23E2514400DCD162 /* SDL_render_metal.m in Sources */, A7D8AE7B23E2514100DCD162 /* SDL_clipboard.c in Sources */, A7D8AEC923E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1C323E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86B23E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AF23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9FA23E2514400DCD162 /* SDL_rotate.c in Sources */, A7D8A97A23E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, A7D8BB9223E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19F23E2514200DCD162 /* SDL_x11events.c in Sources */, A7D8AC5623E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */, A7D8B3F723E2514300DCD162 /* SDL_thread.c in Sources */, A7D8B56223E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, + A1626A442617006A003F1973 /* SDL_triangle.c in Sources */, 5616CA62252BB35E005D5928 /* SDL_sysurl.m in Sources */, A7D8A95C23E2514000DCD162 /* SDL_atomic.c in Sources */, A75FDBD423EA380300529352 /* SDL_hidapi_rumble.c in Sources */, A7D8BB2C23E2514500DCD162 /* SDL_displayevents.c in Sources */, - A7D8AF1D23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, A7D8AB2A23E2514100DCD162 /* SDL_log.c in Sources */, A7D8AE8D23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, A7D8AB7823E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, @@ -9819,14 +8935,12 @@ A7D8AB3C23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8ACB023E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, A7D8BA1823E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B19323E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42723E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53E23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D723E2514400DCD162 /* SDL_coreaudio.m in Sources */, A7D8BA2423E2514400DCD162 /* SDL_blendline.c in Sources */, A7D8ADF723E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BA3C23E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17B23E2514200DCD162 /* SDL_x11mouse.c in Sources */, A7D8ABF023E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6C23E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ACAA23E2514100DCD162 /* SDL_uikitview.m in Sources */, @@ -9837,7 +8951,7 @@ A7D8BA9C23E2514400DCD162 /* s_copysign.c in Sources */, A7D8AABB23E2514100DCD162 /* SDL_haptic.c in Sources */, A7D8AC9223E2514100DCD162 /* SDL_uikitvulkan.m in Sources */, - A7D8B15723E2514200DCD162 /* SDL_x11modes.c in Sources */, + F3984CD625BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A7D8AF2923E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86523E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, A7D8AC5C23E2514100DCD162 /* SDL_uikitevents.m in Sources */, @@ -9869,16 +8983,11 @@ A7D8AA6A23E2514000DCD162 /* SDL_hints.c in Sources */, A7D8B54423E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD7323E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B1A523E2514200DCD162 /* SDL_x11clipboard.c in Sources */, A7D8B76323E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B16F23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F823E2514300DCD162 /* SDL_syspower.c in Sources */, 560572142473688300B46B66 /* SDL_locale.c in Sources */, - A7D8B1C923E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95523E2514400DCD162 /* SDL_iconv.c in Sources */, A7D8BAA223E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E723E2514200DCD162 /* SDL_x11shape.c in Sources */, - A7D8B19923E2514200DCD162 /* imKStoUCS.c in Sources */, A7D8B99723E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, F395C1B72569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A7D8AC5023E2514100DCD162 /* SDL_uikitwindow.m in Sources */, @@ -9894,7 +9003,6 @@ A7D8BB5C23E2514500DCD162 /* SDL_events.c in Sources */, A7D8ADEB23E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0E23E2514500DCD162 /* k_tan.c in Sources */, - A7D8B16323E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A7D8B8AD23E2514400DCD162 /* SDL_diskaudio.c in Sources */, A7D8AFC523E2514200DCD162 /* SDL_egl.c in Sources */, A7D8AC3823E2514100DCD162 /* SDL_RLEaccel.c in Sources */, @@ -9909,7 +9017,6 @@ A7D8B96123E2514400DCD162 /* SDL_string.c in Sources */, A7D8BA8423E2514400DCD162 /* SDL_render_gl.c in Sources */, A7D8AC8623E2514100DCD162 /* SDL_uikitopengles.m in Sources */, - A7D8B20523E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9923E2514100DCD162 /* SDL_cocoamodes.m in Sources */, A7D8BAA823E2514400DCD162 /* k_rem_pio2.c in Sources */, A7D8BB9E23E2514500DCD162 /* SDL_gesture.c in Sources */, @@ -9920,7 +9027,6 @@ A7D8AC3223E2514100DCD162 /* SDL_surface.c in Sources */, A7D8B55023E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2823E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1AB23E2514200DCD162 /* SDL_x11keyboard.c in Sources */, A7D8BB6E23E2514500DCD162 /* SDL_keyboard.c in Sources */, A7D8ACEC23E2514100DCD162 /* SDL_rect.c in Sources */, A7D8AE9F23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, @@ -9928,7 +9034,6 @@ A7D8B55623E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96723E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7A23E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18723E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, A7D8BABA23E2514400DCD162 /* k_cos.c in Sources */, A7D8B54A23E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97923E2514400DCD162 /* SDL_malloc.c in Sources */, @@ -9943,6 +9048,7 @@ A7D8B43F23E2514300DCD162 /* SDL_sysmutex.c in Sources */, A7D8AAB523E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8B5CE23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, + F3F07D60269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8AC1423E2514100DCD162 /* SDL_video.c in Sources */, A7D8AB5A23E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, A7D8ACC823E2514100DCD162 /* SDL_uikitmetalview.m in Sources */, @@ -9950,7 +9056,6 @@ A7D8BA6023E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, 5605720C2473687B00B46B66 /* SDL_syslocale.m in Sources */, A7D8B14523E2514200DCD162 /* SDL_blit_1.c in Sources */, - A7D8B18123E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1A23E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADE23E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB1423E2514500DCD162 /* SDL_dataqueue.c in Sources */, @@ -9958,15 +9063,12 @@ F395C1A22569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, A7D8B3E523E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99823E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18D23E2514200DCD162 /* SDL_x11window.c in Sources */, A7D8BAAE23E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CF23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4E23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA2A23E2514400DCD162 /* SDL_drawpoint.c in Sources */, A7D8BAFC23E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEB123E2514100DCD162 /* SDL_cocoavideo.m in Sources */, A7D8A95023E2514000DCD162 /* SDL.c in Sources */, - A7D8B15D23E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8AEA523E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AC6823E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */, A7D8AB6623E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, @@ -9981,11 +9083,6 @@ target = BECDF5FE0761BA81005FE872 /* Framework */; targetProxy = BECDF6C50761BA81005FE872 /* PBXContainerItemProxy */; }; - F3190017240CA3BA00ED104F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = A75FDB8023E4C74400529352 /* hidapi */; - targetProxy = F3190016240CA3BA00ED104F /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -10014,7 +9111,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEPLOYMENT_POSTPROCESSING = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 15.0.0; + DYLIB_CURRENT_VERSION = 19.3.0; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_ALTIVEC_EXTENSIONS = YES; @@ -10038,7 +9135,11 @@ ); INFOPLIST_FILE = "Info-Framework.plist"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MACOSX_DEPLOYMENT_TARGET = 10.6; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL2; PRODUCT_NAME = SDL2; @@ -10051,6 +9152,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_LINK_OBJC_RUNTIME = NO; + MARKETING_VERSION = 2.0.17; OTHER_LDFLAGS = "-liconv"; }; name = Release; @@ -10093,7 +9195,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 15.0.0; + DYLIB_CURRENT_VERSION = 19.3.0; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -10117,7 +9219,11 @@ ); INFOPLIST_FILE = "Info-Framework.plist"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MACOSX_DEPLOYMENT_TARGET = 10.6; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL2; @@ -10131,6 +9237,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_LINK_OBJC_RUNTIME = NO; + MARKETING_VERSION = 2.0.17; OTHER_LDFLAGS = "-liconv"; }; name = Debug; @@ -10158,10 +9265,10 @@ "$(inherited)", "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", ); - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; GCC_SYMBOLS_PRIVATE_EXTERN = YES; INSTALL_PATH = "@rpath"; SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Debug; }; @@ -10174,10 +9281,10 @@ "$(inherited)", "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", ); - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; GCC_SYMBOLS_PRIVATE_EXTERN = YES; INSTALL_PATH = "@rpath"; SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Release; }; @@ -10186,7 +9293,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; EXECUTABLE_PREFIX = lib; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; GCC_SYMBOLS_PRIVATE_EXTERN = YES; INSTALL_PATH = "@rpath"; SDKROOT = appletvos; @@ -10198,115 +9304,12 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; EXECUTABLE_PREFIX = lib; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; GCC_SYMBOLS_PRIVATE_EXTERN = YES; INSTALL_PATH = "@rpath"; SDKROOT = appletvos; }; name = Release; }; - A75FDB4E23E399AC00529352 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", - ); - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = hidapi; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - A75FDB4F23E399AC00529352 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", - ); - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = hidapi; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - A75FDB6C23E3A2C900529352 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = hidapi; - SDKROOT = appletvos; - }; - name = Debug; - }; - A75FDB6D23E3A2C900529352 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = hidapi; - SDKROOT = appletvos; - }; - name = Release; - }; - A75FDB8A23E4C74400529352 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - A75FDB8B23E4C74400529352 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; A769B23B23E259AE00872273 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -10338,10 +9341,9 @@ "$(inherited)", "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", ); - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; OTHER_LDFLAGS = "-liconv"; SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Debug; }; @@ -10354,10 +9356,9 @@ "$(inherited)", "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", ); - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; OTHER_LDFLAGS = "-liconv"; SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Release; }; @@ -10366,7 +9367,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CLANG_LINK_OBJC_RUNTIME = NO; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; OTHER_LDFLAGS = "-liconv"; SDKROOT = appletvos; }; @@ -10377,7 +9377,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CLANG_LINK_OBJC_RUNTIME = NO; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; OTHER_LDFLAGS = "-liconv"; SDKROOT = appletvos; }; @@ -10480,33 +9479,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - A75FDB5023E399AC00529352 /* Build configuration list for PBXNativeTarget "hidapi-iOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A75FDB4E23E399AC00529352 /* Debug */, - A75FDB4F23E399AC00529352 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - A75FDB6B23E3A2C900529352 /* Build configuration list for PBXNativeTarget "hidapi-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A75FDB6C23E3A2C900529352 /* Debug */, - A75FDB6D23E3A2C900529352 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - A75FDB8923E4C74400529352 /* Build configuration list for PBXNativeTarget "hidapi" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A75FDB8A23E4C74400529352 /* Debug */, - A75FDB8B23E4C74400529352 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; A769B23A23E259AE00872273 /* Build configuration list for PBXNativeTarget "Static Library-tvOS" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Engine/lib/sdl/Xcode/SDL/hidapi/Info.plist b/Engine/lib/sdl/Xcode/SDL/hidapi/Info.plist deleted file mode 100644 index 145b17a93..000000000 --- a/Engine/lib/sdl/Xcode/SDL/hidapi/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - $(CURRENT_PROJECT_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - - diff --git a/Engine/lib/sdl/Xcode/SDL/pkg-support/resources/License.txt b/Engine/lib/sdl/Xcode/SDL/pkg-support/resources/License.txt index 9bbafca5e..d2785a681 100644 --- a/Engine/lib/sdl/Xcode/SDL/pkg-support/resources/License.txt +++ b/Engine/lib/sdl/Xcode/SDL/pkg-support/resources/License.txt @@ -1,6 +1,6 @@ Simple DirectMedia Layer -Copyright (C) 1997-2020 Sam Lantinga +Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/acinclude/alsa.m4 b/Engine/lib/sdl/acinclude/alsa.m4 index e21fd46fb..1a276a23d 100644 --- a/Engine/lib/sdl/acinclude/alsa.m4 +++ b/Engine/lib/sdl/acinclude/alsa.m4 @@ -72,11 +72,10 @@ no_alsa="" alsa_min_micro_version=`echo $min_alsa_version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` -AC_LANG_SAVE -AC_LANG_C -AC_TRY_COMPILE([ +AC_LANG_PUSH([C]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include -], [ +]], [[ /* ensure backward compatibility */ #if !defined(SND_LIB_MAJOR) && defined(SOUNDLIB_VERSION_MAJOR) #define SND_LIB_MAJOR SOUNDLIB_VERSION_MAJOR @@ -108,13 +107,13 @@ AC_TRY_COMPILE([ # endif # endif exit(0); -], +]])], [AC_MSG_RESULT(found.)], [AC_MSG_RESULT(not present.) ifelse([$3], , [AC_MSG_ERROR(Sufficiently new version of libasound not found.)]) alsa_found=no] ) -AC_LANG_RESTORE +AC_LANG_POP([C]) dnl Now that we know that we have the right version, let's see if we have the library and not just the headers. if test "x$enable_alsatest" = "xyes"; then diff --git a/Engine/lib/sdl/acinclude/esd.m4 b/Engine/lib/sdl/acinclude/esd.m4 index 979d1b865..2e50ddb68 100644 --- a/Engine/lib/sdl/acinclude/esd.m4 +++ b/Engine/lib/sdl/acinclude/esd.m4 @@ -8,7 +8,7 @@ dnl AM_PATH_ESD([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for ESD, and define ESD_CFLAGS and ESD_LIBS dnl AC_DEFUN([AM_PATH_ESD], -[dnl +[dnl dnl Get the cflags and libraries from the esd-config script dnl AC_ARG_WITH(esd-prefix,[ --with-esd-prefix=PFX Prefix where ESD is installed (optional)], @@ -48,6 +48,7 @@ AC_ARG_ENABLE(esdtest, [ --disable-esdtest Do not try to compile and run esd_micro_version=`$ESD_CONFIG $esd_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` if test "x$enable_esdtest" = "xyes" ; then + AC_LANG_PUSH([C]) ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $ESD_CFLAGS" @@ -57,38 +58,19 @@ dnl Now check if the installed ESD is sufficiently new. (Also sanity dnl checks the results of esd-config to some extent dnl rm -f conf.esdtest - AC_TRY_RUN([ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -#include #include -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - -int main () +int main (void) { int major, minor, micro; - char *tmp_version; + FILE *fp = fopen("conf.esdtest", "w"); - system ("touch conf.esdtest"); + if (fp) fclose(fp); - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_esd_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + if (sscanf("$min_esd_version", "%d.%d.%d", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_esd_version"); exit(1); } @@ -110,15 +92,15 @@ int main () return 1; } } - -],, no_esd=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) +]])], [], [no_esd=yes], [echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" + AC_LANG_POP([C]) fi fi if test "x$no_esd" = x ; then AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) + ifelse([$2], , :, [$2]) else AC_MSG_RESULT(no) if test "$ESD_CONFIG" = "no" ; then @@ -133,10 +115,11 @@ int main () echo "*** Could not run ESD test program, checking why..." CFLAGS="$CFLAGS $ESD_CFLAGS" LIBS="$LIBS $ESD_LIBS" - AC_TRY_LINK([ + AC_LANG_PUSH([C]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include -], [ return 0; ], +]], [[ return 0; ]])], [ echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding ESD or finding the wrong" echo "*** version of ESD. If it is not finding ESD, you'll need to set your" @@ -152,6 +135,7 @@ int main () echo "*** may want to edit the esd-config script: $ESD_CONFIG" ]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" + AC_LANG_POP([C]) fi fi ESD_CFLAGS="" @@ -162,3 +146,27 @@ int main () AC_SUBST(ESD_LIBS) rm -f conf.esdtest ]) + +dnl AM_ESD_SUPPORTS_MULTIPLE_RECORD([ACTION-IF-SUPPORTS [, ACTION-IF-NOT-SUPPORTS]]) +dnl Test, whether esd supports multiple recording clients (version >=0.2.21) +dnl +AC_DEFUN([AM_ESD_SUPPORTS_MULTIPLE_RECORD], +[dnl + AC_MSG_NOTICE([whether installed esd version supports multiple recording clients]) + ac_save_ESD_CFLAGS="$ESD_CFLAGS" + ac_save_ESD_LIBS="$ESD_LIBS" + AM_PATH_ESD(0.2.21, + ifelse([$1], , [ + AM_CONDITIONAL(ESD_SUPPORTS_MULTIPLE_RECORD, true) + AC_DEFINE(ESD_SUPPORTS_MULTIPLE_RECORD, 1, + [Define if you have esound with support of multiple recording clients.])], + [$1]), + ifelse([$2], , [AM_CONDITIONAL(ESD_SUPPORTS_MULTIPLE_RECORD, false)], [$2]) + if test "x$ac_save_ESD_CFLAGS" != x ; then + ESD_CFLAGS="$ac_save_ESD_CFLAGS" + fi + if test "x$ac_save_ESD_LIBS" != x ; then + ESD_LIBS="$ac_save_ESD_LIBS" + fi + ) +]) diff --git a/Engine/lib/sdl/acinclude/libtool.m4 b/Engine/lib/sdl/acinclude/libtool.m4 index b8ba0324f..3236ddab0 100644 --- a/Engine/lib/sdl/acinclude/libtool.m4 +++ b/Engine/lib/sdl/acinclude/libtool.m4 @@ -1,10 +1,6 @@ -############################################################################## -# Based on libtool-2.4.2 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -12,36 +8,30 @@ # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. # -# This file is part of GNU Libtool. +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. # -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# along with this program. If not, see . ]) -# serial 57 LT_INIT +# serial 58 LT_INIT # LT_PREREQ(VERSION) @@ -69,7 +59,7 @@ esac # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], -[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl @@ -93,7 +83,7 @@ dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" +LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' @@ -113,26 +103,43 @@ dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + # _LT_CC_BASENAME(CC) # ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} @@ -179,15 +186,16 @@ m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our +# See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then +if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) -if test -n "${ZSH_VERSION+set}" ; then +if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi @@ -200,7 +208,7 @@ aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then + if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -211,14 +219,14 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a `.a' archive for static linking (except MSVC, +# All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a -with_gnu_ld="$lt_cv_prog_gnu_ld" +with_gnu_ld=$lt_cv_prog_gnu_ld -old_CC="$CC" -old_CFLAGS="$CFLAGS" +old_CC=$CC +old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc @@ -271,14 +279,14 @@ no_glob_subst='s/\*/\\\*/g' # _LT_PROG_LTMAIN # --------------- -# Note that this code is called both from `configure', and `config.status' +# Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" +ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN @@ -288,7 +296,7 @@ ltmain="$ac_aux_dir/ltmain.sh" # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' +# in macros and then make a single call at the end using the 'libtool' # label. @@ -423,8 +431,8 @@ m4_define([_lt_decl_all_varnames], # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) @@ -448,7 +456,7 @@ m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl +available_tags='_LT_TAGS'dnl ]) @@ -476,7 +484,7 @@ m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], @@ -502,8 +510,8 @@ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], @@ -549,7 +557,7 @@ for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -562,7 +570,7 @@ for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -578,7 +586,7 @@ _LT_OUTPUT_LIBTOOL_INIT # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the -# `#!' sequence but before initialization text begins. After this +# '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). @@ -600,7 +608,7 @@ AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF -test $lt_write_fail = 0 && chmod +x $1[]dnl +test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT @@ -623,7 +631,7 @@ exec AS_MESSAGE_LOG_FD>>config.log } >&AS_MESSAGE_LOG_FD lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, +'$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. @@ -645,7 +653,7 @@ Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." -while test $[#] != 0 +while test 0 != $[#] do case $[1] in --version | --v* | -V ) @@ -658,10 +666,10 @@ do lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; +Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; +Try '$[0] --help' for more information.]) ;; esac shift done @@ -687,7 +695,7 @@ chmod +x "$CONFIG_LT" # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: -test "$silent" = yes && +test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false @@ -707,32 +715,47 @@ m4_defun([_LT_CONFIG], _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our + # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then + if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi - cfgfile="${ofile}T" + cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. -# + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + _LT_COPYING _LT_LIBTOOL_TAGS +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + _LT_EOF case $host_os in @@ -741,7 +764,7 @@ _LT_EOF # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then +if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -758,8 +781,6 @@ _LT_EOF sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) - _LT_PROG_REPLACE_SHELLFNS - mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" @@ -777,7 +798,6 @@ _LT_EOF [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS @@ -976,7 +996,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then + if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the @@ -994,7 +1014,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1012,7 +1032,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], @@ -1034,7 +1054,7 @@ _LT_EOF _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1044,32 +1064,27 @@ _LT_EOF ]) case $host_os in rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then + if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= @@ -1089,29 +1104,29 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; + ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac - if test "$_lt_dar_can_shared" = "yes"; then + if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else @@ -1131,7 +1146,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl -if test "${lt_cv_aix_libpath+set}" = set; then +if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], @@ -1149,7 +1164,7 @@ else _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) @@ -1169,8 +1184,8 @@ m4_define([_LT_SHELL_INIT], # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start -# of the generated configure script which will find a shell with a builtin -# printf (which we can use as an echo command). +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO @@ -1198,10 +1213,10 @@ fi # Invoke $ECHO with all args, space-separated. func_echo_all () { - $ECHO "$*" + $ECHO "$*" } -case "$ECHO" in +case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; @@ -1227,16 +1242,17 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], -[ --with-sysroot[=DIR] Search for dependent libraries within DIR - (or the compiler's sysroot if not specified).], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= -case ${with_sysroot} in #( +case $with_sysroot in #( yes) - if test "$GCC" = yes; then + if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( @@ -1246,14 +1262,14 @@ case ${with_sysroot} in #( no|'') ;; #( *) - AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl -[dependent libraries, and in which our libraries should be installed.])]) +[dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- @@ -1261,31 +1277,33 @@ m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes +test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) - HPUX_IA64_MODE="32" + HPUX_IA64_MODE=32 ;; *ELF-64*) - HPUX_IA64_MODE="64" + HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" @@ -1314,9 +1332,46 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in @@ -1326,9 +1381,19 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) - LD="${LD-ld} -m elf_i386" + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -1347,10 +1412,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - powerpc64le-*linux*) + powerpcle-*linux*|powerpc64le-*linux*) LD="${LD-ld} -m elf64lppc" ;; - powerpc64-*linux*) + powerpc-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -1368,19 +1433,20 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" + SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then + if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" + CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in @@ -1388,7 +1454,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) case $lt_cv_prog_gnu_ld in yes*) case $host in - i?86-*-solaris*) + i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) @@ -1397,7 +1463,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" + LD=${LD-ld}_sol2 fi ;; *) @@ -1413,7 +1479,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac -need_locks="$enable_libtool_lock" +need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK @@ -1432,11 +1498,11 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -eq 0; then + if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -ne 0; then + if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi @@ -1444,7 +1510,7 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], ]) ]) -if test "x$lt_cv_ar_at_file" = xno; then +if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file @@ -1475,7 +1541,7 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in - openbsd*) + bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) @@ -1511,7 +1577,7 @@ AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins @@ -1538,7 +1604,7 @@ AC_CACHE_CHECK([$1], [$2], $RM conftest* ]) -if test x"[$]$2" = xyes; then +if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) @@ -1560,7 +1626,7 @@ AC_DEFUN([_LT_LINKER_OPTION], m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then @@ -1579,10 +1645,10 @@ AC_CACHE_CHECK([$1], [$2], fi fi $RM -r conftest* - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS ]) -if test x"[$]$2" = xyes; then +if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) @@ -1603,7 +1669,7 @@ AC_DEFUN([LT_CMD_MAX_LEN], AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 - teststring="ABCD" + teststring=ABCD case $build_os in msdosdjgpp*) @@ -1643,7 +1709,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=8192; ;; - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -1693,22 +1759,23 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do + for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough + test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring @@ -1724,7 +1791,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ;; esac ]) -if test -n $lt_cv_sys_max_cmd_len ; then +if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) @@ -1752,7 +1819,7 @@ m4_defun([_LT_HEADER_DLFCN], # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : +if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -1799,9 +1866,9 @@ else # endif #endif -/* When -fvisbility=hidden is used, assume the code has been annotated +/* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif @@ -1827,7 +1894,7 @@ int main () return status; }] _LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in @@ -1848,7 +1915,7 @@ rm -fr conftest* # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then +if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown @@ -1858,44 +1925,52 @@ else case $host_os in beos*) - lt_cv_dlopen="load_add_on" + lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) - lt_cv_dlopen="dlopen" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) - # if libdl is installed we need to link against it + # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + *) AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], + [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], + [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) @@ -1904,21 +1979,21 @@ else ;; esac - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else + if test no = "$lt_cv_dlopen"; then enable_dlopen=no + else + enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - save_LIBS="$LIBS" + save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], @@ -1928,7 +2003,7 @@ else lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) - if test "x$lt_cv_dlopen_self" = xyes; then + if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl @@ -1938,9 +2013,9 @@ else ]) fi - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS ;; esac @@ -2032,8 +2107,8 @@ m4_defun([_LT_COMPILER_FILE_LOCKS], m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes @@ -2043,8 +2118,8 @@ if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else @@ -2071,8 +2146,8 @@ objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR @@ -2084,15 +2159,15 @@ m4_defun([_LT_LINKER_HARDCODE_LIBPATH], _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else @@ -2106,12 +2181,12 @@ else fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi @@ -2127,32 +2202,82 @@ m4_defun([_LT_CMD_STRIPLIB], striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) +if test -z "$STRIP"; then + AC_MSG_RESULT([no]) else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then + if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + case $host_os in + darwin*) + # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) - else + ;; + freebsd*) + if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac + ;; + esac + fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics @@ -2163,17 +2288,18 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in @@ -2192,8 +2318,8 @@ if test "$GCC" = yes; then # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - # ...but if some path already ends with the multilib dir we assume - # that all is fine and trust -print-search-dirs as is (GCC 4.2 or newer). + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= @@ -2208,16 +2334,16 @@ if test "$GCC" = yes; then fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; + lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } @@ -2231,7 +2357,7 @@ BEGIN {RS=" "; FS="/|\n";} { # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else @@ -2240,7 +2366,7 @@ fi]) library_names_spec= libname_spec='lib$name' soname_spec= -shrext_cmds=".so" +shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= @@ -2257,14 +2383,17 @@ hardcode_into_libs=no # flags to be left without arguments need_version=unknown +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' + soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) @@ -2272,41 +2401,91 @@ aix[[4-9]]*) need_lib_prefix=no need_version=no hardcode_into_libs=yes - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac shlibpath_var=LIBPATH fi ;; @@ -2316,18 +2495,18 @@ amigaos*) powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) - library_names_spec='${libname}${shared_ext}' + library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; @@ -2335,8 +2514,8 @@ beos*) bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" @@ -2348,7 +2527,7 @@ bsdi[[45]]*) cygwin* | mingw* | pw32* | cegcc*) version_type=windows - shrext_cmds=".dll" + shrext_cmds=.dll need_version=no need_lib_prefix=no @@ -2357,8 +2536,8 @@ cygwin* | mingw* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ @@ -2374,19 +2553,19 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - #soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - soname_spec='`echo ${libname} | sed -e 's/^lib//'`${shared_ext}' + #soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | sed -e 's/^lib//'`$shared_ext' # SDL customization m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix - #soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - soname_spec='`echo ${libname} | $SED -e 's/^lib//'`${shared_ext}' + #soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib//'`$shared_ext' # SDL customization ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' @@ -2395,8 +2574,8 @@ m4_if([$1], [],[ *,cl*) # Native MSVC libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' case $build_os in mingw*) @@ -2423,7 +2602,7 @@ m4_if([$1], [],[ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) - sys_lib_search_path_spec="$LIB" + sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` @@ -2436,8 +2615,8 @@ m4_if([$1], [],[ esac # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' @@ -2450,7 +2629,7 @@ m4_if([$1], [],[ *) # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac @@ -2463,8 +2642,8 @@ darwin* | rhapsody*) version_type=darwin need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' @@ -2477,12 +2656,12 @@ dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -2496,12 +2675,13 @@ freebsd* | dragonfly*) version_type=freebsd-$objformat case $version_type in freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac @@ -2526,26 +2706,15 @@ freebsd* | dragonfly*) esac ;; -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes + shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; @@ -2563,14 +2732,15 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' @@ -2578,8 +2748,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; @@ -2588,8 +2758,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... @@ -2602,8 +2772,8 @@ interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -2614,7 +2784,7 @@ irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix @@ -2622,8 +2792,8 @@ irix5* | irix6* | nonstopux*) esac need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= @@ -2642,8 +2812,8 @@ irix5* | irix6* | nonstopux*) esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; @@ -2652,13 +2822,33 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -2683,10 +2873,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu) # before this can be enabled. hardcode_into_libs=yes - # Append ld.so.conf contents to the search path + # Add ABI-specific directories to the system library path. + sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -2703,12 +2901,12 @@ netbsd*) need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH @@ -2718,7 +2916,7 @@ netbsd*) newsos6) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; @@ -2727,58 +2925,70 @@ newsos6) version_type=qnx need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; -openbsd*) +openbsd* | bitrig*) version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" + sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi + shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' - shrext_cmds=".dll" + shrext_cmds=.dll need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' + # OS/2 can only load a DLL with a base name of 8 characters or less. +# SDL customization: removed versioning support. +# version_type=windows +# need_version=no +# soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; +# v=$($ECHO $release$versuffix | tr -d .-); +# n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); +# $ECHO $n$v`$shared_ext' + soname_spec='`test -n "$os2dllname" && libname=$os2dllname; $ECHO $libname | cut -b -8 | tr . _`$shared_ext' + library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) @@ -2789,8 +2999,8 @@ solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes @@ -2800,11 +3010,11 @@ solaris*) sunos4*) version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes @@ -2812,8 +3022,8 @@ sunos4*) sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) @@ -2834,24 +3044,24 @@ sysv4 | sysv4.3*) ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf + version_type=sco need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' @@ -2869,7 +3079,7 @@ tpf*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes @@ -2877,8 +3087,8 @@ tpf*) uts4*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -2887,20 +3097,30 @@ uts4*) ;; esac AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no +test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then +if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) @@ -2933,39 +3153,41 @@ _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) -_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], - [Run-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- -# find a file program which can recognize shared library +# find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : @@ -2988,11 +3210,11 @@ _LT_EOF break fi done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else @@ -3010,7 +3232,7 @@ dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- -# find a file program which can recognize a shared library +# find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then @@ -3037,16 +3259,16 @@ m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], + [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld -if test "$GCC" = yes; then +if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw + # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; @@ -3060,7 +3282,7 @@ if test "$GCC" = yes; then while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done - test -z "$LD" && LD="$ac_prog" + test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. @@ -3071,37 +3293,37 @@ if test "$GCC" = yes; then with_gnu_ld=unknown ;; esac -elif test "$with_gnu_ld" = yes; then +elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" + lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies @@ -3187,13 +3446,13 @@ lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. +# 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) @@ -3214,15 +3473,14 @@ cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' - lt_cv_deplibs_check_method=pass_all + lt_cv_deplibs_check_method=pass_all # SDL customization ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. - # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. - if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else @@ -3230,7 +3488,7 @@ mingw* | pw32*) lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi - lt_cv_deplibs_check_method=pass_all + lt_cv_deplibs_check_method=pass_all # SDL customization ;; cegcc*) @@ -3243,7 +3501,7 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) @@ -3259,10 +3517,6 @@ freebsd* | dragonfly*) fi ;; -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - haiku*) lt_cv_deplibs_check_method=pass_all ;; @@ -3301,7 +3555,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; @@ -3323,8 +3577,8 @@ newos6*) lt_cv_deplibs_check_method=pass_all ;; -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' @@ -3377,6 +3631,9 @@ sysv4 | sysv4.3*) tpf*) lt_cv_deplibs_check_method=pass_all ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; esac ]) @@ -3417,33 +3674,38 @@ AC_DEFUN([LT_PATH_NM], AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. - lt_cv_path_NM="$NM" + lt_cv_path_NM=$NM else - lt_nm_to_check="${ac_tool_prefix}nm" + lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" - break + break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" - break + break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but @@ -3454,21 +3716,21 @@ else esac fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) - DUMPBIN="$DUMPBIN -symbols" + DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: @@ -3476,8 +3738,8 @@ else esac fi AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" + if test : != "$DUMPBIN"; then + NM=$DUMPBIN fi fi test -z "$NM" && NM=nm @@ -3523,8 +3785,8 @@ lt_cv_sharedlib_from_linklib_cmd, case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib @@ -3536,7 +3798,7 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" + lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) @@ -3563,13 +3825,28 @@ AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) -if test "x$lt_cv_path_mainfest_tool" != xyes; then +if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + # LT_LIB_M # -------- # check for math library @@ -3577,15 +3854,15 @@ AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-mingw* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) - AC_CHECK_LIB(m, cos, LIBM="-lm") + AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) @@ -3604,7 +3881,7 @@ m4_defun([_LT_COMPILER_NO_RTTI], _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; @@ -3656,7 +3933,7 @@ cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; @@ -3667,7 +3944,7 @@ osf*) symcode='[[BCDEGQRST]]' ;; solaris*) - symcode='[[BDRT]]' + symcode='[[BCDRT]]' ;; sco3.2v5*) symcode='[[DT]]' @@ -3689,14 +3966,44 @@ case `$NM -V 2>&1` in symcode='[[ABCDGIRSTW]]' ;; esac +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= @@ -3714,21 +4021,24 @@ for ac_symprfx in "" "_"; do # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" @@ -3768,11 +4078,11 @@ _LT_EOF if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST -#elif defined(__osf__) +#elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else @@ -3798,7 +4108,7 @@ lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; @@ -3818,9 +4128,9 @@ _LT_EOF mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" + LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS @@ -3841,7 +4151,7 @@ _LT_EOF rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then + if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= @@ -3868,12 +4178,16 @@ _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS @@ -3889,17 +4203,18 @@ _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then + if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) @@ -3910,8 +4225,8 @@ m4_if([$1], [CXX], [ ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -3927,6 +4242,11 @@ m4_if([$1], [CXX], [ # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac ;; darwin* | rhapsody*) # PIC is the default on this platform @@ -3976,7 +4296,7 @@ m4_if([$1], [CXX], [ case $host_os in aix[[4-9]]*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else @@ -4010,21 +4330,21 @@ m4_if([$1], [CXX], [ ;; esac ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default @@ -4053,7 +4373,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler @@ -4061,7 +4381,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. + # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' @@ -4206,17 +4526,18 @@ m4_if([$1], [CXX], [ fi ], [ - if test "$GCC" = yes; then + if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) @@ -4227,8 +4548,8 @@ m4_if([$1], [CXX], [ ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -4245,6 +4566,11 @@ m4_if([$1], [CXX], [ # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac ;; darwin* | rhapsody*) @@ -4315,7 +4641,7 @@ m4_if([$1], [CXX], [ case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else @@ -4323,11 +4649,30 @@ m4_if([$1], [CXX], [ fi ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac ;; hpux9* | hpux10* | hpux11*) @@ -4343,7 +4688,7 @@ m4_if([$1], [CXX], [ ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) @@ -4352,9 +4697,9 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. + # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4379,6 +4724,12 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) @@ -4476,7 +4827,7 @@ m4_if([$1], [CXX], [ ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi @@ -4505,7 +4856,7 @@ m4_if([$1], [CXX], [ fi ]) case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: + # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; @@ -4571,17 +4922,21 @@ m4_if([$1], [CXX], [ case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global defined - # symbols, whereas GNU nm marks them as "W". + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in @@ -4627,9 +4982,9 @@ m4_if([$1], [CXX], [ # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if @@ -4645,7 +5000,7 @@ dnl Note also adjust exclude_expsyms for C++ above. # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. - if test "$GCC" != yes; then + if test yes != "$GCC"; then with_gnu_ld=no fi ;; @@ -4653,7 +5008,7 @@ dnl Note also adjust exclude_expsyms for C++ above. # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; - openbsd*) + openbsd* | bitrig*) with_gnu_ld=no ;; esac @@ -4663,7 +5018,7 @@ dnl Note also adjust exclude_expsyms for C++ above. # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility @@ -4685,24 +5040,24 @@ dnl Note also adjust exclude_expsyms for C++ above. esac fi - if test "$lt_use_gnu_ld_interface" = yes; then + if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' + wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no - case `$LD -v 2>&1` in + case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -4715,7 +5070,7 @@ dnl Note also adjust exclude_expsyms for C++ above. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then + if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 @@ -4734,7 +5089,7 @@ _LT_EOF case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) @@ -4750,7 +5105,7 @@ _LT_EOF _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4760,7 +5115,7 @@ _LT_EOF # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes @@ -4768,61 +5123,90 @@ _LT_EOF _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + ;; + interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no - if test "$host_os" = linux-dietlibc; then + if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no + && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; @@ -4833,42 +5217,47 @@ _LT_EOF lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac @@ -4882,8 +5271,8 @@ _LT_EOF _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; @@ -4901,8 +5290,8 @@ _LT_EOF _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4914,7 +5303,7 @@ _LT_EOF _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify @@ -4929,9 +5318,9 @@ _LT_EOF # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4948,15 +5337,15 @@ _LT_EOF *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= @@ -4972,7 +5361,7 @@ _LT_EOF # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported @@ -4980,34 +5369,57 @@ _LT_EOF ;; aix[[4-9]]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi ;; esac @@ -5026,13 +5438,21 @@ _LT_EOF _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac - if test "$GCC" = yes; then + if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -5051,61 +5471,80 @@ _LT_EOF ;; esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' fi fi - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; @@ -5114,7 +5553,7 @@ _LT_EOF case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) @@ -5144,16 +5583,17 @@ _LT_EOF # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes @@ -5162,18 +5602,18 @@ _LT_EOF # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # Assume MSVC wrapper @@ -5182,7 +5622,7 @@ _LT_EOF # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. @@ -5224,7 +5664,7 @@ _LT_EOF ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes @@ -5232,33 +5672,33 @@ _LT_EOF ;; hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes @@ -5266,25 +5706,25 @@ _LT_EOF ;; hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then + if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ @@ -5292,14 +5732,14 @@ _LT_EOF # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in @@ -5310,7 +5750,7 @@ _LT_EOF *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. @@ -5321,16 +5761,16 @@ _LT_EOF ;; irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], - [save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], @@ -5343,21 +5783,31 @@ _LT_EOF end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) - LDFLAGS="$save_LDFLAGS"]) - if test "$lt_cv_irix_exported_symbol" = yes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out @@ -5372,7 +5822,7 @@ _LT_EOF newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; @@ -5380,27 +5830,19 @@ _LT_EOF *nto* | *qnx*) ;; - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no @@ -5411,33 +5853,54 @@ _LT_EOF _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' @@ -5448,24 +5911,24 @@ _LT_EOF solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi @@ -5475,11 +5938,11 @@ _LT_EOF solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', + # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi @@ -5489,10 +5952,10 @@ _LT_EOF ;; sunos4*) - if test "x$host_vendor" = xsequent; then + if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi @@ -5541,43 +6004,43 @@ _LT_EOF ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; @@ -5592,17 +6055,17 @@ _LT_EOF ;; esac - if test x$host_vendor = xsni; then + if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld @@ -5619,7 +6082,7 @@ x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - if test "$enable_shared" = yes && test "$GCC" = yes; then + if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. @@ -5699,12 +6162,12 @@ _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the + "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR @@ -5745,10 +6208,10 @@ dnl [Compiler flag to generate thread safe objects]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. +# the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" +lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. @@ -5788,18 +6251,18 @@ if test -n "$compiler"; then LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB - # Report which library types will actually be built + # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' @@ -5807,8 +6270,12 @@ if test -n "$compiler"; then ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac fi ;; esac @@ -5816,13 +6283,13 @@ if test -n "$compiler"; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP -CC="$lt_save_CC" +CC=$lt_save_CC ])# _LT_LANG_C_CONFIG @@ -5830,14 +6297,14 @@ CC="$lt_save_CC" # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. +# the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes @@ -5879,7 +6346,7 @@ _LT_TAGVAR(objext, $1)=$objext # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then +if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" @@ -5921,35 +6388,35 @@ if test "$_lt_caught_CXX_error" != yes; then if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately - if test "$GXX" = yes; then + if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi - if test "$GXX" = yes; then + if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) - wlarc='${wl}' + wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi @@ -5985,18 +6452,30 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in @@ -6006,6 +6485,13 @@ if test "$_lt_caught_CXX_error" != yes; then ;; esac done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi ;; esac @@ -6024,13 +6510,21 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac - if test "$GXX" = yes; then + if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -6048,64 +6542,84 @@ if test "$_lt_caught_CXX_error" != yes; then fi esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' fi fi - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; @@ -6115,7 +6629,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -6143,57 +6657,58 @@ if test "$_lt_caught_CXX_error" != yes; then # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -6204,6 +6719,35 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_DARWIN_LINKER_FEATURES($1) ;; + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + ;; + dgux*) case $cc_basename in ec++*) @@ -6232,24 +6776,21 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; - gnu*) - ;; - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default @@ -6261,7 +6802,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -6270,11 +6811,11 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no @@ -6284,15 +6825,15 @@ if test "$_lt_caught_CXX_error" != yes; then ;; hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi @@ -6318,13 +6859,13 @@ if test "$_lt_caught_CXX_error" != yes; then aCC*) case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists @@ -6335,20 +6876,20 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi @@ -6363,22 +6904,22 @@ if test "$_lt_caught_CXX_error" != yes; then interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is @@ -6387,22 +6928,22 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler @@ -6410,8 +6951,8 @@ if test "$_lt_caught_CXX_error" != yes; then # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -6420,10 +6961,10 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. @@ -6437,59 +6978,59 @@ if test "$_lt_caught_CXX_error" != yes; then # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' @@ -6503,18 +7044,18 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) @@ -6522,10 +7063,10 @@ if test "$_lt_caught_CXX_error" != yes; then *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on @@ -6583,22 +7124,17 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=yes ;; - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else @@ -6614,9 +7150,9 @@ if test "$_lt_caught_CXX_error" != yes; then # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using @@ -6634,17 +7170,17 @@ if test "$_lt_caught_CXX_error" != yes; then cxx*) case $host in osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac @@ -6659,21 +7195,21 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists @@ -6719,9 +7255,9 @@ if test "$_lt_caught_CXX_error" != yes; then # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no @@ -6729,7 +7265,7 @@ if test "$_lt_caught_CXX_error" != yes; then solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. + # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; @@ -6746,30 +7282,30 @@ if test "$_lt_caught_CXX_error" != yes; then ;; gcx*) # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else - # g++ 2.7 appears to require `-G' NOT `-shared' on this + # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when @@ -6777,11 +7313,11 @@ if test "$_lt_caught_CXX_error" != yes; then output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi @@ -6790,52 +7326,52 @@ if test "$_lt_caught_CXX_error" != yes; then ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ - '"$_LT_TAGVAR(old_archive_cmds, $1)" + '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ - '"$_LT_TAGVAR(reload_cmds, $1)" + '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; @@ -6866,10 +7402,10 @@ if test "$_lt_caught_CXX_error" != yes; then esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -6896,7 +7432,7 @@ if test "$_lt_caught_CXX_error" != yes; then lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes +fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG @@ -6918,13 +7454,14 @@ AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF + # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose @@ -7008,13 +7545,14 @@ if AC_TRY_EVAL(ac_compile); then pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in + case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. - if test $p = "-L" || - test $p = "-R"; then + if test x-L = "x$p" || + test x-R = "x$p" || + test x-l = "x$p"; then prev=$p continue fi @@ -7030,16 +7568,16 @@ if AC_TRY_EVAL(ac_compile); then case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in + if test no = "$pre_test_object_deps_done"; then + case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being @@ -7047,9 +7585,9 @@ if AC_TRY_EVAL(ac_compile); then esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" + _LT_TAGVAR(postdeps, $1)=$prev$p else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= @@ -7064,15 +7602,15 @@ if AC_TRY_EVAL(ac_compile); then continue fi - if test "$pre_test_object_deps_done" = no; then + if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" + _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" + _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi @@ -7103,51 +7641,6 @@ interix[[3-9]]*) _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC* | sunCC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; esac ]) @@ -7156,7 +7649,7 @@ case " $_LT_TAGVAR(postdeps, $1) " in esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) @@ -7176,10 +7669,10 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1], # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) -if test -z "$F77" || test "X$F77" = "Xno"; then +if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi @@ -7216,7 +7709,7 @@ _LT_TAGVAR(objext, $1)=$objext # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then +if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t @@ -7238,7 +7731,7 @@ if test "$_lt_disable_F77" != yes; then _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. - lt_save_CC="$CC" + lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} @@ -7252,21 +7745,25 @@ if test "$_lt_disable_F77" != yes; then AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac fi ;; esac @@ -7274,11 +7771,11 @@ if test "$_lt_disable_F77" != yes; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -7295,9 +7792,9 @@ if test "$_lt_disable_F77" != yes; then fi # test -n "$compiler" GCC=$lt_save_GCC - CC="$lt_save_CC" - CFLAGS="$lt_save_CFLAGS" -fi # test "$_lt_disable_F77" != yes + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG @@ -7307,11 +7804,11 @@ AC_LANG_POP # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) -if test -z "$FC" || test "X$FC" = "Xno"; then +if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi @@ -7348,7 +7845,7 @@ _LT_TAGVAR(objext, $1)=$objext # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then +if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t @@ -7370,7 +7867,7 @@ if test "$_lt_disable_FC" != yes; then _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. - lt_save_CC="$CC" + lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} @@ -7386,21 +7883,25 @@ if test "$_lt_disable_FC" != yes; then AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac fi ;; esac @@ -7408,11 +7909,11 @@ if test "$_lt_disable_FC" != yes; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -7432,7 +7933,7 @@ if test "$_lt_disable_FC" != yes; then GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS -fi # test "$_lt_disable_FC" != yes +fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG @@ -7442,7 +7943,7 @@ AC_LANG_POP # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE @@ -7476,7 +7977,7 @@ CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" +_LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. @@ -7513,7 +8014,7 @@ CFLAGS=$lt_save_CFLAGS # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE @@ -7547,7 +8048,7 @@ CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" +_LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. @@ -7584,7 +8085,7 @@ CFLAGS=$lt_save_CFLAGS # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE @@ -7600,7 +8101,7 @@ _LT_TAGVAR(objext, $1)=$objext lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" +lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER @@ -7610,7 +8111,7 @@ _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. -lt_save_CC="$CC" +lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= @@ -7639,7 +8140,7 @@ AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) @@ -7750,7 +8251,7 @@ lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue + test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in @@ -7767,9 +8268,9 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break + test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then + if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi @@ -7793,27 +8294,7 @@ dnl AC_DEFUN([LT_AC_PROG_SED], []) # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false @@ -7837,102 +8318,9 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES -# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) -# ------------------------------------------------------ -# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and -# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. -m4_defun([_LT_PROG_FUNCTION_REPLACE], -[dnl { -sed -e '/^$1 ()$/,/^} # $1 /c\ -$1 ()\ -{\ -m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) -} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: -]) - - -# _LT_PROG_REPLACE_SHELLFNS -# ------------------------- -# Replace existing portable implementations of several shell functions with -# equivalent extended shell implementations where those features are available.. -m4_defun([_LT_PROG_REPLACE_SHELLFNS], -[if test x"$xsi_shell" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl - func_split_long_opt_name=${1%%=*} - func_split_long_opt_arg=${1#*=}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) - - _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) - - _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) - - _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) -fi - -if test x"$lt_shell_append" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) - - _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl - func_quote_for_eval "${2}" -dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ - eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) -fi -]) - # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- -# Determine which file name conversion functions should be used by +# Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], diff --git a/Engine/lib/sdl/acinclude/ltoptions.m4 b/Engine/lib/sdl/acinclude/ltoptions.m4 index 5d9acd8e2..94b082976 100644 --- a/Engine/lib/sdl/acinclude/ltoptions.m4 +++ b/Engine/lib/sdl/acinclude/ltoptions.m4 @@ -1,14 +1,14 @@ # Helper functions for option handling. -*- Autoconf -*- # -# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 7 ltoptions.m4 +# serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) @@ -29,7 +29,7 @@ m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option `$2'])])[]dnl + [m4_warning([Unknown $1 option '$2'])])[]dnl ]) @@ -75,13 +75,15 @@ m4_if([$1],[LT_INIT],[ dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither - dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS @@ -112,7 +114,7 @@ AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `dlopen' option into LT_INIT's first parameter.]) +put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -148,7 +150,7 @@ AU_DEFUN([AC_LIBTOOL_WIN32_DLL], _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `win32-dll' option into LT_INIT's first parameter.]) +put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -157,9 +159,9 @@ dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- -# implement the --enable-shared flag, and supports the `shared' and -# `disable-shared' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], @@ -172,14 +174,14 @@ AC_ARG_ENABLE([shared], *) enable_shared=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) @@ -211,9 +213,9 @@ dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- -# implement the --enable-static flag, and support the `static' and -# `disable-static' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], @@ -226,14 +228,14 @@ AC_ARG_ENABLE([static], *) enable_static=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) @@ -265,9 +267,9 @@ dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- -# implement the --enable-fast-install flag, and support the `fast-install' -# and `disable-fast-install' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], @@ -280,14 +282,14 @@ AC_ARG_ENABLE([fast-install], *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) @@ -304,14 +306,14 @@ AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `fast-install' option into LT_INIT's first parameter.]) +the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `disable-fast-install' option into LT_INIT's first parameter.]) +the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -319,11 +321,64 @@ dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + # _LT_WITH_PIC([MODE]) # -------------------- -# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], @@ -334,19 +389,17 @@ m4_define([_LT_WITH_PIC], *) pic_mode=default # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], - [pic_mode=default]) - -test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC @@ -359,7 +412,7 @@ AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `pic-only' option into LT_INIT's first parameter.]) +put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: diff --git a/Engine/lib/sdl/acinclude/ltsugar.m4 b/Engine/lib/sdl/acinclude/ltsugar.m4 index 9000a057d..48bc9344a 100644 --- a/Engine/lib/sdl/acinclude/ltsugar.m4 +++ b/Engine/lib/sdl/acinclude/ltsugar.m4 @@ -1,6 +1,7 @@ # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives @@ -33,7 +34,7 @@ m4_define([_lt_join], # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support -# Autoconf-2.59 which quotes differently. +# Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], @@ -44,7 +45,7 @@ m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different diff --git a/Engine/lib/sdl/acinclude/ltversion.m4 b/Engine/lib/sdl/acinclude/ltversion.m4 index 07a8602d4..fa04b52a3 100644 --- a/Engine/lib/sdl/acinclude/ltversion.m4 +++ b/Engine/lib/sdl/acinclude/ltversion.m4 @@ -1,6 +1,6 @@ # ltversion.m4 -- version numbers -*- Autoconf -*- # -# Copyright (C) 2004 Free Software Foundation, Inc. +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives @@ -9,15 +9,15 @@ # @configure_input@ -# serial 3337 ltversion.m4 +# serial 4179 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4.2]) -m4_define([LT_PACKAGE_REVISION], [1.3337]) +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.2' -macro_revision='1.3337' +[macro_version='2.4.6' +macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/Engine/lib/sdl/acinclude/lt~obsolete.m4 b/Engine/lib/sdl/acinclude/lt~obsolete.m4 index c573da90c..c6b26f88f 100644 --- a/Engine/lib/sdl/acinclude/lt~obsolete.m4 +++ b/Engine/lib/sdl/acinclude/lt~obsolete.m4 @@ -1,6 +1,7 @@ # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # -# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives @@ -11,7 +12,7 @@ # These exist entirely to fool aclocal when bootstrapping libtool. # -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # @@ -25,7 +26,7 @@ # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until diff --git a/Engine/lib/sdl/acinclude/pkg.m4 b/Engine/lib/sdl/acinclude/pkg.m4 new file mode 100644 index 000000000..13a889017 --- /dev/null +++ b/Engine/lib/sdl/acinclude/pkg.m4 @@ -0,0 +1,275 @@ +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 12 (pkg-config-0.29.2) + +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.2]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $2]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR diff --git a/Engine/lib/sdl/acinclude/pkg_config.m4 b/Engine/lib/sdl/acinclude/pkg_config.m4 deleted file mode 100644 index 596b10f58..000000000 --- a/Engine/lib/sdl/acinclude/pkg_config.m4 +++ /dev/null @@ -1,133 +0,0 @@ -# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -# ---------------------------------- -AC_DEFUN([PKG_PROG_PKG_CONFIG], -[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) -AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) -AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) -AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) - -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=m4_default([$1], [0.9.0]) - AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - PKG_CONFIG="" - fi -fi[]dnl -])# PKG_PROG_PKG_CONFIG - -# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# Check to see whether a particular set of modules exists. Similar -# to PKG_CHECK_MODULES(), but does not set variables or print errors. -# -# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -# only at the first occurence in configure.ac, so if the first place -# it's called might be skipped (such as if it is within an "if", you -# have to call PKG_CHECK_EXISTS manually -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_EXISTS], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -if test -n "$PKG_CONFIG" && \ - AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then - m4_default([$2], [:]) -m4_ifvaln([$3], [else - $3])dnl -fi]) - -# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -# --------------------------------------------- -m4_define([_PKG_CONFIG], -[if test -n "$$1"; then - pkg_cv_[]$1="$$1" - elif test -n "$PKG_CONFIG"; then - PKG_CHECK_EXISTS([$3], - [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], - [pkg_failed=yes]) - else - pkg_failed=untried -fi[]dnl -])# _PKG_CONFIG - -# _PKG_SHORT_ERRORS_SUPPORTED -# ----------------------------- -AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi[]dnl -])# _PKG_SHORT_ERRORS_SUPPORTED - - -# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -# [ACTION-IF-NOT-FOUND]) -# -# -# Note that if there is a possibility the first call to -# PKG_CHECK_MODULES might not happen, you should be sure to include an -# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -# -# -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_MODULES], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl -AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl - -pkg_failed=no -AC_MSG_CHECKING([for $1]) - -_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) -_PKG_CONFIG([$1][_LIBS], [libs], [$2]) - -m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS -and $1[]_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details.]) - -if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) - _PKG_SHORT_ERRORS_SUPPORTED - if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` - else - $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD - - m4_default([$4], [AC_MSG_ERROR( -[Package requirements ($2) were not met: - -$$1_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -_PKG_TEXT])dnl - ]) -elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) - m4_default([$4], [AC_MSG_FAILURE( -[The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -_PKG_TEXT - -To get pkg-config, see .])dnl - ]) -else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS - AC_MSG_RESULT([yes]) - $3 -fi[]dnl -])# PKG_CHECK_MODULES diff --git a/Engine/lib/sdl/android-project/app/build.gradle b/Engine/lib/sdl/android-project/app/build.gradle index bf3c35d6b..baa0edc8d 100644 --- a/Engine/lib/sdl/android-project/app/build.gradle +++ b/Engine/lib/sdl/android-project/app/build.gradle @@ -8,13 +8,13 @@ else { } android { - compileSdkVersion 26 + compileSdkVersion 31 defaultConfig { if (buildAsApplication) { applicationId "org.libsdl.app" } minSdkVersion 16 - targetSdkVersion 26 + targetSdkVersion 31 versionCode 1 versionName "1.0" externalNativeBuild { @@ -35,6 +35,10 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + applicationVariants.all { variant -> + tasks["merge${variant.name.capitalize()}Assets"] + .dependsOn("externalNativeBuild${variant.name.capitalize()}") + } if (!project.hasProperty('EXCLUDE_NATIVE_LIBS')) { sourceSets.main { jniLibs.srcDir 'libs' diff --git a/Engine/lib/sdl/android-project/app/jni/src/Android.mk b/Engine/lib/sdl/android-project/app/jni/src/Android.mk index 1adcb6e9a..04e006ae9 100644 --- a/Engine/lib/sdl/android-project/app/jni/src/Android.mk +++ b/Engine/lib/sdl/android-project/app/jni/src/Android.mk @@ -13,6 +13,6 @@ LOCAL_SRC_FILES := YourSourceHere.c LOCAL_SHARED_LIBRARIES := SDL2 -LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog +LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid include $(BUILD_SHARED_LIBRARY) diff --git a/Engine/lib/sdl/android-project/app/src/main/AndroidManifest.xml b/Engine/lib/sdl/android-project/app/src/main/AndroidManifest.xml index 36c5378b1..d997afe4a 100644 --- a/Engine/lib/sdl/android-project/app/src/main/AndroidManifest.xml +++ b/Engine/lib/sdl/android-project/app/src/main/AndroidManifest.xml @@ -38,10 +38,14 @@ android:name="android.hardware.microphone" android:required="false" /> --> - - + + + - + + + + @@ -71,11 +75,17 @@ android:alwaysRetainTaskState="true" android:launchMode="singleInstance" android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation" + android:preferMinimalPostProcessing="true" + android:exported="true" > + + + + add 45000 in total diff --git a/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic.c b/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic.c index 322afe9a6..f10c369af 100644 --- a/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic.c +++ b/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,6 +20,7 @@ */ #include "../../SDL_internal.h" +#include "SDL.h" #include "SDL_error.h" #include "SDL_haptic.h" #include "../SDL_syshaptic.h" @@ -61,7 +62,7 @@ static BOOL CALLBACK EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) { (void) pContext; - SDL_DINPUT_MaybeAddDevice(pdidInstance); + SDL_DINPUT_HapticMaybeAddDevice(pdidInstance); return DIENUM_CONTINUE; /* continue enumerating */ } @@ -70,6 +71,7 @@ SDL_DINPUT_HapticInit(void) { HRESULT ret; HINSTANCE instance; + DWORD devClass; if (dinput != NULL) { /* Already open. */ return SDL_SetError("Haptic: SubSystem already open."); @@ -103,21 +105,29 @@ SDL_DINPUT_HapticInit(void) } /* Look for haptic devices. */ - ret = IDirectInput8_EnumDevices(dinput, - 0, - EnumHapticsCallback, - NULL, - DIEDFL_FORCEFEEDBACK | - DIEDFL_ATTACHEDONLY); - if (FAILED(ret)) { - SDL_SYS_HapticQuit(); - return DI_SetError("Enumerating DirectInput devices", ret); + for (devClass = DI8DEVCLASS_DEVICE; devClass <= DI8DEVCLASS_GAMECTRL; devClass++) { + if (devClass == DI8DEVCLASS_GAMECTRL && SDL_WasInit(SDL_INIT_JOYSTICK)) { + /* The joystick subsystem will manage adding DInput joystick haptic devices */ + continue; + } + + ret = IDirectInput8_EnumDevices(dinput, + devClass, + EnumHapticsCallback, + NULL, + DIEDFL_FORCEFEEDBACK | + DIEDFL_ATTACHEDONLY); + if (FAILED(ret)) { + SDL_SYS_HapticQuit(); + return DI_SetError("Enumerating DirectInput devices", ret); + } } + return 0; } int -SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance) +SDL_DINPUT_HapticMaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance) { HRESULT ret; LPDIRECTINPUTDEVICE8 device; @@ -176,7 +186,7 @@ SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance) } int -SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance) +SDL_DINPUT_HapticMaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance) { SDL_hapticlist_item *item; SDL_hapticlist_item *prev = NULL; @@ -419,7 +429,6 @@ SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item) { HRESULT ret; LPDIRECTINPUTDEVICE8 device; - LPDIRECTINPUTDEVICE8 device8; /* Open the device */ ret = IDirectInput8_CreateDevice(dinput, &item->instance.guidInstance, @@ -429,19 +438,8 @@ SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item) return -1; } - /* Now get the IDirectInputDevice8 interface, instead. */ - ret = IDirectInputDevice8_QueryInterface(device, - &IID_IDirectInputDevice8, - (LPVOID *)&device8); - /* Done with the temporary one now. */ - IDirectInputDevice8_Release(device); - if (FAILED(ret)) { - DI_SetError("Querying DirectInput interface", ret); - return -1; - } - - if (SDL_DINPUT_HapticOpenFromDevice(haptic, device8, SDL_FALSE) < 0) { - IDirectInputDevice8_Release(device8); + if (SDL_DINPUT_HapticOpenFromDevice(haptic, device, SDL_FALSE) < 0) { + IDirectInputDevice8_Release(device); return -1; } return 0; @@ -494,8 +492,7 @@ SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) ++index; } - SDL_SetError("Couldn't find joystick in haptic device list"); - return -1; + return SDL_SetError("Couldn't find joystick in haptic device list"); } void @@ -713,7 +710,7 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, /* Specifics */ periodic->dwMagnitude = CONVERT(SDL_abs(hap_periodic->magnitude)); periodic->lOffset = CONVERT(hap_periodic->offset); - periodic->dwPhase = + periodic->dwPhase = (hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000; periodic->dwPeriod = hap_periodic->period * 1000; dest->cbTypeSpecificParams = sizeof(DIPERIODIC); @@ -961,8 +958,7 @@ SDL_DINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SD REFGUID type = SDL_SYS_HapticEffectType(base); if (type == NULL) { - SDL_SetError("Haptic: Unknown effect type."); - return -1; + return SDL_SetError("Haptic: Unknown effect type."); } /* Get the effect. */ @@ -1200,13 +1196,13 @@ SDL_DINPUT_HapticInit(void) } int -SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance) +SDL_DINPUT_HapticMaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance) { return SDL_Unsupported(); } int -SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance) +SDL_DINPUT_HapticMaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance) { return SDL_Unsupported(); } diff --git a/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic_c.h b/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic_c.h index 0a11dbf5a..e854971a0 100644 --- a/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic_c.h +++ b/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,8 +25,8 @@ extern int SDL_DINPUT_HapticInit(void); -extern int SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance); -extern int SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance); +extern int SDL_DINPUT_HapticMaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance); +extern int SDL_DINPUT_HapticMaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance); extern int SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item); extern int SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick); extern int SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick); diff --git a/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic.c b/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic.c index f837bb9e8..1be2fc487 100644 --- a/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic.c +++ b/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -52,12 +52,28 @@ static int numhaptics = 0; int SDL_SYS_HapticInit(void) { + JoyStick_DeviceData* device; + if (SDL_DINPUT_HapticInit() < 0) { return -1; } if (SDL_XINPUT_HapticInit() < 0) { return -1; } + + /* The joystick subsystem will usually be initialized before haptics, + * so the initial HapticMaybeAddDevice() calls from the joystick + * subsystem will arrive too early to create haptic devices. We will + * invoke those callbacks again here to pick up any joysticks that + * were added prior to haptics initialization. */ + for (device = SYS_Joystick; device; device = device->pNext) { + if (device->bXInputDevice) { + SDL_XINPUT_HapticMaybeAddDevice(device->XInputUserId); + } else { + SDL_DINPUT_HapticMaybeAddDevice(&device->dxdevice); + } + } + return numhaptics; } diff --git a/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic_c.h b/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic_c.h index 9048663f4..ec6e333ce 100644 --- a/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic_c.h +++ b/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic.c b/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic.c index 164b7894f..9212fbf32 100644 --- a/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic.c +++ b/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,6 +20,7 @@ */ #include "../../SDL_internal.h" +#include "SDL.h" #include "SDL_error.h" #include "SDL_haptic.h" #include "../SDL_syshaptic.h" @@ -47,17 +48,18 @@ SDL_XINPUT_HapticInit(void) loaded_xinput = (WIN_LoadXInputDLL() == 0); } - if (loaded_xinput) { + /* If the joystick subsystem is active, it will manage adding XInput haptic devices */ + if (loaded_xinput && !SDL_WasInit(SDL_INIT_JOYSTICK)) { DWORD i; for (i = 0; i < XUSER_MAX_COUNT; i++) { - SDL_XINPUT_MaybeAddDevice(i); + SDL_XINPUT_HapticMaybeAddDevice(i); } } return 0; } int -SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid) +SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid) { const Uint8 userid = (Uint8)dwUserid; SDL_hapticlist_item *item; @@ -106,7 +108,7 @@ SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid) } int -SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid) +SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid) { const Uint8 userid = (Uint8)dwUserid; SDL_hapticlist_item *item; @@ -244,8 +246,7 @@ SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) ++index; } - SDL_SetError("Couldn't find joystick in haptic device list"); - return -1; + return SDL_SetError("Couldn't find joystick in haptic device list"); } void @@ -377,13 +378,13 @@ SDL_XINPUT_HapticInit(void) } int -SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid) +SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid) { return SDL_Unsupported(); } int -SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid) +SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid) { return SDL_Unsupported(); } diff --git a/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic_c.h b/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic_c.h index e05461972..d0347e632 100644 --- a/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic_c.h +++ b/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,8 +25,8 @@ extern int SDL_XINPUT_HapticInit(void); -extern int SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid); -extern int SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid); +extern int SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid); +extern int SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid); extern int SDL_XINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item); extern int SDL_XINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick); extern int SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick); diff --git a/Engine/lib/sdl/src/hidapi/SDL_hidapi.c b/Engine/lib/sdl/src/hidapi/SDL_hidapi.c index 0b07716b8..aacff63bf 100644 --- a/Engine/lib/sdl/src/hidapi/SDL_hidapi.c +++ b/Engine/lib/sdl/src/hidapi/SDL_hidapi.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,17 +27,501 @@ * This merges the two, at a small performance cost, until distributions * have granted access to /dev/hidraw* */ - #include "../SDL_internal.h" -#include "SDL_loadso.h" -#ifdef SDL_JOYSTICK_HIDAPI +#include "SDL_loadso.h" +#include "SDL_hidapi.h" +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_hidapi_c.h" + +#if !SDL_HIDAPI_DISABLED + +#if defined(__WIN32__) +#include "../core/windows/SDL_windows.h" +#endif + +#if defined(__MACOSX__) +#include +#include +#include +#include +#include +#endif + +#include "../core/linux/SDL_udev.h" +#ifdef SDL_USE_LIBUDEV +#include +#include +#endif + +#ifdef HAVE_INOTIFY +#include /* just in case we didn't use that SDL_USE_LIBUDEV block... */ +#include /* errno, strerror */ +#include +#include /* For the definition of NAME_MAX */ +#include +#endif + +#if defined(SDL_USE_LIBUDEV) +typedef enum +{ + ENUMERATION_UNSET, + ENUMERATION_LIBUDEV, + ENUMERATION_FALLBACK +} LinuxEnumerationMethod; + +static LinuxEnumerationMethod linux_enumeration_method = ENUMERATION_UNSET; +#endif + +#if defined(HAVE_INOTIFY) +static int inotify_fd = -1; +#endif + +#if defined(SDL_USE_LIBUDEV) +static const SDL_UDEV_Symbols * usyms = NULL; +#endif + +static struct +{ + SDL_bool m_bInitialized; + Uint32 m_unDeviceChangeCounter; + SDL_bool m_bCanGetNotifications; + Uint32 m_unLastDetect; + +#if defined(__WIN32__) + SDL_threadID m_nThreadID; + WNDCLASSEXA m_wndClass; + HWND m_hwndMsg; + HDEVNOTIFY m_hNotify; + double m_flLastWin32MessageCheck; +#endif + +#if defined(__MACOSX__) + IONotificationPortRef m_notificationPort; + mach_port_t m_notificationMach; +#endif + +#if defined(SDL_USE_LIBUDEV) + struct udev *m_pUdev; + struct udev_monitor *m_pUdevMonitor; + int m_nUdevFd; +#endif +} SDL_HIDAPI_discovery; + + +#ifdef __WIN32__ +struct _DEV_BROADCAST_HDR +{ + DWORD dbch_size; + DWORD dbch_devicetype; + DWORD dbch_reserved; +}; + +typedef struct _DEV_BROADCAST_DEVICEINTERFACE_A +{ + DWORD dbcc_size; + DWORD dbcc_devicetype; + DWORD dbcc_reserved; + GUID dbcc_classguid; + char dbcc_name[ 1 ]; +} DEV_BROADCAST_DEVICEINTERFACE_A, *PDEV_BROADCAST_DEVICEINTERFACE_A; + +typedef struct _DEV_BROADCAST_HDR DEV_BROADCAST_HDR; +#define DBT_DEVICEARRIVAL 0x8000 /* system detected a new device */ +#define DBT_DEVICEREMOVECOMPLETE 0x8004 /* device was removed from the system */ +#define DBT_DEVTYP_DEVICEINTERFACE 0x00000005 /* device interface class */ +#define DBT_DEVNODES_CHANGED 0x0007 +#define DBT_CONFIGCHANGED 0x0018 +#define DBT_DEVICETYPESPECIFIC 0x8005 /* type specific event */ +#define DBT_DEVINSTSTARTED 0x8008 /* device installed and started */ + +#include +DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); + +static LRESULT CALLBACK ControllerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case WM_DEVICECHANGE: + switch (wParam) { + case DBT_DEVICEARRIVAL: + case DBT_DEVICEREMOVECOMPLETE: + if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + } + break; + } + return TRUE; + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} +#endif /* __WIN32__ */ + + +#if defined(__MACOSX__) +static void CallbackIOServiceFunc(void *context, io_iterator_t portIterator) +{ + /* Must drain the iterator, or we won't receive new notifications */ + io_object_t entry; + while ((entry = IOIteratorNext(portIterator)) != 0) { + IOObjectRelease(entry); + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + } +} +#endif /* __MACOSX__ */ + +#ifdef HAVE_INOTIFY +#ifdef HAVE_INOTIFY_INIT1 +static int SDL_inotify_init1(void) { + return inotify_init1(IN_NONBLOCK | IN_CLOEXEC); +} +#else +static int SDL_inotify_init1(void) { + int fd = inotify_init(); + if (fd < 0) return -1; + fcntl(fd, F_SETFL, O_NONBLOCK); + fcntl(fd, F_SETFD, FD_CLOEXEC); + return fd; +} +#endif + +static int +StrHasPrefix(const char *string, const char *prefix) +{ + return (SDL_strncmp(string, prefix, SDL_strlen(prefix)) == 0); +} + +static int +StrIsInteger(const char *string) +{ + const char *p; + + if (*string == '\0') { + return 0; + } + + for (p = string; *p != '\0'; p++) { + if (*p < '0' || *p > '9') { + return 0; + } + } + + return 1; +} +#endif /* HAVE_INOTIFY */ + +static void +HIDAPI_InitializeDiscovery() +{ + SDL_HIDAPI_discovery.m_bInitialized = SDL_TRUE; + SDL_HIDAPI_discovery.m_unDeviceChangeCounter = 1; + SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_FALSE; + SDL_HIDAPI_discovery.m_unLastDetect = 0; + +#if defined(__WIN32__) + SDL_HIDAPI_discovery.m_nThreadID = SDL_ThreadID(); + + SDL_zero(SDL_HIDAPI_discovery.m_wndClass); + SDL_HIDAPI_discovery.m_wndClass.hInstance = GetModuleHandle(NULL); + SDL_HIDAPI_discovery.m_wndClass.lpszClassName = "SDL_HIDAPI_DEVICE_DETECTION"; + SDL_HIDAPI_discovery.m_wndClass.lpfnWndProc = ControllerWndProc; /* This function is called by windows */ + SDL_HIDAPI_discovery.m_wndClass.cbSize = sizeof(WNDCLASSEX); + + RegisterClassExA(&SDL_HIDAPI_discovery.m_wndClass); + SDL_HIDAPI_discovery.m_hwndMsg = CreateWindowExA(0, "SDL_HIDAPI_DEVICE_DETECTION", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); + + { + DEV_BROADCAST_DEVICEINTERFACE_A devBroadcast; + + SDL_zero(devBroadcast); + devBroadcast.dbcc_size = sizeof( devBroadcast ); + devBroadcast.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + devBroadcast.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; + + /* DEVICE_NOTIFY_ALL_INTERFACE_CLASSES is important, makes GUID_DEVINTERFACE_USB_DEVICE ignored, + * but that seems to be necessary to get a notice after each individual usb input device actually + * installs, rather than just as the composite device is seen. + */ + SDL_HIDAPI_discovery.m_hNotify = RegisterDeviceNotification( SDL_HIDAPI_discovery.m_hwndMsg, &devBroadcast, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES ); + SDL_HIDAPI_discovery.m_bCanGetNotifications = ( SDL_HIDAPI_discovery.m_hNotify != 0 ); + } +#endif /* __WIN32__ */ + +#if defined(__MACOSX__) + SDL_HIDAPI_discovery.m_notificationPort = IONotificationPortCreate(kIOMasterPortDefault); + if (SDL_HIDAPI_discovery.m_notificationPort) { + { + io_iterator_t portIterator = 0; + io_object_t entry; + IOReturn result = IOServiceAddMatchingNotification( + SDL_HIDAPI_discovery.m_notificationPort, + kIOFirstMatchNotification, + IOServiceMatching(kIOHIDDeviceKey), + CallbackIOServiceFunc, NULL, &portIterator); + + if (result == 0) { + /* Must drain the existing iterator, or we won't receive new notifications */ + while ((entry = IOIteratorNext(portIterator)) != 0) { + IOObjectRelease(entry); + } + } else { + IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort); + SDL_HIDAPI_discovery.m_notificationPort = nil; + } + } + { + io_iterator_t portIterator = 0; + io_object_t entry; + IOReturn result = IOServiceAddMatchingNotification( + SDL_HIDAPI_discovery.m_notificationPort, + kIOTerminatedNotification, + IOServiceMatching(kIOHIDDeviceKey), + CallbackIOServiceFunc, NULL, &portIterator); + + if (result == 0) { + /* Must drain the existing iterator, or we won't receive new notifications */ + while ((entry = IOIteratorNext(portIterator)) != 0) { + IOObjectRelease(entry); + } + } else { + IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort); + SDL_HIDAPI_discovery.m_notificationPort = nil; + } + } + } + + SDL_HIDAPI_discovery.m_notificationMach = MACH_PORT_NULL; + if (SDL_HIDAPI_discovery.m_notificationPort) { + SDL_HIDAPI_discovery.m_notificationMach = IONotificationPortGetMachPort(SDL_HIDAPI_discovery.m_notificationPort); + } + + SDL_HIDAPI_discovery.m_bCanGetNotifications = (SDL_HIDAPI_discovery.m_notificationMach != MACH_PORT_NULL); + +#endif /* __MACOSX__ */ + +#if defined(SDL_USE_LIBUDEV) + if (linux_enumeration_method == ENUMERATION_LIBUDEV) { + SDL_HIDAPI_discovery.m_pUdev = NULL; + SDL_HIDAPI_discovery.m_pUdevMonitor = NULL; + SDL_HIDAPI_discovery.m_nUdevFd = -1; + + usyms = SDL_UDEV_GetUdevSyms(); + if (usyms) { + SDL_HIDAPI_discovery.m_pUdev = usyms->udev_new(); + } + if (SDL_HIDAPI_discovery.m_pUdev) { + SDL_HIDAPI_discovery.m_pUdevMonitor = usyms->udev_monitor_new_from_netlink(SDL_HIDAPI_discovery.m_pUdev, "udev"); + if (SDL_HIDAPI_discovery.m_pUdevMonitor) { + usyms->udev_monitor_enable_receiving(SDL_HIDAPI_discovery.m_pUdevMonitor); + SDL_HIDAPI_discovery.m_nUdevFd = usyms->udev_monitor_get_fd(SDL_HIDAPI_discovery.m_pUdevMonitor); + SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE; + } + } + } + else +#endif /* SDL_USE_LIBUDEV */ + { +#if defined(HAVE_INOTIFY) + inotify_fd = SDL_inotify_init1(); + + if (inotify_fd < 0) { + SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, + "Unable to initialize inotify, falling back to polling: %s", + strerror(errno)); + return; + } + + /* We need to watch for attribute changes in addition to + * creation, because when a device is first created, it has + * permissions that we can't read. When udev chmods it to + * something that we maybe *can* read, we'll get an + * IN_ATTRIB event to tell us. */ + if (inotify_add_watch(inotify_fd, "/dev", + IN_CREATE | IN_DELETE | IN_MOVE | IN_ATTRIB) < 0) { + close(inotify_fd); + inotify_fd = -1; + SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, + "Unable to add inotify watch, falling back to polling: %s", + strerror (errno)); + return; + } + + SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE; +#endif /* HAVE_INOTIFY */ + } +} + +static void +HIDAPI_UpdateDiscovery() +{ + if (!SDL_HIDAPI_discovery.m_bInitialized) { + HIDAPI_InitializeDiscovery(); + } + + if (!SDL_HIDAPI_discovery.m_bCanGetNotifications) { + const Uint32 SDL_HIDAPI_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */ + Uint32 now = SDL_GetTicks(); + if (!SDL_HIDAPI_discovery.m_unLastDetect || SDL_TICKS_PASSED(now, SDL_HIDAPI_discovery.m_unLastDetect + SDL_HIDAPI_DETECT_INTERVAL_MS)) { + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + SDL_HIDAPI_discovery.m_unLastDetect = now; + } + return; + } + +#if defined(__WIN32__) +#if 0 /* just let the usual SDL_PumpEvents loop dispatch these, fixing bug 4286. --ryan. */ + /* We'll only get messages on the same thread that created the window */ + if (SDL_ThreadID() == SDL_HIDAPI_discovery.m_nThreadID) { + MSG msg; + while (PeekMessage(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0, PM_NOREMOVE)) { + if (GetMessageA(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0) != 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } +#endif +#endif /* __WIN32__ */ + +#if defined(__MACOSX__) + if (SDL_HIDAPI_discovery.m_notificationPort) { + struct { mach_msg_header_t hdr; char payload[ 4096 ]; } msg; + while (mach_msg(&msg.hdr, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(msg), SDL_HIDAPI_discovery.m_notificationMach, 0, MACH_PORT_NULL) == KERN_SUCCESS) { + IODispatchCalloutFromMessage(NULL, &msg.hdr, SDL_HIDAPI_discovery.m_notificationPort); + } + } +#endif + +#if defined(SDL_USE_LIBUDEV) + if (linux_enumeration_method == ENUMERATION_LIBUDEV) { + if (SDL_HIDAPI_discovery.m_nUdevFd >= 0) { + /* Drain all notification events. + * We don't expect a lot of device notifications so just + * do a new discovery on any kind or number of notifications. + * This could be made more restrictive if necessary. + */ + for (;;) { + struct pollfd PollUdev; + struct udev_device *pUdevDevice; + + PollUdev.fd = SDL_HIDAPI_discovery.m_nUdevFd; + PollUdev.events = POLLIN; + if (poll(&PollUdev, 1, 0) != 1) { + break; + } + + pUdevDevice = usyms->udev_monitor_receive_device(SDL_HIDAPI_discovery.m_pUdevMonitor); + if (pUdevDevice) { + const char *action = NULL; + action = usyms->udev_device_get_action(pUdevDevice); + if (!action || SDL_strcmp(action, "add") == 0 || SDL_strcmp(action, "remove") == 0) { + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + } + usyms->udev_device_unref(pUdevDevice); + } + } + } + } + else +#endif /* SDL_USE_LIBUDEV */ + { +#if defined(HAVE_INOTIFY) + if (inotify_fd >= 0) { + union + { + struct inotify_event event; + char storage[4096]; + char enough_for_inotify[sizeof (struct inotify_event) + NAME_MAX + 1]; + } buf; + ssize_t bytes; + size_t remain = 0; + size_t len; + + bytes = read(inotify_fd, &buf, sizeof (buf)); + + if (bytes > 0) { + remain = (size_t) bytes; + } + + while (remain > 0) { + if (buf.event.len > 0) { + if (StrHasPrefix(buf.event.name, "hidraw") && + StrIsInteger(buf.event.name + SDL_strlen ("hidraw"))) { + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + /* We found an hidraw change. We still continue to + * drain the inotify fd to avoid leaving old + * notifications in the queue. */ + } + } + + len = sizeof (struct inotify_event) + buf.event.len; + remain -= len; + + if (remain != 0) { + SDL_memmove(&buf.storage[0], &buf.storage[len], remain); + } + } + } +#endif /* HAVE_INOTIFY */ + } +} + +static void +HIDAPI_ShutdownDiscovery() +{ + if (!SDL_HIDAPI_discovery.m_bInitialized) { + return; + } + +#if defined(__WIN32__) + if (SDL_HIDAPI_discovery.m_hNotify) + UnregisterDeviceNotification(SDL_HIDAPI_discovery.m_hNotify); + + if (SDL_HIDAPI_discovery.m_hwndMsg) { + DestroyWindow(SDL_HIDAPI_discovery.m_hwndMsg); + } + + UnregisterClassA(SDL_HIDAPI_discovery.m_wndClass.lpszClassName, SDL_HIDAPI_discovery.m_wndClass.hInstance); +#endif + +#if defined(__MACOSX__) + if (SDL_HIDAPI_discovery.m_notificationPort) { + IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort); + } +#endif + +#if defined(SDL_USE_LIBUDEV) + if (linux_enumeration_method == ENUMERATION_LIBUDEV) { + if (usyms) { + if (SDL_HIDAPI_discovery.m_pUdevMonitor) { + usyms->udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor); + } + if (SDL_HIDAPI_discovery.m_pUdev) { + usyms->udev_unref(SDL_HIDAPI_discovery.m_pUdev); + } + SDL_UDEV_ReleaseUdevSyms(); + usyms = NULL; + } + } + else +#endif /* SDL_USE_LIBUDEV */ + { +#if defined(HAVE_INOTIFY) + if (inotify_fd >= 0) { + close(inotify_fd); + inotify_fd = -1; + } +#endif + } + + SDL_HIDAPI_discovery.m_bInitialized = SDL_FALSE; +} /* Platform HIDAPI Implementation */ -#define hid_device_ PLATFORM_hid_device_ #define hid_device PLATFORM_hid_device -#define hid_device_info PLATFORM_hid_device_info +#define hid_device_ PLATFORM_hid_device_ #define hid_init PLATFORM_hid_init #define hid_exit PLATFORM_hid_exit #define hid_enumerate PLATFORM_hid_enumerate @@ -66,7 +550,7 @@ #undef HIDAPI_H__ #if __LINUX__ -#include "../../core/linux/SDL_udev.h" +#include "../core/linux/SDL_udev.h" #if SDL_USE_LIBUDEV static const SDL_UDEV_Symbols *udev_ctx = NULL; @@ -98,11 +582,20 @@ static const SDL_UDEV_Symbols *udev_ctx = NULL; #include "windows/hid.c" #define HAVE_PLATFORM_BACKEND 1 #define udev_ctx 1 +#elif __ANDROID__ +/* The implementation for Android is in a separate .cpp file */ +#include "hidapi/hidapi.h" +#define HAVE_PLATFORM_BACKEND 1 +#define udev_ctx 1 +#elif __IPHONEOS__ || __TVOS__ +/* The implementation for iOS and tvOS is in a separate .m file */ +#include "hidapi/hidapi.h" +#define HAVE_PLATFORM_BACKEND 1 +#define udev_ctx 1 #endif -#undef hid_device_ #undef hid_device -#undef hid_device_info +#undef hid_device_ #undef hid_init #undef hid_exit #undef hid_enumerate @@ -136,9 +629,8 @@ static const SDL_UDEV_Symbols *udev_ctx = NULL; /* DRIVER HIDAPI Implementation */ -#define hid_device_ DRIVER_hid_device_ #define hid_device DRIVER_hid_device -#define hid_device_info DRIVER_hid_device_info +#define hid_device_ DRIVER_hid_device_ #define hid_init DRIVER_hid_init #define hid_exit DRIVER_hid_exit #define hid_enumerate DRIVER_hid_enumerate @@ -165,9 +657,8 @@ static const SDL_UDEV_Symbols *udev_ctx = NULL; #error Need a driver hid.c for this platform! #endif -#undef hid_device_ #undef hid_device -#undef hid_device_info +#undef hid_device_ #undef hid_init #undef hid_exit #undef hid_enumerate @@ -200,33 +691,33 @@ static struct { void* libhandle; - int (*init)(libusb_context **ctx); - void (*exit)(libusb_context *ctx); - ssize_t (*get_device_list)(libusb_context *ctx, libusb_device ***list); - void (*free_device_list)(libusb_device **list, int unref_devices); - int (*get_device_descriptor)(libusb_device *dev, struct libusb_device_descriptor *desc); - int (*get_active_config_descriptor)(libusb_device *dev, struct libusb_config_descriptor **config); - int (*get_config_descriptor)( + int (LIBUSB_CALL *init)(libusb_context **ctx); + void (LIBUSB_CALL *exit)(libusb_context *ctx); + ssize_t (LIBUSB_CALL *get_device_list)(libusb_context *ctx, libusb_device ***list); + void (LIBUSB_CALL *free_device_list)(libusb_device **list, int unref_devices); + int (LIBUSB_CALL *get_device_descriptor)(libusb_device *dev, struct libusb_device_descriptor *desc); + int (LIBUSB_CALL *get_active_config_descriptor)(libusb_device *dev, struct libusb_config_descriptor **config); + int (LIBUSB_CALL *get_config_descriptor)( libusb_device *dev, uint8_t config_index, struct libusb_config_descriptor **config ); - void (*free_config_descriptor)(struct libusb_config_descriptor *config); - uint8_t (*get_bus_number)(libusb_device *dev); - uint8_t (*get_device_address)(libusb_device *dev); - int (*open)(libusb_device *dev, libusb_device_handle **dev_handle); - void (*close)(libusb_device_handle *dev_handle); - int (*claim_interface)(libusb_device_handle *dev_handle, int interface_number); - int (*release_interface)(libusb_device_handle *dev_handle, int interface_number); - int (*kernel_driver_active)(libusb_device_handle *dev_handle, int interface_number); - int (*detach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number); - int (*attach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number); - int (*set_interface_alt_setting)(libusb_device_handle *dev, int interface_number, int alternate_setting); - struct libusb_transfer * (*alloc_transfer)(int iso_packets); - int (*submit_transfer)(struct libusb_transfer *transfer); - int (*cancel_transfer)(struct libusb_transfer *transfer); - void (*free_transfer)(struct libusb_transfer *transfer); - int (*control_transfer)( + void (LIBUSB_CALL *free_config_descriptor)(struct libusb_config_descriptor *config); + uint8_t (LIBUSB_CALL *get_bus_number)(libusb_device *dev); + uint8_t (LIBUSB_CALL *get_device_address)(libusb_device *dev); + int (LIBUSB_CALL *open)(libusb_device *dev, libusb_device_handle **dev_handle); + void (LIBUSB_CALL *close)(libusb_device_handle *dev_handle); + int (LIBUSB_CALL *claim_interface)(libusb_device_handle *dev_handle, int interface_number); + int (LIBUSB_CALL *release_interface)(libusb_device_handle *dev_handle, int interface_number); + int (LIBUSB_CALL *kernel_driver_active)(libusb_device_handle *dev_handle, int interface_number); + int (LIBUSB_CALL *detach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number); + int (LIBUSB_CALL *attach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number); + int (LIBUSB_CALL *set_interface_alt_setting)(libusb_device_handle *dev, int interface_number, int alternate_setting); + struct libusb_transfer * (LIBUSB_CALL *alloc_transfer)(int iso_packets); + int (LIBUSB_CALL *submit_transfer)(struct libusb_transfer *transfer); + int (LIBUSB_CALL *cancel_transfer)(struct libusb_transfer *transfer); + void (LIBUSB_CALL *free_transfer)(struct libusb_transfer *transfer); + int (LIBUSB_CALL *control_transfer)( libusb_device_handle *dev_handle, uint8_t request_type, uint8_t bRequest, @@ -236,7 +727,7 @@ static struct uint16_t wLength, unsigned int timeout ); - int (*interrupt_transfer)( + int (LIBUSB_CALL *interrupt_transfer)( libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, @@ -244,8 +735,8 @@ static struct int *actual_length, unsigned int timeout ); - int (*handle_events)(libusb_context *ctx); - int (*handle_events_completed)(libusb_context *ctx, int *completed); + int (LIBUSB_CALL *handle_events)(libusb_context *ctx); + int (LIBUSB_CALL *handle_events_completed)(libusb_context *ctx, int *completed); } libusb_ctx; #define libusb_init libusb_ctx.init @@ -275,9 +766,8 @@ static struct #define libusb_handle_events libusb_ctx.handle_events #define libusb_handle_events_completed libusb_ctx.handle_events_completed -#define hid_device_ LIBUSB_hid_device_ #define hid_device LIBUSB_hid_device -#define hid_device_info LIBUSB_hid_device_info +#define hid_device_ LIBUSB_hid_device_ #define hid_init LIBUSB_hid_init #define hid_exit LIBUSB_hid_exit #define hid_enumerate LIBUSB_hid_enumerate @@ -326,9 +816,8 @@ SDL_libusb_get_string_descriptor(libusb_device_handle *dev, #undef HIDAPI_H__ #include "libusb/hid.c" -#undef hid_device_ #undef hid_device -#undef hid_device_info +#undef hid_device_ #undef hid_init #undef hid_exit #undef hid_enumerate @@ -356,24 +845,23 @@ SDL_libusb_get_string_descriptor(libusb_device_handle *dev, #endif /* SDL_LIBUSB_DYNAMIC */ +#endif /* !SDL_HIDAPI_DISABLED */ + /* Shared HIDAPI Implementation */ -#undef HIDAPI_H__ -#include "hidapi/hidapi.h" - struct hidapi_backend { - int (*hid_write)(hid_device* device, const unsigned char* data, size_t length); - int (*hid_read_timeout)(hid_device* device, unsigned char* data, size_t length, int milliseconds); - int (*hid_read)(hid_device* device, unsigned char* data, size_t length); - int (*hid_set_nonblocking)(hid_device* device, int nonblock); - int (*hid_send_feature_report)(hid_device* device, const unsigned char* data, size_t length); - int (*hid_get_feature_report)(hid_device* device, unsigned char* data, size_t length); - void (*hid_close)(hid_device* device); - int (*hid_get_manufacturer_string)(hid_device* device, wchar_t* string, size_t maxlen); - int (*hid_get_product_string)(hid_device* device, wchar_t* string, size_t maxlen); - int (*hid_get_serial_number_string)(hid_device* device, wchar_t* string, size_t maxlen); - int (*hid_get_indexed_string)(hid_device* device, int string_index, wchar_t* string, size_t maxlen); - const wchar_t* (*hid_error)(hid_device* device); + int (*hid_write)(void* device, const unsigned char* data, size_t length); + int (*hid_read_timeout)(void* device, unsigned char* data, size_t length, int milliseconds); + int (*hid_read)(void* device, unsigned char* data, size_t length); + int (*hid_set_nonblocking)(void* device, int nonblock); + int (*hid_send_feature_report)(void* device, const unsigned char* data, size_t length); + int (*hid_get_feature_report)(void* device, unsigned char* data, size_t length); + void (*hid_close)(void* device); + int (*hid_get_manufacturer_string)(void* device, wchar_t* string, size_t maxlen); + int (*hid_get_product_string)(void* device, wchar_t* string, size_t maxlen); + int (*hid_get_serial_number_string)(void* device, wchar_t* string, size_t maxlen); + int (*hid_get_indexed_string)(void* device, int string_index, wchar_t* string, size_t maxlen); + const wchar_t* (*hid_error)(void* device); }; #if HAVE_PLATFORM_BACKEND @@ -427,40 +915,43 @@ static const struct hidapi_backend LIBUSB_Backend = { }; #endif /* SDL_LIBUSB_DYNAMIC */ -typedef struct _HIDDeviceWrapper HIDDeviceWrapper; -struct _HIDDeviceWrapper +struct SDL_hid_device_ { - hid_device *device; /* must be first field */ + const void *magic; + void *device; const struct hidapi_backend *backend; }; +static char device_magic; -static HIDDeviceWrapper * -CreateHIDDeviceWrapper(hid_device *device, const struct hidapi_backend *backend) +#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC) + +static SDL_hid_device * +CreateHIDDeviceWrapper(void *device, const struct hidapi_backend *backend) { - HIDDeviceWrapper *ret = (HIDDeviceWrapper *)SDL_malloc(sizeof(*ret)); - ret->device = device; - ret->backend = backend; - return ret; + SDL_hid_device *wrapper = (SDL_hid_device *)SDL_malloc(sizeof(*wrapper)); + wrapper->magic = &device_magic; + wrapper->device = device; + wrapper->backend = backend; + return wrapper; } -static hid_device * -WrapHIDDevice(HIDDeviceWrapper *wrapper) -{ - return (hid_device *)wrapper; -} - -static HIDDeviceWrapper * -UnwrapHIDDevice(hid_device *device) -{ - return (HIDDeviceWrapper *)device; -} +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */ static void -DeleteHIDDeviceWrapper(HIDDeviceWrapper *device) +DeleteHIDDeviceWrapper(SDL_hid_device *device) { + device->magic = NULL; SDL_free(device); } +#define CHECK_DEVICE_MAGIC(device, retval) \ + if (!device || device->magic != &device_magic) { \ + SDL_SetError("Invalid device"); \ + return retval; \ + } + +#if !SDL_HIDAPI_DISABLED + #define COPY_IF_EXISTS(var) \ if (pSrc->var != NULL) { \ pDst->var = SDL_strdup(pSrc->var); \ @@ -474,10 +965,8 @@ DeleteHIDDeviceWrapper(HIDDeviceWrapper *device) pDst->var = NULL; \ } -#ifdef SDL_LIBUSB_DYNAMIC static void -LIBUSB_CopyHIDDeviceInfo(struct LIBUSB_hid_device_info *pSrc, - struct hid_device_info *pDst) +CopyHIDDeviceInfo(struct SDL_hid_device_info *pSrc, struct SDL_hid_device_info *pDst) { COPY_IF_EXISTS(path) pDst->vendor_id = pSrc->vendor_id; @@ -494,71 +983,66 @@ LIBUSB_CopyHIDDeviceInfo(struct LIBUSB_hid_device_info *pSrc, pDst->interface_protocol = pSrc->interface_protocol; pDst->next = NULL; } -#endif /* SDL_LIBUSB_DYNAMIC */ - -#if HAVE_DRIVER_BACKEND -static void -DRIVER_CopyHIDDeviceInfo(struct DRIVER_hid_device_info *pSrc, - struct hid_device_info *pDst) -{ - COPY_IF_EXISTS(path) - pDst->vendor_id = pSrc->vendor_id; - pDst->product_id = pSrc->product_id; - WCOPY_IF_EXISTS(serial_number) - pDst->release_number = pSrc->release_number; - WCOPY_IF_EXISTS(manufacturer_string) - WCOPY_IF_EXISTS(product_string) - pDst->usage_page = pSrc->usage_page; - pDst->usage = pSrc->usage; - pDst->interface_number = pSrc->interface_number; - pDst->interface_class = pSrc->interface_class; - pDst->interface_subclass = pSrc->interface_subclass; - pDst->interface_protocol = pSrc->interface_protocol; - pDst->next = NULL; -} -#endif /* HAVE_DRIVER_BACKEND */ - -#if HAVE_PLATFORM_BACKEND -static void -PLATFORM_CopyHIDDeviceInfo(struct PLATFORM_hid_device_info *pSrc, - struct hid_device_info *pDst) -{ - COPY_IF_EXISTS(path) - pDst->vendor_id = pSrc->vendor_id; - pDst->product_id = pSrc->product_id; - WCOPY_IF_EXISTS(serial_number) - pDst->release_number = pSrc->release_number; - WCOPY_IF_EXISTS(manufacturer_string) - WCOPY_IF_EXISTS(product_string) - pDst->usage_page = pSrc->usage_page; - pDst->usage = pSrc->usage; - pDst->interface_number = pSrc->interface_number; - pDst->interface_class = pSrc->interface_class; - pDst->interface_subclass = pSrc->interface_subclass; - pDst->interface_protocol = pSrc->interface_protocol; - pDst->next = NULL; -} -#endif /* HAVE_PLATFORM_BACKEND */ #undef COPY_IF_EXISTS #undef WCOPY_IF_EXISTS -static SDL_bool SDL_hidapi_wasinit = SDL_FALSE; +#endif /* !SDL_HIDAPI_DISABLED */ -int HID_API_EXPORT HID_API_CALL hid_init(void) +static int SDL_hidapi_refcount = 0; + +static void SDL_SetHIDAPIError( const wchar_t *error ) { - int err; + if (error) { + char *error_utf8 = SDL_iconv_wchar_utf8(error); + if (error_utf8) { + SDL_SetError("%s", error_utf8); + SDL_free(error_utf8); + } + } +} - if (SDL_hidapi_wasinit == SDL_TRUE) { +int SDL_hid_init(void) +{ + int attempts = 0, success = 0; + + if (SDL_hidapi_refcount > 0) { + ++SDL_hidapi_refcount; return 0; } +#if defined(SDL_USE_LIBUDEV) + if (SDL_getenv("SDL_HIDAPI_JOYSTICK_DISABLE_UDEV") != NULL) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "udev disabled by SDL_HIDAPI_JOYSTICK_DISABLE_UDEV"); + linux_enumeration_method = ENUMERATION_FALLBACK; + } else if (access("/.flatpak-info", F_OK) == 0 + || access("/run/host/container-manager", F_OK) == 0) { + /* Explicitly check `/.flatpak-info` because, for old versions of + * Flatpak, this was the only available way to tell if we were in + * a Flatpak container. */ + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Container detected, disabling HIDAPI udev integration"); + linux_enumeration_method = ENUMERATION_FALLBACK; + } else { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Using udev for HIDAPI joystick device discovery"); + linux_enumeration_method = ENUMERATION_LIBUDEV; + } +#endif + #ifdef SDL_LIBUSB_DYNAMIC + ++attempts; libusb_ctx.libhandle = SDL_LoadObject(SDL_LIBUSB_DYNAMIC); if (libusb_ctx.libhandle != NULL) { SDL_bool loaded = SDL_TRUE; + #ifdef __OS2__ + #define LOAD_LIBUSB_SYMBOL(func) \ + if (!(libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle,"_libusb_" #func))) {loaded = SDL_FALSE;} + #else #define LOAD_LIBUSB_SYMBOL(func) \ if (!(libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle, "libusb_" #func))) {loaded = SDL_FALSE;} + #endif LOAD_LIBUSB_SYMBOL(init) LOAD_LIBUSB_SYMBOL(exit) LOAD_LIBUSB_SYMBOL(get_device_list) @@ -587,82 +1071,114 @@ int HID_API_EXPORT HID_API_CALL hid_init(void) LOAD_LIBUSB_SYMBOL(handle_events_completed) #undef LOAD_LIBUSB_SYMBOL - if (loaded == SDL_TRUE) { - if ((err = LIBUSB_hid_init()) < 0) { - SDL_UnloadObject(libusb_ctx.libhandle); - libusb_ctx.libhandle = NULL; - return err; - } - } else { + if (!loaded) { SDL_UnloadObject(libusb_ctx.libhandle); libusb_ctx.libhandle = NULL; - /* SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, SDL_LIBUSB_DYNAMIC " found but could not load function."); */ - /* ignore error: continue without libusb */ + /* SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, SDL_LIBUSB_DYNAMIC " found but could not load function"); */ + } else if (LIBUSB_hid_init() < 0) { + SDL_UnloadObject(libusb_ctx.libhandle); + libusb_ctx.libhandle = NULL; + } else { + ++success; } } #endif /* SDL_LIBUSB_DYNAMIC */ #if HAVE_PLATFORM_BACKEND + ++attempts; #if __LINUX__ udev_ctx = SDL_UDEV_GetUdevSyms(); #endif /* __LINUX __ */ - if (udev_ctx && (err = PLATFORM_hid_init()) < 0) { -#ifdef SDL_LIBUSB_DYNAMIC - if (libusb_ctx.libhandle) { - LIBUSB_hid_exit(); - SDL_UnloadObject(libusb_ctx.libhandle); - libusb_ctx.libhandle = NULL; - } -#endif /* SDL_LIBUSB_DYNAMIC */ - return err; + if (udev_ctx && PLATFORM_hid_init() == 0) { + ++success; } #endif /* HAVE_PLATFORM_BACKEND */ - SDL_hidapi_wasinit = SDL_TRUE; + if (attempts > 0 && success == 0) { + return -1; + } + + ++SDL_hidapi_refcount; return 0; } -int HID_API_EXPORT HID_API_CALL hid_exit(void) +int SDL_hid_exit(void) { - int err = 0; + int result = 0; - if (SDL_hidapi_wasinit == SDL_FALSE) { + if (SDL_hidapi_refcount == 0) { return 0; } - SDL_hidapi_wasinit = SDL_FALSE; + --SDL_hidapi_refcount; + if (SDL_hidapi_refcount > 0) { + return 0; + } + SDL_hidapi_refcount = 0; + +#if !SDL_HIDAPI_DISABLED + HIDAPI_ShutdownDiscovery(); +#endif #if HAVE_PLATFORM_BACKEND if (udev_ctx) { - err = PLATFORM_hid_exit(); + result |= PLATFORM_hid_exit(); } +#if __LINUX__ + SDL_UDEV_ReleaseUdevSyms(); +#endif /* __LINUX __ */ #endif /* HAVE_PLATFORM_BACKEND */ + #ifdef SDL_LIBUSB_DYNAMIC if (libusb_ctx.libhandle) { - err |= LIBUSB_hid_exit(); /* Ehhhhh */ + result |= LIBUSB_hid_exit(); SDL_UnloadObject(libusb_ctx.libhandle); libusb_ctx.libhandle = NULL; } #endif /* SDL_LIBUSB_DYNAMIC */ - return err; + + return result; } -struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) +Uint32 SDL_hid_device_change_count(void) { + Uint32 counter = 0; + +#if !SDL_HIDAPI_DISABLED + if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) { + return 0; + } + + HIDAPI_UpdateDiscovery(); + + if (SDL_HIDAPI_discovery.m_unDeviceChangeCounter == 0) { + /* Counter wrapped! */ + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + } + counter = SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + +#endif /* !SDL_HIDAPI_DISABLED */ + + return counter; +} + +struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id) +{ +#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC) #ifdef SDL_LIBUSB_DYNAMIC - struct LIBUSB_hid_device_info *usb_devs = NULL; - struct LIBUSB_hid_device_info *usb_dev; + struct SDL_hid_device_info *usb_devs = NULL; + struct SDL_hid_device_info *usb_dev; #endif #if HAVE_DRIVER_BACKEND - struct DRIVER_hid_device_info* driver_devs = NULL; - struct DRIVER_hid_device_info* driver_dev; + struct SDL_hid_device_info* driver_devs = NULL; + struct SDL_hid_device_info* driver_dev; #endif #if HAVE_PLATFORM_BACKEND - struct PLATFORM_hid_device_info *raw_devs = NULL; - struct PLATFORM_hid_device_info *raw_dev; + struct SDL_hid_device_info *raw_devs = NULL; + struct SDL_hid_device_info *raw_dev; #endif - struct hid_device_info *devs = NULL, *last = NULL, *new_dev; + struct SDL_hid_device_info *devs = NULL, *last = NULL, *new_dev; - if (hid_init() != 0) { + if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) { return NULL; } @@ -673,14 +1189,14 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor SDL_Log("libusb devices found:"); #endif for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) { - new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info)); + new_dev = (struct SDL_hid_device_info*) SDL_malloc(sizeof(struct SDL_hid_device_info)); if (!new_dev) { LIBUSB_hid_free_enumeration(usb_devs); - hid_free_enumeration(devs); + SDL_hid_free_enumeration(devs); SDL_OutOfMemory(); return NULL; } - LIBUSB_CopyHIDDeviceInfo(usb_dev, new_dev); + CopyHIDDeviceInfo(usb_dev, new_dev); #ifdef DEBUG_HIDAPI SDL_Log(" - %ls %ls 0x%.4hx 0x%.4hx", usb_dev->manufacturer_string, usb_dev->product_string, @@ -700,8 +1216,8 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor #ifdef HAVE_DRIVER_BACKEND driver_devs = DRIVER_hid_enumerate(vendor_id, product_id); for (driver_dev = driver_devs; driver_dev; driver_dev = driver_dev->next) { - new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info)); - DRIVER_CopyHIDDeviceInfo(driver_dev, new_dev); + new_dev = (struct SDL_hid_device_info*) SDL_malloc(sizeof(struct SDL_hid_device_info)); + CopyHIDDeviceInfo(driver_dev, new_dev); if (last != NULL) { last->next = new_dev; @@ -746,7 +1262,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor } #endif if (!bFound) { - new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info)); + new_dev = (struct SDL_hid_device_info*) SDL_malloc(sizeof(struct SDL_hid_device_info)); if (!new_dev) { #ifdef SDL_LIBUSB_DYNAMIC if (libusb_ctx.libhandle) { @@ -754,11 +1270,11 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor } #endif PLATFORM_hid_free_enumeration(raw_devs); - hid_free_enumeration(devs); + SDL_hid_free_enumeration(devs); SDL_OutOfMemory(); return NULL; } - PLATFORM_CopyHIDDeviceInfo(raw_dev, new_dev); + CopyHIDDeviceInfo(raw_dev, new_dev); new_dev->next = NULL; if (last != NULL) { @@ -779,12 +1295,16 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor } #endif return devs; + +#else + return NULL; +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */ } -void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs) +void SDL_hid_free_enumeration(struct SDL_hid_device_info *devs) { while (devs) { - struct hid_device_info *next = devs->next; + struct SDL_hid_device_info *next = devs->next; SDL_free(devs->path); SDL_free(devs->serial_number); SDL_free(devs->manufacturer_string); @@ -794,153 +1314,274 @@ void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *d } } -HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +SDL_hid_device *SDL_hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) { - hid_device *pDevice = NULL; +#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC) + void *pDevice = NULL; - if (hid_init() != 0) { + if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) { return NULL; } #if HAVE_PLATFORM_BACKEND if (udev_ctx && - (pDevice = (hid_device*) PLATFORM_hid_open(vendor_id, product_id, serial_number)) != NULL) { - - HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend); - return WrapHIDDevice(wrapper); + (pDevice = PLATFORM_hid_open(vendor_id, product_id, serial_number)) != NULL) { + return CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend); } #endif /* HAVE_PLATFORM_BACKEND */ #if HAVE_DRIVER_BACKEND - if ((pDevice = (hid_device*) DRIVER_hid_open(vendor_id, product_id, serial_number)) != NULL) { - - HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend); - return WrapHIDDevice(wrapper); + if ((pDevice = DRIVER_hid_open(vendor_id, product_id, serial_number)) != NULL) { + return CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend); } #endif /* HAVE_DRIVER_BACKEND */ #ifdef SDL_LIBUSB_DYNAMIC if (libusb_ctx.libhandle && - (pDevice = (hid_device*) LIBUSB_hid_open(vendor_id, product_id, serial_number)) != NULL) { - - HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend); - return WrapHIDDevice(wrapper); + (pDevice = LIBUSB_hid_open(vendor_id, product_id, serial_number)) != NULL) { + return CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend); } #endif /* SDL_LIBUSB_DYNAMIC */ +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */ + return NULL; } -HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bExclusive /* = false */) +SDL_hid_device *SDL_hid_open_path(const char *path, int bExclusive /* = false */) { - hid_device *pDevice = NULL; +#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC) + void *pDevice = NULL; - if (hid_init() != 0) { + if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) { return NULL; } #if HAVE_PLATFORM_BACKEND if (udev_ctx && - (pDevice = (hid_device*) PLATFORM_hid_open_path(path, bExclusive)) != NULL) { - - HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend); - return WrapHIDDevice(wrapper); + (pDevice = PLATFORM_hid_open_path(path, bExclusive)) != NULL) { + return CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend); } #endif /* HAVE_PLATFORM_BACKEND */ #if HAVE_DRIVER_BACKEND - if ((pDevice = (hid_device*) DRIVER_hid_open_path(path, bExclusive)) != NULL) { - - HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend); - return WrapHIDDevice(wrapper); + if ((pDevice = DRIVER_hid_open_path(path, bExclusive)) != NULL) { + return CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend); } #endif /* HAVE_DRIVER_BACKEND */ #ifdef SDL_LIBUSB_DYNAMIC if (libusb_ctx.libhandle && - (pDevice = (hid_device*) LIBUSB_hid_open_path(path, bExclusive)) != NULL) { - - HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend); - return WrapHIDDevice(wrapper); + (pDevice = LIBUSB_hid_open_path(path, bExclusive)) != NULL) { + return CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend); } #endif /* SDL_LIBUSB_DYNAMIC */ +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */ + return NULL; } -int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length) +int SDL_hid_write(SDL_hid_device *device, const unsigned char *data, size_t length) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - return wrapper->backend->hid_write(wrapper->device, data, length); + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_write(device->device, data, length); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; } -int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds) +int SDL_hid_read_timeout(SDL_hid_device *device, unsigned char *data, size_t length, int milliseconds) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - return wrapper->backend->hid_read_timeout(wrapper->device, data, length, milliseconds); + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_read_timeout(device->device, data, length, milliseconds); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; } -int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length) +int SDL_hid_read(SDL_hid_device *device, unsigned char *data, size_t length) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - return wrapper->backend->hid_read(wrapper->device, data, length); + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_read(device->device, data, length); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; } -int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock) +int SDL_hid_set_nonblocking(SDL_hid_device *device, int nonblock) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - return wrapper->backend->hid_set_nonblocking(wrapper->device, nonblock); + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_set_nonblocking(device->device, nonblock); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; } -int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length) +int SDL_hid_send_feature_report(SDL_hid_device *device, const unsigned char *data, size_t length) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - return wrapper->backend->hid_send_feature_report(wrapper->device, data, length); + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_send_feature_report(device->device, data, length); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; } -int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length) +int SDL_hid_get_feature_report(SDL_hid_device *device, unsigned char *data, size_t length) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - return wrapper->backend->hid_get_feature_report(wrapper->device, data, length); + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_get_feature_report(device->device, data, length); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; } -void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device) +void SDL_hid_close(SDL_hid_device *device) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - wrapper->backend->hid_close(wrapper->device); - DeleteHIDDeviceWrapper(wrapper); + CHECK_DEVICE_MAGIC(device,); + + device->backend->hid_close(device->device); + DeleteHIDDeviceWrapper(device); } -int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen) +int SDL_hid_get_manufacturer_string(SDL_hid_device *device, wchar_t *string, size_t maxlen) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - return wrapper->backend->hid_get_manufacturer_string(wrapper->device, string, maxlen); + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_get_manufacturer_string(device->device, string, maxlen); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; } -int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen) +int SDL_hid_get_product_string(SDL_hid_device *device, wchar_t *string, size_t maxlen) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - return wrapper->backend->hid_get_product_string(wrapper->device, string, maxlen); + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_get_product_string(device->device, string, maxlen); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; } -int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen) +int SDL_hid_get_serial_number_string(SDL_hid_device *device, wchar_t *string, size_t maxlen) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - return wrapper->backend->hid_get_serial_number_string(wrapper->device, string, maxlen); + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_get_serial_number_string(device->device, string, maxlen); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; } -int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen) +int SDL_hid_get_indexed_string(SDL_hid_device *device, int string_index, wchar_t *string, size_t maxlen) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - return wrapper->backend->hid_get_indexed_string(wrapper->device, string_index, string, maxlen); + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_get_indexed_string(device->device, string_index, string, maxlen); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; } -HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device) +void SDL_hid_ble_scan(SDL_bool active) { - HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); - return wrapper->backend->hid_error(wrapper->device); +#if __IPHONEOS__ || __TVOS__ + hid_ble_scan(active); +#endif } -#endif /* SDL_JOYSTICK_HIDAPI */ +#ifdef HAVE_ENABLE_GAMECUBE_ADAPTORS +/* This is needed to enable input for Nyko and EVORETRO GameCube adaptors */ +void SDL_EnableGameCubeAdaptors(void) +{ +#ifdef SDL_LIBUSB_DYNAMIC + libusb_context *context = NULL; + libusb_device **devs = NULL; + libusb_device_handle *handle = NULL; + struct libusb_device_descriptor desc; + ssize_t i, num_devs; + int kernel_detached = 0; + + if (libusb_ctx.libhandle == NULL) { + return; + } + + if (libusb_init(&context) == 0) { + num_devs = libusb_get_device_list(context, &devs); + for (i = 0; i < num_devs; ++i) { + if (libusb_get_device_descriptor(devs[i], &desc) != 0) { + continue; + } + + if (desc.idVendor != 0x057e || desc.idProduct != 0x0337) { + continue; + } + + if (libusb_open(devs[i], &handle) != 0) { + continue; + } + + if (libusb_kernel_driver_active(handle, 0)) { + if (libusb_detach_kernel_driver(handle, 0) == 0) { + kernel_detached = 1; + } + } + + if (libusb_claim_interface(handle, 0) == 0) { + libusb_control_transfer(handle, 0x21, 11, 0x0001, 0, NULL, 0, 1000); + libusb_release_interface(handle, 0); + } + + if (kernel_detached) { + libusb_attach_kernel_driver(handle, 0); + } + + libusb_close(handle); + } + + libusb_free_device_list(devs, 1); + + libusb_exit(context); + } +#endif /* SDL_LIBUSB_DYNAMIC */ +} +#endif /* HAVE_ENABLE_GAMECUBE_ADAPTORS */ /* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/hidapi/SDL_hidapi_c.h b/Engine/lib/sdl/src/hidapi/SDL_hidapi_c.h new file mode 100644 index 000000000..1b4094232 --- /dev/null +++ b/Engine/lib/sdl/src/hidapi/SDL_hidapi_c.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../SDL_internal.h" + +#ifdef SDL_JOYSTICK_HIDAPI + +#ifdef SDL_LIBUSB_DYNAMIC +#define HAVE_ENABLE_GAMECUBE_ADAPTORS +#endif + +#ifdef HAVE_ENABLE_GAMECUBE_ADAPTORS +extern void SDL_EnableGameCubeAdaptors(void); +#endif + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/hidapi/android/hid.cpp b/Engine/lib/sdl/src/hidapi/android/hid.cpp index e5af5ad2d..de365d005 100644 --- a/Engine/lib/sdl/src/hidapi/android/hid.cpp +++ b/Engine/lib/sdl/src/hidapi/android/hid.cpp @@ -1,17 +1,33 @@ -//=================== Copyright Valve Corporation, All rights reserved. ======= -// +/* + Simple DirectMedia Layer + Copyright (C) 2021 Valve Corporation + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + // Purpose: A wrapper implementing "HID" API for Android // // This layer glues the hidapi API to Android's USB and BLE stack. -// -//============================================================================= + +// Common to stub version and non-stub version of functions #include #include -#include -#include // For ETIMEDOUT and ECONNRESET -#include // For malloc() and free() -#include // For memcpy() #define TAG "hidapi" @@ -31,6 +47,35 @@ #define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function #define HID_DEVICE_MANAGER_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function) + +#if !SDL_HIDAPI_DISABLED + +#include "SDL_hints.h" +#include "../../core/android/SDL_android.h" + +#define hid_init PLATFORM_hid_init +#define hid_exit PLATFORM_hid_exit +#define hid_enumerate PLATFORM_hid_enumerate +#define hid_free_enumeration PLATFORM_hid_free_enumeration +#define hid_open PLATFORM_hid_open +#define hid_open_path PLATFORM_hid_open_path +#define hid_write PLATFORM_hid_write +#define hid_read_timeout PLATFORM_hid_read_timeout +#define hid_read PLATFORM_hid_read +#define hid_set_nonblocking PLATFORM_hid_set_nonblocking +#define hid_send_feature_report PLATFORM_hid_send_feature_report +#define hid_get_feature_report PLATFORM_hid_get_feature_report +#define hid_close PLATFORM_hid_close +#define hid_get_manufacturer_string PLATFORM_hid_get_manufacturer_string +#define hid_get_product_string PLATFORM_hid_get_product_string +#define hid_get_serial_number_string PLATFORM_hid_get_serial_number_string +#define hid_get_indexed_string PLATFORM_hid_get_indexed_string +#define hid_error PLATFORM_hid_error + +#include +#include // For ETIMEDOUT and ECONNRESET +#include // For malloc() and free() + #include "../hidapi/hidapi.h" typedef uint32_t uint32; @@ -154,7 +199,7 @@ public: } m_nSize = nSize; - memcpy( m_pData, pData, nSize ); + SDL_memcpy( m_pData, pData, nSize ); } void clear() @@ -269,9 +314,9 @@ private: static jbyteArray NewByteArray( JNIEnv* env, const uint8_t *pData, size_t nDataLen ) { - jbyteArray array = env->NewByteArray( nDataLen ); + jbyteArray array = env->NewByteArray( (jsize)nDataLen ); jbyte *pBuf = env->GetByteArrayElements( array, NULL ); - memcpy( pBuf, pData, nDataLen ); + SDL_memcpy( pBuf, pData, nDataLen ); env->ReleaseByteArrayElements( array, pBuf, 0 ); return array; @@ -282,7 +327,7 @@ static char *CreateStringFromJString( JNIEnv *env, const jstring &sString ) size_t nLength = env->GetStringUTFLength( sString ); const char *pjChars = env->GetStringUTFChars( sString, NULL ); char *psString = (char*)malloc( nLength + 1 ); - memcpy( psString, pjChars, nLength ); + SDL_memcpy( psString, pjChars, nLength ); psString[ nLength ] = '\0'; env->ReleaseStringUTFChars( sString, pjChars ); return psString; @@ -305,9 +350,9 @@ static wchar_t *CreateWStringFromJString( JNIEnv *env, const jstring &sString ) static wchar_t *CreateWStringFromWString( const wchar_t *pwSrc ) { - size_t nLength = wcslen( pwSrc ); + size_t nLength = SDL_wcslen( pwSrc ); wchar_t *pwString = (wchar_t*)malloc( ( nLength + 1 ) * sizeof( wchar_t ) ); - memcpy( pwString, pwSrc, nLength * sizeof( wchar_t ) ); + SDL_memcpy( pwString, pwSrc, nLength * sizeof( wchar_t ) ); pwString[ nLength ] = '\0'; return pwString; } @@ -316,7 +361,7 @@ static hid_device_info *CopyHIDDeviceInfo( const hid_device_info *pInfo ) { hid_device_info *pCopy = new hid_device_info; *pCopy = *pInfo; - pCopy->path = strdup( pInfo->path ); + pCopy->path = SDL_strdup( pInfo->path ); pCopy->product_string = CreateWStringFromWString( pInfo->product_string ); pCopy->manufacturer_string = CreateWStringFromWString( pInfo->manufacturer_string ); pCopy->serial_number = CreateWStringFromWString( pInfo->serial_number ); @@ -334,17 +379,49 @@ static void FreeHIDDeviceInfo( hid_device_info *pInfo ) static jclass g_HIDDeviceManagerCallbackClass; static jobject g_HIDDeviceManagerCallbackHandler; +static jmethodID g_midHIDDeviceManagerInitialize; static jmethodID g_midHIDDeviceManagerOpen; static jmethodID g_midHIDDeviceManagerSendOutputReport; static jmethodID g_midHIDDeviceManagerSendFeatureReport; static jmethodID g_midHIDDeviceManagerGetFeatureReport; static jmethodID g_midHIDDeviceManagerClose; +static bool g_initialized = false; static uint64_t get_timespec_ms( const struct timespec &ts ) { return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; } +static void ExceptionCheck( JNIEnv *env, const char *pszClassName, const char *pszMethodName ) +{ + if ( env->ExceptionCheck() ) + { + // Get our exception + jthrowable jExcept = env->ExceptionOccurred(); + + // Clear the exception so we can call JNI again + env->ExceptionClear(); + + // Get our exception message + jclass jExceptClass = env->GetObjectClass( jExcept ); + jmethodID jMessageMethod = env->GetMethodID( jExceptClass, "getMessage", "()Ljava/lang/String;" ); + jstring jMessage = (jstring)( env->CallObjectMethod( jExcept, jMessageMethod ) ); + const char *pszMessage = env->GetStringUTFChars( jMessage, NULL ); + + // ...and log it. + LOGE( "%s%s%s threw an exception: %s", + pszClassName ? pszClassName : "", + pszClassName ? "::" : "", + pszMethodName, pszMessage ); + + // Cleanup + env->ReleaseStringUTFChars( jMessage, pszMessage ); + env->DeleteLocalRef( jMessage ); + env->DeleteLocalRef( jExceptClass ); + env->DeleteLocalRef( jExcept ); + } +} + class CHIDDevice { public: @@ -404,29 +481,7 @@ public: void ExceptionCheck( JNIEnv *env, const char *pszMethodName ) { - if ( env->ExceptionCheck() ) - { - // Get our exception - jthrowable jExcept = env->ExceptionOccurred(); - - // Clear the exception so we can call JNI again - env->ExceptionClear(); - - // Get our exception message - jclass jExceptClass = env->GetObjectClass( jExcept ); - jmethodID jMessageMethod = env->GetMethodID( jExceptClass, "getMessage", "()Ljava/lang/String;" ); - jstring jMessage = (jstring)( env->CallObjectMethod( jExcept, jMessageMethod ) ); - const char *pszMessage = env->GetStringUTFChars( jMessage, NULL ); - - // ...and log it. - LOGE( "CHIDDevice::%s threw an exception: %s", pszMethodName, pszMessage ); - - // Cleanup - env->ReleaseStringUTFChars( jMessage, pszMessage ); - env->DeleteLocalRef( jMessage ); - env->DeleteLocalRef( jExceptClass ); - env->DeleteLocalRef( jExcept ); - } + ::ExceptionCheck( env, "CHIDDevice", pszMethodName ); } bool BOpen() @@ -527,12 +582,12 @@ public: if ( m_bIsBLESteamController ) { data[0] = 0x03; - memcpy( data + 1, buffer.data(), nDataLen ); + SDL_memcpy( data + 1, buffer.data(), nDataLen ); ++nDataLen; } else { - memcpy( data, buffer.data(), nDataLen ); + SDL_memcpy( data, buffer.data(), nDataLen ); } m_vecData.pop_front(); @@ -541,7 +596,7 @@ public: // data[0], data[1], data[2], data[3], // data[4], data[5], data[6], data[7]); - return nDataLen; + return (int)nDataLen; } int SendOutputReport( const unsigned char *pData, size_t nDataLen ) @@ -669,11 +724,11 @@ public: } size_t uBytesToCopy = m_featureReport.size() > nDataLen ? nDataLen : m_featureReport.size(); - memcpy( pData, m_featureReport.data(), uBytesToCopy ); + SDL_memcpy( pData, m_featureReport.data(), uBytesToCopy ); m_featureReport.clear(); LOGV( "=== Got %u bytes", uBytesToCopy ); - return uBytesToCopy; + return (int)uBytesToCopy; } } @@ -815,6 +870,11 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallba if ( objClass ) { g_HIDDeviceManagerCallbackClass = reinterpret_cast< jclass >( env->NewGlobalRef( objClass ) ); + g_midHIDDeviceManagerInitialize = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "initialize", "(ZZ)Z" ); + if ( !g_midHIDDeviceManagerInitialize ) + { + __android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing initialize" ); + } g_midHIDDeviceManagerOpen = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "openDevice", "(I)Z" ); if ( !g_midHIDDeviceManagerOpen ) { @@ -854,6 +914,7 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallbac g_HIDDeviceManagerCallbackClass = NULL; env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler ); g_HIDDeviceManagerCallbackHandler = NULL; + g_initialized = false; } } @@ -863,7 +924,7 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNI LOGV( "HIDDeviceConnected() id=%d VID/PID = %.4x/%.4x, interface %d\n", nDeviceID, nVendorId, nProductId, nInterface ); hid_device_info *pInfo = new hid_device_info; - memset( pInfo, 0, sizeof( *pInfo ) ); + SDL_memset( pInfo, 0, sizeof( *pInfo ) ); pInfo->path = CreateStringFromJString( env, sIdentifier ); pInfo->vendor_id = nVendorId; pInfo->product_id = nProductId; @@ -988,6 +1049,36 @@ extern "C" int hid_init(void) { + if ( !g_initialized ) + { + // HIDAPI doesn't work well with Android < 4.3 + if (SDL_GetAndroidSDKVersion() >= 18) { + // Make sure thread is attached to JVM/env + JNIEnv *env; + g_JVM->AttachCurrentThread( &env, NULL ); + pthread_setspecific( g_ThreadKey, (void*)env ); + + if ( !g_HIDDeviceManagerCallbackHandler ) + { + LOGV( "hid_init() without callback handler" ); + return -1; + } + + // Bluetooth is currently only used for Steam Controllers, so check that hint + // before initializing Bluetooth, which will prompt the user for permission. + bool init_usb = true; + bool init_bluetooth = false; + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_STEAM, SDL_FALSE)) { + if (SDL_GetAndroidSDKVersion() < 31 || + Android_JNI_RequestPermission("android.permission.BLUETOOTH_CONNECT")) { + init_bluetooth = true; + } + } + env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerInitialize, init_usb, init_bluetooth ); + ExceptionCheck( env, NULL, "hid_init" ); + } + g_initialized = true; // Regardless of result, so it's only called once + } return 0; } @@ -1035,7 +1126,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx hid_mutex_guard l( &g_DevicesMutex ); for ( hid_device_ref pCurr = g_Devices; pCurr; pCurr = pCurr->next ) { - if ( strcmp( pCurr->GetDeviceInfo()->path, path ) == 0 ) + if ( SDL_strcmp( pCurr->GetDeviceInfo()->path, path ) == 0 ) { hid_device *pValue = pCurr->GetDevice(); if ( pValue ) @@ -1072,7 +1163,32 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned ch return -1; // Controller was disconnected } -// TODO: Implement timeout? +static uint32_t getms() +{ + struct timeval now; + + gettimeofday(&now, NULL); + return (uint32_t)(now.tv_sec * 1000 + now.tv_usec / 1000); +} + +static void delayms(uint32_t ms) +{ + int was_error; + + struct timespec elapsed, tv; + + /* Set the timeout interval */ + elapsed.tv_sec = ms / 1000; + elapsed.tv_nsec = (ms % 1000) * 1000000; + do { + errno = 0; + + tv.tv_sec = elapsed.tv_sec; + tv.tv_nsec = elapsed.tv_nsec; + was_error = nanosleep(&tv, &elapsed); + } while (was_error && (errno == EINTR)); +} + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds) { if ( device ) @@ -1081,7 +1197,17 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned ch hid_device_ref pDevice = FindDevice( device->m_nId ); if ( pDevice ) { - return pDevice->GetInput( data, length ); + int nResult = pDevice->GetInput( data, length ); + if ( nResult == 0 && milliseconds > 0 ) + { + uint32_t start = getms(); + do + { + delayms( 1 ); + nResult = pDevice->GetInput( data, length ); + } while ( nResult == 0 && ( getms() - start ) < milliseconds ); + } + return nResult; } LOGV( "controller was disconnected" ); } @@ -1213,3 +1339,80 @@ int hid_exit(void) } } + +#else + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol ); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value); + + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz ) +{ + LOGV("Stub HIDDeviceRegisterCallback()"); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz) +{ + LOGV("Stub HIDDeviceReleaseCallback()"); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol ) +{ + LOGV("Stub HIDDeviceConnected() id=%d VID/PID = %.4x/%.4x, interface %d\n", nDeviceID, nVendorId, nProductId, nInterface); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID) +{ + LOGV("Stub HIDDeviceOpenPending() id=%d\n", nDeviceID); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened) +{ + LOGV("Stub HIDDeviceOpenResult() id=%d, result=%s\n", nDeviceID, bOpened ? "true" : "false"); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID) +{ + LOGV("Stub HIDDeviceDisconnected() id=%d\n", nDeviceID); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value) +{ + LOGV("Stub HIDDeviceInput() id=%d len=%u\n", nDeviceID, nBufSize); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value) +{ + LOGV("Stub HIDDeviceFeatureReport() id=%d len=%u\n", nDeviceID, nBufSize); +} + +#endif /* SDL_HIDAPI_DISABLED */ diff --git a/Engine/lib/sdl/src/hidapi/hidapi/hidapi.h b/Engine/lib/sdl/src/hidapi/hidapi/hidapi.h index 2c663196b..3fddfa885 100644 --- a/Engine/lib/sdl/src/hidapi/hidapi/hidapi.h +++ b/Engine/lib/sdl/src/hidapi/hidapi/hidapi.h @@ -29,7 +29,12 @@ #include -#if defined(_WIN32) && !defined(NAMESPACE) && (0) /* SDL: don't export hidapi syms */ +#ifdef SDL_hidapi_h_ +#define SDL_HIDAPI_IMPLEMENTATION +#define hid_device_info SDL_hid_device_info +#endif + +#if defined(_WIN32) && !defined(NAMESPACE) && !defined(SDL_HIDAPI_IMPLEMENTATION) /* SDL: don't export hidapi syms */ #define HID_API_EXPORT __declspec(dllexport) #define HID_API_CALL #else @@ -53,6 +58,7 @@ namespace NAMESPACE { struct hid_device_; typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ +#ifndef SDL_HIDAPI_IMPLEMENTATION /** hidapi info structure */ struct hid_device_info { /** Platform-specific device path */ @@ -77,9 +83,11 @@ namespace NAMESPACE { (Windows/Mac only).*/ unsigned short usage; /** The USB interface which this logical device - represents. Valid on both Linux implementations - in all cases, and valid on the Windows implementation - only if the device contains more than one interface. */ + represents. + + * Valid on both Linux implementations in all cases. + * Valid on the Windows implementation only if the device + contains more than one interface. */ int interface_number; /** Additional information about the USB interface. @@ -91,6 +99,7 @@ namespace NAMESPACE { /** Pointer to the next device */ struct hid_device_info *next; }; +#endif /* !SDL_HIDAPI_IMPLEMENTATION */ /** @brief Initialize the HIDAPI library. @@ -101,7 +110,7 @@ namespace NAMESPACE { needed. This function should be called at the beginning of execution however, if there is a chance of HIDAPI handles being opened by different threads simultaneously. - + @ingroup API @returns @@ -139,7 +148,7 @@ namespace NAMESPACE { @returns This function returns a pointer to a linked list of type - struct #hid_device, containing information about the HID devices + struct #hid_device_info, containing information about the HID devices attached to the system, or NULL in the case of failure. Free this linked list by calling hid_free_enumeration(). */ @@ -205,7 +214,7 @@ namespace NAMESPACE { the Control Endpoint (Endpoint 0). @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param data The data to send, including the report number as the first byte. @param length The length in bytes of the data to send. @@ -214,7 +223,7 @@ namespace NAMESPACE { This function returns the actual number of bytes written and -1 on error. */ - int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length); + int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length); /** @brief Read an Input report from a HID device with timeout. @@ -223,7 +232,7 @@ namespace NAMESPACE { contain the Report number if the device uses numbered reports. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param data A buffer to put the read data into. @param length The number of bytes to read. For devices with multiple reports, make sure to read an extra byte for @@ -235,7 +244,7 @@ namespace NAMESPACE { -1 on error. If no packet was available to be read within the timeout period, this function returns 0. */ - int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds); + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); /** @brief Read an Input report from a HID device. @@ -244,7 +253,7 @@ namespace NAMESPACE { contain the Report number if the device uses numbered reports. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param data A buffer to put the read data into. @param length The number of bytes to read. For devices with multiple reports, make sure to read an extra byte for @@ -255,7 +264,7 @@ namespace NAMESPACE { -1 on error. If no packet was available to be read and the handle is in non-blocking mode, this function returns 0. */ - int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length); + int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length); /** @brief Set the device handle to be non-blocking. @@ -267,7 +276,7 @@ namespace NAMESPACE { Nonblocking can be turned on and off at any time. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param nonblock enable or not the nonblocking reads - 1 to enable nonblocking - 0 to disable nonblocking. @@ -275,7 +284,7 @@ namespace NAMESPACE { @returns This function returns 0 on success and -1 on error. */ - int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock); + int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock); /** @brief Send a Feature report to the device. @@ -293,7 +302,7 @@ namespace NAMESPACE { in would be 17. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param data The data to send, including the report number as the first byte. @param length The length in bytes of the data to send, including @@ -303,7 +312,7 @@ namespace NAMESPACE { This function returns the actual number of bytes written and -1 on error. */ - int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length); + int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length); /** @brief Get a feature report from a HID device. @@ -314,7 +323,7 @@ namespace NAMESPACE { start in data[1]. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param data A buffer to put the read data into, including the Report ID. Set the first byte of @p data[] to the Report ID of the report to be read, or set it to zero @@ -328,55 +337,55 @@ namespace NAMESPACE { one for the report ID (which is still in the first byte), or -1 on error. */ - int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length); + int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length); /** @brief Close a HID device. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). */ - void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device); + void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev); /** @brief Get The Manufacturer String from a HID device. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @returns This function returns 0 on success and -1 on error. */ - int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen); + int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen); /** @brief Get The Product String from a HID device. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @returns This function returns 0 on success and -1 on error. */ - int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen); + int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen); /** @brief Get The Serial Number String from a HID device. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @returns This function returns 0 on success and -1 on error. */ - int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen); + int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen); /** @brief Get a string from a HID device, based on its string index. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param string_index The index of the string to get. @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @@ -384,18 +393,22 @@ namespace NAMESPACE { @returns This function returns 0 on success and -1 on error. */ - int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen); + int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen); /** @brief Get a string describing the last error which occurred. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @returns This function returns a string containing the last error which occurred or NULL if none has occurred. */ - HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device); + HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *dev); + +#if __IPHONEOS__ || __TVOS__ + HID_API_EXPORT void HID_API_CALL hid_ble_scan(int active); +#endif #if defined(__cplusplus) && !defined(NAMESPACE) } diff --git a/Engine/lib/sdl/src/hidapi/ios/hid.m b/Engine/lib/sdl/src/hidapi/ios/hid.m index 504a994b1..111b8f236 100644 --- a/Engine/lib/sdl/src/hidapi/ios/hid.m +++ b/Engine/lib/sdl/src/hidapi/ios/hid.m @@ -1,11 +1,47 @@ -//======== Copyright (c) 2017 Valve Corporation, All rights reserved. ========= -// -// Purpose: HID device abstraction temporary stub -// -//============================================================================= +/* + Simple DirectMedia Layer + Copyright (C) 2021 Valve Corporation + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ #include "../../SDL_internal.h" -#ifdef SDL_JOYSTICK_HIDAPI +#if !SDL_HIDAPI_DISABLED + +#include "SDL_hints.h" + +#define hid_init PLATFORM_hid_init +#define hid_exit PLATFORM_hid_exit +#define hid_enumerate PLATFORM_hid_enumerate +#define hid_free_enumeration PLATFORM_hid_free_enumeration +#define hid_open PLATFORM_hid_open +#define hid_open_path PLATFORM_hid_open_path +#define hid_write PLATFORM_hid_write +#define hid_read_timeout PLATFORM_hid_read_timeout +#define hid_read PLATFORM_hid_read +#define hid_set_nonblocking PLATFORM_hid_set_nonblocking +#define hid_send_feature_report PLATFORM_hid_send_feature_report +#define hid_get_feature_report PLATFORM_hid_get_feature_report +#define hid_close PLATFORM_hid_close +#define hid_get_manufacturer_string PLATFORM_hid_get_manufacturer_string +#define hid_get_product_string PLATFORM_hid_get_product_string +#define hid_get_serial_number_string PLATFORM_hid_get_serial_number_string +#define hid_get_indexed_string PLATFORM_hid_get_indexed_string +#define hid_error PLATFORM_hid_error #include #include @@ -193,24 +229,29 @@ typedef enum sharedInstance = [HIDBLEManager new]; sharedInstance.nPendingScans = 0; sharedInstance.nPendingPairs = 0; - - [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appWillResignActiveNotification:) name: UIApplicationWillResignActiveNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appDidBecomeActiveNotification:) name:UIApplicationDidBecomeActiveNotification object:nil]; - // receive reports on a high-priority serial-queue. optionally put writes on the serial queue to avoid logical - // race conditions talking to the controller from multiple threads, although BLE fragmentation/assembly means - // that we can still screw this up. - // most importantly we need to consume reports at a high priority to avoid the OS thinking we aren't really - // listening to the BLE device, as iOS on slower devices may stop delivery of packets to the app WITHOUT ACTUALLY - // DISCONNECTING FROM THE DEVICE if we don't react quickly enough to their delivery. - // see also the error-handling states in the peripheral delegate to re-open the device if it gets closed - sharedInstance.bleSerialQueue = dispatch_queue_create( "com.valvesoftware.steamcontroller.ble", DISPATCH_QUEUE_SERIAL ); - dispatch_set_target_queue( sharedInstance.bleSerialQueue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); + // Bluetooth is currently only used for Steam Controllers, so check that hint + // before initializing Bluetooth, which will prompt the user for permission. + if ( SDL_GetHintBoolean( SDL_HINT_JOYSTICK_HIDAPI_STEAM, SDL_FALSE ) ) + { + [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appWillResignActiveNotification:) name: UIApplicationWillResignActiveNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appDidBecomeActiveNotification:) name:UIApplicationDidBecomeActiveNotification object:nil]; - // creating a CBCentralManager will always trigger a future centralManagerDidUpdateState: - // where any scanning gets started or connecting to existing peripherals happens, it's never already in a - // powered-on state for a newly launched application. - sharedInstance.centralManager = [[CBCentralManager alloc] initWithDelegate:sharedInstance queue:sharedInstance.bleSerialQueue]; + // receive reports on a high-priority serial-queue. optionally put writes on the serial queue to avoid logical + // race conditions talking to the controller from multiple threads, although BLE fragmentation/assembly means + // that we can still screw this up. + // most importantly we need to consume reports at a high priority to avoid the OS thinking we aren't really + // listening to the BLE device, as iOS on slower devices may stop delivery of packets to the app WITHOUT ACTUALLY + // DISCONNECTING FROM THE DEVICE if we don't react quickly enough to their delivery. + // see also the error-handling states in the peripheral delegate to re-open the device if it gets closed + sharedInstance.bleSerialQueue = dispatch_queue_create( "com.valvesoftware.steamcontroller.ble", DISPATCH_QUEUE_SERIAL ); + dispatch_set_target_queue( sharedInstance.bleSerialQueue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); + + // creating a CBCentralManager will always trigger a future centralManagerDidUpdateState: + // where any scanning gets started or connecting to existing peripherals happens, it's never already in a + // powered-on state for a newly launched application. + sharedInstance.centralManager = [[CBCentralManager alloc] initWithDelegate:sharedInstance queue:sharedInstance.bleSerialQueue]; + } sharedInstance.deviceMap = [[NSMapTable alloc] initWithKeyOptions:NSMapTableWeakMemory valueOptions:NSMapTableStrongMemory capacity:4]; }); return sharedInstance; @@ -250,6 +291,11 @@ typedef enum static uint64_t s_unLastUpdateTick = 0; static mach_timebase_info_data_t s_timebase_info; + if ( self.centralManager == nil ) + { + return 0; + } + if (s_timebase_info.denom == 0) { mach_timebase_info( &s_timebase_info ); @@ -295,6 +341,11 @@ typedef enum // manual API for folks to start & stop scanning - (void)startScan:(int)duration { + if ( self.centralManager == nil ) + { + return; + } + NSLog( @"BLE: requesting scan for %d seconds", duration ); @synchronized (self) { @@ -314,6 +365,11 @@ typedef enum - (void)stopScan { + if ( self.centralManager == nil ) + { + return; + } + NSLog( @"BLE: stopping scan" ); @synchronized (self) { @@ -709,7 +765,7 @@ int HID_API_EXPORT HID_API_CALL hid_exit(void) return 0; } -void HID_API_EXPORT HID_API_CALL hid_ble_scan( bool bStart ) +void HID_API_EXPORT HID_API_CALL hid_ble_scan( int bStart ) { HIDBLEManager *bleManager = HIDBLEManager.sharedInstance; if ( bStart ) @@ -722,7 +778,12 @@ void HID_API_EXPORT HID_API_CALL hid_ble_scan( bool bStart ) } } -hid_device * HID_API_EXPORT hid_open_path( const char *path, int bExclusive /* = false */ ) +HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +{ + return NULL; +} + +HID_API_EXPORT hid_device * HID_API_CALL hid_open_path( const char *path, int bExclusive /* = false */ ) { hid_device *result = NULL; NSString *nssPath = [NSString stringWithUTF8String:path]; @@ -836,6 +897,11 @@ int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *s return 0; } +int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) +{ + return -1; +} + int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length) { HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle; @@ -912,4 +978,9 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t return result; } -#endif /* SDL_JOYSTICK_HIDAPI */ +HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *dev) +{ + return NULL; +} + +#endif /* !SDL_HIDAPI_DISABLED */ diff --git a/Engine/lib/sdl/src/hidapi/libusb/hid.c b/Engine/lib/sdl/src/hidapi/libusb/hid.c index 67833d9b6..c54746e4d 100644 --- a/Engine/lib/sdl/src/hidapi/libusb/hid.c +++ b/Engine/lib/sdl/src/hidapi/libusb/hid.c @@ -31,12 +31,29 @@ #include "SDL_thread.h" #include "SDL_mutex.h" -#ifdef SDL_JOYSTICK_HIDAPI +#ifndef HAVE_WCSDUP +#ifdef HAVE__WCSDUP +#define wcsdup _wcsdup +#else +#define wcsdup _dupwcs +static wchar_t *_dupwcs(const wchar_t *src) +{ + wchar_t *dst = NULL; + if (src) { + size_t len = SDL_wcslen(src) + 1; + len *= sizeof(wchar_t); + dst = (wchar_t *) malloc(len); + if (dst) memcpy(dst, src, len); + } + return dst; +} +#endif +#endif /* HAVE_WCSDUP */ #include #include /* setlocale */ -#include "hidapi.h" +#include "../hidapi/hidapi.h" #ifdef NAMESPACE namespace NAMESPACE @@ -57,12 +74,8 @@ typedef struct _SDL_ThreadBarrier static int SDL_CreateThreadBarrier(SDL_ThreadBarrier *barrier, Uint32 count) { - if (barrier == NULL) { - return SDL_SetError("barrier must be non-NULL"); - } - if (count == 0) { - return SDL_SetError("count must be > 0"); - } + SDL_assert(barrier != NULL); + SDL_assert(count != 0); barrier->mutex = SDL_CreateMutex(); if (barrier->mutex == NULL) { @@ -157,7 +170,7 @@ struct hid_device_ { SDL_cond *condition; SDL_ThreadBarrier barrier; /* Ensures correct startup sequence */ int shutdown_thread; - int cancelled; + int transfer_loop_finished; struct libusb_transfer *transfer; /* List of received input reports. */ @@ -196,7 +209,6 @@ static void free_hid_device(hid_device *dev) /*TODO: Implement this function on hidapi/libusb.. */ static void register_error(hid_device *dev, const char *op) { - } #endif @@ -320,7 +332,6 @@ static inline int libusb_get_string_descriptor(libusb_device_handle *dev, (LIBUSB_DT_STRING << 8) | descriptor_index, lang_id, data, (uint16_t) length, 1000); } - #endif @@ -373,12 +384,16 @@ static int is_language_supported(libusb_device_handle *dev, uint16_t lang) /* This function returns a newly allocated wide string containing the USB device string numbered by the index. The returned string must be freed by using free(). */ +#if defined(__OS2__) /* don't use iconv on OS/2: no support for wchar_t. */ +#define NO_ICONV +#endif static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) { char buf[512]; int len; wchar_t *str = NULL; +#if !defined(NO_ICONV) wchar_t wbuf[256]; SDL_iconv_t ic; size_t inbytes; @@ -386,6 +401,9 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) size_t res; const char *inptr; char *outptr; +#else + int i; +#endif /* Determine which language to use. */ uint16_t lang; @@ -402,6 +420,23 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) if (len < 0) return NULL; +#if defined(NO_ICONV) /* original hidapi code for NO_ICONV : */ + + /* Bionic does not have wchar_t iconv support, so it + has to be done manually. The following code will only work for + code points that can be represented as a single UTF-16 character, + and will incorrectly convert any code points which require more + than one UTF-16 character. + + Skip over the first character (2-bytes). */ + len -= 2; + str = (wchar_t*) malloc((len / 2 + 1) * sizeof(wchar_t)); + for (i = 0; i < len / 2; i++) { + str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8); + } + str[len / 2] = 0x00000000; + +#else /* buf does not need to be explicitly NULL-terminated because it is only passed into iconv() which does not need it. */ @@ -434,10 +469,100 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) err: SDL_iconv_close(ic); +#endif return str; } +struct usb_string_cache_entry { + uint16_t vid; + uint16_t pid; + wchar_t *vendor; + wchar_t *product; +}; + +static struct usb_string_cache_entry *usb_string_cache = NULL; +static size_t usb_string_cache_size = 0; +static size_t usb_string_cache_insert_pos = 0; + +static int usb_string_cache_grow() +{ + struct usb_string_cache_entry *new_cache; + size_t allocSize; + size_t new_cache_size; + + new_cache_size = usb_string_cache_size + 8; + allocSize = sizeof(struct usb_string_cache_entry) * new_cache_size; + new_cache = (struct usb_string_cache_entry *)realloc(usb_string_cache, allocSize); + if (!new_cache) + return -1; + + usb_string_cache = new_cache; + usb_string_cache_size = new_cache_size; + + return 0; +} + +static void usb_string_cache_destroy() +{ + size_t i; + for (i = 0; i < usb_string_cache_insert_pos; i++) { + free(usb_string_cache[i].vendor); + free(usb_string_cache[i].product); + } + free(usb_string_cache); + + usb_string_cache = NULL; + usb_string_cache_size = 0; + usb_string_cache_insert_pos = 0; +} + +static struct usb_string_cache_entry *usb_string_cache_insert() +{ + struct usb_string_cache_entry *new_entry = NULL; + if (usb_string_cache_insert_pos >= usb_string_cache_size) { + if (usb_string_cache_grow() < 0) + return NULL; + } + new_entry = &usb_string_cache[usb_string_cache_insert_pos]; + usb_string_cache_insert_pos++; + return new_entry; +} + +static const struct usb_string_cache_entry *usb_string_cache_find(struct libusb_device_descriptor *desc, struct libusb_device_handle *handle) +{ + struct usb_string_cache_entry *entry = NULL; + size_t i; + + /* Search for existing string cache entry */ + for (i = 0; i < usb_string_cache_insert_pos; i++) { + entry = &usb_string_cache[i]; + if (entry->vid != desc->idVendor) + continue; + if (entry->pid != desc->idProduct) + continue; + return entry; + } + + /* Not found, create one. */ + entry = usb_string_cache_insert(); + if (!entry) + return NULL; + + entry->vid = desc->idVendor; + entry->pid = desc->idProduct; + if (desc->iManufacturer > 0) + entry->vendor = get_usb_string(handle, desc->iManufacturer); + else + entry->vendor = NULL; + if (desc->iProduct > 0) + entry->product = get_usb_string(handle, desc->iProduct); + else + entry->product = NULL; + + return entry; +} + static char *make_path(libusb_device *dev, int interface_number) { char str[64]; @@ -471,6 +596,8 @@ int HID_API_EXPORT hid_init(void) int HID_API_EXPORT hid_exit(void) { + usb_string_cache_destroy(); + if (usb_context) { libusb_exit(usb_context); usb_context = NULL; @@ -504,7 +631,9 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de 0x15e4, /* Numark */ 0x162e, /* Joytech */ 0x1689, /* Razer Onza */ + 0x1949, /* Lab126, Inc. */ 0x1bad, /* Harmonix */ + 0x20d6, /* PowerA */ 0x24c6, /* PowerA */ }; @@ -524,17 +653,18 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc) { - static const int XB1_IFACE_SUBCLASS = 71; - static const int XB1_IFACE_PROTOCOL = 208; - static const int SUPPORTED_VENDORS[] = { - 0x045e, /* Microsoft */ - 0x0738, /* Mad Catz */ - 0x0e6f, /* PDP */ - 0x0f0d, /* Hori */ - 0x1532, /* Razer Wildcat */ - 0x24c6, /* PowerA */ - 0x2e24, /* Hyperkin */ - }; + static const int XB1_IFACE_SUBCLASS = 71; + static const int XB1_IFACE_PROTOCOL = 208; + static const int SUPPORTED_VENDORS[] = { + 0x045e, /* Microsoft */ + 0x0738, /* Mad Catz */ + 0x0e6f, /* PDP */ + 0x0f0d, /* Hori */ + 0x1532, /* Razer Wildcat */ + 0x20d6, /* PowerA */ + 0x24c6, /* PowerA */ + 0x2e24, /* Hyperkin */ + }; if (intf_desc->bInterfaceNumber == 0 && intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && @@ -612,6 +742,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, if (res >= 0) { struct hid_device_info *tmp; + const struct usb_string_cache_entry *string_cache; /* VID/PID match. Create the record. */ tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info)); @@ -633,12 +764,24 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, get_usb_string(handle, desc.iSerialNumber); /* Manufacturer and Product strings */ - if (desc.iManufacturer > 0) - cur_dev->manufacturer_string = - get_usb_string(handle, desc.iManufacturer); - if (desc.iProduct > 0) - cur_dev->product_string = - get_usb_string(handle, desc.iProduct); + if (dev_vid && dev_pid) { + string_cache = usb_string_cache_find(&desc, handle); + if (string_cache) { + if (string_cache->vendor) { + cur_dev->manufacturer_string = wcsdup(string_cache->vendor); + } + if (string_cache->product) { + cur_dev->product_string = wcsdup(string_cache->product); + } + } + } else { + if (desc.iManufacturer > 0) + cur_dev->manufacturer_string = + get_usb_string(handle, desc.iManufacturer); + if (desc.iProduct > 0) + cur_dev->product_string = + get_usb_string(handle, desc.iProduct); + } #ifdef INVASIVE_GET_USAGE { @@ -825,13 +968,9 @@ static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer) } else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { dev->shutdown_thread = 1; - dev->cancelled = 1; - return; } else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) { dev->shutdown_thread = 1; - dev->cancelled = 1; - return; } else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) { //LOG("Timeout (normal)\n"); @@ -840,12 +979,17 @@ static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer) LOG("Unknown transfer code: %d\n", transfer->status); } + if (dev->shutdown_thread) { + dev->transfer_loop_finished = 1; + return; + } + /* Re-submit the transfer object. */ res = libusb_submit_transfer(transfer); if (res != 0) { LOG("Unable to submit URB. libusb error code: %d\n", res); dev->shutdown_thread = 1; - dev->cancelled = 1; + dev->transfer_loop_finished = 1; } } @@ -888,6 +1032,7 @@ static int read_thread(void *param) res != LIBUSB_ERROR_TIMEOUT && res != LIBUSB_ERROR_OVERFLOW && res != LIBUSB_ERROR_INTERRUPTED) { + dev->shutdown_thread = 1; break; } } @@ -897,8 +1042,8 @@ static int read_thread(void *param) if no transfers are pending, but that's OK. */ libusb_cancel_transfer(dev->transfer); - while (!dev->cancelled) - libusb_handle_events_completed(usb_context, &dev->cancelled); + while (!dev->transfer_loop_finished) + libusb_handle_events_completed(usb_context, &dev->transfer_loop_finished); /* Now that the read thread is stopping, Wake any threads which are waiting on data (in hid_read_timeout()). Do this under a mutex to @@ -920,35 +1065,46 @@ static int read_thread(void *param) return 0; } -static void init_xboxone(libusb_device_handle *device_handle, struct libusb_config_descriptor *conf_desc) +static void init_xboxone(libusb_device_handle *device_handle, unsigned short idVendor, unsigned short idProduct, struct libusb_config_descriptor *conf_desc) { - static const int XB1_IFACE_SUBCLASS = 71; - static const int XB1_IFACE_PROTOCOL = 208; + static const int VENDOR_MICROSOFT = 0x045e; + static const int XB1_IFACE_SUBCLASS = 71; + static const int XB1_IFACE_PROTOCOL = 208; int j, k, res; for (j = 0; j < conf_desc->bNumInterfaces; j++) { const struct libusb_interface *intf = &conf_desc->interface[j]; for (k = 0; k < intf->num_altsetting; k++) { - const struct libusb_interface_descriptor *intf_desc; - intf_desc = &intf->altsetting[k]; - - if (intf_desc->bInterfaceNumber != 0 && - intf_desc->bAlternateSetting == 0 && - intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && + const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k]; + if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && intf_desc->bInterfaceSubClass == XB1_IFACE_SUBCLASS && intf_desc->bInterfaceProtocol == XB1_IFACE_PROTOCOL) { - res = libusb_claim_interface(device_handle, intf_desc->bInterfaceNumber); - if (res < 0) { - LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res); - continue; + int bSetAlternateSetting = 0; + + /* Newer Microsoft Xbox One controllers have a high speed alternate setting */ + if (idVendor == VENDOR_MICROSOFT && + intf_desc->bInterfaceNumber == 0 && intf_desc->bAlternateSetting == 1) { + bSetAlternateSetting = 1; + } else if (intf_desc->bInterfaceNumber != 0 && intf_desc->bAlternateSetting == 0) { + bSetAlternateSetting = 1; } - res = libusb_set_interface_alt_setting(device_handle, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting); - if (res < 0) { - LOG("xbox init: can't set alt setting %d: %d\n", intf_desc->bInterfaceNumber, res); - } + if (bSetAlternateSetting) { + res = libusb_claim_interface(device_handle, intf_desc->bInterfaceNumber); + if (res < 0) { + LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res); + continue; + } - libusb_release_interface(device_handle, intf_desc->bInterfaceNumber); + LOG("Setting alternate setting for VID/PID 0x%x/0x%x interface %d to %d\n", idVendor, idProduct, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting); + + res = libusb_set_interface_alt_setting(device_handle, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting); + if (res < 0) { + LOG("xbox init: can't set alt setting %d: %d\n", intf_desc->bInterfaceNumber, res); + } + + libusb_release_interface(device_handle, intf_desc->bInterfaceNumber); + } } } } @@ -1030,7 +1186,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) /* Initialize XBox One controllers */ if (is_xboxone(desc.idVendor, intf_desc)) { - init_xboxone(dev->device_handle, conf_desc); + init_xboxone(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc); } /* Store off the string descriptor indexes */ @@ -1173,21 +1329,21 @@ static void cleanup_mutex(void *param) } #endif - int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) { - int bytes_read = -1; - #if 0 int transferred; int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000); LOG("transferred: %d\n", transferred); return transferred; #endif + int bytes_read; SDL_LockMutex(dev->mutex); /* TODO: pthread_cleanup SDL? */ + bytes_read = -1; + /* There's an input report queued up. Return it. */ if (dev->input_reports) { /* Return the first one */ @@ -1620,5 +1776,3 @@ uint16_t get_usb_code_for_current_locale(void) #ifdef NAMESPACE } #endif - -#endif /* SDL_JOYSTICK_HIDAPI */ diff --git a/Engine/lib/sdl/src/hidapi/linux/hid.c b/Engine/lib/sdl/src/hidapi/linux/hid.c index 19a0d9669..6a0ae9fed 100644 --- a/Engine/lib/sdl/src/hidapi/linux/hid.c +++ b/Engine/lib/sdl/src/hidapi/linux/hid.c @@ -22,8 +22,6 @@ ********************************************************/ #include "../../SDL_internal.h" -#ifdef SDL_JOYSTICK_HIDAPI - #ifndef _GNU_SOURCE #define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */ #endif @@ -50,7 +48,7 @@ #include #include -#include "hidapi.h" +#include "../hidapi/hidapi.h" #ifdef NAMESPACE namespace NAMESPACE @@ -217,7 +215,7 @@ static int uses_numbered_reports(__u8 *report_descriptor, __u32 size) { * strings pointed to by serial_number_utf8 and product_name_utf8 after use. */ static int -parse_uevent_info(const char *uevent, int *bus_type, +parse_uevent_info(const char *uevent, unsigned *bus_type, unsigned short *vendor_id, unsigned short *product_id, char **serial_number_utf8, char **product_name_utf8) { @@ -300,7 +298,7 @@ static int is_BLE(hid_device *dev) if (hid_dev) { unsigned short dev_vid = 0; unsigned short dev_pid = 0; - int bus_type = 0; + unsigned bus_type = 0; char *serial_number_utf8 = NULL; char *product_name_utf8 = NULL; @@ -338,8 +336,8 @@ static int get_device_string(hid_device *dev, enum device_string_id key, wchar_t struct udev_device *udev_dev, *parent, *hid_dev; struct stat s; int ret = -1; - char *serial_number_utf8 = NULL; - char *product_name_utf8 = NULL; + char *serial_number_utf8 = NULL; + char *product_name_utf8 = NULL; char *tmp; /* Create the udev object */ @@ -365,7 +363,7 @@ static int get_device_string(hid_device *dev, enum device_string_id key, wchar_t if (hid_dev) { unsigned short dev_vid; unsigned short dev_pid; - int bus_type; + unsigned bus_type; size_t retm; ret = parse_uevent_info( @@ -433,8 +431,8 @@ static int get_device_string(hid_device *dev, enum device_string_id key, wchar_t } end: - free(serial_number_utf8); - free(product_name_utf8); + free(serial_number_utf8); + free(product_name_utf8); udev_device_unref(udev_dev); /* parent and hid_dev don't need to be (and can't be) unref'd. @@ -503,7 +501,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short dev_pid; char *serial_number_utf8 = NULL; char *product_name_utf8 = NULL; - int bus_type; + unsigned bus_type; int result; /* Get the filename of the /sys entry for the device @@ -716,7 +714,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) dev = new_hid_device(); /* OPEN HERE */ - dev->device_handle = open(path, O_RDWR); + dev->device_handle = open(path, O_RDWR | O_CLOEXEC); /* If we have a good handle, return it. */ if (dev->device_handle >= 0) { @@ -828,34 +826,47 @@ int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) return 0; /* Success */ } - int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) { + static const int MAX_RETRIES = 50; + int retry; int res; - res = ioctl(dev->device_handle, HIDIOCSFEATURE(length), data); - if (res < 0) - perror("ioctl (SFEATURE)"); + for (retry = 0; retry < MAX_RETRIES; ++retry) { + res = ioctl(dev->device_handle, HIDIOCSFEATURE(length), data); + if (res < 0 && errno == EPIPE) { + /* Try again... */ + continue; + } + if (res < 0) + perror("ioctl (SFEATURE)"); + break; + } return res; } int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) { int res; + unsigned char report = data[0]; - /* It looks like HIDIOCGFEATURE() on Bluetooth LE devices doesn't return the report number */ - if (dev->needs_ble_hack) { - data[1] = data[0]; - ++data; - --length; - } res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data); if (res < 0) perror("ioctl (GFEATURE)"); - else if (dev->needs_ble_hack) - ++res; - + else if (dev->needs_ble_hack) { + /* Versions of BlueZ before 5.56 don't include the report in the data, + * and versions of BlueZ >= 5.56 include 2 copies of the report. + * We'll fix it so that there is a single copy of the report in both cases + */ + if (data[0] == report && data[1] == report) { + memmove(&data[0], &data[1], res); + } else if (data[0] != report) { + memmove(&data[1], &data[0], res); + data[0] = report; + ++res; + } + } return res; } @@ -886,6 +897,10 @@ int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *s int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) { + (void)dev; + (void)string_index; + (void)string; + (void)maxlen; return -1; } @@ -898,5 +913,3 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) #ifdef NAMESPACE } #endif - -#endif /* SDL_JOYSTICK_HIDAPI */ diff --git a/Engine/lib/sdl/src/hidapi/linux/hid.cpp b/Engine/lib/sdl/src/hidapi/linux/hid.cpp deleted file mode 100644 index 841f34fb4..000000000 --- a/Engine/lib/sdl/src/hidapi/linux/hid.cpp +++ /dev/null @@ -1,333 +0,0 @@ -//=================== Copyright Valve Corporation, All rights reserved. ======= -// -// Purpose: A wrapper around both the libusb and hidraw versions of HIDAPI -// -// The libusb version doesn't support Bluetooth, but not all Linux -// distributions allow access to /dev/hidraw* -// -// This merges the two, at a small performance cost, until distributions -// have granted access to /dev/hidraw* -// -//============================================================================= - -#define NAMESPACE HIDRAW -#include "../hidapi/hidapi.h" -#undef NAMESPACE -#undef HIDAPI_H__ - -#define NAMESPACE HIDUSB -#include "../hidapi/hidapi.h" -#undef NAMESPACE -#undef HIDAPI_H__ - -#include "../hidapi/hidapi.h" - -#include "../../../public/tier1/utlvector.h" -#include "../../../public/tier1/utlhashmap.h" - - -template -void CopyHIDDeviceInfo( T *pSrc, struct hid_device_info *pDst ) -{ - pDst->path = pSrc->path ? strdup( pSrc->path ) : NULL; - pDst->vendor_id = pSrc->vendor_id; - pDst->product_id = pSrc->product_id; - pDst->serial_number = pSrc->serial_number ? wcsdup( pSrc->serial_number ) : NULL; - pDst->release_number = pSrc->release_number; - pDst->manufacturer_string = pSrc->manufacturer_string ? wcsdup( pSrc->manufacturer_string ) : NULL; - pDst->product_string = pSrc->product_string ? wcsdup( pSrc->product_string ) : NULL; - pDst->usage_page = pSrc->usage_page; - pDst->usage = pSrc->usage; - pDst->interface_number = pSrc->interface_number; - pDst->next = NULL; -} - -extern "C" -{ - -enum EHIDAPIType -{ - k_EHIDAPIUnknown, - k_EHIDAPIRAW, - k_EHIDAPIUSB -}; - -static CUtlHashMap s_hashDeviceToAPI; - -static EHIDAPIType GetAPIForDevice( hid_device *pDevice ) -{ - int iIndex = s_hashDeviceToAPI.Find( (uintptr_t)pDevice ); - if ( iIndex != -1 ) - { - return s_hashDeviceToAPI[ iIndex ]; - } - return k_EHIDAPIUnknown; -} - -struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) -{ - struct HIDUSB::hid_device_info *usb_devs = HIDUSB::hid_enumerate( vendor_id, product_id ); - struct HIDUSB::hid_device_info *usb_dev; - struct HIDRAW::hid_device_info *raw_devs = HIDRAW::hid_enumerate( vendor_id, product_id ); - struct HIDRAW::hid_device_info *raw_dev; - struct hid_device_info *devs = NULL, *last = NULL, *new_dev; - - for ( usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next ) - { - bool bFound = false; - for ( raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next ) - { - if ( usb_dev->vendor_id == raw_dev->vendor_id && usb_dev->product_id == raw_dev->product_id ) - { - bFound = true; - break; - } - } - -//printf("%s USB device VID/PID 0x%.4x/0x%.4x, %ls %ls\n", bFound ? "Found matching" : "Added new", usb_dev->vendor_id, usb_dev->product_id, usb_dev->manufacturer_string, usb_dev->product_string ); - - if ( !bFound ) - { - new_dev = new struct hid_device_info; - CopyHIDDeviceInfo( usb_dev, new_dev ); - - if ( last ) - { - last->next = new_dev; - } - else - { - devs = new_dev; - } - last = new_dev; - } - } - HIDUSB::hid_free_enumeration( usb_devs ); - - for ( raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next ) - { - new_dev = new struct hid_device_info; - CopyHIDDeviceInfo( raw_dev, new_dev ); - new_dev->next = NULL; - - if ( last ) - { - last->next = new_dev; - } - else - { - devs = new_dev; - } - last = new_dev; - } - HIDRAW::hid_free_enumeration( raw_devs ); - - return devs; -} - -void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs) -{ - while ( devs ) - { - struct hid_device_info *next = devs->next; - free( devs->path ); - free( devs->serial_number ); - free( devs->manufacturer_string ); - free( devs->product_string ); - delete devs; - devs = next; - } -} - -HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) -{ - hid_device *pDevice = NULL; - if ( ( pDevice = (hid_device *)HIDRAW::hid_open( vendor_id, product_id, serial_number ) ) != NULL ) - { - s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIRAW ); - return pDevice; - } - if ( ( pDevice = (hid_device *)HIDUSB::hid_open( vendor_id, product_id, serial_number ) ) != NULL ) - { - s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIUSB ); - return pDevice; - } - return NULL; -} - -HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bExclusive) -{ - hid_device *pDevice = NULL; - if ( ( pDevice = (hid_device *)HIDRAW::hid_open_path( path, bExclusive ) ) != NULL ) - { - s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIRAW ); - return pDevice; - } - if ( ( pDevice = (hid_device *)HIDUSB::hid_open_path( path, bExclusive ) ) != NULL ) - { - s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIUSB ); - return pDevice; - } - return NULL; -} - -int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - return HIDRAW::hid_write( (HIDRAW::hid_device*)device, data, length ); - case k_EHIDAPIUSB: - return HIDUSB::hid_write( (HIDUSB::hid_device*)device, data, length ); - default: - return -1; - } -} - -int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - return HIDRAW::hid_read_timeout( (HIDRAW::hid_device*)device, data, length, milliseconds ); - case k_EHIDAPIUSB: - return HIDUSB::hid_read_timeout( (HIDUSB::hid_device*)device, data, length, milliseconds ); - default: - return -1; - } -} - -int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - return HIDRAW::hid_read( (HIDRAW::hid_device*)device, data, length ); - case k_EHIDAPIUSB: - return HIDUSB::hid_read( (HIDUSB::hid_device*)device, data, length ); - default: - return -1; - } -} - -int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - return HIDRAW::hid_set_nonblocking( (HIDRAW::hid_device*)device, nonblock ); - case k_EHIDAPIUSB: - return HIDUSB::hid_set_nonblocking( (HIDUSB::hid_device*)device, nonblock ); - default: - return -1; - } -} - -int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - return HIDRAW::hid_send_feature_report( (HIDRAW::hid_device*)device, data, length ); - case k_EHIDAPIUSB: - return HIDUSB::hid_send_feature_report( (HIDUSB::hid_device*)device, data, length ); - default: - return -1; - } -} - -int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - return HIDRAW::hid_get_feature_report( (HIDRAW::hid_device*)device, data, length ); - case k_EHIDAPIUSB: - return HIDUSB::hid_get_feature_report( (HIDUSB::hid_device*)device, data, length ); - default: - return -1; - } -} - -void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - HIDRAW::hid_close( (HIDRAW::hid_device*)device ); - break; - case k_EHIDAPIUSB: - HIDUSB::hid_close( (HIDUSB::hid_device*)device ); - break; - default: - break; - } - s_hashDeviceToAPI.Remove( (uintptr_t)device ); -} - -int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - return HIDRAW::hid_get_manufacturer_string( (HIDRAW::hid_device*)device, string, maxlen ); - case k_EHIDAPIUSB: - return HIDUSB::hid_get_manufacturer_string( (HIDUSB::hid_device*)device, string, maxlen ); - default: - return -1; - } -} - -int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - return HIDRAW::hid_get_product_string( (HIDRAW::hid_device*)device, string, maxlen ); - case k_EHIDAPIUSB: - return HIDUSB::hid_get_product_string( (HIDUSB::hid_device*)device, string, maxlen ); - default: - return -1; - } -} - -int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - return HIDRAW::hid_get_serial_number_string( (HIDRAW::hid_device*)device, string, maxlen ); - case k_EHIDAPIUSB: - return HIDUSB::hid_get_serial_number_string( (HIDUSB::hid_device*)device, string, maxlen ); - default: - return -1; - } -} - -int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - return HIDRAW::hid_get_indexed_string( (HIDRAW::hid_device*)device, string_index, string, maxlen ); - case k_EHIDAPIUSB: - return HIDUSB::hid_get_indexed_string( (HIDUSB::hid_device*)device, string_index, string, maxlen ); - default: - return -1; - } -} - -HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device) -{ - switch ( GetAPIForDevice( device ) ) - { - case k_EHIDAPIRAW: - return HIDRAW::hid_error( (HIDRAW::hid_device*)device ); - case k_EHIDAPIUSB: - return HIDUSB::hid_error( (HIDUSB::hid_device*)device ); - default: - return NULL; - } -} - -} diff --git a/Engine/lib/sdl/src/hidapi/mac/hid.c b/Engine/lib/sdl/src/hidapi/mac/hid.c index 70a2fb0d3..a9a85b1f7 100644 --- a/Engine/lib/sdl/src/hidapi/mac/hid.c +++ b/Engine/lib/sdl/src/hidapi/mac/hid.c @@ -21,8 +21,6 @@ ********************************************************/ #include "../../SDL_internal.h" -#ifdef SDL_JOYSTICK_HIDAPI - /* See Apple Technical Note TN2187 for details on IOHidManager. */ #include @@ -33,7 +31,9 @@ #include #include -#include "hidapi.h" +#include "../hidapi/hidapi.h" + +#define VALVE_USB_VID 0x28DE /* Barrier implementation because Mac OSX doesn't have pthread_barrier. It also doesn't have clock_gettime(). So much for POSIX and SUSv2. @@ -251,12 +251,15 @@ static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t if (!len) return 0; - + + if (CFGetTypeID(prop) != CFStringGetTypeID()) + return 0; + str = (CFStringRef)IOHIDDeviceGetProperty(device, prop); buf[0] = 0; - if (str) { + if (str && CFGetTypeID(str) == CFStringGetTypeID()) { len --; CFIndex str_len = CFStringGetLength(str); @@ -288,11 +291,14 @@ static int get_string_property_utf8(IOHIDDeviceRef device, CFStringRef prop, cha if (!len) return 0; + if (CFGetTypeID(prop) != CFStringGetTypeID()) + return 0; + str = (CFStringRef)IOHIDDeviceGetProperty(device, prop); buf[0] = 0; - if (str) { + if (str && CFGetTypeID(str) == CFStringGetTypeID()) { len--; CFIndex str_len = CFStringGetLength(str); @@ -392,20 +398,86 @@ static void hid_device_removal_callback(void *context, IOReturn result, } } +static CFDictionaryRef +create_usage_match(const UInt32 page, const UInt32 usage, int *okay) +{ + CFDictionaryRef retval = NULL; + CFNumberRef pageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page); + CFNumberRef usageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); + const void *keys[2] = { (void *) CFSTR(kIOHIDDeviceUsagePageKey), (void *) CFSTR(kIOHIDDeviceUsageKey) }; + const void *vals[2] = { (void *) pageNumRef, (void *) usageNumRef }; + + if (pageNumRef && usageNumRef) { + retval = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + } + + if (pageNumRef) { + CFRelease(pageNumRef); + } + if (usageNumRef) { + CFRelease(usageNumRef); + } + + if (!retval) { + *okay = 0; + } + + return retval; +} + +static CFDictionaryRef +create_vendor_match(const UInt32 vendor, int *okay) +{ + CFDictionaryRef retval = NULL; + CFNumberRef vidNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendor); + const void *keys[1] = { (void *) CFSTR(kIOHIDVendorIDKey) }; + const void *vals[1] = { (void *) vidNumRef }; + + if (vidNumRef) { + retval = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFRelease(vidNumRef); + } + + if (!retval) { + *okay = 0; + } + + return retval; +} + /* Initialize the IOHIDManager. Return 0 for success and -1 for failure. */ static int init_hid_manager(void) { + int okay = 1; + const void *vals[] = { + (void *) create_usage_match(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick, &okay), + (void *) create_usage_match(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad, &okay), + (void *) create_usage_match(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController, &okay), + (void *) create_vendor_match(VALVE_USB_VID, &okay), + }; + const size_t numElements = SDL_arraysize(vals); + CFArrayRef matchingArray = okay ? CFArrayCreate(kCFAllocatorDefault, vals, numElements, &kCFTypeArrayCallBacks) : NULL; + size_t i; + + for (i = 0; i < numElements; i++) { + if (vals[i]) { + CFRelease((CFTypeRef) vals[i]); + } + } /* Initialize all the HID Manager Objects */ hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (hid_mgr) { - IOHIDManagerSetDeviceMatching(hid_mgr, NULL); + IOHIDManagerSetDeviceMatchingMultiple(hid_mgr, matchingArray); IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerRegisterDeviceRemovalCallback(hid_mgr, hid_device_removal_callback, NULL); - return 0; } - return -1; + if (matchingArray != NULL) { + CFRelease(matchingArray); + } + + return hid_mgr ? 0 : -1; } /* Initialize the IOHIDManager if necessary. This is the public function, and @@ -482,6 +554,17 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, continue; } +#if 0 // Prefer direct HID support as that has extended functionality +#if defined(SDL_JOYSTICK_MFI) + // We want to prefer Game Controller support where available, + // as Apple will likely be requiring that for supported devices. + extern SDL_bool IOS_SupportedHIDDevice(IOHIDDeviceRef device); + if (IOS_SupportedHIDDevice(dev)) { + continue; + } +#endif +#endif + dev_vid = get_vendor_id(dev); dev_pid = get_product_id(dev); @@ -1173,5 +1256,3 @@ int main(void) return 0; } #endif - -#endif /* SDL_JOYSTICK_HIDAPI */ diff --git a/Engine/lib/sdl/src/hidapi/windows/hid.c b/Engine/lib/sdl/src/hidapi/windows/hid.c index 3965a281b..f0a30c7d1 100644 --- a/Engine/lib/sdl/src/hidapi/windows/hid.c +++ b/Engine/lib/sdl/src/hidapi/windows/hid.c @@ -21,10 +21,12 @@ ********************************************************/ #include "../../SDL_internal.h" -#ifdef SDL_JOYSTICK_HIDAPI - #include +#ifndef _WIN32_WINNT_WIN8 +#define _WIN32_WINNT_WIN8 0x0602 +#endif + #if 0 /* can cause redefinition errors on some toolchains */ #ifdef __MINGW32__ #include @@ -51,7 +53,6 @@ typedef LONG NTSTATUS; #define memset SDL_memset #define strcmp SDL_strcmp #define strlen SDL_strlen -#define strncpy SDL_strlcpy #define strstr SDL_strstr #define strtol SDL_strtol #define wcscmp SDL_wcscmp @@ -93,8 +94,8 @@ extern "C" { } /* extern "C" */ #endif -#include -#include +/*#include */ +/*#include */ #include "../hidapi/hidapi.h" @@ -103,8 +104,8 @@ extern "C" { #define MIN(x,y) ((x) < (y)? (x): (y)) #ifdef _MSC_VER - /* Thanks Microsoft, but I know how to use strncpy(). */ - #pragma warning(disable:4996) + /* Yes, we have some unreferenced formal parameters */ + #pragma warning(disable:4100) #endif #ifdef __cplusplus @@ -176,8 +177,29 @@ struct hid_device_ { char *read_buf; OVERLAPPED ol; OVERLAPPED write_ol; + BOOL use_hid_write_output_report; }; +static BOOL +IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL ), + VER_MINORVERSION, VER_GREATER_EQUAL ), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL ); + + memset(&osvi, 0, sizeof(osvi)); + osvi.dwOSVersionInfoSize = sizeof( osvi ); + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} + static hid_device *new_hid_device() { hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device)); @@ -242,7 +264,7 @@ static void register_error(hid_device *device, const char *op) #ifndef HIDAPI_USE_DDK static int lookup_functions() { - lib_handle = LoadLibraryA("hid.dll"); + lib_handle = LoadLibrary(TEXT("hid.dll")); if (lib_handle) { #define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1; RESOLVE(HidD_GetAttributes); @@ -321,6 +343,7 @@ int hid_blacklist(unsigned short vendor_id, unsigned short product_id) { 0x1532, 0x0109 }, /* Razer Lycosa Gaming keyboard */ { 0x1532, 0x010B }, /* Razer Arctosa Gaming keyboard */ { 0x045E, 0x0822 }, /* Microsoft Precision Mouse */ + { 0x0D8C, 0x0014 }, /* Sharkoon Skiller SGH2 headset */ /* Turns into an Android controller when enumerated... */ { 0x0738, 0x2217 } /* SPEEDLINK COMPETITION PRO */ @@ -523,8 +546,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor if (str) { len = strlen(str); cur_dev->path = (char*) calloc(len+1, sizeof(char)); - strncpy(cur_dev->path, str, len+1); - cur_dev->path[len] = '\0'; + memcpy(cur_dev->path, str, len+1); } else cur_dev->path = NULL; @@ -692,6 +714,11 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx dev->input_report_length = caps.InputReportByteLength; HidD_FreePreparsedData(pp_data); + /* On Windows 7, we need to use hid_write_output_report() over Bluetooth */ + if (dev->output_report_length > 512) { + dev->use_hid_write_output_report = !IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN8 ), LOBYTE( _WIN32_WINNT_WIN8 ), 0 ); + } + dev->read_buf = (char*) malloc(dev->input_report_length); return dev; @@ -717,17 +744,12 @@ static int hid_write_timeout(hid_device *dev, const unsigned char *data, size_t { DWORD bytes_written; BOOL res; - size_t stashed_length = length; unsigned char *buf; -#if 1 - /* If the application is writing to the device, it knows how much data to write. - * This matches the behavior on other platforms. It's also important when writing - * to Sony game controllers over Bluetooth, where there's a CRC at the end which - * must not be tampered with. - */ - buf = (unsigned char *) data; -#else + if (dev->use_hid_write_output_report) { + return hid_write_output_report(dev, data, length); + } + /* Make sure the right number of bytes are passed to WriteFile. Windows expects the number of bytes which are in the _longest_ report (plus one for the report number) bytes even if the data is a report @@ -745,42 +767,35 @@ static int hid_write_timeout(hid_device *dev, const unsigned char *data, size_t memset(buf + length, 0, dev->output_report_length - length); length = dev->output_report_length; } -#endif - if (length > 512) - { - return hid_write_output_report( dev, data, stashed_length ); - } - else - { - res = WriteFile( dev->device_handle, buf, ( DWORD ) length, NULL, &dev->write_ol ); - if (!res) { - if (GetLastError() != ERROR_IO_PENDING) { - /* WriteFile() failed. Return error. */ - register_error(dev, "WriteFile"); - bytes_written = (DWORD) -1; - goto end_of_function; - } - } - /* Wait here until the write is done. This makes - hid_write() synchronous. */ - res = WaitForSingleObject(dev->write_ol.hEvent, milliseconds); - if (res != WAIT_OBJECT_0) - { - // There was a Timeout. - bytes_written = (DWORD) -1; - register_error(dev, "WriteFile/WaitForSingleObject Timeout"); - goto end_of_function; - } - - res = GetOverlappedResult(dev->device_handle, &dev->write_ol, &bytes_written, FALSE/*F=don't_wait*/); - if (!res) { - /* The Write operation failed. */ + res = WriteFile( dev->device_handle, buf, ( DWORD ) length, NULL, &dev->write_ol ); + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* WriteFile() failed. Return error. */ register_error(dev, "WriteFile"); bytes_written = (DWORD) -1; goto end_of_function; } } + + /* Wait here until the write is done. This makes hid_write() synchronous. */ + res = WaitForSingleObject(dev->write_ol.hEvent, milliseconds); + if (res != WAIT_OBJECT_0) + { + // There was a Timeout. + bytes_written = (DWORD) -1; + register_error(dev, "WriteFile/WaitForSingleObject Timeout"); + goto end_of_function; + } + + res = GetOverlappedResult(dev->device_handle, &dev->write_ol, &bytes_written, FALSE/*F=don't_wait*/); + if (!res) { + /* The Write operation failed. */ + register_error(dev, "WriteFile"); + bytes_written = (DWORD) -1; + goto end_of_function; + } + end_of_function: if (buf != data) free(buf); @@ -820,20 +835,19 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char } } - if (milliseconds >= 0) { - /* See if there is any data yet. */ - res = WaitForSingleObject(ev, milliseconds); - if (res != WAIT_OBJECT_0) { - /* There was no data this time. Return zero bytes available, - but leave the Overlapped I/O running. */ - return 0; - } + /* See if there is any data yet. */ + res = WaitForSingleObject(ev, milliseconds >= 0 ? milliseconds : INFINITE); + if (res != WAIT_OBJECT_0) { + /* There was no data this time. Return zero bytes available, + but leave the Overlapped I/O running. */ + return 0; } - /* Either WaitForSingleObject() told us that ReadFile has completed, or - we are in non-blocking mode. Get the number of bytes read. The actual - data has been copied to the data[] array which was passed to ReadFile(). */ - res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/); + /* Get the number of bytes read. The actual data has been copied to the data[] + array which was passed to ReadFile(). We must not wait here because we've + already waited on our event above, and since it's auto-reset, it will have + been reset back to unsignalled by now. */ + res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, FALSE/*don't wait*/); /* Set pending back to false, even if GetOverlappedResult() returned error. */ dev->read_pending = FALSE; @@ -932,9 +946,23 @@ int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev) { + typedef BOOL (WINAPI *CancelIoEx_t)(HANDLE hFile, LPOVERLAPPED lpOverlapped); + CancelIoEx_t CancelIoExFunc = (CancelIoEx_t)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "CancelIoEx"); + if (!dev) return; - CancelIo(dev->device_handle); + + if (CancelIoExFunc) { + CancelIoExFunc(dev->device_handle, NULL); + } else { + /* Windows XP, this will only cancel I/O on the current thread */ + CancelIo(dev->device_handle); + } + if (dev->read_pending) { + DWORD bytes_read = 0; + + GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/); + } free_hid_device(dev); } @@ -1064,5 +1092,3 @@ int __cdecl main(int argc, char* argv[]) #ifdef __cplusplus } /* extern "C" */ #endif - -#endif /* SDL_JOYSTICK_HIDAPI */ diff --git a/Engine/lib/sdl/src/joystick/SDL_gamecontroller.c b/Engine/lib/sdl/src/joystick/SDL_gamecontroller.c index a6674505a..e27922a6d 100644 --- a/Engine/lib/sdl/src/joystick/SDL_gamecontroller.c +++ b/Engine/lib/sdl/src/joystick/SDL_gamecontroller.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -470,6 +470,10 @@ static int SDLCALL SDL_GameControllerEventWatcher(void *userdata, SDL_Event * ev */ static ControllerMapping_t *SDL_CreateMappingForAndroidController(SDL_JoystickGUID guid) { + const int face_button_mask = ((1 << SDL_CONTROLLER_BUTTON_A) | + (1 << SDL_CONTROLLER_BUTTON_B) | + (1 << SDL_CONTROLLER_BUTTON_X) | + (1 << SDL_CONTROLLER_BUTTON_Y)); SDL_bool existing; char mapping_string[1024]; int button_mask; @@ -481,6 +485,10 @@ static ControllerMapping_t *SDL_CreateMappingForAndroidController(SDL_JoystickGU /* Accelerometer, shouldn't have a game controller mapping */ return NULL; } + if (!(button_mask & face_button_mask)) { + /* We don't know what buttons or axes are supported, don't make up a mapping */ + return NULL; + } SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string)); @@ -574,21 +582,16 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL); - if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER) { + if ((vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER) || + (vendor == USB_VENDOR_SHENZHEN && product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER)) { /* GameCube driver has 12 buttons and 6 axes */ SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3,start:b8,x:b2,y:b3,", sizeof(mapping_string)); } else { /* All other controllers have the standard set of 19 buttons and 6 axes */ - if (!SDL_IsJoystickNintendoSwitchPro(vendor, product) || - SDL_GetHintBoolean(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, SDL_TRUE)) { - SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string)); - } else { - /* Nintendo Switch Pro Controller with swapped face buttons to match Xbox Controller physical layout */ - SDL_strlcat(mapping_string, "a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,", sizeof(mapping_string)); - } + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string)); - if (SDL_IsJoystickXboxOneSeriesX(vendor, product)) { - /* XBox One Series X Controllers have a share button under the guide button */ + if (SDL_IsJoystickXboxSeriesX(vendor, product)) { + /* XBox Series X Controllers have a share button under the guide button */ SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); } else if (SDL_IsJoystickXboxOneElite(vendor, product)) { /* XBox One Elite Controllers have 4 back paddle buttons */ @@ -604,13 +607,31 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI break; case SDL_CONTROLLER_TYPE_PS5: /* PS5 controllers have a microphone button and an additional touchpad button */ - SDL_strlcat(mapping_string, "misc1:b15,touchpad:b16", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "touchpad:b15,misc1:b16", sizeof(mapping_string)); break; case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: /* Nintendo Switch Pro controllers have a screenshot button */ SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); + /* Joy-Cons have extra buttons in the same place as paddles */ + if (SDL_IsJoystickNintendoSwitchJoyConLeft(vendor, product)) { + SDL_strlcat(mapping_string, "paddle2:b17,paddle4:b19,", sizeof(mapping_string)); + } else if (SDL_IsJoystickNintendoSwitchJoyConRight(vendor, product)) { + SDL_strlcat(mapping_string, "paddle1:b16,paddle3:b18,", sizeof(mapping_string)); + } + break; + case SDL_CONTROLLER_TYPE_AMAZON_LUNA: + /* Amazon Luna Controller has a mic button under the guide button */ + SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); + break; + case SDL_CONTROLLER_TYPE_GOOGLE_STADIA: + /* The Google Stadia controller has a share button and a Google Assistant button */ + SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); break; default: + if (vendor == 0 && product == 0) { + /* This is a Bluetooth Nintendo Switch Pro controller */ + SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); + } break; } } @@ -635,6 +656,25 @@ static ControllerMapping_t *SDL_CreateMappingForRAWINPUTController(SDL_JoystickG &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); } +/* + * Helper function to guess at a mapping for WGI controllers + */ +static ControllerMapping_t *SDL_CreateMappingForWGIController(SDL_JoystickGUID guid) +{ + SDL_bool existing; + char mapping_string[1024]; + + if (guid.data[15] != SDL_JOYSTICK_TYPE_GAMECONTROLLER) { + return NULL; + } + + SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:b10,dpdown:b12,dpleft:b13,dpright:b11,leftx:a1,lefty:a0~,rightx:a3,righty:a2~,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string)); + + return SDL_PrivateAddMappingForGUID(guid, mapping_string, + &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); +} + /* * Helper function to scan the mappings database for a controller with the specified GUID */ @@ -667,6 +707,9 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG if (!mapping && SDL_IsJoystickRAWINPUT(guid)) { mapping = SDL_CreateMappingForRAWINPUTController(guid); } + if (!mapping && SDL_IsJoystickWGI(guid)) { + mapping = SDL_CreateMappingForWGIController(guid); + } } return mapping; } @@ -817,7 +860,7 @@ static void SDL_PrivateGameControllerParseElement(SDL_GameController *gamecontro invert_input = SDL_TRUE; } - if (szJoystickButton[0] == 'a' && SDL_isdigit(szJoystickButton[1])) { + if (szJoystickButton[0] == 'a' && SDL_isdigit((unsigned char) szJoystickButton[1])) { bind.inputType = SDL_CONTROLLER_BINDTYPE_AXIS; bind.input.axis.axis = SDL_atoi(&szJoystickButton[1]); if (half_axis_input == '+') { @@ -835,11 +878,11 @@ static void SDL_PrivateGameControllerParseElement(SDL_GameController *gamecontro bind.input.axis.axis_min = bind.input.axis.axis_max; bind.input.axis.axis_max = tmp; } - } else if (szJoystickButton[0] == 'b' && SDL_isdigit(szJoystickButton[1])) { + } else if (szJoystickButton[0] == 'b' && SDL_isdigit((unsigned char) szJoystickButton[1])) { bind.inputType = SDL_CONTROLLER_BINDTYPE_BUTTON; bind.input.button = SDL_atoi(&szJoystickButton[1]); - } else if (szJoystickButton[0] == 'h' && SDL_isdigit(szJoystickButton[1]) && - szJoystickButton[2] == '.' && SDL_isdigit(szJoystickButton[3])) { + } else if (szJoystickButton[0] == 'h' && SDL_isdigit((unsigned char) szJoystickButton[1]) && + szJoystickButton[2] == '.' && SDL_isdigit((unsigned char) szJoystickButton[3])) { int hat = SDL_atoi(&szJoystickButton[1]); int mask = SDL_atoi(&szJoystickButton[3]); bind.inputType = SDL_CONTROLLER_BINDTYPE_HAT; @@ -1139,15 +1182,12 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const mapping = SDL_PrivateAddMappingForGUID(guid, "none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3", &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); + } else if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box") || SDL_strstr(name, "XBOX")) { + mapping = s_pXInputMapping; } } #endif /* __LINUX__ */ - if (!mapping && name && !SDL_IsJoystickWGI(guid)) { - if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box") || SDL_strstr(name, "XBOX")) { - mapping = s_pXInputMapping; - } - } if (!mapping) { mapping = s_pDefaultMapping; } @@ -1475,6 +1515,57 @@ SDL_GameControllerNumMappings(void) return num_mappings; } +/* + * Create a mapping string for a mapping + */ +static char * +CreateMappingString(ControllerMapping_t *mapping, SDL_JoystickGUID guid) +{ + char *pMappingString, *pPlatformString; + char pchGUID[33]; + size_t needed; + const char *platform = SDL_GetPlatform(); + + SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID)); + + /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */ + needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1; + + if (!SDL_strstr(mapping->mapping, SDL_CONTROLLER_PLATFORM_FIELD)) { + /* add memory for ',' + platform:PLATFORM */ + if (mapping->mapping[SDL_strlen(mapping->mapping) - 1] != ',') { + needed += 1; + } + needed += SDL_strlen(SDL_CONTROLLER_PLATFORM_FIELD) + SDL_strlen(platform); + } + + pMappingString = SDL_malloc(needed); + if (!pMappingString) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping); + + if (!SDL_strstr(mapping->mapping, SDL_CONTROLLER_PLATFORM_FIELD)) { + if (mapping->mapping[SDL_strlen(mapping->mapping) - 1] != ',') { + SDL_strlcat(pMappingString, ",", needed); + } + SDL_strlcat(pMappingString, SDL_CONTROLLER_PLATFORM_FIELD, needed); + SDL_strlcat(pMappingString, platform, needed); + } + + /* Make sure multiple platform strings haven't made their way into the mapping */ + pPlatformString = SDL_strstr(pMappingString, SDL_CONTROLLER_PLATFORM_FIELD); + if (pPlatformString) { + pPlatformString = SDL_strstr(pPlatformString + 1, SDL_CONTROLLER_PLATFORM_FIELD); + if (pPlatformString) { + *pPlatformString = '\0'; + } + } + return pMappingString; +} + /* * Get the mapping at a particular index. */ @@ -1488,20 +1579,7 @@ SDL_GameControllerMappingForIndex(int mapping_index) continue; } if (mapping_index == 0) { - char *pMappingString; - char pchGUID[33]; - size_t needed; - - SDL_JoystickGetGUIDString(mapping->guid, pchGUID, sizeof(pchGUID)); - /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */ - needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1; - pMappingString = SDL_malloc(needed); - if (!pMappingString) { - SDL_OutOfMemory(); - return NULL; - } - SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping); - return pMappingString; + return CreateMappingString(mapping, mapping->guid); } --mapping_index; } @@ -1514,22 +1592,11 @@ SDL_GameControllerMappingForIndex(int mapping_index) char * SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid) { - char *pMappingString = NULL; ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(guid, SDL_FALSE); if (mapping) { - char pchGUID[33]; - size_t needed; - SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID)); - /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */ - needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1; - pMappingString = SDL_malloc(needed); - if (!pMappingString) { - SDL_OutOfMemory(); - return NULL; - } - SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping); + return CreateMappingString(mapping, guid); } - return pMappingString; + return NULL; } /* @@ -1753,6 +1820,13 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid) } #endif +#if defined(__ANDROID__) + if (name && SDL_strcmp(name, "uinput-fpc") == 0) { + /* The Google Pixel fingerprint sensor reports itself as a joystick */ + return SDL_TRUE; + } +#endif + if (SDL_allowed_controllers.num_entries == 0 && SDL_ignored_controllers.num_entries == 0) { return SDL_FALSE; @@ -1762,11 +1836,12 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid) if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) { /* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */ + /* https://partner.steamgames.com/doc/features/steam_controller/steam_input_gamepad_emulation_bestpractices */ SDL_bool bSteamVirtualGamepad = SDL_FALSE; #if defined(__LINUX__) - bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF); + bSteamVirtualGamepad = (vendor == USB_VENDOR_VALVE && product == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD); #elif defined(__MACOSX__) - bSteamVirtualGamepad = (vendor == 0x045E && product == 0x028E && version == 1); + bSteamVirtualGamepad = (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 1); #elif defined(__WIN32__) /* We can't tell on Windows, but Steam will block others in input hooks */ bSteamVirtualGamepad = SDL_TRUE; @@ -2158,6 +2233,29 @@ SDL_bool SDL_GameControllerIsSensorEnabled(SDL_GameController *gamecontroller, S return SDL_FALSE; } +/* + * Get the data rate of a game controller sensor. + */ +float +SDL_GameControllerGetSensorDataRate(SDL_GameController *gamecontroller, SDL_SensorType type) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + int i; + + if (!joystick) { + return 0.0f; + } + + for (i = 0; i < joystick->nsensors; ++i) { + SDL_JoystickSensorInfo *sensor = &joystick->sensors[i]; + + if (sensor->type == type) { + return sensor->rate; + } + } + return 0.0f; +} + /* * Get the current state of a game controller sensor. */ @@ -2383,12 +2481,30 @@ SDL_GameControllerHasLED(SDL_GameController *gamecontroller) return SDL_JoystickHasLED(SDL_GameControllerGetJoystick(gamecontroller)); } +SDL_bool +SDL_GameControllerHasRumble(SDL_GameController *gamecontroller) +{ + return SDL_JoystickHasRumble(SDL_GameControllerGetJoystick(gamecontroller)); +} + +SDL_bool +SDL_GameControllerHasRumbleTriggers(SDL_GameController *gamecontroller) +{ + return SDL_JoystickHasRumbleTriggers(SDL_GameControllerGetJoystick(gamecontroller)); +} + int SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 green, Uint8 blue) { return SDL_JoystickSetLED(SDL_GameControllerGetJoystick(gamecontroller), red, green, blue); } +int +SDL_GameControllerSendEffect(SDL_GameController *gamecontroller, const void *data, int size) +{ + return SDL_JoystickSendEffect(SDL_GameControllerGetJoystick(gamecontroller), data, size); +} + void SDL_GameControllerClose(SDL_GameController *gamecontroller) { @@ -2605,4 +2721,26 @@ SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick) } } +const char * +SDL_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button) +{ +#if defined(SDL_JOYSTICK_MFI) + const char *IOS_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button); + return IOS_GameControllerGetAppleSFSymbolsNameForButton(gamecontroller, button); +#else + return NULL; +#endif +} + +const char * +SDL_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis) +{ +#if defined(SDL_JOYSTICK_MFI) + const char *IOS_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); + return IOS_GameControllerGetAppleSFSymbolsNameForAxis(gamecontroller, axis); +#else + return NULL; +#endif +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h b/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h index e032bdede..2aa9ca6e8 100644 --- a/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h +++ b/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,7 @@ The easiest way to generate a new mapping is to start Steam in Big Picture mode, configure your joystick and then look in config/config.vdf in your Steam installation directory for the "SDL_GamepadBind" entry. - + Alternatively, you can use the app located in test/controllermap */ static const char *s_ControllerMappings [] = @@ -35,9 +35,14 @@ static const char *s_ControllerMappings [] = "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", #endif #if SDL_JOYSTICK_WGI + "03000000491900001904000000007700,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", + "03000000d11800000094000000007700,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "030000007e0500000920000000007701,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "030000007e0500000920000000007701,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000004c050000c405000000007701,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000e60c000000007700,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "0300000032150000000a000000007703,Razer Atrox Arcade Stick,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b11,dpup:b10,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,x:b2,y:b3,", + "03000000de280000ff11000000007701,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:b12,dpleft:b13,dpright:b11,dpup:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a4,leftx:a1,lefty:a0~,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a2~,start:b7,x:b2,y:b3,", #endif #if SDL_JOYSTICK_DINPUT "03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,", @@ -95,6 +100,7 @@ static const char *s_ControllerMappings [] = "030000006f0e00001901000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006f0e00001a01000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000d62000001d57000000000000,Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000491900001904000000000000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", "03000000d62000002a79000000000000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,", "03000000d6200000e557000000000000,Batarang,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -127,7 +133,9 @@ static const char *s_ControllerMappings [] = "030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,", "78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,", - "03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,", + "03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,", + "03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,", + "03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000300f00000b01000000000000,GGE909 Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", "03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", @@ -146,6 +154,7 @@ static const char *s_ControllerMappings [] = "03000000f0250000c383000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000f0250000c483000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000f0250000c283000000000000,Gioteck,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", + "03000000d11800000094000000000000,Google Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", "03000000632500002605000000000000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "030000000d0f00008400000000000000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f00008500000000000000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -178,6 +187,7 @@ static const char *s_ControllerMappings [] = "030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */ + "030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000380700006382000000000000,MLG Gamepad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", @@ -208,6 +218,7 @@ static const char *s_ControllerMappings [] = "030000006b140000010c000000000000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,", "03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,", + "030000005509000000b4000000000000,NVIDIA Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000004b120000014d000000000000,NYKO AIRFLO EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,", "03000000790000004318000000000000,Nintendo GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "03000000790000004318000000000000,Nintendo GameCube Controller,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", @@ -238,7 +249,7 @@ static const char *s_ControllerMappings [] = "030000003807000056a8000000000000,PS3 RF pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000100000008200000000000000,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,", "030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", @@ -256,6 +267,12 @@ static const char *s_ControllerMappings [] = "030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,", "030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,", "030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000050b00005819000000000000,ROG Chakram Core,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b0000181a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b00001a1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b00001c1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", "03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", @@ -297,7 +314,7 @@ static const char *s_ControllerMappings [] = "030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,", "030000008f0e00000800000000000000,SpeedLink Strike FX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000c01100000591000000000000,Speedlink Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", - "03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "03000000de280000ff11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000110100003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,", "03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", @@ -317,7 +334,6 @@ static const char *s_ControllerMappings [] = "03000000d90400000200000000000000,TwinShock PS2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", "03000000300f00000701000000000000,USB 4-Axis 12-Button Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", "03000000341a00002308000000000000,USB Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", - "030000005509000000b4000000000000,USB Gamepad,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,", "030000006b1400000203000000000000,USB Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "03000000790000000a00000000000000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,", "03000000f0250000c183000000000000,USB Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -375,6 +391,8 @@ static const char *s_ControllerMappings [] = "03000000a00500003232000008010000,8BitDo Zero Gamepad,a:b1,b:b2,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "03000000a00500003232000009010000,8BitDo Zero Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "03000000a00500003232000009010000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", + "03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,", "03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", @@ -383,10 +401,13 @@ static const char *s_ControllerMappings [] = "03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,", "030000000d0f00008400000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f00008500000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "03000000790000000600000000000000,G-Shark GP-702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,", + "03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", + "03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,", + "03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", + "03000000d11800000094000000010000,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -445,8 +466,8 @@ static const char *s_ControllerMappings [] = "03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,", "030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "03000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", + "050000004e696d6275732b0000000000,SteelSeries Nimbus+,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,", "03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,", "03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,", "03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,", @@ -468,6 +489,7 @@ static const char *s_ControllerMappings [] = "030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", "030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", "030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", + "030000005e040000200b000011050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", @@ -480,6 +502,7 @@ static const char *s_ControllerMappings [] = "03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,", #endif #if defined(__LINUX__) + "xinput,*,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", @@ -524,6 +547,7 @@ static const char *s_ControllerMappings [] = "05000000a00500003232000001000000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "05000000a00500003232000008010000,8BitDo Zero Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "05000000a00500003232000008010000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000031000011010000,8Bitdo Receiver,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", "03000000c82d00001290000011010000,8Bitdo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "03000000c82d00001290000011010000,8Bitdo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "05000000c82d00006228000000010000,8Bitdo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", @@ -535,9 +559,17 @@ static const char *s_ControllerMappings [] = "030000006f0e00001302000000010000,Afterglow,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", + "05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "03000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,", + "05000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,", + "03000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,", + "05000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,", + "030000005e0400008e02000047010000,Atari Xbox 360 Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:,lefty:,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:,righty:,start:b9,x:b0,y:b3,", "03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,", "03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,", "03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", @@ -545,6 +577,8 @@ static const char *s_ControllerMappings [] = "03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,", "03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,", "030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "0500000047532067616d657061640000,GS Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,", @@ -555,6 +589,7 @@ static const char *s_ControllerMappings [] = "030000008f0e00000800000010010000,Gasia Co. Ltd PS(R) Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000d11800000094000011010000,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "03000000280400000140000000010000,Gravis Gamepad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,", "030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,", @@ -563,6 +598,7 @@ static const char *s_ControllerMappings [] = "030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "030000000d0f00005001000009040000,HORI Fighting Commander OCTA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000000d0f00008400000011010000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f00008500000010010000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000000d0f0000d800000072056800,HORI Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", @@ -580,6 +616,7 @@ static const char *s_ControllerMappings [] = "03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000d80400008200000003000000,IMS PCU#0 Gamepad Interface,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,", "03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,", + "05000000491900000204000000000000,Ipega PG-9087S,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,", "03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,", "03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", @@ -619,6 +656,7 @@ static const char *s_ControllerMappings [] = "030000005e040000d102000001010000,Microsoft X-Box One pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,", "030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,", + "030000005e0400008902000020010000,Microsoft Xbox Controller S,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,", "05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "030000006b140000010c000010010000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,", @@ -665,9 +703,13 @@ static const char *s_ControllerMappings [] = "050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,", "050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,", + "030000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,", "050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,", "030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,", + "03000000c62400003a54000001010000,PowerA XBox One Controller,a:b0,b:b1,back:b6,dpdown:h0.7,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,", "030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", @@ -705,7 +747,6 @@ static const char *s_ControllerMappings [] = "03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,", "030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", "03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", "03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", @@ -742,16 +783,17 @@ static const char *s_ControllerMappings [] = "030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e040000a102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", - "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", "030000005e040000a102000014010000,Xbox 360 Wireless Receiver (XBOX),a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "050000005e040000050b000003090000,Xbox One Elite Series 2,a:b0,b:b1,back:b121,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "030000005e040000ea02000000000000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e040000ea02000001030000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "050000005e040000130b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,", "03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,", "03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", @@ -797,6 +839,7 @@ static const char *s_ControllerMappings [] = "05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b0,b:b1,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000b404000011240000dfff3f00,Flydigi Vader 2,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "05000000d6020000e5890000dfff3f00,GPD XD Plus,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", "0500000031366332860c44aadfff0f00,GS Gamepad,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "05000000bc20000000550000ffff3f00,GameSir G3w,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", @@ -807,6 +850,7 @@ static const char *s_ControllerMappings [] = "050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b17,y:b2,sdk<=:28,", /* Extremely slow in Bluetooth mode on Android */ "050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "030000004c050000cc09000000006800,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "050000004c050000c405000000783f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000004c050000c4050000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,", "050000004c050000c4050000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000004c050000cc090000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,", @@ -817,10 +861,15 @@ static const char *s_ControllerMappings [] = "050000003215000007070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000003215000000090000bf7f3f00,Razer Serval,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,", "050000004f0400000ed00000fffe3f00,ThrustMaster eSwap PRO Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "050000005e0400008e02000000783f00,Xbox 360 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "050000005e040000000b000000783f00,Xbox One Elite 2 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", + "050000005e040000e002000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "050000005e040000ea02000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000005e040000fd020000ff7f3f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", - "050000005e040000130b0000ffff3f00,Xbox One Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000005e040000e00200000ffe3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b17,y:b2,", "050000005e040000fd020000ffff3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "050000005e040000120b000000783f00,Xbox Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", + "050000005e040000130b0000ffff3f00,Xbox Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", /* The DPAD doesn't seem to work on this controller on Android TV? */ "050000001727000044310000ffff3f00,XiaoMi Game Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", "0500000083050000602000000ffe0000,iBuffalo SNES Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", @@ -833,10 +882,16 @@ static const char *s_ControllerMappings [] = "05000000ac05000001000000ff076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", "05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,", "050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000004c050000cc090000df870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", "050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", "050000004c050000cc090000ff870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,", + "050000004c050000e60c0000df870000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,touchpad:b10,x:b2,y:b3,", + "050000004c050000e60c0000ff870000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,", "05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,", + "050000005e040000050b0000df070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b10,paddle2:b12,paddle3:b11,paddle4:b13,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", "050000005e040000050b0000ff070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", + "050000005e040000130b0000df870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000005e040000130b0000ff870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", "050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", "050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", #endif @@ -846,6 +901,13 @@ static const char *s_ControllerMappings [] = #if defined(SDL_JOYSTICK_EMSCRIPTEN) "default,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", #endif +#if defined(SDL_JOYSTICK_VITA) + "50535669746120436f6e74726f6c6c65,PSVita Controller,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftstick:b14,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,", +#endif +#if defined(SDL_JOYSTICK_PSP) + "505350206275696c74696e206a6f7970,PSP builtin joypad,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,", +#endif + "hidapi,*,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", NULL }; diff --git a/Engine/lib/sdl/src/joystick/SDL_joystick.c b/Engine/lib/sdl/src/joystick/SDL_joystick.c index 32eb7c248..3f3482b7d 100644 --- a/Engine/lib/sdl/src/joystick/SDL_joystick.c +++ b/Engine/lib/sdl/src/joystick/SDL_joystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -56,11 +56,14 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = { #ifdef SDL_JOYSTICK_RAWINPUT /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */ &SDL_RAWINPUT_JoystickDriver, #endif +#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) /* Before WGI driver, as WGI wants to check if this driver is handling things */ + &SDL_WINDOWS_JoystickDriver, +#endif #if defined(SDL_JOYSTICK_WGI) &SDL_WGI_JoystickDriver, #endif -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) - &SDL_WINDOWS_JoystickDriver, +#if defined(SDL_JOYSTICK_WINMM) + &SDL_WINMM_JoystickDriver, #endif #ifdef SDL_JOYSTICK_LINUX &SDL_LINUX_JoystickDriver, @@ -83,9 +86,18 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = { #ifdef SDL_JOYSTICK_USBHID /* !!! FIXME: "USBHID" is a generic name, and doubly-confusing with HIDAPI next to it. This is the *BSD interface, rename this. */ &SDL_BSD_JoystickDriver, #endif +#ifdef SDL_JOYSTICK_OS2 + &SDL_OS2_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_PSP + &SDL_PSP_JoystickDriver, +#endif #ifdef SDL_JOYSTICK_VIRTUAL &SDL_VIRTUAL_JoystickDriver, #endif +#ifdef SDL_JOYSTICK_VITA + &SDL_VITA_JoystickDriver, +#endif #if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED) &SDL_DUMMY_JoystickDriver #endif @@ -160,9 +172,6 @@ SDL_SetJoystickIDForPlayerIndex(int player_index, SDL_JoystickID instance_id) int device_index; int existing_player_index; - if (player_index < 0) { - return SDL_FALSE; - } if (player_index >= SDL_joystick_player_count) { SDL_JoystickID *new_players = (SDL_JoystickID *)SDL_realloc(SDL_joystick_players, (player_index + 1)*sizeof(*SDL_joystick_players)); if (!new_players) { @@ -184,7 +193,9 @@ SDL_SetJoystickIDForPlayerIndex(int player_index, SDL_JoystickID instance_id) SDL_joystick_players[existing_player_index] = -1; } - SDL_joystick_players[player_index] = instance_id; + if (player_index >= 0) { + SDL_joystick_players[player_index] = instance_id; + } /* Update the driver with the new index */ device_index = SDL_JoystickGetDeviceIndexFromInstanceID(instance_id); @@ -332,6 +343,9 @@ SDL_JoystickGetDevicePlayerIndex(int device_index) static SDL_bool SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick) { +#ifdef __WINRT__ + return SDL_TRUE; +#else static Uint32 zero_centered_joysticks[] = { MAKE_VIDPID(0x0e8f, 0x3013), /* HuiJia SNES USB adapter */ MAKE_VIDPID(0x05a0, 0x3232), /* 8Bitdo Zero Gamepad */ @@ -341,7 +355,7 @@ SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick) Uint32 id = MAKE_VIDPID(SDL_JoystickGetVendor(joystick), SDL_JoystickGetProduct(joystick)); -/*printf("JOYSTICK '%s' VID/PID 0x%.4x/0x%.4x AXES: %d\n", joystick->name, vendor, product, joystick->naxes);*/ + /*printf("JOYSTICK '%s' VID/PID 0x%.4x/0x%.4x AXES: %d\n", joystick->name, vendor, product, joystick->naxes);*/ if (joystick->naxes == 2) { /* Assume D-pad or thumbstick style axes are centered at 0 */ @@ -354,6 +368,7 @@ SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick) } } return SDL_FALSE; +#endif /* __WINRT__ */ } /* @@ -405,6 +420,7 @@ SDL_JoystickOpen(int device_index) joystick->instance_id = instance_id; joystick->attached = SDL_TRUE; joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; + joystick->led_expiration = SDL_GetTicks(); if (driver->Open(joystick, device_index) < 0) { SDL_free(joystick); @@ -747,7 +763,7 @@ SDL_JoystickGetButton(SDL_Joystick *joystick, int button) SDL_bool SDL_JoystickGetAttached(SDL_Joystick *joystick) { - if (!SDL_PrivateJoystickValid(joystick)) { + if (!joystick) { return SDL_FALSE; } @@ -870,17 +886,18 @@ SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble); } - /* Save the rumble value regardless of success, so we don't spam the driver */ - joystick->low_frequency_rumble = low_frequency_rumble; - joystick->high_frequency_rumble = high_frequency_rumble; + if (result == 0) { + joystick->low_frequency_rumble = low_frequency_rumble; + joystick->high_frequency_rumble = high_frequency_rumble; - if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) { - joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); - if (!joystick->rumble_expiration) { - joystick->rumble_expiration = 1; + if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) { + joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); + if (!joystick->rumble_expiration) { + joystick->rumble_expiration = 1; + } + } else { + joystick->rumble_expiration = 0; } - } else { - joystick->rumble_expiration = 0; } SDL_UnlockJoysticks(); @@ -904,17 +921,18 @@ SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri result = joystick->driver->RumbleTriggers(joystick, left_rumble, right_rumble); } - /* Save the rumble value regardless of success, so we don't spam the driver */ - joystick->left_trigger_rumble = left_rumble; - joystick->right_trigger_rumble = right_rumble; + if (result == 0) { + joystick->left_trigger_rumble = left_rumble; + joystick->right_trigger_rumble = right_rumble; - if ((left_rumble || right_rumble) && duration_ms) { - joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); - if (!joystick->trigger_rumble_expiration) { - joystick->trigger_rumble_expiration = 1; + if ((left_rumble || right_rumble) && duration_ms) { + joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); + if (!joystick->trigger_rumble_expiration) { + joystick->trigger_rumble_expiration = 1; + } + } else { + joystick->trigger_rumble_expiration = 0; } - } else { - joystick->trigger_rumble_expiration = 0; } SDL_UnlockJoysticks(); @@ -932,7 +950,43 @@ SDL_JoystickHasLED(SDL_Joystick *joystick) SDL_LockJoysticks(); - result = joystick->driver->HasLED(joystick); + result = (joystick->driver->GetCapabilities(joystick) & SDL_JOYCAP_LED) != 0; + + SDL_UnlockJoysticks(); + + return result; +} + +SDL_bool +SDL_JoystickHasRumble(SDL_Joystick *joystick) +{ + SDL_bool result; + + if (!SDL_PrivateJoystickValid(joystick)) { + return SDL_FALSE; + } + + SDL_LockJoysticks(); + + result = (joystick->driver->GetCapabilities(joystick) & SDL_JOYCAP_RUMBLE) != 0; + + SDL_UnlockJoysticks(); + + return result; +} + +SDL_bool +SDL_JoystickHasRumbleTriggers(SDL_Joystick *joystick) +{ + SDL_bool result; + + if (!SDL_PrivateJoystickValid(joystick)) { + return SDL_FALSE; + } + + SDL_LockJoysticks(); + + result = (joystick->driver->GetCapabilities(joystick) & SDL_JOYCAP_RUMBLE_TRIGGERS) != 0; SDL_UnlockJoysticks(); @@ -943,6 +997,7 @@ int SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) { int result; + SDL_bool isfreshvalue; if (!SDL_PrivateJoystickValid(joystick)) { return -1; @@ -950,13 +1005,17 @@ SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) SDL_LockJoysticks(); - if (red == joystick->led_red && - green == joystick->led_green && - blue == joystick->led_blue) { + isfreshvalue = red != joystick->led_red || + green != joystick->led_green || + blue != joystick->led_blue; + + if ( isfreshvalue || SDL_TICKS_PASSED( SDL_GetTicks(), joystick->led_expiration ) ) { + result = joystick->driver->SetLED(joystick, red, green, blue); + joystick->led_expiration = SDL_GetTicks() + SDL_LED_MIN_REPEAT_MS; + } + else { /* Avoid spamming the driver */ result = 0; - } else { - result = joystick->driver->SetLED(joystick, red, green, blue); } /* Save the LED value regardless of success, so we don't spam the driver */ @@ -969,6 +1028,24 @@ SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) return result; } +int +SDL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + int result; + + if (!SDL_PrivateJoystickValid(joystick)) { + return -1; + } + + SDL_LockJoysticks(); + + result = joystick->driver->SendEffect(joystick, data, size); + + SDL_UnlockJoysticks(); + + return result; +} + /* * Close a joystick previously opened with SDL_JoystickOpen() */ @@ -1060,8 +1137,8 @@ SDL_JoystickQuit(void) SDL_JoystickClose(SDL_joysticks); } - /* Quit the joystick setup */ - for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) { + /* Quit drivers in reverse order to avoid breaking dependencies between drivers */ + for (i = SDL_arraysize(SDL_joystick_drivers) - 1; i >= 0; --i) { SDL_joystick_drivers[i]->Quit(); } @@ -1127,7 +1204,7 @@ void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers) } } -void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type) +void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type, float rate) { int nsensors = joystick->nsensors + 1; SDL_JoystickSensorInfo *sensors = (SDL_JoystickSensorInfo *)SDL_realloc(joystick->sensors, (nsensors * sizeof(SDL_JoystickSensorInfo))); @@ -1136,6 +1213,7 @@ void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type) SDL_zerop(sensor); sensor->type = type; + sensor->rate = rate; joystick->nsensors = nsensors; joystick->sensors = sensors; @@ -1247,7 +1325,6 @@ SDL_PrivateJoystickForceRecentering(SDL_Joystick *joystick) SDL_PrivateJoystickTouchpad(joystick, i, j, SDL_RELEASED, 0.0f, 0.0f, 0.0f); } } - } void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance) @@ -1309,7 +1386,7 @@ SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value) info->value = value; info->zero = value; info->has_initial_value = SDL_TRUE; - } else if (value == info->value) { + } else if (value == info->value && !info->sending_initial_value) { return 0; } else { info->has_second_value = SDL_TRUE; @@ -1321,15 +1398,17 @@ SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value) return 0; } info->sent_initial_value = SDL_TRUE; - info->value = ~value; /* Just so we pass the check above */ + info->sending_initial_value = SDL_TRUE; SDL_PrivateJoystickAxis(joystick, axis, info->initial_value); + info->sending_initial_value = SDL_FALSE; } /* We ignore events if we don't have keyboard focus, except for centering * events. */ if (SDL_PrivateJoystickShouldIgnoreEvent()) { - if ((value > info->zero && value >= info->value) || + if (info->sending_initial_value || + (value > info->zero && value >= info->value) || (value < info->zero && value <= info->value)) { return 0; } @@ -1636,7 +1715,7 @@ PrefixMatch(const char *a, const char *b) { int matchlen = 0; while (*a && *b) { - if (SDL_tolower(*a++) == SDL_tolower(*b++)) { + if (SDL_tolower((unsigned char) *a++) == SDL_tolower((unsigned char) *b++)) { ++matchlen; } else { break; @@ -1656,6 +1735,7 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c { "Performance Designed Products", "PDP" }, { "HORI CO.,LTD.", "HORI" }, { "HORI CO.,LTD", "HORI" }, + { "Unknown ", "" }, }; const char *custom_name; char *name; @@ -1716,27 +1796,30 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c } } - /* Remove duplicate manufacturer or product in the name */ - for (i = 1; i < (len - 1); ++i) { - int matchlen = PrefixMatch(name, &name[i]); - if (matchlen > 0 && name[matchlen-1] == ' ') { - SDL_memmove(name, name+matchlen, len-matchlen+1); - len -= matchlen; - break; - } else if (matchlen > 0 && name[matchlen] == ' ') { - SDL_memmove(name, name+matchlen+1, len-matchlen); - len -= (matchlen + 1); - break; - } - } - /* Perform any manufacturer replacements */ for (i = 0; i < SDL_arraysize(replacements); ++i) { size_t prefixlen = SDL_strlen(replacements[i].prefix); if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) { size_t replacementlen = SDL_strlen(replacements[i].replacement); - SDL_memcpy(name, replacements[i].replacement, replacementlen); - SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen+1)); + if (replacementlen <= prefixlen) { + SDL_memcpy(name, replacements[i].replacement, replacementlen); + SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen)+1); + len -= (prefixlen - replacementlen); + } else { + /* FIXME: Need to handle the expand case by reallocating the string */ + } + break; + } + } + + /* Remove duplicate manufacturer or product in the name */ + for (i = 1; i < (len - 1); ++i) { + int matchlen = PrefixMatch(name, &name[i]); + if (matchlen > 0 && name[matchlen-1] == ' ') { + SDL_memmove(name, name+matchlen, len-matchlen+1); + break; + } else if (matchlen > 0 && name[matchlen] == ' ') { + SDL_memmove(name, name+matchlen+1, len-matchlen); break; } } @@ -1801,11 +1884,13 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc 0x12ab, /* Unknown */ 0x1430, /* RedOctane */ 0x146b, /* BigBen */ - 0x1532, /* Razer Sabertooth */ + 0x1532, /* Razer */ 0x15e4, /* Numark */ 0x162e, /* Joytech */ 0x1689, /* Razer Onza */ + 0x1949, /* Lab126, Inc. */ 0x1bad, /* Harmonix */ + 0x20d6, /* PowerA */ 0x24c6, /* PowerA */ }; @@ -1828,7 +1913,8 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc 0x0738, /* Mad Catz */ 0x0e6f, /* PDP */ 0x0f0d, /* Hori */ - 0x1532, /* Razer Wildcat */ + 0x1532, /* Razer */ + 0x20d6, /* PowerA */ 0x24c6, /* PowerA */ 0x2e24, /* Hyperkin */ }; @@ -1860,6 +1946,19 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc } else if (vendor == 0x0001 && product == 0x0001) { type = SDL_CONTROLLER_TYPE_UNKNOWN; + } else if (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER) { + type = SDL_CONTROLLER_TYPE_XBOXONE; + + } else if ((vendor == USB_VENDOR_AMAZON && product == USB_PRODUCT_AMAZON_LUNA_CONTROLLER) || + (vendor == BLUETOOTH_VENDOR_AMAZON && product == BLUETOOTH_PRODUCT_LUNA_CONTROLLER)) { + type = SDL_CONTROLLER_TYPE_AMAZON_LUNA; + + } else if (vendor == USB_VENDOR_GOOGLE && product == USB_PRODUCT_GOOGLE_STADIA_CONTROLLER) { + type = SDL_CONTROLLER_TYPE_GOOGLE_STADIA; + + } else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) { + type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN; + } else { switch (GuessControllerType(vendor, product)) { case k_eControllerType_XBox360Controller: @@ -1881,6 +1980,10 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc case k_eControllerType_SwitchInputOnlyController: type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO; break; + case k_eControllerType_SwitchJoyConLeft: + case k_eControllerType_SwitchJoyConRight: + type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN; + break; default: type = SDL_CONTROLLER_TYPE_UNKNOWN; break; @@ -1904,11 +2007,43 @@ SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id) } SDL_bool -SDL_IsJoystickXboxOneSeriesX(Uint16 vendor_id, Uint16 product_id) +SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id) { if (vendor_id == USB_VENDOR_MICROSOFT) { - if (product_id == USB_PRODUCT_XBOX_ONE_SERIES_X || - product_id == USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH) { + if (product_id == USB_PRODUCT_XBOX_SERIES_X || + product_id == USB_PRODUCT_XBOX_SERIES_X_BLE) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_PDP) { + if (product_id == USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT || + product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE || + product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_POWERA_ALT) { + if ((product_id >= 0x2001 && product_id <= 0x201a) || + product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 || + product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +SDL_bool +SDL_IsJoystickBluetoothXboxOne(Uint16 vendor_id, Uint16 product_id) +{ + if (vendor_id == USB_VENDOR_MICROSOFT) { + if (product_id == USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLUETOOTH || + product_id == USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLE || + product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH || + product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH || + product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLE || + product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH || + product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLE || + product_id == USB_PRODUCT_XBOX_SERIES_X_BLE) { return SDL_TRUE; } } @@ -1934,7 +2069,8 @@ SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id) { EControllerType eType = GuessControllerType(vendor_id, product_id); return (eType == k_eControllerType_SwitchProController || - eType == k_eControllerType_SwitchInputOnlyController); + eType == k_eControllerType_SwitchInputOnlyController || + (vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP)); } SDL_bool @@ -1944,6 +2080,28 @@ SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id) return (eType == k_eControllerType_SwitchInputOnlyController); } +SDL_bool +SDL_IsJoystickNintendoSwitchJoyCon(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return (eType == k_eControllerType_SwitchJoyConLeft || + eType == k_eControllerType_SwitchJoyConRight); +} + +SDL_bool +SDL_IsJoystickNintendoSwitchJoyConLeft(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return (eType == k_eControllerType_SwitchJoyConLeft); +} + +SDL_bool +SDL_IsJoystickNintendoSwitchJoyConRight(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return (eType == k_eControllerType_SwitchJoyConRight); +} + SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id) { @@ -1991,12 +2149,17 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid) MAKE_VIDPID(0x046d, 0xc299), /* Logitech G25 */ MAKE_VIDPID(0x046d, 0xc29a), /* Logitech Driving Force GT */ MAKE_VIDPID(0x046d, 0xc29b), /* Logitech G27 */ - MAKE_VIDPID(0x046d, 0xc24f), /* Logitech G29 */ + MAKE_VIDPID(0x046d, 0xc24f), /* Logitech G29 (PS3) */ + MAKE_VIDPID(0x046d, 0xc260), /* Logitech G29 (PS4) */ MAKE_VIDPID(0x046d, 0xc261), /* Logitech G920 (initial mode) */ MAKE_VIDPID(0x046d, 0xc262), /* Logitech G920 (active mode) */ + MAKE_VIDPID(0x046d, 0xc26e), /* Logitech G923 */ + MAKE_VIDPID(0x046d, 0xca03), /* Logitech Momo Racing */ MAKE_VIDPID(0x044f, 0xb65d), /* Thrustmaster Wheel FFB */ MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster Wheel FFB */ MAKE_VIDPID(0x044f, 0xb677), /* Thrustmaster T150 */ + MAKE_VIDPID(0x044f, 0xb66e), /* Thrustmaster T300RS */ + MAKE_VIDPID(0x044f, 0xb65e), /* Thrustmaster T500RS */ MAKE_VIDPID(0x044f, 0xb664), /* Thrustmaster TX (initial mode) */ MAKE_VIDPID(0x044f, 0xb669), /* Thrustmaster TX (active mode) */ }; @@ -2010,11 +2173,46 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid) return SDL_FALSE; } +static SDL_bool SDL_IsJoystickProductArcadeStick(Uint32 vidpid) +{ + static Uint32 arcadestick_joysticks[] = { + MAKE_VIDPID(0x0079, 0x181a), /* Venom Arcade Stick */ + MAKE_VIDPID(0x0f0d, 0x006a), /* Real Arcade Pro 4 */ + MAKE_VIDPID(0x0079, 0x181b), /* Venom Arcade Stick */ + MAKE_VIDPID(0x0c12, 0x0ef6), /* Hitbox Arcade Stick */ + MAKE_VIDPID(0x0f0d, 0x008a), /* HORI Real Arcade Pro 4 */ + MAKE_VIDPID(0x0f0d, 0x0016), /* Hori Real Arcade Pro.EX */ + MAKE_VIDPID(0x0f0d, 0x001b), /* Hori Real Arcade Pro VX */ + MAKE_VIDPID(0x0f0d, 0x008c), /* Hori Real Arcade Pro 4 */ + MAKE_VIDPID(0x1bad, 0xf03d), /* Street Fighter IV Arcade Stick TE - Chun Li */ + MAKE_VIDPID(0x1bad, 0xf502), /* Hori Real Arcade Pro.VX SA */ + MAKE_VIDPID(0x1bad, 0xf504), /* Hori Real Arcade Pro. EX */ + MAKE_VIDPID(0x1bad, 0xf506), /* Hori Real Arcade Pro.EX Premium VLX */ + MAKE_VIDPID(0x24c6, 0x5000), /* Razer Atrox Arcade Stick */ + MAKE_VIDPID(0x24c6, 0x5501), /* Hori Real Arcade Pro VX-SA */ + MAKE_VIDPID(0x24c6, 0x550e), /* Hori Real Arcade Pro V Kai 360 */ + MAKE_VIDPID(0x0f0d, 0x0063), /* Hori Real Arcade Pro Hayabusa (USA) Xbox One */ + MAKE_VIDPID(0x0f0d, 0x0078), /* Hori Real Arcade Pro V Kai Xbox One */ + MAKE_VIDPID(0x1532, 0x0a00), /* Razer Atrox Arcade Stick */ + MAKE_VIDPID(0x0f0d, 0x00aa), /* HORI Real Arcade Pro V Hayabusa in Switch Mode */ + MAKE_VIDPID(0x20d6, 0xa715), /* PowerA Nintendo Switch Fusion Arcade Stick */ + }; + int i; + + for (i = 0; i < SDL_arraysize(arcadestick_joysticks); ++i) { + if (vidpid == arcadestick_joysticks[i]) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + static SDL_bool SDL_IsJoystickProductFlightStick(Uint32 vidpid) { static Uint32 flightstick_joysticks[] = { MAKE_VIDPID(0x044f, 0x0402), /* HOTAS Warthog Joystick */ MAKE_VIDPID(0x0738, 0x2221), /* Saitek Pro Flight X-56 Rhino Stick */ + MAKE_VIDPID(0x044f, 0xb10a), /* ThrustMaster, Inc. T.16000M Joystick */ }; int i; @@ -2089,6 +2287,10 @@ static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid) return SDL_JOYSTICK_TYPE_WHEEL; } + if (SDL_IsJoystickProductArcadeStick(vidpid)) { + return SDL_JOYSTICK_TYPE_ARCADE_STICK; + } + if (SDL_IsJoystickProductFlightStick(vidpid)) { return SDL_JOYSTICK_TYPE_FLIGHT_STICK; } @@ -2237,6 +2439,27 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid) MAKE_VIDPID(0x2516, 0x001f), /* Cooler Master Storm Mizar Mouse */ MAKE_VIDPID(0x2516, 0x0028), /* Cooler Master Storm Alcor Mouse */ + + /*****************************************************************/ + /* Additional entries */ + /*****************************************************************/ + + MAKE_VIDPID(0x04d9, 0x8008), /* OBINLB USB-HID Keyboard (Anne Pro II) */ + MAKE_VIDPID(0x04d9, 0x8009), /* OBINLB USB-HID Keyboard (Anne Pro II) */ + MAKE_VIDPID(0x04d9, 0xa292), /* OBINLB USB-HID Keyboard (Anne Pro II) */ + MAKE_VIDPID(0x04d9, 0xa293), /* OBINLB USB-HID Keyboard (Anne Pro II) */ + MAKE_VIDPID(0x1532, 0x0266), /* Razer Huntman V2 Analog, non-functional DInput device */ + MAKE_VIDPID(0x1532, 0x0282), /* Razer Huntman Mini Analog, non-functional DInput device */ + MAKE_VIDPID(0x26ce, 0x01a2), /* ASRock LED Controller */ + }; + + static Uint32 rog_chakram_list[] = { + MAKE_VIDPID(0x0b05, 0x1958), /* ROG Chakram Core Mouse */ + MAKE_VIDPID(0x0b05, 0x18e3), /* ROG Chakram (wired) Mouse */ + MAKE_VIDPID(0x0b05, 0x18e5), /* ROG Chakram (wireless) Mouse */ + MAKE_VIDPID(0x0b05, 0x1a18), /* ROG Chakram X (wired) Mouse */ + MAKE_VIDPID(0x0b05, 0x1a1a), /* ROG Chakram X (wireless) Mouse */ + MAKE_VIDPID(0x0b05, 0x1a1c), /* ROG Chakram X (Bluetooth) Mouse */ }; unsigned int i; @@ -2254,6 +2477,13 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid) return SDL_TRUE; } } + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_ROG_CHAKRAM, SDL_FALSE)) { + for (i = 0; i < SDL_arraysize(rog_chakram_list); ++i) { + if (id == rog_chakram_list[i]) { + return SDL_TRUE; + } + } + } type = SDL_GetJoystickGameControllerType(name, vendor, product, -1, 0, 0, 0); if ((type == SDL_CONTROLLER_TYPE_PS4 || type == SDL_CONTROLLER_TYPE_PS5) && SDL_IsPS4RemapperRunning()) { @@ -2442,18 +2672,18 @@ void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID) * Input : c - * Output : unsigned char *-----------------------------------------------------------------------------*/ -static unsigned char nibble(char c) +static unsigned char nibble(unsigned char c) { if ((c >= '0') && (c <= '9')) { - return (unsigned char)(c - '0'); + return (c - '0'); } if ((c >= 'A') && (c <= 'F')) { - return (unsigned char)(c - 'A' + 0x0a); + return (c - 'A' + 0x0a); } if ((c >= 'a') && (c <= 'f')) { - return (unsigned char)(c - 'a' + 0x0a); + return (c - 'a' + 0x0a); } /* received an invalid character, and no real way to return an error */ @@ -2477,7 +2707,7 @@ SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID) p = (Uint8 *)&guid; for (i = 0; (i < len) && ((p - (Uint8 *)&guid) < maxoutputbytes); i+=2, p++) { - *p = (nibble(pchGUID[i]) << 4) | nibble(pchGUID[i+1]); + *p = (nibble((unsigned char)pchGUID[i]) << 4) | nibble((unsigned char)pchGUID[i+1]); } return guid; @@ -2503,9 +2733,7 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger SDL_JoystickTouchpadInfo *touchpad_info; SDL_JoystickTouchpadFingerInfo *finger_info; int posted; -#if !SDL_EVENTS_DISABLED Uint32 event_type; -#endif if (touchpad < 0 || touchpad >= joystick->ntouchpads) { return 0; @@ -2549,7 +2777,6 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger } } -#if !SDL_EVENTS_DISABLED if (state == finger_info->state) { event_type = SDL_CONTROLLERTOUCHPADMOTION; } else if (state) { @@ -2557,7 +2784,13 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger } else { event_type = SDL_CONTROLLERTOUCHPADUP; } -#endif + + /* We ignore events if we don't have keyboard focus, except for touch release */ + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + if (event_type != SDL_CONTROLLERTOUCHPADUP) { + return 0; + } + } /* Update internal joystick state */ finger_info->state = state; @@ -2588,31 +2821,34 @@ int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, SDL_SensorType type, const int i; int posted = 0; + /* We ignore events if we don't have keyboard focus */ + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + return 0; + } + for (i = 0; i < joystick->nsensors; ++i) { SDL_JoystickSensorInfo *sensor = &joystick->sensors[i]; if (sensor->type == type) { if (sensor->enabled) { num_values = SDL_min(num_values, SDL_arraysize(sensor->data)); - if (SDL_memcmp(data, sensor->data, num_values*sizeof(*data)) != 0) { - /* Update internal sensor state */ - SDL_memcpy(sensor->data, data, num_values*sizeof(*data)); + /* Update internal sensor state */ + SDL_memcpy(sensor->data, data, num_values*sizeof(*data)); - /* Post the event, if desired */ + /* Post the event, if desired */ #if !SDL_EVENTS_DISABLED - if (SDL_GetEventState(SDL_CONTROLLERSENSORUPDATE) == SDL_ENABLE) { - SDL_Event event; - event.type = SDL_CONTROLLERSENSORUPDATE; - event.csensor.which = joystick->instance_id; - event.csensor.sensor = type; - num_values = SDL_min(num_values, SDL_arraysize(event.csensor.data)); - SDL_memset(event.csensor.data, 0, sizeof(event.csensor.data)); - SDL_memcpy(event.csensor.data, data, num_values*sizeof(*data)); - posted = SDL_PushEvent(&event) == 1; - } -#endif /* !SDL_EVENTS_DISABLED */ + if (SDL_GetEventState(SDL_CONTROLLERSENSORUPDATE) == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_CONTROLLERSENSORUPDATE; + event.csensor.which = joystick->instance_id; + event.csensor.sensor = type; + num_values = SDL_min(num_values, SDL_arraysize(event.csensor.data)); + SDL_memset(event.csensor.data, 0, sizeof(event.csensor.data)); + SDL_memcpy(event.csensor.data, data, num_values*sizeof(*data)); + posted = SDL_PushEvent(&event) == 1; } +#endif /* !SDL_EVENTS_DISABLED */ } break; } diff --git a/Engine/lib/sdl/src/joystick/SDL_joystick_c.h b/Engine/lib/sdl/src/joystick/SDL_joystick_c.h index de330aba0..312e11337 100644 --- a/Engine/lib/sdl/src/joystick/SDL_joystick_c.h +++ b/Engine/lib/sdl/src/joystick/SDL_joystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -65,8 +65,11 @@ extern SDL_GameControllerType SDL_GetJoystickGameControllerType(const char *name /* Function to return whether a joystick is an Xbox One Elite controller */ extern SDL_bool SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id); -/* Function to return whether a joystick is an Xbox One Series X controller */ -extern SDL_bool SDL_IsJoystickXboxOneSeriesX(Uint16 vendor_id, Uint16 product_id); +/* Function to return whether a joystick is an Xbox Series X controller */ +extern SDL_bool SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id); + +/* Function to return whether a joystick is an Xbox One controller connected via Bluetooth */ +extern SDL_bool SDL_IsJoystickBluetoothXboxOne(Uint16 vendor_id, Uint16 product_id); /* Function to return whether a joystick is a PS4 controller */ extern SDL_bool SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id); @@ -77,6 +80,9 @@ extern SDL_bool SDL_IsJoystickPS5(Uint16 vendor_id, Uint16 product_id); /* Function to return whether a joystick is a Nintendo Switch Pro controller */ extern SDL_bool SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id); extern SDL_bool SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id); +extern SDL_bool SDL_IsJoystickNintendoSwitchJoyCon(Uint16 vendor_id, Uint16 product_id); +extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConLeft(Uint16 vendor_id, Uint16 product_id); +extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConRight(Uint16 vendor_id, Uint16 product_id); /* Function to return whether a joystick is a Steam Controller */ extern SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id); @@ -110,7 +116,7 @@ extern void SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick); /* Internal event queueing functions */ extern void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers); -extern void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type); +extern void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type, float rate); extern void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance); extern void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance); extern int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, diff --git a/Engine/lib/sdl/src/joystick/SDL_sysjoystick.h b/Engine/lib/sdl/src/joystick/SDL_sysjoystick.h index 3ea7d39c1..8b8792179 100644 --- a/Engine/lib/sdl/src/joystick/SDL_sysjoystick.h +++ b/Engine/lib/sdl/src/joystick/SDL_sysjoystick.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +24,6 @@ #define SDL_sysjoystick_h_ /* This is the system specific header for the SDL joystick API */ - #include "SDL_joystick.h" #include "SDL_joystick_c.h" @@ -37,6 +36,7 @@ typedef struct _SDL_JoystickAxisInfo SDL_bool has_initial_value; /* Whether we've seen a value on the axis yet */ SDL_bool has_second_value; /* Whether we've seen a second value on the axis yet */ SDL_bool sent_initial_value; /* Whether we've sent the initial axis value */ + SDL_bool sending_initial_value; /* Whether we are sending the initial axis value */ } SDL_JoystickAxisInfo; typedef struct _SDL_JoystickTouchpadFingerInfo @@ -57,6 +57,7 @@ typedef struct _SDL_JoystickSensorInfo { SDL_SensorType type; SDL_bool enabled; + float rate; float data[3]; /* If this needs to expand, update SDL_ControllerSensorEvent */ } SDL_JoystickSensorInfo; @@ -100,6 +101,7 @@ struct _SDL_Joystick Uint8 led_red; Uint8 led_green; Uint8 led_blue; + Uint32 led_expiration; SDL_bool attached; SDL_bool is_game_controller; @@ -119,6 +121,11 @@ struct _SDL_Joystick #define SDL_HARDWARE_BUS_USB 0x03 #define SDL_HARDWARE_BUS_BLUETOOTH 0x05 +/* Joystick capability flags for GetCapabilities() */ +#define SDL_JOYCAP_LED 0x01 +#define SDL_JOYCAP_RUMBLE 0x02 +#define SDL_JOYCAP_RUMBLE_TRIGGERS 0x04 + /* Macro to combine a USB vendor ID and product ID into a single Uint32 value */ #define MAKE_VIDPID(VID, PID) (((Uint32)(VID))<<16|(PID)) @@ -162,10 +169,15 @@ typedef struct _SDL_JoystickDriver int (*Rumble)(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); int (*RumbleTriggers)(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble); + /* Capability detection */ + Uint32 (*GetCapabilities)(SDL_Joystick *joystick); + /* LED functionality */ - SDL_bool (*HasLED)(SDL_Joystick *joystick); int (*SetLED)(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); + /* General effects */ + int (*SendEffect)(SDL_Joystick *joystick, const void *data, int size); + /* Sensor functionality */ int (*SetSensorsEnabled)(SDL_Joystick *joystick, SDL_bool enabled); @@ -190,6 +202,8 @@ typedef struct _SDL_JoystickDriver /* Windows and Mac OSX has a limit of MAX_DWORD / 1000, Linux kernel has a limit of 0xFFFF */ #define SDL_MAX_RUMBLE_DURATION_MS 0xFFFF +#define SDL_LED_MIN_REPEAT_MS 5000 + /* The available joystick drivers */ extern SDL_JoystickDriver SDL_ANDROID_JoystickDriver; extern SDL_JoystickDriver SDL_BSD_JoystickDriver; @@ -204,6 +218,10 @@ extern SDL_JoystickDriver SDL_LINUX_JoystickDriver; extern SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver; extern SDL_JoystickDriver SDL_WGI_JoystickDriver; extern SDL_JoystickDriver SDL_WINDOWS_JoystickDriver; +extern SDL_JoystickDriver SDL_WINMM_JoystickDriver; +extern SDL_JoystickDriver SDL_OS2_JoystickDriver; +extern SDL_JoystickDriver SDL_PSP_JoystickDriver; +extern SDL_JoystickDriver SDL_VITA_JoystickDriver; #endif /* SDL_sysjoystick_h_ */ diff --git a/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick.c index 9b949d382..aef014d16 100644 --- a/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -103,6 +103,7 @@ keycode_to_SDL(int keycode) case AKEYCODE_BUTTON_THUMBR: button = SDL_CONTROLLER_BUTTON_RIGHTSTICK; break; + case AKEYCODE_MENU: case AKEYCODE_BUTTON_START: button = SDL_CONTROLLER_BUTTON_START; break; @@ -581,7 +582,7 @@ ANDROID_JoystickGetDeviceInstanceID(int device_index) } static int -ANDROID_JoystickOpen(SDL_Joystick * joystick, int device_index) +ANDROID_JoystickOpen(SDL_Joystick *joystick, int device_index) { SDL_joylist_item *item = JoystickByDevIndex(device_index); @@ -605,25 +606,31 @@ ANDROID_JoystickOpen(SDL_Joystick * joystick, int device_index) } static int -ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +ANDROID_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { return SDL_Unsupported(); } static int -ANDROID_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble) +ANDROID_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { return SDL_Unsupported(); } -static SDL_bool -ANDROID_JoystickHasLED(SDL_Joystick * joystick) +static Uint32 +ANDROID_JoystickGetCapabilities(SDL_Joystick *joystick) { - return SDL_FALSE; + return 0; } static int -ANDROID_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) +ANDROID_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int +ANDROID_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) { return SDL_Unsupported(); } @@ -635,7 +642,7 @@ ANDROID_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) } static void -ANDROID_JoystickUpdate(SDL_Joystick * joystick) +ANDROID_JoystickUpdate(SDL_Joystick *joystick) { SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata; @@ -664,7 +671,7 @@ ANDROID_JoystickUpdate(SDL_Joystick * joystick) } static void -ANDROID_JoystickClose(SDL_Joystick * joystick) +ANDROID_JoystickClose(SDL_Joystick *joystick) { SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata; if (item) { @@ -713,8 +720,9 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver = ANDROID_JoystickOpen, ANDROID_JoystickRumble, ANDROID_JoystickRumbleTriggers, - ANDROID_JoystickHasLED, + ANDROID_JoystickGetCapabilities, ANDROID_JoystickSetLED, + ANDROID_JoystickSendEffect, ANDROID_JoystickSetSensorsEnabled, ANDROID_JoystickUpdate, ANDROID_JoystickClose, diff --git a/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick_c.h b/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick_c.h index 92ae64acf..881c8aa41 100644 --- a/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/joystick/bsd/SDL_bsdjoystick.c b/Engine/lib/sdl/src/joystick/bsd/SDL_bsdjoystick.c index 60d779938..f8859a534 100644 --- a/Engine/lib/sdl/src/joystick/bsd/SDL_bsdjoystick.c +++ b/Engine/lib/sdl/src/joystick/bsd/SDL_bsdjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -69,7 +69,7 @@ #include #endif -#if SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H +#if SDL_HAVE_MACHINE_JOYSTICK_H #include #endif @@ -240,7 +240,7 @@ BSD_JoystickInit(void) } for (i = 0; i < MAX_JOY_JOYS; i++) { SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i); - fd = open(s, O_RDONLY); + fd = open(s, O_RDONLY | O_CLOEXEC); if (fd != -1) { joynames[numjoysticks++] = SDL_strdup(s); close(fd); @@ -357,7 +357,7 @@ BSD_JoystickOpen(SDL_Joystick *joy, int device_index) int fd; int i; - fd = open(path, O_RDONLY); + fd = open(path, O_RDONLY | O_CLOEXEC); if (fd == -1) { return SDL_SetError("%s: %s", path, strerror(errno)); } @@ -426,7 +426,7 @@ BSD_JoystickOpen(SDL_Joystick *joy, int device_index) str[i] = UGETW(usd.usd_desc.bString[i]); } str[i] = '\0'; - asprintf(&new_name, "%s @ %s", str, path); + SDL_asprintf(&new_name, "%s @ %s", str, path); if (new_name != NULL) { SDL_free(joydevnames[numjoysticks]); joydevnames[numjoysticks] = new_name; @@ -546,13 +546,13 @@ BSD_JoystickUpdate(SDL_Joystick *joy) Sint32 dpad[4] = {0, 0, 0, 0}; #endif -#if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__) || defined(__DragonFly_) +#if defined(__FREEBSD__) || SDL_HAVE_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__) || defined(__DragonFly_) struct joystick gameport; static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0; if (joy->hwdata->type == BSDJOY_JOY) { while (read(joy->hwdata->fd, &gameport, sizeof gameport) == sizeof gameport) { - if (abs(x - gameport.x) > 8) { + if (SDL_abs(x - gameport.x) > 8) { x = gameport.x; if (x < xmin) { xmin = x; @@ -569,7 +569,7 @@ BSD_JoystickUpdate(SDL_Joystick *joy) v *= 32768 / ((xmax - xmin + 1) / 2); SDL_PrivateJoystickAxis(joy, 0, v); } - if (abs(y - gameport.y) > 8) { + if (SDL_abs(y - gameport.y) > 8) { y = gameport.y; if (y < ymin) { ymin = y; @@ -591,7 +591,7 @@ BSD_JoystickUpdate(SDL_Joystick *joy) } return; } -#endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */ +#endif /* defined(__FREEBSD__) || SDL_HAVE_MACHINE_JOYSTICK_H */ rep = &joy->hwdata->inreport; @@ -777,10 +777,10 @@ BSD_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) return SDL_FALSE; } -static SDL_bool -BSD_JoystickHasLED(SDL_Joystick *joystick) +static Uint32 +BSD_JoystickGetCapabilities(SDL_Joystick *joystick) { - return SDL_FALSE; + return 0; } static int @@ -789,6 +789,12 @@ BSD_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) return SDL_Unsupported(); } +static int +BSD_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + static int BSD_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) { @@ -808,8 +814,9 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver = BSD_JoystickOpen, BSD_JoystickRumble, BSD_JoystickRumbleTriggers, - BSD_JoystickHasLED, + BSD_JoystickGetCapabilities, BSD_JoystickSetLED, + BSD_JoystickSendEffect, BSD_JoystickSetSensorsEnabled, BSD_JoystickUpdate, BSD_JoystickClose, diff --git a/Engine/lib/sdl/src/joystick/controller_type.h b/Engine/lib/sdl/src/joystick/controller_type.h index 224526fd8..26950345c 100644 --- a/Engine/lib/sdl/src/joystick/controller_type.h +++ b/Engine/lib/sdl/src/joystick/controller_type.h @@ -51,7 +51,7 @@ typedef enum k_eControllerType_SwitchJoyConLeft = 39, k_eControllerType_SwitchJoyConRight = 40, k_eControllerType_SwitchJoyConPair = 41, - k_eControllerType_SwitchInputOnlyController = 42, + k_eControllerType_SwitchInputOnlyController = 42, k_eControllerType_MobileTouch = 43, k_eControllerType_XInputSwitchController = 44, // Client-side only, used to mark Switch-compatible controllers as not supporting Switch controller protocol k_eControllerType_PS5Controller = 45, @@ -160,7 +160,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x1532, 0x1009 ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju 2 Ultimate BT { MAKE_CONTROLLER_ID( 0x1532, 0x100A ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju 2 Tournament edition BT { MAKE_CONTROLLER_ID( 0x1532, 0x1100 ), k_eControllerType_PS4Controller, NULL }, // Razer RAION Fightpad - Trackpad, no gyro, lightbar hardcoded to green - { MAKE_CONTROLLER_ID( 0x20d6, 0x792a ), k_eControllerType_PS4Controller, NULL }, // PowerA - Fusion Fight Pad + { MAKE_CONTROLLER_ID( 0x20d6, 0x792a ), k_eControllerType_PS4Controller, NULL }, // PowerA Fusion Fight Pad { MAKE_CONTROLLER_ID( 0x7545, 0x0104 ), k_eControllerType_PS4Controller, NULL }, // Armor 3 or Level Up Cobra - At least one variant has gyro { MAKE_CONTROLLER_ID( 0x9886, 0x0025 ), k_eControllerType_PS4Controller, NULL }, // Astro C40 { MAKE_CONTROLLER_ID( 0x0e6f, 0x0207 ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro Fightstick w/ Touchpad for PS4 @@ -175,18 +175,20 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x146b, 0x1103 ), k_eControllerType_PS4Controller, NULL }, // NACON Asymetrical Controller -- on windows this doesn't enumerate { MAKE_CONTROLLER_ID( 0x0f0d, 0x0123 ), k_eControllerType_PS4Controller, NULL }, // HORI Wireless Controller Light (Japan only) - only over bt- over usb is xbox and pid 0x0124 { MAKE_CONTROLLER_ID( 0x146b, 0x0d13 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution 3 + { MAKE_CONTROLLER_ID( 0x0c12, 0x0e20 ), k_eControllerType_PS4Controller, NULL }, // Brook Mars Controller - needs FW update to show up as Ps4 controller on PC. Has Gyro but touchpad is a single button. { MAKE_CONTROLLER_ID( 0x054c, 0x0ce6 ), k_eControllerType_PS5Controller, NULL }, // Sony PS5 Controller { MAKE_CONTROLLER_ID( 0x0079, 0x0006 ), k_eControllerType_UnknownNonSteamController, NULL }, // DragonRise Generic USB PCB, sometimes configured as a PC Twin Shock Controller - looks like a DS3 but the face buttons are 1-4 instead of symbols { MAKE_CONTROLLER_ID( 0x0079, 0x18d4 ), k_eControllerType_XBox360Controller, NULL }, // GPD Win 2 X-Box Controller + { MAKE_CONTROLLER_ID( 0x03eb, 0xff02 ), k_eControllerType_XBox360Controller, NULL }, // Wooting Two { MAKE_CONTROLLER_ID( 0x044f, 0xb326 ), k_eControllerType_XBox360Controller, NULL }, // Thrustmaster Gamepad GP XID { MAKE_CONTROLLER_ID( 0x045e, 0x028e ), k_eControllerType_XBox360Controller, "Xbox 360 Controller" }, // Microsoft X-Box 360 pad { MAKE_CONTROLLER_ID( 0x045e, 0x028f ), k_eControllerType_XBox360Controller, "Xbox 360 Controller" }, // Microsoft X-Box 360 pad v2 { MAKE_CONTROLLER_ID( 0x045e, 0x0291 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver (XBOX) { MAKE_CONTROLLER_ID( 0x045e, 0x02a0 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 Big Button IR - { MAKE_CONTROLLER_ID( 0x045e, 0x02a1 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 pad + { MAKE_CONTROLLER_ID( 0x045e, 0x02a1 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 Wireless Controller with XUSB driver on Windows { MAKE_CONTROLLER_ID( 0x045e, 0x02a9 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver (third party knockoff) { MAKE_CONTROLLER_ID( 0x045e, 0x0719 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver { MAKE_CONTROLLER_ID( 0x046d, 0xc21d ), k_eControllerType_XBox360Controller, NULL }, // Logitech Gamepad F310 @@ -254,6 +256,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x1689, 0xfd00 ), k_eControllerType_XBox360Controller, NULL }, // Razer Onza Tournament Edition { MAKE_CONTROLLER_ID( 0x1689, 0xfd01 ), k_eControllerType_XBox360Controller, NULL }, // Razer Onza Classic Edition { MAKE_CONTROLLER_ID( 0x1689, 0xfe00 ), k_eControllerType_XBox360Controller, NULL }, // Razer Sabertooth + { MAKE_CONTROLLER_ID( 0x1949, 0x041a ), k_eControllerType_XBox360Controller, "Amazon Luna Controller" }, // Amazon Luna Controller { MAKE_CONTROLLER_ID( 0x1bad, 0x0002 ), k_eControllerType_XBox360Controller, NULL }, // Harmonix Rock Band Guitar { MAKE_CONTROLLER_ID( 0x1bad, 0x0003 ), k_eControllerType_XBox360Controller, NULL }, // Harmonix Rock Band Drumkit { MAKE_CONTROLLER_ID( 0x1bad, 0xf016 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Xbox 360 Controller @@ -320,11 +323,17 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x045e, 0x02e3 ), k_eControllerType_XBoxOneController, "Xbox One Elite Controller" }, // Microsoft X-Box One Elite pad { MAKE_CONTROLLER_ID( 0x045e, 0x02ea ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad { MAKE_CONTROLLER_ID( 0x045e, 0x02fd ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad (Bluetooth) - { MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController, NULL }, // Microsoft X-Box One controller with the RAWINPUT driver on Windows + { MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController, NULL }, // Microsoft X-Box One controller with XBOXGIP driver on Windows { MAKE_CONTROLLER_ID( 0x045e, 0x0b00 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad + { MAKE_CONTROLLER_ID( 0x045e, 0x0b02 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (Bluetooth) { MAKE_CONTROLLER_ID( 0x045e, 0x0b05 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (Bluetooth) - { MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Elite Series X pad - { MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Elite Series X pad (Bluetooth) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b0a ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft X-Box Adaptive pad + { MAKE_CONTROLLER_ID( 0x045e, 0x0b0c ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft X-Box Adaptive pad (Bluetooth) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft X-Box Series X pad + { MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft X-Box Series X pad (BLE) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b20 ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad (BLE) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b21 ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft X-Box Adaptive pad (BLE) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b22 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (BLE) { MAKE_CONTROLLER_ID( 0x0738, 0x4a01 ), k_eControllerType_XBoxOneController, NULL }, // Mad Catz FightStick TE 2 { MAKE_CONTROLLER_ID( 0x0e6f, 0x0139 ), k_eControllerType_XBoxOneController, "PDP Xbox One Afterglow" }, // PDP Afterglow Wired Controller for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x013B ), k_eControllerType_XBoxOneController, "PDP Xbox One Face-Off Controller" }, // PDP Face-Off Gamepad for Xbox One @@ -390,6 +399,9 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0e6f, 0x02d5 ), k_eControllerType_XBoxOneController, "PDP Xbox One Red Camo" }, // PDP Wired Controller for Xbox One - Red Camo { MAKE_CONTROLLER_ID( 0x0e6f, 0x0346 ), k_eControllerType_XBoxOneController, "PDP Xbox One RC Gamepad" }, // PDP RC Gamepad for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x0446 ), k_eControllerType_XBoxOneController, "PDP Xbox One RC Gamepad" }, // PDP RC Gamepad for Xbox One + { MAKE_CONTROLLER_ID( 0x0e6f, 0x02da ), k_eControllerType_XBoxOneController, "PDP Xbox Series X Afterglow" }, // PDP Xbox Series X Afterglow + { MAKE_CONTROLLER_ID( 0x0e6f, 0x02d6 ), k_eControllerType_XBoxOneController, "Victrix Gambit Tournament Controller" }, // Victrix Gambit Tournament Controller + { MAKE_CONTROLLER_ID( 0x0e6f, 0x02d9 ), k_eControllerType_XBoxOneController, "PDP Xbox Series X Midnight Blue" }, // PDP Xbox Series X Midnight Blue { MAKE_CONTROLLER_ID( 0x0f0d, 0x0063 ), k_eControllerType_XBoxOneController, NULL }, // Hori Real Arcade Pro Hayabusa (USA) Xbox One { MAKE_CONTROLLER_ID( 0x0f0d, 0x0067 ), k_eControllerType_XBoxOneController, NULL }, // HORIPAD ONE { MAKE_CONTROLLER_ID( 0x0f0d, 0x0078 ), k_eControllerType_XBoxOneController, NULL }, // Hori Real Arcade Pro V Kai Xbox One @@ -397,9 +409,33 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x1532, 0x0a00 ), k_eControllerType_XBoxOneController, NULL }, // Razer Atrox Arcade Stick { MAKE_CONTROLLER_ID( 0x1532, 0x0a03 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wildcat { MAKE_CONTROLLER_ID( 0x1532, 0x0a14 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wolverine Ultimate + { MAKE_CONTROLLER_ID( 0x1532, 0x0a15 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wolverine Tournament Edition + { MAKE_CONTROLLER_ID( 0x20d6, 0x2001 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Black Inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x2002 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Gray/White Inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x2003 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Green Inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x2004 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Pink inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x2005 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Wired Controller Core - Black + { MAKE_CONTROLLER_ID( 0x20d6, 0x2006 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Wired Controller Core - White + { MAKE_CONTROLLER_ID( 0x20d6, 0x2009 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Red inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x200a ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Blue inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x200b ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Camo Metallic Red + { MAKE_CONTROLLER_ID( 0x20d6, 0x200c ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Camo Metallic Blue + { MAKE_CONTROLLER_ID( 0x20d6, 0x200d ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Seafoam Fade + { MAKE_CONTROLLER_ID( 0x20d6, 0x200e ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Midnight Blue + { MAKE_CONTROLLER_ID( 0x20d6, 0x200f ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Soldier Green + { MAKE_CONTROLLER_ID( 0x20d6, 0x2011 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired - Metallic Ice + { MAKE_CONTROLLER_ID( 0x20d6, 0x2012 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Cuphead EnWired Controller - Mugman + { MAKE_CONTROLLER_ID( 0x20d6, 0x2015 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Blue Hint + { MAKE_CONTROLLER_ID( 0x20d6, 0x2016 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Green Hint + { MAKE_CONTROLLER_ID( 0x20d6, 0x2017 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Cntroller - Arctic Camo + { MAKE_CONTROLLER_ID( 0x20d6, 0x2018 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Arc Lightning + { MAKE_CONTROLLER_ID( 0x20d6, 0x2019 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Royal Purple + { MAKE_CONTROLLER_ID( 0x20d6, 0x201a ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Nebula + { MAKE_CONTROLLER_ID( 0x20d6, 0x4001 ), k_eControllerType_XBoxOneController, "PowerA Fusion Pro 2 Controller" }, // PowerA Fusion Pro 2 Wired Controller (Xbox Series X style) + { MAKE_CONTROLLER_ID( 0x20d6, 0x4002 ), k_eControllerType_XBoxOneController, "PowerA Spectra Infinity Controller" }, // PowerA Spectra Infinity Wired Controller (Xbox Series X style) { MAKE_CONTROLLER_ID( 0x24c6, 0x541a ), k_eControllerType_XBoxOneController, NULL }, // PowerA Xbox One Mini Wired Controller { MAKE_CONTROLLER_ID( 0x24c6, 0x542a ), k_eControllerType_XBoxOneController, NULL }, // Xbox ONE spectra - { MAKE_CONTROLLER_ID( 0x24c6, 0x543a ), k_eControllerType_XBoxOneController, "PowerA XBox One Controller" }, // PowerA Xbox ONE liquid metal controller + { MAKE_CONTROLLER_ID( 0x24c6, 0x543a ), k_eControllerType_XBoxOneController, "PowerA Xbox One Controller" }, // PowerA Xbox ONE liquid metal controller { MAKE_CONTROLLER_ID( 0x24c6, 0x551a ), k_eControllerType_XBoxOneController, NULL }, // PowerA FUSION Pro Controller { MAKE_CONTROLLER_ID( 0x24c6, 0x561a ), k_eControllerType_XBoxOneController, NULL }, // PowerA FUSION Controller { MAKE_CONTROLLER_ID( 0x24c6, 0x581a ), k_eControllerType_XBoxOneController, NULL }, // BDA XB1 Classic Controller @@ -450,7 +486,6 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x2f24, 0x91 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x1430, 0x719 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xf0d, 0xed ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller - { MAKE_CONTROLLER_ID( 0x3eb, 0xff02 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xf0d, 0xc0 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xe6f, 0x152 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xe6f, 0x2a7 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller @@ -516,17 +551,19 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0xf0d, 0xd8 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xfff, 0x2a1 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x45e, 0x867 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller - + // Added 12-17-2020 + { MAKE_CONTROLLER_ID( 0x16d0, 0xf3f ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller + { MAKE_CONTROLLER_ID( 0x2f24, 0x8f ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller + { MAKE_CONTROLLER_ID( 0xe6f, 0xf501 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller + //{ MAKE_CONTROLLER_ID( 0x1949, 0x0402 ), /*android*/, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x05ac, 0x0001 ), k_eControllerType_AppleController, NULL }, // MFI Extended Gamepad (generic entry for iOS/tvOS) { MAKE_CONTROLLER_ID( 0x05ac, 0x0002 ), k_eControllerType_AppleController, NULL }, // MFI Standard Gamepad (generic entry for iOS/tvOS) - // We currently don't support using a pair of Switch Joy-Con's as a single - // controller and we don't want to support using them individually for the - // time being, so these should be disabled until one of the above is true - // { MAKE_CONTROLLER_ID( 0x057e, 0x2006 ), k_eControllerType_SwitchJoyConLeft, NULL }, // Nintendo Switch Joy-Con (Left) - // { MAKE_CONTROLLER_ID( 0x057e, 0x2007 ), k_eControllerType_SwitchJoyConRight, NULL }, // Nintendo Switch Joy-Con (Right) + // We now support Joy-Cons if SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS is set to "1", but they won't be combined into one controller. + { MAKE_CONTROLLER_ID( 0x057e, 0x2006 ), k_eControllerType_SwitchJoyConLeft, NULL }, // Nintendo Switch Joy-Con (Left) + { MAKE_CONTROLLER_ID( 0x057e, 0x2007 ), k_eControllerType_SwitchJoyConRight, NULL }, // Nintendo Switch Joy-Con (Right) // This same controller ID is spoofed by many 3rd-party Switch controllers. // The ones we currently know of are: @@ -544,19 +581,22 @@ static const ControllerDescription_t arrControllers[] = { #else { MAKE_CONTROLLER_ID( 0x0f0d, 0x00dc ), k_eControllerType_SwitchProController, "HORI Fighting Commander" }, #endif - { MAKE_CONTROLLER_ID( 0x0e6f, 0x0185 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Wired Fight Pad Pro for Nintendo Switch { MAKE_CONTROLLER_ID( 0x0e6f, 0x0180 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Wired Pro Controller for Nintendo Switch { MAKE_CONTROLLER_ID( 0x0e6f, 0x0181 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Deluxe Wired Pro Controller for Nintendo Switch - { MAKE_CONTROLLER_ID( 0x20d6, 0xa711 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Wired Controller Plus/PowerA Wired Controller Nintendo GameCube Style - { MAKE_CONTROLLER_ID( 0x20d6, 0xa712 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA - Fusion Fight Pad - { MAKE_CONTROLLER_ID( 0x20d6, 0xa713 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA - Super Mario Controller - { MAKE_CONTROLLER_ID( 0x0e6f, 0x0186 ), k_eControllerType_SwitchProController, NULL }, // PDP Afterglow Wireless Switch Controller - working gyro. USB doesn't work { MAKE_CONTROLLER_ID( 0x0e6f, 0x0184 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Wired Deluxe+ Audio Controller - { MAKE_CONTROLLER_ID( 0x0f0d, 0x00aa ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORI Real Arcade Pro V Hayabusa in Switch Mode + { MAKE_CONTROLLER_ID( 0x0e6f, 0x0185 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Wired Fight Pad Pro for Nintendo Switch + { MAKE_CONTROLLER_ID( 0x0e6f, 0x0186 ), k_eControllerType_SwitchProController, NULL }, // PDP Afterglow Wireless Switch Controller - working gyro. USB is for charging only. Many later "Wireless" line devices w/ gyro also use this vid/pid + { MAKE_CONTROLLER_ID( 0x0e6f, 0x0187 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Rockcandy Wired Controller { MAKE_CONTROLLER_ID( 0x0e6f, 0x0188 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Afterglow Wired Deluxe+ Audio Controller - { MAKE_CONTROLLER_ID( 0x0e6f, 0x0187 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Rockcandy Wirec Controller + { MAKE_CONTROLLER_ID( 0x0f0d, 0x00aa ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORI Real Arcade Pro V Hayabusa in Switch Mode + { MAKE_CONTROLLER_ID( 0x20d6, 0xa711 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Wired Controller Plus/PowerA Wired Controller Nintendo GameCube Style + { MAKE_CONTROLLER_ID( 0x20d6, 0xa712 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Fusion Fight Pad + { MAKE_CONTROLLER_ID( 0x20d6, 0xa713 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Super Mario Controller + { MAKE_CONTROLLER_ID( 0x20d6, 0xa714 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Spectra Controller + { MAKE_CONTROLLER_ID( 0x20d6, 0xa715 ), k_eControllerType_SwitchInputOnlyController, NULL }, // Power A Fusion Wireless Arcade Stick (USB Mode) Over BT is shows up as 057e 2009 + { MAKE_CONTROLLER_ID( 0x20d6, 0xa716 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Fusion Pro Controller - USB requires toggling switch on back of device - // Valve products - don't add to public list + // Valve products { MAKE_CONTROLLER_ID( 0x0000, 0x11fb ), k_eControllerType_MobileTouch, NULL }, // Streaming mobile touch virtual controls { MAKE_CONTROLLER_ID( 0x28de, 0x1101 ), k_eControllerType_SteamController, NULL }, // Valve Legacy Steam Controller (CHELL) { MAKE_CONTROLLER_ID( 0x28de, 0x1102 ), k_eControllerType_SteamController, NULL }, // Valve wired Steam Controller (D0G) @@ -691,11 +731,11 @@ static SDL_INLINE int GetDefaultDeadzoneSizeForControllerType( EControllerType e case k_eControllerType_AppleController: case k_eControllerType_AndroidController: case k_eControllerType_PS3Controller: + case k_eControllerType_PS5Controller: return 10000; case k_eControllerType_SteamControllerV2: return 8192; case k_eControllerType_PS4Controller: - case k_eControllerType_PS5Controller: return 4096; case k_eControllerType_SwitchJoyConLeft: case k_eControllerType_SwitchJoyConRight: diff --git a/Engine/lib/sdl/src/joystick/darwin/SDL_iokitjoystick.c b/Engine/lib/sdl/src/joystick/darwin/SDL_iokitjoystick.c index 423f85740..7f2514728 100644 --- a/Engine/lib/sdl/src/joystick/darwin/SDL_iokitjoystick.c +++ b/Engine/lib/sdl/src/joystick/darwin/SDL_iokitjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -152,14 +152,17 @@ FreeDevice(recDevice *removeDevice) /* save next device prior to disposing of this device */ pDeviceNext = removeDevice->pNext; - if ( gpDeviceList == removeDevice ) { + if (gpDeviceList == removeDevice) { gpDeviceList = pDeviceNext; } else if (gpDeviceList) { - recDevice *device = gpDeviceList; - while (device->pNext != removeDevice) { - device = device->pNext; + recDevice *device; + + for (device = gpDeviceList; device; device = device->pNext) { + if (device->pNext == removeDevice) { + device->pNext = pDeviceNext; + break; + } } - device->pNext = pDeviceNext; } removeDevice->pNext = NULL; @@ -781,7 +784,7 @@ DARWIN_JoystickGetDeviceInstanceID(int device_index) } static int -DARWIN_JoystickOpen(SDL_Joystick * joystick, int device_index) +DARWIN_JoystickOpen(SDL_Joystick *joystick, int device_index) { recDevice *device = GetDeviceForIndex(device_index); @@ -891,7 +894,7 @@ DARWIN_JoystickInitRumble(recDevice *device, Sint16 magnitude) } static int -DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +DARWIN_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { HRESULT result; recDevice *device = joystick->hwdata; @@ -931,19 +934,36 @@ DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint } static int -DARWIN_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble) +DARWIN_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { return SDL_Unsupported(); } -static SDL_bool -DARWIN_JoystickHasLED(SDL_Joystick * joystick) +static Uint32 +DARWIN_JoystickGetCapabilities(SDL_Joystick *joystick) { - return SDL_FALSE; + recDevice *device = joystick->hwdata; + Uint32 result = 0; + + if (!device) { + return 0; + } + + if (device->ffservice) { + result |= SDL_JOYCAP_RUMBLE; + } + + return result; } static int -DARWIN_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) +DARWIN_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int +DARWIN_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) { return SDL_Unsupported(); } @@ -955,7 +975,7 @@ DARWIN_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) } static void -DARWIN_JoystickUpdate(SDL_Joystick * joystick) +DARWIN_JoystickUpdate(SDL_Joystick *joystick) { recDevice *device = joystick->hwdata; recElement *element; @@ -1060,7 +1080,7 @@ DARWIN_JoystickUpdate(SDL_Joystick * joystick) } static void -DARWIN_JoystickClose(SDL_Joystick * joystick) +DARWIN_JoystickClose(SDL_Joystick *joystick) { recDevice *device = joystick->hwdata; if (device) { @@ -1102,8 +1122,9 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver = DARWIN_JoystickOpen, DARWIN_JoystickRumble, DARWIN_JoystickRumbleTriggers, - DARWIN_JoystickHasLED, + DARWIN_JoystickGetCapabilities, DARWIN_JoystickSetLED, + DARWIN_JoystickSendEffect, DARWIN_JoystickSetSensorsEnabled, DARWIN_JoystickUpdate, DARWIN_JoystickClose, diff --git a/Engine/lib/sdl/src/joystick/darwin/SDL_iokitjoystick_c.h b/Engine/lib/sdl/src/joystick/darwin/SDL_iokitjoystick_c.h index 4505eccab..369edd130 100644 --- a/Engine/lib/sdl/src/joystick/darwin/SDL_iokitjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/darwin/SDL_iokitjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/joystick/dummy/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/dummy/SDL_sysjoystick.c index a51fb206a..ec1c8e651 100644 --- a/Engine/lib/sdl/src/joystick/dummy/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/dummy/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -95,10 +95,10 @@ DUMMY_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 return SDL_Unsupported(); } -static SDL_bool -DUMMY_JoystickHasLED(SDL_Joystick *joystick) +static Uint32 +DUMMY_JoystickGetCapabilities(SDL_Joystick *joystick) { - return SDL_FALSE; + return 0; } static int @@ -107,6 +107,12 @@ DUMMY_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) return SDL_Unsupported(); } +static int +DUMMY_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + static int DUMMY_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) { @@ -147,8 +153,9 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver = DUMMY_JoystickOpen, DUMMY_JoystickRumble, DUMMY_JoystickRumbleTriggers, - DUMMY_JoystickHasLED, + DUMMY_JoystickGetCapabilities, DUMMY_JoystickSetLED, + DUMMY_JoystickSendEffect, DUMMY_JoystickSetSensorsEnabled, DUMMY_JoystickUpdate, DUMMY_JoystickClose, diff --git a/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick.c index 8651d42a1..eb0ff2a74 100644 --- a/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -414,10 +414,10 @@ EMSCRIPTEN_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) return SDL_FALSE; } -static SDL_bool -EMSCRIPTEN_JoystickHasLED(SDL_Joystick *joystick) +static Uint32 +EMSCRIPTEN_JoystickGetCapabilities(SDL_Joystick *joystick) { - return SDL_FALSE; + return 0; } static int @@ -426,6 +426,12 @@ EMSCRIPTEN_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 return SDL_Unsupported(); } +static int +EMSCRIPTEN_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + static int EMSCRIPTEN_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) { @@ -445,8 +451,9 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver = EMSCRIPTEN_JoystickOpen, EMSCRIPTEN_JoystickRumble, EMSCRIPTEN_JoystickRumbleTriggers, - EMSCRIPTEN_JoystickHasLED, + EMSCRIPTEN_JoystickGetCapabilities, EMSCRIPTEN_JoystickSetLED, + EMSCRIPTEN_JoystickSendEffect, EMSCRIPTEN_JoystickSetSensorsEnabled, EMSCRIPTEN_JoystickUpdate, EMSCRIPTEN_JoystickClose, diff --git a/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick_c.h b/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick_c.h index 37a45b15b..815b53aaf 100644 --- a/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/joystick/haiku/SDL_haikujoystick.cc b/Engine/lib/sdl/src/joystick/haiku/SDL_haikujoystick.cc index 31f52ae0e..38a975227 100644 --- a/Engine/lib/sdl/src/joystick/haiku/SDL_haikujoystick.cc +++ b/Engine/lib/sdl/src/joystick/haiku/SDL_haikujoystick.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -271,9 +271,9 @@ extern "C" return SDL_FALSE; } - static SDL_bool HAIKU_JoystickHasLED(SDL_Joystick *joystick) + static Uint32 HAIKU_JoystickGetCapabilities(SDL_Joystick *joystick) { - return SDL_FALSE; + return 0; } static int HAIKU_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) @@ -281,6 +281,12 @@ extern "C" return SDL_Unsupported(); } + + static int HAIKU_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) + { + return SDL_Unsupported(); + } + static int HAIKU_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) { return SDL_Unsupported(); @@ -299,8 +305,9 @@ extern "C" HAIKU_JoystickOpen, HAIKU_JoystickRumble, HAIKU_JoystickRumbleTriggers, - HAIKU_JoystickHasLED, + HAIKU_JoystickGetCapabilities, HAIKU_JoystickSetLED, + HAIKU_JoystickSendEffect, HAIKU_JoystickSetSensorsEnabled, HAIKU_JoystickUpdate, HAIKU_JoystickClose, diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_gamecube.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_gamecube.c index ab36742bb..694556482 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_gamecube.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_gamecube.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,13 +32,18 @@ #include "../SDL_sysjoystick.h" #include "SDL_hidapijoystick_c.h" #include "SDL_hidapi_rumble.h" +#include "../../hidapi/SDL_hidapi_c.h" #ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_GAMECUBE_PROTOCOL*/ + #define MAX_CONTROLLERS 4 typedef struct { + SDL_bool pc_mode; SDL_JoystickID joysticks[MAX_CONTROLLERS]; Uint8 wireless[MAX_CONTROLLERS]; Uint8 min_axis[MAX_CONTROLLERS*SDL_CONTROLLER_AXIS_MAX]; @@ -48,6 +53,7 @@ typedef struct { /* Without this variable, hid_write starts to lag a TON */ SDL_bool rumbleUpdate; SDL_bool m_bUseButtonLabels; + SDL_bool useRumbleBrake; } SDL_DriverGameCube_Context; static SDL_bool @@ -57,6 +63,10 @@ HIDAPI_DriverGameCube_IsSupportedDevice(const char *name, SDL_GameControllerType /* Nintendo Co., Ltd. Wii U GameCube Controller Adapter */ return SDL_TRUE; } + if (vendor_id == USB_VENDOR_SHENZHEN && product_id == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER) { + /* EVORETRO GameCube Controller Adapter */ + return SDL_TRUE; + } return SDL_FALSE; } @@ -77,31 +87,20 @@ ResetAxisRange(SDL_DriverGameCube_Context *ctx, int joystick_index) ctx->min_axis[joystick_index*SDL_CONTROLLER_AXIS_MAX+SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = 40; } -static float fsel(float fComparand, float fValGE, float fLT) -{ - return fComparand >= 0 ? fValGE : fLT; -} - -static float RemapVal(float val, float A, float B, float C, float D) -{ - if (A == B) { - return fsel(val - B , D , C); - } - if (val < A) { - val = A; - } - if (val > B) { - val = B; - } - return C + (D - C) * (val - A) / (B - A); -} - static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)userdata; ctx->m_bUseButtonLabels = SDL_GetStringBoolean(hint, SDL_TRUE); } +static void SDLCALL SDL_JoystickGameCubeRumbleBrakeHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + if (hint) { + SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)userdata; + ctx->useRumbleBrake = SDL_GetStringBoolean(hint, SDL_FALSE); + } +} + static Uint8 RemapButton(SDL_DriverGameCube_Context *ctx, Uint8 button) { if (!ctx->m_bUseButtonLabels) { @@ -129,13 +128,17 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device) Uint8 initMagic = 0x13; Uint8 rumbleMagic = 0x11; +#ifdef HAVE_ENABLE_GAMECUBE_ADAPTORS + SDL_EnableGameCubeAdaptors(); +#endif + ctx = (SDL_DriverGameCube_Context *)SDL_calloc(1, sizeof(*ctx)); if (!ctx) { SDL_OutOfMemory(); return SDL_FALSE; } - device->dev = hid_open_path(device->path, 0); + device->dev = SDL_hid_open_path(device->path, 0); if (!device->dev) { SDL_free(ctx); SDL_SetError("Couldn't open %s", device->path); @@ -148,59 +151,81 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device) ctx->joysticks[2] = -1; ctx->joysticks[3] = -1; ctx->rumble[0] = rumbleMagic; + ctx->useRumbleBrake = SDL_FALSE; - /* This is all that's needed to initialize the device. Really! */ - if (hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) { - SDL_SetError("Couldn't initialize WUP-028"); - goto error; + if (device->vendor_id != USB_VENDOR_NINTENDO) { + ctx->pc_mode = SDL_TRUE; } - /* Wait for the adapter to initialize */ - SDL_Delay(10); - - /* Add all the applicable joysticks */ - while ((size = hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) { - if (size < 37 || packet[0] != 0x21) { - continue; /* Nothing to do yet...? */ + if (ctx->pc_mode) { + for (i = 0; i < MAX_CONTROLLERS; ++i) { + ResetAxisRange(ctx, i); + HIDAPI_JoystickConnected(device, &ctx->joysticks[i]); + } + } else { + /* This is all that's needed to initialize the device. Really! */ + if (SDL_hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) { + SDL_SetError("Couldn't initialize WUP-028"); + goto error; } - /* Go through all 4 slots */ - curSlot = packet + 1; - for (i = 0; i < MAX_CONTROLLERS; i += 1, curSlot += 9) { - ctx->wireless[i] = (curSlot[0] & 0x20) != 0; + /* Wait for the adapter to initialize */ + SDL_Delay(10); - /* Only allow rumble if the adapter's second USB cable is connected */ - ctx->rumbleAllowed[i] = (curSlot[0] & 0x04) != 0 && !ctx->wireless[i]; + /* Add all the applicable joysticks */ + while ((size = SDL_hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) { +#ifdef DEBUG_GAMECUBE_PROTOCOL + HIDAPI_DumpPacket("Nintendo GameCube packet: size = %d", packet, size); +#endif + if (size < 37 || packet[0] != 0x21) { + continue; /* Nothing to do yet...? */ + } - if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */ - if (ctx->joysticks[i] == -1) { - ResetAxisRange(ctx, i); - HIDAPI_JoystickConnected(device, &ctx->joysticks[i]); + /* Go through all 4 slots */ + curSlot = packet + 1; + for (i = 0; i < MAX_CONTROLLERS; i += 1, curSlot += 9) { + ctx->wireless[i] = (curSlot[0] & 0x20) != 0; + + /* Only allow rumble if the adapter's second USB cable is connected */ + ctx->rumbleAllowed[i] = (curSlot[0] & 0x04) != 0 && !ctx->wireless[i]; + + if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */ + if (ctx->joysticks[i] == -1) { + ResetAxisRange(ctx, i); + HIDAPI_JoystickConnected(device, &ctx->joysticks[i]); + } + } else { + if (ctx->joysticks[i] != -1) { + HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]); + ctx->joysticks[i] = -1; + } + continue; } - } else { - if (ctx->joysticks[i] != -1) { - HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]); - ctx->joysticks[i] = -1; - } - continue; } } } + SDL_AddHintCallback(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE, + SDL_JoystickGameCubeRumbleBrakeHintChanged, ctx); SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, SDL_GameControllerButtonReportingHintChanged, ctx); return SDL_TRUE; error: - if (device->dev) { - hid_close(device->dev); - device->dev = NULL; - } - if (device->context) { - SDL_free(device->context); - device->context = NULL; + SDL_LockMutex(device->dev_lock); + { + if (device->dev) { + SDL_hid_close(device->dev); + device->dev = NULL; + } + if (device->context) { + SDL_free(device->context); + device->context = NULL; + } } + SDL_UnlockMutex(device->dev_lock); + return SDL_FALSE; } @@ -223,90 +248,167 @@ HIDAPI_DriverGameCube_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_Joysti { } +static void +HIDAPI_DriverGameCube_HandleJoystickPacket(SDL_HIDAPI_Device *device, SDL_DriverGameCube_Context *ctx, Uint8 *packet, int size) +{ + SDL_Joystick *joystick; + Uint8 i, v; + Sint16 axis_value; + + if (size != 10) { + return; /* How do we handle this packet? */ + } + + i = packet[0] - 1; + if (i >= MAX_CONTROLLERS) { + return; /* How do we handle this packet? */ + } + + joystick = SDL_JoystickFromInstanceID(ctx->joysticks[i]); + if (!joystick) { + /* Hasn't been opened yet, skip */ + return; + } + + #define READ_BUTTON(off, flag, button) \ + SDL_PrivateJoystickButton( \ + joystick, \ + RemapButton(ctx, button), \ + (packet[off] & flag) ? SDL_PRESSED : SDL_RELEASED \ + ); + READ_BUTTON(1, 0x02, 0) /* A */ + READ_BUTTON(1, 0x04, 1) /* B */ + READ_BUTTON(1, 0x01, 2) /* X */ + READ_BUTTON(1, 0x08, 3) /* Y */ + READ_BUTTON(2, 0x80, 4) /* DPAD_LEFT */ + READ_BUTTON(2, 0x20, 5) /* DPAD_RIGHT */ + READ_BUTTON(2, 0x40, 6) /* DPAD_DOWN */ + READ_BUTTON(2, 0x10, 7) /* DPAD_UP */ + READ_BUTTON(2, 0x02, 8) /* START */ + READ_BUTTON(1, 0x80, 9) /* RIGHTSHOULDER */ + /* These two buttons are for the bottoms of the analog triggers. + * More than likely, you're going to want to read the axes instead! + * -flibit + */ + READ_BUTTON(1, 0x20, 10) /* TRIGGERRIGHT */ + READ_BUTTON(1, 0x10, 11) /* TRIGGERLEFT */ + #undef READ_BUTTON + + #define READ_AXIS(off, axis, invert) \ + v = invert ? (0xff - packet[off]) : packet[off]; \ + if (v < ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis]) ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis] = v; \ + if (v > ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis]) ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis] = v; \ + axis_value = (Sint16)HIDAPI_RemapVal(v, ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis], ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis], SDL_MIN_SINT16, SDL_MAX_SINT16); \ + SDL_PrivateJoystickAxis( \ + joystick, \ + axis, axis_value \ + ); + READ_AXIS(3, SDL_CONTROLLER_AXIS_LEFTX, 0) + READ_AXIS(4, SDL_CONTROLLER_AXIS_LEFTY, 0) + READ_AXIS(6, SDL_CONTROLLER_AXIS_RIGHTX, 1) + READ_AXIS(5, SDL_CONTROLLER_AXIS_RIGHTY, 1) + READ_AXIS(7, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0) + READ_AXIS(8, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0) + #undef READ_AXIS +} + +static void +HIDAPI_DriverGameCube_HandleNintendoPacket(SDL_HIDAPI_Device *device, SDL_DriverGameCube_Context *ctx, Uint8 *packet, int size) +{ + SDL_Joystick *joystick; + Uint8 *curSlot; + Uint8 i; + Sint16 axis_value; + + if (size < 37 || packet[0] != 0x21) { + return; /* Nothing to do right now...? */ + } + + /* Go through all 4 slots */ + curSlot = packet + 1; + for (i = 0; i < MAX_CONTROLLERS; i += 1, curSlot += 9) { + ctx->wireless[i] = (curSlot[0] & 0x20) != 0; + + /* Only allow rumble if the adapter's second USB cable is connected */ + ctx->rumbleAllowed[i] = (curSlot[0] & 0x04) != 0 && !ctx->wireless[i]; + + if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */ + if (ctx->joysticks[i] == -1) { + ResetAxisRange(ctx, i); + HIDAPI_JoystickConnected(device, &ctx->joysticks[i]); + } + joystick = SDL_JoystickFromInstanceID(ctx->joysticks[i]); + + /* Hasn't been opened yet, skip */ + if (joystick == NULL) { + continue; + } + } else { + if (ctx->joysticks[i] != -1) { + HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]); + ctx->joysticks[i] = -1; + } + continue; + } + + #define READ_BUTTON(off, flag, button) \ + SDL_PrivateJoystickButton( \ + joystick, \ + RemapButton(ctx, button), \ + (curSlot[off] & flag) ? SDL_PRESSED : SDL_RELEASED \ + ); + READ_BUTTON(1, 0x01, 0) /* A */ + READ_BUTTON(1, 0x04, 1) /* B */ + READ_BUTTON(1, 0x02, 2) /* X */ + READ_BUTTON(1, 0x08, 3) /* Y */ + READ_BUTTON(1, 0x10, 4) /* DPAD_LEFT */ + READ_BUTTON(1, 0x20, 5) /* DPAD_RIGHT */ + READ_BUTTON(1, 0x40, 6) /* DPAD_DOWN */ + READ_BUTTON(1, 0x80, 7) /* DPAD_UP */ + READ_BUTTON(2, 0x01, 8) /* START */ + READ_BUTTON(2, 0x02, 9) /* RIGHTSHOULDER */ + /* These two buttons are for the bottoms of the analog triggers. + * More than likely, you're going to want to read the axes instead! + * -flibit + */ + READ_BUTTON(2, 0x04, 10) /* TRIGGERRIGHT */ + READ_BUTTON(2, 0x08, 11) /* TRIGGERLEFT */ + #undef READ_BUTTON + + #define READ_AXIS(off, axis) \ + if (curSlot[off] < ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis]) ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis] = curSlot[off]; \ + if (curSlot[off] > ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis]) ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis] = curSlot[off]; \ + axis_value = (Sint16)HIDAPI_RemapVal(curSlot[off], ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis], ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis], SDL_MIN_SINT16, SDL_MAX_SINT16); \ + SDL_PrivateJoystickAxis( \ + joystick, \ + axis, axis_value \ + ); + READ_AXIS(3, SDL_CONTROLLER_AXIS_LEFTX) + READ_AXIS(4, SDL_CONTROLLER_AXIS_LEFTY) + READ_AXIS(5, SDL_CONTROLLER_AXIS_RIGHTX) + READ_AXIS(6, SDL_CONTROLLER_AXIS_RIGHTY) + READ_AXIS(7, SDL_CONTROLLER_AXIS_TRIGGERLEFT) + READ_AXIS(8, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + #undef READ_AXIS + } +} + static SDL_bool HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device) { SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; - SDL_Joystick *joystick; - Uint8 packet[37]; - Uint8 *curSlot; - Uint8 i; - Sint16 axis_value; + Uint8 packet[USB_PACKET_LENGTH]; int size; /* Read input packet */ - while ((size = hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) { - if (size < 37 || packet[0] != 0x21) { - continue; /* Nothing to do right now...? */ - } - - /* Go through all 4 slots */ - curSlot = packet + 1; - for (i = 0; i < MAX_CONTROLLERS; i += 1, curSlot += 9) { - ctx->wireless[i] = (curSlot[0] & 0x20) != 0; - - /* Only allow rumble if the adapter's second USB cable is connected */ - ctx->rumbleAllowed[i] = (curSlot[0] & 0x04) != 0 && !ctx->wireless[i]; - - if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */ - if (ctx->joysticks[i] == -1) { - ResetAxisRange(ctx, i); - HIDAPI_JoystickConnected(device, &ctx->joysticks[i]); - } - joystick = SDL_JoystickFromInstanceID(ctx->joysticks[i]); - - /* Hasn't been opened yet, skip */ - if (joystick == NULL) { - continue; - } - } else { - if (ctx->joysticks[i] != -1) { - HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]); - ctx->joysticks[i] = -1; - } - continue; - } - - #define READ_BUTTON(off, flag, button) \ - SDL_PrivateJoystickButton( \ - joystick, \ - RemapButton(ctx, button), \ - (curSlot[off] & flag) ? SDL_PRESSED : SDL_RELEASED \ - ); - READ_BUTTON(1, 0x01, 0) /* A */ - READ_BUTTON(1, 0x04, 1) /* B */ - READ_BUTTON(1, 0x02, 2) /* X */ - READ_BUTTON(1, 0x08, 3) /* Y */ - READ_BUTTON(1, 0x10, 4) /* DPAD_LEFT */ - READ_BUTTON(1, 0x20, 5) /* DPAD_RIGHT */ - READ_BUTTON(1, 0x40, 6) /* DPAD_DOWN */ - READ_BUTTON(1, 0x80, 7) /* DPAD_UP */ - READ_BUTTON(2, 0x01, 8) /* START */ - READ_BUTTON(2, 0x02, 9) /* RIGHTSHOULDER */ - /* These two buttons are for the bottoms of the analog triggers. - * More than likely, you're going to want to read the axes instead! - * -flibit - */ - READ_BUTTON(2, 0x04, 10) /* TRIGGERRIGHT */ - READ_BUTTON(2, 0x08, 11) /* TRIGGERLEFT */ - #undef READ_BUTTON - - #define READ_AXIS(off, axis) \ - if (axis < SDL_CONTROLLER_AXIS_TRIGGERLEFT) \ - if (curSlot[off] < ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis]) ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis] = curSlot[off]; \ - if (curSlot[off] > ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis]) ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis] = curSlot[off]; \ - axis_value = (Sint16)(RemapVal(curSlot[off], ctx->min_axis[i*SDL_CONTROLLER_AXIS_MAX+axis], ctx->max_axis[i*SDL_CONTROLLER_AXIS_MAX+axis], SDL_MIN_SINT16, SDL_MAX_SINT16)); \ - SDL_PrivateJoystickAxis( \ - joystick, \ - axis, axis_value \ - ); - READ_AXIS(3, SDL_CONTROLLER_AXIS_LEFTX) - READ_AXIS(4, SDL_CONTROLLER_AXIS_LEFTY) - READ_AXIS(5, SDL_CONTROLLER_AXIS_RIGHTX) - READ_AXIS(6, SDL_CONTROLLER_AXIS_RIGHTY) - READ_AXIS(7, SDL_CONTROLLER_AXIS_TRIGGERLEFT) - READ_AXIS(8, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) - #undef READ_AXIS + while ((size = SDL_hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) { +#ifdef DEBUG_GAMECUBE_PROTOCOL + //HIDAPI_DumpPacket("Nintendo GameCube packet: size = %d", packet, size); +#endif + if (ctx->pc_mode) { + HIDAPI_DriverGameCube_HandleJoystickPacket(device, ctx, packet, size); + } else { + HIDAPI_DriverGameCube_HandleNintendoPacket(device, ctx, packet, size); } } @@ -341,15 +443,30 @@ HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo { SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; Uint8 i, val; + + if (ctx->pc_mode) { + return SDL_Unsupported(); + } + for (i = 0; i < MAX_CONTROLLERS; i += 1) { if (joystick->instance_id == ctx->joysticks[i]) { if (ctx->wireless[i]) { - return SDL_SetError("Ninteno GameCube WaveBird controllers do not support rumble"); + return SDL_SetError("Nintendo GameCube WaveBird controllers do not support rumble"); } if (!ctx->rumbleAllowed[i]) { return SDL_SetError("Second USB cable for WUP-028 not connected"); } - val = (low_frequency_rumble > 0 || high_frequency_rumble > 0); + if (ctx->useRumbleBrake) { + if (low_frequency_rumble == 0 && high_frequency_rumble > 0) { + val = 0; /* if only low is 0 we want to do a regular stop*/ + } else if (low_frequency_rumble == 0 && high_frequency_rumble == 0) { + val = 2; /* if both frequencies are 0 we want to do a hard stop */ + } else { + val = 1; /* normal rumble */ + } + } else { + val = (low_frequency_rumble > 0 || high_frequency_rumble > 0); + } if (val != ctx->rumble[i + 1]) { ctx->rumble[i + 1] = val; ctx->rumbleUpdate = SDL_TRUE; @@ -359,8 +476,7 @@ HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo } /* Should never get here! */ - SDL_SetError("Couldn't find joystick"); - return -1; + return SDL_SetError("Couldn't find joystick"); } static int @@ -369,10 +485,26 @@ HIDAPI_DriverGameCube_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joys return SDL_Unsupported(); } -static SDL_bool -HIDAPI_DriverGameCube_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +static Uint32 +HIDAPI_DriverGameCube_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - return SDL_FALSE; + SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; + Uint32 result = 0; + + if (!ctx->pc_mode) { + Uint8 i; + + for (i = 0; i < MAX_CONTROLLERS; i += 1) { + if (joystick->instance_id == ctx->joysticks[i]) { + if (!ctx->wireless[i] && ctx->rumbleAllowed[i]) { + result |= SDL_JOYCAP_RUMBLE; + break; + } + } + } + } + + return result; } static int @@ -381,6 +513,12 @@ HIDAPI_DriverGameCube_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *jo return SDL_Unsupported(); } +static int +HIDAPI_DriverGameCube_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + static int HIDAPI_DriverGameCube_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) { @@ -404,20 +542,27 @@ HIDAPI_DriverGameCube_FreeDevice(SDL_HIDAPI_Device *device) { SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; - hid_close(device->dev); - device->dev = NULL; - SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, SDL_GameControllerButtonReportingHintChanged, ctx); + SDL_DelHintCallback(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE, + SDL_JoystickGameCubeRumbleBrakeHintChanged, ctx); - SDL_free(device->context); - device->context = NULL; + SDL_LockMutex(device->dev_lock); + { + SDL_hid_close(device->dev); + device->dev = NULL; + + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); } SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube = { SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE, SDL_TRUE, + SDL_TRUE, HIDAPI_DriverGameCube_IsSupportedDevice, HIDAPI_DriverGameCube_GetDeviceName, HIDAPI_DriverGameCube_InitDevice, @@ -427,8 +572,9 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube = HIDAPI_DriverGameCube_OpenJoystick, HIDAPI_DriverGameCube_RumbleJoystick, HIDAPI_DriverGameCube_RumbleJoystickTriggers, - HIDAPI_DriverGameCube_HasJoystickLED, + HIDAPI_DriverGameCube_GetJoystickCapabilities, HIDAPI_DriverGameCube_SetJoystickLED, + HIDAPI_DriverGameCube_SendJoystickEffect, HIDAPI_DriverGameCube_SetJoystickSensorsEnabled, HIDAPI_DriverGameCube_CloseJoystick, HIDAPI_DriverGameCube_FreeDevice, diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_luna.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_luna.c new file mode 100644 index 000000000..ead55af34 --- /dev/null +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_luna.c @@ -0,0 +1,463 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_hints.h" +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + + +#ifdef SDL_JOYSTICK_HIDAPI_LUNA + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_LUNA_PROTOCOL*/ + +enum +{ + SDL_CONTROLLER_BUTTON_LUNA_MIC = 15, + SDL_CONTROLLER_NUM_LUNA_BUTTONS, +}; + +typedef struct { + Uint8 last_state[USB_PACKET_LENGTH]; +} SDL_DriverLuna_Context; + + +static SDL_bool +HIDAPI_DriverLuna_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + return (type == SDL_CONTROLLER_TYPE_AMAZON_LUNA) ? SDL_TRUE : SDL_FALSE; +} + +static const char * +HIDAPI_DriverLuna_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +{ + return "Amazon Luna Controller"; +} + +static SDL_bool +HIDAPI_DriverLuna_InitDevice(SDL_HIDAPI_Device *device) +{ + return HIDAPI_JoystickConnected(device, NULL); +} + +static int +HIDAPI_DriverLuna_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void +HIDAPI_DriverLuna_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ +} + +static SDL_bool +HIDAPI_DriverLuna_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverLuna_Context *ctx; + + ctx = (SDL_DriverLuna_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + + device->dev = SDL_hid_open_path(device->path, 0); + if (!device->dev) { + SDL_SetError("Couldn't open %s", device->path); + SDL_free(ctx); + return SDL_FALSE; + } + device->context = ctx; + + /* Initialize the joystick capabilities */ + joystick->nbuttons = SDL_CONTROLLER_NUM_LUNA_BUTTONS; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL; + joystick->serial = NULL; + + return SDL_TRUE; +} + +static int +HIDAPI_DriverLuna_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + if (device->product_id == BLUETOOTH_PRODUCT_LUNA_CONTROLLER) { + /* Same packet as on Xbox One controllers connected via Bluetooth */ + Uint8 rumble_packet[] = { 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEB }; + + /* Magnitude is 1..100 so scale the 16-bit input here */ + rumble_packet[4] = low_frequency_rumble / 655; + rumble_packet[5] = high_frequency_rumble / 655; + + if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } + + return 0; + } else { + /* FIXME: Is there a rumble packet over USB? */ + return SDL_Unsupported(); + } +} + +static int +HIDAPI_DriverLuna_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 +HIDAPI_DriverLuna_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + Uint32 result = 0; + + if (device->product_id == BLUETOOTH_PRODUCT_LUNA_CONTROLLER) { + result |= SDL_JOYCAP_RUMBLE; + } + + return result; +} + +static int +HIDAPI_DriverLuna_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int +HIDAPI_DriverLuna_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int +HIDAPI_DriverLuna_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void +HIDAPI_DriverLuna_HandleUSBStatePacket(SDL_Joystick *joystick, SDL_DriverLuna_Context *ctx, Uint8 *data, int size) +{ + if (ctx->last_state[1] != data[1]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[1] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[1] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[1] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[1] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[1] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[1] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[1] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + if (ctx->last_state[2] != data[2]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[2] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LUNA_MIC, (data[2] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[2] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[2] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[3] != data[3]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[3] & 0xf) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + +#define READ_STICK_AXIS(offset) \ + (data[offset] == 0x7f ? 0 : \ + (Sint16)HIDAPI_RemapVal((float)data[offset], 0x00, 0xff, SDL_MIN_SINT16, SDL_MAX_SINT16)) + { + Sint16 axis = READ_STICK_AXIS(4); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = READ_STICK_AXIS(5); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = READ_STICK_AXIS(6); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = READ_STICK_AXIS(7); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + } +#undef READ_STICK_AXIS + +#define READ_TRIGGER_AXIS(offset) \ + (Sint16)HIDAPI_RemapVal((float)data[offset], 0x00, 0xff, SDL_MIN_SINT16, SDL_MAX_SINT16) + { + Sint16 axis = READ_TRIGGER_AXIS(8); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = READ_TRIGGER_AXIS(9); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + } +#undef READ_TRIGGER_AXIS + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static void +HIDAPI_DriverLuna_HandleBluetoothStatePacket(SDL_Joystick *joystick, SDL_DriverLuna_Context *ctx, Uint8 *data, int size) +{ + if (size >= 2 && data[0] == 0x02) { + /* Home button has dedicated report */ + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[1] & 0x1) ? SDL_PRESSED : SDL_RELEASED); + return; + } + + if (size >= 2 && data[0] == 0x04) { + /* Battery level report */ + int level = data[1] * 100 / 0xFF; + if (level == 0) { + joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY; + } + else if (level <= 20) { + joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW; + } + else if (level <= 70) { + joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM; + } + else { + joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL; + } + + return; + } + + if (size < 17 || data[0] != 0x01) { + /* We don't know how to handle this report */ + return; + } + + if (ctx->last_state[13] != data[13]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[13] & 0xf) { + case 1: + dpad_up = SDL_TRUE; + break; + case 2: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + break; + case 4: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 5: + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 7: + dpad_left = SDL_TRUE; + break; + case 8: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + + if (ctx->last_state[14] != data[14]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[14] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[14] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[14] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[14] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[14] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[14] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + if (ctx->last_state[15] != data[15]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[15] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[15] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + } + if (ctx->last_state[16] != data[16]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LUNA_MIC, (data[16] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + } + +#define READ_STICK_AXIS(offset) \ + (data[offset] == 0x7f ? 0 : \ + (Sint16)HIDAPI_RemapVal((float)data[offset], 0x00, 0xff, SDL_MIN_SINT16, SDL_MAX_SINT16)) + { + Sint16 axis = READ_STICK_AXIS(2); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = READ_STICK_AXIS(4); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = READ_STICK_AXIS(6); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = READ_STICK_AXIS(8); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + } +#undef READ_STICK_AXIS + +#define READ_TRIGGER_AXIS(offset) \ + (Sint16)HIDAPI_RemapVal((float)((int)(((data[offset] | (data[offset + 1] << 8)) & 0x3ff) - 0x200)), 0x00 - 0x200, 0x3ff - 0x200, SDL_MIN_SINT16, SDL_MAX_SINT16) + { + Sint16 axis = READ_TRIGGER_AXIS(9); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = READ_TRIGGER_AXIS(11); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + } +#undef READ_TRIGGER_AXIS + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static SDL_bool +HIDAPI_DriverLuna_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverLuna_Context *ctx = (SDL_DriverLuna_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH]; + int size = 0; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } + if (!joystick) { + return SDL_FALSE; + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_LUNA_PROTOCOL + HIDAPI_DumpPacket("Amazon Luna packet: size = %d", data, size); +#endif + switch (size) { + case 10: + HIDAPI_DriverLuna_HandleUSBStatePacket(joystick, ctx, data, size); + break; + default: + HIDAPI_DriverLuna_HandleBluetoothStatePacket(joystick, ctx, data, size); + break; + } + } + + if (size < 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, joystick->instance_id); + } + return (size >= 0); +} + +static void +HIDAPI_DriverLuna_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_LockMutex(device->dev_lock); + { + if (device->dev) { + SDL_hid_close(device->dev); + device->dev = NULL; + } + + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); +} + +static void +HIDAPI_DriverLuna_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna = +{ + SDL_HINT_JOYSTICK_HIDAPI_LUNA, + SDL_TRUE, + SDL_TRUE, + HIDAPI_DriverLuna_IsSupportedDevice, + HIDAPI_DriverLuna_GetDeviceName, + HIDAPI_DriverLuna_InitDevice, + HIDAPI_DriverLuna_GetDevicePlayerIndex, + HIDAPI_DriverLuna_SetDevicePlayerIndex, + HIDAPI_DriverLuna_UpdateDevice, + HIDAPI_DriverLuna_OpenJoystick, + HIDAPI_DriverLuna_RumbleJoystick, + HIDAPI_DriverLuna_RumbleJoystickTriggers, + HIDAPI_DriverLuna_GetJoystickCapabilities, + HIDAPI_DriverLuna_SetJoystickLED, + HIDAPI_DriverLuna_SendJoystickEffect, + HIDAPI_DriverLuna_SetJoystickSensorsEnabled, + HIDAPI_DriverLuna_CloseJoystick, + HIDAPI_DriverLuna_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_LUNA */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps4.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps4.c index a20757183..8e7699fe4 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps4.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,6 +30,7 @@ #include "SDL_timer.h" #include "SDL_joystick.h" #include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" #include "../SDL_sysjoystick.h" #include "SDL_hidapijoystick_c.h" #include "SDL_hidapi_rumble.h" @@ -45,6 +46,7 @@ #define GYRO_RES_PER_DEGREE 1024.0f #define ACCEL_RES_PER_G 8192.0f +#define BLUETOOTH_DISCONNECT_TIMEOUT_MS 500 #define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) @@ -119,14 +121,18 @@ typedef struct { } IMUCalibrationData; typedef struct { + SDL_HIDAPI_Device *device; + SDL_Joystick *joystick; SDL_bool is_dongle; SDL_bool is_bluetooth; SDL_bool official_controller; SDL_bool audio_supported; SDL_bool effects_supported; + SDL_bool enhanced_mode; SDL_bool report_sensors; SDL_bool hardware_calibration; IMUCalibrationData calibration[6]; + Uint32 last_packet; int player_index; Uint8 rumble_left; Uint8 rumble_right; @@ -140,6 +146,8 @@ typedef struct { } SDL_DriverPS4_Context; +static int HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size); + static SDL_bool HIDAPI_DriverPS4_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) { @@ -155,11 +163,11 @@ HIDAPI_DriverPS4_GetDeviceName(Uint16 vendor_id, Uint16 product_id) return NULL; } -static int ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *report, size_t length) +static int ReadFeatureReport(SDL_hid_device *dev, Uint8 report_id, Uint8 *report, size_t length) { SDL_memset(report, 0, length); report[0] = report_id; - return hid_get_feature_report(dev, report, length); + return SDL_hid_get_feature_report(dev, report, length); } static SDL_bool HIDAPI_DriverPS4_CanRumble(Uint16 vendor_id, Uint16 product_id) @@ -169,6 +177,12 @@ static SDL_bool HIDAPI_DriverPS4_CanRumble(Uint16 vendor_id, Uint16 product_id) (product_id == USB_PRODUCT_RAZER_PANTHERA || product_id == USB_PRODUCT_RAZER_PANTHERA_EVO)) { return SDL_FALSE; } + + /* The Victrix Pro FS v2 will hang on reboot if we send output reports */ + if (vendor_id == USB_VENDOR_PDP && product_id == USB_PRODUCT_VICTRIX_FS_PRO_V2) { + return SDL_FALSE; + } + return SDL_TRUE; } @@ -379,57 +393,66 @@ static int HIDAPI_DriverPS4_UpdateEffects(SDL_HIDAPI_Device *device) { SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; - DS4EffectsState_t *effects; - Uint8 data[78]; - int report_size, offset; + DS4EffectsState_t effects; - if (!ctx->effects_supported) { + if (!ctx->enhanced_mode) { return SDL_Unsupported(); } - SDL_zero(data); + SDL_zero(effects); - if (ctx->is_bluetooth) { - data[0] = k_EPS4ReportIdBluetoothEffects; - data[1] = 0xC0 | 0x04; /* Magic value HID + CRC, also sets interval to 4ms for samples */ - data[3] = 0x03; /* 0x1 is rumble, 0x2 is lightbar, 0x4 is the blink interval */ - - report_size = 78; - offset = 6; - } else { - data[0] = k_EPS4ReportIdUsbEffects; - data[1] = 0x07; /* Magic value */ - - report_size = 32; - offset = 4; - } - effects = (DS4EffectsState_t *)&data[offset]; - - effects->ucRumbleLeft = ctx->rumble_left; - effects->ucRumbleRight = ctx->rumble_right; + effects.ucRumbleLeft = ctx->rumble_left; + effects.ucRumbleRight = ctx->rumble_right; /* Populate the LED state with the appropriate color from our lookup table */ if (ctx->color_set) { - effects->ucLedRed = ctx->led_red; - effects->ucLedGreen = ctx->led_green; - effects->ucLedBlue = ctx->led_blue; + effects.ucLedRed = ctx->led_red; + effects.ucLedGreen = ctx->led_green; + effects.ucLedBlue = ctx->led_blue; } else { - SetLedsForPlayerIndex(effects, ctx->player_index); + SetLedsForPlayerIndex(&effects, ctx->player_index); } + return HIDAPI_DriverPS4_SendJoystickEffect(device, ctx->joystick, &effects, sizeof(effects)); +} - if (ctx->is_bluetooth) { - /* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */ - Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */ - Uint32 unCRC; - unCRC = SDL_crc32(0, &ubHdr, 1); - unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC))); - SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC)); - } +static void +HIDAPI_DriverPS4_TickleBluetooth(SDL_HIDAPI_Device *device) +{ + /* This is just a dummy packet that should have no effect, since we don't set the CRC */ + Uint8 data[78]; - if (SDL_HIDAPI_SendRumble(device, data, report_size) != report_size) { - return SDL_SetError("Couldn't send rumble packet"); + SDL_zeroa(data); + + data[0] = k_EPS4ReportIdBluetoothEffects; + data[1] = 0xC0; /* Magic value HID + CRC */ + + SDL_HIDAPI_SendRumble(device, data, sizeof(data)); +} + +static void +HIDAPI_DriverPS4_SetEnhancedMode(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + if (!ctx->enhanced_mode) { + ctx->enhanced_mode = SDL_TRUE; + + SDL_PrivateJoystickAddTouchpad(joystick, 2); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f); + + HIDAPI_DriverPS4_UpdateEffects(device); + } +} + +static void SDLCALL SDL_PS4RumbleHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)userdata; + + /* This is a one-way trip, you can't switch the controller back to simple report mode */ + if (SDL_GetStringBoolean(hint, SDL_FALSE)) { + HIDAPI_DriverPS4_SetEnhancedMode(ctx->device, ctx->joystick); } - return 0; } static void @@ -451,14 +474,18 @@ static SDL_bool HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { SDL_DriverPS4_Context *ctx; + SDL_bool enhanced_mode = SDL_FALSE; ctx = (SDL_DriverPS4_Context *)SDL_calloc(1, sizeof(*ctx)); if (!ctx) { SDL_OutOfMemory(); return SDL_FALSE; } + ctx->device = device; + ctx->joystick = joystick; + ctx->last_packet = SDL_GetTicks(); - device->dev = hid_open_path(device->path, 0); + device->dev = SDL_hid_open_path(device->path, 0); if (!device->dev) { SDL_free(ctx); SDL_SetError("Couldn't open %s", device->path); @@ -471,6 +498,7 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) if (ctx->is_dongle) { ctx->is_bluetooth = SDL_FALSE; ctx->official_controller = SDL_TRUE; + enhanced_mode = SDL_TRUE; } else if (device->vendor_id == USB_VENDOR_SONY) { Uint8 data[USB_PACKET_LENGTH]; int size; @@ -484,13 +512,30 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) data[6], data[5], data[4], data[3], data[2], data[1]); joystick->serial = SDL_strdup(serial); ctx->is_bluetooth = SDL_FALSE; + enhanced_mode = SDL_TRUE; } else { ctx->is_bluetooth = SDL_TRUE; + + /* Read a report to see if we're in enhanced mode */ + size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16); +#ifdef DEBUG_PS4_PROTOCOL + if (size > 0) { + HIDAPI_DumpPacket("PS4 first packet: size = %d", data, size); + } else { + SDL_Log("PS4 first packet: size = %d\n", size); + } +#endif + if (size > 0 && + data[0] >= k_EPS4ReportIdBluetoothState1 && + data[0] <= k_EPS4ReportIdBluetoothState9) { + enhanced_mode = SDL_TRUE; + } } ctx->official_controller = SDL_TRUE; } else { /* Third party controllers appear to all be wired */ ctx->is_bluetooth = SDL_FALSE; + enhanced_mode = SDL_TRUE; } #ifdef DEBUG_PS4 SDL_Log("PS4 dongle = %s, bluetooth = %s\n", ctx->is_dongle ? "TRUE" : "FALSE", ctx->is_bluetooth ? "TRUE" : "FALSE"); @@ -503,28 +548,42 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) } if (HIDAPI_DriverPS4_CanRumble(device->vendor_id, device->product_id)) { - if (ctx->is_bluetooth) { - ctx->effects_supported = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, SDL_FALSE); - } else { - ctx->effects_supported = SDL_TRUE; + ctx->effects_supported = SDL_TRUE; + } + + if (!joystick->serial && device->serial && SDL_strlen(device->serial) == 12) { + int i, j; + char serial[18]; + + j = -1; + for (i = 0; i < 12; i += 2) { + j += 1; + SDL_memcpy(&serial[j], &device->serial[i], 2); + j += 2; + serial[j] = '-'; } + serial[j] = '\0'; + + joystick->serial = SDL_strdup(serial); } /* Initialize player index (needed for setting LEDs) */ ctx->player_index = SDL_JoystickGetPlayerIndex(joystick); - /* Initialize LED and effect state */ - HIDAPI_DriverPS4_UpdateEffects(device); - - /* Initialize the joystick capabilities */ + /* Initialize the joystick capabilities + * + * We can't dynamically add the touchpad button, so always report it here + */ joystick->nbuttons = 16; joystick->naxes = SDL_CONTROLLER_AXIS_MAX; - joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; - - SDL_PrivateJoystickAddTouchpad(joystick, 2); - SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO); - SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL); + joystick->epowerlevel = ctx->is_bluetooth ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED; + if (enhanced_mode) { + HIDAPI_DriverPS4_SetEnhancedMode(device, joystick); + } else { + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, + SDL_PS4RumbleHintChanged, ctx); + } return SDL_TRUE; } @@ -545,10 +604,17 @@ HIDAPI_DriverPS4_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick return SDL_Unsupported(); } -static SDL_bool -HIDAPI_DriverPS4_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +static Uint32 +HIDAPI_DriverPS4_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - return SDL_TRUE; + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + Uint32 result = 0; + + if (ctx->enhanced_mode && ctx->effects_supported) { + result |= SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE; + } + + return result; } static int @@ -564,11 +630,64 @@ HIDAPI_DriverPS4_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystic return HIDAPI_DriverPS4_UpdateEffects(device); } +static int +HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + Uint8 data[78]; + int report_size, offset; + + if (!ctx->effects_supported) { + return SDL_Unsupported(); + } + + if (!ctx->enhanced_mode) { + HIDAPI_DriverPS4_SetEnhancedMode(device, joystick); + } + + SDL_zeroa(data); + + if (ctx->is_bluetooth) { + data[0] = k_EPS4ReportIdBluetoothEffects; + data[1] = 0xC0 | 0x04; /* Magic value HID + CRC, also sets interval to 4ms for samples */ + data[3] = 0x03; /* 0x1 is rumble, 0x2 is lightbar, 0x4 is the blink interval */ + + report_size = 78; + offset = 6; + } else { + data[0] = k_EPS4ReportIdUsbEffects; + data[1] = 0x07; /* Magic value */ + + report_size = 32; + offset = 4; + } + + SDL_memcpy(&data[offset], effect, SDL_min((sizeof(data) - offset), (size_t)size)); + + if (ctx->is_bluetooth) { + /* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */ + Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */ + Uint32 unCRC; + unCRC = SDL_crc32(0, &ubHdr, 1); + unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC))); + SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC)); + } + + if (SDL_HIDAPI_SendRumble(device, data, report_size) != report_size) { + return SDL_SetError("Couldn't send rumble packet"); + } + return 0; +} + static int HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) { SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + if (!ctx->enhanced_mode) { + return SDL_Unsupported(); + } + if (enabled) { HIDAPI_DriverPS4_LoadCalibrationData(device); } @@ -578,7 +697,7 @@ HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joysti } static void -HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet) +HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet) { static const float TOUCHPAD_SCALEX = 1.0f / 1920; static const float TOUCHPAD_SCALEY = 1.0f / 920; /* This is noted as being 944 resolution, but 920 feels better */ @@ -729,8 +848,9 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device) { SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; SDL_Joystick *joystick = NULL; - Uint8 data[USB_PACKET_LENGTH]; + Uint8 data[USB_PACKET_LENGTH*2]; int size; + int packet_count = 0; if (device->num_joysticks > 0) { joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); @@ -739,10 +859,13 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device) return SDL_FALSE; } - while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { #ifdef DEBUG_PS4_PROTOCOL HIDAPI_DumpPacket("PS4 packet: size = %d", data, size); #endif + ++packet_count; + ctx->last_packet = SDL_GetTicks(); + switch (data[0]) { case k_EPS4ReportIdUsbState: HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t *)&data[1]); @@ -756,6 +879,10 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device) case k_EPS4ReportIdBluetoothState7: case k_EPS4ReportIdBluetoothState8: case k_EPS4ReportIdBluetoothState9: + if (!ctx->enhanced_mode) { + /* This is the extended report, we can enable effects now */ + HIDAPI_DriverPS4_SetEnhancedMode(device, joystick); + } /* Bluetooth state packets have two additional bytes at the beginning, the first notes if HID is present */ if (data[1] & 0x80) { HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t*)&data[3]); @@ -769,6 +896,14 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device) } } + if (ctx->is_bluetooth && packet_count == 0) { + /* Check to see if it looks like the device disconnected */ + if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { + /* Send an empty output report to tickle the Bluetooth stack */ + HIDAPI_DriverPS4_TickleBluetooth(device); + } + } + if (size < 0) { /* Read error, device is disconnected */ HIDAPI_JoystickDisconnected(device, joystick->instance_id); @@ -779,11 +914,20 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device) static void HIDAPI_DriverPS4_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - hid_close(device->dev); - device->dev = NULL; + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; - SDL_free(device->context); - device->context = NULL; + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, + SDL_PS4RumbleHintChanged, ctx); + + SDL_LockMutex(device->dev_lock); + { + SDL_hid_close(device->dev); + device->dev = NULL; + + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); } static void @@ -795,6 +939,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 = { SDL_HINT_JOYSTICK_HIDAPI_PS4, SDL_TRUE, + SDL_TRUE, HIDAPI_DriverPS4_IsSupportedDevice, HIDAPI_DriverPS4_GetDeviceName, HIDAPI_DriverPS4_InitDevice, @@ -804,8 +949,9 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 = HIDAPI_DriverPS4_OpenJoystick, HIDAPI_DriverPS4_RumbleJoystick, HIDAPI_DriverPS4_RumbleJoystickTriggers, - HIDAPI_DriverPS4_HasJoystickLED, + HIDAPI_DriverPS4_GetJoystickCapabilities, HIDAPI_DriverPS4_SetJoystickLED, + HIDAPI_DriverPS4_SendJoystickEffect, HIDAPI_DriverPS4_SetJoystickSensorsEnabled, HIDAPI_DriverPS4_CloseJoystick, HIDAPI_DriverPS4_FreeDevice, diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps5.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps5.c index fc0554124..6d7f87d59 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps5.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps5.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,6 +27,7 @@ #include "SDL_timer.h" #include "SDL_joystick.h" #include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" #include "../SDL_sysjoystick.h" #include "SDL_hidapijoystick_c.h" #include "SDL_hidapi_rumble.h" @@ -129,13 +130,12 @@ typedef struct } DS5EffectsState_t; typedef enum { - k_EDS5EffectNone, - k_EDS5EffectRumbleStart, - k_EDS5EffectRumble, - k_EDS5EffectLEDReset, - k_EDS5EffectLED, - k_EDS5EffectPadLights, - k_EDS5EffectMicLight, + k_EDS5EffectRumbleStart = (1 << 0), + k_EDS5EffectRumble = (1 << 1), + k_EDS5EffectLEDReset = (1 << 2), + k_EDS5EffectLED = (1 << 3), + k_EDS5EffectPadLights = (1 << 4), + k_EDS5EffectMicLight = (1 << 5) } EDS5Effect; typedef enum { @@ -150,12 +150,16 @@ typedef struct { } IMUCalibrationData; typedef struct { + SDL_HIDAPI_Device *device; + SDL_Joystick *joystick; SDL_bool is_bluetooth; + SDL_bool enhanced_mode; SDL_bool report_sensors; SDL_bool hardware_calibration; IMUCalibrationData calibration[6]; Uint32 last_packet; int player_index; + SDL_bool player_lights; Uint8 rumble_left; Uint8 rumble_right; SDL_bool color_set; @@ -171,6 +175,8 @@ typedef struct { } SDL_DriverPS5_Context; +static int HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size); + static SDL_bool HIDAPI_DriverPS5_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) { @@ -186,11 +192,11 @@ HIDAPI_DriverPS5_GetDeviceName(Uint16 vendor_id, Uint16 product_id) return NULL; } -static int ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *report, size_t length) +static int ReadFeatureReport(SDL_hid_device *dev, Uint8 report_id, Uint8 *report, size_t length) { SDL_memset(report, 0, length); report[0] = report_id; - return hid_get_feature_report(dev, report, length); + return SDL_hid_get_feature_report(dev, report, length); } static void @@ -204,9 +210,9 @@ SetLedsForPlayerIndex(DS5EffectsState_t *effects, int player_index) { 0x40, 0x00, 0x00 }, /* Red */ { 0x00, 0x40, 0x00 }, /* Green */ { 0x20, 0x00, 0x20 }, /* Pink */ - { 0x02, 0x01, 0x00 }, /* Orange */ - { 0x00, 0x01, 0x01 }, /* Teal */ - { 0x01, 0x01, 0x01 } /* White */ + { 0x20, 0x10, 0x00 }, /* Orange */ + { 0x00, 0x10, 0x10 }, /* Teal */ + { 0x10, 0x10, 0x10 } /* White */ }; if (player_index >= 0) { @@ -220,6 +226,24 @@ SetLedsForPlayerIndex(DS5EffectsState_t *effects, int player_index) effects->ucLedBlue = colors[player_index][2]; } +static void +SetLightsForPlayerIndex(DS5EffectsState_t *effects, int player_index) +{ + static const Uint8 lights[] = { + 0x04, + 0x0A, + 0x15, + 0x1B + }; + + if (player_index >= 0 && player_index < SDL_arraysize(lights)) { + /* Bitmask, 0x1F enables all lights, 0x20 changes instantly instead of fade */ + effects->ucPadLights = lights[player_index] | 0x20; + } else { + effects->ucPadLights = 0x00; + } +} + static SDL_bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device) { @@ -350,35 +374,20 @@ HIDAPI_DriverPS5_ApplyCalibrationData(SDL_DriverPS5_Context *ctx, int index, Sin } static int -HIDAPI_DriverPS5_UpdateEffects(SDL_HIDAPI_Device *device, EDS5Effect effect) +HIDAPI_DriverPS5_UpdateEffects(SDL_HIDAPI_Device *device, int effect_mask) { SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; - DS5EffectsState_t *effects; - Uint8 data[78]; - int report_size, offset; - Uint8 *pending_data; - int *pending_size; - int maximum_size; + DS5EffectsState_t effects; - - SDL_zero(data); - - if (ctx->is_bluetooth) { - data[0] = k_EPS5ReportIdBluetoothEffects; - data[1] = 0x02; /* Magic value */ - - report_size = 78; - offset = 2; - } else { - data[0] = k_EPS5ReportIdUsbEffects; - - report_size = 48; - offset = 1; + if (!ctx->enhanced_mode) { + return SDL_Unsupported(); } - effects = (DS5EffectsState_t *)&data[offset]; + + SDL_zero(effects); /* Make sure the Bluetooth connection sequence has completed before sending LED color change */ - if (effect == k_EDS5EffectLED && ctx->is_bluetooth) { + if (ctx->is_bluetooth && + (effect_mask & (k_EDS5EffectLED | k_EDS5EffectPadLights)) != 0) { if (ctx->led_reset_state != k_EDS5LEDResetStateComplete) { ctx->led_reset_state = k_EDS5LEDResetStatePending; return 0; @@ -386,90 +395,53 @@ HIDAPI_DriverPS5_UpdateEffects(SDL_HIDAPI_Device *device, EDS5Effect effect) } if (ctx->rumble_left || ctx->rumble_right) { - effects->ucEnableBits1 |= 0x01; /* Enable rumble emulation */ - effects->ucEnableBits1 |= 0x02; /* Disable audio haptics */ + effects.ucEnableBits1 |= 0x01; /* Enable rumble emulation */ + effects.ucEnableBits1 |= 0x02; /* Disable audio haptics */ /* Shift to reduce effective rumble strength to match Xbox controllers */ - effects->ucRumbleLeft = ctx->rumble_left >> 1; - effects->ucRumbleRight = ctx->rumble_right >> 1; + effects.ucRumbleLeft = ctx->rumble_left >> 1; + effects.ucRumbleRight = ctx->rumble_right >> 1; } else { /* Leaving emulated rumble bits off will restore audio haptics */ } - switch (effect) { - case k_EDS5EffectRumbleStart: - effects->ucEnableBits1 |= 0x02; /* Disable audio haptics */ - break; - case k_EDS5EffectRumble: + if ((effect_mask & k_EDS5EffectRumbleStart) != 0) { + effects.ucEnableBits1 |= 0x02; /* Disable audio haptics */ + } + if ((effect_mask & k_EDS5EffectRumble) != 0) { /* Already handled above */ - break; - case k_EDS5EffectLEDReset: - effects->ucEnableBits2 |= 0x08; /* Reset LED state */ - break; - case k_EDS5EffectLED: - effects->ucEnableBits2 |= 0x04; /* Enable LED color */ + } + if ((effect_mask & k_EDS5EffectLEDReset) != 0) { + effects.ucEnableBits2 |= 0x08; /* Reset LED state */ + } + if ((effect_mask & k_EDS5EffectLED) != 0) { + effects.ucEnableBits2 |= 0x04; /* Enable LED color */ /* Populate the LED state with the appropriate color from our lookup table */ if (ctx->color_set) { - effects->ucLedRed = ctx->led_red; - effects->ucLedGreen = ctx->led_green; - effects->ucLedBlue = ctx->led_blue; + effects.ucLedRed = ctx->led_red; + effects.ucLedGreen = ctx->led_green; + effects.ucLedBlue = ctx->led_blue; } else { - SetLedsForPlayerIndex(effects, ctx->player_index); - } - break; - case k_EDS5EffectPadLights: - effects->ucEnableBits2 |= 0x10; /* Enable touchpad lights */ - - effects->ucPadLights = 0x00; /* Bitmask, 0x1F enables all lights, 0x20 changes instantly instead of fade */ - break; - case k_EDS5EffectMicLight: - effects->ucEnableBits2 |= 0x01; /* Enable microphone light */ - - effects->ucMicLightMode = 0; /* Bitmask, 0x00 = off, 0x01 = solid, 0x02 = pulse */ - break; - default: - break; - } - - if (ctx->is_bluetooth) { - /* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */ - Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */ - Uint32 unCRC; - unCRC = SDL_crc32(0, &ubHdr, 1); - unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC))); - SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC)); - } - - if (SDL_HIDAPI_LockRumble() < 0) { - return -1; - } - - /* See if we can update an existing pending request */ - if (SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_data, &pending_size, &maximum_size)) { - DS5EffectsState_t *pending_effects = (DS5EffectsState_t *)&pending_data[offset]; - if (report_size == *pending_size && - effects->ucEnableBits1 == pending_effects->ucEnableBits1 && - effects->ucEnableBits2 == pending_effects->ucEnableBits2) { - /* We're simply updating the data for this request */ - SDL_memcpy(pending_data, data, report_size); - SDL_HIDAPI_UnlockRumble(); - return 0; + SetLedsForPlayerIndex(&effects, ctx->player_index); } } + if ((effect_mask & k_EDS5EffectPadLights) != 0) { + effects.ucEnableBits2 |= 0x10; /* Enable touchpad lights */ - return SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size); -} - -static void -HIDAPI_DriverPS5_SetBluetooth(SDL_HIDAPI_Device *device, SDL_bool is_bluetooth) -{ - SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; - - if (ctx->is_bluetooth != is_bluetooth) { - ctx->is_bluetooth = is_bluetooth; - HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLED); + if (ctx->player_lights) { + SetLightsForPlayerIndex(&effects, ctx->player_index); + } else { + effects.ucPadLights = 0x00; + } } + if ((effect_mask & k_EDS5EffectMicLight) != 0) { + effects.ucEnableBits2 |= 0x01; /* Enable microphone light */ + + effects.ucMicLightMode = 0; /* Bitmask, 0x00 = off, 0x01 = solid, 0x02 = pulse */ + } + + return HIDAPI_DriverPS5_SendJoystickEffect(device, ctx->joystick, &effects, sizeof(effects)); } static void @@ -479,17 +451,73 @@ HIDAPI_DriverPS5_CheckPendingLEDReset(SDL_HIDAPI_Device *device) const PS5StatePacket_t *packet = &ctx->last_state.state; /* Check the timer to make sure the Bluetooth connection LED animation is complete */ - const Uint32 connection_complete = 10000000; + const Uint32 connection_complete = 10200000; Uint32 timer = ((Uint32)packet->rgucTimer1[0] << 0) | ((Uint32)packet->rgucTimer1[1] << 8) | ((Uint32)packet->rgucTimer1[2] << 16) | ((Uint32)packet->rgucTimer1[3] << 24); - if (timer >= connection_complete) { + if (SDL_TICKS_PASSED(timer, connection_complete)) { HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLEDReset); ctx->led_reset_state = k_EDS5LEDResetStateComplete; - HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLED); + HIDAPI_DriverPS5_UpdateEffects(device, (k_EDS5EffectLED | k_EDS5EffectPadLights)); + } +} + +static void +HIDAPI_DriverPS5_TickleBluetooth(SDL_HIDAPI_Device *device) +{ + /* This is just a dummy packet that should have no effect, since we don't set the CRC */ + Uint8 data[78]; + + SDL_zeroa(data); + + data[0] = k_EPS5ReportIdBluetoothEffects; + data[1] = 0x02; /* Magic value */ + + SDL_HIDAPI_SendRumble(device, data, sizeof(data)); +} + +static void +HIDAPI_DriverPS5_SetEnhancedMode(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + + if (!ctx->enhanced_mode) { + ctx->enhanced_mode = SDL_TRUE; + + SDL_PrivateJoystickAddTouchpad(joystick, 2); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f); + + /* Switch into enhanced report mode */ + HIDAPI_DriverPS5_UpdateEffects(device, 0); + + /* Update the light effects */ + HIDAPI_DriverPS5_UpdateEffects(device, (k_EDS5EffectLED | k_EDS5EffectPadLights)); + } +} + +static void SDLCALL SDL_PS5RumbleHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)userdata; + + /* This is a one-way trip, you can't switch the controller back to simple report mode */ + if (SDL_GetStringBoolean(hint, SDL_FALSE)) { + HIDAPI_DriverPS5_SetEnhancedMode(ctx->device, ctx->joystick); + } +} + +static void SDLCALL SDL_PS5PlayerLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)userdata; + SDL_bool player_lights = SDL_GetStringBoolean(hint, SDL_TRUE); + + if (player_lights != ctx->player_lights) { + ctx->player_lights = player_lights; + + HIDAPI_DriverPS5_UpdateEffects(ctx->device, k_EDS5EffectPadLights); } } @@ -505,23 +533,27 @@ HIDAPI_DriverPS5_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID ctx->player_index = player_index; /* This will set the new LED state based on the new player index */ - HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLED); + HIDAPI_DriverPS5_UpdateEffects(device, (k_EDS5EffectLED | k_EDS5EffectPadLights)); } static SDL_bool HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { SDL_DriverPS5_Context *ctx; - Uint8 data[USB_PACKET_LENGTH]; + Uint8 data[USB_PACKET_LENGTH*2]; + int size; + SDL_bool enhanced_mode = SDL_FALSE; ctx = (SDL_DriverPS5_Context *)SDL_calloc(1, sizeof(*ctx)); if (!ctx) { SDL_OutOfMemory(); return SDL_FALSE; } + ctx->device = device; + ctx->joystick = joystick; ctx->last_packet = SDL_GetTicks(); - device->dev = hid_open_path(device->path, 0); + device->dev = SDL_hid_open_path(device->path, 0); if (!device->dev) { SDL_free(ctx); SDL_SetError("Couldn't open %s", device->path); @@ -529,31 +561,84 @@ HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) } device->context = ctx; - /* Read the serial number (Bluetooth address in reverse byte order) - This will also enable enhanced reports over Bluetooth - */ - if (ReadFeatureReport(device->dev, k_EPS5FeatureReportIdSerialNumber, data, sizeof(data)) >= 7) { + /* Read a report to see what mode we're in */ + size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16); +#ifdef DEBUG_PS5_PROTOCOL + if (size > 0) { + HIDAPI_DumpPacket("PS5 first packet: size = %d", data, size); + } else { + SDL_Log("PS5 first packet: size = %d\n", size); + } +#endif + if (size == 64) { + /* Connected over USB */ + ctx->is_bluetooth = SDL_FALSE; + enhanced_mode = SDL_TRUE; + } else if (size > 0 && data[0] == k_EPS5ReportIdBluetoothEffects) { + /* Connected over Bluetooth, using enhanced reports */ + ctx->is_bluetooth = SDL_TRUE; + enhanced_mode = SDL_TRUE; + } else { + /* Connected over Bluetooth, using simple reports (DirectInput enabled) */ + ctx->is_bluetooth = SDL_TRUE; + + /* Games written prior the introduction of PS5 controller support in SDL will not be aware of + SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, but they did know SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE. + To support apps that only knew about the PS4 hint, we'll use the PS4 hint as the default. + */ + enhanced_mode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, + SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, SDL_FALSE)); + } + + if (enhanced_mode) { + /* Read the serial number (Bluetooth address in reverse byte order) + This will also enable enhanced reports over Bluetooth + */ + if (ReadFeatureReport(device->dev, k_EPS5FeatureReportIdSerialNumber, data, sizeof(data)) >= 7) { + char serial[18]; + + SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + data[6], data[5], data[4], data[3], data[2], data[1]); + joystick->serial = SDL_strdup(serial); + } + } + + if (!joystick->serial && device->serial && SDL_strlen(device->serial) == 12) { + int i, j; char serial[18]; - SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", - data[6], data[5], data[4], data[3], data[2], data[1]); + j = -1; + for (i = 0; i < 12; i += 2) { + j += 1; + SDL_memcpy(&serial[j], &device->serial[i], 2); + j += 2; + serial[j] = '-'; + } + serial[j] = '\0'; + joystick->serial = SDL_strdup(serial); } /* Initialize player index (needed for setting LEDs) */ ctx->player_index = SDL_JoystickGetPlayerIndex(joystick); + ctx->player_lights = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED, SDL_TRUE); - /* Initialize LED and effect state */ - HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLED); - - /* Initialize the joystick capabilities */ + /* Initialize the joystick capabilities + * + * We can't dynamically add the touchpad button, so always report it here + */ joystick->nbuttons = 17; joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = ctx->is_bluetooth ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED; - SDL_PrivateJoystickAddTouchpad(joystick, 2); - SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO); - SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL); - + if (enhanced_mode) { + HIDAPI_DriverPS5_SetEnhancedMode(device, joystick); + } else { + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, + SDL_PS5RumbleHintChanged, ctx); + } + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED, + SDL_PS5PlayerLEDHintChanged, ctx); return SDL_TRUE; } @@ -578,10 +663,17 @@ HIDAPI_DriverPS5_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick return SDL_Unsupported(); } -static SDL_bool -HIDAPI_DriverPS5_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +static Uint32 +HIDAPI_DriverPS5_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - return SDL_FALSE; + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + Uint32 result = 0; + + if (ctx->enhanced_mode) { + result |= SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE; + } + + return result; } static int @@ -597,11 +689,76 @@ HIDAPI_DriverPS5_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystic return HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLED); } +static int +HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + Uint8 data[78]; + int report_size, offset; + Uint8 *pending_data; + int *pending_size; + int maximum_size; + + if (!ctx->enhanced_mode) { + HIDAPI_DriverPS5_SetEnhancedMode(device, joystick); + } + + SDL_zeroa(data); + + if (ctx->is_bluetooth) { + data[0] = k_EPS5ReportIdBluetoothEffects; + data[1] = 0x02; /* Magic value */ + + report_size = 78; + offset = 2; + } else { + data[0] = k_EPS5ReportIdUsbEffects; + + report_size = 48; + offset = 1; + } + + SDL_memcpy(&data[offset], effect, SDL_min((sizeof(data) - offset), (size_t)size)); + + if (ctx->is_bluetooth) { + /* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */ + Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */ + Uint32 unCRC; + unCRC = SDL_crc32(0, &ubHdr, 1); + unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC))); + SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC)); + } + + if (SDL_HIDAPI_LockRumble() < 0) { + return -1; + } + + /* See if we can update an existing pending request */ + if (SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_data, &pending_size, &maximum_size)) { + DS5EffectsState_t *effects = (DS5EffectsState_t *)&data[offset]; + DS5EffectsState_t *pending_effects = (DS5EffectsState_t *)&pending_data[offset]; + if (report_size == *pending_size && + effects->ucEnableBits1 == pending_effects->ucEnableBits1 && + effects->ucEnableBits2 == pending_effects->ucEnableBits2) { + /* We're simply updating the data for this request */ + SDL_memcpy(pending_data, data, report_size); + SDL_HIDAPI_UnlockRumble(); + return 0; + } + } + + return SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size); +} + static int HIDAPI_DriverPS5_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) { SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + if (!ctx->enhanced_mode) { + return SDL_Unsupported(); + } + if (enabled) { HIDAPI_DriverPS5_LoadCalibrationData(device); } @@ -611,7 +768,7 @@ HIDAPI_DriverPS5_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joysti } static void -HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverPS5_Context *ctx, PS5SimpleStatePacket_t *packet) +HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5SimpleStatePacket_t *packet) { Sint16 axis; @@ -705,7 +862,7 @@ HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, hid_device *dev } static void -HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacket_t *packet) +HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacket_t *packet) { static const float TOUCHPAD_SCALEX = 1.0f / 1920; static const float TOUCHPAD_SCALEY = 1.0f / 1070; @@ -783,8 +940,8 @@ HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_ Uint8 data = packet->rgucButtonsAndHat[2]; SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, 15, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, 16, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, 15, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, 16, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); } axis = ((int)packet->ucTriggerLeft * 257) - 32768; @@ -860,7 +1017,7 @@ HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device) return SDL_FALSE; } - while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { #ifdef DEBUG_PS5_PROTOCOL HIDAPI_DumpPacket("PS5 packet: size = %d", data, size); #endif @@ -869,20 +1026,21 @@ HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device) switch (data[0]) { case k_EPS5ReportIdState: - if (size == 10) { - HIDAPI_DriverPS5_SetBluetooth(device, SDL_TRUE); /* Simple state packet over Bluetooth */ + if (size == 10 || size == 78) { HIDAPI_DriverPS5_HandleSimpleStatePacket(joystick, device->dev, ctx, (PS5SimpleStatePacket_t *)&data[1]); } else { - HIDAPI_DriverPS5_SetBluetooth(device, SDL_FALSE); HIDAPI_DriverPS5_HandleStatePacket(joystick, device->dev, ctx, (PS5StatePacket_t *)&data[1]); } break; case k_EPS5ReportIdBluetoothState: - HIDAPI_DriverPS5_SetBluetooth(device, SDL_TRUE); - HIDAPI_DriverPS5_HandleStatePacket(joystick, device->dev, ctx, (PS5StatePacket_t *)&data[2]); + if (!ctx->enhanced_mode) { + /* This is the extended report, we can enable effects now */ + HIDAPI_DriverPS5_SetEnhancedMode(device, joystick); + } if (ctx->led_reset_state == k_EDS5LEDResetStatePending) { HIDAPI_DriverPS5_CheckPendingLEDReset(device); } + HIDAPI_DriverPS5_HandleStatePacket(joystick, device->dev, ctx, (PS5StatePacket_t *)&data[2]); break; default: #ifdef DEBUG_JOYSTICK @@ -896,7 +1054,7 @@ HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device) /* Check to see if it looks like the device disconnected */ if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { /* Send an empty output report to tickle the Bluetooth stack */ - HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectNone); + HIDAPI_DriverPS5_TickleBluetooth(device); } } @@ -910,11 +1068,23 @@ HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device) static void HIDAPI_DriverPS5_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - hid_close(device->dev); - device->dev = NULL; + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; - SDL_free(device->context); - device->context = NULL; + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, + SDL_PS5RumbleHintChanged, ctx); + + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED, + SDL_PS5PlayerLEDHintChanged, ctx); + + SDL_LockMutex(device->dev_lock); + { + SDL_hid_close(device->dev); + device->dev = NULL; + + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); } static void @@ -926,6 +1096,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 = { SDL_HINT_JOYSTICK_HIDAPI_PS5, SDL_TRUE, + SDL_TRUE, HIDAPI_DriverPS5_IsSupportedDevice, HIDAPI_DriverPS5_GetDeviceName, HIDAPI_DriverPS5_InitDevice, @@ -935,8 +1106,9 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 = HIDAPI_DriverPS5_OpenJoystick, HIDAPI_DriverPS5_RumbleJoystick, HIDAPI_DriverPS5_RumbleJoystickTriggers, - HIDAPI_DriverPS5_HasJoystickLED, + HIDAPI_DriverPS5_GetJoystickCapabilities, HIDAPI_DriverPS5_SetJoystickLED, + HIDAPI_DriverPS5_SendJoystickEffect, HIDAPI_DriverPS5_SetJoystickSensorsEnabled, HIDAPI_DriverPS5_CloseJoystick, HIDAPI_DriverPS5_FreeDevice, diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_rumble.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_rumble.c index 3a3c2e243..bf376277e 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_rumble.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_rumble.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,6 +25,7 @@ /* Handle rumble on a separate thread so it doesn't block the application */ #include "SDL_thread.h" +#include "SDL_timer.h" #include "SDL_hidapijoystick_c.h" #include "SDL_hidapi_rumble.h" #include "../../thread/SDL_systhread.h" @@ -76,11 +77,17 @@ static int SDL_HIDAPI_RumbleThread(void *data) if (request) { SDL_LockMutex(request->device->dev_lock); if (request->device->dev) { - hid_write( request->device->dev, request->data, request->size ); +#ifdef DEBUG_RUMBLE + HIDAPI_DumpPacket("Rumble packet: size = %d", request->data, request->size); +#endif + SDL_hid_write(request->device->dev, request->data, request->size); } SDL_UnlockMutex(request->device->dev_lock); (void)SDL_AtomicDecRef(&request->device->rumble_pending); SDL_free(request); + + /* Make sure we're not starving report reads when there's lots of rumble */ + SDL_Delay(10); } } return 0; diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_rumble.h b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_rumble.h index 9b14da098..b04794a9a 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_rumble.h +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_rumble.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_stadia.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_stadia.c new file mode 100644 index 000000000..0a5c2584f --- /dev/null +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_stadia.c @@ -0,0 +1,331 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_hints.h" +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + + +#ifdef SDL_JOYSTICK_HIDAPI_STADIA + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_STADIA_PROTOCOL*/ + +enum +{ + SDL_CONTROLLER_BUTTON_STADIA_SHARE = 15, + SDL_CONTROLLER_BUTTON_STADIA_GOOGLE_ASSISTANT, + SDL_CONTROLLER_NUM_STADIA_BUTTONS, +}; + +typedef struct { + Uint8 last_state[USB_PACKET_LENGTH]; +} SDL_DriverStadia_Context; + + +static SDL_bool +HIDAPI_DriverStadia_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + return (type == SDL_CONTROLLER_TYPE_GOOGLE_STADIA) ? SDL_TRUE : SDL_FALSE; +} + +static const char * +HIDAPI_DriverStadia_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +{ + return "Google Stadia Controller"; +} + +static SDL_bool +HIDAPI_DriverStadia_InitDevice(SDL_HIDAPI_Device *device) +{ + return HIDAPI_JoystickConnected(device, NULL); +} + +static int +HIDAPI_DriverStadia_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void +HIDAPI_DriverStadia_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ +} + +static SDL_bool +HIDAPI_DriverStadia_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverStadia_Context *ctx; + + ctx = (SDL_DriverStadia_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + + device->dev = SDL_hid_open_path(device->path, 0); + if (!device->dev) { + SDL_SetError("Couldn't open %s", device->path); + SDL_free(ctx); + return SDL_FALSE; + } + device->context = ctx; + + /* Initialize the joystick capabilities */ + joystick->nbuttons = SDL_CONTROLLER_NUM_STADIA_BUTTONS; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + + return SDL_TRUE; +} + +static int +HIDAPI_DriverStadia_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + Uint8 rumble_packet[] = { 0x05, 0x00, 0x00, 0x00, 0x00 }; + + rumble_packet[1] = (low_frequency_rumble & 0xFF); + rumble_packet[2] = (low_frequency_rumble >> 8); + rumble_packet[3] = (high_frequency_rumble & 0xFF); + rumble_packet[4] = (high_frequency_rumble >> 8); + + if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } + return 0; +} + +static int +HIDAPI_DriverStadia_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 +HIDAPI_DriverStadia_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + return SDL_JOYCAP_RUMBLE; +} + +static int +HIDAPI_DriverStadia_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int +HIDAPI_DriverStadia_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int +HIDAPI_DriverStadia_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void +HIDAPI_DriverStadia_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverStadia_Context *ctx, Uint8 *data, int size) +{ + Sint16 axis; + + // The format is the same but the original FW will send 10 bytes and January '21 FW update will send 11 + if (size < 10 || data[0] != 0x03) { + /* We don't know how to handle this report */ + return; + } + + if (ctx->last_state[1] != data[1]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[1]) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + + if (ctx->last_state[2] != data[2]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[2] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[2] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[2] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[2] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_STADIA_SHARE, (data[2] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_STADIA_GOOGLE_ASSISTANT, (data[2] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[3] != data[3]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[3] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[3] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[3] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[3] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[3] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[3] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[3] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } + +#define READ_STICK_AXIS(offset) \ + (data[offset] == 0x80 ? 0 : \ + (Sint16)HIDAPI_RemapVal((float)((int)data[offset] - 0x80), 0x01 - 0x80, 0xff - 0x80, SDL_MIN_SINT16, SDL_MAX_SINT16)) + { + axis = READ_STICK_AXIS(4); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = READ_STICK_AXIS(5); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = READ_STICK_AXIS(6); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = READ_STICK_AXIS(7); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + } +#undef READ_STICK_AXIS + +#define READ_TRIGGER_AXIS(offset) \ + (Sint16)(((int)data[offset] * 257) - 32768) + { + axis = READ_TRIGGER_AXIS(8); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = READ_TRIGGER_AXIS(9); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + } +#undef READ_TRIGGER_AXIS + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static SDL_bool +HIDAPI_DriverStadia_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverStadia_Context *ctx = (SDL_DriverStadia_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH]; + int size = 0; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } + if (!joystick) { + return SDL_FALSE; + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_STADIA_PROTOCOL + HIDAPI_DumpPacket("Google Stadia packet: size = %d", data, size); +#endif + HIDAPI_DriverStadia_HandleStatePacket(joystick, ctx, data, size); + } + + if (size < 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, joystick->instance_id); + } + return (size >= 0); +} + +static void +HIDAPI_DriverStadia_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_LockMutex(device->dev_lock); + { + if (device->dev) { + SDL_hid_close(device->dev); + device->dev = NULL; + } + + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); +} + +static void +HIDAPI_DriverStadia_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia = +{ + SDL_HINT_JOYSTICK_HIDAPI_STADIA, + SDL_TRUE, + SDL_TRUE, + HIDAPI_DriverStadia_IsSupportedDevice, + HIDAPI_DriverStadia_GetDeviceName, + HIDAPI_DriverStadia_InitDevice, + HIDAPI_DriverStadia_GetDevicePlayerIndex, + HIDAPI_DriverStadia_SetDevicePlayerIndex, + HIDAPI_DriverStadia_UpdateDevice, + HIDAPI_DriverStadia_OpenJoystick, + HIDAPI_DriverStadia_RumbleJoystick, + HIDAPI_DriverStadia_RumbleJoystickTriggers, + HIDAPI_DriverStadia_GetJoystickCapabilities, + HIDAPI_DriverStadia_SetJoystickLED, + HIDAPI_DriverStadia_SendJoystickEffect, + HIDAPI_DriverStadia_SetJoystickSensorsEnabled, + HIDAPI_DriverStadia_CloseJoystick, + HIDAPI_DriverStadia_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_STADIA */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_steam.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_steam.c index 87827f476..b69c598dc 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_steam.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_steam.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -190,7 +190,7 @@ typedef struct // Wireless firmware quirk: the firmware intentionally signals "failure" when performing -// SET_FEATURE / GET_FEATURE when it actually means "pending radio round-trip". The only +// SET_FEATURE / GET_FEATURE when it actually means "pending radio roundtrip". The only // way to make SET_FEATURE / GET_FEATURE work is to loop several times with a sleep. If // it takes more than 50ms to get the response for SET_FEATURE / GET_FEATURE, we assume // that the controller has failed. @@ -220,7 +220,7 @@ static void hexdump( const uint8_t *ptr, int len ) static void ResetSteamControllerPacketAssembler( SteamControllerPacketAssembler *pAssembler ) { - memset( pAssembler->uBuffer, 0, sizeof( pAssembler->uBuffer ) ); + SDL_memset( pAssembler->uBuffer, 0, sizeof( pAssembler->uBuffer ) ); pAssembler->nExpectedSegmentNumber = 0; } @@ -239,6 +239,9 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs { if ( pAssembler->bIsBle ) { + uint8_t uSegmentHeader = pSegment[ 1 ]; + int nSegmentNumber = uSegmentHeader & 0x07; + HEXDUMP( pSegment, nSegmentLength ); if ( pSegment[ 0 ] != BLE_REPORT_NUMBER ) @@ -255,7 +258,6 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs return -1; } - uint8_t uSegmentHeader = pSegment[ 1 ]; DPRINTF("GOT PACKET HEADER = 0x%x\n", uSegmentHeader); if ( ( uSegmentHeader & REPORT_SEGMENT_DATA_FLAG ) == 0 ) @@ -264,7 +266,6 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs return 0; } - int nSegmentNumber = uSegmentHeader & 0x07; if ( nSegmentNumber != pAssembler->nExpectedSegmentNumber ) { ResetSteamControllerPacketAssembler( pAssembler ); @@ -278,7 +279,7 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs } } - memcpy( pAssembler->uBuffer + nSegmentNumber * MAX_REPORT_SEGMENT_PAYLOAD_SIZE, + SDL_memcpy( pAssembler->uBuffer + nSegmentNumber * MAX_REPORT_SEGMENT_PAYLOAD_SIZE, pSegment + 2, // ignore header and report number MAX_REPORT_SEGMENT_PAYLOAD_SIZE ); @@ -293,7 +294,7 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs else { // Just pass through - memcpy( pAssembler->uBuffer, + SDL_memcpy( pAssembler->uBuffer, pSegment, nSegmentLength ); return nSegmentLength; @@ -304,22 +305,23 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs #define BLE_MAX_READ_RETRIES 8 -static int SetFeatureReport( hid_device *dev, unsigned char uBuffer[65], int nActualDataLen ) +static int SetFeatureReport( SDL_hid_device *dev, unsigned char uBuffer[65], int nActualDataLen ) { - DPRINTF("SetFeatureReport %p %p %d\n", dev, uBuffer, nActualDataLen); int nRet = -1; bool bBle = true; // only wireless/BLE for now, though macOS could do wired in the future + DPRINTF("SetFeatureReport %p %p %d\n", dev, uBuffer, nActualDataLen); + if ( bBle ) { + int nSegmentNumber = 0; + uint8_t uPacketBuffer[ MAX_REPORT_SEGMENT_SIZE ]; + unsigned char *pBufferPtr = uBuffer + 1; + if ( nActualDataLen < 1 ) return -1; - int nSegmentNumber = 0; - uint8_t uPacketBuffer[ MAX_REPORT_SEGMENT_SIZE ]; - // Skip report number in data - unsigned char *pBufferPtr = uBuffer + 1; nActualDataLen--; while ( nActualDataLen > 0 ) @@ -329,15 +331,15 @@ static int SetFeatureReport( hid_device *dev, unsigned char uBuffer[65], int nAc nActualDataLen -= nBytesInPacket; // Construct packet - memset( uPacketBuffer, 0, sizeof( uPacketBuffer ) ); + SDL_memset( uPacketBuffer, 0, sizeof( uPacketBuffer ) ); uPacketBuffer[ 0 ] = BLE_REPORT_NUMBER; uPacketBuffer[ 1 ] = GetSegmentHeader( nSegmentNumber, nActualDataLen == 0 ); - memcpy( &uPacketBuffer[ 2 ], pBufferPtr, nBytesInPacket ); + SDL_memcpy( &uPacketBuffer[ 2 ], pBufferPtr, nBytesInPacket ); pBufferPtr += nBytesInPacket; nSegmentNumber++; - nRet = hid_send_feature_report( dev, uPacketBuffer, sizeof( uPacketBuffer ) ); + nRet = SDL_hid_send_feature_report( dev, uPacketBuffer, sizeof( uPacketBuffer ) ); DPRINTF("SetFeatureReport() ret = %d\n", nRet); } } @@ -345,24 +347,26 @@ static int SetFeatureReport( hid_device *dev, unsigned char uBuffer[65], int nAc return nRet; } -static int GetFeatureReport( hid_device *dev, unsigned char uBuffer[65] ) +static int GetFeatureReport( SDL_hid_device *dev, unsigned char uBuffer[65] ) { - DPRINTF("GetFeatureReport( %p %p )\n", dev, uBuffer ); int nRet = -1; bool bBle = true; + DPRINTF("GetFeatureReport( %p %p )\n", dev, uBuffer ); + if ( bBle ) { + int nRetries = 0; + uint8_t uSegmentBuffer[ MAX_REPORT_SEGMENT_SIZE ]; + SteamControllerPacketAssembler assembler; InitializeSteamControllerPacketAssembler( &assembler ); - int nRetries = 0; - uint8_t uSegmentBuffer[ MAX_REPORT_SEGMENT_SIZE ]; while( nRetries < BLE_MAX_READ_RETRIES ) { - memset( uSegmentBuffer, 0, sizeof( uSegmentBuffer ) ); + SDL_memset( uSegmentBuffer, 0, sizeof( uSegmentBuffer ) ); uSegmentBuffer[ 0 ] = BLE_REPORT_NUMBER; - nRet = hid_get_feature_report( dev, uSegmentBuffer, sizeof( uSegmentBuffer ) ); + nRet = SDL_hid_get_feature_report( dev, uSegmentBuffer, sizeof( uSegmentBuffer ) ); DPRINTF( "GetFeatureReport ble ret=%d\n", nRet ); HEXDUMP( uSegmentBuffer, nRet ); @@ -382,7 +386,7 @@ static int GetFeatureReport( hid_device *dev, unsigned char uBuffer[65] ) { // Leave space for "report number" uBuffer[ 0 ] = 0; - memcpy( uBuffer + 1, assembler.uBuffer, nPacketLength ); + SDL_memcpy( uBuffer + 1, assembler.uBuffer, nPacketLength ); return nPacketLength; } } @@ -396,11 +400,12 @@ static int GetFeatureReport( hid_device *dev, unsigned char uBuffer[65] ) return nRet; } -static int ReadResponse( hid_device *dev, uint8_t uBuffer[65], int nExpectedResponse ) +static int ReadResponse( SDL_hid_device *dev, uint8_t uBuffer[65], int nExpectedResponse ) { - DPRINTF("ReadResponse( %p %p %d )\n", dev, uBuffer, nExpectedResponse ); int nRet = GetFeatureReport( dev, uBuffer ); + DPRINTF("ReadResponse( %p %p %d )\n", dev, uBuffer, nExpectedResponse ); + if ( nRet < 0 ) return nRet; @@ -416,13 +421,18 @@ static int ReadResponse( hid_device *dev, uint8_t uBuffer[65], int nExpectedResp //--------------------------------------------------------------------------- // Reset steam controller (unmap buttons and pads) and re-fetch capability bits //--------------------------------------------------------------------------- -static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew ) +static bool ResetSteamController( SDL_hid_device *dev, bool bSuppressErrorSpew, uint32_t *punUpdateRateUS ) { - DPRINTF( "ResetSteamController hid=%p\n", dev ); // Firmware quirk: Set Feature and Get Feature requests always require a 65-byte buffer. unsigned char buf[65]; - int res = -1; + int res = -1, i; + int nSettings = 0; + int nAttributesLength; + FeatureReportMsg *msg; + uint32_t unUpdateRateUS = 9000; // Good default rate + DPRINTF( "ResetSteamController hid=%p\n", dev ); + buf[0] = 0; buf[1] = ID_GET_ATTRIBUTES_VALUES; res = SetFeatureReport( dev, buf, 2 ); @@ -444,14 +454,40 @@ static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew ) return false; } - int nAttributesLength = buf[ 2 ]; + nAttributesLength = buf[ 2 ]; if ( nAttributesLength > res ) { if ( !bSuppressErrorSpew ) printf( "Bad GET_ATTRIBUTES_VALUES response for controller %p\n", dev ); return false; } - + + msg = (FeatureReportMsg *)&buf[1]; + for ( i = 0; i < (int)msg->header.length / sizeof( ControllerAttribute ); ++i ) + { + uint8_t unAttribute = msg->payload.getAttributes.attributes[i].attributeTag; + uint32_t unValue = msg->payload.getAttributes.attributes[i].attributeValue; + + switch ( unAttribute ) + { + case ATTRIB_UNIQUE_ID: + break; + case ATTRIB_PRODUCT_ID: + break; + case ATTRIB_CAPABILITIES: + break; + case ATTRIB_CONNECTION_INTERVAL_IN_US: + unUpdateRateUS = unValue; + break; + default: + break; + } + } + if ( punUpdateRateUS ) + { + *punUpdateRateUS = unUpdateRateUS; + } + // Clear digital button mappings buf[0] = 0; buf[1] = ID_CLEAR_DIGITAL_MAPPINGS; @@ -464,7 +500,7 @@ static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew ) } // Reset the default settings - memset( buf, 0, 65 ); + SDL_memset( buf, 0, 65 ); buf[1] = ID_LOAD_DEFAULT_SETTINGS; buf[2] = 0; res = SetFeatureReport( dev, buf, 3 ); @@ -476,14 +512,13 @@ static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew ) } // Apply custom settings - clear trackpad modes (cancel mouse emulation), etc - int nSettings = 0; #define ADD_SETTING(SETTING, VALUE) \ buf[3+nSettings*3] = SETTING; \ buf[3+nSettings*3+1] = ((uint16_t)VALUE)&0xFF; \ buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \ ++nSettings; - memset( buf, 0, 65 ); + SDL_memset( buf, 0, 65 ); buf[1] = ID_SET_SETTINGS_VALUES; ADD_SETTING( SETTING_WIRELESS_PACKET_VERSION, 2 ); ADD_SETTING( SETTING_LEFT_TRACKPAD_MODE, TRACKPAD_NONE ); @@ -512,7 +547,7 @@ buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \ int iRetry; for ( iRetry = 0; iRetry < 2; ++iRetry ) { - memset( buf, 0, 65 ); + SDL_memset( buf, 0, 65 ); buf[1] = ID_GET_DIGITAL_MAPPINGS; buf[2] = 1; // one byte - requesting from index 0 buf[3] = 0; @@ -545,7 +580,7 @@ buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \ } // Set our new mappings - memset( buf, 0, 65 ); + SDL_memset( buf, 0, 65 ); buf[1] = ID_SET_DIGITAL_MAPPINGS; buf[2] = 6; // 2 settings x 3 bytes buf[3] = IO_DIGITAL_BUTTON_RIGHT_TRIGGER; @@ -571,36 +606,36 @@ buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \ //--------------------------------------------------------------------------- // Read from a Steam Controller //--------------------------------------------------------------------------- -static int ReadSteamController( hid_device *dev, uint8_t *pData, int nDataSize ) +static int ReadSteamController( SDL_hid_device *dev, uint8_t *pData, int nDataSize ) { - memset( pData, 0, nDataSize ); + SDL_memset( pData, 0, nDataSize ); pData[ 0 ] = BLE_REPORT_NUMBER; // hid_read will also overwrite this with the same value, 0x03 - return hid_read( dev, pData, nDataSize ); + return SDL_hid_read( dev, pData, nDataSize ); } //--------------------------------------------------------------------------- // Close a Steam Controller //--------------------------------------------------------------------------- -static void CloseSteamController( hid_device *dev ) +static void CloseSteamController( SDL_hid_device *dev ) { // Switch the Steam Controller back to lizard mode so it works with the OS unsigned char buf[65]; int nSettings = 0; // Reset digital button mappings - memset( buf, 0, 65 ); + SDL_memset( buf, 0, 65 ); buf[1] = ID_SET_DEFAULT_DIGITAL_MAPPINGS; SetFeatureReport( dev, buf, 2 ); // Reset the default settings - memset( buf, 0, 65 ); + SDL_memset( buf, 0, 65 ); buf[1] = ID_LOAD_DEFAULT_SETTINGS; buf[2] = 0; SetFeatureReport( dev, buf, 3 ); // Reset mouse mode for lizard mode - memset( buf, 0, 65 ); + SDL_memset( buf, 0, 65 ); buf[1] = ID_SET_SETTINGS_VALUES; ADD_SETTING( SETTING_RIGHT_TRACKPAD_MODE, TRACKPAD_ABSOLUTE_MOUSE ); buf[2] = nSettings*3; @@ -651,14 +686,23 @@ static void RotatePadShort( short *pX, short *pY, float flAngleInRad ) //--------------------------------------------------------------------------- static void FormatStatePacketUntilGyro( SteamControllerStateInternal_t *pState, ValveControllerStatePacket_t *pStatePacket ) { - memset(pState, 0, offsetof(SteamControllerStateInternal_t, sBatteryLevel)); + int nLeftPadX; + int nLeftPadY; + int nRightPadX; + int nRightPadY; + int nPadOffset; + + // 15 degrees in rad + const float flRotationAngle = 0.261799f; + + SDL_memset(pState, 0, offsetof(SteamControllerStateInternal_t, sBatteryLevel)); //pState->eControllerType = m_eControllerType; pState->eControllerType = 2; // k_eControllerType_SteamController; pState->unPacketNum = pStatePacket->unPacketNum; // We have a chunk of trigger data in the packet format here, so zero it out afterwards - memcpy(&pState->ulButtons, &pStatePacket->ButtonTriggerData.ulButtons, 8); + SDL_memcpy(&pState->ulButtons, &pStatePacket->ButtonTriggerData.ulButtons, 8); pState->ulButtons &= ~0xFFFF000000LL; // The firmware uses this bit to tell us what kind of data is packed into the left two axises @@ -735,18 +779,14 @@ static void FormatStatePacketUntilGyro( SteamControllerStateInternal_t *pState, pState->sRightPadX = pStatePacket->sRightPadX; pState->sRightPadY = pStatePacket->sRightPadY; - int nLeftPadX = pState->sLeftPadX; - int nLeftPadY = pState->sLeftPadY; - int nRightPadX = pState->sRightPadX; - int nRightPadY = pState->sRightPadY; - - // 15 degrees in rad - const float flRotationAngle = 0.261799f; + nLeftPadX = pState->sLeftPadX; + nLeftPadY = pState->sLeftPadY; + nRightPadX = pState->sRightPadX; + nRightPadY = pState->sRightPadY; RotatePad(&nLeftPadX, &nLeftPadY, -flRotationAngle); RotatePad(&nRightPadX, &nRightPadY, flRotationAngle); - int nPadOffset; if (pState->ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK) nPadOffset = 1000; else @@ -782,7 +822,7 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize, ucOptionDataMask |= (uint32_t)(*pData++) << 8; if ( ucOptionDataMask & k_EBLEButtonChunk1 ) { - memcpy( &pState->ulButtons, pData, 3 ); + SDL_memcpy( &pState->ulButtons, pData, 3 ); pData += 3; } if ( ucOptionDataMask & k_EBLEButtonChunk2 ) @@ -804,14 +844,14 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize, // This doesn't handle any of the special headcrab stuff for raw joystick which is OK for now since that FW doesn't support // this protocol yet either int nLength = sizeof( pState->sLeftStickX ) + sizeof( pState->sLeftStickY ); - memcpy( &pState->sLeftStickX, pData, nLength ); + SDL_memcpy( &pState->sLeftStickX, pData, nLength ); pData += nLength; } if ( ucOptionDataMask & k_EBLELeftTrackpadChunk ) { int nLength = sizeof( pState->sLeftPadX ) + sizeof( pState->sLeftPadY ); int nPadOffset; - memcpy( &pState->sLeftPadX, pData, nLength ); + SDL_memcpy( &pState->sLeftPadX, pData, nLength ); if ( pState->ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK ) nPadOffset = 1000; else @@ -827,7 +867,7 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize, int nLength = sizeof( pState->sRightPadX ) + sizeof( pState->sRightPadY ); int nPadOffset = 0; - memcpy( &pState->sRightPadX, pData, nLength ); + SDL_memcpy( &pState->sRightPadX, pData, nLength ); if ( pState->ulButtons & STEAM_RIGHTPAD_FINGERDOWN_MASK ) nPadOffset = 1000; @@ -842,19 +882,19 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize, if ( ucOptionDataMask & k_EBLEIMUAccelChunk ) { int nLength = sizeof( pState->sAccelX ) + sizeof( pState->sAccelY ) + sizeof( pState->sAccelZ ); - memcpy( &pState->sAccelX, pData, nLength ); + SDL_memcpy( &pState->sAccelX, pData, nLength ); pData += nLength; } if ( ucOptionDataMask & k_EBLEIMUGyroChunk ) { int nLength = sizeof( pState->sAccelX ) + sizeof( pState->sAccelY ) + sizeof( pState->sAccelZ ); - memcpy( &pState->sGyroX, pData, nLength ); + SDL_memcpy( &pState->sGyroX, pData, nLength ); pData += nLength; } if ( ucOptionDataMask & k_EBLEIMUQuatChunk ) { int nLength = sizeof( pState->sGyroQuatW ) + sizeof( pState->sGyroQuatX ) + sizeof( pState->sGyroQuatY ) + sizeof( pState->sGyroQuatZ ); - memcpy( &pState->sGyroQuatW, pData, nLength ); + SDL_memcpy( &pState->sGyroQuatW, pData, nLength ); pData += nLength; } return true; @@ -950,6 +990,7 @@ static bool UpdateSteamControllerState( const uint8_t *pData, int nDataSize, Ste /*****************************************************************************************************/ typedef struct { + SDL_bool report_sensors; SteamControllerPacketAssembler m_assembler; SteamControllerStateInternal_t m_state; SteamControllerStateInternal_t m_last_state; @@ -989,6 +1030,8 @@ static SDL_bool HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { SDL_DriverSteam_Context *ctx; + uint32_t update_rate_in_us = 0; + float update_rate_in_hz = 0.0f; ctx = (SDL_DriverSteam_Context *)SDL_calloc(1, sizeof(*ctx)); if (!ctx) { @@ -997,15 +1040,20 @@ HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic } device->context = ctx; - device->dev = hid_open_path(device->path, 0); + device->dev = SDL_hid_open_path(device->path, 0); if (!device->dev) { SDL_SetError("Couldn't open %s", device->path); goto error; } + SDL_hid_set_nonblocking(device->dev, 1); - if (!ResetSteamController(device->dev, false)) { + if (!ResetSteamController(device->dev, false, &update_rate_in_us)) { + SDL_SetError("Couldn't reset controller"); goto error; } + if (update_rate_in_us > 0) { + update_rate_in_hz = 1000000.0f / update_rate_in_us; + } InitializeSteamControllerPacketAssembler(&ctx->m_assembler); @@ -1013,17 +1061,24 @@ HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic joystick->nbuttons = 17; joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz); + return SDL_TRUE; error: - if (device->dev) { - hid_close(device->dev); - device->dev = NULL; - } - if (device->context) { - SDL_free(device->context); - device->context = NULL; + SDL_LockMutex(device->dev_lock); + { + if (device->dev) { + SDL_hid_close(device->dev); + device->dev = NULL; + } + if (device->context) { + SDL_free(device->context); + device->context = NULL; + } } + SDL_UnlockMutex(device->dev_lock); return SDL_FALSE; } @@ -1040,11 +1095,11 @@ HIDAPI_DriverSteam_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystic return SDL_Unsupported(); } -static SDL_bool -HIDAPI_DriverSteam_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +static Uint32 +HIDAPI_DriverSteam_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { /* You should use the full Steam Input API for LED support */ - return SDL_FALSE; + return 0; } static int @@ -1054,11 +1109,34 @@ HIDAPI_DriverSteam_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joyst return SDL_Unsupported(); } +static int +HIDAPI_DriverSteam_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + static int HIDAPI_DriverSteam_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) { - /* You should use the full Steam Input API for sensor support */ - return SDL_Unsupported(); + SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)device->context; + unsigned char buf[65]; + int nSettings = 0; + + SDL_memset( buf, 0, 65 ); + buf[1] = ID_SET_SETTINGS_VALUES; + if (enabled) { + ADD_SETTING( SETTING_GYRO_MODE, 0x18 /* SETTING_GYRO_SEND_RAW_ACCEL | SETTING_GYRO_MODE_SEND_RAW_GYRO */ ); + } else { + ADD_SETTING( SETTING_GYRO_MODE, 0x00 /* SETTING_GYRO_MODE_OFF */ ); + } + buf[2] = nSettings*3; + if (SetFeatureReport( device->dev, buf, 3+nSettings*3 ) < 0) { + return SDL_SetError("Couldn't write feature report"); + } + + ctx->report_sensors = enabled; + + return 0; } static SDL_bool @@ -1155,6 +1233,20 @@ HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device) SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, ctx->m_state.sRightPadX); SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, ~ctx->m_state.sRightPadY); + if (ctx->report_sensors) { + float values[3]; + + values[0] = (ctx->m_state.sGyroX / 32768.0f) * (2000.0f * (M_PI / 180.0f)); + values[1] = (ctx->m_state.sGyroZ / 32768.0f) * (2000.0f * (M_PI / 180.0f)); + values[2] = (ctx->m_state.sGyroY / 32768.0f) * (2000.0f * (M_PI / 180.0f)); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, values, 3); + + values[0] = (ctx->m_state.sAccelX / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + values[1] = (ctx->m_state.sAccelZ / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + values[2] = (-ctx->m_state.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, values, 3); + } + ctx->m_last_state = ctx->m_state; } @@ -1170,12 +1262,17 @@ HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device) static void HIDAPI_DriverSteam_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - CloseSteamController(device->dev); - hid_close(device->dev); - device->dev = NULL; + SDL_LockMutex(device->dev_lock); + { + CloseSteamController(device->dev); - SDL_free(device->context); - device->context = NULL; + SDL_hid_close(device->dev); + device->dev = NULL; + + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); } static void @@ -1187,6 +1284,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam = { SDL_HINT_JOYSTICK_HIDAPI_STEAM, SDL_TRUE, + SDL_FALSE, HIDAPI_DriverSteam_IsSupportedDevice, HIDAPI_DriverSteam_GetDeviceName, HIDAPI_DriverSteam_InitDevice, @@ -1196,8 +1294,9 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam = HIDAPI_DriverSteam_OpenJoystick, HIDAPI_DriverSteam_RumbleJoystick, HIDAPI_DriverSteam_RumbleJoystickTriggers, - HIDAPI_DriverSteam_HasJoystickLED, + HIDAPI_DriverSteam_GetJoystickCapabilities, HIDAPI_DriverSteam_SetJoystickLED, + HIDAPI_DriverSteam_SendJoystickEffect, HIDAPI_DriverSteam_SetSensorsEnabled, HIDAPI_DriverSteam_CloseJoystick, HIDAPI_DriverSteam_FreeDevice, diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_switch.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_switch.c index aad03de0c..912d613ed 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_switch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -44,13 +44,24 @@ /* Define this to get log output for rumble logic */ /*#define DEBUG_RUMBLE*/ -/* How often you can write rumble commands to the controller in Bluetooth mode - If you send commands more frequently than this, you can turn off the controller. +/* The initialization sequence doesn't appear to work correctly on Windows unless + the reads and writes are on the same thread. + + ... and now I can't reproduce this, so I'm leaving it in, but disabled for now. */ -#define RUMBLE_WRITE_FREQUENCY_MS 25 +/*#define SWITCH_SYNCHRONOUS_WRITES*/ + +/* How often you can write rumble commands to the controller. + If you send commands more frequently than this, you can turn off the controller + in Bluetooth mode, or the motors can miss the command in USB mode. + */ +#define RUMBLE_WRITE_FREQUENCY_MS 30 /* How often you have to refresh a long duration rumble to keep the motors running */ -#define RUMBLE_REFRESH_FREQUENCY_MS 40 +#define RUMBLE_REFRESH_FREQUENCY_MS 50 + +#define SWITCH_GYRO_SCALE 14.2842f +#define SWITCH_ACCEL_SCALE 4096.f typedef enum { k_eSwitchInputReportIDs_SubcommandReply = 0x21, @@ -79,6 +90,7 @@ typedef enum { } ESwitchSubcommandIDs; typedef enum { + k_eSwitchProprietaryCommandIDs_Status = 0x01, k_eSwitchProprietaryCommandIDs_Handshake = 0x02, k_eSwitchProprietaryCommandIDs_HighSpeed = 0x03, k_eSwitchProprietaryCommandIDs_ForceUSB = 0x04, @@ -87,6 +99,7 @@ typedef enum { } ESwitchProprietaryCommandIDs; typedef enum { + k_eSwitchDeviceInfoControllerType_Unknown = 0x0, k_eSwitchDeviceInfoControllerType_JoyConLeft = 0x1, k_eSwitchDeviceInfoControllerType_JoyConRight = 0x2, k_eSwitchDeviceInfoControllerType_ProController = 0x3, @@ -176,6 +189,16 @@ typedef struct }; } SwitchSubcommandInputPacket_t; +typedef struct +{ + Uint8 ucPacketType; + Uint8 ucCommandID; + Uint8 ucFiller; + + Uint8 ucDeviceType; + Uint8 rgucMACAddress[6]; +} SwitchProprietaryStatusPacket_t; + typedef struct { Uint8 rgucData[4]; @@ -212,6 +235,8 @@ typedef struct { SDL_bool m_bUsingBluetooth; SDL_bool m_bIsGameCube; SDL_bool m_bUseButtonLabels; + ESwitchDeviceInfoControllerType m_eControllerType; + Uint8 m_rgucMACAddress[6]; Uint8 m_nCommandNumber; SwitchCommonOutputPacket_t m_RumblePacket; Uint8 m_rgucReadBuffer[k_unSwitchMaxOutputPacketLength]; @@ -220,6 +245,8 @@ typedef struct { SDL_bool m_bRumblePending; SDL_bool m_bRumbleZeroPending; Uint32 m_unRumblePending; + SDL_bool m_bHasSensors; + SDL_bool m_bReportSensors; SwitchInputOnlyControllerStatePacket_t m_lastInputOnlyState; SwitchSimpleStatePacket_t m_lastSimpleState; @@ -285,7 +312,7 @@ HIDAPI_DriverSwitch_IsSupportedDevice(const char *name, SDL_GameControllerType t controller to continually attempt to reconnect is to filter it out by manufactuer/product string. Note that the controller does have a different product string when connected over Bluetooth. */ - if (SDL_strcmp( name, "HORI Wireless Switch Pad" ) == 0) { + if (SDL_strcmp(name, "HORI Wireless Switch Pad") == 0) { return SDL_FALSE; } return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) ? SDL_TRUE : SDL_FALSE; @@ -295,6 +322,20 @@ static const char * HIDAPI_DriverSwitch_GetDeviceName(Uint16 vendor_id, Uint16 product_id) { /* Give a user friendly name for this controller */ + if (vendor_id == USB_VENDOR_NINTENDO) { + if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) { + return "Nintendo Switch Joy-Con Grip"; + } + + if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT) { + return "Nintendo Switch Joy-Con Left"; + } + + if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT) { + return "Nintendo Switch Joy-Con Right"; + } + } + return "Nintendo Switch Pro Controller"; } @@ -305,16 +346,20 @@ static int ReadInput(SDL_DriverSwitch_Context *ctx) return 0; } - return hid_read_timeout(ctx->device->dev, ctx->m_rgucReadBuffer, sizeof(ctx->m_rgucReadBuffer), 0); + return SDL_hid_read_timeout(ctx->device->dev, ctx->m_rgucReadBuffer, sizeof(ctx->m_rgucReadBuffer), 0); } static int WriteOutput(SDL_DriverSwitch_Context *ctx, const Uint8 *data, int size) { +#ifdef SWITCH_SYNCHRONOUS_WRITES + return SDL_hid_write(ctx->device->dev, data, size); +#else /* Use the rumble thread for general asynchronous writes */ if (SDL_HIDAPI_LockRumble() < 0) { return -1; } return SDL_HIDAPI_SendRumbleAndUnlock(ctx->device, data, size); +#endif /* SWITCH_SYNCHRONOUS_WRITES */ } static SwitchSubcommandInputPacket_t *ReadSubcommandReply(SDL_DriverSwitch_Context *ctx, ESwitchSubcommandIDs expectedID) @@ -373,7 +418,7 @@ static void ConstructSubcommand(SDL_DriverSwitch_Context *ctx, ESwitchSubcommand outPacket->commonData.ucPacketType = k_eSwitchOutputReportIDs_RumbleAndSubcommand; outPacket->commonData.ucPacketNumber = ctx->m_nCommandNumber; - SDL_memcpy(&outPacket->commonData.rumbleData, &ctx->m_RumblePacket.rumbleData, sizeof(ctx->m_RumblePacket.rumbleData)); + SDL_memcpy(outPacket->commonData.rumbleData, ctx->m_RumblePacket.rumbleData, sizeof(ctx->m_RumblePacket.rumbleData)); outPacket->ucSubcommandID = ucCommandID; SDL_memcpy(outPacket->rgucSubcommandData, pBuf, ucLen); @@ -432,6 +477,7 @@ static SDL_bool WriteProprietary(SDL_DriverSwitch_Context *ctx, ESwitchProprieta return SDL_FALSE; } + SDL_zero(packet); packet.ucPacketType = k_eSwitchOutputReportIDs_Proprietary; packet.ucProprietaryID = ucCommand; if (pBuf) { @@ -449,6 +495,64 @@ static SDL_bool WriteProprietary(SDL_DriverSwitch_Context *ctx, ESwitchProprieta return SDL_FALSE; } +static Uint8 EncodeRumbleHighAmplitude(Uint16 amplitude) { + /* More information about these values can be found here: + * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md + */ + Uint16 hfa[101][2] = { {0, 0x0},{514, 0x2},{775, 0x4},{921, 0x6},{1096, 0x8},{1303, 0x0a},{1550, 0x0c}, + {1843, 0x0e},{2192, 0x10},{2606, 0x12},{3100, 0x14},{3686, 0x16},{4383, 0x18},{5213, 0x1a}, + {6199, 0x1c},{7372, 0x1e},{7698, 0x20},{8039, 0x22},{8395, 0x24},{8767, 0x26},{9155, 0x28}, + {9560, 0x2a},{9984, 0x2c},{10426, 0x2e},{10887, 0x30},{11369, 0x32},{11873, 0x34},{12398, 0x36}, + {12947, 0x38},{13520, 0x3a},{14119, 0x3c},{14744, 0x3e},{15067, 0x40},{15397, 0x42},{15734, 0x44}, + {16079, 0x46},{16431, 0x48},{16790, 0x4a},{17158, 0x4c},{17534, 0x4e},{17918, 0x50},{18310, 0x52}, + {18711, 0x54},{19121, 0x56},{19540, 0x58},{19967, 0x5a},{20405, 0x5c},{20851, 0x5e},{21308, 0x60}, + {21775, 0x62},{22251, 0x64},{22739, 0x66},{23236, 0x68},{23745, 0x6a},{24265, 0x6c},{24797, 0x6e}, + {25340, 0x70},{25894, 0x72},{26462, 0x74},{27041, 0x76},{27633, 0x78},{28238, 0x7a},{28856, 0x7c}, + {29488, 0x7e},{30134, 0x80},{30794, 0x82},{31468, 0x84},{32157, 0x86},{32861, 0x88},{33581, 0x8a}, + {34316, 0x8c},{35068, 0x8e},{35836, 0x90},{36620, 0x92},{37422, 0x94},{38242, 0x96},{39079, 0x98}, + {39935, 0x9a},{40809, 0x9c},{41703, 0x9e},{42616, 0xa0},{43549, 0xa2},{44503, 0xa4},{45477, 0xa6}, + {46473, 0xa8},{47491, 0xaa},{48531, 0xac},{49593, 0xae},{50679, 0xb0},{51789, 0xb2},{52923, 0xb4}, + {54082, 0xb6},{55266, 0xb8},{56476, 0xba},{57713, 0xbc},{58977, 0xbe},{60268, 0xc0},{61588, 0xc2}, + {62936, 0xc4},{64315, 0xc6},{65535, 0xc8} }; + int index = 0; + for ( ; index < 101; index++) { + if (amplitude <= hfa[index][0]) { + return (Uint8)hfa[index][1]; + } + } + return (Uint8)hfa[100][1]; +} + +static Uint16 EncodeRumbleLowAmplitude(Uint16 amplitude) { + /* More information about these values can be found here: + * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md + */ + Uint16 lfa[101][2] = { {0, 0x0040},{514, 0x8040},{775, 0x0041},{921, 0x8041},{1096, 0x0042}, + {1303, 0x8042},{1550, 0x0043},{1843, 0x8043},{2192, 0x0044},{2606, 0x8044},{3100, 0x0045}, + {3686, 0x8045},{4383, 0x0046},{5213, 0x8046},{6199, 0x0047},{7372, 0x8047},{7698, 0x0048}, + {8039, 0x8048},{8395, 0x0049},{8767, 0x8049},{9155, 0x004a},{9560, 0x804a},{9984, 0x004b}, + {10426, 0x804b},{10887, 0x004c},{11369, 0x804c},{11873, 0x004d},{12398, 0x804d},{12947, 0x004e}, + {13520, 0x804e},{14119, 0x004f},{14744, 0x804f},{15067, 0x0050},{15397, 0x8050},{15734, 0x0051}, + {16079, 0x8051},{16431, 0x0052},{16790, 0x8052},{17158, 0x0053},{17534, 0x8053},{17918, 0x0054}, + {18310, 0x8054},{18711, 0x0055},{19121, 0x8055},{19540, 0x0056},{19967, 0x8056},{20405, 0x0057}, + {20851, 0x8057},{21308, 0x0058},{21775, 0x8058},{22251, 0x0059},{22739, 0x8059},{23236, 0x005a}, + {23745, 0x805a},{24265, 0x005b},{24797, 0x805b},{25340, 0x005c},{25894, 0x805c},{26462, 0x005d}, + {27041, 0x805d},{27633, 0x005e},{28238, 0x805e},{28856, 0x005f},{29488, 0x805f},{30134, 0x0060}, + {30794, 0x8060},{31468, 0x0061},{32157, 0x8061},{32861, 0x0062},{33581, 0x8062},{34316, 0x0063}, + {35068, 0x8063},{35836, 0x0064},{36620, 0x8064},{37422, 0x0065},{38242, 0x8065},{39079, 0x0066}, + {39935, 0x8066},{40809, 0x0067},{41703, 0x8067},{42616, 0x0068},{43549, 0x8068},{44503, 0x0069}, + {45477, 0x8069},{46473, 0x006a},{47491, 0x806a},{48531, 0x006b},{49593, 0x806b},{50679, 0x006c}, + {51789, 0x806c},{52923, 0x006d},{54082, 0x806d},{55266, 0x006e},{56476, 0x806e},{57713, 0x006f}, + {58977, 0x806f},{60268, 0x0070},{61588, 0x8070},{62936, 0x0071},{64315, 0x8071},{65535, 0x0072} }; + int index = 0; + for (; index < 101; index++) { + if (amplitude <= lfa[index][0]) { + return lfa[index][1]; + } + } + return lfa[100][1]; +} + static void SetNeutralRumble(SwitchRumbleData_t *pRumble) { pRumble->rgucData[0] = 0x00; @@ -493,6 +597,40 @@ static SDL_bool WriteRumble(SDL_DriverSwitch_Context *ctx) return WritePacket(ctx, (Uint8 *)&ctx->m_RumblePacket, sizeof(ctx->m_RumblePacket)); } +static SDL_bool BReadDeviceInfo(SDL_DriverSwitch_Context *ctx) +{ + SwitchSubcommandInputPacket_t *reply = NULL; + + ctx->m_bUsingBluetooth = SDL_FALSE; + + if (WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Status, NULL, 0, SDL_TRUE)) { + SwitchProprietaryStatusPacket_t *status = (SwitchProprietaryStatusPacket_t *)&ctx->m_rgucReadBuffer[0]; + size_t i; + + ctx->m_eControllerType = (ESwitchDeviceInfoControllerType)status->ucDeviceType; + for (i = 0; i < sizeof (ctx->m_rgucMACAddress); ++i) + ctx->m_rgucMACAddress[i] = status->rgucMACAddress[ sizeof(ctx->m_rgucMACAddress) - i - 1 ]; + + return SDL_TRUE; + } + + ctx->m_bUsingBluetooth = SDL_TRUE; + + if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_RequestDeviceInfo, NULL, 0, &reply)) { + // Byte 2: Controller ID (1=LJC, 2=RJC, 3=Pro) + ctx->m_eControllerType = (ESwitchDeviceInfoControllerType)reply->deviceInfo.ucDeviceType; + + // Bytes 4-9: MAC address (big-endian) + SDL_memcpy(ctx->m_rgucMACAddress, reply->deviceInfo.rgucMACAddress, sizeof(ctx->m_rgucMACAddress)); + + return SDL_TRUE; + } + + ctx->m_bUsingBluetooth = SDL_FALSE; + + return SDL_FALSE; +} + static SDL_bool BTrySetupUSB(SDL_DriverSwitch_Context *ctx) { /* We have to send a connection handshake to the controller when communicating over USB @@ -508,6 +646,10 @@ static SDL_bool BTrySetupUSB(SDL_DriverSwitch_Context *ctx) /*return SDL_FALSE;*/ } if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Handshake, NULL, 0, SDL_TRUE)) { + /* This fails on the right Joy-Con when plugged into the charging grip */ + /*return SDL_FALSE;*/ + } + if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_ForceUSB, NULL, 0, SDL_FALSE)) { return SDL_FALSE; } return SDL_TRUE; @@ -550,6 +692,12 @@ static SDL_bool SetSlotLED(SDL_DriverSwitch_Context *ctx, Uint8 slot) return WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SetPlayerLights, &led_data, sizeof(led_data), NULL); } +static SDL_bool SetIMUEnabled(SDL_DriverSwitch_Context* ctx, SDL_bool enabled) +{ + Uint8 imu_data = enabled ? 1 : 0; + return WriteSubcommand(ctx, k_eSwitchSubcommandIDs_EnableIMU, &imu_data, sizeof(imu_data), NULL); +} + static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx, Uint8 input_mode) { Uint8 *pStickCal; @@ -621,19 +769,6 @@ static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx, Uint8 input_ return SDL_TRUE; } -static float fsel(float fComparand, float fValGE, float fLT) -{ - return fComparand >= 0 ? fValGE : fLT; -} - -static float RemapVal(float val, float A, float B, float C, float D) -{ - if (A == B) { - return fsel(val - B , D , C); - } - return C + (D - C) * (val - A) / (B - A); -} - static Sint16 ApplyStickCalibrationCentered(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue, Sint16 sCenter) { sRawValue -= sCenter; @@ -645,11 +780,7 @@ static Sint16 ApplyStickCalibrationCentered(SDL_DriverSwitch_Context *ctx, int n ctx->m_StickExtents[nStick].axis[nAxis].sMin = sRawValue; } - if (sRawValue > 0) { - return (Sint16)(RemapVal(sRawValue, 0, ctx->m_StickExtents[nStick].axis[nAxis].sMax, 0, SDL_MAX_SINT16)); - } else { - return (Sint16)(RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, 0, SDL_MIN_SINT16, 0)); - } + return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, ctx->m_StickExtents[nStick].axis[nAxis].sMax, SDL_MIN_SINT16, SDL_MAX_SINT16); } static Sint16 ApplyStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue) @@ -725,7 +856,7 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti ctx->device = device; device->context = ctx; - device->dev = hid_open_path(device->path, 0); + device->dev = SDL_hid_open_path(device->path, 0); if (!device->dev) { SDL_SetError("Couldn't open %s", device->path); goto error; @@ -740,9 +871,16 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]); SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[1]); - /* Try setting up USB mode, and if that fails we're using Bluetooth */ - if (!BTrySetupUSB(ctx)) { - ctx->m_bUsingBluetooth = SDL_TRUE; + if (!BReadDeviceInfo(ctx)) { + SDL_SetError("Couldn't read device info"); + goto error; + } + + if (!ctx->m_bUsingBluetooth) { + if (!BTrySetupUSB(ctx)) { + SDL_SetError("Couldn't setup USB mode"); + goto error; + } } /* Determine the desired input mode (needed before loading stick calibration) */ @@ -758,9 +896,18 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti * level and we only care about battery level over bluetooth anyway. */ if (device->vendor_id == USB_VENDOR_NINTENDO && - device->product_id == USB_PRODUCT_NINTENDO_SWITCH_PRO) { + (device->product_id == USB_PRODUCT_NINTENDO_SWITCH_PRO || + device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP || + device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT || + device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT)) { input_mode = k_eSwitchInputReportIDs_FullControllerState; } + + if (input_mode == k_eSwitchInputReportIDs_FullControllerState) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 200.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 200.0f); + ctx->m_bHasSensors = SDL_TRUE; + } if (!LoadStickCalibration(ctx, input_mode)) { SDL_SetError("Couldn't load stick calibration"); @@ -789,9 +936,30 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti /* Set the LED state */ if (ctx->m_bHasHomeLED) { - SetHomeLED(ctx, 100); + const char *hint = SDL_GetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED); + if (hint && *hint) { + if (SDL_GetStringBoolean(hint, SDL_TRUE)) { + SetHomeLED(ctx, 100); + } else { + SetHomeLED(ctx, 0); + } + } } SetSlotLED(ctx, (joystick->instance_id % 4)); + + /* Set the serial number */ + { + char serial[18]; + + SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + ctx->m_rgucMACAddress[0], + ctx->m_rgucMACAddress[1], + ctx->m_rgucMACAddress[2], + ctx->m_rgucMACAddress[3], + ctx->m_rgucMACAddress[4], + ctx->m_rgucMACAddress[5]); + joystick->serial = SDL_strdup(serial); + } } if (IsGameCubeFormFactor(device->vendor_id, device->product_id)) { @@ -803,21 +971,30 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti SDL_GameControllerButtonReportingHintChanged, ctx); /* Initialize the joystick capabilities */ - joystick->nbuttons = 16; + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft || + ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + joystick->nbuttons = 20; + } else { + joystick->nbuttons = 16; + } joystick->naxes = SDL_CONTROLLER_AXIS_MAX; joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; return SDL_TRUE; error: - if (device->dev) { - hid_close(device->dev); - device->dev = NULL; - } - if (device->context) { - SDL_free(device->context); - device->context = NULL; + SDL_LockMutex(device->dev_lock); + { + if (device->dev) { + SDL_hid_close(device->dev); + device->dev = NULL; + } + if (device->context) { + SDL_free(device->context); + device->context = NULL; + } } + SDL_UnlockMutex(device->dev_lock); return SDL_FALSE; } @@ -831,27 +1008,22 @@ HIDAPI_DriverSwitch_ActuallyRumbleJoystick(SDL_DriverSwitch_Context *ctx, Uint16 * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md */ const Uint16 k_usHighFreq = 0x0074; - const Uint8 k_ucHighFreqAmp = 0xBE; + const Uint8 k_ucHighFreqAmp = EncodeRumbleHighAmplitude(high_frequency_rumble); const Uint8 k_ucLowFreq = 0x3D; - const Uint16 k_usLowFreqAmp = 0x806F; + const Uint16 k_usLowFreqAmp = EncodeRumbleLowAmplitude(low_frequency_rumble); - if (low_frequency_rumble) { + if (low_frequency_rumble || high_frequency_rumble) { EncodeRumble(&ctx->m_RumblePacket.rumbleData[0], k_usHighFreq, k_ucHighFreqAmp, k_ucLowFreq, k_usLowFreqAmp); - } else { - SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]); - } - - if (high_frequency_rumble) { EncodeRumble(&ctx->m_RumblePacket.rumbleData[1], k_usHighFreq, k_ucHighFreqAmp, k_ucLowFreq, k_usLowFreqAmp); } else { + SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]); SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[1]); } ctx->m_bRumbleActive = (low_frequency_rumble || high_frequency_rumble) ? SDL_TRUE : SDL_FALSE; if (!WriteRumble(ctx)) { - SDL_SetError("Couldn't send rumble packet"); - return -1; + return SDL_SetError("Couldn't send rumble packet"); } return 0; } @@ -859,7 +1031,7 @@ HIDAPI_DriverSwitch_ActuallyRumbleJoystick(SDL_DriverSwitch_Context *ctx, Uint16 static int HIDAPI_DriverSwitch_SendPendingRumble(SDL_DriverSwitch_Context *ctx) { - if ((SDL_GetTicks() - ctx->m_unRumbleSent) < RUMBLE_WRITE_FREQUENCY_MS) { + if (!SDL_TICKS_PASSED(SDL_GetTicks(), ctx->m_unRumbleSent + RUMBLE_WRITE_FREQUENCY_MS)) { return 0; } @@ -868,7 +1040,7 @@ HIDAPI_DriverSwitch_SendPendingRumble(SDL_DriverSwitch_Context *ctx) Uint16 high_frequency_rumble = (Uint16)ctx->m_unRumblePending; #ifdef DEBUG_RUMBLE - SDL_Log("Sent pending rumble %d/%d\n", low_frequency_rumble, high_frequency_rumble); + SDL_Log("Sent pending rumble %d/%d, %d ms after previous rumble\n", low_frequency_rumble, high_frequency_rumble, SDL_GetTicks() - ctx->m_unRumbleSent); #endif ctx->m_bRumblePending = SDL_FALSE; ctx->m_unRumblePending = 0; @@ -880,7 +1052,7 @@ HIDAPI_DriverSwitch_SendPendingRumble(SDL_DriverSwitch_Context *ctx) ctx->m_bRumbleZeroPending = SDL_FALSE; #ifdef DEBUG_RUMBLE - SDL_Log("Sent pending zero rumble\n"); + SDL_Log("Sent pending zero rumble, %d ms after previous rumble\n", SDL_GetTicks() - ctx->m_unRumbleSent); #endif return HIDAPI_DriverSwitch_ActuallyRumbleJoystick(ctx, 0, 0); } @@ -893,13 +1065,17 @@ HIDAPI_DriverSwitch_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys { SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; + if (ctx->m_bInputOnly) { + return SDL_Unsupported(); + } + if (ctx->m_bRumblePending) { if (HIDAPI_DriverSwitch_SendPendingRumble(ctx) < 0) { return -1; } } - if (ctx->m_bUsingBluetooth && (SDL_GetTicks() - ctx->m_unRumbleSent) < RUMBLE_WRITE_FREQUENCY_MS) { + if (!SDL_TICKS_PASSED(SDL_GetTicks(), ctx->m_unRumbleSent + RUMBLE_WRITE_FREQUENCY_MS)) { if (low_frequency_rumble || high_frequency_rumble) { Uint32 unRumblePending = ((Uint32)low_frequency_rumble << 16) | high_frequency_rumble; @@ -929,11 +1105,18 @@ HIDAPI_DriverSwitch_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joysti return SDL_Unsupported(); } -static SDL_bool -HIDAPI_DriverSwitch_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +static Uint32 +HIDAPI_DriverSwitch_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - /* Doesn't have an RGB LED, so don't return true here */ - return SDL_FALSE; + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; + Uint32 result = 0; + + if (!ctx->m_bInputOnly) { + /* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */ + result |= SDL_JOYCAP_RUMBLE; + } + + return result; } static int @@ -943,11 +1126,40 @@ HIDAPI_DriverSwitch_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joys } static int -HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +HIDAPI_DriverSwitch_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) { return SDL_Unsupported(); } +static int +HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + SDL_DriverSwitch_Context* ctx = (SDL_DriverSwitch_Context*)device->context; + + if (!ctx->m_bHasSensors) { + return SDL_Unsupported(); + } + + SetIMUEnabled(ctx, enabled); + ctx->m_bReportSensors = enabled; + + return 0; +} + +static float +HIDAPI_DriverSwitch_ScaleGyro(Sint16 value) +{ + float result = (value / SWITCH_GYRO_SCALE) * (float)M_PI / 180.0f; + return result; +} + +static float +HIDAPI_DriverSwitch_ScaleAccel(Sint16 value) +{ + float result = (value / SWITCH_ACCEL_SCALE) * SDL_STANDARD_GRAVITY; + return result; +} + static void HandleInputOnlyControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchInputOnlyControllerStatePacket_t *packet) { Sint16 axis; @@ -1023,22 +1235,22 @@ static void HandleInputOnlyControllerState(SDL_Joystick *joystick, SDL_DriverSwi } if (packet->rgucJoystickLeft[0] != ctx->m_lastInputOnlyState.rgucJoystickLeft[0]) { - axis = (Sint16)(RemapVal(packet->rgucJoystickLeft[0], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16)); + axis = (Sint16)HIDAPI_RemapVal(packet->rgucJoystickLeft[0], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16); SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); } if (packet->rgucJoystickLeft[1] != ctx->m_lastInputOnlyState.rgucJoystickLeft[1]) { - axis = (Sint16)(RemapVal(packet->rgucJoystickLeft[1], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16)); + axis = (Sint16)HIDAPI_RemapVal(packet->rgucJoystickLeft[1], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16); SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); } if (packet->rgucJoystickRight[0] != ctx->m_lastInputOnlyState.rgucJoystickRight[0]) { - axis = (Sint16)(RemapVal(packet->rgucJoystickRight[0], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16)); + axis = (Sint16)HIDAPI_RemapVal(packet->rgucJoystickRight[0], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16); SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); } if (packet->rgucJoystickRight[1] != ctx->m_lastInputOnlyState.rgucJoystickRight[1]) { - axis = (Sint16)(RemapVal(packet->rgucJoystickRight[1], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16)); + axis = (Sint16)HIDAPI_RemapVal(packet->rgucJoystickRight[1], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16); SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); } @@ -1136,6 +1348,33 @@ static void HandleSimpleControllerState(SDL_Joystick *joystick, SDL_DriverSwitch ctx->m_lastSimpleState = *packet; } +static void SendSensorUpdate(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SDL_SensorType type, Sint16 *values) +{ + float data[3]; + + /* Note the order of components has been shuffled to match PlayStation controllers, + * since that's our de facto standard from already supporting those controllers, and + * users will want consistent axis mappings across devices. + */ + if (type == SDL_SENSOR_GYRO) { + data[0] = -HIDAPI_DriverSwitch_ScaleGyro(values[1]); + data[1] = HIDAPI_DriverSwitch_ScaleGyro(values[2]); + data[2] = -HIDAPI_DriverSwitch_ScaleGyro(values[0]); + } else { + data[0] = -HIDAPI_DriverSwitch_ScaleAccel(values[1]); + data[1] = HIDAPI_DriverSwitch_ScaleAccel(values[2]); + data[2] = -HIDAPI_DriverSwitch_ScaleAccel(values[0]); + } + + /* Right Joy-Con flips some axes, so let's flip them back for consistency */ + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + data[0] = -data[0]; + data[1] = -data[1]; + } + + SDL_PrivateJoystickSensor(joystick, type, data, 3); +} + static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet) { Sint16 axis; @@ -1146,6 +1385,10 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE1, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE3, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + } SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); axis = (data & 0x80) ? 32767 : -32768; SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); @@ -1168,6 +1411,10 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE4, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE2, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + } SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); axis = (data & 0x80) ? 32767 : -32768; SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); @@ -1210,6 +1457,16 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C } } + if (ctx->m_bReportSensors) { + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[2].sGyroX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[1].sGyroX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[0].sGyroX); + + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[2].sAccelX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[1].sAccelX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[0].sAccelX); + } + ctx->m_lastFullState = *packet; } @@ -1252,7 +1509,7 @@ HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device) } else if (ctx->m_bRumbleActive && SDL_TICKS_PASSED(SDL_GetTicks(), ctx->m_unRumbleSent + RUMBLE_REFRESH_FREQUENCY_MS)) { #ifdef DEBUG_RUMBLE - SDL_Log("Sent continuing rumble\n"); + SDL_Log("Sent continuing rumble, %d ms after previous rumble\n", SDL_GetTicks() - ctx->m_unRumbleSent); #endif WriteRumble(ctx); } @@ -1277,11 +1534,15 @@ HIDAPI_DriverSwitch_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, SDL_GameControllerButtonReportingHintChanged, ctx); - hid_close(device->dev); - device->dev = NULL; + SDL_LockMutex(device->dev_lock); + { + SDL_hid_close(device->dev); + device->dev = NULL; - SDL_free(device->context); - device->context = NULL; + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); } static void @@ -1293,6 +1554,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch = { SDL_HINT_JOYSTICK_HIDAPI_SWITCH, SDL_TRUE, + SDL_TRUE, HIDAPI_DriverSwitch_IsSupportedDevice, HIDAPI_DriverSwitch_GetDeviceName, HIDAPI_DriverSwitch_InitDevice, @@ -1302,8 +1564,9 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch = HIDAPI_DriverSwitch_OpenJoystick, HIDAPI_DriverSwitch_RumbleJoystick, HIDAPI_DriverSwitch_RumbleJoystickTriggers, - HIDAPI_DriverSwitch_HasJoystickLED, + HIDAPI_DriverSwitch_GetJoystickCapabilities, HIDAPI_DriverSwitch_SetJoystickLED, + HIDAPI_DriverSwitch_SendJoystickEffect, HIDAPI_DriverSwitch_SetJoystickSensorsEnabled, HIDAPI_DriverSwitch_CloseJoystick, HIDAPI_DriverSwitch_FreeDevice, diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xbox360.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xbox360.c index e3b3919c6..da7aa240f 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xbox360.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xbox360.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -42,22 +42,6 @@ typedef struct { Uint8 last_state[USB_PACKET_LENGTH]; } SDL_DriverXbox360_Context; -#if defined(__MACOSX__) -static SDL_bool -IsBluetoothXboxOneController(Uint16 vendor_id, Uint16 product_id) -{ - /* Check to see if it's the Xbox One S or Xbox One Elite Series 2 in Bluetooth mode */ - if (vendor_id == USB_VENDOR_MICROSOFT) { - if (product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH || - product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH || - product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH) { - return SDL_TRUE; - } - } - return SDL_FALSE; -} -#endif - static SDL_bool HIDAPI_DriverXbox360_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) { @@ -89,7 +73,7 @@ HIDAPI_DriverXbox360_IsSupportedDevice(const char *name, SDL_GameControllerType Bluetooth Xbox One controllers are handled by the SDL Xbox One driver */ - if (IsBluetoothXboxOneController(vendor_id, product_id)) { + if (SDL_IsJoystickBluetoothXboxOne(vendor_id, product_id)) { return SDL_FALSE; } return (type == SDL_CONTROLLER_TYPE_XBOX360 || type == SDL_CONTROLLER_TYPE_XBOXONE) ? SDL_TRUE : SDL_FALSE; @@ -104,12 +88,14 @@ HIDAPI_DriverXbox360_GetDeviceName(Uint16 vendor_id, Uint16 product_id) return NULL; } -static SDL_bool SetSlotLED(hid_device *dev, Uint8 slot) +static SDL_bool SetSlotLED(SDL_hid_device *dev, Uint8 slot) { - Uint8 mode = 0x02 + slot; - const Uint8 led_packet[] = { 0x01, 0x03, mode }; + const SDL_bool blink = SDL_FALSE; + Uint8 mode = (blink ? 0x02 : 0x06) + slot; + Uint8 led_packet[] = { 0x01, 0x03, 0x00 }; - if (hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) { + led_packet[2] = mode; + if (SDL_hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) { return SDL_FALSE; } return SDL_TRUE; @@ -133,7 +119,9 @@ HIDAPI_DriverXbox360_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_Joystic if (!device->dev) { return; } - SetSlotLED(device->dev, (player_index % 4)); + if (player_index >= 0) { + SetSlotLED(device->dev, (player_index % 4)); + } } static SDL_bool @@ -148,7 +136,7 @@ HIDAPI_DriverXbox360_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst return SDL_FALSE; } - device->dev = hid_open_path(device->path, 0); + device->dev = SDL_hid_open_path(device->path, 0); if (!device->dev) { SDL_SetError("Couldn't open %s", device->path); SDL_free(ctx); @@ -174,7 +162,7 @@ static int HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { #ifdef __MACOSX__ - if (IsBluetoothXboxOneController(device->vendor_id, device->product_id)) { + if (SDL_IsJoystickBluetoothXboxOne(device->vendor_id, device->product_id)) { Uint8 rumble_packet[] = { 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00 }; rumble_packet[4] = (low_frequency_rumble >> 8); @@ -215,11 +203,11 @@ HIDAPI_DriverXbox360_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joyst return SDL_Unsupported(); } -static SDL_bool -HIDAPI_DriverXbox360_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +static Uint32 +HIDAPI_DriverXbox360_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - /* Doesn't have an RGB LED, so don't return true here */ - return SDL_FALSE; + /* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */ + return SDL_JOYCAP_RUMBLE; } static int @@ -228,6 +216,12 @@ HIDAPI_DriverXbox360_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joy return SDL_Unsupported(); } +static int +HIDAPI_DriverXbox360_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + static int HIDAPI_DriverXbox360_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) { @@ -302,7 +296,7 @@ HIDAPI_DriverXbox360_UpdateDevice(SDL_HIDAPI_Device *device) return SDL_FALSE; } - while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { #ifdef DEBUG_XBOX_PROTOCOL HIDAPI_DumpPacket("Xbox 360 packet: size = %d", data, size); #endif @@ -321,13 +315,17 @@ HIDAPI_DriverXbox360_UpdateDevice(SDL_HIDAPI_Device *device) static void HIDAPI_DriverXbox360_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - if (device->dev) { - hid_close(device->dev); - device->dev = NULL; - } + SDL_LockMutex(device->dev_lock); + { + if (device->dev) { + SDL_hid_close(device->dev); + device->dev = NULL; + } - SDL_free(device->context); - device->context = NULL; + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); } static void @@ -339,6 +337,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 = { SDL_HINT_JOYSTICK_HIDAPI_XBOX, SDL_TRUE, + SDL_TRUE, HIDAPI_DriverXbox360_IsSupportedDevice, HIDAPI_DriverXbox360_GetDeviceName, HIDAPI_DriverXbox360_InitDevice, @@ -348,8 +347,9 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 = HIDAPI_DriverXbox360_OpenJoystick, HIDAPI_DriverXbox360_RumbleJoystick, HIDAPI_DriverXbox360_RumbleJoystickTriggers, - HIDAPI_DriverXbox360_HasJoystickLED, + HIDAPI_DriverXbox360_GetJoystickCapabilities, HIDAPI_DriverXbox360_SetJoystickLED, + HIDAPI_DriverXbox360_SendJoystickEffect, HIDAPI_DriverXbox360_SetJoystickSensorsEnabled, HIDAPI_DriverXbox360_CloseJoystick, HIDAPI_DriverXbox360_FreeDevice, diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xbox360w.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xbox360w.c index 40dcae626..e6e6171ab 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xbox360w.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xbox360w.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -49,7 +49,7 @@ HIDAPI_DriverXbox360W_IsSupportedDevice(const char *name, SDL_GameControllerType { const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */ - if ((vendor_id == USB_VENDOR_MICROSOFT && (product_id == 0x0291 || product_id == 0x02a9 || product_id == 0x0719)) || + if ((vendor_id == USB_VENDOR_MICROSOFT && (product_id == 0x0291 || product_id == 0x02a9 || product_id == 0x0719) && interface_protocol == 0) || (type == SDL_CONTROLLER_TYPE_XBOX360 && interface_protocol == XB360W_IFACE_PROTOCOL)) { return SDL_TRUE; } @@ -62,12 +62,14 @@ HIDAPI_DriverXbox360W_GetDeviceName(Uint16 vendor_id, Uint16 product_id) return "Xbox 360 Wireless Controller"; } -static SDL_bool SetSlotLED(hid_device *dev, Uint8 slot) +static SDL_bool SetSlotLED(SDL_hid_device *dev, Uint8 slot) { - Uint8 mode = 0x02 + slot; - const Uint8 led_packet[] = { 0x00, 0x00, 0x08, (0x40 + (mode % 0x0e)), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + const SDL_bool blink = SDL_FALSE; + Uint8 mode = (blink ? 0x02 : 0x06) + slot; + Uint8 led_packet[] = { 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - if (hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) { + led_packet[3] = 0x40 + (mode % 0x0e); + if (SDL_hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) { return SDL_FALSE; } return SDL_TRUE; @@ -103,7 +105,7 @@ HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device) return SDL_FALSE; } - device->dev = hid_open_path(device->path, 0); + device->dev = SDL_hid_open_path(device->path, 0); if (!device->dev) { SDL_free(ctx); SDL_SetError("Couldn't open %s", device->path); @@ -111,7 +113,7 @@ HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device) } device->context = ctx; - if (hid_write(device->dev, init_packet, sizeof(init_packet)) != sizeof(init_packet)) { + if (SDL_hid_write(device->dev, init_packet, sizeof(init_packet)) != sizeof(init_packet)) { SDL_SetError("Couldn't write init packet"); return SDL_FALSE; } @@ -131,7 +133,9 @@ HIDAPI_DriverXbox360W_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_Joysti if (!device->dev) { return; } - SetSlotLED(device->dev, (player_index % 4)); + if (player_index >= 0) { + SetSlotLED(device->dev, (player_index % 4)); + } } static SDL_bool @@ -169,11 +173,11 @@ HIDAPI_DriverXbox360W_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joys return SDL_Unsupported(); } -static SDL_bool -HIDAPI_DriverXbox360W_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +static Uint32 +HIDAPI_DriverXbox360W_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - /* Doesn't have an RGB LED, so don't return true here */ - return SDL_FALSE; + /* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */ + return SDL_JOYCAP_RUMBLE; } static int @@ -182,6 +186,12 @@ HIDAPI_DriverXbox360W_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *jo return SDL_Unsupported(); } +static int +HIDAPI_DriverXbox360W_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + static int HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) { @@ -189,7 +199,7 @@ HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_J } static void -HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXbox360W_Context *ctx, Uint8 *data, int size) +HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverXbox360W_Context *ctx, Uint8 *data, int size) { Sint16 axis; const SDL_bool invert_y_axes = SDL_TRUE; @@ -249,7 +259,7 @@ HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device) joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); } - while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { #ifdef DEBUG_XBOX_PROTOCOL HIDAPI_DumpPacket("Xbox 360 wireless packet: size = %d", data, size); #endif @@ -309,17 +319,22 @@ HIDAPI_DriverXbox360W_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy static void HIDAPI_DriverXbox360W_FreeDevice(SDL_HIDAPI_Device *device) { - hid_close(device->dev); - device->dev = NULL; + SDL_LockMutex(device->dev_lock); + { + SDL_hid_close(device->dev); + device->dev = NULL; - SDL_free(device->context); - device->context = NULL; + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); } SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W = { SDL_HINT_JOYSTICK_HIDAPI_XBOX, SDL_TRUE, + SDL_TRUE, HIDAPI_DriverXbox360W_IsSupportedDevice, HIDAPI_DriverXbox360W_GetDeviceName, HIDAPI_DriverXbox360W_InitDevice, @@ -329,8 +344,9 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W = HIDAPI_DriverXbox360W_OpenJoystick, HIDAPI_DriverXbox360W_RumbleJoystick, HIDAPI_DriverXbox360W_RumbleJoystickTriggers, - HIDAPI_DriverXbox360W_HasJoystickLED, + HIDAPI_DriverXbox360W_GetJoystickCapabilities, HIDAPI_DriverXbox360W_SetJoystickLED, + HIDAPI_DriverXbox360W_SendJoystickEffect, HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled, HIDAPI_DriverXbox360W_CloseJoystick, HIDAPI_DriverXbox360W_FreeDevice, diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xboxone.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xboxone.c index 5cb7dabc4..1f0cf5b5a 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -43,34 +43,28 @@ #define CONTROLLER_NEGOTIATION_TIMEOUT_MS 300 #define CONTROLLER_PREPARE_INPUT_TIMEOUT_MS 50 +/* Deadzone thresholds */ +#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849 +#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689 +#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD -25058 /* Uint8 30 scaled to Sint16 full range */ -/* Connect controller */ +/* Start controller */ static const Uint8 xboxone_init0[] = { - 0x04, 0x20, 0x00, 0x00 -}; -/* Start controller - extended? */ -static const Uint8 xboxone_init1[] = { - 0x05, 0x20, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x55, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 -}; -/* Start controller with input */ -static const Uint8 xboxone_init2[] = { 0x05, 0x20, 0x03, 0x01, 0x00 }; /* Enable LED */ -static const Uint8 xboxone_init3[] = { +static const Uint8 xboxone_init1[] = { 0x0A, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14 }; -/* Start input reports? */ -static const Uint8 xboxone_init4[] = { - 0x06, 0x20, 0x00, 0x02, 0x01, 0x00 -}; -/* Start rumble? */ -static const Uint8 xboxone_init5[] = { +/* Setup rumble (not needed for Microsoft controllers, but it doesn't hurt) */ +static const Uint8 xboxone_init2[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEB }; +/* This controller passed security check */ +static const Uint8 security_passed_packet[] = { + 0x06, 0x20, 0x00, 0x02, 0x01, 0x00 +}; /* * This specifies the selection of init packets that a gamepad @@ -90,16 +84,11 @@ typedef struct { static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = { - { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init0, sizeof(xboxone_init0), { 0x04, 0xb0 } }, + /* The PDP Rock Candy controller doesn't start sending input until it gets this packet */ + { 0x0e6f, 0x0246, 0x0000, 0x0000, security_passed_packet, sizeof(security_passed_packet), { 0x00, 0x00 } }, + { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init0, sizeof(xboxone_init0), { 0x00, 0x00 } }, { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init1, sizeof(xboxone_init1), { 0x00, 0x00 } }, { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init2, sizeof(xboxone_init2), { 0x00, 0x00 } }, - { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init3, sizeof(xboxone_init3), { 0x00, 0x00 } }, - - /* These next packets are required for third party controllers (PowerA, PDP, HORI), - but aren't the correct protocol for Microsoft Xbox controllers. - */ - { 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init4, sizeof(xboxone_init4), { 0x00, 0x00 } }, - { 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init5, sizeof(xboxone_init5), { 0x00, 0x00 } }, }; typedef enum { @@ -120,6 +109,7 @@ typedef struct { Uint32 send_time; Uint8 last_state[USB_PACKET_LENGTH]; SDL_bool has_guide_packet; + SDL_bool has_color_led; SDL_bool has_paddles; SDL_bool has_trigger_rumble; SDL_bool has_share_button; @@ -129,20 +119,10 @@ typedef struct { Uint8 right_trigger_rumble; } SDL_DriverXboxOne_Context; - static SDL_bool -IsBluetoothXboxOneController(Uint16 vendor_id, Uint16 product_id) +ControllerHasColorLED(Uint16 vendor_id, Uint16 product_id) { - /* Check to see if it's the Xbox One S or Xbox One Elite Series 2 in Bluetooth mode */ - if (vendor_id == USB_VENDOR_MICROSOFT) { - if (product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH || - product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH || - product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH || - product_id == USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH) { - return SDL_TRUE; - } - } - return SDL_FALSE; + return (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2); } static SDL_bool @@ -154,13 +134,14 @@ ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id) static SDL_bool ControllerHasTriggerRumble(Uint16 vendor_id, Uint16 product_id) { - return SDL_IsJoystickXboxOneElite(vendor_id, product_id); + /* All the Microsoft Xbox One controllers have trigger rumble */ + return (vendor_id == USB_VENDOR_MICROSOFT); } static SDL_bool ControllerHasShareButton(Uint16 vendor_id, Uint16 product_id) { - return SDL_IsJoystickXboxOneSeriesX(vendor_id, product_id); + return SDL_IsJoystickXboxSeriesX(vendor_id, product_id); } static void @@ -179,7 +160,11 @@ SendAckIfNeeded(SDL_HIDAPI_Device *device, Uint8 *data, int size) /* The Windows driver is taking care of acks */ #else if ((data[1] & 0x30) == 0x30) { - Uint8 ack_packet[] = { 0x01, 0x20, data[2], 0x09, 0x00, data[0], 0x20, data[3], 0x00, 0x00, 0x00, 0x00, 0x00 }; + Uint8 ack_packet[] = { 0x01, 0x20, 0x00, 0x09, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + ack_packet[2] = data[2]; + ack_packet[5] = data[0]; + ack_packet[7] = data[3]; /* The initial ack needs 0x80 added to the response, for some reason */ if (data[0] == 0x04 && data[1] == 0xF0) { @@ -189,7 +174,10 @@ SendAckIfNeeded(SDL_HIDAPI_Device *device, Uint8 *data, int size) #ifdef DEBUG_XBOX_PROTOCOL HIDAPI_DumpPacket("Xbox One sending ACK packet: size = %d", ack_packet, sizeof(ack_packet)); #endif - hid_write(device->dev, ack_packet, sizeof(ack_packet)); + if (SDL_HIDAPI_LockRumble() < 0 || + SDL_HIDAPI_SendRumbleAndUnlock(device, ack_packet, sizeof(ack_packet)) != sizeof(ack_packet)) { + SDL_SetError("Couldn't send ack packet"); + } } #endif /* __WIN32__ */ } @@ -289,7 +277,7 @@ HIDAPI_DriverXboxOne_IsSupportedDevice(const char *name, SDL_GameControllerType #endif #ifdef __MACOSX__ /* Wired Xbox One controllers are handled by the 360Controller driver */ - if (!IsBluetoothXboxOneController(vendor_id, product_id)) { + if (!SDL_IsJoystickBluetoothXboxOne(vendor_id, product_id)) { return SDL_FALSE; } #endif @@ -333,7 +321,7 @@ HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst return SDL_FALSE; } - device->dev = hid_open_path(device->path, 0); + device->dev = SDL_hid_open_path(device->path, 0); if (!device->dev) { SDL_free(ctx); SDL_SetError("Couldn't open %s", device->path); @@ -343,9 +331,10 @@ HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst ctx->vendor_id = device->vendor_id; ctx->product_id = device->product_id; - ctx->bluetooth = IsBluetoothXboxOneController(device->vendor_id, device->product_id); + ctx->bluetooth = SDL_IsJoystickBluetoothXboxOne(device->vendor_id, device->product_id); ctx->start_time = SDL_GetTicks(); ctx->sequence = 1; + ctx->has_color_led = ControllerHasColorLED(ctx->vendor_id, ctx->product_id); ctx->has_paddles = ControllerHasPaddles(ctx->vendor_id, ctx->product_id); ctx->has_trigger_rumble = ControllerHasTriggerRumble(ctx->vendor_id, ctx->product_id); ctx->has_share_button = ControllerHasShareButton(ctx->vendor_id, ctx->product_id); @@ -437,15 +426,48 @@ HIDAPI_DriverXboxOne_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joyst return HIDAPI_DriverXboxOne_UpdateRumble(device); } -static SDL_bool -HIDAPI_DriverXboxOne_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +static Uint32 +HIDAPI_DriverXboxOne_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - /* Doesn't have an RGB LED, so don't return true here */ - return SDL_FALSE; + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context; + Uint32 result = 0; + + result |= SDL_JOYCAP_RUMBLE; + if (ctx->has_trigger_rumble) { + result |= SDL_JOYCAP_RUMBLE_TRIGGERS; + } + + if (ctx->has_color_led) { + result |= SDL_JOYCAP_LED; + } + + return result; } static int HIDAPI_DriverXboxOne_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context; + + if (ctx->has_color_led) { + Uint8 led_packet[] = { 0x0E, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + led_packet[5] = 0x00; /* Whiteness? Sets white intensity when RGB is 0, seems additive */ + led_packet[6] = red; + led_packet[7] = green; + led_packet[8] = blue; + + if (SDL_HIDAPI_SendRumble(device, led_packet, sizeof(led_packet)) != sizeof(led_packet)) { + return SDL_SetError("Couldn't send LED packet"); + } + return 0; + } else { + return SDL_Unsupported(); + } +} + +static int +HIDAPI_DriverXboxOne_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) { return SDL_Unsupported(); } @@ -488,14 +510,23 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne } if (ctx->has_share_button) { - /* Version 1 of the firmware for Xbox One Series X */ - if (ctx->last_state[18] != data[18]) { - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[18] & 0x01) ? SDL_PRESSED : SDL_RELEASED); - } - - /* Version 2 of the firmware for Xbox One Series X */ - if (ctx->last_state[22] != data[22]) { - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[22] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + /* Xbox Series X firmware version 5.0, report is 36 bytes, share button is in byte 18 + * Xbox Series X firmware version 5.1, report is 44 bytes, share button is in byte 18 + * Xbox Series X firmware version 5.5, report is 48 bytes, share button is in byte 22 + * Victrix Gambit Tournament Controller, report is 50 bytes, share button is in byte 32 + */ + if (size < 48) { + if (ctx->last_state[18] != data[18]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[18] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } + } else if (size == 48) { + if (ctx->last_state[22] != data[22]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[22] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } + } else if (size == 50) { + if (ctx->last_state[32] != data[32]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[32] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } } } @@ -504,12 +535,16 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne Paddle bits: P3: 0x01 (A) P1: 0x02 (B) P4: 0x04 (X) P2: 0x08 (Y) - Xbox One Elite Series 2 report is 38 bytes, paddles in data[18], mode in data[19], mode 0 has no mapped paddles by default + Xbox One Elite Series 2 4.x firmware report is 38 bytes, paddles in data[18], mode in data[19], mode 0 has no mapped paddles by default + Paddle bits: + P3: 0x04 (A) P1: 0x01 (B) + P4: 0x08 (X) P2: 0x02 (Y) + Xbox One Elite Series 2 5.x firmware report is 50 bytes, paddles in data[22], mode in data[23], mode 0 has no mapped paddles by default Paddle bits: P3: 0x04 (A) P1: 0x01 (B) P4: 0x08 (X) P2: 0x02 (Y) */ - if (ctx->has_paddles && (size == 33 || size == 38)) { + if (ctx->has_paddles && (size == 33 || size == 38 || size == 50)) { int paddle_index; int button1_bit; int button2_bit; @@ -526,9 +561,9 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne button4_bit = 0x04; /* The mapped controller state is at offset 4, the raw state is at offset 18, compare them to see if the paddles are mapped */ - paddles_mapped = (SDL_memcmp(&data[4], &data[18], 14) != 0); + paddles_mapped = (SDL_memcmp(&data[4], &data[18], 2) != 0); - } else /* if (size == 38) */ { + } else if (size == 38) { /* XBox One Elite Series 2 */ paddle_index = 18; button1_bit = 0x01; @@ -536,6 +571,15 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne button3_bit = 0x04; button4_bit = 0x08; paddles_mapped = (data[19] != 0); + + } else /* if (size == 50) */{ + /* XBox One Elite Series 2 */ + paddle_index = 22; + button1_bit = 0x01; + button2_bit = 0x02; + button3_bit = 0x04; + button4_bit = 0x08; + paddles_mapped = (data[23] != 0); } #ifdef DEBUG_XBOX_PROTOCOL SDL_Log(">>> Paddles: %d,%d,%d,%d mapped = %s\n", @@ -591,6 +635,14 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); } +static void +HIDAPI_DriverXboxOne_HandleStatusPacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) +{ + if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) { + SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE); + } +} + static void HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) { @@ -623,9 +675,11 @@ HIDAPI_DriverXboxOneBluetooth_HandleButtons16(SDL_Joystick *joystick, SDL_Driver /* * Xbox One S with firmware 4.8.1923 uses a 17 byte packet with BACK button in byte 16 and the GUIDE button in a separate packet (on Windows), or in byte 15 (on Linux) + * Xbox One S with firmware 5.x uses a 17 byte packet with BACK and GUIDE buttons in byte 15 * Xbox One Elite Series 2 with firmware 4.7.1872 uses a 55 byte packet with BACK button in byte 16, paddles starting at byte 33, and the GUIDE button in a separate packet * Xbox One Elite Series 2 with firmware 4.8.1908 uses a 33 byte packet with BACK button in byte 16, paddles starting at byte 17, and the GUIDE button in a separate packet - * Xbox One Series X with firmware 5.5.2641 uses a 17 byte packet with BACK and GUIDE buttons in byte 15, and SHARE button in byte 17 + * Xbox One Elite Series 2 with firmware 5.11.3112 uses a 19 byte packet with BACK and GUIDE buttons in byte 15 + * Xbox Series X with firmware 5.5.2641 uses a 17 byte packet with BACK and GUIDE buttons in byte 15, and SHARE button in byte 17 */ static void HIDAPI_DriverXboxOneBluetooth_HandleButtons(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) @@ -640,10 +694,7 @@ HIDAPI_DriverXboxOneBluetooth_HandleButtons(SDL_Joystick *joystick, SDL_DriverXb } if (ctx->last_state[15] != data[15]) { - if (ctx->has_share_button) { - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[15] & 0x04) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[15] & 0x10) ? SDL_PRESSED : SDL_RELEASED); - } else if (!ctx->has_guide_packet) { + if (!ctx->has_guide_packet) { SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[15] & 0x10) ? SDL_PRESSED : SDL_RELEASED); } SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[15] & 0x08) ? SDL_PRESSED : SDL_RELEASED); @@ -651,12 +702,11 @@ HIDAPI_DriverXboxOneBluetooth_HandleButtons(SDL_Joystick *joystick, SDL_DriverXb SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x40) ? SDL_PRESSED : SDL_RELEASED); } - if (ctx->last_state[16] != data[16]) { - if (ctx->has_share_button) { - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED); - } else { - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED); - } + if (ctx->has_share_button) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[15] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } else { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, ((data[15] & 0x04) || (data[16] & 0x01)) ? SDL_PRESSED : SDL_RELEASED); } /* @@ -723,8 +773,13 @@ HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(SDL_Joystick *joystick, SDL_Driv if (size == 16) { /* Original Xbox One S, with separate report for guide button */ HIDAPI_DriverXboxOneBluetooth_HandleButtons16(joystick, ctx, data, size); - } else { + } else if (size > 16) { HIDAPI_DriverXboxOneBluetooth_HandleButtons(joystick, ctx, data, size); + } else { +#ifdef DEBUG_XBOX_PROTOCOL + SDL_Log("Unknown Bluetooth state packet format\n"); +#endif + return; } if (ctx->last_state[13] != data[13]) { @@ -771,15 +826,6 @@ HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(SDL_Joystick *joystick, SDL_Driv SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); } - axis = (int)*(Uint16*)(&data[1]) - 0x8000; - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); - axis = (int)*(Uint16*)(&data[3]) - 0x8000; - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); - axis = (int)*(Uint16*)(&data[5]) - 0x8000; - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); - axis = (int)*(Uint16*)(&data[7]) - 0x8000; - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); - axis = ((int)*(Sint16*)(&data[9]) * 64) - 32768; if (axis == 32704) { axis = 32767; @@ -792,6 +838,15 @@ HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(SDL_Joystick *joystick, SDL_Driv } SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + axis = (int)*(Uint16*)(&data[1]) - 0x8000; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = (int)*(Uint16*)(&data[3]) - 0x8000; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = (int)*(Uint16*)(&data[5]) - 0x8000; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = (int)*(Uint16*)(&data[7]) - 0x8000; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); } @@ -904,7 +959,7 @@ HIDAPI_DriverXboxOne_UpdateJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy Uint8 data[USB_PACKET_LENGTH]; int size; - while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { #ifdef DEBUG_XBOX_PROTOCOL HIDAPI_DumpPacket("Xbox One packet: size = %d", data, size); #endif @@ -957,16 +1012,18 @@ HIDAPI_DriverXboxOne_UpdateJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy is firmware version 5.5.2641.0, and product version 0x0505 = 1285 then 8 bytes of unknown data */ + if (data[1] == 0x20) { #ifdef DEBUG_JOYSTICK - SDL_Log("Controller announce after %u ms\n", (SDL_GetTicks() - ctx->start_time)); + SDL_Log("Controller announce after %u ms\n", (SDL_GetTicks() - ctx->start_time)); #endif - SetInitState(ctx, XBOX_ONE_INIT_STATE_START_NEGOTIATING); + SetInitState(ctx, XBOX_ONE_INIT_STATE_START_NEGOTIATING); + } else { + /* Possibly an announce from a device plugged into the controller */ + } break; case 0x03: - /* Controller heartbeat */ - if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) { - SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE); - } + /* Controller status update */ + HIDAPI_DriverXboxOne_HandleStatusPacket(joystick, ctx, data, size); break; case 0x04: /* Unknown chatty controller information, sent by both sides */ @@ -1054,11 +1111,15 @@ HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device) static void HIDAPI_DriverXboxOne_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { - hid_close(device->dev); - device->dev = NULL; + SDL_LockMutex(device->dev_lock); + { + SDL_hid_close(device->dev); + device->dev = NULL; - SDL_free(device->context); - device->context = NULL; + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); } static void @@ -1070,6 +1131,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne = { SDL_HINT_JOYSTICK_HIDAPI_XBOX, SDL_TRUE, + SDL_TRUE, HIDAPI_DriverXboxOne_IsSupportedDevice, HIDAPI_DriverXboxOne_GetDeviceName, HIDAPI_DriverXboxOne_InitDevice, @@ -1079,8 +1141,9 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne = HIDAPI_DriverXboxOne_OpenJoystick, HIDAPI_DriverXboxOne_RumbleJoystick, HIDAPI_DriverXboxOne_RumbleJoystickTriggers, - HIDAPI_DriverXboxOne_HasJoystickLED, + HIDAPI_DriverXboxOne_GetJoystickCapabilities, HIDAPI_DriverXboxOne_SetJoystickLED, + HIDAPI_DriverXboxOne_SendJoystickEffect, HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled, HIDAPI_DriverXboxOne_CloseJoystick, HIDAPI_DriverXboxOne_FreeDevice, diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick.c index a6a1c3d87..55d9a1353 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,7 +25,6 @@ #include "SDL_atomic.h" #include "SDL_endian.h" #include "SDL_hints.h" -#include "SDL_thread.h" #include "SDL_timer.h" #include "SDL_joystick.h" #include "../SDL_sysjoystick.h" @@ -34,24 +33,9 @@ #include "../../SDL_hints_c.h" #if defined(__WIN32__) -#include "../../core/windows/SDL_windows.h" #include "../windows/SDL_rawinputjoystick_c.h" #endif -#if defined(__MACOSX__) -#include -#include -#include -#include -#include -#endif - -#if defined(__LINUX__) -#include "../../core/linux/SDL_udev.h" -#ifdef SDL_USE_LIBUDEV -#include -#endif -#endif struct joystick_hwdata { @@ -59,12 +43,21 @@ struct joystick_hwdata }; static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = { +#ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE + &SDL_HIDAPI_DriverGameCube, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_LUNA + &SDL_HIDAPI_DriverLuna, +#endif #ifdef SDL_JOYSTICK_HIDAPI_PS4 &SDL_HIDAPI_DriverPS4, #endif #ifdef SDL_JOYSTICK_HIDAPI_PS5 &SDL_HIDAPI_DriverPS5, #endif +#ifdef SDL_JOYSTICK_HIDAPI_STADIA + &SDL_HIDAPI_DriverStadia, +#endif #ifdef SDL_JOYSTICK_HIDAPI_STEAM &SDL_HIDAPI_DriverSteam, #endif @@ -78,317 +71,15 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = { #ifdef SDL_JOYSTICK_HIDAPI_XBOXONE &SDL_HIDAPI_DriverXboxOne, #endif -#ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE - &SDL_HIDAPI_DriverGameCube, -#endif }; static int SDL_HIDAPI_numdrivers = 0; static SDL_SpinLock SDL_HIDAPI_spinlock; +static Uint32 SDL_HIDAPI_change_count = 0; static SDL_HIDAPI_Device *SDL_HIDAPI_devices; static int SDL_HIDAPI_numjoysticks = 0; static SDL_bool initialized = SDL_FALSE; static SDL_bool shutting_down = SDL_FALSE; -#if defined(SDL_USE_LIBUDEV) -static const SDL_UDEV_Symbols * usyms = NULL; -#endif - -static struct -{ - SDL_bool m_bHaveDevicesChanged; - SDL_bool m_bCanGetNotifications; - Uint32 m_unLastDetect; - -#if defined(__WIN32__) - SDL_threadID m_nThreadID; - WNDCLASSEXA m_wndClass; - HWND m_hwndMsg; - HDEVNOTIFY m_hNotify; - double m_flLastWin32MessageCheck; -#endif - -#if defined(__MACOSX__) - IONotificationPortRef m_notificationPort; - mach_port_t m_notificationMach; -#endif - -#if defined(SDL_USE_LIBUDEV) - struct udev *m_pUdev; - struct udev_monitor *m_pUdevMonitor; - int m_nUdevFd; -#endif -} SDL_HIDAPI_discovery; - - -#ifdef __WIN32__ -struct _DEV_BROADCAST_HDR -{ - DWORD dbch_size; - DWORD dbch_devicetype; - DWORD dbch_reserved; -}; - -typedef struct _DEV_BROADCAST_DEVICEINTERFACE_A -{ - DWORD dbcc_size; - DWORD dbcc_devicetype; - DWORD dbcc_reserved; - GUID dbcc_classguid; - char dbcc_name[ 1 ]; -} DEV_BROADCAST_DEVICEINTERFACE_A, *PDEV_BROADCAST_DEVICEINTERFACE_A; - -typedef struct _DEV_BROADCAST_HDR DEV_BROADCAST_HDR; -#define DBT_DEVICEARRIVAL 0x8000 /* system detected a new device */ -#define DBT_DEVICEREMOVECOMPLETE 0x8004 /* device was removed from the system */ -#define DBT_DEVTYP_DEVICEINTERFACE 0x00000005 /* device interface class */ -#define DBT_DEVNODES_CHANGED 0x0007 -#define DBT_CONFIGCHANGED 0x0018 -#define DBT_DEVICETYPESPECIFIC 0x8005 /* type specific event */ -#define DBT_DEVINSTSTARTED 0x8008 /* device installed and started */ - -#include -DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); - -static LRESULT CALLBACK ControllerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_DEVICECHANGE: - switch (wParam) { - case DBT_DEVICEARRIVAL: - case DBT_DEVICEREMOVECOMPLETE: - if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { - SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE; - } - break; - } - return TRUE; - } - - return DefWindowProc(hwnd, message, wParam, lParam); -} -#endif /* __WIN32__ */ - - -#if defined(__MACOSX__) -static void CallbackIOServiceFunc(void *context, io_iterator_t portIterator) -{ - /* Must drain the iterator, or we won't receive new notifications */ - io_object_t entry; - while ((entry = IOIteratorNext(portIterator)) != 0) { - IOObjectRelease(entry); - *(SDL_bool*)context = SDL_TRUE; - } -} -#endif /* __MACOSX__ */ - -static void -HIDAPI_InitializeDiscovery() -{ - SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE; - SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_FALSE; - SDL_HIDAPI_discovery.m_unLastDetect = 0; - -#if defined(__WIN32__) - SDL_HIDAPI_discovery.m_nThreadID = SDL_ThreadID(); - - SDL_zero(SDL_HIDAPI_discovery.m_wndClass); - SDL_HIDAPI_discovery.m_wndClass.hInstance = GetModuleHandle(NULL); - SDL_HIDAPI_discovery.m_wndClass.lpszClassName = "SDL_HIDAPI_DEVICE_DETECTION"; - SDL_HIDAPI_discovery.m_wndClass.lpfnWndProc = ControllerWndProc; /* This function is called by windows */ - SDL_HIDAPI_discovery.m_wndClass.cbSize = sizeof(WNDCLASSEX); - - RegisterClassExA(&SDL_HIDAPI_discovery.m_wndClass); - SDL_HIDAPI_discovery.m_hwndMsg = CreateWindowExA(0, "SDL_HIDAPI_DEVICE_DETECTION", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); - - { - DEV_BROADCAST_DEVICEINTERFACE_A devBroadcast; - - SDL_zero(devBroadcast); - devBroadcast.dbcc_size = sizeof( devBroadcast ); - devBroadcast.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - devBroadcast.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; - - /* DEVICE_NOTIFY_ALL_INTERFACE_CLASSES is important, makes GUID_DEVINTERFACE_USB_DEVICE ignored, - * but that seems to be necessary to get a notice after each individual usb input device actually - * installs, rather than just as the composite device is seen. - */ - SDL_HIDAPI_discovery.m_hNotify = RegisterDeviceNotification( SDL_HIDAPI_discovery.m_hwndMsg, &devBroadcast, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES ); - SDL_HIDAPI_discovery.m_bCanGetNotifications = ( SDL_HIDAPI_discovery.m_hNotify != 0 ); - } -#endif /* __WIN32__ */ - -#if defined(__MACOSX__) - SDL_HIDAPI_discovery.m_notificationPort = IONotificationPortCreate(kIOMasterPortDefault); - if (SDL_HIDAPI_discovery.m_notificationPort) { - { - io_iterator_t portIterator = 0; - io_object_t entry; - IOReturn result = IOServiceAddMatchingNotification( - SDL_HIDAPI_discovery.m_notificationPort, - kIOFirstMatchNotification, - IOServiceMatching(kIOHIDDeviceKey), - CallbackIOServiceFunc, &SDL_HIDAPI_discovery.m_bHaveDevicesChanged, &portIterator); - - if (result == 0) { - /* Must drain the existing iterator, or we won't receive new notifications */ - while ((entry = IOIteratorNext(portIterator)) != 0) { - IOObjectRelease(entry); - } - } else { - IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort); - SDL_HIDAPI_discovery.m_notificationPort = nil; - } - } - { - io_iterator_t portIterator = 0; - io_object_t entry; - IOReturn result = IOServiceAddMatchingNotification( - SDL_HIDAPI_discovery.m_notificationPort, - kIOTerminatedNotification, - IOServiceMatching(kIOHIDDeviceKey), - CallbackIOServiceFunc, &SDL_HIDAPI_discovery.m_bHaveDevicesChanged, &portIterator); - - if (result == 0) { - /* Must drain the existing iterator, or we won't receive new notifications */ - while ((entry = IOIteratorNext(portIterator)) != 0) { - IOObjectRelease(entry); - } - } else { - IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort); - SDL_HIDAPI_discovery.m_notificationPort = nil; - } - } - } - - SDL_HIDAPI_discovery.m_notificationMach = MACH_PORT_NULL; - if (SDL_HIDAPI_discovery.m_notificationPort) { - SDL_HIDAPI_discovery.m_notificationMach = IONotificationPortGetMachPort(SDL_HIDAPI_discovery.m_notificationPort); - } - - SDL_HIDAPI_discovery.m_bCanGetNotifications = (SDL_HIDAPI_discovery.m_notificationMach != MACH_PORT_NULL); - -#endif // __MACOSX__ - -#if defined(SDL_USE_LIBUDEV) - SDL_HIDAPI_discovery.m_pUdev = NULL; - SDL_HIDAPI_discovery.m_pUdevMonitor = NULL; - SDL_HIDAPI_discovery.m_nUdevFd = -1; - - usyms = SDL_UDEV_GetUdevSyms(); - if (usyms) { - SDL_HIDAPI_discovery.m_pUdev = usyms->udev_new(); - } - if (SDL_HIDAPI_discovery.m_pUdev) { - SDL_HIDAPI_discovery.m_pUdevMonitor = usyms->udev_monitor_new_from_netlink(SDL_HIDAPI_discovery.m_pUdev, "udev"); - if (SDL_HIDAPI_discovery.m_pUdevMonitor) { - usyms->udev_monitor_enable_receiving(SDL_HIDAPI_discovery.m_pUdevMonitor); - SDL_HIDAPI_discovery.m_nUdevFd = usyms->udev_monitor_get_fd(SDL_HIDAPI_discovery.m_pUdevMonitor); - SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE; - } - } - -#endif /* SDL_USE_LIBUDEV */ -} - -static void -HIDAPI_UpdateDiscovery() -{ - if (!SDL_HIDAPI_discovery.m_bCanGetNotifications) { - const Uint32 SDL_HIDAPI_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */ - Uint32 now = SDL_GetTicks(); - if (!SDL_HIDAPI_discovery.m_unLastDetect || SDL_TICKS_PASSED(now, SDL_HIDAPI_discovery.m_unLastDetect + SDL_HIDAPI_DETECT_INTERVAL_MS)) { - SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE; - SDL_HIDAPI_discovery.m_unLastDetect = now; - } - return; - } - -#if defined(__WIN32__) -#if 0 /* just let the usual SDL_PumpEvents loop dispatch these, fixing bug 4286. --ryan. */ - /* We'll only get messages on the same thread that created the window */ - if (SDL_ThreadID() == SDL_HIDAPI_discovery.m_nThreadID) { - MSG msg; - while (PeekMessage(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0, PM_NOREMOVE)) { - if (GetMessageA(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0) != 0) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - } -#endif -#endif /* __WIN32__ */ - -#if defined(__MACOSX__) - if (SDL_HIDAPI_discovery.m_notificationPort) { - struct { mach_msg_header_t hdr; char payload[ 4096 ]; } msg; - while (mach_msg(&msg.hdr, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(msg), SDL_HIDAPI_discovery.m_notificationMach, 0, MACH_PORT_NULL) == KERN_SUCCESS) { - IODispatchCalloutFromMessage(NULL, &msg.hdr, SDL_HIDAPI_discovery.m_notificationPort); - } - } -#endif - -#if defined(SDL_USE_LIBUDEV) - if (SDL_HIDAPI_discovery.m_nUdevFd >= 0) { - /* Drain all notification events. - * We don't expect a lot of device notifications so just - * do a new discovery on any kind or number of notifications. - * This could be made more restrictive if necessary. - */ - for (;;) { - struct pollfd PollUdev; - struct udev_device *pUdevDevice; - - PollUdev.fd = SDL_HIDAPI_discovery.m_nUdevFd; - PollUdev.events = POLLIN; - if (poll(&PollUdev, 1, 0) != 1) { - break; - } - - SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE; - - pUdevDevice = usyms->udev_monitor_receive_device(SDL_HIDAPI_discovery.m_pUdevMonitor); - if (pUdevDevice) { - usyms->udev_device_unref(pUdevDevice); - } - } - } -#endif -} - -static void -HIDAPI_ShutdownDiscovery() -{ -#if defined(__WIN32__) - if (SDL_HIDAPI_discovery.m_hNotify) - UnregisterDeviceNotification(SDL_HIDAPI_discovery.m_hNotify); - - if (SDL_HIDAPI_discovery.m_hwndMsg) { - DestroyWindow(SDL_HIDAPI_discovery.m_hwndMsg); - } - - UnregisterClassA(SDL_HIDAPI_discovery.m_wndClass.lpszClassName, SDL_HIDAPI_discovery.m_wndClass.hInstance); -#endif - -#if defined(__MACOSX__) - if (SDL_HIDAPI_discovery.m_notificationPort) { - IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort); - } -#endif - -#if defined(SDL_USE_LIBUDEV) - if (usyms) { - if (SDL_HIDAPI_discovery.m_pUdevMonitor) { - usyms->udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor); - } - if (SDL_HIDAPI_discovery.m_pUdev) { - usyms->udev_unref(SDL_HIDAPI_discovery.m_pUdev); - } - SDL_UDEV_ReleaseUdevSyms(); - usyms = NULL; - } -#endif -} - void HIDAPI_DumpPacket(const char *prefix, Uint8 *data, int size) { @@ -410,8 +101,14 @@ HIDAPI_DumpPacket(const char *prefix, Uint8 *data, int size) SDL_free(buffer); } +float +HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float output_max) +{ + return output_min + (output_max - output_min) * (val - val_min) / (val_max - val_min); +} + static void HIDAPI_JoystickDetect(void); -static void HIDAPI_JoystickClose(SDL_Joystick * joystick); +static void HIDAPI_JoystickClose(SDL_Joystick *joystick); static SDL_bool HIDAPI_IsDeviceSupported(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) @@ -437,8 +134,14 @@ HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device) const Uint16 USAGE_MULTIAXISCONTROLLER = 0x0008; int i; SDL_GameControllerType type; + SDL_JoystickGUID check_guid; - if (SDL_ShouldIgnoreJoystick(device->name, device->guid)) { + /* Make sure we have a generic GUID here, otherwise if we pass a HIDAPI + guid, this call will create a game controller mapping for the device. + */ + check_guid = device->guid; + check_guid.data[14] = 0; + if (SDL_ShouldIgnoreJoystick(device->name, check_guid)) { return NULL; } @@ -498,8 +201,7 @@ static void HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device) { if (device->driver) { - /* Already setup */ - return; + return; /* Already setup */ } device->driver = HIDAPI_GetDeviceDriver(device); @@ -521,8 +223,7 @@ static void HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device) { if (!device->driver) { - /* Already cleaned up */ - return; + return; /* Already cleaned up */ } /* Disconnect any joysticks */ @@ -585,19 +286,30 @@ HIDAPI_JoystickInit(void) return 0; } -#if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__) - /* The hidapi framwork is weak-linked on Apple platforms */ - int HID_API_EXPORT HID_API_CALL hid_init(void) __attribute__((weak_import)); - - if (hid_init == NULL) { - SDL_SetError("Couldn't initialize hidapi, framework not available"); - return -1; +#if defined(SDL_USE_LIBUDEV) + if (linux_enumeration_method == ENUMERATION_UNSET) { + if (SDL_getenv("SDL_HIDAPI_JOYSTICK_DISABLE_UDEV") != NULL) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "udev disabled by SDL_HIDAPI_JOYSTICK_DISABLE_UDEV"); + linux_enumeration_method = ENUMERATION_FALLBACK; + } else if (access("/.flatpak-info", F_OK) == 0 + || access("/run/host/container-manager", F_OK) == 0) { + /* Explicitly check `/.flatpak-info` because, for old versions of + * Flatpak, this was the only available way to tell if we were in + * a Flatpak container. */ + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Container detected, disabling HIDAPI udev integration"); + linux_enumeration_method = ENUMERATION_FALLBACK; + } else { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Using udev for HIDAPI joystick device discovery"); + linux_enumeration_method = ENUMERATION_LIBUDEV; + } } -#endif /* __MACOSX__ || __IPHONEOS__ || __TVOS__ */ +#endif - if (hid_init() < 0) { - SDL_SetError("Couldn't initialize hidapi"); - return -1; + if (SDL_hid_init() < 0) { + return SDL_SetError("Couldn't initialize hidapi"); } for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) { @@ -606,7 +318,6 @@ HIDAPI_JoystickInit(void) } SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPIDriverHintChanged, NULL); - HIDAPI_InitializeDiscovery(); HIDAPI_JoystickDetect(); HIDAPI_UpdateDevices(); @@ -681,10 +392,13 @@ HIDAPI_ConvertString(const wchar_t *wide_string) if (wide_string) { string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t)); if (!string) { - if (sizeof(wchar_t) == sizeof(Uint16)) { + switch (sizeof(wchar_t)) { + case 2: string = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t)); - } else if (sizeof(wchar_t) == sizeof(Uint32)) { + break; + case 4: string = SDL_iconv_string("UTF-8", "UCS-4-INTERNAL", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t)); + break; } } } @@ -692,7 +406,7 @@ HIDAPI_ConvertString(const wchar_t *wide_string) } static void -HIDAPI_AddDevice(struct hid_device_info *info) +HIDAPI_AddDevice(struct SDL_hid_device_info *info) { SDL_HIDAPI_Device *device; SDL_HIDAPI_Device *curr, *last = NULL; @@ -856,7 +570,7 @@ static void HIDAPI_UpdateDeviceList(void) { SDL_HIDAPI_Device *device; - struct hid_device_info *devs, *info; + struct SDL_hid_device_info *devs, *info; SDL_LockJoysticks(); @@ -869,7 +583,7 @@ HIDAPI_UpdateDeviceList(void) /* Enumerate the devices */ if (SDL_HIDAPI_numdrivers > 0) { - devs = hid_enumerate(0, 0); + devs = SDL_hid_enumerate(0, 0); if (devs) { for (info = devs; info; info = info->next) { device = HIDAPI_GetJoystickByInfo(info->path, info->vendor_id, info->product_id); @@ -879,16 +593,17 @@ HIDAPI_UpdateDeviceList(void) HIDAPI_AddDevice(info); } } - hid_free_enumeration(devs); + SDL_hid_free_enumeration(devs); } } - /* Remove any devices that weren't seen */ + /* Remove any devices that weren't seen or have been disconnected due to read errors */ device = SDL_HIDAPI_devices; while (device) { SDL_HIDAPI_Device *next = device->next; - if (!device->seen) { + if (!device->seen || + (device->driver && device->num_joysticks == 0 && !device->dev)) { HIDAPI_DelDevice(device); } device = next; @@ -906,12 +621,12 @@ HIDAPI_IsEquivalentToDevice(Uint16 vendor_id, Uint16 product_id, SDL_HIDAPI_Devi if (vendor_id == USB_VENDOR_MICROSOFT) { /* If we're looking for the wireless XBox 360 controller, also look for the dongle */ - if (product_id == 0x02a1 && device->product_id == 0x0719) { + if (product_id == USB_PRODUCT_XBOX360_XUSB_CONTROLLER && device->product_id == USB_PRODUCT_XBOX360_WIRELESS_RECEIVER) { return SDL_TRUE; } /* If we're looking for the raw input Xbox One controller, match it against any other Xbox One controller */ - if (product_id == USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER && + if (product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER && SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == SDL_CONTROLLER_TYPE_XBOXONE) { return SDL_TRUE; } @@ -927,6 +642,40 @@ HIDAPI_IsEquivalentToDevice(Uint16 vendor_id, Uint16 product_id, SDL_HIDAPI_Devi return SDL_FALSE; } +SDL_bool +HIDAPI_IsDeviceTypePresent(SDL_GameControllerType type) +{ + SDL_HIDAPI_Device *device; + SDL_bool result = SDL_FALSE; + + /* Make sure we're initialized, as this could be called from other drivers during startup */ + if (HIDAPI_JoystickInit() < 0) { + return SDL_FALSE; + } + + if (SDL_AtomicTryLock(&SDL_HIDAPI_spinlock)) { + HIDAPI_UpdateDeviceList(); + SDL_AtomicUnlock(&SDL_HIDAPI_spinlock); + } + + SDL_LockJoysticks(); + device = SDL_HIDAPI_devices; + while (device) { + if (device->driver && + SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == type) { + result = SDL_TRUE; + break; + } + device = device->next; + } + SDL_UnlockJoysticks(); + +#ifdef DEBUG_HIDAPI + SDL_Log("HIDAPI_IsDeviceTypePresent() returning %s for %d\n", result ? "true" : "false", type); +#endif + return result; +} + SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) { @@ -969,6 +718,7 @@ HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, cons if (device->driver && HIDAPI_IsEquivalentToDevice(vendor_id, product_id, device)) { result = SDL_TRUE; + break; } device = device->next; } @@ -984,11 +734,10 @@ static void HIDAPI_JoystickDetect(void) { if (SDL_AtomicTryLock(&SDL_HIDAPI_spinlock)) { - HIDAPI_UpdateDiscovery(); - if (SDL_HIDAPI_discovery.m_bHaveDevicesChanged) { - /* FIXME: We probably need to schedule an update in a few seconds as well */ + Uint32 count = SDL_hid_device_change_count(); + if (SDL_HIDAPI_change_count != count) { HIDAPI_UpdateDeviceList(); - SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_FALSE; + SDL_HIDAPI_change_count = count; } SDL_AtomicUnlock(&SDL_HIDAPI_spinlock); } @@ -1086,7 +835,7 @@ HIDAPI_JoystickGetDeviceInstanceID(int device_index) } static int -HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index) +HIDAPI_JoystickOpen(SDL_Joystick *joystick, int device_index) { SDL_JoystickID joystickID; SDL_HIDAPI_Device *device = HIDAPI_GetDeviceByIndex(device_index, &joystickID); @@ -1112,7 +861,7 @@ HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index) } static int -HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +HIDAPI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { int result; @@ -1121,15 +870,14 @@ HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint result = device->driver->RumbleJoystick(device, joystick, low_frequency_rumble, high_frequency_rumble); } else { - SDL_SetError("Rumble failed, device disconnected"); - result = -1; + result = SDL_SetError("Rumble failed, device disconnected"); } return result; } static int -HIDAPI_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble) +HIDAPI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { int result; @@ -1138,29 +886,28 @@ HIDAPI_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint1 result = device->driver->RumbleJoystickTriggers(device, joystick, left_rumble, right_rumble); } else { - SDL_SetError("Rumble failed, device disconnected"); - result = -1; + result = SDL_SetError("Rumble failed, device disconnected"); } return result; } -static SDL_bool -HIDAPI_JoystickHasLED(SDL_Joystick * joystick) +static Uint32 +HIDAPI_JoystickGetCapabilities(SDL_Joystick *joystick) { - SDL_bool result = SDL_FALSE; + Uint32 result = 0; if (joystick->hwdata) { SDL_HIDAPI_Device *device = joystick->hwdata->device; - result = device->driver->HasJoystickLED(device, joystick); + result = device->driver->GetJoystickCapabilities(device, joystick); } return result; } static int -HIDAPI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) +HIDAPI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) { int result; @@ -1169,15 +916,30 @@ HIDAPI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blu result = device->driver->SetJoystickLED(device, joystick, red, green, blue); } else { - SDL_SetError("SetLED failed, device disconnected"); - result = -1; + result = SDL_SetError("SetLED failed, device disconnected"); } return result; } static int -HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick * joystick, SDL_bool enabled) +HIDAPI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + int result; + + if (joystick->hwdata) { + SDL_HIDAPI_Device *device = joystick->hwdata->device; + + result = device->driver->SendJoystickEffect(device, joystick, data, size); + } else { + result = SDL_SetError("SendEffect failed, device disconnected"); + } + + return result; +} + +static int +HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) { int result; @@ -1186,21 +948,20 @@ HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick * joystick, SDL_bool enabled) result = device->driver->SetJoystickSensorsEnabled(device, joystick, enabled); } else { - SDL_SetError("SetSensorsEnabled failed, device disconnected"); - result = -1; + result = SDL_SetError("SetSensorsEnabled failed, device disconnected"); } return result; } static void -HIDAPI_JoystickUpdate(SDL_Joystick * joystick) +HIDAPI_JoystickUpdate(SDL_Joystick *joystick) { /* This is handled in SDL_HIDAPI_UpdateDevices() */ } static void -HIDAPI_JoystickClose(SDL_Joystick * joystick) +HIDAPI_JoystickClose(SDL_Joystick *joystick) { if (joystick->hwdata) { SDL_HIDAPI_Device *device = joystick->hwdata->device; @@ -1235,8 +996,6 @@ HIDAPI_JoystickQuit(void) shutting_down = SDL_TRUE; - HIDAPI_ShutdownDiscovery(); - SDL_HIDAPI_QuitRumble(); while (SDL_HIDAPI_devices) { @@ -1253,7 +1012,7 @@ HIDAPI_JoystickQuit(void) SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPIDriverHintChanged, NULL); - hid_exit(); + SDL_hid_exit(); shutting_down = SDL_FALSE; initialized = SDL_FALSE; @@ -1278,8 +1037,9 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver = HIDAPI_JoystickOpen, HIDAPI_JoystickRumble, HIDAPI_JoystickRumbleTriggers, - HIDAPI_JoystickHasLED, + HIDAPI_JoystickGetCapabilities, HIDAPI_JoystickSetLED, + HIDAPI_JoystickSendEffect, HIDAPI_JoystickSetSensorsEnabled, HIDAPI_JoystickUpdate, HIDAPI_JoystickClose, diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick_c.h b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick_c.h index 5af5b08c0..c1b75d8db 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,16 +27,18 @@ #include "SDL_mutex.h" #include "SDL_joystick.h" #include "SDL_gamecontroller.h" -#include "../../hidapi/hidapi/hidapi.h" +#include "SDL_hidapi.h" #include "../usb_ids.h" /* This is the full set of HIDAPI drivers available */ +#define SDL_JOYSTICK_HIDAPI_GAMECUBE +#define SDL_JOYSTICK_HIDAPI_LUNA #define SDL_JOYSTICK_HIDAPI_PS4 #define SDL_JOYSTICK_HIDAPI_PS5 +#define SDL_JOYSTICK_HIDAPI_STADIA #define SDL_JOYSTICK_HIDAPI_SWITCH #define SDL_JOYSTICK_HIDAPI_XBOX360 #define SDL_JOYSTICK_HIDAPI_XBOXONE -#define SDL_JOYSTICK_HIDAPI_GAMECUBE #if defined(__IPHONEOS__) || defined(__TVOS__) || defined(__ANDROID__) /* Very basic Steam Controller support on mobile devices */ @@ -68,7 +70,7 @@ typedef struct _SDL_HIDAPI_Device struct _SDL_HIDAPI_DeviceDriver *driver; void *context; SDL_mutex *dev_lock; - hid_device *dev; + SDL_hid_device *dev; SDL_atomic_t rumble_pending; int num_joysticks; SDL_JoystickID *joysticks; @@ -86,6 +88,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver { const char *hint; SDL_bool enabled; + SDL_bool enabled_default; SDL_bool (*IsSupportedDevice)(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol); const char *(*GetDeviceName)(Uint16 vendor_id, Uint16 product_id); SDL_bool (*InitDevice)(SDL_HIDAPI_Device *device); @@ -95,8 +98,9 @@ typedef struct _SDL_HIDAPI_DeviceDriver SDL_bool (*OpenJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); int (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); int (*RumbleJoystickTriggers)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble); - SDL_bool (*HasJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); + Uint32 (*GetJoystickCapabilities)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); int (*SetJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); + int (*SendJoystickEffect)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size); int (*SetJoystickSensorsEnabled)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled); void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); void (*FreeDevice)(SDL_HIDAPI_Device *device); @@ -105,14 +109,19 @@ typedef struct _SDL_HIDAPI_DeviceDriver /* HIDAPI device support */ +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne; -extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube; + +/* Return true if a HID device is present and supported as a joystick of the given type */ +extern SDL_bool HIDAPI_IsDeviceTypePresent(SDL_GameControllerType type); /* Return true if a HID device is present and supported as a joystick */ extern SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name); @@ -123,6 +132,8 @@ extern void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickI extern void HIDAPI_DumpPacket(const char *prefix, Uint8 *data, int size); +extern float HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float output_max); + #endif /* SDL_JOYSTICK_HIDAPI_H */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/joystick/hidapi/steam/controller_constants.h b/Engine/lib/sdl/src/joystick/hidapi/steam/controller_constants.h index d57315ba9..d0d568851 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/steam/controller_constants.h +++ b/Engine/lib/sdl/src/joystick/hidapi/steam/controller_constants.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 2020 Valve Corporation + Copyright (C) 2021 Valve Corporation This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/joystick/hidapi/steam/controller_structs.h b/Engine/lib/sdl/src/joystick/hidapi/steam/controller_structs.h index 967c96f40..c8fd61226 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/steam/controller_structs.h +++ b/Engine/lib/sdl/src/joystick/hidapi/steam/controller_structs.h @@ -23,6 +23,43 @@ #pragma pack(1) +#define HID_FEATURE_REPORT_BYTES 64 + +// Header for all host <==> target messages +typedef struct +{ + unsigned char type; + unsigned char length; +} FeatureReportHeader; + +// Generic controller attribute structure +typedef struct +{ + unsigned char attributeTag; + uint32_t attributeValue; +} ControllerAttribute; + +// Generic controller settings structure +typedef struct +{ + ControllerAttribute attributes[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerAttribute ) ]; +} MsgGetAttributes; + + +// This is the only message struct that application code should use to interact with feature request messages. Any new +// messages should be added to the union. The structures defined here should correspond to the ones defined in +// ValveDeviceCore.cpp. +// +typedef struct +{ + FeatureReportHeader header; + union + { + MsgGetAttributes getAttributes; + } payload; + +} FeatureReportMsg; + // Roll this version forward anytime that you are breaking compatibility of existing // message types within ValveInReport_t or the header itself. Hopefully this should // be super rare and instead you shoudl just add new message payloads to the union, diff --git a/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick.m b/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick.m index 0c802216a..c75fbbae2 100644 --- a/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick.m +++ b/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,6 +27,7 @@ #include "SDL_stdinc.h" #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" +#include "../hidapi/SDL_hidapijoystick_c.h" #include "../usb_ids.h" #include "SDL_mfijoystick_c.h" @@ -53,6 +54,7 @@ static id connectObserver = nil; static id disconnectObserver = nil; +static NSString *GCInputXboxShareButton = @"Button Share"; #include #include @@ -64,6 +66,12 @@ static id disconnectObserver = nil; #if defined(__MACOSX__) && (__MAC_OS_X_VERSION_MAX_ALLOWED <= 101600) + (BOOL)supportsHIDDevice:(IOHIDDeviceRef)device; #endif +#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 130000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 130000) || (__MAC_OS_VERSION_MAX_ALLOWED >= 1500000)) +@property(nonatomic, readonly) NSString *productCategory; +#endif +#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 140500) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 140500) || (__MAC_OS_X_VERSION_MAX_ALLOWED >= 110300)) +@property(class, nonatomic, readwrite) BOOL shouldMonitorBackgroundEvents; +#endif @end @interface GCExtendedGamepad (SDL) #if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 121000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 121000) || (__MAC_OS_VERSION_MAX_ALLOWED >= 1401000)) @@ -89,6 +97,7 @@ static id disconnectObserver = nil; #define ENABLE_MFI_RUMBLE #define ENABLE_MFI_LIGHT #define ENABLE_MFI_SENSORS +#define ENABLE_MFI_SYSTEM_GESTURE_STATE #define ENABLE_PHYSICAL_INPUT_PROFILE #endif @@ -126,7 +135,49 @@ GetDeviceForIndex(int device_index) } #ifdef SDL_JOYSTICK_MFI -static void +static BOOL +IsControllerPS4(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"DualShock 4"]) { + return TRUE; + } + } else { + if ([controller.vendorName containsString: @"DUALSHOCK"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL +IsControllerPS5(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"DualSense"]) { + return TRUE; + } + } else { + if ([controller.vendorName containsString: @"DualSense"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL +IsControllerXbox(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"Xbox One"]) { + return TRUE; + } + } else { + if ([controller.vendorName containsString: @"Xbox"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller) { Uint16 *guid16 = (Uint16 *)device->guid.data; @@ -151,13 +202,23 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle if (controller.extendedGamepad) { GCExtendedGamepad *gamepad = controller.extendedGamepad; - BOOL is_xbox = [controller.vendorName containsString: @"Xbox"]; - BOOL is_ps4 = [controller.vendorName containsString: @"DUALSHOCK"]; + BOOL is_xbox = IsControllerXbox(controller); + BOOL is_ps4 = IsControllerPS4(controller); + BOOL is_ps5 = IsControllerPS5(controller); #if TARGET_OS_TV - BOOL is_MFi = (!is_xbox && !is_ps4); + BOOL is_MFi = (!is_xbox && !is_ps4 && !is_ps5); #endif int nbuttons = 0; +#ifdef SDL_JOYSTICK_HIDAPI + if ((is_xbox && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_XBOXONE)) || + (is_ps4 && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_PS4)) || + (is_ps5 && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_PS5))) { + /* The HIDAPI driver is taking care of this device */ + return FALSE; + } +#endif + /* These buttons are part of the original MFi spec */ device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A); device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B); @@ -226,6 +287,11 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_PADDLE4); ++nbuttons; } + if (controller.physicalInputProfile.buttons[GCInputXboxShareButton] != nil) { + device->has_xbox_share_button = SDL_TRUE; + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_MISC1); + ++nbuttons; + } } #endif #pragma clang diagnostic pop @@ -236,8 +302,12 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle /* Assume Xbox One Elite Series 2 Controller unless/until GCController flows VID/PID */ product = USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH; subtype = 1; + } else if (device->has_xbox_share_button) { + /* Assume Xbox Series X Controller unless/until GCController flows VID/PID */ + product = USB_PRODUCT_XBOX_SERIES_X_BLE; + subtype = 1; } else { - /* Assume Xbox One S BLE Controller unless/until GCController flows VID/PID */ + /* Assume Xbox One S Bluetooth Controller unless/until GCController flows VID/PID */ product = USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH; subtype = 0; } @@ -250,6 +320,10 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle } else { subtype = 0; } + } else if (is_ps5) { + vendor = USB_VENDOR_SONY; + product = USB_PRODUCT_SONY_DS5; + subtype = 0; } else { vendor = USB_VENDOR_APPLE; product = 1; @@ -326,6 +400,7 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle /* This will be set when the first button press of the controller is * detected. */ controller.playerIndex = -1; + return TRUE; } #endif /* SDL_JOYSTICK_MFI */ @@ -374,7 +449,10 @@ IOS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer) #endif /* SDL_JOYSTICK_iOS_ACCELEROMETER */ } else if (controller) { #ifdef SDL_JOYSTICK_MFI - IOS_AddMFIJoystickDevice(device, controller); + if (!IOS_AddMFIJoystickDevice(device, controller)) { + SDL_free(device); + return; + } #else SDL_free(device); return; @@ -497,6 +575,10 @@ IOS_JoystickInit(void) return 0; } + if (@available(macOS 11.3, iOS 14.5, tvOS 14.5, *)) { + GCController.shouldMonitorBackgroundEvents = YES; + } + /* For whatever reason, this always returns an empty array on macOS 11.0.1 */ for (GCController *controller in [GCController controllers]) { @@ -580,7 +662,7 @@ IOS_JoystickSetDevicePlayerIndex(int device_index, int player_index) } static SDL_JoystickGUID -IOS_JoystickGetDeviceGUID( int device_index ) +IOS_JoystickGetDeviceGUID(int device_index) { SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index); SDL_JoystickGUID guid; @@ -648,14 +730,26 @@ IOS_JoystickOpen(SDL_Joystick *joystick, int device_index) GCController *controller = joystick->hwdata->controller; GCMotion *motion = controller.motion; if (motion && motion.hasRotationRate) { - SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 0.0f); } if (motion && motion.hasGravityAndUserAcceleration) { - SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 0.0f); } } #endif /* ENABLE_MFI_SENSORS */ +#ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE + if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { + GCController *controller = joystick->hwdata->controller; + for (id key in controller.physicalInputProfile.buttons) { + GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key]; + if ([button isBoundToSystemGesture]) { + button.preferredSystemGestureState = GCSystemGestureStateDisabled; + } + } + } +#endif /* ENABLE_MFI_SYSTEM_GESTURE_STATE */ + #endif /* SDL_JOYSTICK_MFI */ } } @@ -699,9 +793,9 @@ IOS_AccelerometerUpdate(SDL_Joystick *joystick) */ /* clamp the data */ - accel.x = SDL_min(SDL_max(accel.x, -maxgforce), maxgforce); - accel.y = SDL_min(SDL_max(accel.y, -maxgforce), maxgforce); - accel.z = SDL_min(SDL_max(accel.z, -maxgforce), maxgforce); + accel.x = SDL_clamp(accel.x, -maxgforce, maxgforce); + accel.y = SDL_clamp(accel.y, -maxgforce, maxgforce); + accel.z = SDL_clamp(accel.z, -maxgforce, maxgforce); /* pass in data mapped to range of SInt16 */ SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16); @@ -839,6 +933,10 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) controller.physicalInputProfile.buttons[GCInputXboxPaddleFour].isPressed); */ } + + if (joystick->hwdata->has_xbox_share_button) { + buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxShareButton].isPressed; + } #endif #pragma clang diagnostic pop @@ -987,23 +1085,27 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) #ifdef ENABLE_MFI_RUMBLE @interface SDL_RumbleMotor : NSObject + @property(nonatomic,strong) CHHapticEngine *engine API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0)); + @property(nonatomic,strong) id player API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0)); + @property bool active; @end @implementation SDL_RumbleMotor { - CHHapticEngine *engine API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0)); - id player API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0)); - bool active; } -(void)cleanup { - if (self->player != nil) { - [self->player cancelAndReturnError:nil]; - self->player = nil; - } - if (self->engine != nil) { - [self->engine stopWithCompletionHandler:nil]; - self->engine = nil; + @autoreleasepool { + if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { + if (self.player != nil) { + [self.player cancelAndReturnError:nil]; + self.player = nil; + } + if (self.engine != nil) { + [self.engine stopWithCompletionHandler:nil]; + self.engine = nil; + } + } } } @@ -1011,21 +1113,21 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) { @autoreleasepool { if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { - NSError *error; + NSError *error = nil; - if (self->engine == nil) { + if (self.engine == nil) { return SDL_SetError("Haptics engine was stopped"); } if (intensity == 0.0f) { - if (self->player && self->active) { - [self->player stopAtTime:0 error:&error]; + if (self.player && self.active) { + [self.player stopAtTime:0 error:&error]; } - self->active = false; + self.active = false; return 0; } - if (self->player == nil) { + if (self.player == nil) { CHHapticEventParameter *param = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity value:1.0f]; CHHapticEvent *event = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous parameters:[NSArray arrayWithObjects:param, nil] relativeTime:0 duration:GCHapticDurationInfinite]; CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithEvents:[NSArray arrayWithObject:event] parameters:[[NSArray alloc] init] error:&error]; @@ -1033,22 +1135,22 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) return SDL_SetError("Couldn't create haptic pattern: %s", [error.localizedDescription UTF8String]); } - self->player = [self->engine createPlayerWithPattern:pattern error:&error]; + self.player = [self.engine createPlayerWithPattern:pattern error:&error]; if (error != nil) { return SDL_SetError("Couldn't create haptic player: %s", [error.localizedDescription UTF8String]); } - self->active = false; + self.active = false; } CHHapticDynamicParameter *param = [[CHHapticDynamicParameter alloc] initWithParameterID:CHHapticDynamicParameterIDHapticIntensityControl value:intensity relativeTime:0]; - [self->player sendParameters:[NSArray arrayWithObject:param] atTime:0 error:&error]; + [self.player sendParameters:[NSArray arrayWithObject:param] atTime:0 error:&error]; if (error != nil) { return SDL_SetError("Couldn't update haptic player: %s", [error.localizedDescription UTF8String]); } - if (!self->active) { - [self->player startAtTime:0 error:&error]; - self->active = true; + if (!self.active) { + [self.player startAtTime:0 error:&error]; + self.active = true; } } @@ -1062,36 +1164,36 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) self = [super init]; NSError *error; - self->engine = [controller.haptics createEngineWithLocality:locality]; - if (self->engine == nil) { + self.engine = [controller.haptics createEngineWithLocality:locality]; + if (self.engine == nil) { SDL_SetError("Couldn't create haptics engine"); return nil; } - [self->engine startAndReturnError:&error]; + [self.engine startAndReturnError:&error]; if (error != nil) { SDL_SetError("Couldn't start haptics engine"); return nil; } - __weak typeof(self) weakSelf = self; - self->engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) { + __weak __typeof(self) weakSelf = self; + self.engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) { SDL_RumbleMotor *_this = weakSelf; if (_this == nil) { return; } - _this->player = nil; - _this->engine = nil; + _this.player = nil; + _this.engine = nil; }; - self->engine.resetHandler = ^{ + self.engine.resetHandler = ^{ SDL_RumbleMotor *_this = weakSelf; if (_this == nil) { return; } - _this->player = nil; - [_this->engine startAndReturnError:nil]; + _this.player = nil; + [_this.engine startAndReturnError:nil]; }; return self; @@ -1101,13 +1203,13 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) @end @interface SDL_RumbleContext : NSObject + @property(nonatomic,strong) SDL_RumbleMotor *m_low_frequency_motor; + @property(nonatomic,strong) SDL_RumbleMotor *m_high_frequency_motor; + @property(nonatomic,strong) SDL_RumbleMotor *m_left_trigger_motor; + @property(nonatomic,strong) SDL_RumbleMotor *m_right_trigger_motor; @end @implementation SDL_RumbleContext { - SDL_RumbleMotor *m_low_frequency_motor; - SDL_RumbleMotor *m_high_frequency_motor; - SDL_RumbleMotor *m_left_trigger_motor; - SDL_RumbleMotor *m_right_trigger_motor; } -(id) initWithLowFrequencyMotor:(SDL_RumbleMotor*)low_frequency_motor @@ -1116,10 +1218,10 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) RightTriggerMotor:(SDL_RumbleMotor*)right_trigger_motor { self = [super init]; - self->m_low_frequency_motor = low_frequency_motor; - self->m_high_frequency_motor = high_frequency_motor; - self->m_left_trigger_motor = left_trigger_motor; - self->m_right_trigger_motor = right_trigger_motor; + self.m_low_frequency_motor = low_frequency_motor; + self.m_high_frequency_motor = high_frequency_motor; + self.m_left_trigger_motor = left_trigger_motor; + self.m_right_trigger_motor = right_trigger_motor; return self; } @@ -1127,8 +1229,8 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) { int result = 0; - result += [self->m_low_frequency_motor setIntensity:((float)low_frequency_rumble / 65535.0f)]; - result += [self->m_high_frequency_motor setIntensity:((float)high_frequency_rumble / 65535.0f)]; + result += [self.m_low_frequency_motor setIntensity:((float)low_frequency_rumble / 65535.0f)]; + result += [self.m_high_frequency_motor setIntensity:((float)high_frequency_rumble / 65535.0f)]; return ((result < 0) ? -1 : 0); } @@ -1136,9 +1238,9 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) { int result = 0; - if (self->m_left_trigger_motor && self->m_right_trigger_motor) { - result += [self->m_left_trigger_motor setIntensity:((float)left_rumble / 65535.0f)]; - result += [self->m_right_trigger_motor setIntensity:((float)right_rumble / 65535.0f)]; + if (self.m_left_trigger_motor && self.m_right_trigger_motor) { + result += [self.m_left_trigger_motor setIntensity:((float)left_rumble / 65535.0f)]; + result += [self.m_right_trigger_motor setIntensity:((float)right_rumble / 65535.0f)]; } else { result = SDL_Unsupported(); } @@ -1147,8 +1249,8 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) -(void)cleanup { - [self->m_low_frequency_motor cleanup]; - [self->m_high_frequency_motor cleanup]; + [self.m_low_frequency_motor cleanup]; + [self.m_high_frequency_motor cleanup]; } @end @@ -1180,6 +1282,10 @@ IOS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h #ifdef ENABLE_MFI_RUMBLE SDL_JoystickDeviceItem *device = joystick->hwdata; + if (device == NULL) { + return SDL_SetError("Controller is no longer connected"); + } + if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { if (!device->rumble && device->controller && device->controller.haptics) { SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller); @@ -1206,6 +1312,10 @@ IOS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri #ifdef ENABLE_MFI_RUMBLE SDL_JoystickDeviceItem *device = joystick->hwdata; + if (device == NULL) { + return SDL_SetError("Controller is no longer connected"); + } + if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { if (!device->rumble && device->controller && device->controller.haptics) { SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller); @@ -1226,22 +1336,43 @@ IOS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri #endif } -static SDL_bool -IOS_JoystickHasLED(SDL_Joystick *joystick) +static Uint32 +IOS_JoystickGetCapabilities(SDL_Joystick *joystick) { -#ifdef ENABLE_MFI_LIGHT + Uint32 result = 0; + +#if defined(ENABLE_MFI_LIGHT) || defined(ENABLE_MFI_RUMBLE) @autoreleasepool { + SDL_JoystickDeviceItem *device = joystick->hwdata; + + if (device == NULL) { + return 0; + } + if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { - GCController *controller = joystick->hwdata->controller; - GCDeviceLight *light = controller.light; - if (light) { - return SDL_TRUE; + GCController *controller = device->controller; + #ifdef ENABLE_MFI_LIGHT + if (controller.light) { + result |= SDL_JOYCAP_LED; } + #endif + + #ifdef ENABLE_MFI_RUMBLE + if (controller.haptics) { + for (GCHapticsLocality locality in controller.haptics.supportedLocalities) { + if ([locality isEqualToString:GCHapticsLocalityHandles]) { + result |= SDL_JOYCAP_RUMBLE; + } else if ([locality isEqualToString:GCHapticsLocalityTriggers]) { + result |= SDL_JOYCAP_RUMBLE_TRIGGERS; + } + } + } + #endif } } -#endif /* ENABLE_MFI_LIGHT */ +#endif /* ENABLE_MFI_LIGHT || ENABLE_MFI_RUMBLE */ - return SDL_FALSE; + return result; } static int @@ -1249,8 +1380,14 @@ IOS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) { #ifdef ENABLE_MFI_LIGHT @autoreleasepool { + SDL_JoystickDeviceItem *device = joystick->hwdata; + + if (device == NULL) { + return SDL_SetError("Controller is no longer connected"); + } + if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { - GCController *controller = joystick->hwdata->controller; + GCController *controller = device->controller; GCDeviceLight *light = controller.light; if (light) { light.color = [[GCColor alloc] initWithRed:(float)red / 255.0f @@ -1265,13 +1402,25 @@ IOS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) return SDL_Unsupported(); } +static int +IOS_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + static int IOS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) { #ifdef ENABLE_MFI_SENSORS @autoreleasepool { + SDL_JoystickDeviceItem *device = joystick->hwdata; + + if (device == NULL) { + return SDL_SetError("Controller is no longer connected"); + } + if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { - GCController *controller = joystick->hwdata->controller; + GCController *controller = device->controller; GCMotion *motion = controller.motion; if (motion) { motion.sensorsActive = enabled ? YES : NO; @@ -1331,7 +1480,19 @@ IOS_JoystickClose(SDL_Joystick *joystick) GCController *controller = device->controller; controller.controllerPausedHandler = nil; controller.playerIndex = -1; -#endif + +#ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE + if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { + for (id key in controller.physicalInputProfile.buttons) { + GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key]; + if ([button isBoundToSystemGesture]) { + button.preferredSystemGestureState = GCSystemGestureStateEnabled; + } + } + } +#endif /* ENABLE_MFI_SYSTEM_GESTURE_STATE */ + +#endif /* SDL_JOYSTICK_MFI */ } } if (device->remote) { @@ -1384,12 +1545,223 @@ IOS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) SDL_bool IOS_SupportedHIDDevice(IOHIDDeviceRef device) { if (is_macos11()) { - return [GCController supportsHIDDevice:device] ? SDL_TRUE : SDL_FALSE; + if ([GCController supportsHIDDevice:device]) { + return SDL_TRUE; + } + + /* GCController supportsHIDDevice may return false if the device hasn't been + * seen by the framework yet, so check a few controllers we know are supported. + */ + { + Sint32 vendor = 0; + Sint32 product = 0; + CFTypeRef refCF = NULL; + + refCF = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)); + if (refCF) { + CFNumberGetValue(refCF, kCFNumberSInt32Type, &vendor); + } + + refCF = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey)); + if (refCF) { + CFNumberGetValue(refCF, kCFNumberSInt32Type, &product); + } + + if (vendor == USB_VENDOR_MICROSOFT && SDL_IsJoystickXboxSeriesX(vendor, product)) { + return SDL_TRUE; + } + } } return SDL_FALSE; } #endif +#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE) +static void +GetAppleSFSymbolsNameForElement(GCControllerElement *element, char *name) +{ + if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { + if (element) { + [element.sfSymbolsName getCString: name maxLength: 255 encoding: NSASCIIStringEncoding]; + } + } +} + +static GCControllerDirectionPad * +GetDirectionalPadForController(GCController *controller) +{ + if (controller.extendedGamepad) { + return controller.extendedGamepad.dpad; + } + + if (controller.gamepad) { + return controller.gamepad.dpad; + } + + if (controller.microGamepad) { + return controller.microGamepad.dpad; + } + + return nil; +} +#endif /* SDL_JOYSTICK_MFI && ENABLE_PHYSICAL_INPUT_PROFILE */ + +static char elementName[256]; + +const char * +IOS_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button) +{ + elementName[0] = '\0'; +#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE) + if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) { + if (@available(iOS 14.0, tvOS 14.0, macOS 11.0, *)) { + GCController *controller = SDL_GameControllerGetJoystick(gamecontroller)->hwdata->controller; + if ([controller respondsToSelector:@selector(physicalInputProfile)]) { + NSDictionary *elements = controller.physicalInputProfile.elements; + switch (button) + { + case SDL_CONTROLLER_BUTTON_A: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonA], elementName); + break; + case SDL_CONTROLLER_BUTTON_B: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonB], elementName); + break; + case SDL_CONTROLLER_BUTTON_X: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonX], elementName); + break; + case SDL_CONTROLLER_BUTTON_Y: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonY], elementName); + break; + case SDL_CONTROLLER_BUTTON_BACK: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonOptions], elementName); + break; + case SDL_CONTROLLER_BUTTON_GUIDE: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonHome], elementName); + break; + case SDL_CONTROLLER_BUTTON_START: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonMenu], elementName); + break; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: + GetAppleSFSymbolsNameForElement(elements[GCInputLeftThumbstickButton], elementName); + break; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: + GetAppleSFSymbolsNameForElement(elements[GCInputRightThumbstickButton], elementName); + break; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: + GetAppleSFSymbolsNameForElement(elements[GCInputLeftShoulder], elementName); + break; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: + GetAppleSFSymbolsNameForElement(elements[GCInputRightShoulder], elementName); + break; + case SDL_CONTROLLER_BUTTON_DPAD_UP: { + GCControllerDirectionPad * dpad = GetDirectionalPadForController(controller); + if (dpad) { + GetAppleSFSymbolsNameForElement(dpad.up, elementName); + if (SDL_strlen(elementName) == 0) { + SDL_strlcpy(elementName, "dpad.up.fill", sizeof(elementName)); + } + } + break; + } + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: { + GCControllerDirectionPad * dpad = GetDirectionalPadForController(controller); + if (dpad) { + GetAppleSFSymbolsNameForElement(dpad.down, elementName); + if (SDL_strlen(elementName) == 0) { + SDL_strlcpy(elementName, "dpad.down.fill", sizeof(elementName)); + } + } + break; + } + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: { + GCControllerDirectionPad * dpad = GetDirectionalPadForController(controller); + if (dpad) { + GetAppleSFSymbolsNameForElement(dpad.left, elementName); + if (SDL_strlen(elementName) == 0) { + SDL_strlcpy(elementName, "dpad.left.fill", sizeof(elementName)); + } + } + break; + } + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: { + GCControllerDirectionPad * dpad = GetDirectionalPadForController(controller); + if (dpad) { + GetAppleSFSymbolsNameForElement(dpad.right, elementName); + if (SDL_strlen(elementName) == 0) { + SDL_strlcpy(elementName, "dpad.right.fill", sizeof(elementName)); + } + } + break; + } + case SDL_CONTROLLER_BUTTON_MISC1: + GetAppleSFSymbolsNameForElement(elements[GCInputDualShockTouchpadButton], elementName); + break; + case SDL_CONTROLLER_BUTTON_PADDLE1: + GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleOne], elementName); + break; + case SDL_CONTROLLER_BUTTON_PADDLE2: + GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleTwo], elementName); + break; + case SDL_CONTROLLER_BUTTON_PADDLE3: + GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleThree], elementName); + break; + case SDL_CONTROLLER_BUTTON_PADDLE4: + GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleFour], elementName); + break; + case SDL_CONTROLLER_BUTTON_TOUCHPAD: + GetAppleSFSymbolsNameForElement(elements[GCInputDualShockTouchpadButton], elementName); + break; + default: + break; + } + } + } + } +#endif + return elementName; +} + +const char * +IOS_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis) +{ + elementName[0] = '\0'; +#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE) + if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) { + if (@available(iOS 14.0, tvOS 14.0, macOS 11.0, *)) { + GCController *controller = SDL_GameControllerGetJoystick(gamecontroller)->hwdata->controller; + if ([controller respondsToSelector:@selector(physicalInputProfile)]) { + NSDictionary *elements = controller.physicalInputProfile.elements; + switch (axis) + { + case SDL_CONTROLLER_AXIS_LEFTX: + GetAppleSFSymbolsNameForElement(elements[GCInputLeftThumbstick], elementName); + break; + case SDL_CONTROLLER_AXIS_LEFTY: + GetAppleSFSymbolsNameForElement(elements[GCInputLeftThumbstick], elementName); + break; + case SDL_CONTROLLER_AXIS_RIGHTX: + GetAppleSFSymbolsNameForElement(elements[GCInputRightThumbstick], elementName); + break; + case SDL_CONTROLLER_AXIS_RIGHTY: + GetAppleSFSymbolsNameForElement(elements[GCInputRightThumbstick], elementName); + break; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + GetAppleSFSymbolsNameForElement(elements[GCInputLeftTrigger], elementName); + break; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + GetAppleSFSymbolsNameForElement(elements[GCInputRightTrigger], elementName); + break; + default: + break; + } + } + } + } +#endif + return *elementName ? elementName : NULL; +} + + SDL_JoystickDriver SDL_IOS_JoystickDriver = { IOS_JoystickInit, @@ -1403,8 +1775,9 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver = IOS_JoystickOpen, IOS_JoystickRumble, IOS_JoystickRumbleTriggers, - IOS_JoystickHasLED, + IOS_JoystickGetCapabilities, IOS_JoystickSetLED, + IOS_JoystickSendEffect, IOS_JoystickSetSensorsEnabled, IOS_JoystickUpdate, IOS_JoystickClose, diff --git a/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick_c.h b/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick_c.h index 21d01b0b9..157dc829e 100644 --- a/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick_c.h +++ b/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -50,6 +50,7 @@ typedef struct joystick_hwdata Uint32 button_mask; SDL_bool has_dualshock_touchpad; SDL_bool has_xbox_paddles; + SDL_bool has_xbox_share_button; struct joystick_hwdata *next; } joystick_hwdata; diff --git a/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c index ee4a8c197..851448acd 100644 --- a/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -56,12 +56,6 @@ #ifndef SYN_DROPPED #define SYN_DROPPED 3 #endif -#ifndef BTN_SOUTH -#define BTN_SOUTH 0x130 -#endif -#ifndef BTN_EAST -#define BTN_EAST 0x131 -#endif #ifndef BTN_NORTH #define BTN_NORTH 0x133 #endif @@ -97,6 +91,7 @@ typedef enum static EnumerationMethod enumeration_method = ENUMERATION_UNSET; +static SDL_bool IsJoystickJSNode(const char *node); static int MaybeAddDevice(const char *path); static int MaybeRemoveDevice(const char *path); @@ -113,8 +108,11 @@ typedef struct SDL_joylist_item /* Steam Controller support */ SDL_bool m_bSteamController; + + SDL_GamepadMapping *mapping; } SDL_joylist_item; +static SDL_bool SDL_classic_joysticks = SDL_FALSE; static SDL_joylist_item *SDL_joylist = NULL; static SDL_joylist_item *SDL_joylist_tail = NULL; static int numjoysticks = 0; @@ -137,6 +135,14 @@ FixupDeviceInfoForMapping(int fd, struct input_id *inpid) inpid->version = 0x0902; } } + + /* For Atari vcs modern and classic controllers have the version reflecting + * firmware version, but the mapping stays stable so ignore + * version information */ + if (inpid->vendor == 0x3250 + && (inpid->product == 0x1001 || inpid->product == 0x1002)) { + inpid->version = 0; + } } #ifdef SDL_JOYSTICK_HIDAPI @@ -178,24 +184,31 @@ GuessIsJoystick(int fd) } static int -IsJoystick(int fd, char **name_return, SDL_JoystickGUID *guid) +IsJoystick(const char *path, int fd, char **name_return, SDL_JoystickGUID *guid) { struct input_id inpid; Uint16 *guid16 = (Uint16 *)guid->data; char *name; char product_string[128]; - /* When udev is enabled we only get joystick devices here, so there's no need to test them */ - if (enumeration_method != ENUMERATION_LIBUDEV && !GuessIsJoystick(fd)) { - return 0; - } + if (ioctl(fd, JSIOCGNAME(sizeof(product_string)), product_string) >= 0) { + SDL_zero(inpid); +#if SDL_USE_LIBUDEV + SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version); +#endif + } else { + /* When udev is enabled we only get joystick devices here, so there's no need to test them */ + if (enumeration_method != ENUMERATION_LIBUDEV && !GuessIsJoystick(fd)) { + return 0; + } - if (ioctl(fd, EVIOCGID, &inpid) < 0) { - return 0; - } + if (ioctl(fd, EVIOCGID, &inpid) < 0) { + return 0; + } - if (ioctl(fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) { - return 0; + if (ioctl(fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) { + return 0; + } } name = SDL_CreateJoystickName(inpid.vendor, inpid.product, NULL, product_string); @@ -215,7 +228,7 @@ IsJoystick(int fd, char **name_return, SDL_JoystickGUID *guid) FixupDeviceInfoForMapping(fd, &inpid); #ifdef DEBUG_JOYSTICK - printf("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version); + SDL_Log("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version); #endif SDL_memset(guid->data, 0, sizeof(guid->data)); @@ -256,6 +269,15 @@ static void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_clas if (!(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) { return; } + if (SDL_classic_joysticks) { + if (!IsJoystickJSNode(devpath)) { + return; + } + } else { + if (IsJoystickJSNode(devpath)) { + return; + } + } MaybeAddDevice(devpath); break; @@ -270,6 +292,15 @@ static void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_clas } #endif /* SDL_USE_LIBUDEV */ +static void +FreeJoylistItem(SDL_joylist_item *item) +{ + SDL_free(item->mapping); + SDL_free(item->path); + SDL_free(item->name); + SDL_free(item); +} + static int MaybeAddDevice(const char *path) { @@ -295,36 +326,33 @@ MaybeAddDevice(const char *path) } } - fd = open(path, O_RDONLY, 0); + fd = open(path, O_RDONLY | O_CLOEXEC, 0); if (fd < 0) { return -1; } #ifdef DEBUG_INPUT_EVENTS - printf("Checking %s\n", path); + SDL_Log("Checking %s\n", path); #endif - isstick = IsJoystick(fd, &name, &guid); + isstick = IsJoystick(path, fd, &name, &guid); close(fd); if (!isstick) { return -1; } - item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item)); + item = (SDL_joylist_item *) SDL_calloc(1, sizeof (SDL_joylist_item)); if (item == NULL) { return -1; } - SDL_zerop(item); item->devnum = sb.st_rdev; item->path = SDL_strdup(path); item->name = name; item->guid = guid; if ((item->path == NULL) || (item->name == NULL)) { - SDL_free(item->path); - SDL_free(item->name); - SDL_free(item); + FreeJoylistItem(item); return -1; } @@ -344,6 +372,31 @@ MaybeAddDevice(const char *path) return numjoysticks; } +static void +RemoveJoylistItem(SDL_joylist_item *item, SDL_joylist_item *prev) +{ + if (item->hwdata) { + item->hwdata->item = NULL; + } + + if (prev != NULL) { + prev->next = item->next; + } else { + SDL_assert(SDL_joylist == item); + SDL_joylist = item->next; + } + + if (item == SDL_joylist_tail) { + SDL_joylist_tail = prev; + } + + /* Need to decrement the joystick count before we post the event */ + --numjoysticks; + + SDL_PrivateJoystickRemoved(item->device_instance); + FreeJoylistItem(item); +} + static int MaybeRemoveDevice(const char *path) { @@ -358,27 +411,7 @@ MaybeRemoveDevice(const char *path) /* found it, remove it. */ if (SDL_strcmp(path, item->path) == 0) { const int retval = item->device_instance; - if (item->hwdata) { - item->hwdata->item = NULL; - } - if (prev != NULL) { - prev->next = item->next; - } else { - SDL_assert(SDL_joylist == item); - SDL_joylist = item->next; - } - if (item == SDL_joylist_tail) { - SDL_joylist_tail = prev; - } - - /* Need to decrement the joystick count before we post the event */ - --numjoysticks; - - SDL_PrivateJoystickRemoved(item->device_instance); - - SDL_free(item->path); - SDL_free(item->name); - SDL_free(item); + RemoveJoylistItem(item, prev); return retval; } prev = item; @@ -395,26 +428,7 @@ HandlePendingRemovals(void) while (item != NULL) { if (item->hwdata && item->hwdata->gone) { - item->hwdata->item = NULL; - - if (prev != NULL) { - prev->next = item->next; - } else { - SDL_assert(SDL_joylist == item); - SDL_joylist = item->next; - } - if (item == SDL_joylist_tail) { - SDL_joylist_tail = prev; - } - - /* Need to decrement the joystick count before we post the event */ - --numjoysticks; - - SDL_PrivateJoystickRemoved(item->device_instance); - - SDL_free(item->path); - SDL_free(item->name); - SDL_free(item); + RemoveJoylistItem(item, prev); if (prev != NULL) { item = prev->next; @@ -443,9 +457,7 @@ static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickG item->m_bSteamController = SDL_TRUE; if ((item->path == NULL) || (item->name == NULL)) { - SDL_free(item->path); - SDL_free(item->name); - SDL_free(item); + FreeJoylistItem(item); return SDL_FALSE; } @@ -473,26 +485,7 @@ static void SteamControllerDisconnectedCallback(int device_instance) for (item = SDL_joylist; item != NULL; item = item->next) { /* found it, remove it. */ if (item->device_instance == device_instance) { - if (item->hwdata) { - item->hwdata->item = NULL; - } - if (prev != NULL) { - prev->next = item->next; - } else { - SDL_assert(SDL_joylist == item); - SDL_joylist = item->next; - } - if (item == SDL_joylist_tail) { - SDL_joylist_tail = prev; - } - - /* Need to decrement the joystick count before we post the event */ - --numjoysticks; - - SDL_PrivateJoystickRemoved(item->device_instance); - - SDL_free(item->name); - SDL_free(item); + RemoveJoylistItem(item, prev); return; } prev = item; @@ -538,6 +531,36 @@ StrIsInteger(const char *string) return 1; } +static SDL_bool +IsJoystickJSNode(const char *node) +{ + const char *last_slash = SDL_strrchr(node, '/'); + if (last_slash) { + node = last_slash + 1; + } + return (StrHasPrefix(node, "js") && StrIsInteger(node + 2)); +} + +static SDL_bool +IsJoystickEventNode(const char *node) +{ + const char *last_slash = SDL_strrchr(node, '/'); + if (last_slash) { + node = last_slash + 1; + } + return (StrHasPrefix(node, "event") && StrIsInteger(node + 5)); +} + +static SDL_bool +IsJoystickDeviceNode(const char *node) +{ + if (SDL_classic_joysticks) { + return IsJoystickJSNode(node); + } else { + return IsJoystickEventNode(node); + } +} + static void LINUX_InotifyJoystickDetect(void) { @@ -550,6 +573,7 @@ LINUX_InotifyJoystickDetect(void) ssize_t bytes; size_t remain = 0; size_t len; + char path[PATH_MAX]; bytes = read(inotify_fd, &buf, sizeof (buf)); @@ -559,10 +583,7 @@ LINUX_InotifyJoystickDetect(void) while (remain > 0) { if (buf.event.len > 0) { - if (StrHasPrefix(buf.event.name, "event") && - StrIsInteger(buf.event.name + strlen ("event"))) { - char path[PATH_MAX]; - + if (IsJoystickDeviceNode(buf.event.name)) { SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", buf.event.name); if (buf.event.mask & (IN_CREATE | IN_MOVED_TO | IN_ATTRIB)) { @@ -578,7 +599,7 @@ LINUX_InotifyJoystickDetect(void) remain -= len; if (remain != 0) { - memmove (&buf.storage[0], &buf.storage[len], remain); + SDL_memmove (&buf.storage[0], &buf.storage[len], remain); } } } @@ -588,6 +609,18 @@ LINUX_InotifyJoystickDetect(void) * have to do this the first time, to detect devices that already existed * before we started; in the non-inotify code path we do this repeatedly * (polling). */ +static int +filter_entries(const struct dirent *entry) +{ + return IsJoystickDeviceNode(entry->d_name); +} +static int +sort_entries(const struct dirent **a, const struct dirent **b) +{ + int numA = SDL_atoi((*a)->d_name+5); + int numB = SDL_atoi((*b)->d_name+5); + return (numA - numB); +} static void LINUX_FallbackJoystickDetect(void) { @@ -599,22 +632,18 @@ LINUX_FallbackJoystickDetect(void) /* Opening input devices can generate synchronous device I/O, so avoid it if we can */ if (stat("/dev/input", &sb) == 0 && sb.st_mtime != last_input_dir_mtime) { - DIR *folder; - struct dirent *dent; + int i, count; + struct dirent **entries; + char path[PATH_MAX]; - folder = opendir("/dev/input"); - if (folder) { - while ((dent = readdir(folder))) { - int len = SDL_strlen(dent->d_name); - if (len > 5 && SDL_strncmp(dent->d_name, "event", 5) == 0) { - char path[PATH_MAX]; - SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", dent->d_name); - MaybeAddDevice(path); - } - } + count = scandir("/dev/input", &entries, filter_entries, sort_entries); + for (i = 0; i < count; ++i) { + SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name); + MaybeAddDevice(path); - closedir(folder); + free(entries[i]); /* This should NOT be SDL_free() */ } + free(entries); /* This should NOT be SDL_free() */ last_input_dir_mtime = sb.st_mtime; } @@ -650,20 +679,27 @@ LINUX_JoystickDetect(void) static int LINUX_JoystickInit(void) { + const char *devices = SDL_GetHint(SDL_HINT_JOYSTICK_DEVICE); + + SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE); + #if SDL_USE_LIBUDEV if (enumeration_method == ENUMERATION_UNSET) { - if (SDL_getenv("SDL_JOYSTICK_DISABLE_UDEV") != NULL) { + if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) { SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "udev disabled by SDL_JOYSTICK_DISABLE_UDEV"); enumeration_method = ENUMERATION_FALLBACK; - } - else if (access("/.flatpak-info", F_OK) == 0 - || access("/run/pressure-vessel", F_OK) == 0) { + + } else if (access("/.flatpak-info", F_OK) == 0 + || access("/run/host/container-manager", F_OK) == 0) { + /* Explicitly check `/.flatpak-info` because, for old versions of + * Flatpak, this was the only available way to tell if we were in + * a Flatpak container. */ SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "Container detected, disabling udev integration"); enumeration_method = ENUMERATION_FALLBACK; - } - else { + + } else { SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "Using udev for joystick device discovery"); enumeration_method = ENUMERATION_LIBUDEV; @@ -672,9 +708,9 @@ LINUX_JoystickInit(void) #endif /* First see if the user specified one or more joysticks to use */ - if (SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL) { + if (devices != NULL) { char *envcopy, *envpath, *delim; - envcopy = SDL_strdup(SDL_getenv("SDL_JOYSTICK_DEVICE")); + envcopy = SDL_strdup(devices); envpath = envcopy; while (envpath != NULL) { delim = SDL_strchr(envpath, ':'); @@ -694,6 +730,9 @@ LINUX_JoystickInit(void) last_joy_detect_time = 0; last_input_dir_mtime = 0; + /* Manually scan first, since we sort by device number and udev doesn't */ + LINUX_JoystickDetect(); + #if SDL_USE_LIBUDEV if (enumeration_method == ENUMERATION_LIBUDEV) { if (SDL_UDEV_Init() < 0) { @@ -735,9 +774,6 @@ LINUX_JoystickInit(void) } } #endif /* HAVE_INOTIFY */ - - /* Report all devices currently present */ - LINUX_JoystickDetect(); } return 0; @@ -842,6 +878,7 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; unsigned long relbit[NBITS(REL_MAX)] = { 0 }; unsigned long ffbit[NBITS(FF_MAX)] = { 0 }; + Uint8 key_pam_size, abs_pam_size; SDL_bool use_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_DEADZONES, SDL_FALSE); /* See if this device uses the new unified event API */ @@ -853,7 +890,7 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) { if (test_bit(i, keybit)) { #ifdef DEBUG_INPUT_EVENTS - printf("Joystick has button: 0x%x\n", i); + SDL_Log("Joystick has button: 0x%x\n", i); #endif joystick->hwdata->key_map[i] = joystick->nbuttons; joystick->hwdata->has_key[i] = SDL_TRUE; @@ -863,7 +900,7 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) for (i = 0; i < BTN_JOYSTICK; ++i) { if (test_bit(i, keybit)) { #ifdef DEBUG_INPUT_EVENTS - printf("Joystick has button: 0x%x\n", i); + SDL_Log("Joystick has button: 0x%x\n", i); #endif joystick->hwdata->key_map[i] = joystick->nbuttons; joystick->hwdata->has_key[i] = SDL_TRUE; @@ -884,10 +921,10 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) continue; } #ifdef DEBUG_INPUT_EVENTS - printf("Joystick has absolute axis: 0x%.2x\n", i); - printf("Values = { %d, %d, %d, %d, %d }\n", - absinfo.value, absinfo.minimum, absinfo.maximum, - absinfo.fuzz, absinfo.flat); + SDL_Log("Joystick has absolute axis: 0x%.2x\n", i); + SDL_Log("Values = { %d, %d, %d, %d, %d }\n", + absinfo.value, absinfo.minimum, absinfo.maximum, + absinfo.fuzz, absinfo.flat); #endif /* DEBUG_INPUT_EVENTS */ joystick->hwdata->abs_map[i] = joystick->naxes; joystick->hwdata->has_abs[i] = SDL_TRUE; @@ -924,10 +961,10 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) continue; } #ifdef DEBUG_INPUT_EVENTS - printf("Joystick has hat %d\n", hat_index); - printf("Values = { %d, %d, %d, %d, %d }\n", - absinfo.value, absinfo.minimum, absinfo.maximum, - absinfo.fuzz, absinfo.flat); + SDL_Log("Joystick has hat %d\n", hat_index); + SDL_Log("Values = { %d, %d, %d, %d, %d }\n", + absinfo.value, absinfo.minimum, absinfo.maximum, + absinfo.fuzz, absinfo.flat); #endif /* DEBUG_INPUT_EVENTS */ joystick->hwdata->hats_indices[hat_index] = joystick->nhats++; joystick->hwdata->has_hat[hat_index] = SDL_TRUE; @@ -937,16 +974,76 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) ++joystick->nballs; } - /* Allocate data to keep track of these thingamajigs */ - if (joystick->nhats > 0) { - if (allocate_hatdata(joystick) < 0) { - joystick->nhats = 0; + } else if ((ioctl(fd, JSIOCGBUTTONS, &key_pam_size, sizeof(key_pam_size)) >= 0) && + (ioctl(fd, JSIOCGAXES, &abs_pam_size, sizeof(abs_pam_size)) >= 0)) { + size_t len; + + joystick->hwdata->classic = SDL_TRUE; + + len = (KEY_MAX - BTN_MISC + 1) * sizeof(*joystick->hwdata->key_pam); + joystick->hwdata->key_pam = (Uint16 *)SDL_calloc(1, len); + if (joystick->hwdata->key_pam) { + if (ioctl(fd, JSIOCGBTNMAP, joystick->hwdata->key_pam, len) < 0) { + SDL_free(joystick->hwdata->key_pam); + joystick->hwdata->key_pam = NULL; + key_pam_size = 0; + } + } else { + key_pam_size = 0; + } + for (i = 0; i < key_pam_size; ++i) { + Uint16 code = joystick->hwdata->key_pam[i]; +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has button: 0x%x\n", code); +#endif + joystick->hwdata->key_map[code] = joystick->nbuttons; + joystick->hwdata->has_key[code] = SDL_TRUE; + ++joystick->nbuttons; + } + + len = ABS_CNT * sizeof(*joystick->hwdata->abs_pam); + joystick->hwdata->abs_pam = (Uint8 *)SDL_calloc(1, len); + if (joystick->hwdata->abs_pam) { + if (ioctl(fd, JSIOCGAXMAP, joystick->hwdata->abs_pam, len) < 0) { + SDL_free(joystick->hwdata->abs_pam); + joystick->hwdata->abs_pam = NULL; + abs_pam_size = 0; + } + } else { + abs_pam_size = 0; + } + for (i = 0; i < abs_pam_size; ++i) { + Uint8 code = joystick->hwdata->abs_pam[i]; + + if (code >= ABS_HAT0X && code <= ABS_HAT3Y) { + int hat_index = (code - ABS_HAT0X) / 2; + if (!joystick->hwdata->has_hat[hat_index]) { +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has hat %d\n", hat_index); +#endif + joystick->hwdata->hats_indices[hat_index] = joystick->nhats++; + joystick->hwdata->has_hat[hat_index] = SDL_TRUE; + } + } else { +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has absolute axis: 0x%.2x\n", code); +#endif + joystick->hwdata->abs_map[code] = joystick->naxes; + joystick->hwdata->has_abs[code] = SDL_TRUE; + ++joystick->naxes; } } - if (joystick->nballs > 0) { - if (allocate_balldata(joystick) < 0) { - joystick->nballs = 0; - } + } + + /* Allocate data to keep track of these thingamajigs */ + if (joystick->nhats > 0) { + if (allocate_hatdata(joystick) < 0) { + joystick->nhats = 0; + } + } + if (joystick->nballs > 0) { + if (allocate_balldata(joystick) < 0) { + joystick->nballs = 0; } } @@ -961,6 +1058,54 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) } +/* This is used to do the heavy lifting for LINUX_JoystickOpen and + also LINUX_JoystickGetGamepadMapping, so we can query the hardware + without adding an opened SDL_Joystick object to the system. + This expects `joystick->hwdata` to be allocated and will not free it + on error. Returns -1 on error, 0 on success. */ +static int +PrepareJoystickHwdata(SDL_Joystick *joystick, SDL_joylist_item *item) +{ + joystick->hwdata->item = item; + joystick->hwdata->guid = item->guid; + joystick->hwdata->effect.id = -1; + joystick->hwdata->m_bSteamController = item->m_bSteamController; + SDL_memset(joystick->hwdata->key_map, 0xFF, sizeof(joystick->hwdata->key_map)); + SDL_memset(joystick->hwdata->abs_map, 0xFF, sizeof(joystick->hwdata->abs_map)); + + if (item->m_bSteamController) { + joystick->hwdata->fd = -1; + SDL_GetSteamControllerInputs(&joystick->nbuttons, + &joystick->naxes, + &joystick->nhats); + } else { + /* Try read-write first, so we can do rumble */ + int fd = open(item->path, O_RDWR | O_CLOEXEC, 0); + if (fd < 0) { + /* Try read-only again, at least we'll get events in this case */ + fd = open(item->path, O_RDONLY | O_CLOEXEC, 0); + } + if (fd < 0) { + return SDL_SetError("Unable to open %s", item->path); + } + + joystick->hwdata->fd = fd; + joystick->hwdata->fname = SDL_strdup(item->path); + if (joystick->hwdata->fname == NULL) { + close(fd); + return SDL_OutOfMemory(); + } + + /* Set the joystick to non-blocking read mode */ + fcntl(fd, F_SETFL, O_NONBLOCK); + + /* Get the number of buttons and axes on the joystick */ + ConfigJoystick(joystick, fd); + } + return 0; +} + + /* Function to open a joystick for use. The joystick to open is specified by the device index. This should fill the nbuttons and naxes fields of the joystick structure. @@ -981,39 +1126,11 @@ LINUX_JoystickOpen(SDL_Joystick *joystick, int device_index) if (joystick->hwdata == NULL) { return SDL_OutOfMemory(); } - joystick->hwdata->item = item; - joystick->hwdata->guid = item->guid; - joystick->hwdata->effect.id = -1; - joystick->hwdata->m_bSteamController = item->m_bSteamController; - SDL_memset(joystick->hwdata->abs_map, 0xFF, sizeof(joystick->hwdata->abs_map)); - if (item->m_bSteamController) { - joystick->hwdata->fd = -1; - SDL_GetSteamControllerInputs(&joystick->nbuttons, - &joystick->naxes, - &joystick->nhats); - } else { - int fd = open(item->path, O_RDWR, 0); - if (fd < 0) { - SDL_free(joystick->hwdata); - joystick->hwdata = NULL; - return SDL_SetError("Unable to open %s", item->path); - } - - joystick->hwdata->fd = fd; - joystick->hwdata->fname = SDL_strdup(item->path); - if (joystick->hwdata->fname == NULL) { - SDL_free(joystick->hwdata); - joystick->hwdata = NULL; - close(fd); - return SDL_OutOfMemory(); - } - - /* Set the joystick to non-blocking read mode */ - fcntl(fd, F_SETFL, O_NONBLOCK); - - /* Get the number of buttons and axes on the joystick */ - ConfigJoystick(joystick, fd); + if (PrepareJoystickHwdata(joystick, item) == -1) { + SDL_free(joystick->hwdata); + joystick->hwdata = NULL; + return -1; /* SDL_SetError will already have been called */ } SDL_assert(item->hwdata == NULL); @@ -1022,7 +1139,7 @@ LINUX_JoystickOpen(SDL_Joystick *joystick, int device_index) /* mark joystick as fresh and ready */ joystick->hwdata->fresh = SDL_TRUE; - return (0); + return 0; } static int @@ -1073,10 +1190,16 @@ LINUX_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 return SDL_Unsupported(); } -static SDL_bool -LINUX_JoystickHasLED(SDL_Joystick *joystick) +static Uint32 +LINUX_JoystickGetCapabilities(SDL_Joystick *joystick) { - return SDL_FALSE; + Uint32 result = 0; + + if (joystick->hwdata->ff_rumble || joystick->hwdata->ff_sine) { + result |= SDL_JOYCAP_RUMBLE; + } + + return result; } static int @@ -1085,13 +1208,19 @@ LINUX_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) return SDL_Unsupported(); } +static int +LINUX_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + static int LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) { return SDL_Unsupported(); } -static SDL_INLINE void +static void HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value) { struct hwdata_hat *the_hat; @@ -1116,14 +1245,14 @@ HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value) } } -static SDL_INLINE void +static void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value) { stick->hwdata->balls[ball].axis[axis] += value; } -static SDL_INLINE int +static int AxisCorrect(SDL_Joystick *joystick, int which, int value) { struct axis_correct *correct; @@ -1157,7 +1286,7 @@ AxisCorrect(SDL_Joystick *joystick, int which, int value) return value; } -static SDL_INLINE void +static void PollAllValues(SDL_Joystick *joystick) { struct input_absinfo absinfo; @@ -1175,7 +1304,7 @@ PollAllValues(SDL_Joystick *joystick) absinfo.value = AxisCorrect(joystick, i, absinfo.value); #ifdef DEBUG_INPUT_EVENTS - printf("Joystick : Re-read Axis %d (%d) val= %d\n", + SDL_Log("Joystick : Re-read Axis %d (%d) val= %d\n", joystick->hwdata->abs_map[i], i, absinfo.value); #endif SDL_PrivateJoystickAxis(joystick, @@ -1205,7 +1334,7 @@ PollAllValues(SDL_Joystick *joystick) if (joystick->hwdata->has_key[i]) { const Uint8 value = test_bit(i, keyinfo) ? SDL_PRESSED : SDL_RELEASED; #ifdef DEBUG_INPUT_EVENTS - printf("Joystick : Re-read Button %d (%d) val= %d\n", + SDL_Log("Joystick : Re-read Button %d (%d) val= %d\n", joystick->hwdata->key_map[i], i, value); #endif SDL_PrivateJoystickButton(joystick, @@ -1217,12 +1346,11 @@ PollAllValues(SDL_Joystick *joystick) /* Joyballs are relative input, so there's no poll state. Events only! */ } -static SDL_INLINE void +static void HandleInputEvents(SDL_Joystick *joystick) { struct input_event events[32]; - int i, len; - int code; + int i, len, code; if (joystick->hwdata->fresh) { PollAllValues(joystick); @@ -1261,13 +1389,10 @@ HandleInputEvents(SDL_Joystick *joystick) HandleHat(joystick, joystick->hwdata->hats_indices[code / 2], code % 2, events[i].value); break; default: - if (joystick->hwdata->abs_map[code] != 0xFF) { - events[i].value = - AxisCorrect(joystick, code, events[i].value); - SDL_PrivateJoystickAxis(joystick, - joystick->hwdata->abs_map[code], - events[i].value); - } + events[i].value = AxisCorrect(joystick, code, events[i].value); + SDL_PrivateJoystickAxis(joystick, + joystick->hwdata->abs_map[code], + events[i].value); break; } break; @@ -1286,7 +1411,7 @@ HandleInputEvents(SDL_Joystick *joystick) switch (code) { case SYN_DROPPED : #ifdef DEBUG_INPUT_EVENTS - printf("Event SYN_DROPPED detected\n"); + SDL_Log("Event SYN_DROPPED detected\n"); #endif joystick->hwdata->recovering_from_dropped = SDL_TRUE; break; @@ -1311,6 +1436,48 @@ HandleInputEvents(SDL_Joystick *joystick) } } +static void +HandleClassicEvents(SDL_Joystick *joystick) +{ + struct js_event events[32]; + int i, len, code; + + joystick->hwdata->fresh = SDL_FALSE; + while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) { + len /= sizeof(events[0]); + for (i = 0; i < len; ++i) { + switch (events[i].type) { + case JS_EVENT_BUTTON: + code = joystick->hwdata->key_pam[events[i].number]; + SDL_PrivateJoystickButton(joystick, + joystick->hwdata->key_map[code], + events[i].value); + break; + case JS_EVENT_AXIS: + code = joystick->hwdata->abs_pam[events[i].number]; + switch (code) { + case ABS_HAT0X: + case ABS_HAT0Y: + case ABS_HAT1X: + case ABS_HAT1Y: + case ABS_HAT2X: + case ABS_HAT2Y: + case ABS_HAT3X: + case ABS_HAT3Y: + code -= ABS_HAT0X; + HandleHat(joystick, joystick->hwdata->hats_indices[code / 2], code % 2, events[i].value); + break; + default: + SDL_PrivateJoystickAxis(joystick, + joystick->hwdata->abs_map[code], + events[i].value); + break; + } + } + } + } +} + static void LINUX_JoystickUpdate(SDL_Joystick *joystick) { @@ -1321,7 +1488,11 @@ LINUX_JoystickUpdate(SDL_Joystick *joystick) return; } - HandleInputEvents(joystick); + if (joystick->hwdata->classic) { + HandleClassicEvents(joystick); + } else { + HandleInputEvents(joystick); + } /* Deliver ball motion updates */ for (i = 0; i < joystick->nballs; ++i) { @@ -1352,6 +1523,8 @@ LINUX_JoystickClose(SDL_Joystick *joystick) if (joystick->hwdata->item) { joystick->hwdata->item->hwdata = NULL; } + SDL_free(joystick->hwdata->key_pam); + SDL_free(joystick->hwdata->abs_pam); SDL_free(joystick->hwdata->hats); SDL_free(joystick->hwdata->balls); SDL_free(joystick->hwdata->fname); @@ -1373,9 +1546,7 @@ LINUX_JoystickQuit(void) for (item = SDL_joylist; item; item = next) { next = item->next; - SDL_free(item->path); - SDL_free(item->name); - SDL_free(item); + FreeJoylistItem(item); } SDL_joylist = SDL_joylist_tail = NULL; @@ -1400,19 +1571,40 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) { SDL_Joystick *joystick; + SDL_joylist_item *item = JoystickByDevIndex(device_index); + if (item->mapping) { + SDL_memcpy(out, item->mapping, sizeof(*out)); + return SDL_TRUE; + } + + /* We temporarily open the device to check how it's configured. Make + a fake SDL_Joystick object to do so. */ joystick = (SDL_Joystick *) SDL_calloc(sizeof(*joystick), 1); if (joystick == NULL) { SDL_OutOfMemory(); return SDL_FALSE; } + SDL_memcpy(&joystick->guid, &item->guid, sizeof(item->guid)); - /* We temporarily open the device to check how it's configured. */ - if (LINUX_JoystickOpen(joystick, device_index) < 0) { + joystick->hwdata = (struct joystick_hwdata *) + SDL_calloc(1, sizeof(*joystick->hwdata)); + if (joystick->hwdata == NULL) { SDL_free(joystick); + SDL_OutOfMemory(); return SDL_FALSE; } + if (PrepareJoystickHwdata(joystick, item) == -1) { + SDL_free(joystick->hwdata); + SDL_free(joystick); + return SDL_FALSE; /* SDL_SetError will already have been called */ + } + + /* don't assign `item->hwdata` so it's not in any global state. */ + + /* it is now safe to call LINUX_JoystickClose on this fake joystick. */ + if (!joystick->hwdata->has_key[BTN_GAMEPAD]) { /* Not a gamepad according to the specs. */ LINUX_JoystickClose(joystick); @@ -1422,24 +1614,37 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) /* We have a gamepad, start filling out the mappings */ - if (joystick->hwdata->has_key[BTN_SOUTH]) { + if (joystick->hwdata->has_key[BTN_A]) { out->a.kind = EMappingKind_Button; - out->a.target = joystick->hwdata->key_map[BTN_SOUTH]; + out->a.target = joystick->hwdata->key_map[BTN_A]; } - if (joystick->hwdata->has_key[BTN_EAST]) { + if (joystick->hwdata->has_key[BTN_B]) { out->b.kind = EMappingKind_Button; - out->b.target = joystick->hwdata->key_map[BTN_EAST]; + out->b.target = joystick->hwdata->key_map[BTN_B]; } - if (joystick->hwdata->has_key[BTN_NORTH]) { - out->y.kind = EMappingKind_Button; - out->y.target = joystick->hwdata->key_map[BTN_NORTH]; - } + /* Xbox controllers use BTN_X and BTN_Y, and PS4 controllers use BTN_WEST and BTN_NORTH */ + if (SDL_JoystickGetVendor(joystick) == USB_VENDOR_SONY) { + if (joystick->hwdata->has_key[BTN_WEST]) { + out->x.kind = EMappingKind_Button; + out->x.target = joystick->hwdata->key_map[BTN_WEST]; + } - if (joystick->hwdata->has_key[BTN_WEST]) { - out->x.kind = EMappingKind_Button; - out->x.target = joystick->hwdata->key_map[BTN_WEST]; + if (joystick->hwdata->has_key[BTN_NORTH]) { + out->y.kind = EMappingKind_Button; + out->y.target = joystick->hwdata->key_map[BTN_NORTH]; + } + } else { + if (joystick->hwdata->has_key[BTN_X]) { + out->x.kind = EMappingKind_Button; + out->x.target = joystick->hwdata->key_map[BTN_X]; + } + + if (joystick->hwdata->has_key[BTN_Y]) { + out->y.kind = EMappingKind_Button; + out->y.target = joystick->hwdata->key_map[BTN_Y]; + } } if (joystick->hwdata->has_key[BTN_SELECT]) { @@ -1500,12 +1705,18 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) out->lefttrigger.target = hat | 0x4; out->righttrigger.target = hat | 0x2; } else { - if (joystick->hwdata->has_key[BTN_TL2]) { + if (joystick->hwdata->has_abs[ABS_Z]) { + out->lefttrigger.kind = EMappingKind_Axis; + out->lefttrigger.target = joystick->hwdata->abs_map[ABS_Z]; + } else if (joystick->hwdata->has_key[BTN_TL2]) { out->lefttrigger.kind = EMappingKind_Button; out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2]; } - if (joystick->hwdata->has_key[BTN_TR2]) { + if (joystick->hwdata->has_abs[ABS_RZ]) { + out->righttrigger.kind = EMappingKind_Axis; + out->righttrigger.target = joystick->hwdata->abs_map[ABS_RZ]; + } else if (joystick->hwdata->has_key[BTN_TR2]) { out->righttrigger.kind = EMappingKind_Button; out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2]; } @@ -1563,6 +1774,12 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) LINUX_JoystickClose(joystick); SDL_free(joystick); + /* Cache the mapping for later */ + item->mapping = (SDL_GamepadMapping *)SDL_malloc(sizeof(*item->mapping)); + if (item->mapping) { + SDL_memcpy(item->mapping, out, sizeof(*out)); + } + return SDL_TRUE; } @@ -1579,8 +1796,9 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver = LINUX_JoystickOpen, LINUX_JoystickRumble, LINUX_JoystickRumbleTriggers, - LINUX_JoystickHasLED, + LINUX_JoystickGetCapabilities, LINUX_JoystickSetLED, + LINUX_JoystickSendEffect, LINUX_JoystickSetSensorsEnabled, LINUX_JoystickUpdate, LINUX_JoystickClose, diff --git a/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick_c.h b/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick_c.h index dea9405b7..49b8686d0 100644 --- a/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -56,6 +56,11 @@ struct joystick_hwdata SDL_bool has_key[KEY_MAX]; SDL_bool has_abs[ABS_MAX]; + /* Support for the classic joystick interface */ + SDL_bool classic; + Uint16 *key_pam; + Uint8 *abs_pam; + struct axis_correct { SDL_bool use_deadzones; @@ -74,6 +79,7 @@ struct joystick_hwdata /* Steam Controller support */ SDL_bool m_bSteamController; + /* 4 = (ABS_HAT3X-ABS_HAT0X)/2 (see input-event-codes.h in kernel) */ int hats_indices[4]; SDL_bool has_hat[4]; diff --git a/Engine/lib/sdl/src/joystick/os2/SDL_os2joystick.c b/Engine/lib/sdl/src/joystick/os2/SDL_os2joystick.c new file mode 100644 index 000000000..00b7fc554 --- /dev/null +++ b/Engine/lib/sdl/src/joystick/os2/SDL_os2joystick.c @@ -0,0 +1,799 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_JOYSTICK_OS2 + +/* OS/2 Joystick driver, contributed by Daniel Caetano */ + +#define INCL_DOSDEVICES +#define INCL_DOSDEVIOCTL +#define INCL_DOSMEMMGR +#include + +/***************************************************************** + * OS/2 Joystick driver defs. Based on docs at edm2.com and in old + * drivers available at hobbes.nmsu.edu and www.os2site.com + *****************************************************************/ + +#define GAME_GET_VERSION 0x01 +#define GAME_GET_PARMS 0x02 +#define GAME_GET_CALIB 0x04 +#define GAME_GET_STATUS 0x10 + +#define IOCTL_CAT_USER 0x80 +#define GAME_PORT_GET 0x20 +#define GAME_PORT_RESET 0x60 + +#pragma pack(push,1) +typedef struct { + USHORT uJs_AxCnt, uJs_AyCnt; /* A joystick X/Y pos */ + USHORT uJs_BxCnt, uJs_ByCnt; /* B joystick X/Y pos */ + USHORT usJs_ButtonA1Cnt, usJs_ButtonA2Cnt;/* A1/A2 press cnts */ + USHORT usJs_ButtonB1Cnt, usJs_ButtonB2Cnt;/* B1/B2 press cnts */ + UCHAR ucJs_JoyStickMask; /* mask of connected joystick pots */ + UCHAR ucJs_ButtonStatus; /* bits of switches down */ + ULONG ulJs_Ticks; /* total clock ticks (60 Hz) */ +} GAME_PORT_STRUCT; +#pragma pack(pop) + +typedef struct { + USHORT useA, useB; + USHORT mode; + USHORT format; + USHORT sampDiv; + USHORT scale; + USHORT res1, res2; +} GAME_PARM_STRUCT; + +typedef struct { + SHORT x, y; +} GAME_2DPOS_STRUCT; + +typedef struct { + SHORT lower, centre, upper; +} GAME_3POS_STRUCT; + +typedef struct { + GAME_3POS_STRUCT Ax, Ay, Bx, By; +} GAME_CALIB_STRUCT; + +typedef struct { + GAME_2DPOS_STRUCT A, B; + USHORT butMask; +} GAME_DATA_STRUCT; + +typedef struct { + GAME_DATA_STRUCT curdata; + USHORT b1cnt, b2cnt, b3cnt, b4cnt; +} GAME_STATUS_STRUCT; + +/*****************************************************************/ + +#include "SDL_joystick.h" +#include "SDL_events.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +static HFILE hJoyPort = NULLHANDLE; /* Joystick GAME$ Port Address */ +#define MAX_JOYSTICKS 2 /* Maximum of two joysticks */ +#define MAX_AXES 4 /* each joystick can have up to 4 axes */ +#define MAX_BUTTONS 8 /* 8 buttons */ +#define MAX_HATS 0 /* 0 hats - OS/2 doesn't support it */ +#define MAX_BALLS 0 /* and 0 balls - OS/2 doesn't support it */ +#define MAX_JOYNAME 128 /* Joystick name may have 128 characters */ +/* Calc Button Flag for buttons A to D */ +#define JOY_BUTTON_FLAG(n) (1< MAX_JOYSTICKS) maxdevs = MAX_JOYSTICKS; + + /* Defines min/max axes values (callibration) */ + ulDataLen = sizeof(stGameCalib); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_CALIB, + NULL, 0, NULL, &stGameCalib, ulDataLen, &ulDataLen); + if (rc != 0) + { + joyPortClose(&hJoyPort); + return SDL_SetError("Could not read callibration data."); + } + + /* Determine how many joysticks are active */ + numdevs = 0; /* Points no device */ + ucNewJoystickMask = 0x0F; /* read all 4 joystick axis */ + ulDataLen = sizeof(ucNewJoystickMask); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_RESET, + &ucNewJoystickMask, ulDataLen, &ulDataLen, NULL, 0, NULL); + if (rc == 0) + { + ulDataLen = sizeof(stJoyStatus); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, + NULL, 0, NULL, &stJoyStatus, ulDataLen, &ulDataLen); + if (rc != 0) + { + joyPortClose(&hJoyPort); + return SDL_SetError("Could not call joystick port."); + } + ulLastTick = stJoyStatus.ulJs_Ticks; + while (stJoyStatus.ulJs_Ticks == ulLastTick) + { + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, + NULL, 0, NULL, &stJoyStatus, ulDataLen, &ulDataLen); + } + if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) numdevs++; + if (((stJoyStatus.ucJs_JoyStickMask >> 2) & 0x03) > 0) numdevs++; + } + + if (numdevs > maxdevs) numdevs = maxdevs; + + /* If *any* joystick was detected... Let's configure SDL for them */ + if (numdevs > 0) + { + /* Verify if it is a "user defined" joystick */ + if (joyGetEnv(&joycfg)) + { + GAME_3POS_STRUCT * axis[4]; + axis[0] = &stGameCalib.Ax; + axis[1] = &stGameCalib.Ay; + axis[2] = &stGameCalib.Bx; + axis[3] = &stGameCalib.By; + + /* Say it has one device only (user defined is always one device only) */ + numdevs = 1; + + /* Define Device 0 as... */ + SYS_JoyData[0].id = 0; + + /* Define Number of Axes... up to 4 */ + if (joycfg.axes>MAX_AXES) joycfg.axes = MAX_AXES; + SYS_JoyData[0].axes = joycfg.axes; + + /* Define number of buttons... 8 if 2 axes, 6 if 3 axes and 4 if 4 axes */ + maxbut = MAX_BUTTONS; + if (joycfg.axes>2) maxbut -= ((joycfg.axes - 2)<<1); /* MAX_BUTTONS - 2*(axes-2) */ + if (joycfg.buttons > maxbut) joycfg.buttons = maxbut; + SYS_JoyData[0].buttons = joycfg.buttons; + + /* Define number of hats */ + if (joycfg.hats > MAX_HATS) joycfg.hats = MAX_HATS; + SYS_JoyData[0].hats = joycfg.hats; + + /* Define number of balls */ + if (joycfg.balls > MAX_BALLS) joycfg.balls = MAX_BALLS; + SYS_JoyData[0].balls = joycfg.balls; + + /* Initialize Axes Callibration Values */ + for (i=0; ilower; + SYS_JoyData[0].axes_med[i] = axis[i]->centre; + SYS_JoyData[0].axes_max[i] = axis[i]->upper; + } + /* Initialize Buttons 5 to 8 structures */ + if (joycfg.buttons>=5) SYS_JoyData[0].buttoncalc[0] = ((axis[2]->lower+axis[3]->centre)>>1); + if (joycfg.buttons>=6) SYS_JoyData[0].buttoncalc[1] = ((axis[3]->lower+axis[3]->centre)>>1); + if (joycfg.buttons>=7) SYS_JoyData[0].buttoncalc[2] = ((axis[2]->upper+axis[3]->centre)>>1); + if (joycfg.buttons>=8) SYS_JoyData[0].buttoncalc[3] = ((axis[3]->upper+axis[3]->centre)>>1); + /* Intialize Joystick Name */ + SDL_strlcpy (SYS_JoyData[0].szDeviceName,joycfg.name, SDL_arraysize(SYS_JoyData[0].szDeviceName)); + } + /* Default Init ... autoconfig */ + else + { + /* if two devices were detected... configure as Joy1 4 axis and Joy2 2 axis */ + if (numdevs == 2) + { + /* Define Device 0 as 4 axes, 4 buttons */ + SYS_JoyData[0].id=0; + SYS_JoyData[0].axes = 4; + SYS_JoyData[0].buttons = 4; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; + SYS_JoyData[0].axes_min[2] = stGameCalib.Bx.lower; + SYS_JoyData[0].axes_med[2] = stGameCalib.Bx.centre; + SYS_JoyData[0].axes_max[2] = stGameCalib.Bx.upper; + SYS_JoyData[0].axes_min[3] = stGameCalib.By.lower; + SYS_JoyData[0].axes_med[3] = stGameCalib.By.centre; + SYS_JoyData[0].axes_max[3] = stGameCalib.By.upper; + /* Define Device 1 as 2 axes, 2 buttons */ + SYS_JoyData[1].id=1; + SYS_JoyData[1].axes = 2; + SYS_JoyData[1].buttons = 2; + SYS_JoyData[1].hats = 0; + SYS_JoyData[1].balls = 0; + SYS_JoyData[1].axes_min[0] = stGameCalib.Bx.lower; + SYS_JoyData[1].axes_med[0] = stGameCalib.Bx.centre; + SYS_JoyData[1].axes_max[0] = stGameCalib.Bx.upper; + SYS_JoyData[1].axes_min[1] = stGameCalib.By.lower; + SYS_JoyData[1].axes_med[1] = stGameCalib.By.centre; + SYS_JoyData[1].axes_max[1] = stGameCalib.By.upper; + } + /* One joystick only? */ + else + { + /* If it is joystick A... */ + if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) + { + /* Define Device 0 as 2 axes, 4 buttons */ + SYS_JoyData[0].id=0; + SYS_JoyData[0].axes = 2; + SYS_JoyData[0].buttons = 4; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; + } + /* If not, it is joystick B */ + else + { + /* Define Device 1 as 2 axes, 2 buttons */ + SYS_JoyData[0].id=1; + SYS_JoyData[0].axes = 2; + SYS_JoyData[0].buttons = 2; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Bx.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Bx.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Bx.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.By.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.By.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.By.upper; + } + } + + /* Hack to define Joystick Port Names */ + if (numdevs > maxdevs) numdevs = maxdevs; + + for (i = 0; i < numdevs; i++) + { + SDL_snprintf(SYS_JoyData[i].szDeviceName, + SDL_arraysize(SYS_JoyData[i].szDeviceName), + "Default Joystick %c", 'A'+SYS_JoyData[i].id); + } + } + } + /* Return the number of devices found */ + numjoysticks = numdevs; + return numdevs; +} + +static int OS2_NumJoysticks(void) +{ + return numjoysticks; +} + +static void OS2_JoystickDetect(void) +{ +} + +/***********************************************************/ +/* Function to get the device-dependent name of a joystick */ +/***********************************************************/ +static const char *OS2_JoystickGetDeviceName(int device_index) +{ + /* No need to verify if device exists, already done in upper layer */ + return SYS_JoyData[device_index].szDeviceName; +} + +static int OS2_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void OS2_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static SDL_JoystickGUID OS2_JoystickGetDeviceGUID(int device_index) +{ + SDL_JoystickGUID guid; + /* the GUID is just the first 16 chars of the name for now */ + const char *name = OS2_JoystickGetDeviceName(device_index); + SDL_zero(guid); + SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name))); + return guid; +} + +static SDL_JoystickID OS2_JoystickGetDeviceInstanceID(int device_index) +{ + return device_index; +} + +/******************************************************************************/ +/* Function to open a joystick for use. */ +/* The joystick to open is specified by the device index. */ +/* This should fill the nbuttons and naxes fields of the joystick structure. */ +/* It returns 0, or -1 if there is an error. */ +/******************************************************************************/ +static int OS2_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + int index; /* Index shortcut for index in joystick structure */ + int i; /* Generic Counter */ + + /* allocate memory for system specific hardware data */ + joystick->hwdata = (struct joystick_hwdata *) SDL_calloc(1, sizeof(*joystick->hwdata)); + if (!joystick->hwdata) + { + return SDL_OutOfMemory(); + } + + /* ShortCut Pointer */ + index = device_index; + joystick->instance_id = device_index; + + /* Define offsets and scales for all axes */ + joystick->hwdata->id = SYS_JoyData[index].id; + for (i = 0; i < MAX_AXES; ++i) + { + if ((i < 2) || i < SYS_JoyData[index].axes) + { + joystick->hwdata->transaxes[i].offset = ((SDL_JOYSTICK_AXIS_MAX + SDL_JOYSTICK_AXIS_MIN)>>1) - SYS_JoyData[index].axes_med[i]; + joystick->hwdata->transaxes[i].scale1 = (float)SDL_abs((SDL_JOYSTICK_AXIS_MIN/SYS_JoyData[index].axes_min[i])); + joystick->hwdata->transaxes[i].scale2 = (float)SDL_abs((SDL_JOYSTICK_AXIS_MAX/SYS_JoyData[index].axes_max[i])); + } + else + { + joystick->hwdata->transaxes[i].offset = 0; + joystick->hwdata->transaxes[i].scale1 = 1.0f; /* Just in case */ + joystick->hwdata->transaxes[i].scale2 = 1.0f; /* Just in case */ + } + } + + /* fill nbuttons, naxes, and nhats fields */ + joystick->nbuttons = SYS_JoyData[index].buttons; + joystick->naxes = SYS_JoyData[index].axes; + + /* joystick->nhats = SYS_JoyData[index].hats; */ + joystick->nhats = 0; /* No support for hats at this time */ + + /* joystick->nballs = SYS_JoyData[index].balls; */ + joystick->nballs = 0; /* No support for balls at this time */ + + return 0; +} + +static int OS2_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static int OS2_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 OS2_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +static int OS2_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int OS2_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int OS2_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +/***************************************************************************/ +/* Function to update the state of a joystick - called as a device poll. */ +/* This function shouldn't update the joystick structure directly, */ +/* but instead should call SDL_PrivateJoystick*() to deliver events */ +/* and update joystick device state. */ +/***************************************************************************/ +static void OS2_JoystickUpdate(SDL_Joystick *joystick) +{ + APIRET rc; /* Generic OS/2 return code */ + int index; /* index shortcurt to joystick index */ + int i; /* Generic counter */ + int normbut; /* Number of buttons reported by joystick */ + int corr; /* Correction for button names */ + Sint16 value; /* Values used to update axis values */ + struct _transaxes *transaxes; /* Shortcut for Correction structure */ + Uint32 pos[MAX_AXES]; /* Vector to inform the Axis status */ + ULONG ulDataLen; /* Size of data */ + GAME_STATUS_STRUCT stGameStatus; /* Joystick Status Structure */ + + ulDataLen = sizeof(stGameStatus); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_STATUS, + NULL, 0, NULL, &stGameStatus, ulDataLen, &ulDataLen); + if (rc != 0) + { + SDL_SetError("Could not read joystick status."); + return; /* Could not read data */ + } + + /* Shortcut pointer */ + index = joystick->instance_id; + + /* joystick motion events */ + + if (SYS_JoyData[index].id == 0) + { + pos[0] = stGameStatus.curdata.A.x; + pos[1] = stGameStatus.curdata.A.y; + if (SYS_JoyData[index].axes >= 3) pos[2] = stGameStatus.curdata.B.x; + else pos[2] = 0; + if (SYS_JoyData[index].axes >= 4) pos[3] = stGameStatus.curdata.B.y; + else pos[3] = 0; + /* OS/2 basic drivers do not support more than 4 axes joysticks */ + } + else if (SYS_JoyData[index].id == 1) + { + pos[0] = stGameStatus.curdata.B.x; + pos[1] = stGameStatus.curdata.B.y; + pos[2] = 0; + pos[3] = 0; + } + + /* Corrects the movements using the callibration */ + transaxes = joystick->hwdata->transaxes; + for (i = 0; i < joystick->naxes; i++) + { + value = pos[i] + transaxes[i].offset; + if (value < 0) + { + value *= transaxes[i].scale1; + if (value > 0) value = SDL_JOYSTICK_AXIS_MIN; + } + else + { + value *= transaxes[i].scale2; + if (value < 0) value = SDL_JOYSTICK_AXIS_MAX; + } + SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)value); + } + + /* joystick button A to D events */ + if (SYS_JoyData[index].id == 1) corr = 2; + else corr = 0; + normbut = 4; /* Number of normal buttons */ + if (joystick->nbuttons < normbut) normbut = joystick->nbuttons; + for (i = corr; (i-corr) < normbut; ++i) + { + /* + Button A: 1110 0000 + Button B: 1101 0000 + Button C: 1011 0000 + Button D: 0111 0000 + */ + if ((~stGameStatus.curdata.butMask)>>4 & JOY_BUTTON_FLAG(i)) + { + SDL_PrivateJoystickButton(joystick, (Uint8)(i-corr), SDL_PRESSED); + } + else + { + SDL_PrivateJoystickButton(joystick, (Uint8)(i-corr), SDL_RELEASED); + } + } + + /* Joystick button E to H buttons */ + /* + Button E: Axis 2 X Left + Button F: Axis 2 Y Up + Button G: Axis 2 X Right + Button H: Axis 2 Y Down + */ + if (joystick->nbuttons >= 5) + { + if (stGameStatus.curdata.B.x < SYS_JoyData[index].buttoncalc[0]) SDL_PrivateJoystickButton(joystick, (Uint8)4, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)4, SDL_RELEASED); + } + if (joystick->nbuttons >= 6) + { + if (stGameStatus.curdata.B.y < SYS_JoyData[index].buttoncalc[1]) SDL_PrivateJoystickButton(joystick, (Uint8)5, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)5, SDL_RELEASED); + } + if (joystick->nbuttons >= 7) + { + if (stGameStatus.curdata.B.x > SYS_JoyData[index].buttoncalc[2]) SDL_PrivateJoystickButton(joystick, (Uint8)6, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)6, SDL_RELEASED); + } + if (joystick->nbuttons >= 8) + { + if (stGameStatus.curdata.B.y > SYS_JoyData[index].buttoncalc[3]) SDL_PrivateJoystickButton(joystick, (Uint8)7, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)7, SDL_RELEASED); + } + + /* joystick hat events */ + /* Not Supported under OS/2 */ + /* joystick ball events */ + /* Not Supported under OS/2 */ +} + +/******************************************/ +/* Function to close a joystick after use */ +/******************************************/ +static void OS2_JoystickClose(SDL_Joystick *joystick) +{ + /* free system specific hardware data */ + SDL_free(joystick->hwdata); +} + +/********************************************************************/ +/* Function to perform any system-specific joystick related cleanup */ +/********************************************************************/ +static void OS2_JoystickQuit(void) +{ + joyPortClose(&hJoyPort); +} + +static SDL_bool OS2_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + + +/************************/ +/* OS/2 Implementations */ +/************************/ + +/*****************************************/ +/* Open Joystick Port, if not opened yet */ +/*****************************************/ +static int joyPortOpen(HFILE * hGame) +{ + APIRET rc; /* Generic Return Code */ + ULONG ulAction; /* ? */ + ULONG ulVersion; /* Version of joystick driver */ + ULONG ulDataLen; /* Size of version data */ + + /* Verifies if joyport is not already open... */ + if (*hGame != NULLHANDLE) return 0; + + /* Open GAME$ for read */ + rc = DosOpen("GAME$ ", hGame, &ulAction, 0, FILE_READONLY, + FILE_OPEN, OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, NULL); + if (rc != 0) + { + return SDL_SetError("Could not open Joystick Port."); + } + + /* Get Joystick Driver Version... must be 2.0 or higher */ + ulVersion = 0; + ulDataLen = sizeof(ulVersion); + rc = DosDevIOCtl(*hGame, IOCTL_CAT_USER, GAME_GET_VERSION, + NULL, 0, NULL, &ulVersion, ulDataLen, &ulDataLen); + if (rc != 0) + { + joyPortClose(hGame); + return SDL_SetError("Could not get Joystick Driver version."); + } + if (ulVersion < 0x20) + { + joyPortClose(hGame); + return SDL_SetError("Driver too old. At least IBM driver version 2.0 required."); + } + return 0; +} + +/****************************/ +/* Close JoyPort, if opened */ +/****************************/ +static void joyPortClose(HFILE * hGame) +{ + if (*hGame != NULLHANDLE) DosClose(*hGame); + *hGame = NULLHANDLE; +} + +/***************************/ +/* Get SDL Joystick EnvVar */ +/***************************/ +static int joyGetEnv(struct _joycfg * joydata) +{ + const char *joyenv; /* Pointer to tested character */ + char tempnumber[5]; /* Temporary place to put numeric texts */ + + joyenv = SDL_getenv("SDL_OS2_JOYSTICK"); + if (joyenv == NULL) return 0; + + /* Joystick Environment is defined! */ + while (*joyenv == ' ' && *joyenv != 0) joyenv++; /* jump spaces... */ + + /* If the string name starts with '... get if fully */ + if (*joyenv == '\'') { + joyenv++; + joyenv += joyGetData(joyenv,joydata->name,'\'',sizeof(joydata->name)); + } + /* If not, get it until the next space */ + else if (*joyenv == '\"') { + joyenv++; + joyenv += joyGetData(joyenv,joydata->name,'\"',sizeof(joydata->name)); + } + else { + joyenv += joyGetData(joyenv,joydata->name, ' ',sizeof(joydata->name)); + } + + /* Now get the number of axes */ + while (*joyenv == ' ' && *joyenv != 0) joyenv++; /* jump spaces... */ + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->axes = SDL_atoi(tempnumber); + + /* Now get the number of buttons */ + while (*joyenv == ' ' && *joyenv != 0) joyenv++; /* jump spaces... */ + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->buttons = SDL_atoi(tempnumber); + + /* Now get the number of hats */ + while (*joyenv == ' ' && *joyenv != 0) joyenv++; /* jump spaces... */ + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->hats = SDL_atoi(tempnumber); + + /* Now get the number of balls */ + while (*joyenv==' ' && *joyenv != 0) joyenv++; /* jump spaces... */ + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->balls = SDL_atoi(tempnumber); + return 1; +} + +/************************************************************************/ +/* Get a text from in the string starting in joyenv until it finds */ +/* the stopchar or maxchars is reached. The result is placed in name. */ +/************************************************************************/ +static int joyGetData(const char *joyenv, char *name, char stopchar, size_t maxchars) +{ + char *nameptr; /* Pointer to the selected character */ + int chcnt = 0; /* Count how many characters where copied */ + + nameptr = name; + while (*joyenv!=stopchar && *joyenv!=0) + { + if (nameptr < (name + (maxchars-1))) + { + *nameptr = *joyenv; /* Only copy if smaller than maximum */ + nameptr++; + } + chcnt++; + joyenv++; + } + if (*joyenv == stopchar) + { + joyenv++; /* Jump stopchar */ + chcnt++; + } + *nameptr = 0; /* Mark last byte */ + return chcnt; +} + +SDL_JoystickDriver SDL_OS2_JoystickDriver = +{ + OS2_JoystickInit, + OS2_NumJoysticks, + OS2_JoystickDetect, + OS2_JoystickGetDeviceName, + OS2_JoystickGetDevicePlayerIndex, + OS2_JoystickSetDevicePlayerIndex, + OS2_JoystickGetDeviceGUID, + OS2_JoystickGetDeviceInstanceID, + OS2_JoystickOpen, + OS2_JoystickRumble, + OS2_JoystickRumbleTriggers, + OS2_JoystickGetCapabilities, + OS2_JoystickSetLED, + OS2_JoystickSendEffect, + OS2_JoystickSetSensorsEnabled, + OS2_JoystickUpdate, + OS2_JoystickClose, + OS2_JoystickQuit, + OS2_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_OS2 */ diff --git a/Engine/lib/sdl/src/joystick/psp/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/psp/SDL_sysjoystick.c index 261e6a677..d71979560 100644 --- a/Engine/lib/sdl/src/joystick/psp/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/psp/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -63,10 +63,10 @@ static point c = { 78, 32767 }; static point d = { 128, 32767 }; /* simple linear interpolation between two points */ -static SDL_INLINE void lerp (point *dest, point *a, point *b, float t) +static SDL_INLINE void lerp (point *dest, point *pt_a, point *pt_b, float t) { - dest->x = a->x + (b->x - a->x)*t; - dest->y = a->y + (b->y - a->y)*t; + dest->x = pt_a->x + (pt_b->x - pt_a->x)*t; + dest->y = pt_a->y + (pt_b->y - pt_a->y)*t; } /* evaluate a point on a bezier-curve. t goes from 0 to 1.0 */ @@ -103,7 +103,7 @@ int JoystickUpdate(void *data) * Joystick 0 should be the system default joystick. * It should return number of joysticks, or -1 on an unrecoverable fatal error. */ -int SDL_SYS_JoystickInit(void) +static int PSP_JoystickInit(void) { int i; @@ -132,35 +132,55 @@ int SDL_SYS_JoystickInit(void) return 1; } -int SDL_SYS_NumJoysticks(void) +static int PSP_NumJoysticks(void) { return 1; } -void SDL_SYS_JoystickDetect(void) +static void PSP_JoystickDetect(void) { } +#if 0 /* Function to get the device-dependent name of a joystick */ -const char * SDL_SYS_JoystickNameForDeviceIndex(int device_index) +static const char *PSP_JoystickName(int idx) +{ + if (idx == 0) return "PSP controller"; + SDL_SetError("No joystick available with that index"); + return NULL; +} +#endif + +/* Function to get the device-dependent name of a joystick */ +static const char *PSP_JoystickGetDeviceName(int device_index) { return "PSP builtin joypad"; } -/* Function to perform the mapping from device index to the instance id for this index */ -SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +static int PSP_JoystickGetDevicePlayerIndex(int device_index) { - return device_index; + return -1; } -/* Function to get the device-dependent name of a joystick */ -const char *SDL_SYS_JoystickName(int index) +static void +PSP_JoystickSetDevicePlayerIndex(int device_index, int player_index) { - if (index == 0) - return "PSP controller"; +} - SDL_SetError("No joystick available with that index"); - return(NULL); +static SDL_JoystickGUID PSP_JoystickGetDeviceGUID(int device_index) +{ + SDL_JoystickGUID guid; + /* the GUID is just the first 16 chars of the name for now */ + const char *name = PSP_JoystickGetDeviceName(device_index); + SDL_zero(guid); + SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name))); + return guid; +} + +/* Function to perform the mapping from device index to the instance id for this index */ +static SDL_JoystickID PSP_JoystickGetDeviceInstanceID(int device_index) +{ + return device_index; } /* Function to open a joystick for use. @@ -168,7 +188,7 @@ const char *SDL_SYS_JoystickName(int index) This should fill the nbuttons and naxes fields of the joystick structure. It returns 0, or -1 if there is an error. */ -int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index) +static int PSP_JoystickOpen(SDL_Joystick *joystick, int device_index) { joystick->nbuttons = 14; joystick->naxes = 2; @@ -177,12 +197,46 @@ int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index) return 0; } +static int +PSP_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static int +PSP_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 PSP_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +static int +PSP_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int +PSP_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int PSP_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events * and update joystick device state. */ -void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +static void PSP_JoystickUpdate(SDL_Joystick *joystick) { int i; enum PspCtrlButtons buttons; @@ -225,12 +279,12 @@ void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) } /* Function to close a joystick after use */ -void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +static void PSP_JoystickClose(SDL_Joystick *joystick) { } /* Function to perform any system-specific joystick related cleanup */ -void SDL_SYS_JoystickQuit(void) +static void PSP_JoystickQuit(void) { /* Cleanup Threads and Semaphore. */ running = 0; @@ -238,25 +292,34 @@ void SDL_SYS_JoystickQuit(void) SDL_DestroySemaphore(pad_sem); } -SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +static SDL_bool +PSP_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) { - SDL_JoystickGUID guid; - /* the GUID is just the first 16 chars of the name for now */ - const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); - SDL_zero( guid ); - SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); - return guid; + return SDL_FALSE; } -SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) +SDL_JoystickDriver SDL_PSP_JoystickDriver = { - SDL_JoystickGUID guid; - /* the GUID is just the first 16 chars of the name for now */ - const char *name = joystick->name; - SDL_zero( guid ); - SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); - return guid; -} + PSP_JoystickInit, + PSP_NumJoysticks, + PSP_JoystickDetect, + PSP_JoystickGetDeviceName, + PSP_JoystickGetDevicePlayerIndex, + PSP_JoystickSetDevicePlayerIndex, + PSP_JoystickGetDeviceGUID, + PSP_JoystickGetDeviceInstanceID, + PSP_JoystickOpen, + PSP_JoystickRumble, + PSP_JoystickRumbleTriggers, + PSP_JoystickGetCapabilities, + PSP_JoystickSetLED, + PSP_JoystickSendEffect, + PSP_JoystickSetSensorsEnabled, + PSP_JoystickUpdate, + PSP_JoystickClose, + PSP_JoystickQuit, + PSP_JoystickGetGamepadMapping +}; #endif /* SDL_JOYSTICK_PSP */ diff --git a/Engine/lib/sdl/src/joystick/sort_controllers.py b/Engine/lib/sdl/src/joystick/sort_controllers.py index 084260965..bcd05f6a4 100755 --- a/Engine/lib/sdl/src/joystick/sort_controllers.py +++ b/Engine/lib/sdl/src/joystick/sort_controllers.py @@ -67,7 +67,7 @@ def write_controllers(): for entry in sorted(controllers, key=lambda entry: entry[2]+"-"+entry[1]): line = "".join(entry) + "\n" line = line.replace("\t", " ") - if not line.endswith(",\n") and not line.endswith("*/\n"): + if not line.endswith(",\n") and not line.endswith("*/\n") and not line.endswith(",\r\n") and not line.endswith("*/\r\n"): print("Warning: '%s' is missing a comma at the end of the line" % (line)) output.write(line) diff --git a/Engine/lib/sdl/src/joystick/steam/SDL_steamcontroller.c b/Engine/lib/sdl/src/joystick/steam/SDL_steamcontroller.c index 82656f4ed..52511fbea 100644 --- a/Engine/lib/sdl/src/joystick/steam/SDL_steamcontroller.c +++ b/Engine/lib/sdl/src/joystick/steam/SDL_steamcontroller.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/joystick/steam/SDL_steamcontroller.h b/Engine/lib/sdl/src/joystick/steam/SDL_steamcontroller.h index 629d6875e..f740693ff 100644 --- a/Engine/lib/sdl/src/joystick/steam/SDL_steamcontroller.h +++ b/Engine/lib/sdl/src/joystick/steam/SDL_steamcontroller.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/joystick/usb_ids.h b/Engine/lib/sdl/src/joystick/usb_ids.h index c39ff6919..97f37b0f8 100644 --- a/Engine/lib/sdl/src/joystick/usb_ids.h +++ b/Engine/lib/sdl/src/joystick/usb_ids.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,36 +24,61 @@ /* Definitions of useful USB VID/PID values */ +#define USB_VENDOR_AMAZON 0x1949 #define USB_VENDOR_APPLE 0x05ac +#define USB_VENDOR_GOOGLE 0x18d1 #define USB_VENDOR_HYPERKIN 0x2e24 #define USB_VENDOR_MICROSOFT 0x045e #define USB_VENDOR_NINTENDO 0x057e #define USB_VENDOR_NVIDIA 0x0955 #define USB_VENDOR_PDP 0x0e6f #define USB_VENDOR_POWERA 0x24c6 -#define USB_VENDOR_SONY 0x054c +#define USB_VENDOR_POWERA_ALT 0x20d6 #define USB_VENDOR_RAZER 0x1532 +#define USB_VENDOR_SHENZHEN 0x0079 +#define USB_VENDOR_SONY 0x054c #define USB_VENDOR_VALVE 0x28de -#define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER 0x0337 -#define USB_PRODUCT_NINTENDO_SWITCH_PRO 0x2009 -#define USB_PRODUCT_RAZER_PANTHERA 0x0401 -#define USB_PRODUCT_RAZER_PANTHERA_EVO 0x1008 -#define USB_PRODUCT_RAZER_ATROX 0x0a00 -#define USB_PRODUCT_SONY_DS4 0x05c4 -#define USB_PRODUCT_SONY_DS4_DONGLE 0x0ba0 -#define USB_PRODUCT_SONY_DS4_SLIM 0x09cc -#define USB_PRODUCT_SONY_DS5 0x0ce6 -#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 0x02e3 -#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 0x0b00 -#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH 0x0b05 -#define USB_PRODUCT_XBOX_ONE_S 0x02ea -#define USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH 0x02e0 -#define USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH 0x02fd -#define USB_PRODUCT_XBOX_ONE_SERIES_X 0x0b12 -#define USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH 0x0b13 -#define USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER 0x02ff -#define USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER 0x02fe /* Made up product ID for XInput */ +#define USB_PRODUCT_AMAZON_LUNA_CONTROLLER 0x0419 +#define USB_PRODUCT_GOOGLE_STADIA_CONTROLLER 0x9400 +#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER 0x1846 +#define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER 0x0337 +#define USB_PRODUCT_NINTENDO_SWITCH_PRO 0x2009 +#define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT 0x2006 +#define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT 0x2007 +#define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP 0x200e +#define USB_PRODUCT_RAZER_PANTHERA 0x0401 +#define USB_PRODUCT_RAZER_PANTHERA_EVO 0x1008 +#define USB_PRODUCT_RAZER_ATROX 0x0a00 +#define USB_PRODUCT_SONY_DS4 0x05c4 +#define USB_PRODUCT_SONY_DS4_DONGLE 0x0ba0 +#define USB_PRODUCT_SONY_DS4_SLIM 0x09cc +#define USB_PRODUCT_SONY_DS5 0x0ce6 +#define USB_PRODUCT_VICTRIX_FS_PRO_V2 0x0207 +#define USB_PRODUCT_XBOX360_XUSB_CONTROLLER 0x02a1 /* XUSB driver software PID */ +#define USB_PRODUCT_XBOX360_WIRED_CONTROLLER 0x028e +#define USB_PRODUCT_XBOX360_WIRELESS_RECEIVER 0x0719 +#define USB_PRODUCT_XBOX_ONE_ADAPTIVE 0x0b0a +#define USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLUETOOTH 0x0b0c +#define USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLE 0x0b21 +#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 0x02e3 +#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 0x0b00 +#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH 0x0b05 +#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLE 0x0b22 +#define USB_PRODUCT_XBOX_ONE_S 0x02ea +#define USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH 0x02e0 +#define USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH 0x02fd +#define USB_PRODUCT_XBOX_ONE_S_REV2_BLE 0x0b20 +#define USB_PRODUCT_XBOX_SERIES_X 0x0b12 +#define USB_PRODUCT_XBOX_SERIES_X_BLE 0x0b13 +#define USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT 0x02d6 +#define USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE 0x02d9 +#define USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW 0x02da +#define USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 0x4001 +#define USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA 0x4002 +#define USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER 0x02ff /* XBOXGIP driver software PID */ +#define USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER 0x02fe /* Made up product ID for XInput */ +#define USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD 0x11ff /* USB usage pages */ #define USB_USAGEPAGE_GENERIC_DESKTOP 0x0001 @@ -78,6 +103,12 @@ #define USB_USAGE_GENERIC_WHEEL 0x0038 #define USB_USAGE_GENERIC_HAT 0x0039 +/* Bluetooth SIG assigned Company Identifiers + https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers/ */ +#define BLUETOOTH_VENDOR_AMAZON 0x0171 + +#define BLUETOOTH_PRODUCT_LUNA_CONTROLLER 0x0419 + #endif /* usb_ids_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/joystick/virtual/SDL_virtualjoystick.c b/Engine/lib/sdl/src/joystick/virtual/SDL_virtualjoystick.c index e140b4fa0..508dd80f9 100644 --- a/Engine/lib/sdl/src/joystick/virtual/SDL_virtualjoystick.c +++ b/Engine/lib/sdl/src/joystick/virtual/SDL_virtualjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -164,7 +164,7 @@ SDL_JoystickDetachVirtualInner(int device_index) int -SDL_JoystickSetVirtualAxisInner(SDL_Joystick * joystick, int axis, Sint16 value) +SDL_JoystickSetVirtualAxisInner(SDL_Joystick *joystick, int axis, Sint16 value) { joystick_hwdata *hwdata; @@ -176,7 +176,7 @@ SDL_JoystickSetVirtualAxisInner(SDL_Joystick * joystick, int axis, Sint16 value) } hwdata = (joystick_hwdata *)joystick->hwdata; - if (axis < 0 || axis >= hwdata->nbuttons) { + if (axis < 0 || axis >= hwdata->naxes) { SDL_UnlockJoysticks(); return SDL_SetError("Invalid axis index"); } @@ -189,7 +189,7 @@ SDL_JoystickSetVirtualAxisInner(SDL_Joystick * joystick, int axis, Sint16 value) int -SDL_JoystickSetVirtualButtonInner(SDL_Joystick * joystick, int button, Uint8 value) +SDL_JoystickSetVirtualButtonInner(SDL_Joystick *joystick, int button, Uint8 value) { joystick_hwdata *hwdata; @@ -214,7 +214,7 @@ SDL_JoystickSetVirtualButtonInner(SDL_Joystick * joystick, int button, Uint8 val int -SDL_JoystickSetVirtualHatInner(SDL_Joystick * joystick, int hat, Uint8 value) +SDL_JoystickSetVirtualHatInner(SDL_Joystick *joystick, int hat, Uint8 value) { joystick_hwdata *hwdata; @@ -226,7 +226,7 @@ SDL_JoystickSetVirtualHatInner(SDL_Joystick * joystick, int hat, Uint8 value) } hwdata = (joystick_hwdata *)joystick->hwdata; - if (hat < 0 || hat >= hwdata->nbuttons) { + if (hat < 0 || hat >= hwdata->nhats) { SDL_UnlockJoysticks(); return SDL_SetError("Invalid hat index"); } @@ -313,7 +313,7 @@ VIRTUAL_JoystickGetDeviceInstanceID(int device_index) static int -VIRTUAL_JoystickOpen(SDL_Joystick * joystick, int device_index) +VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index) { joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index); if (!hwdata) { @@ -333,27 +333,33 @@ VIRTUAL_JoystickOpen(SDL_Joystick * joystick, int device_index) static int -VIRTUAL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +VIRTUAL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { return SDL_Unsupported(); } static int -VIRTUAL_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble) +VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { return SDL_Unsupported(); } -static SDL_bool -VIRTUAL_JoystickHasLED(SDL_Joystick * joystick) +static Uint32 +VIRTUAL_JoystickGetCapabilities(SDL_Joystick *joystick) { - return SDL_FALSE; + return 0; } static int -VIRTUAL_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) +VIRTUAL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int +VIRTUAL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) { return SDL_Unsupported(); } @@ -366,7 +372,7 @@ VIRTUAL_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) static void -VIRTUAL_JoystickUpdate(SDL_Joystick * joystick) +VIRTUAL_JoystickUpdate(SDL_Joystick *joystick) { joystick_hwdata *hwdata; int i; @@ -393,7 +399,7 @@ VIRTUAL_JoystickUpdate(SDL_Joystick * joystick) static void -VIRTUAL_JoystickClose(SDL_Joystick * joystick) +VIRTUAL_JoystickClose(SDL_Joystick *joystick) { joystick_hwdata *hwdata; @@ -436,8 +442,9 @@ SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver = VIRTUAL_JoystickOpen, VIRTUAL_JoystickRumble, VIRTUAL_JoystickRumbleTriggers, - VIRTUAL_JoystickHasLED, + VIRTUAL_JoystickGetCapabilities, VIRTUAL_JoystickSetLED, + VIRTUAL_JoystickSendEffect, VIRTUAL_JoystickSetSensorsEnabled, VIRTUAL_JoystickUpdate, VIRTUAL_JoystickClose, @@ -445,6 +452,6 @@ SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver = VIRTUAL_JoystickGetGamepadMapping }; -#endif /* SDL_JOYSTICK_VIRTUAL || SDL_JOYSTICK_DISABLED */ +#endif /* SDL_JOYSTICK_VIRTUAL */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/joystick/virtual/SDL_virtualjoystick_c.h b/Engine/lib/sdl/src/joystick/virtual/SDL_virtualjoystick_c.h index 654fdc5ba..b251c2d14 100644 --- a/Engine/lib/sdl/src/joystick/virtual/SDL_virtualjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/virtual/SDL_virtualjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/joystick/vita/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/vita/SDL_sysjoystick.c new file mode 100644 index 000000000..aa52cd77f --- /dev/null +++ b/Engine/lib/sdl/src/joystick/vita/SDL_sysjoystick.c @@ -0,0 +1,425 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_JOYSTICK_VITA + +/* This is the PSVita implementation of the SDL joystick API */ +#include +#include +#include + +#include /* For the definition of NULL */ +#include + +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +#include "SDL_events.h" +#include "SDL_error.h" +#include "SDL_thread.h" +#include "SDL_mutex.h" +#include "SDL_timer.h" + +/* Current pad state */ +static SceCtrlData pad0 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .lt = 0, .rt = 0, .buttons = 0 }; +static SceCtrlData pad1 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .lt = 0, .rt = 0, .buttons = 0 }; +static SceCtrlData pad2 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .lt = 0, .rt = 0, .buttons = 0 }; +static SceCtrlData pad3 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .lt = 0, .rt = 0, .buttons = 0 }; + +static int port_map[4]= { 0, 2, 3, 4 }; //index: SDL joy number, entry: Vita port number +static int ext_port_map[4]= { 1, 2, 3, 4 }; //index: SDL joy number, entry: Vita port number. For external controllers + +static int SDL_numjoysticks = 1; + +static const unsigned int button_map[] = { + SCE_CTRL_TRIANGLE, + SCE_CTRL_CIRCLE, + SCE_CTRL_CROSS, + SCE_CTRL_SQUARE, + SCE_CTRL_LTRIGGER, + SCE_CTRL_RTRIGGER, + SCE_CTRL_DOWN, + SCE_CTRL_LEFT, + SCE_CTRL_UP, + SCE_CTRL_RIGHT, + SCE_CTRL_SELECT, + SCE_CTRL_START +}; + +static const unsigned int ext_button_map[] = { + SCE_CTRL_TRIANGLE, + SCE_CTRL_CIRCLE, + SCE_CTRL_CROSS, + SCE_CTRL_SQUARE, + SCE_CTRL_L1, + SCE_CTRL_R1, + SCE_CTRL_DOWN, + SCE_CTRL_LEFT, + SCE_CTRL_UP, + SCE_CTRL_RIGHT, + SCE_CTRL_SELECT, + SCE_CTRL_START, + SCE_CTRL_L2, + SCE_CTRL_R2, + SCE_CTRL_L3, + SCE_CTRL_R3 +}; + +static int analog_map[256]; /* Map analog inputs to -32768 -> 32767 */ + +typedef struct +{ + int x; + int y; +} point; + +/* 4 points define the bezier-curve. */ +/* The Vita has a good amount of analog travel, so use a linear curve */ +static point a = { 0, 0 }; +static point b = { 0, 0 }; +static point c = { 128, 32767 }; +static point d = { 128, 32767 }; + +/* simple linear interpolation between two points */ +static SDL_INLINE void lerp (point *dest, point *first, point *second, float t) +{ + dest->x = first->x + (second->x - first->x) * t; + dest->y = first->y + (second->y - first->y) * t; +} + +/* evaluate a point on a bezier-curve. t goes from 0 to 1.0 */ +static int calc_bezier_y(float t) +{ + point ab, bc, cd, abbc, bccd, dest; + lerp (&ab, &a, &b, t); /* point between a and b */ + lerp (&bc, &b, &c, t); /* point between b and c */ + lerp (&cd, &c, &d, t); /* point between c and d */ + lerp (&abbc, &ab, &bc, t); /* point between ab and bc */ + lerp (&bccd, &bc, &cd, t); /* point between bc and cd */ + lerp (&dest, &abbc, &bccd, t); /* point on the bezier-curve */ + return dest.y; +} + +/* Function to scan the system for joysticks. + * Joystick 0 should be the system default joystick. + * It should return number of joysticks, or -1 on an unrecoverable fatal error. + */ +int VITA_JoystickInit(void) +{ + int i; + SceCtrlPortInfo myPortInfo; + + /* Setup input */ + sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE); + sceCtrlSetSamplingModeExt(SCE_CTRL_MODE_ANALOG_WIDE); + + /* Create an accurate map from analog inputs (0 to 255) + to SDL joystick positions (-32768 to 32767) */ + for (i = 0; i < 128; i++) + { + float t = (float)i/127.0f; + analog_map[i+128] = calc_bezier_y(t); + analog_map[127-i] = -1 * analog_map[i+128]; + } + + // Assume we have at least one controller, even when nothing is paired + // This way the user can jump in, pair a controller + // and control things immediately even if it is paired + // after the app has already started. + + SDL_numjoysticks = 1; + SDL_PrivateJoystickAdded(0); + // How many additional paired controllers are there? + sceCtrlGetControllerPortInfo(&myPortInfo); + + // On Vita TV, port 0 and 1 are the same controller + // and that is the first one, so start at port 2 + for (i=2; i<=4; i++) + { + if (myPortInfo.port[i]!=SCE_CTRL_TYPE_UNPAIRED) + { + SDL_PrivateJoystickAdded(SDL_numjoysticks); + SDL_numjoysticks++; + } + } + return SDL_numjoysticks; +} + +int VITA_JoystickGetCount() +{ + return SDL_numjoysticks; +} + +void VITA_JoystickDetect() +{ +} + +/* Function to perform the mapping from device index to the instance id for this index */ +SDL_JoystickID VITA_JoystickGetDeviceInstanceID(int device_index) +{ + return device_index; +} + +/* Function to get the device-dependent name of a joystick */ +const char *VITA_JoystickGetDeviceName(int index) +{ + if (index == 0) + return "PSVita Controller"; + + if (index == 1) + return "PSVita Controller"; + + if (index == 2) + return "PSVita Controller"; + + if (index == 3) + return "PSVita Controller"; + + SDL_SetError("No joystick available with that index"); + return(NULL); +} + +static int +VITA_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void +VITA_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +/* Function to open a joystick for use. + The joystick to open is specified by the device index. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int VITA_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + joystick->nbuttons = SDL_arraysize(ext_button_map); + joystick->naxes = 6; + joystick->nhats = 0; + joystick->instance_id = device_index; + + return 0; +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +static void VITA_JoystickUpdate(SDL_Joystick *joystick) +{ + int i; + unsigned int buttons; + unsigned int changed; + unsigned char lx, ly, rx, ry, lt, rt; + static unsigned int old_buttons[] = { 0, 0, 0, 0 }; + static unsigned char old_lx[] = { 0, 0, 0, 0 }; + static unsigned char old_ly[] = { 0, 0, 0, 0 }; + static unsigned char old_rx[] = { 0, 0, 0, 0 }; + static unsigned char old_ry[] = { 0, 0, 0, 0 }; + static unsigned char old_lt[] = { 0, 0, 0, 0 }; + static unsigned char old_rt[] = { 0, 0, 0, 0 }; + SceCtrlData *pad = NULL; + SDL_bool fallback = SDL_FALSE; + + int index = (int) SDL_JoystickInstanceID(joystick); + + if (index == 0) pad = &pad0; + else if (index == 1) pad = &pad1; + else if (index == 2) pad = &pad2; + else if (index == 3) pad = &pad3; + else return; + + if (index == 0) { + if (sceCtrlPeekBufferPositiveExt2(ext_port_map[index], pad, 1) < 0) { + // on vita fallback to port 0 + sceCtrlPeekBufferPositive(port_map[index], pad, 1); + fallback = SDL_TRUE; + } + } else { + sceCtrlPeekBufferPositiveExt2(ext_port_map[index], pad, 1); + } + + buttons = pad->buttons; + + lx = pad->lx; + ly = pad->ly; + rx = pad->rx; + ry = pad->ry; + lt = pad->lt; + rt = pad->rt; + + // Axes + + if (old_lx[index] != lx) { + SDL_PrivateJoystickAxis(joystick, 0, analog_map[lx]); + old_lx[index] = lx; + } + if (old_ly[index] != ly) { + SDL_PrivateJoystickAxis(joystick, 1, analog_map[ly]); + old_ly[index] = ly; + } + if (old_rx[index] != rx) { + SDL_PrivateJoystickAxis(joystick, 2, analog_map[rx]); + old_rx[index] = rx; + } + if (old_ry[index] != ry) { + SDL_PrivateJoystickAxis(joystick, 3, analog_map[ry]); + old_ry[index] = ry; + } + + if (old_lt[index] != lt) { + SDL_PrivateJoystickAxis(joystick, 4, analog_map[lt]); + old_lt[index] = lt; + } + if (old_rt[index] != rt) { + SDL_PrivateJoystickAxis(joystick, 5, analog_map[rt]); + old_rt[index] = rt; + } + + // Buttons + changed = old_buttons[index] ^ buttons; + old_buttons[index] = buttons; + + if (changed) { + if (fallback) { + for (i = 0; i < SDL_arraysize(button_map); i++) { + if (changed & button_map[i]) { + SDL_PrivateJoystickButton( + joystick, i, + (buttons & button_map[i]) ? + SDL_PRESSED : SDL_RELEASED); + } + } + } else { + for (i = 0; i < SDL_arraysize(ext_button_map); i++) { + if (changed & ext_button_map[i]) { + SDL_PrivateJoystickButton( + joystick, i, + (buttons & ext_button_map[i]) ? + SDL_PRESSED : SDL_RELEASED); + } + } + } + } +} + +/* Function to close a joystick after use */ +void VITA_JoystickClose(SDL_Joystick *joystick) +{ +} + +/* Function to perform any system-specific joystick related cleanup */ +void VITA_JoystickQuit(void) +{ +} + +SDL_JoystickGUID VITA_JoystickGetDeviceGUID( int device_index ) +{ + SDL_JoystickGUID guid; + /* the GUID is just the first 16 chars of the name for now */ + const char *name = VITA_JoystickGetDeviceName( device_index ); + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + +static int +VITA_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + int index = (int) SDL_JoystickInstanceID(joystick); + SceCtrlActuator act; + SDL_zero(act); + + act.small = high_frequency_rumble / 256; + act.large = low_frequency_rumble / 256; + sceCtrlSetActuator(ext_port_map[index], &act); + return 0; +} + +static int +VITA_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left, Uint16 right) +{ + return SDL_Unsupported(); +} + +static Uint32 +VITA_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + // always return LED and rumble supported for now + return SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE; +} + + +static int +VITA_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + int index = (int) SDL_JoystickInstanceID(joystick); + sceCtrlSetLightBar(ext_port_map[index], red, green, blue); + return 0; +} + +static int +VITA_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int +VITA_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +SDL_JoystickDriver SDL_VITA_JoystickDriver = +{ + VITA_JoystickInit, + VITA_JoystickGetCount, + VITA_JoystickDetect, + VITA_JoystickGetDeviceName, + VITA_JoystickGetDevicePlayerIndex, + VITA_JoystickSetDevicePlayerIndex, + VITA_JoystickGetDeviceGUID, + VITA_JoystickGetDeviceInstanceID, + + VITA_JoystickOpen, + + VITA_JoystickRumble, + VITA_JoystickRumbleTriggers, + + VITA_JoystickGetCapabilities, + VITA_JoystickSetLED, + VITA_JoystickSendEffect, + VITA_JoystickSetSensorsEnabled, + + VITA_JoystickUpdate, + VITA_JoystickClose, + VITA_JoystickQuit, +}; + +#endif /* SDL_JOYSTICK_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick.c b/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick.c index 6852910fb..c2f53a93f 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick.c +++ b/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,7 +34,7 @@ #define DIDFT_OPTIONAL 0x80000000 #endif -#define INPUT_QSIZE 32 /* Buffer up to 32 input messages */ +#define INPUT_QSIZE 128 /* Buffer up to 128 input messages */ #define JOY_AXIS_THRESHOLD (((SDL_JOYSTICK_AXIS_MAX)-(SDL_JOYSTICK_AXIS_MIN))/100) /* 1% motion */ #define CONVERT_MAGNITUDE(x) (((x)*10000) / 0x7FFF) @@ -45,19 +45,17 @@ extern HWND SDL_HelperWindow; /* local variables */ static SDL_bool coinitialized = SDL_FALSE; static LPDIRECTINPUT8 dinput = NULL; -static PRAWINPUTDEVICELIST SDL_RawDevList = NULL; -static UINT SDL_RawDevListCount = 0; /* Taken from Wine - Thanks! */ static DIOBJECTDATAFORMAT dfDIJoystick2[] = { - { &GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, + { &GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, { &GUID_POV, DIJOFS_POV(0), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 }, { &GUID_POV, DIJOFS_POV(1), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 }, { &GUID_POV, DIJOFS_POV(2), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 }, @@ -190,30 +188,33 @@ static DIOBJECTDATAFORMAT dfDIJoystick2[] = { { NULL, DIJOFS_BUTTON(125), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 }, { NULL, DIJOFS_BUTTON(126), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 }, { NULL, DIJOFS_BUTTON(127), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 }, - { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lVX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lVY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lVZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lVRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lVRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lVRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglVSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglVSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lAX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lAY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lAZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lARx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lARy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lARz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglASlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglASlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lFX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lFY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lFZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lFRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lFRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lFRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglFSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglFSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, + { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lVX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lVY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lVZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lVRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lVRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lVRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + /* note: dwOfs value matches Windows */ + { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lAX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lAY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lAZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lARx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lARy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lARz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + /* note: dwOfs value matches Windows */ + { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lFX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lFY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lFZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lFRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lFRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lFRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + /* note: dwOfs value matches Windows */ + { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, }; const DIDATAFORMAT SDL_c_dfDIJoystick2 = { @@ -232,210 +233,109 @@ SetDIerror(const char *function, HRESULT code) return SDL_SetError("%s() DirectX error 0x%8.8lx", function, code); } -#if 0 /* Microsoft recommended implementation, but slower than checking raw devices */ -#define COBJMACROS -#include -#include - -static const IID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0,{ 0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 } }; -static const IID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf,{ 0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 } }; - static SDL_bool -WIN_IsXInputDevice(const WCHAR *name, const GUID* pGuidProductFromDirectInput) +SDL_IsXInputDevice(Uint16 vendor_id, Uint16 product_id, const char* hidPath) { - IWbemLocator* pIWbemLocator = NULL; - IEnumWbemClassObject* pEnumDevices = NULL; - IWbemClassObject* pDevices[20]; - IWbemServices* pIWbemServices = NULL; - BSTR bstrNamespace = NULL; - BSTR bstrDeviceID = NULL; - BSTR bstrClassName = NULL; - DWORD uReturned = 0; - SDL_bool bIsXinputDevice = SDL_FALSE; - UINT iDevice = 0; - VARIANT var; - HRESULT hr; + SDL_GameControllerType type; - if (!SDL_XINPUT_Enabled()) { + /* XInput and RawInput backends will pick up XInput-compatible devices */ + if (!SDL_XINPUT_Enabled() +#ifdef SDL_JOYSTICK_RAWINPUT + && !RAWINPUT_IsEnabled() +#endif + ) { return SDL_FALSE; } - if (SDL_wcsstr(name, L" XINPUT ") != NULL) { - /* This is a duplicate interface for a controller that will show up with XInput, - e.g. Xbox One Elite Series 2 in Bluetooth mode. - */ + /* If device path contains "IG_" then its an XInput device */ + /* See: https://docs.microsoft.com/windows/win32/xinput/xinput-and-directinput */ + if (SDL_strstr(hidPath, "IG_") != NULL) { return SDL_TRUE; } - SDL_zeroa(pDevices); - - // Create WMI - hr = CoCreateInstance(&CLSID_WbemLocator, - NULL, - CLSCTX_INPROC_SERVER, - &IID_IWbemLocator, - (LPVOID*)&pIWbemLocator); - if (FAILED(hr) || pIWbemLocator == NULL) - goto LCleanup; - - bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == NULL) goto LCleanup; - bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == NULL) goto LCleanup; - bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == NULL) goto LCleanup; - - // Connect to WMI - hr = IWbemLocator_ConnectServer(pIWbemLocator, bstrNamespace, NULL, NULL, 0L, - 0L, NULL, NULL, &pIWbemServices); - if (FAILED(hr) || pIWbemServices == NULL) { - goto LCleanup; - } - - // Switch security level to IMPERSONATE. - CoSetProxyBlanket((IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, - RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); - - hr = IWbemServices_CreateInstanceEnum(pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices); - if (FAILED(hr) || pEnumDevices == NULL) - goto LCleanup; - - // Loop over all devices - for (;;) { - // Get 20 at a time - hr = IEnumWbemClassObject_Next(pEnumDevices, 10000, SDL_arraysize(pDevices), pDevices, &uReturned); - if (FAILED(hr)) { - goto LCleanup; - } - if (uReturned == 0) { - break; - } - - for (iDevice = 0; iDevice < uReturned; iDevice++) { - // For each device, get its device ID - hr = IWbemClassObject_Get(pDevices[iDevice], bstrDeviceID, 0L, &var, NULL, NULL); - if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL) { - // Check if the device ID contains "IG_". If it does, then it's an XInput device - // This information can not be found from DirectInput - if (SDL_wcsstr(var.bstrVal, L"IG_")) { - char *bstrVal = WIN_StringToUTF8(var.bstrVal); - - // If it does, then get the VID/PID from var.bstrVal - DWORD dwPid = 0, dwVid = 0, dwVidPid; - const char *strVid, *strPid; - strVid = SDL_strstr(bstrVal, "VID_"); - if (strVid && SDL_sscanf(strVid, "VID_%4X", &dwVid) != 1) - dwVid = 0; - strPid = SDL_strstr(bstrVal, "PID_"); - if (strPid && SDL_sscanf(strPid, "PID_%4X", &dwPid) != 1) - dwPid = 0; - - SDL_free(bstrVal); - - // Compare the VID/PID to the DInput device - dwVidPid = MAKELONG(dwVid, dwPid); - if (dwVidPid == pGuidProductFromDirectInput->Data1) { - bIsXinputDevice = SDL_TRUE; - goto LCleanup; - } - } - } - IWbemClassObject_Release(pDevices[iDevice]); - } - } - -LCleanup: - if (bstrNamespace) { - SysFreeString(bstrNamespace); - } - if (bstrDeviceID) { - SysFreeString(bstrDeviceID); - } - if (bstrClassName) { - SysFreeString(bstrClassName); - } - for (iDevice = 0; iDevice < SDL_arraysize(pDevices); iDevice++) { - if (pDevices[iDevice]) { - IWbemClassObject_Release(pDevices[iDevice]); - } - } - if (pEnumDevices) { - IEnumWbemClassObject_Release(pEnumDevices); - } - if (pIWbemLocator) { - IWbemLocator_Release(pIWbemLocator); - } - if (pIWbemServices) { - IWbemServices_Release(pIWbemServices); - } - - return bIsXinputDevice; -} -#endif /* 0 */ - -static SDL_bool -SDL_IsXInputDevice(const WCHAR *name, const GUID* pGuidProductFromDirectInput) -{ - UINT i; - - if (!SDL_XINPUT_Enabled()) { - return SDL_FALSE; - } - - if (SDL_wcsstr(name, L" XINPUT ") != NULL) { - /* This is a duplicate interface for a controller that will show up with XInput, - e.g. Xbox One Elite Series 2 in Bluetooth mode. - */ + type = SDL_GetJoystickGameControllerType("", vendor_id, product_id, -1, 0, 0, 0); + if (type == SDL_CONTROLLER_TYPE_XBOX360 || + type == SDL_CONTROLLER_TYPE_XBOXONE || + (vendor_id == USB_VENDOR_VALVE && product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD)) { return SDL_TRUE; } - if (SDL_memcmp(&pGuidProductFromDirectInput->Data4[2], "PIDVID", 6) == 0) { - Uint16 vendor_id = (Uint16)LOWORD(pGuidProductFromDirectInput->Data1); - Uint16 product_id = (Uint16)HIWORD(pGuidProductFromDirectInput->Data1); - SDL_GameControllerType type = SDL_GetJoystickGameControllerType("", vendor_id, product_id, -1, 0, 0, 0); - if (type == SDL_CONTROLLER_TYPE_XBOX360 || - type == SDL_CONTROLLER_TYPE_XBOXONE || - (vendor_id == 0x28DE && product_id == 0x11FF)) { - return SDL_TRUE; - } - } - - /* Go through RAWINPUT (WinXP and later) to find HID devices. */ - /* Cache this if we end up using it. */ - if (SDL_RawDevList == NULL) { - if ((GetRawInputDeviceList(NULL, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) || (!SDL_RawDevListCount)) { - return SDL_FALSE; /* oh well. */ - } - - SDL_RawDevList = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * SDL_RawDevListCount); - if (SDL_RawDevList == NULL) { - SDL_OutOfMemory(); - return SDL_FALSE; - } - - if (GetRawInputDeviceList(SDL_RawDevList, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) { - SDL_free(SDL_RawDevList); - SDL_RawDevList = NULL; - return SDL_FALSE; /* oh well. */ - } - } - - for (i = 0; i < SDL_RawDevListCount; i++) { - RID_DEVICE_INFO rdi; - char devName[MAX_PATH]; - UINT rdiSize = sizeof(rdi); - UINT nameSize = SDL_arraysize(devName); - - rdi.cbSize = sizeof(rdi); - if ((SDL_RawDevList[i].dwType == RIM_TYPEHID) && - (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) && - (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) && - (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) && - (SDL_strstr(devName, "IG_") != NULL)) { - return SDL_TRUE; - } - } - return SDL_FALSE; } +static SDL_bool +QueryDeviceName(LPDIRECTINPUTDEVICE8 device, char** device_name) +{ + DIPROPSTRING dipstr; + + if (!device || !device_name) { + return SDL_FALSE; + } + + dipstr.diph.dwSize = sizeof(dipstr); + dipstr.diph.dwHeaderSize = sizeof(dipstr.diph); + dipstr.diph.dwObj = 0; + dipstr.diph.dwHow = DIPH_DEVICE; + + if (FAILED(IDirectInputDevice8_GetProperty(device, DIPROP_PRODUCTNAME, &dipstr.diph))) { + return SDL_FALSE; + } + + *device_name = WIN_StringToUTF8(dipstr.wsz); + + return SDL_TRUE; +} + +static SDL_bool +QueryDevicePath(LPDIRECTINPUTDEVICE8 device, char** device_path) +{ + DIPROPGUIDANDPATH dippath; + + if (!device || !device_path) { + return SDL_FALSE; + } + + dippath.diph.dwSize = sizeof(dippath); + dippath.diph.dwHeaderSize = sizeof(dippath.diph); + dippath.diph.dwObj = 0; + dippath.diph.dwHow = DIPH_DEVICE; + + if (FAILED(IDirectInputDevice8_GetProperty(device, DIPROP_GUIDANDPATH, &dippath.diph))) { + return SDL_FALSE; + } + + *device_path = WIN_StringToUTF8W(dippath.wszPath); + + /* Normalize path to upper case. */ + SDL_strupr(*device_path); + + return SDL_TRUE; +} + +static SDL_bool +QueryDeviceInfo(LPDIRECTINPUTDEVICE8 device, Uint16* vendor_id, Uint16* product_id) +{ + DIPROPDWORD dipdw; + + if (!device || !vendor_id || !product_id) { + return SDL_FALSE; + } + + dipdw.diph.dwSize = sizeof(dipdw); + dipdw.diph.dwHeaderSize = sizeof(dipdw.diph); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + + if (FAILED(IDirectInputDevice8_GetProperty(device, DIPROP_VIDPID, &dipdw.diph))) { + return SDL_FALSE; + } + + *vendor_id = LOWORD(dipdw.dwData); + *product_id = HIWORD(dipdw.dwData); + + return SDL_TRUE; +} + void FreeRumbleEffectData(DIEFFECT *effect) { if (!effect) { @@ -530,88 +430,49 @@ SDL_DINPUT_JoystickInit(void) /* helper function for direct input, gets called for each connected joystick */ static BOOL CALLBACK -EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext) { - JoyStick_DeviceData *pNewJoystick; +#define CHECK(expression) { if(!(expression)) goto err; } + JoyStick_DeviceData *pNewJoystick = NULL; JoyStick_DeviceData *pPrevJoystick = NULL; - const DWORD devtype = (pdidInstance->dwDevType & 0xFF); Uint16 *guid16; Uint16 vendor = 0; Uint16 product = 0; Uint16 version = 0; - WCHAR hidPath[MAX_PATH]; - char *name; + char *hidPath = NULL; + char *name = NULL; + LPDIRECTINPUTDEVICE8 device = NULL; - if (devtype == DI8DEVTYPE_SUPPLEMENTAL) { - /* Add any supplemental devices that should be ignored here */ -#define MAKE_TABLE_ENTRY(VID, PID) ((((DWORD)PID)<<16)|VID) - static DWORD ignored_devices[] = { - MAKE_TABLE_ENTRY(0, 0) - }; -#undef MAKE_TABLE_ENTRY - unsigned int i; + /* We are only supporting HID devices. */ + CHECK((pDeviceInstance->dwDevType & DIDEVTYPE_HID) != 0); - for (i = 0; i < SDL_arraysize(ignored_devices); ++i) { - if (pdidInstance->guidProduct.Data1 == ignored_devices[i]) { - return DIENUM_CONTINUE; - } - } - } + CHECK(SUCCEEDED(IDirectInput8_CreateDevice(dinput, &pDeviceInstance->guidInstance, &device, NULL))); + CHECK(QueryDeviceName(device, &name)); + CHECK(QueryDevicePath(device, &hidPath)); + CHECK(QueryDeviceInfo(device, &vendor, &product)); - if (SDL_IsXInputDevice(pdidInstance->tszProductName, &pdidInstance->guidProduct)) { - return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */ - } + CHECK(!SDL_IsXInputDevice(vendor, product, hidPath)); - { - HRESULT result; - LPDIRECTINPUTDEVICE8 device; - LPDIRECTINPUTDEVICE8 InputDevice; - DIPROPGUIDANDPATH dipdw2; - - result = IDirectInput8_CreateDevice(dinput, &(pdidInstance->guidInstance), &device, NULL); - if (FAILED(result)) { - return DIENUM_CONTINUE; /* better luck next time? */ - } - - /* Now get the IDirectInputDevice8 interface, instead. */ - result = IDirectInputDevice8_QueryInterface(device, &IID_IDirectInputDevice8, (LPVOID *)&InputDevice); - /* We are done with this object. Use the stored one from now on. */ - IDirectInputDevice8_Release(device); - if (FAILED(result)) { - return DIENUM_CONTINUE; /* better luck next time? */ - } - dipdw2.diph.dwSize = sizeof(dipdw2); - dipdw2.diph.dwHeaderSize = sizeof(dipdw2.diph); - dipdw2.diph.dwObj = 0; // device property - dipdw2.diph.dwHow = DIPH_DEVICE; - - result = IDirectInputDevice8_GetProperty(InputDevice, DIPROP_GUIDANDPATH, &dipdw2.diph); - IDirectInputDevice8_Release(InputDevice); - if (FAILED(result)) { - return DIENUM_CONTINUE; /* better luck next time? */ - } - - /* Get device path, compare that instead of GUID, additionally update GUIDs of joysticks with matching paths, in case they're not open yet. */ - SDL_wcslcpy(hidPath, dipdw2.wszPath, SDL_arraysize(hidPath)); - } - - pNewJoystick = *(JoyStick_DeviceData **)pContext; + pNewJoystick = *(JoyStick_DeviceData**)pContext; while (pNewJoystick) { - if (SDL_wcscmp(pNewJoystick->hidPath, hidPath) == 0) { + /* update GUIDs of joysticks with matching paths, in case they're not open yet */ + if (SDL_strcmp(pNewJoystick->hidPath, hidPath) == 0) { /* if we are replacing the front of the list then update it */ - if (pNewJoystick == *(JoyStick_DeviceData **)pContext) { - *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext; - } else if (pPrevJoystick) { + if (pNewJoystick == *(JoyStick_DeviceData**)pContext) { + *(JoyStick_DeviceData**)pContext = pNewJoystick->pNext; + } + else if (pPrevJoystick) { pPrevJoystick->pNext = pNewJoystick->pNext; } /* Update with new guid/etc, if it has changed */ - SDL_memcpy(&pNewJoystick->dxdevice, pdidInstance, sizeof(DIDEVICEINSTANCE)); + SDL_memcpy(&pNewJoystick->dxdevice, pDeviceInstance, sizeof(DIDEVICEINSTANCE)); pNewJoystick->pNext = SYS_Joystick; SYS_Joystick = pNewJoystick; - return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */ + pNewJoystick = NULL; + CHECK(FALSE); } pPrevJoystick = pNewJoystick; @@ -619,31 +480,18 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) } pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData)); - if (!pNewJoystick) { - return DIENUM_CONTINUE; /* better luck next time? */ - } + CHECK(pNewJoystick); SDL_zerop(pNewJoystick); - SDL_wcslcpy(pNewJoystick->hidPath, hidPath, SDL_arraysize(pNewJoystick->hidPath)); - SDL_memcpy(&pNewJoystick->dxdevice, pdidInstance, sizeof(DIDEVICEINSTANCE)); + SDL_strlcpy(pNewJoystick->hidPath, hidPath, SDL_arraysize(pNewJoystick->hidPath)); + SDL_memcpy(&pNewJoystick->dxdevice, pDeviceInstance, sizeof(DIDEVICEINSTANCE)); SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data)); - if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) { - vendor = (Uint16)LOWORD(pdidInstance->guidProduct.Data1); - product = (Uint16)HIWORD(pdidInstance->guidProduct.Data1); - } - - name = WIN_StringToUTF8(pdidInstance->tszProductName); pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, name); - SDL_free(name); - - if (!pNewJoystick->joystickname) { - SDL_free(pNewJoystick); - return DIENUM_CONTINUE; /* better luck next time? */ - } + CHECK(pNewJoystick->joystickname); guid16 = (Uint16 *)pNewJoystick->guid.data; - if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) { + if (vendor && product) { *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB); *guid16++ = 0; *guid16++ = SDL_SwapLE16(vendor); @@ -658,127 +506,132 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4); } - if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) { - SDL_free(pNewJoystick->joystickname); - SDL_free(pNewJoystick); - return DIENUM_CONTINUE; - } + CHECK(!SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)); #ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(vendor, product, 0, pNewJoystick->joystickname)) { - /* The HIDAPI driver is taking care of this device */ - SDL_free(pNewJoystick->joystickname); - SDL_free(pNewJoystick); - return DIENUM_CONTINUE; - } + CHECK(!HIDAPI_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)); #endif #ifdef SDL_JOYSTICK_RAWINPUT - if (RAWINPUT_IsDevicePresent(vendor, product, 0, pNewJoystick->joystickname)) { - /* The RAWINPUT driver is taking care of this device */ - SDL_free(pNewJoystick); - return DIENUM_CONTINUE; - } + CHECK(!RAWINPUT_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)); #endif WINDOWS_AddJoystickDevice(pNewJoystick); + pNewJoystick = NULL; + +err: + if (pNewJoystick) { + SDL_free(pNewJoystick->joystickname); + SDL_free(pNewJoystick); + } + + SDL_free(hidPath); + SDL_free(name); + + if (device) { + IDirectInputDevice8_Release(device); + } return DIENUM_CONTINUE; /* get next device, please */ +#undef CHECK } void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext) { - IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, pContext, DIEDFL_ATTACHEDONLY); - - if (SDL_RawDevList) { - SDL_free(SDL_RawDevList); /* in case we used this in DirectInput detection */ - SDL_RawDevList = NULL; - } - SDL_RawDevListCount = 0; + IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoystickDetectCallback, pContext, DIEDFL_ATTACHEDONLY); } +/* helper function for direct input, gets called for each connected joystick */ typedef struct { Uint16 vendor; Uint16 product; - Uint16 version; SDL_bool present; -} EnumJoystickPresentData; +} Joystick_PresentData; static BOOL CALLBACK -EnumJoystickPresentCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +EnumJoystickPresentCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext) { - EnumJoystickPresentData *data = (EnumJoystickPresentData *)pContext; +#define CHECK(expression) { if(!(expression)) goto err; } + Joystick_PresentData *pData = (Joystick_PresentData *)pContext; Uint16 vendor = 0; Uint16 product = 0; - Uint16 version = 0; + LPDIRECTINPUTDEVICE8 device = NULL; + BOOL result = DIENUM_CONTINUE; - if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) { - vendor = (Uint16)LOWORD(pdidInstance->guidProduct.Data1); - product = (Uint16)HIWORD(pdidInstance->guidProduct.Data1); - if (data->vendor == vendor && data->product == product && data->version == version) { - data->present = SDL_TRUE; - return DIENUM_STOP; - } + /* We are only supporting HID devices. */ + CHECK((pDeviceInstance->dwDevType & DIDEVTYPE_HID) != 0); + + CHECK(SUCCEEDED(IDirectInput8_CreateDevice(dinput, &pDeviceInstance->guidInstance, &device, NULL))); + CHECK(QueryDeviceInfo(device, &vendor, &product)); + + if (vendor == pData->vendor && product == pData->product) { + pData->present = SDL_TRUE; + result = DIENUM_STOP; /* found it */ } - return DIENUM_CONTINUE; + +err: + if (device) { + IDirectInputDevice8_Release(device); + } + + return result; +#undef CHECK } SDL_bool -SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version) +SDL_DINPUT_JoystickPresent(Uint16 vendor_id, Uint16 product_id, Uint16 version_number) { - EnumJoystickPresentData data; + Joystick_PresentData data; if (dinput == NULL) { return SDL_FALSE; } - data.vendor = vendor; - data.product = product; - data.version = version; + data.vendor = vendor_id; + data.product = product_id; data.present = SDL_FALSE; IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoystickPresentCallback, &data, DIEDFL_ATTACHEDONLY); - return data.present; } static BOOL CALLBACK -EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) +EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE pDeviceObject, LPVOID pContext) { - SDL_Joystick *joystick = (SDL_Joystick *)pvRef; + SDL_Joystick *joystick = (SDL_Joystick *)pContext; HRESULT result; input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs]; - if (dev->dwType & DIDFT_BUTTON) { + if (pDeviceObject->dwType & DIDFT_BUTTON) { in->type = BUTTON; in->num = joystick->nbuttons; in->ofs = DIJOFS_BUTTON(in->num); joystick->nbuttons++; - } else if (dev->dwType & DIDFT_POV) { + } else if (pDeviceObject->dwType & DIDFT_POV) { in->type = HAT; in->num = joystick->nhats; in->ofs = DIJOFS_POV(in->num); joystick->nhats++; - } else if (dev->dwType & DIDFT_AXIS) { + } else if (pDeviceObject->dwType & DIDFT_AXIS) { DIPROPRANGE diprg; DIPROPDWORD dilong; in->type = AXIS; in->num = joystick->naxes; - if (!SDL_memcmp(&dev->guidType, &GUID_XAxis, sizeof(dev->guidType))) + if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_XAxis, sizeof(pDeviceObject->guidType))) in->ofs = DIJOFS_X; - else if (!SDL_memcmp(&dev->guidType, &GUID_YAxis, sizeof(dev->guidType))) + else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_YAxis, sizeof(pDeviceObject->guidType))) in->ofs = DIJOFS_Y; - else if (!SDL_memcmp(&dev->guidType, &GUID_ZAxis, sizeof(dev->guidType))) + else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_ZAxis, sizeof(pDeviceObject->guidType))) in->ofs = DIJOFS_Z; - else if (!SDL_memcmp(&dev->guidType, &GUID_RxAxis, sizeof(dev->guidType))) + else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_RxAxis, sizeof(pDeviceObject->guidType))) in->ofs = DIJOFS_RX; - else if (!SDL_memcmp(&dev->guidType, &GUID_RyAxis, sizeof(dev->guidType))) + else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_RyAxis, sizeof(pDeviceObject->guidType))) in->ofs = DIJOFS_RY; - else if (!SDL_memcmp(&dev->guidType, &GUID_RzAxis, sizeof(dev->guidType))) + else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_RzAxis, sizeof(pDeviceObject->guidType))) in->ofs = DIJOFS_RZ; - else if (!SDL_memcmp(&dev->guidType, &GUID_Slider, sizeof(dev->guidType))) { + else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_Slider, sizeof(pDeviceObject->guidType))) { in->ofs = DIJOFS_SLIDER(joystick->hwdata->NumSliders); ++joystick->hwdata->NumSliders; } else { @@ -787,7 +640,7 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) diprg.diph.dwSize = sizeof(diprg); diprg.diph.dwHeaderSize = sizeof(diprg.diph); - diprg.diph.dwObj = dev->dwType; + diprg.diph.dwObj = pDeviceObject->dwType; diprg.diph.dwHow = DIPH_BYID; diprg.lMin = SDL_JOYSTICK_AXIS_MIN; diprg.lMax = SDL_JOYSTICK_AXIS_MAX; @@ -802,7 +655,7 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) /* Set dead zone to 0. */ dilong.diph.dwSize = sizeof(dilong); dilong.diph.dwHeaderSize = sizeof(dilong.diph); - dilong.diph.dwObj = dev->dwType; + dilong.diph.dwObj = pDeviceObject->dwType; dilong.diph.dwHow = DIPH_BYID; dilong.dwData = 0; result = @@ -879,7 +732,6 @@ int SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice) { HRESULT result; - LPDIRECTINPUTDEVICE8 device; DIPROPDWORD dipdw; joystick->hwdata->buffered = SDL_TRUE; @@ -891,23 +743,13 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde result = IDirectInput8_CreateDevice(dinput, - &(joystickdevice->dxdevice.guidInstance), &device, NULL); + &joystickdevice->dxdevice.guidInstance, + &joystick->hwdata->InputDevice, + NULL); if (FAILED(result)) { return SetDIerror("IDirectInput::CreateDevice", result); } - /* Now get the IDirectInputDevice8 interface, instead. */ - result = IDirectInputDevice8_QueryInterface(device, - &IID_IDirectInputDevice8, - (LPVOID *)& joystick-> - hwdata->InputDevice); - /* We are done with this object. Use the stored one from now on. */ - IDirectInputDevice8_Release(device); - - if (FAILED(result)) { - return SetDIerror("IDirectInputDevice8::QueryInterface", result); - } - /* Acquire shared access. Exclusive access is required for forces, * though. */ result = @@ -1087,6 +929,18 @@ SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, return 0; } +Uint32 +SDL_DINPUT_JoystickGetCapabilities(SDL_Joystick * joystick) +{ + Uint32 result = 0; + + if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { + result |= SDL_JOYCAP_RUMBLE; + } + + return result; +} + static Uint8 TranslatePOV(DWORD value) { @@ -1115,60 +969,6 @@ TranslatePOV(DWORD value) return HAT_VALS[value]; } -static void -UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick) -{ - int i; - HRESULT result; - DWORD numevents; - DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE]; - - numevents = INPUT_QSIZE; - result = - IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, - sizeof(DIDEVICEOBJECTDATA), evtbuf, - &numevents, 0); - if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { - IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); - result = - IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, - sizeof(DIDEVICEOBJECTDATA), - evtbuf, &numevents, 0); - } - - /* Handle the events or punt */ - if (FAILED(result)) { - return; - } - - for (i = 0; i < (int)numevents; ++i) { - int j; - - for (j = 0; j < joystick->hwdata->NumInputs; ++j) { - const input_t *in = &joystick->hwdata->Inputs[j]; - - if (evtbuf[i].dwOfs != in->ofs) - continue; - - switch (in->type) { - case AXIS: - SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData); - break; - case BUTTON: - SDL_PrivateJoystickButton(joystick, in->num, - (Uint8)(evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED)); - break; - case HAT: - { - Uint8 pos = TranslatePOV(evtbuf[i].dwData); - SDL_PrivateJoystickHat(joystick, in->num, pos); - } - break; - } - } - } -} - /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events @@ -1243,6 +1043,67 @@ UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick) } } +static void +UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick) +{ + int i; + HRESULT result; + DWORD numevents; + DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE]; + + numevents = INPUT_QSIZE; + result = + IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, + sizeof(DIDEVICEOBJECTDATA), evtbuf, + &numevents, 0); + if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { + IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); + result = + IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, + sizeof(DIDEVICEOBJECTDATA), + evtbuf, &numevents, 0); + } + + /* Handle the events or punt */ + if (FAILED(result)) { + return; + } + + for (i = 0; i < (int)numevents; ++i) { + int j; + + for (j = 0; j < joystick->hwdata->NumInputs; ++j) { + const input_t *in = &joystick->hwdata->Inputs[j]; + + if (evtbuf[i].dwOfs != in->ofs) + continue; + + switch (in->type) { + case AXIS: + SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData); + break; + case BUTTON: + SDL_PrivateJoystickButton(joystick, in->num, + (Uint8)(evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED)); + break; + case HAT: + { + Uint8 pos = TranslatePOV(evtbuf[i].dwData); + SDL_PrivateJoystickHat(joystick, in->num, pos); + } + break; + } + } + } + + if (result == DI_BUFFEROVERFLOW) { + /* Our buffer wasn't big enough to hold all the queued events, + * so poll the device to make sure we have the complete state. + */ + UpdateDINPUTJoystickState_Polled(joystick); + } +} + void SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick) { @@ -1324,6 +1185,12 @@ SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, return SDL_Unsupported(); } +Uint32 +SDL_DINPUT_JoystickGetCapabilities(SDL_Joystick * joystick) +{ + return 0; +} + void SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick) { diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick_c.h b/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick_c.h index 2e7e7db70..d0e583465 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,6 +25,7 @@ extern void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext); extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version); extern int SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice); extern int SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); +extern Uint32 SDL_DINPUT_JoystickGetCapabilities(SDL_Joystick * joystick); extern void SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick); extern void SDL_DINPUT_JoystickClose(SDL_Joystick * joystick); extern void SDL_DINPUT_JoystickQuit(void); diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_mmjoystick.c b/Engine/lib/sdl/src/joystick/windows/SDL_mmjoystick.c deleted file mode 100644 index 197403269..000000000 --- a/Engine/lib/sdl/src/joystick/windows/SDL_mmjoystick.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifdef SDL_JOYSTICK_WINMM - -/* Win32 MultiMedia Joystick driver, contributed by Andrei de A. Formiga */ - -#include "../../core/windows/SDL_windows.h" -#include -#include - -#include "SDL_events.h" -#include "SDL_joystick.h" -#include "../SDL_sysjoystick.h" -#include "../SDL_joystick_c.h" - -#ifdef REGSTR_VAL_JOYOEMNAME -#undef REGSTR_VAL_JOYOEMNAME -#endif -#define REGSTR_VAL_JOYOEMNAME "OEMName" - -#define MAX_JOYSTICKS 16 -#define MAX_AXES 6 /* each joystick can have up to 6 axes */ -#define MAX_BUTTONS 32 /* and 32 buttons */ -#define JOY_BUTTON_FLAG(n) (1<instance_id = device_index; - joystick->hwdata = - (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); - if (joystick->hwdata == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); - - /* set hardware data */ - joystick->hwdata->id = SYS_JoystickID[index]; - for (i = 0; i < MAX_AXES; ++i) { - if ((i < 2) || (SYS_Joystick[index].wCaps & caps_flags[i - 2])) { - joystick->hwdata->transaxis[i].offset = SDL_JOYSTICK_AXIS_MIN - axis_min[i]; - joystick->hwdata->transaxis[i].scale = - (float) (SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) / (axis_max[i] - axis_min[i]); - } else { - joystick->hwdata->transaxis[i].offset = 0; - joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */ - } - } - - /* fill nbuttons, naxes, and nhats fields */ - joystick->nbuttons = SYS_Joystick[index].wNumButtons; - joystick->naxes = SYS_Joystick[index].wNumAxes; - if (SYS_Joystick[index].wCaps & JOYCAPS_HASPOV) { - joystick->nhats = 1; - } else { - joystick->nhats = 0; - } - return (0); -} - -static Uint8 -TranslatePOV(DWORD value) -{ - Uint8 pos; - - pos = SDL_HAT_CENTERED; - if (value != JOY_POVCENTERED) { - if ((value > JOY_POVLEFT) || (value < JOY_POVRIGHT)) { - pos |= SDL_HAT_UP; - } - if ((value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD)) { - pos |= SDL_HAT_RIGHT; - } - if ((value > JOY_POVRIGHT) && (value < JOY_POVLEFT)) { - pos |= SDL_HAT_DOWN; - } - if (value > JOY_POVBACKWARD) { - pos |= SDL_HAT_LEFT; - } - } - return (pos); -} - -/* Function to update the state of a joystick - called as a device poll. - * This function shouldn't update the joystick structure directly, - * but instead should call SDL_PrivateJoystick*() to deliver events - * and update joystick device state. - */ -void -SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) -{ - MMRESULT result; - int i; - DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, - JOY_RETURNR, JOY_RETURNU, JOY_RETURNV - }; - DWORD pos[MAX_AXES]; - struct _transaxis *transaxis; - int value; - JOYINFOEX joyinfo; - - joyinfo.dwSize = sizeof(joyinfo); - joyinfo.dwFlags = JOY_RETURNALL | JOY_RETURNPOVCTS; - if (!joystick->hats) { - joyinfo.dwFlags &= ~(JOY_RETURNPOV | JOY_RETURNPOVCTS); - } - result = joyGetPosEx(joystick->hwdata->id, &joyinfo); - if (result != JOYERR_NOERROR) { - SetMMerror("joyGetPosEx", result); - return; - } - - /* joystick motion events */ - pos[0] = joyinfo.dwXpos; - pos[1] = joyinfo.dwYpos; - pos[2] = joyinfo.dwZpos; - pos[3] = joyinfo.dwRpos; - pos[4] = joyinfo.dwUpos; - pos[5] = joyinfo.dwVpos; - - transaxis = joystick->hwdata->transaxis; - for (i = 0; i < joystick->naxes; i++) { - if (joyinfo.dwFlags & flags[i]) { - value = (int) (((float) pos[i] + transaxis[i].offset) * transaxis[i].scale); - SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value); - } - } - - /* joystick button events */ - if (joyinfo.dwFlags & JOY_RETURNBUTTONS) { - for (i = 0; i < joystick->nbuttons; ++i) { - if (joyinfo.dwButtons & JOY_BUTTON_FLAG(i)) { - SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_PRESSED); - } else { - SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_RELEASED); - } - } - } - - /* joystick hat events */ - if (joyinfo.dwFlags & JOY_RETURNPOV) { - SDL_PrivateJoystickHat(joystick, 0, TranslatePOV(joyinfo.dwPOV)); - } -} - -/* Function to close a joystick after use */ -void -SDL_SYS_JoystickClose(SDL_Joystick * joystick) -{ - SDL_free(joystick->hwdata); -} - -/* Function to perform any system-specific joystick related cleanup */ -void -SDL_SYS_JoystickQuit(void) -{ - int i; - for (i = 0; i < MAX_JOYSTICKS; i++) { - SDL_free(SYS_JoystickName[i]); - SYS_JoystickName[i] = NULL; - } -} - -SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) -{ - SDL_JoystickGUID guid; - /* the GUID is just the first 16 chars of the name for now */ - const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); - SDL_zero( guid ); - SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); - return guid; -} - -SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) -{ - SDL_JoystickGUID guid; - /* the GUID is just the first 16 chars of the name for now */ - const char *name = joystick->name; - SDL_zero( guid ); - SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); - return guid; -} - - -/* implementation functions */ -void -SetMMerror(char *function, int code) -{ - static char *error; - static char errbuf[1024]; - - errbuf[0] = 0; - switch (code) { - case MMSYSERR_NODRIVER: - error = "Joystick driver not present"; - break; - - case MMSYSERR_INVALPARAM: - case JOYERR_PARMS: - error = "Invalid parameter(s)"; - break; - - case MMSYSERR_BADDEVICEID: - error = "Bad device ID"; - break; - - case JOYERR_UNPLUGGED: - error = "Joystick not attached"; - break; - - case JOYERR_NOCANDO: - error = "Can't capture joystick input"; - break; - - default: - SDL_snprintf(errbuf, SDL_arraysize(errbuf), - "%s: Unknown Multimedia system error: 0x%x", - function, code); - break; - } - - if (!errbuf[0]) { - SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, - error); - } - SDL_SetError("%s", errbuf); -} - -#endif /* SDL_JOYSTICK_WINMM */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick.c b/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick.c index 0af76b023..32b637827 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick.c +++ b/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 2019 Sam Lantinga + Copyright (C) 2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -40,12 +40,15 @@ #include "SDL_timer.h" #include "../usb_ids.h" #include "../SDL_sysjoystick.h" +#include "../controller_type.h" #include "../../core/windows/SDL_windows.h" #include "../../core/windows/SDL_hid.h" #include "../hidapi/SDL_hidapijoystick_c.h" +#ifdef HAVE_XINPUT_H #define SDL_JOYSTICK_RAWINPUT_XINPUT -#ifdef SDL_WINDOWS10_SDK +#endif +#ifdef HAVE_WINDOWS_GAMING_INPUT_H #define SDL_JOYSTICK_RAWINPUT_WGI #endif @@ -64,6 +67,12 @@ typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState; #if defined(SDL_JOYSTICK_RAWINPUT_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT_WGI) #define SDL_JOYSTICK_RAWINPUT_MATCHING #define SDL_JOYSTICK_RAWINPUT_MATCH_AXES +#define SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS +#define SDL_JOYSTICK_RAWINPUT_MATCH_COUNT 6 // stick + trigger axes +#else +#define SDL_JOYSTICK_RAWINPUT_MATCH_COUNT 4 // stick axes +#endif #endif /*#define DEBUG_RAWINPUT*/ @@ -100,6 +109,7 @@ typedef struct _SDL_RAWINPUT_Device Uint16 version; SDL_JoystickGUID guid; SDL_bool is_xinput; + SDL_bool is_xboxone; PHIDP_PREPARSED_DATA preparsed_data; HANDLE hDevice; @@ -112,6 +122,7 @@ typedef struct _SDL_RAWINPUT_Device struct joystick_hwdata { SDL_bool is_xinput; + SDL_bool is_xboxone; PHIDP_PREPARSED_DATA preparsed_data; ULONG max_data_length; HIDP_DATA *data; @@ -123,7 +134,7 @@ struct joystick_hwdata USHORT trigger_hack_index; #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING - Uint32 match_state; /* Low 16 bits for button states, high 16 for 4 4bit axes */ + Uint64 match_state; /* Lowest 16 bits for button states, higher 24 for 6 4bit axes */ Uint32 last_state_packet; #endif @@ -168,7 +179,7 @@ static struct { typedef struct WindowsMatchState { #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES - SHORT match_axes[4]; + SHORT match_axes[SDL_JOYSTICK_RAWINPUT_MATCH_COUNT]; #endif #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT WORD xinput_buttons; @@ -179,13 +190,13 @@ typedef struct WindowsMatchState { SDL_bool any_data; } WindowsMatchState; -static void RAWINPUT_FillMatchState(WindowsMatchState *state, Uint32 match_state) +static void RAWINPUT_FillMatchState(WindowsMatchState *state, Uint64 match_state) { #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES int ii; #endif - state->any_data = SDL_FALSE; + SDL_bool any_axes_data = SDL_FALSE; #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES /* SHORT state->match_axes[4] = { (match_state & 0x000F0000) >> 4, @@ -194,12 +205,18 @@ static void RAWINPUT_FillMatchState(WindowsMatchState *state, Uint32 match_state (match_state & 0xF0000000) >> 16, }; */ for (ii = 0; ii < 4; ii++) { - state->match_axes[ii] = (match_state & (0x000F0000 << (ii * 4))) >> (4 + ii * 4); - if ((Uint32)(state->match_axes[ii] + 0x1000) > 0x2000) { /* match_state bit is not 0xF, 0x1, or 0x2 */ - state->any_data = SDL_TRUE; - } + state->match_axes[ii] = (SHORT)((match_state & (0x000F0000ull << (ii * 4))) >> (4 + ii * 4)); + any_axes_data |= ((Uint32)(state->match_axes[ii] + 0x1000) > 0x2000); /* match_state bit is not 0xF, 0x1, or 0x2 */ } #endif /* SDL_JOYSTICK_RAWINPUT_MATCH_AXES */ +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS + for (; ii < SDL_JOYSTICK_RAWINPUT_MATCH_COUNT; ii++) { + state->match_axes[ii] = (SHORT)((match_state & (0x000F0000ull << (ii * 4))) >> (4 + ii * 4)); + any_axes_data |= (state->match_axes[ii] != SDL_MIN_SINT16); + } +#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS */ + + state->any_data = any_axes_data; #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT /* Match axes by checking if the distance between the high 4 bits of axis and the 4 bits from match_state is 1 or less */ @@ -215,9 +232,16 @@ static void RAWINPUT_FillMatchState(WindowsMatchState *state, Uint32 match_state SDL_abs((Sint8)((gamepad.sThumbRX & 0xF000) >> 8) - ((match_state & 0x0F000000) >> 20)) <= 0x10 && \ SDL_abs((Sint8)((~gamepad.sThumbRY & 0xF000) >> 8) - ((match_state & 0xF0000000) >> 24)) <= 0x10) */ + /* Can only match trigger values if a single trigger has a value. */ +#define XInputTriggersMatch(gamepad) ( \ + ((state->match_axes[4] == SDL_MIN_SINT16) && (state->match_axes[5] == SDL_MIN_SINT16)) || \ + ((gamepad.bLeftTrigger != 0) && (gamepad.bRightTrigger != 0)) || \ + ((Uint32)((((int)gamepad.bLeftTrigger * 257) - 32768) - state->match_axes[4]) <= 0x2fff) || \ + ((Uint32)((((int)gamepad.bRightTrigger * 257) - 32768) - state->match_axes[5]) <= 0x2fff)) + state->xinput_buttons = /* Bitwise map .RLDUWVQTS.KYXBA -> YXBA..WVQTKSRLDU */ - match_state << 12 | (match_state & 0x0780) >> 1 | (match_state & 0x0010) << 1 | (match_state & 0x0040) >> 2 | (match_state & 0x7800) >> 11; + (WORD)(match_state << 12 | (match_state & 0x0780) >> 1 | (match_state & 0x0010) << 1 | (match_state & 0x0040) >> 2 | (match_state & 0x7800) >> 11); /* Explicit ((match_state & (1<match_axes[2] + 0x1000) <= 0x2fff && \ (Uint16)((~(Sint16)(gamepad.RightThumbstickY * SDL_MAX_SINT16) & 0xF000) - state->match_axes[3] + 0x1000) <= 0x2fff) +#define WindowsGamingInputTriggersMatch(gamepad) ( \ + ((state->match_axes[4] == SDL_MIN_SINT16) && (state->match_axes[5] == SDL_MIN_SINT16)) || \ + ((gamepad.LeftTrigger == 0.0f) && (gamepad.RightTrigger == 0.0f)) || \ + ((Uint16)((((int)(gamepad.LeftTrigger * SDL_MAX_UINT16)) - 32768) - state->match_axes[4]) <= 0x2fff) || \ + ((Uint16)((((int)(gamepad.RightTrigger * SDL_MAX_UINT16)) - 32768) - state->match_axes[5]) <= 0x2fff)) state->wgi_buttons = /* Bitwise map .RLD UWVQ TS.K YXBA -> ..QT WVRL DUYX BAKS */ @@ -349,6 +378,9 @@ RAWINPUT_XInputSlotMatches(const WindowsMatchState *state, Uint8 slot_idx) if ((xinput_buttons & ~XINPUT_GAMEPAD_GUIDE) == state->xinput_buttons #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES && XInputAxesMatch(xinput_state[slot_idx].state.Gamepad) +#endif +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS + && XInputTriggersMatch(xinput_state[slot_idx].state.Gamepad) #endif ) { return SDL_TRUE; @@ -447,12 +479,12 @@ RAWINPUT_UpdateWindowsGamingInput() wgi_state.dirty = SDL_FALSE; if (wgi_state.need_device_list_update) { + HRESULT hr; + __FIVectorView_1_Windows__CGaming__CInput__CGamepad *gamepads; wgi_state.need_device_list_update = SDL_FALSE; for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) { wgi_state.per_gamepad[ii]->connected = SDL_FALSE; } - HRESULT hr; - __FIVectorView_1_Windows__CGaming__CInput__CGamepad *gamepads; hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_get_Gamepads(wgi_state.gamepad_statics, &gamepads); if (SUCCEEDED(hr)) { @@ -477,13 +509,15 @@ RAWINPUT_UpdateWindowsGamingInput() } if (!found) { /* New device, add it */ + WindowsGamingInputGamepadState *gamepad_state; + wgi_state.per_gamepad_count++; wgi_state.per_gamepad = SDL_realloc(wgi_state.per_gamepad, sizeof(wgi_state.per_gamepad[0]) * wgi_state.per_gamepad_count); if (!wgi_state.per_gamepad) { SDL_OutOfMemory(); return; } - WindowsGamingInputGamepadState *gamepad_state = SDL_calloc(1, sizeof(*gamepad_state)); + gamepad_state = SDL_calloc(1, sizeof(*gamepad_state)); if (!gamepad_state) { SDL_OutOfMemory(); return; @@ -529,6 +563,10 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) wgi_state.need_device_list_update = SDL_TRUE; wgi_state.ref_count++; if (!wgi_state.initialized) { + static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } }; + HRESULT hr; + HMODULE hModule; + /* I think this takes care of RoInitialize() in a way that is compatible with the rest of SDL */ if (FAILED(WIN_CoInitialize())) { return; @@ -536,9 +574,7 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) wgi_state.initialized = SDL_TRUE; wgi_state.dirty = SDL_TRUE; - static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } }; - HRESULT hr; - HMODULE hModule = LoadLibraryA("combase.dll"); + hModule = LoadLibraryA("combase.dll"); if (hModule != NULL) { typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string); typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory); @@ -546,13 +582,13 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference"); RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory"); if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) { - LPTSTR pNamespace = L"Windows.Gaming.Input.Gamepad"; + PCWSTR pNamespace = L"Windows.Gaming.Input.Gamepad"; HSTRING_HEADER hNamespaceStringHeader; HSTRING hNamespaceString; hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); if (SUCCEEDED(hr)) { - RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, &wgi_state.gamepad_statics); + RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, (void **)&wgi_state.gamepad_statics); } } FreeLibrary(hModule); @@ -561,12 +597,16 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) } static SDL_bool -RAWINPUT_WindowsGamingInputSlotMatches(const WindowsMatchState *state, WindowsGamingInputGamepadState *slot) +RAWINPUT_WindowsGamingInputSlotMatches(const WindowsMatchState *state, WindowsGamingInputGamepadState *slot, SDL_bool xinput_correlated) { Uint32 wgi_buttons = slot->state.Buttons; if ((wgi_buttons & 0x3FFF) == state->wgi_buttons #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES && WindowsGamingInputAxesMatch(slot->state) +#endif +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS + // Don't try to match WGI triggers if getting values from XInput + && (xinput_correlated || WindowsGamingInputTriggersMatch(slot->state)) #endif ) { return SDL_TRUE; @@ -575,14 +615,14 @@ RAWINPUT_WindowsGamingInputSlotMatches(const WindowsMatchState *state, WindowsGa } static SDL_bool -RAWINPUT_GuessWindowsGamingInputSlot(const WindowsMatchState *state, Uint8 *correlation_id, WindowsGamingInputGamepadState **slot) +RAWINPUT_GuessWindowsGamingInputSlot(const WindowsMatchState *state, Uint8 *correlation_id, WindowsGamingInputGamepadState **slot, SDL_bool xinput_correlated) { int match_count, user_index; match_count = 0; for (user_index = 0; user_index < wgi_state.per_gamepad_count; ++user_index) { WindowsGamingInputGamepadState *gamepad_state = wgi_state.per_gamepad[user_index]; - if (RAWINPUT_WindowsGamingInputSlotMatches(state, gamepad_state)) { + if (RAWINPUT_WindowsGamingInputSlotMatches(state, gamepad_state, xinput_correlated)) { ++match_count; *slot = gamepad_state; /* Incrementing correlation_id for any match, as negative evidence for others being correlated */ @@ -670,7 +710,7 @@ RAWINPUT_DeviceFromHandle(HANDLE hDevice) static void RAWINPUT_AddDevice(HANDLE hDevice) { -#define CHECK(exp) { if(!(exp)) goto err; } +#define CHECK(expression) { if(!(expression)) goto err; } SDL_RAWINPUT_Device *device = NULL; SDL_RAWINPUT_Device *curr, *last; RID_DEVICE_INFO rdi; @@ -703,6 +743,7 @@ RAWINPUT_AddDevice(HANDLE hDevice) device->product_id = (Uint16)rdi.hid.dwProductId; device->version = (Uint16)rdi.hid.dwVersionNumber; device->is_xinput = SDL_TRUE; + device->is_xboxone = GuessControllerType(device->vendor_id, device->product_id) == k_eControllerType_XBoxOneController; { const Uint16 vendor = device->vendor_id; @@ -733,10 +774,10 @@ RAWINPUT_AddDevice(HANDLE hDevice) WCHAR string[128]; if (SDL_HidD_GetManufacturerString(hFile, string, sizeof(string))) { - manufacturer_string = WIN_StringToUTF8(string); + manufacturer_string = WIN_StringToUTF8W(string); } if (SDL_HidD_GetProductString(hFile, string, sizeof(string))) { - product_string = WIN_StringToUTF8(string); + product_string = WIN_StringToUTF8W(string); } device->name = SDL_CreateJoystickName(device->vendor_id, device->product_id, manufacturer_string, product_string); @@ -880,16 +921,19 @@ RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, co return SDL_TRUE; } - /* The Xbox 360 wireless controller shows up as product 0 in WGI */ + /* The Xbox 360 wireless controller shows up as product 0 in WGI. + Try to match it to a Raw Input device via name or known product ID. */ if (vendor_id == device->vendor_id && product_id == 0 && - name && SDL_strstr(device->name, name) != NULL) { + ((name && SDL_strstr(device->name, name) != NULL) || + (device->vendor_id == USB_VENDOR_MICROSOFT && + device->product_id == USB_PRODUCT_XBOX360_XUSB_CONTROLLER))) { return SDL_TRUE; } /* The Xbox One controller shows up as a hardcoded raw input VID/PID */ if (name && SDL_strcmp(name, "Xbox One Game Controller") == 0 && device->vendor_id == USB_VENDOR_MICROSOFT && - device->product_id == USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER) { + device->product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER) { return SDL_TRUE; } @@ -1040,7 +1084,7 @@ RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) /* We'll try to get guide button and trigger axes from XInput */ #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT xinput_device_change = SDL_TRUE; - ctx->xinput_enabled = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_CORRELATE_XINPUT, SDL_TRUE); + ctx->xinput_enabled = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT, SDL_TRUE); if (ctx->xinput_enabled && (WIN_LoadXInputDLL() < 0 || !XINPUTGETSTATE)) { ctx->xinput_enabled = SDL_FALSE; } @@ -1052,6 +1096,7 @@ RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) } ctx->is_xinput = device->is_xinput; + ctx->is_xboxone = device->is_xboxone; ctx->preparsed_data = device->preparsed_data; ctx->max_data_length = SDL_HidP_MaxDataListLength(HidP_Input, ctx->preparsed_data); ctx->data = (HIDP_DATA *)SDL_malloc(ctx->max_data_length * sizeof(*ctx->data)); @@ -1216,9 +1261,8 @@ RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uin { #if defined(SDL_JOYSTICK_RAWINPUT_WGI) || defined(SDL_JOYSTICK_RAWINPUT_XINPUT) RAWINPUT_DeviceContext *ctx = joystick->hwdata; -#endif - SDL_bool rumbled = SDL_FALSE; +#endif #ifdef SDL_JOYSTICK_RAWINPUT_WGI if (!rumbled && ctx->wgi_correlated) { @@ -1251,6 +1295,13 @@ RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uin } #endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */ + if (!rumbled) { +#if defined(SDL_JOYSTICK_RAWINPUT_WGI) || defined(SDL_JOYSTICK_RAWINPUT_XINPUT) + return SDL_SetError("Controller isn't correlated yet, try hitting a button first"); +#else + return SDL_Unsupported(); +#endif + } return 0; } @@ -1267,7 +1318,7 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint gamepad_state->vibration.RightTrigger = (DOUBLE)right_rumble / SDL_MAX_UINT16; hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration); if (!SUCCEEDED(hr)) { - return SDL_SetError("Setting vibration failed: 0x%x\n", hr); + return SDL_SetError("Setting vibration failed: 0x%lx\n", hr); } } return 0; @@ -1276,10 +1327,29 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint #endif } -static SDL_bool -RAWINPUT_JoystickHasLED(SDL_Joystick *joystick) +static Uint32 +RAWINPUT_JoystickGetCapabilities(SDL_Joystick *joystick) { - return SDL_FALSE; + RAWINPUT_DeviceContext *ctx = joystick->hwdata; + Uint32 result = 0; + +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + if (ctx->is_xinput) { + result |= SDL_JOYCAP_RUMBLE; + } +#endif + +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + if (ctx->is_xinput) { + result |= SDL_JOYCAP_RUMBLE; + + if (ctx->is_xboxone) { + result |= SDL_JOYCAP_RUMBLE_TRIGGERS; + } + } +#endif + + return result; } static int @@ -1288,6 +1358,12 @@ RAWINPUT_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 bl return SDL_Unsupported(); } +static int +RAWINPUT_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + static int RAWINPUT_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) { @@ -1348,12 +1424,13 @@ RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int size) (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT), (1 << SDL_CONTROLLER_BUTTON_DPAD_UP) | (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT), }; - Uint32 match_state = ctx->match_state; + Uint64 match_state = ctx->match_state; /* Update match_state with button bit, then fall through */ -#define SDL_PrivateJoystickButton(joystick, button, state) if (button < SDL_arraysize(button_map)) { if (state) match_state |= 1 << button_map[button]; else match_state &= ~(1 << button_map[button]); } SDL_PrivateJoystickButton(joystick, button, state) +#define SDL_PrivateJoystickButton(joystick, button, state) if (button < SDL_arraysize(button_map)) { Uint64 button_bit = 1ull << button_map[button]; match_state = (match_state & ~button_bit) | (button_bit * (state)); } SDL_PrivateJoystickButton(joystick, button, state) #ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES /* Grab high 4 bits of value, then fall through */ -#define SDL_PrivateJoystickAxis(joystick, axis, value) if (axis < 4) match_state = (match_state & ~(0xF << (4 * axis + 16))) | ((value) & 0xF000) << (4 * axis + 4); SDL_PrivateJoystickAxis(joystick, axis, value) +#define AddAxisToMatchState(axis, value) { match_state = (match_state & ~(0xFull << (4 * axis + 16))) | ((value) & 0xF000ull) << (4 * axis + 4); } +#define SDL_PrivateJoystickAxis(joystick, axis, value) if (axis < 4) AddAxisToMatchState(axis, value); SDL_PrivateJoystickAxis(joystick, axis, value) #endif #endif /* SDL_JOYSTICK_RAWINPUT_MATCHING */ @@ -1418,8 +1495,14 @@ RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int size) #undef SDL_PrivateJoystickAxis #endif +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS +#define AddTriggerToMatchState(axis, value) { int match_axis = axis + SDL_JOYSTICK_RAWINPUT_MATCH_COUNT - joystick->naxes; AddAxisToMatchState(match_axis, value); } +#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS */ + if (ctx->trigger_hack) { SDL_bool has_trigger_data = SDL_FALSE; + int left_trigger = joystick->naxes - 2; + int right_trigger = joystick->naxes - 1; #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT /* Prefer XInput over WindowsGamingInput, it continues to provide data in the background */ @@ -1434,28 +1517,36 @@ RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int size) } #endif /* SDL_JOYSTICK_RAWINPUT_WGI */ - if (!has_trigger_data) { +#ifndef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS + if (!has_trigger_data) +#endif + { HIDP_DATA *item = GetData(ctx->trigger_hack_index, ctx->data, data_length); if (item) { - int left_trigger = joystick->naxes - 2; - int right_trigger = joystick->naxes - 1; Sint16 value = (int)(Uint16)item->RawValue - 0x8000; - if (value < 0) { - value = -value * 2 - 32769; - SDL_PrivateJoystickAxis(joystick, left_trigger, SDL_MIN_SINT16); - SDL_PrivateJoystickAxis(joystick, right_trigger, value); - } else if (value > 0) { - value = value * 2 - 32767; - SDL_PrivateJoystickAxis(joystick, left_trigger, value); - SDL_PrivateJoystickAxis(joystick, right_trigger, SDL_MIN_SINT16); - } else { - SDL_PrivateJoystickAxis(joystick, left_trigger, SDL_MIN_SINT16); - SDL_PrivateJoystickAxis(joystick, right_trigger, SDL_MIN_SINT16); + Sint16 left_value = (value > 0) ? (value * 2 - 32767) : SDL_MIN_SINT16; + Sint16 right_value = (value < 0) ? (-value * 2 - 32769) : SDL_MIN_SINT16; + +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS + AddTriggerToMatchState(left_trigger, left_value); + AddTriggerToMatchState(right_trigger, right_value); + if (!has_trigger_data) +#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS */ + { + SDL_PrivateJoystickAxis(joystick, left_trigger, left_value); + SDL_PrivateJoystickAxis(joystick, right_trigger, right_value); } } } } +#ifdef AddAxisToMatchState +#undef AddAxisToMatchState +#endif +#ifdef AddTriggerToMatchState +#undef AddTriggerToMatchState +#endif + #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING if (ctx->is_xinput) { ctx->match_state = match_state; @@ -1481,17 +1572,19 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick) #ifdef SDL_JOYSTICK_RAWINPUT_WGI /* Parallel logic to WINDOWS_XINPUT below */ RAWINPUT_UpdateWindowsGamingInput(); - if (ctx->wgi_correlated) { + if (ctx->wgi_correlated && + !joystick->low_frequency_rumble && !joystick->high_frequency_rumble && + !joystick->left_trigger_rumble && !joystick->right_trigger_rumble) { /* We have been previously correlated, ensure we are still matching, see comments in XINPUT section */ - if (RAWINPUT_WindowsGamingInputSlotMatches(&match_state_xinput, ctx->wgi_slot)) { + if (RAWINPUT_WindowsGamingInputSlotMatches(&match_state_xinput, ctx->wgi_slot, ctx->xinput_correlated)) { ctx->wgi_uncorrelate_count = 0; } else { ++ctx->wgi_uncorrelate_count; /* Only un-correlate if this is consistent over multiple Update() calls - the timing of polling/event pumping can easily cause this to uncorrelate for a frame. 2 seemed reliable in my testing, but - let's set it to 3 to be safe. An incorrect un-correlation will simply result in lower precision + let's set it to 5 to be safe. An incorrect un-correlation will simply result in lower precision triggers for a frame. */ - if (ctx->wgi_uncorrelate_count >= 3) { + if (ctx->wgi_uncorrelate_count >= 5) { #ifdef DEBUG_RAWINPUT SDL_Log("UN-Correlated joystick %d to WindowsGamingInput device #%d\n", joystick->instance_id, ctx->wgi_slot); #endif @@ -1511,8 +1604,8 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick) SDL_bool new_correlation_count = 0; if (RAWINPUT_MissingWindowsGamingInputSlot()) { Uint8 correlation_id; - WindowsGamingInputGamepadState *slot_idx; - if (RAWINPUT_GuessWindowsGamingInputSlot(&match_state_xinput, &correlation_id, &slot_idx)) { + WindowsGamingInputGamepadState *slot_idx = NULL; + if (RAWINPUT_GuessWindowsGamingInputSlot(&match_state_xinput, &correlation_id, &slot_idx, ctx->xinput_correlated)) { /* we match exactly one WindowsGamingInput device */ /* Probably can do without wgi_correlation_count, just check and clear wgi_slot to NULL, unless we need even more frames to be sure. */ @@ -1559,7 +1652,8 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick) /* Parallel logic to WINDOWS_GAMING_INPUT above */ if (ctx->xinput_enabled) { RAWINPUT_UpdateXInput(); - if (ctx->xinput_correlated) { + if (ctx->xinput_correlated && + !joystick->low_frequency_rumble && !joystick->high_frequency_rumble) { /* We have been previously correlated, ensure we are still matching */ /* This is required to deal with two (mostly) un-preventable mis-correlation situations: A) Since the HID data stream does not provide an initial state (but polling XInput does), if we open @@ -1582,9 +1676,9 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick) ++ctx->xinput_uncorrelate_count; /* Only un-correlate if this is consistent over multiple Update() calls - the timing of polling/event pumping can easily cause this to uncorrelate for a frame. 2 seemed reliable in my testing, but - let's set it to 3 to be safe. An incorrect un-correlation will simply result in lower precision + let's set it to 5 to be safe. An incorrect un-correlation will simply result in lower precision triggers for a frame. */ - if (ctx->xinput_uncorrelate_count >= 3) { + if (ctx->xinput_uncorrelate_count >= 5) { #ifdef DEBUG_RAWINPUT SDL_Log("UN-Correlated joystick %d to XInput device #%d\n", joystick->instance_id, ctx->xinput_slot); #endif @@ -1819,9 +1913,9 @@ RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { LRESULT result = -1; - SDL_LockMutex(SDL_RAWINPUT_mutex); - if (SDL_RAWINPUT_inited) { + SDL_LockMutex(SDL_RAWINPUT_mutex); + switch (msg) { case WM_INPUT_DEVICE_CHANGE: { @@ -1865,9 +1959,9 @@ RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) result = 0; break; } - } - SDL_UnlockMutex(SDL_RAWINPUT_mutex); + SDL_UnlockMutex(SDL_RAWINPUT_mutex); + } if (result >= 0) { return result; @@ -1882,8 +1976,6 @@ RAWINPUT_JoystickQuit(void) return; } - SDL_LockMutex(SDL_RAWINPUT_mutex); - while (SDL_RAWINPUT_devices) { RAWINPUT_DelDevice(SDL_RAWINPUT_devices, SDL_FALSE); } @@ -1894,7 +1986,6 @@ RAWINPUT_JoystickQuit(void) SDL_RAWINPUT_inited = SDL_FALSE; - SDL_UnlockMutex(SDL_RAWINPUT_mutex); SDL_DestroyMutex(SDL_RAWINPUT_mutex); SDL_RAWINPUT_mutex = NULL; } @@ -1918,8 +2009,9 @@ SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver = RAWINPUT_JoystickOpen, RAWINPUT_JoystickRumble, RAWINPUT_JoystickRumbleTriggers, - RAWINPUT_JoystickHasLED, + RAWINPUT_JoystickGetCapabilities, RAWINPUT_JoystickSetLED, + RAWINPUT_JoystickSendEffect, RAWINPUT_JoystickSetSensorsEnabled, RAWINPUT_JoystickUpdate, RAWINPUT_JoystickClose, diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick_c.h b/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick_c.h index 14f77fb35..a5d8143e0 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2019 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_windows_gaming_input.c b/Engine/lib/sdl/src/joystick/windows/SDL_windows_gaming_input.c index 29a9c7682..a731dad63 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_windows_gaming_input.c +++ b/Engine/lib/sdl/src/joystick/windows/SDL_windows_gaming_input.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,6 +31,8 @@ #include "../../core/windows/SDL_windows.h" #define COBJMACROS #include "windows.gaming.input.h" +#include +#include struct joystick_hwdata @@ -77,15 +79,15 @@ static const IID IID_IGameController = { 0x1BAF6522, 0x5F64, 0x42C5, { 0x82, 0x6 static const IID IID_IGameControllerBatteryInfo = { 0xDCECC681, 0x3963, 0x4DA6, { 0x95, 0x5D, 0x55, 0x3F, 0x3B, 0x6F, 0x61, 0x61 } }; static const IID IID_IArcadeStickStatics = { 0x5C37B8C8, 0x37B1, 0x4AD8, { 0x94, 0x58, 0x20, 0x0F, 0x1A, 0x30, 0x01, 0x8E } }; static const IID IID_IArcadeStickStatics2 = { 0x52B5D744, 0xBB86, 0x445A, { 0xB5, 0x9C, 0x59, 0x6F, 0x0E, 0x2A, 0x49, 0xDF } }; -static const IID IID_IArcadeStick = { 0xB14A539D, 0xBEFB, 0x4C81, { 0x80, 0x51, 0x15, 0xEC, 0xF3, 0xB1, 0x30, 0x36 } }; +/*static const IID IID_IArcadeStick = { 0xB14A539D, 0xBEFB, 0x4C81, { 0x80, 0x51, 0x15, 0xEC, 0xF3, 0xB1, 0x30, 0x36 } };*/ static const IID IID_IFlightStickStatics = { 0x5514924A, 0xFECC, 0x435E, { 0x83, 0xDC, 0x5C, 0xEC, 0x8A, 0x18, 0xA5, 0x20 } }; -static const IID IID_IFlightStick = { 0xB4A2C01C, 0xB83B, 0x4459, { 0xA1, 0xA9, 0x97, 0xB0, 0x3C, 0x33, 0xDA, 0x7C } }; +/*static const IID IID_IFlightStick = { 0xB4A2C01C, 0xB83B, 0x4459, { 0xA1, 0xA9, 0x97, 0xB0, 0x3C, 0x33, 0xDA, 0x7C } };*/ static const IID IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } }; static const IID IID_IGamepadStatics2 = { 0x42676DC5, 0x0856, 0x47C4, { 0x92, 0x13, 0xB3, 0x95, 0x50, 0x4C, 0x3A, 0x3C } }; -static const IID IID_IGamepad = { 0xBC7BB43C, 0x0A69, 0x3903, { 0x9E, 0x9D, 0xA5, 0x0F, 0x86, 0xA4, 0x5D, 0xE5 } }; +/*static const IID IID_IGamepad = { 0xBC7BB43C, 0x0A69, 0x3903, { 0x9E, 0x9D, 0xA5, 0x0F, 0x86, 0xA4, 0x5D, 0xE5 } };*/ static const IID IID_IRacingWheelStatics = { 0x3AC12CD5, 0x581B, 0x4936, { 0x9F, 0x94, 0x69, 0xF1, 0xE6, 0x51, 0x4C, 0x7D } }; static const IID IID_IRacingWheelStatics2 = { 0xE666BCAA, 0xEDFD, 0x4323, { 0xA9, 0xF6, 0x3C, 0x38, 0x40, 0x48, 0xD1, 0xED } }; -static const IID IID_IRacingWheel = { 0xF546656F, 0xE106, 0x4C82, { 0xA9, 0x0F, 0x55, 0x40, 0x12, 0x90, 0x4B, 0x85 } }; +/*static const IID IID_IRacingWheel = { 0xF546656F, 0xE106, 0x4C82, { 0xA9, 0x0F, 0x55, 0x40, 0x12, 0x90, 0x4B, 0x85 } };*/ extern SDL_bool SDL_XINPUT_Enabled(void); extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version); @@ -93,11 +95,17 @@ extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 static SDL_bool SDL_IsXInputDevice(Uint16 vendor, Uint16 product) { +#ifdef SDL_JOYSTICK_XINPUT PRAWINPUTDEVICELIST raw_devices = NULL; UINT i, raw_device_count = 0; LONG vidpid = MAKELONG(vendor, product); - if (!SDL_XINPUT_Enabled()) { + /* XInput and RawInput backends will pick up XInput-compatible devices */ + if (!SDL_XINPUT_Enabled() +#ifdef SDL_JOYSTICK_RAWINPUT + && !RAWINPUT_IsEnabled() +#endif + ) { return SDL_FALSE; } @@ -123,17 +131,70 @@ SDL_IsXInputDevice(Uint16 vendor, Uint16 product) char devName[MAX_PATH]; UINT rdiSize = sizeof(rdi); UINT nameSize = SDL_arraysize(devName); + DEVINST devNode; + char devVidPidString[32]; + int j; rdi.cbSize = sizeof(rdi); - if ((raw_devices[i].dwType == RIM_TYPEHID) && - (GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) && - (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == vidpid) && - (GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) && - (SDL_strstr(devName, "IG_") != NULL)) { + + if ((raw_devices[i].dwType != RIM_TYPEHID) || + (GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) == ((UINT)-1)) || + (GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) == ((UINT)-1)) || + (SDL_strstr(devName, "IG_") == NULL)) { + /* Skip non-XInput devices */ + continue; + } + + /* First check for a simple VID/PID match. This will work for Xbox 360 controllers. */ + if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == vidpid) { + SDL_free(raw_devices); return SDL_TRUE; } + + /* For Xbox One controllers, Microsoft doesn't propagate the VID/PID down to the HID stack. + * We'll have to walk the device tree upwards searching for a match for our VID/PID. */ + + /* Make sure the device interface string is something we know how to parse */ + /* Example: \\?\HID#VID_045E&PID_02FF&IG_00#9&2c203035&2&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} */ + if ((SDL_strstr(devName, "\\\\?\\") != devName) || (SDL_strstr(devName, "#{") == NULL)) { + continue; + } + + /* Unescape the backslashes in the string and terminate before the GUID portion */ + for (j = 0; devName[j] != '\0'; j++) { + if (devName[j] == '#') { + if (devName[j + 1] == '{') { + devName[j] = '\0'; + break; + } else { + devName[j] = '\\'; + } + } + } + + /* We'll be left with a string like this: \\?\HID\VID_045E&PID_02FF&IG_00\9&2c203035&2&0000 + * Simply skip the \\?\ prefix and we'll have a properly formed device instance ID */ + if (CM_Locate_DevNodeA(&devNode, &devName[4], CM_LOCATE_DEVNODE_NORMAL) != CR_SUCCESS) { + continue; + } + + SDL_snprintf(devVidPidString, sizeof(devVidPidString), "VID_%04X&PID_%04X", vendor, product); + + while (CM_Get_Parent(&devNode, devNode, 0) == CR_SUCCESS) { + char deviceId[MAX_DEVICE_ID_LEN]; + + if ((CM_Get_Device_IDA(devNode, deviceId, SDL_arraysize(deviceId), 0) == CR_SUCCESS) && + (SDL_strstr(deviceId, devVidPidString) != NULL)) { + /* The VID/PID matched a parent device */ + SDL_free(raw_devices); + return SDL_TRUE; + } + } } + SDL_free(raw_devices); +#endif /* SDL_JOYSTICK_XINPUT */ + return SDL_FALSE; } @@ -166,7 +227,13 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde HRESULT hr; __x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller = NULL; - hr = IUnknown_QueryInterface((IUnknown *)e, &IID_IRawGameController, (void **)&controller); + /* We can get delayed calls to InvokeAdded() after WGI_JoystickQuit(). Do nothing if WGI is deinitialized. + * FIXME: Can we tell if WGI has been quit and reinitialized prior to a delayed callback? */ + if (wgi.statics == NULL) { + return S_OK; + } + + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(e, &IID_IRawGameController, (void **)&controller); if (SUCCEEDED(hr)) { char *name = NULL; SDL_JoystickGUID guid; @@ -184,28 +251,42 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IRawGameController2, (void **)&controller2); if (SUCCEEDED(hr)) { + typedef PCWSTR (WINAPI *WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 *length); + typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string); + + WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = NULL; + WindowsDeleteString_t WindowsDeleteStringFunc = NULL; +#ifdef __WINRT__ + WindowsGetStringRawBufferFunc = WindowsGetStringRawBuffer; + WindowsDeleteStringFunc = WindowsDeleteString; +#else HMODULE hModule = LoadLibraryA("combase.dll"); if (hModule != NULL) { - typedef PCWSTR (WINAPI *WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 *length); - typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string); - - WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer"); - WindowsDeleteString_t WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString"); - if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) { - HSTRING hString; - hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_get_DisplayName(controller2, &hString); - if (SUCCEEDED(hr)) { - PCWSTR string = WindowsGetStringRawBufferFunc(hString, NULL); - if (string) { - name = WIN_StringToUTF8(string); - } - WindowsDeleteStringFunc(hString); + WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer"); + WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString"); + } +#endif /* __WINRT__ */ + if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) { + HSTRING hString; + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_get_DisplayName(controller2, &hString); + if (SUCCEEDED(hr)) { + PCWSTR string = WindowsGetStringRawBufferFunc(hString, NULL); + if (string) { + name = WIN_StringToUTF8W(string); } + WindowsDeleteStringFunc(hString); } + } +#ifndef __WINRT__ + if (hModule != NULL) { FreeLibrary(hModule); } +#endif __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2); } + if (!name) { + name = SDL_strdup(""); + } hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IGameController, (void **)&gamecontroller); if (SUCCEEDED(hr)) { @@ -307,7 +388,7 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeRemo HRESULT hr; __x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller = NULL; - hr = IUnknown_QueryInterface((IUnknown *)e, &IID_IRawGameController, (void **)&controller); + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(e, &IID_IRawGameController, (void **)&controller); if (SUCCEEDED(hr)) { int i; @@ -358,87 +439,120 @@ static __FIEventHandler_1_Windows__CGaming__CInput__CRawGameController controlle static int WGI_JoystickInit(void) { + typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string); + typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory); + + WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL; + RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL; +#ifndef __WINRT__ + HMODULE hModule; +#endif + HRESULT hr; + if (FAILED(WIN_CoInitialize())) { return SDL_SetError("CoInitialize() failed"); } - HRESULT hr; - HMODULE hModule = LoadLibraryA("combase.dll"); +#ifdef __WINRT__ + WindowsCreateStringReferenceFunc = WindowsCreateStringReference; + RoGetActivationFactoryFunc = RoGetActivationFactory; +#else + hModule = LoadLibraryA("combase.dll"); if (hModule != NULL) { - typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string); - typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string); - typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory); + WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference"); + RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory"); + } +#endif /* __WINRT__ */ + if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) { + PCWSTR pNamespace; + HSTRING_HEADER hNamespaceStringHeader; + HSTRING hNamespaceString; - WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference"); - RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory"); - if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) { - LPTSTR pNamespace; - HSTRING_HEADER hNamespaceStringHeader; - HSTRING hNamespaceString; - - pNamespace = L"Windows.Gaming.Input.RawGameController"; - hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); - if (SUCCEEDED(hr)) { - hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, &wgi.statics); - if (!SUCCEEDED(hr)) { - SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%x", hr); - } - } - - pNamespace = L"Windows.Gaming.Input.ArcadeStick"; - hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); - if (SUCCEEDED(hr)) { - hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, &wgi.arcade_stick_statics); - if (SUCCEEDED(hr)) { - __x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics_QueryInterface(wgi.arcade_stick_statics, &IID_IArcadeStickStatics2, &wgi.arcade_stick_statics2); - } else { - SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%x", hr); - } - } - - pNamespace = L"Windows.Gaming.Input.FlightStick"; - hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); - if (SUCCEEDED(hr)) { - hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, &wgi.flight_stick_statics); - if (!SUCCEEDED(hr)) { - SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%x", hr); - } - } - - pNamespace = L"Windows.Gaming.Input.Gamepad"; - hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); - if (SUCCEEDED(hr)) { - hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, &wgi.gamepad_statics); - if (SUCCEEDED(hr)) { - __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_QueryInterface(wgi.gamepad_statics, &IID_IGamepadStatics2, &wgi.gamepad_statics2); - } else { - SDL_SetError("Couldn't find IGamepadStatics: 0x%x", hr); - } - } - - pNamespace = L"Windows.Gaming.Input.RacingWheel"; - hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); - if (SUCCEEDED(hr)) { - hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, &wgi.racing_wheel_statics); - if (SUCCEEDED(hr)) { - __x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics_QueryInterface(wgi.racing_wheel_statics, &IID_IRacingWheelStatics2, &wgi.racing_wheel_statics2); - } else { - SDL_SetError("Couldn't find IRacingWheelStatics: 0x%x", hr); - } + pNamespace = L"Windows.Gaming.Input.RawGameController"; + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); + if (SUCCEEDED(hr)) { + hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, (void **)&wgi.statics); + if (!SUCCEEDED(hr)) { + SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%lx", hr); } } + + pNamespace = L"Windows.Gaming.Input.ArcadeStick"; + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); + if (SUCCEEDED(hr)) { + hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, (void **)&wgi.arcade_stick_statics); + if (SUCCEEDED(hr)) { + __x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics_QueryInterface(wgi.arcade_stick_statics, &IID_IArcadeStickStatics2, (void **)&wgi.arcade_stick_statics2); + } else { + SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%lx", hr); + } + } + + pNamespace = L"Windows.Gaming.Input.FlightStick"; + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); + if (SUCCEEDED(hr)) { + hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, (void **)&wgi.flight_stick_statics); + if (!SUCCEEDED(hr)) { + SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%lx", hr); + } + } + + pNamespace = L"Windows.Gaming.Input.Gamepad"; + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); + if (SUCCEEDED(hr)) { + hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, (void **)&wgi.gamepad_statics); + if (SUCCEEDED(hr)) { + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_QueryInterface(wgi.gamepad_statics, &IID_IGamepadStatics2, (void **)&wgi.gamepad_statics2); + } else { + SDL_SetError("Couldn't find IGamepadStatics: 0x%lx", hr); + } + } + + pNamespace = L"Windows.Gaming.Input.RacingWheel"; + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); + if (SUCCEEDED(hr)) { + hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, (void **)&wgi.racing_wheel_statics); + if (SUCCEEDED(hr)) { + __x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics_QueryInterface(wgi.racing_wheel_statics, &IID_IRacingWheelStatics2, (void **)&wgi.racing_wheel_statics2); + } else { + SDL_SetError("Couldn't find IRacingWheelStatics: 0x%lx", hr); + } + } + } +#ifndef __WINRT__ + if (hModule != NULL) { FreeLibrary(hModule); } +#endif if (wgi.statics) { + __FIVectorView_1_Windows__CGaming__CInput__CRawGameController *controllers; + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_add_RawGameControllerAdded(wgi.statics, &controller_added, &wgi.controller_added_token); if (!SUCCEEDED(hr)) { - SDL_SetError("add_RawGameControllerAdded() failed: 0x%x\n", hr); + SDL_SetError("add_RawGameControllerAdded() failed: 0x%lx\n", hr); } hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_add_RawGameControllerRemoved(wgi.statics, &controller_removed, &wgi.controller_removed_token); if (!SUCCEEDED(hr)) { - SDL_SetError("add_RawGameControllerRemoved() failed: 0x%x\n", hr); + SDL_SetError("add_RawGameControllerRemoved() failed: 0x%lx\n", hr); + } + + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_get_RawGameControllers(wgi.statics, &controllers); + if (SUCCEEDED(hr)) { + unsigned i, count = 0; + + hr = __FIVectorView_1_Windows__CGaming__CInput__CRawGameController_get_Size(controllers, &count); + if (SUCCEEDED(hr)) { + for (i = 0; i < count; ++i) { + __x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller = NULL; + + hr = __FIVectorView_1_Windows__CGaming__CInput__CRawGameController_GetAt(controllers, i, &controller); + if (SUCCEEDED(hr) && controller) { + IEventHandler_CRawGameControllerVtbl_InvokeAdded(&controller_added, NULL, controller); + } + } + } } } @@ -486,7 +600,7 @@ WGI_JoystickGetDeviceInstanceID(int device_index) } static int -WGI_JoystickOpen(SDL_Joystick * joystick, int device_index) +WGI_JoystickOpen(SDL_Joystick *joystick, int device_index) { WindowsGamingInputControllerState *state = &wgi.controllers[device_index]; struct joystick_hwdata *hwdata; @@ -558,7 +672,7 @@ WGI_JoystickOpen(SDL_Joystick * joystick, int device_index) } static int -WGI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +WGI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { struct joystick_hwdata *hwdata = joystick->hwdata; @@ -571,7 +685,7 @@ WGI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 if (SUCCEEDED(hr)) { return 0; } else { - return SDL_SetError("Setting vibration failed: 0x%x\n", hr); + return SDL_SetError("Setting vibration failed: 0x%lx\n", hr); } } else { return SDL_Unsupported(); @@ -579,7 +693,7 @@ WGI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 } static int -WGI_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble) +WGI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { struct joystick_hwdata *hwdata = joystick->hwdata; @@ -592,21 +706,34 @@ WGI_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 r if (SUCCEEDED(hr)) { return 0; } else { - return SDL_SetError("Setting vibration failed: 0x%x\n", hr); + return SDL_SetError("Setting vibration failed: 0x%lx\n", hr); } } else { return SDL_Unsupported(); } } -static SDL_bool -WGI_JoystickHasLED(SDL_Joystick * joystick) +static Uint32 +WGI_JoystickGetCapabilities(SDL_Joystick *joystick) { - return SDL_FALSE; + struct joystick_hwdata *hwdata = joystick->hwdata; + + if (hwdata->gamepad) { + /* FIXME: Can WGI even tell us if trigger rumble is supported? */ + return SDL_JOYCAP_RUMBLE | SDL_JOYCAP_RUMBLE_TRIGGERS; + } else { + return 0; + } } static int -WGI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) +WGI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int +WGI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) { return SDL_Unsupported(); } @@ -643,7 +770,7 @@ ConvertHatValue(__x_ABI_CWindows_CGaming_CInput_CGameControllerSwitchPosition va } static void -WGI_JoystickUpdate(SDL_Joystick * joystick) +WGI_JoystickUpdate(SDL_Joystick *joystick) { struct joystick_hwdata *hwdata = joystick->hwdata; HRESULT hr; @@ -677,7 +804,7 @@ WGI_JoystickUpdate(SDL_Joystick * joystick) } static void -WGI_JoystickClose(SDL_Joystick * joystick) +WGI_JoystickClose(SDL_Joystick *joystick) { struct joystick_hwdata *hwdata = joystick->hwdata; @@ -704,7 +831,7 @@ WGI_JoystickQuit(void) { if (wgi.statics) { while (wgi.controller_count > 0) { - IEventHandler_CRawGameControllerVtbl_InvokeRemoved(&controller_removed, NULL, (__x_ABI_CWindows_CGaming_CInput_CIRawGameController *)wgi.controllers[wgi.controller_count - 1].controller); + IEventHandler_CRawGameControllerVtbl_InvokeRemoved(&controller_removed, NULL, wgi.controllers[wgi.controller_count - 1].controller); } if (wgi.controllers) { SDL_free(wgi.controllers); @@ -760,8 +887,9 @@ SDL_JoystickDriver SDL_WGI_JoystickDriver = WGI_JoystickOpen, WGI_JoystickRumble, WGI_JoystickRumbleTriggers, - WGI_JoystickHasLED, + WGI_JoystickGetCapabilities, WGI_JoystickSetLED, + WGI_JoystickSendEffect, WGI_JoystickSetSensorsEnabled, WGI_JoystickUpdate, WGI_JoystickClose, diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick.c b/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick.c index 5722f50da..7dae16d9f 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick.c +++ b/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -59,6 +59,77 @@ #define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000 #endif +/* CM_Register_Notification definitions */ + +#define CR_SUCCESS (0x00000000) + +DECLARE_HANDLE(HCMNOTIFICATION); +typedef HCMNOTIFICATION* PHCMNOTIFICATION; + +typedef enum _CM_NOTIFY_FILTER_TYPE { + CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE = 0, + CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE, + CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE, + CM_NOTIFY_FILTER_TYPE_MAX +} CM_NOTIFY_FILTER_TYPE, * PCM_NOTIFY_FILTER_TYPE; + +typedef struct _CM_NOTIFY_FILTER { + DWORD cbSize; + DWORD Flags; + CM_NOTIFY_FILTER_TYPE FilterType; + DWORD Reserved; + union { + struct { + GUID ClassGuid; + } DeviceInterface; + struct { + HANDLE hTarget; + } DeviceHandle; + struct { + WCHAR InstanceId[200]; + } DeviceInstance; + } u; +} CM_NOTIFY_FILTER, * PCM_NOTIFY_FILTER; + +typedef enum _CM_NOTIFY_ACTION { + CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL = 0, + CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL, + CM_NOTIFY_ACTION_DEVICEQUERYREMOVE, + CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED, + CM_NOTIFY_ACTION_DEVICEREMOVEPENDING, + CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE, + CM_NOTIFY_ACTION_DEVICECUSTOMEVENT, + CM_NOTIFY_ACTION_DEVICEINSTANCEENUMERATED, + CM_NOTIFY_ACTION_DEVICEINSTANCESTARTED, + CM_NOTIFY_ACTION_DEVICEINSTANCEREMOVED, + CM_NOTIFY_ACTION_MAX +} CM_NOTIFY_ACTION, * PCM_NOTIFY_ACTION; + +typedef struct _CM_NOTIFY_EVENT_DATA { + CM_NOTIFY_FILTER_TYPE FilterType; + DWORD Reserved; + union { + struct { + GUID ClassGuid; + WCHAR SymbolicLink[ANYSIZE_ARRAY]; + } DeviceInterface; + struct { + GUID EventGuid; + LONG NameOffset; + DWORD DataSize; + BYTE Data[ANYSIZE_ARRAY]; + } DeviceHandle; + struct { + WCHAR InstanceId[ANYSIZE_ARRAY]; + } DeviceInstance; + } u; +} CM_NOTIFY_EVENT_DATA, * PCM_NOTIFY_EVENT_DATA; + +typedef DWORD (CALLBACK *PCM_NOTIFY_CALLBACK)(HCMNOTIFICATION hNotify, PVOID Context, CM_NOTIFY_ACTION Action, PCM_NOTIFY_EVENT_DATA EventData, DWORD EventDataSize); + +typedef DWORD (WINAPI *CM_Register_NotificationFunc)(PCM_NOTIFY_FILTER pFilter, PVOID pContext, PCM_NOTIFY_CALLBACK pCallback, PHCMNOTIFICATION pNotifyContext); +typedef DWORD (WINAPI *CM_Unregister_NotificationFunc)(HCMNOTIFICATION NotifyContext); + /* local variables */ static SDL_bool s_bJoystickThread = SDL_FALSE; static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE; @@ -66,35 +137,64 @@ static SDL_cond *s_condJoystickThread = NULL; static SDL_mutex *s_mutexJoyStickEnum = NULL; static SDL_Thread *s_joystickThread = NULL; static SDL_bool s_bJoystickThreadQuit = SDL_FALSE; +static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } }; JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */ -#ifdef __WINRT__ +#ifndef __WINRT__ +static HMODULE cfgmgr32_lib_handle; +static CM_Register_NotificationFunc CM_Register_Notification; +static CM_Unregister_NotificationFunc CM_Unregister_Notification; +static HCMNOTIFICATION s_DeviceNotificationFuncHandle; -typedef struct -{ - int unused; -} SDL_DeviceNotificationData; - -static void -SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data) +static DWORD CALLBACK +SDL_DeviceNotificationFunc(HCMNOTIFICATION hNotify, PVOID context, CM_NOTIFY_ACTION action, PCM_NOTIFY_EVENT_DATA eventData, DWORD event_data_size) { + if (action == CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL || + action == CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL) { + s_bWindowsDeviceChanged = SDL_TRUE; + } + return ERROR_SUCCESS; } -static int -SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data) +static void +SDL_CleanupDeviceNotificationFunc(void) { - return 0; + if (cfgmgr32_lib_handle) { + if (s_DeviceNotificationFuncHandle) { + CM_Unregister_Notification(s_DeviceNotificationFuncHandle); + s_DeviceNotificationFuncHandle = NULL; + } + + FreeLibrary(cfgmgr32_lib_handle); + cfgmgr32_lib_handle = NULL; + } } static SDL_bool -SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex) +SDL_CreateDeviceNotificationFunc(void) { + cfgmgr32_lib_handle = LoadLibraryA("cfgmgr32.dll"); + if (cfgmgr32_lib_handle) { + CM_Register_Notification = (CM_Register_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Register_Notification"); + CM_Unregister_Notification = (CM_Unregister_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Unregister_Notification"); + if (CM_Register_Notification && CM_Unregister_Notification) { + CM_NOTIFY_FILTER notify_filter; + + SDL_zero(notify_filter); + notify_filter.cbSize = sizeof(notify_filter); + notify_filter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE; + notify_filter.u.DeviceInterface.ClassGuid = GUID_DEVINTERFACE_HID; + if (CM_Register_Notification(¬ify_filter, NULL, SDL_DeviceNotificationFunc, &s_DeviceNotificationFuncHandle) == CR_SUCCESS) { + return SDL_TRUE; + } + } + } + + SDL_CleanupDeviceNotificationFunc(); return SDL_FALSE; } -#else /* !__WINRT__ */ - typedef struct { HRESULT coinitialized; @@ -164,14 +264,13 @@ static int SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data) { DEV_BROADCAST_DEVICEINTERFACE dbh; - GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } }; SDL_zerop(data); data->coinitialized = WIN_CoInitialize(); data->wincl.hInstance = GetModuleHandle(NULL); - data->wincl.lpszClassName = L"Message"; + data->wincl.lpszClassName = TEXT("Message"); data->wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc; /* This function is called by windows */ data->wincl.cbSize = sizeof (WNDCLASSEX); @@ -181,7 +280,7 @@ SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data) return -1; } - data->messageWindow = (HWND)CreateWindowEx(0, L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); + data->messageWindow = (HWND)CreateWindowEx(0, TEXT("Message"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); if (!data->messageWindow) { WIN_SetError("Failed to create message window for joystick autodetect"); SDL_CleanupDeviceNotification(data); @@ -228,8 +327,6 @@ SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex return (lastret != -1) ? SDL_TRUE : SDL_FALSE; } -#endif /* __WINRT__ */ - static SDL_DeviceNotificationData s_notification_data; /* Function/thread to scan the system for joysticks. */ @@ -310,9 +407,7 @@ SDL_StopJoystickThread(void) s_bJoystickThreadQuit = SDL_TRUE; SDL_CondBroadcast(s_condJoystickThread); /* signal the joystick thread to quit */ SDL_UnlockMutex(s_mutexJoyStickEnum); -#ifndef __WINRT__ PostThreadMessage(SDL_GetThreadID(s_joystickThread), WM_QUIT, 0, 0); -#endif SDL_WaitThread(s_joystickThread, NULL); /* wait for it to bugger off */ SDL_DestroyCond(s_condJoystickThread); @@ -324,6 +419,8 @@ SDL_StopJoystickThread(void) s_joystickThread = NULL; } +#endif /* !__WINRT__ */ + void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device) { device->send_add_event = SDL_TRUE; @@ -356,6 +453,9 @@ WINDOWS_JoystickInit(void) WINDOWS_JoystickDetect(); +#ifndef __WINRT__ + SDL_CreateDeviceNotificationFunc(); + s_bJoystickThread = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_THREAD, SDL_FALSE); if (s_bJoystickThread) { if (SDL_StartJoystickThread() < 0) { @@ -366,6 +466,7 @@ WINDOWS_JoystickInit(void) return -1; } } +#endif return 0; } @@ -419,11 +520,11 @@ WINDOWS_JoystickDetect(void) if (pCurList->bXInputDevice) { #if SDL_HAPTIC_XINPUT - SDL_XINPUT_MaybeRemoveDevice(pCurList->XInputUserId); + SDL_XINPUT_HapticMaybeRemoveDevice(pCurList->XInputUserId); #endif } else { #if SDL_HAPTIC_DINPUT - SDL_DINPUT_MaybeRemoveDevice(&pCurList->dxdevice); + SDL_DINPUT_HapticMaybeRemoveDevice(&pCurList->dxdevice); #endif } @@ -439,11 +540,11 @@ WINDOWS_JoystickDetect(void) if (pCurList->send_add_event) { if (pCurList->bXInputDevice) { #if SDL_HAPTIC_XINPUT - SDL_XINPUT_MaybeAddDevice(pCurList->XInputUserId); + SDL_XINPUT_HapticMaybeAddDevice(pCurList->XInputUserId); #endif } else { #if SDL_HAPTIC_DINPUT - SDL_DINPUT_MaybeAddDevice(&pCurList->dxdevice); + SDL_DINPUT_HapticMaybeAddDevice(&pCurList->dxdevice); #endif } @@ -516,7 +617,7 @@ WINDOWS_JoystickGetDeviceInstanceID(int device_index) It returns 0, or -1 if there is an error. */ static int -WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index) +WINDOWS_JoystickOpen(SDL_Joystick *joystick, int device_index) { JoyStick_DeviceData *device = SYS_Joystick; int index; @@ -542,7 +643,7 @@ WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index) } static int -WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +WINDOWS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { if (joystick->hwdata->bXInputDevice) { return SDL_XINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble); @@ -552,19 +653,29 @@ WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uin } static int -WINDOWS_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble) +WINDOWS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { return SDL_Unsupported(); } -static SDL_bool -WINDOWS_JoystickHasLED(SDL_Joystick * joystick) +static Uint32 +WINDOWS_JoystickGetCapabilities(SDL_Joystick *joystick) { - return SDL_FALSE; + if (joystick->hwdata->bXInputDevice) { + return SDL_XINPUT_JoystickGetCapabilities(joystick); + } else { + return SDL_DINPUT_JoystickGetCapabilities(joystick); + } } static int -WINDOWS_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) +WINDOWS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int +WINDOWS_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) { return SDL_Unsupported(); } @@ -576,7 +687,7 @@ WINDOWS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) } static void -WINDOWS_JoystickUpdate(SDL_Joystick * joystick) +WINDOWS_JoystickUpdate(SDL_Joystick *joystick) { if (!joystick->hwdata) { return; @@ -591,7 +702,7 @@ WINDOWS_JoystickUpdate(SDL_Joystick * joystick) /* Function to close a joystick after use */ static void -WINDOWS_JoystickClose(SDL_Joystick * joystick) +WINDOWS_JoystickClose(SDL_Joystick *joystick) { if (joystick->hwdata->bXInputDevice) { SDL_XINPUT_JoystickClose(joystick); @@ -616,12 +727,16 @@ WINDOWS_JoystickQuit(void) } SYS_Joystick = NULL; +#ifndef __WINRT__ if (s_bJoystickThread) { SDL_StopJoystickThread(); } else { SDL_CleanupDeviceNotification(&s_notification_data); } + SDL_CleanupDeviceNotificationFunc(); +#endif + SDL_DINPUT_JoystickQuit(); SDL_XINPUT_JoystickQuit(); @@ -647,8 +762,9 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver = WINDOWS_JoystickOpen, WINDOWS_JoystickRumble, WINDOWS_JoystickRumbleTriggers, - WINDOWS_JoystickHasLED, + WINDOWS_JoystickGetCapabilities, WINDOWS_JoystickSetLED, + WINDOWS_JoystickSendEffect, WINDOWS_JoystickSetSensorsEnabled, WINDOWS_JoystickUpdate, WINDOWS_JoystickClose, @@ -656,6 +772,13 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver = WINDOWS_JoystickGetGamepadMapping }; +#else + +#if SDL_JOYSTICK_RAWINPUT +/* The RAWINPUT driver needs the device notification setup above */ +#error SDL_JOYSTICK_RAWINPUT requires SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT +#endif + #endif /* SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick_c.h b/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick_c.h index 4dbc87649..1b9625385 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,7 +37,7 @@ typedef struct JoyStick_DeviceData BYTE SubType; Uint8 XInputUserId; DIDEVICEINSTANCE dxdevice; - WCHAR hidPath[MAX_PATH]; + char hidPath[MAX_PATH]; struct JoyStick_DeviceData *pNext; } JoyStick_DeviceData; diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick.c b/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick.c index 30025428d..f3ab8a0b2 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick.c +++ b/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -201,9 +201,20 @@ GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion) * userid, but we'll record it so we'll at least be consistent * when the raw device list changes. */ - *pVID = (Uint16)rdi.hid.dwVendorId; - *pPID = (Uint16)rdi.hid.dwProductId; - *pVersion = (Uint16)rdi.hid.dwVersionNumber; + if (rdi.hid.dwVendorId == USB_VENDOR_VALVE && + rdi.hid.dwProductId == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD) { + /* Steam encodes the real device in the path */ + int realVID = rdi.hid.dwVendorId; + int realPID = rdi.hid.dwProductId; + SDL_sscanf(devName, "\\\\.\\pipe\\HID#VID_045E&PID_028E&IG_00#%x&%x&", &realVID, &realPID); + *pVID = (Uint16)realVID; + *pPID = (Uint16)realPID; + *pVersion = 0; + } else { + *pVID = (Uint16)rdi.hid.dwVendorId; + *pPID = (Uint16)rdi.hid.dwProductId; + *pVersion = (Uint16)rdi.hid.dwVersionNumber; + } if (s_arrXInputDevicePath[userid]) { SDL_free(s_arrXInputDevicePath[userid]); } @@ -503,6 +514,12 @@ SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, return 0; } +Uint32 +SDL_XINPUT_JoystickGetCapabilities(SDL_Joystick * joystick) +{ + return SDL_JOYCAP_RUMBLE; +} + void SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick) { @@ -579,6 +596,12 @@ SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, return SDL_Unsupported(); } +Uint32 +SDL_XINPUT_JoystickGetCapabilities(SDL_Joystick * joystick) +{ + return 0; +} + void SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick) { diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick_c.h b/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick_c.h index 9afd1607e..c0a0600d7 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,6 +27,7 @@ extern int SDL_XINPUT_JoystickInit(void); extern void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext); extern int SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice); extern int SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); +extern Uint32 SDL_XINPUT_JoystickGetCapabilities(SDL_Joystick * joystick); extern void SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick); extern void SDL_XINPUT_JoystickClose(SDL_Joystick * joystick); extern void SDL_XINPUT_JoystickQuit(void); diff --git a/Engine/lib/sdl/src/libm/math_libm.h b/Engine/lib/sdl/src/libm/math_libm.h index 2f26e3ad3..0bce44f73 100644 --- a/Engine/lib/sdl/src/libm/math_libm.h +++ b/Engine/lib/sdl/src/libm/math_libm.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/libm/math_private.h b/Engine/lib/sdl/src/libm/math_private.h index 02535559a..4a30a521a 100644 --- a/Engine/lib/sdl/src/libm/math_private.h +++ b/Engine/lib/sdl/src/libm/math_private.h @@ -27,7 +27,7 @@ #define libm_hidden_def(x) #define strong_alias(x, y) -#ifndef __HAIKU__ /* already defined in a system header. */ +#if !defined(__HAIKU__) && !defined(__PSP__) /* already defined in a system header. */ typedef unsigned int u_int32_t; #endif diff --git a/Engine/lib/sdl/src/loadso/dlopen/SDL_sysloadso.c b/Engine/lib/sdl/src/loadso/dlopen/SDL_sysloadso.c index d4bebe14c..e5abe85db 100644 --- a/Engine/lib/sdl/src/loadso/dlopen/SDL_sysloadso.c +++ b/Engine/lib/sdl/src/loadso/dlopen/SDL_sysloadso.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/loadso/dummy/SDL_sysloadso.c b/Engine/lib/sdl/src/loadso/dummy/SDL_sysloadso.c index 559118db7..da45a842f 100644 --- a/Engine/lib/sdl/src/loadso/dummy/SDL_sysloadso.c +++ b/Engine/lib/sdl/src/loadso/dummy/SDL_sysloadso.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/loadso/os2/SDL_sysloadso.c b/Engine/lib/sdl/src/loadso/os2/SDL_sysloadso.c index ca9d2fd24..2b96848ac 100644 --- a/Engine/lib/sdl/src/loadso/os2/SDL_sysloadso.c +++ b/Engine/lib/sdl/src/loadso/os2/SDL_sysloadso.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -41,7 +41,7 @@ SDL_LoadObject(const char *sofile) PSZ pszModName; if (!sofile) { - SDL_SetError("NULL sofile"); + SDL_InvalidParamError("sofile"); return NULL; } diff --git a/Engine/lib/sdl/src/loadso/windows/SDL_sysloadso.c b/Engine/lib/sdl/src/loadso/windows/SDL_sysloadso.c index 3513718de..d3c84042b 100644 --- a/Engine/lib/sdl/src/loadso/windows/SDL_sysloadso.c +++ b/Engine/lib/sdl/src/loadso/windows/SDL_sysloadso.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -36,7 +36,7 @@ SDL_LoadObject(const char *sofile) LPTSTR tstr; if (!sofile) { - SDL_SetError("NULL sofile"); + SDL_InvalidParamError("sofile"); return NULL; } tstr = WIN_UTF8ToString(sofile); diff --git a/Engine/lib/sdl/src/locale/SDL_locale.c b/Engine/lib/sdl/src/locale/SDL_locale.c index c7e5b1011..5aaf87284 100644 --- a/Engine/lib/sdl/src/locale/SDL_locale.c +++ b/Engine/lib/sdl/src/locale/SDL_locale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -45,7 +45,7 @@ build_locales_from_csv_string(char *csv) num_locales++; /* one more for terminator */ - slen = ((size_t) (ptr - csv)) + 1; /* strlen(csv) + 1 */ + slen = ((size_t) (ptr - csv)) + 1; /* SDL_strlen(csv) + 1 */ alloclen = slen + (num_locales * sizeof (SDL_Locale)); loc = retval = (SDL_Locale *) SDL_calloc(1, alloclen); diff --git a/Engine/lib/sdl/src/locale/SDL_syslocale.h b/Engine/lib/sdl/src/locale/SDL_syslocale.h index 887baa063..826313971 100644 --- a/Engine/lib/sdl/src/locale/SDL_syslocale.h +++ b/Engine/lib/sdl/src/locale/SDL_syslocale.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/locale/android/SDL_syslocale.c b/Engine/lib/sdl/src/locale/android/SDL_syslocale.c index 6cfb9751b..ed969b8dd 100644 --- a/Engine/lib/sdl/src/locale/android/SDL_syslocale.c +++ b/Engine/lib/sdl/src/locale/android/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/locale/dummy/SDL_syslocale.c b/Engine/lib/sdl/src/locale/dummy/SDL_syslocale.c index ad554daef..e5ed1ad13 100644 --- a/Engine/lib/sdl/src/locale/dummy/SDL_syslocale.c +++ b/Engine/lib/sdl/src/locale/dummy/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/locale/emscripten/SDL_syslocale.c b/Engine/lib/sdl/src/locale/emscripten/SDL_syslocale.c index 7004258e0..98d3c0353 100644 --- a/Engine/lib/sdl/src/locale/emscripten/SDL_syslocale.c +++ b/Engine/lib/sdl/src/locale/emscripten/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/locale/haiku/SDL_syslocale.cc b/Engine/lib/sdl/src/locale/haiku/SDL_syslocale.cc index 3b930e8bc..1f885b023 100644 --- a/Engine/lib/sdl/src/locale/haiku/SDL_syslocale.cc +++ b/Engine/lib/sdl/src/locale/haiku/SDL_syslocale.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/locale/macosx/SDL_syslocale.m b/Engine/lib/sdl/src/locale/macosx/SDL_syslocale.m index 5ffbecdde..0e6bd3634 100644 --- a/Engine/lib/sdl/src/locale/macosx/SDL_syslocale.m +++ b/Engine/lib/sdl/src/locale/macosx/SDL_syslocale.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/locale/unix/SDL_syslocale.c b/Engine/lib/sdl/src/locale/unix/SDL_syslocale.c index 2a51f0c37..b9a377439 100644 --- a/Engine/lib/sdl/src/locale/unix/SDL_syslocale.c +++ b/Engine/lib/sdl/src/locale/unix/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/locale/windows/SDL_syslocale.c b/Engine/lib/sdl/src/locale/windows/SDL_syslocale.c index 1252046cf..2d033f476 100644 --- a/Engine/lib/sdl/src/locale/windows/SDL_syslocale.c +++ b/Engine/lib/sdl/src/locale/windows/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,9 +23,9 @@ #include "../../core/windows/SDL_windows.h" #include "../SDL_syslocale.h" -typedef BOOL (WINAPI *pfnGetUserPreferredUILanguages)(DWORD,PULONG,/*PZZWSTR*/WCHAR*,PULONG); +typedef BOOL (WINAPI *pfnGetUserPreferredUILanguages)(DWORD,PULONG,WCHAR*,PULONG); #ifndef MUI_LANGUAGE_NAME -#define MUI_LANGUAGE_NAME 0x8 +#define MUI_LANGUAGE_NAME 0x8 #endif static pfnGetUserPreferredUILanguages pGetUserPreferredUILanguages = NULL; @@ -39,11 +39,11 @@ SDL_SYS_GetPreferredLocales_winxp(char *buf, size_t buflen) char lang[16]; char country[16]; - const int langrc = GetLocaleInfoA(LOCALE_USER_DEFAULT, + const int langrc = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, lang, sizeof (lang)); - const int ctryrc = GetLocaleInfoA(LOCALE_USER_DEFAULT, + const int ctryrc = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, country, sizeof (country)); @@ -100,7 +100,7 @@ void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) { if (!kernel32) { - kernel32 = LoadLibraryW(L"kernel32.dll"); + kernel32 = GetModuleHandle(TEXT("kernel32.dll")); if (kernel32) { pGetUserPreferredUILanguages = (pfnGetUserPreferredUILanguages) GetProcAddress(kernel32, "GetUserPreferredUILanguages"); } diff --git a/Engine/lib/sdl/src/locale/winrt/SDL_syslocale.c b/Engine/lib/sdl/src/locale/winrt/SDL_syslocale.c index 923565cc0..1af2a95fc 100644 --- a/Engine/lib/sdl/src/locale/winrt/SDL_syslocale.c +++ b/Engine/lib/sdl/src/locale/winrt/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/main/dummy/SDL_dummy_main.c b/Engine/lib/sdl/src/main/dummy/SDL_dummy_main.c index 0174136b2..b78d8db14 100644 --- a/Engine/lib/sdl/src/main/dummy/SDL_dummy_main.c +++ b/Engine/lib/sdl/src/main/dummy/SDL_dummy_main.c @@ -15,9 +15,6 @@ main(int argc, char *argv[]) } #else /* Nothing to do on this platform */ -int -SDL_main_stub_symbol(void); - int SDL_main_stub_symbol(void) { diff --git a/Engine/lib/sdl/src/main/haiku/SDL_BApp.h b/Engine/lib/sdl/src/main/haiku/SDL_BApp.h index ce1fc6812..215f83662 100644 --- a/Engine/lib/sdl/src/main/haiku/SDL_BApp.h +++ b/Engine/lib/sdl/src/main/haiku/SDL_BApp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,6 +21,7 @@ #ifndef SDL_BAPP_H #define SDL_BAPP_H +#include #include #include #if SDL_VIDEO_OPENGL @@ -93,6 +94,15 @@ public: } + virtual void RefsReceived(BMessage* message) { + char filePath[512]; + entry_ref entryRef; + for (int32 i = 0; message->FindRef("refs", i, &entryRef) == B_OK; i++) { + BPath referencePath = BPath(&entryRef); + SDL_SendDropFile(NULL, referencePath.Path()); + } + return; + } /* Event-handling functions */ virtual void MessageReceived(BMessage* message) { @@ -198,6 +208,10 @@ public: } #if SDL_VIDEO_OPENGL + BGLView *GetCurrentContext() { + return _current_context; + } + void SetCurrentContext(BGLView *newContext) { if(_current_context) _current_context->UnlockGL(); @@ -234,25 +248,22 @@ private: } win = GetSDLWindow(winID); - // Simple relative mode support for mouse. - if (SDL_GetMouse()->relative_mode) { - int winWidth, winHeight, winPosX, winPosY; - SDL_GetWindowSize(win, &winWidth, &winHeight); - SDL_GetWindowPosition(win, &winPosX, &winPosY); - int dx = x - (winWidth / 2); - int dy = y - (winHeight / 2); - SDL_SendMouseMotion(win, 0, SDL_GetMouse()->relative_mode, dx, dy); - set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2)); - if (!be_app->IsCursorHidden()) - be_app->HideCursor(); - } else { - SDL_SendMouseMotion(win, 0, 0, x, y); - if (SDL_ShowCursor(-1) && be_app->IsCursorHidden()) - be_app->ShowCursor(); - } - - /* Tell the application that the mouse passed over, redraw needed */ - HAIKU_UpdateWindowFramebuffer(NULL,win,NULL,-1); + // Simple relative mode support for mouse. + if (SDL_GetMouse()->relative_mode) { + int winWidth, winHeight, winPosX, winPosY; + SDL_GetWindowSize(win, &winWidth, &winHeight); + SDL_GetWindowPosition(win, &winPosX, &winPosY); + int dx = x - (winWidth / 2); + int dy = y - (winHeight / 2); + SDL_SendMouseMotion(win, 0, SDL_GetMouse()->relative_mode, dx, dy); + set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2)); + if (!be_app->IsCursorHidden()) + be_app->HideCursor(); + } else { + SDL_SendMouseMotion(win, 0, 0, x, y); + if (SDL_ShowCursor(-1) && be_app->IsCursorHidden()) + be_app->ShowCursor(); + } } void _HandleMouseButton(BMessage *msg) { @@ -300,7 +311,7 @@ private: } HAIKU_SetKeyState(scancode, state); SDL_SendKeyboardKey(state, HAIKU_GetScancodeFromBeKey(scancode)); - + if (state == SDL_PRESSED && SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { const int8 *keyUtf8; ssize_t count; diff --git a/Engine/lib/sdl/src/main/haiku/SDL_BeApp.cc b/Engine/lib/sdl/src/main/haiku/SDL_BeApp.cc index 403be8258..a5e1428cc 100644 --- a/Engine/lib/sdl/src/main/haiku/SDL_BeApp.cc +++ b/Engine/lib/sdl/src/main/haiku/SDL_BeApp.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/main/haiku/SDL_BeApp.h b/Engine/lib/sdl/src/main/haiku/SDL_BeApp.h index db92b6d0b..5b74466e0 100644 --- a/Engine/lib/sdl/src/main/haiku/SDL_BeApp.h +++ b/Engine/lib/sdl/src/main/haiku/SDL_BeApp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/main/nacl/SDL_nacl_main.c b/Engine/lib/sdl/src/main/nacl/SDL_nacl_main.c index 4c223faba..a0838b184 100644 --- a/Engine/lib/sdl/src/main/nacl/SDL_nacl_main.c +++ b/Engine/lib/sdl/src/main/nacl/SDL_nacl_main.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/main/psp/SDL_psp_main.c b/Engine/lib/sdl/src/main/psp/SDL_psp_main.c index 2ca8e446b..8eb173fb4 100644 --- a/Engine/lib/sdl/src/main/psp/SDL_psp_main.c +++ b/Engine/lib/sdl/src/main/psp/SDL_psp_main.c @@ -7,11 +7,11 @@ #include "SDL_main.h" #include -#include -#include #include -#include -#include + +#ifdef main + #undef main +#endif /* If application's main() is redefined as SDL_main, and libSDLmain is linked, then this file will create the standard exit callback, @@ -23,11 +23,12 @@ PSP_MAIN_THREAD_STACK_SIZE, etc. */ -PSP_MODULE_INFO("SDL App", 0, 1, 1); +PSP_MODULE_INFO("SDL App", 0, 1, 0); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_VFPU | THREAD_ATTR_USER); int sdl_psp_exit_callback(int arg1, int arg2, void *common) { - exit(0); + sceKernelExitGame(); return 0; } @@ -43,7 +44,7 @@ int sdl_psp_callback_thread(SceSize args, void *argp) int sdl_psp_setup_callbacks(void) { - int thid = 0; + int thid; thid = sceKernelCreateThread("update_thread", sdl_psp_callback_thread, 0x11, 0xFA0, 0, 0); if(thid >= 0) @@ -53,12 +54,8 @@ int sdl_psp_setup_callbacks(void) int main(int argc, char *argv[]) { - pspDebugScreenInit(); sdl_psp_setup_callbacks(); - /* Register sceKernelExitGame() to be called when we exit */ - atexit(sceKernelExitGame); - SDL_SetMainReady(); (void)SDL_main(argc, argv); diff --git a/Engine/lib/sdl/src/main/uikit/SDL_uikit_main.c b/Engine/lib/sdl/src/main/uikit/SDL_uikit_main.c index 5717d0e80..702f67391 100644 --- a/Engine/lib/sdl/src/main/uikit/SDL_uikit_main.c +++ b/Engine/lib/sdl/src/main/uikit/SDL_uikit_main.c @@ -6,6 +6,7 @@ /* Include the SDL main definition header */ #include "SDL_main.h" +#ifndef SDL_MAIN_HANDLED #ifdef main #undef main #endif @@ -15,5 +16,6 @@ main(int argc, char *argv[]) { return SDL_UIKitRunApp(argc, argv, SDL_main); } +#endif /* !SDL_MAIN_HANDLED */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/main/windows/SDL_windows_main.c b/Engine/lib/sdl/src/main/windows/SDL_windows_main.c index f8b104186..056787e40 100644 --- a/Engine/lib/sdl/src/main/windows/SDL_windows_main.c +++ b/Engine/lib/sdl/src/main/windows/SDL_windows_main.c @@ -19,8 +19,6 @@ # undef main #endif /* main */ -#define WIN_WStringToUTF8(S) SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(S), (SDL_wcslen(S)+1)*sizeof(WCHAR)) - /* Pop up an out of memory message, returns to Windows */ static BOOL OutOfMemory(void) @@ -51,16 +49,29 @@ main_getcmdline(void) return OutOfMemory(); } + /* Note that we need to be careful about how we allocate/free memory here. + * If the application calls SDL_SetMemoryFunctions(), we can't rely on + * SDL_free() to use the same allocator after SDL_main() returns. + */ + /* Parse it into argv and argc */ - argv = (char **)SDL_calloc(argc + 1, sizeof(*argv)); + argv = (char **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc + 1) * sizeof(*argv)); if (!argv) { return OutOfMemory(); } for (i = 0; i < argc; ++i) { - argv[i] = WIN_WStringToUTF8(argvw[i]); + DWORD len; + char *arg = WIN_StringToUTF8W(argvw[i]); + if (!arg) { + return OutOfMemory(); + } + len = (DWORD)SDL_strlen(arg); + argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len + 1); if (!argv[i]) { return OutOfMemory(); } + CopyMemory(argv[i], arg, len); + SDL_free(arg); } argv[i] = NULL; LocalFree(argvw); @@ -72,9 +83,9 @@ main_getcmdline(void) /* Free argv, to avoid memory leak */ for (i = 0; i < argc; ++i) { - SDL_free(argv[i]); + HeapFree(GetProcessHeap(), 0, argv[i]); } - SDL_free(argv); + HeapFree(GetProcessHeap(), 0, argv); return result; } diff --git a/Engine/lib/sdl/src/main/windows/version.rc b/Engine/lib/sdl/src/main/windows/version.rc index 90c14981f..36ff39f12 100644 --- a/Engine/lib/sdl/src/main/windows/version.rc +++ b/Engine/lib/sdl/src/main/windows/version.rc @@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,14,0 - PRODUCTVERSION 2,0,14,0 + FILEVERSION 2,0,21,0 + PRODUCTVERSION 2,0,21,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -23,12 +23,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "2, 0, 14, 0\0" + VALUE "FileVersion", "2, 0, 21, 0\0" VALUE "InternalName", "SDL\0" - VALUE "LegalCopyright", "Copyright © 2020 Sam Lantinga\0" + VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL2.dll\0" VALUE "ProductName", "Simple DirectMedia Layer\0" - VALUE "ProductVersion", "2, 0, 14, 0\0" + VALUE "ProductVersion", "2, 0, 21, 0\0" END END BLOCK "VarFileInfo" diff --git a/Engine/lib/sdl/src/misc/SDL_sysurl.h b/Engine/lib/sdl/src/misc/SDL_sysurl.h index d10e0271b..28cc40daf 100644 --- a/Engine/lib/sdl/src/misc/SDL_sysurl.h +++ b/Engine/lib/sdl/src/misc/SDL_sysurl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/misc/SDL_url.c b/Engine/lib/sdl/src/misc/SDL_url.c index fe60766c9..eb258d962 100644 --- a/Engine/lib/sdl/src/misc/SDL_url.c +++ b/Engine/lib/sdl/src/misc/SDL_url.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/misc/android/SDL_sysurl.c b/Engine/lib/sdl/src/misc/android/SDL_sysurl.c index 37ea689d0..c17fbca46 100644 --- a/Engine/lib/sdl/src/misc/android/SDL_sysurl.c +++ b/Engine/lib/sdl/src/misc/android/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/misc/dummy/SDL_sysurl.c b/Engine/lib/sdl/src/misc/dummy/SDL_sysurl.c index 201f56be5..d35d016fc 100644 --- a/Engine/lib/sdl/src/misc/dummy/SDL_sysurl.c +++ b/Engine/lib/sdl/src/misc/dummy/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/misc/emscripten/SDL_sysurl.c b/Engine/lib/sdl/src/misc/emscripten/SDL_sysurl.c new file mode 100644 index 000000000..f344232ab --- /dev/null +++ b/Engine/lib/sdl/src/misc/emscripten/SDL_sysurl.c @@ -0,0 +1,37 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../SDL_sysurl.h" + +#include + +int +SDL_SYS_OpenURL(const char *url) +{ + EM_ASM({ + window.open(UTF8ToString($0), "_blank"); + }, url); + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/Engine/lib/sdl/src/misc/haiku/SDL_sysurl.cc b/Engine/lib/sdl/src/misc/haiku/SDL_sysurl.cc index cd0df1cd2..01a43f989 100644 --- a/Engine/lib/sdl/src/misc/haiku/SDL_sysurl.cc +++ b/Engine/lib/sdl/src/misc/haiku/SDL_sysurl.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/misc/ios/SDL_sysurl.m b/Engine/lib/sdl/src/misc/ios/SDL_sysurl.m index c7a5207da..73d5c73ec 100644 --- a/Engine/lib/sdl/src/misc/ios/SDL_sysurl.m +++ b/Engine/lib/sdl/src/misc/ios/SDL_sysurl.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/misc/macosx/SDL_sysurl.m b/Engine/lib/sdl/src/misc/macosx/SDL_sysurl.m index c896d9904..1b141ee1f 100644 --- a/Engine/lib/sdl/src/misc/macosx/SDL_sysurl.m +++ b/Engine/lib/sdl/src/misc/macosx/SDL_sysurl.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,10 +27,10 @@ int SDL_SYS_OpenURL(const char *url) { @autoreleasepool { - NSString *nsstr = [NSString stringWithUTF8String:url]; - NSURL *nsurl = [NSURL URLWithString:nsstr]; - return [[NSWorkspace sharedWorkspace] openURL:nsurl] ? 0 : -1; + CFURLRef cfurl = CFURLCreateWithBytes(NULL, (const UInt8 *) url, SDL_strlen(url), kCFStringEncodingUTF8, NULL); + OSStatus status = LSOpenCFURLRef(cfurl, NULL); + CFRelease(cfurl); + return status == noErr ? 0 : -1; }} /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/Engine/lib/sdl/src/misc/riscos/SDL_sysurl.c b/Engine/lib/sdl/src/misc/riscos/SDL_sysurl.c index f51661f17..2662c4d68 100644 --- a/Engine/lib/sdl/src/misc/riscos/SDL_sysurl.c +++ b/Engine/lib/sdl/src/misc/riscos/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/misc/unix/SDL_sysurl.c b/Engine/lib/sdl/src/misc/unix/SDL_sysurl.c index 1fb7f3242..8d6e0fc91 100644 --- a/Engine/lib/sdl/src/misc/unix/SDL_sysurl.c +++ b/Engine/lib/sdl/src/misc/unix/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,8 +33,11 @@ SDL_SYS_OpenURL(const char *url) { const pid_t pid1 = fork(); if (pid1 == 0) { /* child process */ + pid_t pid2; + /* Clear LD_PRELOAD so Chrome opens correctly when this application is launched by Steam */ + unsetenv("LD_PRELOAD"); /* Notice this is vfork and not fork! */ - const pid_t pid2 = vfork(); + pid2 = vfork(); if (pid2 == 0) { /* Grandchild process will try to launch the url */ execlp("xdg-open", "xdg-open", url, NULL); _exit(EXIT_FAILURE); @@ -62,8 +65,6 @@ SDL_SYS_OpenURL(const char *url) return SDL_SetError("Waiting on xdg-open failed: %s", strerror(errno)); } } - - return 0; } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/misc/vita/SDL_sysurl.c b/Engine/lib/sdl/src/misc/vita/SDL_sysurl.c new file mode 100644 index 000000000..1052efb40 --- /dev/null +++ b/Engine/lib/sdl/src/misc/vita/SDL_sysurl.c @@ -0,0 +1,44 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../SDL_sysurl.h" + +#include +#include + +int +SDL_SYS_OpenURL(const char *url) +{ + SceAppUtilInitParam init_param; + SceAppUtilBootParam boot_param; + SceAppUtilWebBrowserParam browser_param; + SDL_zero(init_param); + SDL_zero(boot_param); + sceAppUtilInit(&init_param, &boot_param); + SDL_zero(browser_param); + browser_param.str = url; + browser_param.strlen = SDL_strlen(url); + sceAppUtilLaunchWebBrowser(&browser_param); + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/Engine/lib/sdl/src/misc/windows/SDL_sysurl.c b/Engine/lib/sdl/src/misc/windows/SDL_sysurl.c index 1b2962031..12903db8f 100644 --- a/Engine/lib/sdl/src/misc/windows/SDL_sysurl.c +++ b/Engine/lib/sdl/src/misc/windows/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,7 +37,7 @@ SDL_SYS_OpenURL(const char *url) return WIN_SetErrorFromHRESULT("CoInitialize failed", hr); } - wurl = WIN_UTF8ToString(url); + wurl = WIN_UTF8ToStringW(url); if (wurl == NULL) { WIN_CoUninitialize(); return SDL_OutOfMemory(); diff --git a/Engine/lib/sdl/src/misc/winrt/SDL_sysurl.cpp b/Engine/lib/sdl/src/misc/winrt/SDL_sysurl.cpp index d2bd4de9f..111a14413 100644 --- a/Engine/lib/sdl/src/misc/winrt/SDL_sysurl.cpp +++ b/Engine/lib/sdl/src/misc/winrt/SDL_sysurl.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,15 +19,13 @@ 3. This notice may not be removed or altered from any source distribution. */ -#include - -#include "../../core/windows/SDL_windows.h" #include "../SDL_sysurl.h" +#include "../../core/windows/SDL_windows.h" int SDL_SYS_OpenURL(const char *url) { - WCHAR *wurl = WIN_UTF8ToString(url); + WCHAR *wurl = WIN_UTF8ToStringW(url); if (!wurl) { return SDL_OutOfMemory(); } diff --git a/Engine/lib/sdl/src/power/SDL_power.c b/Engine/lib/sdl/src/power/SDL_power.c index ca19d4492..625a8fa08 100644 --- a/Engine/lib/sdl/src/power/SDL_power.c +++ b/Engine/lib/sdl/src/power/SDL_power.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -68,6 +68,9 @@ static SDL_GetPowerInfo_Impl implementations[] = { #ifdef SDL_POWER_PSP /* handles PSP. */ SDL_GetPowerInfo_PSP, #endif +#ifdef SDL_POWER_VITA /* handles PSVita. */ + SDL_GetPowerInfo_VITA, +#endif #ifdef SDL_POWER_WINRT /* handles WinRT */ SDL_GetPowerInfo_WinRT, #endif diff --git a/Engine/lib/sdl/src/power/SDL_syspower.h b/Engine/lib/sdl/src/power/SDL_syspower.h index f28cc982b..d66e50f9c 100644 --- a/Engine/lib/sdl/src/power/SDL_syspower.h +++ b/Engine/lib/sdl/src/power/SDL_syspower.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -38,6 +38,7 @@ SDL_bool SDL_GetPowerInfo_MacOSX(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_Haiku(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_Android(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_PSP(SDL_PowerState *, int *, int *); +SDL_bool SDL_GetPowerInfo_VITA(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_WinRT(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_Emscripten(SDL_PowerState *, int *, int *); diff --git a/Engine/lib/sdl/src/power/android/SDL_syspower.c b/Engine/lib/sdl/src/power/android/SDL_syspower.c index 045925af3..4be3b1502 100644 --- a/Engine/lib/sdl/src/power/android/SDL_syspower.c +++ b/Engine/lib/sdl/src/power/android/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/power/emscripten/SDL_syspower.c b/Engine/lib/sdl/src/power/emscripten/SDL_syspower.c index 97afe3405..4bac68602 100644 --- a/Engine/lib/sdl/src/power/emscripten/SDL_syspower.c +++ b/Engine/lib/sdl/src/power/emscripten/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/power/haiku/SDL_syspower.c b/Engine/lib/sdl/src/power/haiku/SDL_syspower.c index 28ccdec6b..ac1fae917 100644 --- a/Engine/lib/sdl/src/power/haiku/SDL_syspower.c +++ b/Engine/lib/sdl/src/power/haiku/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -45,7 +45,7 @@ SDL_bool SDL_GetPowerInfo_Haiku(SDL_PowerState * state, int *seconds, int *percent) { - const int fd = open("/dev/misc/apm", O_RDONLY); + const int fd = open("/dev/misc/apm", O_RDONLY | O_CLOEXEC); SDL_bool need_details = SDL_FALSE; uint16 regs[6]; uint8 ac_status; @@ -59,7 +59,7 @@ SDL_GetPowerInfo_Haiku(SDL_PowerState * state, int *seconds, int *percent) return SDL_FALSE; /* maybe some other method will work? */ } - memset(regs, '\0', sizeof(regs)); + SDL_memset(regs, '\0', sizeof(regs)); regs[0] = APM_FUNC_OFFSET + APM_FUNC_GET_POWER_STATUS; regs[1] = APM_DEVICE_ALL; rc = ioctl(fd, APM_BIOS_CALL, regs); diff --git a/Engine/lib/sdl/src/power/linux/SDL_syspower.c b/Engine/lib/sdl/src/power/linux/SDL_syspower.c index 234119c5a..f4e1ecc3d 100644 --- a/Engine/lib/sdl/src/power/linux/SDL_syspower.c +++ b/Engine/lib/sdl/src/power/linux/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -44,14 +44,17 @@ static const char *sys_class_power_supply_path = "/sys/class/power_supply"; static int open_power_file(const char *base, const char *node, const char *key) { - const size_t pathlen = strlen(base) + strlen(node) + strlen(key) + 3; - char *path = (char *) alloca(pathlen); + int fd; + const size_t pathlen = SDL_strlen(base) + SDL_strlen(node) + SDL_strlen(key) + 3; + char *path = SDL_stack_alloc(char, pathlen); if (path == NULL) { return -1; /* oh well. */ } - snprintf(path, pathlen, "%s/%s/%s", base, node, key); - return open(path, O_RDONLY); + SDL_snprintf(path, pathlen, "%s/%s/%s", base, node, key); + fd = open(path, O_RDONLY | O_CLOEXEC); + SDL_stack_free(path); + return fd; } @@ -146,20 +149,20 @@ check_proc_acpi_battery(const char * node, SDL_bool * have_battery, ptr = &state[0]; while (make_proc_acpi_key_val(&ptr, &key, &val)) { - if (strcmp(key, "present") == 0) { - if (strcmp(val, "yes") == 0) { + if (SDL_strcmp(key, "present") == 0) { + if (SDL_strcmp(val, "yes") == 0) { *have_battery = SDL_TRUE; } - } else if (strcmp(key, "charging state") == 0) { + } else if (SDL_strcmp(key, "charging state") == 0) { /* !!! FIXME: what exactly _does_ charging/discharging mean? */ - if (strcmp(val, "charging/discharging") == 0) { + if (SDL_strcmp(val, "charging/discharging") == 0) { charge = SDL_TRUE; - } else if (strcmp(val, "charging") == 0) { + } else if (SDL_strcmp(val, "charging") == 0) { charge = SDL_TRUE; } - } else if (strcmp(key, "remaining capacity") == 0) { + } else if (SDL_strcmp(key, "remaining capacity") == 0) { char *endptr = NULL; - const int cvt = (int) strtol(val, &endptr, 10); + const int cvt = (int) SDL_strtol(val, &endptr, 10); if (*endptr == ' ') { remaining = cvt; } @@ -168,9 +171,9 @@ check_proc_acpi_battery(const char * node, SDL_bool * have_battery, ptr = &info[0]; while (make_proc_acpi_key_val(&ptr, &key, &val)) { - if (strcmp(key, "design capacity") == 0) { + if (SDL_strcmp(key, "design capacity") == 0) { char *endptr = NULL; - const int cvt = (int) strtol(val, &endptr, 10); + const int cvt = (int) SDL_strtol(val, &endptr, 10); if (*endptr == ' ') { maximum = cvt; } @@ -225,8 +228,8 @@ check_proc_acpi_ac_adapter(const char * node, SDL_bool * have_ac) ptr = &state[0]; while (make_proc_acpi_key_val(&ptr, &key, &val)) { - if (strcmp(key, "state") == 0) { - if (strcmp(val, "on-line") == 0) { + if (SDL_strcmp(key, "state") == 0) { + if (SDL_strcmp(val, "on-line") == 0) { *have_ac = SDL_TRUE; } } @@ -315,7 +318,7 @@ static SDL_bool int_string(char *str, int *val) { char *endptr = NULL; - *val = (int) strtol(str, &endptr, 0); + *val = (int) SDL_strtol(str, &endptr, 0); return ((*str != '\0') && (*endptr == '\0')); } @@ -330,7 +333,7 @@ SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState * state, int battery_flag = 0; int battery_percent = 0; int battery_time = 0; - const int fd = open(proc_apm_path, O_RDONLY); + const int fd = open(proc_apm_path, O_RDONLY | O_CLOEXEC); char buf[128]; char *ptr = &buf[0]; char *str = NULL; @@ -377,8 +380,8 @@ SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState * state, if (!next_string(&ptr, &str)) { /* remaining battery life percent */ return SDL_FALSE; } - if (str[strlen(str) - 1] == '%') { - str[strlen(str) - 1] = '\0'; + if (str[SDL_strlen(str) - 1] == '%') { + str[SDL_strlen(str) - 1] = '\0'; } if (!int_string(str, &battery_percent)) { return SDL_FALSE; @@ -392,7 +395,7 @@ SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState * state, if (!next_string(&ptr, &str)) { /* remaining battery life time units */ return SDL_FALSE; - } else if (strcmp(str, "min") == 0) { + } else if (SDL_strcmp(str, "min") == 0) { battery_time *= 60; } @@ -558,20 +561,30 @@ check_upower_device(DBusConnection *conn, const char *path, SDL_PowerState *stat return; } else if (!ui32) { return; /* we don't care about random devices with batteries, like wireless controllers, etc */ - } else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "IsPresent", DBUS_TYPE_BOOLEAN, &ui32)) { + } + + if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "IsPresent", DBUS_TYPE_BOOLEAN, &ui32)) { return; - } else if (!ui32) { + } + if (!ui32) { st = SDL_POWERSTATE_NO_BATTERY; - } else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "State", DBUS_TYPE_UINT32, &ui32)) { - st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ - } else if (ui32 == 1) { /* 1 == charging */ - st = SDL_POWERSTATE_CHARGING; - } else if ((ui32 == 2) || (ui32 == 3)) { /* 2 == discharging, 3 == empty. */ - st = SDL_POWERSTATE_ON_BATTERY; - } else if (ui32 == 4) { /* 4 == full */ - st = SDL_POWERSTATE_CHARGED; } else { - st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + /* Get updated information on the battery status + * This can occasionally fail, and we'll just return slightly stale data in that case + */ + SDL_DBus_CallMethodOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Refresh", DBUS_TYPE_INVALID, DBUS_TYPE_INVALID); + + if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "State", DBUS_TYPE_UINT32, &ui32)) { + st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + } else if (ui32 == 1) { /* 1 == charging */ + st = SDL_POWERSTATE_CHARGING; + } else if ((ui32 == 2) || (ui32 == 3)) { /* 2 == discharging, 3 == empty. */ + st = SDL_POWERSTATE_ON_BATTERY; + } else if (ui32 == 4) { /* 4 == full */ + st = SDL_POWERSTATE_CHARGED; + } else { + st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + } } if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Percentage", DBUS_TYPE_DOUBLE, &d)) { diff --git a/Engine/lib/sdl/src/power/macosx/SDL_syspower.c b/Engine/lib/sdl/src/power/macosx/SDL_syspower.c index 86c48ebf9..8277b3472 100644 --- a/Engine/lib/sdl/src/power/macosx/SDL_syspower.c +++ b/Engine/lib/sdl/src/power/macosx/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/power/psp/SDL_syspower.c b/Engine/lib/sdl/src/power/psp/SDL_syspower.c index 6a073edfd..ca9ba66b7 100644 --- a/Engine/lib/sdl/src/power/psp/SDL_syspower.c +++ b/Engine/lib/sdl/src/power/psp/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/power/uikit/SDL_syspower.h b/Engine/lib/sdl/src/power/uikit/SDL_syspower.h index 451f45229..a412780b0 100644 --- a/Engine/lib/sdl/src/power/uikit/SDL_syspower.h +++ b/Engine/lib/sdl/src/power/uikit/SDL_syspower.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/power/uikit/SDL_syspower.m b/Engine/lib/sdl/src/power/uikit/SDL_syspower.m index 969628c2a..2a5ec9c6a 100644 --- a/Engine/lib/sdl/src/power/uikit/SDL_syspower.m +++ b/Engine/lib/sdl/src/power/uikit/SDL_syspower.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/power/vita/SDL_syspower.c b/Engine/lib/sdl/src/power/vita/SDL_syspower.c new file mode 100644 index 000000000..46eef930e --- /dev/null +++ b/Engine/lib/sdl/src/power/vita/SDL_syspower.c @@ -0,0 +1,68 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#ifndef SDL_POWER_DISABLED +#if SDL_POWER_VITA + +#include "SDL_power.h" +#include + + +SDL_bool +SDL_GetPowerInfo_VITA(SDL_PowerState * state, int *seconds, + int *percent) +{ + int battery = 1; + int plugged = scePowerIsPowerOnline(); + int charging = scePowerIsBatteryCharging(); + + *state = SDL_POWERSTATE_UNKNOWN; + *seconds = -1; + *percent = -1; + + if (!battery) { + *state = SDL_POWERSTATE_NO_BATTERY; + *seconds = -1; + *percent = -1; + } else if (charging) { + *state = SDL_POWERSTATE_CHARGING; + *percent = scePowerGetBatteryLifePercent(); + *seconds = scePowerGetBatteryLifeTime()*60; + } else if (plugged) { + *state = SDL_POWERSTATE_CHARGED; + *percent = scePowerGetBatteryLifePercent(); + *seconds = scePowerGetBatteryLifeTime()*60; + } else { + *state = SDL_POWERSTATE_ON_BATTERY; + *percent = scePowerGetBatteryLifePercent(); + *seconds = scePowerGetBatteryLifeTime()*60; + } + + + return SDL_TRUE; /* always the definitive answer on VITA. */ +} + +#endif /* SDL_POWER_VITA */ +#endif /* SDL_POWER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/power/windows/SDL_syspower.c b/Engine/lib/sdl/src/power/windows/SDL_syspower.c index 9108fe440..666b563a7 100644 --- a/Engine/lib/sdl/src/power/windows/SDL_syspower.c +++ b/Engine/lib/sdl/src/power/windows/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/power/winrt/SDL_syspower.cpp b/Engine/lib/sdl/src/power/winrt/SDL_syspower.cpp index 227fd2f11..62e7ea6d6 100644 --- a/Engine/lib/sdl/src/power/winrt/SDL_syspower.cpp +++ b/Engine/lib/sdl/src/power/winrt/SDL_syspower.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/SDL_d3dmath.c b/Engine/lib/sdl/src/render/SDL_d3dmath.c index 5acc10da9..63048bb88 100644 --- a/Engine/lib/sdl/src/render/SDL_d3dmath.c +++ b/Engine/lib/sdl/src/render/SDL_d3dmath.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/SDL_d3dmath.h b/Engine/lib/sdl/src/render/SDL_d3dmath.h index 5bd3dc67d..7b74cfe75 100644 --- a/Engine/lib/sdl/src/render/SDL_d3dmath.h +++ b/Engine/lib/sdl/src/render/SDL_d3dmath.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/SDL_render.c b/Engine/lib/sdl/src/render/SDL_render.c index e80cf6c01..441badbc6 100644 --- a/Engine/lib/sdl/src/render/SDL_render.c +++ b/Engine/lib/sdl/src/render/SDL_render.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,19 +32,29 @@ # include "../core/android/SDL_android.h" #endif +/* as a courtesy to iOS apps, we don't try to draw when in the background, as +that will crash the app. However, these apps _should_ have used +SDL_AddEventWatch to catch SDL_APP_WILLENTERBACKGROUND events and stopped +drawing themselves. Other platforms still draw, as the compositor can use it, +and more importantly: drawing to render targets isn't lost. But I still think +this should probably be removed at some point in the future. --ryan. */ +#if defined(__IPHONEOS__) || defined(__TVOS__) || defined(__ANDROID__) +#define DONT_DRAW_WHILE_HIDDEN 1 +#else +#define DONT_DRAW_WHILE_HIDDEN 0 +#endif + #define SDL_WINDOWRENDERDATA "_SDL_WindowRenderData" #define CHECK_RENDERER_MAGIC(renderer, retval) \ - SDL_assert(renderer && renderer->magic == &renderer_magic); \ if (!renderer || renderer->magic != &renderer_magic) { \ - SDL_SetError("Invalid renderer"); \ + SDL_InvalidParamError("renderer"); \ return retval; \ } #define CHECK_TEXTURE_MAGIC(texture, retval) \ - SDL_assert(texture && texture->magic == &texture_magic); \ if (!texture || texture->magic != &texture_magic) { \ - SDL_SetError("Invalid texture"); \ + SDL_InvalidParamError("texture"); \ return retval; \ } @@ -104,6 +114,9 @@ static const SDL_RenderDriver *render_drivers[] = { #if SDL_VIDEO_RENDER_PSP &PSP_RenderDriver, #endif +#if SDL_VIDEO_RENDER_VITA_GXM + &VITA_GXM_RenderDriver, +#endif #if SDL_VIDEO_RENDER_SW &SW_RenderDriver #endif @@ -198,6 +211,16 @@ DebugLogRenderCommands(const SDL_RenderCommand *cmd) (int) cmd->data.draw.b, (int) cmd->data.draw.a, (int) cmd->data.draw.blend, cmd->data.draw.texture); break; + + case SDL_RENDERCMD_GEOMETRY: + SDL_Log(" %u. geometry (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d, tex=%p)", i++, + (unsigned int) cmd->data.draw.first, + (unsigned int) cmd->data.draw.count, + (int) cmd->data.draw.r, (int) cmd->data.draw.g, + (int) cmd->data.draw.b, (int) cmd->data.draw.a, + (int) cmd->data.draw.blend, cmd->data.draw.texture); + break; + } cmd = cmd->next; } @@ -262,10 +285,10 @@ void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset) { const size_t needed = renderer->vertex_data_used + numbytes + alignment; - size_t current_offset = renderer->vertex_data_used; + const size_t current_offset = renderer->vertex_data_used; - size_t aligner = (alignment && ((current_offset & (alignment - 1)) != 0)) ? (alignment - (current_offset & (alignment - 1))) : 0; - size_t aligned = current_offset + aligner; + const size_t aligner = (alignment && ((current_offset & (alignment - 1)) != 0)) ? (alignment - (current_offset & (alignment - 1))) : 0; + const size_t aligned = current_offset + aligner; if (renderer->vertex_data_allocation < needed) { const size_t current_allocation = renderer->vertex_data ? renderer->vertex_data_allocation : 1024; @@ -274,7 +297,9 @@ SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const while (newsize < needed) { newsize *= 2; } + ptr = SDL_realloc(renderer->vertex_data, newsize); + if (ptr == NULL) { SDL_OutOfMemory(); return NULL; @@ -331,7 +356,11 @@ QueueCmdSetViewport(SDL_Renderer *renderer) if (cmd != NULL) { cmd->command = SDL_RENDERCMD_SETVIEWPORT; cmd->data.viewport.first = 0; /* render backend will fill this in. */ - SDL_memcpy(&cmd->data.viewport.rect, &renderer->viewport, sizeof (renderer->viewport)); + /* Convert SDL_FRect to SDL_Rect */ + cmd->data.viewport.rect.x = (int)SDL_floor(renderer->viewport.x); + cmd->data.viewport.rect.y = (int)SDL_floor(renderer->viewport.y); + cmd->data.viewport.rect.w = (int)SDL_floor(renderer->viewport.w); + cmd->data.viewport.rect.h = (int)SDL_floor(renderer->viewport.h); retval = renderer->QueueSetViewport(renderer, cmd); if (retval < 0) { cmd->command = SDL_RENDERCMD_NO_OP; @@ -357,7 +386,11 @@ QueueCmdSetClipRect(SDL_Renderer *renderer) } else { cmd->command = SDL_RENDERCMD_SETCLIPRECT; cmd->data.cliprect.enabled = renderer->clipping_enabled; - SDL_memcpy(&cmd->data.cliprect.rect, &renderer->clip_rect, sizeof (cmd->data.cliprect.rect)); + /* Convert SDL_FRect to SDL_Rect */ + cmd->data.cliprect.rect.x = (int)SDL_floor(renderer->clip_rect.x); + cmd->data.cliprect.rect.y = (int)SDL_floor(renderer->clip_rect.y); + cmd->data.cliprect.rect.w = (int)SDL_floor(renderer->clip_rect.w); + cmd->data.cliprect.rect.h = (int)SDL_floor(renderer->clip_rect.h); SDL_memcpy(&renderer->last_queued_cliprect, &renderer->clip_rect, sizeof (SDL_Rect)); renderer->last_queued_cliprect_enabled = renderer->clipping_enabled; renderer->cliprect_queued = SDL_TRUE; @@ -367,11 +400,11 @@ QueueCmdSetClipRect(SDL_Renderer *renderer) } static int -QueueCmdSetDrawColor(SDL_Renderer *renderer, const Uint8 r, const Uint8 g, const Uint8 b, const Uint8 a) +QueueCmdSetDrawColor(SDL_Renderer *renderer, SDL_Color *col) { - const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); + const Uint32 color = (((Uint32)col->a << 24) | (col->r << 16) | (col->g << 8) | col->b); int retval = 0; - + if (!renderer->color_queued || (color != renderer->last_queued_color)) { SDL_RenderCommand *cmd = AllocateRenderCommand(renderer); retval = -1; @@ -379,10 +412,10 @@ QueueCmdSetDrawColor(SDL_Renderer *renderer, const Uint8 r, const Uint8 g, const if (cmd != NULL) { cmd->command = SDL_RENDERCMD_SETDRAWCOLOR; cmd->data.color.first = 0; /* render backend will fill this in. */ - cmd->data.color.r = r; - cmd->data.color.g = g; - cmd->data.color.b = b; - cmd->data.color.a = a; + cmd->data.color.r = col->r; + cmd->data.color.g = col->g; + cmd->data.color.b = col->b; + cmd->data.color.a = col->a; retval = renderer->QueueSetDrawColor(renderer, cmd); if (retval < 0) { cmd->command = SDL_RENDERCMD_NO_OP; @@ -405,17 +438,33 @@ QueueCmdClear(SDL_Renderer *renderer) cmd->command = SDL_RENDERCMD_CLEAR; cmd->data.color.first = 0; - cmd->data.color.r = renderer->r; - cmd->data.color.g = renderer->g; - cmd->data.color.b = renderer->b; - cmd->data.color.a = renderer->a; + cmd->data.color.r = renderer->color.r; + cmd->data.color.g = renderer->color.g; + cmd->data.color.b = renderer->color.b; + cmd->data.color.a = renderer->color.a; return 0; } -static int -PrepQueueCmdDraw(SDL_Renderer *renderer, const Uint8 r, const Uint8 g, const Uint8 b, const Uint8 a) +static SDL_RenderCommand * +PrepQueueCmdDraw(SDL_Renderer *renderer, const SDL_RenderCommandType cmdtype, SDL_Texture *texture) { - int retval = QueueCmdSetDrawColor(renderer, r, g, b, a); + SDL_RenderCommand *cmd = NULL; + int retval = 0; + SDL_Color *color; + SDL_BlendMode blendMode; + + if (texture) { + color = &texture->color; + blendMode = texture->blendMode; + } else { + color = &renderer->color; + blendMode = renderer->blendMode; + } + + if (cmdtype != SDL_RENDERCMD_GEOMETRY) { + /* !!! FIXME: drop this draw if viewport w or h is zero. */ + retval = QueueCmdSetDrawColor(renderer, color); + } /* Set the viewport and clip rect directly before draws, so the backends * don't have to worry about that state not being valid at draw time. */ @@ -425,26 +474,19 @@ PrepQueueCmdDraw(SDL_Renderer *renderer, const Uint8 r, const Uint8 g, const Uin if (retval == 0 && !renderer->cliprect_queued) { retval = QueueCmdSetClipRect(renderer); } - return retval; -} -static SDL_RenderCommand * -PrepQueueCmdDrawSolid(SDL_Renderer *renderer, const SDL_RenderCommandType cmdtype) -{ - /* !!! FIXME: drop this draw if viewport w or h is zero. */ - SDL_RenderCommand *cmd = NULL; - if (PrepQueueCmdDraw(renderer, renderer->r, renderer->g, renderer->b, renderer->a) == 0) { + if (retval == 0) { cmd = AllocateRenderCommand(renderer); if (cmd != NULL) { cmd->command = cmdtype; cmd->data.draw.first = 0; /* render backend will fill this in. */ cmd->data.draw.count = 0; /* render backend will fill this in. */ - cmd->data.draw.r = renderer->r; - cmd->data.draw.g = renderer->g; - cmd->data.draw.b = renderer->b; - cmd->data.draw.a = renderer->a; - cmd->data.draw.blend = renderer->blendMode; - cmd->data.draw.texture = NULL; /* no texture. */ + cmd->data.draw.r = color->r; + cmd->data.draw.g = color->g; + cmd->data.draw.b = color->b; + cmd->data.draw.a = color->a; + cmd->data.draw.blend = blendMode; + cmd->data.draw.texture = texture; } } return cmd; @@ -453,7 +495,7 @@ PrepQueueCmdDrawSolid(SDL_Renderer *renderer, const SDL_RenderCommandType cmdtyp static int QueueCmdDrawPoints(SDL_Renderer *renderer, const SDL_FPoint * points, const int count) { - SDL_RenderCommand *cmd = PrepQueueCmdDrawSolid(renderer, SDL_RENDERCMD_DRAW_POINTS); + SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_DRAW_POINTS, NULL); int retval = -1; if (cmd != NULL) { retval = renderer->QueueDrawPoints(renderer, cmd, points, count); @@ -467,7 +509,7 @@ QueueCmdDrawPoints(SDL_Renderer *renderer, const SDL_FPoint * points, const int static int QueueCmdDrawLines(SDL_Renderer *renderer, const SDL_FPoint * points, const int count) { - SDL_RenderCommand *cmd = PrepQueueCmdDrawSolid(renderer, SDL_RENDERCMD_DRAW_LINES); + SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_DRAW_LINES, NULL); int retval = -1; if (cmd != NULL) { retval = renderer->QueueDrawLines(renderer, cmd, points, count); @@ -481,43 +523,81 @@ QueueCmdDrawLines(SDL_Renderer *renderer, const SDL_FPoint * points, const int c static int QueueCmdFillRects(SDL_Renderer *renderer, const SDL_FRect * rects, const int count) { - SDL_RenderCommand *cmd = PrepQueueCmdDrawSolid(renderer, SDL_RENDERCMD_FILL_RECTS); + SDL_RenderCommand *cmd; int retval = -1; + const int use_rendergeometry = (renderer->QueueFillRects == NULL); + + cmd = PrepQueueCmdDraw(renderer, (use_rendergeometry ? SDL_RENDERCMD_GEOMETRY : SDL_RENDERCMD_FILL_RECTS), NULL); + if (cmd != NULL) { - retval = renderer->QueueFillRects(renderer, cmd, rects, count); - if (retval < 0) { - cmd->command = SDL_RENDERCMD_NO_OP; + if (use_rendergeometry) { + SDL_bool isstack1; + SDL_bool isstack2; + float *xy = SDL_small_alloc(float, 4 * 2 * count, &isstack1); + int *indices = SDL_small_alloc(int, 6 * count, &isstack2); + + if (xy && indices) { + int i; + float *ptr_xy = xy; + int *ptr_indices = indices; + const int xy_stride = 2 * sizeof (float); + const int num_vertices = 4 * count; + const int num_indices = 6 * count; + const int size_indices = 4; + int cur_indice = 0; + + for (i = 0; i < count; ++i) { + float minx, miny, maxx, maxy; + + minx = rects[i].x; + miny = rects[i].y; + maxx = rects[i].x + rects[i].w; + maxy = rects[i].y + rects[i].h; + + *ptr_xy++ = minx; + *ptr_xy++ = miny; + *ptr_xy++ = maxx; + *ptr_xy++ = miny; + *ptr_xy++ = maxx; + *ptr_xy++ = maxy; + *ptr_xy++ = minx; + *ptr_xy++ = maxy; + + *ptr_indices++ = cur_indice + 0; + *ptr_indices++ = cur_indice + 1; + *ptr_indices++ = cur_indice + 2; + *ptr_indices++ = cur_indice + 0; + *ptr_indices++ = cur_indice + 2; + *ptr_indices++ = cur_indice + 3; + cur_indice += 4; + } + + retval = renderer->QueueGeometry(renderer, cmd, NULL, + xy, xy_stride, &renderer->color, 0 /* color_stride */, NULL, 0, + num_vertices, indices, num_indices, size_indices, + 1.0f, 1.0f); + + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } + + SDL_small_free(xy, isstack1); + SDL_small_free(indices, isstack2); + } + } else { + retval = renderer->QueueFillRects(renderer, cmd, rects, count); + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } } } return retval; } -static SDL_RenderCommand * -PrepQueueCmdDrawTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_RenderCommandType cmdtype) -{ - /* !!! FIXME: drop this draw if viewport w or h is zero. */ - SDL_RenderCommand *cmd = NULL; - if (PrepQueueCmdDraw(renderer, texture->r, texture->g, texture->b, texture->a) == 0) { - cmd = AllocateRenderCommand(renderer); - if (cmd != NULL) { - cmd->command = cmdtype; - cmd->data.draw.first = 0; /* render backend will fill this in. */ - cmd->data.draw.count = 0; /* render backend will fill this in. */ - cmd->data.draw.r = texture->r; - cmd->data.draw.g = texture->g; - cmd->data.draw.b = texture->b; - cmd->data.draw.a = texture->a; - cmd->data.draw.blend = texture->blendMode; - cmd->data.draw.texture = texture; - } - } - return cmd; -} - static int QueueCmdCopy(SDL_Renderer *renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect) { - SDL_RenderCommand *cmd = PrepQueueCmdDrawTexture(renderer, texture, SDL_RENDERCMD_COPY); + SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_COPY, texture); int retval = -1; if (cmd != NULL) { retval = renderer->QueueCopy(renderer, cmd, texture, srcrect, dstrect); @@ -531,13 +611,12 @@ QueueCmdCopy(SDL_Renderer *renderer, SDL_Texture * texture, const SDL_Rect * src static int QueueCmdCopyEx(SDL_Renderer *renderer, SDL_Texture * texture, const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y) { - SDL_RenderCommand *cmd = PrepQueueCmdDrawTexture(renderer, texture, SDL_RENDERCMD_COPY_EX); + SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_COPY_EX, texture); int retval = -1; - SDL_assert(renderer->QueueCopyEx != NULL); /* should have caught at higher level. */ if (cmd != NULL) { - retval = renderer->QueueCopyEx(renderer, cmd, texture, srcquad, dstrect, angle, center, flip); + retval = renderer->QueueCopyEx(renderer, cmd, texture, srcquad, dstrect, angle, center, flip, scale_x, scale_y); if (retval < 0) { cmd->command = SDL_RENDERCMD_NO_OP; } @@ -545,6 +624,30 @@ QueueCmdCopyEx(SDL_Renderer *renderer, SDL_Texture * texture, return retval; } +static int +QueueCmdGeometry(SDL_Renderer *renderer, SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + SDL_RenderCommand *cmd; + int retval = -1; + cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_GEOMETRY, texture); + if (cmd != NULL) { + retval = renderer->QueueGeometry(renderer, cmd, texture, + xy, xy_stride, + color, color_stride, uv, uv_stride, + num_vertices, indices, num_indices, size_indices, + scale_x, scale_y); + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } + } + return retval; +} static int UpdateLogicalSize(SDL_Renderer *renderer); @@ -573,7 +676,7 @@ SDL_GetRenderDriverInfo(int index, SDL_RendererInfo * info) #endif } -static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_Rect *viewport, SDL_FPoint *scale) +static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_FRect *viewport, SDL_FPoint *scale) { SDL_LockMutex(renderer->target_mutex); *logical_w = renderer->target ? renderer->logical_w_backup : renderer->logical_w; @@ -602,6 +705,17 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) SDL_SetRenderTarget(renderer, NULL); } + /* Update the DPI scale if the window has been resized. */ + if (window && renderer->GetOutputSize) { + int window_w, window_h; + int output_w, output_h; + if (renderer->GetOutputSize(renderer, &output_w, &output_h) == 0) { + SDL_GetWindowSize(renderer->window, &window_w, &window_h); + renderer->dpi_scale.x = (float)window_w / output_w; + renderer->dpi_scale.y = (float)window_h / output_h; + } + } + if (renderer->logical_w) { UpdateLogicalSize(renderer); } else { @@ -614,19 +728,12 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) SDL_GetWindowSize(renderer->window, &w, &h); } - if (renderer->target) { - renderer->viewport_backup.x = 0; - renderer->viewport_backup.y = 0; - renderer->viewport_backup.w = w; - renderer->viewport_backup.h = h; - } else { - renderer->viewport.x = 0; - renderer->viewport.y = 0; - renderer->viewport.w = w; - renderer->viewport.h = h; - QueueCmdSetViewport(renderer); - FlushRenderCommandsIfNotBatching(renderer); - } + renderer->viewport.x = 0; + renderer->viewport.y = 0; + renderer->viewport.w = (float) w; + renderer->viewport.h = (float) h; + QueueCmdSetViewport(renderer); + FlushRenderCommandsIfNotBatching(renderer); } if (saved_target) { @@ -640,7 +747,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) } } else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) { renderer->hidden = SDL_TRUE; - } else if (event->window.event == SDL_WINDOWEVENT_RESTORED || + } else if (event->window.event == SDL_WINDOWEVENT_RESTORED || event->window.event == SDL_WINDOWEVENT_MAXIMIZED) { if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_HIDDEN)) { renderer->hidden = SDL_FALSE; @@ -651,7 +758,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) SDL_Window *window = SDL_GetWindowFromID(event->motion.windowID); if (window == renderer->window) { int logical_w, logical_h; - SDL_Rect viewport; + SDL_FRect viewport; SDL_FPoint scale; GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale); if (logical_w) { @@ -661,15 +768,15 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) event->motion.y = (int)(event->motion.y / (scale.y * renderer->dpi_scale.y)); if (event->motion.xrel != 0 && renderer->relative_scaling) { float rel = renderer->xrel + event->motion.xrel / (scale.x * renderer->dpi_scale.x); - float trunc = SDL_truncf(rel); - renderer->xrel = rel - trunc; - event->motion.xrel = (Sint32) trunc; + float truncated = SDL_truncf(rel); + renderer->xrel = rel - truncated; + event->motion.xrel = (Sint32) truncated; } if (event->motion.yrel != 0 && renderer->relative_scaling) { float rel = renderer->yrel + event->motion.yrel / (scale.y * renderer->dpi_scale.y); - float trunc = SDL_truncf(rel); - renderer->yrel = rel - trunc; - event->motion.yrel = (Sint32) trunc; + float truncated = SDL_truncf(rel); + renderer->yrel = rel - truncated; + event->motion.yrel = (Sint32) truncated; } } } @@ -678,7 +785,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) SDL_Window *window = SDL_GetWindowFromID(event->button.windowID); if (window == renderer->window) { int logical_w, logical_h; - SDL_Rect viewport; + SDL_FRect viewport; SDL_FPoint scale; GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale); if (logical_w) { @@ -687,13 +794,13 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) event->button.x = (int)(event->button.x / (scale.x * renderer->dpi_scale.x)); event->button.y = (int)(event->button.y / (scale.y * renderer->dpi_scale.y)); } - } + } } else if (event->type == SDL_FINGERDOWN || event->type == SDL_FINGERUP || event->type == SDL_FINGERMOTION) { int logical_w, logical_h; float physical_w, physical_h; - SDL_Rect viewport; + SDL_FRect viewport; SDL_FPoint scale; GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale); @@ -776,12 +883,32 @@ void VerifyDrawQueueFunctions(const SDL_Renderer *renderer) SDL_assert(renderer->QueueSetViewport != NULL); SDL_assert(renderer->QueueSetDrawColor != NULL); SDL_assert(renderer->QueueDrawPoints != NULL); - SDL_assert(renderer->QueueDrawLines != NULL); - SDL_assert(renderer->QueueFillRects != NULL); - SDL_assert(renderer->QueueCopy != NULL); + SDL_assert(renderer->QueueDrawLines != NULL || renderer->QueueGeometry != NULL); + SDL_assert(renderer->QueueFillRects != NULL || renderer->QueueGeometry != NULL); + SDL_assert(renderer->QueueCopy != NULL || renderer->QueueGeometry != NULL); SDL_assert(renderer->RunCommandQueue != NULL); } +static SDL_RenderLineMethod SDL_GetRenderLineMethod() +{ + const char *hint = SDL_GetHint(SDL_HINT_RENDER_LINE_METHOD); + + int method = 0; + if (hint) { + method = SDL_atoi(hint); + } + switch (method) { + case 1: + return SDL_RENDERLINEMETHOD_POINTS; + case 2: + return SDL_RENDERLINEMETHOD_LINES; + case 3: + return SDL_RENDERLINEMETHOD_GEOMETRY; + default: + return SDL_RENDERLINEMETHOD_POINTS; + } +} + SDL_Renderer * SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags) { @@ -796,7 +923,7 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags) #endif if (!window) { - SDL_SetError("Invalid window"); + SDL_InvalidParamError("window"); goto error; } @@ -805,7 +932,8 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags) goto error; } - if (SDL_GetHint(SDL_HINT_RENDER_VSYNC)) { + hint = SDL_GetHint(SDL_HINT_RENDER_VSYNC); + if (hint && *hint) { if (SDL_GetHintBoolean(SDL_HINT_RENDER_VSYNC, SDL_TRUE)) { flags |= SDL_RENDERER_PRESENTVSYNC; } else { @@ -844,24 +972,24 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags) } } } - if (index == n) { + if (!renderer) { SDL_SetError("Couldn't find matching render driver"); goto error; } } else { - if (index >= SDL_GetNumRenderDrivers()) { + if (index >= n) { SDL_SetError("index must be -1 or in the range of 0 - %d", - SDL_GetNumRenderDrivers() - 1); + n - 1); goto error; } /* Create a new renderer instance */ renderer = render_drivers[index]->CreateRenderer(window, flags); batching = SDL_FALSE; + if (!renderer) { + goto error; + } } - if (!renderer) { - goto error; - } VerifyDrawQueueFunctions(renderer); @@ -896,6 +1024,8 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags) renderer->relative_scaling = SDL_GetHintBoolean(SDL_HINT_MOUSE_RELATIVE_SCALING, SDL_TRUE); + renderer->line_method = SDL_GetRenderLineMethod(); + if (SDL_GetWindowFlags(window) & (SDL_WINDOW_HIDDEN|SDL_WINDOW_MINIMIZED)) { renderer->hidden = SDL_TRUE; } else { @@ -947,6 +1077,9 @@ SDL_CreateSoftwareRenderer(SDL_Surface * surface) /* new textures start at zero, so we start at 1 so first render doesn't flush by accident. */ renderer->render_command_generation = 1; + /* Software renderer always uses line method, for speed */ + renderer->line_method = SDL_RENDERLINEMETHOD_LINES; + SDL_RenderSetViewport(renderer, NULL); } return renderer; @@ -1066,6 +1199,7 @@ SDL_Texture * SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h) { SDL_Texture *texture; + SDL_bool texture_is_fourcc_and_target; CHECK_RENDERER_MAGIC(renderer, NULL); @@ -1077,8 +1211,10 @@ SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int return NULL; } if (SDL_ISPIXELFORMAT_INDEXED(format)) { - SDL_SetError("Palettized textures are not supported"); - return NULL; + if (!IsSupportedFormat(renderer, format)) { + SDL_SetError("Palettized textures are not supported"); + return NULL; + } } if (w <= 0 || h <= 0) { SDL_SetError("Texture dimensions can't be 0"); @@ -1099,10 +1235,10 @@ SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int texture->access = access; texture->w = w; texture->h = h; - texture->r = 255; - texture->g = 255; - texture->b = 255; - texture->a = 255; + texture->color.r = 255; + texture->color.g = 255; + texture->color.b = 255; + texture->color.a = 255; texture->scaleMode = SDL_GetScaleMode(); texture->renderer = renderer; texture->next = renderer->textures; @@ -1111,15 +1247,24 @@ SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int } renderer->textures = texture; - if (IsSupportedFormat(renderer, format)) { + /* FOURCC format cannot be used directly by renderer back-ends for target texture */ + texture_is_fourcc_and_target = (access == SDL_TEXTUREACCESS_TARGET && SDL_ISPIXELFORMAT_FOURCC(texture->format)); + + if (texture_is_fourcc_and_target == SDL_FALSE && IsSupportedFormat(renderer, format)) { if (renderer->CreateTexture(renderer, texture) < 0) { SDL_DestroyTexture(texture); return NULL; } } else { - texture->native = SDL_CreateTexture(renderer, - GetClosestSupportedFormat(renderer, format), - access, w, h); + int closest_format; + + if (texture_is_fourcc_and_target == SDL_FALSE) { + closest_format = GetClosestSupportedFormat(renderer, format); + } else { + closest_format = renderer->info.texture_formats[0]; + } + + texture->native = SDL_CreateTexture(renderer, closest_format, access, w, h); if (!texture->native) { SDL_DestroyTexture(texture); return NULL; @@ -1174,7 +1319,7 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface) CHECK_RENDERER_MAGIC(renderer, NULL); if (!surface) { - SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); + SDL_InvalidParamError("SDL_CreateTextureFromSurface(): surface"); return NULL; } @@ -1263,6 +1408,18 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface) } else { SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch); } + +#if SDL_VIDEO_RENDER_DIRECTFB + /* DirectFB allows palette format for textures. + * Copy SDL_Surface palette to the texture */ + if (SDL_ISPIXELFORMAT_INDEXED(format)) { + if (SDL_strcasecmp(renderer->info.name, "directfb") == 0) { + extern void DirectFB_SetTexturePalette(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Palette *pal); + DirectFB_SetTexturePalette(renderer, texture, surface->format->palette); + } + } +#endif + } else { SDL_PixelFormat *dst_fmt; SDL_Surface *temp = NULL; @@ -1336,9 +1493,9 @@ SDL_SetTextureColorMod(SDL_Texture * texture, Uint8 r, Uint8 g, Uint8 b) } else { texture->modMode &= ~SDL_TEXTUREMODULATE_COLOR; } - texture->r = r; - texture->g = g; - texture->b = b; + texture->color.r = r; + texture->color.g = g; + texture->color.b = b; if (texture->native) { return SDL_SetTextureColorMod(texture->native, r, g, b); } @@ -1352,13 +1509,13 @@ SDL_GetTextureColorMod(SDL_Texture * texture, Uint8 * r, Uint8 * g, CHECK_TEXTURE_MAGIC(texture, -1); if (r) { - *r = texture->r; + *r = texture->color.r; } if (g) { - *g = texture->g; + *g = texture->color.g; } if (b) { - *b = texture->b; + *b = texture->color.b; } return 0; } @@ -1373,7 +1530,7 @@ SDL_SetTextureAlphaMod(SDL_Texture * texture, Uint8 alpha) } else { texture->modMode &= ~SDL_TEXTUREMODULATE_ALPHA; } - texture->a = alpha; + texture->color.a = alpha; if (texture->native) { return SDL_SetTextureAlphaMod(texture->native, alpha); } @@ -1386,7 +1543,7 @@ SDL_GetTextureAlphaMod(SDL_Texture * texture, Uint8 * alpha) CHECK_TEXTURE_MAGIC(texture, -1); if (alpha) { - *alpha = texture->a; + *alpha = texture->color.a; } return 0; } @@ -1447,6 +1604,23 @@ SDL_GetTextureScaleMode(SDL_Texture * texture, SDL_ScaleMode *scaleMode) return 0; } +int +SDL_SetTextureUserData(SDL_Texture * texture, void *userdata) +{ + CHECK_TEXTURE_MAGIC(texture, -1); + + texture->userdata = userdata; + return 0; +} + +void * +SDL_GetTextureUserData(SDL_Texture * texture) +{ + CHECK_TEXTURE_MAGIC(texture, NULL); + + return texture->userdata; +} + #if SDL_HAVE_YUV static int SDL_UpdateTextureYUV(SDL_Texture * texture, const SDL_Rect * rect, @@ -1540,7 +1714,7 @@ int SDL_UpdateTexture(SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { - SDL_Rect full_rect; + SDL_Rect real_rect; CHECK_TEXTURE_MAGIC(texture, -1); @@ -1551,28 +1725,30 @@ SDL_UpdateTexture(SDL_Texture * texture, const SDL_Rect * rect, return SDL_InvalidParamError("pitch"); } - if (!rect) { - full_rect.x = 0; - full_rect.y = 0; - full_rect.w = texture->w; - full_rect.h = texture->h; - rect = &full_rect; + real_rect.x = 0; + real_rect.y = 0; + real_rect.w = texture->w; + real_rect.h = texture->h; + if (rect) { + if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) { + return 0; + } } - if ((rect->w == 0) || (rect->h == 0)) { + if (real_rect.w == 0 || real_rect.h == 0) { return 0; /* nothing to do. */ #if SDL_HAVE_YUV } else if (texture->yuv) { - return SDL_UpdateTextureYUV(texture, rect, pixels, pitch); + return SDL_UpdateTextureYUV(texture, &real_rect, pixels, pitch); #endif } else if (texture->native) { - return SDL_UpdateTextureNative(texture, rect, pixels, pitch); + return SDL_UpdateTextureNative(texture, &real_rect, pixels, pitch); } else { SDL_Renderer *renderer = texture->renderer; if (FlushRenderCommandsIfTextureNeeded(texture) < 0) { return -1; } - return renderer->UpdateTexture(renderer, texture, rect, pixels, pitch); + return renderer->UpdateTexture(renderer, texture, &real_rect, pixels, pitch); } } @@ -1628,6 +1804,59 @@ SDL_UpdateTextureYUVPlanar(SDL_Texture * texture, const SDL_Rect * rect, } return 0; } + +static int +SDL_UpdateTextureNVPlanar(SDL_Texture * texture, const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ + SDL_Texture *native = texture->native; + SDL_Rect full_rect; + + if (SDL_SW_UpdateNVTexturePlanar(texture->yuv, rect, Yplane, Ypitch, UVplane, UVpitch) < 0) { + return -1; + } + + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = texture->w; + full_rect.h = texture->h; + rect = &full_rect; + + if (!rect->w || !rect->h) { + return 0; /* nothing to do. */ + } + + if (texture->access == SDL_TEXTUREACCESS_STREAMING) { + /* We can lock the texture and copy to it */ + void *native_pixels = NULL; + int native_pitch = 0; + + if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) { + return -1; + } + SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format, + rect->w, rect->h, native_pixels, native_pitch); + SDL_UnlockTexture(native); + } else { + /* Use a temporary buffer for updating */ + const int temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3); + const size_t alloclen = rect->h * temp_pitch; + if (alloclen > 0) { + void *temp_pixels = SDL_malloc(alloclen); + if (!temp_pixels) { + return SDL_OutOfMemory(); + } + SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format, + rect->w, rect->h, temp_pixels, temp_pitch); + SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch); + SDL_free(temp_pixels); + } + } + return 0; +} + + #endif /* SDL_HAVE_YUV */ int SDL_UpdateYUVTexture(SDL_Texture * texture, const SDL_Rect * rect, @@ -1637,7 +1866,7 @@ int SDL_UpdateYUVTexture(SDL_Texture * texture, const SDL_Rect * rect, { #if SDL_HAVE_YUV SDL_Renderer *renderer; - SDL_Rect full_rect; + SDL_Rect real_rect; CHECK_TEXTURE_MAGIC(texture, -1); @@ -1665,20 +1894,20 @@ int SDL_UpdateYUVTexture(SDL_Texture * texture, const SDL_Rect * rect, return SDL_SetError("Texture format must by YV12 or IYUV"); } - if (!rect) { - full_rect.x = 0; - full_rect.y = 0; - full_rect.w = texture->w; - full_rect.h = texture->h; - rect = &full_rect; + real_rect.x = 0; + real_rect.y = 0; + real_rect.w = texture->w; + real_rect.h = texture->h; + if (rect) { + SDL_IntersectRect(rect, &real_rect, &real_rect); } - if (!rect->w || !rect->h) { + if (real_rect.w == 0 || real_rect.h == 0) { return 0; /* nothing to do. */ } if (texture->yuv) { - return SDL_UpdateTextureYUVPlanar(texture, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch); + return SDL_UpdateTextureYUVPlanar(texture, &real_rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch); } else { SDL_assert(!texture->native); renderer = texture->renderer; @@ -1687,7 +1916,7 @@ int SDL_UpdateYUVTexture(SDL_Texture * texture, const SDL_Rect * rect, if (FlushRenderCommandsIfTextureNeeded(texture) < 0) { return -1; } - return renderer->UpdateTextureYUV(renderer, texture, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch); + return renderer->UpdateTextureYUV(renderer, texture, &real_rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch); } else { return SDL_Unsupported(); } @@ -1697,6 +1926,68 @@ int SDL_UpdateYUVTexture(SDL_Texture * texture, const SDL_Rect * rect, #endif } +int SDL_UpdateNVTexture(SDL_Texture * texture, const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ +#if SDL_HAVE_YUV + SDL_Renderer *renderer; + SDL_Rect real_rect; + + CHECK_TEXTURE_MAGIC(texture, -1); + + if (!Yplane) { + return SDL_InvalidParamError("Yplane"); + } + if (!Ypitch) { + return SDL_InvalidParamError("Ypitch"); + } + if (!UVplane) { + return SDL_InvalidParamError("UVplane"); + } + if (!UVpitch) { + return SDL_InvalidParamError("UVpitch"); + } + + if (texture->format != SDL_PIXELFORMAT_NV12 && + texture->format != SDL_PIXELFORMAT_NV21) { + return SDL_SetError("Texture format must by NV12 or NV21"); + } + + real_rect.x = 0; + real_rect.y = 0; + real_rect.w = texture->w; + real_rect.h = texture->h; + if (rect) { + SDL_IntersectRect(rect, &real_rect, &real_rect); + } + + if (real_rect.w == 0 || real_rect.h == 0) { + return 0; /* nothing to do. */ + } + + if (texture->yuv) { + return SDL_UpdateTextureNVPlanar(texture, &real_rect, Yplane, Ypitch, UVplane, UVpitch); + } else { + SDL_assert(!texture->native); + renderer = texture->renderer; + SDL_assert(renderer->UpdateTextureNV); + if (renderer->UpdateTextureNV) { + if (FlushRenderCommandsIfTextureNeeded(texture) < 0) { + return -1; + } + return renderer->UpdateTextureNV(renderer, texture, &real_rect, Yplane, Ypitch, UVplane, UVpitch); + } else { + return SDL_Unsupported(); + } + } +#else + return -1; +#endif +} + + + #if SDL_HAVE_YUV static int SDL_LockTextureYUV(SDL_Texture * texture, const SDL_Rect * rect, @@ -1775,7 +2066,6 @@ SDL_LockTextureToSurface(SDL_Texture *texture, const SDL_Rect *rect, real_rect.y = 0; real_rect.w = texture->w; real_rect.h = texture->h; - if (rect) { SDL_IntersectRect(rect, &real_rect, &real_rect); } @@ -1920,10 +2210,10 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) } if (texture) { - renderer->viewport.x = 0; - renderer->viewport.y = 0; - renderer->viewport.w = texture->w; - renderer->viewport.h = texture->h; + renderer->viewport.x = 0.0f; + renderer->viewport.y = 0.0f; + renderer->viewport.w = (float) texture->w; + renderer->viewport.h = (float) texture->h; SDL_zero(renderer->clip_rect); renderer->clipping_enabled = SDL_FALSE; renderer->scale.x = 1.0f; @@ -2007,9 +2297,14 @@ UpdateLogicalSize(SDL_Renderer *renderer) } else { scale = (float)(h / renderer->logical_h); } - viewport.w = (int)SDL_ceil(renderer->logical_w * scale); + + if (scale < 1.0f) { + scale = 1.0f; + } + + viewport.w = (int)SDL_floor(renderer->logical_w * scale); viewport.x = (w - viewport.w) / 2; - viewport.h = (int)SDL_ceil(renderer->logical_h * scale); + viewport.h = (int)SDL_floor(renderer->logical_h * scale); viewport.y = (h - viewport.h) / 2; SDL_RenderSetViewport(renderer, &viewport); @@ -2026,7 +2321,7 @@ UpdateLogicalSize(SDL_Renderer *renderer) scale = (float)h / renderer->logical_h; viewport.y = 0; viewport.h = h; - viewport.w = (int)SDL_ceil(renderer->logical_w * scale); + viewport.w = (int)SDL_floor(renderer->logical_w * scale); viewport.x = (w - viewport.w) / 2; SDL_RenderSetViewport(renderer, &viewport); } else { @@ -2034,7 +2329,7 @@ UpdateLogicalSize(SDL_Renderer *renderer) scale = (float)w / renderer->logical_w; viewport.x = 0; viewport.w = w; - viewport.h = (int)SDL_ceil(renderer->logical_h * scale); + viewport.h = (int)SDL_floor(renderer->logical_h * scale); viewport.y = (h - viewport.h) / 2; SDL_RenderSetViewport(renderer, &viewport); } @@ -2047,7 +2342,7 @@ UpdateLogicalSize(SDL_Renderer *renderer) scale = (float)w / renderer->logical_w; viewport.x = 0; viewport.w = w; - viewport.h = (int)SDL_ceil(renderer->logical_h * scale); + viewport.h = (int)SDL_floor(renderer->logical_h * scale); viewport.y = (h - viewport.h) / 2; SDL_RenderSetViewport(renderer, &viewport); } else { @@ -2055,7 +2350,7 @@ UpdateLogicalSize(SDL_Renderer *renderer) scale = (float)h / renderer->logical_h; viewport.y = 0; viewport.h = h; - viewport.w = (int)SDL_ceil(renderer->logical_w * scale); + viewport.w = (int)SDL_floor(renderer->logical_w * scale); viewport.x = (w - viewport.w) / 2; SDL_RenderSetViewport(renderer, &viewport); } @@ -2125,16 +2420,19 @@ SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect) CHECK_RENDERER_MAGIC(renderer, -1); if (rect) { - renderer->viewport.x = (int)SDL_floor(rect->x * renderer->scale.x); - renderer->viewport.y = (int)SDL_floor(rect->y * renderer->scale.y); - renderer->viewport.w = (int)SDL_ceil(rect->w * renderer->scale.x); - renderer->viewport.h = (int)SDL_ceil(rect->h * renderer->scale.y); + renderer->viewport.x = rect->x * renderer->scale.x; + renderer->viewport.y = rect->y * renderer->scale.y; + renderer->viewport.w = rect->w * renderer->scale.x; + renderer->viewport.h = rect->h * renderer->scale.y; } else { - renderer->viewport.x = 0; - renderer->viewport.y = 0; - if (SDL_GetRendererOutputSize(renderer, &renderer->viewport.w, &renderer->viewport.h) < 0) { + int w, h; + if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) { return -1; } + renderer->viewport.x = 0.0f; + renderer->viewport.y = 0.0f; + renderer->viewport.w = (float) w; + renderer->viewport.h = (float) h; } retval = QueueCmdSetViewport(renderer); return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); @@ -2146,13 +2444,22 @@ SDL_RenderGetViewport(SDL_Renderer * renderer, SDL_Rect * rect) CHECK_RENDERER_MAGIC(renderer, ); if (rect) { - rect->x = (int)(renderer->viewport.x / renderer->scale.x); - rect->y = (int)(renderer->viewport.y / renderer->scale.y); - rect->w = (int)(renderer->viewport.w / renderer->scale.x); - rect->h = (int)(renderer->viewport.h / renderer->scale.y); + rect->x = (int)SDL_floor(renderer->viewport.x / renderer->scale.x); + rect->y = (int)SDL_floor(renderer->viewport.y / renderer->scale.y); + rect->w = (int)SDL_floor(renderer->viewport.w / renderer->scale.x); + rect->h = (int)SDL_floor(renderer->viewport.h / renderer->scale.y); } } +static void +RenderGetViewportSize(SDL_Renderer * renderer, SDL_FRect * rect) +{ + rect->x = 0.0f; + rect->y = 0.0f; + rect->w = renderer->viewport.w / renderer->scale.x; + rect->h = renderer->viewport.h / renderer->scale.y; +} + int SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect) { @@ -2161,10 +2468,10 @@ SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect) if (rect) { renderer->clipping_enabled = SDL_TRUE; - renderer->clip_rect.x = (int)SDL_floor(rect->x * renderer->scale.x); - renderer->clip_rect.y = (int)SDL_floor(rect->y * renderer->scale.y); - renderer->clip_rect.w = (int)SDL_ceil(rect->w * renderer->scale.x); - renderer->clip_rect.h = (int)SDL_ceil(rect->h * renderer->scale.y); + renderer->clip_rect.x = rect->x * renderer->scale.x; + renderer->clip_rect.y = rect->y * renderer->scale.y; + renderer->clip_rect.w = rect->w * renderer->scale.x; + renderer->clip_rect.h = rect->h * renderer->scale.y; } else { renderer->clipping_enabled = SDL_FALSE; SDL_zero(renderer->clip_rect); @@ -2180,10 +2487,10 @@ SDL_RenderGetClipRect(SDL_Renderer * renderer, SDL_Rect * rect) CHECK_RENDERER_MAGIC(renderer, ) if (rect) { - rect->x = (int)(renderer->clip_rect.x / renderer->scale.x); - rect->y = (int)(renderer->clip_rect.y / renderer->scale.y); - rect->w = (int)(renderer->clip_rect.w / renderer->scale.x); - rect->h = (int)(renderer->clip_rect.h / renderer->scale.y); + rect->x = (int)SDL_floor(renderer->clip_rect.x / renderer->scale.x); + rect->y = (int)SDL_floor(renderer->clip_rect.y / renderer->scale.y); + rect->w = (int)SDL_floor(renderer->clip_rect.w / renderer->scale.x); + rect->h = (int)SDL_floor(renderer->clip_rect.h / renderer->scale.y); } } @@ -2217,16 +2524,52 @@ SDL_RenderGetScale(SDL_Renderer * renderer, float *scaleX, float *scaleY) } } +void +SDL_RenderWindowToLogical(SDL_Renderer * renderer, int windowX, int windowY, float *logicalX, float *logicalY) +{ + float window_physical_x, window_physical_y; + + CHECK_RENDERER_MAGIC(renderer, ); + + window_physical_x = ((float) windowX) / renderer->dpi_scale.x; + window_physical_y = ((float) windowY) / renderer->dpi_scale.y; + + if (logicalX) { + *logicalX = (window_physical_x - renderer->viewport.x) / renderer->scale.x; + } + if (logicalY) { + *logicalY = (window_physical_y - renderer->viewport.y) / renderer->scale.y; + } +} + +void +SDL_RenderLogicalToWindow(SDL_Renderer * renderer, float logicalX, float logicalY, int *windowX, int *windowY) +{ + float window_physical_x, window_physical_y; + + CHECK_RENDERER_MAGIC(renderer, ); + + window_physical_x = (logicalX * renderer->scale.x) + renderer->viewport.x; + window_physical_y = (logicalY * renderer->scale.y) + renderer->viewport.y; + + if (windowX) { + *windowX = (int)(window_physical_x * renderer->dpi_scale.x); + } + if (windowY) { + *windowY = (int)(window_physical_y * renderer->dpi_scale.y); + } +} + int SDL_SetRenderDrawColor(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { CHECK_RENDERER_MAGIC(renderer, -1); - renderer->r = r; - renderer->g = g; - renderer->b = b; - renderer->a = a; + renderer->color.r = r; + renderer->color.g = g; + renderer->color.b = b; + renderer->color.a = a; return 0; } @@ -2237,16 +2580,16 @@ SDL_GetRenderDrawColor(SDL_Renderer * renderer, CHECK_RENDERER_MAGIC(renderer, -1); if (r) { - *r = renderer->r; + *r = renderer->color.r; } if (g) { - *g = renderer->g; + *g = renderer->color.g; } if (b) { - *b = renderer->b; + *b = renderer->color.b; } if (a) { - *a = renderer->a; + *a = renderer->color.a; } return 0; } @@ -2323,11 +2666,13 @@ RenderDrawPointsWithRects(SDL_Renderer * renderer, frects[i].h = renderer->scale.y; } - retval = QueueCmdFillRects(renderer, frects, count); + if (count) { + retval = QueueCmdFillRects(renderer, frects, count); + } SDL_small_free(frects, isstack); - return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); + return retval; } int @@ -2342,34 +2687,35 @@ SDL_RenderDrawPoints(SDL_Renderer * renderer, CHECK_RENDERER_MAGIC(renderer, -1); if (!points) { - return SDL_SetError("SDL_RenderDrawPoints(): Passed NULL points"); + return SDL_InvalidParamError("SDL_RenderDrawPoints(): points"); } if (count < 1) { return 0; } +#if DONT_DRAW_WHILE_HIDDEN /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; } +#endif if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { - return RenderDrawPointsWithRects(renderer, points, count); + retval = RenderDrawPointsWithRects(renderer, points, count); + } else { + fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack); + if (!fpoints) { + return SDL_OutOfMemory(); + } + for (i = 0; i < count; ++i) { + fpoints[i].x = (float) points[i].x; + fpoints[i].y = (float) points[i].y; + } + + retval = QueueCmdDrawPoints(renderer, fpoints, count); + + SDL_small_free(fpoints, isstack); } - - fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack); - if (!fpoints) { - return SDL_OutOfMemory(); - } - for (i = 0; i < count; ++i) { - fpoints[i].x = points[i].x * renderer->scale.x; - fpoints[i].y = points[i].y * renderer->scale.y; - } - - retval = QueueCmdDrawPoints(renderer, fpoints, count); - - SDL_small_free(fpoints, isstack); - return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); } @@ -2393,53 +2739,42 @@ RenderDrawPointsWithRectsF(SDL_Renderer * renderer, frects[i].h = renderer->scale.y; } - retval = QueueCmdFillRects(renderer, frects, count); + if (count) { + retval = QueueCmdFillRects(renderer, frects, count); + } SDL_small_free(frects, isstack); - return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); + return retval; } int SDL_RenderDrawPointsF(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { - SDL_FPoint *fpoints; - int i; int retval; - SDL_bool isstack; CHECK_RENDERER_MAGIC(renderer, -1); if (!points) { - return SDL_SetError("SDL_RenderDrawFPoints(): Passed NULL points"); + return SDL_InvalidParamError("SDL_RenderDrawPointsF(): points"); } if (count < 1) { return 0; } +#if DONT_DRAW_WHILE_HIDDEN /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; } +#endif if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { - return RenderDrawPointsWithRectsF(renderer, points, count); + retval = RenderDrawPointsWithRectsF(renderer, points, count); + } else { + retval = QueueCmdDrawPoints(renderer, points, count); } - - fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack); - if (!fpoints) { - return SDL_OutOfMemory(); - } - for (i = 0; i < count; ++i) { - fpoints[i].x = points[i].x * renderer->scale.x; - fpoints[i].y = points[i].y * renderer->scale.y; - } - - retval = QueueCmdDrawPoints(renderer, fpoints, count); - - SDL_small_free(fpoints, isstack); - return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); } @@ -2465,71 +2800,98 @@ SDL_RenderDrawLineF(SDL_Renderer * renderer, float x1, float y1, float x2, float return SDL_RenderDrawLinesF(renderer, points, 2); } -static int -RenderDrawLinesWithRects(SDL_Renderer * renderer, - const SDL_Point * points, const int count) +static int RenderDrawLineBresenham(SDL_Renderer *renderer, int x1, int y1, int x2, int y2, SDL_bool draw_last) { - SDL_FRect *frect; - SDL_FRect *frects; - SDL_FPoint fpoints[2]; - int i, nrects = 0; - int retval = 0; + int i, deltax, deltay, numpixels; + int d, dinc1, dinc2; + int x, xinc1, xinc2; + int y, yinc1, yinc2; + int retval; SDL_bool isstack; + SDL_FPoint *points; - frects = SDL_small_alloc(SDL_FRect, count-1, &isstack); - if (!frects) { - return SDL_OutOfMemory(); + deltax = SDL_abs(x2 - x1); + deltay = SDL_abs(y2 - y1); + + if (deltax >= deltay) { + numpixels = deltax + 1; + d = (2 * deltay) - deltax; + dinc1 = deltay * 2; + dinc2 = (deltay - deltax) * 2; + xinc1 = 1; + xinc2 = 1; + yinc1 = 0; + yinc2 = 1; + } else { + numpixels = deltay + 1; + d = (2 * deltax) - deltay; + dinc1 = deltax * 2; + dinc2 = (deltax - deltay) * 2; + xinc1 = 0; + xinc2 = 1; + yinc1 = 1; + yinc2 = 1; } - for (i = 0; i < count-1; ++i) { - if (points[i].x == points[i+1].x) { - const int minY = SDL_min(points[i].y, points[i+1].y); - const int maxY = SDL_max(points[i].y, points[i+1].y); + if (x1 > x2) { + xinc1 = -xinc1; + xinc2 = -xinc2; + } + if (y1 > y2) { + yinc1 = -yinc1; + yinc2 = -yinc2; + } - frect = &frects[nrects++]; - frect->x = points[i].x * renderer->scale.x; - frect->y = minY * renderer->scale.y; - frect->w = renderer->scale.x; - frect->h = (maxY - minY + 1) * renderer->scale.y; - } else if (points[i].y == points[i+1].y) { - const int minX = SDL_min(points[i].x, points[i+1].x); - const int maxX = SDL_max(points[i].x, points[i+1].x); + x = x1; + y = y1; - frect = &frects[nrects++]; - frect->x = minX * renderer->scale.x; - frect->y = points[i].y * renderer->scale.y; - frect->w = (maxX - minX + 1) * renderer->scale.x; - frect->h = renderer->scale.y; + if (!draw_last) { + --numpixels; + } + + points = SDL_small_alloc(SDL_FPoint, numpixels, &isstack); + if (!points) { + return SDL_OutOfMemory(); + } + for (i = 0; i < numpixels; ++i) { + points[i].x = (float)x; + points[i].y = (float)y; + + if (d < 0) { + d += dinc1; + x += xinc1; + y += yinc1; } else { - /* FIXME: We can't use a rect for this line... */ - fpoints[0].x = points[i].x * renderer->scale.x; - fpoints[0].y = points[i].y * renderer->scale.y; - fpoints[1].x = points[i+1].x * renderer->scale.x; - fpoints[1].y = points[i+1].y * renderer->scale.y; - retval += QueueCmdDrawLines(renderer, fpoints, 2); + d += dinc2; + x += xinc2; + y += yinc2; } } - retval += QueueCmdFillRects(renderer, frects, nrects); - - SDL_small_free(frects, isstack); - - if (retval < 0) { - retval = -1; + if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { + retval = RenderDrawPointsWithRectsF(renderer, points, numpixels); + } else { + retval = QueueCmdDrawPoints(renderer, points, numpixels); } - return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); + + SDL_small_free(points, isstack); + + return retval; } static int RenderDrawLinesWithRectsF(SDL_Renderer * renderer, const SDL_FPoint * points, const int count) { + const float scale_x = renderer->scale.x; + const float scale_y = renderer->scale.y; SDL_FRect *frect; SDL_FRect *frects; - SDL_FPoint fpoints[2]; int i, nrects = 0; int retval = 0; SDL_bool isstack; + SDL_bool drew_line = SDL_FALSE; + SDL_bool draw_last = SDL_FALSE; frects = SDL_small_alloc(SDL_FRect, count-1, &isstack); if (!frects) { @@ -2537,42 +2899,59 @@ RenderDrawLinesWithRectsF(SDL_Renderer * renderer, } for (i = 0; i < count-1; ++i) { - if (points[i].x == points[i+1].x) { - const int minY = (int)SDL_min(points[i].y, points[i+1].y); - const int maxY = (int)SDL_max(points[i].y, points[i+1].y); + SDL_bool same_x = (points[i].x == points[i+1].x); + SDL_bool same_y = (points[i].y == points[i+1].y); - frect = &frects[nrects++]; - frect->x = points[i].x * renderer->scale.x; - frect->y = minY * renderer->scale.y; - frect->w = renderer->scale.x; - frect->h = (maxY - minY + 1) * renderer->scale.y; - } else if (points[i].y == points[i+1].y) { - const int minX = (int)SDL_min(points[i].x, points[i+1].x); - const int maxX = (int)SDL_max(points[i].x, points[i+1].x); - - frect = &frects[nrects++]; - frect->x = minX * renderer->scale.x; - frect->y = points[i].y * renderer->scale.y; - frect->w = (maxX - minX + 1) * renderer->scale.x; - frect->h = renderer->scale.y; + if (i == (count - 2)) { + if (!drew_line || points[i+1].x != points[0].x || points[i+1].y != points[0].y) { + draw_last = SDL_TRUE; + } } else { - /* FIXME: We can't use a rect for this line... */ - fpoints[0].x = points[i].x * renderer->scale.x; - fpoints[0].y = points[i].y * renderer->scale.y; - fpoints[1].x = points[i+1].x * renderer->scale.x; - fpoints[1].y = points[i+1].y * renderer->scale.y; - retval += QueueCmdDrawLines(renderer, fpoints, 2); + if (same_x && same_y) { + continue; + } } + if (same_x) { + const float minY = SDL_min(points[i].y, points[i+1].y); + const float maxY = SDL_max(points[i].y, points[i+1].y); + + frect = &frects[nrects++]; + frect->x = points[i].x * scale_x; + frect->y = minY * scale_y; + frect->w = scale_x; + frect->h = (maxY - minY + draw_last) * scale_y; + if (!draw_last && points[i+1].y < points[i].y) { + frect->y += scale_y; + } + } else if (same_y) { + const float minX = SDL_min(points[i].x, points[i+1].x); + const float maxX = SDL_max(points[i].x, points[i+1].x); + + frect = &frects[nrects++]; + frect->x = minX * scale_x; + frect->y = points[i].y * scale_y; + frect->w = (maxX - minX + draw_last) * scale_x; + frect->h = scale_y; + if (!draw_last && points[i+1].x < points[i].x) { + frect->x += scale_x; + } + } else { + retval += RenderDrawLineBresenham(renderer, (int)points[i].x, (int)points[i].y, + (int)points[i+1].x, (int)points[i+1].y, draw_last); + } + drew_line = SDL_TRUE; } - retval += QueueCmdFillRects(renderer, frects, nrects); + if (nrects) { + retval += QueueCmdFillRects(renderer, frects, nrects); + } SDL_small_free(frects, isstack); if (retval < 0) { retval = -1; } - return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); + return retval; } int @@ -2587,77 +2966,188 @@ SDL_RenderDrawLines(SDL_Renderer * renderer, CHECK_RENDERER_MAGIC(renderer, -1); if (!points) { - return SDL_SetError("SDL_RenderDrawLines(): Passed NULL points"); + return SDL_InvalidParamError("SDL_RenderDrawLines(): points"); } if (count < 2) { return 0; } +#if DONT_DRAW_WHILE_HIDDEN /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; } - - if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { - return RenderDrawLinesWithRects(renderer, points, count); - } +#endif fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack); if (!fpoints) { return SDL_OutOfMemory(); } + for (i = 0; i < count; ++i) { - fpoints[i].x = points[i].x * renderer->scale.x; - fpoints[i].y = points[i].y * renderer->scale.y; + fpoints[i].x = (float) points[i].x; + fpoints[i].y = (float) points[i].y; } - retval = QueueCmdDrawLines(renderer, fpoints, count); + retval = SDL_RenderDrawLinesF(renderer, fpoints, count); SDL_small_free(fpoints, isstack); - return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); + return retval; } int SDL_RenderDrawLinesF(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { - SDL_FPoint *fpoints; - int i; - int retval; - SDL_bool isstack; + int retval = 0; CHECK_RENDERER_MAGIC(renderer, -1); if (!points) { - return SDL_SetError("SDL_RenderDrawLines(): Passed NULL points"); + return SDL_InvalidParamError("SDL_RenderDrawLinesF(): points"); } if (count < 2) { return 0; } +#if DONT_DRAW_WHILE_HIDDEN /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; } +#endif - if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { - return RenderDrawLinesWithRectsF(renderer, points, count); + if (renderer->line_method == SDL_RENDERLINEMETHOD_POINTS) { + retval = RenderDrawLinesWithRectsF(renderer, points, count); + } else if (renderer->line_method == SDL_RENDERLINEMETHOD_GEOMETRY) { + SDL_bool isstack1; + SDL_bool isstack2; + const float scale_x = renderer->scale.x; + const float scale_y = renderer->scale.y; + float *xy = SDL_small_alloc(float, 4 * 2 * count, &isstack1); + int *indices = SDL_small_alloc(int, + (4) * 3 * (count - 1) + + (2) * 3 * (count) + , &isstack2); + + if (xy && indices) { + int i; + float *ptr_xy = xy; + int *ptr_indices = indices; + const int xy_stride = 2 * sizeof (float); + int num_vertices = 4 * count; + int num_indices = 0; + const int size_indices = 4; + int cur_indice = -4; + const int is_looping = (points[0].x == points[count - 1].x && points[0].y == points[count - 1].y); + SDL_FPoint p; /* previous point */ + p.x = p.y = 0.0f; + /* p q + + 0----1------ 4----5 + | \ |``\ | \ | + | \ | ` `\| \ | + 3----2-------7----6 + */ + for (i = 0; i < count; ++i) { + SDL_FPoint q = points[i]; /* current point */ + + q.x *= scale_x; + q.y *= scale_y; + + *ptr_xy++ = q.x; + *ptr_xy++ = q.y; + *ptr_xy++ = q.x + scale_x; + *ptr_xy++ = q.y; + *ptr_xy++ = q.x + scale_x; + *ptr_xy++ = q.y + scale_y; + *ptr_xy++ = q.x; + *ptr_xy++ = q.y + scale_y; + +#define ADD_TRIANGLE(i1, i2, i3) \ + *ptr_indices++ = cur_indice + i1; \ + *ptr_indices++ = cur_indice + i2; \ + *ptr_indices++ = cur_indice + i3; \ + num_indices += 3; \ + + /* closed polyline, don´t draw twice the point */ + if (i || is_looping == 0) { + ADD_TRIANGLE(4, 5, 6) + ADD_TRIANGLE(4, 6, 7) + } + + /* first point only, no segment */ + if (i == 0) { + p = q; + cur_indice += 4; + continue; + } + + /* draw segment */ + if (p.y == q.y) { + if (p.x < q.x) { + ADD_TRIANGLE(1, 4, 7) + ADD_TRIANGLE(1, 7, 2) + } else { + ADD_TRIANGLE(5, 0, 3) + ADD_TRIANGLE(5, 3, 6) + } + } else if (p.x == q.x) { + if (p.y < q.y) { + ADD_TRIANGLE(2, 5, 4) + ADD_TRIANGLE(2, 4, 3) + } else { + ADD_TRIANGLE(6, 1, 0) + ADD_TRIANGLE(6, 0, 7) + } + } else { + if (p.y < q.y) { + if (p.x < q.x) { + ADD_TRIANGLE(1, 5, 4) + ADD_TRIANGLE(1, 4, 2) + ADD_TRIANGLE(2, 4, 7) + ADD_TRIANGLE(2, 7, 3) + } else { + ADD_TRIANGLE(4, 0, 5) + ADD_TRIANGLE(5, 0, 3) + ADD_TRIANGLE(5, 3, 6) + ADD_TRIANGLE(6, 3, 2) + } + } else { + if (p.x < q.x) { + ADD_TRIANGLE(0, 4, 7) + ADD_TRIANGLE(0, 7, 1) + ADD_TRIANGLE(1, 7, 6) + ADD_TRIANGLE(1, 6, 2) + } else { + ADD_TRIANGLE(6, 5, 1) + ADD_TRIANGLE(6, 1, 0) + ADD_TRIANGLE(7, 6, 0) + ADD_TRIANGLE(7, 0, 3) + } + } + } + + p = q; + cur_indice += 4; + } + + retval = QueueCmdGeometry(renderer, NULL, + xy, xy_stride, &renderer->color, 0 /* color_stride */, NULL, 0, + num_vertices, indices, num_indices, size_indices, + 1.0f, 1.0f); + + SDL_small_free(xy, isstack1); + SDL_small_free(indices, isstack2); + } + + } else if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { + retval = RenderDrawLinesWithRectsF(renderer, points, count); + } else { + retval = QueueCmdDrawLines(renderer, points, count); } - fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack); - if (!fpoints) { - return SDL_OutOfMemory(); - } - for (i = 0; i < count; ++i) { - fpoints[i].x = points[i].x * renderer->scale.x; - fpoints[i].y = points[i].y * renderer->scale.y; - } - - retval = QueueCmdDrawLines(renderer, fpoints, count); - - SDL_small_free(fpoints, isstack); - return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); } @@ -2688,12 +3178,7 @@ SDL_RenderDrawRectF(SDL_Renderer * renderer, const SDL_FRect * rect) /* If 'rect' == NULL, then outline the whole surface */ if (!rect) { - SDL_Rect r; - SDL_RenderGetViewport(renderer, &r); - frect.x = 0.0f; - frect.y = 0.0f; - frect.w = (float) r.w; - frect.h = (float) r.h; + RenderGetViewportSize(renderer, &frect); rect = &frect; } @@ -2719,16 +3204,18 @@ SDL_RenderDrawRects(SDL_Renderer * renderer, CHECK_RENDERER_MAGIC(renderer, -1); if (!rects) { - return SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects"); + return SDL_InvalidParamError("SDL_RenderDrawRects(): rects"); } if (count < 1) { return 0; } +#if DONT_DRAW_WHILE_HIDDEN /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; } +#endif for (i = 0; i < count; ++i) { if (SDL_RenderDrawRect(renderer, &rects[i]) < 0) { @@ -2747,16 +3234,18 @@ SDL_RenderDrawRectsF(SDL_Renderer * renderer, CHECK_RENDERER_MAGIC(renderer, -1); if (!rects) { - return SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects"); + return SDL_InvalidParamError("SDL_RenderDrawRectsF(): rects"); } if (count < 1) { return 0; } +#if DONT_DRAW_WHILE_HIDDEN /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; } +#endif for (i = 0; i < count; ++i) { if (SDL_RenderDrawRectF(renderer, &rects[i]) < 0) { @@ -2780,13 +3269,7 @@ SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect) frect.w = (float) rect->w; frect.h = (float) rect->h; } else { - SDL_Rect r; - SDL_zero(r); - SDL_RenderGetViewport(renderer, &r); - frect.x = 0.0f; - frect.y = 0.0f; - frect.w = (float) r.w; - frect.h = (float) r.h; + RenderGetViewportSize(renderer, &frect); } return SDL_RenderFillRectsF(renderer, &frect, 1); } @@ -2800,13 +3283,7 @@ SDL_RenderFillRectF(SDL_Renderer * renderer, const SDL_FRect * rect) /* If 'rect' == NULL, then outline the whole surface */ if (!rect) { - SDL_Rect r; - SDL_zero(r); - SDL_RenderGetViewport(renderer, &r); - frect.x = 0.0f; - frect.y = 0.0f; - frect.w = (float) r.w; - frect.h = (float) r.h; + RenderGetViewportSize(renderer, &frect); rect = &frect; } return SDL_RenderFillRectsF(renderer, rect, 1); @@ -2824,16 +3301,18 @@ SDL_RenderFillRects(SDL_Renderer * renderer, CHECK_RENDERER_MAGIC(renderer, -1); if (!rects) { - return SDL_SetError("SDL_RenderFillRects(): Passed NULL rects"); + return SDL_InvalidParamError("SDL_RenderFillRects(): rects"); } if (count < 1) { return 0; } +#if DONT_DRAW_WHILE_HIDDEN /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; } +#endif frects = SDL_small_alloc(SDL_FRect, count, &isstack); if (!frects) { @@ -2865,16 +3344,18 @@ SDL_RenderFillRectsF(SDL_Renderer * renderer, CHECK_RENDERER_MAGIC(renderer, -1); if (!rects) { - return SDL_SetError("SDL_RenderFillFRects(): Passed NULL rects"); + return SDL_InvalidParamError("SDL_RenderFillRectsF(): rects"); } if (count < 1) { return 0; } +#if DONT_DRAW_WHILE_HIDDEN /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; } +#endif frects = SDL_small_alloc(SDL_FRect, count, &isstack); if (!frects) { @@ -2894,60 +3375,6 @@ SDL_RenderFillRectsF(SDL_Renderer * renderer, return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); } -/* !!! FIXME: move this to a public API if we want to do float versions of all of these later */ -SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r) -{ - return ((!r) || (r->w <= 0.0f) || (r->h <= 0.0f)) ? SDL_TRUE : SDL_FALSE; -} - -/* !!! FIXME: move this to a public API if we want to do float versions of all of these later */ -static SDL_bool -SDL_HasIntersectionF(const SDL_FRect * A, const SDL_FRect * B) -{ - float Amin, Amax, Bmin, Bmax; - - if (!A) { - SDL_InvalidParamError("A"); - return SDL_FALSE; - } - - if (!B) { - SDL_InvalidParamError("B"); - return SDL_FALSE; - } - - /* Special cases for empty rects */ - if (SDL_FRectEmpty(A) || SDL_FRectEmpty(B)) { - return SDL_FALSE; - } - - /* Horizontal intersection */ - Amin = A->x; - Amax = Amin + A->w; - Bmin = B->x; - Bmax = Bmin + B->w; - if (Bmin > Amin) - Amin = Bmin; - if (Bmax < Amax) - Amax = Bmax; - if (Amax <= Amin) - return SDL_FALSE; - - /* Vertical intersection */ - Amin = A->y; - Amax = Amin + A->h; - Bmin = B->y; - Bmax = Bmin + B->h; - if (Bmin > Amin) - Amin = Bmin; - if (Bmax < Amax) - Amax = Bmax; - if (Amax <= Amin) - return SDL_FALSE; - - return SDL_TRUE; -} - int SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect) @@ -2970,8 +3397,9 @@ SDL_RenderCopyF(SDL_Renderer * renderer, SDL_Texture * texture, { SDL_Rect real_srcrect; SDL_FRect real_dstrect; - SDL_Rect r; int retval; + int use_rendergeometry; + CHECK_RENDERER_MAGIC(renderer, -1); CHECK_TEXTURE_MAGIC(texture, -1); @@ -2980,10 +3408,14 @@ SDL_RenderCopyF(SDL_Renderer * renderer, SDL_Texture * texture, return SDL_SetError("Texture was not created with this renderer"); } +#if DONT_DRAW_WHILE_HIDDEN /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; } +#endif + + use_rendergeometry = (renderer->QueueCopy == NULL); real_srcrect.x = 0; real_srcrect.y = 0; @@ -2995,12 +3427,7 @@ SDL_RenderCopyF(SDL_Renderer * renderer, SDL_Texture * texture, } } - SDL_zero(r); - SDL_RenderGetViewport(renderer, &r); - real_dstrect.x = 0.0f; - real_dstrect.y = 0.0f; - real_dstrect.w = (float) r.w; - real_dstrect.h = (float) r.h; + RenderGetViewportSize(renderer, &real_dstrect); if (dstrect) { if (!SDL_HasIntersectionF(dstrect, &real_dstrect)) { return 0; @@ -3012,14 +3439,62 @@ SDL_RenderCopyF(SDL_Renderer * renderer, SDL_Texture * texture, texture = texture->native; } - real_dstrect.x *= renderer->scale.x; - real_dstrect.y *= renderer->scale.y; - real_dstrect.w *= renderer->scale.x; - real_dstrect.h *= renderer->scale.y; - texture->last_command_generation = renderer->render_command_generation; - retval = QueueCmdCopy(renderer, texture, &real_srcrect, &real_dstrect); + if (use_rendergeometry) { + float xy[8]; + const int xy_stride = 2 * sizeof (float); + float uv[8]; + const int uv_stride = 2 * sizeof (float); + const int num_vertices = 4; + const int indices[6] = {0, 1, 2, 0, 2, 3}; + const int num_indices = 6; + const int size_indices = 4; + float minu, minv, maxu, maxv; + float minx, miny, maxx, maxy; + + minu = (float) (real_srcrect.x) / (float) texture->w; + minv = (float) (real_srcrect.y) / (float) texture->h; + maxu = (float) (real_srcrect.x + real_srcrect.w) / (float) texture->w; + maxv = (float) (real_srcrect.y + real_srcrect.h) / (float) texture->h; + + minx = real_dstrect.x; + miny = real_dstrect.y; + maxx = real_dstrect.x + real_dstrect.w; + maxy = real_dstrect.y + real_dstrect.h; + + uv[0] = minu; + uv[1] = minv; + uv[2] = maxu; + uv[3] = minv; + uv[4] = maxu; + uv[5] = maxv; + uv[6] = minu; + uv[7] = maxv; + + xy[0] = minx; + xy[1] = miny; + xy[2] = maxx; + xy[3] = miny; + xy[4] = maxx; + xy[5] = maxy; + xy[6] = minx; + xy[7] = maxy; + + retval = QueueCmdGeometry(renderer, texture, + xy, xy_stride, &texture->color, 0 /* color_stride */, uv, uv_stride, + num_vertices, + indices, num_indices, size_indices, + renderer->scale.x, renderer->scale.y); + } else { + + real_dstrect.x *= renderer->scale.x; + real_dstrect.y *= renderer->scale.y; + real_dstrect.w *= renderer->scale.x; + real_dstrect.h *= renderer->scale.y; + + retval = QueueCmdCopy(renderer, texture, &real_srcrect, &real_dstrect); + } return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); } @@ -3059,6 +3534,7 @@ SDL_RenderCopyExF(SDL_Renderer * renderer, SDL_Texture * texture, SDL_FRect real_dstrect; SDL_FPoint real_center; int retval; + int use_rendergeometry; if (flip == SDL_FLIP_NONE && (int)(angle/360) == angle/360) { /* fast path when we don't need rotation or flipping */ return SDL_RenderCopyF(renderer, texture, srcrect, dstrect); @@ -3070,14 +3546,18 @@ SDL_RenderCopyExF(SDL_Renderer * renderer, SDL_Texture * texture, if (renderer != texture->renderer) { return SDL_SetError("Texture was not created with this renderer"); } - if (!renderer->QueueCopyEx) { + if (!renderer->QueueCopyEx && !renderer->QueueGeometry) { return SDL_SetError("Renderer does not support RenderCopyEx"); } +#if DONT_DRAW_WHILE_HIDDEN /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; } +#endif + + use_rendergeometry = (renderer->QueueCopyEx == NULL); real_srcrect.x = 0; real_srcrect.y = 0; @@ -3093,13 +3573,7 @@ SDL_RenderCopyExF(SDL_Renderer * renderer, SDL_Texture * texture, if (dstrect) { real_dstrect = *dstrect; } else { - SDL_Rect r; - SDL_zero(r); - SDL_RenderGetViewport(renderer, &r); - real_dstrect.x = 0.0f; - real_dstrect.y = 0.0f; - real_dstrect.w = (float) r.w; - real_dstrect.h = (float) r.h; + RenderGetViewportSize(renderer, &real_dstrect); } if (texture->native) { @@ -3113,20 +3587,574 @@ SDL_RenderCopyExF(SDL_Renderer * renderer, SDL_Texture * texture, real_center.y = real_dstrect.h / 2.0f; } - real_dstrect.x *= renderer->scale.x; - real_dstrect.y *= renderer->scale.y; - real_dstrect.w *= renderer->scale.x; - real_dstrect.h *= renderer->scale.y; - - real_center.x *= renderer->scale.x; - real_center.y *= renderer->scale.y; - texture->last_command_generation = renderer->render_command_generation; - retval = QueueCmdCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip); + if (use_rendergeometry) { + float xy[8]; + const int xy_stride = 2 * sizeof (float); + float uv[8]; + const int uv_stride = 2 * sizeof (float); + const int num_vertices = 4; + const int indices[6] = {0, 1, 2, 0, 2, 3}; + const int num_indices = 6; + const int size_indices = 4; + float minu, minv, maxu, maxv; + float minx, miny, maxx, maxy; + float centerx, centery; + + float s_minx, s_miny, s_maxx, s_maxy; + float c_minx, c_miny, c_maxx, c_maxy; + + const float radian_angle = (float)((M_PI * angle) / 180.0); + const float s = SDL_sinf(radian_angle); + const float c = SDL_cosf(radian_angle); + + minu = (float) (real_srcrect.x) / (float) texture->w; + minv = (float) (real_srcrect.y) / (float) texture->h; + maxu = (float) (real_srcrect.x + real_srcrect.w) / (float) texture->w; + maxv = (float) (real_srcrect.y + real_srcrect.h) / (float) texture->h; + + centerx = real_center.x + real_dstrect.x; + centery = real_center.y + real_dstrect.y; + + if (flip & SDL_FLIP_HORIZONTAL) { + minx = real_dstrect.x + real_dstrect.w; + maxx = real_dstrect.x; + } else { + minx = real_dstrect.x; + maxx = real_dstrect.x + real_dstrect.w; + } + + if (flip & SDL_FLIP_VERTICAL) { + miny = real_dstrect.y + real_dstrect.h; + maxy = real_dstrect.y; + } else { + miny = real_dstrect.y; + maxy = real_dstrect.y + real_dstrect.h; + } + + uv[0] = minu; + uv[1] = minv; + uv[2] = maxu; + uv[3] = minv; + uv[4] = maxu; + uv[5] = maxv; + uv[6] = minu; + uv[7] = maxv; + + /* apply rotation with 2x2 matrix ( c -s ) + * ( s c ) */ + s_minx = s * (minx - centerx); + s_miny = s * (miny - centery); + s_maxx = s * (maxx - centerx); + s_maxy = s * (maxy - centery); + c_minx = c * (minx - centerx); + c_miny = c * (miny - centery); + c_maxx = c * (maxx - centerx); + c_maxy = c * (maxy - centery); + + /* (minx, miny) */ + xy[0] = (c_minx - s_miny) + centerx; + xy[1] = (s_minx + c_miny) + centery; + /* (maxx, miny) */ + xy[2] = (c_maxx - s_miny) + centerx; + xy[3] = (s_maxx + c_miny) + centery; + /* (maxx, maxy) */ + xy[4] = (c_maxx - s_maxy) + centerx; + xy[5] = (s_maxx + c_maxy) + centery; + /* (minx, maxy) */ + xy[6] = (c_minx - s_maxy) + centerx; + xy[7] = (s_minx + c_maxy) + centery; + + retval = QueueCmdGeometry(renderer, texture, + xy, xy_stride, &texture->color, 0 /* color_stride */, uv, uv_stride, + num_vertices, + indices, num_indices, size_indices, + renderer->scale.x, renderer->scale.y); + } else { + + retval = QueueCmdCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip, renderer->scale.x, renderer->scale.y); + } return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); } +int +SDL_RenderGeometry(SDL_Renderer *renderer, + SDL_Texture *texture, + const SDL_Vertex *vertices, int num_vertices, + const int *indices, int num_indices) +{ + if (vertices) { + const float *xy = &vertices->position.x; + int xy_stride = sizeof (SDL_Vertex); + const SDL_Color *color = &vertices->color; + int color_stride = sizeof (SDL_Vertex); + const float *uv = &vertices->tex_coord.x; + int uv_stride = sizeof (SDL_Vertex); + int size_indices = 4; + return SDL_RenderGeometryRaw(renderer, texture, xy, xy_stride, color, color_stride, uv, uv_stride, num_vertices, indices, num_indices, size_indices); + } else { + return SDL_InvalidParamError("vertices"); + } +} + +static int +remap_one_indice( + int prev, + int k, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride) +{ + const float *xy0_, *xy1_, *uv0_, *uv1_; + int col0_, col1_; + xy0_ = (const float *)((const char*)xy + prev * xy_stride); + xy1_ = (const float *)((const char*)xy + k * xy_stride); + if (xy0_[0] != xy1_[0]) { + return k; + } + if (xy0_[1] != xy1_[1]) { + return k; + } + if (texture) { + uv0_ = (const float *)((const char*)uv + prev * uv_stride); + uv1_ = (const float *)((const char*)uv + k * uv_stride); + if (uv0_[0] != uv1_[0]) { + return k; + } + if (uv0_[1] != uv1_[1]) { + return k; + } + } + col0_ = *(const int *)((const char*)color + prev * color_stride); + col1_ = *(const int *)((const char*)color + k * color_stride); + + if (col0_ != col1_) { + return k; + } + + return prev; +} + +static int +remap_indices( + int prev[3], + int k, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride) +{ + int i; + if (prev[0] == -1) { + return k; + } + + for (i = 0; i < 3; i++) { + int new_k = remap_one_indice(prev[i], k, texture, xy, xy_stride, color, color_stride, uv, uv_stride); + if (new_k != k) { + return new_k; + } + } + return k; +} + +#define DEBUG_SW_RENDER_GEOMETRY 0 +/* For the software renderer, try to reinterpret triangles as SDL_Rect */ +static int SDLCALL +SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indices) +{ + int i; + int retval = 0; + int count = indices ? num_indices : num_vertices; + int prev[3]; /* Previous triangle vertex indices */ + int texw = 0, texh = 0; + SDL_BlendMode blendMode = SDL_BLENDMODE_NONE; + Uint8 r = 0, g = 0, b = 0, a = 0; + + /* Save */ + SDL_GetRenderDrawBlendMode(renderer, &blendMode); + SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a); + + if (texture) { + SDL_QueryTexture(texture, NULL, NULL, &texw, &texh); + } + + prev[0] = -1; prev[1] = -1; prev[2] = -1; + size_indices = indices ? size_indices : 0; + + for (i = 0; i < count; i += 3) { + int k0, k1, k2; /* Current triangle indices */ + int is_quad = 1; +#if DEBUG_SW_RENDER_GEOMETRY + int is_uniform = 1; + int is_rectangle = 1; +#endif + int A = -1; /* Top left vertex */ + int B = -1; /* Bottom right vertex */ + int C = -1; /* Third vertex of current triangle */ + int C2 = -1; /* Last, vertex of previous triangle */ + + if (size_indices == 4) { + k0 = ((const Uint32 *)indices)[i]; + k1 = ((const Uint32 *)indices)[i + 1]; + k2 = ((const Uint32 *)indices)[i + 2]; + } else if (size_indices == 2) { + k0 = ((const Uint16 *)indices)[i]; + k1 = ((const Uint16 *)indices)[i + 1]; + k2 = ((const Uint16 *)indices)[i + 2]; + } else if (size_indices == 1) { + k0 = ((const Uint8 *)indices)[i]; + k1 = ((const Uint8 *)indices)[i + 1]; + k2 = ((const Uint8 *)indices)[i + 2]; + } else { + /* Vertices were not provided by indices. Maybe some are duplicated. + * We try to indentificate the duplicates by comparing with the previous three vertices */ + k0 = remap_indices(prev, i, texture, xy, xy_stride, color, color_stride, uv, uv_stride); + k1 = remap_indices(prev, i + 1, texture, xy, xy_stride, color, color_stride, uv, uv_stride); + k2 = remap_indices(prev, i + 2, texture, xy, xy_stride, color, color_stride, uv, uv_stride); + } + + if (prev[0] == -1) { + prev[0] = k0; + prev[1] = k1; + prev[2] = k2; + continue; + } + + /* Two triangles forming a quadialateral, + * prev and current triangles must have exactly 2 common vertices */ + { + int cnt = 0, j = 3; + while (j--) { + int p = prev[j]; + if (p == k0 || p == k1 || p == k2) { + cnt++; + } + } + is_quad = (cnt == 2); + } + + /* Identify vertices */ + if (is_quad) { + const float *xy0_, *xy1_, *xy2_; + float x0, x1, x2; + float y0, y1, y2; + xy0_ = (const float *)((const char*)xy + k0 * xy_stride); + xy1_ = (const float *)((const char*)xy + k1 * xy_stride); + xy2_ = (const float *)((const char*)xy + k2 * xy_stride); + x0 = xy0_[0]; y0 = xy0_[1]; + x1 = xy1_[0]; y1 = xy1_[1]; + x2 = xy2_[0]; y2 = xy2_[1]; + + /* Find top-left */ + if (x0 <= x1 && y0 <= y1) { + if (x0 <= x2 && y0 <= y2) { + A = k0; + } else { + A = k2; + } + } else { + if (x1 <= x2 && y1 <= y2) { + A = k1; + } else { + A = k2; + } + } + + /* Find bottom-right */ + if (x0 >= x1 && y0 >= y1) { + if (x0 >= x2 && y0 >= y2) { + B = k0; + } else { + B = k2; + } + } else { + if (x1 >= x2 && y1 >= y2) { + B = k1; + } else { + B = k2; + } + } + + /* Find C */ + if (k0 != A && k0 != B) { + C = k0; + } else if (k1 != A && k1 != B) { + C = k1; + } else { + C = k2; + } + + /* Find C2 */ + if (prev[0] != A && prev[0] != B) { + C2 = prev[0]; + } else if (prev[1] != A && prev[1] != B) { + C2 = prev[1]; + } else { + C2 = prev[2]; + } + + xy0_ = (const float *)((const char*)xy + A * xy_stride); + xy1_ = (const float *)((const char*)xy + B * xy_stride); + xy2_ = (const float *)((const char*)xy + C * xy_stride); + x0 = xy0_[0]; y0 = xy0_[1]; + x1 = xy1_[0]; y1 = xy1_[1]; + x2 = xy2_[0]; y2 = xy2_[1]; + + /* Check if triangle A B C is rectangle */ + if ((x0 == x2 && y1 == y2) || (y0 == y2 && x1 == x2)){ + /* ok */ + } else { + is_quad = 0; +#if DEBUG_SW_RENDER_GEOMETRY + is_rectangle = 0; +#endif + } + + xy2_ = (const float *)((const char*)xy + C2 * xy_stride); + x2 = xy2_[0]; y2 = xy2_[1]; + + /* Check if triangle A B C2 is rectangle */ + if ((x0 == x2 && y1 == y2) || (y0 == y2 && x1 == x2)){ + /* ok */ + } else { + is_quad = 0; +#if DEBUG_SW_RENDER_GEOMETRY + is_rectangle = 0; +#endif + } + } + + /* Check if uniformly colored */ + if (is_quad) { + const int col0_ = *(const int *)((const char*)color + A * color_stride); + const int col1_ = *(const int *)((const char*)color + B * color_stride); + const int col2_ = *(const int *)((const char*)color + C * color_stride); + const int col3_ = *(const int *)((const char*)color + C2 * color_stride); + if (col0_ == col1_ && col0_ == col2_ && col0_ == col3_) { + /* ok */ + } else { + is_quad = 0; +#if DEBUG_SW_RENDER_GEOMETRY + is_uniform = 0; +#endif + } + } + + /* Start rendering rect */ + if (is_quad) { + SDL_Rect s; + SDL_FRect d; + const float *xy0_, *xy1_, *uv0_, *uv1_; + SDL_Color col0_ = *(const SDL_Color *)((const char*)color + k0 * color_stride); + + xy0_ = (const float *)((const char*)xy + A * xy_stride); + xy1_ = (const float *)((const char*)xy + B * xy_stride); + + if (texture) { + uv0_ = (const float *)((const char*)uv + A * uv_stride); + uv1_ = (const float *)((const char*)uv + B * uv_stride); + s.x = (int) (uv0_[0] * texw); + s.y = (int) (uv0_[1] * texh); + s.w = (int) (uv1_[0] * texw - s.x); + s.h = (int) (uv1_[1] * texh - s.y); + } + + d.x = xy0_[0]; + d.y = xy0_[1]; + d.w = xy1_[0] - d.x; + d.h = xy1_[1] - d.y; + + /* Rect + texture */ + if (texture && s.w != 0 && s.h != 0) { + SDL_SetTextureAlphaMod(texture, col0_.a); + SDL_SetTextureColorMod(texture, col0_.r, col0_.g, col0_.b); + SDL_RenderCopyF(renderer, texture, &s, &d); +#if DEBUG_SW_RENDER_GEOMETRY + SDL_Log("Rect-COPY: RGB %d %d %d - Alpha:%d - texture=%p: src=(%d,%d, %d x %d) dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a, + (void *)texture, s.x, s.y, s.w, s.h, d.x, d.y, d.w, d.h); +#endif + } else if (d.w != 0.0f && d.h != 0.0f) { /* Rect, no texture */ + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, col0_.r, col0_.g, col0_.b, col0_.a); + SDL_RenderFillRectF(renderer, &d); +#if DEBUG_SW_RENDER_GEOMETRY + SDL_Log("Rect-FILL: RGB %d %d %d - Alpha:%d - texture=%p: src=(%d,%d, %d x %d) dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a, + (void *)texture, s.x, s.y, s.w, s.h, d.x, d.y, d.w, d.h); + } else { + SDL_Log("Rect-DISMISS: RGB %d %d %d - Alpha:%d - texture=%p: src=(%d,%d, %d x %d) dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a, + (void *)texture, s.x, s.y, s.w, s.h, d.x, d.y, d.w, d.h); +#endif + } + + prev[0] = -1; + } else { + /* Render triangles */ + if (prev[0] != -1) { +#if DEBUG_SW_RENDER_GEOMETRY + SDL_Log("Triangle %d %d %d - is_uniform:%d is_rectangle:%d", prev[0], prev[1], prev[2], is_uniform, is_rectangle); +#endif + retval = QueueCmdGeometry(renderer, texture, + xy, xy_stride, color, color_stride, uv, uv_stride, + num_vertices, prev, 3, 4, renderer->scale.x, renderer->scale.y); + if (retval < 0) { + goto end; + } else { + FlushRenderCommandsIfNotBatching(renderer); + } + } + + prev[0] = k0; + prev[1] = k1; + prev[2] = k2; + } + } /* End for(), next triangle */ + + if (prev[0] != -1) { + /* flush the last triangle */ +#if DEBUG_SW_RENDER_GEOMETRY + SDL_Log("Last triangle %d %d %d", prev[0], prev[1], prev[2]); +#endif + retval = QueueCmdGeometry(renderer, texture, + xy, xy_stride, color, color_stride, uv, uv_stride, + num_vertices, prev, 3, 4, renderer->scale.x, renderer->scale.y); + if (retval < 0) { + goto end; + } else { + FlushRenderCommandsIfNotBatching(renderer); + } + } + +end: + /* Restore */ + SDL_SetRenderDrawBlendMode(renderer, blendMode); + SDL_SetRenderDrawColor(renderer, r, g, b, a); + + return retval; +} + +int +SDL_RenderGeometryRaw(SDL_Renderer *renderer, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indices) +{ + int i; + int retval = 0; + int count = indices ? num_indices : num_vertices; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!renderer->QueueGeometry) { + return SDL_Unsupported(); + } + + if (texture) { + CHECK_TEXTURE_MAGIC(texture, -1); + + if (renderer != texture->renderer) { + return SDL_SetError("Texture was not created with this renderer"); + } + } + + if (!xy) { + return SDL_InvalidParamError("xy"); + } + + if (!color) { + return SDL_InvalidParamError("color"); + } + + if (texture && !uv) { + return SDL_InvalidParamError("uv"); + } + + if (count % 3 != 0) { + return SDL_InvalidParamError(indices ? "num_indices" : "num_vertices"); + } + + if (indices) { + if (size_indices != 1 && size_indices != 2 && size_indices != 4) { + return SDL_InvalidParamError("size_indices"); + } + } else { + size_indices = 0; + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + if (num_vertices < 3) { + return 0; + } + + if (texture && texture->native) { + texture = texture->native; + } + + if (texture) { + for (i = 0; i < num_vertices; ++i) { + const float *uv_ = (const float *)((const char*)uv + i * uv_stride); + float u = uv_[0]; + float v = uv_[1]; + if (u < 0.0f || v < 0.0f || u > 1.0f || v > 1.0f) { + return SDL_SetError("Values of 'uv' out of bounds %f %f at %d/%d", u, v, i, num_vertices); + } + } + } + + if (indices) { + for (i = 0; i < num_indices; ++i) { + int j; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else { + j = ((const Uint8 *)indices)[i]; + } + if (j < 0 || j >= num_vertices) { + return SDL_SetError("Values of 'indices' out of bounds"); + } + } + } + + if (texture) { + texture->last_command_generation = renderer->render_command_generation; + } + + /* For the software renderer, try to reinterpret triangles as SDL_Rect */ + if (renderer->info.flags & SDL_RENDERER_SOFTWARE) { + return SDL_SW_RenderGeometryRaw(renderer, texture, + xy, xy_stride, color, color_stride, uv, uv_stride, num_vertices, + indices, num_indices, size_indices); + } + + retval = QueueCmdGeometry(renderer, texture, + xy, xy_stride, color, color_stride, uv, uv_stride, + num_vertices, + indices, num_indices, size_indices, + renderer->scale.x, renderer->scale.y); + + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + + int SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch) @@ -3142,13 +4170,17 @@ SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, FlushRenderCommands(renderer); /* we need to render before we read the results. */ if (!format) { - format = SDL_GetWindowPixelFormat(renderer->window); + if (renderer->target == NULL) { + format = SDL_GetWindowPixelFormat(renderer->window); + } else { + format = renderer->target->format; + } } - real_rect.x = renderer->viewport.x; - real_rect.y = renderer->viewport.y; - real_rect.w = renderer->viewport.w; - real_rect.h = renderer->viewport.h; + real_rect.x = (int)SDL_floor(renderer->viewport.x); + real_rect.y = (int)SDL_floor(renderer->viewport.y); + real_rect.w = (int)SDL_floor(renderer->viewport.w); + real_rect.h = (int)SDL_floor(renderer->viewport.h); if (rect) { if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) { return 0; @@ -3173,10 +4205,13 @@ SDL_RenderPresent(SDL_Renderer * renderer) FlushRenderCommands(renderer); /* time to send everything to the GPU! */ +#if DONT_DRAW_WHILE_HIDDEN /* Don't present while we're hidden */ if (renderer->hidden) { return; } +#endif + renderer->RenderPresent(renderer); } @@ -3424,4 +4459,19 @@ SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode) return (SDL_BlendOperation)(((Uint32)blendMode >> 16) & 0xF); } +int +SDL_RenderSetVSync(SDL_Renderer * renderer, int vsync) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + if (vsync != 0 && vsync != 1) { + return SDL_Unsupported(); + } + + if (renderer->SetVSync) { + return renderer->SetVSync(renderer, vsync); + } + return SDL_Unsupported(); +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/SDL_sysrender.h b/Engine/lib/sdl/src/render/SDL_sysrender.h index 5bb98094e..5d92f6a26 100644 --- a/Engine/lib/sdl/src/render/SDL_sysrender.h +++ b/Engine/lib/sdl/src/render/SDL_sysrender.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -43,7 +43,7 @@ struct SDL_Texture int modMode; /**< The texture modulation mode */ SDL_BlendMode blendMode; /**< The texture blend mode */ SDL_ScaleMode scaleMode; /**< The texture scale mode */ - Uint8 r, g, b, a; /**< Texture modulation values */ + SDL_Color color; /**< Texture modulation values */ SDL_Renderer *renderer; @@ -58,6 +58,7 @@ struct SDL_Texture Uint32 last_command_generation; /* last command queue generation this texture was in. */ void *driverdata; /**< Driver specific texture representation */ + void *userdata; SDL_Texture *prev; SDL_Texture *next; @@ -74,7 +75,8 @@ typedef enum SDL_RENDERCMD_DRAW_LINES, SDL_RENDERCMD_FILL_RECTS, SDL_RENDERCMD_COPY, - SDL_RENDERCMD_COPY_EX + SDL_RENDERCMD_COPY_EX, + SDL_RENDERCMD_GEOMETRY } SDL_RenderCommandType; typedef struct SDL_RenderCommand @@ -105,6 +107,21 @@ typedef struct SDL_RenderCommand } SDL_RenderCommand; +typedef struct SDL_VertexSolid +{ + SDL_FPoint position; + SDL_Color color; +} SDL_VertexSolid; + + +typedef enum +{ + SDL_RENDERLINEMETHOD_POINTS, + SDL_RENDERLINEMETHOD_LINES, + SDL_RENDERLINEMETHOD_GEOMETRY, +} SDL_RenderLineMethod; + + /* Define the SDL renderer structure */ struct SDL_Renderer { @@ -126,16 +143,27 @@ struct SDL_Renderer const SDL_Rect * srcrect, const SDL_FRect * dstrect); int (*QueueCopyEx) (SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y); + int (*QueueGeometry) (SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y); + int (*RunCommandQueue) (SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize); int (*UpdateTexture) (SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch); +#if SDL_HAVE_YUV int (*UpdateTextureYUV) (SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch); + int (*UpdateTextureNV) (SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch); +#endif int (*LockTexture) (SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch); void (*UnlockTexture) (SDL_Renderer * renderer, SDL_Texture * texture); @@ -148,6 +176,8 @@ struct SDL_Renderer void (*DestroyRenderer) (SDL_Renderer * renderer); + int (*SetVSync) (SDL_Renderer * renderer, int vsync); + int (*GL_BindTexture) (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh); int (*GL_UnbindTexture) (SDL_Renderer * renderer, SDL_Texture *texture); @@ -171,12 +201,12 @@ struct SDL_Renderer SDL_bool integer_scale; /* The drawable area within the window */ - SDL_Rect viewport; - SDL_Rect viewport_backup; + SDL_FRect viewport; + SDL_FRect viewport_backup; /* The clip rectangle within the window */ - SDL_Rect clip_rect; - SDL_Rect clip_rect_backup; + SDL_FRect clip_rect; + SDL_FRect clip_rect_backup; /* Wether or not the clipping rectangle is used. */ SDL_bool clipping_enabled; @@ -192,6 +222,9 @@ struct SDL_Renderer /* Whether or not to scale relative mouse motion */ SDL_bool relative_scaling; + /* The method of drawing lines */ + SDL_RenderLineMethod line_method; + /* Remainder from scaled relative motion */ float xrel; float yrel; @@ -201,7 +234,7 @@ struct SDL_Renderer SDL_Texture *target; SDL_mutex *target_mutex; - Uint8 r, g, b, a; /**< Color for drawing operations values */ + SDL_Color color; /**< Color for drawing operations values */ SDL_BlendMode blendMode; /**< The drawing blend mode */ SDL_bool always_batch; @@ -211,8 +244,8 @@ struct SDL_Renderer SDL_RenderCommand *render_commands_pool; Uint32 render_command_generation; Uint32 last_queued_color; - SDL_Rect last_queued_viewport; - SDL_Rect last_queued_cliprect; + SDL_FRect last_queued_viewport; + SDL_FRect last_queued_cliprect; SDL_bool last_queued_cliprect_enabled; SDL_bool color_queued; SDL_bool viewport_queued; @@ -244,6 +277,7 @@ extern SDL_RenderDriver DirectFB_RenderDriver; extern SDL_RenderDriver METAL_RenderDriver; extern SDL_RenderDriver PSP_RenderDriver; extern SDL_RenderDriver SW_RenderDriver; +extern SDL_RenderDriver VITA_GXM_RenderDriver; /* Blend mode functions */ extern SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode); @@ -258,6 +292,9 @@ extern SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode the next call, because it might be in an array that gets realloc()'d. */ extern void *SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset); +extern int SDL_PrivateLowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect, SDL_ScaleMode scaleMode); +extern int SDL_PrivateUpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect, SDL_ScaleMode scaleMode); + #endif /* SDL_sysrender_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/SDL_yuv_sw.c b/Engine/lib/sdl/src/render/SDL_yuv_sw.c index 11b8b4ad5..10fe54e69 100644 --- a/Engine/lib/sdl/src/render/SDL_yuv_sw.c +++ b/Engine/lib/sdl/src/render/SDL_yuv_sw.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,6 +26,7 @@ #include "SDL_yuv_sw_c.h" +#include "SDL_cpuinfo.h" SDL_SW_YUVTexture * @@ -84,7 +85,7 @@ SDL_SW_CreateYUVTexture(Uint32 format, int w, int h) SDL_assert(0 && "We should never get here (caught above)"); break; } - swdata->pixels = (Uint8 *) SDL_malloc(dst_size); + swdata->pixels = (Uint8 *) SDL_SIMDAlloc(dst_size); if (!swdata->pixels) { SDL_SW_DestroyYUVTexture(swdata); SDL_OutOfMemory(); @@ -299,6 +300,40 @@ SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, return 0; } +int SDL_SW_UpdateNVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ + const Uint8 *src; + Uint8 *dst; + int row; + size_t length; + + /* Copy the Y plane */ + src = Yplane; + dst = swdata->pixels + rect->y * swdata->w + rect->x; + length = rect->w; + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += Ypitch; + dst += swdata->w; + } + + /* Copy the UV or VU plane */ + src = UVplane; + dst = swdata->pixels + swdata->h * swdata->w; + dst += rect->y * ((swdata->w + 1)/2) + rect->x; + length = (rect->w + 1) / 2; + length *= 2; + for (row = 0; row < (rect->h + 1)/2; ++row) { + SDL_memcpy(dst, src, length); + src += UVpitch; + dst += 2 * ((swdata->w + 1)/2); + } + + return 0; +} + int SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, void **pixels, int *pitch) @@ -405,7 +440,7 @@ void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture * swdata) { if (swdata) { - SDL_free(swdata->pixels); + SDL_SIMDFree(swdata->pixels); SDL_FreeSurface(swdata->stretch); SDL_FreeSurface(swdata->display); SDL_free(swdata); diff --git a/Engine/lib/sdl/src/render/SDL_yuv_sw_c.h b/Engine/lib/sdl/src/render/SDL_yuv_sw_c.h index 75c6f273e..8d9dc79cd 100644 --- a/Engine/lib/sdl/src/render/SDL_yuv_sw_c.h +++ b/Engine/lib/sdl/src/render/SDL_yuv_sw_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -55,6 +55,9 @@ int SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * r const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch); +int SDL_SW_UpdateNVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch); int SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, void **pixels, int *pitch); void SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture * swdata); @@ -63,11 +66,6 @@ int SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect, int pitch); void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture * swdata); -/* FIXME: This breaks on various versions of GCC and should be rewritten using intrinsics */ -#if 0 /* (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES && !defined(__clang__) */ -#define USE_MMX_ASSEMBLY 1 -#endif - #endif /* SDL_yuv_sw_c_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c b/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c index 709409157..b267fb23e 100644 --- a/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c +++ b/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -51,7 +51,6 @@ typedef struct SDL_bool cliprect_enabled_dirty; SDL_Rect cliprect; SDL_bool cliprect_dirty; - SDL_bool is_copy_ex; LPDIRECT3DPIXELSHADER9 shader; } D3D_DrawStateCache; @@ -72,7 +71,9 @@ typedef struct IDirect3DSurface9 *defaultRenderTarget; IDirect3DSurface9 *currentRenderTarget; void* d3dxDLL; +#if SDL_HAVE_YUV LPDIRECT3DPIXELSHADER9 shaders[NUM_SHADERS]; +#endif LPDIRECT3DVERTEXBUFFER9 vertexBuffers[8]; size_t vertexBufferSize[8]; int currentVertexBuffer; @@ -96,6 +97,7 @@ typedef struct D3D_TextureRep texture; D3DTEXTUREFILTERTYPE scaleMode; +#if SDL_HAVE_YUV /* YV12 texture support */ SDL_bool yuv; D3D_TextureRep utexture; @@ -103,6 +105,7 @@ typedef struct Uint8 *pixels; int pitch; SDL_Rect locked_rect; +#endif } D3D_TextureData; typedef struct @@ -535,7 +538,7 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (D3D_CreateTextureRep(data->device, &texturedata->texture, usage, texture->format, PixelFormatToD3DFMT(texture->format), texture->w, texture->h) < 0) { return -1; } - +#if SDL_HAVE_YUV if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { texturedata->yuv = SDL_TRUE; @@ -548,6 +551,7 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return -1; } } +#endif return 0; } @@ -564,7 +568,7 @@ D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (D3D_RecreateTextureRep(data->device, &texturedata->texture) < 0) { return -1; } - +#if SDL_HAVE_YUV if (texturedata->yuv) { if (D3D_RecreateTextureRep(data->device, &texturedata->utexture) < 0) { return -1; @@ -574,6 +578,7 @@ D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return -1; } } +#endif return 0; } @@ -585,14 +590,13 @@ D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; if (!texturedata) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->x, rect->y, rect->w, rect->h, pixels, pitch) < 0) { return -1; } - +#if SDL_HAVE_YUV if (texturedata->yuv) { /* Skip to the correct offset into the next texture */ pixels = (const void*)((const Uint8*)pixels + rect->h * pitch); @@ -607,9 +611,11 @@ D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } } +#endif return 0; } +#if SDL_HAVE_YUV static int D3D_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, @@ -621,8 +627,7 @@ D3D_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; if (!texturedata) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) { @@ -636,6 +641,7 @@ D3D_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, } return 0; } +#endif static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, @@ -646,10 +652,9 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, IDirect3DDevice9 *device = data->device; if (!texturedata) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } - +#if SDL_HAVE_YUV texturedata->locked_rect = *rect; if (texturedata->yuv) { @@ -665,7 +670,9 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, (void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch + rect->x * SDL_BYTESPERPIXEL(texture->format)); *pitch = texturedata->pitch; - } else { + } else +#endif + { RECT d3drect; D3DLOCKED_RECT locked; HRESULT result; @@ -698,14 +705,17 @@ D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (!texturedata) { return; } - +#if SDL_HAVE_YUV if (texturedata->yuv) { const SDL_Rect *rect = &texturedata->locked_rect; void *pixels = (void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch + rect->x * SDL_BYTESPERPIXEL(texture->format)); D3D_UpdateTexture(renderer, texture, rect, pixels, texturedata->pitch); - } else { + } + else +#endif + { IDirect3DTexture9_UnlockRect(texturedata->texture.staging, 0); texturedata->texture.dirty = SDL_TRUE; if (data->drawstate.texture == texture) { @@ -713,10 +723,6 @@ D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) data->drawstate.shader = NULL; IDirect3DDevice9_SetPixelShader(data->device, NULL); IDirect3DDevice9_SetTexture(data->device, 0, NULL); - if (texturedata->yuv) { - IDirect3DDevice9_SetTexture(data->device, 1, NULL); - IDirect3DDevice9_SetTexture(data->device, 2, NULL); - } } } } @@ -755,8 +761,7 @@ D3D_SetRenderTargetInternal(SDL_Renderer * renderer, SDL_Texture * texture) texturedata = (D3D_TextureData *)texture->driverdata; if (!texturedata) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } /* Make sure the render target is updated if it was locked and written to */ @@ -831,190 +836,55 @@ D3D_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_F } static int -D3D_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +D3D_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) { - const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b); - const size_t vertslen = count * sizeof (Vertex) * 4; - Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first); int i; + int count = indices ? num_indices : num_vertices; + Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, count * sizeof (Vertex), 0, &cmd->data.draw.first); if (!verts) { return -1; } - SDL_memset(verts, '\0', vertslen); cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; for (i = 0; i < count; i++) { - const SDL_FRect *rect = &rects[i]; - const float minx = rect->x; - const float maxx = rect->x + rect->w; - const float miny = rect->y; - const float maxy = rect->y + rect->h; + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } - verts->x = minx; - verts->y = miny; - verts->color = color; - verts++; + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); - verts->x = maxx; - verts->y = miny; - verts->color = color; - verts++; + verts->x = xy_[0] * scale_x - 0.5f; + verts->y = xy_[1] * scale_y - 0.5f; + verts->z = 0.0f; + verts->color = D3DCOLOR_ARGB(col_.a, col_.r, col_.g, col_.b); - verts->x = maxx; - verts->y = maxy; - verts->color = color; - verts++; + if (texture) { + float *uv_ = (float *)((char*)uv + j * uv_stride); + verts->u = uv_[0]; + verts->v = uv_[1]; + } else { + verts->u = 0.0f; + verts->v = 0.0f; + } - verts->x = minx; - verts->y = maxy; - verts->color = color; - verts++; + verts += 1; } - - return 0; -} - -static int -D3D_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) -{ - const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b); - float minx, miny, maxx, maxy; - float minu, maxu, minv, maxv; - const size_t vertslen = sizeof (Vertex) * 4; - Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - minx = dstrect->x - 0.5f; - miny = dstrect->y - 0.5f; - maxx = dstrect->x + dstrect->w - 0.5f; - maxy = dstrect->y + dstrect->h - 0.5f; - - minu = (float) srcrect->x / texture->w; - maxu = (float) (srcrect->x + srcrect->w) / texture->w; - minv = (float) srcrect->y / texture->h; - maxv = (float) (srcrect->y + srcrect->h) / texture->h; - - verts->x = minx; - verts->y = miny; - verts->z = 0.0f; - verts->color = color; - verts->u = minu; - verts->v = minv; - verts++; - - verts->x = maxx; - verts->y = miny; - verts->z = 0.0f; - verts->color = color; - verts->u = maxu; - verts->v = minv; - verts++; - - verts->x = maxx; - verts->y = maxy; - verts->z = 0.0f; - verts->color = color; - verts->u = maxu; - verts->v = maxv; - verts++; - - verts->x = minx; - verts->y = maxy; - verts->z = 0.0f; - verts->color = color; - verts->u = minu; - verts->v = maxv; - verts++; - - return 0; -} - -static int -D3D_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b); - float minx, miny, maxx, maxy; - float minu, maxu, minv, maxv; - const size_t vertslen = sizeof (Vertex) * 5; - Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - minx = -center->x; - maxx = dstrect->w - center->x; - miny = -center->y; - maxy = dstrect->h - center->y; - - if (flip & SDL_FLIP_HORIZONTAL) { - minu = (float) (srcquad->x + srcquad->w) / texture->w; - maxu = (float) srcquad->x / texture->w; - } else { - minu = (float) srcquad->x / texture->w; - maxu = (float) (srcquad->x + srcquad->w) / texture->w; - } - - if (flip & SDL_FLIP_VERTICAL) { - minv = (float) (srcquad->y + srcquad->h) / texture->h; - maxv = (float) srcquad->y / texture->h; - } else { - minv = (float) srcquad->y / texture->h; - maxv = (float) (srcquad->y + srcquad->h) / texture->h; - } - - verts->x = minx; - verts->y = miny; - verts->z = 0.0f; - verts->color = color; - verts->u = minu; - verts->v = minv; - verts++; - - verts->x = maxx; - verts->y = miny; - verts->z = 0.0f; - verts->color = color; - verts->u = maxu; - verts->v = minv; - verts++; - - verts->x = maxx; - verts->y = maxy; - verts->z = 0.0f; - verts->color = color; - verts->u = maxu; - verts->v = maxv; - verts++; - - verts->x = minx; - verts->y = maxy; - verts->z = 0.0f; - verts->color = color; - verts->u = minu; - verts->v = maxv; - verts++; - - verts->x = dstrect->x + center->x - 0.5f; /* X translation */ - verts->y = dstrect->y + center->y - 0.5f; /* Y translation */ - verts->z = (float)(M_PI * (float) angle / 180.0f); /* rotation */ - verts->color = 0; - verts->u = 0.0f; - verts->v = 0.0f; - verts++; - return 0; } @@ -1076,8 +946,7 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH SDL_assert(*shader == NULL); if (!texturedata) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } UpdateTextureScaleMode(data, texturedata, 0); @@ -1085,7 +954,7 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH if (BindTextureRep(data->device, &texturedata->texture, 0) < 0) { return -1; } - +#if SDL_HAVE_YUV if (texturedata->yuv) { switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) { case SDL_YUV_CONVERSION_JPEG: @@ -1111,30 +980,33 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH return -1; } } +#endif return 0; } static int SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) { - const SDL_bool was_copy_ex = data->drawstate.is_copy_ex; - const SDL_bool is_copy_ex = (cmd->command == SDL_RENDERCMD_COPY_EX); SDL_Texture *texture = cmd->data.draw.texture; const SDL_BlendMode blend = cmd->data.draw.blend; if (texture != data->drawstate.texture) { +#if SDL_HAVE_YUV D3D_TextureData *oldtexturedata = data->drawstate.texture ? (D3D_TextureData *) data->drawstate.texture->driverdata : NULL; D3D_TextureData *newtexturedata = texture ? (D3D_TextureData *) texture->driverdata : NULL; +#endif LPDIRECT3DPIXELSHADER9 shader = NULL; /* disable any enabled textures we aren't going to use, let SetupTextureState() do the rest. */ if (texture == NULL) { IDirect3DDevice9_SetTexture(data->device, 0, NULL); } +#if SDL_HAVE_YUV if ((!newtexturedata || !newtexturedata->yuv) && (oldtexturedata && oldtexturedata->yuv)) { IDirect3DDevice9_SetTexture(data->device, 1, NULL); IDirect3DDevice9_SetTexture(data->device, 2, NULL); } +#endif if (texture && SetupTextureState(data, texture, &shader) < 0) { return -1; } @@ -1151,10 +1023,12 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) } else if (texture) { D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; UpdateDirtyTexture(data->device, &texturedata->texture); +#if SDL_HAVE_YUV if (texturedata->yuv) { UpdateDirtyTexture(data->device, &texturedata->utexture); UpdateDirtyTexture(data->device, &texturedata->vtexture); } +#endif } if (blend != data->drawstate.blend) { @@ -1177,14 +1051,6 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) data->drawstate.blend = blend; } - if (is_copy_ex != was_copy_ex) { - if (!is_copy_ex) { /* SDL_RENDERCMD_COPY_EX will set this, we only want to reset it here if necessary. */ - const Float4X4 d3dmatrix = MatrixIdentity(); - IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*) &d3dmatrix); - } - data->drawstate.is_copy_ex = is_copy_ex; - } - if (data->drawstate.viewport_dirty) { const SDL_Rect *viewport = &data->drawstate.viewport; const D3DVIEWPORT9 d3dviewport = { viewport->x, viewport->y, viewport->w, viewport->h, 0.0f, 1.0f }; @@ -1229,52 +1095,53 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti const int vboidx = data->currentVertexBuffer; IDirect3DVertexBuffer9 *vbo = NULL; const SDL_bool istarget = renderer->target != NULL; - size_t i; if (D3D_ActivateRenderer(renderer) < 0) { return -1; } - /* upload the new VBO data for this set of commands. */ - vbo = data->vertexBuffers[vboidx]; - if (data->vertexBufferSize[vboidx] < vertsize) { - const DWORD usage = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY; - const DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1; + if (vertices) { + /* upload the new VBO data for this set of commands. */ + vbo = data->vertexBuffers[vboidx]; + if (data->vertexBufferSize[vboidx] < vertsize) { + const DWORD usage = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY; + const DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1; + if (vbo) { + IDirect3DVertexBuffer9_Release(vbo); + } + + if (FAILED(IDirect3DDevice9_CreateVertexBuffer(data->device, (UINT) vertsize, usage, fvf, D3DPOOL_DEFAULT, &vbo, NULL))) { + vbo = NULL; + } + data->vertexBuffers[vboidx] = vbo; + data->vertexBufferSize[vboidx] = vbo ? vertsize : 0; + } + if (vbo) { - IDirect3DVertexBuffer9_Release(vbo); - } - - if (FAILED(IDirect3DDevice9_CreateVertexBuffer(data->device, (UINT) vertsize, usage, fvf, D3DPOOL_DEFAULT, &vbo, NULL))) { - vbo = NULL; - } - data->vertexBuffers[vboidx] = vbo; - data->vertexBufferSize[vboidx] = vbo ? vertsize : 0; - } - - if (vbo) { - void *ptr; - if (FAILED(IDirect3DVertexBuffer9_Lock(vbo, 0, (UINT) vertsize, &ptr, D3DLOCK_DISCARD))) { - vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */ - } else { - SDL_memcpy(ptr, vertices, vertsize); - if (FAILED(IDirect3DVertexBuffer9_Unlock(vbo))) { + void *ptr; + if (FAILED(IDirect3DVertexBuffer9_Lock(vbo, 0, (UINT) vertsize, &ptr, D3DLOCK_DISCARD))) { vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */ + } else { + SDL_memcpy(ptr, vertices, vertsize); + if (FAILED(IDirect3DVertexBuffer9_Unlock(vbo))) { + vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */ + } } } - } - /* cycle through a few VBOs so D3D has some time with the data before we replace it. */ - if (vbo) { - data->currentVertexBuffer++; - if (data->currentVertexBuffer >= SDL_arraysize(data->vertexBuffers)) { - data->currentVertexBuffer = 0; + /* cycle through a few VBOs so D3D has some time with the data before we replace it. */ + if (vbo) { + data->currentVertexBuffer++; + if (data->currentVertexBuffer >= SDL_arraysize(data->vertexBuffers)) { + data->currentVertexBuffer = 0; + } + } else if (!data->reportedVboProblem) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL failed to get a vertex buffer for this Direct3D 9 rendering batch!"); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Dropping back to a slower method."); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This might be a brief hiccup, but if performance is bad, this is probably why."); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This error will not be logged again for this renderer."); + data->reportedVboProblem = SDL_TRUE; } - } else if (!data->reportedVboProblem) { - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL failed to get a vertex buffer for this Direct3D 9 rendering batch!"); - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Dropping back to a slower method."); - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This might be a brief hiccup, but if performance is bad, this is probably why."); - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This error will not be logged again for this renderer."); - data->reportedVboProblem = SDL_TRUE; } IDirect3DDevice9_SetStreamSource(data->device, 0, vbo, 0, sizeof (Vertex)); @@ -1316,20 +1183,21 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti const SDL_Rect *viewport = &data->drawstate.viewport; const int backw = istarget ? renderer->target->w : data->pparams.BackBufferWidth; const int backh = istarget ? renderer->target->h : data->pparams.BackBufferHeight; + const SDL_bool viewport_equal = ((viewport->x == 0) && (viewport->y == 0) && (viewport->w == backw) && (viewport->h == backh)) ? SDL_TRUE : SDL_FALSE; - if (data->drawstate.cliprect_enabled) { + if (data->drawstate.cliprect_enabled || data->drawstate.cliprect_enabled_dirty) { IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, FALSE); - data->drawstate.cliprect_enabled_dirty = SDL_TRUE; + data->drawstate.cliprect_enabled_dirty = data->drawstate.cliprect_enabled; } /* Don't reset the viewport if we don't have to! */ - if (!viewport->x && !viewport->y && (viewport->w == backw) && (viewport->h == backh)) { + if (!data->drawstate.viewport_dirty && viewport_equal) { IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0); } else { /* Clear is defined to clear the entire render target */ const D3DVIEWPORT9 wholeviewport = { 0, 0, backw, backh, 0.0f, 1.0f }; IDirect3DDevice9_SetViewport(data->device, &wholeviewport); - data->drawstate.viewport_dirty = SDL_TRUE; + data->drawstate.viewport_dirty = SDL_TRUE; /* we still need to (re)set orthographic projection, so always mark it dirty. */ IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0); } @@ -1374,58 +1242,24 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti break; } - case SDL_RENDERCMD_FILL_RECTS: { + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; + + case SDL_RENDERCMD_COPY: /* unused */ + break; + + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; + + case SDL_RENDERCMD_GEOMETRY: { const size_t count = cmd->data.draw.count; const size_t first = cmd->data.draw.first; SetDrawState(data, cmd); if (vbo) { - size_t offset = 0; - for (i = 0; i < count; ++i, offset += 4) { - IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) ((first / sizeof (Vertex)) + offset), 2); - } + IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLELIST, (UINT) (first / sizeof (Vertex)), (UINT) count / 3); } else { - const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first); - for (i = 0; i < count; ++i, verts += 4) { - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex)); - } - } - break; - } - - case SDL_RENDERCMD_COPY: { - const size_t count = cmd->data.draw.count; - const size_t first = cmd->data.draw.first; - SetDrawState(data, cmd); - if (vbo) { - size_t offset = 0; - for (i = 0; i < count; ++i, offset += 4) { - IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) ((first / sizeof (Vertex)) + offset), 2); - } - } else { - const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first); - for (i = 0; i < count; ++i, verts += 4) { - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex)); - } - } - break; - } - - case SDL_RENDERCMD_COPY_EX: { - const size_t first = cmd->data.draw.first; - const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first); - const Vertex *transvert = verts + 4; - const float translatex = transvert->x; - const float translatey = transvert->y; - const float rotation = transvert->z; - const Float4X4 d3dmatrix = MatrixMultiply(MatrixRotationZ(rotation), MatrixTranslation(translatex, translatey, 0)); - SetDrawState(data, cmd); - - IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix); - - if (vbo) { - IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) (first / sizeof (Vertex)), 2); - } else { - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex)); + const Vertex* verts = (Vertex*)(((Uint8*)vertices) + first); + IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLELIST, (UINT) count / 3, verts, sizeof(Vertex)); } break; } @@ -1452,6 +1286,7 @@ D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, RECT d3drect; D3DLOCKED_RECT locked; HRESULT result; + int status; if (data->currentRenderTarget) { backBuffer = data->currentRenderTarget; @@ -1486,7 +1321,7 @@ D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, return D3D_SetError("LockRect()", result); } - SDL_ConvertPixels(rect->w, rect->h, + status = SDL_ConvertPixels(rect->w, rect->h, D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch, format, pixels, pitch); @@ -1494,7 +1329,7 @@ D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, IDirect3DSurface9_Release(surface); - return 0; + return status; } static void @@ -1533,10 +1368,12 @@ D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) renderdata->drawstate.shader = NULL; IDirect3DDevice9_SetPixelShader(renderdata->device, NULL); IDirect3DDevice9_SetTexture(renderdata->device, 0, NULL); +#if SDL_HAVE_YUV if (data->yuv) { IDirect3DDevice9_SetTexture(renderdata->device, 1, NULL); IDirect3DDevice9_SetTexture(renderdata->device, 2, NULL); } +#endif } if (!data) { @@ -1544,9 +1381,11 @@ D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) } D3D_DestroyTextureRep(&data->texture); +#if SDL_HAVE_YUV D3D_DestroyTextureRep(&data->utexture); D3D_DestroyTextureRep(&data->vtexture); SDL_free(data->pixels); +#endif SDL_free(data); texture->driverdata = NULL; } @@ -1568,12 +1407,14 @@ D3D_DestroyRenderer(SDL_Renderer * renderer) IDirect3DSurface9_Release(data->currentRenderTarget); data->currentRenderTarget = NULL; } +#if SDL_HAVE_YUV for (i = 0; i < SDL_arraysize(data->shaders); ++i) { if (data->shaders[i]) { IDirect3DPixelShader9_Release(data->shaders[i]); data->shaders[i] = NULL; } } +#endif /* Release all vertex buffers */ for (i = 0; i < SDL_arraysize(data->vertexBuffers); ++i) { if (data->vertexBuffers[i]) { @@ -1603,6 +1444,12 @@ D3D_Reset(SDL_Renderer * renderer) SDL_Texture *texture; int i; + /* Cancel any scene that we've started */ + if (!data->beginScene) { + IDirect3DDevice9_EndScene(data->device); + data->beginScene = SDL_TRUE; + } + /* Release the default render target before reset */ if (data->defaultRenderTarget) { IDirect3DSurface9_Release(data->defaultRenderTarget); @@ -1657,7 +1504,6 @@ D3D_Reset(SDL_Renderer * renderer) data->drawstate.texture = NULL; data->drawstate.shader = NULL; data->drawstate.blend = SDL_BLENDMODE_INVALID; - data->drawstate.is_copy_ex = SDL_FALSE; IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix); /* Let the application know that render targets were reset */ @@ -1670,6 +1516,24 @@ D3D_Reset(SDL_Renderer * renderer) return 0; } +static int +D3D_SetVSync(SDL_Renderer * renderer, const int vsync) +{ + D3D_RenderData *data = renderer->driverdata; + if (vsync) { + data->pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + data->pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + if (D3D_Reset(renderer) < 0) { + /* D3D_Reset will call SDL_SetError() */ + return -1; + } + return 0; +} + SDL_Renderer * D3D_CreateRenderer(SDL_Window * window, Uint32 flags) { @@ -1710,7 +1574,9 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->SupportsBlendMode = D3D_SupportsBlendMode; renderer->CreateTexture = D3D_CreateTexture; renderer->UpdateTexture = D3D_UpdateTexture; +#if SDL_HAVE_YUV renderer->UpdateTextureYUV = D3D_UpdateTextureYUV; +#endif renderer->LockTexture = D3D_LockTexture; renderer->UnlockTexture = D3D_UnlockTexture; renderer->SetTextureScaleMode = D3D_SetTextureScaleMode; @@ -1719,14 +1585,13 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->QueueSetDrawColor = D3D_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = D3D_QueueDrawPoints; renderer->QueueDrawLines = D3D_QueueDrawPoints; /* lines and points queue vertices the same way. */ - renderer->QueueFillRects = D3D_QueueFillRects; - renderer->QueueCopy = D3D_QueueCopy; - renderer->QueueCopyEx = D3D_QueueCopyEx; + renderer->QueueGeometry = D3D_QueueGeometry; renderer->RunCommandQueue = D3D_RunCommandQueue; renderer->RenderReadPixels = D3D_RenderReadPixels; renderer->RenderPresent = D3D_RenderPresent; renderer->DestroyTexture = D3D_DestroyTexture; renderer->DestroyRenderer = D3D_DestroyRenderer; + renderer->SetVSync = D3D_SetVSync; renderer->info = D3D_RenderDriver.info; renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); renderer->driverdata = data; @@ -1811,9 +1676,6 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) IDirect3DDevice9_GetDeviceCaps(data->device, &caps); renderer->info.max_texture_width = caps.MaxTextureWidth; renderer->info.max_texture_height = caps.MaxTextureHeight; - if (caps.NumSimultaneousRTs >= 2) { - renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE; - } if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) { data->enableSeparateAlphaBlend = SDL_TRUE; @@ -1825,7 +1687,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) /* Set up parameters for rendering */ D3D_InitRenderState(data); - +#if SDL_HAVE_YUV if (caps.MaxSimultaneousTextures >= 3) { int i; for (i = 0; i < SDL_arraysize(data->shaders); ++i) { @@ -1839,7 +1701,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV; } } - +#endif data->drawstate.blend = SDL_BLENDMODE_INVALID; return renderer; diff --git a/Engine/lib/sdl/src/render/direct3d/SDL_shaders_d3d.c b/Engine/lib/sdl/src/render/direct3d/SDL_shaders_d3d.c index 7ab4cbc23..d734351c8 100644 --- a/Engine/lib/sdl/src/render/direct3d/SDL_shaders_d3d.c +++ b/Engine/lib/sdl/src/render/direct3d/SDL_shaders_d3d.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/direct3d/SDL_shaders_d3d.h b/Engine/lib/sdl/src/render/direct3d/SDL_shaders_d3d.h index 4c8e711f3..b7715cb75 100644 --- a/Engine/lib/sdl/src/render/direct3d/SDL_shaders_d3d.h +++ b/Engine/lib/sdl/src/render/direct3d/SDL_shaders_d3d.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c b/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c index d814abc5d..89e2ee544 100644 --- a/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c +++ b/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,6 +20,9 @@ */ #include "../../SDL_internal.h" +#include "SDL_render.h" +#include "SDL_system.h" + #if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED #define COBJMACROS @@ -51,13 +54,17 @@ extern ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNat #endif /* __WINRT__ */ +#if defined(_MSC_VER) && !defined(__clang__) +#define SDL_COMPOSE_ERROR(str) __FUNCTION__ ", " str +#else #define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str +#endif #define SAFE_RELEASE(X) if ((X)) { IUnknown_Release(SDL_static_cast(IUnknown*, X)); X = NULL; } -/* !!! FIXME: vertex buffer bandwidth could be significantly lower; move color to a uniform, only use UV coords - !!! FIXME: when textures are needed, and don't ever pass Z, since it's always zero. */ +/* !!! FIXME: vertex buffer bandwidth could be lower; only use UV coords when + !!! FIXME: textures are needed. */ /* Vertex shader, common values */ typedef struct @@ -69,9 +76,9 @@ typedef struct /* Per-vertex data */ typedef struct { - Float3 pos; + Float2 pos; Float2 tex; - Float4 color; + SDL_Color color; } VertexPositionColor; /* Per-texture data */ @@ -84,7 +91,7 @@ typedef struct int lockedTexturePositionX; int lockedTexturePositionY; D3D11_FILTER scaleMode; - +#if SDL_HAVE_YUV /* YV12 texture support */ SDL_bool yuv; ID3D11Texture2D *mainTextureU; @@ -100,6 +107,7 @@ typedef struct Uint8 *pixels; int pitch; SDL_Rect locked_rect; +#endif } D3D11_TextureData; /* Blend mode data */ @@ -176,11 +184,13 @@ typedef struct static const GUID SDL_IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } }; static const GUID SDL_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } }; +#if defined(__WINRT__) && NTDDI_VERSION > NTDDI_WIN8 static const GUID SDL_IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } }; +#endif static const GUID SDL_IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } }; static const GUID SDL_IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } }; static const GUID SDL_IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } }; -static const GUID SDL_IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } }; +/*static const GUID SDL_IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } };*/ #ifdef __GNUC__ #pragma GCC diagnostic pop @@ -478,6 +488,11 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) creationFlags |= D3D11_CREATE_DEVICE_DEBUG; } + /* Create a single-threaded device unless the app requests otherwise. */ + if (!SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D_THREADSAFE, SDL_FALSE)) { + creationFlags |= D3D11_CREATE_DEVICE_SINGLETHREADED; + } + /* Create the Direct3D 11 API device object and a corresponding context. */ result = D3D11CreateDeviceFunc( data->dxgiAdapter, @@ -691,7 +706,10 @@ D3D11_GetRotationForCurrentRenderTarget(SDL_Renderer * renderer) static int D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRect, D3D11_RECT * outRect, BOOL includeViewportOffset) { + D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer); + const SDL_Rect *viewport = &data->currentViewport; + switch (rotation) { case DXGI_MODE_ROTATION_IDENTITY: outRect->left = sdlRect->x; @@ -699,27 +717,27 @@ D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRec outRect->top = sdlRect->y; outRect->bottom = sdlRect->y + sdlRect->h; if (includeViewportOffset) { - outRect->left += renderer->viewport.x; - outRect->right += renderer->viewport.x; - outRect->top += renderer->viewport.y; - outRect->bottom += renderer->viewport.y; + outRect->left += viewport->x; + outRect->right += viewport->x; + outRect->top += viewport->y; + outRect->bottom += viewport->y; } break; case DXGI_MODE_ROTATION_ROTATE270: outRect->left = sdlRect->y; outRect->right = sdlRect->y + sdlRect->h; - outRect->top = renderer->viewport.w - sdlRect->x - sdlRect->w; - outRect->bottom = renderer->viewport.w - sdlRect->x; + outRect->top = viewport->w - sdlRect->x - sdlRect->w; + outRect->bottom = viewport->w - sdlRect->x; break; case DXGI_MODE_ROTATION_ROTATE180: - outRect->left = renderer->viewport.w - sdlRect->x - sdlRect->w; - outRect->right = renderer->viewport.w - sdlRect->x; - outRect->top = renderer->viewport.h - sdlRect->y - sdlRect->h; - outRect->bottom = renderer->viewport.h - sdlRect->y; + outRect->left = viewport->w - sdlRect->x - sdlRect->w; + outRect->right = viewport->w - sdlRect->x; + outRect->top = viewport->h - sdlRect->y - sdlRect->h; + outRect->bottom = viewport->h - sdlRect->y; break; case DXGI_MODE_ROTATION_ROTATE90: - outRect->left = renderer->viewport.h - sdlRect->y - sdlRect->h; - outRect->right = renderer->viewport.h - sdlRect->y; + outRect->left = viewport->h - sdlRect->y - sdlRect->h; + outRect->right = viewport->h - sdlRect->y; outRect->top = sdlRect->x; outRect->bottom = sdlRect->x + sdlRect->h; break; @@ -761,7 +779,11 @@ D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h) if (usingXAML) { swapChainDesc.Scaling = DXGI_SCALING_STRETCH; } else { - swapChainDesc.Scaling = DXGI_SCALING_NONE; + if (WIN_IsWindows8OrGreater()) { + swapChainDesc.Scaling = DXGI_SCALING_NONE; + } else { + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + } } swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; /* All Windows Store apps must use this SwapEffect. */ #endif @@ -944,11 +966,13 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) * * TODO, WinRT: reexamine the docs for IDXGISwapChain1::SetRotation, see if might be available, usable, and prudent-to-call on WinPhone 8.1 */ - if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) { - result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::SetRotation"), result); - goto done; + if (WIN_IsWindows8OrGreater()) { + if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) { + result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::SetRotation"), result); + goto done; + } } } #endif @@ -1091,10 +1115,9 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); } - +#if SDL_HAVE_YUV if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { textureData->yuv = SDL_TRUE; @@ -1109,8 +1132,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); } result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice, @@ -1120,8 +1142,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); } } @@ -1142,11 +1163,10 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); } } - +#endif /* SDL_HAVE_YUV */ resourceViewDesc.Format = textureDesc.Format; resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; resourceViewDesc.Texture2D.MostDetailedMip = 0; @@ -1158,10 +1178,9 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); } - +#if SDL_HAVE_YUV if (textureData->yuv) { result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice, (ID3D11Resource *)textureData->mainTextureU, @@ -1170,8 +1189,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); } result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice, (ID3D11Resource *)textureData->mainTextureV, @@ -1180,8 +1198,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); } } @@ -1197,8 +1214,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); } } @@ -1214,11 +1230,10 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) &textureData->mainTextureRenderTargetView); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result); } } - +#endif /* SDL_HAVE_YUV */ return 0; } @@ -1236,11 +1251,15 @@ D3D11_DestroyTexture(SDL_Renderer * renderer, SAFE_RELEASE(data->mainTextureResourceView); SAFE_RELEASE(data->mainTextureRenderTargetView); SAFE_RELEASE(data->stagingTexture); +#if SDL_HAVE_YUV SAFE_RELEASE(data->mainTextureU); SAFE_RELEASE(data->mainTextureResourceViewU); SAFE_RELEASE(data->mainTextureV); SAFE_RELEASE(data->mainTextureResourceViewV); + SAFE_RELEASE(data->mainTextureNV); + SAFE_RELEASE(data->mainTextureResourceViewNV); SDL_free(data->pixels); +#endif SDL_free(data); texture->driverdata = NULL; } @@ -1270,8 +1289,7 @@ D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *tex NULL, &stagingTexture); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); } /* Get a write-only pointer to data in the staging texture: */ @@ -1283,9 +1301,8 @@ D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *tex &textureMemory ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); SAFE_RELEASE(stagingTexture); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); } src = (const Uint8 *)pixels; @@ -1337,14 +1354,13 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata; if (!textureData) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, srcPixels, srcPitch) < 0) { return -1; } - +#if SDL_HAVE_YUV if (textureData->yuv) { /* Skip to the correct offset into the next texture */ srcPixels = (const void*)((const Uint8*)srcPixels + rect->h * srcPitch); @@ -1368,9 +1384,11 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } } +#endif /* SDL_HAVE_YUV */ return 0; } +#if SDL_HAVE_YUV static int D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, @@ -1382,8 +1400,7 @@ D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata; if (!textureData) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) { @@ -1398,6 +1415,30 @@ D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, return 0; } +static int +D3D11_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ + D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; + D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata; + + if (!textureData) { + return SDL_SetError("Texture is not currently available"); + } + + if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) { + return -1; + } + + if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureNV, 2, rect->x / 2, rect->y / 2, ((rect->w + 1) / 2), (rect->h + 1) / 2, UVplane, UVpitch) < 0) { + return -1; + } + return 0; +} +#endif + static int D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch) @@ -1409,10 +1450,9 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, D3D11_MAPPED_SUBRESOURCE textureMemory; if (!textureData) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } - +#if SDL_HAVE_YUV if (textureData->yuv || textureData->nv12) { /* It's more efficient to upload directly... */ if (!textureData->pixels) { @@ -1429,7 +1469,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, *pitch = textureData->pitch; return 0; } - +#endif if (textureData->stagingTexture) { return SDL_SetError("texture is already locked"); } @@ -1454,8 +1494,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, NULL, &textureData->stagingTexture); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); } /* Get a write-only pointer to data in the staging texture: */ @@ -1467,9 +1506,8 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, &textureMemory ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); SAFE_RELEASE(textureData->stagingTexture); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); } /* Make note of where the staging texture will be written to @@ -1495,7 +1533,7 @@ D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (!textureData) { return; } - +#if SDL_HAVE_YUV if (textureData->yuv || textureData->nv12) { const SDL_Rect *rect = &textureData->locked_rect; void *pixels = @@ -1504,7 +1542,7 @@ D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) D3D11_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch); return; } - +#endif /* Commit the pixel buffer's changes back to the staging texture: */ ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)textureData->stagingTexture, @@ -1568,11 +1606,12 @@ static int D3D11_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) { VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertexPositionColor), 0, &cmd->data.draw.first); - const float r = (float)(cmd->data.draw.r / 255.0f); - const float g = (float)(cmd->data.draw.g / 255.0f); - const float b = (float)(cmd->data.draw.b / 255.0f); - const float a = (float)(cmd->data.draw.a / 255.0f); int i; + SDL_Color color; + color.r = cmd->data.draw.r; + color.g = cmd->data.draw.g; + color.b = cmd->data.draw.b; + color.a = cmd->data.draw.a; if (!verts) { return -1; @@ -1583,13 +1622,9 @@ D3D11_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL for (i = 0; i < count; i++) { verts->pos.x = points[i].x + 0.5f; verts->pos.y = points[i].y + 0.5f; - verts->pos.z = 0.0f; verts->tex.x = 0.0f; verts->tex.y = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; + verts->color = color; verts++; } @@ -1597,238 +1632,55 @@ D3D11_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL } static int -D3D11_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +D3D11_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) { - VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * 4 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first); - const float r = (float)(cmd->data.draw.r / 255.0f); - const float g = (float)(cmd->data.draw.g / 255.0f); - const float b = (float)(cmd->data.draw.b / 255.0f); - const float a = (float)(cmd->data.draw.a / 255.0f); int i; + int count = indices ? num_indices : num_vertices; + VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertexPositionColor), 0, &cmd->data.draw.first); if (!verts) { return -1; } cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; for (i = 0; i < count; i++) { - verts->pos.x = rects[i].x; - verts->pos.y = rects[i].y; - verts->pos.z = 0.0f; - verts->tex.x = 0.0f; - verts->tex.y = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; + int j; + float *xy_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } - verts->pos.x = rects[i].x; - verts->pos.y = rects[i].y + rects[i].h; - verts->pos.z = 0.0f; - verts->tex.x = 0.0f; - verts->tex.y = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; + xy_ = (float *)((char*)xy + j * xy_stride); - verts->pos.x = rects[i].x + rects[i].w; - verts->pos.y = rects[i].y; - verts->pos.z = 0.0f; - verts->tex.x = 0.0f; - verts->tex.y = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; + verts->pos.x = xy_[0] * scale_x; + verts->pos.y = xy_[1] * scale_y; + verts->color = *(SDL_Color*)((char*)color + j * color_stride); - verts->pos.x = rects[i].x + rects[i].w; - verts->pos.y = rects[i].y + rects[i].h; - verts->pos.z = 0.0f; - verts->tex.x = 0.0f; - verts->tex.y = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; + if (texture) { + float *uv_ = (float *)((char*)uv + j * uv_stride); + verts->tex.x = uv_[0]; + verts->tex.y = uv_[1]; + } else { + verts->tex.x = 0.0f; + verts->tex.y = 0.0f; + } + + verts += 1; } - return 0; } -static int -D3D11_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) -{ - VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, 4 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first); - const float r = (float)(cmd->data.draw.r / 255.0f); - const float g = (float)(cmd->data.draw.g / 255.0f); - const float b = (float)(cmd->data.draw.b / 255.0f); - const float a = (float)(cmd->data.draw.a / 255.0f); - const float minu = (float) srcrect->x / texture->w; - const float maxu = (float) (srcrect->x + srcrect->w) / texture->w; - const float minv = (float) srcrect->y / texture->h; - const float maxv = (float) (srcrect->y + srcrect->h) / texture->h; - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - verts->pos.x = dstrect->x; - verts->pos.y = dstrect->y; - verts->pos.z = 0.0f; - verts->tex.x = minu; - verts->tex.y = minv; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; - - verts->pos.x = dstrect->x; - verts->pos.y = dstrect->y + dstrect->h; - verts->pos.z = 0.0f; - verts->tex.x = minu; - verts->tex.y = maxv; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; - - verts->pos.x = dstrect->x + dstrect->w; - verts->pos.y = dstrect->y; - verts->pos.z = 0.0f; - verts->tex.x = maxu; - verts->tex.y = minv; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; - - verts->pos.x = dstrect->x + dstrect->w; - verts->pos.y = dstrect->y + dstrect->h; - verts->pos.z = 0.0f; - verts->tex.x = maxu; - verts->tex.y = maxv; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; - - return 0; -} - -static int -D3D11_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, 5 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first); - const float r = (float)(cmd->data.draw.r / 255.0f); - const float g = (float)(cmd->data.draw.g / 255.0f); - const float b = (float)(cmd->data.draw.b / 255.0f); - const float a = (float)(cmd->data.draw.a / 255.0f); - float minx, miny, maxx, maxy; - float minu, maxu, minv, maxv; - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - minx = -center->x; - maxx = dstrect->w - center->x; - miny = -center->y; - maxy = dstrect->h - center->y; - - if (flip & SDL_FLIP_HORIZONTAL) { - minu = (float) (srcrect->x + srcrect->w) / texture->w; - maxu = (float) srcrect->x / texture->w; - } else { - minu = (float) srcrect->x / texture->w; - maxu = (float) (srcrect->x + srcrect->w) / texture->w; - } - - if (flip & SDL_FLIP_VERTICAL) { - minv = (float) (srcrect->y + srcrect->h) / texture->h; - maxv = (float) srcrect->y / texture->h; - } else { - minv = (float) srcrect->y / texture->h; - maxv = (float) (srcrect->y + srcrect->h) / texture->h; - } - - - - verts->pos.x = minx; - verts->pos.y = miny; - verts->pos.z = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts->tex.x = minu; - verts->tex.y = minv; - verts++; - - verts->pos.x = minx; - verts->pos.y = maxy; - verts->pos.z = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts->tex.x = minu; - verts->tex.y = maxv; - verts++; - - verts->pos.x = maxx; - verts->pos.y = miny; - verts->pos.z = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts->tex.x = maxu; - verts->tex.y = minv; - verts++; - - verts->pos.x = maxx; - verts->pos.y = maxy; - verts->pos.z = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts->tex.x = maxu; - verts->tex.y = maxv; - verts++; - - verts->pos.x = dstrect->x + center->x; /* X translation */ - verts->pos.y = dstrect->y + center->y; /* Y translation */ - verts->pos.z = (float)(M_PI * (float) angle / 180.0f); /* rotation */ - verts->color.x = 0; - verts->color.y = 0; - verts->color.z = 0; - verts->color.w = 0; - verts->tex.x = 0.0f; - verts->tex.y = 0.0f; - verts++; - - return 0; -} - - static int D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, const void * vertexData, size_t dataSizeInBytes) @@ -1853,8 +1705,7 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, &mappedResource ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [vertex buffer]"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [vertex buffer]"), result); } SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes); ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffers[vbidx], 0); @@ -1881,8 +1732,7 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, &rendererData->vertexBuffers[vbidx] ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result); } rendererData->vertexBufferSizes[vbidx] = dataSizeInBytes; @@ -2135,7 +1985,7 @@ D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const default: return SDL_SetError("Unknown scale mode: %d\n", textureData->scaleMode); } - +#if SDL_HAVE_YUV if (textureData->yuv) { ID3D11ShaderResourceView *shaderResources[] = { textureData->mainTextureResourceView, @@ -2186,7 +2036,7 @@ D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const SDL_arraysize(shaderResources), shaderResources, textureSampler, matrix); } - +#endif /* SDL_HAVE_YUV */ return D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_RGB], 1, &textureData->mainTextureResourceView, textureSampler, matrix); } @@ -2204,7 +2054,6 @@ D3D11_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver { D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; const int viewportRotation = D3D11_GetRotationForCurrentRenderTarget(renderer); - size_t i; if (rendererData->currentViewportRotation != viewportRotation) { rendererData->currentViewportRotation = viewportRotation; @@ -2276,37 +2125,28 @@ D3D11_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver break; } - case SDL_RENDERCMD_FILL_RECTS: { + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; + + case SDL_RENDERCMD_COPY: /* unused */ + break; + + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; + + case SDL_RENDERCMD_GEOMETRY: { + SDL_Texture *texture = cmd->data.draw.texture; const size_t count = cmd->data.draw.count; const size_t first = cmd->data.draw.first; const size_t start = first / sizeof (VertexPositionColor); - size_t offset = 0; - D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL); - for (i = 0; i < count; i++, offset += 4) { - D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start + offset, 4); + + if (texture) { + D3D11_SetCopyState(renderer, cmd, NULL); + } else { + D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL); } - break; - } - case SDL_RENDERCMD_COPY: { - const size_t first = cmd->data.draw.first; - const size_t start = first / sizeof (VertexPositionColor); - D3D11_SetCopyState(renderer, cmd, NULL); - D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start, 4); - break; - } - - case SDL_RENDERCMD_COPY_EX: { - const size_t first = cmd->data.draw.first; - const size_t start = first / sizeof (VertexPositionColor); - const VertexPositionColor *verts = (VertexPositionColor *) (((Uint8 *) vertices) + first); - const VertexPositionColor *transvert = verts + 4; - const float translatex = transvert->pos.x; - const float translatey = transvert->pos.y; - const float rotation = transvert->pos.z; - const Float4X4 matrix = MatrixMultiply(MatrixRotationZ(rotation), MatrixTranslation(translatex, translatey, 0)); - D3D11_SetCopyState(renderer, cmd, &matrix); - D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start, 4); + D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, start, count); break; } @@ -2399,30 +2239,20 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, /* Copy the data into the desired buffer, converting pixels to the * desired format at the same time: */ - if (SDL_ConvertPixels( + status = SDL_ConvertPixels( rect->w, rect->h, D3D11_DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format), textureMemory.pData, textureMemory.RowPitch, format, pixels, - pitch) != 0) { - /* When SDL_ConvertPixels fails, it'll have already set the format. - * Get the error message, and attach some extra data to it. - */ - char errorMessage[1024]; - SDL_snprintf(errorMessage, sizeof(errorMessage), "%s, Convert Pixels failed: %s", __FUNCTION__, SDL_GetError()); - SDL_SetError("%s", errorMessage); - goto done; - } + pitch); /* Unmap the texture: */ ID3D11DeviceContext_Unmap(data->d3dContext, (ID3D11Resource *)stagingTexture, 0); - status = 0; - done: SAFE_RELEASE(backBuffer); SAFE_RELEASE(stagingTexture); @@ -2486,6 +2316,21 @@ D3D11_RenderPresent(SDL_Renderer * renderer) } } +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + /* no-op. */ +#else +static int +D3D11_SetVSync(SDL_Renderer * renderer, const int vsync) +{ + if (vsync) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return 0; +} +#endif + SDL_Renderer * D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) { @@ -2500,6 +2345,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) data = (D3D11_RenderData *) SDL_calloc(1, sizeof(*data)); if (!data) { + SDL_free(renderer); SDL_OutOfMemory(); return NULL; } @@ -2510,7 +2356,10 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->SupportsBlendMode = D3D11_SupportsBlendMode; renderer->CreateTexture = D3D11_CreateTexture; renderer->UpdateTexture = D3D11_UpdateTexture; +#if SDL_HAVE_YUV renderer->UpdateTextureYUV = D3D11_UpdateTextureYUV; + renderer->UpdateTextureNV = D3D11_UpdateTextureNV; +#endif renderer->LockTexture = D3D11_LockTexture; renderer->UnlockTexture = D3D11_UnlockTexture; renderer->SetTextureScaleMode = D3D11_SetTextureScaleMode; @@ -2519,9 +2368,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->QueueSetDrawColor = D3D11_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = D3D11_QueueDrawPoints; renderer->QueueDrawLines = D3D11_QueueDrawPoints; /* lines and points queue vertices the same way. */ - renderer->QueueFillRects = D3D11_QueueFillRects; - renderer->QueueCopy = D3D11_QueueCopy; - renderer->QueueCopyEx = D3D11_QueueCopyEx; + renderer->QueueGeometry = D3D11_QueueGeometry; renderer->RunCommandQueue = D3D11_RunCommandQueue; renderer->RenderReadPixels = D3D11_RenderReadPixels; renderer->RenderPresent = D3D11_RenderPresent; @@ -2548,6 +2395,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) if ((flags & SDL_RENDERER_PRESENTVSYNC)) { renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } + renderer->SetVSync = D3D11_SetVSync; #endif /* HACK: make sure the SDL_Renderer references the SDL_Window data now, in @@ -2593,4 +2441,30 @@ SDL_RenderDriver D3D11_RenderDriver = { #endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ +#ifdef __WIN32__ +/* This function needs to always exist on Windows, for the Dynamic API. */ +ID3D11Device * +SDL_RenderGetD3D11Device(SDL_Renderer * renderer) +{ + ID3D11Device *device = NULL; + +#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED + D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + + /* Make sure that this is a D3D renderer */ + if (renderer->DestroyRenderer != D3D11_DestroyRenderer) { + SDL_SetError("Renderer is not a D3D11 renderer"); + return NULL; + } + + device = (ID3D11Device *)data->d3dDevice; + if (device) { + ID3D11Device_AddRef(device); + } +#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ + + return device; +} +#endif /* __WIN32__ */ + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/direct3d11/SDL_render_winrt.cpp b/Engine/lib/sdl/src/render/direct3d11/SDL_render_winrt.cpp index 329b3ff2a..9784c32c4 100644 --- a/Engine/lib/sdl/src/render/direct3d11/SDL_render_winrt.cpp +++ b/Engine/lib/sdl/src/render/direct3d11/SDL_render_winrt.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/direct3d11/SDL_render_winrt.h b/Engine/lib/sdl/src/render/direct3d11/SDL_render_winrt.h index c2fd3a4c4..97d27cb27 100644 --- a/Engine/lib/sdl/src/render/direct3d11/SDL_render_winrt.h +++ b/Engine/lib/sdl/src/render/direct3d11/SDL_render_winrt.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/direct3d11/SDL_shaders_d3d11.c b/Engine/lib/sdl/src/render/direct3d11/SDL_shaders_d3d11.c index 4c23f6d76..3a6807b5f 100644 --- a/Engine/lib/sdl/src/render/direct3d11/SDL_shaders_d3d11.c +++ b/Engine/lib/sdl/src/render/direct3d11/SDL_shaders_d3d11.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -1886,9 +1886,10 @@ static struct { const void *shader_data; SIZE_T shader_size; -} D3D11_shaders[] = { +} D3D11_shaders[NUM_SHADERS] = { { D3D11_PixelShader_Colors, sizeof(D3D11_PixelShader_Colors) }, { D3D11_PixelShader_Textures, sizeof(D3D11_PixelShader_Textures) }, +#if SDL_HAVE_YUV { D3D11_PixelShader_YUV_JPEG, sizeof(D3D11_PixelShader_YUV_JPEG) }, { D3D11_PixelShader_YUV_BT601, sizeof(D3D11_PixelShader_YUV_BT601) }, { D3D11_PixelShader_YUV_BT709, sizeof(D3D11_PixelShader_YUV_BT709) }, @@ -1898,6 +1899,7 @@ static struct { D3D11_PixelShader_NV21_JPEG, sizeof(D3D11_PixelShader_NV21_JPEG) }, { D3D11_PixelShader_NV21_BT601, sizeof(D3D11_PixelShader_NV21_BT601) }, { D3D11_PixelShader_NV21_BT709, sizeof(D3D11_PixelShader_NV21_BT709) }, +#endif }; int D3D11_CreateVertexShader(ID3D11Device1 *d3dDevice, ID3D11VertexShader **vertexShader, ID3D11InputLayout **inputLayout) @@ -1905,9 +1907,9 @@ int D3D11_CreateVertexShader(ID3D11Device1 *d3dDevice, ID3D11VertexShader **vert /* Declare how the input layout for SDL's vertex shader will be setup: */ const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; HRESULT result; diff --git a/Engine/lib/sdl/src/render/direct3d11/SDL_shaders_d3d11.h b/Engine/lib/sdl/src/render/direct3d11/SDL_shaders_d3d11.h index cffb99807..d877c0906 100644 --- a/Engine/lib/sdl/src/render/direct3d11/SDL_shaders_d3d11.h +++ b/Engine/lib/sdl/src/render/direct3d11/SDL_shaders_d3d11.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,6 +25,7 @@ typedef enum { SHADER_SOLID, SHADER_RGB, +#if SDL_HAVE_YUV SHADER_YUV_JPEG, SHADER_YUV_BT601, SHADER_YUV_BT709, @@ -34,6 +35,7 @@ typedef enum { SHADER_NV21_JPEG, SHADER_NV21_BT601, SHADER_NV21_BT709, +#endif NUM_SHADERS } D3D11_Shader; diff --git a/Engine/lib/sdl/src/render/metal/SDL_render_metal.m b/Engine/lib/sdl/src/render/metal/SDL_render_metal.m index c9b205c87..329e5b3a0 100644 --- a/Engine/lib/sdl/src/render/metal/SDL_render_metal.m +++ b/Engine/lib/sdl/src/render/metal/SDL_render_metal.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,6 +32,7 @@ #import #ifdef __MACOSX__ +#import #import #endif @@ -59,7 +60,7 @@ extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags); /* macOS requires constants in a buffer to have a 256 byte alignment. */ /* Use native type alignments from https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf */ -#if defined(__MACOSX__) || TARGET_OS_SIMULATOR +#if defined(__MACOSX__) || TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST #define CONSTANT_ALIGN(x) (256) #else #define CONSTANT_ALIGN(x) (x < 4 ? 4 : x) @@ -166,11 +167,12 @@ typedef struct METAL_ShaderPipelines @property (nonatomic, retain) id mtltexture_uv; @property (nonatomic, retain) id mtlsampler; @property (nonatomic, assign) SDL_MetalFragmentFunction fragmentFunction; +#if SDL_HAVE_YUV @property (nonatomic, assign) BOOL yuv; @property (nonatomic, assign) BOOL nv12; @property (nonatomic, assign) size_t conversionBufferOffset; +#endif @property (nonatomic, assign) BOOL hasdata; - @property (nonatomic, retain) id lockedbuffer; @property (nonatomic, assign) SDL_Rect lockedrect; @end @@ -279,26 +281,35 @@ MakePipelineState(METAL_RenderData *data, METAL_PipelineCache *cache, switch (cache->vertexFunction) { case SDL_METAL_VERTEX_SOLID: - /* position (float2) */ - vertdesc.layouts[0].stride = sizeof(float) * 2; + /* position (float2), color (uchar4normalized) */ + vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof (int); vertdesc.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex; vertdesc.attributes[0].format = MTLVertexFormatFloat2; vertdesc.attributes[0].offset = 0; vertdesc.attributes[0].bufferIndex = 0; + + vertdesc.attributes[1].format = MTLVertexFormatUChar4Normalized; + vertdesc.attributes[1].offset = sizeof (float) * 2; + vertdesc.attributes[1].bufferIndex = 0; + break; case SDL_METAL_VERTEX_COPY: - /* position (float2), texcoord (float2) */ - vertdesc.layouts[0].stride = sizeof(float) * 4; + /* position (float2), color (uchar4normalized), texcoord (float2) */ + vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof (int) + sizeof (float) * 2; vertdesc.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex; vertdesc.attributes[0].format = MTLVertexFormatFloat2; vertdesc.attributes[0].offset = 0; vertdesc.attributes[0].bufferIndex = 0; - vertdesc.attributes[1].format = MTLVertexFormatFloat2; - vertdesc.attributes[1].offset = sizeof(float) * 2; + vertdesc.attributes[1].format = MTLVertexFormatUChar4Normalized; + vertdesc.attributes[1].offset = sizeof (float) * 2; vertdesc.attributes[1].bufferIndex = 0; + + vertdesc.attributes[2].format = MTLVertexFormatFloat2; + vertdesc.attributes[2].offset = sizeof(float) * 2 + sizeof (int); + vertdesc.attributes[2].bufferIndex = 0; break; } @@ -450,7 +461,7 @@ ChoosePipelineState(METAL_RenderData *data, METAL_ShaderPipelines *pipelines, SD return MakePipelineState(data, cache, [NSString stringWithFormat:@" (blend=custom 0x%x)", blendmode], blendmode); } -static void +static SDL_bool METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load, MTLClearColor *clear_color, id vertex_buffer) { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; @@ -472,10 +483,16 @@ METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load, load = MTLLoadActionDontCare; } } - mtltexture = data.mtlbackbuffer.texture; + if (data.mtlbackbuffer != nil) { + mtltexture = data.mtlbackbuffer.texture; + } } - SDL_assert(mtltexture); + /* mtltexture can be nil here if macOS refused to give us a drawable, + which apparently can happen for minimized windows, etc. */ + if (mtltexture == nil) { + return SDL_FALSE; + } if (load == MTLLoadActionClear) { SDL_assert(clear_color != NULL); @@ -508,6 +525,8 @@ METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load, // or whatever. This means we can _always_ batch rendering commands! [data.mtlcmdbuffer enqueue]; } + + return SDL_TRUE; } static void @@ -587,14 +606,14 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) mtltexdesc.usage = MTLTextureUsageShaderRead; } } - + id mtltexture = [data.mtldevice newTextureWithDescriptor:mtltexdesc]; if (mtltexture == nil) { return SDL_SetError("Texture allocation failed"); } id mtltexture_uv = nil; - +#if SDL_HAVE_YUV BOOL yuv = (texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12); BOOL nv12 = (texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21); @@ -619,7 +638,7 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return SDL_SetError("Texture allocation failed"); } } - +#endif /* SDL_HAVE_YUV */ METAL_TextureData *texturedata = [[METAL_TextureData alloc] init]; if (texture->scaleMode == SDL_ScaleModeNearest) { texturedata.mtlsampler = data.mtlsamplernearest; @@ -628,7 +647,7 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } texturedata.mtltexture = mtltexture; texturedata.mtltexture_uv = mtltexture_uv; - +#if SDL_HAVE_YUV texturedata.yuv = yuv; texturedata.nv12 = nv12; @@ -638,10 +657,12 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV12; } else if (texture->format == SDL_PIXELFORMAT_NV21) { texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV21; - } else { + } else +#endif + { texturedata.fragmentFunction = SDL_METAL_FRAGMENT_COPY; } - +#if SDL_HAVE_YUV if (yuv || nv12) { size_t offset = 0; SDL_YUV_CONVERSION_MODE mode = SDL_GetYUVConversionModeForResolution(texture->w, texture->h); @@ -653,7 +674,7 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } texturedata.conversionBufferOffset = offset; } - +#endif texture->driverdata = (void*)CFBridgingRetain(texturedata); #if !__has_feature(objc_arc) @@ -767,7 +788,7 @@ METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, if (METAL_UpdateTextureInternal(renderer, texturedata, texturedata.mtltexture, *rect, 0, pixels, pitch) < 0) { return -1; } - +#if SDL_HAVE_YUV if (texturedata.yuv) { int Uslice = texture->format == SDL_PIXELFORMAT_YV12 ? 1 : 0; int Vslice = texture->format == SDL_PIXELFORMAT_YV12 ? 0 : 1; @@ -797,12 +818,13 @@ METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } } - +#endif texturedata.hasdata = YES; return 0; }} +#if SDL_HAVE_YUV static int METAL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, @@ -835,6 +857,34 @@ METAL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, return 0; }} +static int +METAL_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ @autoreleasepool { + METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata; + SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2}; + + /* Bail out if we're supposed to update an empty rectangle */ + if (rect->w <= 0 || rect->h <= 0) { + return 0; + } + + if (METAL_UpdateTextureInternal(renderer, texturedata, texturedata.mtltexture, *rect, 0, Yplane, Ypitch) < 0) { + return -1; + } + + if (METAL_UpdateTextureInternal(renderer, texturedata, texturedata.mtltexture_uv, UVrect, 0, UVplane, UVpitch) < 0) { + return -1; + } + + texturedata.hasdata = YES; + + return 0; +}} +#endif + static int METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch) @@ -849,10 +899,12 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, } *pitch = SDL_BYTESPERPIXEL(texture->format) * rect->w; - +#if SDL_HAVE_YUV if (texturedata.yuv || texturedata.nv12) { buffersize = ((*pitch) * rect->h) + (2 * (*pitch + 1) / 2) * ((rect->h + 1) / 2); - } else { + } else +#endif + { buffersize = (*pitch) * rect->h; } @@ -906,7 +958,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(rect.x, rect.y, 0)]; - +#if SDL_HAVE_YUV if (texturedata.yuv) { int Uslice = texture->format == SDL_PIXELFORMAT_YV12 ? 1 : 0; int Vslice = texture->format == SDL_PIXELFORMAT_YV12 ? 0 : 1; @@ -946,7 +998,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) destinationLevel:0 destinationOrigin:MTLOriginMake(UVrect.x, UVrect.y, 0)]; } - +#endif [blitcmd endEncoding]; [data.mtlcmdbuffer commit]; @@ -991,13 +1043,6 @@ METAL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) }} -// normalize a value from 0.0f to len into 0.0f to 1.0f. -static inline float -normtex(const float _val, const float len) -{ - return _val / len; -} - static int METAL_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) { @@ -1031,38 +1076,66 @@ METAL_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd) if (!verts) { return -1; } + /* + * FIXME: not needed anymore, some cleanup to do + * *(verts++) = ((float)cmd->data.color.r) / 255.0f; *(verts++) = ((float)cmd->data.color.g) / 255.0f; *(verts++) = ((float)cmd->data.color.b) / 255.0f; *(verts++) = ((float)cmd->data.color.a) / 255.0f; + */ return 0; } static int METAL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) { - const size_t vertlen = (sizeof (float) * 2) * count; + const SDL_Color color = { + cmd->data.draw.r, + cmd->data.draw.g, + cmd->data.draw.b, + cmd->data.draw.a + }; + + const size_t vertlen = (2 * sizeof (float) + sizeof (SDL_Color)) * count; float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first); if (!verts) { return -1; } cmd->data.draw.count = count; - SDL_memcpy(verts, points, vertlen); + + for (int i = 0; i < count; i++, points++) { + *(verts++) = points->x; + *(verts++) = points->y; + *((SDL_Color *)verts++) = color; + } return 0; } static int METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) { + const SDL_Color color = { + cmd->data.draw.r, + cmd->data.draw.g, + cmd->data.draw.b, + cmd->data.draw.a + }; + SDL_assert(count >= 2); /* should have been checked at the higher level. */ - const size_t vertlen = (sizeof (float) * 2) * count; + const size_t vertlen = (2 * sizeof (float) + sizeof (SDL_Color)) * count; float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first); if (!verts) { return -1; } cmd->data.draw.count = count; - SDL_memcpy(verts, points, vertlen); + + for (int i = 0; i < count; i++, points++) { + *(verts++) = points->x; + *(verts++) = points->y; + *((SDL_Color *)verts++) = color; + } /* If the line segment is completely horizontal or vertical, make it one pixel longer, to satisfy the diamond-exit rule. @@ -1072,8 +1145,8 @@ METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_ that are missing a pixel that frames something and not arbitrary angles. Maybe !!! FIXME for later, though. */ - points += count - 2; /* update the last line. */ - verts += (count * 2) - 2; + points -= 2; /* update the last line. */ + verts -= 2 + 1; const float xstart = points[0].x; const float ystart = points[0].y; @@ -1090,161 +1163,50 @@ METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_ } static int -METAL_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) { - const size_t vertlen = (sizeof (float) * 8) * count; + int count = indices ? num_indices : num_vertices; + const size_t vertlen = (2 * sizeof (float) + sizeof (int) + (texture ? 2 : 0) * sizeof (float)) * count; float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first); if (!verts) { return -1; } cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; - /* Quads in the following vertex order (matches the quad index buffer): - * 1---3 - * | \ | - * 0---2 - */ - for (int i = 0; i < count; i++, rects++) { - if ((rects->w <= 0.0f) || (rects->h <= 0.0f)) { - cmd->data.draw.count--; + for (int i = 0; i < count; i++) { + int j; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; } else { - *(verts++) = rects->x; - *(verts++) = rects->y + rects->h; - *(verts++) = rects->x; - *(verts++) = rects->y; - *(verts++) = rects->x + rects->w; - *(verts++) = rects->y + rects->h; - *(verts++) = rects->x + rects->w; - *(verts++) = rects->y; + j = i; + } + + float *xy_ = (float *)((char*)xy + j * xy_stride); + + *(verts++) = xy_[0] * scale_x; + *(verts++) = xy_[1] * scale_y; + + *((SDL_Color *)verts++) = *(SDL_Color *)((char*)color + j * color_stride); + + if (texture) { + float *uv_ = (float *)((char*)uv + j * uv_stride); + *(verts++) = uv_[0]; + *(verts++) = uv_[1]; } } - if (cmd->data.draw.count == 0) { - cmd->command = SDL_RENDERCMD_NO_OP; // nothing to do, just skip this one later. - } - return 0; } -static int -METAL_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) -{ - const float texw = (float) texture->w; - const float texh = (float) texture->h; - // !!! FIXME: use an index buffer - const size_t vertlen = (sizeof (float) * 16); - float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first); - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - /* Interleaved positions and texture coordinates */ - *(verts++) = dstrect->x; - *(verts++) = dstrect->y + dstrect->h; - *(verts++) = normtex(srcrect->x, texw); - *(verts++) = normtex(srcrect->y + srcrect->h, texh); - - *(verts++) = dstrect->x; - *(verts++) = dstrect->y; - *(verts++) = normtex(srcrect->x, texw); - *(verts++) = normtex(srcrect->y, texh); - - *(verts++) = dstrect->x + dstrect->w; - *(verts++) = dstrect->y + dstrect->h; - *(verts++) = normtex(srcrect->x + srcrect->w, texw); - *(verts++) = normtex(srcrect->y + srcrect->h, texh); - - *(verts++) = dstrect->x + dstrect->w; - *(verts++) = dstrect->y; - *(verts++) = normtex(srcrect->x + srcrect->w, texw); - *(verts++) = normtex(srcrect->y, texh); - - return 0; -} - -static int -METAL_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - const float texw = (float) texture->w; - const float texh = (float) texture->h; - const float rads = (float)(M_PI * (float) angle / 180.0f); - const float c = cosf(rads), s = sinf(rads); - float minu, maxu, minv, maxv; - const size_t vertlen = (sizeof (float) * 32); - float *verts; - - // cheat and store this offset in (count) because it needs to be aligned in ways other fields don't and we aren't using count otherwise. - verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, CONSTANT_ALIGN(16), &cmd->data.draw.count); - if (!verts) { - return -1; - } - - // transform matrix - SDL_memset(verts, '\0', sizeof (*verts) * 16); - verts[10] = verts[15] = 1.0f; - // rotation - verts[0] = c; - verts[1] = s; - verts[4] = -s; - verts[5] = c; - - // translation - verts[12] = dstrect->x + center->x; - verts[13] = dstrect->y + center->y; - - // rest of the vertices don't need the aggressive alignment. Pack them in. - verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first); - if (!verts) { - return -1; - } - - minu = normtex(srcquad->x, texw); - maxu = normtex(srcquad->x + srcquad->w, texw); - minv = normtex(srcquad->y, texh); - maxv = normtex(srcquad->y + srcquad->h, texh); - - if (flip & SDL_FLIP_HORIZONTAL) { - float tmp = maxu; - maxu = minu; - minu = tmp; - } - if (flip & SDL_FLIP_VERTICAL) { - float tmp = maxv; - maxv = minv; - minv = tmp; - } - - /* Interleaved positions and texture coordinates */ - *(verts++) = -center->x; - *(verts++) = dstrect->h - center->y; - *(verts++) = minu; - *(verts++) = maxv; - - *(verts++) = -center->x; - *(verts++) = -center->y; - *(verts++) = minu; - *(verts++) = minv; - - *(verts++) = dstrect->w - center->x; - *(verts++) = dstrect->h - center->y; - *(verts++) = maxu; - *(verts++) = maxv; - - *(verts++) = dstrect->w - center->x; - *(verts++) = -center->y; - *(verts++) = maxu; - *(verts++) = minv; - - return 0; -} - - typedef struct { #if __has_feature(objc_arc) @@ -1266,7 +1228,7 @@ typedef struct size_t color_offset; } METAL_DrawStateCache; -static void +static SDL_bool SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_MetalFragmentFunction shader, const size_t constants_offset, id mtlbufvertex, METAL_DrawStateCache *statecache) { @@ -1275,7 +1237,9 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met size_t first = cmd->data.draw.first; id newpipeline; - METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, statecache->vertex_buffer); + if (!METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, statecache->vertex_buffer)) { + return SDL_FALSE; + } if (statecache->viewport_dirty) { MTLViewport viewport; @@ -1291,22 +1255,29 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met } if (statecache->cliprect_dirty) { - MTLScissorRect mtlrect; + SDL_Rect output; + SDL_Rect clip; if (statecache->cliprect_enabled) { - const SDL_Rect *rect = &statecache->cliprect; - mtlrect.x = statecache->viewport.x + rect->x; - mtlrect.y = statecache->viewport.y + rect->y; - mtlrect.width = rect->w; - mtlrect.height = rect->h; + clip = statecache->cliprect; + clip.x += statecache->viewport.x; + clip.y += statecache->viewport.y; } else { - mtlrect.x = statecache->viewport.x; - mtlrect.y = statecache->viewport.y; - mtlrect.width = statecache->viewport.w; - mtlrect.height = statecache->viewport.h; + clip = statecache->viewport; } - if (mtlrect.width > 0 && mtlrect.height > 0) { + + /* Set Scissor Rect Validation: w/h must be <= render pass */ + SDL_zero(output); + METAL_GetOutputSize(renderer, &output.w, &output.h); + + if (SDL_IntersectRect(&output, &clip, &clip)) { + MTLScissorRect mtlrect; + mtlrect.x = clip.x; + mtlrect.y = clip.y; + mtlrect.width = clip.w; + mtlrect.height = clip.h; [data.mtlcmdencoder setScissorRect:mtlrect]; } + statecache->cliprect_dirty = SDL_FALSE; } @@ -1329,9 +1300,10 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met } [data.mtlcmdencoder setVertexBufferOffset:first atIndex:0]; /* position/texcoords */ + return SDL_TRUE; } -static void +static SDL_bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t constants_offset, id mtlbufvertex, METAL_DrawStateCache *statecache) { @@ -1339,7 +1311,9 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t SDL_Texture *texture = cmd->data.draw.texture; METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata; - SetDrawState(renderer, cmd, texturedata.fragmentFunction, constants_offset, mtlbufvertex, statecache); + if (!SetDrawState(renderer, cmd, texturedata.fragmentFunction, constants_offset, mtlbufvertex, statecache)) { + return SDL_FALSE; + } if (texture != statecache->texture) { METAL_TextureData *oldtexturedata = NULL; @@ -1351,12 +1325,15 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t } [data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture atIndex:0]; +#if SDL_HAVE_YUV if (texturedata.yuv || texturedata.nv12) { [data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture_uv atIndex:1]; [data.mtlcmdencoder setFragmentBuffer:data.mtlbufconstants offset:texturedata.conversionBufferOffset atIndex:1]; } +#endif statecache->texture = texture; } + return SDL_TRUE; } static int @@ -1454,6 +1431,7 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver MTLClearColor color = MTLClearColorMake(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f); // get new command encoder, set up with an initial clear operation. + // (this might fail, and future draw operations will notice.) METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, mtlbufvertex); break; } @@ -1462,44 +1440,34 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver case SDL_RENDERCMD_DRAW_LINES: { const size_t count = cmd->data.draw.count; const MTLPrimitiveType primtype = (cmd->command == SDL_RENDERCMD_DRAW_POINTS) ? MTLPrimitiveTypePoint : MTLPrimitiveTypeLineStrip; - SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_HALF_PIXEL_TRANSFORM, mtlbufvertex, &statecache); - [data.mtlcmdencoder drawPrimitives:primtype vertexStart:0 vertexCount:count]; - break; - } - - case SDL_RENDERCMD_FILL_RECTS: { - const size_t count = cmd->data.draw.count; - const size_t maxcount = UINT16_MAX / 4; - SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache); - if (count == 1) { - [data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; - } else { - /* Our index buffer has 16 bit indices, so we can only draw - * 65k vertices (16k rects) at a time. */ - for (size_t i = 0; i < count; i += maxcount) { - /* Set the vertex buffer offset for our current positions. - * The vertex buffer itself was bound in SetDrawState. */ - [data.mtlcmdencoder setVertexBufferOffset:cmd->data.draw.first + i*sizeof(float)*8 atIndex:0]; - [data.mtlcmdencoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle - indexCount:SDL_min(maxcount, count - i) * 6 - indexType:MTLIndexTypeUInt16 - indexBuffer:data.mtlbufquadindices - indexBufferOffset:0]; - } + if (SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_HALF_PIXEL_TRANSFORM, mtlbufvertex, &statecache)) { + [data.mtlcmdencoder drawPrimitives:primtype vertexStart:0 vertexCount:count]; } break; } - case SDL_RENDERCMD_COPY: { - SetCopyState(renderer, cmd, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache); - [data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; + case SDL_RENDERCMD_FILL_RECTS: /* unused */ break; - } - case SDL_RENDERCMD_COPY_EX: { - SetCopyState(renderer, cmd, CONSTANTS_OFFSET_INVALID, mtlbufvertex, &statecache); - [data.mtlcmdencoder setVertexBuffer:mtlbufvertex offset:cmd->data.draw.count atIndex:3]; // transform - [data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; + case SDL_RENDERCMD_COPY: /* unused */ + break; + + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; + + case SDL_RENDERCMD_GEOMETRY: { + const size_t count = cmd->data.draw.count; + SDL_Texture *texture = cmd->data.draw.texture; + + if (texture) { + if (SetCopyState(renderer, cmd, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache)) { + [data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:count]; + } + } else { + if (SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache)) { + [data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:count]; + } + } break; } @@ -1517,7 +1485,9 @@ METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; - METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil); + if (!METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil)) { + return SDL_SetError("Failed to activate render command encoder (is your window in the background?"); + } [data.mtlcmdencoder endEncoding]; id mtltexture = data.mtlpassdesc.colorAttachments[0].texture; @@ -1562,20 +1532,28 @@ static void METAL_RenderPresent(SDL_Renderer * renderer) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; + SDL_bool ready = SDL_TRUE; // If we don't have a command buffer, we can't present, so activate to get one. if (data.mtlcmdencoder == nil) { // We haven't even gotten a backbuffer yet? Clear it to black. Otherwise, load the existing data. if (data.mtlbackbuffer == nil) { MTLClearColor color = MTLClearColorMake(0.0f, 0.0f, 0.0f, 1.0f); - METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, nil); + ready = METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, nil); } else { - METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil); + ready = METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil); } } [data.mtlcmdencoder endEncoding]; - [data.mtlcmdbuffer presentDrawable:data.mtlbackbuffer]; + + // If we don't have a drawable to present, don't try to present it. + // But we'll still try to commit the command buffer in case it was already enqueued. + if (ready) { + SDL_assert(data.mtlbackbuffer != nil); + [data.mtlcmdbuffer presentDrawable:data.mtlbackbuffer]; + } + [data.mtlcmdbuffer commit]; data.mtlcmdencoder = nil; @@ -1602,7 +1580,11 @@ METAL_DestroyRenderer(SDL_Renderer * renderer) DestroyAllPipelines(data.allpipelines, data.pipelinescount); - SDL_Metal_DestroyView(data.mtlview); + /* Release the metal view instead of destroying it, + in case we want to use it later (recreating the renderer) + */ + /* SDL_Metal_DestroyView(data.mtlview); */ + CFBridgingRelease(data.mtlview); } SDL_free(renderer); @@ -1618,11 +1600,61 @@ METAL_GetMetalLayer(SDL_Renderer * renderer) static void * METAL_GetMetalCommandEncoder(SDL_Renderer * renderer) { @autoreleasepool { + // note that data.mtlcmdencoder can be nil if METAL_ActivateRenderCommandEncoder fails. + // Before SDL 2.0.18, it might have returned a non-nil encoding that might not have been + // usable for presentation. Check your return values! METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil); METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; return (__bridge void*)data.mtlcmdencoder; }} +static int +METAL_SetVSync(SDL_Renderer * renderer, const int vsync) +{ +#if (defined(__MACOSX__) && defined(MAC_OS_X_VERSION_10_13)) || TARGET_OS_MACCATALYST + if (@available(macOS 10.13, *)) { + METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; + if (vsync) { + data.mtllayer.displaySyncEnabled = YES; + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + data.mtllayer.displaySyncEnabled = NO; + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return 0; + } +#endif + return SDL_SetError("This Apple OS does not support displaySyncEnabled!"); +} + +static SDL_MetalView GetWindowView(SDL_Window *window) +{ + SDL_SysWMinfo info; + + SDL_VERSION(&info.version); + if (SDL_GetWindowWMInfo(window, &info)) { +#ifdef __MACOSX__ + if (info.subsystem == SDL_SYSWM_COCOA) { + NSView *view = info.info.cocoa.window.contentView; + if (view.subviews.count > 0) { + view = view.subviews[0]; + if (view.tag == SDL_METALVIEW_TAG) { + return (SDL_MetalView)CFBridgingRetain(view); + } + } + } +#else + if (info.subsystem == SDL_SYSWM_UIKIT) { + UIView *view = info.info.uikit.window.rootViewController.view; + if (view.tag == SDL_METALVIEW_TAG) { + return (SDL_MetalView)CFBridgingRetain(view); + } + } +#endif + } + return nil; +} + static SDL_Renderer * METAL_CreateRenderer(SDL_Window * window, Uint32 flags) { @autoreleasepool { @@ -1673,7 +1705,10 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) return NULL; } - view = SDL_Metal_CreateView(window); + view = GetWindowView(window); + if (view == nil) { + view = SDL_Metal_CreateView(window); + } if (view == NULL) { #if !__has_feature(objc_arc) @@ -1693,7 +1728,11 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) #if !__has_feature(objc_arc) [mtldevice release]; #endif - SDL_Metal_DestroyView(view); + /* Release the metal view instead of destroying it, + in case we want to use it later (recreating the renderer) + */ + /* SDL_Metal_DestroyView(view); */ + CFBridgingRelease(view); SDL_free(renderer); if (changed_window) { SDL_RecreateWindow(window, window_flags); @@ -1850,7 +1889,10 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->SupportsBlendMode = METAL_SupportsBlendMode; renderer->CreateTexture = METAL_CreateTexture; renderer->UpdateTexture = METAL_UpdateTexture; +#if SDL_HAVE_YUV renderer->UpdateTextureYUV = METAL_UpdateTextureYUV; + renderer->UpdateTextureNV = METAL_UpdateTextureNV; +#endif renderer->LockTexture = METAL_LockTexture; renderer->UnlockTexture = METAL_UnlockTexture; renderer->SetTextureScaleMode = METAL_SetTextureScaleMode; @@ -1859,14 +1901,13 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->QueueSetDrawColor = METAL_QueueSetDrawColor; renderer->QueueDrawPoints = METAL_QueueDrawPoints; renderer->QueueDrawLines = METAL_QueueDrawLines; - renderer->QueueFillRects = METAL_QueueFillRects; - renderer->QueueCopy = METAL_QueueCopy; - renderer->QueueCopyEx = METAL_QueueCopyEx; + renderer->QueueGeometry = METAL_QueueGeometry; renderer->RunCommandQueue = METAL_RunCommandQueue; renderer->RenderReadPixels = METAL_RenderReadPixels; renderer->RenderPresent = METAL_RenderPresent; renderer->DestroyTexture = METAL_DestroyTexture; renderer->DestroyRenderer = METAL_DestroyRenderer; + renderer->SetVSync = METAL_SetVSync; renderer->GetMetalLayer = METAL_GetMetalLayer; renderer->GetMetalCommandEncoder = METAL_GetMetalCommandEncoder; @@ -1875,7 +1916,7 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->always_batch = SDL_TRUE; -#if defined(__MACOSX__) && defined(MAC_OS_X_VERSION_10_13) +#if (defined(__MACOSX__) && defined(MAC_OS_X_VERSION_10_13)) || TARGET_OS_MACCATALYST if (@available(macOS 10.13, *)) { data.mtllayer.displaySyncEnabled = (flags & SDL_RENDERER_PRESENTVSYNC) != 0; if (data.mtllayer.displaySyncEnabled) { @@ -1889,7 +1930,7 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) /* https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf */ int maxtexsize = 4096; -#if defined(__MACOSX__) +#if defined(__MACOSX__) || TARGET_OS_MACCATALYST maxtexsize = 16384; #elif defined(__TVOS__) maxtexsize = 8192; diff --git a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal.metal b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal.metal index 7975a39fa..fd9e3a816 100644 --- a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal.metal +++ b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal.metal @@ -6,11 +6,13 @@ using namespace metal; struct SolidVertexInput { float2 position [[attribute(0)]]; + float4 color [[attribute(1)]]; }; struct SolidVertexOutput { float4 position [[position]]; + float4 color; float pointSize [[point_size]]; }; @@ -20,24 +22,27 @@ vertex SolidVertexOutput SDL_Solid_vertex(SolidVertexInput in [[stage_in]], { SolidVertexOutput v; v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f); + v.color = in.color; v.pointSize = 1.0f; return v; } -fragment float4 SDL_Solid_fragment(const device float4 &col [[buffer(0)]]) +fragment float4 SDL_Solid_fragment(SolidVertexInput in [[stage_in]]) { - return col; + return in.color; } struct CopyVertexInput { float2 position [[attribute(0)]]; - float2 texcoord [[attribute(1)]]; + float4 color [[attribute(1)]]; + float2 texcoord [[attribute(2)]]; }; struct CopyVertexOutput { float4 position [[position]]; + float4 color; float2 texcoord; }; @@ -47,16 +52,16 @@ vertex CopyVertexOutput SDL_Copy_vertex(CopyVertexInput in [[stage_in]], { CopyVertexOutput v; v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f); + v.color = in.color; v.texcoord = in.texcoord; return v; } fragment float4 SDL_Copy_fragment(CopyVertexOutput vert [[stage_in]], - const device float4 &col [[buffer(0)]], texture2d tex [[texture(0)]], sampler s [[sampler(0)]]) { - return tex.sample(s, vert.texcoord) * col; + return tex.sample(s, vert.texcoord) * vert.color; } struct YUVDecode @@ -68,7 +73,6 @@ struct YUVDecode }; fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]], - const device float4 &col [[buffer(0)]], constant YUVDecode &decode [[buffer(1)]], texture2d texY [[texture(0)]], texture2d_array texUV [[texture(1)]], @@ -81,11 +85,10 @@ fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]], yuv += decode.offset; - return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); + return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); } fragment float4 SDL_NV12_fragment(CopyVertexOutput vert [[stage_in]], - const device float4 &col [[buffer(0)]], constant YUVDecode &decode [[buffer(1)]], texture2d texY [[texture(0)]], texture2d texUV [[texture(1)]], @@ -97,11 +100,10 @@ fragment float4 SDL_NV12_fragment(CopyVertexOutput vert [[stage_in]], yuv += decode.offset; - return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); + return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); } fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]], - const device float4 &col [[buffer(0)]], constant YUVDecode &decode [[buffer(1)]], texture2d texY [[texture(0)]], texture2d texUV [[texture(1)]], @@ -113,5 +115,6 @@ fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]], yuv += decode.offset; - return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); + return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); } + diff --git a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_ios.h b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_ios.h index c62288d5a..4488c67e7 100644 --- a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_ios.h +++ b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_ios.h @@ -1,206 +1,208 @@ const unsigned char sdl_metallib[] = { 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x04, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x51, 0x00, 0x00, + 0x72, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, - 0x28, 0x31, 0x40, 0x63, 0x07, 0x67, 0xcf, 0xec, 0x7b, 0x53, 0x36, 0x27, - 0xdc, 0xe7, 0xb5, 0x97, 0xd0, 0x99, 0xe7, 0x0a, 0x52, 0x5d, 0x98, 0xd7, - 0xc6, 0x8e, 0xba, 0x3c, 0x01, 0x5f, 0xad, 0xf5, 0x4f, 0x46, 0x46, 0x54, + 0x13, 0x37, 0x18, 0x80, 0x89, 0x69, 0x90, 0x54, 0x43, 0x22, 0xe0, 0xd3, + 0xc9, 0x73, 0x9e, 0x97, 0x0d, 0x2b, 0x28, 0xbd, 0x50, 0x37, 0x8f, 0x58, + 0x37, 0x77, 0x01, 0xac, 0x6d, 0x88, 0x24, 0x29, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x77, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, - 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x47, - 0xb8, 0x4f, 0x55, 0x1e, 0x1e, 0x4a, 0x32, 0x12, 0x7a, 0x9e, 0xc2, 0xf0, - 0xf9, 0x2b, 0x85, 0x1f, 0xe9, 0x90, 0x33, 0xc4, 0xdf, 0xa9, 0x3a, 0xca, - 0x6b, 0x6d, 0xdd, 0xe9, 0x46, 0x64, 0x83, 0x4f, 0x46, 0x46, 0x54, 0x18, - 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x91, + 0x5a, 0xbb, 0x5b, 0x02, 0x11, 0xc3, 0x5b, 0xf6, 0x76, 0xc1, 0x89, 0xa1, + 0x01, 0x7b, 0x59, 0xb6, 0xd1, 0xe0, 0xb8, 0xdf, 0x74, 0x12, 0x2a, 0xd4, + 0x0f, 0x39, 0x55, 0x63, 0x7e, 0xe8, 0x4f, 0x4f, 0x46, 0x46, 0x54, 0x18, + 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x7a, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x13, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, - 0x00, 0x69, 0x9d, 0x1d, 0x1f, 0x5c, 0x05, 0x77, 0xfb, 0x40, 0x83, 0x70, - 0x5e, 0x26, 0x13, 0x34, 0xb5, 0xd7, 0x61, 0x21, 0x42, 0x6a, 0xc9, 0x8d, - 0xd0, 0x59, 0x04, 0x0b, 0x18, 0x09, 0x74, 0x40, 0x7c, 0x4f, 0x46, 0x46, - 0x54, 0x18, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x16, 0x00, 0x00, 0x00, + 0x00, 0x44, 0xbf, 0x90, 0x59, 0x71, 0xf7, 0xaf, 0x19, 0x2d, 0x19, 0x6e, + 0x76, 0x40, 0x8a, 0xf6, 0xce, 0x7f, 0x14, 0x46, 0xc9, 0xe3, 0xae, 0x8b, + 0x7a, 0x85, 0x41, 0x59, 0x0f, 0xbd, 0xd7, 0x95, 0x16, 0x4f, 0x46, 0x46, + 0x54, 0x18, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, - 0x20, 0x00, 0x88, 0x94, 0x57, 0x70, 0x82, 0x3f, 0xe3, 0xbc, 0x88, 0x1c, - 0x9c, 0x13, 0xbd, 0x4d, 0xc3, 0x16, 0xdf, 0x68, 0x5e, 0xe0, 0xe9, 0xa9, - 0x06, 0x9e, 0x2f, 0xf0, 0x86, 0xf6, 0x8d, 0x56, 0xf2, 0xbf, 0x4f, 0x46, - 0x46, 0x54, 0x18, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x5f, 0x19, 0x9c, 0xe8, 0xec, 0xd5, 0xc9, 0xc3, 0x03, 0xc5, + 0x04, 0xc4, 0x43, 0x19, 0x4b, 0x03, 0xde, 0x02, 0xe4, 0x31, 0xab, 0x30, + 0xae, 0xca, 0x0a, 0xb2, 0x45, 0x33, 0x78, 0x01, 0x3f, 0xd3, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x78, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, - 0x20, 0x00, 0xf7, 0x98, 0xd0, 0xe2, 0xdc, 0xe8, 0x70, 0x90, 0xb8, 0xd2, - 0x1e, 0x21, 0x36, 0xa4, 0xb8, 0xca, 0x52, 0xcb, 0xb8, 0xc9, 0x61, 0xa4, - 0x80, 0x75, 0xa2, 0x9b, 0x4b, 0x82, 0x22, 0x60, 0xa6, 0xc9, 0x4f, 0x46, - 0x46, 0x54, 0x18, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, + 0x20, 0x00, 0xff, 0xfc, 0x03, 0x55, 0x1e, 0xae, 0x75, 0xbf, 0xb8, 0x4e, + 0x84, 0xd6, 0xd4, 0x1c, 0x39, 0x5f, 0x4d, 0x60, 0xe8, 0x3a, 0x9c, 0xa7, + 0xed, 0xa5, 0xcf, 0xaa, 0xff, 0x32, 0xce, 0x0b, 0xd3, 0x57, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, - 0x48, 0x20, 0x00, 0x64, 0x76, 0x02, 0x5c, 0xd4, 0x80, 0xf1, 0x25, 0xd7, - 0x2a, 0xa6, 0xb0, 0x3c, 0xd8, 0xe6, 0x3a, 0x38, 0xe3, 0xd6, 0x15, 0x67, - 0x59, 0x20, 0xfd, 0x1b, 0xfe, 0x8c, 0x87, 0x1e, 0xfe, 0x9d, 0x9e, 0x4f, - 0x46, 0x46, 0x54, 0x18, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x38, 0x00, + 0x48, 0x20, 0x00, 0xbe, 0x64, 0x2f, 0xcf, 0xf2, 0xe7, 0x72, 0x42, 0x38, + 0xf8, 0x0e, 0x52, 0x43, 0x15, 0x53, 0x7e, 0x24, 0x4c, 0xc4, 0x53, 0xfc, + 0xe6, 0xda, 0xd9, 0x4b, 0x9a, 0xfd, 0x84, 0x1e, 0x42, 0x31, 0x43, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, - 0x53, 0x48, 0x20, 0x00, 0x23, 0xbd, 0x28, 0xce, 0x4f, 0xb7, 0xc7, 0x94, - 0x2a, 0x0a, 0x20, 0x48, 0x6f, 0x52, 0x4a, 0xcc, 0x07, 0x9c, 0x7f, 0x41, - 0x8d, 0x0a, 0x31, 0x81, 0xec, 0xe4, 0xd4, 0x71, 0x77, 0x7b, 0x22, 0x7d, - 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x44, + 0x53, 0x48, 0x20, 0x00, 0xe6, 0xe4, 0xd7, 0x33, 0x1f, 0x59, 0xe9, 0x03, + 0xec, 0x6d, 0x07, 0xd1, 0xa3, 0xc3, 0x49, 0x6a, 0x9d, 0x22, 0x8b, 0xce, + 0x27, 0xd1, 0xae, 0x1e, 0xfc, 0x33, 0x6d, 0x56, 0x86, 0x25, 0xd5, 0x66, + 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x45, 0x4e, 0x44, 0x54, 0x20, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, - 0x0d, 0x00, 0x01, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x00, 0x00, 0x80, 0x56, 0x41, 0x54, 0x59, 0x03, 0x00, 0x01, 0x00, 0x04, - 0x45, 0x4e, 0x44, 0x54, 0x2c, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, - 0x18, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x00, 0x00, 0x80, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, - 0x01, 0x80, 0x56, 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x04, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x3c, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, - 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, - 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, - 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, - 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, - 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, - 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, - 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, - 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, - 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, - 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, - 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, - 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, - 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, - 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, - 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, - 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, - 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, - 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, - 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, - 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, - 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, - 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, - 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, - 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, - 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, - 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, - 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, - 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, - 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, - 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, - 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, - 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, - 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, - 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, - 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, - 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, - 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, - 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, - 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, - 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, - 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, + 0x45, 0x4e, 0x44, 0x54, 0x29, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, + 0x15, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x56, + 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x06, 0x45, 0x4e, 0x44, + 0x54, 0x35, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x20, 0x00, 0x03, + 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x80, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x02, 0x80, 0x56, 0x41, 0x54, 0x59, 0x05, + 0x00, 0x03, 0x00, 0x04, 0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa0, 0x0b, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0xe5, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, + 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, + 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, + 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, + 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, + 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, + 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, + 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, + 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, + 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, + 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, + 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, + 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, + 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, + 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, + 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, - 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, - 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, - 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, - 0x36, 0x20, 0x82, 0x00, 0x24, 0xc0, 0x02, 0x54, 0x1b, 0x90, 0x61, 0x00, - 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x89, 0x20, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, - 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, - 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, - 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x60, 0x85, 0x00, 0x86, 0x11, - 0x04, 0x20, 0x09, 0xc2, 0x4c, 0xd4, 0x3c, 0xd0, 0x83, 0x3c, 0xd4, 0xc3, - 0x38, 0xd0, 0x83, 0x1b, 0xb4, 0x43, 0x39, 0xd0, 0x43, 0x38, 0xb0, 0x83, - 0x1e, 0xe8, 0x41, 0x3b, 0x84, 0x03, 0x3d, 0xc8, 0x43, 0x3a, 0xe0, 0x03, - 0x0a, 0xc8, 0x20, 0x42, 0x21, 0x14, 0x42, 0x0c, 0x63, 0xe8, 0x0c, 0x04, - 0xcc, 0x11, 0x80, 0x41, 0x0a, 0xa8, 0x39, 0x02, 0x50, 0x18, 0x44, 0x08, - 0x84, 0x61, 0x04, 0x42, 0x19, 0x01, 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, - 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, - 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, - 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, - 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, - 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, - 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, - 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, - 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, - 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, - 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, - 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, - 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, - 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, - 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, - 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, - 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, - 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, - 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, - 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, - 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, - 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, - 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, - 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, - 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, - 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, - 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, - 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, - 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, - 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, - 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x80, 0x01, 0x45, 0x50, - 0x20, 0x85, 0x50, 0x10, 0x65, 0x40, 0x6c, 0x04, 0x80, 0xd6, 0x58, 0x82, - 0x23, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, - 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, - 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, 0xc0, 0xa2, 0x50, 0xb9, - 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, - 0x41, 0x22, 0x28, 0x06, 0xdd, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, - 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, - 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x06, 0x04, 0xa5, 0xad, - 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, - 0x85, 0x66, 0x26, 0x65, 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, 0x50, 0x0e, + 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, + 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, + 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, + 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, + 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, + 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, + 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, + 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, + 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, + 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, + 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, + 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x20, 0xc2, 0x00, 0x24, 0xc0, + 0x02, 0x54, 0x1b, 0x90, 0x81, 0x00, 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, + 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, + 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, + 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, + 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, + 0x04, 0x60, 0x87, 0x10, 0xc0, 0x30, 0x82, 0x00, 0x24, 0x41, 0x98, 0x89, + 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, + 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, + 0x52, 0x88, 0x11, 0x8c, 0xa1, 0x33, 0x10, 0x30, 0x47, 0x00, 0x06, 0x29, + 0xa0, 0xe6, 0x08, 0x40, 0x61, 0x10, 0x21, 0x10, 0x86, 0x11, 0x08, 0x65, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, + 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, + 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, + 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, + 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, + 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, + 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, + 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, + 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, + 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, + 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, + 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, + 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x43, 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x80, 0x01, 0x45, 0x50, 0x20, 0x65, + 0x50, 0x08, 0x05, 0x41, 0x6c, 0x04, 0x80, 0xd6, 0x58, 0x82, 0x43, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, + 0x28, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, 0x50, 0x10, 0x45, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, 0x0e, 0x25, 0x50, 0x02, 0x45, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, @@ -216,283 +218,45 @@ const unsigned char sdl_metallib[] = { 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x64, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, 0x88, 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, - 0xb9, 0x0d, 0x51, 0x92, 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x4e, - 0x58, 0x9a, 0x9c, 0x0b, 0xdc, 0x5b, 0x9a, 0x1b, 0xdd, 0xd7, 0x5c, 0x9a, - 0x5e, 0x19, 0x0b, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x26, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x43, 0x94, 0xa4, 0x4a, 0xa0, 0xc4, - 0x4a, 0xa4, 0xe4, 0x1a, 0x42, 0x24, 0x54, 0x82, 0x11, 0x0a, 0x4b, 0x93, - 0x73, 0xb1, 0x2b, 0x93, 0xa3, 0x2b, 0xc3, 0xfb, 0x4a, 0x73, 0x83, 0xab, - 0xa3, 0xa3, 0x14, 0x96, 0x26, 0xe7, 0xc2, 0xf6, 0x36, 0x16, 0x46, 0x97, - 0xf6, 0xe6, 0xf6, 0x95, 0xe6, 0x46, 0x56, 0x86, 0x47, 0xef, 0xac, 0xcc, - 0xad, 0x4c, 0x2e, 0x8c, 0xae, 0x8c, 0x0c, 0xe5, 0xeb, 0x2b, 0x2c, 0x4d, - 0xee, 0x0b, 0x8e, 0x2d, 0x6c, 0xac, 0x0c, 0xed, 0x8d, 0x8d, 0xac, 0x4c, - 0xee, 0xeb, 0x2b, 0x85, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0x9d, 0xcc, 0x10, - 0x4a, 0x11, 0x12, 0x2d, 0xd9, 0x14, 0x41, 0x09, 0x12, 0x2e, 0x81, 0x92, - 0x2e, 0x91, 0x92, 0x89, 0x4a, 0x58, 0x9a, 0x9c, 0x8b, 0x58, 0x9d, 0x99, - 0x59, 0x99, 0x1c, 0x9f, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, 0xb3, - 0x32, 0xb9, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x22, 0x61, 0x69, 0x72, 0x2e, - 0x72, 0x65, 0x61, 0x64, 0x8c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, - 0xbe, 0xe8, 0xf2, 0xe0, 0xca, 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x78, 0x85, - 0xa5, 0xc9, 0xb9, 0x84, 0xc9, 0x9d, 0x7d, 0xd1, 0xe5, 0xc1, 0x95, 0x7d, - 0x85, 0xb1, 0xa5, 0x9d, 0xb9, 0x7d, 0xcd, 0xa5, 0xe9, 0x95, 0x11, 0x31, - 0x63, 0x7b, 0x0b, 0xa3, 0xa3, 0xc1, 0xa3, 0xa1, 0x02, 0x27, 0xf7, 0xa6, - 0x56, 0x36, 0x46, 0x97, 0xf6, 0xe6, 0x36, 0x04, 0x0c, 0x94, 0x20, 0xf9, - 0x12, 0x30, 0x50, 0x86, 0x64, 0x53, 0x08, 0x25, 0x48, 0xc2, 0x20, 0x11, - 0x03, 0x65, 0x48, 0xc6, 0x40, 0x29, 0x12, 0x28, 0x21, 0x83, 0x44, 0x4a, - 0xca, 0x80, 0x09, 0x9d, 0x5c, 0x98, 0xdb, 0x9c, 0xd9, 0x9b, 0x5c, 0xdb, - 0x10, 0x30, 0x50, 0x88, 0xe4, 0x4b, 0xc0, 0x40, 0x19, 0x92, 0x4d, 0x41, - 0x94, 0x20, 0x09, 0x83, 0x44, 0x0c, 0x94, 0x21, 0x19, 0x03, 0xa5, 0x48, - 0xa0, 0x84, 0x0c, 0x12, 0x29, 0x39, 0x83, 0x21, 0x46, 0xe2, 0x25, 0x66, - 0x90, 0xa0, 0xc1, 0x10, 0x03, 0x01, 0x92, 0x2c, 0x49, 0x03, 0x3e, 0x6f, - 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, - 0x61, 0x72, 0x7c, 0xa6, 0xd2, 0xda, 0xe0, 0xd8, 0xca, 0x40, 0x86, 0x56, - 0x56, 0x40, 0xa8, 0x84, 0x82, 0x82, 0x86, 0x08, 0x09, 0x1b, 0x0c, 0x31, - 0x92, 0x35, 0x48, 0xda, 0x80, 0x49, 0x86, 0x18, 0x89, 0x1b, 0x24, 0x6e, - 0xc0, 0x24, 0x23, 0x22, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, - 0x87, 0x77, 0x20, 0x87, 0x7a, 0x60, 0x87, 0x72, 0x70, 0x03, 0x73, 0x60, - 0x87, 0x70, 0x38, 0x87, 0x79, 0x98, 0x22, 0x04, 0xc3, 0x08, 0x85, 0x1d, - 0xd8, 0xc1, 0x1e, 0xda, 0xc1, 0x0d, 0xd2, 0x81, 0x1c, 0xca, 0xc1, 0x1d, - 0xe8, 0x61, 0x4a, 0x50, 0x8c, 0x58, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, - 0xec, 0xa1, 0x1c, 0xe4, 0x61, 0x1e, 0xd2, 0xe1, 0x1d, 0xdc, 0x61, 0x4a, - 0x60, 0x8c, 0xa0, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, 0xd8, 0x21, 0x1c, - 0xdc, 0xe1, 0x1c, 0xea, 0x21, 0x1c, 0xce, 0xa1, 0x1c, 0x7e, 0xc1, 0x1e, - 0xca, 0x41, 0x1e, 0xe6, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0xa6, 0x04, 0xc8, - 0x88, 0x29, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0x60, 0x1c, 0xde, 0xa1, 0x1d, - 0xe0, 0x21, 0x1d, 0xd8, 0xa1, 0x1c, 0x7e, 0xe1, 0x1d, 0xe0, 0x81, 0x1e, - 0xd2, 0xe1, 0x1d, 0xdc, 0x61, 0x1e, 0xa6, 0x0c, 0x0a, 0xe3, 0x8c, 0x50, - 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, 0xec, 0xa1, 0x1c, 0xe4, 0x81, 0x1e, - 0xca, 0x01, 0x1f, 0xa6, 0x04, 0x6a, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, - 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, - 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, - 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, - 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, - 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, - 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, - 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, - 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, - 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, - 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, - 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, - 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, - 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, - 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, - 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, - 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, - 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, - 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, - 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, - 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, - 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, - 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, - 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, - 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, - 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, - 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, - 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, - 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, - 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, - 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, - 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, - 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, - 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, - 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, - 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, - 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, - 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, - 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, - 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, - 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, - 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x06, 0x00, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, 0x45, 0x44, - 0x13, 0x71, 0x01, 0x00, 0x61, 0x20, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, - 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, - 0x22, 0x82, 0x20, 0x08, 0x46, 0x00, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, - 0x8d, 0x19, 0x00, 0x12, 0x33, 0x00, 0x14, 0x66, 0x00, 0x08, 0x8c, 0x11, - 0x80, 0x20, 0x08, 0xe2, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x11, 0x0c, 0x74, - 0x41, 0x14, 0x94, 0xf1, 0x88, 0x47, 0xca, 0x24, 0x0a, 0xca, 0x20, 0xc3, - 0x60, 0x30, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x98, 0xac, 0xae, 0xa1, 0xa0, - 0x0c, 0x32, 0x1c, 0x4a, 0x64, 0x42, 0x20, 0x1f, 0x0b, 0x0a, 0xf8, 0x8c, - 0x47, 0x60, 0x9b, 0x18, 0x40, 0x14, 0x94, 0x41, 0x06, 0xe6, 0xb9, 0x4c, - 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x88, 0x0e, 0x0c, 0xce, 0xc0, - 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x54, 0x67, 0x42, 0x20, 0x1f, 0x2b, 0x02, - 0xf8, 0x8c, 0x47, 0x84, 0x41, 0x19, 0xb0, 0x01, 0x47, 0x41, 0x19, 0x64, - 0x08, 0xb2, 0xcf, 0x82, 0x4a, 0x3e, 0x83, 0x0c, 0xc3, 0x26, 0x06, 0x16, - 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, 0xe1, 0x99, 0x81, 0x05, - 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, 0x84, 0x81, 0x1a, 0x58, - 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, 0x6e, 0x20, 0x07, 0x79, - 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xc0, 0x0c, 0xd8, 0xc0, 0x02, 0x31, - 0x90, 0xcf, 0x20, 0xc3, 0x80, 0x06, 0x6f, 0x60, 0x01, 0x18, 0xc8, 0x67, - 0x90, 0xa1, 0x50, 0x03, 0x39, 0xb0, 0xa0, 0x93, 0xcf, 0x20, 0xc3, 0xc1, - 0x06, 0x75, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x06, 0x3d, 0x80, 0x03, 0x3a, - 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x03, 0x1f, 0xc8, 0xc1, 0x1d, 0x98, 0x13, - 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, 0xb1, 0x20, 0x81, 0x8f, - 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, 0x80, 0x07, 0x01, 0x30, - 0xdb, 0x10, 0xdc, 0x41, 0x90, 0x41, 0x40, 0x0c, 0x09, 0x00, 0x00, 0x00, - 0x5b, 0x86, 0x20, 0x78, 0x83, 0x2d, 0xc3, 0x10, 0xbc, 0xc1, 0x96, 0xe1, - 0x08, 0xde, 0x60, 0xcb, 0xc0, 0x04, 0x6f, 0xb0, 0x65, 0x88, 0x82, 0x37, - 0xd8, 0x32, 0x58, 0xc1, 0x1b, 0x6c, 0x19, 0xc6, 0x20, 0x78, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x60, 0x0b, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, - 0xd5, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, - 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, - 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, - 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, - 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, - 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, - 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, - 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, - 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, - 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, - 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, - 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, - 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, - 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, - 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, - 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, - 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, - 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, - 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, - 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, - 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, - 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, - 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, - 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, - 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, - 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, - 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, - 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, - 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, - 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, - 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, - 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, - 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, - 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, - 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, - 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, - 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, - 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, - 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, - 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, - 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, - 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, - 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, - 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, - 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, - 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, - 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, - 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, - 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, - 0x98, 0x87, 0x72, 0x00, 0x36, 0x20, 0xc2, 0x00, 0x24, 0xc0, 0x02, 0x54, - 0x1b, 0x90, 0x81, 0x00, 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, - 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, - 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, - 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, - 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, - 0x8c, 0x20, 0x00, 0x56, 0x08, 0x22, 0x09, 0xc2, 0x4c, 0xd4, 0x3c, 0xd0, - 0x83, 0x3c, 0xd4, 0xc3, 0x38, 0xd0, 0x83, 0x1b, 0xb4, 0x43, 0x39, 0xd0, - 0x43, 0x38, 0xb0, 0x83, 0x1e, 0xe8, 0x41, 0x3b, 0x84, 0x03, 0x3d, 0xc8, - 0x43, 0x3a, 0xe0, 0x03, 0x0a, 0xc8, 0x20, 0x42, 0x21, 0x94, 0x62, 0x08, - 0x61, 0x0c, 0x9d, 0x81, 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x35, 0x47, - 0x00, 0x0a, 0x83, 0x08, 0x81, 0x30, 0x8c, 0x40, 0x28, 0x23, 0x00, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x04, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, - 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, - 0x80, 0x01, 0x45, 0x50, 0x20, 0x65, 0x50, 0x08, 0x05, 0x41, 0x6c, 0x04, - 0x80, 0xd6, 0x58, 0x82, 0x23, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, - 0xd9, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, - 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, 0x28, 0x07, 0xdd, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, - 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, - 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x26, 0x65, 0x88, 0x90, 0x10, 0x43, - 0x0c, 0x25, 0x50, 0x10, 0x45, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, - 0x04, 0x49, 0x0e, 0x25, 0x50, 0x02, 0x45, 0xe0, 0x16, 0x96, 0x26, 0xe7, - 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, - 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, - 0x44, 0x48, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, - 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, - 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x64, 0x21, - 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, - 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, - 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, - 0x95, 0x0d, 0x11, 0x92, 0x86, 0x4c, 0x58, 0x9a, 0x9c, 0x0b, 0xdc, 0xdb, - 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0x1b, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, - 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, - 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x64, 0xc2, 0xd2, 0xe4, 0x5c, - 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, 0x88, 0xc0, 0xbd, 0xcd, - 0xa5, 0xd1, 0xa5, 0xbd, 0xb9, 0x0d, 0x51, 0x92, 0x27, 0x81, 0x92, 0x28, - 0x91, 0x92, 0x89, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5d, 0x99, 0x1c, 0x5d, - 0x19, 0xde, 0xd7, 0x5b, 0x1d, 0x1d, 0x5c, 0x1d, 0x1d, 0xb3, 0xb3, 0x32, - 0xb7, 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x14, 0x1c, 0xba, 0x32, 0xbc, - 0xb1, 0xb7, 0x37, 0x39, 0x32, 0x22, 0x3b, 0x99, 0x2f, 0xb3, 0x14, 0x1a, - 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x44, 0xe8, 0xca, 0xf0, 0xc6, 0xde, - 0xde, 0xe4, 0xc8, 0x86, 0x30, 0x49, 0x95, 0x58, 0x09, 0x94, 0x5c, 0x89, - 0x94, 0x60, 0x43, 0x88, 0x84, 0x4a, 0x32, 0x42, 0x61, 0x69, 0x72, 0x2e, - 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x94, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, - 0xdc, 0xbe, 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0xe8, 0x9d, 0x95, 0xb9, 0x95, - 0xc9, 0x85, 0xd1, 0x95, 0x91, 0xa1, 0x7c, 0x7d, 0x85, 0xa5, 0xc9, 0x7d, - 0xc1, 0xb1, 0x85, 0x8d, 0x95, 0xa1, 0xbd, 0xb1, 0x91, 0x95, 0xc9, 0x7d, - 0x7d, 0xa5, 0x0c, 0xa1, 0x14, 0x21, 0xd9, 0x12, 0x4e, 0x11, 0x94, 0x20, - 0xe9, 0x12, 0x28, 0xb9, 0x12, 0x29, 0x99, 0x86, 0x50, 0x4a, 0x90, 0x6c, - 0x09, 0xa7, 0x04, 0x4a, 0x90, 0x74, 0x09, 0x94, 0x5c, 0x89, 0x94, 0x60, - 0x54, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, 0xf8, - 0x84, 0xa5, 0xc9, 0xb9, 0x88, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0xcd, - 0xa5, 0xe9, 0x95, 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, - 0x63, 0x14, 0x96, 0x26, 0xe7, 0x12, 0x26, 0x77, 0xf6, 0x45, 0x97, 0x07, - 0x57, 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x2b, 0x2c, 0x4d, 0xce, 0x25, - 0x4c, 0xee, 0xec, 0x8b, 0x2e, 0x0f, 0xae, 0xec, 0x2b, 0x8c, 0x2d, 0xed, - 0xcc, 0xed, 0x6b, 0x2e, 0x4d, 0xaf, 0x8c, 0x88, 0x19, 0xdb, 0x5b, 0x18, - 0x1d, 0x0d, 0x1e, 0x0d, 0x15, 0x38, 0xb9, 0x37, 0xb5, 0xb2, 0x31, 0xba, - 0xb4, 0x37, 0xb7, 0x21, 0x60, 0xa0, 0x10, 0x09, 0x18, 0x24, 0x61, 0xa0, - 0x0c, 0x09, 0xa7, 0x10, 0x4a, 0x90, 0x88, 0x41, 0x32, 0x06, 0xca, 0x90, - 0x90, 0x81, 0x52, 0x24, 0x50, 0x52, 0x06, 0x89, 0x94, 0x98, 0x01, 0x13, - 0x3a, 0xb9, 0x30, 0xb7, 0x39, 0xb3, 0x37, 0xb9, 0xb6, 0x21, 0x60, 0xa0, - 0x18, 0x09, 0x18, 0x24, 0x61, 0xa0, 0x0c, 0x09, 0xa7, 0x18, 0x4a, 0x90, - 0x88, 0x41, 0x32, 0x06, 0xca, 0x90, 0x90, 0x81, 0x52, 0x24, 0x50, 0x52, - 0x06, 0x89, 0x94, 0xa0, 0xc1, 0x10, 0x24, 0xf1, 0x92, 0x2f, 0x39, 0x83, - 0x24, 0x0d, 0x86, 0x18, 0x08, 0x90, 0x68, 0x89, 0x1a, 0xf0, 0x79, 0x6b, + 0xb9, 0x0d, 0x51, 0x92, 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, + 0x58, 0x9a, 0x9c, 0x8b, 0x5d, 0x99, 0x1c, 0x5d, 0x19, 0xde, 0xd7, 0x5b, + 0x1d, 0x1d, 0x5c, 0x1d, 0x1d, 0xad, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, + 0xba, 0x32, 0x32, 0x94, 0x9a, 0xb1, 0x37, 0xb6, 0x37, 0x39, 0x22, 0x3b, + 0x9a, 0x2f, 0xb3, 0x14, 0x16, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x98, + 0xa4, 0x4a, 0xac, 0x04, 0x4a, 0xa2, 0x44, 0x4a, 0x2e, 0x3a, 0x61, 0x69, + 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x2c, 0xcc, 0xd8, 0xde, 0xc2, 0xe8, 0x98, 0xc0, 0xbd, 0xa5, 0xb9, 0xd1, + 0x4d, 0xa5, 0xe9, 0x95, 0x0d, 0x51, 0x92, 0x2c, 0x81, 0x12, 0x2d, 0x91, + 0x92, 0x6d, 0x88, 0x91, 0x50, 0x09, 0x96, 0x70, 0x84, 0xc2, 0xd2, 0xe4, + 0x5c, 0xec, 0xca, 0xe4, 0xe8, 0xca, 0xf0, 0xbe, 0xd2, 0xdc, 0xe0, 0xea, + 0xe8, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, + 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0xd1, 0x3b, 0x2b, 0x73, + 0x2b, 0x93, 0x0b, 0xa3, 0x2b, 0x23, 0x43, 0xf9, 0xfa, 0x0a, 0x4b, 0x93, + 0xfb, 0x82, 0x63, 0x0b, 0x1b, 0x2b, 0x43, 0x7b, 0x63, 0x23, 0x2b, 0x93, + 0xfb, 0xfa, 0x4a, 0xa1, 0x61, 0xc6, 0xf6, 0x16, 0x46, 0x27, 0x33, 0x84, + 0x52, 0x84, 0xc4, 0x4b, 0x3e, 0x45, 0x50, 0x82, 0x04, 0x0c, 0x12, 0x28, + 0x09, 0x83, 0x44, 0x4a, 0xa6, 0x21, 0x94, 0x12, 0x24, 0x5e, 0xf2, 0x29, + 0x81, 0x12, 0x24, 0x60, 0x90, 0x40, 0x49, 0x94, 0x48, 0xc9, 0x45, 0x25, + 0x2c, 0x4d, 0xce, 0x45, 0xac, 0xce, 0xcc, 0xac, 0x4c, 0x8e, 0x4f, 0x58, + 0x9a, 0x9c, 0x8b, 0x58, 0x9d, 0x99, 0x59, 0x99, 0xdc, 0xd7, 0x5c, 0x9a, + 0x5e, 0x19, 0x91, 0xb0, 0x34, 0x39, 0x17, 0xb9, 0xb2, 0x30, 0x32, 0x46, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0xbc, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, + 0xce, 0xbe, 0xe8, 0xf2, 0xe0, 0xca, 0xbe, 0xc2, 0xd8, 0xd2, 0xce, 0xdc, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x88, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xd1, + 0xe0, 0xd1, 0x50, 0x81, 0x93, 0x7b, 0x53, 0x2b, 0x1b, 0xa3, 0x4b, 0x7b, + 0x73, 0x1b, 0x02, 0x06, 0x0a, 0x91, 0x90, 0x41, 0x52, 0x06, 0xca, 0x90, + 0x7c, 0x0a, 0xa1, 0x04, 0x89, 0x19, 0x24, 0x67, 0xa0, 0x0c, 0x09, 0x1a, + 0x28, 0x45, 0x02, 0x25, 0x69, 0x90, 0x48, 0x89, 0x1a, 0x30, 0xa1, 0x93, + 0x0b, 0x73, 0x9b, 0x33, 0x7b, 0x93, 0x6b, 0x1b, 0x02, 0x06, 0x8a, 0x91, + 0x90, 0x41, 0x52, 0x06, 0xca, 0x90, 0x7c, 0x8a, 0xa1, 0x04, 0x89, 0x19, + 0x24, 0x67, 0xa0, 0x0c, 0x09, 0x1a, 0x28, 0x45, 0x02, 0x25, 0x69, 0x90, + 0x48, 0x09, 0x1b, 0x0c, 0x41, 0x12, 0x31, 0x48, 0xc6, 0x20, 0x59, 0x83, + 0xa4, 0x0d, 0x86, 0x18, 0x08, 0x90, 0x74, 0x89, 0x1b, 0xf0, 0x79, 0x6b, 0x73, 0x4b, 0x83, 0x7b, 0xa3, 0x2b, 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, 0x93, 0xe3, 0x33, 0x95, 0xd6, 0x06, 0xc7, 0x56, 0x06, 0x32, 0xb4, 0xb2, - 0x02, 0x42, 0x25, 0x14, 0x14, 0x34, 0x44, 0x48, 0xda, 0x60, 0x88, 0x91, - 0xb0, 0x41, 0xe2, 0x06, 0x4c, 0x32, 0xc4, 0x48, 0xde, 0x20, 0x79, 0x03, + 0x02, 0x42, 0x25, 0x14, 0x14, 0x34, 0x44, 0x48, 0xe2, 0x60, 0x88, 0x91, + 0xc0, 0x41, 0x22, 0x07, 0x4c, 0x32, 0xc4, 0x48, 0xe6, 0x20, 0x99, 0x03, 0x26, 0x19, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, @@ -506,182 +270,435 @@ const unsigned char sdl_metallib[] = { 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x84, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf4, 0x50, - 0x0e, 0xf8, 0x30, 0x25, 0x58, 0x03, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, - 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, - 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, - 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, - 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, - 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, - 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, - 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, - 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, - 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, - 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, - 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, - 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, - 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, - 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, - 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, - 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, - 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, - 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, - 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, - 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, - 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, - 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, - 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, - 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, - 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, - 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, - 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, - 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, - 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, - 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, - 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, - 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, - 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, - 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, - 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, - 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, - 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, - 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, - 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, - 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, - 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x06, 0xf0, 0xb0, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x15, 0x11, 0x4d, - 0xc4, 0x05, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, - 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, - 0x22, 0x82, 0x20, 0x08, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, 0xb9, 0x11, - 0x00, 0x1a, 0x33, 0x00, 0x24, 0x66, 0x00, 0x28, 0xcc, 0x00, 0x00, 0x00, - 0xe3, 0x11, 0x0b, 0x74, 0x41, 0x14, 0x94, 0xf1, 0x08, 0x47, 0xca, 0x24, - 0x0a, 0xca, 0x20, 0xc3, 0x50, 0x20, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x90, - 0xac, 0xae, 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x09, 0x64, 0x42, 0x20, 0x1f, - 0x0b, 0x0a, 0xf8, 0x8c, 0x47, 0x5c, 0x9b, 0x18, 0x40, 0x14, 0x94, 0x41, - 0x06, 0xc6, 0xb1, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x08, - 0x0e, 0x0c, 0xce, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x13, 0x67, 0x42, - 0x20, 0x1f, 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x80, 0x41, 0x19, 0xb0, 0x01, - 0x47, 0x41, 0x19, 0x64, 0x08, 0xb0, 0xcd, 0x82, 0x4a, 0x3e, 0x83, 0x0c, - 0x83, 0x16, 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, - 0xd1, 0x95, 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, - 0x80, 0x41, 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, - 0x6d, 0x20, 0x07, 0x79, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xa0, 0x0c, - 0xd0, 0xc0, 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x70, 0x06, 0x6e, 0x60, - 0x01, 0x18, 0xc8, 0x67, 0x90, 0xa1, 0x48, 0x83, 0x38, 0xb0, 0xa0, 0x93, - 0xcf, 0x20, 0xc3, 0xb1, 0x06, 0x74, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x06, - 0x3d, 0x70, 0x03, 0x38, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x03, 0x1f, 0xc0, - 0x81, 0x1d, 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, - 0xb1, 0x20, 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, - 0x80, 0x07, 0x01, 0x30, 0xdb, 0x10, 0x8c, 0x42, 0x90, 0x41, 0x40, 0x0c, - 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0x80, 0x83, 0x2d, 0xc3, 0x10, - 0xc0, 0xc1, 0x96, 0xe1, 0x08, 0xe0, 0x60, 0xcb, 0xc0, 0x04, 0x70, 0xb0, - 0x65, 0x88, 0x02, 0x38, 0xd8, 0x32, 0x58, 0x01, 0x1c, 0x6c, 0x19, 0xc6, - 0x20, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0xf8, 0x30, 0x25, 0x78, 0x03, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x06, 0x00, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, + 0x45, 0x44, 0x13, 0x71, 0x01, 0x00, 0x61, 0x20, 0x00, 0x00, 0x54, 0x00, + 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, + 0x10, 0xc6, 0x22, 0x82, 0x20, 0x08, 0x46, 0x00, 0x88, 0x95, 0x40, 0x19, + 0x14, 0x01, 0x8d, 0x19, 0x00, 0x12, 0x33, 0x00, 0x14, 0x66, 0x00, 0x08, + 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x11, + 0x4c, 0x84, 0x45, 0x14, 0x94, 0xf1, 0x88, 0x67, 0xd2, 0x26, 0x0a, 0xca, + 0x20, 0xc3, 0x60, 0x30, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x98, 0x2e, 0xaf, + 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x4a, 0x64, 0x42, 0x20, 0x1f, 0x0b, 0x0a, + 0xf8, 0x8c, 0x47, 0x60, 0xdc, 0x18, 0x40, 0x14, 0x94, 0x41, 0x06, 0xe6, + 0xb9, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x88, 0x2e, 0x0c, + 0xd0, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x54, 0x67, 0x42, 0x20, 0x1f, + 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x84, 0x81, 0x19, 0xb4, 0x01, 0x47, 0x41, + 0x19, 0x64, 0x08, 0xb2, 0xcf, 0x82, 0x4a, 0x3e, 0x83, 0x0c, 0xc3, 0x26, + 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, 0xe1, 0x99, + 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, 0x84, 0x81, + 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, 0x6e, 0x30, + 0x07, 0x7a, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xc0, 0x0c, 0xd8, 0xc0, + 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x80, 0x06, 0x6f, 0x60, 0x01, 0x18, + 0xc8, 0x67, 0x90, 0xa1, 0x50, 0x03, 0x39, 0xb0, 0xa0, 0x93, 0xcf, 0x20, + 0xc3, 0xc1, 0x06, 0x75, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x86, 0x3d, 0x80, + 0x03, 0x3a, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, 0x1f, 0xc8, 0xc1, 0x1d, + 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, 0xb1, 0x20, + 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, 0x80, 0x07, + 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, 0x10, 0xe0, 0x81, 0x90, + 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, + 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, 0x96, 0xe1, 0x08, 0xe8, + 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, 0x02, 0x3a, 0xd8, 0x32, + 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x14, 0x09, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, - 0x21, 0x0c, 0x00, 0x00, 0x42, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, - 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, - 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, - 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, - 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, - 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x08, 0x11, 0x62, 0xa8, 0xa0, - 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, - 0x82, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, - 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, - 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, - 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, - 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, - 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, - 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, - 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, - 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, - 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, - 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, - 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, - 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, - 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, - 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, - 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, - 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, - 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, - 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, - 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, - 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, - 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, - 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, - 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, - 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, - 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, - 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, - 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, - 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, - 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, - 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, - 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, - 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, - 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xb0, 0x0b, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xe9, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, - 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, - 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, - 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x20, 0x42, 0x00, - 0x24, 0xc0, 0x02, 0x54, 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, - 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, - 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x28, 0x33, 0x00, - 0xc3, 0x08, 0x04, 0x30, 0x88, 0x10, 0x04, 0x45, 0x08, 0xa1, 0x19, 0x08, - 0x98, 0x23, 0x00, 0x83, 0x14, 0xb0, 0x39, 0x02, 0x50, 0x18, 0x01, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x02, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, - 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, 0x12, 0x18, 0x01, 0x28, - 0x90, 0x22, 0x28, 0x84, 0x82, 0x20, 0x1c, 0x01, 0xa0, 0x1b, 0x4b, 0x70, - 0x04, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, - 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, - 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, 0x41, 0x14, 0xc0, 0x81, 0x50, 0xb9, - 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x18, - 0x41, 0x21, 0x18, 0x05, 0xdd, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, - 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, - 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x06, 0x04, 0xa5, 0xad, - 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, - 0x85, 0x66, 0x26, 0x65, 0x88, 0x50, 0x10, 0x43, 0x0c, 0x23, 0x30, 0x0c, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x20, 0x02, 0x01, 0x24, 0xc0, 0x02, 0x54, 0x1b, 0x90, + 0xa1, 0x00, 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0x76, 0x08, 0x41, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, + 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, + 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, + 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x62, 0x0c, 0x11, 0x84, + 0x31, 0x74, 0x06, 0x02, 0xe6, 0x08, 0xc0, 0x20, 0x05, 0xd4, 0x1c, 0x01, + 0x28, 0x0c, 0x22, 0x04, 0xc2, 0x30, 0x02, 0xa1, 0x8c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x50, + 0x04, 0x23, 0x00, 0x05, 0x18, 0x50, 0x08, 0x65, 0x50, 0x20, 0x05, 0x41, + 0x6c, 0x04, 0x80, 0xd6, 0x58, 0x82, 0x43, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, + 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, + 0x22, 0x24, 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, + 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, 0x28, 0x05, 0xe1, 0x20, + 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, + 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, + 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, + 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, + 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, 0x50, 0x10, 0x65, 0x60, 0xd1, 0x54, + 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, 0x0e, 0x25, 0x50, 0x02, 0x65, 0xe0, + 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, + 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, + 0x26, 0xc6, 0x56, 0x36, 0x44, 0x48, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, + 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, + 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x43, 0x84, 0x64, 0x21, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, + 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, + 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, + 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x92, 0x86, 0x4c, 0x58, 0x9a, + 0x9c, 0x0b, 0xdc, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0x1b, 0xa3, 0xb0, + 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, + 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x64, + 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, + 0x88, 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, 0xb9, 0x0d, 0x51, 0x92, + 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, 0x58, 0x9a, 0x9c, 0x8b, + 0x5d, 0x99, 0x1c, 0x5d, 0x19, 0xde, 0xd7, 0x5b, 0x1d, 0x1d, 0x5c, 0x1d, + 0x1d, 0xad, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x94, + 0x9a, 0xb1, 0x37, 0xb6, 0x37, 0x39, 0x22, 0x3b, 0x9a, 0x2f, 0xb3, 0x14, + 0x16, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x98, 0xa4, 0x4a, 0xac, 0x04, + 0x4a, 0xa2, 0x44, 0x4a, 0x2e, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, + 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x34, 0xcc, 0xd8, 0xde, 0xc2, + 0xe8, 0x64, 0x88, 0xd0, 0x95, 0xe1, 0x8d, 0xbd, 0xbd, 0xc9, 0x91, 0x0d, + 0x61, 0x92, 0x2a, 0xc9, 0x12, 0x28, 0xd1, 0x12, 0x29, 0xd9, 0x86, 0x18, + 0x09, 0x95, 0x60, 0x09, 0x47, 0x28, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, + 0x8e, 0xae, 0x0c, 0xef, 0x2b, 0xcd, 0x0d, 0xae, 0x8e, 0x8e, 0x52, 0x58, + 0x9a, 0x9c, 0x0b, 0xdb, 0xdb, 0x58, 0x18, 0x5d, 0xda, 0x9b, 0xdb, 0x57, + 0x9a, 0x1b, 0x59, 0x19, 0x1e, 0xbd, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, + 0xba, 0x32, 0x32, 0x94, 0xaf, 0xaf, 0xb0, 0x34, 0xb9, 0x2f, 0x38, 0xb6, + 0xb0, 0xb1, 0x32, 0xb4, 0x37, 0x36, 0xb2, 0x32, 0xb9, 0xaf, 0xaf, 0x94, + 0x21, 0x94, 0x32, 0x24, 0x5e, 0xf2, 0x29, 0x83, 0x12, 0x24, 0x60, 0x90, + 0x40, 0x89, 0x96, 0x48, 0xc9, 0x34, 0x84, 0x52, 0x82, 0xc4, 0x4b, 0x3e, + 0x25, 0x50, 0x82, 0x04, 0x0c, 0x12, 0x28, 0x89, 0x12, 0x29, 0xb9, 0x86, + 0x50, 0x8a, 0x90, 0x78, 0xc9, 0xa7, 0x08, 0x4a, 0x90, 0x80, 0x41, 0x02, + 0x25, 0x5a, 0x22, 0x25, 0x1b, 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, + 0x33, 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, + 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x44, 0xc2, 0xd2, 0xe4, + 0x5c, 0xe4, 0xca, 0xc2, 0xc8, 0x18, 0x85, 0xa5, 0xc9, 0xb9, 0x84, 0xc9, + 0x9d, 0x7d, 0xd1, 0xe5, 0xc1, 0x95, 0x7d, 0xcd, 0xa5, 0xe9, 0x95, 0xf1, + 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, + 0xfb, 0x0a, 0x63, 0x4b, 0x3b, 0x73, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x23, + 0x62, 0xc6, 0xf6, 0x16, 0x46, 0x47, 0x83, 0x47, 0x43, 0x05, 0x4e, 0xee, + 0x4d, 0xad, 0x6c, 0x8c, 0x2e, 0xed, 0xcd, 0x6d, 0x08, 0x18, 0x28, 0x46, + 0x42, 0x06, 0x49, 0x19, 0x28, 0x44, 0xf2, 0x29, 0x82, 0x12, 0x24, 0x66, + 0x90, 0x9c, 0x81, 0x42, 0x24, 0x68, 0xa0, 0x1c, 0x09, 0x94, 0xa4, 0x41, + 0x22, 0x25, 0x6a, 0xc0, 0x84, 0x4e, 0x2e, 0xcc, 0x6d, 0xce, 0xec, 0x4d, + 0xae, 0x6d, 0x08, 0x18, 0x28, 0x45, 0x42, 0x06, 0x49, 0x19, 0x28, 0x44, + 0xf2, 0x29, 0x86, 0x12, 0x24, 0x66, 0x90, 0x9c, 0x81, 0x42, 0x24, 0x68, + 0xa0, 0x1c, 0x09, 0x94, 0xa4, 0x41, 0x22, 0x25, 0x6c, 0x30, 0x44, 0x49, + 0xc2, 0x20, 0x11, 0x83, 0x64, 0x0c, 0x92, 0x35, 0x48, 0xda, 0x60, 0x88, + 0x81, 0x00, 0x49, 0x97, 0xb8, 0x01, 0x9f, 0xb7, 0x36, 0xb7, 0x34, 0xb8, + 0x37, 0xba, 0x32, 0x37, 0x3a, 0x90, 0x31, 0xb4, 0x30, 0x39, 0x3e, 0x53, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, + 0x41, 0x41, 0x43, 0x84, 0x24, 0x0e, 0x86, 0x18, 0x09, 0x1c, 0x24, 0x72, + 0xc0, 0x24, 0x43, 0x8c, 0x64, 0x0e, 0x92, 0x39, 0x60, 0x92, 0x11, 0x11, + 0x3b, 0xb0, 0x83, 0x3d, 0xb4, 0x83, 0x1b, 0xb4, 0xc3, 0x3b, 0x90, 0x43, + 0x3d, 0xb0, 0x43, 0x39, 0xb8, 0x81, 0x39, 0xb0, 0x43, 0x38, 0x9c, 0xc3, + 0x3c, 0x4c, 0x11, 0x82, 0x61, 0x84, 0xc2, 0x0e, 0xec, 0x60, 0x0f, 0xed, + 0xe0, 0x06, 0xe9, 0x40, 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x28, + 0x46, 0x2c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xf6, 0x50, 0x0e, 0xf2, + 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x30, 0x46, 0x50, 0xe1, + 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xec, 0x10, 0x0e, 0xee, 0x70, 0x0e, 0xf5, + 0x10, 0x0e, 0xe7, 0x50, 0x0e, 0xbf, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, + 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x64, 0xc4, 0x14, 0x0e, 0xe9, + 0x20, 0x0f, 0x6e, 0x30, 0x0e, 0xef, 0xd0, 0x0e, 0xf0, 0x90, 0x0e, 0xec, + 0x50, 0x0e, 0xbf, 0xf0, 0x0e, 0xf0, 0x40, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, + 0x30, 0x0f, 0x53, 0x06, 0x85, 0x71, 0x46, 0x28, 0xe1, 0x90, 0x0e, 0xf2, + 0xe0, 0x06, 0xf6, 0x50, 0x0e, 0xf2, 0x40, 0x0f, 0xe5, 0x80, 0x0f, 0x53, + 0x82, 0x37, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, + 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, + 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, + 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, + 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, + 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, + 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, + 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, + 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, + 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, + 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, + 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, + 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, + 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, + 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, + 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, + 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, + 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, + 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, + 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, + 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, + 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, + 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, + 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, + 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, + 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, + 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, + 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, + 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, + 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, + 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, + 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, + 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, + 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, + 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, + 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, + 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, + 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, + 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0xf0, + 0xb0, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x15, 0x11, 0x4d, 0xc4, 0x05, + 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x13, 0x04, + 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xe4, 0xc6, + 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, 0x22, 0x82, + 0x20, 0x08, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, 0xb9, 0x11, 0x00, 0x1a, + 0x33, 0x00, 0x24, 0x66, 0x00, 0x28, 0xcc, 0x00, 0x00, 0x00, 0xe3, 0x11, + 0x4b, 0x74, 0x45, 0x14, 0x94, 0xf1, 0x08, 0x67, 0xca, 0x26, 0x0a, 0xca, + 0x20, 0xc3, 0x50, 0x20, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x90, 0xae, 0xae, + 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x09, 0x64, 0x42, 0x20, 0x1f, 0x0b, 0x0a, + 0xf8, 0x8c, 0x47, 0x5c, 0x9c, 0x18, 0x40, 0x14, 0x94, 0x41, 0x06, 0xc6, + 0xb1, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x08, 0x2e, 0x0c, + 0xce, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x13, 0x67, 0x42, 0x20, 0x1f, + 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x80, 0x81, 0x19, 0xb0, 0x01, 0x47, 0x41, + 0x19, 0x64, 0x08, 0xb0, 0xcd, 0x82, 0x4a, 0x3e, 0x83, 0x0c, 0x83, 0x16, + 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, 0xd1, 0x95, + 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, 0x80, 0x41, + 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, 0x6d, 0x30, + 0x07, 0x79, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xa0, 0x0c, 0xd0, 0xc0, + 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x70, 0x06, 0x6e, 0x60, 0x01, 0x18, + 0xc8, 0x67, 0x90, 0xa1, 0x48, 0x83, 0x38, 0xb0, 0xa0, 0x93, 0xcf, 0x20, + 0xc3, 0xb1, 0x06, 0x74, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x86, 0x3d, 0x70, + 0x03, 0x38, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, 0x1f, 0xc0, 0x81, 0x1d, + 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, 0xb1, 0x20, + 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, 0x80, 0x07, + 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, 0x10, 0x90, 0x82, 0x90, + 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, + 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, 0x96, 0xe1, 0x08, 0xe8, + 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, 0x02, 0x3a, 0xd8, 0x32, + 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x35, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x08, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x00, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x10, 0x82, 0x00, 0x58, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x24, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x65, 0x08, 0x09, + 0x9a, 0x81, 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x1b, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x0c, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, 0x12, 0x18, + 0x01, 0x28, 0x82, 0x42, 0x28, 0x08, 0xba, 0xb1, 0x04, 0x87, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x31, 0x14, 0xc0, 0x61, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x18, 0x41, 0x21, + 0x18, 0x04, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x50, 0x10, 0x43, 0x0c, 0x23, 0x30, 0x0a, 0x43, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x29, 0x0e, 0x23, 0x30, 0x02, 0x43, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, @@ -696,254 +713,1030 @@ const unsigned char sdl_metallib[] = { 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe2, 0x31, - 0x84, 0x02, 0x2a, 0xa2, 0x21, 0x42, 0x21, 0x51, 0x09, 0x4b, 0x93, 0x73, - 0x11, 0xab, 0x33, 0x33, 0x2b, 0x93, 0xe3, 0x13, 0x96, 0x26, 0xe7, 0x22, - 0x56, 0x67, 0x66, 0x56, 0x26, 0xf7, 0x35, 0x97, 0xa6, 0x57, 0x46, 0x29, - 0x2c, 0x4d, 0xce, 0x85, 0xed, 0x6d, 0x2c, 0x8c, 0x2e, 0xed, 0xcd, 0xed, - 0x2b, 0xcd, 0x8d, 0xac, 0x0c, 0x8f, 0x48, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, - 0x59, 0x18, 0x19, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, - 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, - 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, - 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x64, 0xc2, 0xd2, - 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, 0x38, 0x8c, - 0xbd, 0xb1, 0x0d, 0x01, 0x03, 0x43, 0x28, 0xa8, 0xa2, 0x32, 0x86, 0xc2, - 0x32, 0x04, 0x23, 0x28, 0xae, 0x02, 0x33, 0x86, 0x22, 0x33, 0x86, 0x02, - 0x2a, 0xa2, 0x42, 0x2b, 0xb6, 0x21, 0x42, 0xc1, 0x0d, 0x31, 0x08, 0xa0, - 0x98, 0x8a, 0x8e, 0xcf, 0x5b, 0x9b, 0x5b, 0x1a, 0xdc, 0x1b, 0x5d, 0x99, - 0x1b, 0x1d, 0xc8, 0x18, 0x5a, 0x98, 0x1c, 0x9f, 0xa9, 0xb4, 0x36, 0x38, - 0xb6, 0x32, 0x90, 0xa1, 0x95, 0x15, 0x10, 0x2a, 0xa1, 0xa0, 0xa0, 0x21, - 0x42, 0x01, 0x06, 0x43, 0x8c, 0xe2, 0x2b, 0xc2, 0x00, 0x39, 0x86, 0x18, - 0x85, 0x18, 0x14, 0x62, 0x80, 0x1c, 0x23, 0x22, 0x76, 0x60, 0x07, 0x7b, - 0x68, 0x07, 0x37, 0x68, 0x87, 0x77, 0x20, 0x87, 0x7a, 0x60, 0x87, 0x72, - 0x70, 0x03, 0x73, 0x60, 0x87, 0x70, 0x38, 0x87, 0x79, 0x98, 0x22, 0x04, - 0xc3, 0x08, 0x85, 0x1d, 0xd8, 0xc1, 0x1e, 0xda, 0xc1, 0x0d, 0xd2, 0x81, - 0x1c, 0xca, 0xc1, 0x1d, 0xe8, 0x61, 0x4a, 0x50, 0x8c, 0x58, 0xc2, 0x21, - 0x1d, 0xe4, 0xc1, 0x0d, 0xec, 0xa1, 0x1c, 0xe4, 0x61, 0x1e, 0xd2, 0xe1, - 0x1d, 0xdc, 0x61, 0x4a, 0x60, 0x8c, 0xa0, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, - 0x0d, 0xd8, 0x21, 0x1c, 0xdc, 0xe1, 0x1c, 0xea, 0x21, 0x1c, 0xce, 0xa1, - 0x1c, 0x7e, 0xc1, 0x1e, 0xca, 0x41, 0x1e, 0xe6, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0xa6, 0x04, 0xc8, 0x88, 0x29, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0x60, - 0x1c, 0xde, 0xa1, 0x1d, 0xe0, 0x21, 0x1d, 0xd8, 0xa1, 0x1c, 0x7e, 0xe1, - 0x1d, 0xe0, 0x81, 0x1e, 0xd2, 0xe1, 0x1d, 0xdc, 0x61, 0x1e, 0xa6, 0x0c, - 0x0a, 0xe3, 0x8c, 0x60, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, 0xcc, 0x41, - 0x1e, 0xc2, 0xe1, 0x1c, 0xda, 0xa1, 0x1c, 0xdc, 0x81, 0x1e, 0xa6, 0x04, - 0x1e, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, - 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, - 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, - 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, - 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, - 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, - 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, - 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, - 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, - 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, - 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, - 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, - 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, - 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, - 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, - 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, - 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, - 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, - 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, - 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, - 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, - 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, - 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, - 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, - 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, - 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, - 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, - 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, - 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, - 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, - 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, - 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, - 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, - 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, - 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, - 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, - 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, - 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, - 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, - 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, - 0x71, 0x20, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x20, 0xb1, 0x5d, - 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, 0x11, 0x01, 0x06, 0x43, 0x34, 0x13, - 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x13, 0x04, 0x01, 0x05, 0x25, 0x83, 0x80, 0x18, 0x02, 0x00, 0x00, 0x00, - 0x5b, 0x06, 0x20, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x02, 0x2a, 0xa2, 0x21, 0x42, 0x21, 0x51, 0x0a, 0x4b, 0x93, 0x73, + 0x31, 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, 0xa3, 0xfb, 0x4a, 0x73, 0x83, + 0xab, 0xa3, 0x63, 0x76, 0x56, 0xe6, 0x56, 0x26, 0x17, 0x46, 0x57, 0x46, + 0x86, 0x82, 0x03, 0xf7, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x46, 0x64, + 0x27, 0xf3, 0x65, 0x96, 0x42, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0xac, 0xcc, + 0x8d, 0xae, 0x4c, 0x8e, 0x4f, 0x58, 0x9a, 0x9c, 0x0b, 0x5c, 0x99, 0xdc, + 0x1c, 0x5c, 0xd9, 0x18, 0x5d, 0x9a, 0x5d, 0x19, 0x0d, 0x33, 0xb6, 0xb7, + 0x30, 0x3a, 0x19, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x44, 0xe0, 0xde, 0xe6, 0xd2, 0xe8, 0xd2, 0xde, + 0xdc, 0x86, 0x48, 0x86, 0x50, 0x50, 0x45, 0x55, 0x58, 0xc5, 0x55, 0x40, + 0x05, 0x56, 0x64, 0x85, 0x46, 0xeb, 0xac, 0xcc, 0xad, 0x4c, 0x2e, 0x8c, + 0xae, 0x8c, 0x0c, 0xa5, 0x66, 0xec, 0x8d, 0xed, 0x4d, 0x8e, 0xc8, 0x8e, + 0xe6, 0xcb, 0x2c, 0x85, 0xc5, 0xd8, 0x1b, 0xdb, 0x9b, 0xdc, 0x10, 0xc9, + 0x08, 0x0a, 0xaa, 0xe0, 0x0a, 0xab, 0xb8, 0x0a, 0xa8, 0x88, 0x8a, 0xac, + 0xe8, 0x86, 0x10, 0xc5, 0x56, 0x78, 0x43, 0x0c, 0x02, 0x28, 0xa6, 0xe2, + 0x1b, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, + 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, + 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, + 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, + 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, + 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, + 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, + 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, + 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, + 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, + 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, + 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, 0x0e, + 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, 0x0e, + 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x03, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x06, 0x20, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, + 0x11, 0x01, 0x06, 0x43, 0x34, 0x13, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xe4, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, - 0x21, 0x0c, 0x00, 0x00, 0xb6, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, - 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, - 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, - 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, - 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, - 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, - 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, - 0x8b, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, - 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, - 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, - 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, - 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, - 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, - 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, - 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, - 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, - 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, - 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, - 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, - 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, - 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, - 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, - 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, - 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, - 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, - 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, - 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, - 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, - 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, - 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, - 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, - 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, - 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, - 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, - 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, - 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, - 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, - 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, - 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, - 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, - 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x44, 0x0a, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x8e, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x1b, 0xcc, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, + 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, + 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, + 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, + 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, + 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, + 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, + 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, + 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, + 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, + 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, + 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, + 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, + 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, - 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, - 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, - 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, - 0x0c, 0x40, 0x02, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x08, 0x60, 0x01, 0xaa, - 0x0d, 0x06, 0x51, 0x00, 0x0b, 0x50, 0x6d, 0x40, 0x8a, 0xff, 0xff, 0xff, - 0xff, 0x1f, 0x00, 0x06, 0x90, 0x80, 0x6a, 0x83, 0x61, 0x04, 0xc0, 0x02, - 0x54, 0x1b, 0x8c, 0x43, 0x00, 0x16, 0xa0, 0x02, 0x49, 0x18, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, 0x88, 0x09, 0x43, 0x61, - 0x1c, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, - 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, - 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, - 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x4c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, - 0x8c, 0x20, 0x00, 0x83, 0x08, 0x41, 0x70, 0x94, 0x34, 0x45, 0x94, 0x30, - 0xf9, 0xff, 0x44, 0x5c, 0x13, 0x15, 0x11, 0xbf, 0x3d, 0xfc, 0xd3, 0x18, - 0x01, 0x30, 0x88, 0x40, 0x04, 0x17, 0x49, 0x53, 0x44, 0x09, 0x93, 0xff, - 0x4b, 0x00, 0xf3, 0x2c, 0x44, 0xf4, 0x4f, 0x63, 0x04, 0xc0, 0x20, 0x82, - 0x21, 0x14, 0x23, 0x04, 0x31, 0xca, 0x21, 0x34, 0x47, 0x10, 0xcc, 0x11, - 0x80, 0xc1, 0x30, 0x82, 0xb0, 0x14, 0x24, 0x94, 0x23, 0x14, 0x53, 0x80, - 0xda, 0x40, 0x40, 0x0a, 0xac, 0x39, 0x02, 0x50, 0x18, 0x01, 0x00, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x98, 0x04, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x8c, 0x03, 0x04, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, - 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x25, 0x30, 0x02, 0x50, - 0x20, 0x45, 0x50, 0x08, 0x05, 0x51, 0x06, 0x14, 0x47, 0x00, 0x08, 0x8e, - 0x25, 0x38, 0x02, 0x00, 0x79, 0x18, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, - 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, - 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0xc6, 0x52, 0x3c, 0x00, 0xa4, 0x50, 0xb9, - 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x2c, - 0xc2, 0x23, 0x2c, 0x06, 0xdd, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, - 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, - 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x06, 0x04, 0xa5, 0xad, - 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, - 0x85, 0x66, 0x26, 0x65, 0x88, 0xf0, 0x10, 0x43, 0x8c, 0x45, 0x58, 0x8e, - 0x65, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x79, 0x8e, 0x45, - 0x58, 0x84, 0x65, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, + 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, + 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, + 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, + 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, + 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, + 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, + 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, + 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, + 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, + 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, + 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, + 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x60, 0x83, 0x21, 0x10, 0xc0, 0x02, 0x54, 0x1b, 0x8c, + 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x80, 0x10, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x00, 0x0c, 0x20, 0x01, 0xd5, 0x06, 0xa3, 0x08, 0x80, 0x05, 0xa8, 0x36, + 0x18, 0x86, 0x00, 0x2c, 0x40, 0x05, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x26, 0x0c, 0x44, 0x61, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x44, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0x47, 0x49, 0x53, 0x44, 0x09, 0x93, 0xff, 0x4f, 0xc4, 0x35, 0x51, + 0x11, 0xf1, 0xdb, 0xc3, 0x3f, 0x8d, 0x11, 0x00, 0x83, 0x08, 0x43, 0x70, + 0x91, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xbf, 0x04, 0x30, 0xcf, 0x42, 0x44, + 0xff, 0x34, 0x46, 0x00, 0x0c, 0x22, 0x14, 0x42, 0x31, 0x42, 0x08, 0x82, + 0x18, 0x3a, 0x73, 0x04, 0xc1, 0x1c, 0x01, 0x18, 0x0c, 0x23, 0x08, 0x4a, + 0x41, 0x02, 0x31, 0x22, 0xad, 0x04, 0x88, 0x0d, 0x04, 0xa4, 0x80, 0x1a, + 0x01, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4c, + 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, + 0x02, 0x50, 0x04, 0x85, 0x50, 0x10, 0x65, 0x40, 0x6f, 0x2c, 0xc1, 0x21, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x42, 0x38, 0xc0, 0x83, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x82, 0x23, + 0x28, 0x05, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0xe0, 0x10, 0x43, 0x0c, 0x45, 0x50, 0x0c, + 0x65, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x71, 0x0e, 0x45, + 0x50, 0x04, 0x65, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, - 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x78, 0x12, 0x72, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x70, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x67, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, 0x67, 0x21, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, - 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x9e, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x9c, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, - 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe7, 0x59, - 0x86, 0x07, 0x7a, 0xa2, 0x21, 0xc2, 0x23, 0x91, 0x09, 0x4b, 0x93, 0x73, + 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x10, 0xe7, 0x51, + 0x06, 0x07, 0x72, 0xa2, 0x21, 0x82, 0x23, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, - 0xb7, 0x21, 0xd0, 0x32, 0x3c, 0xd4, 0x53, 0x3d, 0xd6, 0x03, 0x3d, 0xd1, - 0x73, 0x3d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, - 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x66, 0x67, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, - 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, - 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, - 0xe8, 0xd2, 0xec, 0xca, 0x68, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xc9, 0x10, - 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, 0x7b, 0x93, 0x23, 0x1b, 0x22, 0x2d, 0xc2, - 0xa3, 0x3d, 0xdb, 0x53, 0x3d, 0xdc, 0x03, 0x3d, 0xdd, 0x73, 0x3d, 0x1e, - 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, 0xb3, 0x32, 0x39, 0x3e, - 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x94, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, - 0xe8, 0xd2, 0xde, 0xdc, 0xbe, 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0x88, 0x84, - 0xa5, 0xc9, 0xb9, 0xc8, 0x95, 0x85, 0x91, 0x31, 0x0a, 0x4b, 0x93, 0x73, - 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0xe3, 0x15, 0x96, 0x26, 0xe7, 0x12, 0x26, 0x77, 0xf6, 0x45, 0x97, - 0x07, 0x57, 0xf6, 0x15, 0xc6, 0x96, 0x76, 0xe6, 0xf6, 0x35, 0x97, 0xa6, - 0x57, 0xc6, 0x61, 0xec, 0x8d, 0x6d, 0x08, 0x18, 0x2c, 0xc5, 0x03, 0x06, - 0x4f, 0x18, 0x2c, 0xc4, 0x23, 0x06, 0xcb, 0xb0, 0x08, 0xcf, 0x18, 0x3c, - 0x64, 0xb0, 0x10, 0x4f, 0x19, 0x2c, 0xc4, 0x03, 0x3d, 0xd1, 0x73, 0x3d, - 0x66, 0xc0, 0x25, 0x2c, 0x4d, 0xce, 0x85, 0xae, 0x0c, 0x8f, 0xae, 0x4e, - 0xae, 0x8c, 0x4a, 0x58, 0x9a, 0x9c, 0xcb, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, - 0x19, 0x31, 0xba, 0x32, 0x3c, 0xba, 0x3a, 0xb9, 0x32, 0x19, 0x32, 0x1e, - 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x16, 0x90, 0xb9, 0xb0, 0x36, 0x38, 0xb6, - 0x32, 0x1f, 0x0e, 0x74, 0x65, 0x78, 0x43, 0xa8, 0x05, 0x79, 0xd0, 0xe0, - 0x11, 0x83, 0x65, 0x58, 0x84, 0x27, 0x0d, 0x1e, 0xe8, 0x51, 0x83, 0xe7, - 0x7a, 0xd6, 0x80, 0x4b, 0x58, 0x9a, 0x9c, 0xcb, 0x5c, 0x58, 0x1b, 0x1c, - 0x5b, 0x99, 0x1c, 0x8f, 0xb9, 0xb0, 0x36, 0x38, 0xb6, 0x32, 0x39, 0x06, - 0x73, 0x43, 0xa4, 0xc5, 0x78, 0xda, 0xe0, 0x11, 0x83, 0x65, 0x58, 0x84, - 0x07, 0x7a, 0xdc, 0xe0, 0xb9, 0x9e, 0x37, 0x18, 0xa2, 0x3c, 0xd9, 0xf3, - 0x3d, 0x67, 0xf0, 0xb0, 0xc1, 0x03, 0x07, 0x43, 0x8c, 0x04, 0x78, 0xa6, - 0x27, 0x0e, 0xf8, 0xbc, 0xb5, 0xb9, 0xa5, 0xc1, 0xbd, 0xd1, 0x95, 0xb9, - 0xd1, 0x81, 0x8c, 0xa1, 0x85, 0xc9, 0xf1, 0x99, 0x4a, 0x6b, 0x83, 0x63, - 0x2b, 0x03, 0x19, 0x5a, 0x59, 0x01, 0xa1, 0x12, 0x0a, 0x0a, 0x1a, 0x22, - 0x3c, 0x74, 0x30, 0xc4, 0x78, 0xe6, 0xe0, 0xa9, 0x83, 0x28, 0x19, 0x62, - 0x3c, 0x76, 0xf0, 0xd8, 0x41, 0x94, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, + 0xb7, 0x21, 0x90, 0x32, 0x38, 0x94, 0x53, 0x39, 0x96, 0x03, 0x39, 0x91, + 0x73, 0x39, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, + 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, + 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x14, 0xc1, 0xd1, + 0x9c, 0xcd, 0xa9, 0x1c, 0xce, 0x81, 0x9c, 0xc8, 0xb9, 0x9c, 0x8e, 0xd9, + 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, + 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, + 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, + 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0x24, 0x85, 0x70, 0x34, 0xe7, 0x73, + 0x2a, 0x87, 0x73, 0x20, 0x07, 0x0c, 0x9c, 0xcb, 0x09, 0x03, 0x2e, 0x61, + 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x94, 0xc2, + 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, + 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0xa8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, + 0xb5, 0xc1, 0xb1, 0x95, 0x11, 0xa3, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, + 0x93, 0x21, 0xe3, 0x31, 0x63, 0x7b, 0x0b, 0xa3, 0x63, 0x01, 0x99, 0x0b, + 0x6b, 0x83, 0x63, 0x2b, 0xf3, 0xe1, 0x40, 0x57, 0x86, 0x37, 0x84, 0x52, + 0x0e, 0x67, 0x0c, 0x1c, 0x32, 0x50, 0x06, 0x45, 0x70, 0xca, 0xc0, 0x81, + 0x1c, 0x33, 0x70, 0x2e, 0xe7, 0x0c, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, + 0x85, 0xb5, 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, 0x63, + 0x2b, 0x93, 0x63, 0x30, 0x37, 0x44, 0x52, 0x0a, 0x27, 0x0d, 0x1c, 0x32, + 0x50, 0x06, 0x45, 0x70, 0x20, 0x47, 0x0d, 0x9c, 0xcb, 0x59, 0x83, 0x21, + 0x8a, 0x93, 0x39, 0x9e, 0x23, 0x06, 0x0e, 0x1a, 0x38, 0x6c, 0x30, 0xc4, + 0x40, 0x00, 0x67, 0x72, 0xda, 0x60, 0x44, 0xc4, 0x0e, 0xec, 0x60, 0x0f, + 0xed, 0xe0, 0x06, 0xed, 0xf0, 0x0e, 0xe4, 0x50, 0x0f, 0xec, 0x50, 0x0e, + 0x6e, 0x60, 0x0e, 0xec, 0x10, 0x0e, 0xe7, 0x30, 0x0f, 0x53, 0x84, 0x60, + 0x18, 0xa1, 0xb0, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3a, 0x90, + 0x43, 0x39, 0xb8, 0x03, 0x3d, 0x4c, 0x09, 0x8a, 0x11, 0x4b, 0x38, 0xa4, + 0x83, 0x3c, 0xb8, 0x81, 0x3d, 0x94, 0x83, 0x3c, 0xcc, 0x43, 0x3a, 0xbc, + 0x83, 0x3b, 0x4c, 0x09, 0x8c, 0x11, 0x54, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x01, 0x3b, 0x84, 0x83, 0x3b, 0x9c, 0x43, 0x3d, 0x84, 0xc3, 0x39, 0x94, + 0xc3, 0x2f, 0xd8, 0x43, 0x39, 0xc8, 0xc3, 0x3c, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x94, 0x00, 0x19, 0x31, 0x85, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0x8c, + 0xc3, 0x3b, 0xb4, 0x03, 0x3c, 0xa4, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x03, 0x3c, 0xd0, 0x43, 0x3a, 0xbc, 0x83, 0x3b, 0xcc, 0xc3, 0x94, 0x41, + 0x61, 0x9c, 0x11, 0x4c, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xc8, + 0x43, 0x38, 0x9c, 0x43, 0x3b, 0x94, 0x83, 0x3b, 0xd0, 0xc3, 0x94, 0xc0, + 0x0d, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x10, 0xb1, 0x5d, 0xf9, 0x73, + 0xce, 0x83, 0xfd, 0x45, 0x04, 0x18, 0x0c, 0xd1, 0x4c, 0x16, 0xb0, 0x01, + 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, + 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x0d, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb4, 0x46, 0x00, 0x28, 0xd5, 0xc0, + 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8a, 0x10, 0x44, 0x46, + 0x71, 0x0c, 0x84, 0x10, 0x58, 0x90, 0xc8, 0x27, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xc8, 0x0c, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0x2f, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x8e, 0x00, + 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, + 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, + 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, + 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, + 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, + 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, + 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, + 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, + 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, + 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, + 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, + 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, + 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, + 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, + 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, + 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, + 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, + 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, + 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, + 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, + 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, + 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, + 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, + 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, + 0x02, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x71, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x8a, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0x00, 0x09, 0xa0, 0x36, 0x20, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, + 0x03, 0x48, 0x40, 0xb5, 0xc1, 0x38, 0x02, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x22, 0x00, 0x0b, 0x50, 0x01, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, 0x88, 0x09, 0x41, 0x31, 0x61, 0x30, + 0x0e, 0x04, 0x89, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, + 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, + 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, + 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, + 0x34, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, 0x26, 0x2a, 0x22, + 0x7e, 0x7b, 0xf8, 0x81, 0x28, 0x02, 0xb0, 0x7f, 0x1a, 0x23, 0x00, 0x06, + 0x11, 0x90, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, + 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x50, 0x84, 0x82, + 0x84, 0x10, 0x44, 0x39, 0x69, 0x11, 0x2b, 0x03, 0x18, 0x83, 0xdc, 0x1c, + 0x01, 0x18, 0xcc, 0x11, 0x04, 0xc3, 0x08, 0x02, 0x54, 0x92, 0x90, 0x96, + 0x80, 0x51, 0x46, 0x40, 0xb3, 0x20, 0xe1, 0x2c, 0x11, 0x65, 0x04, 0x54, + 0x07, 0x02, 0x52, 0x00, 0x0e, 0x23, 0x0c, 0xd0, 0x20, 0x42, 0x20, 0xcc, + 0x11, 0x80, 0xc2, 0x20, 0xc2, 0x20, 0x8c, 0x00, 0x00, 0x00, 0x13, 0xa8, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, + 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, + 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, + 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, + 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, + 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, + 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x98, 0x06, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xcc, 0x03, 0x04, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x86, 0x02, 0x02, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x08, 0x63, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x90, 0x05, 0x02, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, + 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x78, 0x2c, + 0xc1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x13, 0x01, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x74, 0x5c, 0x00, 0x06, + 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x40, 0xc4, 0x25, 0x40, 0x08, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, + 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, + 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x70, 0x11, 0x43, + 0x0c, 0x88, 0x80, 0x14, 0xa8, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, + 0x04, 0xb9, 0x0e, 0x88, 0x80, 0x08, 0xa8, 0xe0, 0x16, 0x96, 0x26, 0xe7, + 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, + 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, + 0x44, 0xb8, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, + 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x6b, 0x21, + 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, + 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, + 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, + 0x95, 0x0d, 0x11, 0xae, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, + 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, + 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, + 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, + 0x43, 0x90, 0xeb, 0x81, 0x8a, 0x0b, 0xba, 0xa2, 0x21, 0xc2, 0x25, 0x91, + 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, + 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, + 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, + 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, + 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, + 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x54, 0x5c, 0xd4, 0x55, 0x5d, + 0xd6, 0x05, 0x5d, 0xd1, 0x75, 0x5d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, + 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, + 0x3a, 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, + 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, + 0x91, 0x20, 0xe2, 0xd2, 0xae, 0xed, 0xaa, 0x2e, 0xee, 0x82, 0xae, 0xe8, + 0xba, 0xae, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, + 0x19, 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, + 0x9d, 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, + 0x22, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0x24, 0xe8, + 0xb8, 0xb4, 0xeb, 0xbb, 0xaa, 0x8b, 0xbb, 0xa0, 0x0b, 0x0c, 0xae, 0xeb, + 0x0a, 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, + 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, + 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, + 0x26, 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, + 0x57, 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, + 0x6e, 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, + 0xb7, 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, + 0x84, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0x01, 0x54, 0x40, 0x06, + 0x54, 0x5c, 0x68, 0x70, 0xa5, 0x01, 0x64, 0x40, 0x06, 0x54, 0x5c, 0x68, + 0x70, 0xa9, 0x01, 0xc4, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xad, 0x01, + 0xd4, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xb1, 0x01, 0xa3, 0xb0, 0x34, + 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, + 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, + 0xca, 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x03, 0x68, + 0xb9, 0xc6, 0xe0, 0x22, 0x03, 0x28, 0xb9, 0xca, 0x00, 0x22, 0x20, 0xe2, + 0x32, 0x83, 0xeb, 0x0c, 0xae, 0x36, 0xb8, 0xdc, 0x00, 0x4a, 0xae, 0x37, + 0x80, 0x8c, 0x0b, 0xba, 0xe0, 0xe0, 0xba, 0xae, 0x38, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, + 0x4d, 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, + 0x1e, 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, + 0x1d, 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, + 0x32, 0xbc, 0xac, 0x21, 0x14, 0x84, 0x5c, 0x73, 0x70, 0x95, 0x01, 0x54, + 0x40, 0xc4, 0x45, 0x07, 0x17, 0x74, 0xd5, 0xc1, 0x75, 0x5d, 0x76, 0x40, + 0x8f, 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0xec, 0x2b, 0x4c, + 0x4e, 0x2e, 0x2c, 0x8f, 0xc7, 0x8c, 0xed, 0x2d, 0x8c, 0x8e, 0x05, 0x64, + 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, 0x05, 0x5d, 0x19, 0x5e, 0x95, + 0xd5, 0x10, 0x0a, 0x72, 0xae, 0x39, 0xb8, 0xca, 0x00, 0x22, 0x20, 0xe2, + 0xa2, 0x83, 0x0b, 0xba, 0xf0, 0xe0, 0xba, 0xae, 0x3c, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x63, 0x2e, + 0xac, 0x0d, 0x8e, 0xad, 0x4c, 0x8e, 0xc1, 0xdc, 0x10, 0x09, 0x7a, 0xae, + 0x3d, 0xb8, 0xca, 0x00, 0x2a, 0x20, 0xe2, 0x82, 0x2e, 0x3e, 0xb8, 0xae, + 0xab, 0x0f, 0x86, 0x38, 0x57, 0x76, 0x79, 0x97, 0x18, 0x5c, 0x72, 0x70, + 0xdd, 0xc1, 0xa5, 0x07, 0x97, 0x1f, 0x0c, 0x31, 0x1a, 0xe0, 0x9a, 0xae, + 0x3f, 0x18, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, + 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, + 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, + 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, + 0x0f, 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, + 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, + 0x63, 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, + 0x0e, 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, + 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, + 0x4c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, + 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, + 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, + 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, + 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x05, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x26, 0x10, 0x06, 0x00, 0x12, 0xf9, 0x12, 0xc0, 0x3c, 0x0b, + 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0xc3, 0x0f, 0x44, 0x11, + 0x80, 0xf9, 0x15, 0x5e, 0xdc, 0xb6, 0x05, 0x34, 0x00, 0x12, 0xf9, 0x83, + 0x33, 0xf9, 0xd5, 0x5d, 0xdc, 0xb6, 0x0d, 0x6c, 0x00, 0x12, 0xf9, 0x12, + 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0x83, + 0x5f, 0xe1, 0xc5, 0x6d, 0x1b, 0x00, 0xc4, 0x76, 0xe5, 0x2f, 0xbb, 0xef, + 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xb4, 0x47, 0x00, 0x28, 0xcf, 0x31, + 0x14, 0x5d, 0x37, 0xd6, 0x00, 0x04, 0x02, 0xc9, 0x11, 0x00, 0x8a, 0x23, + 0x00, 0x04, 0x67, 0x00, 0x28, 0xd6, 0x00, 0x85, 0x39, 0x08, 0x31, 0x10, + 0x03, 0x31, 0x08, 0x83, 0x19, 0x00, 0x02, 0x63, 0x04, 0x20, 0x08, 0x82, + 0xf8, 0x37, 0x03, 0x30, 0x02, 0x00, 0x23, 0x06, 0xca, 0x10, 0x84, 0xc1, + 0xd3, 0x44, 0x46, 0x82, 0x04, 0x83, 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x2c, + 0x43, 0x40, 0x06, 0xd0, 0x33, 0x85, 0x01, 0xb2, 0x28, 0xc3, 0x18, 0x42, + 0x20, 0x06, 0x73, 0x0c, 0x43, 0x40, 0x06, 0x23, 0x06, 0xcb, 0x10, 0x9c, + 0xc1, 0x24, 0x59, 0x65, 0xb0, 0x38, 0x8d, 0x31, 0x86, 0x10, 0x94, 0xc1, + 0x1c, 0xc3, 0x10, 0x90, 0xc1, 0x61, 0x7a, 0x29, 0x28, 0x83, 0x0c, 0x81, + 0x43, 0x19, 0x11, 0xc0, 0x67, 0xbc, 0x81, 0xc3, 0xd8, 0xe0, 0x02, 0xbd, + 0x14, 0x94, 0x41, 0x86, 0x60, 0xca, 0x46, 0x0c, 0x0a, 0x21, 0x98, 0x83, + 0x22, 0x18, 0x6f, 0x08, 0x83, 0xce, 0x0d, 0x2e, 0xd0, 0x4b, 0x41, 0x19, + 0x64, 0x08, 0x30, 0x6f, 0xc4, 0xa0, 0x10, 0x02, 0x3c, 0x50, 0x82, 0xf1, + 0x06, 0x33, 0x10, 0x83, 0x37, 0xb8, 0x40, 0x2f, 0x05, 0x65, 0x90, 0x21, + 0xe8, 0xc6, 0x60, 0xc4, 0xa0, 0x10, 0x82, 0x3e, 0x78, 0x82, 0x39, 0x06, + 0x30, 0x58, 0xf4, 0x60, 0x8e, 0x21, 0x38, 0xf8, 0x60, 0x8e, 0x21, 0x18, + 0xf4, 0xc0, 0x02, 0x38, 0x90, 0x4f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x5c, 0x0c, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x14, 0x03, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x1b, 0xcc, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, + 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, + 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, + 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, + 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, + 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, + 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, + 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, + 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, + 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, + 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, + 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, + 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, + 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, + 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, + 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, + 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, + 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, + 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, + 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, + 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, + 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, + 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, + 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, + 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, + 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, 0x02, 0x2c, 0x40, 0xb5, + 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, 0x61, 0x00, 0x0b, 0x50, + 0x6d, 0x30, 0x8a, 0x03, 0x58, 0x80, 0x6a, 0x83, 0x61, 0xfc, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x48, 0x00, 0xb5, 0x01, 0x39, 0xfe, 0xff, 0xff, 0xff, + 0x7f, 0x00, 0x18, 0x40, 0x02, 0xaa, 0x0d, 0x06, 0x12, 0x00, 0x0b, 0x50, + 0x6d, 0x30, 0x12, 0x01, 0x58, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, + 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x68, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, + 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, + 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, + 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, + 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, + 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, + 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, + 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, 0x00, 0x06, 0xc3, 0x08, + 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, 0x8a, 0x03, 0x01, 0x29, + 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, 0xe6, 0x08, 0x40, 0x61, + 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, + 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, + 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, + 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, + 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, + 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, + 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, + 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, + 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, + 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, + 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, + 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, + 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x43, 0x98, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x21, 0x4c, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x10, 0x46, 0x02, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x7a, 0x25, 0x30, + 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, + 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x74, 0x2c, 0xc1, 0x21, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0xc6, 0x63, 0x4c, 0x00, 0xf5, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x3c, 0xc3, 0x24, + 0x3c, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, 0x8c, 0x67, 0x78, 0x92, + 0x87, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x99, 0x8e, 0x67, + 0x78, 0x86, 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x98, 0x12, 0x72, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, + 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x69, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, + 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0xa6, + 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, + 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, + 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, + 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe9, 0x79, + 0x88, 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, 0x09, 0x4b, 0x93, 0x73, + 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, + 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, + 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, + 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, + 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, + 0xb7, 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, 0xd6, 0x04, 0x4d, 0xd1, + 0x74, 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, + 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, + 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x9e, 0x61, 0xd2, + 0xa6, 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, 0xba, 0xa6, 0x8e, 0xd9, + 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, + 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, + 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, + 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, 0x98, 0xb4, 0xe9, 0x9b, + 0xaa, 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, 0x0a, 0x03, 0x2a, 0x61, + 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, 0xbe, 0xe6, 0xd2, 0xf4, + 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, + 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0x11, 0x09, 0x4b, 0x93, + 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, 0x26, 0xe7, 0x32, 0x47, + 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x95, 0xe6, + 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, 0x6e, 0x86, 0xc6, 0x9b, + 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, 0xb7, 0x32, 0x33, 0x33, + 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, 0x84, 0xc6, 0xde, 0xca, + 0xcc, 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, + 0xa5, 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xa9, 0xc1, 0xb3, + 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, 0xc3, 0x3c, 0xc5, 0x43, + 0x4c, 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, + 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x5e, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x4c, + 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x68, 0x90, 0x95, + 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, 0x99, 0xc6, 0x60, 0x22, + 0x83, 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, 0x32, 0x83, 0xe9, 0x0c, + 0xa6, 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, 0x78, 0x8a, 0x09, 0x9a, + 0xe0, 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, 0x26, 0xe7, 0x42, 0x57, + 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0x2e, + 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, 0x1e, 0x5d, 0x9d, 0x5c, + 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, 0x1d, 0x0b, 0xc8, 0x5c, + 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, 0x32, 0xbc, 0xac, 0x21, + 0xd4, 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, 0x3c, 0xc3, 0x44, 0x07, + 0x13, 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, 0x82, 0xae, 0x0c, 0xaf, + 0xca, 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, 0x65, 0xf0, 0x0c, 0xcf, + 0x30, 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, 0x13, 0x1e, 0x70, 0x09, + 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, 0xe3, 0x31, + 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, 0x6e, 0x88, 0xf4, 0x38, + 0x93, 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, 0x41, 0xd3, 0x1e, 0x4c, + 0xd7, 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, 0x49, 0x0c, 0x26, 0x39, + 0x98, 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, 0x18, 0x0b, 0x30, 0x4d, + 0x93, 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, + 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, + 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, 0x77, + 0xa0, 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, + 0xb0, 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, 0x29, + 0x81, 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, 0x70, + 0x70, 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, 0x7b, + 0x28, 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, 0x20, + 0x23, 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, + 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, 0x7a, + 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, + 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, + 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xfc, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, + 0xce, 0xe4, 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, + 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, + 0x7e, 0x85, 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xd6, + 0xf6, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x74, 0x47, 0x00, 0xa8, 0x8e, 0x35, + 0x00, 0x03, 0x31, 0xc7, 0x40, 0x0c, 0xde, 0x1c, 0x03, 0xe1, 0x79, 0x63, + 0x0d, 0x40, 0x20, 0x90, 0xab, 0x81, 0x11, 0x00, 0x7a, 0x33, 0x00, 0x04, + 0x47, 0x00, 0x28, 0xcc, 0x41, 0x90, 0x01, 0x19, 0x90, 0x81, 0x18, 0xcc, + 0x00, 0x10, 0x18, 0x23, 0x00, 0x41, 0x10, 0xc4, 0xbf, 0x11, 0x80, 0x19, + 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x8c, 0x41, 0xf4, 0x4c, 0x89, 0x81, + 0x08, 0x83, 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x28, 0x43, 0x50, 0x06, 0x52, + 0x54, 0x2d, 0x88, 0x42, 0x0c, 0x32, 0x04, 0xc7, 0x33, 0xc8, 0x30, 0x04, + 0xd1, 0x5d, 0x76, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x12, 0x19, 0x11, 0xc0, + 0x67, 0xbc, 0x61, 0xbb, 0xd6, 0xe0, 0x02, 0xbb, 0x14, 0x94, 0x41, 0x86, + 0x00, 0xb2, 0x46, 0x0c, 0x0a, 0x21, 0x88, 0x83, 0x22, 0x18, 0x6f, 0x00, + 0x03, 0xae, 0x0d, 0x2e, 0xb0, 0x4b, 0x41, 0x19, 0x64, 0x08, 0xaa, 0x6d, + 0xc4, 0xa0, 0x10, 0x02, 0x3b, 0x50, 0x82, 0xf1, 0x86, 0x32, 0x08, 0x03, + 0x37, 0xb8, 0xc0, 0x2e, 0x05, 0x65, 0x90, 0x21, 0xd0, 0xc0, 0x60, 0xc4, + 0xa0, 0x10, 0x82, 0x3d, 0x78, 0x82, 0x39, 0x86, 0x6e, 0xc9, 0x83, 0x39, + 0x86, 0xe0, 0xd8, 0x83, 0x39, 0x86, 0x60, 0xc8, 0x03, 0x0b, 0xde, 0x40, + 0x3e, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x68, 0x0c, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0x17, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, + 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, + 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, + 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, + 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, + 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, + 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, + 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, + 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, + 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, + 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, + 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, + 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, + 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, + 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, + 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, + 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, + 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, + 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, + 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, + 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, + 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, + 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, + 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, + 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, + 0x02, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x61, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x8a, 0x03, 0x58, 0x80, 0x6a, 0x83, + 0x61, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x00, 0x48, 0x00, 0xb5, 0x01, 0x39, + 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x18, 0x40, 0x02, 0xaa, 0x0d, 0x06, + 0x12, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x12, 0x01, 0x58, 0x80, 0x0a, 0x00, + 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, + 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x68, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, + 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, + 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, + 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, + 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, + 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, + 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, + 0x00, 0x06, 0xc3, 0x08, 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, + 0x8a, 0x03, 0x01, 0x29, 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, + 0xe6, 0x08, 0x40, 0x61, 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xa8, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, + 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, + 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, + 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, + 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, + 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, + 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x98, 0x05, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4c, 0x03, 0x04, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x46, 0x02, 0x02, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x7a, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, + 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x74, 0x2c, + 0xc1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x0c, 0x01, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0xc6, 0x63, 0x4c, 0x00, 0xf5, + 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x3c, 0xc3, 0x24, 0x3c, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, + 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, + 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, + 0x8c, 0x67, 0x78, 0x92, 0x87, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, + 0x04, 0x99, 0x8e, 0x67, 0x78, 0x86, 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, + 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, + 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, + 0x44, 0x98, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, + 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x69, 0x21, + 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, + 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, + 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, + 0x95, 0x0d, 0x11, 0xa6, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, + 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, + 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, + 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, + 0x43, 0x90, 0xe9, 0x79, 0x88, 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, + 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, + 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, + 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, + 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, + 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, + 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, + 0xd6, 0x04, 0x4d, 0xd1, 0x74, 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, + 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, + 0x3a, 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, + 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, + 0x91, 0x9e, 0x61, 0xd2, 0xa6, 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, + 0xba, 0xa6, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, + 0x19, 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, + 0x9d, 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, + 0x22, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, + 0x98, 0xb4, 0xe9, 0x9b, 0xaa, 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, + 0x0a, 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, + 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, + 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, + 0x26, 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, + 0x57, 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, + 0x6e, 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, + 0xb7, 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, + 0x84, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, + 0x43, 0x4c, 0x68, 0x30, 0xa5, 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, + 0x30, 0xa9, 0xc1, 0xb3, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, + 0xc3, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, + 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, + 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, + 0xca, 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, + 0x99, 0xc6, 0x60, 0x22, 0x83, 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, + 0x32, 0x83, 0xe9, 0x0c, 0xa6, 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, + 0x78, 0x8a, 0x09, 0x9a, 0xe0, 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, + 0x4d, 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, + 0x1e, 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, + 0x1d, 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, + 0x32, 0xbc, 0xac, 0x21, 0xd4, 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, + 0x3c, 0xc3, 0x44, 0x07, 0x13, 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, + 0x82, 0xae, 0x0c, 0xaf, 0xca, 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, + 0x65, 0xf0, 0x0c, 0xcf, 0x30, 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, + 0x13, 0x1e, 0x70, 0x09, 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, + 0x2b, 0x93, 0xe3, 0x31, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, + 0x6e, 0x88, 0xf4, 0x38, 0x93, 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, + 0x41, 0xd3, 0x1e, 0x4c, 0xd7, 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, + 0x49, 0x0c, 0x26, 0x39, 0x98, 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, + 0x18, 0x0b, 0x30, 0x4d, 0x93, 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, @@ -957,885 +1750,72 @@ const unsigned char sdl_metallib[] = { 0x77, 0x80, 0x07, 0x7a, 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, - 0xc8, 0x01, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, - 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, - 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, - 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, - 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, - 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, - 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, - 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, - 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, - 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, - 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, - 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, - 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, - 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, - 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, - 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, - 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, - 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, - 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, - 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, - 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, - 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, - 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, - 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, - 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, - 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, - 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, - 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, - 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, - 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, - 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, - 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, - 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, - 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, - 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, - 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, - 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, - 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, - 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, - 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, - 0x71, 0x20, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x10, 0xb1, 0x5d, - 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x45, 0x04, 0x18, 0x0c, 0xd1, 0x4c, 0x16, - 0xb0, 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, - 0x44, 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x0d, 0x00, 0x00, - 0x61, 0x20, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, - 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xc4, 0x46, 0x00, 0x48, - 0xd5, 0xc0, 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8a, 0x10, - 0x4c, 0x46, 0x81, 0x0c, 0x84, 0x10, 0x10, 0x52, 0x2c, 0x10, 0xe4, 0x93, - 0x41, 0x40, 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xb8, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x0d, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, - 0x41, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, - 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, - 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, - 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, - 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, - 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, - 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, - 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, - 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, - 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, - 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, - 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, - 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, - 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, - 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, - 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, - 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, - 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, - 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, - 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, - 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, - 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, - 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, - 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, - 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, - 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, - 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, - 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, - 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, - 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, - 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, - 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, - 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, - 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, - 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, - 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, - 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, - 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, - 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, - 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, - 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, - 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, - 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, - 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, - 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, - 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, - 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, - 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, - 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x0c, 0x40, 0x02, 0x2c, - 0x40, 0xb5, 0x01, 0x19, 0x08, 0x20, 0x01, 0x16, 0xa0, 0xda, 0x60, 0x10, - 0x05, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, 0xa8, 0x36, 0x18, - 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, 0x1b, 0x90, 0xe3, - 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x01, 0x24, 0xa0, 0xda, 0x60, 0x20, - 0x01, 0xb0, 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, 0xa8, 0x00, 0x00, - 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, - 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, - 0x89, 0x20, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, - 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, - 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, - 0x10, 0x7c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, - 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, 0x07, 0x49, 0x53, 0x44, 0x09, 0x93, - 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, 0x40, 0x20, 0x82, 0x10, 0x42, 0x06, - 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, - 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0xa7, 0x31, 0x02, 0x60, 0x10, 0xe1, - 0x08, 0x4e, 0x93, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, - 0x22, 0xe2, 0xb7, 0x87, 0x1f, 0x88, 0x22, 0x00, 0xfb, 0xa7, 0x31, 0x02, - 0x60, 0x10, 0x21, 0x09, 0x2e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x97, - 0x00, 0xe6, 0x59, 0x88, 0xe8, 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, 0x45, - 0x28, 0x48, 0x08, 0x62, 0x18, 0xa4, 0x18, 0xb5, 0x32, 0x00, 0x42, 0xe8, - 0xcd, 0x11, 0x80, 0xc1, 0x1c, 0x41, 0x30, 0x8c, 0x20, 0x44, 0x25, 0x09, - 0x8a, 0x89, 0x28, 0xa7, 0x04, 0x44, 0x0b, 0x12, 0x10, 0x13, 0x72, 0x4a, - 0x40, 0x76, 0x20, 0x20, 0x05, 0xe2, 0x30, 0xc2, 0x10, 0x0d, 0x22, 0x04, - 0xc2, 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x10, 0xc2, 0x08, 0x00, 0x00, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x07, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x0c, 0x04, 0x04, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0xa6, 0x02, 0x02, 0x60, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x73, 0x01, 0x01, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x05, 0x02, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x8a, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, - 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, - 0x7c, 0x04, 0x80, 0xf2, 0x58, 0x82, 0x23, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x1d, 0x01, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x46, 0x74, 0x60, - 0x40, 0x16, 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x44, 0x04, 0x26, 0x44, 0x08, 0xdd, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, - 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, - 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x26, 0x65, 0x88, 0x80, 0x11, 0x43, - 0x8c, 0x88, 0x88, 0x94, 0xa8, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, - 0x04, 0xc1, 0x8e, 0x88, 0x88, 0x88, 0xa8, 0xe0, 0x16, 0x96, 0x26, 0xe7, - 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, - 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, - 0x44, 0xc0, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, - 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, - 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, 0x6c, 0x21, - 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, - 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, - 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, - 0x95, 0x0d, 0x11, 0xb0, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, - 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, - 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, - 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, - 0x43, 0x10, 0xec, 0x89, 0x0a, 0x0c, 0xc2, 0xa2, 0x21, 0x02, 0x26, 0x91, - 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, - 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, - 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, - 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, - 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, - 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x50, 0x54, 0x60, 0x14, 0x56, 0x61, - 0x16, 0x06, 0x61, 0x11, 0x76, 0x61, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, - 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, - 0x3a, 0x3a, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, - 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, - 0x32, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, - 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x68, 0x98, 0xb1, 0xbd, - 0x85, 0xd1, 0xc9, 0x10, 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, 0x7b, 0x93, 0x23, - 0x1b, 0x22, 0x45, 0x04, 0xa6, 0x61, 0x1b, 0x56, 0x61, 0x1c, 0x06, 0x61, - 0x1d, 0x76, 0x61, 0x1e, 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, - 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, - 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x94, 0xc2, 0xd2, 0xe4, 0x5c, - 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, 0xd2, 0xdc, 0xc8, - 0xca, 0xf0, 0x88, 0x84, 0xa5, 0xc9, 0xb9, 0xc8, 0x95, 0x85, 0x91, 0x31, - 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, - 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0xe3, 0x15, 0x96, 0x26, 0xe7, 0x12, 0x26, - 0x77, 0xf6, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x15, 0xc6, 0x96, 0x76, 0xe6, - 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x61, 0xec, 0x8d, 0x6d, 0x08, 0x18, - 0x44, 0x07, 0x06, 0x06, 0x58, 0x18, 0x44, 0x06, 0x26, 0x06, 0x51, 0x11, - 0x11, 0xd8, 0x18, 0x60, 0x64, 0x10, 0x19, 0x58, 0x19, 0x44, 0x06, 0x06, - 0x61, 0x11, 0x76, 0x61, 0x66, 0x40, 0x2a, 0x2c, 0x4d, 0xce, 0x65, 0x8e, - 0x4e, 0xae, 0x6e, 0x8c, 0xee, 0x8b, 0x2e, 0x0f, 0xae, 0xec, 0x2b, 0xcd, - 0xcd, 0xec, 0x8d, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0x0c, 0x8d, 0x37, - 0x33, 0xb3, 0xb9, 0x32, 0x3a, 0x1a, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, - 0x34, 0x8e, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x68, 0x08, 0x8d, 0xbd, 0x95, - 0x99, 0x99, 0x0d, 0x41, 0x83, 0xa8, 0x88, 0x8c, 0xa8, 0xc0, 0xd2, 0x00, - 0x53, 0x83, 0xc8, 0x88, 0x8c, 0xa8, 0xc0, 0xd2, 0x00, 0x5b, 0x83, 0x88, - 0x89, 0x8c, 0xa8, 0xc0, 0xd2, 0x00, 0x63, 0x83, 0xa8, 0x89, 0x8c, 0xa8, - 0xc0, 0xd2, 0x00, 0x6b, 0x03, 0x26, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, - 0x6f, 0x64, 0x65, 0x34, 0xc8, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x86, 0x90, - 0x41, 0xb4, 0x60, 0x60, 0x80, 0x85, 0x41, 0x94, 0x60, 0x62, 0x10, 0x11, - 0x11, 0x81, 0x8d, 0x01, 0x86, 0x06, 0x98, 0x1b, 0x60, 0x64, 0x10, 0x25, - 0x58, 0x19, 0x44, 0x06, 0x06, 0x61, 0x6f, 0x80, 0x5d, 0x18, 0x1c, 0x70, - 0x09, 0x4b, 0x93, 0x73, 0xa1, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, 0xa3, - 0x12, 0x96, 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x46, 0x8c, - 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0x8c, 0xc7, 0x8c, 0xed, - 0x2d, 0x8c, 0x8e, 0x05, 0x64, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, - 0x04, 0x5d, 0x19, 0x5e, 0xd6, 0x10, 0x2a, 0x42, 0x30, 0x39, 0xc0, 0xc4, - 0x20, 0x2a, 0x22, 0x02, 0x9b, 0x03, 0x0c, 0xc2, 0xe8, 0x00, 0xbb, 0xb0, - 0x3a, 0xa0, 0x47, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x26, 0x43, 0xf6, - 0x15, 0x26, 0x27, 0x17, 0x96, 0xc7, 0x63, 0xc6, 0xf6, 0x16, 0x46, 0xc7, - 0x02, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0xe6, 0xc3, 0x82, 0xae, 0x0c, - 0xaf, 0xca, 0x6a, 0x08, 0x15, 0x39, 0x98, 0x1c, 0x60, 0x62, 0x10, 0x11, - 0x11, 0x81, 0xcd, 0x01, 0x06, 0x61, 0x77, 0x80, 0x5d, 0x18, 0x1e, 0x70, - 0x09, 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, 0xe3, - 0x31, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, 0x6e, 0x88, 0x14, - 0x3d, 0x98, 0x1e, 0x60, 0x62, 0x10, 0x15, 0x11, 0x81, 0x41, 0xd8, 0x1e, - 0x60, 0x17, 0xc6, 0x07, 0x43, 0x1c, 0x2c, 0xc3, 0x3e, 0xec, 0x0c, 0xb0, - 0x38, 0xc0, 0xec, 0x00, 0xcb, 0x03, 0xac, 0x0f, 0x86, 0x18, 0x0e, 0x80, - 0x4d, 0x98, 0x1f, 0xf0, 0x79, 0x6b, 0x73, 0x4b, 0x83, 0x7b, 0xa3, 0x2b, - 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, 0x93, 0xe3, 0x33, 0x95, 0xd6, 0x06, - 0xc7, 0x56, 0x06, 0x32, 0xb4, 0xb2, 0x02, 0x42, 0x25, 0x14, 0x14, 0x34, - 0x44, 0xc0, 0x42, 0x61, 0x88, 0x81, 0x81, 0x02, 0x26, 0x0a, 0x1c, 0x34, - 0xc4, 0xc0, 0x46, 0x01, 0x1b, 0x05, 0x0e, 0x1a, 0x11, 0xb1, 0x03, 0x3b, - 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, - 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, - 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, 0x90, - 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, 0x53, 0x82, 0x62, 0xc4, 0x12, - 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, - 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, 0x04, 0x15, 0x0e, 0xe9, 0x20, - 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, 0xe7, 0x50, 0x0f, 0xe1, 0x70, - 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, - 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, - 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, - 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, - 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, - 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, - 0x25, 0xf8, 0x03, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, - 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, - 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, - 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, - 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, - 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, - 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, - 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, - 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, - 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, - 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, - 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, - 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, - 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, - 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, - 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, - 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, - 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, - 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, - 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, - 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, - 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, - 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, - 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, - 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, - 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, - 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, - 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, - 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, - 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, - 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, - 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, - 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, - 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, - 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, - 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, - 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, - 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, - 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, - 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, - 0x71, 0x20, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x26, 0x10, 0x06, 0x00, - 0x12, 0xf9, 0x12, 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, - 0xf1, 0xdb, 0xc3, 0x0f, 0x44, 0x11, 0x80, 0xf9, 0x15, 0x5e, 0xdc, 0xb6, - 0x05, 0x34, 0x00, 0x12, 0xf9, 0x83, 0x33, 0xf9, 0xd5, 0x5d, 0xdc, 0xb6, - 0x0d, 0x6c, 0x00, 0x12, 0xf9, 0x12, 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, - 0x35, 0x51, 0x11, 0xf1, 0xdb, 0x83, 0x5f, 0xe1, 0xc5, 0x6d, 0x1b, 0x00, - 0xc4, 0x76, 0xe5, 0x2f, 0xbb, 0xef, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, - 0x04, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, - 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0xa4, 0xe7, 0x18, 0x0a, 0xcf, 0x1b, 0x6b, 0x00, 0x02, 0x81, 0xe6, 0x08, - 0x00, 0xc9, 0x11, 0x80, 0x1a, 0xa0, 0x38, 0x03, 0x40, 0x61, 0x0e, 0x42, - 0x0c, 0xc4, 0x40, 0x0c, 0xc2, 0x60, 0x06, 0x80, 0xc0, 0x18, 0x01, 0x08, - 0x82, 0x20, 0xfe, 0xcd, 0x00, 0x8c, 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, - 0x84, 0x81, 0xc3, 0x44, 0x47, 0x82, 0x04, 0x83, 0x0c, 0x41, 0xc1, 0x8c, - 0x18, 0x2c, 0x43, 0x40, 0x06, 0x8f, 0x33, 0x85, 0x41, 0xb2, 0x28, 0xc3, - 0x18, 0x42, 0x20, 0x06, 0x73, 0x0c, 0x43, 0x40, 0x06, 0x23, 0x06, 0xcb, - 0x10, 0x9c, 0x81, 0x14, 0x59, 0x65, 0xc0, 0x38, 0x8d, 0x31, 0x86, 0x10, - 0x94, 0xc1, 0x1c, 0xc3, 0x10, 0x90, 0xc1, 0x5d, 0x7b, 0x29, 0x28, 0x83, - 0x0c, 0x81, 0x43, 0x19, 0x11, 0xc0, 0x87, 0xb8, 0x32, 0xde, 0xc0, 0x85, - 0x41, 0x1b, 0x5c, 0xb0, 0x97, 0x82, 0x32, 0xc8, 0x10, 0x50, 0xda, 0x88, - 0x41, 0x21, 0x04, 0x74, 0x60, 0x04, 0xe3, 0x0d, 0x61, 0x60, 0x06, 0x6f, - 0x70, 0xc1, 0x5e, 0x0a, 0xca, 0x20, 0x43, 0x90, 0x7d, 0x23, 0x06, 0x85, - 0x10, 0xe4, 0xc1, 0x12, 0x8c, 0x37, 0x98, 0xc1, 0x1a, 0xc0, 0xc1, 0x05, - 0x7b, 0x29, 0x28, 0x83, 0x0c, 0x81, 0x47, 0x06, 0x23, 0x06, 0x85, 0x10, - 0xf8, 0x01, 0x14, 0xcc, 0x31, 0x84, 0xc1, 0xb2, 0x07, 0x73, 0x0c, 0xc1, - 0xd1, 0x07, 0x73, 0x0c, 0xc1, 0xb0, 0x07, 0x16, 0x4c, 0xf2, 0xc9, 0x20, - 0x20, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x06, 0x26, 0x20, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xa4, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, - 0x21, 0x0c, 0x00, 0x00, 0x26, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, - 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, - 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, - 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, - 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, - 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, - 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, - 0x92, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, - 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, - 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, - 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, - 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, - 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, - 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, - 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, - 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, - 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, - 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, - 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, - 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, - 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, - 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, - 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, - 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, - 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, - 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, - 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, - 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, - 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, - 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, - 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, - 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, - 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, - 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, - 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, - 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, - 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, - 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, - 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, - 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, - 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, - 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, - 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, - 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, - 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, - 0x0c, 0x40, 0x02, 0x2c, 0x40, 0xb5, 0x01, 0x19, 0x08, 0x20, 0x01, 0x16, - 0xa0, 0xda, 0x60, 0x10, 0x05, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x30, 0x80, - 0x05, 0xa8, 0x36, 0x18, 0xc6, 0x01, 0x2c, 0x40, 0xb5, 0xc1, 0x38, 0xfe, - 0xff, 0xff, 0xff, 0x7f, 0x00, 0x24, 0x80, 0xda, 0x80, 0x20, 0xff, 0xff, - 0xff, 0xff, 0x3f, 0x00, 0x0c, 0x20, 0x01, 0xd5, 0x06, 0x23, 0x09, 0x80, - 0x05, 0xa8, 0x36, 0x18, 0x8a, 0x00, 0x2c, 0x40, 0x05, 0x00, 0x00, 0x00, - 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8c, 0x40, 0x18, - 0x88, 0xc2, 0x98, 0x10, 0x1c, 0x13, 0x06, 0x24, 0x51, 0x00, 0x00, 0x00, - 0x89, 0x20, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, - 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, - 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, - 0x10, 0x6c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, - 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, 0x07, 0x49, 0x53, 0x44, 0x09, 0x93, - 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, 0x40, 0x20, 0x82, 0x10, 0x42, 0x06, - 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, - 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0xa7, 0x31, 0x02, 0x60, 0x10, 0xe1, - 0x08, 0x2e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x97, 0x00, 0xe6, 0x59, - 0x88, 0xe8, 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, 0x44, 0x28, 0x48, 0x08, - 0x62, 0x18, 0x84, 0x14, 0xad, 0x32, 0x00, 0x42, 0xa8, 0xcd, 0x11, 0x04, - 0x73, 0x04, 0x60, 0x30, 0x8c, 0x20, 0x40, 0x05, 0x09, 0x48, 0x89, 0x17, - 0x1f, 0x20, 0x39, 0x10, 0x90, 0x02, 0x70, 0x18, 0x61, 0x80, 0x06, 0x11, - 0x02, 0x61, 0x8e, 0x00, 0x14, 0x06, 0x11, 0x08, 0x61, 0x04, 0x00, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x06, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x8c, 0x03, 0x04, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x66, 0x02, 0x02, 0x60, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, - 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, - 0x78, 0x04, 0x80, 0xea, 0x58, 0x82, 0x23, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x16, 0x01, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x64, 0x50, - 0x40, 0x05, 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x40, 0x03, 0x25, 0x40, 0x07, 0xdd, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, - 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, - 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x26, 0x65, 0x88, 0x40, 0x11, 0x43, - 0x0c, 0x68, 0x80, 0x12, 0x88, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, - 0x04, 0xa1, 0x0e, 0x68, 0x80, 0x06, 0x88, 0xe0, 0x16, 0x96, 0x26, 0xe7, - 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, - 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, - 0x44, 0xa0, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, - 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, - 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, 0x6a, 0x21, - 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, - 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, - 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, - 0x95, 0x0d, 0x11, 0xa8, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, - 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, - 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, - 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, - 0x43, 0x10, 0xea, 0x81, 0x08, 0x0a, 0xa2, 0xa2, 0x21, 0x02, 0x25, 0x91, - 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, - 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, - 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, - 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, - 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, - 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x44, 0x50, 0x14, 0x55, 0x51, - 0x16, 0x05, 0x51, 0x11, 0x75, 0x51, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, - 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, - 0x3a, 0x3a, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, - 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, - 0x32, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, - 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x68, 0x98, 0xb1, 0xbd, - 0x85, 0xd1, 0xc9, 0x10, 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, 0x7b, 0x93, 0x23, - 0x1b, 0x22, 0x41, 0x03, 0xa5, 0x51, 0x1b, 0x55, 0x51, 0x1c, 0x05, 0x51, - 0x1d, 0x75, 0x51, 0x1e, 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, - 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, - 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x94, 0xc2, 0xd2, 0xe4, 0x5c, - 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, 0xd2, 0xdc, 0xc8, - 0xca, 0xf0, 0x88, 0x84, 0xa5, 0xc9, 0xb9, 0xc8, 0x95, 0x85, 0x91, 0x31, - 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, - 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0xe3, 0x15, 0x96, 0x26, 0xe7, 0x12, 0x26, - 0x77, 0xf6, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x15, 0xc6, 0x96, 0x76, 0xe6, - 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x61, 0xec, 0x8d, 0x6d, 0x08, 0x18, - 0x40, 0x06, 0x05, 0x06, 0x54, 0x18, 0x40, 0x05, 0x25, 0x06, 0x10, 0x01, - 0x0d, 0xd4, 0x18, 0x50, 0x64, 0x00, 0x15, 0x54, 0x19, 0x40, 0x05, 0x05, - 0x51, 0x11, 0x75, 0x51, 0x66, 0x40, 0x2a, 0x2c, 0x4d, 0xce, 0x65, 0x8e, - 0x4e, 0xae, 0x6e, 0x8c, 0xee, 0x8b, 0x2e, 0x0f, 0xae, 0xec, 0x2b, 0xcd, - 0xcd, 0xec, 0x8d, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0x0c, 0x8d, 0x37, - 0x33, 0xb3, 0xb9, 0x32, 0x3a, 0x1a, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, - 0x34, 0x8e, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x68, 0x08, 0x8d, 0xbd, 0x95, - 0x99, 0x99, 0x0d, 0x41, 0x03, 0x88, 0x80, 0x0a, 0x88, 0xa0, 0xd2, 0x80, - 0x52, 0x03, 0xa8, 0x80, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x5a, 0x03, 0x68, - 0x81, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x62, 0x03, 0x88, 0x81, 0x0a, 0x88, - 0xa0, 0xd2, 0x80, 0x6a, 0x03, 0x26, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, - 0x6f, 0x64, 0x65, 0x34, 0xc8, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x86, 0x90, - 0x01, 0xa4, 0x50, 0x60, 0x40, 0x85, 0x01, 0x84, 0x50, 0x62, 0x00, 0x0d, - 0xd0, 0x40, 0x8d, 0x01, 0x85, 0x06, 0x94, 0x1b, 0x50, 0x64, 0x00, 0x21, - 0x54, 0x19, 0x40, 0x05, 0x05, 0x51, 0x6f, 0x40, 0x5d, 0x14, 0x1c, 0x70, - 0x09, 0x4b, 0x93, 0x73, 0xa1, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, 0xa3, - 0x12, 0x96, 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x46, 0x8c, - 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0x8c, 0xc7, 0x8c, 0xed, - 0x2d, 0x8c, 0x8e, 0x05, 0x64, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, - 0x04, 0x5d, 0x19, 0x5e, 0xd6, 0x10, 0x0a, 0x3a, 0x28, 0x39, 0xa0, 0xc4, - 0x00, 0x22, 0xa0, 0x81, 0x9a, 0x03, 0x0a, 0xa2, 0xe8, 0x80, 0xba, 0xa8, - 0x3a, 0x60, 0x41, 0x57, 0x86, 0x57, 0x65, 0x35, 0x84, 0x82, 0x1a, 0x4a, - 0x0e, 0x28, 0x31, 0x80, 0x06, 0x68, 0xa0, 0xe6, 0x80, 0x82, 0x28, 0x3a, - 0xa0, 0x2e, 0xea, 0x0e, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, 0xb5, - 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, - 0x63, 0x30, 0x37, 0x44, 0x82, 0x1c, 0x2a, 0x0f, 0x28, 0x31, 0x80, 0x08, - 0x68, 0xa0, 0x20, 0x4a, 0x0f, 0xa8, 0x8b, 0xda, 0x83, 0x21, 0x0e, 0x95, - 0x51, 0x1f, 0x75, 0x06, 0x54, 0x1c, 0x50, 0x76, 0x40, 0xe1, 0x01, 0xc5, - 0x07, 0x43, 0x0c, 0x06, 0xa0, 0x26, 0xaa, 0x0f, 0xf8, 0xbc, 0xb5, 0xb9, - 0xa5, 0xc1, 0xbd, 0xd1, 0x95, 0xb9, 0xd1, 0x81, 0x8c, 0xa1, 0x85, 0xc9, - 0xf1, 0x99, 0x4a, 0x6b, 0x83, 0x63, 0x2b, 0x03, 0x19, 0x5a, 0x59, 0x01, - 0xa1, 0x12, 0x0a, 0x0a, 0x1a, 0x22, 0x50, 0xa0, 0x30, 0xc4, 0xa0, 0xfe, - 0x80, 0x0a, 0x05, 0xec, 0x19, 0x62, 0x50, 0xa2, 0x40, 0x89, 0x02, 0xf6, - 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, 0x1d, 0xde, - 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, 0x1d, 0xc2, - 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, 0x60, 0x07, - 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, 0x77, 0xa0, 0x87, - 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0xb0, 0x87, - 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, 0x29, 0x81, 0x31, - 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, 0x70, 0x70, 0x87, - 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, 0x7b, 0x28, 0x07, - 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, 0x20, 0x23, 0xa6, - 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, 0x80, 0x87, - 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, 0x7a, 0x48, 0x87, - 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, 0x09, 0x87, - 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, 0x68, 0x87, - 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, - 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, - 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, - 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, - 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, - 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, - 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, - 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, - 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, - 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, - 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, - 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, - 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, - 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, - 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, - 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, - 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, - 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, - 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, - 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, - 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, - 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, - 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, - 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, - 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, - 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, - 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, - 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, - 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, - 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, - 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, - 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, - 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, - 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, - 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, - 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, - 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, - 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, - 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, - 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, - 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, - 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, - 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, - 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, - 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xd6, 0xf6, 0x5f, - 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x64, 0xc7, 0x1a, 0x80, 0x81, 0x98, 0x63, 0x20, - 0x86, 0x6f, 0x8e, 0x81, 0xf8, 0xbe, 0xb1, 0x06, 0x20, 0x10, 0x28, 0x8e, - 0x00, 0xd0, 0xab, 0x81, 0x11, 0x00, 0x82, 0x33, 0x00, 0x14, 0xe6, 0x20, - 0xc8, 0x80, 0x0c, 0xc8, 0x40, 0x0c, 0x66, 0x00, 0x08, 0x8c, 0x11, 0x80, - 0x20, 0x08, 0xe2, 0xdf, 0x08, 0xc0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x23, 0x06, 0xca, 0x10, 0x8c, 0x01, 0xe4, 0x4c, 0x48, 0x72, 0x08, 0x83, - 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x28, 0x43, 0x50, 0x06, 0x11, 0x54, 0x29, - 0x4b, 0x42, 0x0c, 0x32, 0x04, 0xc7, 0x33, 0xc8, 0x30, 0x04, 0xd1, 0x59, - 0x77, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x12, 0x19, 0x11, 0xc0, 0x87, 0xb6, - 0x32, 0xde, 0xb0, 0x81, 0x01, 0x1b, 0x5c, 0x70, 0x97, 0x82, 0x32, 0xc8, - 0x10, 0x44, 0xd7, 0x88, 0x41, 0x21, 0x04, 0x72, 0x60, 0x04, 0xe3, 0x0d, - 0x60, 0x50, 0x06, 0x6e, 0x70, 0xc1, 0x5d, 0x0a, 0xca, 0x20, 0x43, 0x60, - 0x71, 0x23, 0x06, 0x85, 0x10, 0xdc, 0xc1, 0x12, 0x8c, 0x37, 0x94, 0x81, - 0x1a, 0xbc, 0xc1, 0x05, 0x77, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x16, 0x06, - 0x23, 0x06, 0x85, 0x10, 0xf0, 0x01, 0x14, 0xcc, 0x31, 0x78, 0x8b, 0x1e, - 0xcc, 0x31, 0x04, 0x07, 0x1f, 0xcc, 0x31, 0x04, 0x83, 0x1e, 0x58, 0x30, - 0xc9, 0x27, 0x83, 0x80, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x5b, 0x86, 0x24, 0x18, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xb0, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, - 0x21, 0x0c, 0x00, 0x00, 0x29, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, - 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, - 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, - 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, - 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, - 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, - 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, - 0x92, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, - 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, - 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, - 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, - 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, - 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, - 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, - 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, - 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, - 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, - 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, - 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, - 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, - 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, - 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, - 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, - 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, - 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, - 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, - 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, - 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, - 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, - 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, - 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, - 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, - 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, - 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, - 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, - 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, - 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, - 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, - 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, - 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, - 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, - 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, - 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, - 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, - 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, - 0x0c, 0x40, 0x02, 0x2c, 0x40, 0xb5, 0x01, 0x19, 0x08, 0x20, 0x01, 0x16, - 0xa0, 0xda, 0x60, 0x10, 0x05, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x30, 0x80, - 0x05, 0xa8, 0x36, 0x18, 0xc6, 0x01, 0x2c, 0x40, 0xb5, 0xc1, 0x38, 0xfe, - 0xff, 0xff, 0xff, 0x7f, 0x00, 0x24, 0x80, 0xda, 0x80, 0x20, 0xff, 0xff, - 0xff, 0xff, 0x3f, 0x00, 0x0c, 0x20, 0x01, 0xd5, 0x06, 0x23, 0x09, 0x80, - 0x05, 0xa8, 0x36, 0x18, 0x8a, 0x00, 0x2c, 0x40, 0x05, 0x00, 0x00, 0x00, - 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8c, 0x40, 0x18, - 0x88, 0xc2, 0x98, 0x10, 0x1c, 0x13, 0x06, 0x24, 0x51, 0x00, 0x00, 0x00, - 0x89, 0x20, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, - 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, - 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, - 0x10, 0x6c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, - 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, 0x07, 0x49, 0x53, 0x44, 0x09, 0x93, - 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, 0x40, 0x20, 0x82, 0x10, 0x42, 0x06, - 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, - 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0xa7, 0x31, 0x02, 0x60, 0x10, 0xe1, - 0x08, 0x2e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x97, 0x00, 0xe6, 0x59, - 0x88, 0xe8, 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, 0x44, 0x28, 0x48, 0x08, - 0x62, 0x18, 0x84, 0x14, 0xad, 0x32, 0x00, 0x42, 0xa8, 0xcd, 0x11, 0x04, - 0x73, 0x04, 0x60, 0x30, 0x8c, 0x20, 0x40, 0x05, 0x09, 0x48, 0x89, 0x17, - 0x1f, 0x20, 0x39, 0x10, 0x90, 0x02, 0x70, 0x18, 0x61, 0x80, 0x06, 0x11, - 0x02, 0x61, 0x8e, 0x00, 0x14, 0x06, 0x11, 0x08, 0x61, 0x04, 0x00, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x06, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x8c, 0x03, 0x04, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x66, 0x02, 0x02, 0x60, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, - 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, - 0x78, 0x04, 0x80, 0xea, 0x58, 0x82, 0x23, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x16, 0x01, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x64, 0x50, - 0x40, 0x05, 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x40, 0x03, 0x25, 0x40, 0x07, 0xdd, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, - 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, - 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x26, 0x65, 0x88, 0x40, 0x11, 0x43, - 0x0c, 0x68, 0x80, 0x12, 0x88, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, - 0x04, 0xa1, 0x0e, 0x68, 0x80, 0x06, 0x88, 0xe0, 0x16, 0x96, 0x26, 0xe7, - 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, - 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, - 0x44, 0xa0, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, - 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, - 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, 0x6a, 0x21, - 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, - 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, - 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, - 0x95, 0x0d, 0x11, 0xa8, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, - 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, - 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, - 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, - 0x43, 0x10, 0xea, 0x81, 0x08, 0x0a, 0xa2, 0xa2, 0x21, 0x02, 0x25, 0x91, - 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, - 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, - 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, - 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, - 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, - 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x44, 0x50, 0x14, 0x55, 0x51, - 0x16, 0x05, 0x51, 0x11, 0x75, 0x51, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, - 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, - 0x3a, 0x3a, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, - 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, - 0x32, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, - 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x68, 0x98, 0xb1, 0xbd, - 0x85, 0xd1, 0xc9, 0x10, 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, 0x7b, 0x93, 0x23, - 0x1b, 0x22, 0x41, 0x03, 0xa5, 0x51, 0x1b, 0x55, 0x51, 0x1c, 0x05, 0x51, - 0x1d, 0x75, 0x51, 0x1e, 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, - 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, - 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x94, 0xc2, 0xd2, 0xe4, 0x5c, - 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, 0xd2, 0xdc, 0xc8, - 0xca, 0xf0, 0x88, 0x84, 0xa5, 0xc9, 0xb9, 0xc8, 0x95, 0x85, 0x91, 0x31, - 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, - 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0xe3, 0x15, 0x96, 0x26, 0xe7, 0x12, 0x26, - 0x77, 0xf6, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x15, 0xc6, 0x96, 0x76, 0xe6, - 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x61, 0xec, 0x8d, 0x6d, 0x08, 0x18, - 0x40, 0x06, 0x05, 0x06, 0x54, 0x18, 0x40, 0x05, 0x25, 0x06, 0x10, 0x01, - 0x0d, 0xd4, 0x18, 0x50, 0x64, 0x00, 0x15, 0x54, 0x19, 0x40, 0x05, 0x05, - 0x51, 0x11, 0x75, 0x51, 0x66, 0x40, 0x2a, 0x2c, 0x4d, 0xce, 0x65, 0x8e, - 0x4e, 0xae, 0x6e, 0x8c, 0xee, 0x8b, 0x2e, 0x0f, 0xae, 0xec, 0x2b, 0xcd, - 0xcd, 0xec, 0x8d, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0x0c, 0x8d, 0x37, - 0x33, 0xb3, 0xb9, 0x32, 0x3a, 0x1a, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, - 0x34, 0x8e, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x68, 0x08, 0x8d, 0xbd, 0x95, - 0x99, 0x99, 0x0d, 0x41, 0x03, 0x88, 0x80, 0x0a, 0x88, 0xa0, 0xd2, 0x80, - 0x52, 0x03, 0xa8, 0x80, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x5a, 0x03, 0x68, - 0x81, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x62, 0x03, 0x88, 0x81, 0x0a, 0x88, - 0xa0, 0xd2, 0x80, 0x6a, 0x03, 0x26, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, - 0x6f, 0x64, 0x65, 0x34, 0xc8, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x86, 0x90, - 0x01, 0xa4, 0x50, 0x60, 0x40, 0x85, 0x01, 0x84, 0x50, 0x62, 0x00, 0x0d, - 0xd0, 0x40, 0x8d, 0x01, 0x85, 0x06, 0x94, 0x1b, 0x50, 0x64, 0x00, 0x21, - 0x54, 0x19, 0x40, 0x05, 0x05, 0x51, 0x6f, 0x40, 0x5d, 0x14, 0x1c, 0x70, - 0x09, 0x4b, 0x93, 0x73, 0xa1, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, 0xa3, - 0x12, 0x96, 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x46, 0x8c, - 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0x8c, 0xc7, 0x8c, 0xed, - 0x2d, 0x8c, 0x8e, 0x05, 0x64, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, - 0x04, 0x5d, 0x19, 0x5e, 0xd6, 0x10, 0x0a, 0x3a, 0x28, 0x39, 0xa0, 0xc4, - 0x00, 0x22, 0xa0, 0x81, 0x9a, 0x03, 0x0a, 0xa2, 0xe8, 0x80, 0xba, 0xa8, - 0x3a, 0x60, 0x41, 0x57, 0x86, 0x57, 0x65, 0x35, 0x84, 0x82, 0x1a, 0x4a, - 0x0e, 0x28, 0x31, 0x80, 0x06, 0x68, 0xa0, 0xe6, 0x80, 0x82, 0x28, 0x3a, - 0xa0, 0x2e, 0xea, 0x0e, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, 0xb5, - 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, - 0x63, 0x30, 0x37, 0x44, 0x82, 0x1c, 0x2a, 0x0f, 0x28, 0x31, 0x80, 0x08, - 0x68, 0xa0, 0x20, 0x4a, 0x0f, 0xa8, 0x8b, 0xda, 0x83, 0x21, 0x0e, 0x95, - 0x51, 0x1f, 0x75, 0x06, 0x54, 0x1c, 0x50, 0x76, 0x40, 0xe1, 0x01, 0xc5, - 0x07, 0x43, 0x0c, 0x06, 0xa0, 0x26, 0xaa, 0x0f, 0xf8, 0xbc, 0xb5, 0xb9, - 0xa5, 0xc1, 0xbd, 0xd1, 0x95, 0xb9, 0xd1, 0x81, 0x8c, 0xa1, 0x85, 0xc9, - 0xf1, 0x99, 0x4a, 0x6b, 0x83, 0x63, 0x2b, 0x03, 0x19, 0x5a, 0x59, 0x01, - 0xa1, 0x12, 0x0a, 0x0a, 0x1a, 0x22, 0x50, 0xa0, 0x30, 0xc4, 0xa0, 0xfe, - 0x80, 0x0a, 0x05, 0xec, 0x19, 0x62, 0x50, 0xa2, 0x40, 0x89, 0x02, 0xf6, - 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, 0x1d, 0xde, - 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, 0x1d, 0xc2, - 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, 0x60, 0x07, - 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, 0x77, 0xa0, 0x87, - 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0xb0, 0x87, - 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, 0x29, 0x81, 0x31, - 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, 0x70, 0x70, 0x87, - 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, 0x7b, 0x28, 0x07, - 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, 0x20, 0x23, 0xa6, - 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, 0x80, 0x87, - 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, 0x7a, 0x48, 0x87, - 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, 0x09, 0x87, - 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, 0x68, 0x87, - 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, - 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, - 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, - 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, - 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, - 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, - 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, - 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, - 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, - 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, - 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, - 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, - 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, - 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, - 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, - 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, - 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, - 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, - 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, - 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, - 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, - 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, - 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, - 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, - 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, - 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, - 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, - 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, - 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, - 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, - 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, - 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, - 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, - 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, - 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, - 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, - 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, - 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, - 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, - 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, - 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, - 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, - 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, - 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, - 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xda, 0xf5, 0x5f, - 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, - 0x3b, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x64, 0xc7, 0x1a, 0x80, 0x81, 0x98, 0x63, 0x20, - 0x06, 0x30, 0x98, 0x63, 0x20, 0xc0, 0x00, 0x0c, 0xc6, 0x1a, 0x80, 0x40, - 0xa0, 0x38, 0x96, 0x10, 0x00, 0x23, 0x00, 0xf4, 0x6a, 0x60, 0x04, 0x80, - 0xe0, 0x0c, 0x00, 0x89, 0x19, 0x00, 0x0a, 0x73, 0x10, 0x66, 0x60, 0x06, - 0x66, 0x40, 0x06, 0x33, 0x00, 0x04, 0xc6, 0x08, 0x40, 0x10, 0x04, 0xf1, - 0x6f, 0x04, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, - 0x94, 0x81, 0x04, 0x55, 0x89, 0x82, 0x08, 0x83, 0x0c, 0x41, 0xe1, 0x8c, - 0x18, 0x28, 0x43, 0x70, 0x06, 0x93, 0x74, 0x2d, 0x8c, 0x42, 0x0c, 0x32, - 0x04, 0x87, 0x33, 0xc8, 0x10, 0x28, 0xd2, 0x20, 0x03, 0x11, 0x50, 0x97, - 0xdd, 0xa5, 0xa0, 0x0c, 0x32, 0x04, 0x0c, 0x65, 0x44, 0x00, 0x1f, 0xf2, - 0xca, 0x78, 0x83, 0x37, 0x06, 0x6f, 0x70, 0xc1, 0x5d, 0x0a, 0xca, 0x20, - 0x43, 0x20, 0x69, 0x23, 0x06, 0x85, 0x10, 0xd4, 0x81, 0x11, 0x8c, 0x37, - 0x8c, 0x01, 0x1a, 0xc4, 0xc1, 0x05, 0x77, 0x29, 0x28, 0x83, 0x0c, 0xc1, - 0xf5, 0x8d, 0x18, 0x14, 0x42, 0xa0, 0x07, 0x4b, 0x30, 0xde, 0x80, 0x06, - 0x6d, 0x20, 0x07, 0x17, 0xdc, 0xa5, 0xa0, 0x0c, 0x32, 0x04, 0x1c, 0x19, - 0x8c, 0x18, 0x14, 0x42, 0xf0, 0x07, 0x50, 0x30, 0xc7, 0xf0, 0x2d, 0x7d, - 0x30, 0xc7, 0x10, 0x1c, 0x7f, 0x30, 0xc7, 0x10, 0x0c, 0x7d, 0x60, 0xc1, - 0x24, 0x9f, 0x0c, 0x02, 0x62, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x5b, 0x06, 0x25, 0x18, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, + 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, + 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, + 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, + 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, + 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, + 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, + 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, + 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, + 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, + 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, + 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, + 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, + 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, + 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, + 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, + 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, + 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, + 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, + 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, + 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, + 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, + 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, + 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, + 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, + 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, + 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, + 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, + 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, + 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, + 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, + 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, + 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, + 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, + 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, + 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, + 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, + 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, + 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, + 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, + 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, + 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, + 0x95, 0xff, 0xf9, 0xda, 0xf5, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, + 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x13, 0x04, + 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x74, 0x47, + 0x00, 0xa8, 0x8e, 0x35, 0x00, 0x03, 0x31, 0xc7, 0x40, 0x0c, 0xdf, 0x1c, + 0x03, 0xf1, 0x7d, 0x63, 0x0d, 0x40, 0x20, 0x10, 0x1c, 0x4b, 0x08, 0x00, + 0x72, 0x35, 0x30, 0x02, 0x40, 0x6f, 0x06, 0x80, 0xe0, 0x08, 0x00, 0x89, + 0x19, 0x00, 0x0a, 0x73, 0x10, 0x66, 0x60, 0x06, 0x66, 0x40, 0x06, 0x33, + 0x00, 0x04, 0xc6, 0x08, 0x40, 0x10, 0x04, 0xf1, 0x6f, 0x04, 0x60, 0x06, + 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x94, 0xc1, 0x14, 0x55, 0xca, 0x91, + 0x08, 0x83, 0x0c, 0x41, 0xe1, 0x8c, 0x18, 0x28, 0x43, 0x70, 0x06, 0xd4, + 0x74, 0x31, 0xc9, 0x42, 0x0c, 0x32, 0x04, 0x87, 0x33, 0xc8, 0x10, 0x28, + 0xd2, 0x20, 0x03, 0x11, 0x50, 0xa7, 0xd9, 0xa5, 0xa0, 0x0c, 0x32, 0x04, + 0x0c, 0x65, 0x44, 0x00, 0x9f, 0xf1, 0x06, 0x4f, 0x73, 0x83, 0x0b, 0xec, + 0x52, 0x50, 0x06, 0x19, 0x82, 0x28, 0x1b, 0x31, 0x28, 0x84, 0x80, 0x0e, + 0x8a, 0x60, 0xbc, 0x61, 0x0c, 0x3e, 0x38, 0xb8, 0xc0, 0x2e, 0x05, 0x65, + 0x90, 0x21, 0xb0, 0xbc, 0x11, 0x83, 0x42, 0x08, 0xf2, 0x40, 0x09, 0xc6, + 0x1b, 0xd0, 0x80, 0x0c, 0xe2, 0xe0, 0x02, 0xbb, 0x14, 0x94, 0x41, 0x86, + 0x60, 0x1b, 0x83, 0x11, 0x83, 0x42, 0x08, 0xfc, 0xe0, 0x09, 0xe6, 0x18, + 0xbc, 0x85, 0x0f, 0xe6, 0x18, 0x82, 0xc3, 0x0f, 0xe6, 0x18, 0x82, 0x81, + 0x0f, 0x2c, 0x90, 0x03, 0xf9, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -const unsigned int sdl_metallib_len = 22048; +const unsigned int sdl_metallib_len = 21810; diff --git a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_iphonesimulator.h b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_iphonesimulator.h index 7347013fa..afa2f9d24 100644 --- a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_iphonesimulator.h +++ b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_iphonesimulator.h @@ -1,19 +1,19 @@ const unsigned char sdl_metallib[] = { 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa2, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x04, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc2, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x5c, 0x00, 0x00, + 0xd4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, - 0x7f, 0x4c, 0xdb, 0xde, 0x31, 0xe2, 0x3f, 0x23, 0x2d, 0x4c, 0xd0, 0xa6, - 0xf1, 0x58, 0xb9, 0x57, 0xeb, 0xc6, 0x37, 0x59, 0xae, 0x56, 0x95, 0xd1, - 0xc7, 0x7b, 0x8a, 0x10, 0x1e, 0x22, 0xf2, 0xe1, 0x4d, 0x44, 0x53, 0x5a, - 0x08, 0x00, 0xa0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, + 0x58, 0x42, 0x4b, 0xfb, 0xa2, 0x63, 0xc5, 0xbe, 0xa5, 0x8f, 0x87, 0x96, + 0xe5, 0x35, 0xca, 0x35, 0xa0, 0xb5, 0xd2, 0xda, 0x62, 0x66, 0xc3, 0xd2, + 0x70, 0xc6, 0x5e, 0xbd, 0x02, 0xc6, 0xb7, 0xe7, 0x4d, 0x44, 0x53, 0x5a, + 0x08, 0x00, 0x20, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, @@ -21,243 +21,245 @@ const unsigned char sdl_metallib[] = { 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, - 0x00, 0x1a, 0x5e, 0xb2, 0x92, 0x8c, 0x25, 0x43, 0xbc, 0x6f, 0x79, 0x8a, - 0x1c, 0xf6, 0x2d, 0x29, 0x0e, 0x5d, 0xf0, 0xa9, 0xbe, 0x96, 0xd1, 0xbe, - 0xa8, 0x69, 0xe5, 0xa2, 0x57, 0x11, 0xbe, 0xa3, 0xf5, 0x4d, 0x44, 0x53, - 0x5a, 0x08, 0x00, 0xe0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, - 0x46, 0x46, 0x54, 0x18, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0c, 0x00, + 0x00, 0x66, 0xdb, 0x11, 0xb3, 0x31, 0x5a, 0xaa, 0xb0, 0x50, 0xa4, 0x35, + 0xc1, 0x73, 0x21, 0x6b, 0xe9, 0xc9, 0x0c, 0x95, 0x5f, 0xa8, 0xd9, 0x57, + 0xa3, 0x88, 0xec, 0x3f, 0xa9, 0x0a, 0x90, 0xbe, 0x0f, 0x4d, 0x44, 0x53, + 0x5a, 0x08, 0x00, 0x30, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x88, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x13, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, - 0x41, 0x53, 0x48, 0x20, 0x00, 0x47, 0x0b, 0xfe, 0x5f, 0xa1, 0xeb, 0xee, - 0x4e, 0x51, 0xcc, 0x14, 0x22, 0x88, 0xb1, 0xb6, 0x2b, 0xd5, 0x11, 0x64, - 0xbe, 0xee, 0x92, 0xff, 0x91, 0x7f, 0xcb, 0x3f, 0xb8, 0x2d, 0xdf, 0x4c, - 0xcd, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x54, 0x00, 0x00, + 0x41, 0x53, 0x48, 0x20, 0x00, 0xbf, 0xdd, 0x75, 0x01, 0xa6, 0xb2, 0xda, + 0x74, 0x88, 0xeb, 0x9a, 0x42, 0x99, 0x64, 0xad, 0x86, 0x24, 0x0f, 0x60, + 0xba, 0xca, 0x60, 0x8d, 0x5b, 0x03, 0xaa, 0xb6, 0x47, 0xf6, 0x63, 0x4e, + 0xf7, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x30, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, + 0x00, 0x50, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x87, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, - 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0xae, 0x09, 0x73, 0x8a, - 0xda, 0x8b, 0xb3, 0x29, 0x5d, 0x2a, 0xd9, 0x5b, 0xa2, 0xb4, 0x19, 0xe7, - 0xe6, 0xb4, 0x6c, 0xf1, 0xfa, 0x7f, 0xd0, 0x52, 0xeb, 0x18, 0x25, 0x3d, - 0xee, 0xbf, 0xab, 0x64, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x70, 0x0c, + 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x5c, 0xba, 0x6c, 0xdf, + 0xc2, 0xf6, 0x3b, 0x3e, 0x3e, 0x08, 0x43, 0xbe, 0x7d, 0x22, 0xfe, 0x64, + 0xc7, 0x25, 0x19, 0x08, 0xc4, 0x0f, 0xc6, 0xb9, 0x40, 0x15, 0x4f, 0x9d, + 0xae, 0x55, 0xea, 0x33, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0xc0, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, - 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x86, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, - 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x90, 0xd8, - 0x72, 0x29, 0x17, 0x5f, 0x3a, 0x0e, 0x5a, 0xeb, 0xa9, 0x7c, 0x3d, 0x51, - 0x27, 0x7c, 0x80, 0x1b, 0x02, 0x17, 0x8f, 0x4d, 0x8f, 0x4c, 0x47, 0x21, - 0x6e, 0x1b, 0xb6, 0xe7, 0x9b, 0xbb, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, - 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, - 0x18, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x39, 0xaf, + 0x60, 0x76, 0x98, 0x96, 0x34, 0xa7, 0xe6, 0x4c, 0xe7, 0x40, 0xaf, 0x1b, + 0x46, 0x4a, 0x1e, 0xc7, 0x26, 0x6a, 0x31, 0xc3, 0x0d, 0xe8, 0x89, 0x4e, + 0x88, 0xff, 0x38, 0x12, 0x36, 0xcc, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, + 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, + 0x18, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x87, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, - 0x00, 0x8a, 0x26, 0x54, 0x14, 0x4d, 0x2b, 0x8c, 0x28, 0x92, 0x9a, 0x3b, - 0x6a, 0xd9, 0x09, 0x02, 0xbd, 0xed, 0x11, 0xf3, 0xe5, 0xa8, 0xdb, 0xe9, - 0x7e, 0xda, 0xcd, 0xc0, 0xa1, 0x44, 0x9a, 0x82, 0x25, 0x4d, 0x44, 0x53, - 0x5a, 0x08, 0x00, 0x90, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, - 0x46, 0x46, 0x54, 0x18, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x3f, 0x00, + 0x00, 0xb2, 0xee, 0x20, 0x5e, 0x09, 0xbf, 0x7f, 0xac, 0xd0, 0x23, 0x12, + 0xf8, 0xa4, 0x8d, 0xdc, 0x2f, 0x44, 0x73, 0xe5, 0x8b, 0xe3, 0xba, 0xb1, + 0x72, 0xaa, 0x49, 0x43, 0x65, 0xbf, 0x81, 0x38, 0x26, 0x4d, 0x44, 0x53, + 0x5a, 0x08, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x87, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, - 0x53, 0x48, 0x20, 0x00, 0xe4, 0x1e, 0xcf, 0xae, 0xef, 0x87, 0x32, 0xa7, - 0x5b, 0x04, 0x89, 0x62, 0xa2, 0x3a, 0x12, 0x73, 0xdc, 0xfa, 0x41, 0xe8, - 0xa8, 0xdd, 0x61, 0x74, 0x9e, 0x56, 0x25, 0xc8, 0x6f, 0x52, 0x57, 0xb0, - 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0xa0, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x53, 0x48, 0x20, 0x00, 0x07, 0x3f, 0x28, 0x46, 0x4d, 0xc8, 0x8f, 0xea, + 0x98, 0xaa, 0x7f, 0xba, 0xf9, 0xee, 0x72, 0x32, 0x9b, 0x5f, 0xbd, 0x82, + 0xbc, 0x63, 0x20, 0x7f, 0xfe, 0xfa, 0x50, 0x7c, 0xc8, 0xc5, 0xe1, 0x28, + 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x40, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, + 0x40, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, - 0x44, 0x54, 0x45, 0x4e, 0x44, 0x54, 0x20, 0x00, 0x00, 0x00, 0x56, 0x41, - 0x54, 0x54, 0x0d, 0x00, 0x01, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x00, 0x00, 0x80, 0x56, 0x41, 0x54, 0x59, 0x03, 0x00, 0x01, - 0x00, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x2c, 0x00, 0x00, 0x00, 0x56, 0x41, - 0x54, 0x54, 0x18, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x00, 0x00, 0x80, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, - 0x64, 0x00, 0x01, 0x80, 0x56, 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, - 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, - 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, - 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, - 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, - 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, - 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, - 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, - 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x88, 0x0c, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, - 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x00, 0x0b, 0x02, - 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, - 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, - 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, - 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, - 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, - 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, - 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, - 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x1b, 0xc8, - 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, - 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, - 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, - 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, - 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, - 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, - 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, - 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, - 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, - 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, - 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, - 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, - 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, - 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, - 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, - 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, - 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, - 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, - 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, - 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, - 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, - 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, - 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, - 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, - 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, - 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, - 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, - 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, - 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, - 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, - 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, - 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, - 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, - 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, - 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, - 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, - 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, - 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x44, 0x54, 0x45, 0x4e, 0x44, 0x54, 0x29, 0x00, 0x00, 0x00, 0x56, 0x41, + 0x54, 0x54, 0x15, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x00, 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, + 0x80, 0x56, 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x06, 0x45, + 0x4e, 0x44, 0x54, 0x35, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x20, + 0x00, 0x03, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x74, 0x65, + 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x02, 0x80, 0x56, 0x41, 0x54, + 0x59, 0x05, 0x00, 0x03, 0x00, 0x04, 0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0c, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, + 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, + 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, + 0x08, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, + 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, + 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, + 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, + 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, + 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, + 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, + 0x85, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, + 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, + 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, + 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, - 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, - 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, - 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, - 0x72, 0x00, 0x36, 0x2c, 0x82, 0x00, 0x24, 0xc0, 0x02, 0x54, 0x41, 0x1a, - 0x80, 0xc2, 0x86, 0x65, 0x18, 0x80, 0x04, 0x58, 0x80, 0x2a, 0x48, 0x03, - 0x50, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, - 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1b, 0x00, - 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, - 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, - 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, - 0x04, 0x60, 0x85, 0x00, 0x86, 0x11, 0x04, 0x20, 0x09, 0xc2, 0x4c, 0xd4, - 0x3c, 0xd0, 0x83, 0x3c, 0xd4, 0xc3, 0x38, 0xd0, 0x83, 0x1b, 0xb4, 0x43, - 0x39, 0xd0, 0x43, 0x38, 0xb0, 0x83, 0x1e, 0xe8, 0x41, 0x3b, 0x84, 0x03, - 0x3d, 0xc8, 0x43, 0x3a, 0xe0, 0x03, 0x0a, 0xc8, 0x20, 0x42, 0x21, 0x14, - 0x42, 0x0c, 0x63, 0xe8, 0x0c, 0x04, 0xcc, 0x11, 0x80, 0x41, 0x0a, 0xa8, - 0x39, 0x02, 0x50, 0x18, 0x44, 0x08, 0x84, 0x61, 0x04, 0x42, 0x19, 0x01, - 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, - 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, - 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, - 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, - 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, - 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, - 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, - 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, - 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, - 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, - 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, - 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, - 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, - 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, - 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, - 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, - 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, - 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, - 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, - 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, - 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, - 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, - 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, - 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, - 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, - 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, - 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, - 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, - 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, - 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, - 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, - 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x10, 0xdb, 0x95, 0x3f, 0xeb, - 0x2c, 0xc8, 0xf0, 0x57, 0x44, 0x34, 0x11, 0xd7, 0x90, 0x08, 0x80, 0x0e, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0xd8, - 0x20, 0x50, 0x54, 0x5d, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x0a, 0x00, - 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, - 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, - 0x50, 0x80, 0x01, 0x05, 0x52, 0x06, 0xc4, 0x46, 0x00, 0x68, 0x8d, 0x25, - 0x38, 0x02, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, - 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, - 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, - 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, - 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, - 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, - 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, - 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, - 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, - 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, - 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, - 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, - 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, - 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, - 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, - 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, - 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, - 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, - 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, - 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, - 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, - 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, - 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, - 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, - 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, - 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, - 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, - 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, - 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, - 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, - 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, - 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, - 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, - 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, - 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, - 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, - 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, - 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, - 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, - 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, - 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, - 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, - 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x32, 0x9a, - 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, - 0xd4, 0x36, 0x0c, 0x6f, 0x00, 0x00, 0x8b, 0xe2, 0x06, 0xc5, 0xc6, 0x91, - 0x01, 0x13, 0x19, 0x0c, 0xe2, 0x14, 0x09, 0x24, 0x79, 0x86, 0xf2, 0x20, - 0xd1, 0x85, 0x28, 0x09, 0x00, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, - 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, - 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, - 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, + 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, + 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, + 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, + 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, + 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, + 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, + 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, + 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, + 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, + 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, + 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, + 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, + 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, + 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, + 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, + 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, + 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, + 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, + 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, + 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, + 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, + 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, + 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, + 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, + 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, + 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, + 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x2c, 0xc2, 0x00, + 0x24, 0xc0, 0x02, 0x54, 0x41, 0x1a, 0x80, 0xc2, 0x86, 0x65, 0x20, 0x80, + 0x04, 0x58, 0x80, 0x2a, 0x48, 0x03, 0x50, 0x00, 0x49, 0x18, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, + 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x60, 0x87, 0x10, 0xc0, 0x30, + 0x82, 0x00, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, + 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, + 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, + 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x52, 0x88, 0x11, 0x8c, 0xa1, 0x33, + 0x10, 0x30, 0x47, 0x00, 0x06, 0x29, 0xa0, 0xe6, 0x08, 0x40, 0x61, 0x10, + 0x21, 0x10, 0x86, 0x11, 0x08, 0x65, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, + 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, + 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, + 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, + 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, + 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, + 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, + 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, + 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, + 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, + 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, + 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, + 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x10, 0xdb, 0x95, 0x3f, 0xeb, 0x2c, 0xc8, + 0xf0, 0x57, 0x44, 0x34, 0x11, 0xd7, 0x90, 0x08, 0x80, 0x0e, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0xd8, 0x20, 0x50, + 0x54, 0x61, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, + 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x80, + 0x01, 0x05, 0x52, 0x06, 0xc4, 0x46, 0x00, 0x68, 0x8d, 0x25, 0x38, 0x04, + 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x3c, + 0xcc, 0x7c, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x01, 0x13, + 0x19, 0x0c, 0x12, 0x59, 0x85, 0x53, 0x24, 0x90, 0xe4, 0x19, 0xca, 0x83, + 0x44, 0x17, 0xa2, 0x24, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, @@ -271,531 +273,547 @@ const unsigned char sdl_metallib[] = { 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x66, 0x6c, - 0x6f, 0x61, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, - 0x61, 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, - 0x6e, 0x70, 0x75, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x67, 0x65, - 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x5f, 0x5f, 0x61, 0x69, - 0x72, 0x5f, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, - 0x72, 0x5f, 0x5f, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x61, 0x69, - 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, - 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, - 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x61, - 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, - 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x66, - 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, - 0x72, 0x6d, 0x23, 0x08, 0x4a, 0x30, 0x82, 0xb0, 0x24, 0x23, 0x08, 0x8a, - 0x30, 0x82, 0xa0, 0x0c, 0x23, 0x08, 0x0a, 0x31, 0x82, 0x80, 0x00, 0x23, - 0x08, 0x4a, 0x31, 0x82, 0xa0, 0x18, 0x23, 0x08, 0xca, 0x31, 0xc3, 0xc0, - 0x05, 0xdd, 0x0c, 0x83, 0x27, 0x7c, 0x33, 0x04, 0xc3, 0x0c, 0x03, 0xc7, - 0x81, 0xc1, 0x0c, 0x04, 0xe1, 0x79, 0x60, 0x30, 0x43, 0x50, 0xcc, 0x10, - 0x18, 0x33, 0x04, 0xc7, 0x0c, 0x05, 0x92, 0x28, 0x0b, 0x33, 0x43, 0xd1, - 0x24, 0xce, 0xf2, 0xcc, 0x20, 0xb4, 0x81, 0x1b, 0xcc, 0xa0, 0x80, 0x01, - 0x14, 0x81, 0x81, 0x27, 0x25, 0xd3, 0xc2, 0xcc, 0x00, 0x79, 0x54, 0x25, - 0x06, 0x11, 0xe7, 0x59, 0x97, 0x18, 0x60, 0x63, 0x90, 0x64, 0x8b, 0x36, - 0x03, 0xc4, 0x51, 0x95, 0x18, 0x44, 0x64, 0xe0, 0x59, 0x97, 0x18, 0x60, - 0x63, 0x90, 0x64, 0xcb, 0x36, 0xc3, 0x00, 0x07, 0x71, 0x20, 0x07, 0x33, - 0x0c, 0x61, 0xf0, 0x06, 0x73, 0x20, 0x23, 0x81, 0x09, 0xba, 0x88, 0x8d, - 0xcd, 0xae, 0xcd, 0xa5, 0xed, 0x8d, 0xac, 0x8e, 0xad, 0xcc, 0xc5, 0x8c, - 0x2d, 0xec, 0x6c, 0x6e, 0x14, 0x81, 0x0c, 0xca, 0xe0, 0x14, 0x36, 0x36, - 0xbb, 0x36, 0x97, 0x34, 0xb2, 0x32, 0x37, 0xba, 0x51, 0x02, 0x33, 0xb8, - 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, - 0x94, 0xe0, 0x0c, 0x8e, 0x0a, 0x4b, 0x93, 0x73, 0x61, 0x0b, 0x73, 0x3b, - 0xab, 0x0b, 0x3b, 0x2b, 0xfb, 0xb2, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, - 0x1b, 0x25, 0x40, 0x83, 0x9b, 0xc2, 0xd2, 0xe4, 0x5c, 0xc6, 0xde, 0xda, - 0xe0, 0xd2, 0xd8, 0xca, 0xbe, 0xde, 0xe0, 0xe8, 0xd2, 0xde, 0xdc, 0xe6, - 0x46, 0x19, 0xd2, 0x40, 0x0d, 0xd6, 0xe0, 0x94, 0xb0, 0x34, 0x39, 0x17, - 0xbb, 0x32, 0x39, 0xba, 0x32, 0xbc, 0x51, 0x82, 0x39, 0x00, 0xa9, 0x18, - 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, - 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, - 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, - 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, - 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, - 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, - 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, - 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xc4, 0x4a, 0xa0, 0x0c, 0x8a, 0x80, - 0xdc, 0x08, 0xc0, 0x58, 0x44, 0x10, 0x04, 0xc1, 0x58, 0x84, 0x20, 0x08, - 0xc2, 0x58, 0xc4, 0x30, 0x0c, 0x03, 0x81, 0x31, 0x02, 0x10, 0x04, 0x41, - 0xfc, 0xa3, 0x30, 0x03, 0x40, 0x62, 0x06, 0x80, 0xc6, 0x0c, 0x00, 0x00, - 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, - 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, - 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, - 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, - 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, - 0x06, 0xd9, 0x10, 0xd8, 0xc1, 0x86, 0xa1, 0x0e, 0xf0, 0xe0, 0x0e, 0x36, - 0x0c, 0x79, 0x90, 0x07, 0x77, 0x00, 0xbb, 0x10, 0x0c, 0x44, 0x41, 0x14, - 0x84, 0xb2, 0x0b, 0xf1, 0x48, 0x96, 0x44, 0x41, 0x28, 0x83, 0x0c, 0xc3, - 0xc1, 0x98, 0x10, 0x88, 0xff, 0x2e, 0xc4, 0x64, 0x69, 0x11, 0x05, 0xa1, - 0x0c, 0x32, 0x1c, 0xcb, 0x63, 0x42, 0x20, 0xfe, 0x16, 0x14, 0xe0, 0xbf, - 0x0b, 0x81, 0x6d, 0x1f, 0x45, 0x41, 0x28, 0x83, 0x0c, 0x0c, 0x34, 0x99, - 0x10, 0x88, 0xbf, 0x15, 0x01, 0xf8, 0xef, 0x42, 0x74, 0x60, 0x40, 0x06, - 0x1a, 0x05, 0xa1, 0x0c, 0x32, 0x44, 0xd5, 0x65, 0x42, 0x20, 0xfe, 0x56, - 0x04, 0xe0, 0xbf, 0x0b, 0x11, 0x06, 0x65, 0x90, 0x06, 0x60, 0x40, 0x41, - 0x28, 0x83, 0x0c, 0x81, 0xf6, 0x59, 0x50, 0x89, 0xff, 0x20, 0xc3, 0xc0, - 0x81, 0x81, 0x05, 0x93, 0xf8, 0xdb, 0x10, 0x80, 0xff, 0x20, 0x83, 0xf1, - 0x89, 0x81, 0x05, 0x91, 0xf8, 0xdb, 0x10, 0x80, 0xff, 0x20, 0x43, 0x22, - 0x06, 0x64, 0x60, 0xc1, 0x23, 0xfe, 0x36, 0x04, 0xe0, 0xbf, 0x0b, 0xe1, - 0x06, 0x72, 0x60, 0x07, 0x6c, 0x40, 0x41, 0x28, 0x83, 0x0c, 0xc1, 0x19, - 0xb0, 0x81, 0x05, 0x62, 0x20, 0xfe, 0x83, 0x0c, 0x43, 0x1a, 0xb4, 0x81, - 0x05, 0x60, 0x20, 0xfe, 0x83, 0x0c, 0xc5, 0x1a, 0xb8, 0x81, 0x05, 0x9d, - 0xf8, 0x0f, 0x32, 0x1c, 0x6d, 0xf0, 0x06, 0x16, 0x68, 0xe2, 0x3f, 0xc8, - 0xa0, 0x07, 0x6d, 0x40, 0x07, 0x96, 0x05, 0xe2, 0x3f, 0xc8, 0xc0, 0x07, - 0x6f, 0x50, 0x07, 0xe6, 0x04, 0xe2, 0x6f, 0xc9, 0x00, 0xfe, 0x16, 0x30, - 0xe0, 0x6f, 0x41, 0x02, 0xfe, 0x16, 0x20, 0xe0, 0x6f, 0x41, 0x01, 0xfe, - 0xb3, 0x0d, 0x77, 0x10, 0x00, 0xb3, 0x0d, 0x81, 0x1e, 0x04, 0x19, 0x04, - 0xc4, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xc8, 0x83, 0x2d, - 0xc3, 0x10, 0xe4, 0xc1, 0x96, 0xe1, 0x08, 0xf2, 0x60, 0xcb, 0xc0, 0x04, - 0x79, 0xb0, 0x65, 0x88, 0x82, 0x3c, 0xd8, 0x32, 0x58, 0x41, 0x1e, 0x6c, - 0x19, 0xc6, 0x20, 0xc8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, - 0x81, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, - 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, - 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x03, - 0x94, 0x77, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, - 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x33, 0x31, - 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, - 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6f, 0x73, 0x31, 0x33, 0x2e, - 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, - 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, - 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xcc, 0x0c, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, - 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0xf9, 0x02, - 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, - 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, - 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, - 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, - 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, - 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, - 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, - 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x85, 0x00, - 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, - 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, - 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, - 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, - 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, - 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, - 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, - 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, - 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, - 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, - 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, - 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, - 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, - 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, - 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, - 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, - 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, - 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, - 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, - 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, - 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, - 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, - 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, - 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, - 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, - 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, - 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, - 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, - 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, - 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, - 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, - 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, - 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, - 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, - 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, - 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, - 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, - 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, - 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, - 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, - 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, - 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, - 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x2c, 0xc2, 0x00, 0x24, 0xc0, - 0x02, 0x54, 0x41, 0x1a, 0x80, 0xc2, 0x86, 0x65, 0x20, 0x80, 0x04, 0x58, - 0x80, 0x2a, 0x48, 0x03, 0x50, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, - 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, - 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, - 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, - 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x56, 0x08, 0x22, - 0x09, 0xc2, 0x4c, 0xd4, 0x3c, 0xd0, 0x83, 0x3c, 0xd4, 0xc3, 0x38, 0xd0, - 0x83, 0x1b, 0xb4, 0x43, 0x39, 0xd0, 0x43, 0x38, 0xb0, 0x83, 0x1e, 0xe8, - 0x41, 0x3b, 0x84, 0x03, 0x3d, 0xc8, 0x43, 0x3a, 0xe0, 0x03, 0x0a, 0xc8, - 0x20, 0x42, 0x21, 0x94, 0x62, 0x08, 0x61, 0x0c, 0x9d, 0x81, 0x80, 0x39, - 0x02, 0x30, 0x48, 0x01, 0x35, 0x47, 0x00, 0x0a, 0x83, 0x08, 0x81, 0x30, - 0x8c, 0x40, 0x28, 0x23, 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, - 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, - 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, - 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, - 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, - 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, - 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, - 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, - 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, - 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, - 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, - 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, - 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, - 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, - 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, - 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x0f, - 0xdb, 0x95, 0x3f, 0xe7, 0x3c, 0xd8, 0x5f, 0x11, 0xd1, 0x44, 0x5c, 0x43, - 0x22, 0xe0, 0x39, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x40, 0x62, 0x83, 0x40, 0xd1, 0x7d, 0x01, 0x00, 0x80, 0x2c, 0x10, - 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, - 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, - 0x02, 0x85, 0x30, 0x02, 0x50, 0x80, 0x01, 0x05, 0x52, 0x06, 0xc4, 0x46, - 0x00, 0x68, 0x8d, 0x25, 0x38, 0x02, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, - 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, - 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, - 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, - 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, - 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, - 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, - 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, - 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, - 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, - 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, - 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, - 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, - 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, - 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, - 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, - 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, - 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, - 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, - 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, - 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, - 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, - 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, - 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, - 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, - 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, - 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, - 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, - 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, - 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, - 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, - 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, - 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, - 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, - 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, - 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, - 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, - 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, - 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, - 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0xc7, 0x00, - 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, - 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x36, 0xcc, 0x75, 0x00, 0x00, 0x8b, 0xe2, - 0x06, 0xc5, 0xc6, 0x91, 0x01, 0x13, 0x19, 0x0c, 0x12, 0x65, 0x06, 0x02, - 0x49, 0x9e, 0xf2, 0x20, 0xd1, 0x85, 0x28, 0x09, 0x00, 0x00, 0x53, 0x44, - 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, - 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, - 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x20, 0x28, - 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, - 0x31, 0x2e, 0x34, 0x33, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, - 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, - 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, - 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, - 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, - 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, - 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, - 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, - 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, + 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x5f, 0x5f, 0x61, 0x69, 0x72, 0x5f, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x5f, 0x29, - 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, - 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, - 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, - 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x66, 0x6f, 0x72, 0x6d, 0x00, 0x00, 0x04, 0x4a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x82, 0xa0, 0x04, 0x23, 0x08, 0x4b, 0x32, 0x82, 0xa0, - 0x08, 0x23, 0x08, 0xca, 0x30, 0x82, 0xa0, 0x10, 0x23, 0x08, 0x08, 0x30, - 0x82, 0xa0, 0x14, 0x23, 0x08, 0x8a, 0x31, 0x82, 0xa0, 0x1c, 0x33, 0x0c, - 0x5c, 0xd0, 0xcd, 0x30, 0x78, 0xc2, 0x37, 0x43, 0x30, 0xcc, 0x30, 0x70, - 0x1c, 0x18, 0xcc, 0x40, 0x10, 0x9e, 0x07, 0x06, 0x33, 0x04, 0xc5, 0x0c, - 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x89, 0xb2, 0x30, 0x33, 0x18, - 0x8d, 0x93, 0x3c, 0x0b, 0x34, 0x83, 0xd0, 0x06, 0x6e, 0x30, 0x83, 0x02, - 0x06, 0x91, 0x04, 0x06, 0xde, 0x94, 0x3c, 0x0b, 0x33, 0x83, 0xe2, 0x45, - 0x92, 0xe7, 0x4d, 0xc9, 0xb3, 0x40, 0x33, 0x40, 0x1c, 0x55, 0x89, 0x81, - 0xc4, 0x79, 0xd6, 0x25, 0x06, 0xd8, 0x18, 0x24, 0xd9, 0xa2, 0xcd, 0x00, - 0x91, 0x01, 0x55, 0x89, 0x81, 0x44, 0x06, 0x9e, 0x75, 0x89, 0x01, 0x36, - 0x06, 0x49, 0xb6, 0x6c, 0x33, 0x10, 0x70, 0x10, 0x07, 0x72, 0x30, 0x07, - 0x33, 0x0c, 0x61, 0xf0, 0x06, 0x74, 0x50, 0x1a, 0xc0, 0x71, 0x1c, 0xc7, - 0x71, 0x1c, 0xc7, 0x89, 0x81, 0x18, 0x58, 0x68, 0xe0, 0x06, 0x96, 0x65, - 0xb9, 0x01, 0x1d, 0xa0, 0x01, 0x2e, 0xb0, 0x82, 0x48, 0xb8, 0x04, 0x28, - 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, - 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, - 0x20, 0x83, 0x32, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, - 0xcc, 0x8d, 0x6e, 0x94, 0xc0, 0x0c, 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, - 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0x38, 0x83, 0xa3, 0xc2, - 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, - 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xd0, 0xe0, 0xa6, - 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, - 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x86, 0x34, 0x50, 0x83, - 0x35, 0x38, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x8e, 0xae, 0x0c, - 0x6f, 0x94, 0x80, 0x0e, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, - 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, - 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, - 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, - 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, - 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, - 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, - 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x65, 0x00, - 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x00, 0x00, 0xc4, 0x4a, 0xa0, 0x0c, 0x8a, 0x80, 0xdc, 0x08, 0xc0, 0x58, - 0x44, 0x10, 0x04, 0xc1, 0x58, 0x84, 0x20, 0x08, 0xc2, 0x58, 0xc4, 0x30, - 0x0c, 0x03, 0x85, 0x19, 0x00, 0x12, 0x33, 0x00, 0x34, 0x66, 0x00, 0x00, - 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, - 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, - 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, - 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, - 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, - 0x06, 0xd9, 0x10, 0xdc, 0xc1, 0x86, 0xc1, 0x0e, 0xf2, 0x00, 0x0f, 0x36, - 0x0c, 0x7a, 0xa0, 0x07, 0x78, 0x00, 0xbb, 0x10, 0x0b, 0x44, 0x41, 0x14, - 0x84, 0xb2, 0x0b, 0xe1, 0x48, 0x96, 0x44, 0x41, 0x28, 0x83, 0x0c, 0xc3, - 0xb1, 0x98, 0x10, 0x88, 0xff, 0x2e, 0x84, 0x64, 0x69, 0x10, 0x05, 0xa1, - 0x0c, 0x32, 0x1c, 0x8b, 0x63, 0x42, 0x20, 0xfe, 0x16, 0x14, 0xe0, 0xbf, - 0x0b, 0x71, 0x6d, 0xdf, 0x44, 0x41, 0x28, 0x83, 0x0c, 0x0c, 0x24, 0x99, - 0x10, 0x88, 0xbf, 0x15, 0x01, 0xf8, 0xef, 0x42, 0x70, 0x60, 0x40, 0x06, - 0x19, 0x05, 0xa1, 0x0c, 0x32, 0x44, 0x95, 0x65, 0x42, 0x20, 0xfe, 0x56, - 0x04, 0xe0, 0xbf, 0x0b, 0x01, 0x06, 0x65, 0x90, 0x06, 0x1f, 0x05, 0xa1, - 0x0c, 0x32, 0x04, 0x9a, 0x67, 0x41, 0x25, 0xfe, 0x83, 0x0c, 0x03, 0xf7, - 0x59, 0x30, 0x89, 0xbf, 0x0d, 0x01, 0xf8, 0x0f, 0x32, 0x18, 0x5f, 0x18, - 0x58, 0x10, 0x89, 0xbf, 0x0d, 0x01, 0xf8, 0x0f, 0x32, 0x24, 0x62, 0x30, - 0x06, 0x16, 0x3c, 0xe2, 0x6f, 0x43, 0x00, 0xfe, 0xbb, 0x10, 0x6d, 0x20, - 0x07, 0x76, 0xb0, 0x06, 0x14, 0x84, 0x32, 0xc8, 0x10, 0x9c, 0xc1, 0x1a, - 0x58, 0x20, 0x06, 0xe2, 0x3f, 0xc8, 0x30, 0xa4, 0x01, 0x1b, 0x58, 0x00, - 0x06, 0xe2, 0x3f, 0xc8, 0x50, 0xac, 0x41, 0x1b, 0x58, 0xd0, 0x89, 0xff, - 0x20, 0xc3, 0xd1, 0x06, 0x6e, 0x60, 0x81, 0x26, 0xfe, 0x83, 0x0c, 0x7a, - 0xe0, 0x06, 0x73, 0x60, 0x59, 0x20, 0xfe, 0x83, 0x0c, 0x7c, 0x00, 0x07, - 0x74, 0x60, 0x4e, 0x20, 0xfe, 0x96, 0x0c, 0xe0, 0x6f, 0x01, 0x03, 0xfe, - 0x16, 0x24, 0xe0, 0x6f, 0x01, 0x02, 0xfe, 0x16, 0x14, 0xe0, 0x3f, 0xdb, - 0x60, 0x07, 0x01, 0x30, 0xdb, 0x10, 0x8c, 0x42, 0x90, 0x41, 0x40, 0x0c, - 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xd0, 0x83, 0x2d, - 0xc3, 0x10, 0xe8, 0xc1, 0x96, 0xe1, 0x08, 0xf4, 0x60, 0xcb, 0xc0, 0x04, - 0x7a, 0xb0, 0x65, 0x88, 0x02, 0x3d, 0xd8, 0x32, 0x58, 0x81, 0x1e, 0x6c, - 0x19, 0xc6, 0x20, 0xd0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, - 0x94, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, - 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, - 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x03, - 0x94, 0x76, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, - 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x33, 0x31, 0x30, - 0x30, 0x31, 0x2e, 0x34, 0x33, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, - 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, - 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x6c, 0x0a, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, - 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0x0b, 0x02, - 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, - 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, - 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, - 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, - 0x18, 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, - 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x11, 0x22, - 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, - 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x1b, 0xcc, - 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0x03, 0x40, 0x02, 0x2a, - 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, - 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, - 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, - 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, - 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, - 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, - 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, - 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, - 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, - 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, - 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, - 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, - 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, - 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, + 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, + 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, + 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x34, 0x78, 0x34, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x00, 0x00, + 0xc4, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0xa0, 0x04, + 0x23, 0x08, 0x4b, 0x32, 0x82, 0xa0, 0x08, 0x23, 0x08, 0xca, 0x30, 0x82, + 0xa0, 0x10, 0x23, 0x08, 0x08, 0x30, 0x82, 0xa0, 0x14, 0x23, 0x08, 0x8a, + 0x31, 0x82, 0xa0, 0x1c, 0x33, 0x0c, 0x5f, 0x00, 0x06, 0x33, 0x0c, 0x61, + 0x20, 0x88, 0xc1, 0x0c, 0xc1, 0x30, 0xc3, 0xf0, 0x7d, 0x63, 0x30, 0x03, + 0x41, 0x84, 0x41, 0x18, 0x8c, 0xc1, 0x0c, 0x41, 0x31, 0x43, 0x60, 0xcc, + 0x10, 0x1c, 0x33, 0x14, 0x48, 0xa2, 0x2c, 0xcc, 0x0c, 0x46, 0xe3, 0x24, + 0xca, 0xf2, 0xcc, 0x50, 0x40, 0x49, 0xb4, 0x48, 0x33, 0x0c, 0x70, 0x10, + 0x07, 0x72, 0x30, 0x83, 0x32, 0x06, 0x13, 0x35, 0x06, 0x61, 0x50, 0x25, + 0xd6, 0xc2, 0xcc, 0xa0, 0x84, 0xc1, 0x44, 0x85, 0x41, 0x18, 0x54, 0x89, + 0xb2, 0x3c, 0x33, 0x40, 0xdf, 0x85, 0x95, 0x01, 0xf5, 0x85, 0x41, 0xa6, + 0x95, 0xc1, 0x66, 0x06, 0x09, 0xb7, 0x74, 0x33, 0x40, 0x67, 0x70, 0x61, + 0x65, 0x40, 0x9d, 0x41, 0x18, 0x64, 0x5a, 0x19, 0x6c, 0x66, 0x90, 0x70, + 0x8b, 0x37, 0x03, 0x41, 0x07, 0x75, 0x60, 0x07, 0x77, 0x30, 0xc3, 0x40, + 0x06, 0x73, 0x80, 0x07, 0xb5, 0x01, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, + 0x1c, 0x1a, 0xb8, 0x81, 0x85, 0x06, 0x7a, 0x60, 0x59, 0x96, 0x1b, 0xd0, + 0x81, 0x1b, 0xd0, 0x81, 0x2f, 0xf8, 0x02, 0x4a, 0xd0, 0x04, 0x28, 0xc8, + 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, + 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0x38, + 0x03, 0x34, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, + 0x8d, 0x6e, 0x94, 0x20, 0x0d, 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, + 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0x50, 0x83, 0xa3, 0xc2, 0xd2, + 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, + 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xd6, 0xe0, 0xa6, 0xb0, + 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, + 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x06, 0x36, 0x68, 0x03, 0x37, + 0x38, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x8e, 0xae, 0x0c, 0x6f, + 0x94, 0x00, 0x0f, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0xc4, 0x4a, 0xa0, 0x0c, 0x8a, 0x80, 0xdc, 0x08, 0xc0, 0x58, 0x44, 0x10, + 0x04, 0xc1, 0x58, 0x84, 0x20, 0x08, 0xc2, 0x58, 0xc4, 0x30, 0x0c, 0x03, + 0x81, 0x31, 0x02, 0x10, 0x04, 0x41, 0xfc, 0xa3, 0x30, 0x03, 0x40, 0x62, + 0x06, 0x80, 0xc6, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, + 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, + 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, 0x06, 0xd9, 0x10, 0xec, 0xc1, 0x86, + 0x41, 0x0f, 0xfa, 0x80, 0x0f, 0x36, 0x0c, 0x7e, 0xe0, 0x07, 0x7c, 0x00, + 0xbb, 0x10, 0x4c, 0x54, 0x45, 0x14, 0x84, 0xb2, 0x0b, 0xf1, 0x4c, 0xd7, + 0x44, 0x41, 0x28, 0x83, 0x0c, 0xc3, 0xc1, 0x98, 0x10, 0x88, 0xff, 0x2e, + 0xc4, 0x74, 0x6d, 0x11, 0x05, 0xa1, 0x0c, 0x32, 0x1c, 0xcb, 0x63, 0x42, + 0x20, 0xfe, 0x16, 0x14, 0xe0, 0xbf, 0x0b, 0x81, 0x71, 0x60, 0x40, 0x51, + 0x10, 0xca, 0x20, 0x03, 0x03, 0x4d, 0x26, 0x04, 0xe2, 0x6f, 0x45, 0x00, + 0xfe, 0xbb, 0x10, 0x5d, 0x18, 0x94, 0x81, 0x46, 0x41, 0x28, 0x83, 0x0c, + 0x51, 0x75, 0x99, 0x10, 0x88, 0xbf, 0x15, 0x01, 0xf8, 0xef, 0x42, 0x84, + 0x81, 0x19, 0xa8, 0x01, 0x18, 0x50, 0x10, 0xca, 0x20, 0x43, 0xa0, 0x7d, + 0x16, 0x54, 0xe2, 0x3f, 0xc8, 0x30, 0x70, 0x60, 0x60, 0xc1, 0x24, 0xfe, + 0x36, 0x04, 0xe0, 0x3f, 0xc8, 0x60, 0x7c, 0x62, 0x60, 0x41, 0x24, 0xfe, + 0x36, 0x04, 0xe0, 0x3f, 0xc8, 0x90, 0x88, 0x01, 0x19, 0x58, 0xf0, 0x88, + 0xbf, 0x0d, 0x01, 0xf8, 0xef, 0x42, 0xb8, 0xc1, 0x1c, 0xdc, 0x01, 0x1b, + 0x50, 0x10, 0xca, 0x20, 0x43, 0x70, 0x06, 0x6c, 0x60, 0x81, 0x18, 0x88, + 0xff, 0x20, 0xc3, 0x90, 0x06, 0x6d, 0x60, 0x01, 0x18, 0x88, 0xff, 0x20, + 0x43, 0xb1, 0x06, 0x6e, 0x60, 0x41, 0x27, 0xfe, 0x83, 0x0c, 0x47, 0x1b, + 0xbc, 0x81, 0x05, 0x9a, 0xf8, 0x0f, 0x32, 0xec, 0x41, 0x1b, 0xd0, 0x81, + 0x65, 0x81, 0xf8, 0x0f, 0x32, 0xf4, 0xc1, 0x1b, 0xd4, 0x81, 0x39, 0x81, + 0xf8, 0x5b, 0x32, 0x80, 0xbf, 0x05, 0x0c, 0xf8, 0x5b, 0x90, 0x80, 0xbf, + 0x05, 0x08, 0xf8, 0x5b, 0x50, 0x80, 0xff, 0x6c, 0xc3, 0x1d, 0x04, 0xc0, + 0x6c, 0x43, 0x40, 0x0a, 0xc1, 0x6c, 0x43, 0xb0, 0x07, 0x42, 0x06, 0x01, + 0x31, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xf0, + 0x83, 0x2d, 0xc3, 0x10, 0xf8, 0xc1, 0x96, 0xe1, 0x08, 0xfc, 0x60, 0xcb, + 0xc0, 0x04, 0x7e, 0xb0, 0x65, 0x88, 0x02, 0x3f, 0xd8, 0x32, 0x58, 0x81, + 0x1f, 0x6c, 0x19, 0xc6, 0x20, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, + 0x84, 0x00, 0x9f, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x0c, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x79, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, + 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6f, + 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, + 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x10, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, + 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, + 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, + 0x0a, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, + 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, + 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, + 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, + 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, + 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, + 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, + 0x85, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, + 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, + 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, + 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, + 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, + 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, + 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, + 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, - 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, - 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, + 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, + 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, + 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, + 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, + 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, + 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, + 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, + 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, + 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, + 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, - 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, - 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, - 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, - 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, - 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, - 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, + 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, + 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, - 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, - 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, - 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, - 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, - 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, - 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, - 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, - 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, - 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, - 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, - 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, - 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x01, 0x90, 0x00, 0x0b, 0x50, - 0x05, 0x69, 0x00, 0x01, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, 0x00, 0x00, 0x0e, 0x00, - 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x22, - 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, - 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x28, 0x33, 0x00, 0xc3, 0x08, - 0x04, 0x30, 0x88, 0x10, 0x04, 0x45, 0x08, 0xa1, 0x19, 0x08, 0x98, 0x23, - 0x00, 0x83, 0x14, 0xb0, 0x39, 0x02, 0x50, 0x18, 0x01, 0x00, 0x13, 0xbe, - 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, - 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, - 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, - 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, - 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, - 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, - 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, - 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, - 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, - 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, - 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, - 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, - 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, - 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, - 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, - 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, - 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, - 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, - 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, - 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, - 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, - 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, - 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, - 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, - 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, - 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, - 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, - 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, - 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, - 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, - 0x11, 0xc2, 0x90, 0x12, 0xdb, 0x95, 0x3f, 0xeb, 0x2c, 0xc8, 0xf0, 0x17, - 0x11, 0x60, 0x30, 0x44, 0x33, 0x0d, 0x89, 0x00, 0x69, 0x00, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x89, 0x0d, 0x02, 0x45, - 0xc5, 0x04, 0x00, 0x00, 0xb2, 0x40, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, - 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, - 0x43, 0xb2, 0x22, 0x28, 0x81, 0x42, 0x18, 0x01, 0x28, 0x10, 0xc2, 0x11, - 0x00, 0xba, 0xb1, 0x04, 0x47, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, - 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, - 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, - 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, - 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, - 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, - 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, - 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, - 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, - 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, - 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, - 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, - 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, - 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, - 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, - 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, - 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, - 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, - 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, - 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, - 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, - 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, - 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, - 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, - 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, - 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, - 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, - 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, - 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, - 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, - 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, - 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, - 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, - 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, - 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, - 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, - 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, - 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, - 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, - 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, - 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, - 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, - 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x32, 0x9a, - 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, - 0xd4, 0x24, 0xa8, 0x54, 0x00, 0x00, 0x8b, 0xe2, 0x06, 0xc5, 0xc6, 0x91, - 0x41, 0x14, 0x19, 0xca, 0x23, 0x21, 0xd1, 0xc5, 0x0c, 0x00, 0x53, 0x44, - 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, - 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, - 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x20, 0x28, - 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, - 0x31, 0x2e, 0x34, 0x33, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, + 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, + 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, + 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, + 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, + 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, + 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x2c, 0x02, 0x01, + 0x24, 0xc0, 0x02, 0x54, 0x41, 0x1a, 0x80, 0xc2, 0x86, 0x65, 0x28, 0x80, + 0x04, 0x58, 0x80, 0x2a, 0x48, 0x03, 0x50, 0x00, 0x49, 0x18, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, + 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x76, + 0x08, 0x41, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, + 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, + 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, + 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x62, 0x0c, 0x11, 0x84, 0x31, 0x74, + 0x06, 0x02, 0xe6, 0x08, 0xc0, 0x20, 0x05, 0xd4, 0x1c, 0x01, 0x28, 0x0c, + 0x22, 0x04, 0xc2, 0x30, 0x02, 0xa1, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, + 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, + 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, + 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, + 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, + 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, + 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, + 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, + 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, + 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, + 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, + 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, + 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x0f, 0xdb, 0x95, 0x3f, 0xe7, 0x3c, 0xd8, + 0x5f, 0x11, 0xd1, 0x44, 0x5c, 0x43, 0x22, 0xe0, 0x39, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x62, 0x83, 0x40, 0x51, + 0x86, 0x01, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, + 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x06, + 0x05, 0x18, 0x50, 0x20, 0xc4, 0x46, 0x00, 0x68, 0x8d, 0x25, 0x38, 0x04, + 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x3a, + 0x6c, 0x7d, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x01, 0x13, + 0x19, 0x0c, 0x12, 0x59, 0x45, 0x66, 0x20, 0x90, 0xe4, 0x29, 0x0f, 0x12, + 0x5d, 0x88, 0x92, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, + 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, + 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, + 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, + 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, + 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, + 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x76, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x61, + 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x5f, 0x5f, 0x61, 0x69, 0x72, 0x5f, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x5f, 0x29, 0x61, + 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, + 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, + 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x00, 0x04, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x82, 0xa0, 0x04, 0x23, 0x08, 0x4b, 0x32, 0x82, 0xa0, 0x08, 0x23, + 0x08, 0xca, 0x30, 0x82, 0xa0, 0x10, 0x23, 0x08, 0x08, 0x30, 0x82, 0xa0, + 0x14, 0x23, 0x08, 0x8a, 0x31, 0x82, 0xa0, 0x1c, 0x33, 0x0c, 0x5e, 0xf0, + 0xcd, 0x30, 0x80, 0x81, 0x10, 0x06, 0x33, 0x04, 0xc3, 0x0c, 0x83, 0xe7, + 0x89, 0xc1, 0x0c, 0x04, 0x01, 0x06, 0x60, 0x20, 0x06, 0x33, 0x04, 0xc5, + 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x89, 0xb2, 0x30, 0x33, + 0x18, 0x8d, 0x93, 0x28, 0xcb, 0x33, 0x83, 0xd1, 0x40, 0x49, 0xb4, 0x48, + 0x33, 0x0c, 0x6f, 0x00, 0x07, 0x71, 0x30, 0x83, 0x22, 0x06, 0x13, 0x25, + 0x06, 0x60, 0x50, 0x25, 0xd1, 0xc2, 0xcc, 0xa0, 0x80, 0xc1, 0x44, 0x81, + 0x01, 0x18, 0x54, 0x89, 0xb2, 0x3c, 0x33, 0x28, 0xde, 0x44, 0x79, 0x60, + 0x50, 0x25, 0xd1, 0x22, 0xcd, 0x00, 0x91, 0x81, 0x75, 0x95, 0x01, 0xe5, + 0x81, 0x01, 0x96, 0x95, 0x81, 0x66, 0x06, 0xc9, 0xb6, 0x70, 0x33, 0x40, + 0x61, 0x60, 0x5d, 0x65, 0x40, 0x91, 0x01, 0x18, 0x60, 0x59, 0x19, 0x68, + 0x66, 0x90, 0x6c, 0x4b, 0x37, 0x43, 0x31, 0x07, 0x74, 0x50, 0x07, 0x76, + 0x70, 0x07, 0x33, 0x0c, 0x63, 0x20, 0x07, 0x78, 0x50, 0x1c, 0xc0, 0x71, + 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x89, 0x81, 0x1b, 0x58, 0x68, 0xa0, 0x07, + 0x96, 0x65, 0xb9, 0x01, 0x1d, 0xd0, 0x01, 0x1d, 0xf8, 0x82, 0x2f, 0xc8, + 0x82, 0x4b, 0xd0, 0x04, 0x2b, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, + 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, + 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0x30, 0x83, 0x33, 0x38, 0x85, 0x8d, 0xcd, + 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x00, 0x0d, 0x6e, + 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, + 0x25, 0x48, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, + 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, + 0x46, 0x09, 0xd4, 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, + 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, + 0x51, 0x86, 0x35, 0x60, 0x83, 0x36, 0x38, 0x25, 0x2c, 0x4d, 0xce, 0xc5, + 0xae, 0x4c, 0x8e, 0xae, 0x0c, 0x6f, 0x94, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, + 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, + 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, + 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, + 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, + 0x61, 0x20, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, + 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xc4, 0x4a, 0xa0, 0x0c, + 0x8a, 0x80, 0xdc, 0x08, 0xc0, 0x58, 0x44, 0x10, 0x04, 0xc1, 0x58, 0x84, + 0x20, 0x08, 0xc2, 0x58, 0xc4, 0x30, 0x0c, 0x03, 0x85, 0x19, 0x00, 0x12, + 0x33, 0x00, 0x34, 0x66, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, + 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, + 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, 0x06, 0xd9, 0x10, 0xec, 0xc1, 0x86, + 0x41, 0x0f, 0xfa, 0x80, 0x0f, 0x36, 0x0c, 0x7e, 0xe0, 0x07, 0x7c, 0x00, + 0xbb, 0x10, 0x4b, 0x54, 0x45, 0x14, 0x84, 0xb2, 0x0b, 0xe1, 0x4c, 0xd7, + 0x44, 0x41, 0x28, 0x83, 0x0c, 0xc3, 0xb1, 0x98, 0x10, 0x88, 0xff, 0x2e, + 0x84, 0x74, 0x6d, 0x10, 0x05, 0xa1, 0x0c, 0x32, 0x1c, 0x8b, 0x63, 0x42, + 0x20, 0xfe, 0x16, 0x14, 0xe0, 0xbf, 0x0b, 0x71, 0x71, 0x60, 0x30, 0x51, + 0x10, 0xca, 0x20, 0x03, 0x03, 0x49, 0x26, 0x04, 0xe2, 0x6f, 0x45, 0x00, + 0xfe, 0xbb, 0x10, 0x5c, 0x18, 0x94, 0x41, 0x46, 0x41, 0x28, 0x83, 0x0c, + 0x51, 0x65, 0x99, 0x10, 0x88, 0xbf, 0x15, 0x01, 0xf8, 0xef, 0x42, 0x80, + 0x81, 0x19, 0xa8, 0xc1, 0x47, 0x41, 0x28, 0x83, 0x0c, 0x81, 0xe6, 0x59, + 0x50, 0x89, 0xff, 0x20, 0xc3, 0xc0, 0x7d, 0x16, 0x4c, 0xe2, 0x6f, 0x43, + 0x00, 0xfe, 0x83, 0x0c, 0xc6, 0x17, 0x06, 0x16, 0x44, 0xe2, 0x6f, 0x43, + 0x00, 0xfe, 0x83, 0x0c, 0x89, 0x18, 0x8c, 0x81, 0x05, 0x8f, 0xf8, 0xdb, + 0x10, 0x80, 0xff, 0x2e, 0x44, 0x1b, 0xcc, 0xc1, 0x1d, 0xac, 0x01, 0x05, + 0xa1, 0x0c, 0x32, 0x04, 0x67, 0xb0, 0x06, 0x16, 0x88, 0x81, 0xf8, 0x0f, + 0x32, 0x0c, 0x69, 0xc0, 0x06, 0x16, 0x80, 0x81, 0xf8, 0x0f, 0x32, 0x14, + 0x6b, 0xd0, 0x06, 0x16, 0x74, 0xe2, 0x3f, 0xc8, 0x70, 0xb4, 0x81, 0x1b, + 0x58, 0xa0, 0x89, 0xff, 0x20, 0xc3, 0x1e, 0xb8, 0xc1, 0x1c, 0x58, 0x16, + 0x88, 0xff, 0x20, 0x43, 0x1f, 0xc0, 0x01, 0x1d, 0x98, 0x13, 0x88, 0xbf, + 0x25, 0x03, 0xf8, 0x5b, 0xc0, 0x80, 0xbf, 0x05, 0x09, 0xf8, 0x5b, 0x80, + 0x80, 0xbf, 0x05, 0x05, 0xf8, 0xcf, 0x36, 0xd8, 0x41, 0x00, 0xcc, 0x36, + 0x04, 0xa4, 0x10, 0xcc, 0x36, 0x04, 0xa4, 0x20, 0x64, 0x10, 0x10, 0x03, + 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xf0, 0x83, 0x2d, 0xc3, 0x10, + 0xf8, 0xc1, 0x96, 0xe1, 0x08, 0xfc, 0x60, 0xcb, 0xc0, 0x04, 0x7e, 0xb0, + 0x65, 0x88, 0x02, 0x3f, 0xd8, 0x32, 0x58, 0x81, 0x1f, 0x6c, 0x19, 0xc6, + 0x20, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xa4, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, + 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x33, 0x31, 0x30, 0x30, 0x31, + 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, + 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, + 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x14, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x0c, 0x00, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, + 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, + 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, + 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, + 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, + 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x11, 0x22, 0xc4, 0x50, + 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, 0x46, 0x06, + 0x51, 0x18, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0x03, 0x40, 0x02, 0x28, 0x62, 0x1c, + 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, + 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, + 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, + 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, + 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, + 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, + 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, + 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, + 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, + 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, + 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, + 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, + 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, + 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, + 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, + 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, + 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, + 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, + 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, + 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, + 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, + 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, + 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, + 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, + 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, + 0xca, 0x01, 0xd8, 0x40, 0x08, 0x02, 0x60, 0x01, 0x49, 0x18, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, + 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, + 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x24, 0x33, 0x00, + 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x65, 0x08, 0x09, 0x9a, 0x81, + 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x1b, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, + 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, + 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, + 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, + 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, + 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, + 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, + 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, + 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, + 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, + 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, + 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, + 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x12, 0xdb, 0x95, 0x3f, 0xeb, 0x2c, 0xc8, + 0xf0, 0x17, 0x11, 0x60, 0x30, 0x44, 0x33, 0x0d, 0x89, 0x00, 0x69, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x89, 0x0d, + 0x02, 0x45, 0x99, 0x04, 0x00, 0x00, 0xb2, 0x40, 0x07, 0x00, 0x00, 0x00, + 0x32, 0x1e, 0x98, 0x0c, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, + 0xc6, 0x04, 0x43, 0xb2, 0x22, 0x28, 0x81, 0x42, 0x18, 0x01, 0xa0, 0x1b, + 0x4b, 0x70, 0x08, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x26, + 0xc8, 0x56, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, + 0x19, 0x52, 0xa6, 0x3c, 0x06, 0x83, 0x58, 0x05, 0x53, 0x44, 0x4b, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, + 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, + 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, + 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, @@ -807,231 +825,223 @@ const unsigned char sdl_metallib[] = { 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, - 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, - 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, - 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, - 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x63, 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x23, 0x08, - 0x46, 0x30, 0x82, 0x70, 0x1c, 0x23, 0x08, 0x86, 0x30, 0x82, 0x60, 0x0c, - 0x23, 0x08, 0x06, 0x31, 0x82, 0x40, 0x00, 0x23, 0x08, 0x46, 0x31, 0xc3, - 0x30, 0x05, 0xd4, 0x0c, 0x43, 0x25, 0x58, 0x33, 0x04, 0xc3, 0x0c, 0xc3, - 0x34, 0x5d, 0x33, 0x10, 0x44, 0x55, 0x5d, 0x33, 0x04, 0xc5, 0x0c, 0x81, - 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0xd7, 0x95, 0x28, 0x33, 0x04, 0x62, - 0x30, 0x03, 0x74, 0x2d, 0x4c, 0xd6, 0x5c, 0x95, 0xf3, 0x64, 0x50, 0x96, - 0x28, 0x91, 0x34, 0x43, 0x40, 0x06, 0x33, 0x0c, 0xd8, 0x18, 0x94, 0x81, - 0x8c, 0x04, 0x26, 0xe8, 0x22, 0x36, 0x36, 0xbb, 0x36, 0x97, 0xb6, 0x37, - 0xb2, 0x3a, 0xb6, 0x32, 0x17, 0x33, 0xb6, 0xb0, 0xb3, 0xb9, 0x51, 0x84, - 0x4c, 0x3b, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, - 0x6e, 0x94, 0x60, 0xbb, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x6d, 0x94, 0x80, 0x3b, 0x2a, 0x2c, 0x4d, 0xce, 0x85, - 0x2d, 0xcc, 0xed, 0xac, 0x2e, 0xec, 0xac, 0xec, 0xcb, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x6d, 0x94, 0xa0, 0xbb, 0x29, 0x2c, 0x4d, 0xce, 0x65, - 0xec, 0xad, 0x0d, 0x2e, 0x8d, 0xad, 0xec, 0xeb, 0x0d, 0x8e, 0x2e, 0xed, - 0xcd, 0x6d, 0x6e, 0x94, 0xc1, 0xfb, 0xc0, 0xe0, 0x98, 0xb0, 0x34, 0x39, - 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0x51, 0x82, 0x32, - 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, - 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, - 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, - 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, - 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, - 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, - 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x13, 0x04, - 0x41, 0x3c, 0x0c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, - 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, - 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, - 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, - 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, - 0xc4, 0xd8, 0x10, 0xa0, 0xc1, 0x86, 0xe1, 0x0c, 0xd4, 0x20, 0x0d, 0x36, - 0x0c, 0x6b, 0xb0, 0x06, 0x69, 0x00, 0x14, 0x44, 0xc9, 0x20, 0x20, 0x06, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x06, 0x20, 0x58, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xc6, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x1d, 0x00, - 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x44, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x39, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, - 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x79, 0x00, 0x00, - 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, - 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x33, 0x31, 0x30, 0x30, - 0x31, 0x2e, 0x34, 0x33, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, - 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, - 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x5c, 0x0c, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, - 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x0b, 0x02, - 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, - 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, - 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, - 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, - 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, - 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, - 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, - 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x1b, 0xcc, - 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, - 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, - 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, - 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, - 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, - 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, - 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, - 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, - 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, - 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, - 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, - 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, - 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, - 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, - 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, - 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, - 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, - 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, - 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, - 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, - 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, - 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, - 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, - 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, - 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, - 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, - 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, - 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, - 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, - 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, - 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, - 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, - 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, - 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, - 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, - 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, - 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x03, 0x90, 0x00, 0x0b, 0x50, - 0x05, 0x69, 0x00, 0x6d, 0x30, 0x06, 0x02, 0x58, 0x80, 0x6a, 0x83, 0x41, - 0x14, 0xc0, 0x02, 0x54, 0x1b, 0x94, 0xe2, 0xff, 0xff, 0xff, 0xff, 0x07, - 0xa0, 0x0d, 0x80, 0x35, 0x00, 0x24, 0xa0, 0xda, 0x60, 0x18, 0x01, 0xb0, - 0x00, 0xd5, 0x06, 0xe3, 0x10, 0x80, 0x05, 0xa8, 0x00, 0x00, 0x49, 0x18, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, 0x88, 0x09, - 0x43, 0x61, 0x1c, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x20, 0x00, - 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, - 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, - 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x54, 0x33, 0x00, 0xc3, 0x08, - 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, 0x08, 0x41, 0x70, 0x94, 0x34, 0x45, - 0x94, 0x30, 0xf9, 0xff, 0x44, 0x5c, 0x13, 0x15, 0x11, 0xbf, 0x3d, 0xfc, - 0xd3, 0x18, 0x01, 0x30, 0x88, 0x40, 0x04, 0x17, 0x49, 0x53, 0x44, 0x09, - 0x93, 0xff, 0x4b, 0x00, 0xf3, 0x2c, 0x44, 0xf4, 0x4f, 0x63, 0x04, 0xc0, - 0x20, 0x82, 0x21, 0x14, 0x23, 0x04, 0x31, 0xca, 0x21, 0x34, 0x47, 0x80, - 0x18, 0x21, 0xa8, 0x39, 0x82, 0x60, 0x8e, 0x00, 0x0c, 0x86, 0x11, 0x84, - 0xa6, 0x28, 0xab, 0x1c, 0xc1, 0x1c, 0x03, 0xa0, 0xd1, 0x1b, 0x08, 0x48, - 0x81, 0x36, 0x47, 0x00, 0x0a, 0x23, 0x00, 0x00, 0x00, 0x00, 0x13, 0xbe, - 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, - 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, - 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, - 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, - 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, - 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, - 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, - 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, - 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, - 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x38, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x76, + 0x32, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x61, + 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, + 0x76, 0x34, 0x5f, 0x66, 0x29, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, + 0x23, 0x08, 0x46, 0x30, 0x82, 0x70, 0x14, 0x23, 0x08, 0x86, 0x30, 0x82, + 0x60, 0x0c, 0x23, 0x08, 0x06, 0x31, 0x82, 0x40, 0x00, 0x33, 0x0c, 0x54, + 0x50, 0xcd, 0x30, 0x58, 0xc2, 0x35, 0x43, 0x30, 0xcc, 0x30, 0x50, 0x14, + 0x36, 0x03, 0x41, 0x58, 0x16, 0x36, 0x43, 0x50, 0xcc, 0x10, 0x18, 0x33, + 0x04, 0xc7, 0x0c, 0x05, 0x82, 0x61, 0x89, 0x32, 0x43, 0x20, 0x06, 0x33, + 0x24, 0xd8, 0xc2, 0x34, 0x4e, 0xf2, 0x40, 0xd1, 0x0c, 0x89, 0xb5, 0x48, + 0x8d, 0x93, 0x28, 0xd0, 0x34, 0x83, 0x40, 0x06, 0x65, 0x30, 0xc3, 0x90, + 0x8d, 0x81, 0x19, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, + 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, + 0x9b, 0x1b, 0x45, 0xc8, 0xb4, 0x53, 0xd8, 0xd8, 0xec, 0xda, 0x5c, 0xd2, + 0xc8, 0xca, 0xdc, 0xe8, 0x46, 0x09, 0xb6, 0x5b, 0xc2, 0xd2, 0xe4, 0x5c, + 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xb8, 0xa3, 0xc2, + 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, + 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xba, 0x9b, 0xc2, + 0xd2, 0xe4, 0x5c, 0xc6, 0xde, 0xda, 0xe0, 0xd2, 0xd8, 0xca, 0xbe, 0xde, + 0xe0, 0xe8, 0xd2, 0xde, 0xdc, 0xe6, 0x46, 0x19, 0xbc, 0x0f, 0x0c, 0x8e, + 0x09, 0x4b, 0x93, 0x73, 0x31, 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, 0xa3, + 0x1b, 0x25, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, + 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, + 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, + 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, + 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, + 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, + 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, + 0x84, 0x00, 0xc8, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x0c, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, + 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, + 0x69, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, + 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, + 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0xa2, 0x02, 0x00, 0x00, + 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, + 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, + 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, + 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, + 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, + 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, + 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, + 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, + 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, + 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, + 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, + 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, + 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, + 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, + 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, + 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, + 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, + 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, + 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, + 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, + 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, + 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, + 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, + 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, + 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, + 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, + 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, + 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, + 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, + 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, + 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, + 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, + 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, + 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, + 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, + 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, + 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, + 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, + 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, + 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0x60, 0x08, 0x04, 0xb0, 0x00, + 0xd5, 0x06, 0x63, 0x28, 0x80, 0x05, 0xa8, 0x36, 0x28, 0xc4, 0xff, 0xff, + 0xff, 0xff, 0x0f, 0x40, 0x1b, 0x00, 0x6b, 0x00, 0x48, 0x40, 0xb5, 0xc1, + 0x28, 0x02, 0x60, 0x01, 0xaa, 0x0d, 0x86, 0x21, 0x00, 0x0b, 0x50, 0x01, + 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, + 0x26, 0x0c, 0x44, 0x61, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, + 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, + 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x4c, 0x33, 0x00, + 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x47, 0x49, 0x53, 0x44, 0x09, + 0x93, 0xff, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0xc3, 0x3f, 0x8d, + 0x11, 0x00, 0x83, 0x08, 0x43, 0x70, 0x91, 0x34, 0x45, 0x94, 0x30, 0xf9, + 0xbf, 0x04, 0x30, 0xcf, 0x42, 0x44, 0xff, 0x34, 0x46, 0x00, 0x0c, 0x22, + 0x14, 0x42, 0x31, 0x42, 0x08, 0x82, 0x18, 0x3a, 0x73, 0x04, 0x88, 0x11, + 0x42, 0x9a, 0x23, 0x08, 0xe6, 0x08, 0xc0, 0x60, 0x18, 0x41, 0x60, 0x8a, + 0xa2, 0x88, 0x11, 0xab, 0x2d, 0x00, 0x18, 0xb9, 0x81, 0x80, 0x14, 0x60, + 0x23, 0x00, 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, + 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, + 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, + 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, + 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, - 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, - 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, - 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, - 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, - 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, - 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, - 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, - 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, - 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, - 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, - 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, - 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, - 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, - 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, - 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, - 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, - 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, - 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, - 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, - 0x11, 0xc2, 0x90, 0x11, 0xdb, 0x95, 0x3f, 0xe7, 0x3c, 0xd8, 0x5f, 0x44, - 0x80, 0xc1, 0x10, 0xcd, 0x34, 0x24, 0x02, 0x22, 0x04, 0x00, 0x80, 0x00, - 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x86, 0x44, 0xd1, 0xf6, 0x00, - 0x01, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0xc4, 0x06, - 0x81, 0xa2, 0xd2, 0x02, 0x00, 0x00, 0x59, 0x20, 0x00, 0x00, 0x09, 0x00, - 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, - 0x26, 0x47, 0xc6, 0x04, 0x43, 0x6a, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, - 0x50, 0x20, 0x65, 0x40, 0x73, 0x04, 0x80, 0xe4, 0x58, 0x82, 0x23, 0x00, - 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, - 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, - 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, - 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, - 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, - 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, - 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, - 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, - 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, - 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, - 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, - 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, - 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, - 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, - 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, - 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, - 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, - 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, - 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, - 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, - 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, - 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, - 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, - 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, - 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, - 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, - 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, - 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, - 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, - 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, - 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, - 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, - 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, - 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, - 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, - 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, - 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, - 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, - 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, - 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, - 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, - 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, - 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, - 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xc4, 0x80, 0x63, - 0x21, 0x00, 0x8b, 0xe2, 0x06, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, - 0x22, 0x31, 0x88, 0x94, 0x3d, 0x06, 0xa2, 0x3c, 0x12, 0x12, 0x5d, 0xc3, - 0xa2, 0x60, 0xc3, 0x72, 0x04, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, - 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, - 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, - 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, + 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, + 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, + 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, + 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, + 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, + 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x11, 0xdb, 0x95, + 0x3f, 0xe7, 0x3c, 0xd8, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x34, 0x24, + 0x02, 0xa2, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x86, 0x44, 0xd1, 0xe6, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x80, 0xc4, 0x06, 0x81, 0xa2, 0xa4, 0x02, 0x00, 0x00, + 0x59, 0x20, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, + 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x62, + 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x06, 0x14, 0xc7, 0x12, 0x1c, + 0x02, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x3c, + 0x2c, 0x77, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, + 0x19, 0x8c, 0x22, 0x31, 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0x8b, 0xa4, + 0x60, 0xc3, 0x72, 0x04, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, @@ -1050,588 +1060,565 @@ const unsigned char sdl_metallib[] = { 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, - 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, - 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, - 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, - 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, - 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, - 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, - 0x63, 0x6f, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, - 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, - 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, - 0x74, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x23, 0x08, - 0x8d, 0x30, 0x82, 0x20, 0x25, 0x23, 0x08, 0xcd, 0x30, 0x82, 0xd0, 0x10, - 0x23, 0x08, 0x4d, 0x31, 0x82, 0x90, 0x00, 0x23, 0x08, 0x8d, 0x31, 0x82, - 0xd0, 0x1c, 0x33, 0x0c, 0x63, 0x10, 0x90, 0xc1, 0x0c, 0x43, 0x19, 0x08, - 0x66, 0x30, 0x43, 0x30, 0xcc, 0x30, 0x8c, 0xc1, 0x18, 0x9c, 0xc1, 0x0c, - 0x04, 0x51, 0x06, 0x65, 0x70, 0x06, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, - 0x43, 0x70, 0xcc, 0x50, 0x20, 0x67, 0x70, 0x06, 0x89, 0x32, 0x43, 0x30, - 0x07, 0x33, 0x20, 0x67, 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0x49, - 0x19, 0x40, 0x11, 0x23, 0x25, 0x93, 0x43, 0xcd, 0x00, 0x8d, 0x41, 0x65, - 0xa5, 0xc1, 0x75, 0x06, 0x65, 0x80, 0x65, 0x69, 0xa0, 0xa5, 0x41, 0xa2, - 0x38, 0xdb, 0x0c, 0x8a, 0x1a, 0x70, 0xd7, 0x19, 0x94, 0x41, 0x97, 0x78, - 0xce, 0x37, 0x43, 0x62, 0x06, 0x60, 0x70, 0x9d, 0x41, 0x19, 0x24, 0x61, - 0xe0, 0x88, 0xc1, 0x0c, 0x45, 0x1d, 0xd8, 0xc1, 0x1d, 0xe0, 0x41, 0x1e, - 0xcc, 0x30, 0xa0, 0x01, 0x1d, 0xe8, 0x81, 0x8c, 0x04, 0x26, 0xe8, 0x22, - 0x36, 0x36, 0xbb, 0x36, 0x97, 0xb6, 0x37, 0xb2, 0x3a, 0xb6, 0x32, 0x17, - 0x33, 0xb6, 0xb0, 0xb3, 0xb9, 0x51, 0x04, 0x35, 0x58, 0x83, 0x53, 0xd8, - 0xd8, 0xec, 0xda, 0x5c, 0xd2, 0xc8, 0xca, 0xdc, 0xe8, 0x46, 0x09, 0xd8, - 0xe0, 0x96, 0xb0, 0x34, 0x39, 0x17, 0xbb, 0x32, 0xb9, 0xb9, 0xb4, 0x37, - 0xb7, 0x51, 0x82, 0x36, 0x38, 0x2a, 0x2c, 0x4d, 0xce, 0x85, 0x2d, 0xcc, - 0xed, 0xac, 0x2e, 0xec, 0xac, 0xec, 0xcb, 0xae, 0x4c, 0x6e, 0x2e, 0xed, - 0xcd, 0x6d, 0x94, 0xc0, 0x0d, 0x6e, 0x0a, 0x4b, 0x93, 0x73, 0x19, 0x7b, - 0x6b, 0x83, 0x4b, 0x63, 0x2b, 0xfb, 0x7a, 0x83, 0xa3, 0x4b, 0x7b, 0x73, - 0x9b, 0x1b, 0x65, 0x78, 0x03, 0x38, 0x88, 0x83, 0x63, 0xc2, 0xd2, 0xe4, - 0x5c, 0xcc, 0xe4, 0xc2, 0xce, 0xda, 0xca, 0xdc, 0xe8, 0x46, 0x09, 0xf4, - 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, - 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, - 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, - 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, - 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, - 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, - 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x13, 0x04, - 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xc4, 0x6a, - 0x60, 0x04, 0x80, 0xdc, 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0xf1, 0x30, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, - 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, - 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, - 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, - 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x84, 0x09, 0xd9, 0x10, 0xf4, - 0xc1, 0x86, 0x81, 0x0f, 0xfe, 0xc0, 0x0f, 0x36, 0x0c, 0xa0, 0x00, 0x0a, - 0x7e, 0x00, 0x23, 0x06, 0x8d, 0x10, 0x82, 0x60, 0xf0, 0x48, 0x46, 0x81, - 0x10, 0xc2, 0x10, 0x04, 0xce, 0x68, 0x42, 0x00, 0x50, 0x12, 0x8a, 0x09, - 0x81, 0xf8, 0x67, 0x10, 0x10, 0x03, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x06, - 0x21, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, - 0xac, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, - 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x20, 0x01, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, - 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1b, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x12, 0x03, - 0x94, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, - 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, - 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, - 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, - 0x33, 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x61, 0x69, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, + 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, + 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, + 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, + 0x23, 0x08, 0x8c, 0x30, 0x82, 0x10, 0x1d, 0x23, 0x08, 0xcc, 0x30, 0x82, + 0xc0, 0x10, 0x23, 0x08, 0x4c, 0x31, 0x82, 0x80, 0x00, 0x23, 0x08, 0x8c, + 0x31, 0xc3, 0xf0, 0x05, 0x60, 0x30, 0xc3, 0x10, 0x06, 0x82, 0x18, 0xcc, + 0x10, 0x0c, 0x33, 0x0c, 0xdf, 0x37, 0x06, 0x33, 0x10, 0x44, 0x18, 0x84, + 0xc1, 0x18, 0xcc, 0x10, 0x14, 0x33, 0x04, 0xc6, 0x0c, 0xc1, 0x31, 0x43, + 0x81, 0x8c, 0xc1, 0x18, 0x24, 0xca, 0x0c, 0x81, 0x1b, 0xcc, 0x80, 0x8c, + 0xc1, 0xc2, 0x34, 0x89, 0xe2, 0x3c, 0x33, 0x24, 0x61, 0x00, 0x45, 0x8c, + 0x94, 0x28, 0xce, 0x34, 0x43, 0xf2, 0x41, 0x14, 0x23, 0x25, 0x95, 0x63, + 0xcd, 0xa0, 0x94, 0xc1, 0x85, 0x8d, 0x41, 0x18, 0x64, 0x89, 0xe6, 0x6c, + 0x33, 0x24, 0x62, 0xc0, 0x61, 0x63, 0x10, 0x06, 0x49, 0xe7, 0x78, 0x33, + 0x14, 0x70, 0x10, 0x07, 0x72, 0x30, 0x07, 0x74, 0x30, 0xc3, 0x40, 0x06, + 0x6f, 0x50, 0x07, 0x32, 0x12, 0x98, 0xa0, 0x8b, 0xd8, 0xd8, 0xec, 0xda, + 0x5c, 0xda, 0xde, 0xc8, 0xea, 0xd8, 0xca, 0x5c, 0xcc, 0xd8, 0xc2, 0xce, + 0xe6, 0x46, 0x11, 0xca, 0xc0, 0x0c, 0x4e, 0x61, 0x63, 0xb3, 0x6b, 0x73, + 0x49, 0x23, 0x2b, 0x73, 0xa3, 0x1b, 0x25, 0x38, 0x83, 0x5b, 0xc2, 0xd2, + 0xe4, 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xd0, + 0xe0, 0xa8, 0xb0, 0x34, 0x39, 0x17, 0xb6, 0x30, 0xb7, 0xb3, 0xba, 0xb0, + 0xb3, 0xb2, 0x2f, 0xbb, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x51, 0x82, + 0x34, 0xb8, 0x29, 0x2c, 0x4d, 0xce, 0x65, 0xec, 0xad, 0x0d, 0x2e, 0x8d, + 0xad, 0xec, 0xeb, 0x0d, 0x8e, 0x2e, 0xed, 0xcd, 0x6d, 0x6e, 0x94, 0x41, + 0x0d, 0xd6, 0x80, 0x0d, 0x8e, 0x09, 0x4b, 0x93, 0x73, 0x31, 0x93, 0x0b, + 0x3b, 0x6b, 0x2b, 0x73, 0xa3, 0x1b, 0x25, 0xa8, 0x03, 0x00, 0x00, 0x00, + 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, + 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, + 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, + 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, + 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, + 0x61, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, + 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb4, 0x6a, 0x60, 0x04, + 0x80, 0xda, 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8d, 0x10, + 0x82, 0x60, 0xe0, 0x40, 0x46, 0x71, 0x10, 0xc2, 0x10, 0x04, 0xcc, 0x68, + 0x42, 0x00, 0x58, 0xa0, 0x88, 0x7f, 0x06, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0x96, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x20, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xb5, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, + 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, + 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, - 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, - 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x0f, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, - 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x6a, 0x03, - 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, - 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, - 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, - 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4, 0x10, - 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48, 0x90, - 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, - 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, - 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x93, 0x00, - 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, - 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, - 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, - 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, - 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, - 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, - 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, - 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, - 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, - 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, - 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, - 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, - 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, - 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, - 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, - 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, - 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, - 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, - 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, - 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, - 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, - 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, - 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, - 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, - 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, - 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, - 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, - 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, - 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, - 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, - 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, - 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, - 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, - 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0xb8, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x0c, 0x00, 0x00, 0x4f, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, + 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, + 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, + 0x42, 0x92, 0x0b, 0x42, 0xc4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, + 0x0a, 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, + 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, + 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, + 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, + 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, + 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, + 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, + 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, + 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, + 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, + 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, + 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, + 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, + 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, + 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, + 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, + 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, - 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, - 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, - 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x03, - 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, 0x00, 0x6d, 0x58, 0x06, 0x02, 0x48, - 0x80, 0x05, 0xa8, 0x82, 0x34, 0x00, 0x85, 0x0d, 0x06, 0x51, 0x00, 0x0b, - 0x50, 0x6d, 0x30, 0x8a, 0x03, 0x58, 0x80, 0x6a, 0x83, 0x61, 0xfc, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x48, 0x00, 0xb5, 0x41, 0x39, 0xfe, 0xff, 0xff, - 0xff, 0x7f, 0x00, 0xda, 0x00, 0x58, 0x03, 0x40, 0x02, 0xaa, 0x0d, 0x06, - 0x12, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x12, 0x01, 0x58, 0x80, 0x0a, 0x00, - 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, - 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, - 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x32, 0x22, - 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x23, 0xa4, 0x84, 0x04, 0x13, - 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8c, 0x8c, 0x0b, 0x84, - 0xc4, 0x4c, 0x10, 0x84, 0xc1, 0x0c, 0xc0, 0x30, 0x02, 0x01, 0x0c, 0x23, - 0x08, 0xc0, 0x20, 0x42, 0x10, 0x0c, 0x23, 0x0c, 0xc0, 0x41, 0xd2, 0x14, - 0x51, 0xc2, 0xe4, 0xcb, 0xee, 0xdb, 0x11, 0x82, 0x33, 0x10, 0x88, 0x20, - 0x08, 0x82, 0x18, 0x44, 0x28, 0x84, 0xa3, 0xa4, 0x29, 0xa2, 0x84, 0xc9, - 0xff, 0x27, 0xe2, 0x9a, 0xa8, 0x88, 0xf8, 0xed, 0xe1, 0x9f, 0xc6, 0x08, - 0x80, 0x41, 0x84, 0x23, 0x38, 0x4d, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x7f, - 0x22, 0xae, 0x89, 0x8a, 0x88, 0xdf, 0x1e, 0x7e, 0x20, 0x8a, 0x00, 0xec, - 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, 0x24, 0xb8, 0x48, 0x9a, 0x22, 0x4a, - 0x98, 0xfc, 0x5f, 0x02, 0x98, 0x67, 0x21, 0xa2, 0x7f, 0x1a, 0x23, 0x00, - 0x06, 0x11, 0x16, 0xa1, 0x20, 0x41, 0x20, 0x0c, 0x06, 0xa2, 0x30, 0xd4, - 0x94, 0x01, 0x20, 0x08, 0x7a, 0xe6, 0x08, 0x10, 0x23, 0x04, 0xd1, 0x1c, - 0x01, 0x18, 0xcc, 0x11, 0x04, 0xc3, 0x08, 0xc2, 0x54, 0x16, 0x49, 0x61, - 0x84, 0x89, 0xaa, 0x28, 0x00, 0x98, 0xc8, 0x2a, 0x8a, 0x84, 0x30, 0x02, - 0x55, 0x51, 0x00, 0x30, 0x11, 0x36, 0x10, 0x90, 0x02, 0xd3, 0x30, 0xc2, - 0x30, 0xcd, 0x11, 0x80, 0xc2, 0x20, 0x42, 0x20, 0x0c, 0x22, 0x10, 0xc2, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, - 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, - 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, - 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, - 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, - 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, - 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, - 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, - 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, - 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, - 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, - 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, - 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, - 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, - 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, - 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x10, - 0xdb, 0x95, 0xbf, 0xec, 0xbe, 0x7f, 0x11, 0x01, 0x06, 0x43, 0x34, 0xd3, - 0x90, 0x08, 0x80, 0x1a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x18, 0x12, 0x41, 0xcd, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x43, 0xa2, 0x2e, 0x0c, 0x2c, 0x20, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x12, 0xf9, 0xc1, - 0x86, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, - 0xc4, 0x06, 0x81, 0xa2, 0x6c, 0x03, 0x00, 0x00, 0x59, 0x20, 0x0b, 0x00, - 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, - 0x26, 0x47, 0xc6, 0x04, 0x43, 0x9a, 0x8a, 0xa0, 0x04, 0x0a, 0x61, 0x04, - 0xa0, 0x40, 0xca, 0xa0, 0x00, 0x03, 0x0a, 0xa8, 0xc0, 0x4a, 0xa1, 0x18, - 0xa8, 0x1b, 0x01, 0xa0, 0x6d, 0x2c, 0xc1, 0x11, 0x00, 0x00, 0xb1, 0x18, - 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, - 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, - 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, - 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, - 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, - 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, - 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, - 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, - 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, - 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, - 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, - 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, - 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, - 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, - 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, - 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, - 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, - 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, - 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, - 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, - 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, - 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, - 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, - 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, - 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, - 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, - 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, - 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, - 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, - 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, - 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, - 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, - 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, - 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, - 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, - 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, - 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, - 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, - 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0x0c, 0x01, - 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, - 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xd8, 0x80, 0x0c, 0xf2, 0x09, 0x8b, 0xe2, - 0x06, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, 0x88, 0x94, - 0x3d, 0x06, 0xa2, 0x3c, 0x12, 0x12, 0x5d, 0x03, 0x65, 0x18, 0x86, 0x61, - 0x24, 0xc6, 0xa2, 0x60, 0x84, 0x57, 0x2c, 0x47, 0x00, 0x00, 0x53, 0x44, - 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, - 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, - 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x20, 0x28, - 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, - 0x31, 0x2e, 0x34, 0x33, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, - 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, - 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, + 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, + 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, + 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, + 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, + 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, + 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, + 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, + 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, + 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, + 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, + 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, + 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, + 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x04, 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, + 0x00, 0x0a, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x07, + 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, + 0x00, 0x6a, 0x83, 0x62, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x00, 0xb4, 0x01, + 0xb0, 0x06, 0x80, 0x04, 0x54, 0x1b, 0x8c, 0x23, 0x00, 0x16, 0xa0, 0xda, + 0x60, 0x20, 0x02, 0xb0, 0x00, 0x15, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, 0x88, 0x09, 0x41, 0x31, + 0x61, 0x30, 0x0e, 0x04, 0x89, 0x20, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x23, 0xa4, 0x84, + 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8c, 0x8c, + 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x80, 0xc1, 0x0c, 0xc0, 0x30, 0x02, 0x01, + 0x0c, 0x23, 0x08, 0xc0, 0x30, 0xc2, 0x00, 0x1c, 0x24, 0x4d, 0x11, 0x25, + 0x4c, 0xbe, 0xec, 0xbe, 0x1d, 0x21, 0x38, 0x03, 0x81, 0x88, 0x61, 0x18, + 0x86, 0x41, 0x04, 0x42, 0x38, 0x4a, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x7f, + 0x22, 0xae, 0x89, 0x8a, 0x88, 0xdf, 0x1e, 0xfe, 0x69, 0x8c, 0x00, 0x18, + 0x44, 0x30, 0x82, 0xd3, 0xa4, 0x29, 0xa2, 0x84, 0xc9, 0xff, 0x27, 0xe2, + 0x9a, 0xa8, 0x88, 0xf8, 0xed, 0xe1, 0x07, 0xa2, 0x08, 0xc0, 0xfe, 0x69, + 0x8c, 0x00, 0x18, 0x44, 0x40, 0x82, 0x8b, 0xa4, 0x29, 0xa2, 0x84, 0xc9, + 0xff, 0x25, 0x80, 0x79, 0x16, 0x22, 0xfa, 0xa7, 0x31, 0x02, 0x60, 0x10, + 0x41, 0x11, 0x0a, 0x12, 0x04, 0x81, 0x50, 0x1c, 0xc9, 0x42, 0x4c, 0x19, + 0x80, 0x61, 0x20, 0x67, 0x8e, 0x00, 0x31, 0x42, 0x00, 0xcd, 0x11, 0x80, + 0xc1, 0x1c, 0x41, 0x30, 0x8c, 0x20, 0x48, 0x65, 0x89, 0x92, 0x45, 0x90, + 0x26, 0x6a, 0x02, 0x00, 0x89, 0xaa, 0xa2, 0x44, 0xc7, 0x22, 0x4c, 0xd4, + 0x04, 0x00, 0x12, 0x5d, 0x03, 0x01, 0x29, 0x20, 0x0d, 0x23, 0x0c, 0xd2, + 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x04, 0xc2, 0x20, 0xc2, 0x20, 0x8c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, + 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, + 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, + 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, + 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, + 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, + 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, + 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, + 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, + 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x10, 0xdb, 0x95, + 0xbf, 0xec, 0xbe, 0x7f, 0x11, 0x01, 0x06, 0x43, 0x34, 0xd3, 0x90, 0x08, + 0x80, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x18, 0x12, 0x41, 0x8d, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x43, 0xa2, 0x2e, 0x0c, 0x2a, 0x20, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x12, 0xf9, 0xc1, 0x76, 0x01, + 0x01, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0xc4, 0x06, + 0x81, 0xa2, 0x51, 0x03, 0x00, 0x00, 0x59, 0x20, 0x0a, 0x00, 0x00, 0x00, + 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, + 0xc6, 0x04, 0x43, 0x92, 0x8a, 0xa0, 0x04, 0x0a, 0x61, 0x04, 0xa0, 0x0c, + 0x0a, 0x30, 0xa0, 0x40, 0x0a, 0xa8, 0xc0, 0x4a, 0xa1, 0x18, 0x48, 0x1b, + 0x4b, 0x70, 0x08, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xda, + 0x80, 0x0c, 0x66, 0x0a, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, + 0x19, 0x8c, 0x22, 0x31, 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0xca, 0x23, + 0x21, 0x94, 0x61, 0x18, 0x86, 0x11, 0x5d, 0x89, 0xb1, 0x28, 0x18, 0xe1, + 0x15, 0xcb, 0x11, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, + 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, + 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, + 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, - 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, - 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, - 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e, - 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, - 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, - 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, - 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x6e, - 0x6f, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, - 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, - 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, - 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, - 0x32, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, - 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, - 0x32, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, - 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, - 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, - 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, - 0x73, 0x69, 0x7a, 0x65, 0x63, 0x6f, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x73, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, - 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, - 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, - 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x59, 0x55, 0x56, - 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, - 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, - 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, - 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, - 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, - 0x59, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x5f, 0x61, - 0x72, 0x72, 0x61, 0x79, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, - 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x55, 0x56, - 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0x64, 0x78, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x30, 0x11, 0x23, 0x08, - 0x1b, 0x34, 0x82, 0x30, 0x15, 0x23, 0x08, 0x93, 0x31, 0x82, 0x30, 0x1d, - 0x23, 0x08, 0x0e, 0x30, 0x82, 0x30, 0x21, 0x23, 0x08, 0x53, 0x32, 0x82, - 0x30, 0x29, 0x23, 0x08, 0xd3, 0x32, 0x82, 0x30, 0x31, 0x23, 0x08, 0x53, - 0x33, 0x82, 0x30, 0x39, 0x33, 0x0c, 0x6d, 0x10, 0xb8, 0xc1, 0x0c, 0xc3, - 0x1b, 0x08, 0x70, 0x30, 0x43, 0x30, 0xcc, 0x30, 0xb4, 0x41, 0x1b, 0xc4, - 0xc1, 0x0c, 0x04, 0xf1, 0x06, 0x6f, 0x10, 0x07, 0x33, 0x04, 0xc5, 0x0c, - 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x71, 0x10, 0x07, 0x89, 0x32, - 0x43, 0x20, 0x0a, 0x33, 0x20, 0x71, 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, - 0x0c, 0xc9, 0x1b, 0x40, 0x11, 0x23, 0x25, 0x93, 0x43, 0xcd, 0x00, 0xb5, - 0x41, 0x65, 0xcd, 0xc1, 0x15, 0x07, 0x6f, 0x80, 0x65, 0x73, 0xa0, 0xcd, - 0x41, 0xa2, 0x38, 0xdb, 0x0c, 0x54, 0x1c, 0xcc, 0x41, 0x1c, 0x74, 0xde, - 0x1c, 0xcc, 0x41, 0x1c, 0x74, 0x9f, 0x1d, 0xcc, 0x41, 0x1c, 0x74, 0x60, - 0x70, 0x07, 0x73, 0x10, 0x07, 0x5d, 0x18, 0xcc, 0x20, 0xd1, 0x41, 0x65, - 0xd5, 0xc1, 0xf5, 0x06, 0x6f, 0x80, 0x71, 0xa7, 0x90, 0xd5, 0x81, 0x36, - 0x07, 0x89, 0x18, 0x38, 0x63, 0x30, 0x83, 0x02, 0x07, 0x64, 0x70, 0xc5, - 0xc1, 0x1b, 0x94, 0x41, 0x62, 0x06, 0xce, 0x19, 0xcc, 0xa0, 0xe0, 0x01, - 0x19, 0x5c, 0x6f, 0xf0, 0x06, 0x65, 0x90, 0xa0, 0x81, 0x93, 0x06, 0x33, - 0x24, 0x79, 0xa0, 0x06, 0x57, 0x1c, 0xbc, 0x41, 0xb2, 0x06, 0x0e, 0x1b, - 0xcc, 0x70, 0x90, 0x42, 0x29, 0x98, 0x02, 0x2a, 0xa4, 0x82, 0x2a, 0xac, - 0xc2, 0x0c, 0x83, 0x1c, 0x8c, 0x02, 0x2b, 0x54, 0x18, 0x00, 0x1c, 0xc7, - 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x9c, 0x1b, 0xb8, 0x81, 0x45, - 0x07, 0x7a, 0x60, 0x59, 0x96, 0x1e, 0x70, 0xa6, 0xc0, 0x0a, 0x34, 0xc1, - 0x1b, 0x72, 0x61, 0x0f, 0xf6, 0xa0, 0x0e, 0xe4, 0x20, 0x23, 0x81, 0x09, - 0xba, 0x88, 0x8d, 0xcd, 0xae, 0xcd, 0xa5, 0xed, 0x8d, 0xac, 0x8e, 0xad, - 0xcc, 0xc5, 0x8c, 0x2d, 0xec, 0x6c, 0x6e, 0x14, 0x21, 0x0f, 0xf4, 0xe0, - 0x14, 0x36, 0x36, 0xbb, 0x36, 0x97, 0x34, 0xb2, 0x32, 0x37, 0xba, 0x51, - 0x82, 0x3d, 0xb8, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x6e, 0x2e, - 0xed, 0xcd, 0x6d, 0x94, 0x80, 0x0f, 0x8e, 0x0a, 0x4b, 0x93, 0x73, 0x61, - 0x0b, 0x73, 0x3b, 0xab, 0x0b, 0x3b, 0x2b, 0xfb, 0xb2, 0x2b, 0x93, 0x9b, - 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0xe8, 0x83, 0x9b, 0xc2, 0xd2, 0xe4, 0x5c, - 0xc6, 0xde, 0xda, 0xe0, 0xd2, 0xd8, 0xca, 0xbe, 0xde, 0xe0, 0xe8, 0xd2, - 0xde, 0xdc, 0xe6, 0x46, 0x19, 0xfc, 0xe0, 0x0f, 0x40, 0xe1, 0x98, 0xb0, - 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0x51, - 0x02, 0x56, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, - 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, - 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, - 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, - 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, - 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, - 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, - 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x5b, 0x00, - 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0x00, 0x00, 0x34, 0xcd, 0x00, 0x10, 0x55, 0x03, 0x23, 0x00, 0x54, 0x8d, - 0x00, 0x10, 0x37, 0xd6, 0x00, 0x04, 0xc2, 0x1c, 0xc3, 0x81, 0x61, 0xd4, - 0x95, 0x40, 0x11, 0x10, 0x30, 0x02, 0x30, 0x03, 0x30, 0x46, 0x00, 0x82, + 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x6e, 0x6f, 0x5f, 0x70, 0x65, + 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, + 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, + 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, + 0x69, 0x72, 0x2e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x33, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, + 0x66, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, + 0x66, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, + 0x64, 0x65, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, + 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x59, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, + 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, 0x72, 0x2e, + 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x72, 0x73, 0x00, 0x44, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x82, 0x20, 0x11, 0x23, 0x08, 0xda, 0x33, 0x82, 0x20, 0x15, 0x23, + 0x08, 0x92, 0x31, 0x82, 0x20, 0x1d, 0x23, 0x08, 0x0d, 0x30, 0x82, 0x20, + 0x21, 0x23, 0x08, 0x52, 0x32, 0x82, 0x20, 0x29, 0x23, 0x08, 0xd2, 0x32, + 0x82, 0x20, 0x31, 0x23, 0x08, 0x52, 0x33, 0x82, 0x20, 0x39, 0x33, 0x0c, + 0x6e, 0x10, 0xbc, 0xc1, 0x0c, 0x03, 0x1c, 0x08, 0x71, 0x30, 0x43, 0x30, + 0xcc, 0x30, 0xb8, 0x81, 0x1b, 0xc8, 0xc1, 0x0c, 0x04, 0x01, 0x07, 0x70, + 0x20, 0x07, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, + 0x20, 0x72, 0x20, 0x07, 0x89, 0x32, 0x43, 0x30, 0x0a, 0x33, 0x20, 0x72, + 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0x09, 0x1c, 0x40, 0x11, 0x23, + 0x25, 0x8a, 0x33, 0xcd, 0x90, 0xb8, 0x01, 0x44, 0x31, 0x52, 0x52, 0x39, + 0xd6, 0x0c, 0x94, 0x1c, 0xd8, 0x81, 0x1c, 0x70, 0x9d, 0x1d, 0xd8, 0x81, + 0x1c, 0x70, 0xde, 0x1d, 0xd8, 0x81, 0x1c, 0x70, 0x1f, 0x1e, 0xd8, 0x81, + 0x1c, 0x70, 0x60, 0x30, 0x83, 0x44, 0x07, 0x17, 0x56, 0x07, 0x19, 0x1c, + 0xc0, 0x81, 0xb6, 0xa1, 0x42, 0x18, 0xd4, 0x81, 0x18, 0xd8, 0x41, 0x32, + 0x06, 0x0e, 0x19, 0xcc, 0xa0, 0xc4, 0x41, 0x19, 0x64, 0x72, 0x00, 0x07, + 0x66, 0x90, 0x9c, 0x81, 0x83, 0x06, 0x33, 0x28, 0x79, 0x50, 0x06, 0x19, + 0x1c, 0xc0, 0x81, 0x19, 0x24, 0x69, 0xe0, 0xa8, 0xc1, 0x0c, 0x89, 0x1e, + 0xac, 0x41, 0x26, 0x07, 0x70, 0x90, 0xb0, 0x81, 0xd3, 0x06, 0x33, 0x1c, + 0xa5, 0x60, 0x0a, 0xa7, 0x90, 0x0a, 0xaa, 0xb0, 0x0a, 0xac, 0x30, 0xc3, + 0x30, 0x07, 0xa4, 0xd0, 0x0a, 0x15, 0x06, 0x00, 0xc7, 0x71, 0x1c, 0xc7, + 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xe7, 0x06, 0x6e, 0x60, 0xd1, 0x81, 0x1e, + 0x58, 0x96, 0xa5, 0x07, 0x9c, 0x29, 0xb0, 0x02, 0x2b, 0xd8, 0x86, 0x5f, + 0xd8, 0x83, 0x3d, 0xa8, 0x03, 0x39, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, + 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, + 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0xd0, 0x83, 0x3d, 0x38, 0x85, 0x8d, + 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x80, 0x0f, + 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, + 0x1b, 0x25, 0xe8, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, + 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, + 0xdc, 0x46, 0x09, 0xfc, 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, + 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, + 0xb9, 0x51, 0x86, 0x3f, 0x00, 0x85, 0x50, 0x38, 0x26, 0x2c, 0x4d, 0xce, + 0xc5, 0x4c, 0x2e, 0xec, 0xac, 0xad, 0xcc, 0x8d, 0x6e, 0x94, 0xa0, 0x15, + 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x24, 0xcd, 0x00, 0xd0, 0x54, 0x03, 0x23, 0x00, 0x44, 0x8d, 0x00, 0xd0, + 0x36, 0xd6, 0x00, 0x04, 0xc2, 0x1c, 0xc3, 0x71, 0x5d, 0xc4, 0x8d, 0x00, + 0x94, 0x40, 0x11, 0x10, 0x30, 0x02, 0x30, 0x03, 0x30, 0x46, 0x00, 0x82, 0x20, 0x88, 0x7f, 0x14, 0xcc, 0x00, 0xcc, 0x41, 0x84, 0x41, 0x18, 0x84, - 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, - 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, - 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, - 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, - 0x00, 0x00, 0x13, 0x84, 0xee, 0xd9, 0x10, 0xbc, 0xc2, 0x86, 0xc1, 0x15, - 0x62, 0x01, 0x16, 0x36, 0x0c, 0xb2, 0x20, 0x0b, 0xb0, 0x00, 0x23, 0x06, - 0xcd, 0x10, 0x82, 0x60, 0x80, 0x89, 0x01, 0xe4, 0x4c, 0x8c, 0xb2, 0x14, - 0x85, 0x37, 0x9a, 0x10, 0x00, 0x83, 0x0c, 0x01, 0xa1, 0x8c, 0x18, 0x38, - 0x43, 0x08, 0x82, 0x81, 0x65, 0x06, 0x52, 0x64, 0x85, 0xc1, 0xd3, 0x38, - 0x08, 0x12, 0x06, 0xa3, 0x09, 0x01, 0x30, 0x86, 0x10, 0x6c, 0x73, 0x0c, - 0x44, 0xd0, 0x8c, 0x18, 0x38, 0x43, 0x08, 0x82, 0x81, 0xa5, 0x06, 0x56, - 0xa5, 0x9d, 0xc1, 0x14, 0x49, 0x0c, 0x53, 0x06, 0xa3, 0x09, 0x01, 0x30, - 0x86, 0x10, 0x7c, 0x73, 0x0c, 0x44, 0x00, 0x1d, 0xe7, 0x2d, 0x05, 0x41, - 0x19, 0x64, 0x08, 0x1e, 0xcb, 0x88, 0x00, 0xfc, 0x29, 0x0c, 0x82, 0xb2, - 0x8b, 0x21, 0x0c, 0xcc, 0x00, 0x0e, 0x2e, 0xf0, 0x96, 0x82, 0xa0, 0x0c, - 0x32, 0x04, 0x15, 0x37, 0x62, 0x70, 0x08, 0x21, 0x08, 0x16, 0xfe, 0xf1, - 0xe0, 0x81, 0x11, 0xec, 0x62, 0x30, 0x83, 0x35, 0xb0, 0x83, 0x0b, 0xbc, - 0xa5, 0x20, 0x28, 0x83, 0x0c, 0x81, 0x16, 0x06, 0x23, 0x06, 0x87, 0x10, - 0x82, 0x60, 0xe1, 0x1f, 0x4f, 0x1f, 0x2c, 0xc1, 0x2e, 0x86, 0x35, 0x80, - 0x03, 0x3b, 0xb8, 0xc0, 0x5b, 0x0a, 0x82, 0x32, 0xc8, 0x10, 0x7c, 0x66, - 0x30, 0x62, 0x70, 0x08, 0x21, 0x08, 0x16, 0xfe, 0xf1, 0x88, 0x02, 0x14, - 0xcc, 0x31, 0x80, 0xc1, 0xd2, 0x07, 0x73, 0x0c, 0xc1, 0x01, 0x0a, 0x73, - 0x0c, 0xc1, 0x20, 0x0a, 0x16, 0x4c, 0xe2, 0x9f, 0x41, 0x40, 0x0c, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x27, 0x90, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0x8f, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x2f, 0x00, - 0x00, 0x00, 0x12, 0x03, 0x94, 0x70, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x44, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x1f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, - 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x1b, 0x00, - 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, - 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x20, 0x01, 0x00, - 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, - 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x64, 0x6f, - 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, - 0x65, 0x5f, 0x32, 0x64, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x76, - 0x34, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, - 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, - 0x2e, 0x34, 0x33, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, - 0x6c, 0x65, 0x2d, 0x69, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, - 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, - 0x00, 0x00, 0x74, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, - 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, - 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, - 0x00, 0x00, 0x4d, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, - 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, - 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, - 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, - 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, - 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, - 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, - 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, - 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, - 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, - 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, - 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, - 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, - 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, - 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, - 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, - 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, - 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, - 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, - 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, - 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, - 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, - 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, - 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, - 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, - 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, - 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, - 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, - 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, - 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, - 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, - 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, - 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, - 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, - 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, - 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, - 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, - 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, - 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, - 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, - 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, - 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, - 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, - 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, - 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, - 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, - 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, - 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, - 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, - 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, - 0xd8, 0xb0, 0x08, 0x03, 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, 0x00, 0x6d, - 0x58, 0x06, 0x02, 0x48, 0x80, 0x05, 0xa8, 0x82, 0x34, 0x00, 0x85, 0x0d, - 0x06, 0x51, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x0a, 0x03, 0x58, 0x80, 0x6a, - 0x83, 0x61, 0x1c, 0xc0, 0x02, 0x54, 0x1b, 0x8c, 0xe3, 0xff, 0xff, 0xff, - 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x0a, 0xf2, 0xff, 0xff, 0xff, 0xff, - 0x03, 0xd0, 0x06, 0xc0, 0x1a, 0x00, 0x12, 0x50, 0x6d, 0x30, 0x92, 0x00, - 0x58, 0x80, 0x6a, 0x83, 0xa1, 0x08, 0xc0, 0x02, 0x54, 0x00, 0x49, 0x18, - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8c, 0x40, 0x18, 0x88, 0xc2, - 0x98, 0x10, 0x1c, 0x13, 0x06, 0x24, 0x51, 0x00, 0x00, 0x00, 0x89, 0x20, - 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, - 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, - 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x74, - 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, 0x08, 0x41, - 0x30, 0x8c, 0x30, 0x00, 0x07, 0x49, 0x53, 0x44, 0x09, 0x93, 0x2f, 0xbb, - 0x6f, 0x47, 0x08, 0xce, 0x40, 0x20, 0x82, 0x10, 0x42, 0x06, 0x11, 0x0a, - 0xe1, 0x28, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, 0x26, 0x2a, - 0x22, 0x7e, 0x7b, 0xf8, 0xa7, 0x31, 0x02, 0x60, 0x10, 0xe1, 0x08, 0x2e, - 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x97, 0x00, 0xe6, 0x59, 0x88, 0xe8, - 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, 0x44, 0x28, 0x48, 0x08, 0x62, 0x18, - 0x84, 0x14, 0xad, 0x32, 0x00, 0x42, 0xa8, 0xcd, 0x11, 0x20, 0x46, 0x08, - 0x6f, 0x8e, 0x20, 0x98, 0x23, 0x00, 0x83, 0x61, 0x04, 0x41, 0x2a, 0x0a, - 0x44, 0x4a, 0xc4, 0x19, 0x01, 0x90, 0x44, 0x07, 0x02, 0x52, 0x40, 0x0e, - 0x23, 0x0c, 0xd2, 0x20, 0x42, 0x20, 0xcc, 0x11, 0x80, 0xc2, 0x20, 0x02, - 0x21, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, - 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, - 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, - 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, - 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, - 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, - 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, - 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, - 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, - 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, - 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, - 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, - 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, - 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, - 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, - 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x11, - 0xdb, 0x95, 0xff, 0xf9, 0xd6, 0xf6, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, - 0x34, 0x24, 0x02, 0xa2, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x86, 0x44, 0x51, 0xd3, 0x00, 0x01, 0x20, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc8, 0xdb, 0x28, 0x20, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0xd8, 0x20, 0x50, - 0xf4, 0x69, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x0b, 0x00, - 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, - 0x26, 0x47, 0xc6, 0x04, 0x43, 0x92, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, - 0x50, 0x20, 0x65, 0x50, 0x80, 0x01, 0x05, 0x54, 0x60, 0xa5, 0x50, 0x0c, - 0xa4, 0x47, 0x00, 0xe8, 0x8e, 0x25, 0x38, 0x02, 0x00, 0x00, 0xb1, 0x18, - 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, - 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, - 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, - 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, - 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, - 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, - 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, - 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, - 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, - 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, - 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, - 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, - 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, - 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, - 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, - 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, - 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, - 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, - 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, - 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, - 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, - 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, - 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, - 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, - 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, - 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, - 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, - 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, - 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, - 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, - 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, - 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, - 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, - 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, - 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, - 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, - 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, - 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, - 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0x04, 0x01, - 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, - 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xd6, 0x80, 0x0c, 0x76, 0x09, 0x8b, 0xe2, - 0x06, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, 0x88, 0x94, - 0x3d, 0x06, 0xa2, 0x3c, 0x12, 0x12, 0x5d, 0x03, 0x65, 0x18, 0x86, 0x61, - 0x24, 0xc6, 0xa2, 0x60, 0x44, 0xb1, 0x1c, 0x01, 0x00, 0x00, 0x53, 0x44, - 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, - 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, - 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x20, 0x28, - 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, - 0x31, 0x2e, 0x34, 0x33, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, + 0x81, 0x18, 0x00, 0x00, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x70, 0x89, + 0x41, 0xf4, 0x4c, 0xcd, 0xc2, 0x14, 0x85, 0x37, 0x9a, 0x10, 0x00, 0x83, + 0x0c, 0x01, 0xb1, 0x8c, 0x18, 0x38, 0x43, 0x08, 0x82, 0x41, 0x65, 0x06, + 0x93, 0x64, 0x85, 0x01, 0xe4, 0x3c, 0x08, 0x12, 0x06, 0xa3, 0x09, 0x01, + 0x30, 0x86, 0x10, 0x34, 0x73, 0x0c, 0x44, 0xd0, 0x8c, 0x18, 0x38, 0x43, + 0x08, 0x82, 0x41, 0xa5, 0x06, 0x97, 0xa5, 0x9d, 0x01, 0x25, 0x4d, 0x0c, + 0x53, 0x06, 0xa3, 0x09, 0x01, 0x30, 0x86, 0x10, 0x44, 0x73, 0x0c, 0x44, + 0x00, 0x5d, 0xd7, 0x2d, 0x05, 0x41, 0x19, 0x64, 0x08, 0x9e, 0xcb, 0x88, + 0x00, 0xfc, 0x37, 0x31, 0x84, 0xc1, 0xf5, 0x06, 0x17, 0x74, 0x4b, 0x41, + 0x50, 0x06, 0x19, 0x02, 0x8a, 0x1b, 0x31, 0x38, 0x84, 0x10, 0x04, 0x0b, + 0xff, 0x70, 0xee, 0xa0, 0x08, 0x36, 0x31, 0x98, 0x01, 0x57, 0x07, 0x17, + 0x74, 0x4b, 0x41, 0x50, 0x06, 0x19, 0x82, 0x2c, 0x0c, 0x46, 0x0c, 0x0e, + 0x21, 0x04, 0xc1, 0xc2, 0x3f, 0x1c, 0x3e, 0x50, 0x82, 0x4d, 0x0c, 0x6b, + 0x10, 0x06, 0x76, 0x70, 0x41, 0xb7, 0x14, 0x04, 0x65, 0x90, 0x21, 0xf0, + 0xcc, 0x60, 0xc4, 0xe0, 0x10, 0x42, 0x10, 0x2c, 0xfc, 0xc3, 0x09, 0x85, + 0x27, 0x98, 0x63, 0xf8, 0x16, 0x3e, 0x98, 0x63, 0x08, 0x8e, 0x3f, 0x98, + 0x63, 0x08, 0x86, 0x50, 0xb0, 0xa0, 0x0e, 0xc4, 0x3f, 0x03, 0x00, 0x00, + 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, + 0x84, 0x00, 0x8d, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x0c, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x70, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, + 0x3e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x22, 0x01, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x69, 0x72, 0x2e, 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, + 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, + 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x5f, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x61, 0x69, + 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, + 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, + 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, + 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, + 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x0c, 0x00, 0x00, 0x36, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, + 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, + 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, + 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, + 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, + 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, + 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, + 0x51, 0x18, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, + 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, + 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, + 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, + 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, + 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, + 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, + 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, + 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, + 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, + 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, + 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, + 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, + 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, + 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, + 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, + 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, + 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, + 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, + 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, + 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, + 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, + 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, + 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, + 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, + 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, + 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x04, 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, + 0x00, 0x0a, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x06, + 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, 0xa8, 0x36, 0x18, 0xc6, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, 0x1b, 0x94, 0xe3, 0xff, + 0xff, 0xff, 0xff, 0x07, 0xa0, 0x0d, 0x80, 0x35, 0x00, 0x24, 0xa0, 0xda, + 0x60, 0x20, 0x01, 0xb0, 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, + 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, + 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, + 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, + 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, + 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, + 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, + 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, + 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, + 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, + 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x01, + 0x62, 0x84, 0xe0, 0xe6, 0x08, 0x82, 0x39, 0x02, 0x30, 0x18, 0x46, 0x10, + 0xa2, 0xa2, 0xbc, 0x93, 0x04, 0x94, 0x10, 0x80, 0x48, 0x73, 0x20, 0x20, + 0x05, 0xe2, 0x30, 0xc2, 0x10, 0x0d, 0x22, 0x04, 0xc2, 0x1c, 0x01, 0x28, + 0x0c, 0x22, 0x0c, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, + 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, + 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, + 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, + 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, + 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, + 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, + 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, + 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, + 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, + 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, + 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, + 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, + 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, + 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, + 0x90, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xd6, 0xf6, 0x5f, 0x44, 0x80, 0xc1, + 0x10, 0xcd, 0x34, 0x24, 0x02, 0x22, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x86, 0x44, 0x51, 0xc3, 0x00, 0x01, 0x20, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc8, 0xdb, 0x26, + 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0xd8, + 0x20, 0x50, 0x14, 0x67, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, + 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x8a, 0x45, 0x50, 0x02, 0x85, + 0x30, 0x02, 0x50, 0x06, 0x05, 0x18, 0x50, 0x20, 0x05, 0x54, 0x60, 0xa5, + 0x50, 0x0c, 0x64, 0xc7, 0x12, 0x1c, 0x02, 0x00, 0xb1, 0x18, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, + 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, + 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, + 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, + 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, + 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, + 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, + 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, + 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, + 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, + 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, + 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, + 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, + 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, + 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, + 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, + 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, + 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, + 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, + 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, + 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, + 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, + 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, + 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, + 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, + 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, + 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, + 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, + 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, + 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, + 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, + 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, + 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, + 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, + 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, + 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, + 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, + 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, + 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, + 0x32, 0x64, 0xd4, 0xd8, 0x80, 0x0c, 0xea, 0x09, 0x8b, 0x02, 0x07, 0xc5, + 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, 0x88, 0x64, 0x3d, 0x45, + 0x66, 0x20, 0xca, 0x23, 0x21, 0x94, 0x61, 0x18, 0x86, 0x11, 0x5d, 0x89, + 0xb1, 0x28, 0x18, 0x51, 0x2c, 0x47, 0x00, 0x00, 0x53, 0x44, 0x4b, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, + 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, + 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, + 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, @@ -1650,22 +1637,24 @@ const unsigned char sdl_metallib[] = { 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, - 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, - 0x32, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, - 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, - 0x32, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, - 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, - 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, - 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, - 0x73, 0x69, 0x7a, 0x65, 0x63, 0x6f, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x73, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, - 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, - 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, - 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x59, 0x55, 0x56, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, + 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, + 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x52, + 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x42, + 0x63, 0x6f, 0x65, 0x66, 0x66, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, + 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, @@ -1673,275 +1662,265 @@ const unsigned char sdl_metallib[] = { 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x59, 0x74, 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, - 0x73, 0x00, 0x64, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, - 0x20, 0x0d, 0x23, 0x08, 0xd7, 0x33, 0x82, 0x20, 0x11, 0x23, 0x08, 0x52, - 0x31, 0x82, 0x20, 0x19, 0x23, 0x08, 0x0c, 0x30, 0x82, 0x20, 0x1d, 0x23, - 0x08, 0x12, 0x32, 0x82, 0x20, 0x25, 0x23, 0x08, 0x92, 0x32, 0x82, 0x20, - 0x2d, 0x23, 0x08, 0x12, 0x33, 0x82, 0x20, 0x35, 0x33, 0x0c, 0x6c, 0x10, - 0xb4, 0xc1, 0x0c, 0x83, 0x1b, 0x08, 0x6f, 0x30, 0x43, 0x30, 0xcc, 0x30, - 0xb0, 0x01, 0x1b, 0xc0, 0xc1, 0x0c, 0x04, 0xe1, 0x06, 0x6e, 0x00, 0x07, - 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x70, - 0x00, 0x07, 0x89, 0x32, 0x43, 0x10, 0x0a, 0x33, 0x20, 0x70, 0xb0, 0x30, - 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0x89, 0x1b, 0x40, 0x11, 0x23, 0x25, 0x93, - 0x43, 0xcd, 0x00, 0xb1, 0x41, 0x65, 0xc9, 0xc1, 0x05, 0x07, 0x6e, 0x80, - 0x65, 0x72, 0xa0, 0xc9, 0x41, 0xa2, 0x38, 0xdb, 0x0c, 0x14, 0x1c, 0xc8, - 0x01, 0x1c, 0x74, 0x9e, 0x1c, 0xc8, 0x01, 0x1c, 0x74, 0x5f, 0x1d, 0xc8, - 0x01, 0x1c, 0x74, 0x60, 0x60, 0x07, 0x72, 0x00, 0x07, 0x5d, 0x18, 0xcc, - 0x20, 0xcd, 0x41, 0x65, 0xd1, 0xc1, 0xe5, 0x06, 0x6e, 0x80, 0x71, 0xa6, - 0x90, 0xd1, 0x81, 0x26, 0x07, 0x89, 0x18, 0x38, 0x63, 0x30, 0x83, 0xf2, - 0x06, 0x64, 0x70, 0xc1, 0x81, 0x1b, 0x94, 0x41, 0x62, 0x06, 0xce, 0x19, - 0xcc, 0xa0, 0xdc, 0x01, 0x19, 0x5c, 0x6e, 0xe0, 0x06, 0x65, 0x90, 0x98, - 0x81, 0x83, 0x06, 0x33, 0x24, 0x78, 0x90, 0x06, 0x17, 0x1c, 0xb8, 0x41, - 0xa2, 0x06, 0xce, 0x1a, 0xcc, 0x70, 0x8c, 0x02, 0x29, 0x94, 0xc2, 0x29, - 0xa0, 0x42, 0x2a, 0xa8, 0xc2, 0x0c, 0x43, 0x1c, 0x88, 0xc2, 0x2a, 0x54, - 0x18, 0x00, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x9c, - 0x1b, 0xb8, 0x81, 0x45, 0x07, 0x7a, 0x60, 0x59, 0x96, 0x1e, 0x70, 0xa6, - 0xc0, 0x0a, 0x34, 0xc1, 0x1b, 0x72, 0x61, 0x0f, 0xf6, 0xa0, 0x0e, 0xe4, - 0x20, 0x23, 0x81, 0x09, 0xba, 0x88, 0x8d, 0xcd, 0xae, 0xcd, 0xa5, 0xed, - 0x8d, 0xac, 0x8e, 0xad, 0xcc, 0xc5, 0x8c, 0x2d, 0xec, 0x6c, 0x6e, 0x14, - 0x01, 0x0f, 0xf2, 0xe0, 0x14, 0x36, 0x36, 0xbb, 0x36, 0x97, 0x34, 0xb2, - 0x32, 0x37, 0xba, 0x51, 0x02, 0x3d, 0xb8, 0x25, 0x2c, 0x4d, 0xce, 0xc5, - 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x94, 0x60, 0x0f, 0x8e, 0x0a, - 0x4b, 0x93, 0x73, 0x61, 0x0b, 0x73, 0x3b, 0xab, 0x0b, 0x3b, 0x2b, 0xfb, - 0xb2, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0xe0, 0x83, 0x9b, - 0xc2, 0xd2, 0xe4, 0x5c, 0xc6, 0xde, 0xda, 0xe0, 0xd2, 0xd8, 0xca, 0xbe, - 0xde, 0xe0, 0xe8, 0xd2, 0xde, 0xdc, 0xe6, 0x46, 0x19, 0xfa, 0xc0, 0x0f, - 0xfe, 0xe0, 0x98, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, - 0x32, 0x37, 0xba, 0x51, 0x82, 0x55, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, - 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, - 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, - 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, - 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, - 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, - 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, - 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, - 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x6b, 0x60, 0x04, 0x80, 0xe4, - 0x0c, 0x00, 0xcd, 0x11, 0x00, 0xc2, 0x63, 0x0d, 0x40, 0x20, 0xcc, 0x31, - 0x18, 0x59, 0x36, 0xc7, 0x60, 0x10, 0xd9, 0x58, 0x03, 0x30, 0x10, 0x04, - 0x46, 0x00, 0x66, 0x00, 0xc6, 0x08, 0x40, 0x10, 0x04, 0xf1, 0x8f, 0xc2, - 0x0c, 0xc0, 0x1c, 0x04, 0x18, 0x80, 0x01, 0x18, 0x84, 0x01, 0x00, 0x00, - 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, - 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, - 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, - 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, - 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, - 0xcd, 0xd9, 0x10, 0xb8, 0xc2, 0x86, 0xa1, 0x15, 0x60, 0xe1, 0x15, 0x36, - 0x0c, 0xb1, 0x10, 0x0b, 0xaf, 0x00, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, - 0x40, 0x89, 0x01, 0xe4, 0x4c, 0x8d, 0xc2, 0x14, 0x85, 0x37, 0x9a, 0x10, - 0x00, 0x83, 0x0c, 0x01, 0xa1, 0x8c, 0x18, 0x34, 0x43, 0x08, 0x82, 0x01, - 0x55, 0x06, 0x52, 0x64, 0x41, 0xcd, 0x83, 0x20, 0x61, 0x30, 0x9a, 0x10, - 0x00, 0x83, 0x0c, 0xc1, 0xc1, 0x0c, 0x32, 0x10, 0x01, 0x73, 0x58, 0x5e, - 0x0a, 0x42, 0x19, 0x64, 0x08, 0x16, 0xc9, 0x88, 0x00, 0xfc, 0xa9, 0x0b, - 0x65, 0x97, 0xa1, 0x13, 0x03, 0x36, 0xb8, 0x20, 0x2f, 0x05, 0xa1, 0x0c, - 0x32, 0x04, 0x11, 0x36, 0x62, 0x70, 0x08, 0x21, 0x08, 0x16, 0xfe, 0xd1, - 0xcc, 0x81, 0x11, 0xec, 0x32, 0x88, 0xc1, 0x19, 0xc8, 0xc1, 0x05, 0x79, - 0x29, 0x08, 0x65, 0x90, 0x21, 0xb0, 0xba, 0x11, 0x83, 0x43, 0x08, 0x41, - 0xb0, 0xf0, 0x8f, 0x06, 0x0f, 0x96, 0x60, 0x97, 0xe1, 0x0c, 0xd8, 0x40, - 0x0e, 0x2e, 0xc8, 0x4b, 0x41, 0x28, 0x83, 0x0c, 0xc1, 0x26, 0x06, 0x23, - 0x06, 0x87, 0x10, 0x82, 0x60, 0xe1, 0x1f, 0x4d, 0x1f, 0x40, 0xc1, 0x1c, - 0x03, 0xb7, 0xe4, 0xc1, 0x1c, 0x43, 0x70, 0xf0, 0xc1, 0x1c, 0x43, 0x30, - 0xf8, 0x81, 0x05, 0x93, 0xf8, 0x67, 0x10, 0x10, 0x03, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x5b, 0x86, 0x25, 0x88, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, - 0x10, 0x22, 0x84, 0x00, 0xfa, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x12, 0x03, - 0x94, 0x38, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, - 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1e, 0x00, - 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x1b, 0x00, - 0x00, 0x00, 0x12, 0x03, 0x94, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, - 0x4c, 0x5f, 0x4e, 0x56, 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, - 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x64, 0x6f, 0x74, 0x2e, 0x76, - 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, - 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, - 0x2e, 0x34, 0x33, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, - 0x6c, 0x65, 0x2d, 0x69, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, - 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, - 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x80, 0x0e, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, - 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x50, 0x03, - 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, - 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, - 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, - 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, - 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, - 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, - 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, - 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x94, 0x00, - 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, - 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, - 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, - 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, - 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, - 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, - 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, - 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, - 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, - 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, - 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, - 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, - 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, - 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, - 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, - 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, - 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, - 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, - 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, - 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, - 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, - 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, - 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, - 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, - 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, - 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, - 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, - 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, - 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, - 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, - 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, - 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, - 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, - 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, - 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, - 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, - 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, - 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x03, - 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, 0x00, 0x6d, 0x58, 0x06, 0x02, 0x48, - 0x80, 0x05, 0xa8, 0x82, 0x34, 0x00, 0x85, 0x0d, 0x06, 0x51, 0x00, 0x0b, - 0x50, 0x6d, 0x30, 0x0a, 0x03, 0x58, 0x80, 0x6a, 0x83, 0x61, 0x1c, 0xc0, - 0x02, 0x54, 0x1b, 0x8c, 0xe3, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, - 0xa8, 0x0d, 0x0a, 0xf2, 0xff, 0xff, 0xff, 0xff, 0x03, 0xd0, 0x06, 0xc0, - 0x1a, 0x00, 0x12, 0x50, 0x6d, 0x30, 0x92, 0x00, 0x58, 0x80, 0x6a, 0x83, - 0xa1, 0x08, 0xc0, 0x02, 0x54, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x13, 0x8c, 0x40, 0x18, 0x88, 0xc2, 0x98, 0x10, 0x1c, 0x13, - 0x06, 0x24, 0x51, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x2a, 0x00, - 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, - 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, - 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x74, 0x33, 0x00, 0xc3, 0x08, - 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, - 0x07, 0x49, 0x53, 0x44, 0x09, 0x93, 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, - 0x40, 0x20, 0x82, 0x10, 0x42, 0x06, 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, - 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, - 0xa7, 0x31, 0x02, 0x60, 0x10, 0xe1, 0x08, 0x2e, 0x92, 0xa6, 0x88, 0x12, - 0x26, 0xff, 0x97, 0x00, 0xe6, 0x59, 0x88, 0xe8, 0x9f, 0xc6, 0x08, 0x80, - 0x41, 0x84, 0x44, 0x28, 0x48, 0x08, 0x62, 0x18, 0x84, 0x14, 0xad, 0x32, - 0x00, 0x42, 0xa8, 0xcd, 0x11, 0x20, 0x46, 0x08, 0x6f, 0x8e, 0x20, 0x98, - 0x23, 0x00, 0x83, 0x61, 0x04, 0x41, 0x2a, 0x0a, 0x44, 0x4a, 0xc4, 0x19, - 0x01, 0x90, 0x44, 0x07, 0x02, 0x52, 0x40, 0x0e, 0x23, 0x0c, 0xd2, 0x20, - 0x42, 0x20, 0xcc, 0x11, 0x80, 0xc2, 0x20, 0x02, 0x21, 0x8c, 0x00, 0x00, - 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, - 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, - 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, - 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, - 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, - 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, - 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, - 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, - 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, - 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, - 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, - 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, - 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, - 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, - 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, - 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, - 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, - 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, - 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, - 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, - 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, - 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, - 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, - 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, - 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, - 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, - 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, - 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, - 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, - 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, - 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, - 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x11, 0xdb, 0x95, 0xff, 0xf9, - 0xda, 0xf5, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x34, 0x24, 0x02, 0xa2, - 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x86, - 0x44, 0x51, 0xd3, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0xc0, 0x90, 0xc8, 0xdb, 0x28, 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x90, 0xd8, 0x20, 0x50, 0x54, 0x6a, 0x00, 0x00, - 0x20, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, - 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, - 0x43, 0x92, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x20, 0x65, 0x50, - 0x80, 0x01, 0x05, 0x54, 0x60, 0xa5, 0x50, 0x0c, 0xa4, 0x47, 0x00, 0xe8, - 0x8e, 0x25, 0x38, 0x02, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, - 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, - 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, - 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, - 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, - 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, - 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, - 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, - 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, - 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, - 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, - 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, - 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, - 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, - 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, - 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, - 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, - 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, - 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, - 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, - 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, - 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, - 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, - 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, - 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, - 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, - 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, - 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, - 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, - 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, - 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, - 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, - 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, - 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, - 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, - 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, - 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, - 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, - 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, - 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, - 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, - 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, - 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x32, 0x9a, - 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, - 0xd4, 0xd6, 0x80, 0x0c, 0x76, 0x09, 0x8b, 0xe2, 0x06, 0xc5, 0xc6, 0x91, - 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, 0x88, 0x94, 0x3d, 0x06, 0xa2, 0x3c, - 0x12, 0x12, 0x5d, 0x03, 0x65, 0x18, 0x86, 0x61, 0x24, 0xc6, 0xa2, 0x60, - 0x44, 0xb1, 0x1c, 0x01, 0x00, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, - 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, - 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, - 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, + 0x73, 0x00, 0x00, 0x00, 0x44, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x82, 0x10, 0x0d, 0x23, 0x08, 0x96, 0x33, 0x82, 0x10, 0x11, 0x23, + 0x08, 0x51, 0x31, 0x82, 0x10, 0x19, 0x23, 0x08, 0x0b, 0x30, 0x82, 0x10, + 0x1d, 0x23, 0x08, 0x11, 0x32, 0x82, 0x10, 0x25, 0x23, 0x08, 0x91, 0x32, + 0x82, 0x10, 0x2d, 0x23, 0x08, 0x11, 0x33, 0x82, 0x10, 0x35, 0x33, 0x0c, + 0x6d, 0x10, 0xb8, 0xc1, 0x0c, 0xc3, 0x1b, 0x08, 0x70, 0x30, 0x43, 0x30, + 0xcc, 0x30, 0xb4, 0x41, 0x1b, 0xc4, 0xc1, 0x0c, 0x04, 0xf1, 0x06, 0x6f, + 0x10, 0x07, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, + 0x20, 0x71, 0x10, 0x07, 0x89, 0x32, 0x43, 0x20, 0x0a, 0x33, 0x20, 0x71, + 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0xc9, 0x1b, 0x40, 0x11, 0x23, + 0x25, 0x8a, 0x33, 0xcd, 0x90, 0xb4, 0x01, 0x44, 0x31, 0x52, 0x52, 0x39, + 0xd6, 0x0c, 0x54, 0x1c, 0xd4, 0x41, 0x1c, 0x70, 0x5d, 0x1d, 0xd4, 0x41, + 0x1c, 0x70, 0x9e, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0xdf, 0x1d, 0xd4, 0x41, + 0x1c, 0x70, 0x60, 0x30, 0x83, 0x34, 0x07, 0x17, 0x46, 0x07, 0xd9, 0x1b, + 0xbc, 0x81, 0xb6, 0x9d, 0x42, 0x18, 0xd0, 0x81, 0x18, 0xd4, 0x41, 0x32, + 0x06, 0x0e, 0x19, 0xcc, 0xa0, 0xc0, 0x41, 0x19, 0x64, 0x71, 0xf0, 0x06, + 0x66, 0x90, 0x9c, 0x81, 0x83, 0x06, 0x33, 0x28, 0x78, 0x50, 0x06, 0xd9, + 0x1b, 0xbc, 0x81, 0x19, 0x24, 0x67, 0xe0, 0xa4, 0xc1, 0x0c, 0x49, 0x1e, + 0xa8, 0x41, 0x16, 0x07, 0x6f, 0x90, 0xac, 0x81, 0xc3, 0x06, 0x33, 0x1c, + 0xa4, 0x50, 0x0a, 0xa6, 0x80, 0x0a, 0xa9, 0xa0, 0x0a, 0xab, 0x30, 0xc3, + 0x20, 0x07, 0xa3, 0xc0, 0x0a, 0x15, 0x06, 0x00, 0xc7, 0x71, 0x1c, 0xc7, + 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xe7, 0x06, 0x6e, 0x60, 0xd1, 0x81, 0x1e, + 0x58, 0x96, 0xa5, 0x07, 0x9c, 0x29, 0xb0, 0x02, 0x2b, 0xd8, 0x86, 0x5f, + 0xd8, 0x83, 0x3d, 0xa8, 0x03, 0x39, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, + 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, + 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0xc8, 0x03, 0x3d, 0x38, 0x85, 0x8d, + 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x60, 0x0f, + 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, + 0x1b, 0x25, 0xe0, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, + 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, + 0xdc, 0x46, 0x09, 0xfa, 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, + 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, + 0xb9, 0x51, 0x06, 0x3f, 0xf8, 0x03, 0x50, 0x38, 0x26, 0x2c, 0x4d, 0xce, + 0xc5, 0x4c, 0x2e, 0xec, 0xac, 0xad, 0xcc, 0x8d, 0x6e, 0x94, 0x80, 0x15, + 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x04, 0x6b, 0x60, 0x04, 0x80, 0xe2, 0x0c, 0x00, 0xc9, 0x11, 0x00, 0xba, + 0x63, 0x0d, 0x40, 0x20, 0xcc, 0x31, 0x18, 0x18, 0x36, 0xc7, 0x60, 0x10, + 0xd8, 0x58, 0x03, 0x30, 0x10, 0x94, 0x47, 0x00, 0x08, 0x8c, 0x00, 0xcc, + 0x00, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0x1f, 0x85, 0x19, 0x80, 0x39, + 0x08, 0x30, 0x00, 0x03, 0x30, 0x08, 0x03, 0x00, 0x23, 0x06, 0xcd, 0x10, + 0x82, 0x60, 0x30, 0x89, 0x41, 0xf4, 0x4c, 0xce, 0xd2, 0x14, 0x85, 0x37, + 0x9a, 0x10, 0x00, 0x83, 0x0c, 0x01, 0xb1, 0x8c, 0x18, 0x34, 0x43, 0x08, + 0x82, 0xc1, 0x54, 0x06, 0x93, 0x64, 0x45, 0x0e, 0x84, 0x20, 0x61, 0x30, + 0x9a, 0x10, 0x00, 0x83, 0x0c, 0xc1, 0xd1, 0x0c, 0x32, 0x10, 0x41, 0x73, + 0x19, 0x5e, 0x0a, 0x42, 0x19, 0x64, 0x08, 0x96, 0xc9, 0x88, 0x00, 0xfc, + 0x37, 0x19, 0xba, 0x68, 0x0d, 0x2e, 0xc0, 0x4b, 0x41, 0x28, 0x83, 0x0c, + 0x01, 0x84, 0x8d, 0x18, 0x1c, 0x42, 0x08, 0x82, 0x85, 0x7f, 0x30, 0x72, + 0x50, 0x04, 0x9b, 0x0c, 0x62, 0x60, 0xc5, 0xc1, 0x05, 0x78, 0x29, 0x08, + 0x65, 0x90, 0x21, 0xa8, 0xba, 0x11, 0x83, 0x43, 0x08, 0x41, 0xb0, 0xf0, + 0x0f, 0xe6, 0x0e, 0x94, 0x60, 0x93, 0xe1, 0x0c, 0x36, 0x39, 0xb8, 0x00, + 0x2f, 0x05, 0xa1, 0x0c, 0x32, 0x04, 0x9a, 0x18, 0x8c, 0x18, 0x1c, 0x42, + 0x08, 0x82, 0x85, 0x7f, 0x30, 0x7c, 0xf0, 0x04, 0x73, 0x0c, 0xdb, 0x82, + 0x07, 0x73, 0x0c, 0xc1, 0xb1, 0x07, 0x73, 0x0c, 0xc1, 0xd0, 0x07, 0x16, + 0xc4, 0x81, 0xf8, 0x67, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xfb, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x38, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x31, 0x32, + 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, + 0x2e, 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, + 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, + 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, + 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, + 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, + 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x28, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, + 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, + 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, + 0x39, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, + 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, + 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, + 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, + 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, + 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, + 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, + 0x92, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, + 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, + 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, + 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, + 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, + 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, + 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, + 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, + 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, + 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, + 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, + 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, + 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, + 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, + 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, + 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, + 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, + 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, + 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, + 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, + 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, + 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, + 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, + 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, + 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, + 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, + 0x08, 0x04, 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, 0x00, 0x0a, 0x1b, 0x8c, + 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x06, 0xb0, 0x00, 0xd5, 0x06, + 0xa3, 0x38, 0x80, 0x05, 0xa8, 0x36, 0x18, 0xc6, 0xff, 0xff, 0xff, 0xff, + 0x0f, 0x80, 0x04, 0x50, 0x1b, 0x94, 0xe3, 0xff, 0xff, 0xff, 0xff, 0x07, + 0xa0, 0x0d, 0x80, 0x35, 0x00, 0x24, 0xa0, 0xda, 0x60, 0x20, 0x01, 0xb0, + 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, 0xa8, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, + 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, + 0x10, 0x70, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, + 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, + 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, + 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, + 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, 0x22, 0x69, + 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, + 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x27, + 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x01, 0x62, 0x84, 0xe0, 0xe6, + 0x08, 0x82, 0x39, 0x02, 0x30, 0x18, 0x46, 0x10, 0xa2, 0xa2, 0xbc, 0x93, + 0x04, 0x94, 0x10, 0x80, 0x48, 0x73, 0x20, 0x20, 0x05, 0xe2, 0x30, 0xc2, + 0x10, 0x0d, 0x22, 0x04, 0xc2, 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x0c, 0xc2, + 0x08, 0x00, 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, + 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, + 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, + 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, + 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, + 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, + 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, + 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, + 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, + 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x11, 0xdb, 0x95, + 0xff, 0xf9, 0xda, 0xf5, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x34, 0x24, + 0x02, 0x22, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x86, 0x44, 0x51, 0xc3, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc8, 0xdb, 0x26, 0x20, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0xd8, 0x20, 0x50, 0x74, 0x67, + 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, + 0xc6, 0x04, 0x43, 0x8a, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x06, + 0x05, 0x18, 0x50, 0x20, 0x05, 0x54, 0x60, 0xa5, 0x50, 0x0c, 0x64, 0xc7, + 0x12, 0x1c, 0x02, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xd8, + 0x80, 0x0c, 0xea, 0x09, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, + 0x19, 0x8c, 0x22, 0x31, 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0xca, 0x23, + 0x21, 0x94, 0x61, 0x18, 0x86, 0x11, 0x5d, 0x89, 0xb1, 0x28, 0x18, 0x51, + 0x2c, 0x47, 0x00, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, @@ -1960,127 +1939,120 @@ const unsigned char sdl_metallib[] = { 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, - 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, - 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, - 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, - 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, - 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, - 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, - 0x63, 0x6f, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x74, 0x72, 0x75, 0x63, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x66, - 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x52, - 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x42, - 0x63, 0x6f, 0x65, 0x66, 0x66, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, + 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, + 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, + 0x69, 0x72, 0x2e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x33, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, + 0x66, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, + 0x66, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x59, 0x74, 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x64, 0x78, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x20, 0x0d, 0x23, 0x08, - 0xd7, 0x33, 0x82, 0x20, 0x11, 0x23, 0x08, 0x52, 0x31, 0x82, 0x20, 0x19, - 0x23, 0x08, 0x0c, 0x30, 0x82, 0x20, 0x1d, 0x23, 0x08, 0x12, 0x32, 0x82, - 0x20, 0x25, 0x23, 0x08, 0x92, 0x32, 0x82, 0x20, 0x2d, 0x23, 0x08, 0x12, - 0x33, 0x82, 0x20, 0x35, 0x33, 0x0c, 0x6c, 0x10, 0xb4, 0xc1, 0x0c, 0x83, - 0x1b, 0x08, 0x6f, 0x30, 0x43, 0x30, 0xcc, 0x30, 0xb0, 0x01, 0x1b, 0xc0, - 0xc1, 0x0c, 0x04, 0xe1, 0x06, 0x6e, 0x00, 0x07, 0x33, 0x04, 0xc5, 0x0c, - 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x70, 0x00, 0x07, 0x89, 0x32, - 0x43, 0x10, 0x0a, 0x33, 0x20, 0x70, 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, - 0x0c, 0x89, 0x1b, 0x40, 0x11, 0x23, 0x25, 0x93, 0x43, 0xcd, 0x00, 0xb1, - 0x41, 0x65, 0xc9, 0xc1, 0x05, 0x07, 0x6e, 0x80, 0x65, 0x72, 0xa0, 0xc9, - 0x41, 0xa2, 0x38, 0xdb, 0x0c, 0x14, 0x1c, 0xc8, 0x01, 0x1c, 0x74, 0x9e, - 0x1c, 0xc8, 0x01, 0x1c, 0x74, 0x5f, 0x1d, 0xc8, 0x01, 0x1c, 0x74, 0x60, - 0x60, 0x07, 0x72, 0x00, 0x07, 0x5d, 0x18, 0xcc, 0x20, 0xcd, 0x41, 0x65, - 0xd1, 0xc1, 0xe5, 0x06, 0x6e, 0x80, 0x71, 0xa6, 0x90, 0xd1, 0x81, 0x26, - 0x07, 0x89, 0x18, 0x38, 0x63, 0x30, 0x83, 0xf2, 0x06, 0x64, 0x70, 0xc1, - 0x81, 0x1b, 0x94, 0x41, 0x62, 0x06, 0xce, 0x19, 0xcc, 0xa0, 0xdc, 0x01, - 0x19, 0x5c, 0x6e, 0xe0, 0x06, 0x65, 0x90, 0x98, 0x81, 0x83, 0x06, 0x33, - 0x24, 0x78, 0x90, 0x06, 0x17, 0x1c, 0xb8, 0x41, 0xa2, 0x06, 0xce, 0x1a, - 0xcc, 0x70, 0x8c, 0x02, 0x29, 0x94, 0xc2, 0x29, 0xa0, 0x42, 0x2a, 0xa8, - 0xc2, 0x0c, 0x43, 0x1c, 0x88, 0xc2, 0x2a, 0x54, 0x18, 0x00, 0x1c, 0xc7, - 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x9c, 0x1b, 0xb8, 0x81, 0x45, - 0x07, 0x7a, 0x60, 0x59, 0x96, 0x1e, 0x70, 0xa6, 0xc0, 0x0a, 0x34, 0xc1, - 0x1b, 0x72, 0x61, 0x0f, 0xf6, 0xa0, 0x0e, 0xe4, 0x20, 0x23, 0x81, 0x09, - 0xba, 0x88, 0x8d, 0xcd, 0xae, 0xcd, 0xa5, 0xed, 0x8d, 0xac, 0x8e, 0xad, - 0xcc, 0xc5, 0x8c, 0x2d, 0xec, 0x6c, 0x6e, 0x14, 0x01, 0x0f, 0xf2, 0xe0, - 0x14, 0x36, 0x36, 0xbb, 0x36, 0x97, 0x34, 0xb2, 0x32, 0x37, 0xba, 0x51, - 0x02, 0x3d, 0xb8, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x6e, 0x2e, - 0xed, 0xcd, 0x6d, 0x94, 0x60, 0x0f, 0x8e, 0x0a, 0x4b, 0x93, 0x73, 0x61, - 0x0b, 0x73, 0x3b, 0xab, 0x0b, 0x3b, 0x2b, 0xfb, 0xb2, 0x2b, 0x93, 0x9b, - 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0xe0, 0x83, 0x9b, 0xc2, 0xd2, 0xe4, 0x5c, - 0xc6, 0xde, 0xda, 0xe0, 0xd2, 0xd8, 0xca, 0xbe, 0xde, 0xe0, 0xe8, 0xd2, - 0xde, 0xdc, 0xe6, 0x46, 0x19, 0xfa, 0xc0, 0x0f, 0xfe, 0xe0, 0x98, 0xb0, - 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0x51, - 0x82, 0x55, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, - 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, - 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, - 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, - 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, - 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, - 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, - 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x56, 0x00, - 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x14, 0x6b, 0x60, 0x04, 0x80, 0xe4, 0x0c, 0x00, 0xcd, 0x11, - 0x80, 0xb1, 0x84, 0x00, 0x20, 0x3c, 0xd6, 0x00, 0x04, 0xc2, 0x1c, 0x83, - 0x91, 0x65, 0x73, 0x0c, 0x06, 0x91, 0x8d, 0x35, 0x00, 0x03, 0x41, 0x60, - 0x04, 0x60, 0x06, 0x60, 0x8c, 0x00, 0x04, 0x41, 0x10, 0xff, 0x28, 0xcc, - 0x00, 0xcc, 0x41, 0x84, 0x41, 0x18, 0x84, 0x81, 0x18, 0x90, 0x98, 0x01, - 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, - 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, - 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, - 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, - 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, - 0xcd, 0xd9, 0x10, 0xb8, 0xc2, 0x86, 0xa1, 0x15, 0x60, 0xe1, 0x15, 0x36, - 0x0c, 0xb1, 0x10, 0x0b, 0xaf, 0x00, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, - 0x40, 0x91, 0x81, 0x04, 0x55, 0x0f, 0xe3, 0x18, 0x06, 0x18, 0x8c, 0x26, - 0x04, 0xc0, 0x20, 0x43, 0x50, 0x2c, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, - 0x40, 0x9d, 0x01, 0x35, 0x61, 0xd2, 0x13, 0x25, 0xc9, 0x18, 0x8c, 0x26, - 0x04, 0xc0, 0x20, 0x43, 0x80, 0x40, 0x83, 0x0c, 0xc1, 0xe1, 0x0c, 0x32, - 0x14, 0x81, 0x73, 0x5b, 0x5e, 0x0a, 0x42, 0x19, 0x64, 0x08, 0x1a, 0xca, - 0x88, 0x00, 0xfc, 0x09, 0x0c, 0x42, 0xd9, 0x65, 0x00, 0x83, 0x32, 0x78, - 0x83, 0x0b, 0xf2, 0x52, 0x10, 0xca, 0x20, 0x43, 0x30, 0x69, 0x23, 0x06, - 0x87, 0x10, 0x82, 0x60, 0xe1, 0x1f, 0x8d, 0x1d, 0x18, 0xc1, 0x2e, 0x43, - 0x19, 0xa8, 0x41, 0x1d, 0x5c, 0x90, 0x97, 0x82, 0x50, 0x06, 0x19, 0x02, - 0xec, 0x1b, 0x31, 0x38, 0x84, 0x10, 0x04, 0x0b, 0xff, 0x68, 0xf6, 0x60, - 0x09, 0x76, 0x19, 0xd4, 0xe0, 0x0d, 0xea, 0xe0, 0x82, 0xbc, 0x14, 0x84, - 0x32, 0xc8, 0x10, 0x74, 0x64, 0x30, 0x62, 0x70, 0x08, 0x21, 0x08, 0x16, - 0xfe, 0xd1, 0x80, 0x02, 0x14, 0xcc, 0x31, 0x78, 0x0b, 0x1f, 0xcc, 0x31, - 0x04, 0xc7, 0x1f, 0xcc, 0x31, 0x04, 0x43, 0x28, 0x58, 0x30, 0x89, 0x7f, - 0x06, 0x01, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x06, - 0x26, 0x88, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, - 0xfa, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, - 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x38, 0x01, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, - 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x1e, 0x00, - 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x12, 0x03, - 0x94, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, - 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, - 0x69, 0x72, 0x2e, 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, - 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, - 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, - 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x61, - 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, - 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, - 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, + 0x44, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x10, 0x0d, + 0x23, 0x08, 0x96, 0x33, 0x82, 0x10, 0x11, 0x23, 0x08, 0x51, 0x31, 0x82, + 0x10, 0x19, 0x23, 0x08, 0x0b, 0x30, 0x82, 0x10, 0x1d, 0x23, 0x08, 0x11, + 0x32, 0x82, 0x10, 0x25, 0x23, 0x08, 0x91, 0x32, 0x82, 0x10, 0x2d, 0x23, + 0x08, 0x11, 0x33, 0x82, 0x10, 0x35, 0x33, 0x0c, 0x6d, 0x10, 0xb8, 0xc1, + 0x0c, 0xc3, 0x1b, 0x08, 0x70, 0x30, 0x43, 0x30, 0xcc, 0x30, 0xb4, 0x41, + 0x1b, 0xc4, 0xc1, 0x0c, 0x04, 0xf1, 0x06, 0x6f, 0x10, 0x07, 0x33, 0x04, + 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x71, 0x10, 0x07, + 0x89, 0x32, 0x43, 0x20, 0x0a, 0x33, 0x20, 0x71, 0xb0, 0x30, 0x4d, 0xa2, + 0x38, 0xcf, 0x0c, 0xc9, 0x1b, 0x40, 0x11, 0x23, 0x25, 0x8a, 0x33, 0xcd, + 0x90, 0xb4, 0x01, 0x44, 0x31, 0x52, 0x52, 0x39, 0xd6, 0x0c, 0x54, 0x1c, + 0xd4, 0x41, 0x1c, 0x70, 0x5d, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0x9e, 0x1d, + 0xd4, 0x41, 0x1c, 0x70, 0xdf, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0x60, 0x30, + 0x83, 0x34, 0x07, 0x17, 0x46, 0x07, 0xd9, 0x1b, 0xbc, 0x81, 0xb6, 0x9d, + 0x42, 0x18, 0xd0, 0x81, 0x18, 0xd4, 0x41, 0x32, 0x06, 0x0e, 0x19, 0xcc, + 0xa0, 0xc0, 0x41, 0x19, 0x64, 0x71, 0xf0, 0x06, 0x66, 0x90, 0x9c, 0x81, + 0x83, 0x06, 0x33, 0x28, 0x78, 0x50, 0x06, 0xd9, 0x1b, 0xbc, 0x81, 0x19, + 0x24, 0x67, 0xe0, 0xa4, 0xc1, 0x0c, 0x49, 0x1e, 0xa8, 0x41, 0x16, 0x07, + 0x6f, 0x90, 0xac, 0x81, 0xc3, 0x06, 0x33, 0x1c, 0xa4, 0x50, 0x0a, 0xa6, + 0x80, 0x0a, 0xa9, 0xa0, 0x0a, 0xab, 0x30, 0xc3, 0x20, 0x07, 0xa3, 0xc0, + 0x0a, 0x15, 0x06, 0x00, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, + 0x1c, 0xe7, 0x06, 0x6e, 0x60, 0xd1, 0x81, 0x1e, 0x58, 0x96, 0xa5, 0x07, + 0x9c, 0x29, 0xb0, 0x02, 0x2b, 0xd8, 0x86, 0x5f, 0xd8, 0x83, 0x3d, 0xa8, + 0x03, 0x39, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, + 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, + 0x1b, 0x45, 0xc8, 0x03, 0x3d, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, + 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x60, 0x0f, 0x6e, 0x09, 0x4b, 0x93, + 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0xe0, 0x83, + 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, + 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xfa, + 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, + 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x06, 0x3f, + 0xf8, 0x03, 0x50, 0x38, 0x26, 0x2c, 0x4d, 0xce, 0xc5, 0x4c, 0x2e, 0xec, + 0xac, 0xad, 0xcc, 0x8d, 0x6e, 0x94, 0x80, 0x15, 0x00, 0x00, 0x00, 0x00, + 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, + 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, + 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, + 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, + 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, + 0x61, 0x20, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, + 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x6b, 0x60, 0x04, + 0x80, 0xe2, 0x0c, 0x00, 0xc9, 0x11, 0x80, 0xb1, 0x84, 0x00, 0xa0, 0x3b, + 0xd6, 0x00, 0x04, 0xc2, 0x1c, 0x83, 0x81, 0x61, 0x73, 0x0c, 0x06, 0x81, + 0x8d, 0x35, 0x00, 0x03, 0x41, 0x79, 0x04, 0x80, 0xc0, 0x08, 0xc0, 0x0c, + 0xc0, 0x18, 0x01, 0x08, 0x82, 0x20, 0xfe, 0x51, 0x98, 0x01, 0x98, 0x83, + 0x08, 0x83, 0x30, 0x08, 0x03, 0x31, 0x20, 0x31, 0x03, 0x00, 0x00, 0x00, + 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x30, 0x91, 0xc1, 0x14, 0x55, 0x50, + 0xf3, 0x18, 0x06, 0x18, 0x8c, 0x26, 0x04, 0xc0, 0x20, 0x43, 0x50, 0x30, + 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x30, 0x9d, 0x41, 0x45, 0x61, 0x13, + 0x24, 0x25, 0xc9, 0x18, 0x8c, 0x26, 0x04, 0xc0, 0x20, 0x43, 0x80, 0x44, + 0x83, 0x0c, 0xc1, 0xf1, 0x0c, 0x32, 0x14, 0xc1, 0x73, 0x1c, 0x5e, 0x0a, + 0x42, 0x19, 0x64, 0x08, 0x9a, 0xca, 0x88, 0x00, 0xfc, 0x37, 0x19, 0xc0, + 0x60, 0x72, 0x83, 0x0b, 0xf0, 0x52, 0x10, 0xca, 0x20, 0x43, 0x20, 0x69, + 0x23, 0x06, 0x87, 0x10, 0x82, 0x60, 0xe1, 0x1f, 0x4c, 0x1d, 0x14, 0xc1, + 0x26, 0x43, 0x19, 0x60, 0x74, 0x70, 0x01, 0x5e, 0x0a, 0x42, 0x19, 0x64, + 0x08, 0xae, 0x6f, 0xc4, 0xe0, 0x10, 0x42, 0x10, 0x2c, 0xfc, 0x83, 0xd1, + 0x03, 0x25, 0xd8, 0x64, 0x50, 0x83, 0xae, 0x0e, 0x2e, 0xc0, 0x4b, 0x41, + 0x28, 0x83, 0x0c, 0x01, 0x47, 0x06, 0x23, 0x06, 0x87, 0x10, 0x82, 0x60, + 0xe1, 0x1f, 0xcc, 0x1f, 0x3c, 0xc1, 0x1c, 0x43, 0xb7, 0xec, 0xc1, 0x1c, + 0x43, 0x70, 0xf8, 0xc1, 0x1c, 0x43, 0x30, 0x80, 0x82, 0x05, 0x74, 0x20, + 0xfe, 0x19, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xfb, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x38, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x08, 0x24, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x64, 0x6f, 0x74, + 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, + 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, + 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6f, 0x73, 0x31, 0x33, + 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, + 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -const unsigned int sdl_metallib_len = 24994; +const unsigned int sdl_metallib_len = 24660; diff --git a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_osx.h b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_osx.h index 7b46b67e8..2bec8a56d 100644 --- a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_osx.h +++ b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_osx.h @@ -1,207 +1,209 @@ const unsigned char sdl_metallib[] = { 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x80, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x62, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x04, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x51, 0x00, 0x00, + 0x72, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, - 0x18, 0xea, 0xb3, 0x5d, 0xbf, 0xaa, 0x85, 0x5c, 0xa4, 0xe2, 0x19, 0xd2, - 0xd7, 0xf3, 0xc8, 0xae, 0x57, 0x80, 0x4d, 0x74, 0x93, 0x35, 0x84, 0x06, - 0x60, 0x4b, 0xc2, 0xa9, 0x6e, 0x93, 0x8d, 0x75, 0x4f, 0x46, 0x46, 0x54, + 0xb0, 0x1e, 0xd4, 0x63, 0x77, 0xeb, 0x95, 0x35, 0xec, 0xfd, 0x42, 0xfc, + 0x8f, 0x6c, 0xc0, 0x67, 0x91, 0x59, 0x50, 0x52, 0x7e, 0x6d, 0x23, 0xef, + 0x26, 0x6e, 0x78, 0xc7, 0x67, 0x3f, 0xa3, 0xda, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x77, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, - 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x55, - 0xff, 0x61, 0x04, 0xcf, 0x03, 0x92, 0x2a, 0xe4, 0x3e, 0x6e, 0xac, 0x10, - 0x11, 0x71, 0x19, 0x62, 0x92, 0x90, 0x10, 0xb2, 0x4f, 0x3e, 0x09, 0xcf, - 0xaf, 0x67, 0x48, 0xf4, 0x4a, 0x79, 0xfc, 0x4f, 0x46, 0x46, 0x54, 0x18, - 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0xc6, + 0x60, 0xef, 0x78, 0xb0, 0x6b, 0x69, 0x3a, 0x1f, 0x4c, 0xad, 0xbb, 0xcb, + 0xbc, 0x96, 0x77, 0xac, 0xa6, 0xe1, 0x3b, 0x3b, 0x06, 0x4c, 0x64, 0x10, + 0xee, 0xfe, 0xc0, 0xb7, 0x24, 0x28, 0x70, 0x4f, 0x46, 0x46, 0x54, 0x18, + 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x7a, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x13, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, - 0x00, 0x5b, 0x2b, 0x83, 0x7d, 0x5e, 0x9c, 0x63, 0x41, 0x0e, 0x77, 0xef, - 0xcb, 0x9a, 0x54, 0xa9, 0x04, 0x30, 0x49, 0x36, 0x56, 0xad, 0x1e, 0x17, - 0xd8, 0xf6, 0xe7, 0x7d, 0x59, 0xb0, 0xf4, 0x4d, 0xbb, 0x4f, 0x46, 0x46, - 0x54, 0x18, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x16, 0x00, 0x00, 0x00, + 0x00, 0xec, 0xda, 0x64, 0x8c, 0x89, 0xb3, 0x61, 0x32, 0x78, 0xa4, 0x67, + 0x9d, 0xd2, 0xad, 0x75, 0x55, 0x9d, 0xec, 0xf8, 0x6d, 0xc9, 0xb1, 0x4a, + 0x94, 0xac, 0x2d, 0x9a, 0x29, 0xed, 0xf5, 0x72, 0x3e, 0x4f, 0x46, 0x46, + 0x54, 0x18, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, - 0x20, 0x00, 0xb1, 0x1c, 0x24, 0x29, 0x04, 0xa5, 0x53, 0x74, 0xc4, 0x82, - 0xad, 0x1a, 0x2d, 0xa9, 0x96, 0xa8, 0xe9, 0xa6, 0x2f, 0x36, 0x1a, 0x7e, - 0x93, 0x36, 0x9c, 0x2a, 0x0f, 0x97, 0x9e, 0x6e, 0xaf, 0x8a, 0x4f, 0x46, - 0x46, 0x54, 0x18, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x8c, 0xa9, 0xc1, 0x5f, 0x0c, 0x8d, 0x69, 0xe0, 0xac, 0x20, + 0x39, 0x45, 0xb5, 0x81, 0x5a, 0xbd, 0x1a, 0xb2, 0x48, 0xa8, 0xe7, 0x81, + 0x31, 0x3b, 0x3a, 0x22, 0x20, 0xe2, 0xb9, 0xf7, 0x71, 0x8f, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x78, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, - 0x20, 0x00, 0xd6, 0x03, 0x6c, 0x38, 0x0d, 0xb2, 0xc5, 0xa4, 0xb7, 0xac, - 0x4c, 0x6c, 0x9c, 0x3e, 0xba, 0x38, 0xc2, 0x1a, 0x78, 0xef, 0xa2, 0x3e, - 0xe7, 0x0c, 0x2c, 0x7e, 0x1a, 0x14, 0xd9, 0xbf, 0xae, 0xfb, 0x4f, 0x46, - 0x46, 0x54, 0x18, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x2b, 0x00, 0x00, + 0x20, 0x00, 0x21, 0x22, 0xf2, 0x05, 0x0d, 0x3c, 0xbe, 0x5c, 0xe3, 0xc5, + 0xe5, 0xf2, 0x92, 0x32, 0x24, 0xf8, 0xeb, 0xfe, 0xd1, 0xe9, 0x4e, 0xc0, + 0x0f, 0x88, 0x2e, 0xf5, 0xfd, 0x77, 0x98, 0x5e, 0x6a, 0x30, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, - 0x48, 0x20, 0x00, 0x21, 0xcc, 0x99, 0xca, 0x3d, 0x14, 0x24, 0x0e, 0xca, - 0x0a, 0x3c, 0x21, 0xc6, 0xf7, 0xea, 0xe9, 0xd7, 0x67, 0xab, 0xcf, 0x59, - 0x48, 0xf3, 0x7f, 0xcf, 0x44, 0x88, 0x29, 0x73, 0xe3, 0xc0, 0x97, 0x4f, - 0x46, 0x46, 0x54, 0x18, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x38, 0x00, + 0x48, 0x20, 0x00, 0xe5, 0xd5, 0x21, 0xe2, 0x33, 0x80, 0x3a, 0xf8, 0xa1, + 0x58, 0x1b, 0xcc, 0x61, 0xe3, 0xba, 0xd9, 0x3e, 0xc3, 0x5a, 0xaa, 0xbc, + 0x0c, 0x67, 0x0a, 0x41, 0xcc, 0x77, 0xb3, 0xb8, 0x43, 0x43, 0x43, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, - 0x53, 0x48, 0x20, 0x00, 0xa8, 0x51, 0xa7, 0x5a, 0x68, 0xcb, 0x23, 0x3b, - 0xb3, 0xad, 0x28, 0x51, 0x84, 0x7c, 0xb4, 0x76, 0x1d, 0x33, 0x29, 0xdd, - 0x07, 0x44, 0xe1, 0x68, 0xec, 0xdd, 0x61, 0x02, 0x20, 0x3f, 0x1c, 0xfd, - 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x45, + 0x53, 0x48, 0x20, 0x00, 0xd2, 0x98, 0x77, 0xab, 0xf4, 0x02, 0x99, 0x2b, + 0x5d, 0xda, 0xac, 0xe3, 0x25, 0xb7, 0xe0, 0xfd, 0x5f, 0x85, 0x65, 0x3b, + 0x16, 0xb8, 0x21, 0xa3, 0x6e, 0x13, 0x5b, 0x11, 0x32, 0x77, 0xca, 0xc2, + 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x45, 0x4e, 0x44, 0x54, 0x20, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, - 0x0d, 0x00, 0x01, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x00, 0x00, 0x80, 0x56, 0x41, 0x54, 0x59, 0x03, 0x00, 0x01, 0x00, 0x04, - 0x45, 0x4e, 0x44, 0x54, 0x2c, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, - 0x18, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x00, 0x00, 0x80, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, - 0x01, 0x80, 0x56, 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x04, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x44, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xce, 0x02, 0x00, 0x00, - 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, - 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, - 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, - 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, - 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, - 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, - 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, - 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, - 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, - 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, - 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, - 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, - 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, - 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, - 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, - 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, - 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, - 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, - 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, - 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, - 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, - 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, - 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, - 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, - 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, - 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, - 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, - 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, - 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, - 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, - 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, - 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, - 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, - 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, - 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, - 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, - 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, - 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, - 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, - 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, - 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, + 0x45, 0x4e, 0x44, 0x54, 0x29, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, + 0x15, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x56, + 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x06, 0x45, 0x4e, 0x44, + 0x54, 0x35, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x20, 0x00, 0x03, + 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x80, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x02, 0x80, 0x56, 0x41, 0x54, 0x59, 0x05, + 0x00, 0x03, 0x00, 0x04, 0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa4, 0x0b, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0xe6, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x83, 0x00, + 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, + 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, + 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, + 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, + 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, + 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, + 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, + 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, + 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, + 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, + 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, + 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, + 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, + 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, + 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, - 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, - 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, - 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, - 0x36, 0x18, 0x82, 0x00, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x06, 0x60, 0x01, - 0x2a, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, - 0x1b, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, - 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, - 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, - 0xc3, 0x08, 0x04, 0x60, 0x85, 0x00, 0x86, 0x11, 0x04, 0x20, 0x09, 0xc2, - 0x4c, 0xd4, 0x3c, 0xd0, 0x83, 0x3c, 0xd4, 0xc3, 0x38, 0xd0, 0x83, 0x1b, - 0xb4, 0x43, 0x39, 0xd0, 0x43, 0x38, 0xb0, 0x83, 0x1e, 0xe8, 0x41, 0x3b, - 0x84, 0x03, 0x3d, 0xc8, 0x43, 0x3a, 0xe0, 0x03, 0x0a, 0xc8, 0x20, 0x42, - 0x21, 0x14, 0x42, 0x0c, 0x63, 0xe8, 0x0c, 0x04, 0xcc, 0x11, 0x80, 0x41, - 0x0a, 0xa8, 0x39, 0x02, 0x50, 0x18, 0x44, 0x08, 0x84, 0x61, 0x04, 0x42, - 0x19, 0x01, 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, - 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, - 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, - 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, - 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, - 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, - 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, - 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, - 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, - 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, - 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, - 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, - 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, - 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, - 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, - 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, - 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, - 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, - 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, - 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, - 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, - 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, - 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, - 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, - 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, - 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x41, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, - 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, - 0x80, 0x01, 0x45, 0x50, 0x20, 0x85, 0x50, 0x10, 0x65, 0x40, 0x6c, 0x04, - 0x80, 0xd6, 0x58, 0xc2, 0x02, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, - 0xcf, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, - 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, 0x28, 0x06, 0xe1, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0x86, - 0x66, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, - 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0x86, 0x66, 0x26, 0x65, 0x88, 0x90, - 0x10, 0x43, 0x0c, 0x25, 0x50, 0x0e, 0x45, 0x60, 0xd1, 0x54, 0x46, 0x17, + 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, + 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, + 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, + 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, + 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, + 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, + 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, + 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, + 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, + 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, + 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, + 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x18, 0xc2, 0x00, 0x2c, 0x40, + 0xb5, 0xc1, 0x18, 0x08, 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x60, 0x87, 0x10, + 0xc0, 0x30, 0x82, 0x00, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, + 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, + 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, + 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x52, 0x88, 0x11, 0x8c, + 0xa1, 0x33, 0x10, 0x30, 0x47, 0x00, 0x06, 0x29, 0xa0, 0xe6, 0x08, 0x40, + 0x61, 0x10, 0x21, 0x10, 0x86, 0x11, 0x08, 0x65, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, + 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, + 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, + 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, + 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, + 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, + 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, + 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x41, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, + 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x80, 0x01, + 0x45, 0x50, 0x20, 0x65, 0x50, 0x08, 0x05, 0x41, 0x6c, 0x04, 0x80, 0xd6, + 0x58, 0xc2, 0x12, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xe4, 0x00, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, 0xc0, 0xa2, + 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x28, 0x41, 0x22, 0x28, 0x07, 0xe5, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0x06, + 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, + 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x90, + 0x10, 0x43, 0x0c, 0x25, 0x50, 0x10, 0x45, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, 0x0e, 0x25, 0x50, 0x02, 0x45, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, @@ -217,235 +219,243 @@ const unsigned char sdl_metallib[] = { 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x64, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, 0x88, 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, 0xb9, 0x0d, 0x51, 0x92, 0x27, - 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x4e, 0x58, 0x9a, 0x9c, 0x0b, 0xdc, - 0x5b, 0x9a, 0x1b, 0xdd, 0xd7, 0x5c, 0x9a, 0x5e, 0x19, 0x0b, 0x33, 0xb6, - 0xb7, 0x30, 0x3a, 0x26, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, - 0x65, 0x43, 0x94, 0xa4, 0x4a, 0xa0, 0xc4, 0x4a, 0xa4, 0xe4, 0x1a, 0x42, - 0x24, 0x54, 0x82, 0x11, 0x0a, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0xa3, - 0x2b, 0xc3, 0xfb, 0x4a, 0x73, 0x83, 0xab, 0xa3, 0xa3, 0x14, 0x96, 0x26, - 0xe7, 0xc2, 0xf6, 0x36, 0x16, 0x46, 0x97, 0xf6, 0xe6, 0xf6, 0x95, 0xe6, - 0x46, 0x56, 0x86, 0x47, 0xef, 0xac, 0xcc, 0xad, 0x4c, 0x2e, 0x8c, 0xae, - 0x8c, 0x0c, 0xe5, 0xeb, 0x2b, 0x2c, 0x4d, 0xee, 0x0b, 0x8e, 0x2d, 0x6c, - 0xac, 0x0c, 0xed, 0x8d, 0x8d, 0xac, 0x4c, 0xee, 0xeb, 0x2b, 0x85, 0x86, - 0x19, 0xdb, 0x5b, 0x18, 0x9d, 0xcc, 0x10, 0x4a, 0x11, 0x12, 0x2d, 0xd9, - 0x14, 0x41, 0x09, 0x12, 0x2e, 0x81, 0x92, 0x2e, 0x91, 0x92, 0x89, 0x4a, - 0x58, 0x9a, 0x9c, 0x8b, 0x58, 0x9d, 0x99, 0x59, 0x99, 0x1c, 0x9f, 0xb0, - 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, 0xb3, 0x32, 0xb9, 0xaf, 0xb9, 0x34, - 0xbd, 0x32, 0x22, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x8c, - 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xe8, 0xf2, 0xe0, 0xca, - 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x78, 0x85, 0xa5, 0xc9, 0xb9, 0x84, 0xc9, - 0x9d, 0x7d, 0xd1, 0xe5, 0xc1, 0x95, 0x7d, 0x85, 0xb1, 0xa5, 0x9d, 0xb9, - 0x7d, 0xcd, 0xa5, 0xe9, 0x95, 0x11, 0x31, 0x63, 0x7b, 0x0b, 0xa3, 0xa3, - 0xc1, 0xa3, 0xa1, 0x02, 0x27, 0xf7, 0xa6, 0x56, 0x36, 0x46, 0x97, 0xf6, - 0xe6, 0x36, 0x04, 0x0c, 0x94, 0x20, 0xf9, 0x12, 0x30, 0x50, 0x86, 0x64, - 0x53, 0x08, 0x25, 0x48, 0xc2, 0x20, 0x11, 0x03, 0x65, 0x48, 0xc6, 0x40, - 0x29, 0x12, 0x28, 0x21, 0x83, 0x44, 0x4a, 0xca, 0x80, 0x09, 0x9d, 0x5c, - 0x98, 0xdb, 0x9c, 0xd9, 0x9b, 0x5c, 0xdb, 0x10, 0x30, 0x50, 0x88, 0xe4, - 0x4b, 0xc0, 0x40, 0x19, 0x92, 0x4d, 0x41, 0x94, 0x20, 0x09, 0x83, 0x44, - 0x0c, 0x94, 0x21, 0x19, 0x03, 0xa5, 0x48, 0xa0, 0x84, 0x0c, 0x12, 0x29, - 0x39, 0x83, 0x21, 0x46, 0xe2, 0x25, 0x66, 0x90, 0xa0, 0xc1, 0x10, 0x03, - 0x01, 0x92, 0x2c, 0x49, 0x03, 0x3e, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, - 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x7c, 0xa6, 0xd2, - 0xda, 0xe0, 0xd8, 0xca, 0x40, 0x86, 0x56, 0x56, 0x40, 0xa8, 0x84, 0x82, - 0x82, 0x86, 0x08, 0x09, 0x1b, 0x0c, 0x31, 0x92, 0x35, 0x48, 0xda, 0x80, - 0x49, 0x86, 0x18, 0x89, 0x1b, 0x24, 0x6e, 0xc0, 0x24, 0x23, 0x22, 0x76, - 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x77, 0x20, 0x87, 0x7a, - 0x60, 0x87, 0x72, 0x70, 0x03, 0x73, 0x60, 0x87, 0x70, 0x38, 0x87, 0x79, - 0x98, 0x22, 0x04, 0xc3, 0x08, 0x85, 0x1d, 0xd8, 0xc1, 0x1e, 0xda, 0xc1, - 0x0d, 0xd2, 0x81, 0x1c, 0xca, 0xc1, 0x1d, 0xe8, 0x61, 0x4a, 0x50, 0x8c, - 0x58, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, 0xec, 0xa1, 0x1c, 0xe4, 0x61, - 0x1e, 0xd2, 0xe1, 0x1d, 0xdc, 0x61, 0x4a, 0x60, 0x8c, 0xa0, 0xc2, 0x21, - 0x1d, 0xe4, 0xc1, 0x0d, 0xd8, 0x21, 0x1c, 0xdc, 0xe1, 0x1c, 0xea, 0x21, - 0x1c, 0xce, 0xa1, 0x1c, 0x7e, 0xc1, 0x1e, 0xca, 0x41, 0x1e, 0xe6, 0x21, - 0x1d, 0xde, 0xc1, 0x1d, 0xa6, 0x04, 0xc8, 0x88, 0x29, 0x1c, 0xd2, 0x41, - 0x1e, 0xdc, 0x60, 0x1c, 0xde, 0xa1, 0x1d, 0xe0, 0x21, 0x1d, 0xd8, 0xa1, - 0x1c, 0x7e, 0xe1, 0x1d, 0xe0, 0x81, 0x1e, 0xd2, 0xe1, 0x1d, 0xdc, 0x61, - 0x1e, 0xa6, 0x0c, 0x0a, 0xe3, 0x8c, 0x50, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, - 0x0d, 0xec, 0xa1, 0x1c, 0xe4, 0x81, 0x1e, 0xca, 0x01, 0x1f, 0xa6, 0x04, - 0x6a, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, - 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, - 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, - 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, - 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, - 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, - 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, - 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, - 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, - 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, - 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, - 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, - 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, - 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, - 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, - 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, - 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, - 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, - 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, - 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, - 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, - 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, - 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, - 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, - 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, - 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, - 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, - 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, - 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, - 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, - 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, - 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, - 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, - 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, - 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, - 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, - 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, - 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, - 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, - 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, - 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0xb1, 0x5d, - 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, 0x45, 0x44, 0x13, 0x71, 0x01, 0x00, - 0x61, 0x20, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, - 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xe4, 0xc6, 0x22, 0x86, - 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, 0x22, 0x82, 0x20, 0x08, - 0x46, 0x00, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, 0x8d, 0x19, 0x00, 0x12, - 0x33, 0x00, 0x14, 0x66, 0x00, 0x08, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, - 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x11, 0x0c, 0x74, 0x41, 0x14, 0x94, 0xf1, - 0x88, 0x47, 0xca, 0x24, 0x0a, 0xca, 0x20, 0xc3, 0x60, 0x30, 0x26, 0x04, - 0xf2, 0x19, 0x8f, 0x98, 0xac, 0xae, 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x4a, - 0x64, 0x42, 0x20, 0x1f, 0x0b, 0x0a, 0xf8, 0x8c, 0x47, 0x60, 0x9b, 0x18, - 0x40, 0x14, 0x94, 0x41, 0x06, 0xe6, 0xb9, 0x4c, 0x08, 0xe4, 0x63, 0x45, - 0x00, 0x9f, 0xf1, 0x88, 0x0e, 0x0c, 0xce, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, - 0x44, 0x54, 0x67, 0x42, 0x20, 0x1f, 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x84, - 0x41, 0x19, 0xb0, 0x01, 0x47, 0x41, 0x19, 0x64, 0x08, 0xb2, 0xcf, 0x82, - 0x4a, 0x3e, 0x83, 0x0c, 0xc3, 0x26, 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, - 0x80, 0xcf, 0x20, 0x83, 0xe1, 0x99, 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, - 0xe0, 0x33, 0xc8, 0x90, 0x84, 0x81, 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, - 0x00, 0x3e, 0xe3, 0x11, 0x6e, 0x20, 0x07, 0x79, 0x80, 0x06, 0x14, 0x94, - 0x41, 0x86, 0xc0, 0x0c, 0xd8, 0xc0, 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, - 0x80, 0x06, 0x6f, 0x60, 0x01, 0x18, 0xc8, 0x67, 0x90, 0xa1, 0x50, 0x03, - 0x39, 0xb0, 0xa0, 0x93, 0xcf, 0x20, 0xc3, 0xc1, 0x06, 0x75, 0x60, 0x81, - 0x26, 0x9f, 0x41, 0x06, 0x3d, 0x80, 0x03, 0x3a, 0xb0, 0x2c, 0x90, 0xcf, - 0x20, 0x03, 0x1f, 0xc8, 0xc1, 0x1d, 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, - 0x3e, 0x16, 0x30, 0xf0, 0xb1, 0x20, 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, - 0x28, 0xe0, 0x33, 0xdb, 0x80, 0x07, 0x01, 0x30, 0xdb, 0x10, 0xdc, 0x41, - 0x90, 0x41, 0x40, 0x0c, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0x78, - 0x83, 0x2d, 0xc3, 0x10, 0xbc, 0xc1, 0x96, 0xe1, 0x08, 0xde, 0x60, 0xcb, - 0xc0, 0x04, 0x6f, 0xb0, 0x65, 0x88, 0x82, 0x37, 0xd8, 0x32, 0x58, 0xc1, - 0x1b, 0x6c, 0x19, 0xc6, 0x20, 0x78, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x68, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, - 0x21, 0x0c, 0x00, 0x00, 0xd7, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, - 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, - 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, - 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, - 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, - 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, - 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, - 0x83, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, - 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, - 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, - 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, - 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, - 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, - 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, - 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, - 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, - 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, - 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, - 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, - 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, - 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, - 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, - 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, - 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, - 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, - 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, - 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, - 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, - 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, - 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, - 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, - 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, - 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, - 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, - 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, - 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, - 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, - 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, - 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, - 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, - 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5d, + 0x99, 0x1c, 0x5d, 0x19, 0xde, 0xd7, 0x5b, 0x1d, 0x1d, 0x5c, 0x1d, 0x1d, + 0xad, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x94, 0x9a, + 0xb1, 0x37, 0xb6, 0x37, 0x39, 0x22, 0x3b, 0x9a, 0x2f, 0xb3, 0x14, 0x16, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x98, 0xa4, 0x4a, 0xac, 0x04, 0x4a, + 0xa2, 0x44, 0x4a, 0x2e, 0x3a, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x2c, 0xcc, 0xd8, 0xde, 0xc2, + 0xe8, 0x98, 0xc0, 0xbd, 0xa5, 0xb9, 0xd1, 0x4d, 0xa5, 0xe9, 0x95, 0x0d, + 0x51, 0x92, 0x2c, 0x81, 0x12, 0x2d, 0x91, 0x92, 0x6d, 0x88, 0x91, 0x50, + 0x09, 0x96, 0x70, 0x84, 0xc2, 0xd2, 0xe4, 0x5c, 0xec, 0xca, 0xe4, 0xe8, + 0xca, 0xf0, 0xbe, 0xd2, 0xdc, 0xe0, 0xea, 0xe8, 0x28, 0x85, 0xa5, 0xc9, + 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, + 0x91, 0x95, 0xe1, 0xd1, 0x3b, 0x2b, 0x73, 0x2b, 0x93, 0x0b, 0xa3, 0x2b, + 0x23, 0x43, 0xf9, 0xfa, 0x0a, 0x4b, 0x93, 0xfb, 0x82, 0x63, 0x0b, 0x1b, + 0x2b, 0x43, 0x7b, 0x63, 0x23, 0x2b, 0x93, 0xfb, 0xfa, 0x4a, 0xa1, 0x61, + 0xc6, 0xf6, 0x16, 0x46, 0x27, 0x33, 0x84, 0x52, 0x84, 0xc4, 0x4b, 0x3e, + 0x45, 0x50, 0x82, 0x04, 0x0c, 0x12, 0x28, 0x09, 0x83, 0x44, 0x4a, 0xa6, + 0x21, 0x94, 0x12, 0x24, 0x5e, 0xf2, 0x29, 0x81, 0x12, 0x24, 0x60, 0x90, + 0x40, 0x49, 0x94, 0x48, 0xc9, 0x45, 0x25, 0x2c, 0x4d, 0xce, 0x45, 0xac, + 0xce, 0xcc, 0xac, 0x4c, 0x8e, 0x4f, 0x58, 0x9a, 0x9c, 0x8b, 0x58, 0x9d, + 0x99, 0x59, 0x99, 0xdc, 0xd7, 0x5c, 0x9a, 0x5e, 0x19, 0x91, 0xb0, 0x34, + 0x39, 0x17, 0xb9, 0xb2, 0x30, 0x32, 0x46, 0x61, 0x69, 0x72, 0x2e, 0x61, + 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0xbc, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xe8, 0xf2, 0xe0, + 0xca, 0xbe, 0xc2, 0xd8, 0xd2, 0xce, 0xdc, 0xbe, 0xe6, 0xd2, 0xf4, 0xca, + 0x88, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xd1, 0xe0, 0xd1, 0x50, 0x81, 0x93, + 0x7b, 0x53, 0x2b, 0x1b, 0xa3, 0x4b, 0x7b, 0x73, 0x1b, 0x02, 0x06, 0x0a, + 0x91, 0x90, 0x41, 0x52, 0x06, 0xca, 0x90, 0x7c, 0x0a, 0xa1, 0x04, 0x89, + 0x19, 0x24, 0x67, 0xa0, 0x0c, 0x09, 0x1a, 0x28, 0x45, 0x02, 0x25, 0x69, + 0x90, 0x48, 0x89, 0x1a, 0x30, 0xa1, 0x93, 0x0b, 0x73, 0x9b, 0x33, 0x7b, + 0x93, 0x6b, 0x1b, 0x02, 0x06, 0x8a, 0x91, 0x90, 0x41, 0x52, 0x06, 0xca, + 0x90, 0x7c, 0x8a, 0xa1, 0x04, 0x89, 0x19, 0x24, 0x67, 0xa0, 0x0c, 0x09, + 0x1a, 0x28, 0x45, 0x02, 0x25, 0x69, 0x90, 0x48, 0x09, 0x1b, 0x0c, 0x41, + 0x12, 0x31, 0x48, 0xc6, 0x20, 0x59, 0x83, 0xa4, 0x0d, 0x86, 0x18, 0x08, + 0x90, 0x74, 0x89, 0x1b, 0xf0, 0x79, 0x6b, 0x73, 0x4b, 0x83, 0x7b, 0xa3, + 0x2b, 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, 0x93, 0xe3, 0x33, 0x95, 0xd6, + 0x06, 0xc7, 0x56, 0x06, 0x32, 0xb4, 0xb2, 0x02, 0x42, 0x25, 0x14, 0x14, + 0x34, 0x44, 0x48, 0xe2, 0x60, 0x88, 0x91, 0xc0, 0x41, 0x22, 0x07, 0x4c, + 0x32, 0xc4, 0x48, 0xe6, 0x20, 0x99, 0x03, 0x26, 0x19, 0x11, 0xb1, 0x03, + 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, 0x03, 0x39, 0xd4, 0x03, + 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, 0xc3, 0x39, 0xcc, 0xc3, + 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, + 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, 0x53, 0x82, 0x62, 0xc4, + 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, + 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, 0x04, 0x15, 0x0e, 0xe9, + 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, 0xe7, 0x50, 0x0f, 0xe1, + 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, 0xf2, 0x30, 0x0f, 0xe9, + 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, 0xe1, 0x90, 0x0e, 0xf2, + 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, + 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0xf3, + 0x30, 0x65, 0x50, 0x18, 0x67, 0x84, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, + 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf4, 0x50, 0x0e, 0xf8, 0x30, 0x25, 0x78, + 0x03, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0xb1, 0x5d, 0xf9, 0xb3, + 0xce, 0x82, 0x0c, 0x7f, 0x45, 0x44, 0x13, 0x71, 0x01, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, + 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, 0x22, 0x82, 0x20, 0x08, 0x46, 0x00, + 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, 0x8d, 0x19, 0x00, 0x12, 0x33, 0x00, + 0x14, 0x66, 0x00, 0x08, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0x1f, 0x00, + 0x00, 0x00, 0xe3, 0x11, 0x4c, 0x84, 0x45, 0x14, 0x94, 0xf1, 0x88, 0x67, + 0xd2, 0x26, 0x0a, 0xca, 0x20, 0xc3, 0x60, 0x30, 0x26, 0x04, 0xf2, 0x19, + 0x8f, 0x98, 0x2e, 0xaf, 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x4a, 0x64, 0x42, + 0x20, 0x1f, 0x0b, 0x0a, 0xf8, 0x8c, 0x47, 0x60, 0xdc, 0x18, 0x40, 0x14, + 0x94, 0x41, 0x06, 0xe6, 0xb9, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, + 0xf1, 0x88, 0x2e, 0x0c, 0xd0, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x54, + 0x67, 0x42, 0x20, 0x1f, 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x84, 0x81, 0x19, + 0xb4, 0x01, 0x47, 0x41, 0x19, 0x64, 0x08, 0xb2, 0xcf, 0x82, 0x4a, 0x3e, + 0x83, 0x0c, 0xc3, 0x26, 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, + 0x20, 0x83, 0xe1, 0x99, 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, + 0xc8, 0x90, 0x84, 0x81, 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, + 0xe3, 0x11, 0x6e, 0x30, 0x07, 0x7a, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, + 0xc0, 0x0c, 0xd8, 0xc0, 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x80, 0x06, + 0x6f, 0x60, 0x01, 0x18, 0xc8, 0x67, 0x90, 0xa1, 0x50, 0x03, 0x39, 0xb0, + 0xa0, 0x93, 0xcf, 0x20, 0xc3, 0xc1, 0x06, 0x75, 0x60, 0x81, 0x26, 0x9f, + 0x41, 0x86, 0x3d, 0x80, 0x03, 0x3a, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, + 0x1f, 0xc8, 0xc1, 0x1d, 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, + 0x30, 0xf0, 0xb1, 0x20, 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, + 0x33, 0xdb, 0x80, 0x07, 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, + 0x10, 0xe0, 0x81, 0x90, 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x5b, 0x86, 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, + 0x96, 0xe1, 0x08, 0xe8, 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, + 0x02, 0x3a, 0xd8, 0x32, 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xb4, 0x0b, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xea, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, - 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, - 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, - 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x18, 0xc2, 0x00, - 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x08, 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, - 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, - 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, - 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, - 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, - 0x8c, 0x20, 0x00, 0x56, 0x08, 0x22, 0x09, 0xc2, 0x4c, 0xd4, 0x3c, 0xd0, - 0x83, 0x3c, 0xd4, 0xc3, 0x38, 0xd0, 0x83, 0x1b, 0xb4, 0x43, 0x39, 0xd0, - 0x43, 0x38, 0xb0, 0x83, 0x1e, 0xe8, 0x41, 0x3b, 0x84, 0x03, 0x3d, 0xc8, - 0x43, 0x3a, 0xe0, 0x03, 0x0a, 0xc8, 0x20, 0x42, 0x21, 0x94, 0x62, 0x08, - 0x61, 0x0c, 0x9d, 0x81, 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x35, 0x47, - 0x00, 0x0a, 0x83, 0x08, 0x81, 0x30, 0x8c, 0x40, 0x28, 0x23, 0x00, 0x00, - 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, - 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, 0x83, 0x38, - 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, - 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, - 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, - 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, - 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, - 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, - 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, - 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, - 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, - 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x41, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x80, 0x01, 0x45, 0x50, - 0x20, 0x65, 0x50, 0x08, 0x05, 0x41, 0x6c, 0x04, 0x80, 0xd6, 0x58, 0xc2, - 0x02, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, - 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, - 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, 0xc0, 0xa2, 0x50, 0xb9, - 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, - 0x41, 0x22, 0x28, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, - 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, - 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0x86, 0x66, 0x06, 0x04, 0xa5, - 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, - 0xc6, 0x25, 0x86, 0x66, 0x26, 0x65, 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, - 0x50, 0x10, 0x45, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, - 0x0e, 0x25, 0x50, 0x02, 0x45, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x18, 0x02, 0x01, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x0a, + 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x76, 0x08, 0x41, + 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, + 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, 0xd0, 0x03, + 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, 0x40, 0x01, + 0x19, 0x44, 0x28, 0x84, 0x62, 0x0c, 0x11, 0x84, 0x31, 0x74, 0x06, 0x02, + 0xe6, 0x08, 0xc0, 0x20, 0x05, 0xd4, 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x04, + 0xc2, 0x30, 0x02, 0xa1, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xb2, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, + 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, + 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, + 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, + 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, + 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, + 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, + 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, + 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, + 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, + 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, + 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0x30, 0x84, 0x41, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x52, 0x25, 0x50, 0x04, 0x23, 0x00, 0x05, 0x18, 0x50, 0x08, 0x65, + 0x50, 0x20, 0x05, 0x41, 0x6c, 0x04, 0x80, 0xd6, 0x58, 0xc2, 0x12, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x22, 0x24, 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, + 0x28, 0x05, 0xe5, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, + 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, + 0xc6, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, + 0x50, 0x10, 0x65, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, + 0x0e, 0x25, 0x50, 0x02, 0x65, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x48, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, @@ -461,229 +471,235 @@ const unsigned char sdl_metallib[] = { 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, 0x88, 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, 0xb9, 0x0d, 0x51, 0x92, 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5d, 0x99, 0x1c, 0x5d, 0x19, - 0xde, 0xd7, 0x5b, 0x1d, 0x1d, 0x5c, 0x1d, 0x1d, 0xb3, 0xb3, 0x32, 0xb7, - 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x14, 0x1c, 0xba, 0x32, 0xbc, 0xb1, - 0xb7, 0x37, 0x39, 0x32, 0x22, 0x3b, 0x99, 0x2f, 0xb3, 0x14, 0x1a, 0x66, - 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x44, 0xe8, 0xca, 0xf0, 0xc6, 0xde, 0xde, - 0xe4, 0xc8, 0x86, 0x30, 0x49, 0x95, 0x58, 0x09, 0x94, 0x5c, 0x89, 0x94, - 0x60, 0x43, 0x88, 0x84, 0x4a, 0x32, 0x42, 0x61, 0x69, 0x72, 0x2e, 0x76, - 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x94, - 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, - 0xbe, 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0xe8, 0x9d, 0x95, 0xb9, 0x95, 0xc9, - 0x85, 0xd1, 0x95, 0x91, 0xa1, 0x7c, 0x7d, 0x85, 0xa5, 0xc9, 0x7d, 0xc1, - 0xb1, 0x85, 0x8d, 0x95, 0xa1, 0xbd, 0xb1, 0x91, 0x95, 0xc9, 0x7d, 0x7d, - 0xa5, 0x0c, 0xa1, 0x14, 0x21, 0xd9, 0x12, 0x4e, 0x11, 0x94, 0x20, 0xe9, - 0x12, 0x28, 0xb9, 0x12, 0x29, 0x99, 0x86, 0x50, 0x4a, 0x90, 0x6c, 0x09, - 0xa7, 0x04, 0x4a, 0x90, 0x74, 0x09, 0x94, 0x5c, 0x89, 0x94, 0x60, 0x54, - 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, 0xf8, 0x84, - 0xa5, 0xc9, 0xb9, 0x88, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0xcd, 0xa5, - 0xe9, 0x95, 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x63, - 0x14, 0x96, 0x26, 0xe7, 0x12, 0x26, 0x77, 0xf6, 0x45, 0x97, 0x07, 0x57, - 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x2b, 0x2c, 0x4d, 0xce, 0x25, 0x4c, - 0xee, 0xec, 0x8b, 0x2e, 0x0f, 0xae, 0xec, 0x2b, 0x8c, 0x2d, 0xed, 0xcc, - 0xed, 0x6b, 0x2e, 0x4d, 0xaf, 0x8c, 0x88, 0x19, 0xdb, 0x5b, 0x18, 0x1d, - 0x0d, 0x1e, 0x0d, 0x15, 0x38, 0xb9, 0x37, 0xb5, 0xb2, 0x31, 0xba, 0xb4, - 0x37, 0xb7, 0x21, 0x60, 0xa0, 0x10, 0x09, 0x18, 0x24, 0x61, 0xa0, 0x0c, - 0x09, 0xa7, 0x10, 0x4a, 0x90, 0x88, 0x41, 0x32, 0x06, 0xca, 0x90, 0x90, - 0x81, 0x52, 0x24, 0x50, 0x52, 0x06, 0x89, 0x94, 0x98, 0x01, 0x13, 0x3a, - 0xb9, 0x30, 0xb7, 0x39, 0xb3, 0x37, 0xb9, 0xb6, 0x21, 0x60, 0xa0, 0x18, - 0x09, 0x18, 0x24, 0x61, 0xa0, 0x0c, 0x09, 0xa7, 0x18, 0x4a, 0x90, 0x88, - 0x41, 0x32, 0x06, 0xca, 0x90, 0x90, 0x81, 0x52, 0x24, 0x50, 0x52, 0x06, - 0x89, 0x94, 0xa0, 0xc1, 0x10, 0x24, 0xf1, 0x92, 0x2f, 0x39, 0x83, 0x24, - 0x0d, 0x86, 0x18, 0x08, 0x90, 0x68, 0x89, 0x1a, 0xf0, 0x79, 0x6b, 0x73, - 0x4b, 0x83, 0x7b, 0xa3, 0x2b, 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, 0x93, - 0xe3, 0x33, 0x95, 0xd6, 0x06, 0xc7, 0x56, 0x06, 0x32, 0xb4, 0xb2, 0x02, - 0x42, 0x25, 0x14, 0x14, 0x34, 0x44, 0x48, 0xda, 0x60, 0x88, 0x91, 0xb0, - 0x41, 0xe2, 0x06, 0x4c, 0x32, 0xc4, 0x48, 0xde, 0x20, 0x79, 0x03, 0x26, - 0x19, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, - 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, - 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, - 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, - 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, - 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, - 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, - 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, - 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, - 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, - 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, - 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x84, 0x12, 0x0e, - 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf4, 0x50, 0x0e, - 0xf8, 0x30, 0x25, 0x58, 0x03, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, - 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, - 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, - 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, - 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, - 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, - 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, - 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, - 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, - 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, - 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, - 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, - 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, - 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, - 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, - 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, - 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, - 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, - 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, - 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, - 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, - 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, - 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, - 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, - 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, - 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, - 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, - 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, - 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, - 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, - 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, - 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, - 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, - 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, - 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, - 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, - 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, - 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, - 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, - 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, - 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, - 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x06, 0xf0, 0xb0, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x15, 0x11, 0x4d, - 0xc4, 0x05, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, - 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, - 0x22, 0x82, 0x20, 0x08, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, 0xb9, 0x11, - 0x00, 0x1a, 0x33, 0x00, 0x24, 0x66, 0x00, 0x28, 0xcc, 0x00, 0x00, 0x00, - 0xe3, 0x11, 0x0b, 0x74, 0x41, 0x14, 0x94, 0xf1, 0x08, 0x47, 0xca, 0x24, - 0x0a, 0xca, 0x20, 0xc3, 0x50, 0x20, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x90, - 0xac, 0xae, 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x09, 0x64, 0x42, 0x20, 0x1f, - 0x0b, 0x0a, 0xf8, 0x8c, 0x47, 0x5c, 0x9b, 0x18, 0x40, 0x14, 0x94, 0x41, - 0x06, 0xc6, 0xb1, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x08, - 0x0e, 0x0c, 0xce, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x13, 0x67, 0x42, - 0x20, 0x1f, 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x80, 0x41, 0x19, 0xb0, 0x01, - 0x47, 0x41, 0x19, 0x64, 0x08, 0xb0, 0xcd, 0x82, 0x4a, 0x3e, 0x83, 0x0c, - 0x83, 0x16, 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, - 0xd1, 0x95, 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, - 0x80, 0x41, 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, - 0x6d, 0x20, 0x07, 0x79, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xa0, 0x0c, - 0xd0, 0xc0, 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x70, 0x06, 0x6e, 0x60, - 0x01, 0x18, 0xc8, 0x67, 0x90, 0xa1, 0x48, 0x83, 0x38, 0xb0, 0xa0, 0x93, - 0xcf, 0x20, 0xc3, 0xb1, 0x06, 0x74, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x06, - 0x3d, 0x70, 0x03, 0x38, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x03, 0x1f, 0xc0, - 0x81, 0x1d, 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, - 0xb1, 0x20, 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, - 0x80, 0x07, 0x01, 0x30, 0xdb, 0x10, 0x8c, 0x42, 0x90, 0x41, 0x40, 0x0c, - 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0x80, 0x83, 0x2d, 0xc3, 0x10, - 0xc0, 0xc1, 0x96, 0xe1, 0x08, 0xe0, 0x60, 0xcb, 0xc0, 0x04, 0x70, 0xb0, - 0x65, 0x88, 0x02, 0x38, 0xd8, 0x32, 0x58, 0x01, 0x1c, 0x6c, 0x19, 0xc6, - 0x20, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x1c, 0x09, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x44, 0x02, 0x00, 0x00, - 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, - 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, - 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, - 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, - 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x08, - 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, - 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, - 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, - 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, - 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, - 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, - 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, - 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, - 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, - 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, - 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, - 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, - 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, - 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, - 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, - 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, - 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, - 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, - 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, - 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, - 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, - 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, - 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, - 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, - 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, - 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, - 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, - 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, - 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, - 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, - 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, - 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, - 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, - 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, - 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, - 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, - 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, - 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, - 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, - 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, - 0x36, 0x18, 0x42, 0x00, 0x2c, 0x40, 0x05, 0x00, 0x49, 0x18, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, - 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, - 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x28, 0x33, 0x00, - 0xc3, 0x08, 0x04, 0x30, 0x88, 0x10, 0x04, 0x45, 0x08, 0xa1, 0x19, 0x08, - 0x98, 0x23, 0x00, 0x83, 0x14, 0xb0, 0x39, 0x02, 0x50, 0x18, 0x01, 0x00, - 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, - 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, 0x83, 0x38, - 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, - 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, - 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, - 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, - 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, - 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, - 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, - 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, - 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, - 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x21, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0xb2, 0x12, 0x18, 0x01, 0x28, 0x90, 0x22, 0x28, 0x84, - 0x82, 0x20, 0x1c, 0x01, 0xa0, 0x1b, 0x4b, 0x58, 0x00, 0x00, 0x00, 0x00, - 0x79, 0x18, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, - 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, - 0x21, 0x86, 0x41, 0x14, 0xc0, 0x81, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, - 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x18, 0x41, 0x21, 0x18, 0x05, - 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, - 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, - 0x26, 0xc6, 0x25, 0x86, 0x66, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, - 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0x86, 0x66, - 0x26, 0x65, 0x88, 0x50, 0x10, 0x43, 0x0c, 0x23, 0x30, 0x0c, 0x43, 0x60, + 0xde, 0xd7, 0x5b, 0x1d, 0x1d, 0x5c, 0x1d, 0x1d, 0xad, 0xb3, 0x32, 0xb7, + 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x94, 0x9a, 0xb1, 0x37, 0xb6, 0x37, + 0x39, 0x22, 0x3b, 0x9a, 0x2f, 0xb3, 0x14, 0x16, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x43, 0x98, 0xa4, 0x4a, 0xac, 0x04, 0x4a, 0xa2, 0x44, 0x4a, 0x2e, + 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, + 0x66, 0x29, 0x34, 0xcc, 0xd8, 0xde, 0xc2, 0xe8, 0x64, 0x88, 0xd0, 0x95, + 0xe1, 0x8d, 0xbd, 0xbd, 0xc9, 0x91, 0x0d, 0x61, 0x92, 0x2a, 0xc9, 0x12, + 0x28, 0xd1, 0x12, 0x29, 0xd9, 0x86, 0x18, 0x09, 0x95, 0x60, 0x09, 0x47, + 0x28, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x8e, 0xae, 0x0c, 0xef, 0x2b, + 0xcd, 0x0d, 0xae, 0x8e, 0x8e, 0x52, 0x58, 0x9a, 0x9c, 0x0b, 0xdb, 0xdb, + 0x58, 0x18, 0x5d, 0xda, 0x9b, 0xdb, 0x57, 0x9a, 0x1b, 0x59, 0x19, 0x1e, + 0xbd, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x94, 0xaf, + 0xaf, 0xb0, 0x34, 0xb9, 0x2f, 0x38, 0xb6, 0xb0, 0xb1, 0x32, 0xb4, 0x37, + 0x36, 0xb2, 0x32, 0xb9, 0xaf, 0xaf, 0x94, 0x21, 0x94, 0x32, 0x24, 0x5e, + 0xf2, 0x29, 0x83, 0x12, 0x24, 0x60, 0x90, 0x40, 0x89, 0x96, 0x48, 0xc9, + 0x34, 0x84, 0x52, 0x82, 0xc4, 0x4b, 0x3e, 0x25, 0x50, 0x82, 0x04, 0x0c, + 0x12, 0x28, 0x89, 0x12, 0x29, 0xb9, 0x86, 0x50, 0x8a, 0x90, 0x78, 0xc9, + 0xa7, 0x08, 0x4a, 0x90, 0x80, 0x41, 0x02, 0x25, 0x5a, 0x22, 0x25, 0x1b, + 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, 0xb3, 0x32, 0x39, 0x3e, + 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x44, 0xc2, 0xd2, 0xe4, 0x5c, 0xe4, 0xca, 0xc2, 0xc8, + 0x18, 0x85, 0xa5, 0xc9, 0xb9, 0x84, 0xc9, 0x9d, 0x7d, 0xd1, 0xe5, 0xc1, + 0x95, 0x7d, 0xcd, 0xa5, 0xe9, 0x95, 0xf1, 0x0a, 0x4b, 0x93, 0x73, 0x09, + 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, 0xfb, 0x0a, 0x63, 0x4b, 0x3b, + 0x73, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x23, 0x62, 0xc6, 0xf6, 0x16, 0x46, + 0x47, 0x83, 0x47, 0x43, 0x05, 0x4e, 0xee, 0x4d, 0xad, 0x6c, 0x8c, 0x2e, + 0xed, 0xcd, 0x6d, 0x08, 0x18, 0x28, 0x46, 0x42, 0x06, 0x49, 0x19, 0x28, + 0x44, 0xf2, 0x29, 0x82, 0x12, 0x24, 0x66, 0x90, 0x9c, 0x81, 0x42, 0x24, + 0x68, 0xa0, 0x1c, 0x09, 0x94, 0xa4, 0x41, 0x22, 0x25, 0x6a, 0xc0, 0x84, + 0x4e, 0x2e, 0xcc, 0x6d, 0xce, 0xec, 0x4d, 0xae, 0x6d, 0x08, 0x18, 0x28, + 0x45, 0x42, 0x06, 0x49, 0x19, 0x28, 0x44, 0xf2, 0x29, 0x86, 0x12, 0x24, + 0x66, 0x90, 0x9c, 0x81, 0x42, 0x24, 0x68, 0xa0, 0x1c, 0x09, 0x94, 0xa4, + 0x41, 0x22, 0x25, 0x6c, 0x30, 0x44, 0x49, 0xc2, 0x20, 0x11, 0x83, 0x64, + 0x0c, 0x92, 0x35, 0x48, 0xda, 0x60, 0x88, 0x81, 0x00, 0x49, 0x97, 0xb8, + 0x01, 0x9f, 0xb7, 0x36, 0xb7, 0x34, 0xb8, 0x37, 0xba, 0x32, 0x37, 0x3a, + 0x90, 0x31, 0xb4, 0x30, 0x39, 0x3e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, + 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x43, 0x84, 0x24, + 0x0e, 0x86, 0x18, 0x09, 0x1c, 0x24, 0x72, 0xc0, 0x24, 0x43, 0x8c, 0x64, + 0x0e, 0x92, 0x39, 0x60, 0x92, 0x11, 0x11, 0x3b, 0xb0, 0x83, 0x3d, 0xb4, + 0x83, 0x1b, 0xb4, 0xc3, 0x3b, 0x90, 0x43, 0x3d, 0xb0, 0x43, 0x39, 0xb8, + 0x81, 0x39, 0xb0, 0x43, 0x38, 0x9c, 0xc3, 0x3c, 0x4c, 0x11, 0x82, 0x61, + 0x84, 0xc2, 0x0e, 0xec, 0x60, 0x0f, 0xed, 0xe0, 0x06, 0xe9, 0x40, 0x0e, + 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x28, 0x46, 0x2c, 0xe1, 0x90, 0x0e, + 0xf2, 0xe0, 0x06, 0xf6, 0x50, 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, + 0xee, 0x30, 0x25, 0x30, 0x46, 0x50, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, + 0xec, 0x10, 0x0e, 0xee, 0x70, 0x0e, 0xf5, 0x10, 0x0e, 0xe7, 0x50, 0x0e, + 0xbf, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, + 0x53, 0x02, 0x64, 0xc4, 0x14, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x30, 0x0e, + 0xef, 0xd0, 0x0e, 0xf0, 0x90, 0x0e, 0xec, 0x50, 0x0e, 0xbf, 0xf0, 0x0e, + 0xf0, 0x40, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x0f, 0x53, 0x06, 0x85, + 0x71, 0x46, 0x28, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xf6, 0x50, 0x0e, + 0xf2, 0x40, 0x0f, 0xe5, 0x80, 0x0f, 0x53, 0x82, 0x37, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x06, 0xf0, 0xb0, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x15, + 0x11, 0x4d, 0xc4, 0x05, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x52, 0x00, + 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, + 0x00, 0x00, 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, + 0x10, 0xc6, 0x22, 0x82, 0x20, 0x08, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, + 0xb9, 0x11, 0x00, 0x1a, 0x33, 0x00, 0x24, 0x66, 0x00, 0x28, 0xcc, 0x00, + 0x00, 0x00, 0xe3, 0x11, 0x4b, 0x74, 0x45, 0x14, 0x94, 0xf1, 0x08, 0x67, + 0xca, 0x26, 0x0a, 0xca, 0x20, 0xc3, 0x50, 0x20, 0x26, 0x04, 0xf2, 0x19, + 0x8f, 0x90, 0xae, 0xae, 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x09, 0x64, 0x42, + 0x20, 0x1f, 0x0b, 0x0a, 0xf8, 0x8c, 0x47, 0x5c, 0x9c, 0x18, 0x40, 0x14, + 0x94, 0x41, 0x06, 0xc6, 0xb1, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, + 0xf1, 0x08, 0x2e, 0x0c, 0xce, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x13, + 0x67, 0x42, 0x20, 0x1f, 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x80, 0x81, 0x19, + 0xb0, 0x01, 0x47, 0x41, 0x19, 0x64, 0x08, 0xb0, 0xcd, 0x82, 0x4a, 0x3e, + 0x83, 0x0c, 0x83, 0x16, 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, + 0x20, 0x83, 0xd1, 0x95, 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, + 0xc8, 0x90, 0x80, 0x41, 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, + 0xe3, 0x11, 0x6d, 0x30, 0x07, 0x79, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, + 0xa0, 0x0c, 0xd0, 0xc0, 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x70, 0x06, + 0x6e, 0x60, 0x01, 0x18, 0xc8, 0x67, 0x90, 0xa1, 0x48, 0x83, 0x38, 0xb0, + 0xa0, 0x93, 0xcf, 0x20, 0xc3, 0xb1, 0x06, 0x74, 0x60, 0x81, 0x26, 0x9f, + 0x41, 0x86, 0x3d, 0x70, 0x03, 0x38, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, + 0x1f, 0xc0, 0x81, 0x1d, 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, + 0x30, 0xf0, 0xb1, 0x20, 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, + 0x33, 0xdb, 0x80, 0x07, 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, + 0x10, 0x90, 0x82, 0x90, 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x5b, 0x86, 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, + 0x96, 0xe1, 0x08, 0xe8, 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, + 0x02, 0x3a, 0xd8, 0x32, 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xec, 0x08, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x38, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x08, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x00, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x10, 0x82, 0x00, 0x58, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x24, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x65, 0x08, 0x09, + 0x9a, 0x81, 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x1b, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, + 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, + 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, + 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, + 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, + 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, + 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, + 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x21, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x32, 0x1e, 0x98, 0x0c, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, + 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, 0x12, 0x18, 0x01, 0x28, 0x82, 0x42, + 0x28, 0x08, 0xba, 0xb1, 0x84, 0x25, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, + 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, + 0x31, 0x14, 0xc0, 0x61, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, + 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x18, 0x41, 0x21, 0x18, 0x04, 0xe5, 0x20, + 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, + 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, + 0x25, 0xc6, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, + 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0xc6, 0x25, + 0x26, 0x65, 0x88, 0x50, 0x10, 0x43, 0x0c, 0x23, 0x30, 0x0a, 0x43, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x29, 0x0e, 0x23, 0x30, 0x02, 0x43, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, @@ -698,1146 +714,1112 @@ const unsigned char sdl_metallib[] = { 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe2, 0x31, 0x84, - 0x02, 0x2a, 0xa2, 0x21, 0x42, 0x21, 0x51, 0x09, 0x4b, 0x93, 0x73, 0x11, - 0xab, 0x33, 0x33, 0x2b, 0x93, 0xe3, 0x13, 0x96, 0x26, 0xe7, 0x22, 0x56, - 0x67, 0x66, 0x56, 0x26, 0xf7, 0x35, 0x97, 0xa6, 0x57, 0x46, 0x29, 0x2c, - 0x4d, 0xce, 0x85, 0xed, 0x6d, 0x2c, 0x8c, 0x2e, 0xed, 0xcd, 0xed, 0x2b, - 0xcd, 0x8d, 0xac, 0x0c, 0x8f, 0x48, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x59, - 0x18, 0x19, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, - 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, - 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, - 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x64, 0xc2, 0xd2, 0xe4, - 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, 0x38, 0x8c, 0xbd, - 0xb1, 0x0d, 0x01, 0x03, 0x43, 0x28, 0xa8, 0xa2, 0x32, 0x86, 0xc2, 0x32, - 0x04, 0x23, 0x28, 0xae, 0x02, 0x33, 0x86, 0x22, 0x33, 0x86, 0x02, 0x2a, - 0xa2, 0x42, 0x2b, 0xb6, 0x21, 0x42, 0xc1, 0x0d, 0x31, 0x08, 0xa0, 0x98, - 0x8a, 0x8e, 0xcf, 0x5b, 0x9b, 0x5b, 0x1a, 0xdc, 0x1b, 0x5d, 0x99, 0x1b, - 0x1d, 0xc8, 0x18, 0x5a, 0x98, 0x1c, 0x9f, 0xa9, 0xb4, 0x36, 0x38, 0xb6, - 0x32, 0x90, 0xa1, 0x95, 0x15, 0x10, 0x2a, 0xa1, 0xa0, 0xa0, 0x21, 0x42, - 0x01, 0x06, 0x43, 0x8c, 0xe2, 0x2b, 0xc2, 0x00, 0x39, 0x86, 0x18, 0x85, - 0x18, 0x14, 0x62, 0x80, 0x1c, 0x23, 0x22, 0x76, 0x60, 0x07, 0x7b, 0x68, - 0x07, 0x37, 0x68, 0x87, 0x77, 0x20, 0x87, 0x7a, 0x60, 0x87, 0x72, 0x70, - 0x03, 0x73, 0x60, 0x87, 0x70, 0x38, 0x87, 0x79, 0x98, 0x22, 0x04, 0xc3, - 0x08, 0x85, 0x1d, 0xd8, 0xc1, 0x1e, 0xda, 0xc1, 0x0d, 0xd2, 0x81, 0x1c, - 0xca, 0xc1, 0x1d, 0xe8, 0x61, 0x4a, 0x50, 0x8c, 0x58, 0xc2, 0x21, 0x1d, - 0xe4, 0xc1, 0x0d, 0xec, 0xa1, 0x1c, 0xe4, 0x61, 0x1e, 0xd2, 0xe1, 0x1d, - 0xdc, 0x61, 0x4a, 0x60, 0x8c, 0xa0, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, - 0xd8, 0x21, 0x1c, 0xdc, 0xe1, 0x1c, 0xea, 0x21, 0x1c, 0xce, 0xa1, 0x1c, - 0x7e, 0xc1, 0x1e, 0xca, 0x41, 0x1e, 0xe6, 0x21, 0x1d, 0xde, 0xc1, 0x1d, - 0xa6, 0x04, 0xc8, 0x88, 0x29, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0x60, 0x1c, - 0xde, 0xa1, 0x1d, 0xe0, 0x21, 0x1d, 0xd8, 0xa1, 0x1c, 0x7e, 0xe1, 0x1d, - 0xe0, 0x81, 0x1e, 0xd2, 0xe1, 0x1d, 0xdc, 0x61, 0x1e, 0xa6, 0x0c, 0x0a, - 0xe3, 0x8c, 0x60, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, 0xcc, 0x41, 0x1e, - 0xc2, 0xe1, 0x1c, 0xda, 0xa1, 0x1c, 0xdc, 0x81, 0x1e, 0xa6, 0x04, 0x1e, - 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, - 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, - 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, - 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, - 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, - 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, - 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, - 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, - 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, - 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, - 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, - 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, - 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, - 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, - 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, - 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, - 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, - 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, - 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, - 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, - 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, - 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, - 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, - 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, - 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, - 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, - 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, - 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, - 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, - 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, - 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, - 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, - 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, - 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, - 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, - 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, - 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, - 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, - 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, - 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, - 0x71, 0x20, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x20, 0xb1, 0x5d, - 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, 0x11, 0x01, 0x06, 0x43, 0x34, 0x13, - 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x13, 0x04, 0x01, 0x05, 0x25, 0x83, 0x80, 0x18, 0x02, 0x00, 0x00, 0x00, - 0x5b, 0x06, 0x20, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0xf0, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xb9, 0x02, 0x00, 0x00, - 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, - 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, - 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, - 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, - 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, - 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, - 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, - 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, - 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, - 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, - 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, - 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, - 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, - 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, - 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, - 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, - 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, - 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, - 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, - 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, - 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, - 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, - 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, - 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, - 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, - 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, - 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, - 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, - 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, - 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, - 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, - 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, - 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, - 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, - 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, - 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, - 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, - 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, - 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, - 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, - 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, - 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, - 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, - 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, - 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, - 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, - 0x07, 0x60, 0x83, 0x21, 0x0c, 0xc0, 0x02, 0x54, 0x1b, 0x8c, 0x81, 0x00, - 0x16, 0xa0, 0xda, 0x60, 0x10, 0x05, 0xb0, 0x00, 0xd5, 0x06, 0xa4, 0xf8, - 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x36, 0x18, 0x46, - 0x00, 0x2c, 0x40, 0xb5, 0xc1, 0x38, 0x04, 0x60, 0x01, 0x2a, 0x00, 0x00, - 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, - 0x88, 0x09, 0x43, 0x61, 0x1c, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, - 0x1e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, - 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, - 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x4c, 0x33, 0x00, - 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, 0x08, 0x41, 0x70, 0x94, - 0x34, 0x45, 0x94, 0x30, 0xf9, 0xff, 0x44, 0x5c, 0x13, 0x15, 0x11, 0xbf, - 0x3d, 0xfc, 0xd3, 0x18, 0x01, 0x30, 0x88, 0x40, 0x04, 0x17, 0x49, 0x53, - 0x44, 0x09, 0x93, 0xff, 0x4b, 0x00, 0xf3, 0x2c, 0x44, 0xf4, 0x4f, 0x63, - 0x04, 0xc0, 0x20, 0x82, 0x21, 0x14, 0x23, 0x04, 0x31, 0xca, 0x21, 0x34, - 0x47, 0x10, 0xcc, 0x11, 0x80, 0xc1, 0x30, 0x82, 0xb0, 0x14, 0x24, 0x94, - 0x23, 0x14, 0x53, 0x80, 0xda, 0x40, 0x40, 0x0a, 0xac, 0x39, 0x02, 0x50, - 0x18, 0x01, 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, - 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, - 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, - 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, - 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, - 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, - 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, - 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, - 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, - 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, + 0x02, 0x2a, 0xa2, 0x21, 0x42, 0x21, 0x51, 0x0a, 0x4b, 0x93, 0x73, 0x31, + 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, 0xa3, 0xfb, 0x4a, 0x73, 0x83, 0xab, + 0xa3, 0x63, 0x76, 0x56, 0xe6, 0x56, 0x26, 0x17, 0x46, 0x57, 0x46, 0x86, + 0x82, 0x03, 0xf7, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x46, 0x64, 0x27, + 0xf3, 0x65, 0x96, 0x42, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0xac, 0xcc, 0x8d, + 0xae, 0x4c, 0x8e, 0x4f, 0x58, 0x9a, 0x9c, 0x0b, 0x5c, 0x99, 0xdc, 0x1c, + 0x5c, 0xd9, 0x18, 0x5d, 0x9a, 0x5d, 0x19, 0x0d, 0x33, 0xb6, 0xb7, 0x30, + 0x3a, 0x19, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x44, 0xe0, 0xde, 0xe6, 0xd2, 0xe8, 0xd2, 0xde, 0xdc, + 0x86, 0x48, 0x86, 0x50, 0x50, 0x45, 0x55, 0x58, 0xc5, 0x55, 0x40, 0x05, + 0x56, 0x64, 0x85, 0x46, 0xeb, 0xac, 0xcc, 0xad, 0x4c, 0x2e, 0x8c, 0xae, + 0x8c, 0x0c, 0xa5, 0x66, 0xec, 0x8d, 0xed, 0x4d, 0x8e, 0xc8, 0x8e, 0xe6, + 0xcb, 0x2c, 0x85, 0xc5, 0xd8, 0x1b, 0xdb, 0x9b, 0xdc, 0x10, 0xc9, 0x08, + 0x0a, 0xaa, 0xe0, 0x0a, 0xab, 0xb8, 0x0a, 0xa8, 0x88, 0x8a, 0xac, 0xe8, + 0x86, 0x10, 0xc5, 0x56, 0x78, 0x43, 0x0c, 0x02, 0x28, 0xa6, 0xe2, 0x1b, + 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, 0x03, + 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, 0xc3, + 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, 0xf6, + 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, 0x53, + 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, + 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, 0x04, + 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, 0xe7, + 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, 0xf2, + 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, 0xe1, + 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, 0xe9, + 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, 0xef, + 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, 0x0e, 0xe9, + 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, 0x0e, 0xe5, + 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x03, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x06, 0x20, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, + 0x11, 0x01, 0x06, 0x43, 0x34, 0x13, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x50, 0x0a, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x91, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x1b, 0xcc, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, + 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, + 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, + 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, + 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, + 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, + 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, + 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, + 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, + 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, + 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, + 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, + 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, + 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, + 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, + 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, + 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, + 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, + 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, + 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, + 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, + 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, + 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, + 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, + 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, + 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x60, 0x83, 0x21, 0x10, 0xc0, 0x02, 0x54, 0x1b, 0x8c, + 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x80, 0x10, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x00, 0x0c, 0x20, 0x01, 0xd5, 0x06, 0xa3, 0x08, 0x80, 0x05, 0xa8, 0x36, + 0x18, 0x86, 0x00, 0x2c, 0x40, 0x05, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x26, 0x0c, 0x44, 0x61, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x44, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0x47, 0x49, 0x53, 0x44, 0x09, 0x93, 0xff, 0x4f, 0xc4, 0x35, 0x51, + 0x11, 0xf1, 0xdb, 0xc3, 0x3f, 0x8d, 0x11, 0x00, 0x83, 0x08, 0x43, 0x70, + 0x91, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xbf, 0x04, 0x30, 0xcf, 0x42, 0x44, + 0xff, 0x34, 0x46, 0x00, 0x0c, 0x22, 0x14, 0x42, 0x31, 0x42, 0x08, 0x82, + 0x18, 0x3a, 0x73, 0x04, 0xc1, 0x1c, 0x01, 0x18, 0x0c, 0x23, 0x08, 0x4a, + 0x41, 0x02, 0x31, 0x22, 0xad, 0x04, 0x88, 0x0d, 0x04, 0xa4, 0x80, 0x1a, + 0x01, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, + 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, + 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, + 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, + 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, + 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, + 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, + 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x41, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc2, 0x34, 0x40, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x81, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, + 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x04, 0x85, + 0x50, 0x10, 0x65, 0x40, 0x6f, 0x2c, 0x61, 0x09, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, + 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, + 0x42, 0x38, 0xc0, 0x83, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, + 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x82, 0x23, 0x28, 0x05, 0xe5, 0x20, + 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, + 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, + 0x25, 0xc6, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, + 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0xc6, 0x25, + 0x26, 0x65, 0x88, 0xe0, 0x10, 0x43, 0x0c, 0x45, 0x50, 0x0c, 0x65, 0x60, + 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x71, 0x0e, 0x45, 0x50, 0x04, + 0x65, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, + 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, + 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x70, 0x12, 0x72, 0x61, 0x69, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, + 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x43, 0x04, 0x67, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, + 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, + 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, + 0x7d, 0x91, 0xa5, 0xcd, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x9c, 0x86, + 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, + 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, + 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, + 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x10, 0xe7, 0x51, 0x06, + 0x07, 0x72, 0xa2, 0x21, 0x82, 0x23, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, + 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, + 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, + 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, + 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, + 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, 0xb7, + 0x21, 0x90, 0x32, 0x38, 0x94, 0x53, 0x39, 0x96, 0x03, 0x39, 0x91, 0x73, + 0x39, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, + 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, + 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, + 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x14, 0xc1, 0xd1, 0x9c, + 0xcd, 0xa9, 0x1c, 0xce, 0x81, 0x9c, 0xc8, 0xb9, 0x9c, 0x8e, 0xd9, 0x59, + 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, 0x19, + 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, 0x0a, + 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x43, 0x24, 0x85, 0x70, 0x34, 0xe7, 0x73, 0x2a, + 0x87, 0x73, 0x20, 0x07, 0x0c, 0x9c, 0xcb, 0x09, 0x03, 0x2e, 0x61, 0x69, + 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x94, 0xc2, 0xd2, + 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, 0xd2, + 0xdc, 0xc8, 0xca, 0xf0, 0xa8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, 0xb5, + 0xc1, 0xb1, 0x95, 0x11, 0xa3, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, 0x93, + 0x21, 0xe3, 0x31, 0x63, 0x7b, 0x0b, 0xa3, 0x63, 0x01, 0x99, 0x0b, 0x6b, + 0x83, 0x63, 0x2b, 0xf3, 0xe1, 0x40, 0x57, 0x86, 0x37, 0x84, 0x52, 0x0e, + 0x67, 0x0c, 0x1c, 0x32, 0x50, 0x06, 0x45, 0x70, 0xca, 0xc0, 0x81, 0x1c, + 0x33, 0x70, 0x2e, 0xe7, 0x0c, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, + 0xb5, 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, 0x63, 0x2b, + 0x93, 0x63, 0x30, 0x37, 0x44, 0x52, 0x0a, 0x27, 0x0d, 0x1c, 0x32, 0x50, + 0x06, 0x45, 0x70, 0x20, 0x47, 0x0d, 0x9c, 0xcb, 0x59, 0x83, 0x21, 0x8a, + 0x93, 0x39, 0x9e, 0x23, 0x06, 0x0e, 0x1a, 0x38, 0x6c, 0x30, 0xc4, 0x40, + 0x00, 0x67, 0x72, 0xda, 0x60, 0x44, 0xc4, 0x0e, 0xec, 0x60, 0x0f, 0xed, + 0xe0, 0x06, 0xed, 0xf0, 0x0e, 0xe4, 0x50, 0x0f, 0xec, 0x50, 0x0e, 0x6e, + 0x60, 0x0e, 0xec, 0x10, 0x0e, 0xe7, 0x30, 0x0f, 0x53, 0x84, 0x60, 0x18, + 0xa1, 0xb0, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3a, 0x90, 0x43, + 0x39, 0xb8, 0x03, 0x3d, 0x4c, 0x09, 0x8a, 0x11, 0x4b, 0x38, 0xa4, 0x83, + 0x3c, 0xb8, 0x81, 0x3d, 0x94, 0x83, 0x3c, 0xcc, 0x43, 0x3a, 0xbc, 0x83, + 0x3b, 0x4c, 0x09, 0x8c, 0x11, 0x54, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x01, + 0x3b, 0x84, 0x83, 0x3b, 0x9c, 0x43, 0x3d, 0x84, 0xc3, 0x39, 0x94, 0xc3, + 0x2f, 0xd8, 0x43, 0x39, 0xc8, 0xc3, 0x3c, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, + 0x94, 0x00, 0x19, 0x31, 0x85, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0x8c, 0xc3, + 0x3b, 0xb4, 0x03, 0x3c, 0xa4, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x03, + 0x3c, 0xd0, 0x43, 0x3a, 0xbc, 0x83, 0x3b, 0xcc, 0xc3, 0x94, 0x41, 0x61, + 0x9c, 0x11, 0x4c, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xc8, 0x43, + 0x38, 0x9c, 0x43, 0x3b, 0x94, 0x83, 0x3b, 0xd0, 0xc3, 0x94, 0xc0, 0x0d, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x10, 0xb1, 0x5d, 0xf9, 0x73, + 0xce, 0x83, 0xfd, 0x45, 0x04, 0x18, 0x0c, 0xd1, 0x4c, 0x16, 0xb0, 0x01, + 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, + 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x0d, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb4, 0x46, 0x00, 0x28, 0xd5, 0xc0, + 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8a, 0x10, 0x44, 0x46, + 0x71, 0x0c, 0x84, 0x10, 0x58, 0x90, 0xc8, 0x27, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0xd4, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, + 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x32, 0x03, 0x00, 0x00, 0x0b, 0x82, + 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, + 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, + 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, + 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, + 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, + 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, + 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, + 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, + 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, + 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, + 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, + 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, + 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, + 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, + 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, + 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, + 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, + 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, + 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, + 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, + 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, + 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, + 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, + 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, + 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, + 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, + 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, + 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, + 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, + 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, + 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, + 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, + 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, + 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, + 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, + 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, + 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, + 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, + 0x83, 0x21, 0x10, 0xc0, 0x02, 0x54, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, + 0xda, 0x60, 0x10, 0x07, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x90, 0x00, 0x6a, 0x03, 0x62, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x30, 0x80, 0x04, 0x54, 0x1b, 0x8c, 0x23, 0x00, 0x16, 0xa0, + 0xda, 0x60, 0x20, 0x02, 0xb0, 0x00, 0x15, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, 0x88, 0x09, + 0x41, 0x31, 0x61, 0x30, 0x0e, 0x04, 0x89, 0x20, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, + 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, + 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, + 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, + 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, + 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, + 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, + 0x06, 0x11, 0x8c, 0xe0, 0x34, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, + 0xb8, 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0x81, 0x28, 0x02, 0xb0, 0x7f, + 0x1a, 0x23, 0x00, 0x06, 0x11, 0x90, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, + 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, + 0x44, 0x50, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x69, 0x11, 0x2b, 0x03, + 0x18, 0x83, 0xdc, 0x1c, 0x01, 0x18, 0xcc, 0x11, 0x04, 0xc3, 0x08, 0x02, + 0x54, 0x92, 0x90, 0x96, 0x80, 0x51, 0x46, 0x40, 0xb3, 0x20, 0xe1, 0x2c, + 0x11, 0x65, 0x04, 0x54, 0x07, 0x02, 0x52, 0x00, 0x0e, 0x23, 0x0c, 0xd0, + 0x20, 0x42, 0x20, 0xcc, 0x11, 0x80, 0xc2, 0x20, 0xc2, 0x20, 0x8c, 0x00, + 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, + 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, + 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, + 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, + 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, + 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, + 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, + 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x69, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc2, 0x3c, 0x40, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x28, 0x20, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x86, 0x30, 0x16, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x59, 0x20, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, + 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x78, 0x2c, + 0x61, 0x09, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x14, 0x01, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x74, 0x5c, 0x00, 0x06, + 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x40, 0xc4, 0x25, 0x40, 0x08, 0xe5, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0x06, + 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, + 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x70, + 0x11, 0x43, 0x0c, 0x88, 0x80, 0x14, 0xa8, 0x60, 0xd1, 0x54, 0x46, 0x17, + 0xc6, 0x36, 0x04, 0xb9, 0x0e, 0x88, 0x80, 0x08, 0xa8, 0xe0, 0x16, 0x96, + 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, + 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, + 0x56, 0x36, 0x44, 0xb8, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, + 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, + 0x6b, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, + 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, + 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x91, 0xa5, 0xcd, + 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0xae, 0x86, 0x51, 0x58, 0x9a, 0x9c, + 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, + 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, + 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x34, 0x43, 0x90, 0xeb, 0x81, 0x8a, 0x0b, 0xba, 0xa2, 0x21, + 0xc2, 0x25, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, + 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, + 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, + 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, + 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, + 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x54, 0x5c, + 0xd4, 0x55, 0x5d, 0xd6, 0x05, 0x5d, 0xd1, 0x75, 0x5d, 0x18, 0xa5, 0xb0, + 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, + 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, + 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, + 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, + 0xbd, 0xc9, 0x0d, 0x91, 0x20, 0xe2, 0xd2, 0xae, 0xed, 0xaa, 0x2e, 0xee, + 0x82, 0xae, 0xe8, 0xba, 0xae, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, + 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, + 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, + 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x43, 0x24, 0xe8, 0xb8, 0xb4, 0xeb, 0xbb, 0xaa, 0x8b, 0xbb, 0xa0, 0x0b, + 0x0c, 0xae, 0xeb, 0x0a, 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, + 0xcc, 0xca, 0xe4, 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, + 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, + 0x91, 0x95, 0xe1, 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, + 0x23, 0x15, 0x96, 0x26, 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, + 0x45, 0x97, 0x07, 0x57, 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, + 0xed, 0x2d, 0x8c, 0x6e, 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, + 0x0d, 0xa9, 0xb1, 0xb7, 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, + 0x66, 0x66, 0x34, 0x84, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0x01, + 0x54, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xa5, 0x01, 0x64, 0x40, 0x06, + 0x54, 0x5c, 0x68, 0x70, 0xa9, 0x01, 0xc4, 0x40, 0x06, 0x54, 0x5c, 0x68, + 0x70, 0xad, 0x01, 0xd4, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xb1, 0x01, + 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, + 0xb2, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, + 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, + 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, + 0xc6, 0xde, 0xc8, 0xca, 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, + 0x21, 0x03, 0x68, 0xb9, 0xc6, 0xe0, 0x22, 0x03, 0x28, 0xb9, 0xca, 0x00, + 0x22, 0x20, 0xe2, 0x32, 0x83, 0xeb, 0x0c, 0xae, 0x36, 0xb8, 0xdc, 0x00, + 0x4a, 0xae, 0x37, 0x80, 0x8c, 0x0b, 0xba, 0xe0, 0xe0, 0xba, 0xae, 0x38, + 0xe0, 0x12, 0x96, 0x26, 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, + 0x46, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, + 0x18, 0x5d, 0x19, 0x1e, 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, + 0xdb, 0x5b, 0x18, 0x1d, 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, + 0x0f, 0x09, 0xba, 0x32, 0xbc, 0xac, 0x21, 0x14, 0x84, 0x5c, 0x73, 0x70, + 0x95, 0x01, 0x54, 0x40, 0xc4, 0x45, 0x07, 0x17, 0x74, 0xd5, 0xc1, 0x75, + 0x5d, 0x76, 0x40, 0x8f, 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, + 0xec, 0x2b, 0x4c, 0x4e, 0x2e, 0x2c, 0x8f, 0xc7, 0x8c, 0xed, 0x2d, 0x8c, + 0x8e, 0x05, 0x64, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, 0x05, 0x5d, + 0x19, 0x5e, 0x95, 0xd5, 0x10, 0x0a, 0x72, 0xae, 0x39, 0xb8, 0xca, 0x00, + 0x22, 0x20, 0xe2, 0xa2, 0x83, 0x0b, 0xba, 0xf0, 0xe0, 0xba, 0xae, 0x3c, + 0xe0, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, + 0xc7, 0x63, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x4c, 0x8e, 0xc1, 0xdc, 0x10, + 0x09, 0x7a, 0xae, 0x3d, 0xb8, 0xca, 0x00, 0x2a, 0x20, 0xe2, 0x82, 0x2e, + 0x3e, 0xb8, 0xae, 0xab, 0x0f, 0x86, 0x38, 0x57, 0x76, 0x79, 0x97, 0x18, + 0x5c, 0x72, 0x70, 0xdd, 0xc1, 0xa5, 0x07, 0x97, 0x1f, 0x0c, 0x31, 0x1a, + 0xe0, 0x9a, 0xae, 0x3f, 0x18, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, + 0xb8, 0x41, 0x3b, 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, + 0x98, 0x03, 0x3b, 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, + 0x28, 0xec, 0xc0, 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, + 0x0e, 0xee, 0x40, 0x0f, 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, + 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, + 0x0e, 0x53, 0x02, 0x63, 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, + 0x0e, 0xe1, 0xe0, 0x0e, 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, + 0x0b, 0xf6, 0x50, 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, + 0x25, 0x40, 0x46, 0x4c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, + 0x0e, 0xed, 0x00, 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, + 0x0f, 0xf4, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, + 0x67, 0x04, 0x13, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, + 0x0e, 0xe7, 0xd0, 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x05, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x26, 0x10, 0x06, 0x00, 0x12, 0xf9, + 0x12, 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, + 0xc3, 0x0f, 0x44, 0x11, 0x80, 0xf9, 0x15, 0x5e, 0xdc, 0xb6, 0x05, 0x34, + 0x00, 0x12, 0xf9, 0x83, 0x33, 0xf9, 0xd5, 0x5d, 0xdc, 0xb6, 0x0d, 0x6c, + 0x00, 0x12, 0xf9, 0x12, 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, 0x35, 0x51, + 0x11, 0xf1, 0xdb, 0x83, 0x5f, 0xe1, 0xc5, 0x6d, 0x1b, 0x00, 0xc4, 0x76, + 0xe5, 0x2f, 0xbb, 0xef, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, + 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x13, 0x04, + 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xb4, 0x47, + 0x00, 0x28, 0xcf, 0x31, 0x14, 0x5d, 0x37, 0xd6, 0x00, 0x04, 0x02, 0xc9, + 0x11, 0x00, 0x8a, 0x23, 0x00, 0x04, 0x67, 0x00, 0x28, 0xd6, 0x00, 0x85, + 0x39, 0x08, 0x31, 0x10, 0x03, 0x31, 0x08, 0x83, 0x19, 0x00, 0x02, 0x63, + 0x04, 0x20, 0x08, 0x82, 0xf8, 0x37, 0x03, 0x30, 0x02, 0x00, 0x23, 0x06, + 0xca, 0x10, 0x84, 0xc1, 0xd3, 0x44, 0x46, 0x82, 0x04, 0x83, 0x0c, 0x41, + 0xc1, 0x8c, 0x18, 0x2c, 0x43, 0x40, 0x06, 0xd0, 0x33, 0x85, 0x01, 0xb2, + 0x28, 0xc3, 0x18, 0x42, 0x20, 0x06, 0x73, 0x0c, 0x43, 0x40, 0x06, 0x23, + 0x06, 0xcb, 0x10, 0x9c, 0xc1, 0x24, 0x59, 0x65, 0xb0, 0x38, 0x8d, 0x31, + 0x86, 0x10, 0x94, 0xc1, 0x1c, 0xc3, 0x10, 0x90, 0xc1, 0x61, 0x7a, 0x29, + 0x28, 0x83, 0x0c, 0x81, 0x43, 0x19, 0x11, 0xc0, 0x67, 0xbc, 0x81, 0xc3, + 0xd8, 0xe0, 0x02, 0xbd, 0x14, 0x94, 0x41, 0x86, 0x60, 0xca, 0x46, 0x0c, + 0x0a, 0x21, 0x98, 0x83, 0x22, 0x18, 0x6f, 0x08, 0x83, 0xce, 0x0d, 0x2e, + 0xd0, 0x4b, 0x41, 0x19, 0x64, 0x08, 0x30, 0x6f, 0xc4, 0xa0, 0x10, 0x02, + 0x3c, 0x50, 0x82, 0xf1, 0x06, 0x33, 0x10, 0x83, 0x37, 0xb8, 0x40, 0x2f, + 0x05, 0x65, 0x90, 0x21, 0xe8, 0xc6, 0x60, 0xc4, 0xa0, 0x10, 0x82, 0x3e, + 0x78, 0x82, 0x39, 0x06, 0x30, 0x58, 0xf4, 0x60, 0x8e, 0x21, 0x38, 0xf8, + 0x60, 0x8e, 0x21, 0x18, 0xf4, 0xc0, 0x02, 0x38, 0x90, 0x4f, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x60, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, + 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x15, 0x03, 0x00, 0x00, 0x0b, 0x82, + 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, + 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, + 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, + 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, + 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, + 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, + 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, + 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, + 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, + 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, + 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, + 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, + 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, + 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, + 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, + 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, + 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, + 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, + 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, + 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, + 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, + 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, + 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, + 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, + 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, + 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, + 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, + 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, + 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, + 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, + 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, + 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, + 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, + 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, + 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, + 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, + 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, + 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, + 0x83, 0x21, 0x10, 0xc0, 0x02, 0x54, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, + 0xda, 0x60, 0x10, 0x06, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, + 0xa8, 0x36, 0x18, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, + 0x1b, 0x90, 0xe3, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x01, 0x24, 0xa0, + 0xda, 0x60, 0x20, 0x01, 0xb0, 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, + 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, + 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x68, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, + 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, + 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, + 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, + 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, + 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, + 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, + 0x00, 0x06, 0xc3, 0x08, 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, + 0x8a, 0x03, 0x01, 0x29, 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, + 0xe6, 0x08, 0x40, 0x61, 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xb2, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, + 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, + 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, + 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, - 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, - 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, - 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, - 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, - 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, - 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, - 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, - 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, - 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, - 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, - 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, - 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, - 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, - 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, - 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x49, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc2, 0x38, 0x40, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x81, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, - 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x25, 0x30, 0x02, 0x50, - 0x20, 0x45, 0x50, 0x08, 0x05, 0x51, 0x06, 0x14, 0x47, 0x00, 0x08, 0x8e, - 0x25, 0x2c, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, - 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, - 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0xc6, 0x52, 0x3c, 0x00, 0xa4, 0x50, 0xb9, - 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x2c, - 0xc2, 0x23, 0x2c, 0x06, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, - 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, - 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0x86, 0x66, 0x06, 0x04, 0xa5, - 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, - 0xc6, 0x25, 0x86, 0x66, 0x26, 0x65, 0x88, 0xf0, 0x10, 0x43, 0x8c, 0x45, - 0x58, 0x8e, 0x65, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x79, - 0x8e, 0x45, 0x58, 0x84, 0x65, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, + 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, + 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, + 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, + 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, + 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, + 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, + 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, + 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0x30, 0x84, 0x59, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0xc2, 0x34, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x61, 0x24, 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, + 0x40, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x7a, 0x25, 0x30, + 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, + 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x74, 0x2c, 0x61, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0xc6, 0x63, 0x4c, 0x00, 0xf5, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x3c, 0xc3, 0x24, + 0x3c, 0x07, 0xe5, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, + 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, + 0xc6, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, 0x8c, 0x67, + 0x78, 0x92, 0x87, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x99, + 0x8e, 0x67, 0x78, 0x86, 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, - 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x78, + 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x98, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x67, 0x61, 0x19, 0x84, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x69, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x91, 0xa5, 0xcd, 0x85, 0x89, 0xb1, 0x95, - 0x0d, 0x11, 0x9e, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, + 0x0d, 0x11, 0xa6, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, - 0x90, 0xe7, 0x59, 0x86, 0x07, 0x7a, 0xa2, 0x21, 0xc2, 0x23, 0x91, 0x09, + 0x90, 0xe9, 0x79, 0x88, 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, - 0xba, 0xb4, 0x37, 0xb7, 0x21, 0xd0, 0x32, 0x3c, 0xd4, 0x53, 0x3d, 0xd6, - 0x03, 0x3d, 0xd1, 0x73, 0x3d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, + 0xba, 0xb4, 0x37, 0xb7, 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, 0xd6, + 0x04, 0x4d, 0xd1, 0x74, 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, - 0x3a, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, - 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, - 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, - 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x68, 0x98, 0xb1, 0xbd, 0x85, - 0xd1, 0xc9, 0x10, 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, 0x7b, 0x93, 0x23, 0x1b, - 0x22, 0x2d, 0xc2, 0xa3, 0x3d, 0xdb, 0x53, 0x3d, 0xdc, 0x03, 0x3d, 0xdd, - 0x73, 0x3d, 0x1e, 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, 0xb3, - 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, - 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x94, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, - 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, 0xd2, 0xdc, 0xc8, 0xca, - 0xf0, 0x88, 0x84, 0xa5, 0xc9, 0xb9, 0xc8, 0x95, 0x85, 0x91, 0x31, 0x0a, - 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, 0xfb, - 0x9a, 0x4b, 0xd3, 0x2b, 0xe3, 0x15, 0x96, 0x26, 0xe7, 0x12, 0x26, 0x77, - 0xf6, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x15, 0xc6, 0x96, 0x76, 0xe6, 0xf6, - 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x61, 0xec, 0x8d, 0x6d, 0x08, 0x18, 0x2c, - 0xc5, 0x03, 0x06, 0x4f, 0x18, 0x2c, 0xc4, 0x23, 0x06, 0xcb, 0xb0, 0x08, - 0xcf, 0x18, 0x3c, 0x64, 0xb0, 0x10, 0x4f, 0x19, 0x2c, 0xc4, 0x03, 0x3d, - 0xd1, 0x73, 0x3d, 0x66, 0xc0, 0x25, 0x2c, 0x4d, 0xce, 0x85, 0xae, 0x0c, - 0x8f, 0xae, 0x4e, 0xae, 0x8c, 0x4a, 0x58, 0x9a, 0x9c, 0xcb, 0x5c, 0x58, - 0x1b, 0x1c, 0x5b, 0x19, 0x31, 0xba, 0x32, 0x3c, 0xba, 0x3a, 0xb9, 0x32, - 0x19, 0x32, 0x1e, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x16, 0x90, 0xb9, 0xb0, - 0x36, 0x38, 0xb6, 0x32, 0x1f, 0x0e, 0x74, 0x65, 0x78, 0x43, 0xa8, 0x05, - 0x79, 0xd0, 0xe0, 0x11, 0x83, 0x65, 0x58, 0x84, 0x27, 0x0d, 0x1e, 0xe8, - 0x51, 0x83, 0xe7, 0x7a, 0xd6, 0x80, 0x4b, 0x58, 0x9a, 0x9c, 0xcb, 0x5c, - 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x1c, 0x8f, 0xb9, 0xb0, 0x36, 0x38, 0xb6, - 0x32, 0x39, 0x06, 0x73, 0x43, 0xa4, 0xc5, 0x78, 0xda, 0xe0, 0x11, 0x83, - 0x65, 0x58, 0x84, 0x07, 0x7a, 0xdc, 0xe0, 0xb9, 0x9e, 0x37, 0x18, 0xa2, - 0x3c, 0xd9, 0xf3, 0x3d, 0x67, 0xf0, 0xb0, 0xc1, 0x03, 0x07, 0x43, 0x8c, - 0x04, 0x78, 0xa6, 0x27, 0x0e, 0xf8, 0xbc, 0xb5, 0xb9, 0xa5, 0xc1, 0xbd, - 0xd1, 0x95, 0xb9, 0xd1, 0x81, 0x8c, 0xa1, 0x85, 0xc9, 0xf1, 0x99, 0x4a, - 0x6b, 0x83, 0x63, 0x2b, 0x03, 0x19, 0x5a, 0x59, 0x01, 0xa1, 0x12, 0x0a, - 0x0a, 0x1a, 0x22, 0x3c, 0x74, 0x30, 0xc4, 0x78, 0xe6, 0xe0, 0xa9, 0x83, - 0x28, 0x19, 0x62, 0x3c, 0x76, 0xf0, 0xd8, 0x41, 0x94, 0x8c, 0x88, 0xd8, - 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, 0x1d, 0xde, 0x81, 0x1c, 0xea, - 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, - 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, - 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, 0x77, 0xa0, 0x87, 0x29, 0x41, 0x31, - 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0xb0, 0x87, 0x72, 0x90, 0x87, - 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, 0x29, 0x81, 0x31, 0x82, 0x0a, 0x87, - 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, 0x70, 0x70, 0x87, 0x73, 0xa8, 0x87, - 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, 0x7b, 0x28, 0x07, 0x79, 0x98, 0x87, - 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, 0x20, 0x23, 0xa6, 0x70, 0x48, 0x07, - 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, 0x80, 0x87, 0x74, 0x60, 0x87, - 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, 0x7a, 0x48, 0x87, 0x77, 0x70, 0x87, - 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, 0x09, 0x87, 0x74, 0x90, 0x07, - 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, 0x68, 0x87, 0x72, 0x70, 0x07, - 0x7a, 0x98, 0x12, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, - 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, - 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, - 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, - 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, - 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, - 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, - 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, - 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, - 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, - 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, - 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, - 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, - 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, - 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, - 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, - 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, - 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, - 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, - 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, - 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, - 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, - 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, - 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, - 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, - 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, - 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, - 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, - 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, - 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, - 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, - 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, - 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, - 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, - 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, - 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, - 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, - 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, - 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, - 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, - 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, - 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x06, 0x10, 0xb1, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x45, 0x04, 0x18, - 0x0c, 0xd1, 0x4c, 0x16, 0xb0, 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, - 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, - 0xb7, 0x0d, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0xc4, 0x46, 0x00, 0x48, 0xd5, 0xc0, 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, - 0x23, 0x06, 0x8a, 0x10, 0x4c, 0x46, 0x81, 0x0c, 0x84, 0x10, 0x10, 0x52, - 0x2c, 0x10, 0xe4, 0x93, 0x41, 0x40, 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x5b, 0x86, 0x20, 0xb8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x18, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x43, 0x03, 0x00, 0x00, - 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, - 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, - 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, - 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, - 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, - 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, - 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, - 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, - 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, - 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, - 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, - 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, - 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, - 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, - 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, - 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, - 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, - 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, - 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, - 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, - 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, - 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, - 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, - 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, - 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, - 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, - 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, - 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, - 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, - 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, - 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, - 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, - 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, - 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, - 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, - 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, - 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, - 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, - 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, - 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, - 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, - 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, + 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, + 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, + 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, + 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, + 0x9e, 0x61, 0xd2, 0xa6, 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, 0xba, + 0xa6, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, + 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, + 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, 0x98, + 0xb4, 0xe9, 0x9b, 0xaa, 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, 0x0a, + 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, 0xbe, + 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, + 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0x11, + 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, 0x26, + 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, 0x57, + 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, 0x6e, + 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, 0xb7, + 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, 0x84, + 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, 0x43, + 0x4c, 0x68, 0x30, 0xa5, 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, + 0xa9, 0xc1, 0xb3, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, 0xc3, + 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, 0x39, + 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, 0x34, + 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, 0xca, + 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, 0x99, + 0xc6, 0x60, 0x22, 0x83, 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, 0x32, + 0x83, 0xe9, 0x0c, 0xa6, 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, 0x78, + 0x8a, 0x09, 0x9a, 0xe0, 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, 0x26, + 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, 0x4d, + 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, 0x1e, + 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, 0x1d, + 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, 0x32, + 0xbc, 0xac, 0x21, 0xd4, 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, 0x3c, + 0xc3, 0x44, 0x07, 0x13, 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, 0x82, + 0xae, 0x0c, 0xaf, 0xca, 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, 0x65, + 0xf0, 0x0c, 0xcf, 0x30, 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, 0x13, + 0x1e, 0x70, 0x09, 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, 0x2b, + 0x93, 0xe3, 0x31, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, 0x6e, + 0x88, 0xf4, 0x38, 0x93, 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, 0x41, + 0xd3, 0x1e, 0x4c, 0xd7, 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, 0x49, + 0x0c, 0x26, 0x39, 0x98, 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, 0x18, + 0x0b, 0x30, 0x4d, 0x93, 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, + 0x1d, 0xdc, 0xa0, 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, + 0x0d, 0xcc, 0x81, 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, + 0x23, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, + 0x28, 0x07, 0x77, 0xa0, 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, + 0x90, 0x07, 0x37, 0xb0, 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, + 0x70, 0x87, 0x29, 0x81, 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, + 0x60, 0x87, 0x70, 0x70, 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, + 0xf8, 0x05, 0x7b, 0x28, 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, + 0x98, 0x12, 0x20, 0x23, 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, + 0x78, 0x87, 0x76, 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, + 0x80, 0x07, 0x7a, 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, + 0x8c, 0x33, 0x82, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, + 0x08, 0x87, 0x73, 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xfc, + 0x01, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, + 0xce, 0xe4, 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, + 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, + 0x7e, 0x85, 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xd6, + 0xf6, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x74, 0x47, 0x00, 0xa8, 0x8e, 0x35, + 0x00, 0x03, 0x31, 0xc7, 0x40, 0x0c, 0xde, 0x1c, 0x03, 0xe1, 0x79, 0x63, + 0x0d, 0x40, 0x20, 0x90, 0xab, 0x81, 0x11, 0x00, 0x7a, 0x33, 0x00, 0x04, + 0x47, 0x00, 0x28, 0xcc, 0x41, 0x90, 0x01, 0x19, 0x90, 0x81, 0x18, 0xcc, + 0x00, 0x10, 0x18, 0x23, 0x00, 0x41, 0x10, 0xc4, 0xbf, 0x11, 0x80, 0x19, + 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x8c, 0x41, 0xf4, 0x4c, 0x89, 0x81, + 0x08, 0x83, 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x28, 0x43, 0x50, 0x06, 0x52, + 0x54, 0x2d, 0x88, 0x42, 0x0c, 0x32, 0x04, 0xc7, 0x33, 0xc8, 0x30, 0x04, + 0xd1, 0x5d, 0x76, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x12, 0x19, 0x11, 0xc0, + 0x67, 0xbc, 0x61, 0xbb, 0xd6, 0xe0, 0x02, 0xbb, 0x14, 0x94, 0x41, 0x86, + 0x00, 0xb2, 0x46, 0x0c, 0x0a, 0x21, 0x88, 0x83, 0x22, 0x18, 0x6f, 0x00, + 0x03, 0xae, 0x0d, 0x2e, 0xb0, 0x4b, 0x41, 0x19, 0x64, 0x08, 0xaa, 0x6d, + 0xc4, 0xa0, 0x10, 0x02, 0x3b, 0x50, 0x82, 0xf1, 0x86, 0x32, 0x08, 0x03, + 0x37, 0xb8, 0xc0, 0x2e, 0x05, 0x65, 0x90, 0x21, 0xd0, 0xc0, 0x60, 0xc4, + 0xa0, 0x10, 0x82, 0x3d, 0x78, 0x82, 0x39, 0x86, 0x6e, 0xc9, 0x83, 0x39, + 0x86, 0xe0, 0xd8, 0x83, 0x39, 0x86, 0x60, 0xc8, 0x03, 0x0b, 0xde, 0x40, + 0x3e, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x6c, 0x0c, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x8f, 0x00, + 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, + 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, + 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, + 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, - 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, - 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, - 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, - 0x07, 0x60, 0x83, 0x21, 0x0c, 0xc0, 0x02, 0x54, 0x1b, 0x8c, 0x81, 0x00, - 0x16, 0xa0, 0xda, 0x60, 0x10, 0x05, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, - 0x80, 0x05, 0xa8, 0x36, 0x18, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, - 0x04, 0x50, 0x1b, 0x90, 0xe3, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x01, - 0x24, 0xa0, 0xda, 0x60, 0x20, 0x01, 0xb0, 0x00, 0xd5, 0x06, 0x23, 0x11, - 0x80, 0x05, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, - 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, - 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, - 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, - 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x7c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, - 0x8c, 0x20, 0x00, 0x83, 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, 0x07, 0x49, - 0x53, 0x44, 0x09, 0x93, 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, 0x40, 0x20, - 0x82, 0x10, 0x42, 0x06, 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, 0x28, 0x61, - 0xf2, 0xff, 0x89, 0xb8, 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0xa7, 0x31, - 0x02, 0x60, 0x10, 0xe1, 0x08, 0x4e, 0x93, 0xa6, 0x88, 0x12, 0x26, 0xff, - 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, 0x1f, 0x88, 0x22, 0x00, - 0xfb, 0xa7, 0x31, 0x02, 0x60, 0x10, 0x21, 0x09, 0x2e, 0x92, 0xa6, 0x88, - 0x12, 0x26, 0xff, 0x97, 0x00, 0xe6, 0x59, 0x88, 0xe8, 0x9f, 0xc6, 0x08, - 0x80, 0x41, 0x84, 0x45, 0x28, 0x48, 0x08, 0x62, 0x18, 0xa4, 0x18, 0xb5, - 0x32, 0x00, 0x42, 0xe8, 0xcd, 0x11, 0x80, 0xc1, 0x1c, 0x41, 0x30, 0x8c, - 0x20, 0x44, 0x25, 0x09, 0x8a, 0x89, 0x28, 0xa7, 0x04, 0x44, 0x0b, 0x12, - 0x10, 0x13, 0x72, 0x4a, 0x40, 0x76, 0x20, 0x20, 0x05, 0xe2, 0x30, 0xc2, - 0x10, 0x0d, 0x22, 0x04, 0xc2, 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x10, 0xc2, - 0x08, 0x00, 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, - 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, - 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, - 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, - 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, - 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, - 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, - 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, - 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, - 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, - 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, - 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, - 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, - 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, - 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, - 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, - 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, - 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, - 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, - 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, - 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, - 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, - 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, - 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, - 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, - 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x71, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc2, 0x40, 0x40, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x2a, 0x20, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x30, 0x17, 0x10, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x59, 0x20, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x8a, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, - 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, - 0x7c, 0x04, 0x80, 0xf2, 0x58, 0xc2, 0x02, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x1e, 0x01, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x46, 0x74, 0x60, - 0x40, 0x16, 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x44, 0x04, 0x26, 0x44, 0x08, 0xe1, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0x86, - 0x66, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, - 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0x86, 0x66, 0x26, 0x65, 0x88, 0x80, - 0x11, 0x43, 0x8c, 0x88, 0x88, 0x94, 0xa8, 0x60, 0xd1, 0x54, 0x46, 0x17, - 0xc6, 0x36, 0x04, 0xc1, 0x8e, 0x88, 0x88, 0x88, 0xa8, 0xe0, 0x16, 0x96, - 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, - 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, - 0x56, 0x36, 0x44, 0xc0, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, - 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, - 0x6c, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, - 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, - 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x91, 0xa5, 0xcd, - 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0xb0, 0x86, 0x51, 0x58, 0x9a, 0x9c, - 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, - 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, - 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, - 0x61, 0x74, 0x34, 0x43, 0x10, 0xec, 0x89, 0x0a, 0x0c, 0xc2, 0xa2, 0x21, - 0x02, 0x26, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, - 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, - 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, - 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, - 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, - 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x50, 0x54, 0x60, - 0x14, 0x56, 0x61, 0x16, 0x06, 0x61, 0x11, 0x76, 0x61, 0x18, 0xa5, 0xb0, - 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, - 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, - 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, - 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x68, - 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xc9, 0x10, 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, - 0x7b, 0x93, 0x23, 0x1b, 0x22, 0x45, 0x04, 0xa6, 0x61, 0x1b, 0x56, 0x61, - 0x1c, 0x06, 0x61, 0x1d, 0x76, 0x61, 0x1e, 0x95, 0xb0, 0x34, 0x39, 0x17, - 0xb1, 0x3a, 0x33, 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x94, 0xc2, - 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, - 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0x88, 0x84, 0xa5, 0xc9, 0xb9, 0xc8, 0x95, - 0x85, 0x91, 0x31, 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, - 0xcb, 0x83, 0x2b, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0xe3, 0x15, 0x96, 0x26, - 0xe7, 0x12, 0x26, 0x77, 0xf6, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x15, 0xc6, - 0x96, 0x76, 0xe6, 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x61, 0xec, 0x8d, - 0x6d, 0x08, 0x18, 0x44, 0x07, 0x06, 0x06, 0x58, 0x18, 0x44, 0x06, 0x26, - 0x06, 0x51, 0x11, 0x11, 0xd8, 0x18, 0x60, 0x64, 0x10, 0x19, 0x58, 0x19, - 0x44, 0x06, 0x06, 0x61, 0x11, 0x76, 0x61, 0x66, 0x40, 0x2a, 0x2c, 0x4d, - 0xce, 0x65, 0x8e, 0x4e, 0xae, 0x6e, 0x8c, 0xee, 0x8b, 0x2e, 0x0f, 0xae, - 0xec, 0x2b, 0xcd, 0xcd, 0xec, 0x8d, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, - 0x0c, 0x8d, 0x37, 0x33, 0xb3, 0xb9, 0x32, 0x3a, 0x1a, 0x52, 0x63, 0x6f, - 0x65, 0x66, 0x66, 0x34, 0x8e, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x68, 0x08, - 0x8d, 0xbd, 0x95, 0x99, 0x99, 0x0d, 0x41, 0x83, 0xa8, 0x88, 0x8c, 0xa8, - 0xc0, 0xd2, 0x00, 0x53, 0x83, 0xc8, 0x88, 0x8c, 0xa8, 0xc0, 0xd2, 0x00, - 0x5b, 0x83, 0x88, 0x89, 0x8c, 0xa8, 0xc0, 0xd2, 0x00, 0x63, 0x83, 0xa8, - 0x89, 0x8c, 0xa8, 0xc0, 0xd2, 0x00, 0x6b, 0x03, 0x26, 0x59, 0x55, 0x56, - 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x34, 0xc8, 0xca, 0xc6, 0xde, 0xc8, - 0xca, 0x86, 0x90, 0x41, 0xb4, 0x60, 0x60, 0x80, 0x85, 0x41, 0x94, 0x60, - 0x62, 0x10, 0x11, 0x11, 0x81, 0x8d, 0x01, 0x86, 0x06, 0x98, 0x1b, 0x60, - 0x64, 0x10, 0x25, 0x58, 0x19, 0x44, 0x06, 0x06, 0x61, 0x6f, 0x80, 0x5d, - 0x18, 0x1c, 0x70, 0x09, 0x4b, 0x93, 0x73, 0xa1, 0x2b, 0xc3, 0xa3, 0xab, - 0x93, 0x2b, 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, - 0x56, 0x46, 0x8c, 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0x8c, - 0xc7, 0x8c, 0xed, 0x2d, 0x8c, 0x8e, 0x05, 0x64, 0x2e, 0xac, 0x0d, 0x8e, - 0xad, 0xcc, 0x87, 0x04, 0x5d, 0x19, 0x5e, 0xd6, 0x10, 0x2a, 0x42, 0x30, - 0x39, 0xc0, 0xc4, 0x20, 0x2a, 0x22, 0x02, 0x9b, 0x03, 0x0c, 0xc2, 0xe8, - 0x00, 0xbb, 0xb0, 0x3a, 0xa0, 0x47, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, - 0x26, 0x43, 0xf6, 0x15, 0x26, 0x27, 0x17, 0x96, 0xc7, 0x63, 0xc6, 0xf6, - 0x16, 0x46, 0xc7, 0x02, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0xe6, 0xc3, - 0x82, 0xae, 0x0c, 0xaf, 0xca, 0x6a, 0x08, 0x15, 0x39, 0x98, 0x1c, 0x60, - 0x62, 0x10, 0x11, 0x11, 0x81, 0xcd, 0x01, 0x06, 0x61, 0x77, 0x80, 0x5d, - 0x18, 0x1e, 0x70, 0x09, 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, - 0x2b, 0x93, 0xe3, 0x31, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, - 0x6e, 0x88, 0x14, 0x3d, 0x98, 0x1e, 0x60, 0x62, 0x10, 0x15, 0x11, 0x81, - 0x41, 0xd8, 0x1e, 0x60, 0x17, 0xc6, 0x07, 0x43, 0x1c, 0x2c, 0xc3, 0x3e, - 0xec, 0x0c, 0xb0, 0x38, 0xc0, 0xec, 0x00, 0xcb, 0x03, 0xac, 0x0f, 0x86, - 0x18, 0x0e, 0x80, 0x4d, 0x98, 0x1f, 0xf0, 0x79, 0x6b, 0x73, 0x4b, 0x83, - 0x7b, 0xa3, 0x2b, 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, 0x93, 0xe3, 0x33, - 0x95, 0xd6, 0x06, 0xc7, 0x56, 0x06, 0x32, 0xb4, 0xb2, 0x02, 0x42, 0x25, - 0x14, 0x14, 0x34, 0x44, 0xc0, 0x42, 0x61, 0x88, 0x81, 0x81, 0x02, 0x26, - 0x0a, 0x1c, 0x34, 0xc4, 0xc0, 0x46, 0x01, 0x1b, 0x05, 0x0e, 0x1a, 0x11, - 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, 0x03, 0x39, - 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, 0xc3, 0x39, - 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, 0xf6, 0xd0, - 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, 0x53, 0x82, - 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, - 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, 0x04, 0x15, - 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, 0xe7, 0x50, - 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, 0xf2, 0x30, - 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, 0xe1, 0x90, - 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, 0xe9, 0xc0, - 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, 0xef, 0xe0, - 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, 0x0e, 0xe9, 0x20, - 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, 0x0e, 0xe5, 0xe0, - 0x0e, 0xf4, 0x30, 0x25, 0xf8, 0x03, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, - 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, - 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, - 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, - 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, - 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, - 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, - 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, - 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, - 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, - 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, - 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, - 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, - 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, - 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, - 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, - 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, - 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, - 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, - 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, - 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, - 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, - 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, - 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, - 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, - 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, - 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, - 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, - 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, - 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, - 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, - 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, - 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, - 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, - 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, - 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, - 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, - 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, - 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, - 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, - 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, - 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x26, 0x10, 0x06, 0x00, 0x12, 0xf9, 0x12, 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, - 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0xc3, 0x0f, 0x44, 0x11, 0x80, 0xf9, - 0x15, 0x5e, 0xdc, 0xb6, 0x05, 0x34, 0x00, 0x12, 0xf9, 0x83, 0x33, 0xf9, - 0xd5, 0x5d, 0xdc, 0xb6, 0x0d, 0x6c, 0x00, 0x12, 0xf9, 0x12, 0xc0, 0x3c, - 0x0b, 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0x83, 0x5f, 0xe1, - 0xc5, 0x6d, 0x1b, 0x00, 0xc4, 0x76, 0xe5, 0x2f, 0xbb, 0xef, 0x5f, 0x44, - 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, - 0x3b, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0xa4, 0xe7, 0x18, 0x0a, 0xcf, 0x1b, 0x6b, 0x00, - 0x02, 0x81, 0xe6, 0x08, 0x00, 0xc9, 0x11, 0x80, 0x1a, 0xa0, 0x38, 0x03, - 0x40, 0x61, 0x0e, 0x42, 0x0c, 0xc4, 0x40, 0x0c, 0xc2, 0x60, 0x06, 0x80, - 0xc0, 0x18, 0x01, 0x08, 0x82, 0x20, 0xfe, 0xcd, 0x00, 0x8c, 0x00, 0x00, - 0x23, 0x06, 0xca, 0x10, 0x84, 0x81, 0xc3, 0x44, 0x47, 0x82, 0x04, 0x83, - 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x2c, 0x43, 0x40, 0x06, 0x8f, 0x33, 0x85, - 0x41, 0xb2, 0x28, 0xc3, 0x18, 0x42, 0x20, 0x06, 0x73, 0x0c, 0x43, 0x40, - 0x06, 0x23, 0x06, 0xcb, 0x10, 0x9c, 0x81, 0x14, 0x59, 0x65, 0xc0, 0x38, - 0x8d, 0x31, 0x86, 0x10, 0x94, 0xc1, 0x1c, 0xc3, 0x10, 0x90, 0xc1, 0x5d, - 0x7b, 0x29, 0x28, 0x83, 0x0c, 0x81, 0x43, 0x19, 0x11, 0xc0, 0x87, 0xb8, - 0x32, 0xde, 0xc0, 0x85, 0x41, 0x1b, 0x5c, 0xb0, 0x97, 0x82, 0x32, 0xc8, - 0x10, 0x50, 0xda, 0x88, 0x41, 0x21, 0x04, 0x74, 0x60, 0x04, 0xe3, 0x0d, - 0x61, 0x60, 0x06, 0x6f, 0x70, 0xc1, 0x5e, 0x0a, 0xca, 0x20, 0x43, 0x90, - 0x7d, 0x23, 0x06, 0x85, 0x10, 0xe4, 0xc1, 0x12, 0x8c, 0x37, 0x98, 0xc1, - 0x1a, 0xc0, 0xc1, 0x05, 0x7b, 0x29, 0x28, 0x83, 0x0c, 0x81, 0x47, 0x06, - 0x23, 0x06, 0x85, 0x10, 0xf8, 0x01, 0x14, 0xcc, 0x31, 0x84, 0xc1, 0xb2, - 0x07, 0x73, 0x0c, 0xc1, 0xd1, 0x07, 0x73, 0x0c, 0xc1, 0xb0, 0x07, 0x16, - 0x4c, 0xf2, 0xc9, 0x20, 0x20, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x5b, 0x06, 0x26, 0x20, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa8, 0x0c, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, - 0x27, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, - 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, - 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, - 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, - 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, - 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, - 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, - 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, - 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, - 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, - 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, - 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, - 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, - 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, - 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, - 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, - 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, - 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, - 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, - 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, - 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, - 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, - 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, - 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, - 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, - 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, - 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, - 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, - 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, - 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, - 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, - 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, - 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, - 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, - 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, - 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, - 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, - 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, - 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, - 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, - 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, - 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, - 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, - 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, - 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, - 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, - 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, - 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, - 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, - 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x83, 0x21, 0x0c, 0xc0, 0x02, 0x54, - 0x1b, 0x8c, 0x81, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x05, 0xb0, 0x00, - 0xd5, 0x06, 0xa3, 0x30, 0x80, 0x05, 0xa8, 0x36, 0x18, 0xc6, 0x01, 0x2c, - 0x40, 0xb5, 0xc1, 0x38, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x24, 0x80, - 0xda, 0x80, 0x20, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x0c, 0x20, 0x01, - 0xd5, 0x06, 0x23, 0x09, 0x80, 0x05, 0xa8, 0x36, 0x18, 0x8a, 0x00, 0x2c, - 0x40, 0x05, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x13, 0x8c, 0x40, 0x18, 0x88, 0xc2, 0x98, 0x10, 0x1c, 0x13, 0x06, 0x24, - 0x51, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, - 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, - 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, - 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x6c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, - 0x8c, 0x20, 0x00, 0x83, 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, 0x07, 0x49, - 0x53, 0x44, 0x09, 0x93, 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, 0x40, 0x20, - 0x82, 0x10, 0x42, 0x06, 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, 0x28, 0x61, - 0xf2, 0xff, 0x89, 0xb8, 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0xa7, 0x31, - 0x02, 0x60, 0x10, 0xe1, 0x08, 0x2e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, - 0x97, 0x00, 0xe6, 0x59, 0x88, 0xe8, 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, - 0x44, 0x28, 0x48, 0x08, 0x62, 0x18, 0x84, 0x14, 0xad, 0x32, 0x00, 0x42, - 0xa8, 0xcd, 0x11, 0x04, 0x73, 0x04, 0x60, 0x30, 0x8c, 0x20, 0x40, 0x05, - 0x09, 0x48, 0x89, 0x17, 0x1f, 0x20, 0x39, 0x10, 0x90, 0x02, 0x70, 0x18, - 0x61, 0x80, 0x06, 0x11, 0x02, 0x61, 0x8e, 0x00, 0x14, 0x06, 0x11, 0x08, - 0x61, 0x04, 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, - 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, - 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, - 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, - 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, - 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, - 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, - 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, - 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, - 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, - 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, - 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, - 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, - 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, - 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, - 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, - 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, - 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, - 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, - 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, - 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, - 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, - 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, - 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, - 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, - 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x61, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc2, 0x38, 0x40, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x26, 0x20, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x40, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, - 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, - 0x78, 0x04, 0x80, 0xea, 0x58, 0xc2, 0x02, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x16, 0x01, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x64, 0x50, - 0x40, 0x05, 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x40, 0x03, 0x25, 0x40, 0x07, 0xe1, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0x86, - 0x66, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, - 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0x86, 0x66, 0x26, 0x65, 0x88, 0x40, - 0x11, 0x43, 0x0c, 0x68, 0x80, 0x12, 0x88, 0x60, 0xd1, 0x54, 0x46, 0x17, - 0xc6, 0x36, 0x04, 0xa1, 0x0e, 0x68, 0x80, 0x06, 0x88, 0xe0, 0x16, 0x96, - 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, - 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, - 0x56, 0x36, 0x44, 0xa0, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, - 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, - 0x6a, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, - 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, - 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x91, 0xa5, 0xcd, - 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0xa8, 0x86, 0x51, 0x58, 0x9a, 0x9c, - 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, - 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, - 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, - 0x61, 0x74, 0x34, 0x43, 0x10, 0xea, 0x81, 0x08, 0x0a, 0xa2, 0xa2, 0x21, - 0x02, 0x25, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, - 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, - 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, - 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, - 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, - 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x44, 0x50, - 0x14, 0x55, 0x51, 0x16, 0x05, 0x51, 0x11, 0x75, 0x51, 0x18, 0xa5, 0xb0, - 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, - 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, - 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, - 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x68, - 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xc9, 0x10, 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, - 0x7b, 0x93, 0x23, 0x1b, 0x22, 0x41, 0x03, 0xa5, 0x51, 0x1b, 0x55, 0x51, - 0x1c, 0x05, 0x51, 0x1d, 0x75, 0x51, 0x1e, 0x95, 0xb0, 0x34, 0x39, 0x17, - 0xb1, 0x3a, 0x33, 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x94, 0xc2, - 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, - 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0x88, 0x84, 0xa5, 0xc9, 0xb9, 0xc8, 0x95, - 0x85, 0x91, 0x31, 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, - 0xcb, 0x83, 0x2b, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0xe3, 0x15, 0x96, 0x26, - 0xe7, 0x12, 0x26, 0x77, 0xf6, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x15, 0xc6, - 0x96, 0x76, 0xe6, 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x61, 0xec, 0x8d, - 0x6d, 0x08, 0x18, 0x40, 0x06, 0x05, 0x06, 0x54, 0x18, 0x40, 0x05, 0x25, - 0x06, 0x10, 0x01, 0x0d, 0xd4, 0x18, 0x50, 0x64, 0x00, 0x15, 0x54, 0x19, - 0x40, 0x05, 0x05, 0x51, 0x11, 0x75, 0x51, 0x66, 0x40, 0x2a, 0x2c, 0x4d, - 0xce, 0x65, 0x8e, 0x4e, 0xae, 0x6e, 0x8c, 0xee, 0x8b, 0x2e, 0x0f, 0xae, - 0xec, 0x2b, 0xcd, 0xcd, 0xec, 0x8d, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, - 0x0c, 0x8d, 0x37, 0x33, 0xb3, 0xb9, 0x32, 0x3a, 0x1a, 0x52, 0x63, 0x6f, - 0x65, 0x66, 0x66, 0x34, 0x8e, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x68, 0x08, - 0x8d, 0xbd, 0x95, 0x99, 0x99, 0x0d, 0x41, 0x03, 0x88, 0x80, 0x0a, 0x88, - 0xa0, 0xd2, 0x80, 0x52, 0x03, 0xa8, 0x80, 0x0a, 0x88, 0xa0, 0xd2, 0x80, - 0x5a, 0x03, 0x68, 0x81, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x62, 0x03, 0x88, - 0x81, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x6a, 0x03, 0x26, 0x59, 0x55, 0x56, - 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x34, 0xc8, 0xca, 0xc6, 0xde, 0xc8, - 0xca, 0x86, 0x90, 0x01, 0xa4, 0x50, 0x60, 0x40, 0x85, 0x01, 0x84, 0x50, - 0x62, 0x00, 0x0d, 0xd0, 0x40, 0x8d, 0x01, 0x85, 0x06, 0x94, 0x1b, 0x50, - 0x64, 0x00, 0x21, 0x54, 0x19, 0x40, 0x05, 0x05, 0x51, 0x6f, 0x40, 0x5d, - 0x14, 0x1c, 0x70, 0x09, 0x4b, 0x93, 0x73, 0xa1, 0x2b, 0xc3, 0xa3, 0xab, - 0x93, 0x2b, 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, - 0x56, 0x46, 0x8c, 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0x8c, - 0xc7, 0x8c, 0xed, 0x2d, 0x8c, 0x8e, 0x05, 0x64, 0x2e, 0xac, 0x0d, 0x8e, - 0xad, 0xcc, 0x87, 0x04, 0x5d, 0x19, 0x5e, 0xd6, 0x10, 0x0a, 0x3a, 0x28, - 0x39, 0xa0, 0xc4, 0x00, 0x22, 0xa0, 0x81, 0x9a, 0x03, 0x0a, 0xa2, 0xe8, - 0x80, 0xba, 0xa8, 0x3a, 0x60, 0x41, 0x57, 0x86, 0x57, 0x65, 0x35, 0x84, - 0x82, 0x1a, 0x4a, 0x0e, 0x28, 0x31, 0x80, 0x06, 0x68, 0xa0, 0xe6, 0x80, - 0x82, 0x28, 0x3a, 0xa0, 0x2e, 0xea, 0x0e, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, - 0xcc, 0x85, 0xb5, 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, - 0x63, 0x2b, 0x93, 0x63, 0x30, 0x37, 0x44, 0x82, 0x1c, 0x2a, 0x0f, 0x28, - 0x31, 0x80, 0x08, 0x68, 0xa0, 0x20, 0x4a, 0x0f, 0xa8, 0x8b, 0xda, 0x83, - 0x21, 0x0e, 0x95, 0x51, 0x1f, 0x75, 0x06, 0x54, 0x1c, 0x50, 0x76, 0x40, - 0xe1, 0x01, 0xc5, 0x07, 0x43, 0x0c, 0x06, 0xa0, 0x26, 0xaa, 0x0f, 0xf8, - 0xbc, 0xb5, 0xb9, 0xa5, 0xc1, 0xbd, 0xd1, 0x95, 0xb9, 0xd1, 0x81, 0x8c, - 0xa1, 0x85, 0xc9, 0xf1, 0x99, 0x4a, 0x6b, 0x83, 0x63, 0x2b, 0x03, 0x19, - 0x5a, 0x59, 0x01, 0xa1, 0x12, 0x0a, 0x0a, 0x1a, 0x22, 0x50, 0xa0, 0x30, - 0xc4, 0xa0, 0xfe, 0x80, 0x0a, 0x05, 0xec, 0x19, 0x62, 0x50, 0xa2, 0x40, - 0x89, 0x02, 0xf6, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, - 0xa0, 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, - 0x81, 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, - 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, - 0x77, 0xa0, 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, - 0x37, 0xb0, 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, - 0x29, 0x81, 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, - 0x70, 0x70, 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, - 0x7b, 0x28, 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, - 0x20, 0x23, 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, - 0x76, 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, - 0x7a, 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, - 0x82, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, - 0x73, 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xf8, 0x01, 0x00, - 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, - 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, - 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, - 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, - 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, - 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, - 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, - 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, - 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, - 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, - 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, - 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, - 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, - 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, - 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, - 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, - 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, - 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, - 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, - 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, - 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, - 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, - 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, - 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, - 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, - 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, - 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, - 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, - 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, - 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, - 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, - 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, - 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, - 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, - 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, - 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, - 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, - 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, - 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, - 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, - 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, - 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, - 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, - 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, - 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xd6, 0xf6, 0x5f, - 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x64, 0xc7, 0x1a, 0x80, 0x81, 0x98, 0x63, 0x20, - 0x86, 0x6f, 0x8e, 0x81, 0xf8, 0xbe, 0xb1, 0x06, 0x20, 0x10, 0x28, 0x8e, - 0x00, 0xd0, 0xab, 0x81, 0x11, 0x00, 0x82, 0x33, 0x00, 0x14, 0xe6, 0x20, - 0xc8, 0x80, 0x0c, 0xc8, 0x40, 0x0c, 0x66, 0x00, 0x08, 0x8c, 0x11, 0x80, - 0x20, 0x08, 0xe2, 0xdf, 0x08, 0xc0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x23, 0x06, 0xca, 0x10, 0x8c, 0x01, 0xe4, 0x4c, 0x48, 0x72, 0x08, 0x83, - 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x28, 0x43, 0x50, 0x06, 0x11, 0x54, 0x29, - 0x4b, 0x42, 0x0c, 0x32, 0x04, 0xc7, 0x33, 0xc8, 0x30, 0x04, 0xd1, 0x59, - 0x77, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x12, 0x19, 0x11, 0xc0, 0x87, 0xb6, - 0x32, 0xde, 0xb0, 0x81, 0x01, 0x1b, 0x5c, 0x70, 0x97, 0x82, 0x32, 0xc8, - 0x10, 0x44, 0xd7, 0x88, 0x41, 0x21, 0x04, 0x72, 0x60, 0x04, 0xe3, 0x0d, - 0x60, 0x50, 0x06, 0x6e, 0x70, 0xc1, 0x5d, 0x0a, 0xca, 0x20, 0x43, 0x60, - 0x71, 0x23, 0x06, 0x85, 0x10, 0xdc, 0xc1, 0x12, 0x8c, 0x37, 0x94, 0x81, - 0x1a, 0xbc, 0xc1, 0x05, 0x77, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x16, 0x06, - 0x23, 0x06, 0x85, 0x10, 0xf0, 0x01, 0x14, 0xcc, 0x31, 0x78, 0x8b, 0x1e, - 0xcc, 0x31, 0x04, 0x07, 0x1f, 0xcc, 0x31, 0x04, 0x83, 0x1e, 0x58, 0x30, - 0xc9, 0x27, 0x83, 0x80, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x5b, 0x86, 0x24, 0x18, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xb4, 0x0c, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, - 0x2a, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, - 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, - 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, - 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, - 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, - 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, - 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, - 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, - 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, - 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, - 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, - 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, - 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, - 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, - 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, - 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, - 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, - 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, - 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, - 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, - 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, - 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, - 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, - 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, - 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, - 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, - 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, - 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, - 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, - 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, - 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, - 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, - 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, - 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, - 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, - 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, - 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, - 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, - 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, - 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, - 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, - 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, - 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, - 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, - 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, - 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, - 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, - 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, - 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, - 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x83, 0x21, 0x0c, 0xc0, 0x02, 0x54, - 0x1b, 0x8c, 0x81, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x05, 0xb0, 0x00, - 0xd5, 0x06, 0xa3, 0x30, 0x80, 0x05, 0xa8, 0x36, 0x18, 0xc6, 0x01, 0x2c, - 0x40, 0xb5, 0xc1, 0x38, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x24, 0x80, - 0xda, 0x80, 0x20, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x0c, 0x20, 0x01, - 0xd5, 0x06, 0x23, 0x09, 0x80, 0x05, 0xa8, 0x36, 0x18, 0x8a, 0x00, 0x2c, - 0x40, 0x05, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x13, 0x8c, 0x40, 0x18, 0x88, 0xc2, 0x98, 0x10, 0x1c, 0x13, 0x06, 0x24, - 0x51, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, - 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, - 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, - 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x6c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, - 0x8c, 0x20, 0x00, 0x83, 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, 0x07, 0x49, - 0x53, 0x44, 0x09, 0x93, 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, 0x40, 0x20, - 0x82, 0x10, 0x42, 0x06, 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, 0x28, 0x61, - 0xf2, 0xff, 0x89, 0xb8, 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0xa7, 0x31, - 0x02, 0x60, 0x10, 0xe1, 0x08, 0x2e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, - 0x97, 0x00, 0xe6, 0x59, 0x88, 0xe8, 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, - 0x44, 0x28, 0x48, 0x08, 0x62, 0x18, 0x84, 0x14, 0xad, 0x32, 0x00, 0x42, - 0xa8, 0xcd, 0x11, 0x04, 0x73, 0x04, 0x60, 0x30, 0x8c, 0x20, 0x40, 0x05, - 0x09, 0x48, 0x89, 0x17, 0x1f, 0x20, 0x39, 0x10, 0x90, 0x02, 0x70, 0x18, - 0x61, 0x80, 0x06, 0x11, 0x02, 0x61, 0x8e, 0x00, 0x14, 0x06, 0x11, 0x08, - 0x61, 0x04, 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, - 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, - 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, - 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, - 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, - 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, - 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, - 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, - 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, - 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, - 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, - 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, - 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, - 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, - 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, - 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, - 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, - 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, - 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, - 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, - 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, - 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, - 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, - 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, - 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, - 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, - 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, - 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x61, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc2, 0x38, 0x40, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x26, 0x20, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x40, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, - 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, - 0x78, 0x04, 0x80, 0xea, 0x58, 0xc2, 0x02, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x16, 0x01, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x64, 0x50, - 0x40, 0x05, 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x40, 0x03, 0x25, 0x40, 0x07, 0xe1, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0x86, - 0x66, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, - 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0x86, 0x66, 0x26, 0x65, 0x88, 0x40, - 0x11, 0x43, 0x0c, 0x68, 0x80, 0x12, 0x88, 0x60, 0xd1, 0x54, 0x46, 0x17, - 0xc6, 0x36, 0x04, 0xa1, 0x0e, 0x68, 0x80, 0x06, 0x88, 0xe0, 0x16, 0x96, - 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, - 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, - 0x56, 0x36, 0x44, 0xa0, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, - 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, - 0x6a, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, - 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, - 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x91, 0xa5, 0xcd, - 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0xa8, 0x86, 0x51, 0x58, 0x9a, 0x9c, - 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, - 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, - 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, - 0x61, 0x74, 0x34, 0x43, 0x10, 0xea, 0x81, 0x08, 0x0a, 0xa2, 0xa2, 0x21, - 0x02, 0x25, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, - 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, - 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, - 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, - 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, - 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x44, 0x50, - 0x14, 0x55, 0x51, 0x16, 0x05, 0x51, 0x11, 0x75, 0x51, 0x18, 0xa5, 0xb0, - 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, - 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, - 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, - 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x68, - 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xc9, 0x10, 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, - 0x7b, 0x93, 0x23, 0x1b, 0x22, 0x41, 0x03, 0xa5, 0x51, 0x1b, 0x55, 0x51, - 0x1c, 0x05, 0x51, 0x1d, 0x75, 0x51, 0x1e, 0x95, 0xb0, 0x34, 0x39, 0x17, - 0xb1, 0x3a, 0x33, 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x94, 0xc2, - 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, - 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0x88, 0x84, 0xa5, 0xc9, 0xb9, 0xc8, 0x95, - 0x85, 0x91, 0x31, 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, - 0xcb, 0x83, 0x2b, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0xe3, 0x15, 0x96, 0x26, - 0xe7, 0x12, 0x26, 0x77, 0xf6, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x15, 0xc6, - 0x96, 0x76, 0xe6, 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x61, 0xec, 0x8d, - 0x6d, 0x08, 0x18, 0x40, 0x06, 0x05, 0x06, 0x54, 0x18, 0x40, 0x05, 0x25, - 0x06, 0x10, 0x01, 0x0d, 0xd4, 0x18, 0x50, 0x64, 0x00, 0x15, 0x54, 0x19, - 0x40, 0x05, 0x05, 0x51, 0x11, 0x75, 0x51, 0x66, 0x40, 0x2a, 0x2c, 0x4d, - 0xce, 0x65, 0x8e, 0x4e, 0xae, 0x6e, 0x8c, 0xee, 0x8b, 0x2e, 0x0f, 0xae, - 0xec, 0x2b, 0xcd, 0xcd, 0xec, 0x8d, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, - 0x0c, 0x8d, 0x37, 0x33, 0xb3, 0xb9, 0x32, 0x3a, 0x1a, 0x52, 0x63, 0x6f, - 0x65, 0x66, 0x66, 0x34, 0x8e, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x68, 0x08, - 0x8d, 0xbd, 0x95, 0x99, 0x99, 0x0d, 0x41, 0x03, 0x88, 0x80, 0x0a, 0x88, - 0xa0, 0xd2, 0x80, 0x52, 0x03, 0xa8, 0x80, 0x0a, 0x88, 0xa0, 0xd2, 0x80, - 0x5a, 0x03, 0x68, 0x81, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x62, 0x03, 0x88, - 0x81, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x6a, 0x03, 0x26, 0x59, 0x55, 0x56, - 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x34, 0xc8, 0xca, 0xc6, 0xde, 0xc8, - 0xca, 0x86, 0x90, 0x01, 0xa4, 0x50, 0x60, 0x40, 0x85, 0x01, 0x84, 0x50, - 0x62, 0x00, 0x0d, 0xd0, 0x40, 0x8d, 0x01, 0x85, 0x06, 0x94, 0x1b, 0x50, - 0x64, 0x00, 0x21, 0x54, 0x19, 0x40, 0x05, 0x05, 0x51, 0x6f, 0x40, 0x5d, - 0x14, 0x1c, 0x70, 0x09, 0x4b, 0x93, 0x73, 0xa1, 0x2b, 0xc3, 0xa3, 0xab, - 0x93, 0x2b, 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, - 0x56, 0x46, 0x8c, 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0x8c, - 0xc7, 0x8c, 0xed, 0x2d, 0x8c, 0x8e, 0x05, 0x64, 0x2e, 0xac, 0x0d, 0x8e, - 0xad, 0xcc, 0x87, 0x04, 0x5d, 0x19, 0x5e, 0xd6, 0x10, 0x0a, 0x3a, 0x28, - 0x39, 0xa0, 0xc4, 0x00, 0x22, 0xa0, 0x81, 0x9a, 0x03, 0x0a, 0xa2, 0xe8, - 0x80, 0xba, 0xa8, 0x3a, 0x60, 0x41, 0x57, 0x86, 0x57, 0x65, 0x35, 0x84, - 0x82, 0x1a, 0x4a, 0x0e, 0x28, 0x31, 0x80, 0x06, 0x68, 0xa0, 0xe6, 0x80, - 0x82, 0x28, 0x3a, 0xa0, 0x2e, 0xea, 0x0e, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, - 0xcc, 0x85, 0xb5, 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, - 0x63, 0x2b, 0x93, 0x63, 0x30, 0x37, 0x44, 0x82, 0x1c, 0x2a, 0x0f, 0x28, - 0x31, 0x80, 0x08, 0x68, 0xa0, 0x20, 0x4a, 0x0f, 0xa8, 0x8b, 0xda, 0x83, - 0x21, 0x0e, 0x95, 0x51, 0x1f, 0x75, 0x06, 0x54, 0x1c, 0x50, 0x76, 0x40, - 0xe1, 0x01, 0xc5, 0x07, 0x43, 0x0c, 0x06, 0xa0, 0x26, 0xaa, 0x0f, 0xf8, - 0xbc, 0xb5, 0xb9, 0xa5, 0xc1, 0xbd, 0xd1, 0x95, 0xb9, 0xd1, 0x81, 0x8c, - 0xa1, 0x85, 0xc9, 0xf1, 0x99, 0x4a, 0x6b, 0x83, 0x63, 0x2b, 0x03, 0x19, - 0x5a, 0x59, 0x01, 0xa1, 0x12, 0x0a, 0x0a, 0x1a, 0x22, 0x50, 0xa0, 0x30, - 0xc4, 0xa0, 0xfe, 0x80, 0x0a, 0x05, 0xec, 0x19, 0x62, 0x50, 0xa2, 0x40, - 0x89, 0x02, 0xf6, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, - 0xa0, 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, - 0x81, 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, - 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, - 0x77, 0xa0, 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, - 0x37, 0xb0, 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, - 0x29, 0x81, 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, - 0x70, 0x70, 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, - 0x7b, 0x28, 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, - 0x20, 0x23, 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, - 0x76, 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, - 0x7a, 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, - 0x82, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, - 0x73, 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xf8, 0x01, 0x00, - 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, - 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, - 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, - 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, - 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, - 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, - 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, - 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, - 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, - 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, - 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, - 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, - 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, - 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, - 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, - 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, - 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, - 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, - 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, - 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, - 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, - 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, - 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, - 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, - 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, - 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, - 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, - 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, - 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, - 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, - 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, - 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, - 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, - 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, - 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, - 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, - 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, - 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, - 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, - 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, - 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, - 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, - 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, - 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, - 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xda, 0xf5, 0x5f, - 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, - 0x3b, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x64, 0xc7, 0x1a, 0x80, 0x81, 0x98, 0x63, 0x20, - 0x06, 0x30, 0x98, 0x63, 0x20, 0xc0, 0x00, 0x0c, 0xc6, 0x1a, 0x80, 0x40, - 0xa0, 0x38, 0x96, 0x10, 0x00, 0x23, 0x00, 0xf4, 0x6a, 0x60, 0x04, 0x80, - 0xe0, 0x0c, 0x00, 0x89, 0x19, 0x00, 0x0a, 0x73, 0x10, 0x66, 0x60, 0x06, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, + 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, + 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, + 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, + 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, + 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, + 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, + 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, + 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, + 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, + 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, + 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, + 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, + 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, + 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, + 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, + 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, + 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, + 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, + 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, + 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x83, 0x21, 0x10, 0xc0, + 0x02, 0x54, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x06, + 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, 0xa8, 0x36, 0x18, 0xc6, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, 0x1b, 0x90, 0xe3, 0xff, + 0xff, 0xff, 0xff, 0x07, 0x80, 0x01, 0x24, 0xa0, 0xda, 0x60, 0x20, 0x01, + 0xb0, 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, 0xa8, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, + 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x68, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, + 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, + 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, + 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, + 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, + 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, + 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, + 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, 0x00, 0x06, 0xc3, 0x08, + 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, 0x8a, 0x03, 0x01, 0x29, + 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, 0xe6, 0x08, 0x40, 0x61, + 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, + 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, + 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, + 0x80, 0x03, 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, + 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, + 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, + 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, + 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, + 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, + 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, + 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, + 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, + 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, + 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, + 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, + 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, + 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, + 0x59, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc2, 0x34, + 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x24, 0x20, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x40, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, + 0x26, 0x47, 0xc6, 0x04, 0x43, 0x7a, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, + 0x50, 0x08, 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, + 0xc5, 0x40, 0x74, 0x2c, 0x61, 0x09, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, + 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0xc6, + 0x63, 0x4c, 0x00, 0xf5, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, + 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x3c, 0xc3, 0x24, 0x3c, 0x07, 0xe5, 0x20, + 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, + 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, + 0x25, 0xc6, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, + 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0xc6, 0x25, + 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, 0x8c, 0x67, 0x78, 0x92, 0x87, 0x60, + 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x99, 0x8e, 0x67, 0x78, 0x86, + 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, + 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, + 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x98, 0x12, 0x72, 0x61, 0x69, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, + 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x43, 0x84, 0x69, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, + 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, + 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, + 0x7d, 0x91, 0xa5, 0xcd, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0xa6, 0x86, + 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, + 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, + 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, + 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe9, 0x79, 0x88, + 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, + 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, + 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, + 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, + 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, + 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, 0xb7, + 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, 0xd6, 0x04, 0x4d, 0xd1, 0x74, + 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, + 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, + 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, + 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x9e, 0x61, 0xd2, 0xa6, + 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, 0xba, 0xa6, 0x8e, 0xd9, 0x59, + 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, 0x19, + 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, 0x0a, + 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, 0x98, 0xb4, 0xe9, 0x9b, 0xaa, + 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, 0x0a, 0x03, 0x2a, 0x61, 0x69, + 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x7c, 0xc2, 0xd2, 0xe4, + 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, 0xbe, 0xe6, 0xd2, 0xf4, 0xca, + 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, 0xbd, + 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0x11, 0x09, 0x4b, 0x93, 0x73, + 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, 0x26, 0xe7, 0x32, 0x47, 0x27, + 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x95, 0xe6, 0x66, + 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, 0x6e, 0x86, 0xc6, 0x9b, 0x99, + 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, 0xb7, 0x32, 0x33, 0x33, 0x1a, + 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, 0x84, 0xc6, 0xde, 0xca, 0xcc, + 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xa5, + 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xa9, 0xc1, 0xb3, 0x3c, + 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, 0xc3, 0x3c, 0xc5, 0x43, 0x4c, + 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, + 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x5e, 0x61, + 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x4c, 0xb2, + 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x68, 0x90, 0x95, 0x8d, + 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, 0x99, 0xc6, 0x60, 0x22, 0x83, + 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, 0x32, 0x83, 0xe9, 0x0c, 0xa6, + 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, 0x78, 0x8a, 0x09, 0x9a, 0xe0, + 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, 0x26, 0xe7, 0x42, 0x57, 0x86, + 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0x2e, 0xac, + 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, 0x1e, 0x5d, 0x9d, 0x5c, 0x99, + 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, 0x1d, 0x0b, 0xc8, 0x5c, 0x58, + 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, 0x32, 0xbc, 0xac, 0x21, 0xd4, + 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, 0x3c, 0xc3, 0x44, 0x07, 0x13, + 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, 0x82, 0xae, 0x0c, 0xaf, 0xca, + 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, 0x65, 0xf0, 0x0c, 0xcf, 0x30, + 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, 0x13, 0x1e, 0x70, 0x09, 0x4b, + 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, 0xe3, 0x31, 0x17, + 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, 0x6e, 0x88, 0xf4, 0x38, 0x93, + 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, 0x41, 0xd3, 0x1e, 0x4c, 0xd7, + 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, 0x49, 0x0c, 0x26, 0x39, 0x98, + 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, 0x18, 0x0b, 0x30, 0x4d, 0x93, + 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, 0x1d, + 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, 0x1d, + 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, 0x77, 0xa0, + 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0xb0, + 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, 0x29, 0x81, + 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, 0x70, 0x70, + 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, 0x7b, 0x28, + 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, 0x20, 0x23, + 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, 0x80, + 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, 0x7a, 0x48, + 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, 0x09, + 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, 0x68, + 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xfc, 0x01, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, 0x57, 0x77, + 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, + 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, + 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xda, 0xf5, 0x5f, 0x44, 0x80, + 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x74, 0x47, 0x00, 0xa8, 0x8e, 0x35, 0x00, 0x03, 0x31, 0xc7, + 0x40, 0x0c, 0xdf, 0x1c, 0x03, 0xf1, 0x7d, 0x63, 0x0d, 0x40, 0x20, 0x10, + 0x1c, 0x4b, 0x08, 0x00, 0x72, 0x35, 0x30, 0x02, 0x40, 0x6f, 0x06, 0x80, + 0xe0, 0x08, 0x00, 0x89, 0x19, 0x00, 0x0a, 0x73, 0x10, 0x66, 0x60, 0x06, 0x66, 0x40, 0x06, 0x33, 0x00, 0x04, 0xc6, 0x08, 0x40, 0x10, 0x04, 0xf1, - 0x6f, 0x04, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, - 0x94, 0x81, 0x04, 0x55, 0x89, 0x82, 0x08, 0x83, 0x0c, 0x41, 0xe1, 0x8c, - 0x18, 0x28, 0x43, 0x70, 0x06, 0x93, 0x74, 0x2d, 0x8c, 0x42, 0x0c, 0x32, - 0x04, 0x87, 0x33, 0xc8, 0x10, 0x28, 0xd2, 0x20, 0x03, 0x11, 0x50, 0x97, - 0xdd, 0xa5, 0xa0, 0x0c, 0x32, 0x04, 0x0c, 0x65, 0x44, 0x00, 0x1f, 0xf2, - 0xca, 0x78, 0x83, 0x37, 0x06, 0x6f, 0x70, 0xc1, 0x5d, 0x0a, 0xca, 0x20, - 0x43, 0x20, 0x69, 0x23, 0x06, 0x85, 0x10, 0xd4, 0x81, 0x11, 0x8c, 0x37, - 0x8c, 0x01, 0x1a, 0xc4, 0xc1, 0x05, 0x77, 0x29, 0x28, 0x83, 0x0c, 0xc1, - 0xf5, 0x8d, 0x18, 0x14, 0x42, 0xa0, 0x07, 0x4b, 0x30, 0xde, 0x80, 0x06, - 0x6d, 0x20, 0x07, 0x17, 0xdc, 0xa5, 0xa0, 0x0c, 0x32, 0x04, 0x1c, 0x19, - 0x8c, 0x18, 0x14, 0x42, 0xf0, 0x07, 0x50, 0x30, 0xc7, 0xf0, 0x2d, 0x7d, - 0x30, 0xc7, 0x10, 0x1c, 0x7f, 0x30, 0xc7, 0x10, 0x0c, 0x7d, 0x60, 0xc1, - 0x24, 0x9f, 0x0c, 0x02, 0x62, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x5b, 0x06, 0x25, 0x18, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x6f, 0x04, 0x60, 0x06, 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x94, 0xc1, + 0x14, 0x55, 0xca, 0x91, 0x08, 0x83, 0x0c, 0x41, 0xe1, 0x8c, 0x18, 0x28, + 0x43, 0x70, 0x06, 0xd4, 0x74, 0x31, 0xc9, 0x42, 0x0c, 0x32, 0x04, 0x87, + 0x33, 0xc8, 0x10, 0x28, 0xd2, 0x20, 0x03, 0x11, 0x50, 0xa7, 0xd9, 0xa5, + 0xa0, 0x0c, 0x32, 0x04, 0x0c, 0x65, 0x44, 0x00, 0x9f, 0xf1, 0x06, 0x4f, + 0x73, 0x83, 0x0b, 0xec, 0x52, 0x50, 0x06, 0x19, 0x82, 0x28, 0x1b, 0x31, + 0x28, 0x84, 0x80, 0x0e, 0x8a, 0x60, 0xbc, 0x61, 0x0c, 0x3e, 0x38, 0xb8, + 0xc0, 0x2e, 0x05, 0x65, 0x90, 0x21, 0xb0, 0xbc, 0x11, 0x83, 0x42, 0x08, + 0xf2, 0x40, 0x09, 0xc6, 0x1b, 0xd0, 0x80, 0x0c, 0xe2, 0xe0, 0x02, 0xbb, + 0x14, 0x94, 0x41, 0x86, 0x60, 0x1b, 0x83, 0x11, 0x83, 0x42, 0x08, 0xfc, + 0xe0, 0x09, 0xe6, 0x18, 0xbc, 0x85, 0x0f, 0xe6, 0x18, 0x82, 0xc3, 0x0f, + 0xe6, 0x18, 0x82, 0x81, 0x0f, 0x2c, 0x90, 0x03, 0xf9, 0x64, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -const unsigned int sdl_metallib_len = 22080; +const unsigned int sdl_metallib_len = 21858; diff --git a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_tvos.h b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_tvos.h index c62288d5a..bbf2cec09 100644 --- a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_tvos.h +++ b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_tvos.h @@ -1,206 +1,208 @@ const unsigned char sdl_metallib[] = { 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x04, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x51, 0x00, 0x00, + 0x72, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, - 0x28, 0x31, 0x40, 0x63, 0x07, 0x67, 0xcf, 0xec, 0x7b, 0x53, 0x36, 0x27, - 0xdc, 0xe7, 0xb5, 0x97, 0xd0, 0x99, 0xe7, 0x0a, 0x52, 0x5d, 0x98, 0xd7, - 0xc6, 0x8e, 0xba, 0x3c, 0x01, 0x5f, 0xad, 0xf5, 0x4f, 0x46, 0x46, 0x54, + 0xa4, 0x5e, 0x94, 0xe7, 0x16, 0x2a, 0x15, 0xdb, 0x41, 0x62, 0x0f, 0xc4, + 0x8a, 0xaa, 0x92, 0x52, 0xe1, 0x1e, 0xbe, 0x5f, 0xef, 0xec, 0x0e, 0x83, + 0x38, 0xb6, 0x06, 0x42, 0xfb, 0x46, 0x30, 0x45, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x77, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, - 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x47, - 0xb8, 0x4f, 0x55, 0x1e, 0x1e, 0x4a, 0x32, 0x12, 0x7a, 0x9e, 0xc2, 0xf0, - 0xf9, 0x2b, 0x85, 0x1f, 0xe9, 0x90, 0x33, 0xc4, 0xdf, 0xa9, 0x3a, 0xca, - 0x6b, 0x6d, 0xdd, 0xe9, 0x46, 0x64, 0x83, 0x4f, 0x46, 0x46, 0x54, 0x18, - 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x4a, + 0xdb, 0x37, 0xcf, 0x60, 0x13, 0xba, 0xf8, 0x04, 0xff, 0xec, 0xd1, 0x3d, + 0x3f, 0x77, 0xbb, 0xaa, 0xe4, 0x36, 0xd0, 0x6e, 0x89, 0xfb, 0x91, 0xfb, + 0xfd, 0xb2, 0xb4, 0x56, 0x8e, 0x5e, 0x05, 0x4f, 0x46, 0x46, 0x54, 0x18, + 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x7a, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x13, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, - 0x00, 0x69, 0x9d, 0x1d, 0x1f, 0x5c, 0x05, 0x77, 0xfb, 0x40, 0x83, 0x70, - 0x5e, 0x26, 0x13, 0x34, 0xb5, 0xd7, 0x61, 0x21, 0x42, 0x6a, 0xc9, 0x8d, - 0xd0, 0x59, 0x04, 0x0b, 0x18, 0x09, 0x74, 0x40, 0x7c, 0x4f, 0x46, 0x46, - 0x54, 0x18, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x16, 0x00, 0x00, 0x00, + 0x00, 0x93, 0xcd, 0x48, 0xeb, 0xee, 0x18, 0x36, 0xf1, 0x25, 0x14, 0x9f, + 0x98, 0xc6, 0x7e, 0x3f, 0x06, 0xd1, 0x5d, 0x98, 0x2a, 0x2f, 0x70, 0xe1, + 0xa3, 0xa4, 0x4f, 0x06, 0x51, 0xd9, 0x24, 0xdb, 0x3d, 0x4f, 0x46, 0x46, + 0x54, 0x18, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, - 0x20, 0x00, 0x88, 0x94, 0x57, 0x70, 0x82, 0x3f, 0xe3, 0xbc, 0x88, 0x1c, - 0x9c, 0x13, 0xbd, 0x4d, 0xc3, 0x16, 0xdf, 0x68, 0x5e, 0xe0, 0xe9, 0xa9, - 0x06, 0x9e, 0x2f, 0xf0, 0x86, 0xf6, 0x8d, 0x56, 0xf2, 0xbf, 0x4f, 0x46, - 0x46, 0x54, 0x18, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x48, 0x19, 0xba, 0x48, 0x88, 0x08, 0x02, 0x7a, 0x7b, 0x87, + 0x60, 0x4f, 0x56, 0x77, 0x82, 0x12, 0xd0, 0x8d, 0x75, 0x00, 0x13, 0xd4, + 0x4f, 0x12, 0x69, 0x87, 0x49, 0x45, 0xb7, 0xda, 0x31, 0x6f, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x78, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, - 0x20, 0x00, 0xf7, 0x98, 0xd0, 0xe2, 0xdc, 0xe8, 0x70, 0x90, 0xb8, 0xd2, - 0x1e, 0x21, 0x36, 0xa4, 0xb8, 0xca, 0x52, 0xcb, 0xb8, 0xc9, 0x61, 0xa4, - 0x80, 0x75, 0xa2, 0x9b, 0x4b, 0x82, 0x22, 0x60, 0xa6, 0xc9, 0x4f, 0x46, - 0x46, 0x54, 0x18, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, + 0x20, 0x00, 0x86, 0xd8, 0xc8, 0xb9, 0x4b, 0x3f, 0xf0, 0x71, 0x98, 0x15, + 0x75, 0xd7, 0xc4, 0x78, 0x49, 0x02, 0xc5, 0x2c, 0x0d, 0xa2, 0xf8, 0x40, + 0xd8, 0x18, 0xf5, 0xa8, 0xc2, 0x8b, 0x11, 0x42, 0x60, 0x9e, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, - 0x48, 0x20, 0x00, 0x64, 0x76, 0x02, 0x5c, 0xd4, 0x80, 0xf1, 0x25, 0xd7, - 0x2a, 0xa6, 0xb0, 0x3c, 0xd8, 0xe6, 0x3a, 0x38, 0xe3, 0xd6, 0x15, 0x67, - 0x59, 0x20, 0xfd, 0x1b, 0xfe, 0x8c, 0x87, 0x1e, 0xfe, 0x9d, 0x9e, 0x4f, - 0x46, 0x46, 0x54, 0x18, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x38, 0x00, + 0x48, 0x20, 0x00, 0x0c, 0x19, 0x24, 0x25, 0x5b, 0x90, 0x7b, 0xbe, 0xd8, + 0x0c, 0x0d, 0x1b, 0x66, 0xe5, 0x2f, 0xc5, 0x6d, 0x8a, 0xf1, 0x08, 0xc3, + 0x68, 0x52, 0x1a, 0x5b, 0x1f, 0x8d, 0x05, 0xe0, 0x43, 0x9b, 0xce, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, - 0x53, 0x48, 0x20, 0x00, 0x23, 0xbd, 0x28, 0xce, 0x4f, 0xb7, 0xc7, 0x94, - 0x2a, 0x0a, 0x20, 0x48, 0x6f, 0x52, 0x4a, 0xcc, 0x07, 0x9c, 0x7f, 0x41, - 0x8d, 0x0a, 0x31, 0x81, 0xec, 0xe4, 0xd4, 0x71, 0x77, 0x7b, 0x22, 0x7d, - 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x44, + 0x53, 0x48, 0x20, 0x00, 0x4a, 0x04, 0xcb, 0xef, 0xd3, 0x81, 0xd0, 0x17, + 0x11, 0xf6, 0x23, 0x6b, 0x3b, 0x38, 0xfc, 0x61, 0xe0, 0x6d, 0x22, 0x94, + 0x28, 0x7c, 0x7f, 0xe6, 0x31, 0xde, 0x9b, 0xe1, 0x58, 0x2b, 0x1f, 0x84, + 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x45, 0x4e, 0x44, 0x54, 0x20, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, - 0x0d, 0x00, 0x01, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x00, 0x00, 0x80, 0x56, 0x41, 0x54, 0x59, 0x03, 0x00, 0x01, 0x00, 0x04, - 0x45, 0x4e, 0x44, 0x54, 0x2c, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, - 0x18, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x00, 0x00, 0x80, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, - 0x01, 0x80, 0x56, 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x04, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, - 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, - 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x3c, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, - 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, - 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, - 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, - 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, - 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, - 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, - 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, - 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, - 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, - 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, - 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, - 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, - 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, - 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, - 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, - 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, - 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, - 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, - 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, - 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, - 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, - 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, - 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, - 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, - 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, - 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, - 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, - 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, - 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, - 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, - 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, - 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, - 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, - 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, - 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, - 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, - 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, - 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, - 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, - 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, - 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, + 0x45, 0x4e, 0x44, 0x54, 0x29, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, + 0x15, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x56, + 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x06, 0x45, 0x4e, 0x44, + 0x54, 0x35, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x20, 0x00, 0x03, + 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x80, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x02, 0x80, 0x56, 0x41, 0x54, 0x59, 0x05, + 0x00, 0x03, 0x00, 0x04, 0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa0, 0x0b, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0xe5, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, + 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, + 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, + 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, + 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, + 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, + 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, + 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, + 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, + 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, + 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, + 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, + 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, + 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, + 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, + 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, - 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, - 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, - 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, - 0x36, 0x20, 0x82, 0x00, 0x24, 0xc0, 0x02, 0x54, 0x1b, 0x90, 0x61, 0x00, - 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x89, 0x20, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, - 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, - 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, - 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x60, 0x85, 0x00, 0x86, 0x11, - 0x04, 0x20, 0x09, 0xc2, 0x4c, 0xd4, 0x3c, 0xd0, 0x83, 0x3c, 0xd4, 0xc3, - 0x38, 0xd0, 0x83, 0x1b, 0xb4, 0x43, 0x39, 0xd0, 0x43, 0x38, 0xb0, 0x83, - 0x1e, 0xe8, 0x41, 0x3b, 0x84, 0x03, 0x3d, 0xc8, 0x43, 0x3a, 0xe0, 0x03, - 0x0a, 0xc8, 0x20, 0x42, 0x21, 0x14, 0x42, 0x0c, 0x63, 0xe8, 0x0c, 0x04, - 0xcc, 0x11, 0x80, 0x41, 0x0a, 0xa8, 0x39, 0x02, 0x50, 0x18, 0x44, 0x08, - 0x84, 0x61, 0x04, 0x42, 0x19, 0x01, 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, - 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, - 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, - 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, - 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, - 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, - 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, - 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, - 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, - 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, - 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, - 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, - 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, - 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, - 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, - 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, - 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, - 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, - 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, - 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, - 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, - 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, - 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, - 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, - 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, - 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, - 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, - 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, - 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, - 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, - 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x80, 0x01, 0x45, 0x50, - 0x20, 0x85, 0x50, 0x10, 0x65, 0x40, 0x6c, 0x04, 0x80, 0xd6, 0x58, 0x82, - 0x23, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, - 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, - 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, 0xc0, 0xa2, 0x50, 0xb9, - 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, - 0x41, 0x22, 0x28, 0x06, 0xdd, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, - 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, - 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x06, 0x04, 0xa5, 0xad, - 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, - 0x85, 0x66, 0x26, 0x65, 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, 0x50, 0x0e, + 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, + 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, + 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, + 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, + 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, + 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, + 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, + 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, + 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, + 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, + 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, + 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x20, 0xc2, 0x00, 0x24, 0xc0, + 0x02, 0x54, 0x1b, 0x90, 0x81, 0x00, 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, + 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, + 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, + 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, + 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, + 0x04, 0x60, 0x87, 0x10, 0xc0, 0x30, 0x82, 0x00, 0x24, 0x41, 0x98, 0x89, + 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, + 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, + 0x52, 0x88, 0x11, 0x8c, 0xa1, 0x33, 0x10, 0x30, 0x47, 0x00, 0x06, 0x29, + 0xa0, 0xe6, 0x08, 0x40, 0x61, 0x10, 0x21, 0x10, 0x86, 0x11, 0x08, 0x65, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, + 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, + 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, + 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, + 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, + 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, + 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, + 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, + 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, + 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, + 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, + 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, + 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x43, 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x80, 0x01, 0x45, 0x50, 0x20, 0x65, + 0x50, 0x08, 0x05, 0x41, 0x6c, 0x04, 0x80, 0xd6, 0x58, 0x82, 0x33, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, + 0x28, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, 0x50, 0x10, 0x45, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, 0x0e, 0x25, 0x50, 0x02, 0x45, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, @@ -216,283 +218,45 @@ const unsigned char sdl_metallib[] = { 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x64, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, 0x88, 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, - 0xb9, 0x0d, 0x51, 0x92, 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x4e, - 0x58, 0x9a, 0x9c, 0x0b, 0xdc, 0x5b, 0x9a, 0x1b, 0xdd, 0xd7, 0x5c, 0x9a, - 0x5e, 0x19, 0x0b, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x26, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x43, 0x94, 0xa4, 0x4a, 0xa0, 0xc4, - 0x4a, 0xa4, 0xe4, 0x1a, 0x42, 0x24, 0x54, 0x82, 0x11, 0x0a, 0x4b, 0x93, - 0x73, 0xb1, 0x2b, 0x93, 0xa3, 0x2b, 0xc3, 0xfb, 0x4a, 0x73, 0x83, 0xab, - 0xa3, 0xa3, 0x14, 0x96, 0x26, 0xe7, 0xc2, 0xf6, 0x36, 0x16, 0x46, 0x97, - 0xf6, 0xe6, 0xf6, 0x95, 0xe6, 0x46, 0x56, 0x86, 0x47, 0xef, 0xac, 0xcc, - 0xad, 0x4c, 0x2e, 0x8c, 0xae, 0x8c, 0x0c, 0xe5, 0xeb, 0x2b, 0x2c, 0x4d, - 0xee, 0x0b, 0x8e, 0x2d, 0x6c, 0xac, 0x0c, 0xed, 0x8d, 0x8d, 0xac, 0x4c, - 0xee, 0xeb, 0x2b, 0x85, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0x9d, 0xcc, 0x10, - 0x4a, 0x11, 0x12, 0x2d, 0xd9, 0x14, 0x41, 0x09, 0x12, 0x2e, 0x81, 0x92, - 0x2e, 0x91, 0x92, 0x89, 0x4a, 0x58, 0x9a, 0x9c, 0x8b, 0x58, 0x9d, 0x99, - 0x59, 0x99, 0x1c, 0x9f, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, 0xb3, - 0x32, 0xb9, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x22, 0x61, 0x69, 0x72, 0x2e, - 0x72, 0x65, 0x61, 0x64, 0x8c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, - 0xbe, 0xe8, 0xf2, 0xe0, 0xca, 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x78, 0x85, - 0xa5, 0xc9, 0xb9, 0x84, 0xc9, 0x9d, 0x7d, 0xd1, 0xe5, 0xc1, 0x95, 0x7d, - 0x85, 0xb1, 0xa5, 0x9d, 0xb9, 0x7d, 0xcd, 0xa5, 0xe9, 0x95, 0x11, 0x31, - 0x63, 0x7b, 0x0b, 0xa3, 0xa3, 0xc1, 0xa3, 0xa1, 0x02, 0x27, 0xf7, 0xa6, - 0x56, 0x36, 0x46, 0x97, 0xf6, 0xe6, 0x36, 0x04, 0x0c, 0x94, 0x20, 0xf9, - 0x12, 0x30, 0x50, 0x86, 0x64, 0x53, 0x08, 0x25, 0x48, 0xc2, 0x20, 0x11, - 0x03, 0x65, 0x48, 0xc6, 0x40, 0x29, 0x12, 0x28, 0x21, 0x83, 0x44, 0x4a, - 0xca, 0x80, 0x09, 0x9d, 0x5c, 0x98, 0xdb, 0x9c, 0xd9, 0x9b, 0x5c, 0xdb, - 0x10, 0x30, 0x50, 0x88, 0xe4, 0x4b, 0xc0, 0x40, 0x19, 0x92, 0x4d, 0x41, - 0x94, 0x20, 0x09, 0x83, 0x44, 0x0c, 0x94, 0x21, 0x19, 0x03, 0xa5, 0x48, - 0xa0, 0x84, 0x0c, 0x12, 0x29, 0x39, 0x83, 0x21, 0x46, 0xe2, 0x25, 0x66, - 0x90, 0xa0, 0xc1, 0x10, 0x03, 0x01, 0x92, 0x2c, 0x49, 0x03, 0x3e, 0x6f, - 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, - 0x61, 0x72, 0x7c, 0xa6, 0xd2, 0xda, 0xe0, 0xd8, 0xca, 0x40, 0x86, 0x56, - 0x56, 0x40, 0xa8, 0x84, 0x82, 0x82, 0x86, 0x08, 0x09, 0x1b, 0x0c, 0x31, - 0x92, 0x35, 0x48, 0xda, 0x80, 0x49, 0x86, 0x18, 0x89, 0x1b, 0x24, 0x6e, - 0xc0, 0x24, 0x23, 0x22, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, - 0x87, 0x77, 0x20, 0x87, 0x7a, 0x60, 0x87, 0x72, 0x70, 0x03, 0x73, 0x60, - 0x87, 0x70, 0x38, 0x87, 0x79, 0x98, 0x22, 0x04, 0xc3, 0x08, 0x85, 0x1d, - 0xd8, 0xc1, 0x1e, 0xda, 0xc1, 0x0d, 0xd2, 0x81, 0x1c, 0xca, 0xc1, 0x1d, - 0xe8, 0x61, 0x4a, 0x50, 0x8c, 0x58, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, - 0xec, 0xa1, 0x1c, 0xe4, 0x61, 0x1e, 0xd2, 0xe1, 0x1d, 0xdc, 0x61, 0x4a, - 0x60, 0x8c, 0xa0, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, 0xd8, 0x21, 0x1c, - 0xdc, 0xe1, 0x1c, 0xea, 0x21, 0x1c, 0xce, 0xa1, 0x1c, 0x7e, 0xc1, 0x1e, - 0xca, 0x41, 0x1e, 0xe6, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0xa6, 0x04, 0xc8, - 0x88, 0x29, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0x60, 0x1c, 0xde, 0xa1, 0x1d, - 0xe0, 0x21, 0x1d, 0xd8, 0xa1, 0x1c, 0x7e, 0xe1, 0x1d, 0xe0, 0x81, 0x1e, - 0xd2, 0xe1, 0x1d, 0xdc, 0x61, 0x1e, 0xa6, 0x0c, 0x0a, 0xe3, 0x8c, 0x50, - 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, 0xec, 0xa1, 0x1c, 0xe4, 0x81, 0x1e, - 0xca, 0x01, 0x1f, 0xa6, 0x04, 0x6a, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, - 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, - 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, - 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, - 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, - 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, - 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, - 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, - 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, - 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, - 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, - 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, - 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, - 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, - 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, - 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, - 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, - 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, - 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, - 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, - 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, - 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, - 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, - 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, - 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, - 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, - 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, - 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, - 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, - 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, - 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, - 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, - 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, - 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, - 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, - 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, - 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, - 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, - 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, - 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, - 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, - 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x06, 0x00, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, 0x45, 0x44, - 0x13, 0x71, 0x01, 0x00, 0x61, 0x20, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, - 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, - 0x22, 0x82, 0x20, 0x08, 0x46, 0x00, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, - 0x8d, 0x19, 0x00, 0x12, 0x33, 0x00, 0x14, 0x66, 0x00, 0x08, 0x8c, 0x11, - 0x80, 0x20, 0x08, 0xe2, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x11, 0x0c, 0x74, - 0x41, 0x14, 0x94, 0xf1, 0x88, 0x47, 0xca, 0x24, 0x0a, 0xca, 0x20, 0xc3, - 0x60, 0x30, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x98, 0xac, 0xae, 0xa1, 0xa0, - 0x0c, 0x32, 0x1c, 0x4a, 0x64, 0x42, 0x20, 0x1f, 0x0b, 0x0a, 0xf8, 0x8c, - 0x47, 0x60, 0x9b, 0x18, 0x40, 0x14, 0x94, 0x41, 0x06, 0xe6, 0xb9, 0x4c, - 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x88, 0x0e, 0x0c, 0xce, 0xc0, - 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x54, 0x67, 0x42, 0x20, 0x1f, 0x2b, 0x02, - 0xf8, 0x8c, 0x47, 0x84, 0x41, 0x19, 0xb0, 0x01, 0x47, 0x41, 0x19, 0x64, - 0x08, 0xb2, 0xcf, 0x82, 0x4a, 0x3e, 0x83, 0x0c, 0xc3, 0x26, 0x06, 0x16, - 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, 0xe1, 0x99, 0x81, 0x05, - 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, 0x84, 0x81, 0x1a, 0x58, - 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, 0x6e, 0x20, 0x07, 0x79, - 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xc0, 0x0c, 0xd8, 0xc0, 0x02, 0x31, - 0x90, 0xcf, 0x20, 0xc3, 0x80, 0x06, 0x6f, 0x60, 0x01, 0x18, 0xc8, 0x67, - 0x90, 0xa1, 0x50, 0x03, 0x39, 0xb0, 0xa0, 0x93, 0xcf, 0x20, 0xc3, 0xc1, - 0x06, 0x75, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x06, 0x3d, 0x80, 0x03, 0x3a, - 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x03, 0x1f, 0xc8, 0xc1, 0x1d, 0x98, 0x13, - 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, 0xb1, 0x20, 0x81, 0x8f, - 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, 0x80, 0x07, 0x01, 0x30, - 0xdb, 0x10, 0xdc, 0x41, 0x90, 0x41, 0x40, 0x0c, 0x09, 0x00, 0x00, 0x00, - 0x5b, 0x86, 0x20, 0x78, 0x83, 0x2d, 0xc3, 0x10, 0xbc, 0xc1, 0x96, 0xe1, - 0x08, 0xde, 0x60, 0xcb, 0xc0, 0x04, 0x6f, 0xb0, 0x65, 0x88, 0x82, 0x37, - 0xd8, 0x32, 0x58, 0xc1, 0x1b, 0x6c, 0x19, 0xc6, 0x20, 0x78, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x60, 0x0b, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, - 0xd5, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, - 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, - 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, - 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, - 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, - 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, - 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, - 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, - 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, - 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, - 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, - 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, - 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, - 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, - 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, - 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, - 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, - 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, - 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, - 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, - 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, - 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, - 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, - 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, - 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, - 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, - 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, - 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, - 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, - 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, - 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, - 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, - 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, - 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, - 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, - 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, - 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, - 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, - 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, - 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, - 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, - 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, - 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, - 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, - 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, - 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, - 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, - 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, - 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, - 0x98, 0x87, 0x72, 0x00, 0x36, 0x20, 0xc2, 0x00, 0x24, 0xc0, 0x02, 0x54, - 0x1b, 0x90, 0x81, 0x00, 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, - 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, - 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, - 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, - 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, - 0x8c, 0x20, 0x00, 0x56, 0x08, 0x22, 0x09, 0xc2, 0x4c, 0xd4, 0x3c, 0xd0, - 0x83, 0x3c, 0xd4, 0xc3, 0x38, 0xd0, 0x83, 0x1b, 0xb4, 0x43, 0x39, 0xd0, - 0x43, 0x38, 0xb0, 0x83, 0x1e, 0xe8, 0x41, 0x3b, 0x84, 0x03, 0x3d, 0xc8, - 0x43, 0x3a, 0xe0, 0x03, 0x0a, 0xc8, 0x20, 0x42, 0x21, 0x94, 0x62, 0x08, - 0x61, 0x0c, 0x9d, 0x81, 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x35, 0x47, - 0x00, 0x0a, 0x83, 0x08, 0x81, 0x30, 0x8c, 0x40, 0x28, 0x23, 0x00, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x04, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, - 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, - 0x80, 0x01, 0x45, 0x50, 0x20, 0x65, 0x50, 0x08, 0x05, 0x41, 0x6c, 0x04, - 0x80, 0xd6, 0x58, 0x82, 0x23, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, - 0xd9, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, - 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, 0x28, 0x07, 0xdd, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, - 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, - 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x26, 0x65, 0x88, 0x90, 0x10, 0x43, - 0x0c, 0x25, 0x50, 0x10, 0x45, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, - 0x04, 0x49, 0x0e, 0x25, 0x50, 0x02, 0x45, 0xe0, 0x16, 0x96, 0x26, 0xe7, - 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, - 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, - 0x44, 0x48, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, - 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, - 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x64, 0x21, - 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, - 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, - 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, - 0x95, 0x0d, 0x11, 0x92, 0x86, 0x4c, 0x58, 0x9a, 0x9c, 0x0b, 0xdc, 0xdb, - 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0x1b, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, - 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, - 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x64, 0xc2, 0xd2, 0xe4, 0x5c, - 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, 0x88, 0xc0, 0xbd, 0xcd, - 0xa5, 0xd1, 0xa5, 0xbd, 0xb9, 0x0d, 0x51, 0x92, 0x27, 0x81, 0x92, 0x28, - 0x91, 0x92, 0x89, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5d, 0x99, 0x1c, 0x5d, - 0x19, 0xde, 0xd7, 0x5b, 0x1d, 0x1d, 0x5c, 0x1d, 0x1d, 0xb3, 0xb3, 0x32, - 0xb7, 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x14, 0x1c, 0xba, 0x32, 0xbc, - 0xb1, 0xb7, 0x37, 0x39, 0x32, 0x22, 0x3b, 0x99, 0x2f, 0xb3, 0x14, 0x1a, - 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x44, 0xe8, 0xca, 0xf0, 0xc6, 0xde, - 0xde, 0xe4, 0xc8, 0x86, 0x30, 0x49, 0x95, 0x58, 0x09, 0x94, 0x5c, 0x89, - 0x94, 0x60, 0x43, 0x88, 0x84, 0x4a, 0x32, 0x42, 0x61, 0x69, 0x72, 0x2e, - 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x94, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, - 0xdc, 0xbe, 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0xe8, 0x9d, 0x95, 0xb9, 0x95, - 0xc9, 0x85, 0xd1, 0x95, 0x91, 0xa1, 0x7c, 0x7d, 0x85, 0xa5, 0xc9, 0x7d, - 0xc1, 0xb1, 0x85, 0x8d, 0x95, 0xa1, 0xbd, 0xb1, 0x91, 0x95, 0xc9, 0x7d, - 0x7d, 0xa5, 0x0c, 0xa1, 0x14, 0x21, 0xd9, 0x12, 0x4e, 0x11, 0x94, 0x20, - 0xe9, 0x12, 0x28, 0xb9, 0x12, 0x29, 0x99, 0x86, 0x50, 0x4a, 0x90, 0x6c, - 0x09, 0xa7, 0x04, 0x4a, 0x90, 0x74, 0x09, 0x94, 0x5c, 0x89, 0x94, 0x60, - 0x54, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, 0xf8, - 0x84, 0xa5, 0xc9, 0xb9, 0x88, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0xcd, - 0xa5, 0xe9, 0x95, 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, - 0x63, 0x14, 0x96, 0x26, 0xe7, 0x12, 0x26, 0x77, 0xf6, 0x45, 0x97, 0x07, - 0x57, 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x2b, 0x2c, 0x4d, 0xce, 0x25, - 0x4c, 0xee, 0xec, 0x8b, 0x2e, 0x0f, 0xae, 0xec, 0x2b, 0x8c, 0x2d, 0xed, - 0xcc, 0xed, 0x6b, 0x2e, 0x4d, 0xaf, 0x8c, 0x88, 0x19, 0xdb, 0x5b, 0x18, - 0x1d, 0x0d, 0x1e, 0x0d, 0x15, 0x38, 0xb9, 0x37, 0xb5, 0xb2, 0x31, 0xba, - 0xb4, 0x37, 0xb7, 0x21, 0x60, 0xa0, 0x10, 0x09, 0x18, 0x24, 0x61, 0xa0, - 0x0c, 0x09, 0xa7, 0x10, 0x4a, 0x90, 0x88, 0x41, 0x32, 0x06, 0xca, 0x90, - 0x90, 0x81, 0x52, 0x24, 0x50, 0x52, 0x06, 0x89, 0x94, 0x98, 0x01, 0x13, - 0x3a, 0xb9, 0x30, 0xb7, 0x39, 0xb3, 0x37, 0xb9, 0xb6, 0x21, 0x60, 0xa0, - 0x18, 0x09, 0x18, 0x24, 0x61, 0xa0, 0x0c, 0x09, 0xa7, 0x18, 0x4a, 0x90, - 0x88, 0x41, 0x32, 0x06, 0xca, 0x90, 0x90, 0x81, 0x52, 0x24, 0x50, 0x52, - 0x06, 0x89, 0x94, 0xa0, 0xc1, 0x10, 0x24, 0xf1, 0x92, 0x2f, 0x39, 0x83, - 0x24, 0x0d, 0x86, 0x18, 0x08, 0x90, 0x68, 0x89, 0x1a, 0xf0, 0x79, 0x6b, + 0xb9, 0x0d, 0x51, 0x92, 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, + 0x58, 0x9a, 0x9c, 0x8b, 0x5d, 0x99, 0x1c, 0x5d, 0x19, 0xde, 0xd7, 0x5b, + 0x1d, 0x1d, 0x5c, 0x1d, 0x1d, 0xad, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, + 0xba, 0x32, 0x32, 0x94, 0x9a, 0xb1, 0x37, 0xb6, 0x37, 0x39, 0x22, 0x3b, + 0x9a, 0x2f, 0xb3, 0x14, 0x16, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x98, + 0xa4, 0x4a, 0xac, 0x04, 0x4a, 0xa2, 0x44, 0x4a, 0x2e, 0x3a, 0x61, 0x69, + 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x2c, 0xcc, 0xd8, 0xde, 0xc2, 0xe8, 0x98, 0xc0, 0xbd, 0xa5, 0xb9, 0xd1, + 0x4d, 0xa5, 0xe9, 0x95, 0x0d, 0x51, 0x92, 0x2c, 0x81, 0x12, 0x2d, 0x91, + 0x92, 0x6d, 0x88, 0x91, 0x50, 0x09, 0x96, 0x70, 0x84, 0xc2, 0xd2, 0xe4, + 0x5c, 0xec, 0xca, 0xe4, 0xe8, 0xca, 0xf0, 0xbe, 0xd2, 0xdc, 0xe0, 0xea, + 0xe8, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, + 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0xd1, 0x3b, 0x2b, 0x73, + 0x2b, 0x93, 0x0b, 0xa3, 0x2b, 0x23, 0x43, 0xf9, 0xfa, 0x0a, 0x4b, 0x93, + 0xfb, 0x82, 0x63, 0x0b, 0x1b, 0x2b, 0x43, 0x7b, 0x63, 0x23, 0x2b, 0x93, + 0xfb, 0xfa, 0x4a, 0xa1, 0x61, 0xc6, 0xf6, 0x16, 0x46, 0x27, 0x33, 0x84, + 0x52, 0x84, 0xc4, 0x4b, 0x3e, 0x45, 0x50, 0x82, 0x04, 0x0c, 0x12, 0x28, + 0x09, 0x83, 0x44, 0x4a, 0xa6, 0x21, 0x94, 0x12, 0x24, 0x5e, 0xf2, 0x29, + 0x81, 0x12, 0x24, 0x60, 0x90, 0x40, 0x49, 0x94, 0x48, 0xc9, 0x45, 0x25, + 0x2c, 0x4d, 0xce, 0x45, 0xac, 0xce, 0xcc, 0xac, 0x4c, 0x8e, 0x4f, 0x58, + 0x9a, 0x9c, 0x8b, 0x58, 0x9d, 0x99, 0x59, 0x99, 0xdc, 0xd7, 0x5c, 0x9a, + 0x5e, 0x19, 0x91, 0xb0, 0x34, 0x39, 0x17, 0xb9, 0xb2, 0x30, 0x32, 0x46, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0xbc, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, + 0xce, 0xbe, 0xe8, 0xf2, 0xe0, 0xca, 0xbe, 0xc2, 0xd8, 0xd2, 0xce, 0xdc, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x88, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xd1, + 0xe0, 0xd1, 0x50, 0x81, 0x93, 0x7b, 0x53, 0x2b, 0x1b, 0xa3, 0x4b, 0x7b, + 0x73, 0x1b, 0x02, 0x06, 0x0a, 0x91, 0x90, 0x41, 0x52, 0x06, 0xca, 0x90, + 0x7c, 0x0a, 0xa1, 0x04, 0x89, 0x19, 0x24, 0x67, 0xa0, 0x0c, 0x09, 0x1a, + 0x28, 0x45, 0x02, 0x25, 0x69, 0x90, 0x48, 0x89, 0x1a, 0x30, 0xa1, 0x93, + 0x0b, 0x73, 0x9b, 0x33, 0x7b, 0x93, 0x6b, 0x1b, 0x02, 0x06, 0x8a, 0x91, + 0x90, 0x41, 0x52, 0x06, 0xca, 0x90, 0x7c, 0x8a, 0xa1, 0x04, 0x89, 0x19, + 0x24, 0x67, 0xa0, 0x0c, 0x09, 0x1a, 0x28, 0x45, 0x02, 0x25, 0x69, 0x90, + 0x48, 0x09, 0x1b, 0x0c, 0x41, 0x12, 0x31, 0x48, 0xc6, 0x20, 0x59, 0x83, + 0xa4, 0x0d, 0x86, 0x18, 0x08, 0x90, 0x74, 0x89, 0x1b, 0xf0, 0x79, 0x6b, 0x73, 0x4b, 0x83, 0x7b, 0xa3, 0x2b, 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, 0x93, 0xe3, 0x33, 0x95, 0xd6, 0x06, 0xc7, 0x56, 0x06, 0x32, 0xb4, 0xb2, - 0x02, 0x42, 0x25, 0x14, 0x14, 0x34, 0x44, 0x48, 0xda, 0x60, 0x88, 0x91, - 0xb0, 0x41, 0xe2, 0x06, 0x4c, 0x32, 0xc4, 0x48, 0xde, 0x20, 0x79, 0x03, + 0x02, 0x42, 0x25, 0x14, 0x14, 0x34, 0x44, 0x48, 0xe2, 0x60, 0x88, 0x91, + 0xc0, 0x41, 0x22, 0x07, 0x4c, 0x32, 0xc4, 0x48, 0xe6, 0x20, 0x99, 0x03, 0x26, 0x19, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, @@ -506,182 +270,435 @@ const unsigned char sdl_metallib[] = { 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x84, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf4, 0x50, - 0x0e, 0xf8, 0x30, 0x25, 0x58, 0x03, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, - 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, - 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, - 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, - 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, - 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, - 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, - 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, - 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, - 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, - 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, - 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, - 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, - 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, - 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, - 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, - 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, - 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, - 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, - 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, - 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, - 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, - 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, - 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, - 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, - 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, - 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, - 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, - 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, - 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, - 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, - 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, - 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, - 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, - 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, - 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, - 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, - 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, - 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, - 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, - 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, - 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x06, 0xf0, 0xb0, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x15, 0x11, 0x4d, - 0xc4, 0x05, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, - 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, - 0x22, 0x82, 0x20, 0x08, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, 0xb9, 0x11, - 0x00, 0x1a, 0x33, 0x00, 0x24, 0x66, 0x00, 0x28, 0xcc, 0x00, 0x00, 0x00, - 0xe3, 0x11, 0x0b, 0x74, 0x41, 0x14, 0x94, 0xf1, 0x08, 0x47, 0xca, 0x24, - 0x0a, 0xca, 0x20, 0xc3, 0x50, 0x20, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x90, - 0xac, 0xae, 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x09, 0x64, 0x42, 0x20, 0x1f, - 0x0b, 0x0a, 0xf8, 0x8c, 0x47, 0x5c, 0x9b, 0x18, 0x40, 0x14, 0x94, 0x41, - 0x06, 0xc6, 0xb1, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x08, - 0x0e, 0x0c, 0xce, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x13, 0x67, 0x42, - 0x20, 0x1f, 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x80, 0x41, 0x19, 0xb0, 0x01, - 0x47, 0x41, 0x19, 0x64, 0x08, 0xb0, 0xcd, 0x82, 0x4a, 0x3e, 0x83, 0x0c, - 0x83, 0x16, 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, - 0xd1, 0x95, 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, - 0x80, 0x41, 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, - 0x6d, 0x20, 0x07, 0x79, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xa0, 0x0c, - 0xd0, 0xc0, 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x70, 0x06, 0x6e, 0x60, - 0x01, 0x18, 0xc8, 0x67, 0x90, 0xa1, 0x48, 0x83, 0x38, 0xb0, 0xa0, 0x93, - 0xcf, 0x20, 0xc3, 0xb1, 0x06, 0x74, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x06, - 0x3d, 0x70, 0x03, 0x38, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x03, 0x1f, 0xc0, - 0x81, 0x1d, 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, - 0xb1, 0x20, 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, - 0x80, 0x07, 0x01, 0x30, 0xdb, 0x10, 0x8c, 0x42, 0x90, 0x41, 0x40, 0x0c, - 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0x80, 0x83, 0x2d, 0xc3, 0x10, - 0xc0, 0xc1, 0x96, 0xe1, 0x08, 0xe0, 0x60, 0xcb, 0xc0, 0x04, 0x70, 0xb0, - 0x65, 0x88, 0x02, 0x38, 0xd8, 0x32, 0x58, 0x01, 0x1c, 0x6c, 0x19, 0xc6, - 0x20, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0xf8, 0x30, 0x25, 0x78, 0x03, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x06, 0x00, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, + 0x45, 0x44, 0x13, 0x71, 0x01, 0x00, 0x61, 0x20, 0x00, 0x00, 0x54, 0x00, + 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, + 0x10, 0xc6, 0x22, 0x82, 0x20, 0x08, 0x46, 0x00, 0x88, 0x95, 0x40, 0x19, + 0x14, 0x01, 0x8d, 0x19, 0x00, 0x12, 0x33, 0x00, 0x14, 0x66, 0x00, 0x08, + 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x11, + 0x4c, 0x84, 0x45, 0x14, 0x94, 0xf1, 0x88, 0x67, 0xd2, 0x26, 0x0a, 0xca, + 0x20, 0xc3, 0x60, 0x30, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x98, 0x2e, 0xaf, + 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x4a, 0x64, 0x42, 0x20, 0x1f, 0x0b, 0x0a, + 0xf8, 0x8c, 0x47, 0x60, 0xdc, 0x18, 0x40, 0x14, 0x94, 0x41, 0x06, 0xe6, + 0xb9, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x88, 0x2e, 0x0c, + 0xd0, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x54, 0x67, 0x42, 0x20, 0x1f, + 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x84, 0x81, 0x19, 0xb4, 0x01, 0x47, 0x41, + 0x19, 0x64, 0x08, 0xb2, 0xcf, 0x82, 0x4a, 0x3e, 0x83, 0x0c, 0xc3, 0x26, + 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, 0xe1, 0x99, + 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, 0x84, 0x81, + 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, 0x6e, 0x30, + 0x07, 0x7a, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xc0, 0x0c, 0xd8, 0xc0, + 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x80, 0x06, 0x6f, 0x60, 0x01, 0x18, + 0xc8, 0x67, 0x90, 0xa1, 0x50, 0x03, 0x39, 0xb0, 0xa0, 0x93, 0xcf, 0x20, + 0xc3, 0xc1, 0x06, 0x75, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x86, 0x3d, 0x80, + 0x03, 0x3a, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, 0x1f, 0xc8, 0xc1, 0x1d, + 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, 0xb1, 0x20, + 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, 0x80, 0x07, + 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, 0x10, 0xe0, 0x81, 0x90, + 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, + 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, 0x96, 0xe1, 0x08, 0xe8, + 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, 0x02, 0x3a, 0xd8, 0x32, + 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x14, 0x09, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, - 0x21, 0x0c, 0x00, 0x00, 0x42, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, - 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, - 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, - 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, - 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, - 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x08, 0x11, 0x62, 0xa8, 0xa0, - 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, - 0x82, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, - 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, - 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, - 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, - 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, - 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, - 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, - 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, - 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, - 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, - 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, - 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, - 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, - 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, - 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, - 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, - 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, - 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, - 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, - 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, - 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, - 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, - 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, - 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, - 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, - 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, - 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, - 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, - 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, - 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, - 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, - 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, - 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, - 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xb0, 0x0b, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xe9, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, - 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, - 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, - 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x20, 0x42, 0x00, - 0x24, 0xc0, 0x02, 0x54, 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, - 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, - 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x28, 0x33, 0x00, - 0xc3, 0x08, 0x04, 0x30, 0x88, 0x10, 0x04, 0x45, 0x08, 0xa1, 0x19, 0x08, - 0x98, 0x23, 0x00, 0x83, 0x14, 0xb0, 0x39, 0x02, 0x50, 0x18, 0x01, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x02, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, - 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, 0x12, 0x18, 0x01, 0x28, - 0x90, 0x22, 0x28, 0x84, 0x82, 0x20, 0x1c, 0x01, 0xa0, 0x1b, 0x4b, 0x70, - 0x04, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, - 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, - 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, 0x41, 0x14, 0xc0, 0x81, 0x50, 0xb9, - 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x18, - 0x41, 0x21, 0x18, 0x05, 0xdd, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, - 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, - 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x06, 0x04, 0xa5, 0xad, - 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, - 0x85, 0x66, 0x26, 0x65, 0x88, 0x50, 0x10, 0x43, 0x0c, 0x23, 0x30, 0x0c, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x20, 0x02, 0x01, 0x24, 0xc0, 0x02, 0x54, 0x1b, 0x90, + 0xa1, 0x00, 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0x76, 0x08, 0x41, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, + 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, + 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, + 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x62, 0x0c, 0x11, 0x84, + 0x31, 0x74, 0x06, 0x02, 0xe6, 0x08, 0xc0, 0x20, 0x05, 0xd4, 0x1c, 0x01, + 0x28, 0x0c, 0x22, 0x04, 0xc2, 0x30, 0x02, 0xa1, 0x8c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x50, + 0x04, 0x23, 0x00, 0x05, 0x18, 0x50, 0x08, 0x65, 0x50, 0x20, 0x05, 0x41, + 0x6c, 0x04, 0x80, 0xd6, 0x58, 0x82, 0x33, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, + 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, + 0x22, 0x24, 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, + 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, 0x28, 0x05, 0xe1, 0x20, + 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, + 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, + 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, + 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, + 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, 0x50, 0x10, 0x65, 0x60, 0xd1, 0x54, + 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, 0x0e, 0x25, 0x50, 0x02, 0x65, 0xe0, + 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, + 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, + 0x26, 0xc6, 0x56, 0x36, 0x44, 0x48, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, + 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, + 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x43, 0x84, 0x64, 0x21, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, + 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, + 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, + 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x92, 0x86, 0x4c, 0x58, 0x9a, + 0x9c, 0x0b, 0xdc, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0x1b, 0xa3, 0xb0, + 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, + 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x64, + 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, + 0x88, 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, 0xb9, 0x0d, 0x51, 0x92, + 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, 0x58, 0x9a, 0x9c, 0x8b, + 0x5d, 0x99, 0x1c, 0x5d, 0x19, 0xde, 0xd7, 0x5b, 0x1d, 0x1d, 0x5c, 0x1d, + 0x1d, 0xad, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x94, + 0x9a, 0xb1, 0x37, 0xb6, 0x37, 0x39, 0x22, 0x3b, 0x9a, 0x2f, 0xb3, 0x14, + 0x16, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x98, 0xa4, 0x4a, 0xac, 0x04, + 0x4a, 0xa2, 0x44, 0x4a, 0x2e, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, + 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x34, 0xcc, 0xd8, 0xde, 0xc2, + 0xe8, 0x64, 0x88, 0xd0, 0x95, 0xe1, 0x8d, 0xbd, 0xbd, 0xc9, 0x91, 0x0d, + 0x61, 0x92, 0x2a, 0xc9, 0x12, 0x28, 0xd1, 0x12, 0x29, 0xd9, 0x86, 0x18, + 0x09, 0x95, 0x60, 0x09, 0x47, 0x28, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, + 0x8e, 0xae, 0x0c, 0xef, 0x2b, 0xcd, 0x0d, 0xae, 0x8e, 0x8e, 0x52, 0x58, + 0x9a, 0x9c, 0x0b, 0xdb, 0xdb, 0x58, 0x18, 0x5d, 0xda, 0x9b, 0xdb, 0x57, + 0x9a, 0x1b, 0x59, 0x19, 0x1e, 0xbd, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, + 0xba, 0x32, 0x32, 0x94, 0xaf, 0xaf, 0xb0, 0x34, 0xb9, 0x2f, 0x38, 0xb6, + 0xb0, 0xb1, 0x32, 0xb4, 0x37, 0x36, 0xb2, 0x32, 0xb9, 0xaf, 0xaf, 0x94, + 0x21, 0x94, 0x32, 0x24, 0x5e, 0xf2, 0x29, 0x83, 0x12, 0x24, 0x60, 0x90, + 0x40, 0x89, 0x96, 0x48, 0xc9, 0x34, 0x84, 0x52, 0x82, 0xc4, 0x4b, 0x3e, + 0x25, 0x50, 0x82, 0x04, 0x0c, 0x12, 0x28, 0x89, 0x12, 0x29, 0xb9, 0x86, + 0x50, 0x8a, 0x90, 0x78, 0xc9, 0xa7, 0x08, 0x4a, 0x90, 0x80, 0x41, 0x02, + 0x25, 0x5a, 0x22, 0x25, 0x1b, 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, + 0x33, 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, + 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x44, 0xc2, 0xd2, 0xe4, + 0x5c, 0xe4, 0xca, 0xc2, 0xc8, 0x18, 0x85, 0xa5, 0xc9, 0xb9, 0x84, 0xc9, + 0x9d, 0x7d, 0xd1, 0xe5, 0xc1, 0x95, 0x7d, 0xcd, 0xa5, 0xe9, 0x95, 0xf1, + 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, + 0xfb, 0x0a, 0x63, 0x4b, 0x3b, 0x73, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x23, + 0x62, 0xc6, 0xf6, 0x16, 0x46, 0x47, 0x83, 0x47, 0x43, 0x05, 0x4e, 0xee, + 0x4d, 0xad, 0x6c, 0x8c, 0x2e, 0xed, 0xcd, 0x6d, 0x08, 0x18, 0x28, 0x46, + 0x42, 0x06, 0x49, 0x19, 0x28, 0x44, 0xf2, 0x29, 0x82, 0x12, 0x24, 0x66, + 0x90, 0x9c, 0x81, 0x42, 0x24, 0x68, 0xa0, 0x1c, 0x09, 0x94, 0xa4, 0x41, + 0x22, 0x25, 0x6a, 0xc0, 0x84, 0x4e, 0x2e, 0xcc, 0x6d, 0xce, 0xec, 0x4d, + 0xae, 0x6d, 0x08, 0x18, 0x28, 0x45, 0x42, 0x06, 0x49, 0x19, 0x28, 0x44, + 0xf2, 0x29, 0x86, 0x12, 0x24, 0x66, 0x90, 0x9c, 0x81, 0x42, 0x24, 0x68, + 0xa0, 0x1c, 0x09, 0x94, 0xa4, 0x41, 0x22, 0x25, 0x6c, 0x30, 0x44, 0x49, + 0xc2, 0x20, 0x11, 0x83, 0x64, 0x0c, 0x92, 0x35, 0x48, 0xda, 0x60, 0x88, + 0x81, 0x00, 0x49, 0x97, 0xb8, 0x01, 0x9f, 0xb7, 0x36, 0xb7, 0x34, 0xb8, + 0x37, 0xba, 0x32, 0x37, 0x3a, 0x90, 0x31, 0xb4, 0x30, 0x39, 0x3e, 0x53, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, + 0x41, 0x41, 0x43, 0x84, 0x24, 0x0e, 0x86, 0x18, 0x09, 0x1c, 0x24, 0x72, + 0xc0, 0x24, 0x43, 0x8c, 0x64, 0x0e, 0x92, 0x39, 0x60, 0x92, 0x11, 0x11, + 0x3b, 0xb0, 0x83, 0x3d, 0xb4, 0x83, 0x1b, 0xb4, 0xc3, 0x3b, 0x90, 0x43, + 0x3d, 0xb0, 0x43, 0x39, 0xb8, 0x81, 0x39, 0xb0, 0x43, 0x38, 0x9c, 0xc3, + 0x3c, 0x4c, 0x11, 0x82, 0x61, 0x84, 0xc2, 0x0e, 0xec, 0x60, 0x0f, 0xed, + 0xe0, 0x06, 0xe9, 0x40, 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x28, + 0x46, 0x2c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xf6, 0x50, 0x0e, 0xf2, + 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x30, 0x46, 0x50, 0xe1, + 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xec, 0x10, 0x0e, 0xee, 0x70, 0x0e, 0xf5, + 0x10, 0x0e, 0xe7, 0x50, 0x0e, 0xbf, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, + 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x64, 0xc4, 0x14, 0x0e, 0xe9, + 0x20, 0x0f, 0x6e, 0x30, 0x0e, 0xef, 0xd0, 0x0e, 0xf0, 0x90, 0x0e, 0xec, + 0x50, 0x0e, 0xbf, 0xf0, 0x0e, 0xf0, 0x40, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, + 0x30, 0x0f, 0x53, 0x06, 0x85, 0x71, 0x46, 0x28, 0xe1, 0x90, 0x0e, 0xf2, + 0xe0, 0x06, 0xf6, 0x50, 0x0e, 0xf2, 0x40, 0x0f, 0xe5, 0x80, 0x0f, 0x53, + 0x82, 0x37, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, + 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, + 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, + 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, + 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, + 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, + 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, + 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, + 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, + 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, + 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, + 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, + 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, + 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, + 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, + 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, + 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, + 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, + 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, + 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, + 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, + 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, + 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, + 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, + 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, + 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, + 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, + 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, + 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, + 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, + 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, + 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, + 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, + 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, + 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, + 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, + 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, + 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, + 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0xf0, + 0xb0, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x15, 0x11, 0x4d, 0xc4, 0x05, + 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x13, 0x04, + 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xe4, 0xc6, + 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, 0x22, 0x82, + 0x20, 0x08, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, 0xb9, 0x11, 0x00, 0x1a, + 0x33, 0x00, 0x24, 0x66, 0x00, 0x28, 0xcc, 0x00, 0x00, 0x00, 0xe3, 0x11, + 0x4b, 0x74, 0x45, 0x14, 0x94, 0xf1, 0x08, 0x67, 0xca, 0x26, 0x0a, 0xca, + 0x20, 0xc3, 0x50, 0x20, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x90, 0xae, 0xae, + 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x09, 0x64, 0x42, 0x20, 0x1f, 0x0b, 0x0a, + 0xf8, 0x8c, 0x47, 0x5c, 0x9c, 0x18, 0x40, 0x14, 0x94, 0x41, 0x06, 0xc6, + 0xb1, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x08, 0x2e, 0x0c, + 0xce, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x13, 0x67, 0x42, 0x20, 0x1f, + 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x80, 0x81, 0x19, 0xb0, 0x01, 0x47, 0x41, + 0x19, 0x64, 0x08, 0xb0, 0xcd, 0x82, 0x4a, 0x3e, 0x83, 0x0c, 0x83, 0x16, + 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, 0xd1, 0x95, + 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, 0x80, 0x41, + 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, 0x6d, 0x30, + 0x07, 0x79, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xa0, 0x0c, 0xd0, 0xc0, + 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x70, 0x06, 0x6e, 0x60, 0x01, 0x18, + 0xc8, 0x67, 0x90, 0xa1, 0x48, 0x83, 0x38, 0xb0, 0xa0, 0x93, 0xcf, 0x20, + 0xc3, 0xb1, 0x06, 0x74, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x86, 0x3d, 0x70, + 0x03, 0x38, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, 0x1f, 0xc0, 0x81, 0x1d, + 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, 0xb1, 0x20, + 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, 0x80, 0x07, + 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, 0x10, 0x90, 0x82, 0x90, + 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, + 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, 0x96, 0xe1, 0x08, 0xe8, + 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, 0x02, 0x3a, 0xd8, 0x32, + 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x35, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x08, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x00, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x10, 0x82, 0x00, 0x58, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x24, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x65, 0x08, 0x09, + 0x9a, 0x81, 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x1b, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x0c, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, 0x12, 0x18, + 0x01, 0x28, 0x82, 0x42, 0x28, 0x08, 0xba, 0xb1, 0x04, 0x67, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x31, 0x14, 0xc0, 0x61, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x18, 0x41, 0x21, + 0x18, 0x04, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x50, 0x10, 0x43, 0x0c, 0x23, 0x30, 0x0a, 0x43, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x29, 0x0e, 0x23, 0x30, 0x02, 0x43, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, @@ -696,254 +713,1030 @@ const unsigned char sdl_metallib[] = { 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe2, 0x31, - 0x84, 0x02, 0x2a, 0xa2, 0x21, 0x42, 0x21, 0x51, 0x09, 0x4b, 0x93, 0x73, - 0x11, 0xab, 0x33, 0x33, 0x2b, 0x93, 0xe3, 0x13, 0x96, 0x26, 0xe7, 0x22, - 0x56, 0x67, 0x66, 0x56, 0x26, 0xf7, 0x35, 0x97, 0xa6, 0x57, 0x46, 0x29, - 0x2c, 0x4d, 0xce, 0x85, 0xed, 0x6d, 0x2c, 0x8c, 0x2e, 0xed, 0xcd, 0xed, - 0x2b, 0xcd, 0x8d, 0xac, 0x0c, 0x8f, 0x48, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, - 0x59, 0x18, 0x19, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, - 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, - 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, - 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x64, 0xc2, 0xd2, - 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, 0x38, 0x8c, - 0xbd, 0xb1, 0x0d, 0x01, 0x03, 0x43, 0x28, 0xa8, 0xa2, 0x32, 0x86, 0xc2, - 0x32, 0x04, 0x23, 0x28, 0xae, 0x02, 0x33, 0x86, 0x22, 0x33, 0x86, 0x02, - 0x2a, 0xa2, 0x42, 0x2b, 0xb6, 0x21, 0x42, 0xc1, 0x0d, 0x31, 0x08, 0xa0, - 0x98, 0x8a, 0x8e, 0xcf, 0x5b, 0x9b, 0x5b, 0x1a, 0xdc, 0x1b, 0x5d, 0x99, - 0x1b, 0x1d, 0xc8, 0x18, 0x5a, 0x98, 0x1c, 0x9f, 0xa9, 0xb4, 0x36, 0x38, - 0xb6, 0x32, 0x90, 0xa1, 0x95, 0x15, 0x10, 0x2a, 0xa1, 0xa0, 0xa0, 0x21, - 0x42, 0x01, 0x06, 0x43, 0x8c, 0xe2, 0x2b, 0xc2, 0x00, 0x39, 0x86, 0x18, - 0x85, 0x18, 0x14, 0x62, 0x80, 0x1c, 0x23, 0x22, 0x76, 0x60, 0x07, 0x7b, - 0x68, 0x07, 0x37, 0x68, 0x87, 0x77, 0x20, 0x87, 0x7a, 0x60, 0x87, 0x72, - 0x70, 0x03, 0x73, 0x60, 0x87, 0x70, 0x38, 0x87, 0x79, 0x98, 0x22, 0x04, - 0xc3, 0x08, 0x85, 0x1d, 0xd8, 0xc1, 0x1e, 0xda, 0xc1, 0x0d, 0xd2, 0x81, - 0x1c, 0xca, 0xc1, 0x1d, 0xe8, 0x61, 0x4a, 0x50, 0x8c, 0x58, 0xc2, 0x21, - 0x1d, 0xe4, 0xc1, 0x0d, 0xec, 0xa1, 0x1c, 0xe4, 0x61, 0x1e, 0xd2, 0xe1, - 0x1d, 0xdc, 0x61, 0x4a, 0x60, 0x8c, 0xa0, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, - 0x0d, 0xd8, 0x21, 0x1c, 0xdc, 0xe1, 0x1c, 0xea, 0x21, 0x1c, 0xce, 0xa1, - 0x1c, 0x7e, 0xc1, 0x1e, 0xca, 0x41, 0x1e, 0xe6, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0xa6, 0x04, 0xc8, 0x88, 0x29, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0x60, - 0x1c, 0xde, 0xa1, 0x1d, 0xe0, 0x21, 0x1d, 0xd8, 0xa1, 0x1c, 0x7e, 0xe1, - 0x1d, 0xe0, 0x81, 0x1e, 0xd2, 0xe1, 0x1d, 0xdc, 0x61, 0x1e, 0xa6, 0x0c, - 0x0a, 0xe3, 0x8c, 0x60, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, 0xcc, 0x41, - 0x1e, 0xc2, 0xe1, 0x1c, 0xda, 0xa1, 0x1c, 0xdc, 0x81, 0x1e, 0xa6, 0x04, - 0x1e, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, - 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, - 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, - 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, - 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, - 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, - 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, - 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, - 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, - 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, - 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, - 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, - 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, - 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, - 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, - 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, - 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, - 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, - 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, - 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, - 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, - 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, - 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, - 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, - 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, - 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, - 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, - 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, - 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, - 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, - 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, - 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, - 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, - 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, - 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, - 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, - 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, - 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, - 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, - 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, - 0x71, 0x20, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x20, 0xb1, 0x5d, - 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, 0x11, 0x01, 0x06, 0x43, 0x34, 0x13, - 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x13, 0x04, 0x01, 0x05, 0x25, 0x83, 0x80, 0x18, 0x02, 0x00, 0x00, 0x00, - 0x5b, 0x06, 0x20, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x02, 0x2a, 0xa2, 0x21, 0x42, 0x21, 0x51, 0x0a, 0x4b, 0x93, 0x73, + 0x31, 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, 0xa3, 0xfb, 0x4a, 0x73, 0x83, + 0xab, 0xa3, 0x63, 0x76, 0x56, 0xe6, 0x56, 0x26, 0x17, 0x46, 0x57, 0x46, + 0x86, 0x82, 0x03, 0xf7, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x46, 0x64, + 0x27, 0xf3, 0x65, 0x96, 0x42, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0xac, 0xcc, + 0x8d, 0xae, 0x4c, 0x8e, 0x4f, 0x58, 0x9a, 0x9c, 0x0b, 0x5c, 0x99, 0xdc, + 0x1c, 0x5c, 0xd9, 0x18, 0x5d, 0x9a, 0x5d, 0x19, 0x0d, 0x33, 0xb6, 0xb7, + 0x30, 0x3a, 0x19, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x44, 0xe0, 0xde, 0xe6, 0xd2, 0xe8, 0xd2, 0xde, + 0xdc, 0x86, 0x48, 0x86, 0x50, 0x50, 0x45, 0x55, 0x58, 0xc5, 0x55, 0x40, + 0x05, 0x56, 0x64, 0x85, 0x46, 0xeb, 0xac, 0xcc, 0xad, 0x4c, 0x2e, 0x8c, + 0xae, 0x8c, 0x0c, 0xa5, 0x66, 0xec, 0x8d, 0xed, 0x4d, 0x8e, 0xc8, 0x8e, + 0xe6, 0xcb, 0x2c, 0x85, 0xc5, 0xd8, 0x1b, 0xdb, 0x9b, 0xdc, 0x10, 0xc9, + 0x08, 0x0a, 0xaa, 0xe0, 0x0a, 0xab, 0xb8, 0x0a, 0xa8, 0x88, 0x8a, 0xac, + 0xe8, 0x86, 0x10, 0xc5, 0x56, 0x78, 0x43, 0x0c, 0x02, 0x28, 0xa6, 0xe2, + 0x1b, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, + 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, + 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, + 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, + 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, + 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, + 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, + 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, + 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, + 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, + 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, + 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, 0x0e, + 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, 0x0e, + 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x03, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x06, 0x20, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, + 0x11, 0x01, 0x06, 0x43, 0x34, 0x13, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xe4, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, - 0x21, 0x0c, 0x00, 0x00, 0xb6, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, - 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, - 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, - 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, - 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, - 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, - 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, - 0x8b, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, - 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, - 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, - 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, - 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, - 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, - 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, - 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, - 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, - 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, - 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, - 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, - 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, - 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, - 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, - 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, - 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, - 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, - 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, - 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, - 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, - 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, - 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, - 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, - 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, - 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, - 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, - 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, - 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, - 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, - 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, - 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, - 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, - 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x44, 0x0a, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x8e, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x1b, 0xcc, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, + 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, + 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, + 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, + 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, + 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, + 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, + 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, + 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, + 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, + 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, + 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, + 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, + 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, - 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, - 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, - 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, - 0x0c, 0x40, 0x02, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x08, 0x60, 0x01, 0xaa, - 0x0d, 0x06, 0x51, 0x00, 0x0b, 0x50, 0x6d, 0x40, 0x8a, 0xff, 0xff, 0xff, - 0xff, 0x1f, 0x00, 0x06, 0x90, 0x80, 0x6a, 0x83, 0x61, 0x04, 0xc0, 0x02, - 0x54, 0x1b, 0x8c, 0x43, 0x00, 0x16, 0xa0, 0x02, 0x49, 0x18, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, 0x88, 0x09, 0x43, 0x61, - 0x1c, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, - 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, - 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, - 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x4c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, - 0x8c, 0x20, 0x00, 0x83, 0x08, 0x41, 0x70, 0x94, 0x34, 0x45, 0x94, 0x30, - 0xf9, 0xff, 0x44, 0x5c, 0x13, 0x15, 0x11, 0xbf, 0x3d, 0xfc, 0xd3, 0x18, - 0x01, 0x30, 0x88, 0x40, 0x04, 0x17, 0x49, 0x53, 0x44, 0x09, 0x93, 0xff, - 0x4b, 0x00, 0xf3, 0x2c, 0x44, 0xf4, 0x4f, 0x63, 0x04, 0xc0, 0x20, 0x82, - 0x21, 0x14, 0x23, 0x04, 0x31, 0xca, 0x21, 0x34, 0x47, 0x10, 0xcc, 0x11, - 0x80, 0xc1, 0x30, 0x82, 0xb0, 0x14, 0x24, 0x94, 0x23, 0x14, 0x53, 0x80, - 0xda, 0x40, 0x40, 0x0a, 0xac, 0x39, 0x02, 0x50, 0x18, 0x01, 0x00, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x98, 0x04, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x8c, 0x03, 0x04, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, - 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x25, 0x30, 0x02, 0x50, - 0x20, 0x45, 0x50, 0x08, 0x05, 0x51, 0x06, 0x14, 0x47, 0x00, 0x08, 0x8e, - 0x25, 0x38, 0x02, 0x00, 0x79, 0x18, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, - 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, - 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0xc6, 0x52, 0x3c, 0x00, 0xa4, 0x50, 0xb9, - 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x2c, - 0xc2, 0x23, 0x2c, 0x06, 0xdd, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, - 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, - 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x06, 0x04, 0xa5, 0xad, - 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, - 0x85, 0x66, 0x26, 0x65, 0x88, 0xf0, 0x10, 0x43, 0x8c, 0x45, 0x58, 0x8e, - 0x65, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x79, 0x8e, 0x45, - 0x58, 0x84, 0x65, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, + 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, + 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, + 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, + 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, + 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, + 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, + 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, + 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, + 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, + 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, + 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, + 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x60, 0x83, 0x21, 0x10, 0xc0, 0x02, 0x54, 0x1b, 0x8c, + 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x80, 0x10, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x00, 0x0c, 0x20, 0x01, 0xd5, 0x06, 0xa3, 0x08, 0x80, 0x05, 0xa8, 0x36, + 0x18, 0x86, 0x00, 0x2c, 0x40, 0x05, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x26, 0x0c, 0x44, 0x61, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x44, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0x47, 0x49, 0x53, 0x44, 0x09, 0x93, 0xff, 0x4f, 0xc4, 0x35, 0x51, + 0x11, 0xf1, 0xdb, 0xc3, 0x3f, 0x8d, 0x11, 0x00, 0x83, 0x08, 0x43, 0x70, + 0x91, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xbf, 0x04, 0x30, 0xcf, 0x42, 0x44, + 0xff, 0x34, 0x46, 0x00, 0x0c, 0x22, 0x14, 0x42, 0x31, 0x42, 0x08, 0x82, + 0x18, 0x3a, 0x73, 0x04, 0xc1, 0x1c, 0x01, 0x18, 0x0c, 0x23, 0x08, 0x4a, + 0x41, 0x02, 0x31, 0x22, 0xad, 0x04, 0x88, 0x0d, 0x04, 0xa4, 0x80, 0x1a, + 0x01, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4c, + 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, + 0x02, 0x50, 0x04, 0x85, 0x50, 0x10, 0x65, 0x40, 0x6f, 0x2c, 0xc1, 0x19, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x42, 0x38, 0xc0, 0x83, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x82, 0x23, + 0x28, 0x05, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0xe0, 0x10, 0x43, 0x0c, 0x45, 0x50, 0x0c, + 0x65, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x71, 0x0e, 0x45, + 0x50, 0x04, 0x65, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, - 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x78, 0x12, 0x72, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x70, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x67, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, 0x67, 0x21, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, - 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x9e, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x9c, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, - 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe7, 0x59, - 0x86, 0x07, 0x7a, 0xa2, 0x21, 0xc2, 0x23, 0x91, 0x09, 0x4b, 0x93, 0x73, + 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x10, 0xe7, 0x51, + 0x06, 0x07, 0x72, 0xa2, 0x21, 0x82, 0x23, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, - 0xb7, 0x21, 0xd0, 0x32, 0x3c, 0xd4, 0x53, 0x3d, 0xd6, 0x03, 0x3d, 0xd1, - 0x73, 0x3d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, - 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x66, 0x67, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, - 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, - 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, - 0xe8, 0xd2, 0xec, 0xca, 0x68, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xc9, 0x10, - 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, 0x7b, 0x93, 0x23, 0x1b, 0x22, 0x2d, 0xc2, - 0xa3, 0x3d, 0xdb, 0x53, 0x3d, 0xdc, 0x03, 0x3d, 0xdd, 0x73, 0x3d, 0x1e, - 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, 0xb3, 0x32, 0x39, 0x3e, - 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x94, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, - 0xe8, 0xd2, 0xde, 0xdc, 0xbe, 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0x88, 0x84, - 0xa5, 0xc9, 0xb9, 0xc8, 0x95, 0x85, 0x91, 0x31, 0x0a, 0x4b, 0x93, 0x73, - 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0xe3, 0x15, 0x96, 0x26, 0xe7, 0x12, 0x26, 0x77, 0xf6, 0x45, 0x97, - 0x07, 0x57, 0xf6, 0x15, 0xc6, 0x96, 0x76, 0xe6, 0xf6, 0x35, 0x97, 0xa6, - 0x57, 0xc6, 0x61, 0xec, 0x8d, 0x6d, 0x08, 0x18, 0x2c, 0xc5, 0x03, 0x06, - 0x4f, 0x18, 0x2c, 0xc4, 0x23, 0x06, 0xcb, 0xb0, 0x08, 0xcf, 0x18, 0x3c, - 0x64, 0xb0, 0x10, 0x4f, 0x19, 0x2c, 0xc4, 0x03, 0x3d, 0xd1, 0x73, 0x3d, - 0x66, 0xc0, 0x25, 0x2c, 0x4d, 0xce, 0x85, 0xae, 0x0c, 0x8f, 0xae, 0x4e, - 0xae, 0x8c, 0x4a, 0x58, 0x9a, 0x9c, 0xcb, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, - 0x19, 0x31, 0xba, 0x32, 0x3c, 0xba, 0x3a, 0xb9, 0x32, 0x19, 0x32, 0x1e, - 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x16, 0x90, 0xb9, 0xb0, 0x36, 0x38, 0xb6, - 0x32, 0x1f, 0x0e, 0x74, 0x65, 0x78, 0x43, 0xa8, 0x05, 0x79, 0xd0, 0xe0, - 0x11, 0x83, 0x65, 0x58, 0x84, 0x27, 0x0d, 0x1e, 0xe8, 0x51, 0x83, 0xe7, - 0x7a, 0xd6, 0x80, 0x4b, 0x58, 0x9a, 0x9c, 0xcb, 0x5c, 0x58, 0x1b, 0x1c, - 0x5b, 0x99, 0x1c, 0x8f, 0xb9, 0xb0, 0x36, 0x38, 0xb6, 0x32, 0x39, 0x06, - 0x73, 0x43, 0xa4, 0xc5, 0x78, 0xda, 0xe0, 0x11, 0x83, 0x65, 0x58, 0x84, - 0x07, 0x7a, 0xdc, 0xe0, 0xb9, 0x9e, 0x37, 0x18, 0xa2, 0x3c, 0xd9, 0xf3, - 0x3d, 0x67, 0xf0, 0xb0, 0xc1, 0x03, 0x07, 0x43, 0x8c, 0x04, 0x78, 0xa6, - 0x27, 0x0e, 0xf8, 0xbc, 0xb5, 0xb9, 0xa5, 0xc1, 0xbd, 0xd1, 0x95, 0xb9, - 0xd1, 0x81, 0x8c, 0xa1, 0x85, 0xc9, 0xf1, 0x99, 0x4a, 0x6b, 0x83, 0x63, - 0x2b, 0x03, 0x19, 0x5a, 0x59, 0x01, 0xa1, 0x12, 0x0a, 0x0a, 0x1a, 0x22, - 0x3c, 0x74, 0x30, 0xc4, 0x78, 0xe6, 0xe0, 0xa9, 0x83, 0x28, 0x19, 0x62, - 0x3c, 0x76, 0xf0, 0xd8, 0x41, 0x94, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, + 0xb7, 0x21, 0x90, 0x32, 0x38, 0x94, 0x53, 0x39, 0x96, 0x03, 0x39, 0x91, + 0x73, 0x39, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, + 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, + 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x14, 0xc1, 0xd1, + 0x9c, 0xcd, 0xa9, 0x1c, 0xce, 0x81, 0x9c, 0xc8, 0xb9, 0x9c, 0x8e, 0xd9, + 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, + 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, + 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, + 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0x24, 0x85, 0x70, 0x34, 0xe7, 0x73, + 0x2a, 0x87, 0x73, 0x20, 0x07, 0x0c, 0x9c, 0xcb, 0x09, 0x03, 0x2e, 0x61, + 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x94, 0xc2, + 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, + 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0xa8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, + 0xb5, 0xc1, 0xb1, 0x95, 0x11, 0xa3, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, + 0x93, 0x21, 0xe3, 0x31, 0x63, 0x7b, 0x0b, 0xa3, 0x63, 0x01, 0x99, 0x0b, + 0x6b, 0x83, 0x63, 0x2b, 0xf3, 0xe1, 0x40, 0x57, 0x86, 0x37, 0x84, 0x52, + 0x0e, 0x67, 0x0c, 0x1c, 0x32, 0x50, 0x06, 0x45, 0x70, 0xca, 0xc0, 0x81, + 0x1c, 0x33, 0x70, 0x2e, 0xe7, 0x0c, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, + 0x85, 0xb5, 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, 0x63, + 0x2b, 0x93, 0x63, 0x30, 0x37, 0x44, 0x52, 0x0a, 0x27, 0x0d, 0x1c, 0x32, + 0x50, 0x06, 0x45, 0x70, 0x20, 0x47, 0x0d, 0x9c, 0xcb, 0x59, 0x83, 0x21, + 0x8a, 0x93, 0x39, 0x9e, 0x23, 0x06, 0x0e, 0x1a, 0x38, 0x6c, 0x30, 0xc4, + 0x40, 0x00, 0x67, 0x72, 0xda, 0x60, 0x44, 0xc4, 0x0e, 0xec, 0x60, 0x0f, + 0xed, 0xe0, 0x06, 0xed, 0xf0, 0x0e, 0xe4, 0x50, 0x0f, 0xec, 0x50, 0x0e, + 0x6e, 0x60, 0x0e, 0xec, 0x10, 0x0e, 0xe7, 0x30, 0x0f, 0x53, 0x84, 0x60, + 0x18, 0xa1, 0xb0, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3a, 0x90, + 0x43, 0x39, 0xb8, 0x03, 0x3d, 0x4c, 0x09, 0x8a, 0x11, 0x4b, 0x38, 0xa4, + 0x83, 0x3c, 0xb8, 0x81, 0x3d, 0x94, 0x83, 0x3c, 0xcc, 0x43, 0x3a, 0xbc, + 0x83, 0x3b, 0x4c, 0x09, 0x8c, 0x11, 0x54, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x01, 0x3b, 0x84, 0x83, 0x3b, 0x9c, 0x43, 0x3d, 0x84, 0xc3, 0x39, 0x94, + 0xc3, 0x2f, 0xd8, 0x43, 0x39, 0xc8, 0xc3, 0x3c, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x94, 0x00, 0x19, 0x31, 0x85, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0x8c, + 0xc3, 0x3b, 0xb4, 0x03, 0x3c, 0xa4, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x03, 0x3c, 0xd0, 0x43, 0x3a, 0xbc, 0x83, 0x3b, 0xcc, 0xc3, 0x94, 0x41, + 0x61, 0x9c, 0x11, 0x4c, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xc8, + 0x43, 0x38, 0x9c, 0x43, 0x3b, 0x94, 0x83, 0x3b, 0xd0, 0xc3, 0x94, 0xc0, + 0x0d, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x10, 0xb1, 0x5d, 0xf9, 0x73, + 0xce, 0x83, 0xfd, 0x45, 0x04, 0x18, 0x0c, 0xd1, 0x4c, 0x16, 0xb0, 0x01, + 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, + 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x0d, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb4, 0x46, 0x00, 0x28, 0xd5, 0xc0, + 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8a, 0x10, 0x44, 0x46, + 0x71, 0x0c, 0x84, 0x10, 0x58, 0x90, 0xc8, 0x27, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xc8, 0x0c, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0x2f, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x8e, 0x00, + 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, + 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, + 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, + 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, + 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, + 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, + 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, + 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, + 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, + 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, + 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, + 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, + 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, + 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, + 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, + 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, + 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, + 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, + 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, + 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, + 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, + 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, + 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, + 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, + 0x02, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x71, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x8a, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0x00, 0x09, 0xa0, 0x36, 0x20, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, + 0x03, 0x48, 0x40, 0xb5, 0xc1, 0x38, 0x02, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x22, 0x00, 0x0b, 0x50, 0x01, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, 0x88, 0x09, 0x41, 0x31, 0x61, 0x30, + 0x0e, 0x04, 0x89, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, + 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, + 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, + 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, + 0x34, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, 0x26, 0x2a, 0x22, + 0x7e, 0x7b, 0xf8, 0x81, 0x28, 0x02, 0xb0, 0x7f, 0x1a, 0x23, 0x00, 0x06, + 0x11, 0x90, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, + 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x50, 0x84, 0x82, + 0x84, 0x10, 0x44, 0x39, 0x69, 0x11, 0x2b, 0x03, 0x18, 0x83, 0xdc, 0x1c, + 0x01, 0x18, 0xcc, 0x11, 0x04, 0xc3, 0x08, 0x02, 0x54, 0x92, 0x90, 0x96, + 0x80, 0x51, 0x46, 0x40, 0xb3, 0x20, 0xe1, 0x2c, 0x11, 0x65, 0x04, 0x54, + 0x07, 0x02, 0x52, 0x00, 0x0e, 0x23, 0x0c, 0xd0, 0x20, 0x42, 0x20, 0xcc, + 0x11, 0x80, 0xc2, 0x20, 0xc2, 0x20, 0x8c, 0x00, 0x00, 0x00, 0x13, 0xa8, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, + 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, + 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, + 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, + 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, + 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, + 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x98, 0x06, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xcc, 0x03, 0x04, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x86, 0x02, 0x02, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x08, 0x63, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x90, 0x05, 0x02, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, + 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x78, 0x2c, + 0xc1, 0x19, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x13, 0x01, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x74, 0x5c, 0x00, 0x06, + 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x40, 0xc4, 0x25, 0x40, 0x08, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, + 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, + 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x70, 0x11, 0x43, + 0x0c, 0x88, 0x80, 0x14, 0xa8, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, + 0x04, 0xb9, 0x0e, 0x88, 0x80, 0x08, 0xa8, 0xe0, 0x16, 0x96, 0x26, 0xe7, + 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, + 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, + 0x44, 0xb8, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, + 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x6b, 0x21, + 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, + 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, + 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, + 0x95, 0x0d, 0x11, 0xae, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, + 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, + 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, + 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, + 0x43, 0x90, 0xeb, 0x81, 0x8a, 0x0b, 0xba, 0xa2, 0x21, 0xc2, 0x25, 0x91, + 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, + 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, + 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, + 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, + 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, + 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x54, 0x5c, 0xd4, 0x55, 0x5d, + 0xd6, 0x05, 0x5d, 0xd1, 0x75, 0x5d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, + 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, + 0x3a, 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, + 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, + 0x91, 0x20, 0xe2, 0xd2, 0xae, 0xed, 0xaa, 0x2e, 0xee, 0x82, 0xae, 0xe8, + 0xba, 0xae, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, + 0x19, 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, + 0x9d, 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, + 0x22, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0x24, 0xe8, + 0xb8, 0xb4, 0xeb, 0xbb, 0xaa, 0x8b, 0xbb, 0xa0, 0x0b, 0x0c, 0xae, 0xeb, + 0x0a, 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, + 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, + 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, + 0x26, 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, + 0x57, 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, + 0x6e, 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, + 0xb7, 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, + 0x84, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0x01, 0x54, 0x40, 0x06, + 0x54, 0x5c, 0x68, 0x70, 0xa5, 0x01, 0x64, 0x40, 0x06, 0x54, 0x5c, 0x68, + 0x70, 0xa9, 0x01, 0xc4, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xad, 0x01, + 0xd4, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xb1, 0x01, 0xa3, 0xb0, 0x34, + 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, + 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, + 0xca, 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x03, 0x68, + 0xb9, 0xc6, 0xe0, 0x22, 0x03, 0x28, 0xb9, 0xca, 0x00, 0x22, 0x20, 0xe2, + 0x32, 0x83, 0xeb, 0x0c, 0xae, 0x36, 0xb8, 0xdc, 0x00, 0x4a, 0xae, 0x37, + 0x80, 0x8c, 0x0b, 0xba, 0xe0, 0xe0, 0xba, 0xae, 0x38, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, + 0x4d, 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, + 0x1e, 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, + 0x1d, 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, + 0x32, 0xbc, 0xac, 0x21, 0x14, 0x84, 0x5c, 0x73, 0x70, 0x95, 0x01, 0x54, + 0x40, 0xc4, 0x45, 0x07, 0x17, 0x74, 0xd5, 0xc1, 0x75, 0x5d, 0x76, 0x40, + 0x8f, 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0xec, 0x2b, 0x4c, + 0x4e, 0x2e, 0x2c, 0x8f, 0xc7, 0x8c, 0xed, 0x2d, 0x8c, 0x8e, 0x05, 0x64, + 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, 0x05, 0x5d, 0x19, 0x5e, 0x95, + 0xd5, 0x10, 0x0a, 0x72, 0xae, 0x39, 0xb8, 0xca, 0x00, 0x22, 0x20, 0xe2, + 0xa2, 0x83, 0x0b, 0xba, 0xf0, 0xe0, 0xba, 0xae, 0x3c, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x63, 0x2e, + 0xac, 0x0d, 0x8e, 0xad, 0x4c, 0x8e, 0xc1, 0xdc, 0x10, 0x09, 0x7a, 0xae, + 0x3d, 0xb8, 0xca, 0x00, 0x2a, 0x20, 0xe2, 0x82, 0x2e, 0x3e, 0xb8, 0xae, + 0xab, 0x0f, 0x86, 0x38, 0x57, 0x76, 0x79, 0x97, 0x18, 0x5c, 0x72, 0x70, + 0xdd, 0xc1, 0xa5, 0x07, 0x97, 0x1f, 0x0c, 0x31, 0x1a, 0xe0, 0x9a, 0xae, + 0x3f, 0x18, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, + 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, + 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, + 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, + 0x0f, 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, + 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, + 0x63, 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, + 0x0e, 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, + 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, + 0x4c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, + 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, + 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, + 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, + 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x05, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x26, 0x10, 0x06, 0x00, 0x12, 0xf9, 0x12, 0xc0, 0x3c, 0x0b, + 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0xc3, 0x0f, 0x44, 0x11, + 0x80, 0xf9, 0x15, 0x5e, 0xdc, 0xb6, 0x05, 0x34, 0x00, 0x12, 0xf9, 0x83, + 0x33, 0xf9, 0xd5, 0x5d, 0xdc, 0xb6, 0x0d, 0x6c, 0x00, 0x12, 0xf9, 0x12, + 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0x83, + 0x5f, 0xe1, 0xc5, 0x6d, 0x1b, 0x00, 0xc4, 0x76, 0xe5, 0x2f, 0xbb, 0xef, + 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xb4, 0x47, 0x00, 0x28, 0xcf, 0x31, + 0x14, 0x5d, 0x37, 0xd6, 0x00, 0x04, 0x02, 0xc9, 0x11, 0x00, 0x8a, 0x23, + 0x00, 0x04, 0x67, 0x00, 0x28, 0xd6, 0x00, 0x85, 0x39, 0x08, 0x31, 0x10, + 0x03, 0x31, 0x08, 0x83, 0x19, 0x00, 0x02, 0x63, 0x04, 0x20, 0x08, 0x82, + 0xf8, 0x37, 0x03, 0x30, 0x02, 0x00, 0x23, 0x06, 0xca, 0x10, 0x84, 0xc1, + 0xd3, 0x44, 0x46, 0x82, 0x04, 0x83, 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x2c, + 0x43, 0x40, 0x06, 0xd0, 0x33, 0x85, 0x01, 0xb2, 0x28, 0xc3, 0x18, 0x42, + 0x20, 0x06, 0x73, 0x0c, 0x43, 0x40, 0x06, 0x23, 0x06, 0xcb, 0x10, 0x9c, + 0xc1, 0x24, 0x59, 0x65, 0xb0, 0x38, 0x8d, 0x31, 0x86, 0x10, 0x94, 0xc1, + 0x1c, 0xc3, 0x10, 0x90, 0xc1, 0x61, 0x7a, 0x29, 0x28, 0x83, 0x0c, 0x81, + 0x43, 0x19, 0x11, 0xc0, 0x67, 0xbc, 0x81, 0xc3, 0xd8, 0xe0, 0x02, 0xbd, + 0x14, 0x94, 0x41, 0x86, 0x60, 0xca, 0x46, 0x0c, 0x0a, 0x21, 0x98, 0x83, + 0x22, 0x18, 0x6f, 0x08, 0x83, 0xce, 0x0d, 0x2e, 0xd0, 0x4b, 0x41, 0x19, + 0x64, 0x08, 0x30, 0x6f, 0xc4, 0xa0, 0x10, 0x02, 0x3c, 0x50, 0x82, 0xf1, + 0x06, 0x33, 0x10, 0x83, 0x37, 0xb8, 0x40, 0x2f, 0x05, 0x65, 0x90, 0x21, + 0xe8, 0xc6, 0x60, 0xc4, 0xa0, 0x10, 0x82, 0x3e, 0x78, 0x82, 0x39, 0x06, + 0x30, 0x58, 0xf4, 0x60, 0x8e, 0x21, 0x38, 0xf8, 0x60, 0x8e, 0x21, 0x18, + 0xf4, 0xc0, 0x02, 0x38, 0x90, 0x4f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x5c, 0x0c, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x14, 0x03, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x1b, 0xcc, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, + 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, + 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, + 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, + 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, + 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, + 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, + 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, + 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, + 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, + 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, + 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, + 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, + 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, + 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, + 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, + 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, + 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, + 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, + 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, + 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, + 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, + 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, + 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, + 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, + 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, 0x02, 0x2c, 0x40, 0xb5, + 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, 0x61, 0x00, 0x0b, 0x50, + 0x6d, 0x30, 0x8a, 0x03, 0x58, 0x80, 0x6a, 0x83, 0x61, 0xfc, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x48, 0x00, 0xb5, 0x01, 0x39, 0xfe, 0xff, 0xff, 0xff, + 0x7f, 0x00, 0x18, 0x40, 0x02, 0xaa, 0x0d, 0x06, 0x12, 0x00, 0x0b, 0x50, + 0x6d, 0x30, 0x12, 0x01, 0x58, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, + 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x68, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, + 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, + 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, + 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, + 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, + 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, + 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, + 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, 0x00, 0x06, 0xc3, 0x08, + 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, 0x8a, 0x03, 0x01, 0x29, + 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, 0xe6, 0x08, 0x40, 0x61, + 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, + 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, + 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, + 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, + 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, + 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, + 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, + 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, + 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, + 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, + 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, + 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, + 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x43, 0x98, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x21, 0x4c, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x10, 0x46, 0x02, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x7a, 0x25, 0x30, + 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, + 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x74, 0x2c, 0xc1, 0x19, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0xc6, 0x63, 0x4c, 0x00, 0xf5, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x3c, 0xc3, 0x24, + 0x3c, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, 0x8c, 0x67, 0x78, 0x92, + 0x87, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x99, 0x8e, 0x67, + 0x78, 0x86, 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x98, 0x12, 0x72, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, + 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x69, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, + 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0xa6, + 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, + 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, + 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, + 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe9, 0x79, + 0x88, 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, 0x09, 0x4b, 0x93, 0x73, + 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, + 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, + 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, + 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, + 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, + 0xb7, 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, 0xd6, 0x04, 0x4d, 0xd1, + 0x74, 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, + 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, + 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x9e, 0x61, 0xd2, + 0xa6, 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, 0xba, 0xa6, 0x8e, 0xd9, + 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, + 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, + 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, + 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, 0x98, 0xb4, 0xe9, 0x9b, + 0xaa, 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, 0x0a, 0x03, 0x2a, 0x61, + 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, 0xbe, 0xe6, 0xd2, 0xf4, + 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, + 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0x11, 0x09, 0x4b, 0x93, + 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, 0x26, 0xe7, 0x32, 0x47, + 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x95, 0xe6, + 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, 0x6e, 0x86, 0xc6, 0x9b, + 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, 0xb7, 0x32, 0x33, 0x33, + 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, 0x84, 0xc6, 0xde, 0xca, + 0xcc, 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, + 0xa5, 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xa9, 0xc1, 0xb3, + 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, 0xc3, 0x3c, 0xc5, 0x43, + 0x4c, 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, + 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x5e, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x4c, + 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x68, 0x90, 0x95, + 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, 0x99, 0xc6, 0x60, 0x22, + 0x83, 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, 0x32, 0x83, 0xe9, 0x0c, + 0xa6, 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, 0x78, 0x8a, 0x09, 0x9a, + 0xe0, 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, 0x26, 0xe7, 0x42, 0x57, + 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0x2e, + 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, 0x1e, 0x5d, 0x9d, 0x5c, + 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, 0x1d, 0x0b, 0xc8, 0x5c, + 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, 0x32, 0xbc, 0xac, 0x21, + 0xd4, 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, 0x3c, 0xc3, 0x44, 0x07, + 0x13, 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, 0x82, 0xae, 0x0c, 0xaf, + 0xca, 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, 0x65, 0xf0, 0x0c, 0xcf, + 0x30, 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, 0x13, 0x1e, 0x70, 0x09, + 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, 0xe3, 0x31, + 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, 0x6e, 0x88, 0xf4, 0x38, + 0x93, 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, 0x41, 0xd3, 0x1e, 0x4c, + 0xd7, 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, 0x49, 0x0c, 0x26, 0x39, + 0x98, 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, 0x18, 0x0b, 0x30, 0x4d, + 0x93, 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, + 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, + 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, 0x77, + 0xa0, 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, + 0xb0, 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, 0x29, + 0x81, 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, 0x70, + 0x70, 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, 0x7b, + 0x28, 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, 0x20, + 0x23, 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, + 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, 0x7a, + 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, + 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, + 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xfc, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, + 0xce, 0xe4, 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, + 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, + 0x7e, 0x85, 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xd6, + 0xf6, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x74, 0x47, 0x00, 0xa8, 0x8e, 0x35, + 0x00, 0x03, 0x31, 0xc7, 0x40, 0x0c, 0xde, 0x1c, 0x03, 0xe1, 0x79, 0x63, + 0x0d, 0x40, 0x20, 0x90, 0xab, 0x81, 0x11, 0x00, 0x7a, 0x33, 0x00, 0x04, + 0x47, 0x00, 0x28, 0xcc, 0x41, 0x90, 0x01, 0x19, 0x90, 0x81, 0x18, 0xcc, + 0x00, 0x10, 0x18, 0x23, 0x00, 0x41, 0x10, 0xc4, 0xbf, 0x11, 0x80, 0x19, + 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x8c, 0x41, 0xf4, 0x4c, 0x89, 0x81, + 0x08, 0x83, 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x28, 0x43, 0x50, 0x06, 0x52, + 0x54, 0x2d, 0x88, 0x42, 0x0c, 0x32, 0x04, 0xc7, 0x33, 0xc8, 0x30, 0x04, + 0xd1, 0x5d, 0x76, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x12, 0x19, 0x11, 0xc0, + 0x67, 0xbc, 0x61, 0xbb, 0xd6, 0xe0, 0x02, 0xbb, 0x14, 0x94, 0x41, 0x86, + 0x00, 0xb2, 0x46, 0x0c, 0x0a, 0x21, 0x88, 0x83, 0x22, 0x18, 0x6f, 0x00, + 0x03, 0xae, 0x0d, 0x2e, 0xb0, 0x4b, 0x41, 0x19, 0x64, 0x08, 0xaa, 0x6d, + 0xc4, 0xa0, 0x10, 0x02, 0x3b, 0x50, 0x82, 0xf1, 0x86, 0x32, 0x08, 0x03, + 0x37, 0xb8, 0xc0, 0x2e, 0x05, 0x65, 0x90, 0x21, 0xd0, 0xc0, 0x60, 0xc4, + 0xa0, 0x10, 0x82, 0x3d, 0x78, 0x82, 0x39, 0x86, 0x6e, 0xc9, 0x83, 0x39, + 0x86, 0xe0, 0xd8, 0x83, 0x39, 0x86, 0x60, 0xc8, 0x03, 0x0b, 0xde, 0x40, + 0x3e, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x68, 0x0c, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0x17, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, + 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, + 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, + 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, + 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, + 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, + 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, + 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, + 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, + 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, + 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, + 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, + 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, + 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, + 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, + 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, + 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, + 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, + 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, + 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, + 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, + 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, + 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, + 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, + 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, + 0x02, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x61, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x8a, 0x03, 0x58, 0x80, 0x6a, 0x83, + 0x61, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x00, 0x48, 0x00, 0xb5, 0x01, 0x39, + 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x18, 0x40, 0x02, 0xaa, 0x0d, 0x06, + 0x12, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x12, 0x01, 0x58, 0x80, 0x0a, 0x00, + 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, + 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x68, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, + 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, + 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, + 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, + 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, + 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, + 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, + 0x00, 0x06, 0xc3, 0x08, 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, + 0x8a, 0x03, 0x01, 0x29, 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, + 0xe6, 0x08, 0x40, 0x61, 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xa8, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, + 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, + 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, + 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, + 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, + 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, + 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x98, 0x05, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4c, 0x03, 0x04, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x46, 0x02, 0x02, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x7a, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, + 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x74, 0x2c, + 0xc1, 0x19, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x0c, 0x01, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0xc6, 0x63, 0x4c, 0x00, 0xf5, + 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x3c, 0xc3, 0x24, 0x3c, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, + 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, + 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, + 0x8c, 0x67, 0x78, 0x92, 0x87, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, + 0x04, 0x99, 0x8e, 0x67, 0x78, 0x86, 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, + 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, + 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, + 0x44, 0x98, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, + 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x69, 0x21, + 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, + 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, + 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, + 0x95, 0x0d, 0x11, 0xa6, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, + 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, + 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, + 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, + 0x43, 0x90, 0xe9, 0x79, 0x88, 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, + 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, + 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, + 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, + 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, + 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, + 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, + 0xd6, 0x04, 0x4d, 0xd1, 0x74, 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, + 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, + 0x3a, 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, + 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, + 0x91, 0x9e, 0x61, 0xd2, 0xa6, 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, + 0xba, 0xa6, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, + 0x19, 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, + 0x9d, 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, + 0x22, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, + 0x98, 0xb4, 0xe9, 0x9b, 0xaa, 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, + 0x0a, 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, + 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, + 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, + 0x26, 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, + 0x57, 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, + 0x6e, 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, + 0xb7, 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, + 0x84, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, + 0x43, 0x4c, 0x68, 0x30, 0xa5, 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, + 0x30, 0xa9, 0xc1, 0xb3, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, + 0xc3, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, + 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, + 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, + 0xca, 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, + 0x99, 0xc6, 0x60, 0x22, 0x83, 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, + 0x32, 0x83, 0xe9, 0x0c, 0xa6, 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, + 0x78, 0x8a, 0x09, 0x9a, 0xe0, 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, + 0x4d, 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, + 0x1e, 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, + 0x1d, 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, + 0x32, 0xbc, 0xac, 0x21, 0xd4, 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, + 0x3c, 0xc3, 0x44, 0x07, 0x13, 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, + 0x82, 0xae, 0x0c, 0xaf, 0xca, 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, + 0x65, 0xf0, 0x0c, 0xcf, 0x30, 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, + 0x13, 0x1e, 0x70, 0x09, 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, + 0x2b, 0x93, 0xe3, 0x31, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, + 0x6e, 0x88, 0xf4, 0x38, 0x93, 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, + 0x41, 0xd3, 0x1e, 0x4c, 0xd7, 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, + 0x49, 0x0c, 0x26, 0x39, 0x98, 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, + 0x18, 0x0b, 0x30, 0x4d, 0x93, 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, @@ -957,885 +1750,72 @@ const unsigned char sdl_metallib[] = { 0x77, 0x80, 0x07, 0x7a, 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, - 0xc8, 0x01, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, - 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, - 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, - 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, - 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, - 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, - 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, - 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, - 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, - 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, - 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, - 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, - 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, - 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, - 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, - 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, - 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, - 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, - 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, - 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, - 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, - 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, - 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, - 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, - 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, - 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, - 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, - 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, - 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, - 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, - 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, - 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, - 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, - 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, - 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, - 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, - 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, - 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, - 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, - 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, - 0x71, 0x20, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x10, 0xb1, 0x5d, - 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x45, 0x04, 0x18, 0x0c, 0xd1, 0x4c, 0x16, - 0xb0, 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, - 0x44, 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x0d, 0x00, 0x00, - 0x61, 0x20, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, - 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xc4, 0x46, 0x00, 0x48, - 0xd5, 0xc0, 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8a, 0x10, - 0x4c, 0x46, 0x81, 0x0c, 0x84, 0x10, 0x10, 0x52, 0x2c, 0x10, 0xe4, 0x93, - 0x41, 0x40, 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xb8, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x0d, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, - 0x41, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, - 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, - 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, - 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, - 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, - 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, - 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, - 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, - 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, - 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, - 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, - 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, - 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, - 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, - 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, - 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, - 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, - 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, - 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, - 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, - 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, - 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, - 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, - 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, - 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, - 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, - 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, - 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, - 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, - 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, - 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, - 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, - 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, - 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, - 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, - 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, - 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, - 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, - 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, - 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, - 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, - 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, - 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, - 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, - 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, - 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, - 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, - 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, - 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x0c, 0x40, 0x02, 0x2c, - 0x40, 0xb5, 0x01, 0x19, 0x08, 0x20, 0x01, 0x16, 0xa0, 0xda, 0x60, 0x10, - 0x05, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, 0xa8, 0x36, 0x18, - 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, 0x1b, 0x90, 0xe3, - 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x01, 0x24, 0xa0, 0xda, 0x60, 0x20, - 0x01, 0xb0, 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, 0xa8, 0x00, 0x00, - 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, - 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, - 0x89, 0x20, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, - 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, - 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, - 0x10, 0x7c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, - 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, 0x07, 0x49, 0x53, 0x44, 0x09, 0x93, - 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, 0x40, 0x20, 0x82, 0x10, 0x42, 0x06, - 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, - 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0xa7, 0x31, 0x02, 0x60, 0x10, 0xe1, - 0x08, 0x4e, 0x93, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, - 0x22, 0xe2, 0xb7, 0x87, 0x1f, 0x88, 0x22, 0x00, 0xfb, 0xa7, 0x31, 0x02, - 0x60, 0x10, 0x21, 0x09, 0x2e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x97, - 0x00, 0xe6, 0x59, 0x88, 0xe8, 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, 0x45, - 0x28, 0x48, 0x08, 0x62, 0x18, 0xa4, 0x18, 0xb5, 0x32, 0x00, 0x42, 0xe8, - 0xcd, 0x11, 0x80, 0xc1, 0x1c, 0x41, 0x30, 0x8c, 0x20, 0x44, 0x25, 0x09, - 0x8a, 0x89, 0x28, 0xa7, 0x04, 0x44, 0x0b, 0x12, 0x10, 0x13, 0x72, 0x4a, - 0x40, 0x76, 0x20, 0x20, 0x05, 0xe2, 0x30, 0xc2, 0x10, 0x0d, 0x22, 0x04, - 0xc2, 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x10, 0xc2, 0x08, 0x00, 0x00, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x07, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x0c, 0x04, 0x04, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0xa6, 0x02, 0x02, 0x60, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x73, 0x01, 0x01, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x05, 0x02, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x8a, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, - 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, - 0x7c, 0x04, 0x80, 0xf2, 0x58, 0x82, 0x23, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x1d, 0x01, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x46, 0x74, 0x60, - 0x40, 0x16, 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x44, 0x04, 0x26, 0x44, 0x08, 0xdd, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, - 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, - 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x26, 0x65, 0x88, 0x80, 0x11, 0x43, - 0x8c, 0x88, 0x88, 0x94, 0xa8, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, - 0x04, 0xc1, 0x8e, 0x88, 0x88, 0x88, 0xa8, 0xe0, 0x16, 0x96, 0x26, 0xe7, - 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, - 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, - 0x44, 0xc0, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, - 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, - 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, 0x6c, 0x21, - 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, - 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, - 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, - 0x95, 0x0d, 0x11, 0xb0, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, - 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, - 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, - 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, - 0x43, 0x10, 0xec, 0x89, 0x0a, 0x0c, 0xc2, 0xa2, 0x21, 0x02, 0x26, 0x91, - 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, - 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, - 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, - 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, - 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, - 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x50, 0x54, 0x60, 0x14, 0x56, 0x61, - 0x16, 0x06, 0x61, 0x11, 0x76, 0x61, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, - 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, - 0x3a, 0x3a, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, - 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, - 0x32, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, - 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x68, 0x98, 0xb1, 0xbd, - 0x85, 0xd1, 0xc9, 0x10, 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, 0x7b, 0x93, 0x23, - 0x1b, 0x22, 0x45, 0x04, 0xa6, 0x61, 0x1b, 0x56, 0x61, 0x1c, 0x06, 0x61, - 0x1d, 0x76, 0x61, 0x1e, 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, - 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, - 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x94, 0xc2, 0xd2, 0xe4, 0x5c, - 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, 0xd2, 0xdc, 0xc8, - 0xca, 0xf0, 0x88, 0x84, 0xa5, 0xc9, 0xb9, 0xc8, 0x95, 0x85, 0x91, 0x31, - 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, - 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0xe3, 0x15, 0x96, 0x26, 0xe7, 0x12, 0x26, - 0x77, 0xf6, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x15, 0xc6, 0x96, 0x76, 0xe6, - 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x61, 0xec, 0x8d, 0x6d, 0x08, 0x18, - 0x44, 0x07, 0x06, 0x06, 0x58, 0x18, 0x44, 0x06, 0x26, 0x06, 0x51, 0x11, - 0x11, 0xd8, 0x18, 0x60, 0x64, 0x10, 0x19, 0x58, 0x19, 0x44, 0x06, 0x06, - 0x61, 0x11, 0x76, 0x61, 0x66, 0x40, 0x2a, 0x2c, 0x4d, 0xce, 0x65, 0x8e, - 0x4e, 0xae, 0x6e, 0x8c, 0xee, 0x8b, 0x2e, 0x0f, 0xae, 0xec, 0x2b, 0xcd, - 0xcd, 0xec, 0x8d, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0x0c, 0x8d, 0x37, - 0x33, 0xb3, 0xb9, 0x32, 0x3a, 0x1a, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, - 0x34, 0x8e, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x68, 0x08, 0x8d, 0xbd, 0x95, - 0x99, 0x99, 0x0d, 0x41, 0x83, 0xa8, 0x88, 0x8c, 0xa8, 0xc0, 0xd2, 0x00, - 0x53, 0x83, 0xc8, 0x88, 0x8c, 0xa8, 0xc0, 0xd2, 0x00, 0x5b, 0x83, 0x88, - 0x89, 0x8c, 0xa8, 0xc0, 0xd2, 0x00, 0x63, 0x83, 0xa8, 0x89, 0x8c, 0xa8, - 0xc0, 0xd2, 0x00, 0x6b, 0x03, 0x26, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, - 0x6f, 0x64, 0x65, 0x34, 0xc8, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x86, 0x90, - 0x41, 0xb4, 0x60, 0x60, 0x80, 0x85, 0x41, 0x94, 0x60, 0x62, 0x10, 0x11, - 0x11, 0x81, 0x8d, 0x01, 0x86, 0x06, 0x98, 0x1b, 0x60, 0x64, 0x10, 0x25, - 0x58, 0x19, 0x44, 0x06, 0x06, 0x61, 0x6f, 0x80, 0x5d, 0x18, 0x1c, 0x70, - 0x09, 0x4b, 0x93, 0x73, 0xa1, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, 0xa3, - 0x12, 0x96, 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x46, 0x8c, - 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0x8c, 0xc7, 0x8c, 0xed, - 0x2d, 0x8c, 0x8e, 0x05, 0x64, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, - 0x04, 0x5d, 0x19, 0x5e, 0xd6, 0x10, 0x2a, 0x42, 0x30, 0x39, 0xc0, 0xc4, - 0x20, 0x2a, 0x22, 0x02, 0x9b, 0x03, 0x0c, 0xc2, 0xe8, 0x00, 0xbb, 0xb0, - 0x3a, 0xa0, 0x47, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x26, 0x43, 0xf6, - 0x15, 0x26, 0x27, 0x17, 0x96, 0xc7, 0x63, 0xc6, 0xf6, 0x16, 0x46, 0xc7, - 0x02, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0xe6, 0xc3, 0x82, 0xae, 0x0c, - 0xaf, 0xca, 0x6a, 0x08, 0x15, 0x39, 0x98, 0x1c, 0x60, 0x62, 0x10, 0x11, - 0x11, 0x81, 0xcd, 0x01, 0x06, 0x61, 0x77, 0x80, 0x5d, 0x18, 0x1e, 0x70, - 0x09, 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, 0xe3, - 0x31, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, 0x6e, 0x88, 0x14, - 0x3d, 0x98, 0x1e, 0x60, 0x62, 0x10, 0x15, 0x11, 0x81, 0x41, 0xd8, 0x1e, - 0x60, 0x17, 0xc6, 0x07, 0x43, 0x1c, 0x2c, 0xc3, 0x3e, 0xec, 0x0c, 0xb0, - 0x38, 0xc0, 0xec, 0x00, 0xcb, 0x03, 0xac, 0x0f, 0x86, 0x18, 0x0e, 0x80, - 0x4d, 0x98, 0x1f, 0xf0, 0x79, 0x6b, 0x73, 0x4b, 0x83, 0x7b, 0xa3, 0x2b, - 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, 0x93, 0xe3, 0x33, 0x95, 0xd6, 0x06, - 0xc7, 0x56, 0x06, 0x32, 0xb4, 0xb2, 0x02, 0x42, 0x25, 0x14, 0x14, 0x34, - 0x44, 0xc0, 0x42, 0x61, 0x88, 0x81, 0x81, 0x02, 0x26, 0x0a, 0x1c, 0x34, - 0xc4, 0xc0, 0x46, 0x01, 0x1b, 0x05, 0x0e, 0x1a, 0x11, 0xb1, 0x03, 0x3b, - 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, - 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, - 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, 0x90, - 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, 0x53, 0x82, 0x62, 0xc4, 0x12, - 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, - 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, 0x04, 0x15, 0x0e, 0xe9, 0x20, - 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, 0xe7, 0x50, 0x0f, 0xe1, 0x70, - 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, - 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, - 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, - 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, - 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, - 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, - 0x25, 0xf8, 0x03, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, - 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, - 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, - 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, - 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, - 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, - 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, - 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, - 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, - 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, - 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, - 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, - 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, - 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, - 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, - 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, - 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, - 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, - 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, - 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, - 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, - 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, - 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, - 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, - 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, - 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, - 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, - 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, - 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, - 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, - 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, - 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, - 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, - 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, - 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, - 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, - 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, - 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, - 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, - 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, - 0x71, 0x20, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x26, 0x10, 0x06, 0x00, - 0x12, 0xf9, 0x12, 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, - 0xf1, 0xdb, 0xc3, 0x0f, 0x44, 0x11, 0x80, 0xf9, 0x15, 0x5e, 0xdc, 0xb6, - 0x05, 0x34, 0x00, 0x12, 0xf9, 0x83, 0x33, 0xf9, 0xd5, 0x5d, 0xdc, 0xb6, - 0x0d, 0x6c, 0x00, 0x12, 0xf9, 0x12, 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, - 0x35, 0x51, 0x11, 0xf1, 0xdb, 0x83, 0x5f, 0xe1, 0xc5, 0x6d, 0x1b, 0x00, - 0xc4, 0x76, 0xe5, 0x2f, 0xbb, 0xef, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, - 0x04, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, - 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0xa4, 0xe7, 0x18, 0x0a, 0xcf, 0x1b, 0x6b, 0x00, 0x02, 0x81, 0xe6, 0x08, - 0x00, 0xc9, 0x11, 0x80, 0x1a, 0xa0, 0x38, 0x03, 0x40, 0x61, 0x0e, 0x42, - 0x0c, 0xc4, 0x40, 0x0c, 0xc2, 0x60, 0x06, 0x80, 0xc0, 0x18, 0x01, 0x08, - 0x82, 0x20, 0xfe, 0xcd, 0x00, 0x8c, 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, - 0x84, 0x81, 0xc3, 0x44, 0x47, 0x82, 0x04, 0x83, 0x0c, 0x41, 0xc1, 0x8c, - 0x18, 0x2c, 0x43, 0x40, 0x06, 0x8f, 0x33, 0x85, 0x41, 0xb2, 0x28, 0xc3, - 0x18, 0x42, 0x20, 0x06, 0x73, 0x0c, 0x43, 0x40, 0x06, 0x23, 0x06, 0xcb, - 0x10, 0x9c, 0x81, 0x14, 0x59, 0x65, 0xc0, 0x38, 0x8d, 0x31, 0x86, 0x10, - 0x94, 0xc1, 0x1c, 0xc3, 0x10, 0x90, 0xc1, 0x5d, 0x7b, 0x29, 0x28, 0x83, - 0x0c, 0x81, 0x43, 0x19, 0x11, 0xc0, 0x87, 0xb8, 0x32, 0xde, 0xc0, 0x85, - 0x41, 0x1b, 0x5c, 0xb0, 0x97, 0x82, 0x32, 0xc8, 0x10, 0x50, 0xda, 0x88, - 0x41, 0x21, 0x04, 0x74, 0x60, 0x04, 0xe3, 0x0d, 0x61, 0x60, 0x06, 0x6f, - 0x70, 0xc1, 0x5e, 0x0a, 0xca, 0x20, 0x43, 0x90, 0x7d, 0x23, 0x06, 0x85, - 0x10, 0xe4, 0xc1, 0x12, 0x8c, 0x37, 0x98, 0xc1, 0x1a, 0xc0, 0xc1, 0x05, - 0x7b, 0x29, 0x28, 0x83, 0x0c, 0x81, 0x47, 0x06, 0x23, 0x06, 0x85, 0x10, - 0xf8, 0x01, 0x14, 0xcc, 0x31, 0x84, 0xc1, 0xb2, 0x07, 0x73, 0x0c, 0xc1, - 0xd1, 0x07, 0x73, 0x0c, 0xc1, 0xb0, 0x07, 0x16, 0x4c, 0xf2, 0xc9, 0x20, - 0x20, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x06, 0x26, 0x20, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xa4, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, - 0x21, 0x0c, 0x00, 0x00, 0x26, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, - 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, - 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, - 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, - 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, - 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, - 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, - 0x92, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, - 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, - 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, - 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, - 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, - 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, - 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, - 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, - 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, - 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, - 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, - 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, - 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, - 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, - 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, - 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, - 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, - 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, - 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, - 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, - 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, - 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, - 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, - 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, - 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, - 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, - 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, - 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, - 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, - 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, - 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, - 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, - 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, - 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, - 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, - 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, - 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, - 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, - 0x0c, 0x40, 0x02, 0x2c, 0x40, 0xb5, 0x01, 0x19, 0x08, 0x20, 0x01, 0x16, - 0xa0, 0xda, 0x60, 0x10, 0x05, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x30, 0x80, - 0x05, 0xa8, 0x36, 0x18, 0xc6, 0x01, 0x2c, 0x40, 0xb5, 0xc1, 0x38, 0xfe, - 0xff, 0xff, 0xff, 0x7f, 0x00, 0x24, 0x80, 0xda, 0x80, 0x20, 0xff, 0xff, - 0xff, 0xff, 0x3f, 0x00, 0x0c, 0x20, 0x01, 0xd5, 0x06, 0x23, 0x09, 0x80, - 0x05, 0xa8, 0x36, 0x18, 0x8a, 0x00, 0x2c, 0x40, 0x05, 0x00, 0x00, 0x00, - 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8c, 0x40, 0x18, - 0x88, 0xc2, 0x98, 0x10, 0x1c, 0x13, 0x06, 0x24, 0x51, 0x00, 0x00, 0x00, - 0x89, 0x20, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, - 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, - 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, - 0x10, 0x6c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, - 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, 0x07, 0x49, 0x53, 0x44, 0x09, 0x93, - 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, 0x40, 0x20, 0x82, 0x10, 0x42, 0x06, - 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, - 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0xa7, 0x31, 0x02, 0x60, 0x10, 0xe1, - 0x08, 0x2e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x97, 0x00, 0xe6, 0x59, - 0x88, 0xe8, 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, 0x44, 0x28, 0x48, 0x08, - 0x62, 0x18, 0x84, 0x14, 0xad, 0x32, 0x00, 0x42, 0xa8, 0xcd, 0x11, 0x04, - 0x73, 0x04, 0x60, 0x30, 0x8c, 0x20, 0x40, 0x05, 0x09, 0x48, 0x89, 0x17, - 0x1f, 0x20, 0x39, 0x10, 0x90, 0x02, 0x70, 0x18, 0x61, 0x80, 0x06, 0x11, - 0x02, 0x61, 0x8e, 0x00, 0x14, 0x06, 0x11, 0x08, 0x61, 0x04, 0x00, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x06, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x8c, 0x03, 0x04, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x66, 0x02, 0x02, 0x60, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, - 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, - 0x78, 0x04, 0x80, 0xea, 0x58, 0x82, 0x23, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x16, 0x01, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x64, 0x50, - 0x40, 0x05, 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x40, 0x03, 0x25, 0x40, 0x07, 0xdd, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, - 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, - 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x26, 0x65, 0x88, 0x40, 0x11, 0x43, - 0x0c, 0x68, 0x80, 0x12, 0x88, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, - 0x04, 0xa1, 0x0e, 0x68, 0x80, 0x06, 0x88, 0xe0, 0x16, 0x96, 0x26, 0xe7, - 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, - 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, - 0x44, 0xa0, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, - 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, - 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, 0x6a, 0x21, - 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, - 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, - 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, - 0x95, 0x0d, 0x11, 0xa8, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, - 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, - 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, - 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, - 0x43, 0x10, 0xea, 0x81, 0x08, 0x0a, 0xa2, 0xa2, 0x21, 0x02, 0x25, 0x91, - 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, - 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, - 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, - 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, - 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, - 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x44, 0x50, 0x14, 0x55, 0x51, - 0x16, 0x05, 0x51, 0x11, 0x75, 0x51, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, - 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, - 0x3a, 0x3a, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, - 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, - 0x32, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, - 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x68, 0x98, 0xb1, 0xbd, - 0x85, 0xd1, 0xc9, 0x10, 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, 0x7b, 0x93, 0x23, - 0x1b, 0x22, 0x41, 0x03, 0xa5, 0x51, 0x1b, 0x55, 0x51, 0x1c, 0x05, 0x51, - 0x1d, 0x75, 0x51, 0x1e, 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, - 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, - 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x94, 0xc2, 0xd2, 0xe4, 0x5c, - 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, 0xd2, 0xdc, 0xc8, - 0xca, 0xf0, 0x88, 0x84, 0xa5, 0xc9, 0xb9, 0xc8, 0x95, 0x85, 0x91, 0x31, - 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, - 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0xe3, 0x15, 0x96, 0x26, 0xe7, 0x12, 0x26, - 0x77, 0xf6, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x15, 0xc6, 0x96, 0x76, 0xe6, - 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x61, 0xec, 0x8d, 0x6d, 0x08, 0x18, - 0x40, 0x06, 0x05, 0x06, 0x54, 0x18, 0x40, 0x05, 0x25, 0x06, 0x10, 0x01, - 0x0d, 0xd4, 0x18, 0x50, 0x64, 0x00, 0x15, 0x54, 0x19, 0x40, 0x05, 0x05, - 0x51, 0x11, 0x75, 0x51, 0x66, 0x40, 0x2a, 0x2c, 0x4d, 0xce, 0x65, 0x8e, - 0x4e, 0xae, 0x6e, 0x8c, 0xee, 0x8b, 0x2e, 0x0f, 0xae, 0xec, 0x2b, 0xcd, - 0xcd, 0xec, 0x8d, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0x0c, 0x8d, 0x37, - 0x33, 0xb3, 0xb9, 0x32, 0x3a, 0x1a, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, - 0x34, 0x8e, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x68, 0x08, 0x8d, 0xbd, 0x95, - 0x99, 0x99, 0x0d, 0x41, 0x03, 0x88, 0x80, 0x0a, 0x88, 0xa0, 0xd2, 0x80, - 0x52, 0x03, 0xa8, 0x80, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x5a, 0x03, 0x68, - 0x81, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x62, 0x03, 0x88, 0x81, 0x0a, 0x88, - 0xa0, 0xd2, 0x80, 0x6a, 0x03, 0x26, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, - 0x6f, 0x64, 0x65, 0x34, 0xc8, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x86, 0x90, - 0x01, 0xa4, 0x50, 0x60, 0x40, 0x85, 0x01, 0x84, 0x50, 0x62, 0x00, 0x0d, - 0xd0, 0x40, 0x8d, 0x01, 0x85, 0x06, 0x94, 0x1b, 0x50, 0x64, 0x00, 0x21, - 0x54, 0x19, 0x40, 0x05, 0x05, 0x51, 0x6f, 0x40, 0x5d, 0x14, 0x1c, 0x70, - 0x09, 0x4b, 0x93, 0x73, 0xa1, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, 0xa3, - 0x12, 0x96, 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x46, 0x8c, - 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0x8c, 0xc7, 0x8c, 0xed, - 0x2d, 0x8c, 0x8e, 0x05, 0x64, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, - 0x04, 0x5d, 0x19, 0x5e, 0xd6, 0x10, 0x0a, 0x3a, 0x28, 0x39, 0xa0, 0xc4, - 0x00, 0x22, 0xa0, 0x81, 0x9a, 0x03, 0x0a, 0xa2, 0xe8, 0x80, 0xba, 0xa8, - 0x3a, 0x60, 0x41, 0x57, 0x86, 0x57, 0x65, 0x35, 0x84, 0x82, 0x1a, 0x4a, - 0x0e, 0x28, 0x31, 0x80, 0x06, 0x68, 0xa0, 0xe6, 0x80, 0x82, 0x28, 0x3a, - 0xa0, 0x2e, 0xea, 0x0e, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, 0xb5, - 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, - 0x63, 0x30, 0x37, 0x44, 0x82, 0x1c, 0x2a, 0x0f, 0x28, 0x31, 0x80, 0x08, - 0x68, 0xa0, 0x20, 0x4a, 0x0f, 0xa8, 0x8b, 0xda, 0x83, 0x21, 0x0e, 0x95, - 0x51, 0x1f, 0x75, 0x06, 0x54, 0x1c, 0x50, 0x76, 0x40, 0xe1, 0x01, 0xc5, - 0x07, 0x43, 0x0c, 0x06, 0xa0, 0x26, 0xaa, 0x0f, 0xf8, 0xbc, 0xb5, 0xb9, - 0xa5, 0xc1, 0xbd, 0xd1, 0x95, 0xb9, 0xd1, 0x81, 0x8c, 0xa1, 0x85, 0xc9, - 0xf1, 0x99, 0x4a, 0x6b, 0x83, 0x63, 0x2b, 0x03, 0x19, 0x5a, 0x59, 0x01, - 0xa1, 0x12, 0x0a, 0x0a, 0x1a, 0x22, 0x50, 0xa0, 0x30, 0xc4, 0xa0, 0xfe, - 0x80, 0x0a, 0x05, 0xec, 0x19, 0x62, 0x50, 0xa2, 0x40, 0x89, 0x02, 0xf6, - 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, 0x1d, 0xde, - 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, 0x1d, 0xc2, - 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, 0x60, 0x07, - 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, 0x77, 0xa0, 0x87, - 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0xb0, 0x87, - 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, 0x29, 0x81, 0x31, - 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, 0x70, 0x70, 0x87, - 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, 0x7b, 0x28, 0x07, - 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, 0x20, 0x23, 0xa6, - 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, 0x80, 0x87, - 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, 0x7a, 0x48, 0x87, - 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, 0x09, 0x87, - 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, 0x68, 0x87, - 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, - 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, - 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, - 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, - 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, - 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, - 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, - 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, - 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, - 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, - 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, - 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, - 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, - 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, - 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, - 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, - 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, - 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, - 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, - 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, - 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, - 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, - 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, - 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, - 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, - 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, - 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, - 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, - 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, - 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, - 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, - 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, - 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, - 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, - 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, - 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, - 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, - 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, - 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, - 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, - 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, - 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, - 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, - 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, - 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xd6, 0xf6, 0x5f, - 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x64, 0xc7, 0x1a, 0x80, 0x81, 0x98, 0x63, 0x20, - 0x86, 0x6f, 0x8e, 0x81, 0xf8, 0xbe, 0xb1, 0x06, 0x20, 0x10, 0x28, 0x8e, - 0x00, 0xd0, 0xab, 0x81, 0x11, 0x00, 0x82, 0x33, 0x00, 0x14, 0xe6, 0x20, - 0xc8, 0x80, 0x0c, 0xc8, 0x40, 0x0c, 0x66, 0x00, 0x08, 0x8c, 0x11, 0x80, - 0x20, 0x08, 0xe2, 0xdf, 0x08, 0xc0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x23, 0x06, 0xca, 0x10, 0x8c, 0x01, 0xe4, 0x4c, 0x48, 0x72, 0x08, 0x83, - 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x28, 0x43, 0x50, 0x06, 0x11, 0x54, 0x29, - 0x4b, 0x42, 0x0c, 0x32, 0x04, 0xc7, 0x33, 0xc8, 0x30, 0x04, 0xd1, 0x59, - 0x77, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x12, 0x19, 0x11, 0xc0, 0x87, 0xb6, - 0x32, 0xde, 0xb0, 0x81, 0x01, 0x1b, 0x5c, 0x70, 0x97, 0x82, 0x32, 0xc8, - 0x10, 0x44, 0xd7, 0x88, 0x41, 0x21, 0x04, 0x72, 0x60, 0x04, 0xe3, 0x0d, - 0x60, 0x50, 0x06, 0x6e, 0x70, 0xc1, 0x5d, 0x0a, 0xca, 0x20, 0x43, 0x60, - 0x71, 0x23, 0x06, 0x85, 0x10, 0xdc, 0xc1, 0x12, 0x8c, 0x37, 0x94, 0x81, - 0x1a, 0xbc, 0xc1, 0x05, 0x77, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x16, 0x06, - 0x23, 0x06, 0x85, 0x10, 0xf0, 0x01, 0x14, 0xcc, 0x31, 0x78, 0x8b, 0x1e, - 0xcc, 0x31, 0x04, 0x07, 0x1f, 0xcc, 0x31, 0x04, 0x83, 0x1e, 0x58, 0x30, - 0xc9, 0x27, 0x83, 0x80, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x5b, 0x86, 0x24, 0x18, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xb0, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, - 0x21, 0x0c, 0x00, 0x00, 0x29, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, - 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, - 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, - 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, - 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, - 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, - 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, - 0x92, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, - 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, - 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, - 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, - 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, - 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, - 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, - 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, - 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, - 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, - 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, - 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, - 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, - 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, - 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, - 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, - 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, - 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, - 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, - 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, - 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, - 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, - 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, - 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, - 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, - 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, - 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, - 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, - 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, - 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, - 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, - 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, - 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, - 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, - 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, - 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, - 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, - 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, - 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, - 0x0c, 0x40, 0x02, 0x2c, 0x40, 0xb5, 0x01, 0x19, 0x08, 0x20, 0x01, 0x16, - 0xa0, 0xda, 0x60, 0x10, 0x05, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x30, 0x80, - 0x05, 0xa8, 0x36, 0x18, 0xc6, 0x01, 0x2c, 0x40, 0xb5, 0xc1, 0x38, 0xfe, - 0xff, 0xff, 0xff, 0x7f, 0x00, 0x24, 0x80, 0xda, 0x80, 0x20, 0xff, 0xff, - 0xff, 0xff, 0x3f, 0x00, 0x0c, 0x20, 0x01, 0xd5, 0x06, 0x23, 0x09, 0x80, - 0x05, 0xa8, 0x36, 0x18, 0x8a, 0x00, 0x2c, 0x40, 0x05, 0x00, 0x00, 0x00, - 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8c, 0x40, 0x18, - 0x88, 0xc2, 0x98, 0x10, 0x1c, 0x13, 0x06, 0x24, 0x51, 0x00, 0x00, 0x00, - 0x89, 0x20, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, - 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, - 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, - 0x10, 0x6c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, - 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, 0x07, 0x49, 0x53, 0x44, 0x09, 0x93, - 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, 0x40, 0x20, 0x82, 0x10, 0x42, 0x06, - 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, - 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0xa7, 0x31, 0x02, 0x60, 0x10, 0xe1, - 0x08, 0x2e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x97, 0x00, 0xe6, 0x59, - 0x88, 0xe8, 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, 0x44, 0x28, 0x48, 0x08, - 0x62, 0x18, 0x84, 0x14, 0xad, 0x32, 0x00, 0x42, 0xa8, 0xcd, 0x11, 0x04, - 0x73, 0x04, 0x60, 0x30, 0x8c, 0x20, 0x40, 0x05, 0x09, 0x48, 0x89, 0x17, - 0x1f, 0x20, 0x39, 0x10, 0x90, 0x02, 0x70, 0x18, 0x61, 0x80, 0x06, 0x11, - 0x02, 0x61, 0x8e, 0x00, 0x14, 0x06, 0x11, 0x08, 0x61, 0x04, 0x00, 0x00, - 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, - 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, - 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, - 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, - 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, - 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, - 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, - 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, - 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, - 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, - 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, - 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, - 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, - 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, - 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, - 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, - 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, - 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, - 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, - 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, - 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, - 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, - 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, - 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, - 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x18, 0x06, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x8c, 0x03, 0x04, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x66, 0x02, 0x02, 0x60, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, - 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, - 0xc6, 0x04, 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, - 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, - 0x78, 0x04, 0x80, 0xea, 0x58, 0x82, 0x23, 0x00, 0x79, 0x18, 0x00, 0x00, - 0x16, 0x01, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, - 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x64, 0x50, - 0x40, 0x05, 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, - 0x2b, 0x1b, 0x62, 0x40, 0x03, 0x25, 0x40, 0x07, 0xdd, 0x20, 0x08, 0x0e, - 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, - 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, - 0x06, 0x06, 0x26, 0xc6, 0x85, 0x66, 0x26, 0x65, 0x88, 0x40, 0x11, 0x43, - 0x0c, 0x68, 0x80, 0x12, 0x88, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, - 0x04, 0xa1, 0x0e, 0x68, 0x80, 0x06, 0x88, 0xe0, 0x16, 0x96, 0x26, 0xe7, - 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, - 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, - 0x44, 0xa0, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, - 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, - 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, 0x6a, 0x21, - 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, - 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, - 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, - 0x95, 0x0d, 0x11, 0xa8, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, - 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, - 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, - 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, - 0x43, 0x10, 0xea, 0x81, 0x08, 0x0a, 0xa2, 0xa2, 0x21, 0x02, 0x25, 0x91, - 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, - 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, - 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, - 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, - 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, - 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x44, 0x50, 0x14, 0x55, 0x51, - 0x16, 0x05, 0x51, 0x11, 0x75, 0x51, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, - 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, - 0x3a, 0x3a, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, - 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, - 0x32, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, - 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x68, 0x98, 0xb1, 0xbd, - 0x85, 0xd1, 0xc9, 0x10, 0xa1, 0x2b, 0xc3, 0x1b, 0x7b, 0x7b, 0x93, 0x23, - 0x1b, 0x22, 0x41, 0x03, 0xa5, 0x51, 0x1b, 0x55, 0x51, 0x1c, 0x05, 0x51, - 0x1d, 0x75, 0x51, 0x1e, 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, - 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, - 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x94, 0xc2, 0xd2, 0xe4, 0x5c, - 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, 0xd2, 0xdc, 0xc8, - 0xca, 0xf0, 0x88, 0x84, 0xa5, 0xc9, 0xb9, 0xc8, 0x95, 0x85, 0x91, 0x31, - 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, - 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0xe3, 0x15, 0x96, 0x26, 0xe7, 0x12, 0x26, - 0x77, 0xf6, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x15, 0xc6, 0x96, 0x76, 0xe6, - 0xf6, 0x35, 0x97, 0xa6, 0x57, 0xc6, 0x61, 0xec, 0x8d, 0x6d, 0x08, 0x18, - 0x40, 0x06, 0x05, 0x06, 0x54, 0x18, 0x40, 0x05, 0x25, 0x06, 0x10, 0x01, - 0x0d, 0xd4, 0x18, 0x50, 0x64, 0x00, 0x15, 0x54, 0x19, 0x40, 0x05, 0x05, - 0x51, 0x11, 0x75, 0x51, 0x66, 0x40, 0x2a, 0x2c, 0x4d, 0xce, 0x65, 0x8e, - 0x4e, 0xae, 0x6e, 0x8c, 0xee, 0x8b, 0x2e, 0x0f, 0xae, 0xec, 0x2b, 0xcd, - 0xcd, 0xec, 0x8d, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0x0c, 0x8d, 0x37, - 0x33, 0xb3, 0xb9, 0x32, 0x3a, 0x1a, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, - 0x34, 0x8e, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x68, 0x08, 0x8d, 0xbd, 0x95, - 0x99, 0x99, 0x0d, 0x41, 0x03, 0x88, 0x80, 0x0a, 0x88, 0xa0, 0xd2, 0x80, - 0x52, 0x03, 0xa8, 0x80, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x5a, 0x03, 0x68, - 0x81, 0x0a, 0x88, 0xa0, 0xd2, 0x80, 0x62, 0x03, 0x88, 0x81, 0x0a, 0x88, - 0xa0, 0xd2, 0x80, 0x6a, 0x03, 0x26, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, - 0x6f, 0x64, 0x65, 0x34, 0xc8, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x86, 0x90, - 0x01, 0xa4, 0x50, 0x60, 0x40, 0x85, 0x01, 0x84, 0x50, 0x62, 0x00, 0x0d, - 0xd0, 0x40, 0x8d, 0x01, 0x85, 0x06, 0x94, 0x1b, 0x50, 0x64, 0x00, 0x21, - 0x54, 0x19, 0x40, 0x05, 0x05, 0x51, 0x6f, 0x40, 0x5d, 0x14, 0x1c, 0x70, - 0x09, 0x4b, 0x93, 0x73, 0xa1, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, 0xa3, - 0x12, 0x96, 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x46, 0x8c, - 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0x8c, 0xc7, 0x8c, 0xed, - 0x2d, 0x8c, 0x8e, 0x05, 0x64, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, - 0x04, 0x5d, 0x19, 0x5e, 0xd6, 0x10, 0x0a, 0x3a, 0x28, 0x39, 0xa0, 0xc4, - 0x00, 0x22, 0xa0, 0x81, 0x9a, 0x03, 0x0a, 0xa2, 0xe8, 0x80, 0xba, 0xa8, - 0x3a, 0x60, 0x41, 0x57, 0x86, 0x57, 0x65, 0x35, 0x84, 0x82, 0x1a, 0x4a, - 0x0e, 0x28, 0x31, 0x80, 0x06, 0x68, 0xa0, 0xe6, 0x80, 0x82, 0x28, 0x3a, - 0xa0, 0x2e, 0xea, 0x0e, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, 0xb5, - 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, - 0x63, 0x30, 0x37, 0x44, 0x82, 0x1c, 0x2a, 0x0f, 0x28, 0x31, 0x80, 0x08, - 0x68, 0xa0, 0x20, 0x4a, 0x0f, 0xa8, 0x8b, 0xda, 0x83, 0x21, 0x0e, 0x95, - 0x51, 0x1f, 0x75, 0x06, 0x54, 0x1c, 0x50, 0x76, 0x40, 0xe1, 0x01, 0xc5, - 0x07, 0x43, 0x0c, 0x06, 0xa0, 0x26, 0xaa, 0x0f, 0xf8, 0xbc, 0xb5, 0xb9, - 0xa5, 0xc1, 0xbd, 0xd1, 0x95, 0xb9, 0xd1, 0x81, 0x8c, 0xa1, 0x85, 0xc9, - 0xf1, 0x99, 0x4a, 0x6b, 0x83, 0x63, 0x2b, 0x03, 0x19, 0x5a, 0x59, 0x01, - 0xa1, 0x12, 0x0a, 0x0a, 0x1a, 0x22, 0x50, 0xa0, 0x30, 0xc4, 0xa0, 0xfe, - 0x80, 0x0a, 0x05, 0xec, 0x19, 0x62, 0x50, 0xa2, 0x40, 0x89, 0x02, 0xf6, - 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, 0x1d, 0xde, - 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, 0x1d, 0xc2, - 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, 0x60, 0x07, - 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, 0x77, 0xa0, 0x87, - 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0xb0, 0x87, - 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, 0x29, 0x81, 0x31, - 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, 0x70, 0x70, 0x87, - 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, 0x7b, 0x28, 0x07, - 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, 0x20, 0x23, 0xa6, - 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, 0x80, 0x87, - 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, 0x7a, 0x48, 0x87, - 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, 0x09, 0x87, - 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, 0x68, 0x87, - 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, - 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, - 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, - 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, - 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, - 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, - 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, - 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, - 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, - 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, - 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, - 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, - 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, - 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, - 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, - 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, - 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, - 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, - 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, - 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, - 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, - 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, - 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, - 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, - 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, - 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, - 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, - 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, - 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, - 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, - 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, - 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, - 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, - 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, - 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, - 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, - 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, - 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, - 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, - 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, - 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, - 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, - 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, - 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, - 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xda, 0xf5, 0x5f, - 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, - 0x3b, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x64, 0xc7, 0x1a, 0x80, 0x81, 0x98, 0x63, 0x20, - 0x06, 0x30, 0x98, 0x63, 0x20, 0xc0, 0x00, 0x0c, 0xc6, 0x1a, 0x80, 0x40, - 0xa0, 0x38, 0x96, 0x10, 0x00, 0x23, 0x00, 0xf4, 0x6a, 0x60, 0x04, 0x80, - 0xe0, 0x0c, 0x00, 0x89, 0x19, 0x00, 0x0a, 0x73, 0x10, 0x66, 0x60, 0x06, - 0x66, 0x40, 0x06, 0x33, 0x00, 0x04, 0xc6, 0x08, 0x40, 0x10, 0x04, 0xf1, - 0x6f, 0x04, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, - 0x94, 0x81, 0x04, 0x55, 0x89, 0x82, 0x08, 0x83, 0x0c, 0x41, 0xe1, 0x8c, - 0x18, 0x28, 0x43, 0x70, 0x06, 0x93, 0x74, 0x2d, 0x8c, 0x42, 0x0c, 0x32, - 0x04, 0x87, 0x33, 0xc8, 0x10, 0x28, 0xd2, 0x20, 0x03, 0x11, 0x50, 0x97, - 0xdd, 0xa5, 0xa0, 0x0c, 0x32, 0x04, 0x0c, 0x65, 0x44, 0x00, 0x1f, 0xf2, - 0xca, 0x78, 0x83, 0x37, 0x06, 0x6f, 0x70, 0xc1, 0x5d, 0x0a, 0xca, 0x20, - 0x43, 0x20, 0x69, 0x23, 0x06, 0x85, 0x10, 0xd4, 0x81, 0x11, 0x8c, 0x37, - 0x8c, 0x01, 0x1a, 0xc4, 0xc1, 0x05, 0x77, 0x29, 0x28, 0x83, 0x0c, 0xc1, - 0xf5, 0x8d, 0x18, 0x14, 0x42, 0xa0, 0x07, 0x4b, 0x30, 0xde, 0x80, 0x06, - 0x6d, 0x20, 0x07, 0x17, 0xdc, 0xa5, 0xa0, 0x0c, 0x32, 0x04, 0x1c, 0x19, - 0x8c, 0x18, 0x14, 0x42, 0xf0, 0x07, 0x50, 0x30, 0xc7, 0xf0, 0x2d, 0x7d, - 0x30, 0xc7, 0x10, 0x1c, 0x7f, 0x30, 0xc7, 0x10, 0x0c, 0x7d, 0x60, 0xc1, - 0x24, 0x9f, 0x0c, 0x02, 0x62, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x5b, 0x06, 0x25, 0x18, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, + 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, + 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, + 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, + 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, + 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, + 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, + 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, + 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, + 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, + 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, + 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, + 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, + 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, + 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, + 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, + 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, + 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, + 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, + 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, + 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, + 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, + 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, + 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, + 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, + 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, + 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, + 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, + 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, + 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, + 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, + 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, + 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, + 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, + 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, + 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, + 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, + 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, + 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, + 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, + 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, + 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, + 0x95, 0xff, 0xf9, 0xda, 0xf5, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, + 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x13, 0x04, + 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x74, 0x47, + 0x00, 0xa8, 0x8e, 0x35, 0x00, 0x03, 0x31, 0xc7, 0x40, 0x0c, 0xdf, 0x1c, + 0x03, 0xf1, 0x7d, 0x63, 0x0d, 0x40, 0x20, 0x10, 0x1c, 0x4b, 0x08, 0x00, + 0x72, 0x35, 0x30, 0x02, 0x40, 0x6f, 0x06, 0x80, 0xe0, 0x08, 0x00, 0x89, + 0x19, 0x00, 0x0a, 0x73, 0x10, 0x66, 0x60, 0x06, 0x66, 0x40, 0x06, 0x33, + 0x00, 0x04, 0xc6, 0x08, 0x40, 0x10, 0x04, 0xf1, 0x6f, 0x04, 0x60, 0x06, + 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x94, 0xc1, 0x14, 0x55, 0xca, 0x91, + 0x08, 0x83, 0x0c, 0x41, 0xe1, 0x8c, 0x18, 0x28, 0x43, 0x70, 0x06, 0xd4, + 0x74, 0x31, 0xc9, 0x42, 0x0c, 0x32, 0x04, 0x87, 0x33, 0xc8, 0x10, 0x28, + 0xd2, 0x20, 0x03, 0x11, 0x50, 0xa7, 0xd9, 0xa5, 0xa0, 0x0c, 0x32, 0x04, + 0x0c, 0x65, 0x44, 0x00, 0x9f, 0xf1, 0x06, 0x4f, 0x73, 0x83, 0x0b, 0xec, + 0x52, 0x50, 0x06, 0x19, 0x82, 0x28, 0x1b, 0x31, 0x28, 0x84, 0x80, 0x0e, + 0x8a, 0x60, 0xbc, 0x61, 0x0c, 0x3e, 0x38, 0xb8, 0xc0, 0x2e, 0x05, 0x65, + 0x90, 0x21, 0xb0, 0xbc, 0x11, 0x83, 0x42, 0x08, 0xf2, 0x40, 0x09, 0xc6, + 0x1b, 0xd0, 0x80, 0x0c, 0xe2, 0xe0, 0x02, 0xbb, 0x14, 0x94, 0x41, 0x86, + 0x60, 0x1b, 0x83, 0x11, 0x83, 0x42, 0x08, 0xfc, 0xe0, 0x09, 0xe6, 0x18, + 0xbc, 0x85, 0x0f, 0xe6, 0x18, 0x82, 0xc3, 0x0f, 0xe6, 0x18, 0x82, 0x81, + 0x0f, 0x2c, 0x90, 0x03, 0xf9, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -const unsigned int sdl_metallib_len = 22048; +const unsigned int sdl_metallib_len = 21810; diff --git a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_tvsimulator.h b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_tvsimulator.h index a19c28ec3..2ceddcf10 100644 --- a/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_tvsimulator.h +++ b/Engine/lib/sdl/src/render/metal/SDL_shaders_metal_tvsimulator.h @@ -1,19 +1,19 @@ const unsigned char sdl_metallib[] = { 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc2, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x04, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc2, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, + 0xd4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, - 0xa1, 0x1a, 0x08, 0xa6, 0xd4, 0x06, 0x5b, 0x9f, 0x1d, 0x1a, 0x7e, 0x1c, - 0x9e, 0xf1, 0x2b, 0xa9, 0x09, 0x12, 0x30, 0x70, 0xf6, 0x82, 0xb1, 0x5a, - 0xac, 0x6b, 0xa9, 0xd3, 0x14, 0x34, 0xcd, 0x0b, 0x4d, 0x44, 0x53, 0x5a, - 0x08, 0x00, 0xa0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, + 0x0c, 0x89, 0xfb, 0xf3, 0x80, 0x90, 0x8e, 0x7b, 0x79, 0xce, 0x85, 0xbe, + 0x02, 0x5a, 0x26, 0xb3, 0x39, 0x94, 0x89, 0x06, 0x15, 0xa3, 0x7c, 0x33, + 0xd4, 0xcb, 0xcd, 0x46, 0xe6, 0x32, 0x49, 0x18, 0x4d, 0x44, 0x53, 0x5a, + 0x08, 0x00, 0x30, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, @@ -21,513 +21,246 @@ const unsigned char sdl_metallib[] = { 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, - 0x00, 0xbf, 0x74, 0x9c, 0x9c, 0xf6, 0x5a, 0xa7, 0xf1, 0x7f, 0x79, 0xbd, - 0xbf, 0x4f, 0x66, 0xef, 0xad, 0x72, 0xbc, 0xd5, 0x58, 0x86, 0xf4, 0xf9, - 0xdc, 0x10, 0x57, 0x64, 0xbc, 0x42, 0x49, 0x7d, 0xe4, 0x4d, 0x44, 0x53, - 0x5a, 0x08, 0x00, 0xe0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, - 0x46, 0x46, 0x54, 0x18, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0c, 0x00, + 0x00, 0xc8, 0xfe, 0x88, 0x61, 0xa2, 0xe6, 0xe3, 0x42, 0xf3, 0x2b, 0x5b, + 0x2a, 0x0e, 0x54, 0x9a, 0xec, 0x71, 0xac, 0x02, 0xfb, 0x88, 0xa2, 0x85, + 0x0e, 0x9c, 0x45, 0x93, 0x65, 0x23, 0xd3, 0xd3, 0x45, 0x4d, 0x44, 0x53, + 0x5a, 0x08, 0x00, 0x30, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x88, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x13, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, - 0x41, 0x53, 0x48, 0x20, 0x00, 0x4c, 0x67, 0xd2, 0xbf, 0xc5, 0x1c, 0xd8, - 0x80, 0xdb, 0xde, 0xed, 0xf1, 0xfa, 0xe2, 0x4a, 0x01, 0x5f, 0x48, 0xf0, - 0xc3, 0x0b, 0xdf, 0xba, 0x45, 0x78, 0xd5, 0x1a, 0x12, 0x3b, 0x34, 0xdc, - 0x52, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x90, 0x0a, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x54, 0x00, 0x00, + 0x41, 0x53, 0x48, 0x20, 0x00, 0xb3, 0x8a, 0x68, 0x2a, 0xd9, 0x82, 0x7b, + 0x43, 0xfb, 0xac, 0xd7, 0x0b, 0x21, 0xbf, 0x15, 0x37, 0x2d, 0x69, 0xf4, + 0x5e, 0xa9, 0xbf, 0xea, 0x08, 0xb5, 0xae, 0xdd, 0x08, 0xa0, 0x57, 0x15, + 0x34, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x30, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, + 0x00, 0x60, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x87, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, - 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0xf2, 0x3f, 0x0e, 0xaf, - 0x26, 0xec, 0x90, 0x97, 0x14, 0x10, 0x3e, 0xe4, 0x09, 0xeb, 0xcd, 0x08, - 0x39, 0xe4, 0xef, 0x15, 0x4c, 0xd5, 0xc4, 0x48, 0x4d, 0x93, 0xbf, 0x0e, - 0xd3, 0xa0, 0x84, 0xa0, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x80, 0x0c, + 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x3a, 0xdb, 0x4f, 0xd9, + 0x5c, 0xa8, 0x18, 0xff, 0x1d, 0x96, 0x7f, 0x0d, 0xce, 0x02, 0xc1, 0xaf, + 0x38, 0xef, 0x15, 0x30, 0x92, 0x06, 0x8f, 0xfe, 0xa9, 0x07, 0x34, 0xfb, + 0x22, 0x93, 0xdc, 0xf9, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0xc0, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, - 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x90, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x86, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, - 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x1b, 0x3d, - 0x7f, 0xbb, 0x00, 0x92, 0x05, 0xf2, 0xfe, 0xfc, 0xcc, 0xc2, 0xd7, 0x71, - 0x65, 0x40, 0x45, 0xaf, 0xee, 0xfc, 0x35, 0x50, 0x11, 0x09, 0xdf, 0x8b, - 0xc7, 0x5e, 0xea, 0x7e, 0x39, 0x69, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, - 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, - 0x18, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x26, 0x67, + 0x01, 0x40, 0x41, 0x64, 0x85, 0x58, 0xad, 0x6c, 0x46, 0xe8, 0xbf, 0x1a, + 0x79, 0x22, 0x12, 0x67, 0x32, 0x81, 0x20, 0xca, 0x22, 0xde, 0xc9, 0xc5, + 0xa1, 0x0a, 0x41, 0xfe, 0xd9, 0xa3, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, + 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, + 0x18, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x87, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, - 0x00, 0x63, 0xd6, 0x78, 0xc5, 0xa7, 0x85, 0xa1, 0x37, 0xa6, 0xa2, 0xed, - 0x14, 0xb5, 0x6e, 0x7f, 0x89, 0x3f, 0xbc, 0x1f, 0xee, 0x5e, 0xbb, 0x28, - 0x68, 0x8c, 0x1a, 0x62, 0xdf, 0x43, 0xfa, 0x11, 0x1c, 0x4d, 0x44, 0x53, - 0x5a, 0x08, 0x00, 0x90, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, - 0x46, 0x46, 0x54, 0x18, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x3f, 0x00, + 0x00, 0xff, 0x5a, 0xf7, 0xe3, 0x70, 0x77, 0x5e, 0x01, 0xaf, 0xf6, 0x9f, + 0x0b, 0xa1, 0x25, 0x76, 0xbf, 0xa1, 0x1f, 0xfb, 0x62, 0xbf, 0x02, 0xfa, + 0xa4, 0x10, 0x0d, 0xe9, 0x0f, 0x97, 0x2d, 0x3e, 0xca, 0x4d, 0x44, 0x53, + 0x5a, 0x08, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x87, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, - 0x53, 0x48, 0x20, 0x00, 0x59, 0x98, 0xa1, 0x99, 0x21, 0x4f, 0xf0, 0xd6, - 0x63, 0xb1, 0x37, 0x97, 0x47, 0x88, 0xe9, 0xe8, 0x3a, 0x95, 0x75, 0xbd, - 0x84, 0x48, 0x90, 0xa6, 0x3c, 0x11, 0x3b, 0xfc, 0xac, 0xd2, 0xa7, 0x1f, - 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0xa0, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x53, 0x48, 0x20, 0x00, 0xdb, 0xf5, 0x5b, 0x6b, 0x9e, 0xad, 0xda, 0x32, + 0x16, 0x65, 0xd3, 0x04, 0x29, 0x2b, 0xc3, 0x71, 0xb9, 0x29, 0x97, 0xe1, + 0x4c, 0xa7, 0x36, 0x12, 0x81, 0x50, 0x19, 0xa9, 0x4b, 0x3f, 0xe8, 0xdb, + 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x40, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, + 0x50, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, - 0x44, 0x54, 0x45, 0x4e, 0x44, 0x54, 0x20, 0x00, 0x00, 0x00, 0x56, 0x41, - 0x54, 0x54, 0x0d, 0x00, 0x01, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x00, 0x00, 0x80, 0x56, 0x41, 0x54, 0x59, 0x03, 0x00, 0x01, - 0x00, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x2c, 0x00, 0x00, 0x00, 0x56, 0x41, - 0x54, 0x54, 0x18, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x00, 0x00, 0x80, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, - 0x64, 0x00, 0x01, 0x80, 0x56, 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, - 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, - 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, - 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, - 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, - 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, - 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, - 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, - 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x8c, 0x0c, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, - 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0xe9, 0x02, 0x00, 0x00, 0x0b, 0x02, - 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, - 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, - 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, - 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, - 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, - 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, - 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, - 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x1b, 0xc8, - 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, - 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, - 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, - 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, - 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, - 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, - 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, - 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, - 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, - 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, - 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, - 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, - 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, - 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, - 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, - 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, - 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, - 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, - 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, - 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, - 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, - 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, - 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, - 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, - 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, - 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, - 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, - 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, - 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, - 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, - 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, - 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, - 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, - 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, - 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, - 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, - 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, - 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x44, 0x54, 0x45, 0x4e, 0x44, 0x54, 0x29, 0x00, 0x00, 0x00, 0x56, 0x41, + 0x54, 0x54, 0x15, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x00, 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, + 0x80, 0x56, 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x06, 0x45, + 0x4e, 0x44, 0x54, 0x35, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x20, + 0x00, 0x03, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x74, 0x65, + 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x02, 0x80, 0x56, 0x41, 0x54, + 0x59, 0x05, 0x00, 0x03, 0x00, 0x04, 0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x10, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, + 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, + 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, + 0x09, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, + 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, + 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, + 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, + 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, + 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, + 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, + 0x85, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, + 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, + 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, + 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, - 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, - 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, - 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, - 0x72, 0x00, 0x36, 0x2c, 0x82, 0x00, 0x24, 0xc0, 0x02, 0x54, 0x41, 0x1a, - 0x80, 0xc2, 0x86, 0x65, 0x18, 0x80, 0x04, 0x58, 0x80, 0x2a, 0x48, 0x03, - 0x50, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, - 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1b, 0x00, - 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, - 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, - 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, - 0x04, 0x60, 0x85, 0x00, 0x86, 0x11, 0x04, 0x20, 0x09, 0xc2, 0x4c, 0xd4, - 0x3c, 0xd0, 0x83, 0x3c, 0xd4, 0xc3, 0x38, 0xd0, 0x83, 0x1b, 0xb4, 0x43, - 0x39, 0xd0, 0x43, 0x38, 0xb0, 0x83, 0x1e, 0xe8, 0x41, 0x3b, 0x84, 0x03, - 0x3d, 0xc8, 0x43, 0x3a, 0xe0, 0x03, 0x0a, 0xc8, 0x20, 0x42, 0x21, 0x14, - 0x42, 0x0c, 0x63, 0xe8, 0x0c, 0x04, 0xcc, 0x11, 0x80, 0x41, 0x0a, 0xa8, - 0x39, 0x02, 0x50, 0x18, 0x44, 0x08, 0x84, 0x61, 0x04, 0x42, 0x19, 0x01, - 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, - 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, - 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, - 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, - 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, - 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, - 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, - 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, - 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, - 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, - 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, - 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, - 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, - 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, - 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, - 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, - 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, - 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, - 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, - 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, - 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, - 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, - 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, - 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, - 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, - 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, - 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, - 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, - 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x42, 0x6c, 0x57, - 0xfe, 0xac, 0xb3, 0x20, 0xc3, 0x5f, 0x11, 0xd1, 0x44, 0x5c, 0x43, 0x22, - 0x00, 0x3a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x40, 0x62, 0x83, 0x40, 0xd1, 0x75, 0x01, 0x00, 0x80, 0x2c, 0x10, 0x00, - 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, - 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, - 0x02, 0x85, 0x30, 0x02, 0x50, 0x80, 0x01, 0x05, 0x52, 0x06, 0xc4, 0x46, - 0x00, 0x68, 0x8d, 0x25, 0x38, 0x02, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, - 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, - 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, - 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, - 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, - 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, - 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, - 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, - 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, - 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, - 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, - 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, - 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, - 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, - 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, - 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, - 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, - 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, - 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, - 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, - 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, - 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, - 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, - 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, - 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, - 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, - 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, - 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, - 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, - 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, - 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, - 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, - 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, - 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, - 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, - 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, - 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, - 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, - 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, - 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0xb4, 0x00, - 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, - 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x36, 0x0c, 0x6f, 0x00, 0x00, 0x8b, 0xe2, - 0x06, 0xc5, 0xc6, 0x91, 0x01, 0x13, 0x19, 0x0c, 0xe2, 0x14, 0x09, 0x24, - 0x79, 0x86, 0xf2, 0x20, 0xd1, 0x85, 0x28, 0x09, 0x00, 0x00, 0x53, 0x44, - 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, - 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, - 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x20, 0x28, - 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, - 0x31, 0x2e, 0x34, 0x33, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, - 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, - 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, - 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, - 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, - 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, - 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x73, 0x69, - 0x7a, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x53, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, - 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x61, 0x69, 0x72, 0x2e, - 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, - 0x5f, 0x5f, 0x61, 0x69, 0x72, 0x5f, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, - 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x5f, 0x29, 0x66, 0x6c, 0x6f, 0x61, - 0x74, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, - 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, - 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, - 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x23, 0x08, 0x4a, 0x30, 0x82, 0xb0, - 0x24, 0x23, 0x08, 0x8a, 0x30, 0x82, 0xa0, 0x0c, 0x23, 0x08, 0x0a, 0x31, - 0x82, 0x80, 0x00, 0x23, 0x08, 0x4a, 0x31, 0x82, 0xa0, 0x18, 0x23, 0x08, - 0xca, 0x31, 0xc3, 0xc0, 0x05, 0xdd, 0x0c, 0x83, 0x27, 0x7c, 0x33, 0x04, - 0xc3, 0x0c, 0x03, 0xc7, 0x81, 0xc1, 0x0c, 0x04, 0xe1, 0x79, 0x60, 0x30, - 0x43, 0x50, 0xcc, 0x10, 0x18, 0x33, 0x04, 0xc7, 0x0c, 0x05, 0x92, 0x28, - 0x0b, 0x33, 0x43, 0xd1, 0x24, 0xce, 0xf2, 0xcc, 0x20, 0xb4, 0x81, 0x1b, - 0xcc, 0xa0, 0x80, 0x01, 0x14, 0x81, 0x81, 0x27, 0x25, 0xd3, 0xc2, 0xcc, - 0x00, 0x79, 0x54, 0x25, 0x06, 0x11, 0xe7, 0x59, 0x97, 0x18, 0x60, 0x63, - 0x90, 0x64, 0x8b, 0x36, 0x03, 0xc4, 0x51, 0x95, 0x18, 0x44, 0x64, 0xe0, - 0x59, 0x97, 0x18, 0x60, 0x63, 0x90, 0x64, 0xcb, 0x36, 0xc3, 0x00, 0x07, - 0x71, 0x20, 0x07, 0x33, 0x0c, 0x61, 0xf0, 0x06, 0x73, 0x20, 0x23, 0x81, - 0x09, 0xba, 0x88, 0x8d, 0xcd, 0xae, 0xcd, 0xa5, 0xed, 0x8d, 0xac, 0x8e, - 0xad, 0xcc, 0xc5, 0x8c, 0x2d, 0xec, 0x6c, 0x6e, 0x14, 0x81, 0x0c, 0xca, - 0xe0, 0x14, 0x36, 0x36, 0xbb, 0x36, 0x97, 0x34, 0xb2, 0x32, 0x37, 0xba, - 0x51, 0x02, 0x33, 0xb8, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x6e, - 0x2e, 0xed, 0xcd, 0x6d, 0x94, 0xe0, 0x0c, 0x8e, 0x0a, 0x4b, 0x93, 0x73, - 0x61, 0x0b, 0x73, 0x3b, 0xab, 0x0b, 0x3b, 0x2b, 0xfb, 0xb2, 0x2b, 0x93, - 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0x40, 0x83, 0x9b, 0xc2, 0xd2, 0xe4, - 0x5c, 0xc6, 0xde, 0xda, 0xe0, 0xd2, 0xd8, 0xca, 0xbe, 0xde, 0xe0, 0xe8, - 0xd2, 0xde, 0xdc, 0xe6, 0x46, 0x19, 0xd2, 0x40, 0x0d, 0xd6, 0xe0, 0x94, - 0xb0, 0x34, 0x39, 0x17, 0xbb, 0x32, 0x39, 0xba, 0x32, 0xbc, 0x51, 0x82, - 0x39, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, - 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, - 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, - 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, - 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, - 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, - 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x13, 0x04, - 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xc4, 0x4a, - 0xa0, 0x0c, 0x8a, 0x80, 0xdc, 0x08, 0xc0, 0x58, 0x44, 0x10, 0x04, 0xc1, - 0x58, 0x84, 0x20, 0x08, 0xc2, 0x58, 0xc4, 0x30, 0x0c, 0x03, 0x81, 0x31, - 0x02, 0x10, 0x04, 0x41, 0xfc, 0xa3, 0x30, 0x03, 0x40, 0x62, 0x06, 0x80, - 0xc6, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, - 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, - 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, - 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, - 0x00, 0x00, 0x13, 0x04, 0x06, 0xd9, 0x10, 0xd8, 0xc1, 0x86, 0xa1, 0x0e, - 0xf0, 0xe0, 0x0e, 0x36, 0x0c, 0x79, 0x90, 0x07, 0x77, 0x00, 0xbb, 0x10, - 0x0c, 0x44, 0x41, 0x14, 0x84, 0xb2, 0x0b, 0xf1, 0x48, 0x96, 0x44, 0x41, - 0x28, 0x83, 0x0c, 0xc3, 0xc1, 0x98, 0x10, 0x88, 0xff, 0x2e, 0xc4, 0x64, - 0x69, 0x11, 0x05, 0xa1, 0x0c, 0x32, 0x1c, 0xcb, 0x63, 0x42, 0x20, 0xfe, - 0x16, 0x14, 0xe0, 0xbf, 0x0b, 0x81, 0x6d, 0x1f, 0x45, 0x41, 0x28, 0x83, - 0x0c, 0x0c, 0x34, 0x99, 0x10, 0x88, 0xbf, 0x15, 0x01, 0xf8, 0xef, 0x42, - 0x74, 0x60, 0x40, 0x06, 0x1a, 0x05, 0xa1, 0x0c, 0x32, 0x44, 0xd5, 0x65, - 0x42, 0x20, 0xfe, 0x56, 0x04, 0xe0, 0xbf, 0x0b, 0x11, 0x06, 0x65, 0x90, - 0x06, 0x60, 0x40, 0x41, 0x28, 0x83, 0x0c, 0x81, 0xf6, 0x59, 0x50, 0x89, - 0xff, 0x20, 0xc3, 0xc0, 0x81, 0x81, 0x05, 0x93, 0xf8, 0xdb, 0x10, 0x80, - 0xff, 0x20, 0x83, 0xf1, 0x89, 0x81, 0x05, 0x91, 0xf8, 0xdb, 0x10, 0x80, - 0xff, 0x20, 0x43, 0x22, 0x06, 0x64, 0x60, 0xc1, 0x23, 0xfe, 0x36, 0x04, - 0xe0, 0xbf, 0x0b, 0xe1, 0x06, 0x72, 0x60, 0x07, 0x6c, 0x40, 0x41, 0x28, - 0x83, 0x0c, 0xc1, 0x19, 0xb0, 0x81, 0x05, 0x62, 0x20, 0xfe, 0x83, 0x0c, - 0x43, 0x1a, 0xb4, 0x81, 0x05, 0x60, 0x20, 0xfe, 0x83, 0x0c, 0xc5, 0x1a, - 0xb8, 0x81, 0x05, 0x9d, 0xf8, 0x0f, 0x32, 0x1c, 0x6d, 0xf0, 0x06, 0x16, - 0x68, 0xe2, 0x3f, 0xc8, 0xa0, 0x07, 0x6d, 0x40, 0x07, 0x96, 0x05, 0xe2, - 0x3f, 0xc8, 0xc0, 0x07, 0x6f, 0x50, 0x07, 0xe6, 0x04, 0xe2, 0x6f, 0xc9, - 0x00, 0xfe, 0x16, 0x30, 0xe0, 0x6f, 0x41, 0x02, 0xfe, 0x16, 0x20, 0xe0, - 0x6f, 0x41, 0x01, 0xfe, 0xb3, 0x0d, 0x77, 0x10, 0x00, 0xb3, 0x0d, 0x81, - 0x1e, 0x04, 0x19, 0x04, 0xc4, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, - 0x20, 0xc8, 0x83, 0x2d, 0xc3, 0x10, 0xe4, 0xc1, 0x96, 0xe1, 0x08, 0xf2, - 0x60, 0xcb, 0xc0, 0x04, 0x79, 0xb0, 0x65, 0x88, 0x82, 0x3c, 0xd8, 0x32, - 0x58, 0x41, 0x1e, 0x6c, 0x19, 0xc6, 0x20, 0xc8, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, - 0x10, 0x22, 0x84, 0x00, 0x82, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, - 0x94, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x12, 0x03, 0x94, 0x78, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, - 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, - 0x65, 0x78, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x61, 0x69, - 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, - 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, - 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, - 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xcc, 0x0c, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, - 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0xf9, 0x02, - 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, - 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, - 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, - 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, - 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, - 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, - 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, - 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x85, 0x00, - 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, - 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, - 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, - 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, - 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, - 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, - 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, - 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, - 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, - 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, - 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, - 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, - 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, - 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, - 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, - 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, - 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, - 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, - 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, - 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, - 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, - 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, - 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, - 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, - 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, - 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, - 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, - 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, - 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, - 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, - 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, - 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, - 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, - 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, - 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, - 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, - 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, - 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, - 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, - 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, - 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, - 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, - 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x2c, 0xc2, 0x00, 0x24, 0xc0, - 0x02, 0x54, 0x41, 0x1a, 0x80, 0xc2, 0x86, 0x65, 0x20, 0x80, 0x04, 0x58, - 0x80, 0x2a, 0x48, 0x03, 0x50, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, - 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, - 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, - 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, - 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x56, 0x08, 0x22, - 0x09, 0xc2, 0x4c, 0xd4, 0x3c, 0xd0, 0x83, 0x3c, 0xd4, 0xc3, 0x38, 0xd0, - 0x83, 0x1b, 0xb4, 0x43, 0x39, 0xd0, 0x43, 0x38, 0xb0, 0x83, 0x1e, 0xe8, - 0x41, 0x3b, 0x84, 0x03, 0x3d, 0xc8, 0x43, 0x3a, 0xe0, 0x03, 0x0a, 0xc8, - 0x20, 0x42, 0x21, 0x94, 0x62, 0x08, 0x61, 0x0c, 0x9d, 0x81, 0x80, 0x39, - 0x02, 0x30, 0x48, 0x01, 0x35, 0x47, 0x00, 0x0a, 0x83, 0x08, 0x81, 0x30, - 0x8c, 0x40, 0x28, 0x23, 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, - 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, - 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, - 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, - 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, - 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, - 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, - 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, - 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, - 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, - 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, + 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, + 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, + 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, + 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, + 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, + 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, + 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, + 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, + 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, + 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, + 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, + 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, + 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, + 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, + 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, + 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, + 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, + 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, + 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, + 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, + 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, + 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, + 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, + 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, + 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, + 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, + 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x2c, 0xc2, 0x00, + 0x24, 0xc0, 0x02, 0x54, 0x41, 0x1a, 0x80, 0xc2, 0x86, 0x65, 0x20, 0x80, + 0x04, 0x58, 0x80, 0x2a, 0x48, 0x03, 0x50, 0x00, 0x49, 0x18, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, + 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x60, 0x87, 0x10, 0xc0, 0x30, + 0x82, 0x00, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, + 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, + 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, + 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x52, 0x88, 0x11, 0x8c, 0xa1, 0x33, + 0x10, 0x30, 0x47, 0x00, 0x06, 0x29, 0xa0, 0xe6, 0x08, 0x40, 0x61, 0x10, + 0x21, 0x10, 0x86, 0x11, 0x08, 0x65, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, + 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, + 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, + 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, + 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, - 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, - 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, - 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, - 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, - 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, - 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, - 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, - 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, - 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, - 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, - 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, - 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, - 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, - 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, - 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, - 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, - 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, - 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, - 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, - 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, - 0x43, 0x3e, 0x6c, 0x57, 0xfe, 0x9c, 0xf3, 0x60, 0x7f, 0x45, 0x44, 0x13, - 0x71, 0x0d, 0x89, 0x80, 0xe7, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x89, 0x0d, 0x02, 0x45, 0xf7, 0x05, 0x00, 0x00, - 0xb2, 0x40, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, - 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, - 0x02, 0x85, 0x30, 0x02, 0x50, 0x80, 0x01, 0x05, 0x52, 0x06, 0xc4, 0x46, - 0x00, 0x68, 0x8d, 0x25, 0x38, 0x02, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, - 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, - 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, - 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, - 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, - 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, - 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, - 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, - 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, - 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, - 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, - 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, - 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, - 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, - 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, - 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, - 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, - 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, - 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, - 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, - 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, - 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, - 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, - 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, - 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, - 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, - 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, - 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, - 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, - 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, - 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, - 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, - 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, - 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, - 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, - 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, - 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, - 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, - 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, - 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0xc7, 0x00, - 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, - 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x36, 0xcc, 0x75, 0x00, 0x00, 0x8b, 0xe2, - 0x06, 0xc5, 0xc6, 0x91, 0x01, 0x13, 0x19, 0x0c, 0x12, 0x65, 0x06, 0x02, - 0x49, 0x9e, 0xf2, 0x20, 0xd1, 0x85, 0x28, 0x09, 0x00, 0x00, 0x53, 0x44, - 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, - 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, - 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x20, 0x28, - 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, - 0x31, 0x2e, 0x34, 0x33, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, + 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, + 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, + 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, + 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, + 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, + 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, + 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, + 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, + 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, + 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, + 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, + 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, + 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, + 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, + 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, + 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, + 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, + 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, + 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, + 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, + 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, + 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, + 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x42, 0x6c, 0x57, 0xfe, 0xac, + 0xb3, 0x20, 0xc3, 0x5f, 0x11, 0xd1, 0x44, 0x5c, 0x43, 0x22, 0x00, 0x3a, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x62, + 0x83, 0x40, 0xd1, 0x85, 0x01, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, + 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, 0x02, 0x85, + 0x30, 0x02, 0x50, 0x80, 0x01, 0x05, 0x52, 0x06, 0xc4, 0x46, 0x00, 0x68, + 0x8d, 0x25, 0x38, 0x03, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, + 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, + 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, + 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, + 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, + 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, + 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, + 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, + 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, + 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, + 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, + 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, + 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, + 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, + 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, + 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, + 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, + 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, + 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, + 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, + 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, + 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, + 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, + 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, + 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, + 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, + 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, + 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, + 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, + 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, + 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, + 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, + 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, + 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, + 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, + 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, + 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, + 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, + 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, + 0x32, 0x64, 0xd4, 0x3c, 0xcc, 0x7c, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, + 0xc6, 0x91, 0x01, 0x13, 0x19, 0x0c, 0x12, 0x59, 0x85, 0x53, 0x24, 0x90, + 0xe4, 0x19, 0xca, 0x83, 0x44, 0x17, 0xa2, 0x24, 0x53, 0x44, 0x4b, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, + 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, + 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, + 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, @@ -542,498 +275,775 @@ const unsigned char sdl_metallib[] = { 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, - 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, - 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, - 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x64, 0x28, 0x5f, 0x5f, 0x61, 0x69, 0x72, 0x5f, 0x70, 0x6c, - 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x5f, 0x29, - 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, - 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, - 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, - 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x66, 0x6f, 0x72, 0x6d, 0x00, 0x00, 0x04, 0x4a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x82, 0xa0, 0x04, 0x23, 0x08, 0x4b, 0x32, 0x82, 0xa0, - 0x08, 0x23, 0x08, 0xca, 0x30, 0x82, 0xa0, 0x10, 0x23, 0x08, 0x08, 0x30, - 0x82, 0xa0, 0x14, 0x23, 0x08, 0x8a, 0x31, 0x82, 0xa0, 0x1c, 0x33, 0x0c, - 0x5c, 0xd0, 0xcd, 0x30, 0x78, 0xc2, 0x37, 0x43, 0x30, 0xcc, 0x30, 0x70, - 0x1c, 0x18, 0xcc, 0x40, 0x10, 0x9e, 0x07, 0x06, 0x33, 0x04, 0xc5, 0x0c, - 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x89, 0xb2, 0x30, 0x33, 0x18, - 0x8d, 0x93, 0x3c, 0x0b, 0x34, 0x83, 0xd0, 0x06, 0x6e, 0x30, 0x83, 0x02, - 0x06, 0x91, 0x04, 0x06, 0xde, 0x94, 0x3c, 0x0b, 0x33, 0x83, 0xe2, 0x45, - 0x92, 0xe7, 0x4d, 0xc9, 0xb3, 0x40, 0x33, 0x40, 0x1c, 0x55, 0x89, 0x81, - 0xc4, 0x79, 0xd6, 0x25, 0x06, 0xd8, 0x18, 0x24, 0xd9, 0xa2, 0xcd, 0x00, - 0x91, 0x01, 0x55, 0x89, 0x81, 0x44, 0x06, 0x9e, 0x75, 0x89, 0x01, 0x36, - 0x06, 0x49, 0xb6, 0x6c, 0x33, 0x10, 0x70, 0x10, 0x07, 0x72, 0x30, 0x07, - 0x33, 0x0c, 0x61, 0xf0, 0x06, 0x74, 0x50, 0x1a, 0xc0, 0x71, 0x1c, 0xc7, - 0x71, 0x1c, 0xc7, 0x89, 0x81, 0x18, 0x58, 0x68, 0xe0, 0x06, 0x96, 0x65, - 0xb9, 0x01, 0x1d, 0xa0, 0x01, 0x2e, 0xb0, 0x82, 0x48, 0xb8, 0x04, 0x28, - 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, - 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, - 0x20, 0x83, 0x32, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, - 0xcc, 0x8d, 0x6e, 0x94, 0xc0, 0x0c, 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, - 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0x38, 0x83, 0xa3, 0xc2, - 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, - 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xd0, 0xe0, 0xa6, - 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, - 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x86, 0x34, 0x50, 0x83, - 0x35, 0x38, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x8e, 0xae, 0x0c, - 0x6f, 0x94, 0x80, 0x0e, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, - 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, - 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, - 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, - 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, - 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, - 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, - 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x65, 0x00, - 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x00, 0x00, 0xc4, 0x4a, 0xa0, 0x0c, 0x8a, 0x80, 0xdc, 0x08, 0xc0, 0x58, - 0x44, 0x10, 0x04, 0xc1, 0x58, 0x84, 0x20, 0x08, 0xc2, 0x58, 0xc4, 0x30, - 0x0c, 0x03, 0x85, 0x19, 0x00, 0x12, 0x33, 0x00, 0x34, 0x66, 0x00, 0x00, - 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, - 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, - 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, - 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, - 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, - 0x06, 0xd9, 0x10, 0xdc, 0xc1, 0x86, 0xc1, 0x0e, 0xf2, 0x00, 0x0f, 0x36, - 0x0c, 0x7a, 0xa0, 0x07, 0x78, 0x00, 0xbb, 0x10, 0x0b, 0x44, 0x41, 0x14, - 0x84, 0xb2, 0x0b, 0xe1, 0x48, 0x96, 0x44, 0x41, 0x28, 0x83, 0x0c, 0xc3, - 0xb1, 0x98, 0x10, 0x88, 0xff, 0x2e, 0x84, 0x64, 0x69, 0x10, 0x05, 0xa1, - 0x0c, 0x32, 0x1c, 0x8b, 0x63, 0x42, 0x20, 0xfe, 0x16, 0x14, 0xe0, 0xbf, - 0x0b, 0x71, 0x6d, 0xdf, 0x44, 0x41, 0x28, 0x83, 0x0c, 0x0c, 0x24, 0x99, - 0x10, 0x88, 0xbf, 0x15, 0x01, 0xf8, 0xef, 0x42, 0x70, 0x60, 0x40, 0x06, - 0x19, 0x05, 0xa1, 0x0c, 0x32, 0x44, 0x95, 0x65, 0x42, 0x20, 0xfe, 0x56, - 0x04, 0xe0, 0xbf, 0x0b, 0x01, 0x06, 0x65, 0x90, 0x06, 0x1f, 0x05, 0xa1, - 0x0c, 0x32, 0x04, 0x9a, 0x67, 0x41, 0x25, 0xfe, 0x83, 0x0c, 0x03, 0xf7, - 0x59, 0x30, 0x89, 0xbf, 0x0d, 0x01, 0xf8, 0x0f, 0x32, 0x18, 0x5f, 0x18, - 0x58, 0x10, 0x89, 0xbf, 0x0d, 0x01, 0xf8, 0x0f, 0x32, 0x24, 0x62, 0x30, - 0x06, 0x16, 0x3c, 0xe2, 0x6f, 0x43, 0x00, 0xfe, 0xbb, 0x10, 0x6d, 0x20, - 0x07, 0x76, 0xb0, 0x06, 0x14, 0x84, 0x32, 0xc8, 0x10, 0x9c, 0xc1, 0x1a, - 0x58, 0x20, 0x06, 0xe2, 0x3f, 0xc8, 0x30, 0xa4, 0x01, 0x1b, 0x58, 0x00, - 0x06, 0xe2, 0x3f, 0xc8, 0x50, 0xac, 0x41, 0x1b, 0x58, 0xd0, 0x89, 0xff, - 0x20, 0xc3, 0xd1, 0x06, 0x6e, 0x60, 0x81, 0x26, 0xfe, 0x83, 0x0c, 0x7a, - 0xe0, 0x06, 0x73, 0x60, 0x59, 0x20, 0xfe, 0x83, 0x0c, 0x7c, 0x00, 0x07, - 0x74, 0x60, 0x4e, 0x20, 0xfe, 0x96, 0x0c, 0xe0, 0x6f, 0x01, 0x03, 0xfe, - 0x16, 0x24, 0xe0, 0x6f, 0x01, 0x02, 0xfe, 0x16, 0x14, 0xe0, 0x3f, 0xdb, - 0x60, 0x07, 0x01, 0x30, 0xdb, 0x10, 0x8c, 0x42, 0x90, 0x41, 0x40, 0x0c, - 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xd0, 0x83, 0x2d, - 0xc3, 0x10, 0xe8, 0xc1, 0x96, 0xe1, 0x08, 0xf4, 0x60, 0xcb, 0xc0, 0x04, - 0x7a, 0xb0, 0x65, 0x88, 0x02, 0x3d, 0xd8, 0x32, 0x58, 0x81, 0x1e, 0x6c, - 0x19, 0xc6, 0x20, 0xd0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, - 0x94, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, - 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, - 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x03, - 0x94, 0x77, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, - 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x33, 0x31, 0x30, - 0x30, 0x31, 0x2e, 0x34, 0x33, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, - 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, 0x33, 0x2e, - 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, - 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x70, 0x0a, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, - 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x61, 0x02, 0x00, 0x00, 0x0b, 0x02, - 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, - 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, - 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, - 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, - 0x18, 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, - 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x11, 0x22, - 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, - 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x1b, 0xcc, - 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0x03, 0x40, 0x02, 0x2a, - 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, - 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, - 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, - 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, - 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, - 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, - 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, - 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, - 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, - 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, - 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, - 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, - 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, - 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, - 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, - 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, - 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, - 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, - 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, - 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, - 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, - 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, - 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, - 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, - 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, - 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, - 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, - 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, - 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, - 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, - 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, - 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, - 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, - 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, - 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, - 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x01, 0x90, 0x00, 0x0b, 0x50, - 0x05, 0x69, 0x00, 0x01, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, 0x00, 0x00, 0x0e, 0x00, - 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x22, - 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, - 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x28, 0x33, 0x00, 0xc3, 0x08, - 0x04, 0x30, 0x88, 0x10, 0x04, 0x45, 0x08, 0xa1, 0x19, 0x08, 0x98, 0x23, - 0x00, 0x83, 0x14, 0xb0, 0x39, 0x02, 0x50, 0x18, 0x01, 0x00, 0x13, 0xc0, - 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, - 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, - 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, - 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, - 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, - 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, - 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, - 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, - 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, + 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, + 0x5f, 0x66, 0x29, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x69, 0x72, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, + 0x61, 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x5f, 0x5f, 0x61, 0x69, + 0x72, 0x5f, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, + 0x72, 0x5f, 0x5f, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x61, 0x69, + 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, + 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, + 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x61, + 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, + 0x72, 0x6d, 0x00, 0x00, 0xc4, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x82, 0xa0, 0x04, 0x23, 0x08, 0x4b, 0x32, 0x82, 0xa0, 0x08, 0x23, + 0x08, 0xca, 0x30, 0x82, 0xa0, 0x10, 0x23, 0x08, 0x08, 0x30, 0x82, 0xa0, + 0x14, 0x23, 0x08, 0x8a, 0x31, 0x82, 0xa0, 0x1c, 0x33, 0x0c, 0x5f, 0x00, + 0x06, 0x33, 0x0c, 0x61, 0x20, 0x88, 0xc1, 0x0c, 0xc1, 0x30, 0xc3, 0xf0, + 0x7d, 0x63, 0x30, 0x03, 0x41, 0x84, 0x41, 0x18, 0x8c, 0xc1, 0x0c, 0x41, + 0x31, 0x43, 0x60, 0xcc, 0x10, 0x1c, 0x33, 0x14, 0x48, 0xa2, 0x2c, 0xcc, + 0x0c, 0x46, 0xe3, 0x24, 0xca, 0xf2, 0xcc, 0x50, 0x40, 0x49, 0xb4, 0x48, + 0x33, 0x0c, 0x70, 0x10, 0x07, 0x72, 0x30, 0x83, 0x32, 0x06, 0x13, 0x35, + 0x06, 0x61, 0x50, 0x25, 0xd6, 0xc2, 0xcc, 0xa0, 0x84, 0xc1, 0x44, 0x85, + 0x41, 0x18, 0x54, 0x89, 0xb2, 0x3c, 0x33, 0x40, 0xdf, 0x85, 0x95, 0x01, + 0xf5, 0x85, 0x41, 0xa6, 0x95, 0xc1, 0x66, 0x06, 0x09, 0xb7, 0x74, 0x33, + 0x40, 0x67, 0x70, 0x61, 0x65, 0x40, 0x9d, 0x41, 0x18, 0x64, 0x5a, 0x19, + 0x6c, 0x66, 0x90, 0x70, 0x8b, 0x37, 0x03, 0x41, 0x07, 0x75, 0x60, 0x07, + 0x77, 0x30, 0xc3, 0x40, 0x06, 0x73, 0x80, 0x07, 0xb5, 0x01, 0x1c, 0xc7, + 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0x1a, 0xb8, 0x81, 0x85, 0x06, 0x7a, 0x60, + 0x59, 0x96, 0x1b, 0xd0, 0x81, 0x1b, 0xd0, 0x81, 0x2f, 0xf8, 0x02, 0x4a, + 0xd0, 0x04, 0x28, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, + 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, + 0x9b, 0x1b, 0x45, 0x38, 0x03, 0x34, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, + 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x20, 0x0d, 0x6e, 0x09, 0x4b, + 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0x50, + 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, + 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, + 0xd6, 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, + 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x06, + 0x36, 0x68, 0x03, 0x37, 0x38, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, + 0x8e, 0xae, 0x0c, 0x6f, 0x94, 0x00, 0x0f, 0x00, 0xa9, 0x18, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, + 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, + 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, + 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, + 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, + 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, + 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, + 0x69, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0xc4, 0x4a, 0xa0, 0x0c, 0x8a, 0x80, 0xdc, 0x08, + 0xc0, 0x58, 0x44, 0x10, 0x04, 0xc1, 0x58, 0x84, 0x20, 0x08, 0xc2, 0x58, + 0xc4, 0x30, 0x0c, 0x03, 0x81, 0x31, 0x02, 0x10, 0x04, 0x41, 0xfc, 0xa3, + 0x30, 0x03, 0x40, 0x62, 0x06, 0x80, 0xc6, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, + 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, + 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, + 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, 0x06, 0xd9, + 0x10, 0xec, 0xc1, 0x86, 0x41, 0x0f, 0xfa, 0x80, 0x0f, 0x36, 0x0c, 0x7e, + 0xe0, 0x07, 0x7c, 0x00, 0xbb, 0x10, 0x4c, 0x54, 0x45, 0x14, 0x84, 0xb2, + 0x0b, 0xf1, 0x4c, 0xd7, 0x44, 0x41, 0x28, 0x83, 0x0c, 0xc3, 0xc1, 0x98, + 0x10, 0x88, 0xff, 0x2e, 0xc4, 0x74, 0x6d, 0x11, 0x05, 0xa1, 0x0c, 0x32, + 0x1c, 0xcb, 0x63, 0x42, 0x20, 0xfe, 0x16, 0x14, 0xe0, 0xbf, 0x0b, 0x81, + 0x71, 0x60, 0x40, 0x51, 0x10, 0xca, 0x20, 0x03, 0x03, 0x4d, 0x26, 0x04, + 0xe2, 0x6f, 0x45, 0x00, 0xfe, 0xbb, 0x10, 0x5d, 0x18, 0x94, 0x81, 0x46, + 0x41, 0x28, 0x83, 0x0c, 0x51, 0x75, 0x99, 0x10, 0x88, 0xbf, 0x15, 0x01, + 0xf8, 0xef, 0x42, 0x84, 0x81, 0x19, 0xa8, 0x01, 0x18, 0x50, 0x10, 0xca, + 0x20, 0x43, 0xa0, 0x7d, 0x16, 0x54, 0xe2, 0x3f, 0xc8, 0x30, 0x70, 0x60, + 0x60, 0xc1, 0x24, 0xfe, 0x36, 0x04, 0xe0, 0x3f, 0xc8, 0x60, 0x7c, 0x62, + 0x60, 0x41, 0x24, 0xfe, 0x36, 0x04, 0xe0, 0x3f, 0xc8, 0x90, 0x88, 0x01, + 0x19, 0x58, 0xf0, 0x88, 0xbf, 0x0d, 0x01, 0xf8, 0xef, 0x42, 0xb8, 0xc1, + 0x1c, 0xdc, 0x01, 0x1b, 0x50, 0x10, 0xca, 0x20, 0x43, 0x70, 0x06, 0x6c, + 0x60, 0x81, 0x18, 0x88, 0xff, 0x20, 0xc3, 0x90, 0x06, 0x6d, 0x60, 0x01, + 0x18, 0x88, 0xff, 0x20, 0x43, 0xb1, 0x06, 0x6e, 0x60, 0x41, 0x27, 0xfe, + 0x83, 0x0c, 0x47, 0x1b, 0xbc, 0x81, 0x05, 0x9a, 0xf8, 0x0f, 0x32, 0xec, + 0x41, 0x1b, 0xd0, 0x81, 0x65, 0x81, 0xf8, 0x0f, 0x32, 0xf4, 0xc1, 0x1b, + 0xd4, 0x81, 0x39, 0x81, 0xf8, 0x5b, 0x32, 0x80, 0xbf, 0x05, 0x0c, 0xf8, + 0x5b, 0x90, 0x80, 0xbf, 0x05, 0x08, 0xf8, 0x5b, 0x50, 0x80, 0xff, 0x6c, + 0xc3, 0x1d, 0x04, 0xc0, 0x6c, 0x43, 0x40, 0x0a, 0xc1, 0x6c, 0x43, 0xb0, + 0x07, 0x42, 0x06, 0x01, 0x31, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x5b, 0x86, 0x20, 0xf0, 0x83, 0x2d, 0xc3, 0x10, 0xf8, 0xc1, 0x96, 0xe1, + 0x08, 0xfc, 0x60, 0xcb, 0xc0, 0x04, 0x7e, 0xb0, 0x65, 0x88, 0x02, 0x3f, + 0xd8, 0x32, 0x58, 0x81, 0x1f, 0x6c, 0x19, 0xc6, 0x20, 0xf0, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xa0, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x7a, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, + 0x72, 0x74, 0x65, 0x78, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, + 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, + 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, + 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x14, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x0c, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, + 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, + 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, + 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, + 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, + 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, + 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, + 0x51, 0x18, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, + 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, + 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, + 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, + 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, + 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, + 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, + 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, + 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, + 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, + 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, + 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, + 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, + 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, + 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, + 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, + 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, + 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, + 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, + 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, + 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, + 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, + 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, + 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, + 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, + 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, + 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, + 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, + 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, + 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, + 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, + 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, + 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, + 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, + 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, + 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, + 0x36, 0x2c, 0x02, 0x01, 0x24, 0xc0, 0x02, 0x54, 0x41, 0x1a, 0x80, 0xc2, + 0x86, 0x65, 0x28, 0x80, 0x04, 0x58, 0x80, 0x2a, 0x48, 0x03, 0x50, 0x00, + 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, + 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, + 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, + 0x8c, 0x20, 0x00, 0x76, 0x08, 0x41, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, + 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, + 0x7a, 0x08, 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x79, 0x48, 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x62, 0x0c, + 0x11, 0x84, 0x31, 0x74, 0x06, 0x02, 0xe6, 0x08, 0xc0, 0x20, 0x05, 0xd4, + 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x04, 0xc2, 0x30, 0x02, 0xa1, 0x8c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, + 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, + 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, + 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, + 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, + 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, + 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, + 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, + 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, + 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, + 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, - 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, - 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, - 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, - 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, - 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, - 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, - 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, - 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, - 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, - 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, - 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, - 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, - 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, - 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, - 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, - 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, - 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, - 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, - 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, - 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, - 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, - 0xc8, 0x81, 0x46, 0x08, 0x43, 0x4a, 0x6c, 0x57, 0xfe, 0xac, 0xb3, 0x20, - 0xc3, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x34, 0x24, 0x02, 0xa4, 0x01, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x24, 0x36, - 0x08, 0x14, 0x1d, 0x13, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, - 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, 0x22, 0x28, 0x81, 0x42, 0x18, 0x01, - 0x28, 0x10, 0xc2, 0x11, 0x00, 0xba, 0xb1, 0x04, 0x47, 0x00, 0xb1, 0x18, - 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, - 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, - 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, - 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, - 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, - 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, - 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, - 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, - 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, - 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, - 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, - 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, - 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, - 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, - 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, - 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, - 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, - 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, - 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, - 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, - 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, - 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, - 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, - 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, - 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, - 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, - 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, - 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, - 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, - 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, - 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, - 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, - 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, - 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, - 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, - 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, - 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, - 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, - 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0x8b, 0x00, - 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, - 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x24, 0xa8, 0x54, 0x00, 0x00, 0x8b, 0xe2, - 0x06, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0xca, 0x23, 0x21, 0xd1, 0xc5, - 0x0c, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, - 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, - 0x34, 0x33, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, - 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x29, 0x4d, 0x65, 0x74, - 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, - 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, - 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, - 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, - 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, - 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, - 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, - 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, - 0x34, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, - 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, - 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, - 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, - 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, - 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, - 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x63, 0x6f, 0x6c, 0x00, - 0x00, 0x00, 0x23, 0x08, 0x46, 0x30, 0x82, 0x70, 0x1c, 0x23, 0x08, 0x86, - 0x30, 0x82, 0x60, 0x0c, 0x23, 0x08, 0x06, 0x31, 0x82, 0x40, 0x00, 0x23, - 0x08, 0x46, 0x31, 0xc3, 0x30, 0x05, 0xd4, 0x0c, 0x43, 0x25, 0x58, 0x33, - 0x04, 0xc3, 0x0c, 0xc3, 0x34, 0x5d, 0x33, 0x10, 0x44, 0x55, 0x5d, 0x33, - 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0xd7, 0x95, - 0x28, 0x33, 0x04, 0x62, 0x30, 0x03, 0x74, 0x2d, 0x4c, 0xd6, 0x5c, 0x95, - 0xf3, 0x64, 0x50, 0x96, 0x28, 0x91, 0x34, 0x43, 0x40, 0x06, 0x33, 0x0c, - 0xd8, 0x18, 0x94, 0x81, 0x8c, 0x04, 0x26, 0xe8, 0x22, 0x36, 0x36, 0xbb, - 0x36, 0x97, 0xb6, 0x37, 0xb2, 0x3a, 0xb6, 0x32, 0x17, 0x33, 0xb6, 0xb0, - 0xb3, 0xb9, 0x51, 0x84, 0x4c, 0x3b, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, - 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x60, 0xbb, 0x25, 0x2c, 0x4d, 0xce, - 0xc5, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x94, 0x80, 0x3b, 0x2a, - 0x2c, 0x4d, 0xce, 0x85, 0x2d, 0xcc, 0xed, 0xac, 0x2e, 0xec, 0xac, 0xec, - 0xcb, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x94, 0xa0, 0xbb, 0x29, - 0x2c, 0x4d, 0xce, 0x65, 0xec, 0xad, 0x0d, 0x2e, 0x8d, 0xad, 0xec, 0xeb, - 0x0d, 0x8e, 0x2e, 0xed, 0xcd, 0x6d, 0x6e, 0x94, 0xc1, 0xfb, 0xc0, 0xe0, - 0x98, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, - 0xba, 0x51, 0x82, 0x32, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, - 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, - 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, - 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, - 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, - 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, - 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, - 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x13, 0x04, 0x41, 0x3c, 0x0c, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, - 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, - 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, - 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, - 0x00, 0x00, 0x13, 0x04, 0xc4, 0xd8, 0x10, 0xa0, 0xc1, 0x86, 0xe1, 0x0c, - 0xd4, 0x20, 0x0d, 0x36, 0x0c, 0x6b, 0xb0, 0x06, 0x69, 0x00, 0x14, 0x44, - 0xc9, 0x20, 0x20, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x06, - 0x20, 0x58, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, - 0xc7, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, - 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, - 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x03, - 0x94, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, - 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, - 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x61, 0x69, 0x72, 0x36, + 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, + 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, + 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, + 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, + 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, + 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, + 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, + 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, + 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, + 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, + 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, + 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, + 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, + 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, + 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, + 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, + 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x3e, + 0x6c, 0x57, 0xfe, 0x9c, 0xf3, 0x60, 0x7f, 0x45, 0x44, 0x13, 0x71, 0x0d, + 0x89, 0x80, 0xe7, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x0d, 0x02, 0x45, 0x19, 0x06, 0x00, 0x00, 0xb2, 0x40, + 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, + 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, 0x02, 0x85, + 0x30, 0x02, 0x50, 0x06, 0x05, 0x18, 0x50, 0x20, 0xc4, 0x46, 0x00, 0x68, + 0x8d, 0x25, 0x38, 0x03, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, + 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, + 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, + 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, + 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, + 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, + 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, + 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, + 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, + 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, + 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, + 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, + 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, + 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, + 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, + 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, + 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, + 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, + 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, + 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, + 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, + 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, + 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, + 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, + 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, + 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, + 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, + 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, + 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, + 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, + 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, + 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, + 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, + 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, + 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, + 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, + 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, + 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, + 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, + 0x32, 0x64, 0xd4, 0x3a, 0x6c, 0x7d, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, + 0xc6, 0x91, 0x01, 0x13, 0x19, 0x0c, 0x12, 0x59, 0x45, 0x66, 0x20, 0x90, + 0xe4, 0x29, 0x0f, 0x12, 0x5d, 0x88, 0x92, 0x00, 0x53, 0x44, 0x4b, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, + 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, + 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, + 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, + 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, + 0x5f, 0x66, 0x29, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, + 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, + 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x5f, 0x5f, 0x61, 0x69, 0x72, + 0x5f, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, + 0x5f, 0x5f, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x00, 0x04, 0x58, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0xa0, 0x04, 0x23, 0x08, 0x4b, 0x32, + 0x82, 0xa0, 0x08, 0x23, 0x08, 0xca, 0x30, 0x82, 0xa0, 0x10, 0x23, 0x08, + 0x08, 0x30, 0x82, 0xa0, 0x14, 0x23, 0x08, 0x8a, 0x31, 0x82, 0xa0, 0x1c, + 0x33, 0x0c, 0x5e, 0xf0, 0xcd, 0x30, 0x80, 0x81, 0x10, 0x06, 0x33, 0x04, + 0xc3, 0x0c, 0x83, 0xe7, 0x89, 0xc1, 0x0c, 0x04, 0x01, 0x06, 0x60, 0x20, + 0x06, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, + 0x89, 0xb2, 0x30, 0x33, 0x18, 0x8d, 0x93, 0x28, 0xcb, 0x33, 0x83, 0xd1, + 0x40, 0x49, 0xb4, 0x48, 0x33, 0x0c, 0x6f, 0x00, 0x07, 0x71, 0x30, 0x83, + 0x22, 0x06, 0x13, 0x25, 0x06, 0x60, 0x50, 0x25, 0xd1, 0xc2, 0xcc, 0xa0, + 0x80, 0xc1, 0x44, 0x81, 0x01, 0x18, 0x54, 0x89, 0xb2, 0x3c, 0x33, 0x28, + 0xde, 0x44, 0x79, 0x60, 0x50, 0x25, 0xd1, 0x22, 0xcd, 0x00, 0x91, 0x81, + 0x75, 0x95, 0x01, 0xe5, 0x81, 0x01, 0x96, 0x95, 0x81, 0x66, 0x06, 0xc9, + 0xb6, 0x70, 0x33, 0x40, 0x61, 0x60, 0x5d, 0x65, 0x40, 0x91, 0x01, 0x18, + 0x60, 0x59, 0x19, 0x68, 0x66, 0x90, 0x6c, 0x4b, 0x37, 0x43, 0x31, 0x07, + 0x74, 0x50, 0x07, 0x76, 0x70, 0x07, 0x33, 0x0c, 0x63, 0x20, 0x07, 0x78, + 0x50, 0x1c, 0xc0, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x89, 0x81, 0x1b, + 0x58, 0x68, 0xa0, 0x07, 0x96, 0x65, 0xb9, 0x01, 0x1d, 0xd0, 0x01, 0x1d, + 0xf8, 0x82, 0x2f, 0xc8, 0x82, 0x4b, 0xd0, 0x04, 0x2b, 0xc8, 0x48, 0x60, + 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, + 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0x30, 0x83, 0x33, + 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, + 0x94, 0x00, 0x0d, 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, + 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0x48, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, + 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, + 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xd4, 0xe0, 0xa6, 0xb0, 0x34, 0x39, + 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, + 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x86, 0x35, 0x60, 0x83, 0x36, 0x38, 0x25, + 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x8e, 0xae, 0x0c, 0x6f, 0x94, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0xc4, 0x4a, 0xa0, 0x0c, 0x8a, 0x80, 0xdc, 0x08, 0xc0, 0x58, 0x44, 0x10, + 0x04, 0xc1, 0x58, 0x84, 0x20, 0x08, 0xc2, 0x58, 0xc4, 0x30, 0x0c, 0x03, + 0x85, 0x19, 0x00, 0x12, 0x33, 0x00, 0x34, 0x66, 0x00, 0x00, 0x00, 0x00, + 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, + 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, + 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, + 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, 0x06, 0xd9, + 0x10, 0xec, 0xc1, 0x86, 0x41, 0x0f, 0xfa, 0x80, 0x0f, 0x36, 0x0c, 0x7e, + 0xe0, 0x07, 0x7c, 0x00, 0xbb, 0x10, 0x4b, 0x54, 0x45, 0x14, 0x84, 0xb2, + 0x0b, 0xe1, 0x4c, 0xd7, 0x44, 0x41, 0x28, 0x83, 0x0c, 0xc3, 0xb1, 0x98, + 0x10, 0x88, 0xff, 0x2e, 0x84, 0x74, 0x6d, 0x10, 0x05, 0xa1, 0x0c, 0x32, + 0x1c, 0x8b, 0x63, 0x42, 0x20, 0xfe, 0x16, 0x14, 0xe0, 0xbf, 0x0b, 0x71, + 0x71, 0x60, 0x30, 0x51, 0x10, 0xca, 0x20, 0x03, 0x03, 0x49, 0x26, 0x04, + 0xe2, 0x6f, 0x45, 0x00, 0xfe, 0xbb, 0x10, 0x5c, 0x18, 0x94, 0x41, 0x46, + 0x41, 0x28, 0x83, 0x0c, 0x51, 0x65, 0x99, 0x10, 0x88, 0xbf, 0x15, 0x01, + 0xf8, 0xef, 0x42, 0x80, 0x81, 0x19, 0xa8, 0xc1, 0x47, 0x41, 0x28, 0x83, + 0x0c, 0x81, 0xe6, 0x59, 0x50, 0x89, 0xff, 0x20, 0xc3, 0xc0, 0x7d, 0x16, + 0x4c, 0xe2, 0x6f, 0x43, 0x00, 0xfe, 0x83, 0x0c, 0xc6, 0x17, 0x06, 0x16, + 0x44, 0xe2, 0x6f, 0x43, 0x00, 0xfe, 0x83, 0x0c, 0x89, 0x18, 0x8c, 0x81, + 0x05, 0x8f, 0xf8, 0xdb, 0x10, 0x80, 0xff, 0x2e, 0x44, 0x1b, 0xcc, 0xc1, + 0x1d, 0xac, 0x01, 0x05, 0xa1, 0x0c, 0x32, 0x04, 0x67, 0xb0, 0x06, 0x16, + 0x88, 0x81, 0xf8, 0x0f, 0x32, 0x0c, 0x69, 0xc0, 0x06, 0x16, 0x80, 0x81, + 0xf8, 0x0f, 0x32, 0x14, 0x6b, 0xd0, 0x06, 0x16, 0x74, 0xe2, 0x3f, 0xc8, + 0x70, 0xb4, 0x81, 0x1b, 0x58, 0xa0, 0x89, 0xff, 0x20, 0xc3, 0x1e, 0xb8, + 0xc1, 0x1c, 0x58, 0x16, 0x88, 0xff, 0x20, 0x43, 0x1f, 0xc0, 0x01, 0x1d, + 0x98, 0x13, 0x88, 0xbf, 0x25, 0x03, 0xf8, 0x5b, 0xc0, 0x80, 0xbf, 0x05, + 0x09, 0xf8, 0x5b, 0x80, 0x80, 0xbf, 0x05, 0x05, 0xf8, 0xcf, 0x36, 0xd8, + 0x41, 0x00, 0xcc, 0x36, 0x04, 0xa4, 0x10, 0xcc, 0x36, 0x04, 0xa4, 0x20, + 0x64, 0x10, 0x10, 0x03, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xf0, + 0x83, 0x2d, 0xc3, 0x10, 0xf8, 0xc1, 0x96, 0xe1, 0x08, 0xfc, 0x60, 0xcb, + 0xc0, 0x04, 0x7e, 0xb0, 0x65, 0x88, 0x02, 0x3f, 0xd8, 0x32, 0x58, 0x81, + 0x1f, 0x6c, 0x19, 0xc6, 0x20, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, + 0x84, 0x00, 0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x0c, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x79, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x33, + 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, + 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, + 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, + 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18, 0x0a, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, + 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x4b, 0x02, 0x00, 0x00, + 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, + 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, + 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, + 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, + 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, + 0x11, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, + 0x04, 0x21, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, + 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0x03, 0x40, + 0x02, 0x28, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, + 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, + 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, + 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, + 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, + 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, + 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, + 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, + 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, + 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, + 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, + 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, + 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, + 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, + 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, + 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, + 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, + 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, + 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, + 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, + 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, + 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, + 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, + 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, + 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, + 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, + 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, + 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, + 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, + 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, + 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, + 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0x40, 0x08, 0x02, 0x60, 0x01, + 0x49, 0x18, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, + 0x10, 0x24, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x65, + 0x08, 0x09, 0x9a, 0x81, 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x1b, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, + 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, + 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, + 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, + 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, + 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, + 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, + 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, + 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, + 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, + 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, + 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, + 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, + 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, + 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, + 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, + 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, + 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, + 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, + 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, + 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, + 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, + 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, + 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, + 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, + 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, + 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, + 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, + 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x4a, + 0x6c, 0x57, 0xfe, 0xac, 0xb3, 0x20, 0xc3, 0x5f, 0x44, 0x80, 0xc1, 0x10, + 0xcd, 0x34, 0x24, 0x02, 0xa4, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x36, 0x08, 0x14, 0x6d, 0x12, 0x00, 0x00, + 0xc8, 0x02, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x0c, + 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, + 0x22, 0x28, 0x81, 0x42, 0x18, 0x01, 0xa0, 0x1b, 0x4b, 0x70, 0x06, 0x00, + 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, + 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, + 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, + 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, + 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, + 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, + 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, + 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, + 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, + 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, + 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, + 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, + 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, + 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, + 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, + 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, + 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, + 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, + 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, + 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, + 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, + 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, + 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, + 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, + 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, + 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, + 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, + 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, + 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, + 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, + 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, + 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, + 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, + 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, + 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, + 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, + 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x26, 0xc8, 0x56, 0x00, 0x00, + 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x52, 0xa6, 0x3c, + 0x06, 0x83, 0x58, 0x05, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, + 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, + 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, + 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x69, + 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x61, + 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x23, 0x08, 0x46, 0x30, + 0x82, 0x70, 0x14, 0x23, 0x08, 0x86, 0x30, 0x82, 0x60, 0x0c, 0x23, 0x08, + 0x06, 0x31, 0x82, 0x40, 0x00, 0x33, 0x0c, 0x54, 0x50, 0xcd, 0x30, 0x58, + 0xc2, 0x35, 0x43, 0x30, 0xcc, 0x30, 0x50, 0x14, 0x36, 0x03, 0x41, 0x58, + 0x16, 0x36, 0x43, 0x50, 0xcc, 0x10, 0x18, 0x33, 0x04, 0xc7, 0x0c, 0x05, + 0x82, 0x61, 0x89, 0x32, 0x43, 0x20, 0x06, 0x33, 0x24, 0xd8, 0xc2, 0x34, + 0x4e, 0xf2, 0x40, 0xd1, 0x0c, 0x89, 0xb5, 0x48, 0x8d, 0x93, 0x28, 0xd0, + 0x34, 0x83, 0x40, 0x06, 0x65, 0x30, 0xc3, 0x90, 0x8d, 0x81, 0x19, 0xc8, + 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, + 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0xc8, + 0xb4, 0x53, 0xd8, 0xd8, 0xec, 0xda, 0x5c, 0xd2, 0xc8, 0xca, 0xdc, 0xe8, + 0x46, 0x09, 0xb6, 0x5b, 0xc2, 0xd2, 0xe4, 0x5c, 0xec, 0xca, 0xe4, 0xe6, + 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xb8, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, + 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, + 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xba, 0x9b, 0xc2, 0xd2, 0xe4, 0x5c, 0xc6, + 0xde, 0xda, 0xe0, 0xd2, 0xd8, 0xca, 0xbe, 0xde, 0xe0, 0xe8, 0xd2, 0xde, + 0xdc, 0xe6, 0x46, 0x19, 0xbc, 0x0f, 0x0c, 0x8e, 0x09, 0x4b, 0x93, 0x73, + 0x31, 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, 0xa3, 0x1b, 0x25, 0x30, 0x03, + 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x06, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xc9, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, + 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x33, 0x31, + 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, - 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x60, 0x0c, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, - 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0xd1, 0x02, - 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, - 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, - 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, - 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, - 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, - 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, - 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, - 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x8d, 0x00, - 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, - 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, - 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, - 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, - 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, - 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, - 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, - 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, - 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, - 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, - 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, - 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, - 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, - 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, - 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, - 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, - 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, - 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, - 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, - 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, - 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, - 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, - 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, - 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, - 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, - 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, - 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, - 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, - 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, - 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, - 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, - 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, - 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, - 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, - 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, - 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, - 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, - 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x03, - 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, 0x00, 0x6d, 0x30, 0x06, 0x02, 0x58, - 0x80, 0x6a, 0x83, 0x41, 0x14, 0xc0, 0x02, 0x54, 0x1b, 0x94, 0xe2, 0xff, - 0xff, 0xff, 0xff, 0x07, 0xa0, 0x0d, 0x80, 0x35, 0x00, 0x24, 0xa0, 0xda, - 0x60, 0x18, 0x01, 0xb0, 0x00, 0xd5, 0x06, 0xe3, 0x10, 0x80, 0x05, 0xa8, - 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x88, - 0x40, 0x18, 0x88, 0x09, 0x43, 0x61, 0x1c, 0x00, 0x00, 0x00, 0x89, 0x20, - 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, - 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, - 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x54, - 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, 0x08, 0x41, - 0x70, 0x94, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xff, 0x44, 0x5c, 0x13, 0x15, - 0x11, 0xbf, 0x3d, 0xfc, 0xd3, 0x18, 0x01, 0x30, 0x88, 0x40, 0x04, 0x17, - 0x49, 0x53, 0x44, 0x09, 0x93, 0xff, 0x4b, 0x00, 0xf3, 0x2c, 0x44, 0xf4, - 0x4f, 0x63, 0x04, 0xc0, 0x20, 0x82, 0x21, 0x14, 0x23, 0x04, 0x31, 0xca, - 0x21, 0x34, 0x47, 0x80, 0x18, 0x21, 0xa8, 0x39, 0x82, 0x60, 0x8e, 0x00, - 0x0c, 0x86, 0x11, 0x84, 0xa6, 0x28, 0xab, 0x1c, 0xc1, 0x1c, 0x03, 0xa0, - 0xd1, 0x1b, 0x08, 0x48, 0x81, 0x36, 0x47, 0x00, 0x0a, 0x23, 0x00, 0x00, - 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, - 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, - 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, - 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, - 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, - 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, - 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, - 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, - 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, - 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, - 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, - 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, - 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, - 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, - 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, - 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, - 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, - 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, - 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, - 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, - 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, - 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, - 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, - 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, - 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, - 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, - 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, - 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, - 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x46, 0x6c, 0x57, - 0xfe, 0x9c, 0xf3, 0x60, 0x7f, 0x11, 0x01, 0x06, 0x43, 0x34, 0xd3, 0x90, - 0x08, 0x88, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x18, 0x12, 0x45, 0xdb, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x12, 0x1b, 0x04, 0x8a, 0x4e, 0x0b, 0x00, 0x00, - 0x64, 0x81, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x32, 0x1e, - 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, - 0x43, 0x6a, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x20, 0x65, 0x40, - 0x73, 0x04, 0x80, 0xe4, 0x58, 0x82, 0x23, 0x00, 0x00, 0x00, 0xb1, 0x18, - 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, - 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, - 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, - 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, - 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, - 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, - 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, - 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, - 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, - 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, - 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, - 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, - 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, - 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, - 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, - 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, - 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, - 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, - 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, - 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, - 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, - 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, - 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, - 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, - 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, - 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, - 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, - 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, - 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, - 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, - 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, - 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, - 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, - 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, - 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, - 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, - 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, - 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, - 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0xce, 0x00, - 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, - 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xc4, 0x80, 0x63, 0x21, 0x00, 0x8b, 0xe2, - 0x06, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, 0x88, 0x94, - 0x3d, 0x06, 0xa2, 0x3c, 0x12, 0x12, 0x5d, 0xc3, 0xa2, 0x60, 0xc3, 0x72, - 0x04, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, - 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, - 0x34, 0x33, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, - 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x29, 0x4d, 0x65, 0x74, + 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0xac, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, + 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, + 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, + 0xa3, 0x02, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, + 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, + 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, + 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, + 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, + 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, + 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, + 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, + 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, + 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, + 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, + 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, + 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, + 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, + 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, + 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, + 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, + 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, + 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, + 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, + 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, + 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, + 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, + 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, + 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, + 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, + 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, + 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, + 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, + 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, + 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, + 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0x60, + 0x08, 0x04, 0xb0, 0x00, 0xd5, 0x06, 0x63, 0x28, 0x80, 0x05, 0xa8, 0x36, + 0x28, 0xc4, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x40, 0x1b, 0x00, 0x6b, 0x00, + 0x48, 0x40, 0xb5, 0xc1, 0x28, 0x02, 0x60, 0x01, 0xaa, 0x0d, 0x86, 0x21, + 0x00, 0x0b, 0x50, 0x01, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x13, 0x86, 0x40, 0x18, 0x26, 0x0c, 0x44, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, + 0x10, 0x4c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x47, + 0x49, 0x53, 0x44, 0x09, 0x93, 0xff, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, + 0xdb, 0xc3, 0x3f, 0x8d, 0x11, 0x00, 0x83, 0x08, 0x43, 0x70, 0x91, 0x34, + 0x45, 0x94, 0x30, 0xf9, 0xbf, 0x04, 0x30, 0xcf, 0x42, 0x44, 0xff, 0x34, + 0x46, 0x00, 0x0c, 0x22, 0x14, 0x42, 0x31, 0x42, 0x08, 0x82, 0x18, 0x3a, + 0x73, 0x04, 0x88, 0x11, 0x42, 0x9a, 0x23, 0x08, 0xe6, 0x08, 0xc0, 0x60, + 0x18, 0x41, 0x60, 0x8a, 0xa2, 0x88, 0x11, 0xab, 0x2d, 0x00, 0x18, 0xb9, + 0x81, 0x80, 0x14, 0x60, 0x23, 0x00, 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, + 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, + 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, + 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, + 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, + 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, + 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, + 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, + 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, + 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, + 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, + 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, + 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, + 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, + 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, + 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, + 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, + 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, + 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, + 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, + 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, + 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, + 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, + 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, + 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, + 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, + 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x46, 0x08, 0x43, 0x46, 0x6c, 0x57, 0xfe, 0x9c, 0xf3, 0x60, 0x7f, 0x11, + 0x01, 0x06, 0x43, 0x34, 0xd3, 0x90, 0x08, 0x88, 0x0e, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x12, 0x45, 0x9b, 0x03, + 0x04, 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1b, + 0x04, 0x8a, 0x96, 0x0a, 0x00, 0x00, 0x64, 0x81, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, + 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x62, 0x45, 0x50, 0x02, 0x85, + 0x30, 0x02, 0x50, 0x06, 0x14, 0xc7, 0x12, 0x9c, 0x01, 0x00, 0x00, 0x00, + 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, + 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, + 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, + 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, + 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, + 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, + 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, + 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, + 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, + 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, + 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, + 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, + 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, + 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, + 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, + 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, + 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, + 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, + 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, + 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, + 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, + 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, + 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, + 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, + 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, + 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, + 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, + 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, + 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, + 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, + 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, + 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, + 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, + 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, + 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, + 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, + 0xbe, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, + 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x3c, 0x2c, 0x77, 0x00, 0x00, + 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, + 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0x8b, 0xa4, 0x60, 0xc3, 0x72, 0x04, + 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, + 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, + 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, + 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, @@ -1052,268 +1062,867 @@ const unsigned char sdl_metallib[] = { 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, - 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, - 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, - 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x66, - 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, - 0x64, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, - 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, - 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, - 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, - 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, - 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x63, 0x6f, 0x6c, 0x61, - 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, 0x69, - 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, 0x74, - 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, - 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x61, - 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x23, 0x08, 0x8d, 0x30, 0x82, 0x20, - 0x25, 0x23, 0x08, 0xcd, 0x30, 0x82, 0xd0, 0x10, 0x23, 0x08, 0x4d, 0x31, - 0x82, 0x90, 0x00, 0x23, 0x08, 0x8d, 0x31, 0x82, 0xd0, 0x1c, 0x33, 0x0c, - 0x63, 0x10, 0x90, 0xc1, 0x0c, 0x43, 0x19, 0x08, 0x66, 0x30, 0x43, 0x30, - 0xcc, 0x30, 0x8c, 0xc1, 0x18, 0x9c, 0xc1, 0x0c, 0x04, 0x51, 0x06, 0x65, - 0x70, 0x06, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, - 0x20, 0x67, 0x70, 0x06, 0x89, 0x32, 0x43, 0x30, 0x07, 0x33, 0x20, 0x67, - 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0x49, 0x19, 0x40, 0x11, 0x23, - 0x25, 0x93, 0x43, 0xcd, 0x00, 0x8d, 0x41, 0x65, 0xa5, 0xc1, 0x75, 0x06, - 0x65, 0x80, 0x65, 0x69, 0xa0, 0xa5, 0x41, 0xa2, 0x38, 0xdb, 0x0c, 0x8a, - 0x1a, 0x70, 0xd7, 0x19, 0x94, 0x41, 0x97, 0x78, 0xce, 0x37, 0x43, 0x62, - 0x06, 0x60, 0x70, 0x9d, 0x41, 0x19, 0x24, 0x61, 0xe0, 0x88, 0xc1, 0x0c, - 0x45, 0x1d, 0xd8, 0xc1, 0x1d, 0xe0, 0x41, 0x1e, 0xcc, 0x30, 0xa0, 0x01, - 0x1d, 0xe8, 0x81, 0x8c, 0x04, 0x26, 0xe8, 0x22, 0x36, 0x36, 0xbb, 0x36, - 0x97, 0xb6, 0x37, 0xb2, 0x3a, 0xb6, 0x32, 0x17, 0x33, 0xb6, 0xb0, 0xb3, - 0xb9, 0x51, 0x04, 0x35, 0x58, 0x83, 0x53, 0xd8, 0xd8, 0xec, 0xda, 0x5c, - 0xd2, 0xc8, 0xca, 0xdc, 0xe8, 0x46, 0x09, 0xd8, 0xe0, 0x96, 0xb0, 0x34, - 0x39, 0x17, 0xbb, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x51, 0x82, 0x36, - 0x38, 0x2a, 0x2c, 0x4d, 0xce, 0x85, 0x2d, 0xcc, 0xed, 0xac, 0x2e, 0xec, - 0xac, 0xec, 0xcb, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x94, 0xc0, - 0x0d, 0x6e, 0x0a, 0x4b, 0x93, 0x73, 0x19, 0x7b, 0x6b, 0x83, 0x4b, 0x63, - 0x2b, 0xfb, 0x7a, 0x83, 0xa3, 0x4b, 0x7b, 0x73, 0x9b, 0x1b, 0x65, 0x78, - 0x03, 0x38, 0x88, 0x83, 0x63, 0xc2, 0xd2, 0xe4, 0x5c, 0xcc, 0xe4, 0xc2, - 0xce, 0xda, 0xca, 0xdc, 0xe8, 0x46, 0x09, 0xf4, 0x00, 0x00, 0xa9, 0x18, - 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, - 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, - 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, - 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, - 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, - 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, - 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xc4, 0x6a, 0x60, 0x04, 0x80, 0xdc, - 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, - 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, - 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, - 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, - 0x00, 0x00, 0x13, 0x84, 0x09, 0xd9, 0x10, 0xf4, 0xc1, 0x86, 0x81, 0x0f, - 0xfe, 0xc0, 0x0f, 0x36, 0x0c, 0xa0, 0x00, 0x0a, 0x7e, 0x00, 0x23, 0x06, - 0x8d, 0x10, 0x82, 0x60, 0xf0, 0x48, 0x46, 0x81, 0x10, 0xc2, 0x10, 0x04, - 0xce, 0x68, 0x42, 0x00, 0x50, 0x12, 0x8a, 0x09, 0x81, 0xf8, 0x67, 0x10, - 0x10, 0x03, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x06, 0x21, 0x00, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xad, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x23, 0x00, - 0x00, 0x00, 0x12, 0x03, 0x94, 0x20, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x44, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x54, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1b, 0x00, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, - 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xb4, 0x00, 0x00, - 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x66, - 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x73, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, - 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, - 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, + 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, + 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, + 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, + 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, + 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, + 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x61, 0x69, + 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0x23, 0x08, 0x8c, 0x30, + 0x82, 0x10, 0x1d, 0x23, 0x08, 0xcc, 0x30, 0x82, 0xc0, 0x10, 0x23, 0x08, + 0x4c, 0x31, 0x82, 0x80, 0x00, 0x23, 0x08, 0x8c, 0x31, 0xc3, 0xf0, 0x05, + 0x60, 0x30, 0xc3, 0x10, 0x06, 0x82, 0x18, 0xcc, 0x10, 0x0c, 0x33, 0x0c, + 0xdf, 0x37, 0x06, 0x33, 0x10, 0x44, 0x18, 0x84, 0xc1, 0x18, 0xcc, 0x10, + 0x14, 0x33, 0x04, 0xc6, 0x0c, 0xc1, 0x31, 0x43, 0x81, 0x8c, 0xc1, 0x18, + 0x24, 0xca, 0x0c, 0x81, 0x1b, 0xcc, 0x80, 0x8c, 0xc1, 0xc2, 0x34, 0x89, + 0xe2, 0x3c, 0x33, 0x24, 0x61, 0x00, 0x45, 0x8c, 0x94, 0x28, 0xce, 0x34, + 0x43, 0xf2, 0x41, 0x14, 0x23, 0x25, 0x95, 0x63, 0xcd, 0xa0, 0x94, 0xc1, + 0x85, 0x8d, 0x41, 0x18, 0x64, 0x89, 0xe6, 0x6c, 0x33, 0x24, 0x62, 0xc0, + 0x61, 0x63, 0x10, 0x06, 0x49, 0xe7, 0x78, 0x33, 0x14, 0x70, 0x10, 0x07, + 0x72, 0x30, 0x07, 0x74, 0x30, 0xc3, 0x40, 0x06, 0x6f, 0x50, 0x07, 0x32, + 0x12, 0x98, 0xa0, 0x8b, 0xd8, 0xd8, 0xec, 0xda, 0x5c, 0xda, 0xde, 0xc8, + 0xea, 0xd8, 0xca, 0x5c, 0xcc, 0xd8, 0xc2, 0xce, 0xe6, 0x46, 0x11, 0xca, + 0xc0, 0x0c, 0x4e, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, + 0xa3, 0x1b, 0x25, 0x38, 0x83, 0x5b, 0xc2, 0xd2, 0xe4, 0x5c, 0xec, 0xca, + 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xd0, 0xe0, 0xa8, 0xb0, 0x34, + 0x39, 0x17, 0xb6, 0x30, 0xb7, 0xb3, 0xba, 0xb0, 0xb3, 0xb2, 0x2f, 0xbb, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x51, 0x82, 0x34, 0xb8, 0x29, 0x2c, + 0x4d, 0xce, 0x65, 0xec, 0xad, 0x0d, 0x2e, 0x8d, 0xad, 0xec, 0xeb, 0x0d, + 0x8e, 0x2e, 0xed, 0xcd, 0x6d, 0x6e, 0x94, 0x41, 0x0d, 0xd6, 0x80, 0x0d, + 0x8e, 0x09, 0x4b, 0x93, 0x73, 0x31, 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, + 0xa3, 0x1b, 0x25, 0xa8, 0x03, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, + 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, + 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, + 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, + 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, + 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, + 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0xb4, 0x6a, 0x60, 0x04, 0x80, 0xda, 0x08, 0x00, + 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8d, 0x10, 0x82, 0x60, 0xe0, 0x40, + 0x46, 0x71, 0x10, 0xc2, 0x10, 0x04, 0xcc, 0x68, 0x42, 0x00, 0x58, 0xa0, + 0x88, 0x7f, 0x06, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0x97, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x20, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xb6, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, + 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, - 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x28, 0x0f, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, - 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x6b, 0x03, 0x00, 0x00, 0x0b, 0x02, - 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, - 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, - 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x18, - 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4, 0x10, 0x32, 0x14, 0x38, 0x08, - 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, - 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x11, 0x23, - 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x31, - 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x1b, 0xcc, - 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, - 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, - 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, - 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, - 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, - 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, - 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, - 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, - 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, - 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, - 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, - 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, - 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, - 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, - 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, - 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, - 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, - 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, - 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, - 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, - 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, - 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, - 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, - 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, - 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, - 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, - 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, - 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, - 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, - 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, - 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, - 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, - 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, - 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, - 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, - 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, - 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x03, 0x90, 0x00, 0x0b, 0x50, - 0x05, 0x69, 0x00, 0x6d, 0x58, 0x06, 0x02, 0x48, 0x80, 0x05, 0xa8, 0x82, - 0x34, 0x00, 0x85, 0x0d, 0x06, 0x51, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x8a, - 0x03, 0x58, 0x80, 0x6a, 0x83, 0x61, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x48, 0x00, 0xb5, 0x41, 0x39, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xda, - 0x00, 0x58, 0x03, 0x40, 0x02, 0xaa, 0x0d, 0x06, 0x12, 0x00, 0x0b, 0x50, - 0x6d, 0x30, 0x12, 0x01, 0x58, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x49, 0x18, - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, - 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, - 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, - 0x85, 0x04, 0x13, 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, - 0x90, 0x14, 0x12, 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x84, - 0xc1, 0x0c, 0xc0, 0x30, 0x02, 0x01, 0x0c, 0x23, 0x08, 0xc0, 0x20, 0x42, - 0x10, 0x0c, 0x23, 0x0c, 0xc0, 0x41, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xcb, - 0xee, 0xdb, 0x11, 0x82, 0x33, 0x10, 0x88, 0x20, 0x08, 0x82, 0x18, 0x44, - 0x28, 0x84, 0xa3, 0xa4, 0x29, 0xa2, 0x84, 0xc9, 0xff, 0x27, 0xe2, 0x9a, - 0xa8, 0x88, 0xf8, 0xed, 0xe1, 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, 0x23, - 0x38, 0x4d, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x7f, 0x22, 0xae, 0x89, 0x8a, - 0x88, 0xdf, 0x1e, 0x7e, 0x20, 0x8a, 0x00, 0xec, 0x9f, 0xc6, 0x08, 0x80, - 0x41, 0x84, 0x24, 0xb8, 0x48, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x5f, 0x02, - 0x98, 0x67, 0x21, 0xa2, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x16, 0xa1, - 0x20, 0x41, 0x20, 0x0c, 0x06, 0xa2, 0x30, 0xd4, 0x94, 0x01, 0x20, 0x08, - 0x7a, 0xe6, 0x08, 0x10, 0x23, 0x04, 0xd1, 0x1c, 0x01, 0x18, 0xcc, 0x11, - 0x04, 0xc3, 0x08, 0xc2, 0x54, 0x16, 0x49, 0x61, 0x84, 0x89, 0xaa, 0x28, - 0x00, 0x98, 0xc8, 0x2a, 0x8a, 0x84, 0x30, 0x02, 0x55, 0x51, 0x00, 0x30, - 0x11, 0x36, 0x10, 0x90, 0x02, 0xd3, 0x30, 0xc2, 0x30, 0xcd, 0x11, 0x80, - 0xc2, 0x20, 0x42, 0x20, 0x0c, 0x22, 0x10, 0xc2, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, - 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, - 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, - 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, - 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, - 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, - 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, - 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, - 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, - 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, - 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, - 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, - 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, - 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, - 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, - 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, - 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, - 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, - 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, - 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, - 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, - 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, - 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, - 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, - 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, - 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, - 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, - 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, - 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x42, 0x6c, 0x57, - 0xfe, 0xb2, 0xfb, 0xfe, 0x45, 0x04, 0x18, 0x0c, 0xd1, 0x4c, 0x43, 0x22, - 0x00, 0x6a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x60, 0x48, 0x04, 0x35, 0x0f, 0x10, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x89, 0xba, 0x30, 0xb0, 0x80, 0x00, 0x18, 0x00, - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x60, 0x48, 0xe4, 0x07, 0x1b, 0x06, - 0x04, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1b, - 0x04, 0x8a, 0xb6, 0x0d, 0x00, 0x00, 0x64, 0x81, 0x00, 0x00, 0x0b, 0x00, - 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, - 0x26, 0x47, 0xc6, 0x04, 0x43, 0x9a, 0x8a, 0xa0, 0x04, 0x0a, 0x61, 0x04, - 0xa0, 0x40, 0xca, 0xa0, 0x00, 0x03, 0x0a, 0xa8, 0xc0, 0x4a, 0xa1, 0x18, - 0xa8, 0x1b, 0x01, 0xa0, 0x6d, 0x2c, 0xc1, 0x11, 0x00, 0x00, 0xb1, 0x18, - 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, - 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, - 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, - 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, - 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, - 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, - 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, - 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, - 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, - 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, - 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, - 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, - 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, - 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, - 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, - 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, - 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, - 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, - 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, - 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, - 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, - 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, - 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, - 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, - 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, - 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, - 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, - 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, - 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, - 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, - 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, - 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, - 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, - 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, - 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, - 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, - 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, - 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, - 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, - 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, - 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, - 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0x0c, 0x01, - 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, - 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xd8, 0x80, 0x0c, 0xf2, 0x09, 0x8b, 0xe2, - 0x06, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, 0x88, 0x94, - 0x3d, 0x06, 0xa2, 0x3c, 0x12, 0x12, 0x5d, 0x03, 0x65, 0x18, 0x86, 0x61, - 0x24, 0xc6, 0xa2, 0x60, 0x84, 0x57, 0x2c, 0x47, 0x00, 0x00, 0x53, 0x44, - 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, - 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, - 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x20, 0x28, - 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, - 0x31, 0x2e, 0x34, 0x33, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, + 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xbc, 0x0e, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, + 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x50, 0x03, 0x00, 0x00, + 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, + 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, + 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4, 0x10, 0x32, 0x14, + 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, + 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, + 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, + 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, + 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, + 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, + 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, + 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, + 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, + 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, + 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, + 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, + 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, + 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, + 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, + 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, + 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, + 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, + 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, + 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, + 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, + 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, + 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, + 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, + 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, + 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, + 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, + 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, + 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, + 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, + 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, + 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, + 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, + 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, + 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, + 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, + 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x04, 0x90, 0x00, + 0x0b, 0x50, 0x05, 0x69, 0x00, 0x0a, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, + 0xda, 0x60, 0x10, 0x07, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x90, 0x00, 0x6a, 0x83, 0x62, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0x00, 0xb4, 0x01, 0xb0, 0x06, 0x80, 0x04, 0x54, 0x1b, 0x8c, 0x23, + 0x00, 0x16, 0xa0, 0xda, 0x60, 0x20, 0x02, 0xb0, 0x00, 0x15, 0x00, 0x00, + 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, + 0x88, 0x09, 0x41, 0x31, 0x61, 0x30, 0x0e, 0x04, 0x89, 0x20, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, + 0x13, 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, + 0x12, 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x80, 0xc1, 0x0c, + 0xc0, 0x30, 0x02, 0x01, 0x0c, 0x23, 0x08, 0xc0, 0x30, 0xc2, 0x00, 0x1c, + 0x24, 0x4d, 0x11, 0x25, 0x4c, 0xbe, 0xec, 0xbe, 0x1d, 0x21, 0x38, 0x03, + 0x81, 0x88, 0x61, 0x18, 0x86, 0x41, 0x04, 0x42, 0x38, 0x4a, 0x9a, 0x22, + 0x4a, 0x98, 0xfc, 0x7f, 0x22, 0xae, 0x89, 0x8a, 0x88, 0xdf, 0x1e, 0xfe, + 0x69, 0x8c, 0x00, 0x18, 0x44, 0x30, 0x82, 0xd3, 0xa4, 0x29, 0xa2, 0x84, + 0xc9, 0xff, 0x27, 0xe2, 0x9a, 0xa8, 0x88, 0xf8, 0xed, 0xe1, 0x07, 0xa2, + 0x08, 0xc0, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x82, 0x8b, 0xa4, + 0x29, 0xa2, 0x84, 0xc9, 0xff, 0x25, 0x80, 0x79, 0x16, 0x22, 0xfa, 0xa7, + 0x31, 0x02, 0x60, 0x10, 0x41, 0x11, 0x0a, 0x12, 0x04, 0x81, 0x50, 0x1c, + 0xc9, 0x42, 0x4c, 0x19, 0x80, 0x61, 0x20, 0x67, 0x8e, 0x00, 0x31, 0x42, + 0x00, 0xcd, 0x11, 0x80, 0xc1, 0x1c, 0x41, 0x30, 0x8c, 0x20, 0x48, 0x65, + 0x89, 0x92, 0x45, 0x90, 0x26, 0x6a, 0x02, 0x00, 0x89, 0xaa, 0xa2, 0x44, + 0xc7, 0x22, 0x4c, 0xd4, 0x04, 0x00, 0x12, 0x5d, 0x03, 0x01, 0x29, 0x20, + 0x0d, 0x23, 0x0c, 0xd2, 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x04, 0xc2, 0x20, + 0xc2, 0x20, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, + 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, + 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, + 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, + 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, + 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, + 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, + 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, + 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, + 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, + 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, + 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, + 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, + 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, + 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, + 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, + 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, + 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, + 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, + 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, + 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, + 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, + 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, + 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, + 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, + 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, + 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x46, 0x08, 0x43, 0x42, 0x6c, 0x57, 0xfe, 0xb2, 0xfb, 0xfe, 0x45, 0x04, + 0x18, 0x0c, 0xd1, 0x4c, 0x43, 0x22, 0x00, 0x62, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x60, 0x48, 0x04, 0x35, 0x0e, 0x10, + 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x89, 0xba, + 0x30, 0xa8, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x60, 0x48, 0xe4, 0x07, 0xdb, 0x05, 0x04, 0xc0, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x1b, 0x04, 0x8a, 0x4a, 0x0d, 0x00, 0x00, + 0x64, 0x81, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, + 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x92, + 0x8a, 0xa0, 0x04, 0x0a, 0x61, 0x04, 0xa0, 0x0c, 0x0a, 0x30, 0xa0, 0x40, + 0x0a, 0xa8, 0xc0, 0x4a, 0xa1, 0x18, 0x48, 0x1b, 0x4b, 0x70, 0x06, 0x00, + 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, + 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, + 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, + 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, + 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, + 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, + 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, + 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, + 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, + 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, + 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, + 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, + 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, + 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, + 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, + 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, + 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, + 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, + 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, + 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, + 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, + 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, + 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, + 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, + 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, + 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, + 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, + 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, + 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, + 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, + 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, + 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, + 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, + 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, + 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, + 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, + 0x10, 0x01, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, + 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xda, 0x80, 0x0c, 0x66, 0x0a, + 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, + 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0xca, 0x23, 0x21, 0x94, 0x61, 0x18, + 0x86, 0x11, 0x5d, 0x89, 0xb1, 0x28, 0x18, 0xe1, 0x15, 0xcb, 0x11, 0x00, + 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, + 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, + 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, + 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, + 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, + 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, + 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, + 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x34, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, + 0x69, 0x72, 0x2e, 0x6e, 0x6f, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, + 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, + 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, + 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, + 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, + 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x61, 0x69, 0x72, + 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x65, + 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x3e, 0x74, 0x65, 0x78, 0x59, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x32, 0x64, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, + 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, + 0x44, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x20, 0x11, + 0x23, 0x08, 0xda, 0x33, 0x82, 0x20, 0x15, 0x23, 0x08, 0x92, 0x31, 0x82, + 0x20, 0x1d, 0x23, 0x08, 0x0d, 0x30, 0x82, 0x20, 0x21, 0x23, 0x08, 0x52, + 0x32, 0x82, 0x20, 0x29, 0x23, 0x08, 0xd2, 0x32, 0x82, 0x20, 0x31, 0x23, + 0x08, 0x52, 0x33, 0x82, 0x20, 0x39, 0x33, 0x0c, 0x6e, 0x10, 0xbc, 0xc1, + 0x0c, 0x03, 0x1c, 0x08, 0x71, 0x30, 0x43, 0x30, 0xcc, 0x30, 0xb8, 0x81, + 0x1b, 0xc8, 0xc1, 0x0c, 0x04, 0x01, 0x07, 0x70, 0x20, 0x07, 0x33, 0x04, + 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x72, 0x20, 0x07, + 0x89, 0x32, 0x43, 0x30, 0x0a, 0x33, 0x20, 0x72, 0xb0, 0x30, 0x4d, 0xa2, + 0x38, 0xcf, 0x0c, 0x09, 0x1c, 0x40, 0x11, 0x23, 0x25, 0x8a, 0x33, 0xcd, + 0x90, 0xb8, 0x01, 0x44, 0x31, 0x52, 0x52, 0x39, 0xd6, 0x0c, 0x94, 0x1c, + 0xd8, 0x81, 0x1c, 0x70, 0x9d, 0x1d, 0xd8, 0x81, 0x1c, 0x70, 0xde, 0x1d, + 0xd8, 0x81, 0x1c, 0x70, 0x1f, 0x1e, 0xd8, 0x81, 0x1c, 0x70, 0x60, 0x30, + 0x83, 0x44, 0x07, 0x17, 0x56, 0x07, 0x19, 0x1c, 0xc0, 0x81, 0xb6, 0xa1, + 0x42, 0x18, 0xd4, 0x81, 0x18, 0xd8, 0x41, 0x32, 0x06, 0x0e, 0x19, 0xcc, + 0xa0, 0xc4, 0x41, 0x19, 0x64, 0x72, 0x00, 0x07, 0x66, 0x90, 0x9c, 0x81, + 0x83, 0x06, 0x33, 0x28, 0x79, 0x50, 0x06, 0x19, 0x1c, 0xc0, 0x81, 0x19, + 0x24, 0x69, 0xe0, 0xa8, 0xc1, 0x0c, 0x89, 0x1e, 0xac, 0x41, 0x26, 0x07, + 0x70, 0x90, 0xb0, 0x81, 0xd3, 0x06, 0x33, 0x1c, 0xa5, 0x60, 0x0a, 0xa7, + 0x90, 0x0a, 0xaa, 0xb0, 0x0a, 0xac, 0x30, 0xc3, 0x30, 0x07, 0xa4, 0xd0, + 0x0a, 0x15, 0x06, 0x00, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, + 0x1c, 0xe7, 0x06, 0x6e, 0x60, 0xd1, 0x81, 0x1e, 0x58, 0x96, 0xa5, 0x07, + 0x9c, 0x29, 0xb0, 0x02, 0x2b, 0xd8, 0x86, 0x5f, 0xd8, 0x83, 0x3d, 0xa8, + 0x03, 0x39, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, + 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, + 0x1b, 0x45, 0xd0, 0x83, 0x3d, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, + 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x80, 0x0f, 0x6e, 0x09, 0x4b, 0x93, + 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0xe8, 0x83, + 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, + 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xfc, + 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, + 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x86, 0x3f, + 0x00, 0x85, 0x50, 0x38, 0x26, 0x2c, 0x4d, 0xce, 0xc5, 0x4c, 0x2e, 0xec, + 0xac, 0xad, 0xcc, 0x8d, 0x6e, 0x94, 0xa0, 0x15, 0x00, 0x00, 0x00, 0x00, + 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, + 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, + 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, + 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, + 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, + 0x61, 0x20, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, + 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x24, 0xcd, 0x00, 0xd0, + 0x54, 0x03, 0x23, 0x00, 0x44, 0x8d, 0x00, 0xd0, 0x36, 0xd6, 0x00, 0x04, + 0xc2, 0x1c, 0xc3, 0x71, 0x5d, 0xc4, 0x8d, 0x00, 0x94, 0x40, 0x11, 0x10, + 0x30, 0x02, 0x30, 0x03, 0x30, 0x46, 0x00, 0x82, 0x20, 0x88, 0x7f, 0x14, + 0xcc, 0x00, 0xcc, 0x41, 0x84, 0x41, 0x18, 0x84, 0x81, 0x18, 0x00, 0x00, + 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x70, 0x89, 0x41, 0xf4, 0x4c, 0xcd, + 0xc2, 0x14, 0x85, 0x37, 0x9a, 0x10, 0x00, 0x83, 0x0c, 0x01, 0xb1, 0x8c, + 0x18, 0x38, 0x43, 0x08, 0x82, 0x41, 0x65, 0x06, 0x93, 0x64, 0x85, 0x01, + 0xe4, 0x3c, 0x08, 0x12, 0x06, 0xa3, 0x09, 0x01, 0x30, 0x86, 0x10, 0x34, + 0x73, 0x0c, 0x44, 0xd0, 0x8c, 0x18, 0x38, 0x43, 0x08, 0x82, 0x41, 0xa5, + 0x06, 0x97, 0xa5, 0x9d, 0x01, 0x25, 0x4d, 0x0c, 0x53, 0x06, 0xa3, 0x09, + 0x01, 0x30, 0x86, 0x10, 0x44, 0x73, 0x0c, 0x44, 0x00, 0x5d, 0xd7, 0x2d, + 0x05, 0x41, 0x19, 0x64, 0x08, 0x9e, 0xcb, 0x88, 0x00, 0xfc, 0x37, 0x31, + 0x84, 0xc1, 0xf5, 0x06, 0x17, 0x74, 0x4b, 0x41, 0x50, 0x06, 0x19, 0x02, + 0x8a, 0x1b, 0x31, 0x38, 0x84, 0x10, 0x04, 0x0b, 0xff, 0x70, 0xee, 0xa0, + 0x08, 0x36, 0x31, 0x98, 0x01, 0x57, 0x07, 0x17, 0x74, 0x4b, 0x41, 0x50, + 0x06, 0x19, 0x82, 0x2c, 0x0c, 0x46, 0x0c, 0x0e, 0x21, 0x04, 0xc1, 0xc2, + 0x3f, 0x1c, 0x3e, 0x50, 0x82, 0x4d, 0x0c, 0x6b, 0x10, 0x06, 0x76, 0x70, + 0x41, 0xb7, 0x14, 0x04, 0x65, 0x90, 0x21, 0xf0, 0xcc, 0x60, 0xc4, 0xe0, + 0x10, 0x42, 0x10, 0x2c, 0xfc, 0xc3, 0x09, 0x85, 0x27, 0x98, 0x63, 0xf8, + 0x16, 0x3e, 0x98, 0x63, 0x08, 0x8e, 0x3f, 0x98, 0x63, 0x08, 0x86, 0x50, + 0xb0, 0xa0, 0x0e, 0xc4, 0x3f, 0x03, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0x8e, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x2f, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x70, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x23, + 0x01, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x59, 0x55, 0x56, 0x5f, + 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, 0x2e, + 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, + 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, + 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, + 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, + 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, + 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, + 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, + 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x36, 0x03, 0x00, 0x00, + 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, + 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, + 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, + 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, + 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, + 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, + 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, + 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, + 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, + 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, + 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, + 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, + 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, + 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, + 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, + 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, + 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, + 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, + 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, + 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, + 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, + 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, + 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, + 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, + 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, + 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, + 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, + 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, + 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, + 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, + 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, + 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, + 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, + 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, + 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, + 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, + 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, + 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, + 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x04, 0x90, 0x00, + 0x0b, 0x50, 0x05, 0x69, 0x00, 0x0a, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, + 0xda, 0x60, 0x10, 0x06, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, + 0xa8, 0x36, 0x18, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, + 0x1b, 0x94, 0xe3, 0xff, 0xff, 0xff, 0xff, 0x07, 0xa0, 0x0d, 0x80, 0x35, + 0x00, 0x24, 0xa0, 0xda, 0x60, 0x20, 0x01, 0xb0, 0x00, 0xd5, 0x06, 0x23, + 0x11, 0x80, 0x05, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, + 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, + 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, + 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x33, 0x00, + 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, + 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, + 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, + 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, + 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, + 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, + 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, + 0x83, 0xd8, 0x1c, 0x01, 0x62, 0x84, 0xe0, 0xe6, 0x08, 0x82, 0x39, 0x02, + 0x30, 0x18, 0x46, 0x10, 0xa2, 0xa2, 0xbc, 0x93, 0x04, 0x94, 0x10, 0x80, + 0x48, 0x73, 0x20, 0x20, 0x05, 0xe2, 0x30, 0xc2, 0x10, 0x0d, 0x22, 0x04, + 0xc2, 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x0c, 0xc2, 0x08, 0x00, 0x00, 0x00, + 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, + 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, + 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, + 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, + 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, + 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, + 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, + 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, + 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, + 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, + 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, + 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, + 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, + 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, + 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, + 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, + 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, + 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, + 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, + 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, + 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, + 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, + 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, + 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, + 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, + 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, + 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, + 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, + 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x46, 0x6c, 0x57, 0xfe, 0xe7, + 0x5b, 0xdb, 0x7f, 0x11, 0x01, 0x06, 0x43, 0x34, 0xd3, 0x90, 0x08, 0x88, + 0x14, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, + 0x12, 0x45, 0x0d, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x43, 0x22, 0x6f, 0x9b, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x40, 0x62, 0x83, 0x40, 0x51, 0x9c, 0x01, 0x00, + 0x80, 0x2c, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, + 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x8a, + 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x06, 0x05, 0x18, 0x50, 0x20, + 0x05, 0x54, 0x60, 0xa5, 0x50, 0x0c, 0x64, 0xc7, 0x12, 0x9c, 0x01, 0x00, + 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, + 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, + 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, + 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, + 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, + 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, + 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, + 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, + 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, + 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, + 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, + 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, + 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, + 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, + 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, + 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, + 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, + 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, + 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, + 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, + 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, + 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, + 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, + 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, + 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, + 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, + 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, + 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, + 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, + 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, + 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, + 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, + 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, + 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, + 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, + 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, + 0x09, 0x01, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, + 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xd8, 0x80, 0x0c, 0xea, 0x09, + 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, + 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0xca, 0x23, 0x21, 0x94, 0x61, 0x18, + 0x86, 0x11, 0x5d, 0x89, 0xb1, 0x28, 0x18, 0x51, 0x2c, 0x47, 0x00, 0x00, + 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, + 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, + 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, + 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, + 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, + 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, + 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, + 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x34, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, + 0x69, 0x72, 0x2e, 0x6e, 0x6f, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, + 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, + 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, + 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, + 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, + 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x61, 0x69, 0x72, + 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x65, + 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x3e, 0x74, 0x65, 0x78, 0x59, 0x74, 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, + 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0x44, 0x74, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x10, 0x0d, 0x23, 0x08, 0x96, 0x33, + 0x82, 0x10, 0x11, 0x23, 0x08, 0x51, 0x31, 0x82, 0x10, 0x19, 0x23, 0x08, + 0x0b, 0x30, 0x82, 0x10, 0x1d, 0x23, 0x08, 0x11, 0x32, 0x82, 0x10, 0x25, + 0x23, 0x08, 0x91, 0x32, 0x82, 0x10, 0x2d, 0x23, 0x08, 0x11, 0x33, 0x82, + 0x10, 0x35, 0x33, 0x0c, 0x6d, 0x10, 0xb8, 0xc1, 0x0c, 0xc3, 0x1b, 0x08, + 0x70, 0x30, 0x43, 0x30, 0xcc, 0x30, 0xb4, 0x41, 0x1b, 0xc4, 0xc1, 0x0c, + 0x04, 0xf1, 0x06, 0x6f, 0x10, 0x07, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, + 0x43, 0x70, 0xcc, 0x50, 0x20, 0x71, 0x10, 0x07, 0x89, 0x32, 0x43, 0x20, + 0x0a, 0x33, 0x20, 0x71, 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0xc9, + 0x1b, 0x40, 0x11, 0x23, 0x25, 0x8a, 0x33, 0xcd, 0x90, 0xb4, 0x01, 0x44, + 0x31, 0x52, 0x52, 0x39, 0xd6, 0x0c, 0x54, 0x1c, 0xd4, 0x41, 0x1c, 0x70, + 0x5d, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0x9e, 0x1d, 0xd4, 0x41, 0x1c, 0x70, + 0xdf, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0x60, 0x30, 0x83, 0x34, 0x07, 0x17, + 0x46, 0x07, 0xd9, 0x1b, 0xbc, 0x81, 0xb6, 0x9d, 0x42, 0x18, 0xd0, 0x81, + 0x18, 0xd4, 0x41, 0x32, 0x06, 0x0e, 0x19, 0xcc, 0xa0, 0xc0, 0x41, 0x19, + 0x64, 0x71, 0xf0, 0x06, 0x66, 0x90, 0x9c, 0x81, 0x83, 0x06, 0x33, 0x28, + 0x78, 0x50, 0x06, 0xd9, 0x1b, 0xbc, 0x81, 0x19, 0x24, 0x67, 0xe0, 0xa4, + 0xc1, 0x0c, 0x49, 0x1e, 0xa8, 0x41, 0x16, 0x07, 0x6f, 0x90, 0xac, 0x81, + 0xc3, 0x06, 0x33, 0x1c, 0xa4, 0x50, 0x0a, 0xa6, 0x80, 0x0a, 0xa9, 0xa0, + 0x0a, 0xab, 0x30, 0xc3, 0x20, 0x07, 0xa3, 0xc0, 0x0a, 0x15, 0x06, 0x00, + 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xe7, 0x06, 0x6e, + 0x60, 0xd1, 0x81, 0x1e, 0x58, 0x96, 0xa5, 0x07, 0x9c, 0x29, 0xb0, 0x02, + 0x2b, 0xd8, 0x86, 0x5f, 0xd8, 0x83, 0x3d, 0xa8, 0x03, 0x39, 0xc8, 0x48, + 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, + 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0xc8, 0x03, + 0x3d, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, + 0x6e, 0x94, 0x60, 0x0f, 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, + 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0xe0, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, + 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, + 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xfa, 0xe0, 0xa6, 0xb0, 0x34, + 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, + 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x06, 0x3f, 0xf8, 0x03, 0x50, 0x38, + 0x26, 0x2c, 0x4d, 0xce, 0xc5, 0x4c, 0x2e, 0xec, 0xac, 0xad, 0xcc, 0x8d, + 0x6e, 0x94, 0x80, 0x15, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, + 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, + 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, + 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, + 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, + 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, + 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, + 0x3b, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x04, 0x6b, 0x60, 0x04, 0x80, 0xe2, 0x0c, 0x00, + 0xc9, 0x11, 0x00, 0xba, 0x63, 0x0d, 0x40, 0x20, 0xcc, 0x31, 0x18, 0x18, + 0x36, 0xc7, 0x60, 0x10, 0xd8, 0x58, 0x03, 0x30, 0x10, 0x94, 0x47, 0x00, + 0x08, 0x8c, 0x00, 0xcc, 0x00, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0x1f, + 0x85, 0x19, 0x80, 0x39, 0x08, 0x30, 0x00, 0x03, 0x30, 0x08, 0x03, 0x00, + 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x30, 0x89, 0x41, 0xf4, 0x4c, 0xce, + 0xd2, 0x14, 0x85, 0x37, 0x9a, 0x10, 0x00, 0x83, 0x0c, 0x01, 0xb1, 0x8c, + 0x18, 0x34, 0x43, 0x08, 0x82, 0xc1, 0x54, 0x06, 0x93, 0x64, 0x45, 0x0e, + 0x84, 0x20, 0x61, 0x30, 0x9a, 0x10, 0x00, 0x83, 0x0c, 0xc1, 0xd1, 0x0c, + 0x32, 0x10, 0x41, 0x73, 0x19, 0x5e, 0x0a, 0x42, 0x19, 0x64, 0x08, 0x96, + 0xc9, 0x88, 0x00, 0xfc, 0x37, 0x19, 0xba, 0x68, 0x0d, 0x2e, 0xc0, 0x4b, + 0x41, 0x28, 0x83, 0x0c, 0x01, 0x84, 0x8d, 0x18, 0x1c, 0x42, 0x08, 0x82, + 0x85, 0x7f, 0x30, 0x72, 0x50, 0x04, 0x9b, 0x0c, 0x62, 0x60, 0xc5, 0xc1, + 0x05, 0x78, 0x29, 0x08, 0x65, 0x90, 0x21, 0xa8, 0xba, 0x11, 0x83, 0x43, + 0x08, 0x41, 0xb0, 0xf0, 0x0f, 0xe6, 0x0e, 0x94, 0x60, 0x93, 0xe1, 0x0c, + 0x36, 0x39, 0xb8, 0x00, 0x2f, 0x05, 0xa1, 0x0c, 0x32, 0x04, 0x9a, 0x18, + 0x8c, 0x18, 0x1c, 0x42, 0x08, 0x82, 0x85, 0x7f, 0x30, 0x7c, 0xf0, 0x04, + 0x73, 0x0c, 0xdb, 0x82, 0x07, 0x73, 0x0c, 0xc1, 0xb1, 0x07, 0x73, 0x0c, + 0xc1, 0xd0, 0x07, 0x16, 0xc4, 0x81, 0xf8, 0x67, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, + 0x84, 0x00, 0xfb, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x0c, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x38, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x4e, 0x56, 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x61, 0x69, 0x72, 0x2e, 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, + 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, + 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, + 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, + 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, + 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x28, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x0c, 0x00, 0x00, 0x39, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, + 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, + 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, + 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, + 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, + 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, + 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, + 0x51, 0x18, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, + 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, + 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, + 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, + 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, + 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, + 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, + 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, + 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, + 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, + 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, + 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, + 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, + 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, + 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, + 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, + 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, + 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, + 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, + 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, + 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, + 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, + 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, + 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, + 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, + 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, + 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x04, 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, + 0x00, 0x0a, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x06, + 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, 0xa8, 0x36, 0x18, 0xc6, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, 0x1b, 0x94, 0xe3, 0xff, + 0xff, 0xff, 0xff, 0x07, 0xa0, 0x0d, 0x80, 0x35, 0x00, 0x24, 0xa0, 0xda, + 0x60, 0x20, 0x01, 0xb0, 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, + 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, + 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, + 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, + 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, + 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, + 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, + 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, + 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, + 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, + 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x01, + 0x62, 0x84, 0xe0, 0xe6, 0x08, 0x82, 0x39, 0x02, 0x30, 0x18, 0x46, 0x10, + 0xa2, 0xa2, 0xbc, 0x93, 0x04, 0x94, 0x10, 0x80, 0x48, 0x73, 0x20, 0x20, + 0x05, 0xe2, 0x30, 0xc2, 0x10, 0x0d, 0x22, 0x04, 0xc2, 0x1c, 0x01, 0x28, + 0x0c, 0x22, 0x0c, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, + 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, + 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, + 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, + 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, + 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, + 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, + 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, + 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, + 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, + 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, + 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, + 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, + 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, + 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, + 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, + 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, + 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, + 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, + 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, + 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, + 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, + 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, + 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, + 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, + 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, + 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x46, 0x08, 0x43, 0x46, 0x6c, 0x57, 0xfe, 0xe7, 0x6b, 0xd7, 0x7f, 0x11, + 0x01, 0x06, 0x43, 0x34, 0xd3, 0x90, 0x08, 0x88, 0x14, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x12, 0x45, 0x0d, 0x03, + 0x04, 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x43, 0x22, + 0x6f, 0x9b, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x40, 0x62, 0x83, 0x40, 0xd1, 0x9d, 0x01, 0x00, 0x80, 0x2c, 0x10, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, + 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x8a, 0x45, 0x50, 0x02, 0x85, + 0x30, 0x02, 0x50, 0x06, 0x05, 0x18, 0x50, 0x20, 0x05, 0x54, 0x60, 0xa5, + 0x50, 0x0c, 0x64, 0xc7, 0x12, 0x9c, 0x01, 0x00, 0xb1, 0x18, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, + 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, + 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, + 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, + 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, + 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, + 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, + 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, + 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, + 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, + 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, + 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, + 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, + 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, + 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, + 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, + 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, + 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, + 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, + 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, + 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, + 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, + 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, + 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, + 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, + 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, + 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, + 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, + 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, + 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, + 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, + 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, + 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, + 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, + 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, + 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, + 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, + 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, + 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, + 0x32, 0x64, 0xd4, 0xd8, 0x80, 0x0c, 0xea, 0x09, 0x8b, 0x02, 0x07, 0xc5, + 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, 0x88, 0x64, 0x3d, 0x45, + 0x66, 0x20, 0xca, 0x23, 0x21, 0x94, 0x61, 0x18, 0x86, 0x11, 0x5d, 0x89, + 0xb1, 0x28, 0x18, 0x51, 0x2c, 0x47, 0x00, 0x00, 0x53, 0x44, 0x4b, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, + 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, + 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, + 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, @@ -1332,758 +1941,120 @@ const unsigned char sdl_metallib[] = { 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, - 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, - 0x32, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, - 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, - 0x32, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, - 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, - 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, - 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, - 0x73, 0x69, 0x7a, 0x65, 0x63, 0x6f, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x73, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, - 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, - 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, - 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x59, 0x55, 0x56, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, + 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, + 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x52, + 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x42, + 0x63, 0x6f, 0x65, 0x66, 0x66, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, + 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, - 0x59, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x5f, 0x61, - 0x72, 0x72, 0x61, 0x79, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, - 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x55, 0x56, - 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0x64, 0x78, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x30, 0x11, 0x23, 0x08, - 0x1b, 0x34, 0x82, 0x30, 0x15, 0x23, 0x08, 0x93, 0x31, 0x82, 0x30, 0x1d, - 0x23, 0x08, 0x0e, 0x30, 0x82, 0x30, 0x21, 0x23, 0x08, 0x53, 0x32, 0x82, - 0x30, 0x29, 0x23, 0x08, 0xd3, 0x32, 0x82, 0x30, 0x31, 0x23, 0x08, 0x53, - 0x33, 0x82, 0x30, 0x39, 0x33, 0x0c, 0x6d, 0x10, 0xb8, 0xc1, 0x0c, 0xc3, - 0x1b, 0x08, 0x70, 0x30, 0x43, 0x30, 0xcc, 0x30, 0xb4, 0x41, 0x1b, 0xc4, - 0xc1, 0x0c, 0x04, 0xf1, 0x06, 0x6f, 0x10, 0x07, 0x33, 0x04, 0xc5, 0x0c, - 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x71, 0x10, 0x07, 0x89, 0x32, - 0x43, 0x20, 0x0a, 0x33, 0x20, 0x71, 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, - 0x0c, 0xc9, 0x1b, 0x40, 0x11, 0x23, 0x25, 0x93, 0x43, 0xcd, 0x00, 0xb5, - 0x41, 0x65, 0xcd, 0xc1, 0x15, 0x07, 0x6f, 0x80, 0x65, 0x73, 0xa0, 0xcd, - 0x41, 0xa2, 0x38, 0xdb, 0x0c, 0x54, 0x1c, 0xcc, 0x41, 0x1c, 0x74, 0xde, - 0x1c, 0xcc, 0x41, 0x1c, 0x74, 0x9f, 0x1d, 0xcc, 0x41, 0x1c, 0x74, 0x60, - 0x70, 0x07, 0x73, 0x10, 0x07, 0x5d, 0x18, 0xcc, 0x20, 0xd1, 0x41, 0x65, - 0xd5, 0xc1, 0xf5, 0x06, 0x6f, 0x80, 0x71, 0xa7, 0x90, 0xd5, 0x81, 0x36, - 0x07, 0x89, 0x18, 0x38, 0x63, 0x30, 0x83, 0x02, 0x07, 0x64, 0x70, 0xc5, - 0xc1, 0x1b, 0x94, 0x41, 0x62, 0x06, 0xce, 0x19, 0xcc, 0xa0, 0xe0, 0x01, - 0x19, 0x5c, 0x6f, 0xf0, 0x06, 0x65, 0x90, 0xa0, 0x81, 0x93, 0x06, 0x33, - 0x24, 0x79, 0xa0, 0x06, 0x57, 0x1c, 0xbc, 0x41, 0xb2, 0x06, 0x0e, 0x1b, - 0xcc, 0x70, 0x90, 0x42, 0x29, 0x98, 0x02, 0x2a, 0xa4, 0x82, 0x2a, 0xac, - 0xc2, 0x0c, 0x83, 0x1c, 0x8c, 0x02, 0x2b, 0x54, 0x18, 0x00, 0x1c, 0xc7, - 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x9c, 0x1b, 0xb8, 0x81, 0x45, - 0x07, 0x7a, 0x60, 0x59, 0x96, 0x1e, 0x70, 0xa6, 0xc0, 0x0a, 0x34, 0xc1, - 0x1b, 0x72, 0x61, 0x0f, 0xf6, 0xa0, 0x0e, 0xe4, 0x20, 0x23, 0x81, 0x09, - 0xba, 0x88, 0x8d, 0xcd, 0xae, 0xcd, 0xa5, 0xed, 0x8d, 0xac, 0x8e, 0xad, - 0xcc, 0xc5, 0x8c, 0x2d, 0xec, 0x6c, 0x6e, 0x14, 0x21, 0x0f, 0xf4, 0xe0, - 0x14, 0x36, 0x36, 0xbb, 0x36, 0x97, 0x34, 0xb2, 0x32, 0x37, 0xba, 0x51, - 0x82, 0x3d, 0xb8, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x6e, 0x2e, - 0xed, 0xcd, 0x6d, 0x94, 0x80, 0x0f, 0x8e, 0x0a, 0x4b, 0x93, 0x73, 0x61, - 0x0b, 0x73, 0x3b, 0xab, 0x0b, 0x3b, 0x2b, 0xfb, 0xb2, 0x2b, 0x93, 0x9b, - 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0xe8, 0x83, 0x9b, 0xc2, 0xd2, 0xe4, 0x5c, - 0xc6, 0xde, 0xda, 0xe0, 0xd2, 0xd8, 0xca, 0xbe, 0xde, 0xe0, 0xe8, 0xd2, - 0xde, 0xdc, 0xe6, 0x46, 0x19, 0xfc, 0xe0, 0x0f, 0x40, 0xe1, 0x98, 0xb0, - 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0x51, - 0x02, 0x56, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, - 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, - 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, - 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, - 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, - 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, - 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, - 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x5b, 0x00, - 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0x00, 0x00, 0x34, 0xcd, 0x00, 0x10, 0x55, 0x03, 0x23, 0x00, 0x54, 0x8d, - 0x00, 0x10, 0x37, 0xd6, 0x00, 0x04, 0xc2, 0x1c, 0xc3, 0x81, 0x61, 0xd4, - 0x95, 0x40, 0x11, 0x10, 0x30, 0x02, 0x30, 0x03, 0x30, 0x46, 0x00, 0x82, - 0x20, 0x88, 0x7f, 0x14, 0xcc, 0x00, 0xcc, 0x41, 0x84, 0x41, 0x18, 0x84, - 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, - 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, - 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, - 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, - 0x00, 0x00, 0x13, 0x84, 0xee, 0xd9, 0x10, 0xbc, 0xc2, 0x86, 0xc1, 0x15, - 0x62, 0x01, 0x16, 0x36, 0x0c, 0xb2, 0x20, 0x0b, 0xb0, 0x00, 0x23, 0x06, - 0xcd, 0x10, 0x82, 0x60, 0x80, 0x89, 0x01, 0xe4, 0x4c, 0x8c, 0xb2, 0x14, - 0x85, 0x37, 0x9a, 0x10, 0x00, 0x83, 0x0c, 0x01, 0xa1, 0x8c, 0x18, 0x38, - 0x43, 0x08, 0x82, 0x81, 0x65, 0x06, 0x52, 0x64, 0x85, 0xc1, 0xd3, 0x38, - 0x08, 0x12, 0x06, 0xa3, 0x09, 0x01, 0x30, 0x86, 0x10, 0x6c, 0x73, 0x0c, - 0x44, 0xd0, 0x8c, 0x18, 0x38, 0x43, 0x08, 0x82, 0x81, 0xa5, 0x06, 0x56, - 0xa5, 0x9d, 0xc1, 0x14, 0x49, 0x0c, 0x53, 0x06, 0xa3, 0x09, 0x01, 0x30, - 0x86, 0x10, 0x7c, 0x73, 0x0c, 0x44, 0x00, 0x1d, 0xe7, 0x2d, 0x05, 0x41, - 0x19, 0x64, 0x08, 0x1e, 0xcb, 0x88, 0x00, 0xfc, 0x29, 0x0c, 0x82, 0xb2, - 0x8b, 0x21, 0x0c, 0xcc, 0x00, 0x0e, 0x2e, 0xf0, 0x96, 0x82, 0xa0, 0x0c, - 0x32, 0x04, 0x15, 0x37, 0x62, 0x70, 0x08, 0x21, 0x08, 0x16, 0xfe, 0xf1, - 0xe0, 0x81, 0x11, 0xec, 0x62, 0x30, 0x83, 0x35, 0xb0, 0x83, 0x0b, 0xbc, - 0xa5, 0x20, 0x28, 0x83, 0x0c, 0x81, 0x16, 0x06, 0x23, 0x06, 0x87, 0x10, - 0x82, 0x60, 0xe1, 0x1f, 0x4f, 0x1f, 0x2c, 0xc1, 0x2e, 0x86, 0x35, 0x80, - 0x03, 0x3b, 0xb8, 0xc0, 0x5b, 0x0a, 0x82, 0x32, 0xc8, 0x10, 0x7c, 0x66, - 0x30, 0x62, 0x70, 0x08, 0x21, 0x08, 0x16, 0xfe, 0xf1, 0x88, 0x02, 0x14, - 0xcc, 0x31, 0x80, 0xc1, 0xd2, 0x07, 0x73, 0x0c, 0xc1, 0x01, 0x0a, 0x73, - 0x0c, 0xc1, 0x20, 0x0a, 0x16, 0x4c, 0xe2, 0x9f, 0x41, 0x40, 0x0c, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x27, 0x90, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0x90, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x2f, 0x00, - 0x00, 0x00, 0x12, 0x03, 0x94, 0x70, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x44, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, - 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x1b, 0x00, - 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, - 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x21, 0x01, 0x00, - 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, - 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x64, 0x6f, - 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, - 0x65, 0x5f, 0x32, 0x64, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x76, - 0x34, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, - 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, - 0x2e, 0x34, 0x33, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, - 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, - 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, - 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x78, 0x0e, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, - 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x4d, 0x03, - 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, - 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, - 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, - 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, - 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, - 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, - 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, - 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x94, 0x00, - 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, - 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, - 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, - 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, - 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, - 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, - 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, - 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, - 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, - 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, - 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, - 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, - 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, - 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, - 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, - 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, - 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, - 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, - 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, - 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, - 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, - 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, - 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, - 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, - 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, - 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, - 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, - 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, - 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, - 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, - 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, - 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, - 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, - 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, - 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, - 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, - 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, - 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, - 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, - 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, - 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x03, - 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, 0x00, 0x6d, 0x58, 0x06, 0x02, 0x48, - 0x80, 0x05, 0xa8, 0x82, 0x34, 0x00, 0x85, 0x0d, 0x06, 0x51, 0x00, 0x0b, - 0x50, 0x6d, 0x30, 0x0a, 0x03, 0x58, 0x80, 0x6a, 0x83, 0x61, 0x1c, 0xc0, - 0x02, 0x54, 0x1b, 0x8c, 0xe3, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, - 0xa8, 0x0d, 0x0a, 0xf2, 0xff, 0xff, 0xff, 0xff, 0x03, 0xd0, 0x06, 0xc0, - 0x1a, 0x00, 0x12, 0x50, 0x6d, 0x30, 0x92, 0x00, 0x58, 0x80, 0x6a, 0x83, - 0xa1, 0x08, 0xc0, 0x02, 0x54, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x13, 0x8c, 0x40, 0x18, 0x88, 0xc2, 0x98, 0x10, 0x1c, 0x13, - 0x06, 0x24, 0x51, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x2a, 0x00, - 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, - 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, - 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x74, 0x33, 0x00, 0xc3, 0x08, - 0x04, 0x30, 0x8c, 0x20, 0x00, 0x83, 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, - 0x07, 0x49, 0x53, 0x44, 0x09, 0x93, 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, - 0x40, 0x20, 0x82, 0x10, 0x42, 0x06, 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, - 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, - 0xa7, 0x31, 0x02, 0x60, 0x10, 0xe1, 0x08, 0x2e, 0x92, 0xa6, 0x88, 0x12, - 0x26, 0xff, 0x97, 0x00, 0xe6, 0x59, 0x88, 0xe8, 0x9f, 0xc6, 0x08, 0x80, - 0x41, 0x84, 0x44, 0x28, 0x48, 0x08, 0x62, 0x18, 0x84, 0x14, 0xad, 0x32, - 0x00, 0x42, 0xa8, 0xcd, 0x11, 0x20, 0x46, 0x08, 0x6f, 0x8e, 0x20, 0x98, - 0x23, 0x00, 0x83, 0x61, 0x04, 0x41, 0x2a, 0x0a, 0x44, 0x4a, 0xc4, 0x19, - 0x01, 0x90, 0x44, 0x07, 0x02, 0x52, 0x40, 0x0e, 0x23, 0x0c, 0xd2, 0x20, - 0x42, 0x20, 0xcc, 0x11, 0x80, 0xc2, 0x20, 0x02, 0x21, 0x8c, 0x00, 0x00, - 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, - 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, - 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, - 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, - 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, - 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, - 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, - 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, - 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, - 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, - 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, - 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, - 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, - 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, - 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, - 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, - 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, - 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, - 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, - 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, - 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, - 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, - 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, - 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, - 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, - 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, - 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, - 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, - 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, - 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x46, 0x6c, 0x57, - 0xfe, 0xe7, 0x5b, 0xdb, 0x7f, 0x11, 0x01, 0x06, 0x43, 0x34, 0xd3, 0x90, - 0x08, 0x88, 0x16, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x18, 0x12, 0x45, 0x4d, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x43, 0x22, 0x6f, 0xa3, 0x80, 0x00, 0x18, 0x00, - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x62, 0x83, 0x40, 0xd1, 0xa7, - 0x01, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, - 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, - 0x43, 0x92, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x20, 0x65, 0x50, - 0x80, 0x01, 0x05, 0x54, 0x60, 0xa5, 0x50, 0x0c, 0xa4, 0x47, 0x00, 0xe8, - 0x8e, 0x25, 0x38, 0x02, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, - 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, - 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, - 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, - 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, - 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, - 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, - 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, - 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, - 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, - 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, - 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, - 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, - 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, - 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, - 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, - 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, - 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, - 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, - 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, - 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, - 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, - 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, - 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, - 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, - 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, - 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, - 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, - 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, - 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, - 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, - 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, - 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, - 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, - 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, - 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, - 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, - 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, - 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, - 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, - 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, - 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, - 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x32, 0x9a, - 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, - 0xd4, 0xd6, 0x80, 0x0c, 0x76, 0x09, 0x8b, 0xe2, 0x06, 0xc5, 0xc6, 0x91, - 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, 0x88, 0x94, 0x3d, 0x06, 0xa2, 0x3c, - 0x12, 0x12, 0x5d, 0x03, 0x65, 0x18, 0x86, 0x61, 0x24, 0xc6, 0xa2, 0x60, - 0x44, 0xb1, 0x1c, 0x01, 0x00, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, - 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, - 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, - 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, - 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, - 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, - 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, - 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, - 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, - 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, - 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, - 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, - 0x74, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x6e, 0x6f, 0x5f, 0x70, 0x65, - 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x61, 0x69, 0x72, - 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, - 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, - 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, - 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, - 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, - 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, - 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, - 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, - 0x63, 0x6f, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x74, 0x72, 0x75, 0x63, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x66, - 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x52, - 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x42, - 0x63, 0x6f, 0x65, 0x66, 0x66, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, - 0x64, 0x65, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, - 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, - 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x59, 0x74, 0x65, 0x78, - 0x55, 0x56, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x64, 0x78, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x20, 0x0d, 0x23, 0x08, - 0xd7, 0x33, 0x82, 0x20, 0x11, 0x23, 0x08, 0x52, 0x31, 0x82, 0x20, 0x19, - 0x23, 0x08, 0x0c, 0x30, 0x82, 0x20, 0x1d, 0x23, 0x08, 0x12, 0x32, 0x82, - 0x20, 0x25, 0x23, 0x08, 0x92, 0x32, 0x82, 0x20, 0x2d, 0x23, 0x08, 0x12, - 0x33, 0x82, 0x20, 0x35, 0x33, 0x0c, 0x6c, 0x10, 0xb4, 0xc1, 0x0c, 0x83, - 0x1b, 0x08, 0x6f, 0x30, 0x43, 0x30, 0xcc, 0x30, 0xb0, 0x01, 0x1b, 0xc0, - 0xc1, 0x0c, 0x04, 0xe1, 0x06, 0x6e, 0x00, 0x07, 0x33, 0x04, 0xc5, 0x0c, - 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x70, 0x00, 0x07, 0x89, 0x32, - 0x43, 0x10, 0x0a, 0x33, 0x20, 0x70, 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, - 0x0c, 0x89, 0x1b, 0x40, 0x11, 0x23, 0x25, 0x93, 0x43, 0xcd, 0x00, 0xb1, - 0x41, 0x65, 0xc9, 0xc1, 0x05, 0x07, 0x6e, 0x80, 0x65, 0x72, 0xa0, 0xc9, - 0x41, 0xa2, 0x38, 0xdb, 0x0c, 0x14, 0x1c, 0xc8, 0x01, 0x1c, 0x74, 0x9e, - 0x1c, 0xc8, 0x01, 0x1c, 0x74, 0x5f, 0x1d, 0xc8, 0x01, 0x1c, 0x74, 0x60, - 0x60, 0x07, 0x72, 0x00, 0x07, 0x5d, 0x18, 0xcc, 0x20, 0xcd, 0x41, 0x65, - 0xd1, 0xc1, 0xe5, 0x06, 0x6e, 0x80, 0x71, 0xa6, 0x90, 0xd1, 0x81, 0x26, - 0x07, 0x89, 0x18, 0x38, 0x63, 0x30, 0x83, 0xf2, 0x06, 0x64, 0x70, 0xc1, - 0x81, 0x1b, 0x94, 0x41, 0x62, 0x06, 0xce, 0x19, 0xcc, 0xa0, 0xdc, 0x01, - 0x19, 0x5c, 0x6e, 0xe0, 0x06, 0x65, 0x90, 0x98, 0x81, 0x83, 0x06, 0x33, - 0x24, 0x78, 0x90, 0x06, 0x17, 0x1c, 0xb8, 0x41, 0xa2, 0x06, 0xce, 0x1a, - 0xcc, 0x70, 0x8c, 0x02, 0x29, 0x94, 0xc2, 0x29, 0xa0, 0x42, 0x2a, 0xa8, - 0xc2, 0x0c, 0x43, 0x1c, 0x88, 0xc2, 0x2a, 0x54, 0x18, 0x00, 0x1c, 0xc7, - 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x9c, 0x1b, 0xb8, 0x81, 0x45, - 0x07, 0x7a, 0x60, 0x59, 0x96, 0x1e, 0x70, 0xa6, 0xc0, 0x0a, 0x34, 0xc1, - 0x1b, 0x72, 0x61, 0x0f, 0xf6, 0xa0, 0x0e, 0xe4, 0x20, 0x23, 0x81, 0x09, - 0xba, 0x88, 0x8d, 0xcd, 0xae, 0xcd, 0xa5, 0xed, 0x8d, 0xac, 0x8e, 0xad, - 0xcc, 0xc5, 0x8c, 0x2d, 0xec, 0x6c, 0x6e, 0x14, 0x01, 0x0f, 0xf2, 0xe0, - 0x14, 0x36, 0x36, 0xbb, 0x36, 0x97, 0x34, 0xb2, 0x32, 0x37, 0xba, 0x51, - 0x02, 0x3d, 0xb8, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x6e, 0x2e, - 0xed, 0xcd, 0x6d, 0x94, 0x60, 0x0f, 0x8e, 0x0a, 0x4b, 0x93, 0x73, 0x61, - 0x0b, 0x73, 0x3b, 0xab, 0x0b, 0x3b, 0x2b, 0xfb, 0xb2, 0x2b, 0x93, 0x9b, - 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0xe0, 0x83, 0x9b, 0xc2, 0xd2, 0xe4, 0x5c, - 0xc6, 0xde, 0xda, 0xe0, 0xd2, 0xd8, 0xca, 0xbe, 0xde, 0xe0, 0xe8, 0xd2, - 0xde, 0xdc, 0xe6, 0x46, 0x19, 0xfa, 0xc0, 0x0f, 0xfe, 0xe0, 0x98, 0xb0, - 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0x51, - 0x82, 0x55, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, - 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, - 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, - 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, - 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, - 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, - 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, - 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x53, 0x00, - 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0e, 0x00, - 0x00, 0x00, 0x14, 0x6b, 0x60, 0x04, 0x80, 0xe4, 0x0c, 0x00, 0xcd, 0x11, - 0x00, 0xc2, 0x63, 0x0d, 0x40, 0x20, 0xcc, 0x31, 0x18, 0x59, 0x36, 0xc7, - 0x60, 0x10, 0xd9, 0x58, 0x03, 0x30, 0x10, 0x04, 0x46, 0x00, 0x66, 0x00, - 0xc6, 0x08, 0x40, 0x10, 0x04, 0xf1, 0x8f, 0xc2, 0x0c, 0xc0, 0x1c, 0x04, - 0x18, 0x80, 0x01, 0x18, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x30, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, - 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, - 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, - 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, - 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, 0xcd, 0xd9, 0x10, 0xb8, - 0xc2, 0x86, 0xa1, 0x15, 0x60, 0xe1, 0x15, 0x36, 0x0c, 0xb1, 0x10, 0x0b, - 0xaf, 0x00, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x40, 0x89, 0x01, 0xe4, - 0x4c, 0x8d, 0xc2, 0x14, 0x85, 0x37, 0x9a, 0x10, 0x00, 0x83, 0x0c, 0x01, - 0xa1, 0x8c, 0x18, 0x34, 0x43, 0x08, 0x82, 0x01, 0x55, 0x06, 0x52, 0x64, - 0x41, 0xcd, 0x83, 0x20, 0x61, 0x30, 0x9a, 0x10, 0x00, 0x83, 0x0c, 0xc1, - 0xc1, 0x0c, 0x32, 0x10, 0x01, 0x73, 0x58, 0x5e, 0x0a, 0x42, 0x19, 0x64, - 0x08, 0x16, 0xc9, 0x88, 0x00, 0xfc, 0xa9, 0x0b, 0x65, 0x97, 0xa1, 0x13, - 0x03, 0x36, 0xb8, 0x20, 0x2f, 0x05, 0xa1, 0x0c, 0x32, 0x04, 0x11, 0x36, - 0x62, 0x70, 0x08, 0x21, 0x08, 0x16, 0xfe, 0xd1, 0xcc, 0x81, 0x11, 0xec, - 0x32, 0x88, 0xc1, 0x19, 0xc8, 0xc1, 0x05, 0x79, 0x29, 0x08, 0x65, 0x90, - 0x21, 0xb0, 0xba, 0x11, 0x83, 0x43, 0x08, 0x41, 0xb0, 0xf0, 0x8f, 0x06, - 0x0f, 0x96, 0x60, 0x97, 0xe1, 0x0c, 0xd8, 0x40, 0x0e, 0x2e, 0xc8, 0x4b, - 0x41, 0x28, 0x83, 0x0c, 0xc1, 0x26, 0x06, 0x23, 0x06, 0x87, 0x10, 0x82, - 0x60, 0xe1, 0x1f, 0x4d, 0x1f, 0x40, 0xc1, 0x1c, 0x03, 0xb7, 0xe4, 0xc1, - 0x1c, 0x43, 0x70, 0xf0, 0xc1, 0x1c, 0x43, 0x30, 0xf8, 0x81, 0x05, 0x93, - 0xf8, 0x67, 0x10, 0x10, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x86, - 0x25, 0x88, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, - 0xfa, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, - 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x38, 0x01, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, - 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x1e, 0x00, - 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x12, 0x03, - 0x94, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, - 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, - 0x69, 0x72, 0x2e, 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, - 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, - 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, - 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x61, + 0x59, 0x74, 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, + 0x73, 0x00, 0x00, 0x00, 0x44, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x82, 0x10, 0x0d, 0x23, 0x08, 0x96, 0x33, 0x82, 0x10, 0x11, 0x23, + 0x08, 0x51, 0x31, 0x82, 0x10, 0x19, 0x23, 0x08, 0x0b, 0x30, 0x82, 0x10, + 0x1d, 0x23, 0x08, 0x11, 0x32, 0x82, 0x10, 0x25, 0x23, 0x08, 0x91, 0x32, + 0x82, 0x10, 0x2d, 0x23, 0x08, 0x11, 0x33, 0x82, 0x10, 0x35, 0x33, 0x0c, + 0x6d, 0x10, 0xb8, 0xc1, 0x0c, 0xc3, 0x1b, 0x08, 0x70, 0x30, 0x43, 0x30, + 0xcc, 0x30, 0xb4, 0x41, 0x1b, 0xc4, 0xc1, 0x0c, 0x04, 0xf1, 0x06, 0x6f, + 0x10, 0x07, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, + 0x20, 0x71, 0x10, 0x07, 0x89, 0x32, 0x43, 0x20, 0x0a, 0x33, 0x20, 0x71, + 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0xc9, 0x1b, 0x40, 0x11, 0x23, + 0x25, 0x8a, 0x33, 0xcd, 0x90, 0xb4, 0x01, 0x44, 0x31, 0x52, 0x52, 0x39, + 0xd6, 0x0c, 0x54, 0x1c, 0xd4, 0x41, 0x1c, 0x70, 0x5d, 0x1d, 0xd4, 0x41, + 0x1c, 0x70, 0x9e, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0xdf, 0x1d, 0xd4, 0x41, + 0x1c, 0x70, 0x60, 0x30, 0x83, 0x34, 0x07, 0x17, 0x46, 0x07, 0xd9, 0x1b, + 0xbc, 0x81, 0xb6, 0x9d, 0x42, 0x18, 0xd0, 0x81, 0x18, 0xd4, 0x41, 0x32, + 0x06, 0x0e, 0x19, 0xcc, 0xa0, 0xc0, 0x41, 0x19, 0x64, 0x71, 0xf0, 0x06, + 0x66, 0x90, 0x9c, 0x81, 0x83, 0x06, 0x33, 0x28, 0x78, 0x50, 0x06, 0xd9, + 0x1b, 0xbc, 0x81, 0x19, 0x24, 0x67, 0xe0, 0xa4, 0xc1, 0x0c, 0x49, 0x1e, + 0xa8, 0x41, 0x16, 0x07, 0x6f, 0x90, 0xac, 0x81, 0xc3, 0x06, 0x33, 0x1c, + 0xa4, 0x50, 0x0a, 0xa6, 0x80, 0x0a, 0xa9, 0xa0, 0x0a, 0xab, 0x30, 0xc3, + 0x20, 0x07, 0xa3, 0xc0, 0x0a, 0x15, 0x06, 0x00, 0xc7, 0x71, 0x1c, 0xc7, + 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xe7, 0x06, 0x6e, 0x60, 0xd1, 0x81, 0x1e, + 0x58, 0x96, 0xa5, 0x07, 0x9c, 0x29, 0xb0, 0x02, 0x2b, 0xd8, 0x86, 0x5f, + 0xd8, 0x83, 0x3d, 0xa8, 0x03, 0x39, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, + 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, + 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0xc8, 0x03, 0x3d, 0x38, 0x85, 0x8d, + 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x60, 0x0f, + 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, + 0x1b, 0x25, 0xe0, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, + 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, + 0xdc, 0x46, 0x09, 0xfa, 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, + 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, + 0xb9, 0x51, 0x06, 0x3f, 0xf8, 0x03, 0x50, 0x38, 0x26, 0x2c, 0x4d, 0xce, + 0xc5, 0x4c, 0x2e, 0xec, 0xac, 0xad, 0xcc, 0x8d, 0x6e, 0x94, 0x80, 0x15, + 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x04, 0x6b, 0x60, 0x04, 0x80, 0xe2, 0x0c, 0x00, 0xc9, 0x11, 0x80, 0xb1, + 0x84, 0x00, 0xa0, 0x3b, 0xd6, 0x00, 0x04, 0xc2, 0x1c, 0x83, 0x81, 0x61, + 0x73, 0x0c, 0x06, 0x81, 0x8d, 0x35, 0x00, 0x03, 0x41, 0x79, 0x04, 0x80, + 0xc0, 0x08, 0xc0, 0x0c, 0xc0, 0x18, 0x01, 0x08, 0x82, 0x20, 0xfe, 0x51, + 0x98, 0x01, 0x98, 0x83, 0x08, 0x83, 0x30, 0x08, 0x03, 0x31, 0x20, 0x31, + 0x03, 0x00, 0x00, 0x00, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x30, 0x91, + 0xc1, 0x14, 0x55, 0x50, 0xf3, 0x18, 0x06, 0x18, 0x8c, 0x26, 0x04, 0xc0, + 0x20, 0x43, 0x50, 0x30, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x30, 0x9d, + 0x41, 0x45, 0x61, 0x13, 0x24, 0x25, 0xc9, 0x18, 0x8c, 0x26, 0x04, 0xc0, + 0x20, 0x43, 0x80, 0x44, 0x83, 0x0c, 0xc1, 0xf1, 0x0c, 0x32, 0x14, 0xc1, + 0x73, 0x1c, 0x5e, 0x0a, 0x42, 0x19, 0x64, 0x08, 0x9a, 0xca, 0x88, 0x00, + 0xfc, 0x37, 0x19, 0xc0, 0x60, 0x72, 0x83, 0x0b, 0xf0, 0x52, 0x10, 0xca, + 0x20, 0x43, 0x20, 0x69, 0x23, 0x06, 0x87, 0x10, 0x82, 0x60, 0xe1, 0x1f, + 0x4c, 0x1d, 0x14, 0xc1, 0x26, 0x43, 0x19, 0x60, 0x74, 0x70, 0x01, 0x5e, + 0x0a, 0x42, 0x19, 0x64, 0x08, 0xae, 0x6f, 0xc4, 0xe0, 0x10, 0x42, 0x10, + 0x2c, 0xfc, 0x83, 0xd1, 0x03, 0x25, 0xd8, 0x64, 0x50, 0x83, 0xae, 0x0e, + 0x2e, 0xc0, 0x4b, 0x41, 0x28, 0x83, 0x0c, 0x01, 0x47, 0x06, 0x23, 0x06, + 0x87, 0x10, 0x82, 0x60, 0xe1, 0x1f, 0xcc, 0x1f, 0x3c, 0xc1, 0x1c, 0x43, + 0xb7, 0xec, 0xc1, 0x1c, 0x43, 0x70, 0xf8, 0xc1, 0x1c, 0x43, 0x30, 0x80, + 0x82, 0x05, 0x74, 0x20, 0xfe, 0x19, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xfb, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x38, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe3, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x32, 0x31, + 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, + 0x2e, 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, + 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, + 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x84, 0x0e, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, - 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x50, 0x03, 0x00, 0x00, 0x0b, 0x02, - 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, - 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, - 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, - 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, - 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, - 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, - 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, - 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x1b, 0xcc, - 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, - 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, - 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, - 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, - 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, - 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, - 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, - 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, - 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, - 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, - 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, - 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, - 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, - 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, - 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, - 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, - 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, - 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, - 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, - 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, - 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, - 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, - 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, - 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, - 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, - 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, - 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, - 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, - 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, - 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, - 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, - 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, - 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, - 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, - 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, - 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, - 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, - 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, - 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, - 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, - 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x03, 0x90, 0x00, 0x0b, 0x50, - 0x05, 0x69, 0x00, 0x6d, 0x58, 0x06, 0x02, 0x48, 0x80, 0x05, 0xa8, 0x82, - 0x34, 0x00, 0x85, 0x0d, 0x06, 0x51, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x0a, - 0x03, 0x58, 0x80, 0x6a, 0x83, 0x61, 0x1c, 0xc0, 0x02, 0x54, 0x1b, 0x8c, - 0xe3, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x0a, 0xf2, - 0xff, 0xff, 0xff, 0xff, 0x03, 0xd0, 0x06, 0xc0, 0x1a, 0x00, 0x12, 0x50, - 0x6d, 0x30, 0x92, 0x00, 0x58, 0x80, 0x6a, 0x83, 0xa1, 0x08, 0xc0, 0x02, - 0x54, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8c, - 0x40, 0x18, 0x88, 0xc2, 0x98, 0x10, 0x1c, 0x13, 0x06, 0x24, 0x51, 0x00, - 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x32, 0x22, - 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, - 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, - 0xa4, 0x4c, 0x10, 0x74, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, - 0x00, 0x83, 0x08, 0x41, 0x30, 0x8c, 0x30, 0x00, 0x07, 0x49, 0x53, 0x44, - 0x09, 0x93, 0x2f, 0xbb, 0x6f, 0x47, 0x08, 0xce, 0x40, 0x20, 0x82, 0x10, - 0x42, 0x06, 0x11, 0x0a, 0xe1, 0x28, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, - 0x89, 0xb8, 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0xa7, 0x31, 0x02, 0x60, - 0x10, 0xe1, 0x08, 0x2e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x97, 0x00, - 0xe6, 0x59, 0x88, 0xe8, 0x9f, 0xc6, 0x08, 0x80, 0x41, 0x84, 0x44, 0x28, - 0x48, 0x08, 0x62, 0x18, 0x84, 0x14, 0xad, 0x32, 0x00, 0x42, 0xa8, 0xcd, - 0x11, 0x20, 0x46, 0x08, 0x6f, 0x8e, 0x20, 0x98, 0x23, 0x00, 0x83, 0x61, - 0x04, 0x41, 0x2a, 0x0a, 0x44, 0x4a, 0xc4, 0x19, 0x01, 0x90, 0x44, 0x07, - 0x02, 0x52, 0x40, 0x0e, 0x23, 0x0c, 0xd2, 0x20, 0x42, 0x20, 0xcc, 0x11, - 0x80, 0xc2, 0x20, 0x02, 0x21, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x13, 0xc0, - 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, - 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, - 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, - 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, - 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, - 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, - 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, - 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, - 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, - 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, - 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, - 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, - 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, - 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, - 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, - 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, - 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, - 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, - 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, - 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, - 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, - 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, - 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, - 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, - 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, - 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, - 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, - 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, - 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, - 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, - 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, - 0xc8, 0x81, 0x46, 0x08, 0x43, 0x46, 0x6c, 0x57, 0xfe, 0xe7, 0x6b, 0xd7, - 0x7f, 0x11, 0x01, 0x06, 0x43, 0x34, 0xd3, 0x90, 0x08, 0x88, 0x16, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x12, 0x45, - 0x4d, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x43, 0x22, 0x6f, 0xa3, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x40, 0x62, 0x83, 0x40, 0x51, 0xa9, 0x01, 0x00, 0x80, 0x2c, - 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, - 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x92, 0x45, 0x50, - 0x02, 0x85, 0x30, 0x02, 0x50, 0x20, 0x65, 0x50, 0x80, 0x01, 0x05, 0x54, - 0x60, 0xa5, 0x50, 0x0c, 0xa4, 0x47, 0x00, 0xe8, 0x8e, 0x25, 0x38, 0x02, - 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, - 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, - 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, - 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, - 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, - 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, - 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, - 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, - 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, - 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, - 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, - 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, - 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, - 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, - 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, - 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, - 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, - 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, - 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, - 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, - 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, - 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, - 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, - 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, - 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, - 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, - 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, - 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, - 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, - 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, - 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, - 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, - 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, - 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, - 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, - 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, - 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, - 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, - 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, - 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, - 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, - 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, - 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, - 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xd6, 0x80, 0x0c, - 0x76, 0x09, 0x8b, 0xe2, 0x06, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, - 0x22, 0x31, 0x88, 0x94, 0x3d, 0x06, 0xa2, 0x3c, 0x12, 0x12, 0x5d, 0x03, - 0x65, 0x18, 0x86, 0x61, 0x24, 0xc6, 0xa2, 0x60, 0x44, 0xb1, 0x1c, 0x01, - 0x00, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, - 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, - 0x34, 0x33, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, - 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x29, 0x4d, 0x65, 0x74, - 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, - 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, - 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, - 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, - 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, - 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, - 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, - 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, - 0x34, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, - 0x69, 0x72, 0x2e, 0x6e, 0x6f, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, - 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, - 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, - 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, - 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x66, - 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, - 0x64, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, - 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, - 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, - 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, - 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, - 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x63, 0x6f, 0x6c, 0x61, - 0x69, 0x72, 0x2e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, - 0x33, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, - 0x66, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, - 0x66, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x65, - 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, - 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, - 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x3e, 0x74, 0x65, 0x78, 0x59, 0x74, 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, - 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x64, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x82, 0x20, 0x0d, 0x23, 0x08, 0xd7, 0x33, 0x82, 0x20, - 0x11, 0x23, 0x08, 0x52, 0x31, 0x82, 0x20, 0x19, 0x23, 0x08, 0x0c, 0x30, - 0x82, 0x20, 0x1d, 0x23, 0x08, 0x12, 0x32, 0x82, 0x20, 0x25, 0x23, 0x08, - 0x92, 0x32, 0x82, 0x20, 0x2d, 0x23, 0x08, 0x12, 0x33, 0x82, 0x20, 0x35, - 0x33, 0x0c, 0x6c, 0x10, 0xb4, 0xc1, 0x0c, 0x83, 0x1b, 0x08, 0x6f, 0x30, - 0x43, 0x30, 0xcc, 0x30, 0xb0, 0x01, 0x1b, 0xc0, 0xc1, 0x0c, 0x04, 0xe1, - 0x06, 0x6e, 0x00, 0x07, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, - 0xcc, 0x50, 0x20, 0x70, 0x00, 0x07, 0x89, 0x32, 0x43, 0x10, 0x0a, 0x33, - 0x20, 0x70, 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0x89, 0x1b, 0x40, - 0x11, 0x23, 0x25, 0x93, 0x43, 0xcd, 0x00, 0xb1, 0x41, 0x65, 0xc9, 0xc1, - 0x05, 0x07, 0x6e, 0x80, 0x65, 0x72, 0xa0, 0xc9, 0x41, 0xa2, 0x38, 0xdb, - 0x0c, 0x14, 0x1c, 0xc8, 0x01, 0x1c, 0x74, 0x9e, 0x1c, 0xc8, 0x01, 0x1c, - 0x74, 0x5f, 0x1d, 0xc8, 0x01, 0x1c, 0x74, 0x60, 0x60, 0x07, 0x72, 0x00, - 0x07, 0x5d, 0x18, 0xcc, 0x20, 0xcd, 0x41, 0x65, 0xd1, 0xc1, 0xe5, 0x06, - 0x6e, 0x80, 0x71, 0xa6, 0x90, 0xd1, 0x81, 0x26, 0x07, 0x89, 0x18, 0x38, - 0x63, 0x30, 0x83, 0xf2, 0x06, 0x64, 0x70, 0xc1, 0x81, 0x1b, 0x94, 0x41, - 0x62, 0x06, 0xce, 0x19, 0xcc, 0xa0, 0xdc, 0x01, 0x19, 0x5c, 0x6e, 0xe0, - 0x06, 0x65, 0x90, 0x98, 0x81, 0x83, 0x06, 0x33, 0x24, 0x78, 0x90, 0x06, - 0x17, 0x1c, 0xb8, 0x41, 0xa2, 0x06, 0xce, 0x1a, 0xcc, 0x70, 0x8c, 0x02, - 0x29, 0x94, 0xc2, 0x29, 0xa0, 0x42, 0x2a, 0xa8, 0xc2, 0x0c, 0x43, 0x1c, - 0x88, 0xc2, 0x2a, 0x54, 0x18, 0x00, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, - 0x1c, 0xc7, 0x71, 0x9c, 0x1b, 0xb8, 0x81, 0x45, 0x07, 0x7a, 0x60, 0x59, - 0x96, 0x1e, 0x70, 0xa6, 0xc0, 0x0a, 0x34, 0xc1, 0x1b, 0x72, 0x61, 0x0f, - 0xf6, 0xa0, 0x0e, 0xe4, 0x20, 0x23, 0x81, 0x09, 0xba, 0x88, 0x8d, 0xcd, - 0xae, 0xcd, 0xa5, 0xed, 0x8d, 0xac, 0x8e, 0xad, 0xcc, 0xc5, 0x8c, 0x2d, - 0xec, 0x6c, 0x6e, 0x14, 0x01, 0x0f, 0xf2, 0xe0, 0x14, 0x36, 0x36, 0xbb, - 0x36, 0x97, 0x34, 0xb2, 0x32, 0x37, 0xba, 0x51, 0x02, 0x3d, 0xb8, 0x25, - 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x94, - 0x60, 0x0f, 0x8e, 0x0a, 0x4b, 0x93, 0x73, 0x61, 0x0b, 0x73, 0x3b, 0xab, - 0x0b, 0x3b, 0x2b, 0xfb, 0xb2, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, - 0x25, 0xe0, 0x83, 0x9b, 0xc2, 0xd2, 0xe4, 0x5c, 0xc6, 0xde, 0xda, 0xe0, - 0xd2, 0xd8, 0xca, 0xbe, 0xde, 0xe0, 0xe8, 0xd2, 0xde, 0xdc, 0xe6, 0x46, - 0x19, 0xfa, 0xc0, 0x0f, 0xfe, 0xe0, 0x98, 0xb0, 0x34, 0x39, 0x17, 0x33, - 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0x51, 0x82, 0x55, 0x00, 0x00, - 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, - 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, - 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, - 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, - 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, - 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, - 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x13, 0x04, - 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x14, 0x6b, - 0x60, 0x04, 0x80, 0xe4, 0x0c, 0x00, 0xcd, 0x11, 0x80, 0xb1, 0x84, 0x00, - 0x20, 0x3c, 0xd6, 0x00, 0x04, 0xc2, 0x1c, 0x83, 0x91, 0x65, 0x73, 0x0c, - 0x06, 0x91, 0x8d, 0x35, 0x00, 0x03, 0x41, 0x60, 0x04, 0x60, 0x06, 0x60, - 0x8c, 0x00, 0x04, 0x41, 0x10, 0xff, 0x28, 0xcc, 0x00, 0xcc, 0x41, 0x84, - 0x41, 0x18, 0x84, 0x81, 0x18, 0x90, 0x98, 0x01, 0x00, 0x00, 0xf1, 0x30, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, - 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, - 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, - 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, - 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, 0xcd, 0xd9, 0x10, 0xb8, - 0xc2, 0x86, 0xa1, 0x15, 0x60, 0xe1, 0x15, 0x36, 0x0c, 0xb1, 0x10, 0x0b, - 0xaf, 0x00, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x40, 0x91, 0x81, 0x04, - 0x55, 0x0f, 0xe3, 0x18, 0x06, 0x18, 0x8c, 0x26, 0x04, 0xc0, 0x20, 0x43, - 0x50, 0x2c, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x40, 0x9d, 0x01, 0x35, - 0x61, 0xd2, 0x13, 0x25, 0xc9, 0x18, 0x8c, 0x26, 0x04, 0xc0, 0x20, 0x43, - 0x80, 0x40, 0x83, 0x0c, 0xc1, 0xe1, 0x0c, 0x32, 0x14, 0x81, 0x73, 0x5b, - 0x5e, 0x0a, 0x42, 0x19, 0x64, 0x08, 0x1a, 0xca, 0x88, 0x00, 0xfc, 0x09, - 0x0c, 0x42, 0xd9, 0x65, 0x00, 0x83, 0x32, 0x78, 0x83, 0x0b, 0xf2, 0x52, - 0x10, 0xca, 0x20, 0x43, 0x30, 0x69, 0x23, 0x06, 0x87, 0x10, 0x82, 0x60, - 0xe1, 0x1f, 0x8d, 0x1d, 0x18, 0xc1, 0x2e, 0x43, 0x19, 0xa8, 0x41, 0x1d, - 0x5c, 0x90, 0x97, 0x82, 0x50, 0x06, 0x19, 0x02, 0xec, 0x1b, 0x31, 0x38, - 0x84, 0x10, 0x04, 0x0b, 0xff, 0x68, 0xf6, 0x60, 0x09, 0x76, 0x19, 0xd4, - 0xe0, 0x0d, 0xea, 0xe0, 0x82, 0xbc, 0x14, 0x84, 0x32, 0xc8, 0x10, 0x74, - 0x64, 0x30, 0x62, 0x70, 0x08, 0x21, 0x08, 0x16, 0xfe, 0xd1, 0x80, 0x02, - 0x14, 0xcc, 0x31, 0x78, 0x0b, 0x1f, 0xcc, 0x31, 0x04, 0xc7, 0x1f, 0xcc, - 0x31, 0x04, 0x43, 0x28, 0x58, 0x30, 0x89, 0x7f, 0x06, 0x01, 0x31, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x06, 0x26, 0x88, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xfa, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x29, 0x00, - 0x00, 0x00, 0x12, 0x03, 0x94, 0x38, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x44, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x98, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x61, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, - 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, - 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe1, 0x00, 0x00, - 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, - 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x64, - 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, - 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, - 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, - 0x31, 0x30, 0x30, 0x31, 0x2e, 0x34, 0x33, 0x61, 0x69, 0x72, 0x36, 0x34, - 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, - 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, - 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00 }; -const unsigned int sdl_metallib_len = 25026; +const unsigned int sdl_metallib_len = 24676; diff --git a/Engine/lib/sdl/src/render/opengl/SDL_glfuncs.h b/Engine/lib/sdl/src/render/opengl/SDL_glfuncs.h index 36846db8c..acdcf8803 100644 --- a/Engine/lib/sdl/src/render/opengl/SDL_glfuncs.h +++ b/Engine/lib/sdl/src/render/opengl/SDL_glfuncs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -73,7 +73,7 @@ SDL_PROC_UNUSED(void, glColor4i, (GLint, GLint, GLint, GLint)) SDL_PROC_UNUSED(void, glColor4iv, (const GLint *)) SDL_PROC_UNUSED(void, glColor4s, (GLshort, GLshort, GLshort, GLshort)) SDL_PROC_UNUSED(void, glColor4sv, (const GLshort *)) -SDL_PROC_UNUSED(void, glColor4ub, +SDL_PROC(void, glColor4ub, (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)) SDL_PROC_UNUSED(void, glColor4ubv, (const GLubyte * v)) SDL_PROC_UNUSED(void, glColor4ui, @@ -86,7 +86,7 @@ SDL_PROC_UNUSED(void, glColorMask, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) SDL_PROC_UNUSED(void, glColorMaterial, (GLenum face, GLenum mode)) -SDL_PROC_UNUSED(void, glColorPointer, +SDL_PROC(void, glColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer)) SDL_PROC_UNUSED(void, glCopyPixels, @@ -111,8 +111,8 @@ SDL_PROC(void, glDepthFunc, (GLenum func)) SDL_PROC_UNUSED(void, glDepthMask, (GLboolean flag)) SDL_PROC_UNUSED(void, glDepthRange, (GLclampd zNear, GLclampd zFar)) SDL_PROC(void, glDisable, (GLenum cap)) -SDL_PROC_UNUSED(void, glDisableClientState, (GLenum array)) -SDL_PROC_UNUSED(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count)) +SDL_PROC(void, glDisableClientState, (GLenum array)) +SDL_PROC(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count)) SDL_PROC_UNUSED(void, glDrawBuffer, (GLenum mode)) SDL_PROC_UNUSED(void, glDrawElements, (GLenum mode, GLsizei count, GLenum type, @@ -125,7 +125,7 @@ SDL_PROC_UNUSED(void, glEdgeFlagPointer, (GLsizei stride, const GLvoid * pointer)) SDL_PROC_UNUSED(void, glEdgeFlagv, (const GLboolean * flag)) SDL_PROC(void, glEnable, (GLenum cap)) -SDL_PROC_UNUSED(void, glEnableClientState, (GLenum array)) +SDL_PROC(void, glEnableClientState, (GLenum array)) SDL_PROC(void, glEnd, (void)) SDL_PROC_UNUSED(void, glEndList, (void)) SDL_PROC_UNUSED(void, glEvalCoord1d, (GLdouble u)) @@ -159,7 +159,7 @@ SDL_PROC_UNUSED(void, glGetBooleanv, (GLenum pname, GLboolean * params)) SDL_PROC_UNUSED(void, glGetClipPlane, (GLenum plane, GLdouble * equation)) SDL_PROC_UNUSED(void, glGetDoublev, (GLenum pname, GLdouble * params)) SDL_PROC(GLenum, glGetError, (void)) -SDL_PROC_UNUSED(void, glGetFloatv, (GLenum pname, GLfloat * params)) +SDL_PROC(void, glGetFloatv, (GLenum pname, GLfloat * params)) SDL_PROC(void, glGetIntegerv, (GLenum pname, GLint * params)) SDL_PROC_UNUSED(void, glGetLightfv, (GLenum light, GLenum pname, GLfloat * params)) @@ -302,14 +302,14 @@ SDL_PROC_UNUSED(void, glPolygonOffset, (GLfloat factor, GLfloat units)) SDL_PROC_UNUSED(void, glPolygonStipple, (const GLubyte * mask)) SDL_PROC_UNUSED(void, glPopAttrib, (void)) SDL_PROC_UNUSED(void, glPopClientAttrib, (void)) -SDL_PROC(void, glPopMatrix, (void)) +SDL_PROC_UNUSED(void, glPopMatrix, (void)) SDL_PROC_UNUSED(void, glPopName, (void)) SDL_PROC_UNUSED(void, glPrioritizeTextures, (GLsizei n, const GLuint * textures, const GLclampf * priorities)) SDL_PROC_UNUSED(void, glPushAttrib, (GLbitfield mask)) SDL_PROC_UNUSED(void, glPushClientAttrib, (GLbitfield mask)) -SDL_PROC(void, glPushMatrix, (void)) +SDL_PROC_UNUSED(void, glPushMatrix, (void)) SDL_PROC_UNUSED(void, glPushName, (GLuint name)) SDL_PROC_UNUSED(void, glRasterPos2d, (GLdouble x, GLdouble y)) SDL_PROC_UNUSED(void, glRasterPos2dv, (const GLdouble * v)) @@ -354,7 +354,7 @@ SDL_PROC_UNUSED(void, glRects, (GLshort x1, GLshort y1, GLshort x2, GLshort y2)) SDL_PROC_UNUSED(void, glRectsv, (const GLshort * v1, const GLshort * v2)) SDL_PROC_UNUSED(GLint, glRenderMode, (GLenum mode)) -SDL_PROC(void, glRotated, +SDL_PROC_UNUSED(void, glRotated, (GLdouble angle, GLdouble x, GLdouble y, GLdouble z)) SDL_PROC(void, glRotatef, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) @@ -401,7 +401,7 @@ SDL_PROC_UNUSED(void, glTexCoord4iv, (const GLint * v)) SDL_PROC_UNUSED(void, glTexCoord4s, (GLshort s, GLshort t, GLshort r, GLshort q)) SDL_PROC_UNUSED(void, glTexCoord4sv, (const GLshort * v)) -SDL_PROC_UNUSED(void, glTexCoordPointer, +SDL_PROC(void, glTexCoordPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer)) SDL_PROC(void, glTexEnvf, (GLenum target, GLenum pname, GLfloat param)) @@ -442,7 +442,7 @@ SDL_PROC(void, glTexSubImage2D, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels)) SDL_PROC_UNUSED(void, glTranslated, (GLdouble x, GLdouble y, GLdouble z)) -SDL_PROC(void, glTranslatef, (GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void, glTranslatef, (GLfloat x, GLfloat y, GLfloat z)) SDL_PROC_UNUSED(void, glVertex2d, (GLdouble x, GLdouble y)) SDL_PROC_UNUSED(void, glVertex2dv, (const GLdouble * v)) SDL_PROC(void, glVertex2f, (GLfloat x, GLfloat y)) @@ -470,7 +470,7 @@ SDL_PROC_UNUSED(void, glVertex4iv, (const GLint * v)) SDL_PROC_UNUSED(void, glVertex4s, (GLshort x, GLshort y, GLshort z, GLshort w)) SDL_PROC_UNUSED(void, glVertex4sv, (const GLshort * v)) -SDL_PROC_UNUSED(void, glVertexPointer, +SDL_PROC(void, glVertexPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer)) SDL_PROC(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height)) diff --git a/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c b/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c index 895a556c7..b5df73ace 100644 --- a/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c +++ b/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,6 @@ #include "../../SDL_internal.h" #if SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED - #include "SDL_hints.h" #include "SDL_opengl.h" #include "../SDL_sysrender.h" @@ -73,6 +72,9 @@ typedef struct SDL_bool cliprect_dirty; SDL_Rect cliprect; SDL_bool texturing; + SDL_bool vertex_array; + SDL_bool color_array; + SDL_bool texture_array; Uint32 color; Uint32 clear_color; } GL_DrawStateCache; @@ -124,15 +126,18 @@ typedef struct GLfloat texh; GLenum format; GLenum formattype; + GL_Shader shader; void *pixels; int pitch; SDL_Rect locked_rect; +#if SDL_HAVE_YUV /* YUV texture support */ SDL_bool yuv; SDL_bool nv12; GLuint utexture; GLuint vtexture; +#endif GL_FBOList *fbo; } GL_TextureData; @@ -577,6 +582,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return -1; } +#if SDL_HAVE_YUV if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { data->yuv = SDL_TRUE; @@ -626,6 +632,58 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) renderdata->glTexImage2D(textype, 0, GL_LUMINANCE_ALPHA, (texture_w+1)/2, (texture_h+1)/2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); } +#endif + + if (texture->format == SDL_PIXELFORMAT_ABGR8888 || texture->format == SDL_PIXELFORMAT_ARGB8888) { + data->shader = SHADER_RGBA; + } else { + data->shader = SHADER_RGB; + } + +#if SDL_HAVE_YUV + if (data->yuv || data->nv12) { + switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) { + case SDL_YUV_CONVERSION_JPEG: + if (data->yuv) { + data->shader = SHADER_YUV_JPEG; + } else if (texture->format == SDL_PIXELFORMAT_NV12) { + data->shader = SHADER_NV12_JPEG; + } else { + data->shader = SHADER_NV21_JPEG; + } + break; + case SDL_YUV_CONVERSION_BT601: + if (data->yuv) { + data->shader = SHADER_YUV_BT601; + } else if (texture->format == SDL_PIXELFORMAT_NV12) { + if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) { + data->shader = SHADER_NV12_RG_BT601; + } else { + data->shader = SHADER_NV12_RA_BT601; + } + } else { + data->shader = SHADER_NV21_BT601; + } + break; + case SDL_YUV_CONVERSION_BT709: + if (data->yuv) { + data->shader = SHADER_YUV_BT709; + } else if (texture->format == SDL_PIXELFORMAT_NV12) { + if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) { + data->shader = SHADER_NV12_RG_BT709; + } else { + data->shader = SHADER_NV12_RA_BT709; + } + } else { + data->shader = SHADER_NV21_BT709; + } + break; + default: + SDL_assert(!"unsupported YUV conversion mode"); + break; + } + } +#endif /* SDL_HAVE_YUV */ return GL_CheckError("", renderer); } @@ -651,6 +709,7 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, renderdata->glTexSubImage2D(textype, 0, rect->x, rect->y, rect->w, rect->h, data->format, data->formattype, pixels); +#if SDL_HAVE_YUV if (data->yuv) { renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, ((pitch + 1) / 2)); @@ -687,10 +746,11 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, (rect->w + 1)/2, (rect->h + 1)/2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pixels); } - +#endif return GL_CheckError("glTexSubImage2D()", renderer); } +#if SDL_HAVE_YUV static int GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, @@ -728,6 +788,38 @@ GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, return GL_CheckError("glTexSubImage2D()", renderer); } +static int +GL_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ + GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; + const GLenum textype = renderdata->textype; + GL_TextureData *data = (GL_TextureData *) texture->driverdata; + + GL_ActivateRenderer(renderer); + + renderdata->drawstate.texture = NULL; /* we trash this state. */ + + renderdata->glBindTexture(textype, data->texture); + renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Ypitch); + renderdata->glTexSubImage2D(textype, 0, rect->x, rect->y, rect->w, + rect->h, data->format, data->formattype, + Yplane); + + + renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, UVpitch / 2); + renderdata->glBindTexture(textype, data->utexture); + renderdata->glTexSubImage2D(textype, 0, rect->x/2, rect->y/2, + (rect->w + 1)/2, (rect->h + 1)/2, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, UVplane); + + return GL_CheckError("glTexSubImage2D()", renderer); +} +#endif + static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch) @@ -768,6 +860,7 @@ GL_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Scale renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, glScaleMode); renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, glScaleMode); +#if SDL_HAVE_YUV if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { renderdata->glBindTexture(textype, data->utexture); @@ -785,6 +878,7 @@ GL_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Scale renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, glScaleMode); renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, glScaleMode); } +#endif } static int @@ -851,171 +945,106 @@ static int GL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) { int i; + GLfloat prevx, prevy; const size_t vertlen = (sizeof (GLfloat) * 2) * count; GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first); + if (!verts) { return -1; } cmd->data.draw.count = count; - /* Offset to hit the center of the pixel. */ - for (i = 0; i < count; i++) { - *(verts++) = 0.5f + points[i].x; - *(verts++) = 0.5f + points[i].y; + /* 0.5f offset to hit the center of the pixel. */ + prevx = 0.5f + points->x; + prevy = 0.5f + points->y; + *(verts++) = prevx; + *(verts++) = prevy; + + /* bump the end of each line segment out a quarter of a pixel, to provoke + the diamond-exit rule. Without this, you won't just drop the last + pixel of the last line segment, but you might also drop pixels at the + edge of any given line segment along the way too. */ + for (i = 1; i < count; i++) { + const GLfloat xstart = prevx; + const GLfloat ystart = prevy; + const GLfloat xend = points[i].x + 0.5f; /* 0.5f to hit pixel center. */ + const GLfloat yend = points[i].y + 0.5f; + /* bump a little in the direction we are moving in. */ + const GLfloat deltax = xend - xstart; + const GLfloat deltay = yend - ystart; + const GLfloat angle = SDL_atan2f(deltay, deltax); + prevx = xend + (SDL_cosf(angle) * 0.25f); + prevy = yend + (SDL_sinf(angle) * 0.25f); + *(verts++) = prevx; + *(verts++) = prevy; } - /* Make the last line segment one pixel longer, to satisfy the - diamond-exit rule. */ - verts -= 4; - { - const GLfloat xstart = verts[0]; - const GLfloat ystart = verts[1]; - const GLfloat xend = verts[2]; - const GLfloat yend = verts[3]; + return 0; +} - if (ystart == yend) { /* horizontal line */ - verts[2] += (xend > xstart) ? 1.0f : -1.0f; - } else if (xstart == xend) { /* vertical line */ - verts[3] += (yend > ystart) ? 1.0f : -1.0f; - } else { /* bump a pixel in the direction we are moving in. */ - const GLfloat deltax = xend - xstart; - const GLfloat deltay = yend - ystart; - const GLfloat angle = SDL_atan2f(deltay, deltax); - verts[2] += SDL_cosf(angle); - verts[3] += SDL_sinf(angle); +static int +GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + GL_TextureData *texturedata = NULL; + int i; + int count = indices ? num_indices : num_vertices; + GLfloat *verts; + size_t sz = 2 * sizeof(GLfloat) + 4 * sizeof(Uint8) + (texture ? 2 : 0) * sizeof(GLfloat); + + verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * sz, 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + if (texture) { + texturedata = (GL_TextureData *) texture->driverdata; + } + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + for (i = 0; i < count; i++) { + int j; + float *xy_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + + *(verts++) = xy_[0] * scale_x; + *(verts++) = xy_[1] * scale_y; + + /* Not really a float, but it is still 4 bytes and will be cast to the + right type in the graphics driver. */ + SDL_memcpy(verts, ((char*)color + j * color_stride), sizeof(*color)); + ++verts; + + if (texture) { + float *uv_ = (float *)((char*)uv + j * uv_stride); + *(verts++) = uv_[0] * texturedata->texw; + *(verts++) = uv_[1] * texturedata->texh; } } - return 0; } static int -GL_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) -{ - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 4 * sizeof (GLfloat), 0, &cmd->data.draw.first); - int i; - - if (!verts) { - return -1; - } - - cmd->data.draw.count = count; - for (i = 0; i < count; i++) { - const SDL_FRect *rect = &rects[i]; - *(verts++) = rect->x; - *(verts++) = rect->y; - *(verts++) = rect->x + rect->w; - *(verts++) = rect->y + rect->h; - } - - return 0; -} - -static int -GL_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) -{ - GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; - GLfloat minx, miny, maxx, maxy; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 8 * sizeof (GLfloat), 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - minx = dstrect->x; - miny = dstrect->y; - maxx = dstrect->x + dstrect->w; - maxy = dstrect->y + dstrect->h; - - minu = (GLfloat) srcrect->x / texture->w; - minu *= texturedata->texw; - maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; - maxu *= texturedata->texw; - minv = (GLfloat) srcrect->y / texture->h; - minv *= texturedata->texh; - maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; - maxv *= texturedata->texh; - - cmd->data.draw.count = 1; - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = maxy; - *(verts++) = minu; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = maxv; - return 0; -} - -static int -GL_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; - GLfloat minx, miny, maxx, maxy; - GLfloat centerx, centery; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 11 * sizeof (GLfloat), 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - centerx = center->x; - centery = center->y; - - if (flip & SDL_FLIP_HORIZONTAL) { - minx = dstrect->w - centerx; - maxx = -centerx; - } - else { - minx = -centerx; - maxx = dstrect->w - centerx; - } - - if (flip & SDL_FLIP_VERTICAL) { - miny = dstrect->h - centery; - maxy = -centery; - } - else { - miny = -centery; - maxy = dstrect->h - centery; - } - - minu = (GLfloat) srcrect->x / texture->w; - minu *= texturedata->texw; - maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; - maxu *= texturedata->texw; - minv = (GLfloat) srcrect->y / texture->h; - minv *= texturedata->texh; - maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; - maxv *= texturedata->texh; - - cmd->data.draw.count = 1; - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = maxy; - *(verts++) = minu; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = maxv; - *(verts++) = (GLfloat) dstrect->x + centerx; - *(verts++) = (GLfloat) dstrect->y + centery; - *(verts++) = (GLfloat) angle; - return 0; -} - -static void SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader shader) { const SDL_BlendMode blend = cmd->data.draw.blend; + SDL_bool vertex_array; + SDL_bool color_array; + SDL_bool texture_array; if (data->drawstate.viewport_dirty) { const SDL_bool istarget = data->drawstate.target != NULL; @@ -1081,78 +1110,83 @@ SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader data->drawstate.texturing = SDL_TRUE; } } + + vertex_array = cmd->command == SDL_RENDERCMD_DRAW_POINTS + || cmd->command == SDL_RENDERCMD_DRAW_LINES + || cmd->command == SDL_RENDERCMD_GEOMETRY; + color_array = cmd->command == SDL_RENDERCMD_GEOMETRY; + texture_array = cmd->data.draw.texture != NULL; + + if (vertex_array != data->drawstate.vertex_array) { + if (vertex_array) { + data->glEnableClientState(GL_VERTEX_ARRAY); + } else { + data->glDisableClientState(GL_VERTEX_ARRAY); + } + data->drawstate.vertex_array = vertex_array; + } + + if (color_array != data->drawstate.color_array) { + if (color_array) { + data->glEnableClientState(GL_COLOR_ARRAY); + } else { + data->glDisableClientState(GL_COLOR_ARRAY); + } + data->drawstate.color_array = color_array; + } + + /* This is a little awkward but should avoid texcoord arrays getting into + a bad state if SDL_GL_BindTexture/UnbindTexture are called. */ + if (texture_array != data->drawstate.texture_array) { + if (texture_array) { + data->glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } else { + data->glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + data->drawstate.texture_array = texture_array; + } + + return 0; } -static void +static int SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd) { SDL_Texture *texture = cmd->data.draw.texture; const GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; - GL_Shader shader; - if (texture->format == SDL_PIXELFORMAT_ABGR8888 || texture->format == SDL_PIXELFORMAT_ARGB8888) { - shader = SHADER_RGBA; - } else { - shader = SHADER_RGB; - } - - if (data->shaders) { - if (texturedata->yuv || texturedata->nv12) { - switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) { - case SDL_YUV_CONVERSION_JPEG: - if (texturedata->yuv) { - shader = SHADER_YUV_JPEG; - } else if (texture->format == SDL_PIXELFORMAT_NV12) { - shader = SHADER_NV12_JPEG; - } else { - shader = SHADER_NV21_JPEG; - } - break; - case SDL_YUV_CONVERSION_BT601: - if (texturedata->yuv) { - shader = SHADER_YUV_BT601; - } else if (texture->format == SDL_PIXELFORMAT_NV12) { - shader = SHADER_NV12_BT601; - } else { - shader = SHADER_NV21_BT601; - } - break; - case SDL_YUV_CONVERSION_BT709: - if (texturedata->yuv) { - shader = SHADER_YUV_BT709; - } else if (texture->format == SDL_PIXELFORMAT_NV12) { - shader = SHADER_NV12_BT709; - } else { - shader = SHADER_NV21_BT709; - } - break; - default: - SDL_assert(!"unsupported YUV conversion mode"); - break; - } - } - } - - SetDrawState(data, cmd, shader); + SetDrawState(data, cmd, texturedata->shader); if (texture != data->drawstate.texture) { const GLenum textype = data->textype; +#if SDL_HAVE_YUV if (texturedata->yuv) { - data->glActiveTextureARB(GL_TEXTURE2_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE2_ARB); + } data->glBindTexture(textype, texturedata->vtexture); - data->glActiveTextureARB(GL_TEXTURE1_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } data->glBindTexture(textype, texturedata->utexture); } if (texturedata->nv12) { - data->glActiveTextureARB(GL_TEXTURE1_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } data->glBindTexture(textype, texturedata->utexture); } - data->glActiveTextureARB(GL_TEXTURE0_ARB); +#endif + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } data->glBindTexture(textype, texturedata->texture); data->drawstate.texture = texture; } + + return 0; } static int @@ -1160,7 +1194,6 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic { /* !!! FIXME: it'd be nice to use a vertex buffer instead of immediate mode... */ GL_RenderData *data = (GL_RenderData *) renderer->driverdata; - size_t i; if (GL_ActivateRenderer(renderer) < 0) { return -1; @@ -1168,9 +1201,22 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic data->drawstate.target = renderer->target; if (!data->drawstate.target) { - SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh); + int w, h; + SDL_GL_GetDrawableSize(renderer->window, &w, &h); + if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) { + data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc. + data->drawstate.cliprect_dirty = SDL_TRUE; + data->drawstate.drawablew = w; + data->drawstate.drawableh = h; + } } +#ifdef __MACOSX__ + // On macOS, moving the window seems to invalidate the OpenGL viewport state, + // so don't bother trying to persist it across frames; always reset it. + // Workaround for: https://github.com/libsdl-org/SDL/issues/1504 + data->drawstate.viewport_dirty = SDL_TRUE; +#endif while (cmd) { switch (cmd->command) { @@ -1179,12 +1225,9 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic const Uint8 g = cmd->data.color.g; const Uint8 b = cmd->data.color.b; const Uint8 a = cmd->data.color.a; - const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); + const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b); if (color != data->drawstate.color) { - data->glColor4f((GLfloat) r * inv255f, - (GLfloat) g * inv255f, - (GLfloat) b * inv255f, - (GLfloat) a * inv255f); + data->glColor4ub((GLubyte) r, (GLubyte) g, (GLubyte) b, (GLubyte) a); data->drawstate.color = color; } break; @@ -1205,6 +1248,7 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; data->drawstate.cliprect_enabled_dirty = SDL_TRUE; } + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); data->drawstate.cliprect_dirty = SDL_TRUE; @@ -1217,7 +1261,7 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic const Uint8 g = cmd->data.color.g; const Uint8 b = cmd->data.color.b; const Uint8 a = cmd->data.color.a; - const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); + const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b); if (color != data->drawstate.clear_color) { const GLfloat fr = ((GLfloat) r) * inv255f; const GLfloat fg = ((GLfloat) g) * inv255f; @@ -1233,99 +1277,123 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic } data->glClear(GL_COLOR_BUFFER_BIT); - break; } - case SDL_RENDERCMD_DRAW_POINTS: { - const size_t count = cmd->data.draw.count; - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - SetDrawState(data, cmd, SHADER_SOLID); - data->glBegin(GL_POINTS); - for (i = 0; i < count; i++, verts += 2) { - data->glVertex2f(verts[0], verts[1]); - } - data->glEnd(); + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; + + case SDL_RENDERCMD_COPY: /* unused */ + break; + + case SDL_RENDERCMD_COPY_EX: /* unused */ break; - } case SDL_RENDERCMD_DRAW_LINES: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - const size_t count = cmd->data.draw.count; - SDL_assert(count >= 2); - SetDrawState(data, cmd, SHADER_SOLID); - data->glBegin(GL_LINE_STRIP); - for (i = 0; i < count; ++i, verts += 2) { - data->glVertex2f(verts[0], verts[1]); - } - data->glEnd(); - break; - } + if (SetDrawState(data, cmd, SHADER_SOLID) == 0) { + size_t count = cmd->data.draw.count; + const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - case SDL_RENDERCMD_FILL_RECTS: { - const size_t count = cmd->data.draw.count; - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - SetDrawState(data, cmd, SHADER_SOLID); - for (i = 0; i < count; ++i, verts += 4) { - data->glRectf(verts[0], verts[1], verts[2], verts[3]); + /* SetDrawState handles glEnableClientState. */ + data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, verts); + + if (count > 2) { + /* joined lines cannot be grouped */ + data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)count); + } else { + /* let's group non joined lines */ + SDL_RenderCommand *finalcmd = cmd; + SDL_RenderCommand *nextcmd = cmd->next; + SDL_BlendMode thisblend = cmd->data.draw.blend; + + while (nextcmd != NULL) { + const SDL_RenderCommandType nextcmdtype = nextcmd->command; + if (nextcmdtype != SDL_RENDERCMD_DRAW_LINES) { + break; /* can't go any further on this draw call, different render command up next. */ + } else if (nextcmd->data.draw.count != 2) { + break; /* can't go any further on this draw call, those are joined lines */ + } else if (nextcmd->data.draw.blend != thisblend) { + break; /* can't go any further on this draw call, different blendmode copy up next. */ + } else { + finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */ + count += nextcmd->data.draw.count; + } + nextcmd = nextcmd->next; + } + + data->glDrawArrays(GL_LINES, 0, (GLsizei)count); + cmd = finalcmd; /* skip any copy commands we just combined in here. */ + } } break; } - case SDL_RENDERCMD_COPY: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - const GLfloat minx = verts[0]; - const GLfloat miny = verts[1]; - const GLfloat maxx = verts[2]; - const GLfloat maxy = verts[3]; - const GLfloat minu = verts[4]; - const GLfloat maxu = verts[5]; - const GLfloat minv = verts[6]; - const GLfloat maxv = verts[7]; - SetCopyState(data, cmd); - data->glBegin(GL_TRIANGLE_STRIP); - data->glTexCoord2f(minu, minv); - data->glVertex2f(minx, miny); - data->glTexCoord2f(maxu, minv); - data->glVertex2f(maxx, miny); - data->glTexCoord2f(minu, maxv); - data->glVertex2f(minx, maxy); - data->glTexCoord2f(maxu, maxv); - data->glVertex2f(maxx, maxy); - data->glEnd(); - break; - } + case SDL_RENDERCMD_DRAW_POINTS: + case SDL_RENDERCMD_GEOMETRY: { + /* as long as we have the same copy command in a row, with the + same texture, we can combine them all into a single draw call. */ + SDL_Texture *thistexture = cmd->data.draw.texture; + SDL_BlendMode thisblend = cmd->data.draw.blend; + const SDL_RenderCommandType thiscmdtype = cmd->command; + SDL_RenderCommand *finalcmd = cmd; + SDL_RenderCommand *nextcmd = cmd->next; + size_t count = cmd->data.draw.count; + int ret; + while (nextcmd != NULL) { + const SDL_RenderCommandType nextcmdtype = nextcmd->command; + if (nextcmdtype != thiscmdtype) { + break; /* can't go any further on this draw call, different render command up next. */ + } else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) { + break; /* can't go any further on this draw call, different texture/blendmode copy up next. */ + } else { + finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */ + count += nextcmd->data.draw.count; + } + nextcmd = nextcmd->next; + } - case SDL_RENDERCMD_COPY_EX: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - const GLfloat minx = verts[0]; - const GLfloat miny = verts[1]; - const GLfloat maxx = verts[2]; - const GLfloat maxy = verts[3]; - const GLfloat minu = verts[4]; - const GLfloat maxu = verts[5]; - const GLfloat minv = verts[6]; - const GLfloat maxv = verts[7]; - const GLfloat translatex = verts[8]; - const GLfloat translatey = verts[9]; - const GLdouble angle = verts[10]; - SetCopyState(data, cmd); + if (thistexture) { + ret = SetCopyState(data, cmd); + } else { + ret = SetDrawState(data, cmd, SHADER_SOLID); + } - /* Translate to flip, rotate, translate to position */ - data->glPushMatrix(); - data->glTranslatef(translatex, translatey, 0.0f); - data->glRotated(angle, 0.0, 0.0, 1.0); - data->glBegin(GL_TRIANGLE_STRIP); - data->glTexCoord2f(minu, minv); - data->glVertex2f(minx, miny); - data->glTexCoord2f(maxu, minv); - data->glVertex2f(maxx, miny); - data->glTexCoord2f(minu, maxv); - data->glVertex2f(minx, maxy); - data->glTexCoord2f(maxu, maxv); - data->glVertex2f(maxx, maxy); - data->glEnd(); - data->glPopMatrix(); + if (ret == 0) { + const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); + int op = GL_TRIANGLES; /* SDL_RENDERCMD_GEOMETRY */ + if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) { + op = GL_POINTS; + } + + if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) { + /* SetDrawState handles glEnableClientState. */ + data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, verts); + } else { + /* SetDrawState handles glEnableClientState. */ + if (thistexture) { + data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 0); + data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 5, verts + 2); + data->glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 3); + } else { + data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 3, verts + 0); + data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 3, verts + 2); + } + } + + data->glDrawArrays(op, 0, (GLsizei) count); + + /* Restore previously set color when we're done. */ + if (thiscmdtype != SDL_RENDERCMD_DRAW_POINTS) { + Uint32 color = data->drawstate.color; + GLubyte a = (GLubyte)((color >> 24) & 0xFF); + GLubyte r = (GLubyte)((color >> 16) & 0xFF); + GLubyte g = (GLubyte)((color >> 8) & 0xFF); + GLubyte b = (GLubyte)((color >> 0) & 0xFF); + data->glColor4ub(r, g, b, a); + } + } + + cmd = finalcmd; /* skip any copy commands we just combined in here. */ break; } @@ -1336,6 +1404,21 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic cmd = cmd->next; } + /* Turn off vertex array state when we're done, in case external code + relies on it being off. */ + if (data->drawstate.vertex_array) { + data->glDisableClientState(GL_VERTEX_ARRAY); + data->drawstate.vertex_array = SDL_FALSE; + } + if (data->drawstate.color_array) { + data->glDisableClientState(GL_COLOR_ARRAY); + data->drawstate.color_array = SDL_FALSE; + } + if (data->drawstate.texture_array) { + data->glDisableClientState(GL_TEXTURE_COORD_ARRAY); + data->drawstate.texture_array = SDL_FALSE; + } + return GL_CheckError("", renderer); } @@ -1439,10 +1522,12 @@ GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (data->texture) { renderdata->glDeleteTextures(1, &data->texture); } +#if SDL_HAVE_YUV if (data->yuv) { renderdata->glDeleteTextures(1, &data->utexture); renderdata->glDeleteTextures(1, &data->vtexture); } +#endif SDL_free(data->pixels); SDL_free(data); texture->driverdata = NULL; @@ -1496,23 +1581,44 @@ GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, floa GL_ActivateRenderer(renderer); data->glEnable(textype); +#if SDL_HAVE_YUV if (texturedata->yuv) { - data->glActiveTextureARB(GL_TEXTURE2_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE2_ARB); + } data->glBindTexture(textype, texturedata->vtexture); - data->glActiveTextureARB(GL_TEXTURE1_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } data->glBindTexture(textype, texturedata->utexture); - data->glActiveTextureARB(GL_TEXTURE0_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } } + if (texturedata->nv12) { + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } + data->glBindTexture(textype, texturedata->utexture); + + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } + } +#endif data->glBindTexture(textype, texturedata->texture); data->drawstate.texturing = SDL_TRUE; data->drawstate.texture = texture; - if(texw) *texw = (float)texturedata->texw; - if(texh) *texh = (float)texturedata->texh; - + if (texw) { + *texw = (float)texturedata->texw; + } + if (texh) { + *texh = (float)texturedata->texh; + } return 0; } @@ -1525,16 +1631,37 @@ GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) GL_ActivateRenderer(renderer); +#if SDL_HAVE_YUV if (texturedata->yuv) { - data->glActiveTextureARB(GL_TEXTURE2_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE2_ARB); + } + data->glBindTexture(textype, 0); data->glDisable(textype); - data->glActiveTextureARB(GL_TEXTURE1_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } + data->glBindTexture(textype, 0); data->glDisable(textype); - data->glActiveTextureARB(GL_TEXTURE0_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } } + if (texturedata->nv12) { + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } + data->glBindTexture(textype, 0); + data->glDisable(textype); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } + } +#endif + data->glBindTexture(textype, 0); data->glDisable(textype); data->drawstate.texturing = SDL_FALSE; @@ -1543,6 +1670,52 @@ GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) return 0; } +static int +GL_SetVSync(SDL_Renderer * renderer, const int vsync) +{ + int retval; + if (vsync) { + retval = SDL_GL_SetSwapInterval(1); + } else { + retval = SDL_GL_SetSwapInterval(0); + } + if (retval != 0) { + return retval; + } + if (SDL_GL_GetSwapInterval() > 0) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return retval; +} + +static SDL_bool +GL_IsProbablyAccelerated(const GL_RenderData *data) +{ + /*const char *vendor = (const char *) data->glGetString(GL_VENDOR);*/ + const char *renderer = (const char *) data->glGetString(GL_RENDERER); + +#ifdef __WINDOWS__ + if (SDL_strcmp(renderer, "GDI Generic") == 0) { + return SDL_FALSE; /* Microsoft's fallback software renderer. Fix your system! */ + } +#endif + +#ifdef __APPLE__ + if (SDL_strcmp(renderer, "Apple Software Renderer") == 0) { + return SDL_FALSE; /* (a probably very old) Apple software-based OpenGL. */ + } +#endif + + if (SDL_strcmp(renderer, "Software Rasterizer") == 0) { + return SDL_FALSE; /* (a probably very old) Software Mesa, or some other generic thing. */ + } + + /* !!! FIXME: swrast? llvmpipe? softpipe? */ + + return SDL_TRUE; +} static SDL_Renderer * GL_CreateRenderer(SDL_Window * window, Uint32 flags) @@ -1553,6 +1726,8 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) Uint32 window_flags; int profile_mask = 0, major = 0, minor = 0; SDL_bool changed_window = SDL_FALSE; + const char *hint; + SDL_bool non_power_of_two_supported = SDL_FALSE; SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_mask); SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major); @@ -1589,7 +1764,10 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->SupportsBlendMode = GL_SupportsBlendMode; renderer->CreateTexture = GL_CreateTexture; renderer->UpdateTexture = GL_UpdateTexture; +#if SDL_HAVE_YUV renderer->UpdateTextureYUV = GL_UpdateTextureYUV; + renderer->UpdateTextureNV = GL_UpdateTextureNV; +#endif renderer->LockTexture = GL_LockTexture; renderer->UnlockTexture = GL_UnlockTexture; renderer->SetTextureScaleMode = GL_SetTextureScaleMode; @@ -1598,18 +1776,17 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->QueueSetDrawColor = GL_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = GL_QueueDrawPoints; renderer->QueueDrawLines = GL_QueueDrawLines; - renderer->QueueFillRects = GL_QueueFillRects; - renderer->QueueCopy = GL_QueueCopy; - renderer->QueueCopyEx = GL_QueueCopyEx; + renderer->QueueGeometry = GL_QueueGeometry; renderer->RunCommandQueue = GL_RunCommandQueue; renderer->RenderReadPixels = GL_RenderReadPixels; renderer->RenderPresent = GL_RenderPresent; renderer->DestroyTexture = GL_DestroyTexture; renderer->DestroyRenderer = GL_DestroyRenderer; + renderer->SetVSync = GL_SetVSync; renderer->GL_BindTexture = GL_BindTexture; renderer->GL_UnbindTexture = GL_UnbindTexture; renderer->info = GL_RenderDriver.info; - renderer->info.flags = SDL_RENDERER_ACCELERATED; + renderer->info.flags = 0; /* will set some flags below. */ renderer->driverdata = data; renderer->window = window; @@ -1633,6 +1810,10 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) goto error; } + if (GL_IsProbablyAccelerated(data)) { + renderer->info.flags |= SDL_RENDERER_ACCELERATED; + } + #ifdef __MACOSX__ /* Enable multi-threaded rendering */ /* Disabled until Ryan finishes his VBO/PBO code... @@ -1666,15 +1847,37 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) data->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } + hint = SDL_getenv("GL_ARB_texture_non_power_of_two"); + if (!hint || *hint != '0') { + SDL_bool isGL2 = SDL_FALSE; + const char *verstr = (const char *)data->glGetString(GL_VERSION); + if (verstr) { + char verbuf[16]; + char *ptr; + SDL_strlcpy(verbuf, verstr, sizeof (verbuf)); + ptr = SDL_strchr(verbuf, '.'); + if (ptr) { + *ptr = '\0'; + if (SDL_atoi(verbuf) >= 2) { + isGL2 = SDL_TRUE; + } + } + } + if (isGL2 || SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) { + non_power_of_two_supported = SDL_TRUE; + } + } + data->textype = GL_TEXTURE_2D; - if (SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) { + if (non_power_of_two_supported) { data->GL_ARB_texture_non_power_of_two_supported = SDL_TRUE; + data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); + renderer->info.max_texture_width = value; + renderer->info.max_texture_height = value; } else if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) { data->GL_ARB_texture_rectangle_supported = SDL_TRUE; data->textype = GL_TEXTURE_RECTANGLE_ARB; - } - if (data->GL_ARB_texture_rectangle_supported) { data->glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &value); renderer->info.max_texture_width = value; renderer->info.max_texture_height = value; @@ -1699,7 +1902,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) } SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s", data->shaders ? "ENABLED" : "DISABLED"); - +#if SDL_HAVE_YUV /* We support YV12 textures using 3 textures and a shader */ if (data->shaders && data->num_texture_units >= 3) { renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12; @@ -1707,7 +1910,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12; renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21; } - +#endif #ifdef __MACOSX__ renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_UYVY; #endif @@ -1736,7 +1939,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) data->glDisable(GL_SCISSOR_TEST); data->glDisable(data->textype); data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + data->glColor4ub(255, 255, 255, 255); /* This ended up causing video discrepancies between OpenGL and Direct3D */ /* data->glEnable(GL_LINE_SMOOTH); */ diff --git a/Engine/lib/sdl/src/render/opengl/SDL_shaders_gl.c b/Engine/lib/sdl/src/render/opengl/SDL_shaders_gl.c index db20ea17e..4db083555 100644 --- a/Engine/lib/sdl/src/render/opengl/SDL_shaders_gl.c +++ b/Engine/lib/sdl/src/render/opengl/SDL_shaders_gl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -149,7 +149,7 @@ struct GL_ShaderContext "uniform sampler2D tex1; // U/V \n" \ "\n" \ -#define NV12_SHADER_BODY \ +#define NV12_RA_SHADER_BODY \ "\n" \ "void main()\n" \ "{\n" \ @@ -174,6 +174,31 @@ struct GL_ShaderContext " gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \ "}" \ +#define NV12_RG_SHADER_BODY \ +"\n" \ +"void main()\n" \ +"{\n" \ +" vec2 tcoord;\n" \ +" vec3 yuv, rgb;\n" \ +"\n" \ +" // Get the Y value \n" \ +" tcoord = v_texCoord;\n" \ +" yuv.x = texture2D(tex0, tcoord).r;\n" \ +"\n" \ +" // Get the U and V values \n" \ +" tcoord *= UVCoordScale;\n" \ +" yuv.yz = texture2D(tex1, tcoord).rg;\n" \ +"\n" \ +" // Do the color transform \n" \ +" yuv += offset;\n" \ +" rgb.r = dot(yuv, Rcoeff);\n" \ +" rgb.g = dot(yuv, Gcoeff);\n" \ +" rgb.b = dot(yuv, Bcoeff);\n" \ +"\n" \ +" // That was easy. :) \n" \ +" gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \ +"}" \ + #define NV21_SHADER_PROLOGUE \ "varying vec4 v_color;\n" \ "varying vec2 v_texCoord;\n" \ @@ -259,7 +284,7 @@ static const char *shader_source[NUM_SHADERS][2] = " gl_FragColor = texture2D(tex0, v_texCoord) * v_color;\n" "}" }, - +#if SDL_HAVE_YUV /* SHADER_YUV_JPEG */ { /* vertex shader */ @@ -294,25 +319,43 @@ static const char *shader_source[NUM_SHADERS][2] = /* fragment shader */ NV12_SHADER_PROLOGUE JPEG_SHADER_CONSTANTS - NV12_SHADER_BODY + NV12_RA_SHADER_BODY }, - /* SHADER_NV12_BT601 */ + /* SHADER_NV12_RA_BT601 */ { /* vertex shader */ TEXTURE_VERTEX_SHADER, /* fragment shader */ NV12_SHADER_PROLOGUE BT601_SHADER_CONSTANTS - NV12_SHADER_BODY + NV12_RA_SHADER_BODY }, - /* SHADER_NV12_BT709 */ + /* SHADER_NV12_RG_BT601 */ + { + /* vertex shader */ + TEXTURE_VERTEX_SHADER, + /* fragment shader */ + NV12_SHADER_PROLOGUE + BT601_SHADER_CONSTANTS + NV12_RG_SHADER_BODY + }, + /* SHADER_NV12_RA_BT709 */ { /* vertex shader */ TEXTURE_VERTEX_SHADER, /* fragment shader */ NV12_SHADER_PROLOGUE BT709_SHADER_CONSTANTS - NV12_SHADER_BODY + NV12_RA_SHADER_BODY + }, + /* SHADER_NV12_RG_BT709 */ + { + /* vertex shader */ + TEXTURE_VERTEX_SHADER, + /* fragment shader */ + NV12_SHADER_PROLOGUE + BT709_SHADER_CONSTANTS + NV12_RG_SHADER_BODY }, /* SHADER_NV21_JPEG */ { @@ -341,6 +384,7 @@ static const char *shader_source[NUM_SHADERS][2] = BT709_SHADER_CONSTANTS NV21_SHADER_BODY }, +#endif /* SDL_HAVE_YUV */ }; static SDL_bool diff --git a/Engine/lib/sdl/src/render/opengl/SDL_shaders_gl.h b/Engine/lib/sdl/src/render/opengl/SDL_shaders_gl.h index 71d864c4f..d3e6c398a 100644 --- a/Engine/lib/sdl/src/render/opengl/SDL_shaders_gl.h +++ b/Engine/lib/sdl/src/render/opengl/SDL_shaders_gl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,15 +32,19 @@ typedef enum { SHADER_SOLID, SHADER_RGB, SHADER_RGBA, +#if SDL_HAVE_YUV SHADER_YUV_JPEG, SHADER_YUV_BT601, SHADER_YUV_BT709, SHADER_NV12_JPEG, - SHADER_NV12_BT601, - SHADER_NV12_BT709, + SHADER_NV12_RA_BT601, + SHADER_NV12_RG_BT601, + SHADER_NV12_RA_BT709, + SHADER_NV12_RG_BT709, SHADER_NV21_JPEG, SHADER_NV21_BT601, SHADER_NV21_BT709, +#endif NUM_SHADERS } GL_Shader; diff --git a/Engine/lib/sdl/src/render/opengles/SDL_glesfuncs.h b/Engine/lib/sdl/src/render/opengles/SDL_glesfuncs.h index e1d54bd95..40a656455 100644 --- a/Engine/lib/sdl/src/render/opengles/SDL_glesfuncs.h +++ b/Engine/lib/sdl/src/render/opengles/SDL_glesfuncs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,6 +27,7 @@ SDL_PROC_OES(void, glBlendFuncSeparateOES, (GLenum, GLenum, GLenum, GLenum)) SDL_PROC(void, glClear, (GLbitfield)) SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf)) SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat)) +SDL_PROC(void, glColorPointer, (GLint, GLenum, GLsizei, const GLvoid *)) SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *)) SDL_PROC(void, glDisable, (GLenum)) SDL_PROC(void, glDisableClientState, (GLenum array)) @@ -56,10 +57,6 @@ SDL_PROC(void, glViewport, (GLint, GLint, GLsizei, GLsizei)) SDL_PROC_OES(void, glBindFramebufferOES, (GLenum, GLuint)) SDL_PROC_OES(void, glFramebufferTexture2DOES, (GLenum, GLenum, GLenum, GLuint, GLint)) SDL_PROC_OES(GLenum, glCheckFramebufferStatusOES, (GLenum)) -SDL_PROC(void, glPushMatrix, (void)) -SDL_PROC(void, glTranslatef, (GLfloat, GLfloat, GLfloat)) -SDL_PROC(void, glRotatef, (GLfloat, GLfloat, GLfloat, GLfloat)) -SDL_PROC(void, glPopMatrix, (void)) SDL_PROC_OES(void, glDeleteFramebuffersOES, (GLsizei, const GLuint*)) /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/opengles/SDL_render_gles.c b/Engine/lib/sdl/src/render/opengles/SDL_render_gles.c index 6bb3031e9..a6b58f2d7 100644 --- a/Engine/lib/sdl/src/render/opengles/SDL_render_gles.c +++ b/Engine/lib/sdl/src/render/opengles/SDL_render_gles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -564,194 +564,98 @@ static int GLES_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) { int i; + GLfloat prevx, prevy; const size_t vertlen = (sizeof (GLfloat) * 2) * count; GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first); + if (!verts) { return -1; } cmd->data.draw.count = count; - /* Offset to hit the center of the pixel. */ - for (i = 0; i < count; i++) { - *(verts++) = 0.5f + points[i].x; - *(verts++) = 0.5f + points[i].y; + /* 0.5f offset to hit the center of the pixel. */ + prevx = 0.5f + points->x; + prevy = 0.5f + points->y; + *(verts++) = prevx; + *(verts++) = prevy; + + /* bump the end of each line segment out a quarter of a pixel, to provoke + the diamond-exit rule. Without this, you won't just drop the last + pixel of the last line segment, but you might also drop pixels at the + edge of any given line segment along the way too. */ + for (i = 1; i < count; i++) { + const GLfloat xstart = prevx; + const GLfloat ystart = prevy; + const GLfloat xend = points[i].x + 0.5f; /* 0.5f to hit pixel center. */ + const GLfloat yend = points[i].y + 0.5f; + /* bump a little in the direction we are moving in. */ + const GLfloat deltax = xend - xstart; + const GLfloat deltay = yend - ystart; + const GLfloat angle = SDL_atan2f(deltay, deltax); + prevx = xend + (SDL_cosf(angle) * 0.25f); + prevy = yend + (SDL_sinf(angle) * 0.25f); + *(verts++) = prevx; + *(verts++) = prevy; } - /* Make the last line segment one pixel longer, to satisfy the - diamond-exit rule. */ - verts -= 4; - { - const GLfloat xstart = verts[0]; - const GLfloat ystart = verts[1]; - const GLfloat xend = verts[2]; - const GLfloat yend = verts[3]; + return 0; +} - if (ystart == yend) { /* horizontal line */ - verts[2] += (xend > xstart) ? 1.0f : -1.0f; - } else if (xstart == xend) { /* vertical line */ - verts[3] += (yend > ystart) ? 1.0f : -1.0f; - } else { /* bump a pixel in the direction we are moving in. */ - const GLfloat deltax = xend - xstart; - const GLfloat deltay = yend - ystart; - const GLfloat angle = SDL_atan2f(deltay, deltax); - verts[2] += SDL_cosf(angle); - verts[3] += SDL_sinf(angle); +static int +GLES_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + GLES_TextureData *texturedata = NULL; + int i; + int count = indices ? num_indices : num_vertices; + GLfloat *verts; + int sz = 2 + 4 + (texture ? 2 : 0); + + verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * sz * sizeof (GLfloat), 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + if (texture) { + texturedata = (GLES_TextureData *) texture->driverdata; + } + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); + + *(verts++) = xy_[0] * scale_x; + *(verts++) = xy_[1] * scale_y; + + *(verts++) = col_.r * inv255f; + *(verts++) = col_.g * inv255f; + *(verts++) = col_.b * inv255f; + *(verts++) = col_.a * inv255f; + + if (texture) { + float *uv_ = (float *)((char*)uv + j * uv_stride); + *(verts++) = uv_[0] * texturedata->texw; + *(verts++) = uv_[1] * texturedata->texh; } } - - return 0; -} - -static int -GLES_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) -{ - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 8 * sizeof (GLfloat), 0, &cmd->data.draw.first); - int i; - - if (!verts) { - return -1; - } - - cmd->data.draw.count = count; - - for (i = 0; i < count; i++) { - const SDL_FRect *rect = &rects[i]; - const GLfloat minx = rect->x; - const GLfloat maxx = rect->x + rect->w; - const GLfloat miny = rect->y; - const GLfloat maxy = rect->y + rect->h; - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; - } - - return 0; -} - -static int -GLES_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) -{ - GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; - GLfloat minx, miny, maxx, maxy; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 16 * sizeof (GLfloat), 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - minx = dstrect->x; - miny = dstrect->y; - maxx = dstrect->x + dstrect->w; - maxy = dstrect->y + dstrect->h; - - minu = (GLfloat) srcrect->x / texture->w; - minu *= texturedata->texw; - maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; - maxu *= texturedata->texw; - minv = (GLfloat) srcrect->y / texture->h; - minv *= texturedata->texh; - maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; - maxv *= texturedata->texh; - - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; - - *(verts++) = minu; - *(verts++) = minv; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = minu; - *(verts++) = maxv; - *(verts++) = maxu; - *(verts++) = maxv; - - return 0; -} - -static int -GLES_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; - GLfloat minx, miny, maxx, maxy; - GLfloat centerx, centery; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 19 * sizeof (GLfloat), 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - centerx = center->x; - centery = center->y; - - if (flip & SDL_FLIP_HORIZONTAL) { - minx = dstrect->w - centerx; - maxx = -centerx; - } - else { - minx = -centerx; - maxx = dstrect->w - centerx; - } - - if (flip & SDL_FLIP_VERTICAL) { - miny = dstrect->h - centery; - maxy = -centery; - } - else { - miny = -centery; - maxy = dstrect->h - centery; - } - - minu = (GLfloat) srcquad->x / texture->w; - minu *= texturedata->texw; - maxu = (GLfloat) (srcquad->x + srcquad->w) / texture->w; - maxu *= texturedata->texw; - minv = (GLfloat) srcquad->y / texture->h; - minv *= texturedata->texh; - maxv = (GLfloat) (srcquad->y + srcquad->h) / texture->h; - maxv *= texturedata->texh; - - cmd->data.draw.count = 1; - - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; - - *(verts++) = minu; - *(verts++) = minv; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = minu; - *(verts++) = maxv; - *(verts++) = maxu; - *(verts++) = maxv; - - *(verts++) = (GLfloat) dstrect->x + centerx; - *(verts++) = (GLfloat) dstrect->y + centery; - *(verts++) = (GLfloat) angle; - return 0; } @@ -763,7 +667,7 @@ SetDrawState(GLES_RenderData *data, const SDL_RenderCommand *cmd) const Uint8 g = cmd->data.draw.g; const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; - const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); + const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b); if (color != data->drawstate.color) { const GLfloat fr = ((GLfloat) r) * inv255f; @@ -865,7 +769,6 @@ static int GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - size_t i; if (GLES_ActivateRenderer(renderer) < 0) { return -1; @@ -874,7 +777,15 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert data->drawstate.target = renderer->target; if (!renderer->target) { - SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh); + int w, h; + SDL_GL_GetDrawableSize(renderer->window, &w, &h); + if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) { + data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc. + data->drawstate.cliprect_dirty = SDL_TRUE; + data->drawstate.drawablew = w; + data->drawstate.drawableh = h; + } + } while (cmd) { @@ -910,7 +821,7 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert const Uint8 g = cmd->data.color.g; const Uint8 b = cmd->data.color.b; const Uint8 a = cmd->data.color.a; - const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); + const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b); if (color != data->drawstate.clear_color) { const GLfloat fr = ((GLfloat) r) * inv255f; const GLfloat fg = ((GLfloat) g) * inv255f; @@ -949,42 +860,38 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert break; } - case SDL_RENDERCMD_FILL_RECTS: { + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; + + case SDL_RENDERCMD_COPY: /* unused */ + break; + + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; + + case SDL_RENDERCMD_GEOMETRY: { + const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); + SDL_Texture *texture = cmd->data.draw.texture; const size_t count = cmd->data.draw.count; - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - GLsizei offset = 0; - SetDrawState(data, cmd); - data->glVertexPointer(2, GL_FLOAT, 0, verts); - for (i = 0; i < count; ++i, offset += 4) { - data->glDrawArrays(GL_TRIANGLE_STRIP, offset, 4); + int stride = (2 + 4 + (texture ? 2 : 0)) * sizeof (float); + + if (texture) { + SetCopyState(data, cmd); + } else { + SetDrawState(data, cmd); } - break; - } - case SDL_RENDERCMD_COPY: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - SetCopyState(data, cmd); - data->glVertexPointer(2, GL_FLOAT, 0, verts); - data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8); - data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - break; - } + data->glEnableClientState(GL_COLOR_ARRAY); - case SDL_RENDERCMD_COPY_EX: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - const GLfloat translatex = verts[16]; - const GLfloat translatey = verts[17]; - const GLfloat angle = verts[18]; - SetCopyState(data, cmd); - data->glVertexPointer(2, GL_FLOAT, 0, verts); - data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8); + data->glVertexPointer(2, GL_FLOAT, stride, verts); + data->glColorPointer(4, GL_FLOAT, stride, verts + 2); + if (texture) { + data->glTexCoordPointer(2, GL_FLOAT, stride, verts + 2 + 4); + } - /* Translate to flip, rotate, translate to position */ - data->glPushMatrix(); - data->glTranslatef(translatex, translatey, 0.0f); - data->glRotatef(angle, 0.0, 0.0, 1.0); - data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - data->glPopMatrix(); + data->glDrawArrays(GL_TRIANGLES, 0, (GLsizei) count); + + data->glDisableClientState(GL_COLOR_ARRAY); break; } @@ -1141,6 +1048,27 @@ static int GLES_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) return 0; } +static int +GLES_SetVSync(SDL_Renderer * renderer, const int vsync) +{ + int retval; + if (vsync) { + retval = SDL_GL_SetSwapInterval(1); + } else { + retval = SDL_GL_SetSwapInterval(0); + } + if (retval != 0) { + return retval; + } + if (SDL_GL_GetSwapInterval() > 0) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return retval; +} + + static SDL_Renderer * GLES_CreateRenderer(SDL_Window * window, Uint32 flags) { @@ -1195,14 +1123,13 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->QueueSetDrawColor = GLES_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = GLES_QueueDrawPoints; renderer->QueueDrawLines = GLES_QueueDrawLines; - renderer->QueueFillRects = GLES_QueueFillRects; - renderer->QueueCopy = GLES_QueueCopy; - renderer->QueueCopyEx = GLES_QueueCopyEx; + renderer->QueueGeometry = GLES_QueueGeometry; renderer->RunCommandQueue = GLES_RunCommandQueue; renderer->RenderReadPixels = GLES_RenderReadPixels; renderer->RenderPresent = GLES_RenderPresent; renderer->DestroyTexture = GLES_DestroyTexture; renderer->DestroyRenderer = GLES_DestroyRenderer; + renderer->SetVSync = GLES_SetVSync; renderer->GL_BindTexture = GLES_BindTexture; renderer->GL_UnbindTexture = GLES_UnbindTexture; renderer->info = GLES_RenderDriver.info; diff --git a/Engine/lib/sdl/src/render/opengles2/SDL_gles2funcs.h b/Engine/lib/sdl/src/render/opengles2/SDL_gles2funcs.h index 2a914ae99..ab8bf85bb 100644 --- a/Engine/lib/sdl/src/render/opengles2/SDL_gles2funcs.h +++ b/Engine/lib/sdl/src/render/opengles2/SDL_gles2funcs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -41,7 +41,6 @@ SDL_PROC(void, glEnableVertexAttribArray, (GLuint)) SDL_PROC(void, glFinish, (void)) SDL_PROC(void, glGenFramebuffers, (GLsizei, GLuint *)) SDL_PROC(void, glGenTextures, (GLsizei, GLuint *)) -SDL_PROC(void, glGetBooleanv, (GLenum, GLboolean *)) SDL_PROC(const GLubyte *, glGetString, (GLenum)) SDL_PROC(GLenum, glGetError, (void)) SDL_PROC(void, glGetIntegerv, (GLenum, GLint *)) diff --git a/Engine/lib/sdl/src/render/opengles2/SDL_render_gles2.c b/Engine/lib/sdl/src/render/opengles2/SDL_render_gles2.c index 38d1e4a44..c2f5d640f 100644 --- a/Engine/lib/sdl/src/render/opengles2/SDL_render_gles2.c +++ b/Engine/lib/sdl/src/render/opengles2/SDL_render_gles2.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,6 +28,17 @@ #include "../../video/SDL_blit.h" #include "SDL_shaders_gles2.h" +/* WebGL doesn't offer client-side arrays, so use Vertex Buffer Objects + on Emscripten, which converts GLES2 into WebGL calls. + In all other cases, attempt to use client-side arrays, as they tend to + be dramatically faster when not batching, and about the same when + we are. */ +#if defined(__EMSCRIPTEN__) +#define USE_VERTEX_BUFFER_OBJECTS 1 +#else +#define USE_VERTEX_BUFFER_OBJECTS 0 +#endif + /* To prevent unnecessary window recreation, * these should match the defaults selected in SDL_GL_ResetAttributes */ @@ -58,37 +69,22 @@ typedef struct GLES2_TextureData GLenum pixel_type; void *pixel_data; int pitch; +#if SDL_HAVE_YUV /* YUV texture support */ SDL_bool yuv; SDL_bool nv12; GLenum texture_v; GLenum texture_u; +#endif GLES2_FBOList *fbo; } GLES2_TextureData; -typedef struct GLES2_ShaderCacheEntry -{ - GLuint id; - GLES2_ShaderType type; - const GLES2_ShaderInstance *instance; - int references; - struct GLES2_ShaderCacheEntry *prev; - struct GLES2_ShaderCacheEntry *next; -} GLES2_ShaderCacheEntry; - -typedef struct GLES2_ShaderCache -{ - int count; - GLES2_ShaderCacheEntry *head; -} GLES2_ShaderCache; - typedef struct GLES2_ProgramCacheEntry { GLuint id; - GLES2_ShaderCacheEntry *vertex_shader; - GLES2_ShaderCacheEntry *fragment_shader; + GLuint vertex_shader; + GLuint fragment_shader; GLuint uniform_locations[16]; - Uint32 color; GLfloat projection[4][4]; struct GLES2_ProgramCacheEntry *prev; struct GLES2_ProgramCacheEntry *next; @@ -104,16 +100,14 @@ typedef struct GLES2_ProgramCache typedef enum { GLES2_ATTRIBUTE_POSITION = 0, - GLES2_ATTRIBUTE_TEXCOORD = 1, - GLES2_ATTRIBUTE_ANGLE = 2, - GLES2_ATTRIBUTE_CENTER = 3, + GLES2_ATTRIBUTE_COLOR = 1, + GLES2_ATTRIBUTE_TEXCOORD = 2, } GLES2_Attribute; typedef enum { GLES2_UNIFORM_PROJECTION, GLES2_UNIFORM_TEXTURE, - GLES2_UNIFORM_COLOR, GLES2_UNIFORM_TEXTURE_U, GLES2_UNIFORM_TEXTURE_V } GLES2_Uniform; @@ -144,8 +138,6 @@ typedef struct SDL_bool cliprect_dirty; SDL_Rect cliprect; SDL_bool texturing; - SDL_bool is_copy_ex; - Uint32 color; Uint32 clear_color; int drawablew; int drawableh; @@ -165,15 +157,17 @@ typedef struct GLES2_RenderData GLES2_FBOList *framebuffers; GLuint window_framebuffer; - int shader_format_count; - GLenum *shader_formats; - GLES2_ShaderCache shader_cache; + GLuint shader_id_cache[GLES2_SHADER_COUNT]; + GLES2_ProgramCache program_cache; Uint8 clear_r, clear_g, clear_b, clear_a; +#if USE_VERTEX_BUFFER_OBJECTS GLuint vertex_buffers[8]; size_t vertex_buffer_size[8]; int current_vertex_buffer; +#endif + GLES2_DrawStateCache drawstate; } GLES2_RenderData; @@ -393,32 +387,10 @@ GLES2_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) } -static void -GLES2_EvictShader(GLES2_RenderData *data, GLES2_ShaderCacheEntry *entry) -{ - /* Unlink the shader from the cache */ - if (entry->next) { - entry->next->prev = entry->prev; - } - if (entry->prev) { - entry->prev->next = entry->next; - } - if (data->shader_cache.head == entry) { - data->shader_cache.head = entry->next; - } - --data->shader_cache.count; - - /* Deallocate the shader */ - data->glDeleteShader(entry->id); - SDL_free(entry); -} - static GLES2_ProgramCacheEntry * -GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, - GLES2_ShaderCacheEntry *fragment) +GLES2_CacheProgram(GLES2_RenderData *data, GLuint vertex, GLuint fragment) { GLES2_ProgramCacheEntry *entry; - GLES2_ShaderCacheEntry *shaderEntry; GLint linkSuccessful; /* Check if we've already cached this program */ @@ -456,12 +428,11 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, /* Create the program and link it */ entry->id = data->glCreateProgram(); - data->glAttachShader(entry->id, vertex->id); - data->glAttachShader(entry->id, fragment->id); + data->glAttachShader(entry->id, vertex); + data->glAttachShader(entry->id, fragment); data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position"); + data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_COLOR, "a_color"); data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord"); - data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE, "a_angle"); - data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER, "a_center"); data->glLinkProgram(entry->id); data->glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful); if (!linkSuccessful) { @@ -480,10 +451,6 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, data->glGetUniformLocation(entry->id, "u_texture_u"); entry->uniform_locations[GLES2_UNIFORM_TEXTURE] = data->glGetUniformLocation(entry->id, "u_texture"); - entry->uniform_locations[GLES2_UNIFORM_COLOR] = - data->glGetUniformLocation(entry->id, "u_color"); - - entry->color = 0; data->glUseProgram(entry->id); if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] != -1) { @@ -498,9 +465,6 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, if (entry->uniform_locations[GLES2_UNIFORM_PROJECTION] != -1) { data->glUniformMatrix4fv(entry->uniform_locations[GLES2_UNIFORM_PROJECTION], 1, GL_FALSE, (GLfloat *)entry->projection); } - if (entry->uniform_locations[GLES2_UNIFORM_COLOR] != -1) { - data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_COLOR], 0.0f, 0.0f, 0.0f, 0.0f); - } /* Cache the linked program */ if (data->program_cache.head) { @@ -512,20 +476,8 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, data->program_cache.head = entry; ++data->program_cache.count; - /* Increment the refcount of the shaders we're using */ - ++vertex->references; - ++fragment->references; - /* Evict the last entry from the cache if we exceed the limit */ if (data->program_cache.count > GLES2_MAX_CACHED_PROGRAMS) { - shaderEntry = data->program_cache.tail->vertex_shader; - if (--shaderEntry->references <= 0) { - GLES2_EvictShader(data, shaderEntry); - } - shaderEntry = data->program_cache.tail->fragment_shader; - if (--shaderEntry->references <= 0) { - GLES2_EvictShader(data, shaderEntry); - } data->glDeleteProgram(data->program_cache.tail->id); data->program_cache.tail = data->program_cache.tail->prev; if (data->program_cache.tail != NULL) { @@ -537,80 +489,34 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, return entry; } -static GLES2_ShaderCacheEntry * -GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type) +static GLuint +GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type, GLenum shader_type) { - const GLES2_Shader *shader; - const GLES2_ShaderInstance *instance = NULL; - GLES2_ShaderCacheEntry *entry = NULL; + GLuint id; GLint compileSuccessful = GL_FALSE; - int i, j; + const char *shader_src = (char *)GLES2_GetShader(type); - /* Find the corresponding shader */ - shader = GLES2_GetShader(type); - if (!shader) { - SDL_SetError("No shader matching the requested characteristics was found"); - return NULL; + if (!shader_src) { + SDL_SetError("No shader src"); + return 0; } - /* Find a matching shader instance that's supported on this hardware */ - for (i = 0; i < shader->instance_count && !instance; ++i) { - for (j = 0; j < data->shader_format_count && !instance; ++j) { - if (!shader->instances[i]) { - continue; - } - if (shader->instances[i]->format != data->shader_formats[j]) { - continue; - } - instance = shader->instances[i]; - } - } - if (!instance) { - SDL_SetError("The specified shader cannot be loaded on the current platform"); - return NULL; - } + /* Compile */ + id = data->glCreateShader(shader_type); + data->glShaderSource(id, 1, &shader_src, NULL); + data->glCompileShader(id); + data->glGetShaderiv(id, GL_COMPILE_STATUS, &compileSuccessful); - /* Check if we've already cached this shader */ - entry = data->shader_cache.head; - while (entry) { - if (entry->instance == instance) { - break; - } - entry = entry->next; - } - if (entry) { - return entry; - } - - /* Create a shader cache entry */ - entry = (GLES2_ShaderCacheEntry *)SDL_calloc(1, sizeof(GLES2_ShaderCacheEntry)); - if (!entry) { - SDL_OutOfMemory(); - return NULL; - } - entry->type = type; - entry->instance = instance; - - /* Compile or load the selected shader instance */ - entry->id = data->glCreateShader(instance->type); - if (instance->format == (GLenum)-1) { - data->glShaderSource(entry->id, 1, (const char **)(char *)&instance->data, NULL); - data->glCompileShader(entry->id); - data->glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful); - } else { - data->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length); - compileSuccessful = GL_TRUE; - } if (!compileSuccessful) { SDL_bool isstack = SDL_FALSE; char *info = NULL; int length = 0; - data->glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length); + data->glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); if (length > 0) { info = SDL_small_alloc(char, length, &isstack); if (info) { - data->glGetShaderInfoLog(entry->id, length, &length, info); + data->glGetShaderInfoLog(id, length, &length, info); } } if (info) { @@ -619,26 +525,21 @@ GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type) } else { SDL_SetError("Failed to load the shader"); } - data->glDeleteShader(entry->id); - SDL_free(entry); - return NULL; + data->glDeleteShader(id); + return 0; } - /* Link the shader entry in at the front of the cache */ - if (data->shader_cache.head) { - entry->next = data->shader_cache.head; - data->shader_cache.head->prev = entry; - } - data->shader_cache.head = entry; - ++data->shader_cache.count; - return entry; + /* Cache */ + data->shader_id_cache[(Uint32)type] = id; + + return id; } static int GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int h) { - GLES2_ShaderCacheEntry *vertex = NULL; - GLES2_ShaderCacheEntry *fragment = NULL; + GLuint vertex; + GLuint fragment; GLES2_ShaderType vtype, ftype; GLES2_ProgramCacheEntry *program; @@ -646,30 +547,31 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int vtype = GLES2_SHADER_VERTEX_DEFAULT; switch (source) { case GLES2_IMAGESOURCE_SOLID: - ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC; + ftype = GLES2_SHADER_FRAGMENT_SOLID; break; case GLES2_IMAGESOURCE_TEXTURE_ABGR: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR; break; case GLES2_IMAGESOURCE_TEXTURE_ARGB: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB; break; case GLES2_IMAGESOURCE_TEXTURE_RGB: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB; break; case GLES2_IMAGESOURCE_TEXTURE_BGR: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR; break; +#if SDL_HAVE_YUV case GLES2_IMAGESOURCE_TEXTURE_YUV: switch (SDL_GetYUVConversionModeForResolution(w, h)) { case SDL_YUV_CONVERSION_JPEG: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG; break; case SDL_YUV_CONVERSION_BT601: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601; break; case SDL_YUV_CONVERSION_BT709: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709; break; default: SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h)); @@ -679,13 +581,21 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int case GLES2_IMAGESOURCE_TEXTURE_NV12: switch (SDL_GetYUVConversionModeForResolution(w, h)) { case SDL_YUV_CONVERSION_JPEG: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG; break; case SDL_YUV_CONVERSION_BT601: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601_SRC; + if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) { + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601; + } else { + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601; + } break; case SDL_YUV_CONVERSION_BT709: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709_SRC; + if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) { + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709; + } else { + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709; + } break; default: SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h)); @@ -695,34 +605,42 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int case GLES2_IMAGESOURCE_TEXTURE_NV21: switch (SDL_GetYUVConversionModeForResolution(w, h)) { case SDL_YUV_CONVERSION_JPEG: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG; break; case SDL_YUV_CONVERSION_BT601: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601; break; case SDL_YUV_CONVERSION_BT709: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709; break; default: SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h)); goto fault; } break; +#endif /* SDL_HAVE_YUV */ case GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES; break; default: goto fault; } /* Load the requested shaders */ - vertex = GLES2_CacheShader(data, vtype); + vertex = data->shader_id_cache[(Uint32)vtype]; if (!vertex) { - goto fault; + vertex = GLES2_CacheShader(data, vtype, GL_VERTEX_SHADER); + if (!vertex) { + goto fault; + } } - fragment = GLES2_CacheShader(data, ftype); + + fragment = data->shader_id_cache[(Uint32)ftype]; if (!fragment) { - goto fault; + fragment = GLES2_CacheShader(data, ftype, GL_FRAGMENT_SHADER); + if (!fragment) { + goto fault; + } } /* Check if we need to change programs at all */ @@ -747,12 +665,6 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int /* Clean up and return */ return 0; fault: - if (vertex && vertex->references <= 0) { - GLES2_EvictShader(data, vertex); - } - if (fragment && fragment->references <= 0) { - GLES2_EvictShader(data, fragment); - } data->drawstate.program = NULL; return -1; } @@ -766,17 +678,31 @@ GLES2_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) static int GLES2_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) { - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (GLfloat), 0, &cmd->data.draw.first); + const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888)); + SDL_VertexSolid *verts = (SDL_VertexSolid *) SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first); int i; + SDL_Color color; + color.r = cmd->data.draw.r; + color.g = cmd->data.draw.g; + color.b = cmd->data.draw.b; + color.a = cmd->data.draw.a; if (!verts) { return -1; } + if (colorswap) { + Uint8 r = color.r; + color.r = color.b; + color.b = r; + } + cmd->data.draw.count = count; for (i = 0; i < count; i++) { - *(verts++) = 0.5f + points[i].x; - *(verts++) = 0.5f + points[i].y; + verts->position.x = 0.5f + points[i].x; + verts->position.y = 0.5f + points[i].y; + verts->color = color; + verts++; } return 0; @@ -785,39 +711,148 @@ GLES2_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL static int GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) { + const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888)); int i; - const size_t vertlen = (sizeof (GLfloat) * 2) * count; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first); + GLfloat prevx, prevy; + SDL_VertexSolid *verts = (SDL_VertexSolid *) SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first); + SDL_Color color; + color.r = cmd->data.draw.r; + color.g = cmd->data.draw.g; + color.b = cmd->data.draw.b; + color.a = cmd->data.draw.a; + if (!verts) { return -1; } - cmd->data.draw.count = count; - /* Offset to hit the center of the pixel. */ - for (i = 0; i < count; i++) { - *(verts++) = 0.5f + points[i].x; - *(verts++) = 0.5f + points[i].y; + if (colorswap) { + Uint8 r = color.r; + color.r = color.b; + color.b = r; } - /* Make the last line segment one pixel longer, to satisfy the - diamond-exit rule. */ - verts -= 4; - { - const GLfloat xstart = verts[0]; - const GLfloat ystart = verts[1]; - const GLfloat xend = verts[2]; - const GLfloat yend = verts[3]; + cmd->data.draw.count = count; - if (ystart == yend) { /* horizontal line */ - verts[2] += (xend > xstart) ? 1.0f : -1.0f; - } else if (xstart == xend) { /* vertical line */ - verts[3] += (yend > ystart) ? 1.0f : -1.0f; - } else { /* bump a pixel in the direction we are moving in. */ - const GLfloat deltax = xend - xstart; - const GLfloat deltay = yend - ystart; - const GLfloat angle = SDL_atan2f(deltay, deltax); - verts[2] += SDL_cosf(angle); - verts[3] += SDL_sinf(angle); + /* 0.5f offset to hit the center of the pixel. */ + prevx = 0.5f + points->x; + prevy = 0.5f + points->y; + verts->position.x = prevx; + verts->position.y = prevy; + verts->color = color; + verts++; + + /* bump the end of each line segment out a quarter of a pixel, to provoke + the diamond-exit rule. Without this, you won't just drop the last + pixel of the last line segment, but you might also drop pixels at the + edge of any given line segment along the way too. */ + for (i = 1; i < count; i++) { + const GLfloat xstart = prevx; + const GLfloat ystart = prevy; + const GLfloat xend = points[i].x + 0.5f; /* 0.5f to hit pixel center. */ + const GLfloat yend = points[i].y + 0.5f; + /* bump a little in the direction we are moving in. */ + const GLfloat deltax = xend - xstart; + const GLfloat deltay = yend - ystart; + const GLfloat angle = SDL_atan2f(deltay, deltax); + prevx = xend + (SDL_cosf(angle) * 0.25f); + prevy = yend + (SDL_sinf(angle) * 0.25f); + verts->position.x = prevx; + verts->position.y = prevy; + verts->color = color; + verts++; + } + + return 0; +} + +static int +GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + int i; + const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888)); + int count = indices ? num_indices : num_vertices; + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + if (texture) { + SDL_Vertex *verts = (SDL_Vertex *) SDL_AllocateRenderVertices(renderer, count * sizeof (*verts), 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + float *uv_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); + uv_ = (float *)((char*)uv + j * uv_stride); + + verts->position.x = xy_[0] * scale_x; + verts->position.y = xy_[1] * scale_y; + + if (colorswap) { + Uint8 r = col_.r; + col_.r = col_.b; + col_.b = r; + } + + verts->color = col_; + verts->tex_coord.x = uv_[0]; + verts->tex_coord.y = uv_[1]; + verts++; + } + + } else { + SDL_VertexSolid *verts = (SDL_VertexSolid *) SDL_AllocateRenderVertices(renderer, count * sizeof (*verts), 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); + + verts->position.x = xy_[0] * scale_x; + verts->position.y = xy_[1] * scale_y; + + if (colorswap) { + Uint8 r = col_.r; + col_.r = col_.b; + col_.b = r; + } + + verts->color = col_; + verts++; } } @@ -825,171 +860,12 @@ GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_ } static int -GLES2_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_ImageSource imgsrc, void *vertices) { - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 8 * sizeof (GLfloat), 0, &cmd->data.draw.first); - int i; - - if (!verts) { - return -1; - } - - cmd->data.draw.count = count; - - for (i = 0; i < count; i++) { - const SDL_FRect *rect = &rects[i]; - const GLfloat minx = rect->x; - const GLfloat maxx = rect->x + rect->w; - const GLfloat miny = rect->y; - const GLfloat maxy = rect->y + rect->h; - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; - } - - return 0; -} - -static int -GLES2_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) -{ - GLfloat minx, miny, maxx, maxy; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 16 * sizeof (GLfloat), 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - minx = dstrect->x; - miny = dstrect->y; - maxx = dstrect->x + dstrect->w; - maxy = dstrect->y + dstrect->h; - - minu = (GLfloat) srcrect->x / texture->w; - maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; - minv = (GLfloat) srcrect->y / texture->h; - maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; - - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; - - *(verts++) = minu; - *(verts++) = minv; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = minu; - *(verts++) = maxv; - *(verts++) = maxu; - *(verts++) = maxv; - - return 0; -} - -static int -GLES2_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - /* render expects cos value - 1 (see GLES2_VertexSrc_Default_) */ - const float radian_angle = (float)(M_PI * (360.0 - angle) / 180.0); - const GLfloat s = (GLfloat) SDL_sin(radian_angle); - const GLfloat c = (GLfloat) SDL_cos(radian_angle) - 1.0f; - const GLfloat centerx = center->x + dstrect->x; - const GLfloat centery = center->y + dstrect->y; - GLfloat minx, miny, maxx, maxy; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 32 * sizeof (GLfloat), 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - if (flip & SDL_FLIP_HORIZONTAL) { - minx = dstrect->x + dstrect->w; - maxx = dstrect->x; - } else { - minx = dstrect->x; - maxx = dstrect->x + dstrect->w; - } - - if (flip & SDL_FLIP_VERTICAL) { - miny = dstrect->y + dstrect->h; - maxy = dstrect->y; - } else { - miny = dstrect->y; - maxy = dstrect->y + dstrect->h; - } - - minu = ((GLfloat) srcquad->x) / ((GLfloat) texture->w); - maxu = ((GLfloat) (srcquad->x + srcquad->w)) / ((GLfloat) texture->w); - minv = ((GLfloat) srcquad->y) / ((GLfloat) texture->h); - maxv = ((GLfloat) (srcquad->y + srcquad->h)) / ((GLfloat) texture->h); - - - cmd->data.draw.count = 1; - - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; - - *(verts++) = minu; - *(verts++) = minv; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = minu; - *(verts++) = maxv; - *(verts++) = maxu; - *(verts++) = maxv; - - *(verts++) = s; - *(verts++) = c; - *(verts++) = s; - *(verts++) = c; - *(verts++) = s; - *(verts++) = c; - *(verts++) = s; - *(verts++) = c; - - *(verts++) = centerx; - *(verts++) = centery; - *(verts++) = centerx; - *(verts++) = centery; - *(verts++) = centerx; - *(verts++) = centery; - *(verts++) = centerx; - *(verts++) = centery; - - return 0; -} - -static int -SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_ImageSource imgsrc) -{ - const SDL_bool was_copy_ex = data->drawstate.is_copy_ex; - const SDL_bool is_copy_ex = (cmd->command == SDL_RENDERCMD_COPY_EX); SDL_Texture *texture = cmd->data.draw.texture; const SDL_BlendMode blend = cmd->data.draw.blend; GLES2_ProgramCacheEntry *program; + int stride; SDL_assert((texture != NULL) == (imgsrc != GLES2_IMAGESOURCE_SOLID)); @@ -1024,41 +900,25 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I data->drawstate.cliprect_dirty = SDL_FALSE; } - if (texture != data->drawstate.texture) { - if ((texture != NULL) != data->drawstate.texturing) { - if (texture == NULL) { - data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD); - data->drawstate.texturing = SDL_FALSE; - } else { - data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD); - data->drawstate.texturing = SDL_TRUE; - } + if ((texture != NULL) != data->drawstate.texturing) { + if (texture == NULL) { + data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD); + data->drawstate.texturing = SDL_FALSE; + } else { + data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD); + data->drawstate.texturing = SDL_TRUE; } - - if (texture) { - GLES2_TextureData *tdata = (GLES2_TextureData *) texture->driverdata; - if (tdata->yuv) { - data->glActiveTexture(GL_TEXTURE2); - data->glBindTexture(tdata->texture_type, tdata->texture_v); - - data->glActiveTexture(GL_TEXTURE1); - data->glBindTexture(tdata->texture_type, tdata->texture_u); - - data->glActiveTexture(GL_TEXTURE0); - } else if (tdata->nv12) { - data->glActiveTexture(GL_TEXTURE1); - data->glBindTexture(tdata->texture_type, tdata->texture_u); - - data->glActiveTexture(GL_TEXTURE0); - } - data->glBindTexture(tdata->texture_type, tdata->texture); - } - - data->drawstate.texture = texture; } if (texture) { - data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 8))); + stride = sizeof(SDL_Vertex); + } else { + stride = sizeof(SDL_VertexSolid); + } + + if (texture) { + SDL_Vertex *verts = (SDL_Vertex *) (((Uint8 *) vertices) + cmd->data.draw.first); + data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *)&verts->tex_coord); } if (GLES2_SelectProgram(data, imgsrc, texture ? texture->w : 0, texture ? texture->h : 0) < 0) { @@ -1074,17 +934,6 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I } } - if (program->uniform_locations[GLES2_UNIFORM_COLOR] != -1) { - if (data->drawstate.color != program->color) { - const Uint8 r = (data->drawstate.color >> 16) & 0xFF; - const Uint8 g = (data->drawstate.color >> 8) & 0xFF; - const Uint8 b = (data->drawstate.color >> 0) & 0xFF; - const Uint8 a = (data->drawstate.color >> 24) & 0xFF; - data->glUniform4f(program->uniform_locations[GLES2_UNIFORM_COLOR], r * inv255f, g * inv255f, b * inv255f, a * inv255f); - program->color = data->drawstate.color; - } - } - if (blend != data->drawstate.blend) { if (blend == SDL_BLENDMODE_NONE) { data->glDisable(GL_BLEND); @@ -1101,33 +950,22 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I } /* all drawing commands use this */ - data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) cmd->data.draw.first); - - if (is_copy_ex != was_copy_ex) { - if (is_copy_ex) { - data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_ANGLE); - data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_CENTER); - } else { - data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_ANGLE); - data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_CENTER); - } - data->drawstate.is_copy_ex = is_copy_ex; - } - - if (is_copy_ex) { - data->glVertexAttribPointer(GLES2_ATTRIBUTE_ANGLE, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 16))); - data->glVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 24))); + { + SDL_VertexSolid *verts = (SDL_VertexSolid *) (((Uint8 *) vertices) + cmd->data.draw.first); + data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) &verts->position); + data->glVertexAttribPointer(GLES2_ATTRIBUTE_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE /* Normalized */, stride, (const GLvoid *) &verts->color); } return 0; } static int -SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd) +SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertices) { GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata; GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; SDL_Texture *texture = cmd->data.draw.texture; + int ret; /* Pick an appropriate shader */ if (renderer->target) { @@ -1182,6 +1020,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd) break; } break; +#if SDL_HAVE_YUV case SDL_PIXELFORMAT_IYUV: case SDL_PIXELFORMAT_YV12: sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV; @@ -1192,6 +1031,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd) case SDL_PIXELFORMAT_NV21: sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21; break; +#endif case SDL_PIXELFORMAT_EXTERNAL_OES: sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES; break; @@ -1215,6 +1055,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd) case SDL_PIXELFORMAT_BGR888: sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; break; +#if SDL_HAVE_YUV case SDL_PIXELFORMAT_IYUV: case SDL_PIXELFORMAT_YV12: sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV; @@ -1225,6 +1066,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd) case SDL_PIXELFORMAT_NV21: sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21; break; +#endif case SDL_PIXELFORMAT_EXTERNAL_OES: sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES; break; @@ -1233,7 +1075,31 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd) } } - return SetDrawState(data, cmd, sourceType); + ret = SetDrawState(data, cmd, sourceType, vertices); + + if (texture != data->drawstate.texture) { + GLES2_TextureData *tdata = (GLES2_TextureData *) texture->driverdata; +#if SDL_HAVE_YUV + if (tdata->yuv) { + data->glActiveTexture(GL_TEXTURE2); + data->glBindTexture(tdata->texture_type, tdata->texture_v); + + data->glActiveTexture(GL_TEXTURE1); + data->glBindTexture(tdata->texture_type, tdata->texture_u); + + data->glActiveTexture(GL_TEXTURE0); + } else if (tdata->nv12) { + data->glActiveTexture(GL_TEXTURE1); + data->glBindTexture(tdata->texture_type, tdata->texture_u); + + data->glActiveTexture(GL_TEXTURE0); + } +#endif + data->glBindTexture(tdata->texture_type, tdata->texture); + data->drawstate.texture = texture; + } + + return ret; } static int @@ -1241,9 +1107,11 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver { GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata; const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888)); + +#if USE_VERTEX_BUFFER_OBJECTS const int vboidx = data->current_vertex_buffer; const GLuint vbo = data->vertex_buffers[vboidx]; - size_t i; +#endif if (GLES2_ActivateRenderer(renderer) < 0) { return -1; @@ -1251,9 +1119,17 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver data->drawstate.target = renderer->target; if (!data->drawstate.target) { - SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh); + int w, h; + SDL_GL_GetDrawableSize(renderer->window, &w, &h); + if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) { + data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc. + data->drawstate.cliprect_dirty = SDL_TRUE; + data->drawstate.drawablew = w; + data->drawstate.drawableh = h; + } } +#if USE_VERTEX_BUFFER_OBJECTS /* upload the new VBO data for this set of commands. */ data->glBindBuffer(GL_ARRAY_BUFFER, vbo); if (data->vertex_buffer_size[vboidx] < vertsize) { @@ -1268,15 +1144,12 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver if (data->current_vertex_buffer >= SDL_arraysize(data->vertex_buffers)) { data->current_vertex_buffer = 0; } + vertices = NULL; /* attrib pointers will be offsets into the VBO. */ +#endif while (cmd) { switch (cmd->command) { case SDL_RENDERCMD_SETDRAWCOLOR: { - const Uint8 r = colorswap ? cmd->data.color.b : cmd->data.color.r; - const Uint8 g = cmd->data.color.g; - const Uint8 b = colorswap ? cmd->data.color.r : cmd->data.color.b; - const Uint8 a = cmd->data.color.a; - data->drawstate.color = ((a << 24) | (r << 16) | (g << 8) | b); break; } @@ -1308,7 +1181,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver const Uint8 g = cmd->data.color.g; const Uint8 b = colorswap ? cmd->data.color.r : cmd->data.color.b; const Uint8 a = cmd->data.color.a; - const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); + const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b); if (color != data->drawstate.clear_color) { const GLfloat fr = ((GLfloat) r) * inv255f; const GLfloat fg = ((GLfloat) g) * inv255f; @@ -1327,38 +1200,88 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver break; } - case SDL_RENDERCMD_DRAW_POINTS: { - if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) { - data->glDrawArrays(GL_POINTS, 0, (GLsizei) cmd->data.draw.count); - } + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; + + case SDL_RENDERCMD_COPY: /* unused */ + break; + + case SDL_RENDERCMD_COPY_EX: /* unused */ break; - } case SDL_RENDERCMD_DRAW_LINES: { - const size_t count = cmd->data.draw.count; - SDL_assert(count >= 2); - if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) { - data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) count); - } - break; - } + if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID, vertices) == 0) { + size_t count = cmd->data.draw.count; + if (count > 2) { + /* joined lines cannot be grouped */ + data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)count); + } else { + /* let's group non joined lines */ + SDL_RenderCommand *finalcmd = cmd; + SDL_RenderCommand *nextcmd = cmd->next; + SDL_BlendMode thisblend = cmd->data.draw.blend; - case SDL_RENDERCMD_FILL_RECTS: { - const size_t count = cmd->data.draw.count; - size_t offset = 0; - if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) { - for (i = 0; i < count; ++i, offset += 4) { - data->glDrawArrays(GL_TRIANGLE_STRIP, (GLsizei) offset, 4); + while (nextcmd != NULL) { + const SDL_RenderCommandType nextcmdtype = nextcmd->command; + if (nextcmdtype != SDL_RENDERCMD_DRAW_LINES) { + break; /* can't go any further on this draw call, different render command up next. */ + } else if (nextcmd->data.draw.count != 2) { + break; /* can't go any further on this draw call, those are joined lines */ + } else if (nextcmd->data.draw.blend != thisblend) { + break; /* can't go any further on this draw call, different blendmode copy up next. */ + } else { + finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */ + count += nextcmd->data.draw.count; + } + nextcmd = nextcmd->next; + } + + data->glDrawArrays(GL_LINES, 0, (GLsizei)count); + cmd = finalcmd; /* skip any copy commands we just combined in here. */ } } break; } - case SDL_RENDERCMD_COPY: - case SDL_RENDERCMD_COPY_EX: { - if (SetCopyState(renderer, cmd) == 0) { - data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + case SDL_RENDERCMD_DRAW_POINTS: + case SDL_RENDERCMD_GEOMETRY: { + /* as long as we have the same copy command in a row, with the + same texture, we can combine them all into a single draw call. */ + SDL_Texture *thistexture = cmd->data.draw.texture; + SDL_BlendMode thisblend = cmd->data.draw.blend; + const SDL_RenderCommandType thiscmdtype = cmd->command; + SDL_RenderCommand *finalcmd = cmd; + SDL_RenderCommand *nextcmd = cmd->next; + size_t count = cmd->data.draw.count; + int ret; + while (nextcmd != NULL) { + const SDL_RenderCommandType nextcmdtype = nextcmd->command; + if (nextcmdtype != thiscmdtype) { + break; /* can't go any further on this draw call, different render command up next. */ + } else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) { + break; /* can't go any further on this draw call, different texture/blendmode copy up next. */ + } else { + finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */ + count += nextcmd->data.draw.count; + } + nextcmd = nextcmd->next; } + + if (thistexture) { + ret = SetCopyState(renderer, cmd, vertices); + } else { + ret = SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID, vertices); + } + + if (ret == 0) { + int op = GL_TRIANGLES; /* SDL_RENDERCMD_GEOMETRY */ + if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) { + op = GL_POINTS; + } + data->glDrawArrays(op, 0, (GLsizei) count); + } + + cmd = finalcmd; /* skip any copy commands we just combined in here. */ break; } @@ -1382,14 +1305,12 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer) GLES2_ActivateRenderer(renderer); { - GLES2_ShaderCacheEntry *entry; - GLES2_ShaderCacheEntry *next; - entry = data->shader_cache.head; - while (entry) { - data->glDeleteShader(entry->id); - next = entry->next; - SDL_free(entry); - entry = next; + int i; + for (i = 0; i < GLES2_SHADER_COUNT; i++) { + GLuint id = data->shader_id_cache[i]; + if (id) { + data->glDeleteShader(id); + } } } { @@ -1413,13 +1334,14 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer) data->framebuffers = nextnode; } +#if USE_VERTEX_BUFFER_OBJECTS data->glDeleteBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers); GL_CheckError("", renderer); +#endif SDL_GL_DeleteContext(data->context); } - SDL_free(data->shader_formats); SDL_free(data); } SDL_free(renderer); @@ -1448,6 +1370,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) format = GL_RGBA; type = GL_UNSIGNED_BYTE; break; +#if SDL_HAVE_YUV case SDL_PIXELFORMAT_IYUV: case SDL_PIXELFORMAT_YV12: case SDL_PIXELFORMAT_NV12: @@ -1455,6 +1378,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) format = GL_LUMINANCE; type = GL_UNSIGNED_BYTE; break; +#endif #ifdef GL_TEXTURE_EXTERNAL_OES case SDL_PIXELFORMAT_EXTERNAL_OES: format = GL_NONE; @@ -1483,10 +1407,12 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) #endif data->pixel_format = format; data->pixel_type = type; +#if SDL_HAVE_YUV data->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12)); data->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21)); data->texture_u = 0; data->texture_v = 0; +#endif scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR; /* Allocate a blob for image renderdata */ @@ -1494,6 +1420,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) size_t size; data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); size = texture->h * data->pitch; +#if SDL_HAVE_YUV if (data->yuv) { /* Need to add size for the U and V planes */ size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2); @@ -1501,6 +1428,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) /* Need to add size for the U/V plane */ size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2); } +#endif data->pixel_data = SDL_calloc(1, size); if (!data->pixel_data) { SDL_free(data); @@ -1511,6 +1439,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) /* Allocate the texture */ GL_CheckError("", renderer); +#if SDL_HAVE_YUV if (data->yuv) { renderdata->glGenTextures(1, &data->texture_v); if (GL_CheckError("glGenTexures()", renderer) < 0) { @@ -1554,6 +1483,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) return -1; } } +#endif renderdata->glGenTextures(1, &data->texture); if (GL_CheckError("glGenTexures()", renderer) < 0) { @@ -1586,6 +1516,9 @@ static int GLES2_TexSubImage2D(GLES2_RenderData *data, GLenum target, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, GLint pitch, GLint bpp) { Uint8 *blob = NULL; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + Uint32 *blob2 = NULL; +#endif Uint8 *src; int src_pitch; int y; @@ -1612,10 +1545,33 @@ GLES2_TexSubImage2D(GLES2_RenderData *data, GLenum target, GLint xoffset, GLint src = blob; } +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + if (format == GL_RGBA) { + int i; + Uint32 *src32 = (Uint32 *)src; + blob2 = (Uint32 *)SDL_malloc(src_pitch * height); + if (!blob2) { + if (blob) { + SDL_free(blob); + } + return SDL_OutOfMemory(); + } + for (i = 0; i < (src_pitch * height) / 4; i++) { + blob2[i] = SDL_Swap32(src32[i]); + } + src = (Uint8 *) blob2; + } +#endif + data->glTexSubImage2D(target, 0, xoffset, yoffset, width, height, format, type, src); if (blob) { SDL_free(blob); } +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + if (blob2) { + SDL_free(blob2); + } +#endif return 0; } @@ -1646,6 +1602,7 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect tdata->pixel_type, pixels, pitch, SDL_BYTESPERPIXEL(texture->format)); +#if SDL_HAVE_YUV if (tdata->yuv) { /* Skip to the correct offset into the next texture */ pixels = (const void*)((const Uint8*)pixels + rect->h * pitch); @@ -1692,10 +1649,12 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect GL_UNSIGNED_BYTE, pixels, 2 * ((pitch + 1) / 2), 2); } +#endif return GL_CheckError("glTexSubImage2D()", renderer); } +#if SDL_HAVE_YUV static int GLES2_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, @@ -1748,6 +1707,48 @@ GLES2_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, return GL_CheckError("glTexSubImage2D()", renderer); } +static int +GLES2_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ + GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; + GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; + + GLES2_ActivateRenderer(renderer); + + /* Bail out if we're supposed to update an empty rectangle */ + if (rect->w <= 0 || rect->h <= 0) { + return 0; + } + + data->drawstate.texture = NULL; /* we trash this state. */ + + data->glBindTexture(tdata->texture_type, tdata->texture_u); + GLES2_TexSubImage2D(data, tdata->texture_type, + rect->x / 2, + rect->y / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, + GL_LUMINANCE_ALPHA, + GL_UNSIGNED_BYTE, + UVplane, UVpitch, 2); + + data->glBindTexture(tdata->texture_type, tdata->texture); + GLES2_TexSubImage2D(data, tdata->texture_type, + rect->x, + rect->y, + rect->w, + rect->h, + tdata->pixel_format, + tdata->pixel_type, + Yplane, Ypitch, 1); + + return GL_CheckError("glTexSubImage2D()", renderer); +} +#endif + static int GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch) @@ -1784,6 +1785,7 @@ GLES2_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Sc GLES2_TextureData *data = (GLES2_TextureData *) texture->driverdata; GLenum glScaleMode = (scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR; +#if SDL_HAVE_YUV if (data->yuv) { renderdata->glActiveTexture(GL_TEXTURE2); renderdata->glBindTexture(data->texture_type, data->texture_v); @@ -1800,6 +1802,7 @@ GLES2_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Sc renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode); renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode); } +#endif renderdata->glActiveTexture(GL_TEXTURE0); renderdata->glBindTexture(data->texture_type, data->texture); @@ -1850,12 +1853,14 @@ GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) /* Destroy the texture */ if (tdata) { data->glDeleteTextures(1, &tdata->texture); +#if SDL_HAVE_YUV if (tdata->texture_v) { data->glDeleteTextures(1, &tdata->texture_v); } if (tdata->texture_u) { data->glDeleteTextures(1, &tdata->texture_u); } +#endif SDL_free(tdata->pixel_data); SDL_free(tdata); texture->driverdata = NULL; @@ -1927,6 +1932,26 @@ GLES2_RenderPresent(SDL_Renderer *renderer) SDL_GL_SwapWindow(renderer->window); } +static int +GLES2_SetVSync(SDL_Renderer * renderer, const int vsync) +{ + int retval; + if (vsync) { + retval = SDL_GL_SetSwapInterval(1); + } else { + retval = SDL_GL_SetSwapInterval(0); + } + if (retval != 0) { + return retval; + } + if (SDL_GL_GetSwapInterval() > 0) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return retval; +} + /************************************************************************************************* * Bind/unbinding of textures @@ -1970,20 +1995,11 @@ static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) * Renderer instantiation * *************************************************************************************************/ -#ifdef ZUNE_HD -#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B -#endif - - static SDL_Renderer * GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) { SDL_Renderer *renderer; GLES2_RenderData *data; - GLint nFormats; -#ifndef ZUNE_HD - GLboolean hasCompiler; -#endif Uint32 window_flags = 0; /* -Wconditional-uninitialized */ GLint window_framebuffer; GLint value; @@ -2085,35 +2101,10 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); renderer->info.max_texture_height = value; - /* Determine supported shader formats */ - /* HACK: glGetInteger is broken on the Zune HD's compositor, so we just hardcode this */ -#ifdef ZUNE_HD - nFormats = 1; -#else /* !ZUNE_HD */ - data->glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats); - data->glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler); - if (hasCompiler) { - ++nFormats; - } -#endif /* ZUNE_HD */ - data->shader_formats = (GLenum *)SDL_calloc(nFormats, sizeof(GLenum)); - if (!data->shader_formats) { - GLES2_DestroyRenderer(renderer); - SDL_OutOfMemory(); - goto error; - } - data->shader_format_count = nFormats; -#ifdef ZUNE_HD - data->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV; -#else /* !ZUNE_HD */ - data->glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)data->shader_formats); - if (hasCompiler) { - data->shader_formats[nFormats - 1] = (GLenum)-1; - } -#endif /* ZUNE_HD */ - +#if USE_VERTEX_BUFFER_OBJECTS /* we keep a few of these and cycle through them, so data can live for a few frames. */ data->glGenBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers); +#endif data->framebuffers = NULL; data->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer); @@ -2125,7 +2116,10 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) renderer->SupportsBlendMode = GLES2_SupportsBlendMode; renderer->CreateTexture = GLES2_CreateTexture; renderer->UpdateTexture = GLES2_UpdateTexture; +#if SDL_HAVE_YUV renderer->UpdateTextureYUV = GLES2_UpdateTextureYUV; + renderer->UpdateTextureNV = GLES2_UpdateTextureNV; +#endif renderer->LockTexture = GLES2_LockTexture; renderer->UnlockTexture = GLES2_UnlockTexture; renderer->SetTextureScaleMode = GLES2_SetTextureScaleMode; @@ -2134,21 +2128,21 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) renderer->QueueSetDrawColor = GLES2_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = GLES2_QueueDrawPoints; renderer->QueueDrawLines = GLES2_QueueDrawLines; - renderer->QueueFillRects = GLES2_QueueFillRects; - renderer->QueueCopy = GLES2_QueueCopy; - renderer->QueueCopyEx = GLES2_QueueCopyEx; + renderer->QueueGeometry = GLES2_QueueGeometry; renderer->RunCommandQueue = GLES2_RunCommandQueue; renderer->RenderReadPixels = GLES2_RenderReadPixels; renderer->RenderPresent = GLES2_RenderPresent; renderer->DestroyTexture = GLES2_DestroyTexture; renderer->DestroyRenderer = GLES2_DestroyRenderer; + renderer->SetVSync = GLES2_SetVSync; renderer->GL_BindTexture = GLES2_BindTexture; renderer->GL_UnbindTexture = GLES2_UnbindTexture; - +#if SDL_HAVE_YUV renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12; renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV; renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12; renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21; +#endif #ifdef GL_TEXTURE_EXTERNAL_OES renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_EXTERNAL_OES; #endif @@ -2159,12 +2153,12 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) data->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_COLOR); data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f); data->drawstate.blend = SDL_BLENDMODE_INVALID; - data->drawstate.color = 0xFFFFFFFF; data->drawstate.clear_color = 0xFFFFFFFF; data->drawstate.projection[3][0] = -1.0f; data->drawstate.projection[3][3] = 1.0f; @@ -2204,3 +2198,4 @@ SDL_RenderDriver GLES2_RenderDriver = { #endif /* SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED */ /* vi: set ts=4 sw=4 expandtab: */ + diff --git a/Engine/lib/sdl/src/render/opengles2/SDL_shaders_gles2.c b/Engine/lib/sdl/src/render/opengles2/SDL_shaders_gles2.c index d9db27f7a..a1f78fdd9 100644 --- a/Engine/lib/sdl/src/render/opengles2/SDL_shaders_gles2.c +++ b/Engine/lib/sdl/src/render/opengles2/SDL_shaders_gles2.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,60 +30,51 @@ /************************************************************************************************* * Vertex/fragment shader source * *************************************************************************************************/ -/* Notes on a_angle: - * It is a vector containing sin and cos for rotation matrix - * To get correct rotation for most cases when a_angle is disabled cos - value is decremented by 1.0 to get proper output with 0.0 which is - default value -*/ -static const Uint8 GLES2_VertexSrc_Default_[] = " \ +static const Uint8 GLES2_Vertex_Default[] = " \ uniform mat4 u_projection; \ attribute vec2 a_position; \ + attribute vec4 a_color; \ attribute vec2 a_texCoord; \ - attribute vec2 a_angle; \ - attribute vec2 a_center; \ varying vec2 v_texCoord; \ + varying vec4 v_color; \ \ void main() \ { \ - float s = a_angle[0]; \ - float c = a_angle[1] + 1.0; \ - mat2 rotationMatrix = mat2(c, -s, s, c); \ - vec2 position = rotationMatrix * (a_position - a_center) + a_center; \ v_texCoord = a_texCoord; \ - gl_Position = u_projection * vec4(position, 0.0, 1.0);\ + gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\ gl_PointSize = 1.0; \ + v_color = a_color; \ } \ "; -static const Uint8 GLES2_FragmentSrc_SolidSrc_[] = " \ +static const Uint8 GLES2_Fragment_Solid[] = " \ precision mediump float; \ - uniform vec4 u_color; \ + varying vec4 v_color; \ \ void main() \ { \ - gl_FragColor = u_color; \ + gl_FragColor = v_color; \ } \ "; -static const Uint8 GLES2_FragmentSrc_TextureABGRSrc_[] = " \ +static const Uint8 GLES2_Fragment_TextureABGR[] = " \ precision mediump float; \ uniform sampler2D u_texture; \ - uniform vec4 u_color; \ + varying vec4 v_color; \ varying vec2 v_texCoord; \ \ void main() \ { \ gl_FragColor = texture2D(u_texture, v_texCoord); \ - gl_FragColor *= u_color; \ + gl_FragColor *= v_color; \ } \ "; /* ARGB to ABGR conversion */ -static const Uint8 GLES2_FragmentSrc_TextureARGBSrc_[] = " \ +static const Uint8 GLES2_Fragment_TextureARGB[] = " \ precision mediump float; \ uniform sampler2D u_texture; \ - uniform vec4 u_color; \ + varying vec4 v_color; \ varying vec2 v_texCoord; \ \ void main() \ @@ -92,15 +83,15 @@ static const Uint8 GLES2_FragmentSrc_TextureARGBSrc_[] = " \ gl_FragColor = abgr; \ gl_FragColor.r = abgr.b; \ gl_FragColor.b = abgr.r; \ - gl_FragColor *= u_color; \ + gl_FragColor *= v_color; \ } \ "; /* RGB to ABGR conversion */ -static const Uint8 GLES2_FragmentSrc_TextureRGBSrc_[] = " \ +static const Uint8 GLES2_Fragment_TextureRGB[] = " \ precision mediump float; \ uniform sampler2D u_texture; \ - uniform vec4 u_color; \ + varying vec4 v_color; \ varying vec2 v_texCoord; \ \ void main() \ @@ -110,15 +101,15 @@ static const Uint8 GLES2_FragmentSrc_TextureRGBSrc_[] = " \ gl_FragColor.r = abgr.b; \ gl_FragColor.b = abgr.r; \ gl_FragColor.a = 1.0; \ - gl_FragColor *= u_color; \ + gl_FragColor *= v_color; \ } \ "; /* BGR to ABGR conversion */ -static const Uint8 GLES2_FragmentSrc_TextureBGRSrc_[] = " \ +static const Uint8 GLES2_Fragment_TextureBGR[] = " \ precision mediump float; \ uniform sampler2D u_texture; \ - uniform vec4 u_color; \ + varying vec4 v_color; \ varying vec2 v_texCoord; \ \ void main() \ @@ -126,10 +117,12 @@ static const Uint8 GLES2_FragmentSrc_TextureBGRSrc_[] = " \ vec4 abgr = texture2D(u_texture, v_texCoord); \ gl_FragColor = abgr; \ gl_FragColor.a = 1.0; \ - gl_FragColor *= u_color; \ + gl_FragColor *= v_color; \ } \ "; +#if SDL_HAVE_YUV + #define JPEG_SHADER_CONSTANTS \ "// YUV offset \n" \ "const vec3 offset = vec3(0, -0.501960814, -0.501960814);\n" \ @@ -163,7 +156,7 @@ static const Uint8 GLES2_FragmentSrc_TextureBGRSrc_[] = " \ "uniform sampler2D u_texture;\n" \ "uniform sampler2D u_texture_u;\n" \ "uniform sampler2D u_texture_v;\n" \ -"uniform vec4 u_color;\n" \ +"varying vec4 v_color;\n" \ "varying vec2 v_texCoord;\n" \ "\n" \ @@ -185,10 +178,10 @@ static const Uint8 GLES2_FragmentSrc_TextureBGRSrc_[] = " \ "\n" \ " // That was easy. :) \n" \ " gl_FragColor = vec4(rgb, 1);\n" \ -" gl_FragColor *= u_color;\n" \ +" gl_FragColor *= v_color;\n" \ "}" \ -#define NV12_SHADER_BODY \ +#define NV12_RA_SHADER_BODY \ "\n" \ "void main()\n" \ "{\n" \ @@ -205,7 +198,27 @@ static const Uint8 GLES2_FragmentSrc_TextureBGRSrc_[] = " \ "\n" \ " // That was easy. :) \n" \ " gl_FragColor = vec4(rgb, 1);\n" \ -" gl_FragColor *= u_color;\n" \ +" gl_FragColor *= v_color;\n" \ +"}" \ + +#define NV12_RG_SHADER_BODY \ +"\n" \ +"void main()\n" \ +"{\n" \ +" mediump vec3 yuv;\n" \ +" lowp vec3 rgb;\n" \ +"\n" \ +" // Get the YUV values \n" \ +" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \ +" yuv.yz = texture2D(u_texture_u, v_texCoord).rg;\n" \ +"\n" \ +" // Do the color transform \n" \ +" yuv += offset;\n" \ +" rgb = matrix * yuv;\n" \ +"\n" \ +" // That was easy. :) \n" \ +" gl_FragColor = vec4(rgb, 1);\n" \ +" gl_FragColor *= v_color;\n" \ "}" \ #define NV21_SHADER_BODY \ @@ -225,344 +238,132 @@ static const Uint8 GLES2_FragmentSrc_TextureBGRSrc_[] = " \ "\n" \ " // That was easy. :) \n" \ " gl_FragColor = vec4(rgb, 1);\n" \ -" gl_FragColor *= u_color;\n" \ +" gl_FragColor *= v_color;\n" \ "}" \ /* YUV to ABGR conversion */ -static const Uint8 GLES2_FragmentSrc_TextureYUVJPEGSrc_[] = \ +static const Uint8 GLES2_Fragment_TextureYUVJPEG[] = \ YUV_SHADER_PROLOGUE \ JPEG_SHADER_CONSTANTS \ YUV_SHADER_BODY \ ; -static const Uint8 GLES2_FragmentSrc_TextureYUVBT601Src_[] = \ +static const Uint8 GLES2_Fragment_TextureYUVBT601[] = \ YUV_SHADER_PROLOGUE \ BT601_SHADER_CONSTANTS \ YUV_SHADER_BODY \ ; -static const Uint8 GLES2_FragmentSrc_TextureYUVBT709Src_[] = \ +static const Uint8 GLES2_Fragment_TextureYUVBT709[] = \ YUV_SHADER_PROLOGUE \ BT709_SHADER_CONSTANTS \ YUV_SHADER_BODY \ ; /* NV12 to ABGR conversion */ -static const Uint8 GLES2_FragmentSrc_TextureNV12JPEGSrc_[] = \ +static const Uint8 GLES2_Fragment_TextureNV12JPEG[] = \ YUV_SHADER_PROLOGUE \ JPEG_SHADER_CONSTANTS \ - NV12_SHADER_BODY \ + NV12_RA_SHADER_BODY \ ; -static const Uint8 GLES2_FragmentSrc_TextureNV12BT601Src_[] = \ +static const Uint8 GLES2_Fragment_TextureNV12BT601_RA[] = \ YUV_SHADER_PROLOGUE \ BT601_SHADER_CONSTANTS \ - NV12_SHADER_BODY \ + NV12_RA_SHADER_BODY \ ; -static const Uint8 GLES2_FragmentSrc_TextureNV12BT709Src_[] = \ +static const Uint8 GLES2_Fragment_TextureNV12BT601_RG[] = \ + YUV_SHADER_PROLOGUE \ + BT601_SHADER_CONSTANTS \ + NV12_RG_SHADER_BODY \ +; +static const Uint8 GLES2_Fragment_TextureNV12BT709_RA[] = \ YUV_SHADER_PROLOGUE \ BT709_SHADER_CONSTANTS \ - NV12_SHADER_BODY \ + NV12_RA_SHADER_BODY \ +; +static const Uint8 GLES2_Fragment_TextureNV12BT709_RG[] = \ + YUV_SHADER_PROLOGUE \ + BT709_SHADER_CONSTANTS \ + NV12_RG_SHADER_BODY \ ; /* NV21 to ABGR conversion */ -static const Uint8 GLES2_FragmentSrc_TextureNV21JPEGSrc_[] = \ +static const Uint8 GLES2_Fragment_TextureNV21JPEG[] = \ YUV_SHADER_PROLOGUE \ JPEG_SHADER_CONSTANTS \ NV21_SHADER_BODY \ ; -static const Uint8 GLES2_FragmentSrc_TextureNV21BT601Src_[] = \ +static const Uint8 GLES2_Fragment_TextureNV21BT601[] = \ YUV_SHADER_PROLOGUE \ BT601_SHADER_CONSTANTS \ NV21_SHADER_BODY \ ; -static const Uint8 GLES2_FragmentSrc_TextureNV21BT709Src_[] = \ +static const Uint8 GLES2_Fragment_TextureNV21BT709[] = \ YUV_SHADER_PROLOGUE \ BT709_SHADER_CONSTANTS \ NV21_SHADER_BODY \ ; +#endif /* Custom Android video format texture */ -static const Uint8 GLES2_FragmentSrc_TextureExternalOESSrc_[] = " \ +static const Uint8 GLES2_Fragment_TextureExternalOES[] = " \ #extension GL_OES_EGL_image_external : require\n\ precision mediump float; \ uniform samplerExternalOES u_texture; \ - uniform vec4 u_color; \ + varying vec4 v_color; \ varying vec2 v_texCoord; \ \ void main() \ { \ gl_FragColor = texture2D(u_texture, v_texCoord); \ - gl_FragColor *= u_color; \ + gl_FragColor *= v_color; \ } \ "; -static const GLES2_ShaderInstance GLES2_VertexSrc_Default = { - GL_VERTEX_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_VertexSrc_Default_), - GLES2_VertexSrc_Default_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_SolidSrc = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_SolidSrc_), - GLES2_FragmentSrc_SolidSrc_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureABGRSrc = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureABGRSrc_), - GLES2_FragmentSrc_TextureABGRSrc_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureARGBSrc = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureARGBSrc_), - GLES2_FragmentSrc_TextureARGBSrc_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureRGBSrc = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureRGBSrc_), - GLES2_FragmentSrc_TextureRGBSrc_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureBGRSrc = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureBGRSrc_), - GLES2_FragmentSrc_TextureBGRSrc_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureYUVJPEGSrc = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureYUVJPEGSrc_), - GLES2_FragmentSrc_TextureYUVJPEGSrc_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureYUVBT601Src = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureYUVBT601Src_), - GLES2_FragmentSrc_TextureYUVBT601Src_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureYUVBT709Src = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureYUVBT709Src_), - GLES2_FragmentSrc_TextureYUVBT709Src_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV12JPEGSrc = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureNV12JPEGSrc_), - GLES2_FragmentSrc_TextureNV12JPEGSrc_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV12BT601Src = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureNV12BT601Src_), - GLES2_FragmentSrc_TextureNV12BT601Src_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV21BT709Src = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureNV21BT709Src_), - GLES2_FragmentSrc_TextureNV21BT709Src_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV21JPEGSrc = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureNV21JPEGSrc_), - GLES2_FragmentSrc_TextureNV21JPEGSrc_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV21BT601Src = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureNV21BT601Src_), - GLES2_FragmentSrc_TextureNV21BT601Src_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV12BT709Src = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureNV12BT709Src_), - GLES2_FragmentSrc_TextureNV12BT709Src_ -}; - -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureExternalOESSrc = { - GL_FRAGMENT_SHADER, - GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureExternalOESSrc_), - GLES2_FragmentSrc_TextureExternalOESSrc_ -}; - - -/************************************************************************************************* - * Vertex/fragment shader definitions * - *************************************************************************************************/ - -static GLES2_Shader GLES2_VertexShader_Default = { - 1, - { - &GLES2_VertexSrc_Default - } -}; - -static GLES2_Shader GLES2_FragmentShader_SolidSrc = { - 1, - { - &GLES2_FragmentSrc_SolidSrc - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureABGRSrc = { - 1, - { - &GLES2_FragmentSrc_TextureABGRSrc - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureARGBSrc = { - 1, - { - &GLES2_FragmentSrc_TextureARGBSrc - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureRGBSrc = { - 1, - { - &GLES2_FragmentSrc_TextureRGBSrc - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureBGRSrc = { - 1, - { - &GLES2_FragmentSrc_TextureBGRSrc - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureYUVJPEGSrc = { - 1, - { - &GLES2_FragmentSrc_TextureYUVJPEGSrc - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureYUVBT601Src = { - 1, - { - &GLES2_FragmentSrc_TextureYUVBT601Src - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureYUVBT709Src = { - 1, - { - &GLES2_FragmentSrc_TextureYUVBT709Src - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureNV12JPEGSrc = { - 1, - { - &GLES2_FragmentSrc_TextureNV12JPEGSrc - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureNV12BT601Src = { - 1, - { - &GLES2_FragmentSrc_TextureNV12BT601Src - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureNV12BT709Src = { - 1, - { - &GLES2_FragmentSrc_TextureNV12BT709Src - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureNV21JPEGSrc = { - 1, - { - &GLES2_FragmentSrc_TextureNV21JPEGSrc - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureNV21BT601Src = { - 1, - { - &GLES2_FragmentSrc_TextureNV21BT601Src - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureNV21BT709Src = { - 1, - { - &GLES2_FragmentSrc_TextureNV21BT709Src - } -}; - -static GLES2_Shader GLES2_FragmentShader_TextureExternalOESSrc = { - 1, - { - &GLES2_FragmentSrc_TextureExternalOESSrc - } -}; - /************************************************************************************************* * Shader selector * *************************************************************************************************/ -const GLES2_Shader *GLES2_GetShader(GLES2_ShaderType type) +const Uint8 *GLES2_GetShader(GLES2_ShaderType type) { switch (type) { case GLES2_SHADER_VERTEX_DEFAULT: - return &GLES2_VertexShader_Default; - case GLES2_SHADER_FRAGMENT_SOLID_SRC: - return &GLES2_FragmentShader_SolidSrc; - case GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC: - return &GLES2_FragmentShader_TextureABGRSrc; - case GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC: - return &GLES2_FragmentShader_TextureARGBSrc; - case GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC: - return &GLES2_FragmentShader_TextureRGBSrc; - case GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC: - return &GLES2_FragmentShader_TextureBGRSrc; - case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG_SRC: - return &GLES2_FragmentShader_TextureYUVJPEGSrc; - case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601_SRC: - return &GLES2_FragmentShader_TextureYUVBT601Src; - case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709_SRC: - return &GLES2_FragmentShader_TextureYUVBT709Src; - case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG_SRC: - return &GLES2_FragmentShader_TextureNV12JPEGSrc; - case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601_SRC: - return &GLES2_FragmentShader_TextureNV12BT601Src; - case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709_SRC: - return &GLES2_FragmentShader_TextureNV12BT709Src; - case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC: - return &GLES2_FragmentShader_TextureNV21JPEGSrc; - case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC: - return &GLES2_FragmentShader_TextureNV21BT601Src; - case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC: - return &GLES2_FragmentShader_TextureNV21BT709Src; - case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC: - return &GLES2_FragmentShader_TextureExternalOESSrc; + return GLES2_Vertex_Default; + case GLES2_SHADER_FRAGMENT_SOLID: + return GLES2_Fragment_Solid; + case GLES2_SHADER_FRAGMENT_TEXTURE_ABGR: + return GLES2_Fragment_TextureABGR; + case GLES2_SHADER_FRAGMENT_TEXTURE_ARGB: + return GLES2_Fragment_TextureARGB; + case GLES2_SHADER_FRAGMENT_TEXTURE_RGB: + return GLES2_Fragment_TextureRGB; + case GLES2_SHADER_FRAGMENT_TEXTURE_BGR: + return GLES2_Fragment_TextureBGR; +#if SDL_HAVE_YUV + case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG: + return GLES2_Fragment_TextureYUVJPEG; + case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601: + return GLES2_Fragment_TextureYUVBT601; + case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709: + return GLES2_Fragment_TextureYUVBT709; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG: + return GLES2_Fragment_TextureNV12JPEG; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601: + return GLES2_Fragment_TextureNV12BT601_RA; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601: + return GLES2_Fragment_TextureNV12BT601_RG; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709: + return GLES2_Fragment_TextureNV12BT709_RA; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709: + return GLES2_Fragment_TextureNV12BT709_RG; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG: + return GLES2_Fragment_TextureNV21JPEG; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601: + return GLES2_Fragment_TextureNV21BT601; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709: + return GLES2_Fragment_TextureNV21BT709; +#endif + case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES: + return GLES2_Fragment_TextureExternalOES; default: return NULL; } diff --git a/Engine/lib/sdl/src/render/opengles2/SDL_shaders_gles2.h b/Engine/lib/sdl/src/render/opengles2/SDL_shaders_gles2.h index 6cbf92acd..09780239d 100644 --- a/Engine/lib/sdl/src/render/opengles2/SDL_shaders_gles2.h +++ b/Engine/lib/sdl/src/render/opengles2/SDL_shaders_gles2.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,43 +25,33 @@ #if SDL_VIDEO_RENDER_OGL_ES2 -typedef struct GLES2_ShaderInstance -{ - GLenum type; - GLenum format; - int length; - const void *data; -} GLES2_ShaderInstance; - -typedef struct GLES2_Shader -{ - int instance_count; - const GLES2_ShaderInstance *instances[4]; -} GLES2_Shader; typedef enum { - GLES2_SHADER_VERTEX_DEFAULT, - GLES2_SHADER_FRAGMENT_SOLID_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC + GLES2_SHADER_VERTEX_DEFAULT = 0, + GLES2_SHADER_FRAGMENT_SOLID, + GLES2_SHADER_FRAGMENT_TEXTURE_ABGR, + GLES2_SHADER_FRAGMENT_TEXTURE_ARGB, + GLES2_SHADER_FRAGMENT_TEXTURE_BGR, + GLES2_SHADER_FRAGMENT_TEXTURE_RGB, +#if SDL_HAVE_YUV + GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG, + GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601, + GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709, + GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG, + GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601, + GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601, + GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709, + GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709, + GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG, + GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601, + GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709, +#endif + GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES, + GLES2_SHADER_COUNT } GLES2_ShaderType; -#define GLES2_SOURCE_SHADER (GLenum)-1 - -const GLES2_Shader *GLES2_GetShader(GLES2_ShaderType type); +const Uint8 *GLES2_GetShader(GLES2_ShaderType type); #endif /* SDL_VIDEO_RENDER_OGL_ES2 */ diff --git a/Engine/lib/sdl/src/render/psp/SDL_render_psp.c b/Engine/lib/sdl/src/render/psp/SDL_render_psp.c index 6aad21f6b..cdc0b9156 100644 --- a/Engine/lib/sdl/src/render/psp/SDL_render_psp.c +++ b/Engine/lib/sdl/src/render/psp/SDL_render_psp.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -56,24 +56,13 @@ static unsigned int __attribute__((aligned(16))) DisplayList[262144]; #define COL4444(r,g,b,a) ((r>>4) | ((g>>4)<<4) | ((b>>4)<<8) | ((a>>4)<<12)) #define COL8888(r,g,b,a) ((r) | ((g)<<8) | ((b)<<16) | ((a)<<24)) - -typedef struct -{ - void* frontbuffer ; - void* backbuffer ; - SDL_bool initialized ; - SDL_bool displayListAvail ; - unsigned int psm ; - unsigned int bpp ; - - SDL_bool vsync; - unsigned int currentColor; - int currentBlendMode; - -} PSP_RenderData; - - -typedef struct +/** + * Holds psp specific texture data + * + * Part of a hot-list of textures that are used as render targets + * When short of vram we spill Least-Recently-Used render targets to system memory + */ +typedef struct PSP_TextureData { void *data; /**< Image data. */ unsigned int size; /**< Size of data in bytes. */ @@ -85,9 +74,37 @@ typedef struct unsigned int format; /**< Image format - one of ::pgePixelFormat. */ unsigned int pitch; SDL_bool swizzled; /**< Is image swizzled. */ - + struct PSP_TextureData* prevhotw; /**< More recently used render target */ + struct PSP_TextureData* nexthotw; /**< Less recently used render target */ } PSP_TextureData; +typedef struct +{ + SDL_BlendMode mode; + unsigned int color; + int shadeModel; + SDL_Texture* texture; +} PSP_BlendState; + +typedef struct +{ + void* frontbuffer; /**< main screen buffer */ + void* backbuffer; /**< buffer presented to display */ + SDL_Texture* boundTarget; /**< currently bound rendertarget */ + SDL_bool initialized; /**< is driver initialized */ + SDL_bool displayListAvail; /**< is the display list already initialized for this frame */ + unsigned int psm; /**< format of the display buffers */ + unsigned int bpp; /**< bits per pixel of the main display */ + + SDL_bool vsync; /**< wether we do vsync */ + PSP_BlendState blendState; /**< current blend mode */ + PSP_TextureData* most_recent_target; /**< start of render target LRU double linked list */ + PSP_TextureData* least_recent_target; /**< end of the LRU list */ + + SDL_bool vblank_not_reached; /**< wether vblank wasn't reached */ +} PSP_RenderData; + + typedef struct { float x, y, z; @@ -98,15 +115,29 @@ typedef struct { float u, v; float x, y, z; - } VertTV; +typedef struct +{ + SDL_Color col; + float x, y, z; +} VertCV; + + +typedef struct +{ + float u, v; + SDL_Color col; + float x, y, z; +} VertTCV; + #define PI 3.14159265358979f #define radToDeg(x) ((x)*180.f/PI) #define degToRad(x) ((x)*PI/180.f) -float MathAbs(float x) +static float +MathAbs(float x) { float result; @@ -119,7 +150,8 @@ float MathAbs(float x) return result; } -void MathSincos(float r, float *s, float *c) +static void +MathSincos(float r, float *s, float *c) { __asm__ volatile ( "mtv %2, S002\n" @@ -131,28 +163,40 @@ void MathSincos(float r, float *s, float *c) : "=r"(*s), "=r"(*c): "r"(r)); } -void Swap(float *a, float *b) +static void +Swap(float *a, float *b) { float n=*a; *a = *b; *b = n; } +static inline int +InVram(void* data) +{ + return data < (void*)0x04200000; +} + /* Return next power of 2 */ static int TextureNextPow2(unsigned int w) { + unsigned int n = 2; if(w == 0) return 0; - unsigned int n = 2; - while(w > n) n <<= 1; return n; } +static void psp_on_vblank(u32 sub, PSP_RenderData *data) +{ + if (data) + data->vblank_not_reached = SDL_FALSE; +} + static int PixelFormatToPSPFMT(Uint32 format) @@ -171,36 +215,89 @@ PixelFormatToPSPFMT(Uint32 format) } } -void -StartDrawing(SDL_Renderer * renderer) -{ - PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata; - if(data->displayListAvail) - return; - - sceGuStart(GU_DIRECT, DisplayList); - data->displayListAvail = SDL_TRUE; +///SECTION render target LRU management +static void +LRUTargetRelink(PSP_TextureData* psp_texture) { + if(psp_texture->prevhotw) { + psp_texture->prevhotw->nexthotw = psp_texture->nexthotw; + } + if(psp_texture->nexthotw) { + psp_texture->nexthotw->prevhotw = psp_texture->prevhotw; + } } +static void +LRUTargetPushFront(PSP_RenderData* data, PSP_TextureData* psp_texture) { + psp_texture->nexthotw = data->most_recent_target; + if(data->most_recent_target) { + data->most_recent_target->prevhotw = psp_texture; + } + data->most_recent_target = psp_texture; + if(!data->least_recent_target) { + data->least_recent_target = psp_texture; + } +} -int -TextureSwizzle(PSP_TextureData *psp_texture) +static void +LRUTargetRemove(PSP_RenderData* data, PSP_TextureData* psp_texture) { + LRUTargetRelink(psp_texture); + if(data->most_recent_target == psp_texture) { + data->most_recent_target = psp_texture->nexthotw; + } + if(data->least_recent_target == psp_texture) { + data->least_recent_target = psp_texture->prevhotw; + } + psp_texture->prevhotw = NULL; + psp_texture->nexthotw = NULL; +} + +static void +LRUTargetBringFront(PSP_RenderData* data, PSP_TextureData* psp_texture) { + if(data->most_recent_target == psp_texture) { + return; //nothing to do + } + LRUTargetRemove(data, psp_texture); + LRUTargetPushFront(data, psp_texture); +} + +static void +TextureStorageFree(void* storage) { + if(InVram(storage)) { + vfree(storage); + } else { + SDL_free(storage); + } +} + +static int +TextureSwizzle(PSP_TextureData *psp_texture, void* dst) { + int bytewidth, height; + int rowblocks, rowblocksadd; + int i, j; + unsigned int blockaddress = 0; + unsigned int *src = NULL; + unsigned char *data = NULL; + if(psp_texture->swizzled) return 1; - int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3); - int height = psp_texture->size / bytewidth; + bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3); + height = psp_texture->size / bytewidth; - int rowblocks = (bytewidth>>4); - int rowblocksadd = (rowblocks-1)<<7; - unsigned int blockaddress = 0; - unsigned int *src = (unsigned int*) psp_texture->data; + rowblocks = (bytewidth>>4); + rowblocksadd = (rowblocks-1)<<7; - unsigned char *data = NULL; - data = malloc(psp_texture->size); + src = (unsigned int*) psp_texture->data; - int j; + data = dst; + if(!data) { + data = SDL_malloc(psp_texture->size); + } + + if(!data) { + return SDL_OutOfMemory(); + } for(j = 0; j < height; j++, blockaddress += 16) { @@ -208,8 +305,6 @@ TextureSwizzle(PSP_TextureData *psp_texture) block = (unsigned int*)&data[blockaddress]; - int i; - for(i = 0; i < rowblocks; i++) { *block++ = *src++; @@ -223,42 +318,50 @@ TextureSwizzle(PSP_TextureData *psp_texture) blockaddress += rowblocksadd; } - free(psp_texture->data); + TextureStorageFree(psp_texture->data); psp_texture->data = data; psp_texture->swizzled = SDL_TRUE; + sceKernelDcacheWritebackRange(psp_texture->data, psp_texture->size); return 1; } -int TextureUnswizzle(PSP_TextureData *psp_texture) + +static int +TextureUnswizzle(PSP_TextureData *psp_texture, void* dst) { + int bytewidth, height; + int widthblocks, heightblocks; + int dstpitch, dstrow; + int blockx, blocky; + int j; + unsigned int *src = NULL; + unsigned char *data = NULL; + unsigned char *ydst = NULL; + if(!psp_texture->swizzled) return 1; - int blockx, blocky; + bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3); + height = psp_texture->size / bytewidth; - int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3); - int height = psp_texture->size / bytewidth; + widthblocks = bytewidth/16; + heightblocks = height/8; - int widthblocks = bytewidth/16; - int heightblocks = height/8; + dstpitch = (bytewidth - 16)/4; + dstrow = bytewidth * 8; - int dstpitch = (bytewidth - 16)/4; - int dstrow = bytewidth * 8; + src = (unsigned int*) psp_texture->data; - unsigned int *src = (unsigned int*) psp_texture->data; + data = dst; - unsigned char *data = NULL; - - data = malloc(psp_texture->size); + if(!data) { + data = SDL_malloc(psp_texture->size); + } if(!data) - return 0; + return SDL_OutOfMemory(); - sceKernelDcacheWritebackAll(); - - int j; - - unsigned char *ydst = (unsigned char *)data; + ydst = (unsigned char *)data; for(blocky = 0; blocky < heightblocks; ++blocky) { @@ -285,15 +388,108 @@ int TextureUnswizzle(PSP_TextureData *psp_texture) ydst += dstrow; } - free(psp_texture->data); + TextureStorageFree(psp_texture->data); psp_texture->data = data; psp_texture->swizzled = SDL_FALSE; + sceKernelDcacheWritebackRange(psp_texture->data, psp_texture->size); return 1; } +static int +TextureSpillToSram(PSP_RenderData* data, PSP_TextureData* psp_texture) +{ + // Assumes the texture is in VRAM + if(psp_texture->swizzled) { + //Texture was swizzled in vram, just copy to system memory + void* data = SDL_malloc(psp_texture->size); + if(!data) { + return SDL_OutOfMemory(); + } + + SDL_memcpy(data, psp_texture->data, psp_texture->size); + vfree(psp_texture->data); + psp_texture->data = data; + return 0; + } else { + return TextureSwizzle(psp_texture, NULL); //Will realloc in sysram + } +} + +static int +TexturePromoteToVram(PSP_RenderData* data, PSP_TextureData* psp_texture, SDL_bool target) +{ + // Assumes texture in sram and a large enough continuous block in vram + void* tdata = valloc(psp_texture->size); + if(psp_texture->swizzled && target) { + return TextureUnswizzle(psp_texture, tdata); + } else { + SDL_memcpy(tdata, psp_texture->data, psp_texture->size); + SDL_free(psp_texture->data); + psp_texture->data = tdata; + return 0; + } +} + +static int +TextureSpillLRU(PSP_RenderData* data, size_t wanted) { + PSP_TextureData* lru = data->least_recent_target; + if(lru) { + if(TextureSpillToSram(data, lru) < 0) { + return -1; + } + LRUTargetRemove(data, lru); + } else { + // Asked to spill but there nothing to spill + return SDL_SetError("Could not spill more VRAM to system memory. VRAM : %dKB,(%dKB), wanted %dKB", vmemavail()/1024, vlargestblock()/1024, wanted/1024); + } + return 0; +} + +static int +TextureSpillTargetsForSpace(PSP_RenderData* data, size_t size) +{ + while(vlargestblock() < size) { + if(TextureSpillLRU(data, size) < 0) { + return -1; + } + } + return 0; +} + +static int +TextureBindAsTarget(PSP_RenderData* data, PSP_TextureData* psp_texture) { + unsigned int dstFormat; + + if(!InVram(psp_texture->data)) { + // Bring back the texture in vram + if(TextureSpillTargetsForSpace(data, psp_texture->size) < 0) { + return -1; + } + if(TexturePromoteToVram(data, psp_texture, SDL_TRUE) < 0) { + return -1; + } + } + LRUTargetBringFront(data, psp_texture); + sceGuDrawBufferList(psp_texture->format, vrelptr(psp_texture->data), psp_texture->textureWidth); + + // Stencil alpha dst hack + dstFormat = psp_texture->format; + if(dstFormat == GU_PSM_5551) { + sceGuEnable(GU_STENCIL_TEST); + sceGuStencilOp(GU_REPLACE, GU_REPLACE, GU_REPLACE); + sceGuStencilFunc(GU_GEQUAL, 0xff, 0xff); + sceGuEnable(GU_ALPHA_TEST); + sceGuAlphaFunc(GU_GREATER, 0x00, 0xff); + } else { + sceGuDisable(GU_STENCIL_TEST); + sceGuDisable(GU_ALPHA_TEST); + } + return 0; +} + static void PSP_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) { @@ -303,11 +499,11 @@ PSP_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) static int PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { -/* PSP_RenderData *renderdata = (PSP_RenderData *) renderer->driverdata; */ + PSP_RenderData *data = renderer->driverdata; PSP_TextureData* psp_texture = (PSP_TextureData*) SDL_calloc(1, sizeof(*psp_texture)); if(!psp_texture) - return -1; + return SDL_OutOfMemory(); psp_texture->swizzled = SDL_FALSE; psp_texture->width = texture->w; @@ -334,7 +530,17 @@ PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) psp_texture->pitch = psp_texture->textureWidth * SDL_BYTESPERPIXEL(texture->format); psp_texture->size = psp_texture->textureHeight*psp_texture->pitch; - psp_texture->data = SDL_calloc(1, psp_texture->size); + if(texture->access & SDL_TEXTUREACCESS_TARGET) { + if(TextureSpillTargetsForSpace(renderer->driverdata, psp_texture->size) < 0){ + return -1; + } + psp_texture->data = valloc(psp_texture->size); + if(psp_texture->data) { + LRUTargetPushFront(data, psp_texture); + } + } else { + psp_texture->data = SDL_calloc(1, psp_texture->size); + } if(!psp_texture->data) { @@ -347,32 +553,35 @@ PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } static int -PSP_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) +TextureShouldSwizzle(PSP_TextureData* psp_texture, SDL_Texture *texture) { - return SDL_Unsupported(); + return !((texture->access == SDL_TEXTUREACCESS_TARGET) && InVram(psp_texture->data)) + && texture->access != SDL_TEXTUREACCESS_STREAMING + && (texture->w >= 16 || texture->h >= 16); } -void +static void TextureActivate(SDL_Texture * texture) { PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata; int scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GU_NEAREST : GU_LINEAR; /* Swizzling is useless with small textures. */ - if (texture->w >= 16 || texture->h >= 16) + if (TextureShouldSwizzle(psp_texture, texture)) { - TextureSwizzle(psp_texture); + TextureSwizzle(psp_texture, NULL); } - sceGuEnable(GU_TEXTURE_2D); sceGuTexWrap(GU_REPEAT, GU_REPEAT); sceGuTexMode(psp_texture->format, 0, 0, psp_texture->swizzled); sceGuTexFilter(scaleMode, scaleMode); /* GU_NEAREST good for tile-map */ /* GU_LINEAR good for scaling */ sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data); - sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); } +static int +PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, void **pixels, int *pitch); static int PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, @@ -466,10 +675,98 @@ PSP_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_F return 0; } +static int +PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + int i; + int count = indices ? num_indices : num_vertices; + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + if (texture == NULL) { + VertCV *verts; + verts = (VertCV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertCV), 4, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); + + verts->x = xy_[0] * scale_x; + verts->y = xy_[1] * scale_y; + verts->z = 0; + + verts->col = col_; + + verts++; + } + } else { + PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata; + VertTCV *verts; + verts = (VertTCV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertTCV), 4, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + float *uv_; + + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); + uv_ = (float *)((char*)uv + j * uv_stride); + + verts->x = xy_[0] * scale_x; + verts->y = xy_[1] * scale_y; + verts->z = 0; + + verts->col = col_; + + verts->u = uv_[0] * psp_texture->textureWidth; + verts->v = uv_[1] * psp_texture->textureHeight; + + verts++; + } + } + + return 0; +} + static int PSP_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) { - VertV *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (VertV), 4, &cmd->data.draw.first); + VertV *verts = (VertV *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (VertV), 4, &cmd->data.draw.first); int i; if (!verts) { @@ -478,14 +775,13 @@ PSP_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FR cmd->data.draw.count = count; for (i = 0; i < count; i++, rects++) { - const SDL_FRect *rect = &rects[i]; - verts->x = rect->x; - verts->y = rect->y; + verts->x = rects->x; + verts->y = rects->y; verts->z = 0.0f; verts++; - verts->x = rect->x + rect->w; - verts->y = rect->y + rect->h; + verts->x = rects->x + rects->w + 0.5f; + verts->y = rects->y + rects->h + 0.5f; verts->z = 0.0f; verts++; } @@ -547,7 +843,7 @@ PSP_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * tex cmd->data.draw.count = count; - verts = (VertTV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertTV), 4, &cmd->data.draw.first); + verts = (VertTV *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (VertTV), 4, &cmd->data.draw.first); if (!verts) { return -1; } @@ -565,6 +861,7 @@ PSP_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * tex verts->x = curX; verts->y = y; verts->z = 0; + verts++; curU += sourceWidth; curX += polyWidth; @@ -574,6 +871,7 @@ PSP_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * tex verts->x = curX; verts->y = (y + height); verts->z = 0; + verts++; } } @@ -583,7 +881,7 @@ PSP_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * tex static int PSP_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y) { VertTV *verts = (VertTV *) SDL_AllocateRenderVertices(renderer, 4 * sizeof (VertTV), 4, &cmd->data.draw.first); const float centerx = center->x; @@ -593,25 +891,29 @@ PSP_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * t const float width = dstrect->w - centerx; const float height = dstrect->h - centery; float s, c; + float cw1, sw1, ch1, sh1, cw2, sw2, ch2, sh2; float u0 = srcrect->x; float v0 = srcrect->y; float u1 = srcrect->x + srcrect->w; float v1 = srcrect->y + srcrect->h; - if (!verts) { return -1; } cmd->data.draw.count = 1; - MathSincos(degToRad(angle), &s, &c); + MathSincos(degToRad(360-angle), &s, &c); - const float cw = c * width; - const float sw = s * width; - const float ch = c * height; - const float sh = s * height; + cw1 = c * -centerx; + sw1 = s * -centerx; + ch1 = c * -centery; + sh1 = s * -centery; + cw2 = c * width; + sw2 = s * width; + ch2 = c * height; + sh2 = s * height; if (flip & SDL_FLIP_VERTICAL) { Swap(&v0, &v1); @@ -623,76 +925,148 @@ PSP_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * t verts->u = u0; verts->v = v0; - verts->x = x - cw + sh; - verts->y = y - sw - ch; + verts->x = x + cw1 + sh1; + verts->y = y - sw1 + ch1; verts->z = 0; verts++; verts->u = u0; verts->v = v1; - verts->x = x - cw - sh; - verts->y = y - sw + ch; + verts->x = x + cw1 + sh2; + verts->y = y - sw1 + ch2; verts->z = 0; verts++; verts->u = u1; verts->v = v1; - verts->x = x + cw - sh; - verts->y = y + sw + ch; + verts->x = x + cw2 + sh2; + verts->y = y - sw2 + ch2; verts->z = 0; verts++; verts->u = u1; verts->v = v0; - verts->x = x + cw + sh; - verts->y = y + sw - ch; + verts->x = x + cw2 + sh1; + verts->y = y - sw2 + ch1; verts->z = 0; - verts++; + + if (scale_x != 1.0f || scale_y != 1.0f) { + verts->x *= scale_x; + verts->y *= scale_y; + verts--; + verts->x *= scale_x; + verts->y *= scale_y; + verts--; + verts->x *= scale_x; + verts->y *= scale_y; + verts--; + verts->x *= scale_x; + verts->y *= scale_y; + } return 0; } static void -PSP_SetBlendMode(SDL_Renderer * renderer, int blendMode) +ResetBlendState(PSP_BlendState* state) { + sceGuColor(0xffffffff); + state->color = 0xffffffff; + state->mode = SDL_BLENDMODE_INVALID; + state->texture = NULL; + sceGuDisable(GU_TEXTURE_2D); + sceGuShadeModel(GU_SMOOTH); + state->shadeModel = GU_SMOOTH; +} + +static void +StartDrawing(SDL_Renderer * renderer) { PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata; - if (blendMode != data-> currentBlendMode) { - switch (blendMode) { + + // Check if we need to start GU displaylist + if(!data->displayListAvail) { + sceGuStart(GU_DIRECT, DisplayList); + data->displayListAvail = SDL_TRUE; + //ResetBlendState(&data->blendState); + } + + // Check if we need a draw buffer change + if(renderer->target != data->boundTarget) { + SDL_Texture* texture = renderer->target; + if(texture) { + PSP_TextureData* psp_texture = (PSP_TextureData*) texture->driverdata; + // Set target, registering LRU + TextureBindAsTarget(data, psp_texture); + } else { + // Set target back to screen + sceGuDrawBufferList(data->psm, vrelptr(data->frontbuffer), PSP_FRAME_BUFFER_WIDTH); + } + data->boundTarget = texture; + } +} + + +static void +PSP_SetBlendState(PSP_RenderData* data, PSP_BlendState* state) +{ + PSP_BlendState* current = &data->blendState; + + if (state->mode != current->mode) { + switch (state->mode) { case SDL_BLENDMODE_NONE: - sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); - sceGuDisable(GU_BLEND); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + sceGuDisable(GU_BLEND); break; case SDL_BLENDMODE_BLEND: - sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA); - sceGuEnable(GU_BLEND); - sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 ); + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 ); + sceGuEnable(GU_BLEND); break; case SDL_BLENDMODE_ADD: - sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA); - sceGuEnable(GU_BLEND); - sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF ); + sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF ); + sceGuEnable(GU_BLEND); break; case SDL_BLENDMODE_MOD: - sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA); - sceGuEnable(GU_BLEND); - sceGuBlendFunc(GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0); + sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0); + sceGuEnable(GU_BLEND); break; case SDL_BLENDMODE_MUL: - sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA); - sceGuEnable(GU_BLEND); - sceGuBlendFunc(GU_ADD, GU_DST_COLOR, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_DST_COLOR, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuEnable(GU_BLEND); + break; + case SDL_BLENDMODE_INVALID: break; } - data->currentBlendMode = blendMode; } + + if(state->color != current->color) { + sceGuColor(state->color); + } + + if(state->shadeModel != current->shadeModel) { + sceGuShadeModel(state->shadeModel); + } + + if(state->texture != current->texture) { + if(state->texture != NULL) { + TextureActivate(state->texture); + sceGuEnable(GU_TEXTURE_2D); + } else { + sceGuDisable(GU_TEXTURE_2D); + } + } + + *current = *state; } static int PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata; - size_t i; - + Uint8 *gpumem = NULL; StartDrawing(renderer); /* note that before the renderer interface change, this would do extrememly small @@ -701,7 +1075,7 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti I don't know what the limits on PSP hardware are. It might be useful to have rendering backends report a reasonable maximum, so the higher level can flush if we appear to be exceeding that. */ - Uint8 *gpumem = (Uint8 *) sceGuGetMemory(vertsize); + gpumem = (Uint8 *) sceGuGetMemory(vertsize); if (!gpumem) { return SDL_SetError("Couldn't obtain a %d-byte vertex buffer!", (int) vertsize); } @@ -714,23 +1088,20 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti } case SDL_RENDERCMD_SETVIEWPORT: { - SDL_Rect *viewport = &data->drawstate.viewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); - data->drawstate.viewport_dirty = SDL_TRUE; - } + SDL_Rect *viewport = &cmd->data.viewport.rect; + sceGuOffset(2048 - (viewport->w >> 1), 2048 - (viewport->h >> 1)); + sceGuViewport(2048, 2048, viewport->w, viewport->h); + sceGuScissor(viewport->x, viewport->y, viewport->w, viewport->h); break; } case SDL_RENDERCMD_SETCLIPRECT: { const SDL_Rect *rect = &cmd->data.cliprect.rect; - if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { - data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; - data->drawstate.cliprect_enabled_dirty = SDL_TRUE; - } - if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); - data->drawstate.cliprect_dirty = SDL_TRUE; + if(cmd->data.cliprect.enabled){ + sceGuEnable(GU_SCISSOR_TEST); + sceGuScissor(rect->x, rect->y, rect->w, rect->h); + } else { + sceGuDisable(GU_SCISSOR_TEST); } break; } @@ -740,11 +1111,9 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti const Uint8 g = cmd->data.color.g; const Uint8 b = cmd->data.color.b; const Uint8 a = cmd->data.color.a; - const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r); - /* !!! FIXME: we could cache drawstate like clear color */ - sceGuClearColor(color); - sceGuClearDepth(0); - sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT); + sceGuClearColor(GU_RGBA(r,g,b,a)); + sceGuClearStencil(a); + sceGuClear(GU_COLOR_BUFFER_BIT | GU_STENCIL_BUFFER_BIT); break; } @@ -755,14 +1124,14 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti const Uint8 g = cmd->data.draw.g; const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; - const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r); - /* !!! FIXME: we could cache draw state like color, texturing, etc */ - sceGuColor(color); - sceGuDisable(GU_TEXTURE_2D); - sceGuShadeModel(GU_FLAT); + PSP_BlendState state = { + .color = GU_RGBA(r,g,b,a), + .texture = NULL, + .mode = cmd->data.draw.blend, + .shadeModel = GU_FLAT + }; + PSP_SetBlendState(data, &state); sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts); - sceGuShadeModel(GU_SMOOTH); - sceGuEnable(GU_TEXTURE_2D); break; } @@ -773,14 +1142,14 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti const Uint8 g = cmd->data.draw.g; const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; - const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r); - /* !!! FIXME: we could cache draw state like color, texturing, etc */ - sceGuColor(color); - sceGuDisable(GU_TEXTURE_2D); - sceGuShadeModel(GU_FLAT); + PSP_BlendState state = { + .color = GU_RGBA(r,g,b,a), + .texture = NULL, + .mode = cmd->data.draw.blend, + .shadeModel = GU_FLAT + }; + PSP_SetBlendState(data, &state); sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts); - sceGuShadeModel(GU_SMOOTH); - sceGuEnable(GU_TEXTURE_2D); break; } @@ -791,58 +1160,75 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti const Uint8 g = cmd->data.draw.g; const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; - const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r); - /* !!! FIXME: we could cache draw state like color, texturing, etc */ - sceGuColor(color); - sceGuDisable(GU_TEXTURE_2D); - sceGuShadeModel(GU_FLAT); + PSP_BlendState state = { + .color = GU_RGBA(r,g,b,a), + .texture = NULL, + .mode = cmd->data.draw.blend, + .shadeModel = GU_FLAT + }; + PSP_SetBlendState(data, &state); sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2 * count, 0, verts); - sceGuShadeModel(GU_SMOOTH); - sceGuEnable(GU_TEXTURE_2D); break; } case SDL_RENDERCMD_COPY: { const size_t count = cmd->data.draw.count; const VertTV *verts = (VertTV *) (gpumem + cmd->data.draw.first); - const Uint8 alpha = cmd->data.draw.a; - TextureActivate(cmd->data.draw.texture); - PSP_SetBlendMode(renderer, cmd->data.draw.blend); - - if(alpha != 255) { /* !!! FIXME: is this right? */ - sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); - sceGuColor(GU_RGBA(255, 255, 255, alpha)); - } else { - sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); - sceGuColor(0xFFFFFFFF); - } - + const Uint8 a = cmd->data.draw.a; + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + PSP_BlendState state = { + .color = GU_RGBA(r,g,b,a), + .texture = cmd->data.draw.texture, + .mode = cmd->data.draw.blend, + .shadeModel = GU_SMOOTH + }; + PSP_SetBlendState(data, &state); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2 * count, 0, verts); - - if(alpha != 255) { - sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); - } break; } case SDL_RENDERCMD_COPY_EX: { const VertTV *verts = (VertTV *) (gpumem + cmd->data.draw.first); - const Uint8 alpha = cmd->data.draw.a; - TextureActivate(cmd->data.draw.texture); - PSP_SetBlendMode(renderer, cmd->data.draw.blend); - - if(alpha != 255) { /* !!! FIXME: is this right? */ - sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); - sceGuColor(GU_RGBA(255, 255, 255, alpha)); - } else { - sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); - sceGuColor(0xFFFFFFFF); - } - + const Uint8 a = cmd->data.draw.a; + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + PSP_BlendState state = { + .color = GU_RGBA(r,g,b,a), + .texture = cmd->data.draw.texture, + .mode = cmd->data.draw.blend, + .shadeModel = GU_SMOOTH + }; + PSP_SetBlendState(data, &state); sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, verts); + break; + } - if(alpha != 255) { - sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + case SDL_RENDERCMD_GEOMETRY: { + const size_t count = cmd->data.draw.count; + if (cmd->data.draw.texture == NULL) { + const VertCV *verts = (VertCV *) (gpumem + cmd->data.draw.first); + sceGuDisable(GU_TEXTURE_2D); + /* In GU_SMOOTH mode */ + sceGuDrawArray(GU_TRIANGLES, GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts); + sceGuEnable(GU_TEXTURE_2D); + } else { + const VertTCV *verts = (VertTCV *) (gpumem + cmd->data.draw.first); + const Uint8 a = cmd->data.draw.a; + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + PSP_BlendState state = { + .color = GU_RGBA(r,g,b,a), + .texture = NULL, + .mode = cmd->data.draw.blend, + .shadeModel = GU_FLAT + }; + TextureActivate(cmd->data.draw.texture); + PSP_SetBlendState(data, &state); + sceGuDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts); } break; } @@ -875,8 +1261,9 @@ PSP_RenderPresent(SDL_Renderer * renderer) sceGuFinish(); sceGuSync(0,0); -/* if(data->vsync) */ + if ((data->vsync) && (data->vblank_not_reached)) sceDisplayWaitVblankStart(); + data->vblank_not_reached = SDL_TRUE; data->backbuffer = data->frontbuffer; data->frontbuffer = vabsptr(sceGuSwapBuffers()); @@ -895,7 +1282,8 @@ PSP_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) if(psp_texture == 0) return; - SDL_free(psp_texture->data); + LRUTargetRemove(renderdata, psp_texture); + TextureStorageFree(psp_texture->data); SDL_free(psp_texture); texture->driverdata = NULL; } @@ -910,9 +1298,13 @@ PSP_DestroyRenderer(SDL_Renderer * renderer) StartDrawing(renderer); + sceKernelDisableSubIntr(PSP_VBLANK_INT, 0); + sceKernelReleaseSubIntrHandler(PSP_VBLANK_INT,0); + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_FALSE); sceGuTerm(); -/* vfree(data->backbuffer); */ -/* vfree(data->frontbuffer); */ + vfree(data->backbuffer); + vfree(data->frontbuffer); data->initialized = SDL_FALSE; data->displayListAvail = SDL_FALSE; @@ -921,13 +1313,23 @@ PSP_DestroyRenderer(SDL_Renderer * renderer) SDL_free(renderer); } +static int +PSP_SetVSync(SDL_Renderer * renderer, const int vsync) +{ + PSP_RenderData *data = renderer->driverdata; + data->vsync = vsync; + return 0; +} + SDL_Renderer * PSP_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_Renderer *renderer; PSP_RenderData *data; - int pixelformat; + int pixelformat; + void* doublebuffer = NULL; + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); @@ -944,7 +1346,6 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->WindowEvent = PSP_WindowEvent; renderer->CreateTexture = PSP_CreateTexture; - renderer->SetTextureColorMod = PSP_SetTextureColorMod; renderer->UpdateTexture = PSP_UpdateTexture; renderer->LockTexture = PSP_LockTexture; renderer->UnlockTexture = PSP_UnlockTexture; @@ -954,6 +1355,7 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->QueueSetDrawColor = PSP_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = PSP_QueueDrawPoints; renderer->QueueDrawLines = PSP_QueueDrawPoints; /* lines and points queue vertices the same way. */ + renderer->QueueGeometry = PSP_QueueGeometry; renderer->QueueFillRects = PSP_QueueFillRects; renderer->QueueCopy = PSP_QueueCopy; renderer->QueueCopyEx = PSP_QueueCopyEx; @@ -962,6 +1364,7 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->RenderPresent = PSP_RenderPresent; renderer->DestroyTexture = PSP_DestroyTexture; renderer->DestroyRenderer = PSP_DestroyRenderer; + renderer->SetVSync = PSP_SetVSync; renderer->info = PSP_RenderDriver.info; renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); renderer->driverdata = data; @@ -971,6 +1374,9 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags) return 0; data->initialized = SDL_TRUE; + data->most_recent_target = NULL; + data->least_recent_target = NULL; + if (flags & SDL_RENDERER_PRESENTVSYNC) { data->vsync = SDL_TRUE; } else { @@ -983,56 +1389,56 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags) case GU_PSM_4444: case GU_PSM_5650: case GU_PSM_5551: - data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1); - data->backbuffer = (unsigned int *)(0); data->bpp = 2; data->psm = pixelformat; break; default: - data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2); - data->backbuffer = (unsigned int *)(0); data->bpp = 4; data->psm = GU_PSM_8888; break; } + doublebuffer = valloc(PSP_FRAME_BUFFER_SIZE*data->bpp*2); + data->backbuffer = doublebuffer; + data->frontbuffer = ((uint8_t*)doublebuffer)+PSP_FRAME_BUFFER_SIZE*data->bpp; + sceGuInit(); /* setup GU */ sceGuStart(GU_DIRECT, DisplayList); - sceGuDrawBuffer(data->psm, data->frontbuffer, PSP_FRAME_BUFFER_WIDTH); - sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, data->backbuffer, PSP_FRAME_BUFFER_WIDTH); + sceGuDrawBuffer(data->psm, vrelptr(data->frontbuffer), PSP_FRAME_BUFFER_WIDTH); + sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, vrelptr(data->backbuffer), PSP_FRAME_BUFFER_WIDTH); sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1)); sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT); - data->frontbuffer = vabsptr(data->frontbuffer); - data->backbuffer = vabsptr(data->backbuffer); + + sceGuDisable(GU_DEPTH_TEST); /* Scissoring */ sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); /* Backface culling */ + /* + FIXME: Culling probably un-needed ? It can conflict with SDL_RENDERCMD_GEOMETRY sceGuFrontFace(GU_CCW); sceGuEnable(GU_CULL_FACE); + */ - /* Texturing */ - sceGuEnable(GU_TEXTURE_2D); - sceGuShadeModel(GU_SMOOTH); - sceGuTexWrap(GU_REPEAT, GU_REPEAT); - - /* Blending */ - sceGuEnable(GU_BLEND); - sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); - - sceGuTexFilter(GU_LINEAR,GU_LINEAR); + //Setup initial blend state + ResetBlendState(&data->blendState); sceGuFinish(); sceGuSync(0,0); sceDisplayWaitVblankStartCB(); sceGuDisplay(GU_TRUE); + /* Improve performance when VSYC is enabled and it is not reaching the 60 FPS */ + data->vblank_not_reached = SDL_TRUE; + sceKernelRegisterSubIntrHandler(PSP_VBLANK_INT, 0, psp_on_vblank, data); + sceKernelEnableSubIntr(PSP_VBLANK_INT, 0); + return renderer; } diff --git a/Engine/lib/sdl/src/render/software/SDL_blendfillrect.c b/Engine/lib/sdl/src/render/software/SDL_blendfillrect.c index 9ab547681..569c15058 100644 --- a/Engine/lib/sdl/src/render/software/SDL_blendfillrect.c +++ b/Engine/lib/sdl/src/render/software/SDL_blendfillrect.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -220,7 +220,7 @@ SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect, SDL_Rect clipped; if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_BlendFillRect(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ @@ -291,7 +291,7 @@ SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, int status = 0; if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_BlendFillRects(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ diff --git a/Engine/lib/sdl/src/render/software/SDL_blendfillrect.h b/Engine/lib/sdl/src/render/software/SDL_blendfillrect.h index f120e130c..8ee62b198 100644 --- a/Engine/lib/sdl/src/render/software/SDL_blendfillrect.h +++ b/Engine/lib/sdl/src/render/software/SDL_blendfillrect.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/software/SDL_blendline.c b/Engine/lib/sdl/src/render/software/SDL_blendline.c index 38b2d04bf..4921bf101 100644 --- a/Engine/lib/sdl/src/render/software/SDL_blendline.c +++ b/Engine/lib/sdl/src/render/software/SDL_blendline.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -809,7 +809,7 @@ SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, BlendLineFunc func; if (!dst) { - return SDL_SetError("SDL_BlendLine(): Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_BlendLine(): dst"); } func = SDL_CalculateBlendLineFunc(dst->format); diff --git a/Engine/lib/sdl/src/render/software/SDL_blendline.h b/Engine/lib/sdl/src/render/software/SDL_blendline.h index 4e313135e..a844110c4 100644 --- a/Engine/lib/sdl/src/render/software/SDL_blendline.h +++ b/Engine/lib/sdl/src/render/software/SDL_blendline.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/software/SDL_blendpoint.c b/Engine/lib/sdl/src/render/software/SDL_blendpoint.c index b6a406e51..613169b7b 100644 --- a/Engine/lib/sdl/src/render/software/SDL_blendpoint.c +++ b/Engine/lib/sdl/src/render/software/SDL_blendpoint.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -218,7 +218,7 @@ SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r Uint8 g, Uint8 b, Uint8 a) { if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_BlendPoint(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ @@ -287,7 +287,7 @@ SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count, int status = 0; if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_BlendPoints(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ diff --git a/Engine/lib/sdl/src/render/software/SDL_blendpoint.h b/Engine/lib/sdl/src/render/software/SDL_blendpoint.h index 9ac836577..bf6ddec07 100644 --- a/Engine/lib/sdl/src/render/software/SDL_blendpoint.h +++ b/Engine/lib/sdl/src/render/software/SDL_blendpoint.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/software/SDL_draw.h b/Engine/lib/sdl/src/render/software/SDL_draw.h index 0d66f2dc4..2acb3d3a1 100644 --- a/Engine/lib/sdl/src/render/software/SDL_draw.h +++ b/Engine/lib/sdl/src/render/software/SDL_draw.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -618,10 +618,10 @@ do { \ while (height--) { \ { int n = (width+3)/4; \ switch (width & 3) { \ - case 0: do { op; pixel++; /* fallthrough */ \ - case 3: op; pixel++; /* fallthrough */ \ - case 2: op; pixel++; /* fallthrough */ \ - case 1: op; pixel++; /* fallthrough */ \ + case 0: do { op; pixel++; SDL_FALLTHROUGH; \ + case 3: op; pixel++; SDL_FALLTHROUGH; \ + case 2: op; pixel++; SDL_FALLTHROUGH; \ + case 1: op; pixel++; \ } while ( --n > 0 ); \ } \ } \ diff --git a/Engine/lib/sdl/src/render/software/SDL_drawline.c b/Engine/lib/sdl/src/render/software/SDL_drawline.c index 0faeb4fc1..e309f1619 100644 --- a/Engine/lib/sdl/src/render/software/SDL_drawline.c +++ b/Engine/lib/sdl/src/render/software/SDL_drawline.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -144,7 +144,7 @@ SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color) DrawLineFunc func; if (!dst) { - return SDL_SetError("SDL_DrawLine(): Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_DrawLine(): dst"); } func = SDL_CalculateDrawLineFunc(dst->format); @@ -173,7 +173,7 @@ SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, DrawLineFunc func; if (!dst) { - return SDL_SetError("SDL_DrawLines(): Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_DrawLines(): dst"); } func = SDL_CalculateDrawLineFunc(dst->format); @@ -193,8 +193,8 @@ SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, continue; } - /* Draw the end if it was clipped */ - draw_end = (x2 != points[i].x || y2 != points[i].y); + /* Draw the end if the whole line is a single point or it was clipped */ + draw_end = ((x1 == x2) && (y1 == y2)) || (x2 != points[i].x || y2 != points[i].y); func(dst, x1, y1, x2, y2, color, draw_end); } diff --git a/Engine/lib/sdl/src/render/software/SDL_drawline.h b/Engine/lib/sdl/src/render/software/SDL_drawline.h index ca464345f..186119e8e 100644 --- a/Engine/lib/sdl/src/render/software/SDL_drawline.h +++ b/Engine/lib/sdl/src/render/software/SDL_drawline.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/software/SDL_drawpoint.c b/Engine/lib/sdl/src/render/software/SDL_drawpoint.c index 0e78744b9..b99838ac6 100644 --- a/Engine/lib/sdl/src/render/software/SDL_drawpoint.c +++ b/Engine/lib/sdl/src/render/software/SDL_drawpoint.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,7 +30,7 @@ int SDL_DrawPoint(SDL_Surface * dst, int x, int y, Uint32 color) { if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_DrawPoint(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ @@ -71,7 +71,7 @@ SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count, int x, y; if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_DrawPoints(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ diff --git a/Engine/lib/sdl/src/render/software/SDL_drawpoint.h b/Engine/lib/sdl/src/render/software/SDL_drawpoint.h index 33e014fd7..4c019e014 100644 --- a/Engine/lib/sdl/src/render/software/SDL_drawpoint.h +++ b/Engine/lib/sdl/src/render/software/SDL_drawpoint.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/software/SDL_render_sw.c b/Engine/lib/sdl/src/render/software/SDL_render_sw.c index 18dc1808c..a1af12cd6 100644 --- a/Engine/lib/sdl/src/render/software/SDL_render_sw.c +++ b/Engine/lib/sdl/src/render/software/SDL_render_sw.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,6 +33,7 @@ #include "SDL_drawline.h" #include "SDL_drawpoint.h" #include "SDL_rotate.h" +#include "SDL_triangle.h" /* SDL surface based renderer implementation */ @@ -98,8 +99,7 @@ SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) return 0; } - SDL_SetError("Software renderer doesn't have an output surface"); - return -1; + return SDL_SetError("Software renderer doesn't have an output surface"); } static int @@ -116,9 +116,8 @@ SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) texture->driverdata = SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask, Bmask, Amask); - SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g, - texture->b); - SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a); + SDL_SetSurfaceColorMod(texture->driverdata, texture->color.r, texture->color.g, texture->color.b); + SDL_SetSurfaceAlphaMod(texture->driverdata, texture->color.a); SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode); /* Only RLE encode textures without an alpha channel since the RLE coder @@ -214,18 +213,9 @@ SW_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FP cmd->data.draw.count = count; - if (renderer->viewport.x || renderer->viewport.y) { - const int x = renderer->viewport.x; - const int y = renderer->viewport.y; - for (i = 0; i < count; i++, verts++, points++) { - verts->x = (int)(x + points->x); - verts->y = (int)(y + points->y); - } - } else { - for (i = 0; i < count; i++, verts++, points++) { - verts->x = (int)points->x; - verts->y = (int)points->y; - } + for (i = 0; i < count; i++, verts++, points++) { + verts->x = (int)points->x; + verts->y = (int)points->y; } return 0; @@ -243,23 +233,11 @@ SW_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRe cmd->data.draw.count = count; - if (renderer->viewport.x || renderer->viewport.y) { - const int x = renderer->viewport.x; - const int y = renderer->viewport.y; - - for (i = 0; i < count; i++, verts++, rects++) { - verts->x = (int)(x + rects->x); - verts->y = (int)(y + rects->y); - verts->w = SDL_max((int)rects->w, 1); - verts->h = SDL_max((int)rects->h, 1); - } - } else { - for (i = 0; i < count; i++, verts++, rects++) { - verts->x = (int)rects->x; - verts->y = (int)rects->y; - verts->w = SDL_max((int)rects->w, 1); - verts->h = SDL_max((int)rects->h, 1); - } + for (i = 0; i < count; i++, verts++, rects++) { + verts->x = (int)rects->x; + verts->y = (int)rects->y; + verts->w = SDL_max((int)rects->w, 1); + verts->h = SDL_max((int)rects->h, 1); } return 0; @@ -280,13 +258,8 @@ SW_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * text SDL_memcpy(verts, srcrect, sizeof (SDL_Rect)); verts++; - if (renderer->viewport.x || renderer->viewport.y) { - verts->x = (int)(renderer->viewport.x + dstrect->x); - verts->y = (int)(renderer->viewport.y + dstrect->y); - } else { - verts->x = (int)dstrect->x; - verts->y = (int)dstrect->y; - } + verts->x = (int)dstrect->x; + verts->y = (int)dstrect->y; verts->w = (int)dstrect->w; verts->h = (int)dstrect->h; @@ -300,12 +273,14 @@ typedef struct CopyExData double angle; SDL_FPoint center; SDL_RendererFlip flip; + float scale_x; + float scale_y; } CopyExData; static int SW_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y) { CopyExData *verts = (CopyExData *) SDL_AllocateRenderVertices(renderer, sizeof (CopyExData), 0, &cmd->data.draw.first); @@ -317,33 +292,48 @@ SW_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * te SDL_memcpy(&verts->srcrect, srcrect, sizeof (SDL_Rect)); - if (renderer->viewport.x || renderer->viewport.y) { - verts->dstrect.x = (int)(renderer->viewport.x + dstrect->x); - verts->dstrect.y = (int)(renderer->viewport.y + dstrect->y); - } else { - verts->dstrect.x = (int)dstrect->x; - verts->dstrect.y = (int)dstrect->y; - } + verts->dstrect.x = (int)dstrect->x; + verts->dstrect.y = (int)dstrect->y; verts->dstrect.w = (int)dstrect->w; verts->dstrect.h = (int)dstrect->h; verts->angle = angle; SDL_memcpy(&verts->center, center, sizeof (SDL_FPoint)); verts->flip = flip; + verts->scale_x = scale_x; + verts->scale_y = scale_y; return 0; } +static int +Blit_to_Screen(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *surface, SDL_Rect *dstrect, + float scale_x, float scale_y, SDL_ScaleMode scaleMode) +{ + int retval; + /* Renderer scaling, if needed */ + if (scale_x != 1.0f || scale_y != 1.0f) { + SDL_Rect r; + r.x = (int)((float) dstrect->x * scale_x); + r.y = (int)((float) dstrect->y * scale_y); + r.w = (int)((float) dstrect->w * scale_x); + r.h = (int)((float) dstrect->h * scale_y); + retval = SDL_PrivateUpperBlitScaled(src, srcrect, surface, &r, scaleMode); + } else { + retval = SDL_BlitSurface(src, srcrect, surface, dstrect); + } + return retval; +} + static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * final_rect, - const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip, float scale_x, float scale_y) { SDL_Surface *src = (SDL_Surface *) texture->driverdata; SDL_Rect tmp_rect; SDL_Surface *src_clone, *src_rotated, *src_scaled; SDL_Surface *mask = NULL, *mask_rotated = NULL; - int retval = 0, dstwidth, dstheight, abscenterx, abscentery; - double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y; + int retval = 0; SDL_BlendMode blendmode; Uint8 alphaMod, rMod, gMod, bMod; int applyModulation = SDL_FALSE; @@ -434,7 +424,7 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex retval = -1; } else { SDL_SetSurfaceBlendMode(src_clone, SDL_BLENDMODE_NONE); - retval = SDL_BlitScaled(src_clone, srcrect, src_scaled, &scale_rect); + retval = SDL_PrivateUpperBlitScaled(src_clone, srcrect, src_scaled, &scale_rect, texture->scaleMode); SDL_FreeSurface(src_clone); src_clone = src_scaled; src_scaled = NULL; @@ -445,53 +435,32 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex SDL_SetSurfaceBlendMode(src_clone, blendmode); if (!retval) { - SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle); - src_rotated = SDLgfx_rotateSurface(src_clone, angle, dstwidth/2, dstheight/2, (texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle); + SDL_Rect rect_dest; + double cangle, sangle; + + SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, center, + &rect_dest, &cangle, &sangle); + src_rotated = SDLgfx_rotateSurface(src_clone, angle, + (texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, + &rect_dest, cangle, sangle, center); if (src_rotated == NULL) { retval = -1; } if (!retval && mask != NULL) { /* The mask needed for the NONE blend mode gets rotated with the same parameters. */ - mask_rotated = SDLgfx_rotateSurface(mask, angle, dstwidth/2, dstheight/2, SDL_FALSE, 0, 0, dstwidth, dstheight, cangle, sangle); + mask_rotated = SDLgfx_rotateSurface(mask, angle, + SDL_FALSE, 0, 0, + &rect_dest, cangle, sangle, center); if (mask_rotated == NULL) { retval = -1; } } if (!retval) { - /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */ - abscenterx = final_rect->x + (int)center->x; - abscentery = final_rect->y + (int)center->y; - /* Compensate the angle inversion to match the behaviour of the other backends */ - sangle = -sangle; - /* Top Left */ - px = final_rect->x - abscenterx; - py = final_rect->y - abscentery; - p1x = px * cangle - py * sangle + abscenterx; - p1y = px * sangle + py * cangle + abscentery; - - /* Top Right */ - px = final_rect->x + final_rect->w - abscenterx; - py = final_rect->y - abscentery; - p2x = px * cangle - py * sangle + abscenterx; - p2y = px * sangle + py * cangle + abscentery; - - /* Bottom Left */ - px = final_rect->x - abscenterx; - py = final_rect->y + final_rect->h - abscentery; - p3x = px * cangle - py * sangle + abscenterx; - p3y = px * sangle + py * cangle + abscentery; - - /* Bottom Right */ - px = final_rect->x + final_rect->w - abscenterx; - py = final_rect->y + final_rect->h - abscentery; - p4x = px * cangle - py * sangle + abscenterx; - p4y = px * sangle + py * cangle + abscentery; - - tmp_rect.x = (int)MIN(MIN(p1x, p2x), MIN(p3x, p4x)); - tmp_rect.y = (int)MIN(MIN(p1y, p2y), MIN(p3y, p4y)); - tmp_rect.w = dstwidth; - tmp_rect.h = dstheight; + tmp_rect.x = final_rect->x + rect_dest.x; + tmp_rect.y = final_rect->y + rect_dest.y; + tmp_rect.w = rect_dest.w; + tmp_rect.h = rect_dest.h; /* The NONE blend mode needs some special care with non-opaque surfaces. * Other blend modes or opaque surfaces can be blitted directly. @@ -502,7 +471,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex SDL_SetSurfaceAlphaMod(src_rotated, alphaMod); SDL_SetSurfaceColorMod(src_rotated, rMod, gMod, bMod); } - retval = SDL_BlitSurface(src_rotated, NULL, surface, &tmp_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(src_rotated, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode); } else { /* The NONE blend mode requires three steps to get the pixels onto the destination surface. * First, the area where the rotated pixels will be blitted to get set to zero. @@ -511,7 +481,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex */ SDL_Rect mask_rect = tmp_rect; SDL_SetSurfaceBlendMode(mask_rotated, SDL_BLENDMODE_NONE); - retval = SDL_BlitSurface(mask_rotated, NULL, surface, &mask_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(mask_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode); if (!retval) { /* The next step copies the alpha value. This is done with the BLEND blend mode and * by modulating the source colors with 0. Since the destination is all zeros, this @@ -519,7 +490,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex */ SDL_SetSurfaceColorMod(src_rotated, 0, 0, 0); mask_rect = tmp_rect; - retval = SDL_BlitSurface(src_rotated, NULL, surface, &mask_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(src_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode); if (!retval) { /* The last step gets the color values in place. The ADD blend mode simply adds them to * the destination (where the color values are all zero). However, because the ADD blend @@ -535,7 +507,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex retval = -1; } else { SDL_SetSurfaceBlendMode(src_rotated_rgb, SDL_BLENDMODE_ADD); - retval = SDL_BlitSurface(src_rotated_rgb, NULL, surface, &tmp_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(src_rotated_rgb, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode); SDL_FreeSurface(src_rotated_rgb); } } @@ -560,6 +533,104 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex return retval; } + +typedef struct GeometryFillData +{ + SDL_Point dst; + SDL_Color color; +} GeometryFillData; + +typedef struct GeometryCopyData +{ + SDL_Point src; + SDL_Point dst; + SDL_Color color; +} GeometryCopyData; + +static int +SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + int i; + int count = indices ? num_indices : num_vertices; + void *verts; + int sz = texture ? sizeof (GeometryCopyData) : sizeof (GeometryFillData); + + verts = (void *) SDL_AllocateRenderVertices(renderer, count * sz, 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + if (texture) { + GeometryCopyData *ptr = (GeometryCopyData *) verts; + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + float *uv_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); + + uv_ = (float *)((char*)uv + j * uv_stride); + + ptr->src.x = (int)(uv_[0] * texture->w); + ptr->src.y = (int)(uv_[1] * texture->h); + + ptr->dst.x = (int)(xy_[0] * scale_x); + ptr->dst.y = (int)(xy_[1] * scale_y); + trianglepoint_2_fixedpoint(&ptr->dst); + + ptr->color = col_; + + ptr++; + } + } else { + GeometryFillData *ptr = (GeometryFillData *) verts; + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); + + ptr->dst.x = (int)(xy_[0] * scale_x); + ptr->dst.y = (int)(xy_[1] * scale_y); + trianglepoint_2_fixedpoint(&ptr->dst); + + ptr->color = col_; + + ptr++; + } + } + return 0; +} + static void PrepTextureForCopy(const SDL_RenderCommand *cmd) { @@ -634,7 +705,7 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic } case SDL_RENDERCMD_SETCLIPRECT: { - drawstate.cliprect = cmd->data.cliprect.enabled ? &cmd->data.cliprect.rect : NULL; + drawstate.cliprect = cmd->data.cliprect.enabled ? &cmd->data.cliprect.rect : NULL; drawstate.surface_cliprect_dirty = SDL_TRUE; break; } @@ -657,9 +728,19 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const int count = (int) cmd->data.draw.count; - const SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) + cmd->data.draw.first); + SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) + cmd->data.draw.first); const SDL_BlendMode blend = cmd->data.draw.blend; SetDrawState(surface, &drawstate); + + /* Apply viewport */ + if (drawstate.viewport->x || drawstate.viewport->y) { + int i; + for (i = 0; i < count; i++) { + verts[i].x += drawstate.viewport->x; + verts[i].y += drawstate.viewport->y; + } + } + if (blend == SDL_BLENDMODE_NONE) { SDL_DrawPoints(surface, verts, count, SDL_MapRGBA(surface->format, r, g, b, a)); } else { @@ -674,9 +755,19 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const int count = (int) cmd->data.draw.count; - const SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) + cmd->data.draw.first); + SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) + cmd->data.draw.first); const SDL_BlendMode blend = cmd->data.draw.blend; SetDrawState(surface, &drawstate); + + /* Apply viewport */ + if (drawstate.viewport->x || drawstate.viewport->y) { + int i; + for (i = 0; i < count; i++) { + verts[i].x += drawstate.viewport->x; + verts[i].y += drawstate.viewport->y; + } + } + if (blend == SDL_BLENDMODE_NONE) { SDL_DrawLines(surface, verts, count, SDL_MapRGBA(surface->format, r, g, b, a)); } else { @@ -691,9 +782,19 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const int count = (int) cmd->data.draw.count; - const SDL_Rect *verts = (SDL_Rect *) (((Uint8 *) vertices) + cmd->data.draw.first); + SDL_Rect *verts = (SDL_Rect *) (((Uint8 *) vertices) + cmd->data.draw.first); const SDL_BlendMode blend = cmd->data.draw.blend; SetDrawState(surface, &drawstate); + + /* Apply viewport */ + if (drawstate.viewport->x || drawstate.viewport->y) { + int i; + for (i = 0; i < count; i++) { + verts[i].x += drawstate.viewport->x; + verts[i].y += drawstate.viewport->y; + } + } + if (blend == SDL_BLENDMODE_NONE) { SDL_FillRects(surface, verts, count, SDL_MapRGBA(surface->format, r, g, b, a)); } else { @@ -713,6 +814,12 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic PrepTextureForCopy(cmd); + /* Apply viewport */ + if (drawstate.viewport->x || drawstate.viewport->y) { + dstrect->x += drawstate.viewport->x; + dstrect->y += drawstate.viewport->y; + } + if ( srcrect->w == dstrect->w && srcrect->h == dstrect->h ) { SDL_BlitSurface(src, srcrect, surface, dstrect); } else { @@ -720,17 +827,118 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic * to avoid potentially frequent RLE encoding/decoding. */ SDL_SetSurfaceRLE(surface, 0); - SDL_BlitScaled(src, srcrect, surface, dstrect); + + /* Prevent to do scaling + clipping on viewport boundaries as it may lose proportion */ + if (dstrect->x < 0 || dstrect->y < 0 || dstrect->x + dstrect->w > surface->w || dstrect->y + dstrect->h > surface->h) { + SDL_Surface *tmp = SDL_CreateRGBSurfaceWithFormat(0, dstrect->w, dstrect->h, 0, src->format->format); + /* Scale to an intermediate surface, then blit */ + if (tmp) { + SDL_Rect r; + SDL_BlendMode blendmode; + Uint8 alphaMod, rMod, gMod, bMod; + + SDL_GetSurfaceBlendMode(src, &blendmode); + SDL_GetSurfaceAlphaMod(src, &alphaMod); + SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod); + + r.x = 0; + r.y = 0; + r.w = dstrect->w; + r.h = dstrect->h; + + SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_NONE); + SDL_SetSurfaceColorMod(src, 255, 255, 255); + SDL_SetSurfaceAlphaMod(src, 255); + + SDL_PrivateUpperBlitScaled(src, srcrect, tmp, &r, texture->scaleMode); + + SDL_SetSurfaceColorMod(tmp, rMod, gMod, bMod); + SDL_SetSurfaceAlphaMod(tmp, alphaMod); + SDL_SetSurfaceBlendMode(tmp, blendmode); + + SDL_BlitSurface(tmp, NULL, surface, dstrect); + SDL_FreeSurface(tmp); + /* No need to set back r/g/b/a/blendmode to 'src' since it's done in PrepTextureForCopy() */ + } + } else{ + SDL_PrivateUpperBlitScaled(src, srcrect, surface, dstrect, texture->scaleMode); + } } break; } case SDL_RENDERCMD_COPY_EX: { - const CopyExData *copydata = (CopyExData *) (((Uint8 *) vertices) + cmd->data.draw.first); + CopyExData *copydata = (CopyExData *) (((Uint8 *) vertices) + cmd->data.draw.first); SetDrawState(surface, &drawstate); PrepTextureForCopy(cmd); + + /* Apply viewport */ + if (drawstate.viewport->x || drawstate.viewport->y) { + copydata->dstrect.x += drawstate.viewport->x; + copydata->dstrect.y += drawstate.viewport->y; + } + SW_RenderCopyEx(renderer, surface, cmd->data.draw.texture, ©data->srcrect, - ©data->dstrect, copydata->angle, ©data->center, copydata->flip); + ©data->dstrect, copydata->angle, ©data->center, copydata->flip, + copydata->scale_x, copydata->scale_y); + break; + } + + case SDL_RENDERCMD_GEOMETRY: { + int i; + SDL_Rect *verts = (SDL_Rect *) (((Uint8 *) vertices) + cmd->data.draw.first); + const int count = (int) cmd->data.draw.count; + SDL_Texture *texture = cmd->data.draw.texture; + const SDL_BlendMode blend = cmd->data.draw.blend; + + SetDrawState(surface, &drawstate); + + if (texture) { + SDL_Surface *src = (SDL_Surface *) texture->driverdata; + + GeometryCopyData *ptr = (GeometryCopyData *) verts; + + PrepTextureForCopy(cmd); + + /* Apply viewport */ + if (drawstate.viewport->x || drawstate.viewport->y) { + SDL_Point vp; + vp.x = drawstate.viewport->x; + vp.y = drawstate.viewport->y; + trianglepoint_2_fixedpoint(&vp); + for (i = 0; i < count; i++) { + ptr[i].dst.x += vp.x; + ptr[i].dst.y += vp.y; + } + } + + for (i = 0; i < count; i += 3, ptr += 3) { + SDL_SW_BlitTriangle( + src, + &(ptr[0].src), &(ptr[1].src), &(ptr[2].src), + surface, + &(ptr[0].dst), &(ptr[1].dst), &(ptr[2].dst), + ptr[0].color, ptr[1].color, ptr[2].color); + } + } else { + GeometryFillData *ptr = (GeometryFillData *) verts; + + /* Apply viewport */ + if (drawstate.viewport->x || drawstate.viewport->y) { + SDL_Point vp; + vp.x = drawstate.viewport->x; + vp.y = drawstate.viewport->y; + trianglepoint_2_fixedpoint(&vp); + for (i = 0; i < count; i++) { + ptr[i].dst.x += vp.x; + ptr[i].dst.y += vp.y; + } + } + + for (i = 0; i < count; i += 3, ptr += 3) { + SDL_SW_FillTriangle(surface, &(ptr[0].dst), &(ptr[1].dst), &(ptr[2].dst), blend, ptr[0].color, ptr[1].color, ptr[2].color); + } + } break; } @@ -809,7 +1017,7 @@ SW_CreateRendererForSurface(SDL_Surface * surface) SW_RenderData *data; if (!surface) { - SDL_SetError("Can't create renderer for NULL surface"); + SDL_InvalidParamError("surface"); return NULL; } @@ -843,6 +1051,7 @@ SW_CreateRendererForSurface(SDL_Surface * surface) renderer->QueueFillRects = SW_QueueFillRects; renderer->QueueCopy = SW_QueueCopy; renderer->QueueCopyEx = SW_QueueCopyEx; + renderer->QueueGeometry = SW_QueueGeometry; renderer->RunCommandQueue = SW_RunCommandQueue; renderer->RenderReadPixels = SW_RenderReadPixels; renderer->RenderPresent = SW_RenderPresent; @@ -859,9 +1068,29 @@ SW_CreateRendererForSurface(SDL_Surface * surface) static SDL_Renderer * SW_CreateRenderer(SDL_Window * window, Uint32 flags) { + const char *hint; SDL_Surface *surface; + SDL_bool no_hint_set; + + /* Set the vsync hint based on our flags, if it's not already set */ + hint = SDL_GetHint(SDL_HINT_RENDER_VSYNC); + if (!hint || !*hint) { + no_hint_set = SDL_TRUE; + } else { + no_hint_set = SDL_FALSE; + } + + if (no_hint_set) { + SDL_SetHint(SDL_HINT_RENDER_VSYNC, (flags & SDL_RENDERER_PRESENTVSYNC) ? "1" : "0"); + } surface = SDL_GetWindowSurface(window); + + /* Reset the vsync hint if we set it above */ + if (no_hint_set) { + SDL_SetHint(SDL_HINT_RENDER_VSYNC, ""); + } + if (!surface) { return NULL; } @@ -872,7 +1101,7 @@ SDL_RenderDriver SW_RenderDriver = { SW_CreateRenderer, { "software", - SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE, + SDL_RENDERER_SOFTWARE | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE, 8, { SDL_PIXELFORMAT_ARGB8888, diff --git a/Engine/lib/sdl/src/render/software/SDL_render_sw_c.h b/Engine/lib/sdl/src/render/software/SDL_render_sw_c.h index fa6289b23..4962ea6c0 100644 --- a/Engine/lib/sdl/src/render/software/SDL_render_sw_c.h +++ b/Engine/lib/sdl/src/render/software/SDL_render_sw_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/render/software/SDL_rotate.c b/Engine/lib/sdl/src/render/software/SDL_rotate.c index a903d1db2..6a9efac9c 100644 --- a/Engine/lib/sdl/src/render/software/SDL_rotate.c +++ b/Engine/lib/sdl/src/render/software/SDL_rotate.c @@ -82,7 +82,7 @@ to a situation where the program can segfault. \brief Returns colorkey info for a surface */ static Uint32 -_colorkey(SDL_Surface *src) +get_colorkey(SDL_Surface *src) { Uint32 key = 0; if (SDL_HasColorKey(src)) { @@ -91,6 +91,18 @@ _colorkey(SDL_Surface *src) return key; } +/* rotate (sx, sy) by (angle, center) into (dx, dy) */ +static void +rotate(double sx, double sy, double sinangle, double cosangle, const SDL_FPoint *center, double *dx, double *dy) { + sx -= center->x; + sy -= center->y; + + *dx = cosangle * sx - sinangle * sy; + *dy = sinangle * sx + cosangle * sy; + + *dx += center->x; + *dy += center->y; +} /* ! \brief Internal target surface sizing function for rotations with trig result return. @@ -105,49 +117,61 @@ _colorkey(SDL_Surface *src) */ void -SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, - int *dstwidth, int *dstheight, - double *cangle, double *sangle) +SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center, + SDL_Rect *rect_dest, double *cangle, double *sangle) { - /* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */ - int angle90 = (int)(angle/90); - if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */ - angle90 %= 4; - if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ - if(angle90 & 1) { - *dstwidth = height; - *dstheight = width; - *cangle = 0; - *sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */ - } else { - *dstwidth = width; - *dstheight = height; - *cangle = angle90 == 0 ? 1 : -1; - *sangle = 0; - } - } else { - double x, y, cx, cy, sx, sy; - double radangle; - int dstwidthhalf, dstheighthalf; - /* - * Determine destination width and height by rotating a centered source box - */ - radangle = angle * (M_PI / -180.0); /* reverse the angle because our rotations are clockwise */ - *sangle = SDL_sin(radangle); - *cangle = SDL_cos(radangle); - x = (double)(width / 2); - y = (double)(height / 2); - cx = *cangle * x; - cy = *cangle * y; - sx = *sangle * x; - sy = *sangle * y; + int minx, maxx, miny, maxy; + double radangle; + double x0, x1, x2, x3; + double y0, y1, y2, y3; + double sinangle; + double cosangle; - dstwidthhalf = MAX((int) - SDL_ceil(MAX(MAX(MAX(SDL_fabs(cx + sy), SDL_fabs(cx - sy)), SDL_fabs(-cx + sy)), SDL_fabs(-cx - sy))), 1); - dstheighthalf = MAX((int) - SDL_ceil(MAX(MAX(MAX(SDL_fabs(sx + cy), SDL_fabs(sx - cy)), SDL_fabs(-sx + cy)), SDL_fabs(-sx - cy))), 1); - *dstwidth = 2 * dstwidthhalf; - *dstheight = 2 * dstheighthalf; + radangle = angle * (M_PI / 180.0); + sinangle = SDL_sin(radangle); + cosangle = SDL_cos(radangle); + + /* + * Determine destination width and height by rotating a source box, at pixel center + */ + rotate(0.5, 0.5, sinangle, cosangle, center, &x0, &y0); + rotate(width - 0.5, 0.5, sinangle, cosangle, center, &x1, &y1); + rotate(0.5, height - 0.5, sinangle, cosangle, center, &x2, &y2); + rotate(width - 0.5, height - 0.5, sinangle, cosangle, center, &x3, &y3); + + minx = (int)SDL_floor( SDL_min( SDL_min(x0, x1), SDL_min(x2, x3) ) ); + maxx = (int)SDL_ceil( SDL_max( SDL_max(x0, x1), SDL_max(x2, x3) ) ); + + miny = (int)SDL_floor( SDL_min( SDL_min(y0, y1), SDL_min(y2, y3) ) ); + maxy = (int)SDL_ceil( SDL_max( SDL_max(y0, y1), SDL_max(y2, y3) ) ); + + rect_dest->w = maxx - minx; + rect_dest->h = maxy - miny; + rect_dest->x = minx; + rect_dest->y = miny; + + /* reverse the angle because our rotations are clockwise */ + *sangle = -sinangle; + *cangle = cosangle; + + { + /* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */ + int angle90 = (int)(angle/90); + if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */ + angle90 %= 4; + if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ + if(angle90 & 1) { + rect_dest->w = height; + rect_dest->h = width; + *cangle = 0; + *sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */ + } else { + rect_dest->w = width; + rect_dest->h = height; + *cangle = angle90 == 0 ? 1 : -1; + *sangle = 0; + } + } } } @@ -184,7 +208,7 @@ computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int if (signy < 0) sp += (src->h-1)*src->pitch; \ \ for (dy = 0; dy < dst->h; sp += sincy, dp += dincy, dy++) { \ - if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use memcpy */ \ + if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use SDL_memcpy */ \ SDL_memcpy(dp, sp, dst->w*sizeof(pixelType)); \ sp += dst->w*sizeof(pixelType); \ dp += dst->w*sizeof(pixelType); \ @@ -220,48 +244,56 @@ Assumes dst surface was allocated with the correct dimensions. \param src Source surface. \param dst Destination surface. -\param cx Horizontal center coordinate. -\param cy Vertical center coordinate. \param isin Integer version of sine of angle. \param icos Integer version of cosine of angle. \param flipx Flag indicating horizontal mirroring should be applied. \param flipy Flag indicating vertical mirroring should be applied. \param smooth Flag indicating anti-aliasing should be used. +\param dst_rect destination coordinates +\param center true center. */ static void -_transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth) +transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int isin, int icos, + int flipx, int flipy, int smooth, + const SDL_Rect *rect_dest, + const SDL_FPoint *center) { - int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; + int sw, sh; + int cx, cy; tColorRGBA c00, c01, c10, c11, cswap; tColorRGBA *pc, *sp; int gap; + const int fp_half = (1<<15); /* * Variable setup */ - xd = ((src->w - dst->w) << 15); - yd = ((src->h - dst->h) << 15); - ax = (cx << 16) - (icos * cx); - ay = (cy << 16) - (isin * cx); sw = src->w - 1; sh = src->h - 1; pc = (tColorRGBA*) dst->pixels; gap = dst->pitch - dst->w * 4; + cx = (int)(center->x * 65536.0); + cy = (int)(center->y * 65536.0); /* * Switch between interpolating and non-interpolating code */ if (smooth) { + int y; for (y = 0; y < dst->h; y++) { - dy = cy - y; - sdx = (ax + (isin * dy)) + xd; - sdy = (ay - (icos * dy)) + yd; + int x; + double src_x = (rect_dest->x + 0 + 0.5 - center->x); + double src_y = (rect_dest->y + y + 0.5 - center->y); + int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half); + int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half); for (x = 0; x < dst->w; x++) { - dx = (sdx >> 16); - dy = (sdy >> 16); + int dx = (sdx >> 16); + int dy = (sdy >> 16); if (flipx) dx = sw - dx; if (flipy) dy = sh - dy; if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) { + int ex, ey; + int t1, t2; sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy) + dx; c00 = *sp; sp += 1; @@ -303,13 +335,16 @@ _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int pc = (tColorRGBA *) ((Uint8 *) pc + gap); } } else { + int y; for (y = 0; y < dst->h; y++) { - dy = cy - y; - sdx = (ax + (isin * dy)) + xd; - sdy = (ay - (icos * dy)) + yd; + int x; + double src_x = (rect_dest->x + 0 + 0.5 - center->x); + double src_y = (rect_dest->y + y + 0.5 - center->y); + int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half); + int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half); for (x = 0; x < dst->w; x++) { - dx = (sdx >> 16); - dy = (sdy >> 16); + int dx = (sdx >> 16); + int dy = (sdy >> 16); if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) { if(flipx) dx = sw - dx; if(flipy) dy = sh - dy; @@ -335,46 +370,54 @@ Assumes dst surface was allocated with the correct dimensions. \param src Source surface. \param dst Destination surface. -\param cx Horizontal center coordinate. -\param cy Vertical center coordinate. \param isin Integer version of sine of angle. \param icos Integer version of cosine of angle. \param flipx Flag indicating horizontal mirroring should be applied. \param flipy Flag indicating vertical mirroring should be applied. +\param dst_rect destination coordinates +\param center true center. */ static void -transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy) +transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int isin, int icos, int flipx, int flipy, + const SDL_Rect *rect_dest, + const SDL_FPoint *center) { - int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay; + int sw, sh; + int cx, cy; tColorY *pc; int gap; + const int fp_half = (1<<15); + int y; /* * Variable setup */ - xd = ((src->w - dst->w) << 15); - yd = ((src->h - dst->h) << 15); - ax = (cx << 16) - (icos * cx); - ay = (cy << 16) - (isin * cx); + sw = src->w - 1; + sh = src->h - 1; pc = (tColorY*) dst->pixels; gap = dst->pitch - dst->w; + cx = (int)(center->x * 65536.0); + cy = (int)(center->y * 65536.0); + /* * Clear surface to colorkey */ - SDL_memset(pc, (int)(_colorkey(src) & 0xff), dst->pitch * dst->h); + SDL_memset(pc, (int)(get_colorkey(src) & 0xff), dst->pitch * dst->h); /* * Iterate through destination surface */ for (y = 0; y < dst->h; y++) { - dy = cy - y; - sdx = (ax + (isin * dy)) + xd; - sdy = (ay - (icos * dy)) + yd; + int x; + double src_x = (rect_dest->x + 0 + 0.5 - center->x); + double src_y = (rect_dest->y + y + 0.5 - center->y); + int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half); + int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half); for (x = 0; x < dst->w; x++) { - dx = (sdx >> 16); - dy = (sdy >> 16); + int dx = (sdx >> 16); + int dy = (sdy >> 16); if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) { - if (flipx) dx = (src->w-1)-dx; - if (flipy) dy = (src->h-1)-dy; + if (flipx) dx = sw - dx; + if (flipy) dy = sh- dy; *pc = *((tColorY *)src->pixels + src->pitch * dy + dx); } sdx += icos; @@ -390,7 +433,7 @@ transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin \brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing. Rotates a 32-bit or 8-bit 'src' surface to newly created 'dst' surface. -'angle' is the rotation in degrees, 'centerx' and 'centery' the rotation center. If 'smooth' is set +'angle' is the rotation in degrees, 'center' the rotation center. If 'smooth' is set then the destination 32-bit surface is anti-aliased. 8-bit surfaces must have a colorkey. 32-bit surfaces must have a 8888 layout with red, green, blue and alpha masks (any ordering goes). The blend mode of the 'src' surface has some effects on generation of the 'dst' surface: The NONE @@ -400,21 +443,21 @@ When using the NONE and MOD modes, color and alpha modulation must be applied be \param src The surface to rotozoom. \param angle The angle to rotate in degrees. -\param centerx The horizontal coordinate of the center of rotation \param zoomy The vertical coordinate of the center of rotation \param smooth Antialiasing flag; set to SMOOTHING_ON to enable. \param flipx Set to 1 to flip the image horizontally \param flipy Set to 1 to flip the image vertically -\param dstwidth The destination surface width -\param dstheight The destination surface height +\param rect_dest The destination rect bounding box \param cangle The angle cosine \param sangle The angle sine +\param center The true coordinate of the center of rotation \return The new rotated surface. */ SDL_Surface * -SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle) +SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int flipy, + const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center) { SDL_Surface *rz_dst; int is8bit, angle90; @@ -433,13 +476,12 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, colorKeyAvailable = SDL_TRUE; } } - /* This function requires a 32-bit surface or 8-bit surface with a colorkey */ is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable; if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask))) return NULL; - /* Calculate target factors from sin/cos and zoom */ + /* Calculate target factors from sine/cosine and zoom */ sangleinv = sangle*65536.0; cangleinv = cangle*65536.0; @@ -447,16 +489,18 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, rz_dst = NULL; if (is8bit) { /* Target surface is 8 bit */ - rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0); + rz_dst = SDL_CreateRGBSurfaceWithFormat(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 8, src->format->format); if (rz_dst != NULL) { - for (i = 0; i < src->format->palette->ncolors; i++) { - rz_dst->format->palette->colors[i] = src->format->palette->colors[i]; + if (src->format->palette) { + for (i = 0; i < src->format->palette->ncolors; i++) { + rz_dst->format->palette->colors[i] = src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = src->format->palette->ncolors; } - rz_dst->format->palette->ncolors = src->format->palette->ncolors; } } else { /* Target surface is 32 bit with source RGBA ordering */ - rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 32, + rz_dst = SDL_CreateRGBSurface(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 32, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); } @@ -466,7 +510,7 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, return NULL; /* Adjust for guard rows */ - rz_dst->h = dstheight; + rz_dst->h = rect_dest->h; SDL_GetSurfaceBlendMode(src, &blendmode); @@ -497,7 +541,7 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, } /* check if the rotation is a multiple of 90 degrees so we can take a fast path and also somewhat reduce - * the off-by-one problem in _transformSurfaceRGBA that expresses itself when the rotation is near + * the off-by-one problem in transformSurfaceRGBA that expresses itself when the rotation is near * multiples of 90 degrees. */ angle90 = (int)(angle/90); @@ -513,16 +557,16 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, if(angle90 >= 0) { transformSurfaceY90(src, rz_dst, angle90, flipx, flipy); } else { - transformSurfaceY(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv, - flipx, flipy); + transformSurfaceY(src, rz_dst, (int)sangleinv, (int)cangleinv, + flipx, flipy, rect_dest, center); } } else { /* Call the 32-bit transformation routine to do the rotation */ if (angle90 >= 0) { transformSurfaceRGBA90(src, rz_dst, angle90, flipx, flipy); } else { - _transformSurfaceRGBA(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv, - flipx, flipy, smooth); + transformSurfaceRGBA(src, rz_dst, (int)sangleinv, (int)cangleinv, + flipx, flipy, smooth, rect_dest, center); } } diff --git a/Engine/lib/sdl/src/render/software/SDL_rotate.h b/Engine/lib/sdl/src/render/software/SDL_rotate.h index c1864d27a..171baa5dd 100644 --- a/Engine/lib/sdl/src/render/software/SDL_rotate.h +++ b/Engine/lib/sdl/src/render/software/SDL_rotate.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,9 @@ #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif -extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle); -extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle); +extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int flipy, + const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center); +extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center, + SDL_Rect *rect_dest, double *cangle, double *sangle); #endif /* SDL_rotate_h_ */ diff --git a/Engine/lib/sdl/src/render/software/SDL_triangle.c b/Engine/lib/sdl/src/render/software/SDL_triangle.c new file mode 100644 index 000000000..694cb4d91 --- /dev/null +++ b/Engine/lib/sdl/src/render/software/SDL_triangle.c @@ -0,0 +1,888 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED + +#include "SDL_surface.h" +#include "SDL_triangle.h" + +#include "../../video/SDL_blit.h" + +/* fixed points bits precision + * Set to 1, so that it can start rendering wth middle of a pixel precision. + * It doesn't need to be increased. + * But, if increased too much, it overflows (srcx, srcy) coordinates used for filling with texture. + * (which could be turned to int64). + */ +#define FP_BITS 1 + + +#define COLOR_EQ(c1, c2) ((c1).r == (c2).r && (c1).g == (c2).g && (c1).b == (c2).b && (c1).a == (c2).a) + +static void SDL_BlitTriangle_Slow(SDL_BlitInfo * info, + SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2, + int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x, + int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row, + SDL_Color c0, SDL_Color c1, SDL_Color c2, int is_uniform); + +#if 0 +int SDL_BlitTriangle(SDL_Surface *src, const SDL_Point srcpoints[3], SDL_Surface *dst, const SDL_Point dstpoints[3]) +{ + int i; + SDL_Point points[6]; + + if (src == NULL || dst == NULL) { + return -1; + } + + for (i = 0; i < 3; i++) { + if (srcpoints[i].x < 0 || srcpoints[i].y < 0 || srcpoints[i].x >= src->w || srcpoints[i].y >= src->h) { + return SDL_SetError("Values of 'srcpoints' out of bounds"); + } + } + + points[0] = srcpoints[0]; + points[1] = dstpoints[0]; + points[2] = srcpoints[1]; + points[3] = dstpoints[1]; + points[4] = srcpoints[2]; + points[5] = dstpoints[2]; + for (i = 0; i < 3; i++) { + trianglepoint_2_fixedpoint(&points[2 * i + 1]); + } + return SDL_SW_BlitTriangle(src, dst, points); +} + +int SDL_FillTriangle(SDL_Surface *dst, const SDL_Point points[3], Uint32 color) +{ + int i; + SDL_Point points_tmp[3]; + if (dst == NULL) { + return -1; + } + for (i = 0; i < 3; i++) { + points_tmp[i] = points[i]; + trianglepoint_2_fixedpoint(&points_tmp[i]); + } + return SDL_SW_FillTriangle(dst, points_tmp, SDL_BLENDMODE_NONE, color); +} +#endif + +/* cross product AB x AC */ +static int cross_product(const SDL_Point *a, const SDL_Point *b, int c_x, int c_y) +{ + return (b->x - a->x) * (c_y - a->y) - (b->y - a->y) * (c_x - a->x); +} + +/* check for top left rules */ +static int is_top_left(const SDL_Point *a, const SDL_Point *b, int is_clockwise) +{ + if (is_clockwise) { + if (a->y == b->y && a->x < b->x) { + return 1; + } + if (b->y < a->y) { + return 1; + } + } else { + if (a->y == b->y && b->x < a->x) { + return 1; + } + if (a->y < b->y) { + return 1; + } + } + return 0; +} + +void trianglepoint_2_fixedpoint(SDL_Point *a) { + a->x <<= FP_BITS; + a->y <<= FP_BITS; +} + +/* bounding rect of three points (in fixed point) */ +static void bounding_rect_fixedpoint(const SDL_Point *a, const SDL_Point *b, const SDL_Point *c, SDL_Rect *r) +{ + int min_x = SDL_min(a->x, SDL_min(b->x, c->x)); + int max_x = SDL_max(a->x, SDL_max(b->x, c->x)); + int min_y = SDL_min(a->y, SDL_min(b->y, c->y)); + int max_y = SDL_max(a->y, SDL_max(b->y, c->y)); + /* points are in fixed point, shift back */ + r->x = min_x >> FP_BITS; + r->y = min_y >> FP_BITS; + r->w = (max_x - min_x) >> FP_BITS; + r->h = (max_y - min_y) >> FP_BITS; +} + +/* bounding rect of three points */ +static void bounding_rect(const SDL_Point *a, const SDL_Point *b, const SDL_Point *c, SDL_Rect *r) +{ + int min_x = SDL_min(a->x, SDL_min(b->x, c->x)); + int max_x = SDL_max(a->x, SDL_max(b->x, c->x)); + int min_y = SDL_min(a->y, SDL_min(b->y, c->y)); + int max_y = SDL_max(a->y, SDL_max(b->y, c->y)); + r->x = min_x; + r->y = min_y; + r->w = (max_x - min_x); + r->h = (max_y - min_y); +} + + +/* Triangle rendering, using Barycentric coordinates (w0, w1, w2) + * + * The cross product isn't computed from scratch at each iteration, + * but optimized using constant step increments + * + */ + +#define TRIANGLE_BEGIN_LOOP \ + { \ + int x, y; \ + for (y = 0; y < dstrect.h; y++) { \ + /* y start */ \ + int w0 = w0_row; \ + int w1 = w1_row; \ + int w2 = w2_row; \ + for (x = 0; x < dstrect.w; x++) { \ + /* In triangle */ \ + if (w0 + bias_w0 >= 0 && w1 + bias_w1 >= 0 && w2 + bias_w2 >= 0) { \ + Uint8 *dptr = (Uint8 *) dst_ptr + x * dstbpp; \ + + +/* Use 64 bits precision to prevent overflow when interpolating color / texture with wide triangles */ +#define TRIANGLE_GET_TEXTCOORD \ + int srcx = (int)(((Sint64)w0 * s2s0_x + (Sint64)w1 * s2s1_x + s2_x_area.x) / area); \ + int srcy = (int)(((Sint64)w0 * s2s0_y + (Sint64)w1 * s2s1_y + s2_x_area.y) / area); \ + +#define TRIANGLE_GET_MAPPED_COLOR \ + int r = (int)(((Sint64)w0 * c0.r + (Sint64)w1 * c1.r + (Sint64)w2 * c2.r) / area); \ + int g = (int)(((Sint64)w0 * c0.g + (Sint64)w1 * c1.g + (Sint64)w2 * c2.g) / area); \ + int b = (int)(((Sint64)w0 * c0.b + (Sint64)w1 * c1.b + (Sint64)w2 * c2.b) / area); \ + int a = (int)(((Sint64)w0 * c0.a + (Sint64)w1 * c1.a + (Sint64)w2 * c2.a) / area); \ + int color = SDL_MapRGBA(format, r, g, b, a); \ + +#define TRIANGLE_GET_COLOR \ + int r = (int)(((Sint64)w0 * c0.r + (Sint64)w1 * c1.r + (Sint64)w2 * c2.r) / area); \ + int g = (int)(((Sint64)w0 * c0.g + (Sint64)w1 * c1.g + (Sint64)w2 * c2.g) / area); \ + int b = (int)(((Sint64)w0 * c0.b + (Sint64)w1 * c1.b + (Sint64)w2 * c2.b) / area); \ + int a = (int)(((Sint64)w0 * c0.a + (Sint64)w1 * c1.a + (Sint64)w2 * c2.a) / area); \ + + +#define TRIANGLE_END_LOOP \ + } \ + /* x += 1 */ \ + w0 += d2d1_y; \ + w1 += d0d2_y; \ + w2 += d1d0_y; \ + } \ + /* y += 1 */ \ + w0_row += d1d2_x; \ + w1_row += d2d0_x; \ + w2_row += d0d1_x; \ + dst_ptr += dst_pitch; \ + } \ + } \ + +int SDL_SW_FillTriangle(SDL_Surface *dst, SDL_Point *d0, SDL_Point *d1, SDL_Point *d2, SDL_BlendMode blend, SDL_Color c0, SDL_Color c1, SDL_Color c2) +{ + int ret = 0; + int dst_locked = 0; + + SDL_Rect dstrect; + + int dstbpp; + Uint8 *dst_ptr; + int dst_pitch; + + int area, is_clockwise; + + int d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x; + int w0_row, w1_row, w2_row; + int bias_w0, bias_w1, bias_w2; + + int is_uniform; + + SDL_Surface *tmp = NULL; + + if (dst == NULL) { + return -1; + } + + area = cross_product(d0, d1, d2->x, d2->y); + + is_uniform = COLOR_EQ(c0, c1) && COLOR_EQ(c1, c2); + + /* Flat triangle */ + if (area == 0) { + return 0; + } + + /* Lock the destination, if needed */ + if (SDL_MUSTLOCK(dst)) { + if (SDL_LockSurface(dst) < 0) { + ret = -1; + goto end; + } else { + dst_locked = 1; + } + } + + bounding_rect_fixedpoint(d0, d1, d2, &dstrect); + + { + /* Clip triangle rect with surface rect */ + SDL_Rect rect; + rect.x = 0; + rect.y = 0; + rect.w = dst->w; + rect.h = dst->h; + SDL_IntersectRect(&dstrect, &rect, &dstrect); + } + + { + /* Clip triangle with surface clip rect */ + SDL_Rect rect; + SDL_GetClipRect(dst, &rect); + SDL_IntersectRect(&dstrect, &rect, &dstrect); + } + + + if (blend != SDL_BLENDMODE_NONE) { + int format = dst->format->format; + + /* need an alpha format */ + if (! dst->format->Amask) { + format = SDL_PIXELFORMAT_ARGB8888; + } + + /* Use an intermediate surface */ + tmp = SDL_CreateRGBSurfaceWithFormat(0, dstrect.w, dstrect.h, 0, format); + if (tmp == NULL) { + ret = -1; + goto end; + } + + if (blend == SDL_BLENDMODE_MOD) { + Uint32 c = SDL_MapRGBA(tmp->format, 255, 255, 255, 255); + SDL_FillRect(tmp, NULL, c); + } + + SDL_SetSurfaceBlendMode(tmp, blend); + + dstbpp = tmp->format->BytesPerPixel; + dst_ptr = tmp->pixels; + dst_pitch = tmp->pitch; + + } else { + /* Write directly to destination surface */ + dstbpp = dst->format->BytesPerPixel; + dst_ptr = (Uint8 *)dst->pixels + dstrect.x * dstbpp + dstrect.y * dst->pitch; + dst_pitch = dst->pitch; + } + + is_clockwise = area > 0; + area = SDL_abs(area); + + d2d1_y = (d1->y - d2->y) << FP_BITS; + d0d2_y = (d2->y - d0->y) << FP_BITS; + d1d0_y = (d0->y - d1->y) << FP_BITS; + d1d2_x = (d2->x - d1->x) << FP_BITS; + d2d0_x = (d0->x - d2->x) << FP_BITS; + d0d1_x = (d1->x - d0->x) << FP_BITS; + + /* Starting point for rendering, at the middle of a pixel */ + { + SDL_Point p; + p.x = dstrect.x; + p.y = dstrect.y; + trianglepoint_2_fixedpoint(&p); + p.x += (1 << FP_BITS) / 2; + p.y += (1 << FP_BITS) / 2; + w0_row = cross_product(d1, d2, p.x, p.y); + w1_row = cross_product(d2, d0, p.x, p.y); + w2_row = cross_product(d0, d1, p.x, p.y); + } + + /* Handle anti-clockwise triangles */ + if (! is_clockwise) { + d2d1_y *= -1; + d0d2_y *= -1; + d1d0_y *= -1; + d1d2_x *= -1; + d2d0_x *= -1; + d0d1_x *= -1; + w0_row *= -1; + w1_row *= -1; + w2_row *= -1; + } + + /* Add a bias to respect top-left rasterization rule */ + bias_w0 = (is_top_left(d1, d2, is_clockwise) ? 0 : -1); + bias_w1 = (is_top_left(d2, d0, is_clockwise) ? 0 : -1); + bias_w2 = (is_top_left(d0, d1, is_clockwise) ? 0 : -1); + + if (is_uniform) { + Uint32 color; + if (tmp) { + if (dst->format->Amask) { + color = SDL_MapRGBA(tmp->format, c0.r, c0.g, c0.b, c0.a); + } else { + //color = SDL_MapRGB(tmp->format, c0.r, c0.g, c0.b); + color = SDL_MapRGBA(tmp->format, c0.r, c0.g, c0.b, c0.a); + } + } else { + color = SDL_MapRGBA(dst->format, c0.r, c0.g, c0.b, c0.a); + } + + if (dstbpp == 4) { + TRIANGLE_BEGIN_LOOP + { + *(Uint32 *)dptr = color; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 3) { + TRIANGLE_BEGIN_LOOP + { + Uint8 *s = (Uint8*)&color; + dptr[0] = s[0]; + dptr[1] = s[1]; + dptr[2] = s[2]; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 2) { + TRIANGLE_BEGIN_LOOP + { + *(Uint16 *)dptr = color; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 1) { + TRIANGLE_BEGIN_LOOP + { + *dptr = color; + } + TRIANGLE_END_LOOP + } + } else { + SDL_PixelFormat *format = dst->format; + if (tmp) { + format = tmp->format; + } + if (dstbpp == 4) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_MAPPED_COLOR + *(Uint32 *)dptr = color; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 3) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_MAPPED_COLOR + Uint8 *s = (Uint8*)&color; + dptr[0] = s[0]; + dptr[1] = s[1]; + dptr[2] = s[2]; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 2) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_MAPPED_COLOR + *(Uint16 *)dptr = color; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 1) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_MAPPED_COLOR + *dptr = color; + } + TRIANGLE_END_LOOP + } + } + + if (tmp) { + SDL_BlitSurface(tmp, NULL, dst, &dstrect); + SDL_FreeSurface(tmp); + } + +end: + if (dst_locked) { + SDL_UnlockSurface(dst); + } + + return ret; +} + + + + + + + +int SDL_SW_BlitTriangle( + SDL_Surface *src, + SDL_Point *s0, SDL_Point *s1, SDL_Point *s2, + SDL_Surface *dst, + SDL_Point *d0, SDL_Point *d1, SDL_Point *d2, + SDL_Color c0, SDL_Color c1, SDL_Color c2) +{ + int ret = 0; + int src_locked = 0; + int dst_locked = 0; + + SDL_BlendMode blend; + + SDL_Rect dstrect; + + SDL_Point s2_x_area; + + int dstbpp; + Uint8 *dst_ptr; + int dst_pitch; + + int *src_ptr; + int src_pitch; + + int area, is_clockwise; + + int d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x; + int s2s0_x, s2s1_x, s2s0_y, s2s1_y; + + int w0_row, w1_row, w2_row; + int bias_w0, bias_w1, bias_w2; + + int is_uniform; + + int has_modulation; + + if (src == NULL || dst == NULL) { + return -1; + } + + area = cross_product(d0, d1, d2->x, d2->y); + + /* Flat triangle */ + if (area == 0) { + return 0; + } + + /* Lock the destination, if needed */ + if (SDL_MUSTLOCK(dst)) { + if (SDL_LockSurface(dst) < 0) { + ret = -1; + goto end; + } else { + dst_locked = 1; + } + } + + /* Lock the source, if needed */ + if (SDL_MUSTLOCK(src)) { + if (SDL_LockSurface(src) < 0) { + ret = -1; + goto end; + } else { + src_locked = 1; + } + } + + is_uniform = COLOR_EQ(c0, c1) && COLOR_EQ(c1, c2); + + bounding_rect_fixedpoint(d0, d1, d2, &dstrect); + + SDL_GetSurfaceBlendMode(src, &blend); + + /* TRIANGLE_GET_TEXTCOORD interpolates up to the max values included, so reduce by 1 */ + { + SDL_Rect srcrect; + int maxx, maxy; + bounding_rect(s0, s1, s2, &srcrect); + maxx = srcrect.x + srcrect.w; + maxy = srcrect.y + srcrect.h; + if (srcrect.w > 0) { + if (s0->x == maxx) s0->x--; + if (s1->x == maxx) s1->x--; + if (s2->x == maxx) s2->x--; + } + if (srcrect.h > 0) { + if (s0->y == maxy) s0->y--; + if (s1->y == maxy) s1->y--; + if (s2->y == maxy) s2->y--; + } + } + + if (is_uniform) { + // SDL_GetSurfaceColorMod(src, &r, &g, &b); + has_modulation = c0.r != 255 || c0.g != 255 || c0.b != 255 || c0.a != 255;; + } else { + has_modulation = SDL_TRUE; + } + + { + /* Clip triangle rect with surface rect */ + SDL_Rect rect; + rect.x = 0; + rect.y = 0; + rect.w = dst->w; + rect.h = dst->h; + + SDL_IntersectRect(&dstrect, &rect, &dstrect); + } + + { + /* Clip triangle with surface clip rect */ + SDL_Rect rect; + SDL_GetClipRect(dst, &rect); + SDL_IntersectRect(&dstrect, &rect, &dstrect); + } + + /* Set destination pointer */ + dstbpp = dst->format->BytesPerPixel; + dst_ptr = (Uint8 *)dst->pixels + dstrect.x * dstbpp + dstrect.y * dst->pitch; + dst_pitch = dst->pitch; + + /* Set source pointer */ + src_ptr = src->pixels; + src_pitch = src->pitch; + + is_clockwise = area > 0; + area = SDL_abs(area); + + d2d1_y = (d1->y - d2->y) << FP_BITS; + d0d2_y = (d2->y - d0->y) << FP_BITS; + d1d0_y = (d0->y - d1->y) << FP_BITS; + + + d1d2_x = (d2->x - d1->x) << FP_BITS; + d2d0_x = (d0->x - d2->x) << FP_BITS; + d0d1_x = (d1->x - d0->x) << FP_BITS; + + s2s0_x = s0->x - s2->x; + s2s1_x = s1->x - s2->x; + s2s0_y = s0->y - s2->y; + s2s1_y = s1->y - s2->y; + + /* Starting point for rendering, at the middle of a pixel */ + { + SDL_Point p; + p.x = dstrect.x; + p.y = dstrect.y; + trianglepoint_2_fixedpoint(&p); + p.x += (1 << FP_BITS) / 2; + p.y += (1 << FP_BITS) / 2; + w0_row = cross_product(d1, d2, p.x, p.y); + w1_row = cross_product(d2, d0, p.x, p.y); + w2_row = cross_product(d0, d1, p.x, p.y); + } + + /* Handle anti-clockwise triangles */ + if (! is_clockwise) { + d2d1_y *= -1; + d0d2_y *= -1; + d1d0_y *= -1; + d1d2_x *= -1; + d2d0_x *= -1; + d0d1_x *= -1; + w0_row *= -1; + w1_row *= -1; + w2_row *= -1; + } + + /* Add a bias to respect top-left rasterization rule */ + bias_w0 = (is_top_left(d1, d2, is_clockwise) ? 0 : -1); + bias_w1 = (is_top_left(d2, d0, is_clockwise) ? 0 : -1); + bias_w2 = (is_top_left(d0, d1, is_clockwise) ? 0 : -1); + + /* precompute constant 's2->x * area' used in TRIANGLE_GET_TEXTCOORD */ + s2_x_area.x = s2->x * area; + s2_x_area.y = s2->y * area; + + if (blend != SDL_BLENDMODE_NONE || src->format->format != dst->format->format || has_modulation || ! is_uniform) { + /* Use SDL_BlitTriangle_Slow */ + + SDL_BlitInfo *info = &src->map->info; + SDL_BlitInfo tmp_info; + + SDL_zero(tmp_info); + + tmp_info.src_fmt = src->format; + tmp_info.dst_fmt = dst->format; + tmp_info.flags = info->flags; + /* + tmp_info.r = info->r; + tmp_info.g = info->g; + tmp_info.b = info->b; + tmp_info.a = info->a; + */ + tmp_info.r = c0.r; + tmp_info.g = c0.g; + tmp_info.b = c0.b; + tmp_info.a = c0.a; + + + tmp_info.flags &= ~(SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA); + + if (c0.r != 255 || c1.r != 255 || c2.r != 255 || + c0.g != 255 || c1.g != 255 || c2.g != 255 || + c0.b != 255 || c1.b != 255 || c2.b != 255) { + tmp_info.flags |= SDL_COPY_MODULATE_COLOR; + } + + if (c0.a != 255 || c1.a != 255 || c2.a != 255) { + tmp_info.flags |= SDL_COPY_MODULATE_ALPHA; + } + + tmp_info.colorkey = info->colorkey; + + /* src */ + tmp_info.src = (Uint8 *) src_ptr; + tmp_info.src_pitch = src_pitch; + + /* dst */ + tmp_info.dst = (Uint8 *) dst_ptr; + tmp_info.dst_pitch = dst_pitch; + + SDL_BlitTriangle_Slow(&tmp_info, s2_x_area, dstrect, area, bias_w0, bias_w1, bias_w2, + d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x, + s2s0_x, s2s1_x, s2s0_y, s2s1_y, w0_row, w1_row, w2_row, + c0, c1, c2, is_uniform); + + goto end; + } + + if (dstbpp == 4) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_TEXTCOORD + Uint32 *sptr = (Uint32 *)((Uint8 *) src_ptr + srcy * src_pitch); + *(Uint32 *)dptr = sptr[srcx]; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 3) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_TEXTCOORD + Uint8 *sptr = (Uint8 *)((Uint8 *) src_ptr + srcy * src_pitch); + dptr[0] = sptr[3 * srcx]; + dptr[1] = sptr[3 * srcx + 1]; + dptr[2] = sptr[3 * srcx + 2]; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 2) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_TEXTCOORD + Uint16 *sptr = (Uint16 *)((Uint8 *) src_ptr + srcy * src_pitch); + *(Uint16 *)dptr = sptr[srcx]; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 1) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_TEXTCOORD + Uint8 *sptr = (Uint8 *)((Uint8 *) src_ptr + srcy * src_pitch); + *dptr = sptr[srcx]; + } + TRIANGLE_END_LOOP + } + +end: + if (dst_locked) { + SDL_UnlockSurface(dst); + } + if (src_locked) { + SDL_UnlockSurface(src); + } + + return ret; +} + + +#define FORMAT_ALPHA 0 +#define FORMAT_NO_ALPHA -1 +#define FORMAT_2101010 1 +#define FORMAT_HAS_ALPHA(format) format == 0 +#define FORMAT_HAS_NO_ALPHA(format) format < 0 +static int SDL_INLINE detect_format(SDL_PixelFormat *pf) { + if (pf->format == SDL_PIXELFORMAT_ARGB2101010) { + return FORMAT_2101010; + } else if (pf->Amask) { + return FORMAT_ALPHA; + } else { + return FORMAT_NO_ALPHA; + } +} + +static void +SDL_BlitTriangle_Slow(SDL_BlitInfo *info, + SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2, + int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x, + int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row, + SDL_Color c0, SDL_Color c1, SDL_Color c2, int is_uniform) +{ + const int flags = info->flags; + Uint32 modulateR = info->r; + Uint32 modulateG = info->g; + Uint32 modulateB = info->b; + Uint32 modulateA = info->a; + Uint32 srcpixel; + Uint32 srcR, srcG, srcB, srcA; + Uint32 dstpixel; + Uint32 dstR, dstG, dstB, dstA; + SDL_PixelFormat *src_fmt = info->src_fmt; + SDL_PixelFormat *dst_fmt = info->dst_fmt; + int srcbpp = src_fmt->BytesPerPixel; + int dstbpp = dst_fmt->BytesPerPixel; + int srcfmt_val; + int dstfmt_val; + Uint32 rgbmask = ~src_fmt->Amask; + Uint32 ckey = info->colorkey & rgbmask; + + Uint8 *dst_ptr = info->dst; + int dst_pitch = info->dst_pitch;; + + srcfmt_val = detect_format(src_fmt); + dstfmt_val = detect_format(dst_fmt); + + TRIANGLE_BEGIN_LOOP + { + Uint8 *src; + Uint8 *dst = dptr; + TRIANGLE_GET_TEXTCOORD + src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp)); + if (FORMAT_HAS_ALPHA(srcfmt_val)) { + DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB, srcA); + } else if (FORMAT_HAS_NO_ALPHA(srcfmt_val)) { + DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB); + srcA = 0xFF; + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + srcpixel = *((Uint32 *)(src)); + RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA); + } + if (flags & SDL_COPY_COLORKEY) { + /* srcpixel isn't set for 24 bpp */ + if (srcbpp == 3) { + srcpixel = (srcR << src_fmt->Rshift) | + (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift); + } + if ((srcpixel & rgbmask) == ckey) { + continue; + } + } + if (FORMAT_HAS_ALPHA(dstfmt_val)) { + DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA); + } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) { + DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB); + dstA = 0xFF; + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + dstpixel = *((Uint32 *)(dst)); + RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA); + } + + if (! is_uniform) { + TRIANGLE_GET_COLOR + modulateR = r; + modulateG = g; + modulateB = b; + modulateA = a; + } + + if (flags & SDL_COPY_MODULATE_COLOR) { + srcR = (srcR * modulateR) / 255; + srcG = (srcG * modulateG) / 255; + srcB = (srcB * modulateB) / 255; + } + if (flags & SDL_COPY_MODULATE_ALPHA) { + srcA = (srcA * modulateA) / 255; + } + if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) { + /* This goes away if we ever use premultiplied alpha */ + if (srcA < 255) { + srcR = (srcR * srcA) / 255; + srcG = (srcG * srcA) / 255; + srcB = (srcB * srcA) / 255; + } + } + switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL)) { + case 0: + dstR = srcR; + dstG = srcG; + dstB = srcB; + dstA = srcA; + break; + case SDL_COPY_BLEND: + dstR = srcR + ((255 - srcA) * dstR) / 255; + dstG = srcG + ((255 - srcA) * dstG) / 255; + dstB = srcB + ((255 - srcA) * dstB) / 255; + dstA = srcA + ((255 - srcA) * dstA) / 255; + break; + case SDL_COPY_ADD: + dstR = srcR + dstR; + if (dstR > 255) + dstR = 255; + dstG = srcG + dstG; + if (dstG > 255) + dstG = 255; + dstB = srcB + dstB; + if (dstB > 255) + dstB = 255; + break; + case SDL_COPY_MOD: + dstR = (srcR * dstR) / 255; + dstG = (srcG * dstG) / 255; + dstB = (srcB * dstB) / 255; + break; + case SDL_COPY_MUL: + dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; + if (dstR > 255) + dstR = 255; + dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; + if (dstG > 255) + dstG = 255; + dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; + if (dstB > 255) + dstB = 255; + dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; + if (dstA > 255) + dstA = 255; + break; + } + if (FORMAT_HAS_ALPHA(dstfmt_val)) { + ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA); + } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) { + ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB); + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + Uint32 pixel; + ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA); + *(Uint32 *)dst = pixel; + } + } + TRIANGLE_END_LOOP +} + +#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/software/SDL_triangle.h b/Engine/lib/sdl/src/render/software/SDL_triangle.h new file mode 100644 index 000000000..c120b39cf --- /dev/null +++ b/Engine/lib/sdl/src/render/software/SDL_triangle.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_triangle_h_ +#define SDL_triangle_h_ + +#include "../../SDL_internal.h" + +extern int SDL_SW_FillTriangle(SDL_Surface *dst, + SDL_Point *d0, SDL_Point *d1, SDL_Point *d2, + SDL_BlendMode blend, SDL_Color c0, SDL_Color c1, SDL_Color c2); + +extern int SDL_SW_BlitTriangle( + SDL_Surface *src, + SDL_Point *s0, SDL_Point *s1, SDL_Point *s2, + SDL_Surface *dst, + SDL_Point *d0, SDL_Point *d1, SDL_Point *d2, + SDL_Color c0, SDL_Color c1, SDL_Color c2); + +extern void trianglepoint_2_fixedpoint(SDL_Point *a); + +#endif /* SDL_triangle_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm.c b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm.c new file mode 100644 index 000000000..8a8877849 --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm.c @@ -0,0 +1,1042 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_RENDER_VITA_GXM + +#include "SDL_hints.h" +#include "../SDL_sysrender.h" +#include "SDL_log.h" + +#include +#include +#include +#include +#include + +#include "SDL_render_vita_gxm_types.h" +#include "SDL_render_vita_gxm_tools.h" +#include "SDL_render_vita_gxm_memory.h" + +#include + +/* #define DEBUG_RAZOR */ + +#if DEBUG_RAZOR +#include +#endif + +static SDL_Renderer *VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags); + +static void VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event); + +static SDL_bool VITA_GXM_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode); + +static int VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture); + +static int VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *pixels, int pitch); + +static int VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch); + +static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch); + +static void VITA_GXM_UnlockTexture(SDL_Renderer *renderer, + SDL_Texture *texture); + +static void VITA_GXM_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode); + +static int VITA_GXM_SetRenderTarget(SDL_Renderer *renderer, + SDL_Texture *texture); + + +static int VITA_GXM_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd); + +static int VITA_GXM_QueueSetDrawColor(SDL_Renderer * renderer, SDL_RenderCommand *cmd); + + +static int VITA_GXM_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count); +static int VITA_GXM_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count); + +static int +VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y); + +static int VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd); + +static int VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize); + +static int VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 pixel_format, void *pixels, int pitch); + + +static void VITA_GXM_RenderPresent(SDL_Renderer *renderer); +static void VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture); +static void VITA_GXM_DestroyRenderer(SDL_Renderer *renderer); + + +SDL_RenderDriver VITA_GXM_RenderDriver = { + .CreateRenderer = VITA_GXM_CreateRenderer, + .info = { + .name = "VITA gxm", + .flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE, + .num_texture_formats = 4, + .texture_formats = { + [0] = SDL_PIXELFORMAT_ABGR8888, + [1] = SDL_PIXELFORMAT_ARGB8888, + [2] = SDL_PIXELFORMAT_RGB565, + [3] = SDL_PIXELFORMAT_BGR565 + }, + .max_texture_width = 4096, + .max_texture_height = 4096, + } +}; + +static int +PixelFormatToVITAFMT(Uint32 format) +{ + switch (format) { + case SDL_PIXELFORMAT_ARGB8888: + return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB; + case SDL_PIXELFORMAT_RGB888: + return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB; + case SDL_PIXELFORMAT_BGR888: + return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR; + case SDL_PIXELFORMAT_ABGR8888: + return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR; + case SDL_PIXELFORMAT_RGB565: + return SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB; + case SDL_PIXELFORMAT_BGR565: + return SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR; + default: + return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR; + } +} + +void +StartDrawing(SDL_Renderer *renderer) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + if (data->drawing) { + return; + } + + data->drawstate.texture = NULL; + data->drawstate.vertex_program = NULL; + data->drawstate.fragment_program = NULL; + data->drawstate.last_command = -1; + data->drawstate.viewport_dirty = SDL_TRUE; + + // reset blend mode +// data->currentBlendMode = SDL_BLENDMODE_BLEND; +// fragment_programs *in = &data->blendFragmentPrograms.blend_mode_blend; +// data->colorFragmentProgram = in->color; +// data->textureFragmentProgram = in->texture; + + if (renderer->target == NULL) { + sceGxmBeginScene( + data->gxm_context, + 0, + data->renderTarget, + NULL, + NULL, + data->displayBufferSync[data->backBufferIndex], + &data->displaySurface[data->backBufferIndex], + &data->depthSurface + ); + } else { + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) renderer->target->driverdata; + + sceGxmBeginScene( + data->gxm_context, + 0, + vita_texture->tex->gxm_rendertarget, + NULL, + NULL, + NULL, + &vita_texture->tex->gxm_colorsurface, + &vita_texture->tex->gxm_depthstencil + ); + } + +// unset_clip_rectangle(data); + + data->drawing = SDL_TRUE; +} + +static int +VITA_GXM_SetVSync(SDL_Renderer * renderer, const int vsync) +{ + VITA_GXM_RenderData *data = renderer->driverdata; + if (vsync) { + data->displayData.wait_vblank = SDL_TRUE; + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + data->displayData.wait_vblank = SDL_FALSE; + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return 0; +} + +SDL_Renderer * +VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags) +{ + SDL_Renderer *renderer; + VITA_GXM_RenderData *data; + + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (VITA_GXM_RenderData *) SDL_calloc(1, sizeof(VITA_GXM_RenderData)); + if (!data) { + SDL_free(renderer); + SDL_OutOfMemory(); + return NULL; + } + + renderer->WindowEvent = VITA_GXM_WindowEvent; + renderer->SupportsBlendMode = VITA_GXM_SupportsBlendMode; + renderer->CreateTexture = VITA_GXM_CreateTexture; + renderer->UpdateTexture = VITA_GXM_UpdateTexture; +#if SDL_HAVE_YUV + renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV; +#endif + renderer->LockTexture = VITA_GXM_LockTexture; + renderer->UnlockTexture = VITA_GXM_UnlockTexture; + renderer->SetTextureScaleMode = VITA_GXM_SetTextureScaleMode; + renderer->SetRenderTarget = VITA_GXM_SetRenderTarget; + renderer->QueueSetViewport = VITA_GXM_QueueSetViewport; + renderer->QueueSetDrawColor = VITA_GXM_QueueSetDrawColor; + renderer->QueueDrawPoints = VITA_GXM_QueueDrawPoints; + renderer->QueueDrawLines = VITA_GXM_QueueDrawLines; + renderer->QueueGeometry = VITA_GXM_QueueGeometry; + renderer->RunCommandQueue = VITA_GXM_RunCommandQueue; + renderer->RenderReadPixels = VITA_GXM_RenderReadPixels; + renderer->RenderPresent = VITA_GXM_RenderPresent; + renderer->DestroyTexture = VITA_GXM_DestroyTexture; + renderer->DestroyRenderer = VITA_GXM_DestroyRenderer; + renderer->SetVSync = VITA_GXM_SetVSync; + + renderer->info = VITA_GXM_RenderDriver.info; + renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); + renderer->driverdata = data; + renderer->window = window; + + if (data->initialized != SDL_FALSE) + return 0; + data->initialized = SDL_TRUE; + + if (flags & SDL_RENDERER_PRESENTVSYNC) { + data->displayData.wait_vblank = SDL_TRUE; + } else { + data->displayData.wait_vblank = SDL_FALSE; + } + +#if DEBUG_RAZOR + sceSysmoduleLoadModule( SCE_SYSMODULE_RAZOR_HUD ); + sceSysmoduleLoadModule( SCE_SYSMODULE_RAZOR_CAPTURE ); +#endif + + if (gxm_init(renderer) != 0) + { + return NULL; + } + + return renderer; +} + +static void +VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) +{ +} + +static SDL_bool +VITA_GXM_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) +{ + // only for custom modes. we build all modes on init, so no custom modes, sorry + return SDL_FALSE; +} + +static int +VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + VITA_GXM_TextureData* vita_texture = (VITA_GXM_TextureData*) SDL_calloc(1, sizeof(VITA_GXM_TextureData)); + + if (!vita_texture) { + return SDL_OutOfMemory(); + } + + vita_texture->tex = create_gxm_texture(data, texture->w, texture->h, PixelFormatToVITAFMT(texture->format), (texture->access == SDL_TEXTUREACCESS_TARGET)); + + if (!vita_texture->tex) { + SDL_free(vita_texture); + return SDL_OutOfMemory(); + } + + texture->driverdata = vita_texture; + + VITA_GXM_SetTextureScaleMode(renderer, texture, texture->scaleMode); + + vita_texture->w = gxm_texture_get_width(vita_texture->tex); + vita_texture->h = gxm_texture_get_height(vita_texture->tex); + vita_texture->pitch = gxm_texture_get_stride(vita_texture->tex); + + return 0; +} + + +static int +VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *pixels, int pitch) +{ + const Uint8 *src; + Uint8 *dst; + int row, length,dpitch; + src = pixels; + + VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch); + length = rect->w * SDL_BYTESPERPIXEL(texture->format); + if (length == pitch && length == dpitch) { + SDL_memcpy(dst, src, length*rect->h); + } else { + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += dpitch; + } + } + + return 0; +} + +static int +VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch) +{ + return 0; +} + +static int +VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata; + + *pixels = + (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + + (rect->y * vita_texture->pitch) + rect->x * SDL_BYTESPERPIXEL(texture->format)); + *pitch = vita_texture->pitch; + + // make sure that rendering is finished on render target textures + if (vita_texture->tex->gxm_rendertarget != NULL) { + sceGxmFinish(data->gxm_context); + } + + return 0; +} + +static void +VITA_GXM_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + // No need to update texture data on ps vita. + // VITA_GXM_LockTexture already returns a pointer to the texture pixels buffer. + // This really improves framerate when using lock/unlock. +} + +static void +VITA_GXM_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode) +{ + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata; + + /* + set texture filtering according to scaleMode + suported hint values are nearest (0, default) or linear (1) + vitaScaleMode is either SCE_GXM_TEXTURE_FILTER_POINT (good for tile-map) + or SCE_GXM_TEXTURE_FILTER_LINEAR (good for scaling) + */ + + int vitaScaleMode = (scaleMode == SDL_ScaleModeNearest + ? SCE_GXM_TEXTURE_FILTER_POINT + : SCE_GXM_TEXTURE_FILTER_LINEAR); + gxm_texture_set_filters(vita_texture->tex, vitaScaleMode, vitaScaleMode); + + return; +} + +static int +VITA_GXM_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) +{ + return 0; +} + +static void +VITA_GXM_SetBlendMode(VITA_GXM_RenderData *data, int blendMode) +{ + if (blendMode != data->currentBlendMode) + { + fragment_programs *in = &data->blendFragmentPrograms.blend_mode_blend; + + switch (blendMode) + { + case SDL_BLENDMODE_NONE: + in = &data->blendFragmentPrograms.blend_mode_none; + break; + case SDL_BLENDMODE_BLEND: + in = &data->blendFragmentPrograms.blend_mode_blend; + break; + case SDL_BLENDMODE_ADD: + in = &data->blendFragmentPrograms.blend_mode_add; + break; + case SDL_BLENDMODE_MOD: + in = &data->blendFragmentPrograms.blend_mode_mod; + break; + case SDL_BLENDMODE_MUL: + in = &data->blendFragmentPrograms.blend_mode_mul; + break; + } + data->colorFragmentProgram = in->color; + data->textureFragmentProgram = in->texture; + data->currentBlendMode = blendMode; + } +} + +static int +VITA_GXM_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) +{ + return 0; +} + +static int +VITA_GXM_QueueSetDrawColor(SDL_Renderer * renderer, SDL_RenderCommand *cmd) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + + data->drawstate.color.r = cmd->data.color.r; + data->drawstate.color.g = cmd->data.color.g; + data->drawstate.color.b = cmd->data.color.b; + data->drawstate.color.a = cmd->data.color.a; + + return 0; +} + +static int +VITA_GXM_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + + SDL_Color color = data->drawstate.color; + + color_vertex *vertex = (color_vertex *)pool_malloc( + data, + count * sizeof(color_vertex) + ); + + cmd->data.draw.first = (size_t)vertex; + cmd->data.draw.count = count; + + for (int i = 0; i < count; i++) + { + vertex[i].x = points[i].x; + vertex[i].y = points[i].y; + vertex[i].color = color; + } + + return 0; +} + +static int +VITA_GXM_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + SDL_Color color = data->drawstate.color; + + color_vertex *vertex = (color_vertex *)pool_malloc( + data, + (count-1) * 2 * sizeof(color_vertex) + ); + + cmd->data.draw.first = (size_t)vertex; + cmd->data.draw.count = (count-1) * 2; + + for (int i = 0; i < count - 1; i++) + { + vertex[i*2].x = points[i].x; + vertex[i*2].y = points[i].y; + vertex[i*2].color = color; + + vertex[i*2+1].x = points[i+1].x; + vertex[i*2+1].y = points[i+1].y; + vertex[i*2+1].color = color; + } + + return 0; +} + +static int +VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + int i; + int count = indices ? num_indices : num_vertices; + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + if (texture) { + texture_vertex *vertices; + + vertices = (texture_vertex *)pool_malloc( + data, + count * sizeof(texture_vertex)); + + if (!vertices) { + return -1; + } + + + for (i = 0; i < count; i++) { + int j; + float *xy_; + float *uv_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); + uv_ = (float *)((char*)uv + j * uv_stride); + + vertices[i].x = xy_[0] * scale_x; + vertices[i].y = xy_[1] * scale_y; + vertices[i].u = uv_[0]; + vertices[i].v = uv_[1]; + vertices[i].color = col_; + } + + cmd->data.draw.first = (size_t)vertices; + + } else { + color_vertex *vertices; + + vertices = (color_vertex *)pool_malloc( + data, + count * sizeof(color_vertex)); + + if (!vertices) { + return -1; + } + + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); + + vertices[i].x = xy_[0] * scale_x; + vertices[i].y = xy_[1] * scale_y; + vertices[i].color = col_; + } + cmd->data.draw.first = (size_t)vertices; + } + + + return 0; +} + +static int +VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + void *color_buffer; + float clear_color[4]; + + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + unset_clip_rectangle(data); + + clear_color[0] = (cmd->data.color.r)/255.0f; + clear_color[1] = (cmd->data.color.g)/255.0f; + clear_color[2] = (cmd->data.color.b)/255.0f; + clear_color[3] = (cmd->data.color.a)/255.0f; + + // set clear shaders + data->drawstate.fragment_program = data->clearFragmentProgram; + data->drawstate.vertex_program = data->clearVertexProgram; + sceGxmSetVertexProgram(data->gxm_context, data->clearVertexProgram); + sceGxmSetFragmentProgram(data->gxm_context, data->clearFragmentProgram); + + // set the clear color + sceGxmReserveFragmentDefaultUniformBuffer(data->gxm_context, &color_buffer); + sceGxmSetUniformDataF(color_buffer, data->clearClearColorParam, 0, 4, clear_color); + + // draw the clear triangle + sceGxmSetVertexStream(data->gxm_context, 0, data->clearVertices); + sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, 3); + + data->drawstate.cliprect_dirty = SDL_TRUE; + return 0; +} + + +static int +SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd) +{ + SDL_Texture *texture = cmd->data.draw.texture; + const SDL_BlendMode blend = cmd->data.draw.blend; + SceGxmFragmentProgram *fragment_program; + SceGxmVertexProgram *vertex_program; + SDL_bool matrix_updated = SDL_FALSE; + SDL_bool program_updated = SDL_FALSE; + + if (data->drawstate.viewport_dirty) { + const SDL_Rect *viewport = &data->drawstate.viewport; + + + float sw = viewport->w / 2.; + float sh = viewport->h / 2.; + + float x_scale = sw; + float x_off = viewport->x + sw; + float y_scale = -(sh); + float y_off = viewport->y + sh; + + sceGxmSetViewport(data->gxm_context, x_off, x_scale, y_off, y_scale, 0.5f, 0.5f); + + if (viewport->w && viewport->h) { + init_orthographic_matrix(data->ortho_matrix, + (float) 0, + (float) viewport->w, + (float) viewport->h, + (float) 0, + 0.0f, 1.0f); + matrix_updated = SDL_TRUE; + } + + data->drawstate.viewport_dirty = SDL_FALSE; + } + + if (data->drawstate.cliprect_enabled_dirty) { + if (!data->drawstate.cliprect_enabled) { + unset_clip_rectangle(data); + } + data->drawstate.cliprect_enabled_dirty = SDL_FALSE; + } + + if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) { + const SDL_Rect *rect = &data->drawstate.cliprect; + set_clip_rectangle(data, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); + data->drawstate.cliprect_dirty = SDL_FALSE; + } + + VITA_GXM_SetBlendMode(data, blend); // do that first, to select appropriate shaders + + if (texture) { + vertex_program = data->textureVertexProgram; + fragment_program = data->textureFragmentProgram; + } else { + vertex_program = data->colorVertexProgram; + fragment_program = data->colorFragmentProgram; + } + + if (data->drawstate.vertex_program != vertex_program) { + data->drawstate.vertex_program = vertex_program; + sceGxmSetVertexProgram(data->gxm_context, vertex_program); + program_updated = SDL_TRUE; + } + + if (data->drawstate.fragment_program != fragment_program) { + data->drawstate.fragment_program = fragment_program; + sceGxmSetFragmentProgram(data->gxm_context, fragment_program); + program_updated = SDL_TRUE; + } + + + if (program_updated || matrix_updated) { + if (data->drawstate.fragment_program == data->textureFragmentProgram) { + void *vertex_wvp_buffer; + sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertex_wvp_buffer); + sceGxmSetUniformDataF(vertex_wvp_buffer, data->textureWvpParam, 0, 16, data->ortho_matrix); + } else { // color + void *vertexDefaultBuffer; + sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer); + sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix); + } + } + + if (texture != data->drawstate.texture) { + if (texture) { + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) cmd->data.draw.texture->driverdata; + sceGxmSetFragmentTexture(data->gxm_context, 0, &vita_texture->tex->gxm_tex); + } + data->drawstate.texture = texture; + } + + /* all drawing commands use this */ + sceGxmSetVertexStream(data->gxm_context, 0, (const void*)cmd->data.draw.first); + + return 0; +} + +static int +SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + + return SetDrawState(data, cmd); +} + +static int +VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + StartDrawing(renderer); + + data->drawstate.target = renderer->target; + if (!data->drawstate.target) { + int w, h; + SDL_GL_GetDrawableSize(renderer->window, &w, &h); + if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) { + data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc. + data->drawstate.cliprect_dirty = SDL_TRUE; + data->drawstate.drawablew = w; + data->drawstate.drawableh = h; + } + + } + + while (cmd) { + switch (cmd->command) { + + case SDL_RENDERCMD_SETVIEWPORT: { + SDL_Rect *viewport = &data->drawstate.viewport; + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { + SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); + data->drawstate.viewport_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_SETCLIPRECT: { + const SDL_Rect *rect = &cmd->data.cliprect.rect; + if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { + data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; + data->drawstate.cliprect_enabled_dirty = SDL_TRUE; + } + + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { + SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); + data->drawstate.cliprect_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_SETDRAWCOLOR: { + break; + } + + case SDL_RENDERCMD_CLEAR: { + VITA_GXM_RenderClear(renderer, cmd); + break; + } + + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; + + case SDL_RENDERCMD_COPY: /* unused */ + break; + + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; + + case SDL_RENDERCMD_DRAW_POINTS: + case SDL_RENDERCMD_DRAW_LINES: + case SDL_RENDERCMD_GEOMETRY: { + SDL_Texture *thistexture = cmd->data.draw.texture; + SDL_BlendMode thisblend = cmd->data.draw.blend; + const SDL_RenderCommandType thiscmdtype = cmd->command; + SDL_RenderCommand *finalcmd = cmd; + SDL_RenderCommand *nextcmd = cmd->next; + size_t count = cmd->data.draw.count; + int ret; + while (nextcmd != NULL) { + const SDL_RenderCommandType nextcmdtype = nextcmd->command; + if (nextcmdtype != thiscmdtype) { + break; /* can't go any further on this draw call, different render command up next. */ + } else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) { + break; /* can't go any further on this draw call, different texture/blendmode copy up next. */ + } else { + finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */ + count += nextcmd->data.draw.count; + } + nextcmd = nextcmd->next; + } + + if (thistexture) { + ret = SetCopyState(renderer, cmd); + } else { + ret = SetDrawState(data, cmd); + } + + if (ret == 0) { + int op = SCE_GXM_PRIMITIVE_TRIANGLES; + + if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) { + sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_POINT); + op = SCE_GXM_PRIMITIVE_POINTS; + } else if (thiscmdtype == SDL_RENDERCMD_DRAW_LINES) { + sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_LINE); + op = SCE_GXM_PRIMITIVE_LINES; + } + + sceGxmDraw(data->gxm_context, op, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, count); + + if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS || thiscmdtype == SDL_RENDERCMD_DRAW_LINES) { + sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_TRIANGLE_FILL); + } + + } + + cmd = finalcmd; /* skip any copy commands we just combined in here. */ + break; + } + + case SDL_RENDERCMD_NO_OP: + break; + } + data->drawstate.last_command = cmd->command; + cmd = cmd->next; + } + + sceGxmEndScene(data->gxm_context, NULL, NULL); + data->drawing = SDL_FALSE; + + return 0; +} + +void read_pixels(int x, int y, size_t width, size_t height, void *data) { + SceDisplayFrameBuf pParam; + int i, j; + Uint32 *out32; + Uint32 *in32; + + pParam.size = sizeof(SceDisplayFrameBuf); + + sceDisplayGetFrameBuf(&pParam, SCE_DISPLAY_SETBUF_NEXTFRAME); + + out32 = (Uint32 *)data; + in32 = (Uint32 *)pParam.base; + + in32 += (x + y * pParam.pitch); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + out32[(height - (i + 1)) * width + j] = in32[j]; + } + in32 += pParam.pitch; + } +} + + +static int +VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 pixel_format, void *pixels, int pitch) +{ + Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888; + size_t buflen; + void *temp_pixels; + int temp_pitch; + Uint8 *src, *dst, *tmp; + int w, h, length, rows; + int status; + + // TODO: read from texture rendertarget. Although no-one sane should do it. + if (renderer->target) { + return SDL_Unsupported(); + } + + + temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format); + buflen = rect->h * temp_pitch; + if (buflen == 0) { + return 0; /* nothing to do. */ + } + + temp_pixels = SDL_malloc(buflen); + if (!temp_pixels) { + return SDL_OutOfMemory(); + } + + SDL_GetRendererOutputSize(renderer, &w, &h); + + read_pixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h, + rect->w, rect->h, temp_pixels); + + /* Flip the rows to be top-down if necessary */ + + if (!renderer->target) { + SDL_bool isstack; + length = rect->w * SDL_BYTESPERPIXEL(temp_format); + src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; + dst = (Uint8*)temp_pixels; + tmp = SDL_small_alloc(Uint8, length, &isstack); + rows = rect->h / 2; + while (rows--) { + SDL_memcpy(tmp, dst, length); + SDL_memcpy(dst, src, length); + SDL_memcpy(src, tmp, length); + dst += temp_pitch; + src -= temp_pitch; + } + SDL_small_free(tmp, isstack); + } + + status = SDL_ConvertPixels(rect->w, rect->h, + temp_format, temp_pixels, temp_pitch, + pixel_format, pixels, pitch); + SDL_free(temp_pixels); + + return status; +} + + +static void +VITA_GXM_RenderPresent(SDL_Renderer *renderer) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + SceCommonDialogUpdateParam updateParam; + + data->displayData.address = data->displayBufferData[data->backBufferIndex]; + + SDL_memset(&updateParam, 0, sizeof(updateParam)); + + updateParam.renderTarget.colorFormat = VITA_GXM_COLOR_FORMAT; + updateParam.renderTarget.surfaceType = SCE_GXM_COLOR_SURFACE_LINEAR; + updateParam.renderTarget.width = VITA_GXM_SCREEN_WIDTH; + updateParam.renderTarget.height = VITA_GXM_SCREEN_HEIGHT; + updateParam.renderTarget.strideInPixels = VITA_GXM_SCREEN_STRIDE; + + updateParam.renderTarget.colorSurfaceData = data->displayBufferData[data->backBufferIndex]; + updateParam.renderTarget.depthSurfaceData = data->depthBufferData; + + updateParam.displaySyncObject = (SceGxmSyncObject *)data->displayBufferSync[data->backBufferIndex]; + + sceCommonDialogUpdate(&updateParam); + +#if DEBUG_RAZOR + sceGxmPadHeartbeat( + (const SceGxmColorSurface *)&data->displaySurface[data->backBufferIndex], + (SceGxmSyncObject *)data->displayBufferSync[data->backBufferIndex] + ); +#endif + + sceGxmDisplayQueueAddEntry( + data->displayBufferSync[data->frontBufferIndex], // OLD fb + data->displayBufferSync[data->backBufferIndex], // NEW fb + &data->displayData + ); + + // update buffer indices + data->frontBufferIndex = data->backBufferIndex; + data->backBufferIndex = (data->backBufferIndex + 1) % VITA_GXM_BUFFERS; + data->pool_index = 0; + + data->current_pool = (data->current_pool + 1) % 2; +} + +static void +VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata; + + if (data == 0) + return; + + if(vita_texture == 0) + return; + + if(vita_texture->tex == 0) + return; + + sceGxmFinish(data->gxm_context); + + free_gxm_texture(vita_texture->tex); + + SDL_free(vita_texture); + + texture->driverdata = NULL; +} + +static void +VITA_GXM_DestroyRenderer(SDL_Renderer *renderer) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + if (data) { + if (!data->initialized) + return; + + gxm_finish(renderer); + + data->initialized = SDL_FALSE; + data->drawing = SDL_FALSE; + SDL_free(data); + } + SDL_free(renderer); +} + +#endif /* SDL_VIDEO_RENDER_VITA_GXM */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.c b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.c new file mode 100644 index 000000000..d3322730a --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.c @@ -0,0 +1,117 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_RENDER_VITA_GXM + +#include "SDL_render_vita_gxm_memory.h" + +void * +mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid) +{ + void *mem; + + if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW) { + size = ALIGN(size, 256*1024); + } else { + size = ALIGN(size, 4*1024); + } + + *uid = sceKernelAllocMemBlock("gpu_mem", type, size, NULL); + + if (*uid < 0) + return NULL; + + if (sceKernelGetMemBlockBase(*uid, &mem) < 0) + return NULL; + + if (sceGxmMapMemory(mem, size, attribs) < 0) + return NULL; + + return mem; +} + +void +mem_gpu_free(SceUID uid) +{ + void *mem = NULL; + if (sceKernelGetMemBlockBase(uid, &mem) < 0) + return; + sceGxmUnmapMemory(mem); + sceKernelFreeMemBlock(uid); +} + +void * +mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset) +{ + void *mem = NULL; + + size = ALIGN(size, 4096); + *uid = sceKernelAllocMemBlock("vertex_usse", SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, size, NULL); + + if (sceKernelGetMemBlockBase(*uid, &mem) < 0) + return NULL; + if (sceGxmMapVertexUsseMemory(mem, size, usse_offset) < 0) + return NULL; + + return mem; +} + +void +mem_vertex_usse_free(SceUID uid) +{ + void *mem = NULL; + if (sceKernelGetMemBlockBase(uid, &mem) < 0) + return; + sceGxmUnmapVertexUsseMemory(mem); + sceKernelFreeMemBlock(uid); +} + +void * +mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset) +{ + void *mem = NULL; + + size = ALIGN(size, 4096); + *uid = sceKernelAllocMemBlock("fragment_usse", SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, size, NULL); + + if (sceKernelGetMemBlockBase(*uid, &mem) < 0) + return NULL; + if (sceGxmMapFragmentUsseMemory(mem, size, usse_offset) < 0) + return NULL; + + return mem; +} + +void +mem_fragment_usse_free(SceUID uid) +{ + void *mem = NULL; + if (sceKernelGetMemBlockBase(uid, &mem) < 0) + return; + sceGxmUnmapFragmentUsseMemory(mem); + sceKernelFreeMemBlock(uid); +} + +#endif /* SDL_VIDEO_RENDER_VITA_GXM */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.h b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.h new file mode 100644 index 000000000..51bc8a80a --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.h @@ -0,0 +1,40 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_RENDER_VITA_GXM_MEMORY_H +#define SDL_RENDER_VITA_GXM_MEMORY_H + +#include +#include +#include + +#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) + +void *mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid); +void mem_gpu_free(SceUID uid); +void *mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset); +void mem_vertex_usse_free(SceUID uid); +void *mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset); +void mem_fragment_usse_free(SceUID uid); + +#endif /* SDL_RENDER_VITA_GXM_MEMORY_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_shaders.h b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_shaders.h new file mode 100644 index 000000000..f60ad1d55 --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_shaders.h @@ -0,0 +1,280 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_RENDER_VITA_GXM_SHADERS_H +#define SDL_RENDER_VITA_GXM_SHADERS_H + +#include + +#define gxm_shader_clear_f_size 232 +static const unsigned char gxm_shader_clear_f[gxm_shader_clear_f_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0xe8, 0x00, 0x00, 0x00, 0xa2, 0x55, 0x22, 0x3e, + 0xc6, 0x7e, 0x77, 0xf1, 0x01, 0x00, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xa4, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x44, 0xfa, 0x02, 0x80, 0x19, 0xf0, + 0x7e, 0x0d, 0x80, 0x40, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x01, 0xe4, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x75, 0x43, 0x6c, 0x65, + 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, +}; + +#define gxm_shader_clear_v_size 252 +static const unsigned char gxm_shader_clear_v[gxm_shader_clear_v_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0xfa, 0x00, 0x00, 0x00, 0xdc, 0x25, 0x34, 0x74, + 0x53, 0x4a, 0x7a, 0x5b, 0x04, 0x00, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, + 0x01, 0x00, 0x04, 0x90, 0x85, 0x11, 0xa5, 0x08, + 0x01, 0x80, 0x56, 0x90, 0x81, 0x11, 0x83, 0x08, + 0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x00, 0x00, +}; + +#define gxm_shader_color_f_size 212 +static const unsigned char gxm_shader_color_f[gxm_shader_color_f_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0xd4, 0x00, 0x00, 0x00, 0x9c, 0xd6, 0x9b, 0xf7, + 0x78, 0x00, 0x5d, 0x31, 0x01, 0x10, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xac, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x0f, 0xa0, 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x44, 0xfa, 0x02, 0x80, 0x19, 0xa0, + 0x7e, 0x0d, 0x80, 0x40, +}; + +#define gxm_shader_color_v_size 368 +static const unsigned char gxm_shader_color_v[gxm_shader_color_v_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0x6d, 0x01, 0x00, 0x00, 0x09, 0xce, 0x4e, 0xc2, + 0xe1, 0xcd, 0x24, 0xbc, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0x00, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x07, 0x53, 0x40, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, + 0x80, 0x00, 0x08, 0x83, 0x21, 0x1d, 0x80, 0x38, + 0x00, 0x00, 0xf0, 0x83, 0x20, 0x0d, 0x80, 0x38, + 0x0a, 0x84, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, + 0x02, 0x11, 0x45, 0xcf, 0x80, 0x8f, 0xb1, 0x18, + 0x00, 0x11, 0x01, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x01, 0xd1, 0x42, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x40, 0x00, 0x10, 0x41, 0x09, 0x05, 0x82, 0x38, + 0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x61, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0x00, 0x77, 0x76, 0x70, 0x00, 0x00, 0x00, 0x00, +}; + +#define gxm_shader_texture_f_size 288 +static const unsigned char gxm_shader_texture_f[gxm_shader_texture_f_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0x20, 0x01, 0x00, 0x00, 0xeb, 0x4f, 0xb5, 0xba, + 0x60, 0xb2, 0xd0, 0x8d, 0x05, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xc4, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, + 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0xa9, 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x09, 0x00, 0xf8, 0x02, 0x80, 0x99, 0xaf, + 0xbc, 0x0d, 0xc0, 0x40, 0x06, 0x82, 0xb9, 0xaf, + 0xbc, 0x0d, 0x80, 0x40, 0x7c, 0x0f, 0x04, 0x00, + 0x86, 0x47, 0xa4, 0x10, 0x30, 0x00, 0x00, 0x00, + 0x02, 0x04, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00, +}; + +#define gxm_shader_texture_v_size 400 +static const unsigned char gxm_shader_texture_v[gxm_shader_texture_v_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0x8f, 0x01, 0x00, 0x00, 0x60, 0x1e, 0x69, 0x97, + 0x82, 0x7e, 0x0c, 0xac, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x33, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0a, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0x00, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x07, 0x53, 0x40, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, + 0x01, 0x0e, 0x01, 0x01, 0x02, 0x00, 0x10, 0xfa, + 0x80, 0x00, 0x08, 0x83, 0x21, 0x25, 0x80, 0x38, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x14, 0xfa, + 0x00, 0x00, 0xf0, 0x83, 0x20, 0x0d, 0x80, 0x38, + 0x0a, 0x84, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, + 0x02, 0x11, 0x45, 0xcf, 0x80, 0x8f, 0xb1, 0x18, + 0x00, 0x11, 0x01, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x01, 0xd1, 0x42, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x61, 0x54, 0x65, 0x78, 0x63, 0x6f, + 0x6f, 0x72, 0x64, 0x00, 0x61, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x00, 0x77, 0x76, 0x70, 0x00, 0x00, +}; + +static const SceGxmProgram *const clearVertexProgramGxp = (const SceGxmProgram *)gxm_shader_clear_v; +static const SceGxmProgram *const clearFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_clear_f; +static const SceGxmProgram *const colorVertexProgramGxp = (const SceGxmProgram *)gxm_shader_color_v; +static const SceGxmProgram *const colorFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_color_f; +static const SceGxmProgram *const textureVertexProgramGxp = (const SceGxmProgram *)gxm_shader_texture_v; +static const SceGxmProgram *const textureFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_texture_f; + +#endif // SDL_RENDER_VITA_GXM_SHADERS_H + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.c b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.c new file mode 100644 index 000000000..e043b55ab --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.c @@ -0,0 +1,1239 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_RENDER_VITA_GXM + +#include "SDL_hints.h" +#include "../SDL_sysrender.h" +#include "SDL_log.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "SDL_render_vita_gxm_tools.h" +#include "SDL_render_vita_gxm_types.h" +#include "SDL_render_vita_gxm_memory.h" +#include "SDL_render_vita_gxm_shaders.h" + +void +init_orthographic_matrix(float *m, float left, float right, float bottom, float top, float near, float far) +{ + m[0x0] = 2.0f/(right-left); + m[0x4] = 0.0f; + m[0x8] = 0.0f; + m[0xC] = -(right+left)/(right-left); + + m[0x1] = 0.0f; + m[0x5] = 2.0f/(top-bottom); + m[0x9] = 0.0f; + m[0xD] = -(top+bottom)/(top-bottom); + + m[0x2] = 0.0f; + m[0x6] = 0.0f; + m[0xA] = -2.0f/(far-near); + m[0xE] = (far+near)/(far-near); + + m[0x3] = 0.0f; + m[0x7] = 0.0f; + m[0xB] = 0.0f; + m[0xF] = 1.0f; +} + +static void * +patcher_host_alloc(void *user_data, unsigned int size) +{ + void *mem = SDL_malloc(size); + (void)user_data; + return mem; +} + +static void +patcher_host_free(void *user_data, void *mem) +{ + (void)user_data; + SDL_free(mem); +} + +void * +pool_malloc(VITA_GXM_RenderData *data, unsigned int size) +{ + + if ((data->pool_index + size) < VITA_GXM_POOL_SIZE) { + void *addr = (void *)((unsigned int)data->pool_addr[data->current_pool] + data->pool_index); + data->pool_index += size; + return addr; + } + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "POOL OVERFLOW\n"); + return NULL; +} + +void * +pool_memalign(VITA_GXM_RenderData *data, unsigned int size, unsigned int alignment) +{ + unsigned int new_index = (data->pool_index + alignment - 1) & ~(alignment - 1); + if ((new_index + size) < VITA_GXM_POOL_SIZE) { + void *addr = (void *)((unsigned int)data->pool_addr[data->current_pool] + new_index); + data->pool_index = new_index + size; + return addr; + } + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "POOL OVERFLOW\n"); + return NULL; +} + +static int +tex_format_to_bytespp(SceGxmTextureFormat format) +{ + switch (format & 0x9f000000U) { + case SCE_GXM_TEXTURE_BASE_FORMAT_U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8: + case SCE_GXM_TEXTURE_BASE_FORMAT_P8: + return 1; + case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4: + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2: + case SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5: + case SCE_GXM_TEXTURE_BASE_FORMAT_U5U6U5: + case SCE_GXM_TEXTURE_BASE_FORMAT_S5S5U6: + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8S8: + return 2; + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8: + return 3; + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8: + case SCE_GXM_TEXTURE_BASE_FORMAT_F32: + case SCE_GXM_TEXTURE_BASE_FORMAT_U32: + case SCE_GXM_TEXTURE_BASE_FORMAT_S32: + default: + return 4; + } +} + +static void +display_callback(const void *callback_data) +{ + SceDisplayFrameBuf framebuf; + const VITA_GXM_DisplayData *display_data = (const VITA_GXM_DisplayData *)callback_data; + + SDL_memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf)); + framebuf.size = sizeof(SceDisplayFrameBuf); + framebuf.base = display_data->address; + framebuf.pitch = VITA_GXM_SCREEN_STRIDE; + framebuf.pixelformat = VITA_GXM_PIXEL_FORMAT; + framebuf.width = VITA_GXM_SCREEN_WIDTH; + framebuf.height = VITA_GXM_SCREEN_HEIGHT; + sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME); + + if (display_data->wait_vblank) { + sceDisplayWaitVblankStart(); + } +} + +static void +free_fragment_programs(VITA_GXM_RenderData *data, fragment_programs *out) +{ + sceGxmShaderPatcherReleaseFragmentProgram(data->shaderPatcher, out->color); + sceGxmShaderPatcherReleaseFragmentProgram(data->shaderPatcher, out->texture); +} + +static void +make_fragment_programs(VITA_GXM_RenderData *data, fragment_programs *out, + const SceGxmBlendInfo *blend_info) +{ + int err; + + err = sceGxmShaderPatcherCreateFragmentProgram( + data->shaderPatcher, + data->colorFragmentProgramId, + SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, + 0, + blend_info, + colorVertexProgramGxp, + &out->color + ); + + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Patcher create fragment failed: %d\n", err); + return; + } + + err = sceGxmShaderPatcherCreateFragmentProgram( + data->shaderPatcher, + data->textureFragmentProgramId, + SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, + 0, + blend_info, + textureVertexProgramGxp, + &out->texture + ); + + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Patcher create fragment failed: %d\n", err); + return; + } +} + + +static void +set_stencil_mask(VITA_GXM_RenderData *data, float x, float y, float w, float h) +{ + void *vertexDefaultBuffer; + color_vertex *vertices = (color_vertex *)pool_memalign( + data, + 4 * sizeof(color_vertex), // 4 vertices + sizeof(color_vertex) + ); + + vertices[0].x = x; + vertices[0].y = y; + vertices[0].color.r = 0; + vertices[0].color.g = 0; + vertices[0].color.b = 0; + vertices[0].color.a = 0; + + vertices[1].x = x + w; + vertices[1].y = y; + vertices[1].color.r = 0; + vertices[1].color.g = 0; + vertices[1].color.b = 0; + vertices[1].color.a = 0; + + vertices[2].x = x; + vertices[2].y = y + h; + vertices[2].color.r = 0; + vertices[2].color.g = 0; + vertices[2].color.b = 0; + vertices[2].color.a = 0; + + vertices[3].x = x + w; + vertices[3].y = y + h; + vertices[3].color.r = 0; + vertices[3].color.g = 0; + vertices[3].color.b = 0; + vertices[3].color.a = 0; + + data->drawstate.fragment_program = data->colorFragmentProgram; + data->drawstate.vertex_program = data->colorVertexProgram; + sceGxmSetVertexProgram(data->gxm_context, data->colorVertexProgram); + sceGxmSetFragmentProgram(data->gxm_context, data->colorFragmentProgram); + + sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer); + sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix); + + sceGxmSetVertexStream(data->gxm_context, 0, vertices); + sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, 4); +} + + +void +set_clip_rectangle(VITA_GXM_RenderData *data, int x_min, int y_min, int x_max, int y_max) +{ + if(data->drawing) { + // clear the stencil buffer to 0 + sceGxmSetFrontStencilFunc( + data->gxm_context, + SCE_GXM_STENCIL_FUNC_NEVER, + SCE_GXM_STENCIL_OP_ZERO, + SCE_GXM_STENCIL_OP_ZERO, + SCE_GXM_STENCIL_OP_ZERO, + 0xFF, + 0xFF + ); + + set_stencil_mask(data, 0, 0, VITA_GXM_SCREEN_WIDTH, VITA_GXM_SCREEN_HEIGHT); + + // set the stencil to 1 in the desired region + sceGxmSetFrontStencilFunc( + data->gxm_context, + SCE_GXM_STENCIL_FUNC_NEVER, + SCE_GXM_STENCIL_OP_REPLACE, + SCE_GXM_STENCIL_OP_REPLACE, + SCE_GXM_STENCIL_OP_REPLACE, + 0xFF, + 0xFF + ); + + set_stencil_mask(data, x_min, y_min, x_max - x_min, y_max - y_min); + + // set the stencil function to only accept pixels where the stencil is 1 + sceGxmSetFrontStencilFunc( + data->gxm_context, + SCE_GXM_STENCIL_FUNC_EQUAL, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + 0xFF, + 0xFF + ); + } +} + +void +unset_clip_rectangle(VITA_GXM_RenderData *data) +{ + sceGxmSetFrontStencilFunc( + data->gxm_context, + SCE_GXM_STENCIL_FUNC_ALWAYS, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + 0xFF, + 0xFF + ); +} + +int +gxm_init(SDL_Renderer *renderer) +{ + unsigned int i, x, y; + int err; + void *vdmRingBuffer; + void *vertexRingBuffer; + void *fragmentRingBuffer; + unsigned int fragmentUsseRingBufferOffset; + void *fragmentUsseRingBuffer; + unsigned int patcherVertexUsseOffset; + unsigned int patcherFragmentUsseOffset; + void *patcherBuffer; + void *patcherVertexUsse; + void *patcherFragmentUsse; + + SceGxmRenderTargetParams renderTargetParams; + SceGxmShaderPatcherParams patcherParams; + + // compute the memory footprint of the depth buffer + const unsigned int alignedWidth = ALIGN(VITA_GXM_SCREEN_WIDTH, SCE_GXM_TILE_SIZEX); + const unsigned int alignedHeight = ALIGN(VITA_GXM_SCREEN_HEIGHT, SCE_GXM_TILE_SIZEY); + + unsigned int sampleCount = alignedWidth * alignedHeight; + unsigned int depthStrideInSamples = alignedWidth; + + // set buffer sizes for this sample + const unsigned int patcherBufferSize = 64*1024; + const unsigned int patcherVertexUsseSize = 64*1024; + const unsigned int patcherFragmentUsseSize = 64*1024; + + // Fill SceGxmBlendInfo + static const SceGxmBlendInfo blend_info_none = { + .colorFunc = SCE_GXM_BLEND_FUNC_NONE, + .alphaFunc = SCE_GXM_BLEND_FUNC_NONE, + .colorSrc = SCE_GXM_BLEND_FACTOR_ZERO, + .colorDst = SCE_GXM_BLEND_FACTOR_ZERO, + .alphaSrc = SCE_GXM_BLEND_FACTOR_ZERO, + .alphaDst = SCE_GXM_BLEND_FACTOR_ZERO, + .colorMask = SCE_GXM_COLOR_MASK_ALL + }; + + static const SceGxmBlendInfo blend_info_blend = { + .colorFunc = SCE_GXM_BLEND_FUNC_ADD, + .alphaFunc = SCE_GXM_BLEND_FUNC_ADD, + .colorSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA, + .colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .alphaSrc = SCE_GXM_BLEND_FACTOR_ONE, + .alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .colorMask = SCE_GXM_COLOR_MASK_ALL + }; + + static const SceGxmBlendInfo blend_info_add = { + .colorFunc = SCE_GXM_BLEND_FUNC_ADD, + .alphaFunc = SCE_GXM_BLEND_FUNC_ADD, + .colorSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA, + .colorDst = SCE_GXM_BLEND_FACTOR_ONE, + .alphaSrc = SCE_GXM_BLEND_FACTOR_ZERO, + .alphaDst = SCE_GXM_BLEND_FACTOR_ONE, + .colorMask = SCE_GXM_COLOR_MASK_ALL + }; + + static const SceGxmBlendInfo blend_info_mod = { + .colorFunc = SCE_GXM_BLEND_FUNC_ADD, + .alphaFunc = SCE_GXM_BLEND_FUNC_ADD, + + .colorSrc = SCE_GXM_BLEND_FACTOR_ZERO, + .colorDst = SCE_GXM_BLEND_FACTOR_SRC_COLOR, + + .alphaSrc = SCE_GXM_BLEND_FACTOR_ZERO, + .alphaDst = SCE_GXM_BLEND_FACTOR_ONE, + .colorMask = SCE_GXM_COLOR_MASK_ALL + }; + + static const SceGxmBlendInfo blend_info_mul = { + .colorFunc = SCE_GXM_BLEND_FUNC_ADD, + .alphaFunc = SCE_GXM_BLEND_FUNC_ADD, + .colorSrc = SCE_GXM_BLEND_FACTOR_DST_COLOR, + .colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .alphaSrc = SCE_GXM_BLEND_FACTOR_DST_ALPHA, + .alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .colorMask = SCE_GXM_COLOR_MASK_ALL + }; + + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + + SceGxmInitializeParams initializeParams; + SDL_memset(&initializeParams, 0, sizeof(SceGxmInitializeParams)); + initializeParams.flags = 0; + initializeParams.displayQueueMaxPendingCount = VITA_GXM_PENDING_SWAPS; + initializeParams.displayQueueCallback = display_callback; + initializeParams.displayQueueCallbackDataSize = sizeof(VITA_GXM_DisplayData); + initializeParams.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE; + + err = sceGxmInitialize(&initializeParams); + + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "gxm init failed: %d\n", err); + return err; + } + + // allocate ring buffer memory using default sizes + vdmRingBuffer = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE, + 4, + SCE_GXM_MEMORY_ATTRIB_READ, + &data->vdmRingBufferUid); + + vertexRingBuffer = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE, + 4, + SCE_GXM_MEMORY_ATTRIB_READ, + &data->vertexRingBufferUid); + + fragmentRingBuffer = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE, + 4, + SCE_GXM_MEMORY_ATTRIB_READ, + &data->fragmentRingBufferUid); + + fragmentUsseRingBuffer = mem_fragment_usse_alloc( + SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE, + &data->fragmentUsseRingBufferUid, + &fragmentUsseRingBufferOffset); + + SDL_memset(&data->contextParams, 0, sizeof(SceGxmContextParams)); + data->contextParams.hostMem = SDL_malloc(SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE); + data->contextParams.hostMemSize = SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE; + data->contextParams.vdmRingBufferMem = vdmRingBuffer; + data->contextParams.vdmRingBufferMemSize = SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE; + data->contextParams.vertexRingBufferMem = vertexRingBuffer; + data->contextParams.vertexRingBufferMemSize = SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE; + data->contextParams.fragmentRingBufferMem = fragmentRingBuffer; + data->contextParams.fragmentRingBufferMemSize = SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE; + data->contextParams.fragmentUsseRingBufferMem = fragmentUsseRingBuffer; + data->contextParams.fragmentUsseRingBufferMemSize = SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE; + data->contextParams.fragmentUsseRingBufferOffset = fragmentUsseRingBufferOffset; + + err = sceGxmCreateContext(&data->contextParams, &data->gxm_context); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create context failed: %d\n", err); + return err; + } + + // set up parameters + SDL_memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams)); + renderTargetParams.flags = 0; + renderTargetParams.width = VITA_GXM_SCREEN_WIDTH; + renderTargetParams.height = VITA_GXM_SCREEN_HEIGHT; + renderTargetParams.scenesPerFrame = 1; + renderTargetParams.multisampleMode = 0; + renderTargetParams.multisampleLocations = 0; + renderTargetParams.driverMemBlock = -1; // Invalid UID + + // create the render target + err = sceGxmCreateRenderTarget(&renderTargetParams, &data->renderTarget); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "render target creation failed: %d\n", err); + return err; + } + + // allocate memory and sync objects for display buffers + for (i = 0; i < VITA_GXM_BUFFERS; i++) { + + // allocate memory for display + data->displayBufferData[i] = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT, + SCE_GXM_COLOR_SURFACE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &data->displayBufferUid[i]); + + // SDL_memset the buffer to black + for (y = 0; y < VITA_GXM_SCREEN_HEIGHT; y++) { + unsigned int *row = (unsigned int *)data->displayBufferData[i] + y * VITA_GXM_SCREEN_STRIDE; + for (x = 0; x < VITA_GXM_SCREEN_WIDTH; x++) { + row[x] = 0xff000000; + } + } + + // initialize a color surface for this display buffer + err = sceGxmColorSurfaceInit( + &data->displaySurface[i], + VITA_GXM_COLOR_FORMAT, + SCE_GXM_COLOR_SURFACE_LINEAR, + SCE_GXM_COLOR_SURFACE_SCALE_NONE, + SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT, + VITA_GXM_SCREEN_WIDTH, + VITA_GXM_SCREEN_HEIGHT, + VITA_GXM_SCREEN_STRIDE, + data->displayBufferData[i] + ); + + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %d\n", err); + return err; + } + + + // create a sync object that we will associate with this buffer + err = sceGxmSyncObjectCreate(&data->displayBufferSync[i]); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "sync object creation failed: %d\n", err); + return err; + } + + } + + + // allocate the depth buffer + data->depthBufferData = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + 4 * sampleCount, + SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &data->depthBufferUid); + + // allocate the stencil buffer + data->stencilBufferData = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + 4 * sampleCount, + SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &data->stencilBufferUid); + + // create the SceGxmDepthStencilSurface structure + err = sceGxmDepthStencilSurfaceInit( + &data->depthSurface, + SCE_GXM_DEPTH_STENCIL_FORMAT_S8D24, + SCE_GXM_DEPTH_STENCIL_SURFACE_TILED, + depthStrideInSamples, + data->depthBufferData, + data->stencilBufferData); + + // set the stencil test reference (this is currently assumed to always remain 1 after here for region clipping) + sceGxmSetFrontStencilRef(data->gxm_context, 1); + + + // set the stencil function (this wouldn't actually be needed, as the set clip rectangle function has to call this at the begginning of every scene) + sceGxmSetFrontStencilFunc( + data->gxm_context, + SCE_GXM_STENCIL_FUNC_ALWAYS, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + 0xFF, + 0xFF); + + + // allocate memory for buffers and USSE code + patcherBuffer = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + patcherBufferSize, + 4, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &data->patcherBufferUid); + + patcherVertexUsse = mem_vertex_usse_alloc( + patcherVertexUsseSize, + &data->patcherVertexUsseUid, + &patcherVertexUsseOffset); + + patcherFragmentUsse = mem_fragment_usse_alloc( + patcherFragmentUsseSize, + &data->patcherFragmentUsseUid, + &patcherFragmentUsseOffset); + + // create a shader patcher + SDL_memset(&patcherParams, 0, sizeof(SceGxmShaderPatcherParams)); + patcherParams.userData = NULL; + patcherParams.hostAllocCallback = &patcher_host_alloc; + patcherParams.hostFreeCallback = &patcher_host_free; + patcherParams.bufferAllocCallback = NULL; + patcherParams.bufferFreeCallback = NULL; + patcherParams.bufferMem = patcherBuffer; + patcherParams.bufferMemSize = patcherBufferSize; + patcherParams.vertexUsseAllocCallback = NULL; + patcherParams.vertexUsseFreeCallback = NULL; + patcherParams.vertexUsseMem = patcherVertexUsse; + patcherParams.vertexUsseMemSize = patcherVertexUsseSize; + patcherParams.vertexUsseOffset = patcherVertexUsseOffset; + patcherParams.fragmentUsseAllocCallback = NULL; + patcherParams.fragmentUsseFreeCallback = NULL; + patcherParams.fragmentUsseMem = patcherFragmentUsse; + patcherParams.fragmentUsseMemSize = patcherFragmentUsseSize; + patcherParams.fragmentUsseOffset = patcherFragmentUsseOffset; + + err = sceGxmShaderPatcherCreate(&patcherParams, &data->shaderPatcher); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "shader patcher creation failed: %d\n", err); + return err; + } + + + // check the shaders + err = sceGxmProgramCheck(clearVertexProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (clear vertex) failed: %d\n", err); + return err; + } + + err = sceGxmProgramCheck(clearFragmentProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (clear fragment) failed: %d\n", err); + return err; + } + + err = sceGxmProgramCheck(colorVertexProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (color vertex) failed: %d\n", err); + return err; + } + + err = sceGxmProgramCheck(colorFragmentProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (color fragment) failed: %d\n", err); + return err; + } + + err = sceGxmProgramCheck(textureVertexProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (texture vertex) failed: %d\n", err); + return err; + } + + err = sceGxmProgramCheck(textureFragmentProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (texture fragment) failed: %d\n", err); + return err; + } + + // register programs with the patcher + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, clearVertexProgramGxp, &data->clearVertexProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (clear vertex) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, clearFragmentProgramGxp, &data->clearFragmentProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (clear fragment) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, colorVertexProgramGxp, &data->colorVertexProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (color vertex) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, colorFragmentProgramGxp, &data->colorFragmentProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (color fragment) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, textureVertexProgramGxp, &data->textureVertexProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (texture vertex) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, textureFragmentProgramGxp, &data->textureFragmentProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (texture fragment) failed: %d\n", err); + return err; + } + + { + // get attributes by name to create vertex format bindings + const SceGxmProgramParameter *paramClearPositionAttribute = sceGxmProgramFindParameterByName(clearVertexProgramGxp, "aPosition"); + + // create clear vertex format + SceGxmVertexAttribute clearVertexAttributes[1]; + SceGxmVertexStream clearVertexStreams[1]; + clearVertexAttributes[0].streamIndex = 0; + clearVertexAttributes[0].offset = 0; + clearVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; + clearVertexAttributes[0].componentCount = 2; + clearVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramClearPositionAttribute); + clearVertexStreams[0].stride = sizeof(clear_vertex); + clearVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT; + + // create clear programs + err = sceGxmShaderPatcherCreateVertexProgram( + data->shaderPatcher, + data->clearVertexProgramId, + clearVertexAttributes, + 1, + clearVertexStreams, + 1, + &data->clearVertexProgram + ); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create program (clear vertex) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherCreateFragmentProgram( + data->shaderPatcher, + data->clearFragmentProgramId, + SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, + 0, + NULL, + clearVertexProgramGxp, + &data->clearFragmentProgram + ); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create program (clear fragment) failed: %d\n", err); + return err; + } + + // create the clear triangle vertex/index data + data->clearVertices = (clear_vertex *)mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + 3*sizeof(clear_vertex), + 4, + SCE_GXM_MEMORY_ATTRIB_READ, + &data->clearVerticesUid + ); + } + + // Allocate a 64k * 2 bytes = 128 KiB buffer and store all possible + // 16-bit indices in linear ascending order, so we can use this for + // all drawing operations where we don't want to use indexing. + data->linearIndices = (uint16_t *)mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + UINT16_MAX*sizeof(uint16_t), + sizeof(uint16_t), + SCE_GXM_MEMORY_ATTRIB_READ, + &data->linearIndicesUid + ); + + for (i = 0; i <= UINT16_MAX; ++i) + { + data->linearIndices[i] = i; + } + + data->clearVertices[0].x = -1.0f; + data->clearVertices[0].y = -1.0f; + data->clearVertices[1].x = 3.0f; + data->clearVertices[1].y = -1.0f; + data->clearVertices[2].x = -1.0f; + data->clearVertices[2].y = 3.0f; + + { + const SceGxmProgramParameter *paramColorPositionAttribute = sceGxmProgramFindParameterByName(colorVertexProgramGxp, "aPosition"); + + const SceGxmProgramParameter *paramColorColorAttribute = sceGxmProgramFindParameterByName(colorVertexProgramGxp, "aColor"); + + // create color vertex format + SceGxmVertexAttribute colorVertexAttributes[2]; + SceGxmVertexStream colorVertexStreams[1]; + /* x,y: 2 float 32 bits */ + colorVertexAttributes[0].streamIndex = 0; + colorVertexAttributes[0].offset = 0; + colorVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; + colorVertexAttributes[0].componentCount = 2; // (x, y) + colorVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramColorPositionAttribute); + /* color: 4 unsigned char = 32 bits */ + colorVertexAttributes[1].streamIndex = 0; + colorVertexAttributes[1].offset = 8; // (x, y) * 4 = 8 bytes + colorVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_U8N; + colorVertexAttributes[1].componentCount = 4; // (color) + colorVertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(paramColorColorAttribute); + // 16 bit (short) indices + colorVertexStreams[0].stride = sizeof(color_vertex); + colorVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT; + + // create color shaders + err = sceGxmShaderPatcherCreateVertexProgram( + data->shaderPatcher, + data->colorVertexProgramId, + colorVertexAttributes, + 2, + colorVertexStreams, + 1, + &data->colorVertexProgram + ); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create program (color vertex) failed: %d\n", err); + return err; + } + + } + + + { + const SceGxmProgramParameter *paramTexturePositionAttribute = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "aPosition"); + const SceGxmProgramParameter *paramTextureTexcoordAttribute = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "aTexcoord"); + const SceGxmProgramParameter *paramTextureColorAttribute = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "aColor"); + + // create texture vertex format + SceGxmVertexAttribute textureVertexAttributes[3]; + SceGxmVertexStream textureVertexStreams[1]; + /* x,y: 2 float 32 bits */ + textureVertexAttributes[0].streamIndex = 0; + textureVertexAttributes[0].offset = 0; + textureVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; + textureVertexAttributes[0].componentCount = 2; // (x, y) + textureVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramTexturePositionAttribute); + /* u,v: 2 floats 32 bits */ + textureVertexAttributes[1].streamIndex = 0; + textureVertexAttributes[1].offset = 8; // (x, y) * 4 = 8 bytes + textureVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; + textureVertexAttributes[1].componentCount = 2; // (u, v) + textureVertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(paramTextureTexcoordAttribute); + /* r,g,b,a: 4 unsigned chars 32 bits */ + textureVertexAttributes[2].streamIndex = 0; + textureVertexAttributes[2].offset = 16; // (x, y, u, v) * 4 = 16 bytes + textureVertexAttributes[2].format = SCE_GXM_ATTRIBUTE_FORMAT_U8N; + textureVertexAttributes[2].componentCount = 4; // (r, g, b, a) + textureVertexAttributes[2].regIndex = sceGxmProgramParameterGetResourceIndex(paramTextureColorAttribute); + // 16 bit (short) indices + textureVertexStreams[0].stride = sizeof(texture_vertex); + textureVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT; + + // create texture shaders + err = sceGxmShaderPatcherCreateVertexProgram( + data->shaderPatcher, + data->textureVertexProgramId, + textureVertexAttributes, + 3, + textureVertexStreams, + 1, + &data->textureVertexProgram + ); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create program (texture vertex) failed: %x\n", err); + return err; + } + + } + + // Create variations of the fragment program based on blending mode + make_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_none, &blend_info_none); + make_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_blend, &blend_info_blend); + make_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_add, &blend_info_add); + make_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mod, &blend_info_mod); + make_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mul, &blend_info_mul); + + { + // Default to blend blending mode + fragment_programs *in = &data->blendFragmentPrograms.blend_mode_blend; + + data->colorFragmentProgram = in->color; + data->textureFragmentProgram = in->texture; + + } + + // find vertex uniforms by name and cache parameter information + data->clearClearColorParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(clearFragmentProgramGxp, "uClearColor"); + data->colorWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(colorVertexProgramGxp, "wvp"); + data->textureWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(textureVertexProgramGxp, "wvp"); + + // Allocate memory for the memory pool + data->pool_addr[0] = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW, + VITA_GXM_POOL_SIZE, + sizeof(void *), + SCE_GXM_MEMORY_ATTRIB_READ, + &data->poolUid[0] + ); + + data->pool_addr[1] = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW, + VITA_GXM_POOL_SIZE, + sizeof(void *), + SCE_GXM_MEMORY_ATTRIB_READ, + &data->poolUid[1] + ); + + init_orthographic_matrix(data->ortho_matrix, 0.0f, VITA_GXM_SCREEN_WIDTH, VITA_GXM_SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f); + + data->backBufferIndex = 0; + data->frontBufferIndex = 0; + data->pool_index = 0; + data->current_pool = 0; + data->currentBlendMode = SDL_BLENDMODE_BLEND; + + return 0; +} + +void gxm_finish(SDL_Renderer *renderer) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + + // wait until rendering is done + sceGxmFinish(data->gxm_context); + + // clean up allocations + sceGxmShaderPatcherReleaseFragmentProgram(data->shaderPatcher, data->clearFragmentProgram); + sceGxmShaderPatcherReleaseVertexProgram(data->shaderPatcher, data->clearVertexProgram); + sceGxmShaderPatcherReleaseVertexProgram(data->shaderPatcher, data->colorVertexProgram); + sceGxmShaderPatcherReleaseVertexProgram(data->shaderPatcher, data->textureVertexProgram); + + + free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_none); + free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_blend); + free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_add); + free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mod); + free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mul); + + mem_gpu_free(data->linearIndicesUid); + mem_gpu_free(data->clearVerticesUid); + + // wait until display queue is finished before deallocating display buffers + sceGxmDisplayQueueFinish(); + + // clean up display queue + mem_gpu_free(data->depthBufferUid); + + for (size_t i = 0; i < VITA_GXM_BUFFERS; i++) + { + // clear the buffer then deallocate + SDL_memset(data->displayBufferData[i], 0, VITA_GXM_SCREEN_HEIGHT * VITA_GXM_SCREEN_STRIDE * 4); + mem_gpu_free(data->displayBufferUid[i]); + + // destroy the sync object + sceGxmSyncObjectDestroy(data->displayBufferSync[i]); + } + + // Free the depth and stencil buffer + mem_gpu_free(data->depthBufferUid); + mem_gpu_free(data->stencilBufferUid); + + // unregister programs and destroy shader patcher + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->clearFragmentProgramId); + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->clearVertexProgramId); + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->colorFragmentProgramId); + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->colorVertexProgramId); + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureFragmentProgramId); + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureVertexProgramId); + + sceGxmShaderPatcherDestroy(data->shaderPatcher); + mem_fragment_usse_free(data->patcherFragmentUsseUid); + mem_vertex_usse_free(data->patcherVertexUsseUid); + mem_gpu_free(data->patcherBufferUid); + + // destroy the render target + sceGxmDestroyRenderTarget(data->renderTarget); + + // destroy the gxm context + sceGxmDestroyContext(data->gxm_context); + mem_fragment_usse_free(data->fragmentUsseRingBufferUid); + mem_gpu_free(data->fragmentRingBufferUid); + mem_gpu_free(data->vertexRingBufferUid); + mem_gpu_free(data->vdmRingBufferUid); + SDL_free(data->contextParams.hostMem); + + mem_gpu_free(data->poolUid[0]); + mem_gpu_free(data->poolUid[1]); + + // terminate libgxm + sceGxmTerminate(); +} + +// textures + +void +free_gxm_texture(gxm_texture *texture) +{ + if (texture) { + if (texture->gxm_rendertarget) { + sceGxmDestroyRenderTarget(texture->gxm_rendertarget); + } + if (texture->depth_UID) { + mem_gpu_free(texture->depth_UID); + } + mem_gpu_free(texture->data_UID); + SDL_free(texture); + } +} + +SceGxmTextureFormat +gxm_texture_get_format(const gxm_texture *texture) +{ + return sceGxmTextureGetFormat(&texture->gxm_tex); +} + +unsigned int +gxm_texture_get_width(const gxm_texture *texture) +{ + return sceGxmTextureGetWidth(&texture->gxm_tex); +} + +unsigned int +gxm_texture_get_height(const gxm_texture *texture) +{ + return sceGxmTextureGetHeight(&texture->gxm_tex); +} + +unsigned int +gxm_texture_get_stride(const gxm_texture *texture) +{ + return ((gxm_texture_get_width(texture) + 7) & ~7) + * tex_format_to_bytespp(gxm_texture_get_format(texture)); +} + +void * +gxm_texture_get_datap(const gxm_texture *texture) +{ + return sceGxmTextureGetData(&texture->gxm_tex); +} + +gxm_texture * +create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget) +{ + gxm_texture *texture = SDL_calloc(1, sizeof(gxm_texture)); + const int tex_size = ((w + 7) & ~ 7) * h * tex_format_to_bytespp(format); + void *texture_data; + + if (!texture) + return NULL; + + /* Allocate a GPU buffer for the texture */ + texture_data = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + tex_size, + SCE_GXM_TEXTURE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &texture->data_UID + ); + + /* Try SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE in case we're out of VRAM */ + if (!texture_data) { + SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "CDRAM texture allocation failed\n"); + texture_data = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + tex_size, + SCE_GXM_TEXTURE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &texture->data_UID + ); + } + + if (!texture_data) { + SDL_free(texture); + return NULL; + } + + /* Clear the texture */ + SDL_memset(texture_data, 0, tex_size); + + /* Create the gxm texture */ + sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, w, h, 0); + + if (isRenderTarget) { + void *depthBufferData; + const uint32_t alignedWidth = ALIGN(w, SCE_GXM_TILE_SIZEX); + const uint32_t alignedHeight = ALIGN(h, SCE_GXM_TILE_SIZEY); + uint32_t sampleCount = alignedWidth*alignedHeight; + uint32_t depthStrideInSamples = alignedWidth; + const uint32_t alignedColorSurfaceStride = ALIGN(w, 8); + + int err = sceGxmColorSurfaceInit( + &texture->gxm_colorsurface, + SCE_GXM_COLOR_FORMAT_A8B8G8R8, + SCE_GXM_COLOR_SURFACE_LINEAR, + SCE_GXM_COLOR_SURFACE_SCALE_NONE, + SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT, + w, + h, + alignedColorSurfaceStride, + texture_data + ); + + if (err < 0) { + free_gxm_texture(texture); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %d\n", err); + return NULL; + } + + // allocate it + depthBufferData = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + 4*sampleCount, + SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &texture->depth_UID); + + // create the SceGxmDepthStencilSurface structure + err = sceGxmDepthStencilSurfaceInit( + &texture->gxm_depthstencil, + SCE_GXM_DEPTH_STENCIL_FORMAT_S8D24, + SCE_GXM_DEPTH_STENCIL_SURFACE_TILED, + depthStrideInSamples, + depthBufferData, + NULL); + + if (err < 0) { + free_gxm_texture(texture); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %d\n", err); + return NULL; + } + + { + SceGxmRenderTarget *tgt = NULL; + + // set up parameters + SceGxmRenderTargetParams renderTargetParams; + SDL_memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams)); + renderTargetParams.flags = 0; + renderTargetParams.width = w; + renderTargetParams.height = h; + renderTargetParams.scenesPerFrame = 1; + renderTargetParams.multisampleMode = SCE_GXM_MULTISAMPLE_NONE; + renderTargetParams.multisampleLocations = 0; + renderTargetParams.driverMemBlock = -1; + + // create the render target + err = sceGxmCreateRenderTarget(&renderTargetParams, &tgt); + + texture->gxm_rendertarget = tgt; + + if (err < 0) { + free_gxm_texture(texture); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %d\n", err); + return NULL; + } + } + + } + + return texture; +} + +void +gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter) +{ + sceGxmTextureSetMinFilter(&texture->gxm_tex, min_filter); + sceGxmTextureSetMagFilter(&texture->gxm_tex, mag_filter); +} + +static unsigned int back_buffer_index_for_common_dialog = 0; +static unsigned int front_buffer_index_for_common_dialog = 0; +struct +{ + VITA_GXM_DisplayData displayData; + SceGxmSyncObject* sync; + SceGxmColorSurface surf; + SceUID uid; +} buffer_for_common_dialog[VITA_GXM_BUFFERS]; + +void gxm_minimal_init_for_common_dialog(void) +{ + SceGxmInitializeParams initializeParams; + SDL_zero(initializeParams); + initializeParams.flags = 0; + initializeParams.displayQueueMaxPendingCount = VITA_GXM_PENDING_SWAPS; + initializeParams.displayQueueCallback = display_callback; + initializeParams.displayQueueCallbackDataSize = sizeof(VITA_GXM_DisplayData); + initializeParams.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE; + sceGxmInitialize(&initializeParams); +} + +void gxm_minimal_term_for_common_dialog(void) +{ + sceGxmTerminate(); +} + +void gxm_init_for_common_dialog(void) +{ + for (int i = 0; i < VITA_GXM_BUFFERS; i += 1) + { + buffer_for_common_dialog[i].displayData.wait_vblank = SDL_TRUE; + buffer_for_common_dialog[i].displayData.address = mem_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT, + SCE_GXM_COLOR_SURFACE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &buffer_for_common_dialog[i].uid); + sceGxmColorSurfaceInit( + &buffer_for_common_dialog[i].surf, + VITA_GXM_PIXEL_FORMAT, + SCE_GXM_COLOR_SURFACE_LINEAR, + SCE_GXM_COLOR_SURFACE_SCALE_NONE, + SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT, + VITA_GXM_SCREEN_WIDTH, + VITA_GXM_SCREEN_HEIGHT, + VITA_GXM_SCREEN_STRIDE, + buffer_for_common_dialog[i].displayData.address + ); + sceGxmSyncObjectCreate(&buffer_for_common_dialog[i].sync); + } + sceGxmDisplayQueueFinish(); +} + +void gxm_swap_for_common_dialog(void) +{ + SceCommonDialogUpdateParam updateParam; + SDL_zero(updateParam); + updateParam.renderTarget.colorFormat = VITA_GXM_PIXEL_FORMAT; + updateParam.renderTarget.surfaceType = SCE_GXM_COLOR_SURFACE_LINEAR; + updateParam.renderTarget.width = VITA_GXM_SCREEN_WIDTH; + updateParam.renderTarget.height = VITA_GXM_SCREEN_HEIGHT; + updateParam.renderTarget.strideInPixels = VITA_GXM_SCREEN_STRIDE; + + updateParam.renderTarget.colorSurfaceData = buffer_for_common_dialog[back_buffer_index_for_common_dialog].displayData.address; + + updateParam.displaySyncObject = buffer_for_common_dialog[back_buffer_index_for_common_dialog].sync; + SDL_memset(buffer_for_common_dialog[back_buffer_index_for_common_dialog].displayData.address, 0, 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT); + sceCommonDialogUpdate(&updateParam); + + sceGxmDisplayQueueAddEntry(buffer_for_common_dialog[front_buffer_index_for_common_dialog].sync, buffer_for_common_dialog[back_buffer_index_for_common_dialog].sync, &buffer_for_common_dialog[back_buffer_index_for_common_dialog].displayData); + front_buffer_index_for_common_dialog = back_buffer_index_for_common_dialog; + back_buffer_index_for_common_dialog = (back_buffer_index_for_common_dialog + 1) % VITA_GXM_BUFFERS; +} + +void gxm_term_for_common_dialog(void) +{ + sceGxmDisplayQueueFinish(); + for (int i = 0; i < VITA_GXM_BUFFERS; i += 1) + { + mem_gpu_free(buffer_for_common_dialog[i].uid); + sceGxmSyncObjectDestroy(buffer_for_common_dialog[i].sync); + } +} + +#endif /* SDL_VIDEO_RENDER_VITA_GXM */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.h b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.h new file mode 100644 index 000000000..351bdc2e6 --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.h @@ -0,0 +1,70 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_RENDER_VITA_GXM_TOOLS_H +#define SDL_RENDER_VITA_GXM_TOOLS_H + +#include "../../SDL_internal.h" + +#include "SDL_hints.h" +#include "../SDL_sysrender.h" + +#include +#include +#include +#include +#include +#include + +#include "SDL_render_vita_gxm_types.h" + +void +init_orthographic_matrix(float *m, float left, float right, float bottom, float top, float near, float far); + +void *pool_malloc(VITA_GXM_RenderData *data, unsigned int size); +void *pool_memalign(VITA_GXM_RenderData *data, unsigned int size, unsigned int alignment); + +void set_clip_rectangle(VITA_GXM_RenderData *data, int x_min, int y_min, int x_max, int y_max); +void unset_clip_rectangle(VITA_GXM_RenderData *data); + +int gxm_init(SDL_Renderer *renderer); +void gxm_finish(SDL_Renderer *renderer); + +gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget); +void free_gxm_texture(gxm_texture *texture); + +void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter); +SceGxmTextureFormat gxm_texture_get_format(const gxm_texture *texture); + +unsigned int gxm_texture_get_width(const gxm_texture *texture); +unsigned int gxm_texture_get_height(const gxm_texture *texture); +unsigned int gxm_texture_get_stride(const gxm_texture *texture); +void *gxm_texture_get_datap(const gxm_texture *texture); + +void gxm_minimal_init_for_common_dialog(void); +void gxm_minimal_term_for_common_dialog(void); +void gxm_init_for_common_dialog(void); +void gxm_swap_for_common_dialog(void); +void gxm_term_for_common_dialog(void); + +#endif /* SDL_RENDER_VITA_GXM_TOOLS_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_types.h b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_types.h new file mode 100644 index 000000000..898a92d9c --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_types.h @@ -0,0 +1,201 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_RENDER_VITA_GXM_TYPES_H +#define SDL_RENDER_VITA_GXM_TYPES_H + +#include "../../SDL_internal.h" + +#include "SDL_hints.h" +#include "../SDL_sysrender.h" + +#include +#include +#include +#include +#include +#include + +#include + +#define VITA_GXM_SCREEN_WIDTH 960 +#define VITA_GXM_SCREEN_HEIGHT 544 +#define VITA_GXM_SCREEN_STRIDE 960 + +#define VITA_GXM_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8B8G8R8 +#define VITA_GXM_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8 + +#define VITA_GXM_BUFFERS 3 +#define VITA_GXM_PENDING_SWAPS 2 +#define VITA_GXM_POOL_SIZE 2 * 1024 * 1024 + +typedef struct +{ + void *address; + Uint8 wait_vblank; +} VITA_GXM_DisplayData; + +typedef struct clear_vertex { + float x; + float y; +} clear_vertex; + +typedef struct color_vertex { + float x; + float y; + SDL_Color color; +} color_vertex; + +typedef struct texture_vertex { + float x; + float y; + float u; + float v; + SDL_Color color; +} texture_vertex; + +typedef struct gxm_texture { + SceGxmTexture gxm_tex; + SceUID data_UID; + SceGxmRenderTarget *gxm_rendertarget; + SceGxmColorSurface gxm_colorsurface; + SceGxmDepthStencilSurface gxm_depthstencil; + SceUID depth_UID; +} gxm_texture; + +typedef struct fragment_programs { + SceGxmFragmentProgram *color; + SceGxmFragmentProgram *texture; +} fragment_programs; + +typedef struct blend_fragment_programs { + fragment_programs blend_mode_none; + fragment_programs blend_mode_blend; + fragment_programs blend_mode_add; + fragment_programs blend_mode_mod; + fragment_programs blend_mode_mul; +} blend_fragment_programs; + +typedef struct +{ + SDL_Rect viewport; + SDL_bool viewport_dirty; + SDL_Texture *texture; + SDL_Texture *target; + SDL_Color color; + SceGxmFragmentProgram *fragment_program; + SceGxmVertexProgram *vertex_program; + int last_command; + + SDL_bool cliprect_enabled_dirty; + SDL_bool cliprect_enabled; + SDL_bool cliprect_dirty; + SDL_Rect cliprect; + SDL_bool texturing; + SDL_Color clear_color; + int drawablew; + int drawableh; +} gxm_drawstate_cache; + +typedef struct +{ + SDL_bool initialized; + SDL_bool drawing; + + unsigned int psm; + unsigned int bpp; + + int currentBlendMode; + + VITA_GXM_DisplayData displayData; + + SceUID vdmRingBufferUid; + SceUID vertexRingBufferUid; + SceUID fragmentRingBufferUid; + SceUID fragmentUsseRingBufferUid; + SceGxmContextParams contextParams; + SceGxmContext *gxm_context; + SceGxmRenderTarget *renderTarget; + SceUID displayBufferUid[VITA_GXM_BUFFERS]; + void *displayBufferData[VITA_GXM_BUFFERS]; + SceGxmColorSurface displaySurface[VITA_GXM_BUFFERS]; + SceGxmSyncObject *displayBufferSync[VITA_GXM_BUFFERS]; + + SceUID depthBufferUid; + SceUID stencilBufferUid; + SceGxmDepthStencilSurface depthSurface; + void *depthBufferData; + void *stencilBufferData; + + unsigned int backBufferIndex; + unsigned int frontBufferIndex; + + void* pool_addr[2]; + SceUID poolUid[2]; + unsigned int pool_index; + unsigned int current_pool; + + float ortho_matrix[4*4]; + + SceGxmVertexProgram *colorVertexProgram; + SceGxmFragmentProgram *colorFragmentProgram; + SceGxmVertexProgram *textureVertexProgram; + SceGxmFragmentProgram *textureFragmentProgram; + SceGxmProgramParameter *clearClearColorParam; + SceGxmProgramParameter *colorWvpParam; + SceGxmProgramParameter *textureWvpParam; + + SceGxmShaderPatcher *shaderPatcher; + SceGxmVertexProgram *clearVertexProgram; + SceGxmFragmentProgram *clearFragmentProgram; + + SceGxmShaderPatcherId clearVertexProgramId; + SceGxmShaderPatcherId clearFragmentProgramId; + SceGxmShaderPatcherId colorVertexProgramId; + SceGxmShaderPatcherId colorFragmentProgramId; + SceGxmShaderPatcherId textureVertexProgramId; + SceGxmShaderPatcherId textureFragmentProgramId; + + SceUID patcherBufferUid; + SceUID patcherVertexUsseUid; + SceUID patcherFragmentUsseUid; + + SceUID clearVerticesUid; + SceUID linearIndicesUid; + clear_vertex *clearVertices; + uint16_t *linearIndices; + + blend_fragment_programs blendFragmentPrograms; + + gxm_drawstate_cache drawstate; +} VITA_GXM_RenderData; + +typedef struct +{ + gxm_texture *tex; + unsigned int pitch; + unsigned int w; + unsigned int h; +} VITA_GXM_TextureData; + +#endif /* SDL_RENDER_VITA_GXM_TYPES_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/render/vitagxm/shader_src/clear_f.cg b/Engine/lib/sdl/src/render/vitagxm/shader_src/clear_f.cg new file mode 100644 index 000000000..6d8fb3b72 --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/shader_src/clear_f.cg @@ -0,0 +1,4 @@ +float4 main( uniform float4 uClearColor) : COLOR +{ + return uClearColor; +} diff --git a/Engine/lib/sdl/src/render/vitagxm/shader_src/clear_v.cg b/Engine/lib/sdl/src/render/vitagxm/shader_src/clear_v.cg new file mode 100644 index 000000000..ee5aa9fce --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/shader_src/clear_v.cg @@ -0,0 +1,4 @@ +float4 main(float2 aPosition) : POSITION +{ + return float4(aPosition, 1.f, 1.f); +} diff --git a/Engine/lib/sdl/src/render/vitagxm/shader_src/color_f.cg b/Engine/lib/sdl/src/render/vitagxm/shader_src/color_f.cg new file mode 100644 index 000000000..dc87c2a11 --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/shader_src/color_f.cg @@ -0,0 +1,4 @@ +float4 main(float4 vColor : COLOR) +{ + return vColor; +} diff --git a/Engine/lib/sdl/src/render/vitagxm/shader_src/color_v.cg b/Engine/lib/sdl/src/render/vitagxm/shader_src/color_v.cg new file mode 100644 index 000000000..49660995e --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/shader_src/color_v.cg @@ -0,0 +1,13 @@ +void main( + float2 aPosition, + float4 aColor, + uniform float4x4 wvp, + out float4 vPosition : POSITION, + out float4 vColor : COLOR, + out float pSize : PSIZE +) +{ + vPosition = mul(float4(aPosition, 1.f, 0.5f), wvp); + vColor = aColor; + pSize = 1.f; +} diff --git a/Engine/lib/sdl/src/render/vitagxm/shader_src/texture_f.cg b/Engine/lib/sdl/src/render/vitagxm/shader_src/texture_f.cg new file mode 100644 index 000000000..a1f63b8ef --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/shader_src/texture_f.cg @@ -0,0 +1,4 @@ +float4 main(float2 vTexcoord : TEXCOORD0, float4 vColor : COLOR, uniform sampler2D tex) +{ + return tex2D(tex, vTexcoord) * vColor; +} diff --git a/Engine/lib/sdl/src/render/vitagxm/shader_src/texture_v.cg b/Engine/lib/sdl/src/render/vitagxm/shader_src/texture_v.cg new file mode 100644 index 000000000..9e05e9a80 --- /dev/null +++ b/Engine/lib/sdl/src/render/vitagxm/shader_src/texture_v.cg @@ -0,0 +1,14 @@ +void main( + float2 aPosition, + float2 aTexcoord, + float4 aColor, + uniform float4x4 wvp, + out float4 vPosition : POSITION, + out float4 vColor : COLOR, + out float2 vTexcoord : TEXCOORD0 +) +{ + vPosition = mul(float4(aPosition, 1.f, 0.5f), wvp); + vTexcoord = aTexcoord; + vColor = aColor; +} diff --git a/Engine/lib/sdl/src/sensor/SDL_sensor.c b/Engine/lib/sdl/src/sensor/SDL_sensor.c index ccf56d978..161026bd2 100644 --- a/Engine/lib/sdl/src/sensor/SDL_sensor.c +++ b/Engine/lib/sdl/src/sensor/SDL_sensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -39,11 +39,14 @@ static SDL_SensorDriver *SDL_sensor_drivers[] = { &SDL_COREMOTION_SensorDriver, #endif #ifdef SDL_SENSOR_WINDOWS - &SDL_WINDOWS_SensorDriver, + &SDL_WINDOWS_SensorDriver, #endif #if defined(SDL_SENSOR_DUMMY) || defined(SDL_SENSOR_DISABLED) &SDL_DUMMY_SensorDriver #endif +#if defined(SDL_SENSOR_VITA) + &SDL_VITA_SensorDriver +#endif }; static SDL_Sensor *SDL_sensors = NULL; static SDL_bool SDL_updating_sensor = SDL_FALSE; diff --git a/Engine/lib/sdl/src/sensor/SDL_sensor_c.h b/Engine/lib/sdl/src/sensor/SDL_sensor_c.h index a66e85834..f116a065a 100644 --- a/Engine/lib/sdl/src/sensor/SDL_sensor_c.h +++ b/Engine/lib/sdl/src/sensor/SDL_sensor_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/sensor/SDL_syssensor.h b/Engine/lib/sdl/src/sensor/SDL_syssensor.h index d4d5c874e..cabbab675 100644 --- a/Engine/lib/sdl/src/sensor/SDL_syssensor.h +++ b/Engine/lib/sdl/src/sensor/SDL_syssensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -100,6 +100,7 @@ extern SDL_SensorDriver SDL_ANDROID_SensorDriver; extern SDL_SensorDriver SDL_COREMOTION_SensorDriver; extern SDL_SensorDriver SDL_WINDOWS_SensorDriver; extern SDL_SensorDriver SDL_DUMMY_SensorDriver; +extern SDL_SensorDriver SDL_VITA_SensorDriver; #endif /* SDL_syssensor_h_ */ diff --git a/Engine/lib/sdl/src/sensor/android/SDL_androidsensor.c b/Engine/lib/sdl/src/sensor/android/SDL_androidsensor.c index 778fc262e..e6cfc2302 100644 --- a/Engine/lib/sdl/src/sensor/android/SDL_androidsensor.c +++ b/Engine/lib/sdl/src/sensor/android/SDL_androidsensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/sensor/android/SDL_androidsensor.h b/Engine/lib/sdl/src/sensor/android/SDL_androidsensor.h index 23c7cfb14..4fc5e6526 100644 --- a/Engine/lib/sdl/src/sensor/android/SDL_androidsensor.h +++ b/Engine/lib/sdl/src/sensor/android/SDL_androidsensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/sensor/coremotion/SDL_coremotionsensor.h b/Engine/lib/sdl/src/sensor/coremotion/SDL_coremotionsensor.h index c97d15f19..664bf3bf1 100644 --- a/Engine/lib/sdl/src/sensor/coremotion/SDL_coremotionsensor.h +++ b/Engine/lib/sdl/src/sensor/coremotion/SDL_coremotionsensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/sensor/coremotion/SDL_coremotionsensor.m b/Engine/lib/sdl/src/sensor/coremotion/SDL_coremotionsensor.m index 0c61df188..7165f6aec 100644 --- a/Engine/lib/sdl/src/sensor/coremotion/SDL_coremotionsensor.m +++ b/Engine/lib/sdl/src/sensor/coremotion/SDL_coremotionsensor.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/sensor/dummy/SDL_dummysensor.c b/Engine/lib/sdl/src/sensor/dummy/SDL_dummysensor.c index 8d2db39a1..469d35dc1 100644 --- a/Engine/lib/sdl/src/sensor/dummy/SDL_dummysensor.c +++ b/Engine/lib/sdl/src/sensor/dummy/SDL_dummysensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/sensor/dummy/SDL_dummysensor.h b/Engine/lib/sdl/src/sensor/dummy/SDL_dummysensor.h index ee66f2fe0..1f3513629 100644 --- a/Engine/lib/sdl/src/sensor/dummy/SDL_dummysensor.h +++ b/Engine/lib/sdl/src/sensor/dummy/SDL_dummysensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/sensor/vita/SDL_vitasensor.c b/Engine/lib/sdl/src/sensor/vita/SDL_vitasensor.c new file mode 100644 index 000000000..5235e9b11 --- /dev/null +++ b/Engine/lib/sdl/src/sensor/vita/SDL_vitasensor.c @@ -0,0 +1,219 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_config.h" + +#if defined(SDL_SENSOR_VITA) + +#include "SDL_error.h" +#include "SDL_sensor.h" +#include "SDL_vitasensor.h" +#include "../SDL_syssensor.h" +#include + +#if !defined(SCE_MOTION_MAX_NUM_STATES) +#define SCE_MOTION_MAX_NUM_STATES 64 +#endif + +typedef struct +{ + SDL_SensorType type; + SDL_SensorID instance_id; +} SDL_VitaSensor; + +static SDL_VitaSensor *SDL_sensors; +static int SDL_sensors_count; + +static int +SDL_VITA_SensorInit(void) +{ + sceMotionReset(); + sceMotionStartSampling(); + // not sure if these are needed, we are reading unfiltered state + sceMotionSetAngleThreshold(0); + sceMotionSetDeadband(SCE_FALSE); + sceMotionSetTiltCorrection(SCE_FALSE); + + SDL_sensors_count = 2; + + SDL_sensors = (SDL_VitaSensor *)SDL_calloc(SDL_sensors_count, sizeof(*SDL_sensors)); + if (!SDL_sensors) { + return SDL_OutOfMemory(); + } + + SDL_sensors[0].type = SDL_SENSOR_ACCEL; + SDL_sensors[0].instance_id = SDL_GetNextSensorInstanceID(); + SDL_sensors[1].type = SDL_SENSOR_GYRO; + SDL_sensors[1].instance_id = SDL_GetNextSensorInstanceID(); + + return 0; +} + +static int +SDL_VITA_SensorGetCount(void) +{ + return SDL_sensors_count; +} + +static void +SDL_VITA_SensorDetect(void) +{ +} + +static const char * +SDL_VITA_SensorGetDeviceName(int device_index) +{ + if (device_index < SDL_sensors_count) { + switch (SDL_sensors[device_index].type) { + case SDL_SENSOR_ACCEL: + return "Accelerometer"; + case SDL_SENSOR_GYRO: + return "Gyro"; + default: + return "Unknown"; + } + } + + return NULL; +} + +static SDL_SensorType +SDL_VITA_SensorGetDeviceType(int device_index) +{ + if (device_index < SDL_sensors_count) { + return SDL_sensors[device_index].type; + } + + return SDL_SENSOR_INVALID; +} + +static int +SDL_VITA_SensorGetDeviceNonPortableType(int device_index) +{ + if (device_index < SDL_sensors_count) { + return SDL_sensors[device_index].type; + } + return -1; +} + +static SDL_SensorID +SDL_VITA_SensorGetDeviceInstanceID(int device_index) +{ + if (device_index < SDL_sensors_count) { + return SDL_sensors[device_index].instance_id; + } + return -1; +} + +static int +SDL_VITA_SensorOpen(SDL_Sensor *sensor, int device_index) +{ + struct sensor_hwdata *hwdata; + + hwdata = (struct sensor_hwdata *)SDL_calloc(1, sizeof(*hwdata)); + if (hwdata == NULL) { + return SDL_OutOfMemory(); + } + sensor->hwdata = hwdata; + + return 0; +} + +static void +SDL_VITA_SensorUpdate(SDL_Sensor *sensor) +{ + int err = 0; + SceMotionSensorState motionState[SCE_MOTION_MAX_NUM_STATES]; + SDL_memset(motionState, 0, sizeof(motionState)); + + err = sceMotionGetSensorState(motionState, SCE_MOTION_MAX_NUM_STATES); + if (err != 0) + { + return; + } + + for (int i = 0; i < SCE_MOTION_MAX_NUM_STATES; i++) + { + if (sensor->hwdata->counter < motionState[i].counter) + { + sensor->hwdata->counter = motionState[i].counter; + switch (sensor->type) + { + case SDL_SENSOR_ACCEL: + { + float data[3]; + data[0] = motionState[i].accelerometer.x * SDL_STANDARD_GRAVITY; + data[1] = motionState[i].accelerometer.y * SDL_STANDARD_GRAVITY; + data[2] = motionState[i].accelerometer.z * SDL_STANDARD_GRAVITY; + if (SDL_memcmp(data, sensor->hwdata->data, sizeof(data)) != 0) { + SDL_PrivateSensorUpdate(sensor, data, SDL_arraysize(data)); + SDL_memcpy(sensor->hwdata->data, data, sizeof(data)); + } + } + break; + case SDL_SENSOR_GYRO: + { + float data[3]; + data[0] = motionState[i].gyro.x; + data[1] = motionState[i].gyro.y; + data[2] = motionState[i].gyro.z; + if (SDL_memcmp(data, sensor->hwdata->data, sizeof(data)) != 0) { + SDL_PrivateSensorUpdate(sensor, data, SDL_arraysize(data)); + SDL_memcpy(sensor->hwdata->data, data, sizeof(data)); + } + } + break; + default: + break; + } + } + } +} + +static void +SDL_VITA_SensorClose(SDL_Sensor *sensor) +{ +} + +static void +SDL_VITA_SensorQuit(void) +{ + sceMotionStopSampling(); +} + +SDL_SensorDriver SDL_VITA_SensorDriver = +{ + SDL_VITA_SensorInit, + SDL_VITA_SensorGetCount, + SDL_VITA_SensorDetect, + SDL_VITA_SensorGetDeviceName, + SDL_VITA_SensorGetDeviceType, + SDL_VITA_SensorGetDeviceNonPortableType, + SDL_VITA_SensorGetDeviceInstanceID, + SDL_VITA_SensorOpen, + SDL_VITA_SensorUpdate, + SDL_VITA_SensorClose, + SDL_VITA_SensorQuit, +}; + +#endif /* SDL_SENSOR_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/sensor/vita/SDL_vitasensor.h b/Engine/lib/sdl/src/sensor/vita/SDL_vitasensor.h new file mode 100644 index 000000000..2fca628fd --- /dev/null +++ b/Engine/lib/sdl/src/sensor/vita/SDL_vitasensor.h @@ -0,0 +1,30 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +/* The private structure used to keep track of a sensor */ +struct sensor_hwdata +{ + float data[3]; + Uint32 counter; +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/sensor/windows/SDL_windowssensor.c b/Engine/lib/sdl/src/sensor/windows/SDL_windowssensor.c index efb7e3fcf..21b119d22 100644 --- a/Engine/lib/sdl/src/sensor/windows/SDL_windowssensor.c +++ b/Engine/lib/sdl/src/sensor/windows/SDL_windowssensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -279,7 +279,7 @@ static int ConnectSensor(ISensor *sensor) hr = ISensor_GetFriendlyName(sensor, &bstr_name); if (SUCCEEDED(hr) && bstr_name) { - name = WIN_StringToUTF8(bstr_name); + name = WIN_StringToUTF8W(bstr_name); } else { name = SDL_strdup("Unknown Sensor"); } @@ -294,6 +294,7 @@ static int ConnectSensor(ISensor *sensor) new_sensors = (SDL_Windows_Sensor *)SDL_realloc(SDL_sensors, (SDL_num_sensors + 1) * sizeof(SDL_Windows_Sensor)); if (new_sensors == NULL) { SDL_UnlockSensors(); + SDL_free(name); return SDL_OutOfMemory(); } @@ -324,7 +325,10 @@ static int DisconnectSensor(ISensor *sensor) for (i = 0; i < SDL_num_sensors; ++i) { old_sensor = &SDL_sensors[i]; if (sensor == old_sensor->sensor) { - ISensor_SetEventSink(sensor, NULL); + /* This call hangs for some reason: + * https://github.com/libsdl-org/SDL/issues/5288 + */ + /*ISensor_SetEventSink(sensor, NULL);*/ ISensor_Release(sensor); SDL_free(old_sensor->name); --SDL_num_sensors; @@ -351,12 +355,14 @@ SDL_WINDOWS_SensorInit(void) hr = CoCreateInstance(&SDL_CLSID_SensorManager, NULL, CLSCTX_INPROC_SERVER, &SDL_IID_SensorManager, (LPVOID *) &SDL_sensor_manager); if (FAILED(hr)) { - return WIN_SetErrorFromHRESULT("Couldn't create the sensor manager", hr); + /* If we can't create a sensor manager (i.e. on Wine), we won't have any sensors, but don't fail the init */ + return 0; /* WIN_SetErrorFromHRESULT("Couldn't create the sensor manager", hr); */ } hr = ISensorManager_SetEventSink(SDL_sensor_manager, &sensor_manager_events); if (FAILED(hr)) { ISensorManager_Release(SDL_sensor_manager); + SDL_sensor_manager = NULL; return WIN_SetErrorFromHRESULT("Couldn't set the sensor manager event sink", hr); } diff --git a/Engine/lib/sdl/src/sensor/windows/SDL_windowssensor.h b/Engine/lib/sdl/src/sensor/windows/SDL_windowssensor.h index ee66f2fe0..1f3513629 100644 --- a/Engine/lib/sdl/src/sensor/windows/SDL_windowssensor.h +++ b/Engine/lib/sdl/src/sensor/windows/SDL_windowssensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/stdlib/SDL_crc32.c b/Engine/lib/sdl/src/stdlib/SDL_crc32.c index 4a5778b39..ff80dcdba 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_crc32.c +++ b/Engine/lib/sdl/src/stdlib/SDL_crc32.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/stdlib/SDL_getenv.c b/Engine/lib/sdl/src/stdlib/SDL_getenv.c index 2bdacd343..add833284 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_getenv.c +++ b/Engine/lib/sdl/src/stdlib/SDL_getenv.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -48,7 +48,7 @@ int SDL_setenv(const char *name, const char *value, int overwrite) { /* Input validation */ - if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { + if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) { return (-1); } @@ -59,7 +59,7 @@ int SDL_setenv(const char *name, const char *value, int overwrite) { /* Input validation */ - if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { + if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) { return (-1); } @@ -82,7 +82,7 @@ SDL_setenv(const char *name, const char *value, int overwrite) char *new_variable; /* Input validation */ - if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { + if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) { return (-1); } @@ -115,7 +115,7 @@ SDL_setenv(const char *name, const char *value, int overwrite) char *new_variable; /* Input validation */ - if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { + if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) { return (-1); } @@ -181,7 +181,7 @@ SDL_getenv(const char *name) #endif /* Input validation */ - if (!name || !*name) { + if (!name || *name == '\0') { return NULL; } @@ -194,7 +194,7 @@ SDL_getenv(const char *name) size_t bufferlen; /* Input validation */ - if (!name || SDL_strlen(name)==0) { + if (!name || *name == '\0') { return NULL; } @@ -222,7 +222,7 @@ SDL_getenv(const char *name) char *value; /* Input validation */ - if (!name || SDL_strlen(name)==0) { + if (!name || *name == '\0') { return NULL; } diff --git a/Engine/lib/sdl/src/stdlib/SDL_iconv.c b/Engine/lib/sdl/src/stdlib/SDL_iconv.c index fa133a88f..3f5c82745 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_iconv.c +++ b/Engine/lib/sdl/src/stdlib/SDL_iconv.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,19 +31,11 @@ #include "SDL_endian.h" #if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) -#include - -/* Depending on which standard the iconv() was implemented with, - iconv() may or may not use const char ** for the inbuf param. - If we get this wrong, it's just a warning, so no big deal. -*/ -#if defined(_XGP6) || defined(__APPLE__) || defined(__RISCOS__) || defined(__FREEBSD__) || \ - defined(__EMSCRIPTEN__) || \ - (defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) || \ - (defined(_NEWLIB_VERSION))) -#define ICONV_INBUF_NONCONST +#ifdef __FreeBSD__ +/* Define LIBICONV_PLUG to use iconv from the base instead of ports and avoid linker errors. */ +#define LIBICONV_PLUG 1 #endif - +#include #include SDL_COMPILE_TIME_ASSERT(iconv_t, sizeof (iconv_t) <= sizeof (SDL_iconv_t)); @@ -51,13 +43,13 @@ SDL_COMPILE_TIME_ASSERT(iconv_t, sizeof (iconv_t) <= sizeof (SDL_iconv_t)); SDL_iconv_t SDL_iconv_open(const char *tocode, const char *fromcode) { - return (SDL_iconv_t) ((size_t) iconv_open(tocode, fromcode)); + return (SDL_iconv_t) ((uintptr_t) iconv_open(tocode, fromcode)); } int SDL_iconv_close(SDL_iconv_t cd) { - return iconv_close((iconv_t) ((size_t) cd)); + return iconv_close((iconv_t) ((uintptr_t) cd)); } size_t @@ -65,12 +57,9 @@ SDL_iconv(SDL_iconv_t cd, const char **inbuf, size_t * inbytesleft, char **outbuf, size_t * outbytesleft) { - size_t retCode; -#ifdef ICONV_INBUF_NONCONST - retCode = iconv((iconv_t) ((size_t) cd), (char **) inbuf, inbytesleft, outbuf, outbytesleft); -#else - retCode = iconv((iconv_t) ((size_t) cd), inbuf, inbytesleft, outbuf, outbytesleft); -#endif + /* iconv's second parameter may or may not be `const char const *` depending on the + C runtime's whims. Casting to void * seems to make everyone happy, though. */ + const size_t retCode = iconv((iconv_t) ((uintptr_t) cd), (void *) inbuf, inbytesleft, outbuf, outbytesleft); if (retCode == (size_t) - 1) { switch (errno) { case E2BIG: @@ -142,6 +131,11 @@ static struct { "US-ASCII", ENCODING_ASCII }, { "8859-1", ENCODING_LATIN1 }, { "ISO-8859-1", ENCODING_LATIN1 }, +#if defined(__WIN32__) || defined(__OS2__) + { "WCHAR_T", ENCODING_UTF16LE }, +#else + { "WCHAR_T", ENCODING_UCS4NATIVE }, +#endif { "UTF8", ENCODING_UTF8 }, { "UTF-8", ENCODING_UTF8 }, { "UTF16", ENCODING_UTF16 }, @@ -365,33 +359,7 @@ SDL_iconv(SDL_iconv_t cd, Uint8 *p = (Uint8 *) src; size_t left = 0; SDL_bool overlong = SDL_FALSE; - if (p[0] >= 0xFC) { - if ((p[0] & 0xFE) != 0xFC) { - /* Skip illegal sequences - return SDL_ICONV_EILSEQ; - */ - ch = UNKNOWN_UNICODE; - } else { - if (p[0] == 0xFC && srclen > 1 && (p[1] & 0xFC) == 0x80) { - overlong = SDL_TRUE; - } - ch = (Uint32) (p[0] & 0x01); - left = 5; - } - } else if (p[0] >= 0xF8) { - if ((p[0] & 0xFC) != 0xF8) { - /* Skip illegal sequences - return SDL_ICONV_EILSEQ; - */ - ch = UNKNOWN_UNICODE; - } else { - if (p[0] == 0xF8 && srclen > 1 && (p[1] & 0xF8) == 0x80) { - overlong = SDL_TRUE; - } - ch = (Uint32) (p[0] & 0x03); - left = 4; - } - } else if (p[0] >= 0xF0) { + if (p[0] >= 0xF0) { if ((p[0] & 0xF8) != 0xF0) { /* Skip illegal sequences return SDL_ICONV_EILSEQ; @@ -666,7 +634,7 @@ SDL_iconv(SDL_iconv_t cd, p[2] = 0x80 | (Uint8) (ch & 0x3F); dst += 3; dstlen -= 3; - } else if (ch <= 0x1FFFFF) { + } else { if (dstlen < 4) { return SDL_ICONV_E2BIG; } @@ -676,29 +644,6 @@ SDL_iconv(SDL_iconv_t cd, p[3] = 0x80 | (Uint8) (ch & 0x3F); dst += 4; dstlen -= 4; - } else if (ch <= 0x3FFFFFF) { - if (dstlen < 5) { - return SDL_ICONV_E2BIG; - } - p[0] = 0xF8 | (Uint8) ((ch >> 24) & 0x03); - p[1] = 0x80 | (Uint8) ((ch >> 18) & 0x3F); - p[2] = 0x80 | (Uint8) ((ch >> 12) & 0x3F); - p[3] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); - p[4] = 0x80 | (Uint8) (ch & 0x3F); - dst += 5; - dstlen -= 5; - } else { - if (dstlen < 6) { - return SDL_ICONV_E2BIG; - } - p[0] = 0xFC | (Uint8) ((ch >> 30) & 0x01); - p[1] = 0x80 | (Uint8) ((ch >> 24) & 0x3F); - p[2] = 0x80 | (Uint8) ((ch >> 18) & 0x3F); - p[3] = 0x80 | (Uint8) ((ch >> 12) & 0x3F); - p[4] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); - p[5] = 0x80 | (Uint8) (ch & 0x3F); - dst += 6; - dstlen -= 6; } } break; @@ -798,7 +743,7 @@ SDL_iconv(SDL_iconv_t cd, if (ch > 0x10FFFF) { ch = UNKNOWN_UNICODE; } - /* fallthrough */ + SDL_FALLTHROUGH; case ENCODING_UCS4BE: if (ch > 0x7FFFFFFF) { ch = UNKNOWN_UNICODE; @@ -820,7 +765,7 @@ SDL_iconv(SDL_iconv_t cd, if (ch > 0x10FFFF) { ch = UNKNOWN_UNICODE; } - /* fallthrough */ + SDL_FALLTHROUGH; case ENCODING_UCS4LE: if (ch > 0x7FFFFFFF) { ch = UNKNOWN_UNICODE; @@ -907,6 +852,7 @@ SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, stringsize *= 2; string = (char *) SDL_realloc(string, stringsize); if (!string) { + SDL_free(oldstring); SDL_iconv_close(cd); return NULL; } @@ -927,8 +873,7 @@ SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, break; } /* Avoid infinite loops when nothing gets converted */ - if (oldinbytesleft == inbytesleft) - { + if (oldinbytesleft == inbytesleft) { break; } } diff --git a/Engine/lib/sdl/src/stdlib/SDL_malloc.c b/Engine/lib/sdl/src/stdlib/SDL_malloc.c index 7c9f0d63a..b5dd6414f 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_malloc.c +++ b/Engine/lib/sdl/src/stdlib/SDL_malloc.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -485,6 +485,7 @@ DEFAULT_MMAP_THRESHOLD default: 256K #define WIN32 1 #endif /* _WIN32 */ #endif /* WIN32 */ + #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #include @@ -2326,7 +2327,7 @@ static size_t traverse_and_check(mstate m); #define treebin_at(M,i) (&((M)->treebins[i])) /* assign tree index for size S to variable I */ -#if defined(__GNUC__) && defined(i386) +#if defined(__GNUC__) && defined(__i386__) #define compute_tree_index(S, I)\ {\ size_t X = S >> TREEBIN_SHIFT;\ @@ -2391,7 +2392,7 @@ static size_t traverse_and_check(mstate m); /* index corresponding to given bit */ -#if defined(__GNUC__) && defined(i386) +#if defined(__GNUC__) && defined(__i386__) #define compute_bit2idx(X, I)\ {\ unsigned int J;\ diff --git a/Engine/lib/sdl/src/stdlib/SDL_qsort.c b/Engine/lib/sdl/src/stdlib/SDL_qsort.c index 9dc3f4f96..b175f444e 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_qsort.c +++ b/Engine/lib/sdl/src/stdlib/SDL_qsort.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/stdlib/SDL_stdlib.c b/Engine/lib/sdl/src/stdlib/SDL_stdlib.c index 5334a512d..9d785aad5 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_stdlib.c +++ b/Engine/lib/sdl/src/stdlib/SDL_stdlib.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -52,22 +52,22 @@ SDL_atanf(float x) } double -SDL_atan2(double x, double y) +SDL_atan2(double y, double x) { #if defined(HAVE_ATAN2) - return atan2(x, y); + return atan2(y, x); #else - return SDL_uclibc_atan2(x, y); + return SDL_uclibc_atan2(y, x); #endif } float -SDL_atan2f(float x, float y) +SDL_atan2f(float y, float x) { #if defined(HAVE_ATAN2F) - return atan2f(x, y); + return atan2f(y, x); #else - return (float)SDL_atan2((double)x, (double)y); + return (float)SDL_atan2((double)y, (double)x); #endif } @@ -148,7 +148,7 @@ SDL_ceilf(float x) #if defined(HAVE_CEILF) return ceilf(x); #else - return (float)SDL_ceil((float)x); + return (float)SDL_ceil((double)x); #endif } @@ -364,6 +364,50 @@ SDL_powf(float x, float y) #endif } +double +SDL_round(double arg) +{ +#if defined HAVE_ROUND + return round(arg); +#else + if (arg >= 0.0) { + return SDL_floor(arg + 0.5); + } else { + return SDL_ceil(arg - 0.5); + } +#endif +} + +float +SDL_roundf(float arg) +{ +#if defined HAVE_ROUNDF + return roundf(arg); +#else + return (float)SDL_round((double)arg); +#endif +} + +long +SDL_lround(double arg) +{ +#if defined HAVE_LROUND + return lround(arg); +#else + return (long)SDL_round(arg); +#endif +} + +long +SDL_lroundf(float arg) +{ +#if defined HAVE_LROUNDF + return lroundf(arg); +#else + return (long)SDL_round((double)arg); +#endif +} + double SDL_scalbn(double x, int n) { @@ -400,7 +444,7 @@ SDL_sin(double x) #endif } -float +float SDL_sinf(float x) { #if defined(HAVE_SINF) @@ -455,26 +499,45 @@ int SDL_abs(int x) #if defined(HAVE_ABS) return abs(x); #else - return ((x) < 0 ? -(x) : (x)); + return (x < 0) ? -x : x; #endif } #if defined(HAVE_CTYPE_H) +int SDL_isalpha(int x) { return isalpha(x); } +int SDL_isalnum(int x) { return isalnum(x); } int SDL_isdigit(int x) { return isdigit(x); } +int SDL_isxdigit(int x) { return isxdigit(x); } +int SDL_ispunct(int x) { return ispunct(x); } int SDL_isspace(int x) { return isspace(x); } int SDL_isupper(int x) { return isupper(x); } int SDL_islower(int x) { return islower(x); } +int SDL_isprint(int x) { return isprint(x); } +int SDL_isgraph(int x) { return isgraph(x); } +int SDL_iscntrl(int x) { return iscntrl(x); } int SDL_toupper(int x) { return toupper(x); } int SDL_tolower(int x) { return tolower(x); } #else +int SDL_isalpha(int x) { return (SDL_isupper(x)) || (SDL_islower(x)); } +int SDL_isalnum(int x) { return (SDL_isalpha(x)) || (SDL_isdigit(x)); } int SDL_isdigit(int x) { return ((x) >= '0') && ((x) <= '9'); } +int SDL_isxdigit(int x) { return (((x) >= 'A') && ((x) <= 'F')) || (((x) >= 'a') && ((x) <= 'f')) || (SDL_isdigit(x)); } +int SDL_ispunct(int x) { return (SDL_isgraph(x)) && (!SDL_isalnum(x)); } int SDL_isspace(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n') || ((x) == '\f') || ((x) == '\v'); } int SDL_isupper(int x) { return ((x) >= 'A') && ((x) <= 'Z'); } int SDL_islower(int x) { return ((x) >= 'a') && ((x) <= 'z'); } +int SDL_isprint(int x) { return ((x) >= ' ') && ((x) < '\x7f'); } +int SDL_isgraph(int x) { return (SDL_isprint(x)) && ((x) != ' '); } +int SDL_iscntrl(int x) { return (((x) >= '\0') && ((x) <= '\x1f')) || ((x) == '\x7f'); } int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A'+((x)-'a')) : (x); } int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a'+((x)-'A')) : (x); } #endif +#if defined(HAVE_CTYPE_H) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +int SDL_isblank(int x) { return isblank(x); } +#else +int SDL_isblank(int x) { return ((x) == ' ') || ((x) == '\t'); } +#endif #ifndef HAVE_LIBC /* These are some C runtime intrinsics that need to be defined */ diff --git a/Engine/lib/sdl/src/stdlib/SDL_string.c b/Engine/lib/sdl/src/stdlib/SDL_string.c index 44f34601d..133193072 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_string.c +++ b/Engine/lib/sdl/src/stdlib/SDL_string.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,7 +28,15 @@ #include "SDL_stdinc.h" -#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOL) || !defined(HAVE_STRTOUL) || !defined(HAVE_STRTOLL) || !defined(HAVE_STRTOULL) || !defined(HAVE_STRTOD) +#if defined(_MSC_VER) && _MSC_VER <= 1800 +/* Visual Studio 2013 tries to link with _vacopy in the C runtime. Newer versions do an inline assignment */ +#undef va_copy +#define va_copy(dst, src) dst = src +#elif defined(__GNUC__) && (__GNUC__ < 3) +#define va_copy(to, from) __va_copy(to, from) +#endif + +#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOL) || !defined(HAVE_STRTOUL) || !defined(HAVE_STRTOD) || !defined(HAVE_STRTOLL) || !defined(HAVE_STRTOULL) #define SDL_isupperhex(X) (((X) >= 'A') && ((X) <= 'F')) #define SDL_islowerhex(X) (((X) >= 'a') && ((X) <= 'f')) #endif @@ -36,7 +44,7 @@ #define UTF8_IsLeadByte(c) ((c) >= 0xC0 && (c) <= 0xF4) #define UTF8_IsTrailingByte(c) ((c) >= 0x80 && (c) <= 0xBF) -static int UTF8_TrailingBytes(unsigned char c) +static unsigned UTF8_TrailingBytes(unsigned char c) { if (c >= 0xC0 && c <= 0xDF) return 1; @@ -281,7 +289,7 @@ SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len) * execute a 32-bit set. Set first bytes manually if needed until it is * aligned. */ value1 = (Uint8)c; - while ((intptr_t)dstp1 & 0x3) { + while ((uintptr_t)dstp1 & 0x3) { if (len--) { *dstp1++ = value1; } else { @@ -289,7 +297,7 @@ SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len) } } - value4 = (c | (c << 8) | (c << 16) | (c << 24)); + value4 = ((Uint32)c | ((Uint32)c << 8) | ((Uint32)c << 16) | ((Uint32)c << 24)); dstp4 = (Uint32 *) dstp1; left = (len % 4); len /= 4; @@ -329,7 +337,7 @@ SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, using Uint32* pointers, so we need to make sure the pointers are aligned before we loop using them. */ - if (((intptr_t)src & 0x3) || ((intptr_t)dst & 0x3)) { + if (((uintptr_t)src & 0x3) || ((uintptr_t)dst & 0x3)) { /* Do an unaligned byte copy */ Uint8 *srcp1 = (Uint8 *)src; Uint8 *dstp1 = (Uint8 *)dst; @@ -632,20 +640,17 @@ SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_ size_t src_bytes = SDL_strlen(src); size_t bytes = SDL_min(src_bytes, dst_bytes - 1); size_t i = 0; - char trailing_bytes = 0; - if (bytes) - { + unsigned char trailing_bytes = 0; + + if (bytes) { unsigned char c = (unsigned char)src[bytes - 1]; - if (UTF8_IsLeadByte(c)) + if (UTF8_IsLeadByte(c)) { --bytes; - else if (UTF8_IsTrailingByte(c)) - { - for (i = bytes - 1; i != 0; --i) - { + } else if (UTF8_IsTrailingByte(c)) { + for (i = bytes - 1; i != 0; --i) { c = (unsigned char)src[i]; trailing_bytes = UTF8_TrailingBytes(c); - if (trailing_bytes) - { + if (trailing_bytes) { if (bytes - i != trailing_bytes + 1) bytes = i; @@ -656,6 +661,7 @@ SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_ SDL_memcpy(dst, src, bytes); } dst[bytes] = '\0'; + return bytes; } @@ -664,7 +670,7 @@ SDL_utf8strlen(const char *str) { size_t retval = 0; const char *p = str; - char ch; + unsigned char ch; while ((ch = *(p++)) != 0) { /* if top two bits are 1 and 0, it's a continuation byte. */ @@ -928,7 +934,7 @@ int SDL_atoi(const char *string) #ifdef HAVE_ATOI return atoi(string); #else - return SDL_strtol(string, NULL, 0); + return SDL_strtol(string, NULL, 10); #endif /* HAVE_ATOI */ } @@ -1064,13 +1070,16 @@ SDL_strcmp(const char *str1, const char *str2) #if defined(HAVE_STRCMP) return strcmp(str1, str2); #else - while (*str1 && *str2) { - if (*str1 != *str2) + int result; + + while(1) { + result = (int)((unsigned char) *str1 - (unsigned char) *str2); + if (result != 0 || (*str1 == '\0'/* && *str2 == '\0'*/)) break; ++str1; ++str2; } - return (int)((unsigned char) *str1 - (unsigned char) *str2); + return result; #endif /* HAVE_STRCMP */ } @@ -1080,17 +1089,20 @@ SDL_strncmp(const char *str1, const char *str2, size_t maxlen) #if defined(HAVE_STRNCMP) return strncmp(str1, str2, maxlen); #else - while (*str1 && *str2 && maxlen) { - if (*str1 != *str2) + int result; + + while (maxlen) { + result = (int) (unsigned char) *str1 - (unsigned char) *str2; + if (result != 0 || *str1 == '\0'/* && *str2 == '\0'*/) break; ++str1; ++str2; --maxlen; } if (!maxlen) { - return 0; + result = 0; } - return (int) ((unsigned char) *str1 - (unsigned char) *str2); + return result; #endif /* HAVE_STRNCMP */ } @@ -1102,19 +1114,18 @@ SDL_strcasecmp(const char *str1, const char *str2) #elif defined(HAVE__STRICMP) return _stricmp(str1, str2); #else - char a = 0; - char b = 0; - while (*str1 && *str2) { + int a, b, result; + + while (1) { a = SDL_toupper((unsigned char) *str1); b = SDL_toupper((unsigned char) *str2); - if (a != b) + result = a - b; + if (result != 0 || a == 0 /*&& b == 0*/) break; ++str1; ++str2; } - a = SDL_toupper(*str1); - b = SDL_toupper(*str2); - return (int) ((unsigned char) a - (unsigned char) b); + return result; #endif /* HAVE_STRCASECMP */ } @@ -1126,24 +1137,21 @@ SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen) #elif defined(HAVE__STRNICMP) return _strnicmp(str1, str2, maxlen); #else - char a = 0; - char b = 0; - while (*str1 && *str2 && maxlen) { + int a, b, result; + + while (maxlen) { a = SDL_tolower((unsigned char) *str1); b = SDL_tolower((unsigned char) *str2); - if (a != b) + result = a - b; + if (result != 0 || a == 0 /*&& b == 0*/) break; ++str1; ++str2; --maxlen; } - if (maxlen == 0) { - return 0; - } else { - a = SDL_tolower((unsigned char) *str1); - b = SDL_tolower((unsigned char) *str2); - return (int) ((unsigned char) a - (unsigned char) b); - } + if (maxlen == 0) + result = 0; + return result; #endif /* HAVE_STRNCASECMP */ } @@ -1269,7 +1277,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) } } } - /* Fall through to %d handling */ + SDL_FALLTHROUGH; case 'd': if (inttype == DO_LONGLONG) { Sint64 value; @@ -1317,13 +1325,13 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) if (radix == 10) { radix = 8; } - /* Fall through to unsigned handling */ + SDL_FALLTHROUGH; case 'x': case 'X': if (radix == 10) { radix = 16; } - /* Fall through to unsigned handling */ + SDL_FALLTHROUGH; case 'u': if (inttype == DO_LONGLONG) { Uint64 value = 0; @@ -1472,6 +1480,8 @@ int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *f return vsnprintf(text, maxlen, fmt, ap); } #else +#define TEXT_AND_LEN_ARGS (length < maxlen) ? &text[length] : NULL, (length < maxlen) ? (maxlen - length) : 0 + /* FIXME: implement more of the format specifiers */ typedef enum { @@ -1514,25 +1524,27 @@ SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *str filllen = SDL_min(width, maxlen); SDL_memset(text, fill, filllen); text += filllen; - length += filllen; maxlen -= filllen; + length += width; } - slen = SDL_strlcpy(text, string, maxlen); - length += SDL_min(slen, maxlen); + SDL_strlcpy(text, string, maxlen); + length += sz; if (info) { if (info->precision >= 0 && (size_t)info->precision < sz) { slen = (size_t)info->precision; if (slen < maxlen) { - text[slen] = 0; - length -= (sz - slen); + text[slen] = '\0'; } + length -= (sz - slen); } - if (info->force_case == SDL_CASE_LOWER) { - SDL_strlwr(text); - } else if (info->force_case == SDL_CASE_UPPER) { - SDL_strupr(text); + if (maxlen > 1) { + if (info->force_case == SDL_CASE_LOWER) { + SDL_strlwr(text); + } else if (info->force_case == SDL_CASE_UPPER) { + SDL_strupr(text); + } } } return length; @@ -1585,7 +1597,7 @@ SDL_PrintLong(char *text, size_t maxlen, SDL_FormatInfo *info, long value) } SDL_ltoa(value, p, info ? info->radix : 10); - SDL_IntPrecisionAdjust(num, maxlen, info); + SDL_IntPrecisionAdjust(num, sizeof(num), info); return SDL_PrintString(text, maxlen, info, num); } @@ -1595,7 +1607,7 @@ SDL_PrintUnsignedLong(char *text, size_t maxlen, SDL_FormatInfo *info, unsigned char num[130]; SDL_ultoa(value, num, info ? info->radix : 10); - SDL_IntPrecisionAdjust(num, maxlen, info); + SDL_IntPrecisionAdjust(num, sizeof(num), info); return SDL_PrintString(text, maxlen, info, num); } @@ -1609,7 +1621,7 @@ SDL_PrintLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Sint64 value) } SDL_lltoa(value, p, info ? info->radix : 10); - SDL_IntPrecisionAdjust(num, maxlen, info); + SDL_IntPrecisionAdjust(num, sizeof(num), info); return SDL_PrintString(text, maxlen, info, num); } @@ -1619,126 +1631,79 @@ SDL_PrintUnsignedLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Uint6 char num[130]; SDL_ulltoa(value, num, info ? info->radix : 10); - SDL_IntPrecisionAdjust(num, maxlen, info); + SDL_IntPrecisionAdjust(num, sizeof(num), info); return SDL_PrintString(text, maxlen, info, num); } static size_t SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg) { - int width; - size_t len; - size_t left = maxlen; - char *textstart = text; + size_t length = 0; - if (arg) { - /* This isn't especially accurate, but hey, it's easy. :) */ - unsigned long value; + /* This isn't especially accurate, but hey, it's easy. :) */ + unsigned long value; - if (arg < 0) { - if (left > 1) { - *text = '-'; - --left; - } - ++text; - arg = -arg; - } else if (info->force_sign) { - if (left > 1) { - *text = '+'; - --left; - } - ++text; + if (arg < 0) { + if (length < maxlen) { + text[length] = '-'; } - value = (unsigned long) arg; - len = SDL_PrintUnsignedLong(text, left, NULL, value); - if (len >= left) { - text += (left > 1) ? left - 1 : 0; - left = SDL_min(left, 1); - } else { - text += len; - left -= len; + ++length; + arg = -arg; + } else if (info->force_sign) { + if (length < maxlen) { + text[length] = '+'; } - arg -= value; - if (info->precision < 0) { - info->precision = 6; + ++length; + } + value = (unsigned long) arg; + length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, NULL, value); + arg -= value; + if (info->precision < 0) { + info->precision = 6; + } + if (info->force_type || info->precision > 0) { + int mult = 10; + if (length < maxlen) { + text[length] = '.'; } - if (info->force_type || info->precision > 0) { - int mult = 10; - if (left > 1) { - *text = '.'; - --left; - } - ++text; - while (info->precision-- > 0) { - value = (unsigned long) (arg * mult); - len = SDL_PrintUnsignedLong(text, left, NULL, value); - if (len >= left) { - text += (left > 1) ? left - 1 : 0; - left = SDL_min(left, 1); - } else { - text += len; - left -= len; - } - arg -= (double) value / mult; - mult *= 10; - } - } - } else { - if (left > 1) { - *text = '0'; - --left; - } - ++text; - if (info->force_type) { - if (left > 1) { - *text = '.'; - --left; - } - ++text; + ++length; + while (info->precision-- > 0) { + value = (unsigned long) (arg * mult); + length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, NULL, value); + arg -= (double) value / mult; + mult *= 10; } } - width = info->width - (int)(text - textstart); - if (width > 0) { + if (info->width > 0 && (size_t)info->width > length) { const char fill = info->pad_zeroes ? '0' : ' '; - char *end = text+left-1; - len = (text - textstart); - for (len = (text - textstart); len--; ) { - if ((textstart+len+width) < end) { - *(textstart+len+width) = *(textstart+len); - } - } - len = (size_t)width; - if (len >= left) { - text += (left > 1) ? left - 1 : 0; - left = SDL_min(left, 1); - } else { - text += len; - left -= len; - } + size_t width = info->width - length; + size_t filllen, movelen; - if (end != textstart) { - const size_t filllen = SDL_min(len, ((size_t) (end - textstart)) - 1); - SDL_memset(textstart, fill, filllen); - } + filllen = SDL_min(width, maxlen); + movelen = SDL_min(length, (maxlen - filllen)); + SDL_memmove(&text[filllen], text, movelen); + SDL_memset(text, fill, filllen); + length += width; } - return (text - textstart); + return length; } int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap) { - size_t left = maxlen; - char *textstart = text; + size_t length = 0; + if (!text) { + maxlen = 0; + } if (!fmt) { fmt = ""; } - while (*fmt && left > 1) { + while (*fmt) { if (*fmt == '%') { SDL_bool done = SDL_FALSE; - size_t len = 0; SDL_bool check_flag; SDL_FormatInfo info; enum @@ -1800,18 +1765,18 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, while (!done) { switch (*fmt) { case '%': - if (left > 1) { - *text = '%'; + if (length < maxlen) { + text[length] = '%'; } - len = 1; + ++length; done = SDL_TRUE; break; case 'c': /* char is promoted to int when passed through (...) */ - if (left > 1) { - *text = (char) va_arg(ap, int); + if (length < maxlen) { + text[length] = (char) va_arg(ap, int); } - len = 1; + ++length; done = SDL_TRUE; break; case 'h': @@ -1835,15 +1800,15 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, } switch (inttype) { case DO_INT: - len = SDL_PrintLong(text, left, &info, + length += SDL_PrintLong(TEXT_AND_LEN_ARGS, &info, (long) va_arg(ap, int)); break; case DO_LONG: - len = SDL_PrintLong(text, left, &info, + length += SDL_PrintLong(TEXT_AND_LEN_ARGS, &info, va_arg(ap, long)); break; case DO_LONGLONG: - len = SDL_PrintLongLong(text, left, &info, + length += SDL_PrintLongLong(TEXT_AND_LEN_ARGS, &info, va_arg(ap, Sint64)); break; } @@ -1852,7 +1817,7 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, case 'p': case 'x': info.force_case = SDL_CASE_LOWER; - /* Fall through to 'X' handling */ + SDL_FALLTHROUGH; case 'X': if (info.force_case == SDL_CASE_NOCHANGE) { info.force_case = SDL_CASE_UPPER; @@ -1863,12 +1828,12 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, if (*fmt == 'p') { inttype = DO_LONG; } - /* Fall through to unsigned handling */ + SDL_FALLTHROUGH; case 'o': if (info.radix == 10) { info.radix = 8; } - /* Fall through to unsigned handling */ + SDL_FALLTHROUGH; case 'u': info.force_sign = SDL_FALSE; if (info.precision >= 0) { @@ -1876,23 +1841,23 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, } switch (inttype) { case DO_INT: - len = SDL_PrintUnsignedLong(text, left, &info, + length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, &info, (unsigned long) va_arg(ap, unsigned int)); break; case DO_LONG: - len = SDL_PrintUnsignedLong(text, left, &info, + length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, &info, va_arg(ap, unsigned long)); break; case DO_LONGLONG: - len = SDL_PrintUnsignedLongLong(text, left, &info, + length += SDL_PrintUnsignedLongLong(TEXT_AND_LEN_ARGS, &info, va_arg(ap, Uint64)); break; } done = SDL_TRUE; break; case 'f': - len = SDL_PrintFloat(text, left, &info, va_arg(ap, double)); + length += SDL_PrintFloat(TEXT_AND_LEN_ARGS, &info, va_arg(ap, double)); done = SDL_TRUE; break; case 'S': @@ -1902,18 +1867,18 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, if (wide_arg) { char *arg = SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(wide_arg), (SDL_wcslen(wide_arg)+1)*sizeof(*wide_arg)); info.pad_zeroes = SDL_FALSE; - len = SDL_PrintString(text, left, &info, arg); + length += SDL_PrintString(TEXT_AND_LEN_ARGS, &info, arg); SDL_free(arg); } else { info.pad_zeroes = SDL_FALSE; - len = SDL_PrintString(text, left, &info, NULL); + length += SDL_PrintString(TEXT_AND_LEN_ARGS, &info, NULL); } done = SDL_TRUE; } break; case 's': info.pad_zeroes = SDL_FALSE; - len = SDL_PrintString(text, left, &info, va_arg(ap, char *)); + length += SDL_PrintString(TEXT_AND_LEN_ARGS, &info, va_arg(ap, char *)); done = SDL_TRUE; break; default: @@ -1922,23 +1887,80 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, } ++fmt; } - if (len >= left) { - text += (left > 1) ? left - 1 : 0; - left = SDL_min(left, 1); - } else { - text += len; - left -= len; - } } else { - *text++ = *fmt++; - --left; + if (length < maxlen) { + text[length] = *fmt; + } + ++fmt; + ++length; } } - if (left > 0) { - *text = '\0'; + if (length < maxlen) { + text[length] = '\0'; + } else if (maxlen > 0) { + text[maxlen - 1] = '\0'; } - return (int)(text - textstart); + return (int)length; + } + +#undef TEXT_AND_LEN_ARGS #endif /* HAVE_VSNPRINTF */ +int +SDL_asprintf(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + int retval; + + va_start(ap, fmt); + retval = SDL_vasprintf(strp, fmt, ap); + va_end(ap); + + return retval; +} + +int +SDL_vasprintf(char **strp, const char *fmt, va_list ap) +{ + int retval; + int size = 100; /* Guess we need no more than 100 bytes */ + char *p, *np; + va_list aq; + + *strp = NULL; + + p = (char *)SDL_malloc(size); + if (p == NULL) + return -1; + + while (1) { + /* Try to print in the allocated space */ + va_copy(aq, ap); + retval = SDL_vsnprintf(p, size, fmt, aq); + va_end(aq); + + /* Check error code */ + if (retval < 0) + return retval; + + /* If that worked, return the string */ + if (retval < size) { + *strp = p; + return retval; + } + + /* Else try again with more space */ + size = retval + 1; /* Precisely what is needed */ + + np = (char *)SDL_realloc(p, size); + if (np == NULL) { + SDL_free(p); + return -1; + } else { + p = np; + } + } +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/stdlib/SDL_strtokr.c b/Engine/lib/sdl/src/stdlib/SDL_strtokr.c index 3d69363ff..4b624d3fd 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_strtokr.c +++ b/Engine/lib/sdl/src/stdlib/SDL_strtokr.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,12 +28,9 @@ char *SDL_strtokr(char *s1, const char *s2, char **ptr) { -#if defined(HAVE_STRTOK_R) +#ifdef HAVE_STRTOK_R return strtok_r(s1, s2, ptr); -#elif defined(_MSC_VER) && defined(HAVE_STRTOK_S) - return strtok_s(s1, s2, ptr); - #else /* SDL implementation */ /* * Adapted from _PDCLIB_strtok() of PDClib library at diff --git a/Engine/lib/sdl/src/test/SDL_test_assert.c b/Engine/lib/sdl/src/test/SDL_test_assert.c index d8aca4eed..148564ec1 100644 --- a/Engine/lib/sdl/src/test/SDL_test_assert.c +++ b/Engine/lib/sdl/src/test/SDL_test_assert.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -104,7 +104,7 @@ void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription, /* Log pass message */ SDLTest_AssertsPassed++; - SDLTest_Log(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, "Pass"); + SDLTest_Log(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, "Passed"); } /* diff --git a/Engine/lib/sdl/src/test/SDL_test_common.c b/Engine/lib/sdl/src/test/SDL_test_common.c index 72404e02e..48c6c72f0 100644 --- a/Engine/lib/sdl/src/test/SDL_test_common.c +++ b/Engine/lib/sdl/src/test/SDL_test_common.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,12 +30,15 @@ static const char *video_usage[] = { "[--video driver]", "[--renderer driver]", "[--gldebug]", "[--info all|video|modes|render|event]", "[--log all|error|system|audio|video|render|input]", "[--display N]", + "[--metal-window | --opengl-window | --vulkan-window]", "[--fullscreen | --fullscreen-desktop | --windows N]", "[--title title]", "[--icon icon.bmp]", "[--center | --position X,Y]", "[--geometry WxH]", "[--min-geometry WxH]", "[--max-geometry WxH]", "[--logical WxH]", "[--scale N]", "[--depth N]", "[--refresh R]", "[--vsync]", "[--noframe]", - "[--resize]", "[--minimize]", "[--maximize]", "[--grab]", - "[--allow-highdpi]", "[--usable-bounds]" + "[--resizable]", "[--minimize]", "[--maximize]", "[--grab]", "[--keyboard-grab]", + "[--shown]", "[--hidden]", "[--input-focus]", "[--mouse-focus]", + "[--flash-on-focus-loss]", "[--allow-highdpi]", "[--confine-cursor X,Y,W,H]", + "[--usable-bounds]" }; static const char *audio_usage[] = { @@ -218,6 +221,18 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) } return 2; } + if (SDL_strcasecmp(argv[index], "--metal-window") == 0) { + state->window_flags |= SDL_WINDOW_METAL; + return 1; + } + if (SDL_strcasecmp(argv[index], "--opengl-window") == 0) { + state->window_flags |= SDL_WINDOW_OPENGL; + return 1; + } + if (SDL_strcasecmp(argv[index], "--vulkan-window") == 0) { + state->window_flags |= SDL_WINDOW_VULKAN; + return 1; + } if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) { state->window_flags |= SDL_WINDOW_FULLSCREEN; state->num_windows = 1; @@ -234,7 +249,7 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) } if (SDL_strcasecmp(argv[index], "--windows") == 0) { ++index; - if (!argv[index] || !SDL_isdigit(*argv[index])) { + if (!argv[index] || !SDL_isdigit((unsigned char) *argv[index])) { return -1; } if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) { @@ -282,6 +297,34 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) state->window_y = SDL_atoi(y); return 2; } + if (SDL_strcasecmp(argv[index], "--confine-cursor") == 0) { + char *x, *y, *w, *h; + ++index; + if (!argv[index]) { + return -1; + } + x = argv[index]; + y = argv[index]; + #define SEARCHARG(dim) \ + while (*dim && *dim != ',') { \ + ++dim; \ + } \ + if (!*dim) { \ + return -1; \ + } \ + *dim++ = '\0'; + SEARCHARG(y) + w = y; + SEARCHARG(w) + h = w; + SEARCHARG(h) + #undef SEARCHARG + state->confine.x = SDL_atoi(x); + state->confine.y = SDL_atoi(y); + state->confine.w = SDL_atoi(w); + state->confine.h = SDL_atoi(h); + return 2; + } if (SDL_strcasecmp(argv[index], "--usable-bounds") == 0) { /* !!! FIXME: this is a bit of a hack, but I don't want to add a !!! FIXME: flag to the public structure in 2.0.x */ @@ -399,7 +442,7 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) state->window_flags |= SDL_WINDOW_BORDERLESS; return 1; } - if (SDL_strcasecmp(argv[index], "--resize") == 0) { + if (SDL_strcasecmp(argv[index], "--resizable") == 0) { state->window_flags |= SDL_WINDOW_RESIZABLE; return 1; } @@ -411,8 +454,32 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) state->window_flags |= SDL_WINDOW_MAXIMIZED; return 1; } + if (SDL_strcasecmp(argv[index], "--shown") == 0) { + state->window_flags |= SDL_WINDOW_SHOWN; + return 1; + } + if (SDL_strcasecmp(argv[index], "--hidden") == 0) { + state->window_flags |= SDL_WINDOW_HIDDEN; + return 1; + } + if (SDL_strcasecmp(argv[index], "--input-focus") == 0) { + state->window_flags |= SDL_WINDOW_INPUT_FOCUS; + return 1; + } + if (SDL_strcasecmp(argv[index], "--mouse-focus") == 0) { + state->window_flags |= SDL_WINDOW_MOUSE_FOCUS; + return 1; + } + if (SDL_strcasecmp(argv[index], "--flash-on-focus-loss") == 0) { + state->flash_on_focus_loss = SDL_TRUE; + return 1; + } if (SDL_strcasecmp(argv[index], "--grab") == 0) { - state->window_flags |= SDL_WINDOW_INPUT_GRABBED; + state->window_flags |= SDL_WINDOW_MOUSE_GRABBED; + return 1; + } + if (SDL_strcasecmp(argv[index], "--keyboard-grab") == 0) { + state->window_flags |= SDL_WINDOW_KEYBOARD_GRABBED; return 1; } if (SDL_strcasecmp(argv[index], "--rate") == 0) { @@ -595,6 +662,170 @@ SDLTest_CommonDefaultArgs(SDLTest_CommonState *state, const int argc, char **arg return SDL_TRUE; } +static void +SDLTest_PrintDisplayOrientation(char* text, size_t maxlen, SDL_DisplayOrientation orientation) +{ + switch (orientation) { + case SDL_ORIENTATION_UNKNOWN: + SDL_snprintfcat(text, maxlen, "UNKNOWN"); + break; + case SDL_ORIENTATION_LANDSCAPE: + SDL_snprintfcat(text, maxlen, "LANDSCAPE"); + break; + case SDL_ORIENTATION_LANDSCAPE_FLIPPED: + SDL_snprintfcat(text, maxlen, "LANDSCAPE_FLIPPED"); + break; + case SDL_ORIENTATION_PORTRAIT: + SDL_snprintfcat(text, maxlen, "PORTRAIT"); + break; + case SDL_ORIENTATION_PORTRAIT_FLIPPED: + SDL_snprintfcat(text, maxlen, "PORTRAIT_FLIPPED"); + break; + default: + SDL_snprintfcat(text, maxlen, "0x%8.8x", orientation); + break; + } +} + +static void +SDLTest_PrintWindowFlag(char* text, size_t maxlen, Uint32 flag) +{ + switch (flag) { + case SDL_WINDOW_FULLSCREEN: + SDL_snprintfcat(text, maxlen, "FULLSCREEN"); + break; + case SDL_WINDOW_OPENGL: + SDL_snprintfcat(text, maxlen, "OPENGL"); + break; + case SDL_WINDOW_SHOWN: + SDL_snprintfcat(text, maxlen, "SHOWN"); + break; + case SDL_WINDOW_HIDDEN: + SDL_snprintfcat(text, maxlen, "HIDDEN"); + break; + case SDL_WINDOW_BORDERLESS: + SDL_snprintfcat(text, maxlen, "BORDERLESS"); + break; + case SDL_WINDOW_RESIZABLE: + SDL_snprintfcat(text, maxlen, "RESIZABLE"); + break; + case SDL_WINDOW_MINIMIZED: + SDL_snprintfcat(text, maxlen, "MINIMIZED"); + break; + case SDL_WINDOW_MAXIMIZED: + SDL_snprintfcat(text, maxlen, "MAXIMIZED"); + break; + case SDL_WINDOW_MOUSE_GRABBED: + SDL_snprintfcat(text, maxlen, "MOUSE_GRABBED"); + break; + case SDL_WINDOW_INPUT_FOCUS: + SDL_snprintfcat(text, maxlen, "INPUT_FOCUS"); + break; + case SDL_WINDOW_MOUSE_FOCUS: + SDL_snprintfcat(text, maxlen, "MOUSE_FOCUS"); + break; + case SDL_WINDOW_FULLSCREEN_DESKTOP: + SDL_snprintfcat(text, maxlen, "FULLSCREEN_DESKTOP"); + break; + case SDL_WINDOW_FOREIGN: + SDL_snprintfcat(text, maxlen, "FOREIGN"); + break; + case SDL_WINDOW_ALLOW_HIGHDPI: + SDL_snprintfcat(text, maxlen, "ALLOW_HIGHDPI"); + break; + case SDL_WINDOW_MOUSE_CAPTURE: + SDL_snprintfcat(text, maxlen, "MOUSE_CAPTURE"); + break; + case SDL_WINDOW_ALWAYS_ON_TOP: + SDL_snprintfcat(text, maxlen, "ALWAYS_ON_TOP"); + break; + case SDL_WINDOW_SKIP_TASKBAR: + SDL_snprintfcat(text, maxlen, "SKIP_TASKBAR"); + break; + case SDL_WINDOW_UTILITY: + SDL_snprintfcat(text, maxlen, "UTILITY"); + break; + case SDL_WINDOW_TOOLTIP: + SDL_snprintfcat(text, maxlen, "TOOLTIP"); + break; + case SDL_WINDOW_POPUP_MENU: + SDL_snprintfcat(text, maxlen, "POPUP_MENU"); + break; + case SDL_WINDOW_KEYBOARD_GRABBED: + SDL_snprintfcat(text, maxlen, "KEYBOARD_GRABBED"); + break; + case SDL_WINDOW_VULKAN: + SDL_snprintfcat(text, maxlen, "VULKAN"); + break; + case SDL_WINDOW_METAL: + SDL_snprintfcat(text, maxlen, "METAL"); + break; + default: + SDL_snprintfcat(text, maxlen, "0x%8.8x", flag); + break; + } +} + +static void +SDLTest_PrintWindowFlags(char* text, size_t maxlen, Uint32 flags) +{ + const Uint32 window_flags[] = { + SDL_WINDOW_FULLSCREEN, + SDL_WINDOW_OPENGL, + SDL_WINDOW_SHOWN, + SDL_WINDOW_HIDDEN, + SDL_WINDOW_BORDERLESS, + SDL_WINDOW_RESIZABLE, + SDL_WINDOW_MINIMIZED, + SDL_WINDOW_MAXIMIZED, + SDL_WINDOW_MOUSE_GRABBED, + SDL_WINDOW_INPUT_FOCUS, + SDL_WINDOW_MOUSE_FOCUS, + SDL_WINDOW_FULLSCREEN_DESKTOP, + SDL_WINDOW_FOREIGN, + SDL_WINDOW_ALLOW_HIGHDPI, + SDL_WINDOW_MOUSE_CAPTURE, + SDL_WINDOW_ALWAYS_ON_TOP, + SDL_WINDOW_SKIP_TASKBAR, + SDL_WINDOW_UTILITY, + SDL_WINDOW_TOOLTIP, + SDL_WINDOW_POPUP_MENU, + SDL_WINDOW_KEYBOARD_GRABBED, + SDL_WINDOW_VULKAN, + SDL_WINDOW_METAL + }; + + int i; + int count = 0; + for (i = 0; i < (sizeof(window_flags) / sizeof(window_flags[0])); ++i) { + const Uint32 flag = window_flags[i]; + if ((flags & flag) == flag) { + if (count > 0) { + SDL_snprintfcat(text, maxlen, " | "); + } + SDLTest_PrintWindowFlag(text, maxlen, flag); + ++count; + } + } +} + +static void +SDLTest_PrintButtonMask(char* text, size_t maxlen, Uint32 flags) +{ + int i; + int count = 0; + for (i = 1; i <= 32; ++i) { + const Uint32 flag = SDL_BUTTON(i); + if ((flags & flag) == flag) { + if (count > 0) { + SDL_snprintfcat(text, maxlen, " | "); + } + SDL_snprintfcat(text, maxlen, "SDL_BUTTON(%d)", i); + ++count; + } + } +} + static void SDLTest_PrintRendererFlag(char *text, size_t maxlen, Uint32 flag) { @@ -734,7 +965,7 @@ SDLTest_PrintRenderer(SDL_RendererInfo * info) SDL_Log(" Renderer %s:\n", info->name); - SDL_snprintf(text, sizeof(text), " Flags: 0x%8.8X", info->flags); + SDL_snprintf(text, sizeof(text), " Flags: 0x%8.8" SDL_PRIX32, info->flags); SDL_snprintfcat(text, sizeof(text), " ("); count = 0; for (i = 0; i < sizeof(info->flags) * 8; ++i) { @@ -750,7 +981,7 @@ SDLTest_PrintRenderer(SDL_RendererInfo * info) SDL_snprintfcat(text, sizeof(text), ")"); SDL_Log("%s\n", text); - SDL_snprintf(text, sizeof(text), " Texture formats (%d): ", info->num_texture_formats); + SDL_snprintf(text, sizeof(text), " Texture formats (%" SDL_PRIu32 "): ", info->num_texture_formats); for (i = 0; i < (int) info->num_texture_formats; ++i) { if (i > 0) { SDL_snprintfcat(text, sizeof(text), ", "); @@ -931,11 +1162,11 @@ SDLTest_CommonInit(SDLTest_CommonState * state) mode.w, mode.h, mode.refresh_rate, bpp, SDL_GetPixelFormatName(mode.format)); if (Rmask || Gmask || Bmask) { - SDL_Log(" Red Mask = 0x%.8x\n", Rmask); - SDL_Log(" Green Mask = 0x%.8x\n", Gmask); - SDL_Log(" Blue Mask = 0x%.8x\n", Bmask); + SDL_Log(" Red Mask = 0x%.8" SDL_PRIx32 "\n", Rmask); + SDL_Log(" Green Mask = 0x%.8" SDL_PRIx32 "\n", Gmask); + SDL_Log(" Blue Mask = 0x%.8" SDL_PRIx32 "\n", Bmask); if (Amask) - SDL_Log(" Alpha Mask = 0x%.8x\n", Amask); + SDL_Log(" Alpha Mask = 0x%.8" SDL_PRIx32 "\n", Amask); } /* Print available fullscreen video modes */ @@ -952,14 +1183,14 @@ SDLTest_CommonInit(SDLTest_CommonState * state) j, mode.w, mode.h, mode.refresh_rate, bpp, SDL_GetPixelFormatName(mode.format)); if (Rmask || Gmask || Bmask) { - SDL_Log(" Red Mask = 0x%.8x\n", + SDL_Log(" Red Mask = 0x%.8" SDL_PRIx32 "\n", Rmask); - SDL_Log(" Green Mask = 0x%.8x\n", + SDL_Log(" Green Mask = 0x%.8" SDL_PRIx32 "\n", Gmask); - SDL_Log(" Blue Mask = 0x%.8x\n", + SDL_Log(" Blue Mask = 0x%.8" SDL_PRIx32 "\n", Bmask); if (Amask) - SDL_Log(" Alpha Mask = 0x%.8x\n", + SDL_Log(" Alpha Mask = 0x%.8" SDL_PRIx32 "\n", Amask); } } @@ -1061,7 +1292,7 @@ SDLTest_CommonInit(SDLTest_CommonState * state) SDL_GetWindowSize(state->windows[i], &w, &h); if (!(state->window_flags & SDL_WINDOW_RESIZABLE) && (w != state->window_w || h != state->window_h)) { - printf("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h); + SDL_Log("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h); state->window_w = w; state->window_h = h; } @@ -1087,17 +1318,20 @@ SDLTest_CommonInit(SDLTest_CommonState * state) SDL_ShowWindow(state->windows[i]); + if (!SDL_RectEmpty(&state->confine)) { + SDL_SetWindowMouseRect(state->windows[i], &state->confine); + } + if (!state->skip_renderer && (state->renderdriver - || !(state->window_flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_VULKAN)))) { + || !(state->window_flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_VULKAN | SDL_WINDOW_METAL)))) { m = -1; if (state->renderdriver) { SDL_RendererInfo info; n = SDL_GetNumRenderDrivers(); for (j = 0; j < n; ++j) { SDL_GetRenderDriverInfo(j, &info); - if (SDL_strcasecmp(info.name, state->renderdriver) == - 0) { + if (SDL_strcasecmp(info.name, state->renderdriver) == 0) { m = j; break; } @@ -1238,11 +1472,20 @@ SDLTest_PrintEvent(SDL_Event * event) switch (event->type) { case SDL_DISPLAYEVENT: switch (event->display.event) { + case SDL_DISPLAYEVENT_CONNECTED: + SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " connected", + event->display.display); + break; case SDL_DISPLAYEVENT_ORIENTATION: - SDL_Log("SDL EVENT: Display %d changed orientation to %s", event->display.display, DisplayOrientationName(event->display.data1)); + SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed orientation to %s", + event->display.display, DisplayOrientationName(event->display.data1)); + break; + case SDL_DISPLAYEVENT_DISCONNECTED: + SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " disconnected", + event->display.display); break; default: - SDL_Log("SDL EVENT: Display %d got unknown event 0x%4.4x", + SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " got unknown event 0x%4.4x", event->display.display, event->display.event); break; } @@ -1250,123 +1493,120 @@ SDLTest_PrintEvent(SDL_Event * event) case SDL_WINDOWEVENT: switch (event->window.event) { case SDL_WINDOWEVENT_SHOWN: - SDL_Log("SDL EVENT: Window %d shown", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " shown", event->window.windowID); break; case SDL_WINDOWEVENT_HIDDEN: - SDL_Log("SDL EVENT: Window %d hidden", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " hidden", event->window.windowID); break; case SDL_WINDOWEVENT_EXPOSED: - SDL_Log("SDL EVENT: Window %d exposed", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " exposed", event->window.windowID); break; case SDL_WINDOWEVENT_MOVED: - SDL_Log("SDL EVENT: Window %d moved to %d,%d", - event->window.windowID, event->window.data1, - event->window.data2); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " moved to %" SDL_PRIs32 ",%" SDL_PRIs32, + event->window.windowID, event->window.data1, event->window.data2); break; case SDL_WINDOWEVENT_RESIZED: - SDL_Log("SDL EVENT: Window %d resized to %dx%d", - event->window.windowID, event->window.data1, - event->window.data2); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " resized to %" SDL_PRIs32 "x%" SDL_PRIs32, + event->window.windowID, event->window.data1, event->window.data2); break; case SDL_WINDOWEVENT_SIZE_CHANGED: - SDL_Log("SDL EVENT: Window %d changed size to %dx%d", - event->window.windowID, event->window.data1, - event->window.data2); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " changed size to %" SDL_PRIs32 "x%" SDL_PRIs32, + event->window.windowID, event->window.data1, event->window.data2); break; case SDL_WINDOWEVENT_MINIMIZED: - SDL_Log("SDL EVENT: Window %d minimized", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " minimized", event->window.windowID); break; case SDL_WINDOWEVENT_MAXIMIZED: - SDL_Log("SDL EVENT: Window %d maximized", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " maximized", event->window.windowID); break; case SDL_WINDOWEVENT_RESTORED: - SDL_Log("SDL EVENT: Window %d restored", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " restored", event->window.windowID); break; case SDL_WINDOWEVENT_ENTER: - SDL_Log("SDL EVENT: Mouse entered window %d", + SDL_Log("SDL EVENT: Mouse entered window %" SDL_PRIu32 "", event->window.windowID); break; case SDL_WINDOWEVENT_LEAVE: - SDL_Log("SDL EVENT: Mouse left window %d", event->window.windowID); + SDL_Log("SDL EVENT: Mouse left window %" SDL_PRIu32 "", event->window.windowID); break; case SDL_WINDOWEVENT_FOCUS_GAINED: - SDL_Log("SDL EVENT: Window %d gained keyboard focus", + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " gained keyboard focus", event->window.windowID); break; case SDL_WINDOWEVENT_FOCUS_LOST: - SDL_Log("SDL EVENT: Window %d lost keyboard focus", + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " lost keyboard focus", event->window.windowID); break; case SDL_WINDOWEVENT_CLOSE: - SDL_Log("SDL EVENT: Window %d closed", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " closed", event->window.windowID); break; case SDL_WINDOWEVENT_TAKE_FOCUS: - SDL_Log("SDL EVENT: Window %d take focus", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " take focus", event->window.windowID); break; case SDL_WINDOWEVENT_HIT_TEST: - SDL_Log("SDL EVENT: Window %d hit test", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " hit test", event->window.windowID); break; default: - SDL_Log("SDL EVENT: Window %d got unknown event 0x%4.4x", + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " got unknown event 0x%4.4x", event->window.windowID, event->window.event); break; } break; case SDL_KEYDOWN: - SDL_Log("SDL EVENT: Keyboard: key pressed in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s", + SDL_Log("SDL EVENT: Keyboard: key pressed in window %" SDL_PRIu32 ": scancode 0x%08X = %s, keycode 0x%08" SDL_PRIX32 " = %s", event->key.windowID, event->key.keysym.scancode, SDL_GetScancodeName(event->key.keysym.scancode), event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym)); break; case SDL_KEYUP: - SDL_Log("SDL EVENT: Keyboard: key released in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s", + SDL_Log("SDL EVENT: Keyboard: key released in window %" SDL_PRIu32 ": scancode 0x%08X = %s, keycode 0x%08" SDL_PRIX32 " = %s", event->key.windowID, event->key.keysym.scancode, SDL_GetScancodeName(event->key.keysym.scancode), event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym)); break; case SDL_TEXTEDITING: - SDL_Log("SDL EVENT: Keyboard: text editing \"%s\" in window %d", + SDL_Log("SDL EVENT: Keyboard: text editing \"%s\" in window %" SDL_PRIu32, event->edit.text, event->edit.windowID); break; case SDL_TEXTINPUT: - SDL_Log("SDL EVENT: Keyboard: text input \"%s\" in window %d", + SDL_Log("SDL EVENT: Keyboard: text input \"%s\" in window %" SDL_PRIu32, event->text.text, event->text.windowID); break; case SDL_KEYMAPCHANGED: SDL_Log("SDL EVENT: Keymap changed"); break; case SDL_MOUSEMOTION: - SDL_Log("SDL EVENT: Mouse: moved to %d,%d (%d,%d) in window %d", + SDL_Log("SDL EVENT: Mouse: moved to %" SDL_PRIs32 ",%" SDL_PRIs32 " (%" SDL_PRIs32 ",%" SDL_PRIs32 ") in window %" SDL_PRIu32, event->motion.x, event->motion.y, event->motion.xrel, event->motion.yrel, event->motion.windowID); break; case SDL_MOUSEBUTTONDOWN: - SDL_Log("SDL EVENT: Mouse: button %d pressed at %d,%d with click count %d in window %d", + SDL_Log("SDL EVENT: Mouse: button %d pressed at %" SDL_PRIs32 ",%" SDL_PRIs32 " with click count %d in window %" SDL_PRIu32, event->button.button, event->button.x, event->button.y, event->button.clicks, event->button.windowID); break; case SDL_MOUSEBUTTONUP: - SDL_Log("SDL EVENT: Mouse: button %d released at %d,%d with click count %d in window %d", + SDL_Log("SDL EVENT: Mouse: button %d released at %" SDL_PRIs32 ",%" SDL_PRIs32 " with click count %d in window %" SDL_PRIu32, event->button.button, event->button.x, event->button.y, event->button.clicks, event->button.windowID); break; case SDL_MOUSEWHEEL: - SDL_Log("SDL EVENT: Mouse: wheel scrolled %d in x and %d in y (reversed: %d) in window %d", + SDL_Log("SDL EVENT: Mouse: wheel scrolled %" SDL_PRIs32 " in x and %" SDL_PRIs32 " in y (reversed: %" SDL_PRIu32 ") in window %" SDL_PRIu32, event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID); break; case SDL_JOYDEVICEADDED: - SDL_Log("SDL EVENT: Joystick index %d attached", + SDL_Log("SDL EVENT: Joystick index %" SDL_PRIs32 " attached", event->jdevice.which); break; case SDL_JOYDEVICEREMOVED: - SDL_Log("SDL EVENT: Joystick %d removed", + SDL_Log("SDL EVENT: Joystick %" SDL_PRIs32 " removed", event->jdevice.which); break; case SDL_JOYBALLMOTION: - SDL_Log("SDL EVENT: Joystick %d: ball %d moved by %d,%d", + SDL_Log("SDL EVENT: Joystick %" SDL_PRIs32 ": ball %d moved by %d,%d", event->jball.which, event->jball.ball, event->jball.xrel, event->jball.yrel); break; @@ -1402,40 +1642,40 @@ SDLTest_PrintEvent(SDL_Event * event) position = "LEFTUP"; break; } - SDL_Log("SDL EVENT: Joystick %d: hat %d moved to %s", event->jhat.which, - event->jhat.hat, position); + SDL_Log("SDL EVENT: Joystick %" SDL_PRIs32 ": hat %d moved to %s", + event->jhat.which, event->jhat.hat, position); } break; case SDL_JOYBUTTONDOWN: - SDL_Log("SDL EVENT: Joystick %d: button %d pressed", + SDL_Log("SDL EVENT: Joystick %" SDL_PRIs32 ": button %d pressed", event->jbutton.which, event->jbutton.button); break; case SDL_JOYBUTTONUP: - SDL_Log("SDL EVENT: Joystick %d: button %d released", + SDL_Log("SDL EVENT: Joystick %" SDL_PRIs32 ": button %d released", event->jbutton.which, event->jbutton.button); break; case SDL_CONTROLLERDEVICEADDED: - SDL_Log("SDL EVENT: Controller index %d attached", + SDL_Log("SDL EVENT: Controller index %" SDL_PRIs32 " attached", event->cdevice.which); break; case SDL_CONTROLLERDEVICEREMOVED: - SDL_Log("SDL EVENT: Controller %d removed", + SDL_Log("SDL EVENT: Controller %" SDL_PRIs32 " removed", event->cdevice.which); break; case SDL_CONTROLLERAXISMOTION: - SDL_Log("SDL EVENT: Controller %d axis %d ('%s') value: %d", + SDL_Log("SDL EVENT: Controller %" SDL_PRIs32 " axis %d ('%s') value: %d", event->caxis.which, event->caxis.axis, ControllerAxisName((SDL_GameControllerAxis)event->caxis.axis), event->caxis.value); break; case SDL_CONTROLLERBUTTONDOWN: - SDL_Log("SDL EVENT: Controller %d button %d ('%s') down", + SDL_Log("SDL EVENT: Controller %" SDL_PRIs32 "button %d ('%s') down", event->cbutton.which, event->cbutton.button, ControllerButtonName((SDL_GameControllerButton)event->cbutton.button)); break; case SDL_CONTROLLERBUTTONUP: - SDL_Log("SDL EVENT: Controller %d button %d ('%s') up", + SDL_Log("SDL EVENT: Controller %" SDL_PRIs32 " button %d ('%s') up", event->cbutton.which, event->cbutton.button, ControllerButtonName((SDL_GameControllerButton)event->cbutton.button)); break; @@ -1510,10 +1750,10 @@ SDLTest_PrintEvent(SDL_Event * event) SDL_Log("SDL EVENT: Quit requested"); break; case SDL_USEREVENT: - SDL_Log("SDL EVENT: User event %d", event->user.code); + SDL_Log("SDL EVENT: User event %" SDL_PRIs32, event->user.code); break; default: - SDL_Log("Unknown event 0x%4.4x", event->type); + SDL_Log("Unknown event 0x%4.4" SDL_PRIu32, event->type); break; } } @@ -1612,6 +1852,16 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) } } break; + case SDL_WINDOWEVENT_FOCUS_LOST: + if (state->flash_on_focus_loss) { + SDL_Window *window = SDL_GetWindowFromID(event->window.windowID); + if (window) { + SDL_FlashWindow(window, SDL_FLASH_UNTIL_FOCUSED); + } + } + break; + default: + break; } break; case SDL_KEYDOWN: { @@ -1686,7 +1936,7 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) const int delta = 100; int x, y; SDL_GetWindowPosition(window, &x, &y); - + if (event->key.keysym.sym == SDLK_UP) y -= delta; if (event->key.keysym.sym == SDLK_DOWN) y += delta; if (event->key.keysym.sym == SDLK_LEFT) x -= delta; @@ -1719,7 +1969,7 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) if (withControl) { /* Ctrl-C copy awesome text! */ SDL_SetClipboardText("SDL rocks!\nYou know it!"); - printf("Copied text to clipboard\n"); + SDL_Log("Copied text to clipboard\n"); } if (withAlt) { /* Alt-C toggle a render clip rectangle */ @@ -1755,22 +2005,40 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) /* Ctrl-V paste awesome text! */ char *text = SDL_GetClipboardText(); if (*text) { - printf("Clipboard: %s\n", text); + SDL_Log("Clipboard: %s\n", text); } else { - printf("Clipboard is empty\n"); + SDL_Log("Clipboard is empty\n"); } SDL_free(text); } break; + case SDLK_f: + if (withControl) { + /* Ctrl-F flash the window */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + SDL_FlashWindow(window, SDL_FLASH_BRIEFLY); + } + } + break; case SDLK_g: if (withControl) { - /* Ctrl-G toggle grab */ + /* Ctrl-G toggle mouse grab */ SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); if (window) { SDL_SetWindowGrab(window, !SDL_GetWindowGrab(window) ? SDL_TRUE : SDL_FALSE); } } break; + case SDLK_k: + if (withControl) { + /* Ctrl-K toggle keyboard grab */ + SDL_Window* window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + SDL_SetWindowKeyboardGrab(window, !SDL_GetWindowKeyboardGrab(window) ? SDL_TRUE : SDL_FALSE); + } + } + break; case SDLK_m: if (withControl) { /* Ctrl-M maximize */ @@ -1791,6 +2059,20 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode() ? SDL_TRUE : SDL_FALSE); } break; + case SDLK_t: + if (withControl) { + /* Ctrl-T toggle topmost mode */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + Uint32 flags = SDL_GetWindowFlags(window); + if (flags & SDL_WINDOW_ALWAYS_ON_TOP) { + SDL_SetWindowAlwaysOnTop(window, SDL_FALSE); + } else { + SDL_SetWindowAlwaysOnTop(window, SDL_TRUE); + } + } + } + break; case SDLK_z: if (withControl) { /* Ctrl-Z minimize */ @@ -1885,7 +2167,8 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) char message[256]; SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); - SDL_snprintf(message, sizeof(message), "(%i, %i), rel (%i, %i)\n", lastEvent.x, lastEvent.y, lastEvent.xrel, lastEvent.yrel); + SDL_snprintf(message, sizeof(message), "(%" SDL_PRIs32 ", %" SDL_PRIs32 "), rel (%" SDL_PRIs32 ", %" SDL_PRIs32 ")\n", + lastEvent.x, lastEvent.y, lastEvent.xrel, lastEvent.yrel); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Last mouse position", message, window); break; } @@ -1948,4 +2231,172 @@ SDLTest_CommonQuit(SDLTest_CommonState * state) SDLTest_LogAllocations(); } +void +SDLTest_CommonDrawWindowInfo(SDL_Renderer * renderer, SDL_Window * window, int * usedHeight) +{ + char text[1024]; + int textY = 0; + const int lineHeight = 10; + int x, y, w, h; + SDL_Rect rect; + SDL_DisplayMode mode; + float ddpi, hdpi, vdpi; + float scaleX, scaleY; + Uint32 flags; + const int windowDisplayIndex = SDL_GetWindowDisplayIndex(window); + SDL_RendererInfo info; + + /* Video */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, 0, textY, "-- Video --"); + textY += lineHeight; + + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + + SDL_snprintf(text, sizeof(text), "SDL_GetCurrentVideoDriver: %s", SDL_GetCurrentVideoDriver()); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + /* Renderer */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, 0, textY, "-- Renderer --"); + textY += lineHeight; + + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + + if (0 == SDL_GetRendererInfo(renderer, &info)) { + SDL_snprintf(text, sizeof(text), "SDL_GetRendererInfo: name: %s", info.name); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + if (0 == SDL_GetRendererOutputSize(renderer, &w, &h)) { + SDL_snprintf(text, sizeof(text), "SDL_GetRendererOutputSize: %dx%d", w, h); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + SDL_RenderGetViewport(renderer, &rect); + SDL_snprintf(text, sizeof(text), "SDL_RenderGetViewport: %d,%d, %dx%d", + rect.x, rect.y, rect.w, rect.h); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + SDL_RenderGetScale(renderer, &scaleX, &scaleY); + SDL_snprintf(text, sizeof(text), "SDL_RenderGetScale: %f,%f", + scaleX, scaleY); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + SDL_RenderGetLogicalSize(renderer, &w, &h); + SDL_snprintf(text, sizeof(text), "SDL_RenderGetLogicalSize: %dx%d", w, h); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + /* Window */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, 0, textY, "-- Window --"); + textY += lineHeight; + + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + + SDL_GetWindowPosition(window, &x, &y); + SDL_snprintf(text, sizeof(text), "SDL_GetWindowPosition: %d,%d", x, y); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + SDL_GetWindowSize(window, &w, &h); + SDL_snprintf(text, sizeof(text), "SDL_GetWindowSize: %dx%d", w, h); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + SDL_snprintf(text, sizeof(text), "SDL_GetWindowFlags: "); + SDLTest_PrintWindowFlags(text, sizeof(text), SDL_GetWindowFlags(window)); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + if (0 == SDL_GetWindowDisplayMode(window, &mode)) { + SDL_snprintf(text, sizeof(text), "SDL_GetWindowDisplayMode: %dx%d@%dHz (%s)", + mode.w, mode.h, mode.refresh_rate, SDL_GetPixelFormatName(mode.format)); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + /* Display */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, 0, textY, "-- Display --"); + textY += lineHeight; + + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + + SDL_snprintf(text, sizeof(text), "SDL_GetWindowDisplayIndex: %d", windowDisplayIndex); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + SDL_snprintf(text, sizeof(text), "SDL_GetDisplayName: %s", SDL_GetDisplayName(windowDisplayIndex)); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + if (0 == SDL_GetDisplayBounds(windowDisplayIndex, &rect)) { + SDL_snprintf(text, sizeof(text), "SDL_GetDisplayBounds: %d,%d, %dx%d", + rect.x, rect.y, rect.w, rect.h); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + if (0 == SDL_GetCurrentDisplayMode(windowDisplayIndex, &mode)) { + SDL_snprintf(text, sizeof(text), "SDL_GetCurrentDisplayMode: %dx%d@%d", + mode.w, mode.h, mode.refresh_rate); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + if (0 == SDL_GetDesktopDisplayMode(windowDisplayIndex, &mode)) { + SDL_snprintf(text, sizeof(text), "SDL_GetDesktopDisplayMode: %dx%d@%d", + mode.w, mode.h, mode.refresh_rate); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + if (0 == SDL_GetDisplayDPI(windowDisplayIndex, &ddpi, &hdpi, &vdpi)) { + SDL_snprintf(text, sizeof(text), "SDL_GetDisplayDPI: ddpi: %f, hdpi: %f, vdpi: %f", + ddpi, hdpi, vdpi); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + SDL_snprintf(text, sizeof(text), "SDL_GetDisplayOrientation: "); + SDLTest_PrintDisplayOrientation(text, sizeof(text), SDL_GetDisplayOrientation(windowDisplayIndex)); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + /* Mouse */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, 0, textY, "-- Mouse --"); + textY += lineHeight; + + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + + flags = SDL_GetMouseState(&x, &y); + SDL_snprintf(text, sizeof(text), "SDL_GetMouseState: %d,%d ", x, y); + SDLTest_PrintButtonMask(text, sizeof(text), flags); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + flags = SDL_GetGlobalMouseState(&x, &y); + SDL_snprintf(text, sizeof(text), "SDL_GetGlobalMouseState: %d,%d ", x, y); + SDLTest_PrintButtonMask(text, sizeof(text), flags); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + if (usedHeight) { + *usedHeight = textY; + } +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/test/SDL_test_compare.c b/Engine/lib/sdl/src/test/SDL_test_compare.c index 5b19be3fa..157bd2ff8 100644 --- a/Engine/lib/sdl/src/test/SDL_test_compare.c +++ b/Engine/lib/sdl/src/test/SDL_test_compare.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/test/SDL_test_crc32.c b/Engine/lib/sdl/src/test/SDL_test_crc32.c index 8ba9442bf..cfc5a641c 100644 --- a/Engine/lib/sdl/src/test/SDL_test_crc32.c +++ b/Engine/lib/sdl/src/test/SDL_test_crc32.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/test/SDL_test_font.c b/Engine/lib/sdl/src/test/SDL_test_font.c index e185408a8..4129f3da2 100644 --- a/Engine/lib/sdl/src/test/SDL_test_font.c +++ b/Engine/lib/sdl/src/test/SDL_test_font.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -3109,10 +3109,16 @@ static unsigned char SDLTest_FontData[SDL_TESTFONTDATAMAX] = { /* ---- Character */ +struct SDLTest_CharTextureCache { + SDL_Renderer* renderer; + SDL_Texture* charTextureCache[256]; + struct SDLTest_CharTextureCache* next; +}; + /*! -\brief Global cache for 8x8 pixel font textures created at runtime. +\brief List of per-renderer caches for 8x8 pixel font textures created at runtime. */ -static SDL_Texture *SDLTest_CharTextureCache[256]; +static struct SDLTest_CharTextureCache *SDLTest_CharTextureCacheList; int SDLTest_DrawCharacter(SDL_Renderer *renderer, int x, int y, char c) { @@ -3131,6 +3137,7 @@ int SDLTest_DrawCharacter(SDL_Renderer *renderer, int x, int y, char c) SDL_Surface *character; Uint32 ci; Uint8 r, g, b, a; + struct SDLTest_CharTextureCache *cache; /* * Setup source rectangle @@ -3151,10 +3158,25 @@ int SDLTest_DrawCharacter(SDL_Renderer *renderer, int x, int y, char c) /* Character index in cache */ ci = (unsigned char)c; + /* Search for this renderer's cache */ + for (cache = SDLTest_CharTextureCacheList; cache != NULL; cache = cache->next) { + if (cache->renderer == renderer) { + break; + } + } + + /* Allocate a new cache for this renderer if needed */ + if (cache == NULL) { + cache = (struct SDLTest_CharTextureCache*)SDL_calloc(1, sizeof(struct SDLTest_CharTextureCache)); + cache->renderer = renderer; + cache->next = SDLTest_CharTextureCacheList; + SDLTest_CharTextureCacheList = cache; + } + /* * Create new charWidth x charHeight bitmap surface if not already present. */ - if (SDLTest_CharTextureCache[ci] == NULL) { + if (cache->charTextureCache[ci] == NULL) { /* * Redraw character into surface */ @@ -3191,14 +3213,15 @@ int SDLTest_DrawCharacter(SDL_Renderer *renderer, int x, int y, char c) linepos += pitch; } + /* Convert temp surface into texture */ - SDLTest_CharTextureCache[ci] = SDL_CreateTextureFromSurface(renderer, character); + cache->charTextureCache[ci] = SDL_CreateTextureFromSurface(renderer, character); SDL_FreeSurface(character); /* * Check pointer */ - if (SDLTest_CharTextureCache[ci] == NULL) { + if (cache->charTextureCache[ci] == NULL) { return (-1); } } @@ -3208,13 +3231,13 @@ int SDLTest_DrawCharacter(SDL_Renderer *renderer, int x, int y, char c) */ result = 0; result |= SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a); - result |= SDL_SetTextureColorMod(SDLTest_CharTextureCache[ci], r, g, b); - result |= SDL_SetTextureAlphaMod(SDLTest_CharTextureCache[ci], a); + result |= SDL_SetTextureColorMod(cache->charTextureCache[ci], r, g, b); + result |= SDL_SetTextureAlphaMod(cache->charTextureCache[ci], a); /* * Draw texture onto destination */ - result |= SDL_RenderCopy(renderer, SDLTest_CharTextureCache[ci], &srect, &drect); + result |= SDL_RenderCopy(renderer, cache->charTextureCache[ci], &srect, &drect); return (result); } @@ -3239,12 +3262,23 @@ int SDLTest_DrawString(SDL_Renderer * renderer, int x, int y, const char *s) void SDLTest_CleanupTextDrawing(void) { unsigned int i; - for (i = 0; i < SDL_arraysize(SDLTest_CharTextureCache); ++i) { - if (SDLTest_CharTextureCache[i]) { - SDL_DestroyTexture(SDLTest_CharTextureCache[i]); - SDLTest_CharTextureCache[i] = NULL; + struct SDLTest_CharTextureCache* cache, *next; + + cache = SDLTest_CharTextureCacheList; + do { + for (i = 0; i < SDL_arraysize(cache->charTextureCache); ++i) { + if (cache->charTextureCache[i]) { + SDL_DestroyTexture(cache->charTextureCache[i]); + cache->charTextureCache[i] = NULL; + } } - } + + next = cache->next; + SDL_free(cache); + cache = next; + } while (cache); + + SDLTest_CharTextureCacheList = NULL; } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/test/SDL_test_fuzzer.c b/Engine/lib/sdl/src/test/SDL_test_fuzzer.c index 458d934a0..98fb09df6 100644 --- a/Engine/lib/sdl/src/test/SDL_test_fuzzer.c +++ b/Engine/lib/sdl/src/test/SDL_test_fuzzer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/test/SDL_test_harness.c b/Engine/lib/sdl/src/test/SDL_test_harness.c index 7b27a5e28..8f10f3e5c 100644 --- a/Engine/lib/sdl/src/test/SDL_test_harness.c +++ b/Engine/lib/sdl/src/test/SDL_test_harness.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -98,7 +98,7 @@ SDLTest_GenerateRunSeed(const int length) * */ static Uint64 -SDLTest_GenerateExecKey(const char *runSeed, char *suiteName, char *testName, int iteration) +SDLTest_GenerateExecKey(const char *runSeed, const char *suiteName, const char *testName, int iteration) { SDLTest_Md5Context md5Context; Uint64 *keys; @@ -240,7 +240,7 @@ SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_TestCaseRef return TEST_RESULT_SETUP_FAILURE; } - if (!testCase->enabled && forceTestRun == SDL_FALSE) + if (!testCase->enabled && forceTestRun == SDL_FALSE) { SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, "Skipped (Disabled)"); return TEST_RESULT_SKIPPED; @@ -316,7 +316,7 @@ SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_TestCaseRef } /* Prints summary of all suites/tests contained in the given reference */ -#if 0 +#if 0 static void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites) { int suiteCounter; @@ -377,8 +377,8 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user SDLTest_TestSuiteReference *testSuite; const SDLTest_TestCaseReference *testCase; const char *runSeed = NULL; - char *currentSuiteName; - char *currentTestName; + const char *currentSuiteName; + const char *currentTestName; Uint64 execKey; float runStartSeconds; float suiteStartSeconds; @@ -388,10 +388,10 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user float testEndSeconds; float runtime; int suiteFilter = 0; - char *suiteFilterName = NULL; + const char *suiteFilterName = NULL; int testFilter = 0; - char *testFilterName = NULL; - SDL_bool forceTestRun = SDL_FALSE; + const char *testFilterName = NULL; + SDL_bool forceTestRun = SDL_FALSE; int testResult = 0; int runResult = 0; int totalTestFailedCount = 0; @@ -419,7 +419,6 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user runSeed = userRunSeed; } - /* Reset per-run counters */ totalTestFailedCount = 0; totalTestPassedCount = 0; @@ -431,7 +430,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user /* Log run with fuzzer parameters */ SDLTest_Log("::::: Test Run /w seed '%s' started\n", runSeed); - /* Count the total number of tests */ + /* Count the total number of tests */ suiteCounter = 0; while (testSuites[suiteCounter]) { testSuite = testSuites[suiteCounter]; @@ -440,17 +439,17 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user while (testSuite->testCases[testCounter]) { testCounter++; - totalNumberOfTests++; - } - } + totalNumberOfTests++; + } + } - /* Pre-allocate an array for tracking failed tests (potentially all test cases) */ - failedTests = (const SDLTest_TestCaseReference **)SDL_malloc(totalNumberOfTests * sizeof(SDLTest_TestCaseReference *)); - if (failedTests == NULL) { - SDLTest_LogError("Unable to allocate cache for failed tests"); - SDL_Error(SDL_ENOMEM); + /* Pre-allocate an array for tracking failed tests (potentially all test cases) */ + failedTests = (const SDLTest_TestCaseReference **)SDL_malloc(totalNumberOfTests * sizeof(SDLTest_TestCaseReference *)); + if (failedTests == NULL) { + SDLTest_LogError("Unable to allocate cache for failed tests"); + SDL_Error(SDL_ENOMEM); return -1; - } + } /* Initialize filtering */ if (filter != NULL && filter[0] != '\0') { @@ -542,7 +541,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user /* Override 'disabled' flag if we specified a test filter (i.e. force run for debugging) */ if (testFilter == 1 && !testCase->enabled) { SDLTest_Log("Force run of disabled test since test filter was set"); - forceTestRun = SDL_TRUE; + forceTestRun = SDL_TRUE; } /* Take time - test start */ @@ -571,7 +570,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user } SDLTest_Log("Test Iteration %i: execKey %" SDL_PRIu64, iterationCounter, execKey); - testResult = SDLTest_RunTest(testSuite, testCase, execKey, forceTestRun); + testResult = SDLTest_RunTest(testSuite, testCase, execKey, forceTestRun); if (testResult == TEST_RESULT_PASSED) { testPassedCount++; diff --git a/Engine/lib/sdl/src/test/SDL_test_imageBlit.c b/Engine/lib/sdl/src/test/SDL_test_imageBlit.c index 9aa557eb1..7a45127a2 100644 --- a/Engine/lib/sdl/src/test/SDL_test_imageBlit.c +++ b/Engine/lib/sdl/src/test/SDL_test_imageBlit.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/test/SDL_test_imageBlitBlend.c b/Engine/lib/sdl/src/test/SDL_test_imageBlitBlend.c index 4f6c894fc..d57899edb 100644 --- a/Engine/lib/sdl/src/test/SDL_test_imageBlitBlend.c +++ b/Engine/lib/sdl/src/test/SDL_test_imageBlitBlend.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/test/SDL_test_imageFace.c b/Engine/lib/sdl/src/test/SDL_test_imageFace.c index 54a4803ec..27f8c8463 100644 --- a/Engine/lib/sdl/src/test/SDL_test_imageFace.c +++ b/Engine/lib/sdl/src/test/SDL_test_imageFace.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/test/SDL_test_imagePrimitives.c b/Engine/lib/sdl/src/test/SDL_test_imagePrimitives.c index 0f76d5783..20e95d662 100644 --- a/Engine/lib/sdl/src/test/SDL_test_imagePrimitives.c +++ b/Engine/lib/sdl/src/test/SDL_test_imagePrimitives.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/test/SDL_test_imagePrimitivesBlend.c b/Engine/lib/sdl/src/test/SDL_test_imagePrimitivesBlend.c index ca6c7f7a4..5997f9c35 100644 --- a/Engine/lib/sdl/src/test/SDL_test_imagePrimitivesBlend.c +++ b/Engine/lib/sdl/src/test/SDL_test_imagePrimitivesBlend.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/test/SDL_test_log.c b/Engine/lib/sdl/src/test/SDL_test_log.c index 9d4b6abb5..01b4f7b87 100644 --- a/Engine/lib/sdl/src/test/SDL_test_log.c +++ b/Engine/lib/sdl/src/test/SDL_test_log.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/test/SDL_test_md5.c b/Engine/lib/sdl/src/test/SDL_test_md5.c index e749fb851..662e2fa0c 100644 --- a/Engine/lib/sdl/src/test/SDL_test_md5.c +++ b/Engine/lib/sdl/src/test/SDL_test_md5.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/test/SDL_test_memory.c b/Engine/lib/sdl/src/test/SDL_test_memory.c index c9f552035..067b7a5b3 100644 --- a/Engine/lib/sdl/src/test/SDL_test_memory.c +++ b/Engine/lib/sdl/src/test/SDL_test_memory.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,6 +26,7 @@ #include "SDL_test_memory.h" #ifdef HAVE_LIBUNWIND_H +#define UNW_LOCAL_ONLY #include #endif @@ -103,13 +104,13 @@ static void SDL_TrackAllocation(void *mem, size_t size) stack_index = 0; while (unw_step(&cursor) > 0) { unw_word_t offset, pc; - char sym[256]; + char sym[236]; unw_get_reg(&cursor, UNW_REG_IP, &pc); entry->stack[stack_index] = pc; if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) { - snprintf(entry->stack_names[stack_index], sizeof(entry->stack_names[stack_index]), "%s+0x%llx", sym, (unsigned long long)offset); + SDL_snprintf(entry->stack_names[stack_index], sizeof(entry->stack_names[stack_index]), "%s+0x%llx", sym, (unsigned long long)offset); } ++stack_index; diff --git a/Engine/lib/sdl/src/test/SDL_test_random.c b/Engine/lib/sdl/src/test/SDL_test_random.c index 1fe63441c..c52e050bb 100644 --- a/Engine/lib/sdl/src/test/SDL_test_random.c +++ b/Engine/lib/sdl/src/test/SDL_test_random.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -83,7 +83,8 @@ unsigned int SDLTest_Random(SDLTest_RandomContext * rndContext) if (rndContext==NULL) return -1; - xh = rndContext->x >> 16, xl = rndContext->x & 65535; + xh = rndContext->x >> 16; + xl = rndContext->x & 65535; rndContext->x = rndContext->x * rndContext->a + rndContext->c; rndContext->c = xh * rndContext->ah + ((xh * rndContext->al) >> 16) + diff --git a/Engine/lib/sdl/src/thread/SDL_systhread.h b/Engine/lib/sdl/src/thread/SDL_systhread.h index 77dc09845..fd4492c9b 100644 --- a/Engine/lib/sdl/src/thread/SDL_systhread.h +++ b/Engine/lib/sdl/src/thread/SDL_systhread.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/SDL_thread.c b/Engine/lib/sdl/src/thread/SDL_thread.c index 5757ba000..61af43f0c 100644 --- a/Engine/lib/sdl/src/thread/SDL_thread.c +++ b/Engine/lib/sdl/src/thread/SDL_thread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -82,7 +82,7 @@ SDL_TLSSet(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void *)) return 0; } -static void +void SDL_TLSCleanup() { SDL_TLSData *storage; @@ -141,10 +141,10 @@ SDL_Generic_GetTLSData(void) } SDL_AtomicUnlock(&tls_lock); } -#endif /* SDL_THREADS_DISABLED */ - SDL_MemoryBarrierAcquire(); SDL_LockMutex(SDL_generic_TLS_mutex); +#endif /* SDL_THREADS_DISABLED */ + for (entry = SDL_generic_TLS; entry; entry = entry->next) { if (entry->thread == thread) { storage = entry->storage; diff --git a/Engine/lib/sdl/src/thread/SDL_thread_c.h b/Engine/lib/sdl/src/thread/SDL_thread_c.h index c82b59e23..fb0885a2d 100644 --- a/Engine/lib/sdl/src/thread/SDL_thread_c.h +++ b/Engine/lib/sdl/src/thread/SDL_thread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,6 +34,8 @@ #include "windows/SDL_systhread_c.h" #elif SDL_THREAD_PSP #include "psp/SDL_systhread_c.h" +#elif SDL_THREAD_VITA +#include "vita/SDL_systhread_c.h" #elif SDL_THREAD_STDCPP #include "stdcpp/SDL_systhread_c.h" #elif SDL_THREAD_OS2 diff --git a/Engine/lib/sdl/src/thread/generic/SDL_syscond.c b/Engine/lib/sdl/src/thread/generic/SDL_syscond.c index 5cd97457a..59e8ce076 100644 --- a/Engine/lib/sdl/src/thread/generic/SDL_syscond.c +++ b/Engine/lib/sdl/src/thread/generic/SDL_syscond.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,41 +28,57 @@ #include "SDL_thread.h" -struct SDL_cond +#include "../generic/SDL_syscond_c.h" + +/* If two implementations are to be compiled into SDL (the active one + * will be chosen at runtime), the function names need to be + * suffixed + */ +#if !SDL_THREAD_GENERIC_COND_SUFFIX +#define SDL_CreateCond_generic SDL_CreateCond +#define SDL_DestroyCond_generic SDL_DestroyCond +#define SDL_CondSignal_generic SDL_CondSignal +#define SDL_CondBroadcast_generic SDL_CondBroadcast +#define SDL_CondWait_generic SDL_CondWait +#define SDL_CondWaitTimeout_generic SDL_CondWaitTimeout +#endif + +typedef struct SDL_cond_generic { SDL_mutex *lock; int waiting; int signals; SDL_sem *wait_sem; SDL_sem *wait_done; -}; +} SDL_cond_generic; /* Create a condition variable */ SDL_cond * -SDL_CreateCond(void) +SDL_CreateCond_generic(void) { - SDL_cond *cond; + SDL_cond_generic *cond; - cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond)); + cond = (SDL_cond_generic *) SDL_malloc(sizeof(SDL_cond_generic)); if (cond) { cond->lock = SDL_CreateMutex(); cond->wait_sem = SDL_CreateSemaphore(0); cond->wait_done = SDL_CreateSemaphore(0); cond->waiting = cond->signals = 0; if (!cond->lock || !cond->wait_sem || !cond->wait_done) { - SDL_DestroyCond(cond); + SDL_DestroyCond_generic((SDL_cond *)cond); cond = NULL; } } else { SDL_OutOfMemory(); } - return (cond); + return (SDL_cond *)cond; } /* Destroy a condition variable */ void -SDL_DestroyCond(SDL_cond * cond) +SDL_DestroyCond_generic(SDL_cond * _cond) { + SDL_cond_generic *cond = (SDL_cond_generic *)_cond; if (cond) { if (cond->wait_sem) { SDL_DestroySemaphore(cond->wait_sem); @@ -79,10 +95,11 @@ SDL_DestroyCond(SDL_cond * cond) /* Restart one of the threads that are waiting on the condition variable */ int -SDL_CondSignal(SDL_cond * cond) +SDL_CondSignal_generic(SDL_cond * _cond) { + SDL_cond_generic *cond = (SDL_cond_generic *)_cond; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } /* If there are waiting threads not already signalled, then @@ -103,10 +120,11 @@ SDL_CondSignal(SDL_cond * cond) /* Restart all threads that are waiting on the condition variable */ int -SDL_CondBroadcast(SDL_cond * cond) +SDL_CondBroadcast_generic(SDL_cond * _cond) { + SDL_cond_generic *cond = (SDL_cond_generic *)_cond; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } /* If there are waiting threads not already signalled, then @@ -157,12 +175,13 @@ Thread B: SDL_UnlockMutex(lock); */ int -SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) +SDL_CondWaitTimeout_generic(SDL_cond * _cond, SDL_mutex * mutex, Uint32 ms) { + SDL_cond_generic *cond = (SDL_cond_generic *)_cond; int retval; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } /* Obtain the protection mutex, and increment the number of waiters. @@ -212,9 +231,9 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) /* Wait on the condition variable forever */ int -SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) +SDL_CondWait_generic(SDL_cond * cond, SDL_mutex * mutex) { - return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); + return SDL_CondWaitTimeout_generic(cond, mutex, SDL_MUTEX_MAXWAIT); } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/generic/SDL_syscond_c.h b/Engine/lib/sdl/src/thread/generic/SDL_syscond_c.h new file mode 100644 index 000000000..b7dadc781 --- /dev/null +++ b/Engine/lib/sdl/src/thread/generic/SDL_syscond_c.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#include "SDL_thread.h" + +#ifndef SDL_syscond_generic_h_ +#define SDL_syscond_generic_h_ + +#if SDL_THREAD_GENERIC_COND_SUFFIX + +SDL_cond * SDL_CreateCond_generic(void); +void SDL_DestroyCond_generic(SDL_cond * cond); +int SDL_CondSignal_generic(SDL_cond * cond); +int SDL_CondBroadcast_generic(SDL_cond * cond); +int SDL_CondWait_generic(SDL_cond * cond, SDL_mutex * mutex); +int SDL_CondWaitTimeout_generic(SDL_cond * cond, + SDL_mutex * mutex, Uint32 ms); + +#endif /* SDL_THREAD_GENERIC_COND_SUFFIX */ + +#endif /* SDL_syscond_generic_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/generic/SDL_sysmutex.c b/Engine/lib/sdl/src/thread/generic/SDL_sysmutex.c index d3af9c554..42965aa8b 100644 --- a/Engine/lib/sdl/src/thread/generic/SDL_sysmutex.c +++ b/Engine/lib/sdl/src/thread/generic/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -78,7 +78,7 @@ SDL_LockMutex(SDL_mutex * mutex) SDL_threadID this_thread; if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } this_thread = SDL_ThreadID(); @@ -109,7 +109,7 @@ SDL_TryLockMutex(SDL_mutex * mutex) SDL_threadID this_thread; if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } this_thread = SDL_ThreadID(); @@ -139,7 +139,7 @@ SDL_mutexV(SDL_mutex * mutex) return 0; #else if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } /* If we don't own the mutex, we can't unlock it */ diff --git a/Engine/lib/sdl/src/thread/generic/SDL_sysmutex_c.h b/Engine/lib/sdl/src/thread/generic/SDL_sysmutex_c.h index 2f8835937..074071a4b 100644 --- a/Engine/lib/sdl/src/thread/generic/SDL_sysmutex_c.h +++ b/Engine/lib/sdl/src/thread/generic/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/generic/SDL_syssem.c b/Engine/lib/sdl/src/thread/generic/SDL_syssem.c index 027d54e66..c21ff196a 100644 --- a/Engine/lib/sdl/src/thread/generic/SDL_syssem.c +++ b/Engine/lib/sdl/src/thread/generic/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -132,7 +132,7 @@ SDL_SemTryWait(SDL_sem * sem) int retval; if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } retval = SDL_MUTEX_TIMEDOUT; @@ -152,7 +152,7 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) int retval; if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } /* A timeout of 0 is an easy case */ @@ -200,7 +200,7 @@ int SDL_SemPost(SDL_sem * sem) { if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } SDL_LockMutex(sem->count_lock); diff --git a/Engine/lib/sdl/src/thread/generic/SDL_systhread.c b/Engine/lib/sdl/src/thread/generic/SDL_systhread.c index 3a4d6a22e..e36bf4c1c 100644 --- a/Engine/lib/sdl/src/thread/generic/SDL_systhread.c +++ b/Engine/lib/sdl/src/thread/generic/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/generic/SDL_systhread_c.h b/Engine/lib/sdl/src/thread/generic/SDL_systhread_c.h index 53cb82ef5..bdca9a408 100644 --- a/Engine/lib/sdl/src/thread/generic/SDL_systhread_c.h +++ b/Engine/lib/sdl/src/thread/generic/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/generic/SDL_systls.c b/Engine/lib/sdl/src/thread/generic/SDL_systls.c index b814b9bc0..d4c371c39 100644 --- a/Engine/lib/sdl/src/thread/generic/SDL_systls.c +++ b/Engine/lib/sdl/src/thread/generic/SDL_systls.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c b/Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c index d9a0b0f42..984ae10fe 100644 --- a/Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c +++ b/Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -73,7 +73,7 @@ SDL_LockMutex(SDL_mutex * mutex) HMTX hMtx = (HMTX)mutex; if (hMtx == NULLHANDLE) - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); ulRC = DosRequestMutexSem(hMtx, SEM_INDEFINITE_WAIT); if (ulRC != NO_ERROR) { @@ -92,7 +92,7 @@ SDL_TryLockMutex(SDL_mutex * mutex) HMTX hMtx = (HMTX)mutex; if (hMtx == NULLHANDLE) - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); ulRC = DosRequestMutexSem(hMtx, SEM_IMMEDIATE_RETURN); @@ -115,7 +115,7 @@ SDL_UnlockMutex(SDL_mutex * mutex) HMTX hMtx = (HMTX)mutex; if (hMtx == NULLHANDLE) - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); ulRC = DosReleaseMutexSem(hMtx); if (ulRC != NO_ERROR) diff --git a/Engine/lib/sdl/src/thread/os2/SDL_syssem.c b/Engine/lib/sdl/src/thread/os2/SDL_syssem.c index 01b5db3cf..79bf0673f 100644 --- a/Engine/lib/sdl/src/thread/os2/SDL_syssem.c +++ b/Engine/lib/sdl/src/thread/os2/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -89,7 +89,7 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) ULONG cPost; if (sem == NULL) - return SDL_SetError("Passed a NULL sem"); + return SDL_InvalidParamError("sem"); if (timeout != SEM_INDEFINITE_WAIT) DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulStartTime, sizeof(ULONG)); @@ -147,7 +147,7 @@ SDL_SemValue(SDL_sem * sem) ULONG ulRC; if (sem == NULL) { - SDL_SetError("Passed a NULL sem"); + SDL_InvalidParamError("sem"); return 0; } @@ -167,7 +167,7 @@ SDL_SemPost(SDL_sem * sem) ULONG ulRC; if (sem == NULL) - return SDL_SetError("Passed a NULL sem"); + return SDL_InvalidParamError("sem"); ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT); if (ulRC != NO_ERROR) diff --git a/Engine/lib/sdl/src/thread/os2/SDL_systhread.c b/Engine/lib/sdl/src/thread/os2/SDL_systhread.c index bf395ed4f..8c64e9c32 100644 --- a/Engine/lib/sdl/src/thread/os2/SDL_systhread.c +++ b/Engine/lib/sdl/src/thread/os2/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/os2/SDL_systhread_c.h b/Engine/lib/sdl/src/thread/os2/SDL_systhread_c.h index 1bc942154..dedceb396 100644 --- a/Engine/lib/sdl/src/thread/os2/SDL_systhread_c.h +++ b/Engine/lib/sdl/src/thread/os2/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/os2/SDL_systls.c b/Engine/lib/sdl/src/thread/os2/SDL_systls.c index 2aa274b77..b48a4bd39 100644 --- a/Engine/lib/sdl/src/thread/os2/SDL_systls.c +++ b/Engine/lib/sdl/src/thread/os2/SDL_systls.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/os2/SDL_systls_c.h b/Engine/lib/sdl/src/thread/os2/SDL_systls_c.h index 031b23277..e40d5ddcf 100644 --- a/Engine/lib/sdl/src/thread/os2/SDL_systls_c.h +++ b/Engine/lib/sdl/src/thread/os2/SDL_systls_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/psp/SDL_syscond.c b/Engine/lib/sdl/src/thread/psp/SDL_syscond.c index be6a66b71..02307ed9c 100644 --- a/Engine/lib/sdl/src/thread/psp/SDL_syscond.c +++ b/Engine/lib/sdl/src/thread/psp/SDL_syscond.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -84,7 +84,7 @@ int SDL_CondSignal(SDL_cond * cond) { if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } /* If there are waiting threads not already signalled, then @@ -108,7 +108,7 @@ int SDL_CondBroadcast(SDL_cond * cond) { if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } /* If there are waiting threads not already signalled, then @@ -164,7 +164,7 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) int retval; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } /* Obtain the protection mutex, and increment the number of waiters. diff --git a/Engine/lib/sdl/src/thread/psp/SDL_sysmutex.c b/Engine/lib/sdl/src/thread/psp/SDL_sysmutex.c index 3a76e55d4..9e391629a 100644 --- a/Engine/lib/sdl/src/thread/psp/SDL_sysmutex.c +++ b/Engine/lib/sdl/src/thread/psp/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,30 +27,37 @@ #include "SDL_thread.h" #include "SDL_systhread_c.h" +#include +#include + +#define SCE_KERNEL_MUTEX_ATTR_RECURSIVE 0x0200U struct SDL_mutex { - int recursive; - SDL_threadID owner; - SDL_sem *sem; + SceLwMutexWorkarea lock; }; /* Create a mutex */ SDL_mutex * SDL_CreateMutex(void) { - SDL_mutex *mutex; + SDL_mutex *mutex = NULL; + SceInt32 res = 0; /* Allocate mutex memory */ mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); if (mutex) { - /* Create the mutex semaphore, with initial value 1 */ - mutex->sem = SDL_CreateSemaphore(1); - mutex->recursive = 0; - mutex->owner = 0; - if (!mutex->sem) { - SDL_free(mutex); - mutex = NULL; + + res = sceKernelCreateLwMutex( + &mutex->lock, + "SDL mutex", + SCE_KERNEL_MUTEX_ATTR_RECURSIVE, + 0, + NULL + ); + + if (res < 0) { + SDL_SetError("Error trying to create mutex: %x", res); } } else { SDL_OutOfMemory(); @@ -63,37 +70,56 @@ void SDL_DestroyMutex(SDL_mutex * mutex) { if (mutex) { - if (mutex->sem) { - SDL_DestroySemaphore(mutex->sem); - } + sceKernelDeleteLwMutex(&mutex->lock); SDL_free(mutex); } } -/* Lock the semaphore */ +/* Try to lock the mutex */ +int +SDL_TryLockMutex(SDL_mutex * mutex) +{ +#if SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + if (mutex == NULL) { + return SDL_InvalidParamError("mutex"); + } + + res = sceKernelTryLockLwMutex(&mutex->lock, 1); + switch (res) { + case SCE_KERNEL_ERROR_OK: + return 0; + break; + case SCE_KERNEL_ERROR_WAIT_TIMEOUT: + return SDL_MUTEX_TIMEDOUT; + break; + default: + return SDL_SetError("Error trying to lock mutex: %x", res); + break; + } + + return -1; +#endif /* SDL_THREADS_DISABLED */ +} + + +/* Lock the mutex */ int SDL_mutexP(SDL_mutex * mutex) { #if SDL_THREADS_DISABLED return 0; #else - SDL_threadID this_thread; - + SceInt32 res = 0; if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } - this_thread = SDL_ThreadID(); - if (mutex->owner == this_thread) { - ++mutex->recursive; - } else { - /* The order of operations is important. - We set the locking thread id after we obtain the lock - so unlocks from other threads will fail. - */ - SDL_SemWait(mutex->sem); - mutex->owner = this_thread; - mutex->recursive = 0; + res = sceKernelLockLwMutex(&mutex->lock, 1, NULL); + if (res != SCE_KERNEL_ERROR_OK) { + return SDL_SetError("Error trying to lock mutex: %x", res); } return 0; @@ -107,30 +133,20 @@ SDL_mutexV(SDL_mutex * mutex) #if SDL_THREADS_DISABLED return 0; #else + SceInt32 res = 0; + if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } - /* If we don't own the mutex, we can't unlock it */ - if (SDL_ThreadID() != mutex->owner) { - return SDL_SetError("mutex not owned by this thread"); + res = sceKernelUnlockLwMutex(&mutex->lock, 1); + if (res != 0) { + return SDL_SetError("Error trying to unlock mutex: %x", res); } - if (mutex->recursive) { - --mutex->recursive; - } else { - /* The order of operations is important. - First reset the owner so another thread doesn't lock - the mutex and set the ownership before we reset it, - then release the lock semaphore. - */ - mutex->owner = 0; - SDL_SemPost(mutex->sem); - } return 0; #endif /* SDL_THREADS_DISABLED */ } - #endif /* SDL_THREAD_PSP */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/psp/SDL_sysmutex_c.h b/Engine/lib/sdl/src/thread/psp/SDL_sysmutex_c.h index 2f8835937..074071a4b 100644 --- a/Engine/lib/sdl/src/thread/psp/SDL_sysmutex_c.h +++ b/Engine/lib/sdl/src/thread/psp/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/psp/SDL_syssem.c b/Engine/lib/sdl/src/thread/psp/SDL_syssem.c index edad3e4e8..640619cd9 100644 --- a/Engine/lib/sdl/src/thread/psp/SDL_syssem.c +++ b/Engine/lib/sdl/src/thread/psp/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -43,13 +43,13 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) { SDL_sem *sem; - sem = (SDL_sem *) malloc(sizeof(*sem)); + sem = (SDL_sem *) SDL_malloc(sizeof(*sem)); if (sem != NULL) { /* TODO: Figure out the limit on the maximum value. */ sem->semid = sceKernelCreateSema("SDL sema", 0, initial_value, 255, NULL); if (sem->semid < 0) { SDL_SetError("Couldn't create semaphore"); - free(sem); + SDL_free(sem); sem = NULL; } } else { @@ -68,7 +68,7 @@ void SDL_DestroySemaphore(SDL_sem *sem) sem->semid = 0; } - free(sem); + SDL_free(sem); } } @@ -82,7 +82,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) int res; if (sem == NULL) { - SDL_SetError("Passed a NULL sem"); + SDL_InvalidParamError("sem"); return 0; } @@ -128,7 +128,7 @@ Uint32 SDL_SemValue(SDL_sem *sem) SceKernelSemaInfo info; if (sem == NULL) { - SDL_SetError("Passed a NULL sem"); + SDL_InvalidParamError("sem"); return 0; } @@ -144,7 +144,7 @@ int SDL_SemPost(SDL_sem *sem) int res; if (sem == NULL) { - return SDL_SetError("Passed a NULL sem"); + return SDL_InvalidParamError("sem"); } res = sceKernelSignalSema(sem->semid, 1); diff --git a/Engine/lib/sdl/src/thread/psp/SDL_systhread.c b/Engine/lib/sdl/src/thread/psp/SDL_systhread.c index 789f9a057..50417cb24 100644 --- a/Engine/lib/sdl/src/thread/psp/SDL_systhread.c +++ b/Engine/lib/sdl/src/thread/psp/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -95,13 +95,13 @@ int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) int value; if (priority == SDL_THREAD_PRIORITY_LOW) { - value = 19; + value = 111; } else if (priority == SDL_THREAD_PRIORITY_HIGH) { - value = -10; + value = 32; } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) { - value = -20; + value = 16; } else { - value = 0; + value = 50; } return sceKernelChangeThreadPriority(sceKernelGetThreadId(),value); diff --git a/Engine/lib/sdl/src/thread/psp/SDL_systhread_c.h b/Engine/lib/sdl/src/thread/psp/SDL_systhread_c.h index 4622fd3b5..3209a90b9 100644 --- a/Engine/lib/sdl/src/thread/psp/SDL_systhread_c.h +++ b/Engine/lib/sdl/src/thread/psp/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/pthread/SDL_syscond.c b/Engine/lib/sdl/src/thread/pthread/SDL_syscond.c index 28cf81912..c84ec7ada 100644 --- a/Engine/lib/sdl/src/thread/pthread/SDL_syscond.c +++ b/Engine/lib/sdl/src/thread/pthread/SDL_syscond.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -68,7 +68,7 @@ SDL_CondSignal(SDL_cond * cond) int retval; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } retval = 0; @@ -85,7 +85,7 @@ SDL_CondBroadcast(SDL_cond * cond) int retval; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } retval = 0; @@ -105,7 +105,7 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) struct timespec abstime; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } #ifdef HAVE_CLOCK_GETTIME @@ -148,7 +148,7 @@ int SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) { if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } else if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) { return SDL_SetError("pthread_cond_wait() failed"); } diff --git a/Engine/lib/sdl/src/thread/pthread/SDL_sysmutex.c b/Engine/lib/sdl/src/thread/pthread/SDL_sysmutex.c index b4ebcc615..c26982aed 100644 --- a/Engine/lib/sdl/src/thread/pthread/SDL_sysmutex.c +++ b/Engine/lib/sdl/src/thread/pthread/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -85,7 +85,7 @@ SDL_LockMutex(SDL_mutex * mutex) #endif if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } #if FAKE_RECURSIVE_MUTEX @@ -122,7 +122,7 @@ SDL_TryLockMutex(SDL_mutex * mutex) #endif if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } retval = 0; @@ -162,7 +162,7 @@ int SDL_UnlockMutex(SDL_mutex * mutex) { if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } #if FAKE_RECURSIVE_MUTEX diff --git a/Engine/lib/sdl/src/thread/pthread/SDL_sysmutex_c.h b/Engine/lib/sdl/src/thread/pthread/SDL_sysmutex_c.h index 8c38367c0..722ed4a18 100644 --- a/Engine/lib/sdl/src/thread/pthread/SDL_sysmutex_c.h +++ b/Engine/lib/sdl/src/thread/pthread/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/pthread/SDL_syssem.c b/Engine/lib/sdl/src/thread/pthread/SDL_syssem.c index 9f3bc30d6..9a0c88822 100644 --- a/Engine/lib/sdl/src/thread/pthread/SDL_syssem.c +++ b/Engine/lib/sdl/src/thread/pthread/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -73,7 +73,7 @@ SDL_SemTryWait(SDL_sem * sem) int retval; if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } retval = SDL_MUTEX_TIMEDOUT; if (sem_trywait(&sem->sem) == 0) { @@ -88,7 +88,7 @@ SDL_SemWait(SDL_sem * sem) int retval; if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } do { @@ -115,7 +115,7 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) #endif if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } /* Try the easy cases first */ @@ -195,7 +195,7 @@ SDL_SemPost(SDL_sem * sem) int retval; if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } retval = sem_post(&sem->sem); diff --git a/Engine/lib/sdl/src/thread/pthread/SDL_systhread.c b/Engine/lib/sdl/src/thread/pthread/SDL_systhread.c index afed1d9c8..3b3f40fa1 100644 --- a/Engine/lib/sdl/src/thread/pthread/SDL_systhread.c +++ b/Engine/lib/sdl/src/thread/pthread/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,25 +30,24 @@ #endif #include +#include #ifdef __LINUX__ #include #include #include #include -#include #include "../../core/linux/SDL_dbus.h" #endif /* __LINUX__ */ -#if defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__) +#if (defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__)) && defined(HAVE_DLOPEN) #include #ifndef RTLD_DEFAULT #define RTLD_DEFAULT NULL #endif #endif -#include "SDL_platform.h" #include "SDL_thread.h" #include "../SDL_thread_c.h" #include "../SDL_systhread.h" @@ -79,10 +78,10 @@ RunThread(void *data) return NULL; } -#if defined(__MACOSX__) || defined(__IPHONEOS__) +#if (defined(__MACOSX__) || defined(__IPHONEOS__)) && defined(HAVE_DLOPEN) static SDL_bool checked_setname = SDL_FALSE; static int (*ppthread_setname_np)(const char*) = NULL; -#elif defined(__LINUX__) +#elif defined(__LINUX__) && defined(HAVE_DLOPEN) static SDL_bool checked_setname = SDL_FALSE; static int (*ppthread_setname_np)(pthread_t, const char*) = NULL; #endif @@ -92,7 +91,7 @@ SDL_SYS_CreateThread(SDL_Thread * thread) pthread_attr_t type; /* do this here before any threads exist, so there's no race condition. */ - #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) + #if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)) && defined(HAVE_DLOPEN) if (!checked_setname) { void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np"); #if defined(__MACOSX__) || defined(__IPHONEOS__) @@ -132,28 +131,35 @@ SDL_SYS_SetupThread(const char *name) #endif /* !__NACL__ */ if (name != NULL) { - #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) + #if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)) && defined(HAVE_DLOPEN) SDL_assert(checked_setname); if (ppthread_setname_np != NULL) { #if defined(__MACOSX__) || defined(__IPHONEOS__) ppthread_setname_np(name); #elif defined(__LINUX__) - ppthread_setname_np(pthread_self(), name); + if (ppthread_setname_np(pthread_self(), name) == ERANGE) { + char namebuf[16]; /* Limited to 16 char */ + SDL_strlcpy(namebuf, name, sizeof (namebuf)); + ppthread_setname_np(pthread_self(), namebuf); + } #endif } #elif HAVE_PTHREAD_SETNAME_NP #if defined(__NETBSD__) pthread_setname_np(pthread_self(), "%s", name); #else - pthread_setname_np(pthread_self(), name); + if (pthread_setname_np(pthread_self(), name) == ERANGE) { + char namebuf[16]; /* Limited to 16 char */ + SDL_strlcpy(namebuf, name, sizeof (namebuf)); + pthread_setname_np(pthread_self(), namebuf); + } #endif #elif HAVE_PTHREAD_SET_NAME_NP pthread_set_name_np(pthread_self(), name); #elif defined(__HAIKU__) /* The docs say the thread name can't be longer than B_OS_NAME_LENGTH. */ char namebuf[B_OS_NAME_LENGTH]; - SDL_snprintf(namebuf, sizeof (namebuf), "%s", name); - namebuf[sizeof (namebuf) - 1] = '\0'; + SDL_strlcpy(namebuf, name, sizeof (namebuf)); rename_thread(find_thread(NULL), namebuf); #endif } @@ -184,21 +190,10 @@ SDL_ThreadID(void) return ((SDL_threadID) pthread_self()); } -#if __LINUX__ -/** - \brief Sets the SDL priority (not nice level) for a thread, using setpriority() if appropriate, and RealtimeKit if available. - Differs from SDL_LinuxSetThreadPriority in also taking the desired scheduler policy, - such as SCHED_OTHER or SCHED_RR. - - \return 0 on success, or -1 on error. - */ -extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int schedPolicy); -#endif - int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) { -#if __NACL__ || __RISCOS__ +#if __NACL__ || __RISCOS__ || __OS2__ /* FIXME: Setting thread priority does not seem to be supported in NACL */ return 0; #else diff --git a/Engine/lib/sdl/src/thread/pthread/SDL_systhread_c.h b/Engine/lib/sdl/src/thread/pthread/SDL_systhread_c.h index 3a9c992eb..fc24425f8 100644 --- a/Engine/lib/sdl/src/thread/pthread/SDL_systhread_c.h +++ b/Engine/lib/sdl/src/thread/pthread/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/pthread/SDL_systls.c b/Engine/lib/sdl/src/thread/pthread/SDL_systls.c index e14571ca0..c55c69720 100644 --- a/Engine/lib/sdl/src/thread/pthread/SDL_systls.c +++ b/Engine/lib/sdl/src/thread/pthread/SDL_systls.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/stdcpp/SDL_syscond.cpp b/Engine/lib/sdl/src/thread/stdcpp/SDL_syscond.cpp index a50000768..90c38adba 100644 --- a/Engine/lib/sdl/src/thread/stdcpp/SDL_syscond.cpp +++ b/Engine/lib/sdl/src/thread/stdcpp/SDL_syscond.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -70,8 +70,7 @@ int SDL_CondSignal(SDL_cond * cond) { if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; + return SDL_InvalidParamError("cond"); } cond->cpp_cond.notify_one(); @@ -84,8 +83,7 @@ int SDL_CondBroadcast(SDL_cond * cond) { if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; + return SDL_InvalidParamError("cond"); } cond->cpp_cond.notify_all(); @@ -118,13 +116,11 @@ int SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) { if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; + return SDL_InvalidParamError("cond"); } if (!mutex) { - SDL_SetError("Passed a NULL mutex variable"); - return -1; + return SDL_InvalidParamError("mutex"); } try { @@ -148,8 +144,7 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) } } } catch (std::system_error & ex) { - SDL_SetError("unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what()); - return -1; + return SDL_SetError("unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what()); } } diff --git a/Engine/lib/sdl/src/thread/stdcpp/SDL_sysmutex.cpp b/Engine/lib/sdl/src/thread/stdcpp/SDL_sysmutex.cpp index b852c2d76..828801046 100644 --- a/Engine/lib/sdl/src/thread/stdcpp/SDL_sysmutex.cpp +++ b/Engine/lib/sdl/src/thread/stdcpp/SDL_sysmutex.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -65,16 +65,14 @@ int SDL_mutexP(SDL_mutex * mutex) { if (mutex == NULL) { - SDL_SetError("Passed a NULL mutex"); - return -1; + return SDL_InvalidParamError("mutex"); } try { mutex->cpp_mutex.lock(); return 0; } catch (std::system_error & ex) { - SDL_SetError("unable to lock a C++ mutex: code=%d; %s", ex.code(), ex.what()); - return -1; + return SDL_SetError("unable to lock a C++ mutex: code=%d; %s", ex.code(), ex.what()); } } @@ -84,7 +82,7 @@ SDL_TryLockMutex(SDL_mutex * mutex) { int retval = 0; if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } if (mutex->cpp_mutex.try_lock() == false) { @@ -99,8 +97,7 @@ int SDL_mutexV(SDL_mutex * mutex) { if (mutex == NULL) { - SDL_SetError("Passed a NULL mutex"); - return -1; + return SDL_InvalidParamError("mutex"); } mutex->cpp_mutex.unlock(); diff --git a/Engine/lib/sdl/src/thread/stdcpp/SDL_sysmutex_c.h b/Engine/lib/sdl/src/thread/stdcpp/SDL_sysmutex_c.h index f86995f1f..d80897e25 100644 --- a/Engine/lib/sdl/src/thread/stdcpp/SDL_sysmutex_c.h +++ b/Engine/lib/sdl/src/thread/stdcpp/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread.cpp b/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread.cpp index a61e7240e..3d818ac56 100644 --- a/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread.cpp +++ b/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -52,11 +52,9 @@ SDL_SYS_CreateThread(SDL_Thread * thread) thread->handle = (void *) new std::thread(std::move(cpp_thread)); return 0; } catch (std::system_error & ex) { - SDL_SetError("unable to start a C++ thread: code=%d; %s", ex.code(), ex.what()); - return -1; + return SDL_SetError("unable to start a C++ thread: code=%d; %s", ex.code(), ex.what()); } catch (std::bad_alloc &) { - SDL_OutOfMemory(); - return -1; + return SDL_OutOfMemory(); } } diff --git a/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread_c.h b/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread_c.h index 919d71c97..57c660a85 100644 --- a/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread_c.h +++ b/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/vita/SDL_syscond.c b/Engine/lib/sdl/src/thread/vita/SDL_syscond.c new file mode 100644 index 000000000..c6e46c475 --- /dev/null +++ b/Engine/lib/sdl/src/thread/vita/SDL_syscond.c @@ -0,0 +1,224 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_VITA + +/* An implementation of condition variables using semaphores and mutexes */ +/* + This implementation borrows heavily from the BeOS condition variable + implementation, written by Christopher Tate and Owen Smith. Thanks! + */ + +#include "SDL_thread.h" + +struct SDL_cond +{ + SDL_mutex *lock; + int waiting; + int signals; + SDL_sem *wait_sem; + SDL_sem *wait_done; +}; + +/* Create a condition variable */ +SDL_cond * +SDL_CreateCond(void) +{ + SDL_cond *cond; + + cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond)); + if (cond) { + cond->lock = SDL_CreateMutex(); + cond->wait_sem = SDL_CreateSemaphore(0); + cond->wait_done = SDL_CreateSemaphore(0); + cond->waiting = cond->signals = 0; + if (!cond->lock || !cond->wait_sem || !cond->wait_done) { + SDL_DestroyCond(cond); + cond = NULL; + } + } else { + SDL_OutOfMemory(); + } + return (cond); +} + +/* Destroy a condition variable */ +void +SDL_DestroyCond(SDL_cond * cond) +{ + if (cond) { + if (cond->wait_sem) { + SDL_DestroySemaphore(cond->wait_sem); + } + if (cond->wait_done) { + SDL_DestroySemaphore(cond->wait_done); + } + if (cond->lock) { + SDL_DestroyMutex(cond->lock); + } + SDL_free(cond); + } +} + +/* Restart one of the threads that are waiting on the condition variable */ +int +SDL_CondSignal(SDL_cond * cond) +{ + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if (cond->waiting > cond->signals) { + ++cond->signals; + SDL_SemPost(cond->wait_sem); + SDL_UnlockMutex(cond->lock); + SDL_SemWait(cond->wait_done); + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* Restart all threads that are waiting on the condition variable */ +int +SDL_CondBroadcast(SDL_cond * cond) +{ + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if (cond->waiting > cond->signals) { + int i, num_waiting; + + num_waiting = (cond->waiting - cond->signals); + cond->signals = cond->waiting; + for (i = 0; i < num_waiting; ++i) { + SDL_SemPost(cond->wait_sem); + } + /* Now all released threads are blocked here, waiting for us. + Collect them all (and win fabulous prizes!) :-) + */ + SDL_UnlockMutex(cond->lock); + for (i = 0; i < num_waiting; ++i) { + SDL_SemWait(cond->wait_done); + } + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* Wait on the condition variable for at most 'ms' milliseconds. + The mutex must be locked before entering this function! + The mutex is unlocked during the wait, and locked again after the wait. + +Typical use: + +Thread A: + SDL_LockMutex(lock); + while ( ! condition ) { + SDL_CondWait(cond, lock); + } + SDL_UnlockMutex(lock); + +Thread B: + SDL_LockMutex(lock); + ... + condition = true; + ... + SDL_CondSignal(cond); + SDL_UnlockMutex(lock); + */ +int +SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) +{ + int retval; + + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + /* Obtain the protection mutex, and increment the number of waiters. + This allows the signal mechanism to only perform a signal if there + are waiting threads. + */ + SDL_LockMutex(cond->lock); + ++cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Unlock the mutex, as is required by condition variable semantics */ + SDL_UnlockMutex(mutex); + + /* Wait for a signal */ + if (ms == SDL_MUTEX_MAXWAIT) { + retval = SDL_SemWait(cond->wait_sem); + } else { + retval = SDL_SemWaitTimeout(cond->wait_sem, ms); + } + + /* Let the signaler know we have completed the wait, otherwise + the signaler can race ahead and get the condition semaphore + if we are stopped between the mutex unlock and semaphore wait, + giving a deadlock. See the following URL for details: + http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html + */ + SDL_LockMutex(cond->lock); + if (cond->signals > 0) { + /* If we timed out, we need to eat a condition signal */ + if (retval > 0) { + SDL_SemWait(cond->wait_sem); + } + /* We always notify the signal thread that we are done */ + SDL_SemPost(cond->wait_done); + + /* Signal handshake complete */ + --cond->signals; + } + --cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Lock the mutex, as is required by condition variable semantics */ + SDL_LockMutex(mutex); + + return retval; +} + +/* Wait on the condition variable forever */ +int +SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) +{ + return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); +} + +#endif /* SDL_THREAD_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/vita/SDL_sysmutex.c b/Engine/lib/sdl/src/thread/vita/SDL_sysmutex.c new file mode 100644 index 000000000..6327182cc --- /dev/null +++ b/Engine/lib/sdl/src/thread/vita/SDL_sysmutex.c @@ -0,0 +1,149 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_VITA + +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + +#include +#include + +struct SDL_mutex +{ + SceKernelLwMutexWork lock; +}; + +/* Create a mutex */ +SDL_mutex * +SDL_CreateMutex(void) +{ + SDL_mutex *mutex = NULL; + SceInt32 res = 0; + + /* Allocate mutex memory */ + mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); + if (mutex) { + + res = sceKernelCreateLwMutex( + &mutex->lock, + "SDL mutex", + SCE_KERNEL_MUTEX_ATTR_RECURSIVE, + 0, + NULL + ); + + if (res < 0) { + SDL_SetError("Error trying to create mutex: %x", res); + } + } else { + SDL_OutOfMemory(); + } + return mutex; +} + +/* Free the mutex */ +void +SDL_DestroyMutex(SDL_mutex * mutex) +{ + if (mutex) { + sceKernelDeleteLwMutex(&mutex->lock); + SDL_free(mutex); + } +} + +/* Try to lock the mutex */ +int +SDL_TryLockMutex(SDL_mutex * mutex) +{ +#if SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + if (mutex == NULL) { + return SDL_InvalidParamError("mutex"); + } + + res = sceKernelTryLockLwMutex(&mutex->lock, 1); + switch (res) { + case SCE_KERNEL_OK: + return 0; + break; + case SCE_KERNEL_ERROR_MUTEX_FAILED_TO_OWN: + return SDL_MUTEX_TIMEDOUT; + break; + default: + return SDL_SetError("Error trying to lock mutex: %x", res); + break; + } + + return -1; +#endif /* SDL_THREADS_DISABLED */ +} + + +/* Lock the mutex */ +int +SDL_mutexP(SDL_mutex * mutex) +{ +#if SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + if (mutex == NULL) { + return SDL_InvalidParamError("mutex"); + } + + res = sceKernelLockLwMutex(&mutex->lock, 1, NULL); + if (res != SCE_KERNEL_OK) { + return SDL_SetError("Error trying to lock mutex: %x", res); + } + + return 0; +#endif /* SDL_THREADS_DISABLED */ +} + +/* Unlock the mutex */ +int +SDL_mutexV(SDL_mutex * mutex) +{ +#if SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + + if (mutex == NULL) { + return SDL_InvalidParamError("mutex"); + } + + res = sceKernelUnlockLwMutex(&mutex->lock, 1); + if (res != 0) { + return SDL_SetError("Error trying to unlock mutex: %x", res); + } + + return 0; +#endif /* SDL_THREADS_DISABLED */ +} + +#endif /* SDL_THREAD_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/vita/SDL_sysmutex_c.h b/Engine/lib/sdl/src/thread/vita/SDL_sysmutex_c.h new file mode 100644 index 000000000..057bcc4bc --- /dev/null +++ b/Engine/lib/sdl/src/thread/vita/SDL_sysmutex_c.h @@ -0,0 +1,23 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/vita/SDL_syssem.c b/Engine/lib/sdl/src/thread/vita/SDL_syssem.c new file mode 100644 index 000000000..7fecd6ca2 --- /dev/null +++ b/Engine/lib/sdl/src/thread/vita/SDL_syssem.c @@ -0,0 +1,162 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_VITA + +/* Semaphore functions for the VITA. */ + +#include +#include + +#include "SDL_error.h" +#include "SDL_thread.h" + +#include +#include +#include + +struct SDL_semaphore { + SceUID semid; +}; + + +/* Create a semaphore */ +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_sem *sem; + + sem = (SDL_sem *) SDL_malloc(sizeof(*sem)); + if (sem != NULL) { + /* TODO: Figure out the limit on the maximum value. */ + sem->semid = sceKernelCreateSema("SDL sema", 0, initial_value, 255, NULL); + if (sem->semid < 0) { + SDL_SetError("Couldn't create semaphore"); + SDL_free(sem); + sem = NULL; + } + } else { + SDL_OutOfMemory(); + } + + return sem; +} + +/* Free the semaphore */ +void SDL_DestroySemaphore(SDL_sem *sem) +{ + if (sem != NULL) { + if (sem->semid > 0) { + sceKernelDeleteSema(sem->semid); + sem->semid = 0; + } + + SDL_free(sem); + } +} + +/* TODO: This routine is a bit overloaded. + * If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass + * NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout + * is specified, convert it to microseconds. */ +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + Uint32 *pTimeout; + unsigned int res; + + if (sem == NULL) { + SDL_InvalidParamError("sem"); + return 0; + } + + if (timeout == 0) { + res = sceKernelPollSema(sem->semid, 1); + if (res < 0) { + return SDL_MUTEX_TIMEDOUT; + } + return 0; + } + + if (timeout == SDL_MUTEX_MAXWAIT) { + pTimeout = NULL; + } else { + timeout *= 1000; /* Convert to microseconds. */ + pTimeout = &timeout; + } + + res = sceKernelWaitSema(sem->semid, 1, pTimeout); + switch (res) { + case SCE_KERNEL_OK: + return 0; + case SCE_KERNEL_ERROR_WAIT_TIMEOUT: + return SDL_MUTEX_TIMEDOUT; + default: + return SDL_SetError("WaitForSingleObject() failed"); + } +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + return SDL_SemWaitTimeout(sem, 0); +} + +int SDL_SemWait(SDL_sem *sem) +{ + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +/* Returns the current count of the semaphore */ +Uint32 SDL_SemValue(SDL_sem *sem) +{ + SceKernelSemaInfo info; + info.size = sizeof(info); + + if (sem == NULL) { + SDL_InvalidParamError("sem"); + return 0; + } + + if (sceKernelGetSemaInfo(sem->semid, &info) >= 0) { + return info.currentCount; + } + + return 0; +} + +int SDL_SemPost(SDL_sem *sem) +{ + int res; + + if (sem == NULL) { + return SDL_InvalidParamError("sem"); + } + + res = sceKernelSignalSema(sem->semid, 1); + if (res < 0) { + return SDL_SetError("sceKernelSignalSema() failed"); + } + + return 0; +} + +#endif /* SDL_THREAD_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/vita/SDL_systhread.c b/Engine/lib/sdl/src/thread/vita/SDL_systhread.c new file mode 100644 index 000000000..91ae06256 --- /dev/null +++ b/Engine/lib/sdl/src/thread/vita/SDL_systhread.c @@ -0,0 +1,138 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_VITA + +/* VITA thread management routines for SDL */ + +#include +#include + +#include "SDL_error.h" +#include "SDL_thread.h" +#include "../SDL_systhread.h" +#include "../SDL_thread_c.h" +#include +#include + +#define VITA_THREAD_STACK_SIZE_MIN 0x1000 // 4KiB +#define VITA_THREAD_STACK_SIZE_MAX 0x2000000 // 32MiB +#define VITA_THREAD_STACK_SIZE_DEFAULT 0x10000 // 64KiB +#define VITA_THREAD_NAME_MAX 32 + +#define VITA_THREAD_PRIORITY_LOW 191 +#define VITA_THREAD_PRIORITY_NORMAL 160 +#define VITA_THREAD_PRIORITY_HIGH 112 +#define VITA_THREAD_PRIORITY_TIME_CRITICAL 64 + +static int ThreadEntry(SceSize args, void *argp) +{ + SDL_RunThread(*(SDL_Thread **) argp); + return 0; +} + +int SDL_SYS_CreateThread(SDL_Thread *thread) +{ + char thread_name[VITA_THREAD_NAME_MAX]; + size_t stack_size = VITA_THREAD_STACK_SIZE_DEFAULT; + + SDL_strlcpy(thread_name, "SDL thread", VITA_THREAD_NAME_MAX); + if (thread->name) { + SDL_strlcpy(thread_name, thread->name, VITA_THREAD_NAME_MAX); + } + + if (thread->stacksize) { + if (thread->stacksize < VITA_THREAD_STACK_SIZE_MIN) { + thread->stacksize = VITA_THREAD_STACK_SIZE_MIN; + } + if (thread->stacksize > VITA_THREAD_STACK_SIZE_MAX) { + thread->stacksize = VITA_THREAD_STACK_SIZE_MAX; + } + stack_size = thread->stacksize; + } + + /* Create new thread with the same priority as the current thread */ + thread->handle = sceKernelCreateThread( + thread_name, // name + ThreadEntry, // function to run + 0, // priority. 0 means priority of calling thread + stack_size, // stack size + 0, // attibutes. always 0 + 0, // cpu affinity mask. 0 = all CPUs + NULL // opt. always NULL + ); + + if (thread->handle < 0) { + return SDL_SetError("sceKernelCreateThread() failed"); + } + + sceKernelStartThread(thread->handle, 4, &thread); + return 0; +} + +void SDL_SYS_SetupThread(const char *name) +{ + /* Do nothing. */ +} + +SDL_threadID SDL_ThreadID(void) +{ + return (SDL_threadID) sceKernelGetThreadId(); +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + sceKernelWaitThreadEnd(thread->handle, NULL, NULL); + sceKernelDeleteThread(thread->handle); +} + +void SDL_SYS_DetachThread(SDL_Thread *thread) +{ + /* Do nothing. */ +} + +int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + int value = VITA_THREAD_PRIORITY_NORMAL; + + switch(priority) { + case SDL_THREAD_PRIORITY_LOW: + value = VITA_THREAD_PRIORITY_LOW; + break; + case SDL_THREAD_PRIORITY_NORMAL: + value = VITA_THREAD_PRIORITY_NORMAL; + break; + case SDL_THREAD_PRIORITY_HIGH: + value = VITA_THREAD_PRIORITY_HIGH; + break; + case SDL_THREAD_PRIORITY_TIME_CRITICAL: + value = VITA_THREAD_PRIORITY_TIME_CRITICAL; + break; + } + + return sceKernelChangeThreadPriority(0, value); + +} + +#endif /* SDL_THREAD_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/vita/SDL_systhread_c.h b/Engine/lib/sdl/src/thread/vita/SDL_systhread_c.h new file mode 100644 index 000000000..f5f707464 --- /dev/null +++ b/Engine/lib/sdl/src/thread/vita/SDL_systhread_c.h @@ -0,0 +1,26 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include + +typedef SceUID SYS_ThreadHandle; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/windows/SDL_syscond_cv.c b/Engine/lib/sdl/src/thread/windows/SDL_syscond_cv.c new file mode 100644 index 000000000..54d34084f --- /dev/null +++ b/Engine/lib/sdl/src/thread/windows/SDL_syscond_cv.c @@ -0,0 +1,299 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#include "SDL_hints.h" +#include "SDL_thread.h" + +#include "../generic/SDL_syscond_c.h" +#include "SDL_sysmutex_c.h" + +typedef SDL_cond * (*pfnSDL_CreateCond)(void); +typedef void (*pfnSDL_DestroyCond)(SDL_cond *); +typedef int (*pfnSDL_CondSignal)(SDL_cond *); +typedef int (*pfnSDL_CondBroadcast)(SDL_cond *); +typedef int (*pfnSDL_CondWait)(SDL_cond *, SDL_mutex *); +typedef int (*pfnSDL_CondWaitTimeout)(SDL_cond *, SDL_mutex *, Uint32); + +typedef struct SDL_cond_impl_t +{ + pfnSDL_CreateCond Create; + pfnSDL_DestroyCond Destroy; + pfnSDL_CondSignal Signal; + pfnSDL_CondBroadcast Broadcast; + pfnSDL_CondWait Wait; + pfnSDL_CondWaitTimeout WaitTimeout; +} SDL_cond_impl_t; + +/* Implementation will be chosen at runtime based on available Kernel features */ +static SDL_cond_impl_t SDL_cond_impl_active = {0}; + + +/** + * Native Windows Condition Variable (SRW Locks) + */ + +#ifndef CONDITION_VARIABLE_INIT +#define CONDITION_VARIABLE_INIT {0} +typedef struct CONDITION_VARIABLE { + PVOID Ptr; +} CONDITION_VARIABLE, *PCONDITION_VARIABLE; +#endif + +#if __WINRT__ +#define pWakeConditionVariable WakeConditionVariable +#define pWakeAllConditionVariable WakeAllConditionVariable +#define pSleepConditionVariableSRW SleepConditionVariableSRW +#define pSleepConditionVariableCS SleepConditionVariableCS +#else +typedef VOID(WINAPI *pfnWakeConditionVariable)(PCONDITION_VARIABLE); +typedef VOID(WINAPI *pfnWakeAllConditionVariable)(PCONDITION_VARIABLE); +typedef BOOL(WINAPI *pfnSleepConditionVariableSRW)(PCONDITION_VARIABLE, PSRWLOCK, DWORD, ULONG); +typedef BOOL(WINAPI* pfnSleepConditionVariableCS)(PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD); + +static pfnWakeConditionVariable pWakeConditionVariable = NULL; +static pfnWakeAllConditionVariable pWakeAllConditionVariable = NULL; +static pfnSleepConditionVariableSRW pSleepConditionVariableSRW = NULL; +static pfnSleepConditionVariableCS pSleepConditionVariableCS = NULL; +#endif + +typedef struct SDL_cond_cv +{ + CONDITION_VARIABLE cond; +} SDL_cond_cv; + + +static SDL_cond * +SDL_CreateCond_cv(void) +{ + SDL_cond_cv *cond; + + /* Relies on CONDITION_VARIABLE_INIT == 0. */ + cond = (SDL_cond_cv *) SDL_calloc(1, sizeof(*cond)); + if (!cond) { + SDL_OutOfMemory(); + } + + return (SDL_cond *)cond; +} + +static void +SDL_DestroyCond_cv(SDL_cond * cond) +{ + if (cond) { + /* There are no kernel allocated resources */ + SDL_free(cond); + } +} + +static int +SDL_CondSignal_cv(SDL_cond * _cond) +{ + SDL_cond_cv *cond = (SDL_cond_cv *)_cond; + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + pWakeConditionVariable(&cond->cond); + + return 0; +} + +static int +SDL_CondBroadcast_cv(SDL_cond * _cond) +{ + SDL_cond_cv *cond = (SDL_cond_cv *)_cond; + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + pWakeAllConditionVariable(&cond->cond); + + return 0; +} + +static int +SDL_CondWaitTimeout_cv(SDL_cond * _cond, SDL_mutex * _mutex, Uint32 ms) +{ + SDL_cond_cv *cond = (SDL_cond_cv *)_cond; + DWORD timeout; + int ret; + + if (!cond) { + return SDL_InvalidParamError("cond"); + } + if (!_mutex) { + return SDL_InvalidParamError("mutex"); + } + + if (ms == SDL_MUTEX_MAXWAIT) { + timeout = INFINITE; + } else { + timeout = (DWORD) ms; + } + + if (SDL_mutex_impl_active.Type == SDL_MUTEX_SRW) { + SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex; + + if (mutex->count != 1 || mutex->owner != GetCurrentThreadId()) { + return SDL_SetError("Passed mutex is not locked or locked recursively"); + } + + /* The mutex must be updated to the released state */ + mutex->count = 0; + mutex->owner = 0; + + if (pSleepConditionVariableSRW(&cond->cond, &mutex->srw, timeout, 0) == FALSE) { + if (GetLastError() == ERROR_TIMEOUT) { + ret = SDL_MUTEX_TIMEDOUT; + } else { + ret = SDL_SetError("SleepConditionVariableSRW() failed"); + } + } else { + ret = 0; + } + + /* The mutex is owned by us again, regardless of status of the wait */ + SDL_assert(mutex->count == 0 && mutex->owner == 0); + mutex->count = 1; + mutex->owner = GetCurrentThreadId(); + } else { + SDL_mutex_cs *mutex = (SDL_mutex_cs *)_mutex; + + SDL_assert(SDL_mutex_impl_active.Type == SDL_MUTEX_CS); + + if (pSleepConditionVariableCS(&cond->cond, &mutex->cs, timeout) == FALSE) { + if (GetLastError() == ERROR_TIMEOUT) { + ret = SDL_MUTEX_TIMEDOUT; + } else { + ret = SDL_SetError("SleepConditionVariableCS() failed"); + } + } else { + ret = 0; + } + } + + return ret; +} + +static int +SDL_CondWait_cv(SDL_cond * cond, SDL_mutex * mutex) { + return SDL_CondWaitTimeout_cv(cond, mutex, SDL_MUTEX_MAXWAIT); +} + +static const SDL_cond_impl_t SDL_cond_impl_cv = +{ + &SDL_CreateCond_cv, + &SDL_DestroyCond_cv, + &SDL_CondSignal_cv, + &SDL_CondBroadcast_cv, + &SDL_CondWait_cv, + &SDL_CondWaitTimeout_cv, +}; + +/** + * Generic Condition Variable implementation using SDL_mutex and SDL_sem + */ + +static const SDL_cond_impl_t SDL_cond_impl_generic = +{ + &SDL_CreateCond_generic, + &SDL_DestroyCond_generic, + &SDL_CondSignal_generic, + &SDL_CondBroadcast_generic, + &SDL_CondWait_generic, + &SDL_CondWaitTimeout_generic, +}; + + +SDL_cond * +SDL_CreateCond(void) +{ + if (SDL_cond_impl_active.Create == NULL) { + /* Default to generic implementation, works with all mutex implementations */ + const SDL_cond_impl_t * impl = &SDL_cond_impl_generic; + + if (SDL_mutex_impl_active.Type == SDL_MUTEX_INVALID) { + /* The mutex implementation isn't decided yet, trigger it */ + SDL_mutex *mutex = SDL_CreateMutex(); + if (!mutex) { + return NULL; + } + SDL_DestroyMutex(mutex); + + SDL_assert(SDL_mutex_impl_active.Type != SDL_MUTEX_INVALID); + } + +#if __WINRT__ + /* Link statically on this platform */ + impl = &SDL_cond_impl_cv; +#else + { + HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll")); + if (kernel32) { + pWakeConditionVariable = (pfnWakeConditionVariable) GetProcAddress(kernel32, "WakeConditionVariable"); + pWakeAllConditionVariable = (pfnWakeAllConditionVariable) GetProcAddress(kernel32, "WakeAllConditionVariable"); + pSleepConditionVariableSRW = (pfnSleepConditionVariableSRW) GetProcAddress(kernel32, "SleepConditionVariableSRW"); + pSleepConditionVariableCS = (pfnSleepConditionVariableCS) GetProcAddress(kernel32, "SleepConditionVariableCS"); + if (pWakeConditionVariable && pWakeAllConditionVariable && pSleepConditionVariableSRW && pSleepConditionVariableCS) { + /* Use the Windows provided API */ + impl = &SDL_cond_impl_cv; + } + } + } +#endif + + SDL_memcpy(&SDL_cond_impl_active, impl, sizeof(SDL_cond_impl_active)); + } + return SDL_cond_impl_active.Create(); +} + +void +SDL_DestroyCond(SDL_cond * cond) +{ + SDL_cond_impl_active.Destroy(cond); +} + +int +SDL_CondSignal(SDL_cond * cond) +{ + return SDL_cond_impl_active.Signal(cond); +} + +int +SDL_CondBroadcast(SDL_cond * cond) +{ + return SDL_cond_impl_active.Broadcast(cond); +} + +int +SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) +{ + return SDL_cond_impl_active.WaitTimeout(cond, mutex, ms); +} + +int +SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) +{ + return SDL_cond_impl_active.Wait(cond, mutex); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/windows/SDL_sysmutex.c b/Engine/lib/sdl/src/thread/windows/SDL_sysmutex.c index 4e393742a..b0b4abcb0 100644 --- a/Engine/lib/sdl/src/thread/windows/SDL_sysmutex.c +++ b/Engine/lib/sdl/src/thread/windows/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,26 +22,161 @@ #if SDL_THREAD_WINDOWS -/* Mutex functions using the Win32 API */ - -#include "../../core/windows/SDL_windows.h" - -#include "SDL_mutex.h" +/** + * Mutex functions using the Win32 API + * There are two implementations available based on: + * - Critical Sections. Available on all OS versions since Windows XP. + * - Slim Reader/Writer Locks. Requires Windows 7 or newer. + * which are chosen at runtime. + */ -struct SDL_mutex +#include "SDL_hints.h" + +#include "SDL_sysmutex_c.h" + + +/* Implementation will be chosen at runtime based on available Kernel features */ +SDL_mutex_impl_t SDL_mutex_impl_active = {0}; + + +/** + * Implementation based on Slim Reader/Writer (SRW) Locks for Win 7 and newer. + */ + +#if __WINRT__ +/* Functions are guaranteed to be available */ +#define pReleaseSRWLockExclusive ReleaseSRWLockExclusive +#define pAcquireSRWLockExclusive AcquireSRWLockExclusive +#define pTryAcquireSRWLockExclusive TryAcquireSRWLockExclusive +#else +typedef VOID(WINAPI *pfnReleaseSRWLockExclusive)(PSRWLOCK); +typedef VOID(WINAPI *pfnAcquireSRWLockExclusive)(PSRWLOCK); +typedef BOOLEAN(WINAPI *pfnTryAcquireSRWLockExclusive)(PSRWLOCK); +static pfnReleaseSRWLockExclusive pReleaseSRWLockExclusive = NULL; +static pfnAcquireSRWLockExclusive pAcquireSRWLockExclusive = NULL; +static pfnTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive = NULL; +#endif + +static SDL_mutex * +SDL_CreateMutex_srw(void) { - CRITICAL_SECTION cs; + SDL_mutex_srw *mutex; + + /* Relies on SRWLOCK_INIT == 0. */ + mutex = (SDL_mutex_srw *) SDL_calloc(1, sizeof(*mutex)); + if (!mutex) { + SDL_OutOfMemory(); + } + + return (SDL_mutex *)mutex; +} + +static void +SDL_DestroyMutex_srw(SDL_mutex * mutex) +{ + if (mutex) { + /* There are no kernel allocated resources */ + SDL_free(mutex); + } +} + +static int +SDL_LockMutex_srw(SDL_mutex * _mutex) +{ + SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex; + DWORD this_thread; + + if (mutex == NULL) { + return SDL_InvalidParamError("mutex"); + } + + this_thread = GetCurrentThreadId(); + if (mutex->owner == this_thread) { + ++mutex->count; + } else { + /* The order of operations is important. + We set the locking thread id after we obtain the lock + so unlocks from other threads will fail. + */ + pAcquireSRWLockExclusive(&mutex->srw); + SDL_assert(mutex->count == 0 && mutex->owner == 0); + mutex->owner = this_thread; + mutex->count = 1; + } + return 0; +} + +static int +SDL_TryLockMutex_srw(SDL_mutex * _mutex) +{ + SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex; + DWORD this_thread; + int retval = 0; + + if (mutex == NULL) { + return SDL_InvalidParamError("mutex"); + } + + this_thread = GetCurrentThreadId(); + if (mutex->owner == this_thread) { + ++mutex->count; + } else { + if (pTryAcquireSRWLockExclusive(&mutex->srw) != 0) { + SDL_assert(mutex->count == 0 && mutex->owner == 0); + mutex->owner = this_thread; + mutex->count = 1; + } else { + retval = SDL_MUTEX_TIMEDOUT; + } + } + return retval; +} + +static int +SDL_UnlockMutex_srw(SDL_mutex * _mutex) +{ + SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex; + + if (mutex == NULL) { + return SDL_InvalidParamError("mutex"); + } + + if (mutex->owner == GetCurrentThreadId()) { + if (--mutex->count == 0) { + mutex->owner = 0; + pReleaseSRWLockExclusive(&mutex->srw); + } + } else { + return SDL_SetError("mutex not owned by this thread"); + } + + return 0; +} + +static const SDL_mutex_impl_t SDL_mutex_impl_srw = +{ + &SDL_CreateMutex_srw, + &SDL_DestroyMutex_srw, + &SDL_LockMutex_srw, + &SDL_TryLockMutex_srw, + &SDL_UnlockMutex_srw, + SDL_MUTEX_SRW, }; + +/** + * Fallback Mutex implementation using Critical Sections (before Win 7) + */ + /* Create a mutex */ -SDL_mutex * -SDL_CreateMutex(void) +static SDL_mutex * +SDL_CreateMutex_cs(void) { - SDL_mutex *mutex; + SDL_mutex_cs *mutex; /* Allocate mutex memory */ - mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); + mutex = (SDL_mutex_cs *) SDL_malloc(sizeof(*mutex)); if (mutex) { /* Initialize */ /* On SMP systems, a non-zero spin count generally helps performance */ @@ -53,13 +188,14 @@ SDL_CreateMutex(void) } else { SDL_OutOfMemory(); } - return (mutex); + return (SDL_mutex *)mutex; } /* Free the mutex */ -void -SDL_DestroyMutex(SDL_mutex * mutex) +static void +SDL_DestroyMutex_cs(SDL_mutex * mutex_) { + SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_; if (mutex) { DeleteCriticalSection(&mutex->cs); SDL_free(mutex); @@ -67,24 +203,26 @@ SDL_DestroyMutex(SDL_mutex * mutex) } /* Lock the mutex */ -int -SDL_LockMutex(SDL_mutex * mutex) +static int +SDL_LockMutex_cs(SDL_mutex * mutex_) { + SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_; if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } EnterCriticalSection(&mutex->cs); - return (0); + return 0; } /* TryLock the mutex */ -int -SDL_TryLockMutex(SDL_mutex * mutex) +static int +SDL_TryLockMutex_cs(SDL_mutex * mutex_) { + SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_; int retval = 0; if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } if (TryEnterCriticalSection(&mutex->cs) == 0) { @@ -94,15 +232,84 @@ SDL_TryLockMutex(SDL_mutex * mutex) } /* Unlock the mutex */ -int -SDL_UnlockMutex(SDL_mutex * mutex) +static int +SDL_UnlockMutex_cs(SDL_mutex * mutex_) { + SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_; if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return SDL_InvalidParamError("mutex"); } LeaveCriticalSection(&mutex->cs); - return (0); + return 0; +} + +static const SDL_mutex_impl_t SDL_mutex_impl_cs = +{ + &SDL_CreateMutex_cs, + &SDL_DestroyMutex_cs, + &SDL_LockMutex_cs, + &SDL_TryLockMutex_cs, + &SDL_UnlockMutex_cs, + SDL_MUTEX_CS, +}; + + +/** + * Runtime selection and redirection + */ + +SDL_mutex * +SDL_CreateMutex(void) +{ + if (SDL_mutex_impl_active.Create == NULL) { + /* Default to fallback implementation */ + const SDL_mutex_impl_t * impl = &SDL_mutex_impl_cs; + + if (!SDL_GetHintBoolean(SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS, SDL_FALSE)) { +#if __WINRT__ + /* Link statically on this platform */ + impl = &SDL_mutex_impl_srw; +#else + /* Try faster implementation for Windows 7 and newer */ + HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll")); + if (kernel32) { + /* Requires Vista: */ + pReleaseSRWLockExclusive = (pfnReleaseSRWLockExclusive) GetProcAddress(kernel32, "ReleaseSRWLockExclusive"); + pAcquireSRWLockExclusive = (pfnAcquireSRWLockExclusive) GetProcAddress(kernel32, "AcquireSRWLockExclusive"); + /* Requires 7: */ + pTryAcquireSRWLockExclusive = (pfnTryAcquireSRWLockExclusive) GetProcAddress(kernel32, "TryAcquireSRWLockExclusive"); + if (pReleaseSRWLockExclusive && pAcquireSRWLockExclusive && pTryAcquireSRWLockExclusive) { + impl = &SDL_mutex_impl_srw; + } + } +#endif + } + + /* Copy instead of using pointer to save one level of indirection */ + SDL_memcpy(&SDL_mutex_impl_active, impl, sizeof(SDL_mutex_impl_active)); + } + return SDL_mutex_impl_active.Create(); +} + +void +SDL_DestroyMutex(SDL_mutex * mutex) { + SDL_mutex_impl_active.Destroy(mutex); +} + +int +SDL_LockMutex(SDL_mutex * mutex) { + return SDL_mutex_impl_active.Lock(mutex); +} + +int +SDL_TryLockMutex(SDL_mutex * mutex) { + return SDL_mutex_impl_active.TryLock(mutex); +} + +int +SDL_UnlockMutex(SDL_mutex * mutex) { + return SDL_mutex_impl_active.Unlock(mutex); } #endif /* SDL_THREAD_WINDOWS */ diff --git a/Engine/lib/sdl/src/thread/windows/SDL_sysmutex_c.h b/Engine/lib/sdl/src/thread/windows/SDL_sysmutex_c.h new file mode 100644 index 000000000..a97c5293d --- /dev/null +++ b/Engine/lib/sdl/src/thread/windows/SDL_sysmutex_c.h @@ -0,0 +1,74 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#include "../../core/windows/SDL_windows.h" + +#include "SDL_mutex.h" + +typedef SDL_mutex * (*pfnSDL_CreateMutex)(void); +typedef int (*pfnSDL_LockMutex)(SDL_mutex *); +typedef int (*pfnSDL_TryLockMutex)(SDL_mutex *); +typedef int (*pfnSDL_UnlockMutex)(SDL_mutex *); +typedef void (*pfnSDL_DestroyMutex)(SDL_mutex *); + +typedef enum +{ + SDL_MUTEX_INVALID = 0, + SDL_MUTEX_SRW, + SDL_MUTEX_CS, +} SDL_MutexType; + +typedef struct SDL_mutex_impl_t +{ + pfnSDL_CreateMutex Create; + pfnSDL_DestroyMutex Destroy; + pfnSDL_LockMutex Lock; + pfnSDL_TryLockMutex TryLock; + pfnSDL_UnlockMutex Unlock; + /* Needed by SDL_cond: */ + SDL_MutexType Type; +} SDL_mutex_impl_t; + +extern SDL_mutex_impl_t SDL_mutex_impl_active; + + +#ifndef SRWLOCK_INIT +#define SRWLOCK_INIT {0} +typedef struct _SRWLOCK { + PVOID Ptr; +} SRWLOCK, *PSRWLOCK; +#endif + +typedef struct SDL_mutex_srw +{ + SRWLOCK srw; + /* SRW Locks are not recursive, that has to be handled by SDL: */ + DWORD count; + DWORD owner; +} SDL_mutex_srw; + +typedef struct SDL_mutex_cs +{ + CRITICAL_SECTION cs; +} SDL_mutex_cs; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/windows/SDL_syssem.c b/Engine/lib/sdl/src/thread/windows/SDL_syssem.c index 217ea32c7..794a713a8 100644 --- a/Engine/lib/sdl/src/thread/windows/SDL_syssem.c +++ b/Engine/lib/sdl/src/thread/windows/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,27 +22,256 @@ #if SDL_THREAD_WINDOWS -/* Semaphore functions using the Win32 API */ +/** + * Semaphore functions using the Win32 API + * There are two implementations available based on: + * - Kernel Semaphores. Available on all OS versions. (kern) + * Heavy-weight inter-process kernel objects. + * - Atomics and WaitOnAddress API. (atom) + * Faster due to significantly less context switches. + * Requires Windows 8 or newer. + * which are chosen at runtime. +*/ #include "../../core/windows/SDL_windows.h" +#include "SDL_hints.h" #include "SDL_thread.h" +#include "SDL_timer.h" -struct SDL_semaphore +typedef SDL_sem * (*pfnSDL_CreateSemaphore)(Uint32); +typedef void (*pfnSDL_DestroySemaphore)(SDL_sem *); +typedef int (*pfnSDL_SemWaitTimeout)(SDL_sem *, Uint32); +typedef int (*pfnSDL_SemTryWait)(SDL_sem *); +typedef int (*pfnSDL_SemWait)(SDL_sem *); +typedef Uint32 (*pfnSDL_SemValue)(SDL_sem *); +typedef int (*pfnSDL_SemPost)(SDL_sem *); + +typedef struct SDL_semaphore_impl_t +{ + pfnSDL_CreateSemaphore Create; + pfnSDL_DestroySemaphore Destroy; + pfnSDL_SemWaitTimeout WaitTimeout; + pfnSDL_SemTryWait TryWait; + pfnSDL_SemWait Wait; + pfnSDL_SemValue Value; + pfnSDL_SemPost Post; +} SDL_sem_impl_t; + +/* Implementation will be chosen at runtime based on available Kernel features */ +static SDL_sem_impl_t SDL_sem_impl_active = {0}; + + +/** + * Atomic + WaitOnAddress implementation + */ + +/* APIs not available on WinPhone 8.1 */ +/* https://www.microsoft.com/en-us/download/details.aspx?id=47328 */ + +#if (HAVE_WINAPIFAMILY_H) && defined(WINAPI_FAMILY_PHONE_APP) +#define SDL_WINAPI_FAMILY_PHONE (WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) +#else +#define SDL_WINAPI_FAMILY_PHONE 0 +#endif + +#if !SDL_WINAPI_FAMILY_PHONE +#if __WINRT__ +/* Functions are guaranteed to be available */ +#define pWaitOnAddress WaitOnAddress +#define pWakeByAddressSingle WakeByAddressSingle +#else +typedef BOOL(WINAPI *pfnWaitOnAddress)(volatile VOID*, PVOID, SIZE_T, DWORD); +typedef VOID(WINAPI *pfnWakeByAddressSingle)(PVOID); + +static pfnWaitOnAddress pWaitOnAddress = NULL; +static pfnWakeByAddressSingle pWakeByAddressSingle = NULL; +#endif + +typedef struct SDL_semaphore_atom +{ + LONG count; +} SDL_sem_atom; + +static SDL_sem * +SDL_CreateSemaphore_atom(Uint32 initial_value) +{ + SDL_sem_atom *sem; + + sem = (SDL_sem_atom *) SDL_malloc(sizeof(*sem)); + if (sem) { + sem->count = initial_value; + } else { + SDL_OutOfMemory(); + } + return (SDL_sem *)sem; +} + +static void +SDL_DestroySemaphore_atom(SDL_sem * sem) +{ + if (sem) { + SDL_free(sem); + } +} + +static int +SDL_SemTryWait_atom(SDL_sem * _sem) +{ + SDL_sem_atom *sem = (SDL_sem_atom *)_sem; + LONG count; + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + count = sem->count; + if (count == 0) { + return SDL_MUTEX_TIMEDOUT; + } + + if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) { + return 0; + } + + return SDL_MUTEX_TIMEDOUT; +} + +static int +SDL_SemWait_atom(SDL_sem * _sem) +{ + SDL_sem_atom *sem = (SDL_sem_atom *)_sem; + LONG count; + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + for (;;) { + count = sem->count; + while (count == 0) { + if (pWaitOnAddress(&sem->count, &count, sizeof(sem->count), INFINITE) == FALSE) { + return SDL_SetError("WaitOnAddress() failed"); + } + count = sem->count; + } + + if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) { + return 0; + } + } +} + +static int +SDL_SemWaitTimeout_atom(SDL_sem * _sem, Uint32 timeout) +{ + SDL_sem_atom *sem = (SDL_sem_atom *)_sem; + LONG count; + Uint32 now; + Uint32 deadline; + DWORD timeout_eff; + + if (timeout == SDL_MUTEX_MAXWAIT) { + return SDL_SemWait_atom(_sem); + } + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + /** + * WaitOnAddress is subject to spurious and stolen wakeups so we + * need to recalculate the effective timeout before every wait + */ + now = SDL_GetTicks(); + deadline = now + (DWORD) timeout; + + for (;;) { + count = sem->count; + /* If no semaphore is available we need to wait */ + while (count == 0) { + now = SDL_GetTicks(); + if (deadline > now) { + timeout_eff = deadline - now; + } else { + return SDL_MUTEX_TIMEDOUT; + } + if (pWaitOnAddress(&sem->count, &count, sizeof(count), timeout_eff) == FALSE) { + if (GetLastError() == ERROR_TIMEOUT) { + return SDL_MUTEX_TIMEDOUT; + } + return SDL_SetError("WaitOnAddress() failed"); + } + count = sem->count; + } + + /* Actually the semaphore is only consumed if this succeeds */ + /* If it doesn't we need to do everything again */ + if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) { + return 0; + } + } +} + +static Uint32 +SDL_SemValue_atom(SDL_sem * _sem) +{ + SDL_sem_atom *sem = (SDL_sem_atom *)_sem; + + if (!sem) { + SDL_InvalidParamError("sem"); + return 0; + } + + return (Uint32)sem->count; +} + +static int +SDL_SemPost_atom(SDL_sem * _sem) +{ + SDL_sem_atom *sem = (SDL_sem_atom *)_sem; + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + InterlockedIncrement(&sem->count); + pWakeByAddressSingle(&sem->count); + + return 0; +} + +static const SDL_sem_impl_t SDL_sem_impl_atom = +{ + &SDL_CreateSemaphore_atom, + &SDL_DestroySemaphore_atom, + &SDL_SemWaitTimeout_atom, + &SDL_SemTryWait_atom, + &SDL_SemWait_atom, + &SDL_SemValue_atom, + &SDL_SemPost_atom, +}; +#endif /* !SDL_WINAPI_FAMILY_PHONE */ + + +/** + * Fallback Semaphore implementation using Kernel Semaphores + */ + +typedef struct SDL_semaphore_kern { HANDLE id; LONG count; -}; - +} SDL_sem_kern; /* Create a semaphore */ -SDL_sem * -SDL_CreateSemaphore(Uint32 initial_value) +static SDL_sem * +SDL_CreateSemaphore_kern(Uint32 initial_value) { - SDL_sem *sem; + SDL_sem_kern *sem; /* Allocate sem memory */ - sem = (SDL_sem *) SDL_malloc(sizeof(*sem)); + sem = (SDL_sem_kern *) SDL_malloc(sizeof(*sem)); if (sem) { /* Create the semaphore, with max value 32K */ #if __WINRT__ @@ -59,13 +288,14 @@ SDL_CreateSemaphore(Uint32 initial_value) } else { SDL_OutOfMemory(); } - return (sem); + return (SDL_sem *)sem; } /* Free the semaphore */ -void -SDL_DestroySemaphore(SDL_sem * sem) +static void +SDL_DestroySemaphore_kern(SDL_sem * _sem) { + SDL_sem_kern *sem = (SDL_sem_kern *)_sem; if (sem) { if (sem->id) { CloseHandle(sem->id); @@ -75,14 +305,15 @@ SDL_DestroySemaphore(SDL_sem * sem) } } -int -SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) +static int +SDL_SemWaitTimeout_kern(SDL_sem * _sem, Uint32 timeout) { + SDL_sem_kern *sem = (SDL_sem_kern *)_sem; int retval; DWORD dwMilliseconds; if (!sem) { - return SDL_SetError("Passed a NULL sem"); + return SDL_InvalidParamError("sem"); } if (timeout == SDL_MUTEX_MAXWAIT) { @@ -105,34 +336,36 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) return retval; } -int -SDL_SemTryWait(SDL_sem * sem) +static int +SDL_SemTryWait_kern(SDL_sem * sem) { - return SDL_SemWaitTimeout(sem, 0); + return SDL_SemWaitTimeout_kern(sem, 0); } -int -SDL_SemWait(SDL_sem * sem) +static int +SDL_SemWait_kern(SDL_sem * sem) { - return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); + return SDL_SemWaitTimeout_kern(sem, SDL_MUTEX_MAXWAIT); } /* Returns the current count of the semaphore */ -Uint32 -SDL_SemValue(SDL_sem * sem) +static Uint32 +SDL_SemValue_kern(SDL_sem * _sem) { + SDL_sem_kern *sem = (SDL_sem_kern *)_sem; if (!sem) { - SDL_SetError("Passed a NULL sem"); + SDL_InvalidParamError("sem"); return 0; } return (Uint32)sem->count; } -int -SDL_SemPost(SDL_sem * sem) +static int +SDL_SemPost_kern(SDL_sem * _sem) { + SDL_sem_kern *sem = (SDL_sem_kern *)_sem; if (!sem) { - return SDL_SetError("Passed a NULL sem"); + return SDL_InvalidParamError("sem"); } /* Increase the counter in the first place, because * after a successful release the semaphore may @@ -147,6 +380,97 @@ SDL_SemPost(SDL_sem * sem) return 0; } +static const SDL_sem_impl_t SDL_sem_impl_kern = +{ + &SDL_CreateSemaphore_kern, + &SDL_DestroySemaphore_kern, + &SDL_SemWaitTimeout_kern, + &SDL_SemTryWait_kern, + &SDL_SemWait_kern, + &SDL_SemValue_kern, + &SDL_SemPost_kern, +}; + + +/** + * Runtime selection and redirection + */ + +SDL_sem * +SDL_CreateSemaphore(Uint32 initial_value) +{ + if (SDL_sem_impl_active.Create == NULL) { + /* Default to fallback implementation */ + const SDL_sem_impl_t * impl = &SDL_sem_impl_kern; + +#if !SDL_WINAPI_FAMILY_PHONE + if (!SDL_GetHintBoolean(SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL, SDL_FALSE)) { +#if __WINRT__ + /* Link statically on this platform */ + impl = &SDL_sem_impl_atom; +#else + /* We already statically link to features from this Api + * Set (e.g. WaitForSingleObject). Dynamically loading + * API Sets is not explicitly documented but according to + * Microsoft our specific use case is legal and correct: + * https://github.com/microsoft/STL/pull/593#issuecomment-655799859 + */ + HMODULE synch120 = GetModuleHandle(TEXT("api-ms-win-core-synch-l1-2-0.dll")); + if (synch120) { + /* Try to load required functions provided by Win 8 or newer */ + pWaitOnAddress = (pfnWaitOnAddress) GetProcAddress(synch120, "WaitOnAddress"); + pWakeByAddressSingle = (pfnWakeByAddressSingle) GetProcAddress(synch120, "WakeByAddressSingle"); + + if(pWaitOnAddress && pWakeByAddressSingle) { + impl = &SDL_sem_impl_atom; + } + } +#endif + } +#endif + + /* Copy instead of using pointer to save one level of indirection */ + SDL_memcpy(&SDL_sem_impl_active, impl, sizeof(SDL_sem_impl_active)); + } + return SDL_sem_impl_active.Create(initial_value); +} + +void +SDL_DestroySemaphore(SDL_sem * sem) +{ + SDL_sem_impl_active.Destroy(sem); +} + +int +SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) +{ + return SDL_sem_impl_active.WaitTimeout(sem, timeout); +} + +int +SDL_SemTryWait(SDL_sem * sem) +{ + return SDL_sem_impl_active.TryWait(sem); +} + +int +SDL_SemWait(SDL_sem * sem) +{ + return SDL_sem_impl_active.Wait(sem); +} + +Uint32 +SDL_SemValue(SDL_sem * sem) +{ + return SDL_sem_impl_active.Value(sem); +} + +int +SDL_SemPost(SDL_sem * sem) +{ + return SDL_sem_impl_active.Post(sem); +} + #endif /* SDL_THREAD_WINDOWS */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/windows/SDL_systhread.c b/Engine/lib/sdl/src/thread/windows/SDL_systhread.c index 7e3269b2b..8f44e473c 100644 --- a/Engine/lib/sdl/src/thread/windows/SDL_systhread.c +++ b/Engine/lib/sdl/src/thread/windows/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -163,14 +163,14 @@ SDL_SYS_SetupThread(const char *name) static HMODULE kernel32 = 0; if (!kernel32) { - kernel32 = LoadLibraryW(L"kernel32.dll"); + kernel32 = GetModuleHandle(TEXT("kernel32.dll")); if (kernel32) { pSetThreadDescription = (pfnSetThreadDescription) GetProcAddress(kernel32, "SetThreadDescription"); } } if (pSetThreadDescription != NULL) { - WCHAR *strw = WIN_UTF8ToString(name); + WCHAR *strw = WIN_UTF8ToStringW(name); if (strw) { pSetThreadDescription(GetCurrentThread(), strw); SDL_free(strw); diff --git a/Engine/lib/sdl/src/thread/windows/SDL_systhread_c.h b/Engine/lib/sdl/src/thread/windows/SDL_systhread_c.h index f84383081..debb19d7e 100644 --- a/Engine/lib/sdl/src/thread/windows/SDL_systhread_c.h +++ b/Engine/lib/sdl/src/thread/windows/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/thread/windows/SDL_systls.c b/Engine/lib/sdl/src/thread/windows/SDL_systls.c index e37a3321f..22e507a7a 100644 --- a/Engine/lib/sdl/src/thread/windows/SDL_systls.c +++ b/Engine/lib/sdl/src/thread/windows/SDL_systls.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/timer/SDL_timer.c b/Engine/lib/sdl/src/timer/SDL_timer.c index 4e8ea01c9..7b7692df0 100644 --- a/Engine/lib/sdl/src/timer/SDL_timer.c +++ b/Engine/lib/sdl/src/timer/SDL_timer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,6 +28,8 @@ /* #define DEBUG_TIMERS */ +#if !defined(__EMSCRIPTEN__) || !SDL_THREADS_DISABLED + typedef struct _SDL_Timer { int timerID; @@ -370,4 +372,124 @@ SDL_RemoveTimer(SDL_TimerID id) return canceled; } +#else + +#include + +typedef struct _SDL_TimerMap +{ + int timerID; + int timeoutID; + struct _SDL_TimerMap *next; +} SDL_TimerMap; + +typedef struct { + int nextID; + SDL_TimerMap *timermap; +} SDL_TimerData; + +static SDL_TimerData SDL_timer_data; + +static void +SDL_Emscripten_TimerHelper(SDL_TimerMap *entry, Uint32 interval, SDL_TimerCallback callback, void *param) +{ + Uint32 new_timeout; + + new_timeout = callback(interval, param); + + if (new_timeout != 0) { + entry->timeoutID = EM_ASM_INT({ + return Browser.safeSetTimeout(function() { + dynCall('viiii', $0, [$1, $2, $3, $4]); + }, $2); + }, &SDL_Emscripten_TimerHelper, entry, interval, callback, param); + } +} + +int +SDL_TimerInit(void) +{ + return 0; +} + +void +SDL_TimerQuit(void) +{ + SDL_TimerData *data = &SDL_timer_data; + SDL_TimerMap *entry; + + while (data->timermap) { + entry = data->timermap; + data->timermap = entry->next; + SDL_free(entry); + } +} + +SDL_TimerID +SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param) +{ + SDL_TimerData *data = &SDL_timer_data; + SDL_TimerMap *entry; + + entry = (SDL_TimerMap *)SDL_malloc(sizeof(*entry)); + if (!entry) { + SDL_OutOfMemory(); + return 0; + } + entry->timerID = ++data->nextID; + + entry->timeoutID = EM_ASM_INT({ + return Browser.safeSetTimeout(function() { + dynCall('viiii', $0, [$1, $2, $3, $4]); + }, $2); + }, &SDL_Emscripten_TimerHelper, entry, interval, callback, param); + + entry->next = data->timermap; + data->timermap = entry; + + return entry->timerID; +} + +SDL_bool +SDL_RemoveTimer(SDL_TimerID id) +{ + SDL_TimerData *data = &SDL_timer_data; + SDL_TimerMap *prev, *entry; + + /* Find the timer */ + prev = NULL; + for (entry = data->timermap; entry; prev = entry, entry = entry->next) { + if (entry->timerID == id) { + if (prev) { + prev->next = entry->next; + } else { + data->timermap = entry->next; + } + break; + } + } + + if (entry) { + EM_ASM_({ + window.clearTimeout($0); + }, entry->timeoutID); + SDL_free(entry); + + return SDL_TRUE; + } + return SDL_FALSE; +} + +#endif + +/* This is a legacy support function; SDL_GetTicks() returns a Uint32, + which wraps back to zero every ~49 days. The newer SDL_GetTicks64() + doesn't have this problem, so we just wrap that function and clamp to + the low 32-bits for binary compatibility. */ +Uint32 +SDL_GetTicks(void) +{ + return (Uint32) (SDL_GetTicks64() & 0xFFFFFFFF); +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/timer/SDL_timer_c.h b/Engine/lib/sdl/src/timer/SDL_timer_c.h index 4e62845a5..555913e4d 100644 --- a/Engine/lib/sdl/src/timer/SDL_timer_c.h +++ b/Engine/lib/sdl/src/timer/SDL_timer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/timer/dummy/SDL_systimer.c b/Engine/lib/sdl/src/timer/dummy/SDL_systimer.c index ffbdf303a..8e34959f0 100644 --- a/Engine/lib/sdl/src/timer/dummy/SDL_systimer.c +++ b/Engine/lib/sdl/src/timer/dummy/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -41,8 +41,8 @@ SDL_TicksQuit(void) ticks_started = SDL_FALSE; } -Uint32 -SDL_GetTicks(void) +Uint64 +SDL_GetTicks64(void) { if (!ticks_started) { SDL_TicksInit(); diff --git a/Engine/lib/sdl/src/timer/haiku/SDL_systimer.c b/Engine/lib/sdl/src/timer/haiku/SDL_systimer.c index b512fb1d7..fb358b9d2 100644 --- a/Engine/lib/sdl/src/timer/haiku/SDL_systimer.c +++ b/Engine/lib/sdl/src/timer/haiku/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -47,14 +47,14 @@ SDL_TicksQuit(void) ticks_started = SDL_FALSE; } -Uint32 -SDL_GetTicks(void) +Uint64 +SDL_GetTicks64(void) { if (!ticks_started) { SDL_TicksInit(); } - return ((system_time() - start) / 1000); + return (Uint64) ((system_time() - start) / 1000); } Uint64 diff --git a/Engine/lib/sdl/src/timer/os2/SDL_systimer.c b/Engine/lib/sdl/src/timer/os2/SDL_systimer.c index 4b09c9579..c5bcf64b7 100644 --- a/Engine/lib/sdl/src/timer/os2/SDL_systimer.c +++ b/Engine/lib/sdl/src/timer/os2/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -40,25 +40,26 @@ typedef unsigned long long ULLONG; static ULONG ulTmrFreq = 0; -static ULLONG ullTmrStart; +static ULLONG ullTmrStart = 0; void SDL_TicksInit(void) { - ULONG ulRC; - - ulRC = DosTmrQueryFreq(&ulTmrFreq); + ULONG ulTmrStart; /* for 32-bit fallback. */ + ULONG ulRC = DosTmrQueryFreq(&ulTmrFreq); if (ulRC != NO_ERROR) { debug_os2("DosTmrQueryFreq() failed, rc = %u", ulRC); } else { ulRC = DosTmrQueryTime((PQWORD)&ullTmrStart); - if (ulRC == NO_ERROR) + if (ulRC == NO_ERROR) { return; + } debug_os2("DosTmrQueryTime() failed, rc = %u", ulRC); } ulTmrFreq = 0; /* Error - use DosQuerySysInfo() for timer. */ - DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, (PULONG)&ullTmrStart, sizeof(ULONG)); + DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulTmrStart, sizeof (ULONG)); + ullTmrStart = (ULLONG) ulTmrStart; } void @@ -66,24 +67,27 @@ SDL_TicksQuit(void) { } -Uint32 -SDL_GetTicks(void) +Uint64 +SDL_GetTicks64(void) { - ULONG ulResult; - ULLONG ullTmrNow; + Uint64 ui64Result; + ULLONG ullTmrNow; - if (ulTmrFreq == 0) /* Was not initialized. */ + if (ulTmrFreq == 0) { /* Was not initialized. */ SDL_TicksInit(); + } if (ulTmrFreq != 0) { DosTmrQueryTime((PQWORD)&ullTmrNow); - ulResult = (ullTmrNow - ullTmrStart) * 1000 / ulTmrFreq; + ui64Result = (ullTmrNow - ullTmrStart) * 1000 / ulTmrFreq; } else { - DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, (PULONG)&ullTmrNow, sizeof(ULONG)); - ulResult = (ULONG)ullTmrNow - (ULONG)ullTmrStart; + /* note that this counter rolls over to 0 every ~49 days. Fix your system so DosTmrQueryTime works if you need to avoid this. */ + ULONG ulTmrNow; + DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulTmrNow, sizeof (ULONG)); + ui64Result = (((Uint64) ulTmrNow) - ullTmrStart); } - return ulResult; + return ui64Result; } Uint64 @@ -91,9 +95,9 @@ SDL_GetPerformanceCounter(void) { QWORD qwTmrNow; - if (ulTmrFreq == 0 || (DosTmrQueryTime(&qwTmrNow) != NO_ERROR)) - return SDL_GetTicks(); - + if (ulTmrFreq == 0 || (DosTmrQueryTime(&qwTmrNow) != NO_ERROR)) { + return SDL_GetTicks64(); + } return *((Uint64 *)&qwTmrNow); } diff --git a/Engine/lib/sdl/src/timer/psp/SDL_systimer.c b/Engine/lib/sdl/src/timer/psp/SDL_systimer.c index ad4ab29dd..df6225fa3 100644 --- a/Engine/lib/sdl/src/timer/psp/SDL_systimer.c +++ b/Engine/lib/sdl/src/timer/psp/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#ifdef SDL_TIMERS_PSP +#ifdef SDL_TIMER_PSP #include "SDL_thread.h" #include "SDL_timer.h" @@ -51,24 +51,23 @@ SDL_TicksQuit(void) ticks_started = SDL_FALSE; } -Uint32 SDL_GetTicks(void) +Uint64 +SDL_GetTicks64(void) { + struct timeval now; + if (!ticks_started) { SDL_TicksInit(); } - struct timeval now; - Uint32 ticks; - gettimeofday(&now, NULL); - ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; - return(ticks); + return (Uint64)(((Sint64)(now.tv_sec - start.tv_sec) * 1000) + ((now.tv_usec - start.tv_usec) / 1000)); } Uint64 SDL_GetPerformanceCounter(void) { - return SDL_GetTicks(); + return SDL_GetTicks64(); } Uint64 @@ -85,7 +84,7 @@ void SDL_Delay(Uint32 ms) sceKernelDelayThreadCB(ms * 1000); } -#endif /* SDL_TIMERS_PSP */ +#endif /* SDL_TIMER_PSP */ /* vim: ts=4 sw=4 */ diff --git a/Engine/lib/sdl/src/timer/unix/SDL_systimer.c b/Engine/lib/sdl/src/timer/unix/SDL_systimer.c index f6c986848..2cf26764c 100644 --- a/Engine/lib/sdl/src/timer/unix/SDL_systimer.c +++ b/Engine/lib/sdl/src/timer/unix/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -104,10 +104,9 @@ SDL_TicksQuit(void) ticks_started = SDL_FALSE; } -Uint32 -SDL_GetTicks(void) +Uint64 +SDL_GetTicks64(void) { - Uint32 ticks; if (!ticks_started) { SDL_TicksInit(); } @@ -116,21 +115,19 @@ SDL_GetTicks(void) #if HAVE_CLOCK_GETTIME struct timespec now; clock_gettime(SDL_MONOTONIC_CLOCK, &now); - ticks = (Uint32)((now.tv_sec - start_ts.tv_sec) * 1000 + (now.tv_nsec - start_ts.tv_nsec) / 1000000); + return (Uint64)(((Sint64)(now.tv_sec - start_ts.tv_sec) * 1000) + ((now.tv_nsec - start_ts.tv_nsec) / 1000000)); #elif defined(__APPLE__) - uint64_t now = mach_absolute_time(); - ticks = (Uint32)((((now - start_mach) * mach_base_info.numer) / mach_base_info.denom) / 1000000); + const uint64_t now = mach_absolute_time(); + return ((((now - start_mach) * mach_base_info.numer) / mach_base_info.denom) / 1000000); #else SDL_assert(SDL_FALSE); - ticks = 0; + return 0; #endif } else { struct timeval now; - gettimeofday(&now, NULL); - ticks = (Uint32)((now.tv_sec - start_tv.tv_sec) * 1000 + (now.tv_usec - start_tv.tv_usec) / 1000); + return (Uint64)(((Sint64)(now.tv_sec - start_tv.tv_sec) * 1000) + ((now.tv_usec - start_tv.tv_usec) / 1000)); } - return (ticks); } Uint64 @@ -190,6 +187,15 @@ SDL_GetPerformanceFrequency(void) void SDL_Delay(Uint32 ms) { + int was_error; + +#if HAVE_NANOSLEEP + struct timespec elapsed, tv; +#else + struct timeval tv; + Uint64 then, now, elapsed; +#endif + #ifdef __EMSCRIPTEN__ if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) { /* pseudo-synchronous pause, used directly or through e.g. SDL_WaitEvent */ @@ -197,21 +203,13 @@ SDL_Delay(Uint32 ms) return; } #endif - int was_error; - -#if HAVE_NANOSLEEP - struct timespec elapsed, tv; -#else - struct timeval tv; - Uint32 then, now, elapsed; -#endif /* Set the timeout interval */ #if HAVE_NANOSLEEP elapsed.tv_sec = ms / 1000; elapsed.tv_nsec = (ms % 1000) * 1000000; #else - then = SDL_GetTicks(); + then = SDL_GetTicks64(); #endif do { errno = 0; @@ -222,13 +220,13 @@ SDL_Delay(Uint32 ms) was_error = nanosleep(&tv, &elapsed); #else /* Calculate the time interval left (in case of interrupt) */ - now = SDL_GetTicks(); + now = SDL_GetTicks64(); elapsed = (now - then); then = now; - if (elapsed >= ms) { + if (elapsed >= ((Uint64)ms)) { break; } - ms -= elapsed; + ms -= (Uint32)elapsed; tv.tv_sec = ms / 1000; tv.tv_usec = (ms % 1000) * 1000; diff --git a/Engine/lib/sdl/src/timer/vita/SDL_systimer.c b/Engine/lib/sdl/src/timer/vita/SDL_systimer.c new file mode 100644 index 000000000..db382378e --- /dev/null +++ b/Engine/lib/sdl/src/timer/vita/SDL_systimer.c @@ -0,0 +1,89 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_TIMER_VITA + +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_error.h" +#include "../SDL_timer_c.h" +#include +#include +#include +#include + +static uint64_t start; +static SDL_bool ticks_started = SDL_FALSE; + +void +SDL_TicksInit(void) +{ + if (ticks_started) { + return; + } + ticks_started = SDL_TRUE; + + start = sceKernelGetProcessTimeWide(); +} + +void +SDL_TicksQuit(void) +{ + ticks_started = SDL_FALSE; +} + +Uint64 +SDL_GetTicks64(void) +{ + uint64_t now; + + if (!ticks_started) { + SDL_TicksInit(); + } + + now = sceKernelGetProcessTimeWide(); + return (Uint64) ((now - start) / 1000); +} + +Uint64 +SDL_GetPerformanceCounter(void) +{ + return sceKernelGetProcessTimeWide(); +} + +Uint64 +SDL_GetPerformanceFrequency(void) +{ + return 1000000; +} + +void SDL_Delay(Uint32 ms) +{ + const Uint32 max_delay = 0xffffffffUL / 1000; + if(ms > max_delay) + ms = max_delay; + sceKernelDelayThreadCB(ms * 1000); +} + +#endif /* SDL_TIMER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/timer/windows/SDL_systimer.c b/Engine/lib/sdl/src/timer/windows/SDL_systimer.c index 6c8d23f94..7972db131 100644 --- a/Engine/lib/sdl/src/timer/windows/SDL_systimer.c +++ b/Engine/lib/sdl/src/timer/windows/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,12 +33,10 @@ static DWORD start = 0; static BOOL ticks_started = FALSE; -/* Store if a high-resolution performance counter exists on the system */ -static BOOL hires_timer_available; /* The first high-resolution ticks value of the application */ -static LARGE_INTEGER hires_start_ticks; +static LARGE_INTEGER start_ticks; /* The number of ticks per second of the high-resolution performance counter */ -static LARGE_INTEGER hires_ticks_per_second; +static LARGE_INTEGER ticks_per_second; static void SDL_SetSystemTimerResolution(const UINT uPeriod) @@ -79,6 +77,8 @@ SDL_TimerResolutionChanged(void *userdata, const char *name, const char *oldValu void SDL_TicksInit(void) { + BOOL rc; + if (ticks_started) { return; } @@ -90,18 +90,12 @@ SDL_TicksInit(void) SDL_TimerResolutionChanged, NULL); /* Set first ticks value */ - /* QueryPerformanceCounter has had problems in the past, but lots of games - use it, so we'll rely on it here. + /* QueryPerformanceCounter allegedly is always available and reliable as of WinXP, + so we'll rely on it here. */ - if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) { - hires_timer_available = TRUE; - QueryPerformanceCounter(&hires_start_ticks); - } else { - hires_timer_available = FALSE; -#ifndef __WINRT__ - start = timeGetTime(); -#endif /* __WINRT__ */ - } + rc = QueryPerformanceFrequency(&ticks_per_second); + SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */ + QueryPerformanceCounter(&start_ticks); } void @@ -116,53 +110,37 @@ SDL_TicksQuit(void) ticks_started = SDL_FALSE; } -Uint32 -SDL_GetTicks(void) +Uint64 +SDL_GetTicks64(void) { - DWORD now = 0; - LARGE_INTEGER hires_now; + LARGE_INTEGER now; + BOOL rc; if (!ticks_started) { SDL_TicksInit(); } - if (hires_timer_available) { - QueryPerformanceCounter(&hires_now); - - hires_now.QuadPart -= hires_start_ticks.QuadPart; - hires_now.QuadPart *= 1000; - hires_now.QuadPart /= hires_ticks_per_second.QuadPart; - - return (DWORD) hires_now.QuadPart; - } else { -#ifndef __WINRT__ - now = timeGetTime(); -#endif /* __WINRT__ */ - } - - return (now - start); + rc = QueryPerformanceCounter(&now); + SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */ + return (Uint64) (((now.QuadPart - start_ticks.QuadPart) * 1000) / ticks_per_second.QuadPart); } Uint64 SDL_GetPerformanceCounter(void) { LARGE_INTEGER counter; - - if (!QueryPerformanceCounter(&counter)) { - return SDL_GetTicks(); - } - return counter.QuadPart; + const BOOL rc = QueryPerformanceCounter(&counter); + SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */ + return (Uint64) counter.QuadPart; } Uint64 SDL_GetPerformanceFrequency(void) { LARGE_INTEGER frequency; - - if (!QueryPerformanceFrequency(&frequency)) { - return 1000; - } - return frequency.QuadPart; + const BOOL rc = QueryPerformanceFrequency(&frequency); + SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */ + return (Uint64) frequency.QuadPart; } void diff --git a/Engine/lib/sdl/src/video/SDL_RLEaccel.c b/Engine/lib/sdl/src/video/SDL_RLEaccel.c index d04b94ed3..983c9d914 100644 --- a/Engine/lib/sdl/src/video/SDL_RLEaccel.c +++ b/Engine/lib/sdl/src/video/SDL_RLEaccel.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -1227,7 +1227,7 @@ RLEAlphaSurface(SDL_Surface * surface) surface->flags &= ~SDL_SIMD_ALIGNED; } - /* realloc the buffer to release unused memory */ + /* reallocate the buffer to release unused memory */ { Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf); if (!p) @@ -1391,9 +1391,9 @@ RLEColorkeySurface(SDL_Surface * surface) surface->flags &= ~SDL_SIMD_ALIGNED; } - /* realloc the buffer to release unused memory */ + /* reallocate the buffer to release unused memory */ { - /* If realloc returns NULL, the original block is left intact */ + /* If SDL_realloc returns NULL, the original block is left intact */ Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf); if (!p) p = rlebuf; @@ -1423,9 +1423,13 @@ SDL_RLESurface(SDL_Surface * surface) return -1; } - /* If we don't have colorkey or blending, nothing to do... */ flags = surface->map->info.flags; - if (!(flags & (SDL_COPY_COLORKEY | SDL_COPY_BLEND))) { + if (flags & SDL_COPY_COLORKEY) { + /* ok */ + } else if ((flags & SDL_COPY_BLEND) && surface->format->Amask) { + /* ok */ + } else { + /* If we don't have colorkey or blending, nothing to do... */ return -1; } diff --git a/Engine/lib/sdl/src/video/SDL_RLEaccel_c.h b/Engine/lib/sdl/src/video/SDL_RLEaccel_c.h index 3dcc6c023..6f0d95f91 100644 --- a/Engine/lib/sdl/src/video/SDL_RLEaccel_c.h +++ b/Engine/lib/sdl/src/video/SDL_RLEaccel_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/SDL_blit.c b/Engine/lib/sdl/src/video/SDL_blit.c index a5df0b995..fa6492f51 100644 --- a/Engine/lib/sdl/src/video/SDL_blit.c +++ b/Engine/lib/sdl/src/video/SDL_blit.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -231,9 +231,7 @@ SDL_CalculateBlit(SDL_Surface * surface) if (map->identity && !(map->info.flags & ~SDL_COPY_RLE_DESIRED)) { blit = SDL_BlitCopy; } else if (surface->format->Rloss > 8 || dst->format->Rloss > 8) { - /* Greater than 8 bits per channel not supported yet */ - SDL_InvalidateMap(map); - return SDL_SetError("Blit combination not supported"); + blit = SDL_Blit_Slow; } #if SDL_HAVE_BLIT_0 else if (surface->format->BitsPerPixel < 8 && diff --git a/Engine/lib/sdl/src/video/SDL_blit.h b/Engine/lib/sdl/src/video/SDL_blit.h index 81a9d8bb7..e00ba68e2 100644 --- a/Engine/lib/sdl/src/video/SDL_blit.h +++ b/Engine/lib/sdl/src/video/SDL_blit.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,6 +27,12 @@ #include "SDL_endian.h" #include "SDL_surface.h" +/* pixman ARM blitters are 32 bit only : */ +#if defined(__aarch64__)||defined(_M_ARM64) +#undef SDL_ARM_SIMD_BLITTERS +#undef SDL_ARM_NEON_BLITTERS +#endif + /* Table to do pixel byte expansion */ extern Uint8* SDL_expand_byte[9]; @@ -263,18 +269,18 @@ do { \ { \ switch (bpp) { \ case 1: { \ - Uint8 _Pixel; \ + Uint8 _pixel; \ \ - PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \ - *((Uint8 *)(buf)) = _Pixel; \ + PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \ + *((Uint8 *)(buf)) = _pixel; \ } \ break; \ \ case 2: { \ - Uint16 _Pixel; \ + Uint16 _pixel; \ \ - PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \ - *((Uint16 *)(buf)) = _Pixel; \ + PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \ + *((Uint16 *)(buf)) = _pixel; \ } \ break; \ \ @@ -292,10 +298,10 @@ do { \ break; \ \ case 4: { \ - Uint32 _Pixel; \ + Uint32 _pixel; \ \ - PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \ - *((Uint32 *)(buf)) = _Pixel; \ + PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \ + *((Uint32 *)(buf)) = _pixel; \ } \ break; \ } \ @@ -473,14 +479,14 @@ do { \ #define DUFFS_LOOP8(pixel_copy_increment, width) \ { int n = (width+7)/8; \ switch (width & 7) { \ - case 0: do { pixel_copy_increment; /* fallthrough */ \ - case 7: pixel_copy_increment; /* fallthrough */ \ - case 6: pixel_copy_increment; /* fallthrough */ \ - case 5: pixel_copy_increment; /* fallthrough */ \ - case 4: pixel_copy_increment; /* fallthrough */ \ - case 3: pixel_copy_increment; /* fallthrough */ \ - case 2: pixel_copy_increment; /* fallthrough */ \ - case 1: pixel_copy_increment; /* fallthrough */ \ + case 0: do { pixel_copy_increment; SDL_FALLTHROUGH; \ + case 7: pixel_copy_increment; SDL_FALLTHROUGH; \ + case 6: pixel_copy_increment; SDL_FALLTHROUGH; \ + case 5: pixel_copy_increment; SDL_FALLTHROUGH; \ + case 4: pixel_copy_increment; SDL_FALLTHROUGH; \ + case 3: pixel_copy_increment; SDL_FALLTHROUGH; \ + case 2: pixel_copy_increment; SDL_FALLTHROUGH; \ + case 1: pixel_copy_increment; \ } while ( --n > 0 ); \ } \ } @@ -489,10 +495,10 @@ do { \ #define DUFFS_LOOP4(pixel_copy_increment, width) \ { int n = (width+3)/4; \ switch (width & 3) { \ - case 0: do { pixel_copy_increment; /* fallthrough */ \ - case 3: pixel_copy_increment; /* fallthrough */ \ - case 2: pixel_copy_increment; /* fallthrough */ \ - case 1: pixel_copy_increment; /* fallthrough */ \ + case 0: do { pixel_copy_increment; SDL_FALLTHROUGH; \ + case 3: pixel_copy_increment; SDL_FALLTHROUGH; \ + case 2: pixel_copy_increment; SDL_FALLTHROUGH; \ + case 1: pixel_copy_increment; \ } while (--n > 0); \ } \ } diff --git a/Engine/lib/sdl/src/video/SDL_blit_0.c b/Engine/lib/sdl/src/video/SDL_blit_0.c index 1e4ebbe11..54882f8b1 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_0.c +++ b/Engine/lib/sdl/src/video/SDL_blit_0.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -452,11 +452,94 @@ static const SDL_BlitFunc colorkey_blit[] = { (SDL_BlitFunc) NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key }; + +static void +Blit4bto4(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + Uint32 *dst = (Uint32 *) info->dst; + int srcskip = info->src_skip; + int dstskip = info->dst_skip; + Uint32 *map = (Uint32 *) info->table; + int c; + + /* Set up some basic variables */ + srcskip += width - (width + 1) / 2; + + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if ((c & 0x1) == 0) { + byte = *src++; + } + bit = (byte & 0xF0) >> 4; + if (1) { + *dst = map[bit]; + } + byte <<= 4; + dst++; + } + src += srcskip; + dst = (Uint32 *) ((Uint8 *) dst + dstskip); + } +} + +static void +Blit4bto4Key(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + Uint32 *dst = (Uint32 *) info->dst; + int srcskip = info->src_skip; + int dstskip = info->dst_skip; + Uint32 ckey = info->colorkey; + Uint32 *map = (Uint32 *) info->table; + int c; + + /* Set up some basic variables */ + srcskip += width - (width + 1) / 2; + + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if ((c & 0x1) == 0) { + byte = *src++; + } + bit = (byte & 0xF0) >> 4; + if (bit != ckey) { + *dst = map[bit]; + } + byte <<= 4; + dst++; + } + src += srcskip; + dst = (Uint32 *) ((Uint8 *) dst + dstskip); + } +} + SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface * surface) { int which; + /* 4bits to 32bits */ + if (surface->format->BitsPerPixel == 4) { + if (surface->map->dst->format->BytesPerPixel == 4) { + switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) { + case 0: + return Blit4bto4; + + case SDL_COPY_COLORKEY: + return Blit4bto4Key; + } + } + /* We don't fully support 4-bit packed pixel modes */ + return NULL; + } + if (surface->format->BitsPerPixel != 1) { /* We don't support sub 8-bit packed pixel modes */ return (SDL_BlitFunc) NULL; diff --git a/Engine/lib/sdl/src/video/SDL_blit_1.c b/Engine/lib/sdl/src/video/SDL_blit_1.c index d75caff4b..d5030cfb1 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_1.c +++ b/Engine/lib/sdl/src/video/SDL_blit_1.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/SDL_blit_A.c b/Engine/lib/sdl/src/video/SDL_blit_A.c index c9c37f03a..4c0726eb0 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_A.c +++ b/Engine/lib/sdl/src/video/SDL_blit_A.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -397,14 +397,14 @@ void BlitARGBto565PixelAlphaARMSIMDAsm(int32_t w, int32_t h, uint16_t *dst, int3 static void BlitARGBto565PixelAlphaARMSIMD(SDL_BlitInfo * info) { - int32_t width = info->dst_w; - int32_t height = info->dst_h; - uint16_t *dstp = (uint16_t *)info->dst; - int32_t dststride = width + (info->dst_skip >> 1); - uint32_t *srcp = (uint32_t *)info->src; - int32_t srcstride = width + (info->src_skip >> 2); + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint16_t *dstp = (uint16_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 1); + uint32_t *srcp = (uint32_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 2); - BlitARGBto565PixelAlphaARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); + BlitARGBto565PixelAlphaARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); } void BlitRGBtoRGBPixelAlphaARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride); @@ -444,14 +444,14 @@ void BlitRGBtoRGBPixelAlphaARMNEONAsm(int32_t w, int32_t h, uint32_t *dst, int32 static void BlitRGBtoRGBPixelAlphaARMNEON(SDL_BlitInfo * info) { - int32_t width = info->dst_w; - int32_t height = info->dst_h; - uint32_t *dstp = (uint32_t *)info->dst; - int32_t dststride = width + (info->dst_skip >> 2); - uint32_t *srcp = (uint32_t *)info->src; - int32_t srcstride = width + (info->src_skip >> 2); + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint32_t *dstp = (uint32_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 2); + uint32_t *srcp = (uint32_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 2); - BlitRGBtoRGBPixelAlphaARMNEONAsm(width, height, dstp, dststride, srcp, srcstride); + BlitRGBtoRGBPixelAlphaARMNEONAsm(width, height, dstp, dststride, srcp, srcstride); } #endif @@ -575,6 +575,61 @@ BlitRGBtoRGBPixelAlpha(SDL_BlitInfo * info) } } +/* fast ARGB888->(A)BGR888 blending with pixel alpha */ +static void +BlitRGBtoBGRPixelAlpha(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *) info->src; + int srcskip = info->src_skip >> 2; + Uint32 *dstp = (Uint32 *) info->dst; + int dstskip = info->dst_skip >> 2; + + while (height--) { + /* *INDENT-OFF* */ + DUFFS_LOOP4({ + Uint32 dalpha; + Uint32 d; + Uint32 s1; + Uint32 d1; + Uint32 s = *srcp; + Uint32 alpha = s >> 24; + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if (alpha) { + /* + * take out the middle component (green), and process + * the other two in parallel. One multiply less. + */ + s1 = s & 0xff00ff; + s1 = (s1 >> 16) | (s1 << 16); + s &= 0xff00; + + if (alpha == SDL_ALPHA_OPAQUE) { + *dstp = 0xff000000 | s | s1; + } else { + d = *dstp; + dalpha = d >> 24; + d1 = d & 0xff00ff; + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; + d &= 0xff00; + d = (d + ((s - d) * alpha >> 8)) & 0xff00; + dalpha = alpha + (dalpha * (alpha ^ 0xFF) >> 8); + *dstp = d1 | d | (dalpha << 24); + } + } + ++srcp; + ++dstp; + }, width); + /* *INDENT-ON* */ + srcp += srcskip; + dstp += dstskip; + } +} + #ifdef __3dNOW__ /* fast (as in MMX with prefetch) ARGB888->(A)RGB888 blending with pixel alpha */ static void @@ -1407,6 +1462,12 @@ SDL_CalculateBlitA(SDL_Surface * surface) #endif return BlitRGBtoRGBPixelAlpha; } + } else if (sf->Rmask == df->Bmask + && sf->Gmask == df->Gmask + && sf->Bmask == df->Rmask && sf->BytesPerPixel == 4) { + if (sf->Amask == 0xff000000) { + return BlitRGBtoBGRPixelAlpha; + } } return BlitNtoNPixelAlpha; diff --git a/Engine/lib/sdl/src/video/SDL_blit_N.c b/Engine/lib/sdl/src/video/SDL_blit_N.c index 5199abe1d..e3b6c96a3 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_N.c +++ b/Engine/lib/sdl/src/video/SDL_blit_N.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -40,11 +40,11 @@ /* Functions to blit from N-bit surfaces to other surfaces */ enum blit_features { - BLIT_FEATURE_NONE = 0, - BLIT_FEATURE_HAS_MMX = 1, - BLIT_FEATURE_HAS_ALTIVEC = 2, - BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH = 4, - BLIT_FEATURE_HAS_ARM_SIMD = 8 + BLIT_FEATURE_NONE = 0, + BLIT_FEATURE_HAS_MMX = 1, + BLIT_FEATURE_HAS_ALTIVEC = 2, + BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH = 4, + BLIT_FEATURE_HAS_ARM_SIMD = 8 }; #if SDL_ALTIVEC_BLITTERS @@ -128,7 +128,7 @@ calc_swizzle32(const SDL_PixelFormat * srcfmt, const SDL_PixelFormat * dstfmt) * leave alpha with a zero mask, but we should still swizzle the bits. */ /* ARGB */ - const static const struct SDL_PixelFormat default_pixel_format = { + static const struct SDL_PixelFormat default_pixel_format = { 0, NULL, 0, 0, {0, 0}, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, @@ -943,14 +943,14 @@ void Blit_BGR888_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t d static void Blit_BGR888_RGB888ARMSIMD(SDL_BlitInfo * info) { - int32_t width = info->dst_w; - int32_t height = info->dst_h; - uint32_t *dstp = (uint32_t *)info->dst; - int32_t dststride = width + (info->dst_skip >> 2); - uint32_t *srcp = (uint32_t *)info->src; - int32_t srcstride = width + (info->src_skip >> 2); + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint32_t *dstp = (uint32_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 2); + uint32_t *srcp = (uint32_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 2); - Blit_BGR888_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); + Blit_BGR888_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); } void Blit_RGB444_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint16_t *src, int32_t src_stride); @@ -958,14 +958,14 @@ void Blit_RGB444_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t d static void Blit_RGB444_RGB888ARMSIMD(SDL_BlitInfo * info) { - int32_t width = info->dst_w; - int32_t height = info->dst_h; - uint32_t *dstp = (uint32_t *)info->dst; - int32_t dststride = width + (info->dst_skip >> 2); - uint16_t *srcp = (uint16_t *)info->src; - int32_t srcstride = width + (info->src_skip >> 1); + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint32_t *dstp = (uint32_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 2); + uint16_t *srcp = (uint16_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 1); - Blit_RGB444_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); + Blit_RGB444_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); } #endif @@ -2073,6 +2073,35 @@ Blit_RGB565_BGRA8888(SDL_BlitInfo * info) #endif /* SDL_HAVE_BLIT_N_RGB565 */ +/* RGB555->ARGB1555, and BGR555->ABGR1555, SET_ALPHA */ +static void +Blit_RGB555_ARGB1555(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint16 *src = (Uint16 *) info->src; + int srcskip = info->src_skip; + Uint16 *dst = (Uint16 *) info->dst; + int dstskip = info->dst_skip; + SDL_PixelFormat *dstfmt = info->dst_fmt; + + Uint16 mask = ((Uint32)info->a >> dstfmt->Aloss) << dstfmt->Ashift; + + while (height--) { + /* *INDENT-OFF* */ + DUFFS_LOOP( + { + *dst = *src | mask; + ++dst; + ++src; + }, + width); + /* *INDENT-ON* */ + src = (Uint16 *) ((Uint8 *) src + srcskip); + dst = (Uint16 *) ((Uint8 *) dst + dstskip); + } +} + static void BlitNto1(SDL_BlitInfo * info) { @@ -3259,6 +3288,10 @@ static const struct blit_table normal_blit_2[] = { {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, Blit_RGB565_BGRA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, #endif + {0x00007C00, 0x000003E0, 0x0000001F, 2, 0x00007C00, 0x000003E0, 0x0000001F, + 0, Blit_RGB555_ARGB1555, SET_ALPHA}, + {0x0000001F, 0x000003E0, 0x00007C00, 2, 0x0000001F, 0x000003E0, 0x00007C00, + 0, Blit_RGB555_ARGB1555, SET_ALPHA}, /* Default for 16-bit RGB source, used if no other blitter matches */ {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0} diff --git a/Engine/lib/sdl/src/video/SDL_blit_auto.c b/Engine/lib/sdl/src/video/SDL_blit_auto.c index 7aff395c9..f64511fcc 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_auto.c +++ b/Engine/lib/sdl/src/video/SDL_blit_auto.c @@ -1,7 +1,7 @@ /* DO NOT EDIT! This file is generated by sdlgenblit.pl */ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,32 +32,23 @@ static void SDL_Blit_RGB888_RGB888_Scale(SDL_BlitInfo *info) { int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); *dst = *src; posx += incx; ++dst; @@ -124,32 +115,23 @@ static void SDL_Blit_RGB888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -226,32 +208,23 @@ static void SDL_Blit_RGB888_RGB888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -349,32 +322,23 @@ static void SDL_Blit_RGB888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -429,32 +393,23 @@ static void SDL_Blit_RGB888_BGR888_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; pixel = (B << 16) | (G << 8) | R; @@ -524,32 +479,23 @@ static void SDL_Blit_RGB888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -626,32 +572,23 @@ static void SDL_Blit_RGB888_BGR888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -749,32 +686,23 @@ static void SDL_Blit_RGB888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -828,37 +756,26 @@ static void SDL_Blit_RGB888_ARGB8888_Scale(SDL_BlitInfo *info) { Uint32 pixel; const Uint32 A = 0xFF; - Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; - pixel = (A << 24) | (R << 16) | (G << 8) | B; + pixel |= (A << 24); *dst = pixel; posx += incx; ++dst; @@ -927,32 +844,23 @@ static void SDL_Blit_RGB888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -1035,32 +943,23 @@ static void SDL_Blit_RGB888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 A = (flags & SDL_COPY_MODULATE_ALPHA) ? modulateA : 0xFF; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -1160,32 +1059,23 @@ static void SDL_Blit_RGB888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -1242,32 +1132,23 @@ static void SDL_Blit_BGR888_RGB888_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; pixel = (R << 16) | (G << 8) | B; @@ -1337,32 +1218,23 @@ static void SDL_Blit_BGR888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -1439,32 +1311,23 @@ static void SDL_Blit_BGR888_RGB888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -1562,32 +1425,23 @@ static void SDL_Blit_BGR888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -1640,32 +1494,23 @@ static void SDL_Blit_BGR888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_BGR888_BGR888_Scale(SDL_BlitInfo *info) { int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); *dst = *src; posx += incx; ++dst; @@ -1732,32 +1577,23 @@ static void SDL_Blit_BGR888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -1834,32 +1670,23 @@ static void SDL_Blit_BGR888_BGR888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -1957,32 +1784,23 @@ static void SDL_Blit_BGR888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -2038,32 +1856,23 @@ static void SDL_Blit_BGR888_ARGB8888_Scale(SDL_BlitInfo *info) const Uint32 A = 0xFF; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; pixel = (A << 24) | (R << 16) | (G << 8) | B; @@ -2135,32 +1944,23 @@ static void SDL_Blit_BGR888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -2243,32 +2043,23 @@ static void SDL_Blit_BGR888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 A = (flags & SDL_COPY_MODULATE_ALPHA) ? modulateA : 0xFF; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -2368,32 +2159,23 @@ static void SDL_Blit_BGR888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -2448,37 +2230,26 @@ static void SDL_Blit_BGR888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_ARGB8888_RGB888_Scale(SDL_BlitInfo *info) { Uint32 pixel; - Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; - pixel = (R << 16) | (G << 8) | B; + pixel &= 0xFFFFFF; *dst = pixel; posx += incx; ++dst; @@ -2553,32 +2324,23 @@ static void SDL_Blit_ARGB8888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -2663,32 +2425,23 @@ static void SDL_Blit_ARGB8888_RGB888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -2787,32 +2540,23 @@ static void SDL_Blit_ARGB8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -2870,32 +2614,23 @@ static void SDL_Blit_ARGB8888_BGR888_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; pixel = (B << 16) | (G << 8) | R; @@ -2973,32 +2708,23 @@ static void SDL_Blit_ARGB8888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -3083,32 +2809,23 @@ static void SDL_Blit_ARGB8888_BGR888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -3207,32 +2924,23 @@ static void SDL_Blit_ARGB8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -3288,32 +2996,23 @@ static void SDL_Blit_ARGB8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_ARGB8888_ARGB8888_Scale(SDL_BlitInfo *info) { int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); *dst = *src; posx += incx; ++dst; @@ -3390,32 +3089,23 @@ static void SDL_Blit_ARGB8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -3507,32 +3197,23 @@ static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B, A; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; A = (Uint8)(pixel >> 24); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -3636,32 +3317,23 @@ static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -3719,37 +3391,26 @@ static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_RGBA8888_RGB888_Scale(SDL_BlitInfo *info) { Uint32 pixel; - Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); - pixel = (R << 16) | (G << 8) | B; + pixel >>= 8; *dst = pixel; posx += incx; ++dst; @@ -3824,32 +3485,23 @@ static void SDL_Blit_RGBA8888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -3934,32 +3586,23 @@ static void SDL_Blit_RGBA8888_RGB888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -4058,32 +3701,23 @@ static void SDL_Blit_RGBA8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -4141,32 +3775,23 @@ static void SDL_Blit_RGBA8888_BGR888_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); pixel = (B << 16) | (G << 8) | R; @@ -4244,32 +3869,23 @@ static void SDL_Blit_RGBA8888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -4354,32 +3970,23 @@ static void SDL_Blit_RGBA8888_BGR888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -4478,32 +4085,23 @@ static void SDL_Blit_RGBA8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -4559,37 +4157,26 @@ static void SDL_Blit_RGBA8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_RGBA8888_ARGB8888_Scale(SDL_BlitInfo *info) { Uint32 pixel; - Uint32 R, G, B, A; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); A = (Uint8)pixel; - pixel = (A << 24) | (R << 16) | (G << 8) | B; + pixel = (pixel >> 8) | (pixel << 24); *dst = pixel; posx += incx; ++dst; @@ -4666,32 +4253,23 @@ static void SDL_Blit_RGBA8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -4783,32 +4361,23 @@ static void SDL_Blit_RGBA8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B, A; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); A = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -4912,32 +4481,23 @@ static void SDL_Blit_RGBA8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -4997,32 +4557,23 @@ static void SDL_Blit_ABGR8888_RGB888_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; pixel = (R << 16) | (G << 8) | B; @@ -5100,32 +4651,23 @@ static void SDL_Blit_ABGR8888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -5210,32 +4752,23 @@ static void SDL_Blit_ABGR8888_RGB888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -5334,32 +4867,23 @@ static void SDL_Blit_ABGR8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -5415,37 +4939,26 @@ static void SDL_Blit_ABGR8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_ABGR8888_BGR888_Scale(SDL_BlitInfo *info) { Uint32 pixel; - Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; - pixel = (B << 16) | (G << 8) | R; + pixel &= 0xFFFFFF; *dst = pixel; posx += incx; ++dst; @@ -5520,32 +5033,23 @@ static void SDL_Blit_ABGR8888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -5630,32 +5134,23 @@ static void SDL_Blit_ABGR8888_BGR888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -5754,32 +5249,23 @@ static void SDL_Blit_ABGR8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -5837,32 +5323,23 @@ static void SDL_Blit_ABGR8888_ARGB8888_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B, A; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; A = (Uint8)(pixel >> 24); pixel = (A << 24) | (R << 16) | (G << 8) | B; @@ -5942,32 +5419,23 @@ static void SDL_Blit_ABGR8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -6059,32 +5527,23 @@ static void SDL_Blit_ABGR8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B, A; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; A = (Uint8)(pixel >> 24); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -6188,32 +5647,23 @@ static void SDL_Blit_ABGR8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -6273,32 +5723,23 @@ static void SDL_Blit_BGRA8888_RGB888_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); pixel = (R << 16) | (G << 8) | B; @@ -6376,32 +5817,23 @@ static void SDL_Blit_BGRA8888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -6486,32 +5918,23 @@ static void SDL_Blit_BGRA8888_RGB888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -6610,32 +6033,23 @@ static void SDL_Blit_BGRA8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -6691,37 +6105,26 @@ static void SDL_Blit_BGRA8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_BGRA8888_BGR888_Scale(SDL_BlitInfo *info) { Uint32 pixel; - Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); - pixel = (B << 16) | (G << 8) | R; + pixel >>= 8; *dst = pixel; posx += incx; ++dst; @@ -6796,32 +6199,23 @@ static void SDL_Blit_BGRA8888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -6906,32 +6300,23 @@ static void SDL_Blit_BGRA8888_BGR888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -7030,32 +6415,23 @@ static void SDL_Blit_BGRA8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -7113,32 +6489,23 @@ static void SDL_Blit_BGRA8888_ARGB8888_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B, A; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); A = (Uint8)pixel; pixel = (A << 24) | (R << 16) | (G << 8) | B; @@ -7218,32 +6585,23 @@ static void SDL_Blit_BGRA8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -7335,32 +6693,23 @@ static void SDL_Blit_BGRA8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; Uint32 R, G, B, A; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); A = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -7464,32 +6813,23 @@ static void SDL_Blit_BGRA8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; diff --git a/Engine/lib/sdl/src/video/SDL_blit_auto.h b/Engine/lib/sdl/src/video/SDL_blit_auto.h index 53deacb36..9203e4f9b 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_auto.h +++ b/Engine/lib/sdl/src/video/SDL_blit_auto.h @@ -1,7 +1,7 @@ /* DO NOT EDIT! This file is generated by sdlgenblit.pl */ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/SDL_blit_copy.c b/Engine/lib/sdl/src/video/SDL_blit_copy.c index 6dbc36fa6..0223d9a16 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_copy.c +++ b/Engine/lib/sdl/src/video/SDL_blit_copy.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,7 +34,7 @@ SDL_memcpySSE(Uint8 * dst, const Uint8 * src, int len) __m128 values[4]; for (i = len / 64; i--;) { - _mm_prefetch(src, _MM_HINT_NTA); + _mm_prefetch((const char *)src, _MM_HINT_NTA); values[0] = *(__m128 *) (src + 0); values[1] = *(__m128 *) (src + 16); values[2] = *(__m128 *) (src + 32); diff --git a/Engine/lib/sdl/src/video/SDL_blit_copy.h b/Engine/lib/sdl/src/video/SDL_blit_copy.h index 16c4e8d65..24ced5241 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_copy.h +++ b/Engine/lib/sdl/src/video/SDL_blit_copy.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/SDL_blit_slow.c b/Engine/lib/sdl/src/video/SDL_blit_slow.c index 1c0b43e2f..ed9c692b1 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_slow.c +++ b/Engine/lib/sdl/src/video/SDL_blit_slow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,6 +24,21 @@ #include "SDL_blit.h" #include "SDL_blit_slow.h" +#define FORMAT_ALPHA 0 +#define FORMAT_NO_ALPHA -1 +#define FORMAT_2101010 1 +#define FORMAT_HAS_ALPHA(format) format == 0 +#define FORMAT_HAS_NO_ALPHA(format) format < 0 +static int SDL_INLINE detect_format(SDL_PixelFormat *pf) { + if (pf->format == SDL_PIXELFORMAT_ARGB2101010) { + return FORMAT_2101010; + } else if (pf->Amask) { + return FORMAT_ALPHA; + } else { + return FORMAT_NO_ALPHA; + } +} + /* The ONE TRUE BLITTER * This puppy has to handle all the unoptimized cases - yes, it's slow. */ @@ -40,47 +55,45 @@ SDL_Blit_Slow(SDL_BlitInfo * info) Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; SDL_PixelFormat *src_fmt = info->src_fmt; SDL_PixelFormat *dst_fmt = info->dst_fmt; int srcbpp = src_fmt->BytesPerPixel; int dstbpp = dst_fmt->BytesPerPixel; + int srcfmt_val; + int dstfmt_val; Uint32 rgbmask = ~src_fmt->Amask; Uint32 ckey = info->colorkey & rgbmask; - srcy = 0; - posy = 0; + srcfmt_val = detect_format(src_fmt); + dstfmt_val = detect_format(dst_fmt); + incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; /* start at the middle of pixel */ while (info->dst_h--) { Uint8 *src = 0; Uint8 *dst = info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; /* start at the middle of pixel */ + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = - (info->src + (srcy * info->src_pitch) + (srcx * srcbpp)); - } - if (src_fmt->Amask) { - DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, - srcB, srcA); - } else { - DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, - srcB); + srcx = posx >> 16; + src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp)); + + if (FORMAT_HAS_ALPHA(srcfmt_val)) { + DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB, srcA); + } else if (FORMAT_HAS_NO_ALPHA(srcfmt_val)) { + DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB); srcA = 0xFF; + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + srcpixel = *((Uint32 *)(src)); + RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA); } + if (flags & SDL_COPY_COLORKEY) { /* srcpixel isn't set for 24 bpp */ if (srcbpp == 3) { @@ -93,13 +106,15 @@ SDL_Blit_Slow(SDL_BlitInfo * info) continue; } } - if (dst_fmt->Amask) { - DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, - dstB, dstA); - } else { - DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, - dstB); + if (FORMAT_HAS_ALPHA(dstfmt_val)) { + DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA); + } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) { + DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB); dstA = 0xFF; + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + dstpixel = *((Uint32 *)(dst)); + RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA); } if (flags & SDL_COPY_MODULATE_COLOR) { @@ -162,10 +177,15 @@ SDL_Blit_Slow(SDL_BlitInfo * info) dstA = 255; break; } - if (dst_fmt->Amask) { + if (FORMAT_HAS_ALPHA(dstfmt_val)) { ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA); - } else { + } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) { ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB); + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + Uint32 pixel; + ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA); + *(Uint32 *)dst = pixel; } posx += incx; dst += dstbpp; diff --git a/Engine/lib/sdl/src/video/SDL_blit_slow.h b/Engine/lib/sdl/src/video/SDL_blit_slow.h index 082654ef5..cb5388a3e 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_slow.h +++ b/Engine/lib/sdl/src/video/SDL_blit_slow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/SDL_bmp.c b/Engine/lib/sdl/src/video/SDL_bmp.c index cd7962809..0987f5435 100644 --- a/Engine/lib/sdl/src/video/SDL_bmp.c +++ b/Engine/lib/sdl/src/video/SDL_bmp.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -53,7 +53,7 @@ #define LCS_WINDOWS_COLOR_SPACE 0x57696E20 #endif -static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8) +static SDL_bool readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8) { /* | Sets the surface pixels from src. A bmp image is upside down. @@ -70,14 +70,14 @@ static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8) #define COPY_PIXEL(x) spot = &bits[ofs++]; if(spot >= start && spot < end) *spot = (x) for (;;) { - if (!SDL_RWread(src, &ch, 1, 1)) return 1; + if (!SDL_RWread(src, &ch, 1, 1)) return SDL_TRUE; /* | encoded mode starts with a run length, and then a byte | with two colour indexes to alternate between for the run */ if (ch) { Uint8 pixel; - if (!SDL_RWread(src, &pixel, 1, 1)) return 1; + if (!SDL_RWread(src, &pixel, 1, 1)) return SDL_TRUE; if (isRle8) { /* 256-color bitmap, compressed */ do { COPY_PIXEL(pixel); @@ -98,18 +98,18 @@ static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8) | a cursor move, or some absolute data. | zero tag may be absolute mode or an escape */ - if (!SDL_RWread(src, &ch, 1, 1)) return 1; + if (!SDL_RWread(src, &ch, 1, 1)) return SDL_TRUE; switch (ch) { case 0: /* end of line */ ofs = 0; bits -= pitch; /* go to previous */ break; case 1: /* end of bitmap */ - return 0; /* success! */ + return SDL_FALSE; /* success! */ case 2: /* delta */ - if (!SDL_RWread(src, &ch, 1, 1)) return 1; + if (!SDL_RWread(src, &ch, 1, 1)) return SDL_TRUE; ofs += ch; - if (!SDL_RWread(src, &ch, 1, 1)) return 1; + if (!SDL_RWread(src, &ch, 1, 1)) return SDL_TRUE; bits -= (ch * pitch); break; default: /* no compression */ @@ -117,14 +117,14 @@ static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8) needsPad = (ch & 1); do { Uint8 pixel; - if (!SDL_RWread(src, &pixel, 1, 1)) return 1; + if (!SDL_RWread(src, &pixel, 1, 1)) return SDL_TRUE; COPY_PIXEL(pixel); } while (--ch); } else { needsPad = (((ch+1)>>1) & 1); /* (ch+1)>>1: bytes size */ for (;;) { Uint8 pixel; - if (!SDL_RWread(src, &pixel, 1, 1)) return 1; + if (!SDL_RWread(src, &pixel, 1, 1)) return SDL_TRUE; COPY_PIXEL(pixel >> 4); if (!--ch) break; COPY_PIXEL(pixel & 0x0F); @@ -132,7 +132,7 @@ static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8) } } /* pad at even boundary */ - if (needsPad && !SDL_RWread(src, &ch, 1, 1)) return 1; + if (needsPad && !SDL_RWread(src, &ch, 1, 1)) return SDL_TRUE; break; } } @@ -213,12 +213,17 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) surface = NULL; was_error = SDL_FALSE; if (src == NULL) { + SDL_InvalidParamError("src"); was_error = SDL_TRUE; goto done; } /* Read in the BMP file header */ fp_offset = SDL_RWtell(src); + if (fp_offset < 0) { + was_error = SDL_TRUE; + goto done; + } SDL_ClearError(); if (SDL_RWread(src, magic, 1, 2) != 2) { SDL_Error(SDL_EFREAD); @@ -306,7 +311,7 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) } } if (biWidth <= 0 || biHeight == 0) { - SDL_SetError("BMP file with bad dimensions (%dx%d)", biWidth, biHeight); + SDL_SetError("BMP file with bad dimensions (%" SDL_PRIs32 "x%" SDL_PRIs32 ")", biWidth, biHeight); was_error = SDL_TRUE; goto done; } @@ -407,14 +412,20 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) goto done; } - /* - | guich: always use 1< (Uint32)palette->ncolors) { + biClrUsed = 1 << biBitCount; /* try forcing it? */ + if (biClrUsed > (Uint32)palette->ncolors) { + SDL_SetError("Unsupported or incorrect biClrUsed field"); + was_error = SDL_TRUE; + goto done; + } + } + + if (biSize == 12) { for (i = 0; i < (int) biClrUsed; ++i) { SDL_RWread(src, &palette->colors[i].b, 1, 1); SDL_RWread(src, &palette->colors[i].g, 1, 1); @@ -445,8 +456,8 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) goto done; } if ((biCompression == BI_RLE4) || (biCompression == BI_RLE8)) { - was_error = (SDL_bool)readRlePixels(surface, src, biCompression == BI_RLE8); - if (was_error) SDL_SetError("Error reading from BMP"); + was_error = readRlePixels(surface, src, biCompression == BI_RLE8); + if (was_error) SDL_Error(SDL_EFREAD); goto done; } top = (Uint8 *)surface->pixels; @@ -478,7 +489,7 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) for (i = 0; i < surface->w; ++i) { if (i % (8 / ExpandBMP) == 0) { if (!SDL_RWread(src, &pixel, 1, 1)) { - SDL_SetError("Error reading from BMP"); + SDL_Error(SDL_EFREAD); was_error = SDL_TRUE; goto done; } diff --git a/Engine/lib/sdl/src/video/SDL_clipboard.c b/Engine/lib/sdl/src/video/SDL_clipboard.c index f7ad9c341..c3669af6e 100644 --- a/Engine/lib/sdl/src/video/SDL_clipboard.c +++ b/Engine/lib/sdl/src/video/SDL_clipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/SDL_egl.c b/Engine/lib/sdl/src/video/SDL_egl.c index 5ea732fbe..c9fb476b0 100644 --- a/Engine/lib/sdl/src/video/SDL_egl.c +++ b/Engine/lib/sdl/src/video/SDL_egl.c @@ -1,6 +1,6 @@ /* * Simple DirectMedia Layer - * Copyright (C) 1997-2020 Sam Lantinga + * Copyright (C) 1997-2022 Sam Lantinga * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -28,6 +28,10 @@ #if SDL_VIDEO_DRIVER_ANDROID #include #include "../core/android/SDL_android.h" +#include "../video/android/SDL_androidvideo.h" +#endif +#if SDL_VIDEO_DRIVER_RPI +#include #endif #include "SDL_sysvideo.h" @@ -42,6 +46,11 @@ #endif #endif /* EGL_KHR_create_context */ +#ifndef EGL_EXT_present_opaque +#define EGL_EXT_present_opaque 1 +#define EGL_PRESENT_OPAQUE_EXT 0x31DF +#endif /* EGL_EXT_present_opaque */ + #if SDL_VIDEO_DRIVER_RPI /* Raspbian places the OpenGL ES/EGL binaries in a non standard path */ #define DEFAULT_EGL ( vc4 ? "libEGL.so.1" : "libbrcmEGL.so" ) @@ -73,6 +82,7 @@ #define DEFAULT_OGL_ES "libGLESv1_CM.dylib" //??? #elif defined(__OpenBSD__) +/* OpenBSD */ #define DEFAULT_OGL "libGL.so" #define DEFAULT_EGL "libEGL.so" #define DEFAULT_OGL_ES2 "libGLESv2.so" @@ -80,9 +90,10 @@ #define DEFAULT_OGL_ES "libGLESv1_CM.so" #else -/* Desktop Linux */ +/* Desktop Linux/Unix-like */ #define DEFAULT_OGL "libGL.so.1" #define DEFAULT_EGL "libEGL.so.1" +#define ALT_OGL "libOpenGL.so.0" #define DEFAULT_OGL_ES2 "libGLESv2.so.2" #define DEFAULT_OGL_ES_PVR "libGLES_CM.so.1" #define DEFAULT_OGL_ES "libGLESv1_CM.so.1" @@ -99,7 +110,7 @@ #define EGL_PLATFORM_DEVICE_EXT 0x0 #endif -#ifdef SDL_VIDEO_STATIC_ANGLE +#if defined(SDL_VIDEO_STATIC_ANGLE) || defined(SDL_VIDEO_DRIVER_VITA) #define LOAD_FUNC(NAME) \ _this->egl_data->NAME = (void *)NAME; #else @@ -115,7 +126,6 @@ if (!_this->egl_data->NAME) \ #define LOAD_FUNC_EGLEXT(NAME) \ _this->egl_data->NAME = _this->egl_data->eglGetProcAddress(#NAME); - static const char * SDL_EGL_GetErrorName(EGLint eglErrorCode) { #define SDL_EGL_ERROR_TRANSLATE(e) case e: return #e; @@ -237,7 +247,7 @@ SDL_EGL_GetProcAddress(_THIS, const char *proc) retval = _this->egl_data->eglGetProcAddress(proc); } - #ifndef __EMSCRIPTEN__ /* LoadFunction isn't needed on Emscripten and will call dlsym(), causing other problems. */ + #if !defined(__EMSCRIPTEN__) && !defined(SDL_VIDEO_DRIVER_VITA) /* LoadFunction isn't needed on Emscripten and will call dlsym(), causing other problems. */ /* Try SDL_LoadFunction() first for EGL <= 1.4, or as a fallback for >= 1.5. */ if (!retval) { static char procname[64]; @@ -336,7 +346,7 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) } #endif -#ifndef SDL_VIDEO_STATIC_ANGLE +#if !defined(SDL_VIDEO_STATIC_ANGLE) && !defined(SDL_VIDEO_DRIVER_VITA) /* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */ path = SDL_getenv("SDL_VIDEO_GL_DRIVER"); if (path != NULL) { @@ -374,6 +384,12 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) else { path = DEFAULT_OGL; egl_dll_handle = SDL_LoadObject(path); +#ifdef ALT_OGL + if (egl_dll_handle == NULL) { + path = ALT_OGL; + egl_dll_handle = SDL_LoadObject(path); + } +#endif } #endif } @@ -416,6 +432,9 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) #endif _this->egl_data->dll_handle = dll_handle; +#if SDL_VIDEO_DRIVER_VITA + _this->egl_data->egl_dll_handle = egl_dll_handle; +#endif /* Load new function pointers */ LOAD_FUNC(eglGetDisplay); @@ -476,36 +495,40 @@ SDL_EGL_GetVersion(_THIS) { int SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_display, EGLenum platform) { - int egl_version_major, egl_version_minor; int library_load_retcode = SDL_EGL_LoadLibraryOnly(_this, egl_path); if (library_load_retcode != 0) { return library_load_retcode; } - /* EGL 1.5 allows querying for client version with EGL_NO_DISPLAY */ - SDL_EGL_GetVersion(_this); - - egl_version_major = _this->egl_data->egl_version_major; - egl_version_minor = _this->egl_data->egl_version_minor; - - if (egl_version_major == 1 && egl_version_minor == 5) { - LOAD_FUNC(eglGetPlatformDisplay); - } - _this->egl_data->egl_display = EGL_NO_DISPLAY; + #if !defined(__WINRT__) +#if !defined(SDL_VIDEO_DRIVER_VITA) if (platform) { - if (egl_version_major == 1 && egl_version_minor == 5) { - _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(size_t)native_display, NULL); + /* EGL 1.5 allows querying for client version with EGL_NO_DISPLAY + * -- + * Khronos doc: "EGL_BAD_DISPLAY is generated if display is not an EGL display connection, unless display is EGL_NO_DISPLAY and name is EGL_EXTENSIONS." + * Therefore SDL_EGL_GetVersion() shouldn't work with uninitialized display. + * - it actually doesn't work on Android that has 1.5 egl client + * - it works on desktop X11 (using SDL_VIDEO_X11_FORCE_EGL=1) */ + SDL_EGL_GetVersion(_this); + + if (_this->egl_data->egl_version_major == 1 && _this->egl_data->egl_version_minor == 5) { + LOAD_FUNC(eglGetPlatformDisplay); + } + + if (_this->egl_data->eglGetPlatformDisplay) { + _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(uintptr_t)native_display, NULL); } else { if (SDL_EGL_HasExtension(_this, SDL_EGL_CLIENT_EXTENSION, "EGL_EXT_platform_base")) { _this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddress(_this, "eglGetPlatformDisplayEXT"); if (_this->egl_data->eglGetPlatformDisplayEXT) { - _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)(size_t)native_display, NULL); + _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)(uintptr_t)native_display, NULL); } } } } +#endif /* Try the implementation-specific eglGetDisplay even if eglGetPlatformDisplay fails */ if (_this->egl_data->egl_display == EGL_NO_DISPLAY) { _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display); @@ -515,7 +538,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa *_this->gl_config.driver_path = '\0'; return SDL_SetError("Could not get EGL display"); } - + if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) { _this->gl_config.driver_loaded = 0; *_this->gl_config.driver_path = '\0'; @@ -526,7 +549,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa /* Get the EGL version with a valid egl_display, for EGL <= 1.4 */ SDL_EGL_GetVersion(_this); - _this->egl_data->is_offscreen = 0; + _this->egl_data->is_offscreen = SDL_FALSE; return 0; } @@ -546,7 +569,7 @@ SDL_EGL_InitializeOffscreen(_THIS, int device) EGLint num_egl_devices = 0; const char *egl_device_hint; - if (_this->gl_config.driver_loaded != 1) { + if (_this->gl_config.driver_loaded <= 0) { return SDL_SetError("SDL_EGL_LoadLibraryOnly() has not been called or has failed."); } @@ -614,7 +637,7 @@ SDL_EGL_InitializeOffscreen(_THIS, int device) /* Get the EGL version with a valid egl_display, for EGL <= 1.4 */ SDL_EGL_GetVersion(_this); - _this->egl_data->is_offscreen = 1; + _this->egl_data->is_offscreen = SDL_TRUE; return 0; } @@ -634,7 +657,8 @@ typedef struct { char const* name; } Attribute; -Attribute attributes[] = { +static +Attribute all_attributes[] = { ATTRIBUTE( EGL_BUFFER_SIZE ), ATTRIBUTE( EGL_ALPHA_SIZE ), ATTRIBUTE( EGL_BLUE_SIZE ), @@ -674,31 +698,27 @@ Attribute attributes[] = { static void dumpconfig(_THIS, EGLConfig config) { int attr; - for (attr = 0 ; attregl_data->eglGetConfigAttrib(_this->egl_data->egl_display, config, attributes[attr].attribute, &value); - SDL_Log("\t%-32s: %10d (0x%08x)\n", attributes[attr].name, value, value); + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, config, all_attributes[attr].attribute, &value); + SDL_Log("\t%-32s: %10d (0x%08x)\n", all_attributes[attr].name, value, value); } } #endif /* DUMP_EGL_CONFIG */ -int -SDL_EGL_ChooseConfig(_THIS) +static int +SDL_EGL_PrivateChooseConfig(_THIS, SDL_bool set_config_caveat_none) { -/* 64 seems nice. */ + /* 64 seems nice. */ EGLint attribs[64]; EGLint found_configs = 0, value; /* 128 seems even nicer here */ EGLConfig configs[128]; SDL_bool has_matching_format = SDL_FALSE; - int i, j, best_bitdiff = -1, bitdiff; - - if (!_this->egl_data) { - /* The EGL library wasn't loaded, SDL_GetError() should have info */ - return -1; - } - + int i, j, best_bitdiff = -1, best_truecolor_bitdiff = -1; + int truecolor_config_idx = -1; + /* Get a valid EGL configuration */ i = 0; attribs[i++] = EGL_RED_SIZE; @@ -707,30 +727,37 @@ SDL_EGL_ChooseConfig(_THIS) attribs[i++] = _this->gl_config.green_size; attribs[i++] = EGL_BLUE_SIZE; attribs[i++] = _this->gl_config.blue_size; - + + if (set_config_caveat_none) { + attribs[i++] = EGL_CONFIG_CAVEAT; + attribs[i++] = EGL_NONE; + } + if (_this->gl_config.alpha_size) { attribs[i++] = EGL_ALPHA_SIZE; attribs[i++] = _this->gl_config.alpha_size; } - + if (_this->gl_config.buffer_size) { attribs[i++] = EGL_BUFFER_SIZE; attribs[i++] = _this->gl_config.buffer_size; } - - attribs[i++] = EGL_DEPTH_SIZE; - attribs[i++] = _this->gl_config.depth_size; - + + if (_this->gl_config.depth_size) { + attribs[i++] = EGL_DEPTH_SIZE; + attribs[i++] = _this->gl_config.depth_size; + } + if (_this->gl_config.stencil_size) { attribs[i++] = EGL_STENCIL_SIZE; attribs[i++] = _this->gl_config.stencil_size; } - + if (_this->gl_config.multisamplebuffers) { attribs[i++] = EGL_SAMPLE_BUFFERS; attribs[i++] = _this->gl_config.multisamplebuffers; } - + if (_this->gl_config.multisamplesamples) { attribs[i++] = EGL_SAMPLES; attribs[i++] = _this->gl_config.multisamplesamples; @@ -767,24 +794,28 @@ SDL_EGL_ChooseConfig(_THIS) attribs[i++] = EGL_NONE; + SDL_assert(i < SDL_arraysize(attribs)); + if (_this->egl_data->eglChooseConfig(_this->egl_data->egl_display, attribs, configs, SDL_arraysize(configs), &found_configs) == EGL_FALSE || found_configs == 0) { - return SDL_EGL_SetError("Couldn't find matching EGL config", "eglChooseConfig"); + return -1; } /* first ensure that a found config has a matching format, or the function will fall through. */ - for (i = 0; i < found_configs; i++ ) { - if (_this->egl_data->egl_required_visual_id) - { + if (_this->egl_data->egl_required_visual_id) + { + for (i = 0; i < found_configs; i++ ) { EGLint format; _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], EGL_NATIVE_VISUAL_ID, &format); - if (_this->egl_data->egl_required_visual_id == format) + if (_this->egl_data->egl_required_visual_id == format) { has_matching_format = SDL_TRUE; + break; + } } } @@ -792,22 +823,35 @@ SDL_EGL_ChooseConfig(_THIS) /* From those, we select the one that matches our requirements more closely via a makeshift algorithm */ for (i = 0; i < found_configs; i++ ) { - if (has_matching_format && _this->egl_data->egl_required_visual_id) - { + SDL_bool is_truecolor = SDL_FALSE; + int bitdiff = 0; + + if (has_matching_format && _this->egl_data->egl_required_visual_id) { EGLint format; _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, - configs[i], + configs[i], EGL_NATIVE_VISUAL_ID, &format); - if (_this->egl_data->egl_required_visual_id != format) + if (_this->egl_data->egl_required_visual_id != format) { continue; + } + } + + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], EGL_RED_SIZE, &value); + if (value == 8) { + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], EGL_GREEN_SIZE, &value); + if (value == 8) { + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], EGL_BLUE_SIZE, &value); + if (value == 8) { + is_truecolor = SDL_TRUE; + } + } } - bitdiff = 0; for (j = 0; j < SDL_arraysize(attribs) - 1; j += 2) { if (attribs[j] == EGL_NONE) { break; } - + if ( attribs[j+1] != EGL_DONT_CARE && ( attribs[j] == EGL_RED_SIZE || attribs[j] == EGL_GREEN_SIZE || @@ -820,24 +864,70 @@ SDL_EGL_ChooseConfig(_THIS) } } - if (bitdiff < best_bitdiff || best_bitdiff == -1) { + if ((bitdiff < best_bitdiff) || (best_bitdiff == -1)) { _this->egl_data->egl_config = configs[i]; - best_bitdiff = bitdiff; } - if (bitdiff == 0) { - break; /* we found an exact match! */ + if (is_truecolor && ((bitdiff < best_truecolor_bitdiff) || (best_truecolor_bitdiff == -1))) { + truecolor_config_idx = i; + best_truecolor_bitdiff = bitdiff; } } + #define FAVOR_TRUECOLOR 1 + #if FAVOR_TRUECOLOR + /* Some apps request a low color depth, either because they _assume_ + they'll get a larger one but don't want to fail if only smaller ones + are available, or they just never called SDL_GL_SetAttribute at all and + got a tiny default. For these cases, a game that would otherwise run + at 24-bit color might get dithered down to something smaller, which is + worth avoiding. If the app requested <= 16 bit color and an exact 24-bit + match is available, favor that. Otherwise, we look for the closest + match. Note that while the API promises what you request _or better_, + it's feasible this can be disastrous for performance for custom software + on small hardware that all expected to actually get 16-bit color. In this + case, turn off FAVOR_TRUECOLOR (and maybe send a patch to make this more + flexible). */ + if ( ((_this->gl_config.red_size + _this->gl_config.blue_size + _this->gl_config.green_size) <= 16) ) { + if (truecolor_config_idx != -1) { + _this->egl_data->egl_config = configs[truecolor_config_idx]; + } + } + #endif + #ifdef DUMP_EGL_CONFIG dumpconfig(_this, _this->egl_data->egl_config); #endif - + return 0; } +int +SDL_EGL_ChooseConfig(_THIS) +{ + int ret; + + if (!_this->egl_data) { + return SDL_SetError("EGL not initialized"); + } + + /* Try with EGL_CONFIG_CAVEAT set to EGL_NONE, to avoid any EGL_SLOW_CONFIG or EGL_NON_CONFORMANT_CONFIG */ + ret = SDL_EGL_PrivateChooseConfig(_this, SDL_TRUE); + if (ret == 0) { + return 0; + } + + /* Fallback with all configs */ + ret = SDL_EGL_PrivateChooseConfig(_this, SDL_FALSE); + if (ret == 0) { + SDL_Log("SDL_EGL_ChooseConfig: found a slow EGL config"); + return 0; + } + + return SDL_EGL_SetError("Couldn't find matching EGL config", "eglChooseConfig"); +} + SDL_GLContext SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) { @@ -852,7 +942,7 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) SDL_bool profile_es = (profile_mask == SDL_GL_CONTEXT_PROFILE_ES); if (!_this->egl_data) { - /* The EGL library wasn't loaded, SDL_GetError() should have info */ + SDL_SetError("EGL not initialized"); return NULL; } @@ -922,27 +1012,24 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) } } - if (_this->gl_config.no_error) { #ifdef EGL_KHR_create_context_no_error + if (_this->gl_config.no_error) { if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_create_context_no_error")) { attribs[attr++] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR; attribs[attr++] = _this->gl_config.no_error; - } else -#endif - { - SDL_SetError("EGL implementation does not support no_error contexts"); - return NULL; } } +#endif attribs[attr++] = EGL_NONE; /* Bind the API */ if (profile_es) { - _this->egl_data->eglBindAPI(EGL_OPENGL_ES_API); + _this->egl_data->apitype = EGL_OPENGL_ES_API; } else { - _this->egl_data->eglBindAPI(EGL_OPENGL_API); + _this->egl_data->apitype = EGL_OPENGL_API; } + _this->egl_data->eglBindAPI(_this->egl_data->apitype); egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display, _this->egl_data->egl_config, @@ -956,16 +1043,8 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) _this->egl_data->egl_swapinterval = 0; if (SDL_EGL_MakeCurrent(_this, egl_surface, egl_context) < 0) { - /* Save the SDL error set by SDL_EGL_MakeCurrent */ - char errorText[1024]; - SDL_strlcpy(errorText, SDL_GetError(), SDL_arraysize(errorText)); - - /* Delete the context, which may alter the value returned by SDL_GetError() */ + /* Delete the context */ SDL_EGL_DeleteContext(_this, egl_context); - - /* Restore the SDL error */ - SDL_SetError("%s", errorText); - return NULL; } @@ -1008,9 +1087,23 @@ SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context) EGLContext egl_context = (EGLContext) context; if (!_this->egl_data) { - return SDL_SetError("OpenGL not initialized"); + return SDL_SetError("EGL not initialized"); } - + + if (!_this->egl_data->eglMakeCurrent) { + if (!egl_surface && !context) { + /* Can't do the nothing there is to do? Probably trying to cleanup a failed startup, just return. */ + return 0; + } else { + return SDL_SetError("EGL not initialized"); /* something clearly went wrong somewhere. */ + } + } + + /* Make sure current thread has a valid API bound to it. */ + if (_this->egl_data->eglBindAPI) { + _this->egl_data->eglBindAPI(_this->egl_data->apitype); + } + /* The android emulator crashes badly if you try to eglMakeCurrent * with a valid context and invalid surface, so we have to check for both here. */ @@ -1022,7 +1115,7 @@ SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context) return SDL_EGL_SetError("Unable to make EGL context current", "eglMakeCurrent"); } } - + return 0; } @@ -1034,6 +1127,13 @@ SDL_EGL_SetSwapInterval(_THIS, int interval) if (!_this->egl_data) { return SDL_SetError("EGL not initialized"); } + + /* FIXME: Revisit this check when EGL_EXT_swap_control_tear is published: + * https://github.com/KhronosGroup/EGL-Registry/pull/113 + */ + if (interval < 0) { + return SDL_SetError("Late swap tearing currently unsupported"); + } status = _this->egl_data->eglSwapInterval(_this->egl_data->egl_display, interval); if (status == EGL_TRUE) { @@ -1083,8 +1183,12 @@ SDL_EGL_DeleteContext(_THIS, SDL_GLContext context) EGLSurface * SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) { - /* max 2 values plus terminator. */ - EGLint attribs[3]; +#if SDL_VIDEO_DRIVER_ANDROID + EGLint format_wanted; + EGLint format_got; +#endif + /* max 2 key+value pairs, plus terminator. */ + EGLint attribs[5]; int attr = 0; EGLSurface * surface; @@ -1092,24 +1196,18 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) if (SDL_EGL_ChooseConfig(_this) != 0) { return EGL_NO_SURFACE; } - + #if SDL_VIDEO_DRIVER_ANDROID - { - /* Android docs recommend doing this! - * Ref: http://developer.android.com/reference/android/app/NativeActivity.html - */ - EGLint format; - _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, - _this->egl_data->egl_config, - EGL_NATIVE_VISUAL_ID, &format); + /* On Android, EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is + * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). */ + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, + _this->egl_data->egl_config, + EGL_NATIVE_VISUAL_ID, &format_wanted); - ANativeWindow_setBuffersGeometry(nw, 0, 0, format); + /* Format based on selected egl config. */ + ANativeWindow_setBuffersGeometry(nw, 0, 0, format_wanted); +#endif - /* Update SurfaceView holder format. - * May triggers a sequence surfaceDestroyed(), surfaceCreated(), surfaceChanged(). */ - Android_JNI_SetSurfaceViewFormat(format); - } -#endif if (_this->gl_config.framebuffer_srgb_capable) { #ifdef EGL_KHR_gl_colorspace if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_gl_colorspace")) { @@ -1123,6 +1221,14 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) } } +#ifdef EGL_EXT_present_opaque + if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_EXT_present_opaque")) { + const SDL_bool allow_transparent = SDL_GetHintBoolean(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, SDL_FALSE); + attribs[attr++] = EGL_PRESENT_OPAQUE_EXT; + attribs[attr++] = allow_transparent ? EGL_FALSE : EGL_TRUE; + } +#endif + attribs[attr++] = EGL_NONE; surface = _this->egl_data->eglCreateWindowSurface( @@ -1132,6 +1238,12 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) if (surface == EGL_NO_SURFACE) { SDL_EGL_SetError("unable to create an EGL window surface", "eglCreateWindowSurface"); } + +#if SDL_VIDEO_DRIVER_ANDROID + format_got = ANativeWindow_getFormat(nw); + Android_SetFormat(format_wanted, format_got); +#endif + return surface; } diff --git a/Engine/lib/sdl/src/video/SDL_egl_c.h b/Engine/lib/sdl/src/video/SDL_egl_c.h index 991344977..1827af05a 100644 --- a/Engine/lib/sdl/src/video/SDL_egl_c.h +++ b/Engine/lib/sdl/src/video/SDL_egl_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -40,6 +40,8 @@ typedef struct SDL_EGL_VideoData int egl_surfacetype; int egl_version_major, egl_version_minor; EGLint egl_required_visual_id; + SDL_bool is_offscreen; /* whether EGL display was offscreen */ + EGLenum apitype; /* EGL_OPENGL_ES_API, EGL_OPENGL_API, etc */ EGLDisplay(EGLAPIENTRY *eglGetDisplay) (NativeDisplayType display); EGLDisplay(EGLAPIENTRY *eglGetPlatformDisplay) (EGLenum platform, @@ -114,11 +116,6 @@ typedef struct SDL_EGL_VideoData EGLint(EGLAPIENTRY *eglClientWaitSyncKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); /* Atomic functions end */ - - - /* whether EGL display was offscreen */ - int is_offscreen; - } SDL_EGL_VideoData; /* OpenGLES functions */ diff --git a/Engine/lib/sdl/src/video/SDL_fillrect.c b/Engine/lib/sdl/src/video/SDL_fillrect.c index 3deb50132..13872d271 100644 --- a/Engine/lib/sdl/src/video/SDL_fillrect.c +++ b/Engine/lib/sdl/src/video/SDL_fillrect.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,7 +28,7 @@ #ifdef __SSE__ /* *INDENT-OFF* */ -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) #define SSE_BEGIN \ __m128 c128; \ c128.m128_u32[0] = color; \ @@ -145,13 +145,13 @@ SDL_FillRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h) switch ((uintptr_t) p & 3) { case 1: *p++ = (Uint8) color; - --n; /* fallthrough */ + --n; SDL_FALLTHROUGH; case 2: *p++ = (Uint8) color; - --n; /* fallthrough */ + --n; SDL_FALLTHROUGH; case 3: *p++ = (Uint8) color; - --n; /* fallthrough */ + --n; } SDL_memset4(p, color, (n >> 2)); } @@ -159,11 +159,11 @@ SDL_FillRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h) p += (n & ~3); switch (n & 3) { case 3: - *p++ = (Uint8) color; /* fallthrough */ + *p++ = (Uint8) color; SDL_FALLTHROUGH; case 2: - *p++ = (Uint8) color; /* fallthrough */ + *p++ = (Uint8) color; SDL_FALLTHROUGH; case 1: - *p++ = (Uint8) color; /* fallthrough */ + *p++ = (Uint8) color; } } pixels += pitch; @@ -238,7 +238,7 @@ int SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color) { if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_FillRect(): dst"); } /* If 'rect' == NULL, then fill the whole surface */ @@ -306,12 +306,7 @@ SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, int i; if (!dst) { - return SDL_SetError("Passed NULL destination surface"); - } - - /* This function doesn't work on surfaces < 8 bpp */ - if (dst->format->BitsPerPixel < 8) { - return SDL_SetError("SDL_FillRect(): Unsupported surface format"); + return SDL_InvalidParamError("SDL_FillRects(): dst"); } /* Nothing to do */ @@ -321,11 +316,28 @@ SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, /* Perform software fill */ if (!dst->pixels) { - return SDL_SetError("SDL_FillRect(): You must lock the surface"); + return SDL_SetError("SDL_FillRects(): You must lock the surface"); } if (!rects) { - return SDL_SetError("SDL_FillRects() passed NULL rects"); + return SDL_InvalidParamError("SDL_FillRects(): rects"); + } + + /* This function doesn't usually work on surfaces < 8 bpp + * Except: support for 4bits, when filling full size. + */ + if (dst->format->BitsPerPixel < 8) { + if (count == 1) { + const SDL_Rect *r = &rects[0]; + if (r->x == 0 && r->y == 0 && r->w == dst->w && r->w == dst->h) { + if (dst->format->BitsPerPixel == 4) { + Uint8 b = (((Uint8) color << 4) | (Uint8) color); + SDL_memset(dst->pixels, b, dst->h * dst->pitch); + return 1; + } + } + } + return SDL_SetError("SDL_FillRects(): Unsupported surface format"); } #if SDL_ARM_NEON_BLITTERS diff --git a/Engine/lib/sdl/src/video/SDL_pixels.c b/Engine/lib/sdl/src/video/SDL_pixels.c index 84b693217..b76161d03 100644 --- a/Engine/lib/sdl/src/video/SDL_pixels.c +++ b/Engine/lib/sdl/src/video/SDL_pixels.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -333,7 +333,7 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, if (Rmask == 0) { return SDL_PIXELFORMAT_RGB555; } - /* fallthrough */ + SDL_FALLTHROUGH; case 16: if (Rmask == 0) { return SDL_PIXELFORMAT_RGB565; @@ -677,7 +677,7 @@ int SDL_SetPixelFormatPalette(SDL_PixelFormat * format, SDL_Palette *palette) { if (!format) { - return SDL_SetError("SDL_SetPixelFormatPalette() passed NULL format"); + return SDL_InvalidParamError("SDL_SetPixelFormatPalette(): format"); } if (palette && palette->ncolors > (1 << format->BitsPerPixel)) { @@ -871,7 +871,7 @@ SDL_MapRGBA(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b, return (r >> format->Rloss) << format->Rshift | (g >> format->Gloss) << format->Gshift | (b >> format->Bloss) << format->Bshift - | ((a >> format->Aloss) << format->Ashift & format->Amask); + | ((Uint32)(a >> format->Aloss) << format->Ashift & format->Amask); } else { return SDL_FindColor(format->palette, r, g, b, a); } @@ -947,7 +947,7 @@ Map1to1(SDL_Palette * src, SDL_Palette * dst, int *identical) } *identical = 0; } - map = (Uint8 *) SDL_malloc(src->ncolors); + map = (Uint8 *) SDL_calloc(256, sizeof(Uint8)); if (map == NULL) { SDL_OutOfMemory(); return (NULL); @@ -971,7 +971,7 @@ Map1toN(SDL_PixelFormat * src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod, SDL_Palette *pal = src->palette; bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel); - map = (Uint8 *) SDL_malloc(pal->ncolors * bpp); + map = (Uint8 *) SDL_calloc(256, bpp); if (map == NULL) { SDL_OutOfMemory(); return (NULL); @@ -983,7 +983,7 @@ Map1toN(SDL_PixelFormat * src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod, Uint8 G = (Uint8) ((pal->colors[i].g * Gmod) / 255); Uint8 B = (Uint8) ((pal->colors[i].b * Bmod) / 255); Uint8 A = (Uint8) ((pal->colors[i].a * Amod) / 255); - ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, R, G, B, A); + ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, (Uint32)R, (Uint32)G, (Uint32)B, (Uint32)A); } return (map); } diff --git a/Engine/lib/sdl/src/video/SDL_pixels_c.h b/Engine/lib/sdl/src/video/SDL_pixels_c.h index 9ff590e0c..828fe3bd8 100644 --- a/Engine/lib/sdl/src/video/SDL_pixels_c.h +++ b/Engine/lib/sdl/src/video/SDL_pixels_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/SDL_rect.c b/Engine/lib/sdl/src/video/SDL_rect.c index b9aca3b53..dfa939032 100644 --- a/Engine/lib/sdl/src/video/SDL_rect.c +++ b/Engine/lib/sdl/src/video/SDL_rect.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,447 +23,8 @@ #include "SDL_rect.h" #include "SDL_rect_c.h" -SDL_bool -SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B) -{ - int Amin, Amax, Bmin, Bmax; - - if (!A) { - SDL_InvalidParamError("A"); - return SDL_FALSE; - } - - if (!B) { - SDL_InvalidParamError("B"); - return SDL_FALSE; - } - - /* Special cases for empty rects */ - if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) { - return SDL_FALSE; - } - - /* Horizontal intersection */ - Amin = A->x; - Amax = Amin + A->w; - Bmin = B->x; - Bmax = Bmin + B->w; - if (Bmin > Amin) - Amin = Bmin; - if (Bmax < Amax) - Amax = Bmax; - if (Amax <= Amin) - return SDL_FALSE; - - /* Vertical intersection */ - Amin = A->y; - Amax = Amin + A->h; - Bmin = B->y; - Bmax = Bmin + B->h; - if (Bmin > Amin) - Amin = Bmin; - if (Bmax < Amax) - Amax = Bmax; - if (Amax <= Amin) - return SDL_FALSE; - - return SDL_TRUE; -} - -SDL_bool -SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) -{ - int Amin, Amax, Bmin, Bmax; - - if (!A) { - SDL_InvalidParamError("A"); - return SDL_FALSE; - } - - if (!B) { - SDL_InvalidParamError("B"); - return SDL_FALSE; - } - - if (!result) { - SDL_InvalidParamError("result"); - return SDL_FALSE; - } - - /* Special cases for empty rects */ - if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) { - result->w = 0; - result->h = 0; - return SDL_FALSE; - } - - /* Horizontal intersection */ - Amin = A->x; - Amax = Amin + A->w; - Bmin = B->x; - Bmax = Bmin + B->w; - if (Bmin > Amin) - Amin = Bmin; - result->x = Amin; - if (Bmax < Amax) - Amax = Bmax; - result->w = Amax - Amin; - - /* Vertical intersection */ - Amin = A->y; - Amax = Amin + A->h; - Bmin = B->y; - Bmax = Bmin + B->h; - if (Bmin > Amin) - Amin = Bmin; - result->y = Amin; - if (Bmax < Amax) - Amax = Bmax; - result->h = Amax - Amin; - - return !SDL_RectEmpty(result); -} - -void -SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) -{ - int Amin, Amax, Bmin, Bmax; - - if (!A) { - SDL_InvalidParamError("A"); - return; - } - - if (!B) { - SDL_InvalidParamError("B"); - return; - } - - if (!result) { - SDL_InvalidParamError("result"); - return; - } - - /* Special cases for empty Rects */ - if (SDL_RectEmpty(A)) { - if (SDL_RectEmpty(B)) { - /* A and B empty */ - return; - } else { - /* A empty, B not empty */ - *result = *B; - return; - } - } else { - if (SDL_RectEmpty(B)) { - /* A not empty, B empty */ - *result = *A; - return; - } - } - - /* Horizontal union */ - Amin = A->x; - Amax = Amin + A->w; - Bmin = B->x; - Bmax = Bmin + B->w; - if (Bmin < Amin) - Amin = Bmin; - result->x = Amin; - if (Bmax > Amax) - Amax = Bmax; - result->w = Amax - Amin; - - /* Vertical union */ - Amin = A->y; - Amax = Amin + A->h; - Bmin = B->y; - Bmax = Bmin + B->h; - if (Bmin < Amin) - Amin = Bmin; - result->y = Amin; - if (Bmax > Amax) - Amax = Bmax; - result->h = Amax - Amin; -} - -SDL_bool -SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip, - SDL_Rect * result) -{ - int minx = 0; - int miny = 0; - int maxx = 0; - int maxy = 0; - int x, y, i; - - if (!points) { - SDL_InvalidParamError("points"); - return SDL_FALSE; - } - - if (count < 1) { - SDL_InvalidParamError("count"); - return SDL_FALSE; - } - - if (clip) { - SDL_bool added = SDL_FALSE; - const int clip_minx = clip->x; - const int clip_miny = clip->y; - const int clip_maxx = clip->x+clip->w-1; - const int clip_maxy = clip->y+clip->h-1; - - /* Special case for empty rectangle */ - if (SDL_RectEmpty(clip)) { - return SDL_FALSE; - } - - for (i = 0; i < count; ++i) { - x = points[i].x; - y = points[i].y; - - if (x < clip_minx || x > clip_maxx || - y < clip_miny || y > clip_maxy) { - continue; - } - if (!added) { - /* Special case: if no result was requested, we are done */ - if (result == NULL) { - return SDL_TRUE; - } - - /* First point added */ - minx = maxx = x; - miny = maxy = y; - added = SDL_TRUE; - continue; - } - if (x < minx) { - minx = x; - } else if (x > maxx) { - maxx = x; - } - if (y < miny) { - miny = y; - } else if (y > maxy) { - maxy = y; - } - } - if (!added) { - return SDL_FALSE; - } - } else { - /* Special case: if no result was requested, we are done */ - if (result == NULL) { - return SDL_TRUE; - } - - /* No clipping, always add the first point */ - minx = maxx = points[0].x; - miny = maxy = points[0].y; - - for (i = 1; i < count; ++i) { - x = points[i].x; - y = points[i].y; - - if (x < minx) { - minx = x; - } else if (x > maxx) { - maxx = x; - } - if (y < miny) { - miny = y; - } else if (y > maxy) { - maxy = y; - } - } - } - - if (result) { - result->x = minx; - result->y = miny; - result->w = (maxx-minx)+1; - result->h = (maxy-miny)+1; - } - return SDL_TRUE; -} - -/* Use the Cohen-Sutherland algorithm for line clipping */ -#define CODE_BOTTOM 1 -#define CODE_TOP 2 -#define CODE_LEFT 4 -#define CODE_RIGHT 8 - -static int -ComputeOutCode(const SDL_Rect * rect, int x, int y) -{ - int code = 0; - if (y < rect->y) { - code |= CODE_TOP; - } else if (y >= rect->y + rect->h) { - code |= CODE_BOTTOM; - } - if (x < rect->x) { - code |= CODE_LEFT; - } else if (x >= rect->x + rect->w) { - code |= CODE_RIGHT; - } - return code; -} - -SDL_bool -SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2, - int *Y2) -{ - int x = 0; - int y = 0; - int x1, y1; - int x2, y2; - int rectx1; - int recty1; - int rectx2; - int recty2; - int outcode1, outcode2; - - if (!rect) { - SDL_InvalidParamError("rect"); - return SDL_FALSE; - } - - if (!X1) { - SDL_InvalidParamError("X1"); - return SDL_FALSE; - } - - if (!Y1) { - SDL_InvalidParamError("Y1"); - return SDL_FALSE; - } - - if (!X2) { - SDL_InvalidParamError("X2"); - return SDL_FALSE; - } - - if (!Y2) { - SDL_InvalidParamError("Y2"); - return SDL_FALSE; - } - - /* Special case for empty rect */ - if (SDL_RectEmpty(rect)) { - return SDL_FALSE; - } - - x1 = *X1; - y1 = *Y1; - x2 = *X2; - y2 = *Y2; - rectx1 = rect->x; - recty1 = rect->y; - rectx2 = rect->x + rect->w - 1; - recty2 = rect->y + rect->h - 1; - - /* Check to see if entire line is inside rect */ - if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 && - y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) { - return SDL_TRUE; - } - - /* Check to see if entire line is to one side of rect */ - if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) || - (y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) { - return SDL_FALSE; - } - - if (y1 == y2) { - /* Horizontal line, easy to clip */ - if (x1 < rectx1) { - *X1 = rectx1; - } else if (x1 > rectx2) { - *X1 = rectx2; - } - if (x2 < rectx1) { - *X2 = rectx1; - } else if (x2 > rectx2) { - *X2 = rectx2; - } - return SDL_TRUE; - } - - if (x1 == x2) { - /* Vertical line, easy to clip */ - if (y1 < recty1) { - *Y1 = recty1; - } else if (y1 > recty2) { - *Y1 = recty2; - } - if (y2 < recty1) { - *Y2 = recty1; - } else if (y2 > recty2) { - *Y2 = recty2; - } - return SDL_TRUE; - } - - /* More complicated Cohen-Sutherland algorithm */ - outcode1 = ComputeOutCode(rect, x1, y1); - outcode2 = ComputeOutCode(rect, x2, y2); - while (outcode1 || outcode2) { - if (outcode1 & outcode2) { - return SDL_FALSE; - } - - if (outcode1) { - if (outcode1 & CODE_TOP) { - y = recty1; - x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); - } else if (outcode1 & CODE_BOTTOM) { - y = recty2; - x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); - } else if (outcode1 & CODE_LEFT) { - x = rectx1; - y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); - } else if (outcode1 & CODE_RIGHT) { - x = rectx2; - y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); - } - x1 = x; - y1 = y; - outcode1 = ComputeOutCode(rect, x, y); - } else { - if (outcode2 & CODE_TOP) { - y = recty1; - x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); - } else if (outcode2 & CODE_BOTTOM) { - y = recty2; - x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); - } else if (outcode2 & CODE_LEFT) { - /* If this assertion ever fires, here's the static analysis that warned about it: - http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-b0d01a.html#EndPath */ - SDL_assert(x2 != x1); /* if equal: division by zero. */ - x = rectx1; - y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); - } else if (outcode2 & CODE_RIGHT) { - /* If this assertion ever fires, here's the static analysis that warned about it: - http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-39b114.html#EndPath */ - SDL_assert(x2 != x1); /* if equal: division by zero. */ - x = rectx2; - y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); - } - x2 = x; - y2 = y; - outcode2 = ComputeOutCode(rect, x, y); - } - } - *X1 = x1; - *Y1 = y1; - *X2 = x2; - *Y2 = y2; - return SDL_TRUE; -} - +/* There's no float version of this at the moment, because it's not a public API + and internally we only need the int version. */ SDL_bool SDL_GetSpanEnclosingRect(int width, int height, int numrects, const SDL_Rect * rects, SDL_Rect *span) @@ -475,24 +36,16 @@ SDL_GetSpanEnclosingRect(int width, int height, if (width < 1) { SDL_InvalidParamError("width"); return SDL_FALSE; - } - - if (height < 1) { + } else if (height < 1) { SDL_InvalidParamError("height"); return SDL_FALSE; - } - - if (!rects) { + } else if (!rects) { SDL_InvalidParamError("rects"); return SDL_FALSE; - } - - if (!span) { + } else if (!span) { SDL_InvalidParamError("span"); return SDL_FALSE; - } - - if (numrects < 1) { + } else if (numrects < 1) { SDL_InvalidParamError("numrects"); return SDL_FALSE; } @@ -527,4 +80,36 @@ SDL_GetSpanEnclosingRect(int width, int height, return SDL_FALSE; } + +/* For use with the Cohen-Sutherland algorithm for line clipping, in SDL_rect_impl.h */ +#define CODE_BOTTOM 1 +#define CODE_TOP 2 +#define CODE_LEFT 4 +#define CODE_RIGHT 8 + +/* Same code twice, for float and int versions... */ +#define RECTTYPE SDL_Rect +#define POINTTYPE SDL_Point +#define SCALARTYPE int +#define COMPUTEOUTCODE ComputeOutCode +#define SDL_HASINTERSECTION SDL_HasIntersection +#define SDL_INTERSECTRECT SDL_IntersectRect +#define SDL_RECTEMPTY SDL_RectEmpty +#define SDL_UNIONRECT SDL_UnionRect +#define SDL_ENCLOSEPOINTS SDL_EnclosePoints +#define SDL_INTERSECTRECTANDLINE SDL_IntersectRectAndLine +#include "SDL_rect_impl.h" + +#define RECTTYPE SDL_FRect +#define POINTTYPE SDL_FPoint +#define SCALARTYPE float +#define COMPUTEOUTCODE ComputeOutCodeF +#define SDL_HASINTERSECTION SDL_HasIntersectionF +#define SDL_INTERSECTRECT SDL_IntersectFRect +#define SDL_RECTEMPTY SDL_FRectEmpty +#define SDL_UNIONRECT SDL_UnionFRect +#define SDL_ENCLOSEPOINTS SDL_EncloseFPoints +#define SDL_INTERSECTRECTANDLINE SDL_IntersectFRectAndLine +#include "SDL_rect_impl.h" + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/SDL_rect_c.h b/Engine/lib/sdl/src/video/SDL_rect_c.h index f194938e6..6205abc70 100644 --- a/Engine/lib/sdl/src/video/SDL_rect_c.h +++ b/Engine/lib/sdl/src/video/SDL_rect_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/SDL_rect_impl.h b/Engine/lib/sdl/src/video/SDL_rect_impl.h new file mode 100644 index 000000000..993bb8eb0 --- /dev/null +++ b/Engine/lib/sdl/src/video/SDL_rect_impl.h @@ -0,0 +1,444 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* This file is #included twice to support int and float versions with the same code. */ + +SDL_bool +SDL_HASINTERSECTION(const RECTTYPE * A, const RECTTYPE * B) +{ + SCALARTYPE Amin, Amax, Bmin, Bmax; + + if (!A) { + SDL_InvalidParamError("A"); + return SDL_FALSE; + } else if (!B) { + SDL_InvalidParamError("B"); + return SDL_FALSE; + } else if (SDL_RECTEMPTY(A) || SDL_RECTEMPTY(B)) { + return SDL_FALSE; /* Special cases for empty rects */ + } + + /* Horizontal intersection */ + Amin = A->x; + Amax = Amin + A->w; + Bmin = B->x; + Bmax = Bmin + B->w; + if (Bmin > Amin) { + Amin = Bmin; + } + if (Bmax < Amax) { + Amax = Bmax; + } + if (Amax <= Amin) { + return SDL_FALSE; + } + /* Vertical intersection */ + Amin = A->y; + Amax = Amin + A->h; + Bmin = B->y; + Bmax = Bmin + B->h; + if (Bmin > Amin) { + Amin = Bmin; + } + if (Bmax < Amax) { + Amax = Bmax; + } + if (Amax <= Amin) { + return SDL_FALSE; + } + return SDL_TRUE; +} + +SDL_bool +SDL_INTERSECTRECT(const RECTTYPE * A, const RECTTYPE * B, RECTTYPE * result) +{ + SCALARTYPE Amin, Amax, Bmin, Bmax; + + if (!A) { + SDL_InvalidParamError("A"); + return SDL_FALSE; + } else if (!B) { + SDL_InvalidParamError("B"); + return SDL_FALSE; + } else if (!result) { + SDL_InvalidParamError("result"); + return SDL_FALSE; + } else if (SDL_RECTEMPTY(A) || SDL_RECTEMPTY(B)) { /* Special cases for empty rects */ + result->w = 0; + result->h = 0; + return SDL_FALSE; + } + + /* Horizontal intersection */ + Amin = A->x; + Amax = Amin + A->w; + Bmin = B->x; + Bmax = Bmin + B->w; + if (Bmin > Amin) { + Amin = Bmin; + } + result->x = Amin; + if (Bmax < Amax) { + Amax = Bmax; + } + result->w = Amax - Amin; + + /* Vertical intersection */ + Amin = A->y; + Amax = Amin + A->h; + Bmin = B->y; + Bmax = Bmin + B->h; + if (Bmin > Amin) { + Amin = Bmin; + } + result->y = Amin; + if (Bmax < Amax) { + Amax = Bmax; + } + result->h = Amax - Amin; + + return !SDL_RECTEMPTY(result); +} + +void +SDL_UNIONRECT(const RECTTYPE * A, const RECTTYPE * B, RECTTYPE * result) +{ + SCALARTYPE Amin, Amax, Bmin, Bmax; + + if (!A) { + SDL_InvalidParamError("A"); + return; + } else if (!B) { + SDL_InvalidParamError("B"); + return; + } else if (!result) { + SDL_InvalidParamError("result"); + return; + } else if (SDL_RECTEMPTY(A)) { /* Special cases for empty Rects */ + if (SDL_RECTEMPTY(B)) { /* A and B empty */ + SDL_zerop(result); + } else { /* A empty, B not empty */ + *result = *B; + } + return; + } else if (SDL_RECTEMPTY(B)) { /* A not empty, B empty */ + *result = *A; + return; + } + + /* Horizontal union */ + Amin = A->x; + Amax = Amin + A->w; + Bmin = B->x; + Bmax = Bmin + B->w; + if (Bmin < Amin) { + Amin = Bmin; + } + result->x = Amin; + if (Bmax > Amax) { + Amax = Bmax; + } + result->w = Amax - Amin; + + /* Vertical union */ + Amin = A->y; + Amax = Amin + A->h; + Bmin = B->y; + Bmax = Bmin + B->h; + if (Bmin < Amin) { + Amin = Bmin; + } + result->y = Amin; + if (Bmax > Amax) { + Amax = Bmax; + } + result->h = Amax - Amin; +} + +SDL_bool SDL_ENCLOSEPOINTS(const POINTTYPE * points, int count, const RECTTYPE * clip, + RECTTYPE * result) +{ + SCALARTYPE minx = 0; + SCALARTYPE miny = 0; + SCALARTYPE maxx = 0; + SCALARTYPE maxy = 0; + SCALARTYPE x, y; + int i; + + if (!points) { + SDL_InvalidParamError("points"); + return SDL_FALSE; + } else if (count < 1) { + SDL_InvalidParamError("count"); + return SDL_FALSE; + } + + if (clip) { + SDL_bool added = SDL_FALSE; + const SCALARTYPE clip_minx = clip->x; + const SCALARTYPE clip_miny = clip->y; + const SCALARTYPE clip_maxx = clip->x+clip->w-1; + const SCALARTYPE clip_maxy = clip->y+clip->h-1; + + /* Special case for empty rectangle */ + if (SDL_RECTEMPTY(clip)) { + return SDL_FALSE; + } + + for (i = 0; i < count; ++i) { + x = points[i].x; + y = points[i].y; + + if (x < clip_minx || x > clip_maxx || + y < clip_miny || y > clip_maxy) { + continue; + } + if (!added) { + /* Special case: if no result was requested, we are done */ + if (result == NULL) { + return SDL_TRUE; + } + + /* First point added */ + minx = maxx = x; + miny = maxy = y; + added = SDL_TRUE; + continue; + } + if (x < minx) { + minx = x; + } else if (x > maxx) { + maxx = x; + } + if (y < miny) { + miny = y; + } else if (y > maxy) { + maxy = y; + } + } + if (!added) { + return SDL_FALSE; + } + } else { + /* Special case: if no result was requested, we are done */ + if (result == NULL) { + return SDL_TRUE; + } + + /* No clipping, always add the first point */ + minx = maxx = points[0].x; + miny = maxy = points[0].y; + + for (i = 1; i < count; ++i) { + x = points[i].x; + y = points[i].y; + + if (x < minx) { + minx = x; + } else if (x > maxx) { + maxx = x; + } + if (y < miny) { + miny = y; + } else if (y > maxy) { + maxy = y; + } + } + } + + if (result) { + result->x = minx; + result->y = miny; + result->w = (maxx-minx)+1; + result->h = (maxy-miny)+1; + } + return SDL_TRUE; +} + +/* Use the Cohen-Sutherland algorithm for line clipping */ +static int +COMPUTEOUTCODE(const RECTTYPE * rect, SCALARTYPE x, SCALARTYPE y) +{ + int code = 0; + if (y < rect->y) { + code |= CODE_TOP; + } else if (y >= rect->y + rect->h) { + code |= CODE_BOTTOM; + } + if (x < rect->x) { + code |= CODE_LEFT; + } else if (x >= rect->x + rect->w) { + code |= CODE_RIGHT; + } + return code; +} + +SDL_bool +SDL_INTERSECTRECTANDLINE(const RECTTYPE * rect, SCALARTYPE *X1, SCALARTYPE *Y1, SCALARTYPE *X2, + SCALARTYPE *Y2) +{ + SCALARTYPE x = 0; + SCALARTYPE y = 0; + SCALARTYPE x1, y1; + SCALARTYPE x2, y2; + SCALARTYPE rectx1; + SCALARTYPE recty1; + SCALARTYPE rectx2; + SCALARTYPE recty2; + int outcode1, outcode2; + + if (!rect) { + SDL_InvalidParamError("rect"); + return SDL_FALSE; + } else if (!X1) { + SDL_InvalidParamError("X1"); + return SDL_FALSE; + } else if (!Y1) { + SDL_InvalidParamError("Y1"); + return SDL_FALSE; + } else if (!X2) { + SDL_InvalidParamError("X2"); + return SDL_FALSE; + } else if (!Y2) { + SDL_InvalidParamError("Y2"); + return SDL_FALSE; + } else if (SDL_RECTEMPTY(rect)) { + return SDL_FALSE; /* Special case for empty rect */ + } + + x1 = *X1; + y1 = *Y1; + x2 = *X2; + y2 = *Y2; + rectx1 = rect->x; + recty1 = rect->y; + rectx2 = rect->x + rect->w - 1; + recty2 = rect->y + rect->h - 1; + + /* Check to see if entire line is inside rect */ + if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 && + y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) { + return SDL_TRUE; + } + + /* Check to see if entire line is to one side of rect */ + if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) || + (y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) { + return SDL_FALSE; + } + + if (y1 == y2) { /* Horizontal line, easy to clip */ + if (x1 < rectx1) { + *X1 = rectx1; + } else if (x1 > rectx2) { + *X1 = rectx2; + } + if (x2 < rectx1) { + *X2 = rectx1; + } else if (x2 > rectx2) { + *X2 = rectx2; + } + return SDL_TRUE; + } + + if (x1 == x2) { /* Vertical line, easy to clip */ + if (y1 < recty1) { + *Y1 = recty1; + } else if (y1 > recty2) { + *Y1 = recty2; + } + if (y2 < recty1) { + *Y2 = recty1; + } else if (y2 > recty2) { + *Y2 = recty2; + } + return SDL_TRUE; + } + + /* More complicated Cohen-Sutherland algorithm */ + outcode1 = COMPUTEOUTCODE(rect, x1, y1); + outcode2 = COMPUTEOUTCODE(rect, x2, y2); + while (outcode1 || outcode2) { + if (outcode1 & outcode2) { + return SDL_FALSE; + } + + if (outcode1) { + if (outcode1 & CODE_TOP) { + y = recty1; + x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); + } else if (outcode1 & CODE_BOTTOM) { + y = recty2; + x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); + } else if (outcode1 & CODE_LEFT) { + x = rectx1; + y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); + } else if (outcode1 & CODE_RIGHT) { + x = rectx2; + y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); + } + x1 = x; + y1 = y; + outcode1 = COMPUTEOUTCODE(rect, x, y); + } else { + if (outcode2 & CODE_TOP) { + y = recty1; + x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); + } else if (outcode2 & CODE_BOTTOM) { + y = recty2; + x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); + } else if (outcode2 & CODE_LEFT) { + /* If this assertion ever fires, here's the static analysis that warned about it: + http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-b0d01a.html#EndPath */ + SDL_assert(x2 != x1); /* if equal: division by zero. */ + x = rectx1; + y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); + } else if (outcode2 & CODE_RIGHT) { + /* If this assertion ever fires, here's the static analysis that warned about it: + http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-39b114.html#EndPath */ + SDL_assert(x2 != x1); /* if equal: division by zero. */ + x = rectx2; + y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); + } + x2 = x; + y2 = y; + outcode2 = COMPUTEOUTCODE(rect, x, y); + } + } + *X1 = x1; + *Y1 = y1; + *X2 = x2; + *Y2 = y2; + return SDL_TRUE; +} + +#undef RECTTYPE +#undef POINTTYPE +#undef SCALARTYPE +#undef COMPUTEOUTCODE +#undef SDL_HASINTERSECTION +#undef SDL_INTERSECTRECT +#undef SDL_RECTEMPTY +#undef SDL_UNIONRECT +#undef SDL_ENCLOSEPOINTS +#undef SDL_INTERSECTRECTANDLINE + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/SDL_shape.c b/Engine/lib/sdl/src/video/SDL_shape.c index 5c174bf16..919ae9598 100644 --- a/Engine/lib/sdl/src/video/SDL_shape.c +++ b/Engine/lib/sdl/src/video/SDL_shape.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/SDL_shape_internals.h b/Engine/lib/sdl/src/video/SDL_shape_internals.h index a93dfa079..16d659ef1 100644 --- a/Engine/lib/sdl/src/video/SDL_shape_internals.h +++ b/Engine/lib/sdl/src/video/SDL_shape_internals.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/SDL_stretch.c b/Engine/lib/sdl/src/video/SDL_stretch.c index 475373166..bc7b4e551 100644 --- a/Engine/lib/sdl/src/video/SDL_stretch.c +++ b/Engine/lib/sdl/src/video/SDL_stretch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,210 +20,48 @@ */ #include "../SDL_internal.h" -/* This a stretch blit implementation based on ideas given to me by - Tomasz Cejner - thanks! :) - - April 27, 2000 - Sam Lantinga -*/ - #include "SDL_video.h" #include "SDL_blit.h" +#include "SDL_render.h" -/* This isn't ready for general consumption yet - it should be folded - into the general blitting mechanism. -*/ +static int SDL_LowerSoftStretchNearest(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect); +static int SDL_LowerSoftStretchLinear(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect); +static int SDL_UpperSoftStretch(SDL_Surface * src, const SDL_Rect * srcrect, SDL_Surface * dst, const SDL_Rect * dstrect, SDL_ScaleMode scaleMode); -#if ((defined(_MSC_VER) && defined(_M_IX86)) || \ - (defined(__WATCOMC__) && defined(__386__)) || \ - (defined(__GNUC__) && defined(__i386__))) && SDL_ASSEMBLY_ROUTINES -/* There's a bug with gcc 4.4.1 and -O2 where srcp doesn't get the correct - * value after the first scanline. FIXME? */ -/* #define USE_ASM_STRETCH */ -#endif +int +SDL_SoftStretch(SDL_Surface *src, const SDL_Rect *srcrect, + SDL_Surface *dst, const SDL_Rect *dstrect) +{ + return SDL_UpperSoftStretch(src, srcrect, dst, dstrect, SDL_ScaleModeNearest); +} -#ifdef USE_ASM_STRETCH - -#ifdef HAVE_MPROTECT -#include -#include -#endif -#ifdef __GNUC__ -#define PAGE_ALIGNED __attribute__((__aligned__(4096))) -#else -#define PAGE_ALIGNED -#endif - -#if defined(_M_IX86) || defined(__i386__) || defined(__386__) -#define PREFIX16 0x66 -#define STORE_BYTE 0xAA -#define STORE_WORD 0xAB -#define LOAD_BYTE 0xAC -#define LOAD_WORD 0xAD -#define RETURN 0xC3 -#else -#error Need assembly opcodes for this architecture -#endif - -static unsigned char copy_row[4096] PAGE_ALIGNED; +int +SDL_SoftStretchLinear(SDL_Surface *src, const SDL_Rect *srcrect, + SDL_Surface *dst, const SDL_Rect *dstrect) +{ + return SDL_UpperSoftStretch(src, srcrect, dst, dstrect, SDL_ScaleModeLinear); +} static int -generate_rowbytes(int src_w, int dst_w, int bpp) -{ - static struct - { - int bpp; - int src_w; - int dst_w; - int status; - } last; - - int i; - int pos, inc; - unsigned char *eip, *fence; - unsigned char load, store; - - /* See if we need to regenerate the copy buffer */ - if ((src_w == last.src_w) && (dst_w == last.dst_w) && (bpp == last.bpp)) { - return (last.status); - } - last.bpp = bpp; - last.src_w = src_w; - last.dst_w = dst_w; - last.status = -1; - - switch (bpp) { - case 1: - load = LOAD_BYTE; - store = STORE_BYTE; - break; - case 2: - case 4: - load = LOAD_WORD; - store = STORE_WORD; - break; - default: - return SDL_SetError("ASM stretch of %d bytes isn't supported", bpp); - } -#ifdef HAVE_MPROTECT - /* Make the code writeable */ - if (mprotect(copy_row, sizeof(copy_row), PROT_READ | PROT_WRITE) < 0) { - return SDL_SetError("Couldn't make copy buffer writeable"); - } -#endif - pos = 0x10000; - inc = (src_w << 16) / dst_w; - eip = copy_row; - fence = copy_row + sizeof(copy_row)-2; - for (i = 0; i < dst_w; ++i) { - while (pos >= 0x10000L) { - if (eip == fence) { - return -1; - } - if (bpp == 2) { - *eip++ = PREFIX16; - } - *eip++ = load; - pos -= 0x10000L; - } - if (eip == fence) { - return -1; - } - if (bpp == 2) { - *eip++ = PREFIX16; - } - *eip++ = store; - pos += inc; - } - *eip++ = RETURN; - -#ifdef HAVE_MPROTECT - /* Make the code executable but not writeable */ - if (mprotect(copy_row, sizeof(copy_row), PROT_READ | PROT_EXEC) < 0) { - return SDL_SetError("Couldn't make copy buffer executable"); - } -#endif - last.status = 0; - return (0); -} - -#endif /* USE_ASM_STRETCH */ - -#define DEFINE_COPY_ROW(name, type) \ -static void name(type *src, int src_w, type *dst, int dst_w) \ -{ \ - int i; \ - int pos, inc; \ - type pixel = 0; \ - \ - pos = 0x10000; \ - inc = (src_w << 16) / dst_w; \ - for ( i=dst_w; i>0; --i ) { \ - while ( pos >= 0x10000L ) { \ - pixel = *src++; \ - pos -= 0x10000L; \ - } \ - *dst++ = pixel; \ - pos += inc; \ - } \ -} -/* *INDENT-OFF* */ -DEFINE_COPY_ROW(copy_row1, Uint8) -DEFINE_COPY_ROW(copy_row2, Uint16) -DEFINE_COPY_ROW(copy_row4, Uint32) -/* *INDENT-ON* */ - -/* The ASM code doesn't handle 24-bpp stretch blits */ -static void -copy_row3(Uint8 * src, int src_w, Uint8 * dst, int dst_w) -{ - int i; - int pos, inc; - Uint8 pixel[3] = { 0, 0, 0 }; - - pos = 0x10000; - inc = (src_w << 16) / dst_w; - for (i = dst_w; i > 0; --i) { - while (pos >= 0x10000L) { - pixel[0] = *src++; - pixel[1] = *src++; - pixel[2] = *src++; - pos -= 0x10000L; - } - *dst++ = pixel[0]; - *dst++ = pixel[1]; - *dst++ = pixel[2]; - pos += inc; - } -} - -/* Perform a stretch blit between two surfaces of the same format. - NOTE: This function is not safe to call from multiple threads! -*/ -int -SDL_SoftStretch(SDL_Surface * src, const SDL_Rect * srcrect, - SDL_Surface * dst, const SDL_Rect * dstrect) +SDL_UpperSoftStretch(SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, const SDL_Rect * dstrect, SDL_ScaleMode scaleMode) { + int ret; int src_locked; int dst_locked; - int pos, inc; - int dst_maxrow; - int src_row, dst_row; - Uint8 *srcp = NULL; - Uint8 *dstp; SDL_Rect full_src; SDL_Rect full_dst; -#ifdef USE_ASM_STRETCH - SDL_bool use_asm = SDL_TRUE; -#ifdef __GNUC__ - int u1, u2; -#endif -#endif /* USE_ASM_STRETCH */ - const int bpp = dst->format->BytesPerPixel; if (src->format->format != dst->format->format) { return SDL_SetError("Only works with same format surfaces"); } + if (scaleMode != SDL_ScaleModeNearest) { + if (src->format->BytesPerPixel != 4 || src->format->format == SDL_PIXELFORMAT_ARGB2101010) { + return SDL_SetError("Wrong format"); + } + } + /* Verify the blit rectangles */ if (srcrect) { if ((srcrect->x < 0) || (srcrect->y < 0) || @@ -252,6 +90,15 @@ SDL_SoftStretch(SDL_Surface * src, const SDL_Rect * srcrect, dstrect = &full_dst; } + if (dstrect->w <= 0 || dstrect->h <= 0) { + return 0; + } + + if (srcrect->w > SDL_MAX_UINT16 || srcrect->h > SDL_MAX_UINT16 || + dstrect->w > SDL_MAX_UINT16 || dstrect->h > SDL_MAX_UINT16) { + return SDL_SetError("Size too large for scaling"); + } + /* Lock the destination if it's in hardware */ dst_locked = 0; if (SDL_MUSTLOCK(dst)) { @@ -272,72 +119,10 @@ SDL_SoftStretch(SDL_Surface * src, const SDL_Rect * srcrect, src_locked = 1; } - /* Set up the data... */ - pos = 0x10000; - inc = (srcrect->h << 16) / dstrect->h; - src_row = srcrect->y; - dst_row = dstrect->y; - -#ifdef USE_ASM_STRETCH - /* Write the opcodes for this stretch */ - if ((bpp == 3) || (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0)) { - use_asm = SDL_FALSE; - } -#endif - - /* Perform the stretch blit */ - for (dst_maxrow = dst_row + dstrect->h; dst_row < dst_maxrow; ++dst_row) { - dstp = (Uint8 *) dst->pixels + (dst_row * dst->pitch) - + (dstrect->x * bpp); - while (pos >= 0x10000L) { - srcp = (Uint8 *) src->pixels + (src_row * src->pitch) - + (srcrect->x * bpp); - ++src_row; - pos -= 0x10000L; - } -#ifdef USE_ASM_STRETCH - if (use_asm) { -#ifdef __GNUC__ - __asm__ __volatile__("call *%4":"=&D"(u1), "=&S"(u2) - :"0"(dstp), "1"(srcp), "r"(copy_row) - :"memory"); -#elif defined(_MSC_VER) || defined(__WATCOMC__) - /* *INDENT-OFF* */ - { - void *code = copy_row; - __asm { - push edi - push esi - mov edi, dstp - mov esi, srcp - call dword ptr code - pop esi - pop edi - } - } - /* *INDENT-ON* */ -#else -#error Need inline assembly for this compiler -#endif - } else -#endif - switch (bpp) { - case 1: - copy_row1(srcp, srcrect->w, dstp, dstrect->w); - break; - case 2: - copy_row2((Uint16 *) srcp, srcrect->w, - (Uint16 *) dstp, dstrect->w); - break; - case 3: - copy_row3(srcp, srcrect->w, dstp, dstrect->w); - break; - case 4: - copy_row4((Uint32 *) srcp, srcrect->w, - (Uint32 *) dstp, dstrect->w); - break; - } - pos += inc; + if (scaleMode == SDL_ScaleModeNearest) { + ret = SDL_LowerSoftStretchNearest(src, srcrect, dst, dstrect); + } else { + ret = SDL_LowerSoftStretchLinear(src, srcrect, dst, dstrect); } /* We need to unlock the surfaces if they're locked */ @@ -347,7 +132,852 @@ SDL_SoftStretch(SDL_Surface * src, const SDL_Rect * srcrect, if (src_locked) { SDL_UnlockSurface(src); } - return (0); + + return ret; +} + +/* bilinear interpolation precision must be < 8 + Because with SSE: add-multiply: _mm_madd_epi16 works with signed int + so pixels 0xb1...... are negatives and false the result + same in NEON probably */ +#define PRECISION 7 + +#define FIXED_POINT(i) ((Uint32)(i) << 16) +#define SRC_INDEX(fp) ((Uint32)(fp) >> 16) +#define INTEGER(fp) ((Uint32)(fp) >> PRECISION) +#define FRAC(fp) ((Uint32)(fp >> (16 - PRECISION)) & ((1< dst_h - 1 - right_pad_h); \ + index_h = SRC_INDEX(fp_sum_h); \ + frac_h0 = FRAC(fp_sum_h); \ + \ + index_h = no_padding ? index_h : (i < left_pad_h ? 0 : src_h - 1); \ + frac_h0 = no_padding ? frac_h0 : 0; \ + incr_h1 = no_padding ? src_pitch : 0; \ + incr_h0 = index_h * src_pitch; \ + \ + src_h0 = (const Uint32 *)((const Uint8 *)src + incr_h0); \ + src_h1 = (const Uint32 *)((const Uint8 *)src_h0 + incr_h1); \ + \ + fp_sum_h += fp_step_h; \ + \ + frac_h1 = FRAC_ONE - frac_h0; \ + fp_sum_w = fp_sum_w_init; \ + right_pad_w = right_pad_w_init; \ + left_pad_w = left_pad_w_init; \ + middle = middle_init; \ + + + +#if defined(__clang__) +// Remove inlining of this function +// Compiler crash with clang 9.0.8 / android-ndk-r21d +// Compiler crash with clang 11.0.3 / Xcode +// OK with clang 11.0.5 / android-ndk-22 +// OK with clang 12.0.0 / Xcode +__attribute__((noinline)) +#endif +static void +get_scaler_datas(int src_nb, int dst_nb, int *fp_start, int *fp_step, int *left_pad, int *right_pad) +{ + + int step = FIXED_POINT(src_nb) / (dst_nb); /* source step in fixed point */ + int x0 = FP_ONE / 2; /* dst first pixel center at 0.5 in fixed point */ + int fp_sum; + int i; +#if 0 + /* scale to source coordinates */ + x0 *= src_nb; + x0 /= dst_nb; /* x0 == step / 2 */ +#else + /* Use this code for perfect match with pixman */ + Sint64 tmp[2]; + tmp[0] = (Sint64)step * (x0 >> 16); + tmp[1] = (Sint64)step * (x0 & 0xFFFF); + x0 = (int) (tmp[0] + ((tmp[1] + 0x8000) >> 16)); /* x0 == (step + 1) / 2 */ +#endif + /* -= 0.5, get back the pixel origin, in source coordinates */ + x0 -= FP_ONE / 2; + + *fp_start = x0; + *fp_step = step; + *left_pad = 0; + *right_pad = 0; + + fp_sum = x0; + for (i = 0; i < dst_nb; i++) { + if (fp_sum < 0) { + *left_pad += 1; + } else { + int index = SRC_INDEX(fp_sum); + if (index > src_nb - 2) { + *right_pad += 1; + } + } + fp_sum += step; + } +// SDL_Log("%d -> %d x0=%d step=%d left_pad=%d right_pad=%d", src_nb, dst_nb, *fp_start, *fp_step, *left_pad, *right_pad); +} + +typedef struct color_t { + Uint8 a; + Uint8 b; + Uint8 c; + Uint8 d; +} color_t; + +#if 0 +static void +printf_64(const char *str, void *var) +{ + uint8_t *val = (uint8_t*) var; + printf(" * %s: %02x %02x %02x %02x _ %02x %02x %02x %02x\n", + str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]); +} +#endif + +/* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ + +static SDL_INLINE void +INTERPOL(const Uint32 *src_x0, const Uint32 *src_x1, int frac0, int frac1, Uint32 *dst) +{ + const color_t *c0 = (const color_t *)src_x0; + const color_t *c1 = (const color_t *)src_x1; + color_t *cx = (color_t *)dst; +#if 0 + cx->a = c0->a + INTEGER(frac0 * (c1->a - c0->a)); + cx->b = c0->b + INTEGER(frac0 * (c1->b - c0->b)); + cx->c = c0->c + INTEGER(frac0 * (c1->c - c0->c)); + cx->d = c0->d + INTEGER(frac0 * (c1->d - c0->d)); +#else + cx->a = INTEGER(frac1 * c0->a + frac0 * c1->a); + cx->b = INTEGER(frac1 * c0->b + frac0 * c1->b); + cx->c = INTEGER(frac1 * c0->c + frac0 * c1->c); + cx->d = INTEGER(frac1 * c0->d + frac0 * c1->d); +#endif +} + +static SDL_INLINE void +INTERPOL_BILINEAR(const Uint32 *s0, const Uint32 *s1, int frac_w0, int frac_h0, int frac_h1, Uint32 *dst) +{ + Uint32 tmp[2]; + unsigned int frac_w1 = FRAC_ONE - frac_w0; + + /* Vertical first, store to 'tmp' */ + INTERPOL(s0, s1, frac_h0, frac_h1, tmp); + INTERPOL(s0 + 1, s1 + 1, frac_h0, frac_h1, tmp + 1); + + /* Horizontal, store to 'dst' */ + INTERPOL(tmp, tmp + 1, frac_w0, frac_w1, dst); +} + +static int +scale_mat(const Uint32 *src, int src_w, int src_h, int src_pitch, + Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + BILINEAR___START + + for (i = 0; i < dst_h; i++) { + + BILINEAR___HEIGHT + + while (left_pad_w--) { + INTERPOL_BILINEAR(src_h0, src_h1, FRAC_ZERO, frac_h0, frac_h1, dst); + dst += 1; + } + + while (middle--) { + const Uint32 *s_00_01; + const Uint32 *s_10_11; + int index_w = 4 * SRC_INDEX(fp_sum_w); + int frac_w = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + +/* + x00 ... x0_ ..... x01 + . . . + . x . + . . . + . . . + x10 ... x1_ ..... x11 +*/ + s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + + INTERPOL_BILINEAR(s_00_01, s_10_11, frac_w, frac_h0, frac_h1, dst); + + dst += 1; + } + + while (right_pad_w--) { + int index_w = 4 * (src_w - 2); + const Uint32 *s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + const Uint32 *s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + INTERPOL_BILINEAR(s_00_01, s_10_11, FRAC_ONE, frac_h0, frac_h1, dst); + dst += 1; + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} + +#if defined(__SSE2__) +# define HAVE_SSE2_INTRINSICS 1 +#endif + +#if defined(__ARM_NEON) +# define HAVE_NEON_INTRINSICS 1 +# define CAST_uint8x8_t (uint8x8_t) +# define CAST_uint32x2_t (uint32x2_t) +#endif + +#if defined(__WINRT__) || defined(_MSC_VER) +# if defined(HAVE_NEON_INTRINSICS) +# undef CAST_uint8x8_t +# undef CAST_uint32x2_t +# define CAST_uint8x8_t +# define CAST_uint32x2_t +# endif +#endif + +#if defined(HAVE_SSE2_INTRINSICS) + +#if 0 +static void +printf_128(const char *str, __m128i var) +{ + uint16_t *val = (uint16_t*) &var; + printf(" * %s: %04x %04x %04x %04x _ %04x %04x %04x %04x\n", + str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]); +} +#endif + +static SDL_INLINE int +hasSSE2() +{ + static int val = -1; + if (val != -1) { + return val; + } + val = SDL_HasSSE2(); + return val; +} + +static SDL_INLINE void +INTERPOL_BILINEAR_SSE(const Uint32 *s0, const Uint32 *s1, int frac_w, __m128i v_frac_h0, __m128i v_frac_h1, Uint32 *dst, __m128i zero) +{ + __m128i x_00_01, x_10_11; /* Pixels in 4*uint8 in row */ + __m128i v_frac_w0, k0, l0, d0, e0; + + int f, f2; + f = frac_w; + f2 = FRAC_ONE - frac_w; + v_frac_w0 = _mm_set_epi16(f, f2, f, f2, f, f2, f, f2); + + + x_00_01 = _mm_loadl_epi64((const __m128i *)s0); /* Load x00 and x01 */ + x_10_11 = _mm_loadl_epi64((const __m128i *)s1); + + /* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ + + /* Interpolation vertical */ + k0 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_00_01, zero), v_frac_h1); + l0 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_10_11, zero), v_frac_h0); + k0 = _mm_add_epi16(k0, l0); + + /* For perfect match, clear the factionnal part eventually. */ + /* + k0 = _mm_srli_epi16(k0, PRECISION); + k0 = _mm_slli_epi16(k0, PRECISION); + */ + + /* Interpolation horizontal */ + l0 = _mm_unpacklo_epi64(/* unused */ l0, k0); + k0 = _mm_madd_epi16(_mm_unpackhi_epi16(l0, k0), v_frac_w0); + + /* Store 1 pixel */ + d0 = _mm_srli_epi32(k0, PRECISION * 2); + e0 = _mm_packs_epi32(d0, d0); + e0 = _mm_packus_epi16(e0, e0); + *dst = _mm_cvtsi128_si32(e0); +} + +static int +scale_mat_SSE(const Uint32 *src, int src_w, int src_h, int src_pitch, Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + BILINEAR___START + + for (i = 0; i < dst_h; i++) { + int nb_block2; + __m128i v_frac_h0; + __m128i v_frac_h1; + __m128i zero; + + BILINEAR___HEIGHT + + nb_block2 = middle / 2; + + v_frac_h0 = _mm_set_epi16(frac_h0, frac_h0, frac_h0, frac_h0, frac_h0, frac_h0, frac_h0, frac_h0); + v_frac_h1 = _mm_set_epi16(frac_h1, frac_h1, frac_h1, frac_h1, frac_h1, frac_h1, frac_h1, frac_h1); + zero = _mm_setzero_si128(); + + while (left_pad_w--) { + INTERPOL_BILINEAR_SSE(src_h0, src_h1, FRAC_ZERO, v_frac_h0, v_frac_h1, dst, zero); + dst += 1; + } + + while (nb_block2--) { + int index_w_0, frac_w_0; + int index_w_1, frac_w_1; + + const Uint32 *s_00_01, *s_02_03, *s_10_11, *s_12_13; + + __m128i x_00_01, x_10_11, x_02_03, x_12_13;/* Pixels in 4*uint8 in row */ + __m128i v_frac_w0, k0, l0, d0, e0; + __m128i v_frac_w1, k1, l1, d1, e1; + + int f, f2; + index_w_0 = 4 * SRC_INDEX(fp_sum_w); + frac_w_0 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + index_w_1 = 4 * SRC_INDEX(fp_sum_w); + frac_w_1 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; +/* + x00............ x01 x02...........x03 + . . . . . . + j0 f0 j1 j2 f1 j3 + . . . . . . + . . . . . . + . . . . . . + x10............ x11 x12...........x13 + */ + s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_0); + s_02_03 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_1); + s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_0); + s_12_13 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_1); + + f = frac_w_0; + f2 = FRAC_ONE - frac_w_0; + v_frac_w0 = _mm_set_epi16(f, f2, f, f2, f, f2, f, f2); + + f = frac_w_1; + f2 = FRAC_ONE - frac_w_1; + v_frac_w1 = _mm_set_epi16(f, f2, f, f2, f, f2, f, f2); + + x_00_01 = _mm_loadl_epi64((const __m128i *)s_00_01); /* Load x00 and x01 */ + x_02_03 = _mm_loadl_epi64((const __m128i *)s_02_03); + x_10_11 = _mm_loadl_epi64((const __m128i *)s_10_11); + x_12_13 = _mm_loadl_epi64((const __m128i *)s_12_13); + + /* Interpolation vertical */ + k0 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_00_01, zero), v_frac_h1); + l0 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_10_11, zero), v_frac_h0); + k0 = _mm_add_epi16(k0, l0); + k1 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_02_03, zero), v_frac_h1); + l1 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_12_13, zero), v_frac_h0); + k1 = _mm_add_epi16(k1, l1); + + /* Interpolation horizontal */ + l0 = _mm_unpacklo_epi64(/* unused */ l0, k0); + k0 = _mm_madd_epi16(_mm_unpackhi_epi16(l0, k0), v_frac_w0); + l1 = _mm_unpacklo_epi64(/* unused */ l1, k1); + k1 = _mm_madd_epi16(_mm_unpackhi_epi16(l1, k1), v_frac_w1); + + /* Store 1 pixel */ + d0 = _mm_srli_epi32(k0, PRECISION * 2); + e0 = _mm_packs_epi32(d0, d0); + e0 = _mm_packus_epi16(e0, e0); + *dst++ = _mm_cvtsi128_si32(e0); + + /* Store 1 pixel */ + d1 = _mm_srli_epi32(k1, PRECISION * 2); + e1 = _mm_packs_epi32(d1, d1); + e1 = _mm_packus_epi16(e1, e1); + *dst++ = _mm_cvtsi128_si32(e1); + } + + /* Last point */ + if (middle & 0x1) { + const Uint32 *s_00_01; + const Uint32 *s_10_11; + int index_w = 4 * SRC_INDEX(fp_sum_w); + int frac_w = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + INTERPOL_BILINEAR_SSE(s_00_01, s_10_11, frac_w, v_frac_h0, v_frac_h1, dst, zero); + dst += 1; + } + + while (right_pad_w--) { + int index_w = 4 * (src_w - 2); + const Uint32 *s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + const Uint32 *s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + INTERPOL_BILINEAR_SSE(s_00_01, s_10_11, FRAC_ONE, v_frac_h0, v_frac_h1, dst, zero); + dst += 1; + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} +#endif + +#if defined(HAVE_NEON_INTRINSICS) + +static SDL_INLINE int +hasNEON() +{ + static int val = -1; + if (val != -1) { + return val; + } + val = SDL_HasNEON(); + return val; +} + +static SDL_INLINE void +INTERPOL_BILINEAR_NEON(const Uint32 *s0, const Uint32 *s1, int frac_w, uint8x8_t v_frac_h0, uint8x8_t v_frac_h1, Uint32 *dst) +{ + uint8x8_t x_00_01, x_10_11; /* Pixels in 4*uint8 in row */ + uint16x8_t k0; + uint32x4_t l0; + uint16x8_t d0; + uint8x8_t e0; + + x_00_01 = CAST_uint8x8_t vld1_u32(s0); /* Load 2 pixels */ + x_10_11 = CAST_uint8x8_t vld1_u32(s1); + + /* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ + k0 = vmull_u8(x_00_01, v_frac_h1); /* k0 := x0 * (1 - frac) */ + k0 = vmlal_u8(k0, x_10_11, v_frac_h0); /* k0 += x1 * frac */ + + /* k0 now contains 2 interpolated pixels { j0, j1 } */ + l0 = vshll_n_u16(vget_low_u16(k0), PRECISION); + l0 = vmlsl_n_u16(l0, vget_low_u16(k0), frac_w); + l0 = vmlal_n_u16(l0, vget_high_u16(k0), frac_w); + + /* Shift and narrow */ + d0 = vcombine_u16( + /* uint16x4_t */ vshrn_n_u32(l0, 2 * PRECISION), + /* uint16x4_t */ vshrn_n_u32(l0, 2 * PRECISION) + ); + + /* Narrow again */ + e0 = vmovn_u16(d0); + + /* Store 1 pixel */ + *dst = vget_lane_u32(CAST_uint32x2_t e0, 0); +} + + static int +scale_mat_NEON(const Uint32 *src, int src_w, int src_h, int src_pitch, Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + BILINEAR___START + + for (i = 0; i < dst_h; i++) { + int nb_block4; + uint8x8_t v_frac_h0, v_frac_h1; + + BILINEAR___HEIGHT + + nb_block4 = middle / 4; + + v_frac_h0 = vmov_n_u8(frac_h0); + v_frac_h1 = vmov_n_u8(frac_h1); + + while (left_pad_w--) { + INTERPOL_BILINEAR_NEON(src_h0, src_h1, FRAC_ZERO, v_frac_h0, v_frac_h1, dst); + dst += 1; + } + + while (nb_block4--) { + int index_w_0, frac_w_0; + int index_w_1, frac_w_1; + int index_w_2, frac_w_2; + int index_w_3, frac_w_3; + + const Uint32 *s_00_01, *s_02_03, *s_04_05, *s_06_07; + const Uint32 *s_10_11, *s_12_13, *s_14_15, *s_16_17; + + uint8x8_t x_00_01, x_10_11, x_02_03, x_12_13;/* Pixels in 4*uint8 in row */ + uint8x8_t x_04_05, x_14_15, x_06_07, x_16_17; + + uint16x8_t k0, k1, k2, k3; + uint32x4_t l0, l1, l2, l3; + uint16x8_t d0, d1; + uint8x8_t e0, e1; + uint32x4_t f0; + + index_w_0 = 4 * SRC_INDEX(fp_sum_w); + frac_w_0 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + index_w_1 = 4 * SRC_INDEX(fp_sum_w); + frac_w_1 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + index_w_2 = 4 * SRC_INDEX(fp_sum_w); + frac_w_2 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + index_w_3 = 4 * SRC_INDEX(fp_sum_w); + frac_w_3 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + + s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_0); + s_02_03 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_1); + s_04_05 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_2); + s_06_07 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_3); + s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_0); + s_12_13 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_1); + s_14_15 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_2); + s_16_17 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_3); + + /* Interpolation vertical */ + x_00_01 = CAST_uint8x8_t vld1_u32(s_00_01); /* Load 2 pixels */ + x_02_03 = CAST_uint8x8_t vld1_u32(s_02_03); + x_04_05 = CAST_uint8x8_t vld1_u32(s_04_05); + x_06_07 = CAST_uint8x8_t vld1_u32(s_06_07); + x_10_11 = CAST_uint8x8_t vld1_u32(s_10_11); + x_12_13 = CAST_uint8x8_t vld1_u32(s_12_13); + x_14_15 = CAST_uint8x8_t vld1_u32(s_14_15); + x_16_17 = CAST_uint8x8_t vld1_u32(s_16_17); + + /* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ + k0 = vmull_u8(x_00_01, v_frac_h1); /* k0 := x0 * (1 - frac) */ + k0 = vmlal_u8(k0, x_10_11, v_frac_h0); /* k0 += x1 * frac */ + + k1 = vmull_u8(x_02_03, v_frac_h1); + k1 = vmlal_u8(k1, x_12_13, v_frac_h0); + + k2 = vmull_u8(x_04_05, v_frac_h1); + k2 = vmlal_u8(k2, x_14_15, v_frac_h0); + + k3 = vmull_u8(x_06_07, v_frac_h1); + k3 = vmlal_u8(k3, x_16_17, v_frac_h0); + + /* k0 now contains 2 interpolated pixels { j0, j1 } */ + /* k1 now contains 2 interpolated pixels { j2, j3 } */ + /* k2 now contains 2 interpolated pixels { j4, j5 } */ + /* k3 now contains 2 interpolated pixels { j6, j7 } */ + + l0 = vshll_n_u16(vget_low_u16(k0), PRECISION); + l0 = vmlsl_n_u16(l0, vget_low_u16(k0), frac_w_0); + l0 = vmlal_n_u16(l0, vget_high_u16(k0), frac_w_0); + + l1 = vshll_n_u16(vget_low_u16(k1), PRECISION); + l1 = vmlsl_n_u16(l1, vget_low_u16(k1), frac_w_1); + l1 = vmlal_n_u16(l1, vget_high_u16(k1), frac_w_1); + + l2 = vshll_n_u16(vget_low_u16(k2), PRECISION); + l2 = vmlsl_n_u16(l2, vget_low_u16(k2), frac_w_2); + l2 = vmlal_n_u16(l2, vget_high_u16(k2), frac_w_2); + + l3 = vshll_n_u16(vget_low_u16(k3), PRECISION); + l3 = vmlsl_n_u16(l3, vget_low_u16(k3), frac_w_3); + l3 = vmlal_n_u16(l3, vget_high_u16(k3), frac_w_3); + + /* shift and narrow */ + d0 = vcombine_u16( + /* uint16x4_t */ vshrn_n_u32(l0, 2 * PRECISION), + /* uint16x4_t */ vshrn_n_u32(l1, 2 * PRECISION) + ); + /* narrow again */ + e0 = vmovn_u16(d0); + + /* Shift and narrow */ + d1 = vcombine_u16( + /* uint16x4_t */ vshrn_n_u32(l2, 2 * PRECISION), + /* uint16x4_t */ vshrn_n_u32(l3, 2 * PRECISION) + ); + /* Narrow again */ + e1 = vmovn_u16(d1); + + f0 = vcombine_u32(CAST_uint32x2_t e0, CAST_uint32x2_t e1); + /* Store 4 pixels */ + vst1q_u32(dst, f0); + + dst += 4; + } + + if (middle & 0x2) { + int index_w_0, frac_w_0; + int index_w_1, frac_w_1; + const Uint32 *s_00_01, *s_02_03; + const Uint32 *s_10_11, *s_12_13; + uint8x8_t x_00_01, x_10_11, x_02_03, x_12_13;/* Pixels in 4*uint8 in row */ + uint16x8_t k0, k1; + uint32x4_t l0, l1; + uint16x8_t d0; + uint8x8_t e0; + + index_w_0 = 4 * SRC_INDEX(fp_sum_w); + frac_w_0 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + index_w_1 = 4 * SRC_INDEX(fp_sum_w); + frac_w_1 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; +/* + x00............ x01 x02...........x03 + . . . . . . + j0 dest0 j1 j2 dest1 j3 + . . . . . . + . . . . . . + . . . . . . + x10............ x11 x12...........x13 +*/ + s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_0); + s_02_03 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_1); + s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_0); + s_12_13 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_1); + + /* Interpolation vertical */ + x_00_01 = CAST_uint8x8_t vld1_u32(s_00_01);/* Load 2 pixels */ + x_02_03 = CAST_uint8x8_t vld1_u32(s_02_03); + x_10_11 = CAST_uint8x8_t vld1_u32(s_10_11); + x_12_13 = CAST_uint8x8_t vld1_u32(s_12_13); + + /* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ + k0 = vmull_u8(x_00_01, v_frac_h1); /* k0 := x0 * (1 - frac) */ + k0 = vmlal_u8(k0, x_10_11, v_frac_h0); /* k0 += x1 * frac */ + + k1 = vmull_u8(x_02_03, v_frac_h1); + k1 = vmlal_u8(k1, x_12_13, v_frac_h0); + + /* k0 now contains 2 interpolated pixels { j0, j1 } */ + /* k1 now contains 2 interpolated pixels { j2, j3 } */ + + l0 = vshll_n_u16(vget_low_u16(k0), PRECISION); + l0 = vmlsl_n_u16(l0, vget_low_u16(k0), frac_w_0); + l0 = vmlal_n_u16(l0, vget_high_u16(k0), frac_w_0); + + l1 = vshll_n_u16(vget_low_u16(k1), PRECISION); + l1 = vmlsl_n_u16(l1, vget_low_u16(k1), frac_w_1); + l1 = vmlal_n_u16(l1, vget_high_u16(k1), frac_w_1); + + /* Shift and narrow */ + + d0 = vcombine_u16( + /* uint16x4_t */ vshrn_n_u32(l0, 2 * PRECISION), + /* uint16x4_t */ vshrn_n_u32(l1, 2 * PRECISION) + ); + + /* Narrow again */ + e0 = vmovn_u16(d0); + + /* Store 2 pixels */ + vst1_u32(dst, CAST_uint32x2_t e0); + dst += 2; + } + + /* Last point */ + if (middle & 0x1) { + int index_w = 4 * SRC_INDEX(fp_sum_w); + int frac_w = FRAC(fp_sum_w); + const Uint32 *s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + const Uint32 *s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + INTERPOL_BILINEAR_NEON(s_00_01, s_10_11, frac_w, v_frac_h0, v_frac_h1, dst); + dst += 1; + } + + while (right_pad_w--) { + int index_w = 4 * (src_w - 2); + const Uint32 *s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + const Uint32 *s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + INTERPOL_BILINEAR_NEON(s_00_01, s_10_11, FRAC_ONE, v_frac_h0, v_frac_h1, dst); + dst += 1; + } + + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} +#endif + +int +SDL_LowerSoftStretchLinear(SDL_Surface *s, const SDL_Rect *srcrect, + SDL_Surface *d, const SDL_Rect *dstrect) +{ + int ret = -1; + int src_w = srcrect->w; + int src_h = srcrect->h; + int dst_w = dstrect->w; + int dst_h = dstrect->h; + int src_pitch = s->pitch; + int dst_pitch = d->pitch; + Uint32 *src = (Uint32 *) ((Uint8 *)s->pixels + srcrect->x * 4 + srcrect->y * src_pitch); + Uint32 *dst = (Uint32 *) ((Uint8 *)d->pixels + dstrect->x * 4 + dstrect->y * dst_pitch); + +#if defined(HAVE_NEON_INTRINSICS) + if (ret == -1 && hasNEON()) { + ret = scale_mat_NEON(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } +#endif + +#if defined(HAVE_SSE2_INTRINSICS) + if (ret == -1 && hasSSE2()) { + ret = scale_mat_SSE(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } +#endif + + if (ret == -1) { + ret = scale_mat(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } + + return ret; +} + + +#define SDL_SCALE_NEAREST__START \ + int i; \ + Uint32 posy, incy; \ + Uint32 posx, incx; \ + int dst_gap; \ + int srcy, n; \ + const Uint32 *src_h0; \ + incy = (src_h << 16) / dst_h; \ + incx = (src_w << 16) / dst_w; \ + dst_gap = dst_pitch - bpp * dst_w; \ + posy = incy / 2; \ + +#define SDL_SCALE_NEAREST__HEIGHT \ + srcy = (posy >> 16); \ + src_h0 = (const Uint32 *)((const Uint8 *)src_ptr + srcy * src_pitch); \ + posy += incy; \ + posx = incx / 2; \ + n = dst_w; + + +static int +scale_mat_nearest_1(const Uint32 *src_ptr, int src_w, int src_h, int src_pitch, + Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + Uint32 bpp = 1; + SDL_SCALE_NEAREST__START + for (i = 0; i < dst_h; i++) { + SDL_SCALE_NEAREST__HEIGHT + while (n--) { + const Uint8 *src; + int srcx = bpp * (posx >> 16); + posx += incx; + src = (const Uint8 *)src_h0 + srcx; + *(Uint8*)dst = *src; + dst = (Uint32 *)((Uint8*)dst + bpp); + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} + +static int +scale_mat_nearest_2(const Uint32 *src_ptr, int src_w, int src_h, int src_pitch, + Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + Uint32 bpp = 2; + SDL_SCALE_NEAREST__START + for (i = 0; i < dst_h; i++) { + SDL_SCALE_NEAREST__HEIGHT + while (n--) { + const Uint16 *src; + int srcx = bpp * (posx >> 16); + posx += incx; + src = (const Uint16 *)((const Uint8 *)src_h0 + srcx); + *(Uint16*)dst = *src; + dst = (Uint32 *)((Uint8*)dst + bpp); + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} + +static int +scale_mat_nearest_3(const Uint32 *src_ptr, int src_w, int src_h, int src_pitch, + Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + Uint32 bpp = 3; + SDL_SCALE_NEAREST__START + for (i = 0; i < dst_h; i++) { + SDL_SCALE_NEAREST__HEIGHT + while (n--) { + const Uint8 *src; + int srcx = bpp * (posx >> 16); + posx += incx; + src = (const Uint8 *)src_h0 + srcx; + ((Uint8*)dst)[0] = src[0]; + ((Uint8*)dst)[1] = src[1]; + ((Uint8*)dst)[2] = src[2]; + dst = (Uint32 *)((Uint8*)dst + bpp); + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} + +static int +scale_mat_nearest_4(const Uint32 *src_ptr, int src_w, int src_h, int src_pitch, + Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + Uint32 bpp = 4; + SDL_SCALE_NEAREST__START + for (i = 0; i < dst_h; i++) { + SDL_SCALE_NEAREST__HEIGHT + while (n--) { + const Uint32 *src; + int srcx = bpp * (posx >> 16); + posx += incx; + src = (const Uint32 *)((const Uint8 *)src_h0 + srcx); + *dst = *src; + dst = (Uint32 *)((Uint8*)dst + bpp); + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} + +int +SDL_LowerSoftStretchNearest(SDL_Surface *s, const SDL_Rect *srcrect, + SDL_Surface *d, const SDL_Rect *dstrect) +{ + int src_w = srcrect->w; + int src_h = srcrect->h; + int dst_w = dstrect->w; + int dst_h = dstrect->h; + int src_pitch = s->pitch; + int dst_pitch = d->pitch; + + const int bpp = d->format->BytesPerPixel; + + Uint32 *src = (Uint32 *) ((Uint8 *)s->pixels + srcrect->x * bpp + srcrect->y * src_pitch); + Uint32 *dst = (Uint32 *) ((Uint8 *)d->pixels + dstrect->x * bpp + dstrect->y * dst_pitch); + + if (bpp == 4) { + return scale_mat_nearest_4(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } else if (bpp == 3) { + return scale_mat_nearest_3(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } else if (bpp == 2) { + return scale_mat_nearest_2(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } else { + return scale_mat_nearest_1(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/SDL_surface.c b/Engine/lib/sdl/src/video/SDL_surface.c index ade68bf34..ec981a29c 100644 --- a/Engine/lib/sdl/src/video/SDL_surface.c +++ b/Engine/lib/sdl/src/video/SDL_surface.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,6 +26,7 @@ #include "SDL_RLEaccel_c.h" #include "SDL_pixels_c.h" #include "SDL_yuv_c.h" +#include "../render/SDL_sysrender.h" /* Check to make sure we can safely check multiplication of surface w and pitch and it won't overflow size_t */ @@ -218,7 +219,7 @@ int SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette) { if (!surface) { - return SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface"); + return SDL_InvalidParamError("SDL_SetSurfacePalette(): surface"); } if (SDL_SetPixelFormatPalette(surface->format, palette) < 0) { return -1; @@ -325,11 +326,12 @@ SDL_GetColorKey(SDL_Surface * surface, Uint32 * key) return 0; } -/* This is a fairly slow function to switch from colorkey to alpha */ +/* This is a fairly slow function to switch from colorkey to alpha + NB: it doesn't handle bpp 1 or 3, because they have no alpha channel */ static void SDL_ConvertColorkeyToAlpha(SDL_Surface * surface, SDL_bool ignore_alpha) { - int x, y; + int x, y, bpp; if (!surface) { return; @@ -340,82 +342,74 @@ SDL_ConvertColorkeyToAlpha(SDL_Surface * surface, SDL_bool ignore_alpha) return; } + bpp = surface->format->BytesPerPixel; + SDL_LockSurface(surface); - switch (surface->format->BytesPerPixel) { - case 2: - { - Uint16 *row, *spot; - Uint16 ckey = (Uint16) surface->map->info.colorkey; - Uint16 mask = (Uint16) (~surface->format->Amask); + if (bpp == 2) { + Uint16 *row, *spot; + Uint16 ckey = (Uint16) surface->map->info.colorkey; + Uint16 mask = (Uint16) (~surface->format->Amask); - /* Ignore, or not, alpha in colorkey comparison */ - if (ignore_alpha) { - ckey &= mask; - row = (Uint16 *) surface->pixels; - for (y = surface->h; y--;) { - spot = row; - for (x = surface->w; x--;) { - if ((*spot & mask) == ckey) { - *spot &= mask; - } - ++spot; + /* Ignore, or not, alpha in colorkey comparison */ + if (ignore_alpha) { + ckey &= mask; + row = (Uint16 *) surface->pixels; + for (y = surface->h; y--;) { + spot = row; + for (x = surface->w; x--;) { + if ((*spot & mask) == ckey) { + *spot &= mask; } - row += surface->pitch / 2; + ++spot; } - } else { - row = (Uint16 *) surface->pixels; - for (y = surface->h; y--;) { - spot = row; - for (x = surface->w; x--;) { - if (*spot == ckey) { - *spot &= mask; - } - ++spot; + row += surface->pitch / 2; + } + } else { + row = (Uint16 *) surface->pixels; + for (y = surface->h; y--;) { + spot = row; + for (x = surface->w; x--;) { + if (*spot == ckey) { + *spot &= mask; } - row += surface->pitch / 2; + ++spot; } + row += surface->pitch / 2; } } - break; - case 3: - /* FIXME */ - break; - case 4: - { - Uint32 *row, *spot; - Uint32 ckey = surface->map->info.colorkey; - Uint32 mask = ~surface->format->Amask; + } else if (bpp == 4) { + Uint32 *row, *spot; + Uint32 ckey = surface->map->info.colorkey; + Uint32 mask = ~surface->format->Amask; - /* Ignore, or not, alpha in colorkey comparison */ - if (ignore_alpha) { - ckey &= mask; - row = (Uint32 *) surface->pixels; - for (y = surface->h; y--;) { - spot = row; - for (x = surface->w; x--;) { - if ((*spot & mask) == ckey) { - *spot &= mask; - } - ++spot; + /* Ignore, or not, alpha in colorkey comparison */ + if (ignore_alpha) { + ckey &= mask; + row = (Uint32 *) surface->pixels; + for (y = surface->h; y--;) { + spot = row; + for (x = surface->w; x--;) { + if ((*spot & mask) == ckey) { + *spot &= mask; } - row += surface->pitch / 4; + ++spot; } - } else { - row = (Uint32 *) surface->pixels; - for (y = surface->h; y--;) { - spot = row; - for (x = surface->w; x--;) { - if (*spot == ckey) { - *spot &= mask; - } - ++spot; + row += surface->pitch / 4; + } + } else { + row = (Uint32 *) surface->pixels; + for (y = surface->h; y--;) { + spot = row; + for (x = surface->w; x--;) { + if (*spot == ckey) { + *spot &= mask; } - row += surface->pitch / 4; + ++spot; } + row += surface->pitch / 4; } } - break; } SDL_UnlockSurface(surface); @@ -652,7 +646,7 @@ SDL_UpperBlit(SDL_Surface * src, const SDL_Rect * srcrect, /* Make sure the surfaces aren't locked */ if (!src || !dst) { - return SDL_SetError("SDL_UpperBlit: passed a NULL surface"); + return SDL_InvalidParamError("SDL_UpperBlit(): src/dst"); } if (src->locked || dst->locked) { return SDL_SetError("Surfaces must not be locked during blit"); @@ -745,6 +739,14 @@ SDL_UpperBlit(SDL_Surface * src, const SDL_Rect * srcrect, int SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect) +{ + return SDL_PrivateUpperBlitScaled(src, srcrect, dst, dstrect, SDL_ScaleModeNearest); +} + + +int +SDL_PrivateUpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect, SDL_ScaleMode scaleMode) { double src_x0, src_y0, src_x1, src_y1; double dst_x0, dst_y0, dst_x1, dst_y1; @@ -755,7 +757,7 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, /* Make sure the surfaces aren't locked */ if (!src || !dst) { - return SDL_SetError("SDL_UpperBlitScaled: passed a NULL surface"); + return SDL_InvalidParamError("SDL_UpperBlitScaled(): src/dst"); } if (src->locked || dst->locked) { return SDL_SetError("Surfaces must not be locked during blit"); @@ -788,25 +790,25 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, if (NULL == dstrect) { dst_x0 = 0; dst_y0 = 0; - dst_x1 = dst_w - 1; - dst_y1 = dst_h - 1; + dst_x1 = dst_w; + dst_y1 = dst_h; } else { dst_x0 = dstrect->x; dst_y0 = dstrect->y; - dst_x1 = dst_x0 + dst_w - 1; - dst_y1 = dst_y0 + dst_h - 1; + dst_x1 = dst_x0 + dst_w; + dst_y1 = dst_y0 + dst_h; } if (NULL == srcrect) { src_x0 = 0; src_y0 = 0; - src_x1 = src_w - 1; - src_y1 = src_h - 1; + src_x1 = src_w; + src_y1 = src_h; } else { src_x0 = srcrect->x; src_y0 = srcrect->y; - src_x1 = src_x0 + src_w - 1; - src_y1 = src_y0 + src_h - 1; + src_x1 = src_x0 + src_w; + src_y1 = src_y0 + src_h; /* Clip source rectangle to the source surface */ @@ -815,9 +817,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, src_x0 = 0; } - if (src_x1 >= src->w) { - dst_x1 -= (src_x1 - src->w + 1) * scaling_w; - src_x1 = src->w - 1; + if (src_x1 > src->w) { + dst_x1 -= (src_x1 - src->w) * scaling_w; + src_x1 = src->w; } if (src_y0 < 0) { @@ -825,9 +827,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, src_y0 = 0; } - if (src_y1 >= src->h) { - dst_y1 -= (src_y1 - src->h + 1) * scaling_h; - src_y1 = src->h - 1; + if (src_y1 > src->h) { + dst_y1 -= (src_y1 - src->h) * scaling_h; + src_y1 = src->h; } } @@ -844,9 +846,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, dst_x0 = 0; } - if (dst_x1 >= dst->clip_rect.w) { - src_x1 -= (dst_x1 - dst->clip_rect.w + 1) / scaling_w; - dst_x1 = dst->clip_rect.w - 1; + if (dst_x1 > dst->clip_rect.w) { + src_x1 -= (dst_x1 - dst->clip_rect.w) / scaling_w; + dst_x1 = dst->clip_rect.w; } if (dst_y0 < 0) { @@ -854,9 +856,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, dst_y0 = 0; } - if (dst_y1 >= dst->clip_rect.h) { - src_y1 -= (dst_y1 - dst->clip_rect.h + 1) / scaling_h; - dst_y1 = dst->clip_rect.h - 1; + if (dst_y1 > dst->clip_rect.h) { + src_y1 -= (dst_y1 - dst->clip_rect.h) / scaling_h; + dst_y1 = dst->clip_rect.h; } /* Translate back to surface coordinates */ @@ -865,23 +867,32 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, dst_y0 += dst->clip_rect.y; dst_y1 += dst->clip_rect.y; - final_src.x = (int)SDL_floor(src_x0 + 0.5); - final_src.y = (int)SDL_floor(src_y0 + 0.5); - final_src.w = (int)SDL_floor(src_x1 + 1 + 0.5) - (int)SDL_floor(src_x0 + 0.5); - final_src.h = (int)SDL_floor(src_y1 + 1 + 0.5) - (int)SDL_floor(src_y0 + 0.5); + final_src.x = (int)SDL_round(src_x0); + final_src.y = (int)SDL_round(src_y0); + final_src.w = (int)SDL_round(src_x1 - src_x0); + final_src.h = (int)SDL_round(src_y1 - src_y0); - final_dst.x = (int)SDL_floor(dst_x0 + 0.5); - final_dst.y = (int)SDL_floor(dst_y0 + 0.5); - final_dst.w = (int)SDL_floor(dst_x1 - dst_x0 + 1.5); - final_dst.h = (int)SDL_floor(dst_y1 - dst_y0 + 1.5); + final_dst.x = (int)SDL_round(dst_x0); + final_dst.y = (int)SDL_round(dst_y0); + final_dst.w = (int)SDL_round(dst_x1 - dst_x0); + final_dst.h = (int)SDL_round(dst_y1 - dst_y0); - if (final_dst.w < 0) - final_dst.w = 0; - if (final_dst.h < 0) - final_dst.h = 0; + /* Clip again */ + { + SDL_Rect tmp; + tmp.x = 0; + tmp.y = 0; + tmp.w = src->w; + tmp.h = src->h; + SDL_IntersectRect(&tmp, &final_src, &final_src); + } - if (dstrect) + /* Clip again */ + SDL_IntersectRect(&dst->clip_rect, &final_dst, &final_dst); + + if (dstrect) { *dstrect = final_dst; + } if (final_dst.w == 0 || final_dst.h == 0 || final_src.w <= 0 || final_src.h <= 0) { @@ -889,7 +900,7 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, return 0; } - return SDL_LowerBlitScaled(src, &final_src, dst, &final_dst); + return SDL_PrivateLowerBlitScaled(src, &final_src, dst, &final_dst, scaleMode); } /** @@ -899,6 +910,13 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, int SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect) +{ + return SDL_PrivateLowerBlitScaled(src, srcrect, dst, dstrect, SDL_ScaleModeNearest); +} + +int +SDL_PrivateLowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect, SDL_ScaleMode scaleMode) { static const Uint32 complex_copy_flags = ( SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | @@ -906,17 +924,103 @@ SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect, SDL_COPY_COLORKEY ); + if (srcrect->w > SDL_MAX_UINT16 || srcrect->h > SDL_MAX_UINT16 || + dstrect->w > SDL_MAX_UINT16 || dstrect->h > SDL_MAX_UINT16) { + return SDL_SetError("Size too large for scaling"); + } + if (!(src->map->info.flags & SDL_COPY_NEAREST)) { src->map->info.flags |= SDL_COPY_NEAREST; SDL_InvalidateMap(src->map); } - if ( !(src->map->info.flags & complex_copy_flags) && - src->format->format == dst->format->format && - !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) { - return SDL_SoftStretch( src, srcrect, dst, dstrect ); + if (scaleMode == SDL_ScaleModeNearest) { + if ( !(src->map->info.flags & complex_copy_flags) && + src->format->format == dst->format->format && + !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) { + return SDL_SoftStretch( src, srcrect, dst, dstrect ); + } else { + return SDL_LowerBlit( src, srcrect, dst, dstrect ); + } } else { - return SDL_LowerBlit( src, srcrect, dst, dstrect ); + if ( !(src->map->info.flags & complex_copy_flags) && + src->format->format == dst->format->format && + !SDL_ISPIXELFORMAT_INDEXED(src->format->format) && + src->format->BytesPerPixel == 4 && + src->format->format != SDL_PIXELFORMAT_ARGB2101010) { + /* fast path */ + return SDL_SoftStretchLinear(src, srcrect, dst, dstrect); + } else { + /* Use intermediate surface(s) */ + SDL_Surface *tmp1 = NULL; + int ret; + SDL_Rect srcrect2; + int is_complex_copy_flags = (src->map->info.flags & complex_copy_flags); + + Uint32 flags; + Uint8 r, g, b; + Uint8 alpha; + SDL_BlendMode blendMode; + + /* Save source infos */ + flags = src->flags; + SDL_GetSurfaceColorMod(src, &r, &g, &b); + SDL_GetSurfaceAlphaMod(src, &alpha); + SDL_GetSurfaceBlendMode(src, &blendMode); + srcrect2.x = srcrect->x; + srcrect2.y = srcrect->y; + srcrect2.w = srcrect->w; + srcrect2.h = srcrect->h; + + /* Change source format if not appropriate for scaling */ + if (src->format->BytesPerPixel != 4 || src->format->format == SDL_PIXELFORMAT_ARGB2101010) { + SDL_Rect tmprect; + int fmt; + tmprect.x = 0; + tmprect.y = 0; + tmprect.w = src->w; + tmprect.h = src->h; + if (dst->format->BytesPerPixel == 4 && dst->format->format != SDL_PIXELFORMAT_ARGB2101010) { + fmt = dst->format->format; + } else { + fmt = SDL_PIXELFORMAT_ARGB8888; + } + tmp1 = SDL_CreateRGBSurfaceWithFormat(flags, src->w, src->h, 0, fmt); + SDL_LowerBlit(src, srcrect, tmp1, &tmprect); + + + srcrect2.x = 0; + srcrect2.y = 0; + SDL_SetSurfaceColorMod(tmp1, r, g, b); + SDL_SetSurfaceAlphaMod(tmp1, alpha); + SDL_SetSurfaceBlendMode(tmp1, blendMode); + + src = tmp1; + } + + /* Intermediate scaling */ + if (is_complex_copy_flags || src->format->format != dst->format->format) { + SDL_Rect tmprect; + SDL_Surface *tmp2 = SDL_CreateRGBSurfaceWithFormat(flags, dstrect->w, dstrect->h, 0, src->format->format); + SDL_SoftStretchLinear(src, &srcrect2, tmp2, NULL); + + SDL_SetSurfaceColorMod(tmp2, r, g, b); + SDL_SetSurfaceAlphaMod(tmp2, alpha); + SDL_SetSurfaceBlendMode(tmp2, blendMode); + + tmprect.x = 0; + tmprect.y = 0; + tmprect.w = dstrect->w; + tmprect.h = dstrect->h; + ret = SDL_LowerBlit(tmp2, &tmprect, dst, dstrect); + SDL_FreeSurface(tmp2); + } else { + ret = SDL_SoftStretchLinear(src, &srcrect2, dst, dstrect); + } + + SDL_FreeSurface(tmp1); + return ret; + } } } @@ -988,6 +1092,7 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, int palette_ck_value = 0; SDL_bool palette_has_alpha = SDL_FALSE; Uint8 *palette_saved_alpha = NULL; + int palette_saved_alpha_ncolors = 0; if (!surface) { SDL_InvalidParamError("surface"); @@ -1069,8 +1174,9 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, /* Set opaque and backup palette alpha values */ if (set_opaque) { int i; - palette_saved_alpha = SDL_stack_alloc(Uint8, surface->format->palette->ncolors); - for (i = 0; i < surface->format->palette->ncolors; i++) { + palette_saved_alpha_ncolors = surface->format->palette->ncolors; + palette_saved_alpha = SDL_stack_alloc(Uint8, palette_saved_alpha_ncolors); + for (i = 0; i < palette_saved_alpha_ncolors; i++) { palette_saved_alpha[i] = surface->format->palette->colors[i].a; surface->format->palette->colors[i].a = SDL_ALPHA_OPAQUE; } @@ -1097,7 +1203,7 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, /* Restore palette alpha values */ if (palette_saved_alpha) { int i; - for (i = 0; i < surface->format->palette->ncolors; i++) { + for (i = 0; i < palette_saved_alpha_ncolors; i++) { surface->format->palette->colors[i].a = palette_saved_alpha[i]; } SDL_stack_free(palette_saved_alpha); @@ -1275,7 +1381,12 @@ int SDL_ConvertPixels(int width, int height, void *nonconst_src = (void *) src; int ret; - /* Check to make sure we are blitting somewhere, so we don't crash */ + if (!src) { + return SDL_InvalidParamError("src"); + } + if (!src_pitch) { + return SDL_InvalidParamError("src_pitch"); + } if (!dst) { return SDL_InvalidParamError("dst"); } @@ -1293,8 +1404,7 @@ int SDL_ConvertPixels(int width, int height, } #else if (SDL_ISPIXELFORMAT_FOURCC(src_format) || SDL_ISPIXELFORMAT_FOURCC(dst_format)) { - SDL_SetError("SDL not built with YUV support"); - return -1; + return SDL_SetError("SDL not built with YUV support"); } #endif @@ -1334,6 +1444,68 @@ int SDL_ConvertPixels(int width, int height, return ret; } +/* + * Premultiply the alpha on a block of pixels + * + * This is currently only implemented for SDL_PIXELFORMAT_ARGB8888 + * + * Here are some ideas for optimization: + * https://github.com/Wizermil/premultiply_alpha/tree/master/premultiply_alpha + * https://developer.arm.com/documentation/101964/0201/Pre-multiplied-alpha-channel-data + */ +int SDL_PremultiplyAlpha(int width, int height, + Uint32 src_format, const void * src, int src_pitch, + Uint32 dst_format, void * dst, int dst_pitch) +{ + int c; + Uint32 srcpixel; + Uint32 srcR, srcG, srcB, srcA; + Uint32 dstpixel; + Uint32 dstR, dstG, dstB, dstA; + + if (!src) { + return SDL_InvalidParamError("src"); + } + if (!src_pitch) { + return SDL_InvalidParamError("src_pitch"); + } + if (!dst) { + return SDL_InvalidParamError("dst"); + } + if (!dst_pitch) { + return SDL_InvalidParamError("dst_pitch"); + } + if (src_format != SDL_PIXELFORMAT_ARGB8888) { + return SDL_InvalidParamError("src_format"); + } + if (dst_format != SDL_PIXELFORMAT_ARGB8888) { + return SDL_InvalidParamError("dst_format"); + } + + while (height--) { + const Uint32 *src_px = (const Uint32 *)src; + Uint32 *dst_px = (Uint32 *)dst; + for (c = width; c; --c) { + /* Component bytes extraction. */ + srcpixel = *src_px++; + RGBA_FROM_ARGB8888(srcpixel, srcR, srcG, srcB, srcA); + + /* Alpha pre-multiplication of each component. */ + dstA = srcA; + dstR = (srcA * srcR) / 255; + dstG = (srcA * srcG) / 255; + dstB = (srcA * srcB) / 255; + + /* ARGB8888 pixel recomposition. */ + ARGB8888_FROM_RGBA(dstpixel, dstR, dstG, dstB, dstA); + *dst_px++ = dstpixel; + } + src = (const Uint8 *)src + src_pitch; + dst = (Uint8 *)dst + dst_pitch; + } + return 0; +} + /* * Free a surface created by the above function. */ diff --git a/Engine/lib/sdl/src/video/SDL_sysvideo.h b/Engine/lib/sdl/src/video/SDL_sysvideo.h index c8c425b6b..e2a65045b 100644 --- a/Engine/lib/sdl/src/video/SDL_sysvideo.h +++ b/Engine/lib/sdl/src/video/SDL_sysvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -83,6 +83,7 @@ struct SDL_Window int max_w, max_h; Uint32 flags; Uint32 last_fullscreen_flags; + Uint32 display_index; /* Stored position and size for windowed mode */ SDL_Rect windowed; @@ -102,6 +103,8 @@ struct SDL_Window SDL_bool is_destroying; SDL_bool is_dropping; /* drag/drop in progress, expecting SDL_SendDropComplete(). */ + SDL_Rect mouse_rect; + SDL_WindowShaper *shaper; SDL_HitTest hit_test; @@ -229,15 +232,20 @@ struct SDL_VideoDevice void (*RestoreWindow) (_THIS, SDL_Window * window); void (*SetWindowBordered) (_THIS, SDL_Window * window, SDL_bool bordered); void (*SetWindowResizable) (_THIS, SDL_Window * window, SDL_bool resizable); + void (*SetWindowAlwaysOnTop) (_THIS, SDL_Window * window, SDL_bool on_top); void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp); int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp); - void (*SetWindowGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); + void* (*GetWindowICCProfile) (_THIS, SDL_Window * window, size_t* size); + void (*SetWindowMouseRect)(_THIS, SDL_Window * window); + void (*SetWindowMouseGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); + void (*SetWindowKeyboardGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); void (*DestroyWindow) (_THIS, SDL_Window * window); int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window); void (*OnWindowEnter) (_THIS, SDL_Window * window); + int (*FlashWindow) (_THIS, SDL_Window * window, SDL_FlashOperation operation); /* * * */ /* @@ -288,6 +296,8 @@ struct SDL_VideoDevice /* * Event manager functions */ + int (*WaitEventTimeout) (_THIS, int timeout); + void (*SendWakeupEvent) (_THIS, SDL_Window *window); void (*PumpEvents) (_THIS); /* Suspend the screensaver */ @@ -297,6 +307,8 @@ struct SDL_VideoDevice void (*StartTextInput) (_THIS); void (*StopTextInput) (_THIS); void (*SetTextInputRect) (_THIS, SDL_Rect *rect); + void (*ClearComposition) (_THIS); + SDL_bool (*IsTextInputShown) (_THIS); /* Screen keyboard */ SDL_bool (*HasScreenKeyboardSupport) (_THIS); @@ -320,8 +332,11 @@ struct SDL_VideoDevice /* * * */ /* Data common to all drivers */ + SDL_bool checked_texture_framebuffer; SDL_bool is_dummy; SDL_bool suspend_screensaver; + SDL_Window *wakeup_window; + SDL_mutex *wakeup_lock; /* Initialized only if WaitEventTimeout/SendWakeupEvent are supported */ int num_displays; SDL_VideoDisplay *displays; SDL_Window *windows; @@ -329,6 +344,7 @@ struct SDL_VideoDevice Uint8 window_magic; Uint32 next_object_id; char *clipboard_text; + SDL_bool setting_display_mode; /* * * */ /* Data used by the GL drivers */ @@ -427,6 +443,8 @@ extern VideoBootStrap PND_bootstrap; extern VideoBootStrap UIKIT_bootstrap; extern VideoBootStrap Android_bootstrap; extern VideoBootStrap PSP_bootstrap; +extern VideoBootStrap VITA_bootstrap; +extern VideoBootStrap RISCOS_bootstrap; extern VideoBootStrap RPI_bootstrap; extern VideoBootStrap KMSDRM_bootstrap; extern VideoBootStrap KMSDRM_LEGACY_bootstrap; @@ -445,6 +463,9 @@ extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode); extern int SDL_AddVideoDisplay(const SDL_VideoDisplay * display, SDL_bool send_event); extern void SDL_DelVideoDisplay(int index); extern SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode); +extern void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode); +extern void SDL_SetDesktopDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode); +extern void SDL_ResetDisplayModes(int displayIndex); extern int SDL_GetIndexOfDisplay(SDL_VideoDisplay *display); extern SDL_VideoDisplay *SDL_GetDisplay(int displayIndex); extern SDL_VideoDisplay *SDL_GetDisplayForWindow(SDL_Window *window); @@ -458,6 +479,7 @@ extern SDL_bool SDL_HasWindows(void); extern void SDL_OnWindowShown(SDL_Window * window); extern void SDL_OnWindowHidden(SDL_Window * window); +extern void SDL_OnWindowMoved(SDL_Window * window); extern void SDL_OnWindowResized(SDL_Window * window); extern void SDL_OnWindowMinimized(SDL_Window * window); extern void SDL_OnWindowRestored(SDL_Window * window); diff --git a/Engine/lib/sdl/src/video/SDL_video.c b/Engine/lib/sdl/src/video/SDL_video.c index a0ca32243..3be98806d 100644 --- a/Engine/lib/sdl/src/video/SDL_video.c +++ b/Engine/lib/sdl/src/video/SDL_video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -61,12 +61,12 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_COCOA &COCOA_bootstrap, #endif -#if SDL_VIDEO_DRIVER_X11 - &X11_bootstrap, -#endif #if SDL_VIDEO_DRIVER_WAYLAND &Wayland_bootstrap, #endif +#if SDL_VIDEO_DRIVER_X11 + &X11_bootstrap, +#endif #if SDL_VIDEO_DRIVER_VIVANTE &VIVANTE_bootstrap, #endif @@ -94,9 +94,14 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_PSP &PSP_bootstrap, #endif +#if SDL_VIDEO_DRIVER_VITA + &VITA_bootstrap, +#endif #if SDL_VIDEO_DRIVER_KMSDRM &KMSDRM_bootstrap, - &KMSDRM_LEGACY_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_RISCOS + &RISCOS_bootstrap, #endif #if SDL_VIDEO_DRIVER_RPI &RPI_bootstrap, @@ -123,14 +128,11 @@ static VideoBootStrap *bootstrap[] = { NULL }; -static SDL_VideoDevice *_this = NULL; - #define CHECK_WINDOW_MAGIC(window, retval) \ if (!_this) { \ SDL_UninitializedVideo(); \ return retval; \ } \ - SDL_assert(window && window->magic == &_this->window_magic); \ if (!window || window->magic != &_this->window_magic) { \ SDL_SetError("Invalid window"); \ return retval; \ @@ -141,8 +143,6 @@ static SDL_VideoDevice *_this = NULL; SDL_UninitializedVideo(); \ return retval; \ } \ - SDL_assert(_this->displays != NULL); \ - SDL_assert(displayIndex >= 0 && displayIndex < _this->num_displays); \ if (displayIndex < 0 || displayIndex >= _this->num_displays) { \ SDL_SetError("displayIndex must be in the range 0 - %d", \ _this->num_displays - 1); \ @@ -170,137 +170,58 @@ typedef struct { int bytes_per_pixel; } SDL_WindowTextureData; -static SDL_bool -ShouldUseTextureFramebuffer() -{ - const char *hint; - - /* If there's no native framebuffer support then there's no option */ - if (!_this->CreateWindowFramebuffer) { - return SDL_TRUE; - } - - /* If this is the dummy driver there is no texture support */ - if (_this->is_dummy) { - return SDL_FALSE; - } - - /* If the user has specified a software renderer we can't use a - texture framebuffer, or renderer creation will go recursive. - */ - hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER); - if (hint && SDL_strcasecmp(hint, "software") == 0) { - return SDL_FALSE; - } - - /* See if the user or application wants a specific behavior */ - hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); - if (hint) { - if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0) { - return SDL_FALSE; - } else { - return SDL_TRUE; - } - } - - /* Each platform has different performance characteristics */ -#if defined(__WIN32__) - /* GDI BitBlt() is way faster than Direct3D dynamic textures right now. - */ - return SDL_FALSE; - -#elif defined(__MACOSX__) - /* Mac OS X uses OpenGL as the native fast path (for cocoa and X11) */ - return SDL_TRUE; - -#elif defined(__LINUX__) - /* Properly configured OpenGL drivers are faster than MIT-SHM */ -#if SDL_VIDEO_OPENGL - /* Ugh, find a way to cache this value! */ - { - SDL_Window *window; - SDL_GLContext context; - SDL_bool hasAcceleratedOpenGL = SDL_FALSE; - - window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32, SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN); - if (window) { - context = SDL_GL_CreateContext(window); - if (context) { - const GLubyte *(APIENTRY * glGetStringFunc) (GLenum); - const char *vendor = NULL; - - glGetStringFunc = SDL_GL_GetProcAddress("glGetString"); - if (glGetStringFunc) { - vendor = (const char *) glGetStringFunc(GL_VENDOR); - } - /* Add more vendors here at will... */ - if (vendor && - (SDL_strstr(vendor, "ATI Technologies") || - SDL_strstr(vendor, "NVIDIA"))) { - hasAcceleratedOpenGL = SDL_TRUE; - } - SDL_GL_DeleteContext(context); - } - SDL_DestroyWindow(window); - } - return hasAcceleratedOpenGL; - } -#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - /* Let's be optimistic about this! */ - return SDL_TRUE; -#else - return SDL_FALSE; -#endif - -#else - /* Play it safe, assume that if there is a framebuffer driver that it's - optimized for the current platform. - */ - return SDL_FALSE; -#endif -} static int -SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) { - SDL_WindowTextureData *data; + SDL_RendererInfo info; + SDL_WindowTextureData *data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA); + int i; - data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA); if (!data) { SDL_Renderer *renderer = NULL; - int i; const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); - - /* Check to see if there's a specific driver requested */ - if (hint && *hint != '0' && *hint != '1' && + const SDL_bool specific_accelerated_renderer = ( + hint && *hint != '0' && *hint != '1' && SDL_strcasecmp(hint, "true") != 0 && SDL_strcasecmp(hint, "false") != 0 && - SDL_strcasecmp(hint, "software") != 0) { + SDL_strcasecmp(hint, "software") != 0 + ); + + /* Check to see if there's a specific driver requested */ + if (specific_accelerated_renderer) { for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { - SDL_RendererInfo info; SDL_GetRenderDriverInfo(i, &info); if (SDL_strcasecmp(info.name, hint) == 0) { renderer = SDL_CreateRenderer(window, i, 0); break; } } - } - - if (!renderer) { + if (!renderer || (SDL_GetRendererInfo(renderer, &info) == -1)) { + if (renderer) { SDL_DestroyRenderer(renderer); } + return SDL_SetError("Requested renderer for " SDL_HINT_FRAMEBUFFER_ACCELERATION " is not available"); + } + /* if it was specifically requested, even if SDL_RENDERER_ACCELERATED isn't set, we'll accept this renderer. */ + } else { for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { - SDL_RendererInfo info; SDL_GetRenderDriverInfo(i, &info); if (SDL_strcmp(info.name, "software") != 0) { renderer = SDL_CreateRenderer(window, i, 0); - if (renderer) { - break; + if (renderer && (SDL_GetRendererInfo(renderer, &info) == 0) && (info.flags & SDL_RENDERER_ACCELERATED)) { + break; /* this will work. */ + } + if (renderer) { /* wasn't accelerated, etc, skip it. */ + SDL_DestroyRenderer(renderer); + renderer = NULL; } } } + if (!renderer) { + return SDL_SetError("No hardware accelerated renderers available"); + } } - if (!renderer) { - return SDL_SetError("No hardware accelerated renderers available"); - } + + SDL_assert(renderer != NULL); /* should have explicitly checked this above. */ /* Create the data after we successfully create the renderer (bug #1116) */ data = (SDL_WindowTextureData *)SDL_calloc(1, sizeof(*data)); @@ -311,6 +232,10 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, data); data->renderer = renderer; + } else { + if (SDL_GetRendererInfo(data->renderer, &info) == -1) { + return -1; + } } /* Free any old texture and pixel data */ @@ -321,23 +246,14 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f SDL_free(data->pixels); data->pixels = NULL; - { - SDL_RendererInfo info; - Uint32 i; + /* Find the first format without an alpha channel */ + *format = info.texture_formats[0]; - if (SDL_GetRendererInfo(data->renderer, &info) < 0) { - return -1; - } - - /* Find the first format without an alpha channel */ - *format = info.texture_formats[0]; - - for (i = 0; i < info.num_texture_formats; ++i) { - if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i]) && - !SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) { - *format = info.texture_formats[i]; - break; - } + for (i = 0; i < (int) info.num_texture_formats; ++i) { + if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i]) && + !SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) { + *format = info.texture_formats[i]; + break; } } @@ -353,7 +269,7 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3); { - /* Make static analysis happy about potential malloc(0) calls. */ + /* Make static analysis happy about potential SDL_malloc(0) calls. */ const size_t allocsize = window->h * data->pitch; data->pixels = SDL_malloc((allocsize > 0) ? allocsize : 1); if (!data->pixels) { @@ -370,6 +286,8 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f return 0; } +static SDL_VideoDevice *_this = NULL; + static int SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, const SDL_Rect * rects, int numrects) { @@ -419,7 +337,6 @@ SDL_DestroyWindowTexture(SDL_VideoDevice *unused, SDL_Window * window) SDL_free(data); } - static int cmpmodes(const void *A, const void *B) { @@ -471,6 +388,10 @@ SDL_VideoInit(const char *driver_name) SDL_VideoDevice *video; int index; int i; + SDL_bool init_events = SDL_FALSE; + SDL_bool init_keyboard = SDL_FALSE; + SDL_bool init_mouse = SDL_FALSE; + SDL_bool init_touch = SDL_FALSE; /* Check to make sure we don't overwrite '_this' */ if (_this != NULL) { @@ -482,25 +403,45 @@ SDL_VideoInit(const char *driver_name) #endif /* Start the event loop */ - if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0 || - SDL_KeyboardInit() < 0 || - SDL_MouseInit() < 0 || - SDL_TouchInit() < 0) { - return -1; + if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) { + goto pre_driver_error; } + init_events = SDL_TRUE; + if (SDL_KeyboardInit() < 0) { + goto pre_driver_error; + } + init_keyboard = SDL_TRUE; + if (SDL_MouseInit() < 0) { + goto pre_driver_error; + } + init_mouse = SDL_TRUE; + if (SDL_TouchInit() < 0) { + goto pre_driver_error; + } + init_touch = SDL_TRUE; /* Select the proper video driver */ - index = 0; + i = index = 0; video = NULL; if (driver_name == NULL) { driver_name = SDL_getenv("SDL_VIDEODRIVER"); } - if (driver_name != NULL) { - for (i = 0; bootstrap[i]; ++i) { - if (SDL_strncasecmp(bootstrap[i]->name, driver_name, SDL_strlen(driver_name)) == 0) { - video = bootstrap[i]->create(index); - break; + if (driver_name != NULL && *driver_name != 0) { + const char *driver_attempt = driver_name; + while(driver_attempt != NULL && *driver_attempt != 0 && video == NULL) { + const char* driver_attempt_end = SDL_strchr(driver_attempt, ','); + size_t driver_attempt_len = (driver_attempt_end != NULL) ? (driver_attempt_end - driver_attempt) + : SDL_strlen(driver_attempt); + + for (i = 0; bootstrap[i]; ++i) { + if ((driver_attempt_len == SDL_strlen(bootstrap[i]->name)) && + (SDL_strncasecmp(bootstrap[i]->name, driver_attempt, driver_attempt_len) == 0)) { + video = bootstrap[i]->create(index); + break; + } } + + driver_attempt = (driver_attempt_end != NULL) ? (driver_attempt_end + 1) : NULL; } } else { for (i = 0; bootstrap[i]; ++i) { @@ -512,10 +453,15 @@ SDL_VideoInit(const char *driver_name) } if (video == NULL) { if (driver_name) { - return SDL_SetError("%s not available", driver_name); + SDL_SetError("%s not available", driver_name); + goto pre_driver_error; } - return SDL_SetError("No available video device"); + SDL_SetError("No available video device"); + goto pre_driver_error; } + + /* From this point on, use SDL_VideoQuit to cleanup on error, rather than + pre_driver_error. */ _this = video; _this->name = bootstrap[i]->name; _this->next_object_id = 1; @@ -541,13 +487,6 @@ SDL_VideoInit(const char *driver_name) return SDL_SetError("The video driver did not add any displays"); } - /* Add the renderer framebuffer emulation if desired */ - if (ShouldUseTextureFramebuffer()) { - _this->CreateWindowFramebuffer = SDL_CreateWindowTexture; - _this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture; - _this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture; - } - /* Disable the screen saver by default. This is a change from <= 2.0.1, but most things using SDL are games or media players; you wouldn't want a screensaver to trigger if you're playing exclusively with a @@ -571,6 +510,22 @@ SDL_VideoInit(const char *driver_name) /* We're ready to go! */ return 0; + +pre_driver_error: + SDL_assert(_this == NULL); + if (init_touch) { + SDL_TouchQuit(); + } + if (init_mouse) { + SDL_MouseQuit(); + } + if (init_keyboard) { + SDL_KeyboardQuit(); + } + if (init_events) { + SDL_QuitSubSystem(SDL_INIT_EVENTS); + } + return -1; } const char * @@ -789,7 +744,7 @@ SDL_GetDisplayOrientation(int displayIndex) } SDL_bool -SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) +SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) { SDL_DisplayMode *modes; int i, nmodes; @@ -824,6 +779,18 @@ SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) return SDL_TRUE; } +void +SDL_SetCurrentDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) +{ + SDL_memcpy(&display->current_mode, mode, sizeof(*mode)); +} + +void +SDL_SetDesktopDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) +{ + SDL_memcpy(&display->desktop_mode, mode, sizeof(*mode)); +} + static int SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display) { @@ -843,6 +810,25 @@ SDL_GetNumDisplayModes(int displayIndex) return SDL_GetNumDisplayModesForDisplay(&_this->displays[displayIndex]); } +void +SDL_ResetDisplayModes(int displayIndex) +{ + SDL_VideoDisplay *display; + int i; + + CHECK_DISPLAY_INDEX(displayIndex,); + + display = &_this->displays[displayIndex]; + for (i = display->num_display_modes; i--;) { + SDL_free(display->display_modes[i].driverdata); + display->display_modes[i].driverdata = NULL; + } + SDL_free(display->display_modes); + display->display_modes = NULL; + display->num_display_modes = 0; + display->max_display_modes = 0; +} + int SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode) { @@ -900,7 +886,7 @@ SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display, SDL_DisplayMode *current, *match; if (!mode || !closest) { - SDL_SetError("Missing desired mode or closest mode parameter"); + SDL_InvalidParamError("mode/closest"); return NULL; } @@ -1014,6 +1000,7 @@ SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * { SDL_DisplayMode display_mode; SDL_DisplayMode current_mode; + int result; if (mode) { display_mode = *mode; @@ -1051,10 +1038,13 @@ SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * if (!_this->SetDisplayMode) { return SDL_SetError("SDL video driver doesn't support changing display mode"); } - if (_this->SetDisplayMode(_this, display, &display_mode) < 0) { + _this->setting_display_mode = SDL_TRUE; + result = _this->SetDisplayMode(_this, display, &display_mode); + _this->setting_display_mode = SDL_FALSE; + if (result < 0) { return -1; } - display->current_mode = display_mode; + SDL_SetCurrentDisplayMode(display, &display_mode); return 0; } @@ -1151,7 +1141,16 @@ SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode) if (FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { SDL_DisplayMode fullscreen_mode; if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { - SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode); + if (SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode) == 0) { +#ifndef ANDROID + /* Android may not resize the window to exactly what our fullscreen mode is, especially on + * windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't + * use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such, + * Android's SetWindowFullscreen will generate the window event for us with the proper final size. + */ + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, fullscreen_mode.w, fullscreen_mode.h); +#endif + } } } return 0; @@ -1194,6 +1193,16 @@ SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode) return 0; } +void* +SDL_GetWindowICCProfile(SDL_Window * window, size_t* size) +{ + if (!_this->GetWindowICCProfile) { + SDL_Unsupported(); + return NULL; + } + return _this->GetWindowICCProfile(_this, window, size); +} + Uint32 SDL_GetWindowPixelFormat(SDL_Window * window) { @@ -1347,11 +1356,11 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) /* Generate a mode change event here */ if (resized) { #ifndef ANDROID - // Android may not resize the window to exactly what our fullscreen mode is, especially on - // windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't - // use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such, - // Android's SetWindowFullscreen will generate the window event for us with the proper final size. - + /* Android may not resize the window to exactly what our fullscreen mode is, especially on + * windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't + * use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such, + * Android's SetWindowFullscreen will generate the window event for us with the proper final size. + */ SDL_SendWindowEvent(other, SDL_WINDOWEVENT_RESIZED, fullscreen_mode.w, fullscreen_mode.h); #endif @@ -1434,9 +1443,17 @@ SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags) if (flags & SDL_WINDOW_FULLSCREEN) { SDL_SetWindowFullscreen(window, flags); } - if (flags & SDL_WINDOW_INPUT_GRABBED) { + if (flags & SDL_WINDOW_MOUSE_GRABBED) { + /* We must specifically call SDL_SetWindowGrab() and not + SDL_SetWindowMouseGrab() here because older applications may use + this flag plus SDL_HINT_GRAB_KEYBOARD to indicate that they want + the keyboard grabbed too and SDL_SetWindowMouseGrab() won't do that. + */ SDL_SetWindowGrab(window, SDL_TRUE); } + if (flags & SDL_WINDOW_KEYBOARD_GRABBED) { + SDL_SetWindowKeyboardGrab(window, SDL_TRUE); + } if (!(flags & SDL_WINDOW_HIDDEN)) { SDL_ShowWindow(window); } @@ -1446,6 +1463,7 @@ SDL_Window * SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) { SDL_Window *window; + Uint32 graphics_flags = flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_METAL | SDL_WINDOW_VULKAN); if (!_this) { /* Initialize the video system if needed */ @@ -1473,12 +1491,20 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) return NULL; } - /* Some platforms have OpenGL enabled by default */ -#if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__ - if (!_this->is_dummy && !(flags & SDL_WINDOW_VULKAN) && !(flags & SDL_WINDOW_METAL) && !SDL_IsVideoContextExternal()) { - flags |= SDL_WINDOW_OPENGL; - } + /* Some platforms have certain graphics backends enabled by default */ + if (!graphics_flags && !SDL_IsVideoContextExternal()) { +#if (SDL_VIDEO_OPENGL && __MACOSX__) || (__IPHONEOS__ && !TARGET_OS_MACCATALYST) || __ANDROID__ || __NACL__ + if (_this->GL_CreateContext != NULL) { + flags |= SDL_WINDOW_OPENGL; + } #endif +#if SDL_VIDEO_METAL && (TARGET_OS_MACCATALYST || __MACOSX__ || __IPHONEOS__) + if (_this->Metal_CreateView != NULL) { + flags |= SDL_WINDOW_METAL; + } +#endif + } + if (flags & SDL_WINDOW_OPENGL) { if (!_this->GL_CreateContext) { SDL_SetError("OpenGL support is either not configured in SDL " @@ -1498,7 +1524,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) "(%s) or platform", _this->name); return NULL; } - if (flags & SDL_WINDOW_OPENGL) { + if (graphics_flags & SDL_WINDOW_OPENGL) { SDL_SetError("Vulkan and OpenGL not supported on same window"); return NULL; } @@ -1514,11 +1540,12 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) "(%s) or platform", _this->name); return NULL; } - if (flags & SDL_WINDOW_OPENGL) { + /* 'flags' may have default flags appended, don't check against that. */ + if (graphics_flags & SDL_WINDOW_OPENGL) { SDL_SetError("Metal and OpenGL not supported on same window"); return NULL; } - if (flags & SDL_WINDOW_VULKAN) { + if (graphics_flags & SDL_WINDOW_VULKAN) { SDL_SetError("Metal and Vulkan not supported on same window. " "To use MoltenVK, set SDL_WINDOW_VULKAN only."); return NULL; @@ -1573,6 +1600,22 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) displayIndex = SDL_GetIndexOfDisplay(display); SDL_GetDisplayBounds(displayIndex, &bounds); + /* for real fullscreen we might switch the resolution, so get width and height + * from closest supported mode and use that instead of current resolution + */ + if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP + && (bounds.w != w || bounds.h != h)) { + SDL_DisplayMode fullscreen_mode, closest_mode; + SDL_zero(fullscreen_mode); + fullscreen_mode.w = w; + fullscreen_mode.h = h; + if (SDL_GetClosestDisplayModeForDisplay(display, &fullscreen_mode, &closest_mode) != NULL) { + bounds.w = closest_mode.w; + bounds.h = closest_mode.h; + } + } + window->fullscreen_mode.w = bounds.w; + window->fullscreen_mode.h = bounds.h; window->x = bounds.x; window->y = bounds.y; window->w = bounds.w; @@ -1585,6 +1628,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) window->brightness = 1.0f; window->next = _this->windows; window->is_destroying = SDL_FALSE; + window->display_index = SDL_GetWindowDisplayIndex(window); if (_this->windows) { _this->windows->prev = window; @@ -1632,6 +1676,7 @@ SDL_Window * SDL_CreateWindowFrom(const void *data) { SDL_Window *window; + Uint32 flags = SDL_WINDOW_FOREIGN; if (!_this) { SDL_UninitializedVideo(); @@ -1641,6 +1686,37 @@ SDL_CreateWindowFrom(const void *data) SDL_Unsupported(); return NULL; } + + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL, SDL_FALSE)) { + if (!_this->GL_CreateContext) { + SDL_SetError("OpenGL support is either not configured in SDL " + "or not available in current SDL video driver " + "(%s) or platform", _this->name); + return NULL; + } + if (SDL_GL_LoadLibrary(NULL) < 0) { + return NULL; + } + flags |= SDL_WINDOW_OPENGL; + } + + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN, SDL_FALSE)) { + if (!_this->Vulkan_CreateSurface) { + SDL_SetError("Vulkan support is either not configured in SDL " + "or not available in current SDL video driver " + "(%s) or platform", _this->name); + return NULL; + } + if (flags & SDL_WINDOW_OPENGL) { + SDL_SetError("Vulkan and OpenGL not supported on same window"); + return NULL; + } + if (SDL_Vulkan_LoadLibrary(NULL) < 0) { + return NULL; + } + flags |= SDL_WINDOW_VULKAN; + } + window = (SDL_Window *)SDL_calloc(1, sizeof(*window)); if (!window) { SDL_OutOfMemory(); @@ -1648,7 +1724,7 @@ SDL_CreateWindowFrom(const void *data) } window->magic = &_this->window_magic; window->id = _this->next_object_id++; - window->flags = SDL_WINDOW_FOREIGN; + window->flags = flags; window->last_fullscreen_flags = window->flags; window->is_destroying = SDL_FALSE; window->opacity = 1.0f; @@ -1664,6 +1740,7 @@ SDL_CreateWindowFrom(const void *data) return NULL; } + window->display_index = SDL_GetWindowDisplayIndex(window); PrepareDragAndDropSupport(window); return window; @@ -1693,7 +1770,9 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) } /* Restore video mode, etc. */ - SDL_HideWindow(window); + if (!(window->flags & SDL_WINDOW_FOREIGN)) { + SDL_HideWindow(window); + } /* Tear down the old native window */ if (window->surface) { @@ -1702,9 +1781,13 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) window->surface = NULL; window->surface_valid = SDL_FALSE; } - if (_this->DestroyWindowFramebuffer) { - _this->DestroyWindowFramebuffer(_this, window); + + if (_this->checked_texture_framebuffer) { /* never checked? No framebuffer to destroy. Don't risk calling the wrong implementation. */ + if (_this->DestroyWindowFramebuffer) { + _this->DestroyWindowFramebuffer(_this, window); + } } + if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) { _this->DestroyWindow(_this, window); } @@ -1720,17 +1803,6 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) need_gl_load = SDL_TRUE; } - if ((window->flags & SDL_WINDOW_METAL) != (flags & SDL_WINDOW_METAL)) { - if (flags & SDL_WINDOW_METAL) { - need_gl_load = SDL_TRUE; - } else { - need_gl_unload = SDL_TRUE; - } - } else if (window->flags & SDL_WINDOW_METAL) { - need_gl_unload = SDL_TRUE; - need_gl_load = SDL_TRUE; - } - if ((window->flags & SDL_WINDOW_VULKAN) != (flags & SDL_WINDOW_VULKAN)) { if (flags & SDL_WINDOW_VULKAN) { need_vulkan_load = SDL_TRUE; @@ -1743,18 +1815,15 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) } if ((flags & SDL_WINDOW_VULKAN) && (flags & SDL_WINDOW_OPENGL)) { - SDL_SetError("Vulkan and OpenGL not supported on same window"); - return -1; + return SDL_SetError("Vulkan and OpenGL not supported on same window"); } if ((flags & SDL_WINDOW_METAL) && (flags & SDL_WINDOW_OPENGL)) { - SDL_SetError("Metal and OpenGL not supported on same window"); - return -1; + return SDL_SetError("Metal and OpenGL not supported on same window"); } if ((flags & SDL_WINDOW_METAL) && (flags & SDL_WINDOW_VULKAN)) { - SDL_SetError("Metal and Vulkan not supported on same window"); - return -1; + return SDL_SetError("Metal and Vulkan not supported on same window"); } if (need_gl_unload) { @@ -1987,10 +2056,10 @@ SDL_SetWindowPosition(SDL_Window * window, int x, int y) SDL_GetDisplayBounds(displayIndex, &bounds); if (SDL_WINDOWPOS_ISCENTERED(x)) { - x = bounds.x + (bounds.w - window->w) / 2; + x = bounds.x + (bounds.w - window->windowed.w) / 2; } if (SDL_WINDOWPOS_ISCENTERED(y)) { - y = bounds.y + (bounds.h - window->h) / 2; + y = bounds.y + (bounds.h - window->windowed.h) / 2; } } @@ -2093,6 +2162,25 @@ SDL_SetWindowResizable(SDL_Window * window, SDL_bool resizable) } } +void +SDL_SetWindowAlwaysOnTop(SDL_Window * window, SDL_bool on_top) +{ + CHECK_WINDOW_MAGIC(window,); + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + const int want = (on_top != SDL_FALSE); /* normalize the flag. */ + const int have = ((window->flags & SDL_WINDOW_ALWAYS_ON_TOP) != 0); + if ((want != have) && (_this->SetWindowAlwaysOnTop)) { + if (want) { + window->flags |= SDL_WINDOW_ALWAYS_ON_TOP; + } else { + window->flags &= ~SDL_WINDOW_ALWAYS_ON_TOP; + } + + _this->SetWindowAlwaysOnTop(_this, window, (SDL_bool) want); + } + } +} + void SDL_SetWindowSize(SDL_Window * window, int w, int h) { @@ -2129,12 +2217,14 @@ SDL_SetWindowSize(SDL_Window * window, int w, int h) SDL_UpdateFullscreenMode(window, SDL_TRUE); } } else { + int old_w = window->w; + int old_h = window->h; window->w = w; window->h = h; if (_this->SetWindowSize) { _this->SetWindowSize(_this, window); } - if (window->w == w && window->h == h) { + if (window->w != old_w || window->h != old_h) { /* We didn't get a SDL_WINDOWEVENT_RESIZED event (by design) */ SDL_OnWindowResized(window); } @@ -2395,18 +2485,63 @@ SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags) static SDL_Surface * SDL_CreateWindowFramebuffer(SDL_Window * window) { - Uint32 format; - void *pixels; - int pitch; + Uint32 format = 0; + void *pixels = NULL; + int pitch = 0; int bpp; Uint32 Rmask, Gmask, Bmask, Amask; + SDL_bool created_framebuffer = SDL_FALSE; - if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) { - return NULL; + /* This will switch the video backend from using a software surface to + using a GPU texture through the 2D render API, if we think this would + be more efficient. This only checks once, on demand. */ + if (!_this->checked_texture_framebuffer) { + SDL_bool attempt_texture_framebuffer = SDL_TRUE; + + if (_this->is_dummy) { /* dummy driver never has GPU support, of course. */ + attempt_texture_framebuffer = SDL_FALSE; + } + + #if defined(__WIN32__) /* GDI BitBlt() is way faster than Direct3D dynamic textures right now. (!!! FIXME: is this still true?) */ + else if ((_this->CreateWindowFramebuffer != NULL) && (SDL_strcmp(_this->name, "windows") == 0)) { + attempt_texture_framebuffer = SDL_FALSE; + } + #endif + #if defined(__EMSCRIPTEN__) + else { + attempt_texture_framebuffer = SDL_FALSE; + } + #endif + + if (attempt_texture_framebuffer) { + if (SDL_CreateWindowTexture(_this, window, &format, &pixels, &pitch) == -1) { + /* !!! FIXME: if this failed halfway (made renderer, failed to make texture, etc), + !!! FIXME: we probably need to clean this up so it doesn't interfere with + !!! FIXME: a software fallback at the system level (can we blit to an + !!! FIXME: OpenGL window? etc). */ + } else { + /* future attempts will just try to use a texture framebuffer. */ + /* !!! FIXME: maybe we shouldn't override these but check if we used a texture + !!! FIXME: framebuffer at the right places; is it feasible we could have an + !!! FIXME: accelerated OpenGL window and a second ends up in software? */ + _this->CreateWindowFramebuffer = SDL_CreateWindowTexture; + _this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture; + _this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture; + created_framebuffer = SDL_TRUE; + } + } + + _this->checked_texture_framebuffer = SDL_TRUE; /* don't check this again. */ } - if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) { - return NULL; + if (!created_framebuffer) { + if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) { + return NULL; + } + + if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) { + return NULL; + } } if (window->surface) { @@ -2464,6 +2599,8 @@ SDL_UpdateWindowSurfaceRects(SDL_Window * window, const SDL_Rect * rects, return SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface"); } + SDL_assert(_this->checked_texture_framebuffer); /* we should have done this before we had a valid surface. */ + return _this->UpdateWindowFramebuffer(_this, window, rects, numrects); } @@ -2635,31 +2772,46 @@ SDL_GetWindowGammaRamp(SDL_Window * window, Uint16 * red, void SDL_UpdateWindowGrab(SDL_Window * window) { - SDL_Window *grabbed_window; - SDL_bool grabbed; - if ((SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) && - (window->flags & SDL_WINDOW_INPUT_FOCUS)) { - grabbed = SDL_TRUE; + SDL_bool keyboard_grabbed, mouse_grabbed; + + if (window->flags & SDL_WINDOW_INPUT_FOCUS) { + if (SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_MOUSE_GRABBED)) { + mouse_grabbed = SDL_TRUE; + } else { + mouse_grabbed = SDL_FALSE; + } + + if (window->flags & SDL_WINDOW_KEYBOARD_GRABBED) { + keyboard_grabbed = SDL_TRUE; + } else { + keyboard_grabbed = SDL_FALSE; + } } else { - grabbed = SDL_FALSE; + mouse_grabbed = SDL_FALSE; + keyboard_grabbed = SDL_FALSE; } - grabbed_window = _this->grabbed_window; - if (grabbed) { - if (grabbed_window && (grabbed_window != window)) { + if (mouse_grabbed || keyboard_grabbed) { + if (_this->grabbed_window && (_this->grabbed_window != window)) { /* stealing a grab from another window! */ - grabbed_window->flags &= ~SDL_WINDOW_INPUT_GRABBED; - if (_this->SetWindowGrab) { - _this->SetWindowGrab(_this, grabbed_window, SDL_FALSE); + _this->grabbed_window->flags &= ~(SDL_WINDOW_MOUSE_GRABBED | SDL_WINDOW_KEYBOARD_GRABBED); + if (_this->SetWindowMouseGrab) { + _this->SetWindowMouseGrab(_this, _this->grabbed_window, SDL_FALSE); + } + if (_this->SetWindowKeyboardGrab) { + _this->SetWindowKeyboardGrab(_this, _this->grabbed_window, SDL_FALSE); } } _this->grabbed_window = window; - } else if (grabbed_window == window) { - _this->grabbed_window = NULL; /* ungrabbing. */ + } else if (_this->grabbed_window == window) { + _this->grabbed_window = NULL; /* ungrabbing input. */ } - if (_this->SetWindowGrab) { - _this->SetWindowGrab(_this, window, grabbed); + if (_this->SetWindowMouseGrab) { + _this->SetWindowMouseGrab(_this, window, mouse_grabbed); + } + if (_this->SetWindowKeyboardGrab) { + _this->SetWindowKeyboardGrab(_this, window, keyboard_grabbed); } } @@ -2668,30 +2820,117 @@ SDL_SetWindowGrab(SDL_Window * window, SDL_bool grabbed) { CHECK_WINDOW_MAGIC(window,); - if (!!grabbed == !!(window->flags & SDL_WINDOW_INPUT_GRABBED)) { + SDL_SetWindowMouseGrab(window, grabbed); + + if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) { + SDL_SetWindowKeyboardGrab(window, grabbed); + } +} + +void +SDL_SetWindowKeyboardGrab(SDL_Window * window, SDL_bool grabbed) +{ + CHECK_WINDOW_MAGIC(window,); + + if (!!grabbed == !!(window->flags & SDL_WINDOW_KEYBOARD_GRABBED)) { return; } if (grabbed) { - window->flags |= SDL_WINDOW_INPUT_GRABBED; + window->flags |= SDL_WINDOW_KEYBOARD_GRABBED; } else { - window->flags &= ~SDL_WINDOW_INPUT_GRABBED; + window->flags &= ~SDL_WINDOW_KEYBOARD_GRABBED; + } + SDL_UpdateWindowGrab(window); +} + +void +SDL_SetWindowMouseGrab(SDL_Window * window, SDL_bool grabbed) +{ + CHECK_WINDOW_MAGIC(window,); + + if (!!grabbed == !!(window->flags & SDL_WINDOW_MOUSE_GRABBED)) { + return; + } + if (grabbed) { + window->flags |= SDL_WINDOW_MOUSE_GRABBED; + } else { + window->flags &= ~SDL_WINDOW_MOUSE_GRABBED; } SDL_UpdateWindowGrab(window); } SDL_bool SDL_GetWindowGrab(SDL_Window * window) +{ + return (SDL_GetWindowKeyboardGrab(window) || SDL_GetWindowMouseGrab(window)); +} + +SDL_bool +SDL_GetWindowKeyboardGrab(SDL_Window * window) { CHECK_WINDOW_MAGIC(window, SDL_FALSE); - SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0)); - return window == _this->grabbed_window; + return window == _this->grabbed_window && + ((_this->grabbed_window->flags & SDL_WINDOW_KEYBOARD_GRABBED) != 0); +} + +SDL_bool +SDL_GetWindowMouseGrab(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, SDL_FALSE); + return window == _this->grabbed_window && + ((_this->grabbed_window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0); } SDL_Window * SDL_GetGrabbedWindow(void) { - SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0)); - return _this->grabbed_window; + if (_this->grabbed_window && + (_this->grabbed_window->flags & (SDL_WINDOW_MOUSE_GRABBED|SDL_WINDOW_KEYBOARD_GRABBED)) != 0) { + return _this->grabbed_window; + } else { + return NULL; + } +} + +int +SDL_SetWindowMouseRect(SDL_Window * window, const SDL_Rect * rect) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (rect) { + SDL_memcpy(&window->mouse_rect, rect, sizeof(*rect)); + } else { + SDL_zero(window->mouse_rect); + } + + if (_this->SetWindowMouseRect) { + _this->SetWindowMouseRect(_this, window); + } + return 0; +} + +const SDL_Rect * +SDL_GetWindowMouseRect(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, NULL); + + if (SDL_RectEmpty(&window->mouse_rect)) { + return NULL; + } else { + return &window->mouse_rect; + } +} + +int +SDL_FlashWindow(SDL_Window * window, SDL_FlashOperation operation) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (_this->FlashWindow) { + return _this->FlashWindow(_this, window, operation); + } + + return SDL_Unsupported(); } void @@ -2709,8 +2948,28 @@ SDL_OnWindowHidden(SDL_Window * window) void SDL_OnWindowResized(SDL_Window * window) { + int display_index = SDL_GetWindowDisplayIndex(window); window->surface_valid = SDL_FALSE; - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h); + + if (!window->is_destroying) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h); + + if (display_index != window->display_index && display_index != -1) { + window->display_index = display_index; + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_DISPLAY_CHANGED, window->display_index, 0); + } + } +} + +void +SDL_OnWindowMoved(SDL_Window * window) +{ + int display_index = SDL_GetWindowDisplayIndex(window); + + if (!window->is_destroying && display_index != window->display_index && display_index != -1) { + window->display_index = display_index; + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_DISPLAY_CHANGED, window->display_index, 0); + } } void @@ -2759,7 +3018,9 @@ SDL_OnWindowFocusGained(SDL_Window * window) if (mouse && mouse->relative_mode) { SDL_SetMouseFocus(window); - SDL_WarpMouseInWindow(window, window->w/2, window->h/2); + if (mouse->relative_mode_warp) { + SDL_WarpMouseInWindow(window, window->w/2, window->h/2); + } } SDL_UpdateWindowGrab(window); @@ -2768,6 +3029,8 @@ SDL_OnWindowFocusGained(SDL_Window * window) static SDL_bool ShouldMinimizeOnFocusLoss(SDL_Window * window) { + const char *hint; + if (!(window->flags & SDL_WINDOW_FULLSCREEN) || window->is_destroying) { return SDL_FALSE; } @@ -2783,12 +3046,21 @@ ShouldMinimizeOnFocusLoss(SDL_Window * window) #ifdef __ANDROID__ { extern SDL_bool Android_JNI_ShouldMinimizeOnFocusLoss(void); - if (! Android_JNI_ShouldMinimizeOnFocusLoss()) { + if (!Android_JNI_ShouldMinimizeOnFocusLoss()) { return SDL_FALSE; } } #endif + /* Real fullscreen windows should minimize on focus loss so the desktop video mode is restored */ + hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS); + if (!hint || !*hint || SDL_strcasecmp(hint, "auto") == 0) { + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { + return SDL_FALSE; + } else { + return SDL_TRUE; + } + } return SDL_GetHintBoolean(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_FALSE); } @@ -2834,7 +3106,9 @@ SDL_DestroyWindow(SDL_Window * window) window->is_destroying = SDL_TRUE; /* Restore video mode, etc. */ - SDL_HideWindow(window); + if (!(window->flags & SDL_WINDOW_FOREIGN)) { + SDL_HideWindow(window); + } /* Make sure this window no longer has focus */ if (SDL_GetKeyboardFocus() == window) { @@ -2857,8 +3131,10 @@ SDL_DestroyWindow(SDL_Window * window) window->surface = NULL; window->surface_valid = SDL_FALSE; } - if (_this->DestroyWindowFramebuffer) { - _this->DestroyWindowFramebuffer(_this, window); + if (_this->checked_texture_framebuffer) { /* never checked? No framebuffer to destroy. Don't risk calling the wrong implementation. */ + if (_this->DestroyWindowFramebuffer) { + _this->DestroyWindowFramebuffer(_this, window); + } } if (_this->DestroyWindow) { _this->DestroyWindow(_this, window); @@ -2945,7 +3221,7 @@ SDL_DisableScreenSaver() void SDL_VideoQuit(void) { - int i, j; + int i; if (!_this) { return; @@ -2967,12 +3243,7 @@ SDL_VideoQuit(void) for (i = 0; i < _this->num_displays; ++i) { SDL_VideoDisplay *display = &_this->displays[i]; - for (j = display->num_display_modes; j--;) { - SDL_free(display->display_modes[j].driverdata); - display->display_modes[j].driverdata = NULL; - } - SDL_free(display->display_modes); - display->display_modes = NULL; + SDL_ResetDisplayModes(i); SDL_free(display->desktop_mode.driverdata); display->desktop_mode.driverdata = NULL; SDL_free(display->driverdata); @@ -3568,10 +3839,23 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) } if (attachmentattrib && isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) { - glGetFramebufferAttachmentParameterivFunc = SDL_GL_GetProcAddress("glGetFramebufferAttachmentParameteriv"); + /* glGetFramebufferAttachmentParameteriv needs to operate on the window framebuffer for this, so bind FBO 0 if necessary. */ + GLint current_fbo = 0; + void (APIENTRY *glGetIntegervFunc) (GLenum pname, GLint * params) = SDL_GL_GetProcAddress("glGetIntegerv"); + void (APIENTRY *glBindFramebufferFunc) (GLenum target, GLuint fbo) = SDL_GL_GetProcAddress("glBindFramebuffer"); + if (glGetIntegervFunc && glBindFramebufferFunc) { + glGetIntegervFunc(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); + } + glGetFramebufferAttachmentParameterivFunc = SDL_GL_GetProcAddress("glGetFramebufferAttachmentParameteriv"); if (glGetFramebufferAttachmentParameterivFunc) { + if (glBindFramebufferFunc && (current_fbo != 0)) { + glBindFramebufferFunc(GL_DRAW_FRAMEBUFFER, 0); + } glGetFramebufferAttachmentParameterivFunc(GL_FRAMEBUFFER, attachment, attachmentattrib, (GLint *) value); + if (glBindFramebufferFunc && (current_fbo != 0)) { + glBindFramebufferFunc(GL_DRAW_FRAMEBUFFER, current_fbo); + } } else { return -1; } @@ -3892,6 +4176,24 @@ SDL_StartTextInput(void) } } +void +SDL_ClearComposition(void) +{ + if (_this && _this->ClearComposition) { + _this->ClearComposition(_this); + } +} + +SDL_bool +SDL_IsTextInputShown(void) +{ + if (_this && _this->IsTextInputShown) { + return _this->IsTextInputShown(_this); + } + + return SDL_FALSE; +} + SDL_bool SDL_IsTextInputActive(void) { @@ -3960,6 +4262,9 @@ SDL_IsScreenKeyboardShown(SDL_Window *window) #if SDL_VIDEO_DRIVER_UIKIT #include "uikit/SDL_uikitmessagebox.h" #endif +#if SDL_VIDEO_DRIVER_WAYLAND +#include "wayland/SDL_waylandmessagebox.h" +#endif #if SDL_VIDEO_DRIVER_X11 #include "x11/SDL_x11messagebox.h" #endif @@ -3969,8 +4274,14 @@ SDL_IsScreenKeyboardShown(SDL_Window *window) #if SDL_VIDEO_DRIVER_OS2 #include "os2/SDL_os2messagebox.h" #endif +#if SDL_VIDEO_DRIVER_RISCOS +#include "riscos/SDL_riscosmessagebox.h" +#endif +#if SDL_VIDEO_DRIVER_VITA +#include "vita/SDL_vitamessagebox.h" +#endif -#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2 +#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2 || SDL_VIDEO_DRIVER_RISCOS static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype) { SDL_SysWMinfo info; @@ -4023,6 +4334,8 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) if (!mbdata.message) mbdata.message = ""; messageboxdata = &mbdata; + SDL_ClearError(); + if (_this && _this->ShowMessageBox) { retval = _this->ShowMessageBox(_this, messageboxdata, buttonid); } @@ -4062,6 +4375,13 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) retval = 0; } #endif +#if SDL_VIDEO_DRIVER_WAYLAND + if (retval == -1 && + SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WAYLAND) && + Wayland_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } +#endif #if SDL_VIDEO_DRIVER_X11 if (retval == -1 && SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_X11) && @@ -4082,9 +4402,26 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) OS2_ShowMessageBox(messageboxdata, buttonid) == 0) { retval = 0; } +#endif +#if SDL_VIDEO_DRIVER_RISCOS + if (retval == -1 && + SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_RISCOS) && + RISCOS_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } +#endif +#if SDL_VIDEO_DRIVER_VITA + if (retval == -1 && + VITA_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } #endif if (retval == -1) { - SDL_SetError("No message system available"); + const char *error = SDL_GetError(); + + if (!*error) { + SDL_SetError("No message system available"); + } } if (current_window) { diff --git a/Engine/lib/sdl/src/video/SDL_vulkan_internal.h b/Engine/lib/sdl/src/video/SDL_vulkan_internal.h index bc49ec44e..1ec1ab473 100644 --- a/Engine/lib/sdl/src/video/SDL_vulkan_internal.h +++ b/Engine/lib/sdl/src/video/SDL_vulkan_internal.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,12 +25,10 @@ #include "SDL_stdinc.h" -#if defined(SDL_LOADSO_DISABLED) -#undef SDL_VIDEO_VULKAN -#define SDL_VIDEO_VULKAN 0 -#endif - #if SDL_VIDEO_VULKAN +#if SDL_LOADSO_DISABLED || SDL_LOADSO_DUMMY +#error You should not be here. +#endif #if SDL_VIDEO_DRIVER_ANDROID #define VK_USE_PLATFORM_ANDROID_KHR diff --git a/Engine/lib/sdl/src/video/SDL_vulkan_utils.c b/Engine/lib/sdl/src/video/SDL_vulkan_utils.c index df49da72e..33761a591 100644 --- a/Engine/lib/sdl/src/video/SDL_vulkan_utils.c +++ b/Engine/lib/sdl/src/video/SDL_vulkan_utils.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,97 +23,97 @@ #include "SDL_vulkan_internal.h" #include "SDL_error.h" -/* !!! FIXME: this file doesn't match coding standards for SDL (brace position, etc). */ - #if SDL_VIDEO_VULKAN const char *SDL_Vulkan_GetResultString(VkResult result) { - switch((int)result) - { - case VK_SUCCESS: - return "VK_SUCCESS"; - case VK_NOT_READY: - return "VK_NOT_READY"; - case VK_TIMEOUT: - return "VK_TIMEOUT"; - case VK_EVENT_SET: - return "VK_EVENT_SET"; - case VK_EVENT_RESET: - return "VK_EVENT_RESET"; - case VK_INCOMPLETE: - return "VK_INCOMPLETE"; - case VK_ERROR_OUT_OF_HOST_MEMORY: - return "VK_ERROR_OUT_OF_HOST_MEMORY"; - case VK_ERROR_OUT_OF_DEVICE_MEMORY: - return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; - case VK_ERROR_INITIALIZATION_FAILED: - return "VK_ERROR_INITIALIZATION_FAILED"; - case VK_ERROR_DEVICE_LOST: - return "VK_ERROR_DEVICE_LOST"; - case VK_ERROR_MEMORY_MAP_FAILED: - return "VK_ERROR_MEMORY_MAP_FAILED"; - case VK_ERROR_LAYER_NOT_PRESENT: - return "VK_ERROR_LAYER_NOT_PRESENT"; - case VK_ERROR_EXTENSION_NOT_PRESENT: - return "VK_ERROR_EXTENSION_NOT_PRESENT"; - case VK_ERROR_FEATURE_NOT_PRESENT: - return "VK_ERROR_FEATURE_NOT_PRESENT"; - case VK_ERROR_INCOMPATIBLE_DRIVER: - return "VK_ERROR_INCOMPATIBLE_DRIVER"; - case VK_ERROR_TOO_MANY_OBJECTS: - return "VK_ERROR_TOO_MANY_OBJECTS"; - case VK_ERROR_FORMAT_NOT_SUPPORTED: - return "VK_ERROR_FORMAT_NOT_SUPPORTED"; - case VK_ERROR_FRAGMENTED_POOL: - return "VK_ERROR_FRAGMENTED_POOL"; - case VK_ERROR_UNKNOWN: - return "VK_ERROR_UNKNOWN"; - case VK_ERROR_OUT_OF_POOL_MEMORY: - return "VK_ERROR_OUT_OF_POOL_MEMORY"; - case VK_ERROR_INVALID_EXTERNAL_HANDLE: - return "VK_ERROR_INVALID_EXTERNAL_HANDLE"; - case VK_ERROR_FRAGMENTATION: - return "VK_ERROR_FRAGMENTATION"; - case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: - return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case VK_ERROR_SURFACE_LOST_KHR: - return "VK_ERROR_SURFACE_LOST_KHR"; - case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: - return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; - case VK_SUBOPTIMAL_KHR: - return "VK_SUBOPTIMAL_KHR"; - case VK_ERROR_OUT_OF_DATE_KHR: - return "VK_ERROR_OUT_OF_DATE_KHR"; - case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: - return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; - case VK_ERROR_VALIDATION_FAILED_EXT: - return "VK_ERROR_VALIDATION_FAILED_EXT"; - case VK_ERROR_INVALID_SHADER_NV: - return "VK_ERROR_INVALID_SHADER_NV"; - case VK_ERROR_INCOMPATIBLE_VERSION_KHR: - return "VK_ERROR_INCOMPATIBLE_VERSION_KHR"; - case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: - return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; - case VK_ERROR_NOT_PERMITTED_EXT: - return "VK_ERROR_NOT_PERMITTED_EXT"; - case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT: - return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT"; - case VK_THREAD_IDLE_KHR: - return "VK_THREAD_IDLE_KHR"; - case VK_THREAD_DONE_KHR: - return "VK_THREAD_DONE_KHR"; - case VK_OPERATION_DEFERRED_KHR: - return "VK_OPERATION_DEFERRED_KHR"; - case VK_OPERATION_NOT_DEFERRED_KHR: - return "VK_OPERATION_NOT_DEFERRED_KHR"; - case VK_PIPELINE_COMPILE_REQUIRED_EXT: - return "VK_PIPELINE_COMPILE_REQUIRED_EXT"; - default: - break; + switch ((int)result) { + case VK_SUCCESS: + return "VK_SUCCESS"; + case VK_NOT_READY: + return "VK_NOT_READY"; + case VK_TIMEOUT: + return "VK_TIMEOUT"; + case VK_EVENT_SET: + return "VK_EVENT_SET"; + case VK_EVENT_RESET: + return "VK_EVENT_RESET"; + case VK_INCOMPLETE: + return "VK_INCOMPLETE"; + case VK_ERROR_OUT_OF_HOST_MEMORY: + return "VK_ERROR_OUT_OF_HOST_MEMORY"; + case VK_ERROR_OUT_OF_DEVICE_MEMORY: + return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; + case VK_ERROR_INITIALIZATION_FAILED: + return "VK_ERROR_INITIALIZATION_FAILED"; + case VK_ERROR_DEVICE_LOST: + return "VK_ERROR_DEVICE_LOST"; + case VK_ERROR_MEMORY_MAP_FAILED: + return "VK_ERROR_MEMORY_MAP_FAILED"; + case VK_ERROR_LAYER_NOT_PRESENT: + return "VK_ERROR_LAYER_NOT_PRESENT"; + case VK_ERROR_EXTENSION_NOT_PRESENT: + return "VK_ERROR_EXTENSION_NOT_PRESENT"; + case VK_ERROR_FEATURE_NOT_PRESENT: + return "VK_ERROR_FEATURE_NOT_PRESENT"; + case VK_ERROR_INCOMPATIBLE_DRIVER: + return "VK_ERROR_INCOMPATIBLE_DRIVER"; + case VK_ERROR_TOO_MANY_OBJECTS: + return "VK_ERROR_TOO_MANY_OBJECTS"; + case VK_ERROR_FORMAT_NOT_SUPPORTED: + return "VK_ERROR_FORMAT_NOT_SUPPORTED"; + case VK_ERROR_FRAGMENTED_POOL: + return "VK_ERROR_FRAGMENTED_POOL"; + case VK_ERROR_UNKNOWN: + return "VK_ERROR_UNKNOWN"; + case VK_ERROR_OUT_OF_POOL_MEMORY: + return "VK_ERROR_OUT_OF_POOL_MEMORY"; + case VK_ERROR_INVALID_EXTERNAL_HANDLE: + return "VK_ERROR_INVALID_EXTERNAL_HANDLE"; + case VK_ERROR_FRAGMENTATION: + return "VK_ERROR_FRAGMENTATION"; + case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: + return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; + case VK_ERROR_SURFACE_LOST_KHR: + return "VK_ERROR_SURFACE_LOST_KHR"; + case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: + return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; + case VK_SUBOPTIMAL_KHR: + return "VK_SUBOPTIMAL_KHR"; + case VK_ERROR_OUT_OF_DATE_KHR: + return "VK_ERROR_OUT_OF_DATE_KHR"; + case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: + return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; + case VK_ERROR_VALIDATION_FAILED_EXT: + return "VK_ERROR_VALIDATION_FAILED_EXT"; + case VK_ERROR_INVALID_SHADER_NV: + return "VK_ERROR_INVALID_SHADER_NV"; +#if VK_HEADER_VERSION >= 135 && VK_HEADER_VERSION < 162 + case VK_ERROR_INCOMPATIBLE_VERSION_KHR: + return "VK_ERROR_INCOMPATIBLE_VERSION_KHR"; +#endif + case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: + return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; + case VK_ERROR_NOT_PERMITTED_EXT: + return "VK_ERROR_NOT_PERMITTED_EXT"; + case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT: + return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT"; + case VK_THREAD_IDLE_KHR: + return "VK_THREAD_IDLE_KHR"; + case VK_THREAD_DONE_KHR: + return "VK_THREAD_DONE_KHR"; + case VK_OPERATION_DEFERRED_KHR: + return "VK_OPERATION_DEFERRED_KHR"; + case VK_OPERATION_NOT_DEFERRED_KHR: + return "VK_OPERATION_NOT_DEFERRED_KHR"; + case VK_PIPELINE_COMPILE_REQUIRED_EXT: + return "VK_PIPELINE_COMPILE_REQUIRED_EXT"; + default: + break; } - if(result < 0) + if (result < 0) { return "VK_ERROR_"; + } return "VK_"; } @@ -124,11 +124,9 @@ VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList( Uint32 count = 0; VkResult result = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL); VkExtensionProperties *retval; - if(result == VK_ERROR_INCOMPATIBLE_DRIVER) - { - /* Avoid the ERR_MAX_STRLEN limit by passing part of the message - * as a string argument. - */ + + if (result == VK_ERROR_INCOMPATIBLE_DRIVER) { + /* Avoid the ERR_MAX_STRLEN limit by passing part of the message as a string argument. */ SDL_SetError( "You probably don't have a working Vulkan driver installed. %s %s %s(%d)", "Getting Vulkan extensions failed:", @@ -136,9 +134,7 @@ VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList( SDL_Vulkan_GetResultString(result), (int)result); return NULL; - } - else if(result != VK_SUCCESS) - { + } else if (result != VK_SUCCESS) { SDL_SetError( "Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned " "%s(%d)", @@ -146,22 +142,20 @@ VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList( (int)result); return NULL; } - if(count == 0) - { + + if (count == 0) { retval = SDL_calloc(1, sizeof(VkExtensionProperties)); // so we can return non-null - } - else - { + } else { retval = SDL_calloc(count, sizeof(VkExtensionProperties)); } - if(!retval) - { + + if (!retval) { SDL_OutOfMemory(); return NULL; } + result = vkEnumerateInstanceExtensionProperties(NULL, &count, retval); - if(result != VK_SUCCESS) - { + if (result != VK_SUCCESS) { SDL_SetError( "Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned " "%s(%d)", @@ -186,6 +180,7 @@ SDL_bool SDL_Vulkan_GetInstanceExtensions_Helper(unsigned *userCount, SDL_SetError("Output array for SDL_Vulkan_GetInstanceExtensions needs to be at least %d big", nameCount); return SDL_FALSE; } + for (i = 0; i < nameCount; i++) { userNames[i] = names[i]; } @@ -226,55 +221,47 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, const char *chosenDisplayId; int displayId = 0; /* Counting from physical device 0, display 0 */ - if(!vkEnumeratePhysicalDevices || + if (!vkEnumeratePhysicalDevices || !vkGetPhysicalDeviceDisplayPropertiesKHR || !vkGetDisplayModePropertiesKHR || !vkGetPhysicalDeviceDisplayPlanePropertiesKHR || !vkGetDisplayPlaneCapabilitiesKHR || !vkGetDisplayPlaneSupportedDisplaysKHR || - !vkCreateDisplayPlaneSurfaceKHR) - { - SDL_SetError(VK_KHR_DISPLAY_EXTENSION_NAME - " extension is not enabled in the Vulkan instance."); + !vkCreateDisplayPlaneSurfaceKHR) { + SDL_SetError(VK_KHR_DISPLAY_EXTENSION_NAME " extension is not enabled in the Vulkan instance."); goto error; } - if ((chosenDisplayId = SDL_getenv("SDL_VULKAN_DISPLAY")) != NULL) - { + if ((chosenDisplayId = SDL_getenv("SDL_VULKAN_DISPLAY")) != NULL) { displayId = SDL_atoi(chosenDisplayId); } /* Enumerate physical devices */ - result = - vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, NULL); - if(result != VK_SUCCESS) - { + result = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, NULL); + if (result != VK_SUCCESS) { SDL_SetError("Could not enumerate Vulkan physical devices"); goto error; } - if(physicalDeviceCount == 0) - { + + if (physicalDeviceCount == 0) { SDL_SetError("No Vulkan physical devices"); goto error; } + physicalDevices = SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount); - if(!physicalDevices) - { + if (!physicalDevices) { SDL_OutOfMemory(); goto error; } - result = - vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices); - if(result != VK_SUCCESS) - { + + result = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices); + if (result != VK_SUCCESS) { SDL_SetError("Error enumerating physical devices"); goto error; } - for(physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount; - physicalDeviceIndex++) - { - VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex]; + for (physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount; physicalDeviceIndex++) { + VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex]; uint32_t displayPropertiesCount = 0; VkDisplayPropertiesKHR *displayProperties = NULL; uint32_t displayModePropertiesCount = 0; @@ -290,32 +277,27 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, VkDisplayPlaneCapabilitiesKHR planeCaps; /* Get information about the physical displays */ - result = - vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, NULL); - if (result != VK_SUCCESS || displayPropertiesCount == 0) - { + result = vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, NULL); + if (result != VK_SUCCESS || displayPropertiesCount == 0) { /* This device has no physical device display properties, move on to next. */ continue; } SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of display properties for device %u: %u", physicalDeviceIndex, displayPropertiesCount); - if ( (displayId < 0) || (((uint32_t) displayId) >= displayPropertiesCount) ) - { + if (displayId < 0 || (uint32_t) displayId >= displayPropertiesCount) { /* Display id specified was higher than number of available displays, move to next physical device. */ displayId -= displayPropertiesCount; continue; } displayProperties = SDL_malloc(sizeof(VkDisplayPropertiesKHR) * displayPropertiesCount); - if(!displayProperties) - { + if (!displayProperties) { SDL_OutOfMemory(); goto error; } - result = - vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, displayProperties); + result = vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, displayProperties); if (result != VK_SUCCESS || displayPropertiesCount == 0) { SDL_free(displayProperties); SDL_SetError("Error enumerating physical device displays"); @@ -331,8 +313,7 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, displayProperties = NULL; /* Get display mode properties for the chosen display */ - result = - vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, NULL); + result = vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, NULL); if (result != VK_SUCCESS || displayModePropertiesCount == 0) { SDL_SetError("Error enumerating display modes"); @@ -341,14 +322,12 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of display modes: %u", displayModePropertiesCount); displayModeProperties = SDL_malloc(sizeof(VkDisplayModePropertiesKHR) * displayModePropertiesCount); - if(!displayModeProperties) - { + if (!displayModeProperties) { SDL_OutOfMemory(); goto error; } - result = - vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, displayModeProperties); + result = vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, displayModeProperties); if (result != VK_SUCCESS || displayModePropertiesCount == 0) { SDL_SetError("Error enumerating display modes"); SDL_free(displayModeProperties); @@ -356,18 +335,16 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, } /* Try to find a display mode that matches the native resolution */ - for (i = 0; i < displayModePropertiesCount; ++i) - { + for (i = 0; i < displayModePropertiesCount; ++i) { if (displayModeProperties[i].parameters.visibleRegion.width == extent.width && displayModeProperties[i].parameters.visibleRegion.height == extent.height && - displayModeProperties[i].parameters.refreshRate > refreshRate) - { + displayModeProperties[i].parameters.refreshRate > refreshRate) { bestMatchIndex = i; refreshRate = displayModeProperties[i].parameters.refreshRate; } } - if (bestMatchIndex < 0) - { + + if (bestMatchIndex < 0) { SDL_SetError("Found no matching display mode"); SDL_free(displayModeProperties); goto error; @@ -384,62 +361,53 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, displayModeProperties = NULL; /* Try to find a plane index that supports our display */ - result = - vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, NULL); - if (result != VK_SUCCESS || displayPlanePropertiesCount == 0) - { + result = vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, NULL); + if (result != VK_SUCCESS || displayPlanePropertiesCount == 0) { SDL_SetError("Error enumerating display planes"); goto error; } SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of display planes: %u", displayPlanePropertiesCount); displayPlaneProperties = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * displayPlanePropertiesCount); - if(!displayPlaneProperties) - { + if (!displayPlaneProperties) { SDL_OutOfMemory(); goto error; } - result = - vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, displayPlaneProperties); - if (result != VK_SUCCESS || displayPlanePropertiesCount == 0) - { + result = vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, displayPlaneProperties); + if (result != VK_SUCCESS || displayPlanePropertiesCount == 0) { SDL_SetError("Error enumerating display plane properties"); SDL_free(displayPlaneProperties); goto error; } - for (i = 0; i < displayPlanePropertiesCount; ++i) - { + for (i = 0; i < displayPlanePropertiesCount; ++i) { uint32_t planeSupportedDisplaysCount = 0; VkDisplayKHR *planeSupportedDisplays = NULL; uint32_t j; /* Check if plane is attached to a display, if not, continue. */ - if (displayPlaneProperties[i].currentDisplay == VK_NULL_HANDLE) + if (displayPlaneProperties[i].currentDisplay == VK_NULL_HANDLE) { continue; + } /* Check supported displays for this plane. */ - result = - vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, NULL); - if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0) - { + result = vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, NULL); + if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0) { continue; /* No supported displays, on to next plane. */ } + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of supported displays for plane %u: %u", i, planeSupportedDisplaysCount); planeSupportedDisplays = SDL_malloc(sizeof(VkDisplayKHR) * planeSupportedDisplaysCount); - if(!planeSupportedDisplays) - { + if (!planeSupportedDisplays) { SDL_free(displayPlaneProperties); SDL_OutOfMemory(); goto error; } - result = - vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, planeSupportedDisplays); - if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0) - { + result = vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, planeSupportedDisplays); + if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0) { SDL_SetError("Error enumerating supported displays, or no supported displays"); SDL_free(planeSupportedDisplays); SDL_free(displayPlaneProperties); @@ -447,20 +415,19 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, } for (j = 0; j < planeSupportedDisplaysCount && planeSupportedDisplays[j] != display; ++j) - ; + { + } SDL_free(planeSupportedDisplays); planeSupportedDisplays = NULL; - if (j == planeSupportedDisplaysCount) - { + if (j == planeSupportedDisplaysCount) { /* This display is not supported for this plane, move on. */ continue; } result = vkGetDisplayPlaneCapabilitiesKHR(physicalDevice, createInfo.displayMode, i, &planeCaps); - if (result != VK_SUCCESS) - { + if (result != VK_SUCCESS) { SDL_SetError("Error getting display plane capabilities"); SDL_free(displayPlaneProperties); goto error; @@ -468,8 +435,7 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, /* Check if plane fulfills extent requirements. */ if (extent.width >= planeCaps.minDstExtent.width && extent.height >= planeCaps.minDstExtent.height && - extent.width <= planeCaps.maxDstExtent.width && extent.height <= planeCaps.maxDstExtent.height) - { + extent.width <= planeCaps.maxDstExtent.width && extent.height <= planeCaps.maxDstExtent.height) { /* If it does, choose this plane. */ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Choosing plane %d, minimum extent %dx%d maximum extent %dx%d", i, planeCaps.minDstExtent.width, planeCaps.minDstExtent.height, @@ -479,8 +445,7 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, } } - if (planeIndex < 0) - { + if (planeIndex < 0) { SDL_SetError("No plane supports the selected resolution"); SDL_free(displayPlaneProperties); goto error; @@ -509,8 +474,7 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, SDL_free(physicalDevices); physicalDevices = NULL; - if (physicalDeviceIndex == physicalDeviceCount) - { + if (physicalDeviceIndex == physicalDeviceCount) { SDL_SetError("No usable displays found or requested display out of range"); return SDL_FALSE; } @@ -519,16 +483,14 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, createInfo.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; createInfo.globalAlpha = 1.0f; - result = vkCreateDisplayPlaneSurfaceKHR(instance, &createInfo, - NULL, surface); - if(result != VK_SUCCESS) - { - SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s", - SDL_Vulkan_GetResultString(result)); + result = vkCreateDisplayPlaneSurfaceKHR(instance, &createInfo, NULL, surface); + if (result != VK_SUCCESS) { + SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result)); return SDL_FALSE; } SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Created surface"); return SDL_TRUE; + error: SDL_free(physicalDevices); return SDL_FALSE; diff --git a/Engine/lib/sdl/src/video/SDL_yuv.c b/Engine/lib/sdl/src/video/SDL_yuv.c index 4b9755dbe..72ed99d18 100644 --- a/Engine/lib/sdl/src/video/SDL_yuv.c +++ b/Engine/lib/sdl/src/video/SDL_yuv.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -1839,7 +1839,7 @@ SDL_ConvertPixels_YUV_to_YUV(int width, int height, return SDL_SetError("SDL_ConvertPixels_YUV_to_YUV: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format)); } #else - return SDL_SetError("SDL not built with YUV support"); + return SDL_SetError("SDL not built with YUV support"); #endif } diff --git a/Engine/lib/sdl/src/video/SDL_yuv_c.h b/Engine/lib/sdl/src/video/SDL_yuv_c.h index 9b43631b9..d4e2c9108 100644 --- a/Engine/lib/sdl/src/video/SDL_yuv_c.h +++ b/Engine/lib/sdl/src/video/SDL_yuv_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidclipboard.c b/Engine/lib/sdl/src/video/android/SDL_androidclipboard.c index 19c2262f7..42460d723 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidclipboard.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidclipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidclipboard.h b/Engine/lib/sdl/src/video/android/SDL_androidclipboard.h index 94c66742b..9e6ce60d6 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidclipboard.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidevents.c b/Engine/lib/sdl/src/video/android/SDL_androidevents.c index dfd62123d..3424a8254 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidevents.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -48,6 +48,18 @@ static void openslES_ResumeDevices(void) {} static void openslES_PauseDevices(void) {} #endif +#if !SDL_AUDIO_DISABLED && SDL_AUDIO_DRIVER_AAUDIO +extern void aaudio_ResumeDevices(void); +extern void aaudio_PauseDevices(void); +SDL_bool aaudio_DetectBrokenPlayState( void ); +#else +static void aaudio_ResumeDevices(void) {} +static void aaudio_PauseDevices(void) {} +static SDL_bool aaudio_DetectBrokenPlayState( void ) { return SDL_FALSE; } +#endif + + + /* Number of 'type' events in the event queue */ static int SDL_NumberOfEvents(Uint32 type) @@ -55,6 +67,7 @@ SDL_NumberOfEvents(Uint32 type) return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type); } +#if SDL_VIDEO_OPENGL_EGL static void android_egl_context_restore(SDL_Window *window) { @@ -84,7 +97,7 @@ android_egl_context_backup(SDL_Window *window) data->backup_done = 1; } } - +#endif /* * Android_ResumeSem and Android_PauseSem are signaled from Java_org_libsdl_app_SDLActivity_nativePause and Java_org_libsdl_app_SDLActivity_nativeResume @@ -101,15 +114,18 @@ Android_PumpEvents_Blocking(_THIS) if (videodata->isPaused) { SDL_bool isContextExternal = SDL_IsVideoContextExternal(); +#if SDL_VIDEO_OPENGL_EGL /* Make sure this is the last thing we do before pausing */ if (!isContextExternal) { SDL_LockMutex(Android_ActivityMutex); android_egl_context_backup(Android_Window); SDL_UnlockMutex(Android_ActivityMutex); } +#endif ANDROIDAUDIO_PauseDevices(); openslES_PauseDevices(); + aaudio_PauseDevices(); if (SDL_SemWait(Android_ResumeSem) == 0) { @@ -122,13 +138,16 @@ Android_PumpEvents_Blocking(_THIS) ANDROIDAUDIO_ResumeDevices(); openslES_ResumeDevices(); + aaudio_ResumeDevices(); /* Restore the GL Context from here, as this operation is thread dependent */ +#if SDL_VIDEO_OPENGL_EGL if (!isContextExternal && !SDL_HasEvent(SDL_QUIT)) { SDL_LockMutex(Android_ActivityMutex); android_egl_context_restore(Android_Window); SDL_UnlockMutex(Android_ActivityMutex); } +#endif /* Make sure SW Keyboard is restored when an app becomes foreground */ if (SDL_IsTextInputActive()) { @@ -156,6 +175,11 @@ Android_PumpEvents_Blocking(_THIS) } } } + + if ( aaudio_DetectBrokenPlayState() ) { + aaudio_PauseDevices(); + aaudio_ResumeDevices(); + } } void @@ -169,15 +193,18 @@ Android_PumpEvents_NonBlocking(_THIS) SDL_bool isContextExternal = SDL_IsVideoContextExternal(); if (backup_context) { +#if SDL_VIDEO_OPENGL_EGL if (!isContextExternal) { SDL_LockMutex(Android_ActivityMutex); android_egl_context_backup(Android_Window); SDL_UnlockMutex(Android_ActivityMutex); } +#endif if (videodata->pauseAudio) { ANDROIDAUDIO_PauseDevices(); openslES_PauseDevices(); + aaudio_PauseDevices(); } backup_context = 0; @@ -196,14 +223,17 @@ Android_PumpEvents_NonBlocking(_THIS) if (videodata->pauseAudio) { ANDROIDAUDIO_ResumeDevices(); openslES_ResumeDevices(); + aaudio_ResumeDevices(); } +#if SDL_VIDEO_OPENGL_EGL /* Restore the GL Context from here, as this operation is thread dependent */ if (!isContextExternal && !SDL_HasEvent(SDL_QUIT)) { SDL_LockMutex(Android_ActivityMutex); android_egl_context_restore(Android_Window); SDL_UnlockMutex(Android_ActivityMutex); } +#endif /* Make sure SW Keyboard is restored when an app becomes foreground */ if (SDL_IsTextInputActive()) { @@ -232,6 +262,11 @@ Android_PumpEvents_NonBlocking(_THIS) } } } + + if ( aaudio_DetectBrokenPlayState() ) { + aaudio_PauseDevices(); + aaudio_ResumeDevices(); + } } #endif /* SDL_VIDEO_DRIVER_ANDROID */ diff --git a/Engine/lib/sdl/src/video/android/SDL_androidevents.h b/Engine/lib/sdl/src/video/android/SDL_androidevents.h index d985ea20d..db78b0041 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidevents.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidgl.c b/Engine/lib/sdl/src/video/android/SDL_androidgl.c index 8c020845a..fe1b17b26 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidgl.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidgl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_ANDROID +#if SDL_VIDEO_DRIVER_ANDROID && SDL_VIDEO_OPENGL_EGL /* Android SDL video driver implementation */ @@ -69,7 +69,7 @@ Android_GLES_SwapWindow(_THIS, SDL_Window * window) /* The following two calls existed in the original Java code * If you happen to have a device that's affected by their removal, - * please report to Bugzilla. -- Gabriel + * please report to our bug tracker. -- Gabriel */ /*_this->egl_data->eglWaitNative(EGL_CORE_NATIVE_ENGINE); diff --git a/Engine/lib/sdl/src/video/android/SDL_androidgl.h b/Engine/lib/sdl/src/video/android/SDL_androidgl.h index 5cbdaba60..15225303b 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidgl.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidgl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.c b/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.c index 435a8e30d..635a22ead 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.h b/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.h index c617d41e2..01da8ab15 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidmessagebox.c b/Engine/lib/sdl/src/video/android/SDL_androidmessagebox.c index abc2ce9cc..dc8b8ad03 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidmessagebox.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidmessagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidmessagebox.h b/Engine/lib/sdl/src/video/android/SDL_androidmessagebox.h index d9eb98441..73b276f83 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidmessagebox.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidmouse.c b/Engine/lib/sdl/src/video/android/SDL_androidmouse.c index 8f4986203..38953fa07 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidmouse.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -113,6 +113,10 @@ Android_CreateSystemCursor(SDL_SystemCursor id) static void Android_FreeCursor(SDL_Cursor * cursor) { + SDL_AndroidCursorData *data = (SDL_AndroidCursorData*) cursor->driverdata; + if (data->custom_cursor != 0) { + Android_JNI_DestroyCustomCursor(data->custom_cursor); + } SDL_free(cursor->driverdata); SDL_free(cursor); } diff --git a/Engine/lib/sdl/src/video/android/SDL_androidmouse.h b/Engine/lib/sdl/src/video/android/SDL_androidmouse.h index 71d4d291a..b81085999 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidmouse.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidtouch.c b/Engine/lib/sdl/src/video/android/SDL_androidtouch.c index 71056e6d4..24d985b0e 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidtouch.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidtouch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidtouch.h b/Engine/lib/sdl/src/video/android/SDL_androidtouch.h index 50c57dea4..641276f3e 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidtouch.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidtouch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidvideo.c b/Engine/lib/sdl/src/video/android/SDL_androidvideo.c index 3cad3beb6..61b9a87e9 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidvideo.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -64,7 +64,7 @@ int Android_SurfaceWidth = 0; int Android_SurfaceHeight = 0; static int Android_DeviceWidth = 0; static int Android_DeviceHeight = 0; -static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_UNKNOWN; +static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_RGB565; /* Default SurfaceView format, in case this is queried before being filled */ static int Android_ScreenRate = 0; SDL_sem *Android_PauseSem = NULL; SDL_sem *Android_ResumeSem = NULL; @@ -128,6 +128,7 @@ Android_CreateDevice(int devindex) device->free = Android_DeleteDevice; /* GL pointers */ +#if SDL_VIDEO_OPENGL_EGL device->GL_LoadLibrary = Android_GLES_LoadLibrary; device->GL_GetProcAddress = Android_GLES_GetProcAddress; device->GL_UnloadLibrary = Android_GLES_UnloadLibrary; @@ -137,6 +138,7 @@ Android_CreateDevice(int devindex) device->GL_GetSwapInterval = Android_GLES_GetSwapInterval; device->GL_SwapWindow = Android_GLES_SwapWindow; device->GL_DeleteContext = Android_GLES_DeleteContext; +#endif #if SDL_VIDEO_VULKAN device->Vulkan_LoadLibrary = Android_Vulkan_LoadLibrary; @@ -194,7 +196,7 @@ Android_VideoInit(_THIS) return -1; } display = SDL_GetDisplay(display_index); - display->orientation = Android_JNI_GetDisplayOrientation(); + display->orientation = Android_JNI_GetDisplayOrientation(); SDL_AddDisplayMode(&_this->displays[0], &mode); @@ -222,16 +224,54 @@ Android_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi } void -Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate) +Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float rate) { Android_SurfaceWidth = surfaceWidth; Android_SurfaceHeight = surfaceHeight; Android_DeviceWidth = deviceWidth; Android_DeviceHeight = deviceHeight; - Android_ScreenFormat = format; Android_ScreenRate = (int)rate; } +static +Uint32 format_to_pixelFormat(int format) { + Uint32 pf; + if (format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM) { /* 1 */ + pf = SDL_PIXELFORMAT_RGBA8888; + } else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM) { /* 2 */ + pf = SDL_PIXELFORMAT_RGBX8888; + } else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM) { /* 3 */ + pf = SDL_PIXELFORMAT_RGB24; + } else if (format == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM) { /* 4*/ + pf = SDL_PIXELFORMAT_RGB565; + } else if (format == 5) { + pf = SDL_PIXELFORMAT_BGRA8888; + } else if (format == 6) { + pf = SDL_PIXELFORMAT_RGBA5551; + } else if (format == 7) { + pf = SDL_PIXELFORMAT_RGBA4444; + } else { + pf = SDL_PIXELFORMAT_UNKNOWN; + } + return pf; +} + +void +Android_SetFormat(int format_wanted, int format_got) +{ + Uint32 pf_wanted; + Uint32 pf_got; + + pf_wanted = format_to_pixelFormat(format_wanted); + pf_got = format_to_pixelFormat(format_got); + + Android_ScreenFormat = pf_got; + + SDL_Log("pixel format wanted %s (%d), got %s (%d)", + SDL_GetPixelFormatName(pf_wanted), format_wanted, + SDL_GetPixelFormatName(pf_got), format_got); +} + void Android_SendResize(SDL_Window *window) { /* diff --git a/Engine/lib/sdl/src/video/android/SDL_androidvideo.h b/Engine/lib/sdl/src/video/android/SDL_androidvideo.h index b94e879ea..371419ba3 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidvideo.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,7 +28,8 @@ #include "../SDL_sysvideo.h" /* Called by the JNI layer when the screen changes size or format */ -extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate); +extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float rate); +extern void Android_SetFormat(int format_wanted, int format_got); extern void Android_SendResize(SDL_Window *window); /* Private display data */ diff --git a/Engine/lib/sdl/src/video/android/SDL_androidvulkan.c b/Engine/lib/sdl/src/video/android/SDL_androidvulkan.c index 776377f19..058165f57 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidvulkan.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidvulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidvulkan.h b/Engine/lib/sdl/src/video/android/SDL_androidvulkan.h index ee18c3664..f8f23eee5 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidvulkan.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/android/SDL_androidwindow.c b/Engine/lib/sdl/src/video/android/SDL_androidwindow.c index bf4bc914a..c5f8919ea 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidwindow.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidwindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -81,6 +81,7 @@ Android_CreateWindow(_THIS, SDL_Window * window) /* Do not create EGLSurface for Vulkan window since it will then make the window incompatible with vkCreateAndroidSurfaceKHR */ +#if SDL_VIDEO_OPENGL_EGL if ((window->flags & SDL_WINDOW_OPENGL) != 0) { data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window); @@ -91,6 +92,7 @@ Android_CreateWindow(_THIS, SDL_Window * window) goto endfunction; } } +#endif window->driverdata = data; Android_Window = window; @@ -175,9 +177,13 @@ Android_DestroyWindow(_THIS, SDL_Window *window) if (window->driverdata) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + +#if SDL_VIDEO_OPENGL_EGL if (data->egl_surface != EGL_NO_SURFACE) { SDL_EGL_DestroySurface(_this, data->egl_surface); } +#endif + if (data->native_window) { ANativeWindow_release(data->native_window); } @@ -198,7 +204,11 @@ Android_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info) info->version.minor == SDL_MINOR_VERSION) { info->subsystem = SDL_SYSWM_ANDROID; info->info.android.window = data->native_window; + +#if SDL_VIDEO_OPENGL_EGL info->info.android.surface = data->egl_surface; +#endif + return SDL_TRUE; } else { SDL_SetError("Application not compiled with SDL %d.%d", diff --git a/Engine/lib/sdl/src/video/android/SDL_androidwindow.h b/Engine/lib/sdl/src/video/android/SDL_androidwindow.h index c26a072ee..e78d5068e 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidwindow.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,8 +37,10 @@ extern SDL_Window *Android_Window; typedef struct { +#if SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; EGLContext egl_context; /* We use this to preserve the context when losing focus */ +#endif SDL_bool backup_done; ANativeWindow *native_window; diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.h index 26e741ee8..dd5e25224 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.m index 0ff90d0f8..1995c7289 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,10 +32,14 @@ Cocoa_SetClipboardText(_THIS, const char *text) SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; NSPasteboard *pasteboard; NSString *format = NSPasteboardTypeString; + NSString *nsstr = [NSString stringWithUTF8String:text]; + if (nsstr == nil) { + return SDL_SetError("Couldn't create NSString; is your string data in UTF-8 format?"); + } pasteboard = [NSPasteboard generalPasteboard]; data->clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil]; - [pasteboard setString:[NSString stringWithUTF8String:text] forType:format]; + [pasteboard setString:nsstr forType:format]; return 0; }} @@ -61,7 +65,7 @@ Cocoa_GetClipboardText(_THIS) } else { utf8 = [string UTF8String]; } - text = SDL_strdup(utf8); + text = SDL_strdup(utf8 ? utf8 : ""); } else { text = SDL_strdup(""); } diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.h index 7653c4550..ae49be099 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,6 +25,8 @@ extern void Cocoa_RegisterApp(void); extern void Cocoa_PumpEvents(_THIS); +extern int Cocoa_WaitEventTimeout(_THIS, int timeout); +extern void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window); extern void Cocoa_SuspendScreenSaver(_THIS); #endif /* SDL_cocoaevents_h_ */ diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.m index a55e9d9d4..d077bad6e 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,6 +35,24 @@ #ifndef NSAppKitVersionNumber10_8 #define NSAppKitVersionNumber10_8 1187 #endif +#ifndef MAC_OS_X_VERSION_10_12 +#define NSEventTypeApplicationDefined NSApplicationDefined +#endif + +static SDL_Window *FindSDLWindowForNSWindow(NSWindow *win) +{ + SDL_Window *sdlwindow = NULL; + SDL_VideoDevice *device = SDL_GetVideoDevice(); + if (device && device->windows) { + for (sdlwindow = device->windows; sdlwindow; sdlwindow = sdlwindow->next) { + NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow; + if (win == nswindow) + return sdlwindow; + } + } + + return sdlwindow; +} @interface SDLApplication : NSApplication @@ -158,6 +176,13 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) [center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil]; [center removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil]; + /* Remove our URL event handler only if we set it */ + if ([NSApp delegate] == self) { + [[NSAppleEventManager sharedAppleEventManager] + removeEventHandlerForEventClass:kInternetEventClass + andEventID:kAEGetURL]; + } + [super dealloc]; } @@ -169,6 +194,10 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) return; } + /* Don't do anything if this was not an SDL window that was closed */ + if (FindSDLWindowForNSWindow(win) == NULL) + return; + /* HACK: Make the next window in the z-order key when the key window is * closed. The custom event loop and/or windowing code we have seems to * prevent the normal behavior: https://bugzilla.libsdl.org/show_bug.cgi?id=1825 @@ -213,6 +242,13 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) return; } + /* Don't do anything if the application already has a key window + * that is not an SDL window. + */ + if ([NSApp keyWindow] && FindSDLWindowForNSWindow([NSApp keyWindow]) == NULL) { + return; + } + SDL_VideoDevice *device = SDL_GetVideoDevice(); if (device && device->windows) { SDL_Window *window = device->windows; @@ -262,12 +298,6 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) [NSApp activateIgnoringOtherApps:YES]; } - [[NSAppleEventManager sharedAppleEventManager] - setEventHandler:self - andSelector:@selector(handleURLEvent:withReplyEvent:) - forEventClass:kInternetEventClass - andEventID:kAEGetURL]; - /* If we call this before NSApp activation, macOS might print a complaint * about ApplePersistenceIgnoreState. */ [SDLApplication registerUserDefaults]; @@ -469,6 +499,15 @@ Cocoa_RegisterApp(void) * termination into SDL_Quit, and we can't handle application:openFile: */ if (![NSApp delegate]) { + /* Only register the URL event handler if we are being set as the + * app delegate to avoid replacing any existing event handler. + */ + [[NSAppleEventManager sharedAppleEventManager] + setEventHandler:appDelegate + andSelector:@selector(handleURLEvent:withReplyEvent:) + forEventClass:kInternetEventClass + andEventID:kAEGetURL]; + [(NSApplication *)NSApp setDelegate:appDelegate]; } else { appDelegate->seenFirstActivate = YES; @@ -476,9 +515,8 @@ Cocoa_RegisterApp(void) } }} -void -Cocoa_PumpEvents(_THIS) -{ @autoreleasepool +int +Cocoa_PumpEventsUntilDate(_THIS, NSDate *expiration, bool accumulate) { #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 /* Update activity every 30 seconds to prevent screensaver */ @@ -494,9 +532,9 @@ Cocoa_PumpEvents(_THIS) #endif for ( ; ; ) { - NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ]; + NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:expiration inMode:NSDefaultRunLoopMode dequeue:YES ]; if ( event == nil ) { - break; + return 0; } if (!s_bShouldHandleEventsInSDLApplication) { @@ -505,7 +543,52 @@ Cocoa_PumpEvents(_THIS) // Pass events down to SDLApplication to be handled in sendEvent: [NSApp sendEvent:event]; + if ( !accumulate) { + break; + } } + return 1; +} + +int +Cocoa_WaitEventTimeout(_THIS, int timeout) +{ @autoreleasepool +{ + if (timeout > 0) { + NSDate *limitDate = [NSDate dateWithTimeIntervalSinceNow: (double) timeout / 1000.0]; + return Cocoa_PumpEventsUntilDate(_this, limitDate, false); + } else if (timeout == 0) { + return Cocoa_PumpEventsUntilDate(_this, [NSDate distantPast], false); + } else { + while (Cocoa_PumpEventsUntilDate(_this, [NSDate distantFuture], false) == 0) { + } + } + return 1; +}} + +void +Cocoa_PumpEvents(_THIS) +{ @autoreleasepool +{ + Cocoa_PumpEventsUntilDate(_this, [NSDate distantPast], true); +}} + +void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window) +{ @autoreleasepool +{ + NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + + NSEvent* event = [NSEvent otherEventWithType: NSEventTypeApplicationDefined + location: NSMakePoint(0,0) + modifierFlags: 0 + timestamp: 0.0 + windowNumber: nswindow.windowNumber + context: nil + subtype: 0 + data1: 0 + data2: 0]; + + [NSApp postEvent: event atStart: YES]; }} void diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.h index e81f61600..9ff2affdb 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,6 +31,8 @@ extern void Cocoa_StartTextInput(_THIS); extern void Cocoa_StopTextInput(_THIS); extern void Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect); +extern void Cocoa_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed); + #endif /* SDL_cocoakeyboard_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.m index 26a18bdd0..b229ac3f6 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -602,6 +602,23 @@ Cocoa_QuitKeyboard(_THIS) { } +typedef int CGSConnection; +typedef enum { + CGSGlobalHotKeyEnable = 0, + CGSGlobalHotKeyDisable = 1, +} CGSGlobalHotKeyOperatingMode; + +extern CGSConnection _CGSDefaultConnection(void); +extern CGError CGSSetGlobalHotKeyOperatingMode(CGSConnection connection, CGSGlobalHotKeyOperatingMode mode); + +void +Cocoa_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ +#if SDL_MAC_NO_SANDBOX + CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), grabbed ? CGSGlobalHotKeyDisable : CGSGlobalHotKeyEnable); +#endif +} + #endif /* SDL_VIDEO_DRIVER_COCOA */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamessagebox.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamessagebox.h index 15bcfbadf..439a68a80 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamessagebox.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamessagebox.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamessagebox.m index 91a5660ef..e3fc20b7e 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamessagebox.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamessagebox.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -89,10 +89,8 @@ @end -/* Display a Cocoa message box */ -int -Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) -{ @autoreleasepool +static void +Cocoa_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid, int *returnValue) { Cocoa_RegisterApp(); @@ -133,11 +131,8 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window] autorelease]; - [presenter performSelectorOnMainThread:@selector(showAlert:) - withObject:alert - waitUntilDone:YES]; + [presenter showAlert:alert]; - int returnValue = 0; NSInteger clicked = presenter->clicked; if (clicked >= NSAlertFirstButtonReturn) { clicked -= NSAlertFirstButtonReturn; @@ -145,10 +140,24 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) clicked = messageboxdata->numbuttons - 1 - clicked; } *buttonid = buttons[clicked].buttonid; + *returnValue = 0; } else { - returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked); + *returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked); } +} +/* Display a Cocoa message box */ +int +Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ @autoreleasepool +{ + __block int returnValue = 0; + + if ([NSThread isMainThread]) { + Cocoa_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ Cocoa_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); }); + } return returnValue; }} diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoametalview.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoametalview.h index c173a0e7d..d8948b3d6 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoametalview.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoametalview.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -39,7 +39,6 @@ #import #import -#define METALVIEW_TAG 255 @interface SDL_cocoametalview : NSView diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoametalview.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoametalview.m index a55b6337a..6e33c4899 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoametalview.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoametalview.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,6 +31,8 @@ #if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) #include "SDL_events.h" +#include "SDL_syswm.h" + static int SDLCALL SDL_MetalViewEventWatch(void *userdata, SDL_Event *event) @@ -103,7 +105,7 @@ SDL_MetalViewEventWatch(void *userdata, SDL_Event *event) - (NSInteger)tag { - return METALVIEW_TAG; + return SDL_METALVIEW_TAG; } - (void)updateDrawableSize @@ -172,8 +174,8 @@ void Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) { @autoreleasepool { SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; - NSView *view = data->nswindow.contentView; - SDL_cocoametalview* metalview = [view viewWithTag:METALVIEW_TAG]; + NSView *contentView = data->sdlContentView; + SDL_cocoametalview* metalview = [contentView viewWithTag:SDL_METALVIEW_TAG]; if (metalview) { CAMetalLayer *layer = (CAMetalLayer*)metalview.layer; SDL_assert(layer != NULL); @@ -184,7 +186,21 @@ Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) *h = layer.drawableSize.height; } } else { - SDL_GetWindowSize(window, w, h); + /* Fall back to the viewport size. */ + NSRect viewport = [contentView bounds]; + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + /* This gives us the correct viewport for a Retina-enabled view, only + * supported on 10.7+. */ + if ([contentView respondsToSelector:@selector(convertRectToBacking:)]) { + viewport = [contentView convertRectToBacking:viewport]; + } + } + if (w) { + *w = viewport.size.width; + } + if (h) { + *h = viewport.size.height; + } } }} diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.h index 836fda70a..a4176dee8 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.m index 238be8da3..7d19030b2 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -40,6 +40,9 @@ #ifndef MAC_OS_X_VERSION_10_13 #define NSAppKitVersionNumber10_12 1504 #endif +#if (IOGRAPHICSTYPES_REV < 40) +#define kDisplayModeNativeFlag 0x02000000 +#endif static void @@ -162,7 +165,7 @@ GetDisplayModePixelFormat(CGDisplayModeRef vidmode) } static SDL_bool -GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLinkRef link, SDL_DisplayMode *mode) +GetDisplayMode(_THIS, CGDisplayModeRef vidmode, SDL_bool vidmodeCurrent, CFArrayRef modelist, CVDisplayLinkRef link, SDL_DisplayMode *mode) { SDL_DisplayModeData *data; bool usableForGUI = CGDisplayModeIsUsableForDesktopGUI(vidmode); @@ -178,7 +181,9 @@ GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLi return SDL_FALSE; } - if (!HasValidDisplayModeFlags(vidmode)) { + /* Don't fail the current mode based on flags because this could prevent Cocoa_InitModes from + * succeeding if the current mode lacks certain flags (esp kDisplayModeSafeFlag). */ + if (!vidmodeCurrent && !HasValidDisplayModeFlags(vidmode)) { return SDL_FALSE; } @@ -375,7 +380,7 @@ Cocoa_InitModes(_THIS) SDL_zero(display); /* this returns a stddup'ed string */ display.name = (char *)Cocoa_GetDisplayName(displays[i]); - if (!GetDisplayMode(_this, moderef, NULL, link, &mode)) { + if (!GetDisplayMode(_this, moderef, SDL_TRUE, NULL, link, &mode)) { CVDisplayLinkRelease(link); CGDisplayModeRelease(moderef); SDL_free(display.name); @@ -452,28 +457,68 @@ Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdp /* we need the backingScaleFactor for Retina displays, which is only exposed through NSScreen, not CGDisplay, afaik, so find our screen... */ CGFloat scaleFactor = 1.0f; NSArray *screens = [NSScreen screens]; + NSSize displayNativeSize; + displayNativeSize.width = (int) CGDisplayPixelsWide(data->display); + displayNativeSize.height = (int) CGDisplayPixelsHigh(data->display); + for (NSScreen *screen in screens) { const CGDirectDisplayID dpyid = (const CGDirectDisplayID ) [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue]; if (dpyid == data->display) { - if ([screen respondsToSelector:@selector(backingScaleFactor)]) { // Mac OS X 10.7 and later +#ifdef MAC_OS_X_VERSION_10_8 + /* Neither CGDisplayScreenSize(description's NSScreenNumber) nor [NSScreen backingScaleFactor] can calculate the correct dpi in macOS. E.g. backingScaleFactor is always 2 in all display modes for rMBP 16" */ + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_7) { + CFStringRef dmKeys[1] = { kCGDisplayShowDuplicateLowResolutionModes }; + CFBooleanRef dmValues[1] = { kCFBooleanTrue }; + CFDictionaryRef dmOptions = CFDictionaryCreate(kCFAllocatorDefault, (const void**) dmKeys, (const void**) dmValues, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); + CFArrayRef allDisplayModes = CGDisplayCopyAllDisplayModes(dpyid, dmOptions); + CFIndex n = CFArrayGetCount(allDisplayModes); + for(CFIndex i = 0; i < n; ++i) { + CGDisplayModeRef m = (CGDisplayModeRef)CFArrayGetValueAtIndex(allDisplayModes, i); + CGFloat width = CGDisplayModeGetPixelWidth(m); + CGFloat height = CGDisplayModeGetPixelHeight(m); + CGFloat HiDPIWidth = CGDisplayModeGetWidth(m); + + //Only check 1x mode + if(width == HiDPIWidth) { + if (CGDisplayModeGetIOFlags(m) & kDisplayModeNativeFlag) { + displayNativeSize.width = width; + displayNativeSize.height = height; + break; + } + + //Get the largest size even if kDisplayModeNativeFlag is not present e.g. iMac 27-Inch with 5K Retina + if(width > displayNativeSize.width) { + displayNativeSize.width = width; + displayNativeSize.height = height; + } + } + } + CFRelease(allDisplayModes); + CFRelease(dmOptions); + } else +#endif + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) { + // fallback for 10.7 scaleFactor = [screen backingScaleFactor]; + displayNativeSize.width = displayNativeSize.width * scaleFactor; + displayNativeSize.height = displayNativeSize.height * scaleFactor; break; } } } const CGSize displaySize = CGDisplayScreenSize(data->display); - const int pixelWidth = (int) CGDisplayPixelsWide(data->display); - const int pixelHeight = (int) CGDisplayPixelsHigh(data->display); + const int pixelWidth = displayNativeSize.width; + const int pixelHeight = displayNativeSize.height; if (ddpi) { - *ddpi = (SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH)) * scaleFactor; + *ddpi = (SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH)); } if (hdpi) { - *hdpi = (pixelWidth * MM_IN_INCH / displaySize.width) * scaleFactor; + *hdpi = (pixelWidth * MM_IN_INCH / displaySize.width); } if (vdpi) { - *vdpi = (pixelHeight * MM_IN_INCH / displaySize.height) * scaleFactor; + *vdpi = (pixelHeight * MM_IN_INCH / displaySize.height); } return 0; @@ -499,7 +544,7 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display) * sure there are no duplicates so it's safe to always add the desktop mode * even in cases where it is in the CopyAllDisplayModes list. */ - if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, NULL, link, &desktopmode)) { + if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, SDL_TRUE, NULL, link, &desktopmode)) { if (!SDL_AddDisplayMode(display, &desktopmode)) { CFRelease(((SDL_DisplayModeData*)desktopmode.driverdata)->modes); SDL_free(desktopmode.driverdata); @@ -546,7 +591,7 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display) CGDisplayModeRef moderef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); SDL_DisplayMode mode; - if (GetDisplayMode(_this, moderef, modes, link, &mode)) { + if (GetDisplayMode(_this, moderef, SDL_FALSE, modes, link, &mode)) { if (!SDL_AddDisplayMode(display, &mode)) { CFRelease(((SDL_DisplayModeData*)mode.driverdata)->modes); SDL_free(mode.driverdata); diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.h index cde24c8d6..44bbe8a30 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -40,7 +40,6 @@ typedef struct { /* What location we last saw the cursor move to. */ CGFloat lastMoveX; CGFloat lastMoveY; - void *tapdata; } SDL_MouseData; @interface NSCursor (InvisibleCursor) diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.m index 4ce2c61e9..7713fb544 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +24,6 @@ #include "SDL_events.h" #include "SDL_cocoamouse.h" -#include "SDL_cocoamousetap.h" #include "SDL_cocoavideo.h" #include "../../events/SDL_mouse_c.h" @@ -216,8 +215,8 @@ Cocoa_WarpMouseGlobal(int x, int y) SDL_Mouse *mouse = SDL_GetMouse(); if (mouse->focus) { SDL_WindowData *data = (SDL_WindowData *) mouse->focus->driverdata; - if ([data->listener isMoving]) { - DLog("Postponing warp, window being moved."); + if ([data->listener isMovingOrFocusClickPending]) { + DLog("Postponing warp, window being moved or focused."); [data->listener setPendingMoveX:x Y:y]; return 0; } @@ -254,7 +253,7 @@ Cocoa_WarpMouseGlobal(int x, int y) static void Cocoa_WarpMouse(SDL_Window * window, int x, int y) { - Cocoa_WarpMouseGlobal(x + window->x, y + window->y); + Cocoa_WarpMouseGlobal(window->x + x, window->y + y); } static int @@ -263,16 +262,16 @@ Cocoa_SetRelativeMouseMode(SDL_bool enabled) /* We will re-apply the relative mode when the window gets focus, if it * doesn't have focus right now. */ - SDL_Window *window = SDL_GetMouseFocus(); + SDL_Window *window = SDL_GetKeyboardFocus(); if (!window) { - return 0; + return 0; } /* We will re-apply the relative mode when the window finishes being moved, * if it is being moved right now. */ SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - if ([data->listener isMoving]) { + if ([data->listener isMovingOrFocusClickPending]) { return 0; } @@ -348,14 +347,40 @@ Cocoa_InitMouse(_THIS) SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor()); - Cocoa_InitMouseEventTap(driverdata); - const NSPoint location = [NSEvent mouseLocation]; driverdata->lastMoveX = location.x; driverdata->lastMoveY = location.y; return 0; } +static void +Cocoa_HandleTitleButtonEvent(_THIS, NSEvent *event) +{ + SDL_Window *window; + NSWindow *nswindow = [event window]; + + for (window = _this->windows; window; window = window->next) { + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + if (data && data->nswindow == nswindow) { + switch ([event type]) { + case NSEventTypeLeftMouseDown: + case NSEventTypeRightMouseDown: + case NSEventTypeOtherMouseDown: + [data->listener setFocusClickPending:[event buttonNumber]]; + break; + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseUp: + case NSEventTypeOtherMouseUp: + [data->listener clearFocusClickPending:[event buttonNumber]]; + break; + default: + break; + } + break; + } + } +} + void Cocoa_HandleMouseEvent(_THIS, NSEvent *event) { @@ -366,6 +391,21 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event) case NSEventTypeOtherMouseDragged: break; + case NSEventTypeLeftMouseDown: + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseDown: + case NSEventTypeRightMouseUp: + case NSEventTypeOtherMouseDown: + case NSEventTypeOtherMouseUp: + if ([event window]) { + NSRect windowRect = [[[event window] contentView] frame]; + if (!NSMouseInRect([event locationInWindow], windowRect, NO)) { + Cocoa_HandleTitleButtonEvent(_this, event); + return; + } + } + return; + default: /* Ignore any other events. */ return; @@ -433,15 +473,19 @@ Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event) } } - if (x > 0) { - x = SDL_ceil(x); - } else if (x < 0) { - x = SDL_floor(x); - } - if (y > 0) { - y = SDL_ceil(y); - } else if (y < 0) { - y = SDL_floor(y); + /* For discrete scroll events from conventional mice, always send a full tick. + For continuous scroll events from trackpads, send fractional deltas for smoother scrolling. */ + if (![event respondsToSelector:@selector(hasPreciseScrollingDeltas)] || ![event hasPreciseScrollingDeltas]) { + if (x > 0) { + x = SDL_ceil(x); + } else if (x < 0) { + x = SDL_floor(x); + } + if (y > 0) { + y = SDL_ceil(y); + } else if (y < 0) { + y = SDL_floor(y); + } } SDL_SendMouseWheel(window, mouseID, x, y, direction); @@ -467,8 +511,6 @@ Cocoa_QuitMouse(_THIS) SDL_Mouse *mouse = SDL_GetMouse(); if (mouse) { if (mouse->driverdata) { - Cocoa_QuitMouseEventTap(((SDL_MouseData*)mouse->driverdata)); - SDL_free(mouse->driverdata); mouse->driverdata = NULL; } diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamousetap.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamousetap.m deleted file mode 100644 index 953c81a7b..000000000 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamousetap.m +++ /dev/null @@ -1,286 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_VIDEO_DRIVER_COCOA - -#include "SDL_cocoamousetap.h" - -/* Event taps are forbidden in the Mac App Store, so we can only enable this - * code if your app doesn't need to ship through the app store. - * This code makes it so that a grabbed cursor cannot "leak" a mouse click - * past the edge of the window if moving the cursor too fast. - */ -#if SDL_MAC_NO_SANDBOX - -#include "SDL_keyboard.h" -#include "SDL_cocoavideo.h" -#include "../../thread/SDL_systhread.h" - -#include "../../events/SDL_mouse_c.h" - -typedef struct { - CFMachPortRef tap; - CFRunLoopRef runloop; - CFRunLoopSourceRef runloopSource; - SDL_Thread *thread; - SDL_sem *runloopStartedSemaphore; -} SDL_MouseEventTapData; - -static const CGEventMask movementEventsMask = - CGEventMaskBit(kCGEventLeftMouseDragged) - | CGEventMaskBit(kCGEventRightMouseDragged) - | CGEventMaskBit(kCGEventMouseMoved); - -static const CGEventMask allGrabbedEventsMask = - CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseUp) - | CGEventMaskBit(kCGEventRightMouseDown) | CGEventMaskBit(kCGEventRightMouseUp) - | CGEventMaskBit(kCGEventOtherMouseDown) | CGEventMaskBit(kCGEventOtherMouseUp) - | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDragged) - | CGEventMaskBit(kCGEventMouseMoved); - -static CGEventRef -Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) -{ - SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)refcon; - SDL_Mouse *mouse = SDL_GetMouse(); - SDL_Window *window = SDL_GetKeyboardFocus(); - NSWindow *nswindow; - NSRect windowRect; - CGPoint eventLocation; - - switch (type) { - case kCGEventTapDisabledByTimeout: - { - CGEventTapEnable(tapdata->tap, true); - return NULL; - } - case kCGEventTapDisabledByUserInput: - { - return NULL; - } - default: - break; - } - - - if (!window || !mouse) { - return event; - } - - if (mouse->relative_mode) { - return event; - } - - if (!(window->flags & SDL_WINDOW_INPUT_GRABBED)) { - return event; - } - - /* This is the same coordinate system as Cocoa uses. */ - nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; - eventLocation = CGEventGetUnflippedLocation(event); - windowRect = [nswindow contentRectForFrameRect:[nswindow frame]]; - - if (!NSMouseInRect(NSPointFromCGPoint(eventLocation), windowRect, NO)) { - - /* This is in CGs global screenspace coordinate system, which has a - * flipped Y. - */ - CGPoint newLocation = CGEventGetLocation(event); - - if (eventLocation.x < NSMinX(windowRect)) { - newLocation.x = NSMinX(windowRect); - } else if (eventLocation.x >= NSMaxX(windowRect)) { - newLocation.x = NSMaxX(windowRect) - 1.0; - } - - if (eventLocation.y <= NSMinY(windowRect)) { - newLocation.y -= (NSMinY(windowRect) - eventLocation.y + 1); - } else if (eventLocation.y > NSMaxY(windowRect)) { - newLocation.y += (eventLocation.y - NSMaxY(windowRect)); - } - - CGWarpMouseCursorPosition(newLocation); - CGAssociateMouseAndMouseCursorPosition(YES); - - if ((CGEventMaskBit(type) & movementEventsMask) == 0) { - /* For click events, we just constrain the event to the window, so - * no other app receives the click event. We can't due the same to - * movement events, since they mean that our warp cursor above - * behaves strangely. - */ - CGEventSetLocation(event, newLocation); - } - } - - return event; -} - -static void -SemaphorePostCallback(CFRunLoopTimerRef timer, void *info) -{ - SDL_SemPost((SDL_sem*)info); -} - -static int -Cocoa_MouseTapThread(void *data) -{ - SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)data; - - /* Tap was created on main thread but we own it now. */ - CFMachPortRef eventTap = tapdata->tap; - if (eventTap) { - /* Try to create a runloop source we can schedule. */ - CFRunLoopSourceRef runloopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0); - if (runloopSource) { - tapdata->runloopSource = runloopSource; - } else { - CFRelease(eventTap); - SDL_SemPost(tapdata->runloopStartedSemaphore); - /* TODO: Both here and in the return below, set some state in - * tapdata to indicate that initialization failed, which we should - * check in InitMouseEventTap, after we move the semaphore check - * from Quit to Init. - */ - return 1; - } - } else { - SDL_SemPost(tapdata->runloopStartedSemaphore); - return 1; - } - - tapdata->runloop = CFRunLoopGetCurrent(); - CFRunLoopAddSource(tapdata->runloop, tapdata->runloopSource, kCFRunLoopCommonModes); - CFRunLoopTimerContext context = {.info = tapdata->runloopStartedSemaphore}; - /* We signal the runloop started semaphore *after* the run loop has started, indicating it's safe to CFRunLoopStop it. */ - CFRunLoopTimerRef timer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), 0, 0, 0, &SemaphorePostCallback, &context); - CFRunLoopAddTimer(tapdata->runloop, timer, kCFRunLoopCommonModes); - CFRelease(timer); - - /* Run the event loop to handle events in the event tap. */ - CFRunLoopRun(); - /* Make sure this is signaled so that SDL_QuitMouseEventTap knows it can safely SDL_WaitThread for us. */ - if (SDL_SemValue(tapdata->runloopStartedSemaphore) < 1) { - SDL_SemPost(tapdata->runloopStartedSemaphore); - } - CFRunLoopRemoveSource(tapdata->runloop, tapdata->runloopSource, kCFRunLoopCommonModes); - - /* Clean up. */ - CGEventTapEnable(tapdata->tap, false); - CFRelease(tapdata->runloopSource); - CFRelease(tapdata->tap); - tapdata->runloopSource = NULL; - tapdata->tap = NULL; - - return 0; -} - -void -Cocoa_InitMouseEventTap(SDL_MouseData* driverdata) -{ - SDL_MouseEventTapData *tapdata; - driverdata->tapdata = SDL_calloc(1, sizeof(SDL_MouseEventTapData)); - tapdata = (SDL_MouseEventTapData*)driverdata->tapdata; - - tapdata->runloopStartedSemaphore = SDL_CreateSemaphore(0); - if (tapdata->runloopStartedSemaphore) { - tapdata->tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, - kCGEventTapOptionDefault, allGrabbedEventsMask, - &Cocoa_MouseTapCallback, tapdata); - if (tapdata->tap) { - /* Tap starts disabled, until app requests mouse grab */ - CGEventTapEnable(tapdata->tap, false); - tapdata->thread = SDL_CreateThreadInternal(&Cocoa_MouseTapThread, "Event Tap Loop", 512 * 1024, tapdata); - if (tapdata->thread) { - /* Success - early out. Ownership transferred to thread. */ - return; - } - CFRelease(tapdata->tap); - } - SDL_DestroySemaphore(tapdata->runloopStartedSemaphore); - } - SDL_free(driverdata->tapdata); - driverdata->tapdata = NULL; -} - -void -Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled) -{ - SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->tapdata; - if (tapdata && tapdata->tap) - { - CGEventTapEnable(tapdata->tap, !!enabled); - } -} - -void -Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata) -{ - SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->tapdata; - int status; - - if (tapdata == NULL) { - /* event tap was already cleaned up (possibly due to CGEventTapCreate - * returning null.) - */ - return; - } - - /* Ensure that the runloop has been started first. - * TODO: Move this to InitMouseEventTap, check for error conditions that can - * happen in Cocoa_MouseTapThread, and fall back to the non-EventTap way of - * grabbing the mouse if it fails to Init. - */ - status = SDL_SemWaitTimeout(tapdata->runloopStartedSemaphore, 5000); - if (status > -1) { - /* Then stop it, which will cause Cocoa_MouseTapThread to return. */ - CFRunLoopStop(tapdata->runloop); - /* And then wait for Cocoa_MouseTapThread to finish cleaning up. It - * releases some of the pointers in tapdata. */ - SDL_WaitThread(tapdata->thread, &status); - } - - SDL_free(driverdata->tapdata); - driverdata->tapdata = NULL; -} - -#else /* SDL_MAC_NO_SANDBOX */ - -void -Cocoa_InitMouseEventTap(SDL_MouseData *unused) -{ -} - -void -Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled) -{ -} - -void -Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata) -{ -} - -#endif /* !SDL_MAC_NO_SANDBOX */ - -#endif /* SDL_VIDEO_DRIVER_COCOA */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.h index bae8ce48a..9ac44ab5f 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.m index 6fb471139..9d31b9c22 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -135,7 +135,7 @@ if ([NSThread isMainThread]) { [super update]; } else { - dispatch_sync(dispatch_get_main_queue(), ^{ [super update]; }); + dispatch_async(dispatch_get_main_queue(), ^{ [super update]; }); } } diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengles.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengles.h index a079601ae..bfabb6d57 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengles.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengles.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengles.m index 0f551de10..13102f8c0 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengles.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengles.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -109,7 +109,10 @@ Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window) if (_this->egl_data == NULL) { + /* !!! FIXME: commenting out this assertion is (I think) incorrect; figure out why driver_loaded is wrong for ANGLE instead. --ryan. */ + #if 0 /* When hint SDL_HINT_OPENGL_ES_DRIVER is set to "1" (e.g. for ANGLE support), _this->gl_config.driver_loaded can be 1, while the below lines function. */ SDL_assert(!_this->gl_config.driver_loaded); + #endif if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0) < 0) { SDL_EGL_UnloadLibrary(_this); return -1; diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.h index 739f76285..25c41620a 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.m index f278c28c2..1176036ac 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.h index 75b264223..af0abe5cc 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.m index de809da73..231b2de5c 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -38,6 +38,9 @@ static void Cocoa_VideoQuit(_THIS); static void Cocoa_DeleteDevice(SDL_VideoDevice * device) { + if (device->wakeup_lock) { + SDL_DestroyMutex(device->wakeup_lock); + } SDL_free(device->driverdata); SDL_free(device); } @@ -63,6 +66,7 @@ Cocoa_CreateDevice(int devindex) return NULL; } device->driverdata = data; + device->wakeup_lock = SDL_CreateMutex(); /* Set the function pointers */ device->VideoInit = Cocoa_VideoInit; @@ -73,6 +77,8 @@ Cocoa_CreateDevice(int devindex) device->GetDisplayModes = Cocoa_GetDisplayModes; device->SetDisplayMode = Cocoa_SetDisplayMode; device->PumpEvents = Cocoa_PumpEvents; + device->WaitEventTimeout = Cocoa_WaitEventTimeout; + device->SendWakeupEvent = Cocoa_SendWakeupEvent; device->SuspendScreenSaver = Cocoa_SuspendScreenSaver; device->CreateSDLWindow = Cocoa_CreateWindow; @@ -92,14 +98,19 @@ Cocoa_CreateDevice(int devindex) device->RestoreWindow = Cocoa_RestoreWindow; device->SetWindowBordered = Cocoa_SetWindowBordered; device->SetWindowResizable = Cocoa_SetWindowResizable; + device->SetWindowAlwaysOnTop = Cocoa_SetWindowAlwaysOnTop; device->SetWindowFullscreen = Cocoa_SetWindowFullscreen; device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp; device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp; - device->SetWindowGrab = Cocoa_SetWindowGrab; + device->GetWindowICCProfile = Cocoa_GetWindowICCProfile; + device->SetWindowMouseRect = Cocoa_SetWindowMouseRect; + device->SetWindowMouseGrab = Cocoa_SetWindowMouseGrab; + device->SetWindowKeyboardGrab = Cocoa_SetWindowKeyboardGrab; device->DestroyWindow = Cocoa_DestroyWindow; device->GetWindowWMInfo = Cocoa_GetWindowWMInfo; device->SetWindowHitTest = Cocoa_SetWindowHitTest; device->AcceptDragAndDrop = Cocoa_AcceptDragAndDrop; + device->FlashWindow = Cocoa_FlashWindow; device->shape_driver.CreateShaper = Cocoa_CreateShaper; device->shape_driver.SetWindowShape = Cocoa_SetWindowShape; @@ -260,7 +271,10 @@ Cocoa_CreateImage(SDL_Surface * surface) void SDL_NSLog(const char *text) { - NSLog(@"%s", text); + @autoreleasepool { + NSString *str = [NSString stringWithUTF8String:text]; + NSLog(@"%@", str); + } } #endif /* SDL_VIDEO_DRIVER_COCOA */ diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoavulkan.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoavulkan.h index 33dc892f5..9ddc70996 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoavulkan.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoavulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoavulkan.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoavulkan.m index 2af77ceb9..20c83d47d 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoavulkan.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoavulkan.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.h index 4c0570fdf..a42d9c87b 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -48,6 +48,7 @@ typedef enum BOOL inFullscreenTransition; PendingWindowOperation pendingWindowOperation; BOOL isMoving; + NSInteger focusClickPending; int pendingWindowWarpX, pendingWindowWarpY; BOOL isDragAreaRunning; } @@ -62,8 +63,12 @@ typedef enum -(void) close; -(BOOL) isMoving; +-(BOOL) isMovingOrFocusClickPending; +-(void) setFocusClickPending:(NSInteger) button; +-(void) clearFocusClickPending:(NSInteger) button; -(void) setPendingMoveX:(int)x Y:(int)y; -(void) windowDidFinishMoving; +-(void) onMovingOrFocusClickPendingStateCleared; /* Window delegate functionality */ -(BOOL) windowShouldClose:(id) sender; @@ -75,6 +80,7 @@ typedef enum -(void) windowDidBecomeKey:(NSNotification *) aNotification; -(void) windowDidResignKey:(NSNotification *) aNotification; -(void) windowDidChangeBackingProperties:(NSNotification *) aNotification; +-(void) windowDidChangeScreenProfile:(NSNotification *) aNotification; -(void) windowWillEnterFullScreen:(NSNotification *) aNotification; -(void) windowDidEnterFullScreen:(NSNotification *) aNotification; -(void) windowWillExitFullScreen:(NSNotification *) aNotification; @@ -117,6 +123,7 @@ struct SDL_WindowData NSMutableArray *nscontexts; SDL_bool created; SDL_bool inWindowFullscreenTransition; + NSInteger flash_request; Cocoa_WindowListener *listener; struct SDL_VideoData *videodata; #if SDL_VIDEO_OPENGL_EGL @@ -142,14 +149,18 @@ extern void Cocoa_MinimizeWindow(_THIS, SDL_Window * window); extern void Cocoa_RestoreWindow(_THIS, SDL_Window * window); extern void Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); +extern void Cocoa_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top); extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); +extern void* Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size); extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); -extern void Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void Cocoa_SetWindowMouseRect(_THIS, SDL_Window * window); +extern void Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void Cocoa_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); extern int Cocoa_SetWindowHitTest(SDL_Window *window, SDL_bool enabled); extern void Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept); +extern int Cocoa_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation); #endif /* SDL_cocoawindow_h_ */ diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.m index e6128db4f..bca8eb4dd 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -38,7 +38,6 @@ #include "SDL_cocoavideo.h" #include "SDL_cocoashape.h" #include "SDL_cocoamouse.h" -#include "SDL_cocoamousetap.h" #include "SDL_cocoaopengl.h" #include "SDL_cocoaopengles.h" @@ -56,9 +55,21 @@ #ifndef MAC_OS_X_VERSION_10_12 #define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask #endif -#ifndef NSAppKitVersionNumber10_14 -#define NSAppKitVersionNumber10_14 1671 +#ifndef NSAppKitVersionNumber10_13_2 +#define NSAppKitVersionNumber10_13_2 1561.2 #endif +#ifndef NSAppKitVersionNumber10_14 +#define NSAppKitVersionNumber10_14 1671 +#endif + +@interface NSWindow (SDL) +#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000 /* Added in the 10.10 SDK */ +@property (readonly) NSRect contentLayoutRect; +#endif + +/* This is available as of 10.13.2, but isn't in public headers */ +@property (nonatomic) NSRect mouseConfinementRect; +@end @interface SDLWindow : NSWindow /* These are needed for borderless/fullscreen windows */ @@ -161,6 +172,16 @@ SDL_assert([desiredType isEqualToString:NSFilenamesPboardType]); NSArray *array = [pasteboard propertyListForType:@"NSFilenamesPboardType"]; + /* Code addon to update the mouse location */ + NSPoint point = [sender draggingLocation]; + SDL_Mouse *mouse = SDL_GetMouse(); + int x = (int)point.x; + int y = (int)(sdlwindow->h - point.y); + if (x >= 0 && x < sdlwindow->w && y >= 0 && y < sdlwindow->h) { + SDL_SendMouseMotion(sdlwindow, mouse->mouseID, 0, x, y); + } + /* Code addon to update the mouse location */ + for (NSString *path in array) { NSURL *fileURL = [NSURL fileURLWithPath:path]; NSNumber *isAlias = nil; @@ -313,6 +334,119 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) return SDL_TRUE; } +static SDL_bool +ShouldAdjustCoordinatesForGrab(SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if (!data || [data->listener isMovingOrFocusClickPending]) { + return SDL_FALSE; + } + + if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) { + return SDL_FALSE; + } + + if ((window->flags & SDL_WINDOW_MOUSE_GRABBED) || (window->mouse_rect.w > 0 && window->mouse_rect.h > 0)) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +static SDL_bool +AdjustCoordinatesForGrab(SDL_Window * window, int x, int y, CGPoint *adjusted) +{ + if (window->mouse_rect.w > 0 && window->mouse_rect.h > 0) { + SDL_Rect window_rect; + SDL_Rect mouse_rect; + + window_rect.x = 0; + window_rect.y = 0; + window_rect.w = window->w; + window_rect.h = window->h; + + if (SDL_IntersectRect(&window->mouse_rect, &window_rect, &mouse_rect)) { + int left = window->x + mouse_rect.x; + int right = left + mouse_rect.w - 1; + int top = window->y + mouse_rect.y; + int bottom = top + mouse_rect.h - 1; + if (x < left || x > right || y < top || y > bottom) { + adjusted->x = SDL_clamp(x, left, right); + adjusted->y = SDL_clamp(y, top, bottom); + return SDL_TRUE; + } + return SDL_FALSE; + } + } + + if ((window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) { + int left = window->x; + int right = left + window->w - 1; + int top = window->y; + int bottom = top + window->h - 1; + if (x < left || x > right || y < top || y > bottom) { + adjusted->x = SDL_clamp(x, left, right); + adjusted->y = SDL_clamp(y, top, bottom); + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static void +Cocoa_UpdateClipCursor(SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_13_2) { + NSWindow *nswindow = data->nswindow; + SDL_Rect mouse_rect; + + SDL_zero(mouse_rect); + + if (ShouldAdjustCoordinatesForGrab(window)) { + SDL_Rect window_rect; + + window_rect.x = 0; + window_rect.y = 0; + window_rect.w = window->w; + window_rect.h = window->h; + + if (window->mouse_rect.w > 0 && window->mouse_rect.h > 0) { + SDL_IntersectRect(&window->mouse_rect, &window_rect, &mouse_rect); + } + + if ((window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0 && + SDL_RectEmpty(&mouse_rect)) { + SDL_memcpy(&mouse_rect, &window_rect, sizeof(mouse_rect)); + } + } + + if (SDL_RectEmpty(&mouse_rect)) { + nswindow.mouseConfinementRect = NSZeroRect; + } else { + NSRect rect; + rect.origin.x = mouse_rect.x; + rect.origin.y = [nswindow contentLayoutRect].size.height - mouse_rect.y - mouse_rect.h; + rect.size.width = mouse_rect.w; + rect.size.height = mouse_rect.h; + nswindow.mouseConfinementRect = rect; + } + } else { + /* Move the cursor to the nearest point in the window */ + if (ShouldAdjustCoordinatesForGrab(window)) { + int x, y; + CGPoint cgpoint; + + SDL_GetGlobalMouseState(&x, &y); + if (AdjustCoordinatesForGrab(window, x, y, &cgpoint)) { + Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); + CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); + } + } + } +} + @implementation Cocoa_WindowListener @@ -331,6 +465,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) pendingWindowOperation = PENDING_OPERATION_NONE; isMoving = NO; isDragAreaRunning = NO; + pendingWindowWarpX = pendingWindowWarpY = INT_MAX; center = [NSNotificationCenter defaultCenter]; @@ -343,6 +478,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) [center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:window]; [center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window]; [center addObserver:self selector:@selector(windowDidChangeBackingProperties:) name:NSWindowDidChangeBackingPropertiesNotification object:window]; + [center addObserver:self selector:@selector(windowDidChangeScreenProfile:) name:NSWindowDidChangeScreenProfileNotification object:window]; [center addObserver:self selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:window]; [center addObserver:self selector:@selector(windowDidEnterFullScreen:) name:NSWindowDidEnterFullScreenNotification object:window]; [center addObserver:self selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:window]; @@ -474,6 +610,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:window]; [center removeObserver:self name:NSWindowDidResignKeyNotification object:window]; [center removeObserver:self name:NSWindowDidChangeBackingPropertiesNotification object:window]; + [center removeObserver:self name:NSWindowDidChangeScreenProfileNotification object:window]; [center removeObserver:self name:NSWindowWillEnterFullScreenNotification object:window]; [center removeObserver:self name:NSWindowDidEnterFullScreenNotification object:window]; [center removeObserver:self name:NSWindowWillExitFullScreenNotification object:window]; @@ -499,6 +636,26 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) return isMoving; } +- (BOOL)isMovingOrFocusClickPending +{ + return isMoving || (focusClickPending != 0); +} + +-(void) setFocusClickPending:(NSInteger) button +{ + focusClickPending |= (1 << button); +} + +-(void) clearFocusClickPending:(NSInteger) button +{ + if ((focusClickPending & (1 << button)) != 0) { + focusClickPending &= ~(1 << button); + if (focusClickPending == 0) { + [self onMovingOrFocusClickPendingStateCleared]; + } + } +} + -(void) setPendingMoveX:(int)x Y:(int)y { pendingWindowWarpX = x; @@ -507,16 +664,39 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)windowDidFinishMoving { - if ([self isMoving]) { + if (isMoving) { isMoving = NO; + [self onMovingOrFocusClickPendingStateCleared]; + } +} +- (void)onMovingOrFocusClickPendingStateCleared +{ + if (![self isMovingOrFocusClickPending]) { SDL_Mouse *mouse = SDL_GetMouse(); if (pendingWindowWarpX != INT_MAX && pendingWindowWarpY != INT_MAX) { mouse->WarpMouseGlobal(pendingWindowWarpX, pendingWindowWarpY); pendingWindowWarpX = pendingWindowWarpY = INT_MAX; } if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data->window) { + /* Move the cursor to the nearest point in the window */ + { + int x, y; + CGPoint cgpoint; + + SDL_GetMouseState(&x, &y); + cgpoint.x = _data->window->x + x; + cgpoint.y = _data->window->y + y; + + Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); + + DLog("Returning cursor to (%g, %g)", cgpoint.x, cgpoint.y); + CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); + } + mouse->SetRelativeMouseMode(SDL_TRUE); + } else { + Cocoa_UpdateClipCursor(_data->window); } } } @@ -615,6 +795,10 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)windowDidMiniaturize:(NSNotification *)aNotification { + if (focusClickPending) { + focusClickPending = 0; + [self onMovingOrFocusClickPendingStateCleared]; + } SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); } @@ -632,7 +816,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) /* This needs to be done before restoring the relative mouse mode. */ SDL_SetKeyboardFocus(window); - if (mouse->relative_mode && !mouse->relative_mode_warp && ![self isMoving]) { + if (mouse->relative_mode && !mouse->relative_mode_warp && ![self isMovingOrFocusClickPending]) { mouse->SetRelativeMouseMode(SDL_TRUE); } @@ -700,6 +884,11 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) } } +- (void)windowDidChangeScreenProfile:(NSNotification *)aNotification +{ + SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0); +} + - (void)windowWillEnterFullScreen:(NSNotification *)aNotification { SDL_Window *window = _data->window; @@ -962,16 +1151,43 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) return NO; /* not a special area, carry on. */ } +static int +Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * window, const Uint8 state, const Uint8 button) +{ + const SDL_MouseID mouseID = mouse->mouseID; + const int clicks = (int) [theEvent clickCount]; + SDL_Window *focus = SDL_GetKeyboardFocus(); + int rc; + + // macOS will send non-left clicks to background windows without raising them, so we need to + // temporarily adjust the mouse position when this happens, as `mouse` will be tracking + // the position in the currently-focused window. We don't (currently) send a mousemove + // event for the background window, this just makes sure the button is reported at the + // correct position in its own event. + if ( focus && ([theEvent window] == ((SDL_WindowData *) focus->driverdata)->nswindow) ) { + rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks); + } else { + const int orig_x = mouse->x; + const int orig_y = mouse->y; + const NSPoint point = [theEvent locationInWindow]; + mouse->x = (int) point.x; + mouse->y = (int) (window->h - point.y); + rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks); + mouse->x = orig_x; + mouse->y = orig_y; + } + + return rc; +} + - (void)mouseDown:(NSEvent *)theEvent { - const SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Mouse *mouse = SDL_GetMouse(); if (!mouse) { return; } - const SDL_MouseID mouseID = mouse->mouseID; int button; - int clicks; /* Ignore events that aren't inside the client area (i.e. title bar.) */ if ([theEvent window]) { @@ -1008,9 +1224,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) break; } - clicks = (int) [theEvent clickCount]; - - SDL_SendMouseButtonClicks(_data->window, mouseID, SDL_PRESSED, button, clicks); + Cocoa_SendMouseButtonClicks(mouse, theEvent, _data->window, SDL_PRESSED, button); } - (void)rightMouseDown:(NSEvent *)theEvent @@ -1025,14 +1239,12 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)mouseUp:(NSEvent *)theEvent { - const SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Mouse *mouse = SDL_GetMouse(); if (!mouse) { return; } - const SDL_MouseID mouseID = mouse->mouseID; int button; - int clicks; if ([self processHitTest:theEvent]) { SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); @@ -1059,9 +1271,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) break; } - clicks = (int) [theEvent clickCount]; - - SDL_SendMouseButtonClicks(_data->window, mouseID, SDL_RELEASED, button, clicks); + Cocoa_SendMouseButtonClicks(mouse, theEvent, _data->window, SDL_RELEASED, button); } - (void)rightMouseUp:(NSEvent *)theEvent @@ -1099,34 +1309,15 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) x = (int)point.x; y = (int)(window->h - point.y); - if (window->flags & SDL_WINDOW_INPUT_GRABBED) { - if (x < 0 || x >= window->w || y < 0 || y >= window->h) { - if (x < 0) { - x = 0; - } else if (x >= window->w) { - x = window->w - 1; - } - if (y < 0) { - y = 0; - } else if (y >= window->h) { - y = window->h - 1; - } - -#if !SDL_MAC_NO_SANDBOX - CGPoint cgpoint; - - /* When SDL_MAC_NO_SANDBOX is set, this is handled by - * SDL_cocoamousetap.m. - */ - - cgpoint.x = window->x + x; - cgpoint.y = window->y + y; - + if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_13_2) { + /* Mouse grab is taken care of by the confinement rect */ + } else { + CGPoint cgpoint; + if (ShouldAdjustCoordinatesForGrab(window) && + AdjustCoordinatesForGrab(window, window->x + x, window->y + y, &cgpoint)) { + Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); CGAssociateMouseAndMouseCursorPosition(YES); - - Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); -#endif } } @@ -1157,7 +1348,18 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) { /* probably a MacBook trackpad; make this look like a synthesized event. This is backwards from reality, but better matches user expectations. */ - const BOOL istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent); + BOOL istrackpad = NO; + @try { + istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent); + } + @catch (NSException *e) { + /* if NSEvent type doesn't have subtype, such as NSEventTypeBeginGesture on + * macOS 10.5 to 10.10, then NSInternalInconsistencyException is thrown. + * This still prints a message to terminal so catching it's not an ideal solution. + * + * *** Assertion failure in -[NSEvent subtype] + */ + } NSSet *touches = [theEvent touchesMatchingPhase:NSTouchPhaseAny inView:nil]; const SDL_TouchID touchID = istrackpad ? SDL_MOUSE_TOUCHID : (SDL_TouchID)(intptr_t)[[touches anyObject] device]; @@ -1208,7 +1410,18 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) /* probably a MacBook trackpad; make this look like a synthesized event. This is backwards from reality, but better matches user expectations. */ - const BOOL istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent); + BOOL istrackpad = NO; + @try { + istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent); + } + @catch (NSException *e) { + /* if NSEvent type doesn't have subtype, such as NSEventTypeBeginGesture on + * macOS 10.5 to 10.10, then NSInternalInconsistencyException is thrown. + * This still prints a message to terminal so catching it's not an ideal solution. + * + * *** Assertion failure in -[NSEvent subtype] + */ + } for (NSTouch *touch in touches) { const SDL_TouchID touchId = istrackpad ? SDL_MOUSE_TOUCHID : (SDL_TouchID)(intptr_t)[touch device]; @@ -1403,7 +1616,10 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview, { unsigned long style = [nswindow styleMask]; - if (style == NSWindowStyleMaskBorderless) { + /* NSWindowStyleMaskBorderless is zero, and it's possible to be + Resizeable _and_ borderless, so we can't do a simple bitwise AND + of NSWindowStyleMaskBorderless here. */ + if ((style & ~NSWindowStyleMaskResizable) == NSWindowStyleMaskBorderless) { window->flags |= SDL_WINDOW_BORDERLESS; } else { window->flags &= ~SDL_WINDOW_BORDERLESS; @@ -1804,11 +2020,33 @@ Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) */ SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Cocoa_WindowListener *listener = data->listener; + NSWindow *nswindow = data->nswindow; + SDL_VideoData *videodata = ((SDL_WindowData *) window->driverdata)->videodata; if (![listener isInFullscreenSpace]) { SetWindowStyle(window, GetWindowStyle(window)); } + if (videodata->allow_spaces) { + if (resizable) { + /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */ + [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + } else { + [nswindow setCollectionBehavior:NSWindowCollectionBehaviorManaged]; + } + } }} +void +Cocoa_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top) +{ @autoreleasepool + { + NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + if (on_top) { + [nswindow setLevel:NSFloatingWindowLevel]; + } else { + [nswindow setLevel:kCGNormalWindowLevel]; + } + }} + void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) { @autoreleasepool @@ -1923,6 +2161,42 @@ Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) return 0; } +void* +Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + NSWindow *nswindow = data->nswindow; + NSScreen *screen = [nswindow screen]; + NSData* iccProfileData = nil; + void* retIccProfileData = NULL; + + if (screen == nil) { + SDL_SetError("Could not get screen of window."); + return NULL; + } + + if ([screen colorSpace] == nil) { + SDL_SetError("Could not get colorspace information of screen."); + return NULL; + } + + iccProfileData = [[screen colorSpace] ICCProfileData]; + if (iccProfileData == nil) { + SDL_SetError("Could not get ICC profile data."); + return NULL; + } + + retIccProfileData = SDL_malloc([iccProfileData length]); + if (!retIccProfileData) { + SDL_OutOfMemory(); + return NULL; + } + + [iccProfileData getBytes:retIccProfileData length:[iccProfileData length]]; + *size = [iccProfileData length]; + return retIccProfileData; +} + int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) { @@ -1948,30 +2222,19 @@ Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) } void -Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +Cocoa_SetWindowMouseRect(_THIS, SDL_Window * window) +{ + Cocoa_UpdateClipCursor(window); +} + +void +Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { - SDL_Mouse *mouse = SDL_GetMouse(); SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - /* Enable or disable the event tap as necessary */ - Cocoa_EnableMouseEventTap(mouse->driverdata, grabbed); + Cocoa_UpdateClipCursor(window); - /* Move the cursor to the nearest point in the window */ - if (grabbed && data && ![data->listener isMoving]) { - int x, y; - CGPoint cgpoint; - - SDL_GetMouseState(&x, &y); - cgpoint.x = window->x + x; - cgpoint.y = window->y + y; - - Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); - - DLog("Returning cursor to (%g, %g)", cgpoint.x, cgpoint.y); - CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); - } - - if ( data && (window->flags & SDL_WINDOW_FULLSCREEN) ) { + if (data && (window->flags & SDL_WINDOW_FULLSCREEN)) { if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_INPUT_FOCUS) && ![data->listener isInFullscreenSpace]) { /* OpenGL is rendering to the window, so make it visible! */ @@ -2103,6 +2366,34 @@ Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept) } } +int +Cocoa_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation) +{ @autoreleasepool +{ + /* Note that this is app-wide and not window-specific! */ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if (data->flash_request) { + [NSApp cancelUserAttentionRequest:data->flash_request]; + data->flash_request = 0; + } + + switch (operation) { + case SDL_FLASH_CANCEL: + /* Canceled above */ + break; + case SDL_FLASH_BRIEFLY: + data->flash_request = [NSApp requestUserAttention:NSInformationalRequest]; + break; + case SDL_FLASH_UNTIL_FOCUSED: + data->flash_request = [NSApp requestUserAttention:NSCriticalRequest]; + break; + default: + return SDL_Unsupported(); + } + return 0; +}} + int Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) { diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_WM.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_WM.c index bb9acb1f9..dc4af539f 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_WM.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_WM.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -287,9 +287,8 @@ WMPos(DFB_WindowData * p, int x, int y) int DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt) { - SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); - DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL); + SDL_Window *grabbed_window = SDL_GetGrabbedWindow(); IDirectFBWindow *dfbwin = windata->dfbwin; DFBWindowOptions wopts; @@ -324,12 +323,12 @@ DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt) } if (window->flags & SDL_WINDOW_MAXIMIZED) return 1; - /* fall through */ + SDL_FALLTHROUGH; default: windata->wm_grab = pos; - if (gwindata != NULL) - SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin)); - SDL_DFB_CHECK(dfbwin->GrabPointer(dfbwin)); + if (grabbed_window != NULL) + DirectFB_SetWindowMouseGrab(_this, grabbed_window, SDL_FALSE); + DirectFB_SetWindowMouseGrab(_this, window, SDL_TRUE); windata->wm_lastx = evt->cx; windata->wm_lasty = evt->cy; } @@ -359,9 +358,9 @@ DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt) SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy)); } } - SDL_DFB_CHECK(dfbwin->UngrabPointer(dfbwin)); - if (gwindata != NULL) - SDL_DFB_CHECK(gwindata->dfbwin->GrabPointer(gwindata->dfbwin)); + DirectFB_SetWindowMouseGrab(_this, window, SDL_FALSE); + if (grabbed_window != NULL) + DirectFB_SetWindowMouseGrab(_this, grabbed_window, SDL_TRUE); windata->wm_grab = WM_POS_NONE; return 1; } diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_WM.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_WM.h index 965081fbe..be96ec648 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_WM.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_WM.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_dyn.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_dyn.c index 94626af38..d872c29bc 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_dyn.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_dyn.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_dyn.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_dyn.h index f067245cd..28882b833 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_dyn.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_dyn.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_events.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_events.c index 251d6970d..e6ca47ad3 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_events.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_events.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -212,7 +212,7 @@ ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt) case DWET_MOTION: if (ClientXY(windata, &evt->x, &evt->y)) { if (!devdata->use_linux_input) { - if (!(sdlwin->flags & SDL_WINDOW_INPUT_GRABBED)) + if (!(sdlwin->flags & SDL_WINDOW_MOUSE_GRABBED)) SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x, evt->y, 0); } else { @@ -261,7 +261,7 @@ ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt) SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED, evt->x, evt->y); } - /* fall throught */ + SDL_FALLTHROUGH; case DWET_SIZE: /* FIXME: what about < 0 */ evt->w -= (windata->theme.right_size + windata->theme.left_size); @@ -312,15 +312,16 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) int kbd_idx; Uint32 unicode; char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; + SDL_Window* grabbed_window = SDL_GetGrabbedWindow(); if (!devdata->use_linux_input) { if (ievt->type == DIET_AXISMOTION) { - if ((devdata->grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) { + if ((grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) { if (ievt->axis == DIAI_X) - SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, + SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, ievt->axisrel, 0, 0); else if (ievt->axis == DIAI_Y) - SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0, + SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, 0, ievt->axisrel, 0); } } @@ -339,7 +340,7 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) SDL_Mouse *mouse = SDL_GetMouse(ievt->device_id); SDL_Window *window = SDL_GetWindowFromID(mouse->focus); #else - SDL_Window *window = devdata->grabbed_window; + SDL_Window *window = grabbed_window; #endif if (window) { DFB_WindowData *windata = @@ -359,10 +360,10 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) } } else if (ievt->flags & DIEF_AXISREL) { if (ievt->axis == DIAI_X) - SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, + SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, ievt->axisrel, 0, 0); else if (ievt->axis == DIAI_Y) - SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0, + SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, 0, ievt->axisrel, 0); } break; @@ -386,19 +387,19 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) break; case DIET_BUTTONPRESS: if (ievt->buttons & DIBM_LEFT) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 1); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 1); if (ievt->buttons & DIBM_MIDDLE) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 2); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 2); if (ievt->buttons & DIBM_RIGHT) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 3); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 3); break; case DIET_BUTTONRELEASE: if (!(ievt->buttons & DIBM_LEFT)) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 1); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 1); if (!(ievt->buttons & DIBM_MIDDLE)) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 2); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 2); if (!(ievt->buttons & DIBM_RIGHT)) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 3); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 3); break; default: break; /* please gcc */ @@ -682,7 +683,7 @@ EnumKeyboards(DFBInputDeviceID device_id, #endif devdata->keyboard[devdata->num_keyboard].id = device_id; devdata->keyboard[devdata->num_keyboard].is_generic = 0; - if (!strncmp("X11", desc.name, 3)) + if (!SDL_strncmp("X11", desc.name, 3)) { devdata->keyboard[devdata->num_keyboard].map = xfree86_scancode_table2; devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(xfree86_scancode_table2); diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_events.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_events.h index e1bddd585..276d972c6 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_events.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_modes.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_modes.c index 114d95c5f..88fa0568c 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_modes.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_modes.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_modes.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_modes.h index 43b07fe48..22727aa4e 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_modes.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_modes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_mouse.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_mouse.c index f86e13dc4..2457aa903 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_mouse.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_mouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -164,7 +164,7 @@ DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) p = surface->pixels; for (i = 0; i < surface->h; i++) - memcpy((char *) dest + i * pitch, + SDL_memcpy((char *) dest + i * pitch, (char *) p + i * surface->pitch, 4 * surface->w); curdata->surf->Unlock(curdata->surf); diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_mouse.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_mouse.h index 43a705f41..f5c207645 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_mouse.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_opengl.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_opengl.c index 7a841ec43..a1ab96c4a 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_opengl.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_opengl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -47,7 +47,7 @@ struct SDL_GLDriverData }; #define OPENGL_REQUIRS_DLOPEN -#if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN) +#if defined(OPENGL_REQUIRS_DLOPEN) && defined(HAVE_DLOPEN) #include #define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL)) #define GL_LoadFunction dlsym diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_opengl.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_opengl.h index c4e05a2f0..be02c7df1 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_opengl.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_render.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_render.c index 45114dc11..257e95005 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_render.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_render.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -324,6 +324,22 @@ DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture) return 1; } + +/* Copy the SDL_Surface palette to the DirectFB texture palette */ +void DirectFB_SetTexturePalette(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Palette *pal) +{ + int i; + DFBColor dfbpal[256]; + DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; + for (i = 0; i < pal->ncolors; i++) { + dfbpal[i].a = pal->colors[i].a; + dfbpal[i].r = pal->colors[i].r; + dfbpal[i].g = pal->colors[i].g; + dfbpal[i].b = pal->colors[i].b; + } + data->palette->SetEntries(data->palette, dfbpal, pal->ncolors, 0); +} + static int DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { @@ -615,6 +631,59 @@ DirectFB_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const return 0; } +static int +DirectFB_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + int i; + int count = indices ? num_indices : num_vertices; + float *verts; + int sz = 2 + 4 + (texture ? 2 : 0); + + verts = (float *) SDL_AllocateRenderVertices(renderer, count * sz * sizeof (float), 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); + + *(verts++) = xy_[0] * scale_x; + *(verts++) = xy_[1] * scale_y; + + *(verts++) = col_.r; + *(verts++) = col_.g; + *(verts++) = col_.b; + *(verts++) = col_.a; + + if (texture) { + float *uv_ = (float *)((char*)uv + j * uv_stride); + *(verts++) = uv_[0]; + *(verts++) = uv_[1]; + } + } + return 0; +} + static int DirectFB_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) { @@ -648,15 +717,6 @@ DirectFB_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture return 0; } -static int -DirectFB_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - return SDL_Unsupported(); -} - - static int DirectFB_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { @@ -814,8 +874,145 @@ DirectFB_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void * break; } - case SDL_RENDERCMD_COPY_EX: - break; /* unsupported */ + + case SDL_RENDERCMD_GEOMETRY: { + const float *verts = (float *) (((Uint8 *) vertices) + cmd->data.draw.first); + SDL_Texture *texture = cmd->data.draw.texture; + const size_t count = cmd->data.draw.count; + + Uint8 save_r = cmd->data.draw.r; + Uint8 save_g = cmd->data.draw.g; + Uint8 save_b = cmd->data.draw.b; + Uint8 save_a = cmd->data.draw.a; + + int j; + for (j = 0; j < count; j += 3) + { + float x1, y1, r1, g1, b1, a1, u1, v1; + float x2, y2, r2, g2, b2, a2, u2, v2; + float x3, y3, r3, g3, b3, a3, u3, v3; + + x1 = *(verts++); + y1 = *(verts++); + r1 = *(verts++); + g1 = *(verts++); + b1 = *(verts++); + a1 = *(verts++); + if (texture) { + u1 = *(verts++); + v1 = *(verts++); + } + x2 = *(verts++); + y2 = *(verts++); + r2 = *(verts++); + g2 = *(verts++); + b2 = *(verts++); + a2 = *(verts++); + if (texture) { + u2 = *(verts++); + v2 = *(verts++); + } + x3 = *(verts++); + y3 = *(verts++); + r3 = *(verts++); + g3 = *(verts++); + b3 = *(verts++); + a3 = *(verts++); + if (texture) { + u3 = *(verts++); + v3 = *(verts++); + } + + + if (texture) { + DFBVertex vertices[3]; + + DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; + + DFBSurfaceBlittingFlags flags = 0; + + int r = (r1 + r2 + r3) / 3; + int g = (g1 + g2 + g3) / 3; + int b = (b1 + b2 + b3) / 3; + int a = (a1 + a2 + a3) / 3; + + + if (texturedata->isDirty) { + const SDL_Rect rect = { 0, 0, texture->w, texture->h }; + DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch); + } + + if (a != 0xFF) { + flags |= DSBLIT_BLEND_COLORALPHA; + } + + if ((r & g & b) != 0xFF) { + flags |= DSBLIT_COLORIZE; + } + + destsurf->SetColor(destsurf, r, g, b, a); + + /* ???? flags |= DSBLIT_SRC_PREMULTCOLOR; */ + + SetBlendMode(data, texture->blendMode, texturedata); + + destsurf->SetBlittingFlags(destsurf, data->blitFlags | flags); + +#if (DFB_VERSION_ATLEAST(1,2,0)) + destsurf->SetRenderOptions(destsurf, texturedata->render_options); +#endif + + vertices[0].x = x1; + vertices[0].y = y1; + vertices[0].z = 0; + vertices[0].w = 0; + vertices[0].s = u1; + vertices[0].t = v1; + + vertices[1].x = x2; + vertices[1].y = y2; + vertices[1].z = 0; + vertices[1].w = 0; + vertices[1].s = u2; + vertices[1].t = v2; + + vertices[2].x = x3; + vertices[2].y = y3; + vertices[2].z = 0; + vertices[2].w = 0; + vertices[2].s = u3; + vertices[2].t = v3; + + destsurf->TextureTriangles(destsurf, texturedata->surface, vertices, NULL, 3, DTTF_LIST); + } else { + DFBTriangle tris; + tris.x1 = x1; + tris.y1 = y1; + tris.x2 = x2; + tris.y2 = y2; + tris.x3 = x3; + tris.y3 = y3; + + cmd->data.draw.r = (r1 + r2 + r3) / 3; + cmd->data.draw.g = (g1 + g2 + g3) / 3; + cmd->data.draw.b = (b1 + b2 + b3) / 3; + cmd->data.draw.a = (a1 + a2 + a3) / 3; + + PrepareDraw(renderer, cmd); + + destsurf->FillTriangles(destsurf, &tris, 1); + } + } + + cmd->data.draw.r = save_r; + cmd->data.draw.g = save_g; + cmd->data.draw.b = save_b; + cmd->data.draw.a = save_a; + break; + } + + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; case SDL_RENDERCMD_NO_OP: break; @@ -984,9 +1181,9 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->QueueSetDrawColor = DirectFB_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = DirectFB_QueueDrawPoints; renderer->QueueDrawLines = DirectFB_QueueDrawPoints; /* lines and points queue vertices the same way. */ + renderer->QueueGeometry = DirectFB_QueueGeometry; renderer->QueueFillRects = DirectFB_QueueFillRects; renderer->QueueCopy = DirectFB_QueueCopy; - renderer->QueueCopyEx = DirectFB_QueueCopyEx; renderer->RunCommandQueue = DirectFB_RunCommandQueue; renderer->RenderPresent = DirectFB_RenderPresent; diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_render.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_render.h index aa0ceb47f..b8ebae2cc 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_render.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_render.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_shape.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_shape.c index 153a0c8e6..da2290f6d 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_shape.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_shape.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,7 +34,7 @@ DirectFB_CreateShaper(SDL_Window* window) { SDL_ShapeData* data; int resized_properly; - result = malloc(sizeof(SDL_WindowShaper)); + result = SDL_malloc(sizeof(SDL_WindowShaper)); result->window = window; result->mode.mode = ShapeModeDefault; result->mode.parameters.binarizationCutoff = 1; diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_shape.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_shape.h index b98901be0..579e5e4b1 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_shape.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_shape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.c index 5ea61a102..cce1ee5fe 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -113,7 +113,8 @@ DirectFB_CreateDevice(int devindex) device->MaximizeWindow = DirectFB_MaximizeWindow; device->MinimizeWindow = DirectFB_MinimizeWindow; device->RestoreWindow = DirectFB_RestoreWindow; - device->SetWindowGrab = DirectFB_SetWindowGrab; + device->SetWindowMouseGrab = DirectFB_SetWindowMouseGrab; + device->SetWindowKeyboardGrab = DirectFB_SetWindowKeyboardGrab; device->DestroyWindow = DirectFB_DestroyWindow; device->GetWindowWMInfo = DirectFB_GetWindowWMInfo; @@ -200,7 +201,7 @@ static int readBoolEnv(const char *env_name, int def_val) stemp = SDL_getenv(env_name); if (stemp) - return atoi(stemp); + return SDL_atoi(stemp); else return def_val; } @@ -260,7 +261,6 @@ DirectFB_VideoInit(_THIS) devdata->dfb = dfb; devdata->firstwin = NULL; - devdata->grabbed_window = NULL; _this->driverdata = devdata; diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.h index 6acde7fb0..17bbdea28 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -153,10 +153,6 @@ struct _DFB_DeviceData int use_linux_input; int has_own_wm; - - /* window grab */ - SDL_Window *grabbed_window; - /* global events */ IDirectFBEventBuffer *events; }; diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_vulkan.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_vulkan.c index 3a2acae56..398ba55ba 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_vulkan.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_vulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_vulkan.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_vulkan.h index 2e1698035..1e6eb9641 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_vulkan.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_vulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.c index fdba402c8..7dfda6472 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -227,7 +227,7 @@ DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) p = surface->pixels; for (i = 0; i < surface->h; i++) - memcpy((char *) dest + i * pitch, + SDL_memcpy((char *) dest + i * pitch, (char *) p + i * surface->pitch, 4 * surface->w); SDL_DFB_CHECK(windata->icon->Unlock(windata->icon)); @@ -383,25 +383,26 @@ DirectFB_RestoreWindow(_THIS, SDL_Window * window) } void -DirectFB_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +DirectFB_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { - SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); - DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL); - if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) { - if (gwindata != NULL) - { - SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin)); - SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin)); - } + if (grabbed) { SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin)); - SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin)); - devdata->grabbed_window = window; } else { SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin)); + } +} + +void +DirectFB_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + SDL_DFB_WINDOWDATA(window); + + if (grabbed) { + SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin)); + } else { SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin)); - devdata->grabbed_window = NULL; } } diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.h index 1d789c718..fc0b22ccc 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -69,7 +69,8 @@ extern void DirectFB_RaiseWindow(_THIS, SDL_Window * window); extern void DirectFB_MaximizeWindow(_THIS, SDL_Window * window); extern void DirectFB_MinimizeWindow(_THIS, SDL_Window * window); extern void DirectFB_RestoreWindow(_THIS, SDL_Window * window); -extern void DirectFB_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void DirectFB_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void DirectFB_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void DirectFB_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); diff --git a/Engine/lib/sdl/src/video/dummy/SDL_nullevents.c b/Engine/lib/sdl/src/video/dummy/SDL_nullevents.c index 4db63b618..e58ba2978 100644 --- a/Engine/lib/sdl/src/video/dummy/SDL_nullevents.c +++ b/Engine/lib/sdl/src/video/dummy/SDL_nullevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/dummy/SDL_nullevents_c.h b/Engine/lib/sdl/src/video/dummy/SDL_nullevents_c.h index ac56d68df..54eb74c91 100644 --- a/Engine/lib/sdl/src/video/dummy/SDL_nullevents_c.h +++ b/Engine/lib/sdl/src/video/dummy/SDL_nullevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/dummy/SDL_nullframebuffer.c b/Engine/lib/sdl/src/video/dummy/SDL_nullframebuffer.c index 803f131fc..dd7cbbd16 100644 --- a/Engine/lib/sdl/src/video/dummy/SDL_nullframebuffer.c +++ b/Engine/lib/sdl/src/video/dummy/SDL_nullframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,17 +33,13 @@ int SDL_DUMMY_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * forma SDL_Surface *surface; const Uint32 surface_format = SDL_PIXELFORMAT_RGB888; int w, h; - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; /* Free the old framebuffer surface */ - surface = (SDL_Surface *) SDL_GetWindowData(window, DUMMY_SURFACE); - SDL_FreeSurface(surface); + SDL_DUMMY_DestroyWindowFramebuffer(_this, window); /* Create a new one */ - SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); SDL_GetWindowSize(window, &w, &h); - surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask); + surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, surface_format); if (!surface) { return -1; } @@ -69,7 +65,7 @@ int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect /* Send the data to the display */ if (SDL_getenv("SDL_VIDEO_DUMMY_SAVE_FRAMES")) { char file[128]; - SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", + SDL_snprintf(file, sizeof(file), "SDL_window%" SDL_PRIu32 "-%8.8d.bmp", SDL_GetWindowID(window), ++frame_number); SDL_SaveBMP(surface, file); } diff --git a/Engine/lib/sdl/src/video/dummy/SDL_nullframebuffer_c.h b/Engine/lib/sdl/src/video/dummy/SDL_nullframebuffer_c.h index 5b1dea3d7..cd8158e47 100644 --- a/Engine/lib/sdl/src/video/dummy/SDL_nullframebuffer_c.h +++ b/Engine/lib/sdl/src/video/dummy/SDL_nullframebuffer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.c b/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.c index 71ae6879f..aafed848d 100644 --- a/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.c +++ b/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -116,6 +116,7 @@ DUMMY_VideoInit(_THIS) SDL_DisplayMode mode; /* Use a fake 32-bpp desktop mode */ + SDL_zero(mode); mode.format = SDL_PIXELFORMAT_RGB888; mode.w = 1024; mode.h = 768; @@ -125,7 +126,6 @@ DUMMY_VideoInit(_THIS) return -1; } - SDL_zero(mode); SDL_AddDisplayMode(&_this->displays[0], &mode); /* We're done! */ diff --git a/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.h b/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.h index e5c01d9b1..c07aaf144 100644 --- a/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.h +++ b/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.c index c9e764e67..39578f854 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -409,7 +409,22 @@ static EM_BOOL Emscripten_HandleWheel(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData) { SDL_WindowData *window_data = userData; - SDL_SendMouseWheel(window_data->window, 0, (float)wheelEvent->deltaX, (float)-wheelEvent->deltaY, SDL_MOUSEWHEEL_NORMAL); + + float deltaY = wheelEvent->deltaY; + + switch (wheelEvent->deltaMode) { + case DOM_DELTA_PIXEL: + deltaY /= 100; /* 100 pixels make up a step */ + break; + case DOM_DELTA_LINE: + deltaY /= 3; /* 3 lines make up a step */ + break; + case DOM_DELTA_PAGE: + deltaY *= 80; /* A page makes up 80 steps */ + break; + } + + SDL_SendMouseWheel(window_data->window, 0, (float)wheelEvent->deltaX, -deltaY, SDL_MOUSEWHEEL_NORMAL); return SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE; } @@ -478,7 +493,7 @@ static EM_BOOL Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData) { Uint32 scancode; - SDL_bool prevent_default; + SDL_bool prevent_default = SDL_FALSE; SDL_bool is_nav_key; /* .keyCode is deprecated, but still the most reliable way to get keys */ @@ -562,12 +577,10 @@ Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, voi break; } } - SDL_SendKeyboardKey(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode); + prevent_default = SDL_SendKeyboardKey(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode); } } - prevent_default = SDL_GetEventState(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_KEYDOWN : SDL_KEYUP) == SDL_ENABLE; - /* if TEXTINPUT events are enabled we can't prevent keydown or we won't get keypress * we need to ALWAYS prevent backspace and tab otherwise chrome takes action and does bad navigation UX */ @@ -576,7 +589,9 @@ Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, voi keyEvent->keyCode == 37 /* left */ || keyEvent->keyCode == 38 /* up */ || keyEvent->keyCode == 39 /* right */ || - keyEvent->keyCode == 40 /* down */; + keyEvent->keyCode == 40 /* down */ || + (keyEvent->keyCode >= 112 && keyEvent->keyCode <= 135) /* F keys*/ || + keyEvent->ctrlKey; if (eventType == EMSCRIPTEN_EVENT_KEYDOWN && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE && !is_nav_key) prevent_default = SDL_FALSE; @@ -605,9 +620,6 @@ Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChang window_data->window->flags |= window_data->requested_fullscreen_mode; window_data->requested_fullscreen_mode = 0; - - if(!window_data->requested_fullscreen_mode) - window_data->window->flags |= SDL_WINDOW_FULLSCREEN; /*we didn't request fullscreen*/ } else { diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.h b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.h index 04f038ece..cc93e1a79 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.h +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c index 62193b910..d4e9cb8e8 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -109,6 +109,7 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); + SDL2.data32Data = data; } var data32 = SDL2.data32; num = data32.length; @@ -118,7 +119,7 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec // } // the following code is faster though, because // .set() is almost free - easily 10x faster due to - // native memcpy efficiencies, and the remaining loop + // native SDL_memcpy efficiencies, and the remaining loop // just stores, not load + store, so it is faster data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; @@ -156,14 +157,6 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec return 0; }, surface->w, surface->h, surface->pixels); - /*if (SDL_getenv("SDL_VIDEO_Emscripten_SAVE_FRAMES")) { - static int frame_number = 0; - char file[128]; - SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", - SDL_GetWindowID(window), ++frame_number); - SDL_SaveBMP(surface, file); - }*/ - if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) { /* give back control to browser for screen refresh */ emscripten_sleep(0); diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.h b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.h index 6d413dd32..ec59281af 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.h +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c index 8d9689612..e73072590 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.h b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.h index 0a9c0d8af..cfc36aee3 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.h +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenopengles.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenopengles.c index 6544bc613..a450c8c89 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenopengles.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenopengles.h b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenopengles.h index 8a8c5f874..081b02fef 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenopengles.h +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c index 23cf6f43f..f6ee1e7e5 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -43,6 +43,7 @@ static int Emscripten_VideoInit(_THIS); static int Emscripten_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); static void Emscripten_VideoQuit(_THIS); static int Emscripten_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); +static int Emscripten_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi); static int Emscripten_CreateWindow(_THIS, SDL_Window * window); static void Emscripten_SetWindowSize(_THIS, SDL_Window * window); @@ -82,6 +83,7 @@ Emscripten_CreateDevice(int devindex) device->VideoInit = Emscripten_VideoInit; device->VideoQuit = Emscripten_VideoQuit; device->GetDisplayUsableBounds = Emscripten_GetDisplayUsableBounds; + device->GetDisplayDPI = Emscripten_GetDisplayDPI; device->SetDisplayMode = Emscripten_SetDisplayMode; @@ -98,7 +100,7 @@ Emscripten_CreateDevice(int devindex) device->MaximizeWindow = Emscripten_MaximizeWindow; device->MinimizeWindow = Emscripten_MinimizeWindow; device->RestoreWindow = Emscripten_RestoreWindow; - device->SetWindowGrab = Emscripten_SetWindowGrab;*/ + device->SetWindowMouseGrab = Emscripten_SetWindowMouseGrab;*/ device->DestroyWindow = Emscripten_DestroyWindow; device->SetWindowFullscreen = Emscripten_SetWindowFullscreen; @@ -137,14 +139,7 @@ Emscripten_VideoInit(_THIS) /* Use a fake 32-bpp desktop mode */ mode.format = SDL_PIXELFORMAT_RGB888; - - mode.w = EM_ASM_INT_V({ - return screen.width; - }); - - mode.h = EM_ASM_INT_V({ - return screen.height; - }); + emscripten_get_screen_size(&mode.w, &mode.h); mode.refresh_rate = 0; mode.driverdata = NULL; @@ -189,6 +184,27 @@ Emscripten_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * return 0; } +static int +Emscripten_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi_out, float * hdpi_out, float * vdpi_out) +{ + const float dpi_reference = 96.0f; + float dpi; + + dpi = (float)emscripten_get_device_pixel_ratio() * dpi_reference; + + if (ddpi_out) { + *ddpi_out = dpi; + } + if (hdpi_out) { + *hdpi_out = dpi; + } + if (vdpi_out) { + *vdpi_out = dpi; + } + + return 0; +} + static void Emscripten_PumpEvents(_THIS) { @@ -359,12 +375,7 @@ Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * di static void Emscripten_SetWindowTitle(_THIS, SDL_Window * window) { - EM_ASM_INT({ - if (typeof setWindowTitle !== 'undefined') { - setWindowTitle(UTF8ToString($0)); - } - return 0; - }, window->title); + emscripten_set_window_title(window->title); } #endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */ diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.h b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.h index d15800fbf..e87788d3f 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.h +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/haiku/SDL_BApp.h b/Engine/lib/sdl/src/video/haiku/SDL_BApp.h new file mode 100644 index 000000000..215f83662 --- /dev/null +++ b/Engine/lib/sdl/src/video/haiku/SDL_BApp.h @@ -0,0 +1,431 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef SDL_BAPP_H +#define SDL_BAPP_H + +#include +#include +#include +#if SDL_VIDEO_OPENGL +#include +#endif + +#include "../../video/haiku/SDL_bkeyboard.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../SDL_internal.h" + +#include "SDL_video.h" + +/* Local includes */ +#include "../../events/SDL_events_c.h" +#include "../../video/haiku/SDL_bframebuffer.h" + +#ifdef __cplusplus +} +#endif + +#include + + + + +/* Forward declarations */ +class SDL_BWin; + +/* Message constants */ +enum ToSDL { + /* Intercepted by BWindow on its way to BView */ + BAPP_MOUSE_MOVED, + BAPP_MOUSE_BUTTON, + BAPP_MOUSE_WHEEL, + BAPP_KEY, + BAPP_REPAINT, /* from _UPDATE_ */ + /* From BWindow */ + BAPP_MAXIMIZE, /* from B_ZOOM */ + BAPP_MINIMIZE, + BAPP_RESTORE, /* TODO: IMPLEMENT! */ + BAPP_SHOW, + BAPP_HIDE, + BAPP_MOUSE_FOCUS, /* caused by MOUSE_MOVE */ + BAPP_KEYBOARD_FOCUS, /* from WINDOW_ACTIVATED */ + BAPP_WINDOW_CLOSE_REQUESTED, + BAPP_WINDOW_MOVED, + BAPP_WINDOW_RESIZED, + BAPP_SCREEN_CHANGED +}; + + + +/* Create a descendant of BApplication */ +class SDL_BApp : public BApplication { +public: + SDL_BApp(const char* signature) : + BApplication(signature) { +#if SDL_VIDEO_OPENGL + _current_context = NULL; +#endif + } + + + virtual ~SDL_BApp() { + } + + + virtual void RefsReceived(BMessage* message) { + char filePath[512]; + entry_ref entryRef; + for (int32 i = 0; message->FindRef("refs", i, &entryRef) == B_OK; i++) { + BPath referencePath = BPath(&entryRef); + SDL_SendDropFile(NULL, referencePath.Path()); + } + return; + } + + /* Event-handling functions */ + virtual void MessageReceived(BMessage* message) { + /* Sort out SDL-related messages */ + switch ( message->what ) { + case BAPP_MOUSE_MOVED: + _HandleMouseMove(message); + break; + + case BAPP_MOUSE_BUTTON: + _HandleMouseButton(message); + break; + + case BAPP_MOUSE_WHEEL: + _HandleMouseWheel(message); + break; + + case BAPP_KEY: + _HandleKey(message); + break; + + case BAPP_REPAINT: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_EXPOSED); + break; + + case BAPP_MAXIMIZE: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MAXIMIZED); + break; + + case BAPP_MINIMIZE: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MINIMIZED); + break; + + case BAPP_SHOW: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_SHOWN); + break; + + case BAPP_HIDE: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_HIDDEN); + break; + + case BAPP_MOUSE_FOCUS: + _HandleMouseFocus(message); + break; + + case BAPP_KEYBOARD_FOCUS: + _HandleKeyboardFocus(message); + break; + + case BAPP_WINDOW_CLOSE_REQUESTED: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_CLOSE); + break; + + case BAPP_WINDOW_MOVED: + _HandleWindowMoved(message); + break; + + case BAPP_WINDOW_RESIZED: + _HandleWindowResized(message); + break; + + case B_LOCALE_CHANGED: + SDL_SendLocaleChangedEvent(); + break; + + case BAPP_SCREEN_CHANGED: + /* TODO: Handle screen resize or workspace change */ + break; + + default: + BApplication::MessageReceived(message); + break; + } + } + + /* Window creation/destruction methods */ + int32 GetID(SDL_Window *win) { + int32 i; + for(i = 0; i < _GetNumWindowSlots(); ++i) { + if( GetSDLWindow(i) == NULL ) { + _SetSDLWindow(win, i); + return i; + } + } + + /* Expand the vector if all slots are full */ + if( i == _GetNumWindowSlots() ) { + _PushBackWindow(win); + return i; + } + + /* TODO: error handling */ + return 0; + } + + /* FIXME: Bad coding practice, but I can't include SDL_BWin.h here. Is + there another way to do this? */ + void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */ + + + SDL_Window *GetSDLWindow(int32 winID) { + return _window_map[winID]; + } + +#if SDL_VIDEO_OPENGL + BGLView *GetCurrentContext() { + return _current_context; + } + + void SetCurrentContext(BGLView *newContext) { + if(_current_context) + _current_context->UnlockGL(); + _current_context = newContext; + if (_current_context) + _current_context->LockGL(); + } +#endif + +private: + /* Event management */ + void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) { + SDL_Window *win; + int32 winID; + if( + !_GetWinID(msg, &winID) + ) { + return; + } + win = GetSDLWindow(winID); + SDL_SendWindowEvent(win, sdlEventType, 0, 0); + } + + void _HandleMouseMove(BMessage *msg) { + SDL_Window *win; + int32 winID; + int32 x = 0, y = 0; + if( + !_GetWinID(msg, &winID) || + msg->FindInt32("x", &x) != B_OK || /* x movement */ + msg->FindInt32("y", &y) != B_OK /* y movement */ + ) { + return; + } + win = GetSDLWindow(winID); + + // Simple relative mode support for mouse. + if (SDL_GetMouse()->relative_mode) { + int winWidth, winHeight, winPosX, winPosY; + SDL_GetWindowSize(win, &winWidth, &winHeight); + SDL_GetWindowPosition(win, &winPosX, &winPosY); + int dx = x - (winWidth / 2); + int dy = y - (winHeight / 2); + SDL_SendMouseMotion(win, 0, SDL_GetMouse()->relative_mode, dx, dy); + set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2)); + if (!be_app->IsCursorHidden()) + be_app->HideCursor(); + } else { + SDL_SendMouseMotion(win, 0, 0, x, y); + if (SDL_ShowCursor(-1) && be_app->IsCursorHidden()) + be_app->ShowCursor(); + } + } + + void _HandleMouseButton(BMessage *msg) { + SDL_Window *win; + int32 winID; + int32 button, state; /* left/middle/right, pressed/released */ + if( + !_GetWinID(msg, &winID) || + msg->FindInt32("button-id", &button) != B_OK || + msg->FindInt32("button-state", &state) != B_OK + ) { + return; + } + win = GetSDLWindow(winID); + SDL_SendMouseButton(win, 0, state, button); + } + + void _HandleMouseWheel(BMessage *msg) { + SDL_Window *win; + int32 winID; + int32 xTicks, yTicks; + if( + !_GetWinID(msg, &winID) || + msg->FindInt32("xticks", &xTicks) != B_OK || + msg->FindInt32("yticks", &yTicks) != B_OK + ) { + return; + } + win = GetSDLWindow(winID); + SDL_SendMouseWheel(win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL); + } + + void _HandleKey(BMessage *msg) { + int32 scancode, state; /* scancode, pressed/released */ + if( + msg->FindInt32("key-state", &state) != B_OK || + msg->FindInt32("key-scancode", &scancode) != B_OK + ) { + return; + } + + /* Make sure this isn't a repeated event (key pressed and held) */ + if(state == SDL_PRESSED && HAIKU_GetKeyState(scancode) == SDL_PRESSED) { + return; + } + HAIKU_SetKeyState(scancode, state); + SDL_SendKeyboardKey(state, HAIKU_GetScancodeFromBeKey(scancode)); + + if (state == SDL_PRESSED && SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { + const int8 *keyUtf8; + ssize_t count; + if (msg->FindData("key-utf8", B_INT8_TYPE, (const void**)&keyUtf8, &count) == B_OK) { + char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; + SDL_zeroa(text); + SDL_memcpy(text, keyUtf8, count); + SDL_SendKeyboardText(text); + } + } + } + + void _HandleMouseFocus(BMessage *msg) { + SDL_Window *win; + int32 winID; + bool bSetFocus; /* If false, lose focus */ + if( + !_GetWinID(msg, &winID) || + msg->FindBool("focusGained", &bSetFocus) != B_OK + ) { + return; + } + win = GetSDLWindow(winID); + if(bSetFocus) { + SDL_SetMouseFocus(win); + } else if(SDL_GetMouseFocus() == win) { + /* Only lose all focus if this window was the current focus */ + SDL_SetMouseFocus(NULL); + } + } + + void _HandleKeyboardFocus(BMessage *msg) { + SDL_Window *win; + int32 winID; + bool bSetFocus; /* If false, lose focus */ + if( + !_GetWinID(msg, &winID) || + msg->FindBool("focusGained", &bSetFocus) != B_OK + ) { + return; + } + win = GetSDLWindow(winID); + if(bSetFocus) { + SDL_SetKeyboardFocus(win); + } else if(SDL_GetKeyboardFocus() == win) { + /* Only lose all focus if this window was the current focus */ + SDL_SetKeyboardFocus(NULL); + } + } + + void _HandleWindowMoved(BMessage *msg) { + SDL_Window *win; + int32 winID; + int32 xPos, yPos; + /* Get the window id and new x/y position of the window */ + if( + !_GetWinID(msg, &winID) || + msg->FindInt32("window-x", &xPos) != B_OK || + msg->FindInt32("window-y", &yPos) != B_OK + ) { + return; + } + win = GetSDLWindow(winID); + SDL_SendWindowEvent(win, SDL_WINDOWEVENT_MOVED, xPos, yPos); + } + + void _HandleWindowResized(BMessage *msg) { + SDL_Window *win; + int32 winID; + int32 w, h; + /* Get the window id ]and new x/y position of the window */ + if( + !_GetWinID(msg, &winID) || + msg->FindInt32("window-w", &w) != B_OK || + msg->FindInt32("window-h", &h) != B_OK + ) { + return; + } + win = GetSDLWindow(winID); + SDL_SendWindowEvent(win, SDL_WINDOWEVENT_RESIZED, w, h); + } + + bool _GetWinID(BMessage *msg, int32 *winID) { + return msg->FindInt32("window-id", winID) == B_OK; + } + + + + /* Vector functions: Wraps vector stuff in case we need to change + implementation */ + void _SetSDLWindow(SDL_Window *win, int32 winID) { + _window_map[winID] = win; + } + + int32 _GetNumWindowSlots() { + return _window_map.size(); + } + + + void _PopBackWindow() { + _window_map.pop_back(); + } + + void _PushBackWindow(SDL_Window *win) { + _window_map.push_back(win); + } + + + /* Members */ + std::vector _window_map; /* Keeps track of SDL_Windows by index-id */ + +#if SDL_VIDEO_OPENGL + BGLView *_current_context; +#endif +}; + +#endif diff --git a/Engine/lib/sdl/src/video/haiku/SDL_BWin.h b/Engine/lib/sdl/src/video/haiku/SDL_BWin.h index 34f0d5f5d..1ac517164 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_BWin.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_BWin.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,8 +37,8 @@ extern "C" { #include #include +#include #include -#include #if SDL_VIDEO_OPENGL #include #endif @@ -57,19 +57,48 @@ enum WinCommands { BWIN_SET_TITLE, BWIN_SET_BORDERED, BWIN_SET_RESIZABLE, - BWIN_FULLSCREEN + BWIN_FULLSCREEN, + BWIN_UPDATE_FRAMEBUFFER, + BWIN_MINIMUM_SIZE_WINDOW }; +// non-OpenGL framebuffer view +class SDL_BView: public BView +{ +public: + SDL_BView(BRect frame, const char* name, uint32 resizingMode) + : BView(frame, name, resizingMode, B_WILL_DRAW), + fBitmap(NULL) + { + } -class SDL_BWin:public BDirectWindow + void Draw(BRect dirty) + { + if (fBitmap != NULL) + DrawBitmap(fBitmap, B_ORIGIN); + } + + void SetBitmap(BBitmap *bitmap) + { + fBitmap = bitmap; + } + +private: + BBitmap *fBitmap; +}; + +class SDL_BWin: public BWindow { public: /* Constructor/Destructor */ SDL_BWin(BRect bounds, window_look look, uint32 flags) - : BDirectWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags) + : BWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags) { _last_buttons = 0; + _cur_view = NULL; + _SDL_View = NULL; + #if SDL_VIDEO_OPENGL _SDL_GLView = NULL; _gl_type = 0; @@ -78,59 +107,88 @@ class SDL_BWin:public BDirectWindow _inhibit_resize = false; _mouse_focused = false; _prev_frame = NULL; + _fullscreen = NULL; /* Handle framebuffer stuff */ - _connected = _connection_disabled = false; - _buffer_created = _buffer_dirty = false; - _trash_window_buffer = false; _buffer_locker = new BLocker(); _bitmap = NULL; - _clips = NULL; - _num_clips = 0; - -#ifdef DRAWTHREAD - _draw_thread_id = spawn_thread(HAIKU_DrawThread, "drawing_thread", - B_NORMAL_PRIORITY, (void*) this); - resume_thread(_draw_thread_id); -#endif } virtual ~ SDL_BWin() { Lock(); - _connection_disabled = true; - int32 result; + + if (_SDL_View != NULL && _SDL_View != _cur_view) { + delete _SDL_View; + _SDL_View = NULL; + } #if SDL_VIDEO_OPENGL if (_SDL_GLView) { - _SDL_GLView->UnlockGL(); - RemoveChild(_SDL_GLView); /* Why was this outside the if - statement before? */ + if (((SDL_BApp*)be_app)->GetCurrentContext() == _SDL_GLView) + ((SDL_BApp*)be_app)->SetCurrentContext(NULL); + if (_SDL_GLView == _cur_view) + RemoveChild(_SDL_GLView); + _SDL_GLView = NULL; + // _SDL_GLView deleted by HAIKU_GL_DeleteContext } #endif Unlock(); -#if SDL_VIDEO_OPENGL - if (_SDL_GLView) { - delete _SDL_GLView; - } -#endif delete _prev_frame; /* Clean up framebuffer stuff */ _buffer_locker->Lock(); -#ifdef DRAWTHREAD - wait_for_thread(_draw_thread_id, &result); -#endif - free(_clips); delete _buffer_locker; } + + void SetCurrentView(BView *view) + { + if (_cur_view != view) { + if (_cur_view != NULL) + RemoveChild(_cur_view); + _cur_view = view; + if (_cur_view != NULL) + AddChild(_cur_view); + } + } + void UpdateCurrentView() + { + if (_SDL_GLView != NULL) { + SetCurrentView(_SDL_GLView); + } else if (_SDL_View != NULL) { + SetCurrentView(_SDL_View); + } else { + SetCurrentView(NULL); + } + } + + SDL_BView *CreateView() { + Lock(); + if (_SDL_View == NULL) { + _SDL_View = new SDL_BView(Bounds(), "SDL View", B_FOLLOW_ALL_SIDES); + UpdateCurrentView(); + } + Unlock(); + return _SDL_View; + } + + void RemoveView() { + Lock(); + if(_SDL_View != NULL) { + SDL_BView *oldView = _SDL_View; + _SDL_View = NULL; + UpdateCurrentView(); + delete oldView; + } + Unlock(); + } /* * * * * OpenGL functionality * * * * */ #if SDL_VIDEO_OPENGL - virtual BGLView *CreateGLView(Uint32 gl_flags) { + BGLView *CreateGLView(Uint32 gl_flags) { Lock(); if (_SDL_GLView == NULL) { _SDL_GLView = new BGLView(Bounds(), "SDL GLView", @@ -138,93 +196,29 @@ class SDL_BWin:public BDirectWindow (B_WILL_DRAW | B_FRAME_EVENTS), gl_flags); _gl_type = gl_flags; + UpdateCurrentView(); } - AddChild(_SDL_GLView); - _SDL_GLView->SetEventMask(B_POINTER_EVENTS | B_KEYBOARD_EVENTS, B_NO_POINTER_HISTORY); - _SDL_GLView->EnableDirectMode(true); - _SDL_GLView->LockGL(); /* "New" GLViews are created */ Unlock(); - return (_SDL_GLView); + return _SDL_GLView; } - virtual void RemoveGLView() { + void RemoveGLView() { Lock(); - if(_SDL_GLView) { - _SDL_GLView->UnlockGL(); - RemoveChild(_SDL_GLView); + if(_SDL_GLView != NULL) { + if (((SDL_BApp*)be_app)->GetCurrentContext() == _SDL_GLView) + ((SDL_BApp*)be_app)->SetCurrentContext(NULL); + _SDL_GLView = NULL; + UpdateCurrentView(); + // _SDL_GLView deleted by HAIKU_GL_DeleteContext } Unlock(); } - virtual void SwapBuffers(void) { - _SDL_GLView->UnlockGL(); - _SDL_GLView->LockGL(); + void SwapBuffers(void) { _SDL_GLView->SwapBuffers(); } #endif - /* * * * * Framebuffering* * * * */ - virtual void DirectConnected(direct_buffer_info *info) { - if(!_connected && _connection_disabled) { - return; - } - - /* Determine if the pixel buffer is usable after this update */ - _trash_window_buffer = _trash_window_buffer - || ((info->buffer_state & B_BUFFER_RESIZED) - || (info->buffer_state & B_BUFFER_RESET) - || (info->driver_state == B_MODE_CHANGED)); - LockBuffer(); - - switch(info->buffer_state & B_DIRECT_MODE_MASK) { - case B_DIRECT_START: - _connected = true; - - case B_DIRECT_MODIFY: - if (info->clip_list_count > _num_clips) - { - if(_clips) { - free(_clips); - _clips = NULL; - } - } - - _num_clips = info->clip_list_count; - if (_clips == NULL) - _clips = (clipping_rect *)malloc(_num_clips*sizeof(clipping_rect)); - if(_clips) { - memcpy(_clips, info->clip_list, - _num_clips*sizeof(clipping_rect)); - - _bits = (uint8*) info->bits; - _row_bytes = info->bytes_per_row; - _bounds = info->window_bounds; - _bytes_per_px = info->bits_per_pixel / 8; - _buffer_dirty = true; - } - break; - - case B_DIRECT_STOP: - _connected = false; - break; - } -#if SDL_VIDEO_OPENGL - if(_SDL_GLView) { - _SDL_GLView->DirectConnected(info); - } -#endif - - - /* Call the base object directconnected */ - BDirectWindow::DirectConnected(info); - - UnlockBuffer(); - - } - - - - /* * * * * Event sending * * * * */ /* Hook functions */ virtual void FrameMoved(BPoint origin) { @@ -235,10 +229,10 @@ class SDL_BWin:public BDirectWindow _PostWindowEvent(msg); /* Perform normal hook operations */ - BDirectWindow::FrameMoved(origin); + BWindow::FrameMoved(origin); } - virtual void FrameResized(float width, float height) { + void FrameResized(float width, float height) { /* Post a message to the BApp so that it can handle the window event */ BMessage msg(BAPP_WINDOW_RESIZED); @@ -247,10 +241,10 @@ class SDL_BWin:public BDirectWindow _PostWindowEvent(msg); /* Perform normal hook operations */ - BDirectWindow::FrameResized(width, height); + BWindow::FrameResized(width, height); } - virtual bool QuitRequested() { + bool QuitRequested() { BMessage msg(BAPP_WINDOW_CLOSE_REQUESTED); _PostWindowEvent(msg); @@ -258,13 +252,13 @@ class SDL_BWin:public BDirectWindow return false; } - virtual void WindowActivated(bool active) { + void WindowActivated(bool active) { BMessage msg(BAPP_KEYBOARD_FOCUS); /* Mouse focus sold separately */ msg.AddBool("focusGained", active); _PostWindowEvent(msg); } - virtual void Zoom(BPoint origin, + void Zoom(BPoint origin, float width, float height) { BMessage msg(BAPP_MAXIMIZE); /* Closest thing to maximization Haiku has */ @@ -275,13 +269,13 @@ class SDL_BWin:public BDirectWindow _prev_frame = new BRect(Frame()); /* Perform normal hook operations */ - BDirectWindow::Zoom(origin, width, height); + BWindow::Zoom(origin, width, height); } /* Member functions */ - virtual void Show() { + void Show() { while(IsHidden()) { - BDirectWindow::Show(); + BWindow::Show(); } _shown = true; @@ -289,25 +283,33 @@ class SDL_BWin:public BDirectWindow _PostWindowEvent(msg); } - virtual void Hide() { - BDirectWindow::Hide(); + void Hide() { + BWindow::Hide(); _shown = false; BMessage msg(BAPP_HIDE); _PostWindowEvent(msg); } - virtual void Minimize(bool minimize) { - BDirectWindow::Minimize(minimize); + void Minimize(bool minimize) { + BWindow::Minimize(minimize); int32 minState = (minimize ? BAPP_MINIMIZE : BAPP_RESTORE); BMessage msg(minState); _PostWindowEvent(msg); } + void ScreenChanged(BRect screenFrame, color_space depth) + { + if (_fullscreen) { + MoveTo(screenFrame.left, screenFrame.top); + ResizeTo(screenFrame.Width(), screenFrame.Height()); + } + } + /* BView message interruption */ - virtual void DispatchMessage(BMessage * msg, BHandler * target) + void DispatchMessage(BMessage * msg, BHandler * target) { BPoint where; /* Used by mouse moved */ int32 buttons; /* Used for mouse button events */ @@ -356,7 +358,7 @@ class SDL_BWin:public BDirectWindow } } break; - + case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */ if (msg->FindInt32("key", &key) == B_OK) { _KeyEvent((SDL_Scancode)key, NULL, 0, SDL_PRESSED); @@ -376,15 +378,15 @@ class SDL_BWin:public BDirectWindow - CTRL+Q to close window (and other shortcuts) - PrintScreen to make screenshot into /boot/home - etc.. */ - /* BDirectWindow::DispatchMessage(msg, target); */ + /* BWindow::DispatchMessage(msg, target); */ break; } - BDirectWindow::DispatchMessage(msg, target); + BWindow::DispatchMessage(msg, target); } /* Handle command messages */ - virtual void MessageReceived(BMessage* message) { + void MessageReceived(BMessage* message) { switch (message->what) { /* Handle commands from SDL */ case BWIN_SET_TITLE: @@ -396,12 +398,18 @@ class SDL_BWin:public BDirectWindow case BWIN_RESIZE_WINDOW: _ResizeTo(message); break; - case BWIN_SET_BORDERED: - _SetBordered(message); + case BWIN_SET_BORDERED: { + bool bEnabled; + if (message->FindBool("window-border", &bEnabled) == B_OK) + _SetBordered(bEnabled); break; - case BWIN_SET_RESIZABLE: - _SetResizable(message); + } + case BWIN_SET_RESIZABLE: { + bool bEnabled; + if (message->FindBool("window-resizable", &bEnabled) == B_OK) + _SetResizable(bEnabled); break; + } case BWIN_SHOW_WINDOW: Show(); break; @@ -417,12 +425,34 @@ class SDL_BWin:public BDirectWindow case BWIN_RESTORE_WINDOW: _Restore(); break; - case BWIN_FULLSCREEN: - _SetFullScreen(message); + case BWIN_FULLSCREEN: { + bool fullscreen; + if (message->FindBool("fullscreen", &fullscreen) == B_OK) + _SetFullScreen(fullscreen); break; + } + case BWIN_MINIMUM_SIZE_WINDOW: + _SetMinimumSize(message); + break; + case BWIN_UPDATE_FRAMEBUFFER: { + BMessage* pendingMessage; + while ((pendingMessage + = MessageQueue()->FindMessage(BWIN_UPDATE_FRAMEBUFFER, 0))) { + MessageQueue()->RemoveMessage(pendingMessage); + delete pendingMessage; + } + if (_bitmap != NULL) { + if (_SDL_View != NULL && _cur_view == _SDL_View) + _SDL_View->Draw(Bounds()); + else if (_SDL_GLView != NULL && _cur_view == _SDL_GLView) { + _SDL_GLView->CopyPixelsIn(_bitmap, B_ORIGIN); + } + } + break; + } default: /* Perform normal message handling */ - BDirectWindow::MessageReceived(message); + BWindow::MessageReceived(message); break; } @@ -433,19 +463,9 @@ class SDL_BWin:public BDirectWindow /* Accessor methods */ bool IsShown() { return _shown; } int32 GetID() { return _id; } - uint32 GetRowBytes() { return _row_bytes; } - int32 GetFbX() { return _bounds.left; } - int32 GetFbY() { return _bounds.top; } - bool ConnectionEnabled() { return !_connection_disabled; } - bool Connected() { return _connected; } - clipping_rect *GetClips() { return _clips; } - int32 GetNumClips() { return _num_clips; } - uint8* GetBufferPx() { return _bits; } - int32 GetBytesPerPx() { return _bytes_per_px; } - bool CanTrashWindowBuffer() { return _trash_window_buffer; } - bool BufferExists() { return _buffer_created; } - bool BufferIsDirty() { return _buffer_dirty; } BBitmap *GetBitmap() { return _bitmap; } + BView *GetCurView() { return _cur_view; } + SDL_BView *GetView() { return _SDL_View; } #if SDL_VIDEO_OPENGL BGLView *GetGLView() { return _SDL_GLView; } Uint32 GetGLType() { return _gl_type; } @@ -453,12 +473,9 @@ class SDL_BWin:public BDirectWindow /* Setter methods */ void SetID(int32 id) { _id = id; } - void SetBufferExists(bool bufferExists) { _buffer_created = bufferExists; } void LockBuffer() { _buffer_locker->Lock(); } void UnlockBuffer() { _buffer_locker->Unlock(); } - void SetBufferDirty(bool bufferDirty) { _buffer_dirty = bufferDirty; } - void SetTrashBuffer(bool trash) { _trash_window_buffer = trash; } - void SetBitmap(BBitmap *bitmap) { _bitmap = bitmap; } + void SetBitmap(BBitmap *bitmap) { _bitmap = bitmap; if (_SDL_View != NULL) _SDL_View->SetBitmap(bitmap); } private: @@ -564,7 +581,10 @@ private: ) { return; } - MoveTo(x, y); + if (_fullscreen) + _non_fullscreen_frame.OffsetTo(x, y); + else + MoveTo(x, y); } void _ResizeTo(BMessage *msg) { @@ -575,27 +595,48 @@ private: ) { return; } - ResizeTo(w, h); + if (_fullscreen) { + _non_fullscreen_frame.right = _non_fullscreen_frame.left + w; + _non_fullscreen_frame.bottom = _non_fullscreen_frame.top + h; + } else + ResizeTo(w, h); } - void _SetBordered(BMessage *msg) { - bool bEnabled; - if(msg->FindBool("window-border", &bEnabled) != B_OK) { - return; - } - SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK); + void _SetBordered(bool bEnabled) { + if (_fullscreen) + _bordered = bEnabled; + else + SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK); } - void _SetResizable(BMessage *msg) { - bool bEnabled; - if(msg->FindBool("window-resizable", &bEnabled) != B_OK) { + void _SetResizable(bool bEnabled) { + if (_fullscreen) + _resizable = bEnabled; + else { + if (bEnabled) { + SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); + } else { + SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); + } + } + } + + void _SetMinimumSize(BMessage *msg) { + float maxHeight; + float maxWidth; + float _; + int32 minHeight; + int32 minWidth; + + // This is a bit convoluted, we only want to set the minimum not the maximum + // But there is no direct call to do that, so store the maximum size beforehand + GetSizeLimits(&_, &maxWidth, &_, &maxHeight); + if (msg->FindInt32("window-w", &minWidth) != B_OK) return; - } - if (bEnabled) { - SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); - } else { - SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); - } + if (msg->FindInt32("window-h", &minHeight) != B_OK) + return; + SetSizeLimits((float)minWidth, maxWidth, (float)minHeight, maxHeight); + UpdateSizeLimits(); } void _Restore() { @@ -603,23 +644,42 @@ private: Minimize(false); } else if(IsHidden()) { Show(); + } else if (_fullscreen) { + } else if(_prev_frame != NULL) { /* Zoomed */ MoveTo(_prev_frame->left, _prev_frame->top); ResizeTo(_prev_frame->Width(), _prev_frame->Height()); } } - void _SetFullScreen(BMessage *msg) { - bool fullscreen; - if( - msg->FindBool("fullscreen", &fullscreen) != B_OK - ) { - return; + void _SetFullScreen(bool fullscreen) { + if (fullscreen != _fullscreen) { + if (fullscreen) { + BScreen screen(this); + BRect screenFrame = screen.Frame(); + printf("screen frame: "); screenFrame.PrintToStream(); printf("\n"); + _bordered = Look() != B_NO_BORDER_WINDOW_LOOK; + _resizable = !(Flags() & B_NOT_RESIZABLE); + _non_fullscreen_frame = Frame(); + _SetBordered(false); + _SetResizable(false); + MoveTo(screenFrame.left, screenFrame.top); + ResizeTo(screenFrame.Width(), screenFrame.Height()); + _fullscreen = fullscreen; + } else { + _fullscreen = fullscreen; + MoveTo(_non_fullscreen_frame.left, _non_fullscreen_frame.top); + ResizeTo(_non_fullscreen_frame.Width(), _non_fullscreen_frame.Height()); + _SetBordered(_bordered); + _SetResizable(_resizable); + } } - SetFullScreen(fullscreen); } /* Members */ + + BView* _cur_view; + SDL_BView* _SDL_View; #if SDL_VIDEO_OPENGL BGLView * _SDL_GLView; Uint32 _gl_type; @@ -632,23 +692,15 @@ private: bool _inhibit_resize; BRect *_prev_frame; /* Previous position and size of the window */ + bool _fullscreen; + // valid only if fullscreen + BRect _non_fullscreen_frame; + bool _bordered; + bool _resizable; /* Framebuffer members */ - bool _connected, - _connection_disabled, - _buffer_created, - _buffer_dirty, - _trash_window_buffer; - uint8 *_bits; - uint32 _row_bytes; - clipping_rect _bounds; - BLocker *_buffer_locker; - clipping_rect *_clips; - uint32 _num_clips; - int32 _bytes_per_px; - thread_id _draw_thread_id; - - BBitmap *_bitmap; + BLocker *_buffer_locker; + BBitmap *_bitmap; }; diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bclipboard.cc b/Engine/lib/sdl/src/video/haiku/SDL_bclipboard.cc index 50dc9d6c6..37cec38d3 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bclipboard.cc +++ b/Engine/lib/sdl/src/video/haiku/SDL_bclipboard.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bclipboard.h b/Engine/lib/sdl/src/video/haiku/SDL_bclipboard.h index a52758e1e..128e545f9 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bclipboard.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_bclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bevents.cc b/Engine/lib/sdl/src/video/haiku/SDL_bevents.cc index 95df72c4a..460b4ff26 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bevents.cc +++ b/Engine/lib/sdl/src/video/haiku/SDL_bevents.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bevents.h b/Engine/lib/sdl/src/video/haiku/SDL_bevents.h index fa9e79ad6..22e491adb 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bevents.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_bevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bframebuffer.cc b/Engine/lib/sdl/src/video/haiku/SDL_bframebuffer.cc index b5c6acc90..971231924 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bframebuffer.cc +++ b/Engine/lib/sdl/src/video/haiku/SDL_bframebuffer.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,10 +35,6 @@ extern "C" { #endif -#ifndef DRAWTHREAD -static int32 HAIKU_UpdateOnce(SDL_Window *window); -#endif - static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) { return ((SDL_BWin*)(window->driverdata)); } @@ -56,11 +52,11 @@ int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window, return -1; } - while(!bwin->Connected()) { snooze(100); } - /* Make sure we have exclusive access to frame buffer data */ bwin->LockBuffer(); + bwin->CreateView(); + /* format */ display_mode bmode; bscreen.GetMode(&bmode); @@ -76,7 +72,7 @@ int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window, bitmap = new BBitmap(bwin->Bounds(), (color_space)bmode.space, false, /* Views not accepted */ true); /* Contiguous memory required */ - + if(bitmap->InitCheck() != B_OK) { delete bitmap; return SDL_SetError("Could not initialize back buffer!"); @@ -84,15 +80,13 @@ int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window, bwin->SetBitmap(bitmap); - + /* Set the pixel pointer */ *pixels = bitmap->Bits(); /* pitch = width of window, in bytes */ *pitch = bitmap->BytesPerRow(); - bwin->SetBufferExists(true); - bwin->SetTrashBuffer(false); bwin->UnlockBuffer(); return 0; } @@ -106,150 +100,26 @@ int HAIKU_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_BWin *bwin = _ToBeWin(window); -#ifdef DRAWTHREAD - bwin->LockBuffer(); - bwin->SetBufferDirty(true); - bwin->UnlockBuffer(); -#else - bwin->SetBufferDirty(true); - HAIKU_UpdateOnce(window); -#endif + bwin->PostMessage(BWIN_UPDATE_FRAMEBUFFER); return 0; } -int32 HAIKU_DrawThread(void *data) { - SDL_BWin *bwin = (SDL_BWin*)data; - - BScreen bscreen; - if(!bscreen.IsValid()) { - return -1; - } - - while(bwin->ConnectionEnabled()) { - if( bwin->Connected() && bwin->BufferExists() && bwin->BufferIsDirty() ) { - bwin->LockBuffer(); - BBitmap *bitmap = NULL; - bitmap = bwin->GetBitmap(); - int32 windowPitch = bitmap->BytesPerRow(); - int32 bufferPitch = bwin->GetRowBytes(); - uint8 *windowpx; - uint8 *bufferpx; - - int32 BPP = bwin->GetBytesPerPx(); - int32 windowSub = bwin->GetFbX() * BPP + - bwin->GetFbY() * windowPitch; - clipping_rect *clips = bwin->GetClips(); - int32 numClips = bwin->GetNumClips(); - int i, y; - - /* Blit each clipping rectangle */ - bscreen.WaitForRetrace(); - for(i = 0; i < numClips; ++i) { - /* Get addresses of the start of each clipping rectangle */ - int32 width = clips[i].right - clips[i].left + 1; - int32 height = clips[i].bottom - clips[i].top + 1; - bufferpx = bwin->GetBufferPx() + - clips[i].top * bufferPitch + clips[i].left * BPP; - windowpx = (uint8*)bitmap->Bits() + - clips[i].top * windowPitch + clips[i].left * BPP - - windowSub; - - /* Copy each row of pixels from the window buffer into the frame - buffer */ - for(y = 0; y < height; ++y) - { - - if(bwin->CanTrashWindowBuffer()) { - goto escape; /* Break out before the buffer is killed */ - } - - memcpy(bufferpx, windowpx, width * BPP); - bufferpx += bufferPitch; - windowpx += windowPitch; - } - } - - bwin->SetBufferDirty(false); -escape: - bwin->UnlockBuffer(); - } else { - snooze(16000); - } - } - - return B_OK; -} - void HAIKU_DestroyWindowFramebuffer(_THIS, SDL_Window * window) { SDL_BWin *bwin = _ToBeWin(window); - + bwin->LockBuffer(); - + /* Free and clear the window buffer */ BBitmap *bitmap = bwin->GetBitmap(); delete bitmap; bwin->SetBitmap(NULL); - bwin->SetBufferExists(false); + + bwin->RemoveView(); + bwin->UnlockBuffer(); } - -/* - * TODO: - * This was written to test if certain errors were caused by threading issues. - * The specific issues have since become rare enough that they may have been - * solved, but I doubt it- they were pretty sporadic before now. - */ -#ifndef DRAWTHREAD -static int32 HAIKU_UpdateOnce(SDL_Window *window) { - SDL_BWin *bwin = _ToBeWin(window); - BScreen bscreen; - if(!bscreen.IsValid()) { - return -1; - } - - if(bwin->ConnectionEnabled() && bwin->Connected()) { - bwin->LockBuffer(); - int32 windowPitch = window->surface->pitch; - int32 bufferPitch = bwin->GetRowBytes(); - uint8 *windowpx; - uint8 *bufferpx; - - int32 BPP = bwin->GetBytesPerPx(); - uint8 *windowBaseAddress = (uint8*)window->surface->pixels; - int32 windowSub = bwin->GetFbX() * BPP + - bwin->GetFbY() * windowPitch; - clipping_rect *clips = bwin->GetClips(); - int32 numClips = bwin->GetNumClips(); - int i, y; - - /* Blit each clipping rectangle */ - bscreen.WaitForRetrace(); - for(i = 0; i < numClips; ++i) { - /* Get addresses of the start of each clipping rectangle */ - int32 width = clips[i].right - clips[i].left + 1; - int32 height = clips[i].bottom - clips[i].top + 1; - bufferpx = bwin->GetBufferPx() + - clips[i].top * bufferPitch + clips[i].left * BPP; - windowpx = windowBaseAddress + - clips[i].top * windowPitch + clips[i].left * BPP - windowSub; - - /* Copy each row of pixels from the window buffer into the frame - buffer */ - for(y = 0; y < height; ++y) - { - memcpy(bufferpx, windowpx, width * BPP); - bufferpx += bufferPitch; - windowpx += windowPitch; - } - } - bwin->UnlockBuffer(); - } - return 0; -} -#endif - #ifdef __cplusplus } #endif diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bframebuffer.h b/Engine/lib/sdl/src/video/haiku/SDL_bframebuffer.h index 62665ae0f..4361a39df 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bframebuffer.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_bframebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bkeyboard.cc b/Engine/lib/sdl/src/video/haiku/SDL_bkeyboard.cc index 064249fea..a4aea4d48 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bkeyboard.cc +++ b/Engine/lib/sdl/src/video/haiku/SDL_bkeyboard.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bkeyboard.h b/Engine/lib/sdl/src/video/haiku/SDL_bkeyboard.h index a0ddeed67..4c2a5903a 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bkeyboard.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_bkeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bmessagebox.cc b/Engine/lib/sdl/src/video/haiku/SDL_bmessagebox.cc index 781002f41..d777ed834 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bmessagebox.cc +++ b/Engine/lib/sdl/src/video/haiku/SDL_bmessagebox.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga Copyright (C) 2018-2019 EXL This software is provided 'as-is', without any express or implied diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bmessagebox.h b/Engine/lib/sdl/src/video/haiku/SDL_bmessagebox.h index 927400e0b..ca4406ebb 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bmessagebox.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_bmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga Copyright (C) 2018-2019 EXL This software is provided 'as-is', without any express or implied diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bmodes.cc b/Engine/lib/sdl/src/video/haiku/SDL_bmodes.cc index bf41b1b50..0cbc56b0f 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bmodes.cc +++ b/Engine/lib/sdl/src/video/haiku/SDL_bmodes.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -281,7 +281,7 @@ void HAIKU_GetDisplayModes(_THIS, SDL_VideoDisplay *display) { SDL_AddDisplayMode(display, &mode); } } - free(bmodes); + free(bmodes); /* This should not be SDL_free() */ } @@ -313,7 +313,7 @@ int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode return SDL_SetError("Bad video mode"); } - free(bmode_list); + free(bmode_list); /* This should not be SDL_free() */ #if SDL_VIDEO_OPENGL /* FIXME: Is there some way to reboot the OpenGL context? This doesn't diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bmodes.h b/Engine/lib/sdl/src/video/haiku/SDL_bmodes.h index e4e60d002..56fa14488 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bmodes.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_bmodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bopengl.cc b/Engine/lib/sdl/src/video/haiku/SDL_bopengl.cc index b19397924..0c7a704d8 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bopengl.cc +++ b/Engine/lib/sdl/src/video/haiku/SDL_bopengl.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -84,16 +84,21 @@ void *HAIKU_GL_GetProcAddress(_THIS, const char *proc) } - - int HAIKU_GL_SwapWindow(_THIS, SDL_Window * window) { _ToBeWin(window)->SwapBuffers(); return 0; } int HAIKU_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) { - SDL_BWin* win = (SDL_BWin*)context; - _GetBeApp()->SetCurrentContext(win ? win->GetGLView() : NULL); + BGLView* glView = (BGLView*)context; + // printf("HAIKU_GL_MakeCurrent(%llx), win = %llx, thread = %d\n", (uint64)context, (uint64)window, find_thread(NULL)); + if (glView != NULL) { + if ((glView->Window() == NULL) || (window == NULL) || (_ToBeWin(window)->GetGLView() != glView)) { + SDL_SetError("MakeCurrent failed"); + return -1; + } + } + _GetBeApp()->SetCurrentContext(glView); return 0; } @@ -102,6 +107,11 @@ SDL_GLContext HAIKU_GL_CreateContext(_THIS, SDL_Window * window) { /* FIXME: Not sure what flags should be included here; may want to have most of them */ SDL_BWin *bwin = _ToBeWin(window); + // printf("HAIKU_GL_CreateContext, win = %llx, thread = %d\n", (uint64)window, find_thread(NULL)); + if (bwin->GetGLView() != NULL) { + SDL_SetError("Context already creaded"); + return NULL; + } Uint32 gl_flags = BGL_RGB; if (_this->gl_config.alpha_size) { gl_flags |= BGL_ALPHA; @@ -123,13 +133,25 @@ SDL_GLContext HAIKU_GL_CreateContext(_THIS, SDL_Window * window) { _this->gl_config.accum_alpha_size) { gl_flags |= BGL_ACCUM; } +#if __GNUC__ > 3 + if (_this->gl_config.share_with_current_context) { + gl_flags |= BGL_SHARE_CONTEXT; + } +#endif bwin->CreateGLView(gl_flags); - return (SDL_GLContext)(bwin); + _GetBeApp()->SetCurrentContext(bwin->GetGLView()); + return (SDL_GLContext)(bwin->GetGLView()); } void HAIKU_GL_DeleteContext(_THIS, SDL_GLContext context) { - /* Currently, automatically unlocks the view */ - ((SDL_BWin*)context)->RemoveGLView(); + // printf("HAIKU_GL_DeleteContext(%llx), thread = %d\n", (uint64)context, find_thread(NULL)); + BGLView* glView = (BGLView*)context; + SDL_BWin *bwin = (SDL_BWin*)glView->Window(); + if (bwin == NULL) { + delete glView; + } else { + bwin->RemoveGLView(); + } } diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bopengl.h b/Engine/lib/sdl/src/video/haiku/SDL_bopengl.h index 947331db8..4723ae6b5 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bopengl.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_bopengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bvideo.cc b/Engine/lib/sdl/src/video/haiku/SDL_bvideo.cc index 817fccf43..1ac3201f2 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bvideo.cc +++ b/Engine/lib/sdl/src/video/haiku/SDL_bvideo.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,11 +18,14 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ + #include "../../SDL_internal.h" #include "../../main/haiku/SDL_BApp.h" #if SDL_VIDEO_DRIVER_HAIKU +#include "SDL_BWin.h" +#include #ifdef __cplusplus extern "C" { @@ -37,7 +40,9 @@ extern "C" { #include "SDL_bframebuffer.h" #include "SDL_bevents.h" -#include +static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) { + return ((SDL_BWin*)(window->driverdata)); +} /* FIXME: Undefined functions */ // #define HAIKU_PumpEvents NULL @@ -88,7 +93,8 @@ HAIKU_CreateDevice(int devindex) device->SetWindowFullscreen = HAIKU_SetWindowFullscreen; device->SetWindowGammaRamp = HAIKU_SetWindowGammaRamp; device->GetWindowGammaRamp = HAIKU_GetWindowGammaRamp; - device->SetWindowGrab = HAIKU_SetWindowGrab; + device->SetWindowMouseGrab = HAIKU_SetWindowMouseGrab; + device->SetWindowMinimumSize = HAIKU_SetWindowMinimumSize; device->DestroyWindow = HAIKU_DestroyWindow; device->GetWindowWMInfo = HAIKU_GetWindowWMInfo; device->CreateWindowFramebuffer = HAIKU_CreateWindowFramebuffer; @@ -135,31 +141,133 @@ void HAIKU_DeleteDevice(SDL_VideoDevice * device) SDL_free(device); } -static int HAIKU_ShowCursor(SDL_Cursor *cur) +static SDL_Cursor * +HAIKU_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_Cursor *cursor; + BCursorID cursorId = B_CURSOR_ID_SYSTEM_DEFAULT; + + switch(id) + { + default: + SDL_assert(0); + return NULL; + case SDL_SYSTEM_CURSOR_ARROW: cursorId = B_CURSOR_ID_SYSTEM_DEFAULT; break; + case SDL_SYSTEM_CURSOR_IBEAM: cursorId = B_CURSOR_ID_I_BEAM; break; + case SDL_SYSTEM_CURSOR_WAIT: cursorId = B_CURSOR_ID_PROGRESS; break; + case SDL_SYSTEM_CURSOR_CROSSHAIR: cursorId = B_CURSOR_ID_CROSS_HAIR; break; + case SDL_SYSTEM_CURSOR_WAITARROW: cursorId = B_CURSOR_ID_PROGRESS; break; + case SDL_SYSTEM_CURSOR_SIZENWSE: cursorId = B_CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST; break; + case SDL_SYSTEM_CURSOR_SIZENESW: cursorId = B_CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST; break; + case SDL_SYSTEM_CURSOR_SIZEWE: cursorId = B_CURSOR_ID_RESIZE_EAST_WEST; break; + case SDL_SYSTEM_CURSOR_SIZENS: cursorId = B_CURSOR_ID_RESIZE_NORTH_SOUTH; break; + case SDL_SYSTEM_CURSOR_SIZEALL: cursorId = B_CURSOR_ID_MOVE; break; + case SDL_SYSTEM_CURSOR_NO: cursorId = B_CURSOR_ID_NOT_ALLOWED; break; + case SDL_SYSTEM_CURSOR_HAND: cursorId = B_CURSOR_ID_FOLLOW_LINK; break; + } + + cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + cursor->driverdata = (void *)new BCursor(cursorId); + } else { + SDL_OutOfMemory(); + } + + return cursor; +} + +static SDL_Cursor * +HAIKU_CreateDefaultCursor() +{ + return HAIKU_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); +} + +static void +HAIKU_FreeCursor(SDL_Cursor * cursor) +{ + if (cursor->driverdata) { + delete (BCursor*) cursor->driverdata; + } + SDL_free(cursor); +} + +static SDL_Cursor * +HAIKU_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +{ + SDL_Cursor *cursor; + SDL_Surface *converted; + + converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0); + if (!converted) { + return NULL; + } + + BBitmap *cursorBitmap = new BBitmap(BRect(0, 0, surface->w - 1, surface->h - 1), B_RGBA32); + cursorBitmap->SetBits(converted->pixels, converted->h * converted->pitch, 0, B_RGBA32); + SDL_FreeSurface(converted); + + cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + cursor->driverdata = (void *)new BCursor(cursorBitmap, BPoint(hot_x, hot_y)); + } else { + return NULL; + } + + return cursor; +} + +static int HAIKU_ShowCursor(SDL_Cursor *cursor) { SDL_Mouse *mouse = SDL_GetMouse(); - int show; + if (!mouse) return 0; - show = (cur || !mouse->focus); - if (show) { - if (be_app->IsCursorHidden()) - be_app->ShowCursor(); + + if (cursor) { + BCursor *hCursor = (BCursor*)cursor->driverdata; + be_app->SetCursor(hCursor); } else { - if (!be_app->IsCursorHidden()) - be_app->HideCursor(); + BCursor *hCursor = new BCursor(B_CURSOR_ID_NO_CURSOR); + be_app->SetCursor(hCursor); + delete hCursor; } + return 0; } +static int +HAIKU_SetRelativeMouseMode(SDL_bool enabled) +{ + SDL_Window *window = SDL_GetMouseFocus(); + if (!window) { + return 0; + } + + SDL_BWin *bewin = _ToBeWin(window); + BGLView *_SDL_GLView = bewin->GetGLView(); + + bewin->Lock(); + if (enabled) + _SDL_GLView->SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); + else + _SDL_GLView->SetEventMask(0, 0); + bewin->Unlock(); + + return 0; +} + static void HAIKU_MouseInit(_THIS) { SDL_Mouse *mouse = SDL_GetMouse(); if (!mouse) return; + mouse->CreateCursor = HAIKU_CreateCursor; + mouse->CreateSystemCursor = HAIKU_CreateSystemCursor; mouse->ShowCursor = HAIKU_ShowCursor; - mouse->cur_cursor = (SDL_Cursor*)0x1; - mouse->def_cursor = (SDL_Cursor*)0x2; + mouse->FreeCursor = HAIKU_FreeCursor; + mouse->SetRelativeMouseMode = HAIKU_SetRelativeMouseMode; + + SDL_SetDefaultCursor(HAIKU_CreateDefaultCursor()); } int HAIKU_VideoInit(_THIS) diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bvideo.h b/Engine/lib/sdl/src/video/haiku/SDL_bvideo.h index aa56ab22d..d0d7bfea5 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bvideo.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_bvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bwindow.cc b/Engine/lib/sdl/src/video/haiku/SDL_bwindow.cc index addf20604..587affad2 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bwindow.cc +++ b/Engine/lib/sdl/src/video/haiku/SDL_bwindow.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -205,7 +205,14 @@ int HAIKU_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) { } -void HAIKU_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { +void HAIKU_SetWindowMinimumSize(_THIS, SDL_Window * window){ + BMessage msg(BWIN_MINIMUM_SIZE_WINDOW); + msg.AddInt32("window-w", window->w -1); + msg.AddInt32("window-h", window->h -1); + _ToBeWin(window)->PostMessage(&msg); +} + +void HAIKU_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { /* TODO: Implement this! */ } diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bwindow.h b/Engine/lib/sdl/src/video/haiku/SDL_bwindow.h index b6b8a8ea8..58a85d872 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bwindow.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_bwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,6 +32,7 @@ extern void HAIKU_SetWindowTitle(_THIS, SDL_Window * window); extern void HAIKU_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); extern void HAIKU_SetWindowPosition(_THIS, SDL_Window * window); extern void HAIKU_SetWindowSize(_THIS, SDL_Window * window); +extern void HAIKU_SetWindowMinimumSize(_THIS, SDL_Window * window); extern void HAIKU_ShowWindow(_THIS, SDL_Window * window); extern void HAIKU_HideWindow(_THIS, SDL_Window * window); extern void HAIKU_RaiseWindow(_THIS, SDL_Window * window); @@ -43,7 +44,7 @@ extern void HAIKU_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resiza extern void HAIKU_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int HAIKU_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int HAIKU_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); -extern void HAIKU_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void HAIKU_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void HAIKU_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool HAIKU_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); diff --git a/Engine/lib/sdl/src/video/khronos/EGL/egl.h b/Engine/lib/sdl/src/video/khronos/EGL/egl.h index 93a21873c..801f540f8 100644 --- a/Engine/lib/sdl/src/video/khronos/EGL/egl.h +++ b/Engine/lib/sdl/src/video/khronos/EGL/egl.h @@ -6,39 +6,24 @@ extern "C" { #endif /* -** Copyright (c) 2013-2017 The Khronos Group Inc. +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 ** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts +** This header is generated from the Khronos EGL XML API Registry. +** The current version of the Registry, generator scripts ** used to make the header, and the header can be found at ** http://www.khronos.org/registry/egl ** -** Khronos $Git commit SHA1: a732b061e7 $ on $Git commit date: 2017-06-17 23:27:53 +0100 $ +** Khronos $Git commit SHA1: 9581d004ff $ on $Git commit date: 2021-04-06 15:53:59 +0200 $ */ #include -/* Generated on date 20170627 */ +#ifndef EGL_EGL_PROTOTYPES +#define EGL_EGL_PROTOTYPES 1 +#endif + +/* Generated on date 20210802 */ /* Generated C header for: * API: egl @@ -118,6 +103,31 @@ typedef void (*__eglMustCastToProperFunctionPointerType)(void); #define EGL_VERSION 0x3054 #define EGL_WIDTH 0x3057 #define EGL_WINDOW_BIT 0x0004 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); +typedef EGLContext (EGLAPIENTRYP PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETCURRENTDISPLAYPROC) (void); +typedef EGLSurface (EGLAPIENTRYP PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id); +typedef EGLint (EGLAPIENTRYP PFNEGLGETERRORPROC) (void); +typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP PFNEGLGETPROCADDRESSPROC) (const char *procname); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint *major, EGLint *minor); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLTERMINATEPROC) (EGLDisplay dpy); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITGLPROC) (void); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITNATIVEPROC) (EGLint engine); +#if EGL_EGL_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); @@ -142,6 +152,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy); EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void); EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine); +#endif #endif /* EGL_VERSION_1_0 */ #ifndef EGL_VERSION_1_1 @@ -160,10 +171,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine); #define EGL_TEXTURE_RGB 0x305D #define EGL_TEXTURE_RGBA 0x305E #define EGL_TEXTURE_TARGET 0x3081 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval); +#if EGL_EGL_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval); +#endif #endif /* EGL_VERSION_1_1 */ #ifndef EGL_VERSION_1_2 @@ -199,11 +216,18 @@ typedef void *EGLClientBuffer; #define EGL_SWAP_BEHAVIOR 0x3093 #define EGL_UNKNOWN EGL_CAST(EGLint,-1) #define EGL_VERTICAL_RESOLUTION 0x3091 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDAPIPROC) (EGLenum api); +typedef EGLenum (EGLAPIENTRYP PFNEGLQUERYAPIPROC) (void); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETHREADPROC) (void); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITCLIENTPROC) (void); +#if EGL_EGL_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api); EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void); EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void); EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); +#endif #endif /* EGL_VERSION_1_2 */ #ifndef EGL_VERSION_1_3 @@ -232,7 +256,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); #define EGL_OPENGL_API 0x30A2 #define EGL_OPENGL_BIT 0x0008 #define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 +typedef EGLContext (EGLAPIENTRYP PFNEGLGETCURRENTCONTEXTPROC) (void); +#if EGL_EGL_PROTOTYPES EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void); +#endif #endif /* EGL_VERSION_1_4 */ #ifndef EGL_VERSION_1_5 @@ -284,6 +311,17 @@ typedef void *EGLImage; #define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 #define EGL_IMAGE_PRESERVED 0x30D2 #define EGL_NO_IMAGE EGL_CAST(EGLImage,0) +typedef EGLSync (EGLAPIENTRYP PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value); +typedef EGLImage (EGLAPIENTRYP PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags); +#if EGL_EGL_PROTOTYPES EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync); EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); @@ -294,6 +332,7 @@ EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *nat EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags); +#endif #endif /* EGL_VERSION_1_5 */ #ifdef __cplusplus diff --git a/Engine/lib/sdl/src/video/khronos/EGL/eglext.h b/Engine/lib/sdl/src/video/khronos/EGL/eglext.h index d2def032d..94dd038c9 100644 --- a/Engine/lib/sdl/src/video/khronos/EGL/eglext.h +++ b/Engine/lib/sdl/src/video/khronos/EGL/eglext.h @@ -6,39 +6,20 @@ extern "C" { #endif /* -** Copyright (c) 2013-2017 The Khronos Group Inc. +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 ** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts +** This header is generated from the Khronos EGL XML API Registry. +** The current version of the Registry, generator scripts ** used to make the header, and the header can be found at ** http://www.khronos.org/registry/egl ** -** Khronos $Git commit SHA1: a732b061e7 $ on $Git commit date: 2017-06-17 23:27:53 +0100 $ +** Khronos $Git commit SHA1: dc0b58dca5 $ on $Git commit date: 2021-06-25 01:58:50 +0200 $ */ #include -#define EGL_EGLEXT_VERSION 20170627 +#define EGL_EGLEXT_VERSION 20210629 /* Generated C header for: * API: egl @@ -443,9 +424,9 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, #ifndef EGL_KHR_swap_buffers_with_damage #define EGL_KHR_swap_buffers_with_damage 1 -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #endif #endif /* EGL_KHR_swap_buffers_with_damage */ @@ -462,6 +443,10 @@ EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLin #endif #endif /* EGL_KHR_wait_sync */ +#ifndef EGL_ANDROID_GLES_layers +#define EGL_ANDROID_GLES_layers 1 +#endif /* EGL_ANDROID_GLES_layers */ + #ifndef EGL_ANDROID_blob_cache #define EGL_ANDROID_blob_cache 1 typedef khronos_ssize_t EGLsizeiANDROID; @@ -495,6 +480,47 @@ EGLAPI EGLClientBuffer EGLAPIENTRY eglCreateNativeClientBufferANDROID (const EGL #define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C #endif /* EGL_ANDROID_front_buffer_auto_refresh */ +#ifndef EGL_ANDROID_get_frame_timestamps +#define EGL_ANDROID_get_frame_timestamps 1 +typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; +#define EGL_TIMESTAMP_PENDING_ANDROID EGL_CAST(EGLnsecsANDROID,-2) +#define EGL_TIMESTAMP_INVALID_ANDROID EGL_CAST(EGLnsecsANDROID,-1) +#define EGL_TIMESTAMPS_ANDROID 0x3430 +#define EGL_COMPOSITE_DEADLINE_ANDROID 0x3431 +#define EGL_COMPOSITE_INTERVAL_ANDROID 0x3432 +#define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3433 +#define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3434 +#define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3435 +#define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3436 +#define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3437 +#define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3438 +#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3439 +#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x343A +#define EGL_DEQUEUE_READY_TIME_ANDROID 0x343B +#define EGL_READS_DONE_TIME_ANDROID 0x343C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETNEXTFRAMEIDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingANDROID (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values); +EGLAPI EGLBoolean EGLAPIENTRY eglGetNextFrameIdANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId); +EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); +EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampsANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); +#endif +#endif /* EGL_ANDROID_get_frame_timestamps */ + +#ifndef EGL_ANDROID_get_native_client_buffer +#define EGL_ANDROID_get_native_client_buffer 1 +struct AHardwareBuffer; +typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC) (const struct AHardwareBuffer *buffer); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLClientBuffer EGLAPIENTRY eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer); +#endif +#endif /* EGL_ANDROID_get_native_client_buffer */ + #ifndef EGL_ANDROID_image_native_buffer #define EGL_ANDROID_image_native_buffer 1 #define EGL_NATIVE_BUFFER_ANDROID 0x3140 @@ -514,7 +540,6 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR #ifndef EGL_ANDROID_presentation_time #define EGL_ANDROID_presentation_time 1 -typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; typedef EGLBoolean (EGLAPIENTRYP PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); #ifdef EGL_EGLEXT_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); @@ -549,11 +574,25 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 #endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ +#ifndef EGL_ANGLE_sync_control_rate +#define EGL_ANGLE_sync_control_rate 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMSCRATEANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetMscRateANGLE (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator); +#endif +#endif /* EGL_ANGLE_sync_control_rate */ + #ifndef EGL_ANGLE_window_fixed_size #define EGL_ANGLE_window_fixed_size 1 #define EGL_FIXED_SIZE_ANGLE 0x3201 #endif /* EGL_ANGLE_window_fixed_size */ +#ifndef EGL_ARM_image_format +#define EGL_ARM_image_format 1 +#define EGL_COLOR_COMPONENT_TYPE_UNSIGNED_INTEGER_ARM 0x3287 +#define EGL_COLOR_COMPONENT_TYPE_INTEGER_ARM 0x3288 +#endif /* EGL_ARM_image_format */ + #ifndef EGL_ARM_implicit_external_sync #define EGL_ARM_implicit_external_sync 1 #define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A @@ -578,6 +617,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #define EGL_EXT_client_extensions 1 #endif /* EGL_EXT_client_extensions */ +#ifndef EGL_EXT_client_sync +#define EGL_EXT_client_sync 1 +#define EGL_SYNC_CLIENT_EXT 0x3364 +#define EGL_SYNC_CLIENT_SIGNAL_EXT 0x3365 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCLIENTSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglClientSignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_client_sync */ + #ifndef EGL_EXT_compositor #define EGL_EXT_compositor 1 #define EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT 0x3460 @@ -602,6 +651,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSwapPolicyEXT (EGLint external_win_id #endif #endif /* EGL_EXT_compositor */ +#ifndef EGL_EXT_config_select_group +#define EGL_EXT_config_select_group 1 +#define EGL_CONFIG_SELECT_GROUP_EXT 0x34C0 +#endif /* EGL_EXT_config_select_group */ + #ifndef EGL_EXT_create_context_robustness #define EGL_EXT_create_context_robustness 1 #define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF @@ -631,8 +685,14 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #ifndef EGL_EXT_device_drm #define EGL_EXT_device_drm 1 #define EGL_DRM_DEVICE_FILE_EXT 0x3233 +#define EGL_DRM_MASTER_FD_EXT 0x333C #endif /* EGL_EXT_device_drm */ +#ifndef EGL_EXT_device_drm_render_node +#define EGL_EXT_device_drm_render_node 1 +#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377 +#endif /* EGL_EXT_device_drm_render_node */ + #ifndef EGL_EXT_device_enumeration #define EGL_EXT_device_enumeration 1 #endif /* EGL_EXT_device_enumeration */ @@ -642,10 +702,26 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #define EGL_OPENWF_DEVICE_ID_EXT 0x3237 #endif /* EGL_EXT_device_openwf */ +#ifndef EGL_EXT_device_persistent_id +#define EGL_EXT_device_persistent_id 1 +#define EGL_DEVICE_UUID_EXT 0x335C +#define EGL_DRIVER_UUID_EXT 0x335D +#define EGL_DRIVER_NAME_EXT 0x335E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEBINARYEXTPROC) (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceBinaryEXT (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size); +#endif +#endif /* EGL_EXT_device_persistent_id */ + #ifndef EGL_EXT_device_query #define EGL_EXT_device_query 1 #endif /* EGL_EXT_device_query */ +#ifndef EGL_EXT_device_query_name +#define EGL_EXT_device_query_name 1 +#define EGL_RENDERER_EXT 0x335F +#endif /* EGL_EXT_device_query_name */ + #ifndef EGL_EXT_gl_colorspace_bt2020_linear #define EGL_EXT_gl_colorspace_bt2020_linear 1 #define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F @@ -666,6 +742,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362 #endif /* EGL_EXT_gl_colorspace_display_p3_linear */ +#ifndef EGL_EXT_gl_colorspace_display_p3_passthrough +#define EGL_EXT_gl_colorspace_display_p3_passthrough 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT 0x3490 +#endif /* EGL_EXT_gl_colorspace_display_p3_passthrough */ + #ifndef EGL_EXT_gl_colorspace_scrgb #define EGL_EXT_gl_colorspace_scrgb 1 #define EGL_GL_COLORSPACE_SCRGB_EXT 0x3351 @@ -723,6 +804,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufModifiersEXT (EGLDisplay dpy, EGLint #endif #endif /* EGL_EXT_image_dma_buf_import_modifiers */ +#ifndef EGL_EXT_image_gl_colorspace +#define EGL_EXT_image_gl_colorspace 1 +#define EGL_GL_COLORSPACE_DEFAULT_EXT 0x314D +#endif /* EGL_EXT_image_gl_colorspace */ + #ifndef EGL_EXT_image_implicit_sync_control #define EGL_EXT_image_implicit_sync_control 1 #define EGL_IMPORT_SYNC_TYPE_EXT 0x3470 @@ -812,6 +898,17 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, #define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6 #endif /* EGL_EXT_platform_x11 */ +#ifndef EGL_EXT_platform_xcb +#define EGL_EXT_platform_xcb 1 +#define EGL_PLATFORM_XCB_EXT 0x31DC +#define EGL_PLATFORM_XCB_SCREEN_EXT 0x31DE +#endif /* EGL_EXT_platform_xcb */ + +#ifndef EGL_EXT_present_opaque +#define EGL_EXT_present_opaque 1 +#define EGL_PRESENT_OPAQUE_EXT 0x31DF +#endif /* EGL_EXT_present_opaque */ + #ifndef EGL_EXT_protected_content #define EGL_EXT_protected_content 1 #define EGL_PROTECTED_CONTENT_EXT 0x32C0 @@ -852,12 +949,20 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStr #ifndef EGL_EXT_swap_buffers_with_damage #define EGL_EXT_swap_buffers_with_damage 1 -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #endif #endif /* EGL_EXT_swap_buffers_with_damage */ +#ifndef EGL_EXT_sync_reuse +#define EGL_EXT_sync_reuse 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglUnsignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_sync_reuse */ + #ifndef EGL_EXT_yuv_surface #define EGL_EXT_yuv_surface 1 #define EGL_YUV_ORDER_EXT 0x3301 @@ -933,6 +1038,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfi #define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 #define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 #define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 +#define EGL_DRM_BUFFER_USE_CURSOR_MESA 0x00000004 typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); #ifdef EGL_EGLEXT_PROTOTYPES @@ -961,6 +1067,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImage #define EGL_PLATFORM_SURFACELESS_MESA 0x31DD #endif /* EGL_MESA_platform_surfaceless */ +#ifndef EGL_MESA_query_driver +#define EGL_MESA_query_driver 1 +typedef char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERCONFIGPROC) (EGLDisplay dpy); +typedef const char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERNAMEPROC) (EGLDisplay dpy); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI char *EGLAPIENTRY eglGetDisplayDriverConfig (EGLDisplay dpy); +EGLAPI const char *EGLAPIENTRY eglGetDisplayDriverName (EGLDisplay dpy); +#endif +#endif /* EGL_MESA_query_driver */ + #ifndef EGL_NOK_swap_region #define EGL_NOK_swap_region 1 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); @@ -987,6 +1103,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurfa #define EGL_AUTO_STEREO_NV 0x3136 #endif /* EGL_NV_3dvision_surface */ +#ifndef EGL_NV_context_priority_realtime +#define EGL_NV_context_priority_realtime 1 +#define EGL_CONTEXT_PRIORITY_REALTIME_NV 0x3357 +#endif /* EGL_NV_context_priority_realtime */ + #ifndef EGL_NV_coverage_sample #define EGL_NV_coverage_sample 1 #define EGL_COVERAGE_BUFFERS_NV 0x30E0 @@ -1044,19 +1165,42 @@ EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface sur #endif #endif /* EGL_NV_post_sub_buffer */ +#ifndef EGL_NV_quadruple_buffer +#define EGL_NV_quadruple_buffer 1 +#define EGL_QUADRUPLE_BUFFER_NV 0x3231 +#endif /* EGL_NV_quadruple_buffer */ + #ifndef EGL_NV_robustness_video_memory_purge #define EGL_NV_robustness_video_memory_purge 1 #define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C #endif /* EGL_NV_robustness_video_memory_purge */ +#ifndef EGL_NV_stream_consumer_eglimage +#define EGL_NV_stream_consumer_eglimage 1 +#define EGL_STREAM_CONSUMER_IMAGE_NV 0x3373 +#define EGL_STREAM_IMAGE_ADD_NV 0x3374 +#define EGL_STREAM_IMAGE_REMOVE_NV 0x3375 +#define EGL_STREAM_IMAGE_AVAILABLE_NV 0x3376 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMIMAGECONSUMERCONNECTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, EGLuint64KHR *modifiers, EGLAttrib *attrib_list); +typedef EGLint (EGLAPIENTRYP PFNEGLQUERYSTREAMCONSUMEREVENTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMACQUIREIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMRELEASEIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamImageConsumerConnectNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, EGLuint64KHR *modifiers, EGLAttrib *attrib_list); +EGLAPI EGLint EGLAPIENTRY eglQueryStreamConsumerEventNV (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamAcquireImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamReleaseImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync); +#endif +#endif /* EGL_NV_stream_consumer_eglimage */ + #ifndef EGL_NV_stream_consumer_gltexture_yuv #define EGL_NV_stream_consumer_gltexture_yuv 1 #define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C #define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D #define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); #endif #endif /* EGL_NV_stream_consumer_gltexture_yuv */ @@ -1085,6 +1229,12 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDi #define EGL_STREAM_CROSS_SYSTEM_NV 0x334F #endif /* EGL_NV_stream_cross_system */ +#ifndef EGL_NV_stream_dma +#define EGL_NV_stream_dma 1 +#define EGL_STREAM_DMA_NV 0x3371 +#define EGL_STREAM_DMA_SERVER_NV 0x3372 +#endif /* EGL_NV_stream_dma */ + #ifndef EGL_NV_stream_fifo_next #define EGL_NV_stream_fifo_next 1 #define EGL_PENDING_FRAME_NV 0x3329 @@ -1096,6 +1246,14 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDi #define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336 #endif /* EGL_NV_stream_fifo_synchronous */ +#ifndef EGL_NV_stream_flush +#define EGL_NV_stream_flush 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMFLUSHNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamFlushNV (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_NV_stream_flush */ + #ifndef EGL_NV_stream_frame_limits #define EGL_NV_stream_frame_limits 1 #define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337 @@ -1128,6 +1286,21 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStrea #endif #endif /* EGL_NV_stream_metadata */ +#ifndef EGL_NV_stream_origin +#define EGL_NV_stream_origin 1 +#define EGL_STREAM_FRAME_ORIGIN_X_NV 0x3366 +#define EGL_STREAM_FRAME_ORIGIN_Y_NV 0x3367 +#define EGL_STREAM_FRAME_MAJOR_AXIS_NV 0x3368 +#define EGL_CONSUMER_AUTO_ORIENTATION_NV 0x3369 +#define EGL_PRODUCER_AUTO_ORIENTATION_NV 0x336A +#define EGL_LEFT_NV 0x336B +#define EGL_RIGHT_NV 0x336C +#define EGL_TOP_NV 0x336D +#define EGL_BOTTOM_NV 0x336E +#define EGL_X_AXIS_NV 0x336F +#define EGL_Y_AXIS_NV 0x3370 +#endif /* EGL_NV_stream_origin */ + #ifndef EGL_NV_stream_remote #define EGL_NV_stream_remote 1 #define EGL_STREAM_STATE_INITIALIZING_NV 0x3240 @@ -1224,6 +1397,11 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); #endif /* KHRONOS_SUPPORT_INT64 */ #endif /* EGL_NV_system_time */ +#ifndef EGL_NV_triple_buffer +#define EGL_NV_triple_buffer 1 +#define EGL_TRIPLE_BUFFER_NV 0x3230 +#endif /* EGL_NV_triple_buffer */ + #ifndef EGL_TIZEN_image_native_buffer #define EGL_TIZEN_image_native_buffer 1 #define EGL_NATIVE_BUFFER_TIZEN 0x32A0 @@ -1234,6 +1412,40 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); #define EGL_NATIVE_SURFACE_TIZEN 0x32A1 #endif /* EGL_TIZEN_image_native_surface */ +#ifndef EGL_WL_bind_wayland_display +#define EGL_WL_bind_wayland_display 1 +#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC +#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC +#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC +struct wl_display; +struct wl_resource; +#define EGL_WAYLAND_BUFFER_WL 0x31D5 +#define EGL_WAYLAND_PLANE_WL 0x31D6 +#define EGL_TEXTURE_Y_U_V_WL 0x31D7 +#define EGL_TEXTURE_Y_UV_WL 0x31D8 +#define EGL_TEXTURE_Y_XUXV_WL 0x31D9 +#define EGL_TEXTURE_EXTERNAL_WL 0x31DA +#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWLPROC) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#endif +#endif /* EGL_WL_bind_wayland_display */ + +#ifndef EGL_WL_create_wayland_buffer_from_image +#define EGL_WL_create_wayland_buffer_from_image 1 +#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC +struct wl_buffer; +typedef struct wl_buffer *(EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC) (EGLDisplay dpy, EGLImageKHR image); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI struct wl_buffer *EGLAPIENTRY eglCreateWaylandBufferFromImageWL (EGLDisplay dpy, EGLImageKHR image); +#endif +#endif /* EGL_WL_create_wayland_buffer_from_image */ + #ifdef __cplusplus } #endif diff --git a/Engine/lib/sdl/src/video/khronos/EGL/eglplatform.h b/Engine/lib/sdl/src/video/khronos/EGL/eglplatform.h index c77c3338d..99362a23d 100644 --- a/Engine/lib/sdl/src/video/khronos/EGL/eglplatform.h +++ b/Engine/lib/sdl/src/video/khronos/EGL/eglplatform.h @@ -2,36 +2,17 @@ #define __eglplatform_h_ /* -** Copyright (c) 2007-2016 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +** Copyright 2007-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 */ /* Platform-specific types and definitions for egl.h - * $Revision: 30994 $ on $Date: 2015-04-30 13:36:48 -0700 (Thu, 30 Apr 2015) $ * * Adopters may modify khrplatform.h and this file to suit their platform. * You are encouraged to submit all modifications to the Khronos group so that * they can be included in future versions of this file. Please submit changes - * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) - * by filing a bug against product "EGL" component "Registry". + * by filing an issue or pull request on the public Khronos EGL Registry, at + * https://www.github.com/KhronosGroup/EGL-Registry/ */ #include @@ -67,7 +48,13 @@ * implementations. */ -#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ +#if defined(EGL_NO_PLATFORM_SPECIFIC_TYPES) + +typedef void *EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif @@ -77,22 +64,46 @@ typedef HDC EGLNativeDisplayType; typedef HBITMAP EGLNativePixmapType; typedef HWND EGLNativeWindowType; -#elif defined(__APPLE__) || defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ +#elif defined(__EMSCRIPTEN__) + +typedef int EGLNativeDisplayType; +typedef int EGLNativePixmapType; +typedef int EGLNativeWindowType; + +#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ typedef int EGLNativeDisplayType; -typedef void *EGLNativeWindowType; typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(WL_EGL_PLATFORM) + +typedef struct wl_display *EGLNativeDisplayType; +typedef struct wl_egl_pixmap *EGLNativePixmapType; +typedef struct wl_egl_window *EGLNativeWindowType; + +#elif defined(__GBM__) + +typedef struct gbm_device *EGLNativeDisplayType; +typedef struct gbm_bo *EGLNativePixmapType; +typedef void *EGLNativeWindowType; #elif defined(__ANDROID__) || defined(ANDROID) struct ANativeWindow; struct egl_native_pixmap_t; -typedef struct ANativeWindow* EGLNativeWindowType; -typedef struct egl_native_pixmap_t* EGLNativePixmapType; typedef void* EGLNativeDisplayType; +typedef struct egl_native_pixmap_t* EGLNativePixmapType; +typedef struct ANativeWindow* EGLNativeWindowType; -#elif defined(__unix__) +#elif defined(USE_OZONE) + +typedef intptr_t EGLNativeDisplayType; +typedef intptr_t EGLNativePixmapType; +typedef intptr_t EGLNativeWindowType; + +#elif defined(USE_X11) /* X11 (tentative) */ #include @@ -102,6 +113,32 @@ typedef Display *EGLNativeDisplayType; typedef Pixmap EGLNativePixmapType; typedef Window EGLNativeWindowType; +#elif defined(__unix__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__APPLE__) + +typedef int EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(__HAIKU__) + +#include + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__Fuchsia__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + #else #error "Platform not recognized" #endif diff --git a/Engine/lib/sdl/src/video/khronos/KHR/khrplatform.h b/Engine/lib/sdl/src/video/khronos/KHR/khrplatform.h index 1ad3554a7..dd22d9270 100644 --- a/Engine/lib/sdl/src/video/khronos/KHR/khrplatform.h +++ b/Engine/lib/sdl/src/video/khronos/KHR/khrplatform.h @@ -2,7 +2,7 @@ #define __khrplatform_h_ /* -** Copyright (c) 2008-2009 The Khronos Group Inc. +** Copyright (c) 2008-2018 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -26,18 +26,16 @@ /* Khronos platform-specific types and definitions. * - * $Revision: 32517 $ on $Date: 2016-03-11 02:41:19 -0800 (Fri, 11 Mar 2016) $ + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 * * Adopters may modify this file to suit their platform. Adopters are * encouraged to submit platform specific modifications to the Khronos * group so that they can be included in future versions of this file. - * Please submit changes by sending them to the public Khronos Bugzilla - * (http://khronos.org/bugzilla) by filing a bug against product - * "Khronos (general)" component "Registry". - * - * A predefined template which fills in some of the bug fields can be - * reached using http://tinyurl.com/khrplatform-h-bugreport, but you - * must create a Bugzilla login first. + * Please submit changes by filing pull requests or issues on + * the EGL Registry repository linked above. * * * See the Implementer's Guidelines for information about where this file @@ -92,12 +90,20 @@ * int arg2) KHRONOS_APIATTRIBUTES; */ +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + /*------------------------------------------------------------------------- * Definition of KHRONOS_APICALL *------------------------------------------------------------------------- * This precedes the return type of the function in the function prototype. */ -#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) # define KHRONOS_APICALL __declspec(dllimport) #elif defined (__SYMBIAN32__) # define KHRONOS_APICALL IMPORT_C diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmdyn.c b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmdyn.c index 38fc3ab12..bf3ff2e3e 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmdyn.c +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmdyn.c @@ -1,7 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - Atomic KMSDRM backend by Manuel Alfayate Corchete + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,7 +27,6 @@ #include "SDL_kmsdrmdyn.h" - #ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC #include "SDL_name.h" diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmdyn.h b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmdyn.h index a7b825b3f..65de02e1b 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmdyn.h +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmdyn.h @@ -1,7 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - Atomic KMSDRM backend by Manuel Alfayate Corchete + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmevents.c b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmevents.c index f2405d4a3..10773a760 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmevents.c +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmevents.c @@ -1,7 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - Atomic KMSDRM backend by Manuel Alfayate Corchete + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,12 +28,16 @@ #ifdef SDL_INPUT_LINUXEV #include "../../core/linux/SDL_evdev.h" +#elif defined SDL_INPUT_WSCONS +#include "../../core/openbsd/SDL_wscons.h" #endif void KMSDRM_PumpEvents(_THIS) { #ifdef SDL_INPUT_LINUXEV SDL_EVDEV_Poll(); +#elif defined SDL_INPUT_WSCONS + SDL_WSCONS_PumpEvents(); #endif } diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmevents.h b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmevents.h index 74f90da25..c327f032f 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmevents.h +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmevents.h @@ -1,7 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - Atomic KMSDRM backend by Manuel Alfayate Corchete + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmmouse.c b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmmouse.c index 26a7dad90..5722e041a 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmmouse.c +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmmouse.c @@ -1,7 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - Atomic KMSDRM backend by Manuel Alfayate Corchete + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,11 +26,12 @@ #include "SDL_kmsdrmvideo.h" #include "SDL_kmsdrmmouse.h" #include "SDL_kmsdrmdyn.h" -#include "SDL_assert.h" #include "../../events/SDL_mouse_c.h" #include "../../events/default_cursor.h" +#include "../SDL_pixels_c.h" + static SDL_Cursor *KMSDRM_CreateDefaultCursor(void); static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y); static int KMSDRM_ShowCursor(SDL_Cursor * cursor); @@ -40,57 +40,20 @@ static void KMSDRM_FreeCursor(SDL_Cursor * cursor); static void KMSDRM_WarpMouse(SDL_Window * window, int x, int y); static int KMSDRM_WarpMouseGlobal(int x, int y); -/**********************************/ -/* Atomic helper functions block. */ -/**********************************/ - -int -drm_atomic_movecursor(KMSDRM_CursorData *curdata, uint16_t x, uint16_t y) -{ - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - - if (!dispdata->cursor_plane) /* We can't move a non-existing cursor, but that's ok. */ - return 0; - - /* Do we have a set of changes already in the making? If not, allocate a new one. */ - if (!dispdata->atomic_req) - dispdata->atomic_req = KMSDRM_drmModeAtomicAlloc(); - - add_plane_property(dispdata->atomic_req, - dispdata->cursor_plane, "CRTC_X", x - curdata->hot_x); - add_plane_property(dispdata->atomic_req, - dispdata->cursor_plane, "CRTC_Y", y - curdata->hot_y); - - return 0; -} - -/***************************************/ -/* Atomic helper functions block ends. */ -/***************************************/ - -/* Converts a pixel from straight-alpha [AA, RR, GG, BB], which the SDL cursor surface has, - to premultiplied-alpha [AA. AA*RR, AA*GG, AA*BB]. - These multiplications have to be done with floats instead of uint32_t's, - and the resulting values have to be converted to be relative to the 0-255 interval, - where 255 is 1.00 and anything between 0 and 255 is 0.xx. */ -void alpha_premultiply_ARGB8888 (uint32_t *pixel) { - - uint32_t A, R, G, B; - - /* Component bytes extraction. */ - A = (*pixel >> (3 << 3)) & 0xFF; - R = (*pixel >> (2 << 3)) & 0xFF; - G = (*pixel >> (1 << 3)) & 0xFF; - B = (*pixel >> (0 << 3)) & 0xFF; - - /* Alpha pre-multiplication of each component. */ - R = (float)A * ((float)R /255); - G = (float)A * ((float)G /255); - B = (float)A * ((float)B /255); - - /* ARGB8888 pixel recomposition. */ - (*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0); -} +/**************************************************************************************/ +/* BEFORE CODING ANYTHING MOUSE/CURSOR RELATED, REMEMBER THIS. */ +/* How does SDL manage cursors internally? First, mouse =! cursor. The mouse can have */ +/* many cursors in mouse->cursors. */ +/* -SDL tells us to create a cursor with KMSDRM_CreateCursor(). It can create many */ +/* cursosr with this, not only one. */ +/* -SDL stores those cursors in a cursors array, in mouse->cursors. */ +/* -Whenever it wants (or the programmer wants) takes a cursor from that array */ +/* and shows it on screen with KMSDRM_ShowCursor(). */ +/* KMSDRM_ShowCursor() simply shows or hides the cursor it receives: it does NOT */ +/* mind if it's mouse->cur_cursor, etc. */ +/* -If KMSDRM_ShowCursor() returns succesfully, that cursor becomes mouse->cur_cursor */ +/* and mouse->cursor_shown is 1. */ +/**************************************************************************************/ static SDL_Cursor * KMSDRM_CreateDefaultCursor(void) @@ -98,208 +61,123 @@ KMSDRM_CreateDefaultCursor(void) return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY); } -/* This simply gets the cursor soft-buffer ready. We don't copy it to a GBO BO until ShowCursor() - because the cusor GBM BO (living in dispata) is destroyed and recreated when we recreate windows, etc. */ -static SDL_Cursor * -KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +/* Given a display's driverdata, destroy the cursor BO for it. + To be called from KMSDRM_DestroyWindow(), as that's where we + destroy the driverdata for the window's display. */ +void +KMSDRM_DestroyCursorBO (_THIS, SDL_VideoDisplay *display) { - KMSDRM_CursorData *curdata; - SDL_Cursor *cursor, *ret; - - curdata = NULL; - ret = NULL; - - /* All code below assumes ARGB8888 format for the cursor surface, - like other backends do. Also, the GBM BO pixels have to be - alpha-premultiplied, but the SDL surface we receive has - straight-alpha pixels, so we always have to convert. */ - SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); - SDL_assert(surface->pitch == surface->w * 4); - - cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); - if (!cursor) { - SDL_OutOfMemory(); - goto cleanup; + SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata; + + /* Destroy the curso GBM BO. */ + if (dispdata->cursor_bo) { + KMSDRM_gbm_bo_destroy(dispdata->cursor_bo); + dispdata->cursor_bo = NULL; + dispdata->cursor_bo_drm_fd = -1; } - curdata = (KMSDRM_CursorData *) SDL_calloc(1, sizeof(*curdata)); - if (!curdata) { - SDL_OutOfMemory(); - goto cleanup; +} + +/* Given a display's driverdata, create the cursor BO for it. + To be called from KMSDRM_CreateWindow(), as that's where we + build a window and assign a display to it. */ +void +KMSDRM_CreateCursorBO (SDL_VideoDisplay *display) { + + SDL_VideoDevice *dev = SDL_GetVideoDevice(); + SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata); + SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata; + + if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, + GBM_FORMAT_ARGB8888, + GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) + { + SDL_SetError("Unsupported pixel format for cursor"); + return; } - /* hox_x and hot_y are the coordinates of the "tip of the cursor" from it's base. */ - curdata->hot_x = hot_x; - curdata->hot_y = hot_y; - curdata->w = surface->w; - curdata->h = surface->h; - curdata->buffer = NULL; - - /* Configure the cursor buffer info. - This buffer has the original size of the cursor surface we are given. */ - curdata->buffer_pitch = surface->pitch; - curdata->buffer_size = surface->pitch * surface->h; - curdata->buffer = (uint32_t*)SDL_malloc(curdata->buffer_size); - - if (!curdata->buffer) { - SDL_OutOfMemory(); - goto cleanup; + if (KMSDRM_drmGetCap(viddata->drm_fd, + DRM_CAP_CURSOR_WIDTH, &dispdata->cursor_w) || + KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_HEIGHT, + &dispdata->cursor_h)) + { + SDL_SetError("Could not get the recommended GBM cursor size"); + return; } - if (SDL_MUSTLOCK(surface)) { - if (SDL_LockSurface(surface) < 0) { - /* Could not lock surface */ - goto cleanup; - } + if (dispdata->cursor_w == 0 || dispdata->cursor_h == 0) { + SDL_SetError("Could not get an usable GBM cursor size"); + return; } - /* Copy the surface pixels to the cursor buffer, for future use in ShowCursor() */ - SDL_memcpy(curdata->buffer, surface->pixels, curdata->buffer_size); + dispdata->cursor_bo = KMSDRM_gbm_bo_create(viddata->gbm_dev, + dispdata->cursor_w, dispdata->cursor_h, + GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR); - if (SDL_MUSTLOCK(surface)) { - SDL_UnlockSurface(surface); + if (!dispdata->cursor_bo) { + SDL_SetError("Could not create GBM cursor BO"); + return; } - cursor->driverdata = curdata; + dispdata->cursor_bo_drm_fd = viddata->drm_fd; +} - ret = cursor; +/* Remove a cursor buffer from a display's DRM cursor BO. */ +static int +KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display) +{ + int ret = 0; + SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata; + SDL_VideoDevice *video_device = SDL_GetVideoDevice(); + SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata); -cleanup: - if (ret == NULL) { - if (curdata) { - if (curdata->buffer) { - SDL_free(curdata->buffer); - } - SDL_free(curdata); - } - if (cursor) { - SDL_free(cursor); - } + ret = KMSDRM_drmModeSetCursor(viddata->drm_fd, + dispdata->crtc->crtc_id, 0, 0, 0); + + if (ret) { + ret = SDL_SetError("Could not hide current cursor with drmModeSetCursor()."); } return ret; } -/* When we create a window, we have to test if we have to show the cursor, - and explicily do so if necessary. - This is because when we destroy a window, we take the cursor away from the - cursor plane, and destroy the cusror GBM BO. So we have to re-show it, - so to say. */ -void -KMSDRM_InitCursor() -{ - SDL_Mouse *mouse = NULL; - mouse = SDL_GetMouse(); - - if (!mouse) { - return; - } - if (!(mouse->cur_cursor)) { - return; - } - - if (!(mouse->cursor_shown)) { - return; - } - - KMSDRM_ShowCursor(mouse->cur_cursor); -} - -/* Show the specified cursor, or hide if cursor is NULL. - cur_cursor is the current cursor, and cursor is the new cursor. - A cursor is displayed on a display, so we have to add a pointer to dispdata - to the driverdata - */ +/* Dump a cursor buffer to a display's DRM cursor BO. */ static int -KMSDRM_ShowCursor(SDL_Cursor * cursor) +KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor) { + SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata; + KMSDRM_CursorData *curdata = (KMSDRM_CursorData *) cursor->driverdata; SDL_VideoDevice *video_device = SDL_GetVideoDevice(); - //SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata); - SDL_Mouse *mouse; - KMSDRM_CursorData *curdata; - SDL_VideoDisplay *display = NULL; - SDL_DisplayData *dispdata = NULL; - KMSDRM_FBInfo *fb; - KMSDRM_PlaneInfo info = {0}; + SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata); + uint32_t bo_handle; size_t bo_stride; size_t bufsize; - uint32_t *ready_buffer = NULL; - uint32_t pixel; + uint8_t *ready_buffer = NULL; + uint8_t *src_row; - int i,j; + int i; int ret; - mouse = SDL_GetMouse(); - if (!mouse) { - return SDL_SetError("No mouse."); - } - - if (mouse->focus) { - display = SDL_GetDisplayForWindow(mouse->focus); - if (display) { - dispdata = (SDL_DisplayData*) display->driverdata; - } - } - - /**********************************/ - /* if cursor == NULL, HIDE cursor */ - /**********************************/ - if (!cursor) { - /* Hide CURRENT cursor, a cursor that is already on screen - and SDL is stored in mouse->cur_cursor. */ - if (mouse->cur_cursor && mouse->cur_cursor->driverdata) { - if (dispdata && dispdata->cursor_plane) { - info.plane = dispdata->cursor_plane; - /* The rest of the members are zeroed. */ - drm_atomic_set_plane_props(&info); - if (drm_atomic_commit(display->device, SDL_TRUE)) - return SDL_SetError("Failed atomic commit in KMSDRM_ShowCursor."); - } - return 0; - } - return SDL_SetError("Couldn't find cursor to hide."); - } - - /************************************************/ - /* If cursor != NULL, DO show cursor on display */ - /************************************************/ - if (!display) { - return SDL_SetError("Could not get display for mouse."); - } - if (!dispdata) { - return SDL_SetError("Could not get display driverdata."); - } - if (!dispdata->cursor_plane) { - return SDL_SetError("Hardware cursor plane not initialized."); - } - - curdata = (KMSDRM_CursorData *) cursor->driverdata; - if (!curdata || !dispdata->cursor_bo) { - return SDL_SetError("Cursor not initialized properly."); + return SDL_SetError("Cursor or display not initialized properly."); } - /* Prepare a buffer we can dump to our GBM BO (different size, alpha premultiplication...) */ + /* Prepare a buffer we can dump to our GBM BO (different + size, alpha premultiplication...) */ bo_stride = KMSDRM_gbm_bo_get_stride(dispdata->cursor_bo); - bufsize = bo_stride * curdata->h; + bufsize = bo_stride * dispdata->cursor_h; + + ready_buffer = (uint8_t*)SDL_calloc(1, bufsize); - ready_buffer = (uint32_t*)SDL_malloc(bufsize); if (!ready_buffer) { ret = SDL_OutOfMemory(); goto cleanup; } - /* Clean the whole buffer we are preparing. */ - SDL_memset(ready_buffer, 0x00, bo_stride * curdata->h); - - /* Copy from the cursor buffer to a buffer that we can dump to the GBM BO, - pre-multiplying by alpha each pixel as we go. */ + /* Copy from the cursor buffer to a buffer that we can dump to the GBM BO. */ for (i = 0; i < curdata->h; i++) { - for (j = 0; j < curdata->w; j++) { - pixel = ((uint32_t*)curdata->buffer)[i * curdata->w + j]; - alpha_premultiply_ARGB8888 (&pixel); - SDL_memcpy(ready_buffer + (i * dispdata->cursor_w) + j, &pixel, 4); - } + src_row = &((uint8_t*)curdata->buffer)[i * curdata->w * 4]; + SDL_memcpy(ready_buffer + (i * bo_stride), src_row, 4 * curdata->w); } /* Dump the cursor buffer to our GBM BO. */ @@ -308,28 +186,25 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor) goto cleanup; } - /* Get the fb_id for the GBM BO so we can show it on the cursor plane. */ - fb = KMSDRM_FBFromBO(video_device, dispdata->cursor_bo); + /* Put the GBM BO buffer on screen using the DRM interface. */ + bo_handle = KMSDRM_gbm_bo_get_handle(dispdata->cursor_bo).u32; + if (curdata->hot_x == 0 && curdata->hot_y == 0) { + ret = KMSDRM_drmModeSetCursor(viddata->drm_fd, dispdata->crtc->crtc_id, + bo_handle, dispdata->cursor_w, dispdata->cursor_h); + } else { + ret = KMSDRM_drmModeSetCursor2(viddata->drm_fd, dispdata->crtc->crtc_id, + bo_handle, dispdata->cursor_w, dispdata->cursor_h, curdata->hot_x, curdata->hot_y); + } - /* Show the GBM BO buffer on the cursor plane. */ - info.plane = dispdata->cursor_plane; - info.crtc_id = dispdata->crtc->crtc->crtc_id; - info.fb_id = fb->fb_id; - info.src_w = curdata->w; - info.src_h = curdata->h; - info.crtc_x = mouse->x - curdata->hot_x; - info.crtc_y = mouse->y - curdata->hot_y; - info.crtc_w = curdata->w; - info.crtc_h = curdata->h; - - drm_atomic_set_plane_props(&info); - - if (drm_atomic_commit(display->device, SDL_TRUE)) { - ret = SDL_SetError("Failed atomic commit in KMSDRM_ShowCursor."); + if (ret) { + ret = SDL_SetError("Failed to set DRM cursor."); goto cleanup; } - ret = 0; + if (ret) { + ret = SDL_SetError("Failed to reset cursor position."); + goto cleanup; + } cleanup: @@ -339,8 +214,7 @@ cleanup: return ret; } -/* We have destroyed the cursor by now, in KMSDRM_DestroyCursor. - This is only for freeing the SDL_cursor.*/ +/* This is only for freeing the SDL_cursor.*/ static void KMSDRM_FreeCursor(SDL_Cursor * cursor) { @@ -362,6 +236,133 @@ KMSDRM_FreeCursor(SDL_Cursor * cursor) } } +/* This simply gets the cursor soft-buffer ready. + We don't copy it to a GBO BO until ShowCursor() because the cusor GBM BO (living + in dispata) is destroyed and recreated when we recreate windows, etc. */ +static SDL_Cursor * +KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +{ + KMSDRM_CursorData *curdata; + SDL_Cursor *cursor, *ret; + + curdata = NULL; + ret = NULL; + + cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); + if (!cursor) { + SDL_OutOfMemory(); + goto cleanup; + } + curdata = (KMSDRM_CursorData *) SDL_calloc(1, sizeof(*curdata)); + if (!curdata) { + SDL_OutOfMemory(); + goto cleanup; + } + + /* hox_x and hot_y are the coordinates of the "tip of the cursor" from it's base. */ + curdata->hot_x = hot_x; + curdata->hot_y = hot_y; + curdata->w = surface->w; + curdata->h = surface->h; + curdata->buffer = NULL; + + /* Configure the cursor buffer info. + This buffer has the original size of the cursor surface we are given. */ + curdata->buffer_pitch = surface->w; + curdata->buffer_size = surface->w * surface->h * 4; + curdata->buffer = (uint32_t*)SDL_malloc(curdata->buffer_size); + + if (!curdata->buffer) { + SDL_OutOfMemory(); + goto cleanup; + } + + /* All code below assumes ARGB8888 format for the cursor surface, + like other backends do. Also, the GBM BO pixels have to be + alpha-premultiplied, but the SDL surface we receive has + straight-alpha pixels, so we always have to convert. */ + SDL_PremultiplyAlpha(surface->w, surface->h, + surface->format->format, surface->pixels, surface->pitch, + SDL_PIXELFORMAT_ARGB8888, curdata->buffer, surface->w * 4); + + cursor->driverdata = curdata; + + ret = cursor; + +cleanup: + if (ret == NULL) { + if (curdata) { + if (curdata->buffer) { + SDL_free(curdata->buffer); + } + SDL_free(curdata); + } + if (cursor) { + SDL_free(cursor); + } + } + + return ret; +} + +/* Show the specified cursor, or hide if cursor is NULL or has no focus. */ +static int +KMSDRM_ShowCursor(SDL_Cursor * cursor) +{ + SDL_VideoDisplay *display; + SDL_Window *window; + SDL_Mouse *mouse; + + int num_displays, i; + int ret = 0; + + /* Get the mouse focused window, if any. */ + + mouse = SDL_GetMouse(); + if (!mouse) { + return SDL_SetError("No mouse."); + } + + window = mouse->focus; + + if (!window || !cursor) { + + /* If no window is focused by mouse or cursor is NULL, + since we have no window (no mouse->focus) and hence + we have no display, we simply hide mouse on all displays. + This happens on video quit, where we get here after + the mouse focus has been unset, yet SDL wants to + restore the system default cursor (makes no sense here). */ + + num_displays = SDL_GetNumVideoDisplays(); + + /* Iterate on the displays hidding the cursor. */ + for (i = 0; i < num_displays; i++) { + display = SDL_GetDisplay(i); + ret = KMSDRM_RemoveCursorFromBO(display); + } + + } else { + + display = SDL_GetDisplayForWindow(window); + + if (display) { + + if (cursor) { + /* Dump the cursor to the display DRM cursor BO so it becomes visible + on that display. */ + ret = KMSDRM_DumpCursorToBO(display, cursor); + + } else { + /* Hide the cursor on that display. */ + ret = KMSDRM_RemoveCursorFromBO(display); + } + } + } + + return ret; +} + /* Warp the mouse to (x,y) */ static void KMSDRM_WarpMouse(SDL_Window * window, int x, int y) @@ -374,42 +375,42 @@ KMSDRM_WarpMouse(SDL_Window * window, int x, int y) static int KMSDRM_WarpMouseGlobal(int x, int y) { - KMSDRM_CursorData *curdata; SDL_Mouse *mouse = SDL_GetMouse(); - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) { + if (mouse && mouse->cur_cursor && mouse->focus) { + + SDL_Window *window = mouse->focus; + SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + /* Update internal mouse position. */ SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y); /* And now update the cursor graphic position on screen. */ - curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata; if (dispdata->cursor_bo) { - if (drm_atomic_movecursor(curdata, x, y)) { - return SDL_SetError("drm_atomic_movecursor() failed."); + int ret = 0; + + ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, x, y); + + if (ret) { + SDL_SetError("drmModeMoveCursor() failed."); } + + return ret; + } else { return SDL_SetError("Cursor not initialized properly."); } + } else { return SDL_SetError("No mouse or current cursor."); } - - return 0; } void -KMSDRM_InitMouse(_THIS) +KMSDRM_InitMouse(_THIS, SDL_VideoDisplay *display) { - /* FIXME: Using UDEV it should be possible to scan all mice - * but there's no point in doing so as there's no multimice support...yet! - */ - - SDL_VideoDevice *dev = SDL_GetVideoDevice(); - SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata); - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); SDL_Mouse *mouse = SDL_GetMouse(); - uint64_t usable_cursor_w, usable_cursor_h; + SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata; mouse->CreateCursor = KMSDRM_CreateCursor; mouse->ShowCursor = KMSDRM_ShowCursor; @@ -418,96 +419,18 @@ KMSDRM_InitMouse(_THIS) mouse->WarpMouse = KMSDRM_WarpMouse; mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal; - /***************************************************************************/ - /* REMEMBER TO BE SURE OF UNDOING ALL THESE STEPS PROPERLY BEFORE CALLING */ - /* gbm_device_destroy, OR YOU WON'T BE ABLE TO CREATE A NEW ONE (ERROR -13 */ - /* ON gbm_create_device). */ - /***************************************************************************/ - - /* 1- Init cursor plane, if we haven't yet. */ - if (!dispdata->cursor_plane) { - setup_plane(_this, &(dispdata->cursor_plane), DRM_PLANE_TYPE_CURSOR); - } - - /* 2- Create the cursor GBM BO, if we haven't yet. */ - if (!dispdata->cursor_bo) { - - if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, GBM_FORMAT_ARGB8888, - GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) - { - SDL_SetError("Unsupported pixel format for cursor"); - return; - } - - if (KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_WIDTH, &usable_cursor_w) || - KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_HEIGHT, &usable_cursor_h)) - { - SDL_SetError("Could not get the recommended GBM cursor size"); - goto cleanup; - } - - if (usable_cursor_w == 0 || usable_cursor_h == 0) { - SDL_SetError("Could not get an usable GBM cursor size"); - goto cleanup; - } - - dispdata->cursor_w = usable_cursor_w; - dispdata->cursor_h = usable_cursor_h; - - dispdata->cursor_bo = KMSDRM_gbm_bo_create(viddata->gbm_dev, - usable_cursor_w, usable_cursor_h, - GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE); - - if (!dispdata->cursor_bo) { - SDL_SetError("Could not create GBM cursor BO"); - goto cleanup; - } - } - - /* SDL expects to set the default cursor on screen when we init the mouse. */ - SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor()); - - return; - -cleanup: - if (dispdata->cursor_bo) { - KMSDRM_gbm_bo_destroy(dispdata->cursor_bo); - dispdata->cursor_bo = NULL; + /* Only create the default cursor for this display if we haven't done so before, + we don't want several cursors to be created for the same display. */ + if (!dispdata->default_cursor_init) { + SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor()); + dispdata->default_cursor_init = SDL_TRUE; } } void -KMSDRM_DeinitMouse(_THIS) +KMSDRM_QuitMouse(_THIS) { - SDL_VideoDevice *video_device = SDL_GetVideoDevice(); - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - KMSDRM_PlaneInfo info = {0}; - - /*******************************************/ - /* UNDO WHAT WE DID IN KMSDRM_InitMouse(). */ - /*******************************************/ - - /* 1- Destroy the curso GBM BO. */ - if (video_device && dispdata->cursor_bo) { - /* Unsethe the cursor BO from the cursor plane. - (The other members of the plane info are zeroed). */ - info.plane = dispdata->cursor_plane; - drm_atomic_set_plane_props(&info); - /* Wait until the cursor is unset from the cursor plane - before destroying it's BO. */ - if (drm_atomic_commit(video_device, SDL_TRUE)) { - SDL_SetError("Failed atomic commit in KMSDRM_DenitMouse."); - } - /* ..and finally destroy the cursor DRM BO! */ - KMSDRM_gbm_bo_destroy(dispdata->cursor_bo); - dispdata->cursor_bo = NULL; - } - - /* 2- Free the cursor plane, on which the cursor was being shown. */ - if (dispdata->cursor_plane) { - free_plane(&dispdata->cursor_plane); - } - + /* TODO: ? */ } /* This is called when a mouse motion event occurs */ @@ -515,22 +438,24 @@ static void KMSDRM_MoveCursor(SDL_Cursor * cursor) { SDL_Mouse *mouse = SDL_GetMouse(); - KMSDRM_CursorData *curdata; + int ret = 0; /* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity! That's why we move the cursor graphic ONLY. */ - if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) { - curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata; + if (mouse && mouse->cur_cursor && mouse->focus) { - /* Some programs expect cursor movement even while they don't do SwapWindow() calls, - and since we ride on the atomic_commit() in SwapWindow() for cursor movement, - cursor won't move in these situations. We could do an atomic_commit() here - for each cursor movement request, but it cripples the movement to 30FPS, - so a future solution is needed. SDLPoP "QUIT?" menu is an example of this - situation. */ + SDL_Window *window = mouse->focus; + SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - if (drm_atomic_movecursor(curdata, mouse->x, mouse->y)) { - SDL_SetError("drm_atomic_movecursor() failed."); + if (!dispdata->cursor_bo) { + SDL_SetError("Cursor not initialized properly."); + return; + } + + ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, mouse->x, mouse->y); + + if (ret) { + SDL_SetError("drmModeMoveCursor() failed."); } } } diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmmouse.h b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmmouse.h index 8993a315d..3879f7a06 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmmouse.h +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmmouse.h @@ -1,7 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - Atomic KMSDRM backend by Manuel Alfayate Corchete + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,24 +29,26 @@ #define MAX_CURSOR_W 512 #define MAX_CURSOR_H 512 -/* Driverdata with driver-side info about the cursor. */ typedef struct _KMSDRM_CursorData { - uint16_t hot_x, hot_y; - uint16_t w, h; + int hot_x, hot_y; + int w, h; /* The buffer where we store the mouse bitmap ready to be used. - We get it ready and filled in CreateCursor(), and copy it to a GBM BO in ShowCursor().*/ + We get it ready and filled in CreateCursor(), and copy it + to a GBM BO in ShowCursor().*/ uint32_t *buffer; size_t buffer_size; size_t buffer_pitch; } KMSDRM_CursorData; -extern void KMSDRM_InitMouse(_THIS); -extern void KMSDRM_DeinitMouse(_THIS); +extern void KMSDRM_InitMouse(_THIS, SDL_VideoDisplay *display); +extern void KMSDRM_QuitMouse(_THIS); -extern void KMSDRM_InitCursor(); +extern void KMSDRM_CreateCursorBO(SDL_VideoDisplay *display); +extern void KMSDRM_DestroyCursorBO(_THIS, SDL_VideoDisplay *display); +extern void KMSDRM_InitCursor(void); #endif /* SDL_KMSDRM_mouse_h_ */ diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmopengles.c b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmopengles.c index c9ec554b4..25d942e09 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmopengles.c +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmopengles.c @@ -1,7 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - Atomic KMSDRM backend by Manuel Alfayate Corchete + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,29 +21,19 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL +#if SDL_VIDEO_DRIVER_KMSDRM + +#include "SDL_log.h" #include "SDL_kmsdrmvideo.h" #include "SDL_kmsdrmopengles.h" #include "SDL_kmsdrmdyn.h" -#include "SDL_hints.h" +#include #ifndef EGL_PLATFORM_GBM_MESA #define EGL_PLATFORM_GBM_MESA 0x31D7 #endif -#ifndef EGL_SYNC_NATIVE_FENCE_ANDROID -#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144 -#endif - -#ifndef EGL_SYNC_NATIVE_FENCE_FD_ANDROID -#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145 -#endif - -#ifndef EGL_NO_NATIVE_FENCE_FD_ANDROID -#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1 -#endif - /* EGL implementation of SDL OpenGL support */ void @@ -75,13 +64,14 @@ KMSDRM_GLES_LoadLibrary(_THIS, const char *path) { void KMSDRM_GLES_UnloadLibrary(_THIS) { - /* As with KMSDRM_GLES_LoadLibrary(), we define our own unloading function so - we manually unload the library whenever we want. */ + /* As with KMSDRM_GLES_LoadLibrary(), we define our own "dummy" unloading function + so we manually unload the library whenever we want. */ } SDL_EGL_CreateContext_impl(KMSDRM) int KMSDRM_GLES_SetSwapInterval(_THIS, int interval) { + if (!_this->egl_data) { return SDL_SetError("EGL not initialized"); } @@ -95,287 +85,122 @@ int KMSDRM_GLES_SetSwapInterval(_THIS, int interval) { return 0; } -/*********************************/ -/* Atomic functions block */ -/*********************************/ - -#define VOID2U64(x) ((uint64_t)(unsigned long)(x)) - -static EGLSyncKHR create_fence(int fd, _THIS) -{ - EGLint attrib_list[] = { - EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, - EGL_NONE, - }; - - EGLSyncKHR fence = _this->egl_data->eglCreateSyncKHR - (_this->egl_data->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attrib_list); - - assert(fence); - return fence; -} - -/***********************************************************************************/ -/* Comments about buffer access protection mechanism (=fences) are the ones boxed. */ -/* Also, DON'T remove the asserts: if a fence-related call fails, it's better that */ -/* program exits immediately, or we could leave KMS waiting for a failed/missing */ -/* fence forevever. */ -/***********************************************************************************/ int -KMSDRM_GLES_SwapWindowFenced(_THIS, SDL_Window * window) -{ +KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) { SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata); SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - KMSDRM_FBInfo *fb; - KMSDRM_PlaneInfo info = {0}; + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + KMSDRM_FBInfo *fb_info; + int ret = 0; - /******************************************************************/ - /* Create the GPU-side FENCE OBJECT. It will be inserted into the */ - /* GL CMDSTREAM exactly at the end of the gl commands that form a */ - /* frame.(KMS will have to wait on it before doing a pageflip.) */ - /******************************************************************/ - dispdata->gpu_fence = create_fence(EGL_NO_NATIVE_FENCE_FD_ANDROID, _this); - assert(dispdata->gpu_fence); + /* Always wait for the previous issued flip before issuing a new one, + even if you do async flips. */ + uint32_t flip_flags = DRM_MODE_PAGE_FLIP_EVENT; - /******************************************************************/ - /* eglSwapBuffers flushes the fence down the GL CMDSTREAM, so we */ - /* know for sure it's there now. */ - /* Also it marks, at EGL level, the buffer that we want to become */ - /* the new front buffer. (Remember that won't really happen until */ - /* we request a pageflip at the KMS level and it completes. */ - /******************************************************************/ - if (! _this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, windata->egl_surface)) { - return SDL_EGL_SetError("Failed to swap EGL buffers", "eglSwapBuffers"); + /* Recreate the GBM / EGL surfaces if the display mode has changed */ + if (windata->egl_surface_dirty) { + KMSDRM_CreateSurfaces(_this, window); } - /******************************************************************/ - /* EXPORT the GPU-side FENCE OBJECT to the fence INPUT FD, so we */ - /* can pass it into the kernel. Atomic ioctl will pass the */ - /* in-fence fd into the kernel, thus telling KMS that it has to */ - /* wait for GPU to finish rendering the frame (remember where we */ - /* put the fence in the GL CMDSTREAM) before doing the changes */ - /* requested in the atomic ioct (the pageflip in this case). */ - /* (We export the GPU-side FENCE OJECT to the fence INPUT FD now, */ - /* not sooner, because now we are sure that the GPU-side fence is */ - /* in the CMDSTREAM to be lifted when the CMDSTREAM to this point */ - /* is completed). */ - /******************************************************************/ - dispdata->kms_in_fence_fd = _this->egl_data->eglDupNativeFenceFDANDROID (_this->egl_data->egl_display, - dispdata->gpu_fence); - - _this->egl_data->eglDestroySyncKHR(_this->egl_data->egl_display, dispdata->gpu_fence); - assert(dispdata->kms_in_fence_fd != -1); - - /* Lock the buffer that is marked by eglSwapBuffers() to become the - next front buffer (so it can not be chosen by EGL as back buffer - to draw on), and get a handle to it to request the pageflip on it. - REMEMBER that gbm_surface_lock_front_buffer() ALWAYS has to be - called after eglSwapBuffers(). */ - windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs); - if (!windata->next_bo) { - return SDL_SetError("Failed to lock frontbuffer"); - } - fb = KMSDRM_FBFromBO(_this, windata->next_bo); - if (!fb) { - return SDL_SetError("Failed to get a new framebuffer from BO"); + /* Wait for confirmation that the next front buffer has been flipped, at which + point the previous front buffer can be released */ + if (!KMSDRM_WaitPageflip(_this, windata)) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Wait for previous pageflip failed"); + return 0; } - /* Add the pageflip to the request list. */ - info.plane = dispdata->display_plane; - info.crtc_id = dispdata->crtc->crtc->crtc_id; - info.fb_id = fb->fb_id; - - info.src_w = windata->src_w; - info.src_h = windata->src_h; - info.crtc_w = windata->output_w; - info.crtc_h = windata->output_h; - info.crtc_x = windata->output_x; - - drm_atomic_set_plane_props(&info); - - /*****************************************************************/ - /* Tell the display (KMS) that it will have to wait on the fence */ - /* for the GPU-side FENCE. */ - /* */ - /* Since KMS is a kernel thing, we have to pass an FD into */ - /* the kernel, and get another FD out of the kernel. */ - /* */ - /* 1) To pass the GPU-side fence into the kernel, we set the */ - /* INPUT FD as the IN_FENCE_FD prop of the PRIMARY PLANE. */ - /* This FD tells KMS (the kernel) to wait for the GPU-side fence.*/ - /* */ - /* 2) To get the KMS-side fence out of the kernel, we set the */ - /* OUTPUT FD as the OUT_FEWNCE_FD prop of the CRTC. */ - /* This FD will be later imported as a FENCE OBJECT which will be*/ - /* used to tell the GPU to wait for KMS to complete the changes */ - /* requested in atomic_commit (the pageflip in this case). */ - /*****************************************************************/ - if (dispdata->kms_in_fence_fd != -1) - { - add_plane_property(dispdata->atomic_req, dispdata->display_plane, - "IN_FENCE_FD", dispdata->kms_in_fence_fd); - add_crtc_property(dispdata->atomic_req, dispdata->crtc, - "OUT_FENCE_PTR", VOID2U64(&dispdata->kms_out_fence_fd)); - } - - /* Do we have a pending modesetting? If so, set the necessary - props so it's included in the incoming atomic commit. */ - if (dispdata->modeset_pending) { - uint32_t blob_id; - SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; - - dispdata->atomic_flags |= DRM_MODE_ATOMIC_ALLOW_MODESET; - add_connector_property(dispdata->atomic_req, dispdata->connector, "CRTC_ID", dispdata->crtc->crtc->crtc_id); - KMSDRM_drmModeCreatePropertyBlob(viddata->drm_fd, &dispdata->mode, sizeof(dispdata->mode), &blob_id); - add_crtc_property(dispdata->atomic_req, dispdata->crtc, "MODE_ID", blob_id); - add_crtc_property(dispdata->atomic_req, dispdata->crtc, "ACTIVE", 1); - dispdata->modeset_pending = SDL_FALSE; - } - - /*****************************************************************/ - /* Issue a non-blocking atomic commit: for triple buffering, */ - /* this must not block so the game can start building another */ - /* frame, even if the just-requested pageflip hasnt't completed. */ - /*****************************************************************/ - if (drm_atomic_commit(_this, SDL_FALSE)) { - return SDL_SetError("Failed to issue atomic commit on pageflip"); - } - - /* Release the previous front buffer so EGL can chose it as back buffer - and render on it again. */ + /* Release the previous front buffer */ if (windata->bo) { KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo); + windata->bo = NULL; } - /* Take note of the buffer about to become front buffer, so next - time we come here we can free it like we just did with the previous - front buffer. */ windata->bo = windata->next_bo; - /****************************************************************/ - /* Import the KMS-side FENCE OUTPUT FD from the kernel to the */ - /* KMS-side FENCE OBJECT so we can use use it to fence the GPU. */ - /****************************************************************/ - dispdata->kms_fence = create_fence(dispdata->kms_out_fence_fd, _this); - assert(dispdata->kms_fence); - - /****************************************************************/ - /* "Delete" the fence OUTPUT FD, because we already have the */ - /* KMS FENCE OBJECT, the fence itself is away from us, on the */ - /* kernel side. */ - /****************************************************************/ - dispdata->kms_out_fence_fd = -1; - - /*****************************************************************/ - /* Tell the GPU to wait on the fence for the KMS-side FENCE, */ - /* which means waiting until the requested pageflip is completed.*/ - /*****************************************************************/ - _this->egl_data->eglWaitSyncKHR(_this->egl_data->egl_display, dispdata->kms_fence, 0); - - return 0; -} - -int -KMSDRM_GLES_SwapWindowDoubleBuffered(_THIS, SDL_Window * window) -{ - SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata); - SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - KMSDRM_FBInfo *fb; - KMSDRM_PlaneInfo info = {0}; - - /****************************************************************************************************/ - /* In double-buffer mode, atomic_commit will always be synchronous/blocking (ie: won't return until */ - /* the requested changes are really done). */ - /* Also, there's no need to fence KMS or the GPU, because we won't be entering game loop again */ - /* (hence not building or executing a new cmdstring) until pageflip is done, so we don't need to */ - /* protect the KMS/GPU access to the buffer. */ - /****************************************************************************************************/ - - /* Mark, at EGL level, the buffer that we want to become the new front buffer. - However, it won't really happen until we request a pageflip at the KMS level and it completes. */ - if (! _this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, windata->egl_surface)) { - return SDL_EGL_SetError("Failed to swap EGL buffers", "eglSwapBuffers"); + /* Mark a buffer to becume the next front buffer. + This won't happen until pagelip completes. */ + if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, + windata->egl_surface))) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed"); + return 0; } - /* Lock the buffer that is marked by eglSwapBuffers() to become the next front buffer (so it can not - be chosen by EGL as back buffer to draw on), and get a handle to it to request the pageflip on it. */ + /* From the GBM surface, get the next BO to become the next front buffer, + and lock it so it can't be allocated as a back buffer (to prevent EGL + from drawing into it!) */ windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs); if (!windata->next_bo) { - return SDL_SetError("Failed to lock frontbuffer"); - } - fb = KMSDRM_FBFromBO(_this, windata->next_bo); - if (!fb) { - return SDL_SetError("Failed to get a new framebuffer BO"); + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock front buffer on GBM surface"); + return 0; } - /* Add the pageflip to the request list. */ - info.plane = dispdata->display_plane; - info.crtc_id = dispdata->crtc->crtc->crtc_id; - info.fb_id = fb->fb_id; - - info.src_w = windata->src_w; - info.src_h = windata->src_h; - info.crtc_w = windata->output_w; - info.crtc_h = windata->output_h; - info.crtc_x = windata->output_x; - - drm_atomic_set_plane_props(&info); - - /* Do we have a pending modesetting? If so, set the necessary - props so it's included in the incoming atomic commit. */ - if (dispdata->modeset_pending) { - SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; - uint32_t blob_id; - dispdata->atomic_flags |= DRM_MODE_ATOMIC_ALLOW_MODESET; - add_connector_property(dispdata->atomic_req, dispdata->connector, "CRTC_ID", dispdata->crtc->crtc->crtc_id); - KMSDRM_drmModeCreatePropertyBlob(viddata->drm_fd, &dispdata->mode, sizeof(dispdata->mode), &blob_id); - add_crtc_property(dispdata->atomic_req, dispdata->crtc, "MODE_ID", blob_id); - add_crtc_property(dispdata->atomic_req, dispdata->crtc, "ACTIVE", 1); - dispdata->modeset_pending = SDL_FALSE; + /* Get an actual usable fb for the next front buffer. */ + fb_info = KMSDRM_FBFromBO(_this, windata->next_bo); + if (!fb_info) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not get a framebuffer"); + return 0; } - /* Issue the one and only atomic commit where all changes will be requested!. - Blocking for double buffering: won't return until completed. */ - if (drm_atomic_commit(_this, SDL_TRUE)) { - return SDL_SetError("Failed to issue atomic commit"); - } + if (!windata->bo) { + /* On the first swap, immediately present the new front buffer. Before + drmModePageFlip can be used the CRTC has to be configured to use + the current connector and mode with drmModeSetCrtc */ + ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd, + dispdata->crtc->crtc_id, fb_info->fb_id, 0, 0, + &dispdata->connector->connector_id, 1, &dispdata->mode); - /* Release last front buffer so EGL can chose it as back buffer and render on it again. */ - if (windata->bo) { - KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo); - } + if (ret) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not set videomode on CRTC."); + return 0; + } + } else { + /* On subsequent swaps, queue the new front buffer to be flipped during + the next vertical blank - /* Take note of current front buffer, so we can free it next time we come here. */ - windata->bo = windata->next_bo; + Remember: drmModePageFlip() never blocks, it just issues the flip, + which will be done during the next vblank, or immediately if + we pass the DRM_MODE_PAGE_FLIP_ASYNC flag. + Since calling drmModePageFlip() will return EBUSY if we call it + without having completed the last issued flip, we must pass the + DRM_MODE_PAGE_FLIP_ASYNC if we don't block on EGL (egl_swapinterval = 0). + That makes it flip immediately, without waiting for the next vblank + to do so, so even if we don't block on EGL, the flip will have completed + when we get here again. */ + if (_this->egl_data->egl_swapinterval == 0 && viddata->async_pageflip_support) { + flip_flags |= DRM_MODE_PAGE_FLIP_ASYNC; + } - return 0; -} + ret = KMSDRM_drmModePageFlip(viddata->drm_fd, dispdata->crtc->crtc_id, + fb_info->fb_id, flip_flags, &windata->waiting_for_flip); -int -KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) -{ - SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata); - - if (windata->swap_window == NULL) { - /* We want the fenced version by default, but it needs extensions. */ - if ( (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) || - (!SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_ANDROID_native_fence_sync")) ) - { - windata->swap_window = KMSDRM_GLES_SwapWindowDoubleBuffered; + if (ret == 0) { + windata->waiting_for_flip = SDL_TRUE; } else { - windata->swap_window = KMSDRM_GLES_SwapWindowFenced; + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret); + } + + /* Wait immediately for vsync (as if we only had two buffers). + Even if we are already doing a WaitPageflip at the begining of this + function, this is NOT redundant because here we wait immediately + after submitting the image to the screen, reducing lag, and if + we have waited here, there won't be a pending pageflip so the + WaitPageflip at the beggining of this function will be a no-op. + Just leave it here and don't worry. + Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 " + to enable this. */ + if (windata->double_buffer) { + if (!KMSDRM_WaitPageflip(_this, windata)) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Immediate wait for previous pageflip failed"); + return 0; + } } } - return windata->swap_window(_this, window); + return 1; } -/***************************************/ -/* End of Atomic functions block */ -/***************************************/ - SDL_EGL_MakeCurrent_impl(KMSDRM) -#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */ +#endif /* SDL_VIDEO_DRIVER_KMSDRM */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmopengles.h b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmopengles.h index f81b0c3dc..a762ab0f3 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmopengles.h +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmopengles.h @@ -1,7 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - Atomic KMSDRM backend by Manuel Alfayate Corchete + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +23,7 @@ #ifndef SDL_kmsdrmopengles_h_ #define SDL_kmsdrmopengles_h_ -#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL +#if SDL_VIDEO_DRIVER_KMSDRM #include "../SDL_sysvideo.h" #include "../SDL_egl_c.h" @@ -42,7 +41,7 @@ extern SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window * window); extern int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window); extern int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); -#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */ +#endif /* SDL_VIDEO_DRIVER_KMSDRM */ #endif /* SDL_kmsdrmopengles_h_ */ diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmsym.h b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmsym.h index b75943b75..52c78de5e 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmsym.h +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmsym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -41,32 +41,41 @@ SDL_KMSDRM_SYM(void,drmModeFreeCrtc,(drmModeCrtcPtr ptr)) SDL_KMSDRM_SYM(void,drmModeFreeConnector,(drmModeConnectorPtr ptr)) SDL_KMSDRM_SYM(void,drmModeFreeEncoder,(drmModeEncoderPtr ptr)) SDL_KMSDRM_SYM(int,drmGetCap,(int fd, uint64_t capability, uint64_t *value)) -SDL_KMSDRM_SYM(int,drmIoctl,(int fd, unsigned long request, void *arg)) +SDL_KMSDRM_SYM(int,drmSetMaster,(int fd)) +SDL_KMSDRM_SYM(int,drmAuthMagic,(int fd, drm_magic_t magic)) SDL_KMSDRM_SYM(drmModeResPtr,drmModeGetResources,(int fd)) - SDL_KMSDRM_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_t depth, - uint8_t bpp, uint32_t pitch, uint32_t bo_handle, - uint32_t *buf_id)) + uint8_t bpp, uint32_t pitch, uint32_t bo_handle, + uint32_t *buf_id)) SDL_KMSDRM_SYM(int,drmModeAddFB2,(int fd, uint32_t width, uint32_t height, - uint32_t pixel_format, const uint32_t bo_handles[4], - const uint32_t pitches[4], const uint32_t offsets[4], - uint32_t *buf_id, uint32_t flags)) - -SDL_KMSDRM_SYM(int,drmModeAddFB2WithModifiers,(int fd, uint32_t width, uint32_t height, - uint32_t pixel_format, const uint32_t bo_handles[4], - const uint32_t pitches[4], const uint32_t offsets[4], - const uint64_t modifier[4], uint32_t *buf_id, - uint32_t flags)) + uint32_t pixel_format, const uint32_t bo_handles[4], + const uint32_t pitches[4], const uint32_t offsets[4], + uint32_t *buf_id, uint32_t flags)) SDL_KMSDRM_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId)) SDL_KMSDRM_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf)) SDL_KMSDRM_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId)) +SDL_KMSDRM_SYM(int,drmModeSetCrtc,(int fd, uint32_t crtcId, uint32_t bufferId, + uint32_t x, uint32_t y, uint32_t *connectors, int count, + drmModeModeInfoPtr mode)) +SDL_KMSDRM_SYM(int,drmModeCrtcGetGamma,(int fd, uint32_t crtc_id, uint32_t size, + uint16_t *red, uint16_t *green, uint16_t *blue)) +SDL_KMSDRM_SYM(int,drmModeCrtcSetGamma,(int fd, uint32_t crtc_id, uint32_t size, + uint16_t *red, uint16_t *green, uint16_t *blue)) +SDL_KMSDRM_SYM(int,drmModeSetCursor,(int fd, uint32_t crtcId, uint32_t bo_handle, + uint32_t width, uint32_t height)) +SDL_KMSDRM_SYM(int,drmModeSetCursor2,(int fd, uint32_t crtcId, uint32_t bo_handle, + uint32_t width, uint32_t height, + int32_t hot_x, int32_t hot_y)) +SDL_KMSDRM_SYM(int,drmModeMoveCursor,(int fd, uint32_t crtcId, int x, int y)) SDL_KMSDRM_SYM(drmModeEncoderPtr,drmModeGetEncoder,(int fd, uint32_t encoder_id)) SDL_KMSDRM_SYM(drmModeConnectorPtr,drmModeGetConnector,(int fd, uint32_t connector_id)) +SDL_KMSDRM_SYM(int,drmHandleEvent,(int fd,drmEventContextPtr evctx)) +SDL_KMSDRM_SYM(int,drmModePageFlip,(int fd, uint32_t crtc_id, uint32_t fb_id, + uint32_t flags, void *user_data)) -/* Atomic functions */ - +/* Planes stuff. */ SDL_KMSDRM_SYM(int,drmSetClientCap,(int fd, uint64_t capability, uint64_t value)) SDL_KMSDRM_SYM(drmModePlaneResPtr,drmModeGetPlaneResources,(int fd)) SDL_KMSDRM_SYM(drmModePlanePtr,drmModeGetPlane,(int fd, uint32_t plane_id)) @@ -77,17 +86,15 @@ SDL_KMSDRM_SYM(void,drmModeFreeProperty,(drmModePropertyPtr ptr)) SDL_KMSDRM_SYM(void,drmModeFreeObjectProperties,(drmModeObjectPropertiesPtr ptr)) SDL_KMSDRM_SYM(void,drmModeFreePlane,(drmModePlanePtr ptr)) SDL_KMSDRM_SYM(void,drmModeFreePlaneResources,(drmModePlaneResPtr ptr)) - -SDL_KMSDRM_SYM(drmModeAtomicReqPtr,drmModeAtomicAlloc,(void)) -SDL_KMSDRM_SYM(void,drmModeAtomicFree,(drmModeAtomicReqPtr req)) -SDL_KMSDRM_SYM(int,drmModeAtomicCommit,(int fd,drmModeAtomicReqPtr req,uint32_t flags,void *user_data)) -SDL_KMSDRM_SYM(int,drmModeAtomicAddProperty,(drmModeAtomicReqPtr req,uint32_t object_id,uint32_t property_id,uint64_t value)) -SDL_KMSDRM_SYM(int,drmModeCreatePropertyBlob,(int fd,const void *data,size_t size,uint32_t *id)) - -/* End of atomic fns */ +SDL_KMSDRM_SYM(int,drmModeSetPlane,(int fd, uint32_t plane_id, uint32_t crtc_id, + uint32_t fb_id, uint32_t flags, + int32_t crtc_x, int32_t crtc_y, + uint32_t crtc_w, uint32_t crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h)) +/* Planes stuff ends. */ SDL_KMSDRM_MODULE(GBM) -SDL_KMSDRM_SYM(int,gbm_device_get_fd,(struct gbm_device *gbm)) SDL_KMSDRM_SYM(int,gbm_device_is_format_supported,(struct gbm_device *gbm, uint32_t format, uint32_t usage)) SDL_KMSDRM_SYM(void,gbm_device_destroy,(struct gbm_device *gbm)) @@ -95,11 +102,7 @@ SDL_KMSDRM_SYM(struct gbm_device *,gbm_create_device,(int fd)) SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_width,(struct gbm_bo *bo)) SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_height,(struct gbm_bo *bo)) SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride,(struct gbm_bo *bo)) -SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride_for_plane,(struct gbm_bo *bo,int plane)) SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_format,(struct gbm_bo *bo)) -SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_offset,(struct gbm_bo *bo, int plane)) -SDL_KMSDRM_SYM(int,gbm_bo_get_plane_count,(struct gbm_bo *bo)) - SDL_KMSDRM_SYM(union gbm_bo_handle,gbm_bo_get_handle,(struct gbm_bo *bo)) SDL_KMSDRM_SYM(int,gbm_bo_write,(struct gbm_bo *bo, const void *buf, size_t count)) SDL_KMSDRM_SYM(struct gbm_device *,gbm_bo_get_device,(struct gbm_bo *bo)) diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvideo.c b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvideo.c index e84bd5ebc..fd3a3cd63 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -1,7 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - Atomic KMSDRM backend by Manuel Alfayate Corchete + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,12 +26,16 @@ /* SDL internals */ #include "../SDL_sysvideo.h" #include "SDL_syswm.h" +#include "SDL_log.h" +#include "SDL_hints.h" #include "../../events/SDL_events_c.h" #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_keyboard_c.h" #ifdef SDL_INPUT_LINUXEV #include "../../core/linux/SDL_evdev.h" +#elif defined SDL_INPUT_WSCONS +#include "../../core/openbsd/SDL_wscons.h" #endif /* KMS/DRM declarations */ @@ -43,67 +46,80 @@ #include "SDL_kmsdrmdyn.h" #include "SDL_kmsdrmvulkan.h" #include +#include +#include #include -#include #include +#include -/* for older KMSDRM headers... */ -#ifndef DRM_FORMAT_MOD_VENDOR_NONE -#define DRM_FORMAT_MOD_VENDOR_NONE 0 -#endif -#ifndef DRM_FORMAT_MOD_LINEAR -#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0) -#endif - +#ifdef __OpenBSD__ +static SDL_bool openbsd69orgreater = SDL_FALSE; +#define KMSDRM_DRI_PATH openbsd69orgreater ? "/dev/dri/" : "/dev/" +#define KMSDRM_DRI_DEVFMT openbsd69orgreater ? "%scard%d" : "%sdrm%d" +#define KMSDRM_DRI_DEVNAME openbsd69orgreater ? "card" : "drm" +#define KMSDRM_DRI_DEVNAMESIZE openbsd69orgreater ? 4 : 3 +#define KMSDRM_DRI_CARDPATHFMT openbsd69orgreater ? "/dev/dri/card%d" : "/dev/drm%d" +#else #define KMSDRM_DRI_PATH "/dev/dri/" +#define KMSDRM_DRI_DEVFMT "%scard%d" +#define KMSDRM_DRI_DEVNAME "card" +#define KMSDRM_DRI_DEVNAMESIZE 4 +#define KMSDRM_DRI_CARDPATHFMT "/dev/dri/card%d" +#endif -static int set_client_caps (int fd) -{ - if (KMSDRM_drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1)) { - return SDL_SetError("no atomic modesetting support."); - } - if (KMSDRM_drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) { - return SDL_SetError("no universal planes support."); - } - return 0; -} +#ifndef EGL_PLATFORM_GBM_MESA +#define EGL_PLATFORM_GBM_MESA 0x31D7 +#endif static int -check_modesetting(int devindex) +check_modestting(int devindex) { SDL_bool available = SDL_FALSE; char device[512]; - unsigned int i; int drm_fd; + int i; - SDL_snprintf(device, sizeof (device), "%scard%d", KMSDRM_DRI_PATH, devindex); - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "check_modesetting: probing \"%s\"", device); + SDL_snprintf(device, sizeof (device), KMSDRM_DRI_DEVFMT, KMSDRM_DRI_PATH, devindex); drm_fd = open(device, O_RDWR | O_CLOEXEC); if (drm_fd >= 0) { if (SDL_KMSDRM_LoadSymbols()) { - drmModeRes *resources = (set_client_caps(drm_fd) < 0) ? NULL : KMSDRM_drmModeGetResources(drm_fd); + drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd); if (resources) { - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "%scard%d connector, encoder and CRTC counts are: %d %d %d", - KMSDRM_DRI_PATH, devindex, - resources->count_connectors, resources->count_encoders, resources->count_crtcs); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, + KMSDRM_DRI_DEVFMT + " connector, encoder and CRTC counts are: %d %d %d", + KMSDRM_DRI_PATH, devindex, + resources->count_connectors, resources->count_encoders, + resources->count_crtcs); - if (resources->count_connectors > 0 && resources->count_encoders > 0 && resources->count_crtcs > 0) { + if (resources->count_connectors > 0 + && resources->count_encoders > 0 + && resources->count_crtcs > 0) + { + available = SDL_FALSE; for (i = 0; i < resources->count_connectors; i++) { - drmModeConnector *conn = KMSDRM_drmModeGetConnector(drm_fd, resources->connectors[i]); + drmModeConnector *conn = KMSDRM_drmModeGetConnector(drm_fd, + resources->connectors[i]); if (!conn) { continue; } if (conn->connection == DRM_MODE_CONNECTED && conn->count_modes) { + if (SDL_GetHintBoolean(SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER, SDL_TRUE)) { + /* Skip this device if we can't obtain DRM master */ + KMSDRM_drmSetMaster(drm_fd); + if (KMSDRM_drmAuthMagic(drm_fd, 0) == -EACCES) { + continue; + } + } + available = SDL_TRUE; + break; } KMSDRM_drmModeFreeConnector(conn); - if (available) { - break; - } } } KMSDRM_drmModeFreeResources(resources); @@ -116,30 +132,30 @@ check_modesetting(int devindex) return available; } -static unsigned int get_dricount(void) +static int get_dricount(void) { - unsigned int devcount = 0; + int devcount = 0; struct dirent *res; struct stat sb; DIR *folder; - if (!(stat(KMSDRM_DRI_PATH, &sb) == 0 && S_ISDIR(sb.st_mode))) { - SDL_SetError("The path %s cannot be opened or is not available", - KMSDRM_DRI_PATH); + if (!(stat(KMSDRM_DRI_PATH, &sb) == 0 + && S_ISDIR(sb.st_mode))) { + /*printf("The path %s cannot be opened or is not available\n", KMSDRM_DRI_PATH);*/ return 0; } if (access(KMSDRM_DRI_PATH, F_OK) == -1) { - SDL_SetError("The path %s cannot be opened", - KMSDRM_DRI_PATH); + /*printf("The path %s cannot be opened\n", KMSDRM_DRI_PATH);*/ return 0; } folder = opendir(KMSDRM_DRI_PATH); if (folder) { while ((res = readdir(folder))) { - size_t len = SDL_strlen(res->d_name); - if (len > 4 && SDL_strncmp(res->d_name, "card", 4) == 0) { + int len = SDL_strlen(res->d_name); + if (len > KMSDRM_DRI_DEVNAMESIZE && SDL_strncmp(res->d_name, + KMSDRM_DRI_DEVNAME, KMSDRM_DRI_DEVNAMESIZE) == 0) { devcount++; } } @@ -152,11 +168,11 @@ static unsigned int get_dricount(void) static int get_driindex(void) { - const unsigned int devcount = get_dricount(); - unsigned int i; + const int devcount = get_dricount(); + int i; for (i = 0; i < devcount; i++) { - if (check_modesetting(i)) { + if (check_modestting(i)) { return i; } } @@ -164,577 +180,23 @@ get_driindex(void) return -ENOENT; } -#if 0 - -/**********************/ -/* DUMB BUFFER Block. */ -/**********************/ - -/* Create a dumb buffer, mmap the dumb buffer and fill it with pixels, */ -/* then create a KMS framebuffer wrapping the dumb buffer. */ -static dumb_buffer *KMSDRM_CreateDumbBuffer(_THIS) -{ - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - - struct drm_mode_create_dumb create; - struct drm_mode_map_dumb map; - struct drm_mode_destroy_dumb destroy; - - dumb_buffer *ret = SDL_calloc(1, sizeof(*ret)); - if (!ret) { - SDL_OutOfMemory(); - return NULL; - } - - /* - * The create ioctl uses the combination of depth and bpp to infer - * a format; 24/32 refers to DRM_FORMAT_XRGB8888 as defined in - * the drm_fourcc.h header. These arguments are the same as given - * to drmModeAddFB, which has since been superseded by - * drmModeAddFB2 as the latter takes an explicit format token. - * - * We only specify these arguments; the driver calculates the - * pitch (also known as stride or row length) and total buffer size - * for us, also returning us the GEM handle. - */ - create = (struct drm_mode_create_dumb) { - .width = dispdata->mode.hdisplay, - .height = dispdata->mode.vdisplay, - .bpp = 32, - }; - - if (KMSDRM_drmIoctl(viddata->drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create)) { - SDL_SetError("failed to create dumb buffer\n"); - goto err; - } - - ret->gem_handles[0] = create.handle; - ret->format = DRM_FORMAT_XRGB8888; - ret->modifier = DRM_FORMAT_MOD_LINEAR; - ret->width = create.width; - ret->height = create.height; - ret->pitches[0] = create.pitch; - - /* - * In order to map the buffer, we call an ioctl specific to the buffer - * type, which returns us a fake offset to use with the mmap syscall. - * mmap itself then works as you expect. - * - * Note this means it is not possible to map arbitrary offsets of - * buffers without specifically requesting it from the kernel. - */ - map = (struct drm_mode_map_dumb) { - .handle = ret->gem_handles[0], - }; - - if (KMSDRM_drmIoctl(viddata->drm_fd, DRM_IOCTL_MODE_MAP_DUMB, &map)) { - SDL_SetError("failed to get mmap offset for the dumb buffer."); - goto err_dumb; - } - - ret->dumb.mem = mmap(NULL, create.size, PROT_WRITE, MAP_SHARED, - viddata->drm_fd, map.offset); - - if (ret->dumb.mem == MAP_FAILED) { - SDL_SetError("failed to get mmap offset for the dumb buffer."); - goto err_dumb; - } - ret->dumb.size = create.size; - - return ret; - -err_dumb: - destroy = (struct drm_mode_destroy_dumb) { .handle = create.handle }; - KMSDRM_drmIoctl(viddata->drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy); -err: - SDL_free(ret); - return NULL; -} - -static void -KMSDRM_DestroyDumbBuffer(_THIS, dumb_buffer **buffer) -{ - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - - struct drm_mode_destroy_dumb destroy = { - .handle = (*buffer)->gem_handles[0], - }; - - KMSDRM_drmModeRmFB(viddata->drm_fd, (*buffer)->fb_id); - - munmap((*buffer)->dumb.mem, (*buffer)->dumb.size); - KMSDRM_drmIoctl(viddata->drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy); - free(*buffer); - *buffer = NULL; -} - -/* Using the CPU mapping, fill the dumb buffer with black pixels. */ -static void -KMSDRM_FillDumbBuffer(dumb_buffer *buffer) -{ - unsigned int x, y; - for (y = 0; y < buffer->height; y++) { - uint32_t *pix = (uint32_t *) ((uint8_t *) buffer->dumb.mem + (y * buffer->pitches[0])); - for (x = 0; x < buffer->width; x++) { - *pix++ = (0x00000000); - } - } -} - -static dumb_buffer *KMSDRM_CreateBuffer(_THIS) -{ - dumb_buffer *ret; - int err; - - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - - ret = KMSDRM_CreateDumbBuffer(_this); - - if (!ret) - return NULL; - - /* - * Wrap our GEM buffer in a KMS framebuffer, so we can then attach it - * to a plane. Here's where we get out fb_id! - */ - err = KMSDRM_drmModeAddFB2(viddata->drm_fd, ret->width, ret->height, - ret->format, ret->gem_handles, ret->pitches, - ret->offsets, &ret->fb_id, 0); - - if (err != 0 || ret->fb_id == 0) { - SDL_SetError("Failed AddFB2 on dumb buffer\n"); - goto err; - } - return ret; - -err: - KMSDRM_DestroyDumbBuffer(_this, &ret); - return NULL; -} - -/***************************/ -/* DUMB BUFFER Block ends. */ -/***************************/ - -#endif - -/*********************************/ -/* Atomic helper functions block */ -/*********************************/ - -#define VOID2U64(x) ((uint64_t)(unsigned long)(x)) - -int add_connector_property(drmModeAtomicReq *req, struct connector *connector, - const char *name, uint64_t value) -{ - unsigned int i; - int prop_id = 0; - - for (i = 0 ; i < connector->props->count_props ; i++) { - if (strcmp(connector->props_info[i]->name, name) == 0) { - prop_id = connector->props_info[i]->prop_id; - break; - } - } - - if (prop_id < 0) { - SDL_SetError("no connector property: %s", name); - return -EINVAL; - } - - return KMSDRM_drmModeAtomicAddProperty(req, connector->connector->connector_id, prop_id, value); -} - -int add_crtc_property(drmModeAtomicReq *req, struct crtc *crtc, - const char *name, uint64_t value) -{ - unsigned int i; - int prop_id = -1; - - for (i = 0 ; i < crtc->props->count_props ; i++) { - if (strcmp(crtc->props_info[i]->name, name) == 0) { - prop_id = crtc->props_info[i]->prop_id; - break; - } - } - - if (prop_id < 0) { - SDL_SetError("no crtc property: %s", name); - return -EINVAL; - } - - return KMSDRM_drmModeAtomicAddProperty(req, crtc->crtc->crtc_id, prop_id, value); -} - -int add_plane_property(drmModeAtomicReq *req, struct plane *plane, - const char *name, uint64_t value) -{ - unsigned int i; - int prop_id = -1; - - for (i = 0 ; i < plane->props->count_props ; i++) { - if (strcmp(plane->props_info[i]->name, name) == 0) { - prop_id = plane->props_info[i]->prop_id; - break; - } - } - - if (prop_id < 0) { - SDL_SetError("no plane property: %s", name); - return -EINVAL; - } - - return KMSDRM_drmModeAtomicAddProperty(req, plane->plane->plane_id, prop_id, value); -} - -#if 0 - -void print_plane_info(_THIS, drmModePlanePtr plane) -{ - char *plane_type; - drmModeRes *resources; - uint32_t type = 0; - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - int i; - - drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(viddata->drm_fd, - plane->plane_id, DRM_MODE_OBJECT_PLANE); - - /* Search the plane props for the plane type. */ - for (i = 0; i < props->count_props; i++) { - drmModePropertyPtr p = KMSDRM_drmModeGetProperty(viddata->drm_fd, props->props[i]); - if ((strcmp(p->name, "type") == 0)) { - type = props->prop_values[i]; - } - - KMSDRM_drmModeFreeProperty(p); - } - - switch (type) { - case DRM_PLANE_TYPE_OVERLAY: - plane_type = "overlay"; - break; - - case DRM_PLANE_TYPE_PRIMARY: - plane_type = "primary"; - break; - - case DRM_PLANE_TYPE_CURSOR: - plane_type = "cursor"; - break; - } - - - /* Remember that to present a plane on screen, it has to be - connected to a CRTC so the CRTC scans it, - scales it, etc... and presents it on screen. */ - - /* Now we look for the CRTCs supported by the plane. */ - resources = KMSDRM_drmModeGetResources(viddata->drm_fd); - if (!resources) - return; - - printf("--PLANE ID: %d\nPLANE TYPE: %s\nCRTC READING THIS PLANE: %d\nCRTCS SUPPORTED BY THIS PLANE: ", plane->plane_id, plane_type, plane->crtc_id); - for (i = 0; i < resources->count_crtcs; i++) { - if (plane->possible_crtcs & (1 << i)) { - uint32_t crtc_id = resources->crtcs[i]; - printf ("%d", crtc_id); - break; - } - } - - printf ("\n\n"); -} - -void get_planes_info(_THIS) -{ - drmModePlaneResPtr plane_resources; - uint32_t i; - - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - - plane_resources = KMSDRM_drmModeGetPlaneResources(viddata->drm_fd); - if (!plane_resources) { - printf("drmModeGetPlaneResources failed: %s\n", strerror(errno)); - return; - } - - printf("--Number of planes found: %d-- \n", plane_resources->count_planes); - printf("--Usable CRTC that we have chosen: %d-- \n", dispdata->crtc->crtc->crtc_id); - - /* Iterate on all the available planes. */ - for (i = 0; (i < plane_resources->count_planes); i++) { - - uint32_t plane_id = plane_resources->planes[i]; - - drmModePlanePtr plane = KMSDRM_drmModeGetPlane(viddata->drm_fd, plane_id); - if (!plane) { - printf("drmModeGetPlane(%u) failed: %s\n", plane_id, strerror(errno)); - continue; - } - - /* Print plane info. */ - print_plane_info(_this, plane); - KMSDRM_drmModeFreePlane(plane); - } - - KMSDRM_drmModeFreePlaneResources(plane_resources); -} - -#endif - -/* Get the plane_id of a plane that is of the specified plane type (primary, - overlay, cursor...) and can use the CRTC we have chosen previously. */ -static int get_plane_id(_THIS, uint32_t plane_type) -{ - drmModeRes *resources = NULL; - drmModePlaneResPtr plane_resources = NULL; - uint32_t i, j; - unsigned int crtc_index = 0; - int ret = -EINVAL; - int found = 0; - - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - - resources = KMSDRM_drmModeGetResources(viddata->drm_fd); - - /* Get the crtc_index for the current CRTC. - It's needed to find out if a plane supports the CRTC. */ - for (i = 0; i < resources->count_crtcs; i++) { - if (resources->crtcs[i] == dispdata->crtc->crtc->crtc_id) { - crtc_index = i; - break; - } - } - - plane_resources = KMSDRM_drmModeGetPlaneResources(viddata->drm_fd); - if (!plane_resources) { - return SDL_SetError("drmModeGetPlaneResources failed."); - } - - /* Iterate on all the available planes. */ - for (i = 0; (i < plane_resources->count_planes) && !found; i++) { - - uint32_t plane_id = plane_resources->planes[i]; - - drmModePlanePtr plane = KMSDRM_drmModeGetPlane(viddata->drm_fd, plane_id); - if (!plane) { - continue; - } - - /* See if the current CRTC is available for this plane. */ - if (plane->possible_crtcs & (1 << crtc_index)) { - - drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties( - viddata->drm_fd, plane_id, DRM_MODE_OBJECT_PLANE); - ret = plane_id; - - /* Iterate on the plane props to find the type of the plane, - to see if it's of the type we want. */ - for (j = 0; j < props->count_props; j++) { - - drmModePropertyPtr p = KMSDRM_drmModeGetProperty(viddata->drm_fd, - props->props[j]); - - if ((strcmp(p->name, "type") == 0) && (props->prop_values[j] == plane_type)) { - /* found our plane, use that: */ - found = 1; - } - - KMSDRM_drmModeFreeProperty(p); - } - - KMSDRM_drmModeFreeObjectProperties(props); - } - - KMSDRM_drmModeFreePlane(plane); - } - - KMSDRM_drmModeFreePlaneResources(plane_resources); - KMSDRM_drmModeFreeResources(resources); - - return ret; -} - -/* Setup a plane and it's props. */ -int -setup_plane(_THIS, struct plane **plane, uint32_t plane_type) -{ - uint32_t plane_id; - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - int ret = 0; - - *plane = SDL_calloc(1, sizeof(**plane)); - if (!(*plane)) { - ret = SDL_OutOfMemory(); - goto cleanup; - } - - /* Get plane ID. */ - plane_id = get_plane_id(_this, plane_type); - - if (!plane_id) { - ret = SDL_SetError("Invalid Plane ID"); - goto cleanup; - } - - /* Get the DRM plane itself. */ - (*plane)->plane = KMSDRM_drmModeGetPlane(viddata->drm_fd, plane_id); - - /* Get the DRM plane properties. */ - if ((*plane)->plane) { - unsigned int i; - (*plane)->props = KMSDRM_drmModeObjectGetProperties(viddata->drm_fd, - (*plane)->plane->plane_id, DRM_MODE_OBJECT_PLANE); - (*plane)->props_info = SDL_calloc((*plane)->props->count_props, - sizeof(*(*plane)->props_info)); - - if ( !((*plane)->props_info) ) { - ret = SDL_OutOfMemory(); - goto cleanup; - } - - for (i = 0; i < (*plane)->props->count_props; i++) { - (*plane)->props_info[i] = KMSDRM_drmModeGetProperty(viddata->drm_fd, - (*plane)->props->props[i]); - } - } - -cleanup: - - if (ret) { - if (*plane) { - SDL_free(*plane); - *plane = NULL; - } - } - return ret; -} - -/* Free a plane and it's props. */ -void -free_plane(struct plane **plane) -{ - if (*plane) { - if ((*plane)->plane) { - KMSDRM_drmModeFreePlane((*plane)->plane); - (*plane)->plane = NULL; - } - if ((*plane)->props_info) { - SDL_free((*plane)->props_info); - (*plane)->props_info = NULL; - } - SDL_free(*plane); - *plane = NULL; - } -} - -/**********************************************************************************/ -/* The most important ATOMIC fn of the backend. */ -/* A PLANE reads a BUFFER, and a CRTC reads a PLANE and sends it's contents */ -/* over to a CONNECTOR->ENCODER system (several CONNECTORS can be connected */ -/* to the same PLANE). */ -/* Think of a plane as a "frame" sorrounding a picture, where the "picture" */ -/* is the buffer, and we move the "frame" from a picture to another, */ -/* and the one that has the "frame" is the one sent over to the screen */ -/* via the CONNECTOR->ENCODER system. */ -/* Think of a PLANE as being "in the middle", it's the CENTRAL part */ -/* bewteen the CRTC and the BUFFER that is shown on screen. */ -/* What we do here is connect a PLANE to a CRTC and a BUFFER. */ -/* -ALWAYS set the CRTC_ID and FB_ID attribs of a plane at the same time, */ -/* meaning IN THE SAME atomic request. */ -/* -And NEVER destroy a GBM surface whose buffers are being read by a plane: */ -/* first, move the plane away from those buffers and ONLY THEN destroy the */ -/* buffers and/or the GBM surface containig them. */ -/**********************************************************************************/ -void -drm_atomic_set_plane_props(struct KMSDRM_PlaneInfo *info) -{ - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - - /* Do we have a set of changes already in the making? If not, allocate a new one. */ - if (!dispdata->atomic_req) - dispdata->atomic_req = KMSDRM_drmModeAtomicAlloc(); - - add_plane_property(dispdata->atomic_req, info->plane, "FB_ID", info->fb_id); - add_plane_property(dispdata->atomic_req, info->plane, "CRTC_ID", info->crtc_id); - add_plane_property(dispdata->atomic_req, info->plane, "SRC_W", info->src_w << 16); - add_plane_property(dispdata->atomic_req, info->plane, "SRC_H", info->src_h << 16); - add_plane_property(dispdata->atomic_req, info->plane, "SRC_X", info->src_x); - add_plane_property(dispdata->atomic_req, info->plane, "SRC_Y", info->src_y); - add_plane_property(dispdata->atomic_req, info->plane, "CRTC_W", info->crtc_w); - add_plane_property(dispdata->atomic_req, info->plane, "CRTC_H", info->crtc_h); - add_plane_property(dispdata->atomic_req, info->plane, "CRTC_X", info->crtc_x); - add_plane_property(dispdata->atomic_req, info->plane, "CRTC_Y", info->crtc_y); -} - -int drm_atomic_commit(_THIS, SDL_bool blocking) -{ - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - int ret; - - if (!blocking) - dispdata->atomic_flags |= DRM_MODE_ATOMIC_NONBLOCK; - - /* Never issue a new atomic commit if previous has not yet completed, or it will error. */ - drm_atomic_waitpending(_this); - - ret = KMSDRM_drmModeAtomicCommit(viddata->drm_fd, dispdata->atomic_req, dispdata->atomic_flags, NULL); - if (ret) { - SDL_SetError("Atomic commit failed, returned %d.", ret); - /* Uncomment this for fast-debugging */ -#if 0 - printf("ATOMIC COMMIT FAILED: %s.\n", strerror(errno)); -#endif - goto out; - } - - if (dispdata->kms_in_fence_fd != -1) { - close(dispdata->kms_in_fence_fd); - dispdata->kms_in_fence_fd = -1; - } - -out: - KMSDRM_drmModeAtomicFree(dispdata->atomic_req); - dispdata->atomic_req = NULL; - dispdata->atomic_flags = 0; - - return ret; -} - -void -drm_atomic_waitpending(_THIS) -{ - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - - /* Will return immediately if we have already destroyed the fence, because we NULL-ify it just after. - Also, will return immediately in double-buffer mode, because kms_fence will alsawys be NULL. */ - if (dispdata->kms_fence) { - EGLint status; - - do { - status = _this->egl_data->eglClientWaitSyncKHR(_this->egl_data->egl_display, - dispdata->kms_fence, 0, EGL_FOREVER_KHR); - } while (status != EGL_CONDITION_SATISFIED_KHR); - - _this->egl_data->eglDestroySyncKHR(_this->egl_data->egl_display, dispdata->kms_fence); - dispdata->kms_fence = NULL; - } -} - -/***************************************/ -/* End of Atomic helper functions block*/ -/***************************************/ - static int KMSDRM_Available(void) { +#ifdef __OpenBSD__ + struct utsname nameofsystem; + double releaseversion; +#endif int ret = -ENOENT; +#ifdef __OpenBSD__ + if (!(uname(&nameofsystem) < 0)) { + releaseversion = SDL_atof(nameofsystem.release); + if (releaseversion >= 6.9) { + openbsd69orgreater = SDL_TRUE; + } + } +#endif ret = get_driindex(); if (ret >= 0) return 1; @@ -755,36 +217,6 @@ KMSDRM_DeleteDevice(SDL_VideoDevice * device) SDL_KMSDRM_UnloadSymbols(); } -static int -KMSDRM_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi) -{ - int w, h; - - uint32_t display_mm_width; - uint32_t display_mm_height; - - SDL_DisplayData *dispdata; - - dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); //viddata->devindex); - - - if (!dispdata) { - return SDL_SetError("No available displays"); - } - - display_mm_width = dispdata->connector->connector->mmWidth; - display_mm_height = dispdata->connector->connector->mmHeight; - - w = dispdata->mode.hdisplay; - h = dispdata->mode.vdisplay; - - *hdpi = display_mm_width ? (((float) w) * 25.4f / display_mm_width) : 0.0f; - *vdpi = display_mm_height ? (((float) h) * 25.4f / display_mm_height) : 0.0f; - *ddpi = SDL_ComputeDiagonalDPI(w, h, ((float) display_mm_width) / 25.4f,((float) display_mm_height) / 25.4f); - - return 0; -} - static SDL_VideoDevice * KMSDRM_CreateDevice(int devindex) { @@ -800,7 +232,7 @@ KMSDRM_CreateDevice(int devindex) } if (devindex < 0) { - SDL_SetError("devindex (%d) must be between 0 and 99.", devindex); + SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex); return NULL; } @@ -824,12 +256,11 @@ KMSDRM_CreateDevice(int devindex) device->driverdata = viddata; - /* Setup all functions that can be handled from this backend. */ + /* Setup all functions which we can handle */ device->VideoInit = KMSDRM_VideoInit; device->VideoQuit = KMSDRM_VideoQuit; device->GetDisplayModes = KMSDRM_GetDisplayModes; device->SetDisplayMode = KMSDRM_SetDisplayMode; - device->GetDisplayDPI = KMSDRM_GetDisplayDPI; device->CreateSDLWindow = KMSDRM_CreateWindow; device->CreateSDLWindowFrom = KMSDRM_CreateWindowFrom; device->SetWindowTitle = KMSDRM_SetWindowTitle; @@ -837,17 +268,17 @@ KMSDRM_CreateDevice(int devindex) device->SetWindowPosition = KMSDRM_SetWindowPosition; device->SetWindowSize = KMSDRM_SetWindowSize; device->SetWindowFullscreen = KMSDRM_SetWindowFullscreen; + device->GetWindowGammaRamp = KMSDRM_GetWindowGammaRamp; + device->SetWindowGammaRamp = KMSDRM_SetWindowGammaRamp; device->ShowWindow = KMSDRM_ShowWindow; device->HideWindow = KMSDRM_HideWindow; device->RaiseWindow = KMSDRM_RaiseWindow; device->MaximizeWindow = KMSDRM_MaximizeWindow; device->MinimizeWindow = KMSDRM_MinimizeWindow; device->RestoreWindow = KMSDRM_RestoreWindow; - device->SetWindowGrab = KMSDRM_SetWindowGrab; device->DestroyWindow = KMSDRM_DestroyWindow; device->GetWindowWMInfo = KMSDRM_GetWindowWMInfo; -#if SDL_VIDEO_OPENGL_EGL - device->GL_DefaultProfileConfig = KMSDRM_GLES_DefaultProfileConfig; + device->GL_LoadLibrary = KMSDRM_GLES_LoadLibrary; device->GL_GetProcAddress = KMSDRM_GLES_GetProcAddress; device->GL_UnloadLibrary = KMSDRM_GLES_UnloadLibrary; @@ -857,9 +288,8 @@ KMSDRM_CreateDevice(int devindex) device->GL_GetSwapInterval = KMSDRM_GLES_GetSwapInterval; device->GL_SwapWindow = KMSDRM_GLES_SwapWindow; device->GL_DeleteContext = KMSDRM_GLES_DeleteContext; -#endif - device->PumpEvents = KMSDRM_PumpEvents; - device->free = KMSDRM_DeleteDevice; + device->GL_DefaultProfileConfig = KMSDRM_GLES_DefaultProfileConfig; + #if SDL_VIDEO_VULKAN device->Vulkan_LoadLibrary = KMSDRM_Vulkan_LoadLibrary; device->Vulkan_UnloadLibrary = KMSDRM_Vulkan_UnloadLibrary; @@ -867,6 +297,10 @@ KMSDRM_CreateDevice(int devindex) device->Vulkan_CreateSurface = KMSDRM_Vulkan_CreateSurface; device->Vulkan_GetDrawableSize = KMSDRM_Vulkan_GetDrawableSize; #endif + + device->PumpEvents = KMSDRM_PumpEvents; + device->free = KMSDRM_DeleteDevice; + return device; cleanup: @@ -883,7 +317,6 @@ VideoBootStrap KMSDRM_bootstrap = { KMSDRM_CreateDevice }; - static void KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data) { @@ -901,11 +334,9 @@ KMSDRM_FBInfo * KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo) { SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - unsigned width, height; - uint32_t format, strides[4] = {0}, handles[4] = {0}, offsets[4] = {0}; - const int num_planes = KMSDRM_gbm_bo_get_plane_count(bo); - unsigned int i; + unsigned w,h; int ret; + Uint32 stride, handle; /* Check for an existing framebuffer */ KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo); @@ -914,9 +345,10 @@ KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo) return fb_info; } - /* Create a structure that contains the info about framebuffer - that we need to use it. */ + /* Create a structure that contains enough info to remove the framebuffer + when the backing buffer is destroyed */ fb_info = (KMSDRM_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_FBInfo)); + if (!fb_info) { SDL_OutOfMemory(); return NULL; @@ -924,160 +356,213 @@ KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo) fb_info->drm_fd = viddata->drm_fd; - width = KMSDRM_gbm_bo_get_width(bo); - height = KMSDRM_gbm_bo_get_height(bo); - format = KMSDRM_gbm_bo_get_format(bo); - - for (i = 0; i < num_planes; i++) { - strides[i] = KMSDRM_gbm_bo_get_stride_for_plane(bo, i); - handles[i] = KMSDRM_gbm_bo_get_handle(bo).u32; - offsets[i] = KMSDRM_gbm_bo_get_offset(bo, i); - } - - /* Create framebuffer object for the buffer. - It's VERY important to note that fb_id is what we use to set the FB_ID prop - of a plane when using the ATOMIC interface, and we get the fb_id here. */ - ret = KMSDRM_drmModeAddFB2(viddata->drm_fd, width, height, format, - handles, strides, offsets, &fb_info->fb_id, 0); - + /* Create framebuffer object for the buffer */ + w = KMSDRM_gbm_bo_get_width(bo); + h = KMSDRM_gbm_bo_get_height(bo); + stride = KMSDRM_gbm_bo_get_stride(bo); + handle = KMSDRM_gbm_bo_get_handle(bo).u32; + ret = KMSDRM_drmModeAddFB(viddata->drm_fd, w, h, 24, 32, stride, handle, + &fb_info->fb_id); if (ret) { SDL_free(fb_info); return NULL; } - /* Set the userdata pointer. This pointer is used to store custom data that we need - to access in the future, so we store the fb_id here for later use, because fb_id is - what we need to set the FB_ID property of a plane when using the ATOMIC interface. */ + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, stride %u from BO %p", + fb_info->fb_id, w, h, stride, (void *)bo); + + /* Associate our DRM framebuffer with this buffer object */ KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback); return fb_info; } +static void +KMSDRM_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) +{ + *((SDL_bool *) data) = SDL_FALSE; +} + +SDL_bool +KMSDRM_WaitPageflip(_THIS, SDL_WindowData *windata) { + + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + drmEventContext ev = {0}; + struct pollfd pfd = {0}; + int ret; + + ev.version = DRM_EVENT_CONTEXT_VERSION; + ev.page_flip_handler = KMSDRM_FlipHandler; + + pfd.fd = viddata->drm_fd; + pfd.events = POLLIN; + + /* Stay on the while loop until we get the desired event. + We need the while the loop because we could be in a situation where: + -We get and event on the FD in time, thus not on exiting on return number 1. + -The event is not an error, thus not exiting on return number 2. + -The event is of POLLIN type, but even then, if the event is not a pageflip, + drmHandleEvent() won't unset wait_for_pageflip, so we have to iterate + and go polling again. + + If it wasn't for the while loop, we could erroneously exit the function + without the pageflip event to arrive! + + For example, vblank events hit the FD and they are POLLIN events too (POLLIN + means "there's data to read on the FD"), but they are not the pageflip event + we are waiting for, so the drmEventHandle() doesn't run the flip handler, and + since waiting_for_flip is set on the pageflip handle, it's not set and we stay + on the loop, until we get the event for the pageflip, which is fine. + */ + while (windata->waiting_for_flip) { + + pfd.revents = 0; + + /* poll() waits for events arriving on the FD, and returns < 0 if timeout passes + with no events or a signal occurred before any requested event (-EINTR). + We wait forever (timeout = -1), but even if we DO get an event, we have yet + to see if it's of the required type, then if it's a pageflip, etc */ + ret = poll(&pfd, 1, -1); + + if (ret < 0) { + if (errno == EINTR) { + /* poll() returning < 0 and setting errno = EINTR means there was a signal before + any requested event, so we immediately poll again. */ + continue; + } else { + /* There was another error. Don't pull again or we could get into a busy loop. */ + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error"); + return SDL_FALSE; /* Return number 1. */ + } + } + + if (pfd.revents & (POLLHUP | POLLERR)) { + /* An event arrived on the FD in time, but it's an error. */ + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error"); + return SDL_FALSE; /* Return number 2. */ + } + + if (pfd.revents & POLLIN) { + /* There is data to read on the FD! + Is the event a pageflip? We know it is a pageflip if it matches the + event we are passing in &ev. If it does, drmHandleEvent() will unset + windata->waiting_for_flip and we will get out of the "while" loop. + If it's not, we keep iterating on the loop. */ + KMSDRM_drmHandleEvent(viddata->drm_fd, &ev); + } + + /* If we got to this point in the loop, we may iterate or exit the loop: + -A legit (non-error) event arrived, and it was a POLLING event, and it was consumed + by drmHandleEvent(). + -If it was a PAGEFLIP event, waiting_for_flip will be unset by drmHandleEvent() + and we will exit the loop. + -If it wasn't a PAGEFLIP, drmHandleEvent() won't unset waiting_for_flip, so we + iterare back to polling. + -A legit (non-error) event arrived, but it's not a POLLIN event, so it hasn't to be + consumed by drmHandleEvent(), so waiting_for_flip isn't set and we iterate back + to polling. */ + + } + + return SDL_TRUE; +} + +/* Given w, h and refresh rate, returns the closest DRM video mode + available on the DRM connector of the display. + We use the SDL mode list (which we filled in KMSDRM_GetDisplayModes) + because it's ordered, while the list on the connector is mostly random.*/ +static drmModeModeInfo* +KMSDRM_GetClosestDisplayMode(SDL_VideoDisplay * display, +uint32_t width, uint32_t height, uint32_t refresh_rate){ + + SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata; + drmModeConnector *connector = dispdata->connector; + + SDL_DisplayMode target, closest; + drmModeModeInfo *drm_mode; + + target.w = width; + target.h = height; + target.format = 0; /* Will use the default mode format. */ + target.refresh_rate = refresh_rate; + target.driverdata = 0; /* Initialize to 0 */ + + if (!SDL_GetClosestDisplayMode(SDL_atoi(display->name), &target, &closest)) { + return NULL; + } else { + SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)closest.driverdata; + drm_mode = &connector->modes[modedata->mode_index]; + return drm_mode; + } +} + /*****************************************************************************/ /* SDL Video and Display initialization/handling functions */ /* _this is a SDL_VideoDevice * */ /*****************************************************************************/ -/* Deinitializes the dispdata members needed for KMSDRM operation that are - inoffeensive for VK compatibility. */ -void KMSDRM_DisplayDataDeinit (_THIS, SDL_DisplayData *dispdata) { - /* Free connector */ - if (dispdata && dispdata->connector) { - if (dispdata->connector->connector) { - KMSDRM_drmModeFreeConnector(dispdata->connector->connector); - dispdata->connector->connector = NULL; - } - if (dispdata->connector->props_info) { - SDL_free(dispdata->connector->props_info); - dispdata->connector->props_info = NULL; - } - SDL_free(dispdata->connector); - dispdata->connector = NULL; - } +/* Deinitializes the driverdata of the SDL Displays in the SDL display list. */ +static void +KMSDRM_DeinitDisplays (_THIS) { - /* Free CRTC */ - if (dispdata && dispdata->crtc) { - if (dispdata->crtc->crtc) { - KMSDRM_drmModeFreeCrtc(dispdata->crtc->crtc); - dispdata->crtc->crtc = NULL; + SDL_DisplayData *dispdata; + int num_displays, i; + + num_displays = SDL_GetNumVideoDisplays(); + + /* Iterate on the SDL Display list. */ + for (i = 0; i < num_displays; i++) { + + /* Get the driverdata for this display */ + dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(i); + + /* Free connector */ + if (dispdata && dispdata->connector) { + KMSDRM_drmModeFreeConnector(dispdata->connector); + dispdata->connector = NULL; } - if (dispdata->crtc->props_info) { - SDL_free(dispdata->crtc->props_info); - dispdata->crtc->props_info = NULL; + + /* Free CRTC */ + if (dispdata && dispdata->crtc) { + KMSDRM_drmModeFreeCrtc(dispdata->crtc); + dispdata->crtc = NULL; } - SDL_free(dispdata->crtc); - dispdata->crtc = NULL; } } -/* Initializes the dispdata members needed for KMSDRM operation that are - inoffeensive for VK compatibility, except we must leave the drm_fd - closed when we get to the end of this function. - This is to be called early, in VideoInit(), because it gets us - the videomode information, which SDL needs immediately after VideoInit(). */ -int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) { +/* Gets a DRM connector, builds an SDL_Display with it, and adds it to the + list of SDL Displays in _this->displays[] */ +static void +KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources) { + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - - drmModeRes *resources = NULL; + SDL_DisplayData *dispdata = NULL; + SDL_VideoDisplay display = {0}; + SDL_DisplayModeData *modedata = NULL; drmModeEncoder *encoder = NULL; - drmModeConnector *connector = NULL; drmModeCrtc *crtc = NULL; - - char devname[32]; + int mode_index; + int i, j; int ret = 0; - unsigned i,j; - dispdata->atomic_flags = 0; - dispdata->atomic_req = NULL; - dispdata->kms_fence = NULL; - dispdata->gpu_fence = NULL; - dispdata->kms_out_fence_fd = -1; - dispdata->modeset_pending = SDL_FALSE; - dispdata->gbm_init = SDL_FALSE; - - dispdata->display_plane = NULL; - dispdata->cursor_plane = NULL; + /* Reserve memory for the new display's driverdata. */ + dispdata = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData)); + if (!dispdata) { + ret = SDL_OutOfMemory(); + goto cleanup; + } + /* Initialize some of the members of the new display's driverdata + to sane values. */ dispdata->cursor_bo = NULL; + dispdata->cursor_bo_drm_fd = -1; - /* Open /dev/dri/cardNN */ - SDL_snprintf(viddata->devpath, sizeof(viddata->devpath), "/dev/dri/card%d", viddata->devindex); - - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opening device %s", devname); - viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC); - - if (viddata->drm_fd < 0) { - ret = SDL_SetError("Could not open %s", devname); - goto cleanup; - } - - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", viddata->drm_fd); - - /********************************************/ - /* Block for enabling ATOMIC compatibility. */ - /********************************************/ - - /* Set ATOMIC & UNIVERSAL PLANES compatibility */ - ret = set_client_caps(viddata->drm_fd); - if (ret) { - goto cleanup; - } - - /*******************************************/ - /* Block for getting the ATOMIC resources. */ - /*******************************************/ - - /* Get all of the available connectors / devices / crtcs */ - resources = KMSDRM_drmModeGetResources(viddata->drm_fd); - if (!resources) { - ret = SDL_SetError("drmModeGetResources(%d) failed", viddata->drm_fd); - goto cleanup; - } - - /* Iterate on the available connectors to find a connected connector. */ - for (i = 0; i < resources->count_connectors; i++) { - drmModeConnector *conn = KMSDRM_drmModeGetConnector(viddata->drm_fd, - resources->connectors[i]); - - if (!conn) { - continue; - } - - if (conn->connection == DRM_MODE_CONNECTED && conn->count_modes) { - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.", - conn->connector_id, conn->count_modes); - connector = conn; - - break; - } - - KMSDRM_drmModeFreeConnector(conn); - } - - if (!connector) { - ret = SDL_SetError("No currently active connector found."); - goto cleanup; - } + /* Since we create and show the default cursor on KMSDRM_InitMouse(), + and we call KMSDRM_InitMouse() when we create a window, we have to know + if the display used by the window already has a default cursor or not. + If we don't, new default cursors would stack up on mouse->cursors and SDL + would have to hide and delete them at quit, not to mention the memory leak... */ + dispdata->default_cursor_init = SDL_FALSE; /* Try to find the connector's current encoder */ for (i = 0; i < resources->count_encoders; i++) { @@ -1088,7 +573,6 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) { } if (encoder->encoder_id == connector->encoder_id) { - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id); break; } @@ -1099,10 +583,11 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) { if (!encoder) { /* No encoder was connected, find the first supported one */ for (i = 0; i < resources->count_encoders; i++) { - encoder = KMSDRM_drmModeGetEncoder(viddata->drm_fd, resources->encoders[i]); + encoder = KMSDRM_drmModeGetEncoder(viddata->drm_fd, + resources->encoders[i]); if (!encoder) { - continue; + continue; } for (j = 0; j < connector->count_encoders; j++) { @@ -1112,7 +597,7 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) { } if (j != connector->count_encoders) { - break; + break; } KMSDRM_drmModeFreeEncoder(encoder); @@ -1121,12 +606,10 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) { } if (!encoder) { - ret = SDL_SetError("No connected encoder found."); + ret = SDL_SetError("No connected encoder found for connector."); goto cleanup; } - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id); - /* Try to find a CRTC connected to this encoder */ crtc = KMSDRM_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id); @@ -1143,112 +626,186 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) { } if (!crtc) { - ret = SDL_SetError("No CRTC found."); + ret = SDL_SetError("No CRTC found for connector."); goto cleanup; } - /* Figure out the default mode to be set. */ - dispdata->mode = crtc->mode; + /* Find the index of the mode attached to this CRTC */ + mode_index = -1; - /* Find the connector's preferred mode, to be used in case the current mode - is not valid, or if restoring the current mode fails. - We can always count on the preferred mode! */ for (i = 0; i < connector->count_modes; i++) { - if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) { - dispdata->preferred_mode = connector->modes[i]; + drmModeModeInfo *mode = &connector->modes[i]; + + if (!SDL_memcmp(mode, &crtc->mode, sizeof(crtc->mode))) { + mode_index = i; + break; } } - /* If the current CRTC's mode isn't valid, select the preferred - mode of the connector. */ - if (crtc->mode_valid == 0) { - dispdata->mode = dispdata->preferred_mode; + if (mode_index == -1) { + ret = SDL_SetError("Failed to find index of mode attached to the CRTC."); + goto cleanup; } + /*********************************************/ + /* Create an SDL Display for this connector. */ + /*********************************************/ + + /*********************************************/ + /* Part 1: setup the SDL_Display driverdata. */ + /*********************************************/ + + /* Get the mode currently setup for this display, + which is the mode currently setup on the CRTC + we found for the active connector. */ + dispdata->mode = crtc->mode; + dispdata->original_mode = crtc->mode; + dispdata->fullscreen_mode = crtc->mode; + if (dispdata->mode.hdisplay == 0 || dispdata->mode.vdisplay == 0 ) { ret = SDL_SetError("Couldn't get a valid connector videomode."); goto cleanup; } - /* Get CRTC properties */ - dispdata->crtc->props = KMSDRM_drmModeObjectGetProperties(viddata->drm_fd, - crtc->crtc_id, DRM_MODE_OBJECT_CRTC); + /* Store the connector and crtc for this display. */ + dispdata->connector = connector; + dispdata->crtc = crtc; - dispdata->crtc->props_info = SDL_calloc(dispdata->crtc->props->count_props, - sizeof(*dispdata->crtc->props_info)); + /*****************************************/ + /* Part 2: setup the SDL_Display itself. */ + /*****************************************/ - if (!dispdata->crtc->props_info) { + /* Setup the display. + There's no problem with it being still incomplete. */ + modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData)); + + if (!modedata) { ret = SDL_OutOfMemory(); goto cleanup; } - for (i = 0; i < dispdata->crtc->props->count_props; i++) { - dispdata->crtc->props_info[i] = KMSDRM_drmModeGetProperty(viddata->drm_fd, - dispdata->crtc->props->props[i]); - } + modedata->mode_index = mode_index; - /* Get connector properties */ - dispdata->connector->props = KMSDRM_drmModeObjectGetProperties(viddata->drm_fd, - connector->connector_id, DRM_MODE_OBJECT_CONNECTOR); + display.driverdata = dispdata; + display.desktop_mode.w = dispdata->mode.hdisplay; + display.desktop_mode.h = dispdata->mode.vdisplay; + display.desktop_mode.refresh_rate = dispdata->mode.vrefresh; + display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888; + display.desktop_mode.driverdata = modedata; + display.current_mode = display.desktop_mode; - dispdata->connector->props_info = SDL_calloc(dispdata->connector->props->count_props, - sizeof(*dispdata->connector->props_info)); - - if (!dispdata->connector->props_info) { - ret = SDL_OutOfMemory(); - goto cleanup; - } - - for (i = 0; i < dispdata->connector->props->count_props; i++) { - dispdata->connector->props_info[i] = KMSDRM_drmModeGetProperty(viddata->drm_fd, - dispdata->connector->props->props[i]); - } - - /* Store the connector and crtc for future use. This is all we keep from this function, - and these are just structs, inoffensive to VK. */ - dispdata->connector->connector = connector; - dispdata->crtc->crtc = crtc; - - /***********************************/ - /* Block fpr Vulkan compatibility. */ - /***********************************/ - - /* THIS IS FOR VULKAN! Leave the FD closed, so VK can work. - Will reopen this in CreateWindow, but only if requested a non-VK window. */ - KMSDRM_drmSetClientCap(viddata->drm_fd, DRM_CLIENT_CAP_ATOMIC, 0); - KMSDRM_drmSetClientCap(viddata->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 0); - close (viddata->drm_fd); - viddata->drm_fd = -1; + /* Add the display to the list of SDL displays. */ + SDL_AddVideoDisplay(&display, SDL_FALSE); cleanup: if (encoder) KMSDRM_drmModeFreeEncoder(encoder); + if (ret) { + /* Error (complete) cleanup */ + if (dispdata) { + if (dispdata->connector) { + KMSDRM_drmModeFreeConnector(dispdata->connector); + dispdata->connector = NULL; + } + if (dispdata->crtc) { + KMSDRM_drmModeFreeCrtc(dispdata->crtc); + dispdata->crtc = NULL; + } + SDL_free(dispdata); + } + } +} + +/* Initializes the list of SDL displays: we build a new display for each + connecter connector we find. + Inoffeensive for VK compatibility, except we must leave the drm_fd + closed when we get to the end of this function. + This is to be called early, in VideoInit(), because it gets us + the videomode information, which SDL needs immediately after VideoInit(). */ +static int +KMSDRM_InitDisplays (_THIS) { + + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + drmModeRes *resources = NULL; + + uint64_t async_pageflip = 0; + int ret = 0; + int i; + + /* Open /dev/dri/cardNN (/dev/drmN if on OpenBSD) */ + SDL_snprintf(viddata->devpath, sizeof(viddata->devpath), KMSDRM_DRI_CARDPATHFMT, viddata->devindex); + + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opening device %s", viddata->devpath); + viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC); + + if (viddata->drm_fd < 0) { + ret = SDL_SetError("Could not open %s", viddata->devpath); + goto cleanup; + } + + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", viddata->drm_fd); + + /* Get all of the available connectors / devices / crtcs */ + resources = KMSDRM_drmModeGetResources(viddata->drm_fd); + if (!resources) { + ret = SDL_SetError("drmModeGetResources(%d) failed", viddata->drm_fd); + goto cleanup; + } + + /* Iterate on the available connectors. For every connected connector, + we create an SDL_Display and add it to the list of SDL Displays. */ + for (i = 0; i < resources->count_connectors; i++) { + drmModeConnector *connector = KMSDRM_drmModeGetConnector(viddata->drm_fd, + resources->connectors[i]); + + if (!connector) { + continue; + } + + if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes) { + /* If it's a connected connector with available videomodes, try to add + an SDL Display representing it. KMSDRM_AddDisplay() is purposely void, + so if it fails (no encoder for connector, no valid video mode for + connector etc...) we can keep looking for connected connectors. */ + KMSDRM_AddDisplay(_this, connector, resources); + } + else { + /* If it's not, free it now. */ + KMSDRM_drmModeFreeConnector(connector); + } + } + + /* Have we added any SDL displays? */ + if (!SDL_GetNumVideoDisplays()) { + ret = SDL_SetError("No connected displays found."); + goto cleanup; + } + + /* Determine if video hardware supports async pageflips. */ + ret = KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_ASYNC_PAGE_FLIP, &async_pageflip); + if (ret) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not determine async page flip capability."); + } + viddata->async_pageflip_support = async_pageflip ? SDL_TRUE : SDL_FALSE; + + /***********************************/ + /* Block for Vulkan compatibility. */ + /***********************************/ + + /* THIS IS FOR VULKAN! Leave the FD closed, so VK can work. + Will reopen this in CreateWindow, but only if requested a non-VK window. */ + close (viddata->drm_fd); + viddata->drm_fd = -1; + +cleanup: if (resources) KMSDRM_drmModeFreeResources(resources); if (ret) { - /* Error (complete) cleanup */ - if (dispdata->connector->connector) { - KMSDRM_drmModeFreeConnector(dispdata->connector->connector); - dispdata->connector->connector = NULL; - } - if (dispdata->crtc->props_info) { - SDL_free(dispdata->crtc->props_info); - dispdata->crtc->props_info = NULL; - } - if (dispdata->connector->props_info) { - SDL_free(dispdata->connector->props_info); - dispdata->connector->props_info = NULL; - } - if (dispdata->crtc->crtc) { - KMSDRM_drmModeFreeCrtc(dispdata->crtc->crtc); - dispdata->crtc->crtc = NULL; - } if (viddata->drm_fd >= 0) { close(viddata->drm_fd); viddata->drm_fd = -1; } } - return ret; } @@ -1260,7 +817,7 @@ cleanup: These things are incompatible with Vulkan, which accesses the same resources internally so they must be free when trying to build a Vulkan surface. */ -int +static int KMSDRM_GBMInit (_THIS, SDL_DisplayData *dispdata) { SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; @@ -1268,7 +825,9 @@ KMSDRM_GBMInit (_THIS, SDL_DisplayData *dispdata) /* Reopen the FD! */ viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC); - set_client_caps(viddata->drm_fd); + + /* Set the FD we just opened as current DRM master. */ + KMSDRM_drmSetMaster(viddata->drm_fd); /* Create the GBM device. */ viddata->gbm_dev = KMSDRM_gbm_create_device(viddata->drm_fd); @@ -1276,30 +835,17 @@ KMSDRM_GBMInit (_THIS, SDL_DisplayData *dispdata) ret = SDL_SetError("Couldn't create gbm device."); } - /* Setup the display plane. ONLY do this after dispdata has the right - crtc and connector, because these are used in this function. */ - ret = setup_plane(_this, &(dispdata->display_plane), DRM_PLANE_TYPE_PRIMARY); - if (ret) { - ret = SDL_SetError("can't find suitable display plane."); - } - - dispdata->gbm_init = SDL_TRUE; + viddata->gbm_init = SDL_TRUE; return ret; } /* Deinit the Vulkan-incompatible KMSDRM stuff. */ -void +static void KMSDRM_GBMDeinit (_THIS, SDL_DisplayData *dispdata) { SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - /* Free display plane */ - free_plane(&dispdata->display_plane); - - /* Free cursor plane (if still not freed) */ - free_plane(&dispdata->cursor_plane); - /* Destroy GBM device. GBM surface is destroyed by DestroySurfaces(), already called when we get here. */ if (viddata->gbm_dev) { @@ -1313,52 +859,57 @@ KMSDRM_GBMDeinit (_THIS, SDL_DisplayData *dispdata) viddata->drm_fd = -1; } - dispdata->gbm_init = SDL_FALSE; + viddata->gbm_init = SDL_FALSE; } -/* Destroy the window surfaces and buffers. Have the PRIMARY PLANE - disconnected from these buffers before doing so, or have the PRIMARY PLANE - reading the original FB where the TTY lives, before doing this, or CRTC will - be disconnected by the kernel. */ -void +static void KMSDRM_DestroySurfaces(_THIS, SDL_Window *window) { + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - KMSDRM_PlaneInfo plane_info = {0}; + SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + int ret; -#if SDL_VIDEO_OPENGL_EGL - EGLContext egl_context; -#endif + /**********************************************/ + /* Wait for last issued pageflip to complete. */ + /**********************************************/ + /*KMSDRM_WaitPageflip(_this, windata);*/ - /********************************************************************/ - /* BLOCK 1: protect the PRIMARY PLANE before destroying the buffers */ - /* it's using, by making it point to the original CRTC buffer, */ - /* where the TTY console should be. */ - /********************************************************************/ + /***********************************************************************/ + /* Restore the original CRTC configuration: configue the crtc with the */ + /* original video mode and make it point to the original TTY buffer. */ + /***********************************************************************/ - plane_info.plane = dispdata->display_plane; - plane_info.crtc_id = dispdata->crtc->crtc->crtc_id; - plane_info.fb_id = dispdata->crtc->crtc->buffer_id; - plane_info.src_w = dispdata->mode.hdisplay; - plane_info.src_h = dispdata->mode.vdisplay; - plane_info.crtc_w = dispdata->mode.hdisplay; - plane_info.crtc_h = dispdata->mode.vdisplay; + ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd, dispdata->crtc->crtc_id, + dispdata->crtc->buffer_id, 0, 0, &dispdata->connector->connector_id, 1, + &dispdata->original_mode); - drm_atomic_set_plane_props(&plane_info); - - /* Issue blocking atomic commit. */ - if (drm_atomic_commit(_this, SDL_TRUE)) { - SDL_SetError("Failed to issue atomic commit on surfaces destruction."); + /* If we failed to set the original mode, try to set the connector prefered mode. */ + if (ret && (dispdata->crtc->mode_valid == 0)) { + ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd, dispdata->crtc->crtc_id, + dispdata->crtc->buffer_id, 0, 0, &dispdata->connector->connector_id, 1, + &dispdata->original_mode); } - /****************************************************************************/ - /* BLOCK 2: We can finally destroy the window GBM and EGL surfaces, and */ - /* GBM buffers now that the buffers are not being used by the PRIMARY PLANE */ - /* anymore. */ - /****************************************************************************/ + if(ret) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not restore CRTC"); + } + + /***************************/ + /* Destroy the EGL surface */ + /***************************/ + + SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + if (windata->egl_surface != EGL_NO_SURFACE) { + SDL_EGL_DestroySurface(_this, windata->egl_surface); + windata->egl_surface = EGL_NO_SURFACE; + } + + /***************************/ + /* Destroy the GBM buffers */ + /***************************/ - /* Destroy the GBM surface and buffers. */ if (windata->bo) { KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo); windata->bo = NULL; @@ -1369,69 +920,99 @@ KMSDRM_DestroySurfaces(_THIS, SDL_Window *window) windata->next_bo = NULL; } - /***************************************************************************/ - /* Destroy the EGL surface. */ - /* In this eglMakeCurrent() call, we disable the current EGL surface */ - /* because we're going to destroy it, but DON'T disable the EGL context, */ - /* because it won't be enabled again until the programs ask for a pageflip */ - /* so we get to SwapWindow(). */ - /* If we disable the context until then and a program tries to retrieve */ - /* the context version info before calling for a pageflip, the program */ - /* will get wrong info and we will be in trouble. */ - /***************************************************************************/ - -#if SDL_VIDEO_OPENGL_EGL - egl_context = (EGLContext)SDL_GL_GetCurrentContext(); - SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, egl_context); - - if (windata->egl_surface != EGL_NO_SURFACE) { - SDL_EGL_DestroySurface(_this, windata->egl_surface); - windata->egl_surface = EGL_NO_SURFACE; - } -#endif + /***************************/ + /* Destroy the GBM surface */ + /***************************/ if (windata->gs) { KMSDRM_gbm_surface_destroy(windata->gs); windata->gs = NULL; } - } +static void +KMSDRM_GetModeToSet(SDL_Window *window, drmModeModeInfo *out_mode) { + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + + if ((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN) { + *out_mode = dispdata->fullscreen_mode; + } else { + drmModeModeInfo *mode; + + mode = KMSDRM_GetClosestDisplayMode(display, + window->windowed.w, window->windowed.h, 0); + + if (mode) { + *out_mode = *mode; + } else { + *out_mode = dispdata->original_mode; + } + } +} + +static void +KMSDRM_DirtySurfaces(SDL_Window *window) { + SDL_WindowData *windata = (SDL_WindowData *)window->driverdata; + drmModeModeInfo mode; + + /* Can't recreate EGL surfaces right now, need to wait until SwapWindow + so the correct thread-local surface and context state are available */ + windata->egl_surface_dirty = SDL_TRUE; + + /* The app may be waiting for the resize event after calling SetWindowSize + or SetWindowFullscreen, send a fake event for now since the actual + recreation is deferred */ + KMSDRM_GetModeToSet(window, &mode); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode.hdisplay, mode.vdisplay); +} + +/* This determines the size of the fb, which comes from the GBM surface + that we create here. */ int KMSDRM_CreateSurfaces(_THIS, SDL_Window * window) { SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); SDL_WindowData *windata = (SDL_WindowData *)window->driverdata; - SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + uint32_t surface_fmt = GBM_FORMAT_ARGB8888; uint32_t surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; - uint32_t width, height; EGLContext egl_context; int ret = 0; - if (((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) || - ((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN)) { - - width = dispdata->mode.hdisplay; - height = dispdata->mode.vdisplay; - } else { - width = window->w; - height = window->h; + /* If the current window already has surfaces, destroy them before creating other. */ + if (windata->gs) { + KMSDRM_DestroySurfaces(_this, window); } - if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, surface_fmt, surface_flags)) { - SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway."); + if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, + surface_fmt, surface_flags)) { + SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, + "GBM surface format not supported. Trying anyway."); } - windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, width, height, surface_fmt, surface_flags); + /* The KMSDRM backend doesn't always set the mode the higher-level code in + SDL_video.c expects. Hulk-smash the display's current_mode to keep the + mode that's set in sync with what SDL_video.c thinks is set */ + KMSDRM_GetModeToSet(window, &dispdata->mode); + + display->current_mode.w = dispdata->mode.hdisplay; + display->current_mode.h = dispdata->mode.vdisplay; + display->current_mode.refresh_rate = dispdata->mode.vrefresh; + display->current_mode.format = SDL_PIXELFORMAT_ARGB8888; + + windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, + dispdata->mode.hdisplay, dispdata->mode.vdisplay, + surface_fmt, surface_flags); if (!windata->gs) { return SDL_SetError("Could not create GBM surface"); } -#if SDL_VIDEO_OPENGL_EGL /* We can't get the EGL context yet because SDL_CreateRenderer has not been called, but we need an EGL surface NOW, or GL won't be able to render into any surface and we won't see the first frame. */ @@ -1448,7 +1029,10 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window) egl_context = (EGLContext)SDL_GL_GetCurrentContext(); ret = SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context); -#endif + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, + dispdata->mode.hdisplay, dispdata->mode.vdisplay); + + windata->egl_surface_dirty = SDL_FALSE; cleanup: @@ -1463,12 +1047,125 @@ cleanup: return ret; } +int +KMSDRM_VideoInit(_THIS) +{ + int ret = 0; + + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()"); + + viddata->video_init = SDL_FALSE; + viddata->gbm_init = SDL_FALSE; + + /* Get KMSDRM resources info and store what we need. Getting and storing + this info isn't a problem for VK compatibility. + For VK-incompatible initializations we have KMSDRM_GBMInit(), which is + called on window creation, and only when we know it's not a VK window. */ + if (KMSDRM_InitDisplays(_this)) { + ret = SDL_SetError("error getting KMSDRM displays information"); + } + +#ifdef SDL_INPUT_LINUXEV + SDL_EVDEV_Init(); +#elif defined(SDL_INPUT_WSCONS) + SDL_WSCONS_Init(); +#endif + + viddata->video_init = SDL_TRUE; + + return ret; +} + +/* The driverdata pointers, like dispdata, viddata, windata, etc... + are freed by SDL internals, so not our job. */ +void +KMSDRM_VideoQuit(_THIS) +{ + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + + KMSDRM_DeinitDisplays(_this); + +#ifdef SDL_INPUT_LINUXEV + SDL_EVDEV_Quit(); +#elif defined(SDL_INPUT_WSCONS) + SDL_WSCONS_Quit(); +#endif + + /* Clear out the window list */ + SDL_free(viddata->windows); + viddata->windows = NULL; + viddata->max_windows = 0; + viddata->num_windows = 0; + viddata->video_init = SDL_FALSE; +} + +/* Read modes from the connector modes, and store them in display->display_modes. */ +void +KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +{ + SDL_DisplayData *dispdata = display->driverdata; + drmModeConnector *conn = dispdata->connector; + SDL_DisplayMode mode; + int i; + + for (i = 0; i < conn->count_modes; i++) { + SDL_DisplayModeData *modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData)); + + if (modedata) { + modedata->mode_index = i; + } + + mode.w = conn->modes[i].hdisplay; + mode.h = conn->modes[i].vdisplay; + mode.refresh_rate = conn->modes[i].vrefresh; + mode.format = SDL_PIXELFORMAT_ARGB8888; + mode.driverdata = modedata; + + if (!SDL_AddDisplayMode(display, &mode)) { + SDL_free(modedata); + } + } +} + +int +KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + /* Set the dispdata->mode to the new mode and leave actual modesetting + pending to be done on SwapWindow() via drmModeSetCrtc() */ + + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; + drmModeConnector *conn = dispdata->connector; + int i; + + /* Don't do anything if we are in Vulkan mode. */ + if (viddata->vulkan_mode) { + return 0; + } + + if (!modedata) { + return SDL_SetError("Mode doesn't have an associated index"); + } + + /* Take note of the new mode to be set, and leave the CRTC modeset pending + so it's done in SwapWindow. */ + dispdata->fullscreen_mode = conn->modes[modedata->mode_index]; + + for (i = 0; i < viddata->num_windows; i++) { + KMSDRM_DirtySurfaces(viddata->windows[i]); + } + + return 0; +} + void KMSDRM_DestroyWindow(_THIS, SDL_Window *window) { SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - SDL_VideoData *viddata = windata->viddata; + SDL_VideoData *viddata; SDL_bool is_vulkan = window->flags & SDL_WINDOW_VULKAN; /* Is this a VK window? */ unsigned int i, j; @@ -1476,16 +1173,38 @@ KMSDRM_DestroyWindow(_THIS, SDL_Window *window) return; } - if (!is_vulkan) { + viddata = windata->viddata; + + if ( !is_vulkan && viddata->gbm_init) { + + /* Destroy cursor GBM BO of the display of this window. */ + KMSDRM_DestroyCursorBO(_this, SDL_GetDisplayForWindow(window)); + + /* Destroy GBM surface and buffers. */ KMSDRM_DestroySurfaces(_this, window); -#if SDL_VIDEO_OPENGL_EGL - if (_this->egl_data) { - SDL_EGL_UnloadLibrary(_this); - } -#endif - if (dispdata->gbm_init) { - KMSDRM_DeinitMouse(_this); - KMSDRM_GBMDeinit(_this, dispdata); + + /* Unload library and deinit GBM, but only if this is the last window. + Note that this is the right comparision because num_windows could be 1 + if there is a complete window, or 0 if we got here from SDL_CreateWindow() + because KMSDRM_CreateWindow() returned an error so the window wasn't + added to the windows list. */ + if (viddata->num_windows <= 1) { + + /* Unload EGL/GL library and free egl_data. */ + if (_this->egl_data) { + SDL_EGL_UnloadLibrary(_this); + _this->gl_config.driver_loaded = 0; + } + + /* Free display plane, and destroy GBM device. */ + KMSDRM_GBMDeinit(_this, dispdata); + } + + } else { + + /* If we were in Vulkan mode, get out of it. */ + if (viddata->vulkan_mode) { + viddata->vulkan_mode = SDL_FALSE; } } @@ -1508,232 +1227,15 @@ KMSDRM_DestroyWindow(_THIS, SDL_Window *window) /*********************************************************************/ /* Free the window driverdata. Bye bye, surface and buffer pointers! */ /*********************************************************************/ + SDL_free(window->driverdata); window->driverdata = NULL; - SDL_free(windata); -} - -/*****************************************************************************/ -/* Reconfigure the window scaling parameters and re-construct it's surfaces, */ -/* without destroying the window itself. */ -/* To be used by SetWindowSize() and SetWindowFullscreen(). */ -/*****************************************************************************/ -static int -KMSDRM_ReconfigureWindow( _THIS, SDL_Window * window) { - SDL_WindowData *windata = window->driverdata; - SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - SDL_bool is_vulkan = window->flags & SDL_WINDOW_VULKAN; /* Is this a VK window? */ - float ratio; - - if (((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) || - ((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN)) { - - windata->src_w = dispdata->mode.hdisplay; - windata->src_h = dispdata->mode.vdisplay; - windata->output_w = dispdata->mode.hdisplay; - windata->output_h = dispdata->mode.vdisplay; - windata->output_x = 0; - - } else { - - /* Normal non-fullscreen windows are scaled using the CRTC, - so get output (CRTC) size and position, for AR correction. */ - ratio = (float)window->w / (float)window->h; - windata->src_w = window->w; - windata->src_h = window->h; - windata->output_w = dispdata->mode.vdisplay * ratio; - windata->output_h = dispdata->mode.vdisplay; - windata->output_x = (dispdata->mode.hdisplay - windata->output_w) / 2; - - } - - if (!is_vulkan) { - if (KMSDRM_CreateSurfaces(_this, window)) { - return -1; - } - } - return 0; -} - -int -KMSDRM_VideoInit(_THIS) -{ - int ret = 0; - - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - SDL_DisplayData *dispdata = NULL; - SDL_VideoDisplay display = {0}; - - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()"); - - viddata->video_init = SDL_FALSE; - - dispdata = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData)); - if (!dispdata) { - return SDL_OutOfMemory(); - } - - /* Alloc memory for these. */ - dispdata->display_plane = SDL_calloc(1, sizeof(*dispdata->display_plane)); - dispdata->crtc = SDL_calloc(1, sizeof(*dispdata->crtc)); - dispdata->connector = SDL_calloc(1, sizeof(*dispdata->connector)); - if (!(dispdata->display_plane) || !(dispdata->crtc) || !(dispdata->connector)) { - ret = SDL_OutOfMemory(); - goto cleanup; - } - - /* Get KMSDRM resources info and store what we need. Getting and storing - this info isn't a problem for VK compatibility. - For VK-incompatible initializations we have KMSDRM_GBMInit(), which is - called on window creation, and only when we know it's not a VK window. */ - if (KMSDRM_DisplayDataInit(_this, dispdata)) { - ret = SDL_SetError("error getting KMS/DRM information"); - goto cleanup; - } - - /* Setup the single display that's available. - There's no problem with it being still incomplete. */ - display.driverdata = dispdata; - display.desktop_mode.w = dispdata->mode.hdisplay; - display.desktop_mode.h = dispdata->mode.vdisplay; - display.desktop_mode.refresh_rate = dispdata->mode.vrefresh; - display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888; - display.current_mode = display.desktop_mode; - - /* Add the display only when it's ready, */ - SDL_AddVideoDisplay(&display, SDL_FALSE); - - /* Use this if you ever need to see info on all available planes. */ -#if 0 - get_planes_info(_this); -#endif - -#ifdef SDL_INPUT_LINUXEV - SDL_EVDEV_Init(); -#endif - - viddata->video_init = SDL_TRUE; - -cleanup: - - if (ret) { - /* Error (complete) cleanup */ - if (dispdata->display_plane) { - SDL_free(dispdata->display_plane); - } - if (dispdata->crtc) { - SDL_free(dispdata->crtc); - } - if (dispdata->connector) { - SDL_free(dispdata->connector); - } - - SDL_free(dispdata); - } - - return ret; -} - -/* The driverdata pointers, like dispdata, viddata, windata, etc... - are freed by SDL internals, so not our job. */ -void -KMSDRM_VideoQuit(_THIS) -{ - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - - KMSDRM_DisplayDataDeinit(_this, dispdata); - -#ifdef SDL_INPUT_LINUXEV - SDL_EVDEV_Quit(); -#endif - - /* Clear out the window list */ - SDL_free(viddata->windows); - viddata->windows = NULL; - viddata->max_windows = 0; - viddata->num_windows = 0; - viddata->video_init = SDL_FALSE; -} - -#if 0 -void -KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay * display) -{ - /* Only one display mode available: the current one */ - SDL_AddDisplayMode(display, &display->current_mode); -} -#endif - -/* We only change the video mode for FULLSCREEN windows - that are not FULLSCREEN_DESKTOP. - Normal non-fullscreen windows are scaled using the CRTC. */ -void -KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay * display) -{ - SDL_DisplayData *dispdata = display->driverdata; - drmModeConnector *conn = dispdata->connector->connector; - SDL_DisplayMode mode; - int i; - - for (i = 0; i < conn->count_modes; i++) { - SDL_DisplayModeData *modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData)); - - if (!modedata) { - SDL_OutOfMemory(); - return; - } - - modedata->mode_index = i; - - mode.w = conn->modes[i].hdisplay; - mode.h = conn->modes[i].vdisplay; - mode.refresh_rate = conn->modes[i].vrefresh; - mode.format = SDL_PIXELFORMAT_ARGB8888; - mode.driverdata = modedata; - - if (!SDL_AddDisplayMode(display, &mode)) { - SDL_free(modedata); - } - } -} - -int -KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) -{ - /* Set the dispdata->mode to the new mode and leave actual modesetting - pending to be done on SwapWindow(), to be included on next atomic - commit changeset. */ - - SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; - SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; - SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; - drmModeConnector *conn = dispdata->connector->connector; - int i; - - if (!modedata) { - return SDL_SetError("Mode doesn't have an associated index"); - } - - /* Take note of the new mode. It will be used in SwapWindow to - set the props needed for mode setting. */ - dispdata->mode = conn->modes[modedata->mode_index]; - - dispdata->modeset_pending = SDL_TRUE; - - for (i = 0; i < viddata->num_windows; i++) { - SDL_Window *window = viddata->windows[i]; - - if (KMSDRM_CreateSurfaces(_this, window)) { - return -1; - } - - /* Tell app about the window resize */ - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode->w, mode->h); - } - - return 0; } +/**********************************************************************/ +/* We simply IGNORE if it's a fullscreen window, window->flags don't */ +/* reflect it: if it's fullscreen, KMSDRM_SetWindwoFullscreen() will */ +/* be called by SDL later, and we can manage it there. */ +/**********************************************************************/ int KMSDRM_CreateWindow(_THIS, SDL_Window * window) { @@ -1742,81 +1244,93 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window) SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *dispdata = display->driverdata; SDL_bool is_vulkan = window->flags & SDL_WINDOW_VULKAN; /* Is this a VK window? */ + SDL_bool vulkan_mode = viddata->vulkan_mode; /* Do we have any Vulkan windows? */ NativeDisplayType egl_display; - float ratio; + drmModeModeInfo *mode; int ret = 0; - if ( !(dispdata->gbm_init) && (!is_vulkan)) { - /* Reopen FD, create gbm dev, setup display plane, etc,. - but only when we come here for the first time, - and only if it's not a VK window. */ - if ((ret = KMSDRM_GBMInit(_this, dispdata))) { - goto cleanup; - } - -#if SDL_VIDEO_OPENGL_EGL - /* Manually load the EGL library. KMSDRM_EGL_LoadLibrary() has already - been called by SDL_CreateWindow() but we don't do anything there, - precisely to be able to load it here. - If we let SDL_CreateWindow() load the lib, it will be loaded - before we call KMSDRM_GBMInit(), causing GLES programs to fail. */ - if (!_this->egl_data) { - egl_display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm_dev; - if ((ret = SDL_EGL_LoadLibrary(_this, NULL, egl_display, EGL_PLATFORM_GBM_MESA))) { - goto cleanup; - } - } -#endif - - /* Can't init mouse stuff sooner because cursor plane is not ready. */ - KMSDRM_InitMouse(_this); - - /* Since we take cursor buffer way from the cursor plane and - destroy the cursor GBM BO when we destroy a window, we must - also manually re-show the cursor on screen, if necessary, - when we create a window. */ - KMSDRM_InitCursor(); - } - /* Allocate window internal data */ windata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); if (!windata) { - ret = SDL_OutOfMemory(); - goto cleanup; + return(SDL_OutOfMemory()); } - if (((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) || - ((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN)) - { - windata->src_w = dispdata->mode.hdisplay; - windata->src_h = dispdata->mode.vdisplay; - windata->output_w = dispdata->mode.hdisplay; - windata->output_h = dispdata->mode.vdisplay; - windata->output_x = 0; - } else { - /* Normal non-fullscreen windows are scaled using the CRTC, - so get output (CRTC) size and position, for AR correction. */ - ratio = (float)window->w / (float)window->h; - windata->src_w = window->w; - windata->src_h = window->h; - windata->output_w = dispdata->mode.vdisplay * ratio; - windata->output_h = dispdata->mode.vdisplay; - windata->output_x = (dispdata->mode.hdisplay - windata->output_w) / 2; - } - - /* Don't force fullscreen on all windows: it confuses programs that try - to set a window fullscreen after creating it as non-fullscreen (sm64ex) */ - // window->flags |= SDL_WINDOW_FULLSCREEN; - /* Setup driver data for this window */ windata->viddata = viddata; window->driverdata = windata; - if (!is_vulkan) { - if ((ret = KMSDRM_CreateSurfaces(_this, window))) { - goto cleanup; + if (!is_vulkan && !vulkan_mode) { /* NON-Vulkan block. */ + + /* Maybe you didn't ask for an OPENGL window, but that's what you will get. + See following comments on why. */ + window->flags |= SDL_WINDOW_OPENGL; + + if (!(viddata->gbm_init)) { + + /* After SDL_CreateWindow, most SDL2 programs will do SDL_CreateRenderer(), + which will in turn call GL_CreateRenderer() or GLES2_CreateRenderer(). + In order for the GL_CreateRenderer() or GLES2_CreateRenderer() call to + succeed without an unnecessary window re-creation, we must: + -Mark the window as being OPENGL + -Load the GL library (which can't be done until the GBM device has been + created, so we have to do it here instead of doing it on VideoInit()) + and mark it as loaded by setting gl_config.driver_loaded to 1. + So if you ever see KMSDRM_CreateWindow() to be called two times in tests, + don't be shy to debug GL_CreateRenderer() or GLES2_CreateRenderer() + to find out why! + */ + + /* Reopen FD, create gbm dev, setup display plane, etc,. + but only when we come here for the first time, + and only if it's not a VK window. */ + if ((ret = KMSDRM_GBMInit(_this, dispdata))) { + return (SDL_SetError("Can't init GBM on window creation.")); + } } - } + + /* Manually load the GL library. KMSDRM_EGL_LoadLibrary() has already + been called by SDL_CreateWindow() but we don't do anything there, + out KMSDRM_EGL_LoadLibrary() is a dummy precisely to be able to load it here. + If we let SDL_CreateWindow() load the lib, it would be loaded + before we call KMSDRM_GBMInit(), causing all GLES programs to fail. */ + if (!_this->egl_data) { + egl_display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm_dev; + if (SDL_EGL_LoadLibrary(_this, NULL, egl_display, EGL_PLATFORM_GBM_MESA)) { + return (SDL_SetError("Can't load EGL/GL library on window creation.")); + } + + _this->gl_config.driver_loaded = 1; + + } + + /* Create the cursor BO for the display of this window, + now that we know this is not a VK window. */ + KMSDRM_CreateCursorBO(display); + + /* Create and set the default cursor for the display + of this window, now that we know this is not a VK window. */ + KMSDRM_InitMouse(_this, display); + + /* The FULLSCREEN flags are cut out from window->flags at this point, + so we can't know if a window is fullscreen or not, hence all windows + are considered "windowed" at this point of their life. + If a window is fullscreen, SDL internals will call + KMSDRM_SetWindowFullscreen() to reconfigure it if necessary. */ + mode = KMSDRM_GetClosestDisplayMode(display, + window->windowed.w, window->windowed.h, 0 ); + + if (mode) { + dispdata->fullscreen_mode = *mode; + } else { + dispdata->fullscreen_mode = dispdata->original_mode; + } + + /* Create the window surfaces with the size we have just chosen. + Needs the window diverdata in place. */ + if ((ret = KMSDRM_CreateSurfaces(_this, window))) { + return (SDL_SetError("Can't window GBM/EGL surfaces on window creation.")); + } + } /* NON-Vulkan block ends. */ /* Add window to the internal list of tracked windows. Note, while it may seem odd to support multiple fullscreen windows, some apps create an @@ -1828,35 +1342,65 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window) viddata->max_windows = new_max_windows; if (!viddata->windows) { - ret = SDL_OutOfMemory(); - goto cleanup; + return (SDL_OutOfMemory()); } } viddata->windows[viddata->num_windows++] = window; - /* Focus on the newly created window */ + /* If we have just created a Vulkan window, establish that we are in Vulkan mode now. */ + viddata->vulkan_mode = is_vulkan; + + /* Focus on the newly created window. + SDL_SetMouseFocus() also takes care of calling KMSDRM_ShowCursor() if necessary. */ SDL_SetMouseFocus(window); SDL_SetKeyboardFocus(window); - /***********************************************************/ - /* Tell SDL that the mouse has entered the window using an */ - /* artificial event: we have no windowing system to tell */ - /* SDL that it has happened. This makes SDL set the */ - /* SDL_WINDOW_MOUSE_FOCUS on this window, thus fixing */ - /* Scummvm sticky-on-sides software cursor. */ - /***********************************************************/ - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_ENTER, 0, 0); + /* Tell the app that the window has moved to top-left. */ + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, 0, 0); -cleanup: - - if (ret) { - /* Allocated windata will be freed in KMSDRM_DestroyWindow */ - KMSDRM_DestroyWindow(_this, window); - } + /* Allocated windata will be freed in KMSDRM_DestroyWindow, + and KMSDRM_DestroyWindow() will be called by SDL_CreateWindow() + if we return error on any of the previous returns of the function. */ return ret; } +int +KMSDRM_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) +{ + SDL_WindowData *windata = (SDL_WindowData*)window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData*)windata->viddata; + SDL_VideoDisplay *disp = SDL_GetDisplayForWindow(window); + SDL_DisplayData* dispdata = (SDL_DisplayData*)disp->driverdata; + if (KMSDRM_drmModeCrtcGetGamma(viddata->drm_fd, dispdata->crtc->crtc_id, 256, &ramp[0*256], &ramp[1*256], &ramp[2*256]) == -1) + { + return SDL_SetError("Failed to get gamma ramp"); + } + return 0; +} + +int +KMSDRM_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) +{ + SDL_WindowData *windata = (SDL_WindowData*)window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData*)windata->viddata; + SDL_VideoDisplay *disp = SDL_GetDisplayForWindow(window); + SDL_DisplayData* dispdata = (SDL_DisplayData*)disp->driverdata; + Uint16* tempRamp = SDL_calloc(3 * sizeof(Uint16), 256); + if (tempRamp == NULL) + { + return SDL_OutOfMemory(); + } + SDL_memcpy(tempRamp, ramp, 3 * sizeof(Uint16) * 256); + if (KMSDRM_drmModeCrtcSetGamma(viddata->drm_fd, dispdata->crtc->crtc_id, 256, &tempRamp[0*256], &tempRamp[1*256], &tempRamp[2*256]) == -1) + { + SDL_free(tempRamp); + return SDL_SetError("Failed to set gamma ramp"); + } + SDL_free(tempRamp); + return 0; +} + int KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { @@ -1875,23 +1419,23 @@ void KMSDRM_SetWindowPosition(_THIS, SDL_Window * window) { } - void KMSDRM_SetWindowSize(_THIS, SDL_Window * window) { - if (KMSDRM_ReconfigureWindow(_this, window)) { - SDL_SetError("Can't reconfigure window on SetWindowSize."); + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + if (!viddata->vulkan_mode) { + KMSDRM_DirtySurfaces(window); } } - void KMSDRM_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) + { - if (KMSDRM_ReconfigureWindow(_this, window)) { - SDL_SetError("Can't reconfigure window on SetWindowFullscreen."); + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + if (!viddata->vulkan_mode) { + KMSDRM_DirtySurfaces(window); } } - void KMSDRM_ShowWindow(_THIS, SDL_Window * window) { @@ -1915,11 +1459,6 @@ KMSDRM_MinimizeWindow(_THIS, SDL_Window * window) void KMSDRM_RestoreWindow(_THIS, SDL_Window * window) { -} -void -KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) -{ - } /*****************************************************************************/ @@ -1928,16 +1467,22 @@ KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) SDL_bool KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) { - if (info->version.major <= SDL_MAJOR_VERSION) { - return SDL_TRUE; - } else { - SDL_SetError("application not compiled with SDL %d.%d\n", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); - return SDL_FALSE; - } + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + const Uint32 version = SDL_VERSIONNUM((Uint32)info->version.major, + (Uint32)info->version.minor, + (Uint32)info->version.patch); - /* Failed to get window manager information */ - return SDL_FALSE; + if (version < SDL_VERSIONNUM(2, 0, 15)) { + SDL_SetError("Version must be 2.0.15 or newer"); + return SDL_FALSE; + } + + info->subsystem = SDL_SYSWM_KMSDRM; + info->info.kmsdrm.dev_index = viddata->devindex; + info->info.kmsdrm.drm_fd = viddata->drm_fd; + info->info.kmsdrm.gbm_dev = viddata->gbm_dev; + + return SDL_TRUE; } #endif /* SDL_VIDEO_DRIVER_KMSDRM */ diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvideo.h b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvideo.h index 2cf34522b..ebc863f6e 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvideo.h +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvideo.h @@ -1,7 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - Atomic KMSDRM backend by Manuel Alfayate Corchete + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,19 +30,8 @@ #include #include #include - #include -#include -#if SDL_VIDEO_OPENGL_EGL #include -#include -#endif - -/****************************************************************************************/ -/* Driverdata pointers are void struct* used to store backend-specific variables */ -/* and info that supports the SDL-side structs like SDL Display Devices, SDL_Windows... */ -/* which need to be "supported" with backend-side info and mechanisms to work. */ -/****************************************************************************************/ typedef struct SDL_VideoData { @@ -53,71 +41,48 @@ typedef struct SDL_VideoData struct gbm_device *gbm_dev; - SDL_Window **windows; - unsigned int max_windows; - unsigned int num_windows; + SDL_bool video_init; /* Has VideoInit succeeded? */ + SDL_bool vulkan_mode; /* Are we in Vulkan mode? One VK window is enough to be. */ + SDL_bool async_pageflip_support; /* Does the hardware support async. pageflips? */ - SDL_bool video_init; /* Has VideoInit succeeded? */ + SDL_Window **windows; + int max_windows; + int num_windows; + + /* Even if we have several displays, we only have to + open 1 FD and create 1 gbm device. */ + SDL_bool gbm_init; } SDL_VideoData; -typedef struct plane { - drmModePlane *plane; - drmModeObjectProperties *props; - drmModePropertyRes **props_info; -} plane; -typedef struct crtc { - drmModeCrtc *crtc; - drmModeObjectProperties *props; - drmModePropertyRes **props_info; -} crtc; +typedef struct SDL_DisplayModeData +{ + int mode_index; +} SDL_DisplayModeData; -typedef struct connector { - drmModeConnector *connector; - drmModeObjectProperties *props; - drmModePropertyRes **props_info; -} connector; -/* More general driverdata info that gives support and substance to the SDL_Display. */ typedef struct SDL_DisplayData { + drmModeConnector *connector; + drmModeCrtc *crtc; drmModeModeInfo mode; - drmModeModeInfo preferred_mode; - uint32_t atomic_flags; + drmModeModeInfo original_mode; + drmModeModeInfo fullscreen_mode; - plane *display_plane; - plane *cursor_plane; - crtc *crtc; - connector *connector; - - /* Central atomic request list, used for the prop - changeset related to pageflip in SwapWindow. */ - drmModeAtomicReq *atomic_req; - - int kms_in_fence_fd; - int kms_out_fence_fd; - - EGLSyncKHR kms_fence; - EGLSyncKHR gpu_fence; - -#if SDL_VIDEO_OPENGL_EGL - EGLSurface old_egl_surface; -#endif - - SDL_bool modeset_pending; - SDL_bool gbm_init; + drmModeCrtc *saved_crtc; /* CRTC to restore on quit */ /* DRM & GBM cursor stuff lives here, not in an SDL_Cursor's driverdata struct, because setting/unsetting up these is done on window creation/destruction, where we may not have an SDL_Cursor at all (so no SDL_Cursor driverdata). There's only one cursor GBM BO because we only support one cursor. */ struct gbm_bo *cursor_bo; + int cursor_bo_drm_fd; uint64_t cursor_w, cursor_h; + SDL_bool default_cursor_init; } SDL_DisplayData; -/* Driverdata info that gives KMSDRM-side support and substance to the SDL_Window. */ typedef struct SDL_WindowData { SDL_VideoData *viddata; @@ -129,65 +94,24 @@ typedef struct SDL_WindowData struct gbm_bo *bo; struct gbm_bo *next_bo; -#if SDL_VIDEO_OPENGL_EGL + SDL_bool waiting_for_flip; + SDL_bool double_buffer; + EGLSurface egl_surface; -#endif - - /* For scaling and AR correction. */ - int32_t src_w; - int32_t src_h; - int32_t output_w; - int32_t output_h; - int32_t output_x; - - /* This dictates what approach we'll use for SwapBuffers. */ - int (*swap_window)(_THIS, SDL_Window * window); - + SDL_bool egl_surface_dirty; } SDL_WindowData; -typedef struct SDL_DisplayModeData -{ - int mode_index; -} SDL_DisplayModeData; - typedef struct KMSDRM_FBInfo { int drm_fd; /* DRM file desc */ uint32_t fb_id; /* DRM framebuffer ID */ } KMSDRM_FBInfo; -typedef struct KMSDRM_PlaneInfo -{ - struct plane *plane; - uint32_t fb_id; - uint32_t crtc_id; - int32_t src_x; - int32_t src_y; - int32_t src_w; - int32_t src_h; - int32_t crtc_x; - int32_t crtc_y; - int32_t crtc_w; - int32_t crtc_h; -} KMSDRM_PlaneInfo; - /* Helper functions */ -int KMSDRM_CreateEGLSurface(_THIS, SDL_Window * window); +int KMSDRM_CreateSurfaces(_THIS, SDL_Window * window); KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo); - -/* Atomic functions that are used from SDL_kmsdrmopengles.c and SDL_kmsdrmmouse.c */ -void drm_atomic_set_plane_props(struct KMSDRM_PlaneInfo *info); - -void drm_atomic_waitpending(_THIS); -int drm_atomic_commit(_THIS, SDL_bool blocking); -int add_plane_property(drmModeAtomicReq *req, struct plane *plane, - const char *name, uint64_t value); -int add_crtc_property(drmModeAtomicReq *req, struct crtc *crtc, - const char *name, uint64_t value); -int add_connector_property(drmModeAtomicReq *req, struct connector *connector, - const char *name, uint64_t value); -int setup_plane(_THIS, struct plane **plane, uint32_t plane_type); -void free_plane(struct plane **plane); +KMSDRM_FBInfo *KMSDRM_FBFromBO2(_THIS, struct gbm_bo *bo, int w, int h); +SDL_bool KMSDRM_WaitPageflip(_THIS, SDL_WindowData *windata); /****************************************************************************/ /* SDL_VideoDevice functions declaration */ @@ -205,13 +129,14 @@ void KMSDRM_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); void KMSDRM_SetWindowPosition(_THIS, SDL_Window * window); void KMSDRM_SetWindowSize(_THIS, SDL_Window * window); void KMSDRM_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen); +int KMSDRM_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); +int KMSDRM_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); void KMSDRM_ShowWindow(_THIS, SDL_Window * window); void KMSDRM_HideWindow(_THIS, SDL_Window * window); void KMSDRM_RaiseWindow(_THIS, SDL_Window * window); void KMSDRM_MaximizeWindow(_THIS, SDL_Window * window); void KMSDRM_MinimizeWindow(_THIS, SDL_Window * window); void KMSDRM_RestoreWindow(_THIS, SDL_Window * window); -void KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); void KMSDRM_DestroyWindow(_THIS, SDL_Window * window); /* Window manager function */ diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvulkan.c b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvulkan.c index b3160ed66..b9ab13c58 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvulkan.c +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -182,37 +182,40 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, VkInstance instance, VkSurfaceKHR *surface) { - VkPhysicalDevice gpu; + VkPhysicalDevice gpu = NULL; uint32_t gpu_count; uint32_t display_count; uint32_t mode_count; uint32_t plane_count; + uint32_t plane = UINT32_MAX; VkPhysicalDevice *physical_devices = NULL; - VkDisplayPropertiesKHR *displays_props = NULL; - VkDisplayModePropertiesKHR *modes_props = NULL; - VkDisplayPlanePropertiesKHR *planes_props = NULL; + VkPhysicalDeviceProperties *device_props = NULL; + VkDisplayPropertiesKHR *display_props = NULL; + VkDisplayModePropertiesKHR *mode_props = NULL; + VkDisplayPlanePropertiesKHR *plane_props = NULL; + VkDisplayPlaneCapabilitiesKHR plane_caps; VkDisplayModeCreateInfoKHR display_mode_create_info; VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info; VkExtent2D image_size; - VkDisplayModeKHR display_mode; + VkDisplayKHR display; + VkDisplayModeKHR display_mode = (VkDisplayModeKHR)0; VkDisplayModePropertiesKHR display_mode_props = {0}; + VkDisplayModeParametersKHR new_mode_parameters = { {0, 0}, 0}; + /* Prefer a plane that supports per-pixel alpha. */ + VkDisplayPlaneAlphaFlagBitsKHR alpha_mode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR; VkResult result; SDL_bool ret = SDL_FALSE; + SDL_bool valid_gpu = SDL_FALSE; + SDL_bool mode_found = SDL_FALSE; + SDL_bool plane_supports_display = SDL_FALSE; - /* We don't receive a display index in KMSDRM_CreateDevice(), only - a device index, which determines the GPU to use, but not the output. - So we simply use the first connected output (ie, the first connected - video output) for now. - In other words, change this index to select a different output. Easy! */ - int display_index = 0; - - int i; - - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + /* Get the display index from the display being used by the window. */ + int display_index = SDL_atoi(SDL_GetDisplayForWindow(window)->name); + int i, j; /* Get the function pointers for the functions we will use. */ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = @@ -226,6 +229,10 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, (PFN_vkEnumeratePhysicalDevices)vkGetInstanceProcAddr( instance, "vkEnumeratePhysicalDevices"); + PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties = + (PFN_vkGetPhysicalDeviceProperties)vkGetInstanceProcAddr( + instance, "vkGetPhysicalDeviceProperties"); + PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceDisplayPropertiesKHR"); @@ -238,14 +245,13 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR"); - /*PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR = + PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR = (PFN_vkGetDisplayPlaneSupportedDisplaysKHR)vkGetInstanceProcAddr( instance, "vkGetDisplayPlaneSupportedDisplaysKHR"); - + PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR = (PFN_vkGetDisplayPlaneCapabilitiesKHR)vkGetInstanceProcAddr( instance, "vkGetDisplayPlaneCapabilitiesKHR"); - */ PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR = (PFN_vkCreateDisplayModeKHR)vkGetInstanceProcAddr( @@ -273,6 +279,14 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, goto clean; } + /* A GPU (or physical_device, in vkcube terms) is a physical GPU. + A machine with more than one video output doesn't need to have more than one GPU, + like the Pi4 which has 1 GPU and 2 video outputs. + Just in case, we test that the GPU we choose is Vulkan-capable. + If there are new reports about VK init failures, hardcode + gpu = physical_devices[0], instead of probing, and go with that. + */ + /* Get the physical device count. */ vkEnumeratePhysicalDevices(instance, &gpu_count, NULL); @@ -282,14 +296,33 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, } /* Get the physical devices. */ - physical_devices = malloc(sizeof(VkPhysicalDevice) * gpu_count); + physical_devices = SDL_malloc(sizeof(VkPhysicalDevice) * gpu_count); + device_props = SDL_malloc(sizeof(VkPhysicalDeviceProperties)); vkEnumeratePhysicalDevices(instance, &gpu_count, physical_devices); - /* A GPU (or physical_device, in vkcube terms) is a GPU. A machine with more - than one video output doen't need to have more than one GPU, like the Pi4 - which has 1 GPU and 2 video outputs. - We grab the GPU/physical_device with the index we got in KMSDR_CreateDevice(). */ - gpu = physical_devices[viddata->devindex]; + /* Iterate on the physical devices. */ + for (i = 0; i < gpu_count; i++) { + + /* Get the physical device properties. */ + vkGetPhysicalDeviceProperties( + physical_devices[i], + device_props + ); + + /* Is this device a real GPU that supports API version 1 at least? */ + if (device_props->apiVersion >= 1 && + (device_props->deviceType == 1 || device_props->deviceType == 2)) + { + gpu = physical_devices[i]; + valid_gpu = SDL_TRUE; + break; + } + } + + if (!valid_gpu) { + SDL_SetError("Vulkan can't find a valid physical device (gpu)."); + goto clean; + } /* A display is a video output. 1 GPU can have N displays. Vulkan only counts the connected displays. @@ -301,89 +334,175 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, } /* Get the props of the displays of the physical device. */ - displays_props = (VkDisplayPropertiesKHR *) malloc(display_count * sizeof(*displays_props)); + display_props = (VkDisplayPropertiesKHR *) SDL_malloc(display_count * sizeof(*display_props)); vkGetPhysicalDeviceDisplayPropertiesKHR(gpu, &display_count, - displays_props); + display_props); - /* Get the videomode count for the first display. */ + /* Get the chosen display based on the display index. */ + display = display_props[display_index].display; + + /* Get the list of the display videomodes. */ vkGetDisplayModePropertiesKHR(gpu, - displays_props[display_index].display, + display, &mode_count, NULL); if (mode_count == 0) { SDL_SetError("Vulkan can't find any video modes for display %i (%s)\n", 0, - displays_props[display_index].displayName); + display_props[display_index].displayName); goto clean; } - /* Get the props of the videomodes for the first display. */ - modes_props = (VkDisplayModePropertiesKHR *) malloc(mode_count * sizeof(*modes_props)); + mode_props = (VkDisplayModePropertiesKHR *) SDL_malloc(mode_count * sizeof(*mode_props)); vkGetDisplayModePropertiesKHR(gpu, - displays_props[display_index].display, - &mode_count, modes_props); + display, + &mode_count, mode_props); - /* Get the planes count of the physical device. */ + /* Get a video mode equal to the window size among the predefined ones, + if possible. + REMEMBER: We have to get a small enough videomode for the window size, + because videomode determines how big the scanout region is and we can't + scanout a region bigger than the window (we would be reading past the + buffer, and Vulkan would give us a confusing VK_ERROR_SURFACE_LOST_KHR). */ + for (i = 0; i < mode_count; i++) { + if (mode_props[i].parameters.visibleRegion.width == window->w && + mode_props[i].parameters.visibleRegion.height == window->h) + { + display_mode_props = mode_props[i]; + mode_found = SDL_TRUE; + break; + } + } + + if (mode_found && + display_mode_props.parameters.visibleRegion.width > 0 && + display_mode_props.parameters.visibleRegion.height > 0 ) { + /* Found a suitable mode among the predefined ones. Use that. */ + display_mode = display_mode_props.displayMode; + } else { + + /* Couldn't find a suitable mode among the predefined ones, so try to create our own. + This won't work for some video chips atm (like Pi's VideoCore) so these are limited + to supported resolutions. Don't try to use "closest" resolutions either, because + those are often bigger than the window size, thus causing out-of-bunds scanout. */ + new_mode_parameters.visibleRegion.width = window->w; + new_mode_parameters.visibleRegion.height = window->h; + /* SDL (and DRM, if we look at drmModeModeInfo vrefresh) uses plain integer Hz for + display mode refresh rate, but Vulkan expects higher precision. */ + new_mode_parameters.refreshRate = window->fullscreen_mode.refresh_rate * 1000; + + SDL_zero(display_mode_create_info); + display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR; + display_mode_create_info.parameters = new_mode_parameters; + result = vkCreateDisplayModeKHR(gpu, + display, + &display_mode_create_info, + NULL, &display_mode); + if (result != VK_SUCCESS) { + SDL_SetError("Vulkan couldn't find a predefined mode for that window size and couldn't create a suitable mode."); + goto clean; + } + } + + /* Just in case we get here without a display_mode. */ + if (!display_mode) { + SDL_SetError("Vulkan couldn't get a display mode."); + goto clean; + } + + /* Get the list of the physical device planes. */ vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, NULL); if (plane_count == 0) { SDL_SetError("Vulkan can't find any planes."); goto clean; } + plane_props = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count); + vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, plane_props); - /* Get the props of the planes for the physical device. */ - planes_props = malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count); - vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, planes_props); + /* Iterate on the list of planes of the physical device + to find a plane that matches these criteria: + -It must be compatible with the chosen display + mode. + -It isn't currently bound to another display. + -It supports per-pixel alpha, if possible. */ + for (i = 0; i < plane_count; i++) { - /* Get a video mode equal or smaller than the window size. REMEMBER: - We have to get a small enough videomode for the window size, - because videomode determines how big the scanout region is and we can't - scanout a region bigger than the window (we would be reading past the - buffer, and Vulkan would give us a confusing VK_ERROR_SURFACE_LOST_KHR). */ - for (i = 0; i < mode_count; i++) { - if (modes_props[i].parameters.visibleRegion.width <= window->w && - modes_props[i].parameters.visibleRegion.height <= window->h) - { - display_mode_props = modes_props[i]; + uint32_t supported_displays_count = 0; + VkDisplayKHR* supported_displays; + + /* See if the plane is compatible with the current display. */ + vkGetDisplayPlaneSupportedDisplaysKHR(gpu, i, &supported_displays_count, NULL); + if (supported_displays_count == 0) { + /* This plane doesn't support any displays. Continue to the next plane. */ + continue; + } + + /* Get the list of displays supported by this plane. */ + supported_displays = (VkDisplayKHR*)SDL_malloc(sizeof(VkDisplayKHR) * supported_displays_count); + vkGetDisplayPlaneSupportedDisplaysKHR(gpu, i, + &supported_displays_count, supported_displays); + + /* The plane must be bound to the chosen display, or not in use. + If none of these is true, iterate to another plane. */ + if (!((plane_props[i].currentDisplay == display) || + (plane_props[i].currentDisplay == VK_NULL_HANDLE))) + continue; + + /* Iterate the list of displays supported by this plane + in order to find out if the chosen display is among them. */ + plane_supports_display = SDL_FALSE; + for (j = 0; j < supported_displays_count; j++) { + if (supported_displays[j] == display) { + plane_supports_display = SDL_TRUE; + break; + } + } + + /* Free the list of displays supported by this plane. */ + if (supported_displays) { + SDL_free(supported_displays); + } + + /* If the display is not supported by this plane, iterate to the next plane. */ + if (!plane_supports_display) { + continue; + } + + /* Want a plane that supports the alpha mode we have chosen. */ + vkGetDisplayPlaneCapabilitiesKHR(gpu, display_mode, i, &plane_caps); + if (plane_caps.supportedAlpha == alpha_mode) { + /* Yep, this plane is alright. */ + plane = i; break; } } - if (display_mode_props.parameters.visibleRegion.width == 0 - || display_mode_props.parameters.visibleRegion.height == 0) - { - SDL_SetError("Vulkan can't find a proper display mode for the window size."); - goto clean; - } - - /* We have the props of the display mode, but we need an actual display mode. */ - display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR; - display_mode_create_info.parameters = display_mode_props.parameters; - result = vkCreateDisplayModeKHR(gpu, - displays_props[display_index].display, - &display_mode_create_info, - NULL, &display_mode); - if (result != VK_SUCCESS) { - SDL_SetError("Vulkan can't create the display mode."); + /* If we couldn't find an appropiate plane, error out. */ + if (plane == UINT32_MAX) { + SDL_SetError("Vulkan couldn't find an appropiate plane."); goto clean; } + /********************************************/ /* Let's finally create the Vulkan surface! */ + /********************************************/ image_size.width = window->w; image_size.height = window->h; + SDL_zero(display_plane_surface_create_info); display_plane_surface_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR; display_plane_surface_create_info.displayMode = display_mode; - /* For now, simply use the first plane. */ - display_plane_surface_create_info.planeIndex = 0; + display_plane_surface_create_info.planeIndex = plane; display_plane_surface_create_info.imageExtent = image_size; + display_plane_surface_create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + display_plane_surface_create_info.alphaMode = alpha_mode; result = vkCreateDisplayPlaneSurfaceKHR(instance, &display_plane_surface_create_info, NULL, surface); if(result != VK_SUCCESS) { - SDL_SetError("vkCreateKMSDRMSurfaceKHR failed: %s", + SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result)); goto clean; } @@ -392,13 +511,15 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, clean: if (physical_devices) - free (physical_devices); - if (displays_props) - free (displays_props); - if (planes_props) - free (planes_props); - if (modes_props) - free (modes_props); + SDL_free (physical_devices); + if (display_props) + SDL_free (display_props); + if (device_props) + SDL_free (device_props); + if (plane_props) + SDL_free (plane_props); + if (mode_props) + SDL_free (mode_props); return ret; } diff --git a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvulkan.h b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvulkan.h index 2ee04bb9e..92d08732c 100644 --- a/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvulkan.h +++ b/Engine/lib/sdl/src/video/kmsdrm/SDL_kmsdrmvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,8 +26,8 @@ #include "../../SDL_internal.h" -#ifndef SDL_kmsdrmvulkan_h_ -#define SDL_kmsdrmvulkan_h_ +#ifndef SDL_kmsdrm_vulkan_h_ +#define SDL_kmsdrm_vulkan_h_ #include "../SDL_vulkan_internal.h" #include "../SDL_sysvideo.h" @@ -48,6 +48,6 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, #endif -#endif /* SDL_kmsdrmvulkan_h_ */ +#endif /* SDL_kmsdrm_vulkan_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_dyn.c b/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_dyn.c deleted file mode 100644 index 019c8e188..000000000 --- a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_dyn.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -#if SDL_VIDEO_DRIVER_KMSDRM - -#define DEBUG_DYNAMIC_KMSDRM_LEGACY 0 - -#include "SDL_kmsdrm_legacy_dyn.h" - -#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC - -#include "SDL_name.h" -#include "SDL_loadso.h" - -typedef struct -{ - void *lib; - const char *libname; -} kmsdrmdynlib; - -#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC -#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC NULL -#endif -#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM -#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM NULL -#endif - -static kmsdrmdynlib kmsdrmlibs[] = { - {NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM}, - {NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC} -}; - -static void * -KMSDRM_LEGACY_GetSym(const char *fnname, int *pHasModule) -{ - int i; - void *fn = NULL; - for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) { - if (kmsdrmlibs[i].lib != NULL) { - fn = SDL_LoadFunction(kmsdrmlibs[i].lib, fnname); - if (fn != NULL) - break; - } - } - -#if DEBUG_DYNAMIC_KMSDRM_LEGACY - if (fn != NULL) - SDL_Log("KMSDRM_LEGACY: Found '%s' in %s (%p)\n", fnname, kmsdrmlibs[i].libname, fn); - else - SDL_Log("KMSDRM_LEGACY: Symbol '%s' NOT FOUND!\n", fnname); -#endif - - if (fn == NULL) - *pHasModule = 0; /* kill this module. */ - - return fn; -} - -#endif /* SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC */ - -/* Define all the function pointers and wrappers... */ -#define SDL_KMSDRM_LEGACY_MODULE(modname) int SDL_KMSDRM_LEGACY_HAVE_##modname = 0; -#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) SDL_DYNKMSDRM_LEGACYFN_##fn KMSDRM_LEGACY_##fn = NULL; -#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) SDL_DYNKMSDRM_LEGACYCONST_##name KMSDRM_LEGACY_##name = NULL; -#include "SDL_kmsdrm_legacy_sym.h" - -static int kmsdrm_load_refcount = 0; - -void -SDL_KMSDRM_LEGACY_UnloadSymbols(void) -{ - /* Don't actually unload if more than one module is using the libs... */ - if (kmsdrm_load_refcount > 0) { - if (--kmsdrm_load_refcount == 0) { -#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC - int i; -#endif - - /* set all the function pointers to NULL. */ -#define SDL_KMSDRM_LEGACY_MODULE(modname) SDL_KMSDRM_LEGACY_HAVE_##modname = 0; -#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) KMSDRM_LEGACY_##fn = NULL; -#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) KMSDRM_LEGACY_##name = NULL; -#include "SDL_kmsdrm_legacy_sym.h" - - -#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC - for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) { - if (kmsdrmlibs[i].lib != NULL) { - SDL_UnloadObject(kmsdrmlibs[i].lib); - kmsdrmlibs[i].lib = NULL; - } - } -#endif - } - } -} - -/* returns non-zero if all needed symbols were loaded. */ -int -SDL_KMSDRM_LEGACY_LoadSymbols(void) -{ - int rc = 1; /* always succeed if not using Dynamic KMSDRM_LEGACY stuff. */ - - /* deal with multiple modules needing these symbols... */ - if (kmsdrm_load_refcount++ == 0) { -#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC - int i; - int *thismod = NULL; - for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) { - if (kmsdrmlibs[i].libname != NULL) { - kmsdrmlibs[i].lib = SDL_LoadObject(kmsdrmlibs[i].libname); - } - } - -#define SDL_KMSDRM_LEGACY_MODULE(modname) SDL_KMSDRM_LEGACY_HAVE_##modname = 1; /* default yes */ -#include "SDL_kmsdrm_legacy_sym.h" - -#define SDL_KMSDRM_LEGACY_MODULE(modname) thismod = &SDL_KMSDRM_LEGACY_HAVE_##modname; -#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) KMSDRM_LEGACY_##fn = (SDL_DYNKMSDRM_LEGACYFN_##fn) KMSDRM_LEGACY_GetSym(#fn,thismod); -#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) KMSDRM_LEGACY_##name = *(SDL_DYNKMSDRM_LEGACYCONST_##name*) KMSDRM_LEGACY_GetSym(#name,thismod); -#include "SDL_kmsdrm_legacy_sym.h" - - if ((SDL_KMSDRM_LEGACY_HAVE_LIBDRM) && (SDL_KMSDRM_LEGACY_HAVE_GBM)) { - /* all required symbols loaded. */ - SDL_ClearError(); - } else { - /* in case something got loaded... */ - SDL_KMSDRM_LEGACY_UnloadSymbols(); - rc = 0; - } - -#else /* no dynamic KMSDRM_LEGACY */ - -#define SDL_KMSDRM_LEGACY_MODULE(modname) SDL_KMSDRM_LEGACY_HAVE_##modname = 1; /* default yes */ -#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) KMSDRM_LEGACY_##fn = fn; -#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) KMSDRM_LEGACY_##name = name; -#include "SDL_kmsdrm_legacy_sym.h" - -#endif - } - - return rc; -} - -#endif /* SDL_VIDEO_DRIVER_KMSDRM */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_mouse.c b/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_mouse.c deleted file mode 100644 index c980ebba6..000000000 --- a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_mouse.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -#if SDL_VIDEO_DRIVER_KMSDRM - -#include "SDL_kmsdrm_legacy_video.h" -#include "SDL_kmsdrm_legacy_mouse.h" -#include "SDL_kmsdrm_legacy_dyn.h" - -#include "../../events/SDL_mouse_c.h" -#include "../../events/default_cursor.h" - -static SDL_Cursor *KMSDRM_LEGACY_CreateDefaultCursor(void); -static SDL_Cursor *KMSDRM_LEGACY_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y); -static int KMSDRM_LEGACY_ShowCursor(SDL_Cursor * cursor); -static void KMSDRM_LEGACY_MoveCursor(SDL_Cursor * cursor); -static void KMSDRM_LEGACY_FreeCursor(SDL_Cursor * cursor); -static void KMSDRM_LEGACY_WarpMouse(SDL_Window * window, int x, int y); -static int KMSDRM_LEGACY_WarpMouseGlobal(int x, int y); - -static SDL_Cursor * -KMSDRM_LEGACY_CreateDefaultCursor(void) -{ - return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY); -} - -/* Evaluate if a given cursor size is supported or not. Notably, current Intel gfx only support 64x64 and up. */ -static SDL_bool -KMSDRM_LEGACY_IsCursorSizeSupported (int w, int h, uint32_t bo_format) { - - SDL_VideoDevice *dev = SDL_GetVideoDevice(); - SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata); - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - - int ret; - uint32_t bo_handle; - struct gbm_bo *bo = KMSDRM_LEGACY_gbm_bo_create(viddata->gbm, w, h, bo_format, - GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE); - - if (!bo) { - SDL_SetError("Could not create GBM cursor BO width size %dx%d for size testing", w, h); - goto cleanup; - } - - bo_handle = KMSDRM_LEGACY_gbm_bo_get_handle(bo).u32; - ret = KMSDRM_LEGACY_drmModeSetCursor(viddata->drm_fd, dispdata->crtc_id, bo_handle, w, h); - - if (ret) { - goto cleanup; - } - else { - KMSDRM_LEGACY_gbm_bo_destroy(bo); - return SDL_TRUE; - } - -cleanup: - if (bo) { - KMSDRM_LEGACY_gbm_bo_destroy(bo); - } - return SDL_FALSE; -} - -/* Create a cursor from a surface */ -static SDL_Cursor * -KMSDRM_LEGACY_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) -{ - SDL_VideoDevice *dev = SDL_GetVideoDevice(); - SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata); - SDL_PixelFormat *pixlfmt = surface->format; - KMSDRM_LEGACY_CursorData *curdata; - SDL_Cursor *cursor; - SDL_bool cursor_supported = SDL_FALSE; - int i, ret, usable_cursor_w, usable_cursor_h; - uint32_t bo_format, bo_stride; - char *buffer = NULL; - size_t bufsize; - - switch(pixlfmt->format) { - case SDL_PIXELFORMAT_RGB332: - bo_format = GBM_FORMAT_RGB332; - break; - case SDL_PIXELFORMAT_ARGB4444: - bo_format = GBM_FORMAT_ARGB4444; - break; - case SDL_PIXELFORMAT_RGBA4444: - bo_format = GBM_FORMAT_RGBA4444; - break; - case SDL_PIXELFORMAT_ABGR4444: - bo_format = GBM_FORMAT_ABGR4444; - break; - case SDL_PIXELFORMAT_BGRA4444: - bo_format = GBM_FORMAT_BGRA4444; - break; - case SDL_PIXELFORMAT_ARGB1555: - bo_format = GBM_FORMAT_ARGB1555; - break; - case SDL_PIXELFORMAT_RGBA5551: - bo_format = GBM_FORMAT_RGBA5551; - break; - case SDL_PIXELFORMAT_ABGR1555: - bo_format = GBM_FORMAT_ABGR1555; - break; - case SDL_PIXELFORMAT_BGRA5551: - bo_format = GBM_FORMAT_BGRA5551; - break; - case SDL_PIXELFORMAT_RGB565: - bo_format = GBM_FORMAT_RGB565; - break; - case SDL_PIXELFORMAT_BGR565: - bo_format = GBM_FORMAT_BGR565; - break; - case SDL_PIXELFORMAT_RGB888: - case SDL_PIXELFORMAT_RGB24: - bo_format = GBM_FORMAT_RGB888; - break; - case SDL_PIXELFORMAT_BGR888: - case SDL_PIXELFORMAT_BGR24: - bo_format = GBM_FORMAT_BGR888; - break; - case SDL_PIXELFORMAT_RGBX8888: - bo_format = GBM_FORMAT_RGBX8888; - break; - case SDL_PIXELFORMAT_BGRX8888: - bo_format = GBM_FORMAT_BGRX8888; - break; - case SDL_PIXELFORMAT_ARGB8888: - bo_format = GBM_FORMAT_ARGB8888; - break; - case SDL_PIXELFORMAT_RGBA8888: - bo_format = GBM_FORMAT_RGBA8888; - break; - case SDL_PIXELFORMAT_ABGR8888: - bo_format = GBM_FORMAT_ABGR8888; - break; - case SDL_PIXELFORMAT_BGRA8888: - bo_format = GBM_FORMAT_BGRA8888; - break; - case SDL_PIXELFORMAT_ARGB2101010: - bo_format = GBM_FORMAT_ARGB2101010; - break; - default: - SDL_SetError("Unsupported pixel format for cursor"); - return NULL; - } - - if (!KMSDRM_LEGACY_gbm_device_is_format_supported(viddata->gbm, bo_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) { - SDL_SetError("Unsupported pixel format for cursor"); - return NULL; - } - - cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); - if (!cursor) { - SDL_OutOfMemory(); - return NULL; - } - curdata = (KMSDRM_LEGACY_CursorData *) SDL_calloc(1, sizeof(*curdata)); - if (!curdata) { - SDL_OutOfMemory(); - SDL_free(cursor); - return NULL; - } - - /* We have to know beforehand if a cursor with the same size as the surface is supported. - * If it's not, we have to find an usable cursor size and use an intermediate and clean buffer. - * If we can't find a cursor size supported by the hardware, we won't go on trying to - * call SDL_SetCursor() later. */ - - usable_cursor_w = surface->w; - usable_cursor_h = surface->h; - - while (usable_cursor_w <= MAX_CURSOR_W && usable_cursor_h <= MAX_CURSOR_H) { - if (KMSDRM_LEGACY_IsCursorSizeSupported(usable_cursor_w, usable_cursor_h, bo_format)) { - cursor_supported = SDL_TRUE; - break; - } - usable_cursor_w += usable_cursor_w; - usable_cursor_h += usable_cursor_h; - } - - if (!cursor_supported) { - SDL_SetError("Could not find a cursor size supported by the kernel driver"); - goto cleanup; - } - - curdata->hot_x = hot_x; - curdata->hot_y = hot_y; - curdata->w = usable_cursor_w; - curdata->h = usable_cursor_h; - - curdata->bo = KMSDRM_LEGACY_gbm_bo_create(viddata->gbm, usable_cursor_w, usable_cursor_h, bo_format, - GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE); - - if (!curdata->bo) { - SDL_SetError("Could not create GBM cursor BO"); - goto cleanup; - } - - bo_stride = KMSDRM_LEGACY_gbm_bo_get_stride(curdata->bo); - bufsize = bo_stride * curdata->h; - - if (surface->pitch != bo_stride) { - /* pitch doesn't match stride, must be copied to temp buffer */ - buffer = SDL_malloc(bufsize); - if (!buffer) { - SDL_OutOfMemory(); - goto cleanup; - } - - if (SDL_MUSTLOCK(surface)) { - if (SDL_LockSurface(surface) < 0) { - /* Could not lock surface */ - goto cleanup; - } - } - - /* Clean the whole temporary buffer */ - SDL_memset(buffer, 0x00, bo_stride * curdata->h); - - /* Copy to temporary buffer */ - for (i = 0; i < surface->h; i++) { - SDL_memcpy(buffer + (i * bo_stride), - ((char *)surface->pixels) + (i * surface->pitch), - surface->w * pixlfmt->BytesPerPixel); - } - - if (SDL_MUSTLOCK(surface)) { - SDL_UnlockSurface(surface); - } - - if (KMSDRM_LEGACY_gbm_bo_write(curdata->bo, buffer, bufsize)) { - SDL_SetError("Could not write to GBM cursor BO"); - goto cleanup; - } - - /* Free temporary buffer */ - SDL_free(buffer); - buffer = NULL; - } else { - /* surface matches BO format */ - if (SDL_MUSTLOCK(surface)) { - if (SDL_LockSurface(surface) < 0) { - /* Could not lock surface */ - goto cleanup; - } - } - - ret = KMSDRM_LEGACY_gbm_bo_write(curdata->bo, surface->pixels, bufsize); - - if (SDL_MUSTLOCK(surface)) { - SDL_UnlockSurface(surface); - } - - if (ret) { - SDL_SetError("Could not write to GBM cursor BO"); - goto cleanup; - } - } - - cursor->driverdata = curdata; - - return cursor; - -cleanup: - if (buffer) { - SDL_free(buffer); - } - if (cursor) { - SDL_free(cursor); - } - if (curdata) { - if (curdata->bo) { - KMSDRM_LEGACY_gbm_bo_destroy(curdata->bo); - } - SDL_free(curdata); - } - return NULL; -} - -/* Show the specified cursor, or hide if cursor is NULL */ -static int -KMSDRM_LEGACY_ShowCursor(SDL_Cursor * cursor) -{ - SDL_VideoDevice *dev = SDL_GetVideoDevice(); - SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata); - SDL_Mouse *mouse; - KMSDRM_LEGACY_CursorData *curdata; - SDL_VideoDisplay *display = NULL; - SDL_DisplayData *dispdata = NULL; - int ret; - uint32_t bo_handle; - - mouse = SDL_GetMouse(); - if (!mouse) { - return SDL_SetError("No mouse."); - } - - if (mouse->focus) { - display = SDL_GetDisplayForWindow(mouse->focus); - if (display) { - dispdata = (SDL_DisplayData*) display->driverdata; - } - } - - if (!cursor) { - /* Hide current cursor */ - if (mouse->cur_cursor && mouse->cur_cursor->driverdata) { - curdata = (KMSDRM_LEGACY_CursorData *) mouse->cur_cursor->driverdata; - - if (curdata->crtc_id != 0) { - ret = KMSDRM_LEGACY_drmModeSetCursor(viddata->drm_fd, curdata->crtc_id, 0, 0, 0); - if (ret) { - SDL_SetError("Could not hide current cursor with drmModeSetCursor()."); - return ret; - } - /* Mark previous cursor as not-displayed */ - curdata->crtc_id = 0; - - return 0; - } - } - /* otherwise if possible, hide global cursor */ - if (dispdata && dispdata->crtc_id != 0) { - ret = KMSDRM_LEGACY_drmModeSetCursor(viddata->drm_fd, dispdata->crtc_id, 0, 0, 0); - if (ret) { - SDL_SetError("Could not hide display's cursor with drmModeSetCursor()."); - return ret; - } - return 0; - } - - return SDL_SetError("Couldn't find cursor to hide."); - } - /* If cursor != NULL, show new cursor on display */ - if (!display) { - return SDL_SetError("Could not get display for mouse."); - } - if (!dispdata) { - return SDL_SetError("Could not get display driverdata."); - } - - curdata = (KMSDRM_LEGACY_CursorData *) cursor->driverdata; - if (!curdata || !curdata->bo) { - return SDL_SetError("Cursor not initialized properly."); - } - - bo_handle = KMSDRM_LEGACY_gbm_bo_get_handle(curdata->bo).u32; - if (curdata->hot_x == 0 && curdata->hot_y == 0) { - ret = KMSDRM_LEGACY_drmModeSetCursor(viddata->drm_fd, dispdata->crtc_id, bo_handle, - curdata->w, curdata->h); - } else { - ret = KMSDRM_LEGACY_drmModeSetCursor2(viddata->drm_fd, dispdata->crtc_id, bo_handle, - curdata->w, curdata->h, curdata->hot_x, curdata->hot_y); - } - if (ret) { - SDL_SetError("drmModeSetCursor failed."); - return ret; - } - - curdata->crtc_id = dispdata->crtc_id; - - return 0; -} - -/* Free a window manager cursor */ -static void -KMSDRM_LEGACY_FreeCursor(SDL_Cursor * cursor) -{ - KMSDRM_LEGACY_CursorData *curdata; - int drm_fd; - - if (cursor) { - curdata = (KMSDRM_LEGACY_CursorData *) cursor->driverdata; - - if (curdata) { - if (curdata->bo) { - if (curdata->crtc_id != 0) { - drm_fd = KMSDRM_LEGACY_gbm_device_get_fd(KMSDRM_LEGACY_gbm_bo_get_device(curdata->bo)); - /* Hide the cursor if previously shown on a CRTC */ - KMSDRM_LEGACY_drmModeSetCursor(drm_fd, curdata->crtc_id, 0, 0, 0); - curdata->crtc_id = 0; - } - KMSDRM_LEGACY_gbm_bo_destroy(curdata->bo); - curdata->bo = NULL; - } - SDL_free(cursor->driverdata); - } - SDL_free(cursor); - } -} - -/* Warp the mouse to (x,y) */ -static void -KMSDRM_LEGACY_WarpMouse(SDL_Window * window, int x, int y) -{ - /* Only one global/fullscreen window is supported */ - KMSDRM_LEGACY_WarpMouseGlobal(x, y); -} - -/* Warp the mouse to (x,y) */ -static int -KMSDRM_LEGACY_WarpMouseGlobal(int x, int y) -{ - KMSDRM_LEGACY_CursorData *curdata; - SDL_Mouse *mouse = SDL_GetMouse(); - - if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) { - /* Update internal mouse position. */ - SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y); - - /* And now update the cursor graphic position on screen. */ - curdata = (KMSDRM_LEGACY_CursorData *) mouse->cur_cursor->driverdata; - if (curdata->bo) { - - if (curdata->crtc_id != 0) { - int ret, drm_fd; - drm_fd = KMSDRM_LEGACY_gbm_device_get_fd(KMSDRM_LEGACY_gbm_bo_get_device(curdata->bo)); - ret = KMSDRM_LEGACY_drmModeMoveCursor(drm_fd, curdata->crtc_id, x, y); - - if (ret) { - SDL_SetError("drmModeMoveCursor() failed."); - } - - return ret; - } else { - return SDL_SetError("Cursor is not currently shown."); - } - } else { - return SDL_SetError("Cursor not initialized properly."); - } - } else { - return SDL_SetError("No mouse or current cursor."); - } -} - -void -KMSDRM_LEGACY_InitMouse(_THIS) -{ - /* FIXME: Using UDEV it should be possible to scan all mice - * but there's no point in doing so as there's no multimice support...yet! - */ - SDL_Mouse *mouse = SDL_GetMouse(); - - mouse->CreateCursor = KMSDRM_LEGACY_CreateCursor; - mouse->ShowCursor = KMSDRM_LEGACY_ShowCursor; - mouse->MoveCursor = KMSDRM_LEGACY_MoveCursor; - mouse->FreeCursor = KMSDRM_LEGACY_FreeCursor; - mouse->WarpMouse = KMSDRM_LEGACY_WarpMouse; - mouse->WarpMouseGlobal = KMSDRM_LEGACY_WarpMouseGlobal; - - SDL_SetDefaultCursor(KMSDRM_LEGACY_CreateDefaultCursor()); -} - -void -KMSDRM_LEGACY_QuitMouse(_THIS) -{ - /* TODO: ? */ -} - -/* This is called when a mouse motion event occurs */ -static void -KMSDRM_LEGACY_MoveCursor(SDL_Cursor * cursor) -{ - SDL_Mouse *mouse = SDL_GetMouse(); - KMSDRM_LEGACY_CursorData *curdata; - int drm_fd, ret; - - /* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity! - That's why we move the cursor graphic ONLY. */ - if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) { - curdata = (KMSDRM_LEGACY_CursorData *) mouse->cur_cursor->driverdata; - drm_fd = KMSDRM_LEGACY_gbm_device_get_fd(KMSDRM_LEGACY_gbm_bo_get_device(curdata->bo)); - ret = KMSDRM_LEGACY_drmModeMoveCursor(drm_fd, curdata->crtc_id, mouse->x, mouse->y); - - if (ret) { - SDL_SetError("drmModeMoveCursor() failed."); - } - } -} - -#endif /* SDL_VIDEO_DRIVER_KMSDRM */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_opengles.c b/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_opengles.c deleted file mode 100644 index 890801891..000000000 --- a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_opengles.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL - -#include "SDL_log.h" - -#include "SDL_kmsdrm_legacy_video.h" -#include "SDL_kmsdrm_legacy_opengles.h" -#include "SDL_kmsdrm_legacy_dyn.h" - -#ifndef EGL_PLATFORM_GBM_MESA -#define EGL_PLATFORM_GBM_MESA 0x31D7 -#endif - -/* EGL implementation of SDL OpenGL support */ - -int -KMSDRM_LEGACY_GLES_LoadLibrary(_THIS, const char *path) { - NativeDisplayType display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm; - return SDL_EGL_LoadLibrary(_this, path, display, EGL_PLATFORM_GBM_MESA); -} - -SDL_EGL_CreateContext_impl(KMSDRM_LEGACY) - -int KMSDRM_LEGACY_GLES_SetSwapInterval(_THIS, int interval) { - if (!_this->egl_data) { - return SDL_SetError("EGL not initialized"); - } - - if (interval == 0 || interval == 1) { - _this->egl_data->egl_swapinterval = interval; - } else { - return SDL_SetError("Only swap intervals of 0 or 1 are supported"); - } - - return 0; -} - -int -KMSDRM_LEGACY_GLES_SwapWindow(_THIS, SDL_Window * window) { - SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata); - SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - KMSDRM_LEGACY_FBInfo *fb_info; - int ret, timeout; - - /* Recreate the GBM / EGL surfaces if the display mode has changed */ - if (windata->egl_surface_dirty) { - KMSDRM_LEGACY_CreateSurfaces(_this, window); - } - - /* Wait for confirmation that the next front buffer has been flipped, at which - point the previous front buffer can be released */ - timeout = 0; - if (_this->egl_data->egl_swapinterval == 1) { - timeout = -1; - } - if (!KMSDRM_LEGACY_WaitPageFlip(_this, windata, timeout)) { - return 0; - } - - /* Release the previous front buffer */ - if (windata->curr_bo) { - KMSDRM_LEGACY_gbm_surface_release_buffer(windata->gs, windata->curr_bo); - /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Released GBM surface %p", (void *)windata->curr_bo); */ - windata->curr_bo = NULL; - } - - windata->curr_bo = windata->next_bo; - - /* Make the current back buffer the next front buffer */ - if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, windata->egl_surface))) { - SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed."); - return 0; - } - - /* Lock the next front buffer so it can't be allocated as a back buffer */ - windata->next_bo = KMSDRM_LEGACY_gbm_surface_lock_front_buffer(windata->gs); - if (!windata->next_bo) { - SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer"); - return 0; - /* } else { - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Locked GBM surface %p", (void *)windata->next_bo); */ - } - - fb_info = KMSDRM_LEGACY_FBFromBO(_this, windata->next_bo); - if (!fb_info) { - return 0; - } - - if (!windata->curr_bo) { - /* On the first swap, immediately present the new front buffer. Before - drmModePageFlip can be used the CRTC has to be configured to use - the current connector and mode with drmModeSetCrtc */ - ret = KMSDRM_LEGACY_drmModeSetCrtc(viddata->drm_fd, dispdata->crtc_id, fb_info->fb_id, 0, - 0, &dispdata->conn->connector_id, 1, &dispdata->mode); - - if (ret) { - SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not configure CRTC"); - } - } else { - /* On subsequent swaps, queue the new front buffer to be flipped during - the next vertical blank */ - ret = KMSDRM_LEGACY_drmModePageFlip(viddata->drm_fd, dispdata->crtc_id, fb_info->fb_id, - DRM_MODE_PAGE_FLIP_EVENT, &windata->waiting_for_flip); - /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModePageFlip(%d, %u, %u, DRM_MODE_PAGE_FLIP_EVENT, &windata->waiting_for_flip)", - viddata->drm_fd, displaydata->crtc_id, fb_info->fb_id); */ - - if (_this->egl_data->egl_swapinterval == 1) { - if (ret == 0) { - windata->waiting_for_flip = SDL_TRUE; - } else { - SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret); - } - } - - /* Wait immediately for vsync (as if we only had two buffers), for low input-lag scenarios. - Run your SDL2 program with "SDL_KMSDRM_LEGACY_DOUBLE_BUFFER=1 " to enable this. */ - if (_this->egl_data->egl_swapinterval == 1 && windata->double_buffer) { - KMSDRM_LEGACY_WaitPageFlip(_this, windata, -1); - } - } - - return 0; -} - -SDL_EGL_MakeCurrent_impl(KMSDRM_LEGACY) - -#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_opengles.h b/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_opengles.h deleted file mode 100644 index 5e5ba96dc..000000000 --- a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_opengles.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_kmsdrmopengles_h_ -#define SDL_kmsdrmopengles_h_ - -#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL - -#include "../SDL_sysvideo.h" -#include "../SDL_egl_c.h" - -/* OpenGLES functions */ -#define KMSDRM_LEGACY_GLES_GetAttribute SDL_EGL_GetAttribute -#define KMSDRM_LEGACY_GLES_GetProcAddress SDL_EGL_GetProcAddress -#define KMSDRM_LEGACY_GLES_UnloadLibrary SDL_EGL_UnloadLibrary -#define KMSDRM_LEGACY_GLES_DeleteContext SDL_EGL_DeleteContext -#define KMSDRM_LEGACY_GLES_GetSwapInterval SDL_EGL_GetSwapInterval - -extern int KMSDRM_LEGACY_GLES_SetSwapInterval(_THIS, int interval); -extern int KMSDRM_LEGACY_GLES_LoadLibrary(_THIS, const char *path); -extern SDL_GLContext KMSDRM_LEGACY_GLES_CreateContext(_THIS, SDL_Window * window); -extern int KMSDRM_LEGACY_GLES_SwapWindow(_THIS, SDL_Window * window); -extern int KMSDRM_LEGACY_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); - -#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */ - -#endif /* SDL_kmsdrmopengles_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_sym.h b/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_sym.h deleted file mode 100644 index 8c41608fc..000000000 --- a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_sym.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* *INDENT-OFF* */ - -#ifndef SDL_KMSDRM_LEGACY_MODULE -#define SDL_KMSDRM_LEGACY_MODULE(modname) -#endif - -#ifndef SDL_KMSDRM_LEGACY_SYM -#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) -#endif - -#ifndef SDL_KMSDRM_LEGACY_SYM_CONST -#define SDL_KMSDRM_LEGACY_SYM_CONST(type, name) -#endif - - -SDL_KMSDRM_LEGACY_MODULE(LIBDRM) -SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeResources,(drmModeResPtr ptr)) -SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeFB,(drmModeFBPtr ptr)) -SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeCrtc,(drmModeCrtcPtr ptr)) -SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeConnector,(drmModeConnectorPtr ptr)) -SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeEncoder,(drmModeEncoderPtr ptr)) -SDL_KMSDRM_LEGACY_SYM(drmModeResPtr,drmModeGetResources,(int fd)) -SDL_KMSDRM_LEGACY_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_t depth, - uint8_t bpp, uint32_t pitch, uint32_t bo_handle, - uint32_t *buf_id)) -SDL_KMSDRM_LEGACY_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId)) -SDL_KMSDRM_LEGACY_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf)) -SDL_KMSDRM_LEGACY_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId)) -SDL_KMSDRM_LEGACY_SYM(int,drmModeSetCrtc,(int fd, uint32_t crtcId, uint32_t bufferId, - uint32_t x, uint32_t y, uint32_t *connectors, int count, - drmModeModeInfoPtr mode)) -SDL_KMSDRM_LEGACY_SYM(int,drmModeSetCursor,(int fd, uint32_t crtcId, uint32_t bo_handle, - uint32_t width, uint32_t height)) -SDL_KMSDRM_LEGACY_SYM(int,drmModeSetCursor2,(int fd, uint32_t crtcId, uint32_t bo_handle, - uint32_t width, uint32_t height, - int32_t hot_x, int32_t hot_y)) -SDL_KMSDRM_LEGACY_SYM(int,drmModeMoveCursor,(int fd, uint32_t crtcId, int x, int y)) -SDL_KMSDRM_LEGACY_SYM(drmModeEncoderPtr,drmModeGetEncoder,(int fd, uint32_t encoder_id)) -SDL_KMSDRM_LEGACY_SYM(drmModeConnectorPtr,drmModeGetConnector,(int fd, uint32_t connector_id)) -SDL_KMSDRM_LEGACY_SYM(int,drmHandleEvent,(int fd,drmEventContextPtr evctx)) -SDL_KMSDRM_LEGACY_SYM(int,drmModePageFlip,(int fd, uint32_t crtc_id, uint32_t fb_id, - uint32_t flags, void *user_data)) - - -SDL_KMSDRM_LEGACY_MODULE(GBM) -SDL_KMSDRM_LEGACY_SYM(int,gbm_device_get_fd,(struct gbm_device *gbm)) -SDL_KMSDRM_LEGACY_SYM(int,gbm_device_is_format_supported,(struct gbm_device *gbm, - uint32_t format, uint32_t usage)) -SDL_KMSDRM_LEGACY_SYM(void,gbm_device_destroy,(struct gbm_device *gbm)) -SDL_KMSDRM_LEGACY_SYM(struct gbm_device *,gbm_create_device,(int fd)) -SDL_KMSDRM_LEGACY_SYM(unsigned int,gbm_bo_get_width,(struct gbm_bo *bo)) -SDL_KMSDRM_LEGACY_SYM(unsigned int,gbm_bo_get_height,(struct gbm_bo *bo)) -SDL_KMSDRM_LEGACY_SYM(uint32_t,gbm_bo_get_stride,(struct gbm_bo *bo)) -SDL_KMSDRM_LEGACY_SYM(union gbm_bo_handle,gbm_bo_get_handle,(struct gbm_bo *bo)) -SDL_KMSDRM_LEGACY_SYM(int,gbm_bo_write,(struct gbm_bo *bo, const void *buf, size_t count)) -SDL_KMSDRM_LEGACY_SYM(struct gbm_device *,gbm_bo_get_device,(struct gbm_bo *bo)) -SDL_KMSDRM_LEGACY_SYM(void,gbm_bo_set_user_data,(struct gbm_bo *bo, void *data, - void (*destroy_user_data)(struct gbm_bo *, void *))) -SDL_KMSDRM_LEGACY_SYM(void *,gbm_bo_get_user_data,(struct gbm_bo *bo)) -SDL_KMSDRM_LEGACY_SYM(void,gbm_bo_destroy,(struct gbm_bo *bo)) -SDL_KMSDRM_LEGACY_SYM(struct gbm_bo *,gbm_bo_create,(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t usage)) -SDL_KMSDRM_LEGACY_SYM(struct gbm_surface *,gbm_surface_create,(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t flags)) -SDL_KMSDRM_LEGACY_SYM(void,gbm_surface_destroy,(struct gbm_surface *surf)) -SDL_KMSDRM_LEGACY_SYM(struct gbm_bo *,gbm_surface_lock_front_buffer,(struct gbm_surface *surf)) -SDL_KMSDRM_LEGACY_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct gbm_bo *bo)) - - -#undef SDL_KMSDRM_LEGACY_MODULE -#undef SDL_KMSDRM_LEGACY_SYM -#undef SDL_KMSDRM_LEGACY_SYM_CONST - -/* *INDENT-ON* */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_video.c b/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_video.c deleted file mode 100644 index 36b1899bd..000000000 --- a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_video.c +++ /dev/null @@ -1,934 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -#if SDL_VIDEO_DRIVER_KMSDRM - -/* SDL internals */ -#include "../SDL_sysvideo.h" -#include "SDL_syswm.h" -#include "SDL_log.h" -#include "SDL_hints.h" -#include "../../events/SDL_events_c.h" -#include "../../events/SDL_mouse_c.h" -#include "../../events/SDL_keyboard_c.h" - -#ifdef SDL_INPUT_LINUXEV -#include "../../core/linux/SDL_evdev.h" -#endif - -/* KMS/DRM declarations */ -#include "SDL_kmsdrm_legacy_video.h" -#include "SDL_kmsdrm_legacy_events.h" -#include "SDL_kmsdrm_legacy_opengles.h" -#include "SDL_kmsdrm_legacy_mouse.h" -#include "SDL_kmsdrm_legacy_dyn.h" -#include -#include -#include -#include - -#define KMSDRM_LEGACY_DRI_PATH "/dev/dri/" - -static int -check_modestting(int devindex) -{ - SDL_bool available = SDL_FALSE; - char device[512]; - int drm_fd; - - SDL_snprintf(device, sizeof (device), "%scard%d", KMSDRM_LEGACY_DRI_PATH, devindex); - - drm_fd = open(device, O_RDWR | O_CLOEXEC); - if (drm_fd >= 0) { - if (SDL_KMSDRM_LEGACY_LoadSymbols()) { - drmModeRes *resources = KMSDRM_LEGACY_drmModeGetResources(drm_fd); - if (resources) { - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "%scard%d connector, encoder and CRTC counts are: %d %d %d", - KMSDRM_LEGACY_DRI_PATH, devindex, - resources->count_connectors, resources->count_encoders, resources->count_crtcs); - - if (resources->count_connectors > 0 && resources->count_encoders > 0 && resources->count_crtcs > 0) { - available = SDL_TRUE; - } - KMSDRM_LEGACY_drmModeFreeResources(resources); - } - SDL_KMSDRM_LEGACY_UnloadSymbols(); - } - close(drm_fd); - } - - return available; -} - -static int get_dricount(void) -{ - int devcount = 0; - struct dirent *res; - struct stat sb; - DIR *folder; - - if (!(stat(KMSDRM_LEGACY_DRI_PATH, &sb) == 0 - && S_ISDIR(sb.st_mode))) { - printf("The path %s cannot be opened or is not available\n", - KMSDRM_LEGACY_DRI_PATH); - return 0; - } - - if (access(KMSDRM_LEGACY_DRI_PATH, F_OK) == -1) { - printf("The path %s cannot be opened\n", - KMSDRM_LEGACY_DRI_PATH); - return 0; - } - - folder = opendir(KMSDRM_LEGACY_DRI_PATH); - if (folder) { - while ((res = readdir(folder))) { - int len = SDL_strlen(res->d_name); - if (len > 4 && SDL_strncmp(res->d_name, "card", 4) == 0) { - devcount++; - } - } - closedir(folder); - } - - return devcount; -} - -static int -get_driindex(void) -{ - const int devcount = get_dricount(); - int i; - - for (i = 0; i < devcount; i++) { - if (check_modestting(i)) { - return i; - } - } - - return -ENOENT; -} - -static int -KMSDRM_LEGACY_Available(void) -{ - int ret = -ENOENT; - - ret = get_driindex(); - if (ret >= 0) - return 1; - - return ret; -} - -static void -KMSDRM_LEGACY_DeleteDevice(SDL_VideoDevice * device) -{ - if (device->driverdata) { - SDL_free(device->driverdata); - device->driverdata = NULL; - } - - SDL_free(device); - - SDL_KMSDRM_LEGACY_UnloadSymbols(); -} - -static SDL_VideoDevice * -KMSDRM_LEGACY_CreateDevice(int devindex) -{ - SDL_VideoDevice *device; - SDL_VideoData *viddata; - - if (!KMSDRM_LEGACY_Available()) { - return NULL; - } - - if (!devindex || (devindex > 99)) { - devindex = get_driindex(); - } - - if (devindex < 0) { - SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex); - return NULL; - } - - if (!SDL_KMSDRM_LEGACY_LoadSymbols()) { - return NULL; - } - - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); - if (!device) { - SDL_OutOfMemory(); - return NULL; - } - - viddata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); - if (!viddata) { - SDL_OutOfMemory(); - goto cleanup; - } - viddata->devindex = devindex; - viddata->drm_fd = -1; - - device->driverdata = viddata; - - /* Setup all functions which we can handle */ - device->VideoInit = KMSDRM_LEGACY_VideoInit; - device->VideoQuit = KMSDRM_LEGACY_VideoQuit; - device->GetDisplayModes = KMSDRM_LEGACY_GetDisplayModes; - device->SetDisplayMode = KMSDRM_LEGACY_SetDisplayMode; - device->CreateSDLWindow = KMSDRM_LEGACY_CreateWindow; - device->CreateSDLWindowFrom = KMSDRM_LEGACY_CreateWindowFrom; - device->SetWindowTitle = KMSDRM_LEGACY_SetWindowTitle; - device->SetWindowIcon = KMSDRM_LEGACY_SetWindowIcon; - device->SetWindowPosition = KMSDRM_LEGACY_SetWindowPosition; - device->SetWindowSize = KMSDRM_LEGACY_SetWindowSize; - device->ShowWindow = KMSDRM_LEGACY_ShowWindow; - device->HideWindow = KMSDRM_LEGACY_HideWindow; - device->RaiseWindow = KMSDRM_LEGACY_RaiseWindow; - device->MaximizeWindow = KMSDRM_LEGACY_MaximizeWindow; - device->MinimizeWindow = KMSDRM_LEGACY_MinimizeWindow; - device->RestoreWindow = KMSDRM_LEGACY_RestoreWindow; - device->SetWindowGrab = KMSDRM_LEGACY_SetWindowGrab; - device->DestroyWindow = KMSDRM_LEGACY_DestroyWindow; - device->GetWindowWMInfo = KMSDRM_LEGACY_GetWindowWMInfo; -#if SDL_VIDEO_OPENGL_EGL - device->GL_LoadLibrary = KMSDRM_LEGACY_GLES_LoadLibrary; - device->GL_GetProcAddress = KMSDRM_LEGACY_GLES_GetProcAddress; - device->GL_UnloadLibrary = KMSDRM_LEGACY_GLES_UnloadLibrary; - device->GL_CreateContext = KMSDRM_LEGACY_GLES_CreateContext; - device->GL_MakeCurrent = KMSDRM_LEGACY_GLES_MakeCurrent; - device->GL_SetSwapInterval = KMSDRM_LEGACY_GLES_SetSwapInterval; - device->GL_GetSwapInterval = KMSDRM_LEGACY_GLES_GetSwapInterval; - device->GL_SwapWindow = KMSDRM_LEGACY_GLES_SwapWindow; - device->GL_DeleteContext = KMSDRM_LEGACY_GLES_DeleteContext; -#endif - device->PumpEvents = KMSDRM_LEGACY_PumpEvents; - device->free = KMSDRM_LEGACY_DeleteDevice; - - return device; - -cleanup: - if (device) - SDL_free(device); - if (viddata) - SDL_free(viddata); - return NULL; -} - -VideoBootStrap KMSDRM_LEGACY_bootstrap = { - "KMSDRM_LEGACY", - "KMS/DRM Video Driver", - KMSDRM_LEGACY_CreateDevice -}; - - -static void -KMSDRM_LEGACY_FBDestroyCallback(struct gbm_bo *bo, void *data) -{ - KMSDRM_LEGACY_FBInfo *fb_info = (KMSDRM_LEGACY_FBInfo *)data; - - if (fb_info && fb_info->drm_fd >= 0 && fb_info->fb_id != 0) { - KMSDRM_LEGACY_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id); - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id); - } - - SDL_free(fb_info); -} - -KMSDRM_LEGACY_FBInfo * -KMSDRM_LEGACY_FBFromBO(_THIS, struct gbm_bo *bo) -{ - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - unsigned w,h; - int ret; - Uint32 stride, handle; - - /* Check for an existing framebuffer */ - KMSDRM_LEGACY_FBInfo *fb_info = (KMSDRM_LEGACY_FBInfo *)KMSDRM_LEGACY_gbm_bo_get_user_data(bo); - - if (fb_info) { - return fb_info; - } - - /* Create a structure that contains enough info to remove the framebuffer - when the backing buffer is destroyed */ - fb_info = (KMSDRM_LEGACY_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_LEGACY_FBInfo)); - - if (!fb_info) { - SDL_OutOfMemory(); - return NULL; - } - - fb_info->drm_fd = viddata->drm_fd; - - /* Create framebuffer object for the buffer */ - w = KMSDRM_LEGACY_gbm_bo_get_width(bo); - h = KMSDRM_LEGACY_gbm_bo_get_height(bo); - stride = KMSDRM_LEGACY_gbm_bo_get_stride(bo); - handle = KMSDRM_LEGACY_gbm_bo_get_handle(bo).u32; - ret = KMSDRM_LEGACY_drmModeAddFB(viddata->drm_fd, w, h, 24, 32, stride, handle, - &fb_info->fb_id); - if (ret) { - SDL_free(fb_info); - return NULL; - } - - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, stride %u from BO %p", - fb_info->fb_id, w, h, stride, (void *)bo); - - /* Associate our DRM framebuffer with this buffer object */ - KMSDRM_LEGACY_gbm_bo_set_user_data(bo, fb_info, KMSDRM_LEGACY_FBDestroyCallback); - - return fb_info; -} - -static void -KMSDRM_LEGACY_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) -{ - *((SDL_bool *) data) = SDL_FALSE; -} - -SDL_bool -KMSDRM_LEGACY_WaitPageFlip(_THIS, SDL_WindowData *windata, int timeout) { - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - drmEventContext ev = {0}; - struct pollfd pfd = {0}; - - ev.version = DRM_EVENT_CONTEXT_VERSION; - ev.page_flip_handler = KMSDRM_LEGACY_FlipHandler; - - pfd.fd = viddata->drm_fd; - pfd.events = POLLIN; - - while (windata->waiting_for_flip) { - pfd.revents = 0; - - if (poll(&pfd, 1, timeout) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error"); - return SDL_FALSE; - } - - if (pfd.revents & (POLLHUP | POLLERR)) { - SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error"); - return SDL_FALSE; - } - - if (pfd.revents & POLLIN) { - /* Page flip? If so, drmHandleEvent will unset windata->waiting_for_flip */ - KMSDRM_LEGACY_drmHandleEvent(viddata->drm_fd, &ev); - } else { - /* Timed out and page flip didn't happen */ - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Dropping frame while waiting_for_flip"); - return SDL_FALSE; - } - } - - return SDL_TRUE; -} - -/*****************************************************************************/ -/* SDL Video and Display initialization/handling functions */ -/* _this is a SDL_VideoDevice * */ -/*****************************************************************************/ -static void -KMSDRM_LEGACY_DestroySurfaces(_THIS, SDL_Window * window) -{ - SDL_WindowData *windata = (SDL_WindowData *)window->driverdata; - - KMSDRM_LEGACY_WaitPageFlip(_this, windata, -1); - - if (windata->curr_bo) { - KMSDRM_LEGACY_gbm_surface_release_buffer(windata->gs, windata->curr_bo); - windata->curr_bo = NULL; - } - - if (windata->next_bo) { - KMSDRM_LEGACY_gbm_surface_release_buffer(windata->gs, windata->next_bo); - windata->next_bo = NULL; - } - -#if SDL_VIDEO_OPENGL_EGL - SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - if (windata->egl_surface != EGL_NO_SURFACE) { - SDL_EGL_DestroySurface(_this, windata->egl_surface); - windata->egl_surface = EGL_NO_SURFACE; - } -#endif - - if (windata->gs) { - KMSDRM_LEGACY_gbm_surface_destroy(windata->gs); - windata->gs = NULL; - } -} - -int -KMSDRM_LEGACY_CreateSurfaces(_THIS, SDL_Window * window) -{ - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - SDL_WindowData *windata = (SDL_WindowData *)window->driverdata; - SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - Uint32 width = dispdata->mode.hdisplay; - Uint32 height = dispdata->mode.vdisplay; - Uint32 surface_fmt = GBM_FORMAT_XRGB8888; - Uint32 surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; -#if SDL_VIDEO_OPENGL_EGL - EGLContext egl_context; -#endif - - if (!KMSDRM_LEGACY_gbm_device_is_format_supported(viddata->gbm, surface_fmt, surface_flags)) { - SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway."); - } - -#if SDL_VIDEO_OPENGL_EGL - SDL_EGL_SetRequiredVisualId(_this, surface_fmt); - egl_context = (EGLContext)SDL_GL_GetCurrentContext(); -#endif - - KMSDRM_LEGACY_DestroySurfaces(_this, window); - - windata->gs = KMSDRM_LEGACY_gbm_surface_create(viddata->gbm, width, height, surface_fmt, surface_flags); - - if (!windata->gs) { - return SDL_SetError("Could not create GBM surface"); - } - -#if SDL_VIDEO_OPENGL_EGL - windata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)windata->gs); - - if (windata->egl_surface == EGL_NO_SURFACE) { - return SDL_SetError("Could not create EGL window surface"); - } - - SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context); - - windata->egl_surface_dirty = 0; -#endif - - return 0; -} - -int -KMSDRM_LEGACY_VideoInit(_THIS) -{ - int i, j, ret = 0; - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - SDL_DisplayData *dispdata = NULL; - drmModeRes *resources = NULL; - drmModeEncoder *encoder = NULL; - char devname[32]; - SDL_VideoDisplay display = {0}; - - dispdata = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData)); - - if (!dispdata) { - return SDL_OutOfMemory(); - } - - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_LEGACY_VideoInit()"); - - /* Open /dev/dri/cardNN */ - SDL_snprintf(devname, sizeof(devname), "/dev/dri/card%d", viddata->devindex); - - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opening device %s", devname); - viddata->drm_fd = open(devname, O_RDWR | O_CLOEXEC); - - if (viddata->drm_fd < 0) { - ret = SDL_SetError("Could not open %s", devname); - goto cleanup; - } - - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", viddata->drm_fd); - - viddata->gbm = KMSDRM_LEGACY_gbm_create_device(viddata->drm_fd); - if (!viddata->gbm) { - ret = SDL_SetError("Couldn't create gbm device."); - goto cleanup; - } - - /* Get all of the available connectors / devices / crtcs */ - resources = KMSDRM_LEGACY_drmModeGetResources(viddata->drm_fd); - if (!resources) { - ret = SDL_SetError("drmModeGetResources(%d) failed", viddata->drm_fd); - goto cleanup; - } - - for (i = 0; i < resources->count_connectors; i++) { - drmModeConnector *conn = KMSDRM_LEGACY_drmModeGetConnector(viddata->drm_fd, resources->connectors[i]); - - if (!conn) { - continue; - } - - if (conn->connection == DRM_MODE_CONNECTED && conn->count_modes) { - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.", - conn->connector_id, conn->count_modes); - dispdata->conn = conn; - break; - } - - KMSDRM_LEGACY_drmModeFreeConnector(conn); - } - - if (!dispdata->conn) { - ret = SDL_SetError("No currently active connector found."); - goto cleanup; - } - - /* Try to find the connector's current encoder */ - for (i = 0; i < resources->count_encoders; i++) { - encoder = KMSDRM_LEGACY_drmModeGetEncoder(viddata->drm_fd, resources->encoders[i]); - - if (!encoder) { - continue; - } - - if (encoder->encoder_id == dispdata->conn->encoder_id) { - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id); - break; - } - - KMSDRM_LEGACY_drmModeFreeEncoder(encoder); - encoder = NULL; - } - - if (!encoder) { - /* No encoder was connected, find the first supported one */ - for (i = 0; i < resources->count_encoders; i++) { - encoder = KMSDRM_LEGACY_drmModeGetEncoder(viddata->drm_fd, resources->encoders[i]); - - if (!encoder) { - continue; - } - - for (j = 0; j < dispdata->conn->count_encoders; j++) { - if (dispdata->conn->encoders[j] == encoder->encoder_id) { - break; - } - } - - if (j != dispdata->conn->count_encoders) { - break; - } - - KMSDRM_LEGACY_drmModeFreeEncoder(encoder); - encoder = NULL; - } - } - - if (!encoder) { - ret = SDL_SetError("No connected encoder found."); - goto cleanup; - } - - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id); - - /* Try to find a CRTC connected to this encoder */ - dispdata->saved_crtc = KMSDRM_LEGACY_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id); - - if (!dispdata->saved_crtc) { - /* No CRTC was connected, find the first CRTC that can be connected */ - for (i = 0; i < resources->count_crtcs; i++) { - if (encoder->possible_crtcs & (1 << i)) { - encoder->crtc_id = resources->crtcs[i]; - dispdata->saved_crtc = KMSDRM_LEGACY_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id); - break; - } - } - } - - if (!dispdata->saved_crtc) { - ret = SDL_SetError("No CRTC found."); - goto cleanup; - } - - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u", - dispdata->saved_crtc->crtc_id, dispdata->saved_crtc->buffer_id, dispdata->saved_crtc->x, - dispdata->saved_crtc->y, dispdata->saved_crtc->width, dispdata->saved_crtc->height); - - dispdata->crtc_id = encoder->crtc_id; - - /* Figure out the default mode to be set. If the current CRTC's mode isn't - valid, select the first mode supported by the connector - - FIXME find first mode that specifies DRM_MODE_TYPE_PREFERRED */ - dispdata->mode = dispdata->saved_crtc->mode; - - if (dispdata->saved_crtc->mode_valid == 0) { - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, - "Current mode is invalid, selecting connector's mode #0."); - dispdata->mode = dispdata->conn->modes[0]; - } - - /* Setup the single display that's available */ - - display.desktop_mode.w = dispdata->mode.hdisplay; - display.desktop_mode.h = dispdata->mode.vdisplay; - display.desktop_mode.refresh_rate = dispdata->mode.vrefresh; -#if 1 - display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888; -#else - /* FIXME */ - drmModeFB *fb = drmModeGetFB(viddata->drm_fd, dispdata->saved_crtc->buffer_id); - display.desktop_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth); - drmModeFreeFB(fb); -#endif - display.current_mode = display.desktop_mode; - display.driverdata = dispdata; - SDL_AddVideoDisplay(&display, SDL_FALSE); - -#ifdef SDL_INPUT_LINUXEV - SDL_EVDEV_Init(); -#endif - - KMSDRM_LEGACY_InitMouse(_this); - - return ret; - -cleanup: - if (encoder) - KMSDRM_LEGACY_drmModeFreeEncoder(encoder); - if (resources) - KMSDRM_LEGACY_drmModeFreeResources(resources); - - if (ret != 0) { - /* Error (complete) cleanup */ - if (dispdata->conn) { - KMSDRM_LEGACY_drmModeFreeConnector(dispdata->conn); - dispdata->conn = NULL; - } - if (dispdata->saved_crtc) { - KMSDRM_LEGACY_drmModeFreeCrtc(dispdata->saved_crtc); - dispdata->saved_crtc = NULL; - } - if (viddata->gbm) { - KMSDRM_LEGACY_gbm_device_destroy(viddata->gbm); - viddata->gbm = NULL; - } - if (viddata->drm_fd >= 0) { - close(viddata->drm_fd); - viddata->drm_fd = -1; - } - SDL_free(dispdata); - } - return ret; -} - -void -KMSDRM_LEGACY_VideoQuit(_THIS) -{ - SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); - - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_LEGACY_VideoQuit()"); - - if (_this->gl_config.driver_loaded) { - SDL_GL_UnloadLibrary(); - } - - /* Clear out the window list */ - SDL_free(viddata->windows); - viddata->windows = NULL; - viddata->max_windows = 0; - viddata->num_windows = 0; - - /* Restore saved CRTC settings */ - if (viddata->drm_fd >= 0 && dispdata && dispdata->conn && dispdata->saved_crtc) { - drmModeConnector *conn = dispdata->conn; - drmModeCrtc *crtc = dispdata->saved_crtc; - - int ret = KMSDRM_LEGACY_drmModeSetCrtc(viddata->drm_fd, crtc->crtc_id, crtc->buffer_id, - crtc->x, crtc->y, &conn->connector_id, 1, &crtc->mode); - - if (ret != 0) { - SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode"); - } - } - if (dispdata && dispdata->conn) { - KMSDRM_LEGACY_drmModeFreeConnector(dispdata->conn); - dispdata->conn = NULL; - } - if (dispdata && dispdata->saved_crtc) { - KMSDRM_LEGACY_drmModeFreeCrtc(dispdata->saved_crtc); - dispdata->saved_crtc = NULL; - } - if (viddata->gbm) { - KMSDRM_LEGACY_gbm_device_destroy(viddata->gbm); - viddata->gbm = NULL; - } - if (viddata->drm_fd >= 0) { - close(viddata->drm_fd); - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", viddata->drm_fd); - viddata->drm_fd = -1; - } -#ifdef SDL_INPUT_LINUXEV - SDL_EVDEV_Quit(); -#endif -} - -void -KMSDRM_LEGACY_GetDisplayModes(_THIS, SDL_VideoDisplay * display) -{ - SDL_DisplayData *dispdata = display->driverdata; - drmModeConnector *conn = dispdata->conn; - SDL_DisplayMode mode; - int i; - - for (i = 0; i < conn->count_modes; i++) { - SDL_DisplayModeData *modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData)); - - if (modedata) { - modedata->mode_index = i; - } - - mode.w = conn->modes[i].hdisplay; - mode.h = conn->modes[i].vdisplay; - mode.refresh_rate = conn->modes[i].vrefresh; - mode.format = SDL_PIXELFORMAT_ARGB8888; - mode.driverdata = modedata; - - if (!SDL_AddDisplayMode(display, &mode)) { - SDL_free(modedata); - } - } -} - -int -KMSDRM_LEGACY_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) -{ - SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; - SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; - SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; - drmModeConnector *conn = dispdata->conn; - int i; - - if (!modedata) { - return SDL_SetError("Mode doesn't have an associated index"); - } - - dispdata->mode = conn->modes[modedata->mode_index]; - - for (i = 0; i < viddata->num_windows; i++) { - SDL_Window *window = viddata->windows[i]; - SDL_WindowData *windata = (SDL_WindowData *)window->driverdata; - -#if SDL_VIDEO_OPENGL_EGL - /* Can't recreate EGL surfaces right now, need to wait until SwapWindow - so the correct thread-local surface and context state are available */ - windata->egl_surface_dirty = 1; -#else - if (KMSDRM_LEGACY_CreateSurfaces(_this, window)) { - return -1; - } -#endif - - /* Tell app about the resize */ - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode->w, mode->h); - } - - return 0; -} - -int -KMSDRM_LEGACY_CreateWindow(_THIS, SDL_Window * window) -{ - SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; - SDL_WindowData *windata; - SDL_VideoDisplay *display; - -#if SDL_VIDEO_OPENGL_EGL - if (!_this->egl_data) { - if (SDL_GL_LoadLibrary(NULL) < 0) { - goto error; - } - } -#endif - - /* Allocate window internal data */ - windata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); - - if (!windata) { - SDL_OutOfMemory(); - goto error; - } - - /* Windows have one size for now */ - display = SDL_GetDisplayForWindow(window); - window->w = display->desktop_mode.w; - window->h = display->desktop_mode.h; - - /* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */ - window->flags |= (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL); - - /* In case we want low-latency, double-buffer video, we take note here */ - windata->double_buffer = SDL_FALSE; - - if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) { - windata->double_buffer = SDL_TRUE; - } - - /* Setup driver data for this window */ - windata->viddata = viddata; - window->driverdata = windata; - - if (KMSDRM_LEGACY_CreateSurfaces(_this, window)) { - goto error; - } - - /* Add window to the internal list of tracked windows. Note, while it may - seem odd to support multiple fullscreen windows, some apps create an - extra window as a dummy surface when working with multiple contexts */ - if (viddata->num_windows >= viddata->max_windows) { - int new_max_windows = viddata->max_windows + 1; - viddata->windows = (SDL_Window **)SDL_realloc(viddata->windows, - new_max_windows * sizeof(SDL_Window *)); - viddata->max_windows = new_max_windows; - - if (!viddata->windows) { - SDL_OutOfMemory(); - goto error; - } - } - - viddata->windows[viddata->num_windows++] = window; - - /* Focus on the newly created window */ - SDL_SetMouseFocus(window); - SDL_SetKeyboardFocus(window); - - return 0; - -error: - KMSDRM_LEGACY_DestroyWindow(_this, window); - - return -1; -} - -void -KMSDRM_LEGACY_DestroyWindow(_THIS, SDL_Window * window) -{ - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; - SDL_VideoData *viddata; - int i, j; - - if (!windata) { - return; - } - - /* Remove from the internal window list */ - viddata = windata->viddata; - - for (i = 0; i < viddata->num_windows; i++) { - if (viddata->windows[i] == window) { - viddata->num_windows--; - - for (j = i; j < viddata->num_windows; j++) { - viddata->windows[j] = viddata->windows[j + 1]; - } - - break; - } - } - - KMSDRM_LEGACY_DestroySurfaces(_this, window); - - window->driverdata = NULL; - - SDL_free(windata); -} - -int -KMSDRM_LEGACY_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) -{ - return -1; -} - -void -KMSDRM_LEGACY_SetWindowTitle(_THIS, SDL_Window * window) -{ -} -void -KMSDRM_LEGACY_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) -{ -} -void -KMSDRM_LEGACY_SetWindowPosition(_THIS, SDL_Window * window) -{ -} -void -KMSDRM_LEGACY_SetWindowSize(_THIS, SDL_Window * window) -{ -} -void -KMSDRM_LEGACY_ShowWindow(_THIS, SDL_Window * window) -{ -} -void -KMSDRM_LEGACY_HideWindow(_THIS, SDL_Window * window) -{ -} -void -KMSDRM_LEGACY_RaiseWindow(_THIS, SDL_Window * window) -{ -} -void -KMSDRM_LEGACY_MaximizeWindow(_THIS, SDL_Window * window) -{ -} -void -KMSDRM_LEGACY_MinimizeWindow(_THIS, SDL_Window * window) -{ -} -void -KMSDRM_LEGACY_RestoreWindow(_THIS, SDL_Window * window) -{ -} -void -KMSDRM_LEGACY_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) -{ - -} - -/*****************************************************************************/ -/* SDL Window Manager function */ -/*****************************************************************************/ -SDL_bool -KMSDRM_LEGACY_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) -{ - if (info->version.major <= SDL_MAJOR_VERSION) { - return SDL_TRUE; - } else { - SDL_SetError("application not compiled with SDL %d.%d\n", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); - return SDL_FALSE; - } - - /* Failed to get window manager information */ - return SDL_FALSE; -} - -#endif /* SDL_VIDEO_DRIVER_KMSDRM */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_video.h b/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_video.h deleted file mode 100644 index 28e1bc4fe..000000000 --- a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_video.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -#ifndef __SDL_KMSDRM_LEGACYVIDEO_H__ -#define __SDL_KMSDRM_LEGACYVIDEO_H__ - -#include "../SDL_sysvideo.h" - -#include -#include -#include -#include -#include -#if SDL_VIDEO_OPENGL_EGL -#include -#endif - -typedef struct SDL_VideoData -{ - int devindex; /* device index that was passed on creation */ - int drm_fd; /* DRM file desc */ - struct gbm_device *gbm; - - SDL_Window **windows; - int max_windows; - int num_windows; -} SDL_VideoData; - - -typedef struct SDL_DisplayModeData -{ - int mode_index; -} SDL_DisplayModeData; - - -typedef struct SDL_DisplayData -{ - uint32_t crtc_id; - drmModeConnector *conn; - drmModeModeInfo mode; - drmModeCrtc *saved_crtc; /* CRTC to restore on quit */ -} SDL_DisplayData; - - -typedef struct SDL_WindowData -{ - SDL_VideoData *viddata; - struct gbm_surface *gs; - struct gbm_bo *curr_bo; - struct gbm_bo *next_bo; - struct gbm_bo *crtc_bo; - SDL_bool waiting_for_flip; - SDL_bool double_buffer; -#if SDL_VIDEO_OPENGL_EGL - int egl_surface_dirty; - EGLSurface egl_surface; -#endif -} SDL_WindowData; - -typedef struct KMSDRM_LEGACY_FBInfo -{ - int drm_fd; /* DRM file desc */ - uint32_t fb_id; /* DRM framebuffer ID */ -} KMSDRM_LEGACY_FBInfo; - -/* Helper functions */ -int KMSDRM_LEGACY_CreateSurfaces(_THIS, SDL_Window * window); -KMSDRM_LEGACY_FBInfo *KMSDRM_LEGACY_FBFromBO(_THIS, struct gbm_bo *bo); -SDL_bool KMSDRM_LEGACY_WaitPageFlip(_THIS, SDL_WindowData *windata, int timeout); - -/****************************************************************************/ -/* SDL_VideoDevice functions declaration */ -/****************************************************************************/ - -/* Display and window functions */ -int KMSDRM_LEGACY_VideoInit(_THIS); -void KMSDRM_LEGACY_VideoQuit(_THIS); -void KMSDRM_LEGACY_GetDisplayModes(_THIS, SDL_VideoDisplay * display); -int KMSDRM_LEGACY_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); -int KMSDRM_LEGACY_CreateWindow(_THIS, SDL_Window * window); -int KMSDRM_LEGACY_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); -void KMSDRM_LEGACY_SetWindowTitle(_THIS, SDL_Window * window); -void KMSDRM_LEGACY_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); -void KMSDRM_LEGACY_SetWindowPosition(_THIS, SDL_Window * window); -void KMSDRM_LEGACY_SetWindowSize(_THIS, SDL_Window * window); -void KMSDRM_LEGACY_ShowWindow(_THIS, SDL_Window * window); -void KMSDRM_LEGACY_HideWindow(_THIS, SDL_Window * window); -void KMSDRM_LEGACY_RaiseWindow(_THIS, SDL_Window * window); -void KMSDRM_LEGACY_MaximizeWindow(_THIS, SDL_Window * window); -void KMSDRM_LEGACY_MinimizeWindow(_THIS, SDL_Window * window); -void KMSDRM_LEGACY_RestoreWindow(_THIS, SDL_Window * window); -void KMSDRM_LEGACY_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); -void KMSDRM_LEGACY_DestroyWindow(_THIS, SDL_Window * window); - -/* Window manager function */ -SDL_bool KMSDRM_LEGACY_GetWindowWMInfo(_THIS, SDL_Window * window, - struct SDL_SysWMinfo *info); - -/* OpenGL/OpenGL ES functions */ -int KMSDRM_LEGACY_GLES_LoadLibrary(_THIS, const char *path); -void *KMSDRM_LEGACY_GLES_GetProcAddress(_THIS, const char *proc); -void KMSDRM_LEGACY_GLES_UnloadLibrary(_THIS); -SDL_GLContext KMSDRM_LEGACY_GLES_CreateContext(_THIS, SDL_Window * window); -int KMSDRM_LEGACY_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); -int KMSDRM_LEGACY_GLES_SetSwapInterval(_THIS, int interval); -int KMSDRM_LEGACY_GLES_GetSwapInterval(_THIS); -int KMSDRM_LEGACY_GLES_SwapWindow(_THIS, SDL_Window * window); -void KMSDRM_LEGACY_GLES_DeleteContext(_THIS, SDL_GLContext context); - -#endif /* __SDL_KMSDRM_LEGACYVIDEO_H__ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/nacl/SDL_naclevents.c b/Engine/lib/sdl/src/video/nacl/SDL_naclevents.c index 44f47ec23..142d0c1f9 100644 --- a/Engine/lib/sdl/src/video/nacl/SDL_naclevents.c +++ b/Engine/lib/sdl/src/video/nacl/SDL_naclevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/nacl/SDL_naclevents_c.h b/Engine/lib/sdl/src/video/nacl/SDL_naclevents_c.h index 555f6a454..e8d44f41b 100644 --- a/Engine/lib/sdl/src/video/nacl/SDL_naclevents_c.h +++ b/Engine/lib/sdl/src/video/nacl/SDL_naclevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/nacl/SDL_naclglue.c b/Engine/lib/sdl/src/video/nacl/SDL_naclglue.c index 13618478e..ac1e16029 100644 --- a/Engine/lib/sdl/src/video/nacl/SDL_naclglue.c +++ b/Engine/lib/sdl/src/video/nacl/SDL_naclglue.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/nacl/SDL_naclopengles.c b/Engine/lib/sdl/src/video/nacl/SDL_naclopengles.c index 0bd9b13c2..ca5b75f99 100644 --- a/Engine/lib/sdl/src/video/nacl/SDL_naclopengles.c +++ b/Engine/lib/sdl/src/video/nacl/SDL_naclopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,7 +27,7 @@ #include "SDL_video.h" #include "SDL_naclvideo.h" -#if SDL_LOADSO_DLOPEN +#ifdef HAVE_DLOPEN #include "dlfcn.h" #endif @@ -45,7 +45,7 @@ NACL_GLES_LoadLibrary(_THIS, const char *path) void * NACL_GLES_GetProcAddress(_THIS, const char *proc) { -#if SDL_LOADSO_DLOPEN +#ifdef HAVE_DLOPEN return dlsym( 0 /* RTLD_DEFAULT */, proc); #else return NULL; diff --git a/Engine/lib/sdl/src/video/nacl/SDL_naclopengles.h b/Engine/lib/sdl/src/video/nacl/SDL_naclopengles.h index b785101e6..a3fee1f5b 100644 --- a/Engine/lib/sdl/src/video/nacl/SDL_naclopengles.h +++ b/Engine/lib/sdl/src/video/nacl/SDL_naclopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/nacl/SDL_naclvideo.c b/Engine/lib/sdl/src/video/nacl/SDL_naclvideo.c index 74e2c294a..96901e899 100644 --- a/Engine/lib/sdl/src/video/nacl/SDL_naclvideo.c +++ b/Engine/lib/sdl/src/video/nacl/SDL_naclvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/nacl/SDL_naclvideo.h b/Engine/lib/sdl/src/video/nacl/SDL_naclvideo.h index 613dd61a1..3b0892049 100644 --- a/Engine/lib/sdl/src/video/nacl/SDL_naclvideo.h +++ b/Engine/lib/sdl/src/video/nacl/SDL_naclvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/nacl/SDL_naclwindow.c b/Engine/lib/sdl/src/video/nacl/SDL_naclwindow.c index 979abcd63..f0245aef2 100644 --- a/Engine/lib/sdl/src/video/nacl/SDL_naclwindow.c +++ b/Engine/lib/sdl/src/video/nacl/SDL_naclwindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,8 +35,7 @@ NACL_CreateWindow(_THIS, SDL_Window * window) SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata; if (driverdata->window) { - SDL_SetError("NaCl only supports one window"); - return -1; + return SDL_SetError("NaCl only supports one window"); } driverdata->window = window; diff --git a/Engine/lib/sdl/src/video/nacl/SDL_naclwindow.h b/Engine/lib/sdl/src/video/nacl/SDL_naclwindow.h index 5726fcab2..65757c412 100644 --- a/Engine/lib/sdl/src/video/nacl/SDL_naclwindow.h +++ b/Engine/lib/sdl/src/video/nacl/SDL_naclwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenevents.c b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenevents.c index e24d954a4..a14e0b277 100644 --- a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenevents.c +++ b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenevents_c.h b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenevents_c.h index 768fb24f7..3d2614952 100644 --- a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenevents_c.h +++ b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenframebuffer.c b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenframebuffer.c index 93fa36807..3ca57e897 100644 --- a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenframebuffer.c +++ b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,17 +34,13 @@ int SDL_OFFSCREEN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * f SDL_Surface *surface; const Uint32 surface_format = SDL_PIXELFORMAT_RGB888; int w, h; - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; /* Free the old framebuffer surface */ - surface = (SDL_Surface *) SDL_GetWindowData(window, OFFSCREEN_SURFACE); - SDL_FreeSurface(surface); + SDL_OFFSCREEN_DestroyWindowFramebuffer(_this, window); /* Create a new one */ - SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); SDL_GetWindowSize(window, &w, &h); - surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask); + surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, surface_format); if (!surface) { return -1; } diff --git a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenframebuffer_c.h b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenframebuffer_c.h index d8577c914..82ae06c92 100644 --- a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenframebuffer_c.h +++ b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenframebuffer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenopengl.c b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenopengl.c index 92e37f2e6..87641520e 100644 --- a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenopengl.c +++ b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenopengl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -66,7 +66,13 @@ OFFSCREEN_GL_LoadLibrary(_THIS, const char* path) return ret; } + /* driver_loaded gets incremented by SDL_GL_LoadLibrary when we return, + but SDL_EGL_InitializeOffscreen checks that we're loaded before then, + so temporarily bump it since we know that LoadLibraryOnly succeeded. */ + + _this->gl_config.driver_loaded++; ret = SDL_EGL_InitializeOffscreen(_this, 0); + _this->gl_config.driver_loaded--; if (ret != 0) { return ret; } diff --git a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenopengl.h b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenopengl.h index 7dfd7f3f4..1e2df6940 100644 --- a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenopengl.h +++ b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenopengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenvideo.c b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenvideo.c index 35fc3e003..19c7cb5e5 100644 --- a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenvideo.c +++ b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenvideo.h b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenvideo.h index 843c34d43..eae512bbd 100644 --- a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenvideo.h +++ b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenwindow.c b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenwindow.c index 19e0097ac..6697b016a 100644 --- a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenwindow.c +++ b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenwindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenwindow.h b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenwindow.h index e8802c6b1..74c85d26c 100644 --- a/Engine/lib/sdl/src/video/offscreen/SDL_offscreenwindow.h +++ b/Engine/lib/sdl/src/video/offscreen/SDL_offscreenwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/os2/my_gradd.h b/Engine/lib/sdl/src/video/os2/SDL_gradd.h similarity index 99% rename from Engine/lib/sdl/src/video/os2/my_gradd.h rename to Engine/lib/sdl/src/video/os2/SDL_gradd.h index 3f0f3265d..a1369a260 100644 --- a/Engine/lib/sdl/src/video/os2/my_gradd.h +++ b/Engine/lib/sdl/src/video/os2/SDL_gradd.h @@ -5,8 +5,8 @@ Based on public knowledge from around the internet including pages from http://www.osfree.org and http://www.edm2.com */ -#ifndef my_gradd_h_ -#define my_gradd_h_ +#ifndef SDL_gradd_h_ +#define SDL_gradd_h_ typedef struct _INITPROCOUT { ULONG ulLength; /* Length of the INITPROCOUT data structure, in bytes. */ @@ -168,4 +168,4 @@ LONG GreResurrection(HDC hdc, LONG cbVmem, PULONG pReserved, PVOID pInstance, LO ULONG _System Gre32Entry3(ULONG, ULONG, ULONG); ULONG _System Gre32Entry5(ULONG, ULONG, ULONG, ULONG, ULONG); -#endif /* my_gradd_h_ */ +#endif /* SDL_gradd_h_ */ diff --git a/Engine/lib/sdl/src/video/os2/SDL_os2dive.c b/Engine/lib/sdl/src/video/os2/SDL_os2dive.c index f7d6b294e..95aae6f05 100644 --- a/Engine/lib/sdl/src/video/os2/SDL_os2dive.c +++ b/Engine/lib/sdl/src/video/os2/SDL_os2dive.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -67,10 +67,12 @@ OS2VIDEOOUTPUT voDive = { static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo) { - DIVE_CAPS sDiveCaps = { 0 }; - FOURCC fccFormats[100] = { 0 }; + DIVE_CAPS sDiveCaps; + FOURCC fccFormats[100]; /* Query information about display hardware from DIVE. */ + SDL_zeroa(fccFormats); + SDL_zero(sDiveCaps); sDiveCaps.pFormatData = fccFormats; sDiveCaps.ulFormatLength = 100; sDiveCaps.ulStructLen = sizeof(DIVE_CAPS); @@ -172,7 +174,7 @@ static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd, /* Setup DIVE blitter. */ SETUP_BLITTER sSetupBlitter; SWP swp; - POINTL pointl = { 0 }; + POINTL pointl = { 0,0 }; WinQueryWindowPos(hwnd, &swp); WinMapWindowPoints(hwnd, HWND_DESKTOP, &pointl, 1); @@ -302,10 +304,10 @@ static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, debug_os2("Not enough stack size"); return FALSE; } - memset(pbLineMask, 0, pVOData->ulHeight); + SDL_memset(pbLineMask, 0, pVOData->ulHeight); for ( ; ((LONG)cSDLRects) > 0; cSDLRects--, pSDLRects++) { - memset(&pbLineMask[pSDLRects->y], 1, pSDLRects->h); + SDL_memset(&pbLineMask[pSDLRects->y], 1, pSDLRects->h); } ulRC = DiveBlitImageLines(pVOData->hDive, pVOData->ulDIVEBufNum, diff --git a/Engine/lib/sdl/src/video/os2/SDL_os2messagebox.c b/Engine/lib/sdl/src/video/os2/SDL_os2messagebox.c index e3b92672d..c904fa5cb 100644 --- a/Engine/lib/sdl/src/video/os2/SDL_os2messagebox.c +++ b/Engine/lib/sdl/src/video/os2/SDL_os2messagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,8 +35,8 @@ #define IDD_PB_FIRST 1003 typedef struct _MSGBOXDLGDATA { - USHORT cb; - HWND hwndUnder; + USHORT cb; + HWND hwndUnder; } MSGBOXDLGDATA; static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData) @@ -57,8 +57,8 @@ static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData) HWND hwnd; /* Button window handle. */ ULONG ulCX; /* Button width in dialog coordinates. */ } aButtons[32]; - RECTL rectlItem; - HAB hab = WinQueryAnchorBlock(hwnd); + RECTL rectlItem; + HAB hab = WinQueryAnchorBlock(hwnd); /* --- Align the buttons to the right/bottom. --- */ @@ -66,10 +66,10 @@ static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData) hEnum = WinBeginEnumWindows(hwnd); while ((hWndNext = WinGetNextWindow(hEnum)) != NULLHANDLE) { - if (WinQueryClassName(hWndNext, sizeof(acBuf), acBuf) == 0) + if (WinQueryClassName(hWndNext, sizeof(acBuf), acBuf) == 0) { continue; - - if (strcmp(acBuf, "#3") == 0) { /* Class name of button. */ + } + if (SDL_strcmp(acBuf, "#3") == 0) { /* Class name of button. */ if (cButtons < sizeof(aButtons) / sizeof(struct _BUTTON)) { aButtons[cButtons].hwnd = hWndNext; cButtons++; @@ -92,7 +92,7 @@ static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData) /* Convert text size to dialog coordinates. */ WinMapDlgPoints(hwnd, &aptText[TXTBOX_TOPRIGHT], 1, FALSE); /* Add vertical and horizontal space for button's frame (dialog coord.). */ - if (aptText[TXTBOX_TOPRIGHT].x < 30) {/* Minimal button width. */ + if (aptText[TXTBOX_TOPRIGHT].x < 30) { /* Minimal button width. */ aptText[TXTBOX_TOPRIGHT].x = 30; } else { aptText[TXTBOX_TOPRIGHT].x += 4; @@ -176,7 +176,7 @@ static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData) SWP_MOVE | SWP_SIZE); } -MRESULT EXPENTRY DynDlgProc(HWND hwnd, USHORT message, MPARAM mp1, MPARAM mp2) +static MRESULT EXPENTRY DynDlgProc(HWND hwnd, USHORT message, MPARAM mp1, MPARAM mp2) { switch (message) { case WM_INITDLG: @@ -205,10 +205,10 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata) pSDLBtnData = (SDL_MessageBoxButtonData *)messageboxdata->buttons; ULONG cSDLBtnData = messageboxdata->numbuttons; - PSZ pszTitle = OS2_UTF8ToSys((PSZ) messageboxdata->title); - ULONG cbTitle = (pszTitle == NULL)? 0 : strlen(pszTitle); - PSZ pszText = OS2_UTF8ToSys((PSZ) messageboxdata->message); - ULONG cbText = (pszText == NULL)? 0 : strlen(pszText); + PSZ pszTitle = OS2_UTF8ToSys(messageboxdata->title); + ULONG cbTitle = (pszTitle == NULL)? 1 : (SDL_strlen(pszTitle) + 1); + PSZ pszText = OS2_UTF8ToSys(messageboxdata->message); + ULONG cbText = (pszText == NULL)? 1 : (SDL_strlen(pszText) + 1); PDLGTEMPLATE pTemplate; ULONG cbTemplate; @@ -218,28 +218,34 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata) PSZ pszBtnText; ULONG cbBtnText; HWND hwnd; + const SDL_MessageBoxColor* pSDLColors = (messageboxdata->colorScheme == NULL)? NULL : messageboxdata->colorScheme->colors; const SDL_MessageBoxColor* pSDLColor; + MSGBOXDLGDATA stDlgData; /* Build a dialog tamplate in memory */ - /* Size of template (cbTemplate). */ + /* Size of template */ cbTemplate = sizeof(DLGTEMPLATE) + ((2 + cSDLBtnData) * sizeof(DLGTITEM)) + sizeof(ULONG) + /* First item data - frame control data. */ - cbTitle + 1 + /* First item data - frame title + ZERO. */ - cbText + 1 + /* Second item data - ststic text + ZERO.*/ + cbTitle + /* First item data - frame title + ZERO. */ + cbText + /* Second item data - ststic text + ZERO.*/ 3; /* Third item data - system icon Id. */ + /* Button items datas - text for buttons. */ for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) { pszBtnText = (PSZ)pSDLBtnData[ulIdx].text; - cbTemplate += (pszBtnText == NULL)? 1 : (strlen(pszBtnText) + 1); + cbTemplate += (pszBtnText == NULL)? 1 : (SDL_strlen(pszBtnText) + 1); } + /* Presentation parameter space. */ - if (pSDLColors != NULL) - cbTemplate += 26 /* PP for frame. */ + 26 /* PP for static text. */ + + if (pSDLColors != NULL) { + cbTemplate += 26 /* PP for frame. */ + + 26 /* PP for static text. */ + (48 * cSDLBtnData); /* PP for buttons. */ + } /* Allocate memory for the dialog template. */ pTemplate = (PDLGTEMPLATE) SDL_malloc(cbTemplate); @@ -268,11 +274,11 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata) pDlgItem->cchClassName = 0; pDlgItem->offClassName = (USHORT)WC_FRAME; /* Length of text. */ - pDlgItem->cchText = cbTitle + 1; /* +1 - trailing ZERO. */ + pDlgItem->cchText = cbTitle; pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to title text. */ /* Copy text for the title into the dialog template. */ if (pszTitle != NULL) { - strcpy(pcDlgData, pszTitle); + SDL_memcpy(pcDlgData, pszTitle, cbTitle); } else { *pcDlgData = '\0'; } @@ -322,13 +328,13 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata) pDlgItem->cchClassName = 0; pDlgItem->offClassName = (USHORT)WC_STATIC; - pDlgItem->cchText = cbText + 1; + pDlgItem->cchText = cbText; pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */ /* Copy message text into the dialog template. */ if (pszText != NULL) { - strcpy(pcDlgData, pszText); + SDL_memcpy(pcDlgData, pszText, cbText); } else { - *pcDlgData = '\0'; + *pcDlgData = '\0'; } pcDlgData += pDlgItem->cchText; @@ -339,7 +345,7 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata) pDlgItem->cx = 147; pDlgItem->cy = 62; /* It will be used. */ - pDlgItem->id = IDD_TEXT_MESSAGE; /* an ID value */ + pDlgItem->id = IDD_TEXT_MESSAGE; /* an ID value */ if (pSDLColors == NULL) pDlgItem->offPresParams = 0; else { @@ -371,8 +377,8 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata) pDlgItem->cchText = 3; /* 0xFF, low byte of the icon Id, high byte of icon Id. */ pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the Id. */ - /* Write susyem icon ID into dialog template. */ - *pcDlgData = 0xFF; /* First byte is 0xFF - next 2 bytes is system pointer Id. */ + /* Write system icon ID into dialog template. */ + *((PBYTE)pcDlgData) = 0xFF; /* First byte is 0xFF, next 2 are system pointer Id. */ pcDlgData++; *((PUSHORT)pcDlgData) = ((messageboxdata->flags & SDL_MESSAGEBOX_ERROR) != 0)? SPTR_ICONERROR : @@ -400,13 +406,13 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata) pDlgItem->cchClassName = 0; /* 0 - offClassname is WC_ constant. */ pDlgItem->offClassName = (USHORT)WC_BUTTON; - pszBtnText = OS2_UTF8ToSys((PSZ)pSDLBtnData[ulIdx].text); - cbBtnText = (pszBtnText == NULL)? 0 : strlen(pszBtnText); - pDlgItem->cchText = cbBtnText + 1; + pszBtnText = OS2_UTF8ToSys(pSDLBtnData[ulIdx].text); + cbBtnText = (pszBtnText == NULL)? 1 : (SDL_strlen(pszBtnText) + 1); + pDlgItem->cchText = cbBtnText; pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */ /* Copy text for the button into the dialog template. */ if (pszBtnText != NULL) { - strcpy(pcDlgData, pszBtnText); + SDL_memcpy(pcDlgData, pszBtnText, cbBtnText); } else { *pcDlgData = '\0'; } @@ -430,7 +436,7 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata) pDlgItem->id = IDD_PB_FIRST + ulIdx; /* an ID value */ if (pSDLColors == NULL) - pDlgItem->offPresParams = 0; + pDlgItem->offPresParams = 0; else { /* Presentation parameter for the button - dialog colors. */ pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate; diff --git a/Engine/lib/sdl/src/video/os2/SDL_os2messagebox.h b/Engine/lib/sdl/src/video/os2/SDL_os2messagebox.h index 9f81986d0..c3b8969df 100644 --- a/Engine/lib/sdl/src/video/os2/SDL_os2messagebox.h +++ b/Engine/lib/sdl/src/video/os2/SDL_os2messagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/os2/SDL_os2mouse.c b/Engine/lib/sdl/src/video/os2/SDL_os2mouse.c index 3ba1c5202..dd0b7c193 100644 --- a/Engine/lib/sdl/src/video/os2/SDL_os2mouse.c +++ b/Engine/lib/sdl/src/video/os2/SDL_os2mouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/os2/SDL_os2mouse.h b/Engine/lib/sdl/src/video/os2/SDL_os2mouse.h index 30b21d66d..52f5ba3f7 100644 --- a/Engine/lib/sdl/src/video/os2/SDL_os2mouse.h +++ b/Engine/lib/sdl/src/video/os2/SDL_os2mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/os2/SDL_os2output.h b/Engine/lib/sdl/src/video/os2/SDL_os2output.h index bc3d2a6b2..7ded650e9 100644 --- a/Engine/lib/sdl/src/video/os2/SDL_os2output.h +++ b/Engine/lib/sdl/src/video/os2/SDL_os2output.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/os2/SDL_os2util.c b/Engine/lib/sdl/src/video/os2/SDL_os2util.c index 6ed0bd98c..bcc6c54e8 100644 --- a/Engine/lib/sdl/src/video/os2/SDL_os2util.c +++ b/Engine/lib/sdl/src/video/os2/SDL_os2util.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,8 +27,8 @@ HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY) { HBITMAP hbm; - BITMAPINFOHEADER2 bmih = { 0 }; - BITMAPINFO bmi = { 0 }; + BITMAPINFOHEADER2 bmih; + BITMAPINFO bmi; HPS hps; PULONG pulBitmap; PULONG pulDst, pulSrc, pulDstMask; @@ -40,7 +40,7 @@ HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY) return NULLHANDLE; } - pulBitmap = SDL_malloc(surface->h * surface->w * 4 * 2); + pulBitmap = (PULONG) SDL_malloc(surface->h * surface->w * 2 * sizeof(ULONG)); if (pulBitmap == NULL) { SDL_OutOfMemory(); return NULLHANDLE; @@ -72,6 +72,9 @@ HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY) } /* Create system bitmap object. */ + SDL_zero(bmih); + SDL_zero(bmi); + bmih.cbFix = sizeof(BITMAPINFOHEADER2); bmih.cx = surface->w; bmih.cy = 2 * surface->h; diff --git a/Engine/lib/sdl/src/video/os2/SDL_os2util.h b/Engine/lib/sdl/src/video/os2/SDL_os2util.h index c60d9faaa..9379dec54 100644 --- a/Engine/lib/sdl/src/video/os2/SDL_os2util.h +++ b/Engine/lib/sdl/src/video/os2/SDL_os2util.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/os2/SDL_os2video.c b/Engine/lib/sdl/src/video/os2/SDL_os2video.c index 76a9696b0..64731d71d 100644 --- a/Engine/lib/sdl/src/video/os2/SDL_os2video.c +++ b/Engine/lib/sdl/src/video/os2/SDL_os2video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -133,7 +133,7 @@ static BOOL _getSDLPixelFormatData(SDL_PixelFormat *pSDLPixelFormat, default: /* printf("Unknown color encoding: %.4s\n", fccColorEncoding);*/ - memset(pSDLPixelFormat, 0, sizeof(SDL_PixelFormat)); + SDL_memset(pSDLPixelFormat, 0, sizeof(SDL_PixelFormat)); return FALSE; } @@ -183,7 +183,7 @@ static VOID _mouseCheck(WINDATA *pWinData) { SDL_Mouse *pSDLMouse = SDL_GetMouse(); - if ((pSDLMouse->relative_mode || (pWinData->window->flags & SDL_WINDOW_INPUT_GRABBED) != 0) && + if ((pSDLMouse->relative_mode || (pWinData->window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) && ((pWinData->window->flags & SDL_WINDOW_INPUT_FOCUS) != 0)) { /* We will make a real capture in _wmMouseButton() */ } else { @@ -232,7 +232,7 @@ static VOID _wmMouseMove(WINDATA *pWinData, SHORT lX, SHORT lY) if (!pSDLMouse->relative_mode || pSDLMouse->relative_mode_warp) { if (!pSDLMouse->relative_mode && fWinActive && - ((pWinData->window->flags & SDL_WINDOW_INPUT_GRABBED) != 0) && + ((pWinData->window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) && (WinQueryCapture(HWND_DESKTOP) == pWinData->hwnd)) { pointl.x = lX; @@ -281,7 +281,7 @@ static VOID _wmMouseButton(WINDATA *pWinData, ULONG ulButton, BOOL fDown) SDL_BUTTON_MIDDLE }; SDL_Mouse *pSDLMouse = SDL_GetMouse(); - if ((pSDLMouse->relative_mode || ((pWinData->window->flags & SDL_WINDOW_INPUT_GRABBED) != 0)) && + if ((pSDLMouse->relative_mode || ((pWinData->window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0)) && ((pWinData->window->flags & SDL_WINDOW_INPUT_FOCUS) != 0) && (WinQueryCapture(HWND_DESKTOP) != pWinData->hwnd)) { /* Mouse should be captured. */ @@ -320,17 +320,22 @@ static VOID _wmChar(WINDATA *pWinData, MPARAM mp1, MPARAM mp2) } if ((ulFlags & KC_CHAR) != 0) { - CHAR acUTF8[4]; - LONG lRC = StrUTF8(1, acUTF8, sizeof(acUTF8), (PSZ)&ulCharCode, 1); - - SDL_SendKeyboardText((lRC > 0)? acUTF8 : (PSZ)&ulCharCode); +#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) + char *utf8 = SDL_iconv_string("UTF-8", "", (char *)&ulCharCode, 1); + SDL_SendKeyboardText((utf8 && *utf8) ? utf8 : (char *)&ulCharCode); + SDL_free(utf8); +#else + char utf8[4]; + int rc = StrUTF8(1, utf8, sizeof(utf8), (char *)&ulCharCode, 1); + SDL_SendKeyboardText((rc > 0) ? utf8 : (char *) &ulCharCode); +#endif } } static VOID _wmMove(WINDATA *pWinData) { SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow(pWinData->window); - POINTL pointl = { 0 }; + POINTL pointl = { 0,0 }; RECTL rectl; WinQueryWindowRect(pWinData->hwnd, &rectl); @@ -389,7 +394,7 @@ static MRESULT _wmDrop(WINDATA *pWinData, PDRAGINFO pDragInfo) { ULONG ulIdx; PDRAGITEM pDragItem; - CHAR acFName[_MAX_PATH]; + CHAR acFName[CCHMAXPATH]; PCHAR pcFName; if (!DrgAccessDraginfo(pDragInfo)) @@ -403,7 +408,7 @@ static MRESULT _wmDrop(WINDATA *pWinData, PDRAGINFO pDragInfo) pDragItem->hstrSourceName != NULLHANDLE) { /* Get file name from the item. */ DrgQueryStrName(pDragItem->hstrContainerName, sizeof(acFName), acFName); - pcFName = strchr(acFName, '\0'); + pcFName = SDL_strchr(acFName, '\0'); DrgQueryStrName(pDragItem->hstrSourceName, sizeof(acFName) - (pcFName - acFName), pcFName); @@ -428,7 +433,7 @@ static MRESULT _wmDrop(WINDATA *pWinData, PDRAGINFO pDragInfo) return (MRESULT)FALSE; } -MRESULT EXPENTRY wndFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) +static MRESULT EXPENTRY wndFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { HWND hwndClient = WinQueryWindow(hwnd, QW_BOTTOM); WINDATA * pWinData = (WINDATA *)WinQueryWindowULong(hwndClient, 0); @@ -535,7 +540,7 @@ MRESULT EXPENTRY wndFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) return pWinData->fnWndFrameProc(hwnd, msg, mp1, mp2); } -MRESULT EXPENTRY wndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) +static MRESULT EXPENTRY wndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { WINDATA *pWinData = (WINDATA *)WinQueryWindowULong(hwnd, 0); @@ -589,7 +594,7 @@ MRESULT EXPENTRY wndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) WinQueryPointerPos(HWND_DESKTOP, &pointl); WinMapWindowPoints(HWND_DESKTOP, pWinData->hwnd, &pointl, 1); SDL_SendMouseMotion(pWinData->window, 0, 0, - pointl.x, pWinData->window->h - pointl.y - 1); + pointl.x, pWinData->window->h - pointl.y - 1); } else { if (SDL_GetKeyboardFocus() == pWinData->window) SDL_SetKeyboardFocus(NULL); @@ -691,7 +696,7 @@ MRESULT EXPENTRY wndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) } -/* SDL routnes. +/* SDL routines. * ------------ */ @@ -1147,7 +1152,7 @@ static int OS2_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) return 0; } -static void OS2_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +static void OS2_SetWindowMouseGrab(_THIS, SDL_Window *window, SDL_bool grabbed) { WINDATA *pWinData = (WINDATA *)window->driverdata; @@ -1214,7 +1219,7 @@ static int OS2_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, { SDL_ShapeTree *pShapeTree; WINDATA *pWinData; - SHAPERECTS stShapeRects = { 0 }; + SHAPERECTS stShapeRects; HPS hps; debug_os2("Enter"); @@ -1230,6 +1235,7 @@ static int OS2_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, pShapeTree = SDL_CalculateShapeTree(*shape_mode, shape); shaper->driverdata = pShapeTree; + SDL_zero(stShapeRects); stShapeRects.ulWinHeight = shaper->window->h; SDL_TraverseShapeTree(pShapeTree, &_combineRectRegions, &stShapeRects); @@ -1343,9 +1349,9 @@ static int OS2_SetClipboardText(_THIS, const char *text) debug_os2("Enter"); if (pszText == NULL) return -1; - cbText = SDL_strlen(pszText); + cbText = SDL_strlen(pszText) + 1; - ulRC = DosAllocSharedMem((PPVOID)&pszClipboard, 0, cbText + 1, + ulRC = DosAllocSharedMem((PPVOID)&pszClipboard, 0, cbText, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE | OBJ_GETTABLE | OBJ_TILE); if (ulRC != NO_ERROR) { @@ -1354,7 +1360,7 @@ static int OS2_SetClipboardText(_THIS, const char *text) return -1; } - strcpy(pszClipboard, pszText); + SDL_memcpy(pszClipboard, pszText, cbText); SDL_free(pszText); if (!WinOpenClipbrd(pVData->hab)) { @@ -1396,18 +1402,19 @@ static char *OS2_GetClipboardText(_THIS) static SDL_bool OS2_HasClipboardText(_THIS) { SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata; - SDL_bool fClipboard; + PSZ pszClipboard; + SDL_bool result; if (!WinOpenClipbrd(pVData->hab)) { debug_os2("WinOpenClipbrd() failed"); return SDL_FALSE; } - fClipboard = ((PSZ)WinQueryClipbrdData(pVData->hab, CF_TEXT) != NULL)? - SDL_TRUE : SDL_FALSE; + pszClipboard = (PSZ)WinQueryClipbrdData(pVData->hab, CF_TEXT); + result = (pszClipboard && *pszClipboard) ? SDL_TRUE : SDL_FALSE; WinCloseClipbrd(pVData->hab); - return fClipboard; + return result; } @@ -1444,7 +1451,7 @@ static int OS2_VideoInit(_THIS) return SDL_SetError("Window class not successfully registered."); } - if (stricmp(_this->name, OS2DRIVER_NAME_VMAN) == 0) + if (SDL_strcasecmp(_this->name, OS2DRIVER_NAME_VMAN) == 0) pVData->pOutput = &voVMan; else pVData->pOutput = &voDive; @@ -1562,8 +1569,14 @@ static int OS2_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, static void OS2_GetDisplayModes(_THIS, SDL_VideoDisplay *display) { + SDL_DisplayMode mode; + debug_os2("Enter"); - SDL_AddDisplayMode(display, &display->current_mode); + SDL_memcpy(&mode, &display->current_mode, sizeof(SDL_DisplayMode)); + mode.driverdata = (MODEDATA *) SDL_malloc(sizeof(MODEDATA)); + if (!mode.driverdata) return; /* yikes.. */ + SDL_memcpy(mode.driverdata, display->current_mode.driverdata, sizeof(MODEDATA)); + SDL_AddDisplayMode(display, &mode); } static int OS2_SetDisplayMode(_THIS, SDL_VideoDisplay *display, @@ -1616,7 +1629,7 @@ static SDL_VideoDevice *OS2_CreateDevice(int devindex) device->GetWindowWMInfo = OS2_GetWindowWMInfo; device->OnWindowEnter = OS2_OnWindowEnter; device->SetWindowHitTest = OS2_SetWindowHitTest; - device->SetWindowGrab = OS2_SetWindowGrab; + device->SetWindowMouseGrab = OS2_SetWindowMouseGrab; device->CreateWindowFramebuffer = OS2_CreateWindowFramebuffer; device->UpdateWindowFramebuffer = OS2_UpdateWindowFramebuffer; device->DestroyWindowFramebuffer = OS2_DestroyWindowFramebuffer; diff --git a/Engine/lib/sdl/src/video/os2/SDL_os2video.h b/Engine/lib/sdl/src/video/os2/SDL_os2video.h index cb27ed23e..688410c68 100644 --- a/Engine/lib/sdl/src/video/os2/SDL_os2video.h +++ b/Engine/lib/sdl/src/video/os2/SDL_os2video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/os2/SDL_os2vman.c b/Engine/lib/sdl/src/video/os2/SDL_os2vman.c index c55efe1eb..acb920061 100644 --- a/Engine/lib/sdl/src/video/os2/SDL_os2vman.c +++ b/Engine/lib/sdl/src/video/os2/SDL_os2vman.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,7 +31,7 @@ #include "SDL_os2output.h" #include "SDL_os2video.h" -#include "my_gradd.h" +#include "SDL_gradd.h" typedef struct _VODATA { PVOID pBuffer; @@ -78,7 +78,7 @@ static HMODULE hmodVMan = NULLHANDLE; static FNVMIENTRY *pfnVMIEntry = NULL; static ULONG ulVRAMAddress = 0; -VOID APIENTRY ExitVMan(VOID) +static VOID APIENTRY ExitVMan(VOID) { if (ulVRAMAddress != 0 && hmodVMan != NULLHANDLE) { pfnVMIEntry(0, VMI_CMD_TERMPROC, NULL, NULL); @@ -91,10 +91,10 @@ VOID APIENTRY ExitVMan(VOID) static BOOL _vmanInit(void) { ULONG ulRC; - CHAR acBuf[255]; + CHAR acBuf[256]; INITPROCOUT stInitProcOut; - if (hmodVMan != NULLHANDLE) /* Already was initialized */ + if (hmodVMan != NULLHANDLE) /* already initialized */ return TRUE; /* Load vman.dll */ @@ -108,8 +108,7 @@ static BOOL _vmanInit(void) /* Get VMIEntry */ ulRC = DosQueryProcAddr(hmodVMan, 0L, "VMIEntry", (PFN *)&pfnVMIEntry); if (ulRC != NO_ERROR) { - debug_os2("Could not query address of pfnVMIEntry func. of VMAN.DLL, " - "rc = %u", ulRC); + debug_os2("Could not query address of VMIEntry from VMAN.DLL (Err: %lu)", ulRC); DosFreeModule(hmodVMan); hmodVMan = NULLHANDLE; return FALSE; @@ -327,9 +326,8 @@ static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, PPOINTL pptlSrcOrg; PBLTRECT pbrDst; HWREQIN sHWReqIn; - BITBLTINFO sBitbltInfo = { 0 }; + BITBLTINFO sBitbltInfo; ULONG ulIdx; -/* RECTL rectlScreenUpdate;*/ if (pVOData->pBuffer == NULL) return FALSE; @@ -454,6 +452,7 @@ static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, rclSrcBounds.xRight = bmiSrc.ulWidth; rclSrcBounds.yTop = bmiSrc.ulHeight; + SDL_zero(sBitbltInfo); sBitbltInfo.ulLength = sizeof(BITBLTINFO); sBitbltInfo.ulBltFlags = BF_DEFAULT_STATE | BF_ROP_INCL_SRC | BF_PAT_HOLLOW; sBitbltInfo.cBlits = cSDLRects; diff --git a/Engine/lib/sdl/src/video/pandora/SDL_pandora.c b/Engine/lib/sdl/src/video/pandora/SDL_pandora.c index e78c0f2e5..16349f875 100644 --- a/Engine/lib/sdl/src/video/pandora/SDL_pandora.c +++ b/Engine/lib/sdl/src/video/pandora/SDL_pandora.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -114,7 +114,6 @@ PND_create() device->MaximizeWindow = PND_maximizewindow; device->MinimizeWindow = PND_minimizewindow; device->RestoreWindow = PND_restorewindow; - device->SetWindowGrab = PND_setwindowgrab; device->DestroyWindow = PND_destroywindow; #if 0 device->GetWindowWMInfo = PND_getwindowwminfo; @@ -287,10 +286,6 @@ PND_restorewindow(_THIS, SDL_Window * window) { } void -PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed) -{ -} -void PND_destroywindow(_THIS, SDL_Window * window) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; @@ -617,7 +612,7 @@ PND_gl_createcontext(_THIS, SDL_Window * window) #ifdef WIZ_GLES_LITE if( !hNativeWnd ) { - hNativeWnd = (NativeWindowType)malloc(16*1024); + hNativeWnd = (NativeWindowType)SDL_malloc(16*1024); if(!hNativeWnd) printf( "Error: Wiz framebuffer allocatation failed\n" ); @@ -824,7 +819,7 @@ PND_gl_deletecontext(_THIS, SDL_GLContext context) #ifdef WIZ_GLES_LITE if( hNativeWnd != 0 ) { - free(hNativeWnd); + SDL_free(hNativeWnd); hNativeWnd = 0; printf( "SDL: Wiz framebuffer released\n" ); } diff --git a/Engine/lib/sdl/src/video/pandora/SDL_pandora.h b/Engine/lib/sdl/src/video/pandora/SDL_pandora.h index 0d8569108..0954cd3af 100644 --- a/Engine/lib/sdl/src/video/pandora/SDL_pandora.h +++ b/Engine/lib/sdl/src/video/pandora/SDL_pandora.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -77,7 +77,6 @@ void PND_raisewindow(_THIS, SDL_Window * window); void PND_maximizewindow(_THIS, SDL_Window * window); void PND_minimizewindow(_THIS, SDL_Window * window); void PND_restorewindow(_THIS, SDL_Window * window); -void PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed); void PND_destroywindow(_THIS, SDL_Window * window); /* Window manager function */ diff --git a/Engine/lib/sdl/src/video/pandora/SDL_pandora_events.c b/Engine/lib/sdl/src/video/pandora/SDL_pandora_events.c index 779a19940..ab077d5dd 100644 --- a/Engine/lib/sdl/src/video/pandora/SDL_pandora_events.c +++ b/Engine/lib/sdl/src/video/pandora/SDL_pandora_events.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/pandora/SDL_pandora_events.h b/Engine/lib/sdl/src/video/pandora/SDL_pandora_events.h index 399f69f14..8ad8e355d 100644 --- a/Engine/lib/sdl/src/video/pandora/SDL_pandora_events.h +++ b/Engine/lib/sdl/src/video/pandora/SDL_pandora_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/psp/SDL_pspevents.c b/Engine/lib/sdl/src/video/psp/SDL_pspevents.c index 37c711361..04a804770 100644 --- a/Engine/lib/sdl/src/video/psp/SDL_pspevents.c +++ b/Engine/lib/sdl/src/video/psp/SDL_pspevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,6 +34,7 @@ #include "SDL_keyboard.h" #include "../../thread/SDL_systhread.h" #include +#include #ifdef PSPIRKEYB #include diff --git a/Engine/lib/sdl/src/video/psp/SDL_pspevents_c.h b/Engine/lib/sdl/src/video/psp/SDL_pspevents_c.h index 39bd39cc5..8a55dde23 100644 --- a/Engine/lib/sdl/src/video/psp/SDL_pspevents_c.h +++ b/Engine/lib/sdl/src/video/psp/SDL_pspevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/psp/SDL_pspgl.c b/Engine/lib/sdl/src/video/psp/SDL_pspgl.c index 8a99e1d14..ca55ea251 100644 --- a/Engine/lib/sdl/src/video/psp/SDL_pspgl.c +++ b/Engine/lib/sdl/src/video/psp/SDL_pspgl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/psp/SDL_pspgl_c.h b/Engine/lib/sdl/src/video/psp/SDL_pspgl_c.h index a30a9bd0d..06822f37e 100644 --- a/Engine/lib/sdl/src/video/psp/SDL_pspgl_c.h +++ b/Engine/lib/sdl/src/video/psp/SDL_pspgl_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/psp/SDL_pspmouse.c b/Engine/lib/sdl/src/video/psp/SDL_pspmouse.c index 61f00b1fc..926f63977 100644 --- a/Engine/lib/sdl/src/video/psp/SDL_pspmouse.c +++ b/Engine/lib/sdl/src/video/psp/SDL_pspmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/psp/SDL_pspmouse_c.h b/Engine/lib/sdl/src/video/psp/SDL_pspmouse_c.h index e47ba252a..7ffee6f92 100644 --- a/Engine/lib/sdl/src/video/psp/SDL_pspmouse_c.h +++ b/Engine/lib/sdl/src/video/psp/SDL_pspmouse_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/psp/SDL_pspvideo.c b/Engine/lib/sdl/src/video/psp/SDL_pspvideo.c index fa1139ecd..a5c86ecc3 100644 --- a/Engine/lib/sdl/src/video/psp/SDL_pspvideo.c +++ b/Engine/lib/sdl/src/video/psp/SDL_pspvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -112,7 +112,6 @@ PSP_Create() device->MaximizeWindow = PSP_MaximizeWindow; device->MinimizeWindow = PSP_MinimizeWindow; device->RestoreWindow = PSP_RestoreWindow; - device->SetWindowGrab = PSP_SetWindowGrab; device->DestroyWindow = PSP_DestroyWindow; #if 0 device->GetWindowWMInfo = PSP_GetWindowWMInfo; @@ -159,7 +158,6 @@ PSP_VideoInit(_THIS) current_mode.refresh_rate = 60; /* 32 bpp for default */ current_mode.format = SDL_PIXELFORMAT_ABGR8888; - current_mode.driverdata = NULL; SDL_zero(display); @@ -167,8 +165,15 @@ PSP_VideoInit(_THIS) display.current_mode = current_mode; display.driverdata = NULL; - SDL_AddVideoDisplay(&display, SDL_FALSE); + SDL_AddDisplayMode(&display, ¤t_mode); + /* 16 bpp secondary mode */ + current_mode.format = SDL_PIXELFORMAT_BGR565; + display.desktop_mode = current_mode; + display.current_mode = current_mode; + SDL_AddDisplayMode(&display, ¤t_mode); + + SDL_AddVideoDisplay(&display, SDL_FALSE); return 1; } @@ -215,6 +220,7 @@ PSP_CreateWindow(_THIS, SDL_Window * window) /* Setup driver data for this window */ window->driverdata = wdata; + SDL_SetKeyboardFocus(window); /* Window has been successfully created */ return 0; @@ -265,11 +271,6 @@ PSP_MinimizeWindow(_THIS, SDL_Window * window) void PSP_RestoreWindow(_THIS, SDL_Window * window) { -} -void -PSP_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) -{ - } void PSP_DestroyWindow(_THIS, SDL_Window * window) diff --git a/Engine/lib/sdl/src/video/psp/SDL_pspvideo.h b/Engine/lib/sdl/src/video/psp/SDL_pspvideo.h index 484df87d3..e046c891e 100644 --- a/Engine/lib/sdl/src/video/psp/SDL_pspvideo.h +++ b/Engine/lib/sdl/src/video/psp/SDL_pspvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -73,7 +73,6 @@ void PSP_RaiseWindow(_THIS, SDL_Window * window); void PSP_MaximizeWindow(_THIS, SDL_Window * window); void PSP_MinimizeWindow(_THIS, SDL_Window * window); void PSP_RestoreWindow(_THIS, SDL_Window * window); -void PSP_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); void PSP_DestroyWindow(_THIS, SDL_Window * window); /* Window manager function */ diff --git a/Engine/lib/sdl/src/video/qnx/gl.c b/Engine/lib/sdl/src/video/qnx/gl.c index 19e1bd4f7..1862ab425 100644 --- a/Engine/lib/sdl/src/video/qnx/gl.c +++ b/Engine/lib/sdl/src/video/qnx/gl.c @@ -85,7 +85,7 @@ glGetConfig(EGLConfig *pconf, int *pformat) } // Allocate enough memory for all configurations. - egl_configs = malloc(egl_num_configs * sizeof(*egl_configs)); + egl_configs = SDL_malloc(egl_num_configs * sizeof(*egl_configs)); if (egl_configs == NULL) { return -1; } @@ -94,7 +94,7 @@ glGetConfig(EGLConfig *pconf, int *pformat) rc = eglGetConfigs(egl_disp, egl_configs, egl_num_configs, &egl_num_configs); if (rc != EGL_TRUE) { - free(egl_configs); + SDL_free(egl_configs); return -1; } @@ -119,7 +119,7 @@ glGetConfig(EGLConfig *pconf, int *pformat) break; } - free(egl_configs); + SDL_free(egl_configs); *pconf = egl_conf; *pformat = chooseFormat(egl_conf); diff --git a/Engine/lib/sdl/src/video/raspberry/SDL_rpievents.c b/Engine/lib/sdl/src/video/raspberry/SDL_rpievents.c index c2847b36d..31cd1bdc6 100644 --- a/Engine/lib/sdl/src/video/raspberry/SDL_rpievents.c +++ b/Engine/lib/sdl/src/video/raspberry/SDL_rpievents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/raspberry/SDL_rpievents_c.h b/Engine/lib/sdl/src/video/raspberry/SDL_rpievents_c.h index 20e04e91c..9bec91529 100644 --- a/Engine/lib/sdl/src/video/raspberry/SDL_rpievents_c.h +++ b/Engine/lib/sdl/src/video/raspberry/SDL_rpievents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.c b/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.c index 1ed140420..7614fb8c0 100644 --- a/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.c +++ b/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.h b/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.h index 65c89df46..40701e126 100644 --- a/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.h +++ b/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/raspberry/SDL_rpiopengles.c b/Engine/lib/sdl/src/video/raspberry/SDL_rpiopengles.c index 921f3c77a..7b62b3e43 100644 --- a/Engine/lib/sdl/src/video/raspberry/SDL_rpiopengles.c +++ b/Engine/lib/sdl/src/video/raspberry/SDL_rpiopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/raspberry/SDL_rpiopengles.h b/Engine/lib/sdl/src/video/raspberry/SDL_rpiopengles.h index 36f94ac25..2cdf0fdcf 100644 --- a/Engine/lib/sdl/src/video/raspberry/SDL_rpiopengles.h +++ b/Engine/lib/sdl/src/video/raspberry/SDL_rpiopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.c b/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.c index d077ecda3..1a0a4ce19 100644 --- a/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.c +++ b/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -120,7 +120,6 @@ RPI_Create() device->MaximizeWindow = RPI_MaximizeWindow; device->MinimizeWindow = RPI_MinimizeWindow; device->RestoreWindow = RPI_RestoreWindow; - device->SetWindowGrab = RPI_SetWindowGrab; device->DestroyWindow = RPI_DestroyWindow; #if 0 device->GetWindowWMInfo = RPI_GetWindowWMInfo; @@ -420,11 +419,6 @@ RPI_MinimizeWindow(_THIS, SDL_Window * window) void RPI_RestoreWindow(_THIS, SDL_Window * window) { -} -void -RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) -{ - } /*****************************************************************************/ diff --git a/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.h b/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.h index 557201db6..2b5f40f4d 100644 --- a/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.h +++ b/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -81,7 +81,6 @@ void RPI_RaiseWindow(_THIS, SDL_Window * window); void RPI_MaximizeWindow(_THIS, SDL_Window * window); void RPI_MinimizeWindow(_THIS, SDL_Window * window); void RPI_RestoreWindow(_THIS, SDL_Window * window); -void RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); void RPI_DestroyWindow(_THIS, SDL_Window * window); /* Window manager function */ diff --git a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_dyn.h b/Engine/lib/sdl/src/video/riscos/SDL_riscosdefs.h similarity index 55% rename from Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_dyn.h rename to Engine/lib/sdl/src/video/riscos/SDL_riscosdefs.h index 3cb67b08e..89a51f2b8 100644 --- a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_dyn.h +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscosdefs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,36 +18,34 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - -#ifndef SDL_kmsdrmdyn_h_ -#define SDL_kmsdrmdyn_h_ - #include "../../SDL_internal.h" -#include -#include -#include +#ifndef SDL_riscosdefs_h_ +#define SDL_riscosdefs_h_ -#ifdef __cplusplus -extern "C" { -#endif +typedef struct sprite_area { + int size; /* +0 */ + int count; /* +4 */ + int start; /* +8 */ + int end; /* +12 */ +} sprite_area; -int SDL_KMSDRM_LEGACY_LoadSymbols(void); -void SDL_KMSDRM_LEGACY_UnloadSymbols(void); +SDL_COMPILE_TIME_ASSERT(sprite_area, sizeof(sprite_area) == 16); -/* Declare all the function pointers and wrappers... */ -#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) \ - typedef rc (*SDL_DYNKMSDRM_LEGACYFN_##fn) params; \ - extern SDL_DYNKMSDRM_LEGACYFN_##fn KMSDRM_LEGACY_##fn; -#define SDL_KMSDRM_LEGACY_SYM_CONST(type, name) \ - typedef type SDL_DYNKMSDRM_LEGACYCONST_##name; \ - extern SDL_DYNKMSDRM_LEGACYCONST_##name KMSDRM_LEGACY_##name; -#include "SDL_kmsdrm_legacy_sym.h" +typedef struct sprite_header { + int next; /* +0 */ + char name[12]; /* +4 */ + int width; /* +16 */ + int height; /* +20 */ + int first_bit; /* +24 */ + int last_bit; /* +28 */ + int image_offset; /* +32 */ + int mask_offset; /* +36 */ + int mode; /* +40 */ +} sprite_header; -#ifdef __cplusplus -} -#endif +SDL_COMPILE_TIME_ASSERT(sprite_header, sizeof(sprite_header) == 44); -#endif /* SDL_kmsdrmdyn_h_ */ +#endif /* SDL_riscosdefs_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/riscos/SDL_riscosevents.c b/Engine/lib/sdl/src/video/riscos/SDL_riscosevents.c new file mode 100644 index 000000000..b0a0d7509 --- /dev/null +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscosevents.c @@ -0,0 +1,178 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +#include "../../events/SDL_events_c.h" + +#include "SDL_log.h" +#include "SDL_riscosvideo.h" +#include "SDL_riscosevents_c.h" +#include "scancodes_riscos.h" + +#include +#include + +static SDL_Scancode +SDL_RISCOS_translate_keycode(int keycode) +{ + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + + if (keycode < SDL_arraysize(riscos_scancode_table)) { + scancode = riscos_scancode_table[keycode]; + + if (scancode == SDL_SCANCODE_UNKNOWN) { + SDL_Log("The key you just pressed is not recognized by SDL: %d", keycode); + } + } + + return scancode; +} + +void +RISCOS_PollKeyboard(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; + Uint8 key = 2; + int i; + + /* Check for key releases */ + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { + if (driverdata->key_pressed[i] != 255) { + if ((_kernel_osbyte(129, driverdata->key_pressed[i] ^ 0xff, 0xff) & 0xff) != 255) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_RISCOS_translate_keycode(driverdata->key_pressed[i])); + driverdata->key_pressed[i] = 255; + } + } + } + + /* Check for key presses */ + while (key < 0xff) { + key = _kernel_osbyte(121, key + 1, 0) & 0xff; + switch (key) { + case 255: + /* Ignore mouse keys */ + case 9: + case 10: + case 11: + /* Ignore keys with multiple INKEY codes */ + case 24: + case 40: + case 71: + case 87: + break; + + default: + SDL_SendKeyboardKey(SDL_PRESSED, SDL_RISCOS_translate_keycode(key)); + + /* Record the press so we can detect release later. */ + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { + if (driverdata->key_pressed[i] == key) { + break; + } + if (driverdata->key_pressed[i] == 255) { + driverdata->key_pressed[i] = key; + break; + } + } + } + } +} + +static const Uint8 mouse_button_map[] = { + SDL_BUTTON_RIGHT, + SDL_BUTTON_MIDDLE, + SDL_BUTTON_LEFT, + SDL_BUTTON_X1, + SDL_BUTTON_X2, + SDL_BUTTON_X2 + 1, + SDL_BUTTON_X2 + 2, + SDL_BUTTON_X2 + 3 +}; + +void +RISCOS_PollMouse(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Rect rect; + _kernel_swi_regs regs; + int i, x, y, buttons; + + if (SDL_GetDisplayBounds(0, &rect) < 0) { + return; + } + + _kernel_swi(OS_Mouse, ®s, ®s); + x = (regs.r[0] >> 1); + y = rect.h - (regs.r[1] >> 1); + buttons = regs.r[2]; + + if (mouse->x != x || mouse->y != y) { + SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y); + } + + if (driverdata->last_mouse_buttons != buttons) { + for (i = 0; i < SDL_arraysize(mouse_button_map); i++) { + SDL_SendMouseButton(mouse->focus, mouse->mouseID, (buttons & (1 << i)) ? SDL_PRESSED : SDL_RELEASED, mouse_button_map[i]); + } + driverdata->last_mouse_buttons = buttons; + } +} + +int +RISCOS_InitEvents(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata; + int i, status; + + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) + driverdata->key_pressed[i] = 255; + + status = (_kernel_osbyte(202, 0, 255) & 0xFF); + SDL_ToggleModState(KMOD_NUM, (status & (1 << 2)) == 0); + SDL_ToggleModState(KMOD_CAPS, (status & (1 << 4)) == 0); + SDL_ToggleModState(KMOD_SCROLL, (status & (1 << 1)) != 0); + + /* Disable escape. */ + _kernel_osbyte(229, 1, 0); + + return 0; +} + +void +RISCOS_PumpEvents(_THIS) +{ + RISCOS_PollMouse(_this); + RISCOS_PollKeyboard(_this); +} + +void +RISCOS_QuitEvents(_THIS) +{ + /* Re-enable escape. */ + _kernel_osbyte(229, 0, 0); +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamousetap.h b/Engine/lib/sdl/src/video/riscos/SDL_riscosevents_c.h similarity index 70% rename from Engine/lib/sdl/src/video/cocoa/SDL_cocoamousetap.h rename to Engine/lib/sdl/src/video/riscos/SDL_riscosevents_c.h index 3a1a0721b..6b4341111 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamousetap.h +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscosevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,17 +18,18 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ + +#ifndef SDL_riscosevents_c_h_ +#define SDL_riscosevents_c_h_ + #include "../../SDL_internal.h" -#ifndef SDL_cocoamousetap_h_ -#define SDL_cocoamousetap_h_ +#include "SDL_riscosvideo.h" -#include "SDL_cocoamouse.h" +extern int RISCOS_InitEvents(_THIS); +extern void RISCOS_PumpEvents(_THIS); +extern void RISCOS_QuitEvents(_THIS); -extern void Cocoa_InitMouseEventTap(SDL_MouseData *driverdata); -extern void Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled); -extern void Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata); - -#endif /* SDL_cocoamousetap_h_ */ +#endif /* SDL_riscosevents_c_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/riscos/SDL_riscosframebuffer.c b/Engine/lib/sdl/src/video/riscos/SDL_riscosframebuffer.c new file mode 100644 index 000000000..59841992f --- /dev/null +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscosframebuffer.c @@ -0,0 +1,126 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +#include "../SDL_sysvideo.h" +#include "SDL_riscosframebuffer_c.h" +#include "SDL_riscosvideo.h" +#include "SDL_riscoswindow.h" + +#include +#include + +int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +{ + SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata; + const char *sprite_name = "display"; + unsigned int sprite_mode; + _kernel_oserror *error; + _kernel_swi_regs regs; + SDL_DisplayMode mode; + int size; + + /* Free the old framebuffer surface */ + RISCOS_DestroyWindowFramebuffer(_this, window); + + /* Create a new one */ + SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(window), &mode); + if ((SDL_ISPIXELFORMAT_PACKED(mode.format) || SDL_ISPIXELFORMAT_ARRAY(mode.format))) { + *format = mode.format; + sprite_mode = (unsigned int)mode.driverdata; + } else { + *format = SDL_PIXELFORMAT_BGR888; + sprite_mode = (1 | (90 << 1) | (90 << 14) | (6 << 27)); + } + + /* Calculate pitch */ + *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3); + + /* Allocate the sprite area */ + size = sizeof(sprite_area) + sizeof(sprite_header) + ((*pitch) * window->h); + driverdata->fb_area = SDL_malloc(size); + if (!driverdata->fb_area) { + return SDL_OutOfMemory(); + } + + driverdata->fb_area->size = size; + driverdata->fb_area->count = 0; + driverdata->fb_area->start = 16; + driverdata->fb_area->end = 16; + + /* Create the actual image */ + regs.r[0] = 256+15; + regs.r[1] = (int)driverdata->fb_area; + regs.r[2] = (int)sprite_name; + regs.r[3] = 0; + regs.r[4] = window->w; + regs.r[5] = window->h; + regs.r[6] = sprite_mode; + error = _kernel_swi(OS_SpriteOp, ®s, ®s); + if (error != NULL) { + SDL_free(driverdata->fb_area); + return SDL_SetError("Unable to create sprite: %s (%i)", error->errmess, error->errnum); + } + + driverdata->fb_sprite = (sprite_header *)(((Uint8 *)driverdata->fb_area) + driverdata->fb_area->start); + *pixels = ((Uint8 *)driverdata->fb_sprite) + driverdata->fb_sprite->image_offset; + + return 0; +} + +int RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +{ + SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata; + _kernel_swi_regs regs; + _kernel_oserror *error; + + regs.r[0] = 512+52; + regs.r[1] = (int)driverdata->fb_area; + regs.r[2] = (int)driverdata->fb_sprite; + regs.r[3] = 0; /* window->x << 1; */ + regs.r[4] = 0; /* window->y << 1; */ + regs.r[5] = 0x50; + regs.r[6] = 0; + regs.r[7] = 0; + error = _kernel_swi(OS_SpriteOp, ®s, ®s); + if (error != NULL) { + return SDL_SetError("OS_SpriteOp 52 failed: %s (%i)", error->errmess, error->errnum); + } + + return 0; +} + +void RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +{ + SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata; + + if (driverdata->fb_area) { + SDL_free(driverdata->fb_area); + driverdata->fb_area = NULL; + } + driverdata->fb_sprite = NULL; +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_mouse.h b/Engine/lib/sdl/src/video/riscos/SDL_riscosframebuffer_c.h similarity index 65% rename from Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_mouse.h rename to Engine/lib/sdl/src/video/riscos/SDL_riscosframebuffer_c.h index 384196718..100461608 100644 --- a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_mouse.h +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscosframebuffer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,27 +19,15 @@ 3. This notice may not be removed or altered from any source distribution. */ +#ifndef SDL_riscosframebuffer_c_h_ +#define SDL_riscosframebuffer_c_h_ + #include "../../SDL_internal.h" -#ifndef SDL_KMSDRM_LEGACY_mouse_h_ -#define SDL_KMSDRM_LEGACY_mouse_h_ +extern int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); +extern int RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); +extern void RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window * window); -#include - -#define MAX_CURSOR_W 512 -#define MAX_CURSOR_H 512 - -typedef struct _KMSDRM_LEGACY_CursorData -{ - struct gbm_bo *bo; - uint32_t crtc_id; - int hot_x, hot_y; - int w, h; -} KMSDRM_LEGACY_CursorData; - -extern void KMSDRM_LEGACY_InitMouse(_THIS); -extern void KMSDRM_LEGACY_QuitMouse(_THIS); - -#endif /* SDL_KMSDRM_LEGACY_mouse_h_ */ +#endif /* SDL_riscosframebuffer_c_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/riscos/SDL_riscosmessagebox.c b/Engine/lib/sdl/src/video/riscos/SDL_riscosmessagebox.c new file mode 100644 index 000000000..8144a9df6 --- /dev/null +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscosmessagebox.c @@ -0,0 +1,68 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +#include "SDL_messagebox.h" +#include "SDL_riscosmessagebox.h" + +#include +#include + +int +RISCOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ + _kernel_swi_regs regs; + _kernel_oserror error; + char buttonstring[1024]; + int i; + + error.errnum = 0; + SDL_strlcpy(error.errmess, messageboxdata->message, 252); + regs.r[0] = (unsigned int)&error; + + regs.r[1] = (1 << 8) | (1 << 4); + if (messageboxdata->flags == SDL_MESSAGEBOX_INFORMATION) + regs.r[1] |= (1 << 9); + else if (messageboxdata->flags == SDL_MESSAGEBOX_WARNING) + regs.r[1] |= (2 << 9); + regs.r[2] = (unsigned int)messageboxdata->title; + regs.r[3] = 0; + regs.r[4] = 0; + + SDL_strlcpy(buttonstring, "" , 1024); + for (i = 0; i < messageboxdata->numbuttons; i++) { + SDL_strlcat(buttonstring, messageboxdata->buttons[i].text, 1024); + if (i + 1 < messageboxdata->numbuttons) + SDL_strlcat(buttonstring, ",", 1024); + } + regs.r[5] = (unsigned int)buttonstring; + + _kernel_swi(Wimp_ReportError, ®s, ®s); + + *buttonid = (regs.r[1] == 0) ? -1 : messageboxdata->buttons[regs.r[1] - 3].buttonid; + return 0; +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_events.h b/Engine/lib/sdl/src/video/riscos/SDL_riscosmessagebox.h similarity index 76% rename from Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_events.h rename to Engine/lib/sdl/src/video/riscos/SDL_riscosmessagebox.h index 24c23bcb6..3f6c259e8 100644 --- a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_events.h +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscosmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,14 +18,12 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" -#ifndef SDL_kmsdrmevents_h_ -#define SDL_kmsdrmevents_h_ +#if SDL_VIDEO_DRIVER_RISCOS -extern void KMSDRM_LEGACY_PumpEvents(_THIS); -extern void KMSDRM_LEGACY_EventInit(_THIS); -extern void KMSDRM_LEGACY_EventQuit(_THIS); +extern int RISCOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); -#endif /* SDL_kmsdrmevents_h_ */ +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/riscos/SDL_riscosmodes.c b/Engine/lib/sdl/src/video/riscos/SDL_riscosmodes.c new file mode 100644 index 000000000..0e87c140e --- /dev/null +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscosmodes.c @@ -0,0 +1,315 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +#include "../SDL_sysvideo.h" + +#include "SDL_riscosvideo.h" +#include "SDL_riscosmodes.h" + +#include +#include + +enum { + MODE_FLAG_565 = 1 << 7, + + MODE_FLAG_COLOUR_SPACE = 0xF << 12, + + MODE_FLAG_TBGR = 0, + MODE_FLAG_TRGB = 1 << 14, + MODE_FLAG_ABGR = 1 << 15, + MODE_FLAG_ARGB = MODE_FLAG_TRGB | MODE_FLAG_ABGR +}; + +static const struct { + SDL_PixelFormatEnum pixel_format; + int modeflags, ncolour, log2bpp; +} mode_to_pixelformat[] = { + /* { SDL_PIXELFORMAT_INDEX1LSB, 0, 1, 0 }, */ + /* { SDL_PIXELFORMAT_INDEX2LSB, 0, 3, 1 }, */ + /* { SDL_PIXELFORMAT_INDEX4LSB, 0, 15, 2 }, */ + /* { SDL_PIXELFORMAT_INDEX8, MODE_FLAG_565, 255, 3 }, */ + { SDL_PIXELFORMAT_XBGR1555, MODE_FLAG_TBGR, 65535, 4 }, + { SDL_PIXELFORMAT_XRGB1555, MODE_FLAG_TRGB, 65535, 4 }, + { SDL_PIXELFORMAT_ABGR1555, MODE_FLAG_ABGR, 65535, 4 }, + { SDL_PIXELFORMAT_ARGB1555, MODE_FLAG_ARGB, 65535, 4 }, + { SDL_PIXELFORMAT_XBGR4444, MODE_FLAG_TBGR, 4095, 4 }, + { SDL_PIXELFORMAT_XRGB4444, MODE_FLAG_TRGB, 4095, 4 }, + { SDL_PIXELFORMAT_ABGR4444, MODE_FLAG_ABGR, 4095, 4 }, + { SDL_PIXELFORMAT_ARGB4444, MODE_FLAG_ARGB, 4095, 4 }, + { SDL_PIXELFORMAT_BGR565, MODE_FLAG_TBGR | MODE_FLAG_565, 65535, 4 }, + { SDL_PIXELFORMAT_RGB565, MODE_FLAG_TRGB | MODE_FLAG_565, 65535, 4 }, + { SDL_PIXELFORMAT_BGR24, MODE_FLAG_TBGR, 16777215, 6 }, + { SDL_PIXELFORMAT_RGB24, MODE_FLAG_TRGB, 16777215, 6 }, + { SDL_PIXELFORMAT_XBGR8888, MODE_FLAG_TBGR, -1, 5 }, + { SDL_PIXELFORMAT_XRGB8888, MODE_FLAG_TRGB, -1, 5 }, + { SDL_PIXELFORMAT_ABGR8888, MODE_FLAG_ABGR, -1, 5 }, + { SDL_PIXELFORMAT_ARGB8888, MODE_FLAG_ARGB, -1, 5 } +}; + +static SDL_PixelFormatEnum +RISCOS_ModeToPixelFormat(int ncolour, int modeflags, int log2bpp) +{ + int i; + + for (i = 0; i < SDL_arraysize(mode_to_pixelformat); i++) { + if (log2bpp == mode_to_pixelformat[i].log2bpp && + (ncolour == mode_to_pixelformat[i].ncolour || ncolour == 0) && + (modeflags & (MODE_FLAG_565 | MODE_FLAG_COLOUR_SPACE)) == mode_to_pixelformat[i].modeflags) { + return mode_to_pixelformat[i].pixel_format; + } + } + + return SDL_PIXELFORMAT_UNKNOWN; +} + +static size_t +measure_mode_block(const int *block) +{ + size_t blockSize = ((block[0] & 0xFF) == 3) ? 7 : 5; + while(block[blockSize] != -1) { + blockSize += 2; + } + blockSize++; + + return blockSize * 4; +} + +static int +read_mode_variable(int *block, int var) +{ + _kernel_swi_regs regs; + regs.r[0] = (int)block; + regs.r[1] = var; + _kernel_swi(OS_ReadModeVariable, ®s, ®s); + return regs.r[2]; +} + +static SDL_bool +read_mode_block(int *block, SDL_DisplayMode *mode, SDL_bool extended) +{ + int xres, yres, ncolour, modeflags, log2bpp, rate; + + if ((block[0] & 0xFF) == 1) { + xres = block[1]; + yres = block[2]; + log2bpp = block[3]; + rate = block[4]; + ncolour = (1 << (1 << log2bpp)) - 1; + modeflags = MODE_FLAG_TBGR; + } else if ((block[0] & 0xFF) == 3) { + xres = block[1]; + yres = block[2]; + ncolour = block[3]; + modeflags = block[4]; + log2bpp = block[5]; + rate = block[6]; + } else { + return SDL_FALSE; + } + + if (extended) { + xres = read_mode_variable(block, 11) + 1; + yres = read_mode_variable(block, 12) + 1; + log2bpp = read_mode_variable(block, 9); + ncolour = read_mode_variable(block, 3); + modeflags = read_mode_variable(block, 0); + } + + mode->w = xres; + mode->h = yres; + mode->format = RISCOS_ModeToPixelFormat(ncolour, modeflags, log2bpp); + mode->refresh_rate = rate; + + return SDL_TRUE; +} + +static void * +convert_mode_block(const int *block) +{ + int xres, yres, log2bpp, rate, ncolour = 0, modeflags = 0; + size_t pos = 0; + int *dst; + + if ((block[0] & 0xFF) == 1) { + xres = block[1]; + yres = block[2]; + log2bpp = block[3]; + rate = block[4]; + } else if ((block[0] & 0xFF) == 3) { + xres = block[1]; + yres = block[2]; + ncolour = block[3]; + modeflags = block[4]; + log2bpp = block[5]; + rate = block[6]; + } else { + return NULL; + } + + dst = SDL_malloc(40); + if (!dst) { + return NULL; + } + + dst[pos++] = 1; + dst[pos++] = xres; + dst[pos++] = yres; + dst[pos++] = log2bpp; + dst[pos++] = rate; + if (ncolour != 0) { + dst[pos++] = 3; + dst[pos++] = ncolour; + } + if (modeflags != 0) { + dst[pos++] = 0; + dst[pos++] = modeflags; + } + dst[pos++] = -1; + + return dst; +} + +static void * +copy_memory(const void *src, size_t size, size_t alloc) +{ + void *dst = SDL_malloc(alloc); + if (dst) { + SDL_memcpy(dst, src, size); + } + return dst; +} + +int +RISCOS_InitModes(_THIS) +{ + SDL_DisplayMode mode; + int *current_mode; + _kernel_swi_regs regs; + _kernel_oserror *error; + size_t size; + + regs.r[0] = 1; + error = _kernel_swi(OS_ScreenMode, ®s, ®s); + if (error != NULL) { + return SDL_SetError("Unable to retrieve the current screen mode: %s (%i)", error->errmess, error->errnum); + } + + current_mode = (int *)regs.r[1]; + if (!read_mode_block(current_mode, &mode, SDL_TRUE)) { + return SDL_SetError("Unsupported mode block format %d", current_mode[0]); + } + + size = measure_mode_block(current_mode); + mode.driverdata = copy_memory(current_mode, size, size); + if (!mode.driverdata) { + return SDL_OutOfMemory(); + } + + return SDL_AddBasicVideoDisplay(&mode); +} + +void +RISCOS_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +{ + SDL_DisplayMode mode; + _kernel_swi_regs regs; + _kernel_oserror *error; + void *block, *pos; + + regs.r[0] = 2; + regs.r[2] = 0; + regs.r[6] = 0; + regs.r[7] = 0; + error = _kernel_swi(OS_ScreenMode, ®s, ®s); + if (error != NULL) { + SDL_SetError("Unable to enumerate screen modes: %s (%i)", error->errmess, error->errnum); + return; + } + + block = SDL_malloc(-regs.r[7]); + if (!block) { + SDL_OutOfMemory(); + return; + } + + regs.r[6] = (int)block; + regs.r[7] = -regs.r[7]; + error = _kernel_swi(OS_ScreenMode, ®s, ®s); + if (error != NULL) { + SDL_free(block); + SDL_SetError("Unable to enumerate screen modes: %s (%i)", error->errmess, error->errnum); + return; + } + + for (pos = block; pos < (void *)regs.r[6]; pos += *((int *)pos)) { + if (!read_mode_block(pos + 4, &mode, SDL_FALSE)) { + continue; + } + + if (mode.format == SDL_PIXELFORMAT_UNKNOWN) + continue; + + mode.driverdata = convert_mode_block(pos + 4); + if (!mode.driverdata) { + SDL_OutOfMemory(); + break; + } + + if (!SDL_AddDisplayMode(display, &mode)) { + SDL_free(mode.driverdata); + } + } + + SDL_free(block); +} + +int +RISCOS_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + const char disable_cursor[] = { 23, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + _kernel_swi_regs regs; + _kernel_oserror *error; + int i; + + regs.r[0] = 0; + regs.r[1] = (int)mode->driverdata; + error = _kernel_swi(OS_ScreenMode, ®s, ®s); + if (error != NULL) { + return SDL_SetError("Unable to set the current screen mode: %s (%i)", error->errmess, error->errnum); + } + + /* Turn the text cursor off */ + for (i = 0; i < SDL_arraysize(disable_cursor); i++) { + _kernel_oswrch(disable_cursor[i]); + } + + /* Turn the mouse pointer on */ + /* _kernel_osbyte(106, 1, 0); */ + + return 0; +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/riscos/SDL_riscosmodes.h b/Engine/lib/sdl/src/video/riscos/SDL_riscosmodes.h new file mode 100644 index 000000000..eb5347286 --- /dev/null +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscosmodes.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_riscosmodes_h_ +#define SDL_riscosmodes_h_ + +extern int RISCOS_InitModes(_THIS); +extern void RISCOS_GetDisplayModes(_THIS, SDL_VideoDisplay * display); +extern int RISCOS_SetDisplayMode(_THIS, SDL_VideoDisplay * display, + SDL_DisplayMode * mode); + +#endif /* SDL_riscosmodes_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/riscos/SDL_riscosvideo.c b/Engine/lib/sdl/src/video/riscos/SDL_riscosvideo.c new file mode 100644 index 000000000..1d8bd3d95 --- /dev/null +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscosvideo.c @@ -0,0 +1,124 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_riscosvideo.h" +#include "SDL_riscosevents_c.h" +#include "SDL_riscosframebuffer_c.h" +#include "SDL_riscosmodes.h" +#include "SDL_riscoswindow.h" + +#define RISCOSVID_DRIVER_NAME "riscos" + +/* Initialization/Query functions */ +static int RISCOS_VideoInit(_THIS); +static void RISCOS_VideoQuit(_THIS); + +/* RISC OS driver bootstrap functions */ + +static void +RISCOS_DeleteDevice(SDL_VideoDevice * device) +{ + SDL_free(device->driverdata); + SDL_free(device); +} + +static SDL_VideoDevice * +RISCOS_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + SDL_VideoData *phdata; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return (0); + } + + /* Initialize internal data */ + phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + if (phdata == NULL) { + SDL_OutOfMemory(); + SDL_free(device); + return NULL; + } + + device->driverdata = phdata; + + /* Set the function pointers */ + device->VideoInit = RISCOS_VideoInit; + device->VideoQuit = RISCOS_VideoQuit; + device->PumpEvents = RISCOS_PumpEvents; + + device->GetDisplayModes = RISCOS_GetDisplayModes; + device->SetDisplayMode = RISCOS_SetDisplayMode; + + device->CreateSDLWindow = RISCOS_CreateWindow; + device->DestroyWindow = RISCOS_DestroyWindow; + device->GetWindowWMInfo = RISCOS_GetWindowWMInfo; + + device->CreateWindowFramebuffer = RISCOS_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = RISCOS_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = RISCOS_DestroyWindowFramebuffer; + + device->free = RISCOS_DeleteDevice; + + return device; +} + +VideoBootStrap RISCOS_bootstrap = { + RISCOSVID_DRIVER_NAME, "SDL RISC OS video driver", + RISCOS_CreateDevice +}; + +static int +RISCOS_VideoInit(_THIS) +{ + if (RISCOS_InitEvents(_this) < 0) { + return -1; + } + + if (RISCOS_InitModes(_this) < 0) { + return -1; + } + + /* We're done! */ + return 0; +} + +static void +RISCOS_VideoQuit(_THIS) +{ + RISCOS_QuitEvents(_this); +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_events.c b/Engine/lib/sdl/src/video/riscos/SDL_riscosvideo.h similarity index 71% rename from Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_events.c rename to Engine/lib/sdl/src/video/riscos/SDL_riscosvideo.h index a5c765edb..db6c86e49 100644 --- a/Engine/lib/sdl/src/video/kmsdrm_legacy/SDL_kmsdrm_legacy_events.c +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscosvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,25 +18,21 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_KMSDRM +#ifndef SDL_riscosvideo_h_ +#define SDL_riscosvideo_h_ -#include "SDL_kmsdrm_legacy_video.h" -#include "SDL_kmsdrm_legacy_events.h" +#include "../SDL_sysvideo.h" -#ifdef SDL_INPUT_LINUXEV -#include "../../core/linux/SDL_evdev.h" -#endif +#define RISCOS_MAX_KEYS_PRESSED 6 -void KMSDRM_LEGACY_PumpEvents(_THIS) +typedef struct SDL_VideoData { -#ifdef SDL_INPUT_LINUXEV - SDL_EVDEV_Poll(); -#endif + int last_mouse_buttons; + Uint8 key_pressed[RISCOS_MAX_KEYS_PRESSED]; +} SDL_VideoData; -} - -#endif /* SDL_VIDEO_DRIVER_KMSDRM */ +#endif /* SDL_riscosvideo_h_ */ +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/riscos/SDL_riscoswindow.c b/Engine/lib/sdl/src/video/riscos/SDL_riscoswindow.c new file mode 100644 index 000000000..84e4de03e --- /dev/null +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscoswindow.c @@ -0,0 +1,78 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +#include "SDL_version.h" +#include "SDL_syswm.h" +#include "../SDL_sysvideo.h" + +#include "SDL_riscosvideo.h" +#include "SDL_riscoswindow.h" + +int +RISCOS_CreateWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *driverdata; + + driverdata = (SDL_WindowData *) SDL_calloc(1, sizeof(*driverdata)); + if (!driverdata) { + return SDL_OutOfMemory(); + } + driverdata->window = window; + + window->flags |= SDL_WINDOW_FULLSCREEN; + + /* All done! */ + window->driverdata = driverdata; + return 0; +} + +void +RISCOS_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata; + + if (!driverdata) + return; + + SDL_free(driverdata); + window->driverdata = NULL; +} + +SDL_bool +RISCOS_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +{ + if (info->version.major == SDL_MAJOR_VERSION && + info->version.minor == SDL_MINOR_VERSION) { + info->subsystem = SDL_SYSWM_RISCOS; + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d.%d", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + return SDL_FALSE; + } +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/riscos/SDL_riscoswindow.h b/Engine/lib/sdl/src/video/riscos/SDL_riscoswindow.h new file mode 100644 index 000000000..d713b7aeb --- /dev/null +++ b/Engine/lib/sdl/src/video/riscos/SDL_riscoswindow.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_riscoswindow_h_ +#define SDL_riscoswindow_h_ + +#include "SDL_riscosdefs.h" + +typedef struct +{ + SDL_Window *window; + sprite_area *fb_area; + sprite_header *fb_sprite; +} SDL_WindowData; + +extern int RISCOS_CreateWindow(_THIS, SDL_Window * window); +extern void RISCOS_DestroyWindow(_THIS, SDL_Window * window); +extern SDL_bool RISCOS_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info); + +#endif /* SDL_riscoswindow_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/riscos/scancodes_riscos.h b/Engine/lib/sdl/src/video/riscos/scancodes_riscos.h new file mode 100644 index 000000000..ced6b0d1b --- /dev/null +++ b/Engine/lib/sdl/src/video/riscos/scancodes_riscos.h @@ -0,0 +1,158 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_scancode.h" + +/* RISC OS key code to SDL_Keycode mapping table + Sources: + - https://www.riscosopen.org/wiki/documentation/show/Keyboard Scan Codes +*/ +/* *INDENT-OFF* */ +static SDL_Scancode const riscos_scancode_table[] = { + /* 0 */ SDL_SCANCODE_UNKNOWN, /* Shift */ + /* 1 */ SDL_SCANCODE_UNKNOWN, /* Ctrl */ + /* 2 */ SDL_SCANCODE_UNKNOWN, /* Alt */ + /* 3 */ SDL_SCANCODE_LSHIFT, + /* 4 */ SDL_SCANCODE_LCTRL, + /* 5 */ SDL_SCANCODE_LALT, + /* 6 */ SDL_SCANCODE_RSHIFT, + /* 7 */ SDL_SCANCODE_RCTRL, + /* 8 */ SDL_SCANCODE_RALT, + /* 9 */ SDL_SCANCODE_UNKNOWN, /* Left mouse */ + /* 10 */ SDL_SCANCODE_UNKNOWN, /* Center mouse */ + /* 11 */ SDL_SCANCODE_UNKNOWN, /* Right mouse */ + /* 12 */ SDL_SCANCODE_UNKNOWN, + /* 13 */ SDL_SCANCODE_UNKNOWN, + /* 14 */ SDL_SCANCODE_UNKNOWN, + /* 15 */ SDL_SCANCODE_UNKNOWN, + /* 16 */ SDL_SCANCODE_Q, + /* 17 */ SDL_SCANCODE_3, + /* 18 */ SDL_SCANCODE_4, + /* 19 */ SDL_SCANCODE_5, + /* 20 */ SDL_SCANCODE_F4, + /* 21 */ SDL_SCANCODE_8, + /* 22 */ SDL_SCANCODE_F7, + /* 23 */ SDL_SCANCODE_MINUS, + /* 24 */ SDL_SCANCODE_6, /* Duplicate of 52 */ + /* 25 */ SDL_SCANCODE_LEFT, + /* 26 */ SDL_SCANCODE_KP_6, + /* 27 */ SDL_SCANCODE_KP_7, + /* 28 */ SDL_SCANCODE_F11, + /* 29 */ SDL_SCANCODE_F12, + /* 30 */ SDL_SCANCODE_F10, + /* 31 */ SDL_SCANCODE_SCROLLLOCK, + /* 32 */ SDL_SCANCODE_PRINTSCREEN, + /* 33 */ SDL_SCANCODE_W, + /* 34 */ SDL_SCANCODE_E, + /* 35 */ SDL_SCANCODE_T, + /* 36 */ SDL_SCANCODE_7, + /* 37 */ SDL_SCANCODE_I, + /* 38 */ SDL_SCANCODE_9, + /* 39 */ SDL_SCANCODE_0, + /* 40 */ SDL_SCANCODE_MINUS, /* Duplicate of 23 */ + /* 41 */ SDL_SCANCODE_DOWN, + /* 42 */ SDL_SCANCODE_KP_8, + /* 43 */ SDL_SCANCODE_KP_9, + /* 44 */ SDL_SCANCODE_PAUSE, + /* 45 */ SDL_SCANCODE_GRAVE, + /* 46 */ SDL_SCANCODE_CURRENCYUNIT, + /* 47 */ SDL_SCANCODE_BACKSPACE, + /* 48 */ SDL_SCANCODE_1, + /* 49 */ SDL_SCANCODE_2, + /* 50 */ SDL_SCANCODE_D, + /* 51 */ SDL_SCANCODE_R, + /* 52 */ SDL_SCANCODE_6, + /* 53 */ SDL_SCANCODE_U, + /* 54 */ SDL_SCANCODE_O, + /* 55 */ SDL_SCANCODE_P, + /* 56 */ SDL_SCANCODE_LEFTBRACKET, + /* 57 */ SDL_SCANCODE_UP, + /* 58 */ SDL_SCANCODE_KP_PLUS, + /* 59 */ SDL_SCANCODE_KP_MINUS, + /* 60 */ SDL_SCANCODE_KP_ENTER, + /* 61 */ SDL_SCANCODE_INSERT, + /* 62 */ SDL_SCANCODE_HOME, + /* 63 */ SDL_SCANCODE_PAGEUP, + /* 64 */ SDL_SCANCODE_CAPSLOCK, + /* 65 */ SDL_SCANCODE_A, + /* 66 */ SDL_SCANCODE_X, + /* 67 */ SDL_SCANCODE_F, + /* 68 */ SDL_SCANCODE_Y, + /* 69 */ SDL_SCANCODE_J, + /* 70 */ SDL_SCANCODE_K, + /* 71 */ SDL_SCANCODE_2, /* Duplicate of 49 */ + /* 72 */ SDL_SCANCODE_SEMICOLON, /* Duplicate of 87 */ + /* 73 */ SDL_SCANCODE_RETURN, + /* 74 */ SDL_SCANCODE_KP_DIVIDE, + /* 75 */ SDL_SCANCODE_UNKNOWN, + /* 76 */ SDL_SCANCODE_KP_PERIOD, + /* 77 */ SDL_SCANCODE_NUMLOCKCLEAR, + /* 78 */ SDL_SCANCODE_PAGEDOWN, + /* 79 */ SDL_SCANCODE_APOSTROPHE, + /* 80 */ SDL_SCANCODE_UNKNOWN, + /* 81 */ SDL_SCANCODE_S, + /* 82 */ SDL_SCANCODE_C, + /* 83 */ SDL_SCANCODE_G, + /* 84 */ SDL_SCANCODE_H, + /* 85 */ SDL_SCANCODE_N, + /* 86 */ SDL_SCANCODE_L, + /* 87 */ SDL_SCANCODE_SEMICOLON, + /* 88 */ SDL_SCANCODE_RIGHTBRACKET, + /* 89 */ SDL_SCANCODE_DELETE, + /* 90 */ SDL_SCANCODE_KP_HASH, + /* 91 */ SDL_SCANCODE_KP_MULTIPLY, + /* 92 */ SDL_SCANCODE_UNKNOWN, + /* 93 */ SDL_SCANCODE_EQUALS, + /* 94 */ SDL_SCANCODE_NONUSBACKSLASH, + /* 95 */ SDL_SCANCODE_UNKNOWN, + /* 96 */ SDL_SCANCODE_TAB, + /* 97 */ SDL_SCANCODE_Z, + /* 98 */ SDL_SCANCODE_SPACE, + /* 99 */ SDL_SCANCODE_V, + /* 100 */ SDL_SCANCODE_B, + /* 101 */ SDL_SCANCODE_M, + /* 102 */ SDL_SCANCODE_COMMA, + /* 103 */ SDL_SCANCODE_PERIOD, + /* 104 */ SDL_SCANCODE_SLASH, + /* 105 */ SDL_SCANCODE_END, + /* 106 */ SDL_SCANCODE_KP_0, + /* 107 */ SDL_SCANCODE_KP_1, + /* 108 */ SDL_SCANCODE_KP_3, + /* 109 */ SDL_SCANCODE_UNKNOWN, + /* 110 */ SDL_SCANCODE_UNKNOWN, + /* 111 */ SDL_SCANCODE_UNKNOWN, + /* 112 */ SDL_SCANCODE_ESCAPE, + /* 113 */ SDL_SCANCODE_F1, + /* 114 */ SDL_SCANCODE_F2, + /* 115 */ SDL_SCANCODE_F3, + /* 116 */ SDL_SCANCODE_F5, + /* 117 */ SDL_SCANCODE_F6, + /* 118 */ SDL_SCANCODE_F8, + /* 119 */ SDL_SCANCODE_F9, + /* 120 */ SDL_SCANCODE_BACKSLASH, + /* 121 */ SDL_SCANCODE_RIGHT, + /* 122 */ SDL_SCANCODE_KP_4, + /* 123 */ SDL_SCANCODE_KP_5, + /* 124 */ SDL_SCANCODE_KP_2, + /* 125 */ SDL_SCANCODE_LGUI, + /* 126 */ SDL_SCANCODE_RGUI, + /* 127 */ SDL_SCANCODE_MENU +}; +/* *INDENT-ON* */ diff --git a/Engine/lib/sdl/src/video/sdlgenblit.pl b/Engine/lib/sdl/src/video/sdlgenblit.pl index 6206ec299..c2a22b049 100755 --- a/Engine/lib/sdl/src/video/sdlgenblit.pl +++ b/Engine/lib/sdl/src/video/sdlgenblit.pl @@ -92,7 +92,7 @@ sub open_file { /* DO NOT EDIT! This file is generated by sdlgenblit.pl */ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -220,16 +220,82 @@ sub output_copycore my $A_is_const_FF = shift; my $s = ""; my $d = ""; + my $dst_has_alpha = ($dst =~ /A/) ? 1 : 0; + my $src_has_alpha = ($src =~ /A/) ? 1 : 0; + my $sa = ""; + my $da = ""; - # Nice and easy... - if ( $src eq $dst && !$modulate && !$blend ) { - print FILE <<__EOF__; + if (!$modulate && !$blend) { + # Nice and easy... + if ( $src eq $dst ) { + print FILE <<__EOF__; *dst = *src; __EOF__ - return; + return; + } + + # Matching color-order + $sa = $src; + $sa =~ s/[A8]//g; + $da = $dst; + $da =~ s/[A8]//g; + if ($sa eq $da) { + if ($dst_has_alpha && $src_has_alpha) { + $da = substr $dst, 0, 1; + if ($da eq "A") { + # RGBA -> ARGB + print FILE <<__EOF__; + pixel = *src; + pixel = (pixel >> 8) | (pixel << 24); + *dst = pixel; +__EOF__ + } else { + # ARGB -> RGBA -- unused + print FILE <<__EOF__; + pixel = *src; + pixel = (pixel << 8) | A; + *dst = pixel; +__EOF__ + } + } elsif ($dst_has_alpha) { + $da = substr $dst, 0, 1; + if ($da eq "A") { + # RGB -> ARGB + print FILE <<__EOF__; + pixel = *src; + pixel |= (A << 24); + *dst = pixel; +__EOF__ + } else { + # RGB -> RGBA -- unused + print FILE <<__EOF__; + pixel = *src; + pixel = (pixel << 8) | A; + *dst = pixel; +__EOF__ + } + } else { + $sa = substr $src, 0, 1; + if ($sa eq "A") { + # ARGB -> RGB + print FILE <<__EOF__; + pixel = *src; + pixel &= 0xFFFFFF; + *dst = pixel; +__EOF__ + } else { + # RGBA -> RGB + print FILE <<__EOF__; + pixel = *src; + pixel >>= 8; + *dst = pixel; +__EOF__ + } + } + return; + } } - my $dst_has_alpha = ($dst =~ /A/) ? 1 : 0; my $ignore_dst_alpha = !$dst_has_alpha && !$blend; if ( $blend ) { @@ -366,6 +432,14 @@ sub output_copyfunc my $is_modulateA_done = 0; my $A_is_const_FF = 0; + my $sa = $src; + my $da = $dst; + my $matching_colors = 0; + + $sa =~ s/[A8]//g; + $da =~ s/[A8]//g; + $matching_colors = (!$modulate && !$blend && ($sa eq $da)) ? 1 : 0; + output_copyfuncname("static void", $src, $dst, $modulate, $blend, $scale, 1, "\n"); print FILE <<__EOF__; { @@ -424,8 +498,8 @@ __EOF__ print FILE <<__EOF__; Uint32 pixel; __EOF__ - if (!$ignore_dst_alpha && !$src_has_alpha) { - if ($modulate){ + if ( !$ignore_dst_alpha && !$src_has_alpha ) { + if ( $modulate ) { $is_modulateA_done = 1; print FILE <<__EOF__; const Uint32 A = (flags & SDL_COPY_MODULATE_ALPHA) ? modulateA : 0xFF; @@ -436,14 +510,18 @@ __EOF__ const Uint32 A = 0xFF; __EOF__ } - print FILE <<__EOF__; + if ( !$matching_colors ) { + print FILE <<__EOF__; Uint32 R, G, B; __EOF__ - } elsif (!$ignore_dst_alpha) { - print FILE <<__EOF__; + } + } elsif ( !$ignore_dst_alpha ) { + if ( !$matching_colors ) { + print FILE <<__EOF__; Uint32 R, G, B, A; __EOF__ - } else { + } + } elsif ( !$matching_colors ) { print FILE <<__EOF__; Uint32 R, G, B; __EOF__ @@ -452,37 +530,28 @@ __EOF__ if ( $scale ) { print FILE <<__EOF__; int srcy, srcx; - int posy, posx; + Uint32 posy, posx; int incy, incx; __EOF__ print FILE <<__EOF__; - srcy = 0; - posy = 0; incy = (info->src_h << 16) / info->dst_h; incx = (info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { $format_type{$src} *src = 0; $format_type{$dst} *dst = ($format_type{$dst} *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = ($format_type{$src} *)(info->src + (srcy * info->src_pitch) + (srcx * $format_size{$src})); + srcx = posx >> 16; + src = ($format_type{$src} *)(info->src + (srcy * info->src_pitch) + (srcx * $format_size{$src})); __EOF__ print FILE <<__EOF__; - } __EOF__ output_copycore($src, $dst, $modulate, $blend, $is_modulateA_done, $A_is_const_FF); print FILE <<__EOF__; diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.h index 1d19b9d10..ee2b5b6a8 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.m index 4b6e16041..4c21d7336 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.h index 4240b619a..5e6b81497 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.m index df3122ebb..dde939dfb 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.h index 86b12a8bf..083e431ce 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,6 +31,7 @@ extern void SDL_QuitGCKeyboard(void); extern void SDL_InitGCMouse(void); extern SDL_bool SDL_HasGCMouse(void); +extern SDL_bool SDL_GCMouseRelativeMode(void); extern void SDL_QuitGCMouse(void); #endif /* SDL_uikitevents_h_ */ diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.m index 06cb4f1aa..b7ef0bf40 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,9 +24,10 @@ #include "../../events/SDL_events_c.h" -#include "SDL_uikitvideo.h" #include "SDL_uikitevents.h" #include "SDL_uikitopengles.h" +#include "SDL_uikitvideo.h" +#include "SDL_uikitwindow.h" #import @@ -86,14 +87,14 @@ static id keyboard_disconnect_observer = nil; static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) { keyboard_connected = SDL_TRUE; - keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *keyboard, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed) + keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *kbrd, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed) { SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode); }; - dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL ); - dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); - keyboard.handlerQueue = queue; + dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL ); + dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); + keyboard.handlerQueue = queue; } static void OnGCKeyboardDisconnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) @@ -182,10 +183,22 @@ void SDL_QuitGCKeyboard(void) static int mice_connected = 0; static id mouse_connect_observer = nil; static id mouse_disconnect_observer = nil; +static bool mouse_relative_mode = SDL_FALSE; + +static void UpdatePointerLock() +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + SDL_Window *window; + + for (window = _this->windows; window != NULL; window = window->next) { + UIKit_UpdatePointerLock(_this, window); + } +} static int SetGCMouseRelativeMode(SDL_bool enabled) { - /* We'll always send relative motion and we can't warp, so nothing to do here */ + mouse_relative_mode = enabled; + UpdatePointerLock(); return 0; } @@ -212,24 +225,28 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14 }; int auxiliary_button = SDL_BUTTON_X1; - for (GCControllerButtonInput *button in mouse.mouseInput.auxiliaryButtons) { - button.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) + for (GCControllerButtonInput *btn in mouse.mouseInput.auxiliaryButtons) { + btn.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { OnGCMouseButtonChanged(mouseID, auxiliary_button, pressed); }; ++auxiliary_button; } - mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouse, float deltaX, float deltaY) + mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouseInput, float deltaX, float deltaY) { - SDL_SendMouseMotion(SDL_GetMouseFocus(), mouseID, SDL_TRUE, (int)deltaX, -(int)deltaY); + if (SDL_GCMouseRelativeMode()) { + SDL_SendMouseMotion(SDL_GetMouseFocus(), mouseID, 1, (int)deltaX, -(int)deltaY); + } }; - dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL ); - dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); - mouse.handlerQueue = queue; + dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL ); + dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); + mouse.handlerQueue = queue; ++mice_connected; + + UpdatePointerLock(); } static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) @@ -245,36 +262,46 @@ static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios for (GCControllerButtonInput *button in mouse.mouseInput.auxiliaryButtons) { button.pressedChangedHandler = nil; } + + UpdatePointerLock(); } void SDL_InitGCMouse(void) { - @autoreleasepool { - /* There is a bug where mouse accumulates duplicate deltas over time in iOS 14.0 */ + @autoreleasepool { + /* There is a bug where mouse accumulates duplicate deltas over time in iOS 14.0 */ if (@available(iOS 14.1, tvOS 14.1, *)) { - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + /* iOS will not send the new pointer touch events if you don't have this key, + * and we need them to differentiate between mouse events and real touch events. + */ + BOOL indirect_input_available = [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"UIApplicationSupportsIndirectInputEvents"] boolValue]; + if (indirect_input_available) { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - mouse_connect_observer = [center addObserverForName:GCMouseDidConnectNotification - object:nil - queue:nil - usingBlock:^(NSNotification *note) { - GCMouse *mouse = note.object; - OnGCMouseConnected(mouse); - }]; + mouse_connect_observer = [center addObserverForName:GCMouseDidConnectNotification + object:nil + queue:nil + usingBlock:^(NSNotification *note) { + GCMouse *mouse = note.object; + OnGCMouseConnected(mouse); + }]; - mouse_disconnect_observer = [center addObserverForName:GCMouseDidDisconnectNotification - object:nil - queue:nil - usingBlock:^(NSNotification *note) { - GCMouse *mouse = note.object; - OnGCMouseDisconnected(mouse); - }]; + mouse_disconnect_observer = [center addObserverForName:GCMouseDidDisconnectNotification + object:nil + queue:nil + usingBlock:^(NSNotification *note) { + GCMouse *mouse = note.object; + OnGCMouseDisconnected(mouse); + }]; - for (GCMouse *mouse in [GCMouse mice]) { - OnGCMouseConnected(mouse); + for (GCMouse *mouse in [GCMouse mice]) { + OnGCMouseConnected(mouse); + } + + SDL_GetMouse()->SetRelativeMouseMode = SetGCMouseRelativeMode; + } else { + NSLog(@"You need UIApplicationSupportsIndirectInputEvents in your Info.plist for mouse support"); } - - SDL_GetMouse()->SetRelativeMouseMode = SetGCMouseRelativeMode; } } } @@ -284,6 +311,11 @@ SDL_bool SDL_HasGCMouse(void) return (mice_connected > 0); } +SDL_bool SDL_GCMouseRelativeMode(void) +{ + return mouse_relative_mode; +} + void SDL_QuitGCMouse(void) { @autoreleasepool { @@ -320,6 +352,11 @@ SDL_bool SDL_HasGCMouse(void) return SDL_FALSE; } +SDL_bool SDL_GCMouseRelativeMode(void) +{ + return SDL_FALSE; +} + void SDL_QuitGCMouse(void) { } diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.h index 4d5fe1d44..9904ccf3b 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.m index c1f78b7af..fdc20c086 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -86,7 +86,7 @@ UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, in action = [UIAlertAction actionWithTitle:@(sdlButton->text) style:style - handler:^(UIAlertAction *action) { + handler:^(UIAlertAction *alertAction) { clickedindex = (int)(sdlButton - messageboxdata->buttons); }]; [alert addAction:action]; diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitmetalview.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitmetalview.h index cd63e7852..91cd0b0a2 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitmetalview.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitmetalview.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -38,7 +38,6 @@ #import #import -#define METALVIEW_TAG 255 @interface SDL_uikitmetalview : SDL_uikitview diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitmetalview.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitmetalview.m index 78c391d91..8274eaff9 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitmetalview.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitmetalview.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,7 +30,9 @@ #if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) -#import "../SDL_sysvideo.h" +#include "SDL_syswm.h" +#include "../SDL_sysvideo.h" + #import "SDL_uikitwindow.h" #import "SDL_uikitmetalview.h" @@ -47,7 +49,7 @@ scale:(CGFloat)scale { if ((self = [super initWithFrame:frame])) { - self.tag = METALVIEW_TAG; + self.tag = SDL_METALVIEW_TAG; self.layer.contentsScale = scale; [self updateDrawableSize]; } @@ -122,7 +124,7 @@ UIKit_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) @autoreleasepool { SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view; - SDL_uikitmetalview* metalview = [view viewWithTag:METALVIEW_TAG]; + SDL_uikitmetalview* metalview = [view viewWithTag:SDL_METALVIEW_TAG]; if (metalview) { CAMetalLayer *layer = (CAMetalLayer*)metalview.layer; assert(layer != NULL); diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.h index 25b9eca6a..d4f3b20ef 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.m index 7ad4bcb19..bfd7a649b 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.h index 1d24b98bb..c2e6d571c 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.m index fb0dae56f..86fefd76c 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -162,8 +162,8 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window) } if (_this->gl_config.share_with_current_context) { - EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext(); - sharegroup = context.sharegroup; + EAGLContext *currContext = (__bridge EAGLContext *) SDL_GL_GetCurrentContext(); + sharegroup = currContext.sharegroup; } if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.h index 91d6ab087..df659a1f1 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.m index b59f1d68c..52158f8d7 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.h index 9b2b7b204..b684e23a8 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.m index 8adaaffae..5d2b96e38 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -93,6 +93,7 @@ UIKit_CreateDevice(int devindex) device->RaiseWindow = UIKit_RaiseWindow; device->SetWindowBordered = UIKit_SetWindowBordered; device->SetWindowFullscreen = UIKit_SetWindowFullscreen; + device->SetWindowMouseGrab = UIKit_SetWindowMouseGrab; device->DestroyWindow = UIKit_DestroyWindow; device->GetWindowWMInfo = UIKit_GetWindowWMInfo; device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds; @@ -159,8 +160,8 @@ UIKit_VideoInit(_THIS) return -1; } - SDL_InitGCKeyboard(); - SDL_InitGCMouse(); + SDL_InitGCKeyboard(); + SDL_InitGCMouse(); return 0; } @@ -168,8 +169,8 @@ UIKit_VideoInit(_THIS) void UIKit_VideoQuit(_THIS) { - SDL_QuitGCKeyboard(); - SDL_QuitGCMouse(); + SDL_QuitGCKeyboard(); + SDL_QuitGCMouse(); UIKit_QuitModes(_this); } @@ -279,7 +280,10 @@ UIKit_ForceUpdateHomeIndicator() #if !defined(SDL_VIDEO_DRIVER_COCOA) void SDL_NSLog(const char *text) { - NSLog(@"%s", text); + @autoreleasepool { + NSString *str = [NSString stringWithUTF8String:text]; + NSLog(@"%@", str); + } } #endif /* SDL_VIDEO_DRIVER_COCOA */ diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitview.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitview.h index 89b68c22a..dcd63c7a5 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitview.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitview.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitview.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitview.m index cb97aed81..77d398c20 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitview.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitview.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -160,7 +160,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick; #if !TARGET_OS_TV && defined(__IPHONE_13_4) - (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)){ - if (request != nil && !SDL_HasGCMouse()) { + if (request != nil && !SDL_GCMouseRelativeMode()) { CGPoint origin = self.bounds.origin; CGPoint point = request.location; diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.h index 77076d707..cff5445a3 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.m index d001e96f0..2ab23abd9 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,8 +27,9 @@ #include "../SDL_sysvideo.h" #include "../../events/SDL_events_c.h" -#import "SDL_uikitviewcontroller.h" -#import "SDL_uikitmessagebox.h" +#include "SDL_uikitviewcontroller.h" +#include "SDL_uikitmessagebox.h" +#include "SDL_uikitevents.h" #include "SDL_uikitvideo.h" #include "SDL_uikitmodes.h" #include "SDL_uikitwindow.h" @@ -246,7 +247,13 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o return UIRectEdgeNone; } } -#endif + +- (BOOL)prefersPointerLocked +{ + return SDL_GCMouseRelativeMode() ? YES : NO; +} + +#endif /* !TARGET_OS_TV */ /* ---- Keyboard related functionality below this line ---- diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitvulkan.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitvulkan.h index eb7accbe4..cc8f777eb 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitvulkan.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitvulkan.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitvulkan.m index a3692d34e..f0f2d2b04 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitvulkan.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitvulkan.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.h index dd7c38823..65dbc875b 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,6 +33,8 @@ extern void UIKit_HideWindow(_THIS, SDL_Window * window); extern void UIKit_RaiseWindow(_THIS, SDL_Window * window); extern void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); +extern void UIKit_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void UIKit_UpdatePointerLock(_THIS, SDL_Window * window); extern void UIKit_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo * info); diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.m index 41b6e4073..6808de4eb 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -161,14 +161,14 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) @autoreleasepool { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata; - SDL_Window *other; + SDL_Window *other; /* We currently only handle a single window per display on iOS */ - for (other = _this->windows; other; other = other->next) { - if (other != window && SDL_GetDisplayForWindow(other) == display) { - return SDL_SetError("Only one window allowed per display."); - } - } + for (other = _this->windows; other; other = other->next) { + if (other != window && SDL_GetDisplayForWindow(other) == display) { + return SDL_SetError("Only one window allowed per display."); + } + } /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the * user, so it's in standby), try to force the display to a resolution @@ -320,6 +320,28 @@ UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display } } +void +UIKit_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + /* There really isn't a concept of window grab or cursor confinement on iOS */ +} + +void +UIKit_UpdatePointerLock(_THIS, SDL_Window * window) +{ +#if !TARGET_OS_TV +#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 + @autoreleasepool { + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + SDL_uikitviewcontroller *viewcontroller = data.viewcontroller; + if (@available(iOS 14.0, *)) { + [viewcontroller setNeedsUpdateOfPrefersPointerLocked]; + } + } +#endif /* defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 */ +#endif /* !TARGET_OS_TV */ +} + void UIKit_DestroyWindow(_THIS, SDL_Window * window) { diff --git a/Engine/lib/sdl/src/video/uikit/keyinfotable.h b/Engine/lib/sdl/src/video/uikit/keyinfotable.h index 83be4ed6f..25df10534 100644 --- a/Engine/lib/sdl/src/video/uikit/keyinfotable.h +++ b/Engine/lib/sdl/src/video/uikit/keyinfotable.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.c b/Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.c new file mode 100644 index 000000000..992c7af84 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.c @@ -0,0 +1,116 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA + +#include "SDL_vitavideo.h" + +#include + +#define SCREEN_W 960 +#define SCREEN_H 544 +#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) +#define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8 + +void *vita_gpu_alloc(SceKernelMemBlockType type, unsigned int size, SceUID *uid) +{ + void *mem; + + if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW) { + size = ALIGN(size, 256*1024); + } else { + size = ALIGN(size, 4*1024); + } + + *uid = sceKernelAllocMemBlock("gpu_mem", type, size, NULL); + + if (*uid < 0) + return NULL; + + if (sceKernelGetMemBlockBase(*uid, &mem) < 0) + return NULL; + + return mem; +} + +void vita_gpu_free(SceUID uid) +{ + void *mem = NULL; + if (sceKernelGetMemBlockBase(uid, &mem) < 0) + return; + sceKernelFreeMemBlock(uid); +} + +int VITA_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SceDisplayFrameBuf framebuf; + + *format = SDL_PIXELFORMAT_ABGR8888; + *pitch = SCREEN_W * 4; + + data->buffer = vita_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + 4 * SCREEN_W * SCREEN_H, + &data->buffer_uid + ); + + // SDL_memset the buffer to black + SDL_memset(data->buffer, 0x0, SCREEN_W*SCREEN_H*4); + + SDL_memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf)); + framebuf.size = sizeof(SceDisplayFrameBuf); + framebuf.base = data->buffer; + framebuf.pitch = SCREEN_W; + framebuf.pixelformat = DISPLAY_PIXEL_FORMAT; + framebuf.width = SCREEN_W; + framebuf.height = SCREEN_H; + sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME); + + *pixels = data->buffer; + + return 0; +} + +int VITA_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +{ + // do nothing + return 0; +} + +void VITA_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if (!data) { + /* The window wasn't fully initialized */ + return; + } + + vita_gpu_free(data->buffer_uid); + data->buffer = NULL; + return; +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.h b/Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.h new file mode 100644 index 000000000..f2d1e1b94 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.h @@ -0,0 +1,27 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +extern int VITA_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); +extern int VITA_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); +extern void VITA_DestroyWindowFramebuffer(_THIS, SDL_Window * window); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitagl.c b/Engine/lib/sdl/src/video/vita/SDL_vitagl.c new file mode 100644 index 000000000..f65022865 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitagl.c @@ -0,0 +1,235 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PIB +#include +#include + +#include "SDL_error.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "SDL_vitagl_c.h" + +/*****************************************************************************/ +/* SDL OpenGL/OpenGL ES functions */ +/*****************************************************************************/ +#define EGLCHK(stmt) \ + do { \ + EGLint err; \ + \ + stmt; \ + err = eglGetError(); \ + if (err != EGL_SUCCESS) { \ + SDL_SetError("EGL error %d", err); \ + return 0; \ + } \ + } while (0) + +void +VITA_GL_KeyboardCallback(ScePigletPreSwapData *data) +{ + SceCommonDialogUpdateParam commonDialogParam; + SDL_zero(commonDialogParam); + commonDialogParam.renderTarget.colorFormat = data->colorFormat; + commonDialogParam.renderTarget.surfaceType = data->surfaceType; + commonDialogParam.renderTarget.colorSurfaceData = data->colorSurfaceData; + commonDialogParam.renderTarget.depthSurfaceData = data->depthSurfaceData; + commonDialogParam.renderTarget.width = data->width; + commonDialogParam.renderTarget.height = data->height; + commonDialogParam.renderTarget.strideInPixels = data->strideInPixels; + commonDialogParam.displaySyncObject = data->displaySyncObject; + + sceCommonDialogUpdate(&commonDialogParam); +} + +int +VITA_GL_LoadLibrary(_THIS, const char *path) +{ + pibInit(PIB_SHACCCG | PIB_GET_PROC_ADDR_CORE); + return 0; +} + +void * +VITA_GL_GetProcAddress(_THIS, const char *proc) +{ + return eglGetProcAddress(proc); +} + +void +VITA_GL_UnloadLibrary(_THIS) +{ + eglTerminate(_this->gl_data->display); +} + +static EGLint width = 960; +static EGLint height = 544; + +SDL_GLContext +VITA_GL_CreateContext(_THIS, SDL_Window * window) +{ + + SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata; + + EGLint attribs[32]; + EGLDisplay display; + EGLContext context; + EGLSurface surface; + EGLConfig config; + EGLint num_configs; + PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC preSwapCallback; + int i; + + const EGLint contextAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + + EGLCHK(display = eglGetDisplay(0)); + + EGLCHK(eglInitialize(display, NULL, NULL)); + wdata->uses_gles = SDL_TRUE; + window->flags |= SDL_WINDOW_FULLSCREEN; + + EGLCHK(eglBindAPI(EGL_OPENGL_ES_API)); + + i = 0; + attribs[i++] = EGL_RED_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_GREEN_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_BLUE_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_DEPTH_SIZE; + attribs[i++] = 0; + attribs[i++] = EGL_ALPHA_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_STENCIL_SIZE; + attribs[i++] = 0; + + attribs[i++] = EGL_SURFACE_TYPE; + attribs[i++] = 5; + + attribs[i++] = EGL_RENDERABLE_TYPE; + attribs[i++] = EGL_OPENGL_ES2_BIT; + + attribs[i++] = EGL_CONFORMANT; + attribs[i++] = EGL_OPENGL_ES2_BIT; + + attribs[i++] = EGL_NONE; + + EGLCHK(eglChooseConfig(display, attribs, &config, 1, &num_configs)); + + if (num_configs == 0) + { + SDL_SetError("No valid EGL configs for requested mode"); + return 0; + } + + + EGLCHK(surface = eglCreateWindowSurface(display, config, VITA_WINDOW_960X544, NULL)); + + EGLCHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs)); + + EGLCHK(eglMakeCurrent(display, surface, surface, context)); + + EGLCHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); + EGLCHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); + + _this->gl_data->display = display; + _this->gl_data->context = context; + _this->gl_data->surface = surface; + + preSwapCallback = (PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC) eglGetProcAddress("eglPigletVitaSetPreSwapCallbackSCE"); + preSwapCallback(VITA_GL_KeyboardCallback); + + return context; +} + +int +VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ + if (!eglMakeCurrent(_this->gl_data->display, _this->gl_data->surface, + _this->gl_data->surface, _this->gl_data->context)) + { + return SDL_SetError("Unable to make EGL context current"); + } + return 0; +} + +int +VITA_GL_SetSwapInterval(_THIS, int interval) +{ + EGLBoolean status; + status = eglSwapInterval(_this->gl_data->display, interval); + if (status == EGL_TRUE) { + /* Return success to upper level */ + _this->gl_data->swapinterval = interval; + return 0; + } + /* Failed to set swap interval */ + return SDL_SetError("Unable to set the EGL swap interval"); +} + +int +VITA_GL_GetSwapInterval(_THIS) +{ + return _this->gl_data->swapinterval; +} + +int +VITA_GL_SwapWindow(_THIS, SDL_Window * window) +{ + if (!eglSwapBuffers(_this->gl_data->display, _this->gl_data->surface)) { + return SDL_SetError("eglSwapBuffers() failed"); + } + return 0; +} + +void +VITA_GL_DeleteContext(_THIS, SDL_GLContext context) +{ + SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; + EGLBoolean status; + + if (phdata->egl_initialized != SDL_TRUE) { + SDL_SetError("VITA: GLES initialization failed, no OpenGL ES support"); + return; + } + + /* Check if OpenGL ES connection has been initialized */ + if (_this->gl_data->display != EGL_NO_DISPLAY) { + if (context != EGL_NO_CONTEXT) { + status = eglDestroyContext(_this->gl_data->display, context); + if (status != EGL_TRUE) { + /* Error during OpenGL ES context destroying */ + SDL_SetError("VITA: OpenGL ES context destroy error"); + return; + } + } + } + + return; +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitagl_c.h b/Engine/lib/sdl/src/video/vita/SDL_vitagl_c.h new file mode 100644 index 000000000..272653d70 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitagl_c.h @@ -0,0 +1,57 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_vitagl_c_h_ +#define SDL_vitagl_c_h_ + + +#include +#include +#include +#include +#include + +#include "SDL_vitavideo.h" + + +typedef struct SDL_GLDriverData { + EGLDisplay display; + EGLContext context; + EGLSurface surface; + uint32_t swapinterval; +}SDL_GLDriverData; + +extern void * VITA_GL_GetProcAddress(_THIS, const char *proc); +extern int VITA_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context); +extern void VITA_GL_SwapBuffers(_THIS); + +extern int VITA_GL_SwapWindow(_THIS, SDL_Window * window); +extern SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window); + +extern int VITA_GL_LoadLibrary(_THIS, const char *path); +extern void VITA_GL_UnloadLibrary(_THIS); +extern int VITA_GL_SetSwapInterval(_THIS, int interval); +extern int VITA_GL_GetSwapInterval(_THIS); + + +#endif /* SDL_vitagl_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr.c b/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr.c new file mode 100644 index 000000000..3b7fb7477 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr.c @@ -0,0 +1,103 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR +#include +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "../SDL_egl_c.h" +#include "SDL_vitagl_pvr_c.h" + +#define MAX_PATH 256 // vita limits are somehow wrong + +int +VITA_GL_LoadLibrary(_THIS, const char *path) +{ + PVRSRV_PSP2_APPHINT hint; + char* override = SDL_getenv("VITA_MODULE_PATH"); + char* skip_init = SDL_getenv("VITA_PVR_SKIP_INIT"); + char* default_path = "app0:module"; + char target_path[MAX_PATH]; + + if (skip_init == NULL) // we don't care about actual value + { + if (override != NULL) + { + default_path = override; + } + + sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL); + sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + PVRSRVInitializeAppHint(&hint); + + SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx"); + SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx"); + SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx"); + + PVRSRVCreateVirtualAppHint(&hint); + } + + return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) 0, 0); +} + +SDL_GLContext +VITA_GL_CreateContext(_THIS, SDL_Window * window) +{ + return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); +} + +int +VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ + if (window && context) { + return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context); + } else { + return SDL_EGL_MakeCurrent(_this, NULL, NULL); + } +} + +int +VITA_GL_SwapWindow(_THIS, SDL_Window * window) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + if (videodata->ime_active) { + sceImeUpdate(); + } + return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); +} + + +#endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h b/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h new file mode 100644 index 000000000..670eaebb0 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_vitagl_c_h_ +#define SDL_vitagl_c_h_ + +#include "SDL_vitavideo.h" + +extern int VITA_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context); +extern int VITA_GL_SwapWindow(_THIS, SDL_Window * window); +extern SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window); +extern int VITA_GL_LoadLibrary(_THIS, const char *path); + + +#endif /* SDL_vitagl_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitakeyboard.c b/Engine/lib/sdl/src/video/vita/SDL_vitakeyboard.c new file mode 100644 index 000000000..409d424b1 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitakeyboard.c @@ -0,0 +1,203 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA + +#include +#include +#include + +#include "SDL_events.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "SDL_vitakeyboard.h" +#include "../../events/SDL_keyboard_c.h" + +SceHidKeyboardReport k_reports[SCE_HID_MAX_REPORT]; +int keyboard_hid_handle = 0; +Uint8 prev_keys[6] = {0}; +Uint8 prev_modifiers = 0; +Uint8 locks = 0; +Uint8 lock_key_down = 0; + +void +VITA_InitKeyboard(void) +{ +#if defined(SDL_VIDEO_VITA_PVR) + sceSysmoduleLoadModule(SCE_SYSMODULE_IME); /** For PVR OSK Support **/ +#endif + sceHidKeyboardEnumerate(&keyboard_hid_handle, 1); +} + +void +VITA_PollKeyboard(void) +{ + // We skip polling keyboard if no window is created + if (Vita_Window == NULL) + return; + + if (keyboard_hid_handle > 0) + { + int numReports = sceHidKeyboardRead(keyboard_hid_handle, (SceHidKeyboardReport**)&k_reports, SCE_HID_MAX_REPORT); + + if (numReports < 0) { + keyboard_hid_handle = 0; + } + else if (numReports) { + // Numlock and Capslock state changes only on a SDL_PRESSED event + // The k_report only reports the state of the LED + if (k_reports[numReports - 1].modifiers[1] & 0x1) { + if (!(locks & 0x1)) { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR); + locks |= 0x1; + } + } + else { + if (locks & 0x1) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR); + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR); + locks &= ~0x1; + } + } + + if (k_reports[numReports - 1].modifiers[1] & 0x2) { + if (!(locks & 0x2)) { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); + locks |= 0x2; + } + } + else { + if (locks & 0x2) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); + locks &= ~0x2; + } + } + + if (k_reports[numReports - 1].modifiers[1] & 0x4) { + if (!(locks & 0x4)) { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_SCROLLLOCK); + locks |= 0x4; + } + } + else { + if (locks & 0x4) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_SCROLLLOCK); + locks &= ~0x4; + } + } + + { + Uint8 changed_modifiers = k_reports[numReports - 1].modifiers[0] ^ prev_modifiers; + + if (changed_modifiers & 0x01) { + if (prev_modifiers & 0x01) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LCTRL); + } + else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LCTRL); + } + } + if (changed_modifiers & 0x02) { + if (prev_modifiers & 0x02) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT); + } + else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT); + } + } + if (changed_modifiers & 0x04) { + if (prev_modifiers & 0x04) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LALT); + } + else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LALT); + } + } + if (changed_modifiers & 0x08) { + if (prev_modifiers & 0x08) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LGUI); + } + else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LGUI); + } + } + if (changed_modifiers & 0x10) { + if (prev_modifiers & 0x10) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RCTRL); + } + else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RCTRL); + } + } + if (changed_modifiers & 0x20) { + if (prev_modifiers & 0x20) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT); + } + else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RSHIFT); + } + } + if (changed_modifiers & 0x40) { + if (prev_modifiers & 0x40) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RALT); + } + else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RALT); + } + } + if (changed_modifiers & 0x80) { + if (prev_modifiers & 0x80) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RGUI); + } + else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RGUI); + } + } + } + + prev_modifiers = k_reports[numReports - 1].modifiers[0]; + + for (int i = 0; i < 6; i++) { + + int keyCode = k_reports[numReports - 1].keycodes[i]; + + if (keyCode != prev_keys[i]) { + + if (prev_keys[i]) { + SDL_SendKeyboardKey(SDL_RELEASED, prev_keys[i]); + } + if (keyCode) { + SDL_SendKeyboardKey(SDL_PRESSED, keyCode); + } + prev_keys[i] = keyCode; + } + } + } + } +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitakeyboard.h b/Engine/lib/sdl/src/video/vita/SDL_vitakeyboard.h new file mode 100644 index 000000000..419cba7a3 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitakeyboard.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_vitakeyboard_h +#define _SDL_vitakeyboard_h + +#include "../../SDL_internal.h" + +/* Keyboard functions */ +extern void VITA_InitKeyboard(void); +extern void VITA_PollKeyboard(void); + +#endif /* _SDL_vitakeyboard_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitamessagebox.c b/Engine/lib/sdl/src/video/vita/SDL_vitamessagebox.c new file mode 100644 index 000000000..492113986 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitamessagebox.c @@ -0,0 +1,150 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA + +#include "SDL_vitavideo.h" +#include "SDL_vitamessagebox.h" +#include + +#if SDL_VIDEO_RENDER_VITA_GXM +#include "../../render/vitagxm/SDL_render_vita_gxm_tools.h" +#endif /* SDL_VIDEO_RENDER_VITA_GXM */ + +int VITA_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ +#if SDL_VIDEO_RENDER_VITA_GXM + SceMsgDialogParam param; + SceMsgDialogUserMessageParam msgParam; + SceMsgDialogButtonsParam buttonParam; + SceDisplayFrameBuf dispparam; + char message[512]; + + SceMsgDialogResult dialog_result; + SceCommonDialogErrorCode init_result; + SDL_bool setup_minimal_gxm = SDL_FALSE; + + if (messageboxdata->numbuttons > 3) + { + return -1; + } + + SDL_zero(param); + sceMsgDialogParamInit(¶m); + param.mode = SCE_MSG_DIALOG_MODE_USER_MSG; + + SDL_zero(msgParam); + SDL_snprintf(message, sizeof(message), "%s\r\n\r\n%s", messageboxdata->title, messageboxdata->message); + + msgParam.msg = (const SceChar8*)message; + SDL_zero(buttonParam); + + if (messageboxdata->numbuttons == 3) + { + msgParam.buttonType = SCE_MSG_DIALOG_BUTTON_TYPE_3BUTTONS; + msgParam.buttonParam = &buttonParam; + buttonParam.msg1 = messageboxdata->buttons[0].text; + buttonParam.msg2 = messageboxdata->buttons[1].text; + buttonParam.msg3 = messageboxdata->buttons[2].text; + } + else if (messageboxdata->numbuttons == 2) + { + msgParam.buttonType = SCE_MSG_DIALOG_BUTTON_TYPE_YESNO; + } + else if (messageboxdata->numbuttons == 1) + { + msgParam.buttonType = SCE_MSG_DIALOG_BUTTON_TYPE_OK; + } + param.userMsgParam = &msgParam; + + dispparam.size = sizeof(dispparam); + + init_result = sceMsgDialogInit(¶m); + + // Setup display if it hasn't been initialized before + if (init_result == SCE_COMMON_DIALOG_ERROR_GXM_IS_UNINITIALIZED) + { + gxm_minimal_init_for_common_dialog(); + init_result = sceMsgDialogInit(¶m); + setup_minimal_gxm = SDL_TRUE; + } + + gxm_init_for_common_dialog(); + + if (init_result >= 0) + { + while (sceMsgDialogGetStatus() == SCE_COMMON_DIALOG_STATUS_RUNNING) + { + gxm_swap_for_common_dialog(); + } + SDL_zero(dialog_result); + sceMsgDialogGetResult(&dialog_result); + + if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_BUTTON1) + { + *buttonid = messageboxdata->buttons[0].buttonid; + } + else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_BUTTON2) + { + *buttonid = messageboxdata->buttons[1].buttonid; + } + else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_BUTTON3) + { + *buttonid = messageboxdata->buttons[2].buttonid; + } + else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_YES) + { + *buttonid = messageboxdata->buttons[0].buttonid; + } + else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_NO) + { + *buttonid = messageboxdata->buttons[1].buttonid; + } + else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_OK) + { + *buttonid = messageboxdata->buttons[0].buttonid; + } + sceMsgDialogTerm(); + } + else + { + return -1; + } + + gxm_term_for_common_dialog(); + + if (setup_minimal_gxm) + { + gxm_minimal_term_for_common_dialog(); + } + + return 0; +#else + (void)messageboxdata; + (void)buttonid; + return -1; +#endif +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitamessagebox.h b/Engine/lib/sdl/src/video/vita/SDL_vitamessagebox.h new file mode 100644 index 000000000..445636010 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitamessagebox.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_vitamessagebox_h_ +#define SDL_vitamessagebox_h_ + +#if SDL_VIDEO_DRIVER_VITA + +extern int VITA_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +#endif /* SDL_vitamessagebox_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitamouse.c b/Engine/lib/sdl/src/video/vita/SDL_vitamouse.c new file mode 100644 index 000000000..398a19483 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitamouse.c @@ -0,0 +1,94 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA + +#include +#include +#include + +#include "SDL_events.h" +#include "SDL_log.h" +#include "SDL_mouse.h" +#include "SDL_vitavideo.h" +#include "SDL_vitamouse_c.h" +#include "../../events/SDL_mouse_c.h" + +SceHidMouseReport m_reports[SCE_HID_MAX_REPORT]; +int mouse_hid_handle = 0; +Uint8 prev_buttons = 0; + +void +VITA_InitMouse(void) +{ + sceHidMouseEnumerate(&mouse_hid_handle, 1); +} + +void +VITA_PollMouse(void) +{ + // We skip polling mouse if no window is created + if (Vita_Window == NULL) + return; + + if (mouse_hid_handle > 0) + { + int numReports = sceHidMouseRead(mouse_hid_handle, (SceHidMouseReport**)&m_reports, SCE_HID_MAX_REPORT); + if (numReports > 0) + { + for (int i = 0; i <= numReports - 1; i++) + { + Uint8 changed_buttons = m_reports[i].buttons ^ prev_buttons; + + if (changed_buttons & 0x1) { + if (prev_buttons & 0x1) + SDL_SendMouseButton(Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_LEFT); + else + SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_LEFT); + } + if (changed_buttons & 0x2) { + if (prev_buttons & 0x2) + SDL_SendMouseButton(Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_RIGHT); + else + SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_RIGHT); + } + if (changed_buttons & 0x4) { + if (prev_buttons & 0x4) + SDL_SendMouseButton(Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_MIDDLE); + else + SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_MIDDLE); + } + + prev_buttons = m_reports[i].buttons; + + if (m_reports[i].rel_x || m_reports[i].rel_y) + { + SDL_SendMouseMotion(Vita_Window, 0, 1, m_reports[i].rel_x, m_reports[i].rel_y); + } + } + } + } +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitamouse_c.h b/Engine/lib/sdl/src/video/vita/SDL_vitamouse_c.h new file mode 100644 index 000000000..3549da102 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitamouse_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_vitamouse_h +#define _SDL_vitamouse_h + +#include "../../SDL_internal.h" + +/* mouse functions */ +extern void VITA_InitMouse(void); +extern void VITA_PollMouse(void); + +#endif /* _SDL_vitamouse_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitatouch.c b/Engine/lib/sdl/src/video/vita/SDL_vitatouch.c new file mode 100644 index 000000000..43a3ecbd2 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitatouch.c @@ -0,0 +1,194 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA + +#include +#include + +#include "SDL_events.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "SDL_vitatouch.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" + +SceTouchData touch_old[SCE_TOUCH_PORT_MAX_NUM]; +SceTouchData touch[SCE_TOUCH_PORT_MAX_NUM]; + +SDL_FRect area_info[SCE_TOUCH_PORT_MAX_NUM]; + +struct{ + float min; + float range; +} force_info[SCE_TOUCH_PORT_MAX_NUM]; + +char* disableFrontPoll = NULL; +char* disableBackPoll = NULL; + +void +VITA_InitTouch(void) +{ + disableFrontPoll = SDL_getenv("VITA_DISABLE_TOUCH_FRONT"); + disableBackPoll = SDL_getenv("VITA_DISABLE_TOUCH_BACK"); + + sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START); + sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK, SCE_TOUCH_SAMPLING_STATE_START); + sceTouchEnableTouchForce(SCE_TOUCH_PORT_FRONT); + sceTouchEnableTouchForce(SCE_TOUCH_PORT_BACK); + + for(int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) { + SceTouchPanelInfo panelinfo; + sceTouchGetPanelInfo(port, &panelinfo); + + area_info[port].x = (float)panelinfo.minAaX; + area_info[port].y = (float)panelinfo.minAaY; + area_info[port].w = (float)(panelinfo.maxAaX - panelinfo.minAaX); + area_info[port].h = (float)(panelinfo.maxAaY - panelinfo.minAaY); + + force_info[port].min = (float)panelinfo.minForce; + force_info[port].range = (float)(panelinfo.maxForce - panelinfo.minForce); + } + + // Support passing both front and back touch devices in events + SDL_AddTouch((SDL_TouchID)0, SDL_TOUCH_DEVICE_DIRECT, "Front"); + SDL_AddTouch((SDL_TouchID)1, SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, "Back"); +} + +void +VITA_QuitTouch(void){ + sceTouchDisableTouchForce(SCE_TOUCH_PORT_FRONT); + sceTouchDisableTouchForce(SCE_TOUCH_PORT_BACK); +} + +void +VITA_PollTouch(void) +{ + SDL_FingerID finger_id = 0; + int port; + + // We skip polling touch if no window is created + if (Vita_Window == NULL) + return; + + SDL_memcpy(touch_old, touch, sizeof(touch_old)); + + for(port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) { + /** Skip polling of Touch Device if environment variable is set **/ + if (((port == 0) && disableFrontPoll) || ((port == 1) && disableBackPoll)) { + continue; + } + sceTouchPeek(port, &touch[port], 1); + if (touch[port].reportNum > 0) { + for (int i = 0; i < touch[port].reportNum; i++) + { + // adjust coordinates and forces to return normalized values + // for the front, screen area is used as a reference (for direct touch) + // e.g. touch_x = 1.0 corresponds to screen_x = 960 + // for the back panel, the active touch area is used as reference + float x = 0; + float y = 0; + float force = (touch[port].report[i].force - force_info[port].min) / force_info[port].range; + int finger_down = 0; + + if (touch_old[port].reportNum > 0) { + for (int j = 0; j < touch_old[port].reportNum; j++) { + if (touch[port].report[i].id == touch_old[port].report[j].id ) { + finger_down = 1; + } + } + } + + VITA_ConvertTouchXYToSDLXY(&x, &y, touch[port].report[i].x, touch[port].report[i].y, port); + finger_id = (SDL_FingerID) touch[port].report[i].id; + + // Skip if finger was already previously down + if(!finger_down) { + // Send an initial touch + SDL_SendTouch((SDL_TouchID)port, + finger_id, + Vita_Window, + SDL_TRUE, + x, + y, + force); + } + + // Always send the motion + SDL_SendTouchMotion((SDL_TouchID)port, + finger_id, + Vita_Window, + x, + y, + force); + } + } + + // some fingers might have been let go + if (touch_old[port].reportNum > 0) { + for (int i = 0; i < touch_old[port].reportNum; i++) { + int finger_up = 1; + if (touch[port].reportNum > 0) { + for (int j = 0; j < touch[port].reportNum; j++) { + if (touch[port].report[j].id == touch_old[port].report[i].id ) { + finger_up = 0; + } + } + } + if (finger_up == 1) { + float x = 0; + float y = 0; + float force = (touch_old[port].report[i].force - force_info[port].min) / force_info[port].range; + VITA_ConvertTouchXYToSDLXY(&x, &y, touch_old[port].report[i].x, touch_old[port].report[i].y, port); + finger_id = (SDL_FingerID) touch_old[port].report[i].id; + // Finger released from screen + SDL_SendTouch((SDL_TouchID)port, + finger_id, + Vita_Window, + SDL_FALSE, + x, + y, + force); + } + } + } + } +} + +void VITA_ConvertTouchXYToSDLXY(float *sdl_x, float *sdl_y, int vita_x, int vita_y, int port) { + float x = (vita_x - area_info[port].x) / area_info[port].w; + float y = (vita_y - area_info[port].y) / area_info[port].h; + + x = SDL_max(x, 0.0); + x = SDL_min(x, 1.0); + + y = SDL_max(y, 0.0); + y = SDL_min(y, 1.0); + + *sdl_x = x; + *sdl_y = y; +} + + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitatouch.h b/Engine/lib/sdl/src/video/vita/SDL_vitatouch.h new file mode 100644 index 000000000..02f31bc42 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitatouch.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_vitatouch_h +#define _SDL_vitatouch_h + +#include "../../SDL_internal.h" + +/* Touch functions */ +extern void VITA_InitTouch(void); +extern void VITA_QuitTouch(void); +extern void VITA_PollTouch(void); +void VITA_ConvertTouchXYToSDLXY(float *sdl_x, float *sdl_y, int vita_x, int vita_y, int port); + +#endif /* _SDL_vitatouch_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitavideo.c b/Engine/lib/sdl/src/video/vita/SDL_vitavideo.c new file mode 100644 index 000000000..778a87073 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitavideo.c @@ -0,0 +1,601 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA + +/* SDL internals */ +#include "../SDL_sysvideo.h" +#include "SDL_version.h" +#include "SDL_syswm.h" +#include "SDL_loadso.h" +#include "SDL_events.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_keyboard_c.h" + +/* VITA declarations */ +#include +#include "SDL_vitavideo.h" +#include "SDL_vitatouch.h" +#include "SDL_vitakeyboard.h" +#include "SDL_vitamouse_c.h" +#include "SDL_vitaframebuffer.h" + +#if defined(SDL_VIDEO_VITA_PIB) + #include "SDL_vitagl_c.h" +#elif defined(SDL_VIDEO_VITA_PVR) + #include "SDL_vitagl_pvr_c.h" + #include "../SDL_egl_c.h" + #define VITA_GL_GetProcAddress SDL_EGL_GetProcAddress + #define VITA_GL_UnloadLibrary SDL_EGL_UnloadLibrary + #define VITA_GL_SetSwapInterval SDL_EGL_SetSwapInterval + #define VITA_GL_GetSwapInterval SDL_EGL_GetSwapInterval + #define VITA_GL_DeleteContext SDL_EGL_DeleteContext +#endif + +SDL_Window *Vita_Window; + +static void +VITA_Destroy(SDL_VideoDevice * device) +{ +/* SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata; */ + + SDL_free(device->driverdata); + SDL_free(device); +// if (device->driverdata != NULL) { +// device->driverdata = NULL; +// } +} + +static SDL_VideoDevice * +VITA_Create() +{ + SDL_VideoDevice *device; + SDL_VideoData *phdata; +#if SDL_VIDEO_VITA_PIB + SDL_GLDriverData *gldata; +#endif + /* Initialize SDL_VideoDevice structure */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (device == NULL) { + SDL_OutOfMemory(); + return NULL; + } + + /* Initialize internal VITA specific data */ + phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + if (phdata == NULL) { + SDL_OutOfMemory(); + SDL_free(device); + return NULL; + } +#if SDL_VIDEO_VITA_PIB + + gldata = (SDL_GLDriverData *) SDL_calloc(1, sizeof(SDL_GLDriverData)); + if (gldata == NULL) { + SDL_OutOfMemory(); + SDL_free(device); + SDL_free(phdata); + return NULL; + } + device->gl_data = gldata; + phdata->egl_initialized = SDL_TRUE; +#endif + phdata->ime_active = SDL_FALSE; + + device->driverdata = phdata; + + /* Setup amount of available displays and current display */ + device->num_displays = 0; + + /* Set device free function */ + device->free = VITA_Destroy; + + /* Setup all functions which we can handle */ + device->VideoInit = VITA_VideoInit; + device->VideoQuit = VITA_VideoQuit; + device->GetDisplayModes = VITA_GetDisplayModes; + device->SetDisplayMode = VITA_SetDisplayMode; + device->CreateSDLWindow = VITA_CreateWindow; + device->CreateSDLWindowFrom = VITA_CreateWindowFrom; + device->SetWindowTitle = VITA_SetWindowTitle; + device->SetWindowIcon = VITA_SetWindowIcon; + device->SetWindowPosition = VITA_SetWindowPosition; + device->SetWindowSize = VITA_SetWindowSize; + device->ShowWindow = VITA_ShowWindow; + device->HideWindow = VITA_HideWindow; + device->RaiseWindow = VITA_RaiseWindow; + device->MaximizeWindow = VITA_MaximizeWindow; + device->MinimizeWindow = VITA_MinimizeWindow; + device->RestoreWindow = VITA_RestoreWindow; + device->SetWindowMouseGrab = VITA_SetWindowGrab; + device->SetWindowKeyboardGrab = VITA_SetWindowGrab; + device->DestroyWindow = VITA_DestroyWindow; + device->GetWindowWMInfo = VITA_GetWindowWMInfo; + +/* + // Disabled, causes issues on high-framerate updates. SDL still emulates this. + device->CreateWindowFramebuffer = VITA_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = VITA_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = VITA_DestroyWindowFramebuffer; +*/ + +#if defined(SDL_VIDEO_VITA_PIB) || defined(SDL_VIDEO_VITA_PVR) + device->GL_LoadLibrary = VITA_GL_LoadLibrary; + device->GL_GetProcAddress = VITA_GL_GetProcAddress; + device->GL_UnloadLibrary = VITA_GL_UnloadLibrary; + device->GL_CreateContext = VITA_GL_CreateContext; + device->GL_MakeCurrent = VITA_GL_MakeCurrent; + device->GL_SetSwapInterval = VITA_GL_SetSwapInterval; + device->GL_GetSwapInterval = VITA_GL_GetSwapInterval; + device->GL_SwapWindow = VITA_GL_SwapWindow; + device->GL_DeleteContext = VITA_GL_DeleteContext; +#endif + + device->HasScreenKeyboardSupport = VITA_HasScreenKeyboardSupport; + device->ShowScreenKeyboard = VITA_ShowScreenKeyboard; + device->HideScreenKeyboard = VITA_HideScreenKeyboard; + device->IsScreenKeyboardShown = VITA_IsScreenKeyboardShown; + + device->PumpEvents = VITA_PumpEvents; + + return device; +} + +VideoBootStrap VITA_bootstrap = { + "VITA", + "VITA Video Driver", + VITA_Create +}; + +/*****************************************************************************/ +/* SDL Video and Display initialization/handling functions */ +/*****************************************************************************/ +int +VITA_VideoInit(_THIS) +{ + SDL_VideoDisplay display; + SDL_DisplayMode current_mode; +#if defined(SDL_VIDEO_VITA_PVR) + char* res = SDL_getenv("VITA_RESOLUTION"); +#endif + SDL_zero(current_mode); + +#if defined(SDL_VIDEO_VITA_PVR) + if (res) { + /* 1088i for PSTV (Or Sharpscale) */ + if (!SDL_strncmp(res, "1080", 4)) { + current_mode.w = 1920; + current_mode.h = 1088; + } + /* 725p for PSTV (Or Sharpscale) */ + else if (!SDL_strncmp(res, "720", 3)) { + current_mode.w = 1280; + current_mode.h = 725; + } + } + /* 544p */ + else { +#endif + current_mode.w = 960; + current_mode.h = 544; +#if defined(SDL_VIDEO_VITA_PVR) + } +#endif + + current_mode.refresh_rate = 60; + /* 32 bpp for default */ + current_mode.format = SDL_PIXELFORMAT_ABGR8888; + + current_mode.driverdata = NULL; + + SDL_zero(display); + display.desktop_mode = current_mode; + display.current_mode = current_mode; + display.driverdata = NULL; + + SDL_AddVideoDisplay(&display, SDL_FALSE); + VITA_InitTouch(); + VITA_InitKeyboard(); + VITA_InitMouse(); + + return 1; +} + +void +VITA_VideoQuit(_THIS) +{ + VITA_QuitTouch(); +} + +void +VITA_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +{ + SDL_AddDisplayMode(display, &display->current_mode); +} + +int +VITA_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + return 0; +} + +int +VITA_CreateWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *wdata; +#if defined(SDL_VIDEO_VITA_PVR) + Psp2NativeWindow win; +#endif + + /* Allocate window internal data */ + wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); + if (wdata == NULL) { + return SDL_OutOfMemory(); + } + + /* Setup driver data for this window */ + window->driverdata = wdata; + + // Vita can only have one window + if (Vita_Window != NULL) + { + return SDL_SetError("Only one window supported"); + } + + Vita_Window = window; + +#if defined(SDL_VIDEO_VITA_PVR) + win.type = PSP2_DRAWABLE_TYPE_WINDOW; + win.numFlipBuffers = 2; + win.flipChainThrdAffinity = 0x20000; + + /* 1088i for PSTV (Or Sharpscale) */ + if (window->w == 1920) { + win.windowSize = PSP2_WINDOW_1920X1088; + } + /* 725p for PSTV (Or Sharpscale) */ + else if (window->w == 1280) { + win.windowSize = PSP2_WINDOW_1280X725; + } + /* 544p */ + else { + win.windowSize = PSP2_WINDOW_960X544; + } + if ((window->flags & SDL_WINDOW_OPENGL) != 0) { + wdata->egl_surface = SDL_EGL_CreateSurface(_this, &win); + + if (wdata->egl_surface == EGL_NO_SURFACE) { + return SDL_SetError("Could not create GLES window surface"); + } + } +#endif + + // fix input, we need to find a better way + SDL_SetKeyboardFocus(window); + + /* Window has been successfully created */ + return 0; +} + +int +VITA_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +{ + return -1; +} + +void +VITA_SetWindowTitle(_THIS, SDL_Window * window) +{ +} +void +VITA_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) +{ +} +void +VITA_SetWindowPosition(_THIS, SDL_Window * window) +{ +} +void +VITA_SetWindowSize(_THIS, SDL_Window * window) +{ +} +void +VITA_ShowWindow(_THIS, SDL_Window * window) +{ +} +void +VITA_HideWindow(_THIS, SDL_Window * window) +{ +} +void +VITA_RaiseWindow(_THIS, SDL_Window * window) +{ +} +void +VITA_MaximizeWindow(_THIS, SDL_Window * window) +{ +} +void +VITA_MinimizeWindow(_THIS, SDL_Window * window) +{ +} +void +VITA_RestoreWindow(_THIS, SDL_Window * window) +{ +} +void +VITA_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ +} + +void +VITA_DestroyWindow(_THIS, SDL_Window * window) +{ +// SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + SDL_WindowData *data; + + data = window->driverdata; + if (data) { + // TODO: should we destroy egl context? No one sane should recreate ogl window as non-ogl + SDL_free(data); + } + + window->driverdata = NULL; + Vita_Window = NULL; +} + +/*****************************************************************************/ +/* SDL Window Manager function */ +/*****************************************************************************/ +SDL_bool +VITA_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +{ + if (info->version.major <= SDL_MAJOR_VERSION) { + return SDL_TRUE; + } else { + SDL_SetError("application not compiled with SDL %d.%d\n", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + return SDL_FALSE; + } + + /* Failed to get window manager information */ + return SDL_FALSE; +} + +SDL_bool VITA_HasScreenKeyboardSupport(_THIS) +{ + return SDL_TRUE; +} + +#if !defined(SCE_IME_LANGUAGE_ENGLISH_US) +#define SCE_IME_LANGUAGE_ENGLISH_US SCE_IME_LANGUAGE_ENGLISH +#endif + +static void utf16_to_utf8(const uint16_t *src, uint8_t *dst) { + int i; + for (i = 0; src[i]; i++) { + if ((src[i] & 0xFF80) == 0) { + *(dst++) = src[i] & 0xFF; + } else if((src[i] & 0xF800) == 0) { + *(dst++) = ((src[i] >> 6) & 0xFF) | 0xC0; + *(dst++) = (src[i] & 0x3F) | 0x80; + } else if((src[i] & 0xFC00) == 0xD800 && (src[i + 1] & 0xFC00) == 0xDC00) { + *(dst++) = (((src[i] + 64) >> 8) & 0x3) | 0xF0; + *(dst++) = (((src[i] >> 2) + 16) & 0x3F) | 0x80; + *(dst++) = ((src[i] >> 4) & 0x30) | 0x80 | ((src[i + 1] << 2) & 0xF); + *(dst++) = (src[i + 1] & 0x3F) | 0x80; + i += 1; + } else { + *(dst++) = ((src[i] >> 12) & 0xF) | 0xE0; + *(dst++) = ((src[i] >> 6) & 0x3F) | 0x80; + *(dst++) = (src[i] & 0x3F) | 0x80; + } + } + + *dst = '\0'; +} + +#if defined (SDL_VIDEO_VITA_PVR) +SceWChar16 libime_out[SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1]; +char libime_initval[8] = { 1 }; +SceImeCaret caret_rev; + +void VITA_ImeEventHandler(void *arg, const SceImeEventData *e) +{ + SDL_VideoData *videodata = (SDL_VideoData *)arg; + SDL_Scancode scancode; + uint8_t utf8_buffer[SCE_IME_MAX_TEXT_LENGTH]; + switch (e->id) { + case SCE_IME_EVENT_UPDATE_TEXT: + if (e->param.text.caretIndex == 0) { + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_BACKSPACE); + sceImeSetText((SceWChar16 *)libime_initval, 4); + } + else { + scancode = SDL_GetScancodeFromKey(*(SceWChar16 *)&libime_out[1]); + if (scancode == SDL_SCANCODE_SPACE) { + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_SPACE); + } + else { + utf16_to_utf8((SceWChar16 *)&libime_out[1], utf8_buffer); + SDL_SendKeyboardText((const char*)utf8_buffer); + } + SDL_memset(&caret_rev, 0, sizeof(SceImeCaret)); + SDL_memset(libime_out, 0, ((SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1) * sizeof(SceWChar16))); + caret_rev.index = 1; + sceImeSetCaret(&caret_rev); + sceImeSetText((SceWChar16 *)libime_initval, 4); + } + break; + case SCE_IME_EVENT_PRESS_ENTER: + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RETURN); + case SCE_IME_EVENT_PRESS_CLOSE: + sceImeClose(); + videodata->ime_active = SDL_FALSE; + break; + } +} +#endif + +void VITA_ShowScreenKeyboard(_THIS, SDL_Window *window) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + SceInt32 res; + +#if defined(SDL_VIDEO_VITA_PVR) + + SceUInt32 libime_work[SCE_IME_WORK_BUFFER_SIZE / sizeof(SceInt32)]; + SceImeParam param; + + sceImeParamInit(¶m); + + SDL_memset(libime_out, 0, ((SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1) * sizeof(SceWChar16))); + + param.supportedLanguages = SCE_IME_LANGUAGE_ENGLISH_US; + param.languagesForced = SCE_FALSE; + param.type = SCE_IME_TYPE_DEFAULT; + param.option = SCE_IME_OPTION_NO_ASSISTANCE; + param.inputTextBuffer = libime_out; + param.maxTextLength = SCE_IME_MAX_TEXT_LENGTH; + param.handler = VITA_ImeEventHandler; + param.filter = NULL; + param.initialText = (SceWChar16 *)libime_initval; + param.arg = videodata; + param.work = libime_work; + + res = sceImeOpen(¶m); + if (res < 0) { + SDL_SetError("Failed to init IME"); + return; + } + +#else + SceWChar16 *title = u""; + SceWChar16 *text = u""; + + SceImeDialogParam param; + sceImeDialogParamInit(¶m); + + param.supportedLanguages = 0; + param.languagesForced = SCE_FALSE; + param.type = SCE_IME_TYPE_DEFAULT; + param.option = 0; + param.textBoxMode = SCE_IME_DIALOG_TEXTBOX_MODE_WITH_CLEAR; + param.maxTextLength = SCE_IME_DIALOG_MAX_TEXT_LENGTH; + + param.title = title; + param.initialText = text; + param.inputTextBuffer = videodata->ime_buffer; + + res = sceImeDialogInit(¶m); + if (res < 0) { + SDL_SetError("Failed to init IME dialog"); + return; + } + +#endif + + videodata->ime_active = SDL_TRUE; +} + +void VITA_HideScreenKeyboard(_THIS, SDL_Window *window) +{ +#if !defined(SDL_VIDEO_VITA_PVR) + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + + switch (dialogStatus) { + default: + case SCE_COMMON_DIALOG_STATUS_NONE: + case SCE_COMMON_DIALOG_STATUS_RUNNING: + break; + case SCE_COMMON_DIALOG_STATUS_FINISHED: + sceImeDialogTerm(); + break; + } + + videodata->ime_active = SDL_FALSE; +#endif +} + +SDL_bool VITA_IsScreenKeyboardShown(_THIS, SDL_Window *window) +{ +#if defined(SDL_VIDEO_VITA_PVR) + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + return videodata->ime_active; +#else + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + return (dialogStatus == SCE_COMMON_DIALOG_STATUS_RUNNING); +#endif +} + +void VITA_PumpEvents(_THIS) +{ +#if !defined(SDL_VIDEO_VITA_PVR) + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; +#endif + + if (_this->suspend_screensaver) { + // cancel all idle timers to prevent vita going to sleep + sceKernelPowerTick(SCE_KERNEL_POWER_TICK_DEFAULT); + } + + VITA_PollTouch(); + VITA_PollKeyboard(); + VITA_PollMouse(); + +#if !defined(SDL_VIDEO_VITA_PVR) + if (videodata->ime_active == SDL_TRUE) { + // update IME status. Terminate, if finished + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + if (dialogStatus == SCE_COMMON_DIALOG_STATUS_FINISHED) { + uint8_t utf8_buffer[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; + + SceImeDialogResult result; + SDL_memset(&result, 0, sizeof(SceImeDialogResult)); + sceImeDialogGetResult(&result); + + // Convert UTF16 to UTF8 + utf16_to_utf8(videodata->ime_buffer, utf8_buffer); + + // Send SDL event + SDL_SendKeyboardText((const char*)utf8_buffer); + + // Send enter key only on enter + if (result.button == SCE_IME_DIALOG_BUTTON_ENTER) + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RETURN); + + sceImeDialogTerm(); + + videodata->ime_active = SDL_FALSE; + } + + } +#endif +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitavideo.h b/Engine/lib/sdl/src/video/vita/SDL_vitavideo.h new file mode 100644 index 000000000..04488dde3 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitavideo.h @@ -0,0 +1,115 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_vitavideo_h +#define _SDL_vitavideo_h + +#include "../../SDL_internal.h" +#include "../SDL_sysvideo.h" +#include "../SDL_egl_c.h" + +#include +#include +#include +#include + +typedef struct SDL_VideoData +{ + SDL_bool egl_initialized; /* OpenGL device initialization status */ + uint32_t egl_refcount; /* OpenGL reference count */ + + SceWChar16 ime_buffer[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; + SDL_bool ime_active; +} SDL_VideoData; + + +typedef struct SDL_DisplayData +{ + +} SDL_DisplayData; + + +typedef struct SDL_WindowData +{ + SDL_bool uses_gles; + SceUID buffer_uid; + void* buffer; +#if defined(SDL_VIDEO_VITA_PVR) + EGLSurface egl_surface; + EGLContext egl_context; +#endif +} SDL_WindowData; + +extern SDL_Window * Vita_Window; + + +/****************************************************************************/ +/* SDL_VideoDevice functions declaration */ +/****************************************************************************/ + +/* Display and window functions */ +int VITA_VideoInit(_THIS); +void VITA_VideoQuit(_THIS); +void VITA_GetDisplayModes(_THIS, SDL_VideoDisplay * display); +int VITA_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +int VITA_CreateWindow(_THIS, SDL_Window * window); +int VITA_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); +void VITA_SetWindowTitle(_THIS, SDL_Window * window); +void VITA_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); +void VITA_SetWindowPosition(_THIS, SDL_Window * window); +void VITA_SetWindowSize(_THIS, SDL_Window * window); +void VITA_ShowWindow(_THIS, SDL_Window * window); +void VITA_HideWindow(_THIS, SDL_Window * window); +void VITA_RaiseWindow(_THIS, SDL_Window * window); +void VITA_MaximizeWindow(_THIS, SDL_Window * window); +void VITA_MinimizeWindow(_THIS, SDL_Window * window); +void VITA_RestoreWindow(_THIS, SDL_Window * window); +void VITA_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +void VITA_DestroyWindow(_THIS, SDL_Window * window); + +/* Window manager function */ +SDL_bool VITA_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info); + +#if SDL_VIDEO_DRIVER_VITA +/* OpenGL functions */ +int VITA_GL_LoadLibrary(_THIS, const char *path); +void *VITA_GL_GetProcAddress(_THIS, const char *proc); +void VITA_GL_UnloadLibrary(_THIS); +SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window); +int VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +int VITA_GL_SetSwapInterval(_THIS, int interval); +int VITA_GL_GetSwapInterval(_THIS); +int VITA_GL_SwapWindow(_THIS, SDL_Window * window); +void VITA_GL_DeleteContext(_THIS, SDL_GLContext context); +#endif + +/* VITA on screen keyboard */ +SDL_bool VITA_HasScreenKeyboardSupport(_THIS); +void VITA_ShowScreenKeyboard(_THIS, SDL_Window *window); +void VITA_HideScreenKeyboard(_THIS, SDL_Window *window); +SDL_bool VITA_IsScreenKeyboardShown(_THIS, SDL_Window *window); + +void VITA_PumpEvents(_THIS); + +#endif /* _SDL_pspvideo_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vivante/SDL_vivanteopengles.c b/Engine/lib/sdl/src/video/vivante/SDL_vivanteopengles.c index 308f7ee48..42888d6a8 100644 --- a/Engine/lib/sdl/src/video/vivante/SDL_vivanteopengles.c +++ b/Engine/lib/sdl/src/video/vivante/SDL_vivanteopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/vivante/SDL_vivanteopengles.h b/Engine/lib/sdl/src/video/vivante/SDL_vivanteopengles.h index 6241eae2f..dce74ae6b 100644 --- a/Engine/lib/sdl/src/video/vivante/SDL_vivanteopengles.h +++ b/Engine/lib/sdl/src/video/vivante/SDL_vivanteopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/vivante/SDL_vivanteplatform.c b/Engine/lib/sdl/src/video/vivante/SDL_vivanteplatform.c index f6f37cf51..36d6822b4 100644 --- a/Engine/lib/sdl/src/video/vivante/SDL_vivanteplatform.c +++ b/Engine/lib/sdl/src/video/vivante/SDL_vivanteplatform.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/vivante/SDL_vivanteplatform.h b/Engine/lib/sdl/src/video/vivante/SDL_vivanteplatform.h index 0f0e3f3c6..b1621d323 100644 --- a/Engine/lib/sdl/src/video/vivante/SDL_vivanteplatform.h +++ b/Engine/lib/sdl/src/video/vivante/SDL_vivanteplatform.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.c b/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.c index bc6bb62c5..de2fdbfd1 100644 --- a/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.c +++ b/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.h b/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.h index 8d59a1de3..ae4a8e142 100644 --- a/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.h +++ b/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/vivante/SDL_vivantevulkan.c b/Engine/lib/sdl/src/video/vivante/SDL_vivantevulkan.c index 7c86bc9d9..fe6a6b0ae 100644 --- a/Engine/lib/sdl/src/video/vivante/SDL_vivantevulkan.c +++ b/Engine/lib/sdl/src/video/vivante/SDL_vivantevulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/vivante/SDL_vivantevulkan.h b/Engine/lib/sdl/src/video/vivante/SDL_vivantevulkan.h index 764ae2ec5..0be68fae7 100644 --- a/Engine/lib/sdl/src/video/vivante/SDL_vivantevulkan.h +++ b/Engine/lib/sdl/src/video/vivante/SDL_vivantevulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandclipboard.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandclipboard.c index e51f1bae4..e6315540e 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandclipboard.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandclipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,32 +24,34 @@ #include "SDL_waylanddatamanager.h" #include "SDL_waylandevents_c.h" +#include "SDL_waylandclipboard.h" int Wayland_SetClipboardText(_THIS, const char *text) { SDL_VideoData *video_data = NULL; SDL_WaylandDataDevice *data_device = NULL; - + int status = 0; - + if (_this == NULL || _this->driverdata == NULL) { status = SDL_SetError("Video driver uninitialized"); } else { video_data = _this->driverdata; - /* TODO: Support more than one seat */ - data_device = Wayland_get_data_device(video_data->input); - if (text[0] != '\0') { - SDL_WaylandDataSource* source = Wayland_data_source_create(_this); - Wayland_data_source_add_data(source, TEXT_MIME, text, - strlen(text) + 1); + if (video_data->input != NULL && video_data->input->data_device != NULL) { + data_device = video_data->input->data_device; + if (text[0] != '\0') { + SDL_WaylandDataSource* source = Wayland_data_source_create(_this); + Wayland_data_source_add_data(source, TEXT_MIME, text, + SDL_strlen(text) + 1); - status = Wayland_data_device_set_selection(data_device, source); - if (status != 0) { - Wayland_data_source_destroy(source); + status = Wayland_data_device_set_selection(data_device, source); + if (status != 0) { + Wayland_data_source_destroy(source); + } + } else { + status = Wayland_data_device_clear_selection(data_device); } - } else { - status = Wayland_data_device_clear_selection(data_device); } } @@ -66,25 +68,27 @@ Wayland_GetClipboardText(_THIS) void *buffer = NULL; size_t length = 0; - + if (_this == NULL || _this->driverdata == NULL) { SDL_SetError("Video driver uninitialized"); } else { video_data = _this->driverdata; - /* TODO: Support more than one seat */ - data_device = Wayland_get_data_device(video_data->input); - if (data_device->selection_offer != NULL) { - buffer = Wayland_data_offer_receive(data_device->selection_offer, - &length, TEXT_MIME, SDL_TRUE); - if (length > 0) { - text = (char*) buffer; - } - } else if (data_device->selection_source != NULL) { - buffer = Wayland_data_source_get_data(data_device->selection_source, - &length, TEXT_MIME, SDL_TRUE); - if (length > 0) { - text = (char*) buffer; - } + if (video_data->input != NULL && video_data->input->data_device != NULL) { + data_device = video_data->input->data_device; + if (data_device->selection_offer != NULL) { + buffer = Wayland_data_offer_receive(data_device->selection_offer, + &length, TEXT_MIME, SDL_TRUE); + if (length > 0) { + text = (char*) buffer; + } + } + if (length == 0 && data_device->selection_source != NULL) { + buffer = Wayland_data_source_get_data(data_device->selection_source, + &length, TEXT_MIME, SDL_TRUE); + if (length > 0) { + text = (char*) buffer; + } + } } } @@ -101,18 +105,20 @@ Wayland_HasClipboardText(_THIS) SDL_VideoData *video_data = NULL; SDL_WaylandDataDevice *data_device = NULL; - SDL_bool result = SDL_FALSE; + SDL_bool result = SDL_FALSE; if (_this == NULL || _this->driverdata == NULL) { SDL_SetError("Video driver uninitialized"); } else { video_data = _this->driverdata; - data_device = Wayland_get_data_device(video_data->input); - if (data_device != NULL && Wayland_data_offer_has_mime( - data_device->selection_offer, TEXT_MIME)) { - result = SDL_TRUE; - } else if(data_device != NULL && Wayland_data_source_has_mime( - data_device->selection_source, TEXT_MIME)) { - result = SDL_TRUE; + if (video_data->input != NULL && video_data->input->data_device != NULL) { + data_device = video_data->input->data_device; + if (Wayland_data_offer_has_mime( + data_device->selection_offer, TEXT_MIME)) { + result = SDL_TRUE; + } else if (Wayland_data_source_has_mime( + data_device->selection_source, TEXT_MIME)) { + result = SDL_TRUE; + } } } return result; diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandclipboard.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandclipboard.h index d82af2324..b30e1605b 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandclipboard.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylanddatamanager.c b/Engine/lib/sdl/src/video/wayland/SDL_waylanddatamanager.c index af46e29bc..c8d3ec757 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylanddatamanager.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylanddatamanager.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,7 +34,10 @@ #include "SDL_waylandvideo.h" #include "SDL_waylanddatamanager.h" -#include "SDL_waylanddyn.h" +/* FIXME: This is arbitrary, but we want this to be less than a frame because + * any longer can potentially spin an infinite loop of PumpEvents (!) + */ +#define PIPE_MS_TIMEOUT 10 static ssize_t write_pipe(int fd, const void* buffer, size_t total_length, size_t *pos) @@ -47,7 +50,7 @@ write_pipe(int fd, const void* buffer, size_t total_length, size_t *pos) sigset_t old_sig_set; struct timespec zerotime = {0}; - ready = SDL_IOReady(fd, SDL_TRUE, 1 * 1000); + ready = SDL_IOReady(fd, SDL_IOR_WRITE, PIPE_MS_TIMEOUT); sigemptyset(&sig_set); sigaddset(&sig_set, SIGPIPE); @@ -93,7 +96,7 @@ read_pipe(int fd, void** buffer, size_t* total_length, SDL_bool null_terminate) ssize_t bytes_read = 0; size_t pos = 0; - ready = SDL_IOReady(fd, SDL_FALSE, 1 * 1000); + ready = SDL_IOReady(fd, SDL_IOR_READ, PIPE_MS_TIMEOUT); if (ready == 0) { bytes_read = SDL_SetError("Pipe timeout"); @@ -152,7 +155,7 @@ Wayland_convert_mime_type(const char *mime_type) size_t index = 0; for (index = 0; index < MIME_LIST_SIZE; ++index) { - if (strcmp(mime_conversion_list[index][0], mime_type) == 0) { + if (SDL_strcmp(mime_conversion_list[index][0], mime_type) == 0) { found = mime_conversion_list[index][1]; break; } @@ -169,7 +172,7 @@ mime_data_list_find(struct wl_list* list, SDL_MimeDataList *mime_list = NULL; wl_list_for_each(mime_list, list, link) { - if (strcmp(mime_list->mime_type, mime_type) == 0) { + if (SDL_strcmp(mime_list->mime_type, mime_type) == 0) { found = mime_list; break; } @@ -204,7 +207,7 @@ mime_data_list_add(struct wl_list* list, } else { WAYLAND_wl_list_insert(list, &(mime_data->link)); - mime_type_length = strlen(mime_type) + 1; + mime_type_length = SDL_strlen(mime_type) + 1; mime_data->mime_type = SDL_malloc(mime_type_length); if (mime_data->mime_type == NULL) { status = SDL_OutOfMemory(); @@ -393,8 +396,9 @@ Wayland_data_device_clear_selection(SDL_WaylandDataDevice *data_device) if (data_device == NULL || data_device->data_device == NULL) { status = SDL_SetError("Invalid Data Device"); - } else if (data_device->selection_source != 0) { + } else if (data_device->selection_source != NULL) { wl_data_device_set_selection(data_device->data_device, NULL, 0); + Wayland_data_source_destroy(data_device->selection_source); data_device->selection_source = NULL; } return status; @@ -421,7 +425,7 @@ Wayland_data_device_set_selection(SDL_WaylandDataDevice *data_device, /* TODO - Improve system for multiple mime types to same data */ for (index = 0; index < MIME_LIST_SIZE; ++index) { - if (strcmp(mime_conversion_list[index][1], mime_data->mime_type) == 0) { + if (SDL_strcmp(mime_conversion_list[index][1], mime_data->mime_type) == 0) { wl_data_source_offer(source->source, mime_conversion_list[index][0]); } @@ -441,6 +445,9 @@ Wayland_data_device_set_selection(SDL_WaylandDataDevice *data_device, source->source, data_device->selection_serial); } + if (data_device->selection_source != NULL) { + Wayland_data_source_destroy(data_device->selection_source); + } data_device->selection_source = source; } } diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylanddatamanager.h b/Engine/lib/sdl/src/video/wayland/SDL_waylanddatamanager.h index ce003df83..4e85dfa31 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylanddatamanager.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylanddatamanager.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.c b/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.c index 578fad49a..034df7a8c 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -47,12 +47,16 @@ typedef struct #ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON #define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON NULL #endif +#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR +#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR NULL +#endif static waylanddynlib waylandlibs[] = { {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC}, {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL}, {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR}, - {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON} + {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON}, + {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR} }; static void * diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h b/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h index 485a9c19f..c867ec001 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,13 +18,12 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #ifndef SDL_waylanddyn_h_ #define SDL_waylanddyn_h_ #include "../../SDL_internal.h" -/* We can't include wayland-client.h here +/* We can't include wayland-client.h here * but we need some structs from it */ struct wl_interface; @@ -34,10 +33,24 @@ struct wl_display; struct wl_surface; struct wl_shm; +/* We also need some for libdecor */ +struct wl_seat; +struct wl_output; +struct libdecor; +struct libdecor_frame; +struct libdecor_state; +struct libdecor_configuration; +struct libdecor_interface; +struct libdecor_frame_interface; +enum libdecor_resize_edge; +enum libdecor_capabilities; +enum libdecor_window_state; + #include #include "wayland-cursor.h" #include "wayland-util.h" #include "xkbcommon/xkbcommon.h" +#include "xkbcommon/xkbcommon-compose.h" #ifdef __cplusplus extern "C" @@ -54,7 +67,6 @@ void SDL_WAYLAND_UnloadSymbols(void); #define SDL_WAYLAND_INTERFACE(iface) extern const struct wl_interface *WAYLAND_##iface; #include "SDL_waylandsym.h" - #ifdef __cplusplus } #endif @@ -64,7 +76,7 @@ void SDL_WAYLAND_UnloadSymbols(void); #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC -#ifdef _WAYLAND_CLIENT_H +#if defined(_WAYLAND_CLIENT_H) || defined(WAYLAND_CLIENT_H) #error Do not include wayland-client ahead of SDL_waylanddyn.h in dynamic loading mode #endif @@ -81,25 +93,69 @@ void SDL_WAYLAND_UnloadSymbols(void); #define wl_proxy_add_listener (*WAYLAND_wl_proxy_add_listener) #define wl_proxy_marshal_constructor (*WAYLAND_wl_proxy_marshal_constructor) #define wl_proxy_marshal_constructor_versioned (*WAYLAND_wl_proxy_marshal_constructor_versioned) +#define wl_proxy_set_tag (*WAYLAND_wl_proxy_set_tag) +#define wl_proxy_get_tag (*WAYLAND_wl_proxy_get_tag) +#define wl_proxy_marshal_flags (*WAYLAND_wl_proxy_marshal_flags) +#define wl_proxy_marshal_array_flags (*WAYLAND_wl_proxy_marshal_array_flags) #define wl_seat_interface (*WAYLAND_wl_seat_interface) #define wl_surface_interface (*WAYLAND_wl_surface_interface) #define wl_shm_pool_interface (*WAYLAND_wl_shm_pool_interface) #define wl_buffer_interface (*WAYLAND_wl_buffer_interface) #define wl_registry_interface (*WAYLAND_wl_registry_interface) -#define wl_shell_surface_interface (*WAYLAND_wl_shell_surface_interface) #define wl_region_interface (*WAYLAND_wl_region_interface) #define wl_pointer_interface (*WAYLAND_wl_pointer_interface) #define wl_keyboard_interface (*WAYLAND_wl_keyboard_interface) #define wl_compositor_interface (*WAYLAND_wl_compositor_interface) #define wl_output_interface (*WAYLAND_wl_output_interface) -#define wl_shell_interface (*WAYLAND_wl_shell_interface) #define wl_shm_interface (*WAYLAND_wl_shm_interface) #define wl_data_device_interface (*WAYLAND_wl_data_device_interface) #define wl_data_offer_interface (*WAYLAND_wl_data_offer_interface) #define wl_data_source_interface (*WAYLAND_wl_data_source_interface) #define wl_data_device_manager_interface (*WAYLAND_wl_data_device_manager_interface) +#ifdef HAVE_LIBDECOR_H +/* Must be included before our defines */ +#include + +#define libdecor_unref (*WAYLAND_libdecor_unref) +#define libdecor_new (*WAYLAND_libdecor_new) +#define libdecor_decorate (*WAYLAND_libdecor_decorate) +#define libdecor_frame_unref (*WAYLAND_libdecor_frame_unref) +#define libdecor_frame_set_title (*WAYLAND_libdecor_frame_set_title) +#define libdecor_frame_set_app_id (*WAYLAND_libdecor_frame_set_app_id) +#define libdecor_frame_set_max_content_size (*WAYLAND_libdecor_frame_set_max_content_size) +#define libdecor_frame_set_min_content_size (*WAYLAND_libdecor_frame_set_min_content_size) +#define libdecor_frame_resize (*WAYLAND_libdecor_frame_resize) +#define libdecor_frame_move (*WAYLAND_libdecor_frame_move) +#define libdecor_frame_commit (*WAYLAND_libdecor_frame_commit) +#define libdecor_frame_set_minimized (*WAYLAND_libdecor_frame_set_minimized) +#define libdecor_frame_set_maximized (*WAYLAND_libdecor_frame_set_maximized) +#define libdecor_frame_unset_maximized (*WAYLAND_libdecor_frame_unset_maximized) +#define libdecor_frame_set_fullscreen (*WAYLAND_libdecor_frame_set_fullscreen) +#define libdecor_frame_unset_fullscreen (*WAYLAND_libdecor_frame_unset_fullscreen) +#define libdecor_frame_set_capabilities (*WAYLAND_libdecor_frame_set_capabilities) +#define libdecor_frame_unset_capabilities (*WAYLAND_libdecor_frame_unset_capabilities) +#define libdecor_frame_has_capability (*WAYLAND_libdecor_frame_has_capability) +#define libdecor_frame_set_visibility (*WAYLAND_libdecor_frame_set_visibility) +#define libdecor_frame_is_visible (*WAYLAND_libdecor_frame_is_visible) +#define libdecor_frame_is_floating (*WAYLAND_libdecor_frame_is_floating) +#define libdecor_frame_set_parent (*WAYLAND_libdecor_frame_set_parent) +#define libdecor_frame_get_xdg_surface (*WAYLAND_libdecor_frame_get_xdg_surface) +#define libdecor_frame_get_xdg_toplevel (*WAYLAND_libdecor_frame_get_xdg_toplevel) +#define libdecor_frame_map (*WAYLAND_libdecor_frame_map) +#define libdecor_state_new (*WAYLAND_libdecor_state_new) +#define libdecor_state_free (*WAYLAND_libdecor_state_free) +#define libdecor_configuration_get_content_size (*WAYLAND_libdecor_configuration_get_content_size) +#define libdecor_configuration_get_window_state (*WAYLAND_libdecor_configuration_get_window_state) +#endif + +#else /* SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */ + +#ifdef HAVE_LIBDECOR_H +#include +#endif + #endif /* SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */ #include "wayland-client-protocol.h" diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c index 0d57cbfa4..55893201b 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,12 +35,15 @@ #include "SDL_waylandevents_c.h" #include "SDL_waylandwindow.h" -#include "SDL_waylanddyn.h" - #include "pointer-constraints-unstable-v1-client-protocol.h" #include "relative-pointer-unstable-v1-client-protocol.h" #include "xdg-shell-client-protocol.h" -#include "xdg-shell-unstable-v6-client-protocol.h" +#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h" +#include "text-input-unstable-v3-client-protocol.h" + +#ifdef HAVE_LIBDECOR_H +#include +#endif #ifdef SDL_INPUT_LINUXEV #include @@ -55,55 +58,31 @@ #include #include #include +#include #include +#include +#include "../../events/imKStoUCS.h" -typedef struct { - // repeat_rate in range of [1, 1000] - int32_t repeat_rate; - int32_t repeat_delay; - SDL_bool is_initialized; +/* Weston uses a ratio of 10 units per scroll tick */ +#define WAYLAND_WHEEL_AXIS_UNIT 10 - SDL_bool is_key_down; - uint32_t next_repeat_ms; - uint32_t scancode; - char text[8]; -} SDL_WaylandKeyboardRepeat; - -struct SDL_WaylandInput { - SDL_VideoData *display; - struct wl_seat *seat; - struct wl_pointer *pointer; - struct wl_touch *touch; - struct wl_keyboard *keyboard; - SDL_WaylandDataDevice *data_device; - struct zwp_relative_pointer_v1 *relative_pointer; - struct zwp_confined_pointer_v1 *confined_pointer; - SDL_Window *confined_pointer_window; - SDL_WindowData *pointer_focus; - SDL_WindowData *keyboard_focus; - - /* Last motion location */ - wl_fixed_t sx_w; - wl_fixed_t sy_w; - - double dx_frac; - double dy_frac; - - struct { - struct xkb_keymap *keymap; - struct xkb_state *state; - } xkb; - - /* information about axis events on current frame */ - struct { - SDL_bool is_x_discrete; - float x; - - SDL_bool is_y_discrete; - float y; - } pointer_curr_axis_info; - - SDL_WaylandKeyboardRepeat keyboard_repeat; +static const struct { + xkb_keysym_t keysym; + SDL_KeyCode keycode; +} KeySymToSDLKeyCode[] = { + { XKB_KEY_Shift_L, SDLK_LSHIFT }, + { XKB_KEY_Shift_R, SDLK_RSHIFT }, + { XKB_KEY_Control_L, SDLK_LCTRL }, + { XKB_KEY_Control_R, SDLK_RCTRL }, + { XKB_KEY_Caps_Lock, SDLK_CAPSLOCK }, + { XKB_KEY_Alt_L, SDLK_LALT }, + { XKB_KEY_Alt_R, SDLK_RALT }, + { XKB_KEY_Meta_L, SDLK_LGUI }, + { XKB_KEY_Meta_R, SDLK_RGUI }, + { XKB_KEY_Super_L, SDLK_LGUI }, + { XKB_KEY_Super_R, SDLK_RGUI }, + { XKB_KEY_Hyper_L, SDLK_LGUI }, + { XKB_KEY_Hyper_R, SDLK_RGUI }, }; struct SDL_WaylandTouchPoint { @@ -123,6 +102,19 @@ struct SDL_WaylandTouchPointList { static struct SDL_WaylandTouchPointList touch_points = {NULL, NULL}; +static SDL_KeyCode +Wayland_KeySymToSDLKeyCode(xkb_keysym_t keysym) +{ + int i; + + for (i = 0; i < SDL_arraysize(KeySymToSDLKeyCode); ++i) { + if (keysym == KeySymToSDLKeyCode[i].keysym) { + return KeySymToSDLKeyCode[i].keycode; + } + } + return SDLK_UNKNOWN; +} + static void touch_add(SDL_TouchID id, float x, float y, struct wl_surface *surface) { @@ -210,14 +202,12 @@ touch_surface(SDL_TouchID id) return NULL; } -/* Returns the time till next repeat, or 0 if no key is down. */ -static void -keyboard_repeat_handle(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t now) +/* Returns SDL_TRUE if a key repeat event was due */ +static SDL_bool +keyboard_repeat_handle(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t elapsed) { - if (!repeat_info->is_key_down || !repeat_info->is_initialized) { - return; - } - while (repeat_info->next_repeat_ms <= now) { + SDL_bool ret = SDL_FALSE; + while ((elapsed - repeat_info->next_repeat_ms) < 0x80000000U) { if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) { SDL_SendKeyboardKey(SDL_PRESSED, repeat_info->scancode); } @@ -225,7 +215,9 @@ keyboard_repeat_handle(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t now) SDL_SendKeyboardText(repeat_info->text); } repeat_info->next_repeat_ms += 1000 / repeat_info->repeat_rate; + ret = SDL_TRUE; } + return ret; } static void @@ -237,21 +229,111 @@ keyboard_repeat_clear(SDL_WaylandKeyboardRepeat* repeat_info) { } static void -keyboard_repeat_set(SDL_WaylandKeyboardRepeat* repeat_info, +keyboard_repeat_set(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t wl_press_time, uint32_t scancode, SDL_bool has_text, char text[8]) { - if (!repeat_info->is_initialized) { + if (!repeat_info->is_initialized || !repeat_info->repeat_rate) { return; } repeat_info->is_key_down = SDL_TRUE; - repeat_info->next_repeat_ms = SDL_GetTicks() + repeat_info->repeat_delay; + repeat_info->wl_press_time = wl_press_time; + repeat_info->sdl_press_time = SDL_GetTicks(); + repeat_info->next_repeat_ms = repeat_info->repeat_delay; repeat_info->scancode = scancode; if (has_text) { - memcpy(repeat_info->text, text, 8); + SDL_memcpy(repeat_info->text, text, 8); } else { repeat_info->text[0] = '\0'; } } +static SDL_bool keyboard_repeat_is_set(SDL_WaylandKeyboardRepeat* repeat_info) { + return repeat_info->is_initialized && repeat_info->is_key_down; +} + +void +Wayland_SendWakeupEvent(_THIS, SDL_Window *window) +{ + SDL_VideoData *d = _this->driverdata; + + /* TODO: Maybe use a pipe to avoid the compositor roundtrip? */ + wl_display_sync(d->display); + WAYLAND_wl_display_flush(d->display); +} + +int +Wayland_WaitEventTimeout(_THIS, int timeout) +{ + SDL_VideoData *d = _this->driverdata; + struct SDL_WaylandInput *input = d->input; + SDL_bool key_repeat_active = SDL_FALSE; + + WAYLAND_wl_display_flush(d->display); + +#ifdef SDL_USE_IME + if (d->text_input_manager == NULL && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) { + SDL_IME_PumpEvents(); + } +#endif + + /* If key repeat is active, we'll need to cap our maximum wait time to handle repeats */ + if (input && keyboard_repeat_is_set(&input->keyboard_repeat)) { + uint32_t elapsed = SDL_GetTicks() - input->keyboard_repeat.sdl_press_time; + if (keyboard_repeat_handle(&input->keyboard_repeat, elapsed)) { + /* A repeat key event was already due */ + return 1; + } else { + uint32_t next_repeat_wait_time = (input->keyboard_repeat.next_repeat_ms - elapsed) + 1; + if (timeout >= 0) { + timeout = SDL_min(timeout, next_repeat_wait_time); + } else { + timeout = next_repeat_wait_time; + } + key_repeat_active = SDL_TRUE; + } + } + + /* wl_display_prepare_read() will return -1 if the default queue is not empty. + * If the default queue is empty, it will prepare us for our SDL_IOReady() call. */ + if (WAYLAND_wl_display_prepare_read(d->display) == 0) { + /* Use SDL_IOR_NO_RETRY to ensure SIGINT will break us out of our wait */ + int err = SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_IOR_READ | SDL_IOR_NO_RETRY, timeout); + if (err > 0) { + /* There are new events available to read */ + WAYLAND_wl_display_read_events(d->display); + WAYLAND_wl_display_dispatch_pending(d->display); + return 1; + } else if (err == 0) { + /* No events available within the timeout */ + WAYLAND_wl_display_cancel_read(d->display); + + /* If key repeat is active, we might have woken up to generate a key event */ + if (key_repeat_active) { + uint32_t elapsed = SDL_GetTicks() - input->keyboard_repeat.sdl_press_time; + if (keyboard_repeat_handle(&input->keyboard_repeat, elapsed)) { + return 1; + } + } + + return 0; + } else { + /* Error returned from poll()/select() */ + WAYLAND_wl_display_cancel_read(d->display); + + if (errno == EINTR) { + /* If the wait was interrupted by a signal, we may have generated a + * SDL_QUIT event. Let the caller know to call SDL_PumpEvents(). */ + return 1; + } else { + return err; + } + } + } else { + /* We already had pending events */ + WAYLAND_wl_display_dispatch_pending(d->display); + return 1; + } +} + void Wayland_PumpEvents(_THIS) { @@ -261,16 +343,30 @@ Wayland_PumpEvents(_THIS) WAYLAND_wl_display_flush(d->display); - if (input) { - uint32_t now = SDL_GetTicks(); - keyboard_repeat_handle(&input->keyboard_repeat, now); +#ifdef SDL_USE_IME + if (d->text_input_manager == NULL && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) { + SDL_IME_PumpEvents(); + } +#endif + + /* wl_display_prepare_read() will return -1 if the default queue is not empty. + * If the default queue is empty, it will prepare us for our SDL_IOReady() call. */ + if (WAYLAND_wl_display_prepare_read(d->display) == 0) { + if (SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_IOR_READ, 0) > 0) { + WAYLAND_wl_display_read_events(d->display); + } else { + WAYLAND_wl_display_cancel_read(d->display); + } } - if (SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_FALSE, 0)) { - err = WAYLAND_wl_display_dispatch(d->display); - } else { - err = WAYLAND_wl_display_dispatch_pending(d->display); + /* Dispatch any pre-existing pending events or new events we may have read */ + err = WAYLAND_wl_display_dispatch_pending(d->display); + + if (input && keyboard_repeat_is_set(&input->keyboard_repeat)) { + uint32_t elapsed = SDL_GetTicks() - input->keyboard_repeat.sdl_press_time; + keyboard_repeat_handle(&input->keyboard_repeat, elapsed); } + if (err == -1 && !d->display_disconnected) { /* Something has failed with the Wayland connection -- for example, * the compositor may have shut down and closed its end of the socket, @@ -310,6 +406,11 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, return; } + /* check that this surface belongs to one of the SDL windows */ + if (!SDL_WAYLAND_own_surface(surface)) { + return; + } + /* This handler will be called twice in Wayland 1.4 * Once for the window surface which has valid user data * and again for the mouse cursor surface which does not have valid user data @@ -320,11 +421,16 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, if (window) { input->pointer_focus = window; + input->pointer_enter_serial = serial; SDL_SetMouseFocus(window->sdlwindow); /* In the case of e.g. a pointer confine warp, we may receive an enter * event with no following motion event, but with the new coordinates * as part of the enter event. */ pointer_handle_motion(data, pointer, serial, sx_w, sy_w); + /* If the cursor was changed while our window didn't have pointer + * focus, we might need to trigger another call to + * wl_pointer_set_cursor() for the new cursor to be displayed. */ + SDL_SetCursor(NULL); } } @@ -334,6 +440,10 @@ pointer_handle_leave(void *data, struct wl_pointer *pointer, { struct SDL_WaylandInput *input = data; + if (!surface || !SDL_WAYLAND_own_surface(surface)) { + return; + } + if (input->pointer_focus) { SDL_SetMouseFocus(NULL); input->pointer_focus = NULL; @@ -350,25 +460,33 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial) const SDL_Point point = { wl_fixed_to_int(input->sx_w), wl_fixed_to_int(input->sy_w) }; const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data); - static const uint32_t directions_wl[] = { - WL_SHELL_SURFACE_RESIZE_TOP_LEFT, WL_SHELL_SURFACE_RESIZE_TOP, - WL_SHELL_SURFACE_RESIZE_TOP_RIGHT, WL_SHELL_SURFACE_RESIZE_RIGHT, - WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, WL_SHELL_SURFACE_RESIZE_BOTTOM, - WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT, WL_SHELL_SURFACE_RESIZE_LEFT + static const uint32_t directions[] = { + XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_TOP, + XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT, XDG_TOPLEVEL_RESIZE_EDGE_RIGHT, + XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM, + XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_LEFT }; - /* the names are different (ZXDG_TOPLEVEL_V6_RESIZE_EDGE_* vs - WL_SHELL_SURFACE_RESIZE_*), but the values are the same. */ - const uint32_t *directions_zxdg = directions_wl; +#ifdef HAVE_LIBDECOR_H + /* ditto for libdecor. */ + const uint32_t *directions_libdecor = directions; +#endif switch (rc) { case SDL_HITTEST_DRAGGABLE: +#ifdef HAVE_LIBDECOR_H + if (input->display->shell.libdecor) { + if (window_data->shell_surface.libdecor.frame) { + libdecor_frame_move(window_data->shell_surface.libdecor.frame, input->seat, serial); + } + } else +#endif if (input->display->shell.xdg) { - xdg_toplevel_move(window_data->shell_surface.xdg.roleobj.toplevel, input->seat, serial); - } else if (input->display->shell.zxdg) { - zxdg_toplevel_v6_move(window_data->shell_surface.zxdg.roleobj.toplevel, input->seat, serial); - } else { - wl_shell_surface_move(window_data->shell_surface.wl, input->seat, serial); + if (window_data->shell_surface.xdg.roleobj.toplevel) { + xdg_toplevel_move(window_data->shell_surface.xdg.roleobj.toplevel, + input->seat, + serial); + } } return SDL_TRUE; @@ -380,12 +498,20 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial) case SDL_HITTEST_RESIZE_BOTTOM: case SDL_HITTEST_RESIZE_BOTTOMLEFT: case SDL_HITTEST_RESIZE_LEFT: +#ifdef HAVE_LIBDECOR_H + if (input->display->shell.libdecor) { + if (window_data->shell_surface.libdecor.frame) { + libdecor_frame_resize(window_data->shell_surface.libdecor.frame, input->seat, serial, directions_libdecor[rc - SDL_HITTEST_RESIZE_TOPLEFT]); + } + } else +#endif if (input->display->shell.xdg) { - xdg_toplevel_resize(window_data->shell_surface.xdg.roleobj.toplevel, input->seat, serial, directions_zxdg[rc - SDL_HITTEST_RESIZE_TOPLEFT]); - } else if (input->display->shell.zxdg) { - zxdg_toplevel_v6_resize(window_data->shell_surface.zxdg.roleobj.toplevel, input->seat, serial, directions_zxdg[rc - SDL_HITTEST_RESIZE_TOPLEFT]); - } else { - wl_shell_surface_resize(window_data->shell_surface.wl, input->seat, serial, directions_wl[rc - SDL_HITTEST_RESIZE_TOPLEFT]); + if (window_data->shell_surface.xdg.roleobj.toplevel) { + xdg_toplevel_resize(window_data->shell_surface.xdg.roleobj.toplevel, + input->seat, + serial, + directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]); + } } return SDL_TRUE; @@ -459,13 +585,16 @@ pointer_handle_axis_common_v1(struct SDL_WaylandInput *input, y = 0 - (float)wl_fixed_to_double(value); break; case WL_POINTER_AXIS_HORIZONTAL_SCROLL: - x = 0 - (float)wl_fixed_to_double(value); + x = (float)wl_fixed_to_double(value); y = 0; break; default: return; } + x /= WAYLAND_WHEEL_AXIS_UNIT; + y /= WAYLAND_WHEEL_AXIS_UNIT; + SDL_SendMouseWheel(window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL); } } @@ -500,7 +629,7 @@ pointer_handle_axis_common(struct SDL_WaylandInput *input, SDL_bool discrete, * processed a discrete axis event before so we ignore it */ break; } - input->pointer_curr_axis_info.x = 0 - (float)wl_fixed_to_double(value); + input->pointer_curr_axis_info.x = (float)wl_fixed_to_double(value); break; } } @@ -523,10 +652,20 @@ pointer_handle_frame(void *data, struct wl_pointer *pointer) { struct SDL_WaylandInput *input = data; SDL_WindowData *window = input->pointer_focus; - float x = input->pointer_curr_axis_info.x, y = input->pointer_curr_axis_info.y; + float x, y; + + if (input->pointer_curr_axis_info.is_x_discrete) + x = input->pointer_curr_axis_info.x; + else + x = input->pointer_curr_axis_info.x / WAYLAND_WHEEL_AXIS_UNIT; + + if (input->pointer_curr_axis_info.is_y_discrete) + y = input->pointer_curr_axis_info.y; + else + y = input->pointer_curr_axis_info.y / WAYLAND_WHEEL_AXIS_UNIT; /* clear pointer_curr_axis_info for next frame */ - memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info); + SDL_memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info); if(x == 0.0f && y == 0.0f) return; @@ -583,7 +722,7 @@ touch_handler_down(void *data, struct wl_touch *touch, unsigned int serial, touch_add(id, x, y, surface); - SDL_SendTouch(1, (SDL_FingerID)id, window_data->sdlwindow, SDL_TRUE, x, y, 1.0f); + SDL_SendTouch((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, window_data->sdlwindow, SDL_TRUE, x, y, 1.0f); } static void @@ -601,7 +740,7 @@ touch_handler_up(void *data, struct wl_touch *touch, unsigned int serial, window = window_data->sdlwindow; } - SDL_SendTouch(1, (SDL_FingerID)id, window, SDL_FALSE, x, y, 0.0f); + SDL_SendTouch((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, window, SDL_FALSE, x, y, 0.0f); } static void @@ -615,7 +754,7 @@ touch_handler_motion(void *data, struct wl_touch *touch, unsigned int timestamp, const float y = dbly / window_data->sdlwindow->h; touch_update(id, x, y); - SDL_SendTouchMotion(1, (SDL_FingerID)id, window_data->sdlwindow, x, y, 1.0f); + SDL_SendTouchMotion((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, window_data->sdlwindow, x, y, 1.0f); } static void @@ -646,6 +785,7 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, { struct SDL_WaylandInput *input = data; char *map_str; + const char *locale; if (!data) { close(fd); @@ -682,6 +822,30 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, input->xkb.keymap = NULL; return; } + + /* + * See https://blogs.s-osg.org/compose-key-support-weston/ + * for further explanation on dead keys in Wayland. + */ + + /* Look up the preferred locale, falling back to "C" as default */ + if (!(locale = SDL_getenv("LC_ALL"))) + if (!(locale = SDL_getenv("LC_CTYPE"))) + if (!(locale = SDL_getenv("LANG"))) + locale = "C"; + /* Set up XKB compose table */ + input->xkb.compose_table = WAYLAND_xkb_compose_table_new_from_locale(input->display->xkb_context, + locale, XKB_COMPOSE_COMPILE_NO_FLAGS); + if (input->xkb.compose_table) { + /* Set up XKB compose state */ + input->xkb.compose_state = WAYLAND_xkb_compose_state_new(input->xkb.compose_table, + XKB_COMPOSE_STATE_NO_FLAGS); + if (!input->xkb.compose_state) { + fprintf(stderr, "could not create XKB compose state\n"); + WAYLAND_xkb_compose_table_unref(input->xkb.compose_table); + input->xkb.compose_table = NULL; + } + } } static void @@ -697,6 +861,10 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, return; } + if (!SDL_WAYLAND_own_surface(surface)) { + return; + } + window = wl_surface_get_user_data(surface); if (window) { @@ -704,20 +872,42 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, window->keyboard_device = input; SDL_SetKeyboardFocus(window->sdlwindow); } +#ifdef SDL_USE_IME + if (!input->text_input) { + SDL_IME_SetFocus(SDL_TRUE); + } +#endif } static void keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) { + struct SDL_WaylandInput *input = data; + + if (!surface || !SDL_WAYLAND_own_surface(surface)) { + return; + } + + /* Stop key repeat before clearing keyboard focus */ + keyboard_repeat_clear(&input->keyboard_repeat); + + /* This will release any keys still pressed */ SDL_SetKeyboardFocus(NULL); + +#ifdef SDL_USE_IME + if (!input->text_input) { + SDL_IME_SetFocus(SDL_FALSE); + } +#endif } static SDL_bool -keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint32_t key) +keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint32_t key, SDL_bool *handled_by_ime) { SDL_WindowData *window = input->keyboard_focus; const xkb_keysym_t *syms; + xkb_keysym_t sym; if (!window || window->keyboard_device != input || !input->xkb.state) { return SDL_FALSE; @@ -727,8 +917,33 @@ keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint if (WAYLAND_xkb_state_key_get_syms(input->xkb.state, key + 8, &syms) != 1) { return SDL_FALSE; } + sym = syms[0]; - return WAYLAND_xkb_keysym_to_utf8(syms[0], text, 8) > 0; +#ifdef SDL_USE_IME + if (SDL_IME_ProcessKeyEvent(sym, key + 8)) { + *handled_by_ime = SDL_TRUE; + return SDL_TRUE; + } +#endif + + if (input->xkb.compose_state && WAYLAND_xkb_compose_state_feed(input->xkb.compose_state, sym) == XKB_COMPOSE_FEED_ACCEPTED) { + switch(WAYLAND_xkb_compose_state_get_status(input->xkb.compose_state)) { + case XKB_COMPOSE_COMPOSING: + *handled_by_ime = SDL_TRUE; + return SDL_TRUE; + case XKB_COMPOSE_CANCELLED: + default: + sym = XKB_KEY_NoSymbol; + break; + case XKB_COMPOSE_NOTHING: + break; + case XKB_COMPOSE_COMPOSED: + sym = WAYLAND_xkb_compose_state_get_one_sym(input->xkb.compose_state); + break; + } + } + + return WAYLAND_xkb_keysym_to_utf8(sym, text, 8) > 0; } static void @@ -740,8 +955,23 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, enum wl_keyboard_key_state state = state_w; uint32_t scancode = SDL_SCANCODE_UNKNOWN; char text[8]; + SDL_bool has_text = SDL_FALSE; + SDL_bool handled_by_ime = SDL_FALSE; - if (key < SDL_arraysize(xfree86_scancode_table2)) { + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { + has_text = keyboard_input_get_text(text, input, key, &handled_by_ime); + } else { + if (keyboard_repeat_is_set(&input->keyboard_repeat)) { + // Send any due key repeat events before stopping the repeat and generating the key up event + // Compute time based on the Wayland time, as it reports when the release event happened + // Using SDL_GetTicks would be wrong, as it would report when the release event is processed, + // which may be off if the application hasn't pumped events for a while + keyboard_repeat_handle(&input->keyboard_repeat, time - input->keyboard_repeat.wl_press_time); + keyboard_repeat_clear(&input->keyboard_repeat); + } + } + + if (!handled_by_ime && key < SDL_arraysize(xfree86_scancode_table2)) { scancode = xfree86_scancode_table2[key]; if (scancode != SDL_SCANCODE_UNKNOWN) { @@ -751,14 +981,68 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, } if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { - SDL_bool has_text = keyboard_input_get_text(text, input, key); - if (has_text) { + if (has_text && !(SDL_GetModState() & KMOD_CTRL)) { Wayland_data_device_set_serial(input->data_device, serial); - SDL_SendKeyboardText(text); + if (!handled_by_ime) { + SDL_SendKeyboardText(text); + } + } + if (input->xkb.keymap && WAYLAND_xkb_keymap_key_repeats(input->xkb.keymap, key + 8)) { + keyboard_repeat_set(&input->keyboard_repeat, time, scancode, has_text, text); + } + } +} + +typedef struct Wayland_Keymap +{ + xkb_layout_index_t layout; + SDL_Keycode keymap[SDL_NUM_SCANCODES]; +} Wayland_Keymap; + +static void +Wayland_keymap_iter(struct xkb_keymap *keymap, xkb_keycode_t key, void *data) +{ + const xkb_keysym_t *syms; + Wayland_Keymap *sdlKeymap = (Wayland_Keymap *)data; + + if ((key - 8) < SDL_arraysize(xfree86_scancode_table2)) { + SDL_Scancode scancode = xfree86_scancode_table2[key - 8]; + if (scancode == SDL_SCANCODE_UNKNOWN) { + return; + } + + if (WAYLAND_xkb_keymap_key_get_syms_by_level(keymap, key, sdlKeymap->layout, 0, &syms) > 0) { + uint32_t keycode = SDL_KeySymToUcs4(syms[0]); + + if (!keycode) { + keycode = Wayland_KeySymToSDLKeyCode(syms[0]); + } + + if (keycode) { + sdlKeymap->keymap[scancode] = keycode; + } else { + switch (scancode) { + case SDL_SCANCODE_RETURN: + sdlKeymap->keymap[scancode] = SDLK_RETURN; + break; + case SDL_SCANCODE_ESCAPE: + sdlKeymap->keymap[scancode] = SDLK_ESCAPE; + break; + case SDL_SCANCODE_BACKSPACE: + sdlKeymap->keymap[scancode] = SDLK_BACKSPACE; + break; + case SDL_SCANCODE_TAB: + sdlKeymap->keymap[scancode] = SDLK_TAB; + break; + case SDL_SCANCODE_DELETE: + sdlKeymap->keymap[scancode] = SDLK_DELETE; + break; + default: + sdlKeymap->keymap[scancode] = SDL_SCANCODE_TO_KEYCODE(scancode); + break; + } + } } - keyboard_repeat_set(&input->keyboard_repeat, scancode, has_text, text); - } else { - keyboard_repeat_clear(&input->keyboard_repeat); } } @@ -769,9 +1053,18 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t group) { struct SDL_WaylandInput *input = data; + Wayland_Keymap keymap; WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched, mods_locked, 0, 0, group); + + keymap.layout = group; + SDL_GetDefaultKeymap(keymap.keymap); + WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap, + Wayland_keymap_iter, + &keymap); + SDL_SetKeymap(0, keymap.keymap, SDL_NUM_SCANCODES); + SDL_SendKeymapChangedEvent(); } static void @@ -779,7 +1072,7 @@ keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay) { struct SDL_WaylandInput *input = data; - input->keyboard_repeat.repeat_rate = SDL_max(0, SDL_min(rate, 1000)); + input->keyboard_repeat.repeat_rate = SDL_clamp(rate, 0, 1000); input->keyboard_repeat.repeat_delay = delay; input->keyboard_repeat.is_initialized = SDL_TRUE; } @@ -801,7 +1094,7 @@ seat_handle_capabilities(void *data, struct wl_seat *seat, if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) { input->pointer = wl_seat_get_pointer(seat); - memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info); + SDL_memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info); input->display->pointer = input->pointer; wl_pointer_set_user_data(input->pointer, input); wl_pointer_add_listener(input->pointer, &pointer_listener, @@ -813,13 +1106,13 @@ seat_handle_capabilities(void *data, struct wl_seat *seat, } if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) { - SDL_AddTouch(1, SDL_TOUCH_DEVICE_DIRECT, "wayland_touch"); input->touch = wl_seat_get_touch(seat); + SDL_AddTouch((SDL_TouchID)(intptr_t)input->touch, SDL_TOUCH_DEVICE_DIRECT, "wayland_touch"); wl_touch_set_user_data(input->touch, input); wl_touch_add_listener(input->touch, &touch_listener, input); } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) { - SDL_DelTouch(1); + SDL_DelTouch((SDL_TouchID)(intptr_t)input->touch); wl_touch_destroy(input->touch); input->touch = NULL; } @@ -1021,36 +1314,145 @@ data_device_handle_motion(void *data, struct wl_data_device *wl_data_device, { } +/* Decodes URI escape sequences in string buf of len bytes + (excluding the terminating NULL byte) in-place. Since + URI-encoded characters take three times the space of + normal characters, this should not be an issue. + + Returns the number of decoded bytes that wound up in + the buffer, excluding the terminating NULL byte. + + The buffer is guaranteed to be NULL-terminated but + may contain embedded NULL bytes. + + On error, -1 is returned. + + FIXME: This was shamelessly copied from SDL_x11events.c + */ +static int Wayland_URIDecode(char *buf, int len) { + int ri, wi, di; + char decode = '\0'; + if (buf == NULL || len < 0) { + errno = EINVAL; + return -1; + } + if (len == 0) { + len = SDL_strlen(buf); + } + for (ri = 0, wi = 0, di = 0; ri < len && wi < len; ri += 1) { + if (di == 0) { + /* start decoding */ + if (buf[ri] == '%') { + decode = '\0'; + di += 1; + continue; + } + /* normal write */ + buf[wi] = buf[ri]; + wi += 1; + continue; + } else if (di == 1 || di == 2) { + char off = '\0'; + char isa = buf[ri] >= 'a' && buf[ri] <= 'f'; + char isA = buf[ri] >= 'A' && buf[ri] <= 'F'; + char isn = buf[ri] >= '0' && buf[ri] <= '9'; + if (!(isa || isA || isn)) { + /* not a hexadecimal */ + int sri; + for (sri = ri - di; sri <= ri; sri += 1) { + buf[wi] = buf[sri]; + wi += 1; + } + di = 0; + continue; + } + /* itsy bitsy magicsy */ + if (isn) { + off = 0 - '0'; + } else if (isa) { + off = 10 - 'a'; + } else if (isA) { + off = 10 - 'A'; + } + decode |= (buf[ri] + off) << (2 - di) * 4; + if (di == 2) { + buf[wi] = decode; + wi += 1; + di = 0; + } else { + di += 1; + } + continue; + } + } + buf[wi] = '\0'; + return wi; +} + +/* Convert URI to local filename + return filename if possible, else NULL + + FIXME: This was shamelessly copied from SDL_x11events.c +*/ +static char* Wayland_URIToLocal(char* uri) { + char *file = NULL; + SDL_bool local; + + if (SDL_memcmp(uri,"file:/",6) == 0) uri += 6; /* local file? */ + else if (SDL_strstr(uri,":/") != NULL) return file; /* wrong scheme */ + + local = uri[0] != '/' || (uri[0] != '\0' && uri[1] == '/'); + + /* got a hostname? */ + if (!local && uri[0] == '/' && uri[2] != '/') { + char* hostname_end = SDL_strchr(uri+1, '/'); + if (hostname_end != NULL) { + char hostname[ 257 ]; + if (gethostname(hostname, 255) == 0) { + hostname[ 256 ] = '\0'; + if (SDL_memcmp(uri+1, hostname, hostname_end - (uri+1)) == 0) { + uri = hostname_end + 1; + local = SDL_TRUE; + } + } + } + } + if (local) { + file = uri; + /* Convert URI escape sequences to real characters */ + Wayland_URIDecode(file, 0); + if (uri[1] == '/') { + file++; + } else { + file--; + } + } + return file; +} + static void data_device_handle_drop(void *data, struct wl_data_device *wl_data_device) { SDL_WaylandDataDevice *data_device = data; - void *buffer = NULL; - size_t length = 0; - - const char *current_uri = NULL; - const char *last_char = NULL; - char *current_char = NULL; if (data_device->drag_offer != NULL) { /* TODO: SDL Support more mime types */ - buffer = Wayland_data_offer_receive(data_device->drag_offer, - &length, FILE_MIME, SDL_FALSE); - - /* uri-list */ - current_uri = (const char *)buffer; - last_char = (const char *)buffer + length; - for (current_char = buffer; current_char < last_char; ++current_char) { - if (*current_char == '\n' || *current_char == 0) { - if (*current_uri != 0 && *current_uri != '#') { - *current_char = 0; - SDL_SendDropFile(NULL, current_uri); + size_t length; + void *buffer = Wayland_data_offer_receive(data_device->drag_offer, + &length, FILE_MIME, SDL_FALSE); + if (buffer) { + char *saveptr = NULL; + char *token = SDL_strtokr((char *) buffer, "\r\n", &saveptr); + while (token != NULL) { + char *fn = Wayland_URIToLocal(token); + if (fn) { + SDL_SendDropFile(NULL, fn); /* FIXME: Window? */ } - current_uri = (const char *)current_char + 1; + token = SDL_strtokr(NULL, "\r\n", &saveptr); } + SDL_SendDropComplete(NULL); /* FIXME: Window? */ + SDL_free(buffer); } - - SDL_free(buffer); } } @@ -1082,11 +1484,172 @@ static const struct wl_data_device_listener data_device_listener = { data_device_handle_selection }; +static void +text_input_enter(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + struct wl_surface *surface) +{ + /* No-op */ +} + +static void +text_input_leave(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + struct wl_surface *surface) +{ + /* No-op */ +} + +static void +text_input_preedit_string(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + const char *text, + int32_t cursor_begin, + int32_t cursor_end) +{ + SDL_WaylandTextInput *text_input = data; + char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; + text_input->has_preedit = SDL_TRUE; + if (text) { + size_t text_bytes = SDL_strlen(text), i = 0; + size_t cursor = 0; + + do { + const size_t sz = SDL_utf8strlcpy(buf, text+i, sizeof(buf)); + const size_t chars = SDL_utf8strlen(buf); + + SDL_SendEditingText(buf, cursor, chars); + + i += sz; + cursor += chars; + } while (i < text_bytes); + } else { + buf[0] = '\0'; + SDL_SendEditingText(buf, 0, 0); + } +} + +static void +text_input_commit_string(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + const char *text) +{ + if (text && *text) { + char buf[SDL_TEXTINPUTEVENT_TEXT_SIZE]; + size_t text_bytes = SDL_strlen(text), i = 0; + + while (i < text_bytes) { + size_t sz = SDL_utf8strlcpy(buf, text+i, sizeof(buf)); + SDL_SendKeyboardText(buf); + + i += sz; + } + } +} + +static void +text_input_delete_surrounding_text(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + uint32_t before_length, + uint32_t after_length) +{ + /* FIXME: Do we care about this event? */ +} + +static void +text_input_done(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + uint32_t serial) +{ + SDL_WaylandTextInput *text_input = data; + if (!text_input->has_preedit) { + SDL_SendEditingText("", 0, 0); + } + text_input->has_preedit = SDL_FALSE; +} + +static const struct zwp_text_input_v3_listener text_input_listener = { + text_input_enter, + text_input_leave, + text_input_preedit_string, + text_input_commit_string, + text_input_delete_surrounding_text, + text_input_done +}; + +static void +Wayland_create_data_device(SDL_VideoData *d) +{ + SDL_WaylandDataDevice *data_device = NULL; + + data_device = SDL_calloc(1, sizeof *data_device); + if (data_device == NULL) { + return; + } + + data_device->data_device = wl_data_device_manager_get_data_device( + d->data_device_manager, d->input->seat + ); + data_device->video_data = d; + + if (data_device->data_device == NULL) { + SDL_free(data_device); + } else { + wl_data_device_set_user_data(data_device->data_device, data_device); + wl_data_device_add_listener(data_device->data_device, + &data_device_listener, data_device); + d->input->data_device = data_device; + } +} + +static void +Wayland_create_text_input(SDL_VideoData *d) +{ + SDL_WaylandTextInput *text_input = NULL; + + text_input = SDL_calloc(1, sizeof *text_input); + if (text_input == NULL) { + return; + } + + text_input->text_input = zwp_text_input_manager_v3_get_text_input( + d->text_input_manager, d->input->seat + ); + + if (text_input->text_input == NULL) { + SDL_free(text_input); + } else { + zwp_text_input_v3_set_user_data(text_input->text_input, text_input); + zwp_text_input_v3_add_listener(text_input->text_input, + &text_input_listener, text_input); + d->input->text_input = text_input; + } +} + +void +Wayland_add_data_device_manager(SDL_VideoData *d, uint32_t id, uint32_t version) +{ + d->data_device_manager = wl_registry_bind(d->registry, id, &wl_data_device_manager_interface, SDL_min(3, version)); + + if (d->input != NULL) { + Wayland_create_data_device(d); + } +} + +void +Wayland_add_text_input_manager(SDL_VideoData *d, uint32_t id, uint32_t version) +{ + d->text_input_manager = wl_registry_bind(d->registry, id, &zwp_text_input_manager_v3_interface, 1); + + if (d->input != NULL) { + Wayland_create_text_input(d); + } +} + void Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version) { struct SDL_WaylandInput *input; - SDL_WaylandDataDevice *data_device = NULL; input = SDL_calloc(1, sizeof *input); if (input == NULL) @@ -1099,24 +1662,10 @@ Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version) d->input = input; if (d->data_device_manager != NULL) { - data_device = SDL_calloc(1, sizeof *data_device); - if (data_device == NULL) { - return; - } - - data_device->data_device = wl_data_device_manager_get_data_device( - d->data_device_manager, input->seat - ); - data_device->video_data = d; - - if (data_device->data_device == NULL) { - SDL_free(data_device); - } else { - wl_data_device_set_user_data(data_device->data_device, data_device); - wl_data_device_add_listener(data_device->data_device, - &data_device_listener, data_device); - input->data_device = data_device; - } + Wayland_create_data_device(d); + } + if (d->text_input_manager != NULL) { + Wayland_create_text_input(d); } wl_seat_add_listener(input->seat, &seat_listener, input); @@ -1146,6 +1695,11 @@ void Wayland_display_destroy_input(SDL_VideoData *d) SDL_free(input->data_device); } + if (input->text_input != NULL) { + zwp_text_input_v3_destroy(input->text_input->text_input); + SDL_free(input->text_input); + } + if (input->keyboard) wl_keyboard_destroy(input->keyboard); @@ -1160,6 +1714,12 @@ void Wayland_display_destroy_input(SDL_VideoData *d) if (input->seat) wl_seat_destroy(input->seat); + if (input->xkb.compose_state) + WAYLAND_xkb_compose_state_unref(input->xkb.compose_state); + + if (input->xkb.compose_table) + WAYLAND_xkb_compose_table_unref(input->xkb.compose_table); + if (input->xkb.state) WAYLAND_xkb_state_unref(input->xkb.state); @@ -1170,15 +1730,6 @@ void Wayland_display_destroy_input(SDL_VideoData *d) d->input = NULL; } -SDL_WaylandDataDevice* Wayland_get_data_device(struct SDL_WaylandInput *input) -{ - if (input == NULL) { - return NULL; - } - - return input->data_device; -} - /* !!! FIXME: just merge these into display_handle_global(). */ void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id) { @@ -1284,11 +1835,12 @@ lock_pointer_to_window(SDL_Window *window, w->locked_pointer = locked_pointer; } -static void pointer_confine_destroy(struct SDL_WaylandInput *input) +static void pointer_confine_destroy(SDL_Window *window) { - if (input->confined_pointer) { - zwp_confined_pointer_v1_destroy(input->confined_pointer); - input->confined_pointer = NULL; + SDL_WindowData *w = window->driverdata; + if (w->confined_pointer) { + zwp_confined_pointer_v1_destroy(w->confined_pointer); + w->confined_pointer = NULL; } } @@ -1310,7 +1862,8 @@ int Wayland_input_lock_pointer(struct SDL_WaylandInput *input) /* If we have a pointer confine active, we must destroy it here because * creating a locked pointer otherwise would be a protocol error. */ - pointer_confine_destroy(input); + for (window = vd->windows; window; window = window->next) + pointer_confine_destroy(window); if (!input->relative_pointer) { relative_pointer = @@ -1350,8 +1903,8 @@ int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input) d->relative_mouse_mode = 0; - if (input->confined_pointer_window) - Wayland_input_confine_pointer(input->confined_pointer_window, input); + for (window = vd->windows; window; window = window->next) + Wayland_input_confine_pointer(input, window); return 0; } @@ -1373,11 +1926,12 @@ static const struct zwp_confined_pointer_v1_listener confined_pointer_listener = confined_pointer_unconfined, }; -int Wayland_input_confine_pointer(SDL_Window *window, struct SDL_WaylandInput *input) +int Wayland_input_confine_pointer(struct SDL_WaylandInput *input, SDL_Window *window) { SDL_WindowData *w = window->driverdata; SDL_VideoData *d = input->display; struct zwp_confined_pointer_v1 *confined_pointer; + struct wl_region *confine_rect; if (!d->pointer_constraints) return -1; @@ -1387,34 +1941,76 @@ int Wayland_input_confine_pointer(SDL_Window *window, struct SDL_WaylandInput *i /* A confine may already be active, in which case we should destroy it and * create a new one. */ - if (input->confined_pointer) - Wayland_input_unconfine_pointer(input); - - input->confined_pointer_window = window; + pointer_confine_destroy(window); /* We cannot create a confine if the pointer is already locked. Defer until * the pointer is unlocked. */ if (d->relative_mouse_mode) return 0; + if (SDL_RectEmpty(&window->mouse_rect)) { + confine_rect = NULL; + } else { + confine_rect = wl_compositor_create_region(d->compositor); + wl_region_add(confine_rect, + window->mouse_rect.x, + window->mouse_rect.y, + window->mouse_rect.w, + window->mouse_rect.h); + } + confined_pointer = zwp_pointer_constraints_v1_confine_pointer(d->pointer_constraints, w->surface, input->pointer, - NULL, + confine_rect, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); zwp_confined_pointer_v1_add_listener(confined_pointer, &confined_pointer_listener, window); - input->confined_pointer = confined_pointer; + if (confine_rect != NULL) { + wl_region_destroy(confine_rect); + } + + w->confined_pointer = confined_pointer; return 0; } -int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input) +int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input, SDL_Window *window) { - pointer_confine_destroy(input); - input->confined_pointer_window = NULL; + pointer_confine_destroy(window); + return 0; +} + +int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *input) +{ + SDL_WindowData *w = window->driverdata; + SDL_VideoData *d = input->display; + + if (!d->key_inhibitor_manager) + return -1; + + if (w->key_inhibitor) + return 0; + + w->key_inhibitor = + zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(d->key_inhibitor_manager, + w->surface, + input->seat); + + return 0; +} + +int Wayland_input_ungrab_keyboard(SDL_Window *window) +{ + SDL_WindowData *w = window->driverdata; + + if (w->key_inhibitor) { + zwp_keyboard_shortcuts_inhibitor_v1_destroy(w->key_inhibitor); + w->key_inhibitor = NULL; + } + return 0; } diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h index 96aaa397f..24256a7d0 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,28 +27,86 @@ #include "SDL_waylandvideo.h" #include "SDL_waylandwindow.h" #include "SDL_waylanddatamanager.h" +#include "SDL_waylandkeyboard.h" -struct SDL_WaylandInput; +typedef struct { + // repeat_rate in range of [1, 1000] + int32_t repeat_rate; + int32_t repeat_delay; + SDL_bool is_initialized; + + SDL_bool is_key_down; + uint32_t wl_press_time; // Key press time as reported by the Wayland API + uint32_t sdl_press_time; // Key press time expressed in SDL ticks + uint32_t next_repeat_ms; + uint32_t scancode; + char text[8]; +} SDL_WaylandKeyboardRepeat; + +struct SDL_WaylandInput { + SDL_VideoData *display; + struct wl_seat *seat; + struct wl_pointer *pointer; + struct wl_touch *touch; + struct wl_keyboard *keyboard; + SDL_WaylandDataDevice *data_device; + SDL_WaylandTextInput *text_input; + struct zwp_relative_pointer_v1 *relative_pointer; + SDL_WindowData *pointer_focus; + SDL_WindowData *keyboard_focus; + uint32_t pointer_enter_serial; + + /* Last motion location */ + wl_fixed_t sx_w; + wl_fixed_t sy_w; + + double dx_frac; + double dy_frac; + + struct { + struct xkb_keymap *keymap; + struct xkb_state *state; + struct xkb_compose_table *compose_table; + struct xkb_compose_state *compose_state; + } xkb; + + /* information about axis events on current frame */ + struct { + SDL_bool is_x_discrete; + float x; + + SDL_bool is_y_discrete; + float y; + } pointer_curr_axis_info; + + SDL_WaylandKeyboardRepeat keyboard_repeat; +}; extern void Wayland_PumpEvents(_THIS); +extern void Wayland_SendWakeupEvent(_THIS, SDL_Window *window); +extern int Wayland_WaitEventTimeout(_THIS, int timeout); + +extern void Wayland_add_data_device_manager(SDL_VideoData *d, uint32_t id, uint32_t version); +extern void Wayland_add_text_input_manager(SDL_VideoData *d, uint32_t id, uint32_t version); extern void Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version); extern void Wayland_display_destroy_input(SDL_VideoData *d); -extern SDL_WaylandDataDevice* Wayland_get_data_device(struct SDL_WaylandInput *input); - extern void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id); extern void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d); extern int Wayland_input_lock_pointer(struct SDL_WaylandInput *input); extern int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input); -extern int Wayland_input_confine_pointer(SDL_Window *window, struct SDL_WaylandInput *input); -extern int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input); +extern int Wayland_input_confine_pointer(struct SDL_WaylandInput *input, SDL_Window *window); +extern int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input, SDL_Window *window); extern void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id); extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d); +extern int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *input); +extern int Wayland_input_ungrab_keyboard(SDL_Window *window); + #endif /* SDL_waylandevents_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandkeyboard.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandkeyboard.c new file mode 100644 index 000000000..ad91ca5c4 --- /dev/null +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandkeyboard.c @@ -0,0 +1,154 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_WAYLAND + +#include "../SDL_sysvideo.h" +#include "SDL_waylandvideo.h" +#include "SDL_waylandevents_c.h" +#include "text-input-unstable-v3-client-protocol.h" + +int +Wayland_InitKeyboard(_THIS) +{ +#ifdef SDL_USE_IME + SDL_VideoData *driverdata = _this->driverdata; + if (driverdata->text_input_manager == NULL) { + SDL_IME_Init(); + } +#endif + + return 0; +} + +void +Wayland_QuitKeyboard(_THIS) +{ +#ifdef SDL_USE_IME + SDL_VideoData *driverdata = _this->driverdata; + if (driverdata->text_input_manager == NULL) { + SDL_IME_Quit(); + } +#endif +} + +void +Wayland_StartTextInput(_THIS) +{ + SDL_VideoData *driverdata = _this->driverdata; + + if (driverdata->text_input_manager) { + struct SDL_WaylandInput *input = driverdata->input; + if (input != NULL && input->text_input) { + const SDL_Rect *rect = &input->text_input->cursor_rect; + + /* For some reason this has to be done twice, it appears to be a + * bug in mutter? Maybe? + * -flibit + */ + zwp_text_input_v3_enable(input->text_input->text_input); + zwp_text_input_v3_commit(input->text_input->text_input); + zwp_text_input_v3_enable(input->text_input->text_input); + zwp_text_input_v3_commit(input->text_input->text_input); + + /* Now that it's enabled, set the input properties */ + zwp_text_input_v3_set_content_type(input->text_input->text_input, + ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE, + ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL); + if (!SDL_RectEmpty(rect)) { + /* This gets reset on enable so we have to cache it */ + zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input, + rect->x, + rect->y, + rect->w, + rect->h); + } + zwp_text_input_v3_commit(input->text_input->text_input); + } + } +} + +void +Wayland_StopTextInput(_THIS) +{ + SDL_VideoData *driverdata = _this->driverdata; + + if (driverdata->text_input_manager) { + struct SDL_WaylandInput *input = driverdata->input; + if (input != NULL && input->text_input) { + zwp_text_input_v3_disable(input->text_input->text_input); + zwp_text_input_v3_commit(input->text_input->text_input); + } + } + +#ifdef SDL_USE_IME + else { + SDL_IME_Reset(); + } +#endif +} + +void +Wayland_SetTextInputRect(_THIS, SDL_Rect *rect) +{ + SDL_VideoData *driverdata = _this->driverdata; + + if (!rect) { + SDL_InvalidParamError("rect"); + return; + } + + if (driverdata->text_input_manager) { + struct SDL_WaylandInput *input = driverdata->input; + if (input != NULL && input->text_input) { + SDL_memcpy(&input->text_input->cursor_rect, rect, sizeof(SDL_Rect)); + zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input, + rect->x, + rect->y, + rect->w, + rect->h); + zwp_text_input_v3_commit(input->text_input->text_input); + } + } + +#ifdef SDL_USE_IME + else { + SDL_IME_UpdateTextRect(rect); + } +#endif +} + +SDL_bool +Wayland_HasScreenKeyboardSupport(_THIS) +{ + /* In reality we just want to return true when the screen keyboard is the + * _only_ way to get text input. So, in addition to checking for the text + * input protocol, make sure we don't have any physical keyboards either. + */ + SDL_VideoData *driverdata = _this->driverdata; + return (driverdata->input->keyboard == NULL && + driverdata->text_input_manager != NULL); +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandkeyboard.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandkeyboard.h new file mode 100644 index 000000000..604e0f37f --- /dev/null +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandkeyboard.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_waylandkeyboard_h_ +#define SDL_waylandkeyboard_h_ + +typedef struct SDL_WaylandTextInput +{ + struct zwp_text_input_v3 *text_input; + SDL_Rect cursor_rect; + SDL_bool has_preedit; +} SDL_WaylandTextInput; + +extern int Wayland_InitKeyboard(_THIS); +extern void Wayland_QuitKeyboard(_THIS); +extern void Wayland_StartTextInput(_THIS); +extern void Wayland_StopTextInput(_THIS); +extern void Wayland_SetTextInputRect(_THIS, SDL_Rect *rect); +extern SDL_bool Wayland_HasScreenKeyboardSupport(_THIS); + +#endif /* SDL_waylandkeyboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandmessagebox.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandmessagebox.c new file mode 100644 index 000000000..e81f0e64c --- /dev/null +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandmessagebox.c @@ -0,0 +1,195 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_WAYLAND + +#include "SDL.h" +#include /* fgets */ +#include /* FILE, STDOUT_FILENO, fdopen, fclose */ +#include /* pid_t, pipe, fork, close, dup2, execvp, _exit */ +#include /* waitpid, WIFEXITED, WEXITSTATUS */ +#include /* strerr */ +#include + +#include "SDL_waylandmessagebox.h" + +#define MAX_BUTTONS 8 /* Maximum number of buttons supported */ + +int +Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ + int fd_pipe[2]; /* fd_pipe[0]: read end of pipe, fd_pipe[1]: write end of pipe */ + pid_t pid1; + + if (messageboxdata->numbuttons > MAX_BUTTONS) { + return SDL_SetError("Too many buttons (%d max allowed)", MAX_BUTTONS); + } + + if (pipe(fd_pipe) != 0) { /* create a pipe */ + return SDL_SetError("pipe() failed: %s", strerror(errno)); + } + + pid1 = fork(); + if (pid1 == 0) { /* child process */ + int argc = 5, i; + const char* argv[5 + 2/* icon name */ + 2/* title */ + 2/* message */ + 2*MAX_BUTTONS + 1/* NULL */] = { + "zenity", "--question", "--switch", "--no-wrap", "--no-markup" + }; + + close(fd_pipe[0]); /* no reading from pipe */ + /* write stdout in pipe */ + if (dup2(fd_pipe[1], STDOUT_FILENO) == -1) { + _exit(128); + } + + argv[argc++] = "--icon-name"; + switch (messageboxdata->flags) { + case SDL_MESSAGEBOX_ERROR: + argv[argc++] = "dialog-error"; + break; + case SDL_MESSAGEBOX_WARNING: + argv[argc++] = "dialog-warning"; + break; + case SDL_MESSAGEBOX_INFORMATION: + default: + argv[argc++] = "dialog-information"; + break; + } + + if (messageboxdata->title && messageboxdata->title[0]) { + argv[argc++] = "--title"; + argv[argc++] = messageboxdata->title; + } else { + argv[argc++] = "--title=\"\""; + } + + if (messageboxdata->message && messageboxdata->message[0]) { + argv[argc++] = "--text"; + argv[argc++] = messageboxdata->message; + } else { + argv[argc++] = "--text=\"\""; + } + + for (i = 0; i < messageboxdata->numbuttons; ++i) { + if (messageboxdata->buttons[i].text && messageboxdata->buttons[i].text[0]) { + argv[argc++] = "--extra-button"; + argv[argc++] = messageboxdata->buttons[i].text; + } else { + argv[argc++] = "--extra-button=\"\""; + } + } + argv[argc] = NULL; + + /* const casting argv is fine: + * https://pubs.opengroup.org/onlinepubs/9699919799/functions/fexecve.html -> rational + */ + execvp("zenity", (char **)argv); + _exit(129); + } else if (pid1 < 0) { + close(fd_pipe[0]); + close(fd_pipe[1]); + return SDL_SetError("fork() failed: %s", strerror(errno)); + } else { + int status; + if (waitpid(pid1, &status, 0) == pid1) { + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) < 128) { + int i; + size_t output_len = 1; + char* output = NULL; + char* tmp = NULL; + FILE* stdout = NULL; + + close(fd_pipe[1]); /* no writing to pipe */ + /* At this point, if no button ID is needed, we can just bail as soon as the + * process has completed. + */ + if (buttonid == NULL) { + close(fd_pipe[0]); + return 0; + } + *buttonid = -1; + + /* find button with longest text */ + for (i = 0; i < messageboxdata->numbuttons; ++i) { + if (messageboxdata->buttons[i].text != NULL) { + const size_t button_len = SDL_strlen(messageboxdata->buttons[i].text); + if (button_len > output_len) { + output_len = button_len; + } + } + } + output = SDL_malloc(output_len + 1); + if (!output) { + close(fd_pipe[0]); + return SDL_OutOfMemory(); + } + output[0] = '\0'; + + stdout = fdopen(fd_pipe[0], "r"); + if (!stdout) { + SDL_free(output); + close(fd_pipe[0]); + return SDL_SetError("Couldn't open pipe for reading: %s", strerror(errno)); + } + tmp = fgets(output, output_len + 1, stdout); + fclose(stdout); + + if ((tmp == NULL) || (*tmp == '\0') || (*tmp == '\n')) { + SDL_free(output); + return 0; /* User simply closed the dialog */ + } + + /* It likes to add a newline... */ + tmp = SDL_strrchr(output, '\n'); + if (tmp != NULL) { + *tmp = '\0'; + } + + /* Check which button got pressed */ + for (i = 0; i < messageboxdata->numbuttons; i += 1) { + if (messageboxdata->buttons[i].text != NULL) { + if (SDL_strcmp(output, messageboxdata->buttons[i].text) == 0) { + *buttonid = messageboxdata->buttons[i].buttonid; + break; + } + } + } + + SDL_free(output); + return 0; /* success! */ + } else { + return SDL_SetError("zenity reported error or failed to launch: %d", WEXITSTATUS(status)); + } + } else { + return SDL_SetError("zenity failed for some reason"); + } + } else { + return SDL_SetError("Waiting on zenity failed: %s", strerror(errno)); + } + } +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandmessagebox.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandmessagebox.h new file mode 100644 index 000000000..7404520a7 --- /dev/null +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandmessagebox.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_waylandmessagebox_h_ +#define SDL_waylandmessagebox_h_ + +#if SDL_VIDEO_DRIVER_WAYLAND + +extern int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +#endif /* SDL_waylandmessagebox_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.c index 560f98e60..4545c663d 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "../SDL_sysvideo.h" @@ -35,11 +34,11 @@ #include "SDL_mouse.h" #include "../../events/SDL_mouse_c.h" #include "SDL_waylandvideo.h" +#include "../SDL_pixels_c.h" #include "SDL_waylandevents_c.h" -#include "SDL_waylanddyn.h" #include "wayland-cursor.h" - +#include "SDL_waylandmouse.h" typedef struct { @@ -49,11 +48,120 @@ typedef struct { int hot_x, hot_y; int w, h; - /* Either a preloaded cursor, or one we created ourselves */ - struct wl_cursor *cursor; + /* shm_data is non-NULL for custom cursors. + * When shm_data is NULL, system_cursor must be valid + */ + SDL_SystemCursor system_cursor; void *shm_data; } Wayland_CursorData; +static SDL_bool +wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorData *cdata, float *scale) +{ + struct wl_cursor_theme *theme = NULL; + struct wl_cursor *cursor; + + char *xcursor_size; + int size = 0; + + SDL_Window *focus; + SDL_WindowData *focusdata; + int i; + + /* FIXME: We need to be able to query the cursor size from the desktop at + * some point! For a while this was 32, but when testing on real desktops it + * seems like most of them default to 24. We'll need a protocol to get this + * for real, but for now this is a pretty safe bet. + * -flibit + */ + xcursor_size = SDL_getenv("XCURSOR_SIZE"); + if (xcursor_size != NULL) { + size = SDL_atoi(xcursor_size); + } + if (size <= 0) { + size = 24; + } + + /* First, find the appropriate theme based on the current scale... */ + focus = SDL_GetMouse()->focus; + if (focus == NULL) { + /* Nothing to see here, bail. */ + return SDL_FALSE; + } + focusdata = focus->driverdata; + *scale = focusdata->scale_factor; + size *= focusdata->scale_factor; + for (i = 0; i < vdata->num_cursor_themes; i += 1) { + if (vdata->cursor_themes[i].size == size) { + theme = vdata->cursor_themes[i].theme; + break; + } + } + if (theme == NULL) { + vdata->cursor_themes = SDL_realloc(vdata->cursor_themes, + sizeof(SDL_WaylandCursorTheme) * (vdata->num_cursor_themes + 1)); + if (vdata->cursor_themes == NULL) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + theme = WAYLAND_wl_cursor_theme_load(SDL_getenv("XCURSOR_THEME"), size, vdata->shm); + vdata->cursor_themes[vdata->num_cursor_themes].size = size; + vdata->cursor_themes[vdata->num_cursor_themes++].theme = theme; + } + + /* Next, find the cursor from the theme... */ + switch(cdata->system_cursor) + { + case SDL_SYSTEM_CURSOR_ARROW: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "left_ptr"); + break; + case SDL_SYSTEM_CURSOR_IBEAM: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "xterm"); + break; + case SDL_SYSTEM_CURSOR_WAIT: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "watch"); + break; + case SDL_SYSTEM_CURSOR_CROSSHAIR: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1"); + break; + case SDL_SYSTEM_CURSOR_WAITARROW: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "watch"); + break; + case SDL_SYSTEM_CURSOR_SIZENWSE: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1"); + break; + case SDL_SYSTEM_CURSOR_SIZENESW: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1"); + break; + case SDL_SYSTEM_CURSOR_SIZEWE: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1"); + break; + case SDL_SYSTEM_CURSOR_SIZENS: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1"); + break; + case SDL_SYSTEM_CURSOR_SIZEALL: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1"); + break; + case SDL_SYSTEM_CURSOR_NO: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "xterm"); + break; + case SDL_SYSTEM_CURSOR_HAND: + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1"); + break; + default: + SDL_assert(0); + return SDL_FALSE; + } + + /* ... Set the cursor data, finally. */ + cdata->buffer = WAYLAND_wl_cursor_image_get_buffer(cursor->images[0]); + cdata->hot_x = cursor->images[0]->hotspot_x; + cdata->hot_y = cursor->images[0]->hotspot_y; + cdata->w = cursor->images[0]->width; + cdata->h = cursor->images[0]->height; + return SDL_TRUE; +} + static int wayland_create_tmp_file(off_t size) { @@ -148,36 +256,33 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) { SDL_Cursor *cursor; - cursor = calloc(1, sizeof (*cursor)); + cursor = SDL_calloc(1, sizeof (*cursor)); if (cursor) { SDL_VideoDevice *vd = SDL_GetVideoDevice (); SDL_VideoData *wd = (SDL_VideoData *) vd->driverdata; - Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData)); + Wayland_CursorData *data = SDL_calloc (1, sizeof (Wayland_CursorData)); if (!data) { SDL_OutOfMemory(); - free(cursor); + SDL_free(cursor); return NULL; } cursor->driverdata = (void *) data; - /* Assume ARGB8888 */ - SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); - SDL_assert(surface->pitch == surface->w * 4); - /* Allocate shared memory buffer for this cursor */ if (create_buffer_from_shm (data, surface->w, surface->h, WL_SHM_FORMAT_ARGB8888) < 0) { - free (cursor->driverdata); - free (cursor); + SDL_free (cursor->driverdata); + SDL_free (cursor); return NULL; } - SDL_memcpy(data->shm_data, - surface->pixels, - surface->h * surface->pitch); + /* Wayland requires premultiplied alpha for its surfaces. */ + SDL_PremultiplyAlpha(surface->w, surface->h, + surface->format->format, surface->pixels, surface->pitch, + SDL_PIXELFORMAT_ARGB8888, data->shm_data, surface->w * 4); data->surface = wl_compositor_create_surface(wd->compositor); wl_surface_set_user_data(data->surface, NULL); @@ -194,30 +299,30 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) } static SDL_Cursor * -CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor) +Wayland_CreateSystemCursor(SDL_SystemCursor id) { + SDL_VideoData *data = SDL_GetVideoDevice()->driverdata; SDL_Cursor *cursor; - cursor = calloc(1, sizeof (*cursor)); + cursor = SDL_calloc(1, sizeof (*cursor)); if (cursor) { - Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData)); - if (!data) { + Wayland_CursorData *cdata = SDL_calloc (1, sizeof (Wayland_CursorData)); + if (!cdata) { SDL_OutOfMemory(); - free(cursor); + SDL_free(cursor); return NULL; } - cursor->driverdata = (void *) data; + cursor->driverdata = (void *) cdata; - data->buffer = WAYLAND_wl_cursor_image_get_buffer(wlcursor->images[0]); - data->surface = wl_compositor_create_surface(d->compositor); - wl_surface_set_user_data(data->surface, NULL); - data->hot_x = wlcursor->images[0]->hotspot_x; - data->hot_y = wlcursor->images[0]->hotspot_y; - data->w = wlcursor->images[0]->width; - data->h = wlcursor->images[0]->height; - data->cursor= wlcursor; + cdata->surface = wl_compositor_create_surface(data->compositor); + wl_surface_set_user_data(cdata->surface, NULL); + + /* Note that we can't actually set any other cursor properties, as this + * is output-specific. See wayland_get_system_cursor for the rest! + */ + cdata->system_cursor = id; } else { - SDL_OutOfMemory (); + SDL_OutOfMemory(); } return cursor; @@ -226,66 +331,7 @@ CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor) static SDL_Cursor * Wayland_CreateDefaultCursor() { - SDL_VideoDevice *device = SDL_GetVideoDevice(); - SDL_VideoData *data = device->driverdata; - - return CreateCursorFromWlCursor (data, - WAYLAND_wl_cursor_theme_get_cursor(data->cursor_theme, - "left_ptr")); -} - -static SDL_Cursor * -Wayland_CreateSystemCursor(SDL_SystemCursor id) -{ - SDL_VideoDevice *vd = SDL_GetVideoDevice(); - SDL_VideoData *d = vd->driverdata; - - struct wl_cursor *cursor = NULL; - - switch(id) - { - default: - SDL_assert(0); - return NULL; - case SDL_SYSTEM_CURSOR_ARROW: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr"); - break; - case SDL_SYSTEM_CURSOR_IBEAM: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "xterm"); - break; - case SDL_SYSTEM_CURSOR_WAIT: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "watch"); - break; - case SDL_SYSTEM_CURSOR_CROSSHAIR: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1"); - break; - case SDL_SYSTEM_CURSOR_WAITARROW: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "watch"); - break; - case SDL_SYSTEM_CURSOR_SIZENWSE: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1"); - break; - case SDL_SYSTEM_CURSOR_SIZENESW: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1"); - break; - case SDL_SYSTEM_CURSOR_SIZEWE: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1"); - break; - case SDL_SYSTEM_CURSOR_SIZENS: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1"); - break; - case SDL_SYSTEM_CURSOR_SIZEALL: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1"); - break; - case SDL_SYSTEM_CURSOR_NO: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "xterm"); - break; - case SDL_SYSTEM_CURSOR_HAND: - cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1"); - break; - } - - return CreateCursorFromWlCursor(d, cursor); + return Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); } static void @@ -302,14 +348,14 @@ Wayland_FreeCursor(SDL_Cursor *cursor) if (!d) return; - if (d->buffer && !d->cursor) + if (d->buffer && d->shm_data) wl_buffer_destroy(d->buffer); if (d->surface) wl_surface_destroy(d->surface); /* Not sure what's meant to happen to shm_data */ - free (cursor->driverdata); + SDL_free(cursor->driverdata); SDL_free(cursor); } @@ -318,8 +364,9 @@ Wayland_ShowCursor(SDL_Cursor *cursor) { SDL_VideoDevice *vd = SDL_GetVideoDevice(); SDL_VideoData *d = vd->driverdata; - + struct SDL_WaylandInput *input = d->input; struct wl_pointer *pointer = d->pointer; + float scale = 1.0f; if (!pointer) return -1; @@ -328,20 +375,26 @@ Wayland_ShowCursor(SDL_Cursor *cursor) { Wayland_CursorData *data = cursor->driverdata; - wl_pointer_set_cursor (pointer, 0, - data->surface, - data->hot_x, - data->hot_y); + /* TODO: High-DPI custom cursors? -flibit */ + if (data->shm_data == NULL) { + if (!wayland_get_system_cursor(d, data, &scale)) { + return -1; + } + } + + wl_surface_set_buffer_scale(data->surface, scale); + wl_pointer_set_cursor(pointer, + input->pointer_enter_serial, + data->surface, + data->hot_x / scale, + data->hot_y / scale); wl_surface_attach(data->surface, data->buffer, 0, 0); wl_surface_damage(data->surface, 0, 0, data->w, data->h); wl_surface_commit(data->surface); } else { - wl_pointer_set_cursor (pointer, 0, - NULL, - 0, - 0); + wl_pointer_set_cursor(pointer, input->pointer_enter_serial, NULL, 0, 0); } return 0; @@ -388,10 +441,15 @@ Wayland_InitMouse(void) } void -Wayland_FiniMouse(void) +Wayland_FiniMouse(SDL_VideoData *data) { - /* This effectively assumes that nobody else - * touches SDL_Mouse which is effectively - * a singleton */ + int i; + for (i = 0; i < data->num_cursor_themes; i += 1) { + WAYLAND_wl_cursor_theme_destroy(data->cursor_themes[i].theme); + } + SDL_free(data->cursor_themes); } + #endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.h index 95ff7195a..76b58b5c2 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,6 +26,6 @@ #if SDL_VIDEO_DRIVER_WAYLAND extern void Wayland_InitMouse(void); -extern void Wayland_FiniMouse(void); +extern void Wayland_FiniMouse(SDL_VideoData *data); #endif diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.c index b5771e0b8..6b10cbee7 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,16 +22,16 @@ #if SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL +#include "SDL_timer.h" +#include "../../core/unix/SDL_poll.h" #include "../SDL_sysvideo.h" #include "../../events/SDL_windowevents_c.h" #include "SDL_waylandvideo.h" #include "SDL_waylandopengles.h" #include "SDL_waylandwindow.h" #include "SDL_waylandevents_c.h" -#include "SDL_waylanddyn.h" #include "xdg-shell-client-protocol.h" -#include "xdg-shell-unstable-v6-client-protocol.h" /* EGL implementation of SDL OpenGL ES support */ @@ -39,12 +39,12 @@ int Wayland_GLES_LoadLibrary(_THIS, const char *path) { int ret; SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - + ret = SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display, 0); Wayland_PumpEvents(_this); WAYLAND_wl_display_flush(data->display); - + return ret; } @@ -55,21 +55,123 @@ Wayland_GLES_CreateContext(_THIS, SDL_Window * window) SDL_GLContext context; context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); - + return context; } +/* Wayland wants to tell you when to provide new frames, and if you have a non-zero + swap interval, Mesa will block until a callback tells it to do so. On some + compositors, they might decide that a minimized window _never_ gets a callback, + which causes apps to hang during swapping forever. So we always set the official + eglSwapInterval to zero to avoid blocking inside EGL, and manage this ourselves. + If a swap blocks for too long waiting on a callback, we just go on, under the + assumption the frame will be wasted, but this is better than freezing the app. + I frown upon platforms that dictate this sort of control inversion (the callback + is intended for _rendering_, not stalling until vsync), but we can work around + this for now. --ryan. */ +/* Addendum: several recent APIs demand this sort of control inversion: Emscripten, + libretro, Wayland, probably others...it feels like we're eventually going to have + to give in with a future SDL API revision, since we can bend the other APIs to + this style, but this style is much harder to bend the other way. :/ */ +int +Wayland_GLES_SetSwapInterval(_THIS, int interval) +{ + if (!_this->egl_data) { + return SDL_SetError("EGL not initialized"); + } + + /* technically, this is _all_ adaptive vsync (-1), because we can't + actually wait for the _next_ vsync if you set 1, but things that + request 1 probably won't care _that_ much. I hope. No matter what + you do, though, you never see tearing on Wayland. */ + if (interval > 1) { + interval = 1; + } else if (interval < -1) { + interval = -1; + } + + /* !!! FIXME: technically, this should be per-context, right? */ + _this->egl_data->egl_swapinterval = interval; + _this->egl_data->eglSwapInterval(_this->egl_data->egl_display, 0); + return 0; +} + +int +Wayland_GLES_GetSwapInterval(_THIS) +{ + if (!_this->egl_data) { + SDL_SetError("EGL not initialized"); + return 0; + } + + return _this->egl_data->egl_swapinterval; +} + int Wayland_GLES_SwapWindow(_THIS, SDL_Window *window) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + const int swap_interval = _this->egl_data->egl_swapinterval; - if (SDL_EGL_SwapBuffers(_this, data->egl_surface) < 0) { - return -1; + /* For windows that we know are hidden, skip swaps entirely, if we don't do + * this compositors will intentionally stall us indefinitely and there's no + * way for an end user to show the window, unlike other situations (i.e. + * the window is minimized, behind another window, etc.). + * + * FIXME: Request EGL_WAYLAND_swap_buffers_with_timeout. + * -flibit + */ + if (window->flags & SDL_WINDOW_HIDDEN) { + return 0; } - // Wayland-EGL forbids drawing calls in-between SwapBuffers and wl_egl_window_resize - Wayland_HandlePendingResize(window); + /* Control swap interval ourselves. See comments on Wayland_GLES_SetSwapInterval */ + if (swap_interval != 0) { + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + struct wl_display *display = videodata->display; + SDL_VideoDisplay *sdldisplay = SDL_GetDisplayForWindow(window); + /* ~10 frames (or 1 sec), so we'll progress even if throttled to zero. */ + const Uint32 max_wait = SDL_GetTicks() + (sdldisplay->current_mode.refresh_rate ? + (10000 / sdldisplay->current_mode.refresh_rate) : 1000); + while (SDL_AtomicGet(&data->swap_interval_ready) == 0) { + Uint32 now; + + WAYLAND_wl_display_flush(display); + + /* wl_display_prepare_read_queue() will return -1 if the event queue is not empty. + * If the event queue is empty, it will prepare us for our SDL_IOReady() call. */ + if (WAYLAND_wl_display_prepare_read_queue(display, data->frame_event_queue) != 0) { + /* We have some pending events. Check if the frame callback happened. */ + WAYLAND_wl_display_dispatch_queue_pending(display, data->frame_event_queue); + continue; + } + + /* Beyond this point, we must either call wl_display_cancel_read() or wl_display_read_events() */ + + now = SDL_GetTicks(); + if (SDL_TICKS_PASSED(now, max_wait)) { + /* Timeout expired. Cancel the read. */ + WAYLAND_wl_display_cancel_read(display); + break; + } + + if (SDL_IOReady(WAYLAND_wl_display_get_fd(display), SDL_IOR_READ, max_wait - now) <= 0) { + /* Error or timeout expired without any events for us. Cancel the read. */ + WAYLAND_wl_display_cancel_read(display); + break; + } + + /* We have events. Read and dispatch them. */ + WAYLAND_wl_display_read_events(display); + WAYLAND_wl_display_dispatch_queue_pending(display, data->frame_event_queue); + } + SDL_AtomicSet(&data->swap_interval_ready, 0); + } + + /* Feed the frame to Wayland. This will set it so the wl_surface_frame callback can fire again. */ + if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, data->egl_surface)) { + return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers"); + } WAYLAND_wl_display_flush( data->waylandData->display ); @@ -80,16 +182,18 @@ int Wayland_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) { int ret; - + if (window && context) { ret = SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context); } else { ret = SDL_EGL_MakeCurrent(_this, NULL, NULL); } - + WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); - + + _this->egl_data->eglSwapInterval(_this->egl_data->egl_display, 0); /* see comments on Wayland_GLES_SetSwapInterval. */ + return ret; } @@ -110,7 +214,7 @@ Wayland_GLES_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) } } -void +void Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context) { SDL_EGL_DeleteContext(_this, context); diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.h index 23039c340..1abd813df 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,11 +35,11 @@ typedef struct SDL_PrivateGLESData #define Wayland_GLES_GetAttribute SDL_EGL_GetAttribute #define Wayland_GLES_GetProcAddress SDL_EGL_GetProcAddress #define Wayland_GLES_UnloadLibrary SDL_EGL_UnloadLibrary -#define Wayland_GLES_SetSwapInterval SDL_EGL_SetSwapInterval -#define Wayland_GLES_GetSwapInterval SDL_EGL_GetSwapInterval extern int Wayland_GLES_LoadLibrary(_THIS, const char *path); extern SDL_GLContext Wayland_GLES_CreateContext(_THIS, SDL_Window * window); +extern int Wayland_GLES_SetSwapInterval(_THIS, int interval); +extern int Wayland_GLES_GetSwapInterval(_THIS); extern int Wayland_GLES_SwapWindow(_THIS, SDL_Window * window); extern int Wayland_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); extern void Wayland_GLES_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h); diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h index c4c189d3c..fa29bedb1 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,6 +33,8 @@ #define SDL_WAYLAND_INTERFACE(iface) #endif +#include + SDL_WAYLAND_MODULE(WAYLAND_CLIENT) SDL_WAYLAND_SYM(void, wl_proxy_marshal, (struct wl_proxy *, uint32_t, ...)) SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_create, (struct wl_proxy *, const struct wl_interface *)) @@ -44,6 +46,8 @@ SDL_WAYLAND_SYM(uint32_t, wl_proxy_get_version, (struct wl_proxy *)) SDL_WAYLAND_SYM(uint32_t, wl_proxy_get_id, (struct wl_proxy *)) SDL_WAYLAND_SYM(const char *, wl_proxy_get_class, (struct wl_proxy *)) SDL_WAYLAND_SYM(void, wl_proxy_set_queue, (struct wl_proxy *, struct wl_event_queue *)) +SDL_WAYLAND_SYM(void *, wl_proxy_create_wrapper, (void *)) +SDL_WAYLAND_SYM(void, wl_proxy_wrapper_destroy, (void *)) SDL_WAYLAND_SYM(struct wl_display *, wl_display_connect, (const char *)) SDL_WAYLAND_SYM(struct wl_display *, wl_display_connect_to_fd, (int)) SDL_WAYLAND_SYM(void, wl_display_disconnect, (struct wl_display *)) @@ -52,10 +56,15 @@ SDL_WAYLAND_SYM(int, wl_display_dispatch, (struct wl_display *)) SDL_WAYLAND_SYM(int, wl_display_dispatch_queue, (struct wl_display *, struct wl_event_queue *)) SDL_WAYLAND_SYM(int, wl_display_dispatch_queue_pending, (struct wl_display *, struct wl_event_queue *)) SDL_WAYLAND_SYM(int, wl_display_dispatch_pending, (struct wl_display *)) +SDL_WAYLAND_SYM(int, wl_display_prepare_read, (struct wl_display *)) +SDL_WAYLAND_SYM(int, wl_display_prepare_read_queue, (struct wl_display *, struct wl_event_queue *)) +SDL_WAYLAND_SYM(int, wl_display_read_events, (struct wl_display *)) +SDL_WAYLAND_SYM(void, wl_display_cancel_read, (struct wl_display *)) SDL_WAYLAND_SYM(int, wl_display_get_error, (struct wl_display *)) SDL_WAYLAND_SYM(int, wl_display_flush, (struct wl_display *)) SDL_WAYLAND_SYM(int, wl_display_roundtrip, (struct wl_display *)) SDL_WAYLAND_SYM(struct wl_event_queue *, wl_display_create_queue, (struct wl_display *)) +SDL_WAYLAND_SYM(void, wl_event_queue_destroy, (struct wl_event_queue *)) SDL_WAYLAND_SYM(void, wl_log_set_handler_client, (wl_log_func_t)) SDL_WAYLAND_SYM(void, wl_list_init, (struct wl_list *)) SDL_WAYLAND_SYM(void, wl_list_insert, (struct wl_list *, struct wl_list *) ) @@ -71,18 +80,24 @@ SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor, (struct wl_prox SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_10) SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor_versioned, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, ...)) +SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_18) +SDL_WAYLAND_SYM(void, wl_proxy_set_tag, (struct wl_proxy *, const char * const *)) +SDL_WAYLAND_SYM(const char * const *, wl_proxy_get_tag, (struct wl_proxy *)) + +SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_20) +SDL_WAYLAND_SYM(struct wl_proxy*, wl_proxy_marshal_flags, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interfac, uint32_t version, uint32_t flags, ...)) +SDL_WAYLAND_SYM(struct wl_proxy*, wl_proxy_marshal_array_flags, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, uint32_t flags, union wl_argument *args)) + SDL_WAYLAND_INTERFACE(wl_seat_interface) SDL_WAYLAND_INTERFACE(wl_surface_interface) SDL_WAYLAND_INTERFACE(wl_shm_pool_interface) SDL_WAYLAND_INTERFACE(wl_buffer_interface) SDL_WAYLAND_INTERFACE(wl_registry_interface) -SDL_WAYLAND_INTERFACE(wl_shell_surface_interface) SDL_WAYLAND_INTERFACE(wl_region_interface) SDL_WAYLAND_INTERFACE(wl_pointer_interface) SDL_WAYLAND_INTERFACE(wl_keyboard_interface) SDL_WAYLAND_INTERFACE(wl_compositor_interface) SDL_WAYLAND_INTERFACE(wl_output_interface) -SDL_WAYLAND_INTERFACE(wl_shell_interface) SDL_WAYLAND_INTERFACE(wl_shm_interface) SDL_WAYLAND_INTERFACE(wl_data_device_interface) SDL_WAYLAND_INTERFACE(wl_data_source_interface) @@ -107,6 +122,7 @@ SDL_WAYLAND_SYM(int, xkb_state_key_get_syms, (struct xkb_state *, xkb_keycode_t, SDL_WAYLAND_SYM(int, xkb_keysym_to_utf8, (xkb_keysym_t, char *, size_t) ) SDL_WAYLAND_SYM(struct xkb_keymap *, xkb_keymap_new_from_string, (struct xkb_context *, const char *, enum xkb_keymap_format, enum xkb_keymap_compile_flags)) SDL_WAYLAND_SYM(struct xkb_state *, xkb_state_new, (struct xkb_keymap *) ) +SDL_WAYLAND_SYM(int, xkb_keymap_key_repeats, (struct xkb_keymap *keymap, xkb_keycode_t key) ); SDL_WAYLAND_SYM(void, xkb_keymap_unref, (struct xkb_keymap *) ) SDL_WAYLAND_SYM(void, xkb_state_unref, (struct xkb_state *) ) SDL_WAYLAND_SYM(void, xkb_context_unref, (struct xkb_context *) ) @@ -118,6 +134,77 @@ SDL_WAYLAND_SYM(enum xkb_state_component, xkb_state_update_mask, (struct xkb_sta xkb_layout_index_t depressed_layout,\ xkb_layout_index_t latched_layout,\ xkb_layout_index_t locked_layout) ) +SDL_WAYLAND_SYM(struct xkb_compose_table *, xkb_compose_table_new_from_locale, (struct xkb_context *,\ + const char *locale, enum xkb_compose_compile_flags) ) +SDL_WAYLAND_SYM(void, xkb_compose_table_unref, (struct xkb_compose_table *) ) +SDL_WAYLAND_SYM(struct xkb_compose_state *, xkb_compose_state_new, (struct xkb_compose_table *, enum xkb_compose_state_flags) ) +SDL_WAYLAND_SYM(void, xkb_compose_state_unref, (struct xkb_compose_state *) ) +SDL_WAYLAND_SYM(enum xkb_compose_feed_result, xkb_compose_state_feed, (struct xkb_compose_state *, xkb_keysym_t) ) +SDL_WAYLAND_SYM(enum xkb_compose_status, xkb_compose_state_get_status, (struct xkb_compose_state *) ) +SDL_WAYLAND_SYM(xkb_keysym_t, xkb_compose_state_get_one_sym, (struct xkb_compose_state *) ) +SDL_WAYLAND_SYM(void, xkb_keymap_key_for_each, (struct xkb_keymap *, xkb_keymap_key_iter_t, void*) ) +SDL_WAYLAND_SYM(int, xkb_keymap_key_get_syms_by_level, (struct xkb_keymap *, + xkb_keycode_t, + xkb_layout_index_t, + xkb_layout_index_t, + const xkb_keysym_t **) ) +SDL_WAYLAND_SYM(uint32_t, xkb_keysym_to_utf32, (xkb_keysym_t) ) + +#ifdef HAVE_LIBDECOR_H +SDL_WAYLAND_MODULE(WAYLAND_LIBDECOR) +SDL_WAYLAND_SYM(void, libdecor_unref, (struct libdecor *)) +SDL_WAYLAND_SYM(struct libdecor *, libdecor_new, (struct wl_display *, struct libdecor_interface *)) +SDL_WAYLAND_SYM(struct libdecor_frame *, libdecor_decorate, (struct libdecor *,\ + struct wl_surface *,\ + struct libdecor_frame_interface *,\ + void *)) +SDL_WAYLAND_SYM(void, libdecor_frame_unref, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_title, (struct libdecor_frame *, const char *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_app_id, (struct libdecor_frame *, const char *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_max_content_size, (struct libdecor_frame *frame,\ + int content_width,\ + int content_height)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_min_content_size, (struct libdecor_frame *frame,\ + int content_width,\ + int content_height)) +SDL_WAYLAND_SYM(void, libdecor_frame_resize, (struct libdecor_frame *,\ + struct wl_seat *,\ + uint32_t,\ + enum libdecor_resize_edge)) +SDL_WAYLAND_SYM(void, libdecor_frame_move, (struct libdecor_frame *,\ + struct wl_seat *,\ + uint32_t)) +SDL_WAYLAND_SYM(void, libdecor_frame_commit, (struct libdecor_frame *,\ + struct libdecor_state *,\ + struct libdecor_configuration *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_minimized, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_maximized, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_unset_maximized, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_fullscreen, (struct libdecor_frame *, struct wl_output *)) +SDL_WAYLAND_SYM(void, libdecor_frame_unset_fullscreen, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_capabilities, (struct libdecor_frame *, \ + enum libdecor_capabilities)) +SDL_WAYLAND_SYM(void, libdecor_frame_unset_capabilities, (struct libdecor_frame *, \ + enum libdecor_capabilities)) +SDL_WAYLAND_SYM(bool, libdecor_frame_has_capability, (struct libdecor_frame *, \ + enum libdecor_capabilities)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_visibility, (struct libdecor_frame *, bool)) +SDL_WAYLAND_SYM(bool, libdecor_frame_is_visible, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(bool, libdecor_frame_is_floating, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_parent, (struct libdecor_frame *,\ + struct libdecor_frame *)) +SDL_WAYLAND_SYM(struct xdg_surface *, libdecor_frame_get_xdg_surface, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(struct xdg_toplevel *, libdecor_frame_get_xdg_toplevel, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_map, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(struct libdecor_state *, libdecor_state_new, (int, int)) +SDL_WAYLAND_SYM(void, libdecor_state_free, (struct libdecor_state *)) +SDL_WAYLAND_SYM(bool, libdecor_configuration_get_content_size, (struct libdecor_configuration *,\ + struct libdecor_frame *,\ + int *,\ + int *)) +SDL_WAYLAND_SYM(bool, libdecor_configuration_get_window_state, (struct libdecor_configuration *,\ + enum libdecor_window_state *)) +#endif #undef SDL_WAYLAND_MODULE #undef SDL_WAYLAND_SYM diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandtouch.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandtouch.c index cfb95d2e9..b3879f176 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandtouch.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandtouch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -73,8 +73,8 @@ touch_handle_touch(void *data, **/ float FIXED_TO_FLOAT = 1. / 10000.; - float xf = FIXED_TO_FLOAT * x; - float yf = FIXED_TO_FLOAT * y; + float xf = FIXED_TO_FLOAT * normalized_x; + float yf = FIXED_TO_FLOAT * normalized_y; float PRESSURE_TO_FLOAT = 1. / 255.; float pressuref = PRESSURE_TO_FLOAT * pressure; @@ -160,7 +160,7 @@ static const struct wl_message qt_touch_extension_events[] = { { "configure", "u", qt_touch_extension_types + 0 }, }; -WL_EXPORT const struct wl_interface qt_touch_extension_interface = { +const struct wl_interface qt_touch_extension_interface = { "qt_touch_extension", 1, 1, qt_touch_extension_requests, 2, qt_touch_extension_events, @@ -183,7 +183,7 @@ static const struct wl_message qt_windowmanager_events[] = { { "quit", "", qt_windowmanager_types + 0 }, }; -WL_EXPORT const struct wl_interface qt_windowmanager_interface = { +const struct wl_interface qt_windowmanager_interface = { "qt_windowmanager", 1, 1, qt_windowmanager_requests, 2, qt_windowmanager_events, @@ -214,7 +214,7 @@ static const struct wl_message qt_surface_extension_requests[] = { { "get_extended_surface", "no", qt_surface_extension_types + 2 }, }; -WL_EXPORT const struct wl_interface qt_surface_extension_interface = { +const struct wl_interface qt_surface_extension_interface = { "qt_surface_extension", 1, 1, qt_surface_extension_requests, 0, NULL, @@ -232,7 +232,7 @@ static const struct wl_message qt_extended_surface_events[] = { { "close", "", qt_surface_extension_types + 0 }, }; -WL_EXPORT const struct wl_interface qt_extended_surface_interface = { +const struct wl_interface qt_extended_surface_interface = { "qt_extended_surface", 1, 3, qt_extended_surface_requests, 3, qt_extended_surface_events, diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandtouch.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandtouch.h index 0980ae0d9..e4436f9f4 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandtouch.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandtouch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,7 +30,6 @@ #include #include #include "wayland-util.h" -#include "SDL_waylanddyn.h" void Wayland_touch_create(SDL_VideoData *data, uint32_t id); diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c index 469bb7364..61940cca4 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,22 +33,29 @@ #include "SDL_waylandwindow.h" #include "SDL_waylandopengles.h" #include "SDL_waylandmouse.h" +#include "SDL_waylandkeyboard.h" #include "SDL_waylandtouch.h" #include "SDL_waylandclipboard.h" #include "SDL_waylandvulkan.h" +#include "SDL_hints.h" #include #include #include #include -#include "SDL_waylanddyn.h" #include #include "xdg-shell-client-protocol.h" -#include "xdg-shell-unstable-v6-client-protocol.h" #include "xdg-decoration-unstable-v1-client-protocol.h" -#include "org-kde-kwin-server-decoration-manager-client-protocol.h" +#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h" +#include "idle-inhibit-unstable-v1-client-protocol.h" +#include "xdg-activation-v1-client-protocol.h" +#include "text-input-unstable-v3-client-protocol.h" + +#ifdef HAVE_LIBDECOR_H +#include +#endif #define WAYLANDVID_DRIVER_NAME "wayland" @@ -56,10 +63,11 @@ static int Wayland_VideoInit(_THIS); -static void -Wayland_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display); static int -Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); +Wayland_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect); + +static int +Wayland_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * hdpi, float * vdpi); static void Wayland_VideoQuit(_THIS); @@ -120,6 +128,39 @@ get_classname() return SDL_strdup("SDL_App"); } +static const char *SDL_WAYLAND_surface_tag = "sdl-window"; +static const char *SDL_WAYLAND_output_tag = "sdl-output"; + +void SDL_WAYLAND_register_surface(struct wl_surface *surface) +{ + if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { + wl_proxy_set_tag((struct wl_proxy *)surface, &SDL_WAYLAND_surface_tag); + } +} + +void SDL_WAYLAND_register_output(struct wl_output *output) +{ + if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { + wl_proxy_set_tag((struct wl_proxy *)output, &SDL_WAYLAND_output_tag); + } +} + +SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface) +{ + if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { + return wl_proxy_get_tag((struct wl_proxy *) surface) == &SDL_WAYLAND_surface_tag; + } + return SDL_TRUE; /* For older clients we have to assume this is us... */ +} + +SDL_bool SDL_WAYLAND_own_output(struct wl_output *output) +{ + if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { + return wl_proxy_get_tag((struct wl_proxy *) output) == &SDL_WAYLAND_output_tag; + } + return SDL_TRUE; /* For older clients we have to assume this is us... */ +} + static void Wayland_DeleteDevice(SDL_VideoDevice *device) { @@ -128,6 +169,9 @@ Wayland_DeleteDevice(SDL_VideoDevice *device) WAYLAND_wl_display_flush(data->display); WAYLAND_wl_display_disconnect(data->display); } + if (device->wakeup_lock) { + SDL_DestroyMutex(device->wakeup_lock); + } SDL_free(data); SDL_free(device); SDL_WAYLAND_UnloadSymbols(); @@ -158,6 +202,7 @@ Wayland_CreateDevice(int devindex) return NULL; } + data->initializing = SDL_TRUE; data->display = display; /* Initialize all variables that we clean on shutdown */ @@ -171,16 +216,21 @@ Wayland_CreateDevice(int devindex) } device->driverdata = data; + device->wakeup_lock = SDL_CreateMutex(); /* Set the function pointers */ device->VideoInit = Wayland_VideoInit; device->VideoQuit = Wayland_VideoQuit; - device->SetDisplayMode = Wayland_SetDisplayMode; - device->GetDisplayModes = Wayland_GetDisplayModes; + device->GetDisplayBounds = Wayland_GetDisplayBounds; + device->GetDisplayDPI = Wayland_GetDisplayDPI; device->GetWindowWMInfo = Wayland_GetWindowWMInfo; + device->SuspendScreenSaver = Wayland_SuspendScreenSaver; device->PumpEvents = Wayland_PumpEvents; + device->WaitEventTimeout = Wayland_WaitEventTimeout; + device->SendWakeupEvent = Wayland_SendWakeupEvent; +#if SDL_VIDEO_OPENGL_EGL device->GL_SwapWindow = Wayland_GLES_SwapWindow; device->GL_GetSwapInterval = Wayland_GLES_GetSwapInterval; device->GL_SetSwapInterval = Wayland_GLES_SetSwapInterval; @@ -191,22 +241,37 @@ Wayland_CreateDevice(int devindex) device->GL_UnloadLibrary = Wayland_GLES_UnloadLibrary; device->GL_GetProcAddress = Wayland_GLES_GetProcAddress; device->GL_DeleteContext = Wayland_GLES_DeleteContext; +#endif device->CreateSDLWindow = Wayland_CreateWindow; device->ShowWindow = Wayland_ShowWindow; + device->HideWindow = Wayland_HideWindow; + device->RaiseWindow = Wayland_RaiseWindow; device->SetWindowFullscreen = Wayland_SetWindowFullscreen; device->MaximizeWindow = Wayland_MaximizeWindow; - device->SetWindowGrab = Wayland_SetWindowGrab; + device->MinimizeWindow = Wayland_MinimizeWindow; + device->SetWindowMouseRect = Wayland_SetWindowMouseRect; + device->SetWindowMouseGrab = Wayland_SetWindowMouseGrab; + device->SetWindowKeyboardGrab = Wayland_SetWindowKeyboardGrab; device->RestoreWindow = Wayland_RestoreWindow; device->SetWindowBordered = Wayland_SetWindowBordered; + device->SetWindowResizable = Wayland_SetWindowResizable; device->SetWindowSize = Wayland_SetWindowSize; + device->SetWindowMinimumSize = Wayland_SetWindowMinimumSize; + device->SetWindowMaximumSize = Wayland_SetWindowMaximumSize; + device->SetWindowModalFor = Wayland_SetWindowModalFor; device->SetWindowTitle = Wayland_SetWindowTitle; device->DestroyWindow = Wayland_DestroyWindow; device->SetWindowHitTest = Wayland_SetWindowHitTest; + device->FlashWindow = Wayland_FlashWindow; + device->HasScreenKeyboardSupport = Wayland_HasScreenKeyboardSupport; device->SetClipboardText = Wayland_SetClipboardText; device->GetClipboardText = Wayland_GetClipboardText; device->HasClipboardText = Wayland_HasClipboardText; + device->StartTextInput = Wayland_StartTextInput; + device->StopTextInput = Wayland_StopTextInput; + device->SetTextInputRect = Wayland_SetTextInputRect; #if SDL_VIDEO_VULKAN device->Vulkan_LoadLibrary = Wayland_Vulkan_LoadLibrary; @@ -238,9 +303,61 @@ display_handle_geometry(void *data, int transform) { - SDL_VideoDisplay *display = data; + SDL_WaylandOutputData *driverdata = data; + SDL_VideoDisplay *display; + int i; - display->name = SDL_strdup(model); + if (driverdata->done) { + /* Clear the wl_output ref so Reset doesn't free it */ + display = SDL_GetDisplay(driverdata->index); + for (i = 0; i < display->num_display_modes; i += 1) { + display->display_modes[i].driverdata = NULL; + } + + /* Okay, now it's safe to reset */ + SDL_ResetDisplayModes(driverdata->index); + + /* The display has officially started over. */ + driverdata->done = SDL_FALSE; + } + + driverdata->x = x; + driverdata->y = y; + driverdata->physical_width = physical_width; + driverdata->physical_height = physical_height; + if (driverdata->index == -1) { + driverdata->placeholder.name = SDL_strdup(model); + } + + driverdata->transform = transform; + #define TF_CASE(in, out) \ + case WL_OUTPUT_TRANSFORM_##in: \ + driverdata->orientation = SDL_ORIENTATION_##out; \ + break; + if (driverdata->physical_width >= driverdata->physical_height) { + switch (transform) { + TF_CASE(NORMAL, LANDSCAPE) + TF_CASE(90, PORTRAIT) + TF_CASE(180, LANDSCAPE_FLIPPED) + TF_CASE(270, PORTRAIT_FLIPPED) + TF_CASE(FLIPPED, LANDSCAPE_FLIPPED) + TF_CASE(FLIPPED_90, PORTRAIT_FLIPPED) + TF_CASE(FLIPPED_180, LANDSCAPE) + TF_CASE(FLIPPED_270, PORTRAIT) + } + } else { + switch (transform) { + TF_CASE(NORMAL, PORTRAIT) + TF_CASE(90, LANDSCAPE) + TF_CASE(180, PORTRAIT_FLIPPED) + TF_CASE(270, LANDSCAPE_FLIPPED) + TF_CASE(FLIPPED, PORTRAIT_FLIPPED) + TF_CASE(FLIPPED_90, LANDSCAPE_FLIPPED) + TF_CASE(FLIPPED_180, PORTRAIT) + TF_CASE(FLIPPED_270, LANDSCAPE) + } + } + #undef TF_CASE } static void @@ -251,20 +368,37 @@ display_handle_mode(void *data, int height, int refresh) { + SDL_WaylandOutputData* driverdata = data; SDL_DisplayMode mode; - SDL_VideoDisplay *display = data; - - SDL_zero(mode); - mode.format = SDL_PIXELFORMAT_RGB888; - mode.w = width; - mode.h = height; - mode.refresh_rate = refresh / 1000; // mHz to Hz - mode.driverdata = ((SDL_WaylandOutputData*)display->driverdata)->output; - SDL_AddDisplayMode(display, &mode); if (flags & WL_OUTPUT_MODE_CURRENT) { - display->current_mode = mode; - display->desktop_mode = mode; + /* Don't rotate this yet, handle_done will do it later */ + driverdata->width = width; + driverdata->height = height; + driverdata->refresh = refresh; + } + + /* Note that the width/height are NOT multiplied by scale_factor! + * This is intentional and is designed to get the unscaled modes, which is + * important for high-DPI games intending to use the display mode as the + * target drawable size. The scaled desktop mode will be added at the end + * when display_handle_done is called (see below). + */ + SDL_zero(mode); + mode.format = SDL_PIXELFORMAT_RGB888; + if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) { + mode.w = height; + mode.h = width; + } else { + mode.w = width; + mode.h = height; + } + mode.refresh_rate = (int)SDL_round(refresh / 1000.0); /* mHz to Hz */ + mode.driverdata = driverdata->output; + if (driverdata->index > -1) { + SDL_AddDisplayMode(SDL_GetDisplay(driverdata->index), &mode); + } else { + SDL_AddDisplayMode(&driverdata->placeholder, &mode); } } @@ -272,12 +406,70 @@ static void display_handle_done(void *data, struct wl_output *output) { - /* !!! FIXME: this will fail on any further property changes! */ - SDL_VideoDisplay *display = data; - SDL_AddVideoDisplay(display, SDL_FALSE); - wl_output_set_user_data(output, display->driverdata); - SDL_free(display->name); - SDL_free(display); + SDL_WaylandOutputData* driverdata = data; + SDL_DisplayMode mode; + SDL_VideoDisplay *dpy; + + if (driverdata->done) + return; + + driverdata->done = SDL_TRUE; + + SDL_zero(mode); + mode.format = SDL_PIXELFORMAT_RGB888; + if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) { + mode.w = driverdata->height / driverdata->scale_factor; + mode.h = driverdata->width / driverdata->scale_factor; + + driverdata->hdpi = driverdata->physical_height ? + (((float) driverdata->height) * 25.4f / driverdata->physical_height) : + 0.0f; + driverdata->vdpi = driverdata->physical_width ? + (((float) driverdata->width) * 25.4f / driverdata->physical_width) : + 0.0f; + driverdata->ddpi = SDL_ComputeDiagonalDPI(driverdata->height, + driverdata->width, + ((float) driverdata->physical_height) / 25.4f, + ((float) driverdata->physical_width) / 25.4f); + } else { + mode.w = driverdata->width / driverdata->scale_factor; + mode.h = driverdata->height / driverdata->scale_factor; + + driverdata->hdpi = driverdata->physical_width ? + (((float) driverdata->width) * 25.4f / driverdata->physical_width) : + 0.0f; + driverdata->vdpi = driverdata->physical_height ? + (((float) driverdata->height) * 25.4f / driverdata->physical_height) : + 0.0f; + driverdata->ddpi = SDL_ComputeDiagonalDPI(driverdata->width, + driverdata->height, + ((float) driverdata->physical_width) / 25.4f, + ((float) driverdata->physical_height) / 25.4f); + } + mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */ + mode.driverdata = driverdata->output; + + if (driverdata->index > -1) { + dpy = SDL_GetDisplay(driverdata->index); + } else { + dpy = &driverdata->placeholder; + } + + SDL_AddDisplayMode(dpy, &mode); + SDL_SetCurrentDisplayMode(dpy, &mode); + SDL_SetDesktopDisplayMode(dpy, &mode); + + if (driverdata->index == -1) { + /* First time getting display info, create the VideoDisplay */ + SDL_bool send_event = driverdata->videodata->initializing ? SDL_FALSE : SDL_TRUE; + driverdata->placeholder.orientation = driverdata->orientation; + driverdata->placeholder.driverdata = driverdata; + driverdata->index = SDL_AddVideoDisplay(&driverdata->placeholder, send_event); + SDL_free(driverdata->placeholder.name); + SDL_zero(driverdata->placeholder); + } else { + SDL_SendDisplayEvent(dpy, SDL_DISPLAYEVENT_ORIENTATION, driverdata->orientation); + } } static void @@ -285,8 +477,8 @@ display_handle_scale(void *data, struct wl_output *output, int32_t factor) { - SDL_VideoDisplay *display = data; - ((SDL_WaylandOutputData*)display->driverdata)->scale_factor = factor; + SDL_WaylandOutputData *driverdata = data; + driverdata->scale_factor = factor; } static const struct wl_output_listener output_listener = { @@ -301,25 +493,51 @@ Wayland_add_display(SDL_VideoData *d, uint32_t id) { struct wl_output *output; SDL_WaylandOutputData *data; - SDL_VideoDisplay *display = SDL_malloc(sizeof *display); - if (!display) { - SDL_OutOfMemory(); - return; - } - SDL_zero(*display); output = wl_registry_bind(d->registry, id, &wl_output_interface, 2); if (!output) { SDL_SetError("Failed to retrieve output."); - SDL_free(display); return; } data = SDL_malloc(sizeof *data); + SDL_zerop(data); + data->videodata = d; data->output = output; + data->registry_id = id; data->scale_factor = 1.0; - display->driverdata = data; + data->index = -1; - wl_output_add_listener(output, &output_listener, display); + wl_output_add_listener(output, &output_listener, data); + SDL_WAYLAND_register_output(output); +} + +static void +Wayland_free_display(uint32_t id) +{ + int num_displays = SDL_GetNumVideoDisplays(); + SDL_VideoDisplay *display; + SDL_WaylandOutputData *data; + int i; + + for (i = 0; i < num_displays; i += 1) { + display = SDL_GetDisplay(i); + data = (SDL_WaylandOutputData *) display->driverdata; + if (data->registry_id == id) { + SDL_DelVideoDisplay(i); + wl_output_destroy(data->output); + SDL_free(data); + + /* Update the index for all remaining displays */ + num_displays -= 1; + for (; i < num_displays; i += 1) { + display = SDL_GetDisplay(i); + data = (SDL_WaylandOutputData *) display->driverdata; + data->index -= 1; + } + + return; + } + } } #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH @@ -341,18 +559,6 @@ static const struct qt_windowmanager_listener windowmanager_listener = { }; #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ - -static void -handle_ping_zxdg_shell(void *data, struct zxdg_shell_v6 *zxdg, uint32_t serial) -{ - zxdg_shell_v6_pong(zxdg, serial); -} - -static const struct zxdg_shell_v6_listener shell_listener_zxdg = { - handle_ping_zxdg_shell -}; - - static void handle_ping_xdg_wm_base(void *data, struct xdg_wm_base *xdg, uint32_t serial) { @@ -364,6 +570,21 @@ static const struct xdg_wm_base_listener shell_listener_xdg = { }; +#ifdef HAVE_LIBDECOR_H +static void +libdecor_error(struct libdecor *context, + enum libdecor_error error, + const char *message) +{ + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "libdecor error (%d): %s\n", error, message); +} + +static struct libdecor_interface libdecor_interface = { + libdecor_error, +}; +#endif + + static void display_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) @@ -372,41 +593,41 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id, /*printf("WAYLAND INTERFACE: %s\n", interface);*/ - if (strcmp(interface, "wl_compositor") == 0) { + if (SDL_strcmp(interface, "wl_compositor") == 0) { d->compositor = wl_registry_bind(d->registry, id, &wl_compositor_interface, SDL_min(3, version)); - } else if (strcmp(interface, "wl_output") == 0) { + } else if (SDL_strcmp(interface, "wl_output") == 0) { Wayland_add_display(d, id); - } else if (strcmp(interface, "wl_seat") == 0) { + } else if (SDL_strcmp(interface, "wl_seat") == 0) { Wayland_display_add_input(d, id, version); - } else if (strcmp(interface, "xdg_wm_base") == 0) { + } else if (SDL_strcmp(interface, "xdg_wm_base") == 0) { d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, 1); xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL); - } else if (strcmp(interface, "zxdg_shell_v6") == 0) { - d->shell.zxdg = wl_registry_bind(d->registry, id, &zxdg_shell_v6_interface, 1); - zxdg_shell_v6_add_listener(d->shell.zxdg, &shell_listener_zxdg, NULL); - } else if (strcmp(interface, "wl_shell") == 0) { - d->shell.wl = wl_registry_bind(d->registry, id, &wl_shell_interface, 1); - } else if (strcmp(interface, "wl_shm") == 0) { + } else if (SDL_strcmp(interface, "wl_shm") == 0) { d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); - d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm); - } else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) { + } else if (SDL_strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) { Wayland_display_add_relative_pointer_manager(d, id); - } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) { + } else if (SDL_strcmp(interface, "zwp_pointer_constraints_v1") == 0) { Wayland_display_add_pointer_constraints(d, id); - } else if (strcmp(interface, "wl_data_device_manager") == 0) { - d->data_device_manager = wl_registry_bind(d->registry, id, &wl_data_device_manager_interface, SDL_min(3, version)); - } else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0) { + } else if (SDL_strcmp(interface, "zwp_keyboard_shortcuts_inhibit_manager_v1") == 0) { + d->key_inhibitor_manager = wl_registry_bind(d->registry, id, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1); + } else if (SDL_strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) { + d->idle_inhibit_manager = wl_registry_bind(d->registry, id, &zwp_idle_inhibit_manager_v1_interface, 1); + } else if (SDL_strcmp(interface, "xdg_activation_v1") == 0) { + d->activation_manager = wl_registry_bind(d->registry, id, &xdg_activation_v1_interface, 1); + } else if (SDL_strcmp(interface, "zwp_text_input_manager_v3") == 0) { + Wayland_add_text_input_manager(d, id, version); + } else if (SDL_strcmp(interface, "wl_data_device_manager") == 0) { + Wayland_add_data_device_manager(d, id, version); + } else if (SDL_strcmp(interface, "zxdg_decoration_manager_v1") == 0) { d->decoration_manager = wl_registry_bind(d->registry, id, &zxdg_decoration_manager_v1_interface, 1); - } else if (strcmp(interface, "org_kde_kwin_server_decoration_manager") == 0) { - d->kwin_server_decoration_manager = wl_registry_bind(d->registry, id, &org_kde_kwin_server_decoration_manager_interface, 1); #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH - } else if (strcmp(interface, "qt_touch_extension") == 0) { + } else if (SDL_strcmp(interface, "qt_touch_extension") == 0) { Wayland_touch_create(d, id); - } else if (strcmp(interface, "qt_surface_extension") == 0) { + } else if (SDL_strcmp(interface, "qt_surface_extension") == 0) { d->surface_extension = wl_registry_bind(registry, id, &qt_surface_extension_interface, 1); - } else if (strcmp(interface, "qt_windowmanager") == 0) { + } else if (SDL_strcmp(interface, "qt_windowmanager") == 0) { d->windowmanager = wl_registry_bind(registry, id, &qt_windowmanager_interface, 1); qt_windowmanager_add_listener(d->windowmanager, &windowmanager_listener, d); @@ -415,7 +636,11 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id, } static void -display_remove_global(void *data, struct wl_registry *registry, uint32_t id) {} +display_remove_global(void *data, struct wl_registry *registry, uint32_t id) +{ + /* We don't get an interface, just an ID, so assume it's a wl_output :shrug: */ + Wayland_free_display(id); +} static const struct wl_registry_listener registry_listener = { display_handle_global, @@ -442,6 +667,19 @@ Wayland_VideoInit(_THIS) // First roundtrip to receive all registry objects. WAYLAND_wl_display_roundtrip(data->display); +#ifdef HAVE_LIBDECOR_H + /* Don't have server-side decorations? Try client-side instead. */ + if (!data->decoration_manager && SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR && SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR, SDL_TRUE)) { + data->shell.libdecor = libdecor_new(data->display, &libdecor_interface); + + /* If libdecor works, we don't need xdg-shell anymore. */ + if (data->shell.libdecor && data->shell.xdg) { + xdg_wm_base_destroy(data->shell.xdg); + data->shell.xdg = NULL; + } + } +#endif + // Second roundtrip to receive all output events. WAYLAND_wl_display_roundtrip(data->display); @@ -452,20 +690,40 @@ Wayland_VideoInit(_THIS) WAYLAND_wl_display_flush(data->display); + Wayland_InitKeyboard(_this); + + data->initializing = SDL_FALSE; + return 0; } -static void -Wayland_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display) +static int +Wayland_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) { - // Nothing to do here, everything was already done in the wl_output - // callbacks. + SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *)display->driverdata; + rect->x = driverdata->x; + rect->y = driverdata->y; + rect->w = display->current_mode.w; + rect->h = display->current_mode.h; + return 0; } static int -Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) +Wayland_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * hdpi, float * vdpi) { - return SDL_Unsupported(); + SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *)sdl_display->driverdata; + + if (ddpi) { + *ddpi = driverdata->ddpi; + } + if (hdpi) { + *hdpi = driverdata->hdpi; + } + if (vdpi) { + *vdpi = driverdata->vdpi; + } + + return driverdata->ddpi != 0.0f ? 0 : SDL_SetError("Couldn't get DPI"); } void @@ -474,7 +732,7 @@ Wayland_VideoQuit(_THIS) SDL_VideoData *data = _this->driverdata; int i, j; - Wayland_FiniMouse (); + Wayland_FiniMouse(data); for (i = 0; i < _this->num_displays; ++i) { SDL_VideoDisplay *display = &_this->displays[i]; @@ -493,6 +751,20 @@ Wayland_VideoQuit(_THIS) Wayland_display_destroy_pointer_constraints(data); Wayland_display_destroy_relative_pointer_manager(data); + if (data->activation_manager) + xdg_activation_v1_destroy(data->activation_manager); + + if (data->idle_inhibit_manager) + zwp_idle_inhibit_manager_v1_destroy(data->idle_inhibit_manager); + + if (data->key_inhibitor_manager) + zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(data->key_inhibitor_manager); + + Wayland_QuitKeyboard(_this); + + if (data->text_input_manager) + zwp_text_input_manager_v3_destroy(data->text_input_manager); + if (data->xkb_context) { WAYLAND_xkb_context_unref(data->xkb_context); data->xkb_context = NULL; @@ -507,20 +779,24 @@ Wayland_VideoQuit(_THIS) Wayland_touch_destroy(data); #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + if (data->data_device_manager) + wl_data_device_manager_destroy(data->data_device_manager); + if (data->shm) wl_shm_destroy(data->shm); - if (data->cursor_theme) - WAYLAND_wl_cursor_theme_destroy(data->cursor_theme); - - if (data->shell.wl) - wl_shell_destroy(data->shell.wl); - if (data->shell.xdg) xdg_wm_base_destroy(data->shell.xdg); - if (data->shell.zxdg) - zxdg_shell_v6_destroy(data->shell.zxdg); + if (data->decoration_manager) + zxdg_decoration_manager_v1_destroy(data->decoration_manager); + +#ifdef HAVE_LIBDECOR_H + if (data->shell.libdecor) { + libdecor_unref(data->shell.libdecor); + data->shell.libdecor = NULL; + } +#endif if (data->compositor) wl_compositor_destroy(data->compositor); diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h index 2c481d85e..31168a9d5 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,23 +20,18 @@ */ #include "../../SDL_internal.h" +#include "SDL_stdinc.h" #ifndef SDL_waylandvideo_h_ #define SDL_waylandvideo_h_ - -/* -!!! FIXME: xdg_wm_base is the stable replacement for zxdg_shell_v6. While it's -!!! FIXME: harmless to leave it here, consider deleting the obsolete codepath -!!! FIXME: soon, since Wayland (with xdg_wm_base) will probably be mainline -!!! FIXME: by the time people are relying on this SDL target. It's available -!!! FIXME: in Ubuntu 18.04 (and other distros). -*/ - -#define MESA_EGL_NO_X11_HEADERS #include #include "wayland-util.h" +#include "../SDL_sysvideo.h" +#include "../../core/linux/SDL_dbus.h" +#include "../../core/linux/SDL_ime.h" + struct xkb_context; struct SDL_WaylandInput; @@ -47,23 +42,34 @@ struct qt_windowmanager; #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ typedef struct { + struct wl_cursor_theme *theme; + int size; +} SDL_WaylandCursorTheme; + +typedef struct { + SDL_bool initializing; struct wl_display *display; int display_disconnected; struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shm *shm; - struct wl_cursor_theme *cursor_theme; + SDL_WaylandCursorTheme *cursor_themes; + int num_cursor_themes; struct wl_pointer *pointer; struct { struct xdg_wm_base *xdg; - struct zxdg_shell_v6 *zxdg; - struct wl_shell *wl; +#ifdef HAVE_LIBDECOR_H + struct libdecor *libdecor; +#endif } shell; struct zwp_relative_pointer_manager_v1 *relative_pointer_manager; struct zwp_pointer_constraints_v1 *pointer_constraints; struct wl_data_device_manager *data_device_manager; struct zxdg_decoration_manager_v1 *decoration_manager; - struct org_kde_kwin_server_decoration_manager *kwin_server_decoration_manager; + struct zwp_keyboard_shortcuts_inhibit_manager_v1 *key_inhibitor_manager; + struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager; + struct xdg_activation_v1 *activation_manager; + struct zwp_text_input_manager_v3 *text_input_manager; EGLDisplay edpy; EGLContext context; @@ -84,10 +90,27 @@ typedef struct { } SDL_VideoData; typedef struct { + SDL_VideoData *videodata; struct wl_output *output; + uint32_t registry_id; float scale_factor; + int x, y, width, height, refresh, transform; + SDL_DisplayOrientation orientation; + int physical_width, physical_height; + float ddpi, hdpi, vdpi; + int index; + SDL_VideoDisplay placeholder; + SDL_bool done; } SDL_WaylandOutputData; +/* Needed here to get wl_surface declaration, fixes GitHub#4594 */ +#include "SDL_waylanddyn.h" + +extern void SDL_WAYLAND_register_surface(struct wl_surface *surface); +extern void SDL_WAYLAND_register_output(struct wl_output *output); +extern SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface); +extern SDL_bool SDL_WAYLAND_own_output(struct wl_output *output); + #endif /* SDL_waylandvideo_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.c index a67058fef..eb4435131 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.h index 224fa07da..c2b4c4f01 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c index 787c61494..635546af4 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL +#if SDL_VIDEO_DRIVER_WAYLAND #include "../SDL_sysvideo.h" #include "../../events/SDL_windowevents_c.h" @@ -30,235 +30,155 @@ #include "SDL_waylandwindow.h" #include "SDL_waylandvideo.h" #include "SDL_waylandtouch.h" -#include "SDL_waylanddyn.h" #include "SDL_hints.h" #include "xdg-shell-client-protocol.h" -#include "xdg-shell-unstable-v6-client-protocol.h" #include "xdg-decoration-unstable-v1-client-protocol.h" -#include "org-kde-kwin-server-decoration-manager-client-protocol.h" +#include "idle-inhibit-unstable-v1-client-protocol.h" +#include "xdg-activation-v1-client-protocol.h" -static float get_window_scale_factor(SDL_Window *window) { - return ((SDL_WindowData*)window->driverdata)->scale_factor; -} - -/* On modern desktops, we probably will use the xdg-shell protocol instead - of wl_shell, but wl_shell might be useful on older Wayland installs that - don't have the newer protocol, or embedded things that don't have a full - window manager. */ +#ifdef HAVE_LIBDECOR_H +#include +#endif static void -handle_ping_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface, - uint32_t serial) +SetMinMaxDimensions(SDL_Window *window, SDL_bool commit) { - wl_shell_surface_pong(shell_surface, serial); -} + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = wind->waylandData; + int min_width, min_height, max_width, max_height; -static void -handle_configure_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface, - uint32_t edges, int32_t width, int32_t height) -{ - SDL_WindowData *wind = (SDL_WindowData *)data; - SDL_Window *window = wind->sdlwindow; - - /* wl_shell_surface spec states that this is a suggestion. - Ignore if less than or greater than max/min size. */ - - if (width == 0 || height == 0) { - return; - } - - if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { - if ((window->flags & SDL_WINDOW_RESIZABLE)) { - if (window->max_w > 0) { - width = SDL_min(width, window->max_w); - } - width = SDL_max(width, window->min_w); - - if (window->max_h > 0) { - height = SDL_min(height, window->max_h); - } - height = SDL_max(height, window->min_h); - } else { - return; - } - } - - wind->resize.width = width; - wind->resize.height = height; - wind->resize.pending = SDL_TRUE; - - if (!(window->flags & SDL_WINDOW_OPENGL)) { - Wayland_HandlePendingResize(window); /* OpenGL windows handle this in SwapWindow */ - } -} - -static void -handle_popup_done_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface) -{ -} - -static const struct wl_shell_surface_listener shell_surface_listener_wl = { - handle_ping_wl_shell_surface, - handle_configure_wl_shell_surface, - handle_popup_done_wl_shell_surface -}; - - - - -static void -handle_configure_zxdg_shell_surface(void *data, struct zxdg_surface_v6 *zxdg, uint32_t serial) -{ - SDL_WindowData *wind = (SDL_WindowData *)data; - SDL_Window *window = wind->sdlwindow; - struct wl_region *region; - - if (!wind->shell_surface.zxdg.initial_configure_seen) { - window->w = 0; - window->h = 0; - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, wind->resize.width, wind->resize.height); - window->w = wind->resize.width; - window->h = wind->resize.height; - - wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window)); - if (wind->egl_window) { - WAYLAND_wl_egl_window_resize(wind->egl_window, window->w * get_window_scale_factor(window), window->h * get_window_scale_factor(window), 0, 0); - } - - zxdg_surface_v6_ack_configure(zxdg, serial); - - region = wl_compositor_create_region(wind->waylandData->compositor); - wl_region_add(region, 0, 0, window->w, window->h); - wl_surface_set_opaque_region(wind->surface, region); - wl_region_destroy(region); - - wind->shell_surface.zxdg.initial_configure_seen = SDL_TRUE; + if (window->flags & SDL_WINDOW_FULLSCREEN) { + min_width = 0; + min_height = 0; + max_width = 0; + max_height = 0; + } else if (window->flags & SDL_WINDOW_RESIZABLE) { + min_width = window->min_w; + min_height = window->min_h; + max_width = window->max_w; + max_height = window->max_h; } else { - wind->resize.pending = SDL_TRUE; - wind->resize.configure = SDL_TRUE; - wind->resize.serial = serial; - if (!(window->flags & SDL_WINDOW_OPENGL)) { - Wayland_HandlePendingResize(window); /* OpenGL windows handle this in SwapWindow */ + min_width = window->windowed.w; + min_height = window->windowed.h; + max_width = window->windowed.w; + max_height = window->windowed.h; + } + +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_min_content_size(wind->shell_surface.libdecor.frame, + min_width, + min_height); + libdecor_frame_set_max_content_size(wind->shell_surface.libdecor.frame, + max_width, + max_height); + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_min_size(wind->shell_surface.xdg.roleobj.toplevel, + min_width, + min_height); + xdg_toplevel_set_max_size(wind->shell_surface.xdg.roleobj.toplevel, + max_width, + max_height); + if (commit) { + wl_surface_commit(wind->surface); } } } -static const struct zxdg_surface_v6_listener shell_surface_listener_zxdg = { - handle_configure_zxdg_shell_surface -}; - - static void -handle_configure_zxdg_toplevel(void *data, - struct zxdg_toplevel_v6 *zxdg_toplevel_v6, - int32_t width, - int32_t height, - struct wl_array *states) +SetFullscreen(SDL_Window *window, struct wl_output *output, SDL_bool commit) { - SDL_WindowData *wind = (SDL_WindowData *)data; - SDL_Window *window = wind->sdlwindow; + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = wind->waylandData; - enum zxdg_toplevel_v6_state *state; - SDL_bool fullscreen = SDL_FALSE; - wl_array_for_each(state, states) { - if (*state == ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN) { - fullscreen = SDL_TRUE; + /* The desktop may try to enforce min/max sizes here, so turn them off for + * fullscreen and on (if applicable) for windowed + */ + SetMinMaxDimensions(window, SDL_FALSE); + +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ } - } - - if (!fullscreen) { - if (width == 0 || height == 0) { - width = window->windowed.w; - height = window->windowed.h; - } - - /* zxdg_toplevel spec states that this is a suggestion. - Ignore if less than or greater than max/min size. */ - - if ((window->flags & SDL_WINDOW_RESIZABLE)) { - if (window->max_w > 0) { - width = SDL_min(width, window->max_w); + if (output) { + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + /* ensure that window is resizable before going into fullscreen */ + libdecor_frame_set_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + wl_surface_commit(wind->surface); } - width = SDL_max(width, window->min_w); - - if (window->max_h > 0) { - height = SDL_min(height, window->max_h); - } - height = SDL_max(height, window->min_h); + libdecor_frame_set_fullscreen(wind->shell_surface.libdecor.frame, output); } else { - wind->resize.width = window->w; - wind->resize.height = window->h; - return; + libdecor_frame_unset_fullscreen(wind->shell_surface.libdecor.frame); + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + /* restore previous RESIZE capability */ + libdecor_frame_unset_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + wl_surface_commit(wind->surface); + } + } + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + if (output) { + xdg_toplevel_set_fullscreen(wind->shell_surface.xdg.roleobj.toplevel, output); + } else { + xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel); + } + if (commit) { + wl_surface_commit(wind->surface); } } - - if (width == 0 || height == 0) { - wind->resize.width = window->w; - wind->resize.height = window->h; - return; - } - - wind->resize.width = width; - wind->resize.height = height; } +static const struct wl_callback_listener surface_frame_listener; + static void -handle_close_zxdg_toplevel(void *data, struct zxdg_toplevel_v6 *zxdg_toplevel_v6) +handle_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) { - SDL_WindowData *window = (SDL_WindowData *)data; - SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); + SDL_WindowData *wind = (SDL_WindowData *) data; + SDL_AtomicSet(&wind->swap_interval_ready, 1); /* mark window as ready to present again. */ + + /* reset this callback to fire again once a new frame was presented and compositor wants the next one. */ + wind->frame_callback = wl_surface_frame(wind->frame_surface_wrapper); + wl_callback_destroy(cb); + wl_callback_add_listener(wind->frame_callback, &surface_frame_listener, data); } -static const struct zxdg_toplevel_v6_listener toplevel_listener_zxdg = { - handle_configure_zxdg_toplevel, - handle_close_zxdg_toplevel +static const struct wl_callback_listener surface_frame_listener = { + handle_surface_frame_done }; +static void Wayland_HandleResize(SDL_Window *window, int width, int height, float scale); static void handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial) { SDL_WindowData *wind = (SDL_WindowData *)data; SDL_Window *window = wind->sdlwindow; - struct wl_region *region; - if (!wind->shell_surface.xdg.initial_configure_seen) { - window->w = 0; - window->h = 0; - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, wind->resize.width, wind->resize.height); - window->w = wind->resize.width; - window->h = wind->resize.height; + Wayland_HandleResize(window, window->w, window->h, wind->scale_factor); + xdg_surface_ack_configure(xdg, serial); - wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window)); - if (wind->egl_window) { - WAYLAND_wl_egl_window_resize(wind->egl_window, window->w * get_window_scale_factor(window), window->h * get_window_scale_factor(window), 0, 0); - } - - xdg_surface_ack_configure(xdg, serial); - - region = wl_compositor_create_region(wind->waylandData->compositor); - wl_region_add(region, 0, 0, window->w, window->h); - wl_surface_set_opaque_region(wind->surface, region); - wl_region_destroy(region); - - wind->shell_surface.xdg.initial_configure_seen = SDL_TRUE; - } else { - wind->resize.pending = SDL_TRUE; - wind->resize.configure = SDL_TRUE; - wind->resize.serial = serial; - if (!(window->flags & SDL_WINDOW_OPENGL)) { - Wayland_HandlePendingResize(window); /* OpenGL windows handle this in SwapWindow */ - } - } + wind->shell_surface.xdg.initial_configure_seen = SDL_TRUE; } static const struct xdg_surface_listener shell_surface_listener_xdg = { handle_configure_xdg_shell_surface }; - static void handle_configure_xdg_toplevel(void *data, struct xdg_toplevel *xdg_toplevel, @@ -268,19 +188,68 @@ handle_configure_xdg_toplevel(void *data, { SDL_WindowData *wind = (SDL_WindowData *)data; SDL_Window *window = wind->sdlwindow; + SDL_WaylandOutputData *driverdata; enum xdg_toplevel_state *state; SDL_bool fullscreen = SDL_FALSE; + SDL_bool maximized = SDL_FALSE; + SDL_bool floating = SDL_TRUE; wl_array_for_each(state, states) { - if (*state == XDG_TOPLEVEL_STATE_FULLSCREEN) { + switch (*state) { + case XDG_TOPLEVEL_STATE_FULLSCREEN: fullscreen = SDL_TRUE; + floating = SDL_FALSE; + break; + case XDG_TOPLEVEL_STATE_MAXIMIZED: + maximized = SDL_TRUE; + floating = SDL_FALSE; + break; + case XDG_TOPLEVEL_STATE_TILED_LEFT: + case XDG_TOPLEVEL_STATE_TILED_RIGHT: + case XDG_TOPLEVEL_STATE_TILED_TOP: + case XDG_TOPLEVEL_STATE_TILED_BOTTOM: + floating = SDL_FALSE; + break; + default: + break; } - } + } + + driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata; if (!fullscreen) { + if (window->flags & SDL_WINDOW_FULLSCREEN) { + /* We might need to re-enter fullscreen after being restored from minimized */ + SetFullscreen(window, driverdata->output, SDL_FALSE); + + /* Foolishly do what the compositor says here. If it's wrong, don't + * blame us, we were explicitly instructed to do this. + * + * UPDATE: Nope, we can't actually do that, the compositor may give + * us a completely stateless, sizeless configure, with which we have + * to enforce our own state anyway. + */ + if (width != 0 && height != 0 && (window->w != width || window->h != height)) { + window->w = width; + window->h = height; + wind->needs_resize_event = SDL_TRUE; + } + + /* This part is good though. */ + if ((window->flags & SDL_WINDOW_ALLOW_HIGHDPI) && wind->scale_factor != driverdata->scale_factor) { + wind->scale_factor = driverdata->scale_factor; + wind->needs_resize_event = SDL_TRUE; + } + + return; + } + if (width == 0 || height == 0) { - width = window->windowed.w; - height = window->windowed.h; + /* This usually happens when we're being restored from a + * non-floating state, so use the cached floating size here. + */ + width = wind->floating_width; + height = wind->floating_height; } /* xdg_toplevel spec states that this is a suggestion. @@ -296,21 +265,56 @@ handle_configure_xdg_toplevel(void *data, height = SDL_min(height, window->max_h); } height = SDL_max(height, window->min_h); - } else { - wind->resize.width = window->w; - wind->resize.height = window->h; - return; + } else if (floating) { + /* If we're a fixed-size window, we know our size for sure. + * Always assume the configure is wrong. + */ + width = window->windowed.w; + height = window->windowed.h; + } + + /* Always send a maximized/restore event; if the event is redundant it will + * automatically be discarded (see src/events/SDL_windowevents.c) + * + * No, we do not get minimize events from xdg-shell. + */ + SDL_SendWindowEvent(window, + maximized ? + SDL_WINDOWEVENT_MAXIMIZED : + SDL_WINDOWEVENT_RESTORED, + 0, 0); + + /* Store current floating dimensions for restoring */ + if (floating) { + wind->floating_width = width; + wind->floating_height = height; + } + + /* Store this now so the xdg_surface configure knows what to resize to */ + if (window->w != width || window->h != height) { + window->w = width; + window->h = height; + wind->needs_resize_event = SDL_TRUE; + } + } else { + /* For fullscreen, foolishly do what the compositor says. If it's wrong, + * don't blame us, we were explicitly instructed to do this. + * + * UPDATE: Nope, sure enough a compositor sends 0,0. This is a known bug: + * https://bugs.kde.org/show_bug.cgi?id=444962 + */ + if (width != 0 && height != 0 && (window->w != width || window->h != height)) { + window->w = width; + window->h = height; + wind->needs_resize_event = SDL_TRUE; + } + + /* This part is good though. */ + if ((window->flags & SDL_WINDOW_ALLOW_HIGHDPI) && wind->scale_factor != driverdata->scale_factor) { + wind->scale_factor = driverdata->scale_factor; + wind->needs_resize_event = SDL_TRUE; } } - - if (width == 0 || height == 0) { - wind->resize.width = window->w; - wind->resize.height = window->h; - return; - } - - wind->resize.width = width; - wind->resize.height = height; } static void @@ -325,8 +329,155 @@ static const struct xdg_toplevel_listener toplevel_listener_xdg = { handle_close_xdg_toplevel }; +#ifdef HAVE_LIBDECOR_H +static void +decoration_frame_configure(struct libdecor_frame *frame, + struct libdecor_configuration *configuration, + void *user_data) +{ + SDL_WindowData *wind = (SDL_WindowData *)user_data; + SDL_Window *window = wind->sdlwindow; + SDL_WaylandOutputData *driverdata; + struct libdecor_state *state; + enum libdecor_window_state window_state; + int width, height; + float scale_factor = wind->scale_factor; + SDL_bool focused = SDL_FALSE; + SDL_bool fullscreen = SDL_FALSE; + SDL_bool maximized = SDL_FALSE; + SDL_bool tiled = SDL_FALSE; + SDL_bool floating; + + static const enum libdecor_window_state tiled_states = ( + LIBDECOR_WINDOW_STATE_TILED_LEFT | LIBDECOR_WINDOW_STATE_TILED_RIGHT | + LIBDECOR_WINDOW_STATE_TILED_TOP | LIBDECOR_WINDOW_STATE_TILED_BOTTOM + ); + + /* Window State */ + if (libdecor_configuration_get_window_state(configuration, &window_state)) { + fullscreen = (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN) != 0; + maximized = (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) != 0; + focused = (window_state & LIBDECOR_WINDOW_STATE_ACTIVE) != 0; + tiled = (window_state & tiled_states) != 0; + } + floating = !(fullscreen || maximized || tiled); + + driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata; + + if (!fullscreen) { + if (window->flags & SDL_WINDOW_FULLSCREEN) { + /* We might need to re-enter fullscreen after being restored from minimized */ + SetFullscreen(window, driverdata->output, SDL_FALSE); + fullscreen = SDL_TRUE; + floating = SDL_FALSE; + } + + /* Always send a maximized/restore event; if the event is redundant it will + * automatically be discarded (see src/events/SDL_windowevents.c) + * + * No, we do not get minimize events from libdecor. + */ + if (!fullscreen) { + SDL_SendWindowEvent(window, + maximized ? + SDL_WINDOWEVENT_MAXIMIZED : + SDL_WINDOWEVENT_RESTORED, + 0, 0); + } + } + + /* Similar to maximized/restore events above, send focus events too! */ + SDL_SendWindowEvent(window, + focused ? + SDL_WINDOWEVENT_FOCUS_GAINED : + SDL_WINDOWEVENT_FOCUS_LOST, + 0, 0); + + /* For fullscreen or fixed-size windows we know our size. + * Always assume the configure is wrong. + */ + if (fullscreen) { + /* FIXME: We have been explicitly told to respect the fullscreen size + * parameters here, even though they are known to be wrong on GNOME at + * bare minimum. If this is wrong, don't blame us, we were explicitly + * told to do this. + */ + if (!libdecor_configuration_get_content_size(configuration, frame, + &width, &height)) { + width = window->w; + height = window->h; + } + + /* This part is good though. */ + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + scale_factor = driverdata->scale_factor; + } + } else if (!(window->flags & SDL_WINDOW_RESIZABLE) || (floating && wind->floating_resize_pending)) { + width = window->windowed.w; + height = window->windowed.h; + wind->floating_resize_pending = SDL_FALSE; + } else { + /* This will never set 0 for width/height unless the function returns false */ + if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) { + if (floating) { + /* This usually happens when we're being restored from a + * non-floating state, so use the cached floating size here. + */ + width = wind->floating_width; + height = wind->floating_height; + } else { + width = window->w; + height = window->h; + } + } + } + + /* Store current floating dimensions for restoring */ + if (floating) { + wind->floating_width = width; + wind->floating_height = height; + } + + /* Do the resize on the SDL side (this will set window->w/h)... */ + Wayland_HandleResize(window, width, height, scale_factor); + wind->shell_surface.libdecor.initial_configure_seen = SDL_TRUE; + + /* ... then commit the changes on the libdecor side. */ + state = libdecor_state_new(width, height); + libdecor_frame_commit(frame, state, configuration); + libdecor_state_free(state); + + /* Update the resize capability. Since this will change the capabilities and + * commit a new frame state with the last known content dimension, this has + * to be called after the new state has been commited and the new content + * dimensions were updated. + */ + Wayland_SetWindowResizable(SDL_GetVideoDevice(), window, + window->flags & SDL_WINDOW_RESIZABLE); +} + +static void +decoration_frame_close(struct libdecor_frame *frame, void *user_data) +{ + SDL_SendWindowEvent(((SDL_WindowData *)user_data)->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); +} + +static void +decoration_frame_commit(struct libdecor_frame *frame, void *user_data) +{ + SDL_WindowData *wind = user_data; + + SDL_SendWindowEvent(wind->sdlwindow, SDL_WINDOWEVENT_EXPOSED, 0, 0); +} + +static struct libdecor_frame_interface libdecor_frame_interface = { + decoration_frame_configure, + decoration_frame_close, + decoration_frame_commit, +}; +#endif #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH static void @@ -357,63 +508,100 @@ static const struct qt_extended_surface_listener extended_surface_listener = { #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ static void -update_scale_factor(SDL_WindowData *window) { - float old_factor = window->scale_factor, new_factor = 0.0; - int i; +update_scale_factor(SDL_WindowData *window) +{ + float old_factor = window->scale_factor; + float new_factor; + int i; - if (!(window->sdlwindow->flags & SDL_WINDOW_ALLOW_HIGHDPI)) { - return; - } + if (!(window->sdlwindow->flags & SDL_WINDOW_ALLOW_HIGHDPI)) { + /* Scale will always be 1, just ignore this */ + return; + } - if (!window->num_outputs) { - new_factor = old_factor; - } + if (FULLSCREEN_VISIBLE(window->sdlwindow)) { + /* For fullscreen, use the active display's scale factor */ + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window->sdlwindow); + SDL_WaylandOutputData* driverdata = display->driverdata; + new_factor = driverdata->scale_factor; + } else if (window->num_outputs == 0) { + /* No monitor (somehow)? Just fall back. */ + new_factor = old_factor; + } else { + /* Check every display's factor, use the highest */ + new_factor = 0.0f; + for (i = 0; i < window->num_outputs; i++) { + SDL_WaylandOutputData* driverdata = window->outputs[i]; + if (driverdata->scale_factor > new_factor) { + new_factor = driverdata->scale_factor; + } + } + } - if (FULLSCREEN_VISIBLE(window->sdlwindow) && window->sdlwindow->fullscreen_mode.driverdata) { - new_factor = ((SDL_WaylandOutputData*)(wl_output_get_user_data(window->sdlwindow->fullscreen_mode.driverdata)))->scale_factor; - } + if (new_factor != old_factor) { + Wayland_HandleResize(window->sdlwindow, window->sdlwindow->w, window->sdlwindow->h, new_factor); + } +} - for (i = 0; i < window->num_outputs; i++) { - float factor = ((SDL_WaylandOutputData*)(wl_output_get_user_data(window->outputs[i])))->scale_factor; - if (factor > new_factor) { - new_factor = factor; - } - } - - if (new_factor != old_factor) { - /* force the resize event to trigger, as the logical size didn't change */ - window->resize.width = window->sdlwindow->w; - window->resize.height = window->sdlwindow->h; - window->resize.scale_factor = new_factor; - window->resize.pending = SDL_TRUE; - if (!(window->sdlwindow->flags & SDL_WINDOW_OPENGL)) { - Wayland_HandlePendingResize(window->sdlwindow); /* OpenGL windows handle this in SwapWindow */ - } - } +/* While we can't get window position from the compositor, we do at least know + * what monitor we're on, so let's send move events that put the window at the + * center of the whatever display the wl_surface_listener events give us. + */ +static void +Wayland_move_window(SDL_Window *window, + SDL_WaylandOutputData *driverdata) +{ + int i, numdisplays = SDL_GetNumVideoDisplays(); + for (i = 0; i < numdisplays; i += 1) { + if (SDL_GetDisplay(i)->driverdata == driverdata) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, + SDL_WINDOWPOS_CENTERED_DISPLAY(i), + SDL_WINDOWPOS_CENTERED_DISPLAY(i)); + break; + } + } } static void handle_surface_enter(void *data, struct wl_surface *surface, - struct wl_output *output) { + struct wl_output *output) +{ SDL_WindowData *window = data; + SDL_WaylandOutputData *driverdata = wl_output_get_user_data(output); - window->outputs = SDL_realloc(window->outputs, (window->num_outputs + 1) * sizeof *window->outputs); - window->outputs[window->num_outputs++] = output; + if (!SDL_WAYLAND_own_output(output) || !SDL_WAYLAND_own_surface(surface)) { + return; + } + + window->outputs = SDL_realloc(window->outputs, + sizeof(SDL_WaylandOutputData*) * (window->num_outputs + 1)); + window->outputs[window->num_outputs++] = driverdata; update_scale_factor(window); + + Wayland_move_window(window->sdlwindow, driverdata); } static void handle_surface_leave(void *data, struct wl_surface *surface, - struct wl_output *output) { + struct wl_output *output) +{ SDL_WindowData *window = data; - int i; + int i, send_move_event = 0; + SDL_WaylandOutputData *driverdata = wl_output_get_user_data(output); + + if (!SDL_WAYLAND_own_output(output) || !SDL_WAYLAND_own_surface(surface)) { + return; + } for (i = 0; i < window->num_outputs; i++) { - if (window->outputs[i] == output) { /* remove this one */ + if (window->outputs[i] == driverdata) { /* remove this one */ if (i == (window->num_outputs-1)) { window->outputs[i] = NULL; + send_move_event = 1; } else { - SDL_memmove(&window->outputs[i], &window->outputs[i+1], sizeof (output) * ((window->num_outputs - i) - 1)); + SDL_memmove(&window->outputs[i], + &window->outputs[i + 1], + sizeof(SDL_WaylandOutputData*) * ((window->num_outputs - i) - 1)); } window->num_outputs--; i--; @@ -421,8 +609,11 @@ handle_surface_leave(void *data, struct wl_surface *surface, } if (window->num_outputs == 0) { - SDL_free(window->outputs); - window->outputs = NULL; + SDL_free(window->outputs); + window->outputs = NULL; + } else if (send_move_event) { + Wayland_move_window(window->sdlwindow, + window->outputs[window->num_outputs - 1]); } update_scale_factor(window); @@ -436,10 +627,11 @@ static const struct wl_surface_listener surface_listener = { SDL_bool Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) { + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - const Uint32 version = ((((Uint32) info->version.major) * 1000000) + - (((Uint32) info->version.minor) * 10000) + - (((Uint32) info->version.patch))); + const Uint32 version = SDL_VERSIONNUM((Uint32)info->version.major, + (Uint32)info->version.minor, + (Uint32)info->version.patch); /* Before 2.0.6, it was possible to build an SDL with Wayland support (SDL_SysWMinfo will be large enough to hold Wayland info), but build @@ -451,7 +643,7 @@ Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) just return an error for older apps using this function. Those apps will need to be recompiled against newer headers or not use Wayland, maybe by forcing SDL_VIDEODRIVER=x11. */ - if (version < 2000006) { + if (version < SDL_VERSIONNUM(2, 0, 6)) { info->subsystem = SDL_SYSWM_UNKNOWN; SDL_SetError("Version must be 2.0.6 or newer"); return SDL_FALSE; @@ -459,7 +651,34 @@ Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) info->info.wl.display = data->waylandData->display; info->info.wl.surface = data->surface; - info->info.wl.shell_surface = data->shell_surface.wl; + + if (version >= SDL_VERSIONNUM(2, 0, 15)) { + info->info.wl.egl_window = data->egl_window; + +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor && data->shell_surface.libdecor.frame != NULL) { + info->info.wl.xdg_surface = libdecor_frame_get_xdg_surface(data->shell_surface.libdecor.frame); + if (version >= SDL_VERSIONNUM(2, 0, 17)) { + info->info.wl.xdg_toplevel = libdecor_frame_get_xdg_toplevel(data->shell_surface.libdecor.frame); + } + } else +#endif + if (viddata->shell.xdg && data->shell_surface.xdg.surface != NULL) { + info->info.wl.xdg_surface = data->shell_surface.xdg.surface; + if (version >= SDL_VERSIONNUM(2, 0, 17)) { + info->info.wl.xdg_toplevel = data->shell_surface.xdg.roleobj.toplevel; + } + } else { + info->info.wl.xdg_surface = NULL; + if (version >= SDL_VERSIONNUM(2, 0, 17)) { + info->info.wl.xdg_toplevel = NULL; + } + } + } + + /* Deprecated in 2.0.16 */ + info->info.wl.shell_surface = NULL; + info->subsystem = SDL_SYSWM_WAYLAND; return SDL_TRUE; @@ -471,41 +690,286 @@ Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) return 0; /* just succeed, the real work is done elsewhere. */ } -static void -SetFullscreen(_THIS, SDL_Window * window, struct wl_output *output) +int +Wayland_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_window) { - const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata; - SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + SDL_WindowData *modal_data = modal_window->driverdata; + SDL_WindowData *parent_data = parent_window->driverdata; +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor) { + if (modal_data->shell_surface.libdecor.frame == NULL) { + return SDL_SetError("Modal window was hidden"); + } + if (parent_data->shell_surface.libdecor.frame == NULL) { + return SDL_SetError("Parent window was hidden"); + } + libdecor_frame_set_parent(modal_data->shell_surface.libdecor.frame, + parent_data->shell_surface.libdecor.frame); + } else +#endif if (viddata->shell.xdg) { - if (output) { - xdg_toplevel_set_fullscreen(wind->shell_surface.xdg.roleobj.toplevel, output); - } else { - xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel); + if (modal_data->shell_surface.xdg.roleobj.toplevel == NULL) { + return SDL_SetError("Modal window was hidden"); } - } else if (viddata->shell.zxdg) { - if (output) { - zxdg_toplevel_v6_set_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel, output); - } else { - zxdg_toplevel_v6_unset_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel); + if (parent_data->shell_surface.xdg.roleobj.toplevel == NULL) { + return SDL_SetError("Parent window was hidden"); } + xdg_toplevel_set_parent(modal_data->shell_surface.xdg.roleobj.toplevel, + parent_data->shell_surface.xdg.roleobj.toplevel); } else { - if (output) { - wl_shell_surface_set_fullscreen(wind->shell_surface.wl, - WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, - 0, output); - } else { - wl_shell_surface_set_toplevel(wind->shell_surface.wl); - } + return SDL_Unsupported(); } - WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); + WAYLAND_wl_display_flush(viddata->display); + return 0; } void Wayland_ShowWindow(_THIS, SDL_Window *window) { - struct wl_output *output = (struct wl_output *) window->fullscreen_mode.driverdata; - SetFullscreen(_this, window, (window->flags & SDL_WINDOW_FULLSCREEN) ? output : NULL); + SDL_VideoData *c = _this->driverdata; + SDL_WindowData *data = window->driverdata; + + /* Create the shell surface and map the toplevel */ +#ifdef HAVE_LIBDECOR_H + if (c->shell.libdecor) { + data->shell_surface.libdecor.frame = libdecor_decorate(c->shell.libdecor, + data->surface, + &libdecor_frame_interface, + data); + if (data->shell_surface.libdecor.frame == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Failed to create libdecor frame!"); + } else { + libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, c->classname); + libdecor_frame_map(data->shell_surface.libdecor.frame); + } + } else +#endif + if (c->shell.xdg) { + data->shell_surface.xdg.surface = xdg_wm_base_get_xdg_surface(c->shell.xdg, data->surface); + xdg_surface_set_user_data(data->shell_surface.xdg.surface, data); + xdg_surface_add_listener(data->shell_surface.xdg.surface, &shell_surface_listener_xdg, data); + + /* !!! FIXME: add popup role */ + data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface); + xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname); + xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data); + } + + /* Restore state that was set prior to this call */ + Wayland_SetWindowTitle(_this, window); + if (window->flags & SDL_WINDOW_MAXIMIZED) { + Wayland_MaximizeWindow(_this, window); + } + if (window->flags & SDL_WINDOW_MINIMIZED) { + Wayland_MinimizeWindow(_this, window); + } + + /* We have to wait until the surface gets a "configure" event, or use of + * this surface will fail. This is a new rule for xdg_shell. + */ +#ifdef HAVE_LIBDECOR_H + if (c->shell.libdecor) { + if (data->shell_surface.libdecor.frame) { + while (!data->shell_surface.libdecor.initial_configure_seen) { + WAYLAND_wl_display_flush(c->display); + WAYLAND_wl_display_dispatch(c->display); + } + } + } else +#endif + if (c->shell.xdg) { + /* Unlike libdecor we need to call this explicitly to prevent a deadlock. + * libdecor will call this as part of their configure event! + * -flibit + */ + SDL_WaylandOutputData *odata = SDL_GetDisplayForWindow(window)->driverdata; + SetFullscreen(window, (window->flags & SDL_WINDOW_FULLSCREEN) ? odata->output : NULL, SDL_TRUE); + if (data->shell_surface.xdg.surface) { + while (!data->shell_surface.xdg.initial_configure_seen) { + WAYLAND_wl_display_flush(c->display); + WAYLAND_wl_display_dispatch(c->display); + } + } + + /* Create the window decorations */ + if (data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) { + data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel); + } + } else { + /* Nothing to see here, just commit. */ + wl_surface_commit(data->surface); + } + + /* Unlike the rest of window state we have to set this _after_ flushing the + * display, because we need to create the decorations before possibly hiding + * them immediately afterward. + */ +#ifdef HAVE_LIBDECOR_H + if (c->shell.libdecor) { + /* ... but don't call it redundantly for libdecor, the decorator + * may not interpret a redundant call nicely and cause weird stuff to happen + */ + if (window->flags & SDL_WINDOW_BORDERLESS) { + Wayland_SetWindowBordered(_this, window, SDL_FALSE); + } + } else +#endif + { + Wayland_SetWindowBordered(_this, window, !(window->flags & SDL_WINDOW_BORDERLESS)); + } + + /* We're finally done putting the window together, raise if possible */ + if (c->activation_manager) { + /* Note that we don't check for empty strings, as that is still + * considered a valid activation token! + */ + const char *activation_token = SDL_getenv("XDG_ACTIVATION_TOKEN"); + if (activation_token) { + xdg_activation_v1_activate(c->activation_manager, + activation_token, + data->surface); + + /* Clear this variable, per the protocol's request */ + unsetenv("XDG_ACTIVATION_TOKEN"); + } + } +} + +void Wayland_HideWindow(_THIS, SDL_Window *window) +{ + SDL_VideoData *data = _this->driverdata; + SDL_WindowData *wind = window->driverdata; + + if (wind->server_decoration) { + zxdg_toplevel_decoration_v1_destroy(wind->server_decoration); + wind->server_decoration = NULL; + } + +#ifdef HAVE_LIBDECOR_H + if (data->shell.libdecor) { + if (wind->shell_surface.libdecor.frame) { + libdecor_frame_unref(wind->shell_surface.libdecor.frame); + wind->shell_surface.libdecor.frame = NULL; + } + } else +#endif + if (data->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel) { + xdg_toplevel_destroy(wind->shell_surface.xdg.roleobj.toplevel); + wind->shell_surface.xdg.roleobj.toplevel = NULL; + } + if (wind->shell_surface.xdg.surface) { + xdg_surface_destroy(wind->shell_surface.xdg.surface); + wind->shell_surface.xdg.surface = NULL; + } + } + + /* Be sure to detach after this is done, otherwise ShowWindow crashes! */ + wl_surface_attach(wind->surface, NULL, 0, 0); + wl_surface_commit(wind->surface); +} + +static void +handle_xdg_activation_done(void *data, + struct xdg_activation_token_v1 *xdg_activation_token_v1, + const char *token) +{ + SDL_WindowData *window = data; + if (xdg_activation_token_v1 == window->activation_token) { + xdg_activation_v1_activate(window->waylandData->activation_manager, + token, + window->surface); + xdg_activation_token_v1_destroy(window->activation_token); + window->activation_token = NULL; + } +} + +static const struct xdg_activation_token_v1_listener activation_listener_xdg = { + handle_xdg_activation_done +}; + +/* The xdg-activation protocol considers "activation" to be one of two things: + * + * 1: Raising a window to the top and flashing the titlebar + * 2: Flashing the titlebar while keeping the window where it is + * + * As you might expect from Wayland, the general policy is to go with #2 unless + * the client can prove to the compositor beyond a reasonable doubt that raising + * the window will not be malicuous behavior. + * + * For SDL this means RaiseWindow and FlashWindow both use the same protocol, + * but in different ways: RaiseWindow will provide as _much_ information as + * possible while FlashWindow will provide as _little_ information as possible, + * to nudge the compositor into doing what we want. + * + * This isn't _strictly_ what the protocol says will happen, but this is what + * current implementations are doing (as of writing, YMMV in the far distant + * future). + * + * -flibit + */ +static void +Wayland_activate_window(SDL_VideoData *data, SDL_WindowData *wind, + struct wl_surface *surface, + uint32_t serial, struct wl_seat *seat) +{ + if (data->activation_manager) { + if (wind->activation_token != NULL) { + /* We're about to overwrite this with a new request */ + xdg_activation_token_v1_destroy(wind->activation_token); + } + + wind->activation_token = xdg_activation_v1_get_activation_token(data->activation_manager); + xdg_activation_token_v1_add_listener(wind->activation_token, + &activation_listener_xdg, + wind); + + /* Note that we are not setting the app_id or serial here. + * + * Hypothetically we could set the app_id from data->classname, but + * that part of the API is for _external_ programs, not ourselves. + * + * -flibit + */ + if (surface != NULL) { + xdg_activation_token_v1_set_surface(wind->activation_token, surface); + } + if (seat != NULL) { + xdg_activation_token_v1_set_serial(wind->activation_token, serial, seat); + } + xdg_activation_token_v1_commit(wind->activation_token); + } +} + +void +Wayland_RaiseWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + + /* FIXME: This Raise event is arbitrary and doesn't come from an event, so + * it's actually very likely that this token will be ignored! Maybe add + * support for passing serials (and the associated seat) so this can have + * a better chance of actually raising the window. + * -flibit + */ + Wayland_activate_window(_this->driverdata, + wind, + wind->surface, + 0, + NULL); +} + +int +Wayland_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation) +{ + Wayland_activate_window(_this->driverdata, + window->driverdata, + NULL, + 0, + NULL); + return 0; } #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH @@ -514,49 +978,67 @@ QtExtendedSurface_OnHintChanged(void *userdata, const char *name, const char *oldValue, const char *newValue) { struct qt_extended_surface *qt_extended_surface = userdata; + int i; + + static struct { + const char *name; + int32_t value; + } orientations[] = { + { "portrait", QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION }, + { "landscape", QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION }, + { "inverted-portrait", QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION }, + { "inverted-landscape", QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION } + }; if (name == NULL) { return; } - if (strcmp(name, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION) == 0) { + if (SDL_strcmp(name, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION) == 0) { int32_t orientation = QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION; if (newValue != NULL) { - if (strcmp(newValue, "portrait") == 0) { - orientation = QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION; - } else if (strcmp(newValue, "landscape") == 0) { - orientation = QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION; - } else if (strcmp(newValue, "inverted-portrait") == 0) { - orientation = QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION; - } else if (strcmp(newValue, "inverted-landscape") == 0) { - orientation = QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION; + const char *value_attempt = newValue; + while (value_attempt != NULL && *value_attempt != 0) { + const char *value_attempt_end = SDL_strchr(value_attempt, ','); + size_t value_attempt_len = (value_attempt_end != NULL) ? (value_attempt_end - value_attempt) + : SDL_strlen(value_attempt); + + for (i = 0; i < SDL_arraysize(orientations); i += 1) { + if ((value_attempt_len == SDL_strlen(orientations[i].name)) && + (SDL_strncasecmp(orientations[i].name, value_attempt, value_attempt_len) == 0)) { + orientation |= orientations[i].value; + break; + } + } + + value_attempt = (value_attempt_end != NULL) ? (value_attempt_end + 1) : NULL; } } qt_extended_surface_set_content_orientation(qt_extended_surface, orientation); - } else if (strcmp(name, SDL_HINT_QTWAYLAND_WINDOW_FLAGS) == 0) { + } else if (SDL_strcmp(name, SDL_HINT_QTWAYLAND_WINDOW_FLAGS) == 0) { uint32_t flags = 0; if (newValue != NULL) { - char *tmp = strdup(newValue); + char *tmp = SDL_strdup(newValue); char *saveptr = NULL; - char *flag = strtok_r(tmp, " ", &saveptr); + char *flag = SDL_strtokr(tmp, " ", &saveptr); while (flag) { - if (strcmp(flag, "OverridesSystemGestures") == 0) { + if (SDL_strcmp(flag, "OverridesSystemGestures") == 0) { flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES; - } else if (strcmp(flag, "StaysOnTop") == 0) { + } else if (SDL_strcmp(flag, "StaysOnTop") == 0) { flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP; - } else if (strcmp(flag, "BypassWindowManager") == 0) { + } else if (SDL_strcmp(flag, "BypassWindowManager") == 0) { // See https://github.com/qtproject/qtwayland/commit/fb4267103d flags |= 4 /* QT_EXTENDED_SURFACE_WINDOWFLAG_BYPASSWINDOWMANAGER */; } - flag = strtok_r(NULL, " ", &saveptr); + flag = SDL_strtokr(NULL, " ", &saveptr); } - free(tmp); + SDL_free(tmp); } qt_extended_surface_set_window_flags(qt_extended_surface, flags); @@ -579,22 +1061,40 @@ Wayland_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) { struct wl_output *output = ((SDL_WaylandOutputData*) _display->driverdata)->output; - SetFullscreen(_this, window, fullscreen ? output : NULL); + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + SetFullscreen(window, fullscreen ? output : NULL, SDL_TRUE); + + WAYLAND_wl_display_flush(viddata->display); } void Wayland_RestoreWindow(_THIS, SDL_Window * window) { SDL_WindowData *wind = window->driverdata; - const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata; + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + /* Set this flag now even if we never actually maximized, eventually + * ShowWindow will take care of it along with the other window state. + */ + window->flags &= ~SDL_WINDOW_MAXIMIZED; + +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_unset_maximized(wind->shell_surface.libdecor.frame); + } else +#endif + /* Note that xdg-shell does NOT provide a way to unset minimize! */ if (viddata->shell.xdg) { - } else if (viddata->shell.zxdg) { - } else { - wl_shell_surface_set_toplevel(wind->shell_surface.wl); + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_unset_maximized(wind->shell_surface.xdg.roleobj.toplevel); } - WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); + WAYLAND_wl_display_flush( viddata->display ); } void @@ -602,12 +1102,39 @@ Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) { SDL_WindowData *wind = window->driverdata; const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata; +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor) { + if (wind->shell_surface.libdecor.frame) { + libdecor_frame_set_visibility(wind->shell_surface.libdecor.frame, bordered); + } + } else +#endif if ((viddata->decoration_manager) && (wind->server_decoration)) { const enum zxdg_toplevel_decoration_v1_mode mode = bordered ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; zxdg_toplevel_decoration_v1_set_mode(wind->server_decoration, mode); - } else if ((viddata->kwin_server_decoration_manager) && (wind->kwin_server_decoration)) { - const enum org_kde_kwin_server_decoration_manager_mode mode = bordered ? ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER : ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_NONE; - org_kde_kwin_server_decoration_request_mode(wind->kwin_server_decoration, mode); + } +} + +void +Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) +{ +#ifdef HAVE_LIBDECOR_H + SDL_VideoData *data = _this->driverdata; + const SDL_WindowData *wind = window->driverdata; + + if (data->shell.libdecor) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + if (resizable) { + libdecor_frame_set_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + } else { + libdecor_frame_unset_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + } + } else +#endif + { + SetMinMaxDimensions(window, SDL_TRUE); } } @@ -617,26 +1144,99 @@ Wayland_MaximizeWindow(_THIS, SDL_Window * window) SDL_WindowData *wind = window->driverdata; SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; - if (viddata->shell.xdg) { - xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel); - } else if (viddata->shell.zxdg) { - zxdg_toplevel_v6_set_maximized(wind->shell_surface.zxdg.roleobj.toplevel); - } else { - wl_shell_surface_set_maximized(wind->shell_surface.wl, NULL); + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + return; } - WAYLAND_wl_display_flush( viddata->display ); + /* Set this flag now even if we don't actually maximize yet, eventually + * ShowWindow will take care of it along with the other window state. + */ + window->flags |= SDL_WINDOW_MAXIMIZED; + +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_maximized(wind->shell_surface.libdecor.frame); + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel); + } + + WAYLAND_wl_display_flush(viddata->display); } void -Wayland_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +Wayland_MinimizeWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_minimized(wind->shell_surface.libdecor.frame); + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_minimized(wind->shell_surface.xdg.roleobj.toplevel); + } + + WAYLAND_wl_display_flush(viddata->display); +} + +void +Wayland_SetWindowMouseRect(_THIS, SDL_Window *window) { SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - if (grabbed) - Wayland_input_confine_pointer(window, data->input); - else - Wayland_input_unconfine_pointer(data->input); + /* This may look suspiciously like SetWindowGrab, despite SetMouseRect not + * implicitly doing a grab. And you're right! Wayland doesn't let us mess + * around with mouse focus whatsoever, so it just happens to be that the + * work that we can do in these two functions ends up being the same. + * + * Just know that this call lets you confine with a rect, SetWindowGrab + * lets you confine without a rect. + */ + if (SDL_RectEmpty(&window->mouse_rect) && !(window->flags & SDL_WINDOW_MOUSE_GRABBED)) { + Wayland_input_unconfine_pointer(data->input, window); + } else { + Wayland_input_confine_pointer(data->input, window); + } +} + +void +Wayland_SetWindowMouseGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + if (grabbed) { + Wayland_input_confine_pointer(data->input, window); + } else if (SDL_RectEmpty(&window->mouse_rect)) { + Wayland_input_unconfine_pointer(data->input, window); + } +} + +void +Wayland_SetWindowKeyboardGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + if (grabbed) { + Wayland_input_grab_keyboard(window, data->input); + } else { + Wayland_input_ungrab_keyboard(window); + } } int Wayland_CreateWindow(_THIS, SDL_Window *window) @@ -681,33 +1281,29 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) } } - data->resize.pending = SDL_FALSE; - data->resize.width = window->w; - data->resize.height = window->h; - data->resize.scale_factor = data->scale_factor; - data->outputs = NULL; data->num_outputs = 0; + data->floating_width = window->windowed.w; + data->floating_height = window->windowed.h; + data->surface = wl_compositor_create_surface(c->compositor); wl_surface_add_listener(data->surface, &surface_listener, data); - if (c->shell.xdg) { - data->shell_surface.xdg.surface = xdg_wm_base_get_xdg_surface(c->shell.xdg, data->surface); - /* !!! FIXME: add popup role */ - data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface); - xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data); - xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname); - } else if (c->shell.zxdg) { - data->shell_surface.zxdg.surface = zxdg_shell_v6_get_xdg_surface(c->shell.zxdg, data->surface); - /* !!! FIXME: add popup role */ - data->shell_surface.zxdg.roleobj.toplevel = zxdg_surface_v6_get_toplevel(data->shell_surface.zxdg.surface); - zxdg_toplevel_v6_add_listener(data->shell_surface.zxdg.roleobj.toplevel, &toplevel_listener_zxdg, data); - zxdg_toplevel_v6_set_app_id(data->shell_surface.zxdg.roleobj.toplevel, c->classname); - } else { - data->shell_surface.wl = wl_shell_get_shell_surface(c->shell.wl, data->surface); - wl_shell_surface_set_class(data->shell_surface.wl, c->classname); + SDL_WAYLAND_register_surface(data->surface); + + /* Fire a callback when the compositor wants a new frame rendered. + * Right now this only matters for OpenGL; we use this callback to add a + * wait timeout that avoids getting deadlocked by the compositor when the + * window isn't visible. + */ + if (window->flags & SDL_WINDOW_OPENGL) { + data->frame_event_queue = WAYLAND_wl_display_create_queue(data->waylandData->display); + data->frame_surface_wrapper = WAYLAND_wl_proxy_create_wrapper(data->surface); + WAYLAND_wl_proxy_set_queue((struct wl_proxy *)data->frame_surface_wrapper, data->frame_event_queue); + data->frame_callback = wl_surface_frame(data->frame_surface_wrapper); + wl_callback_add_listener(data->frame_callback, &surface_frame_listener, data); } #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH @@ -724,29 +1320,14 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) data->egl_window = WAYLAND_wl_egl_window_create(data->surface, window->w * data->scale_factor, window->h * data->scale_factor); +#if SDL_VIDEO_OPENGL_EGL /* Create the GLES window surface */ data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window); - + if (data->egl_surface == EGL_NO_SURFACE) { return SDL_SetError("failed to create an EGL window surface"); } - } - - if (c->shell.xdg) { - if (data->shell_surface.xdg.surface) { - xdg_surface_set_user_data(data->shell_surface.xdg.surface, data); - xdg_surface_add_listener(data->shell_surface.xdg.surface, &shell_surface_listener_xdg, data); - } - } else if (c->shell.zxdg) { - if (data->shell_surface.zxdg.surface) { - zxdg_surface_v6_set_user_data(data->shell_surface.zxdg.surface, data); - zxdg_surface_v6_add_listener(data->shell_surface.zxdg.surface, &shell_surface_listener_zxdg, data); - } - } else { - if (data->shell_surface.wl) { - wl_shell_surface_set_user_data(data->shell_surface.wl, data); - wl_shell_surface_add_listener(data->shell_surface.wl, &shell_surface_listener_wl, data); - } +#endif } #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH @@ -757,22 +1338,6 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) } #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ - if (c->decoration_manager && c->shell.xdg && data->shell_surface.xdg.surface) { - data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel); - if (data->server_decoration) { - const SDL_bool bordered = (window->flags & SDL_WINDOW_BORDERLESS) == 0; - const enum zxdg_toplevel_decoration_v1_mode mode = bordered ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; - zxdg_toplevel_decoration_v1_set_mode(data->server_decoration, mode); - } - } else if (c->kwin_server_decoration_manager) { - data->kwin_server_decoration = org_kde_kwin_server_decoration_manager_create(c->kwin_server_decoration_manager, data->surface); - if (data->kwin_server_decoration) { - const SDL_bool bordered = (window->flags & SDL_WINDOW_BORDERLESS) == 0; - const enum org_kde_kwin_server_decoration_manager_mode mode = bordered ? ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER : ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_NONE; - org_kde_kwin_server_decoration_request_mode(data->kwin_server_decoration, mode); - } - } - region = wl_compositor_create_region(c->compositor); wl_region_add(region, 0, 0, window->w, window->h); wl_surface_set_opaque_region(data->surface, region); @@ -782,67 +1347,68 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) Wayland_input_lock_pointer(c->input); } - wl_surface_commit(data->surface); + /* Moved this call to ShowWindow: wl_surface_commit(data->surface); */ WAYLAND_wl_display_flush(c->display); - /* we have to wait until the surface gets a "configure" event, or - use of this surface will fail. This is a new rule for xdg_shell. */ - if (c->shell.xdg) { - if (data->shell_surface.xdg.surface) { - while (!data->shell_surface.xdg.initial_configure_seen) { - WAYLAND_wl_display_flush(c->display); - WAYLAND_wl_display_dispatch(c->display); - } - } - } else if (c->shell.zxdg) { - if (data->shell_surface.zxdg.surface) { - while (!data->shell_surface.zxdg.initial_configure_seen) { - WAYLAND_wl_display_flush(c->display); - WAYLAND_wl_display_dispatch(c->display); - } - } - } + /* We may need to create an idle inhibitor for this new window */ + Wayland_SuspendScreenSaver(_this); return 0; } -void -Wayland_HandlePendingResize(SDL_Window *window) +static void +Wayland_HandleResize(SDL_Window *window, int width, int height, float scale) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_VideoData *viddata = data->waylandData; + struct wl_region *region; - if (data->resize.pending) { - struct wl_region *region; - if (data->scale_factor != data->resize.scale_factor) { - window->w = 0; - window->h = 0; - } - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, data->resize.width, data->resize.height); - window->w = data->resize.width; - window->h = data->resize.height; - data->scale_factor = data->resize.scale_factor; - wl_surface_set_buffer_scale(data->surface, data->scale_factor); - if (data->egl_window) { - WAYLAND_wl_egl_window_resize(data->egl_window, window->w * data->scale_factor, window->h * data->scale_factor, 0, 0); - } - - if (data->resize.configure) { - if (data->waylandData->shell.xdg) { - xdg_surface_ack_configure(data->shell_surface.xdg.surface, data->resize.serial); - } else if (data->waylandData->shell.zxdg) { - zxdg_surface_v6_ack_configure(data->shell_surface.zxdg.surface, data->resize.serial); - } - data->resize.configure = SDL_FALSE; - } - - region = wl_compositor_create_region(data->waylandData->compositor); - wl_region_add(region, 0, 0, window->w, window->h); - wl_surface_set_opaque_region(data->surface, region); - wl_region_destroy(region); - - data->resize.pending = SDL_FALSE; + if (data->needs_resize_event || window->w != width || window->h != height || data->scale_factor != scale) { + /* We may have already updated window w/h (or only adjusted scale factor), + * so we must override the deduplication logic in the video core */ + window->w = 0; + window->h = 0; + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height); + window->w = width; + window->h = height; + data->needs_resize_event = SDL_FALSE; } + + wl_surface_set_buffer_scale(data->surface, data->scale_factor); + + if (data->egl_window) { + WAYLAND_wl_egl_window_resize(data->egl_window, + window->w * data->scale_factor, + window->h * data->scale_factor, + 0, 0); + } + + region = wl_compositor_create_region(data->waylandData->compositor); + wl_region_add(region, 0, 0, window->w, window->h); + wl_surface_set_opaque_region(data->surface, region); + wl_region_destroy(region); + + /* XXX: This workarounds issues with commiting buffers with old size after + * already acknowledging the new size, which can cause protocol violations. + * It doesn't fix the first frames after resize being glitched visually, + * but at least lets us not be terminated by the compositor. + * Can be removed once SDL's resize logic becomes compliant. */ + if (viddata->shell.xdg && data->shell_surface.xdg.surface) { + xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, window->w, window->h); + } +} + +void +Wayland_SetWindowMinimumSize(_THIS, SDL_Window * window) +{ + SetMinMaxDimensions(window, SDL_TRUE); +} + +void +Wayland_SetWindowMaximumSize(_THIS, SDL_Window * window) +{ + SetMinMaxDimensions(window, SDL_TRUE); } void Wayland_SetWindowSize(_THIS, SDL_Window * window) @@ -850,35 +1416,114 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window) SDL_VideoData *data = _this->driverdata; SDL_WindowData *wind = window->driverdata; struct wl_region *region; +#ifdef HAVE_LIBDECOR_H + struct libdecor_state *state; +#endif - wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window)); +#ifdef HAVE_LIBDECOR_H + /* we must not resize the window while we have a static (non-floating) size */ + if (data->shell.libdecor && + wind->shell_surface.libdecor.frame && + !libdecor_frame_is_floating(wind->shell_surface.libdecor.frame)) { + /* Commit the resize when we re-enter floating state */ + wind->floating_resize_pending = SDL_TRUE; + return; + } +#endif + + wl_surface_set_buffer_scale(wind->surface, wind->scale_factor); if (wind->egl_window) { - WAYLAND_wl_egl_window_resize(wind->egl_window, window->w * get_window_scale_factor(window), window->h * get_window_scale_factor(window), 0, 0); + WAYLAND_wl_egl_window_resize(wind->egl_window, + window->w * wind->scale_factor, + window->h * wind->scale_factor, + 0, 0); } +#ifdef HAVE_LIBDECOR_H + if (data->shell.libdecor && wind->shell_surface.libdecor.frame) { + state = libdecor_state_new(window->w, window->h); + libdecor_frame_commit(wind->shell_surface.libdecor.frame, state, NULL); + libdecor_state_free(state); + } +#endif + + /* windowed is unconditionally set, so we can trust it here */ + wind->floating_width = window->windowed.w; + wind->floating_height = window->windowed.h; + region = wl_compositor_create_region(data->compositor); wl_region_add(region, 0, 0, window->w, window->h); wl_surface_set_opaque_region(wind->surface, region); wl_region_destroy(region); + + /* Update the geometry which may have been set by a hack in Wayland_HandleResize */ + if (data->shell.xdg && wind->shell_surface.xdg.surface) { + xdg_surface_set_window_geometry(wind->shell_surface.xdg.surface, 0, 0, window->w, window->h); + } } void Wayland_SetWindowTitle(_THIS, SDL_Window * window) { SDL_WindowData *wind = window->driverdata; - SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; - + SDL_VideoData *viddata = _this->driverdata; + if (window->title != NULL) { +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_title(wind->shell_surface.libdecor.frame, window->title); + } else +#endif if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, window->title); - } else if (viddata->shell.zxdg) { - zxdg_toplevel_v6_set_title(wind->shell_surface.zxdg.roleobj.toplevel, window->title); - } else { - wl_shell_surface_set_title(wind->shell_surface.wl, window->title); } } - WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); + WAYLAND_wl_display_flush(viddata->display); +} + +void +Wayland_SuspendScreenSaver(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + +#if SDL_USE_LIBDBUS + if (SDL_DBus_ScreensaverInhibit(_this->suspend_screensaver)) { + return; + } +#endif + + /* The idle_inhibit_unstable_v1 protocol suspends the screensaver + on a per wl_surface basis, but SDL assumes that suspending + the screensaver can be done independently of any window. + + To reconcile these differences, we propagate the idle inhibit + state to each window. If there is no window active, we will + be able to inhibit idle once the first window is created. + */ + if (data->idle_inhibit_manager) { + SDL_Window *window = _this->windows; + while (window) { + SDL_WindowData *win_data = window->driverdata; + + if (_this->suspend_screensaver && !win_data->idle_inhibitor) { + win_data->idle_inhibitor = + zwp_idle_inhibit_manager_v1_create_inhibitor(data->idle_inhibit_manager, + win_data->surface); + } else if (!_this->suspend_screensaver && win_data->idle_inhibitor) { + zwp_idle_inhibitor_v1_destroy(win_data->idle_inhibitor); + win_data->idle_inhibitor = NULL; + } + + window = window->next; + } + } } void Wayland_DestroyWindow(_THIS, SDL_Window *window) @@ -887,39 +1532,29 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window) SDL_WindowData *wind = window->driverdata; if (data) { +#if SDL_VIDEO_OPENGL_EGL if (wind->egl_surface) { SDL_EGL_DestroySurface(_this, wind->egl_surface); } +#endif if (wind->egl_window) { WAYLAND_wl_egl_window_destroy(wind->egl_window); } - if (wind->server_decoration) { - zxdg_toplevel_decoration_v1_destroy(wind->server_decoration); + if (wind->idle_inhibitor) { + zwp_idle_inhibitor_v1_destroy(wind->idle_inhibitor); } - if (wind->kwin_server_decoration) { - org_kde_kwin_server_decoration_release(wind->kwin_server_decoration); + if (wind->activation_token) { + xdg_activation_token_v1_destroy(wind->activation_token); } - if (data->shell.xdg) { - if (wind->shell_surface.xdg.roleobj.toplevel) { - xdg_toplevel_destroy(wind->shell_surface.xdg.roleobj.toplevel); - } - if (wind->shell_surface.zxdg.surface) { - xdg_surface_destroy(wind->shell_surface.xdg.surface); - } - } else if (data->shell.zxdg) { - if (wind->shell_surface.zxdg.roleobj.toplevel) { - zxdg_toplevel_v6_destroy(wind->shell_surface.zxdg.roleobj.toplevel); - } - if (wind->shell_surface.zxdg.surface) { - zxdg_surface_v6_destroy(wind->shell_surface.zxdg.surface); - } - } else { - if (wind->shell_surface.wl) { - wl_shell_surface_destroy(wind->shell_surface.wl); - } + SDL_free(wind->outputs); + + if (wind->frame_callback) { + WAYLAND_wl_event_queue_destroy(wind->frame_event_queue); + WAYLAND_wl_proxy_wrapper_destroy(wind->frame_surface_wrapper); + wl_callback_destroy(wind->frame_callback); } #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH @@ -937,6 +1572,6 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window) window->driverdata = NULL; } -#endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */ +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h index 93ba121b8..90e4d8cf6 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,15 +32,6 @@ struct SDL_WaylandInput; -typedef struct { - struct zxdg_surface_v6 *surface; - union { - struct zxdg_toplevel_v6 *toplevel; - struct zxdg_popup_v6 *popup; - } roleobj; - SDL_bool initial_configure_seen; -} SDL_zxdg_shell_surface; - typedef struct { struct xdg_surface *surface; union { @@ -50,57 +41,82 @@ typedef struct { SDL_bool initial_configure_seen; } SDL_xdg_shell_surface; +#ifdef HAVE_LIBDECOR_H +typedef struct { + struct libdecor_frame *frame; + SDL_bool initial_configure_seen; +} SDL_libdecor_surface; +#endif + typedef struct { SDL_Window *sdlwindow; SDL_VideoData *waylandData; struct wl_surface *surface; + struct wl_callback *frame_callback; + struct wl_event_queue *frame_event_queue; + struct wl_surface *frame_surface_wrapper; union { +#ifdef HAVE_LIBDECOR_H + SDL_libdecor_surface libdecor; +#endif SDL_xdg_shell_surface xdg; - SDL_zxdg_shell_surface zxdg; - struct wl_shell_surface *wl; } shell_surface; struct wl_egl_window *egl_window; struct SDL_WaylandInput *keyboard_device; +#if SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; +#endif struct zwp_locked_pointer_v1 *locked_pointer; + struct zwp_confined_pointer_v1 *confined_pointer; struct zxdg_toplevel_decoration_v1 *server_decoration; - struct org_kde_kwin_server_decoration *kwin_server_decoration; + struct zwp_keyboard_shortcuts_inhibitor_v1 *key_inhibitor; + struct zwp_idle_inhibitor_v1 *idle_inhibitor; + struct xdg_activation_token_v1 *activation_token; + + /* floating dimensions for restoring from maximized and fullscreen */ + int floating_width, floating_height; + + SDL_atomic_t swap_interval_ready; #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH struct qt_extended_surface *extended_surface; #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ - struct { - SDL_bool pending, configure; - uint32_t serial; - int width, height; - float scale_factor; - } resize; - - struct wl_output **outputs; + SDL_WaylandOutputData **outputs; int num_outputs; float scale_factor; + SDL_bool needs_resize_event; + SDL_bool floating_resize_pending; } SDL_WindowData; extern void Wayland_ShowWindow(_THIS, SDL_Window *window); +extern void Wayland_HideWindow(_THIS, SDL_Window *window); +extern void Wayland_RaiseWindow(_THIS, SDL_Window *window); extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen); extern void Wayland_MaximizeWindow(_THIS, SDL_Window * window); -extern void Wayland_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void Wayland_MinimizeWindow(_THIS, SDL_Window * window); +extern void Wayland_SetWindowMouseRect(_THIS, SDL_Window * window); +extern void Wayland_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void Wayland_SetWindowKeyboardGrab(_THIS, SDL_Window *window, SDL_bool grabbed); extern void Wayland_RestoreWindow(_THIS, SDL_Window * window); extern void Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); +extern void Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); extern int Wayland_CreateWindow(_THIS, SDL_Window *window); extern void Wayland_SetWindowSize(_THIS, SDL_Window * window); +extern void Wayland_SetWindowMinimumSize(_THIS, SDL_Window * window); +extern void Wayland_SetWindowMaximumSize(_THIS, SDL_Window * window); +extern int Wayland_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Window * parent_window); extern void Wayland_SetWindowTitle(_THIS, SDL_Window * window); extern void Wayland_DestroyWindow(_THIS, SDL_Window *window); +extern void Wayland_SuspendScreenSaver(_THIS); extern SDL_bool Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info); extern int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled); - -extern void Wayland_HandlePendingResize(SDL_Window *window); +extern int Wayland_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation); #endif /* SDL_waylandwindow_h_ */ diff --git a/Engine/lib/sdl/src/video/windows/SDL_msctf.h b/Engine/lib/sdl/src/video/windows/SDL_msctf.h index 1397e5977..9fa80785d 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_msctf.h +++ b/Engine/lib/sdl/src/video/windows/SDL_msctf.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_vkeys.h b/Engine/lib/sdl/src/video/windows/SDL_vkeys.h index 55b51cad4..3b0c41929 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_vkeys.h +++ b/Engine/lib/sdl/src/video/windows/SDL_vkeys.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsclipboard.c b/Engine/lib/sdl/src/video/windows/SDL_windowsclipboard.c index 1ac477fff..09f33e25b 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsclipboard.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsclipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsclipboard.h b/Engine/lib/sdl/src/video/windows/SDL_windowsclipboard.h index 18642da87..5cdcdfcab 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsclipboard.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c b/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c index 041d055ab..0619f67dd 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -40,6 +40,11 @@ /* For GET_X_LPARAM, GET_Y_LPARAM. */ #include +/* For WM_TABLET_QUERYSYSTEMGESTURESTATUS et. al. */ +#if HAVE_TPCSHRD_H +#include +#endif /* HAVE_TPCSHRD_H */ + /* #define WMMSG_DEBUG */ #ifdef WMMSG_DEBUG #include @@ -81,6 +86,16 @@ #define WM_UNICHAR 0x0109 #endif +#ifndef IS_HIGH_SURROGATE +#define IS_HIGH_SURROGATE(x) (((x) >= 0xd800) && ((x) <= 0xdbff)) +#endif +#ifndef IS_LOW_SURROGATE +#define IS_LOW_SURROGATE(x) (((x) >= 0xdc00) && ((x) <= 0xdfff)) +#endif +#ifndef IS_SURROGATE_PAIR +#define IS_SURROGATE_PAIR(h,l) (IS_HIGH_SURROGATE(h) && IS_LOW_SURROGATE(l)) +#endif + static SDL_Scancode VKeytoScancodeFallback(WPARAM vkey) { @@ -294,31 +309,34 @@ WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data, SDL_MouseID mou } static void -WIN_CheckRawMouseButtons(ULONG rawButtons, SDL_WindowData *data) +WIN_CheckRawMouseButtons(ULONG rawButtons, SDL_WindowData *data, SDL_MouseID mouseID) { + // Add a flag to distinguish raw mouse buttons from wParam above + rawButtons |= 0x8000000; + if (rawButtons != data->mouse_button_flags) { Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL); SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0; if ((rawButtons & RI_MOUSE_BUTTON_1_DOWN)) - WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, 0); + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, mouseID); if ((rawButtons & RI_MOUSE_BUTTON_1_UP)) - WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, 0); + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, mouseID); if ((rawButtons & RI_MOUSE_BUTTON_2_DOWN)) - WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, 0); + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, mouseID); if ((rawButtons & RI_MOUSE_BUTTON_2_UP)) - WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, 0); + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, mouseID); if ((rawButtons & RI_MOUSE_BUTTON_3_DOWN)) - WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, 0); + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, mouseID); if ((rawButtons & RI_MOUSE_BUTTON_3_UP)) - WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, 0); + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, mouseID); if ((rawButtons & RI_MOUSE_BUTTON_4_DOWN)) - WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X1, 0); + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X1, mouseID); if ((rawButtons & RI_MOUSE_BUTTON_4_UP)) - WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X1, 0); + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X1, mouseID); if ((rawButtons & RI_MOUSE_BUTTON_5_DOWN)) - WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X2, 0); + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X2, mouseID); if ((rawButtons & RI_MOUSE_BUTTON_5_UP)) - WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X2, 0); + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X2, mouseID); data->mouse_button_flags = rawButtons; } } @@ -356,7 +374,77 @@ WIN_CheckAsyncMouseRelease(SDL_WindowData *data) if (!(keyState & 0x8000)) { WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_X2, 0); } - data->mouse_button_flags = 0; + data->mouse_button_flags = (WPARAM)-1; +} + +static void +WIN_UpdateFocus(SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + HWND hwnd = data->hwnd; + SDL_bool had_focus = (SDL_GetKeyboardFocus() == window) ? SDL_TRUE : SDL_FALSE; + SDL_bool has_focus = (GetForegroundWindow() == hwnd) ? SDL_TRUE : SDL_FALSE; + + if (had_focus == has_focus) { + return; + } + + if (has_focus) { + POINT cursorPos; + + SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0; + if (GetAsyncKeyState(VK_LBUTTON)) { + data->focus_click_pending |= !swapButtons ? SDL_BUTTON_LMASK : SDL_BUTTON_RMASK; + } + if (GetAsyncKeyState(VK_RBUTTON)) { + data->focus_click_pending |= !swapButtons ? SDL_BUTTON_RMASK : SDL_BUTTON_LMASK; + } + if (GetAsyncKeyState(VK_MBUTTON)) { + data->focus_click_pending |= SDL_BUTTON_MMASK; + } + if (GetAsyncKeyState(VK_XBUTTON1)) { + data->focus_click_pending |= SDL_BUTTON_X1MASK; + } + if (GetAsyncKeyState(VK_XBUTTON2)) { + data->focus_click_pending |= SDL_BUTTON_X2MASK; + } + + SDL_SetKeyboardFocus(window); + + /* In relative mode we are guaranteed to have mouse focus if we have keyboard focus */ + if (!SDL_GetMouse()->relative_mode) { + GetCursorPos(&cursorPos); + ScreenToClient(hwnd, &cursorPos); + SDL_SendMouseMotion(window, 0, 0, cursorPos.x, cursorPos.y); + } + + WIN_CheckAsyncMouseRelease(data); + WIN_UpdateClipCursor(window); + + /* + * FIXME: Update keyboard state + */ + WIN_CheckClipboardUpdate(data->videodata); + + SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0); + SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0); + SDL_ToggleModState(KMOD_SCROLL, (GetKeyState(VK_SCROLL) & 0x0001) != 0); + + } else { + RECT rect; + + data->in_window_deactivation = SDL_TRUE; + + SDL_SetKeyboardFocus(NULL); + WIN_ResetDeadKeys(); + + if (GetClipCursor(&rect) && SDL_memcmp(&rect, &data->cursor_clipped_rect, sizeof(rect)) == 0) { + ClipCursor(NULL); + SDL_zero(data->cursor_clipped_rect); + } + + data->in_window_deactivation = SDL_FALSE; + } } static BOOL @@ -386,17 +474,20 @@ WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text) return SDL_TRUE; } +static BOOL +WIN_ConvertUTF16toUTF8(UINT32 high_surrogate, UINT32 low_surrogate, char * text) +{ + const UINT32 SURROGATE_OFFSET = 0x10000 - (0xD800 << 10) - 0xDC00; + const UINT32 codepoint = (high_surrogate << 10) + low_surrogate + SURROGATE_OFFSET; + return WIN_ConvertUTF32toUTF8(codepoint, text); +} + static SDL_bool ShouldGenerateWindowCloseOnAltF4(void) { return !SDL_GetHintBoolean(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, SDL_FALSE); } -/* Win10 "Fall Creators Update" introduced the bug that SetCursorPos() (as used by SDL_WarpMouseInWindow()) - doesn't reliably generate WM_MOUSEMOVE events anymore (see #3931) which breaks relative mouse mode via warping. - This is used to implement a workaround.. */ -static SDL_bool isWin10FCUorNewer = SDL_FALSE; - /* We want to generate mouse events from mouse and pen, and touch events from touchscreens */ #define MI_WP_SIGNATURE 0xFF515700 #define MI_WP_SIGNATURE_MASK 0xFFFFFF00 @@ -428,6 +519,109 @@ static SDL_MOUSE_EVENT_SOURCE GetMouseMessageSource() return SDL_MOUSE_EVENT_SOURCE_MOUSE; } +static SDL_WindowData * +WIN_GetWindowDataFromHWND(HWND hwnd) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + SDL_Window *window; + + if (_this) { + for (window = _this->windows; window; window = window->next) { + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + if (data && data->hwnd == hwnd) { + return data; + } + } + } + return NULL; +} + +LRESULT CALLBACK +WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + KBDLLHOOKSTRUCT* hookData = (KBDLLHOOKSTRUCT*)lParam; + SDL_VideoData* data = SDL_GetVideoDevice()->driverdata; + SDL_Scancode scanCode; + + if (nCode < 0 || nCode != HC_ACTION) { + return CallNextHookEx(NULL, nCode, wParam, lParam); + } + + switch (hookData->vkCode) { + case VK_LWIN: + scanCode = SDL_SCANCODE_LGUI; + break; + case VK_RWIN: + scanCode = SDL_SCANCODE_RGUI; + break; + case VK_LMENU: + scanCode = SDL_SCANCODE_LALT; + break; + case VK_RMENU: + scanCode = SDL_SCANCODE_RALT; + break; + case VK_LCONTROL: + scanCode = SDL_SCANCODE_LCTRL; + break; + case VK_RCONTROL: + scanCode = SDL_SCANCODE_RCTRL; + break; + + /* These are required to intercept Alt+Tab and Alt+Esc on Windows 7 */ + case VK_TAB: + scanCode = SDL_SCANCODE_TAB; + break; + case VK_ESCAPE: + scanCode = SDL_SCANCODE_ESCAPE; + break; + + default: + return CallNextHookEx(NULL, nCode, wParam, lParam); + } + + if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) { + SDL_SendKeyboardKey(SDL_PRESSED, scanCode); + } else { + SDL_SendKeyboardKey(SDL_RELEASED, scanCode); + + /* If the key was down prior to our hook being installed, allow the + key up message to pass normally the first time. This ensures other + windows have a consistent view of the key state, and avoids keys + being stuck down in those windows if they are down when the grab + happens and raised while grabbed. */ + if (hookData->vkCode <= 0xFF && data->pre_hook_key_state[hookData->vkCode]) { + data->pre_hook_key_state[hookData->vkCode] = 0; + return CallNextHookEx(NULL, nCode, wParam, lParam); + } + } + + return 1; +} + +static void WIN_CheckICMProfileChanged(SDL_Window* window) +{ + SDL_VideoDisplay* display = SDL_GetDisplayForWindow(window); + SDL_DisplayData* data = (SDL_DisplayData*)display->driverdata; + static WCHAR currentIcmFileName[MAX_PATH] = { '\0' }; + WCHAR icmFileName[MAX_PATH]; + HDC hdc; + SDL_bool succeeded; + DWORD fileNameSize = MAX_PATH; + + hdc = CreateDCW(data->DeviceName, NULL, NULL, NULL); + if (hdc) { + succeeded = GetICMProfileW(hdc, &fileNameSize, icmFileName); + DeleteDC(hdc); + if (succeeded) { + + if (SDL_wcsncmp(currentIcmFileName, icmFileName, fileNameSize)) { + SDL_wcslcpy(currentIcmFileName, icmFileName, fileNameSize); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0); + } + } + } +} + LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { @@ -448,7 +642,11 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } /* Get the window data for the window */ - data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData")); + data = WIN_GetWindowDataFromHWND(hwnd); + if (!data) { + /* Fallback */ + data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData")); + } if (!data) { return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); } @@ -484,77 +682,29 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { /* Don't immediately clip the cursor in case we're clicking minimize/maximize buttons */ data->skip_update_clipcursor = SDL_TRUE; + + /* Update the focus here, since it's possible to get WM_ACTIVATE and WM_SETFOCUS without + actually being the foreground window, but this appears to get called in all cases where + the global foreground window changes to and from this window. */ + WIN_UpdateFocus(data->window); + WIN_CheckICMProfileChanged(data->window); } break; case WM_ACTIVATE: { - POINT cursorPos; - BOOL minimized; - - minimized = HIWORD(wParam); - if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) { - /* Don't mark the window as shown if it's activated before being shown */ - if (!IsWindowVisible(hwnd)) { - break; - } - if (LOWORD(wParam) == WA_CLICKACTIVE) { - SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0; - if (GetAsyncKeyState(VK_LBUTTON)) { - data->focus_click_pending |= !swapButtons ? SDL_BUTTON_LMASK : SDL_BUTTON_RMASK; - } - if (GetAsyncKeyState(VK_RBUTTON)) { - data->focus_click_pending |= !swapButtons ? SDL_BUTTON_RMASK : SDL_BUTTON_LMASK; - } - if (GetAsyncKeyState(VK_MBUTTON)) { - data->focus_click_pending |= SDL_BUTTON_MMASK; - } - if (GetAsyncKeyState(VK_XBUTTON1)) { - data->focus_click_pending |= SDL_BUTTON_X1MASK; - } - if (GetAsyncKeyState(VK_XBUTTON2)) { - data->focus_click_pending |= SDL_BUTTON_X2MASK; - } - } - - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); - if (SDL_GetKeyboardFocus() != data->window) { - SDL_SetKeyboardFocus(data->window); - } - - GetCursorPos(&cursorPos); - ScreenToClient(hwnd, &cursorPos); - SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y); - - WIN_CheckAsyncMouseRelease(data); - WIN_UpdateClipCursor(data->window); - - /* - * FIXME: Update keyboard state - */ - WIN_CheckClipboardUpdate(data->videodata); - - SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0); - SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0); - } else { - RECT rect; - - data->in_window_deactivation = SDL_TRUE; - - if (SDL_GetKeyboardFocus() == data->window) { - SDL_SetKeyboardFocus(NULL); - WIN_ResetDeadKeys(); - } - - if (GetClipCursor(&rect) && SDL_memcmp(&rect, &data->cursor_clipped_rect, sizeof(rect)) == 0) { - ClipCursor(NULL); - SDL_zero(data->cursor_clipped_rect); - } - - data->in_window_deactivation = SDL_FALSE; - } + /* Update the focus in case we changed focus to a child window and then away from the application */ + WIN_UpdateFocus(data->window); + } + break; + + case WM_SETFOCUS: + case WM_KILLFOCUS: + case WM_ENTERIDLE: + { + /* Update the focus in case it's changing between top-level windows in the same application */ + WIN_UpdateFocus(data->window); } - returnCode = 0; break; case WM_POINTERUPDATE: @@ -566,29 +716,29 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_MOUSEMOVE: { SDL_Mouse *mouse = SDL_GetMouse(); + + if (!data->mouse_tracked) { + TRACKMOUSEEVENT trackMouseEvent; + + trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT); + trackMouseEvent.dwFlags = TME_LEAVE; + trackMouseEvent.hwndTrack = data->hwnd; + + if (TrackMouseEvent(&trackMouseEvent)) { + data->mouse_tracked = SDL_TRUE; + } + } + if (!mouse->relative_mode || mouse->relative_mode_warp) { /* Only generate mouse events for real mouse */ if (GetMouseMessageSource() != SDL_MOUSE_EVENT_SOURCE_TOUCH && lParam != data->last_pointer_update) { SDL_SendMouseMotion(data->window, 0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - if (isWin10FCUorNewer && mouse->relative_mode_warp) { - /* To work around #3931, Win10 bug introduced in Fall Creators Update, where - SetCursorPos() (SDL_WarpMouseInWindow()) doesn't reliably generate mouse events anymore, - after each windows mouse event generate a fake event for the middle of the window - if relative_mode_warp is used */ - int center_x = 0, center_y = 0; - SDL_GetWindowSize(data->window, ¢er_x, ¢er_y); - center_x /= 2; - center_y /= 2; - SDL_SendMouseMotion(data->window, 0, 0, center_x, center_y); - } } - } else { - /* We still need to update focus */ - SDL_SetMouseFocus(data->window); } } - /* don't break here, fall through to check the wParam like the button presses */ + break; + case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: @@ -618,73 +768,109 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) HRAWINPUT hRawInput = (HRAWINPUT)lParam; RAWINPUT inp; UINT size = sizeof(inp); - const SDL_bool isRelative = mouse->relative_mode || mouse->relative_mode_warp; - const SDL_bool isCapture = ((data->window->flags & SDL_WINDOW_MOUSE_CAPTURE) != 0); - if (!isRelative || mouse->focus != data->window) { - if (!isCapture) { - break; - } + /* We only use raw mouse input in relative mode */ + if (!mouse->relative_mode || mouse->relative_mode_warp) { + break; + } + + /* Relative mouse motion is delivered to the window with keyboard focus */ + if (data->window != SDL_GetKeyboardFocus()) { + break; } GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER)); /* Mouse data (ignoring synthetic mouse events generated for touchscreens) */ if (inp.header.dwType == RIM_TYPEMOUSE) { - if (GetMouseMessageSource() == SDL_MOUSE_EVENT_SOURCE_TOUCH || - (GetMessageExtraInfo() & 0x82) == 0x82) { + SDL_MouseID mouseID; + RAWMOUSE* rawmouse; + if (SDL_GetNumTouchDevices() > 0 && + (GetMouseMessageSource() == SDL_MOUSE_EVENT_SOURCE_TOUCH || (GetMessageExtraInfo() & 0x82) == 0x82)) { break; } - if (isRelative) { - RAWMOUSE* rawmouse = &inp.data.mouse; + /* We do all of our mouse state checking against mouse ID 0 + * We would only use the actual hDevice if we were tracking + * all mouse motion independently, and never using mouse ID 0. + */ + mouseID = 0; /* (SDL_MouseID)(uintptr_t)inp.header.hDevice; */ + rawmouse = &inp.data.mouse; - if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) { - SDL_SendMouseMotion(data->window, 0, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY); - } else if (rawmouse->lLastX || rawmouse->lLastY) { - /* synthesize relative moves from the abs position */ - static SDL_Point lastMousePoint; - SDL_bool virtual_desktop = (rawmouse->usFlags & MOUSE_VIRTUAL_DESKTOP) ? SDL_TRUE : SDL_FALSE; - int w = GetSystemMetrics(virtual_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); - int h = GetSystemMetrics(virtual_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); - int x = (int)(((float)rawmouse->lLastX / 65535.0f) * w); - int y = (int)(((float)rawmouse->lLastY / 65535.0f) * h); + if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) { + SDL_SendMouseMotion(data->window, mouseID, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY); + } else if (rawmouse->lLastX || rawmouse->lLastY) { + /* This is absolute motion, either using a tablet or mouse over RDP - if (lastMousePoint.x == 0 && lastMousePoint.y == 0) { - lastMousePoint.x = x; - lastMousePoint.y = y; + Notes on how RDP appears to work, as of Windows 10 2004: + - SetCursorPos() calls are cached, with multiple calls coalesced into a single call that's sent to the RDP client. If the last call to SetCursorPos() has the same value as the last one that was sent to the client, it appears to be ignored and not sent. This means that we need to jitter the SetCursorPos() position slightly in order for the recentering to work correctly. + - User mouse motion is coalesced with SetCursorPos(), so the WM_INPUT positions we see will not necessarily match the positon we requested with SetCursorPos(). + - SetCursorPos() outside of the bounds of the focus window appears not to do anything. + - SetCursorPos() while the cursor is NULL doesn't do anything + + We handle this by creating a safe area within the application window, and when the mouse leaves that safe area, we warp back to the opposite side. Any single motion > 50% of the safe area is assumed to be a warp and ignored. + */ + SDL_bool remote_desktop = GetSystemMetrics(SM_REMOTESESSION) ? SDL_TRUE : SDL_FALSE; + SDL_bool virtual_desktop = (rawmouse->usFlags & MOUSE_VIRTUAL_DESKTOP) ? SDL_TRUE : SDL_FALSE; + SDL_bool normalized_coordinates = ((rawmouse->usFlags & 0x40) == 0) ? SDL_TRUE : SDL_FALSE; + int w = GetSystemMetrics(virtual_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); + int h = GetSystemMetrics(virtual_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); + int x = normalized_coordinates ? (int)(((float)rawmouse->lLastX / 65535.0f) * w) : (int)rawmouse->lLastX; + int y = normalized_coordinates ? (int)(((float)rawmouse->lLastY / 65535.0f) * h) : (int)rawmouse->lLastY; + int relX, relY; + + /* Calculate relative motion */ + if (data->last_raw_mouse_position.x == 0 && data->last_raw_mouse_position.y == 0) { + data->last_raw_mouse_position.x = x; + data->last_raw_mouse_position.y = y; + } + relX = (int)(x - data->last_raw_mouse_position.x); + relY = (int)(y - data->last_raw_mouse_position.y); + + if (remote_desktop) { + if (!data->in_title_click && !data->focus_click_pending) { + static int wobble; + float floatX = (float)x / w; + float floatY = (float)y / h; + + /* See if the mouse is at the edge of the screen, or in the RDP title bar area */ + if (floatX <= 0.01f || floatX >= 0.99f || floatY <= 0.01f || floatY >= 0.99f || y < 32) { + /* Wobble the cursor position so it's not ignored if the last warp didn't have any effect */ + RECT rect = data->cursor_clipped_rect; + int warpX = rect.left + ((rect.right - rect.left) / 2) + wobble; + int warpY = rect.top + ((rect.bottom - rect.top) / 2); + + WIN_SetCursorPos(warpX, warpY); + + ++wobble; + if (wobble > 1) { + wobble = -1; + } + } else { + /* Send relative motion if we didn't warp last frame (had good position data) + We also sometimes get large deltas due to coalesced mouse motion and warping, + so ignore those. + */ + const int MAX_RELATIVE_MOTION = (h / 6); + if (SDL_abs(relX) < MAX_RELATIVE_MOTION && + SDL_abs(relY) < MAX_RELATIVE_MOTION) { + SDL_SendMouseMotion(data->window, mouseID, 1, relX, relY); + } + } + } + } else { + const int MAXIMUM_TABLET_RELATIVE_MOTION = 32; + if (SDL_abs(relX) > MAXIMUM_TABLET_RELATIVE_MOTION || + SDL_abs(relY) > MAXIMUM_TABLET_RELATIVE_MOTION) { + /* Ignore this motion, probably a pen lift and drop */ + } else { + SDL_SendMouseMotion(data->window, mouseID, 1, relX, relY); } - - SDL_SendMouseMotion(data->window, 0, 1, (int)(x-lastMousePoint.x), (int)(y-lastMousePoint.y)); - - lastMousePoint.x = x; - lastMousePoint.y = y; } - WIN_CheckRawMouseButtons(rawmouse->usButtonFlags, data); - } else if (isCapture) { - /* we check for where Windows thinks the system cursor lives in this case, so we don't really lose mouse accel, etc. */ - POINT pt; - RECT hwndRect; - HWND currentHnd; - GetCursorPos(&pt); - currentHnd = WindowFromPoint(pt); - ScreenToClient(hwnd, &pt); - GetClientRect(hwnd, &hwndRect); - - /* if in the window, WM_MOUSEMOVE, etc, will cover it. */ - if(currentHnd != hwnd || pt.x < 0 || pt.y < 0 || pt.x > hwndRect.right || pt.y > hwndRect.right) { - SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0; - - SDL_SendMouseMotion(data->window, 0, 0, (int)pt.x, (int)pt.y); - SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT); - SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT); - SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE); - SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1); - SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2); - } - } else { - SDL_assert(0 && "Shouldn't happen"); + data->last_raw_mouse_position.x = x; + data->last_raw_mouse_position.y = y; } + WIN_CheckRawMouseButtons(rawmouse->usButtonFlags, data, mouseID); } } break; @@ -701,10 +887,9 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } break; -#ifdef WM_MOUSELEAVE case WM_MOUSELEAVE: - if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode && !(data->window->flags & SDL_WINDOW_MOUSE_CAPTURE)) { - if (!IsIconic(hwnd)) { + if (!(data->window->flags & SDL_WINDOW_MOUSE_CAPTURE)) { + if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode && !IsIconic(hwnd)) { SDL_Mouse *mouse; POINT cursorPos; GetCursorPos(&cursorPos); @@ -721,11 +906,16 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } } } + + /* When WM_MOUSELEAVE is fired we can be assured that the cursor has left the window */ SDL_SetMouseFocus(NULL); } + + /* Once we get WM_MOUSELEAVE we're guaranteed that the window is no longer tracked */ + data->mouse_tracked = SDL_FALSE; + returnCode = 0; break; -#endif /* WM_MOUSELEAVE */ case WM_KEYDOWN: case WM_SYSKEYDOWN: @@ -769,11 +959,36 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_UNICHAR: if (wParam == UNICODE_NOCHAR) { returnCode = 1; - break; + } else { + char text[5]; + if (WIN_ConvertUTF32toUTF8((UINT32)wParam, text)) { + SDL_SendKeyboardText(text); + } + returnCode = 0; } - /* otherwise fall through to below */ + break; + case WM_CHAR: - { + /* When a user enters a Unicode code point defined in the Basic Multilingual Plane, Windows sends a WM_CHAR + message with the code point encoded as UTF-16. When a user enters a Unicode code point from a Supplementary + Plane, Windows sends the code point in two separate WM_CHAR messages: The first message includes the UTF-16 + High Surrogate and the second the UTF-16 Low Surrogate. The High and Low Surrogates cannot be individually + converted to valid UTF-8, therefore, we must save the High Surrogate from the first WM_CHAR message and + concatenate it with the Low Surrogate from the second WM_CHAR message. At that point, we have a valid + UTF-16 surrogate pair ready to re-encode as UTF-8. */ + if (IS_HIGH_SURROGATE(wParam)) { + data->high_surrogate = (WCHAR)wParam; + } else if (IS_SURROGATE_PAIR(data->high_surrogate, wParam)) { + /* The code point is in a Supplementary Plane. + Here wParam is the Low Surrogate. */ + char text[5]; + if (WIN_ConvertUTF16toUTF8((UINT32)data->high_surrogate, (UINT32)wParam, text)) { + SDL_SendKeyboardText(text); + } + data->high_surrogate = 0; + } else { + /* The code point is in the Basic Multilingual Plane. + It's numerically equal to UTF-32. */ char text[5]; if (WIN_ConvertUTF32toUTF8((UINT32)wParam, text)) { SDL_SendKeyboardText(text); @@ -870,6 +1085,14 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Fix our size to the current size */ info = (MINMAXINFO *) lParam; if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_RESIZABLE) { + if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_BORDERLESS) { + int screenW = GetSystemMetrics(SM_CXSCREEN); + int screenH = GetSystemMetrics(SM_CYSCREEN); + info->ptMaxSize.x = SDL_max(w, screenW); + info->ptMaxSize.y = SDL_max(h, screenH); + info->ptMaxPosition.x = SDL_min(0, ((screenW - w) / 2)); + info->ptMaxPosition.y = SDL_min(0, ((screenH - h) / 2)); + } info->ptMinTrackSize.x = w + min_w; info->ptMinTrackSize.y = h + min_h; if (constrain_max_size) { @@ -926,6 +1149,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Forces a WM_PAINT event */ InvalidateRect(hwnd, NULL, FALSE); + + WIN_CheckICMProfileChanged(data->window); } break; @@ -942,10 +1167,12 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); break; - default: + case SIZE_RESTORED: SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0); break; + default: + break; } } break; @@ -1065,6 +1292,25 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } break; +#if HAVE_TPCSHRD_H + + case WM_TABLET_QUERYSYSTEMGESTURESTATUS: + /* See https://msdn.microsoft.com/en-us/library/windows/desktop/bb969148(v=vs.85).aspx . + * If we're handling our own touches, we don't want any gestures. + * Not all of these settings are documented. + * The use of the undocumented ones was suggested by https://github.com/bjarkeck/GCGJ/blob/master/Monogame/Windows/WinFormsGameForm.cs . */ + return TABLET_DISABLE_PRESSANDHOLD | /* disables press and hold (right-click) gesture */ + TABLET_DISABLE_PENTAPFEEDBACK | /* disables UI feedback on pen up (waves) */ + TABLET_DISABLE_PENBARRELFEEDBACK | /* disables UI feedback on pen button down (circle) */ + TABLET_DISABLE_TOUCHUIFORCEON | + TABLET_DISABLE_TOUCHUIFORCEOFF | + TABLET_DISABLE_TOUCHSWITCH | + TABLET_DISABLE_FLICKS | /* disables pen flicks (back, forward, drag down, drag up) */ + TABLET_DISABLE_SMOOTHSCROLLING | + TABLET_DISABLE_FLICKFALLBACKKEYS; + +#endif /* HAVE_TPCSHRD_H */ + case WM_DROPFILES: { UINT i; @@ -1175,6 +1421,31 @@ static void WIN_UpdateClipCursorForWindows() } } +static void WIN_UpdateMouseCapture() +{ + SDL_Window* focusWindow = SDL_GetKeyboardFocus(); + + if (focusWindow && (focusWindow->flags & SDL_WINDOW_MOUSE_CAPTURE)) { + SDL_WindowData *data = (SDL_WindowData *) focusWindow->driverdata; + + if (!data->mouse_tracked) { + POINT pt; + + if (GetCursorPos(&pt) && ScreenToClient(data->hwnd, &pt)) { + SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0; + SDL_MouseID mouseID = SDL_GetMouse()->mouseID; + + SDL_SendMouseMotion(data->window, mouseID, 0, (int)pt.x, (int)pt.y); + SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT); + SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT); + SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE); + SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1); + SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2); + } + } + } +} + /* A message hook called before TranslateMessage() */ static SDL_WindowsMessageHook g_WindowsMessageHook = NULL; static void *g_WindowsMessageHookData = NULL; @@ -1185,13 +1456,57 @@ void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata) g_WindowsMessageHookData = userdata; } +int +WIN_WaitEventTimeout(_THIS, int timeout) +{ + MSG msg; + if (g_WindowsEnableMessageLoop) { + BOOL message_result; + UINT_PTR timer_id = 0; + if (timeout > 0) { + timer_id = SetTimer(NULL, 0, timeout, NULL); + message_result = GetMessage(&msg, 0, 0, 0); + KillTimer(NULL, timer_id); + } else if (timeout == 0) { + message_result = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + } else { + message_result = GetMessage(&msg, 0, 0, 0); + } + if (message_result) { + if (msg.message == WM_TIMER && msg.hwnd == NULL && msg.wParam == timer_id) { + return 0; + } + if (g_WindowsMessageHook) { + g_WindowsMessageHook(g_WindowsMessageHookData, msg.hwnd, msg.message, msg.wParam, msg.lParam); + } + /* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */ + TranslateMessage(&msg); + DispatchMessage(&msg); + return 1; + } else { + return 0; + } + } else { + /* Fail the wait so the caller falls back to polling */ + return -1; + } +} + +void +WIN_SendWakeupEvent(_THIS, SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + PostMessage(data->hwnd, data->videodata->_SDL_WAKEUP, 0, 0); +} + void WIN_PumpEvents(_THIS) { const Uint8 *keystate; MSG msg; - DWORD start_ticks = GetTickCount(); + DWORD end_ticks = GetTickCount() + 1; int new_messages = 0; + SDL_Window *focusWindow; if (g_WindowsEnableMessageLoop) { while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { @@ -1199,12 +1514,22 @@ WIN_PumpEvents(_THIS) g_WindowsMessageHook(g_WindowsMessageHookData, msg.hwnd, msg.message, msg.wParam, msg.lParam); } + /* Don't dispatch any mouse motion queued prior to or including the last mouse warp */ + if (msg.message == WM_MOUSEMOVE && SDL_last_warp_time) { + if (!SDL_TICKS_PASSED(msg.time, (SDL_last_warp_time + 1))) { + continue; + } + + /* This mouse message happened after the warp */ + SDL_last_warp_time = 0; + } + /* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */ TranslateMessage(&msg); DispatchMessage(&msg); /* Make sure we don't busy loop here forever if there are lots of events coming in */ - if (SDL_TICKS_PASSED(msg.time, start_ticks)) { + if (SDL_TICKS_PASSED(msg.time, end_ticks)) { /* We might get a few new messages generated by the Steam overlay or other application hooks In this case those messages will be processed before any pending input, so we want to continue after those messages. (thanks to Peter Deayton for his investigation here) @@ -1230,55 +1555,43 @@ WIN_PumpEvents(_THIS) SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT); } - /* Update the clipping rect in case someone else has stolen it */ - WIN_UpdateClipCursorForWindows(); -} - -/* to work around #3931, a bug introduced in Win10 Fall Creators Update (build nr. 16299) - we need to detect the windows version. this struct and the function below does that. - usually this struct and the corresponding function (RtlGetVersion) are in - but here we just load it dynamically */ -struct SDL_WIN_OSVERSIONINFOW { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - WCHAR szCSDVersion[128]; -}; - -static SDL_bool -IsWin10FCUorNewer(void) -{ - HMODULE handle = GetModuleHandleW(L"ntdll.dll"); - if (handle) { - typedef LONG(WINAPI* RtlGetVersionPtr)(struct SDL_WIN_OSVERSIONINFOW*); - RtlGetVersionPtr getVersionPtr = (RtlGetVersionPtr)GetProcAddress(handle, "RtlGetVersion"); - if (getVersionPtr != NULL) { - struct SDL_WIN_OSVERSIONINFOW info; - SDL_zero(info); - info.dwOSVersionInfoSize = sizeof(info); - if (getVersionPtr(&info) == 0) { /* STATUS_SUCCESS == 0 */ - if ((info.dwMajorVersion == 10 && info.dwMinorVersion == 0 && info.dwBuildNumber >= 16299) || - (info.dwMajorVersion == 10 && info.dwMinorVersion > 0) || - (info.dwMajorVersion > 10)) - { - return SDL_TRUE; - } - } + /* The Windows key state gets lost when using Windows+Space or Windows+G shortcuts and + not grabbing the keyboard. Note: If we *are* grabbing the keyboard, GetKeyState() + will return inaccurate results for VK_LWIN and VK_RWIN but we don't need it anyway. */ + focusWindow = SDL_GetKeyboardFocus(); + if (!focusWindow || !(focusWindow->flags & SDL_WINDOW_KEYBOARD_GRABBED)) { + if ((keystate[SDL_SCANCODE_LGUI] == SDL_PRESSED) && !(GetKeyState(VK_LWIN) & 0x8000)) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LGUI); + } + if ((keystate[SDL_SCANCODE_RGUI] == SDL_PRESSED) && !(GetKeyState(VK_RWIN) & 0x8000)) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RGUI); } } - return SDL_FALSE; + + /* Update the clipping rect in case someone else has stolen it */ + WIN_UpdateClipCursorForWindows(); + + /* Update mouse capture */ + WIN_UpdateMouseCapture(); } + static int app_registered = 0; LPTSTR SDL_Appname = NULL; Uint32 SDL_Appstyle = 0; HINSTANCE SDL_Instance = NULL; +static void WIN_CleanRegisterApp(WNDCLASSEX wcex) +{ + if (wcex.hIcon) DestroyIcon(wcex.hIcon); + if (wcex.hIconSm) DestroyIcon(wcex.hIconSm); + SDL_free(SDL_Appname); + SDL_Appname = NULL; +} + /* Register the class for this application */ int -SDL_RegisterApp(char *name, Uint32 style, void *hInst) +SDL_RegisterApp(const char *name, Uint32 style, void *hInst) { const char *hint; WNDCLASSEX wcex; @@ -1289,19 +1602,16 @@ SDL_RegisterApp(char *name, Uint32 style, void *hInst) ++app_registered; return (0); } - if (!name && !SDL_Appname) { + SDL_assert(SDL_Appname == NULL); + if (!name) { name = "SDL_app"; #if defined(CS_BYTEALIGNCLIENT) || defined(CS_OWNDC) - SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC); + style = (CS_BYTEALIGNCLIENT | CS_OWNDC); #endif - SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); - } - - if (name) { - SDL_Appname = WIN_UTF8ToString(name); - SDL_Appstyle = style; - SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); } + SDL_Appname = WIN_UTF8ToString(name); + SDL_Appstyle = style; + SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); /* Register the application class */ wcex.cbSize = sizeof(WNDCLASSEX); @@ -1332,11 +1642,10 @@ SDL_RegisterApp(char *name, Uint32 style, void *hInst) } if (!RegisterClassEx(&wcex)) { + WIN_CleanRegisterApp(wcex); return SDL_SetError("Couldn't register application class"); } - isWin10FCUorNewer = IsWin10FCUorNewer(); - app_registered = 1; return 0; } @@ -1353,14 +1662,14 @@ SDL_UnregisterApp() } --app_registered; if (app_registered == 0) { + /* Ensure the icons are initialized. */ + wcex.hIcon = NULL; + wcex.hIconSm = NULL; /* Check for any registered window classes. */ if (GetClassInfoEx(SDL_Instance, SDL_Appname, &wcex)) { UnregisterClass(SDL_Appname, SDL_Instance); - if (wcex.hIcon) DestroyIcon(wcex.hIcon); - if (wcex.hIconSm) DestroyIcon(wcex.hIconSm); } - SDL_free(SDL_Appname); - SDL_Appname = NULL; + WIN_CleanRegisterApp(wcex); } } diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsevents.h b/Engine/lib/sdl/src/video/windows/SDL_windowsevents.h index 80d429fca..be7f21ff2 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsevents.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,9 +27,12 @@ extern LPTSTR SDL_Appname; extern Uint32 SDL_Appstyle; extern HINSTANCE SDL_Instance; +extern LRESULT CALLBACK WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam); extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); extern void WIN_PumpEvents(_THIS); +extern void WIN_SendWakeupEvent(_THIS, SDL_Window *window); +extern int WIN_WaitEventTimeout(_THIS, int timeout); #endif /* SDL_windowsevents_h_ */ diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsframebuffer.c b/Engine/lib/sdl/src/video/windows/SDL_windowsframebuffer.c index 2ad2eddee..f41f9c09c 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsframebuffer.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsframebuffer.h b/Engine/lib/sdl/src/video/windows/SDL_windowsframebuffer.h index 9a9e243be..04fc3d130 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsframebuffer.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsframebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.c b/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.c index 5e1ec46da..b9874a543 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,6 +23,7 @@ #if SDL_VIDEO_DRIVER_WINDOWS #include "SDL_windowsvideo.h" +#include "SDL_hints.h" #include "../../events/SDL_keyboard_c.h" #include "../../events/scancodes_windows.h" @@ -35,6 +36,8 @@ static void IME_Init(SDL_VideoData *videodata, HWND hwnd); static void IME_Enable(SDL_VideoData *videodata, HWND hwnd); static void IME_Disable(SDL_VideoData *videodata, HWND hwnd); static void IME_Quit(SDL_VideoData *videodata); +static void IME_ClearComposition(SDL_VideoData *videodata); +static SDL_bool IME_IsTextInputShown(SDL_VideoData* videodata); #endif /* !SDL_DISABLE_WINDOWS_IME */ #ifndef MAPVK_VK_TO_VSC @@ -61,12 +64,14 @@ WIN_InitKeyboard(_THIS) data->ime_hwnd_main = 0; data->ime_hwnd_current = 0; data->ime_himc = 0; + data->ime_composition_length = 32 * sizeof(WCHAR); + data->ime_composition = (WCHAR*)SDL_malloc(data->ime_composition_length); data->ime_composition[0] = 0; data->ime_readingstring[0] = 0; data->ime_cursor = 0; data->ime_candlist = SDL_FALSE; - SDL_memset(data->ime_candidates, 0, sizeof(data->ime_candidates)); + data->ime_candidates = NULL; data->ime_candcount = 0; data->ime_candref = 0; data->ime_candsel = 0; @@ -106,6 +111,7 @@ WIN_InitKeyboard(_THIS) /* Are system caps/num/scroll lock active? Set our state to match. */ SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0); SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0); + SDL_ToggleModState(KMOD_SCROLL, (GetKeyState(VK_SCROLL) & 0x0001) != 0); } void @@ -244,17 +250,43 @@ WIN_SetTextInputRect(_THIS, SDL_Rect *rect) himc = ImmGetContext(videodata->ime_hwnd_current); if (himc) { - COMPOSITIONFORM cf; - cf.ptCurrentPos.x = videodata->ime_rect.x; - cf.ptCurrentPos.y = videodata->ime_rect.y; - cf.dwStyle = CFS_FORCE_POSITION; - ImmSetCompositionWindow(himc, &cf); + COMPOSITIONFORM cof; + CANDIDATEFORM caf; + + cof.dwStyle = CFS_RECT; + cof.ptCurrentPos.x = videodata->ime_rect.x; + cof.ptCurrentPos.y = videodata->ime_rect.y; + cof.rcArea.left = videodata->ime_rect.x; + cof.rcArea.right = videodata->ime_rect.x + videodata->ime_rect.w; + cof.rcArea.top = videodata->ime_rect.y; + cof.rcArea.bottom = videodata->ime_rect.y + videodata->ime_rect.h; + ImmSetCompositionWindow(himc, &cof); + + caf.dwIndex = 0; + caf.dwStyle = CFS_EXCLUDE; + caf.ptCurrentPos.x = videodata->ime_rect.x; + caf.ptCurrentPos.y = videodata->ime_rect.y; + caf.rcArea.left = videodata->ime_rect.x; + caf.rcArea.right = videodata->ime_rect.x + videodata->ime_rect.w; + caf.rcArea.top = videodata->ime_rect.y; + caf.rcArea.bottom = videodata->ime_rect.y + videodata->ime_rect.h; + ImmSetCandidateWindow(himc, &caf); + ImmReleaseContext(videodata->ime_hwnd_current, himc); } } + #ifdef SDL_DISABLE_WINDOWS_IME +void WIN_ClearComposition(_THIS) +{ +} + +SDL_bool WIN_IsTextInputShown(_THIS) +{ + return SDL_FALSE; +} SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata) @@ -324,6 +356,7 @@ DEFINE_GUID(IID_ITfThreadMgrEx, 0x3E90ADE3,0x7594 #define SUBLANG() SUBLANGID(LANG()) static void IME_UpdateInputLocale(SDL_VideoData *videodata); +static int IME_ShowCandidateList(SDL_VideoData *videodata); static void IME_ClearComposition(SDL_VideoData *videodata); static void IME_SetWindow(SDL_VideoData* videodata, HWND hwnd); static void IME_SetupAPI(SDL_VideoData *videodata); @@ -336,6 +369,12 @@ static void UILess_ReleaseSinks(SDL_VideoData *videodata); static void UILess_EnableUIUpdates(SDL_VideoData *videodata); static void UILess_DisableUIUpdates(SDL_VideoData *videodata); +static SDL_bool +WIN_ShouldShowNativeUI() +{ + return SDL_GetHintBoolean(SDL_HINT_IME_SHOW_UI, SDL_FALSE); +} + static void IME_Init(SDL_VideoData *videodata, HWND hwnd) { @@ -370,7 +409,10 @@ IME_Init(SDL_VideoData *videodata, HWND hwnd) videodata->ime_available = SDL_TRUE; IME_UpdateInputLocale(videodata); IME_SetupAPI(videodata); - videodata->ime_uiless = UILess_SetupSinks(videodata); + if (WIN_ShouldShowNativeUI()) + videodata->ime_uiless = SDL_FALSE; + else + videodata->ime_uiless = UILess_SetupSinks(videodata); IME_UpdateInputLocale(videodata); IME_Disable(videodata, hwnd); } @@ -559,16 +601,16 @@ IME_GetId(SDL_VideoData *videodata, UINT uIndex) char szTemp[256]; HKL hkl = 0; DWORD dwLang = 0; - if (uIndex >= sizeof(dwRet) / sizeof(dwRet[0])) - return 0; + SDL_assert(uIndex < sizeof(dwRet) / sizeof(dwRet[0])); hkl = videodata->ime_hkl; if (hklprev == hkl) return dwRet[uIndex]; - hklprev = hkl; + + SDL_assert(uIndex == 0); dwLang = ((DWORD_PTR)hkl & 0xffff); - if (videodata->ime_uiless && LANG() == LANG_CHT) { + if (videodata->ime_uiless && dwLang == LANG_CHT) { dwRet[0] = IMEID_CHT_VER_VISTA; dwRet[1] = 0; return dwRet[0]; @@ -579,11 +621,11 @@ IME_GetId(SDL_VideoData *videodata, UINT uIndex) && hkl != CHT_HKL_HK_CANTONESE && hkl != CHS_HKL) { dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; + return dwRet[0]; } if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0) { dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; + return dwRet[0]; } if (!videodata->GetReadingString) { #define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) @@ -593,7 +635,7 @@ IME_GetId(SDL_VideoData *videodata, UINT uIndex) && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2) { dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; + return dwRet[0]; } #undef LCID_INVARIANT dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle); @@ -632,7 +674,7 @@ IME_GetId(SDL_VideoData *videodata, UINT uIndex) } } dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; + return dwRet[0]; } static void @@ -684,26 +726,13 @@ IME_SetWindow(SDL_VideoData* videodata, HWND hwnd) static void IME_UpdateInputLocale(SDL_VideoData *videodata) { - static HKL hklprev = 0; - videodata->ime_hkl = GetKeyboardLayout(0); - if (hklprev == videodata->ime_hkl) + HKL hklnext = GetKeyboardLayout(0); + + if (hklnext == videodata->ime_hkl) return; - hklprev = videodata->ime_hkl; - switch (PRIMLANG()) { - case LANG_CHINESE: - videodata->ime_candvertical = SDL_TRUE; - if (SUBLANG() == SUBLANG_CHINESE_SIMPLIFIED) - videodata->ime_candvertical = SDL_FALSE; - - break; - case LANG_JAPANESE: - videodata->ime_candvertical = SDL_TRUE; - break; - case LANG_KOREAN: - videodata->ime_candvertical = SDL_FALSE; - break; - } + videodata->ime_hkl = hklnext; + videodata->ime_candvertical = (PRIMLANG() == LANG_KOREAN || LANG() == LANG_CHS) ? SDL_FALSE : SDL_TRUE; } static void @@ -726,30 +755,96 @@ IME_ClearComposition(SDL_VideoData *videodata) SDL_SendEditingText("", 0, 0); } +static SDL_bool +IME_IsTextInputShown(SDL_VideoData* videodata) +{ + if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled) + return SDL_FALSE; + + return videodata->ime_uicontext != 0 ? SDL_TRUE : SDL_FALSE; +} + static void IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string) { - LONG length = ImmGetCompositionStringW(himc, string, videodata->ime_composition, sizeof(videodata->ime_composition) - sizeof(videodata->ime_composition[0])); + LONG length; + DWORD dwLang = ((DWORD_PTR)videodata->ime_hkl & 0xffff); + + length = ImmGetCompositionStringW(himc, string, NULL, 0); + if (length > 0 && videodata->ime_composition_length < length) { + if (videodata->ime_composition != NULL) + SDL_free(videodata->ime_composition); + + videodata->ime_composition = (WCHAR*)SDL_malloc(length + sizeof(WCHAR)); + videodata->ime_composition_length = length; + } + + length = ImmGetCompositionStringW( + himc, + string, + videodata->ime_composition, + videodata->ime_composition_length + ); + if (length < 0) length = 0; - length /= sizeof(videodata->ime_composition[0]); + length /= sizeof(WCHAR); videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0)); - if (videodata->ime_cursor < SDL_arraysize(videodata->ime_composition) && videodata->ime_composition[videodata->ime_cursor] == 0x3000) { + if ((dwLang == LANG_CHT || dwLang == LANG_CHS) && + videodata->ime_cursor > 0 && + videodata->ime_cursor < (int)(videodata->ime_composition_length / sizeof(WCHAR)) && + (videodata->ime_composition[0] == 0x3000 || videodata->ime_composition[0] == 0x0020)) { + // Traditional Chinese IMEs add a placeholder U+3000 + // Simplified Chinese IMEs seem to add a placeholder U+0020 sometimes int i; for (i = videodata->ime_cursor + 1; i < length; ++i) videodata->ime_composition[i - 1] = videodata->ime_composition[i]; --length; } + videodata->ime_composition[length] = 0; + + // Get the correct caret position if we've selected a candidate from the candidate window + if (videodata->ime_cursor == 0 && length > 0) { + Sint32 start = 0; + Sint32 end = 0; + + length = ImmGetCompositionStringW(himc, GCS_COMPATTR, NULL, 0); + if (length > 0) { + Uint8* attributes = (Uint8*)SDL_malloc(length); + ImmGetCompositionString(himc, GCS_COMPATTR, attributes, length); + + for (start = 0; start < length; ++start) { + if (attributes[start] == ATTR_TARGET_CONVERTED || + attributes[start] == ATTR_TARGET_NOTCONVERTED) + break; + } + + for (end = start; end < length; ++end) { + if (attributes[end] != ATTR_TARGET_CONVERTED && + attributes[end] != ATTR_TARGET_NOTCONVERTED) + break; + } + + if (start == length) { + start = 0; + end = length; + } + + SDL_free(attributes); + } + + videodata->ime_cursor = end; + } } static void IME_SendInputEvent(SDL_VideoData *videodata) { char *s = 0; - s = WIN_StringToUTF8(videodata->ime_composition); + s = WIN_StringToUTF8W(videodata->ime_composition); SDL_SendKeyboardText(s); SDL_free(s); @@ -761,48 +856,66 @@ IME_SendInputEvent(SDL_VideoData *videodata) static void IME_SendEditingEvent(SDL_VideoData *videodata) { - char *s = 0; - WCHAR buffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; - const size_t size = SDL_arraysize(buffer); - buffer[0] = 0; + char *s = NULL; + WCHAR *buffer = NULL; + size_t size = videodata->ime_composition_length; if (videodata->ime_readingstring[0]) { size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor); + + size += sizeof(videodata->ime_readingstring); + buffer = (WCHAR*)SDL_malloc(size); + buffer[0] = 0; + SDL_wcslcpy(buffer, videodata->ime_composition, len + 1); SDL_wcslcat(buffer, videodata->ime_readingstring, size); SDL_wcslcat(buffer, &videodata->ime_composition[len], size); } else { + buffer = (WCHAR*)SDL_malloc(size); + buffer[0] = 0; SDL_wcslcpy(buffer, videodata->ime_composition, size); } - s = WIN_StringToUTF8(buffer); + + s = WIN_StringToUTF8W(buffer); SDL_SendEditingText(s, videodata->ime_cursor + (int)SDL_wcslen(videodata->ime_readingstring), 0); SDL_free(s); + SDL_free(buffer); } static void IME_AddCandidate(SDL_VideoData *videodata, UINT i, LPCWSTR candidate) { - LPWSTR dst = videodata->ime_candidates[i]; + LPWSTR dst = &videodata->ime_candidates[i * MAX_CANDLENGTH]; + LPWSTR end = &dst[MAX_CANDLENGTH - 1]; + SDL_COMPILE_TIME_ASSERT(IME_CANDIDATE_INDEXING_REQUIRES, MAX_CANDLIST == 10); *dst++ = (WCHAR)(TEXT('0') + ((i + videodata->ime_candlistindexbase) % 10)); if (videodata->ime_candvertical) *dst++ = TEXT(' '); - while (*candidate && (SDL_arraysize(videodata->ime_candidates[i]) > (dst - videodata->ime_candidates[i]))) + while (*candidate && dst < end) *dst++ = *candidate++; *dst = (WCHAR)'\0'; } static void -IME_GetCandidateList(HIMC himc, SDL_VideoData *videodata) +IME_GetCandidateList(HWND hwnd, SDL_VideoData *videodata) { - LPCANDIDATELIST cand_list = 0; - DWORD size = ImmGetCandidateListW(himc, 0, 0, 0); - if (size) { + HIMC himc; + DWORD size; + LPCANDIDATELIST cand_list; + + if (IME_ShowCandidateList(videodata) < 0) + return; + himc = ImmGetContext(hwnd); + if (!himc) + return; + size = ImmGetCandidateListW(himc, 0, 0, 0); + if (size != 0) { cand_list = (LPCANDIDATELIST)SDL_malloc(size); - if (cand_list) { + if (cand_list != NULL) { size = ImmGetCandidateListW(himc, 0, cand_list, size); - if (size) { + if (size != 0) { UINT i, j; UINT page_start = 0; videodata->ime_candsel = cand_list->dwSelection; @@ -827,34 +940,44 @@ IME_GetCandidateList(HIMC himc, SDL_VideoData *videodata) } videodata->ime_candpgsize = i - page_start; } else { - videodata->ime_candpgsize = SDL_min(cand_list->dwPageSize, MAX_CANDLIST); - if (videodata->ime_candpgsize > 0) { - page_start = (cand_list->dwSelection / videodata->ime_candpgsize) * videodata->ime_candpgsize; - } else { - page_start = 0; - } + videodata->ime_candpgsize = SDL_min(cand_list->dwPageSize == 0 ? MAX_CANDLIST : cand_list->dwPageSize, MAX_CANDLIST); + page_start = (cand_list->dwSelection / videodata->ime_candpgsize) * videodata->ime_candpgsize; } - SDL_memset(&videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); - for (i = page_start, j = 0; (DWORD)i < cand_list->dwCount && j < (int)videodata->ime_candpgsize; i++, j++) { + for (i = page_start, j = 0; (DWORD)i < cand_list->dwCount && j < videodata->ime_candpgsize; i++, j++) { LPCWSTR candidate = (LPCWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[i]); IME_AddCandidate(videodata, j, candidate); } - if (PRIMLANG() == LANG_KOREAN || (PRIMLANG() == LANG_CHT && !IME_GetId(videodata, 0))) - videodata->ime_candsel = -1; + // TODO: why was this necessary? check ime_candvertical instead? PRIMLANG() never equals LANG_CHT ! + //if (PRIMLANG() == LANG_KOREAN || (PRIMLANG() == LANG_CHT && !IME_GetId(videodata, 0))) + // videodata->ime_candsel = -1; } SDL_free(cand_list); } } + ImmReleaseContext(hwnd, himc); } -static void +static int IME_ShowCandidateList(SDL_VideoData *videodata) { + void *candidates; + + videodata->ime_candcount = 0; + candidates = SDL_realloc(videodata->ime_candidates, MAX_CANDSIZE); + if (candidates != NULL) + videodata->ime_candidates = (WCHAR *)candidates; + + if (videodata->ime_candidates == NULL) + return -1; + + SDL_memset(videodata->ime_candidates, 0, MAX_CANDSIZE); + videodata->ime_dirty = SDL_TRUE; videodata->ime_candlist = SDL_TRUE; IME_DestroyTextures(videodata); IME_SendEditingEvent(videodata); + return 0; } static void @@ -875,20 +998,34 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD return SDL_FALSE; switch (msg) { + case WM_KEYDOWN: + if (wParam == VK_PROCESSKEY) + { + videodata->ime_uicontext = 1; + trap = SDL_TRUE; + } + else + videodata->ime_uicontext = 0; + break; case WM_INPUTLANGCHANGE: IME_InputLangChanged(videodata); break; case WM_IME_SETCONTEXT: - *lParam = 0; + if (videodata->ime_uiless) { + *lParam = 0; + } break; - case WM_IME_STARTCOMPOSITION: + case WM_IME_STARTCOMPOSITION: + videodata->ime_suppress_endcomposition_event = SDL_FALSE; trap = SDL_TRUE; break; case WM_IME_COMPOSITION: trap = SDL_TRUE; himc = ImmGetContext(hwnd); if (*lParam & GCS_RESULTSTR) { + videodata->ime_suppress_endcomposition_event = SDL_TRUE; IME_GetCompositionString(videodata, himc, GCS_RESULTSTR); + SDL_SendEditingText("", 0, 0); IME_SendInputEvent(videodata); } if (*lParam & GCS_COMPSTR) { @@ -901,10 +1038,13 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD ImmReleaseContext(hwnd, himc); break; case WM_IME_ENDCOMPOSITION: + videodata->ime_uicontext = 0; videodata->ime_composition[0] = 0; videodata->ime_readingstring[0] = 0; videodata->ime_cursor = 0; - SDL_SendEditingText("", 0, 0); + if (videodata->ime_suppress_endcomposition_event == SDL_FALSE) + SDL_SendEditingText("", 0, 0); + videodata->ime_suppress_endcomposition_event = SDL_FALSE; break; case WM_IME_NOTIFY: switch (wParam) { @@ -918,16 +1058,12 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD break; trap = SDL_TRUE; - IME_ShowCandidateList(videodata); - himc = ImmGetContext(hwnd); - if (!himc) - break; - - IME_GetCandidateList(himc, videodata); - ImmReleaseContext(hwnd, himc); + videodata->ime_uicontext = 1; + IME_GetCandidateList(hwnd, videodata); break; case IMN_CLOSECANDIDATE: trap = SDL_TRUE; + videodata->ime_uicontext = 0; IME_HideCandidateList(videodata); break; case IMN_PRIVATE: @@ -974,7 +1110,8 @@ IME_CloseCandidateList(SDL_VideoData *videodata) { IME_HideCandidateList(videodata); videodata->ime_candcount = 0; - SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); + SDL_free(videodata->ime_candidates); + videodata->ime_candidates = NULL; } static void @@ -987,13 +1124,16 @@ UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pca DWORD pgstart = 0; DWORD pgsize = 0; UINT i, j; + + if (IME_ShowCandidateList(videodata) < 0) + return; + pcandlist->lpVtbl->GetSelection(pcandlist, &selection); pcandlist->lpVtbl->GetCount(pcandlist, &count); pcandlist->lpVtbl->GetCurrentPage(pcandlist, &page); videodata->ime_candsel = selection; videodata->ime_candcount = count; - IME_ShowCandidateList(videodata); pcandlist->lpVtbl->GetPageIndex(pcandlist, 0, 0, &pgcount); if (pgcount > 0) { @@ -1011,8 +1151,6 @@ UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pca } videodata->ime_candpgsize = SDL_min(pgsize, MAX_CANDLIST); videodata->ime_candsel = videodata->ime_candsel - pgstart; - - SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); for (i = pgstart, j = 0; (DWORD)i < count && j < videodata->ime_candpgsize; i++, j++) { BSTR bstr; if (SUCCEEDED(pcandlist->lpVtbl->GetString(pcandlist, i, &bstr))) { @@ -1022,8 +1160,9 @@ UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pca } } } - if (PRIMLANG() == LANG_KOREAN) - videodata->ime_candsel = -1; + // TODO: why was this necessary? check ime_candvertical instead? + //if (PRIMLANG() == LANG_KOREAN) + // videodata->ime_candsel = -1; } STDMETHODIMP_(ULONG) TSFSink_AddRef(TSFSink *sink) @@ -1440,7 +1579,7 @@ IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) SelectObject(hdc, font); for (i = 0; i < candcount; ++i) { - const WCHAR *s = videodata->ime_candidates[i]; + const WCHAR *s = &videodata->ime_candidates[i * MAX_CANDLENGTH]; if (!*s) break; @@ -1502,7 +1641,7 @@ IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) SetBkMode(hdc, TRANSPARENT); for (i = 0; i < candcount; ++i) { - const WCHAR *s = videodata->ime_candidates[i]; + const WCHAR *s = &videodata->ime_candidates[i * MAX_CANDLENGTH]; int left, top, right, bottom; if (!*s) break; @@ -1572,6 +1711,18 @@ void IME_Present(SDL_VideoData *videodata) /* FIXME: Need to show the IME bitmap */ } +SDL_bool WIN_IsTextInputShown(_THIS) +{ + SDL_VideoData* videodata = (SDL_VideoData*)_this->driverdata; + return IME_IsTextInputShown(videodata); +} + +void WIN_ClearComposition(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + IME_ClearComposition(videodata); +} + #endif /* SDL_DISABLE_WINDOWS_IME */ #endif /* SDL_VIDEO_DRIVER_WINDOWS */ diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.h b/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.h index ec20f9a58..97382c7bd 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,6 +32,8 @@ extern void WIN_ResetDeadKeys(void); extern void WIN_StartTextInput(_THIS); extern void WIN_StopTextInput(_THIS); extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect); +extern void WIN_ClearComposition(_THIS); +extern SDL_bool WIN_IsTextInputShown(_THIS); extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata); diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.c b/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.c index 3382a2de8..812f4536f 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -117,7 +117,7 @@ static SDL_bool GetButtonIndex(const SDL_MessageBoxData *messageboxdata, Uint32 return SDL_FALSE; } -static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) { const SDL_MessageBoxData *messageboxdata; size_t buttonindex; @@ -260,7 +260,7 @@ static SDL_bool AddDialogString(WIN_DialogData *dialog, const char *string) string = ""; } - wstring = WIN_UTF8ToString(string); + wstring = WIN_UTF8ToStringW(string); if (!wstring) { return SDL_FALSE; } @@ -645,9 +645,9 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) } /* Measure the *pixel* size of the string. */ - wmessage = WIN_UTF8ToString(messageboxdata->message); + wmessage = WIN_UTF8ToStringW(messageboxdata->message); SDL_zero(TextSize); - DrawText(FontDC, wmessage, -1, &TextSize, DT_CALCRECT | DT_LEFT | DT_NOPREFIX | DT_EDITCONTROL); + DrawTextW(FontDC, wmessage, -1, &TextSize, DT_CALCRECT | DT_LEFT | DT_NOPREFIX | DT_EDITCONTROL); /* Add margins and some padding for hangs, etc. */ TextSize.left += TextMargin; @@ -742,7 +742,7 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) ParentWindow = ((SDL_WindowData*)messageboxdata->window->driverdata)->hwnd; } - result = DialogBoxIndirectParam(NULL, (DLGTEMPLATE*)dialog->lpDialog, ParentWindow, (DLGPROC)MessageBoxDialogProc, (LPARAM)messageboxdata); + result = DialogBoxIndirectParam(NULL, (DLGTEMPLATE*)dialog->lpDialog, ParentWindow, MessageBoxDialogProc, (LPARAM)messageboxdata); if (result >= IDBUTTONINDEX0 && result - IDBUTTONINDEX0 < messageboxdata->numbuttons) { *buttonid = messageboxdata->buttons[result - IDBUTTONINDEX0].buttonid; retval = 0; @@ -798,7 +798,7 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) } /* If we cannot load comctl32.dll use the old messagebox! */ - hComctl32 = LoadLibrary(TEXT("Comctl32.dll")); + hComctl32 = LoadLibrary(TEXT("comctl32.dll")); if (hComctl32 == NULL) { return WIN_ShowOldMessageBox(messageboxdata, buttonid); } @@ -822,8 +822,8 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) ParentWindow = ((SDL_WindowData *) messageboxdata->window->driverdata)->hwnd; } - wmessage = WIN_UTF8ToString(messageboxdata->message); - wtitle = WIN_UTF8ToString(messageboxdata->title); + wmessage = WIN_UTF8ToStringW(messageboxdata->message); + wtitle = WIN_UTF8ToStringW(messageboxdata->title); SDL_zero(TaskConfig); TaskConfig.cbSize = sizeof (TASKDIALOGCONFIG); @@ -872,7 +872,7 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) SDL_free(pButtons); return -1; } - pButton->pszButtonText = WIN_UTF8ToString(buttontext); + pButton->pszButtonText = WIN_UTF8ToStringW(buttontext); if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { TaskConfig.nDefaultButton = pButton->nButtonID; } diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.h b/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.h index 9f1ea00b5..1ffc506e4 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.c b/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.c index d3af5b1e1..9080cc895 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,6 +23,7 @@ #if SDL_VIDEO_DRIVER_WINDOWS #include "SDL_windowsvideo.h" +#include "../../events/SDL_displayevents_c.h" /* Windows CE compatibility */ #ifndef CDS_FULLSCREEN @@ -32,7 +33,7 @@ /* #define DEBUG_MODES */ static void -WIN_UpdateDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) +WIN_UpdateDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_DisplayMode * mode) { SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata; HDC hdc; @@ -108,15 +109,57 @@ WIN_UpdateDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * } } +static SDL_DisplayOrientation +WIN_GetDisplayOrientation(DEVMODE *mode) +{ + int width = mode->dmPelsWidth; + int height = mode->dmPelsHeight; + + /* Use unrotated width/height to guess orientation */ + if (mode->dmDisplayOrientation == DMDO_90 || mode->dmDisplayOrientation == DMDO_270) { + int temp = width; + width = height; + height = temp; + } + + if (width >= height) { + switch (mode->dmDisplayOrientation) { + case DMDO_DEFAULT: + return SDL_ORIENTATION_LANDSCAPE; + case DMDO_90: + return SDL_ORIENTATION_PORTRAIT; + case DMDO_180: + return SDL_ORIENTATION_LANDSCAPE_FLIPPED; + case DMDO_270: + return SDL_ORIENTATION_PORTRAIT_FLIPPED; + default: + return SDL_ORIENTATION_UNKNOWN; + } + } else { + switch (mode->dmDisplayOrientation) { + case DMDO_DEFAULT: + return SDL_ORIENTATION_PORTRAIT; + case DMDO_90: + return SDL_ORIENTATION_LANDSCAPE_FLIPPED; + case DMDO_180: + return SDL_ORIENTATION_PORTRAIT_FLIPPED; + case DMDO_270: + return SDL_ORIENTATION_LANDSCAPE; + default: + return SDL_ORIENTATION_UNKNOWN; + } + } +} + static SDL_bool -WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) +WIN_GetDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_DisplayMode * mode, SDL_DisplayOrientation *orientation) { SDL_DisplayModeData *data; DEVMODE devmode; devmode.dmSize = sizeof(devmode); devmode.dmDriverExtra = 0; - if (!EnumDisplaySettings(deviceName, index, &devmode)) { + if (!EnumDisplaySettingsW(deviceName, index, &devmode)) { return SDL_FALSE; } @@ -135,6 +178,11 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod /* Fill in the mode information */ WIN_UpdateDisplayMode(_this, deviceName, index, mode); + + if (orientation) { + *orientation = WIN_GetDisplayOrientation(&devmode); + } + return SDL_TRUE; } @@ -145,13 +193,14 @@ WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, SDL_bool se SDL_VideoDisplay display; SDL_DisplayData *displaydata; SDL_DisplayMode mode; - DISPLAY_DEVICE device; + SDL_DisplayOrientation orientation; + DISPLAY_DEVICEW device; #ifdef DEBUG_MODES - SDL_Log("Display: %s\n", WIN_StringToUTF8(info->szDevice)); + SDL_Log("Display: %s\n", WIN_StringToUTF8W(info->szDevice)); #endif - if (!WIN_GetDisplayMode(_this, info->szDevice, ENUM_CURRENT_SETTINGS, &mode)) { + if (!WIN_GetDisplayMode(_this, info->szDevice, ENUM_CURRENT_SETTINGS, &mode, &orientation)) { return SDL_FALSE; } @@ -163,6 +212,13 @@ WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, SDL_bool se if (SDL_wcscmp(driverdata->DeviceName, info->szDevice) == 0) { driverdata->MonitorHandle = hMonitor; driverdata->IsValid = SDL_TRUE; + + if (!_this->setting_display_mode) { + SDL_ResetDisplayModes(i); + SDL_SetCurrentDisplayMode(&_this->displays[i], &mode); + SDL_SetDesktopDisplayMode(&_this->displays[i], &mode); + SDL_SendDisplayEvent(&_this->displays[i], SDL_DISPLAYEVENT_ORIENTATION, orientation); + } return SDL_FALSE; } } @@ -178,11 +234,12 @@ WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, SDL_bool se SDL_zero(display); device.cb = sizeof(device); - if (EnumDisplayDevices(info->szDevice, 0, &device, 0)) { - display.name = WIN_StringToUTF8(device.DeviceString); + if (EnumDisplayDevicesW(info->szDevice, 0, &device, 0)) { + display.name = WIN_StringToUTF8W(device.DeviceString); } display.desktop_mode = mode; display.current_mode = mode; + display.orientation = orientation; display.driverdata = displaydata; SDL_AddVideoDisplay(&display, send_event); SDL_free(display.name); @@ -356,8 +413,8 @@ WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display) DWORD i; SDL_DisplayMode mode; - for (i = 0;; ++i) { - if (!WIN_GetDisplayMode(_this, data->DeviceName, i, &mode)) { + for (i = 0; ; ++i) { + if (!WIN_GetDisplayMode(_this, data->DeviceName, i, &mode, NULL)) { break; } if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) { @@ -383,9 +440,9 @@ WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) LONG status; if (mode->driverdata == display->desktop_mode.driverdata) { - status = ChangeDisplaySettingsEx(displaydata->DeviceName, NULL, NULL, CDS_FULLSCREEN, NULL); + status = ChangeDisplaySettingsExW(displaydata->DeviceName, NULL, NULL, CDS_FULLSCREEN, NULL); } else { - status = ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode, NULL, CDS_FULLSCREEN, NULL); + status = ChangeDisplaySettingsExW(displaydata->DeviceName, &data->DeviceMode, NULL, CDS_FULLSCREEN, NULL); } if (status != DISP_CHANGE_SUCCESSFUL) { const char *reason = "Unknown reason"; @@ -405,7 +462,7 @@ WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) } return SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason); } - EnumDisplaySettings(displaydata->DeviceName, ENUM_CURRENT_SETTINGS, &data->DeviceMode); + EnumDisplaySettingsW(displaydata->DeviceName, ENUM_CURRENT_SETTINGS, &data->DeviceMode); WIN_UpdateDisplayMode(_this, displaydata->DeviceName, ENUM_CURRENT_SETTINGS, mode); return 0; } diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.h b/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.h index 431724221..0f2cdf489 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsmouse.c b/Engine/lib/sdl/src/video/windows/SDL_windowsmouse.c index 826cbb2cf..bc4ba6326 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsmouse.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,11 +27,13 @@ #include "../../events/SDL_mouse_c.h" +DWORD SDL_last_warp_time = 0; HCURSOR SDL_cursor = NULL; +static SDL_Cursor *SDL_blank_cursor = NULL; static int rawInputEnableCount = 0; -static int +static int ToggleRawInput(SDL_bool enabled) { RAWINPUTDEVICE rawMouse = { 0x01, 0x02, 0, NULL }; /* Mouse: UsagePage = 1, Usage = 2 */ @@ -57,6 +59,9 @@ ToggleRawInput(SDL_bool enabled) /* (Un)register raw input for mice */ if (RegisterRawInputDevices(&rawMouse, 1, sizeof(RAWINPUTDEVICE)) == FALSE) { + /* Reset the enable count, otherwise subsequent enable calls will + believe raw input is enabled */ + rawInputEnableCount = 0; /* Only return an error when registering. If we unregister and fail, then it's probably that we unregistered twice. That's OK. */ @@ -91,6 +96,7 @@ WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) const size_t pad = (sizeof (size_t) * 8); /* 32 or 64, or whatever. */ SDL_Cursor *cursor; HICON hicon; + HICON hcursor; HDC hdc; BITMAPV4HEADER bmh; LPVOID pixels; @@ -145,17 +151,39 @@ WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) return NULL; } + /* The cursor returned by CreateIconIndirect does not respect system cursor size + preference, use CopyImage to duplicate the cursor with desired sizes */ + hcursor = CopyImage(hicon, IMAGE_CURSOR, surface->w, surface->h, 0); + DestroyIcon(hicon); + + if (!hcursor) { + WIN_SetError("CopyImage()"); + return NULL; + } + cursor = SDL_calloc(1, sizeof(*cursor)); if (cursor) { - cursor->driverdata = hicon; + cursor->driverdata = hcursor; } else { - DestroyIcon(hicon); + DestroyIcon(hcursor); SDL_OutOfMemory(); } return cursor; } +static SDL_Cursor * +WIN_CreateBlankCursor() +{ + SDL_Cursor *cursor = NULL; + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, 32, 32, 32, SDL_PIXELFORMAT_ARGB8888); + if (surface) { + cursor = WIN_CreateCursor(surface, 0, 0); + SDL_FreeSurface(surface); + } + return cursor; +} + static SDL_Cursor * WIN_CreateSystemCursor(SDL_SystemCursor id) { @@ -207,6 +235,9 @@ WIN_FreeCursor(SDL_Cursor * cursor) static int WIN_ShowCursor(SDL_Cursor * cursor) { + if (!cursor) { + cursor = SDL_blank_cursor; + } if (cursor) { SDL_cursor = (HCURSOR)cursor->driverdata; } else { @@ -218,6 +249,21 @@ WIN_ShowCursor(SDL_Cursor * cursor) return 0; } +void +WIN_SetCursorPos(int x, int y) +{ + /* We need to jitter the value because otherwise Windows will occasionally inexplicably ignore the SetCursorPos() or SendInput() */ + SetCursorPos(x, y); + SetCursorPos(x+1, y); + SetCursorPos(x, y); + + /* Flush any mouse motion prior to or associated with this warp */ + SDL_last_warp_time = GetTickCount(); + if (!SDL_last_warp_time) { + SDL_last_warp_time = 1; + } +} + static void WIN_WarpMouse(SDL_Window * window, int x, int y) { @@ -233,7 +279,10 @@ WIN_WarpMouse(SDL_Window * window, int x, int y) pt.x = x; pt.y = y; ClientToScreen(hwnd, &pt); - SetCursorPos(pt.x, pt.y); + WIN_SetCursorPos(pt.x, pt.y); + + /* Send the exact mouse motion associated with this warp */ + SDL_SendMouseMotion(window, SDL_GetMouse()->mouseID, 0, x, y); } static int @@ -256,18 +305,22 @@ WIN_SetRelativeMouseMode(SDL_bool enabled) static int WIN_CaptureMouse(SDL_Window *window) { - if (!window) { - SDL_Window *focusWin = SDL_GetKeyboardFocus(); - if (focusWin) { - WIN_OnWindowEnter(SDL_GetVideoDevice(), focusWin); /* make sure WM_MOUSELEAVE messages are (re)enabled. */ + if (window) { + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SetCapture(data->hwnd); + } else { + SDL_Window *focus_window = SDL_GetMouseFocus(); + + if (focus_window) { + SDL_WindowData *data = (SDL_WindowData *)focus_window->driverdata; + if (!data->mouse_tracked) { + SDL_SetMouseFocus(NULL); + } } + ReleaseCapture(); } - /* While we were thinking of SetCapture() when designing this API in SDL, - we didn't count on the fact that SetCapture() only tracks while the - left mouse button is held down! Instead, we listen for raw mouse input - and manually query the mouse when it leaves the window. :/ */ - return ToggleRawInput(window != NULL); + return 0; } static Uint32 @@ -306,6 +359,8 @@ WIN_InitMouse(_THIS) mouse->GetGlobalMouseState = WIN_GetGlobalMouseState; SDL_SetDefaultCursor(WIN_CreateDefaultCursor()); + + SDL_blank_cursor = WIN_CreateBlankCursor(); } void @@ -315,6 +370,11 @@ WIN_QuitMouse(_THIS) rawInputEnableCount = 1; ToggleRawInput(SDL_FALSE); } + + if (SDL_blank_cursor) { + WIN_FreeCursor(SDL_blank_cursor); + SDL_blank_cursor = NULL; + } } #endif /* SDL_VIDEO_DRIVER_WINDOWS */ diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsmouse.h b/Engine/lib/sdl/src/video/windows/SDL_windowsmouse.h index 72122103d..fd1a8a323 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsmouse.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,10 +23,12 @@ #ifndef SDL_windowsmouse_h_ #define SDL_windowsmouse_h_ +extern DWORD SDL_last_warp_time; extern HCURSOR SDL_cursor; extern void WIN_InitMouse(_THIS); extern void WIN_QuitMouse(_THIS); +extern void WIN_SetCursorPos(int x, int y); #endif /* SDL_windowsmouse_h_ */ diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsopengl.c b/Engine/lib/sdl/src/video/windows/SDL_windowsopengl.c index e0a4ba7d0..0c99ca9a6 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsopengl.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsopengl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsopengl.h b/Engine/lib/sdl/src/video/windows/SDL_windowsopengl.h index 003f1f6e7..2dec0023a 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsopengl.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsopengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsopengles.c b/Engine/lib/sdl/src/video/windows/SDL_windowsopengles.c index 5ee46d83c..eedc0e6ab 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsopengles.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -108,7 +108,10 @@ WIN_GLES_SetupWindow(_THIS, SDL_Window * window) SDL_GLContext current_ctx = SDL_GL_GetCurrentContext(); if (_this->egl_data == NULL) { + /* !!! FIXME: commenting out this assertion is (I think) incorrect; figure out why driver_loaded is wrong for ANGLE instead. --ryan. */ + #if 0 /* When hint SDL_HINT_OPENGL_ES_DRIVER is set to "1" (e.g. for ANGLE support), _this->gl_config.driver_loaded can be 1, while the below lines function. */ SDL_assert(!_this->gl_config.driver_loaded); + #endif if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0) < 0) { SDL_EGL_UnloadLibrary(_this); return -1; diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsopengles.h b/Engine/lib/sdl/src/video/windows/SDL_windowsopengles.h index 6ac5f7b63..b21c56f4f 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsopengles.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsshape.c b/Engine/lib/sdl/src/video/windows/SDL_windowsshape.c index 953cb2478..7af545d94 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsshape.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsshape.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsshape.h b/Engine/lib/sdl/src/video/windows/SDL_windowsshape.h index a5c786e8a..982807357 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsshape.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsshape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowstaskdialog.h b/Engine/lib/sdl/src/video/windows/SDL_windowstaskdialog.h index 707d54db2..cd13d12d0 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowstaskdialog.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowstaskdialog.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.c b/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.c index 3aa93d3e2..4bd2a9831 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -87,7 +87,9 @@ WIN_DeleteDevice(SDL_VideoDevice * device) if (data->shcoreDLL) { SDL_UnloadObject(data->shcoreDLL); } - + if (device->wakeup_lock) { + SDL_DestroyMutex(device->wakeup_lock); + } SDL_free(device->driverdata); SDL_free(device); } @@ -113,6 +115,7 @@ WIN_CreateDevice(int devindex) return NULL; } device->driverdata = data; + device->wakeup_lock = SDL_CreateMutex(); data->userDLL = SDL_LoadObject("USER32.DLL"); if (data->userDLL) { @@ -139,6 +142,8 @@ WIN_CreateDevice(int devindex) device->GetDisplayModes = WIN_GetDisplayModes; device->SetDisplayMode = WIN_SetDisplayMode; device->PumpEvents = WIN_PumpEvents; + device->WaitEventTimeout = WIN_WaitEventTimeout; + device->SendWakeupEvent = WIN_SendWakeupEvent; device->SuspendScreenSaver = WIN_SuspendScreenSaver; device->CreateSDLWindow = WIN_CreateWindow; @@ -157,10 +162,14 @@ WIN_CreateDevice(int devindex) device->RestoreWindow = WIN_RestoreWindow; device->SetWindowBordered = WIN_SetWindowBordered; device->SetWindowResizable = WIN_SetWindowResizable; + device->SetWindowAlwaysOnTop = WIN_SetWindowAlwaysOnTop; device->SetWindowFullscreen = WIN_SetWindowFullscreen; device->SetWindowGammaRamp = WIN_SetWindowGammaRamp; + device->GetWindowICCProfile = WIN_GetWindowICCProfile; device->GetWindowGammaRamp = WIN_GetWindowGammaRamp; - device->SetWindowGrab = WIN_SetWindowGrab; + device->SetWindowMouseRect = WIN_SetWindowMouseRect; + device->SetWindowMouseGrab = WIN_SetWindowMouseGrab; + device->SetWindowKeyboardGrab = WIN_SetWindowKeyboardGrab; device->DestroyWindow = WIN_DestroyWindow; device->GetWindowWMInfo = WIN_GetWindowWMInfo; device->CreateWindowFramebuffer = WIN_CreateWindowFramebuffer; @@ -169,6 +178,7 @@ WIN_CreateDevice(int devindex) device->OnWindowEnter = WIN_OnWindowEnter; device->SetWindowHitTest = WIN_SetWindowHitTest; device->AcceptDragAndDrop = WIN_AcceptDragAndDrop; + device->FlashWindow = WIN_FlashWindow; device->shape_driver.CreateShaper = Win32_CreateShaper; device->shape_driver.SetWindowShape = Win32_SetWindowShape; @@ -184,7 +194,7 @@ WIN_CreateDevice(int devindex) device->GL_GetSwapInterval = WIN_GL_GetSwapInterval; device->GL_SwapWindow = WIN_GL_SwapWindow; device->GL_DeleteContext = WIN_GL_DeleteContext; -#elif SDL_VIDEO_OPENGL_EGL +#elif SDL_VIDEO_OPENGL_EGL /* Use EGL based functions */ device->GL_LoadLibrary = WIN_GLES_LoadLibrary; device->GL_GetProcAddress = WIN_GLES_GetProcAddress; @@ -206,6 +216,8 @@ WIN_CreateDevice(int devindex) device->StartTextInput = WIN_StartTextInput; device->StopTextInput = WIN_StopTextInput; device->SetTextInputRect = WIN_SetTextInputRect; + device->ClearComposition = WIN_ClearComposition; + device->IsTextInputShown = WIN_IsTextInputShown; device->SetClipboardText = WIN_SetClipboardText; device->GetClipboardText = WIN_GetClipboardText; @@ -224,6 +236,8 @@ VideoBootStrap WINDOWS_bootstrap = { int WIN_VideoInit(_THIS) { + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + if (WIN_InitModes(_this) < 0) { return -1; } @@ -234,6 +248,8 @@ WIN_VideoInit(_THIS) SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL); SDL_AddHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL); + data->_SDL_WAKEUP = RegisterWindowMessageA("_SDL_WAKEUP"); + return 0; } @@ -249,7 +265,7 @@ WIN_VideoQuit(_THIS) #define D3D_DEBUG_INFO #include -SDL_bool +SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface) { *pD3DDLL = SDL_LoadObject("D3D9.DLL"); @@ -257,24 +273,24 @@ D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface) typedef IDirect3D9 *(WINAPI *Direct3DCreate9_t) (UINT SDKVersion); Direct3DCreate9_t Direct3DCreate9Func; -#ifdef USE_D3D9EX - typedef HRESULT (WINAPI *Direct3DCreate9Ex_t)(UINT SDKVersion, IDirect3D9Ex **ppD3D); - Direct3DCreate9Ex_t Direct3DCreate9ExFunc; + if (SDL_GetHintBoolean(SDL_HINT_WINDOWS_USE_D3D9EX, SDL_FALSE)) { + typedef HRESULT(WINAPI* Direct3DCreate9Ex_t)(UINT SDKVersion, IDirect3D9Ex** ppD3D); + Direct3DCreate9Ex_t Direct3DCreate9ExFunc; - Direct3DCreate9ExFunc = (Direct3DCreate9Ex_t)SDL_LoadFunction(*pD3DDLL, "Direct3DCreate9Ex"); - if (Direct3DCreate9ExFunc) { - IDirect3D9Ex *pDirect3D9ExInterface; - HRESULT hr = Direct3DCreate9ExFunc(D3D_SDK_VERSION, &pDirect3D9ExInterface); - if (SUCCEEDED(hr)) { - const GUID IDirect3D9_GUID = { 0x81bdcbca, 0x64d4, 0x426d, { 0xae, 0x8d, 0xad, 0x1, 0x47, 0xf4, 0x27, 0x5c } }; - hr = IDirect3D9Ex_QueryInterface(pDirect3D9ExInterface, &IDirect3D9_GUID, (void**)pDirect3D9Interface); - IDirect3D9Ex_Release(pDirect3D9ExInterface); + Direct3DCreate9ExFunc = (Direct3DCreate9Ex_t)SDL_LoadFunction(*pD3DDLL, "Direct3DCreate9Ex"); + if (Direct3DCreate9ExFunc) { + IDirect3D9Ex* pDirect3D9ExInterface; + HRESULT hr = Direct3DCreate9ExFunc(D3D_SDK_VERSION, &pDirect3D9ExInterface); if (SUCCEEDED(hr)) { - return SDL_TRUE; + const GUID IDirect3D9_GUID = { 0x81bdcbca, 0x64d4, 0x426d, { 0xae, 0x8d, 0xad, 0x1, 0x47, 0xf4, 0x27, 0x5c } }; + hr = IDirect3D9Ex_QueryInterface(pDirect3D9ExInterface, &IDirect3D9_GUID, (void**)pDirect3D9Interface); + IDirect3D9Ex_Release(pDirect3D9ExInterface); + if (SUCCEEDED(hr)) { + return SDL_TRUE; + } } } } -#endif /* USE_D3D9EX */ Direct3DCreate9Func = (Direct3DCreate9_t)SDL_LoadFunction(*pD3DDLL, "Direct3DCreate9"); if (Direct3DCreate9Func) { @@ -308,7 +324,7 @@ SDL_Direct3D9GetAdapterIndex(int displayIndex) SDL_SetError("Invalid display index"); adapterIndex = -1; /* make sure we return something invalid */ } else { - char *displayName = WIN_StringToUTF8(pData->DeviceName); + char *displayName = WIN_StringToUTF8W(pData->DeviceName); unsigned int count = IDirect3D9_GetAdapterCount(pD3D); unsigned int i; for (i=0; iDeviceName); + displayName = WIN_StringToUTF8W(pData->DeviceName); nAdapter = 0; while (*adapterIndex == -1 && SUCCEEDED(IDXGIFactory_EnumAdapters(pDXGIFactory, nAdapter, &pDXGIAdapter))) { nOutput = 0; while (*adapterIndex == -1 && SUCCEEDED(IDXGIAdapter_EnumOutputs(pDXGIAdapter, nOutput, &pDXGIOutput))) { DXGI_OUTPUT_DESC outputDesc; if (SUCCEEDED(IDXGIOutput_GetDesc(pDXGIOutput, &outputDesc))) { - char *outputName = WIN_StringToUTF8(outputDesc.DeviceName); + char *outputName = WIN_StringToUTF8W(outputDesc.DeviceName); if (SDL_strcmp(outputName, displayName) == 0) { *adapterIndex = nAdapter; *outputIndex = nOutput; diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.h b/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.h index c701bf56c..d4208c405 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,6 +37,7 @@ #define MAX_CANDLIST 10 #define MAX_CANDLENGTH 256 +#define MAX_CANDSIZE (sizeof(WCHAR) * MAX_CANDLIST * MAX_CANDLENGTH) #include "SDL_windowsclipboard.h" #include "SDL_windowsevents.h" @@ -85,6 +86,8 @@ typedef enum MONITOR_DPI_TYPE { MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE; +#else +#include #endif /* WINVER < 0x0603 */ typedef BOOL (*PFNSHFullScreen)(HWND, DWORD); @@ -148,14 +151,16 @@ typedef struct SDL_VideoData SDL_bool ime_available; HWND ime_hwnd_main; HWND ime_hwnd_current; + SDL_bool ime_suppress_endcomposition_event; HIMC ime_himc; - WCHAR ime_composition[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; + WCHAR* ime_composition; + int ime_composition_length; WCHAR ime_readingstring[16]; int ime_cursor; SDL_bool ime_candlist; - WCHAR ime_candidates[MAX_CANDLIST][MAX_CANDLENGTH]; + WCHAR* ime_candidates; DWORD ime_candcount; DWORD ime_candref; DWORD ime_candsel; @@ -186,6 +191,10 @@ typedef struct SDL_VideoData DWORD ime_convmodesinkcookie; TSFSink *ime_uielemsink; TSFSink *ime_ippasink; + LONG ime_uicontext; + + BYTE pre_hook_key_state[256]; + UINT _SDL_WAKEUP; } SDL_VideoData; extern SDL_bool g_WindowsEnableMessageLoop; diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsvulkan.c b/Engine/lib/sdl/src/video/windows/SDL_windowsvulkan.c index 803f8db82..2a66f4398 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsvulkan.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsvulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsvulkan.h b/Engine/lib/sdl/src/video/windows/SDL_windowsvulkan.h index edf02b8d6..eda37d362 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsvulkan.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c b/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c index 61f12eda2..890d790ea 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,6 +28,7 @@ #include "../SDL_pixels_c.h" #include "../../events/SDL_keyboard_c.h" #include "../../events/SDL_mouse_c.h" +#include "../../SDL_hints_c.h" #include "SDL_windowsvideo.h" #include "SDL_windowswindow.h" @@ -47,20 +48,21 @@ /* Fake window to help with DirectInput events. */ HWND SDL_HelperWindow = NULL; -static WCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher"); -static WCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow"); +static const TCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher"); +static const TCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow"); static ATOM SDL_HelperWindowClass = 0; -/* For borderless Windows, still want the following flags: +/* For borderless Windows, still want the following flag: + - WS_MINIMIZEBOX: window will respond to Windows minimize commands sent to all windows, such as windows key + m, shaking title bar, etc. + Additionally, non-fullscreen windows can add: - WS_CAPTION: this seems to enable the Windows minimize animation - WS_SYSMENU: enables system context menu on task bar - - WS_MINIMIZEBOX: window will respond to Windows minimize commands sent to all windows, such as windows key + m, shaking title bar, etc. This will also cause the task bar to overlap the window and other windowed behaviors, so only use this for windows that shouldn't appear to be fullscreen */ #define STYLE_BASIC (WS_CLIPSIBLINGS | WS_CLIPCHILDREN) -#define STYLE_FULLSCREEN (WS_POPUP) -#define STYLE_BORDERLESS (WS_POPUP) +#define STYLE_FULLSCREEN (WS_POPUP | WS_MINIMIZEBOX) +#define STYLE_BORDERLESS (WS_POPUP | WS_MINIMIZEBOX) #define STYLE_BORDERLESS_WINDOWED (WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX) #define STYLE_NORMAL (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX) #define STYLE_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX) @@ -162,13 +164,20 @@ WIN_SetWindowPositionInternal(_THIS, SDL_Window * window, UINT flags) top = HWND_NOTOPMOST; } - WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_TRUE); + WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_TRUE); data->expected_resize = SDL_TRUE; SetWindowPos(hwnd, top, x, y, w, h, flags); data->expected_resize = SDL_FALSE; } +static void SDLCALL +WIN_MouseRelativeModeCenterChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_WindowData *data = (SDL_WindowData *)userdata; + data->mouse_relative_mode_center = SDL_GetStringBoolean(hint, SDL_TRUE); +} + static int SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool created) { @@ -186,11 +195,14 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool cre data->hdc = GetDC(hwnd); data->hinstance = (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE); data->created = created; - data->mouse_button_flags = 0; + data->high_surrogate = 0; + data->mouse_button_flags = (WPARAM)-1; data->last_pointer_update = (LPARAM)-1; data->videodata = videodata; data->initializing = SDL_TRUE; + SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, WIN_MouseRelativeModeCenterChanged, data); + window->driverdata = data; /* Associate the data with the window */ @@ -280,15 +292,8 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool cre } if (GetFocus() == hwnd) { window->flags |= SDL_WINDOW_INPUT_FOCUS; - SDL_SetKeyboardFocus(data->window); - - if (window->flags & SDL_WINDOW_INPUT_GRABBED) { - RECT rect; - GetClientRect(hwnd, &rect); - ClientToScreen(hwnd, (LPPOINT) & rect); - ClientToScreen(hwnd, (LPPOINT) & rect + 1); - ClipCursor(&rect); - } + SDL_SetKeyboardFocus(window); + WIN_UpdateClipCursor(window); } /* Enable multi-touch */ @@ -302,7 +307,39 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool cre return 0; } +static void CleanupWindowData(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + if (data) { + SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, WIN_MouseRelativeModeCenterChanged, data); + + if (data->keyboard_hook) { + UnhookWindowsHookEx(data->keyboard_hook); + } + ReleaseDC(data->hwnd, data->hdc); + RemoveProp(data->hwnd, TEXT("SDL_WindowData")); + if (data->created) { + DestroyWindow(data->hwnd); + if (data->parent) { + DestroyWindow(data->parent); + } + } else { + /* Restore any original event handler... */ + if (data->wndproc != NULL) { +#ifdef GWLP_WNDPROC + SetWindowLongPtr(data->hwnd, GWLP_WNDPROC, + (LONG_PTR) data->wndproc); +#else + SetWindowLong(data->hwnd, GWL_WNDPROC, + (LONG_PTR) data->wndproc); +#endif + } + } + SDL_free(data); + } + window->driverdata = NULL; +} int WIN_CreateWindow(_THIS, SDL_Window * window) @@ -364,7 +401,7 @@ WIN_CreateWindow(_THIS, SDL_Window * window) return 0; #else return SDL_SetError("Could not create GLES window surface (EGL support not configured)"); -#endif /* SDL_VIDEO_OPENGL_EGL */ +#endif /* SDL_VIDEO_OPENGL_EGL */ } #endif /* SDL_VIDEO_OPENGL_ES2 */ @@ -427,6 +464,9 @@ WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) } } } + } else if (window->flags & SDL_WINDOW_OPENGL) { + /* Try to set up the pixel format, if it hasn't been set by the application */ + WIN_GL_SetupWindow(_this, window); } } #endif @@ -448,39 +488,40 @@ WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; HICON hicon = NULL; BYTE *icon_bmp; - int icon_len, mask_len, y; - SDL_RWops *dst; + int icon_len, mask_len, row_len, y; + BITMAPINFOHEADER *bmi; + Uint8 *dst; SDL_bool isstack; /* Create temporary buffer for ICONIMAGE structure */ + SDL_COMPILE_TIME_ASSERT(WIN_SetWindowIcon_uses_BITMAPINFOHEADER_to_prepare_an_ICONIMAGE, sizeof(BITMAPINFOHEADER) == 40); mask_len = (icon->h * (icon->w + 7)/8); - icon_len = 40 + icon->h * icon->w * sizeof(Uint32) + mask_len; + icon_len = sizeof(BITMAPINFOHEADER) + icon->h * icon->w * sizeof(Uint32) + mask_len; icon_bmp = SDL_small_alloc(BYTE, icon_len, &isstack); - dst = SDL_RWFromMem(icon_bmp, icon_len); - if (!dst) { - SDL_small_free(icon_bmp, isstack); - return; - } /* Write the BITMAPINFO header */ - SDL_WriteLE32(dst, 40); - SDL_WriteLE32(dst, icon->w); - SDL_WriteLE32(dst, icon->h * 2); - SDL_WriteLE16(dst, 1); - SDL_WriteLE16(dst, 32); - SDL_WriteLE32(dst, BI_RGB); - SDL_WriteLE32(dst, icon->h * icon->w * sizeof(Uint32)); - SDL_WriteLE32(dst, 0); - SDL_WriteLE32(dst, 0); - SDL_WriteLE32(dst, 0); - SDL_WriteLE32(dst, 0); + bmi = (BITMAPINFOHEADER *)icon_bmp; + bmi->biSize = SDL_SwapLE32(sizeof(BITMAPINFOHEADER)); + bmi->biWidth = SDL_SwapLE32(icon->w); + bmi->biHeight = SDL_SwapLE32(icon->h * 2); + bmi->biPlanes = SDL_SwapLE16(1); + bmi->biBitCount = SDL_SwapLE16(32); + bmi->biCompression = SDL_SwapLE32(BI_RGB); + bmi->biSizeImage = SDL_SwapLE32(icon->h * icon->w * sizeof(Uint32)); + bmi->biXPelsPerMeter = SDL_SwapLE32(0); + bmi->biYPelsPerMeter = SDL_SwapLE32(0); + bmi->biClrUsed = SDL_SwapLE32(0); + bmi->biClrImportant = SDL_SwapLE32(0); /* Write the pixels upside down into the bitmap buffer */ SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888); + dst = &icon_bmp[sizeof(BITMAPINFOHEADER)]; + row_len = icon->w * sizeof(Uint32); y = icon->h; while (y--) { Uint8 *src = (Uint8 *) icon->pixels + y * icon->pitch; - SDL_RWwrite(dst, src, icon->w * sizeof(Uint32), 1); + SDL_memcpy(dst, src, row_len); + dst += row_len; } /* Write the mask */ @@ -488,7 +529,6 @@ WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000); - SDL_RWclose(dst); SDL_small_free(icon_bmp, isstack); /* Set the icon for the window */ @@ -559,9 +599,9 @@ WIN_ShowWindow(_THIS, SDL_Window * window) DWORD style; HWND hwnd; int nCmdShow; - + hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; - nCmdShow = SW_SHOW; + nCmdShow = SDL_GetHintBoolean(SDL_HINT_WINDOW_NO_ACTIVATION_WHEN_SHOWN, SDL_FALSE) ? SW_SHOWNA : SW_SHOW; style = GetWindowLong(hwnd, GWL_EXSTYLE); if (style & WS_EX_NOACTIVATE) { nCmdShow = SW_SHOWNOACTIVATE; @@ -579,8 +619,38 @@ WIN_HideWindow(_THIS, SDL_Window * window) void WIN_RaiseWindow(_THIS, SDL_Window * window) { + /* If desired, raise the window more forcefully. + * Technique taken from http://stackoverflow.com/questions/916259/ . + * Specifically, http://stackoverflow.com/a/34414846 . + * + * The issue is that Microsoft has gone through a lot of trouble to make it + * nearly impossible to programmatically move a window to the foreground, + * for "security" reasons. Apparently, the following song-and-dance gets + * around their objections. */ + SDL_bool bForce = SDL_GetHintBoolean(SDL_HINT_FORCE_RAISEWINDOW, SDL_FALSE); + + HWND hCurWnd = NULL; + DWORD dwMyID = 0u; + DWORD dwCurID = 0u; + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + if(bForce) + { + hCurWnd = GetForegroundWindow(); + dwMyID = GetCurrentThreadId(); + dwCurID = GetWindowThreadProcessId(hCurWnd, NULL); + ShowWindow(hwnd, SW_RESTORE); + AttachThreadInput(dwCurID, dwMyID, TRUE); + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + } SetForegroundWindow(hwnd); + if (bForce) + { + AttachThreadInput(dwCurID, dwMyID, FALSE); + SetFocus(hwnd); + SetActiveWindow(hwnd); + } } void @@ -631,6 +701,18 @@ WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) SetWindowLong(hwnd, GWL_STYLE, style); } +void +WIN_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + if (on_top) { + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } else { + SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } +} + void WIN_RestoreWindow(_THIS, SDL_Window * window) { @@ -708,7 +790,7 @@ WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) HDC hdc; BOOL succeeded = FALSE; - hdc = CreateDC(data->DeviceName, NULL, NULL, NULL); + hdc = CreateDCW(data->DeviceName, NULL, NULL, NULL); if (hdc) { succeeded = SetDeviceGammaRamp(hdc, (LPVOID)ramp); if (!succeeded) { @@ -719,6 +801,32 @@ WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) return succeeded ? 0 : -1; } +void* +WIN_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size) +{ + SDL_VideoDisplay* display = SDL_GetDisplayForWindow(window); + SDL_DisplayData* data = (SDL_DisplayData*)display->driverdata; + HDC hdc; + BOOL succeeded = FALSE; + WCHAR filename[MAX_PATH]; + DWORD fileNameSize = MAX_PATH; + void* iccProfileData = NULL; + + hdc = CreateDCW(data->DeviceName, NULL, NULL, NULL); + if (hdc) { + succeeded = GetICMProfileW(hdc, &fileNameSize, filename); + DeleteDC(hdc); + } + + if (succeeded) { + iccProfileData = SDL_LoadFile(WIN_StringToUTF8(filename), size); + if (!iccProfileData) + SDL_SetError("Could not open ICC profile"); + } + + return iccProfileData; +} + int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) { @@ -727,7 +835,7 @@ WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) HDC hdc; BOOL succeeded = FALSE; - hdc = CreateDC(data->DeviceName, NULL, NULL, NULL); + hdc = CreateDCW(data->DeviceName, NULL, NULL, NULL); if (hdc) { succeeded = GetDeviceGammaRamp(hdc, (LPVOID)ramp); if (!succeeded) { @@ -738,49 +846,76 @@ WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) return succeeded ? 0 : -1; } +static void WIN_GrabKeyboard(SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HMODULE module; + + if (data->keyboard_hook) { + return; + } + + /* SetWindowsHookEx() needs to know which module contains the hook we + want to install. This is complicated by the fact that SDL can be + linked statically or dynamically. Fortunately XP and later provide + this nice API that will go through the loaded modules and find the + one containing our code. + */ + if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + (LPTSTR)WIN_KeyboardHookProc, + &module)) { + return; + } + + /* Capture a snapshot of the current keyboard state before the hook */ + if (!GetKeyboardState(data->videodata->pre_hook_key_state)) { + return; + } + + /* To grab the keyboard, we have to install a low-level keyboard hook to + intercept keys that would normally be captured by the OS. Intercepting + all key events on the system is rather invasive, but it's what Microsoft + actually documents that you do to capture these. + */ + data->keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, WIN_KeyboardHookProc, module, 0); +} + +void WIN_UngrabKeyboard(SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + + if (data->keyboard_hook) { + UnhookWindowsHookEx(data->keyboard_hook); + data->keyboard_hook = NULL; + } +} + void -WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +WIN_SetWindowMouseRect(_THIS, SDL_Window * window) { WIN_UpdateClipCursor(window); +} - if (window->flags & SDL_WINDOW_FULLSCREEN) { - UINT flags = SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE; +void +WIN_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + WIN_UpdateClipCursor(window); +} - if (!(window->flags & SDL_WINDOW_SHOWN)) { - flags |= SWP_NOACTIVATE; - } - WIN_SetWindowPositionInternal(_this, window, flags); +void +WIN_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + if (grabbed) { + WIN_GrabKeyboard(window); + } else { + WIN_UngrabKeyboard(window); } } void WIN_DestroyWindow(_THIS, SDL_Window * window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - - if (data) { - ReleaseDC(data->hwnd, data->hdc); - RemoveProp(data->hwnd, TEXT("SDL_WindowData")); - if (data->created) { - DestroyWindow(data->hwnd); - if (data->parent) { - DestroyWindow(data->parent); - } - } else { - /* Restore any original event handler... */ - if (data->wndproc != NULL) { -#ifdef GWLP_WNDPROC - SetWindowLongPtr(data->hwnd, GWLP_WNDPROC, - (LONG_PTR) data->wndproc); -#else - SetWindowLong(data->hwnd, GWL_WNDPROC, - (LONG_PTR) data->wndproc); -#endif - } - } - SDL_free(data); - } - window->driverdata = NULL; + CleanupWindowData(_this, window); } SDL_bool @@ -826,7 +961,7 @@ SDL_HelperWindowCreate(void) /* Create the class. */ SDL_zero(wce); wce.lpfnWndProc = DefWindowProc; - wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName; + wce.lpszClassName = SDL_HelperWindowClassName; wce.hInstance = hInstance; /* Register the class. */ @@ -890,18 +1025,6 @@ void WIN_OnWindowEnter(_THIS, SDL_Window * window) if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) { WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE); } - -#ifdef WM_MOUSELEAVE - { - TRACKMOUSEEVENT trackMouseEvent; - - trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT); - trackMouseEvent.dwFlags = TME_LEAVE; - trackMouseEvent.hwndTrack = data->hwnd; - - TrackMouseEvent(&trackMouseEvent); - } -#endif /* WM_MOUSELEAVE */ } void @@ -921,9 +1044,10 @@ WIN_UpdateClipCursor(SDL_Window *window) return; } - if ((mouse->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) && + if ((mouse->relative_mode || (window->flags & SDL_WINDOW_MOUSE_GRABBED) || + (window->mouse_rect.w > 0 && window->mouse_rect.h > 0)) && (window->flags & SDL_WINDOW_INPUT_FOCUS)) { - if (mouse->relative_mode && !mouse->relative_mode_warp) { + if (mouse->relative_mode && !mouse->relative_mode_warp && data->mouse_relative_mode_center) { if (GetWindowRect(data->hwnd, &rect)) { LONG cx, cy; @@ -943,12 +1067,32 @@ WIN_UpdateClipCursor(SDL_Window *window) } } } else { - if (GetClientRect(data->hwnd, &rect) && !IsRectEmpty(&rect)) { + if (GetClientRect(data->hwnd, &rect)) { ClientToScreen(data->hwnd, (LPPOINT) & rect); ClientToScreen(data->hwnd, (LPPOINT) & rect + 1); + if (window->mouse_rect.w > 0 && window->mouse_rect.h > 0) { + RECT mouse_rect, intersection; + + mouse_rect.left = rect.left + window->mouse_rect.x; + mouse_rect.top = rect.top + window->mouse_rect.y; + mouse_rect.right = mouse_rect.left + window->mouse_rect.w - 1; + mouse_rect.bottom = mouse_rect.top + window->mouse_rect.h - 1; + if (IntersectRect(&intersection, &rect, &mouse_rect)) { + SDL_memcpy(&rect, &intersection, sizeof(rect)); + } else if ((window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) { + /* Mouse rect was invalid, just do the normal grab */ + } else { + SDL_zero(rect); + } + } if (SDL_memcmp(&rect, &clipped_rect, sizeof(rect)) != 0) { - if (ClipCursor(&rect)) { - data->cursor_clipped_rect = rect; + if (!IsRectEmpty(&rect)) { + if (ClipCursor(&rect)) { + data->cursor_clipped_rect = rect; + } + } else { + ClipCursor(NULL); + SDL_zero(data->cursor_clipped_rect); } } } @@ -1015,6 +1159,34 @@ WIN_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept) DragAcceptFiles(data->hwnd, accept ? TRUE : FALSE); } +int +WIN_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation) +{ + FLASHWINFO desc; + + SDL_zero(desc); + desc.cbSize = sizeof(desc); + desc.hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + switch (operation) { + case SDL_FLASH_CANCEL: + desc.dwFlags = FLASHW_STOP; + break; + case SDL_FLASH_BRIEFLY: + desc.dwFlags = FLASHW_TRAY; + desc.uCount = 1; + break; + case SDL_FLASH_UNTIL_FOCUSED: + desc.dwFlags = (FLASHW_TRAY | FLASHW_TIMERNOFG); + break; + default: + return SDL_Unsupported(); + } + + FlashWindowEx(&desc); + + return 0; +} + #endif /* SDL_VIDEO_DRIVER_WINDOWS */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowswindow.h b/Engine/lib/sdl/src/video/windows/SDL_windowswindow.h index cfbf12050..659366a9f 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowswindow.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowswindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,9 +37,11 @@ typedef struct HINSTANCE hinstance; HBITMAP hbm; WNDPROC wndproc; + HHOOK keyboard_hook; SDL_bool created; WPARAM mouse_button_flags; LPARAM last_pointer_update; + WCHAR high_surrogate; SDL_bool initializing; SDL_bool expected_resize; SDL_bool in_border_change; @@ -47,9 +49,12 @@ typedef struct Uint8 focus_click_pending; SDL_bool skip_update_clipcursor; Uint32 last_updated_clipcursor; + SDL_bool mouse_relative_mode_center; SDL_bool windowed_mode_was_maximized; SDL_bool in_window_deactivation; RECT cursor_clipped_rect; + SDL_Point last_raw_mouse_position; + SDL_bool mouse_tracked; struct SDL_VideoData *videodata; #if SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; @@ -72,10 +77,14 @@ extern void WIN_MinimizeWindow(_THIS, SDL_Window * window); extern void WIN_RestoreWindow(_THIS, SDL_Window * window); extern void WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); +extern void WIN_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top); extern void WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); +extern void* WIN_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size); extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); -extern void WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void WIN_SetWindowMouseRect(_THIS, SDL_Window * window); +extern void WIN_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void WIN_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void WIN_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); @@ -83,6 +92,7 @@ extern void WIN_OnWindowEnter(_THIS, SDL_Window * window); extern void WIN_UpdateClipCursor(SDL_Window *window); extern int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled); extern void WIN_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept); +extern int WIN_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation); #endif /* SDL_windowswindow_h_ */ diff --git a/Engine/lib/sdl/src/video/windows/wmmsg.h b/Engine/lib/sdl/src/video/windows/wmmsg.h index 37ad7be13..bd416eb80 100644 --- a/Engine/lib/sdl/src/video/windows/wmmsg.h +++ b/Engine/lib/sdl/src/video/windows/wmmsg.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #define MAX_WMMSG (sizeof(wmtab)/sizeof(wmtab[0])) -char *wmtab[] = { +const char *wmtab[] = { "WM_NULL", "WM_CREATE", "WM_DESTROY", diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtevents.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtevents.cpp index b887547d5..646bde773 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtevents.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtevents.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtevents_c.h b/Engine/lib/sdl/src/video/winrt/SDL_winrtevents_c.h index 6f2bcedbf..112318024 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtevents_c.h +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -53,7 +53,7 @@ typedef enum { extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition, WINRT_CursorNormalizationType normalization); -extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt); +extern SDL_bool WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt, Uint8 *button, Uint8 *pressed); extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar.cpp index 8fe513ec2..2b1235721 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -89,7 +89,7 @@ WINRT_GetGameBar() IGameBarStatics_ *pGameBar = NULL; HRESULT hr; - hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName); + hr = ::WindowsCreateString(wClassName, (UINT32)SDL_wcslen(wClassName), &hClassName); if (FAILED(hr)) { goto done; } diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar_cpp.h b/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar_cpp.h index f9b474b08..a77758791 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar_cpp.h +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar_cpp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtkeyboard.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtkeyboard.cpp index 659541f6d..40681cb8a 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtkeyboard.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtkeyboard.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtmessagebox.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtmessagebox.cpp index 7f765e9cb..f74a7f483 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtmessagebox.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtmessagebox.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtmessagebox.h b/Engine/lib/sdl/src/video/winrt/SDL_winrtmessagebox.h index 8ece578b9..7d1429dbc 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtmessagebox.h +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse.cpp index 7dd5eff52..8c32e5fcf 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse_c.h b/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse_c.h index 39dfba64d..f5008962a 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse_c.h +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtopengles.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtopengles.cpp index adb620801..9e3c1772b 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtopengles.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtopengles.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtopengles.h b/Engine/lib/sdl/src/video/winrt/SDL_winrtopengles.h index 5e142b1df..c702c8b69 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtopengles.h +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtpointerinput.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtpointerinput.cpp index 9b36aaaad..51cc93727 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtpointerinput.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtpointerinput.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -116,52 +116,55 @@ WINRT_TransformCursorPosition(SDL_Window * window, return outputPosition; } -static inline int -_lround(float arg) -{ - if (arg >= 0.0f) { - return (int)floor(arg + 0.5f); - } else { - return (int)ceil(arg - 0.5f); - } -} - -Uint8 -WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) +SDL_bool +WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt, Uint8 *button, Uint8 *pressed) { using namespace Windows::UI::Input; #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - return SDL_BUTTON_LEFT; + *button = SDL_BUTTON_LEFT; + return SDL_TRUE; #else switch (pt->Properties->PointerUpdateKind) { case PointerUpdateKind::LeftButtonPressed: case PointerUpdateKind::LeftButtonReleased: - return SDL_BUTTON_LEFT; + *button = SDL_BUTTON_LEFT; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::LeftButtonPressed); + return SDL_TRUE; case PointerUpdateKind::RightButtonPressed: case PointerUpdateKind::RightButtonReleased: - return SDL_BUTTON_RIGHT; + *button = SDL_BUTTON_RIGHT; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::RightButtonPressed); + return SDL_TRUE; case PointerUpdateKind::MiddleButtonPressed: case PointerUpdateKind::MiddleButtonReleased: - return SDL_BUTTON_MIDDLE; + *button = SDL_BUTTON_MIDDLE; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::MiddleButtonPressed); + return SDL_TRUE; case PointerUpdateKind::XButton1Pressed: case PointerUpdateKind::XButton1Released: - return SDL_BUTTON_X1; + *button = SDL_BUTTON_X1; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::XButton1Pressed); + return SDL_TRUE; case PointerUpdateKind::XButton2Pressed: case PointerUpdateKind::XButton2Released: - return SDL_BUTTON_X2; + *button = SDL_BUTTON_X2; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::XButton2Pressed); + return SDL_TRUE; default: break; } #endif - return 0; + *button = 0; + *pressed = 0; + return SDL_FALSE; } //const char * @@ -221,9 +224,10 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po return; } - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if ( ! WINRT_IsTouchEvent(pointerPoint)) { + Uint8 button, pressed; + WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed); + SDL_assert(pressed == 1); SDL_SendMouseButton(window, 0, SDL_PRESSED, button); } else { Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); @@ -251,6 +255,12 @@ WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPo Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize); if ( ! WINRT_IsTouchEvent(pointerPoint)) { + /* For some odd reason Moved events are used for multiple mouse buttons */ + Uint8 button, pressed; + if (WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed)) { + SDL_SendMouseButton(window, 0, pressed, button); + } + SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); } else { SDL_SendTouchMotion( @@ -269,9 +279,10 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P return; } - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (!WINRT_IsTouchEvent(pointerPoint)) { + Uint8 button, pressed; + WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed); + SDL_assert(pressed == 0); SDL_SendMouseButton(window, 0, SDL_RELEASED, button); } else { Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); @@ -389,8 +400,8 @@ WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::Mouse window, 0, 1, - _lround(mouseDeltaInSDLWindowCoords.X), - _lround(mouseDeltaInSDLWindowCoords.Y)); + SDL_lroundf(mouseDeltaInSDLWindowCoords.X), + SDL_lroundf(mouseDeltaInSDLWindowCoords.Y)); } #endif // SDL_VIDEO_DRIVER_WINRT diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo.cpp index 99a52f39d..6ed5918e7 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,6 +28,12 @@ was based off of SDL's "dummy" video driver. */ +/* Standard C++11 includes */ +#include +#include +#include +using namespace std; + /* Windows includes */ #include #include @@ -42,8 +48,8 @@ using namespace Windows::UI::ViewManagement; /* [re]declare Windows GUIDs locally, to limit the amount of external lib(s) SDL has to link to */ -static const GUID IID_IDisplayRequest = { 0xe5732044, 0xf49f, 0x4b60, { 0x8d, 0xd4, 0x5e, 0x7e, 0x3a, 0x63, 0x2a, 0xc0 } }; -static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } }; +static const GUID SDL_IID_IDisplayRequest = { 0xe5732044, 0xf49f, 0x4b60, { 0x8d, 0xd4, 0x5e, 0x7e, 0x3a, 0x63, 0x2a, 0xc0 } }; +static const GUID SDL_IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } }; /* SDL includes */ @@ -67,6 +73,7 @@ extern "C" { #include "SDL_winrtmouse_c.h" #include "SDL_main.h" #include "SDL_system.h" +#include "SDL_hints.h" /* Initialization/Query functions */ @@ -171,6 +178,68 @@ VideoBootStrap WINRT_bootstrap = { WINRT_CreateDevice }; +static void SDLCALL +WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue) +{ + SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0); + + /* HACK: prevent SDL from altering an app's .appxmanifest-set orientation + * from being changed on startup, by detecting when SDL_HINT_ORIENTATIONS + * is getting registered. + * + * TODO, WinRT: consider reading in an app's .appxmanifest file, and apply its orientation when 'newValue == NULL'. + */ + if ((oldValue == NULL) && (newValue == NULL)) { + return; + } + + // Start with no orientation flags, then add each in as they're parsed + // from newValue. + unsigned int orientationFlags = 0; + if (newValue) { + std::istringstream tokenizer(newValue); + while (!tokenizer.eof()) { + std::string orientationName; + std::getline(tokenizer, orientationName, ' '); + if (orientationName == "LandscapeLeft") { + orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped; + } else if (orientationName == "LandscapeRight") { + orientationFlags |= (unsigned int) DisplayOrientations::Landscape; + } else if (orientationName == "Portrait") { + orientationFlags |= (unsigned int) DisplayOrientations::Portrait; + } else if (orientationName == "PortraitUpsideDown") { + orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped; + } + } + } + + // If no valid orientation flags were specified, use a reasonable set of defaults: + if (!orientationFlags) { + // TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s). + orientationFlags = (unsigned int) ( \ + DisplayOrientations::Landscape | + DisplayOrientations::LandscapeFlipped | + DisplayOrientations::Portrait | + DisplayOrientations::PortraitFlipped); + } + + // Set the orientation/rotation preferences. Please note that this does + // not constitute a 100%-certain lock of a given set of possible + // orientations. According to Microsoft's documentation on WinRT [1] + // when a device is not capable of being rotated, Windows may ignore + // the orientation preferences, and stick to what the device is capable of + // displaying. + // + // [1] Documentation on the 'InitialRotationPreference' setting for a + // Windows app's manifest file describes how some orientation/rotation + // preferences may be ignored. See + // http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx + // for details. Microsoft's "Display orientation sample" also gives an + // outline of how Windows treats device rotation + // (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93). + WINRT_DISPLAY_PROPERTY(AutoRotationPreferences) = (DisplayOrientations) orientationFlags; +} + int WINRT_VideoInit(_THIS) { @@ -178,6 +247,11 @@ WINRT_VideoInit(_THIS) if (WINRT_InitModes(_this) < 0) { return -1; } + + // Register the hint, SDL_HINT_ORIENTATIONS, with SDL. + // TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly. + SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL); + WINRT_InitMouse(_this); WINRT_InitTouch(_this); WINRT_InitGameBar(_this); @@ -402,10 +476,9 @@ WINRT_InitModes(_THIS) HRESULT hr; IDXGIFactory2 * dxgiFactory2 = NULL; - hr = CreateDXGIFactory1(IID_IDXGIFactory2, (void **)&dxgiFactory2); + hr = CreateDXGIFactory1(SDL_IID_IDXGIFactory2, (void **)&dxgiFactory2); if (FAILED(hr)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateDXGIFactory1() failed", hr); - return -1; + return WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateDXGIFactory1() failed", hr); } for (int adapterIndex = 0; ; ++adapterIndex) { @@ -556,14 +629,12 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) // Make sure that only one window gets created, at least until multimonitor // support is added. if (WINRT_GlobalSDLWindow != NULL) { - SDL_SetError("WinRT only supports one window"); - return -1; + return SDL_SetError("WinRT only supports one window"); } SDL_WindowData *data = new SDL_WindowData; /* use 'new' here as SDL_WindowData may use WinRT/C++ types */ if (!data) { - SDL_OutOfMemory(); - return -1; + return SDL_OutOfMemory(); } window->driverdata = data; data->sdlWindow = window; @@ -599,9 +670,8 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) * be passed into eglCreateWindowSurface. */ if (SDL_EGL_ChooseConfig(_this) != 0) { - char buf[512]; - SDL_snprintf(buf, sizeof(buf), "SDL_EGL_ChooseConfig failed: %s", SDL_GetError()); - return SDL_SetError("%s", buf); + /* SDL_EGL_ChooseConfig failed, SDL_GetError() should have info */ + return -1; } if (video_data->winrtEglWindow) { /* ... is the 'old' version of ANGLE/WinRT being used? */ @@ -624,7 +694,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) data->egl_surface = _this->egl_data->eglCreateWindowSurface( _this->egl_data->egl_display, _this->egl_data->egl_config, - coreWindowAsIInspectable, + (NativeWindowType)coreWindowAsIInspectable, NULL); if (data->egl_surface == NULL) { return SDL_EGL_SetError("unable to create EGL native-window surface", "eglCreateWindowSurface"); @@ -782,7 +852,7 @@ WINRT_CreateDisplayRequest(_THIS) ABI::Windows::System::Display::IDisplayRequest * pDisplayRequest = nullptr; HRESULT hr; - hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName); + hr = ::WindowsCreateString(wClassName, (UINT32)SDL_wcslen(wClassName), &hClassName); if (FAILED(hr)) { goto done; } @@ -797,7 +867,7 @@ WINRT_CreateDisplayRequest(_THIS) goto done; } - hr = pDisplayRequestRaw->QueryInterface(IID_IDisplayRequest, (void **) &pDisplayRequest); + hr = pDisplayRequestRaw->QueryInterface(SDL_IID_IDisplayRequest, (void **) &pDisplayRequest); if (FAILED(hr)) { goto done; } diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo_cpp.h b/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo_cpp.h index c167b88a0..8e6d63bdc 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo_cpp.h +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo_cpp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11clipboard.c b/Engine/lib/sdl/src/video/x11/SDL_x11clipboard.c index d1469c020..37a17f407 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11clipboard.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11clipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,14 +27,7 @@ #include "SDL_events.h" #include "SDL_x11video.h" #include "SDL_timer.h" - - -/* If you don't support UTF-8, you might use XA_STRING here */ -#ifdef X_HAVE_UTF8_STRING -#define TEXT_FORMAT X11_XInternAtom(display, "UTF8_STRING", False) -#else -#define TEXT_FORMAT XA_STRING -#endif +#include "SDL_x11clipboard.h" /* Get any application owned window handle for clipboard association */ static Window @@ -59,19 +52,77 @@ GetWindow(_THIS) return data->clipboard_window; } + /* We use our own cut-buffer for intermediate storage instead of XA_CUT_BUFFER0 because their use isn't really defined for holding UTF8. */ Atom -X11_GetSDLCutBufferClipboardType(Display *display) +X11_GetSDLCutBufferClipboardType(Display *display, enum ESDLX11ClipboardMimeType mime_type) { - return X11_XInternAtom(display, "SDL_CUTBUFFER", False); + switch (mime_type) { + case SDL_X11_CLIPBOARD_MIME_TYPE_STRING: + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN: + #ifdef X_HAVE_UTF8_STRING + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN_UTF8: + #endif + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT: + return X11_XInternAtom(display, "SDL_CUTBUFFER", False); + default: + SDL_SetError("Can't find mime_type."); + return XA_STRING; + } } +Atom +X11_GetSDLCutBufferClipboardExternalFormat(Display *display, enum ESDLX11ClipboardMimeType mime_type) +{ + switch (mime_type) { + case SDL_X11_CLIPBOARD_MIME_TYPE_STRING: + /* If you don't support UTF-8, you might use XA_STRING here */ + #ifdef X_HAVE_UTF8_STRING + return X11_XInternAtom(display, "UTF8_STRING", False); + #else + return XA_STRING; + #endif + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN: + return X11_XInternAtom(display, "text/plain", False); + #ifdef X_HAVE_UTF8_STRING + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN_UTF8: + return X11_XInternAtom(display, "text/plain;charset=utf-8", False); + #endif + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT: + return X11_XInternAtom(display, "TEXT", False); + default: + SDL_SetError("Can't find mime_type."); + return XA_STRING; + } +} +Atom +X11_GetSDLCutBufferClipboardInternalFormat(Display *display, enum ESDLX11ClipboardMimeType mime_type) +{ + switch (mime_type) { + case SDL_X11_CLIPBOARD_MIME_TYPE_STRING: + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN: + #ifdef X_HAVE_UTF8_STRING + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN_UTF8: + #endif + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT: + /* If you don't support UTF-8, you might use XA_STRING here */ + #ifdef X_HAVE_UTF8_STRING + return X11_XInternAtom(display, "UTF8_STRING", False); + #else + return XA_STRING; + #endif + default: + SDL_SetError("Can't find mime_type."); + return XA_STRING; + } +} + + int X11_SetClipboardText(_THIS, const char *text) { Display *display = ((SDL_VideoData *) _this->driverdata)->display; - Atom format; Window window; Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0); @@ -82,9 +133,8 @@ X11_SetClipboardText(_THIS, const char *text) } /* Save the selection on the root window */ - format = TEXT_FORMAT; X11_XChangeProperty(display, DefaultRootWindow(display), - X11_GetSDLCutBufferClipboardType(display), format, 8, PropModeReplace, + X11_GetSDLCutBufferClipboardType(display, SDL_X11_CLIPBOARD_MIME_TYPE_STRING), X11_GetSDLCutBufferClipboardInternalFormat(display, SDL_X11_CLIPBOARD_MIME_TYPE_STRING), 8, PropModeReplace, (const unsigned char *)text, SDL_strlen(text)); if (XA_CLIPBOARD != None && @@ -125,7 +175,7 @@ X11_GetClipboardText(_THIS) /* Get the window that holds the selection */ window = GetWindow(_this); - format = TEXT_FORMAT; + format = X11_GetSDLCutBufferClipboardInternalFormat(display, SDL_X11_CLIPBOARD_MIME_TYPE_STRING); owner = X11_XGetSelectionOwner(display, XA_CLIPBOARD); if (owner == None) { /* Fall back to ancient X10 cut-buffers which do not support UTF8 strings*/ @@ -134,7 +184,7 @@ X11_GetClipboardText(_THIS) format = XA_STRING; } else if (owner == window) { owner = DefaultRootWindow(display); - selection = X11_GetSDLCutBufferClipboardType(display); + selection = X11_GetSDLCutBufferClipboardType(display, SDL_X11_CLIPBOARD_MIME_TYPE_STRING); } else { /* Request that the selection owner copy the data to our window */ owner = window; diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11clipboard.h b/Engine/lib/sdl/src/video/x11/SDL_x11clipboard.h index 87fb827da..ec98445c4 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11clipboard.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11clipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,10 +23,22 @@ #ifndef SDL_x11clipboard_h_ #define SDL_x11clipboard_h_ +enum ESDLX11ClipboardMimeType { + SDL_X11_CLIPBOARD_MIME_TYPE_STRING, + SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN, + #ifdef X_HAVE_UTF8_STRING + SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN_UTF8, + #endif + SDL_X11_CLIPBOARD_MIME_TYPE_TEXT, + SDL_X11_CLIPBOARD_MIME_TYPE_MAX +}; + extern int X11_SetClipboardText(_THIS, const char *text); extern char *X11_GetClipboardText(_THIS); extern SDL_bool X11_HasClipboardText(_THIS); -extern Atom X11_GetSDLCutBufferClipboardType(Display *display); +extern Atom X11_GetSDLCutBufferClipboardType(Display *display, enum ESDLX11ClipboardMimeType mime_type); +extern Atom X11_GetSDLCutBufferClipboardExternalFormat(Display *display, enum ESDLX11ClipboardMimeType mime_type); +extern Atom X11_GetSDLCutBufferClipboardInternalFormat(Display *display, enum ESDLX11ClipboardMimeType mime_type); #endif /* SDL_x11clipboard_h_ */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11dyn.c b/Engine/lib/sdl/src/video/x11/SDL_x11dyn.c index 777f4bf30..29a8186fa 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11dyn.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11dyn.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -53,6 +53,9 @@ typedef struct #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 NULL #endif +#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES NULL +#endif #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL #endif @@ -69,6 +72,7 @@ static x11dynlib x11libs[] = { {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2}, + {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE} diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11dyn.h b/Engine/lib/sdl/src/video/x11/SDL_x11dyn.h index ecdf76408..c2678bfed 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11dyn.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11dyn.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -39,7 +39,6 @@ #include #include -#include #ifndef NO_SHARED_MEMORY #include @@ -59,6 +58,9 @@ #if SDL_VIDEO_DRIVER_X11_XINPUT2 #include #endif +#if SDL_VIDEO_DRIVER_X11_XFIXES +#include +#endif #if SDL_VIDEO_DRIVER_X11_XRANDR #include #endif diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11events.c b/Engine/lib/sdl/src/video/x11/SDL_x11events.c index ea7292740..c1260215d 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11events.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11events.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,6 +31,7 @@ #include "SDL_x11video.h" #include "SDL_x11touch.h" #include "SDL_x11xinput2.h" +#include "SDL_x11xfixes.h" #include "../../core/unix/SDL_poll.h" #include "../../events/SDL_events_c.h" #include "../../events/SDL_mouse_c.h" @@ -269,19 +270,19 @@ static char* X11_URIToLocal(char* uri) { char *file = NULL; SDL_bool local; - if (memcmp(uri,"file:/",6) == 0) uri += 6; /* local file? */ - else if (strstr(uri,":/") != NULL) return file; /* wrong scheme */ + if (SDL_memcmp(uri,"file:/",6) == 0) uri += 6; /* local file? */ + else if (SDL_strstr(uri,":/") != NULL) return file; /* wrong scheme */ local = uri[0] != '/' || (uri[0] != '\0' && uri[1] == '/'); /* got a hostname? */ if (!local && uri[0] == '/' && uri[2] != '/') { - char* hostname_end = strchr(uri+1, '/'); + char* hostname_end = SDL_strchr(uri+1, '/'); if (hostname_end != NULL) { char hostname[ 257 ]; if (gethostname(hostname, 255) == 0) { hostname[ 256 ] = '\0'; - if (memcmp(uri+1, hostname, hostname_end - (uri+1)) == 0) { + if (SDL_memcmp(uri+1, hostname, hostname_end - (uri+1)) == 0) { uri = hostname_end + 1; local = SDL_TRUE; } @@ -353,6 +354,32 @@ X11_GetNumLockModifierMask(_THIS) return num_mask; } +static unsigned +X11_GetScrollLockModifierMask(_THIS) +{ + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + Display *display = viddata->display; + unsigned num_mask = 0; + int i, j; + XModifierKeymap *xmods; + unsigned n; + + xmods = X11_XGetModifierMapping(display); + n = xmods->max_keypermod; + for(i = 3; i < 8; i++) { + for(j = 0; j < n; j++) { + KeyCode kc = xmods->modifiermap[i * n + j]; + if (viddata->key_layout[kc] == SDL_SCANCODE_SCROLLLOCK) { + num_mask = 1 << i; + break; + } + } + } + X11_XFreeModifiermap(xmods); + + return num_mask; +} + static void X11_ReconcileKeyboardState(_THIS) { @@ -371,6 +398,7 @@ X11_ReconcileKeyboardState(_THIS) if (X11_XQueryPointer(display, DefaultRootWindow(display), &junk_window, &junk_window, &x, &y, &x, &y, &mask)) { SDL_ToggleModState(KMOD_CAPS, (mask & LockMask) != 0); SDL_ToggleModState(KMOD_NUM, (mask & X11_GetNumLockModifierMask(_this)) != 0); + SDL_ToggleModState(KMOD_SCROLL, (mask & X11_GetScrollLockModifierMask(_this)) != 0); } keyboardState = SDL_GetKeyboardState(0); @@ -404,6 +432,9 @@ X11_DispatchFocusIn(_THIS, SDL_WindowData *data) #ifdef SDL_USE_IME SDL_IME_SetFocus(SDL_TRUE); #endif + if (data->flashing_window) { + X11_FlashWindow(_this, data->window, SDL_FLASH_CANCEL); + } } static void @@ -559,6 +590,7 @@ X11_UpdateUserTime(SDL_WindowData *data, const unsigned long latest) static void X11_HandleClipboardEvent(_THIS, const XEvent *xevent) { + int i; SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; Display *display = videodata->display; @@ -570,10 +602,12 @@ X11_HandleClipboardEvent(_THIS, const XEvent *xevent) case SelectionRequest: { const XSelectionRequestEvent *req = &xevent->xselectionrequest; XEvent sevent; - int seln_format; + int seln_format, mime_formats; unsigned long nbytes; unsigned long overflow; - unsigned char *seln_data; + unsigned char *seln_data; + Atom supportedFormats[SDL_X11_CLIPBOARD_MIME_TYPE_MAX+1]; + Atom XA_TARGETS = X11_XInternAtom(display, "TARGETS", 0); #ifdef DEBUG_XEVENTS printf("window CLIPBOARD: SelectionRequest (requestor = %ld, target = %ld)\n", @@ -591,27 +625,38 @@ X11_HandleClipboardEvent(_THIS, const XEvent *xevent) /* !!! FIXME: We were probably storing this on the root window because an SDL window might go away...? but we don't have to do this now (or ever, really). */ - if (X11_XGetWindowProperty(display, DefaultRootWindow(display), - X11_GetSDLCutBufferClipboardType(display), 0, INT_MAX/4, False, req->target, - &sevent.xselection.target, &seln_format, &nbytes, - &overflow, &seln_data) == Success) { - /* !!! FIXME: cache atoms */ - Atom XA_TARGETS = X11_XInternAtom(display, "TARGETS", 0); - if (sevent.xselection.target == req->target) { - X11_XChangeProperty(display, req->requestor, req->property, - sevent.xselection.target, seln_format, PropModeReplace, - seln_data, nbytes); - sevent.xselection.property = req->property; - } else if (XA_TARGETS == req->target) { - Atom SupportedFormats[] = { XA_TARGETS, sevent.xselection.target }; - X11_XChangeProperty(display, req->requestor, req->property, - XA_ATOM, 32, PropModeReplace, - (unsigned char*)SupportedFormats, - SDL_arraysize(SupportedFormats)); - sevent.xselection.property = req->property; - sevent.xselection.target = XA_TARGETS; + + if (req->target == XA_TARGETS) { + supportedFormats[0] = XA_TARGETS; + mime_formats = 1; + for (i = 0; i < SDL_X11_CLIPBOARD_MIME_TYPE_MAX; ++i) + supportedFormats[mime_formats++] = X11_GetSDLCutBufferClipboardExternalFormat(display, i); + X11_XChangeProperty(display, req->requestor, req->property, + XA_ATOM, 32, PropModeReplace, + (unsigned char*)supportedFormats, + mime_formats); + sevent.xselection.property = req->property; + sevent.xselection.target = XA_TARGETS; + } else { + for (i = 0; i < SDL_X11_CLIPBOARD_MIME_TYPE_MAX; ++i) { + if (X11_GetSDLCutBufferClipboardExternalFormat(display, i) != req->target) + continue; + if (X11_XGetWindowProperty(display, DefaultRootWindow(display), + X11_GetSDLCutBufferClipboardType(display, i), 0, INT_MAX/4, False, X11_GetSDLCutBufferClipboardInternalFormat(display, i), + &sevent.xselection.target, &seln_format, &nbytes, + &overflow, &seln_data) == Success) { + if (seln_format != None) { + X11_XChangeProperty(display, req->requestor, req->property, + sevent.xselection.target, seln_format, PropModeReplace, + seln_data, nbytes); + sevent.xselection.property = req->property; + X11_XFree(seln_data); + break; + } else { + X11_XFree(seln_data); + } + } } - X11_XFree(seln_data); } X11_XSendEvent(display, req->requestor, False, 0, &sevent); X11_XSync(display, False); @@ -670,40 +715,35 @@ isReparentNotify(Display *display, XEvent *ev, XPointer arg) } static void -X11_DispatchEvent(_THIS) +X11_DispatchEvent(_THIS, XEvent *xevent) { SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + XkbEvent* xkbEvent = (XkbEvent*) xevent; Display *display; SDL_WindowData *data; - XEvent xevent; int orig_event_type; KeyCode orig_keycode; XClientMessageEvent m; int i; - if (!videodata) { - return; - } + SDL_assert(videodata != NULL); display = videodata->display; - SDL_zero(xevent); /* valgrind fix. --ryan. */ - X11_XNextEvent(display, &xevent); - /* Save the original keycode for dead keys, which are filtered out by the XFilterEvent() call below. */ - orig_event_type = xevent.type; + orig_event_type = xevent->type; if (orig_event_type == KeyPress || orig_event_type == KeyRelease) { - orig_keycode = xevent.xkey.keycode; + orig_keycode = xevent->xkey.keycode; } else { orig_keycode = 0; } /* filter events catchs XIM events and sends them to the correct handler */ - if (X11_XFilterEvent(&xevent, None) == True) { + if (X11_XFilterEvent(xevent, None) == True) { #if 0 printf("Filtered event type = %d display = %d window = %d\n", - xevent.type, xevent.xany.display, xevent.xany.window); + xevent->type, xevent->xany.display, xevent->xany.window); #endif /* Make sure dead key press/release events are sent */ /* But only if we're using one of the DBus IMEs, otherwise @@ -712,7 +752,7 @@ X11_DispatchEvent(_THIS) #if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX) SDL_Scancode scancode = videodata->key_layout[orig_keycode]; videodata->filter_code = orig_keycode; - videodata->filter_time = xevent.xkey.time; + videodata->filter_time = xevent->xkey.time; if (orig_event_type == KeyPress) { SDL_SendKeyboardKey(SDL_PRESSED, scancode); @@ -725,8 +765,8 @@ X11_DispatchEvent(_THIS) } #if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS - if(xevent.type == GenericEvent) { - X11_HandleGenericEvent(videodata, &xevent); + if(xevent->type == GenericEvent) { + X11_HandleGenericEvent(videodata, xevent); return; } #endif @@ -737,18 +777,18 @@ X11_DispatchEvent(_THIS) SDL_VERSION(&wmmsg.version); wmmsg.subsystem = SDL_SYSWM_X11; - wmmsg.msg.x11.event = xevent; + wmmsg.msg.x11.event = *xevent; SDL_SendSysWMEvent(&wmmsg); } #if 0 printf("type = %d display = %d window = %d\n", - xevent.type, xevent.xany.display, xevent.xany.window); + xevent->type, xevent->xany.display, xevent->xany.window); #endif if ((videodata->clipboard_window != None) && - (videodata->clipboard_window == xevent.xany.window)) { - X11_HandleClipboardEvent(_this, &xevent); + (videodata->clipboard_window == xevent->xany.window)) { + X11_HandleClipboardEvent(_this, xevent); return; } @@ -756,7 +796,7 @@ X11_DispatchEvent(_THIS) if (videodata && videodata->windowlist) { for (i = 0; i < videodata->numwindows; ++i) { if ((videodata->windowlist[i] != NULL) && - (videodata->windowlist[i]->xwindow == xevent.xany.window)) { + (videodata->windowlist[i]->xwindow == xevent->xany.window)) { data = videodata->windowlist[i]; break; } @@ -764,71 +804,117 @@ X11_DispatchEvent(_THIS) } if (!data) { /* The window for KeymapNotify, etc events is 0 */ - if (xevent.type == KeymapNotify) { + if (xevent->type == KeymapNotify) { if (SDL_GetKeyboardFocus() != NULL) { X11_ReconcileKeyboardState(_this); } - } else if (xevent.type == MappingNotify) { + } else if (xevent->type == MappingNotify || + (xevent->type == videodata->xkb_event && xkbEvent->any.xkb_type == XkbStateNotify)) { /* Has the keyboard layout changed? */ - const int request = xevent.xmapping.request; + const int request = xevent->xmapping.request; #ifdef DEBUG_XEVENTS printf("window %p: MappingNotify!\n", data); #endif if ((request == MappingKeyboard) || (request == MappingModifier)) { - X11_XRefreshKeyboardMapping(&xevent.xmapping); + X11_XRefreshKeyboardMapping(&xevent->xmapping); } X11_UpdateKeymap(_this); SDL_SendKeymapChangedEvent(); + } else if (xevent->type == PropertyNotify && videodata && videodata->windowlist) { + char* name_of_atom = X11_XGetAtomName(display, xevent->xproperty.atom); + + if (SDL_strncmp(name_of_atom, "_ICC_PROFILE", sizeof("_ICC_PROFILE") - 1) == 0) { + XWindowAttributes attrib; + int screennum; + for (i = 0; i < videodata->numwindows; ++i) { + if (videodata->windowlist[i] != NULL) { + data = videodata->windowlist[i]; + X11_XGetWindowAttributes(display, data->xwindow, &attrib); + screennum = X11_XScreenNumberOfScreen(attrib.screen); + if (screennum == 0 && SDL_strcmp(name_of_atom, "_ICC_PROFILE") == 0) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0); + } else if (SDL_strncmp(name_of_atom, "_ICC_PROFILE_", sizeof("_ICC_PROFILE_") - 1) == 0 && SDL_strlen(name_of_atom) > sizeof("_ICC_PROFILE_") - 1) { + int iccscreennum = SDL_atoi(&name_of_atom[sizeof("_ICC_PROFILE_") - 1]); + + if (screennum == iccscreennum) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0); + } + } + } + } + } + + if (name_of_atom) X11_XFree(name_of_atom); } return; } - switch (xevent.type) { + switch (xevent->type) { /* Gaining mouse coverage? */ case EnterNotify:{ SDL_Mouse *mouse = SDL_GetMouse(); #ifdef DEBUG_XEVENTS printf("window %p: EnterNotify! (%d,%d,%d)\n", data, - xevent.xcrossing.x, - xevent.xcrossing.y, - xevent.xcrossing.mode); - if (xevent.xcrossing.mode == NotifyGrab) + xevent->xcrossing.x, + xevent->xcrossing.y, + xevent->xcrossing.mode); + if (xevent->xcrossing.mode == NotifyGrab) printf("Mode: NotifyGrab\n"); - if (xevent.xcrossing.mode == NotifyUngrab) + if (xevent->xcrossing.mode == NotifyUngrab) printf("Mode: NotifyUngrab\n"); #endif SDL_SetMouseFocus(data->window); - mouse->last_x = xevent.xcrossing.x; - mouse->last_y = xevent.xcrossing.y; + mouse->last_x = xevent->xcrossing.x; + mouse->last_y = xevent->xcrossing.y; + +#if SDL_VIDEO_DRIVER_X11_XFIXES + { + /* Only create the barriers if we have input focus */ + SDL_WindowData* windowdata = (SDL_WindowData *) data->window->driverdata; + if ((data->pointer_barrier_active == SDL_TRUE) && windowdata->window->flags & SDL_WINDOW_INPUT_FOCUS) { + X11_ConfineCursorWithFlags(_this, windowdata->window, &windowdata->barrier_rect, X11_BARRIER_HANDLED_BY_EVENT); + } + } +#endif if (!mouse->relative_mode) { - SDL_SendMouseMotion(data->window, 0, 0, xevent.xcrossing.x, xevent.xcrossing.y); + SDL_SendMouseMotion(data->window, 0, 0, xevent->xcrossing.x, xevent->xcrossing.y); } + + /* We ungrab in LeaveNotify, so we may need to grab again here */ + SDL_UpdateWindowGrab(data->window); } break; /* Losing mouse coverage? */ case LeaveNotify:{ #ifdef DEBUG_XEVENTS printf("window %p: LeaveNotify! (%d,%d,%d)\n", data, - xevent.xcrossing.x, - xevent.xcrossing.y, - xevent.xcrossing.mode); - if (xevent.xcrossing.mode == NotifyGrab) + xevent->xcrossing.x, + xevent->xcrossing.y, + xevent->xcrossing.mode); + if (xevent->xcrossing.mode == NotifyGrab) printf("Mode: NotifyGrab\n"); - if (xevent.xcrossing.mode == NotifyUngrab) + if (xevent->xcrossing.mode == NotifyUngrab) printf("Mode: NotifyUngrab\n"); #endif if (!SDL_GetMouse()->relative_mode) { - SDL_SendMouseMotion(data->window, 0, 0, xevent.xcrossing.x, xevent.xcrossing.y); + SDL_SendMouseMotion(data->window, 0, 0, xevent->xcrossing.x, xevent->xcrossing.y); } - if (xevent.xcrossing.mode != NotifyGrab && - xevent.xcrossing.mode != NotifyUngrab && - xevent.xcrossing.detail != NotifyInferior) { + if (xevent->xcrossing.mode != NotifyGrab && + xevent->xcrossing.mode != NotifyUngrab && + xevent->xcrossing.detail != NotifyInferior) { + + /* In order for interaction with the window decorations and menu to work properly + on Mutter, we need to ungrab the keyboard when the the mouse leaves. */ + if (!(data->window->flags & SDL_WINDOW_FULLSCREEN)) { + X11_SetWindowKeyboardGrab(_this, data->window, SDL_FALSE); + } + SDL_SetMouseFocus(NULL); } } @@ -836,7 +922,7 @@ X11_DispatchEvent(_THIS) /* Gaining input focus? */ case FocusIn:{ - if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) { + if (xevent->xfocus.mode == NotifyGrab || xevent->xfocus.mode == NotifyUngrab) { /* Someone is handling a global hotkey, ignore it */ #ifdef DEBUG_XEVENTS printf("window %p: FocusIn (NotifyGrab/NotifyUngrab, ignoring)\n", data); @@ -844,7 +930,7 @@ X11_DispatchEvent(_THIS) break; } - if (xevent.xfocus.detail == NotifyInferior || xevent.xfocus.detail == NotifyPointer) { + if (xevent->xfocus.detail == NotifyInferior || xevent->xfocus.detail == NotifyPointer) { #ifdef DEBUG_XEVENTS printf("window %p: FocusIn (NotifyInferior/NotifyPointer, ignoring)\n", data); #endif @@ -870,14 +956,14 @@ X11_DispatchEvent(_THIS) /* Losing input focus? */ case FocusOut:{ - if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) { + if (xevent->xfocus.mode == NotifyGrab || xevent->xfocus.mode == NotifyUngrab) { /* Someone is handling a global hotkey, ignore it */ #ifdef DEBUG_XEVENTS printf("window %p: FocusOut (NotifyGrab/NotifyUngrab, ignoring)\n", data); #endif break; } - if (xevent.xfocus.detail == NotifyInferior || xevent.xfocus.detail == NotifyPointer) { + if (xevent->xfocus.detail == NotifyInferior || xevent->xfocus.detail == NotifyPointer) { /* We still have focus if a child gets focus. We also don't care about the position of the pointer when the keyboard focus changed. */ @@ -900,25 +986,32 @@ X11_DispatchEvent(_THIS) data->pending_focus = PENDING_FOCUS_OUT; data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME; } + +#if SDL_VIDEO_DRIVER_X11_XFIXES + /* Disable confinement if it is activated. */ + if (data->pointer_barrier_active == SDL_TRUE) { + X11_ConfineCursorWithFlags(_this, data->window, NULL, X11_BARRIER_HANDLED_BY_EVENT); + } +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ } break; /* Key press? */ case KeyPress:{ - KeyCode keycode = xevent.xkey.keycode; + KeyCode keycode = xevent->xkey.keycode; KeySym keysym = NoSymbol; char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; Status status = 0; SDL_bool handled_by_ime = SDL_FALSE; #ifdef DEBUG_XEVENTS - printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode); + printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent->xkey.keycode); #endif #if 1 if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) { int min_keycode, max_keycode; X11_XDisplayKeycodes(display, &min_keycode, &max_keycode); - keysym = X11_KeyCodeToSym(_this, keycode, xevent.xkey.state >> 13); + keysym = X11_KeyCodeToSym(_this, keycode, xevent->xkey.state >> 13); fprintf(stderr, "The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL forums/mailing list X11 KeyCode %d (%d), X11 KeySym 0x%lX (%s).\n", keycode, keycode - min_keycode, keysym, @@ -929,13 +1022,13 @@ X11_DispatchEvent(_THIS) SDL_zeroa(text); #ifdef X_HAVE_UTF8_STRING if (data->ic) { - X11_Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text), + X11_Xutf8LookupString(data->ic, &xevent->xkey, text, sizeof(text), &keysym, &status); } else { - X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL); + X11_XLookupString(&xevent->xkey, text, sizeof(text), &keysym, NULL); } #else - X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL); + X11_XLookupString(&xevent->xkey, text, sizeof(text), &keysym, NULL); #endif #ifdef SDL_USE_IME @@ -945,7 +1038,7 @@ X11_DispatchEvent(_THIS) #endif if (!handled_by_ime) { /* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */ - if (xevent.xkey.keycode != videodata->filter_code || xevent.xkey.time != videodata->filter_time) { + if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) { SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]); } if(*text) { @@ -953,18 +1046,18 @@ X11_DispatchEvent(_THIS) } } - X11_UpdateUserTime(data, xevent.xkey.time); + X11_UpdateUserTime(data, xevent->xkey.time); } break; /* Key release? */ case KeyRelease:{ - KeyCode keycode = xevent.xkey.keycode; + KeyCode keycode = xevent->xkey.keycode; #ifdef DEBUG_XEVENTS - printf("window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode); + printf("window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent->xkey.keycode); #endif - if (X11_KeyRepeat(display, &xevent)) { + if (X11_KeyRepeat(display, xevent)) { /* We're about to get a repeated key down, ignore the key up */ break; } @@ -980,11 +1073,18 @@ X11_DispatchEvent(_THIS) printf("window %p: UnmapNotify!\n", data); #endif - if (X11_XCheckIfEvent(display, &ev, &isReparentNotify, (XPointer)&xevent.xunmap)) { - X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&xevent.xunmap); + if (X11_XCheckIfEvent(display, &ev, &isReparentNotify, (XPointer)&xevent->xunmap)) { + X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&xevent->xunmap); } else { X11_DispatchUnmapNotify(data); } + +#if SDL_VIDEO_DRIVER_X11_XFIXES + /* Disable confinement if the window gets hidden. */ + if (data->pointer_barrier_active == SDL_TRUE) { + X11_ConfineCursorWithFlags(_this, data->window, NULL, X11_BARRIER_HANDLED_BY_EVENT); + } +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ } break; @@ -994,6 +1094,13 @@ X11_DispatchEvent(_THIS) printf("window %p: MapNotify!\n", data); #endif X11_DispatchMapNotify(data); + +#if SDL_VIDEO_DRIVER_X11_XFIXES + /* Enable confinement if it was activated. */ + if (data->pointer_barrier_active == SDL_TRUE) { + X11_ConfineCursorWithFlags(_this, data->window, &data->barrier_rect, X11_BARRIER_HANDLED_BY_EVENT); + } +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ } break; @@ -1001,27 +1108,27 @@ X11_DispatchEvent(_THIS) case ConfigureNotify:{ #ifdef DEBUG_XEVENTS printf("window %p: ConfigureNotify! (position: %d,%d, size: %dx%d)\n", data, - xevent.xconfigure.x, xevent.xconfigure.y, - xevent.xconfigure.width, xevent.xconfigure.height); + xevent->xconfigure.x, xevent->xconfigure.y, + xevent->xconfigure.width, xevent->xconfigure.height); #endif /* Real configure notify events are relative to the parent, synthetic events are absolute. */ - if (!xevent.xconfigure.send_event) { + if (!xevent->xconfigure.send_event) { unsigned int NumChildren; Window ChildReturn, Root, Parent; Window * Children; /* Translate these coodinates back to relative to root */ - X11_XQueryTree(data->videodata->display, xevent.xconfigure.window, &Root, &Parent, &Children, &NumChildren); - X11_XTranslateCoordinates(xevent.xconfigure.display, - Parent, DefaultRootWindow(xevent.xconfigure.display), - xevent.xconfigure.x, xevent.xconfigure.y, - &xevent.xconfigure.x, &xevent.xconfigure.y, + X11_XQueryTree(data->videodata->display, xevent->xconfigure.window, &Root, &Parent, &Children, &NumChildren); + X11_XTranslateCoordinates(xevent->xconfigure.display, + Parent, DefaultRootWindow(xevent->xconfigure.display), + xevent->xconfigure.x, xevent->xconfigure.y, + &xevent->xconfigure.x, &xevent->xconfigure.y, &ChildReturn); } - if (xevent.xconfigure.x != data->last_xconfigure.x || - xevent.xconfigure.y != data->last_xconfigure.y) { + if (xevent->xconfigure.x != data->last_xconfigure.x || + xevent->xconfigure.y != data->last_xconfigure.y) { SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, - xevent.xconfigure.x, xevent.xconfigure.y); + xevent->xconfigure.x, xevent->xconfigure.y); #ifdef SDL_USE_IME if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){ /* Update IME candidate list position */ @@ -1029,13 +1136,13 @@ X11_DispatchEvent(_THIS) } #endif } - if (xevent.xconfigure.width != data->last_xconfigure.width || - xevent.xconfigure.height != data->last_xconfigure.height) { + if (xevent->xconfigure.width != data->last_xconfigure.width || + xevent->xconfigure.height != data->last_xconfigure.height) { SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, - xevent.xconfigure.width, - xevent.xconfigure.height); + xevent->xconfigure.width, + xevent->xconfigure.height); } - data->last_xconfigure = xevent.xconfigure; + data->last_xconfigure = xevent->xconfigure; } break; @@ -1044,11 +1151,11 @@ X11_DispatchEvent(_THIS) static int xdnd_version=0; - if (xevent.xclient.message_type == videodata->XdndEnter) { + if (xevent->xclient.message_type == videodata->XdndEnter) { - SDL_bool use_list = xevent.xclient.data.l[1] & 1; - data->xdnd_source = xevent.xclient.data.l[0]; - xdnd_version = (xevent.xclient.data.l[1] >> 24); + SDL_bool use_list = xevent->xclient.data.l[1] & 1; + data->xdnd_source = xevent->xclient.data.l[0]; + xdnd_version = (xevent->xclient.data.l[1] >> 24); #ifdef DEBUG_XEVENTS printf("XID of source window : %ld\n", data->xdnd_source); printf("Protocol version to use : %d\n", xdnd_version); @@ -1064,25 +1171,25 @@ X11_DispatchEvent(_THIS) X11_XFree(p.data); } else { /* pick from list of three */ - data->xdnd_req = X11_PickTargetFromAtoms(display, xevent.xclient.data.l[2], xevent.xclient.data.l[3], xevent.xclient.data.l[4]); + data->xdnd_req = X11_PickTargetFromAtoms(display, xevent->xclient.data.l[2], xevent->xclient.data.l[3], xevent->xclient.data.l[4]); } } - else if (xevent.xclient.message_type == videodata->XdndPosition) { + else if (xevent->xclient.message_type == videodata->XdndPosition) { #ifdef DEBUG_XEVENTS Atom act= videodata->XdndActionCopy; if(xdnd_version >= 2) { - act = xevent.xclient.data.l[4]; + act = xevent->xclient.data.l[4]; } printf("Action requested by user is : %s\n", X11_XGetAtomName(display , act)); #endif /* reply with status */ - memset(&m, 0, sizeof(XClientMessageEvent)); + SDL_memset(&m, 0, sizeof(XClientMessageEvent)); m.type = ClientMessage; - m.display = xevent.xclient.display; - m.window = xevent.xclient.data.l[0]; + m.display = xevent->xclient.display; + m.window = xevent->xclient.data.l[0]; m.message_type = videodata->XdndStatus; m.format=32; m.data.l[0] = data->xwindow; @@ -1091,47 +1198,47 @@ X11_DispatchEvent(_THIS) m.data.l[3] = 0; m.data.l[4] = videodata->XdndActionCopy; /* we only accept copying anyway */ - X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&m); + X11_XSendEvent(display, xevent->xclient.data.l[0], False, NoEventMask, (XEvent*)&m); X11_XFlush(display); } - else if(xevent.xclient.message_type == videodata->XdndDrop) { + else if(xevent->xclient.message_type == videodata->XdndDrop) { if (data->xdnd_req == None) { /* say again - not interested! */ - memset(&m, 0, sizeof(XClientMessageEvent)); + SDL_memset(&m, 0, sizeof(XClientMessageEvent)); m.type = ClientMessage; - m.display = xevent.xclient.display; - m.window = xevent.xclient.data.l[0]; + m.display = xevent->xclient.display; + m.window = xevent->xclient.data.l[0]; m.message_type = videodata->XdndFinished; m.format=32; m.data.l[0] = data->xwindow; m.data.l[1] = 0; m.data.l[2] = None; /* fail! */ - X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&m); + X11_XSendEvent(display, xevent->xclient.data.l[0], False, NoEventMask, (XEvent*)&m); } else { /* convert */ if(xdnd_version >= 1) { - X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, xevent.xclient.data.l[2]); + X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, xevent->xclient.data.l[2]); } else { X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, CurrentTime); } } } - else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) && - (xevent.xclient.format == 32) && - (xevent.xclient.data.l[0] == videodata->_NET_WM_PING)) { + else if ((xevent->xclient.message_type == videodata->WM_PROTOCOLS) && + (xevent->xclient.format == 32) && + (xevent->xclient.data.l[0] == videodata->_NET_WM_PING)) { Window root = DefaultRootWindow(display); #ifdef DEBUG_XEVENTS printf("window %p: _NET_WM_PING\n", data); #endif - xevent.xclient.window = root; - X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xevent); + xevent->xclient.window = root; + X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, xevent); break; } - else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) && - (xevent.xclient.format == 32) && - (xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) { + else if ((xevent->xclient.message_type == videodata->WM_PROTOCOLS) && + (xevent->xclient.format == 32) && + (xevent->xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) { #ifdef DEBUG_XEVENTS printf("window %p: WM_DELETE_WINDOW\n", data); @@ -1139,9 +1246,9 @@ X11_DispatchEvent(_THIS) SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0); break; } - else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) && - (xevent.xclient.format == 32) && - (xevent.xclient.data.l[0] == videodata->WM_TAKE_FOCUS)) { + else if ((xevent->xclient.message_type == videodata->WM_PROTOCOLS) && + (xevent->xclient.format == 32) && + (xevent->xclient.data.l[0] == videodata->WM_TAKE_FOCUS)) { #ifdef DEBUG_XEVENTS printf("window %p: WM_TAKE_FOCUS\n", data); @@ -1155,7 +1262,7 @@ X11_DispatchEvent(_THIS) /* Do we need to refresh ourselves? */ case Expose:{ #ifdef DEBUG_XEVENTS - printf("window %p: Expose (count = %d)\n", data, xevent.xexpose.count); + printf("window %p: Expose (count = %d)\n", data, xevent->xexpose.count); #endif SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0); } @@ -1165,10 +1272,10 @@ X11_DispatchEvent(_THIS) SDL_Mouse *mouse = SDL_GetMouse(); if(!mouse->relative_mode || mouse->relative_mode_warp) { #ifdef DEBUG_MOTION - printf("window %p: X11 motion: %d,%d\n", data, xevent.xmotion.x, xevent.xmotion.y); + printf("window %p: X11 motion: %d,%d\n", data, xevent->xmotion.x, xevent->xmotion.y); #endif - SDL_SendMouseMotion(data->window, 0, 0, xevent.xmotion.x, xevent.xmotion.y); + SDL_SendMouseMotion(data->window, 0, 0, xevent->xmotion.x, xevent->xmotion.y); } } break; @@ -1176,15 +1283,15 @@ X11_DispatchEvent(_THIS) case ButtonPress:{ int xticks = 0, yticks = 0; #ifdef DEBUG_XEVENTS - printf("window %p: ButtonPress (X11 button = %d)\n", data, xevent.xbutton.button); + printf("window %p: ButtonPress (X11 button = %d)\n", data, xevent->xbutton.button); #endif - if (X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) { - SDL_SendMouseWheel(data->window, 0, (float) xticks, (float) yticks, SDL_MOUSEWHEEL_NORMAL); + if (X11_IsWheelEvent(display,xevent,&xticks, &yticks)) { + SDL_SendMouseWheel(data->window, 0, (float) -xticks, (float) yticks, SDL_MOUSEWHEEL_NORMAL); } else { SDL_bool ignore_click = SDL_FALSE; - int button = xevent.xbutton.button; + int button = xevent->xbutton.button; if(button == Button1) { - if (ProcessHitTest(_this, data, &xevent)) { + if (ProcessHitTest(_this, data, xevent)) { SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); break; /* don't pass this event on to app. */ } @@ -1205,18 +1312,18 @@ X11_DispatchEvent(_THIS) SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button); } } - X11_UpdateUserTime(data, xevent.xbutton.time); + X11_UpdateUserTime(data, xevent->xbutton.time); } break; case ButtonRelease:{ - int button = xevent.xbutton.button; + int button = xevent->xbutton.button; /* The X server sends a Release event for each Press for wheels. Ignore them. */ int xticks = 0, yticks = 0; #ifdef DEBUG_XEVENTS - printf("window %p: ButtonRelease (X11 button = %d)\n", data, xevent.xbutton.button); + printf("window %p: ButtonRelease (X11 button = %d)\n", data, xevent->xbutton.button); #endif - if (!X11_IsWheelEvent(display, &xevent, &xticks, &yticks)) { + if (!X11_IsWheelEvent(display, xevent, &xticks, &yticks)) { if (button > 7) { /* see explanation at case ButtonPress */ button -= (8-SDL_BUTTON_X1); @@ -1233,13 +1340,13 @@ X11_DispatchEvent(_THIS) Atom real_type; unsigned long items_read, items_left; - char *name = X11_XGetAtomName(display, xevent.xproperty.atom); + char *name = X11_XGetAtomName(display, xevent->xproperty.atom); if (name) { - printf("window %p: PropertyNotify: %s %s time=%lu\n", data, name, (xevent.xproperty.state == PropertyDelete) ? "deleted" : "changed", xevent.xproperty.time); + printf("window %p: PropertyNotify: %s %s time=%lu\n", data, name, (xevent->xproperty.state == PropertyDelete) ? "deleted" : "changed", xevent->xproperty.time); X11_XFree(name); } - status = X11_XGetWindowProperty(display, data->xwindow, xevent.xproperty.atom, 0L, 8192L, False, AnyPropertyType, &real_type, &real_format, &items_read, &items_left, &propdata); + status = X11_XGetWindowProperty(display, data->xwindow, xevent->xproperty.atom, 0L, 8192L, False, AnyPropertyType, &real_type, &real_format, &items_read, &items_left, &propdata); if (status == Success && items_read > 0) { if (real_type == XA_INTEGER) { int *values = (int *)propdata; @@ -1311,16 +1418,16 @@ X11_DispatchEvent(_THIS) set _NET_WM_USER_TIME here, though. That's only for legit user interaction with the window. */ if (!data->user_time) { - data->user_time = xevent.xproperty.time; + data->user_time = xevent->xproperty.time; } - if (xevent.xproperty.atom == data->videodata->_NET_WM_STATE) { + if (xevent->xproperty.atom == data->videodata->_NET_WM_STATE) { /* Get the new state from the window manager. Compositing window managers can alter visibility of windows without ever mapping / unmapping them, so we handle that here, because they use the NETWM protocol to notify us of changes. */ - const Uint32 flags = X11_GetNetWMState(_this, xevent.xproperty.window); + const Uint32 flags = X11_GetNetWMState(_this, xevent->xproperty.window); const Uint32 changed = flags ^ data->window->flags; if ((changed & SDL_WINDOW_HIDDEN) || (changed & SDL_WINDOW_FULLSCREEN)) { @@ -1338,7 +1445,7 @@ X11_DispatchEvent(_THIS) SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0); } } - } else if (xevent.xproperty.atom == videodata->XKLAVIER_STATE) { + } else if (xevent->xproperty.atom == videodata->XKLAVIER_STATE) { /* Hack for Ubuntu 12.04 (etc) that doesn't send MappingNotify events when the keyboard layout changes (for example, changing from English to French on the menubar's keyboard @@ -1347,7 +1454,7 @@ X11_DispatchEvent(_THIS) right approach, but it seems to work. */ X11_UpdateKeymap(_this); SDL_SendKeymapChangedEvent(); - } else if (xevent.xproperty.atom == videodata->_NET_FRAME_EXTENTS) { + } else if (xevent->xproperty.atom == videodata->_NET_FRAME_EXTENTS) { Atom type; int format; unsigned long nitems, bytes_after; @@ -1370,10 +1477,10 @@ X11_DispatchEvent(_THIS) break; case SelectionNotify: { - Atom target = xevent.xselection.target; + Atom target = xevent->xselection.target; #ifdef DEBUG_XEVENTS printf("window %p: SelectionNotify (requestor = %ld, target = %ld)\n", data, - xevent.xselection.requestor, xevent.xselection.target); + xevent->xselection.requestor, xevent->xselection.target); #endif if (target == data->xdnd_req) { /* read data */ @@ -1421,7 +1528,7 @@ X11_DispatchEvent(_THIS) default:{ #ifdef DEBUG_XEVENTS - printf("window %p: Unhandled event %d\n", data, xevent.type); + printf("window %p: Unhandled event %d\n", data, xevent->type); #endif } break; @@ -1451,29 +1558,101 @@ X11_HandleFocusChanges(_THIS) } } } -/* Ack! X11_XPending() actually performs a blocking read if no events available */ -static int -X11_Pending(Display * display) + +static Bool +isAnyEvent(Display *display, XEvent *ev, XPointer arg) { - /* Flush the display connection and look to see if events are queued */ + return True; +} + +static SDL_bool +X11_PollEvent(Display *display, XEvent *event) +{ + if (!X11_XCheckIfEvent(display, event, isAnyEvent, NULL)) { + return SDL_FALSE; + } + + return SDL_TRUE; +} + +void +X11_SendWakeupEvent(_THIS, SDL_Window *window) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + Display *req_display = data->request_display; + Window xwindow = ((SDL_WindowData *) window->driverdata)->xwindow; + XClientMessageEvent event; + + SDL_memset(&event, 0, sizeof(XClientMessageEvent)); + event.type = ClientMessage; + event.display = req_display; + event.send_event = True; + event.message_type = data->_SDL_WAKEUP; + event.format = 8; + + X11_XSendEvent(req_display, xwindow, False, NoEventMask, (XEvent *) &event); + /* XSendEvent returns a status and it could be BadValue or BadWindow. If an + error happens it is an SDL's internal error and there is nothing we can do here. */ + X11_XFlush(req_display); +} + +int +X11_WaitEventTimeout(_THIS, int timeout) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + Display *display; + XEvent xevent; + display = videodata->display; + + SDL_zero(xevent); + + /* Flush and poll to grab any events already read and queued */ X11_XFlush(display); - if (X11_XEventsQueued(display, QueuedAlready)) { - return (1); + if (X11_PollEvent(display, &xevent)) { + /* Fall through */ + } else if (timeout == 0) { + return 0; + } else { + /* Use SDL_IOR_NO_RETRY to ensure SIGINT will break us out of our wait */ + int err = SDL_IOReady(ConnectionNumber(display), SDL_IOR_READ | SDL_IOR_NO_RETRY, timeout); + if (err > 0) { + if (!X11_PollEvent(display, &xevent)) { + /* Someone may have beat us to reading the fd. Return 1 here to + * trigger the normal spurious wakeup logic in the event core. */ + return 1; + } + } else if (err == 0) { + /* Timeout */ + return 0; + } else { + /* Error returned from poll()/select() */ + + if (errno == EINTR) { + /* If the wait was interrupted by a signal, we may have generated a + * SDL_QUIT event. Let the caller know to call SDL_PumpEvents(). */ + return 1; + } else { + return err; + } + } } - /* More drastic measures are required -- see if X is ready to talk */ - if (SDL_IOReady(ConnectionNumber(display), SDL_FALSE, 0)) { - return (X11_XPending(display)); - } + X11_DispatchEvent(_this, &xevent); - /* Oh well, nothing is ready .. */ - return (0); +#ifdef SDL_USE_IME + if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){ + SDL_IME_PumpEvents(); + } +#endif + return 1; } void X11_PumpEvents(_THIS) { SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + XEvent xevent; + int i; if (data->last_mode_change_deadline) { if (SDL_TICKS_PASSED(SDL_GetTicks(), data->last_mode_change_deadline)) { @@ -1496,9 +1675,11 @@ X11_PumpEvents(_THIS) } } + SDL_zero(xevent); + /* Keep processing pending events */ - while (X11_Pending(data->display)) { - X11_DispatchEvent(_this); + while (X11_PollEvent(data->display, &xevent)) { + X11_DispatchEvent(_this, &xevent); } #ifdef SDL_USE_IME @@ -1509,6 +1690,15 @@ X11_PumpEvents(_THIS) /* FIXME: Only need to do this when there are pending focus changes */ X11_HandleFocusChanges(_this); + + /* FIXME: Only need to do this when there are flashing windows */ + for (i = 0; i < data->numwindows; ++i) { + if (data->windowlist[i] != NULL && + data->windowlist[i]->flash_cancel_time && + SDL_TICKS_PASSED(SDL_GetTicks(), data->windowlist[i]->flash_cancel_time)) { + X11_FlashWindow(_this, data->windowlist[i]->window, SDL_FLASH_CANCEL); + } + } } diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11events.h b/Engine/lib/sdl/src/video/x11/SDL_x11events.h index df0782cb5..fc8a57ae2 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11events.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,6 +24,8 @@ #define SDL_x11events_h_ extern void X11_PumpEvents(_THIS); +extern int X11_WaitEventTimeout(_THIS, int timeout); +extern void X11_SendWakeupEvent(_THIS, SDL_Window *window); extern void X11_SuspendScreenSaver(_THIS); #endif /* SDL_x11events_h_ */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11framebuffer.c b/Engine/lib/sdl/src/video/x11/SDL_x11framebuffer.c index 53e7ab00c..123ad8ffb 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11framebuffer.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11framebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -115,6 +115,7 @@ X11_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, shmdt(shminfo->shmaddr); } else { /* Done! */ + data->ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) ? MSBFirst : LSBFirst; data->use_mitshm = SDL_TRUE; *pixels = shminfo->shmaddr; return 0; @@ -135,6 +136,7 @@ X11_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, SDL_free(*pixels); return SDL_SetError("Couldn't create XImage"); } + data->ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) ? MSBFirst : LSBFirst; return 0; } diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11framebuffer.h b/Engine/lib/sdl/src/video/x11/SDL_x11framebuffer.h index c26b4d9e2..63e73604a 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11framebuffer.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11framebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c b/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c index ce53e52f2..c82570c62 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,7 +31,7 @@ #include #include -#include "imKStoUCS.h" +#include "../../events/imKStoUCS.h" #ifdef X_HAVE_UTF8_STRING #include @@ -205,7 +205,7 @@ X11_KeyCodeToUcs4(_THIS, KeyCode keycode, unsigned char group) return 0; } - return X11_KeySymToUcs4(keysym); + return SDL_KeySymToUcs4(keysym); } KeySym @@ -267,7 +267,9 @@ X11_InitKeyboard(_THIS) int best_index; int distance; Bool xkb_repeat = 0; - XKeyboardState values = { .global_auto_repeat = AutoRepeatModeOff }; + XKeyboardState values; + SDL_zero(values); + values.global_auto_repeat = AutoRepeatModeOff; X11_XGetKeyboardControl(data->display, &values); if (values.global_auto_repeat != AutoRepeatModeOn) @@ -278,7 +280,7 @@ X11_InitKeyboard(_THIS) int xkb_major = XkbMajorVersion; int xkb_minor = XkbMinorVersion; - if (X11_XkbQueryExtension(data->display, NULL, NULL, NULL, &xkb_major, &xkb_minor)) { + if (X11_XkbQueryExtension(data->display, NULL, &data->xkb_event, NULL, &xkb_major, &xkb_minor)) { data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd); } diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.h b/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.h index a89437541..dacaf7e18 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.c b/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.c index d7a829b09..aafccca9b 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -334,10 +334,10 @@ X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data ) /* Location for first button. */ if ( messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT ) { - x = data->dialog_width - ( data->dialog_width - width_of_buttons ) / 2 - ( button_width + button_spacing ); - } else { - x = ( data->dialog_width - width_of_buttons ) / 2; - } + x = data->dialog_width - ( data->dialog_width - width_of_buttons ) / 2 - ( button_width + button_spacing ); + } else { + x = ( data->dialog_width - width_of_buttons ) / 2; + } y = ybuttons + ( data->dialog_height - ybuttons - button_height ) / 2; for ( i = 0; i < data->numbuttons; i++ ) { @@ -352,11 +352,11 @@ X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data ) data->buttonpos[ i ].y = y + ( button_height - button_text_height - 1 ) / 2 + button_text_height; /* Scoot over for next button. */ - if ( messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT ) { - x -= button_width + button_spacing; - } else { - x += button_width + button_spacing; - } + if ( messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT ) { + x -= button_width + button_spacing; + } else { + x += button_width + button_spacing; + } } } @@ -404,11 +404,10 @@ X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data ) int x, y; XSizeHints *sizehints; XSetWindowAttributes wnd_attr; - Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG, _NET_WM_NAME; + Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG; Display *display = data->display; SDL_WindowData *windowdata = NULL; const SDL_MessageBoxData *messageboxdata = data->messageboxdata; - char *title_locale = NULL; if ( messageboxdata->window ) { SDL_DisplayData *displaydata = @@ -452,32 +451,7 @@ X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data ) X11_XSetTransientForHint( display, data->window, windowdata->xwindow ); } - X11_XStoreName( display, data->window, messageboxdata->title ); - _NET_WM_NAME = X11_XInternAtom(display, "_NET_WM_NAME", False); - - title_locale = SDL_iconv_utf8_locale(messageboxdata->title); - if (title_locale) { - XTextProperty titleprop; - Status status = X11_XStringListToTextProperty(&title_locale, 1, &titleprop); - SDL_free(title_locale); - if (status) { - X11_XSetTextProperty(display, data->window, &titleprop, XA_WM_NAME); - X11_XFree(titleprop.value); - } - } - -#ifdef X_HAVE_UTF8_STRING - if (SDL_X11_HAVE_UTF8) { - XTextProperty titleprop; - Status status = X11_Xutf8TextListToTextProperty(display, (char **) &messageboxdata->title, 1, - XUTF8StringStyle, &titleprop); - if (status == Success) { - X11_XSetTextProperty(display, data->window, &titleprop, - _NET_WM_NAME); - X11_XFree(titleprop.value); - } - } -#endif + SDL_X11_SetWindowTitle(display, data->window, (char*)messageboxdata->title); /* Let the window manager know this is a dialog box */ _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.h b/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.h index 1fd91e44f..bb85a6525 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11modes.c b/Engine/lib/sdl/src/video/x11/SDL_x11modes.c index 79ad2472c..c1efe243c 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11modes.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11modes.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -257,7 +257,7 @@ static int CalculateXRandRRefreshRate(const XRRModeInfo *info) { return (info->hTotal && info->vTotal) ? - round(((double)info->dotClock / (double)(info->hTotal * info->vTotal))) : 0; + SDL_round(((double)info->dotClock / (double)(info->hTotal * info->vTotal))) : 0; } static SDL_bool @@ -322,7 +322,7 @@ SetXRandRDisplayName(Display *dpy, Atom EDID, char *name, const size_t namelen, dump_monitor_info(info); #endif SDL_strlcpy(name, info->dsc_product_name, namelen); - free(info); + SDL_free(info); } X11_XFree(prop); } @@ -345,6 +345,29 @@ SetXRandRDisplayName(Display *dpy, Atom EDID, char *name, const size_t namelen, #endif } +static int +GetXftDPI(Display* dpy) +{ + char* xdefault_resource; + int xft_dpi, err; + + xdefault_resource = X11_XGetDefault(dpy, "Xft", "dpi"); + + if(!xdefault_resource) { + return 0; + } + + /* + * It's possible for SDL_atoi to call SDL_strtol, if it fails due to a + * overflow or an underflow, it will return LONG_MAX or LONG_MIN and set + * errno to ERANGE. So we need to check for this so we dont get crazy dpi + * values + */ + xft_dpi = SDL_atoi(xdefault_resource); + err = errno; + + return err == ERANGE ? 0 : xft_dpi; +} static int X11_InitModes_XRandR(_THIS) @@ -417,6 +440,7 @@ X11_InitModes_XRandR(_THIS) RRMode modeID; RRCrtc output_crtc; XRRCrtcInfo *crtc; + int xft_dpi = 0; /* The primary output _should_ always be sorted first, but just in case... */ if ((looking_for_primary && (res->outputs[output] != primary)) || @@ -471,6 +495,14 @@ X11_InitModes_XRandR(_THIS) displaydata->hdpi = display_mm_width ? (((float) mode.w) * 25.4f / display_mm_width) : 0.0f; displaydata->vdpi = display_mm_height ? (((float) mode.h) * 25.4f / display_mm_height) : 0.0f; displaydata->ddpi = SDL_ComputeDiagonalDPI(mode.w, mode.h, ((float) display_mm_width) / 25.4f,((float) display_mm_height) / 25.4f); + + /* if xft dpi is available we will use this over xrandr */ + xft_dpi = GetXftDPI(dpy); + if(xft_dpi > 0) { + displaydata->hdpi = (float)xft_dpi; + displaydata->vdpi = (float)xft_dpi; + } + displaydata->scanline_pad = scanline_pad; displaydata->x = display_x; displaydata->y = display_y; @@ -817,6 +849,16 @@ X11_InitModes(_THIS) if (_this->num_displays == 0) { return SDL_SetError("No available displays"); } + +#if SDL_VIDEO_DRIVER_X11_XVIDMODE + if (use_vidmode) { /* we intend to remove support for XVidMode soon. */ + SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "SDL is using XVidMode to manage your displays!"); + SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "This almost always means either SDL was misbuilt"); + SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "or your X server is insufficient. Please check your setup!"); + SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Fullscreen and/or multiple displays will not work well."); + } +#endif + return 0; } @@ -963,6 +1005,15 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display) } } +/* This catches an error from XRRSetScreenSize, as a workaround for now. */ +/* !!! FIXME: remove this later when we have a better solution. */ +static int (*PreXRRSetScreenSizeErrorHandler)(Display *, XErrorEvent *) = NULL; +static int +SDL_XRRSetScreenSizeErrHandler(Display *d, XErrorEvent *e) +{ + return (e->error_code == BadMatch) ? 0 : PreXRRSetScreenSizeErrorHandler(d, e); +} + int X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode) { @@ -970,6 +1021,7 @@ X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode Display *display = viddata->display; SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata; SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; + int mm_width, mm_height; viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2); @@ -998,10 +1050,45 @@ X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode return SDL_SetError("Couldn't get XRandR crtc info"); } + if (crtc->mode == modedata->xrandr_mode) { +#ifdef X11MODES_DEBUG + printf("already in desired mode 0x%lx (%ux%u), nothing to do\n", + crtc->mode, crtc->width, crtc->height); +#endif + status = Success; + goto freeInfo; + } + + X11_XGrabServer(display); + status = X11_XRRSetCrtcConfig(display, res, output_info->crtc, CurrentTime, + 0, 0, None, crtc->rotation, NULL, 0); + if (status != Success) { + goto ungrabServer; + } + + mm_width = mode->w * DisplayWidthMM(display, data->screen) / DisplayWidth(display, data->screen); + mm_height = mode->h * DisplayHeightMM(display, data->screen) / DisplayHeight(display, data->screen); + + /* !!! FIXME: this can get into a problem scenario when a window is + bigger than a physical monitor in a configuration where one screen + spans multiple physical monitors. A detailed reproduction case is + discussed at https://github.com/libsdl-org/SDL/issues/4561 ... + for now we cheat and just catch the X11 error and carry on, which + is likely to cause subtle issues but is better than outright + crashing */ + X11_XSync(display, False); + PreXRRSetScreenSizeErrorHandler = X11_XSetErrorHandler(SDL_XRRSetScreenSizeErrHandler); + X11_XRRSetScreenSize(display, RootWindow(display, data->screen), mode->w, mode->h, mm_width, mm_height); + X11_XSync(display, False); + X11_XSetErrorHandler(PreXRRSetScreenSizeErrorHandler); + status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime, crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation, &data->xrandr_output, 1); +ungrabServer: + X11_XUngrabServer(display); +freeInfo: X11_XRRFreeCrtcInfo(crtc); X11_XRRFreeOutputInfo(output_info); X11_XRRFreeScreenResources(res); diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11modes.h b/Engine/lib/sdl/src/video/x11/SDL_x11modes.h index fc5dd63f9..554868016 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11modes.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11modes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11mouse.c b/Engine/lib/sdl/src/video/x11/SDL_x11mouse.c index 3082d194d..9eb1ddd30 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11mouse.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11mouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -77,7 +77,7 @@ X11_CreateDefaultCursor() cursor = SDL_calloc(1, sizeof(*cursor)); if (cursor) { /* None is used to indicate the default cursor */ - cursor->driverdata = (void*)None; + cursor->driverdata = (void*)(uintptr_t)None; } else { SDL_OutOfMemory(); } @@ -195,6 +195,8 @@ X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y) &fg, &bg, hot_x, hot_y); X11_XFreePixmap(display, data_pixmap); X11_XFreePixmap(display, mask_pixmap); + SDL_free(data_bits); + SDL_free(mask_bits); return cursor; } @@ -216,7 +218,7 @@ X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) if (x11_cursor == None) { x11_cursor = X11_CreatePixmapCursor(surface, hot_x, hot_y); } - cursor->driverdata = (void*)x11_cursor; + cursor->driverdata = (void*)(uintptr_t)x11_cursor; } else { SDL_OutOfMemory(); } @@ -257,7 +259,7 @@ X11_CreateSystemCursor(SDL_SystemCursor id) x11_cursor = X11_XCreateFontCursor(GetDisplay(), shape); - cursor->driverdata = (void*)x11_cursor; + cursor->driverdata = (void*)(uintptr_t)x11_cursor; } else { SDL_OutOfMemory(); } @@ -292,14 +294,15 @@ X11_ShowCursor(SDL_Cursor * cursor) SDL_VideoDevice *video = SDL_GetVideoDevice(); Display *display = GetDisplay(); SDL_Window *window; - SDL_WindowData *data; for (window = video->windows; window; window = window->next) { - data = (SDL_WindowData *)window->driverdata; - if (x11_cursor != None) { - X11_XDefineCursor(display, data->xwindow, x11_cursor); - } else { - X11_XUndefineCursor(display, data->xwindow); + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + if (data) { + if (x11_cursor != None) { + X11_XDefineCursor(display, data->xwindow, x11_cursor); + } else { + X11_XUndefineCursor(display, data->xwindow); + } } } X11_XFlush(display); @@ -321,7 +324,15 @@ static void X11_WarpMouse(SDL_Window * window, int x, int y) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + +#if SDL_VIDEO_DRIVER_X11_XFIXES + /* If we have no barrier, we need to warp */ + if (data->pointer_barrier_active == SDL_FALSE) { + WarpMouseInternal(data->xwindow, x, y); + } +#else WarpMouseInternal(data->xwindow, x, y); +#endif } static int diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11mouse.h b/Engine/lib/sdl/src/video/x11/SDL_x11mouse.h index b6628e1cb..e44adacb1 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11mouse.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c b/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c index 07a71c0ba..64b06340a 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c @@ -1,6 +1,7 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 2021 NVIDIA Corporation This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -141,7 +142,7 @@ typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy, #endif #define OPENGL_REQUIRES_DLOPEN -#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN) +#if defined(OPENGL_REQUIRES_DLOPEN) && defined(HAVE_DLOPEN) #include #define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL)) #define GL_LoadFunction dlsym @@ -173,7 +174,7 @@ X11_GL_LoadLibrary(_THIS, const char *path) } _this->gl_config.dll_handle = GL_LoadObject(path); if (!_this->gl_config.dll_handle) { -#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN) +#if defined(OPENGL_REQUIRES_DLOPEN) && defined(HAVE_DLOPEN) SDL_SetError("Failed loading %s: %s", path, dlerror()); #endif return -1; @@ -420,6 +421,9 @@ X11_GL_InitExtensions(_THIS) _this->gl_data->glXChooseFBConfig = (GLXFBConfig *(*)(Display *, int, const int *, int *)) X11_GL_GetProcAddress(_this, "glXChooseFBConfig"); + _this->gl_data->glXGetVisualFromFBConfig = + (XVisualInfo *(*)(Display *, GLXFBConfig)) + X11_GL_GetProcAddress(_this, "glXGetVisualFromFBConfig"); } /* Check for GLX_EXT_visual_rating */ @@ -598,7 +602,7 @@ X11_GL_GetVisual(_THIS, Display * display, int screen) { /* 64 seems nice. */ int attribs[64]; - XVisualInfo *vinfo; + XVisualInfo *vinfo = NULL; int *pvistypeattr = NULL; if (!_this->gl_data) { @@ -606,12 +610,33 @@ X11_GL_GetVisual(_THIS, Display * display, int screen) return NULL; } - X11_GL_GetAttributes(_this, display, screen, attribs, 64, SDL_FALSE, &pvistypeattr); - vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs); + if (_this->gl_data->glXChooseFBConfig && + _this->gl_data->glXGetVisualFromFBConfig) { + GLXFBConfig *framebuffer_config = NULL; + int fbcount = 0; - if (!vinfo && (pvistypeattr != NULL)) { - *pvistypeattr = None; + X11_GL_GetAttributes(_this, display, screen, attribs, 64, SDL_TRUE, &pvistypeattr); + framebuffer_config = _this->gl_data->glXChooseFBConfig(display, screen, attribs, &fbcount); + if (!framebuffer_config && (pvistypeattr != NULL)) { + *pvistypeattr = None; + framebuffer_config = _this->gl_data->glXChooseFBConfig(display, screen, attribs, &fbcount); + } + + if (framebuffer_config) { + vinfo = _this->gl_data->glXGetVisualFromFBConfig(display, framebuffer_config[0]); + } + + X11_XFree(framebuffer_config); + } + + if (!vinfo) { + X11_GL_GetAttributes(_this, display, screen, attribs, 64, SDL_FALSE, &pvistypeattr); vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs); + + if (!vinfo && (pvistypeattr != NULL)) { + *pvistypeattr = None; + vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs); + } } if (!vinfo) { diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11opengl.h b/Engine/lib/sdl/src/video/x11/SDL_x11opengl.h index 3726a23c7..71e03c0c9 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11opengl.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -53,6 +53,7 @@ struct SDL_GLDriverData GLXContext (*glXCreateContext) (Display*,XVisualInfo*,GLXContext,Bool); GLXContext (*glXCreateContextAttribsARB) (Display*,GLXFBConfig,GLXContext,Bool,const int *); GLXFBConfig *(*glXChooseFBConfig) (Display*,int,const int *,int *); + XVisualInfo *(*glXGetVisualFromFBConfig) (Display*,GLXFBConfig); void (*glXDestroyContext) (Display*, GLXContext); Bool(*glXMakeCurrent) (Display*,GLXDrawable,GLXContext); void (*glXSwapBuffers) (Display*, GLXDrawable); diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11opengles.c b/Engine/lib/sdl/src/video/x11/SDL_x11opengles.c index d3bdaa648..e1ec4e4d2 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11opengles.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11opengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11opengles.h b/Engine/lib/sdl/src/video/x11/SDL_x11opengles.h index afb4edf6e..5219553ca 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11opengles.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11opengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11shape.c b/Engine/lib/sdl/src/video/x11/SDL_x11shape.c index b55ac2c65..7d78f1127 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11shape.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11shape.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,7 +35,7 @@ X11_CreateShaper(SDL_Window* window) { #if SDL_VIDEO_DRIVER_X11_XSHAPE if (SDL_X11_HAVE_XSHAPE) { /* Make sure X server supports it. */ - result = malloc(sizeof(SDL_WindowShaper)); + result = SDL_malloc(sizeof(SDL_WindowShaper)); result->window = window; result->mode.mode = ShapeModeDefault; result->mode.parameters.binarizationCutoff = 1; @@ -65,13 +65,13 @@ X11_ResizeWindowShape(SDL_Window* window) { if(data->bitmapsize != bitmapsize || data->bitmap == NULL) { data->bitmapsize = bitmapsize; if(data->bitmap != NULL) - free(data->bitmap); - data->bitmap = malloc(data->bitmapsize); + SDL_free(data->bitmap); + data->bitmap = SDL_malloc(data->bitmapsize); if(data->bitmap == NULL) { return SDL_SetError("Could not allocate memory for shaped-window bitmap."); } } - memset(data->bitmap,0,data->bitmapsize); + SDL_memset(data->bitmap,0,data->bitmapsize); window->shaper->userx = window->x; window->shaper->usery = window->y; diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11shape.h b/Engine/lib/sdl/src/video/x11/SDL_x11shape.h index d0b26e8d4..4d54fb168 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11shape.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11shape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11sym.h b/Engine/lib/sdl/src/video/x11/SDL_x11sym.h index c7286d753..67b0a793a 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11sym.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11sym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -97,7 +97,6 @@ SDL_X11_SYM(int,XMapRaised,(Display* a,Window b),(a,b),return) SDL_X11_SYM(Status,XMatchVisualInfo,(Display* a,int b,int c,int d,XVisualInfo* e),(a,b,c,d,e),return) SDL_X11_SYM(int,XMissingExtension,(Display* a,_Xconst char* b),(a,b),return) SDL_X11_SYM(int,XMoveWindow,(Display* a,Window b,int c,int d),(a,b,c,d),return) -SDL_X11_SYM(int,XNextEvent,(Display* a,XEvent* b),(a,b),return) SDL_X11_SYM(Display*,XOpenDisplay,(_Xconst char* a),(a),return) SDL_X11_SYM(Status,XInitThreads,(void),(),return) SDL_X11_SYM(int,XPeekEvent,(Display* a,XEvent* b),(a,b),return) @@ -109,6 +108,7 @@ SDL_X11_SYM(int,XRaiseWindow,(Display* a,Window b),(a,b),return) SDL_X11_SYM(int,XReparentWindow,(Display* a,Window b,Window c,int d,int e),(a,b,c,d,e),return) SDL_X11_SYM(int,XResetScreenSaver,(Display* a),(a),return) SDL_X11_SYM(int,XResizeWindow,(Display* a,Window b,unsigned int c,unsigned int d),(a,b,c,d),return) +SDL_X11_SYM(int,XScreenNumberOfScreen,(Screen* a),(a),return) SDL_X11_SYM(int,XSelectInput,(Display* a,Window b,long c),(a,b,c),return) SDL_X11_SYM(Status,XSendEvent,(Display* a,Window b,Bool c,long d,XEvent* e),(a,b,c,d,e),return) SDL_X11_SYM(XErrorHandler,XSetErrorHandler,(XErrorHandler a),(a),return) @@ -119,8 +119,9 @@ SDL_X11_SYM(int,XSetSelectionOwner,(Display* a,Atom b,Window c,Time d),(a,b,c,d) SDL_X11_SYM(int,XSetTransientForHint,(Display* a,Window b,Window c),(a,b,c),return) SDL_X11_SYM(void,XSetTextProperty,(Display* a,Window b,XTextProperty* c,Atom d),(a,b,c,d),) SDL_X11_SYM(int,XSetWindowBackground,(Display* a,Window b,unsigned long c),(a,b,c),return) -SDL_X11_SYM(void,XSetWMProperties,(Display* a,Window b,XTextProperty* c,XTextProperty* d,char** e,int f,XSizeHints* g,XWMHints* h,XClassHint* i),(a,b,c,d,e,f,g,h,i),) +SDL_X11_SYM(void,XSetWMHints,(Display* a,Window b,XWMHints* c),(a,b,c),) SDL_X11_SYM(void,XSetWMNormalHints,(Display* a,Window b,XSizeHints* c),(a,b,c),) +SDL_X11_SYM(void,XSetWMProperties,(Display* a,Window b,XTextProperty* c,XTextProperty* d,char** e,int f,XSizeHints* g,XWMHints* h,XClassHint* i),(a,b,c,d,e,f,g,h,i),) SDL_X11_SYM(Status,XSetWMProtocols,(Display* a,Window b,Atom* c,int d),(a,b,c,d),return) SDL_X11_SYM(int,XStoreColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return) SDL_X11_SYM(int,XStoreName,(Display* a,Window b,_Xconst char* c),(a,b,c),return) @@ -138,15 +139,7 @@ SDL_X11_SYM(int,XWarpPointer,(Display* a,Window b,Window c,int d,int e,unsigned SDL_X11_SYM(int,XWindowEvent,(Display* a,Window b,long c,XEvent* d),(a,b,c,d),return) SDL_X11_SYM(Status,XWithdrawWindow,(Display* a,Window b,int c),(a,b,c),return) SDL_X11_SYM(VisualID,XVisualIDFromVisual,(Visual* a),(a),return) -#if SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY -SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,_Xconst char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return) -#else -SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return) -#endif -SDL_X11_SYM(XExtensionInfo*,XextCreateExtension,(void),(),return) -SDL_X11_SYM(void,XextDestroyExtension,(XExtensionInfo* a),(a),) -SDL_X11_SYM(XExtDisplayInfo*,XextFindDisplay,(XExtensionInfo* a,Display* b),(a,b),return) -SDL_X11_SYM(int,XextRemoveDisplay,(XExtensionInfo* a,Display* b),(a,b),return) +SDL_X11_SYM(char*,XGetDefault,(Display* a,_Xconst char* b, _Xconst char* c),(a,b,c),return) SDL_X11_SYM(Bool,XQueryExtension,(Display* a,_Xconst char* b,int* c,int* d,int* e),(a,b,c,d,e),return) SDL_X11_SYM(char *,XDisplayString,(Display* a),(a),return) SDL_X11_SYM(int,XGetErrorText,(Display* a,int b,char* c,int d),(a,b,c,d),return) @@ -163,6 +156,16 @@ SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,S SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return) SDL_X11_SYM(void,XRefreshKeyboardMapping,(XMappingEvent *a),(a),) SDL_X11_SYM(int,XQueryTree,(Display* a,Window b,Window* c,Window* d,Window** e,unsigned int* f),(a,b,c,d,e,f),return) +SDL_X11_SYM(Bool,XSupportsLocale,(void),(),return) +SDL_X11_SYM(Status,XmbTextListToTextProperty,(Display* a,char** b,int c,XICCEncodingStyle d,XTextProperty* e),(a,b,c,d,e),return) + +#if SDL_VIDEO_DRIVER_X11_XFIXES +SDL_X11_MODULE(XFIXES) +SDL_X11_SYM(PointerBarrier, XFixesCreatePointerBarrier, (Display* a, Window b, int c, int d, int e, int f, int g, int h, int *i),(a,b,c,d,e,f,g,h,i),return) +SDL_X11_SYM(void, XFixesDestroyPointerBarrier, (Display* a, PointerBarrier b), (a,b),) +SDL_X11_SYM(int, XIBarrierReleasePointer,(Display* a, int b, PointerBarrier c, BarrierEventID d), (a,b,c,d), return) /* this is actually Xinput2 */ +SDL_X11_SYM(Status, XFixesQueryVersion,(Display* a, int* b, int* c), (a,b,c), return) +#endif #if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS SDL_X11_SYM(Bool,XGetEventData,(Display* a,XGenericEventCookie* b),(a,b),return) @@ -182,6 +185,7 @@ SDL_X11_SYM(XkbDescPtr,XkbGetMap,(Display* a,unsigned int b,unsigned int c),(a,b SDL_X11_SYM(void,XkbFreeClientMap,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),) SDL_X11_SYM(void,XkbFreeKeyboard,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),) SDL_X11_SYM(Bool,XkbSetDetectableAutoRepeat,(Display* a, Bool b, Bool* c),(a,b,c),return) +SDL_X11_SYM(Bool,XkbSelectEvents,(Display* a, unsigned int b, unsigned int c, unsigned int d),(a,b,c,d),return) #endif #if NeedWidePrototypes @@ -275,6 +279,8 @@ SDL_X11_MODULE(XINPUT2) SDL_X11_SYM(XIDeviceInfo*,XIQueryDevice,(Display *a,int b,int *c),(a,b,c),return) SDL_X11_SYM(void,XIFreeDeviceInfo,(XIDeviceInfo *a),(a),) SDL_X11_SYM(int,XISelectEvents,(Display *a,Window b,XIEventMask *c,int d),(a,b,c,d),return) +SDL_X11_SYM(int,XIGrabTouchBegin,(Display *a,int b,Window c,int d,XIEventMask *e,int f,XIGrabModifiers *g),(a,b,c,d,e,f,g),return) +SDL_X11_SYM(int,XIUngrabTouchBegin, (Display *a,int b,Window c, int d,XIGrabModifiers *e),(a, b, c, d, e),return) SDL_X11_SYM(Status,XIQueryVersion,(Display *a,int *b,int *c),(a,b,c),return) SDL_X11_SYM(XIEventMask*,XIGetSelectedEvents,(Display *a,Window b,int *c),(a,b,c),return) #endif diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11touch.c b/Engine/lib/sdl/src/video/x11/SDL_x11touch.c index aef86aa96..958bee9df 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11touch.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11touch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11touch.h b/Engine/lib/sdl/src/video/x11/SDL_x11touch.h index fba3f2764..61b61a34e 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11touch.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11touch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11video.c b/Engine/lib/sdl/src/video/x11/SDL_x11video.c index 4ae9544e6..fc8c878fb 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11video.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -36,6 +36,7 @@ #include "SDL_x11shape.h" #include "SDL_x11touch.h" #include "SDL_x11xinput2.h" +#include "SDL_x11xfixes.h" #if SDL_VIDEO_OPENGL_EGL #include "SDL_x11opengles.h" @@ -105,7 +106,13 @@ X11_DeleteDevice(SDL_VideoDevice * device) X11_XSetErrorHandler(orig_x11_errhandler); X11_XCloseDisplay(data->display); } + if (data->request_display) { + X11_XCloseDisplay(data->request_display); + } SDL_free(data->windowlist); + if (device->wakeup_lock) { + SDL_DestroyMutex(device->wakeup_lock); + } SDL_free(device->driverdata); SDL_free(device); @@ -181,7 +188,22 @@ X11_CreateDevice(int devindex) data->global_mouse_changed = SDL_TRUE; +#if SDL_VIDEO_DRIVER_X11_XFIXES + data->active_cursor_confined_window = NULL; +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + data->display = x11_display; + data->request_display = X11_XOpenDisplay(display); + if (data->request_display == NULL) { + X11_XCloseDisplay(data->display); + SDL_free(device->driverdata); + SDL_free(device); + SDL_X11_UnloadSymbols(); + return NULL; + } + + device->wakeup_lock = SDL_CreateMutex(); + #ifdef X11_DEBUG X11_XSynchronize(data->display, True); #endif @@ -198,9 +220,12 @@ X11_CreateDevice(int devindex) device->GetDisplayBounds = X11_GetDisplayBounds; device->GetDisplayUsableBounds = X11_GetDisplayUsableBounds; device->GetDisplayDPI = X11_GetDisplayDPI; + device->GetWindowICCProfile = X11_GetWindowICCProfile; device->SetDisplayMode = X11_SetDisplayMode; device->SuspendScreenSaver = X11_SuspendScreenSaver; device->PumpEvents = X11_PumpEvents; + device->WaitEventTimeout = X11_WaitEventTimeout; + device->SendWakeupEvent = X11_SendWakeupEvent; device->CreateSDLWindow = X11_CreateWindow; device->CreateSDLWindowFrom = X11_CreateWindowFrom; @@ -222,9 +247,11 @@ X11_CreateDevice(int devindex) device->RestoreWindow = X11_RestoreWindow; device->SetWindowBordered = X11_SetWindowBordered; device->SetWindowResizable = X11_SetWindowResizable; + device->SetWindowAlwaysOnTop = X11_SetWindowAlwaysOnTop; device->SetWindowFullscreen = X11_SetWindowFullscreen; device->SetWindowGammaRamp = X11_SetWindowGammaRamp; - device->SetWindowGrab = X11_SetWindowGrab; + device->SetWindowMouseGrab = X11_SetWindowMouseGrab; + device->SetWindowKeyboardGrab = X11_SetWindowKeyboardGrab; device->DestroyWindow = X11_DestroyWindow; device->CreateWindowFramebuffer = X11_CreateWindowFramebuffer; device->UpdateWindowFramebuffer = X11_UpdateWindowFramebuffer; @@ -232,6 +259,11 @@ X11_CreateDevice(int devindex) device->GetWindowWMInfo = X11_GetWindowWMInfo; device->SetWindowHitTest = X11_SetWindowHitTest; device->AcceptDragAndDrop = X11_AcceptDragAndDrop; + device->FlashWindow = X11_FlashWindow; + +#if SDL_VIDEO_DRIVER_X11_XFIXES + device->SetWindowMouseRect = X11_SetWindowMouseRect; +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ device->shape_driver.CreateShaper = X11_CreateShaper; device->shape_driver.SetWindowShape = X11_SetWindowShape; @@ -382,6 +414,7 @@ X11_VideoInit(_THIS) GET_ATOM(WM_PROTOCOLS); GET_ATOM(WM_DELETE_WINDOW); GET_ATOM(WM_TAKE_FOCUS); + GET_ATOM(WM_NAME); GET_ATOM(_NET_WM_STATE); GET_ATOM(_NET_WM_STATE_HIDDEN); GET_ATOM(_NET_WM_STATE_FOCUSED); @@ -401,6 +434,7 @@ X11_VideoInit(_THIS) GET_ATOM(_NET_WM_USER_TIME); GET_ATOM(_NET_ACTIVE_WINDOW); GET_ATOM(_NET_FRAME_EXTENTS); + GET_ATOM(_SDL_WAKEUP); GET_ATOM(UTF8_STRING); GET_ATOM(PRIMARY); GET_ATOM(XdndEnter); @@ -422,6 +456,14 @@ X11_VideoInit(_THIS) X11_InitXinput2(_this); +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + X11_InitXfixes(_this); +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + +#ifndef X_HAVE_UTF8_STRING +#warning X server does not support UTF8_STRING, a feature introduced in 2000! This is likely to become a hard error in a future libSDL2. +#endif + if (X11_InitKeyboard(_this) != 0) { return -1; } @@ -429,10 +471,6 @@ X11_VideoInit(_THIS) X11_InitTouch(_this); -#if SDL_USE_LIBDBUS - SDL_DBus_Init(); -#endif - return 0; } @@ -456,12 +494,6 @@ X11_VideoQuit(_THIS) X11_QuitKeyboard(_this); X11_QuitMouse(_this); X11_QuitTouch(_this); - -/* !!! FIXME: other subsystems use D-Bus, so we shouldn't quit it here; - have SDL.c do this at a higher level, or add refcounting. */ -#if SDL_USE_LIBDBUS - SDL_DBus_Quit(); -#endif } SDL_bool diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11video.h b/Engine/lib/sdl/src/video/x11/SDL_x11video.h index 04bedfbd1..8c7eb09ec 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11video.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -75,6 +75,7 @@ typedef struct SDL_VideoData { Display *display; + Display *request_display; char *classname; pid_t pid; XIM im; @@ -84,6 +85,9 @@ typedef struct SDL_VideoData int windowlistlength; XID window_group; Window clipboard_window; +#if SDL_VIDEO_DRIVER_X11_XFIXES + SDL_Window *active_cursor_confined_window; +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ /* This is true for ICCCM2.0-compliant window managers */ SDL_bool net_wm; @@ -92,6 +96,7 @@ typedef struct SDL_VideoData Atom WM_PROTOCOLS; Atom WM_DELETE_WINDOW; Atom WM_TAKE_FOCUS; + Atom WM_NAME; Atom _NET_WM_STATE; Atom _NET_WM_STATE_HIDDEN; Atom _NET_WM_STATE_FOCUSED; @@ -111,6 +116,7 @@ typedef struct SDL_VideoData Atom _NET_WM_USER_TIME; Atom _NET_ACTIVE_WINDOW; Atom _NET_FRAME_EXTENTS; + Atom _SDL_WAKEUP; Atom UTF8_STRING; Atom PRIMARY; Atom XdndEnter; @@ -137,6 +143,7 @@ typedef struct SDL_VideoData #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM XkbDescPtr xkb; #endif + int xkb_event; KeyCode filter_code; Time filter_time; diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11vulkan.c b/Engine/lib/sdl/src/video/x11/SDL_x11vulkan.c index 286da7242..b9eb34b88 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11vulkan.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11vulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11vulkan.h b/Engine/lib/sdl/src/video/x11/SDL_x11vulkan.h index c74707295..e9e422b0d 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11vulkan.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11vulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11window.c b/Engine/lib/sdl/src/video/x11/SDL_x11window.c index ef4fd8877..a6bd91d72 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11window.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11window.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,6 +32,7 @@ #include "SDL_x11mouse.h" #include "SDL_x11shape.h" #include "SDL_x11xinput2.h" +#include "SDL_x11xfixes.h" #if SDL_VIDEO_OPENGL_EGL #include "SDL_x11opengles.h" @@ -261,6 +262,7 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) } data->window = window; data->xwindow = w; + #ifdef X_HAVE_UTF8_STRING if (SDL_X11_HAVE_UTF8 && videodata->im) { data->ic = @@ -325,7 +327,7 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) SDL_SetKeyboardFocus(data->window); } - if (window->flags & SDL_WINDOW_INPUT_GRABBED) { + if (window->flags & SDL_WINDOW_MOUSE_GRABBED) { /* Tell x11 to clip mouse */ } } @@ -372,6 +374,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + const SDL_bool force_override_redirect = SDL_GetHintBoolean(SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT, SDL_FALSE); SDL_WindowData *windowdata; Display *display = data->display; int screen = displaydata->screen; @@ -389,6 +392,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) long compositor = 1; Atom _NET_WM_PID; long fevent = 0; + const char *hint = NULL; #if SDL_VIDEO_OPENGL_GLX || SDL_VIDEO_OPENGL_EGL const char *forced_visual_id = SDL_GetHint(SDL_HINT_VIDEO_X11_WINDOW_VISUALID); @@ -444,7 +448,8 @@ X11_CreateWindow(_THIS, SDL_Window * window) depth = displaydata->depth; } - xattr.override_redirect = ((window->flags & SDL_WINDOW_TOOLTIP) || (window->flags & SDL_WINDOW_POPUP_MENU)) ? True : False; + xattr.override_redirect = ((window->flags & SDL_WINDOW_TOOLTIP) || (window->flags & SDL_WINDOW_POPUP_MENU) || force_override_redirect) ? True : False; + xattr.backing_store = NotUseful; xattr.background_pixmap = None; xattr.border_pixel = 0; @@ -531,7 +536,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) window->x, window->y, window->w, window->h, 0, depth, InputOutput, visual, (CWOverrideRedirect | CWBackPixmap | CWBorderPixel | - CWColormap), &xattr); + CWBackingStore | CWColormap), &xattr); if (!w) { return SDL_SetError("Couldn't create window"); } @@ -587,6 +592,8 @@ X11_CreateWindow(_THIS, SDL_Window * window) wintype_name = "_NET_WM_WINDOW_TYPE_TOOLTIP"; } else if (window->flags & SDL_WINDOW_POPUP_MENU) { wintype_name = "_NET_WM_WINDOW_TYPE_POPUP_MENU"; + } else if ( ((hint = SDL_GetHint(SDL_HINT_X11_WINDOW_TYPE)) != NULL) && *hint ) { + wintype_name = hint; } else { wintype_name = "_NET_WM_WINDOW_TYPE_NORMAL"; compositor = 1; /* disable compositing for "normal" windows */ @@ -668,6 +675,11 @@ X11_CreateWindow(_THIS, SDL_Window * window) PropertyChangeMask | StructureNotifyMask | KeymapStateMask | fevent)); + /* For _ICC_PROFILE. */ + X11_XSelectInput(display, RootWindow(display, screen), PropertyChangeMask); + + X11_XkbSelectEvents(display, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask); + X11_XFlush(display); return 0; @@ -709,8 +721,10 @@ X11_GetWindowTitle(_THIS, Window xwindow) &items_read, &items_left, &propdata); if (status == Success && propdata) { title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Failed to convert WM_NAME title expecting UTF8! Title: %s", title); X11_XFree(propdata); } else { + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Could not get any window title response from Xorg, returning empty string!"); title = SDL_strdup(""); } } @@ -721,41 +735,11 @@ void X11_SetWindowTitle(_THIS, SDL_Window * window) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Window xwindow = data->xwindow; Display *display = data->videodata->display; - XTextProperty titleprop; - Status status; - const char *title = window->title ? window->title : ""; - char *title_locale = NULL; + char *title = window->title ? window->title : ""; -#ifdef X_HAVE_UTF8_STRING - Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME; -#endif - - title_locale = SDL_iconv_utf8_locale(title); - if (!title_locale) { - SDL_OutOfMemory(); - return; - } - - status = X11_XStringListToTextProperty(&title_locale, 1, &titleprop); - SDL_free(title_locale); - if (status) { - X11_XSetTextProperty(display, data->xwindow, &titleprop, XA_WM_NAME); - X11_XFree(titleprop.value); - } -#ifdef X_HAVE_UTF8_STRING - if (SDL_X11_HAVE_UTF8) { - status = X11_Xutf8TextListToTextProperty(display, (char **) &title, 1, - XUTF8StringStyle, &titleprop); - if (status == Success) { - X11_XSetTextProperty(display, data->xwindow, &titleprop, - _NET_WM_NAME); - X11_XFree(titleprop.value); - } - } -#endif - - X11_XFlush(display); + SDL_X11_SetWindowTitle(display, xwindow, title); } void @@ -1107,6 +1091,36 @@ X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) X11_XFlush(display); } +void +X11_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + Display *display = data->videodata->display; + Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; + Atom _NET_WM_STATE_ABOVE = data->videodata->_NET_WM_STATE_ABOVE; + + if (X11_IsWindowMapped(_this, window)) { + XEvent e; + + SDL_zero(e); + e.xany.type = ClientMessage; + e.xclient.message_type = _NET_WM_STATE; + e.xclient.format = 32; + e.xclient.window = data->xwindow; + e.xclient.data.l[0] = + on_top ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + e.xclient.data.l[1] = _NET_WM_STATE_ABOVE; + e.xclient.data.l[3] = 0l; + + X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, + SubstructureNotifyMask | SubstructureRedirectMask, &e); + } else { + X11_SetNetWMState(_this, data->xwindow, window->flags); + } + X11_XFlush(display); +} + void X11_ShowWindow(_THIS, SDL_Window * window) { @@ -1126,6 +1140,7 @@ X11_ShowWindow(_THIS, SDL_Window * window) if (!data->videodata->net_wm) { /* no WM means no FocusIn event, which confuses us. Force it. */ + X11_XSync(display, False); X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime); X11_XFlush(display); } @@ -1560,13 +1575,98 @@ X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) return 0; } -void -X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +typedef struct { + unsigned char *data; + int format, count; + Atom type; +} SDL_x11Prop; + +/* Reads property + Must call X11_XFree on results + */ +static void X11_ReadProperty(SDL_x11Prop *p, Display *disp, Window w, Atom prop) +{ + unsigned char *ret=NULL; + Atom type; + int fmt; + unsigned long count; + unsigned long bytes_left; + int bytes_fetch = 0; + + do { + if (ret != 0) X11_XFree(ret); + X11_XGetWindowProperty(disp, w, prop, 0, bytes_fetch, False, AnyPropertyType, &type, &fmt, &count, &bytes_left, &ret); + bytes_fetch += bytes_left; + } while (bytes_left != 0); + + p->data=ret; + p->format=fmt; + p->count=count; + p->type=type; +} + +void* +X11_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; + XWindowAttributes attributes; + Atom icc_profile_atom; + char icc_atom_string[sizeof("_ICC_PROFILE_") + 12]; + void* ret_icc_profile_data = NULL; + CARD8* icc_profile_data; + int real_format; + unsigned long real_nitems; + SDL_x11Prop atomProp; + + X11_XGetWindowAttributes(display, X11_IsWindowLegacyFullscreen(_this, window) ? data->fswindow : data->xwindow, &attributes); + if (X11_XScreenNumberOfScreen(attributes.screen) > 0) { + SDL_snprintf(icc_atom_string, sizeof("_ICC_PROFILE_") + 12, "%s%d", "_ICC_PROFILE_", X11_XScreenNumberOfScreen(attributes.screen)); + } else { + SDL_strlcpy(icc_atom_string, "_ICC_PROFILE", sizeof("_ICC_PROFILE")); + } + X11_XGetWindowAttributes(display, RootWindowOfScreen(attributes.screen), &attributes); + + icc_profile_atom = X11_XInternAtom(display, icc_atom_string, True); + if (icc_profile_atom == None) { + SDL_SetError("Screen is not calibrated.\n"); + return NULL; + } + + X11_ReadProperty(&atomProp, display, RootWindowOfScreen(attributes.screen), icc_profile_atom); + real_format = atomProp.format; + real_nitems = atomProp.count; + icc_profile_data = atomProp.data; + if (real_format == None) { + SDL_SetError("Screen is not calibrated.\n"); + return NULL; + } + + ret_icc_profile_data = SDL_malloc(real_nitems); + if (!ret_icc_profile_data) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_memcpy(ret_icc_profile_data, icc_profile_data, real_nitems); + *size = real_nitems; + X11_XFree(icc_profile_data); + + return ret_icc_profile_data; +} + +void +X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display; SDL_bool oldstyle_fullscreen; - SDL_bool grab_keyboard; + + if (data == NULL) { + return; + } + + display = data->videodata->display; /* ICCCM2.0-compliant window managers can handle fullscreen windows If we're using XVidMode to change resolution we need to confine @@ -1586,7 +1686,7 @@ X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) if (!data->videodata->broken_pointer_grab) { const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask; int attempts; - int result; + int result = 0; /* Try for up to 5000ms (5s) to grab. If it still fails, stop trying. */ for (attempts = 0; attempts < 100; attempts++) { @@ -1604,24 +1704,46 @@ X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) } } + X11_Xinput2GrabTouch(_this, window); + /* Raise the window if we grab the mouse */ X11_XRaiseWindow(display, data->xwindow); - /* Now grab the keyboard */ - if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) { - grab_keyboard = SDL_TRUE; - } else { - /* We need to do this with the old style override_redirect - fullscreen window otherwise we won't get keyboard focus. - */ - grab_keyboard = oldstyle_fullscreen; - } - if (grab_keyboard) { - X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync, - GrabModeAsync, CurrentTime); + /* Now grab the keyboard on old-style fullscreen */ + if (oldstyle_fullscreen) { + X11_SetWindowKeyboardGrab(_this, window, SDL_TRUE); } } else { X11_XUngrabPointer(display, CurrentTime); + + X11_Xinput2UngrabTouch(_this, window); + } + X11_XSync(display, False); +} + +void +X11_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display; + + if (data == NULL) { + return; + } + + display = data->videodata->display; + + if (grabbed) { + /* If the window is unmapped, XGrab calls return GrabNotViewable, + so when we get a MapNotify later, we'll try to update the grab as + appropriate. */ + if (window->flags & SDL_WINDOW_HIDDEN) { + return; + } + + X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync, + GrabModeAsync, CurrentTime); + } else { X11_XUngrabKeyboard(display, CurrentTime); } X11_XSync(display, False); @@ -1659,6 +1781,13 @@ X11_DestroyWindow(_THIS, SDL_Window * window) X11_XFlush(display); } SDL_free(data); + +#if SDL_VIDEO_DRIVER_X11_XFIXES + /* If the pointer barriers are active for this, deactivate it.*/ + if (videodata->active_cursor_confined_window == window) { + X11_DestroyPointerBarrier(_this, window); + } +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ } window->driverdata = NULL; } @@ -1712,6 +1841,87 @@ X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept) } } +int +X11_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + XWMHints *wmhints; + + wmhints = X11_XGetWMHints(display, data->xwindow); + if (!wmhints) { + return SDL_SetError("Couldn't get WM hints"); + } + + wmhints->flags &= ~XUrgencyHint; + data->flashing_window = SDL_FALSE; + data->flash_cancel_time = 0; + + switch (operation) { + case SDL_FLASH_CANCEL: + /* Taken care of above */ + break; + case SDL_FLASH_BRIEFLY: + if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) { + wmhints->flags |= XUrgencyHint; + data->flashing_window = SDL_TRUE; + /* On Ubuntu 21.04 this causes a dialog to pop up, so leave it up for a full second so users can see it */ + data->flash_cancel_time = SDL_GetTicks() + 1000; + if (!data->flash_cancel_time) { + data->flash_cancel_time = 1; + } + } + break; + case SDL_FLASH_UNTIL_FOCUSED: + if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) { + wmhints->flags |= XUrgencyHint; + data->flashing_window = SDL_TRUE; + } + break; + default: + break; + } + + X11_XSetWMHints(display, data->xwindow, wmhints); + X11_XFree(wmhints); + return 0; +} + +int SDL_X11_SetWindowTitle(Display* display, Window xwindow, char* title) { + Atom _NET_WM_NAME = X11_XInternAtom(display, "_NET_WM_NAME", False); + XTextProperty titleprop; + int conv = X11_XmbTextListToTextProperty(display, (char**) &title, 1, XTextStyle, &titleprop); + Status status; + + if (X11_XSupportsLocale() != True) { + return SDL_SetError("Current locale not supported by X server, cannot continue."); + } + + if (conv == 0) { + X11_XSetTextProperty(display, xwindow, &titleprop, XA_WM_NAME); + X11_XFree(titleprop.value); + /* we know this can't be a locale error as we checked X locale validity */ + } else if (conv < 0) { + return SDL_OutOfMemory(); + } else { /* conv > 0 */ + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "%d characters were not convertable to the current locale!", conv); + return 0; + } + +#ifdef X_HAVE_UTF8_STRING + status = X11_Xutf8TextListToTextProperty(display, (char **) &title, 1, XUTF8StringStyle, &titleprop); + if (status == Success) { + X11_XSetTextProperty(display, xwindow, &titleprop, _NET_WM_NAME); + X11_XFree(titleprop.value); + } else { + return SDL_SetError("Failed to convert title to UTF8! Bad encoding, or bad Xorg encoding? Window title: «%s»", title); + } +#endif + + X11_XFlush(display); + return 0; +} + #endif /* SDL_VIDEO_DRIVER_X11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11window.h b/Engine/lib/sdl/src/video/x11/SDL_x11window.h index 8178ffc14..6f1c71c67 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11window.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11window.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -68,9 +68,16 @@ typedef struct unsigned long user_time; Atom xdnd_req; Window xdnd_source; + SDL_bool flashing_window; + Uint32 flash_cancel_time; #if SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; #endif +#if SDL_VIDEO_DRIVER_X11_XFIXES + SDL_bool pointer_barrier_active; + PointerBarrier barrier[4]; + SDL_Rect barrier_rect; +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ } SDL_WindowData; extern void X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags); @@ -97,14 +104,20 @@ extern void X11_MinimizeWindow(_THIS, SDL_Window * window); extern void X11_RestoreWindow(_THIS, SDL_Window * window); extern void X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); +extern void X11_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top); extern void X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); -extern void X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void* X11_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size); +extern void X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void X11_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void X11_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); extern int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled); extern void X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept); +extern int X11_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation); + +int SDL_X11_SetWindowTitle(Display* display, Window xwindow, char* string); #endif /* SDL_x11window_h_ */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11xfixes.c b/Engine/lib/sdl/src/video/x11/SDL_x11xfixes.c new file mode 100644 index 000000000..95027d46b --- /dev/null +++ b/Engine/lib/sdl/src/video/x11/SDL_x11xfixes.c @@ -0,0 +1,206 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_DRIVER_X11_XFIXES + +#include "SDL_x11video.h" +#include "SDL_x11xfixes.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" + +static int xfixes_initialized = 0; + +static int +query_xfixes_version(Display *display, int major, int minor) +{ + /* We don't care if this fails, so long as it sets major/minor on it's way out the door. */ + X11_XFixesQueryVersion(display, &major, &minor); + return ((major * 1000) + minor); +} + +static SDL_bool +xfixes_version_atleast(const int version, const int wantmajor, const int wantminor) +{ + return (version >= ((wantmajor * 1000) + wantminor)); +} + +void +X11_InitXfixes(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + int version = 0; + int event, error; + int fixes_opcode; + + if (!SDL_X11_HAVE_XFIXES || + !X11_XQueryExtension(data->display, "XFIXES", &fixes_opcode, &event, &error)) { + return; + } + + /* We need at least 5.0 for barriers. */ + version = query_xfixes_version(data->display, 5, 0); + if (!xfixes_version_atleast(version, 5, 0)) { + return; /* X server does not support the version we want at all. */ + } + + xfixes_initialized = 1; +} + +int +X11_XfixesIsInitialized() +{ + return xfixes_initialized; +} + +void +X11_SetWindowMouseRect(_THIS, SDL_Window * window) +{ + if (SDL_RectEmpty(&window->mouse_rect)) { + X11_ConfineCursorWithFlags(_this, window, NULL, 0); + } else { + if (window->flags & SDL_WINDOW_INPUT_FOCUS) { + X11_ConfineCursorWithFlags(_this, window, &window->mouse_rect, 0); + } else { + /* Save the state for when we get focus again */ + SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata; + + SDL_memcpy(&wdata->barrier_rect, &window->mouse_rect, sizeof(wdata->barrier_rect)); + + wdata->pointer_barrier_active = SDL_TRUE; + } + } +} + +int +X11_ConfineCursorWithFlags(_THIS, SDL_Window * window, const SDL_Rect * rect, int flags) +{ + /* Yaakuro: For some reason Xfixes when confining inside a rect where the + * edges exactly match, a rectangle the cursor 'slips' out of the barrier. + * To prevent that the lines for the barriers will span the whole screen. + */ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_WindowData *wdata; + + if (!X11_XfixesIsInitialized()) { + return SDL_Unsupported(); + } + + /* If there is already a set of barriers active, disable them. */ + if (data->active_cursor_confined_window) { + X11_DestroyPointerBarrier(_this, data->active_cursor_confined_window); + } + + SDL_assert(window != NULL); + wdata = (SDL_WindowData *) window->driverdata; + + /* If user did not specify an area to confine, destroy the barrier that was/is assigned to + * this window it was assigned */ + if (rect) { + int x1, y1, x2, y2; + SDL_Rect bounds; + SDL_GetWindowPosition(window, &bounds.x, &bounds.y); + SDL_GetWindowSize(window, &bounds.w, &bounds.h); + + /** Negative values are not allowed. Clip values relative to the specified window. */ + x1 = bounds.x + SDL_max(rect->x, 0); + y1 = bounds.y + SDL_max(rect->y, 0); + x2 = SDL_min(bounds.x + rect->x + rect->w, bounds.x + bounds.w); + y2 = SDL_min(bounds.y + rect->y + rect->h, bounds.y + bounds.h); + + if ((wdata->barrier_rect.x != rect->x) || + (wdata->barrier_rect.y != rect->y) || + (wdata->barrier_rect.w != rect->w) || + (wdata->barrier_rect.h != rect->h)) { + wdata->barrier_rect = *rect; + } + + /* Use the display bounds to ensure the barriers don't have corner gaps */ + SDL_GetDisplayBounds(SDL_GetWindowDisplayIndex(window), &bounds); + + /** Create the left barrier */ + wdata->barrier[0] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow, + x1, bounds.y, + x1, bounds.y + bounds.h, + BarrierPositiveX, + 0, NULL); + /** Create the right barrier */ + wdata->barrier[1] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow, + x2, bounds.y, + x2, bounds.y + bounds.h, + BarrierNegativeX, + 0, NULL); + /** Create the top barrier */ + wdata->barrier[2] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow, + bounds.x, y1, + bounds.x + bounds.w, y1, + BarrierPositiveY, + 0, NULL); + /** Create the bottom barrier */ + wdata->barrier[3] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow, + bounds.x, y2, + bounds.x + bounds.w, y2, + BarrierNegativeY, + 0, NULL); + + X11_XFlush(data->display); + + /* Lets remember current active confined window. */ + data->active_cursor_confined_window = window; + + /* User activated the confinement for this window. We use this later to reactivate + * the confinement if it got deactivated by FocusOut or UnmapNotify */ + wdata->pointer_barrier_active = SDL_TRUE; + } else { + X11_DestroyPointerBarrier(_this, window); + + /* Only set barrier inactive when user specified NULL and not handled by focus out. */ + if (flags != X11_BARRIER_HANDLED_BY_EVENT) { + wdata->pointer_barrier_active = SDL_FALSE; + } + } + return 0; +} + +void +X11_DestroyPointerBarrier(_THIS, SDL_Window * window) +{ + int i; + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + if (window) { + SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata; + + for (i = 0; i < 4; i++) { + if (wdata->barrier[i] > 0) { + X11_XFixesDestroyPointerBarrier(data->display, wdata->barrier[i]); + wdata->barrier[i] = 0; + } + } + X11_XFlush(data->display); + } + data->active_cursor_confined_window = NULL; +} + +#endif /* SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_DRIVER_X11_XFIXES */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11xfixes.h b/Engine/lib/sdl/src/video/x11/SDL_x11xfixes.h new file mode 100644 index 000000000..7239d3fd2 --- /dev/null +++ b/Engine/lib/sdl/src/video/x11/SDL_x11xfixes.h @@ -0,0 +1,41 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#ifndef SDL_x11xfixes_h_ +#define SDL_x11xfixes_h_ + +#if SDL_VIDEO_DRIVER_X11_XFIXES + +#define X11_BARRIER_HANDLED_BY_EVENT 1 + +extern void X11_InitXfixes(_THIS); +extern int X11_XfixesIsInitialized(void); +extern void X11_SetWindowMouseRect(_THIS, SDL_Window * window); +extern int X11_ConfineCursorWithFlags(_THIS, SDL_Window * window, const SDL_Rect * rect, int flags); +extern void X11_DestroyPointerBarrier(_THIS, SDL_Window * window); + +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + +#endif /* SDL_x11xfixes_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.c b/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.c index 97430b480..abfbdf0e3 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -343,6 +343,50 @@ X11_Xinput2IsMultitouchSupported() #endif } +void +X11_Xinput2GrabTouch(_THIS, SDL_Window *window) +{ +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + + unsigned char mask[4] = { 0, 0, 0, 0 }; + XIGrabModifiers mods; + XIEventMask eventmask; + + mods.modifiers = XIAnyModifier; + mods.status = 0; + + eventmask.deviceid = XIAllDevices; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + + XISetMask(eventmask.mask, XI_TouchBegin); + XISetMask(eventmask.mask, XI_TouchUpdate); + XISetMask(eventmask.mask, XI_TouchEnd); + XISetMask(eventmask.mask, XI_Motion); + + X11_XIGrabTouchBegin(display, XIAllDevices, data->xwindow, True, &eventmask, 1, &mods); +#endif +} + +void +X11_Xinput2UngrabTouch(_THIS, SDL_Window *window) +{ +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + + XIGrabModifiers mods; + + mods.modifiers = XIAnyModifier; + mods.status = 0; + + X11_XIUngrabTouchBegin(display, XIAllDevices, data->xwindow, 1, &mods); +#endif +} + + #endif /* SDL_VIDEO_DRIVER_X11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.h b/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.h index 022d81f36..679beb97b 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -36,6 +36,8 @@ extern int X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie * extern int X11_Xinput2IsInitialized(void); extern int X11_Xinput2IsMultitouchSupported(void); extern void X11_Xinput2SelectTouch(_THIS, SDL_Window *window); +extern void X11_Xinput2GrabTouch(_THIS, SDL_Window *window); +extern void X11_Xinput2UngrabTouch(_THIS, SDL_Window *window); #endif /* SDL_x11xinput2_h_ */ diff --git a/Engine/lib/sdl/src/video/x11/edid-parse.c b/Engine/lib/sdl/src/video/x11/edid-parse.c index e22324f2c..c717f1b1f 100644 --- a/Engine/lib/sdl/src/video/x11/edid-parse.c +++ b/Engine/lib/sdl/src/video/x11/edid-parse.c @@ -50,7 +50,7 @@ get_bits (int in, int begin, int end) static int decode_header (const uchar *edid) { - if (memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0) + if (SDL_memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0) return TRUE; return FALSE; } @@ -76,7 +76,7 @@ decode_vendor_and_product_identification (const uchar *edid, MonitorInfo *info) /* Serial Number */ info->serial_number = - edid[0x0c] | edid[0x0d] << 8 | edid[0x0e] << 16 | edid[0x0f] << 24; + edid[0x0c] | edid[0x0d] << 8 | edid[0x0e] << 16 | (Uint32)edid[0x0f] << 24; /* Week and Year */ is_model_year = FALSE; @@ -522,7 +522,7 @@ decode_check_sum (const uchar *edid, MonitorInfo * decode_edid (const uchar *edid) { - MonitorInfo *info = calloc (1, sizeof (MonitorInfo)); + MonitorInfo *info = SDL_calloc (1, sizeof (MonitorInfo)); decode_check_sum (edid, info); @@ -534,8 +534,8 @@ decode_edid (const uchar *edid) !decode_established_timings (edid, info) || !decode_standard_timings (edid, info) || !decode_descriptors (edid, info)) { - free(info); - return NULL; + SDL_free(info); + return NULL; } return info; diff --git a/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb.c b/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb.c index 6e821a8b3..7908b8c48 100644 --- a/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb.c +++ b/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb.c @@ -91,7 +91,7 @@ static uint8_t clampU8(int32_t v) 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 }; - return lut[(v+128*PRECISION_FACTOR)>>PRECISION]; + return lut[((v+128*PRECISION_FACTOR)>>PRECISION)&511]; } diff --git a/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb_sse_func.h b/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb_sse_func.h index f81140e18..3c5ee0db4 100644 --- a/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb_sse_func.h +++ b/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb_sse_func.h @@ -415,6 +415,17 @@ void SSE_FUNCTION_NAME(uint32_t width, uint32_t height, #error Unknown RGB pixel size #endif +#if YUV_FORMAT == YUV_FORMAT_NV12 + /* For NV12 formats (where U/V are interleaved) + * SSE READ_UV does an invalid read access at the very last pixel. + * As a workaround. Make sure not to decode the last column using assembly but with STD fallback path. + * see https://github.com/libsdl-org/SDL/issues/4841 + */ + const int fix_read_nv12 = ((width & 31) == 0); +#else + const int fix_read_nv12 = 0; +#endif + if (width >= 32) { uint32_t xpos, ypos; for(ypos=0; ypos<(height-(uv_y_sample_interval-1)); ypos+=uv_y_sample_interval) @@ -427,7 +438,7 @@ void SSE_FUNCTION_NAME(uint32_t width, uint32_t height, uint8_t *rgb_ptr1=RGB+ypos*RGB_stride, *rgb_ptr2=RGB+(ypos+1)*RGB_stride; - for(xpos=0; xpos<(width-31); xpos+=32) + for(xpos=0; xpos<(width-31) - fix_read_nv12; xpos+=32) { YUV2RGB_32 { @@ -464,6 +475,9 @@ void SSE_FUNCTION_NAME(uint32_t width, uint32_t height, /* Catch the right column, if needed */ { int converted = (width & ~31); + if (fix_read_nv12) { + converted -= 32; + } if (converted != width) { const uint8_t *y_ptr=Y+converted*y_pixel_stride, diff --git a/Engine/lib/sdl/test/CMakeLists.txt b/Engine/lib/sdl/test/CMakeLists.txt index 879800575..330af47c4 100644 --- a/Engine/lib/sdl/test/CMakeLists.txt +++ b/Engine/lib/sdl/test/CMakeLists.txt @@ -1,21 +1,56 @@ -cmake_minimum_required(VERSION 2.8.11) +cmake_minimum_required(VERSION 3.0.0) project(SDL2 C) # Global settings for all of the test targets # FIXME: is this wrong? remove_definitions(-DUSING_GENERATED_CONFIG_H) -link_libraries(SDL2_test SDL2-static) -# FIXME: Parent directory CMakeLists.txt only sets these for mingw/cygwin, -# but we need them for VS as well. +if(PSP) + link_libraries( + SDL2main + SDL2_test + SDL2-static + GL + pspvram + pspvfpu + pspdisplay + pspgu + pspge + pspaudio + pspctrl + psphprm + psppower + ) +else() + link_libraries(SDL2_test SDL2-static) +endif() + if(WINDOWS) + # mingw32 must come before SDL2main to link successfully + if(MINGW OR CYGWIN) + link_libraries(mingw32) + endif() + + # FIXME: Parent directory CMakeLists.txt only sets these for mingw/cygwin, + # but we need them for VS as well. link_libraries(SDL2main) add_definitions(-Dmain=SDL_main) endif() +# CMake incorrectly detects opengl32.lib being present on MSVC ARM64 +if(NOT MSVC OR NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64") + find_package(OpenGL) +endif() + +if (OPENGL_FOUND) +add_definitions(-DHAVE_OPENGL) +endif() + add_executable(checkkeys checkkeys.c) +add_executable(checkkeysthreads checkkeysthreads.c) add_executable(loopwave loopwave.c) add_executable(loopwavequeue loopwavequeue.c) +add_executable(testsurround testsurround.c) add_executable(testresample testresample.c) add_executable(testaudioinfo testaudioinfo.c) @@ -35,6 +70,7 @@ add_executable(testdropfile testdropfile.c) add_executable(testerror testerror.c) add_executable(testfile testfile.c) add_executable(testgamecontroller testgamecontroller.c) +add_executable(testgeometry testgeometry.c) add_executable(testgesture testgesture.c) add_executable(testgl2 testgl2.c) add_executable(testgles testgles.c) @@ -49,6 +85,7 @@ add_executable(testjoystick testjoystick.c) add_executable(testkeys testkeys.c) add_executable(testloadso testloadso.c) add_executable(testlock testlock.c) +add_executable(testmouse testmouse.c) if(APPLE) add_executable(testnative testnative.c @@ -88,43 +125,151 @@ add_executable(controllermap controllermap.c) add_executable(testvulkan testvulkan.c) add_executable(testoffscreen testoffscreen.c) -# HACK: Dummy target to cause the resource files to be copied to the build directory. -# Need to make it an executable so we can use the TARGET_FILE_DIR generator expression. -# This is needed so they get copied to the correct Debug/Release subdirectory in Xcode. -file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/resources_dummy.c "int main(int argc, const char **argv){ return 1; }\n") -add_executable(SDL2_test_resoureces ${CMAKE_CURRENT_BINARY_DIR}/resources_dummy.c) - -file(GLOB RESOURCE_FILES *.bmp *.wav moose.dat utf8.txt) -foreach(RESOURCE_FILE ${RESOURCE_FILES}) - add_custom_command(TARGET SDL2_test_resoureces POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${RESOURCE_FILE} $) -endforeach(RESOURCE_FILE) +if(OPENGL_FOUND) +add_dependencies(testshader OpenGL::GL) +add_dependencies(testgl2 OpenGL::GL) +target_link_libraries(testshader OpenGL::GL) +target_link_libraries(testgl2 OpenGL::GL) +endif() +file(GLOB RESOURCE_FILES *.bmp *.wav *.hex moose.dat utf8.txt) file(COPY ${RESOURCE_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +if(PSP) + set(NEEDS_RESOURCES + testscale + testrendercopyex + controllermap + testyuv + testgamecontroller + testshape + testshader + testspriteminimal + testautomation + testrendertarget + testsprite2 + loopwave + loopwavequeue + testresample + testaudiohotplug + testmultiaudio + testiconv + testoverlay2 + teststreaming + testviewport + ) +else() + set(NEEDS_RESOURCES + testscale + testrendercopyex + controllermap + testyuv + testgamecontroller + testshape + testshader + testspriteminimal + testautomation + testcustomcursor + testrendertarget + testsprite2 + loopwave + loopwavequeue + testresample + testaudiohotplug + testmultiaudio + testime + testnative + testiconv + testoverlay2 + teststreaming + testviewport + ) +endif() -# TODO: Might be easier to make all targets depend on the resources...? +if(PSP) + # Build EBOOT files if building for PSP + set(BUILD_EBOOT + ${NEEDS_RESOURCES} + testbounds + testgl2 + testsem + testdisplayinfo + teststreaming + testgeometry + testfile + testdraw2 + testviewport + testhittesting + testoverlay2 + testver + testdrawchessboard + testsurround + testintersections + testmessage + testaudiocapture + testerror + testatomic + testjoystick + testiconv + testfilesystem + testplatform + testthread + testqsort + testaudioinfo + testlock + testtimer + testpower + testwm2 + torturethread + ) + foreach(APP IN LISTS BUILD_EBOOT) + create_pbp_file( + TARGET ${APP} + TITLE SDL-${APP} + ICON_PATH NULL + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + ) + add_custom_command( + TARGET ${APP} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory + $/sdl-${APP} + ) + add_custom_command( + TARGET ${APP} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E rename + $/EBOOT.PBP + $/sdl-${APP}/EBOOT.PBP + ) + if(${BUILD_PRX}) + add_custom_command( + TARGET ${APP} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + $/${APP} + $/sdl-${APP}/${APP} + ) + add_custom_command( + TARGET ${APP} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E rename + $/${APP}.prx + $/sdl-${APP}/${APP}.prx + ) + endif() + add_custom_command( + TARGET ${APP} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E remove + $/PARAM.SFO + ) + endforeach() +endif() -set(NEEDS_RESOURCES - testscale - testrendercopyex - controllermap - testyuv - testgamecontroller - testshape - testshader - testnative - testspriteminimal - testautomation - testcustomcursor - testrendertarget - testsprite2 - loopwave - loopwavequeue - testresample - testaudiohotplug - testmultiaudio -) foreach(APP IN LISTS NEEDS_RESOURCES) - add_dependencies(${APP} SDL2_test_resoureces) + foreach(RESOURCE_FILE ${RESOURCE_FILES}) + if(PSP) + add_custom_command(TARGET ${APP} POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${RESOURCE_FILE} $/sdl-${APP}) + else() + add_custom_command(TARGET ${APP} POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${RESOURCE_FILE} $) + endif() + endforeach(RESOURCE_FILE) if(APPLE) # Make sure resource files get installed into macOS/iOS .app bundles. target_sources(${APP} PRIVATE "${RESOURCE_FILES}") diff --git a/Engine/lib/sdl/test/Makefile.in b/Engine/lib/sdl/test/Makefile.in index 8c3bbf2a1..d29dc6ecf 100644 --- a/Engine/lib/sdl/test/Makefile.in +++ b/Engine/lib/sdl/test/Makefile.in @@ -9,6 +9,7 @@ LIBS = @LIBS@ TARGETS = \ checkkeys$(EXE) \ + checkkeysthreads$(EXE) \ controllermap$(EXE) \ loopwave$(EXE) \ loopwavequeue$(EXE) \ @@ -28,6 +29,7 @@ TARGETS = \ testfile$(EXE) \ testfilesystem$(EXE) \ testgamecontroller$(EXE) \ + testgeometry$(EXE) \ testgesture$(EXE) \ testhaptic$(EXE) \ testhittesting$(EXE) \ @@ -41,6 +43,7 @@ TARGETS = \ testlocale$(EXE) \ testlock$(EXE) \ testmessage$(EXE) \ + testmouse$(EXE) \ testmultiaudio$(EXE) \ testnative$(EXE) \ testoverlay2$(EXE) \ @@ -59,6 +62,7 @@ TARGETS = \ testsprite2$(EXE) \ testspriteminimal$(EXE) \ teststreaming$(EXE) \ + testsurround$(EXE) \ testthread$(EXE) \ testtimer$(EXE) \ testurl$(EXE) \ @@ -69,7 +73,7 @@ TARGETS = \ testyuv$(EXE) \ torturethread$(EXE) \ - + @OPENGL_TARGETS@ += testgl2$(EXE) testshader$(EXE) @OPENGLES1_TARGETS@ += testgles$(EXE) @OPENGLES2_TARGETS@ += testgles2$(EXE) @@ -83,12 +87,18 @@ Makefile: $(srcdir)/Makefile.in checkkeys$(EXE): $(srcdir)/checkkeys.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) +checkkeysthreads$(EXE): $(srcdir)/checkkeysthreads.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + loopwave$(EXE): $(srcdir)/loopwave.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) loopwavequeue$(EXE): $(srcdir)/loopwavequeue.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) +testsurround$(EXE): $(srcdir)/testsurround.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + testresample$(EXE): $(srcdir)/testresample.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @@ -157,7 +167,10 @@ testfile$(EXE): $(srcdir)/testfile.c testgamecontroller$(EXE): $(srcdir)/testgamecontroller.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) - + +testgeometry$(EXE): $(srcdir)/testgeometry.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + testgesture$(EXE): $(srcdir)/testgesture.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@ @@ -170,6 +183,9 @@ testgles$(EXE): $(srcdir)/testgles.c testgles2$(EXE): $(srcdir)/testgles2.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@ +testgles2_sdf$(EXE): $(srcdir)/testgles2_sdf.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@ + testhaptic$(EXE): $(srcdir)/testhaptic.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @@ -219,14 +235,22 @@ testnative$(EXE): $(srcdir)/testnative.c \ $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @XLIB@ endif +ifeq (@ISOS2@,true) +testnative$(EXE): $(srcdir)/testnative.c \ + $(srcdir)/testnativeos2.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) +endif + #there's probably a better way of doing this ifeq (@ISMACOSX@,false) ifeq (@ISWINDOWS@,false) ifeq (@ISUNIX@,false) +ifeq (@ISOS2@,false) testnative$(EXE): ; endif endif endif +endif testoverlay2$(EXE): $(srcdir)/testoverlay2.c $(srcdir)/testyuv_cvt.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @@ -315,6 +339,8 @@ testvulkan$(EXE): $(srcdir)/testvulkan.c testlocale$(EXE): $(srcdir)/testlocale.c $(CC) -o $@ $? $(CFLAGS) $(LIBS) +testmouse$(EXE): $(srcdir)/testmouse.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) clean: @@ -325,26 +351,25 @@ distclean: clean rm -f config.status config.cache config.log rm -rf $(srcdir)/autom4te* +DATA = \ + axis.bmp \ + button.bmp \ + controllermap.bmp \ + controllermap_back.bmp \ + icon.bmp \ + moose.dat \ + sample.bmp \ + sample.wav \ + testgles2_sdf_img_normal.bmp \ + testgles2_sdf_img_sdf.bmp \ + testyuv.bmp \ + unifont-13.0.06.hex \ + $(NULL) + ifneq ($(srcdir), .) -%.bmp: $(srcdir)/%.bmp - cp $< $@ - -%.wav: $(srcdir)/%.wav - cp $< $@ - -%.dat: $(srcdir)/%.dat +$(DATA) : %: $(srcdir)/% Makefile cp $< $@ endif -copydatafiles: copybmpfiles copywavfiles copydatfiles +copydatafiles: $(DATA) .PHONY : copydatafiles - -copybmpfiles: $(foreach bmp,$(wildcard $(srcdir)/*.bmp),$(notdir $(bmp))) -.PHONY : copybmpfiles - -copywavfiles: $(foreach wav,$(wildcard $(srcdir)/*.wav),$(notdir $(wav))) -.PHONY : copywavfiles - -copydatfiles: $(foreach dat,$(wildcard $(srcdir)/*.dat),$(notdir $(dat))) -.PHONY : copydatfiles - diff --git a/Engine/lib/sdl/test/Makefile.os2 b/Engine/lib/sdl/test/Makefile.os2 index 922dffaf1..e238af4be 100644 --- a/Engine/lib/sdl/test/Makefile.os2 +++ b/Engine/lib/sdl/test/Makefile.os2 @@ -1,8 +1,20 @@ -BINPATH = . +# Open Watcom makefile to build SDL2 tests for OS/2 +# wmake -f Makefile.os2 + +INCPATH = -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h" -I"../include" + +CFLAGS = $(INCPATH) -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier -ei +CFLAGS+= -wx -wcd=303 + +LIBPATH = .. +LIBS = SDL2.lib SDL2test.lib + +#CFLAGS+= -DHAVE_SDL_TTF +#TTFLIBS = SDL2ttf.lib TARGETS = testatomic.exe testdisplayinfo.exe testbounds.exe testdraw2.exe & testdrawchessboard.exe testdropfile.exe testerror.exe testfile.exe & - testfilesystem.exe testgamecontroller.exe testgesture.exe & + testfilesystem.exe testgamecontroller.exe testgeometry.exe testgesture.exe & testhittesting.exe testhotplug.exe testiconv.exe testime.exe testlocale.exe & testintersections.exe testjoystick.exe testkeys.exe testloadso.exe & testlock.exe testmessage.exe testoverlay2.exe testplatform.exe & @@ -11,21 +23,13 @@ TARGETS = testatomic.exe testdisplayinfo.exe testbounds.exe testdraw2.exe & testshader.exe testshape.exe testsprite2.exe testspriteminimal.exe & teststreaming.exe testthread.exe testtimer.exe testver.exe & testviewport.exe testwm2.exe torturethread.exe checkkeys.exe & + checkkeysthreads.exe testmouse.exe & controllermap.exe testhaptic.exe testqsort.exe testresample.exe & testaudioinfo.exe testaudiocapture.exe loopwave.exe loopwavequeue.exe & - testyuv.exe testgl2.exe testvulkan.exe testnative.exe testautomation.exe - -# SDL2test.lib sources (../src/test) - -CSRCS = SDL_test_assert.c SDL_test_common.c SDL_test_compare.c & - SDL_test_crc32.c SDL_test_font.c SDL_test_fuzzer.c SDL_test_harness.c & - SDL_test_imageBlit.c SDL_test_imageBlitBlend.c SDL_test_imageFace.c & - SDL_test_imagePrimitives.c SDL_test_imagePrimitivesBlend.c & - SDL_test_log.c SDL_test_md5.c SDL_test_random.c SDL_test_memory.c -TESTLIB = SDL2test.lib + testsurround.exe testyuv.exe testgl2.exe testvulkan.exe testnative.exe & + testautomation.exe # testautomation sources - TASRCS = testautomation.c testautomation_audio.c testautomation_clipboard.c & testautomation_events.c testautomation_hints.c & testautomation_keyboard.c testautomation_main.c & @@ -42,23 +46,9 @@ TAOBJS = $(TASRCS:.c=.obj) all: $(TARGETS) -INCPATH = -I$(%WATCOM)/h/os2 -I$(%WATCOM)/h -I../include - -CFLAGS = $(INCPATH) -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier -ei - -LIBPATH = .. -LIBS = SDL2.lib $(TESTLIB) - -#CFLAGS+= -DHAVE_SDL_TTF -#LIBS_TTF = SDL2ttf.lib - .c: ../src/test -$(TESTLIB): $(COBJS) - wlib -q -b -n -c $@ $(COBJS) - .obj.exe: - @%make $(TESTLIB) wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ .c.obj: @@ -66,30 +56,22 @@ $(TESTLIB): $(COBJS) # specials testautomation.exe: $(TAOBJS) - @%make $(TESTLIB) wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ testnative.exe: testnative.obj testnativeos2.obj - @%make $(TESTLIB) wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ testoverlay2.exe: testoverlay2.obj testyuv_cvt.obj - @%make $(TESTLIB) wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ testyuv.exe: testyuv.obj testyuv_cvt.obj - @%make $(TESTLIB) wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ testime.exe: testime.obj - @%make $(TESTLIB) - wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS) $(LIBS_TTF)} op q op el file {$<} name $@ + wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS) $(TTFLIBS)} op q op el file {$<} name $@ clean: .SYMBOLIC - @echo * Clean tests in $(BINPATH) @if exist *.obj rm *.obj @if exist *.err rm *.err - distclean: .SYMBOLIC clean @if exist *.exe rm *.exe - @if exist $(TESTLIB) rm $(TESTLIB) diff --git a/Engine/lib/sdl/test/README b/Engine/lib/sdl/test/README index 8329cb96f..b1ee0892e 100644 --- a/Engine/lib/sdl/test/README +++ b/Engine/lib/sdl/test/README @@ -4,6 +4,7 @@ These are test programs for the SDL library: checkkeys Watch the key events to check the keyboard loopwave Audio test -- loop playing a WAV file loopwavequeue Audio test -- loop playing a WAV file with SDL_QueueAudio + testsurround Audio test -- play test tone on each audio channel testaudioinfo Lists audio device capabilities testerror Tests multi-threaded error handling testfile Tests RWops layer @@ -14,6 +15,7 @@ These are test programs for the SDL library: testloadso Tests the loadable library layer testlocale Test Locale API testlock Hacked up test of multi-threading and locking + testmouse Tests mouse coordinates testmultiaudio Tests using several audio devices testoverlay2 Tests the overlay flickering/scaling during playback. testplatform Tests types, endianness and cpu capabilities diff --git a/Engine/lib/sdl/test/acinclude.m4 b/Engine/lib/sdl/test/acinclude.m4 index e2180a3ab..0fdf353ea 100644 --- a/Engine/lib/sdl/test/acinclude.m4 +++ b/Engine/lib/sdl/test/acinclude.m4 @@ -5,13 +5,13 @@ # stolen from Manish Singh # Shamelessly stolen from Owen Taylor -# serial 1 +# serial 2 dnl AM_PATH_SDL2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS dnl AC_DEFUN([AM_PATH_SDL2], -[dnl +[dnl dnl Get the cflags and libraries from the sdl2-config script dnl AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], @@ -80,41 +80,19 @@ dnl Now check if the installed SDL is sufficiently new. (Also sanity dnl checks the results of sdl2-config to some extent dnl rm -f conf.sdltest - AC_TRY_RUN([ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -#include #include "SDL.h" -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - int main (int argc, char *argv[]) { int major, minor, micro; - char *tmp_version; + FILE *fp = fopen("conf.sdltest", "w"); - /* This hangs on some systems (?) - system ("touch conf.sdltest"); - */ - { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + if (fp) fclose(fp); - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_sdl_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + if (sscanf("$min_sdl_version", "%d.%d.%d", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_sdl_version"); exit(1); } @@ -137,7 +115,7 @@ int main (int argc, char *argv[]) } } -],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) +]])], [], [no_sdl=yes], [echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" LIBS="$ac_save_LIBS" @@ -165,7 +143,7 @@ int main (int argc, char *argv[]) CFLAGS="$CFLAGS $SDL_CFLAGS" CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" LIBS="$LIBS $SDL_LIBS" - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include "SDL.h" @@ -173,7 +151,7 @@ int main(int argc, char *argv[]) { return 0; } #undef main #define main K_and_R_C_main -], [ return 0; ], +]], [[ return 0; ]])], [ echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding SDL or finding the wrong" echo "*** version of SDL. If it is not finding SDL, you'll need to set your" @@ -228,7 +206,7 @@ int main(int argc, char *argv[]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +m4_pattern_allow([^PKG_CONFIG(_PATH|_LIBDIR)?$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) @@ -309,7 +287,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $1]) +AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -337,7 +315,7 @@ $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. -_PKG_TEXT])dnl +_PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) @@ -348,7 +326,7 @@ path to pkg-config. _PKG_TEXT -To get pkg-config, see .])dnl +To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS diff --git a/Engine/lib/sdl/test/autogen.sh b/Engine/lib/sdl/test/autogen.sh index 939f34c0f..988d41760 100755 --- a/Engine/lib/sdl/test/autogen.sh +++ b/Engine/lib/sdl/test/autogen.sh @@ -1,12 +1,11 @@ #!/bin/sh -# -# Regenerate configuration files + cp acinclude.m4 aclocal.m4 -found=false -for autoconf in autoconf autoconf259 autoconf-2.59 -do if which $autoconf >/dev/null 2>&1; then $autoconf && found=true; break; fi -done -if test x$found = xfalse; then - echo "Couldn't find autoconf, aborting" - exit 1 + +if test "$AUTOCONF"x = x; then + AUTOCONF=autoconf fi + +$AUTOCONF || exit 1 +rm aclocal.m4 +rm -rf autom4te.cache diff --git a/Engine/lib/sdl/test/checkkeys.c b/Engine/lib/sdl/test/checkkeys.c index 22abc0aa1..caec4b955 100644 --- a/Engine/lib/sdl/test/checkkeys.c +++ b/Engine/lib/sdl/test/checkkeys.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -86,6 +86,8 @@ print_modifiers(char **text, size_t *maxlen) print_string(text, maxlen, " CAPS"); if (mod & KMOD_MODE) print_string(text, maxlen, " MODE"); + if (mod & KMOD_SCROLL) + print_string(text, maxlen, " SCROLL"); } static void @@ -135,9 +137,10 @@ PrintKey(SDL_Keysym * sym, SDL_bool pressed, SDL_bool repeat) } static void -PrintText(char *eventtype, char *text) +PrintText(const char *eventtype, const char *text) { - char *spot, expanded[1024]; + const char *spot; + char expanded[1024]; expanded[0] = '\0'; for ( spot = text; *spot; ++spot ) @@ -199,6 +202,7 @@ int main(int argc, char *argv[]) { SDL_Window *window; + SDL_Renderer *renderer; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); @@ -219,6 +223,12 @@ main(int argc, char *argv[]) quit(2); } + /* On wayland, no window will actually show until something has + actually been displayed. + */ + renderer = SDL_CreateRenderer(window, -1, 0); + SDL_RenderPresent(renderer); + #if __IPHONEOS__ /* Creating the context creates the view, which we need to show keyboard */ SDL_GL_CreateContext(window); diff --git a/Engine/lib/sdl/test/checkkeysthreads.c b/Engine/lib/sdl/test/checkkeysthreads.c new file mode 100644 index 000000000..62d522609 --- /dev/null +++ b/Engine/lib/sdl/test/checkkeysthreads.c @@ -0,0 +1,285 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + +/* Simple program: Loop, watching keystrokes + Note that you need to call SDL_PollEvent() or SDL_WaitEvent() to + pump the event loop and catch keystrokes. +*/ + +#include +#include +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include "SDL.h" + +int done; + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void +quit(int rc) +{ + SDL_Quit(); + exit(rc); +} + +static void +print_string(char **text, size_t *maxlen, const char *fmt, ...) +{ + int len; + va_list ap; + + va_start(ap, fmt); + len = SDL_vsnprintf(*text, *maxlen, fmt, ap); + if (len > 0) { + *text += len; + if ( ((size_t) len) < *maxlen ) { + *maxlen -= (size_t) len; + } else { + *maxlen = 0; + } + } + va_end(ap); +} + +static void +print_modifiers(char **text, size_t *maxlen) +{ + int mod; + print_string(text, maxlen, " modifiers:"); + mod = SDL_GetModState(); + if (!mod) { + print_string(text, maxlen, " (none)"); + return; + } + if (mod & KMOD_LSHIFT) + print_string(text, maxlen, " LSHIFT"); + if (mod & KMOD_RSHIFT) + print_string(text, maxlen, " RSHIFT"); + if (mod & KMOD_LCTRL) + print_string(text, maxlen, " LCTRL"); + if (mod & KMOD_RCTRL) + print_string(text, maxlen, " RCTRL"); + if (mod & KMOD_LALT) + print_string(text, maxlen, " LALT"); + if (mod & KMOD_RALT) + print_string(text, maxlen, " RALT"); + if (mod & KMOD_LGUI) + print_string(text, maxlen, " LGUI"); + if (mod & KMOD_RGUI) + print_string(text, maxlen, " RGUI"); + if (mod & KMOD_NUM) + print_string(text, maxlen, " NUM"); + if (mod & KMOD_CAPS) + print_string(text, maxlen, " CAPS"); + if (mod & KMOD_MODE) + print_string(text, maxlen, " MODE"); + if (mod & KMOD_SCROLL) + print_string(text, maxlen, " SCROLL"); +} + +static void +PrintModifierState() +{ + char message[512]; + char *spot; + size_t left; + + spot = message; + left = sizeof(message); + + print_modifiers(&spot, &left); + SDL_Log("Initial state:%s\n", message); +} + +static void +PrintKey(SDL_Keysym * sym, SDL_bool pressed, SDL_bool repeat) +{ + char message[512]; + char *spot; + size_t left; + + spot = message; + left = sizeof(message); + + /* Print the keycode, name and state */ + if (sym->sym) { + print_string(&spot, &left, + "Key %s: scancode %d = %s, keycode 0x%08X = %s ", + pressed ? "pressed " : "released", + sym->scancode, + SDL_GetScancodeName(sym->scancode), + sym->sym, SDL_GetKeyName(sym->sym)); + } else { + print_string(&spot, &left, + "Unknown Key (scancode %d = %s) %s ", + sym->scancode, + SDL_GetScancodeName(sym->scancode), + pressed ? "pressed " : "released"); + } + print_modifiers(&spot, &left); + if (repeat) { + print_string(&spot, &left, " (repeat)"); + } + SDL_Log("%s\n", message); + fflush(stderr); +} + +static void +PrintText(const char *eventtype, const char *text) +{ + const char *spot; + char expanded[1024]; + + expanded[0] = '\0'; + for ( spot = text; *spot; ++spot ) + { + size_t length = SDL_strlen(expanded); + SDL_snprintf(expanded + length, sizeof(expanded) - length, "\\x%.2x", (unsigned char)*spot); + } + SDL_Log("%s Text (%s): \"%s%s\"\n", eventtype, expanded, *text == '"' ? "\\" : "", text); +} + +void +loop() +{ + SDL_Event event; + /* Check for events */ + /*SDL_WaitEvent(&event); emscripten does not like waiting*/ + + fprintf(stderr, "starting loop\n"); fflush(stderr); + // while (SDL_PollEvent(&event)) { + while (!done && SDL_WaitEvent(&event)) { + fprintf(stderr, "got event type: %d\n", event.type); fflush(stderr); + switch (event.type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + PrintKey(&event.key.keysym, (event.key.state == SDL_PRESSED) ? SDL_TRUE : SDL_FALSE, (event.key.repeat) ? SDL_TRUE : SDL_FALSE); + break; + case SDL_TEXTEDITING: + PrintText("EDIT", event.text.text); + break; + case SDL_TEXTINPUT: + PrintText("INPUT", event.text.text); + break; + case SDL_MOUSEBUTTONDOWN: + /* Left button quits the app, other buttons toggles text input */ + fprintf(stderr, "mouse button down button: %d (LEFT=%d)\n", event.button.button, SDL_BUTTON_LEFT); fflush(stderr); + if (event.button.button == SDL_BUTTON_LEFT) { + done = 1; + } else { + if (SDL_IsTextInputActive()) { + SDL_Log("Stopping text input\n"); + SDL_StopTextInput(); + } else { + SDL_Log("Starting text input\n"); + SDL_StartTextInput(); + } + } + break; + case SDL_QUIT: + done = 1; + break; + default: + break; + } + fprintf(stderr, "waiting new event\n"); fflush(stderr); + } + fprintf(stderr, "exiting event loop\n"); fflush(stderr); +#ifdef __EMSCRIPTEN__ + if (done) { + emscripten_cancel_main_loop(); + } +#endif +} + +/* Very simple thread - counts 0 to 9 delaying 50ms between increments */ +static int SDLCALL ping_thread(void *ptr) +{ + int cnt; + SDL_Event sdlevent; + SDL_memset(&sdlevent, 0 , sizeof(SDL_Event)); + for (cnt = 0; cnt < 10; ++cnt) { + fprintf(stderr, "sending event (%d/%d) from thread.\n", cnt + 1, 10); fflush(stderr); + sdlevent.type = SDL_KEYDOWN; + sdlevent.key.keysym.sym = SDLK_1; + SDL_PushEvent(&sdlevent); + SDL_Delay(1000 + rand() % 1000); + } + return cnt; +} + +int +main(int argc, char *argv[]) +{ + SDL_Window *window; + SDL_Renderer *renderer; + SDL_Thread *thread; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Initialize SDL */ + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); + return (1); + } + + /* Set 640x480 video mode */ + window = SDL_CreateWindow("CheckKeys Test", + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + 640, 480, 0); + if (!window) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create 640x480 window: %s\n", + SDL_GetError()); + quit(2); + } + + /* On wayland, no window will actually show until something has + actually been displayed. + */ + renderer = SDL_CreateRenderer(window, -1, 0); + SDL_RenderPresent(renderer); + +#if __IPHONEOS__ + /* Creating the context creates the view, which we need to show keyboard */ + SDL_GL_CreateContext(window); +#endif + + SDL_StartTextInput(); + + /* Print initial modifier state */ + SDL_PumpEvents(); + PrintModifierState(); + + /* Watch keystrokes */ + done = 0; + + thread = SDL_CreateThread(ping_thread, "PingThread", (void *)NULL); + +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(loop, 0, 1); +#else + while (!done) { + loop(); + } +#endif + + SDL_WaitThread(thread, NULL); + SDL_Quit(); + return (0); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/test/configure b/Engine/lib/sdl/test/configure index 4faf15c43..60344e3ec 100755 --- a/Engine/lib/sdl/test/configure +++ b/Engine/lib/sdl/test/configure @@ -581,9 +581,11 @@ PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= -ac_unique_file="README" +ac_unique_file="loopwave.c" ac_subst_vars='LTLIBOBJS LIBOBJS +LIBUNWIND_LIBS +LIBUNWIND_CFLAGS SDL_TTF_LIB XLIB GLES2LIB @@ -600,6 +602,7 @@ SDL_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG +ISOS2 ISUNIX ISWINDOWS ISMACOSX @@ -681,7 +684,9 @@ PKG_CONFIG_LIBDIR SDL_CFLAGS SDL_LIBS XMKMF -CPP' +CPP +LIBUNWIND_CFLAGS +LIBUNWIND_LIBS' # Initialize some variables set by options. @@ -1323,6 +1328,10 @@ Some influential environment variables: SDL_LIBS linker flags for SDL, overriding pkg-config XMKMF Path to xmkmf, Makefile generator for X Window System CPP C preprocessor + LIBUNWIND_CFLAGS + C compiler flags for LIBUNWIND, overriding pkg-config + LIBUNWIND_LIBS + linker flags for LIBUNWIND, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1442,48 +1451,6 @@ fi } # ac_fn_c_try_compile -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. @@ -1530,6 +1497,48 @@ fi } # ac_fn_c_try_link +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. @@ -1921,7 +1930,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= -for ac_dir in $srcdir/../build-scripts; do +for ac_dir in ../build-scripts "$srcdir"/../build-scripts; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" @@ -1937,7 +1946,7 @@ for ac_dir in $srcdir/../build-scripts; do fi done if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in $srcdir/../build-scripts" "$LINENO" 5 + as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../build-scripts \"$srcdir\"/../build-scripts" "$LINENO" 5 fi # These three variables are undocumented and unsupported, @@ -2897,9 +2906,10 @@ fi ISUNIX="false" ISWINDOWS="false" ISMACOSX="false" +ISOS2="false" case "$host" in - *-*-cygwin* | *-*-mingw32*) + *-*-cygwin* | *-*-mingw*) ISWINDOWS="true" EXE=".exe" MATHLIB="" @@ -2910,7 +2920,7 @@ case "$host" in MATHLIB="" SYS_GL_LIBS="-lGL" ;; - *-*-darwin* ) + *-*-darwin*) ISMACOSX="true" EXE="" MATHLIB="" @@ -2982,21 +2992,68 @@ fi MATHLIB="" SYS_GL_LIBS="-lGLES_CM" ;; - *-*-emscripten* ) + *-*-emscripten*) EXE=".bc" MATHLIB="" SYS_GL_LIBS="" ;; - *-*-riscos* ) + *-*-riscos*) EXE=",e1f" MATHLIB="" SYS_GL_LIBS="" ;; + *-*-os2*) + ISOS2="true" + EXE=".exe" + MATHLIB="" + SYS_GL_LIBS="" + ;; *) ISUNIX="true" EXE="" MATHLIB="-lm" - SYS_GL_LIBS="-lGL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glBegin in -lOpenGL" >&5 +$as_echo_n "checking for glBegin in -lOpenGL... " >&6; } +if ${ac_cv_lib_OpenGL_glBegin+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lOpenGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char glBegin (); +int +main () +{ +return glBegin (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_OpenGL_glBegin=yes +else + ac_cv_lib_OpenGL_glBegin=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_OpenGL_glBegin" >&5 +$as_echo "$ac_cv_lib_OpenGL_glBegin" >&6; } +if test "x$ac_cv_lib_OpenGL_glBegin" = xyes; then : + SYS_GL_LIBS="-lOpenGL" +else + SYS_GL_LIBS="-lGL" +fi + ;; esac @@ -3005,7 +3062,8 @@ esac -SDL_VERSION=2.0.0 + +SDL_VERSION=2.0.18 @@ -3154,8 +3212,8 @@ fi if test "x$sdl_prefix$sdl_exec_prefix" = x ; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5 -$as_echo_n "checking for SDL... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl2 >= $min_sdl_version" >&5 +$as_echo_n "checking for sdl2 >= $min_sdl_version... " >&6; } if test -n "$SDL_CFLAGS"; then pkg_cv_SDL_CFLAGS="$SDL_CFLAGS" @@ -3319,38 +3377,16 @@ else #include #include -#include #include "SDL.h" -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - int main (int argc, char *argv[]) { int major, minor, micro; - char *tmp_version; + FILE *fp = fopen("conf.sdltest", "w"); - /* This hangs on some systems (?) - system ("touch conf.sdltest"); - */ - { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + if (fp) fclose(fp); - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_sdl_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + if (sscanf("$min_sdl_version", "%d.%d.%d", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_sdl_version"); exit(1); } @@ -3862,15 +3898,12 @@ int main () { - ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - -have_opengl=yes - + have_opengl=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_opengl" >&5 @@ -3891,15 +3924,12 @@ int main () { - ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - -have_opengles=yes - + have_opengles=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_opengles" >&5 @@ -3920,15 +3950,12 @@ int main () { - ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - -have_opengles2=yes - + have_opengles2=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_opengles2" >&5 @@ -4010,6 +4037,79 @@ if test x$have_SDL_ttf = xyes; then fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libunwind" >&5 +$as_echo_n "checking for libunwind... " >&6; } + +if test -n "$LIBUNWIND_CFLAGS"; then + pkg_cv_LIBUNWIND_CFLAGS="$LIBUNWIND_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libunwind\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libunwind") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUNWIND_CFLAGS=`$PKG_CONFIG --cflags "libunwind" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBUNWIND_LIBS"; then + pkg_cv_LIBUNWIND_LIBS="$LIBUNWIND_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libunwind\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libunwind") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUNWIND_LIBS=`$PKG_CONFIG --libs "libunwind" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBUNWIND_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libunwind" 2>&1` + else + LIBUNWIND_PKG_ERRORS=`$PKG_CONFIG --print-errors "libunwind" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBUNWIND_PKG_ERRORS" >&5 + + have_libunwind=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_libunwind=no +else + LIBUNWIND_CFLAGS=$pkg_cv_LIBUNWIND_CFLAGS + LIBUNWIND_LIBS=$pkg_cv_LIBUNWIND_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_libunwind=yes +fi +if test x$have_libunwind = xyes ; then + LIBS="$LIBS $LIBUNWIND_LIBS" +fi + ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF diff --git a/Engine/lib/sdl/test/configure.ac b/Engine/lib/sdl/test/configure.ac index 348606aa4..694551c61 100644 --- a/Engine/lib/sdl/test/configure.ac +++ b/Engine/lib/sdl/test/configure.ac @@ -1,9 +1,9 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT -AC_CONFIG_SRCDIR([README]) +AC_CONFIG_SRCDIR([loopwave.c]) dnl Detect the canonical build and host environments -AC_CONFIG_AUX_DIRS($srcdir/../build-scripts) +AC_CONFIG_AUX_DIR([../build-scripts]) AC_CANONICAL_HOST dnl Check for tools @@ -18,10 +18,11 @@ dnl (Haiku, for example, sets none of these.) ISUNIX="false" ISWINDOWS="false" ISMACOSX="false" +ISOS2="false" dnl Figure out which math library to use case "$host" in - *-*-cygwin* | *-*-mingw32*) + *-*-cygwin* | *-*-mingw*) ISWINDOWS="true" EXE=".exe" MATHLIB="" @@ -32,7 +33,7 @@ case "$host" in MATHLIB="" SYS_GL_LIBS="-lGL" ;; - *-*-darwin* ) + *-*-darwin*) ISMACOSX="true" EXE="" MATHLIB="" @@ -64,23 +65,31 @@ case "$host" in MATHLIB="" SYS_GL_LIBS="-lGLES_CM" ;; - *-*-emscripten* ) + *-*-emscripten*) dnl This should really be .js, but we need to specify extra flags when compiling to js EXE=".bc" MATHLIB="" SYS_GL_LIBS="" ;; - *-*-riscos* ) + *-*-riscos*) EXE=",e1f" MATHLIB="" SYS_GL_LIBS="" ;; + *-*-os2*) + ISOS2="true" + EXE=".exe" + MATHLIB="" + SYS_GL_LIBS="" + ;; *) dnl Oh well, call it Unix... ISUNIX="true" EXE="" MATHLIB="-lm" - SYS_GL_LIBS="-lGL" + dnl Use the new libOpenGL if present. + AC_CHECK_LIB(OpenGL, glBegin, + [SYS_GL_LIBS="-lOpenGL"],[SYS_GL_LIBS="-lGL"]) ;; esac AC_SUBST(EXE) @@ -88,9 +97,10 @@ AC_SUBST(MATHLIB) AC_SUBST(ISMACOSX) AC_SUBST(ISWINDOWS) AC_SUBST(ISUNIX) +AC_SUBST(ISOS2) dnl Check for SDL -SDL_VERSION=2.0.0 +SDL_VERSION=2.0.18 AM_PATH_SDL2($SDL_VERSION, :, AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) @@ -122,43 +132,34 @@ fi dnl Check for OpenGL AC_MSG_CHECKING(for OpenGL support) have_opengl=no -AC_TRY_COMPILE([ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include "SDL_opengl.h" #ifndef SDL_VIDEO_OPENGL #error SDL_VIDEO_OPENGL #endif -],[ -],[ -have_opengl=yes -]) +]],[])], [have_opengl=yes],[]) AC_MSG_RESULT($have_opengl) dnl Check for OpenGL ES AC_MSG_CHECKING(for OpenGL ES support) have_opengles=no -AC_TRY_COMPILE([ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include "SDL_opengles.h" #ifndef SDL_VIDEO_OPENGL_ES #error SDL_VIDEO_OPENGL_ES #endif -],[ -],[ -have_opengles=yes -]) +]],[])] ,[have_opengles=yes],[]) AC_MSG_RESULT($have_opengles) dnl Check for OpenGL ES2 AC_MSG_CHECKING(for OpenGL ES2 support) have_opengles2=no -AC_TRY_COMPILE([ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include "SDL_opengles2.h" #ifndef SDL_VIDEO_OPENGL_ES2 #error SDL_VIDEO_OPENGL_ES2 #endif -],[ -],[ -have_opengles2=yes -]) +]],[])], [have_opengles2=yes],[]) AC_MSG_RESULT($have_opengles2) GLLIB="" @@ -199,6 +200,16 @@ if test x$have_SDL_ttf = xyes; then fi AC_SUBST(SDL_TTF_LIB) +dnl Really, SDL2_test should be linking against libunwind (if it found +dnl libunwind.h when configured), but SDL2_test is a static library, so +dnl there's no way for it to link against it. We could make SDL2 depend on +dnl it, but we don't want all SDL2 build to suddenly gain an extra dependency, +dnl so just assume that if it's here now, SDL2_test was probably built with it. +PKG_CHECK_MODULES(LIBUNWIND, libunwind, have_libunwind=yes, have_libunwind=no) +if test x$have_libunwind = xyes ; then + LIBS="$LIBS $LIBUNWIND_LIBS" +fi + dnl Finally create all the generated files AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/Engine/lib/sdl/test/controllermap.c b/Engine/lib/sdl/test/controllermap.c index 03153abcb..308ddf51a 100644 --- a/Engine/lib/sdl/test/controllermap.c +++ b/Engine/lib/sdl/test/controllermap.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -53,7 +53,7 @@ static struct double angle; int marker; -} s_arrBindingDisplay[BINDING_COUNT] = { +} s_arrBindingDisplay[] = { { 387, 167, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_A */ { 431, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_B */ { 342, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_X */ @@ -86,8 +86,9 @@ static struct { 91, -20, 180.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_TRIGGERLEFT */ { 375, -20, 180.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_TRIGGERRIGHT */ }; +SDL_COMPILE_TIME_ASSERT(s_arrBindingDisplay, SDL_arraysize(s_arrBindingDisplay) == BINDING_COUNT); -static int s_arrBindingOrder[BINDING_COUNT] = { +static int s_arrBindingOrder[] = { SDL_CONTROLLER_BUTTON_A, SDL_CONTROLLER_BUTTON_B, SDL_CONTROLLER_BUTTON_Y, @@ -118,7 +119,9 @@ static int s_arrBindingOrder[BINDING_COUNT] = { SDL_CONTROLLER_BUTTON_PADDLE2, SDL_CONTROLLER_BUTTON_PADDLE3, SDL_CONTROLLER_BUTTON_PADDLE4, + SDL_CONTROLLER_BUTTON_TOUCHPAD, }; +SDL_COMPILE_TIME_ASSERT(s_arrBindingOrder, SDL_arraysize(s_arrBindingOrder) == BINDING_COUNT); typedef struct { @@ -162,7 +165,9 @@ static Uint32 s_unPendingAdvanceTime; static SDL_bool s_bBindingComplete; static SDL_Window *window; +static SDL_Renderer *screen; static SDL_bool done = SDL_FALSE; +static SDL_bool bind_touchpad = SDL_FALSE; SDL_Texture * LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) @@ -224,6 +229,19 @@ SetCurrentBinding(int iBinding) return; } + if (s_arrBindingOrder[iBinding] == -1) + { + SetCurrentBinding(iBinding + 1); + return; + } + + if (s_arrBindingOrder[iBinding] == SDL_CONTROLLER_BUTTON_TOUCHPAD && + !bind_touchpad) + { + SetCurrentBinding(iBinding + 1); + return; + } + s_iCurrentBinding = iBinding; pBinding = &s_arrBindings[s_arrBindingOrder[s_iCurrentBinding]]; @@ -366,7 +384,6 @@ BMergeAxisBindings(int iIndex) static void WatchJoystick(SDL_Joystick * joystick) { - SDL_Renderer *screen = NULL; SDL_Texture *background_front, *background_back, *button, *axis, *marker; const char *name = NULL; SDL_Event event; @@ -375,12 +392,6 @@ WatchJoystick(SDL_Joystick * joystick) Uint32 alpha_ticks = 0; SDL_JoystickID nJoystickID; - screen = SDL_CreateRenderer(window, -1, 0); - if (screen == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError()); - return; - } - background_front = LoadTexture(screen, "controllermap.bmp", SDL_FALSE); background_back = LoadTexture(screen, "controllermap_back.bmp", SDL_FALSE); button = LoadTexture(screen, "button.bmp", SDL_TRUE); @@ -412,10 +423,10 @@ WatchJoystick(SDL_Joystick * joystick) s_nNumAxes = SDL_JoystickNumAxes(joystick); s_arrAxisState = (AxisState *)SDL_calloc(s_nNumAxes, sizeof(*s_arrAxisState)); - /* Skip any spurious events at start */ - while (SDL_PollEvent(&event) > 0) { - continue; - } + /* Skip any spurious events at start */ + while (SDL_PollEvent(&event) > 0) { + continue; + } /* Loop, getting joystick events! */ while (!done && !s_bBindingComplete) { @@ -559,7 +570,7 @@ WatchJoystick(SDL_Joystick * joystick) if ((event.key.keysym.sym != SDLK_ESCAPE)) { break; } - /* Fall through to signal quit */ + SDL_FALLTHROUGH; case SDL_QUIT: done = SDL_TRUE; break; @@ -728,6 +739,10 @@ main(int argc, char *argv[]) exit(1); } + if (argv[1] && SDL_strcmp(argv[1], "--bind-touchpad") == 0) { + bind_touchpad = SDL_TRUE; + } + /* Create a window to display joystick axis position */ window = SDL_CreateWindow("Game Controller Map", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, @@ -737,7 +752,13 @@ main(int argc, char *argv[]) return 2; } - while (SDL_NumJoysticks() == 0) { + screen = SDL_CreateRenderer(window, -1, 0); + if (screen == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError()); + return 2; + } + + while (!done && SDL_NumJoysticks() == 0) { SDL_Event event; while (SDL_PollEvent(&event) > 0) { @@ -746,7 +767,7 @@ main(int argc, char *argv[]) if ((event.key.keysym.sym != SDLK_ESCAPE)) { break; } - /* Fall through to signal quit */ + SDL_FALLTHROUGH; case SDL_QUIT: done = SDL_TRUE; break; @@ -754,6 +775,7 @@ main(int argc, char *argv[]) break; } } + SDL_RenderPresent(screen); } /* Print information about the joysticks */ diff --git a/Engine/lib/sdl/test/loopwave.c b/Engine/lib/sdl/test/loopwave.c index 64d2f1aaf..14ac4dbaf 100644 --- a/Engine/lib/sdl/test/loopwave.c +++ b/Engine/lib/sdl/test/loopwave.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/loopwavequeue.c b/Engine/lib/sdl/test/loopwavequeue.c index bb50221f0..a5d0ea3cc 100644 --- a/Engine/lib/sdl/test/loopwavequeue.c +++ b/Engine/lib/sdl/test/loopwavequeue.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testatomic.c b/Engine/lib/sdl/test/testatomic.c index 0a4e62dd1..16678db5d 100644 --- a/Engine/lib/sdl/test/testatomic.c +++ b/Engine/lib/sdl/test/testatomic.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,13 +19,13 @@ */ static -char * -tf(SDL_bool tf) +const char * +tf(SDL_bool _tf) { - static char *t = "TRUE"; - static char *f = "FALSE"; + static const char *t = "TRUE"; + static const char *f = "FALSE"; - if (tf) + if (_tf) { return t; } @@ -353,7 +353,7 @@ static SDL_bool EnqueueEvent_LockFree(SDL_EventQueue *queue, const SDL_Event *ev } #ifdef TEST_SPINLOCK_FIFO - SDL_AtomicDecRef(&queue->rwcount); + (void) SDL_AtomicDecRef(&queue->rwcount); #endif return status; } @@ -400,7 +400,7 @@ static SDL_bool DequeueEvent_LockFree(SDL_EventQueue *queue, SDL_Event *event) } #ifdef TEST_SPINLOCK_FIFO - SDL_AtomicDecRef(&queue->rwcount); + (void) SDL_AtomicDecRef(&queue->rwcount); #endif return status; } @@ -473,8 +473,6 @@ static SDL_bool DequeueEvent_Mutex(SDL_EventQueue *queue, SDL_Event *event) static SDL_sem *writersDone; static SDL_sem *readersDone; -static SDL_atomic_t writersRunning; -static SDL_atomic_t readersRunning; typedef struct { @@ -525,7 +523,6 @@ static int SDLCALL FIFO_Writer(void* _data) } } } - SDL_AtomicAdd(&writersRunning, -1); SDL_SemPost(writersDone); return 0; } @@ -563,7 +560,6 @@ static int SDLCALL FIFO_Reader(void* _data) } } } - SDL_AtomicAdd(&readersRunning, -1); SDL_SemPost(readersDone); return 0; } @@ -581,7 +577,7 @@ static int SDLCALL FIFO_Watcher(void* _data) SDL_Delay(0); } /* Do queue manipulation here... */ - SDL_AtomicDecRef(&queue->watcher); + (void) SDL_AtomicDecRef(&queue->watcher); SDL_AtomicUnlock(&queue->lock); /* Wait a bit... */ @@ -627,7 +623,6 @@ static void RunFIFOTest(SDL_bool lock_free) /* Start the readers first */ SDL_Log("Starting %d readers\n", NUM_READERS); SDL_zeroa(readerData); - SDL_AtomicSet(&readersRunning, NUM_READERS); for (i = 0; i < NUM_READERS; ++i) { char name[64]; SDL_snprintf(name, sizeof (name), "FIFOReader%d", i); @@ -639,7 +634,6 @@ static void RunFIFOTest(SDL_bool lock_free) /* Start up the writers */ SDL_Log("Starting %d writers\n", NUM_WRITERS); SDL_zeroa(writerData); - SDL_AtomicSet(&writersRunning, NUM_WRITERS); for (i = 0; i < NUM_WRITERS; ++i) { char name[64]; SDL_snprintf(name, sizeof (name), "FIFOWriter%d", i); @@ -650,7 +644,7 @@ static void RunFIFOTest(SDL_bool lock_free) } /* Wait for the writers */ - while (SDL_AtomicGet(&writersRunning) > 0) { + for (i = 0; i < NUM_WRITERS; ++i) { SDL_SemWait(writersDone); } @@ -658,7 +652,7 @@ static void RunFIFOTest(SDL_bool lock_free) SDL_AtomicSet(&queue.active, 0); /* Wait for the readers */ - while (SDL_AtomicGet(&readersRunning) > 0) { + for (i = 0; i < NUM_READERS; ++i) { SDL_SemWait(readersDone); } diff --git a/Engine/lib/sdl/test/testaudiocapture.c b/Engine/lib/sdl/test/testaudiocapture.c index 2dfbd02be..03d373273 100644 --- a/Engine/lib/sdl/test/testaudiocapture.c +++ b/Engine/lib/sdl/test/testaudiocapture.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testaudiohotplug.c b/Engine/lib/sdl/test/testaudiohotplug.c index fe9745976..536cc4c3b 100644 --- a/Engine/lib/sdl/test/testaudiohotplug.c +++ b/Engine/lib/sdl/test/testaudiohotplug.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testaudioinfo.c b/Engine/lib/sdl/test/testaudioinfo.c index 8f58498de..d22aed270 100644 --- a/Engine/lib/sdl/test/testaudioinfo.c +++ b/Engine/lib/sdl/test/testaudioinfo.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testautomation.c b/Engine/lib/sdl/test/testautomation.c index ef600178c..0dc37f4a0 100644 --- a/Engine/lib/sdl/test/testautomation.c +++ b/Engine/lib/sdl/test/testautomation.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testautomation_audio.c b/Engine/lib/sdl/test/testautomation_audio.c index be0f15e3d..96c174f5c 100644 --- a/Engine/lib/sdl/test/testautomation_audio.c +++ b/Engine/lib/sdl/test/testautomation_audio.c @@ -498,7 +498,7 @@ const int _numAudioFormats = 18; SDL_AudioFormat _audioFormats[] = { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S16SYS, AUDIO_S16, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U16SYS, AUDIO_U16, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S32SYS, AUDIO_S32, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_F32SYS, AUDIO_F32 }; -char *_audioFormatsVerbose[] = { "AUDIO_S8", "AUDIO_U8", "AUDIO_S16LSB", "AUDIO_S16MSB", "AUDIO_S16SYS", "AUDIO_S16", "AUDIO_U16LSB", +const char *_audioFormatsVerbose[] = { "AUDIO_S8", "AUDIO_U8", "AUDIO_S16LSB", "AUDIO_S16MSB", "AUDIO_S16SYS", "AUDIO_S16", "AUDIO_U16LSB", "AUDIO_U16MSB", "AUDIO_U16SYS", "AUDIO_U16", "AUDIO_S32LSB", "AUDIO_S32MSB", "AUDIO_S32SYS", "AUDIO_S32", "AUDIO_F32LSB", "AUDIO_F32MSB", "AUDIO_F32SYS", "AUDIO_F32" }; const int _numAudioChannels = 4; @@ -697,7 +697,7 @@ int audio_openCloseAndGetAudioStatus() SDL_AudioStatus result; int i; int count; - char *device; + const char *device; SDL_AudioDeviceID id; SDL_AudioSpec desired, obtained; @@ -707,7 +707,7 @@ int audio_openCloseAndGetAudioStatus() if (count > 0) { for (i = 0; i < count; i++) { /* Get device name */ - device = (char *)SDL_GetAudioDeviceName(i, 0); + device = SDL_GetAudioDeviceName(i, 0); SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); if (device == NULL) return TEST_ABORTED; @@ -721,7 +721,7 @@ int audio_openCloseAndGetAudioStatus() desired.userdata=NULL; /* Open device */ - id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); + id = SDL_OpenAudioDevice(device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id); if (id > 1) { @@ -755,7 +755,7 @@ int audio_lockUnlockOpenAudioDevice() { int i; int count; - char *device; + const char *device; SDL_AudioDeviceID id; SDL_AudioSpec desired, obtained; @@ -765,7 +765,7 @@ int audio_lockUnlockOpenAudioDevice() if (count > 0) { for (i = 0; i < count; i++) { /* Get device name */ - device = (char *)SDL_GetAudioDeviceName(i, 0); + device = SDL_GetAudioDeviceName(i, 0); SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); if (device == NULL) return TEST_ABORTED; @@ -779,7 +779,7 @@ int audio_lockUnlockOpenAudioDevice() desired.userdata=NULL; /* Open device */ - id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); + id = SDL_OpenAudioDevice(device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id); if (id > 1) { @@ -917,7 +917,7 @@ int audio_openCloseAudioDeviceConnected() int result = -1; int i; int count; - char *device; + const char *device; SDL_AudioDeviceID id; SDL_AudioSpec desired, obtained; @@ -927,7 +927,7 @@ int audio_openCloseAudioDeviceConnected() if (count > 0) { for (i = 0; i < count; i++) { /* Get device name */ - device = (char *)SDL_GetAudioDeviceName(i, 0); + device = SDL_GetAudioDeviceName(i, 0); SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); if (device == NULL) return TEST_ABORTED; @@ -941,7 +941,7 @@ int audio_openCloseAudioDeviceConnected() desired.userdata=NULL; /* Open device */ - id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); + id = SDL_OpenAudioDevice(device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >1, got: %i", id); if (id > 1) { diff --git a/Engine/lib/sdl/test/testautomation_clipboard.c b/Engine/lib/sdl/test/testautomation_clipboard.c index 417d95746..113c7dc89 100644 --- a/Engine/lib/sdl/test/testautomation_clipboard.c +++ b/Engine/lib/sdl/test/testautomation_clipboard.c @@ -16,13 +16,12 @@ * \brief Check call to SDL_HasClipboardText * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasClipboardText + * http://wiki.libsdl.org/SDL_HasClipboardText */ int clipboard_testHasClipboardText(void *arg) { - SDL_bool result; - result = SDL_HasClipboardText(); + SDL_HasClipboardText(); SDLTest_AssertPass("Call to SDL_HasClipboardText succeeded"); return TEST_COMPLETED; @@ -32,7 +31,7 @@ clipboard_testHasClipboardText(void *arg) * \brief Check call to SDL_GetClipboardText * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetClipboardText + * http://wiki.libsdl.org/SDL_GetClipboardText */ int clipboard_testGetClipboardText(void *arg) @@ -49,7 +48,7 @@ clipboard_testGetClipboardText(void *arg) /** * \brief Check call to SDL_SetClipboardText * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetClipboardText + * http://wiki.libsdl.org/SDL_SetClipboardText */ int clipboard_testSetClipboardText(void *arg) @@ -78,9 +77,9 @@ clipboard_testSetClipboardText(void *arg) /** * \brief End-to-end test of SDL_xyzClipboardText functions * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasClipboardText - * http://wiki.libsdl.org/moin.cgi/SDL_GetClipboardText - * http://wiki.libsdl.org/moin.cgi/SDL_SetClipboardText + * http://wiki.libsdl.org/SDL_HasClipboardText + * http://wiki.libsdl.org/SDL_GetClipboardText + * http://wiki.libsdl.org/SDL_SetClipboardText */ int clipboard_testClipboardTextFunctions(void *arg) diff --git a/Engine/lib/sdl/test/testautomation_events.c b/Engine/lib/sdl/test/testautomation_events.c index 09004da52..20f2ea5e4 100644 --- a/Engine/lib/sdl/test/testautomation_events.c +++ b/Engine/lib/sdl/test/testautomation_events.c @@ -42,8 +42,8 @@ int SDLCALL _events_sampleNullEventFilter(void *userdata, SDL_Event *event) /** * @brief Test pumping and peeking events. * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_PumpEvents - * @sa http://wiki.libsdl.org/moin.cgi/SDL_PollEvent + * @sa http://wiki.libsdl.org/SDL_PumpEvents + * @sa http://wiki.libsdl.org/SDL_PollEvent */ int events_pushPumpAndPollUserevent(void *arg) @@ -76,8 +76,8 @@ events_pushPumpAndPollUserevent(void *arg) /** * @brief Adds and deletes an event watch function with NULL userdata * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_AddEventWatch - * @sa http://wiki.libsdl.org/moin.cgi/SDL_DelEventWatch + * @sa http://wiki.libsdl.org/SDL_AddEventWatch + * @sa http://wiki.libsdl.org/SDL_DelEventWatch * */ int @@ -126,8 +126,8 @@ events_addDelEventWatch(void *arg) /** * @brief Adds and deletes an event watch function with userdata * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_AddEventWatch - * @sa http://wiki.libsdl.org/moin.cgi/SDL_DelEventWatch + * @sa http://wiki.libsdl.org/SDL_AddEventWatch + * @sa http://wiki.libsdl.org/SDL_DelEventWatch * */ int diff --git a/Engine/lib/sdl/test/testautomation_hints.c b/Engine/lib/sdl/test/testautomation_hints.c index a6beb88d7..0d1b7b6f5 100644 --- a/Engine/lib/sdl/test/testautomation_hints.c +++ b/Engine/lib/sdl/test/testautomation_hints.c @@ -9,7 +9,7 @@ const int _numHintsEnum = 25; -char* _HintsEnum[] = +const char* _HintsEnum[] = { SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_HINT_FRAMEBUFFER_ACCELERATION, @@ -37,33 +37,33 @@ char* _HintsEnum[] = SDL_HINT_VIDEO_X11_XVIDMODE, SDL_HINT_XINPUT_ENABLED, }; -char* _HintsVerbose[] = +const char* _HintsVerbose[] = { - "SDL_HINT_ACCELEROMETER_AS_JOYSTICK", - "SDL_HINT_FRAMEBUFFER_ACCELERATION", - "SDL_HINT_GAMECONTROLLERCONFIG", - "SDL_HINT_GRAB_KEYBOARD", - "SDL_HINT_IDLE_TIMER_DISABLED", - "SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS", - "SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK", - "SDL_HINT_MOUSE_RELATIVE_MODE_WARP", - "SDL_HINT_ORIENTATIONS", - "SDL_HINT_RENDER_DIRECT3D_THREADSAFE", - "SDL_HINT_RENDER_DRIVER", - "SDL_HINT_RENDER_OPENGL_SHADERS", - "SDL_HINT_RENDER_SCALE_QUALITY", - "SDL_HINT_RENDER_VSYNC", - "SDL_HINT_TIMER_RESOLUTION", - "SDL_HINT_VIDEO_ALLOW_SCREENSAVER", - "SDL_HINT_VIDEO_HIGHDPI_DISABLED", - "SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES", - "SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS", - "SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT", - "SDL_HINT_VIDEO_WIN_D3DCOMPILER", - "SDL_HINT_VIDEO_X11_XINERAMA", - "SDL_HINT_VIDEO_X11_XRANDR", - "SDL_HINT_VIDEO_X11_XVIDMODE", - "SDL_HINT_XINPUT_ENABLED" + "SDL_ACCELEROMETER_AS_JOYSTICK", + "SDL_FRAMEBUFFER_ACCELERATION", + "SDL_GAMECONTROLLERCONFIG", + "SDL_GRAB_KEYBOARD", + "SDL_IDLE_TIMER_DISABLED", + "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS", + "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK", + "SDL_MOUSE_RELATIVE_MODE_WARP", + "SDL_ORIENTATIONS", + "SDL_RENDER_DIRECT3D_THREADSAFE", + "SDL_RENDER_DRIVER", + "SDL_RENDER_OPENGL_SHADERS", + "SDL_RENDER_SCALE_QUALITY", + "SDL_RENDER_VSYNC", + "SDL_TIMER_RESOLUTION", + "SDL_VIDEO_ALLOW_SCREENSAVER", + "SDL_VIDEO_HIGHDPI_DISABLED", + "SDL_VIDEO_MAC_FULLSCREEN_SPACES", + "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS", + "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT", + "SDL_VIDEO_WIN_D3DCOMPILER", + "SDL_VIDEO_X11_XINERAMA", + "SDL_VIDEO_X11_XRANDR", + "SDL_VIDEO_X11_XVIDMODE", + "SDL_XINPUT_ENABLED" }; @@ -75,14 +75,14 @@ char* _HintsVerbose[] = int hints_getHint(void *arg) { - char *result1; - char *result2; + const char *result1; + const char *result2; int i; - + for (i=0; i<_numHintsEnum; i++) { - result1 = (char *)SDL_GetHint((char*)_HintsEnum[i]); + result1 = SDL_GetHint(_HintsEnum[i]); SDLTest_AssertPass("Call to SDL_GetHint(%s) - using define definition", (char*)_HintsEnum[i]); - result2 = (char *)SDL_GetHint((char *)_HintsVerbose[i]); + result2 = SDL_GetHint(_HintsVerbose[i]); SDLTest_AssertPass("Call to SDL_GetHint(%s) - using string definition", (char*)_HintsVerbose[i]); SDLTest_AssertCheck( (result1 == NULL && result2 == NULL) || (SDL_strcmp(result1, result2) == 0), @@ -90,7 +90,7 @@ hints_getHint(void *arg) (result1 == NULL) ? "null" : result1, (result2 == NULL) ? "null" : result2); } - + return TEST_COMPLETED; } @@ -100,48 +100,52 @@ hints_getHint(void *arg) int hints_setHint(void *arg) { - char *originalValue; - char *value; - char *testValue; + const char *originalValue; + const char *value; + const char *testValue; SDL_bool result; int i, j; - /* Create random values to set */ + /* Create random values to set */ value = SDLTest_RandomAsciiStringOfSize(10); - + for (i=0; i<_numHintsEnum; i++) { /* Capture current value */ - originalValue = (char *)SDL_GetHint((char*)_HintsEnum[i]); - SDLTest_AssertPass("Call to SDL_GetHint(%s)", (char*)_HintsEnum[i]); - + originalValue = SDL_GetHint(_HintsEnum[i]); + SDLTest_AssertPass("Call to SDL_GetHint(%s)", _HintsEnum[i]); + + /* Copy the original value, since it will be freed when we set it again */ + originalValue = originalValue ? SDL_strdup(originalValue) : NULL; + /* Set value (twice) */ for (j=1; j<=2; j++) { - result = SDL_SetHint((char*)_HintsEnum[i], value); - SDLTest_AssertPass("Call to SDL_SetHint(%s, %s) (iteration %i)", (char*)_HintsEnum[i], value, j); + result = SDL_SetHint(_HintsEnum[i], value); + SDLTest_AssertPass("Call to SDL_SetHint(%s, %s) (iteration %i)", _HintsEnum[i], value, j); SDLTest_AssertCheck( result == SDL_TRUE || result == SDL_FALSE, "Verify valid result was returned, got: %i", (int)result); - testValue = (char *)SDL_GetHint((char*)_HintsEnum[i]); - SDLTest_AssertPass("Call to SDL_GetHint(%s) - using string definition", (char*)_HintsVerbose[i]); + testValue = SDL_GetHint(_HintsEnum[i]); + SDLTest_AssertPass("Call to SDL_GetHint(%s) - using string definition", _HintsVerbose[i]); SDLTest_AssertCheck( (SDL_strcmp(value, testValue) == 0), "Verify returned value equals set value; got: testValue='%s' value='%s", (testValue == NULL) ? "null" : testValue, value); } - + /* Reset original value */ - result = SDL_SetHint((char*)_HintsEnum[i], originalValue); - SDLTest_AssertPass("Call to SDL_SetHint(%s, originalValue)", (char*)_HintsEnum[i]); + result = SDL_SetHint(_HintsEnum[i], originalValue); + SDLTest_AssertPass("Call to SDL_SetHint(%s, originalValue)", _HintsEnum[i]); SDLTest_AssertCheck( result == SDL_TRUE || result == SDL_FALSE, "Verify valid result was returned, got: %i", (int)result); + SDL_free((void *)originalValue); } - - SDL_free(value); - + + SDL_free((void *)value); + return TEST_COMPLETED; } diff --git a/Engine/lib/sdl/test/testautomation_keyboard.c b/Engine/lib/sdl/test/testautomation_keyboard.c index 6f25bb76c..84a763589 100644 --- a/Engine/lib/sdl/test/testautomation_keyboard.c +++ b/Engine/lib/sdl/test/testautomation_keyboard.c @@ -16,7 +16,7 @@ /** * @brief Check call to SDL_GetKeyboardState with and without numkeys reference. * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyboardState + * @sa http://wiki.libsdl.org/SDL_GetKeyboardState */ int keyboard_getKeyboardState(void *arg) @@ -42,15 +42,13 @@ keyboard_getKeyboardState(void *arg) /** * @brief Check call to SDL_GetKeyboardFocus * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyboardFocus + * @sa http://wiki.libsdl.org/SDL_GetKeyboardFocus */ int keyboard_getKeyboardFocus(void *arg) { - SDL_Window* window; - /* Call, but ignore return value */ - window = SDL_GetKeyboardFocus(); + SDL_GetKeyboardFocus(); SDLTest_AssertPass("Call to SDL_GetKeyboardFocus()"); return TEST_COMPLETED; @@ -59,7 +57,7 @@ keyboard_getKeyboardFocus(void *arg) /** * @brief Check call to SDL_GetKeyFromName for known, unknown and invalid name. * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyFromName + * @sa http://wiki.libsdl.org/SDL_GetKeyFromName */ int keyboard_getKeyFromName(void *arg) @@ -126,7 +124,7 @@ _checkInvalidScancodeError() /** * @brief Check call to SDL_GetKeyFromScancode * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyFromScancode + * @sa http://wiki.libsdl.org/SDL_GetKeyFromScancode */ int keyboard_getKeyFromScancode(void *arg) @@ -165,13 +163,13 @@ keyboard_getKeyFromScancode(void *arg) /** * @brief Check call to SDL_GetKeyName * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyName + * @sa http://wiki.libsdl.org/SDL_GetKeyName */ int keyboard_getKeyName(void *arg) { - char *result; - char *expected; + const char *result; + const char *expected; /* Case where key has a 1 character name */ expected = "3"; @@ -221,14 +219,14 @@ keyboard_getKeyName(void *arg) /** * @brief SDL_GetScancodeName negative cases * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetScancodeName + * @sa http://wiki.libsdl.org/SDL_GetScancodeName */ int keyboard_getScancodeNameNegative(void *arg) { SDL_Scancode scancode; - char *result; - char *expected = ""; + const char *result; + const char *expected = ""; /* Clear error message */ SDL_ClearError(); @@ -248,14 +246,14 @@ keyboard_getScancodeNameNegative(void *arg) /** * @brief SDL_GetKeyName negative cases * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyName + * @sa http://wiki.libsdl.org/SDL_GetKeyName */ int keyboard_getKeyNameNegative(void *arg) { SDL_Keycode keycode; - char *result; - char *expected = ""; + const char *result; + const char *expected = ""; /* Unknown keycode */ keycode = SDLK_UNKNOWN; @@ -285,8 +283,8 @@ keyboard_getKeyNameNegative(void *arg) /** * @brief Check call to SDL_GetModState and SDL_SetModState * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetModState - * @sa http://wiki.libsdl.org/moin.cgi/SDL_SetModState + * @sa http://wiki.libsdl.org/SDL_GetModState + * @sa http://wiki.libsdl.org/SDL_SetModState */ int keyboard_getSetModState(void *arg) @@ -307,7 +305,7 @@ keyboard_getSetModState(void *arg) KMOD_NUM | KMOD_CAPS | KMOD_MODE | - KMOD_RESERVED; + KMOD_SCROLL; /* Get state, cache for later reset */ result = SDL_GetModState(); @@ -346,8 +344,8 @@ keyboard_getSetModState(void *arg) /** * @brief Check call to SDL_StartTextInput and SDL_StopTextInput * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_StartTextInput - * @sa http://wiki.libsdl.org/moin.cgi/SDL_StopTextInput + * @sa http://wiki.libsdl.org/SDL_StartTextInput + * @sa http://wiki.libsdl.org/SDL_StopTextInput */ int keyboard_startStopTextInput(void *arg) @@ -393,7 +391,7 @@ void _testSetTextInputRect(SDL_Rect refRect) /** * @brief Check call to SDL_SetTextInputRect * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_SetTextInputRect + * @sa http://wiki.libsdl.org/SDL_SetTextInputRect */ int keyboard_setTextInputRect(void *arg) @@ -473,7 +471,7 @@ keyboard_setTextInputRect(void *arg) /** * @brief Check call to SDL_SetTextInputRect with invalid data * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_SetTextInputRect + * @sa http://wiki.libsdl.org/SDL_SetTextInputRect */ int keyboard_setTextInputRectNegative(void *arg) @@ -511,8 +509,8 @@ keyboard_setTextInputRectNegative(void *arg) /** * @brief Check call to SDL_GetScancodeFromKey * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetScancodeFromKey - * @sa http://wiki.libsdl.org/moin.cgi/SDL_Keycode + * @sa http://wiki.libsdl.org/SDL_GetScancodeFromKey + * @sa http://wiki.libsdl.org/SDL_Keycode */ int keyboard_getScancodeFromKey(void *arg) @@ -535,8 +533,8 @@ keyboard_getScancodeFromKey(void *arg) /** * @brief Check call to SDL_GetScancodeFromName * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetScancodeFromName - * @sa http://wiki.libsdl.org/moin.cgi/SDL_Keycode + * @sa http://wiki.libsdl.org/SDL_GetScancodeFromName + * @sa http://wiki.libsdl.org/SDL_Keycode */ int keyboard_getScancodeFromName(void *arg) @@ -608,13 +606,13 @@ _checkInvalidNameError() /** * @brief Check call to SDL_GetScancodeFromName with invalid data * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetScancodeFromName - * @sa http://wiki.libsdl.org/moin.cgi/SDL_Keycode + * @sa http://wiki.libsdl.org/SDL_GetScancodeFromName + * @sa http://wiki.libsdl.org/SDL_Keycode */ int keyboard_getScancodeFromNameNegative(void *arg) { - char *name; + const char *name; SDL_Scancode scancode; /* Clear error message */ @@ -627,9 +625,9 @@ keyboard_getScancodeFromNameNegative(void *arg) if (name == NULL) { return TEST_ABORTED; } - scancode = SDL_GetScancodeFromName((const char *)name); + scancode = SDL_GetScancodeFromName(name); SDLTest_AssertPass("Call to SDL_GetScancodeFromName('%s')", name); - SDL_free(name); + SDL_free((void *)name); SDLTest_AssertCheck(scancode == SDL_SCANCODE_UNKNOWN, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_UNKNOWN, scancode); _checkInvalidNameError(); diff --git a/Engine/lib/sdl/test/testautomation_main.c b/Engine/lib/sdl/test/testautomation_main.c index ae060cdd1..229f2bc55 100644 --- a/Engine/lib/sdl/test/testautomation_main.c +++ b/Engine/lib/sdl/test/testautomation_main.c @@ -13,8 +13,8 @@ /* ! * \brief Tests SDL_Init() and SDL_Quit() of Joystick and Haptic subsystems * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_Init - * http://wiki.libsdl.org/moin.cgi/SDL_Quit + * http://wiki.libsdl.org/SDL_Init + * http://wiki.libsdl.org/SDL_Quit */ static int main_testInitQuitJoystickHaptic (void *arg) { @@ -41,8 +41,8 @@ static int main_testInitQuitJoystickHaptic (void *arg) /* ! * \brief Tests SDL_InitSubSystem() and SDL_QuitSubSystem() * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_Init - * http://wiki.libsdl.org/moin.cgi/SDL_Quit + * http://wiki.libsdl.org/SDL_Init + * http://wiki.libsdl.org/SDL_Quit */ static int main_testInitQuitSubSystem (void *arg) { diff --git a/Engine/lib/sdl/test/testautomation_mouse.c b/Engine/lib/sdl/test/testautomation_mouse.c index ed30f2604..b99afc1ce 100644 --- a/Engine/lib/sdl/test/testautomation_mouse.c +++ b/Engine/lib/sdl/test/testautomation_mouse.c @@ -192,8 +192,8 @@ static SDL_Cursor *_initArrowCursor(const char *image[]) /** * @brief Check call to SDL_CreateCursor and SDL_FreeCursor * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_CreateCursor - * @sa http://wiki.libsdl.org/moin.cgi/SDL_FreeCursor + * @sa http://wiki.libsdl.org/SDL_CreateCursor + * @sa http://wiki.libsdl.org/SDL_FreeCursor */ int mouse_createFreeCursor(void *arg) @@ -218,8 +218,8 @@ mouse_createFreeCursor(void *arg) /** * @brief Check call to SDL_CreateColorCursor and SDL_FreeCursor * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_CreateColorCursor - * @sa http://wiki.libsdl.org/moin.cgi/SDL_FreeCursor + * @sa http://wiki.libsdl.org/SDL_CreateColorCursor + * @sa http://wiki.libsdl.org/SDL_FreeCursor */ int mouse_createFreeColorCursor(void *arg) @@ -275,7 +275,7 @@ void _changeCursorVisibility(int state) /** * @brief Check call to SDL_ShowCursor * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_ShowCursor + * @sa http://wiki.libsdl.org/SDL_ShowCursor */ int mouse_showCursor(void *arg) @@ -305,7 +305,7 @@ mouse_showCursor(void *arg) /** * @brief Check call to SDL_SetCursor * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_SetCursor + * @sa http://wiki.libsdl.org/SDL_SetCursor */ int mouse_setCursor(void *arg) @@ -338,7 +338,7 @@ mouse_setCursor(void *arg) /** * @brief Check call to SDL_GetCursor * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetCursor + * @sa http://wiki.libsdl.org/SDL_GetCursor */ int mouse_getCursor(void *arg) @@ -356,8 +356,8 @@ mouse_getCursor(void *arg) /** * @brief Check call to SDL_GetRelativeMouseMode and SDL_SetRelativeMouseMode * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetRelativeMouseMode - * @sa http://wiki.libsdl.org/moin.cgi/SDL_SetRelativeMouseMode + * @sa http://wiki.libsdl.org/SDL_GetRelativeMouseMode + * @sa http://wiki.libsdl.org/SDL_SetRelativeMouseMode */ int mouse_getSetRelativeMouseMode(void *arg) @@ -440,7 +440,7 @@ void _destroyMouseSuiteTestWindow(SDL_Window *window) /** * @brief Check call to SDL_WarpMouseInWindow * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_WarpMouseInWindow + * @sa http://wiki.libsdl.org/SDL_WarpMouseInWindow */ int mouse_warpMouseInWindow(void *arg) @@ -502,7 +502,7 @@ mouse_warpMouseInWindow(void *arg) /** * @brief Check call to SDL_GetMouseFocus * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetMouseFocus + * @sa http://wiki.libsdl.org/SDL_GetMouseFocus */ int mouse_getMouseFocus(void *arg) @@ -527,6 +527,7 @@ mouse_getMouseFocus(void *arg) SDLTest_AssertPass("SDL_WarpMouseInWindow(...,%i,%i)", x, y); /* Pump events to update focus state */ + SDL_Delay(100); SDL_PumpEvents(); SDLTest_AssertPass("SDL_PumpEvents()"); diff --git a/Engine/lib/sdl/test/testautomation_pixels.c b/Engine/lib/sdl/test/testautomation_pixels.c index b54be8699..0f6870c9a 100644 --- a/Engine/lib/sdl/test/testautomation_pixels.c +++ b/Engine/lib/sdl/test/testautomation_pixels.c @@ -45,7 +45,7 @@ Uint32 _RGBPixelFormats[] = SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB2101010 }; -char* _RGBPixelFormatsVerbose[] = +const char* _RGBPixelFormatsVerbose[] = { "SDL_PIXELFORMAT_INDEX1LSB", "SDL_PIXELFORMAT_INDEX1MSB", @@ -92,7 +92,7 @@ Uint32 _nonRGBPixelFormats[] = SDL_PIXELFORMAT_NV12, SDL_PIXELFORMAT_NV21 }; -char* _nonRGBPixelFormatsVerbose[] = +const char* _nonRGBPixelFormatsVerbose[] = { "SDL_PIXELFORMAT_YV12", "SDL_PIXELFORMAT_IYUV", @@ -110,7 +110,7 @@ Uint32 _invalidPixelFormats[] = 0xfffffffe, 0xffffffff }; -char* _invalidPixelFormatsVerbose[] = +const char* _invalidPixelFormatsVerbose[] = { "SDL_PIXELFORMAT_UNKNOWN", "SDL_PIXELFORMAT_UNKNOWN" @@ -121,8 +121,8 @@ char* _invalidPixelFormatsVerbose[] = /** * @brief Call to SDL_AllocFormat and SDL_FreeFormat * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_AllocFormat - * @sa http://wiki.libsdl.org/moin.fcg/SDL_FreeFormat + * @sa http://wiki.libsdl.org/SDL_AllocFormat + * @sa http://wiki.libsdl.org/SDL_FreeFormat */ int pixels_allocFreeFormat(void *arg) @@ -228,7 +228,7 @@ pixels_allocFreeFormat(void *arg) /** * @brief Call to SDL_GetPixelFormatName * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetPixelFormatName + * @sa http://wiki.libsdl.org/SDL_GetPixelFormatName */ int pixels_getPixelFormatName(void *arg) @@ -237,14 +237,14 @@ pixels_getPixelFormatName(void *arg) const char *error; int i; Uint32 format; - char* result; + const char *result; /* Blank/undefined format */ format = 0; SDLTest_Log("RGB Format: %s (%u)", unknownFormat, format); /* Get name of format */ - result = (char *)SDL_GetPixelFormatName(format); + result = SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { @@ -259,7 +259,7 @@ pixels_getPixelFormatName(void *arg) SDLTest_Log("RGB Format: %s (%u)", _RGBPixelFormatsVerbose[i], format); /* Get name of format */ - result = (char *)SDL_GetPixelFormatName(format); + result = SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { @@ -275,7 +275,7 @@ pixels_getPixelFormatName(void *arg) SDLTest_Log("non-RGB Format: %s (%u)", _nonRGBPixelFormatsVerbose[i], format); /* Get name of format */ - result = (char *)SDL_GetPixelFormatName(format); + result = SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { @@ -292,7 +292,7 @@ pixels_getPixelFormatName(void *arg) SDLTest_AssertPass("Call to SDL_ClearError()"); for (i = 0; i < _numInvalidPixelFormats; i++) { format = _invalidPixelFormats[i]; - result = (char *)SDL_GetPixelFormatName(format); + result = SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName(%u)", format); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { @@ -312,8 +312,8 @@ pixels_getPixelFormatName(void *arg) /** * @brief Call to SDL_AllocPalette and SDL_FreePalette * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_AllocPalette - * @sa http://wiki.libsdl.org/moin.fcg/SDL_FreePalette + * @sa http://wiki.libsdl.org/SDL_AllocPalette + * @sa http://wiki.libsdl.org/SDL_FreePalette */ int pixels_allocFreePalette(void *arg) @@ -402,7 +402,7 @@ pixels_allocFreePalette(void *arg) /** * @brief Call to SDL_CalculateGammaRamp * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_CalculateGammaRamp + * @sa http://wiki.libsdl.org/SDL_CalculateGammaRamp */ int pixels_calcGammaRamp(void *arg) diff --git a/Engine/lib/sdl/test/testautomation_platform.c b/Engine/lib/sdl/test/testautomation_platform.c index 7cc732a7b..4e28ba166 100644 --- a/Engine/lib/sdl/test/testautomation_platform.c +++ b/Engine/lib/sdl/test/testautomation_platform.c @@ -101,11 +101,11 @@ int platform_testEndianessAndSwap(void *arg) /* ! * \brief Tests SDL_GetXYZ() functions * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetPlatform - * http://wiki.libsdl.org/moin.cgi/SDL_GetCPUCount - * http://wiki.libsdl.org/moin.cgi/SDL_GetCPUCacheLineSize - * http://wiki.libsdl.org/moin.cgi/SDL_GetRevision - * http://wiki.libsdl.org/moin.cgi/SDL_GetRevisionNumber + * http://wiki.libsdl.org/SDL_GetPlatform + * http://wiki.libsdl.org/SDL_GetCPUCount + * http://wiki.libsdl.org/SDL_GetCPUCacheLineSize + * http://wiki.libsdl.org/SDL_GetRevision + * http://wiki.libsdl.org/SDL_GetRevisionNumber */ int platform_testGetFunctions (void *arg) { @@ -141,60 +141,55 @@ int platform_testGetFunctions (void *arg) SDLTest_AssertPass("SDL_GetRevision()"); SDLTest_AssertCheck(revision != NULL, "SDL_GetRevision() != NULL"); - ret = SDL_GetRevisionNumber(); - SDLTest_AssertPass("SDL_GetRevisionNumber()"); - return TEST_COMPLETED; } /* ! * \brief Tests SDL_HasXYZ() functions * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_Has3DNow - * http://wiki.libsdl.org/moin.cgi/SDL_HasAltiVec - * http://wiki.libsdl.org/moin.cgi/SDL_HasMMX - * http://wiki.libsdl.org/moin.cgi/SDL_HasRDTSC - * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE - * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE2 - * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE3 - * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE41 - * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE42 - * http://wiki.libsdl.org/moin.cgi/SDL_HasAVX + * http://wiki.libsdl.org/SDL_Has3DNow + * http://wiki.libsdl.org/SDL_HasAltiVec + * http://wiki.libsdl.org/SDL_HasMMX + * http://wiki.libsdl.org/SDL_HasRDTSC + * http://wiki.libsdl.org/SDL_HasSSE + * http://wiki.libsdl.org/SDL_HasSSE2 + * http://wiki.libsdl.org/SDL_HasSSE3 + * http://wiki.libsdl.org/SDL_HasSSE41 + * http://wiki.libsdl.org/SDL_HasSSE42 + * http://wiki.libsdl.org/SDL_HasAVX */ int platform_testHasFunctions (void *arg) { - int ret; - /* TODO: independently determine and compare values as well */ - ret = SDL_HasRDTSC(); + SDL_HasRDTSC(); SDLTest_AssertPass("SDL_HasRDTSC()"); - ret = SDL_HasAltiVec(); + SDL_HasAltiVec(); SDLTest_AssertPass("SDL_HasAltiVec()"); - ret = SDL_HasMMX(); + SDL_HasMMX(); SDLTest_AssertPass("SDL_HasMMX()"); - ret = SDL_Has3DNow(); + SDL_Has3DNow(); SDLTest_AssertPass("SDL_Has3DNow()"); - ret = SDL_HasSSE(); + SDL_HasSSE(); SDLTest_AssertPass("SDL_HasSSE()"); - ret = SDL_HasSSE2(); + SDL_HasSSE2(); SDLTest_AssertPass("SDL_HasSSE2()"); - ret = SDL_HasSSE3(); + SDL_HasSSE3(); SDLTest_AssertPass("SDL_HasSSE3()"); - ret = SDL_HasSSE41(); + SDL_HasSSE41(); SDLTest_AssertPass("SDL_HasSSE41()"); - ret = SDL_HasSSE42(); + SDL_HasSSE42(); SDLTest_AssertPass("SDL_HasSSE42()"); - ret = SDL_HasAVX(); + SDL_HasAVX(); SDLTest_AssertPass("SDL_HasAVX()"); return TEST_COMPLETED; @@ -203,7 +198,7 @@ int platform_testHasFunctions (void *arg) /* ! * \brief Tests SDL_GetVersion * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetVersion + * http://wiki.libsdl.org/SDL_GetVersion */ int platform_testGetVersion(void *arg) { @@ -273,9 +268,9 @@ int platform_testDefaultInit(void *arg) /* ! * \brief Tests SDL_Get/Set/ClearError * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetError - * http://wiki.libsdl.org/moin.cgi/SDL_SetError - * http://wiki.libsdl.org/moin.cgi/SDL_ClearError + * http://wiki.libsdl.org/SDL_GetError + * http://wiki.libsdl.org/SDL_SetError + * http://wiki.libsdl.org/SDL_ClearError */ int platform_testGetSetClearError(void *arg) { @@ -327,7 +322,7 @@ int platform_testGetSetClearError(void *arg) /* ! * \brief Tests SDL_SetError with empty input * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetError + * http://wiki.libsdl.org/SDL_SetError */ int platform_testSetErrorEmptyInput(void *arg) { @@ -365,7 +360,7 @@ int platform_testSetErrorEmptyInput(void *arg) /* ! * \brief Tests SDL_SetError with invalid input * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetError + * http://wiki.libsdl.org/SDL_SetError */ int platform_testSetErrorInvalidInput(void *arg) { @@ -389,7 +384,7 @@ int platform_testSetErrorInvalidInput(void *arg) if (lastError != NULL) { len = SDL_strlen(lastError); - SDLTest_AssertCheck(len == 0, + SDLTest_AssertCheck(len == 0 || SDL_strcmp(lastError, "(null)") == 0, "SDL_GetError(): expected message len 0, was len: %i", (int) len); } @@ -409,7 +404,7 @@ int platform_testSetErrorInvalidInput(void *arg) if (lastError != NULL) { len = SDL_strlen(lastError); - SDLTest_AssertCheck(len == 0, + SDLTest_AssertCheck(len == 0 || SDL_strcmp( lastError, "(null)" ) == 0, "SDL_GetError(): expected message len 0, was len: %i", (int) len); } @@ -448,7 +443,7 @@ int platform_testSetErrorInvalidInput(void *arg) /* ! * \brief Tests SDL_GetPowerInfo * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetPowerInfo + * http://wiki.libsdl.org/SDL_GetPowerInfo */ int platform_testGetPowerInfo(void *arg) { diff --git a/Engine/lib/sdl/test/testautomation_rect.c b/Engine/lib/sdl/test/testautomation_rect.c index abf19f593..26f03e9bb 100644 --- a/Engine/lib/sdl/test/testautomation_rect.c +++ b/Engine/lib/sdl/test/testautomation_rect.c @@ -43,7 +43,7 @@ void _validateIntersectRectAndLineResults( * \brief Tests SDL_IntersectRectAndLine() clipping cases * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRectAndLine + * http://wiki.libsdl.org/SDL_IntersectRectAndLine */ int rect_testIntersectRectAndLine (void *arg) @@ -114,7 +114,7 @@ rect_testIntersectRectAndLine (void *arg) * \brief Tests SDL_IntersectRectAndLine() non-clipping case line inside * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRectAndLine + * http://wiki.libsdl.org/SDL_IntersectRectAndLine */ int rect_testIntersectRectAndLineInside (void *arg) @@ -181,7 +181,7 @@ rect_testIntersectRectAndLineInside (void *arg) * \brief Tests SDL_IntersectRectAndLine() non-clipping cases outside * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRectAndLine + * http://wiki.libsdl.org/SDL_IntersectRectAndLine */ int rect_testIntersectRectAndLineOutside (void *arg) @@ -236,7 +236,7 @@ rect_testIntersectRectAndLineOutside (void *arg) * \brief Tests SDL_IntersectRectAndLine() with empty rectangle * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRectAndLine + * http://wiki.libsdl.org/SDL_IntersectRectAndLine */ int rect_testIntersectRectAndLineEmpty (void *arg) @@ -271,7 +271,7 @@ rect_testIntersectRectAndLineEmpty (void *arg) * \brief Negative tests against SDL_IntersectRectAndLine() with invalid parameters * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRectAndLine + * http://wiki.libsdl.org/SDL_IntersectRectAndLine */ int rect_testIntersectRectAndLineParam (void *arg) @@ -412,7 +412,7 @@ void _validateRectEqualsResults( * \brief Tests SDL_IntersectRect() with B fully inside A * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect + * http://wiki.libsdl.org/SDL_IntersectRect */ int rect_testIntersectRectInside (void *arg) { @@ -440,7 +440,7 @@ int rect_testIntersectRectInside (void *arg) * \brief Tests SDL_IntersectRect() with B fully outside A * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect + * http://wiki.libsdl.org/SDL_IntersectRect */ int rect_testIntersectRectOutside (void *arg) { @@ -468,7 +468,7 @@ int rect_testIntersectRectOutside (void *arg) * \brief Tests SDL_IntersectRect() with B partially intersecting A * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect + * http://wiki.libsdl.org/SDL_IntersectRect */ int rect_testIntersectRectPartial (void *arg) { @@ -557,7 +557,7 @@ int rect_testIntersectRectPartial (void *arg) * \brief Tests SDL_IntersectRect() with 1x1 pixel sized rectangles * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect + * http://wiki.libsdl.org/SDL_IntersectRect */ int rect_testIntersectRectPoint (void *arg) { @@ -604,7 +604,7 @@ int rect_testIntersectRectPoint (void *arg) * \brief Tests SDL_IntersectRect() with empty rectangles * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect + * http://wiki.libsdl.org/SDL_IntersectRect */ int rect_testIntersectRectEmpty (void *arg) { @@ -676,7 +676,7 @@ int rect_testIntersectRectEmpty (void *arg) * \brief Negative tests against SDL_IntersectRect() with invalid parameters * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect + * http://wiki.libsdl.org/SDL_IntersectRect */ int rect_testIntersectRectParam(void *arg) { @@ -706,7 +706,7 @@ int rect_testIntersectRectParam(void *arg) * \brief Tests SDL_HasIntersection() with B fully inside A * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection + * http://wiki.libsdl.org/SDL_HasIntersection */ int rect_testHasIntersectionInside (void *arg) { @@ -733,7 +733,7 @@ int rect_testHasIntersectionInside (void *arg) * \brief Tests SDL_HasIntersection() with B fully outside A * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection + * http://wiki.libsdl.org/SDL_HasIntersection */ int rect_testHasIntersectionOutside (void *arg) { @@ -760,7 +760,7 @@ int rect_testHasIntersectionOutside (void *arg) * \brief Tests SDL_HasIntersection() with B partially intersecting A * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection + * http://wiki.libsdl.org/SDL_HasIntersection */ int rect_testHasIntersectionPartial (void *arg) { @@ -827,7 +827,7 @@ int rect_testHasIntersectionPartial (void *arg) * \brief Tests SDL_HasIntersection() with 1x1 pixel sized rectangles * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection + * http://wiki.libsdl.org/SDL_HasIntersection */ int rect_testHasIntersectionPoint (void *arg) { @@ -873,7 +873,7 @@ int rect_testHasIntersectionPoint (void *arg) * \brief Tests SDL_HasIntersection() with empty rectangles * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection + * http://wiki.libsdl.org/SDL_HasIntersection */ int rect_testHasIntersectionEmpty (void *arg) { @@ -931,7 +931,7 @@ int rect_testHasIntersectionEmpty (void *arg) * \brief Negative tests against SDL_HasIntersection() with invalid parameters * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection + * http://wiki.libsdl.org/SDL_HasIntersection */ int rect_testHasIntersectionParam(void *arg) { @@ -954,7 +954,7 @@ int rect_testHasIntersectionParam(void *arg) * \brief Test SDL_EnclosePoints() without clipping * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_EnclosePoints + * http://wiki.libsdl.org/SDL_EnclosePoints */ int rect_testEnclosePoints(void *arg) { @@ -1024,7 +1024,7 @@ int rect_testEnclosePoints(void *arg) * \brief Test SDL_EnclosePoints() with repeated input points * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_EnclosePoints + * http://wiki.libsdl.org/SDL_EnclosePoints */ int rect_testEnclosePointsRepeatedInput(void *arg) { @@ -1100,7 +1100,7 @@ int rect_testEnclosePointsRepeatedInput(void *arg) * \brief Test SDL_EnclosePoints() with clipping * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_EnclosePoints + * http://wiki.libsdl.org/SDL_EnclosePoints */ int rect_testEnclosePointsWithClipping(void *arg) { @@ -1199,7 +1199,7 @@ int rect_testEnclosePointsWithClipping(void *arg) * \brief Negative tests against SDL_EnclosePoints() with invalid parameters * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_EnclosePoints + * http://wiki.libsdl.org/SDL_EnclosePoints */ int rect_testEnclosePointsParam(void *arg) { @@ -1227,7 +1227,7 @@ int rect_testEnclosePointsParam(void *arg) * \brief Tests SDL_UnionRect() where rect B is outside rect A * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_UnionRect + * http://wiki.libsdl.org/SDL_UnionRect */ int rect_testUnionRectOutside(void *arg) { @@ -1298,7 +1298,7 @@ int rect_testUnionRectOutside(void *arg) * \brief Tests SDL_UnionRect() where rect A or rect B are empty * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_UnionRect + * http://wiki.libsdl.org/SDL_UnionRect */ int rect_testUnionRectEmpty(void *arg) { @@ -1363,7 +1363,7 @@ int rect_testUnionRectEmpty(void *arg) * \brief Tests SDL_UnionRect() where rect B is inside rect A * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_UnionRect + * http://wiki.libsdl.org/SDL_UnionRect */ int rect_testUnionRectInside(void *arg) { @@ -1427,7 +1427,7 @@ int rect_testUnionRectInside(void *arg) * \brief Negative tests against SDL_UnionRect() with invalid parameters * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_UnionRect + * http://wiki.libsdl.org/SDL_UnionRect */ int rect_testUnionRectParam(void *arg) { @@ -1455,7 +1455,7 @@ int rect_testUnionRectParam(void *arg) * \brief Tests SDL_RectEmpty() with various inputs * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RectEmpty + * http://wiki.libsdl.org/SDL_RectEmpty */ int rect_testRectEmpty(void *arg) { @@ -1498,7 +1498,7 @@ int rect_testRectEmpty(void *arg) * \brief Negative tests against SDL_RectEmpty() with invalid parameters * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RectEmpty + * http://wiki.libsdl.org/SDL_RectEmpty */ int rect_testRectEmptyParam(void *arg) { @@ -1515,7 +1515,7 @@ int rect_testRectEmptyParam(void *arg) * \brief Tests SDL_RectEquals() with various inputs * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RectEquals + * http://wiki.libsdl.org/SDL_RectEquals */ int rect_testRectEquals(void *arg) { @@ -1545,7 +1545,7 @@ int rect_testRectEquals(void *arg) * \brief Negative tests against SDL_RectEquals() with invalid parameters * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RectEquals + * http://wiki.libsdl.org/SDL_RectEquals */ int rect_testRectEqualsParam(void *arg) { @@ -1678,7 +1678,7 @@ static const SDLTest_TestCaseReference rectTest29 = * \brief Sequence of Rect test cases; functions that handle simple rectangles including overlaps and merges. * * \sa - * http://wiki.libsdl.org/moin.cgi/CategoryRect + * http://wiki.libsdl.org/CategoryRect */ static const SDLTest_TestCaseReference *rectTests[] = { &rectTest1, &rectTest2, &rectTest3, &rectTest4, &rectTest5, &rectTest6, &rectTest7, &rectTest8, &rectTest9, &rectTest10, &rectTest11, &rectTest12, &rectTest13, &rectTest14, diff --git a/Engine/lib/sdl/test/testautomation_render.c b/Engine/lib/sdl/test/testautomation_render.c index 5a1bc9b8c..0117334a2 100644 --- a/Engine/lib/sdl/test/testautomation_render.c +++ b/Engine/lib/sdl/test/testautomation_render.c @@ -83,7 +83,7 @@ void CleanupDestroyRenderer(void *arg) * @brief Tests call to SDL_GetNumRenderDrivers * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetNumRenderDrivers + * http://wiki.libsdl.org/SDL_GetNumRenderDrivers */ int render_testGetNumRenderDrivers(void *arg) @@ -99,9 +99,9 @@ render_testGetNumRenderDrivers(void *arg) * @brief Tests the SDL primitives for rendering. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawColor - * http://wiki.libsdl.org/moin.cgi/SDL_RenderFillRect - * http://wiki.libsdl.org/moin.cgi/SDL_RenderDrawLine + * http://wiki.libsdl.org/SDL_SetRenderDrawColor + * http://wiki.libsdl.org/SDL_RenderFillRect + * http://wiki.libsdl.org/SDL_RenderDrawLine * */ int render_testPrimitives (void *arg) @@ -187,14 +187,14 @@ int render_testPrimitives (void *arg) ret = SDL_RenderDrawLine(renderer, 79, 59, 50, 30 ); SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderDrawLine, expected: 0, got: %i", ret); - - /* Make current */ - SDL_RenderPresent(renderer); - + /* See if it's the same. */ referenceSurface = SDLTest_ImagePrimitives(); _compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE ); + /* Make current */ + SDL_RenderPresent(renderer); + /* Clean up. */ SDL_FreeSurface(referenceSurface); referenceSurface = NULL; @@ -206,9 +206,9 @@ int render_testPrimitives (void *arg) * @brief Tests the SDL primitives with alpha for rendering. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawColor - * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawBlendMode - * http://wiki.libsdl.org/moin.cgi/SDL_RenderFillRect + * http://wiki.libsdl.org/SDL_SetRenderDrawColor + * http://wiki.libsdl.org/SDL_SetRenderDrawBlendMode + * http://wiki.libsdl.org/SDL_RenderFillRect */ int render_testPrimitivesBlend (void *arg) { @@ -335,13 +335,13 @@ int render_testPrimitivesBlend (void *arg) SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetRenderDrawBlendMode, expected: 0, got: %i", checkFailCount2); SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_RenderDrawPoint, expected: 0, got: %i", checkFailCount3); - /* Make current */ - SDL_RenderPresent(renderer); - /* See if it's the same. */ referenceSurface = SDLTest_ImagePrimitivesBlend(); _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED ); + /* Make current */ + SDL_RenderPresent(renderer); + /* Clean up. */ SDL_FreeSurface(referenceSurface); referenceSurface = NULL; @@ -355,8 +355,8 @@ int render_testPrimitivesBlend (void *arg) * @brief Tests some blitting routines. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RenderCopy - * http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture + * http://wiki.libsdl.org/SDL_RenderCopy + * http://wiki.libsdl.org/SDL_DestroyTexture */ int render_testBlit(void *arg) @@ -404,13 +404,13 @@ render_testBlit(void *arg) } SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_RenderCopy, expected: 0, got: %i", checkFailCount1); - /* Make current */ - SDL_RenderPresent(renderer); - /* See if it's the same */ referenceSurface = SDLTest_ImageBlit(); _compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE ); + /* Make current */ + SDL_RenderPresent(renderer); + /* Clean up. */ SDL_DestroyTexture( tface ); SDL_FreeSurface(referenceSurface); @@ -424,9 +424,9 @@ render_testBlit(void *arg) * @brief Blits doing color tests. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureColorMod - * http://wiki.libsdl.org/moin.cgi/SDL_RenderCopy - * http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture + * http://wiki.libsdl.org/SDL_SetTextureColorMod + * http://wiki.libsdl.org/SDL_RenderCopy + * http://wiki.libsdl.org/SDL_DestroyTexture */ int render_testBlitColor (void *arg) @@ -478,13 +478,13 @@ render_testBlitColor (void *arg) SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetTextureColorMod, expected: 0, got: %i", checkFailCount1); SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_RenderCopy, expected: 0, got: %i", checkFailCount2); - /* Make current */ - SDL_RenderPresent(renderer); - /* See if it's the same. */ referenceSurface = SDLTest_ImageBlitColor(); _compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE ); + /* Make current */ + SDL_RenderPresent(renderer); + /* Clean up. */ SDL_DestroyTexture( tface ); SDL_FreeSurface(referenceSurface); @@ -498,9 +498,9 @@ render_testBlitColor (void *arg) * @brief Tests blitting with alpha. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureAlphaMod - * http://wiki.libsdl.org/moin.cgi/SDL_RenderCopy - * http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture + * http://wiki.libsdl.org/SDL_SetTextureAlphaMod + * http://wiki.libsdl.org/SDL_RenderCopy + * http://wiki.libsdl.org/SDL_DestroyTexture */ int render_testBlitAlpha (void *arg) @@ -555,13 +555,13 @@ render_testBlitAlpha (void *arg) SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetTextureAlphaMod, expected: 0, got: %i", checkFailCount1); SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_RenderCopy, expected: 0, got: %i", checkFailCount2); - /* Make current */ - SDL_RenderPresent(renderer); - /* See if it's the same. */ referenceSurface = SDLTest_ImageBlitAlpha(); _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED ); + /* Make current */ + SDL_RenderPresent(renderer); + /* Clean up. */ SDL_DestroyTexture( tface ); SDL_FreeSurface(referenceSurface); @@ -576,8 +576,8 @@ render_testBlitAlpha (void *arg) * @brief Tests a blend mode. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureBlendMode - * http://wiki.libsdl.org/moin.cgi/SDL_RenderCopy + * http://wiki.libsdl.org/SDL_SetTextureBlendMode + * http://wiki.libsdl.org/SDL_RenderCopy */ static void _testBlitBlendMode( SDL_Texture * tface, int mode ) @@ -626,10 +626,10 @@ _testBlitBlendMode( SDL_Texture * tface, int mode ) * @brief Tests some more blitting routines. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureColorMod - * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureAlphaMod - * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureBlendMode - * http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture + * http://wiki.libsdl.org/SDL_SetTextureColorMod + * http://wiki.libsdl.org/SDL_SetTextureAlphaMod + * http://wiki.libsdl.org/SDL_SetTextureBlendMode + * http://wiki.libsdl.org/SDL_DestroyTexture */ int render_testBlitBlend (void *arg) @@ -674,9 +674,10 @@ render_testBlitBlend (void *arg) _testBlitBlendMode( tface, SDL_BLENDMODE_NONE ); referenceSurface = SDLTest_ImageBlitBlendNone(); - /* Make current and compare */ - SDL_RenderPresent(renderer); + /* Compare, then Present */ _compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE ); + SDL_RenderPresent(renderer); + SDL_FreeSurface(referenceSurface); referenceSurface = NULL; @@ -684,9 +685,10 @@ render_testBlitBlend (void *arg) _testBlitBlendMode( tface, SDL_BLENDMODE_BLEND ); referenceSurface = SDLTest_ImageBlitBlend(); - /* Make current and compare */ - SDL_RenderPresent(renderer); + /* Compare, then Present */ _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED ); + SDL_RenderPresent(renderer); + SDL_FreeSurface(referenceSurface); referenceSurface = NULL; @@ -694,9 +696,10 @@ render_testBlitBlend (void *arg) _testBlitBlendMode( tface, SDL_BLENDMODE_ADD ); referenceSurface = SDLTest_ImageBlitBlendAdd(); - /* Make current and compare */ - SDL_RenderPresent(renderer); + /* Compare, then Present */ _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED ); + SDL_RenderPresent(renderer); + SDL_FreeSurface(referenceSurface); referenceSurface = NULL; @@ -704,9 +707,10 @@ render_testBlitBlend (void *arg) _testBlitBlendMode( tface, SDL_BLENDMODE_MOD); referenceSurface = SDLTest_ImageBlitBlendMod(); - /* Make current and compare */ - SDL_RenderPresent(renderer); + /* Compare, then Present */ _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED ); + SDL_RenderPresent(renderer); + SDL_FreeSurface(referenceSurface); referenceSurface = NULL; @@ -753,12 +757,13 @@ render_testBlitBlend (void *arg) /* Clean up. */ SDL_DestroyTexture( tface ); - /* Make current */ - SDL_RenderPresent(renderer); - /* Check to see if final image matches. */ referenceSurface = SDLTest_ImageBlitBlendAll(); _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED); + + /* Make current */ + SDL_RenderPresent(renderer); + SDL_FreeSurface(referenceSurface); referenceSurface = NULL; @@ -779,8 +784,8 @@ _isSupported( int code ) * @brief Test to see if we can vary the draw color. Helper function. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawColor - * http://wiki.libsdl.org/moin.cgi/SDL_GetRenderDrawColor + * http://wiki.libsdl.org/SDL_SetRenderDrawColor + * http://wiki.libsdl.org/SDL_GetRenderDrawColor */ static int _hasDrawColor (void) @@ -817,8 +822,8 @@ _hasDrawColor (void) * @brief Test to see if we can vary the blend mode. Helper function. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawBlendMode - * http://wiki.libsdl.org/moin.cgi/SDL_GetRenderDrawBlendMode + * http://wiki.libsdl.org/SDL_SetRenderDrawBlendMode + * http://wiki.libsdl.org/SDL_GetRenderDrawBlendMode */ static int _hasBlendModes (void) @@ -874,7 +879,7 @@ _hasBlendModes (void) * @brief Loads the test image 'Face' as texture. Helper function. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_CreateTextureFromSurface + * http://wiki.libsdl.org/SDL_CreateTextureFromSurface */ static SDL_Texture * _loadTestFace(void) @@ -902,9 +907,9 @@ _loadTestFace(void) * @brief Test to see if can set texture color mode. Helper function. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureColorMod - * http://wiki.libsdl.org/moin.cgi/SDL_GetTextureColorMod - * http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture + * http://wiki.libsdl.org/SDL_SetTextureColorMod + * http://wiki.libsdl.org/SDL_GetTextureColorMod + * http://wiki.libsdl.org/SDL_DestroyTexture */ static int _hasTexColor (void) @@ -942,9 +947,9 @@ _hasTexColor (void) * @brief Test to see if we can vary the alpha of the texture. Helper function. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureAlphaMod - * http://wiki.libsdl.org/moin.cgi/SDL_GetTextureAlphaMod - * http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture + * http://wiki.libsdl.org/SDL_SetTextureAlphaMod + * http://wiki.libsdl.org/SDL_GetTextureAlphaMod + * http://wiki.libsdl.org/SDL_DestroyTexture */ static int _hasTexAlpha(void) @@ -984,9 +989,9 @@ _hasTexAlpha(void) * @param s Image to compare against. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RenderReadPixels - * http://wiki.libsdl.org/moin.cgi/SDL_CreateRGBSurfaceFrom - * http://wiki.libsdl.org/moin.cgi/SDL_FreeSurface + * http://wiki.libsdl.org/SDL_RenderReadPixels + * http://wiki.libsdl.org/SDL_CreateRGBSurfaceFrom + * http://wiki.libsdl.org/SDL_FreeSurface */ static void _compare(SDL_Surface *referenceSurface, int allowable_error) @@ -1027,10 +1032,10 @@ _compare(SDL_Surface *referenceSurface, int allowable_error) * @brief Clears the screen. Helper function. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawColor - * http://wiki.libsdl.org/moin.cgi/SDL_RenderClear - * http://wiki.libsdl.org/moin.cgi/SDL_RenderPresent - * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawBlendMode + * http://wiki.libsdl.org/SDL_SetRenderDrawColor + * http://wiki.libsdl.org/SDL_RenderClear + * http://wiki.libsdl.org/SDL_RenderPresent + * http://wiki.libsdl.org/SDL_SetRenderDrawBlendMode */ static int _clearScreen(void) diff --git a/Engine/lib/sdl/test/testautomation_rwops.c b/Engine/lib/sdl/test/testautomation_rwops.c index b5d5b1d32..a7d3c3272 100644 --- a/Engine/lib/sdl/test/testautomation_rwops.c +++ b/Engine/lib/sdl/test/testautomation_rwops.c @@ -88,8 +88,8 @@ RWopsTearDown(void *arg) * @brief Makes sure parameters work properly. Local helper function. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWseek - * http://wiki.libsdl.org/moin.cgi/SDL_RWread + * http://wiki.libsdl.org/SDL_RWseek + * http://wiki.libsdl.org/SDL_RWread */ void _testGenericRWopsValidations(SDL_RWops *rw, int write) @@ -168,7 +168,7 @@ _testGenericRWopsValidations(SDL_RWops *rw, int write) /* ! * Negative test for SDL_RWFromFile parameters * - * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile + * \sa http://wiki.libsdl.org/SDL_RWFromFile * */ int @@ -215,8 +215,8 @@ rwops_testParamNegative (void) /** * @brief Tests opening from memory. * - * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWFromMem - * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWClose + * \sa http://wiki.libsdl.org/SDL_RWFromMem + * \sa http://wiki.libsdl.org/SDL_RWClose */ int rwops_testMem (void) @@ -255,8 +255,8 @@ rwops_testMem (void) * @brief Tests opening from memory. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromConstMem - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose + * http://wiki.libsdl.org/SDL_RWFromConstMem + * http://wiki.libsdl.org/SDL_RWClose */ int rwops_testConstMem (void) @@ -291,8 +291,8 @@ rwops_testConstMem (void) * @brief Tests reading from file. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose + * http://wiki.libsdl.org/SDL_RWFromFile + * http://wiki.libsdl.org/SDL_RWClose */ int rwops_testFileRead(void) @@ -338,8 +338,8 @@ rwops_testFileRead(void) * @brief Tests writing from file. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose + * http://wiki.libsdl.org/SDL_RWFromFile + * http://wiki.libsdl.org/SDL_RWClose */ int rwops_testFileWrite(void) @@ -386,8 +386,8 @@ rwops_testFileWrite(void) * @brief Tests reading from file handle * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFP - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose + * http://wiki.libsdl.org/SDL_RWFromFP + * http://wiki.libsdl.org/SDL_RWClose * */ int @@ -436,8 +436,8 @@ rwops_testFPRead(void) * @brief Tests writing to file handle * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFP - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose + * http://wiki.libsdl.org/SDL_RWFromFP + * http://wiki.libsdl.org/SDL_RWClose * */ int @@ -484,8 +484,8 @@ rwops_testFPWrite(void) /** * @brief Tests alloc and free RW context. * - * \sa http://wiki.libsdl.org/moin.cgi/SDL_AllocRW - * \sa http://wiki.libsdl.org/moin.cgi/SDL_FreeRW + * \sa http://wiki.libsdl.org/SDL_AllocRW + * \sa http://wiki.libsdl.org/SDL_FreeRW */ int rwops_testAllocFree (void) @@ -511,8 +511,8 @@ rwops_testAllocFree (void) /** * @brief Compare memory and file reads * - * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWFromMem - * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile + * \sa http://wiki.libsdl.org/SDL_RWFromMem + * \sa http://wiki.libsdl.org/SDL_RWFromFile */ int rwops_testCompareRWFromMemWithRWFromFile(void) @@ -578,10 +578,10 @@ rwops_testCompareRWFromMemWithRWFromFile(void) * @brief Tests writing and reading from file using endian aware functions. * * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose - * http://wiki.libsdl.org/moin.cgi/SDL_ReadBE16 - * http://wiki.libsdl.org/moin.cgi/SDL_WriteBE16 + * http://wiki.libsdl.org/SDL_RWFromFile + * http://wiki.libsdl.org/SDL_RWClose + * http://wiki.libsdl.org/SDL_ReadBE16 + * http://wiki.libsdl.org/SDL_WriteBE16 */ int rwops_testFileWriteReadEndian(void) diff --git a/Engine/lib/sdl/test/testautomation_sdltest.c b/Engine/lib/sdl/test/testautomation_sdltest.c index 339b7c168..809664dc3 100644 --- a/Engine/lib/sdl/test/testautomation_sdltest.c +++ b/Engine/lib/sdl/test/testautomation_sdltest.c @@ -89,7 +89,6 @@ int sdltest_randomNumber(void *arg) { Sint64 result; - Uint64 uresult; double dresult; Uint64 umax; Sint64 min, max; @@ -127,7 +126,7 @@ sdltest_randomNumber(void *arg) SDLTest_AssertPass("Call to SDLTest_RandomSint32"); SDLTest_AssertCheck(result >= min && result <= max, "Verify result value, expected: [%"SDL_PRIs64",%"SDL_PRIs64"], got: %"SDL_PRIs64, min, max, result); - uresult = SDLTest_RandomUint64(); + SDLTest_RandomUint64(); SDLTest_AssertPass("Call to SDLTest_RandomUint64"); result = SDLTest_RandomSint64(); @@ -1132,7 +1131,7 @@ sdltest_randomAsciiString(void *arg) SDLTest_AssertCheck(len >= 1 && len <= 255, "Validate that result length; expected: len=[1,255], got: %d", (int) len); nonAsciiCharacters = 0; for (i=0; i= 1 && len <= targetLen, "Validate that result length; expected: len=[1,%d], got: %d", (int) targetLen, (int) len); nonAsciiCharacters = 0; for (i=0; i F */ - _setAndCheckWindowGrabState(window, SDL_FALSE); + _setAndCheckWindowMouseGrabState(window, SDL_FALSE); + _setAndCheckWindowKeyboardGrabState(window, SDL_FALSE); + SDLTest_AssertCheck(SDL_GetGrabbedWindow() == NULL, + "Expected NULL grabbed window"); /* F --> T */ - _setAndCheckWindowGrabState(window, SDL_TRUE); + _setAndCheckWindowMouseGrabState(window, SDL_TRUE); + _setAndCheckWindowKeyboardGrabState(window, SDL_TRUE); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); /* T --> T */ - _setAndCheckWindowGrabState(window, SDL_TRUE); + _setAndCheckWindowKeyboardGrabState(window, SDL_TRUE); + _setAndCheckWindowMouseGrabState(window, SDL_TRUE); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); - /* T --> F */ - _setAndCheckWindowGrabState(window, SDL_FALSE); + /* M: T --> F */ + /* K: T --> T */ + _setAndCheckWindowKeyboardGrabState(window, SDL_TRUE); + _setAndCheckWindowMouseGrabState(window, SDL_FALSE); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + + /* M: F --> T */ + /* K: T --> F */ + _setAndCheckWindowMouseGrabState(window, SDL_TRUE); + _setAndCheckWindowKeyboardGrabState(window, SDL_FALSE); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + + /* M: T --> F */ + /* K: F --> F */ + _setAndCheckWindowMouseGrabState(window, SDL_FALSE); + _setAndCheckWindowKeyboardGrabState(window, SDL_FALSE); + SDLTest_AssertCheck(!SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_FALSE"); + SDLTest_AssertCheck(SDL_GetGrabbedWindow() == NULL, + "Expected NULL grabbed window"); + + /* Using the older SDL_SetWindowGrab API should only grab mouse by default */ + SDL_SetWindowGrab(window, SDL_TRUE); + SDLTest_AssertPass("Call to SDL_SetWindowGrab(SDL_TRUE)"); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + SDLTest_AssertCheck(SDL_GetWindowMouseGrab(window), + "SDL_GetWindowMouseGrab() should return SDL_TRUE"); + SDLTest_AssertCheck(!SDL_GetWindowKeyboardGrab(window), + "SDL_GetWindowKeyboardGrab() should return SDL_FALSE"); + SDL_SetWindowGrab(window, SDL_FALSE); + SDLTest_AssertCheck(!SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_FALSE"); + SDLTest_AssertCheck(!SDL_GetWindowMouseGrab(window), + "SDL_GetWindowMouseGrab() should return SDL_FALSE"); + SDLTest_AssertCheck(!SDL_GetWindowKeyboardGrab(window), + "SDL_GetWindowKeyboardGrab() should return SDL_FALSE"); + + /* Now test with SDL_HINT_GRAB_KEYBOARD set. We should get keyboard grab now. */ + SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); + SDL_SetWindowGrab(window, SDL_TRUE); + SDLTest_AssertPass("Call to SDL_SetWindowGrab(SDL_TRUE)"); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + SDLTest_AssertCheck(SDL_GetWindowMouseGrab(window), + "SDL_GetWindowMouseGrab() should return SDL_TRUE"); + SDLTest_AssertCheck(SDL_GetWindowKeyboardGrab(window), + "SDL_GetWindowKeyboardGrab() should return SDL_TRUE"); + SDL_SetWindowGrab(window, SDL_FALSE); + SDLTest_AssertCheck(!SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_FALSE"); + SDLTest_AssertCheck(!SDL_GetWindowMouseGrab(window), + "SDL_GetWindowMouseGrab() should return SDL_FALSE"); + SDLTest_AssertCheck(!SDL_GetWindowKeyboardGrab(window), + "SDL_GetWindowKeyboardGrab() should return SDL_FALSE"); /* Negative tests */ - dummyState = SDL_GetWindowGrab(NULL); + SDL_GetWindowGrab(NULL); SDLTest_AssertPass("Call to SDL_GetWindowGrab(window=NULL)"); _checkInvalidWindowError(); + SDL_GetWindowKeyboardGrab(NULL); + SDLTest_AssertPass("Call to SDL_GetWindowKeyboardGrab(window=NULL)"); + _checkInvalidWindowError(); + SDL_SetWindowGrab(NULL, SDL_FALSE); SDLTest_AssertPass("Call to SDL_SetWindowGrab(window=NULL,SDL_FALSE)"); _checkInvalidWindowError(); - SDL_SetWindowGrab(NULL, SDL_TRUE); - SDLTest_AssertPass("Call to SDL_SetWindowGrab(window=NULL,SDL_FALSE)"); + SDL_SetWindowKeyboardGrab(NULL, SDL_FALSE); + SDLTest_AssertPass("Call to SDL_SetWindowKeyboardGrab(window=NULL,SDL_FALSE)"); _checkInvalidWindowError(); - /* State should still be F */ - desiredState = SDL_FALSE; - currentState = SDL_GetWindowGrab(window); - SDLTest_AssertPass("Call to SDL_GetWindowGrab()"); - SDLTest_AssertCheck( - currentState == desiredState, - "Validate returned state; expected: %s, got: %s", - (desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE", - (currentState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE"); + SDL_SetWindowGrab(NULL, SDL_TRUE); + SDLTest_AssertPass("Call to SDL_SetWindowGrab(window=NULL,SDL_TRUE)"); + _checkInvalidWindowError(); + + SDL_SetWindowKeyboardGrab(NULL, SDL_TRUE); + SDLTest_AssertPass("Call to SDL_SetWindowKeyboardGrab(window=NULL,SDL_TRUE)"); + _checkInvalidWindowError(); /* Restore state */ - _setAndCheckWindowGrabState(window, originalState); + _setAndCheckWindowMouseGrabState(window, originalMouseState); + _setAndCheckWindowKeyboardGrabState(window, originalKeyboardState); /* Clean up */ _destroyVideoSuiteTestWindow(window); @@ -836,8 +964,8 @@ video_getSetWindowGrab(void *arg) /** * @brief Tests call to SDL_GetWindowID and SDL_GetWindowFromID * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowID - * @sa http://wiki.libsdl.org/moin.fcg/SDL_SetWindowFromID + * @sa http://wiki.libsdl.org/SDL_GetWindowID + * @sa http://wiki.libsdl.org/SDL_SetWindowFromID */ int video_getWindowId(void *arg) @@ -892,7 +1020,7 @@ video_getWindowId(void *arg) /** * @brief Tests call to SDL_GetWindowPixelFormat * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowPixelFormat + * @sa http://wiki.libsdl.org/SDL_GetWindowPixelFormat */ int video_getWindowPixelFormat(void *arg) @@ -926,8 +1054,8 @@ video_getWindowPixelFormat(void *arg) /** * @brief Tests call to SDL_GetWindowPosition and SDL_SetWindowPosition * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowPosition - * @sa http://wiki.libsdl.org/moin.fcg/SDL_SetWindowPosition + * @sa http://wiki.libsdl.org/SDL_GetWindowPosition + * @sa http://wiki.libsdl.org/SDL_SetWindowPosition */ int video_getSetWindowPosition(void *arg) @@ -1069,8 +1197,8 @@ void _checkInvalidParameterError() /** * @brief Tests call to SDL_GetWindowSize and SDL_SetWindowSize * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowSize - * @sa http://wiki.libsdl.org/moin.fcg/SDL_SetWindowSize + * @sa http://wiki.libsdl.org/SDL_GetWindowSize + * @sa http://wiki.libsdl.org/SDL_SetWindowSize */ int video_getSetWindowSize(void *arg) @@ -1508,8 +1636,8 @@ video_getSetWindowMaximumSize(void *arg) /** * @brief Tests call to SDL_SetWindowData and SDL_GetWindowData * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_SetWindowData - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowData + * @sa http://wiki.libsdl.org/SDL_SetWindowData + * @sa http://wiki.libsdl.org/SDL_GetWindowData */ int video_getSetWindowData(void *arg) diff --git a/Engine/lib/sdl/test/testbounds.c b/Engine/lib/sdl/test/testbounds.c index e9017e5e6..23f981777 100644 --- a/Engine/lib/sdl/test/testbounds.c +++ b/Engine/lib/sdl/test/testbounds.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testcustomcursor.c b/Engine/lib/sdl/test/testcustomcursor.c index 3881435ad..2feee81a2 100644 --- a/Engine/lib/sdl/test/testcustomcursor.c +++ b/Engine/lib/sdl/test/testcustomcursor.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -128,7 +128,7 @@ init_system_cursor(const char *image[]) } } } - sscanf(image[4+row], "%d,%d", &hot_x, &hot_y); + SDL_sscanf(image[4+row], "%d,%d", &hot_x, &hot_y); return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y); } diff --git a/Engine/lib/sdl/test/testdisplayinfo.c b/Engine/lib/sdl/test/testdisplayinfo.c index 2a8cce1e0..297632c04 100644 --- a/Engine/lib/sdl/test/testdisplayinfo.c +++ b/Engine/lib/sdl/test/testdisplayinfo.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testdraw2.c b/Engine/lib/sdl/test/testdraw2.c index 865b55fbf..0df5ba3ed 100644 --- a/Engine/lib/sdl/test/testdraw2.c +++ b/Engine/lib/sdl/test/testdraw2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,6 +32,8 @@ static int cycle_direction = 1; static int current_alpha = 255; static int current_color = 255; static SDL_BlendMode blendMode = SDL_BLENDMODE_NONE; +static Uint32 next_fps_check, frames; +static const Uint32 fps_check_delay = 5000; int done; @@ -178,6 +180,7 @@ DrawRects(SDL_Renderer * renderer) void loop() { + Uint32 now; int i; SDL_Event event; @@ -203,13 +206,23 @@ loop() emscripten_cancel_main_loop(); } #endif + frames++; + now = SDL_GetTicks(); + if (SDL_TICKS_PASSED(now, next_fps_check)) { + /* Print out some timing information */ + const Uint32 then = next_fps_check - fps_check_delay; + const double fps = ((double) frames * 1000) / (now - then); + SDL_Log("%2.2f frames per second\n", fps); + next_fps_check = now + fps_check_delay; + frames = 0; + } + } int main(int argc, char *argv[]) { int i; - Uint32 then, now, frames; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); @@ -256,7 +269,12 @@ main(int argc, char *argv[]) } } if (consumed < 0) { - static const char *options[] = { "[--blend none|blend|add|mod]", "[--cyclecolor]", "[--cyclealpha]", NULL }; + static const char *options[] = { + "[--blend none|blend|add|mod]", + "[--cyclecolor]", + "[--cyclealpha]", + "[num_objects]", + NULL }; SDLTest_CommonLogUsage(state, argv[0], options); return 1; } @@ -278,27 +296,20 @@ main(int argc, char *argv[]) /* Main render loop */ frames = 0; - then = SDL_GetTicks(); + next_fps_check = SDL_GetTicks() + fps_check_delay; done = 0; #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(loop, 0, 1); #else while (!done) { - ++frames; loop(); - } + } #endif SDLTest_CommonQuit(state); - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - double fps = ((double) frames * 1000) / (now - then); - SDL_Log("%2.2f frames per second\n", fps); - } return 0; } diff --git a/Engine/lib/sdl/test/testdrawchessboard.c b/Engine/lib/sdl/test/testdrawchessboard.c index 8943e70cc..f3636f389 100644 --- a/Engine/lib/sdl/test/testdrawchessboard.c +++ b/Engine/lib/sdl/test/testdrawchessboard.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,7 +29,7 @@ SDL_Surface *surface; int done; void -DrawChessBoard(SDL_Renderer * renderer) +DrawChessBoard() { int row = 0,column = 0,x = 0; SDL_Rect rect, darea; @@ -90,7 +90,7 @@ loop() } } - DrawChessBoard(renderer); + DrawChessBoard(); /* Got everything on rendering surface, now Update the drawing image on window screen */ diff --git a/Engine/lib/sdl/test/testdropfile.c b/Engine/lib/sdl/test/testdropfile.c index 930b80f03..95212472a 100644 --- a/Engine/lib/sdl/test/testdropfile.c +++ b/Engine/lib/sdl/test/testdropfile.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testerror.c b/Engine/lib/sdl/test/testerror.c index e638dd13f..e847c2824 100644 --- a/Engine/lib/sdl/test/testerror.c +++ b/Engine/lib/sdl/test/testerror.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testevdev.c b/Engine/lib/sdl/test/testevdev.c index 9ed3eff34..572c60a05 100644 --- a/Engine/lib/sdl/test/testevdev.c +++ b/Engine/lib/sdl/test/testevdev.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga Copyright (C) 2020 Collabora Ltd. This software is provided 'as-is', without any express or implied diff --git a/Engine/lib/sdl/test/testfile.c b/Engine/lib/sdl/test/testfile.c index b22ffa199..25a309201 100644 --- a/Engine/lib/sdl/test/testfile.c +++ b/Engine/lib/sdl/test/testfile.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testfilesystem.c b/Engine/lib/sdl/test/testfilesystem.c index c9a82d025..9862608d5 100644 --- a/Engine/lib/sdl/test/testfilesystem.c +++ b/Engine/lib/sdl/test/testfilesystem.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testgamecontroller.c b/Engine/lib/sdl/test/testgamecontroller.c index 6522885cf..17fb60bd3 100644 --- a/Engine/lib/sdl/test/testgamecontroller.c +++ b/Engine/lib/sdl/test/testgamecontroller.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -61,15 +61,16 @@ static const struct { int x; int y; double angle; } axis_positions[] = { {375, -20, 0.0}, /* TRIGGERRIGHT */ }; -SDL_Window *window = NULL; -SDL_Renderer *screen = NULL; -SDL_bool retval = SDL_FALSE; -SDL_bool done = SDL_FALSE; -SDL_bool set_LED = SDL_FALSE; -SDL_Texture *background_front, *background_back, *button, *axis; -SDL_GameController *gamecontroller; -SDL_GameController **gamecontrollers; -int num_controllers = 0; +static SDL_Window *window = NULL; +static SDL_Renderer *screen = NULL; +static SDL_bool retval = SDL_FALSE; +static SDL_bool done = SDL_FALSE; +static SDL_bool set_LED = SDL_FALSE; +static int trigger_effect = 0; +static SDL_Texture *background_front, *background_back, *button, *axis; +static SDL_GameController *gamecontroller; +static SDL_GameController **gamecontrollers; +static int num_controllers = 0; static void UpdateWindowTitle() { @@ -146,6 +147,7 @@ static void AddController(int device_index, SDL_bool verbose) controllers[num_controllers++] = controller; gamecontrollers = controllers; gamecontroller = controller; + trigger_effect = 0; if (verbose) { const char *name = SDL_GameControllerName(gamecontroller); @@ -154,18 +156,26 @@ static void AddController(int device_index, SDL_bool verbose) if (SDL_GameControllerHasSensor(gamecontroller, SDL_SENSOR_ACCEL)) { if (verbose) { - SDL_Log("Enabling accelerometer\n"); + SDL_Log("Enabling accelerometer at %.2f Hz\n", SDL_GameControllerGetSensorDataRate(gamecontroller, SDL_SENSOR_ACCEL)); } SDL_GameControllerSetSensorEnabled(gamecontroller, SDL_SENSOR_ACCEL, SDL_TRUE); } if (SDL_GameControllerHasSensor(gamecontroller, SDL_SENSOR_GYRO)) { if (verbose) { - SDL_Log("Enabling gyro\n"); + SDL_Log("Enabling gyro at %.2f Hz\n", SDL_GameControllerGetSensorDataRate(gamecontroller, SDL_SENSOR_GYRO)); } SDL_GameControllerSetSensorEnabled(gamecontroller, SDL_SENSOR_GYRO, SDL_TRUE); } + if (SDL_GameControllerHasRumble(gamecontroller)) { + SDL_Log("Rumble supported"); + } + + if (SDL_GameControllerHasRumbleTriggers(gamecontroller)) { + SDL_Log("Trigger rumble supported"); + } + UpdateWindowTitle(); } @@ -234,17 +244,68 @@ LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) return texture; } -static Uint16 ConvertAxisToRumble(Sint16 axis) +static Uint16 ConvertAxisToRumble(Sint16 axisval) { /* Only start rumbling if the axis is past the halfway point */ const Sint16 half_axis = (Sint16)SDL_ceil(SDL_JOYSTICK_AXIS_MAX / 2.0f); - if (axis > half_axis) { - return (Uint16)(axis - half_axis) * 4; + if (axisval > half_axis) { + return (Uint16)(axisval - half_axis) * 4; } else { return 0; } } +/* PS5 trigger effect documentation: + https://controllers.fandom.com/wiki/Sony_DualSense#FFB_Trigger_Modes +*/ +typedef struct +{ + Uint8 ucEnableBits1; /* 0 */ + Uint8 ucEnableBits2; /* 1 */ + Uint8 ucRumbleRight; /* 2 */ + Uint8 ucRumbleLeft; /* 3 */ + Uint8 ucHeadphoneVolume; /* 4 */ + Uint8 ucSpeakerVolume; /* 5 */ + Uint8 ucMicrophoneVolume; /* 6 */ + Uint8 ucAudioEnableBits; /* 7 */ + Uint8 ucMicLightMode; /* 8 */ + Uint8 ucAudioMuteBits; /* 9 */ + Uint8 rgucRightTriggerEffect[11]; /* 10 */ + Uint8 rgucLeftTriggerEffect[11]; /* 21 */ + Uint8 rgucUnknown1[6]; /* 32 */ + Uint8 ucLedFlags; /* 38 */ + Uint8 rgucUnknown2[2]; /* 39 */ + Uint8 ucLedAnim; /* 41 */ + Uint8 ucLedBrightness; /* 42 */ + Uint8 ucPadLights; /* 43 */ + Uint8 ucLedRed; /* 44 */ + Uint8 ucLedGreen; /* 45 */ + Uint8 ucLedBlue; /* 46 */ +} DS5EffectsState_t; + +static void CyclePS5TriggerEffect() +{ + DS5EffectsState_t state; + + Uint8 effects[3][11] = + { + /* Clear trigger effect */ + { 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* Constant resistance across entire trigger pull */ + { 0x01, 0, 110, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* Resistance and vibration when trigger is pulled */ + { 0x06, 15, 63, 128, 0, 0, 0, 0, 0, 0, 0 }, + }; + + trigger_effect = (trigger_effect + 1) % SDL_arraysize(effects); + + SDL_zero(state); + state.ucEnableBits1 |= (0x04 | 0x08); /* Modify right and left trigger effect respectively */ + SDL_memcpy(state.rgucRightTriggerEffect, effects[trigger_effect], sizeof(effects[trigger_effect])); + SDL_memcpy(state.rgucLeftTriggerEffect, effects[trigger_effect], sizeof(effects[trigger_effect])); + SDL_GameControllerSendEffect(gamecontroller, &state, sizeof(state)); +} + void loop(void *arg) { @@ -252,7 +313,11 @@ loop(void *arg) int i; SDL_bool showing_front = SDL_TRUE; - while (SDL_PollEvent(&event)) { + /* Update to get the current event state */ + SDL_PumpEvents(); + + /* Process all currently pending events */ + while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) == 1) { switch (event.type) { case SDL_CONTROLLERDEVICEADDED: SDL_Log("Game controller device %d added.\n", (int) SDL_JoystickGetDeviceInstanceID(event.cdevice.which)); @@ -267,7 +332,8 @@ loop(void *arg) case SDL_CONTROLLERTOUCHPADDOWN: case SDL_CONTROLLERTOUCHPADMOTION: case SDL_CONTROLLERTOUCHPADUP: - SDL_Log("Controller touchpad %d finger %d %s %.2f, %.2f, %.2f\n", + SDL_Log("Controller %d touchpad %d finger %d %s %.2f, %.2f, %.2f\n", + event.ctouchpad.which, event.ctouchpad.touchpad, event.ctouchpad.finger, (event.type == SDL_CONTROLLERTOUCHPADDOWN ? "pressed at" : @@ -278,35 +344,57 @@ loop(void *arg) event.ctouchpad.pressure); break; +#define VERBOSE_SENSORS +#ifdef VERBOSE_SENSORS case SDL_CONTROLLERSENSORUPDATE: - SDL_Log("Controller sensor %s: %.2f, %.2f, %.2f\n", + SDL_Log("Controller %d sensor %s: %.2f, %.2f, %.2f\n", + event.csensor.which, event.csensor.sensor == SDL_SENSOR_ACCEL ? "accelerometer" : event.csensor.sensor == SDL_SENSOR_GYRO ? "gyro" : "unknown", event.csensor.data[0], event.csensor.data[1], event.csensor.data[2]); break; +#endif /* VERBOSE_SENSORS */ +#define VERBOSE_AXES +#ifdef VERBOSE_AXES case SDL_CONTROLLERAXISMOTION: if (event.caxis.value <= (-SDL_JOYSTICK_AXIS_MAX / 2) || event.caxis.value >= (SDL_JOYSTICK_AXIS_MAX / 2)) { SetController(event.caxis.which); } - SDL_Log("Controller axis %s changed to %d\n", SDL_GameControllerGetStringForAxis((SDL_GameControllerAxis)event.caxis.axis), event.caxis.value); + SDL_Log("Controller %d axis %s changed to %d\n", event.caxis.which, SDL_GameControllerGetStringForAxis((SDL_GameControllerAxis)event.caxis.axis), event.caxis.value); break; +#endif /* VERBOSE_AXES */ case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP: if (event.type == SDL_CONTROLLERBUTTONDOWN) { SetController(event.cbutton.which); } - SDL_Log("Controller button %s %s\n", SDL_GameControllerGetStringForButton((SDL_GameControllerButton)event.cbutton.button), event.cbutton.state ? "pressed" : "released"); + SDL_Log("Controller %d button %s %s\n", event.cbutton.which, SDL_GameControllerGetStringForButton((SDL_GameControllerButton)event.cbutton.button), event.cbutton.state ? "pressed" : "released"); + + /* Cycle PS5 trigger effects when the microphone button is pressed */ + if (event.type == SDL_CONTROLLERBUTTONDOWN && + event.cbutton.button == SDL_CONTROLLER_BUTTON_MISC1 && + SDL_GameControllerGetType(gamecontroller) == SDL_CONTROLLER_TYPE_PS5) { + CyclePS5TriggerEffect(); + } break; case SDL_KEYDOWN: + if (event.key.keysym.sym >= SDLK_0 && event.key.keysym.sym <= SDLK_9) { + if (gamecontroller) { + int player_index = (event.key.keysym.sym - SDLK_0); + + SDL_GameControllerSetPlayerIndex(gamecontroller, player_index); + } + break; + } if (event.key.keysym.sym != SDLK_ESCAPE) { break; } - /* Fall through to signal quit */ + SDL_FALLTHROUGH; case SDL_QUIT: done = SDL_TRUE; break; @@ -336,7 +424,11 @@ loop(void *arg) if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) { SDL_bool on_front = (i < SDL_CONTROLLER_BUTTON_PADDLE1 || i > SDL_CONTROLLER_BUTTON_PADDLE4); if (on_front == showing_front) { - const SDL_Rect dst = { button_positions[i].x, button_positions[i].y, 50, 50 }; + SDL_Rect dst; + dst.x = button_positions[i].x; + dst.y = button_positions[i].y; + dst.w = 50; + dst.h = 50; SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, SDL_FLIP_NONE); } } @@ -347,12 +439,20 @@ loop(void *arg) const Sint16 deadzone = 8000; /* !!! FIXME: real deadzone */ const Sint16 value = SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i)); if (value < -deadzone) { - const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 }; const double angle = axis_positions[i].angle; + SDL_Rect dst; + dst.x = axis_positions[i].x; + dst.y = axis_positions[i].y; + dst.w = 50; + dst.h = 50; SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE); } else if (value > deadzone) { - const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 }; const double angle = axis_positions[i].angle + 180.0; + SDL_Rect dst; + dst.x = axis_positions[i].x; + dst.y = axis_positions[i].y; + dst.w = 50; + dst.h = 50; SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE); } } @@ -386,23 +486,25 @@ loop(void *arg) } } - /* Update rumble based on trigger state */ - { - Sint16 left = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_TRIGGERLEFT); - Sint16 right = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); - Uint16 low_frequency_rumble = ConvertAxisToRumble(left); - Uint16 high_frequency_rumble = ConvertAxisToRumble(right); - SDL_GameControllerRumble(gamecontroller, low_frequency_rumble, high_frequency_rumble, 250); - } + if (trigger_effect == 0) { + /* Update rumble based on trigger state */ + { + Sint16 left = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_TRIGGERLEFT); + Sint16 right = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); + Uint16 low_frequency_rumble = ConvertAxisToRumble(left); + Uint16 high_frequency_rumble = ConvertAxisToRumble(right); + SDL_GameControllerRumble(gamecontroller, low_frequency_rumble, high_frequency_rumble, 250); + } - /* Update trigger rumble based on thumbstick state */ - { - Sint16 left = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_LEFTY); - Sint16 right = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_RIGHTY); - Uint16 left_rumble = ConvertAxisToRumble(~left); - Uint16 right_rumble = ConvertAxisToRumble(~right); + /* Update trigger rumble based on thumbstick state */ + { + Sint16 left = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_LEFTY); + Sint16 right = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_RIGHTY); + Uint16 left_rumble = ConvertAxisToRumble(~left); + Uint16 right_rumble = ConvertAxisToRumble(~right); - SDL_GameControllerRumbleTriggers(gamecontroller, left_rumble, right_rumble, 250); + SDL_GameControllerRumbleTriggers(gamecontroller, left_rumble, right_rumble, 250); + } } } @@ -424,8 +526,12 @@ main(int argc, char *argv[]) char guid[64]; SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1"); + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); + SDL_SetHint(SDL_HINT_JOYSTICK_ROG_CHAKRAM, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); + SDL_SetHint(SDL_HINT_LINUX_JOYSTICK_DEADZONES, "1"); /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); @@ -435,7 +541,7 @@ main(int argc, char *argv[]) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); return 1; } - + SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt"); /* Print information about the mappings */ @@ -463,11 +569,14 @@ main(int argc, char *argv[]) controller_count++; name = SDL_GameControllerNameForIndex(i); switch (SDL_GameControllerTypeForIndex(i)) { - case SDL_CONTROLLER_TYPE_XBOX360: - description = "XBox 360 Controller"; + case SDL_CONTROLLER_TYPE_AMAZON_LUNA: + description = "Amazon Luna Controller"; break; - case SDL_CONTROLLER_TYPE_XBOXONE: - description = "XBox One Controller"; + case SDL_CONTROLLER_TYPE_GOOGLE_STADIA: + description = "Google Stadia Controller"; + break; + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: + description = "Nintendo Switch Pro Controller"; break; case SDL_CONTROLLER_TYPE_PS3: description = "PS3 Controller"; @@ -475,8 +584,14 @@ main(int argc, char *argv[]) case SDL_CONTROLLER_TYPE_PS4: description = "PS4 Controller"; break; - case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: - description = "Nintendo Switch Pro Controller"; + case SDL_CONTROLLER_TYPE_PS5: + description = "PS5 Controller"; + break; + case SDL_CONTROLLER_TYPE_XBOX360: + description = "XBox 360 Controller"; + break; + case SDL_CONTROLLER_TYPE_XBOXONE: + description = "XBox One Controller"; break; case SDL_CONTROLLER_TYPE_VIRTUAL: description = "Virtual Game Controller"; @@ -554,6 +669,12 @@ main(int argc, char *argv[]) } #endif + /* Reset trigger state */ + if (trigger_effect != 0) { + trigger_effect = -1; + CyclePS5TriggerEffect(); + } + SDL_DestroyRenderer(screen); SDL_DestroyWindow(window); SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); diff --git a/Engine/lib/sdl/test/testgeometry.c b/Engine/lib/sdl/test/testgeometry.c new file mode 100644 index 000000000..3a87e3d2e --- /dev/null +++ b/Engine/lib/sdl/test/testgeometry.c @@ -0,0 +1,303 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + +/* Simple program: draw a RGB triangle, with texture */ + +#include +#include +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include "SDL_test_common.h" + +static SDLTest_CommonState *state; +static SDL_bool use_texture = SDL_FALSE; +static SDL_Texture **sprites; +static SDL_BlendMode blendMode = SDL_BLENDMODE_NONE; +static double angle = 0.0; +static int sprite_w, sprite_h; + +int done; + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void +quit(int rc) +{ + SDL_free(sprites); + SDLTest_CommonQuit(state); + exit(rc); +} + +int +LoadSprite(const char *file) +{ + int i; + SDL_Surface *temp; + + /* Load the sprite image */ + temp = SDL_LoadBMP(file); + if (temp == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); + return (-1); + } + sprite_w = temp->w; + sprite_h = temp->h; + + /* Set transparent pixel as the pixel at (0,0) */ + if (temp->format->palette) { + SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels); + } else { + switch (temp->format->BitsPerPixel) { + case 15: + SDL_SetColorKey(temp, 1, (*(Uint16 *) temp->pixels) & 0x00007FFF); + break; + case 16: + SDL_SetColorKey(temp, 1, *(Uint16 *) temp->pixels); + break; + case 24: + SDL_SetColorKey(temp, 1, (*(Uint32 *) temp->pixels) & 0x00FFFFFF); + break; + case 32: + SDL_SetColorKey(temp, 1, *(Uint32 *) temp->pixels); + break; + } + } + + /* Create textures from the image */ + for (i = 0; i < state->num_windows; ++i) { + SDL_Renderer *renderer = state->renderers[i]; + sprites[i] = SDL_CreateTextureFromSurface(renderer, temp); + if (!sprites[i]) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); + SDL_FreeSurface(temp); + return (-1); + } + if (SDL_SetTextureBlendMode(sprites[i], blendMode) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set blend mode: %s\n", SDL_GetError()); + SDL_FreeSurface(temp); + SDL_DestroyTexture(sprites[i]); + return (-1); + } + } + SDL_FreeSurface(temp); + + /* We're ready to roll. :) */ + return (0); +} + + +void +loop() +{ + int i; + SDL_Event event; + + /* Check for events */ + while (SDL_PollEvent(&event)) { + + if (event.type == SDL_MOUSEMOTION) { + if (event.motion.state) { + int xrel, yrel; + int window_w, window_h; + SDL_Window *window = SDL_GetWindowFromID(event.motion.windowID); + SDL_GetWindowSize(window, &window_w, &window_h); + xrel = event.motion.xrel; + yrel = event.motion.yrel; + if (event.motion.y < window_h / 2) { + angle += xrel; + } else { + angle -= xrel; + } + if (event.motion.x < window_w / 2) { + angle -= yrel; + } else { + angle += yrel; + } + } + } else { + SDLTest_CommonEvent(state, &event, &done); + } + } + + for (i = 0; i < state->num_windows; ++i) { + SDL_Renderer *renderer = state->renderers[i]; + if (state->windows[i] == NULL) + continue; + SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); + SDL_RenderClear(renderer); + + { + SDL_Rect viewport; + SDL_Vertex verts[3]; + double a; + double d; + int cx, cy; + + /* Query the sizes */ + SDL_RenderGetViewport(renderer, &viewport); + SDL_zeroa(verts); + cx = viewport.x + viewport.w / 2; + cy = viewport.y + viewport.h / 2; + d = (viewport.w + viewport.h) / 5; + + a = (angle * 3.1415) / 180.0; + verts[0].position.x = cx + d * SDL_cos(a); + verts[0].position.y = cy + d * SDL_sin(a); + verts[0].color.r = 0xFF; + verts[0].color.g = 0; + verts[0].color.b = 0; + verts[0].color.a = 0xFF; + + a = ((angle + 120) * 3.1415) / 180.0; + verts[1].position.x = cx + d * SDL_cos(a); + verts[1].position.y = cy + d * SDL_sin(a); + verts[1].color.r = 0; + verts[1].color.g = 0xFF; + verts[1].color.b = 0; + verts[1].color.a = 0xFF; + + a = ((angle + 240) * 3.1415) / 180.0; + verts[2].position.x = cx + d * SDL_cos(a); + verts[2].position.y = cy + d * SDL_sin(a); + verts[2].color.r = 0; + verts[2].color.g = 0; + verts[2].color.b = 0xFF; + verts[2].color.a = 0xFF; + + if (use_texture) { + verts[0].tex_coord.x = 0.5; + verts[0].tex_coord.y = 0.0; + verts[1].tex_coord.x = 1.0; + verts[1].tex_coord.y = 1.0; + verts[2].tex_coord.x = 0.0; + verts[2].tex_coord.y = 1.0; + } + + SDL_RenderGeometry(renderer, sprites[i], verts, 3, NULL, 0); + } + + SDL_RenderPresent(renderer); + } +#ifdef __EMSCRIPTEN__ + if (done) { + emscripten_cancel_main_loop(); + } +#endif +} + +int +main(int argc, char *argv[]) +{ + int i; + const char *icon = "icon.bmp"; + Uint32 then, now, frames; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Initialize test framework */ + state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); + if (!state) { + return 1; + } + for (i = 1; i < argc;) { + int consumed; + + consumed = SDLTest_CommonArg(state, i); + if (consumed == 0) { + consumed = -1; + if (SDL_strcasecmp(argv[i], "--blend") == 0) { + if (argv[i + 1]) { + if (SDL_strcasecmp(argv[i + 1], "none") == 0) { + blendMode = SDL_BLENDMODE_NONE; + consumed = 2; + } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) { + blendMode = SDL_BLENDMODE_BLEND; + consumed = 2; + } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) { + blendMode = SDL_BLENDMODE_ADD; + consumed = 2; + } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) { + blendMode = SDL_BLENDMODE_MOD; + consumed = 2; + } + } + } else if (SDL_strcasecmp(argv[i], "--use-texture") == 0) { + use_texture = SDL_TRUE; + consumed = 1; + } + } + if (consumed < 0) { + static const char *options[] = { "[--blend none|blend|add|mod]", "[--use-texture]", NULL }; + SDLTest_CommonLogUsage(state, argv[0], options); + return 1; + } + i += consumed; + } + if (!SDLTest_CommonInit(state)) { + return 2; + } + + /* Create the windows, initialize the renderers, and load the textures */ + sprites = + (SDL_Texture **) SDL_malloc(state->num_windows * sizeof(*sprites)); + if (!sprites) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n"); + quit(2); + } + /* Create the windows and initialize the renderers */ + for (i = 0; i < state->num_windows; ++i) { + SDL_Renderer *renderer = state->renderers[i]; + SDL_SetRenderDrawBlendMode(renderer, blendMode); + SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); + SDL_RenderClear(renderer); + sprites[i] = NULL; + } + if (use_texture) { + if (LoadSprite(icon) < 0) { + quit(2); + } + } + + + srand((unsigned int)time(NULL)); + + /* Main render loop */ + frames = 0; + then = SDL_GetTicks(); + done = 0; + +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(loop, 0, 1); +#else + while (!done) { + ++frames; + loop(); + } +#endif + + /* Print out some timing information */ + now = SDL_GetTicks(); + if (now > then) { + double fps = ((double) frames * 1000) / (now - then); + SDL_Log("%2.2f frames per second\n", fps); + } + + quit(0); + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/test/testgesture.c b/Engine/lib/sdl/test/testgesture.c index a925e0ac2..856fd6a2d 100644 --- a/Engine/lib/sdl/test/testgesture.c +++ b/Engine/lib/sdl/test/testgesture.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -90,6 +90,7 @@ setpix(SDL_Surface *screen, float _x, float _y, unsigned int col) *pixmem32 = colour; } +#if 0 /* unused */ static void drawLine(SDL_Surface *screen, float x0, float y0, float x1, float y1, unsigned int col) { @@ -98,6 +99,7 @@ drawLine(SDL_Surface *screen, float x0, float y0, float x1, float y1, unsigned i setpix(screen, x1 + t * (x0 - x1), y1 + t * (y0 - y1), col); } } +#endif static void drawCircle(SDL_Surface *screen, float x, float y, float r, unsigned int c) @@ -188,7 +190,8 @@ loop(void) case SDLK_i: { for (i = 0; i < SDL_GetNumTouchDevices(); ++i) { const SDL_TouchID id = SDL_GetTouchDevice(i); - SDL_Log("Fingers Down on device %"SDL_PRIs64": %d", id, SDL_GetNumTouchFingers(id)); + const char *name = SDL_GetTouchName(i); + SDL_Log("Fingers Down on device %"SDL_PRIs64" (%s): %d", id, name, SDL_GetNumTouchFingers(id)); } break; } @@ -213,7 +216,7 @@ loop(void) #if VERBOSE case SDL_FINGERMOTION: - SDL_Log("Finger: %"SDL_PRIs64",x: %f, y: %f",event.tfinger.fingerId, + SDL_Log("Finger: %"SDL_PRIs64", x: %f, y: %f",event.tfinger.fingerId, event.tfinger.x,event.tfinger.y); break; diff --git a/Engine/lib/sdl/test/testgl2.c b/Engine/lib/sdl/test/testgl2.c index 894ff80c2..6eb439cb1 100644 --- a/Engine/lib/sdl/test/testgl2.c +++ b/Engine/lib/sdl/test/testgl2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -238,10 +238,10 @@ main(int argc, char *argv[]) consumed = SDLTest_CommonArg(state, i); if (consumed == 0) { if (SDL_strcasecmp(argv[i], "--fsaa") == 0 && i+1 < argc) { - fsaa = atoi(argv[i+1]); + fsaa = SDL_atoi(argv[i+1]); consumed = 2; } else if (SDL_strcasecmp(argv[i], "--accel") == 0 && i+1 < argc) { - accel = atoi(argv[i+1]); + accel = SDL_atoi(argv[i+1]); consumed = 2; } else { consumed = -1; diff --git a/Engine/lib/sdl/test/testgles.c b/Engine/lib/sdl/test/testgles.c index 134b41566..cb989f44f 100644 --- a/Engine/lib/sdl/test/testgles.c +++ b/Engine/lib/sdl/test/testgles.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testgles2.c b/Engine/lib/sdl/test/testgles2.c index 3946653c0..153ebe499 100644 --- a/Engine/lib/sdl/test/testgles2.c +++ b/Engine/lib/sdl/test/testgles2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,8 +22,10 @@ #if defined(__IPHONEOS__) || defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__NACL__) \ || defined(__WINDOWS__) || defined(__LINUX__) +#ifndef HAVE_OPENGLES2 #define HAVE_OPENGLES2 #endif +#endif #ifdef HAVE_OPENGLES2 @@ -370,6 +372,8 @@ typedef struct shader_data int angle_x, angle_y, angle_z; + GLuint position_buffer; + GLuint color_buffer; } shader_data; static void @@ -686,8 +690,18 @@ main(int argc, char *argv[]) GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_color)); /* Populate attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices)); - GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors)); + + GL_CHECK(ctx.glGenBuffers(1, &data->position_buffer)); + GL_CHECK(ctx.glBindBuffer(GL_ARRAY_BUFFER, data->position_buffer)); + GL_CHECK(ctx.glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices) * 4, _vertices, GL_STATIC_DRAW)); + GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, 0)); + GL_CHECK(ctx.glBindBuffer(GL_ARRAY_BUFFER, 0)); + + GL_CHECK(ctx.glGenBuffers(1, &data->color_buffer)); + GL_CHECK(ctx.glBindBuffer(GL_ARRAY_BUFFER, data->color_buffer)); + GL_CHECK(ctx.glBufferData(GL_ARRAY_BUFFER, sizeof(_colors) * 4, _colors, GL_STATIC_DRAW)); + GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, 0)); + GL_CHECK(ctx.glBindBuffer(GL_ARRAY_BUFFER, 0)); GL_CHECK(ctx.glEnable(GL_CULL_FACE)); GL_CHECK(ctx.glEnable(GL_DEPTH_TEST)); diff --git a/Engine/lib/sdl/test/testgles2_sdf.c b/Engine/lib/sdl/test/testgles2_sdf.c new file mode 100644 index 000000000..a7f8016ea --- /dev/null +++ b/Engine/lib/sdl/test/testgles2_sdf.c @@ -0,0 +1,805 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ +#include +#include +#include +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include "SDL_test_common.h" + +#if defined(__IPHONEOS__) || defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__NACL__) \ + || defined(__WINDOWS__) || defined(__LINUX__) +#define HAVE_OPENGLES2 +#endif + +#ifdef HAVE_OPENGLES2 + +#include "SDL_opengles2.h" + +typedef struct GLES2_Context +{ +#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; +#include "../src/render/opengles2/SDL_gles2funcs.h" +#undef SDL_PROC +} GLES2_Context; + + +static SDL_Surface *g_surf_sdf = NULL; +GLenum g_texture; +GLenum g_texture_type = GL_TEXTURE_2D; +GLfloat g_verts[24]; +typedef enum +{ + GLES2_ATTRIBUTE_POSITION = 0, + GLES2_ATTRIBUTE_TEXCOORD = 1, + GLES2_ATTRIBUTE_ANGLE = 2, + GLES2_ATTRIBUTE_CENTER = 3, +} GLES2_Attribute; + +typedef enum +{ + GLES2_UNIFORM_PROJECTION, + GLES2_UNIFORM_TEXTURE, + GLES2_UNIFORM_COLOR, +} GLES2_Uniform; + + +GLuint g_uniform_locations[16]; + + + +static SDLTest_CommonState *state; +static SDL_GLContext *context = NULL; +static int depth = 16; +static GLES2_Context ctx; + +static int LoadContext(GLES2_Context * data) +{ +#if SDL_VIDEO_DRIVER_UIKIT +#define __SDL_NOGETPROCADDR__ +#elif SDL_VIDEO_DRIVER_ANDROID +#define __SDL_NOGETPROCADDR__ +#elif SDL_VIDEO_DRIVER_PANDORA +#define __SDL_NOGETPROCADDR__ +#endif + +#if defined __SDL_NOGETPROCADDR__ +#define SDL_PROC(ret,func,params) data->func=func; +#else +#define SDL_PROC(ret,func,params) \ + do { \ + data->func = SDL_GL_GetProcAddress(#func); \ + if ( ! data->func ) { \ + return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \ + } \ + } while ( 0 ); +#endif /* __SDL_NOGETPROCADDR__ */ + +#include "../src/render/opengles2/SDL_gles2funcs.h" +#undef SDL_PROC + return 0; +} + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void +quit(int rc) +{ + int i; + + if (context != NULL) { + for (i = 0; i < state->num_windows; i++) { + if (context[i]) { + SDL_GL_DeleteContext(context[i]); + } + } + + SDL_free(context); + } + + SDLTest_CommonQuit(state); + exit(rc); +} + +#define GL_CHECK(x) \ + x; \ + { \ + GLenum glError = ctx.glGetError(); \ + if(glError != GL_NO_ERROR) { \ + SDL_Log("glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \ + quit(1); \ + } \ + } + + +/* + * Create shader, load in source, compile, dump debug as necessary. + * + * shader: Pointer to return created shader ID. + * source: Passed-in shader source code. + * shader_type: Passed to GL, e.g. GL_VERTEX_SHADER. + */ +void +process_shader(GLuint *shader, const char * source, GLint shader_type) +{ + GLint status = GL_FALSE; + const char *shaders[1] = { NULL }; + char buffer[1024]; + GLsizei length; + + /* Create shader and load into GL. */ + *shader = GL_CHECK(ctx.glCreateShader(shader_type)); + + shaders[0] = source; + + GL_CHECK(ctx.glShaderSource(*shader, 1, shaders, NULL)); + + /* Clean up shader source. */ + shaders[0] = NULL; + + /* Try compiling the shader. */ + GL_CHECK(ctx.glCompileShader(*shader)); + GL_CHECK(ctx.glGetShaderiv(*shader, GL_COMPILE_STATUS, &status)); + + /* Dump debug info (source and log) if compilation failed. */ + if(status != GL_TRUE) { + ctx.glGetProgramInfoLog(*shader, sizeof(buffer), &length, &buffer[0]); + buffer[length] = '\0'; + SDL_Log("Shader compilation failed: %s", buffer);fflush(stderr); + quit(-1); + } +} + +/* Notes on a_angle: + * It is a vector containing sine and cosine for rotation matrix + * To get correct rotation for most cases when a_angle is disabled cosine + * value is decremented by 1.0 to get proper output with 0.0 which is default value + */ +static const Uint8 GLES2_VertexSrc_Default_[] = " \ + uniform mat4 u_projection; \ + attribute vec2 a_position; \ + attribute vec2 a_texCoord; \ + attribute vec2 a_angle; \ + attribute vec2 a_center; \ + varying vec2 v_texCoord; \ + \ + void main() \ + { \ + float s = a_angle[0]; \ + float c = a_angle[1] + 1.0; \ + mat2 rotationMatrix = mat2(c, -s, s, c); \ + vec2 position = rotationMatrix * (a_position - a_center) + a_center; \ + v_texCoord = a_texCoord; \ + gl_Position = u_projection * vec4(position, 0.0, 1.0);\ + gl_PointSize = 1.0; \ + } \ +"; + +static const Uint8 GLES2_FragmentSrc_TextureABGRSrc_[] = " \ + precision mediump float; \ + uniform sampler2D u_texture; \ + uniform vec4 u_color; \ + varying vec2 v_texCoord; \ + \ + void main() \ + { \ + gl_FragColor = texture2D(u_texture, v_texCoord); \ + gl_FragColor *= u_color; \ + } \ +"; + +/* RGB to ABGR conversion */ +static const Uint8 GLES2_FragmentSrc_TextureABGRSrc_SDF[] = " \ + #extension GL_OES_standard_derivatives : enable\n\ + \ + precision mediump float; \ + uniform sampler2D u_texture; \ + uniform vec4 u_color; \ + varying vec2 v_texCoord; \ + \ + void main() \ + { \ + vec4 abgr = texture2D(u_texture, v_texCoord); \ +\ + float sigDist = abgr.a; \ + \ + float w = fwidth( sigDist );\ + float alpha = clamp(smoothstep(0.5 - w, 0.5 + w, sigDist), 0.0, 1.0); \ +\ + gl_FragColor = vec4(abgr.rgb, abgr.a * alpha); \ + gl_FragColor.rgb *= gl_FragColor.a; \ + gl_FragColor *= u_color; \ + } \ +"; + +/* RGB to ABGR conversion DEBUG */ +static const char *GLES2_FragmentSrc_TextureABGRSrc_SDF_dbg = " \ + #extension GL_OES_standard_derivatives : enable\n\ + \ + precision mediump float; \ + uniform sampler2D u_texture; \ + uniform vec4 u_color; \ + varying vec2 v_texCoord; \ + \ + void main() \ + { \ + vec4 abgr = texture2D(u_texture, v_texCoord); \ +\ + float a = abgr.a; \ + gl_FragColor = vec4(a, a, a, 1.0); \ + } \ +"; + + +static float g_val = 1.0f; +static int g_use_SDF = 1; +static int g_use_SDF_debug = 0; +static float g_angle = 0.0f; +static float matrix_mvp[4][4]; + + + + +typedef struct shader_data +{ + GLuint shader_program, shader_frag, shader_vert; + + GLint attr_position; + GLint attr_color, attr_mvp; + +} shader_data; + +static void +Render(unsigned int width, unsigned int height, shader_data* data) +{ + float *verts = g_verts; + ctx.glViewport(0, 0, 640, 480); + + GL_CHECK(ctx.glClear(GL_COLOR_BUFFER_BIT)); + + GL_CHECK(ctx.glUniformMatrix4fv(g_uniform_locations[GLES2_UNIFORM_PROJECTION], 1, GL_FALSE, (const float *)matrix_mvp)); + GL_CHECK(ctx.glUniform4f(g_uniform_locations[GLES2_UNIFORM_COLOR], 1.0f, 1.0f, 1.0f, 1.0f)); + + GL_CHECK(ctx.glVertexAttribPointer(GLES2_ATTRIBUTE_ANGLE, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (verts + 16))); + GL_CHECK(ctx.glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (verts + 8))); + GL_CHECK(ctx.glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) verts)); + + GL_CHECK(ctx.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); +} + + +void renderCopy_angle(float degree_angle) +{ + const float radian_angle = (float)(3.141592 * degree_angle) / 180.0; + const GLfloat s = (GLfloat) SDL_sin(radian_angle); + const GLfloat c = (GLfloat) SDL_cos(radian_angle) - 1.0f; + GLfloat *verts = g_verts + 16; + *(verts++) = s; + *(verts++) = c; + *(verts++) = s; + *(verts++) = c; + *(verts++) = s; + *(verts++) = c; + *(verts++) = s; + *(verts++) = c; +} + + +void renderCopy_position(SDL_Rect *srcrect, SDL_Rect *dstrect) +{ + GLfloat minx, miny, maxx, maxy; + GLfloat minu, maxu, minv, maxv; + GLfloat *verts = g_verts; + + minx = dstrect->x; + miny = dstrect->y; + maxx = dstrect->x + dstrect->w; + maxy = dstrect->y + dstrect->h; + + minu = (GLfloat) srcrect->x / g_surf_sdf->w; + maxu = (GLfloat) (srcrect->x + srcrect->w) / g_surf_sdf->w; + minv = (GLfloat) srcrect->y / g_surf_sdf->h; + maxv = (GLfloat) (srcrect->y + srcrect->h) / g_surf_sdf->h; + + *(verts++) = minx; + *(verts++) = miny; + *(verts++) = maxx; + *(verts++) = miny; + *(verts++) = minx; + *(verts++) = maxy; + *(verts++) = maxx; + *(verts++) = maxy; + + *(verts++) = minu; + *(verts++) = minv; + *(verts++) = maxu; + *(verts++) = minv; + *(verts++) = minu; + *(verts++) = maxv; + *(verts++) = maxu; + *(verts++) = maxv; +} + +int done; +Uint32 frames; +shader_data *datas; + +void loop() +{ + SDL_Event event; + int i; + int status; + + /* Check for events */ + ++frames; + while (SDL_PollEvent(&event) && !done) { + switch (event.type) { + case SDL_KEYDOWN: + { + const int sym = event.key.keysym.sym; + + if (sym == SDLK_TAB) { + SDL_Log("Tab"); + + + } + + + if (sym == SDLK_LEFT) g_val -= 0.05; + if (sym == SDLK_RIGHT) g_val += 0.05; + if (sym == SDLK_UP) g_angle -= 1; + if (sym == SDLK_DOWN) g_angle += 1; + + + break; + } + + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_RESIZED: + for (i = 0; i < state->num_windows; ++i) { + if (event.window.windowID == SDL_GetWindowID(state->windows[i])) { + int w, h; + status = SDL_GL_MakeCurrent(state->windows[i], context[i]); + if (status) { + SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); + break; + } + /* Change view port to the new window dimensions */ + SDL_GL_GetDrawableSize(state->windows[i], &w, &h); + ctx.glViewport(0, 0, w, h); + state->window_w = event.window.data1; + state->window_h = event.window.data2; + /* Update window content */ + Render(event.window.data1, event.window.data2, &datas[i]); + SDL_GL_SwapWindow(state->windows[i]); + break; + } + } + break; + } + } + SDLTest_CommonEvent(state, &event, &done); + } + + + matrix_mvp[3][0] = -1.0f; + matrix_mvp[3][3] = 1.0f; + + matrix_mvp[0][0] = 2.0f / 640.0; + matrix_mvp[1][1] = -2.0f / 480.0; + matrix_mvp[3][1] = 1.0f; + + if (0) + { + float *f = (float *) matrix_mvp; + SDL_Log("-----------------------------------"); + SDL_Log("[ %f, %f, %f, %f ]", *f++, *f++, *f++, *f++); + SDL_Log("[ %f, %f, %f, %f ]", *f++, *f++, *f++, *f++); + SDL_Log("[ %f, %f, %f, %f ]", *f++, *f++, *f++, *f++); + SDL_Log("[ %f, %f, %f, %f ]", *f++, *f++, *f++, *f++); + SDL_Log("-----------------------------------"); + } + + renderCopy_angle(g_angle); + + { + int w, h; + SDL_Rect rs, rd; + + SDL_GL_GetDrawableSize(state->windows[0], &w, &h); + + rs.x = 0; rs.y = 0; rs.w = g_surf_sdf->w; rs.h = g_surf_sdf->h; + rd.w = g_surf_sdf->w * g_val; rd.h = g_surf_sdf->h * g_val; + rd.x = (w - rd.w) / 2; rd.y = (h - rd.h) / 2; + renderCopy_position(&rs, &rd); + } + + + if (!done) { + for (i = 0; i < state->num_windows; ++i) { + status = SDL_GL_MakeCurrent(state->windows[i], context[i]); + if (status) { + SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); + + /* Continue for next window */ + continue; + } + Render(state->window_w, state->window_h, &datas[i]); + SDL_GL_SwapWindow(state->windows[i]); + } + } +#ifdef __EMSCRIPTEN__ + else { + emscripten_cancel_main_loop(); + } +#endif +} + +int +main(int argc, char *argv[]) +{ + int fsaa, accel; + int value; + int i; + SDL_DisplayMode mode; + Uint32 then, now; + int status; + shader_data *data; + + /* Initialize parameters */ + fsaa = 0; + accel = 0; + + /* Initialize test framework */ + state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); + if (!state) { + return 1; + } + for (i = 1; i < argc;) { + int consumed; + + consumed = SDLTest_CommonArg(state, i); + if (consumed == 0) { + if (SDL_strcasecmp(argv[i], "--fsaa") == 0) { + ++fsaa; + consumed = 1; + } else if (SDL_strcasecmp(argv[i], "--accel") == 0) { + ++accel; + consumed = 1; + } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) { + i++; + if (!argv[i]) { + consumed = -1; + } else { + depth = SDL_atoi(argv[i]); + consumed = 1; + } + } else { + consumed = -1; + } + } + if (consumed < 0) { + static const char *options[] = { "[--fsaa]", "[--accel]", "[--zdepth %d]", NULL }; + SDLTest_CommonLogUsage(state, argv[0], options); + quit(1); + } + i += consumed; + } + + /* Set OpenGL parameters */ + state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; + state->gl_red_size = 5; + state->gl_green_size = 5; + state->gl_blue_size = 5; + state->gl_depth_size = depth; + state->gl_major_version = 2; + state->gl_minor_version = 0; + state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES; + + if (fsaa) { + state->gl_multisamplebuffers=1; + state->gl_multisamplesamples=fsaa; + } + if (accel) { + state->gl_accelerated=1; + } + if (!SDLTest_CommonInit(state)) { + quit(2); + return 0; + } + + context = (SDL_GLContext *)SDL_calloc(state->num_windows, sizeof(context)); + if (context == NULL) { + SDL_Log("Out of memory!\n"); + quit(2); + } + + /* Create OpenGL ES contexts */ + for (i = 0; i < state->num_windows; i++) { + context[i] = SDL_GL_CreateContext(state->windows[i]); + if (!context[i]) { + SDL_Log("SDL_GL_CreateContext(): %s\n", SDL_GetError()); + quit(2); + } + } + + /* Important: call this *after* creating the context */ + if (LoadContext(&ctx) < 0) { + SDL_Log("Could not load GLES2 functions\n"); + quit(2); + return 0; + } + + SDL_memset(matrix_mvp, 0, sizeof (matrix_mvp)); + + { + SDL_Surface *tmp; + char *f; + g_use_SDF = 1; + g_use_SDF_debug = 0; + + if (g_use_SDF) { + f = "testgles2_sdf_img_sdf.bmp"; + } else { + f = "testgles2_sdf_img_normal.bmp"; + } + + SDL_Log("SDF is %s", g_use_SDF ? "enabled" : "disabled"); + + /* Load SDF BMP image */ +#if 1 + tmp = SDL_LoadBMP(f); + if (tmp == NULL) { + SDL_Log("missing image file: %s", f); + exit(-1); + } else { + SDL_Log("Load image file: %s", f); + } + +#else + /* Generate SDF image using SDL_ttf */ + + #include "SDL_ttf.h" + char *font_file = "./font/DroidSansFallback.ttf"; + char *str = "Abcde"; + SDL_Color color = { 0, 0,0, 255}; + + TTF_Init(); + TTF_Font *font = TTF_OpenFont(font_file, 72); + + if (font == NULL) { + SDL_Log("Cannot open font %s", font_file); + } + + TTF_SetFontSDF(font, g_use_SDF); + SDL_Surface *tmp = TTF_RenderUTF8_Blended(font, str, color); + + SDL_Log("err: %s", SDL_GetError()); + if (tmp == NULL) { + SDL_Log("can't render text"); + return -1; + } + + SDL_SaveBMP(tmp, f); + + TTF_CloseFont(font); + TTF_Quit(); +#endif + g_surf_sdf = SDL_ConvertSurfaceFormat(tmp, SDL_PIXELFORMAT_ABGR8888, 0); + + SDL_SetSurfaceBlendMode(g_surf_sdf, SDL_BLENDMODE_BLEND); + } + + + if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { + SDL_GL_SetSwapInterval(1); + } else { + SDL_GL_SetSwapInterval(0); + } + + SDL_GetCurrentDisplayMode(0, &mode); + SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); + SDL_Log("\n"); + SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); + SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); + SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); + SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS)); + SDL_Log("\n"); + + status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); + if (!status) { + SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); + } else { + SDL_Log( "Failed to get SDL_GL_RED_SIZE: %s\n", + SDL_GetError()); + } + status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); + if (!status) { + SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); + } else { + SDL_Log( "Failed to get SDL_GL_GREEN_SIZE: %s\n", + SDL_GetError()); + } + status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); + if (!status) { + SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); + } else { + SDL_Log( "Failed to get SDL_GL_BLUE_SIZE: %s\n", + SDL_GetError()); + } + status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); + if (!status) { + SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value); + } else { + SDL_Log( "Failed to get SDL_GL_DEPTH_SIZE: %s\n", + SDL_GetError()); + } + if (fsaa) { + status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); + if (!status) { + SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); + } else { + SDL_Log( "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", + SDL_GetError()); + } + status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); + if (!status) { + SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, + value); + } else { + SDL_Log( "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", + SDL_GetError()); + } + } + if (accel) { + status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); + if (!status) { + SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value); + } else { + SDL_Log( "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", + SDL_GetError()); + } + } + + datas = (shader_data *)SDL_calloc(state->num_windows, sizeof(shader_data)); + + /* Set rendering settings for each context */ + for (i = 0; i < state->num_windows; ++i) { + + int w, h; + status = SDL_GL_MakeCurrent(state->windows[i], context[i]); + if (status) { + SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); + + /* Continue for next window */ + continue; + } + + { + int format = GL_RGBA; + int type = GL_UNSIGNED_BYTE; + + GL_CHECK(ctx.glGenTextures(1, &g_texture)); + + ctx.glActiveTexture(GL_TEXTURE0); + ctx.glPixelStorei(GL_PACK_ALIGNMENT, 1); + ctx.glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + ctx.glBindTexture(g_texture_type, g_texture); + + ctx.glTexParameteri(g_texture_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ctx.glTexParameteri(g_texture_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + ctx.glTexParameteri(g_texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + ctx.glTexParameteri(g_texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + GL_CHECK(ctx.glTexImage2D(g_texture_type, 0, format, g_surf_sdf->w, g_surf_sdf->h, 0, format, type, NULL)); + GL_CHECK(ctx.glTexSubImage2D(g_texture_type, 0, 0 /* xoffset */, 0 /* yoffset */, g_surf_sdf->w, g_surf_sdf->h, format, type, g_surf_sdf->pixels)); + } + + + SDL_GL_GetDrawableSize(state->windows[i], &w, &h); + ctx.glViewport(0, 0, w, h); + + data = &datas[i]; + + /* Shader Initialization */ + process_shader(&data->shader_vert, GLES2_VertexSrc_Default_, GL_VERTEX_SHADER); + + if (g_use_SDF) { + if (g_use_SDF_debug == 0) { + process_shader(&data->shader_frag, GLES2_FragmentSrc_TextureABGRSrc_SDF, GL_FRAGMENT_SHADER); + } else { + process_shader(&data->shader_frag, GLES2_FragmentSrc_TextureABGRSrc_SDF_dbg, GL_FRAGMENT_SHADER); + } + } else { + process_shader(&data->shader_frag, GLES2_FragmentSrc_TextureABGRSrc_, GL_FRAGMENT_SHADER); + } + + /* Create shader_program (ready to attach shaders) */ + data->shader_program = GL_CHECK(ctx.glCreateProgram()); + + /* Attach shaders and link shader_program */ + GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert)); + GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag)); + GL_CHECK(ctx.glLinkProgram(data->shader_program)); + + ctx.glBindAttribLocation(data->shader_program, GLES2_ATTRIBUTE_POSITION, "a_position"); + ctx.glBindAttribLocation(data->shader_program, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord"); + ctx.glBindAttribLocation(data->shader_program, GLES2_ATTRIBUTE_ANGLE, "a_angle"); + ctx.glBindAttribLocation(data->shader_program, GLES2_ATTRIBUTE_CENTER, "a_center"); + + /* Predetermine locations of uniform variables */ + g_uniform_locations[GLES2_UNIFORM_PROJECTION] = ctx.glGetUniformLocation(data->shader_program, "u_projection"); + g_uniform_locations[GLES2_UNIFORM_TEXTURE] = ctx.glGetUniformLocation(data->shader_program, "u_texture"); + g_uniform_locations[GLES2_UNIFORM_COLOR] = ctx.glGetUniformLocation(data->shader_program, "u_color"); + + GL_CHECK(ctx.glUseProgram(data->shader_program)); + + ctx.glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_ANGLE); + ctx.glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_CENTER); + ctx.glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + ctx.glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD); + + + ctx.glUniform1i(g_uniform_locations[GLES2_UNIFORM_TEXTURE], 0); /* always texture unit 0. */ + ctx.glActiveTexture(GL_TEXTURE0); + ctx.glBindTexture(g_texture_type, g_texture); + GL_CHECK(ctx.glClearColor(1, 1, 1, 1)); + + // SDL_BLENDMODE_BLEND + GL_CHECK(ctx.glEnable(GL_BLEND)); + ctx.glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + ctx.glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); + + + } + + /* Main render loop */ + frames = 0; + then = SDL_GetTicks(); + done = 0; + +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(loop, 0, 1); +#else + while (!done) { + loop(); + } +#endif + + /* Print out some timing information */ + now = SDL_GetTicks(); + if (now > then) { + SDL_Log("%2.2f frames per second\n", + ((double) frames * 1000) / (now - then)); + } +#if !defined(__ANDROID__) && !defined(__NACL__) + quit(0); +#endif + return 0; +} + +#else /* HAVE_OPENGLES2 */ + +int +main(int argc, char *argv[]) +{ + SDL_Log("No OpenGL ES support on this system\n"); + return 1; +} + +#endif /* HAVE_OPENGLES2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/test/testgles2_sdf_img_normal.bmp b/Engine/lib/sdl/test/testgles2_sdf_img_normal.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1209e1b1df7105dad9e3e401b9dd9a0d255e4162 GIT binary patch literal 68122 zcmeHP3AA3*6@Ez&No!mPk;*euL8uZ#7ZGD9RU|bh7VSz}sZ^F4O00@`imECLMcT?L zOCvS5B_gD0kkrr`s-iXP!lQ_>`hD@v%6aGQeeSvUp8LnDy_YZd+;jGHzW?rX&%OWu z?ELlqeS5S~P6ECM%mEGrdbG8-^}_L*KA(=G>B%Q;ZJ++fzE9f6jTz|;TGJRX28;n? zz!)$Fi~(c77%&Em0b{@zFb0ePW55_N28;n?z!)$Fi~(c77%&Em0b{@zFb0ePW55_N z28;n?z!)$Fi~(c77%&Em0b{@zFb0ePW55_N28;n?;QyC_l`ys8zHBl24J2=!u83w_uIpZj2jr|oc$d9 zb}XN;K4>=}$nPsSm-PG?TKg{8wg>)loeqYh8Gsf$wf`mf*a;{rYrx=UAT^G!_cZKy zFY{#|ocKDf?dw!+^Uuw{50qI$T>S9JI=>qj3265Ma-*%IQ!v(Q;d&6xgXjG0$&Dt` zbw9>aJ{avX>x`5`2Yl?}`K;UIz5Z0-BS4B*rSGVcNo@yx?iH%UayGoqI1eY>)3`DJ z=*Fua*M}kZ1-{Q*ZLU$8{2l{Rod2Mod(l?OY6!$Vjg-p;1xZNtaa*U&2pqLFK#CRX zdmp}X?6cQfX27JN~D1xUFs8m#!wFxb7R_?2Rn?TgjNp^><} z_q0m*zi!dywRu4jQho4#!T$}+JBr`Gqo4Ok)*jctOMyE9twvpLZ$oD@ppNia%K3{O zIfn(npMbf*QvmnSnoVkba4qhL_;LQ{K<6spbYK#21#mB*aWooZ(q}<`Rb^Kgrri5^ zALG93QQ$scKJW|>_ z{_#qTuM23hA_m3-Zveg>@6#G@7%DCNoQm!n-2WT~tQzq?0AsxGpA5_f!u`Zx^u^>l z4EpnQZSE&liWz1aYlk0=*B>OrNU0C*CH6@0>tz>U8ZZhdlCe;5@xmkT3%uv13a?4t*Frzid8$vRS5(K(L6M(P6=B}r0l3aF z*P{C1JxrPt`%=~ z^MH%*AMYx#%`yCl68qLf=SB7L(?ma#8rNl?55HaJdKv^j+C7r%0N+11Ee9ijpTFO} zr$%r-k7>^&E=C#m-1EN*I9vb7XORudILoAau96Se-u{_lNNzS!;*yip_XDx|;I;Q9 zDR5%nR?zc5AHU6ge5y=_qHpWBuS#`NQ;+M7AJ=blk5)&14rAY6*e>Jy=!maV%Q(uY z%k?dslRM|Vt|>Vaj$Iu8*n$4kXW&?U{4qn~_bNFu-}VIm-1lhv8m>PB5`5HE;hL9Qb0mk!8Det{;4`zvQ)-A+pvW~t^7D&SCk^TGU6GU*`_^k9 z=C+Y|JCukQs}HVgb%pzDjhB=<9viXe?hR0`x|ClN`@Tz*SpO(FzgT^&P|}yA&b4tNAn`I=G6?!&d-GO2mouFyfRsP`a_#R< zkHo-Gl4#Gt%(Lh{Q&NDMN_W6s;_>mCenazK=y+L)H8E5!IM?dq^#Z#x!;e8(;^nmj zC)`6xwtSz}H^DxK${ZyJelNuO&mo7vi8N34rHXd_@ml#TNNkQ#EfHM361 zI9h%1n$9J$y+faZAWvglnk%2ZS|$HPASs8O9C806#b95ma2=L>Jdo<3VLh&AZz(x) zt?9@FZND-L{>zG1AAIkWOJaMZwF-jpy^Hjj^LJIP679E$RruC&-Vp=RJlU5jyuKtK zccnULf!;Mrj#A#a`>K3juhmED_lqf%UJ&7g@26tId!oeCA7Vxs$GCrz;AdevuRweUGH& zp7XjJ9GPn@KQ|WRO3Oc2{}V2Wgkw+WJO|{8o$6<5LT-|ZRv$M?$`$)ghMhJKzNglN z&nBAP4VqEr{#NC%Wn``?Q;OxOahR*WOnq=JXGi9mE2q%Uo+%^>I$C{96LhO~O@d*V zuRD*uqvcxT^upuqRg)=c*DI1k&OPXmNSu_EV_b#YwaIco#hl-aQsloVMfN-J1H^9TdHX9Z8Yw4^*^4P zpriWo?LP{97$ZTZ_R=rFDSMT7ue+-enrV)ZpI+{ zDKW@Vs%Y<_HSTluKbo4Lr*|ycQvBD^zqF^9+T?FkB!BGNEY*pir`1Q5H9>H{sOuK| ztL46oX4KjLpkn(D`g46ZSCGP@zdM!k&-uOEx0QJ^ZmRH|x0EM2JRk!&U&()!b)p}9 zY4_#5F;-S4!a&N6*LNM!>Vw}qrrQEqMERv~EkZjr4USynUJoel6FJ_8y2K;FA zObv0Z;$wcQg91IRKJF;6(}uZ+m*zZ0Gl=v*rTD7*`+2QCnD^?Dd{T$_T%_ws z6zE7CvTvUR`y474MRLgXy9mCo*5;WyhY5<0H&Y!H=xN`RUR_|P4IhL7Y0mtPeOb*& z=-*oL!}}BOQ*|U(AN(ClT^Rxg5(n(NIKlbu5qmz@v_g(R5N!^}WJ)0R?2sB_+en@p zr8-gc`bT^puhZuY&j*SR z-tYNdvuW7?0i@56eSEg6E9=97=AZqkvJ@1x>upS`6Ge~TA80x5s@SA-^WG!*P5pk0 z`xEW`$%vE$3Up%i@koJf$}oLM^XK0JteWBgI=3r6=r;!kDQRfyJKqzmoZ=v&b27#x zj$B{FwA;{iim#d7G|P2dsQBgHnQK^8845!;PyhHX`ct0mw7TtpeVIL)mVc~1nD2I) zVM702(DCQ&x9?7{cPfWO{P6d^Ro(|W->FCL1^xW}_QX^tf?jX*y%6!uIAvrQl>OZN z_TVy(JYC+G_%6lw<=R!B&7J!mXlQHC!A>c1{3XU*F8=X~h)tQHqWZWW&Z_KT_}=y* zz|Yxlr_9~WgT9`R_~QPvY1teB{QUj)YZ&WaF@Z@Dzb-~u*Ygygv(R7VvmCGZV}9QP z>dKjL;O6Qdrx!Tped}$-cKZU`)ZwD~V7^xYtn)I$??L^!`t5&Vtn8Zq-H1Q>o(Po9 z5hiV`@t;JQ0X=^netR~?SjS~#ER?n1-1@%D_@r*^zI|3nXT0aU1^D^6_Os~cy``>f z3^E=j2m=6n;dW!sjr4&lURe&u3zM zP-rNe^Y3)_1vsYX{-pLJ(BZ!2NPxNWbLLue2Eh1y_Vew2hVxXp6pFrW*nR`!-0y7z zkQWNqSbmqZ8^Ezwfza-C^nD=oQ?H7w0;A`FFpfLt=X4sd6|fvYVV8lj896l7#ntu5FY*XO>9*GV1O z1;%A!`th|kuT4HDr$`?tX=|P2pSc#@C*Fh3c7V2z!B8dH5>{^lQeI&n*Nmb(oz1h* zW&Pz8zRQ%ZclL2C6s?|k56>xDeVl?Iyk_nJ94~c_{I255Kn~d%PIyh%$tScuutZ{9 zyZ)9bKKIz%>ruGggn9A2jwY;VLq`tqxM{Z7e51kE2@v8LQ3SVVpWhl=8s>E_OufTq2XHdS2asA=3Q>F4@ z16aFntgG9I=1;QAI5zMI(rH~<(0@ZLBS;5xXZ zh0k+Cfc=0&fy04s0DNv42=oA&67sS=z~`A!0C{2D{yZfW!r#eYhS=W9Os43DN4~h9-iUPn7|ykHyq*Z!XmU_W_qGW1B8E&)U-J=0K=t|pMoQ5^>68fZf3gf$)W<9g| z$Vz8rXI39wsXGRzVSPyF{C>S(SJSL#Rv%gEtnAF{qbqf*;8eO-gf((YSF`MARv+0Z zt>n<^qdRTW(G}K1cwXgu-R_a}9;*+Xn^ulkeROA=-ywzd;Ge&Naen9Cq*#44$!@xD ztB>wn^+p$Kz^@6veR+42>^)W=*(t5$(CR~`?Fw}JHQ~4UJB6mj>Z56f)BIa~$UJR> z?)wBxlhw2LT76`vw30)sk4m&PZe;b*IK@c;tUi)xYPpitN6RS}16qBEv@G#XzGHq` zfdBVVOFYTXK>`~KpMm>aJ_pmcDH;RDfH7bU7z4(DF<=ZB1IBX8( nfH7bU7z4(DF<=ZB1IBX8(fH7bUkb(aJ?X9&q literal 0 HcmV?d00001 diff --git a/Engine/lib/sdl/test/testgles2_sdf_img_sdf.bmp b/Engine/lib/sdl/test/testgles2_sdf_img_sdf.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5f983d2d211509e9e91e4e65e173d78c1a9d64cb GIT binary patch literal 72202 zcmeI&2Y6If-uUsgUef zcmKokHe2a$mJ4wP-o(*Z>2GcSwhEt#P5--|!<6#xzy0mM|KquTw;eL*n3T%gVJ-r> z2;?I0pBe!-w3VCur}Z(lZ<#jU71`g^wpV03%j?;x{dGS7jClDjo1A7LHp*2JGt z9Csd?>y!0f=k?9qWB=DcY6=w(mX0(s4T8E^z!^k=k}QzS}4JX1nIl)+oS+O~+ArWxfUX z7|W$uS8F!4<@`IhK66*>3FDI5U*|I{UhS!K%=X>=Xl1mdmTPtCC731kXY(6-D2f;R*>yy`cz3gAuJ%>@(1AD+VWS%;9@3)O(a3cDkANn`( zyXQ+`jBLX^at&?^*X6Rl58NMp&Nk=-`*;8j!4WtXC!sG=`{wb=B?By7a z5x5kWHGTU1B3K{9z?eCA-C)kP#X4A;;`?A5_#AW4`8CGRRx=elSnQU;+{muA*)foHN@#0M60cSk|&G4{%@Tj+1c?E=O~H zvfk^w{%qJk`gE$H9voVR}!aNOSGIPIfjbdHaLu{B4w zz^brp2>WgS9Y@fB^tSzOpKSMPm_rv~2>Qckc+R>^^I^=bH~;LT`Pdoe zXQq(E7I^2xgFd4=v;P=#c8QVA_z+!u^P2@ZhmZH={% zURL3Rbb%&tzDowdebwih6UO>pIQ}X;h19+U{d<9brI2@1dUyms;W{%tOr?>5Q+cj?H&RsB%ZF4wWN5(cRuRL!oC!ieWqj|YC%+sK( z#6bZH;cv3u=nHeuvAKqBg3q$Q58*L9joC0x0lynB$78&VZ4%yl3lbQO3vnilSugB~ zZLlU%OKZN^FXK88=9bTLu3kk=glg*SgE{Fq`eA?k9jjq!%NpF+0o`#5E`_;dOkPG* zpRD&fuXjIs6k+$gNS(2E&Tqs$Fc+T1D|i#{V*x(KCrzJze-HnJF_?u1Vg8u+mtiQ( z2glGEn_wkmDr<3aTkMX*&=2RpdAtEWcP7k-d3YVQNbg(FzmKT1e{aESy~mt!9o&bB zFz3$4$v6PU+kV>L<1qw|!|~h+$LBa5ujBUlsd2GwzuPCFJHdV*gF$e;Iwr^F7=wAVzi;3je26;O*MQ$WpBk^1_-+n7 zhUswp=0_YC;dJ!IuGkEzWnI1)N9%`T0(^#J`w9&aKBevj7_TcZ80Le|TMtWHHsD70 zO#3th#wiK&e<7m!WWCoJQ~PBueTGc;)Ny_eoM-dpIn0N7QI8++FZ?@$Upe@`~4%l z_H)=r^XdhdCyv?t7=pvG6T0I>oQ<(CH>YD39N!1{5{}#PXKFiWcMoE&1J;o`4uGM+Ka3$L1JqcL99ncla5+m+*7hGGe&wFq^hQmGYKy<*G2#Wo*f4wmjj>GXdE@P6Z{oveU>TB>IY^NN@ z!ra&#OIx<$#=UVohQU}l9%E!|g7!0gnmaGzKDY*};rwN~*7L^8Iq>r%e2cKSXL^R` zoC{<1K5W~*PDUK(z9`oz!nu0__Ui-q{9h2(hvv>N;a+pt zJ#ap%a1$=Tao8XB)Baw8N$`EWC31-<9QQ5BGWzg&wQ#x0x^`J z2>B>LC%EoUf_)u_+fWJjL!a*$8({mH+R65u>&tQ5|2N>ex))bs2%IzfwjP4gngi$g zU<||WLH-L}UXXlcpghV9S;1276xFbf|dD%aEdljQnp z)FaavoY%KdgN0~mzNA0X_OFT=!=qj>&ig&a?U9`fW+yvbpv*p6Nbo{~yK;I1fi-S8Rl!tir+8=!%nY5pIV0 z@D_eRRGZHCJor8sk24Xh+x0naX|ZqS*x_(~ufqK>USA@rFOIne55l}m!u#rx>Av4N z?>ou4_BhiuEj?%Md&=Z1 z@Dy&vaGZ!i7zNMSZ~Ol#!g9a4b~4pF4-1f~&T|cL{wk3`3?(SSw%7;mOP&wby?Gk+ z^=FR5p1rK+8+mpu+-E9Kj#6|%0aA1~)Uu?S)#>Kqt3*X(_ zp)K}?`EfR`#NC*Mx8dFp)yC4+{l;@Yz*D#t!_gP+qxRGOz69U1j$>)t3A^vBh-aEh zHLwo}#884Fn4j)PWf+CqU|zVE+`pC}tj*2v*M-Ih681G4V9R8;G8tKnlUf+M?*&pC3 z7^mUzcYwbw+=u4CdgIxWHnWXS)EqX@W(_KlKnx`)g8NWkq^^7C_EW5gb)PIm#sLlH;%_JRKRzR@16#vKR@;R7u36_O~X|f0^_g~Hbl0?ez^}FfwOQm z9>B|p+SlyMBDh!0z%_^?31eQ5)c$63?7Pr5ov#H=>iGN|-@*K8?m3IO#`W zXdAZsF%~rO*nBW&enZgLY(BlG29-!4h7!2{xDWZ=eaUtI9Ne#dMmEp(cWVR8lOR@p znj6N;IrUj#^J=VXQH2VWqZD0Gfb_BfCw4?{oQd(c5A(1PQGGV9&V#?ZZ^Q*S0efRB zWK&k=qOH*tC&7K_W|)h$_z_`!Fa~vSZ@mj+5JwW`s4)w>H~qZtE5~b_uH)x1tI2FW zU&Nd68s{ke{`BvzM`LI#&4r;j9K{%j(YOP)@jkN2kDs{C_TRzlaE$g#9=oqNAMe5T z%@@aI-^}q3@Dy&va0GKbm*Y zf&!$MH8{~8zE|!0NZbzN?z}|hj_rPg*|-CvFaSNVJzAr=vNjiV#K9N{*Mw`s`Kd!N zu1udlQ19G63fG`(F^(k6uX<#!%Wnmx!(X^aZNSs?*tf&Bd{|z!aB{^gnIjS6wXEhL7pw*I4owK{}SnK z$2pg5I$zIc)crx-LasCR#@4;$YK+E6jKF1ZPA9>9c@4H5+@I<559;eM2d+(@cRKpP zXWoVy_+%%^S{@dmxjDayb4SmrE{c#qIi*1>s@8TzfJ=gQL?_9VKx<+Ft z!xb>TFW@soJ;OS$aXhZ28*v%V!C(w*;&X?h9GAepUWZAzA2X4Jxp^tBg!$uhzeH3Y zoCnv2<2LVnwlO*teVUxY=MdPo`Rkb7@3R?S1J~7{5(&gm0{0*Hp}Q~#b@&}&eYNfr z%)@jTtIJ_b&O{I^KaH3DJr@_j{4plpb0_S}Gk6xk9%5g-_YmxWwUMc`;^em2560(W zxW_$#cMz4=e^6fs+qECIX&idB&>*fKi@WhWj7wPDJl}vf@GvSc48|yqB&t!5sApLB z1)O(tYXZ!Z?p?{k;s1%Qnpy^WF32ysQAEuIFn}4&%`S zU7H-p=Mix3U9a{voBXj|=duRIB!L(XZ~CGw8RKv^eAYhL8ml0zY(hmB_0) z-LM}H#jzNGq3}Lq)E~oPzC8)wJHH~T4na8aVd}#9-ft!F|Z};hypXqMq|9^>c9#%n8SBe~eX8h+R3qH+rB1uC0M6$4Fd? zi(u@mb8j{7>mjPFO{H^UoP3^fy9>s#4!(!N#_|(&=7u?P3nnb3+qlm;eiuI@ti4~T zGY_7Ec{&p2Ng3iuq8jxGdxqz2Bk1={9A5xqW_-8AN>~|f;G9_JHD3EDYT?+U+Hj7a zhp`-uk(i8Ga4r9iu=|%#_aUCaWH`5{!nrR*KGtZ`nos9=6Ko6jfW6QYy>U2t!8rMx zDR>rj2y5T-#@hLK9L}w4@g(evwpaz0bzq(q!~7YGyD=9F5!FTm^);wO0x|T#CAb|= z;{zCvu;&E*e3EN!h4=PF$x=G5>HdCvo(SW25cY=S+!VpsIs9M6ylIQBFkTnoW|%i` zp}D=`W3G7))0dI){}f?y^ZYk>9W&uO&3Bu7b{XPGq8jyxdd_#$&&PxCIqs{zpLfAV z2+D>W?2IFD7M$}Lun*rNsttb=z69T+_H8t#!Zr38qV9FA8hiKW8!-&dv+sc|5LQ;D zA|G2}dlX?OxVBD%du6t{{yo>efroHC&c)H#6&oWc=GHdYALiglOvY?1K-4%JsINgK z5{ThcT#h?oUVVb7XQa;MbzEydea`YSgl8GMW6=Xe*aT6ffXZE9-q?=`xF6=`mxvnA z*VMnZ9MtfP=5jPxyXK|);2<1=GMKYT*ynmg_1Sg#DjtAi9fDrygmn>=wK#B3vW>wQ zkD!gOIBu?u*SKanCg2L(hnLV?Oc!&FYqk;zxRwuxYhwdsQ}VbdAB8AJ8RAI7K757d z`frSa{tw}}H#)=Trj{-F;{NS^J{%L_`{I2pL0CHt)YYI83B)i6<8UwL;R}S_@A*Y| z8Ro0cSl*mF*Y`O%8Qswl>msbQreb@zj}5>mOu;OCh^Uw}QvdC8@+;2?i`|dZ)#5P( zzdsybdahJ+t{!2}@x1k3mqZ+8C`KWSMNn4fpaYDHd(;@*jTf*GQEdeK=1i`;23Nv4 ze+6G7>fUyskHI(;J78^OTfFukI1FdvDm;K}`%ulbNyJfxVick^Qj5QV_JHru z3ve@>r+4rR!p7P_T@5PXI*8#6T#5T(KNlhFe$Tr%y$GMNA{ej9a30P^DVqD8z$O3n z8^Jy1cnm`Y9)|Dy21JeN&!}@heHo7LYMg~5;T${HaU@ZVdPMc<3+m_L9*o85=!p(k z13~e(%(gfHr(hKB#2hsDJLCth`6nL2^{~$~@H!SFoBp{+kHbJ5gzc~}=GQ^QYHR=)7?&s9MfV(jUr=bVhV>JY2B@VX6e&~lwF$K?}4pD6ce*-pKH+mg?PMJPcG2~?s64alYsQ@L(52B14K^`U_C zT~La0RGyMFeO+JP95cS@U8t?L``;PYA>&?v@;cto)un!zt8RAHy8uf^3*BH&kRE)*|bVob1 zLTYKlm#*l85txKoSb%>=FptcqDpbJVd^0g0jwkBgh1Ac*RE)*|bVob1Lbhc+F5D4^ z<1Ac*nV667u)O+Ez_Yrb6y>Nu6>8Cluy$MrHK;@aF`R{KFcb6f9m4MaGtMufecw^j z;5%k84naq>MpW6H%01wF`#f9+$K`wX8~hpl&(y}}wCx_@dhxfle;b#;zt4+NhB&OR zMm;h;Cpfo|`ni~j(HMa4XoprvEp7PH6@4%QlQ0Vl@CW`K;%CmkjYn}Ku7Rv7?ZI2>o;8qCCee23-LhXS6}1*IrQ1*%YsMufG~KwS+g zkw6S*;Tp`ue0+zn`~Qsdi)jC4Ov88##v$m4)`%+kRCdClD8o41jpxza-wP{hY`@a> z`*<3Y;BPK}!xnwj&^8;)Y678UC{?4FbT7;0RN6) z9+^*7sDSxWi5fH@>fVLa&&5=X#sG9jJG4T!Wj!w35haKrflAb%0n4io1w5+@N>Ppq zRG}7)2y4ea*q2Hq5NqPG=W5V^u>1dv^NVQzWlY0(48|eoh}MWI&egWq4}EYkCgO3p z*G9!=MUBmWJ2b8j!oTawaV-2dmO>Px3~?k;je11&$M@X}aIYAH)6fI$u^NK15(itu zc=W@in1W~VF{0Y|iTbzTZ`2!bHD-Fgqk;&k*x2ds{4%eq|H8ND$S zS7QcV$6`eF;dAO=z}*;w)6fI$u^Lj#CVbf)&dV^|gvam>enD6}t`+CD5(&gG6jx&g zUdLjD-T!BtUqt&aV;aU|Fb+XSv_^Af6E5h2qu{>}I?m~M6^jrxhK1C(RCBriDbJjX zd*I)LgK-!-qY%X?LmWv|qaIQH{DS&I2jU=XhcytCRXO-O4uJ2(QMeP&;ZsDl z@dNe#&G!)e-8=ygz&L(`sC&Pn-f=jdILc6rLS!?CT=rjO9sau$dSM7Ape22HiRYku>Td@35`XiW|JkVJI`{FgxcEMFk8^Hr#U<#A z{b8OvCdXEWIFhJFJ;I*pdF#C{i8x%Nhrn^SMo?T^uCbml7GrS_Ucl#wYNLVr8dTyM z*pBU0qaIQBenb7Mm=4!~YoRyXL-LVraV(DM5Ddn6OvB4qgs47P?{)XXzgf?~VfY8u zMrvupmwjiJ*teEV@9uD~E1 zjP0=|nky@FL0cG~6LBGKhJRQ4`^9}Xto_u#b*6G%6!-Y%elt0z=G6?Cljq=Q?1oKI zh+>o>jwGs4kFY*^{u{i8AYX@aoGD+|;k@~CD9oqvmeF1A*!^daszDK#QoqP48%CNAI!rSh>B5at{eNaa0GUS&ku_4 z@NIDb`r|U(foy&gr?wHSr_;E149p$(n*V#^QAJLv>YjMyK2V)S%;U3I`xfs<(1NFwzd`KXMez+8qF&hgI^^9O|G*&J3I`=d;kDqdl z@iGT5hjBa*?a&I@lsqol4m~gcqhKz~g75Gp2peMqb#LGy+<^1pGvsdpf44me^W|rR zJ?97N-om4}85iLsbj8-NkA)~k8RAHy8ubW!uIGP&?LUrN5Ioy=vd_+k>vbF0p6z;# z*FJ`K(1@ru%va~(PB;(45sdvkj(V-;6B#|n_yFHh4v`IUg!z;!DE_~ z@Yx-GVEk{#({LVtLs%b{G+pxypOY{W{b4S3fblU-o54NjNSuWPro(r$xgPd>&o`h3 zmGHh8PCyWA=f_z8g0Sb9CvV~rI6v8Xh-?1|_tvmy|3TdX%)(@hL|^O&^JFDtTejrF zy>UE-p#l%XwbFpFKKzTi4-m}5r5vAv!Em2;@0yEG5%vtve+k!y@5Ko))<<9$6d(_U zC`K9LNTM3`h=p2BUo80Bz( zF^0{}qt7)L-9I0M_g#p-D8@e6y~)0Ox?XzWI1GTXIv=(<6#ZbG^LP{7qiXRJ!p7kF zg_wu?;BSo~a1Qo>@i9)us3&a0ao&Q*kj?YWqZ(8qff$a)xwsCFeLfZ=te@@)A7U1! zU=)m182dO8PvBkrg0N>>=QWSRakP7 za6TQg`FSMVlbsuLdL~}OA_ULL^!YvYZ{iVnpJN|_t1u1r(fuORy}`L(sW%4C;%<1a zYveSXh+~_a#OJ9n#@1hk3AhmzF#hI&@eAG`j@fa1gP^@kpAFRi6IHkwm%#RqLN6F6 zV4_Q#`0xM$F&#+`*eJop?vqb z_rN}Wf~bA*JL=!SLoj#GgX8Uj0<@&8!Nu)yAk3+exE)X7Jw&bRpdSx&opb8=Mq(14 z#``c|(&G|*Z=lX`q~33A+!wZlB@cxtMj7Hrq8jxGo)z}_GuPOUS-2a{=Lnb=#(fCR z#>KcA&cSSafT*$Cp7U!ze7BloKFfS|@4N%E@ezJQSpPh4zMIca;4WN)%P}0rRQAv3 zj)!Y^GHlm1@CeLrbIko>5XQl=%*AJjYX5iYT^BFFec(E{ri_bYGET%680l}I3l5}0q7ViKN4bNSN9HSgjXOvMBkqoAKY*S%&8ZiTUV1K%R5kIv&u zaO}Z*p%=%Uk&l*^&ADL@90S*;@tld*;arFHWeIg3ViqRjGC1Ga?l%j$c3#u<-ggEZ zM-kSCB@cxtMj7Hrq8jxG>s#viuer{Abx{u$u)nk5S{w`4 z(QruzBq5G{k(zi&WAB_jeLTrJ}#mDL(D?zJoeyw2dsgX zmV9pLghNq=akv}L!~O(g$@FO+*l*|HN>t!sG?z!eaLs#o3eNio^uqyYht*-pLm`S` z-{MH38uiH3r}T5?tJl`z1(*-Udj_UsCLV+1H9xa??zdcL{ySF3JPaqmJUJ8Y56<^o z7(@Gz-mlc}K_AWim+>sj8T%!VJ!hNb6 zemWn|z%kdM5n<2re5QFkp7VQSD=bZE#ZB8{KlH)Hm3 zuK6VhyDw7?lyd#<*bG6*hK)y!4)_Iy>TG=;S$_}D%h6umimmaV`Kdl>hM0yZ+UG0zJPs9%{kvaj_FAR zd(%LU$KX!Pg6r=WgtZ%-cRpSJ#>2Q6ALHa0Y{R;2ViY{jPp_{*B@&3C1l@2FE`)oM zYu2{1nb*Z!XFSsT={j?)uDM^4+K=>O_k%hF^BCtin8zJC-T+HmHsQuDI0|ROaZkr9 zh#H@La!;9sDYzfia6IY#PyKEz9LH3Q#ULDle_&k%C69wb6r&7rBvFleq&_qC_>YJ> z^UAz&PR#QLG$Qr>sN+RkTLbsPn=l-Gus@99kr)c!QNHJ&g>&4JHtfIa*0o}PJ&x+r zXVm*%xfjOBycmY-F%!sde_%xELSfWW4N0>NVLO`yAs{i3DOO!A|In!7vA0 z`_I62`vbChetJK>FLkepdWQK^gG}?-j`OQyY0KK&*bxWgbc}}MGZz-%cZBuLwPSv} zma6b3qT=x*^|g2m?&0R+$>@e{uquL*$3Y>AQHD5@s75`)`V`gQuzRvO@3@@rS-1=1 za3&7NF6e**&oh7uH^8%}`zy%y$>`@#aamn^UTr9a30;T^bsGtJ{BoL`o*GB>xyzBm!) z!c7R)hwZ2LDfn)kYshP}S$|(~-OG3YSK}-kiCwWVQcE6R3Q>$Q#F0cb>JjuI)93Qe zokrUG2+p_j?)(pfzghN!dz$mGGkU>%9)(-+2wsKnk>-AfWEx9z=X`&Ch*_8d+Z}*& zVT|v?b9f)_3C%sPCH1x)73&7-Yfy;=+B!Zf^usNZkC3l`v6yn?7a|BZUbG8=c`a-4>P zP>8jVTJref`C^nIjwGs4kFfatL0ughBCZL$H`96Nz%jmvnQ-1m!oHgiJHq(+8(|yl zjZzp#-(i#Beq(&h6Q7r`M6F?2qB7fWO~gfa@-5e{4w~+#B2@zC+l3 z&Or?-kw6S3D8g3Q1Ma71U^H&S!+06XJ67%`=3g+6zB5L^_3S*_C+Bf_lsq1?9eUtY zT!zV*1?RwhC@f~?wz*P^s9Z7b|HLD>5f|VD?1MH~38}?C6`~krh$D$=)FZ4vp8o{z z;+tl!i+YB2?!6yi9^5-8!hOK`HxJB*Hdqywd~A>XaXik(6_^C`#JPMQU&H;Sx%RWE zcWxHJci;oK3PaEv192(Lof&XnehPjJCY zKv>^hLvN!F_C4&nz?ToYHqIWNIZ*bwO@j}wI`Mj7Hrq8jxGYsd4S!rwUd-Q({O zb$xo>k6gbHZ($D1Mdx5N>~|@;!hBc@sbwR+`~%%_BF=_+G7&y!Hs+%a&hxKGZ$F#w zjofD(+;e^2Gq@9D;5s@ON5PzNe{@YffZ1>z1aXO)v-E!0=9h53U%;C%R_WIT-_4sE zR3d>GN>GG+tdEX30Pa6$!TtxaGWJ1VzvK9K1kY~n(`&uQaheCuVmfYyd*YdJ9`{8% zq|YO#mZ>;4$Jq;KU_9=_JeXTi{rBDcRm3&sjQhjWm<0FCQ((?@z?w)ed7LOjG0G4} z64j_jRDV9B{&_qK`|rB2kBjgj_~tmxX)Vu32N~Y9>=|?fH~Vi@N-nA5M|Sv-upaShIg z>$oe-m7_5jBVqeq_b5{1Vmxj8XV_j47uz*1_RYL}2QT9(RKYme->|u8pw2N?B7qo6 zP=tI~+<$h!0XPoEY7}n3JqY^xCdUil_+2MKoPxgEZ_hQrHSe|Ft-*tEPRnsD_QV#*RPs1kh+>o> zjwGs4kFd5p{~4agUGSdA@EpuP_dD~#JpQ2R)9;?Q-s`;nemMTCa1jQ<-0X%zY>2S3 z5)~WcA8_q?pYMzda0PCH^J_ee?_9hJ`|vi5chEnN?Vq{vI$pvYxYm8&-H8gs;qy<$ zAuwmRgKO$YoQ?}|C2qwum}idHHSz|6w$tNc-|XWPn2yP)LM<8*HW%i$^InMrVkkio z@)48*4t9XCDuuB&=Js_WoWm+Si)zeAEsRajSC2hso!88U_uL1cF&>WJc{mDPu{}1x ziYlA&;5~2*&ck(>3Fq+}gvISg>i!i`|0#9Ohx^SH7>vWv8S5ca$>U@picy9*lBh;K z!usO*g|NM;n1Ea0+Ij#F!S(Va%w<3Q{xGcf9EhjF+bu36Vs&^L4Z2?YJ~*#13&N*DvzkbO*GG%my$@cDBR$C_xeOky?zE`E87i zbzgY>2)M3p!X0oQa38XLV-w7w$M)Ykukl*%@m`UXX2eg}^CR$PL<*dKq#YRFXbI9Z5d*q1nxs75`)`r`S8mHnNI0bWP%sgkE zF&YK$@m`W55qC&2iHWAB(XsTu1G&F>Eij z_2I2I^{1i3DOOK@swisTgDP z!oHd#-QgbOcpdkdFo#m(WS@hIBZ+F%BfYKE?+dA)i>Vlm0XPV~;aWZp z#@adZ)9;>lt`9~x?21BciFL6&itmh#@pp8_9&l~hrhPN!$KrU{x1fKXD}}jnC|nP& zA^YfBZ;Or4T%N4WHJih{a$R?Ydq!&8QE{;k<)}avYSD<)*ry&hP*;OWBoIRhija?} zvKE#0wF7p>K5*Q<;68E;f;ib{k3DCddzIIEkM}y>&EPZt>|)HFBj@;Zn2&ejSuDWs zNR3(4@ef@479PdTxCkeqE4Ice2rGG1n9s#1LmWv|qaIQ1E~I`gro#RYKzBHg=Ae1J z7xr%Y^taJt*a7X)1_f}wqT)#P z|0=CHg@~+b=~qDo}-5G$L#+8mOy5B@&3C1VzY4HYJaX+$$WfYpWB2 zz6No!&mQjv*N@kD?N;z!pYeZHR;J;$aQ}0Eybw3R_`Qkm5f;Dn^IvjpHSWg*7*Bs^ z7>@!(6=P6{Vw53{B&t!5^tMvJFQk4hreZV(pgY>Z_-=~Lu|?CT-#zafn`_44&nm8k zJlOVza2;<3`Tv^gHK;@a zF_fSP`DkfbgB#XCrZ^chV`tsE@Y?^BVr*UK{=OKBt1t~O;R~e3EbMp**L{dtn1WF- zuY1Bh(Hx2@))%4}Wr!n*YSbgFUC%GXTujAi3_y3ZLo4J;%OX&~cFqa9iyS6UW<0xs`@Qk0_tRj5TH!seoZx*Aj>ff!0qgnay!iaBroxdvPd zt_j!1Q+N-*AS{kwQ}-GwaV^e8DRzf{H)d1vxTp}tC_@}cRHGhYZF_zp=3**FV*t9N z9a8upAYrLM<8*HWv-l)xbPRAchhYAs>IWV(z;JO5vJtZOnvgWg)%{ z@e${r!&HpLARK~!z<+zmrsQ!^A&OCkIFhJFJ;LTNx1I>jaxMituM5nBa#WxSwP-}x zTr^NugGwY2LkWtIkH10<9Ol*&!CB6wfai5VDauiSD%7G8VRO+yT@5OcKnx`)LO%X##oTudbj1lc z4_D%L+ynof%Eb4QYw25jKap^+a%%b1C3?T~La0 zRGtL3hSM=!3H{627a(g&4zm-%GBgW6%}t;Qw}* zZSmUeVY>riTdraMJ>+97is0|fIk*#}a4HVO-?1ukrDYNDe~)xOJPPOHdIbO0`xVDw zbMZNKFXI7Bz!3C;`IPPNelGq0s;tatHpforfl~B`IUeRT>imu8d&#xrx>z4ADdzpQ z*dP9T$R(JFhv9Ec=PArw>ioTVBQC^=*cWY(D=m+J?-JL5Yr%i(y#oFQ@!zKWy%07J zFH!dxCgXCL7YD(7$irW?nA@A8Blf@nFfL(wQr8W;!1q#1*Alnpd`>y&swu{h#x~<{gOKW0j%Uay%vz*7{F%%=<{^%Tq8Asj4a4+?J>buE4uYp`y zx(F0-+m1K{{ZS70tFSrnd>og-zY$!A{=V4(>mgVECjzT-Xl{maKU?{KE?=f2-zm<4 zYw9RCmxC}kg7tlI1cKk2xj7^l%TQWz?^f6q2gChs0HWrhjQUgH-_Wil*Q38Va^?Rv z0INz?nE?Ab|o7|o&DG_l0+yb58?>5&+)I2y(-LWS+!nL#ta^?R% z0{-^f4E}B_g!2<-d+N4@^OuKQS$+}lcZYuu`!|rk#lz;n^UhOyxCZ@OAy@wMBH-^1 z*GTIK*87_@S5|BU{9PY457w==V!M!gdM*OF2;?G=i$E>{xd`MUkc&Vr0=Wp}B9Mzf zE&{m-{xd`MUkc&Vr0=Wp}B9MzfE&{m-{xd{CK7J>f<{G2Sw literal 0 HcmV?d00001 diff --git a/Engine/lib/sdl/test/testhaptic.c b/Engine/lib/sdl/test/testhaptic.c index 9613629e2..9b73ce293 100644 --- a/Engine/lib/sdl/test/testhaptic.c +++ b/Engine/lib/sdl/test/testhaptic.c @@ -14,10 +14,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND /* * includes */ -#include -#include /* strstr */ -#include /* isdigit */ - #include "SDL.h" #ifndef SDL_HAPTIC_DISABLED @@ -29,7 +25,7 @@ static SDL_Haptic *haptic; * prototypes */ static void abort_execution(void); -static void HapticPrintSupported(SDL_Haptic * haptic); +static void HapticPrintSupported(SDL_Haptic *); /** @@ -55,7 +51,7 @@ main(int argc, char **argv) index = -1; if (argc > 1) { name = argv[1]; - if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) { + if ((SDL_strcmp(name, "--help") == 0) || (SDL_strcmp(name, "-h") == 0)) { SDL_Log("USAGE: %s [device]\n" "If device is a two-digit number it'll use it as an index, otherwise\n" "it'll use it as if it were part of the device's name.\n", @@ -63,9 +59,9 @@ main(int argc, char **argv) return 0; } - i = strlen(name); - if ((i < 3) && isdigit(name[0]) && ((i == 1) || isdigit(name[1]))) { - index = atoi(name); + i = SDL_strlen(name); + if ((i < 3) && SDL_isdigit(name[0]) && ((i == 1) || SDL_isdigit(name[1]))) { + index = SDL_atoi(name); name = NULL; } } @@ -82,7 +78,7 @@ main(int argc, char **argv) /* Try to find matching device */ else { for (i = 0; i < SDL_NumHaptics(); i++) { - if (strstr(SDL_HapticName(i), name) != NULL) + if (SDL_strstr(SDL_HapticName(i), name) != NULL) break; } @@ -110,7 +106,7 @@ main(int argc, char **argv) SDL_ClearError(); /* Create effects. */ - memset(&efx, 0, sizeof(efx)); + SDL_memset(&efx, 0, sizeof(efx)); nefx = 0; supported = SDL_HapticQuery(haptic); @@ -314,13 +310,13 @@ abort_execution(void) * Displays information about the haptic device. */ static void -HapticPrintSupported(SDL_Haptic * haptic) +HapticPrintSupported(SDL_Haptic * ptr) { unsigned int supported; - supported = SDL_HapticQuery(haptic); + supported = SDL_HapticQuery(ptr); SDL_Log(" Supported effects [%d effects, %d playing]:\n", - SDL_HapticNumEffects(haptic), SDL_HapticNumEffectsPlaying(haptic)); + SDL_HapticNumEffects(ptr), SDL_HapticNumEffectsPlaying(ptr)); if (supported & SDL_HAPTIC_CONSTANT) SDL_Log(" constant\n"); if (supported & SDL_HAPTIC_SINE) diff --git a/Engine/lib/sdl/test/testhotplug.c b/Engine/lib/sdl/test/testhotplug.c index 014c08fb3..465fb5680 100644 --- a/Engine/lib/sdl/test/testhotplug.c +++ b/Engine/lib/sdl/test/testhotplug.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testiconv.c b/Engine/lib/sdl/test/testiconv.c index 41666f36e..bf9ad3b92 100644 --- a/Engine/lib/sdl/test/testiconv.c +++ b/Engine/lib/sdl/test/testiconv.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -42,6 +42,8 @@ main(int argc, char *argv[]) "UCS4", "UCS-4", }; + + const char * fname; char buffer[BUFSIZ]; char *ucs4; char *test[2]; @@ -52,12 +54,10 @@ main(int argc, char *argv[]) /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - if (!argv[1]) { - argv[1] = "utf8.txt"; - } - file = fopen(argv[1], "rb"); + fname = (argc < 2) ? "utf8.txt" : argv[1]; + file = fopen(fname, "rb"); if (!file) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to open %s\n", argv[1]); + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to open %s\n", fname); return (1); } diff --git a/Engine/lib/sdl/test/testime.c b/Engine/lib/sdl/test/testime.c index 1a6ecde36..5541d484f 100644 --- a/Engine/lib/sdl/test/testime.c +++ b/Engine/lib/sdl/test/testime.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,7 +35,7 @@ #define DEFAULT_FONT "NoDefaultFont.ttf" #endif #else -#define DEFAULT_FONT "unifont-9.0.02.hex" +#define DEFAULT_FONT "unifont-13.0.06.hex" #endif #define MAX_TEXT_LENGTH 256 @@ -648,12 +648,12 @@ int main(int argc, char *argv[]) } for (argc--, argv++; argc > 0; argc--, argv++) { - if (strcmp(argv[0], "--help") == 0) { + if (SDL_strcmp(argv[0], "--help") == 0) { usage(); return 0; } - else if (strcmp(argv[0], "--font") == 0) + else if (SDL_strcmp(argv[0], "--font") == 0) { argc--; argv++; diff --git a/Engine/lib/sdl/test/testintersections.c b/Engine/lib/sdl/test/testintersections.c index 7e06c9ab8..ff629f526 100644 --- a/Engine/lib/sdl/test/testintersections.c +++ b/Engine/lib/sdl/test/testintersections.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testjoystick.c b/Engine/lib/sdl/test/testjoystick.c index f838af740..db9a3a156 100644 --- a/Engine/lib/sdl/test/testjoystick.c +++ b/Engine/lib/sdl/test/testjoystick.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -38,14 +38,14 @@ static SDL_Joystick *joystick = NULL; static SDL_bool done = SDL_FALSE; static void -PrintJoystick(SDL_Joystick *joystick) +PrintJoystick(SDL_Joystick *joy) { const char *type; char guid[64]; - SDL_assert(SDL_JoystickFromInstanceID(SDL_JoystickInstanceID(joystick)) == joystick); - SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), guid, sizeof (guid)); - switch (SDL_JoystickGetType(joystick)) { + SDL_assert(SDL_JoystickFromInstanceID(SDL_JoystickInstanceID(joy)) == joy); + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joy), guid, sizeof (guid)); + switch (SDL_JoystickGetType(joy)) { case SDL_JOYSTICK_TYPE_GAMECONTROLLER: type = "Game Controller"; break; @@ -78,21 +78,28 @@ PrintJoystick(SDL_Joystick *joystick) break; } SDL_Log("Joystick\n"); - SDL_Log(" name: %s\n", SDL_JoystickName(joystick)); - SDL_Log(" type: %s\n", type); - SDL_Log(" axes: %d\n", SDL_JoystickNumAxes(joystick)); - SDL_Log(" balls: %d\n", SDL_JoystickNumBalls(joystick)); - SDL_Log(" hats: %d\n", SDL_JoystickNumHats(joystick)); - SDL_Log(" buttons: %d\n", SDL_JoystickNumButtons(joystick)); - SDL_Log("instance id: %d\n", SDL_JoystickInstanceID(joystick)); - SDL_Log(" guid: %s\n", guid); - SDL_Log(" VID/PID: 0x%.4x/0x%.4x\n", SDL_JoystickGetVendor(joystick), SDL_JoystickGetProduct(joystick)); + SDL_Log(" name: %s\n", SDL_JoystickName(joy)); + SDL_Log(" type: %s\n", type); + SDL_Log(" LED: %s\n", SDL_JoystickHasLED(joy) ? "yes" : "no"); + SDL_Log(" rumble: %s\n", SDL_JoystickHasRumble(joy) ? "yes" : "no"); + SDL_Log("trigger rumble: %s\n", SDL_JoystickHasRumbleTriggers(joy) ? "yes" : "no"); + SDL_Log(" axes: %d\n", SDL_JoystickNumAxes(joy)); + SDL_Log(" balls: %d\n", SDL_JoystickNumBalls(joy)); + SDL_Log(" hats: %d\n", SDL_JoystickNumHats(joy)); + SDL_Log(" buttons: %d\n", SDL_JoystickNumButtons(joy)); + SDL_Log(" instance id: %d\n", SDL_JoystickInstanceID(joy)); + SDL_Log(" guid: %s\n", guid); + SDL_Log(" VID/PID: 0x%.4x/0x%.4x\n", SDL_JoystickGetVendor(joy), SDL_JoystickGetProduct(joy)); } static void DrawRect(SDL_Renderer *r, const int x, const int y, const int w, const int h) { - const SDL_Rect area = { x, y, w, h }; + SDL_Rect area; + area.x = x; + area.y = y; + area.w = w; + area.h = h; SDL_RenderFillRect(r, &area); } @@ -179,7 +186,7 @@ loop(void *arg) (event.key.keysym.sym != SDLK_AC_BACK)) { break; } - /* Fall through to signal quit */ + SDL_FALLTHROUGH; case SDL_FINGERDOWN: case SDL_MOUSEBUTTONDOWN: case SDL_QUIT: diff --git a/Engine/lib/sdl/test/testkeys.c b/Engine/lib/sdl/test/testkeys.c index 9d6b109a3..7561eb041 100644 --- a/Engine/lib/sdl/test/testkeys.c +++ b/Engine/lib/sdl/test/testkeys.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testloadso.c b/Engine/lib/sdl/test/testloadso.c index 2a3579031..830352558 100644 --- a/Engine/lib/sdl/test/testloadso.c +++ b/Engine/lib/sdl/test/testloadso.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -44,7 +44,7 @@ main(int argc, char *argv[]) return 2; } - if (strcmp(argv[1], "--hello") == 0) { + if (SDL_strcmp(argv[1], "--hello") == 0) { hello = 1; libname = argv[2]; symname = "puts"; diff --git a/Engine/lib/sdl/test/testlocale.c b/Engine/lib/sdl/test/testlocale.c index 762e9c1bc..3a4a6f041 100644 --- a/Engine/lib/sdl/test/testlocale.c +++ b/Engine/lib/sdl/test/testlocale.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testlock.c b/Engine/lib/sdl/test/testlock.c index 2d35f7231..121059608 100644 --- a/Engine/lib/sdl/test/testlock.c +++ b/Engine/lib/sdl/test/testlock.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testmessage.c b/Engine/lib/sdl/test/testmessage.c index 295b24b70..5dd0155f7 100644 --- a/Engine/lib/sdl/test/testmessage.c +++ b/Engine/lib/sdl/test/testmessage.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -61,9 +61,9 @@ button_messagebox(void *eventNumber) if (success == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); if (eventNumber) { - SDL_UserEvent event; + SDL_Event event; event.type = (intptr_t)eventNumber; - SDL_PushEvent((SDL_Event*)&event); + SDL_PushEvent(&event); return 1; } else { quit(2); @@ -72,9 +72,9 @@ button_messagebox(void *eventNumber) SDL_Log("Pressed button: %d, %s\n", button, button == -1 ? "[closed]" : button == 1 ? "Cancel" : "OK"); if (eventNumber) { - SDL_UserEvent event; + SDL_Event event; event.type = (intptr_t)eventNumber; - SDL_PushEvent((SDL_Event*)&event); + SDL_PushEvent(&event); } return 0; @@ -189,9 +189,15 @@ main(int argc, char *argv[]) SDL_Event event; SDL_Window *window = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, 0); + /* On wayland, no window will actually show until something has + actually been displayed. + */ + SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0); + SDL_RenderPresent(renderer); + success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Simple MessageBox", - "This is a simple error MessageBox with a parent window", + "This is a simple error MessageBox with a parent window. Press a key or close the window after dismissing this messagebox.", window); if (success == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); diff --git a/Engine/lib/sdl/test/testmouse.c b/Engine/lib/sdl/test/testmouse.c new file mode 100644 index 000000000..c73adca51 --- /dev/null +++ b/Engine/lib/sdl/test/testmouse.c @@ -0,0 +1,197 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + +#include "SDL.h" + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include /* exit() */ + +#ifdef __IPHONEOS__ +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 480 +#else +#define SCREEN_WIDTH 640 +#define SCREEN_HEIGHT 480 +#endif + +static SDL_Window *window; + +typedef struct _Line { + struct _Line *next; + + int x1, y1, x2, y2; + Uint8 r, g, b; +} Line; + +static Line *active = NULL; +static Line *lines = NULL; +static int buttons = 0; + +static SDL_bool done = SDL_FALSE; + +void +DrawLine(SDL_Renderer * renderer, Line * line) +{ + SDL_SetRenderDrawColor(renderer, line->r, line->g, line->b, 255); + SDL_RenderDrawLine(renderer, line->x1, line->y1, line->x2, line->y2); +} + +void +DrawLines(SDL_Renderer * renderer) +{ + Line *next = lines; + while (next != NULL) { + DrawLine(renderer, next); + next = next->next; + } +} + +void +AppendLine(Line *line) +{ + if (lines) { + Line *next = lines; + while (next->next != NULL) { + next = next->next; + } + next->next = line; + } else { + lines = line; + } +} + +void +loop(void *arg) +{ + SDL_Renderer *renderer = (SDL_Renderer *)arg; + SDL_Event event; + + /* Check for events */ + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_MOUSEMOTION: + if (!active) + break; + + active->x2 = event.motion.x; + active->y2 = event.motion.y; + break; + + case SDL_MOUSEBUTTONDOWN: + if (!active) { + active = SDL_calloc(1, sizeof(*active)); + active->x1 = active->x2 = event.button.x; + active->y1 = active->y2 = event.button.y; + } + + switch (event.button.button) { + case SDL_BUTTON_LEFT: active->r = 255; buttons |= SDL_BUTTON_LMASK; break; + case SDL_BUTTON_MIDDLE: active->g = 255; buttons |= SDL_BUTTON_MMASK; break; + case SDL_BUTTON_RIGHT: active->b = 255; buttons |= SDL_BUTTON_RMASK; break; + case SDL_BUTTON_X1: active->r = 255; active->b = 255; buttons |= SDL_BUTTON_X1MASK; break; + case SDL_BUTTON_X2: active->g = 255; active->b = 255; buttons |= SDL_BUTTON_X2MASK; break; + } + break; + case SDL_MOUSEBUTTONUP: + if (!active) + break; + + switch (event.button.button) { + case SDL_BUTTON_LEFT: buttons &= ~SDL_BUTTON_LMASK; break; + case SDL_BUTTON_MIDDLE: buttons &= ~SDL_BUTTON_MMASK; break; + case SDL_BUTTON_RIGHT: buttons &= ~SDL_BUTTON_RMASK; break; + case SDL_BUTTON_X1: buttons &= ~SDL_BUTTON_X1MASK; break; + case SDL_BUTTON_X2: buttons &= ~SDL_BUTTON_X2MASK; break; + } + + if (buttons == 0) { + AppendLine(active); + active = NULL; + } + break; + + case SDL_QUIT: + done = SDL_TRUE; + break; + + default: + break; + } + } + + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + + DrawLines(renderer); + if (active) + DrawLine(renderer, active); + + SDL_RenderPresent(renderer); + +#ifdef __EMSCRIPTEN__ + if (done) { + emscripten_cancel_main_loop(); + } +#endif +} + +int +main(int argc, char *argv[]) +{ + SDL_Renderer *renderer; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Initialize SDL (Note: video is required to start event loop) */ + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + + /* Create a window to display joystick axis position */ + window = SDL_CreateWindow("Mouse Test", SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, + SCREEN_HEIGHT, 0); + if (window == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError()); + return SDL_FALSE; + } + + renderer = SDL_CreateRenderer(window, -1, 0); + if (renderer == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError()); + SDL_DestroyWindow(window); + return SDL_FALSE; + } + + /* Main render loop */ +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop_arg(loop, renderer, 0, 1); +#else + while (!done) { + loop(renderer); + } +#endif + + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + + SDL_Quit(); + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/test/testmultiaudio.c b/Engine/lib/sdl/test/testmultiaudio.c index faf3d9da9..51a7ff03c 100644 --- a/Engine/lib/sdl/test/testmultiaudio.c +++ b/Engine/lib/sdl/test/testmultiaudio.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,20 +33,20 @@ callback_data cbd[64]; void SDLCALL play_through_once(void *arg, Uint8 * stream, int len) { - callback_data *cbd = (callback_data *) arg; - Uint8 *waveptr = sound + cbd->soundpos; - int waveleft = soundlen - cbd->soundpos; + callback_data *cbdata = (callback_data *) arg; + Uint8 *waveptr = sound + cbdata->soundpos; + int waveleft = soundlen - cbdata->soundpos; int cpy = len; if (cpy > waveleft) cpy = waveleft; SDL_memcpy(stream, waveptr, cpy); len -= cpy; - cbd->soundpos += cpy; + cbdata->soundpos += cpy; if (len > 0) { stream += cpy; SDL_memset(stream, spec.silence, len); - SDL_AtomicSet(&cbd->done, 1); + SDL_AtomicSet(&cbdata->done, 1); } } @@ -180,13 +180,11 @@ main(int argc, char **argv) if (devcount < 1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Don't see any specific audio devices!\n"); } else { - if (argv[1] == NULL) { - argv[1] = "sample.wav"; - } + const char *file = (argc < 2) ? "sample.wav" : argv[1]; /* Load the wave file into memory */ - if (SDL_LoadWAV(argv[1], &spec, &sound, &soundlen) == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1], + if (SDL_LoadWAV(file, &spec, &sound, &soundlen) == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", file, SDL_GetError()); } else { test_multi_audio(devcount); diff --git a/Engine/lib/sdl/test/testnative.c b/Engine/lib/sdl/test/testnative.c index 675c8f41e..48f6f0ea5 100644 --- a/Engine/lib/sdl/test/testnative.c +++ b/Engine/lib/sdl/test/testnative.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -53,7 +53,7 @@ quit(int rc) } SDL_Texture * -LoadSprite(SDL_Renderer *renderer, char *file) +LoadSprite(SDL_Renderer *renderer, const char *file) { SDL_Surface *temp; SDL_Texture *sprite; diff --git a/Engine/lib/sdl/test/testnative.h b/Engine/lib/sdl/test/testnative.h index d7b40fb3d..694f46ec8 100644 --- a/Engine/lib/sdl/test/testnative.h +++ b/Engine/lib/sdl/test/testnative.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testnativeos2.c b/Engine/lib/sdl/test/testnativeos2.c index c84b17572..6998fa614 100644 --- a/Engine/lib/sdl/test/testnativeos2.c +++ b/Engine/lib/sdl/test/testnativeos2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -14,46 +14,44 @@ #ifdef TEST_NATIVE_OS2 -#define WIN_CLIENT_CLASS "SDL Test" +#define WIN_CLIENT_CLASS "SDL Test" static void *CreateWindowNative(int w, int h); static void DestroyWindowNative(void *window); NativeWindowFactory OS2WindowFactory = { - "DIVE", - CreateWindowNative, - DestroyWindowNative + "DIVE", + CreateWindowNative, + DestroyWindowNative }; static void *CreateWindowNative(int w, int h) { - HWND hwnd; - HWND hwndFrame; - ULONG ulFrameFlags = FCF_TASKLIST | FCF_DLGBORDER | FCF_TITLEBAR | - FCF_SYSMENU | FCF_SHELLPOSITION | - FCF_SIZEBORDER | FCF_MINBUTTON | FCF_MAXBUTTON; + HWND hwnd, hwndFrame; + ULONG ulFrameFlags = FCF_TASKLIST | FCF_DLGBORDER | FCF_TITLEBAR | + FCF_SYSMENU | FCF_SHELLPOSITION | + FCF_SIZEBORDER | FCF_MINBUTTON | FCF_MAXBUTTON; - WinRegisterClass( 0, WIN_CLIENT_CLASS, WinDefWindowProc, - CS_SIZEREDRAW | CS_MOVENOTIFY, - sizeof(ULONG) ); // We should have minimum 4 bytes. + WinRegisterClass(0, WIN_CLIENT_CLASS, WinDefWindowProc, + CS_SIZEREDRAW | CS_MOVENOTIFY, + sizeof(ULONG)); /* We should have minimum 4 bytes. */ - hwndFrame = WinCreateStdWindow( HWND_DESKTOP, 0, &ulFrameFlags, - WIN_CLIENT_CLASS, "SDL Test", 0, 0, 1, &hwnd ); - if ( hwndFrame == NULLHANDLE ) - { - return 0; - } + hwndFrame = WinCreateStdWindow(HWND_DESKTOP, 0, &ulFrameFlags, + WIN_CLIENT_CLASS, "SDL Test", 0, 0, 1, &hwnd); + if (hwndFrame == NULLHANDLE) { + return NULL; + } - WinSetWindowPos( hwndFrame, HWND_TOP, 0, 0, w, h, - SWP_ZORDER | SWP_ACTIVATE | SWP_SIZE | SWP_SHOW ); + WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, w, h, + SWP_ZORDER | SWP_ACTIVATE | SWP_SIZE | SWP_SHOW); - return (void *)hwndFrame; // We may returns client or frame window handle - // for SDL_CreateWindowFrom(). + return (void *)hwndFrame; /* We may return client or frame window + handle for SDL_CreateWindowFrom(). */ } static void DestroyWindowNative(void *window) { - WinDestroyWindow( (HWND)window ); + WinDestroyWindow((HWND) window); } #endif /* TEST_NATIVE_OS2 */ diff --git a/Engine/lib/sdl/test/testnativew32.c b/Engine/lib/sdl/test/testnativew32.c index 62627c851..a9bf2c779 100644 --- a/Engine/lib/sdl/test/testnativew32.c +++ b/Engine/lib/sdl/test/testnativew32.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testnativex11.c b/Engine/lib/sdl/test/testnativex11.c index 2a38de2a9..f6bd0c0e4 100644 --- a/Engine/lib/sdl/test/testnativex11.c +++ b/Engine/lib/sdl/test/testnativex11.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testoffscreen.c b/Engine/lib/sdl/test/testoffscreen.c index bebbe011e..3738e9603 100644 --- a/Engine/lib/sdl/test/testoffscreen.c +++ b/Engine/lib/sdl/test/testoffscreen.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testoverlay2.c b/Engine/lib/sdl/test/testoverlay2.c index ac90ba8a4..8bb59a9fa 100644 --- a/Engine/lib/sdl/test/testoverlay2.c +++ b/Engine/lib/sdl/test/testoverlay2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -144,7 +144,6 @@ SDL_Texture *MooseTexture; SDL_Rect displayrect; int window_w; int window_h; -SDL_Window *window; SDL_Renderer *renderer; int paused = 0; int i; diff --git a/Engine/lib/sdl/test/testplatform.c b/Engine/lib/sdl/test/testplatform.c index 943157748..5aa649c12 100644 --- a/Engine/lib/sdl/test/testplatform.c +++ b/Engine/lib/sdl/test/testplatform.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,31 +25,31 @@ badsize(size_t sizeoftype, size_t hardcodetype) return sizeoftype != hardcodetype; } +SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT8, SDL_MAX_SINT8 == 127); +SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT8, SDL_MIN_SINT8 == -128); +SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT8, SDL_MAX_UINT8 == 255); +SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT8, SDL_MIN_UINT8 == 0); + +SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT16, SDL_MAX_SINT16 == 32767); +SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT16, SDL_MIN_SINT16 == -32768); +SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT16, SDL_MAX_UINT16 == 65535); +SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT16, SDL_MIN_UINT16 == 0); + +SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT32, SDL_MAX_SINT32 == 2147483647); +SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT32, SDL_MIN_SINT32 == ~0x7fffffff); /* Instead of -2147483648, which is treated as unsigned by some compilers */ +SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT32, SDL_MAX_UINT32 == 4294967295u); +SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT32, SDL_MIN_UINT32 == 0); + +SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT64, SDL_MAX_SINT64 == 9223372036854775807ll); +SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT64, SDL_MIN_SINT64 == ~0x7fffffffffffffffll); /* Instead of -9223372036854775808, which is treated as unsigned by compilers */ +SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT64, SDL_MAX_UINT64 == 18446744073709551615ull); +SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT64, SDL_MIN_UINT64 == 0); + int TestTypes(SDL_bool verbose) { int error = 0; - SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT8, SDL_MAX_SINT8 == 127); - SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT8, SDL_MIN_SINT8 == -128); - SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT8, SDL_MAX_UINT8 == 255); - SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT8, SDL_MIN_UINT8 == 0); - - SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT16, SDL_MAX_SINT16 == 32767); - SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT16, SDL_MIN_SINT16 == -32768); - SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT16, SDL_MAX_UINT16 == 65535); - SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT16, SDL_MIN_UINT16 == 0); - - SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT32, SDL_MAX_SINT32 == 2147483647); - SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT32, SDL_MIN_SINT32 == ~0x7fffffff); /* Instead of -2147483648, which is treated as unsigned by some compilers */ - SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT32, SDL_MAX_UINT32 == 4294967295u); - SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT32, SDL_MIN_UINT32 == 0); - - SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT64, SDL_MAX_SINT64 == 9223372036854775807ll); - SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT64, SDL_MIN_SINT64 == ~0x7fffffffffffffffll); /* Instead of -9223372036854775808, which is treated as unsigned by compilers */ - SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT64, SDL_MAX_UINT64 == 18446744073709551615ull); - SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT64, SDL_MIN_UINT64 == 0); - if (badsize(sizeof(Uint8), 1)) { if (verbose) SDL_Log("sizeof(Uint8) != 1, instead = %u\n", @@ -381,6 +381,7 @@ TestCPUInfo(SDL_bool verbose) SDL_Log("AVX %s\n", SDL_HasAVX()? "detected" : "not detected"); SDL_Log("AVX2 %s\n", SDL_HasAVX2()? "detected" : "not detected"); SDL_Log("AVX-512F %s\n", SDL_HasAVX512F()? "detected" : "not detected"); + SDL_Log("ARM SIMD %s\n", SDL_HasARMSIMD()? "detected" : "not detected"); SDL_Log("NEON %s\n", SDL_HasNEON()? "detected" : "not detected"); SDL_Log("System RAM %d MB\n", SDL_GetSystemRAM()); } diff --git a/Engine/lib/sdl/test/testpower.c b/Engine/lib/sdl/test/testpower.c index 841d6053f..27b05ee21 100644 --- a/Engine/lib/sdl/test/testpower.c +++ b/Engine/lib/sdl/test/testpower.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,7 +19,7 @@ report_power(void) { int seconds, percent; const SDL_PowerState state = SDL_GetPowerInfo(&seconds, &percent); - char *statestr = NULL; + const char *statestr = NULL; SDL_Log("SDL-reported power info...\n"); switch (state) { @@ -55,7 +55,7 @@ report_power(void) SDL_Log("Time left: unknown\n"); } else { SDL_Log("Time left: %d minutes, %d seconds\n", (int) (seconds / 60), - (int) (seconds % 60)); + (int) (seconds % 60)); } } diff --git a/Engine/lib/sdl/test/testqsort.c b/Engine/lib/sdl/test/testqsort.c index 073a5c5c4..d28daebd4 100644 --- a/Engine/lib/sdl/test/testqsort.c +++ b/Engine/lib/sdl/test/testqsort.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -54,9 +54,9 @@ main(int argc, char *argv[]) int success; Uint64 seed = 0; if (argv[1][0] == '0' && argv[1][1] == 'x') - success = SDL_sscanf(argv[1] + 2, "%llx", &seed); + success = SDL_sscanf(argv[1] + 2, "%"SDL_PRIx64, &seed); else - success = SDL_sscanf(argv[1], "%llu", &seed); + success = SDL_sscanf(argv[1], "%"SDL_PRIu64, &seed); if (!success) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Invalid seed. Use a decimal or hexadecimal number.\n"); return 1; diff --git a/Engine/lib/sdl/test/testrelative.c b/Engine/lib/sdl/test/testrelative.c index 52566f7b1..59a563eea 100644 --- a/Engine/lib/sdl/test/testrelative.c +++ b/Engine/lib/sdl/test/testrelative.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,10 +28,10 @@ SDL_Rect rect; SDL_Event event; static void -DrawRects(SDL_Renderer * renderer, SDL_Rect * rect) +DrawRects(SDL_Renderer * renderer) { SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); - SDL_RenderFillRect(renderer, rect); + SDL_RenderFillRect(renderer, &rect); } static void @@ -63,7 +63,7 @@ loop(){ if (rect.x > viewport.x + viewport.w) rect.x -= viewport.w; if (rect.y > viewport.y + viewport.h) rect.y -= viewport.h; - DrawRects(renderer, &rect); + DrawRects(renderer); SDL_RenderPresent(renderer); } diff --git a/Engine/lib/sdl/test/testrendercopyex.c b/Engine/lib/sdl/test/testrendercopyex.c index 5f51bb64c..47d3ae96f 100644 --- a/Engine/lib/sdl/test/testrendercopyex.c +++ b/Engine/lib/sdl/test/testrendercopyex.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testrendertarget.c b/Engine/lib/sdl/test/testrendertarget.c index 0845cbd66..3fb611270 100644 --- a/Engine/lib/sdl/test/testrendertarget.c +++ b/Engine/lib/sdl/test/testrendertarget.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -46,7 +46,7 @@ quit(int rc) } SDL_Texture * -LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent) +LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) { SDL_Surface *temp; SDL_Texture *texture; diff --git a/Engine/lib/sdl/test/testresample.c b/Engine/lib/sdl/test/testresample.c index 70585f494..6f03aabd4 100644 --- a/Engine/lib/sdl/test/testresample.c +++ b/Engine/lib/sdl/test/testresample.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testrumble.c b/Engine/lib/sdl/test/testrumble.c index 50c7a6544..07fc89c58 100644 --- a/Engine/lib/sdl/test/testrumble.c +++ b/Engine/lib/sdl/test/testrumble.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,10 +25,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND /* * includes */ -#include -#include /* strstr */ -#include /* isdigit */ - #include "SDL.h" #ifndef SDL_HAPTIC_DISABLED @@ -56,7 +52,7 @@ main(int argc, char **argv) if (argc > 1) { size_t l; name = argv[1]; - if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) { + if ((SDL_strcmp(name, "--help") == 0) || (SDL_strcmp(name, "-h") == 0)) { SDL_Log("USAGE: %s [device]\n" "If device is a two-digit number it'll use it as an index, otherwise\n" "it'll use it as if it were part of the device's name.\n", @@ -83,7 +79,7 @@ main(int argc, char **argv) /* Try to find matching device */ else { for (i = 0; i < SDL_NumHaptics(); i++) { - if (strstr(SDL_HapticName(i), name) != NULL) + if (SDL_strstr(SDL_HapticName(i), name) != NULL) break; } diff --git a/Engine/lib/sdl/test/testscale.c b/Engine/lib/sdl/test/testscale.c index 4a603c67d..1235c811d 100644 --- a/Engine/lib/sdl/test/testscale.c +++ b/Engine/lib/sdl/test/testscale.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -47,7 +47,7 @@ quit(int rc) } SDL_Texture * -LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent) +LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) { SDL_Surface *temp; SDL_Texture *texture; diff --git a/Engine/lib/sdl/test/testsem.c b/Engine/lib/sdl/test/testsem.c index 8a60ff122..eaa28642a 100644 --- a/Engine/lib/sdl/test/testsem.c +++ b/Engine/lib/sdl/test/testsem.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,27 +19,21 @@ #include "SDL.h" #define NUM_THREADS 10 +/* This value should be smaller than the maximum count of the */ +/* semaphore implementation: */ +#define NUM_OVERHEAD_OPS 10000 +#define NUM_OVERHEAD_OPS_MULT 10 static SDL_sem *sem; -int alive = 1; +int alive; -int SDLCALL -ThreadFunc(void *data) -{ - int threadnum = (int) (uintptr_t) data; - while (alive) { - SDL_SemWait(sem); - SDL_Log("Thread number %d has got the semaphore (value = %d)!\n", - threadnum, SDL_SemValue(sem)); - SDL_Delay(200); - SDL_SemPost(sem); - SDL_Log("Thread number %d has released the semaphore (value = %d)!\n", - threadnum, SDL_SemValue(sem)); - SDL_Delay(1); /* For the scheduler */ - } - SDL_Log("Thread number %d exiting.\n", threadnum); - return 0; -} +typedef struct Thread_State { + SDL_Thread * thread; + int number; + SDL_bool flag; + int loop_count; + int content_count; +} Thread_State; static void killed(int sig) @@ -47,6 +41,60 @@ killed(int sig) alive = 0; } +static int SDLCALL +ThreadFuncRealWorld(void *data) +{ + Thread_State *state = (Thread_State *) data; + while (alive) { + SDL_SemWait(sem); + SDL_Log("Thread number %d has got the semaphore (value = %d)!\n", + state->number, SDL_SemValue(sem)); + SDL_Delay(200); + SDL_SemPost(sem); + SDL_Log("Thread number %d has released the semaphore (value = %d)!\n", + state->number, SDL_SemValue(sem)); + ++state->loop_count; + SDL_Delay(1); /* For the scheduler */ + } + SDL_Log("Thread number %d exiting.\n", state->number); + return 0; +} + +static void +TestRealWorld(int init_sem) { + Thread_State thread_states[NUM_THREADS] = { {0} }; + int i; + int loop_count; + + sem = SDL_CreateSemaphore(init_sem); + + SDL_Log("Running %d threads, semaphore value = %d\n", NUM_THREADS, + init_sem); + alive = 1; + /* Create all the threads */ + for (i = 0; i < NUM_THREADS; ++i) { + char name[64]; + SDL_snprintf(name, sizeof (name), "Thread%u", (unsigned int) i); + thread_states[i].number = i; + thread_states[i].thread = SDL_CreateThread(ThreadFuncRealWorld, name, (void *) &thread_states[i]); + } + + /* Wait 10 seconds */ + SDL_Delay(10 * 1000); + + /* Wait for all threads to finish */ + SDL_Log("Waiting for threads to finish\n"); + alive = 0; + loop_count = 0; + for (i = 0; i < NUM_THREADS; ++i) { + SDL_WaitThread(thread_states[i].thread, NULL); + loop_count += thread_states[i].loop_count; + } + SDL_Log("Finished waiting for threads, ran %d loops in total\n\n", loop_count); + + SDL_DestroySemaphore(sem); +} + static void TestWaitTimeout(void) { @@ -65,21 +113,137 @@ TestWaitTimeout(void) duration = end_ticks - start_ticks; /* Accept a little offset in the effective wait */ - if (duration > 1900 && duration < 2050) - SDL_Log("Wait done.\n"); - else - SDL_Log("Wait took %d milliseconds\n", duration); + SDL_assert(duration > 1900 && duration < 2050); + SDL_Log("Wait took %d milliseconds\n\n", duration); /* Check to make sure the return value indicates timed out */ if (retval != SDL_MUTEX_TIMEDOUT) - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_SemWaitTimeout returned: %d; expected: %d\n", retval, SDL_MUTEX_TIMEDOUT); + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_SemWaitTimeout returned: %d; expected: %d\n\n", retval, SDL_MUTEX_TIMEDOUT); + + SDL_DestroySemaphore(sem); +} + +static void +TestOverheadUncontended(void) +{ + Uint32 start_ticks; + Uint32 end_ticks; + Uint32 duration; + int i, j; + + sem = SDL_CreateSemaphore(0); + SDL_Log("Doing %d uncontended Post/Wait operations on semaphore\n", NUM_OVERHEAD_OPS * NUM_OVERHEAD_OPS_MULT); + + start_ticks = SDL_GetTicks(); + for (i = 0; i < NUM_OVERHEAD_OPS_MULT; i++){ + for (j = 0; j < NUM_OVERHEAD_OPS; j++) { + SDL_SemPost(sem); + } + for (j = 0; j < NUM_OVERHEAD_OPS; j++) { + SDL_SemWait(sem); + } + } + end_ticks = SDL_GetTicks(); + + duration = end_ticks - start_ticks; + SDL_Log("Took %d milliseconds\n\n", duration); + + SDL_DestroySemaphore(sem); +} + +static int SDLCALL +ThreadFuncOverheadContended(void *data) +{ + Thread_State *state = (Thread_State *) data; + + if (state->flag) { + while(alive) { + if (SDL_SemTryWait(sem) == SDL_MUTEX_TIMEDOUT) { + ++state->content_count; + } + ++state->loop_count; + } + } else { + while(alive) { + /* Timeout needed to allow check on alive flag */ + if (SDL_SemWaitTimeout(sem, 50) == SDL_MUTEX_TIMEDOUT) { + ++state->content_count; + } + ++state->loop_count; + } + } + return 0; +} + +static void +TestOverheadContended(SDL_bool try_wait) +{ + Uint32 start_ticks; + Uint32 end_ticks; + Uint32 duration; + Thread_State thread_states[NUM_THREADS] = { {0} }; + char textBuffer[1024]; + int loop_count; + int content_count; + int i, j; + size_t len; + + sem = SDL_CreateSemaphore(0); + SDL_Log("Doing %d contended %s operations on semaphore using %d threads\n", + NUM_OVERHEAD_OPS * NUM_OVERHEAD_OPS_MULT, try_wait ? "Post/TryWait" : "Post/WaitTimeout", NUM_THREADS); + alive = 1; + /* Create multiple threads to starve the semaphore and cause contention */ + for (i = 0; i < NUM_THREADS; ++i) { + char name[64]; + SDL_snprintf(name, sizeof (name), "Thread%u", (unsigned int) i); + thread_states[i].flag = try_wait; + thread_states[i].thread = SDL_CreateThread(ThreadFuncOverheadContended, name, (void *) &thread_states[i]); + } + + start_ticks = SDL_GetTicks(); + for (i = 0; i < NUM_OVERHEAD_OPS_MULT; i++) { + for (j = 0; j < NUM_OVERHEAD_OPS; j++) { + SDL_SemPost(sem); + } + /* Make sure threads consumed everything */ + while (SDL_SemValue(sem)) { } + } + end_ticks = SDL_GetTicks(); + + alive = 0; + loop_count = 0; + content_count = 0; + for (i = 0; i < NUM_THREADS; ++i) { + SDL_WaitThread(thread_states[i].thread, NULL); + loop_count += thread_states[i].loop_count; + content_count += thread_states[i].content_count; + } + SDL_assert_release((loop_count - content_count) == NUM_OVERHEAD_OPS * NUM_OVERHEAD_OPS_MULT); + + duration = end_ticks - start_ticks; + SDL_Log("Took %d milliseconds, threads %s %d out of %d times in total (%.2f%%)\n", + duration, try_wait ? "where contended" : "timed out", content_count, + loop_count, ((float)content_count * 100) / loop_count); + /* Print how many semaphores where consumed per thread */ + SDL_snprintf(textBuffer, sizeof(textBuffer), "{ "); + for (i = 0; i < NUM_THREADS; ++i) { + if (i > 0) { + len = SDL_strlen(textBuffer); + SDL_snprintf(textBuffer + len, sizeof(textBuffer) - len, ", "); + } + len = SDL_strlen(textBuffer); + SDL_snprintf(textBuffer + len, sizeof(textBuffer) - len, "%d", thread_states[i].loop_count - thread_states[i].content_count); + } + len = SDL_strlen(textBuffer); + SDL_snprintf(textBuffer + len, sizeof(textBuffer) - len, " }\n"); + SDL_Log("%s\n", textBuffer); + + SDL_DestroySemaphore(sem); } int main(int argc, char **argv) { - SDL_Thread *threads[NUM_THREADS]; - uintptr_t i; int init_sem; /* Enable standard application logging */ @@ -98,33 +262,19 @@ main(int argc, char **argv) signal(SIGTERM, killed); signal(SIGINT, killed); - init_sem = atoi(argv[1]); - sem = SDL_CreateSemaphore(init_sem); - - SDL_Log("Running %d threads, semaphore value = %d\n", NUM_THREADS, - init_sem); - /* Create all the threads */ - for (i = 0; i < NUM_THREADS; ++i) { - char name[64]; - SDL_snprintf(name, sizeof (name), "Thread%u", (unsigned int) i); - threads[i] = SDL_CreateThread(ThreadFunc, name, (void *) i); + init_sem = SDL_atoi(argv[1]); + if (init_sem > 0) { + TestRealWorld(init_sem); } - /* Wait 10 seconds */ - SDL_Delay(10 * 1000); - - /* Wait for all threads to finish */ - SDL_Log("Waiting for threads to finish\n"); - alive = 0; - for (i = 0; i < NUM_THREADS; ++i) { - SDL_WaitThread(threads[i], NULL); - } - SDL_Log("Finished waiting for threads\n"); - - SDL_DestroySemaphore(sem); - TestWaitTimeout(); + TestOverheadUncontended(); + + TestOverheadContended(SDL_FALSE); + + TestOverheadContended(SDL_TRUE); + SDL_Quit(); return (0); } diff --git a/Engine/lib/sdl/test/testsensor.c b/Engine/lib/sdl/test/testsensor.c index c29faa24f..658a65be8 100644 --- a/Engine/lib/sdl/test/testsensor.c +++ b/Engine/lib/sdl/test/testsensor.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -95,7 +95,11 @@ main(int argc, char **argv) SDL_CreateWindow("Sensor Test", 0, 0, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP); while (!done) { - while (SDL_PollEvent(&event) > 0) { + /* Update to get the current event state */ + SDL_PumpEvents(); + + /* Process all currently pending events */ + while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) == 1) { switch (event.type) { case SDL_SENSORUPDATE: HandleSensorEvent(&event.sensor); diff --git a/Engine/lib/sdl/test/testshader.c b/Engine/lib/sdl/test/testshader.c index 45e74a604..2cee7d9b3 100644 --- a/Engine/lib/sdl/test/testshader.c +++ b/Engine/lib/sdl/test/testshader.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testshape.c b/Engine/lib/sdl/test/testshape.c index 63288d4d9..1497528a9 100644 --- a/Engine/lib/sdl/test/testshape.c +++ b/Engine/lib/sdl/test/testshape.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testsprite2.c b/Engine/lib/sdl/test/testsprite2.c index 4de0b4bae..88419ffcf 100644 --- a/Engine/lib/sdl/test/testsprite2.c +++ b/Engine/lib/sdl/test/testsprite2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -39,6 +39,7 @@ static int sprite_w, sprite_h; static SDL_BlendMode blendMode = SDL_BLENDMODE_BLEND; static Uint32 next_fps_check, frames; static const Uint32 fps_check_delay = 5000; +static int use_rendergeometry = 0; /* Number of iterations to move sprites - used for visual tests. */ /* -1: infinite random moves (default); >=0: enables N deterministic moves */ @@ -175,7 +176,38 @@ MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite) temp.y = 1; temp.w = sprite_w; temp.h = sprite_h; - SDL_RenderFillRect(renderer, &temp); + if (use_rendergeometry == 0) { + SDL_RenderFillRect(renderer, &temp); + } else { + /* Draw two triangles, filled, uniform */ + SDL_Color color; + SDL_Vertex verts[3]; + SDL_zeroa(verts); + color.r = 0xFF; + color.g = 0xFF; + color.b = 0xFF; + color.a = 0xFF; + + verts[0].position.x = (float)temp.x; + verts[0].position.y = (float)temp.y; + verts[0].color = color; + + verts[1].position.x = (float)temp.x + temp.w; + verts[1].position.y = (float)temp.y; + verts[1].color = color; + + verts[2].position.x = (float)temp.x + temp.w; + verts[2].position.y = (float)temp.y + temp.h; + verts[2].color = color; + + SDL_RenderGeometry(renderer, NULL, verts, 3, NULL, 0); + + verts[1].position.x = (float)temp.x; + verts[1].position.y = (float)temp.y + temp.h; + verts[1].color = color; + + SDL_RenderGeometry(renderer, NULL, verts, 3, NULL, 0); + } SDL_RenderCopy(renderer, sprite, NULL, &temp); temp.x = viewport.w-sprite_w-1; temp.y = 1; @@ -220,7 +252,7 @@ MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite) } } - + /* Countdown sprite-move iterations and disable color changes at iteration end - used for visual tests. */ if (iterations > 0) { iterations--; @@ -232,11 +264,160 @@ MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite) } /* Draw sprites */ - for (i = 0; i < num_sprites; ++i) { - position = &positions[i]; + if (use_rendergeometry == 0) { + for (i = 0; i < num_sprites; ++i) { + position = &positions[i]; - /* Blit the sprite onto the screen */ - SDL_RenderCopy(renderer, sprite, NULL, position); + /* Blit the sprite onto the screen */ + SDL_RenderCopy(renderer, sprite, NULL, position); + } + } else if (use_rendergeometry == 1) { + /* + * 0--1 + * | /| + * |/ | + * 3--2 + * + * Draw sprite2 as triangles that can be recombined as rect by software renderer + */ + SDL_Vertex *verts = (SDL_Vertex *) SDL_malloc(num_sprites * sizeof (SDL_Vertex) * 6); + SDL_Vertex *verts2 = verts; + if (verts) { + SDL_Color color; + SDL_GetTextureColorMod(sprite, &color.r, &color.g, &color.b); + SDL_GetTextureAlphaMod(sprite, &color.a); + for (i = 0; i < num_sprites; ++i) { + position = &positions[i]; + /* 0 */ + verts->position.x = (float)position->x; + verts->position.y = (float)position->y; + verts->color = color; + verts->tex_coord.x = 0.0f; + verts->tex_coord.y = 0.0f; + verts++; + /* 1 */ + verts->position.x = (float)position->x + position->w; + verts->position.y = (float)position->y; + verts->color = color; + verts->tex_coord.x = 1.0f; + verts->tex_coord.y = 0.0f; + verts++; + /* 2 */ + verts->position.x = (float)position->x + position->w; + verts->position.y = (float)position->y + position->h; + verts->color = color; + verts->tex_coord.x = 1.0f; + verts->tex_coord.y = 1.0f; + verts++; + /* 0 */ + verts->position.x = (float)position->x; + verts->position.y = (float)position->y; + verts->color = color; + verts->tex_coord.x = 0.0f; + verts->tex_coord.y = 0.0f; + verts++; + /* 2 */ + verts->position.x = (float)position->x + position->w; + verts->position.y = (float)position->y + position->h; + verts->color = color; + verts->tex_coord.x = 1.0f; + verts->tex_coord.y = 1.0f; + verts++; + /* 3 */ + verts->position.x = (float)position->x; + verts->position.y = (float)position->y + position->h; + verts->color = color; + verts->tex_coord.x = 0.0f; + verts->tex_coord.y = 1.0f; + verts++; + } + + /* Blit sprites as triangles onto the screen */ + SDL_RenderGeometry(renderer, sprite, verts2, num_sprites * 6, NULL, 0); + SDL_free(verts2); + } + } else if (use_rendergeometry == 2) { + /* 0-----1 + * |\ A /| + * | \ / | + * |D 2 B| + * | / \ | + * |/ C \| + * 3-----4 + * + * Draw sprite2 as triangles that can *not* be recombined as rect by software renderer + * Use an 'indices' array + */ + SDL_Vertex *verts = (SDL_Vertex *) SDL_malloc(num_sprites * sizeof (SDL_Vertex) * 5); + SDL_Vertex *verts2 = verts; + int *indices = (int *) SDL_malloc(num_sprites * sizeof (int) * 4 * 3); + int *indices2 = indices; + if (verts && indices) { + int pos = 0; + SDL_Color color; + SDL_GetTextureColorMod(sprite, &color.r, &color.g, &color.b); + SDL_GetTextureAlphaMod(sprite, &color.a); + for (i = 0; i < num_sprites; ++i) { + position = &positions[i]; + /* 0 */ + verts->position.x = (float)position->x; + verts->position.y = (float)position->y; + verts->color = color; + verts->tex_coord.x = 0.0f; + verts->tex_coord.y = 0.0f; + verts++; + /* 1 */ + verts->position.x = (float)position->x + position->w; + verts->position.y = (float)position->y; + verts->color = color; + verts->tex_coord.x = 1.0f; + verts->tex_coord.y = 0.0f; + verts++; + /* 2 */ + verts->position.x = (float)position->x + position->w / 2.0f; + verts->position.y = (float)position->y + position->h / 2.0f; + verts->color = color; + verts->tex_coord.x = 0.5f; + verts->tex_coord.y = 0.5f; + verts++; + /* 3 */ + verts->position.x = (float)position->x; + verts->position.y = (float)position->y + position->h; + verts->color = color; + verts->tex_coord.x = 0.0f; + verts->tex_coord.y = 1.0f; + verts++; + /* 4 */ + verts->position.x = (float)position->x + position->w; + verts->position.y = (float)position->y + position->h; + verts->color = color; + verts->tex_coord.x = 1.0f; + verts->tex_coord.y = 1.0f; + verts++; + /* A */ + *indices++ = pos + 0; + *indices++ = pos + 1; + *indices++ = pos + 2; + /* B */ + *indices++ = pos + 1; + *indices++ = pos + 2; + *indices++ = pos + 4; + /* C */ + *indices++ = pos + 3; + *indices++ = pos + 2; + *indices++ = pos + 4; + /* D */ + *indices++ = pos + 3; + *indices++ = pos + 2; + *indices++ = pos + 0; + pos += 5; + } + } + + /* Blit sprites as triangles onto the screen */ + SDL_RenderGeometry(renderer, sprite, verts2, num_sprites * 5, indices2, num_sprites * 4 * 3); + SDL_free(verts2); + SDL_free(indices2); } /* Update the screen! */ @@ -331,6 +512,20 @@ main(int argc, char *argv[]) } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) { cycle_alpha = SDL_TRUE; consumed = 1; + } else if (SDL_strcasecmp(argv[i], "--use-rendergeometry") == 0) { + if (argv[i + 1]) { + if (SDL_strcasecmp(argv[i + 1], "mode1") == 0) { + /* Draw sprite2 as triangles that can be recombined as rect by software renderer */ + use_rendergeometry = 1; + } else if (SDL_strcasecmp(argv[i + 1], "mode2") == 0) { + /* Draw sprite2 as triangles that can *not* be recombined as rect by software renderer + * Use an 'indices' array */ + use_rendergeometry = 2; + } else { + return -1; + } + } + consumed = 2; } else if (SDL_isdigit(*argv[i])) { num_sprites = SDL_atoi(argv[i]); consumed = 1; @@ -340,7 +535,15 @@ main(int argc, char *argv[]) } } if (consumed < 0) { - static const char *options[] = { "[--blend none|blend|add|mod]", "[--cyclecolor]", "[--cyclealpha]", "[--iterations N]", "[num_sprites]", "[icon.bmp]", NULL }; + static const char *options[] = { + "[--blend none|blend|add|mod]", + "[--cyclecolor]", + "[--cyclealpha]", + "[--iterations N]", + "[--use-rendergeometry mode1|mode2]", + "[num_sprites]", + "[icon.bmp]", + NULL }; SDLTest_CommonLogUsage(state, argv[0], options); quit(1); } @@ -374,7 +577,7 @@ main(int argc, char *argv[]) quit(2); } - /* Position sprites and set their velocities using the fuzzer */ + /* Position sprites and set their velocities using the fuzzer */ if (iterations >= 0) { /* Deterministic seed - used for visual tests */ seed = (Uint64)iterations; diff --git a/Engine/lib/sdl/test/testspriteminimal.c b/Engine/lib/sdl/test/testspriteminimal.c index 5e50baf9b..b9762cab3 100644 --- a/Engine/lib/sdl/test/testspriteminimal.c +++ b/Engine/lib/sdl/test/testspriteminimal.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -43,7 +43,7 @@ quit(int rc) } int -LoadSprite(char *file, SDL_Renderer *renderer) +LoadSprite(const char *file) { SDL_Surface *temp; @@ -92,7 +92,7 @@ LoadSprite(char *file, SDL_Renderer *renderer) } void -MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite) +MoveSprites() { int i; int window_w = WINDOW_WIDTH; @@ -136,7 +136,7 @@ void loop() done = 1; } } - MoveSprites(renderer, sprite); + MoveSprites(); #ifdef __EMSCRIPTEN__ if (done) { emscripten_cancel_main_loop(); @@ -158,7 +158,7 @@ main(int argc, char *argv[]) quit(2); } - if (LoadSprite("icon.bmp", renderer) < 0) { + if (LoadSprite("icon.bmp") < 0) { quit(2); } diff --git a/Engine/lib/sdl/test/teststreaming.c b/Engine/lib/sdl/test/teststreaming.c index 565d5c82e..72444f80e 100644 --- a/Engine/lib/sdl/test/teststreaming.c +++ b/Engine/lib/sdl/test/teststreaming.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -67,7 +67,7 @@ void quit(int rc) exit(rc); } -void UpdateTexture(SDL_Texture *texture, int frame) +void UpdateTexture(SDL_Texture *texture) { SDL_Color *color; Uint8 *src; @@ -110,7 +110,7 @@ loop() } frame = (frame + 1) % MOOSEFRAMES_COUNT; - UpdateTexture(MooseTexture, frame); + UpdateTexture(MooseTexture); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, MooseTexture, NULL, NULL); diff --git a/Engine/lib/sdl/test/testsurround.c b/Engine/lib/sdl/test/testsurround.c new file mode 100644 index 000000000..168415aca --- /dev/null +++ b/Engine/lib/sdl/test/testsurround.c @@ -0,0 +1,200 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + +/* Program to test surround sound audio channels */ +#include "SDL_config.h" + +#include "SDL.h" + +static int total_channels; +static int active_channel; + +#define SAMPLE_RATE_HZ 48000 +#define CHANNEL_TEST_TIME_SEC 5 +#define MAX_AMPLITUDE SDL_MAX_SINT16 + +#define SINE_FREQ_HZ 500 +#define LFE_SINE_FREQ_HZ 50 + +/* The channel layout is defined in SDL_audio.h */ +const char* +get_channel_name(int channel_index, int channel_count) +{ + switch (channel_index) { + case 0: + return "Front Left"; + case 1: + return "Front Right"; + case 2: + switch (channel_count) { + case 3: + return "Low Frequency Effects"; + case 4: + return "Back Left"; + default: + return "Front Center"; + } + case 3: + switch (channel_count) { + case 4: + return "Back Right"; + case 5: + return "Back Left"; + default: + return "Low Frequency Effects"; + } + case 4: + switch (channel_count) { + case 5: + return "Back Right"; + case 7: + return "Back Center"; + case 6: + case 8: + return "Back Left"; + } + case 5: + switch (channel_count) { + case 7: + return "Back Left"; + case 6: + case 8: + return "Back Right"; + } + case 6: + switch (channel_count) { + case 7: + return "Back Right"; + case 8: + return "Side Left"; + } + case 7: + return "Side Right"; + } + + return NULL; +} + +SDL_bool +is_lfe_channel(int channel_index, int channel_count) +{ + return (channel_count == 3 && channel_index == 2) || (channel_count >= 6 && channel_index == 3); +} + +void SDLCALL +fill_buffer(void* unused, Uint8* stream, int len) +{ + Sint16* buffer = (Sint16*)stream; + int samples = len / sizeof(Sint16); + static int total_samples = 0; + int i; + + SDL_memset(stream, 0, len); + + /* This can happen for a short time when switching devices */ + if (active_channel == total_channels) { + return; + } + + /* Play a sine wave on the active channel only */ + for (i = active_channel; i < samples; i += total_channels) { + float time = (float)total_samples++ / SAMPLE_RATE_HZ; + int sine_freq = is_lfe_channel(active_channel, total_channels) ? LFE_SINE_FREQ_HZ : SINE_FREQ_HZ; + int amplitude; + + /* Gradually ramp up and down to avoid audible pops when switching between channels */ + if (total_samples < SAMPLE_RATE_HZ) { + amplitude = total_samples * MAX_AMPLITUDE / SAMPLE_RATE_HZ; + } else if (total_samples > (CHANNEL_TEST_TIME_SEC - 1) * SAMPLE_RATE_HZ) { + amplitude = (CHANNEL_TEST_TIME_SEC * SAMPLE_RATE_HZ - total_samples) * MAX_AMPLITUDE / SAMPLE_RATE_HZ; + } else { + amplitude = MAX_AMPLITUDE; + } + + buffer[i] = (Sint16)(SDL_sin(6.283185f * sine_freq * time) * amplitude); + + /* Reset our state for next callback if this channel test is finished */ + if (total_samples == CHANNEL_TEST_TIME_SEC * SAMPLE_RATE_HZ) { + total_samples = 0; + active_channel++; + break; + } + } +} + +int +main(int argc, char *argv[]) +{ + int i; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + if (SDL_Init(SDL_INIT_AUDIO) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + /* Show the list of available drivers */ + SDL_Log("Available audio drivers:"); + for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) { + SDL_Log("%i: %s", i, SDL_GetAudioDriver(i)); + } + + SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); + + for (i = 0; i < SDL_GetNumAudioDevices(0); i++) { + const char *devname = SDL_GetAudioDeviceName(i, 0); + int j; + SDL_AudioSpec spec; + SDL_AudioDeviceID dev; + + if (SDL_GetAudioDeviceSpec(i, 0, &spec) != 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GetAudioSpec() failed: %s\n", SDL_GetError()); + continue; + } + + spec.freq = SAMPLE_RATE_HZ; + spec.format = AUDIO_S16SYS; + spec.samples = 4096; + spec.callback = fill_buffer; + + dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0); + if (dev == 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_OpenAudioDevice() failed: %s\n", SDL_GetError()); + continue; + } + + SDL_Log("Testing audio device: %s (%d channels)\n", devname, spec.channels); + + /* These are used by the fill_buffer callback */ + total_channels = spec.channels; + active_channel = 0; + + SDL_PauseAudioDevice(dev, 0); + + for (j = 0; j < total_channels; j++) { + int sine_freq = is_lfe_channel(j, total_channels) ? LFE_SINE_FREQ_HZ : SINE_FREQ_HZ; + + SDL_Log("Playing %d Hz test tone on channel: %s\n", sine_freq, get_channel_name(j, total_channels)); + + /* fill_buffer() will increment the active channel */ + SDL_Delay(CHANNEL_TEST_TIME_SEC * 1000); + } + + SDL_CloseAudioDevice(dev); + } + + SDL_Quit(); + return 0; +} + diff --git a/Engine/lib/sdl/test/testthread.c b/Engine/lib/sdl/test/testthread.c index 2c95a7379..bf201e8e4 100644 --- a/Engine/lib/sdl/test/testthread.c +++ b/Engine/lib/sdl/test/testthread.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testtimer.c b/Engine/lib/sdl/test/testtimer.c index 7e49d7508..d696097c8 100644 --- a/Engine/lib/sdl/test/testtimer.c +++ b/Engine/lib/sdl/test/testtimer.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -42,6 +42,7 @@ main(int argc, char *argv[]) { int i, desired; SDL_TimerID t1, t2, t3; + Uint64 start64, now64; Uint32 start32, now32; Uint64 start, now; @@ -53,10 +54,25 @@ main(int argc, char *argv[]) return (1); } + /* Verify SDL_GetTicks* acts monotonically increasing, and not erratic. */ + SDL_Log("Sanity-checking GetTicks\n"); + for (i = 0; i < 1000; ++i) { + start64 = SDL_GetTicks64(); + start32 = SDL_GetTicks(); + SDL_Delay(1); + now64 = SDL_GetTicks64() - start64; + now32 = SDL_GetTicks() - start32; + if (now32 > 100 || now64 > 100) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "testtimer.c: Delta time erratic at iter %d. Delay 1ms = %d ms in ticks, %d ms in ticks64\n", i, (int)now32, (int)now64); + SDL_Quit(); + return 1; + } + } + /* Start the timer */ desired = 0; if (argv[1]) { - desired = atoi(argv[1]); + desired = SDL_atoi(argv[1]); } if (desired == 0) { desired = DEFAULT_RESOLUTION; @@ -108,12 +124,14 @@ main(int argc, char *argv[]) SDL_Log("1 million iterations of ticktock took %f ms\n", (double)((now - start)*1000) / SDL_GetPerformanceFrequency()); SDL_Log("Performance counter frequency: %"SDL_PRIu64"\n", SDL_GetPerformanceFrequency()); + start64 = SDL_GetTicks64(); start32 = SDL_GetTicks(); start = SDL_GetPerformanceCounter(); SDL_Delay(1000); now = SDL_GetPerformanceCounter(); + now64 = SDL_GetTicks64(); now32 = SDL_GetTicks(); - SDL_Log("Delay 1 second = %d ms in ticks, %f ms according to performance counter\n", (now32-start32), (double)((now - start)*1000) / SDL_GetPerformanceFrequency()); + SDL_Log("Delay 1 second = %d ms in ticks, %d ms in ticks64, %f ms according to performance counter\n", (int) (now32-start32), (int) (now64-start64), (double)((now - start)*1000) / SDL_GetPerformanceFrequency()); SDL_Quit(); return (0); diff --git a/Engine/lib/sdl/test/testurl.c b/Engine/lib/sdl/test/testurl.c index fbde1b95f..4b5a4ed29 100644 --- a/Engine/lib/sdl/test/testurl.c +++ b/Engine/lib/sdl/test/testurl.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testver.c b/Engine/lib/sdl/test/testver.c index 94bceae61..cbbba7ec6 100644 --- a/Engine/lib/sdl/test/testver.c +++ b/Engine/lib/sdl/test/testver.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,13 +35,13 @@ main(int argc, char *argv[]) SDL_Log("Compiled with SDL older than 2.0\n"); #endif SDL_VERSION(&compiled); - SDL_Log("Compiled version: %d.%d.%d.%d (%s)\n", + SDL_Log("Compiled version: %d.%d.%d (%s)\n", compiled.major, compiled.minor, compiled.patch, - SDL_REVISION_NUMBER, SDL_REVISION); + SDL_REVISION); SDL_GetVersion(&linked); - SDL_Log("Linked version: %d.%d.%d.%d (%s)\n", + SDL_Log("Linked version: %d.%d.%d (%s)\n", linked.major, linked.minor, linked.patch, - SDL_GetRevisionNumber(), SDL_GetRevision()); + SDL_GetRevision()); SDL_Quit(); return (0); } diff --git a/Engine/lib/sdl/test/testviewport.c b/Engine/lib/sdl/test/testviewport.c index fc44fe1b6..0e39d852d 100644 --- a/Engine/lib/sdl/test/testviewport.c +++ b/Engine/lib/sdl/test/testviewport.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -43,7 +43,7 @@ quit(int rc) } int -LoadSprite(char *file, SDL_Renderer *renderer) +LoadSprite(const char *file, SDL_Renderer *renderer) { SDL_Surface *temp; @@ -92,7 +92,7 @@ LoadSprite(char *file, SDL_Renderer *renderer) } void -DrawOnViewport(SDL_Renderer * renderer, SDL_Rect viewport) +DrawOnViewport(SDL_Renderer * renderer) { SDL_Rect rect; @@ -174,7 +174,7 @@ loop() continue; /* Draw using viewport */ - DrawOnViewport(state->renderers[i], viewport); + DrawOnViewport(state->renderers[i]); /* Update the screen! */ if (use_target) { diff --git a/Engine/lib/sdl/test/testvulkan.c b/Engine/lib/sdl/test/testvulkan.c index 86e095479..3fe047f3f 100644 --- a/Engine/lib/sdl/test/testvulkan.c +++ b/Engine/lib/sdl/test/testvulkan.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -110,70 +110,44 @@ enum { static const char *getVulkanResultString(VkResult result) { - switch((int)result) + switch((int) result) { - case VK_SUCCESS: - return "VK_SUCCESS"; - case VK_NOT_READY: - return "VK_NOT_READY"; - case VK_TIMEOUT: - return "VK_TIMEOUT"; - case VK_EVENT_SET: - return "VK_EVENT_SET"; - case VK_EVENT_RESET: - return "VK_EVENT_RESET"; - case VK_INCOMPLETE: - return "VK_INCOMPLETE"; - case VK_ERROR_OUT_OF_HOST_MEMORY: - return "VK_ERROR_OUT_OF_HOST_MEMORY"; - case VK_ERROR_OUT_OF_DEVICE_MEMORY: - return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; - case VK_ERROR_INITIALIZATION_FAILED: - return "VK_ERROR_INITIALIZATION_FAILED"; - case VK_ERROR_DEVICE_LOST: - return "VK_ERROR_DEVICE_LOST"; - case VK_ERROR_MEMORY_MAP_FAILED: - return "VK_ERROR_MEMORY_MAP_FAILED"; - case VK_ERROR_LAYER_NOT_PRESENT: - return "VK_ERROR_LAYER_NOT_PRESENT"; - case VK_ERROR_EXTENSION_NOT_PRESENT: - return "VK_ERROR_EXTENSION_NOT_PRESENT"; - case VK_ERROR_FEATURE_NOT_PRESENT: - return "VK_ERROR_FEATURE_NOT_PRESENT"; - case VK_ERROR_INCOMPATIBLE_DRIVER: - return "VK_ERROR_INCOMPATIBLE_DRIVER"; - case VK_ERROR_TOO_MANY_OBJECTS: - return "VK_ERROR_TOO_MANY_OBJECTS"; - case VK_ERROR_FORMAT_NOT_SUPPORTED: - return "VK_ERROR_FORMAT_NOT_SUPPORTED"; - case VK_ERROR_FRAGMENTED_POOL: - return "VK_ERROR_FRAGMENTED_POOL"; - case VK_ERROR_SURFACE_LOST_KHR: - return "VK_ERROR_SURFACE_LOST_KHR"; - case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: - return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; - case VK_SUBOPTIMAL_KHR: - return "VK_SUBOPTIMAL_KHR"; - case VK_ERROR_OUT_OF_DATE_KHR: - return "VK_ERROR_OUT_OF_DATE_KHR"; - case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: - return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; - case VK_ERROR_VALIDATION_FAILED_EXT: - return "VK_ERROR_VALIDATION_FAILED_EXT"; - case VK_ERROR_OUT_OF_POOL_MEMORY_KHR: - return "VK_ERROR_OUT_OF_POOL_MEMORY_KHR"; - case VK_ERROR_INVALID_SHADER_NV: - return "VK_ERROR_INVALID_SHADER_NV"; - default: - break; + #define RESULT_CASE(x) case x: return #x + RESULT_CASE(VK_SUCCESS); + RESULT_CASE(VK_NOT_READY); + RESULT_CASE(VK_TIMEOUT); + RESULT_CASE(VK_EVENT_SET); + RESULT_CASE(VK_EVENT_RESET); + RESULT_CASE(VK_INCOMPLETE); + RESULT_CASE(VK_ERROR_OUT_OF_HOST_MEMORY); + RESULT_CASE(VK_ERROR_OUT_OF_DEVICE_MEMORY); + RESULT_CASE(VK_ERROR_INITIALIZATION_FAILED); + RESULT_CASE(VK_ERROR_DEVICE_LOST); + RESULT_CASE(VK_ERROR_MEMORY_MAP_FAILED); + RESULT_CASE(VK_ERROR_LAYER_NOT_PRESENT); + RESULT_CASE(VK_ERROR_EXTENSION_NOT_PRESENT); + RESULT_CASE(VK_ERROR_FEATURE_NOT_PRESENT); + RESULT_CASE(VK_ERROR_INCOMPATIBLE_DRIVER); + RESULT_CASE(VK_ERROR_TOO_MANY_OBJECTS); + RESULT_CASE(VK_ERROR_FORMAT_NOT_SUPPORTED); + RESULT_CASE(VK_ERROR_FRAGMENTED_POOL); + RESULT_CASE(VK_ERROR_SURFACE_LOST_KHR); + RESULT_CASE(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR); + RESULT_CASE(VK_SUBOPTIMAL_KHR); + RESULT_CASE(VK_ERROR_OUT_OF_DATE_KHR); + RESULT_CASE(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR); + RESULT_CASE(VK_ERROR_VALIDATION_FAILED_EXT); + RESULT_CASE(VK_ERROR_OUT_OF_POOL_MEMORY_KHR); + RESULT_CASE(VK_ERROR_INVALID_SHADER_NV); + #undef RESULT_CASE + default: break; } - if(result < 0) - return "VK_ERROR_"; - return "VK_"; + return (result < 0) ? "VK_ERROR_" : "VK_"; } typedef struct VulkanContext { + SDL_Window *window; VkInstance instance; VkDevice device; VkSurfaceKHR surface; @@ -202,14 +176,15 @@ typedef struct VulkanContext } VulkanContext; static SDLTest_CommonState *state; -static VulkanContext vulkanContext = {0}; +static VulkanContext *vulkanContexts = NULL; // an array of state->num_windows items +static VulkanContext *vulkanContext = NULL; // for the currently-rendering window -static void shutdownVulkan(void); +static void shutdownVulkan(SDL_bool doDestroySwapchain); /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ static void quit(int rc) { - shutdownVulkan(); + shutdownVulkan(SDL_TRUE); SDLTest_CommonQuit(state); exit(rc); } @@ -217,8 +192,7 @@ static void quit(int rc) static void loadGlobalFunctions(void) { vkGetInstanceProcAddr = SDL_Vulkan_GetVkGetInstanceProcAddr(); - if(!vkGetInstanceProcAddr) - { + if (!vkGetInstanceProcAddr) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_GetVkGetInstanceProcAddr(): %s\n", SDL_GetError()); @@ -228,8 +202,7 @@ static void loadGlobalFunctions(void) #define VULKAN_DEVICE_FUNCTION(name) #define VULKAN_GLOBAL_FUNCTION(name) \ name = (PFN_##name)vkGetInstanceProcAddr(VK_NULL_HANDLE, #name); \ - if(!name) \ - { \ + if (!name) { \ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \ "vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed\n"); \ quit(2); \ @@ -247,28 +220,24 @@ static void createInstance(void) VkInstanceCreateInfo instanceCreateInfo = {0}; const char **extensions = NULL; unsigned extensionCount = 0; - VkResult result; + VkResult result; - - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.apiVersion = VK_API_VERSION_1_0; instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instanceCreateInfo.pApplicationInfo = &appInfo; - if(!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, NULL)) - { + if (!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, NULL)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_GetInstanceExtensions(): %s\n", SDL_GetError()); quit(2); } - extensions = SDL_malloc(sizeof(const char *) * extensionCount); - if(!extensions) - { + extensions = (const char **) SDL_malloc(sizeof(const char *) * extensionCount); + if (!extensions) { SDL_OutOfMemory(); quit(2); } - if(!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, extensions)) - { + if (!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, extensions)) { SDL_free((void*)extensions); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_GetInstanceExtensions(): %s\n", @@ -277,11 +246,10 @@ static void createInstance(void) } instanceCreateInfo.enabledExtensionCount = extensionCount; instanceCreateInfo.ppEnabledExtensionNames = extensions; - result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext.instance); + result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext->instance); SDL_free((void*)extensions); - if(result != VK_SUCCESS) - { - vulkanContext.instance = VK_NULL_HANDLE; + if (result != VK_SUCCESS) { + vulkanContext->instance = VK_NULL_HANDLE; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkCreateInstance(): %s\n", getVulkanResultString(result)); @@ -294,9 +262,8 @@ static void loadInstanceFunctions(void) #define VULKAN_DEVICE_FUNCTION(name) #define VULKAN_GLOBAL_FUNCTION(name) #define VULKAN_INSTANCE_FUNCTION(name) \ - name = (PFN_##name)vkGetInstanceProcAddr(vulkanContext.instance, #name); \ - if(!name) \ - { \ + name = (PFN_##name)vkGetInstanceProcAddr(vulkanContext->instance, #name); \ + if (!name) { \ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \ "vkGetInstanceProcAddr(instance, \"" #name "\") failed\n"); \ quit(2); \ @@ -309,13 +276,11 @@ static void loadInstanceFunctions(void) static void createSurface(void) { - if(!SDL_Vulkan_CreateSurface(state->windows[0], - vulkanContext.instance, - &vulkanContext.surface)) - { - vulkanContext.surface = VK_NULL_HANDLE; - SDL_LogError( - SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_CreateSurface(): %s\n", SDL_GetError()); + if (!SDL_Vulkan_CreateSurface(vulkanContext->window, + vulkanContext->instance, + &vulkanContext->surface)) { + vulkanContext->surface = VK_NULL_HANDLE; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_CreateSurface(): %s\n", SDL_GetError()); quit(2); } } @@ -323,94 +288,84 @@ static void createSurface(void) static void findPhysicalDevice(void) { uint32_t physicalDeviceCount = 0; - VkPhysicalDevice *physicalDevices; - VkQueueFamilyProperties *queueFamiliesProperties = NULL; + VkPhysicalDevice *physicalDevices; + VkQueueFamilyProperties *queueFamiliesProperties = NULL; uint32_t queueFamiliesPropertiesAllocatedSize = 0; VkExtensionProperties *deviceExtensions = NULL; uint32_t deviceExtensionsAllocatedSize = 0; - uint32_t physicalDeviceIndex; + uint32_t physicalDeviceIndex; + VkResult result; - VkResult result = - vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, NULL); - if(result != VK_SUCCESS) - { + result = vkEnumeratePhysicalDevices(vulkanContext->instance, &physicalDeviceCount, NULL); + if (result != VK_SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkEnumeratePhysicalDevices(): %s\n", getVulkanResultString(result)); quit(2); } - if(physicalDeviceCount == 0) - { + if (physicalDeviceCount == 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkEnumeratePhysicalDevices(): no physical devices\n"); quit(2); } - physicalDevices = SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount); - if(!physicalDevices) - { + physicalDevices = (VkPhysicalDevice *) SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount); + if (!physicalDevices) { SDL_OutOfMemory(); quit(2); } - result = - vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, physicalDevices); - if(result != VK_SUCCESS) - { + result = vkEnumeratePhysicalDevices(vulkanContext->instance, &physicalDeviceCount, physicalDevices); + if (result != VK_SUCCESS) { SDL_free(physicalDevices); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkEnumeratePhysicalDevices(): %s\n", getVulkanResultString(result)); quit(2); } - vulkanContext.physicalDevice = NULL; - for(physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount; - physicalDeviceIndex++) - { + vulkanContext->physicalDevice = NULL; + for (physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount; physicalDeviceIndex++) { uint32_t queueFamiliesCount = 0; - uint32_t queueFamilyIndex; + uint32_t queueFamilyIndex; uint32_t deviceExtensionCount = 0; - SDL_bool hasSwapchainExtension = SDL_FALSE; - uint32_t i; + SDL_bool hasSwapchainExtension = SDL_FALSE; + uint32_t i; - - VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex]; - vkGetPhysicalDeviceProperties(physicalDevice, &vulkanContext.physicalDeviceProperties); - if(VK_VERSION_MAJOR(vulkanContext.physicalDeviceProperties.apiVersion) < 1) + VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex]; + vkGetPhysicalDeviceProperties(physicalDevice, &vulkanContext->physicalDeviceProperties); + if(VK_VERSION_MAJOR(vulkanContext->physicalDeviceProperties.apiVersion) < 1) { continue; - vkGetPhysicalDeviceFeatures(physicalDevice, &vulkanContext.physicalDeviceFeatures); + } + vkGetPhysicalDeviceFeatures(physicalDevice, &vulkanContext->physicalDeviceFeatures); vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesCount, NULL); - if(queueFamiliesCount == 0) + if (queueFamiliesCount == 0) { continue; - if(queueFamiliesPropertiesAllocatedSize < queueFamiliesCount) - { + } + if (queueFamiliesPropertiesAllocatedSize < queueFamiliesCount) { SDL_free(queueFamiliesProperties); queueFamiliesPropertiesAllocatedSize = queueFamiliesCount; - queueFamiliesProperties = - SDL_malloc(sizeof(VkQueueFamilyProperties) * queueFamiliesPropertiesAllocatedSize); - if(!queueFamiliesProperties) - { + queueFamiliesProperties = (VkQueueFamilyProperties *) SDL_malloc(sizeof(VkQueueFamilyProperties) * queueFamiliesPropertiesAllocatedSize); + if (!queueFamiliesProperties) { SDL_free(physicalDevices); SDL_free(deviceExtensions); SDL_OutOfMemory(); quit(2); } } - vkGetPhysicalDeviceQueueFamilyProperties( - physicalDevice, &queueFamiliesCount, queueFamiliesProperties); - vulkanContext.graphicsQueueFamilyIndex = queueFamiliesCount; - vulkanContext.presentQueueFamilyIndex = queueFamiliesCount; - for(queueFamilyIndex = 0; queueFamilyIndex < queueFamiliesCount; - queueFamilyIndex++) - { + vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesCount, queueFamiliesProperties); + vulkanContext->graphicsQueueFamilyIndex = queueFamiliesCount; + vulkanContext->presentQueueFamilyIndex = queueFamiliesCount; + for (queueFamilyIndex = 0; queueFamilyIndex < queueFamiliesCount; queueFamilyIndex++) { VkBool32 supported = 0; - if(queueFamiliesProperties[queueFamilyIndex].queueCount == 0) + if (queueFamiliesProperties[queueFamilyIndex].queueCount == 0) { continue; - if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) - vulkanContext.graphicsQueueFamilyIndex = queueFamilyIndex; - result = vkGetPhysicalDeviceSurfaceSupportKHR( - physicalDevice, queueFamilyIndex, vulkanContext.surface, &supported); - if(result != VK_SUCCESS) - { + } + + if (queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) { + vulkanContext->graphicsQueueFamilyIndex = queueFamilyIndex; + } + + result = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, vulkanContext->surface, &supported); + if (result != VK_SUCCESS) { SDL_free(physicalDevices); SDL_free(queueFamiliesProperties); SDL_free(deviceExtensions); @@ -419,20 +374,22 @@ static void findPhysicalDevice(void) getVulkanResultString(result)); quit(2); } - if(supported) - { - vulkanContext.presentQueueFamilyIndex = queueFamilyIndex; - if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) + if (supported) { + vulkanContext->presentQueueFamilyIndex = queueFamilyIndex; + if (queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) { break; // use this queue because it can present and do graphics + } } } - if(vulkanContext.graphicsQueueFamilyIndex == queueFamiliesCount) // no good queues found + + if (vulkanContext->graphicsQueueFamilyIndex == queueFamiliesCount) { // no good queues found continue; - if(vulkanContext.presentQueueFamilyIndex == queueFamiliesCount) // no good queues found + } + if (vulkanContext->presentQueueFamilyIndex == queueFamiliesCount) { // no good queues found continue; - result = - vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &deviceExtensionCount, NULL); - if(result != VK_SUCCESS) + } + result = vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &deviceExtensionCount, NULL); + if (result != VK_SUCCESS) { SDL_free(physicalDevices); SDL_free(queueFamiliesProperties); @@ -442,26 +399,22 @@ static void findPhysicalDevice(void) getVulkanResultString(result)); quit(2); } - if(deviceExtensionCount == 0) + if (deviceExtensionCount == 0) { continue; - if(deviceExtensionsAllocatedSize < deviceExtensionCount) - { + } + if (deviceExtensionsAllocatedSize < deviceExtensionCount) { SDL_free(deviceExtensions); deviceExtensionsAllocatedSize = deviceExtensionCount; - deviceExtensions = - SDL_malloc(sizeof(VkExtensionProperties) * deviceExtensionsAllocatedSize); - if(!deviceExtensions) - { + deviceExtensions = SDL_malloc(sizeof(VkExtensionProperties) * deviceExtensionsAllocatedSize); + if (!deviceExtensions) { SDL_free(physicalDevices); SDL_free(queueFamiliesProperties); SDL_OutOfMemory(); quit(2); } } - result = vkEnumerateDeviceExtensionProperties( - physicalDevice, NULL, &deviceExtensionCount, deviceExtensions); - if(result != VK_SUCCESS) - { + result = vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &deviceExtensionCount, deviceExtensions); + if (result != VK_SUCCESS) { SDL_free(physicalDevices); SDL_free(queueFamiliesProperties); SDL_free(deviceExtensions); @@ -470,24 +423,22 @@ static void findPhysicalDevice(void) getVulkanResultString(result)); quit(2); } - for(i = 0; i < deviceExtensionCount; i++) - { - if(0 == SDL_strcmp(deviceExtensions[i].extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME)) - { + for (i = 0; i < deviceExtensionCount; i++) { + if(SDL_strcmp(deviceExtensions[i].extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) { hasSwapchainExtension = SDL_TRUE; break; } } - if(!hasSwapchainExtension) + if (!hasSwapchainExtension) { continue; - vulkanContext.physicalDevice = physicalDevice; + } + vulkanContext->physicalDevice = physicalDevice; break; } SDL_free(physicalDevices); SDL_free(queueFamiliesProperties); SDL_free(deviceExtensions); - if(!vulkanContext.physicalDevice) - { + if (!vulkanContext->physicalDevice) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Vulkan: no viable physical devices found"); quit(2); } @@ -495,16 +446,16 @@ static void findPhysicalDevice(void) static void createDevice(void) { - VkDeviceQueueCreateInfo deviceQueueCreateInfo[1] = {0}; + VkDeviceQueueCreateInfo deviceQueueCreateInfo[1] = { {0} }; static const float queuePriority[] = {1.0f}; VkDeviceCreateInfo deviceCreateInfo = {0}; static const char *const deviceExtensionNames[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, }; - VkResult result; + VkResult result; - deviceQueueCreateInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - deviceQueueCreateInfo->queueFamilyIndex = vulkanContext.graphicsQueueFamilyIndex; + deviceQueueCreateInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + deviceQueueCreateInfo->queueFamilyIndex = vulkanContext->graphicsQueueFamilyIndex; deviceQueueCreateInfo->queueCount = 1; deviceQueueCreateInfo->pQueuePriorities = &queuePriority[0]; @@ -514,13 +465,10 @@ static void createDevice(void) deviceCreateInfo.pEnabledFeatures = NULL; deviceCreateInfo.enabledExtensionCount = SDL_arraysize(deviceExtensionNames); deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames; - result = vkCreateDevice( - vulkanContext.physicalDevice, &deviceCreateInfo, NULL, &vulkanContext.device); - if(result != VK_SUCCESS) - { - vulkanContext.device = VK_NULL_HANDLE; - SDL_LogError( - SDL_LOG_CATEGORY_APPLICATION, "vkCreateDevice(): %s\n", getVulkanResultString(result)); + result = vkCreateDevice(vulkanContext->physicalDevice, &deviceCreateInfo, NULL, &vulkanContext->device); + if (result != VK_SUCCESS) { + vulkanContext->device = VK_NULL_HANDLE; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkCreateDevice(): %s\n", getVulkanResultString(result)); quit(2); } } @@ -528,9 +476,8 @@ static void createDevice(void) static void loadDeviceFunctions(void) { #define VULKAN_DEVICE_FUNCTION(name) \ - name = (PFN_##name)vkGetDeviceProcAddr(vulkanContext.device, #name); \ - if(!name) \ - { \ + name = (PFN_##name)vkGetDeviceProcAddr(vulkanContext->device, #name); \ + if (!name) { \ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \ "vkGetDeviceProcAddr(device, \"" #name "\") failed\n"); \ quit(2); \ @@ -547,28 +494,28 @@ static void loadDeviceFunctions(void) static void getQueues(void) { - vkGetDeviceQueue(vulkanContext.device, - vulkanContext.graphicsQueueFamilyIndex, + vkGetDeviceQueue(vulkanContext->device, + vulkanContext->graphicsQueueFamilyIndex, 0, - &vulkanContext.graphicsQueue); - if(vulkanContext.graphicsQueueFamilyIndex != vulkanContext.presentQueueFamilyIndex) - vkGetDeviceQueue(vulkanContext.device, - vulkanContext.presentQueueFamilyIndex, + &vulkanContext->graphicsQueue); + if (vulkanContext->graphicsQueueFamilyIndex != vulkanContext->presentQueueFamilyIndex) { + vkGetDeviceQueue(vulkanContext->device, + vulkanContext->presentQueueFamilyIndex, 0, - &vulkanContext.presentQueue); - else - vulkanContext.presentQueue = vulkanContext.graphicsQueue; + &vulkanContext->presentQueue); + } else { + vulkanContext->presentQueue = vulkanContext->graphicsQueue; + } } static void createSemaphore(VkSemaphore *semaphore) { - VkResult result; + VkResult result; VkSemaphoreCreateInfo createInfo = {0}; createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - result = vkCreateSemaphore(vulkanContext.device, &createInfo, NULL, semaphore); - if(result != VK_SUCCESS) - { + result = vkCreateSemaphore(vulkanContext->device, &createInfo, NULL, semaphore); + if (result != VK_SUCCESS) { *semaphore = VK_NULL_HANDLE; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkCreateSemaphore(): %s\n", @@ -579,16 +526,14 @@ static void createSemaphore(VkSemaphore *semaphore) static void createSemaphores(void) { - createSemaphore(&vulkanContext.imageAvailableSemaphore); - createSemaphore(&vulkanContext.renderingFinishedSemaphore); + createSemaphore(&vulkanContext->imageAvailableSemaphore); + createSemaphore(&vulkanContext->renderingFinishedSemaphore); } static void getSurfaceCaps(void) { - VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR( - vulkanContext.physicalDevice, vulkanContext.surface, &vulkanContext.surfaceCapabilities); - if(result != VK_SUCCESS) - { + VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vulkanContext->physicalDevice, vulkanContext->surface, &vulkanContext->surfaceCapabilities); + if (result != VK_SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): %s\n", getVulkanResultString(result)); @@ -596,8 +541,7 @@ static void getSurfaceCaps(void) } // check surface usage - if(!(vulkanContext.surfaceCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) - { + if (!(vulkanContext->surfaceCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Vulkan surface doesn't support VK_IMAGE_USAGE_TRANSFER_DST_BIT\n"); quit(2); @@ -606,38 +550,33 @@ static void getSurfaceCaps(void) static void getSurfaceFormats(void) { - VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice, - vulkanContext.surface, - &vulkanContext.surfaceFormatsCount, + VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext->physicalDevice, + vulkanContext->surface, + &vulkanContext->surfaceFormatsCount, NULL); - if(result != VK_SUCCESS) - { - vulkanContext.surfaceFormatsCount = 0; + if (result != VK_SUCCESS) { + vulkanContext->surfaceFormatsCount = 0; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n", getVulkanResultString(result)); quit(2); } - if(vulkanContext.surfaceFormatsCount > vulkanContext.surfaceFormatsAllocatedCount) - { - vulkanContext.surfaceFormatsAllocatedCount = vulkanContext.surfaceFormatsCount; - SDL_free(vulkanContext.surfaceFormats); - vulkanContext.surfaceFormats = - SDL_malloc(sizeof(VkSurfaceFormatKHR) * vulkanContext.surfaceFormatsAllocatedCount); - if(!vulkanContext.surfaceFormats) - { - vulkanContext.surfaceFormatsCount = 0; + if (vulkanContext->surfaceFormatsCount > vulkanContext->surfaceFormatsAllocatedCount) { + vulkanContext->surfaceFormatsAllocatedCount = vulkanContext->surfaceFormatsCount; + SDL_free(vulkanContext->surfaceFormats); + vulkanContext->surfaceFormats = (VkSurfaceFormatKHR *) SDL_malloc(sizeof(VkSurfaceFormatKHR) * vulkanContext->surfaceFormatsAllocatedCount); + if (!vulkanContext->surfaceFormats) { + vulkanContext->surfaceFormatsCount = 0; SDL_OutOfMemory(); quit(2); } } - result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice, - vulkanContext.surface, - &vulkanContext.surfaceFormatsCount, - vulkanContext.surfaceFormats); - if(result != VK_SUCCESS) - { - vulkanContext.surfaceFormatsCount = 0; + result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext->physicalDevice, + vulkanContext->surface, + &vulkanContext->surfaceFormatsCount, + vulkanContext->surfaceFormats); + if (result != VK_SUCCESS) { + vulkanContext->surfaceFormatsCount = 0; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n", getVulkanResultString(result)); @@ -647,35 +586,31 @@ static void getSurfaceFormats(void) static void getSwapchainImages(void) { - VkResult result; + VkResult result; - SDL_free(vulkanContext.swapchainImages); - vulkanContext.swapchainImages = NULL; - result = vkGetSwapchainImagesKHR( - vulkanContext.device, vulkanContext.swapchain, &vulkanContext.swapchainImageCount, NULL); - if(result != VK_SUCCESS) - { - vulkanContext.swapchainImageCount = 0; + SDL_free(vulkanContext->swapchainImages); + vulkanContext->swapchainImages = NULL; + result = vkGetSwapchainImagesKHR(vulkanContext->device, vulkanContext->swapchain, &vulkanContext->swapchainImageCount, NULL); + if (result != VK_SUCCESS) { + vulkanContext->swapchainImageCount = 0; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkGetSwapchainImagesKHR(): %s\n", getVulkanResultString(result)); quit(2); } - vulkanContext.swapchainImages = SDL_malloc(sizeof(VkImage) * vulkanContext.swapchainImageCount); - if(!vulkanContext.swapchainImages) - { + vulkanContext->swapchainImages = SDL_malloc(sizeof(VkImage) * vulkanContext->swapchainImageCount); + if (!vulkanContext->swapchainImages) { SDL_OutOfMemory(); quit(2); } - result = vkGetSwapchainImagesKHR(vulkanContext.device, - vulkanContext.swapchain, - &vulkanContext.swapchainImageCount, - vulkanContext.swapchainImages); - if(result != VK_SUCCESS) - { - SDL_free(vulkanContext.swapchainImages); - vulkanContext.swapchainImages = NULL; - vulkanContext.swapchainImageCount = 0; + result = vkGetSwapchainImagesKHR(vulkanContext->device, + vulkanContext->swapchain, + &vulkanContext->swapchainImageCount, + vulkanContext->swapchainImages); + if (result != VK_SUCCESS) { + SDL_free(vulkanContext->swapchainImages); + vulkanContext->swapchainImages = NULL; + vulkanContext->swapchainImageCount = 0; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkGetSwapchainImagesKHR(): %s\n", getVulkanResultString(result)); @@ -685,116 +620,125 @@ static void getSwapchainImages(void) static SDL_bool createSwapchain(void) { - uint32_t i; - int w, h; - VkSwapchainCreateInfoKHR createInfo = {0}; - VkResult result; + uint32_t i; + int w, h; + VkSwapchainCreateInfoKHR createInfo = {0}; + VkResult result; // pick an image count - vulkanContext.swapchainDesiredImageCount = vulkanContext.surfaceCapabilities.minImageCount + 1; - if(vulkanContext.swapchainDesiredImageCount > vulkanContext.surfaceCapabilities.maxImageCount - && vulkanContext.surfaceCapabilities.maxImageCount > 0) - vulkanContext.swapchainDesiredImageCount = vulkanContext.surfaceCapabilities.maxImageCount; + vulkanContext->swapchainDesiredImageCount = vulkanContext->surfaceCapabilities.minImageCount + 1; + if ( (vulkanContext->swapchainDesiredImageCount > vulkanContext->surfaceCapabilities.maxImageCount) && + (vulkanContext->surfaceCapabilities.maxImageCount > 0) ) { + vulkanContext->swapchainDesiredImageCount = vulkanContext->surfaceCapabilities.maxImageCount; + } // pick a format - if(vulkanContext.surfaceFormatsCount == 1 - && vulkanContext.surfaceFormats[0].format == VK_FORMAT_UNDEFINED) - { + if ( (vulkanContext->surfaceFormatsCount == 1) && + (vulkanContext->surfaceFormats[0].format == VK_FORMAT_UNDEFINED) ) { // aren't any preferred formats, so we pick - vulkanContext.surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - vulkanContext.surfaceFormat.format = VK_FORMAT_R8G8B8A8_UNORM; - } - else - { - vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[0]; - for(i = 0; i < vulkanContext.surfaceFormatsCount; i++) - { - if(vulkanContext.surfaceFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM) - { - vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[i]; + vulkanContext->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + vulkanContext->surfaceFormat.format = VK_FORMAT_R8G8B8A8_UNORM; + } else { + vulkanContext->surfaceFormat = vulkanContext->surfaceFormats[0]; + for (i = 0; i < vulkanContext->surfaceFormatsCount; i++) { + if(vulkanContext->surfaceFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM) { + vulkanContext->surfaceFormat = vulkanContext->surfaceFormats[i]; break; } } } // get size - SDL_Vulkan_GetDrawableSize(state->windows[0], &w, &h); - vulkanContext.swapchainSize.width = w; - vulkanContext.swapchainSize.height = h; - if(w == 0 || h == 0) + SDL_Vulkan_GetDrawableSize(vulkanContext->window, &w, &h); + + // Clamp the size to the allowable image extent. + // SDL_Vulkan_GetDrawableSize()'s result it not always in this range (bug #3287) + vulkanContext->swapchainSize.width = SDL_clamp((uint32_t) w, + vulkanContext->surfaceCapabilities.minImageExtent.width, + vulkanContext->surfaceCapabilities.maxImageExtent.width); + + vulkanContext->swapchainSize.height = SDL_clamp((uint32_t) h, + vulkanContext->surfaceCapabilities.minImageExtent.height, + vulkanContext->surfaceCapabilities.maxImageExtent.height); + + if (w == 0 || h == 0) { return SDL_FALSE; + } + + getSurfaceCaps(); createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - createInfo.surface = vulkanContext.surface; - createInfo.minImageCount = vulkanContext.swapchainDesiredImageCount; - createInfo.imageFormat = vulkanContext.surfaceFormat.format; - createInfo.imageColorSpace = vulkanContext.surfaceFormat.colorSpace; - createInfo.imageExtent = vulkanContext.swapchainSize; + createInfo.surface = vulkanContext->surface; + createInfo.minImageCount = vulkanContext->swapchainDesiredImageCount; + createInfo.imageFormat = vulkanContext->surfaceFormat.format; + createInfo.imageColorSpace = vulkanContext->surfaceFormat.colorSpace; + createInfo.imageExtent = vulkanContext->swapchainSize; createInfo.imageArrayLayers = 1; createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - createInfo.preTransform = vulkanContext.surfaceCapabilities.currentTransform; + createInfo.preTransform = vulkanContext->surfaceCapabilities.currentTransform; createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR; createInfo.clipped = VK_TRUE; - createInfo.oldSwapchain = vulkanContext.swapchain; - result = - vkCreateSwapchainKHR(vulkanContext.device, &createInfo, NULL, &vulkanContext.swapchain); - if(createInfo.oldSwapchain) - vkDestroySwapchainKHR(vulkanContext.device, createInfo.oldSwapchain, NULL); - if(result != VK_SUCCESS) - { - vulkanContext.swapchain = VK_NULL_HANDLE; + createInfo.oldSwapchain = vulkanContext->swapchain; + result = vkCreateSwapchainKHR(vulkanContext->device, &createInfo, NULL, &vulkanContext->swapchain); + + if (createInfo.oldSwapchain) { + vkDestroySwapchainKHR(vulkanContext->device, createInfo.oldSwapchain, NULL); + } + + if(result != VK_SUCCESS) { + vulkanContext->swapchain = VK_NULL_HANDLE; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkCreateSwapchainKHR(): %s\n", getVulkanResultString(result)); quit(2); } + getSwapchainImages(); return SDL_TRUE; } static void destroySwapchain(void) { - if(vulkanContext.swapchain) - vkDestroySwapchainKHR(vulkanContext.device, vulkanContext.swapchain, NULL); - vulkanContext.swapchain = VK_NULL_HANDLE; - SDL_free(vulkanContext.swapchainImages); - vulkanContext.swapchainImages = NULL; + if (vulkanContext->swapchain) { + vkDestroySwapchainKHR(vulkanContext->device, vulkanContext->swapchain, NULL); + vulkanContext->swapchain = VK_NULL_HANDLE; + } + SDL_free(vulkanContext->swapchainImages); + vulkanContext->swapchainImages = NULL; } static void destroyCommandBuffers(void) { - if(vulkanContext.commandBuffers) - vkFreeCommandBuffers(vulkanContext.device, - vulkanContext.commandPool, - vulkanContext.swapchainImageCount, - vulkanContext.commandBuffers); - SDL_free(vulkanContext.commandBuffers); - vulkanContext.commandBuffers = NULL; + if (vulkanContext->commandBuffers) { + vkFreeCommandBuffers(vulkanContext->device, + vulkanContext->commandPool, + vulkanContext->swapchainImageCount, + vulkanContext->commandBuffers); + SDL_free(vulkanContext->commandBuffers); + vulkanContext->commandBuffers = NULL; + } } static void destroyCommandPool(void) { - if(vulkanContext.commandPool) - vkDestroyCommandPool(vulkanContext.device, vulkanContext.commandPool, NULL); - vulkanContext.commandPool = VK_NULL_HANDLE; + if (vulkanContext->commandPool) { + vkDestroyCommandPool(vulkanContext->device, vulkanContext->commandPool, NULL); + } + vulkanContext->commandPool = VK_NULL_HANDLE; } static void createCommandPool(void) { - VkResult result; - + VkResult result; VkCommandPoolCreateInfo createInfo = {0}; createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - createInfo.flags = - VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; - createInfo.queueFamilyIndex = vulkanContext.graphicsQueueFamilyIndex; - result = - vkCreateCommandPool(vulkanContext.device, &createInfo, NULL, &vulkanContext.commandPool); - if(result != VK_SUCCESS) - { - vulkanContext.commandPool = VK_NULL_HANDLE; + createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; + createInfo.queueFamilyIndex = vulkanContext->graphicsQueueFamilyIndex; + result = vkCreateCommandPool(vulkanContext->device, &createInfo, NULL, &vulkanContext->commandPool); + if (result != VK_SUCCESS) { + vulkanContext->commandPool = VK_NULL_HANDLE; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkCreateCommandPool(): %s\n", getVulkanResultString(result)); @@ -804,21 +748,17 @@ static void createCommandPool(void) static void createCommandBuffers(void) { - VkResult result; - + VkResult result; VkCommandBufferAllocateInfo allocateInfo = {0}; allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - allocateInfo.commandPool = vulkanContext.commandPool; + allocateInfo.commandPool = vulkanContext->commandPool; allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocateInfo.commandBufferCount = vulkanContext.swapchainImageCount; - vulkanContext.commandBuffers = - SDL_malloc(sizeof(VkCommandBuffer) * vulkanContext.swapchainImageCount); - result = - vkAllocateCommandBuffers(vulkanContext.device, &allocateInfo, vulkanContext.commandBuffers); - if(result != VK_SUCCESS) - { - SDL_free(vulkanContext.commandBuffers); - vulkanContext.commandBuffers = NULL; + allocateInfo.commandBufferCount = vulkanContext->swapchainImageCount; + vulkanContext->commandBuffers = (VkCommandBuffer *) SDL_malloc(sizeof(VkCommandBuffer) * vulkanContext->swapchainImageCount); + result = vkAllocateCommandBuffers(vulkanContext->device, &allocateInfo, vulkanContext->commandBuffers); + if(result != VK_SUCCESS) { + SDL_free(vulkanContext->commandBuffers); + vulkanContext->commandBuffers = NULL; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkAllocateCommandBuffers(): %s\n", getVulkanResultString(result)); @@ -828,31 +768,25 @@ static void createCommandBuffers(void) static void createFences(void) { - uint32_t i; + uint32_t i; - vulkanContext.fences = SDL_malloc(sizeof(VkFence) * vulkanContext.swapchainImageCount); - if(!vulkanContext.fences) - { + vulkanContext->fences = SDL_malloc(sizeof(VkFence) * vulkanContext->swapchainImageCount); + if (!vulkanContext->fences) { SDL_OutOfMemory(); quit(2); } - for(i = 0; i < vulkanContext.swapchainImageCount; i++) - { - VkResult result; - + for (i = 0; i < vulkanContext->swapchainImageCount; i++) { + VkResult result; VkFenceCreateInfo createInfo = {0}; createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; createInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; - result = - vkCreateFence(vulkanContext.device, &createInfo, NULL, &vulkanContext.fences[i]); - if(result != VK_SUCCESS) - { - for(; i > 0; i--) - { - vkDestroyFence(vulkanContext.device, vulkanContext.fences[i - 1], NULL); + result = vkCreateFence(vulkanContext->device, &createInfo, NULL, &vulkanContext->fences[i]); + if(result != VK_SUCCESS) { + for(; i > 0; i--) { + vkDestroyFence(vulkanContext->device, vulkanContext->fences[i - 1], NULL); } - SDL_free(vulkanContext.fences); - vulkanContext.fences = NULL; + SDL_free(vulkanContext->fences); + vulkanContext->fences = NULL; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkCreateFence(): %s\n", getVulkanResultString(result)); @@ -863,16 +797,17 @@ static void createFences(void) static void destroyFences(void) { - uint32_t i; + uint32_t i; - if(!vulkanContext.fences) + if (!vulkanContext->fences) { return; - for(i = 0; i < vulkanContext.swapchainImageCount; i++) - { - vkDestroyFence(vulkanContext.device, vulkanContext.fences[i], NULL); } - SDL_free(vulkanContext.fences); - vulkanContext.fences = NULL; + + for (i = 0; i < vulkanContext->swapchainImageCount; i++) { + vkDestroyFence(vulkanContext->device, vulkanContext->fences[i], NULL); + } + SDL_free(vulkanContext->fences); + vulkanContext->fences = NULL; } static void recordPipelineImageBarrier(VkCommandBuffer commandBuffer, @@ -910,14 +845,13 @@ static void recordPipelineImageBarrier(VkCommandBuffer commandBuffer, static void rerecordCommandBuffer(uint32_t frameIndex, const VkClearColorValue *clearColor) { - VkCommandBuffer commandBuffer = vulkanContext.commandBuffers[frameIndex]; - VkImage image = vulkanContext.swapchainImages[frameIndex]; - VkCommandBufferBeginInfo beginInfo = {0}; + VkCommandBuffer commandBuffer = vulkanContext->commandBuffers[frameIndex]; + VkImage image = vulkanContext->swapchainImages[frameIndex]; + VkCommandBufferBeginInfo beginInfo = {0}; VkImageSubresourceRange clearRange = {0}; VkResult result = vkResetCommandBuffer(commandBuffer, 0); - if(result != VK_SUCCESS) - { + if(result != VK_SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkResetCommandBuffer(): %s\n", getVulkanResultString(result)); @@ -926,8 +860,7 @@ static void rerecordCommandBuffer(uint32_t frameIndex, const VkClearColorValue * beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; result = vkBeginCommandBuffer(commandBuffer, &beginInfo); - if(result != VK_SUCCESS) - { + if (result != VK_SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkBeginCommandBuffer(): %s\n", getVulkanResultString(result)); @@ -944,8 +877,7 @@ static void rerecordCommandBuffer(uint32_t frameIndex, const VkClearColorValue * clearRange.levelCount = 1; clearRange.baseArrayLayer = 0; clearRange.layerCount = 1; - vkCmdClearColorImage( - commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clearColor, 1, &clearRange); + vkCmdClearColorImage(commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clearColor, 1, &clearRange); recordPipelineImageBarrier(commandBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, @@ -953,8 +885,7 @@ static void rerecordCommandBuffer(uint32_t frameIndex, const VkClearColorValue * VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, image); result = vkEndCommandBuffer(commandBuffer); - if(result != VK_SUCCESS) - { + if (result != VK_SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkEndCommandBuffer(): %s\n", getVulkanResultString(result)); @@ -964,11 +895,13 @@ static void rerecordCommandBuffer(uint32_t frameIndex, const VkClearColorValue * static void destroySwapchainAndSwapchainSpecificStuff(SDL_bool doDestroySwapchain) { + vkDeviceWaitIdle(vulkanContext->device); destroyFences(); destroyCommandBuffers(); destroyCommandPool(); - if(doDestroySwapchain) + if (doDestroySwapchain) { destroySwapchain(); + } } static SDL_bool createNewSwapchainAndSwapchainSpecificStuff(void) @@ -976,8 +909,9 @@ static SDL_bool createNewSwapchainAndSwapchainSpecificStuff(void) destroySwapchainAndSwapchainSpecificStuff(SDL_FALSE); getSurfaceCaps(); getSurfaceFormats(); - if(!createSwapchain()) + if(!createSwapchain()) { return SDL_FALSE; + } createCommandPool(); createCommandBuffers(); createFences(); @@ -986,36 +920,70 @@ static SDL_bool createNewSwapchainAndSwapchainSpecificStuff(void) static void initVulkan(void) { + int i; + SDL_Vulkan_LoadLibrary(NULL); - SDL_memset(&vulkanContext, 0, sizeof(VulkanContext)); - loadGlobalFunctions(); - createInstance(); - loadInstanceFunctions(); - createSurface(); - findPhysicalDevice(); - createDevice(); - loadDeviceFunctions(); - getQueues(); - createSemaphores(); - createNewSwapchainAndSwapchainSpecificStuff(); + + vulkanContexts = (VulkanContext *) SDL_calloc(state->num_windows, sizeof (VulkanContext)); + if (!vulkanContexts) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!"); + quit(2); + } + + for (i = 0; i < state->num_windows; ++i) { + vulkanContext = &vulkanContexts[i]; + vulkanContext->window = state->windows[i]; + loadGlobalFunctions(); + createInstance(); + loadInstanceFunctions(); + createSurface(); + findPhysicalDevice(); + createDevice(); + loadDeviceFunctions(); + getQueues(); + createSemaphores(); + createNewSwapchainAndSwapchainSpecificStuff(); + } } -static void shutdownVulkan(void) +static void shutdownVulkan(SDL_bool doDestroySwapchain) { - if(vulkanContext.device && vkDeviceWaitIdle) - vkDeviceWaitIdle(vulkanContext.device); - destroySwapchainAndSwapchainSpecificStuff(SDL_TRUE); - if(vulkanContext.imageAvailableSemaphore && vkDestroySemaphore) - vkDestroySemaphore(vulkanContext.device, vulkanContext.imageAvailableSemaphore, NULL); - if(vulkanContext.renderingFinishedSemaphore && vkDestroySemaphore) - vkDestroySemaphore(vulkanContext.device, vulkanContext.renderingFinishedSemaphore, NULL); - if(vulkanContext.device && vkDestroyDevice) - vkDestroyDevice(vulkanContext.device, NULL); - if(vulkanContext.surface && vkDestroySurfaceKHR) - vkDestroySurfaceKHR(vulkanContext.instance, vulkanContext.surface, NULL); - if(vulkanContext.instance && vkDestroyInstance) - vkDestroyInstance(vulkanContext.instance, NULL); - SDL_free(vulkanContext.surfaceFormats); + if (vulkanContexts) { + int i; + for (i = 0; i < state->num_windows; ++i) { + vulkanContext = &vulkanContexts[i]; + if (vulkanContext->device && vkDeviceWaitIdle) { + vkDeviceWaitIdle(vulkanContext->device); + } + + destroySwapchainAndSwapchainSpecificStuff(doDestroySwapchain); + + if (vulkanContext->imageAvailableSemaphore && vkDestroySemaphore) { + vkDestroySemaphore(vulkanContext->device, vulkanContext->imageAvailableSemaphore, NULL); + } + + if (vulkanContext->renderingFinishedSemaphore && vkDestroySemaphore) { + vkDestroySemaphore(vulkanContext->device, vulkanContext->renderingFinishedSemaphore, NULL); + } + + if (vulkanContext->device && vkDestroyDevice) { + vkDestroyDevice(vulkanContext->device, NULL); + } + + if (vulkanContext->surface && vkDestroySurfaceKHR) { + vkDestroySurfaceKHR(vulkanContext->instance, vulkanContext->surface, NULL); + } + + if (vulkanContext->instance && vkDestroyInstance) { + vkDestroyInstance(vulkanContext->instance, NULL); + } + + SDL_free(vulkanContext->surfaceFormats); + } + SDL_free(vulkanContexts); + vulkanContexts = NULL; + } + SDL_Vulkan_UnloadLibrary(); } @@ -1024,47 +992,42 @@ static SDL_bool render(void) uint32_t frameIndex; VkResult result; double currentTime; - VkClearColorValue clearColor = {0}; + VkClearColorValue clearColor = { {0} }; VkPipelineStageFlags waitDestStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; VkSubmitInfo submitInfo = {0}; VkPresentInfoKHR presentInfo = {0}; int w, h; - if(!vulkanContext.swapchain) - { + if (!vulkanContext->swapchain) { SDL_bool retval = createNewSwapchainAndSwapchainSpecificStuff(); if(!retval) SDL_Delay(100); return retval; } - result = vkAcquireNextImageKHR(vulkanContext.device, - vulkanContext.swapchain, + result = vkAcquireNextImageKHR(vulkanContext->device, + vulkanContext->swapchain, UINT64_MAX, - vulkanContext.imageAvailableSemaphore, + vulkanContext->imageAvailableSemaphore, VK_NULL_HANDLE, &frameIndex); - if(result == VK_ERROR_OUT_OF_DATE_KHR) + if (result == VK_ERROR_OUT_OF_DATE_KHR) { return createNewSwapchainAndSwapchainSpecificStuff(); - if(result != VK_SUBOPTIMAL_KHR && result != VK_SUCCESS) - { + } + + if ((result != VK_SUBOPTIMAL_KHR) && (result != VK_SUCCESS)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkAcquireNextImageKHR(): %s\n", getVulkanResultString(result)); quit(2); } - result = vkWaitForFences( - vulkanContext.device, 1, &vulkanContext.fences[frameIndex], VK_FALSE, UINT64_MAX); - if(result != VK_SUCCESS) - { - SDL_LogError( - SDL_LOG_CATEGORY_APPLICATION, "vkWaitForFences(): %s\n", getVulkanResultString(result)); + result = vkWaitForFences(vulkanContext->device, 1, &vulkanContext->fences[frameIndex], VK_FALSE, UINT64_MAX); + if (result != VK_SUCCESS) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkWaitForFences(): %s\n", getVulkanResultString(result)); quit(2); } - result = vkResetFences(vulkanContext.device, 1, &vulkanContext.fences[frameIndex]); - if(result != VK_SUCCESS) - { - SDL_LogError( - SDL_LOG_CATEGORY_APPLICATION, "vkResetFences(): %s\n", getVulkanResultString(result)); + result = vkResetFences(vulkanContext->device, 1, &vulkanContext->fences[frameIndex]); + if (result != VK_SUCCESS) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkResetFences(): %s\n", getVulkanResultString(result)); quit(2); } currentTime = (double)SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency(); @@ -1075,49 +1038,44 @@ static SDL_bool render(void) rerecordCommandBuffer(frameIndex, &clearColor); submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.waitSemaphoreCount = 1; - submitInfo.pWaitSemaphores = &vulkanContext.imageAvailableSemaphore; + submitInfo.pWaitSemaphores = &vulkanContext->imageAvailableSemaphore; submitInfo.pWaitDstStageMask = &waitDestStageMask; submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &vulkanContext.commandBuffers[frameIndex]; + submitInfo.pCommandBuffers = &vulkanContext->commandBuffers[frameIndex]; submitInfo.signalSemaphoreCount = 1; - submitInfo.pSignalSemaphores = &vulkanContext.renderingFinishedSemaphore; - result = vkQueueSubmit( - vulkanContext.graphicsQueue, 1, &submitInfo, vulkanContext.fences[frameIndex]); - if(result != VK_SUCCESS) - { - SDL_LogError( - SDL_LOG_CATEGORY_APPLICATION, "vkQueueSubmit(): %s\n", getVulkanResultString(result)); + submitInfo.pSignalSemaphores = &vulkanContext->renderingFinishedSemaphore; + result = vkQueueSubmit(vulkanContext->graphicsQueue, 1, &submitInfo, vulkanContext->fences[frameIndex]); + + if (result != VK_SUCCESS) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkQueueSubmit(): %s\n", getVulkanResultString(result)); quit(2); } presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.waitSemaphoreCount = 1; - presentInfo.pWaitSemaphores = &vulkanContext.renderingFinishedSemaphore; + presentInfo.pWaitSemaphores = &vulkanContext->renderingFinishedSemaphore; presentInfo.swapchainCount = 1; - presentInfo.pSwapchains = &vulkanContext.swapchain; + presentInfo.pSwapchains = &vulkanContext->swapchain; presentInfo.pImageIndices = &frameIndex; - result = vkQueuePresentKHR(vulkanContext.presentQueue, &presentInfo); - if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) - { + result = vkQueuePresentKHR(vulkanContext->presentQueue, &presentInfo); + if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR)) { return createNewSwapchainAndSwapchainSpecificStuff(); } - if(result != VK_SUCCESS) - { + + if (result != VK_SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkQueuePresentKHR(): %s\n", getVulkanResultString(result)); quit(2); } - SDL_Vulkan_GetDrawableSize(state->windows[0], &w, &h); - if(w != (int)vulkanContext.swapchainSize.width || h != (int)vulkanContext.swapchainSize.height) - { + SDL_Vulkan_GetDrawableSize(vulkanContext->window, &w, &h); + if(w != (int)vulkanContext->swapchainSize.width || h != (int)vulkanContext->swapchainSize.height) { return createNewSwapchainAndSwapchainSpecificStuff(); } return SDL_TRUE; } -int main(int argc, char *argv[]) +int main(int argc, char **argv) { - int fsaa, accel; int done; SDL_DisplayMode mode; SDL_Event event; @@ -1127,20 +1085,14 @@ int main(int argc, char *argv[]) /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - /* Initialize parameters */ - fsaa = 0; - accel = -1; - /* Initialize test framework */ state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if(!state) - { + if(!state) { return 1; } /* Set Vulkan parameters */ state->window_flags |= SDL_WINDOW_VULKAN; - state->num_windows = 1; state->skip_renderer = 1; if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) { @@ -1162,26 +1114,38 @@ int main(int argc, char *argv[]) frames = 0; then = SDL_GetTicks(); done = 0; - while(!done) - { + while (!done) { /* Check for events */ - ++frames; - while(SDL_PollEvent(&event)) - { + frames++; + while(SDL_PollEvent(&event)) { + /* Need to destroy the swapchain before the window created + * by SDL. + */ + if (event.type == SDL_WINDOWEVENT_CLOSE) { + destroySwapchainAndSwapchainSpecificStuff(SDL_TRUE); + } SDLTest_CommonEvent(state, &event, &done); } - if(!done) - render(); + if (!done) { + int i; + for (i = 0; i < state->num_windows; ++i) { + if (state->windows[i]) { + vulkanContext = &vulkanContexts[i]; + render(); + } + } + } } /* Print out some timing information */ now = SDL_GetTicks(); - if(now > then) - { + if (now > then) { SDL_Log("%2.2f frames per second\n", ((double)frames * 1000) / (now - then)); } - quit(0); + + shutdownVulkan(SDL_TRUE); + SDLTest_CommonQuit(state); return 0; } diff --git a/Engine/lib/sdl/test/testwm2.c b/Engine/lib/sdl/test/testwm2.c index 2d3779b90..93bedf47b 100644 --- a/Engine/lib/sdl/test/testwm2.c +++ b/Engine/lib/sdl/test/testwm2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,6 +18,7 @@ #endif #include "SDL_test_common.h" +#include "SDL_test_font.h" static SDLTest_CommonState *state; int done; @@ -38,6 +39,8 @@ static const char *cursorNames[] = { }; int system_cursor = -1; SDL_Cursor *cursor = NULL; +SDL_bool relative_mode = SDL_FALSE; +int highlighted_mode = -1; /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ static void @@ -47,6 +50,99 @@ quit(int rc) exit(rc); } +/* Draws the modes menu, and stores the mode index under the mouse in highlighted_mode */ +static void +draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_Rect viewport) +{ + SDL_DisplayMode mode; + char text[1024]; + const int lineHeight = 10; + const int display_index = SDL_GetWindowDisplayIndex(window); + const int num_modes = SDL_GetNumDisplayModes(display_index); + int i; + int column_chars = 0; + int text_length; + int x, y; + int table_top; + SDL_Point mouse_pos = { -1, -1 }; + + /* Get mouse position */ + if (SDL_GetMouseFocus() == window) { + int window_x, window_y; + float logical_x, logical_y; + + SDL_GetMouseState(&window_x, &window_y); + SDL_RenderWindowToLogical(renderer, window_x, window_y, &logical_x, &logical_y); + + mouse_pos.x = (int)logical_x; + mouse_pos.y = (int)logical_y; + } + + x = 0; + y = viewport.y; + + y += lineHeight; + + SDL_snprintf(text, sizeof(text), "Click on a mode to set it with SDL_SetWindowDisplayMode"); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, x, y, text); + y += lineHeight; + + SDL_snprintf(text, sizeof(text), "Press Ctrl+Enter to toggle SDL_WINDOW_FULLSCREEN"); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, x, y, text); + y += lineHeight; + + table_top = y; + + /* Clear the cached mode under the mouse */ + if (window == SDL_GetMouseFocus()) { + highlighted_mode = -1; + } + + for (i = 0; i < num_modes; ++i) { + SDL_Rect cell_rect; + + if (0 != SDL_GetDisplayMode(display_index, i, &mode)) { + return; + } + + SDL_snprintf(text, sizeof(text), "%d: %dx%d@%dHz", + i, mode.w, mode.h, mode.refresh_rate); + + /* Update column width */ + text_length = (int)SDL_strlen(text); + column_chars = SDL_max(column_chars, text_length); + + /* Check if under mouse */ + cell_rect.x = x; + cell_rect.y = y; + cell_rect.w = text_length * FONT_CHARACTER_SIZE; + cell_rect.h = lineHeight; + + if (SDL_PointInRect(&mouse_pos, &cell_rect)) { + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + + /* Update cached mode under the mouse */ + if (window == SDL_GetMouseFocus()) { + highlighted_mode = i; + } + } else { + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + } + + SDLTest_DrawString(renderer, x, y, text); + y += lineHeight; + + if (y + lineHeight > (viewport.y + viewport.h)) { + /* Advance to next column */ + x += (column_chars + 1) * FONT_CHARACTER_SIZE; + y = table_top; + column_chars = 0; + } + } +} + void loop() { @@ -76,6 +172,17 @@ loop() SDL_GetDisplayName(SDL_GetWindowDisplayIndex(window))); } } + if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { + relative_mode = SDL_GetRelativeMouseMode(); + if (relative_mode) { + SDL_SetRelativeMouseMode(SDL_FALSE); + } + } + if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) { + if (relative_mode) { + SDL_SetRelativeMouseMode(SDL_TRUE); + } + } } if (event.type == SDL_KEYUP) { SDL_bool updateCursor = SDL_FALSE; @@ -100,12 +207,43 @@ loop() SDL_SetCursor(cursor); } } + if (event.type == SDL_MOUSEBUTTONUP) { + SDL_Window* window = SDL_GetMouseFocus(); + if (highlighted_mode != -1 && window != NULL) { + const int display_index = SDL_GetWindowDisplayIndex(window); + SDL_DisplayMode mode; + if (0 != SDL_GetDisplayMode(display_index, highlighted_mode, &mode)) { + SDL_Log("Couldn't get display mode"); + } else { + SDL_SetWindowDisplayMode(window, &mode); + } + } + } } for (i = 0; i < state->num_windows; ++i) { + SDL_Window* window = state->windows[i]; SDL_Renderer *renderer = state->renderers[i]; - SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); + if (window != NULL && renderer != NULL) { + int y = 0; + SDL_Rect viewport, menurect; + + SDL_RenderGetViewport(renderer, &viewport); + + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_CommonDrawWindowInfo(renderer, state->windows[i], &y); + + menurect.x = 0; + menurect.y = y; + menurect.w = viewport.w; + menurect.h = viewport.h - y; + draw_modes_menu(window, renderer, menurect); + + SDL_RenderPresent(renderer); + } } #ifdef __EMSCRIPTEN__ if (done) { diff --git a/Engine/lib/sdl/test/testyuv.c b/Engine/lib/sdl/test/testyuv.c index 0c12b8ede..9c89c3140 100644 --- a/Engine/lib/sdl/test/testyuv.c +++ b/Engine/lib/sdl/test/testyuv.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/testyuv_cvt.c b/Engine/lib/sdl/test/testyuv_cvt.c index 4d856cae3..ed354d8ac 100644 --- a/Engine/lib/sdl/test/testyuv_cvt.c +++ b/Engine/lib/sdl/test/testyuv_cvt.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,9 +31,9 @@ static void RGBtoYUV(Uint8 * rgb, int *yuv, SDL_YUV_CONVERSION_MODE mode, int mo // This formula is from Microsoft's documentation: // https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx // L = Kr * R + Kb * B + (1 - Kr - Kb) * G - // Y = floor(2^(M-8) * (219*(L-Z)/S + 16) + 0.5); - // U = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(B-L) / ((1-Kb)*S) + 128) + 0.5)); - // V = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(R-L) / ((1-Kr)*S) + 128) + 0.5)); + // Y = SDL_floor(2^(M-8) * (219*(L-Z)/S + 16) + 0.5); + // U = clip3(0, (2^M)-1, SDL_floor(2^(M-8) * (112*(B-L) / ((1-Kb)*S) + 128) + 0.5)); + // V = clip3(0, (2^M)-1, SDL_floor(2^(M-8) * (112*(R-L) / ((1-Kr)*S) + 128) + 0.5)); float S, Z, R, G, B, L, Kr, Kb, Y, U, V; if (mode == SDL_YUV_CONVERSION_BT709) { diff --git a/Engine/lib/sdl/test/testyuv_cvt.h b/Engine/lib/sdl/test/testyuv_cvt.h index 3896a8dec..57ddb7648 100644 --- a/Engine/lib/sdl/test/testyuv_cvt.h +++ b/Engine/lib/sdl/test/testyuv_cvt.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/torturethread.c b/Engine/lib/sdl/test/torturethread.c index 382a2ede1..d76f07755 100644 --- a/Engine/lib/sdl/test/torturethread.c +++ b/Engine/lib/sdl/test/torturethread.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Engine/lib/sdl/test/unifont-13.0.06-license.txt b/Engine/lib/sdl/test/unifont-13.0.06-license.txt new file mode 100644 index 000000000..94339e0f4 --- /dev/null +++ b/Engine/lib/sdl/test/unifont-13.0.06-license.txt @@ -0,0 +1,90 @@ +The SIL Open Font License version 1.1 is copied below, and is also +available with a FAQ at http://scripts.sil.org/OFL. + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/Engine/lib/sdl/test/unifont-13.0.06.hex b/Engine/lib/sdl/test/unifont-13.0.06.hex new file mode 100644 index 000000000..320686a0c --- /dev/null +++ b/Engine/lib/sdl/test/unifont-13.0.06.hex @@ -0,0 +1,57086 @@ +0000:AAAA00018000000180004A51EA505A51C99E0001800000018000000180005555 +0001:AAAA00018000000180003993C252325F8A527193800000018000000180005555 +0002:AAAA00018000000180003BA5C124311989247125800000018000000180005555 +0003:AAAA00018000000180007BA5C1247919C1247925800000018000000180005555 +0004:AAAA000180000001800079BFC2487A49C2487989800000018000000180005555 +0005:AAAA00018000000180007A4DC2527B53C2D67A4F800000018000000180005555 +0006:AAAA000180000001800031A5CA287A31CA2849A5800000018000000180005555 +0007:AAAA000180000001800073D1CA1073D1CA1073DF800000018000000180005555 +0008:AAAA00018000000180001E3991401E3191081E71800000018000000180005555 +0009:AAAA000180000001800022F9A2203E21A2202221800000018000000180005555 +000A:AAAA000180000001800020F9A08020F9A0803E81800000018000000180005555 +000B:AAAA000180000001800022F9A220222194200821800000018000000180005555 +000C:AAAA00018000000180003EF9A0803EF9A0802081800000018000000180005555 +000D:AAAA00018000000180001EF1A08820F1A0901E89800000018000000180005555 +000E:AAAA00018000000180001E71A0881C8982883C71800000018000000180005555 +000F:AAAA00018000000180001EF9A0201C2182203CF9800000018000000180005555 +0010:AAAA0001800000018000391DA510251DA51039DD800000018000000180005555 +0011:AAAA00018000000180007189CA184A09CA08719D800000018000000180005555 +0012:AAAA00018000000180007199CA044A09CA10719D800000018000000180005555 +0013:AAAA00018000000180007199CA044A19CA047199800000018000000180005555 +0014:AAAA00018000000180007185CA0C4A15CA1C7185800000018000000180005555 +0015:AAAA00018000000180004993EA546A59DBD44A53800000018000000180005555 +0016:AAAA00018000000180003453C29A311789127113800000018000000180005555 +0017:AAAA00018000000180007BB9C1247939C1247939800000018000000180005555 +0018:AAAA00018000000180003325C4B447ADC4A434A5800000018000000180005555 +0019:AAAA00018000000180003E89A0D83EA9A0883E89800000018000000180005555 +001A:AAAA00018000000180003A5DC252325D8A52719D800000018000000180005555 +001B:AAAA000180000001800079CFC2107991C0507B8F800000018000000180005555 +001C:AAAA00018000000180001E7190801E61901010E1800000018000000180005555 +001D:AAAA00018000000180000E719080166192100EE1800000018000000180005555 +001E:AAAA00018000000180001C7192801C61941012E1800000018000000180005555 +001F:AAAA000180000001800012719280126192100CE1800000018000000180005555 +0020:00000000000000000000000000000000 +0021:00000000080808080808080008080000 +0022:00002222222200000000000000000000 +0023:000000001212127E24247E4848480000 +0024:00000000083E4948380E09493E080000 +0025:00000000314A4A340808162929460000 +0026:000000001C2222141829454246390000 +0027:00000808080800000000000000000000 +0028:00000004080810101010101008080400 +0029:00000020101008080808080810102000 +002A:00000000000008492A1C2A4908000000 +002B:0000000000000808087F080808000000 +002C:00000000000000000000000018080810 +002D:0000000000000000003C000000000000 +002E:00000000000000000000000018180000 +002F:00000000020204080810102040400000 +0030:00000000182442464A52624224180000 +0031:000000000818280808080808083E0000 +0032:000000003C4242020C102040407E0000 +0033:000000003C4242021C020242423C0000 +0034:00000000040C142444447E0404040000 +0035:000000007E4040407C020202423C0000 +0036:000000001C2040407C424242423C0000 +0037:000000007E0202040404080808080000 +0038:000000003C4242423C424242423C0000 +0039:000000003C4242423E02020204380000 +003A:00000000000018180000001818000000 +003B:00000000000018180000001808081000 +003C:00000000000204081020100804020000 +003D:000000000000007E0000007E00000000 +003E:00000000004020100804081020400000 +003F:000000003C4242020408080008080000 +0040:000000001C224A565252524E201E0000 +0041:0000000018242442427E424242420000 +0042:000000007C4242427C424242427C0000 +0043:000000003C42424040404042423C0000 +0044:00000000784442424242424244780000 +0045:000000007E4040407C404040407E0000 +0046:000000007E4040407C40404040400000 +0047:000000003C424240404E4242463A0000 +0048:00000000424242427E42424242420000 +0049:000000003E08080808080808083E0000 +004A:000000001F0404040404044444380000 +004B:00000000424448506060504844420000 +004C:000000004040404040404040407E0000 +004D:00000000424266665A5A424242420000 +004E:0000000042626252524A4A4646420000 +004F:000000003C42424242424242423C0000 +0050:000000007C4242427C40404040400000 +0051:000000003C4242424242425A663C0300 +0052:000000007C4242427C48444442420000 +0053:000000003C424240300C0242423C0000 +0054:000000007F0808080808080808080000 +0055:000000004242424242424242423C0000 +0056:00000000414141222222141408080000 +0057:00000000424242425A5A666642420000 +0058:00000000424224241818242442420000 +0059:00000000414122221408080808080000 +005A:000000007E02020408102040407E0000 +005B:0000000E080808080808080808080E00 +005C:00000000404020101008080402020000 +005D:00000070101010101010101010107000 +005E:00001824420000000000000000000000 +005F:00000000000000000000000000007F00 +0060:00201008000000000000000000000000 +0061:0000000000003C42023E4242463A0000 +0062:0000004040405C6242424242625C0000 +0063:0000000000003C4240404040423C0000 +0064:0000000202023A4642424242463A0000 +0065:0000000000003C42427E4040423C0000 +0066:0000000C1010107C1010101010100000 +0067:0000000000023A44444438203C42423C +0068:0000004040405C624242424242420000 +0069:000000080800180808080808083E0000 +006A:0000000404000C040404040404044830 +006B:00000040404044485060504844420000 +006C:000000180808080808080808083E0000 +006D:00000000000076494949494949490000 +006E:0000000000005C624242424242420000 +006F:0000000000003C4242424242423C0000 +0070:0000000000005C6242424242625C4040 +0071:0000000000003A4642424242463A0202 +0072:0000000000005C624240404040400000 +0073:0000000000003C4240300C02423C0000 +0074:000000001010107C10101010100C0000 +0075:000000000000424242424242463A0000 +0076:00000000000042424224242418180000 +0077:00000000000041494949494949360000 +0078:00000000000042422418182442420000 +0079:0000000000004242424242261A02023C +007A:0000000000007E0204081020407E0000 +007B:0000000C10100808102010080810100C +007C:00000808080808080808080808080808 +007D:00000030080810100804081010080830 +007E:00000031494600000000000000000000 +007F:AAAA000180000001800073D1CA104BD1CA1073DF800000018000000180005555 +0080:AAAA0001800000018000719DCA5273D3C252425D800000018000000180005555 +0081:AAAA0001800000018000499DCA527A5DCA504991800000018000000180005555 +0082:AAAA00018000000180007393CA52739FCA127213800000018000000180005555 +0083:AAAA00018000000180004B93EA525B9FCA524B93800000018000000180005555 +0084:AAAA000180000001800074B9A6A425A5A4A474B9800000018000000180005555 +0085:AAAA00018000000180004BD1EA105BD1CA104BDF800000018000000180005555 +0086:AAAA000180000001800039CDC212319F88527393800000018000000180005555 +0087:AAAA000180000001800079CDC212799FC0527B93800000018000000180005555 +0088:AAAA00018000000180004B9DC9207919C9044939800000018000000180005555 +0089:AAAA000180000001800025DDA4843C85A4842499800000018000000180005555 +008A:AAAA000180000001800045CDC4904489A8841099800000018000000180005555 +008B:AAAA0001800000018000721DCA127213C21243DD800000018000000180005555 +008C:AAAA00018000000180007213CA127213C21243CD800000018000000180005555 +008D:AAAA00018000000180000E2189200E218A200921800000018000000180005555 +008E:AAAA000180000001800039DDC202318D8850739F800000018000000180005555 +008F:AAAA000180000001800039DDC202318D8842739D800000018000000180005555 +0090:AAAA000180000001800071CFCA104A0DCA0271DD800000018000000180005555 +0091:AAAA00018000000180007245CA4C7245C244418F800000018000000180005555 +0092:AAAA0001800000018000725DCA42724DC250419F800000018000000180005555 +0093:AAAA00018000000180003B9DC120311989047139800000018000000180005555 +0094:AAAA000180000001800039D3C212421FC21239D3800000018000000180005555 +0095:AAAA00018000000180002289B6882AA9A2D82289800000018000000180005555 +0096:AAAA00018000000180003B8DC252339F8A127213800000018000000180005555 +0097:AAAA00018000000180007B8DC2527B9FC2127A13800000018000000180005555 +0098:AAAA0001800000018000398FC250324D8A42719D800000018000000180005555 +0099:AAAA0001800000018000339BC42225A394A2639B800000018000000180005555 +009A:AAAA000180000001800039DDC20832098A0871DD800000018000000180005555 +009B:AAAA000180000001800039DDC2084189C0483B9D800000018000000180005555 +009C:AAAA00018000000180000EF990200C2182201C21800000018000000180005555 +009D:AAAA000180000001800031CFCA104991C850338F800000018000000180005555 +009E:AAAA00018000000180001C8992D81CA990881089800000018000000180005555 +009F:AAAA0001800000018000338FCA507B91CA104A0F800000018000000180005555 +00A0:00000000000000000000000000000000 +00A1:00000000080800080808080808080000 +00A2:0000000008083E494848493E08080000 +00A3:000000000E1010107C1010103E610000 +00A4:0000000000423C244242243C42000000 +00A5:00000000412214087F087F0808080000 +00A6:00000000080808080000080808080000 +00A7:000000003C42403C42423C02423C0000 +00A8:24240000000000000000000000000000 +00A9:000000003C4299A5A1A1A599423C0000 +00AA:00001C021E221E003E00000000000000 +00AB:00000000001212242448242412120000 +00AC:000000000000000000007E0202020000 +00AD:AAAA000180003A63C25433C98A48724980000001800003C18000000180005555 +00AE:000000003C42B9A5A5B9A9A5423C0000 +00AF:00007E00000000000000000000000000 +00B0:00000000182424180000000000000000 +00B1:000000000808087F080808007F000000 +00B2:0000003844041820407C000000000000 +00B3:00000038440438044438000000000000 +00B4:00040810000000000000000000000000 +00B5:00000000000042424242424266594080 +00B6:000000003F7A7A7A3A0A0A0A0A0A0A00 +00B7:00000000000000001818000000000000 +00B8:00000000000000000000000000000830 +00B9:0000001030501010107C000000000000 +00BA:00001C2222221C003E00000000000000 +00BB:00000000004848242412242448480000 +00BC:00000000226224282812162A4E420000 +00BD:000000002262242828141A22444E0000 +00BE:00000000621224186812162A4E420000 +00BF:000000001010001010204042423C0000 +00C0:300C000018242442427E424242420000 +00C1:0C30000018242442427E424242420000 +00C2:1824000018242442427E424242420000 +00C3:324C000018242442427E424242420000 +00C4:2424000018242442427E424242420000 +00C5:1824180018242442427E424242420000 +00C6:000000001F2848487F484848484F0000 +00C7:000000003C42424040404042423C0830 +00C8:300C00007E4040407C404040407E0000 +00C9:0C3000007E4040407C404040407E0000 +00CA:182400007E4040407C404040407E0000 +00CB:242400007E4040407C404040407E0000 +00CC:180600003E08080808080808083E0000 +00CD:0C3000003E08080808080808083E0000 +00CE:182400003E08080808080808083E0000 +00CF:242400003E08080808080808083E0000 +00D0:0000000078444242F242424244780000 +00D1:324C000042626252524A4A4646420000 +00D2:300C00003C42424242424242423C0000 +00D3:0C3000003C42424242424242423C0000 +00D4:182400003C42424242424242423C0000 +00D5:324C00003C42424242424242423C0000 +00D6:242400003C42424242424242423C0000 +00D7:00000000000000422418244200000000 +00D8:000000023A44464A4A525262225C4000 +00D9:300C00004242424242424242423C0000 +00DA:0C3000004242424242424242423C0000 +00DB:182400004242424242424242423C0000 +00DC:242400004242424242424242423C0000 +00DD:0C300000414122221408080808080000 +00DE:00000040407844424244784040400000 +00DF:000000003844444858444242524C0000 +00E0:0000300C00003C42023E4242463A0000 +00E1:00000C3000003C42023E4242463A0000 +00E2:0000182400003C42023E4242463A0000 +00E3:0000324C00003C42023E4242463A0000 +00E4:0000242400003C42023E4242463A0000 +00E5:0018241800003C42023E4242463A0000 +00E6:0000000000003E49093F4848493E0000 +00E7:0000000000003C4240404040423C0830 +00E8:0000300C00003C42427E4040423C0000 +00E9:00000C3000003C42427E4040423C0000 +00EA:0000182400003C42427E4040423C0000 +00EB:0000242400003C42427E4040423C0000 +00EC:0000300C0000180808080808083E0000 +00ED:00000C300000180808080808083E0000 +00EE:000018240000180808080808083E0000 +00EF:000024240000180808080808083E0000 +00F0:0000320C1422023E42424242423C0000 +00F1:0000324C00005C624242424242420000 +00F2:0000300C00003C4242424242423C0000 +00F3:00000C3000003C4242424242423C0000 +00F4:0000182400003C4242424242423C0000 +00F5:0000324C00003C4242424242423C0000 +00F6:0000242400003C4242424242423C0000 +00F7:0000000000001800007E000018000000 +00F8:0000000000023C464A4A5252623C4000 +00F9:0000300C0000424242424242463A0000 +00FA:00000C300000424242424242463A0000 +00FB:000018240000424242424242463A0000 +00FC:000024240000424242424242463A0000 +00FD:00000C3000004242424242261A02023C +00FE:0000004040405C6242424242625C4040 +00FF:0000242400004242424242261A02023C +0100:003C000018242442427E424242420000 +0101:0000003C00003C42023E4242463A0000 +0102:42423C0018242442427E424242420000 +0103:0042423C00003C42023E4242463A0000 +0104:0000000018242442427E424242420403 +0105:0000000000003C42023E4242463A0403 +0106:0C3000003C42424040404042423C0000 +0107:00000C3000003C4240404040423C0000 +0108:182400003C42424040404042423C0000 +0109:0000182400003C4240404040423C0000 +010A:101000003C42424040404042423C0000 +010B:0000101000003C4240404040423C0000 +010C:241800003C42424040404042423C0000 +010D:0000241800003C4240404040423C0000 +010E:48300000784442424242424244780000 +010F:2418000202023A4642424242463A0000 +0110:0000000078444242F242424244780000 +0111:000000020F023A4642424242463A0000 +0112:003C00007E4040407C404040407E0000 +0113:0000003C00003C42427E4040423C0000 +0114:42423C007E4040407C404040407E0000 +0115:000042423C003C42427E4040423C0000 +0116:101000007E4040407C404040407E0000 +0117:0000101000003C42427E4040423C0000 +0118:000000007E4040407C404040407E0806 +0119:0000000000003C42427E4040423C100C +011A:241800007E4040407C404040407E0000 +011B:0000241800003C42427E4040423C0000 +011C:182400003C424240404E4242463A0000 +011D:0000182400023A44444438203C42423C +011E:42423C003C424240404E4242463A0000 +011F:0042423C00023A44444438203C42423C +0120:101000003C424240404E4242463A0000 +0121:0000101000023A44444438203C42423C +0122:000000003C424240404E4242463A0830 +0123:00000C1000023A44444438203C42423C +0124:18240000424242427E42424242420000 +0125:3048004040405C624242424242420000 +0126:000000004242FF42427E424242420000 +0127:00000040F0405C624242424242420000 +0128:324C00003E08080808080808083E0000 +0129:0000324C0000180808080808083E0000 +012A:003C00003E08080808080808083E0000 +012B:0000003C0000180808080808083E0000 +012C:42423C003E08080808080808083E0000 +012D:000042423C00180808080808083E0000 +012E:000000003E08080808080808083E0806 +012F:000000080800180808080808083E0806 +0130:080800003E08080808080808083E0000 +0131:000000000000180808080808083E0000 +0132:000000004242424242420202423C0000 +0133:0000222200002222222222221A02221C +0134:0C1200001F0404040404044444380000 +0135:00000C1200000C040404040404044830 +0136:000000004244485060605048444220C0 +0137:000000404040444850605048444220C0 +0138:00000000000042444870704844420000 +0139:186000004040404040404040407E0000 +013A:0C3000180808080808080808083E0000 +013B:000000004040404040404040407E0830 +013C:000000180808080808080808083E0830 +013D:241800004040404040404040407E0000 +013E:241800180808080808080808083E0000 +013F:000000004040404044444040407E0000 +0140:000000301010101014141010107C0000 +0141:000000004040485060C04040407E0000 +0142:0000001808080A0C18280808083E0000 +0143:0C30000042626252524A4A4646420000 +0144:00000C3000005C624242424242420000 +0145:0000000042626252524A4A46464220C0 +0146:0000000000005C6242424242424220C0 +0147:2418000042626252524A4A4646420000 +0148:0000241800005C624242424242420000 +0149:0060202040005C624242424242420000 +014A:000000005C62424242424242424C0000 +014B:0000000000005C62424242424242020C +014C:003C00003C42424242424242423C0000 +014D:0000003C00003C4242424242423C0000 +014E:42423C003C42424242424242423C0000 +014F:000042423C003C4242424242423C0000 +0150:334400003C42424242424242423C0000 +0151:0000334400003C4242424242423C0000 +0152:00000000374848484E48484848370000 +0153:0000000000003649494F484849360000 +0154:0C3000007C4242427C48444442420000 +0155:00000C3000005C624240404040400000 +0156:000000007C4242427C484444424220C0 +0157:0000000000005C6242404040404020C0 +0158:241800007C4242427C48444442420000 +0159:0000241800005C624240404040400000 +015A:0C3000003C424240300C0242423C0000 +015B:00000C3000003C4240300C42423C0000 +015C:182400003C424240300C0242423C0000 +015D:0000182400003C4240300C02423C0000 +015E:000000003C424240300C0242423C0830 +015F:0000000000003C4240300C02423C0830 +0160:241800003C424240300C0242423C0000 +0161:0000241800003C4240300C02423C0000 +0162:000000007F0808080808080808080830 +0163:000000001010107C10101010100C0830 +0164:241800007F0808080808080808080000 +0165:241800001010107C10101010100C0000 +0166:000000007F0808083E08080808080000 +0167:000000001010107C10107C10100C0000 +0168:324C00004242424242424242423C0000 +0169:0000324C0000424242424242463A0000 +016A:003C00004242424242424242423C0000 +016B:0000003C0000424242424242463A0000 +016C:42423C004242424242424242423C0000 +016D:0042423C0000424242424242463A0000 +016E:182418004242424242424242423C0000 +016F:000018241800424242424242463A0000 +0170:334400004242424242424242423C0000 +0171:000033440000424242424242463A0000 +0172:000000004242424242424242423C100C +0173:000000000000424242424242463A0403 +0174:18240000424242425A5A666642420000 +0175:00001824000041494949494949360000 +0176:18240000414122221408080808080000 +0177:0000182400004242424242261A02023C +0178:24240000414122221408080808080000 +0179:0C3000007E02020408102040407E0000 +017A:00000C3000007E0204081020407E0000 +017B:101000007E02020408102040407E0000 +017C:0000101000007E0204081020407E0000 +017D:241800007E02020408102040407E0000 +017E:0000241800007E0204081020407E0000 +017F:0000000C101010301010101010100000 +0180:00000040F0405C6242424242625C0000 +0181:000000007CA2A2223C222222223C0000 +0182:000000007E4040407C424242427C0000 +0183:0000007C40405C6242424242625C0000 +0184:00000000602020203C222222223C0000 +0185:000000000000602020203C22223C0000 +0186:000000003C42420202020242423C0000 +0187:000003043C4444404040404444380000 +0188:0000000003043C444040404044380000 +0189:0000000078444242F242424244780000 +018A:0000000078A4A2222222222224380000 +018B:000000007E0202023E424242423E0000 +018C:0000003E02023A4642424242463A0000 +018D:0000000000003C424242422418040438 +018E:000000007E0202023E020202027E0000 +018F:0000000018244202027E424224180000 +0190:000000003C42424038404042423C0000 +0191:000000001F1010101E10101010106000 +0192:0000000C1010107C1010101010106000 +0193:000000033C444440405C44444C340000 +0194:00000000424242242418182424180000 +0195:00000040404040724A4A4A4A4A440000 +0196:00000000380808080808080808060000 +0197:000000003E0808083E080808083E0000 +0198:00000000464A50506060504844420000 +0199:00000030484044485060504844420000 +019A:000000180808083E08080808083E0000 +019B:00000000242810304818242442420000 +019C:00000000494949494949494949370000 +019D:00000000222232322A2A26262222C000 +019E:0000000000005C624242424242420202 +019F:000000003C4242427E424242423C0000 +01A0:000000023A4444444444444444380000 +01A1:0000000000023A444444444444380000 +01A2:00000000364A4A4A4A4A4A4A4A320202 +01A3:000000000000364A4A4A4A4A4A320202 +01A4:000000003E5151111E10101010100000 +01A5:0000000000035C644444444464584040 +01A6:0000000070203C22223C282422210000 +01A7:000000003C4242020C304042423C0000 +01A8:0000000000003C42020C3040423C0000 +01A9:000000007E40201008081020407E0000 +01AA:00000020505030101010101010100C00 +01AB:000000001010107C10101010100C0418 +01AC:000000003F4848080808080808080000 +01AD:0000000C1010107C10101010100C0000 +01AE:000000007F0808080808080808080600 +01AF:00000101464444444444444444380000 +01B0:0000000001014644444444444C340000 +01B1:00000000422424424242424224180000 +01B2:000000004C4242424242424448300000 +01B3:00000000464544282810101010100000 +01B4:0000000000034444444444241C040438 +01B5:000000007E0204083C102040407E0000 +01B6:0000000000007E04083C1020407E0000 +01B7:000000007E0408101C020202463C0000 +01B8:000000007E20100838404040623C0000 +01B9:0000000000007C20100838404040423C +01BA:0000000000003E04081C02023C40423C +01BB:000000003C424204087E2040407E0000 +01BC:000000007E2020203C020202423C0000 +01BD:0000000000007E20203C0202423C0000 +01BE:0000000010107C101018040444380000 +01BF:0000000000005C624242444850604040 +01C0:00000010101010101010101010100000 +01C1:00000028282828282828282828280000 +01C2:000000101010107C107C101010100000 +01C3:00000000080808080808080008080000 +01C4:05020000675151515252545454670000 +01C5:00000502605057515152525454670000 +01C6:00000512101037515152525454370000 +01C7:00000000474141414141414949760000 +01C8:0000000141404341414141414179020C +01C9:00000061212023212121212121F9020C +01CA:000000004B4949696959594D4D4A0000 +01CB:0000000149486B69695959594949120C +01CC:0000000101005369494949494949120C +01CD:2418000018242442427E424242420000 +01CE:0000241800003C42023E4242463A0000 +01CF:241800003E08080808080808083E0000 +01D0:000024180000180808080808083E0000 +01D1:241800003C42424242424242423C0000 +01D2:0000241800003C4242424242423C0000 +01D3:241800004242424242424242423C0000 +01D4:000024180000424242424242463A0000 +01D5:3C0024004242424242424242423C0000 +01D6:003C00242400424242424242463A0000 +01D7:0C3000240042424242424242423C0000 +01D8:0C3000242400424242424242463A0000 +01D9:241800240042424242424242423C0000 +01DA:241800242400424242424242463A0000 +01DB:300C00240042424242424242423C0000 +01DC:300C00242400424242424242463A0000 +01DD:0000000000003C4202027E42423C0000 +01DE:3C00240018242442427E424242420000 +01DF:003C002424003C42023E4242463A0000 +01E0:3C00180018242442427E424242420000 +01E1:003C001010003C42023E4242463A0000 +01E2:003C00001F2848487F484848484F0000 +01E3:0000003C00003E49093F4848493E0000 +01E4:000000003C424240404E424F423E0000 +01E5:0000000000023A44444438203C4F423C +01E6:241800003C424240404E4242463A0000 +01E7:0000241800023A44444438203C42423C +01E8:24180000424448506060504844420000 +01E9:24180040404044485060504844420000 +01EA:000000003C42424242424242423C100C +01EB:0000000000003C4242424242423C100C +01EC:003C00003C42424242424242423C100C +01ED:0000003C00003C4242424242423C100C +01EE:241800007E0408101C020202463C0000 +01EF:0000241800003E0408101C020202423C +01F0:0000120C00000C040404040404044830 +01F1:00000000675151515252545454670000 +01F2:00000000605057515152525454670000 +01F3:00000010101037515152525454370000 +01F4:0C3000003C424240404E4242463A0000 +01F5:00000C3000023A44444438203C42423C +01F6:000000004848484A7A4A4A4A4A440000 +01F7:000000005C6242424448506040404000 +01F8:00300C0042626252524A4A4646420000 +01F9:000000300C005C624242424242420000 +01FA:0C30182418182424427E424242420000 +01FB:0C3000182418003C42023E42463A0000 +01FC:061800001F2848487F484848484F0000 +01FD:0000061800003E49093F4848493E0000 +01FE:0C3000023A44464A4A525262225C4000 +01FF:00000C3000023C464A4A5252623C4000 +0200:CC22000018242442427E424242420000 +0201:0000CC2200003C42023E4242463A0000 +0202:3C42420018242442427E424242420000 +0203:00003C4242003C42023E4242463A0000 +0204:CC2200007E4040407C404040407E0000 +0205:0000CC2200003C42427E4040423C0000 +0206:3C4242007E4040407C404040407E0000 +0207:00003C4242003C42427E4040423C0000 +0208:CC2200003E08080808080808083E0000 +0209:0000CC220000180808080808083E0000 +020A:3C4242003E08080808080808083E0000 +020B:00003C424200180808080808083E0000 +020C:CC2200003C42424242424242423C0000 +020D:0000CC2200003C4242424242423C0000 +020E:3C4242003C42424242424242423C0000 +020F:00003C4242003C4242424242423C0000 +0210:CC2200007C4242427C48444442420000 +0211:0000CC2200005C624240404040400000 +0212:3C4242007C4242427C48444442420000 +0213:00003C4242005C624240404040400000 +0214:CC2200004242424242424242423C0000 +0215:0000CC220000424242424242463A0000 +0216:3C4242004242424242424242423C0000 +0217:00003C424200424242424242463A0000 +0218:000000003C424240300C0242423C0810 +0219:0000000000003C4240300C02423C0810 +021A:000000007F0808080808080808080204 +021B:000000001010107C10101010100C2040 +021C:000000003C4242020C340202020C3000 +021D:0000000000003C4202020C3202020C30 +021E:00241800424242427E42424242420000 +021F:002418004040405C6242424242420000 +0220:000000005C6242424242424242420202 +0221:0000000202023A4642424242473B0204 +0222:0000000008244242243C4242423C0000 +0223:000000000000122224182422221C0000 +0224:000000007E02020408102040407E0204 +0225:0000000000007E0204081020407E0204 +0226:0000080018242442427E424242420000 +0227:0000000008003C42023E4242463A0000 +0228:000000007E4040407C404040407E0830 +0229:0000000000003C42427E4040423C0830 +022A:3C0024003C42424242424242423C0000 +022B:00003C0024003C4242424242423C0000 +022C:3C00324C003C424242424242423C0000 +022D:003C00324C003C4242424242423C0000 +022E:000008003C42424242424242423C0000 +022F:0000000008003C4242424242423C0000 +0230:3C0008003C42424242424242423C0000 +0231:00003C0008003C4242424242423C0000 +0232:00003E00414122221408080808080000 +0233:000000003C004242424242261A02023C +0234:0000001808080808080808080C0C1020 +0235:0000000000005C624242424243430204 +0236:000000001010107C10101010160E0810 +0237:0000000000000C040404040404044830 +0238:00000010101054BA92929292BA540000 +0239:00000000000054BA92929292BA541010 +023A:000000021A242C4A527E624242C20000 +023B:000000023C464A4850506062427C8000 +023C:0000000002043C4A50506060427C8000 +023D:000000002020202078202020203E0000 +023E:000001027F0C0C080818182828480000 +023F:0000000000003C4240300C02423C0906 +0240:0000000000007E02040810204060100E +0241:000000003C4242020408080808080000 +0242:0000000000003C424202040808080000 +0243:000000003C2222223C227A22223C0000 +0244:000000004444444444FE444444380000 +0245:00000000181818242424244242420000 +0246:000004047E4848507C505060607E4040 +0247:0000000000023C464A7E5060427C8000 +0248:000000001F040404041F044444380000 +0249:0000000404000C04041F040404044830 +024A:0000000038444444444444444C340403 +024B:000000000000344C444444444C340403 +024C:000000003C2222227C28242422220000 +024D:0000000000002C322270202020200000 +024E:000000004141227F1408080808080000 +024F:0000000000002222227F22120E02021C +0250:0000000000005C6242427C40423C0000 +0251:0000000000003A46424242464A320000 +0252:0000000000004C5262424242625C0000 +0253:0000003840405C6242424242625C0000 +0254:0000000000003C4202020202423C0000 +0255:0000000000003C424040404C523C4000 +0256:000000040404344C444444444C340300 +0257:000000030404344C444444444C340000 +0258:0000000000003C42427E0202423C0000 +0259:0000000000003C4202027E42423C0000 +025A:000000000000344D1A28484848300000 +025B:0000000000003C42403C4040423C0000 +025C:0000000000003C42023C0202423C0000 +025D:000000000000344D0A30080848300000 +025E:0000000000003C42425C4242423C0000 +025F:0000000000000C0404041F0404044830 +0260:000000000003344C4444444C34044438 +0261:0000000000003A46424242463A02423C +0262:0000000000003C4240404E42423E0000 +0263:00000000000042424224241818242418 +0264:00000000000042422424181824180000 +0265:0000000000424242424242463A020202 +0266:0000003840405C624242424242420000 +0267:0000003840405C62424242424242020C +0268:0000000808001808083E0808083E0000 +0269:000000000000701010101010100C0000 +026A:0000000000003E0808080808083E0000 +026B:000000180808083A4C080808083E0000 +026C:00000018080838483E080808083E0000 +026D:00000018080808080808080808080600 +026E:0000003010101F1112141611117D0906 +026F:00000000000049494949494949370000 +0270:00000000000049494949494949370101 +0271:00000000000076494949494949410600 +0272:00000000000016191111111111116000 +0273:00000000000058644444444444440300 +0274:000000000000424262524A4642420000 +0275:0000000000003C42427E4242423C0000 +0276:0000000000003748484E484848370000 +0277:0000000000003E414149494949360000 +0278:0000000808083E4949494949493E0808 +0279:000000000000020202020242463A0000 +027A:000000000202020202020242463A0000 +027B:0000000000000404040404444C340300 +027C:0000000000005C624240404040404040 +027D:0000000000005C624240404040403000 +027E:0000000000003C424240404040400000 +027F:0000000000003C424202020202020202 +0280:0000000000007C42427C484442420000 +0281:000000000000424244487C42427C0000 +0282:0000000000003C4240300C02427C4030 +0283:0000000C101010101010101010106000 +0284:0000000C1010101010107C1010106000 +0285:00000000000060101010101010100C00 +0286:000000060808080808080808384E3000 +0287:00000000601010101010107C10100000 +0288:000000001010107C1010101010100E00 +0289:0000000000002222227F2222261A0000 +028A:00000000000042244242424224180000 +028B:000000000000CC424242424448300000 +028C:00000000000018182424244242420000 +028D:00000000000036494949494949410000 +028E:000000003C4040586442424242420000 +028F:00000000000041412214080808080000 +0290:0000000000007C0808101020207C0403 +0291:0000000000007E0204081026497E1000 +0292:0000000000003E0408101C020202423C +0293:0000000000003E0408101C0202324A3C +0294:000000003C4242020408080808080000 +0295:000000003C4242402010101010100000 +0296:000000000808080808040242423C0000 +0297:0000000000003C42404040404040423C +0298:000000003C4242425A5A4242423C0000 +0299:0000000000007C42427C4242427C0000 +029A:0000000000003C42423A4242423C0000 +029B:0000000000003B4440404C44443C0000 +029C:0000000000002222223E222222220000 +029D:0000000404000C0404040404043E4830 +029E:00000000004222120A060A1222020202 +029F:000000000000404040404040407E0000 +02A0:000000000003344C444444444C340404 +02A1:000000003C4242020408083E08080000 +02A2:000000003C4242402010107C10100000 +02A3:0000001010103F5152525454583F0000 +02A4:0000001010103F515254565151310906 +02A5:0000001010103F5152545852553E0400 +02A6:00000000404046F948444241413E0000 +02A7:000000032424247C24242424241C0418 +02A8:00000000404046F94848484A4D3E0400 +02A9:000000003048406E515151515151020C +02AA:000000602020262928242221217E0000 +02AB:0000006020203E2224242828307E0000 +02AC:00000049495536220049495536220000 +02AD:000000007E42424200007E4242420000 +02AE:0000000000006424242424242C140404 +02AF:0000000000006424242424242C140403 +02B0:00000040405864444444000000000000 +02B1:00000038444058644444000000000000 +02B2:00000004000404040424180000000000 +02B3:00000000005864444040000000000000 +02B4:00000000000404444C34000000000000 +02B5:00000000000404444C34030000000000 +02B6:00000044444878444478000000000000 +02B7:00000000004949553622000000000000 +02B8:000000000044444C3404380000000000 +02B9:00000000081020000000000000000000 +02BA:00000000122448000000000000000000 +02BB:00000000081010180000000000000000 +02BC:00000000180808100000000000000000 +02BD:00000000181010080000000000000000 +02BE:00000030080404083000000000000000 +02BF:0000000C102020100C00000000000000 +02C0:0000003C4202021C1010000000000000 +02C1:0000003C424040380808000000000000 +02C2:00000004081020100804000000000000 +02C3:00000020100804081020000000000000 +02C4:00000000081422410000000000000000 +02C5:00000000412214080000000000000000 +02C6:00000000182400000000000000000000 +02C7:00000000241800000000000000000000 +02C8:00000000080808000000000000000000 +02C9:000000003C0000000000000000000000 +02CA:000000000C3000000000000000000000 +02CB:00000000300C00000000000000000000 +02CC:00000000000000000000080808080000 +02CD:000000000000000000000000003C0000 +02CE:00000000000000000000000000300C00 +02CF:000000000000000000000000000C3000 +02D0:00000000000000381000001038000000 +02D1:00000000000000381000000000000000 +02D2:00000000000030080404083000000000 +02D3:0000000000000C102020100C00000000 +02D4:00000000000000101010107C00000000 +02D5:000000000000007C1010101000000000 +02D6:0000000000000010107C101000000000 +02D7:0000000000000000007C000000000000 +02D8:000042423C0000000000000000000000 +02D9:00001818000000000000000000000000 +02DA:00001824180000000000000000000000 +02DB:00000000000000000000000000000806 +02DC:0000324C000000000000000000000000 +02DD:00003344000000000000000000000000 +02DE:000000000000002060A21C0000000000 +02DF:00000000422418244200000000000000 +02E0:00000000004242241824241800000000 +02E1:00000030101010101038000000000000 +02E2:00000000003E403C027C000000000000 +02E3:00000000004224182442000000000000 +02E4:00003C40403808000000000000000000 +02E5:0000007C040404040404040404040000 +02E6:00000004047C04040404040404040000 +02E7:00000004040404047C04040404040000 +02E8:00000004040404040404047C04040000 +02E9:000000040404040404040404047C0000 +02EA:000000000000404040404C7000000000 +02EB:000000000040404C7040404000000000 +02EC:00000000000000000000004428100000 +02ED:00007E007E0000000000000000000000 +02EE:00000000662222440000000000000000 +02EF:00000000000000000000000044281000 +02F0:00000000000000000000000010284400 +02F1:00000000000000000000040810080400 +02F2:00000000000000000000100804081000 +02F3:00000000000000000000000018241800 +02F4:00000000000000300C00000000000000 +02F5:00000000000000CC2200000000000000 +02F6:00000000000000334400000000000000 +02F7:0000000000000000000000000000324C +02F8:00000018180000001818000000000000 +02F9:00000038202020000000000000000000 +02FA:00000038080808000000000000000000 +02FB:00000000000000000000202020380000 +02FC:00000000000000000000080808380000 +02FD:0000000000000000000000000042427E +02FE:0000000000000000000000000040407E +02FF:000000000000000000000010207E2010 +0300:300C0000000000000000000000000000 +0301:0C300000000000000000000000000000 +0302:18240000000000000000000000000000 +0303:00324C00000000000000000000000000 +0304:00007E00000000000000000000000000 +0305:0000FF00000000000000000000000000 +0306:0042423C000000000000000000000000 +0307:00181800000000000000000000000000 +0308:00666600000000000000000000000000 +0309:18240408080000000000000000000000 +030A:18242418000000000000000000000000 +030B:33440000000000000000000000000000 +030C:00422418000000000000000000000000 +030D:00080808000000000000000000000000 +030E:00242424000000000000000000000000 +030F:CC220000000000000000000000000000 +0310:185A423C000000000000000000000000 +0311:003C4242000000000000000000000000 +0312:00081018000000000000000000000000 +0313:00180810000000000000000000000000 +0314:00181008000000000000000000000000 +0315:00030102000000000000000000000000 +0316:00000000000000000000000000100804 +0317:00000000000000000000000000081020 +0318:00000000000000000000000000083808 +0319:00000000000000000000000000101C10 +031A:001E0202000000000000000000000000 +031B:0000040A020408000000000000000000 +031C:00000000000000000000000000182018 +031D:00000000000000000000000000101038 +031E:00000000000000000000000000381010 +031F:00000000000000000000000000107C10 +0320:0000000000000000000000000000003C +0321:0000000000000000000000000202120C +0322:00000000000000000000000008080906 +0323:00000000000000000000000000001818 +0324:00000000000000000000000000006666 +0325:00000000000000000000000000182418 +0326:00000000000000000000000000180810 +0327:00000000000000000000000010180438 +0328:00000000000000000000000000080806 +0329:00000000000000000000000000101010 +032A:00000000000000000000000000007E42 +032B:00000000000000000000000000494936 +032C:00000000000000000000000000422418 +032D:00000000000000000000000000182442 +032E:0000000000000000000000000042423C +032F:000000000000000000000000003C4242 +0330:0000000000000000000000000000324C +0331:0000000000000000000000000000007E +0332:000000000000000000000000000000FF +0333:00000000000000000000000000FF00FF +0334:0000000000000000324C000000000000 +0335:00000000000000003C00000000000000 +0336:0000000000000000FF00000000000000 +0337:00000000000004081020400000000000 +0338:00000202040408081010202040400000 +0339:00000000000000000000000018040418 +033A:0000000000000000000000000000427E +033B:000000000000000000000000003C243C +033C:000000000000000000000000006C9210 +033D:66186600000000000000000000000000 +033E:08101008100000000000000000000000 +033F:FF00FF00000000000000000000000000 +0340:00402010000000000000000000000000 +0341:00020408000000000000000000000000 +0342:00344800000000000000000000000000 +0343:00180810000000000000000000000000 +0344:10105444000000000000000000000000 +0345:0000000000000000000000001010100C +0346:007E4200000000000000000000000000 +0347:000000000000000000000000007E007E +0348:00000000000000000000000000002424 +0349:00000000000000000000000000001808 +034A:083A5C10000000000000000000000000 +034B:04718E20000000000000000000000000 +034C:324C324C000000000000000000000000 +034D:00000000000000000000000000227F22 +034E:00000000000000000000000000081C08 +034F:AAAA000180000001B9C24203C2E2422BB9C40001824000018420000182405555 +0350:08040204080000000000000000000000 +0351:18202018000000000000000000000000 +0352:3C425A18000000000000000000000000 +0353:00000000000000000000000000241824 +0354:00000000000000000000000810201008 +0355:00000000000000000000001008040810 +0356:00000000000000000000008040244A91 +0357:18040418000000000000000000000000 +0358:00030300000000000000000000000000 +0359:00000000000000000000000054387C38 +035A:000000000000000000000000006C926C +035B:08103E04080000000000000000000000 +035C:00000000000000000000000000000000000000000000000000004002300C0FF0 +035D:00004002300C0FF0000000000000000000000000000000000000000000000000 +035E:000000001FF80000000000000000000000000000000000000000000000000000 +035F:0000000000000000000000000000000000000000000000000000000000001FF8 +0360:00001E0221844078000000000000000000000000000000000000000000000000 +0361:00000FF0300C4002000000000000000000000000000000000000000000000000 +0362:000000000000000000000000000000000000000000000008000C7FFE000C0008 +0363:3C44444C340000000000000000000000 +0364:384478403C0000000000000000000000 +0365:10003010380000000000000000000000 +0366:38444444380000000000000000000000 +0367:444444443C0000000000000000000000 +0368:1C2020201C0000000000000000000000 +0369:04043C243C0000000000000000000000 +036A:20203824240000000000000000000000 +036B:0000EC92920000000000000000000000 +036C:00382420200000000000000000000000 +036D:20782020180000000000000000000000 +036E:00444428100000000000000000000000 +036F:44281028440000000000000000000000 +0370:00000000404040407C40404040400000 +0371:0000000000002050501E101010100000 +0372:00000000FE9292921010101010100000 +0373:000000007C5454541010101010100000 +0374:000000000C1810200000000000000000 +0375:00000000000000000000000004081830 +0376:000000004246464A4A52526262420000 +0377:000000000000889898A8A8CACA840000 +0378:00007FFE738E6DF66DC66DF6738E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000 +0379:00007FFE738E6DF66DC66DF6738E7FFE7FFE61CE7DB67BC677F677CE7FFE0000 +037A:00000000000000000000000020202018 +037B:0000000000003C4202020202423C0000 +037C:0000000000003C4240585840423C0000 +037D:0000000000003C42021A1A02423C0000 +037E:00000000000018180000001808081000 +037F:000000001F0404040404044444380000 +0380:00007FFE738E6DF66DC66DF6738E7FFE7FFE73CE6DB673B66DB673CE7FFE0000 +0381:00007FFE738E6DF66DC66DF6738E7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000 +0382:00007FFE738E6DF66DC66DF6738E7FFE7FFE73866DF673866DBE73867FFE0000 +0383:00007FFE738E6DF66DC66DF6738E7FFE7FFE738E6DF673C66DF6738E7FFE0000 +0384:00040810000000000000000000000000 +0385:04085444000000000000000000000000 +0386:1020400018242442427E424242420000 +0387:00000000000000001818000000000000 +0388:102040007E4040407C404040407E0000 +0389:10204000424242427E42424242420000 +038A:102040003E08080808080808083E0000 +038B:00007FFE738E6DF66DC66DF6738E7FFE7FFE738E6DB6738E6DB6738E7FFE0000 +038C:102040003C42424242424242423C0000 +038D:00007FFE738E6DF66DC66DF6738E7FFE7FFE738E6DB673B66DB6738E7FFE0000 +038E:10204000414122221408080808080000 +038F:102040003E4141414141412214147700 +0390:040810444400301010101010100C0000 +0391:0000000018242442427E424242420000 +0392:000000007C4242427C424242427C0000 +0393:000000007E4240404040404040400000 +0394:000000000808141422222241417F0000 +0395:000000007E4040407C404040407E0000 +0396:000000007E02020408102040407E0000 +0397:00000000424242427E42424242420000 +0398:000000003C4242425A5A4242423C0000 +0399:000000003E08080808080808083E0000 +039A:00000000424448506060504844420000 +039B:00000000080814142222224141410000 +039C:00000000424266665A5A424242420000 +039D:0000000042626252524A4A4646420000 +039E:000000007E0000003C000000007E0000 +039F:000000003C42424242424242423C0000 +03A0:000000007F2222222222222222220000 +03A1:000000007C4242427C40404040400000 +03A2:00007FFE738E6DF66DC66DF6738E7FFE7FFE61866DF661866DBE6D867FFE0000 +03A3:000000007E40201008081020407E0000 +03A4:000000007F0808080808080808080000 +03A5:00000000414122221408080808080000 +03A6:000000007F083E494949493E087F0000 +03A7:00000000424224241818242442420000 +03A8:0000000049494949493E080808080000 +03A9:000000003E4141414141221414770000 +03AA:242400003E08080808080808083E0000 +03AB:24240000414122221408080808080000 +03AC:000408100000324A444444444A320000 +03AD:0004081000003E40403C4040403E0000 +03AE:0004081000005C624242424242420202 +03AF:000408100000301010101010100C0000 +03B0:040810444400424242424242423C0000 +03B1:000000000000324A444444444A320000 +03B2:00000000384444447C424242625C4040 +03B3:00000000000031490A04080810100000 +03B4:000000001C20202018244242423C0000 +03B5:0000000000003C42403C4040423C0000 +03B6:0000000020201C0810202020201C021C +03B7:0000000000005C624242424242420202 +03B8:00000000182424427E42422424180000 +03B9:000000000000301010101010100C0000 +03BA:00000000000022242830302824220000 +03BB:00000000202010100818242442420000 +03BC:0000000000004242424266665A424040 +03BD:00000000000042424244444850600000 +03BE:0000000040403C40403C40403C02023C +03BF:0000000000003C4242424242423C0000 +03C0:0000000000007E242424242424240000 +03C1:0000000000003C4242424242625C4040 +03C2:0000000000001E20404040201C02021C +03C3:0000000000003F484444444444380000 +03C4:0000000000007E1010101010100C0000 +03C5:000000000000424242424242423C0000 +03C6:000000000000264949494949493E0808 +03C7:0000000000C121221214182848448483 +03C8:000000000000494949494949493E0808 +03C9:00000000000022414149494949360000 +03CA:000024240000301010101010100C0000 +03CB:000024240000424242424242423C0000 +03CC:0004081000003C4242424242423C0000 +03CD:000408100000424242424242423C0000 +03CE:00040810000022414149494949360000 +03CF:00000000424448506060504844420408 +03D0:000000001C2242447844424244380000 +03D1:000000000C1212120F226222221C0000 +03D2:000000003655141408080808081C0000 +03D3:102040003655141408080808081C0000 +03D4:003636003655141408080808081C0000 +03D5:0000000008083E4949494949493E0808 +03D6:0000000000007F224141494949360000 +03D7:00000000000082442C2C34342241011E +03D8:000000003C42424242424242423C183C +03D9:0000000000003C4242424242423C1818 +03DA:000000003844404040404038081C0000 +03DB:000000000000003E4040201C021C0000 +03DC:000000007E4240407840404040400000 +03DD:000000000000003C2220203820202020 +03DE:0000000060202020203E040408080000 +03DF:000000000000201010223C4408080400 +03E0:000000001C22060A12060A12020C0000 +03E1:00000000000000601018284C14240408 +03E2:0000000044929292929292926E027C80 +03E3:0000000000004492929292926E027C80 +03E4:0000000032424242463A020202020000 +03E5:000000000000122222221E0202020000 +03E6:000000004040405C624141410101621C +03E7:0000000000083C5252220202324C0000 +03E8:000000003C42420204081020423C0000 +03E9:0000000000003C4242040830423C0000 +03EA:00000000C3A5241818242442427E8100 +03EB:000000000000245A18181824427E0000 +03EC:000000023C40405C62424242423C0000 +03ED:0000000000023C405C624242423C0000 +03EE:000000001010FE921010101010101000 +03EF:0000000000001010FE92101010101000 +03F0:00000000000082442C2C343422410000 +03F1:0000000000003C4242427C40403C0200 +03F2:0000000000003C4240404040423C0000 +03F3:0000000404000C040404040404044830 +03F4:000000003C4242427E424242423C0000 +03F5:0000000000001C2040784040201C0000 +03F6:0000000000007008043C040408700000 +03F7:00000000E040784442424242447840E0 +03F8:0000000040405C6242424242625C4040 +03F9:000000003C42424040404042423C0000 +03FA:00000000424266665A5A424242420000 +03FB:0000000000446C6C5454444445424040 +03FC:0000000000003C42424242625C40F840 +03FD:000000003C42420202020242423C0000 +03FE:000000003C42424058584042423C0000 +03FF:000000003C4242021A1A0242423C0000 +0400:00300C007E4040407C404040407E0000 +0401:242400007E4040407C404040407E0000 +0402:000000007E1010101E11111111160000 +0403:0C3000007E4040404040404040400000 +0404:000000001C2240407C404040221C0000 +0405:000000003C424240300C0242423C0000 +0406:000000003E08080808080808083E0000 +0407:242400003E08080808080808083E0000 +0408:000000000E0404040404044444380000 +0409:00000000784848484E494949498E0000 +040A:00000000484848487E494949494E0000 +040B:000000007E1010101E11111111110000 +040C:0C300000464848505060504844420000 +040D:00300C004246464A4A52526262420000 +040E:42423C00414122221414080810300000 +040F:000000004141414141414141417F0808 +0410:0000000018242442427E424242420000 +0411:000000007C4040407C424242427C0000 +0412:000000007C4242427C424242427C0000 +0413:000000007E4040404040404040400000 +0414:000000000E1212122222224242FF8181 +0415:000000007E4040407C404040407E0000 +0416:0000000049492A2A1C1C2A2A49490000 +0417:000000003C4202023C040202423C0000 +0418:000000004246464A4A52526262420000 +0419:002418004246464A4A52526262420000 +041A:00000000464848505060504844420000 +041B:000000001E1212121212122222420000 +041C:00000000424266665A5A424242420000 +041D:00000000424242427E42424242420000 +041E:000000003C42424242424242423C0000 +041F:000000007E4242424242424242420000 +0420:000000007C4242427C40404040400000 +0421:000000003C42424040404042423C0000 +0422:000000007F0808080808080808080000 +0423:00000000414122221414080810300000 +0424:000000083E49494949493E0808080000 +0425:00000000424224241818242442420000 +0426:000000004242424242424242427F0101 +0427:000000004242424242463A0202020000 +0428:000000004949494949494949497F0000 +0429:00000000929292929292929292FF0101 +042A:00000000701010101E111111111E0000 +042B:0000000042424242724A4A4A4A720000 +042C:00000000404040407C424242427C0000 +042D:00000000384402023E02020244380000 +042E:000000004C52525272525252524C0000 +042F:000000003E4242423E12222242420000 +0430:0000000000003C42023E4242463A0000 +0431:0000021C20407C4242424242423C0000 +0432:0000000000007C42427C4242427C0000 +0433:0000000000007E404040404040400000 +0434:0000000000001E1222224242427F4100 +0435:0000000000003C42427E4040423C0000 +0436:00000000000049492A1C1C2A49490000 +0437:0000000000003C42023C0402423C0000 +0438:00000000000046464A4A525262620000 +0439:00002418000046464A4A525262620000 +043A:00000000000046485060504844420000 +043B:0000000000001E121212122222420000 +043C:0000000000004266665A5A4242420000 +043D:0000000000004242427E424242420000 +043E:0000000000003C4242424242423C0000 +043F:0000000000007E424242424242420000 +0440:0000000000005C6242424242625C4040 +0441:0000000000003C4240404040423C0000 +0442:0000000000007F080808080808080000 +0443:00000000000042422424181810102060 +0444:0000000808083E4949494949493E0808 +0445:00000000000042422418182442420000 +0446:000000000000424242424242427F0101 +0447:00000000000042424242463A02020000 +0448:000000000000494949494949497F0000 +0449:00000000000092929292929292FF0101 +044A:0000000000007010101E1111111E0000 +044B:000000000000424242724A4A4A720000 +044C:0000000000004040407C4242427C0000 +044D:0000000000003844023E020244380000 +044E:0000000000004C5252725252524C0000 +044F:0000000000003E4242423E1222420000 +0450:0000300C00003C42427E4040423C0000 +0451:0000242400003C42427E4040423C0000 +0452:00000040F0405C62424242424242020C +0453:00000C3000007E404040404040400000 +0454:0000000000001C22407C4040221C0000 +0455:0000000000003C4240300C02423C0000 +0456:000000080800180808080808083E0000 +0457:000000242400180808080808083E0000 +0458:0000000404000C040404040404044830 +0459:0000000000007848484E4949498E0000 +045A:0000000000004848487E4949494E0000 +045B:00000040F0405C624242424242420000 +045C:00000C30000046485060504844420000 +045D:0000300C000046464A4A525262620000 +045E:0042423C000042422424181810102060 +045F:000000000000222222222222223E0808 +0460:0000000049494949494949495A240000 +0461:0000000000000049494949495A240000 +0462:00000000107C10101E111111111E0000 +0463:0000000020207820203C2222223C0000 +0464:00000000464950507E50505049460000 +0465:0000000000004649507E505049460000 +0466:000000000808141422362A4949490000 +0467:00000000000008141422364949490000 +0468:000000004848545452766A4949490000 +0469:00000000000048545452764949490000 +046A:000000003E222214081C2A4949490000 +046B:0000000000003E2214083E4949490000 +046C:000000005F51514A744E555555550000 +046D:0000000000005F514A744E5555550000 +046E:000024183C4202023C040202023C4040 +046F:0000002418003C42023C0402023C4040 +0470:0000000049494949493E080808080000 +0471:000000000000000049494949493E0808 +0472:000000003C4242427E424242423C0000 +0473:0000000000003C42427E4242423C0000 +0474:00000000434444442828281010100000 +0475:00000000000046484828282810100000 +0476:66110000434444442828281010100000 +0477:00006611000046484828282810100000 +0478:00000000205059595955565454240808 +0479:00000000000029595955565454240808 +047A:000000083E49414141414141493E0800 +047B:0000000000083E4941414141493E0800 +047C:3C431804080036414149494949360000 +047D:0000003C431804080036414949360000 +047E:007F080049494949494949495A240000 +047F:000000007F080049494949495A240000 +0480:000000003C424240404040403C040404 +0481:0000000000003C42424040403C040404 +0482:000000000000120C442A111824000000 +0483:00087840000000000000000000000000 +0484:02050910000000000000000000000000 +0485:00384030000000000000000000000000 +0486:00380418000000000000000000000000 +0487:00304C83000000000000000000000000 +0488:000000000100028010102828000000004008A014000000000000101029280280 +0489:000000000080108409880C30000000000008700E1000000000000CD808881084 +048A:002418004246464A4A52526262430204 +048B:00002418000046464A4A525262630204 +048C:0000000020702020203C2222263C0000 +048D:000000000000002070203C22223C0000 +048E:000000007C424A447A40404040400000 +048F:0000000000005C624242424A645A4040 +0490:000002027E4040404040404040400000 +0491:0000000002027E404040404040400000 +0492:000000001F101010107C101010100000 +0493:0000000000001F1010107C1010100000 +0494:000000007E404040407C424242420C00 +0495:0000000000007E4040407C4242420C00 +0496:0000000049492A2A1C1C2A2A49490101 +0497:00000000000049492A1C1C2A49490101 +0498:000000003C4202023C040202423C0830 +0499:0000000000003C42023C0402423C0830 +049A:00000000464848505060504844420202 +049B:00000000000046485060504844420202 +049C:00000000434454547854545442410000 +049D:00000000000043545478545442410000 +049E:00000000237424282830282422210000 +049F:00000000000023742830282422210000 +04A0:00000000E32424282830282422210000 +04A1:000000000000E3242830282422210000 +04A2:00000000424242427E42424242430101 +04A3:0000000000004242427E424242430101 +04A4:00000000474444447C44444444440000 +04A5:0000000000004744447C444444440000 +04A6:0000000078484848484E494949490106 +04A7:000000000000784848484E4949490106 +04A8:000000204C525252525252522C180600 +04A9:000000000000204C525252522C180600 +04AA:000000003C42424040404042423C0830 +04AB:0000000000003C4242404042423C0830 +04AC:000000007F08080808080808080C0404 +04AD:0000000000007F0808080808080C0404 +04AE:00000000414122221408080808080000 +04AF:00000000000022222214140808080808 +04B0:00000000414122221408083E08080000 +04B1:0000000000002222221414083E080808 +04B2:00000000424224241818242442430101 +04B3:00000000000042422418182442430101 +04B4:00000000FA22222222222222223F0101 +04B5:000000000000FA2222222222223F0101 +04B6:000000004242424242463A0202030101 +04B7:00000000000042424242463A02030101 +04B8:000000004242424252563A1212020000 +04B9:00000000000042424252563A12020000 +04BA:000000004040405C6242424242420000 +04BB:00000000000040405C62424242420000 +04BC:000000004C5252523E101012120C0000 +04BD:0000000000004C52523E1010120C0000 +04BE:000000004C5252523E101012120C0808 +04BF:0000000000004C52523E1010120C0808 +04C0:000000003E08080808080808083E0000 +04C1:41413E0049492A2A1C1C2A2A49490000 +04C2:0022221C000049492A1C1C2A49490000 +04C3:0000000046484850607C42424242020C +04C4:000000000000464850607C424242020C +04C5:000000001E1212121212122222430204 +04C6:0000000000001E121212122222430204 +04C7:00000000424242427E4242424242020C +04C8:0000000000004242427E42424242020C +04C9:00000000424242427E42424242430204 +04CA:0000000000004242427E424242430204 +04CB:000000004242424242463A0202060404 +04CC:00000000000042424242463A02060404 +04CD:00000000424266665A5A424242430204 +04CE:0000000000004266665A5A4242430204 +04CF:000000001C08080808080808081C0000 +04D0:42423C0018242442427E424242420000 +04D1:0042423C00003C42023E4242463A0000 +04D2:2424000018242442427E424242420000 +04D3:0000242400003C42023E4242463A0000 +04D4:000000001F2848487F484848484F0000 +04D5:0000000000003E49093F4848493E0000 +04D6:42423C007E4040407C404040407E0000 +04D7:000042423C003C42427E4040423C0000 +04D8:0000000018244202027E424224180000 +04D9:0000000000003C4202027E42423C0000 +04DA:2424000018244202027E424224180000 +04DB:0000242400003C4202027E42423C0000 +04DC:2424000049492A2A1C1C2A2A49490000 +04DD:00002424000049492A1C1C2A49490000 +04DE:242400003C4202023C040202423C0000 +04DF:0000242400003C42023C0402423C0000 +04E0:000000007E0408101C020202463C0000 +04E1:0000000000003E0408101C020202423C +04E2:003C00004246464A4A52526262420000 +04E3:0000003C000046464A4A525262620000 +04E4:242400004246464A4A52526262420000 +04E5:00002424000046464A4A525262620000 +04E6:242400003C42424242424242423C0000 +04E7:0000242400003C4242424242423C0000 +04E8:000000003C4242427E424242423C0000 +04E9:0000000000003C42427E4242423C0000 +04EA:242400003C4242427E424242423C0000 +04EB:0000242400003C42427E4242423C0000 +04EC:000024003C4202023E020202423C0000 +04ED:0000000024003C42021E0202423C0000 +04EE:003E0000414122221414080810300000 +04EF:0000003C000042422424181810102060 +04F0:24240000414122221414080810300000 +04F1:00002424000042422424181810102060 +04F2:33440000414122221414080810300000 +04F3:00003344000042422424181810102060 +04F4:242400004242424242463A0202020000 +04F5:00002424000042424242463A02020000 +04F6:000000007E4040404040404040602020 +04F7:0000000000007E404040404040602020 +04F8:2424000042424242724A4A4A4A720000 +04F9:000024240000424242724A4A4A720000 +04FA:000000001F101010107C101010180818 +04FB:0000000000001F10107C101010180818 +04FC:00000000424224241818242442420204 +04FD:00000000000042422418182442420204 +04FE:0000000042422424187E242442420000 +04FF:000000000000424224187E2442420000 +0500:0000000202023E4242424242463A0000 +0501:000000020202023A46424242463A0000 +0502:0000000404043C44444545454D360000 +0503:00000004040404344C4444454D360000 +0504:00000000384444041805050505020000 +0505:00000000000038444404180505020000 +0506:00000000384444041804040404030101 +0507:00000000000038444404180404030101 +0508:000000003C2424242425254545820000 +0509:0000000000003C242424244545820000 +050A:00000000444444447C45454545460000 +050B:0000000000004444447C444545460000 +050C:000000003C424240404E424244380000 +050D:0000000000003C4240404E42423C0000 +050E:000000007F08080808090909090E0000 +050F:0000000000007F0808080909090E0000 +0510:000000003C4240403C204040423C0000 +0511:0000000000003C42403C2040423C0000 +0512:000000001E1212121212122222420A0C +0513:0000000000001E121212122222420A0C +0514:0000000071514A4A44444A4A51910000 +0515:00000000000071514A44444A51910000 +0516:00000000E192949890F0888482810000 +0517:00000000000001E294989894E2818080 +0518:000000007F8888887F284848888F0000 +0519:0000000000007E89897F282849460000 +051A:000000003C4242424242425A663C0300 +051B:0000000000003A4642424242463A0202 +051C:00000000424242425A5A666642420000 +051D:00000000000041494949494949360000 +051E:000000004A444A506060504844420000 +051F:00000000000054485460504844420000 +0520:00000000705050505E51519191910502 +0521:0000000000007050505E515191910502 +0522:0000000090909090FE91919191910502 +0523:000000000000909090FE919191910502 +0524:000000007C4444444444444444460202 +0525:0000000000007C444444444444460202 +0526:000000004040405C6242424242430101 +0527:00000000000040405C62424242430101 +0528:00000000111111111F11111111115020 +0529:0000000000001111111F111111115020 +052A:00000000000000000C4614481448145027E02460245044484444FE4282008200 +052B:0000000000000000000000001C461448245027E04450444844447E4242000000 +052C:000000004C4C5454547C2424447E4242 +052D:0000000000004C5454547C2424247E42 +052E:000000001E1212121212122222430101 +052F:0000000000001E121212122222430101 +0530:00007FFE73866DBE6D866DF673867FFE7FFE63CE7DB671B67DB663CE7FFE0000 +0531:00000000444444444444444745380000 +0532:000000003C4242407C42404040400000 +0533:0000000038444444443E050404040000 +0534:00000000384444040406050404040000 +0535:0000000040407C4240404042423C0000 +0536:000000001C222222221C0408107E0200 +0537:000000004040407C42404040407C0200 +0538:000000003C42424040404040407C0200 +0539:000000003844444F5454484040400000 +053A:00000000040404043F44444444380000 +053B:0000000040405C624240404040400000 +053C:000000004040404040404040407E0200 +053D:00000000404040794949494949460000 +053E:000000007E1824424242424224180000 +053F:00000000404042424242423E02020000 +0540:00000000081010081020406018060000 +0541:000000001C222222221C245848360000 +0542:00000000384444040404040404070100 +0543:000000000464182424424242427E0000 +0544:00000000474544444444444444380000 +0545:000000001C2202427C420202221C0000 +0546:00000000403010101010101011110E00 +0547:000000403C20404042424242423C0000 +0548:000000003C4242424242424242420000 +0549:000000001C222222221C040870180600 +054A:000000003E4949494909090101010000 +054B:000000001C2222120A0C0C08107E0200 +054C:00000000384444474544444444440000 +054D:000000004242424242424242423C0000 +054E:00000000040444444444443C04070100 +054F:000000003C424240300C0242423C0000 +0550:000000003C4242404040404040400000 +0551:000000003C4242423C420202423C0000 +0552:00000000404058644444434040400000 +0553:00000000103854545454545438100000 +0554:000000000C1212121C507C1410100000 +0555:000000003C42424242424242423C0000 +0556:00000000384848380E090909493E0000 +0557:00007FFE73866DBE6D866DF673867FFE7FFE61866FF661EE7DDE61DE7FFE0000 +0558:00007FFE73866DBE6D866DF673867FFE7FFE61CE6FB661CE7DB661CE7FFE0000 +0559:10202010000000000000000000000000 +055A:20101020000000000000000000000000 +055B:08183000000000000000000000000000 +055C:0C300000000000000000000000000000 +055D:20100800000000000000000000000000 +055E:38445418000000000000000000000000 +055F:3050403C000000000000000000000000 +0560:00000000000076494949494949490000 +0561:00000000000049494949494949370000 +0562:000000000000001C224242407E404040 +0563:0000000000003844444444443F040404 +0564:00000000000058644444444444470404 +0565:00000000004040407E404242221C0000 +0566:000000000000344C444444443C040407 +0567:0000000040407C404040404040380400 +0568:0000000000005C62424242424242407E +0569:0000000000005864444F545448404040 +056A:000000000404043F4444444444380000 +056B:0000000040405C624242424242424040 +056C:0000000000004040404040404040407C +056D:00000000404040794949494946404040 +056E:000000007008043F4444444444380000 +056F:000000002020222222222222221E0202 +0570:000000004040405C6242424242420000 +0571:000000000810083E42424242423E0000 +0572:00000000000058644444444444440407 +0573:000000000E11107F11111111130D0000 +0574:0000000002050444444444444C340000 +0575:0000000000000C040404040404044830 +0576:000000003C42404242424242463A0000 +0577:000000003844040808101020203F0000 +0578:0000000000005C624242424242420000 +0579:000000001020100808101020203F0000 +057A:00000000000049494949494949370101 +057B:000000003844442414181820203F0000 +057C:00000000000058644444444444470000 +057D:000000000000424242424242463A0000 +057E:0000000004040444444444444C340407 +057F:0000000000004A4D4949494959290000 +0580:0000000000005C624242424242424040 +0581:0000000000003A46424242463A02423C +0582:000000000000180808080808080E0000 +0583:0000000008084A4D4949494959290808 +0584:0000000000000C1212121C103C101018 +0585:0000000000003C4242424242423C0000 +0586:00000000384848380E090909493E0808 +0587:000000004040404444444444443B0000 +0588:0000000000000C040404041E04044830 +0589:00000000000018180000001818000000 +058A:0000000000000000000000623C000000 +058B:00007FFE73866DBE6D866DF673867FFE7FFE738E6DB6738E6DB6738E7FFE0000 +058C:00007FFE73866DBE6D866DF673867FFE7FFE73C66DBE73BE6DBE73C67FFE0000 +058D:0000000000000DC012301248298827B027C81BC8232824901890076000000000 +058E:00000000000007601890249023281BC827C827B02988124812300DC000000000 +058F:00000000384444041F041F0404040000 +0590:00007FFE73866DBE6D866DF673867FFE7FFE73CE6DB671B67DB673CE7FFE0000 +0591:00000000000000000000000000207088 +0592:00180066000000000000000000000000 +0593:0C300C300C3000000000000000000000 +0594:00180018000000000000000000000000 +0595:002C202C000000000000000000000000 +0596:00000000000000000000000000808060 +0597:081C3E1C080000000000000000000000 +0598:0024524A240000000000000000000000 +0599:00C02020000000000000000000000000 +059A:00000000000000000000000000010201 +059B:000000000000000000000000D0D010E0 +059C:000C1010000000000000000000000000 +059D:00030404000000000000000000000000 +059E:00364848000000000000000000000000 +059F:0042A542240000000000000000000000 +05A0:00020502040000000000000000000000 +05A1:00506080000000000000000000000000 +05A2:00000000000000000000000000887020 +05A3:000000000000000000000000002020E0 +05A4:00000000000000000000000000408040 +05A5:000000000000000000000000002020C0 +05A6:000000000000000000000000002424D8 +05A7:00000000000000000000006080601060 +05A8:00C02020000000000000000000000000 +05A9:0040A040200000000000000000000000 +05AA:00000000000000000000000000009060 +05AB:00102010000000000000000000000000 +05AC:0004041C000000000000000000000000 +05AD:00000000000000000000000000040403 +05AE:0048A8A8900000000000000000000000 +05AF:00182424180000000000000000000000 +05B0:00000000000000000000000000180018 +05B1:000000000000000000000000002A0012 +05B2:000000000000000000000000003A0002 +05B3:000000000000000000000000003A1012 +05B4:00000000000000000000000000001818 +05B5:00000000000000000000000000006666 +05B6:00000000000000000000000000660018 +05B7:00000000000000000000000000003C00 +05B8:000000000000000000000000003E0808 +05B9:00003030000000000000000000000000 +05BA:00006060000000000000000000000000 +05BB:00000000000000000000000000200802 +05BC:00000000000000001800000000000000 +05BD:00000000000000000000000000080808 +05BE:0000007E000000000000000000000000 +05BF:0000003C000000000000000000000000 +05C0:00000000000808080808080808080000 +05C1:00000606000000000000000000000000 +05C2:00006060000000000000000000000000 +05C3:000000000000081C080000081C080000 +05C4:18180000000000000000000000000000 +05C5:00000000000000000000000000001818 +05C6:000000000038202020202020203C0000 +05C7:000000000000000000000000003E0808 +05C8:00007FFE73866DBE6D866DF673867FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +05C9:00007FFE73866DBE6D866DF673867FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +05CA:00007FFE73866DBE6D866DF673867FFE7FFE71866FB66F866FB671B67FFE0000 +05CB:00007FFE73866DBE6D866DF673867FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +05CC:00007FFE73866DBE6D866DF673867FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +05CD:00007FFE73866DBE6D866DF673867FFE7FFE718E6FB66FB66FB6718E7FFE0000 +05CE:00007FFE73866DBE6D866DF673867FFE7FFE71866FBE6F8E6FBE71867FFE0000 +05CF:00007FFE73866DBE6D866DF673867FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +05D0:0000000000424222122C484442420000 +05D1:00000000007C040404040404047F0000 +05D2:000000000030080808040C1422420000 +05D3:00000000007E04040404040404040000 +05D4:00000000007E02022222222222220000 +05D5:00000000003808080808080808080000 +05D6:0000000000300C0A0808080808080000 +05D7:00000000007E22222222222222220000 +05D8:0000000000464A4242424242427E0000 +05D9:00000000003808080800000000000000 +05DA:00000000007E02020202020202020202 +05DB:00000000007E020202020202027C0000 +05DC:00000020203E02020202040408300000 +05DD:0000000000FE222222222222223E0000 +05DE:00000000004E31214141414141470000 +05DF:00000000003808080808080808080808 +05E0:00000000001C040404040404043C0000 +05E1:00000000007E42424242424244780000 +05E2:00000000001212121212121212FE0000 +05E3:00000000007E42424272020202020202 +05E4:00000000007E424242720202027E0000 +05E5:00000000002222242830202020202020 +05E6:000000000042422418080402027E0000 +05E7:00000000007E22222424282020202020 +05E8:00000000007E02020202020202020000 +05E9:000000000049494949494949497F0000 +05EA:00000000003E22222222222222620000 +05EB:00007FFE73866DBE6D866DF673867FFE7FFE618E6FB6638E6FB6618E7FFE0000 +05EC:00007FFE73866DBE6D866DF673867FFE7FFE61C66FBE63BE6FBE61C67FFE0000 +05ED:00007FFE73866DBE6D866DF673867FFE7FFE618E6FB663B66FB6618E7FFE0000 +05EE:00007FFE73866DBE6D866DF673867FFE7FFE61866FBE638E6FBE61867FFE0000 +05EF:00000000003808087711111100000000 +05F0:00000000007711111111111111110000 +05F1:00000000007711111101010101010000 +05F2:00000000007711111100000000000000 +05F3:00000204080000000000000000000000 +05F4:00001224480000000000000000000000 +05F5:00007FFE73866DBE6D866DF673867FFE7FFE61866FBE63866FF66F867FFE0000 +05F6:00007FFE73866DBE6D866DF673867FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +05F7:00007FFE73866DBE6D866DF673867FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +05F8:00007FFE73866DBE6D866DF673867FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +05F9:00007FFE73866DBE6D866DF673867FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +05FA:00007FFE73866DBE6D866DF673867FFE7FFE61866FB663866FB66FB67FFE0000 +05FB:00007FFE73866DBE6D866DF673867FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +05FC:00007FFE73866DBE6D866DF673867FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +05FD:00007FFE73866DBE6D866DF673867FFE7FFE618E6FB663B66FB66F8E7FFE0000 +05FE:00007FFE73866DBE6D866DF673867FFE7FFE61866FBE638E6FBE6F867FFE0000 +05FF:00007FFE73866DBE6D866DF673867FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +0600:5555800000018000000180000001800000018004000980083FFD80000001AAAA +0601:55558000000180000001800000018000000180042A0DAA0C35F580000001AAAA +0602:5555800000018000000180000001800000018E000E1987E0000180000001AAAA +0603:555580000001800000018000001980240045814401499EF0000180000001AAAA +0604:55558000000180000001800000018000000180000195827C0201BF000001AAAA +0605:55558000000188041619A1E0000180000001800000018000000180000001AAAA +0606:000000A870A810D0088008800480040002700240014001800180010001000000 +0607:00200040708010A0084008900460040002700240014001800180010001000000 +0608:000000000000000000640E9832B004500410082007C000000000000000000000 +0609:00000004042808101020204450000000 +060A:00000004042808101020214450000000 +060B:000000000600060000C0012000E0002001C01E10000800080000000000000000 +060C:00000000000000081018180000000000 +060D:00000000000000000C18204000000000 +060E:0000000000000000000000000000000000000E00110011060FF8000000000000 +060F:0000000000000600080008000600080013001480188009001600200000000000 +0610:00060939160000000000000000000000 +0611:0000003000400278038004000800000000000000000000000000000000000000 +0612:00001F880208041008E008000000000000000000000000000000000000000000 +0613:0000060809083910166000000000000000000000000000000000000000000000 +0614:0000000000081FC8002800100000000000000000000000000000000000000000 +0615:0000040005C006200FC000000000000000000000000000000000000000000000 +0616:0500050005000D0010000FE00000000000000000000000000000000000000000 +0617:0000008000000080008003000000000000000000000000000000000000000000 +0618:00001800000000000000000000000000 +0619:181C1020000000000000000000000000 +061A:00000000000000000000000000001800 +061B:00000000000000081018001800000000 +061C:AAAA000180000001B2224A37FA2A4A23CBA20001800000018000000180005555 +061D:00007FFE73CE6DBE6D8E6DB673CE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000 +061E:0000000000000000000000000000000000000000000000800000014000000000 +061F:0000003E414020100808000800000000 +0620:000000000000000C5248443810281000 +0621:000000000000001C203C102000000000 +0622:00013E40080808080808080000000000 +0623:18201820080808080808080000000000 +0624:00000C100C10000C12121E0204483000 +0625:0000000008080808080808000C100C10 +0626:00000000182018200046484846423C00 +0627:00000008080808080808080000000000 +0628:000000000000000422423C0000080000 +0629:000000002400101824243C0000000000 +062A:000000001400000422423C0000000000 +062B:000010002800000422423C0000000000 +062C:00000000000000007E1020404840221C +062D:00000000000000007E1020404040221C +062E:00000000001000007E1020404040221C +062F:000000000000080402427C0000000000 +0630:000000002000080402427C0000000000 +0631:00000000000000000402020204483000 +0632:00000000001000000402020204483000 +0633:00000000000000000115155E48483000 +0634:00000008001200000115155E48483000 +0635:000000000000000006194E4848300000 +0636:000000000004000006194E4848300000 +0637:000000202020202C32227C0000000000 +0638:000000202420202C32227C0000000000 +0639:000000000000001824201C204040423C +063A:000000000800001824201C204040423C +063B:00005004081020403C827E0000000000 +063C:00000004081020403C827E0028001000 +063D:0000000010284400044A484442423C00 +063E:0000000000005000044A484442423C00 +063F:0000000000200050044A484442423C00 +0640:00000000000000000000FF0000000000 +0641:0000000800060A0642423C0000000000 +0642:000000002400001C120A264244380000 +0643:000000020A120A2242423C0000000000 +0644:000000020202020202224242443C0000 +0645:00000000000000001C061E2020202020 +0646:00000000001000000422424244380000 +0647:000000000000101824243C0000000000 +0648:000000000000000C12121E0204483000 +0649:0000000000000000044A484442423C00 +064A:0000000000000000044A4844423C0028 +064B:0C300C30000000000000000000000000 +064C:0C0C6428700000000000000000000000 +064D:0000000000000000000008300C300000 +064E:00000C30000000000000000000000000 +064F:0C0E0810200000000000000000000000 +0650:00000000000000000000000000000C30 +0651:00000004145860000000000000000000 +0652:18242418000000000000000000000000 +0653:00013E40000000000000000000000000 +0654:18201820000000000000000000000000 +0655:00000000000000000000000018201820 +0656:0000000000000000000000000000000000000000000000000000004000200020 +0657:04081070300000000000000000000000 +0658:24241800000000000000000000000000 +0659:0000003C000000000000000000000000 +065A:00442810100000000000000000000000 +065B:00101028440000000000000000000000 +065C:00000000000000000000000018180000 +065D:30701008040000000000000000000000 +065E:24081024000000000000000000000000 +065F:00000000000000000000000006082658 +0660:00000000000010381000000000000000 +0661:00000020201010080804040400000000 +0662:00000022241810080804040400000000 +0663:00000049523C20101008080800000000 +0664:00000004081020182040423C00000000 +0665:00000018242442424242241800000000 +0666:000000403C0404020202010100000000 +0667:00000041412222141408080800000000 +0668:00000008080814142222414100000000 +0669:0000001824444C340202010100000000 +066A:00000404484810102424404000000000 +066B:00000000000000000004040438000000 +066C:00000018180810000000000000000000 +066D:000000000008087F1C36220000000000 +066E:000000000000000422423C0000000000 +066F:000000000000001C120A264244380000 +0670:10101000000000000000000000000000 +0671:040A1E20080808080808080000000000 +0672:06082658000808080808080000000000 +0673:00000000080808080808080006082658 +0674:18201820000000000000000000000000 +0675:06080608202020202020200000000000 +0676:000003040304000C12121E0204483000 +0677:000033341324400C12121E0204483000 +0678:00000000030403040046484846423C00 +0679:000020203838000422423C0000000000 +067A:000010001000000422423C0000000000 +067B:000000000000000422423C0008000800 +067C:000000001400000422423C0814080000 +067D:000028001000000422423C0000000000 +067E:000000000000000422423C0014000800 +067F:000028002800000422423C0000000000 +0680:000000000000000422423C0014001400 +0681:00000018201820007E1020404040221C +0682:00000010001000007E1020404040221C +0683:00000000000000007E1020405440221C +0684:00000000000000007E1020484048221C +0685:00000010002400007E1020404040221C +0686:00000000000000007E2040544048221C +0687:00000000000000007E2040544054221C +0688:002020383800080402427C0000000000 +0689:000000000000080402427C0814080000 +068A:000000000000080402427C0008000000 +068B:002020383800080402427C0008000000 +068C:000000280000080402427C0000000000 +068D:000000000000080402427C0028000000 +068E:000010002800080402427C0000000000 +068F:000028001000080402427C0000000000 +0690:000028002800080402427C0000000000 +0691:000008080E0E00000402020204483000 +0692:00000000442810000402020204483000 +0693:000000000000000004020202044C3A04 +0694:00000000000000000402020204483200 +0695:00000000000000000804040408483502 +0696:00000000000000000402021204483200 +0697:00000000001200000402020204483000 +0698:00000008001400000402020204483000 +0699:00000012001200000402020204483000 +069A:000000000400000115155E484A300000 +069B:000000000000000115155E5055200200 +069C:000008001200000115155E5055200200 +069D:000000000000000006194E5055200000 +069E:000000080012000006194E4848300000 +069F:00000024202A202C32227C0000000000 +06A0:000010002400001824201C204040423C +06A1:0000000000060A0642423C0000000000 +06A2:0000000000060A0642423C0008000000 +06A3:0000040000060A0642423C0008000000 +06A4:0008001200060A0642423C0000000000 +06A5:0000000000060A0642423C0024001000 +06A6:000A000A00060A0642423C0000000000 +06A7:000000000400001C120A264244380000 +06A8:000010002400001C120A264244380000 +06A9:00000004081020403C827E0000000000 +06AA:0000000000000018006001800600080007FC40023FFC00000000000000000000 +06AB:000000040C1A24403C827E0000000000 +06AC:000800020A120A2242423C0000000000 +06AD:100028020A120A2242423C0000000000 +06AE:000000020A120A2242423C0014000800 +06AF:00081024481020403C827E0000000000 +06B0:000810244C1A24403C827E0000000000 +06B1:00500618620C30403C827E0000000000 +06B2:00081024481020403C827E0028000000 +06B3:00081024481020403C827E0010001000 +06B4:4000A618620C30403C827E0000000000 +06B5:00110A040002020202224242443C0000 +06B6:000200020202020202224242443C0000 +06B7:040009000202020202224242443C0000 +06B8:00000002020202020222423C00140008 +06B9:00000000000800000422424244380008 +06BA:00000000000000000422424244380000 +06BB:000010101C1C00000422424244380000 +06BC:000000000008000004224242443C0A04 +06BD:00000010002400000422424244380000 +06BE:000000000000102C2A1A244000000000 +06BF:00000000001000007E2040544048221C +06C0:001820182000101824243C0000000000 +06C1:000000000000000000102F4000000000 +06C2:000000001820182000102F4000000000 +06C3:000000000000280000102F4000000000 +06C4:000000000000000C12120E2252247800 +06C5:000000000000000C12121E021C483000 +06C6:000000221408000C12121E0204483000 +06C7:000018180810200C12121E0204483000 +06C8:000000080404000C12121E0204483000 +06C9:000000081422000C12121E0204483000 +06CA:000000001400000C12121E0204483000 +06CB:000008001200000C12121E0204483000 +06CC:0000000000000000044A484442423C00 +06CD:0000000000000000042A68A422221C00 +06CE:0000000044281000044A484442423C00 +06CF:000000000800000C12121E0204483000 +06D0:000000000000000C5248443800100010 +06D1:000000000000000C5248443800280010 +06D2:00000000000000000008141020407F00 +06D3:00000000003040304008141020407F00 +06D4:000000000000000000003C0000000000 +06D5:000000000000101824243C0000000000 +06D6:0208025C0FFC10001FC000000000000000000000000000000000000000000000 +06D7:024802200FE010001FC000000000000000000000000000000000000000000000 +06D8:0000004000A001E0060000000000000000000000000000000000000000000000 +06D9:0880048003000100030000000000000000000000000000000000000000000000 +06DA:1F8004000900042003C000000000000000000000000000000000000000000000 +06DB:4000A000000000000000000000000000 +06DC:0000012809F80900060000000000000000000000000000000000000000000000 +06DD:0000000001C006300BE80C181004100410040C180BE8063001C0000000000000 +06DE:0000008001401FFC1414180C11C432265225322611C4180C14141FFC01400080 +06DF:18242418000000000000000000000000 +06E0:18242424180000000000000000000000 +06E1:7E0C3000000000000000000000000000 +06E2:0180038002000200010000000000000000000000000000000000000000000000 +06E3:000000000000000000000000000000000000000000000000012809F809000600 +06E4:7C000000000000000000000000000000 +06E5:0000000000000000040A0E021C000000 +06E6:00000000000000001020407F00000000 +06E7:001020407F0000000000000000000000 +06E8:000000800420042003E000000000000000000000000000000000000000000000 +06E9:00000080014002A005500AA815542A2A15541554155415D4141417F430067FFF +06EA:0100028004400280010000000000000000000000000000000000000000000000 +06EB:0000000000000000000000000000000000000000000001000280044002800100 +06EC:0000018001800000000000000000000000000000000000000000000000000000 +06ED:0000000000000000000000000000000000000000000000000180010001000080 +06EE:000008142200080402427C0000000000 +06EF:00000000040A11000402020204483000 +06F0:00000000000010381000000000000000 +06F1:00000020201010080804040400000000 +06F2:00000022241810080804040400000000 +06F3:00000049523C20101008080800000000 +06F4:000000182460722C2010101000000000 +06F5:00000000080814142222495563000000 +06F6:000000001C2220201806186000000000 +06F7:00000041412222141408080800000000 +06F8:00000008080814142222414100000000 +06F9:0000001824444C340202010100000000 +06FA:000008001200000115155E484A300000 +06FB:000000000004000006194E484A300000 +06FC:000000000800001824201C204840423C +06FD:0000000000001C203C10200014141414 +06FE:00000000000000001C063E404A4A4A4A +06FF:000000102844102C2A1A244000000000 +0700:000000000000000001000380010008201C700820010003800100000000000000 +0701:0000000000001800180000000000000000000000000000000000000000000000 +0702:0000000000000000000000000000000000001800180000000000000000000000 +0703:0000000000001800180000000000000000001800180000000000000000000000 +0704:0000000000000000000000000000000018001800000000000000000018001800 +0705:0000000000000000000000006600660000000000000000000000000000000000 +0706:0000000000000000000000006000600000000000060006000000000000000000 +0707:0000000000000000000000000600060000000000000060006000000000000000 +0708:0000000060006000000000000600060000000000000000000000000000000000 +0709:0000000000000000000000000000000000000000600060000000000006000600 +070A:0000240024007E00000000000000000018001800000000000000000018001800 +070B:00000000000000007FFE00000000018001800000000000000000000000000000 +070C:00004000200010000800040002000100008000400024001C001C003C00000000 +070D:00000180018019981998018001807FFE7FFE0180018019981998018001800000 +070E:00007FFE73866DF66DEE6DDE73DE7FFE7FFE73866DBE6D8E6DBE73867FFE0000 +070F:AAAA0001B18C3FFDB18C000180000001B32244B7A7AA14A3E4A2000180005555 +0710:0000000000070007000E003C7FF8FFC0C600C300C1C0C0F04070000000000000 +0711:02000C00780050000C0000000000000000000000000000000000000000000000 +0712:000000000000000000000C000FF007F80008600860087FF83FF0000000000000 +0713:00000600070003000180018070C07C600F3003F000F8001C0006000000000000 +0714:00000600070003000180018073C07E600F3003F000F8001C0006000000000000 +0715:0000000000003F003E000E000600060006000600260006000200000000000000 +0716:0000000000003F003E000E000600060006000600060006000200000000000000 +0717:000000000000000000001F783FFC60844082408241026106320C000000000000 +0718:0000000000000000000007800CC0186010201030101019980F98000000000000 +0719:0000000000000C000E000E000600060006000600060006000200000000000000 +071A:00000000000000000000030C030C010601020082408260843FFC1F7800000000 +071B:00000C000E00060003000100018060807FF83FFC004200420042002400180000 +071C:00000C000E00060003000100018060807FF83FFC0042005A005A002400180000 +071D:000000000000000000000000000000000000300018000C000C000C0018003000 +071E:000002000000050000001DC03FE062204224422244126412240C008000000000 +071F:00000000000000001800186018701C9804980788030C00040004000200020001 +0720:000000000E000E0006000300018000C00060303030303FF01FF0000000000000 +0721:00000000000070007E001FF803FC03040304030403FC06F80C00180010000000 +0722:00000000000000000000000000001C003E003F8007C000F00018000400020000 +0723:000000000000000000003C00667843CC4184618431881FF00FE0000000000000 +0724:000000000000000000003C00667843CC4184618431881FF00FE0018001800000 +0725:00000000000000000000000003000300018060C060607FFE3FFE000000000000 +0726:000000000000000001E002300210021801E8600C60047FFE3FFE000000000000 +0727:00000000000000000F001880108030802F00600C400CFFFCFFF8000000000000 +0728:0000000000000000001000380FFC1FFC10000C0003C0003000180038FFF00000 +0729:00000000000000000000000001F003F802080204020413FC17FC0C0000000000 +072A:0200000000003F003E000E000600060006000600060006000200000000000000 +072B:0000000000000000000006600FF00FF007E003C061867FFE3FFE000000000000 +072C:000060007000300008C005E0061006100A081108208C3F8C1F0C000000000000 +072D:000000000020006000C0018003FC03FE0002000260027FFE3FFC000000000000 +072E:00000300018019801F000C000200010060807C403FE007F8001C000600020000 +072F:0000000000003F003E000E000600060006000600460006001200000000000000 +0730:3E00240028003000200000000000000000000000000000000000000000000000 +0731:0000000000000000000000000000000000000000000004000C00140024007C00 +0732:0000000004000000000000000000000000000000000000000000000020000000 +0733:1800240024001800100020000000000000000000000000000000000000000000 +0734:0000000000000000000000000000000000000000040008001800240024001800 +0735:0000080000002000000000000000000000000000000000000000000000000000 +0736:180004000A001200000000000000000000000000000000000000000000000000 +0737:0000000000000000000000000000000000000000000000002400280010000C00 +0738:0000000000000000000000000000000000000000000000000000000000002400 +0739:0000000000000000000000000000000000000000000000000000000008002000 +073A:7C0010007C000000000000000000000000000000000000000000000000000000 +073B:00000000000000000000000000000000000000000000000000003E0008003E00 +073C:0000000000000000000000000000000000000000000000000000000000001000 +073D:0100020005000880124005200210000000000000000000000000000000000000 +073E:0000000000000000000000000000000000001080094004900220014000800100 +073F:0000000000000800000000000000000000000000000000000000000000000000 +0740:0000000000002000000000000000000000000000000000000000000000000000 +0741:0000000000001000000000000000000000000000000000000000000000000000 +0742:0000000000000000000000000000000000000000000000000000000010000000 +0743:0000100000001000000000000000000000000000000000000000000000000000 +0744:0000000000000000000000000000000000000000000000000000100000001000 +0745:0000100000002800000000000000000000000000000000000000000000000000 +0746:0000000000000000000000000000000000000000000000000000280000001000 +0747:0000000008001000200000000000000000000000000000000000000000000000 +0748:0000000000000000000000000000000000000000000000000000200010000800 +0749:012000D000E8017400BA005C002C001200000000000000000000000000000000 +074A:540010007C001000540000000000000000000000000000000000000000000000 +074B:00007FFE73866DF66DEE6DDE73DE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000 +074C:00007FFE73866DF66DEE6DDE73DE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000 +074D:00001818181818180C300C30042004600660066002C002C003C0018001800000 +074E:00000000000C000600E600FC003000100008000860047FFE3FFE000000000000 +074F:00000180018000C0002C00320012001C0008000860047FFE3FFE000000000000 +0750:000000000000000422423C00002A0000 +0751:000000100028000422423C0000080000 +0752:000000000000000422423C0008001400 +0753:000000000820000422423C0008001400 +0754:000000000010000422423C0000140000 +0755:000000000000000422423C0008142200 +0756:000000442810000422423C0000000000 +0757:00000000000028007E1020404040221C +0758:00000000000000007E1024404A40221C +0759:202028347800080402427C0010001000 +075A:000000000000080402427C0008142200 +075B:00000000000000000402021F04483000 +075C:00000000001400140115155E48483000 +075D:000000000028001824201C204040423C +075E:000000280010001824201C204040423C +075F:000000100010001824201C204040423C +0760:0000000000060A0642423C000A000000 +0761:0000000000060A0642423C0004000A00 +0762:00000004881020403C827E0000000000 +0763:004000A4081020403C827E0000000000 +0764:00000004081020403C827E0008001400 +0765:00000000000800001C061E2020202020 +0766:00000000000000001C061E2028202020 +0767:00000000000020000422424244380014 +0768:20202834780020000422424244380000 +0769:00004428100020000422424244380000 +076A:000000040404041E0424444444380000 +076B:00000000100010000402020204483000 +076C:00000018201820000402020204483000 +076D:00000000040004000115155E48483000 +076E:00000000000000007E10284C4A5C221C +076F:00000000007E10284C4A5C405440221C +0770:00202028347800140115155E48483000 +0771:20202834780010400402020204483000 +0772:00001010141A3C007E1020404040221C +0773:28283020282808080808080000000000 +0774:2A2A3420282808080808080000000000 +0775:00000014141810101046484846423C00 +0776:00000015151A10101046484846423C00 +0777:0000000046484846423C000816101010 +0778:000050506040404C12121E0204483000 +0779:000054546840404C12121E0204483000 +077A:00000000005050604048541020407F00 +077B:00000000005454684048541020407F00 +077C:00000000000000007E10244B4848221C +077D:00000008161010100115155E48483000 +077E:00000000081422000115155E48483000 +077F:000028020A120A2242423C0000000000 +0780:00000000000004081060000000000000 +0781:000000000000121C1020C00000000000 +0782:0000000000002A342040800000000000 +0783:00000000000014081420C00000000000 +0784:00000000000028545438000000000000 +0785:0000000000001024381020C000000000 +0786:00000000000044485060000000000000 +0787:000000000000060A1222C20000000000 +0788:00000000000008141408106000000000 +0789:0000000000001C240810600000000000 +078A:00000000000408040804081060000000 +078B:0000000000000204021C20C000000000 +078C:0000000000000C122C4020C000000000 +078D:00000000000008103C08106000000000 +078E:00000000000000040810087000000000 +078F:0000000000002A342040403800000000 +0790:0000000000000000000000000000000030043FF8400000000000000000000000 +0791:00000000000018601860180600000000 +0792:00000000000028102840403800000000 +0793:00000000000028545438403800000000 +0794:00000000000000161A22C00000000000 +0795:00000000000408040804081260000000 +0796:00000000000004080438403800000000 +0797:0000000102040C122C4020C000000000 +0798:000000000004110C122C4020C0000000 +0799:00000000000004081064000000000000 +079A:00000000001004081060000000000000 +079B:0000000000080204021C20C000000000 +079C:0000000000080014081420C000000000 +079D:0000000000000000000000000080022030043FF8400000000000000000000000 +079E:0000000000000000000000000000000030043FF8400000800000000000000000 +079F:0000000000000000000000000000008030043FF8400000000000000000000000 +07A0:0000000000000C122C4028C000000000 +07A1:000000000004000C122C4020C0000000 +07A2:000000000000060A1222C20800000000 +07A3:00000000000400060A32C20000000000 +07A4:00000000000014000C10087000000000 +07A5:00000000000800081414081060000000 +07A6:00081020000000000000000000000000 +07A7:00122448000000000000000000000000 +07A8:00000000000000000000000000102040 +07A9:00000000000000000000000000122448 +07AA:00300810200000000000000000000000 +07AB:00661122440000000000000000000000 +07AC:00081020180000000000000000000000 +07AD:00224488660000000000000000000000 +07AE:00621428460000000000000000000000 +07AF:1C244840300000000000000000000000 +07B0:00182418000000000000000000000000 +07B1:00000000000010282810204038000000 +07B2:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DF663866DBE63867FFE0000 +07B3:00007FFE73866DF66DEE6DDE73DE7FFE7FFE638E6DF663C66DF6638E7FFE0000 +07B4:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63B66DB663866DF663F67FFE0000 +07B5:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DBE63866DF663867FFE0000 +07B6:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000 +07B7:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DF663EE6DDE63DE7FFE0000 +07B8:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000 +07B9:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63CE6DB663C66DF663CE7FFE0000 +07BA:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DB663866DB663B67FFE0000 +07BB:00007FFE73866DF66DEE6DDE73DE7FFE7FFE638E6DB6638E6DB6638E7FFE0000 +07BC:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000 +07BD:00007FFE73866DF66DEE6DDE73DE7FFE7FFE638E6DB663B66DB6638E7FFE0000 +07BE:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DBE638E6DBE63867FFE0000 +07BF:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DBE638E6DBE63BE7FFE0000 +07C0:00000000182424424242422424180000 +07C1:000000001814121010101010107E0000 +07C2:000000002222223E2020202020200000 +07C3:000000000404040404043C04043C0000 +07C4:0000000004040404043C2020203C0000 +07C5:00000000202020203820202020200000 +07C6:00000000404040407C04040404040000 +07C7:00000000404040404244485060600000 +07C8:00000000404040407E44485060600000 +07C9:00000000384444443810101010100000 +07CA:00000000101010101010101010100000 +07CB:00000000000000001824424224180000 +07CC:00000000824428281010101010100000 +07CD:00000000000000000010282844440000 +07CE:000000000000000044444444447C0000 +07CF:00000000000000007C040404047C0000 +07D0:000000003844444438101010107C0000 +07D1:000000000010202018000000007E0000 +07D2:000000001028281E0A12020202020000 +07D3:000000003C20203C2020202020200000 +07D4:000000003C04043C0404040404040000 +07D5:00000000404040407844444444780000 +07D6:000000003E2020101008080404040000 +07D7:00000000182848080808080808080000 +07D8:00000000000000002C525252527E0000 +07D9:00000000080808083E08080808080000 +07DA:00000000242424247E242424243C0000 +07DB:00000000000000007E424242427E0000 +07DC:00000000000000007C44442828100000 +07DD:00000000040A0A0A0C78484848780000 +07DE:000000000424243C2424040404040000 +07DF:00000000304848483E08080808080000 +07E0:000000007C1010101010101010100000 +07E1:000000000000000010282844447C0000 +07E2:00000000701010384444381010100000 +07E3:000000003E2222020202020202020000 +07E4:0000000020203C242404040404040000 +07E5:000000003C0404043C242424243C0000 +07E6:00000000101010384444381010100000 +07E7:000000007C1010384444381010100000 +07E8:0000000000000000000000001070121C +07E9:00000000000000000000000010741A1C +07EA:000000000000000000000008083E0808 +07EB:00003C00000000000000000000000000 +07EC:122C4000000000000000000000000000 +07ED:00100000000000000000000000000000 +07EE:10284400000000000000000000000000 +07EF:08047E00000000000000000000000000 +07F0:48340200000000000000000000000000 +07F1:10207E00000000000000000000000000 +07F2:00000000000000000000000000000010 +07F3:00002400000000000000000000000000 +07F4:00000000003008081000000000000000 +07F5:00000000001020201800000000000000 +07F6:000000001C2222221E040810203E0000 +07F7:000000001C222A224155412A1C000000 +07F8:000000000000181800000000003C0000 +07F9:0000000000003C000018180018180000 +07FA:00000000000000000000000000FF0000 +07FB:00007FFE73866DF66DEE6DDE73DE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +07FC:00007FFE73866DF66DEE6DDE73DE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +07FD:00000000000000000000000000007E42 +07FE:00000000000000002C5252527E107C10 +07FF:0000000040F040407844444444780000 +0800:000000000000000000000008011002A0044008240828103010200C4000000000 +0801:0000000000000000000000000380044008200FE00010001000083FF800000000 +0802:000000000000000000000000003007C00440084000200010002000C000000000 +0803:00000000000000000000000003F8042008100FF0000800080010002000000000 +0804:000000000000000000000000003007C004C00940026004900520004000000000 +0805:000000000000000000000000004007A004900900030004E00010002000000000 +0806:000000000000000000000000038004401C6013901010101010201CC000000000 +0807:000000000000000000000000002007C004C0094032600C900510022000000000 +0808:000000000000000000000200040009F0111008A004A002400140008000000000 +0809:000000000000000000000000000000F003900490049009200920092000000000 +080A:0000000000000000000008080C081FF0001000100010021007900FF000000000 +080B:00000000000000000000008000800080030004000800081018301FF000000000 +080C:00000000000000000000000008881DD81FF82008000808101E103FF000000000 +080D:00000000040004000400080008000FF0001000100010021007900FF000000000 +080E:0000000000000000060009000A0019C00078009008A01F600100020007800000 +080F:00000000000000000000000000001FE008400440028001800080000000000000 +0810:00000000000000000000000000000FF0001000100010021007900FF000000000 +0811:000000000000000000000000000003F014901C90149005201920092000000000 +0812:000000000000000000000000080007E00610091000A000400180020001800000 +0813:00000000000000000000000003C0042008100FF0000800080010002000000000 +0814:00000000000000000000000008881DD81FF82004000000000000000000000000 +0815:00000000000000000000000001000280044008240828103010200C4000000000 +0816:00000010002000280012000C0000000000000000000000000000000000000000 +0817:000000100010001200140016000C000000000000000000000000000000000000 +0818:00000FFC00000000000000000000000000000000000000000000000000000000 +0819:0080004000200040008000000000000000000000000000000000000000000000 +081A:0000071008E00000000000000000000000000000000000000000000000000000 +081B:0000071008E00000000000000000000000000000000000000000000000000000 +081C:0000440044002800280010001000000000000000000000000000000000000000 +081D:0000440028001000000000000000000000000000000000000000000000000000 +081E:0000100010001000100010001000100010000000000000000000000000000000 +081F:0000100010001000100010000000000000000000000000000000000000000000 +0820:0000100010001000000000000000000000000000000000000000000000000000 +0821:00007F8000000000000000000000000000000000000000000000000000000000 +0822:00001F0000000000000000000000000000000000000000000000000000000000 +0823:00000E0000000000000000000000000000000000000000000000000000000000 +0824:0000008000800100010002000200000000000000000000000000000000000000 +0825:0000080008001000100020002000000000000000000000000000000000000000 +0826:0000100010002800280044004400000000000000000000000000000000000000 +0827:0000100028004400000000000000000000000000000000000000000000000000 +0828:0000008001000200010000800000000000000000000000000000000000000000 +0829:000003000C0030000C0003000000000000000000000000000000000000000000 +082A:0000020004000800040002000000000000000000000000000000000000000000 +082B:0000100010002800280044007C00000000000000000000000000000000000000 +082C:000000C00120012000C000000000000000000000000000000000000000000000 +082D:0000018001800000000000000000000000000000000000000000000000000000 +082E:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DBE618E6FBE61867FFE0000 +082F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DBE618E6FBE61BE7FFE0000 +0830:0000000000000000000000000180018000000000000000000000000000000000 +0831:0000000000000000018001800000000000000000018001800000000000000000 +0832:0000000000000000000000000C600C6000000000000000000000000000000000 +0833:000000000000000000003F183018100008000400020002000400000000000000 +0834:000000000000000000003F183018100008000400021802180400000000000000 +0835:000000000000000000000240000003C004000400030000C00000000000000000 +0836:00000000003000300000008000400040008001000200060007E0000000000000 +0837:00000000000000000000007E006000207F900008000400040008000000000000 +0838:000000000000000000000000000000067FE60000000000000000000000000000 +0839:000000000000000000000006000600007FE00000000600060000000000000000 +083A:0000000000000000000000067FE600000000000000067FE60000000000000000 +083B:0000000000000000000004600460040004000400046004600000000000000000 +083C:0000000000000010002000400080010002000400080010002000000000000000 +083D:0000000000000010002000400080011802180400080011982198000000000000 +083E:0000000000000000000000000180024002400180000000000000000000000000 +083F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63867DBE718E7DBE63BE7FFE0000 +0840:0000000000000000000000000000038004400820082004400380000000000000 +0841:0000000000000000000000840104020403F8004000203FFE0000000000000000 +0842:000000000000000000600090016001000080004000303FFC0000000000000000 +0843:00000000000000000000001400240044007C000400043FF80000000000000000 +0844:000000000000000000000000000000000000005400543FF80000000000000000 +0845:0000000000000000000000100008000403FC0000000000000000000000000000 +0846:0000000000000000008000800080008000800080008000800000000000000000 +0847:0000000000000000000000000000000003E00410040803FC0000000000000000 +0848:00000000000000E001200140014000A03FF00000000000000000000000000000 +0849:0000000000000000000000800100020003F00000000000000000000000000000 +084A:0000000000000000004010800900090004E004200440048009000E0000000000 +084B:0000000000000000000400040004000400040004000401F80000000000000000 +084C:0000000000000000000000840104020403FC004400243FC40000000000000000 +084D:00000000000000000000104008200820042004400440048009000E0000000000 +084E:000000000000000000000000000000000018008400443FF80000000000000000 +084F:0000000000000000000000400080010001F8000400043FF80000000000000000 +0850:000000000000000000C01120096008A0042004400440048009000E0000000000 +0851:0000000000000000002A102A083E0820042004400440048009000E0000000000 +0852:0000000000000000000000840104020403FC004400243FF80000000000000000 +0853:0000000000000000000000840104020403FC000400043FF80000000000000000 +0854:000000000000000000000C18122412240D580140014000800080000000000000 +0855:000000000000000000000084007C002400240FC4000000000000000000000000 +0856:000000000000000000000210042008400FF00000000000000000000000000000 +0857:00000000000000000008111020A020A01F9C008400880090012001C000000000 +0858:0000000000000000008001000200020001C002000200020001C0000000000000 +0859:0000000000000000000000000000000000000000000000000000024002400000 +085A:000000000000000000000000000000000000000000000000000003E000000000 +085B:0000000000000000000000000000000000000000000000000000008000800000 +085C:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000 +085D:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE618E6FB661B67DB6618E7FFE0000 +085E:0000000000000180066008100990124812480990081006600180000000000000 +085F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61866FBE618E7DBE61BE7FFE0000 +0860:000000000000000003C004200A100610001000E00020201010100FF000000000 +0861:00000000000000001EF029082908100800081F082088407040003FF800240018 +0862:0000000000000000180026002984106A001201AC024021A010100FF000000000 +0863:0000000000000000400020001000080004000200010E00840044003800000000 +0864:000000000000000003C004200A10061000D0012000E0201010100FF000000000 +0865:000000000000000007C0082008100410001000E00020201010100FF000000000 +0866:000000000000000007F01808200803F00400040003F00008080807F000000000 +0867:0000000000000000000001000080004000400040008001000600180000000000 +0868:00000000000000000C00120022002400280030002018212421241EF800000000 +0869:00000000000000002000100008000800080008000830084808480FF800400180 +086A:0000000000000000003004480848105010201050109009080A0807F000000000 +086B:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6FB6638E6DB6738E7FFE0000 +086C:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000 +086D:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6FB663B66DB6738E7FFE0000 +086E:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866FBE638E6DBE73867FFE0000 +086F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866FBE638E6DBE73BE7FFE0000 +0870:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61CE7DB67BB677B677CE7FFE0000 +0871:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000 +0872:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DF67B8677BE77867FFE0000 +0873:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE618E7DF67BC677F6778E7FFE0000 +0874:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61B67DB67B8677F677F67FFE0000 +0875:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DBE7B8677F677867FFE0000 +0876:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000 +0877:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DF67BEE77DE77DE7FFE0000 +0878:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000 +0879:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61CE7DB67BC677F677CE7FFE0000 +087A:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DB67B8677B677B67FFE0000 +087B:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE618E7DB67B8E77B6778E7FFE0000 +087C:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000 +087D:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE618E7DB67BB677B6778E7FFE0000 +087E:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DBE7B8E77BE77867FFE0000 +087F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +0880:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB673B66DB673CE7FFE0000 +0881:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000 +0882:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DF673866DBE73867FFE0000 +0883:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DF673C66DF6738E7FFE0000 +0884:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73B66DB673866DF673F67FFE0000 +0885:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE73866DF673867FFE0000 +0886:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000 +0887:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DF673EE6DDE73DE7FFE0000 +0888:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000 +0889:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB673C66DF673CE7FFE0000 +088A:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DB673866DB673B67FFE0000 +088B:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DB6738E6DB6738E7FFE0000 +088C:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000 +088D:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DB673B66DB6738E7FFE0000 +088E:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE738E6DBE73867FFE0000 +088F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE738E6DBE73BE7FFE0000 +0890:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB671B67DB673CE7FFE0000 +0891:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000 +0892:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DF671867DBE73867FFE0000 +0893:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DF671C67DF6738E7FFE0000 +0894:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73B66DB671867DF673F67FFE0000 +0895:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE71867DF673867FFE0000 +0896:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000 +0897:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DF671EE7DDE73DE7FFE0000 +0898:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000 +0899:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB671C67DF673CE7FFE0000 +089A:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DB671867DB673B67FFE0000 +089B:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DB6718E7DB6738E7FFE0000 +089C:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000 +089D:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DB671B67DB6738E7FFE0000 +089E:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE718E7DBE73867FFE0000 +089F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE718E7DBE73BE7FFE0000 +08A0:000000000000000422423C0022140800 +08A1:00000C100C10000422423C0010000000 +08A2:00000000000820007E1020404840221C +08A3:000000202228202C32227C0000000000 +08A4:0010002800060A0642423C0010000000 +08A5:000000002400001C120A264244380010 +08A6:00000004041F041F0424444448380000 +08A7:00000000080014001C061E2020202020 +08A8:0000000018201820044A4844423C0028 +08A9:0000000000001000044A4844423C0028 +08AA:00000000000000000402020234483402 +08AB:000000000000000C12120E2204483000 +08AC:000000000000000000000814146E404A +08AD:00000000000000000000080808080800 +08AE:000000000000080402427C0028001000 +08AF:000000000000000006194E4830042008 +08B0:00000810244850403C827E0000000000 +08B1:000000000000000814141E0404040400 +08B2:00001028440010000402020204483000 +08B3:0000000000001824201C20544048423C +08B4:000000020A120A2242423C0000080000 +08B5:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DBE63866DF663867FFE0000 +08B6:000018041C10100422423C0000080000 +08B7:000018041C10100422423C0024000800 +08B8:00000000140000229D413E0000000000 +08B9:00200008044448300402020204483000 +08BA:0020000804444830044A4844423C0028 +08BB:0000000000060A06423C000000000000 +08BC:0000000000060A0642423C0000000000 +08BD:00000000000000000422424244380000 +08BE:000000442810000422423C0014000800 +08BF:004428100014000422423C0000000000 +08C0:221448405068F00422423C0000000000 +08C1:00000000442810007E2040544048221C +08C2:00885024081020403C827E0000000000 +08C3:001000240008001824201C204040423C +08C4:000010002400001C120A264244380000 +08C5:00000010002400007E1020404840221C +08C6:000000000000007E204840544048221C +08C7:4040506AF202020202224242443C0000 +08C8:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +08C9:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +08CA:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71866FB66F866FB671B67FFE0000 +08CB:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +08CC:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +08CD:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE718E6FB66FB66FB6718E7FFE0000 +08CE:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000 +08CF:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +08D0:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000 +08D1:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000 +08D2:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DF66D866DBE63867FFE0000 +08D3:0000000000000000000000040A0E021C +08D4:216B87A7839364000000000000000000 +08D5:0000000006194E502000000000000000 +08D6:00102820182044380000000000000000 +08D7:0024000C0A4638000000000000000000 +08D8:00200008244832040000000000000000 +08D9:00000000000000000000002008244932 +08DA:020A0B2A6D6A010A154A2EB24000000000000000000000000000000000000000 +08DB:A80508054A05A955566901800000000000000000000000000000000000000000 +08DC:0005481514C58B5575E900000000000000000000000000000000000000000000 +08DD:00C0030094004A00010249AAB6D4000000000000000000000000000000000000 +08DE:0010004000100228009811480FB0000000000000000000000000000000000000 +08DF:00400100284042A4056A22265DC2001C00000000000000000000000000000000 +08E0:0020523C000000000000000000000000 +08E1:00020515EE0000000000000000000000 +08E2:08142222414936000000000000000000 +08E3:0000000000000000000000034C304830 +08E4:0004020C100800000000000000000000 +08E5:0C0E4830000000000000000000000000 +08E6:000000000000000000000004020C1008 +08E7:00221166884400000000000000000000 +08E8:1C22225522221C000000000000000000 +08E9:00000000000000000000002211668844 +08EA:00001000000000000000000000000000 +08EB:00000420000000000000000000000000 +08EC:001A241A000000000000000000000000 +08ED:00000000000000000000000000000010 +08EE:00000000000000000000000000001040 +08EF:00000000000000000000000000344834 +08F0:06180018600000000000000000000000 +08F1:66772244880000000000000000000000 +08F2:00000000000000000000000618001860 +08F3:00040A0E021C00000000000000000000 +08F4:00344854245800000000000000000000 +08F5:200C3000000000000000000000000000 +08F6:000000000000000000000000000C3004 +08F7:20402000000000000000000000000000 +08F8:10081000000000000000000000000000 +08F9:00000000000000000000000000102010 +08FA:00000000000000000000000000100810 +08FB:48244800000000000000000000000000 +08FC:24922400000000000000000000000000 +08FD:08240800000000000000000000000000 +08FE:0C2E0810200000000000000000000000 +08FF:001C0202041800000000000000000000 +0900:01C0022004800000000000000000000000000000000000000000000000000000 +0901:0480022001C00000000000000000000000000000000000000000000000000000 +0902:0180018000000000000000000000000000000000000000000000000000000000 +0903:0000000000000000000000000003000300000000000000030003000000000000 +0904:010000FC000201CF02220012001200620412041E0212022201C2000000000000 +0905:00000000000001CF02220012001200620412041E0212022201C2000000000000 +0906:0000000000000E7F1114009400940314209420F4109411140E14000000000000 +0907:0000000000003FFF004003C00400040003C000200010019001E0004000200010 +0908:00E0011000803FFF004003C00400040003C000200010019001E0004000200010 +0909:0000000000001FFF0010000804080430020802080108011000E0000000000000 +090A:0000000000003FFF00400020102010CC08320822042204420384000000000000 +090B:0000000000007FFF00801E9821F806901888009000A000A40098000000000000 +090C:000000000000FFFF002000201C70228821082010102008200018000000000000 +090D:011000E000001FFF021002100210021002100100008000400020002000000000 +090E:040003E000101FFF021002100210021002100100008000400020002000000000 +090F:0000000000001FFF021002100210021002100100008000400020002000000000 +0910:07C0002000101FFF021002100210021002100100008000400020002000000000 +0911:011000E000000E7F1114009400940314209420F4109411140E14000000000000 +0912:080007F800040E7F1114009400940314209420F4109411140E14000000000000 +0913:07F0000800040E7F1114009400940314209420F4109411140E14000000000000 +0914:01F8000400FC0E3F1114009400940314209420F4109411140E14000000000000 +0915:000000000000FFFF008000800EB011C811880E88009000800080000000000000 +0916:000000000000FFFF0810081009D01A301A3011D00810043003D0000000000000 +0917:000000000000FFFF0210021002100A1006100210001000100010000000000000 +0918:000000000000FFFF08080608018802080408041803E800080008000000000000 +0919:000000000000FFFF008003800400041813981040084008400780000000000000 +091A:000000000000FFFF000800080FF8021802680188000800080008000000000000 +091B:000000000000FFFF004006600890085006200830084804480388001000000000 +091C:000000000000FFFF000800080878084804480388000800080008000000000000 +091D:000000000000FFFF010807080808080807F8010801080E080C08020001000000 +091E:000000000000FFFF0008000803C8132810280838082804480388000000000000 +091F:000000000000FFFF0080008003800400080008000808041003E0000000000000 +0920:000000000000FFFF0080008003E00410080808080808041003E0000000000000 +0921:000000000000FFFF002000E00100010004E004100210021001E0000000000000 +0922:000000000000FFFF0080008003800400086008900890045003E0000000000000 +0923:000000000000FFFF049004900490049003100010001000100010000000000000 +0924:000000000000FFFF0010001003F0041008100810081004100210000000000000 +0925:0000000000000C3F120811080908010802080C18082804480388000000000000 +0926:000000000000FFFF0080008003800400080008000830043003E0001000080000 +0927:0000000000000CFF1208140808080C0807080808081807E80008000000000000 +0928:000000000000FFFF0008000803F8060806080008000800080008000000000000 +0929:000000000000FFFF0008000803F80608060800080008000800C800C000000000 +092A:000000000000FFFF081008100810083004500390001000100010000000000000 +092B:000000000000FFFF104010401040107008C80748004800480050000000000000 +092C:000000000000FFFF0010001007D00C300A300950079000100010000000000000 +092D:0000000000000C7F12080E080208020807F80608000800080008000000000000 +092E:000000000000FFFF04100410041004100FF00C10001000100010000000000000 +092F:000000000000FFFF0210021002100C100810083007D000100010000000000000 +0930:000000000000FFFF020002000200060006000100008000400000000000000000 +0931:000000000000FFFF020002000200060006000100008000400600060000000000 +0932:000000000000FFFF000800080638094808880808040803080008000000000000 +0933:000000000000FFFF002000200C70128810881108128812480C30000000000000 +0934:000000000000FFFF002000200C70128810881108128812480C30018001800000 +0935:000000000000FFFF0010001007D0083008300850079000100010000000000000 +0936:000000000000FFFF0610091009100710011001100E100D100090000000000000 +0937:000000000000FFFF0C100A10091008B004500390001000100010000000000000 +0938:000000000000FFFF04100410041004100FF00C10041002100110000000000000 +0939:0000000000003FFF004003C00400040003800440044002000100008000000000 +093A:0080008000000000000000000000000000000000000000000000000000000000 +093B:000000020002000F000200020002000200020002000200020002000000000000 +093C:0000000000000000000000000000000000000000000000000000000001800180 +093D:00000000000003F004000400030000C00020002010200C400380000000000000 +093E:000000000000000F000200020002000200020002000200020002000000000000 +093F:3FC040204000F000400040004000400040004000400040004000000000000000 +0940:03FC04020002000F000200020002000200020002000200020002000000000000 +0941:00000000000000000000000000000000000000000000000000000410021001E0 +0942:000000000000000000000000000000000000000000000000000001E002100410 +0943:0000000000000000000000000000000000000000000000000000007000800070 +0944:0000000000000000000000000000000000000000000000C00100017000800078 +0945:0400022001C00000000000000000000000000000000000000000000000000000 +0946:10000F0000800080000000000000000000000000000000000000000000000000 +0947:1E00010000800000000000000000000000000000000000000000000000000000 +0948:07801F4000C00000000000000000000000000000000000000000000000000000 +0949:001100090006000F000200020002000200020002000200020002000000000000 +094A:010000FC0002000F000200020002000200020002000200020002000000000000 +094B:01F800040002000F000200020002000200020002000200020002000000000000 +094C:007C01FA0006000F000200020002000200020002000200020002000000000000 +094D:0000000000000000000000000000000000000000000000000000006000100008 +094E:000000000000F000800080008000800080008000800080008000000000000000 +094F:027C01FA0006000F000200020002000200020002000200020002000000000000 +0950:0000001800181C42223C01000100060C41124192216C22001C00000000000000 +0951:0180018000800000000000000000000000000000000000000000000000000000 +0952:0000000000000000000000000000000000000000000000000000000007E00000 +0953:0200010000800000000000000000000000000000000000000000000000000000 +0954:0040008001000000000000000000000000000000000000000000000000000000 +0955:0240018003C00000000000000000000000000000000000000000000000000000 +0956:00000000000000000000000000000000000000000000000000000810042003C0 +0957:00000000000000000000000000000000000000000000000000001248099007E0 +0958:000000000000FFFF008000800EB011C811880E8800900C800C80000000000000 +0959:000000000000FFFF0810081009D01A301A3011D00810043003D0000003000300 +095A:000000000000FFFF0210021002100A1006100210001000100190018000000000 +095B:000000000000FFFF000800080878084804480388000800080188018000000000 +095C:000000000000FFFF002000E00100010004E004100210021001E0000000C000C0 +095D:000000000000FFFF0080008003800400086008900890045003E0000001800180 +095E:000000000000FFFF104010401040107008C80748004806480650000000000000 +095F:000000000000FFFF0210021002100C100810083007D000100310030000000000 +0960:0000000000007FFF00801E8C21FC0688189800A0009800A2009C000000000000 +0961:000000000000FFFF002000201C70228821082030104008300044003800000000 +0962:00000000000000000000000000000000000000000000000000000EE011200818 +0963:0000000000000000000000000000000000000000000000080C7012941118080E +0964:0000000000000000008000800080008000800080008000800080000000000000 +0965:0000000000000000024002400240024002400240024002400240000000000000 +0966:000000000000000003C0042008100810081008100810042003C0000000000000 +0967:000000000000000001C002200220014000800100020001000080004000000000 +0968:000000000000000003C00420001000100010032003C001000080004000200000 +0969:000000000000000003C004200020002001C000200020062007C0010000800000 +096A:0000000000000000101008200440028001000280044004400380000000000000 +096B:00000000000000000800080008C008C007800040004000200020001000100000 +096C:000000000000000003C0042004000400038004000400046003E0008001000000 +096D:000000000000000000E001100910093008D004100410022001C0000000000000 +096E:00000000000000000040008001000200040008000810042003C0000000000000 +096F:0000000000000000018002400240038001000080004000200010000000000000 +0970:000000000000000001C00220022001C000000000000000000000000000000000 +0971:0000000000000180018000000000000000000000000000000000000000000000 +0972:00420022001C01CF02220012001200620412041E0212022201C2000000000000 +0973:00000002000201CF02220012001200620412041E0212022201C2000000000000 +0974:000000020002073F088A004A004A018A104A107A084A088A070A000000000000 +0975:0120009C0072070F088A004A004A018A104A107A084A088A070A000000000000 +0976:00000000000001CF02220012001200620412041E0212022201C2000000840078 +0977:00000000000001CF02220012001200620412041E0212022201C20090026401F8 +0978:000000000000FFFF0400040004000FC00C200020002000400080000000000000 +0979:000000000000FFFF000800080878084804480388000818681868030003000000 +097A:000000000000FFFF0210021003100C900850083007D000100010000000000000 +097B:000000000000FFFF0210021002100A1006100210001000100FF0000000000000 +097C:000000000000FFFF000800080878084804480388000800080FF8000000000000 +097D:00000000000003E00410080800080008001000E0008000800080000000000000 +097E:000000000000FFFF002000E00100010004E00410021001E007F8000000000000 +097F:000000000000FFFF0010001007D00C300A300950079000100FF0000000000000 +0980:0000000000000380044008200920062000200020002000200020002400180000 +0981:0080022001C00000000000000000000000000000000000000000000000000000 +0982:0000000000000000000000020005000500020000000400020001000100000000 +0983:0000000000000000000000020005000500020000000200050005000200000000 +0984:00007FFE73CE6DB66DC66DF673CE7FFE7FFE73B66DB673866DF673F67FFE0000 +0985:0000000000003FFF000811881248122810280828082804580388000000000000 +0986:0000000000003FFF000A118A124A122A102A082A082A045A038A000000000000 +0987:020001F000083FFF000003C004200410001000600780030000C0003000000000 +0988:020001F000083FFF00000618092008E0014002400C4000200018000000000000 +0989:020001F000083FFF0040004008580868080804080408021001E0000000000000 +098A:020001F000083FFF004000400A580A680A080908050804F003E0000000000000 +098B:000000000000002F102824281A6801A80E6830380E2801A80068000000000000 +098C:00000000000003000400020001C0002007100890085004500060008000000000 +098D:00007FFE73CE6DB66DC66DF673CE7FFE7FFE738E6DB673B66DB6738E7FFE0000 +098E:00007FFE73CE6DB66DC66DF673CE7FFE7FFE73866DBE738E6DBE73867FFE0000 +098F:00000000000000E001100210121011101010101010D009300610000000000000 +0990:020001F0000800E401140214121811101010101010D009300610000000000000 +0991:00007FFE73CE6DB66DC66DF673CE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000 +0992:00007FFE73CE6DB66DC66DF673CE7FFE7FFE73866DF671867DBE73867FFE0000 +0993:00000000000000600090040804080430020802080108011000E0000000000000 +0994:000001E00010018802481028102810C808300820042004400380000000000000 +0995:000000000000FFFF00E0015002480C4810480C500240014000C0000000000000 +0996:000000000000088F074800480048018806080F0800C800280018000000000000 +0997:00000000000003CF042808180F08008800880108060800080008000000000000 +0998:000000000000FFFF0408080808080608010806080C0803E80018000000000000 +0999:00000000000004600490029001E01100113008E80808041003E0000000000000 +099A:000000000000FFFF08000C000C000B0008E00810082008C00F00000000000000 +099B:000000000000FFFF08000E0009C00920062000400F80060001C0003000000000 +099C:000000000000FFFF018011401120111808C80850085004500388000000000000 +099D:000000000000FFEF006800A80128062818280628012800B80068000000000000 +099E:0000000000000300048008B008C804880090108810C809B00680000000000000 +099F:020001F00008FFFF040004000400040004300430042004C00700000000000000 +09A0:018002000100FFFF00C000A001100910161010101010082007C0000000000000 +09A1:000000000000FFFF0040004008580868080804080408021001E0000000000000 +09A2:000000000000FFFF040004000400040004300430042004C00700000000000000 +09A3:000000000000000F03C8042808180E0806080008000800080008000000000000 +09A4:000000000000FFFF000008E009100908080804080408021001E0000000000000 +09A5:000000000000078F084808480048018806080F0800C800280018000000000000 +09A6:000000000000FFFF08000800083008D00B100C20002000200010000000000000 +09A7:000000000000020F041804680388060818080608018800680018000000000000 +09A8:000000000000FFFF00080008000803C8042808180E0806080008000000000000 +09A9:00007FFE73CE6DB66DC66DF673CE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000 +09AA:00000000000007CF082818180418026807880008000800080008000000000000 +09AB:000000000000FFFF080004100228012802200C20182007A00060000000000000 +09AC:000000000000FFFF001800680188060818080608018800680018000000000000 +09AD:000000000000FFFF000001800B900A2809C804080408021001E0000000000000 +09AE:000000000000FFFF00080C080208010801080308058802680018000000000000 +09AF:000000000000FFFF080804080208010802080C08038800680018000000000000 +09B0:000000000000FFFF001800680188060818080608018800680318030000000000 +09B1:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000 +09B2:000000000000FFFF000800080638094808880808080806080008000000000000 +09B3:00007FFE73CE6DB66DC66DF673CE7FFE7FFE638E6DF663C66DF6638E7FFE0000 +09B4:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63B66DB663866DF663F67FFE0000 +09B5:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DBE63866DF663867FFE0000 +09B6:000000000000F06F0A9805080D880D8800080008000800080008000000000000 +09B7:000000000000FFFF080804080208018802680C18038800680018000000000000 +09B8:000000000000FFFF06080908008800B800480888070800080008000000000000 +09B9:000000000000FFFF000007C00E200610001000600780030000C0003000000000 +09BA:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DB663866DB663B67FFE0000 +09BB:00007FFE73CE6DB66DC66DF673CE7FFE7FFE638E6DB6638E6DB6638E7FFE0000 +09BC:0000000000000000000000000000000000000000000000000000018001800000 +09BD:0000000000000C0003C0032003100010001000600780030000C0003000000000 +09BE:000000000000000B000600020002000200020002000200020002000000000000 +09BF:3FF040084000E000400040004000400040004000400040004000000000000000 +09C0:0FFC10020FFA0007000200020002000200020002000200020002000000000000 +09C1:000000000000000000000000000000000000000000000000000800E8011000E8 +09C2:00000000000000000000000000000000000000000000000000000060008C0073 +09C3:0000000000000000000000000000000000000000000000000004000800100008 +09C4:0000000000000000000000000000000100020004000200010004000800100008 +09C5:00007FFE73CE6DB66DC66DF673CE7FFE7FFE71866FBE6F866FF671867FFE0000 +09C6:00007FFE73CE6DB66DC66DF673CE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000 +09C7:000000000000F0002000400040008000800080008000E0006000000000000000 +09C8:800060001000F0002000400040008000800080008000E0006000000000000000 +09C9:00007FFE73CE6DB66DC66DF673CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +09CA:00007FFE73CE6DB66DC66DF673CE7FFE7FFE71866FB66F866FB671B67FFE0000 +09CB:000000000000F00B2006400240028002800280028002E0026002000000000000 +09CC:010000FC0002F00B2006400240028002800280028002E0026002000000000000 +09CD:0000000000000000000000000000000000000000000000000000006000100008 +09CE:000000000000000000000380044005800400030000E000100010000000000000 +09CF:00007FFE73CE6DB66DC66DF673CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +09D0:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000 +09D1:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000 +09D2:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DF66D866DBE63867FFE0000 +09D3:00007FFE73CE6DB66DC66DF673CE7FFE7FFE638E6DF66DC66DF6638E7FFE0000 +09D4:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63B66DB66D866DF663F67FFE0000 +09D5:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DBE6D866DF663867FFE0000 +09D6:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000 +09D7:010000FC0002000B000600020002000200020002000200020002000000000000 +09D8:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000 +09D9:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000 +09DA:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DB66D866DB663B67FFE0000 +09DB:00007FFE73CE6DB66DC66DF673CE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +09DC:000000000000FFFF0040004008580868080804080408021001E0000000C000C0 +09DD:000000000000FFFF040004000400040004300430042004C00700006000600000 +09DE:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DBE6D8E6DBE63867FFE0000 +09DF:000000000000FFFF080804080208010802080C08038800680318030000000000 +09E0:000000000000002F102824281A6801A806681838062801A80268040002000100 +09E1:00000000000003000400020001C0002007100890085004600090000800680098 +09E2:000000000000000000000000000000000000000000000000000800040034004C +09E3:000000000000000000000000000000060001000300050000000800040034004C +09E4:00007FFE73CE6DB66DC66DF673CE7FFE7FFE61B66FB663866FF661F67FFE0000 +09E5:00007FFE73CE6DB66DC66DF673CE7FFE7FFE61866FBE63866FF661867FFE0000 +09E6:000000000000000003C0042008100810081008100810042003C0000000000000 +09E7:0000000000000000080006000180006000100008000806700780000000000000 +09E8:0000000000000000030000C000200010001000600780030000C0002000100000 +09E9:000000000000000000E01110120812C811C808080808041003E0000000000000 +09EA:000000000000000003C004200420042003C0042008100810042003C000000000 +09EB:00000000000000000300048008400880088008800850042003C0000000000000 +09EC:00000000000000000040004008400858086804080408021001E0000000000000 +09ED:000000000000000007C008200820086007A00020002000200020000000000000 +09EE:00000000000000000800080008100BE00C800880088009000600000000000000 +09EF:000000000000020004000400020001C000200710089008500460000000000000 +09F0:000000000000FFFF00180068018806C818280618018800680018000000000000 +09F1:000000000000FFFF00180068018806081808060801880C680218010000000000 +09F2:0000000000000000000000000600018000400020001000000000000000000000 +09F3:00000000000006000900010003F00100016001500110012000C0000000000000 +09F4:0000000000000000000000000000001000200040018006000000000000000000 +09F5:00000000000000000000000000000000070808900CA001400380000000000000 +09F6:000000000000000800080F080C880090009001100E2008400780000000000000 +09F7:0000000000000000008000800080008000800080008000800080000000000000 +09F8:00000000000008000800081008300850089009100A100C100810001000080000 +09F9:00000000000000000000000001C00220041004100410022001C0000000000000 +09FA:0000000000000000000000080008000809900990042003C00000000000000000 +09FB:0000000000000000000000000180020002000100008000400020000000000000 +09FC:0000000000000000000000000010019001A00820044003800020001000080000 +09FD:0000000000000000000000000180024002400180000000000000000000000000 +09FE:0300008003C00020000000000000000000000000000000000000000000000000 +09FF:00007FFE73CE6DB66DC66DF673CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +0A00:00007FFE73866DB66D866DB673B67FFE7FFE73CE6DB66DB66DB673CE7FFE0000 +0A01:02A0022001C00000000000000000000000000000000000000000000000000000 +0A02:0180018000000000000000000000000000000000000000000000000000000000 +0A03:0000000000000000000000000002000500020000000200050002000000000000 +0A04:00007FFE73866DB66D866DB673B67FFE7FFE73B66DB66D866DF673F67FFE0000 +0A05:0000000000000000C00720041304149C386430C420C400840004000000000000 +0A06:0000000000000000C03F20241024166439A03320232002200020000000000000 +0A07:3C00420042004000FFFF44044404420441FC42004400420441F8000000000000 +0A08:0078008400840004FFFE4044404420441FC42004400420441F84000000000000 +0A09:07C0082010102008FFFF2008200820103FE010100810042003C00000081007E0 +0A0A:07C0082010102008FFFF200820103FE010100810042003C0081007E0081007E0 +0A0B:00007FFE73866DB66D866DB673B67FFE7FFE738E6DB66D8E6DB6738E7FFE0000 +0A0C:00007FFE73866DB66D866DB673B67FFE7FFE73C66DBE6DBE6DBE73C67FFE0000 +0A0D:00007FFE73866DB66D866DB673B67FFE7FFE738E6DB66DB66DB6738E7FFE0000 +0A0E:00007FFE73866DB66D866DB673B67FFE7FFE73866DBE6D8E6DBE73867FFE0000 +0A0F:00C0002000100010FFFF10101010081007F008001000080007F0000000000000 +0A10:00F0000800F4000CC01F20041304149C386430C420C400840004000400000000 +0A11:00007FFE73866DB66D866DB673B67FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000 +0A12:00007FFE73866DB66D866DB673B67FFE7FFE7B8673F67B867BBE71867FFE0000 +0A13:07F0080010002000FFFF2008200820103FE010100810042003C0000000000000 +0A14:020001F000480048C01F20041304149C386430C420C400840004000400000000 +0A15:0000000000000000FFFF001000100F1010A020602060209011100E1000000000 +0A16:0000000000000000F01F101008100FF01010201010300FD00010001000000000 +0A17:0000000000000000FFFF0090009000901F902090209010900910061000000000 +0A18:0000000000000000F11F1110091009101110211011300ED00010000000000000 +0A19:0000000000000000FFFF100010001FC0002003A0044004A00310000000000000 +0A1A:0000000000000000FFFF0020002018201FE008200820042003C0000000000000 +0A1B:0000000000000000FFFF001000101FF020001FF0210821081FF0000000000000 +0A1C:0000000000000000FFFF0010001018101FF00810081008100810000000000000 +0A1D:0000000000000000FFFF0C3002400FE01010260807F001000080004000000000 +0A1E:0000000000000000FFFF201020101FF0200020001FF0040003F0000000000000 +0A1F:0000000000000000FFFF0040004001C0020004000800041003E0000000000000 +0A20:0000000000000000FFFF0100010002800440082010101010082007C000000000 +0A21:0000000000000000FFFF0008000803F0001000101F08208810700FC000000000 +0A22:0000000000000000FFFF0010001018101FF00800080009E00A10042003C00000 +0A23:0000000000000000FFFF010000C000600F5010C020001010082007C000000000 +0A24:0000000000000000FFFF0010001007A007E00030201030100C2003C000000000 +0A25:0000000000000000FFFF101008100FF0101030100C3003D00010001000000000 +0A26:0000000000000000FFFF0020002030203FE0100010000800041003E000000000 +0A27:0000000000000000FFFF08100410041008101010081006700190001000000000 +0A28:0000000000000000FFFF01000100028004400820101010100820000000000000 +0A29:00007FFE73866DB66D866DB673B67FFE7FFE61CE7DB661C66FF661CE7FFE0000 +0A2A:0000000000000000F81F08100410041008101010081006700190001000000000 +0A2B:0000000000000000FFFF001000101FF02000200021E012100C2003C000000000 +0A2C:0000000000000000FFFF0810041007F008101010081006700190001000000000 +0A2D:0000000000000000FFFF0010001003D0043003C800081010082007C000000000 +0A2E:0000000000000000F01F0810081008100FF01810181000100190019000000000 +0A2F:0000000000000000FFFF08100410041008F01090089004900390001000000000 +0A30:0000000000000000FFFF0010001007F00810081008100410021001E000000000 +0A31:00007FFE73866DB66D866DB673B67FFE7FFE63EE7DCE71EE7DEE63C67FFE0000 +0A32:0000000000000000FFFF0820082004400AA01110101008200440000000000000 +0A33:0000000000000000FFFF0820082004400AA0111010100820044C000C00000000 +0A34:00007FFE73866DB66D866DB673B67FFE7FFE63B67DB671867DF663F67FFE0000 +0A35:0000000000000000FFFF001000101FF0200030000FF0040003E0000000000000 +0A36:0000000000000000FFFF0810081008100FF01810181000100190019000000000 +0A37:00007FFE73866DB66D866DB673B67FFE7FFE63867DF671EE7DDE63DE7FFE0000 +0A38:0000000000000000FFFF0810081008100FF01810181000100010001000000000 +0A39:0000000000000000FFFF0010001007100810081008100410021001E000000000 +0A3A:00007FFE73866DB66D866DB673B67FFE7FFE63867DB671867DB663B67FFE0000 +0A3B:00007FFE73866DB66D866DB673B67FFE7FFE638E7DB6718E7DB6638E7FFE0000 +0A3C:0000000000000000000000000000000000000000000000000000000001800180 +0A3D:00007FFE73866DB66D866DB673B67FFE7FFE638E7DB671B67DB6638E7FFE0000 +0A3E:0000000000000000001F00040004000400040004000000000000000000000000 +0A3F:7800840084008400E00080008000800080008000800080008000800080000000 +0A40:0078008400840084001F00040004000400040004000400040004000400040000 +0A41:0000000000000000000000000000000000000000000000000000082007C00000 +0A42:000000000000000000000000000000000000000000000000082007C0082007C0 +0A43:00007FFE73866DB66D866DB673B67FFE7FFE6D8E6DF661C67DF67D8E7FFE0000 +0A44:00007FFE73866DB66D866DB673B67FFE7FFE6DB66DB661867DF67DF67FFE0000 +0A45:00007FFE73866DB66D866DB673B67FFE7FFE6D866DBE61867DF67D867FFE0000 +0A46:00007FFE73866DB66D866DB673B67FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000 +0A47:000000E000100008000000000000000000000000000000000000000000000000 +0A48:01E0001000F80008000000000000000000000000000000000000000000000000 +0A49:00007FFE73866DB66D866DB673B67FFE7FFE6DCE6DB661C67DF67DCE7FFE0000 +0A4A:00007FFE73866DB66D866DB673B67FFE7FFE6D866DB661867DB67DB67FFE0000 +0A4B:020001F000080008000000000000000000000000000000000000000000000000 +0A4C:020001F000480048000000000000000000000000000000000000000000000000 +0A4D:0000000000000000000000000000000000000000000000000000001800040002 +0A4E:00007FFE73866DB66D866DB673B67FFE7FFE6D866DBE618E7DBE7D867FFE0000 +0A4F:00007FFE73866DB66D866DB673B67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000 +0A50:00007FFE73866DB66D866DB673B67FFE7FFE61CE6FB661B67DB661CE7FFE0000 +0A51:0000000000000000000000000000000000000000000000000000080006000180 +0A52:00007FFE73866DB66D866DB673B67FFE7FFE61866FF661867DBE61867FFE0000 +0A53:00007FFE73866DB66D866DB673B67FFE7FFE618E6FF661C67DF6618E7FFE0000 +0A54:00007FFE73866DB66D866DB673B67FFE7FFE61B66FB661867DF661F67FFE0000 +0A55:00007FFE73866DB66D866DB673B67FFE7FFE61866FBE61867DF661867FFE0000 +0A56:00007FFE73866DB66D866DB673B67FFE7FFE61CE6FBE618E7DB661CE7FFE0000 +0A57:00007FFE73866DB66D866DB673B67FFE7FFE61866FF661EE7DDE61DE7FFE0000 +0A58:00007FFE73866DB66D866DB673B67FFE7FFE61CE6FB661CE7DB661CE7FFE0000 +0A59:0000000000000000F81F0810041007F008101010081006700190181018000000 +0A5A:0000000000000000FFFF009000900F9010901090109008900490031018001800 +0A5B:0000000000000000FFFF0010001018101FF00810081008100810099001800000 +0A5C:0000000000000000FFFF00200020002007E0001000101020084007C004200210 +0A5D:00007FFE73866DB66D866DB673B67FFE7FFE618E6FB661B67DB6618E7FFE0000 +0A5E:0000000000000000FFFF001000101FF02000200021E012100C2063C060000000 +0A5F:00007FFE73866DB66D866DB673B67FFE7FFE61866FBE618E7DBE61BE7FFE0000 +0A60:00007FFE73866DB66D866DB673B67FFE7FFE73CE6FB663B66DB673CE7FFE0000 +0A61:00007FFE73866DB66D866DB673B67FFE7FFE73EE6FCE63EE6DEE73C67FFE0000 +0A62:00007FFE73866DB66D866DB673B67FFE7FFE73866FF663866DBE73867FFE0000 +0A63:00007FFE73866DB66D866DB673B67FFE7FFE738E6FF663C66DF6738E7FFE0000 +0A64:00007FFE73866DB66D866DB673B67FFE7FFE73B66FB663866DF673F67FFE0000 +0A65:00007FFE73866DB66D866DB673B67FFE7FFE73866FBE63866DF673867FFE0000 +0A66:0000000000000000078008401020201020102010102008400780000000000000 +0A67:000000000000000007000880084008C007400040004000400040003000000000 +0A68:000000000000000007C000200010001000200FC0004000200010000000000000 +0A69:00000000000000000F800040002000401F800040002030403F80080004000200 +0A6A:0000000000000000044008200820044003800440082008200440038000000000 +0A6B:0000000000000000103C1020082008201020202010200CE00320002000000000 +0A6C:00E00100010000C003F004300800040003F004000800040803F0000000000000 +0A6D:000000000000000003C004200810081006100020004000800300040000000000 +0A6E:00000000000030003FF0100010001000100010000800040003F0000000000000 +0A6F:00600080008030603FF0103010001000100010000800040003F0000000000000 +0A70:03C0042002400000000000000000000000000000000000000000000000000000 +0A71:0420042003C00000000000000000000000000000000000000000000000000000 +0A72:0000000000000000FFFF10101010081007F0080010000810042003C000000000 +0A73:07E0081010082008FFFF2008200820103FE010100810042003C0000000000000 +0A74:00000000180424F8250C1D920B421482280C280228022404120809F000000000 +0A75:0000000000000000000000000000000000000000000000000200020002400180 +0A76:0000000000000000000000000100038007C00380010000000000000000000000 +0A77:00007FFE73866DB66D866DB673B67FFE7FFE61867DF67BEE77DE77DE7FFE0000 +0A78:00007FFE73866DB66D866DB673B67FFE7FFE61CE7DB67BCE77B677CE7FFE0000 +0A79:00007FFE73866DB66D866DB673B67FFE7FFE61CE7DB67BC677F677CE7FFE0000 +0A7A:00007FFE73866DB66D866DB673B67FFE7FFE61867DB67B8677B677B67FFE0000 +0A7B:00007FFE73866DB66D866DB673B67FFE7FFE618E7DB67B8E77B6778E7FFE0000 +0A7C:00007FFE73866DB66D866DB673B67FFE7FFE61C67DBE7BBE77BE77C67FFE0000 +0A7D:00007FFE73866DB66D866DB673B67FFE7FFE618E7DB67BB677B6778E7FFE0000 +0A7E:00007FFE73866DB66D866DB673B67FFE7FFE61867DBE7B8E77BE77867FFE0000 +0A7F:00007FFE73866DB66D866DB673B67FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +0A80:00007FFE73866DB66D866DB673B67FFE7FFE73CE6DB673B66DB673CE7FFE0000 +0A81:02A0022001C00000000000000000000000000000000000000000000000000000 +0A82:0180018000000000000000000000000000000000000000000000000000000000 +0A83:0000000000000000000000000003000300000000000300030000000000000000 +0A84:00007FFE73866DB66D866DB673B67FFE7FFE73B66DB673866DF673F67FFE0000 +0A85:000000000000000078080408048838F810480888070A00040000000000000000 +0A86:0000000000000000F0220822092271E220A211220E2A00110000000000000000 +0A87:000000180020002003A004200420042003200420044003800000000000000000 +0A88:0000003000480048074008400840084006400840088007000000000000000000 +0A89:000003C00420081009C008200820082008C00420022001C00000000000000000 +0A8A:00000F0010802040272020902090209023101090089407080000000000000000 +0A8B:0000000000000000391005280328011803E40502094210840000000000000000 +0A8C:000000000000000000200F7010882084201810200C20001C0000000000000000 +0A8D:004000200018000078080408048838F810480888070A00040000000000000000 +0A8E:00007FFE73866DB66D866DB673B67FFE7FFE73866DBE738E6DBE73867FFE0000 +0A8F:000000600010000878080408048838F810480888070A00040000000000000000 +0A90:00E0001800F8000878080408048838F810480888070A00040000000000000000 +0A91:0010000800060000F0220822092271E220A211220E2A00110000000000000000 +0A92:00007FFE73866DB66D866DB673B67FFE7FFE73866DF671867DBE73867FFE0000 +0A93:0000001800040002F0220822092271E220A211220E2A00110000000000000000 +0A94:00380006003E0002F0220822092271E220A211220E2A00110000000000000000 +0A95:0000000000000000018002000240018001800240084007800000000000000000 +0A96:000000000000000020405040124013C00C400040005000200000000000000000 +0A97:00000000000000000C2012200120012012200C20002800100000000000000000 +0A98:0000000000000000039004100410041003100430045403880000000000000000 +0A99:000000000000000001000100026004600200210011000E000000000000000000 +0A9A:00000000000000003C10021002101C1008300450039400080000000000000000 +0A9B:00000000000000001CC021202120212018A0204020801F000000000000000000 +0A9C:00000000000000000E10112028C0488049403120012000C00000000000000000 +0A9D:00000000000000000C401240014001E012100C10001000600000000000000000 +0A9E:00000000000000000C201220012001E012200C20002800100000000000000000 +0A9F:0000000000000000380004000400180020004000440038000000000000000000 +0AA0:0000000000000000018002000200010007000880088007000000000000000000 +0AA1:000000000000000001000100020004000200210011000E000000000000000000 +0AA2:00000000000000001C0002000C0010C02120212010C00F800000000000000000 +0AA3:00000000000000004C4052404140414052404C40405040202000100008001000 +0AA4:00000000000000000040004003C0044008400840045002200000000000000000 +0AA5:00000000000000000C4012400A40044008C00740005000200000000000000000 +0AA6:0000000000000000038004000400040003000400044003800000000000000000 +0AA7:00000600080008000640084008C0074000400040005000200000000000000000 +0AA8:00000000000000000080008000801F801880008000A000400000000000000000 +0AA9:00007FFE73866DB66D866DB673B67FFE7FFE61CE6DB661C66DF66DCE7FFE0000 +0AAA:000000000000000010402840084008C007400040005000200000000000000000 +0AAB:000000000000000001800200024001800180024018401F800400020001800000 +0AAC:000000000000000008081008208820F811080E08000A00040000000000000000 +0AAD:000000000000000007080888108810F810080808040A00040000000000000000 +0AAE:00000000000000000C200220022003E000200020002800100000000000000000 +0AAF:00000000000000000C20022004200820046003A0002800100000000000000000 +0AB0:00000000000000001E00010001000E000400020001C000000000000000000000 +0AB1:00007FFE73866DB66D866DB673B67FFE7FFE63EE6DCE63EE6DEE63C67FFE0000 +0AB2:00000000000000000C80108020802780208010800CA000400000000000000000 +0AB3:0000000000000000000021802240224022401C40004000500020000000000000 +0AB4:00007FFE73866DB66D866DB673B67FFE7FFE63B66DB663866DF663F67FFE0000 +0AB5:00000000000000000000074008C0084008C00740004000500020000000000000 +0AB6:00000000000000000C20122012200C2004201820082807100000000000000000 +0AB7:00000000000000000C400A40094008C007400040005000200000000000000000 +0AB8:00000000000000003C20022003E01C2008200420032800100000000000000000 +0AB9:000000000000000021002200210020802480232010200FC00000000000000000 +0ABA:00007FFE73866DB66D866DB673B67FFE7FFE63866DB663866DB663B67FFE0000 +0ABB:00007FFE73866DB66D866DB673B67FFE7FFE638E6DB6638E6DB6638E7FFE0000 +0ABC:0000000000000000000000000000000000000000000000000000000001800180 +0ABD:0000000000000000380040004000300008000400440038000000000000000000 +0ABE:0000000000000000000400040004000400040004000500020000000000000000 +0ABF:6000900088008000800080008000800080008000A00040000000000000000000 +0AC0:0018002400240004000400040004000400040004000500020000000000000000 +0AC1:00000000000000000000000000000000000000000000000000000260011000E0 +0AC2:000000000000000000000000000000000000000000000000000001C002200190 +0AC3:000000000000000000000000000000000000000000000000000001C0020001C0 +0AC4:00000000000000000000000000000000000000000000018002000180020001C0 +0AC5:0010000800060000000000000000000000000000000000000000000000000000 +0AC6:00007FFE73866DB66D866DB673B67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000 +0AC7:0000001800040002000000000000000000000000000000000000000000000000 +0AC8:00380006003E0002000000000000000000000000000000000000000000000000 +0AC9:00200010000C0000000400040004000400040004000500020000000000000000 +0ACA:00007FFE73866DB66D866DB673B67FFE7FFE71866FB66F866FB671B67FFE0000 +0ACB:0030000800040004000400040004000400040004000500020000000000000000 +0ACC:003800040034000C000400040004000400040004000500020000000000000000 +0ACD:000000000000000000000000000000000000000000000000000001C000200010 +0ACE:00007FFE73866DB66D866DB673B67FFE7FFE71866FBE6F8E6FBE71867FFE0000 +0ACF:00007FFE73866DB66D866DB673B67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +0AD0:00300030000000843C780200020C0C121832044C438042003C00000000000000 +0AD1:00007FFE73866DB66D866DB673B67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000 +0AD2:00007FFE73866DB66D866DB673B67FFE7FFE63866DF66D866DBE63867FFE0000 +0AD3:00007FFE73866DB66D866DB673B67FFE7FFE638E6DF66DC66DF6638E7FFE0000 +0AD4:00007FFE73866DB66D866DB673B67FFE7FFE63B66DB66D866DF663F67FFE0000 +0AD5:00007FFE73866DB66D866DB673B67FFE7FFE63866DBE6D866DF663867FFE0000 +0AD6:00007FFE73866DB66D866DB673B67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000 +0AD7:00007FFE73866DB66D866DB673B67FFE7FFE63866DF66DEE6DDE63DE7FFE0000 +0AD8:00007FFE73866DB66D866DB673B67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000 +0AD9:00007FFE73866DB66D866DB673B67FFE7FFE63CE6DB66DC66DF663CE7FFE0000 +0ADA:00007FFE73866DB66D866DB673B67FFE7FFE63866DB66D866DB663B67FFE0000 +0ADB:00007FFE73866DB66D866DB673B67FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +0ADC:00007FFE73866DB66D866DB673B67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +0ADD:00007FFE73866DB66D866DB673B67FFE7FFE638E6DB66DB66DB6638E7FFE0000 +0ADE:00007FFE73866DB66D866DB673B67FFE7FFE63866DBE6D8E6DBE63867FFE0000 +0ADF:00007FFE73866DB66D866DB673B67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +0AE0:000000000000000072200A500650023007DC0A101292210C0000000000000000 +0AE1:000000000000000000200F7010882084201810200C20001C00200020001C0000 +0AE2:0000000000000000000000000000000000000000000000000360049004200018 +0AE3:00000000000000000000000000000000000000000000036004900424001A000C +0AE4:00007FFE73866DB66D866DB673B67FFE7FFE61B66FB663866FF661F67FFE0000 +0AE5:00007FFE73866DB66D866DB673B67FFE7FFE61866FBE63866FF661867FFE0000 +0AE6:0000000000000000078008401020201020102010102008400780000000000000 +0AE7:000000000000000007000880084008C007400040004000400040003000000000 +0AE8:000000000000000007C00020001000100C200FC00200010000C0000000000000 +0AE9:000000000000000001C000200010002003C010200810042003C0000000000000 +0AEA:00000000000000001C080210012000C000C0012002200220022001C000000000 +0AEB:000000000000000010402840084008C007400040005000200000000000000000 +0AEC:0000000000000000070008001000080007E004000800040003F0000800080070 +0AED:000000000000000003C0046008900910061020102010202010400F8000000000 +0AEE:0000000000000080010002000400080010001000100008400780000000000000 +0AEF:000000000000000008001040208021002200200010000F800000000000000000 +0AF0:0000000000000000000000000000000018002400240018000000000000000000 +0AF1:00000000000000000C000200010002001C1C0222012232223C1C080004000300 +0AF2:00007FFE73866DB66D866DB673B67FFE7FFE61866FF663866FBE6F867FFE0000 +0AF3:00007FFE73866DB66D866DB673B67FFE7FFE618E6FF663C66FF66F8E7FFE0000 +0AF4:00007FFE73866DB66D866DB673B67FFE7FFE61B66FB663866FF66FF67FFE0000 +0AF5:00007FFE73866DB66D866DB673B67FFE7FFE61866FBE63866FF66F867FFE0000 +0AF6:00007FFE73866DB66D866DB673B67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +0AF7:00007FFE73866DB66D866DB673B67FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +0AF8:00007FFE73866DB66D866DB673B67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +0AF9:00000000000000001F82284424282430185000900510112004C0000000000000 +0AFA:00C0002000200040000000000000000000000000000000000000000000000000 +0AFB:0888088807700000000000000000000000000000000000000000000000000000 +0AFC:000C013001C00700000000000000000000000000000000000000000000000000 +0AFD:018001800C300C30000000000000000000000000000000000000000000000000 +0AFE:0180024002400180000000000000000000000000000000000000000000000000 +0AFF:0630094809480630000000000000000000000000000000000000000000000000 +0B00:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73CE6DB66DB66DB673CE7FFE0000 +0B01:02A0022001C00000000000000000000000000000000000000000000000000000 +0B02:0002000500020000000000000000000000000000000000000000000000000000 +0B03:0000000000000000000000020005000500020005000500020000000000000000 +0B04:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73B66DB66D866DF673F67FFE0000 +0B05:0000000000000000361049104910221004100810083007D00000000000000000 +0B06:0000000000000000361449144914221404140414023401D40000000000000000 +0B07:00000000000000000F803040402040204A20354015400A200000000000000000 +0B08:0000000000000000038004403E2040204A20354015400A200000000000000000 +0B09:00000000000000000F803040402041205220264022401C200000000000000000 +0B0A:00000000000000000F803040404041405220261022201C100000000000000000 +0B0B:000000000000000007001880208020802C40122012400C200000000000000000 +0B0C:00000000000000000000038004400180020004C0052003C00000000000000000 +0B0D:00007FFE738E6DB66D8E6DB6738E7FFE7FFE738E6DB66DB66DB6738E7FFE0000 +0B0E:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73866DBE6D8E6DBE73867FFE0000 +0B0F:0000000000000000020006000A004200220012000A0006000000000000000000 +0B10:000001E00210001001200320052021E011200920052003200000000000000000 +0B11:00007FFE738E6DB66D8E6DB6738E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000 +0B12:00007FFE738E6DB66D8E6DB6738E7FFE7FFE7B8673F67B867BBE71867FFE0000 +0B13:000000000000000004C009200820082008C00420022001C00000000000000000 +0B14:000000F00108000813102490209020F023101090089007100000000000000000 +0B15:00000000000000000FC03020401040104980364016400A400000000000000000 +0B16:000000000000000003900510093008D008100710049003100000000000000000 +0B17:0000000000000000039004500830081008100710049003100000000000000000 +0B18:00000000000000000390045008300A100C10111011300ED00000000000000000 +0B19:00000000000000000F003080407041485230260022001C000000000000000000 +0B1A:000000000000000003C004200810081008100720048003000000000000000000 +0B1B:000000000000000003C0042008100B10048017000A8005000000000000000000 +0B1C:000000000000000003C00420081008000A6004A004A003200000000000000000 +0B1D:000000000000000003A00490091010E016000900098006400000000000000000 +0B1E:00000000000000001360249020101FE01360249020101FE00000000000000000 +0B1F:0000000000000000039004500830081008000700048003000000000000000000 +0B20:0000000000000000000007000880104010401040088007000000000000000000 +0B21:000000000000000003C00C2010101050149009A0088007000000000000000000 +0B22:000000000000000003C00C2010101010141009200A8007000200010000000000 +0B23:0000000000000000039004500A3011101C10021002100C100000000000000000 +0B24:00000000000000000F803040402040205340230023001C000000000000000000 +0B25:00000000000000000610091001100E1010101010083007D00000000000000000 +0B26:00000000000000000F803040402041205300230023001D000000000000000000 +0B27:0000000000000000001004100210031004900410043003D00000000000000000 +0B28:00000000000000000F80104020202020272019400D000D000000000000000000 +0B29:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE7DB661C66FF661CE7FFE0000 +0B2A:000000000000000007900850103012100C100810083007D00000000000000000 +0B2B:00000000000000001CB022C841C848B03080208021801E800000000000000000 +0B2C:00000000000000000780184020202E203120110011800E800000000000000000 +0B2D:00000000000000000F803040402045205520234021401E200000000000000000 +0B2E:000000000000000007900850103012100C101010601060100010000000000000 +0B2F:000000000000000007900850103012100C101810683067D00000000000000000 +0B30:000000000000000003C00420081008100810072004A003100000000000000000 +0B31:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000 +0B32:00000000000000001FC02020401040105B1024A024A024900000000000000000 +0B33:00000000000000001FC02020401040105B202480248024800000000000000000 +0B34:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63B67DB671867DF663F67FFE0000 +0B35:00000000000000000780184020202E203120150011800E800000000000000000 +0B36:0000000000000000079008500C30121010100E10091006100000000000000000 +0B37:000000000000000007900C50123013100C900850083007D00000000000000000 +0B38:00000000000000000F9010502030211026101E10019000700000000000000000 +0B39:00000000000000000F803040402041205300230023001D000800060001800000 +0B3A:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63867DB671867DB663B67FFE0000 +0B3B:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E7DB6718E7DB6638E7FFE0000 +0B3C:0000000000000000000000000000000000000000000000000000000001800180 +0B3D:00000000000000000C003000400030000C003000400030000C00000000000000 +0B3E:0000000000000000000800080008000800080008000800080008000000000000 +0B3F:07F0080808080000000000000000000000000000000000000000000000000000 +0B40:0000000000000000000800180028000800080008000800080008000000000000 +0B41:000000000000000000000000000000000000000000000000002007A008C007B0 +0B42:00000000000000000000000000000000000000000000000003000400044003B0 +0B43:000000000000000000000000000000000000000000000000024004A0042003C0 +0B44:000000000000000000000000000000000000000000000400084006A0082007C0 +0B45:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6D866DBE61867DF67D867FFE0000 +0B46:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000 +0B47:00000000000000006000800080008000E0009000900090006000000000000000 +0B48:010000F8000400046000800080008000E0009000900090006000000000000000 +0B49:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000 +0B4A:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6D866DB661867DB67DB67FFE0000 +0B4B:00000000000000006008800880088008E0089008900890086008000000000000 +0B4C:00000078008400046008800880088008E0089008900890086008000000000000 +0B4D:0000000000000000000000000000000000000000000000000000008000400020 +0B4E:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6D866DBE618E7DBE7D867FFE0000 +0B4F:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000 +0B50:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6FB661B67DB661CE7FFE0000 +0B51:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000 +0B52:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FF661867DBE61867FFE0000 +0B53:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6FF661C67DF6618E7FFE0000 +0B54:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61B66FB661867DF661F67FFE0000 +0B55:00000FF000000000000000000000000000000000000000000000000000000000 +0B56:010000F800040004000000000000000000000000000000000000000000000000 +0B57:0000007800840004000800080008000800080008000800080008000000000000 +0B58:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6FB661CE7DB661CE7FFE0000 +0B59:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6FB661C67DF661CE7FFE0000 +0B5A:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FB661867DB661B67FFE0000 +0B5B:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6FB6618E7DB6618E7FFE0000 +0B5C:000000000000000003C00C2010101050149009A0088007000000030003000000 +0B5D:000000000000000003C00C2010101010141009200A800700020001000C000C00 +0B5E:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FBE618E7DBE61867FFE0000 +0B5F:000000000000000007900850103012100C1018306848679C0000000000000000 +0B60:00000000000000000780184020C020202CC0122012C00C200010000000000000 +0B61:00000000000000000000038004400180020004C0052003C00080004000200000 +0B62:00000000000000000000000000000000000000000080014001400098012400F8 +0B63:000000000000000000000000000000000000000000800140015800A4013800D0 +0B64:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73B66FB663866DF673F67FFE0000 +0B65:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73866FBE63866DF673867FFE0000 +0B66:0000000000000000000000000380044010101010101004400380000000000000 +0B67:000000000000000003C004200A100A1009E004000200010000C0002000000000 +0B68:000000000000000003C004200850085007900020004000800300040000000000 +0B69:00000000000000000EE011102110291025101910011001100000000000000000 +0B6A:000000000000000004080210012000C000C0012002200220022001C000000000 +0B6B:000000000000000001C012200A20064001800260045004480380000000000000 +0B6C:000000000000000003C004200310009008900720004000800300040000000000 +0B6D:000000000000000003C0042009100A900A900720004000800300040000000000 +0B6E:0000000000000FE0080008000800080008000800080008000800000000000000 +0B6F:0000000000000000072008A00860080008000800040003000000000000000000 +0B70:0000000000000000001000200C400C8041002200140008000000000000000000 +0B71:000000000000000009E0121010E0081007F00810083007D00000000000000000 +0B72:0000000000000000008000800080008000800080008000800000000000000000 +0B73:0000000000000000088008800880098006800080008000800000000000000000 +0B74:0000000000000000222022202220266019A00020002000200000000000000000 +0B75:0000000000000000002000400080010002000400080010000000000000000000 +0B76:000000000000000000201C402A802B0012000400080010000000000000000000 +0B77:0000000000000000000200040008001036204940498049000000000000000000 +0B78:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000 +0B79:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE7DB67BC677F677CE7FFE0000 +0B7A:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61867DB67B8677B677B67FFE0000 +0B7B:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E7DB67B8E77B6778E7FFE0000 +0B7C:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61C67DBE7BBE77BE77C67FFE0000 +0B7D:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E7DB67BB677B6778E7FFE0000 +0B7E:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61867DBE7B8E77BE77867FFE0000 +0B7F:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +0B80:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73CE6DB673B66DB673CE7FFE0000 +0B81:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000 +0B82:0100028001000000000000000000000000000000000000000000000000000000 +0B83:0000000000000000018002400240018018182424242418180000000000000000 +0B84:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73B66DB673866DF673F67FFE0000 +0B85:0000000000000000061009100990069000901FF020901F100000000000000000 +0B86:00000000000000001840244026401A4002407FE082507C500150021001E00000 +0B87:000000000F801040232024902490135008401F8022401D800000000000000000 +0B88:00000000000000001FF81080108016B016B01080108010800000000000000000 +0B89:00000000000000003C004A004900310002003C0040003FF00000000000000000 +0B8A:00000000000000007000980099F86AD00950705080007FF80000000000000000 +0B8B:00007FFE738E6DB66D8E6DB6738E7FFE7FFE738E6DB6738E6DB6738E7FFE0000 +0B8C:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73C66DBE73BE6DBE73C67FFE0000 +0B8D:00007FFE738E6DB66D8E6DB6738E7FFE7FFE738E6DB673B66DB6738E7FFE0000 +0B8E:000000000000000007FC081010101C102210221022101C100000000000000000 +0B8F:000000000000000007FC081010101C102210221022101C100020004000800000 +0B90:00000000000000003EE0711049104910311000103FE040004000421042103DE0 +0B91:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000 +0B92:00000000000000001FC020204010401071D04A504A903260020011E010400F80 +0B93:00000000000000001FC020204010401071D04A504A903260020031E048403F80 +0B94:00000000000000003C0042008100817CCDA8B568B928560010008F0082007C00 +0B95:00000000000000000FE00880088008803FE0409040903F200000000000000000 +0B96:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73CE6DBE718E7DB673CE7FFE0000 +0B97:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73866DF671EE7DDE73DE7FFE0000 +0B98:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000 +0B99:00000000000000007E1048104F1048904890411042104FF00000000000000000 +0B9A:00000000000000000FE00880088008803FE0408040803F000000000000000000 +0B9B:00007FFE738E6DB66D8E6DB6738E7FFE7FFE738E6DB6718E7DB6738E7FFE0000 +0B9C:00000000000000003EE0711049104910311000103FE0400040E0411042103C60 +0B9D:00007FFE738E6DB66D8E6DB6738E7FFE7FFE738E6DB671B67DB6738E7FFE0000 +0B9E:000000000000000027E0488090809CA0A2D0A290A2909C90801040203FC00000 +0B9F:000000000000000010001000100010001000100010001FF80000000000000000 +0BA0:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6DB661B66DB66DCE7FFE0000 +0BA1:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000 +0BA2:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866DF661866DBE6D867FFE0000 +0BA3:00000000000000003BBF44488AA8CAA8AAA8AAA8444800080000000000000000 +0BA4:00000000000000000FE00880088008803FE0409040903F10001000203FC04000 +0BA5:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866DBE61866DF66D867FFE0000 +0BA6:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000 +0BA7:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866DF661EE6DDE6DDE7FFE0000 +0BA8:00000000000000000FE0088008800880088008E008900890001000203FC04000 +0BA9:00000000000000001EFC2110429072904A904A90311000100000000000000000 +0BAA:000000000000000010201020102010201020102010201FE00000000000000000 +0BAB:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6DB6618E6DB66D8E7FFE0000 +0BAC:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000 +0BAD:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6DB661B66DB66D8E7FFE0000 +0BAE:000000000000000021C02220222022202220222022203FC00000000000000000 +0BAF:000000000000000012101210121012101210121016101BF00000000000000000 +0BB0:00000000000000000FF008400840084008400840084008400040008001000200 +0BB1:000000000000000007700888088808880888088808880888001000100FE01000 +0BB2:00000000000000001C2022104110411071104910491030E00000000000000000 +0BB3:00000000000000001CFC23104110411071104910491031100000000000000000 +0BB4:000000000000000021C02220222022202220222022203FC0020023C020801F00 +0BB5:00000000000000001C1023104090409070904890491033F00000000000000000 +0BB6:000000000000000047FC44444444444444444444444438380000000000000000 +0BB7:00000000000000001C10222841284128711049284A4833F00080010000000000 +0BB8:00000000000000001D9022484248424872484A484A4832300000000000000000 +0BB9:0000000000000000386C449282928292E292929294926792000400043FF84000 +0BBA:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DB663866DB663B67FFE0000 +0BBB:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E6DB6638E6DB6638E7FFE0000 +0BBC:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63C66DBE63BE6DBE63C67FFE0000 +0BBD:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E6DB663B66DB6638E7FFE0000 +0BBE:0000000000000000001F00120012001200120012001200120000000000000000 +0BBF:001C002200220012000200020002000200020002000200020000000000000000 +0BC0:01C0022002C00100008000000000000000000000000000000000000000000000 +0BC1:0000000000000000001E00050002000000000000000000000000000000000000 +0BC2:0000000000060009001D000B0005000100020000000000000000000000000000 +0BC3:00007FFE738E6DB66D8E6DB6738E7FFE7FFE718E6FF66FC66FF6718E7FFE0000 +0BC4:00007FFE738E6DB66D8E6DB6738E7FFE7FFE71B66FB66F866FF671F67FFE0000 +0BC5:00007FFE738E6DB66D8E6DB6738E7FFE7FFE71866FBE6F866FF671867FFE0000 +0BC6:00000000000000003000480084008400E4009400940064000000000000000000 +0BC7:000000000000000030004800B00080008000B000480030000000000000000000 +0BC8:00000000000000003D80424087408540E5409540924060000000000000000000 +0BC9:00007FFE738E6DB66D8E6DB6738E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +0BCA:0000000000000000301F481284128412E4129412941264120000000000000000 +0BCB:0000000000000000301F4812B01280128012B012481230120000000000000000 +0BCC:0000000000000000301F482A844A84CAE4AA94AA94AA644A0000000000000000 +0BCD:0300030000000000000000000000000000000000000000000000000000000000 +0BCE:00007FFE738E6DB66D8E6DB6738E7FFE7FFE71866FBE6F8E6FBE71867FFE0000 +0BCF:00007FFE738E6DB66D8E6DB6738E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +0BD0:0000000000000FF0300C400280018001E01D9025942961261AA0279E20041FF8 +0BD1:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000 +0BD2:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DF66D866DBE63867FFE0000 +0BD3:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E6DF66DC66DF6638E7FFE0000 +0BD4:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63B66DB66D866DF663F67FFE0000 +0BD5:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DBE6D866DF663867FFE0000 +0BD6:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000 +0BD7:0000000000000000001F002A004A00CA00AA00AA00AA004A0000000000000000 +0BD8:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000 +0BD9:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63CE6DB66DC66DF663CE7FFE0000 +0BDA:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DB66D866DB663B67FFE0000 +0BDB:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +0BDC:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +0BDD:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E6DB66DB66DB6638E7FFE0000 +0BDE:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DBE6D8E6DBE63867FFE0000 +0BDF:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +0BE0:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6FB663B66FB661CE7FFE0000 +0BE1:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000 +0BE2:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FF663866FBE61867FFE0000 +0BE3:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6FF663C66FF6618E7FFE0000 +0BE4:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61B66FB663866FF661F67FFE0000 +0BE5:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FBE63866FF661867FFE0000 +0BE6:0000000000000000018002400420042004200420024001800000000000000000 +0BE7:00000000000000000FE00880088008803FE0409040903F200000000000000000 +0BE8:00000000000000001C0022004100410022003C0040003FF00000000000000000 +0BE9:00000000000000003F802200220022C023202220204023FC0000000000000000 +0BEA:00000000000000000FE40884088408843FFC408040803F000000000000000000 +0BEB:000000000000000013F82220422042204220423842244224400420081FF00000 +0BEC:00000000000000000FE00880088008803FFE40A440A43F240000000000000000 +0BED:000000000000000007FC081010101C102210221022101C100000000000000000 +0BEE:0000000000000E0011101090085006503FF0405020901F100000000000000000 +0BEF:00000000000000000FC009000900091C3FE24132412A3E120000000000000000 +0BF0:000003800040002022202220222022202220222022201DC00000000000000000 +0BF1:00000000000000001BF826202220222022202220222022200000000000000000 +0BF2:00000000000000000FE00880088008803FFC409040903F780054003400040078 +0BF3:00000000000000001C0023004080408070804880490033F00000000000000000 +0BF4:007000C800AE00C021C02220222022202220222022203FC00000000000000000 +0BF5:000000003FFC40029C3AA252A154A155B152A958AA5493D4800440083FF00000 +0BF6:000000000000000010241024102410241024102410241FE4002407FC082007C0 +0BF7:00000000000000000F801200220032604A904BC84AA8324E0000000000000000 +0BF8:00000000000000003E024105808583C5E4A2949594A5633E0008001000000000 +0BF9:0E0011003C8052F04C0047E0484048404840487048484848400820101FE00000 +0BFA:0038004400F2014B01300F8011001100110011C011201120002000401F802000 +0BFB:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +0BFC:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +0BFD:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +0BFE:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FBE638E6FBE6F867FFE0000 +0BFF:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +0C00:000001800990042003C000000000000000000000000000000000000000000000 +0C01:0000000000000000000000010002000400040004000200010000000000000000 +0C02:0000000000000000000000000006000900090006000000000000000000000000 +0C03:0000000000000000000200050005000200000002000500050002000000000000 +0C04:0000018002400180000000000000000000000000000000000000000000000000 +0C05:00000000000000000C60129032482CC82008200810100FE00000000000000000 +0C06:00000000000000000C10122832282CF02010201010200FC00000000000000000 +0C07:00000000000000003B804440444000401E8021001E8000400040004000000000 +0C08:00000000000000004200240018603C9042207FE042903C600000000000000000 +0C09:00000000010001000FE0101020007FF84000406022901DE00000000000000000 +0C0A:00000000050005001F8820444008FFF88014808845403B800000000000000000 +0C0B:000000000000000064909248124822484248824892486DB00000000000000000 +0C0C:00000000000000001B0024802480011002100210022001C00000000000000000 +0C0D:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE738E6DB66DB66DB6738E7FFE0000 +0C0E:0000000000000000002000100008000800080E0813100CE00000000000000000 +0C0F:000000000000020004E008100808000800080E0813100CE00000000000000000 +0C10:00000000000000000EE011101108000800080E0813100CE00000000000000000 +0C11:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000 +0C12:00000000000000000C001200120004000800100011100EE00000000000000000 +0C13:00000600090004000C001200120004000800100011100EE00000000000000000 +0C14:00003FE001503E200C001200120004000800100011100EE00000000000000000 +0C15:0000002002400180018002400200018000400020082007C00000000000000000 +0C16:00000000000000003000480034800440042034204C4037800400000000000000 +0C17:0000000000000000088005000200050005000880088008800000000000000000 +0C18:00000000000000000000040049303088004830484C9037600400000000000000 +0C19:00000000000000000C40124013F004000800100011100EE00000000000000000 +0C1A:000000000010002001C001A0001000087808090813900C600000000000000000 +0C1B:000000000010002001C001A0001000087808090813900D600100000000000000 +0C1C:00000000000000000C40132012C004000800100011100EE00000000000000000 +0C1D:00000080210012000C901248124812481248124812E80D500040000000000000 +0C1E:00000000000000001B00248024A000F000801D0022001D000100010000000000 +0C1F:000000001000100018C02420582040104010401022101DE00000000000000000 +0C20:000000000000000010400880070008801040124010400F800000000000000000 +0C21:00000020084004800F001200210040804000406022901DE00000000000000000 +0C22:00000020084004800F001200210040804000406022901FE00200000000000000 +0C23:00000000000000000C601290210820081808203822481C300000000000000000 +0C24:0008011000A000400C6012902C6820082008200810100FE00000000000000000 +0C25:000000000000000010400880070008801240104012400F800200000000000000 +0C26:000000000000000010400880070008801040104012400D800000000000000000 +0C27:000000000000000010400880070008801040104012400F800200000000000000 +0C28:008001001A001C00038000400020001018102410222011C00000000000000000 +0C29:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE7DB661C66FF661CE7FFE0000 +0C2A:004000800900060000E000100008000800080E0813100CE00000000000000000 +0C2B:004000800900060000E000100008000800080E0813100DE00100000000000000 +0C2C:000000000000000030C04820081010082008210812900C600000000000000000 +0C2D:00000004000800D030E04820081010082008210812900C600100000000000000 +0C2E:00400080010006000730008800480048004838484CC833300000000000000000 +0C2F:004000800D0002000130008830484848484848484CC833300000000000000000 +0C30:000000000000000010400880070008801040104010400F800000000000000000 +0C31:00000000000000000C60129032882FC82008200810100FE00000000000000000 +0C32:000000000000000018C02420641058104010402020401F800000000000000000 +0C33:0008001001A001C00040182024102C1010200FC0090006000000000000000000 +0C34:000000000000000018C02520653058D04010421022201DC00000000000000000 +0C35:000000100020004001E001900008000800080E0813100CE00000000000000000 +0C36:00000040008001000780064000200E2011401380048003000000000000000000 +0C37:004000800900060000E000100008000800080E0813100CE00010000800040000 +0C38:004000800500020000E000100008000800080E08131010E00000000000000000 +0C39:040008005000200007F8022801100080008038804C8033000000000000000000 +0C3A:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63867DB671867DB663B67FFE0000 +0C3B:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE638E7DB6718E7DB6638E7FFE0000 +0C3C:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63C67DBE71BE7DBE63C67FFE0000 +0C3D:0000000000000000000007000080008003000400040003F80000000000000000 +0C3E:000000000000000000FF00050002000000000000000000000000000000000000 +0C3F:0180024001C00780000000000000000000000000000000000000000000000000 +0C40:04000980064001C0078000000000000000000000000000000000000000000000 +0C41:0000000000000000000000060001000100010001000900060000000000000000 +0C42:000000000000000000FF002500120008000400020012000C0000000000000000 +0C43:0000000000000000000000060001000100010005000B00060000000000000000 +0C44:0000000000000000001F0011000800040002000A0016000C0000000000000000 +0C45:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE6D866DBE61867DF67D867FFE0000 +0C46:0FC00020002000C0000000000000000000000000000000000000000000000000 +0C47:006000800FC0002000C000000000000000000000000000000000000000000000 +0C48:0FC00020002000C000000000000000000000000000000000000004000A000FF0 +0C49:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE6DCE6DB661C67DF67DCE7FFE0000 +0C4A:000037E008900060000000000000000000000000000000000000000000000000 +0C4B:0030004837E04850002000000000000000000000000000000000000000000000 +0C4C:00003FE004903860000000000000000000000000000000000000000000000000 +0C4D:0F0010000C0010000C0000000000000000000000000000000000000000000000 +0C4E:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE6D866DBE618E7DBE7D867FFE0000 +0C4F:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000 +0C50:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6FB661B67DB661CE7FFE0000 +0C51:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61EE6FCE61EE7DEE61C67FFE0000 +0C52:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FF661867DBE61867FFE0000 +0C53:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FF661C67DF6618E7FFE0000 +0C54:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61B66FB661867DF661F67FFE0000 +0C55:0060009000480000000000000000000000000000000000000000000000000000 +0C56:000000000000000000000000000000000000000000000000000004000A000FF0 +0C57:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FF661EE7DDE61DE7FFE0000 +0C58:010002807F90002001C001A0001000087808090813900C600000000000000000 +0C59:004000A01FE000000C40132012C004000800100011100EE00000000000000000 +0C5A:00000000000007C00820101010101FF01110111011100EE00000000000000000 +0C5B:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FB6618E7DB6618E7FFE0000 +0C5C:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61C66FBE61BE7DBE61C67FFE0000 +0C5D:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FB661B67DB6618E7FFE0000 +0C5E:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE618E7DBE61867FFE0000 +0C5F:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE618E7DBE61BE7FFE0000 +0C60:0000000000000000493EA4952492249044908490A4905B600000000000000000 +0C61:00000000000000001B3E24A524A2011002100210022001C00000000000000000 +0C62:00000000000000000000000000000000000000000000000006C0092800280010 +0C63:0000000000000000000000000000000000000000000000001B3824B400A80040 +0C64:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE73B66FB663866DF673F67FFE0000 +0C65:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE73866FBE63866DF673867FFE0000 +0C66:0000000000000000018002400420042004200420024001800000000000000000 +0C67:000000000000000003C004200810081008100810042002400000000000000000 +0C68:0000000000000000000000E0011001480088000800103FE00000000000000000 +0C69:000000000000000001E00210021000E000100210021001E00000000000000000 +0C6A:0000000000000000042008100810042003C00420042003C00000000000000000 +0C6B:00000000000000000004030400C8003000300048008807100000000000000000 +0C6C:00000000000000003800400040003F004000400020001FF80000000000000000 +0C6D:000000000000000001C002200420004003880408041003E00000000000000000 +0C6E:000000000000000010FC2080404040404040404020801F000000000000000000 +0C6F:00000000000000001FF82000400040003F004000400038000000000000000000 +0C70:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE7DB67BB677B677CE7FFE0000 +0C71:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61EE7DCE7BEE77EE77C67FFE0000 +0C72:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61867DF67B8677BE77867FFE0000 +0C73:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E7DF67BC677F6778E7FFE0000 +0C74:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61B67DB67B8677F677F67FFE0000 +0C75:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61867DBE7B8677F677867FFE0000 +0C76:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE7DBE7B8E77B677CE7FFE0000 +0C77:000000000000000001E0021024C82528142812480990042003C0000000000000 +0C78:000000000000000003C0042004200420042003C0002000100060018000000000 +0C79:0000000000000000008000800080008000800080008000800000000000000000 +0C7A:0000000000000000022002200220022001E00020002000200000000000000000 +0C7B:0000000000000000092009200920092006E00020002000200000000000000000 +0C7C:000000000000000000000000000000000000000000001FF80000000000000000 +0C7D:000000000000000007C00020002001C002000400040003F80000000000000000 +0C7E:0000000000000700008003000400030000800300040003F80000000000000000 +0C7F:0000000000000000060009001608100810101010082007C00000000000000000 +0C80:0000000000000000000000000990042003C00000000000000000000000000000 +0C81:0990042003C00000000000000000000000000000000000000000000000000000 +0C82:0000000000000000000000000006000900090006000000000000000000000000 +0C83:0000000000000000000200050005000200000002000500050002000000000000 +0C84:0000000000000000000003F0040808C8492448242444238810100FE000000000 +0C85:00000000000000000C60129032482CE82008200810100FE00000000000000000 +0C86:00000000000000000C30124832282CF02008200810100FE00000000000000000 +0C87:00000000000000003B804440444000401E8021001E8000400040004000000000 +0C88:000000000000000002000200FE603C9042607FE042203C400000000000000000 +0C89:00000000000000004620A910A910C91089108910492030C00000000000000000 +0C8A:0000000000000000461CA922A922C9228926892A492A30C40000000000000000 +0C8B:000000000080008067909088684408440844684494A463180000000000000000 +0C8C:00000000000000001B0024802480008001000110011000E00000000000000000 +0C8D:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE738E6DB673B66DB6738E7FFE0000 +0C8E:00000000000000003E000180004000202010510842883C700000000000000000 +0C8F:000000000000200010000980064000202010510842883C700000000000000000 +0C90:00000000000000001C602290410800082008510842883C700000000000000000 +0C91:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE73EE6DCE71EE7DEE73C67FFE0000 +0C92:000000000000000030004800480010202010410842883C700000000000000000 +0C93:000000001800200030004800480010202010410842883C700000000000000000 +0C94:7FE0021002107C90312048C0480010202010410842883C700000000000000000 +0C95:0000000000C000201FC0020002001FC00880104010400F800000000000000000 +0C96:00000000000000000E2011102088208401040F0412840C780000000000000000 +0C97:000000E0001000103FE004400820082008200820082008200000000000000000 +0C98:0000000007000080FF200010020860289030622027201AC00200000000000000 +0C99:000000000000000033F04C08483011002010410842883C700000000000000000 +0C9A:000000000030000860F09080904020E0404084408A4071800000000000000000 +0C9B:000000000030000860F090809040E040804084408E4075800400000000000000 +0C9C:0000000000000000318048404F80100020404220452038C00000000000000000 +0C9D:00000E0001003E001C902248224822482248224822E81D500040000000000000 +0C9E:00000000000000001B6024902490008000801D0022001D000100010000000000 +0C9F:0000000000000000102018C0242058104010401022101DE00000000000000000 +0CA0:000000000000038000401F80070008801040124010400F800000000000000000 +0CA1:000000000000038000407FC0212040E040104210251018E00000000000000000 +0CA2:000000000000038000407FC0212040E04010421027101AE00200000000000000 +0CA3:000000000000000018E025104208400820884148415030E00000000000000000 +0CA4:0000000001C000200FC00020001010D0112008D0041003E00000000000000000 +0CA5:000000000000038000401F80070008801240104012400F800200000000000000 +0CA6:000000000000038000401F80070008801040104012400D800000000000000000 +0CA7:000000000000038000401F80070008801040104012400F800200000000000000 +0CA8:0000000000E0001007E000400020001018102410222011C00000000000000000 +0CA9:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6DB661C66DF66DCE7FFE0000 +0CAA:0000000000E000101FE00000202051105008610842883C700000000000000000 +0CAB:0000000000E000101FE00000202051105008610842883D700100000000000000 +0CAC:000000000000000030C04820081010082008210812900C600000000000000000 +0CAD:000000000070000831F04840082010102008210812900D600100000000000000 +0CAE:00000000038000403F8000004090A048A048C4488A4871B00000000000000000 +0CAF:00000000000000C0002033C048908448844884488A4871B00000000000000000 +0CB0:000000000000038000401F80070008801040104010400F800000000000000000 +0CB1:00000000000000000C60129032983FF82008210812900C600000000000000000 +0CB2:000000000000000001003080484070204020402020401F800000000000000000 +0CB3:000000000060001001E03080484070204020402020401F800900060000000000 +0CB4:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63B66DB663866DF663F67FFE0000 +0CB5:0000000000000030000803F0202050105008610842883C700000000000000000 +0CB6:0000000001C000207FC030804840442024200420044003800000000000000000 +0CB7:0000000000C000200FC00000202051105008612842983C740000000000000000 +0CB8:00000000018000400F800000042000100E101110209020600000000000000000 +0CB9:0000000000E0001007E0008002A005D008880888049003600000000000000000 +0CBA:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63866DB663866DB663B67FFE0000 +0CBB:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE638E6DB6638E6DB6638E7FFE0000 +0CBC:0000000000000000000000000000000000000000000000000000000002400000 +0CBD:000000000000000003800400080004000300008010800F000000000000000000 +0CBE:000000000000001C000200010001000500090009000600000000000000000000 +0CBF:00180024001C0008003000000000000000000000000000000000000000000000 +0CC0:00180024001C0008003200050005000600040004000400040002000000000000 +0CC1:0000000000000000000000040002000100010001000900060000000000000000 +0CC2:00000000000000000000000600090009000B000B000B00080008003000000000 +0CC3:000000000000000000000000000000000000000C000200010001000D000D0006 +0CC4:00000000000000000000007E0021001500160010000C00020001000D000D0006 +0CC5:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE71866FBE6F866FF671867FFE0000 +0CC6:0018002400040FF8000000000000000000000000000000000000000000000000 +0CC7:0018002400040FF8000200050005000600040004000400040002000000000000 +0CC8:0018002400040FF8000000000000000000040002000400020001000D000D0006 +0CC9:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +0CCA:0018002400040FF80000000600090009000B000B000B00080008003000000000 +0CCB:0063009300120FE20001000700090009000B000B000B00080008003000000000 +0CCC:00FC001200E20001000100010001000500090009000600000000000000000000 +0CCD:00000003000400FE000500020000000000000000000000000000000000000000 +0CCE:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE71866FBE6F8E6FBE71867FFE0000 +0CCF:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +0CD0:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63CE6DB66DB66DB663CE7FFE0000 +0CD1:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000 +0CD2:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63866DF66D866DBE63867FFE0000 +0CD3:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE638E6DF66DC66DF6638E7FFE0000 +0CD4:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63B66DB66D866DF663F67FFE0000 +0CD5:0000000000000000000200050005000600040004000400040002000000000000 +0CD6:0000000000000000000000000000000000040002000400020001000D000D0006 +0CD7:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63866DF66DEE6DDE63DE7FFE0000 +0CD8:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000 +0CD9:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63CE6DB66DC66DF663CE7FFE0000 +0CDA:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63866DB66D866DB663B67FFE0000 +0CDB:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +0CDC:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +0CDD:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE638E6DB66DB66DB6638E7FFE0000 +0CDE:00000000000000000C60129032982C682008200811100EE00000000000000000 +0CDF:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +0CE0:00000000004000400F80620E9111711111137115999566620000000000000000 +0CE1:00000000000000001B0024802480010001400088009000600000000000000000 +0CE2:00000000000000000000000000000000000000000000000006C0092008200418 +0CE3:0000000000000000000000000000000000000000000000000D80124C1050083C +0CE4:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61B66FB663866FF661F67FFE0000 +0CE5:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE63866FF661867FFE0000 +0CE6:0000000000000000018002400420042004200420024001800000000000000000 +0CE7:000000000000000003C004200810081008100810042002400000000000000000 +0CE8:000000000000000000E00110013000D000100010001007E00000000000000000 +0CE9:00000000000000000F00128012400C400E40114810900F600000000000000000 +0CEA:0000000000000000062009100E10042003C00420042003C00000000000000000 +0CEB:000000000000000000181C24232410F807E0191022101C600000000000000000 +0CEC:000000000000100008003E00490049004600400020001FF80000000000000000 +0CED:0000000000000000018002400140008007000800080007F00000000000000000 +0CEE:00000000000000000610092011201E1010101010082007C00000000000000000 +0CEF:000000000000000007FE0800100010000FC0100010000E000000000000000000 +0CF0:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6FB663B66FB66FCE7FFE0000 +0CF1:AAAA000180001FF188200441828001018280044188201FF18000000180005555 +0CF2:AAAA000180000001800000019C702289A28822899C7000018000000180005555 +0CF3:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FF663C66FF66F8E7FFE0000 +0CF4:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61B66FB663866FF66FF67FFE0000 +0CF5:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE63866FF66F867FFE0000 +0CF6:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +0CF7:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +0CF8:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +0CF9:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +0CFA:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FB663866FB66FB67FFE0000 +0CFB:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +0CFC:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +0CFD:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FB663B66FB66F8E7FFE0000 +0CFE:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE638E6FBE6F867FFE0000 +0CFF:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +0D00:0180024002400180000000000000000000000000000000000000000000000000 +0D01:000001800990042003C000000000000000000000000000000000000000000000 +0D02:0000000000000000000000000006000900090006000000000000000000000000 +0D03:0000000000000000000200050005000200000002000500050002000000000000 +0D04:0000000000000000010009201110111011101010082007C00000000000000000 +0D05:00000000000000001E3021487C84A284BC9CA2A4A2A41C980000000000000000 +0D06:00000000000000001E32214D7C8DA295BCA5A2A5A2A51C990001003E00000000 +0D07:000000000000000018C025204210421072104A104A10321000103FE040003FE0 +0D08:000000000000000074508AA88AA88AA8CA08AA48AA30420002007C0080007C00 +0D09:00000000000000000F00128012400C4000400F8010001FC00000000000000000 +0D0A:00000000000000001C502AA82AA812A802081C4820303E000000000000000000 +0D0B:00000000000000000C6012901C701010082007C0082007C00000000000000000 +0D0C:00000000000000000C6012902128214839482548254819300000000000000000 +0D0D:00007FFE738E6DB66DB66DB6738E7FFE7FFE738E6DB66DB66DB6738E7FFE0000 +0D0E:0000000000F001087128892889285FE801280128012800C00000000000000000 +0D0F:0000000001E0021072888A888A885F9002880288028801300000000000000000 +0D10:00000000000E00117395AC55AC554AFD08150015001500080000000000000000 +0D11:00007FFE738E6DB66DB66DB6738E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000 +0D12:0000000000000000078008401020201020103C2022101C600000000000000000 +0D13:00000000000000000E181124210420842084310428A413180000000000000000 +0D14:00000000000000001C2822544254415441046224511826000000000000000000 +0D15:00000000000000000380044004401FF02448244824481B900000000000000000 +0D16:00000000000000001E0421044084404470444844488431FC0000000000000000 +0D17:000000000000000000000000187020884104410422081C700000000000000000 +0D18:00000000000000000072008A388A448A448A2FFA008200FE0000000000000000 +0D19:000000000000000018E025104208420872704A084A0832700000000000000000 +0D1A:000000000000000000080008000806080908010802083FF80000000000000000 +0D1B:00000000000000000030004800840C84128C029404543FC80000000000000000 +0D1C:00000000000000003EE041107110491030203FF040C83F300000000000000000 +0D1D:00000000000000003C245E22A522A52299228122412400D80000000000000000 +0D1E:000000000000000018C025384254429472944A944A9432600000000000000000 +0D1F:0000000000000000000007C00800080007C00020002007C00000000000000000 +0D20:000000000000000007C008201010101010101010082007C00000000000000000 +0D21:000000000000000000000C4812442244224422441244024801B0000000000000 +0D22:00000000000000000000189024A824A824A824A8049804900360000000000000 +0D23:000000000000000019B0264842484248424872484A4832500000000000000000 +0D24:00000000000000000CF013082284244424242424224411880000000000000000 +0D25:000000000000000040F04108410841084108410841087FF80000000000000000 +0D26:000000000000000007C00820102011C010201020122009C00000000000000000 +0D27:000000000000000009201110210821082108210811100EE00000000000000000 +0D28:00000000000000000EE011102108210821082108111009200000000000000000 +0D29:00000000000000000CE013102108390825082508251019200000000000000000 +0D2A:000000000000000000080008000800083808440844082FF80000000000000000 +0D2B:000000000000000000700088008800883888448844882FF80000000000000000 +0D2C:00000000000000001988264842484248424872484A4832780000000000000000 +0D2D:000000000000000007C00820102011C0120011C010200BC00000000000000000 +0D2E:000000000000000007E0091010881088110812081C081FF80000000000000000 +0D2F:000000000000000011882A44242424242444228413080CF00000000000000000 +0D30:00000000000000000F0010C020A0211021082108209010600000000000000000 +0D31:000000000000000007C008201010101010101010101008200000000000000000 +0D32:00000000000000000C081208210821083F08200820083FF80000000000000000 +0D33:00000000000000000FC01020202038C02420182000200FC010000FF000000000 +0D34:000000000000000010E011101110092007C0010011000E000000000000000000 +0D35:00000000000000001E0821084088408840884088410823F80000000000000000 +0D36:00000000000000000870108821042104211C212412240C180000000000000000 +0D37:0000000000000000031804A804C803883888448844882FF80000000000000000 +0D38:0000000000000000361049088888888888888888889048E00000000000000000 +0D39:000000000000000000E001100208020872088A0889105F200000000000000000 +0D3A:000000000000000010001000100010001000100010001FF80100010000000000 +0D3B:0080008000800080008000000000000000000000000000000000000000000000 +0D3C:000C00120012000C000000000000000000000000000000000000000000000000 +0D3D:0000001000280028004000400040004000400040004002800280010000000000 +0D3E:0000000000000000000600090001000100010001000900060000000000000000 +0D3F:0000000600090009000100010001000100010001000100010000000000000000 +0D40:0006000900070001000100010001000100010001000100010000000000000000 +0D41:00000000000000000000000600090001000200040004000A0004000000000000 +0D42:00000000000000000000000600090001000200040004000A00150011000E0000 +0D43:0000000000000000000100020004000400040002000100010001001F0021001E +0D44:000000000000000000010002000400040004000200010001000100DD012500FE +0D45:00007FFE738E6DB66DB66DB6738E7FFE7FFE6D866DBE61867DF67D867FFE0000 +0D46:00000000000000007000880088008800C800A800A80048001000000000000000 +0D47:000000000000000060009000E00080008000E000900060000000000000000000 +0D48:0000000000000000D800B400B400B40090009000D800D8000000000000000000 +0D49:00007FFE738E6DB66DB66DB6738E7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000 +0D4A:00000000000000007006880988018801C801A801A80948061000000000000000 +0D4B:000000000000000060069009E00180018001E001900960060000000000000000 +0D4C:0000000000000000700A881588158801C802A804A80048001000000000000000 +0D4D:001200210021001E000000000000000000000000000000000000000000000000 +0D4E:0000000000000180018000000000000000000000000000000000000000000000 +0D4F:00000000000000002660499050885C885288528852884C8820101FE000000000 +0D50:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB661B67DB661CE7FFE0000 +0D51:00007FFE738E6DB66DB66DB6738E7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000 +0D52:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FF661867DBE61867FFE0000 +0D53:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FF661C67DF6618E7FFE0000 +0D54:00000000000010001600090014801280110012C01C301FF80000000000000000 +0D55:00000000001011282AA024A024A024A022A013200CC000000000000000000000 +0D56:000000001800240004E04510491039200FC0110011000E000000000000000000 +0D57:0000000000000000000A00150015000100020004000000000000000000000000 +0D58:0000000000E000100A481248224822482248224812500DA00000000000000000 +0D59:00000000000000001C0022304148414847F04900490026000000000000000000 +0D5A:00000000000000000DF01248222822282228222812480AF80000000000000000 +0D5B:00000000000000007F1042084408440844084408421041E00000000000000000 +0D5C:000000000000004011202AA02AA02AA02AA02AA02AA024401000000000000000 +0D5D:000000000000001004482AA82AA82AA82AA82AA82AA851100000000000000000 +0D5E:0000000000000000180024C042A842A84F10520052004C002000000000000000 +0D5F:00000000000000000300048009404A24AA2AAA2A492404C00000000000000000 +0D60:0000000000000000186024905868400820101FE02010249020101FE000000000 +0D61:000000000000000018C025384254429472944A944A9432640004004800300000 +0D62:0000000000000000000000000000000000000000000000001EF0393825481930 +0D63:000000000000000000000000000000000000000000001EF039382548183800F0 +0D64:00007FFE738E6DB66DB66DB6738E7FFE7FFE73B66FB663866DF673F67FFE0000 +0D65:00007FFE738E6DB66DB66DB6738E7FFE7FFE73866FBE63866DF673867FFE0000 +0D66:00000000000000000000000003C004200420042003C000000000000000000000 +0D67:000000000000000000F00108010801080108010801081FF820001F0000000000 +0D68:00000000000000001E0021004080408040804080410023F80000000000000000 +0D69:00000000000000001B00248044404440444044404440247C0000000000000000 +0D6A:000000000000000006000100010007C009201120112010C00000000000000000 +0D6B:000000000000000007E008101188124812881248124808500780000000000000 +0D6C:00000000000000001B1824A44442444244424442444224420004000800100000 +0D6D:000000000000000003C004200810100810081E0811080E080010002001C00000 +0D6E:00000000000000001E0821084088408840884088410823F80008000800700000 +0D6F:00000000000000000380008000801BE024904490449024600000000000000000 +0D70:00000000000000000000024802440244024402440244024803B002003C000000 +0D71:00000000000000000EE0111021082108210811080010022001C0000000000000 +0D72:00000000000000001B84244A442A44FE4520452044A024400000000000000000 +0D73:00000000000000000000000000000FF810001C0012000C000000000000000000 +0D74:000001C0002000100FD010202050209038902490249018600000000000000000 +0D75:000000E0001000080C6812902128214839482548254819300000000000000000 +0D76:000000000000000000F001480228022872288A488B885FF80000000000000000 +0D77:0000000000000000033004CA048A049C64A894A894A89E904000000000000000 +0D78:000000000000000008BE554955455545554555455549A25F0000000000000000 +0D79:00000000000000001B802440442044FE4520452044A024400000000000000000 +0D7A:00000030004800041B742488449844A864A854A854A824900000000000000000 +0D7B:000000E0001000080C6812902128214821482148114809300000000000000000 +0D7C:000000C00020001007D008201050109010901090089004600000000000000000 +0D7D:000000E0001000081CE823104528494849484948494826300000000000000000 +0D7E:000000E00010000800681090212821482148214812480C300000000000000000 +0D7F:0000038004400020072008A008A03FF848A448A4489837000000000000000000 +0D80:00007FFE738E6DB66DB66DB6738E7FFE7FFE73CE6DB673B66DB673CE7FFE0000 +0D81:09900990042003C0000000000000000000000000000000000000000000000000 +0D82:0000000000000000000000000006000900090006000000000000000000000000 +0D83:0000000000000000000600090009000600000006000900090006000000000000 +0D84:00007FFE738E6DB66DB66DB6738E7FFE7FFE73B66DB673866DF673F67FFE0000 +0D85:0000000000000000031804A800680FF010201020082007E00020002000200020 +0D86:000000000000000018D8256403427F828102810241243F180100010001000100 +0D87:00000000000000000C4012A001BE3FC24084408420841F840084008400840083 +0D88:00000000000000000C4012A001BE3FC44088409E20821F840084008400840083 +0D89:000000000000000007C008201110129011100E60001000E00000000000000000 +0D8A:0800150009200250042007000880104010401040088007000000000000000000 +0D8B:00000000000000000180024000200FE01000101010200FC00000000000000000 +0D8C:0000000000000000062C092A00923F824012404C40803F000000000000000000 +0D8D:0000000000000000618092400A267BE9802184278A4971868001000000000000 +0D8E:00000000000000004200A500149277AD8089889B952D62120000000000000000 +0D8F:00000000000000001C382A5442424E72500A481227E410080FF0000000000000 +0D90:000000000000000071C0AAA08A36BBB5A0A9A0A19F2940463F80000000000000 +0D91:03800480038000800C8002403E2010202020202010400F800000000000000000 +0D92:03B804A403B800A00CA002603E2010202020202010400F800000000000000000 +0D93:001C0024001C00040064701289F18481B301B9018882707C0000000000000000 +0D94:0000000000003FE0401001C861A450244FC4400421081EF00000000000000000 +0D95:00007FC020203FF0401001C861A450244FC4400421081EF00000000000000000 +0D96:0000000000007F0080800E400D6CC16ABE5280428892770C0007000000000000 +0D97:00007FFE738E6DB66DB66DB6738E7FFE7FFE73866DF671EE7DDE73DE7FFE0000 +0D98:00007FFE738E6DB66DB66DB6738E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000 +0D99:00007FFE738E6DB66DB66DB6738E7FFE7FFE73CE6DB671C67DF673CE7FFE0000 +0D9A:0000000000000000600093E08C100FC8102820284448BB900000000000000000 +0D9B:00000000000000001FE020100F081088204820482C901CE00100000000000000 +0D9C:000000000000000000000000278048408E208220444038800000000000000000 +0D9D:00000000000000003080494005407D8010402020272018C00000000000000000 +0D9E:000000003F8040401C201A1002103E104010401022201DC00000000000000000 +0D9F:00000000000000001C382A4442424E725012482227C41F880000000000000000 +0DA0:000000001F0020800C4002203E2010202020202010400F800000000000000000 +0DA1:00000020004000800CB002C83E78104C2032200210040FF80000000000000000 +0DA2:00000008001000200C2002703EA810A82070202010400F800000000000000000 +0DA3:0000000000000070E088900427C2782286428182C992B66C0000000000000000 +0DA4:000000000000000039F056288404987CA680C180C944B638000800100010000C +0DA5:000000000000000038385454848299BEA1E0C240C44C38340004000800080006 +0DA6:00000004000800101D902A3842544C545038601060201FC00000000000000000 +0DA7:00000000000000001F80204000201C202020202010400F800000000000000000 +0DA8:01C0024001C0004000400020001020104010401022201DC00000000000000000 +0DA9:000000001FC020200C1002083E0810082008200811100EE00000000000000000 +0DAA:01C0024001C00040184004207C1020104010401022201DC00000000000000000 +0DAB:0000000000F801001E002600390C355239B24152820CFC000000000000000000 +0DAC:000000001FC0202007100A88108813081408180811100EE00000000000000000 +0DAD:0000000000000000600093E08C100FC8102820284048BF900000000000000000 +0DAE:01C0024001C0004010402020401040104010401020201FC00000000000000000 +0DAF:0000000000000000000000C00120002007E00400043003D00010002000200018 +0DB0:000000000FC01020201000080C0810082008200811100EE00000000000000000 +0DB1:00000000000000E0611092088C040F04108420844124BE180000000000000000 +0DB2:00007FFE738E6DB66DB66DB6738E7FFE7FFE63866DF663866DBE63867FFE0000 +0DB3:00000000000000000380054008200BE00C000C00022001C00040008000800060 +0DB4:000000000000000000000610012803680C1810040C1803E00000000000000000 +0DB5:000000E0012000E000200620011003080C0810040C1803E00000000000000000 +0DB6:00000000000000001FE020100F081088204820482C901C600000000000000000 +0DB7:00000000000000003070488805047DC41044208421081E100000000000000000 +0DB8:0000000000001FE0201001C81A281AA8162813C8081007E00000000000000000 +0DB9:0000000000001FE0201001C81B281BE817E81008099006600000000000000000 +0DBA:000000000000000000000080014001C01040202022201DC00000000000000000 +0DBB:0000010001000200040007000880104010401040088007000000000000000000 +0DBC:00007FFE738E6DB66DB66DB6738E7FFE7FFE63C66DBE63BE6DBE63C67FFE0000 +0DBD:00000000000000000F801040272022482188201010200FC00000000000000000 +0DBE:00007FFE738E6DB66DB66DB6738E7FFE7FFE63866DBE638E6DBE63867FFE0000 +0DBF:00007FFE738E6DB66DB66DB6738E7FFE7FFE63866DBE638E6DBE63BE7FFE0000 +0DC0:00000000000000001FC02020461041100F101010082007C00000000000000000 +0DC1:00000000000000000000000027C048208E10825044A038400000000000000000 +0DC2:0000000000000C4002A00EE0102023502490231010200FC00000000000000000 +0DC3:00000000000000003080494005407D801040202022201DC00000000000000000 +0DC4:00000000000000003070488805041DC41044208421081E100000000000000000 +0DC5:000000000000000006C0092008201FE0180A17F210040FF80000000000000000 +0DC6:0000000000000000000000000EE011102008200810100C600000000000000000 +0DC7:00007FFE738E6DB66DB66DB6738E7FFE7FFE71866FF66FEE6FDE71DE7FFE0000 +0DC8:00007FFE738E6DB66DB66DB6738E7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +0DC9:00007FFE738E6DB66DB66DB6738E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +0DCA:000E0009000E0008000800080008000000000000000000000000000000000000 +0DCB:00007FFE738E6DB66DB66DB6738E7FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +0DCC:00007FFE738E6DB66DB66DB6738E7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +0DCD:00007FFE738E6DB66DB66DB6738E7FFE7FFE718E6FB66FB66FB6718E7FFE0000 +0DCE:00007FFE738E6DB66DB66DB6738E7FFE7FFE71866FBE6F8E6FBE71867FFE0000 +0DCF:0000000000000000000000000006000900010001000900060000000000000000 +0DD0:0000000000000000003E00020004000400040004000400040004000300000000 +0DD1:000000000000000000000000000E000200040002000400040004000300000000 +0DD2:07F0080808080410000000000000000000000000000000000000000000000000 +0DD3:07F0084808480430000000000000000000000000000000000000000000000000 +0DD4:00000000000000000000000000000000000000000000000000000C1010100FF0 +0DD5:00007FFE738E6DB66DB66DB6738E7FFE7FFE63866DBE6D866DF663867FFE0000 +0DD6:00000000000000000000000000000000000000000000000000000C1010D00F30 +0DD7:00007FFE738E6DB66DB66DB6738E7FFE7FFE63866DF66DEE6DDE63DE7FFE0000 +0DD8:0000000000000000000000000006000900010007000900060001000000000000 +0DD9:00000000000000004000A000900090008000E000E000E0000000000000000000 +0DDA:000E0009000E00084008A008900890008000E000E000E0000000000000000000 +0DDB:00000000000000004800B400900090009000FC00FC00FC000000000000000000 +0DDC:00000000000000004000A000900690098001E001E009E0060000000000000000 +0DDD:000E0009000E00084008A008900E90098001E001E009E0060000000000000000 +0DDE:00000000000000004004A008900A900D8001E001E009E0060000000000000000 +0DDF:000000000000000000040008000A000D00010001000900060000000000000000 +0DE0:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB663B66FB661CE7FFE0000 +0DE1:00007FFE738E6DB66DB66DB6738E7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000 +0DE2:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FF663866FBE61867FFE0000 +0DE3:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FF663C66FF6618E7FFE0000 +0DE4:00007FFE738E6DB66DB66DB6738E7FFE7FFE61B66FB663866FF661F67FFE0000 +0DE5:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE63866FF661867FFE0000 +0DE6:0000000007000880108010800FE00090009001E0008000800080008000800080 +0DE7:00000000000000001FC02020479049504950465020901F100000000000000000 +0DE8:00000000000000001F8C20524F2252A252A24CA221241E280000000000000000 +0DE9:00000000000000003E2C41529C92AA92AA92929244A238AC0000000000000000 +0DEA:0008001008201C702AA83298044018302008200810100FE00000000000000000 +0DEB:0000010003800540064000800300040004100260018000800080007000000000 +0DEC:0000000000000000000000000EE011102C7C228A12920C600000000000000000 +0DED:00000000000000000FE0102012400C4000400080008000840084007800000000 +0DEE:0000004000800100020004C00920121010101010082007C00000000000000000 +0DEF:07E00890086004001F8C20524F2252A252A24CA221241E280000000000000000 +0DF0:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB663B66FB66FCE7FFE0000 +0DF1:00007FFE738E6DB66DB66DB6738E7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000 +0DF2:0000000000000000000000000012002D0009001B002D00120000000000000000 +0DF3:000000000000000000040008000A000D00010005000B00060000000000000000 +0DF4:0000000000000000000000000AA04AA4555425485014C0060000000000000000 +0DF5:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE63866FF66F867FFE0000 +0DF6:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +0DF7:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +0DF8:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +0DF9:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +0DFA:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FB663866FB66FB67FFE0000 +0DFB:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +0DFC:00007FFE738E6DB66DB66DB6738E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +0DFD:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +0DFE:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE638E6FBE6F867FFE0000 +0DFF:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +0E00:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6DB66DB66DB673CE7FFE0000 +0E01:0000000000003C426222222222220000 +0E02:00000000000064642444444444380000 +0E03:000000000000527212222222221C0000 +0E04:0000000000003C42425A7A6242420000 +0E05:000000000000344A425A7A6242420000 +0E06:000000000000527212222222726C0000 +0E07:0000000000000C0C04044424140C0000 +0E08:0000000000003C42021A1A0A0A0C0000 +0E09:0000000000003844046464242E360000 +0E0A:000000000002323412222222221C0000 +0E0B:000000000002527412222222221C0000 +0E0C:0000000000003945254545456F6D0000 +0E0D:000000000000324A2A4A4A4A6E620E00 +0E0E:0000000000003C4262222222667A1600 +0E0F:0000000000003C42622222226A6E1A00 +0E10:0000000000001E201C021A1A06022A16 +0E11:000000000000547A1222222222220000 +0E12:0000000000002955457575556F4D0000 +0E13:000000000000324A2A4A4A4A6F6B0000 +0E14:0000000000003C42425A5A4A72420000 +0E15:000000000000344A425A5A4A72420000 +0E16:0000000000003C426222222232320000 +0E17:000000000000646A3222222222220000 +0E18:0000000000003C407824242424180000 +0E19:0000000000006464244444444E360000 +0E1A:000000000000323212222222221C0000 +0E1B:000000000002023232122222221C0000 +0E1C:00000000000069694949494949360000 +0E1D:00000000000101696949494949360000 +0E1E:00000000000069692949494949360000 +0E1F:00000000000101696929494949360000 +0E20:0000000000003C426222222262620000 +0E21:000000000000626222222222726C0000 +0E22:000000000000626242324242423C0000 +0E23:0000000000003C40780404040C0C0000 +0E24:0000000000003C426222222232320200 +0E25:0000000000003C42021A262232320000 +0E26:0000000000003C426222222262620200 +0E27:0000000000003844040404040C0C0000 +0E28:000000000002023C425A7A6242420000 +0E29:0000000000006262222A2F22221C0000 +0E2A:0000000000033C42021A262232320000 +0E2B:0000000000006666242A322222220000 +0E2C:000000000001016A6929494949360000 +0E2D:0000000000003C4202626242427E0000 +0E2E:0000000000033C7A02626242427E0000 +0E2F:0000000000006C740404040404040000 +0E30:00000000000000343800343800000000 +0E31:000000313E0000000000000000000000 +0E32:00000000000038440404040404040000 +0E33:0000006060001C220202020202020000 +0E34:0000003C420000000000000000000000 +0E35:0000003A460000000000000000000000 +0E36:0000003E460000000000000000000000 +0E37:0000003A4E0000000000000000000000 +0E38:00000000000000000000000000000602 +0E39:00000000000000000000000000001A0E +0E3A:00000000000000000000000000000C0C +0E3B:00007FFE73866DBE6D8E6DBE73867FFE7FFE638E7DB6718E7DB6638E7FFE0000 +0E3C:00007FFE73866DBE6D8E6DBE73867FFE7FFE63C67DBE71BE7DBE63C67FFE0000 +0E3D:00007FFE73866DBE6D8E6DBE73867FFE7FFE638E7DB671B67DB6638E7FFE0000 +0E3E:00007FFE73866DBE6D8E6DBE73867FFE7FFE63867DBE718E7DBE63867FFE0000 +0E3F:00000000087C2A2A2A3C2A2A2A7C0800 +0E40:00000000000010101010101018180000 +0E41:00000000000024242424242436360000 +0E42:0000003E417C04040404040406060000 +0E43:00000038445434040404040406060000 +0E44:0000006C140404040404040406060000 +0E45:00000000000038440404040404040404 +0E46:0000000000006C720202020202020408 +0E47:023C40546C0000000000000000000000 +0E48:04040400000000000000000000000000 +0E49:18091E00000000000000000000000000 +0E4A:28556600000000000000000000000000 +0E4B:040E0400000000000000000000000000 +0E4C:010E0C00000000000000000000000000 +0E4D:00060600000000000000000000000000 +0E4E:030406080C0000000000000000000000 +0E4F:00000000000000003C425A5A423C0000 +0E50:000000000000003C42424242423C0000 +0E51:000000000000003C42425A3A023C0000 +0E52:000000000040404A56525A5A423C0000 +0E53:00000000000000344A4A4A4272720000 +0E54:000000000002023C40404C4C483E0000 +0E55:00000000001A163C40404C4C483E0000 +0E56:000000000000402C12020232323C0000 +0E57:000000000002022A5A4A4A4A6A6C0000 +0E58:000000000000033C40404656526E0000 +0E59:000000000002021A3450484864640000 +0E5A:0000000000006D750505050505050000 +0E5B:0000000000000000000000001800240040004000400242A22552180C00000000 +0E5C:00007FFE73866DBE6D8E6DBE73867FFE7FFE61C66FBE61BE7DBE61C67FFE0000 +0E5D:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FB661B67DB6618E7FFE0000 +0E5E:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE618E7DBE61867FFE0000 +0E5F:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE618E7DBE61BE7FFE0000 +0E60:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6FB663B66DB673CE7FFE0000 +0E61:00007FFE73866DBE6D8E6DBE73867FFE7FFE73EE6FCE63EE6DEE73C67FFE0000 +0E62:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FF663866DBE73867FFE0000 +0E63:00007FFE73866DBE6D8E6DBE73867FFE7FFE738E6FF663C66DF6738E7FFE0000 +0E64:00007FFE73866DBE6D8E6DBE73867FFE7FFE73B66FB663866DF673F67FFE0000 +0E65:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FBE63866DF673867FFE0000 +0E66:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6FBE638E6DB673CE7FFE0000 +0E67:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FF663EE6DDE73DE7FFE0000 +0E68:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6FB663CE6DB673CE7FFE0000 +0E69:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6FB663C66DF673CE7FFE0000 +0E6A:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FB663866DB673B67FFE0000 +0E6B:00007FFE73866DBE6D8E6DBE73867FFE7FFE738E6FB6638E6DB6738E7FFE0000 +0E6C:00007FFE73866DBE6D8E6DBE73867FFE7FFE73C66FBE63BE6DBE73C67FFE0000 +0E6D:00007FFE73866DBE6D8E6DBE73867FFE7FFE738E6FB663B66DB6738E7FFE0000 +0E6E:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FBE638E6DBE73867FFE0000 +0E6F:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FBE638E6DBE73BE7FFE0000 +0E70:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE7DB67BB677B677CE7FFE0000 +0E71:00007FFE73866DBE6D8E6DBE73867FFE7FFE61EE7DCE7BEE77EE77C67FFE0000 +0E72:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DF67B8677BE77867FFE0000 +0E73:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E7DF67BC677F6778E7FFE0000 +0E74:00007FFE73866DBE6D8E6DBE73867FFE7FFE61B67DB67B8677F677F67FFE0000 +0E75:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DBE7B8677F677867FFE0000 +0E76:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE7DBE7B8E77B677CE7FFE0000 +0E77:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DF67BEE77DE77DE7FFE0000 +0E78:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE7DB67BCE77B677CE7FFE0000 +0E79:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE7DB67BC677F677CE7FFE0000 +0E7A:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DB67B8677B677B67FFE0000 +0E7B:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E7DB67B8E77B6778E7FFE0000 +0E7C:00007FFE73866DBE6D8E6DBE73867FFE7FFE61C67DBE7BBE77BE77C67FFE0000 +0E7D:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E7DB67BB677B6778E7FFE0000 +0E7E:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DBE7B8E77BE77867FFE0000 +0E7F:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +0E80:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6DB673B66DB673CE7FFE0000 +0E81:0000000000005C222222222222620000 +0E82:0000000000003C420418204C52220000 +0E83:00007FFE73866DBE6D8E6DBE73867FFE7FFE738E6DF673C66DF6738E7FFE0000 +0E84:0000000000003C424232424242320000 +0E85:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866DBE73866DF673867FFE0000 +0E86:00000000000052AA8A12224A4A340000 +0E87:000000000000182C1404040404040438 +0E88:0000000000003C42021A260202020000 +0E89:0000000000003C4202622222225C0000 +0E8A:0000000000003C42640810204C720202 +0E8B:00007FFE73866DBE6D8E6DBE73867FFE7FFE738E6DB6738E6DB6738E7FFE0000 +0E8C:000000000000344A620418204C720202 +0E8D:000000000000324242324242423C0000 +0E8E:000000000000629292529292925C0000 +0E8F:0000000000003242423242425A240000 +0E90:0000000000003C424242422252220202 +0E91:000000000000A4EAAA2A4A4A4A320000 +0E92:00000000000052AAAA8A8A8A8A540000 +0E93:000000000000344A4A4A4A4A4A2A0000 +0E94:0000000000003C424242424252220000 +0E95:000000000000245A4242424242220000 +0E96:0000000000005C222222222222320202 +0E97:0000000000008C525252525252220000 +0E98:0000000000003E407C0262425A240000 +0E99:000000000000225222222222225C0000 +0E9A:000000000000225222424242423C0000 +0E9B:000002020202225222424242423C0000 +0E9C:000000000001668682828292926C0000 +0E9D:000002020202628282828292926C0000 +0E9E:00000000000042A242828292926C0000 +0E9F:00000202020242A242828292926C0000 +0EA0:0000000000006C925212121212320000 +0EA1:000000000000222222222222225C0000 +0EA2:000002020202324242224242423C0000 +0EA3:0000000000003C42403C0262423C0000 +0EA4:00007FFE73866DBE6D8E6DBE73867FFE7FFE61B66DB661866DF66DF67FFE0000 +0EA5:0000000000003C42020202324A240000 +0EA6:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6DBE618E6DB66DCE7FFE0000 +0EA7:0000000000003C4202020242423C0000 +0EA8:00000000000038555E44344444340000 +0EA9:00000000000024542444555E44380000 +0EAA:0000000000003A44467A02324A440000 +0EAB:00000000000096494949494949310000 +0EAC:000000000000324C403C424252340000 +0EAD:0000000000003C4242463A0244380000 +0EAE:000000000000324C403C0262423C0000 +0EAF:00000000000022261A02040408081010 +0EB0:00000000000022523C0022523C000000 +0EB1:000000627C0000000000000000000000 +0EB2:00000000000018241404040404040000 +0EB3:000040A040000C120A02020202020000 +0EB4:00000038440000000000000000000000 +0EB5:0000003C460000000000000000000000 +0EB6:00000038540000000000000000000000 +0EB7:0000003C560000000000000000000000 +0EB8:00000000000000000000000000001808 +0EB9:00000000000000000000000000001A0C +0EBA:00000000000000000000000000000010 +0EBB:0000007C620000000000000000000000 +0EBC:0000000000000000000000000000324C +0EBD:0000000000003A241804040404644438 +0EBE:00007FFE73866DBE6D8E6DBE73867FFE7FFE63866DBE638E6DBE63867FFE0000 +0EBF:00007FFE73866DBE6D8E6DBE73867FFE7FFE63866DBE638E6DBE63BE7FFE0000 +0EC0:0000000000000C101010101018180000 +0EC1:000000000000668888888888CCCC0000 +0EC2:0000304C221804040404040406060000 +0EC3:00003844543404040404040406060000 +0EC4:0000804C340404040404040406060000 +0EC5:00007FFE73866DBE6D8E6DBE73867FFE7FFE71866FBE6F866FF671867FFE0000 +0EC6:0000000000006C525222020202020408 +0EC7:00007FFE73866DBE6D8E6DBE73867FFE7FFE71866FF66FEE6FDE71DE7FFE0000 +0EC8:10101000000000000000000000000000 +0EC9:32143800000000000000000000000000 +0ECA:29560000000000000000000000000000 +0ECB:081C0800000000000000000000000000 +0ECC:021C1800000000000000000000000000 +0ECD:00000814080000000000000000000000 +0ECE:00007FFE73866DBE6D8E6DBE73867FFE7FFE71866FBE6F8E6FBE71867FFE0000 +0ECF:00007FFE73866DBE6D8E6DBE73867FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +0ED0:0000000000003C4242424242423C0000 +0ED1:0000000000003C42425A3A0204380000 +0ED2:000004040408102040404046423C0000 +0ED3:00001028140A442222222222225C0000 +0ED4:000002020408102040404C4C483E0000 +0ED5:0000020A1408102040404C4C483E0000 +0ED6:00001028140A244242425252522C0000 +0ED7:0000000000005C222222222222620202 +0ED8:0000000000002C52524242260A142C30 +0ED9:000000000000324A4A4A4A4A4A240000 +0EDA:00007FFE73866DBE6D8E6DBE73867FFE7FFE63866DB66D866DB663B67FFE0000 +0EDB:00007FFE73866DBE6D8E6DBE73867FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +0EDC:00000000000099555555555555260000 +0EDD:0000000000009955555555555D2E0000 +0EDE:000000000000B8444444555E44C40000 +0EDF:00000000000064848464959E84780000 +0EE0:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663B66FB661CE7FFE0000 +0EE1:00007FFE73866DBE6D8E6DBE73867FFE7FFE61EE6FCE63EE6FEE61C67FFE0000 +0EE2:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FF663866FBE61867FFE0000 +0EE3:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FF663C66FF6618E7FFE0000 +0EE4:00007FFE73866DBE6D8E6DBE73867FFE7FFE61B66FB663866FF661F67FFE0000 +0EE5:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE63866FF661867FFE0000 +0EE6:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FBE638E6FB661CE7FFE0000 +0EE7:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FF663EE6FDE61DE7FFE0000 +0EE8:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663CE6FB661CE7FFE0000 +0EE9:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663C66FF661CE7FFE0000 +0EEA:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FB663866FB661B67FFE0000 +0EEB:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FB6638E6FB6618E7FFE0000 +0EEC:00007FFE73866DBE6D8E6DBE73867FFE7FFE61C66FBE63BE6FBE61C67FFE0000 +0EED:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FB663B66FB6618E7FFE0000 +0EEE:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE638E6FBE61867FFE0000 +0EEF:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE638E6FBE61BE7FFE0000 +0EF0:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663B66FB66FCE7FFE0000 +0EF1:00007FFE73866DBE6D8E6DBE73867FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000 +0EF2:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FF663866FBE6F867FFE0000 +0EF3:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FF663C66FF66F8E7FFE0000 +0EF4:00007FFE73866DBE6D8E6DBE73867FFE7FFE61B66FB663866FF66FF67FFE0000 +0EF5:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE63866FF66F867FFE0000 +0EF6:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +0EF7:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +0EF8:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +0EF9:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +0EFA:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FB663866FB66FB67FFE0000 +0EFB:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +0EFC:00007FFE73866DBE6D8E6DBE73867FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +0EFD:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FB663B66FB66F8E7FFE0000 +0EFE:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE638E6FBE6F867FFE0000 +0EFF:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +0F00:18671C5D4955534B3901000000000000 +0F01:0000005C4854524A3901000000000000 +0F02:1000100018004430BA487C487830840088309C48224802300600610012000C00 +0F03:1000100018004430BA487C487830840088789C00223002480648613012000C00 +0F04:0000000006C1314E310E000000000000 +0F05:000000000C02621C621C000000000000 +0F06:0000000006C1314E310E000C04040404 +0F07:000000000815C4390000000000000000 +0F08:0000324C006C10381010101010100000 +0F09:0000001E2101020E110E110100000000 +0F0A:000F304E5141424E514E5140310F0000 +0F0B:00000018180000000000000000000000 +0F0C:00000018180000000000000000000000 +0F0D:00000018180808080808080808080000 +0F0E:00000036361212121212121212120000 +0F0F:00000018180018080808080808080000 +0F10:00000018001800180808080808080000 +0F11:00000066001800180808080808080000 +0F12:0814493E0077001A2C08080808080800 +0F13:00000000180018A5A518001800000000 +0F14:00000018242418003C00182424180000 +0F15:00FFE781A581FFB18DE3130905030301 +0F16:00027F827F8260027FFE7FFE01827F827F8200027FFE00827FFE40027FFE0002 +0F17:001100890449224A1252129413FC57145814582457C4500837F0180010000000 +0F18:0000000000000000000200010019002500260018019002600240018009000600 +0F19:00000000000000000018080808080800 +0F1A:00000000000018242418000000000000 +0F1B:00000000000022555522000000000000 +0F1C:00000000081414082255552200000000 +0F1D:00000000000000140814000000000000 +0F1E:00000000000000552255000000000000 +0F1F:00000000000000255225000000000000 +0F20:0000000E112121221C00000000000000 +0F21:000000060B1101020408000000000000 +0F22:0000001E2101020E1101000000000000 +0F23:0000001E21020E01021E210000000000 +0F24:00000000122C40417E00000000000000 +0F25:0000002244443C040201000000000000 +0F26:0000004044282711110E000000000000 +0F27:0000000101314A123C00000000000000 +0F28:00000008102070080402010100000000 +0F29:0000001C2224494E4040000000000000 +0F2A:0000000C16220F740810000000000000 +0F2B:0000003C420F741C2202000000000000 +0F2C:0000003C42041F72043C420000000000 +0F2D:00000000122C46497E20400000000000 +0F2E:000000224E553C440201000000000000 +0F2F:00000040452A2719112E400000000000 +0F30:0000000101314F723C00000000000000 +0F31:000000081020720D3442010100000000 +0F32:0000031D2A34694E4040000000000000 +0F33:0000001D22464A543840000000000000 +0F34:00000000181800101C04101C04000000 +0F35:00000000000000000000000010552A1C +0F36:00000000181800666600181800000000 +0F37:00000000000000000000000018242418 +0F38:334A525C000000000000000000000000 +0F39:07040200000000000000000000000000 +0F3A:000000000000008009401490C428389001400080000000000000000000000000 +0F3B:0000000000000200052012502846123805000200000000000000000000000000 +0F3C:00000202040808182020202020204000 +0F3D:000020201008080C0202020202020100 +0F3E:00000000000000000C02020202020201 +0F3F:00000000000000003040404040404080 +0F40:0000003F156505010101000000000000 +0F41:0000003F494D4B414100000000000000 +0F42:0000003F496959090101000000000000 +0F43:0000003F496959091F204E3111010000 +0F44:0000001E204078440201000000000000 +0F45:0000003E08084E31110E000000000000 +0F46:0000003E08083E494936000000000000 +0F47:0000001E203C407C4201000000000000 +0F48:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000 +0F49:00000038444E11110101020000000000 +0F4A:0000007F013D43414040000000000000 +0F4B:0000003F213A2C222F30200000000000 +0F4C:0000003C02011F214040400000000000 +0F4D:0000003C02011F205E604E3111010000 +0F4E:0000003F081C12322C20200000000000 +0F4F:0000007F405E61410101000000000000 +0F50:0000003F21170D113D03010000000000 +0F51:0000001E20407C420101010000000000 +0F52:0000001E20407C421F204E3111010000 +0F53:0000003F040E12130D01010000000000 +0F54:0000003321417D430101000000000000 +0F55:0000003323457D430101000000000000 +0F56:0000001F21417D430101000000000000 +0F57:0000001F21417D431F204E3111010000 +0F58:0000007D09314D4B3101000000000000 +0F59:0001013E08084E31110E000000000000 +0F5A:0001013E08083E494936000000000000 +0F5B:0001011E2038407C4201000000000000 +0F5C:0001011E2038407C421F204E31110100 +0F5D:00000031494F09111D13010000000000 +0F5E:0000001C224C52534D21010000000000 +0F5F:0000003F011F013D0301000000000000 +0F60:000000384444481C0201000000000000 +0F61:0000006B494949350301000000000000 +0F62:0000003E081C02010100000000000000 +0F63:0000003945490D030100000000000000 +0F64:0000000F11114F311101010000000000 +0F65:0000003C22223D232220200000000000 +0F66:0000007B112965030100000000000000 +0F67:0000001E204E31110101000000000000 +0F68:0000005D4955534B3101000000000000 +0F69:0000003F156505013925243D22242000 +0F6A:0000007C083844020202000000000000 +0F6B:0000007E545350404040000000000000 +0F6C:0000001F080E11202020000000000000 +0F6D:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE738E6FB663B66DB6738E7FFE0000 +0F6E:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE73866FBE638E6DBE73867FFE0000 +0F6F:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE73866FBE638E6DBE73BE7FFE0000 +0F70:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE7DB67BB677B677CE7FFE0000 +0F71:00000000000000000000182804000000 +0F72:70480400000000000000000000000000 +0F73:7048040000000000003F4242041C2202 +0F74:0000000000000000000000000040241C +0F75:00000000000000003E4242040C42221C +0F76:704804000000000000720A0602000000 +0F77:70480400000000027A063F42041C2200 +0F78:70480400000000000000000022525E02 +0F79:70480400000000325E023F42041C2200 +0F7A:E0180400000000000000000000000000 +0F7B:CC220000000000000000000000000000 +0F7C:CF281000000000000000000000000000 +0F7D:45EE1000000000000000000000000000 +0F7E:10281000000000000000000000000000 +0F7F:00000018242418001824241800000000 +0F80:1C244000000000000000000000000000 +0F81:1C24400000000000003F4242041C2202 +0F82:08080C225D3F00000000000000000000 +0F83:0814493E000000000000000000000000 +0F84:00000000000000000004060203010101 +0F85:0000000000384444081C12120A020201 +0F86:10101024180000000000000000000000 +0F87:10101010101000000000000000000000 +0F88:00003F800A0004000A003F800000000000000000000000000000000000000000 +0F89:00364900000000000000000000000000 +0F8A:0000000000000000EEAAAAAABA000000 +0F8B:000000000000000001023A4A4A2E0000 +0F8C:00493600000000000000000000000000 +0F8D:0000000000000000007F22140814227F +0F8E:00000000000000000000000000364900 +0F8F:00000000000000000000000000493600 +0F90:000000000000003F1525010000000000 +0F91:00000000000000003F494D4B41000000 +0F92:000000000000003F4979090000000000 +0F93:000000000000003F4979011E204E3111 +0F94:00000000000000001E207C4201000000 +0F95:00000000000000003E084E310E000000 +0F96:00000000000000003E083E4936000000 +0F97:00000000000000001E2038407E410000 +0F98:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000 +0F99:000000000000000038440E1101020000 +0F9A:00000000000000007F013D4341400000 +0F9B:00000000000000007E4478447E400000 +0F9C:00000000000000003C021F2140400000 +0F9D:00000000000000003C021F207E510100 +0F9E:0000000000001E081C324C4000000000 +0F9F:00000000000000007F405E6141010000 +0FA0:00000000000000003F110F113F010000 +0FA1:00000000000000001E207C4201010000 +0FA2:00000000000000001E207C421F204E31 +0FA3:0000000000003C081C26190100000000 +0FA4:0000000000000033217D030100000000 +0FA5:0000000000000027497D030100000000 +0FA6:000000000000001F217D030100000000 +0FA7:000000000000001F217D031F204E3111 +0FA8:0000000000000079314D330100000000 +0FA9:00000000003C0A094C32120C00000000 +0FAA:00000000000000003E093E4949360000 +0FAB:00000000001C2239417C420000000000 +0FAC:00000000001C2239417C421E204E3111 +0FAD:00000000000000000000000001030503 +0FAE:00000000000000001C224C534D210100 +0FAF:00000000000000003F011F013F010000 +0FB0:00000000000000003844481C02010000 +0FB1:0000000000000000010101121C090600 +0FB2:00000000000000000101013945030100 +0FB3:00000000000000003945491D03010000 +0FB4:000000000000000007092F1109010100 +0FB5:000000000000000038243D2224202000 +0FB6:00000000000000007B29456301000000 +0FB7:00000000000000001E204E3111010000 +0FB8:00000000000000005D49555331010000 +0FB9:000000000000003F15650539243D2220 +0FBA:000000000000000031494F091D030100 +0FBB:00000000000000006B49493503010000 +0FBC:00000000000000003E081C0201010000 +0FBD:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE638E6DB663B66DB6638E7FFE0000 +0FBE:00000000004122140814224100000000 +0FBF:00000000004922144914224900000000 +0FC0:00000000001C224141221C0000000000 +0FC1:000000000000001C22221C0000000000 +0FC2:000000001C021A242458403800000000 +0FC3:000000001C224955492A1C0000000000 +0FC4:0000006B14081C2222223E417F000000 +0FC5:0D600280010003800C601930145022882108155011100D600380010002800D60 +0FC6:00000000000000000000000000000000000045442AA82AA812900FE015502548 +0FC7:0D600280010003808C6299325454A28AA10A555491128D620380010002800D60 +0FC8:00000D60028001003FF824481290129009200920044004400280028001000000 +0FC9:0000000003800440092014501390282827C8200820081010183007C000000000 +0FCA:000007C008203018200840049E06A126C106C90AC0F2400420083018082007C0 +0FCB:000007C0082030183C0C424C810A911281E281028202424422083218092007C0 +0FCC:000007C00820303821287C2482428182892283028482487C29083818082007C0 +0FCD:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE718E6FB66FB66FB6718E7FFE0000 +0FCE:00000000000000522552000000000000 +0FCF:00000000001408140055225500000000 +0FD0:000000001F00208040440F381080008001000700088000000000000000000000 +0FD1:003C4202041C221C2218240408040200 +0FD2:000000007C38100000007C3810000000 +0FD3:0000000006C1310E0000000000000000 +0FD4:000000000C02621C0000000000000000 +0FD5:0000000041FC410041004100410041007FFC010401040104010401047F040000 +0FD6:000000007F04010401040104010401047FFC4100410041004100410041FC0000 +0FD7:0000000041FC410041004920410041007FFC010401040924010401047F040000 +0FD8:000000007F04010401040924010401047FFC4100410049204100410041FC0000 +0FD9:0000000000004000600040000000100218061002000002100738000000000000 +0FDA:0000000000000002000600020000400860184008000008401CE0000000000000 +0FDB:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +0FDC:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +0FDD:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE638E6DB66DB66DB6638E7FFE0000 +0FDE:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE63866DBE6D8E6DBE63867FFE0000 +0FDF:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +0FE0:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663B66FB661CE7FFE0000 +0FE1:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000 +0FE2:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FF663866FBE61867FFE0000 +0FE3:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FF663C66FF6618E7FFE0000 +0FE4:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61B66FB663866FF661F67FFE0000 +0FE5:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE63866FF661867FFE0000 +0FE6:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000 +0FE7:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FF663EE6FDE61DE7FFE0000 +0FE8:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000 +0FE9:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663C66FF661CE7FFE0000 +0FEA:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FB663866FB661B67FFE0000 +0FEB:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FB6638E6FB6618E7FFE0000 +0FEC:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000 +0FED:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FB663B66FB6618E7FFE0000 +0FEE:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE638E6FBE61867FFE0000 +0FEF:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE638E6FBE61BE7FFE0000 +0FF0:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000 +0FF1:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000 +0FF2:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FF663866FBE6F867FFE0000 +0FF3:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FF663C66FF66F8E7FFE0000 +0FF4:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61B66FB663866FF66FF67FFE0000 +0FF5:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE63866FF66F867FFE0000 +0FF6:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +0FF7:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +0FF8:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +0FF9:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +0FFA:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FB663866FB66FB67FFE0000 +0FFB:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +0FFC:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +0FFD:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +0FFE:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE638E6FBE6F867FFE0000 +0FFF:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +1000:00000000000000000000018C02520421042104210242000C0000000000000000 +1001:0000000000000000000000780084000201F2010A008400780000000000000000 +1002:0000000000000000000000780084010201020102008400480000000000000000 +1003:00000000000000000000060C01420221042104210252018C0000000000000000 +1004:0000000000000000000000780084010001000100008400780000000000000000 +1005:0000000000000000000000780084014201420142008400780000000000000000 +1006:00000000000000000000018C02520021002103A10252018C0000000000000000 +1007:0000000000000000000000F001080214020A0200010800F00000000000000000 +1008:0000000000000000000000710089014501450145008900790009000900050002 +1009:0000000000000000000000E00110000800080008011001E001000101010100FE +100A:00000000000000000000018C02420021002100210252038C02000201020101FE +100B:0000000000000000000000780084010001000084007C000400F800800078000E +100C:00000000000000000000007800840100010001000084007C000400C4010400F8 +100D:000000000000000000000078008400020002008400F80080007C000400040006 +100E:0000000000000000000001880044008201020102008400780000000000000000 +100F:0000000000000000000003760489045104510451028A00F80000000000000000 +1010:00000000000000000000018C02520421042104210242018C0000000000000000 +1011:00000000000000000000018C02520421042104210252018C0000000000000000 +1012:0000000000000000000000F00108000800300008010800F00000000000000000 +1013:000000000000000000000078008401020102017A008400780000000000000000 +1014:00000000000000000000001C00200020001C00C2012200FC0020002000000000 +1015:0000000000000000000000480084010201020102008400780000000000000000 +1016:000000000000000000000058009401120112010A008400780000000000000000 +1017:0000000000000000000000000084017A01020102008400780000000000000000 +1018:00000000000000000000018C02520021002100210242018C0000000000000000 +1019:000000000000000000000048008401020102017A008400780000000000000000 +101A:00000000000000000000000C02420421042104210252018C0000000000000000 +101B:0000000000000000000000F00108020403C40224011400F40004000400040007 +101C:00000000000000000000018C02420421042104210212018C0000000000000000 +101D:0000000000000000000000780084010201020102008400780000000000000000 +101E:00000000000000000000018C02420021002100210252018C0000000000000000 +101F:00000000000000000000000C02520421042104210242018C0000000000000000 +1020:0000000000000000000000780084010001000084007C000400F8008000840078 +1021:00000000000000000000019C0262004300850049024A018C0000000000000000 +1022:00000000000000000000018C02520421042102210142060C0000000000000000 +1023:00000000000000000000018C02520421042104210202000001DC022202240107 +1024:000600090008000400020199026504250425042502450005000507E5080507F9 +1025:0000000000000000000000F00108000400040004010801F001000100010400F8 +1026:0070008800A800D80070000000F8010800040004010801F001000100010400F8 +1027:0000000000000000000000780084017801000178008400780000000000000000 +1028:0000000000000000007800840132014A010A0112010C01000102010200840078 +1029:3FFE4001400140004000471C488240414041404148A3471D4001400140013FFE +102A:07C608290828080408000B36288948898889B889D89A6B6808080808080807F0 +102B:0F00108010800080008000800080008000800080008000800000000000000000 +102C:0000000000000000000003E00410000800080008001001E00000000000000000 +102D:0030004800480030000000000000000000000000000000000000000000000000 +102E:0070008800A80088007000000000000000000000000000000000000000000000 +102F:0000000000000000000002000200020002000200020002000200020002000380 +1030:00000000000000000000050005000500050005000500050005000500050005C0 +1031:0000000000000000000000003000400040007000500030000000000000000000 +1032:0100008000400020000000000000000000000000000000000000000000000000 +1033:007000A800D800A8007000000000000000000000000000000000000000000000 +1034:0008001000200040000000000000000000000000000000000000000000000000 +1035:0070008000B800C8007000000000000000000000000000000000000000000000 +1036:0000000200050002000000000000000000000000000000000000000000000000 +1037:0000000000000000000000000000000000000000000000000000001000280010 +1038:0000000000000000000001000280010000000100028001000000000000000000 +1039:0000000000000000000000000000000000000000000000000000002000700020 +103A:000C001200100008000000000000000000000000000000000000000000000000 +103B:0000000000000000000004000400040004000400040084008400840064001C00 +103C:07FC0802080208000800080008000800080008000800080008000800080407F8 +103D:000000000000000000000000000000000000000000000000000800140022001C +103E:0000000000000000000000000000000000000000000000200020002000600000 +103F:000000000000000000000124029200490049004902DA01240000000000000000 +1040:0000000000000000000003600410080808080808041003600000000000000000 +1041:0000000000000000000003C00420001000100010042003C00000000000000000 +1042:0000000000000000000000200020002000200020002000200020002008400780 +1043:0000000000000000000003C00420001000100010042003C00100008000400020 +1044:0000000000000000000003C00420080008000800042003C00080010002000400 +1045:0000000000000000000007C00A200A10041000100010001000100010042003C0 +1046:000001E002100400040004600480048004700410021001E00000000000000000 +1047:0000000000000000000007800840002000200020004000800100020002000180 +1048:0000000000000000000003C004200A1009100910052003000000000000000000 +1049:0000000000000000000001E002100410047004800480046004000400021001E0 +104A:0000000000000000000000800080008000800080008000800000000000000000 +104B:0000000000000000000002400240024002400240024002400000000000000000 +104C:0180024002000100000003C0042000100010042007C0040003E00020042003C0 +104D:000000180024002000100788084810281E28112808A807A800280628080807F0 +104E:00000000000000000000007800840100010001000084007C0004000400040004 +104F:001800240020001000080F6410942F1420142F1410940F140000000000000000 +1050:0000000000000000000000780084010201320102008400480000000000000000 +1051:0000000000000000000000480084010201320102008400780000000000000000 +1052:0000000000000000000000060088010401020102008400780000000000000000 +1053:0000000000000000000001860048008401020102008400780000000000000000 +1054:00000000000000000000007800840142013E0100008400780000000000000000 +1055:00000000000000000000007800840142013E01000092006C0000000000000000 +1056:0000000000000000000000600080004000200020084007800000000000000000 +1057:0000000000000000000000300040002000100010092006C00000000000000000 +1058:0000000000000000000000000000000000000000000000000030005000640038 +1059:000000000000000000000000000000000000000000000000006000A000CA0074 +105A:0000000000000000000000780084010001000084007800200050001000200010 +105B:0000000000000000000000E20112022A02160202011200F200120012000A0004 +105C:00000000000000000000007800840132014A0132008400780000000000000000 +105D:000000000000000000000048008401020102017A0086007A000200C2010200FC +105E:0000000000000000000000000000000000000000000000000010003800540030 +105F:0000000000000000000000000000000000000000000000000010003000440038 +1060:0000000000000000000000000000000000000000000000000010002000400078 +1061:0000000000000000000000780084010201E20112008A007A0002000A000A001A +1062:0000000000000000000003800080008000800080008000800000000000000000 +1063:0000000000000000000003800440002000200020044007800400040004000400 +1064:0000000000000000000007000100010001000100010001C00000000000000000 +1065:0000000000000000000000780084000200020002008400780000000000000000 +1066:0000000000000000000000480084010201020102008400780000001000100030 +1067:0000000000000000000000800080008001800280028001000000000000000000 +1068:0000010002800100000000800080008000800080008003800000000000000000 +1069:0000000000000000000001800240004001800200024001800000000000000000 +106A:0000000000000000000000800080008000800080028001000000000000000000 +106B:0000000000000000000001000280008000800080008000800000000000000000 +106C:0000000000000000000001000100010001000100014000800000000000000000 +106D:0000000000000000000001800240020001800040024001800000000000000000 +106E:0000000000000000000001B60249022902290249015200000000000000000000 +106F:00000000000000000000000C02520421042104210242018C0000000800080018 +1070:00000000000000000000060C01420221042104210252018C0000000800080018 +1071:0000008801540088000000000000000000000000000000000000000000000000 +1072:0030004800400030000000000000000000000000000000000000000000000000 +1073:0020005000880104000000000000000000000000000000000000000000000000 +1074:0000004800480030000000000000000000000000000000000000000000000000 +1075:0000000000000000000000780084010201020082004401880000000000000000 +1076:00000000000000000000013801440082000200FA008400780000000000000000 +1077:0000000000000000000000780084010A010A008A004401800000000000000000 +1078:00000000000000000000018C02520421042104210212018C0000000000000000 +1079:00000000000000000000018C02520621052104A10292018C0000000000000000 +107A:00000000000000000000018C0242042104210421023201AC0020002000200038 +107B:00000000000000000000018C0252042304250429024A018C0000000000000000 +107C:00000000000000000000018C02520020002001FC0252018C0000000000000000 +107D:00000000000000000000060C015202200420042E0252018C0000000000000000 +107E:00000000000000000000060C015202200420042E0252018C0000000800080018 +107F:00000000000000000000006800A4012201220142008400780000000000000000 +1080:00000000000000000000018C02420021002103A10252018C0000000000000000 +1081:000000000000000000000078008401020102012200A4006000200020002000E0 +1082:0000000000000000000000000000000000000000000000000020004000480030 +1083:00000000000000000000070001000100010001000100010001000100010001C0 +1084:0000000000000000000030004800400030004000480030000000000000000000 +1085:0070008800400088007000000000000000000000000000000000000000000000 +1086:0020005000300010002000000000000000000000000000000000000000000000 +1087:0000000000000000000000000000000000000100028001800080010000000000 +1088:0000000000000000000001000280010000000100028001800080010000000000 +1089:0000000000000000000000000000000000000100028001000000000000000000 +108A:0000000000000000000002000540038000000200054003800000000000000000 +108B:0000000000000000000000000000010002800100000000000000000000000000 +108C:0000000000000000000000000000022005500220000000000000000000000000 +108D:000000000000000000000000000000000000000000000000000001FE00000000 +108E:0000000000000000000000780084017A01020102008400780000000000000000 +108F:0000000000000000000001000280010000000100028003000200010000000000 +1090:0000000000000000000003C00420042004200420042003C00000000000000000 +1091:0000000000000000000003000500010001000100014001800000000000000000 +1092:0000000000000000000005C00620002000400080010001000000000000000000 +1093:0000000000000000008000800100010002000380044004400000000000000000 +1094:000000000000000000800080018001800280028004A004C00000000000000000 +1095:0000000000000000000000400040004007E00840084007800000000000000000 +1096:0000000000000000000007800840084007E00040004000400000000000000000 +1097:0000000000000000000007C00040008001000200040007C00000000000000000 +1098:0000000000000000000004200420024003C00420042003C00000000000000000 +1099:0000000000000000000003C00420042003C00240042004200000000000000000 +109A:0000000000000000000001000280010000000000000000000000000000000000 +109B:0000010002800180008001000000000000000000000000000000000000000000 +109C:0000000000000000000003800540020000000380054002000000000000000000 +109D:0000001C00220002000200020000000000000000000000000000000000000000 +109E:00000100028001000000070001000100010001000100010001000100010001C0 +109F:001800240020001000080F041084204420442044104400440044004400440038 +10A0:00000080FE22408080808082463A0000 +10A1:000000006888888898680808080E0200 +10A2:00000000F888880808080808080E0200 +10A3:0000000080FE12103844828244380000 +10A4:000000007C4444040404040404040000 +10A5:00000000F88888080E0A080808080000 +10A6:0000000080E02020202C322222221C00 +10A7:00000000305090909E92909050300000 +10A8:000000407C0404040404040404040000 +10A9:000000004040586444444C3404040000 +10AA:0000000000E0A020202C322222221C00 +10AB:00000080F80808087E8A8A8888700000 +10AC:000000047C4040407C44444444440000 +10AD:00000000708888888888888A8A740000 +10AE:00000080E222222222222222221C0000 +10AF:000000407A122222261A020202020000 +10B0:000000001010141A1292909090600000 +10B1:00000000404040404844444444380000 +10B2:000000007C4242427C404040407E0200 +10B3:00000000708888888888888C8A720000 +10B4:000000007C9292927C10101010100000 +10B5:00000000101010507C14101010100000 +10B6:000000003C4242424242424242420000 +10B7:000000002444444444444C3404040000 +10B8:00000000344444444C34044444380000 +10B9:00000000404040407C44444444440000 +10BA:000000001C22424040404042221C0408 +10BB:00000000080808083E4A4A4848300000 +10BC:000000007C4242427C40407844484040 +10BD:0000000000003844442010080442423C +10BE:0000000044444444447C4040407C0400 +10BF:00000080FE2222141408141422224080 +10C0:00000000F090901010101212120C0000 +10C1:00000000404078444640404040400000 +10C2:00000040784402020202024244380000 +10C3:00000000344444444C34040404040000 +10C4:00000000828282824428101010100000 +10C5:000000001C12121C107C949690600000 +10C6:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000 +10C7:0000000000001C22220408102042423C +10C8:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +10C9:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +10CA:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71866FB66F866FB671B67FFE0000 +10CB:00007FFE7BCE73B67BB67BB671CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +10CC:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +10CD:000000007C04040810102020407C0000 +10CE:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000 +10CF:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +10D0:0000000000000010100C0202423C0000 +10D1:00000000203010103C424242423C0000 +10D2:000000000030484808083C424242423C +10D3:000000000000002C525252524C201C02 +10D4:000000003C424202020202020242423C +10D5:0000000000003C4242021C020242423C +10D6:0000000020505054381C1212120C0000 +10D7:00000000000000344A4A4A4A4A320000 +10D8:000000000000003C4242424242240000 +10D9:0000000000000C0202021C020242423C +10DA:000000000000002A5555554142403E01 +10DB:000000003C424202023E4242423C0000 +10DC:00000000023C4040407C4242423C0000 +10DD:00000000000000285454545444240000 +10DE:0000000020180402021C0242423C0000 +10DF:00000000000000060A5252220222221C +10E0:00000000043840685454545444240000 +10E1:00000000404040485048444444380000 +10E2:000000001824243C66665A424242423C +10E3:000000000000006C121202020222221C +10E4:00000000000000344A4A4A4A3402021C +10E5:00000000040C0404041C240404044438 +10E6:00000000000000285454544448403804 +10E7:0000000000000022424242261A42423C +10E8:0000000028545404041C242424180000 +10E9:00000000384478405C62424242420000 +10EA:0000000000004C4242425C424242423C +10EB:0000000004020202023E4242423C0000 +10EC:0000000028545440407C444428281010 +10ED:00000000081828080819261D04044438 +10EE:00000000404040485078444444380000 +10EF:00000000000000004224181824422040 +10F0:0000100C02120C02120C0242423C0000 +10F1:0000504C42524C42524C4242423C0000 +10F2:0000000000003C4242424224187E0000 +10F3:0000000000003E0204081C020242423C +10F4:0000000008100C0202021C020242423C +10F5:00000000003844443E043E4444380000 +10F6:00000000201010103854543810101008 +10F7:0000000000003C42420408102042423C +10F8:0000000000000044424242645842423C +10F9:00000000003C424242423C101012120C +10FA:0000000000003C4242300C1C22400000 +10FB:00000000000060600006060060600000 +10FC:0000021C20203C22221C000000000000 +10FD:0000000000003C42422010080442423C +10FE:00000000000000C0221C2222221C0000 +10FF:0000000000000000001C2222221C0000 +1100:000000007F800080008000800080010001000200040018006000000000000000 +1101:0000000000007B80088008800880088011001100220044000800000000000000 +1102:000020002000200020003F800000000000000000000000000000000000000000 +1103:00003F802000200020003F800000000000000000000000000000000000000000 +1104:00003B802200220022003B800000000000000000000000000000000000000000 +1105:000000003F8000803F8020003F80000000000000000000000000000000000000 +1106:00003F802080208020803F800000000000000000000000000000000000000000 +1107:0000208020803F8020803F800000000000000000000000000000000000000000 +1108:00002A802A803B802A803B800000000000000000000000000000000000000000 +1109:00000400040004000A0011000000000000000000000000000000000000000000 +110A:00001100110011002A8044400000000000000000000000000000000000000000 +110B:00000E001100110011000E000000000000000000000000000000000000000000 +110C:00003F80010002000D0030800000000000000000000000000000000000000000 +110D:000000003BC00880150022800440000000000000000000000000000000000000 +110E:0E0000003F8002000D0030800000000000000000000000000000000000000000 +110F:00003F8000803F80008000800000000000000000000000000000000000000000 +1110:00003F8020003F8020003F800000000000000000000000000000000000000000 +1111:00007F801200120012007F800000000000000000000000000000000000000000 +1112:00000E0000003F8000001F002080208020801F00000000000000000000000000 +1113:000021FC2004200420043F840000000000000000000000000000000000000000 +1114:000020402040204020403E7C0000000000000000000000000000000000000000 +1115:0000207C2040204020403E7C0000000000000000000000000000000000000000 +1116:000020442044207C20443E7C0000000000000000000000000000000000000000 +1117:00003E7C2004200420043E040000000000000000000000000000000000000000 +1118:000000003E4002403E4020403E7C000000000000000000000000000000000000 +1119:000000003E7C02043E7C20403E7C000000000000000000000000000000000000 +111A:000000003E3002FC3E3020483E30000000000000000000000000000000000000 +111B:000000001FF800081FF810001FF803C00420042003C000000000000000000000 +111C:00003E442244227C22443E7C0000000000000000000000000000000000000000 +111D:00001FFC1004100410041FFC00000000000003E004100410041003E000000000 +111E:0000227C22043E0422043E040000000000000000000000000000000000000000 +111F:0000224022403E4022403E7C0000000000000000000000000000000000000000 +1120:0000227C22403E4022403E7C0000000000000000000000000000000000000000 +1121:0000221022103E1022283E440000000000000000000000000000000000000000 +1122:0000489E4882788249427A220000000000000000000000000000000000000000 +1123:0000488E4888788849487A2E0000000000000000000000000000000000000000 +1124:000049244924793C4AA47C7C0000000000000000000000000000000000000000 +1125:000048884888788849547A220000000000000000000000000000000000000000 +1126:0000493E490479084A947C620000000000000000000000000000000000000000 +1127:0000227C22083E1022283E440000000000000000000000000000000000000000 +1128:00382200227C3E1022283E440000000000000000000000000000000000000000 +1129:0000227C22403E7C22403E7C0000000000000000000000000000000000000000 +112A:0000227C22283E2822283E7C0000000000000000000000000000000000000000 +112B:000008080FF808080FF801C0022001C000000000000000000000000000000000 +112C:000022443E7C22443E7C03C0042003C000000000000000000000000000000000 +112D:0000047C040404040A0411040000000000000000000000000000000000000000 +112E:00000440044004400A40117C0000000000000000000000000000000000000000 +112F:0000047C044004400A40117C0000000000000000000000000000000000000000 +1130:0000047C0404047C0A40117C0000000000000000000000000000000000000000 +1131:0000047C044404440A44117C0000000000000000000000000000000000000000 +1132:000004440444047C0A44117C0000000000000000000000000000000000000000 +1133:0000112E112211E2292245E20000000000000000000000000000000000000000 +1134:0000088808880888155422220000000000000000000000000000000000000000 +1135:00000438044404440A4411380000000000000000000000000000000000000000 +1136:0000047C040804100A2811440000000000000000000000000000000000000000 +1137:00380400047C04100A2811440000000000000000000000000000000000000000 +1138:0000047C0404047C0A0411040000000000000000000000000000000000000000 +1139:0000047C0440047C0A40117C0000000000000000000000000000000000000000 +113A:0000047C042804280A28117C0000000000000000000000000000000000000000 +113B:0000043004FC04300A4811300000000000000000000000000000000000000000 +113C:0000004000400180068018400000000000000000000000000000000000000000 +113D:00000120012002A0045019880000000000000000000000000000000000000000 +113E:0000008000800100068018400000000000000000000000000000000000000000 +113F:00000480048005400A30118C0000000000000000000000000000000000000000 +1140:000002000500088010403FE00000000000000000000000000000000000000000 +1141:00000E7C1104110411040E040000000000000000000000000000000000000000 +1142:00000E3C1120112011200E3C0000000000000000000000000000000000000000 +1143:00000E3E1122112211220E3E0000000000000000000000000000000000000000 +1144:00000E241124113C11240E3C0000000000000000000000000000000000000000 +1145:00000E081108110811140E220000000000000000000000000000000000000000 +1146:0000382044504488450439FC0000000000000000000000000000000000000000 +1147:00000E381144114411440E380000000000000000000000000000000000000000 +1148:00000E7C1108111011280E440000000000000000000000000000000000000000 +1149:00380E00117C111011280E440000000000000000000000000000000000000000 +114A:00000E3C1120113C11200E3C0000000000000000000000000000000000000000 +114B:00000E7C1128112811280E7C0000000000000000000000000000000000000000 +114C:00000E001100110011000E000000000000000000000000000000000000000000 +114D:00003E3804440844144422380000000000000000000000000000000000000000 +114E:00003FE000C003800C4030200000000000000000000000000000000000000000 +114F:000000001FF0012002A00C503188000000000000000000000000000000000000 +1150:00001FF0006001C0062018100000000000000000000000000000000000000000 +1151:000000003FE0084014A02310018C000000000000000000000000000000000000 +1152:1C00007C3E04087C140422040000000000000000000000000000000000000000 +1153:180000303EFC0830144822300000000000000000000000000000000000000000 +1154:078000001FC00180064038200000000000000000000000000000000000000000 +1155:0E0000003F0002000D8030700000000000000000000000000000000000000000 +1156:00003E441444147C14443E7C0000000000000000000000000000000000000000 +1157:00001FF804201FF803C0042003C0000000000000000000000000000000000000 +1158:000018307EFC1C70228822881C70000000000000000000000000000000000000 +1159:1FF0010007C00820082007C00000000000000000000000000000000000000000 +115A:00003E7C024002400240027C0000000000000000000000000000000000000000 +115B:000010101010101010281F440000000000000000000000000000000000000000 +115C:0000107C1008101010281F440000000000000000000000000000000000000000 +115D:0000107011FC107010881E700000000000000000000000000000000000000000 +115E:000000003E7C2004207C20403E7C000000000000000000000000000000000000 +115F:AAAA000180002239A2403E41A2402239800003E1820003818200020180005555 +1160:AAAA000180002279A2103E11A2502221800003E1820003818200020180005555 +1161:0000001000100010001E00100010001000000000000000000000000000000000 +1162:0000001200120012001E00120012001200000000000000000000000000000000 +1163:0000001000100010001E0010001E001000000000000000000000000000000000 +1164:0000001200120012001E0012001E001200000000000000000000000000000000 +1165:0000001000100010007000100010001000000000000000000000000000000000 +1166:0000001200120012007200120012001200000000000000000000000000000000 +1167:0000001000100010007000100070001000000000000000000000000000000000 +1168:0000001200120012007200120072001200000000000000000000000000000000 +1169:000000000000000000000000000000000000008000803FFE0000000000000000 +116A:0000001000100010001E041004103FF000000000000000000000000000000000 +116B:0000001200120012001E041204123FF200000000000000000000000000000000 +116C:00000010001000100010041004103FF000000000000000000000000000000000 +116D:00000000000000000000024002403FFE00000000000000000000000000000000 +116E:00000000000000000000000000003FFE00800080000000000000000000000000 +116F:00000010001000100010001000103F90041004F0041000000000000000000000 +1170:00000012001200120012001200123F92041204F2041200000000000000000000 +1171:00000010001000100010001000103FF004100410041000000000000000000000 +1172:00000000000000000000000000003FFE02200220000000000000000000000000 +1173:00000000000000000000000000003FFE00000000000000000000000000000000 +1174:000000100010001000100010001000100010001000103FF00010001000000000 +1175:0000001000100010001000100010001000000000000000000000000000000000 +1176:00000000000000000000002000200020003800A000A03FF80000000000000000 +1177:0000001000100010001C001000103FFE00800080000000000000000000000000 +1178:000000000000000000080008000E0008000E008800883FFE0000000000000000 +1179:00080008000E0008000E024802483FFE00000000000000000000000000000000 +117A:000000000000000800080008003800080008008800883FFE0000000000000000 +117B:00000000000400040004001C0004000400043FFE008000800000000000000000 +117C:00200020002000E000200020002000203FF00000000000000000000000000000 +117D:000000000000000000080008003800080038008800883FFE0000000000000000 +117E:00080008000800380008003800083FFE00800080000000000000000000000000 +117F:00000000000200020002000200023FFE0082008E000200000000000000000000 +1180:000000000000001200120012007200120012011201123FF20012000000000000 +1181:000000000000001200120012007200120012017201123FF20012000000000000 +1182:000000000000000000000000000000803FFE00803FFE00000000000000000000 +1183:000000000000000000000000008000803FFE00003FFE00800080000000000000 +1184:0000000000100010001E091009103FFE00100000000000000000000000000000 +1185:000000A400A400A404BC04A404FC3FA400000000000000000000000000000000 +1186:00020002000E0002000E048204823FFE00020000000000000000000000000000 +1187:0000000000000000000002203FFE00803FFE0000000000000000000000000000 +1188:00000000000200020002024202423FFE00020000000000000000000000000000 +1189:00000000000000000008000800083FFE02080208000800000000000000000000 +118A:00000000000000000012001200123FFE02120212001200000000000000000000 +118B:000000080008000800081FC80208027802083FFE000000000000000000000000 +118C:0000000A000A000A000A000A000A3FEA020A023A000A003A000A000000000000 +118D:00000000000000000000000000003FFE00803FFE008000000000000000000000 +118E:00000008000800080008000800083FFE02480248000800000000000000000000 +118F:00000001000100010001000100013FFF0221022F000100000000000000000000 +1190:00000000000A000A000A000A000A3FFA048A04BA000A00000000000000000000 +1191:00000000000200020002000200023FFE0242024E0002000E0002000000000000 +1192:00000000000A000A000A000A000A3FFA048A04BA000A003A000A000000000000 +1193:00000000000000000000000000003FFE02203FFE008000000000000000000000 +1194:00000000000100010001000100013FFF02210221000100000000000000000000 +1195:00000000000000000000000000003FFE00003FFE008000000000000000000000 +1196:00000000000000000000000000003FFE00003FFE000000000000000000000000 +1197:00040004000400040004000400040FFC00043FFE008000000000000000000000 +1198:0000004800480048004E00480048004800000000000000000000000000000000 +1199:000000480048004E0048004E0048004800000000000000000000000000000000 +119A:000000000000000400040004000400040004008400843FFE0000000000000000 +119B:00040004000400040004000400043FFE00800080000000000000000000000000 +119C:00000004000400040004000400043FFE00000000000000000000000000000000 +119D:00000020002000200020002000200020000000C0002000100000000000000000 +119E:00000000000000000000000000000000000000C0002000100000000000000000 +119F:000000100010001000700C100210011000000000000000000000000000000000 +11A0:000000000000000000000060001000083FFE0080008000000000000000000000 +11A1:0000001000100010001018100410021000000000000000000000000000000000 +11A2:0000000000000000000018600410020800000000000000000000000000000000 +11A3:000000000000000000000020002000200038002000203FF80000000000000000 +11A4:000000000000000000080008000E0008000E000800083FFE0080008000000000 +11A5:000000000000000000280028002E00E8002800EE002800280028000000000000 +11A6:0000000000100010001E011001103FFE00100000000000000000000000000000 +11A7:0000002400240024003C042404FC3F2400000000000000000000000000000000 +11A8:00000000000000000000000000000000000007F0001000100010001000000000 +11A9:0000000000000000000000000000000000000F78010801080108010800000000 +11AA:0000000000000000000000000000000000000F10011001100128014400000000 +11AB:000000000000000000000000000000000000040004000400040007F000000000 +11AC:00000000000000000000000000000000000008F80820082008500F8800000000 +11AD:000000000000000000000000000000000000083008FC083008480F3000000000 +11AE:00000000000000000000000000000000000007F004000400040007F000000000 +11AF:00000000000000000000000000000000000007F0001007F0040007F000000000 +11B0:0000000000000000000000000000000000000F7801080F0808080F0800000000 +11B1:0000000000000000000000000000000000001EF002901E9010901EF000000000 +11B2:0000000000000000000000000000000000001E9002901EF010901EF000000000 +11B3:0000000000000000000000000000000000001E2002201E2010501E8800000000 +11B4:0000000000000000000000000000000000001EF002801EF010801EF000000000 +11B5:0000000000000000000000000000000000001EF802501E5010501EF800000000 +11B6:0000000000000000000000000000000000001E6003F81E6010901E6000000000 +11B7:00000000000000000000000000000000000007F004100410041007F000000000 +11B8:0000000000000000000000000000000000000410041007F0041007F000000000 +11B9:000000000000000000000000000000000000122012201E2012501E8800000000 +11BA:0000000000000000000000000000000000000040004000C003201C1000000000 +11BB:0000000000000000000000000000000000000120012003A00C50318800000000 +11BC:00000000000000000000000000000000000001C002200220022001C000000000 +11BD:00000000000000000000000000000000000007F0008000800140022000000000 +11BE:00000000000000000000000000000000000001E0000007F8004003A00C180000 +11BF:00000000000000000000000000000000000007F0001007F00010001000000000 +11C0:00000000000000000000000000000000000007F0040007F0040007F000000000 +11C1:0000000000000000000000000000000000000FF00240024002400FF000000000 +11C2:000000000000000000000000000001C0000007F0000001C0022001C000000000 +11C3:0000000000000000000000000000000000007E7C0204027C0240027C00000000 +11C4:00000000000000000000000000000000789E0882088209420A22000000000000 +11C5:00000000000000000000000000000000000021FC2004200420043F8400000000 +11C6:000000000000000000000000000000000000207C2040204020403E7C00000000 +11C7:00000000000000000000000000000000000020202020202020503E8800000000 +11C8:00000000000000000000000000000000000040104028404440827CFE00000000 +11C9:000000000000000000000000000000000000207C2040207C20403E7C00000000 +11CA:0000000000000000000000000000000000003E7C2004200420043E0400000000 +11CB:0000000000000000000000000000000000003E7C2004207C20403E7C00000000 +11CC:0000000000000000000000000000000000007BC408447844404A785100000000 +11CD:0000000000000000000000000000000000003E4002403E4020403E7C00000000 +11CE:0000000000000000000000000000000000003E7C02403E4020403E7C00000000 +11CF:000000000000000000000000000000000000F78C143FF40C8412F78C00000000 +11D0:0000000000000000000000000000000000003E7C02043E7C20403E7C00000000 +11D1:0000000000000000000000000000000000007BDE0A427A4242427BC200000000 +11D2:0000000000000000000000000000000000007BC40A447A44424A7BD100000000 +11D3:0000000000000000000000000000000000007A440A447BC4424A7BD100000000 +11D4:000000000000000000000000000000000000F48C14BFF78C8492F78C00000000 +11D5:0000000000000000000000000000004800783E4802783E3020483E3000000000 +11D6:00000000000000000000000000000000000078880888788841547A2200000000 +11D7:0000000000000000000000000000000000003C2004503C8821043DFC00000000 +11D8:0000000000000000000000000000000000003E7C02043E7C20043E0400000000 +11D9:0000000000000000000000000000000000003E3802FE3E3820443E3800000000 +11DA:0000000000000000000000000000000000003E7C2204220422043E0400000000 +11DB:0000000000000000000000000000000000003E7C2204227C22403E7C00000000 +11DC:0000000000000000000000000000000000003E442244227C22443E7C00000000 +11DD:0000000000000000000000000000000000001F101110111011281F4400000000 +11DE:0000000000000000000000000000000000007C444444444444AA7D1100000000 +11DF:0000000000000000000000000000000000003E102228224422823EFE00000000 +11E0:0000000000000000000000000000000000383E0022FE220822343EC200000000 +11E1:0000000000000000000000000000000000003E3822FE223822443E3800000000 +11E2:00000000000000000000000000000FE008200FE0000003800440038000000000 +11E3:000000000000000000000000000000000000227C22043E7C22403E7C00000000 +11E4:000000000000000000000000000000000000227C22283E2822283E7C00000000 +11E5:000000000000000000000000000000000000223822FE3E3822443E3800000000 +11E6:0000000000000000000000000000041007F0041007F001C0022001C000000000 +11E7:00000000000000000000000000000000000004F8040804080A08110800000000 +11E8:000000000000000000000000000000000000047C044004400A40117C00000000 +11E9:00000000000000000000000000000000000008F8080808F8148022F800000000 +11EA:00000000000000000000000000000000000004440444047C0A44117C00000000 +11EB:00000000000000000000000000000000000001000280044008201FF000000000 +11EC:0000000000000000000000000000000000000E7C1104110411040E0400000000 +11ED:00000000000000000000000000000000000039DC444444444444384400000000 +11EE:0000000000000000000000000000000000001C382244224422441C3800000000 +11EF:0000000000000000000000000000000000001C7C2204227C22041C0400000000 +11F0:0000000000000000000000000000010001000380044004400440038000000000 +11F1:0000000000000000000000000000000000001C202220222022501C8800000000 +11F2:000000000000000000000000000000000000382044504488450439FC00000000 +11F3:0000000000000000000000000000000000003E441444147C14443E7C00000000 +11F4:000000000000000000000000000000000FF002400FF003C0042003C000000000 +11F5:0000000000000000000000000000000000001C407F401C4022401C7C00000000 +11F6:0000000000000000000000000000000000001C7C7F041C7C22401C7C00000000 +11F7:0000000000000000000000000000000000001C7C7F441C4422441C7C00000000 +11F8:0000000000000000000000000000000000001C447F441C7C22441C7C00000000 +11F9:00000000000000000000000000000000000003800FE003800440038000000000 +11FA:0000000000000000000000000000000000003E40024002400240027C00000000 +11FB:0000000000000000000000000000000000003E440244027C0244027C00000000 +11FC:0000000000000000000000000000000000383E0002FE0208023402C200000000 +11FD:0000000000000000000000000000000000003E7C0204027C0204020400000000 +11FE:0000000000000000000000000000000000003E3802FE02380244023800000000 +11FF:00000000000000000000000000000000000020402040204020403E7C00000000 +1200:00000000000001C030C030C030C030C030C030C0318031801F000E0000000000 +1201:00000000000001C030C030C030C030FC30CC30C0318031801F000E0000000000 +1202:0000000006600C600C600C600C6007C003C000C001800300033003F000000000 +1203:0000000006600C600C600C600C6007C003C000C0018003000300030000000000 +1204:0000000006600C600C600C600C6007C003C000C001C00340032003E000000000 +1205:000000000000187018301C300E3006300C300C300C300C6007E003C000000000 +1206:00000000000000F030C830D830E030C030C030C0318031801F000E0000000000 +1207:000000000000003C0C320C360C386C307C306C300C600C6007C0038000000000 +1208:00000000030003000300078007C00CE00C600C600C600C600C600C6000000000 +1209:000000000C000C000C001E001F0033803180318031F831983180318000000000 +120A:000000000C000C000C001E001F0033803180318031803180319831F800000000 +120B:00000000030003000300078007C00CE00C600C600C6000600060006000000000 +120C:000000000C000C000C001E001F00338031803180318031F0319831F000000000 +120D:00000000030003000300078007C00CE00C60186018601E601B601E6000000000 +120E:000000000C000C000C001E001F003380318031F831AC31B83180318000000000 +120F:00000000030003000300078007C00CE00C600C600C6000600060006003FC070E +1210:000000000180018001800180018007E00DB00DB0199819981998199800000000 +1211:00000000060006000600060006001F8036C036C0667E66666660666000000000 +1212:00000000060006000600060006001F8036C036C0666066606666667E00000000 +1213:000000000180018001800180018007E00DB00DB0199800180018001800000000 +1214:00000000060006000600060006001F8036C036C066406678664C667800000000 +1215:000000000600060006000780018007E00DB00DB0199819981998199800000000 +1216:000000000180018001800180018007E00DB00DB0199818001800180000000000 +1217:0000030003000300030003000FC01B601B60333000300030003001FE03870000 +1218:000000000000000000000FFC1FFC112431642344264C3C783C70000000000000 +1219:000000000000000000003FF07FF04490C59E8D129932F1E0F1C0000000000000 +121A:000000001FF83FF86288428845087DF838F80010001000200026003E00000000 +121B:000000000FFC1FFC3144214422843EFC1C7C0008000800100010001000000000 +121C:000000001FF83FF86288428845087DF838F800100010003C0026003C00000000 +121D:000000001FF01FF832882288228822F83E701E00020006000C00180000000000 +121E:000000001FF01FF832882288228822F83E701E00020002000200030000000000 +121F:000000001FF83FF86288428845087DF838F80010001000300020002001F8030C +1220:00000000000000000998199819981998199819B019F00D800780000000000000 +1221:000000000000000026C066C066FC66CC66C066C067C036001E00000000000000 +1222:000000006640666066606660666076E03FE00060006000600066007E00000000 +1223:00000000199019981998199819981DB80FF80018001800180018001800000000 +1224:00000000332033303330333033303B701FF00030003000380064007800000000 +1225:00000000199019981998199819981DB81FF01C00180018001800180000000000 +1226:00000000199819981998199819981DB80FF00380030007000E000C0000000000 +1227:00006640666066606660666076E03FE00060006000600060006003FC070E0000 +1228:00000000018001800180030007000E001C00180018001C600FE007E000000000 +1229:000000000300030007000E001C001800300038001FF00FF00180018000000000 +122A:00000000018001800180030007000E001C00186018701C300FE007C000000000 +122B:0000000003000300030006000E001C003800307830F839981F800F0000000000 +122C:00000000018001800180030007000E001C00180018001CF00F9807F000000000 +122D:00000000000007E00FE018601800180018001800180018601FE00FC000000000 +122E:00000000000007F00F9818F01800180018001800180018601FE00FC000000000 +122F:0000000030301CE00300030006000E001C003800307830F839981F800F000000 +1230:0000000001000100038007C00C600C600C600C600C600C600C600C6000000000 +1231:00000000040004000E001F0031803180318031F8319831803180318000000000 +1232:00000000040004000E001F00318031803180318031803180319831F800000000 +1233:0000000001000100038007C00C600C600C600C600C6000600060006000000000 +1234:000000000200020007000F8018C018C018C018C018E018D018C818F800000000 +1235:0000000000000300018001C003E0063006300630063006300630063000000000 +1236:0000000001000100038007C00C600C600C600C600C600C000C000C0000000000 +1237:0000000001000100038007C00C600C600C600C600C6000600060006001F8030C +1238:0000000030601FC0020007000F8018C018C018C018C018C018C018C000000000 +1239:0000000030601FC0020007000F8018C018C018FC18CC18CC18C018C000000000 +123A:0000000030601FC0020007000F8018C018C018C018C018C018CC18FC00000000 +123B:0000000018300FE00100038007C00C600C600C600C6000600060006000000000 +123C:0000000030601FC0020007000F8018C018C018C018C018F818CC18F800000000 +123D:0000000018600FC0018001C003E0033006300630063006300630063000000000 +123E:0000000018300FE00100038007C00C600C600C600C600C000C000C0000000000 +123F:0000000030601FC0020007000F8018C018C018C018C018C000C000C003F00618 +1240:0000000001800180018003F00D98199819B00FC0018001800180018000000000 +1241:0000000003000300030007E01B30333033601F80030003F00330030000000000 +1242:0000000003000300030007E01B30333033601F8003000300033003F000000000 +1243:0000000001800180018003F00D98199819B00FC00180030006000C0000000000 +1244:0000000003000300030007E01B30333033601F80030003E0033003E000000000 +1245:00000000060006000780018003F00D98199819B00FC001800180018000000000 +1246:0000000001C0026002C0030007E01B30333033601F8003000300030000000000 +1247:0000000001C0026002C0030007E01B30333033601F80030033003F0030000000 +1248:0000000001800180018003F00D98199819B00FC001F801AC01B8018000000000 +1249:00007FFE7B8673F67B867BBE71867FFE7FFE6DCE6DB661C67DF67DCE7FFE0000 +124A:000000000600060006000FC0366C666C66FC3F07060306000600060000000000 +124B:0000000001800180018003F00D98199819B00FC0018001800180018007E00C30 +124C:0000000001800180018003F00D98199819B00FC00180018001F0019807F00C00 +124D:000000000600061806180FFE3666666066C03F00060006000600060000000000 +124E:00007FFE7B8673F67B867BBE71867FFE7FFE6D866DBE618E7DBE7D867FFE0000 +124F:00007FFE7B8673F67B867BBE71867FFE7FFE6D866DBE618E7DBE7DBE7FFE0000 +1250:000000000C3007E00180018003F00D98199819B00FC001800180018000000000 +1251:0000000018600FC00300030007E01B30333033601F80030003F0033000000000 +1252:0000000018600FC00300030007E01B30333033601F800300033003F000000000 +1253:000000000C3007E00180018003F00D98199819B00FC001800300060000000000 +1254:0000000018600FC0030007E01B30333033601F80030003E0033003E000000000 +1255:0000000030C01F8006000780018003F00D98199819B00FC00180018000000000 +1256:000000000C1807F001200160018003F00D98199819B00FC00180018000000000 +1257:00007FFE7B8673F67B867BBE71867FFE7FFE61866FF661EE7DDE61DE7FFE0000 +1258:0000000018600FC0030007E01B30333033601F8003F003580370030000000000 +1259:00007FFE7B8673F67B867BBE71867FFE7FFE61CE6FB661C67DF661CE7FFE0000 +125A:0000000030C01F80060006000FC0366C666C66FC3F0706030600060000000000 +125B:000000000C3007E00180018003F00D98199819B00FC001800180018007E00C30 +125C:000000000C3007E00180018003F00D98199819B00FC0018001F0019807F00C00 +125D:0000000030C01F80061806180FFE3666666066C03F0006000600060000000000 +125E:00007FFE7B8673F67B867BBE71867FFE7FFE61866FBE618E7DBE61867FFE0000 +125F:00007FFE7B8673F67B867BBE71867FFE7FFE61866FBE618E7DBE61BE7FFE0000 +1260:000000000000038007C00C600C600C600C600C600C600C600C600C6000000000 +1261:0000000000000E001F0031803180318031F83198319831803180318000000000 +1262:0000000000000E001F003180318031803180318031803180319831F800000000 +1263:000000000000038007C00C600C600C600C600C60006000600060006000000000 +1264:00000000000007000F8018C018C018C018C018C018C018F818CC18F800000000 +1265:00000000000000E001F00318031803183F183318331803180318031800000000 +1266:000000000000038007C00C600C600C600C600C600C000C000C000C0000000000 +1267:000000000000038007C00C600C600C600C600C60006000600060006001F8030C +1268:0000000030601FC0000007000F8018C018C018C018C018C018C018C000000000 +1269:0000000030601FC0000007000F8018C018C018FC18CC18CC18C018C000000000 +126A:0000000030601FC0000007000F8018C018C018C018C018C018CC18FC00000000 +126B:0000000030601FC0000007000F8018C018C018C018C018C000C000C000000000 +126C:0000000060C03F8000000E001F00318031803180318031F0319831F000000000 +126D:000000000C1807F0000001C003E0063006307E30663066300630063000000000 +126E:0000000030601FC0000007000F8018C018C018C018C018C01800180000000000 +126F:0000000030601FC0000007000F8018C018C018C018C018C000C000C003F00618 +1270:0000000007000300030003003FF07FF863180300030003000300030000000000 +1271:0000000007000300030003003FF07FF86318030003F003300300030000000000 +1272:0000000007000300030003003FF07FF86318030003000300033003F000000000 +1273:0000000007000300030003003FF07FF863180300030007000E001C0000000000 +1274:0000000007000300030003003FF07FF863180300030003E0033003E000000000 +1275:00000000060007000380018001801FF83FFC318C018001800180018000000000 +1276:0000000003E00320016001801FF83FFC318C0180018001800180018000000000 +1277:0000000003800180018001801FF83FFC318C0180018001800180018007E00C30 +1278:0000000018181FF83FFC318C01801FF83FFC318C018001800180018000000000 +1279:0000000018181FF83FFC318C01801FF83FFC318C018001F80198018000000000 +127A:0000000018181FF83FFC318C01801FF83FFC318C01800180019801F800000000 +127B:0000000030303FF07FF8631803003FF07FF86318030007000E001C0000000000 +127C:0000000030303FF07FF8631803003FF07FF86318030003E0033003E000000000 +127D:0000000030C03FC07FE06660070001801FF83FFC318C01800180018000000000 +127E:000000000C301FF81A58024001801FF83FFC318C018001800180018000000000 +127F:0000000018181FF83FFC318C01801FF83FFC318C018001800180018007E00C30 +1280:000000000180018001801F8019E0006000600060006000600060006000000000 +1281:000000000300030003003F0033C000C000C000FC00CC00C000C000C000000000 +1282:000000000300030003003F0033C000C000C000C000C000C000CC00FC00000000 +1283:0000000000C000C000C00FC00CF000300030003000E001800300030000000000 +1284:000000000300030003003F0033C000C000C000C000C000F800CC00F800000000 +1285:0000000000C000C000C003C006F00C300C300030003000300030003000000000 +1286:0000000001F803E406383E003600060007E003E0006000600060006000000000 +1287:0000000001F803E406383E003600060007E003E000600060066007E006000000 +1288:000000000600060006007E006780018001F801AC01B801800180018000000000 +1289:00007FFE7B8673F67B867BBE71867FFE7FFE73CE6DB673C66DF673CE7FFE0000 +128A:000000000600060006007E0067800198019801F8018E01860180018000000000 +128B:000000000180018001801F8019E0006000600060006000600060006001F8030C +128C:000000000300030003003F0033C000C000C000C000C000C000F800CC03F80600 +128D:000000000600060006007E3067B001FC018C0180018001800180018000000000 +128E:00007FFE7B8673F67B867BBE71867FFE7FFE73866DBE738E6DBE73867FFE0000 +128F:00007FFE7B8673F67B867BBE71867FFE7FFE73866DBE738E6DBE73BE7FFE0000 +1290:00000000060006000600078001C0018001800180030003000300030000000000 +1291:00000000060006000600078001C00180018001F0033003000300030000000000 +1292:000000000C000C000C000F00038003000300030006000600066007E000000000 +1293:0000000007C00FE01860300038001F0003800180010003000300030000000000 +1294:00000000060006000600078001C001800180018003C00320036003C000000000 +1295:000000003FC03F803180030007C000C0018003000300060006000C0000000000 +1296:0000000007F00FC81858303038001F0003800180010003000300030000000000 +1297:00000000000007C00FE01860300038001F00038001800100030003000FC01860 +1298:000000000C301FF81188018001E000700060006000C000C000C000C000000000 +1299:0000000018603FF02310030003C000E000C000F8019801800180018000000000 +129A:0000000018603FF02310030003C000E000C000C001800180019801F800000000 +129B:00000C301FF8118807C00FE01860300038001F00038001800300030000000000 +129C:0000000018603FF02310030003C000E000C000C001E0019001B001E000000000 +129D:000030C07FE046201FC03F803180030007C000C0018003000300030000000000 +129E:00000C601FF0111007F00FC81858303038001F00038001800300030000000000 +129F:00000C301FF8118807C00FE01860300038001F0003800180030003000FC01860 +12A0:0000000006000600060007800180038003C006E00E600C600C600C6000000000 +12A1:000000001800180018001E0006000E000F001B8039F831983180318000000000 +12A2:000000001800180018001E0006000E000F001B8039803180319831F800000000 +12A3:000000000600060006000780018003C006E00C600C600C600060006000000000 +12A4:000000001800180018001E0006000E000F001B80398031F0319831F000000000 +12A5:000000000C000C000E0006000300038007C00EE00C600C600C600C6000000000 +12A6:000000000600060006000780018003C006E00C600C600C600C000C0000000000 +12A7:000018C01FC03660060007800180038003C006E00E600C600C600C6000000000 +12A8:000000000000180019C01FE01E30063006300630063006300630063000000000 +12A9:000000000000600067007F8078C018C018C018FC18CC18C018C018C000000000 +12AA:000000000000600067007F8078C018C018C018C018C018C018CC18FC00000000 +12AB:000000000000180019C01FE01E30063006300630063000300030003000000000 +12AC:000000000000600067007F8078C018C018C018C018C018F818CC18F800000000 +12AD:000000000000180019C01BE01E300C300E300630063006300630063000000000 +12AE:000000000000180019C01FE01E30063006300630063006000600060000000000 +12AF:0000000000000C000CE00FF00F18031833183F18331803000300030000000000 +12B0:000000000000600066007F007980198019F819AC19B819801980198000000000 +12B1:00007FFE7B8673F67B867BBE71867FFE7FFE63EE6DCE63EE6DEE63C67FFE0000 +12B2:000000000000600066007F0079801998199819F8198E19861980198000000000 +12B3:000000000000180019C01FE01E30063006300630063000300030003000FC0186 +12B4:000000000000600067007F8078C018C018C018C018C000C000F800CC03F80600 +12B5:000000000000600066307F3079FC198C19801980198019801980198000000000 +12B6:00007FFE7B8673F67B867BBE71867FFE7FFE63CE6DBE638E6DB663CE7FFE0000 +12B7:00007FFE7B8673F67B867BBE71867FFE7FFE63866DF663EE6DDE63DE7FFE0000 +12B8:0000000061803F000C000DC00FE0063006300630063006300630063000000000 +12B9:00000000C3007E0018001B801FC00C600C600C7E0C660C600C600C6000000000 +12BA:00000000C3007E0018001B801FC00C600C600C600C600C600C660C7E00000000 +12BB:0000000061803F000C000DC00FE0063006300630063000300030003000000000 +12BC:0000000061803F000C000DC00FE00630063006300630063E0633063E00000000 +12BD:0000000061803F000C000EE00FF0031803980198019801980198019800000000 +12BE:0000000061803F000C000DC00FE0063006300630063006000600060000000000 +12BF:00007FFE7B8673F67B867BBE71867FFE7FFE63866DBE638E6DBE63BE7FFE0000 +12C0:00000000C3007E0018001B801FC00C600C7E0C6B0C6E0C600C600C6000000000 +12C1:00007FFE7B8673F67B867BBE71867FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000 +12C2:00000000C3007E0018001B001F800CCC0CCC0CFC0CC70CC30CC00CC000000000 +12C3:0000000061803F000C000DC00FE0067006300630063000300030003000FC0186 +12C4:0000000061803F000C000DC00FE006700630063006300030003E003300FE0180 +12C5:00000000C3007E00180C1B8C1FFF0C630C600C600C600C600C600C6000000000 +12C6:00007FFE7B8673F67B867BBE71867FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000 +12C7:00007FFE7B8673F67B867BBE71867FFE7FFE71866FF66FEE6FDE71DE7FFE0000 +12C8:000000000000000000000FF01DB831983198331833303B701FC0000000000000 +12C9:000000000000000000003FC076E0C660C660CC60CCE0EDC67FFC000C00000000 +12CA:000000000FF01DB83198319833183BB01FE0030003000700066007E000000000 +12CB:000000000FF01DB83198319833183BB01FE00300030003000300070000000000 +12CC:000000000FF01DB83198319833183BB01FE0030003000780066007C000000000 +12CD:000000000000000000003FC076E0C660C67ECC66CCC2EDC07F00000000000000 +12CE:000000000FF01DB83198319833183BB01FE0030006000C001800180000000000 +12CF:0000000003FC076E6C667C666CC60EEC07F800C0018003000600060000000000 +12D0:00000000000001E006300C300C300C300C300C300C300C3007F0060000000000 +12D1:000000000000078018C030C030C030C030C030FC30CC30C01FC0180000000000 +12D2:0000000000001F0031806180618061803FC000C000C00180019801F800000000 +12D3:00000000000007C00C601860186018600FF00030003000300060006000000000 +12D4:0000000000001F0031806180618061803FC000C000C001F0019801F000000000 +12D5:000001800180018007E00E300C300C300C300C300C300C3007F0060000000000 +12D6:0000000003C006600C300C300C300E7007E003C007000C000C000C0000000000 +12D7:00007FFE7B8673F67B867BBE71867FFE7FFE63866DF66DEE6DDE63DE7FFE0000 +12D8:000000000C600C600C600C600C600FE00FE00C600C600C600C600C6000000000 +12D9:00000000318031803180318031803F803F8031F8319831983180318000000000 +12DA:00000000318031803180318031803F803F80318031803180319831F800000000 +12DB:000000000C600C600C600C600FE00FE00C600C600C6000600060006000000000 +12DC:0000000018C018C018C018C018C01FC01FC018C018C018F818CC18F800000000 +12DD:000000001C30363036300630063007F007F00630063006300630063000000000 +12DE:000000000C600C600C600C600FE00FE00C600C600C600C000C000C0000000000 +12DF:000000000C600C600C600C600FE00FE00C600C600C6000600060006001F8030C +12E0:000000001C38366C366C0660066007E007E00660066006600660066000000000 +12E1:0000000038706CD86CD80CC00CC00FC00FC00CFC0CCC0CCC0CC00CC000000000 +12E2:0000000038706CD86CD80CC00CC00FC00FC00CC00CC00CC00CCC0CFC00000000 +12E3:000000001C38366C366C066007E007E006600660066000600060006000000000 +12E4:0000000038706CD86CD80CC00CC00FC00FC00CC00CC00CF80CCC0CF800000000 +12E5:000061803F000C001C38366C366C066007E007E0066006600660066000000000 +12E6:000000001C38366C366C066007E007E006600660066006000600060000000000 +12E7:000000001C38366C366C066007E007E006600660066000600060006001F8030C +12E8:00000000038006C00C600C600C600C600EC00780030003000300030000000000 +12E9:00000000038006C00C600C600C600C600EC00780030003F00330030000000000 +12EA:0000000007000D8018C018C018C018C01D800F00066007F80618060000000000 +12EB:0000000001C00360063006300630066007C0038001C0006001C0038000000000 +12EC:0000000007000D8018C018C018C018C01D800F0006F0079806F0060000000000 +12ED:00000000000007800CC018C018C018C00D800F30073003E03E00700060000000 +12EE:000000000E001B00318031F8319831803B001E000C000C000C000C0000000000 +12EF:00000000038006C00C600C7E0C660C606EC07F80630003000300030000000000 +12F0:00000000038007C00C400C400CC00F8006000300030001801FF8181800000000 +12F1:0000000007000F80188019801F000C0006001FC030C030FC018C018000000000 +12F2:0000000007000F80188019801F000C0006001FC030C030C0019801F800000000 +12F3:0000000001C003E00620066007C0030001800FF00C300C300030003000000000 +12F4:0000000007000F801880188019801F000C000600060003F03F9830F000000000 +12F5:0000000007000F8018F8189819801F000C000600060003003FF0303000000000 +12F6:0000000001C003E00620066007C0038007F00C30180018001800180000000000 +12F7:0000000001C003E00620066007C0030001800FF00C300C300030003000FC0186 +12F8:0000000001000100038007C00C400CC00F800600030001800FF00C3000000000 +12F9:000000000200020007000F80188019801F000C001FC030FC318C018000000000 +12FA:000000000200020007000F80188019801F000C001FC030C0319801F800000000 +12FB:0000000001000100038007C00C400CC00F8006001FE018600060006000000000 +12FC:00000000040004000E001F00310033003E0018000C0006F03F9830F000000000 +12FD:000000000200020007000F8018F819981F000C00060003001FE0186000000000 +12FE:0000000001000100038007C00C400CC00F8007F00C3018001800180000000000 +12FF:0080008001C003E00620066007C0030001800FF00C300C300030003000FC0186 +1300:000030301FE0030007800CC00C400CC007800600070003001FE0186000000000 +1301:000060603FC006000F00198019800F0006001FC030C030FC018C018000000000 +1302:000060603FC006000F00198019800F0006001FC030C030C0019801F800000000 +1303:000030301FE0030007800CC00CC0078003001FE0186018600060006000000000 +1304:000060603FC006000F001980188019800F000C000E0007F03F9830F000000000 +1305:000030301FE0030007800CC00C7C0CCC07800600070003001FE0186000000000 +1306:000030301FE0030007800CC00CC0078007F00C30180018001800180000000000 +1307:000030301FE0030007800CC00CC0078003001FE0186018600060006003FC070E +1308:0000000000000F8018C018C000C000C000C00180018001800180018000000000 +1309:0000000000001F003180318001800180018003F8031803000300030000000000 +130A:0000000000000F8018C018C000C000C000C0018001800180019801F800000000 +130B:00000000000007800FE00C6000600060006000C001C007800E000C0000000000 +130C:0000000000000F8018C018C000C000C000C00180018001F0019801F000000000 +130D:0000000000000FE019B00F300030003000600060006000600060006000000000 +130E:0000000001000100010007C00C600C600060004000C000C000C000C000000000 +130F:0000000001000100010007C00C600C600060004000C000C00CC00FC00C000000 +1310:0000000000001F00318031800180018001F803AC033803000300030000000000 +1311:00007FFE7B8E73F67BC67BF6718E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000 +1312:0000000000001F0031803180018001B001B003F0031C030C0300030000000000 +1313:00000000000007800CC00CC000C007E006600060006000600060006000000000 +1314:0000000000000F8018C018C000C000C000C001800180018001F0019807F00C00 +1315:0000000000001F0031B031B001FC018C01800380030003000300030000000000 +1316:00007FFE7B8E73F67BC67BF6718E7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000 +1317:00007FFE7B8E73F67BC67BF6718E7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000 +1318:000000000C3007E0000007C00C600C600060004000C000C000C000C000000000 +1319:0000000030C01F8000001F00318031800180018003F803180300030000000000 +131A:0000000018600FC000000F8018C018C000C0008001800180019801F800000000 +131B:000000000C3007E0000003C007F004300030003000E003C007000E0000000000 +131C:0000000018600FC000000F8018C018C000C00080018001F0019801F000000000 +131D:0000000018600FC000000FE019B00F3000300020006000600060006000000000 +131E:000000000C6007C0010007C00C600C600060004000C000C000C000C000000000 +131F:0000000018600FC002000F8018C018C000C000800180018001800FF00C300000 +1320:000000000000000007C00D600D60193019301930193019301930193000000000 +1321:00000000000000001F003580358064C064C064FC64CC64C064C064C000000000 +1322:00000000000000001F003580358064C064C064C064C064C064CC64FC00000000 +1323:00000000000007C00D600D601930193019301930003000300030003000000000 +1324:0000000000001F003580358064C064C064C064C064C064F864CC64F800000000 +1325:0000000000000FE01FF013303318339831980180018001800180018000000000 +1326:00000000000007C00D600D601930193019301930180018001800180000000000 +1327:00000000000007C00D600D601930193019301930003000300030003000FC0186 +1328:00000000000000001F803FC06260C230C230C230F338DAB6CAB2FBBE00000000 +1329:00000000000000001F803FC06260C230C23FC233F338DAB4CAB2FBBE00000000 +132A:00000000000000001F803FC06260C230C230C230F330DAB0CAB3FBBF00000000 +132B:000000000FE01FF0311861187198695865587DD8001800340032003E00000000 +132C:00000000000000001F803FC06260C23FC239C237F330DABCCAB2FBBE00000000 +132D:0000000000001FC07FE0C630E6389724F33C030003800340032003E000000000 +132E:000000000FE01FF01A183218231862946252639C7000680064007C0000000000 +132F:0000000000000FE01FF0311861187198695865587DD800180030003000FC0186 +1330:0000000001800180018003C00660066003C007E00E700C300C300C3000000000 +1331:000000000600060006000F00198019800F001F8039C030FC30CC30C000000000 +1332:000000000600060006000F00198019800F001F8039C030C030CC30FC00000000 +1333:0000000001800180018003C0066003C007E00E700C700C300030003000000000 +1334:000000000600060006000F00198019800F001F8039C030F830CC30F800000000 +1335:000000000600060006000F0019F819980F001F8039C030C030C030C000000000 +1336:0000000001800180018003C0066003C007E00E700C300C300C000C0000000000 +1337:0000000003000300030007800CC007800FC01CC018E018600060006001F8030C +1338:0000000000000000018003C00660066003C007E00E700C300C300C3000000000 +1339:000000000000000006000F00198019800F001F8039C030FC30CC30C000000000 +133A:000000000000000006000F00198019800F001F8039C030C030CC30FC00000000 +133B:000000000000030007800CC00CC007800FC01CC018E018600060006000000000 +133C:000000000000000006000F00198019800F001F8039C030F030D830F000000000 +133D:000000000000000006000F0019F819980F001F8039C030C030C030C000000000 +133E:000000000000030007800CC00CC007800FC01CE0186018601800180000000000 +133F:000000000000030007800CC00CC007800FC01CC018E018600060006001F8030C +1340:00000000000001E006300C300C300C300FF00C300C300C3007F0060000000000 +1341:000000000000078018C030C030C030C03FC030FC30CC30C01FC0180000000000 +1342:000000007E00C300C300FF00C300C3007F00030003000300033003F000000000 +1343:00007EC3C3FFC3C37F03030303030000 +1344:000000007E00C300C300FF00C300C3007F000300030003E0033003E000000000 +1345:000001800180018007E00E300C300C300FF00C300C300C3007F0060000000000 +1346:0000000003C006600C300FF00C300E7007E003C007000C000C000C0000000000 +1347:0000000001E0033036183FF83618073803F001E0038006000600060000000000 +1348:00000000000000C0004000C00180030006000F00198018880FF803E800000000 +1349:000000000000000000800180030006000C001F00191019F01FC0030006000600 +134A:000000000000018000800180030006000C001E30331031301FE00F8000000000 +134B:000000000000000002000300060004000C001C00360033201FF0031003000300 +134C:00000000018000800180030006000C001E00330031301FE807C8007000000000 +134D:00000000000000000F8019C010C0300030003E0033C037401B00030003000300 +134E:00000000000007E00F9018F03000300030003C003A0031301B600FE000000000 +134F:00000000000002000300060004000C001C00360033201FF0031003000FC01860 +1350:000000000C300FF01FF819980180018001800180018001800180018000000000 +1351:000000000C300FF01FF8199801800180018001F8019801800180018000000000 +1352:000000000C300FF01FF81998018001800180018001800180019801F800000000 +1353:000000000C300FF01FF819980180018001800180030006000C00080000000000 +1354:000000000C300FF01FF819980180018001800180018001F0019801F000000000 +1355:000000000C300FF01FF81998018001E000600060006000600060006000000000 +1356:000000000C300FF01FF819980180018003000300060006000600060000000000 +1357:000000000C300FF01FF81998018001800180018001800180018001800FF01C38 +1358:000018180FF0018001800180030007000E001C00186018701C300FE007C00000 +1359:1C1C07F001C00FFC1FFC3144214422843EFC1C7C000800080010001000100000 +135A:000018180FF0018000800180030006000C001E30331031301FE00F8000000000 +135B:00007FFE7B8E73F67BC67BF6718E7FFE7FFE618E6FB6618E7DB6618E7FFE0000 +135C:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61C66FBE61BE7DBE61C67FFE0000 +135D:1998199800000000000000000000000000000000000000000000000000000000 +135E:0180018000000000000000000000000000000000000000000000000000000000 +135F:0C300C3000000000000000000000000000000000000000000000000000000000 +1360:0000000000000180099004200240199819980240042009900180000000000000 +1361:00000000000303000003030000000000 +1362:0000000000000000000006600660000000000660066000000000000000000000 +1363:000000000000000007E000000180018000000180018000000000000000000000 +1364:000000000000000007E0000001800180000001800180000007E0000000000000 +1365:00000000000000000600060000001F8000000600060000000000000000000000 +1366:000000000000000006000600000003C000000600060000000000000000000000 +1367:0000000000000180018000000000018001800000000001800180000000000000 +1368:000000000000018001800C300C30018001800C300C3001800180000000000000 +1369:0000000018300FE0000001800180030007C00C600C6007C000000FE018300000 +136A:000000000C1807F0000001C00360066007C0060007C0036001C007F00C180000 +136B:0000000000000C3007E0000007E006600600060006000600000007E00C300000 +136C:0000000000000C3007E0000003C0066006600660066003C0000007E00C300000 +136D:0000000018300FE000000300030007E00E600C000C6007E000000FE018300000 +136E:000018300FE0000007800FC00CC000C0018001C0036003C000000FE018300000 +136F:000018300FE0000007800FC00CC000C001800100032003E000000FE018300000 +1370:0000000018180FF000000FF00DB00180018001800FF00C3000000FF018180000 +1371:000000000C3007E0000000000660066007E0066006400380000007E00C300000 +1372:0000000000000C3007E00000018001800180018001800180000007E00C300000 +1373:00000000000018180FF0000007E005A0018003C00660066000000FF018180000 +1374:00000000000018180FF0000005E00DB00DB00DB00DB0073000000FF018180000 +1375:0000000018180FF000000DB00DB00DB007F000300030003000000FF018180000 +1376:000000000C3007E0000003E0066003E0006000C000C000C0000007E00C300000 +1377:0000000018180FF000000FF00DB0018001C000C00FF00C3000000FF018180000 +1378:0000000000000C3007E0000003E006B006E00600066003E0000007E00C300000 +1379:00000000000030181FF000001FF016D006C006C006C006C000001FF030180000 +137A:000018300FE0000007C006C0018001C000C001800180018000000FE018300000 +137B:000000000C3007E0000003C0066007C00600030003000300000007E00C300000 +137C:00000000300C1FF800001E7833CC3EF830C018601860186000001FF8300C0000 +137D:00007FFE7B8E73F67BC67BF6718E7FFE7FFE618E7DB67BB677B6778E7FFE0000 +137E:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61867DBE7B8E77BE77867FFE0000 +137F:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +1380:000000000000000000003FF07FF04490C59F8D159937F1E0F1C0000000000000 +1381:000000003FE07FE0C52C853C8A2FFBE371E0004000400080009800F800000000 +1382:000000001FF83FF86288428845087DF838F800100010003C002403FC03000000 +1383:000000003FE07FE0C53E852A8A2EFBE071E01000100030002000200000000000 +1384:00000000000000000E001F003180318031F831A831B831803180318000000000 +1385:00000000000000000E001F0031B031B031FC318C318031803180318000000000 +1386:00000000000000000E001F003180318031803180318031E031A031E006000600 +1387:0000000000000000038007C00C600C607C7E6C6A0C6E0C600C600C6000000000 +1388:00000000000000C0004000FC0194031C06000F0019B018F00F30000000000000 +1389:000000000000018000B001F0033C060C0C001E00336031E01E60000000000000 +138A:00000000000003000100030006000C001E0011F813A80F3806000C0008000C00 +138B:00000000000000000F8019C010C0300037F03350337033001FE0036003000300 +138C:000000000C300FF01FF819980180018001F801AC01B801800180018000000000 +138D:0000000018601FE03FF0333003000300036003E0031803180300030000000000 +138E:000000000C300FF01FF819980180018001800180018001F001980FF00C000C00 +138F:0000000018601FE03FF033300300030001F801AC01B801800180018000000000 +1390:00000000000000000000000018180000 +1391:000000000000000000000024243C0000 +1392:00001818000000181800000018180000 +1393:00000000000000181800000018180000 +1394:00000000000000000000003C24240000 +1395:00000000000000000000000000000000001800180018003807F0780000000000 +1396:00000000000000000606060E1C600000 +1397:00000000000000000000000000000000000000000000000000007FFE00000000 +1398:00000000000000000000000000000000000000000000480048007FFE00000000 +1399:0000000000606060667E666060600000 +139A:00007FFE7B8E73F67BC67BF6718E7FFE7FFE73866DB671867DB673B67FFE0000 +139B:00007FFE7B8E73F67BC67BF6718E7FFE7FFE738E6DB6718E7DB6738E7FFE0000 +139C:00007FFE7B8E73F67BC67BF6718E7FFE7FFE73C66DBE71BE7DBE73C67FFE0000 +139D:00007FFE7B8E73F67BC67BF6718E7FFE7FFE738E6DB671B67DB6738E7FFE0000 +139E:00007FFE7B8E73F67BC67BF6718E7FFE7FFE73866DBE718E7DBE73867FFE0000 +139F:00007FFE7B8E73F67BC67BF6718E7FFE7FFE73866DBE718E7DBE73BE7FFE0000 +13A0:00000000784442424242424244780000 +13A1:00000000784442424478504844430000 +13A2:000000007F0808080808080808080000 +13A3:000000001C0814122151515155260000 +13A4:000000003048484B494E484848300000 +13A5:00000000080800080808080808080000 +13A6:000000003C424240207F0442423C0000 +13A7:000000001C02225252526242423C0000 +13A8:0000000040404C547640404040400000 +13A9:000000004242424242261A02023C0000 +13AA:0000000018242442427E424242420000 +13AB:00000000040404040404044444380000 +13AC:000000007E4040407C404040407E0000 +13AD:0000000008080848A8BB490A0A0C0000 +13AE:000000003C420202427C404040400000 +13AF:000000001C222222223E2222AACC0000 +13B0:00000000202020203E20202020200000 +13B1:000000007E4240404040404040400000 +13B2:00000000304848484830B7B2B4480000 +13B3:00000000424242425A5A666642420000 +13B4:00000000060909083844444444380000 +13B5:000000003C4242524C40404040400000 +13B6:000000001E204040484C4A4244380000 +13B7:00000000424266665A5A424242420000 +13B8:000000003844020202721E0202020000 +13B9:00000000180A15203C525212120C0000 +13BA:00000000324A4A4A4E4A4A4A4A320000 +13BB:00000000424242427E42424242420000 +13BC:000000003810384402020242423C0000 +13BD:000000004742424242261A02E2443800 +13BE:000000003C424242427E4242423C0000 +13BF:000000004040F0404040404E443C0418 +13C0:0000000078848480809E848484780000 +13C1:000000000C121212122222A2A2420000 +13C2:00000000404040405C62424242420000 +13C3:000000007E02020408102040407E0000 +13C4:000000003844E404E4443C0404040000 +13C5:00000000304848484A4D494848300000 +13C6:00000000FE1010101010101010FE0000 +13C7:000000000C1202424A4A4A4A4A340000 +13C8:00000000661919292A48484848300000 +13C9:00000000F1A122222224242428100000 +13CA:000000001C2222029AA2A2A2A25C0000 +13CB:000000003C4240403C404442423C0000 +13CC:0000000042424242427E4242423C0000 +13CD:000000001C22222202021AD2B26C0000 +13CE:00000000040C142444447E0404040000 +13CF:0000000040404040407C4242427C0000 +13D0:00000000080808080B5D680808080000 +13D1:00000000649AE2448098848484780000 +13D2:00000000784442424458484442420000 +13D3:000000002020202020202022221C0000 +13D4:00000000AAAAAA92B2B2CACA86820000 +13D5:000000003C424740201F0442423C0000 +13D6:00000000F090101010101211110E0000 +13D7:000000000202020202060A1222420000 +13D8:000000007E02020202060A1222420000 +13D9:00000000828282444444282810100000 +13DA:000000003C424240300C0242423C0000 +13DB:00000000364942605048484848300000 +13DC:00000000182424182422555555220000 +13DD:000000001C22424040404040407E0000 +13DE:000000004040404040404040407E0000 +13DF:000000003C42424040404042423C0000 +13E0:000000000444A4A47E24242424180000 +13E1:000000006699999A2844444444380000 +13E2:000000007C4242427C40404040400000 +13E3:000000003C42474040424242423C0000 +13E4:00000000F19112121414141818100000 +13E5:00000040404040434D74444444440000 +13E6:00000000424448506060504844420000 +13E7:00000000020202021E224242221C0000 +13E8:0000000030484A454040454A48300000 +13E9:000000003844444440404E44443B0000 +13EA:00000000225555535131199995620000 +13EB:000000003C424272525E4242423C0000 +13EC:000000003249494971414141221C0000 +13ED:000000000C1212120A06024244380000 +13EE:000000003C424040407C4242423C0000 +13EF:000000001E210101015D494949360000 +13F0:000000001C2222223C222262322C4000 +13F1:000000000E040E1111212129A9660000 +13F2:000000003C424240405C624242420000 +13F3:0000000030484A4540404E44443C0000 +13F4:000000007C4242427C424242427C0000 +13F5:000000000810102020404E4444380000 +13F6:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +13F7:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +13F8:0000000000001C22223C2262322C4000 +13F9:0000000000000E040E111121A9660000 +13FA:0000000000003C4240405C6242420000 +13FB:000000000000304A4540404E443C0000 +13FC:0000000000007C42427C4242427C0000 +13FD:000000000000102020404E4444380000 +13FE:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61866FBE638E6FBE6F867FFE0000 +13FF:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +1400:000000000000007E0000007E00000000 +1401:0000000000000000000000007FFE400220041008081004200240018000000000 +1402:00000180024002400180000001800240042008101008200440027FFE00000000 +1403:00000000000000000000000001800240042008101008200440027FFE00000000 +1404:00000000000001800180000001800240042008101008200440027FFE00000000 +1405:0000000000000C000A00090008800840082008200840088009000A000C000000 +1406:0C000C0000000C000A00090008800840082008200840088009000A000C000000 +1407:0CC00CC000000C000A00090008800840082008200840088009000A000C000000 +1408:0000000000000C000A00090008800A400A200A200A40088009000A000C000000 +1409:0000000000000C000A000900088008400B200B200840088009000A000C000000 +140A:000000000000006000A00120022004200820082004200220012000A000600000 +140B:006000600000006000A00120022004200820082004200220012000A000600000 +140C:0000000000000000000000007FFE400220041008081064206240018000000000 +140D:0000000000000000000000007FFE400220041008081004260246018000000000 +140E:00000000000000000000000001806240642008101008200440027FFE00000000 +140F:00000000000000000000000001800246042608101008200440027FFE00000000 +1410:00000000000001800180000001806240642008101008200440027FFE00000000 +1411:00000000000001800180000001800246042608101008200440027FFE00000000 +1412:0000000000000C000A00090008800840682068200840088009000A000C000000 +1413:0000000000000C000A00090008800840082C082C0840088009000A000C000000 +1414:0C000C0000000C000A00090008800840682068200840088009000A000C000000 +1415:0C000C0000000C000A00090008800840082C082C0840088009000A000C000000 +1416:0000018001800C000A30093008800840082008200840088009000A000C000000 +1417:000000000000006000A00120022004206820682004200220012000A000600000 +1418:000000000000006000A0012002200420082C082C04200220012000A000600000 +1419:006000600000006000A00120022004206820682004200220012000A000600000 +141A:006000600000006000A0012002200420082C082C04200220012000A000600000 +141B:000003000300006018A01920022004200820082004200220012000A000600000 +141C:000000000000000011101110111011100EE00000000000000000000000000000 +141D:0000003000480048003006000900090006000000000000000000000000000000 +141E:00000010102828447C00000000000000 +141F:00000000040810204000000000000000 +1420:00000000402010080400000000000000 +1421:00000000444444443800000000000000 +1422:00000000384444444400000000000000 +1423:00000000780404047800000000000000 +1424:00000000384444443800000000000000 +1425:00000000091224489000000000000000 +1426:00000000242424240000000000000000 +1427:00000000000000001818000000000000 +1428:0000000000007C000000000000000000 +1429:0000000010107C101000000000000000 +142A:000000007C1010101000000000000000 +142B:0000000000000000000800080004FFF480124022204010800900060000000000 +142C:00000000000000000010001000080308048408441020201040087FF800000000 +142D:0000000000001820142012101110108810481040108011001200140018000000 +142E:00000000000001A002A004900890108820882080108008800480028001800000 +142F:0000000000000000000000000000400220041008081004200240018000000000 +1430:0000018002400240018000000180024004200810100820044002000000000000 +1431:0000000000000000000000000180024004200810100820044002000000000000 +1432:0000000000000180018000000180024004200810100820044002000000000000 +1433:00000040201008040202040810204000 +1434:60600040201008040202040810204000 +1435:66660040201008040202040810204000 +1436:00000040201008242222240810204000 +1437:00000040201008043232040810204000 +1438:00000002040810204040201008040200 +1439:06060002040810204040201008040200 +143A:0000000000000000000000000000400220041008081064206240018000000000 +143B:0000000000000000000000000000400220041008081004260246018000000000 +143C:0000000000000000000000000000018062406420081010082004400200000000 +143D:0000000000000000000000000000018002460426081010082004400200000000 +143E:0000000000000000018001800000018062406420081010082004400200000000 +143F:0000000000000000018001800000018002460426081010082004400200000000 +1440:000000000000010000800040002000100C080C08001000200040008001000000 +1441:00000000000004000200010000800040002C002C004000800100020004000000 +1442:018001800000010000800040002000100C080C08001000200040008001000000 +1443:06000600000004000200010000800040002C002C004000800100020004000000 +1444:000000000000001000200040008001001A001A00010000800040002000100000 +1445:00000000000000200040008001000200040C040C020001000080004000200000 +1446:003000300000001000200040008001001A001A00010000800040002000100000 +1447:00600060000000200040008001000200040C040C020001000080004000200000 +1448:00000180018000200C400C800100020004000400020001000080004000200000 +1449:00000000040810201008040000000000 +144A:00000000101010101000000000000000 +144B:00000000202038242400000000000000 +144C:000000000000000000001008100810081008100810081008081007E000000000 +144D:0180024002400180000007E00810100810081008100810081008100800000000 +144E:0000000000000000000007E00810100810081008100810081008100800000000 +144F:0000000001800180000007E00810100810081008100810081008100800000000 +1450:00000000000000000FE0001000080008000800080008000800100FE000000000 +1451:00000300030000000FE0001000080008000800080008000800100FE000000000 +1452:00000CC00CC000000FE0001000080008000800080008000800100FE000000000 +1453:00000000000000000FE0001000080088008800880088000800100FE000000000 +1454:00000000000000000FE0001000080008018801880008000800100FE000000000 +1455:000000000000000003F80400080008000800080008000800040003F800000000 +1456:000000600060000003F80400080008000800080008000800040003F800000000 +1457:000000000000000000000804080408046804680408040804040803F000000000 +1458:00000000000000000000402040204020402C402C4020402020401F8000000000 +1459:0000000000000000000003F00408080408046804680408040804080400000000 +145A:000000000000000000001F80204040204020402C402C40204020402000000000 +145B:0000000000C000C0000003F00408080408046804680408040804080400000000 +145C:000000000600060000001F80204040204020402C402C40204020402000000000 +145D:0000000000000000000007F00008000400046004600400040004000807F00000 +145E:000000000000000000003F80004000200020002C002C0020002000403F800000 +145F:0000000001800180000007F00008000400043004300400040004000807F00000 +1460:000000000C000C0000003F80004000200020002C002C0020002000403F800000 +1461:0000000000000000000001FC0200040004003400340004000400020001FC0000 +1462:000000000000000000000FE0100020002000201820182000200010000FE00000 +1463:0000000000600060000003F80400080008006800680008000800040003F80000 +1464:000000000300030000001FC0200040004000401840184000400020001FC00000 +1465:0000000000000000000003F80400680068000800080068006800040003F80000 +1466:000000003C4040403C00000000000000 +1467:00000000000000000000201420142014201420102010201010200FC000000000 +1468:000000000000000000000FC41024201420142010201020102010201000000000 +1469:00000000000000003F88004800280028002000200020002000403F8000000000 +146A:00000000000000000FE8100820082008200020002000200010000FE000000000 +146B:0000000000384444443C040404040000 +146C:18242418003844444478404040400000 +146D:00000000003844444478404040400000 +146E:00003030003844444478404040400000 +146F:0000000000040404043C444444380000 +1470:00000C0C00040404043C444444380000 +1471:0000363600040404043C444444380000 +1472:00000000004040404078444444380000 +1473:00006060004040404078444444380000 +1474:00000000001C2222221E026262020000 +1475:000000000070888888780B0B08080000 +1476:00000000000E1111111ED0D010100000 +1477:000000000070888888F0868680800000 +1478:00000C0C000E1111111ED0D010100000 +1479:000060600070888888F0868680800000 +147A:0000000000010161610F1111110E0000 +147B:000000000008080B0B78888888700000 +147C:0000030300010161610F1111110E0000 +147D:000018180008080B0B78888888700000 +147E:0000000000101010D0DE1111110E0000 +147F:000000000080808686F0888888700000 +1480:0000181800101010D0DE1111110E0000 +1481:0000C0C00080808686F0888888700000 +1482:00000000001010D0D01ED1D1110E0000 +1483:00000000202020382424180000000000 +1484:000000000404041C2424180000000000 +1485:0000000000728A8A8A78080808080000 +1486:0000000000728A8A8AF0808080800000 +1487:00000000000A0A0A0A78888888700000 +1488:00000000004242424278444444380000 +1489:00000000003844444404040404040000 +148A:30484830003844444440404040400000 +148B:00000000003844444440404040400000 +148C:00003030003844444440404040400000 +148D:00000000000404040404444444380000 +148E:00000C0C000404040404444444380000 +148F:00003636000404040404444444380000 +1490:00000000004040404040444444380000 +1491:00006060004040404040444444380000 +1492:00000000001C22222202C2C202020000 +1493:00000000007088888B0B080808080000 +1494:00000000000E1111D1D0101010100000 +1495:00000000007088888880868680800000 +1496:00000C0C000E1111D1D0101010100000 +1497:000060600070888888808C8C80800000 +1498:00000000000202C2C2022222221C0000 +1499:00000000000808080B0B888888700000 +149A:00000606000202C2C2022222221C0000 +149B:000018180008080B0B08888888700000 +149C:0000000000101010D0D01111110E0000 +149D:00000080808080868680888888700000 +149E:0000181800101010D0D01111110E0000 +149F:0000C0C0008080868680888888700000 +14A0:0000000000101010D0D011D1D10E0000 +14A1:00000000202020202424180000000000 +14A2:00000000040404042424180000000000 +14A3:00000000007C04040404040404040000 +14A4:30484830007C40404040404040400000 +14A5:00000000007C40404040404040400000 +14A6:00003030007C40404040404040400000 +14A7:000000000004040404040404047C0000 +14A8:00000C0C0004040404040404047C0000 +14A9:000036360004040404040404047C0000 +14AA:000000000040404040404040407C0000 +14AB:000060600040404040404040407C0000 +14AC:00000000001F01016161010101010000 +14AD:0000000000F808080B0B080808080000 +14AE:00000000001F1010D0D0101010100000 +14AF:0000000000F880808686808080800000 +14B0:00000C0C001F1010D0D0101010100000 +14B1:00003030007C40404646404040400000 +14B2:000000000001010161610101011F0000 +14B3:00000000000808080B0B080808F80000 +14B4:0000060600020202C2C20202023E0000 +14B5:00001818000808080B0B080808F80000 +14B6:0000000000101010D0D01010101F0000 +14B7:00000000008080808686808080F80000 +14B8:0000181800101010D0D01010101F0000 +14B9:000060600040404046464040407C0000 +14BA:00000000001010D0D010D0D0101F0000 +14BB:0000000020202020203C000000000000 +14BC:000000001C20201C0000000000000000 +14BD:0000000004040404043C000000000000 +14BE:00000000182408103C00000000000000 +14BF:000000003C42020204081020407E0000 +14C0:0000000000000000000000000000000000001FE001100110011000E000000000 +14C1:0000000000000000030004800480030000000FF01100110011000E0000000000 +14C2:0000000000000000000000000000000000000FF01100110011000E0000000000 +14C3:0000000000000000000000000300030000000FF01100110011000E0000000000 +14C4:00000000000000000000000000000000000000E00110011001101FE000000000 +14C5:00000000000000000000000000C000C0000000E00110011001101FE000000000 +14C6:00000000000000000000000006600660000000E00110011001101FE000000000 +14C7:0000000000000000000000000000000000000E001100110011000FF000000000 +14C8:000000000000000000000000030003000000070008800880088007F800000000 +14C9:00000000000000000000000000000000000007F8304430440044003800000000 +14CA:0000000000000000000000000000000000003FC0022C022C022001C000000000 +14CB:000000000000000000000000000000000000038004403440344003FC00000000 +14CC:0000000000000000000000000000000000000E301130110011000FF000000000 +14CD:000000000000000000000000030003000000038004403440344003FC00000000 +14CE:0000000000000000000000000C000C0000000E301130110011000FF000000000 +14CF:0000000000000000000000001980198000000E001100110011000FF000000000 +14D0:000000003048483F0000000000000000 +14D1:000000002222221C0000000000000000 +14D2:000000000609097E0000000000000000 +14D3:0000000000000000000000000000000000001FE000100010001000E000000000 +14D4:0000000000000000060009000900060000000FF01000100010000E0000000000 +14D5:0000000000000000000000000000000000000FF01000100010000E0000000000 +14D6:0000000000000000000000000600060000000FF01000100010000E0000000000 +14D7:00000000000000000000000000000000000000E00010001000101FE000000000 +14D8:00000000000000000000000000C000C0000000E00010001000101FE000000000 +14D9:00000000000000000000000003300330000000E00010001000101FE000000000 +14DA:0000000000000000000000000000000000000E001000100010000FF000000000 +14DB:000000000000000000000000030003000000070008000800080007F800000000 +14DC:00000000000000000000000000000000000007F8300430040004003800000000 +14DD:0000000000000000000000000000000000003FC0002C002C002001C000000000 +14DE:00000000000000000000000000000000000003FC340034000400038000000000 +14DF:0000000000000000000000000000000000001FE0200C200C20001C0000000000 +14E0:00000000000000000000000001800180000003FC340034000400038000000000 +14E1:0000000000000000000000000C000C0000001FE0200C200C20001C0000000000 +14E2:00000000000000000000000000000000000018E01810001000101FE000000000 +14E3:00000000000000000000000000000000000001C0002C002C00203FC000000000 +14E4:00000000000000000000000000600060000018E01810001000101FE000000000 +14E5:00000000000000000000000000C000C0000001C0002C002C00203FC000000000 +14E6:000000000000000000000000000000000000038034003400040003FC00000000 +14E7:000000000000000000000000000000000000071808180800080007F800000000 +14E8:000000000000000000000000030003000000038034003400040003FC00000000 +14E9:0000000000000000000000000C000C0000000E301030100010000FF000000000 +14EA:000000006080807E0000000000000000 +14EB:000000000C300C300C00000000000000 +14EC:000000061860300C020C306018060000 +14ED:0000000040404040201C040404040000 +14EE:0C12120C000404040870404040400000 +14EF:00000000040404040870404040400000 +14F0:000C0C00040404040408704040400000 +14F1:000000000404041C2040404040400000 +14F2:000C0C000404041C2040404040400000 +14F3:006666000404041C2040404040400000 +14F4:00000000404040700804040404040000 +14F5:00606000404040700804040404040000 +14F6:00000000202020202010CEC202020000 +14F7:00000000808080868640380808080000 +14F8:00000000020202C2C204382020200000 +14F9:00000000080808080810E68680800000 +14FA:00060600020202C2C204382020200000 +14FB:00181800080808080810E68680800000 +14FC:000000000262620E1020202020200000 +14FD:000000000404041C2046464040400000 +14FE:000606000262620E1020202020200000 +14FF:000C0C000404041C2046464040400000 +1500:000000004040407008C4C40404040000 +1501:00000000808086E61008080808080000 +1502:006060004040407008C4C40404040000 +1503:00C0C000808086E61008080808080000 +1504:0000000010D0D01C02C1C10101010000 +1505:00000000202030080808000000000000 +1506:00000000182010083000000000000000 +1507:00000000080818202020000000000000 +1508:000000002020201C0000000000000000 +1509:00000000202038041C24180000000000 +150A:0000000004041C203824180000000000 +150B:00303000202030080808001818000000 +150C:000018001800000410081010182004400480048000400C200C10000800040000 +150D:000060006000000040FE4100620012001200120002003200310000FE00000000 +150E:00000000180018000000108010801880048004F0048800880C880C7000000000 +150F:0000000018001800000010801080188004800480048800880C880C7000000000 +1510:000000000000000000000E00110011001100010001100110011000E000000000 +1511:0000000000000000000000E001100110011001001100110011000E0000000000 +1512:0000000000C000C0000000E001100110011001001100110011000E0000000000 +1513:0000000000000000000000000000000000000C601210111010900C6000000000 +1514:0000000000000000000001800180000000000C601210111010900C6000000000 +1515:0000000000000000000000000000000000000C601090111012100C6000000000 +1516:0000000000000000000001800180000000000C601090111012100C6000000000 +1517:0000000000000000000007000880088008800080308830880088007000000000 +1518:000000000000000000001C00220022182218020002200220022001C000000000 +1519:0000000000000000000000700088308830880080088008800880070000000000 +151A:0000000000000000000001C002200220022002002218221822001C0000000000 +151B:0000000000600060000000700088308830880080088008800880070000000000 +151C:0000000001800180000001C002200220022002002218221822001C0000000000 +151D:0000000000000000000000000000000000003318348404440424031800000000 +151E:00000000000000000000000000000000000018CC242C2220212018C000000000 +151F:0000000000000000000000C000C0000000003318348404440424031800000000 +1520:00000000000000000000030003000000000018CC242C2220212018C000000000 +1521:0000000000000000000000000000000000003318348404440424031800000000 +1522:00000000000000000000000000000000000018CC212C2220242018C000000000 +1523:0000000000000000000000C000C0000000003318342404440484031800000000 +1524:0000000000000000000003000300000000000C661096111012100C6000000000 +1525:00000000485424000000000000000000 +1526:00000000040810207C04040404040000 +1527:18242418402010087C40404040400000 +1528:00000000402010087C40404040400000 +1529:00606000402010087C40404040400000 +152A:0000000004040404047C201008040000 +152B:000C0C0004040404047C201008040000 +152C:0066660004040404047C201008040000 +152D:0000000040404040407C081020400000 +152E:0060600040404040407C081020400000 +152F:000000000204C8D03E02020202020000 +1530:0000000008102343F808080808080000 +1531:00000000100804C2DF10101010100000 +1532:0000000080402616F880808080800000 +1533:00181800100804C2DF10101010100000 +1534:00C0C00080402616F880808080800000 +1535:0000000002020202023ED0C804020000 +1536:000000000808080808FB432010080000 +1537:0006060002020202023ED0C804020000 +1538:001818000808080808FB432010080000 +1539:000000001010101010DFC20408100000 +153A:000000008080808080F8162640800000 +153B:001818001010101010DFC20408100000 +153C:00C0C0008080808080F8162640800000 +153D:000000001010D0D0101FC2C408100000 +153E:0000000020203C081020000000000000 +153F:00000000282854540000000000000000 +1540:0000000010107C101000000000000000 +1541:00000000000044281028440000000000 +1542:0000000000000000000000000000000010F010801080108010800F0000000000 +1543:000000000000000000000000000000001E10021002100210021001E000000000 +1544:0000000000000000000000000000000001E002100210021002101E1000000000 +1545:000000000000060009000900060000000F00108010801080108010F000000000 +1546:000000000000000000000000000000000F00108010801080108010F000000000 +1547:000000000000000000000600060000000F00108010801080108010F000000000 +1548:00000000007C020202027C4040400000 +1549:00003030007C020202027C4040400000 +154A:00000000004040407C020202027C0000 +154B:00000000003E404040403E0202020000 +154C:00001818003E404040403E0202020000 +154D:00000000000202023E404040403E0000 +154E:00000C0C001F202020201FC1C1010000 +154F:00003030007C808083837C0404040000 +1550:00000000182020180808000000000000 +1551:00000000300C300C3000000000000000 +1552:0000006018060C3040300C0618600000 +1553:0000000000000000000000001800240224041808081004200240018000000000 +1554:0000000001800240024001800000018002400420081018082404240218000000 +1555:0000000000000000000000000000018002400420081018082404240218000000 +1556:0000000000000000018001800000018002400420081018082404240218000000 +1557:0000000000000000060009000980064000200010001000200040008001000200 +1558:0000060006000000060009000980064000200010001000200040008001000200 +1559:0000000000000000006000900190026004000800080004000200010000800040 +155A:0000006000600000006000900190026004000800080004000200010000800040 +155B:0000001800180000001800240064009801003200320001000080004000200010 +155C:0000018001800000018002400640098010002018201810000800040002000100 +155D:0000000C122C40201008000000000000 +155E:000000000000000000000C08120812081C08100810081008081007E000000000 +155F:000000000000000000001030104810481038100810081008081007E000000000 +1560:0000000000000000000007E008101008100810081C08120812080C0800000000 +1561:0000000000000000000007E00810100810081008103810481048103000000000 +1562:0000000001800180000007E008101008100810081C08120812080C0800000000 +1563:0000000001800180000007E00810100810081008103810481048103000000000 +1564:000000000000000007E0091009080608000800080008000800100FE000000000 +1565:000001800180000007E0091009080608000800080008000800100FE000000000 +1566:000000000000000003F00448084808300800080008000800040003F800000000 +1567:000000C000C0000003F00448084808300800080008000800040003F800000000 +1568:000000600060000001F80224042404183400340004000400020001FC00000000 +1569:00000300030000000FC01120212020C0200C200C2000200010000FE000000000 +156A:000000001C2A2A24201E000000000000 +156B:000000000000000000001110111011101110111010101010082007C000000000 +156C:0000000000000000000007C00820101010101110111011101110111000000000 +156D:000000000000000000001FC00020001000101F100010001000201FC000000000 +156E:0000000000000000000003F804000800080008F808000800040003F800000000 +156F:000000000000000008102A541C3808101C382A54081000000000000000000000 +1570:000000000000000000001450145014501450139010101010082007C000000000 +1571:0000000000000000000007C00820101010101390145014501450145000000000 +1572:000000000000000000001FC000201E100110011001101E1000201FC000000000 +1573:0000000000000000000003F8040008780880088008800878040003F800000000 +1574:000000000000000000000E001100110011000F00012001400180010000000000 +1575:0000000000000000000001C002200220022003C012000A000600020000000000 +1576:0000000001800180000001C002200220022003C012000A000600020000000000 +1577:0000000000000000000001000180014001200F001100110011000E0000000000 +1578:0000000003000300000001000180014001200F001100110011000E0000000000 +1579:00000000000000000000020006000A00120003C002200220022001C000000000 +157A:00000000030003000000020006000A00120003C002200220022001C000000000 +157B:000000001030501C12120C0000000000 +157C:0000000000424242427E424242420000 +157D:00000000442810284400000000000000 +157E:003000480048003000001C70208820881C8804F0048000800080008000000000 +157F:000000000000000000001C70208820881C8804F0048000800080008000000000 +1580:000000000060006000001C70208820881C8804F0048000800080008000000000 +1581:000000000000000000001C08200820081C080478048800880088007000000000 +1582:000000000018001800001C08200820081C080478048800880088007000000000 +1583:000000000000000000001C80208020801C8004F0048800880088007000000000 +1584:0000000000C000C000001C80208020801C8004F0048800880088007000000000 +1585:0000000000000000000006400840087006480248023000000000000000000000 +1586:00000000000E1111110F050509090000 +1587:00000000000E1111111E141412120000 +1588:0000000000090905050F1111110E0000 +1589:0000000000121214141E1111110E0000 +158A:000000000000000000000E001100110011000100012001400180010000000000 +158B:0000000000000000000001C0022002200220020012000A000600020000000000 +158C:00000000000000000000010001800140012001001100110011000E0000000000 +158D:00000000000000000000020006000A001200020002200220022001C000000000 +158E:000C00120012000C0000301C482248223C2204A004A003200020002000000000 +158F:00000000000000000000301C482248223C2204A004A003200020002000000000 +1590:00000000001800180000301C482248223C2204A004A003200020002000000000 +1591:000000000000000000003002480248023C02048204A203220022001C00000000 +1592:000000000006000600003002480248023C02048204A203220022001C00000000 +1593:000000000000000000003020482048203C2004A004A203220022001C00000000 +1594:000000000030003000003020482048203C2004A004A203220022001C00000000 +1595:0000000000000000000006000900090007800090009000600000000000000000 +1596:0000000000000000000031804A404A403FE00024002400180000000000000000 +1597:00000000003C424A4A32020202020000 +1598:00000000003C4252524C404040400000 +1599:000000000002020202324A4A423C0000 +159A:0000000000404040404C5252423C0000 +159B:00000000000000000000000000001FE000001FE001100110011000E000000000 +159C:00000000000000000000000000000FF000000FF01100110011000E0000000000 +159D:00000000000000000000000000001FE0000000E00110011001101FE000000000 +159E:00000000000000000000000000001FE000000E001100110011000FF000000000 +159F:0000003F003048483F00000000000000 +15A0:0000000000000000000000000080004000200FF01000100010000E0000000000 +15A1:0000000000000180018000000080004000200FF01000100010000E0000000000 +15A2:00000000000000000000000000E00010001000101FE008000400020000000000 +15A3:00000000000000C000C0000000E00010001000101FE008000400020000000000 +15A4:0000000000000000000000000E001000100010000FF000200040008000000000 +15A5:0000000000000600060000000E001000100010000FF000200040008000000000 +15A6:000000003040403C0810000000000000 +15A7:00000000040810207C043E0404040000 +15A8:00000000201008043E207C2020200000 +15A9:00606000201008043E207C2020200000 +15AA:000000000404043E047C201008040000 +15AB:000C0C000404043E047C201008040000 +15AC:000000002020207C203E040810200000 +15AD:003030002020207C203E040810200000 +15AE:000000002078203C0810200000000000 +15AF:0000000000808080BCC28282C2BC0000 +15B0:0000000000BCFEFEFEFEBC8080800000 +15B1:00000000000202027AFEFEFEFE7A0000 +15B2:0000000000808080BCFEFEFEFEBC0000 +15B3:00000000007AFEFEFEFE7A0202020000 +15B4:00000000007C4040407C404040400000 +15B5:0000000000040404047C0404047C0000 +15B6:0000000000404040407C4040407C0000 +15B7:00000000007C0404047C040404040000 +15B8:000000000000000000000E100A100A1009E00800080008000800080000000000 +15B9:0000000000000000000000100010001000100010079008500850087000000000 +15BA:000000000000000000000800080008000800080009E00A100A100E1000000000 +15BB:0000000000000000000008700850085007900010001000100010001000000000 +15BC:000000000000000000000C100A20094008800800080008000800080000000000 +15BD:0000000000000000000000100010001000100010011002900450083000000000 +15BE:0000000000000000000008000800080008000800088009400A200C1000000000 +15BF:0000000000000000000008300450029001100010001000100010001000000000 +15C0:0000000000000000000000100010001007100890089000500050003000000000 +15C1:0000000000000000000008000800080008E0091009100A000A000C0000000000 +15C2:0000000000000000000000300050005008900890071000100010001000000000 +15C3:000000000000000000000C000A000A000910091008E008000800080000000000 +15C4:00000000000000000000000000004002200410080FF004200240018000000000 +15C5:00000000000000000000000000000180024004200FF010082004400200000000 +15C6:0000000008000400020001000180014001200120014001800100020004000800 +15C7:0000000008000400020001000180054005200520054001800100020004000800 +15C8:000000000800040002000100018001400D200D20014001800100020004000800 +15C9:00000000004000800100020006000A00120012000A0006000200010000800040 +15CA:000000000000000000000000000040023FFC1008081004200240018000000000 +15CB:0000000000000000000000000000018002400420081010083FFC400200000000 +15CC:0000000008000400060005000480044004200420044004800500060004000800 +15CD:0000000008000400060005000480054005200520054004800500060004000800 +15CE:0000000008000400060005000480044005A005A0044004800500060004000800 +15CF:0000000000400080018002800480088010801080088004800280018000800040 +15D0:0000000000000000000000000000410421081110092005400380010000000000 +15D1:0000000000000000000000000000010003800540092011102108410400000000 +15D2:0000000004000200010000800040002007F00020004000800100020004000000 +15D3:000000000400020001000080044004200FF00420044000800100020004000000 +15D4:000000000400020001000080004006200FF00620004000800100020004000000 +15D5:000000000020004000800100020004000FE00400020001000080004000200000 +15D6:0000000000000000000000000000410421081FF0092005400380010000000000 +15D7:000000000000000000000000000001000380054009201FF02108410400000000 +15D8:0000000004000200010001800140012007F00120014001800100020004000000 +15D9:000000000400020001000180054005200FF00520054001800100020004000000 +15DA:00000000040002000100018001400D201FF00D20014001800100020004000000 +15DB:0000000000100020004000C00140024007F00240014000C00040002000100000 +15DC:000000000000000000001FF8100810081008100810081008081007E000000000 +15DD:0000000000000000000007E008101008100810081008100810081FF800000000 +15DE:00000000000000001FC0102010101010101010101010101010201FC000000000 +15DF:00000000000000001FC0102010101110111011101110101010201FC000000000 +15E0:00000000000000001FC0102010101010131013101010101010201FC000000000 +15E1:000000000000000007F00810101010101010101010101010081007F000000000 +15E2:000000000000000000001818142812481188100810081008081007E000000000 +15E3:0000000000000000000007E00810100810081008118812481428181800000000 +15E4:00000000000000001FE0101008080408020802080408080810101FE000000000 +15E5:00000000000000001FE0101008080448024802480448080810101FE000000000 +15E6:00000000000000001FE010100808040802C802C80408080810101FE000000000 +15E7:000000000000000007F80808101010201040104010201010080807F800000000 +15E8:0000000000000000000010081008100810081FF810081008081007E000000000 +15E9:0000000000000000000007E00810100810081FF8100810081008100800000000 +15EA:00000000000000001FC0042004100410041004100410041004201FC000000000 +15EB:00000000000000001FC0042004100490049004900490041004201FC000000000 +15EC:00000000000000001FC0042004100410059005900410041004201FC000000000 +15ED:000000000000000007F00840104010401040104010401040084007F000000000 +15EE:00000000101010107C00000000000000 +15EF:00000000000000000000410441044104410441044104410422881C7000000000 +15F0:000000000000000000001C702288410441044104410441044104410400000000 +15F1:000000000000000000000FE00010001000100FE00010001000100FE000000000 +15F2:000000000000000000000FE00010001002100FE00210001000100FE000000000 +15F3:000000000000000000000FE00010001006100FE00610001000100FE000000000 +15F4:0000000000000000000007F008000800080007F008000800080007F000000000 +15F5:000000000000000000007FFC41044104410441044104410422881C7000000000 +15F6:000000000000000000001C7022884104410441044104410441047FFC00000000 +15F7:000000000000000000000FE00810081008100FE00810081008100FE000000000 +15F8:000000000000000000000FE00810081008900FE00890081008100FE000000000 +15F9:000000000000000000000FE00810081009900FE00990081008100FE000000000 +15FA:0000000000000000000007F008100810081007F008100810081007F000000000 +15FB:00000000000000000000610C593447C4410441044104410422881C7000000000 +15FC:000000000000000000001C702288410441044104410447C45934610C00000000 +15FD:000000000000000000000FE00810041002100FE00210041008100FE000000000 +15FE:000000000000000000000FE00810041002500FE00250041008100FE000000000 +15FF:000000000000000000000FE00810041002D00FE002D0041008100FE000000000 +1600:0000000000000000000007F008100820084007F008400820081007F000000000 +1601:00000000442810000000000000000000 +1602:00000000004040404040444444380000 +1603:00000000003844444404040404040000 +1604:0000000000000000000000000000000000000FF0000800080008007000000000 +1605:0000000000000000000000000000000000000FF0000800480048000800700000 +1606:0000000000000000000000000000000000000FF0000800680068000800700000 +1607:000000000000000000000000000000000000070008000800080007F800000000 +1608:00000000000000000000400040004100410041044104410422881C7000000000 +1609:000000000000000000001C702288410441044104010401040004000400000000 +160A:000000000000000000001FE000100010001007E000100010001001E000000000 +160B:000000000000000000001FE000100410041007E004100410001001E000000000 +160C:000000000000000000001FE000100010031007E003100010001001E000000000 +160D:000000000000000000000F001000100010000FC01000100010000FF000000000 +160E:000000000000000000001070108810881088104810081008081007E000000000 +160F:0000000000000000000007E008101008100812081108110811080E0800000000 +1610:00000000000000000FE00010000800080008070808880808081007E000000000 +1611:00000000000000000FE00010000800080088078808880808081007E000000000 +1612:00000000000000000FE0001000080008018807C809880808081007E000000000 +1613:000000000000000003F00408080808880870080008000800040003F800000000 +1614:000000000000000007F8003000C00100020004E005100410022001C000000000 +1615:00000000000000000FF00600018000400020039004500410022001C000000000 +1616:000000000000000001C0022004100450039000200040018006000FF000000000 +1617:00000000000000000000000010E0111012481488148818901860100000000000 +1618:00000000000000000000000021E02210244828C829483108311020E000000000 +1619:00000000000000000000000021F02208246428F429643104310820F000000000 +161A:000000000000000000000000100018601890148814881248111010E000000000 +161B:0000000000000000000000000008061809181128112812480888070800000000 +161C:000000000000100008780580020002000400047004880408020801F000000000 +161D:00000000000000000F801040102011200E2000200040004001A01E1000080000 +161E:000000000000200011F00A08040404C40904090808F010001000100000000000 +161F:000000000000200011F00A08044404C40944090808F010001000100000000000 +1620:000000000000200011F00A08046404E40964090808F010001000100000000000 +1621:000000000000000000000E081108110811081210101008600790000800040000 +1622:000000000000000000000000000000003C04040404040404020801F000000000 +1623:000000000000000000000000000000000F801040202020202020203C00000000 +1624:0000000000000400040004000780004000200020002000200040078000000000 +1625:0000000000000400040004000780004001200120012001200040078000000000 +1626:0000000000000400040004000780004000200320032000200040078000000000 +1627:00000000000000200020002001E002000400040004000400020001E000000000 +1628:000000000000000000000000000020003C04240404040404020801F000000000 +1629:000000000000000000000000000000000F801040202020202024203C00040000 +162A:0000000000000E00040004000780004000200020002000200040078000000000 +162B:0000000000000E00040004000780004001200120012001200040078000000000 +162C:0000000000000E00040004000780004000200320032000200040078000000000 +162D:00000000000000E00040004003C004000800080008000800040003C000000000 +162E:000000000000000000001E78042008101008100810081008081007E000000000 +162F:0000000000000000000007E008101008100810081008081004201E7800000000 +1630:000000000000080008000FE00010000800080008000800100FE0080008000000 +1631:000000000000080008000FE00010008800880088008800100FE0080008000000 +1632:000000000000080008000FE00010000801880188000800100FE0080008000000 +1633:0000000000000008000803F804000800080008000800040003F8000800080000 +1634:00000000000000000000000000000002701E101210101010082007C000000000 +1635:0000000000000000000000000000000003E00410080808084808780E40000000 +1636:000000001C00080008000FE00010000800080008000800100FE0080008000000 +1637:000000001C00080008000FE00010008800880088008800100FE0080008000000 +1638:000000001C00080008000FE00010000801880188000800100FE0080008000000 +1639:0000000000380010001007F008001000100010001000080007F0001000100000 +163A:000000000000000000000002610E210A210821082108210821081EF000000000 +163B:0000000000000000000000000F78108410841084108410845084708640000000 +163C:0000000000001C0008000FE00010001000100FE00010001000100FE008000000 +163D:0000000000001C0008000FE00010001008100FE00810001000100FE008000000 +163E:0000000000001C0008000FE0001000100C100FE00C10001000100FE008000000 +163F:000000000000007000200FE01000100010000FE01000100010000FE000200000 +1640:000000000000000000001818042004200810100810081008081007E000000000 +1641:0000000000000000000007E00810100810081008081004200420181800000000 +1642:000000000000000023E02410180800080008000800081808241023E000000000 +1643:000000000000000023E02410180800880088008800881808241023E000000000 +1644:000000000000000023E02410180800080188018800081808241023E000000000 +1645:00000000000000000F88104820302000200020002000203010480F8800000000 +1646:000000007C0810207C00000000000000 +1647:000010107C0810207C10100000000000 +1648:00000000000000000000339809200920101020082008200810100FE000000000 +1649:000000000000000000000FE01010200820082008101009200920339800000000 +164A:00000000000023E024101808000820083808200800081808241023E000000000 +164B:00000000000023E024101808008820883888208800881808241023E000000000 +164C:00000000000023E024101808000820C839E820C800081808241023E000000000 +164D:0000000000000F881048203020002008203820082000203010480F8800000000 +164E:00000000000000000000000021081110111021082108210821081EF000000000 +164F:0000000000000000000000001EF0210821082108210811101110210800000000 +1650:00000000000009E006100010001000100FE0001000100010061009E000000000 +1651:00000000000009E006100010001002100FE0021000100010061009E000000000 +1652:00000000000009E006100010001003100FE0031000100010061009E000000000 +1653:0000000000000790086008000800080007F00800080008000860079000000000 +1654:000000000000000000000000210811101FF021082108210821081EF000000000 +1655:0000000000000000000000001EF021082108210821081FF01110210800000000 +1656:00000000000013E00C100408040804081FF00408040804080C1013E000000000 +1657:00000000000013E00C100408048804881FF00488048804080C1013E000000000 +1658:00000000000013E00C100408040804C81FF004C8040804080C1013E000000000 +1659:00000000000007C808301020102010200FF8102010201020083007C800000000 +165A:000010103C4038047810100000000000 +165B:000000000000000000000000238811101FF021082108210821081EF000000000 +165C:0000000000000000000000001EF021082108210821081FF01110238800000000 +165D:00000000000013E00C100408040814081FF01408040804080C1013E000000000 +165E:00000000000013E00C100408048814881FF01488048804080C1013E000000000 +165F:00000000000013E00C100408040814C81FF014C8040804080C1013E000000000 +1660:00000000000013E00C100408040814081FF01408040804080C1013E000000000 +1661:00000000000000000000000023881110111021082108210821081EF000000000 +1662:0000000000000000000000001EF0210821082108210811101110238800000000 +1663:00000000000009E006100010001008100FE0081000100010061009E000000000 +1664:00000000000009E00610001000100A100FE00A1000100010061009E000000000 +1665:00000000000009E00610001000100B100FE00B1000100010061009E000000000 +1666:0000000000000790086008000800081007F00810080008000860079000000000 +1667:00000000000000000000000023881110193025482388210821081EF000000000 +1668:0000000000000000000000001EF0210821082388254819301110238800000000 +1669:00000000000027E018100808040822083FF0220804080808181027E000000000 +166A:00000000000027E018100808044822483FF0224804480808181027E000000000 +166B:00000000000027E018100808040822683FF0226804080808181027E000000000 +166C:0000000000000FC810302020204020881FF820882040202010300FC800000000 +166D:00000000424224241818242442420000 +166E:00000000000000000044281028440000 +166F:000000000000000000001C70208820881C880478040800080008000800000000 +1670:00000000000000000000301C482248223C220482048203020002000200000000 +1671:00000000000000000000281C542254223E2202A002A001200020002000000000 +1672:00000000001800180000281C542254223E2202A002A001200020002000000000 +1673:000000000000000000002802540254023E02028202A201220022001C00000000 +1674:000000000006000600002802540254023E02028202A201220022001C00000000 +1675:000000000000000000002820542054203E2002A002A201220022001C00000000 +1676:000000000030003000002820542054203E2002A002A201220022001C00000000 +1677:0000000008102646F8087C0808080000 +1678:00000000402313087C40F84040400000 +1679:00606000402313087C40F84040400000 +167A:000000000808087C08F8462610080000 +167B:001818000808087C08F8462610080000 +167C:00000000404040F8407C0B1320400000 +167D:00606000404040F8407C0B1320400000 +167E:000000107C107C100000000000000000 +167F:000000007C007C000000000000000000 +1680:0000000000000000000000000000FFFF00000000000000000000000000000000 +1681:0000000000000000000000000000FFFF01000100010001000100010000000000 +1682:0000000000000000000000000000FFFF02800280028002800280028000000000 +1683:0000000000000000000000000000FFFF05400540054005400540054000000000 +1684:0000000000000000000000000000FFFF0AA00AA00AA00AA00AA00AA000000000 +1685:0000000000000000000000000000FFFF15501550155015501550155000000000 +1686:0000010001000100010001000100FFFF00000000000000000000000000000000 +1687:0000028002800280028002800280FFFF00000000000000000000000000000000 +1688:0000054005400540054005400540FFFF00000000000000000000000000000000 +1689:00000AA00AA00AA00AA00AA00AA0FFFF00000000000000000000000000000000 +168A:0000155015501550155015501550FFFF00000000000000000000000000000000 +168B:0000000000400040008000800100FFFF01000200020004000400000000000000 +168C:0000000000A000A0014001400280FFFF0280050005000A000A00000000000000 +168D:000000000150015002A002A00540FFFF05400A800A8015001500000000000000 +168E:0000000002A802A8055005500AA0FFFF0AA0154015402A802A80000000000000 +168F:00000000055405540AA80AA81550FFFF15502AA02AA055405540000000000000 +1690:0000000000000000000001000100FFFF01000100000000000000000000000000 +1691:0000000000000000000002800280FFFF02800280000000000000000000000000 +1692:0000000000000000000005400540FFFF05400540000000000000000000000000 +1693:000000000000000000000AA00AA0FFFF0AA00AA0000000000000000000000000 +1694:0000000000000000000015501550FFFF15501550000000000000000000000000 +1695:0000000004400440028002800100FFFF01000280028004400440000000000000 +1696:0000010001000280028004400440FFFF04400440028002800100010000000000 +1697:0000000000000000000000000000FFFF0800080009C0084008400FC000000000 +1698:0000000000000000000000000000FFFF1290092006C006C00920129024480000 +1699:05500FF805500FF805500FF80550FFFF00000000000000000000000000000000 +169A:0000000000000000000000000000FFFF00000FF0000000000000000000000000 +169B:000000002000100008000400020001FF02000400080010002000000000000000 +169C:0000000000040008001000200040FF8000400020001000080004000000000000 +169D:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE738E6DB671B67DB6738E7FFE0000 +169E:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE73866DBE718E7DBE73867FFE0000 +169F:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE73866DBE718E7DBE73BE7FFE0000 +16A0:0092A4C890A0C0808080808080808000 +16A1:00AA94A8D0A0C0808080808080808000 +16A2:0080C0A0908884848484848484848400 +16A3:0080C0A0908884829292929292929200 +16A4:0080C0A090888484B4B4848484848400 +16A5:0080C0A0908884C2A292929292929200 +16A6:00808080C0A090888890A0C080808000 +16A7:00808080C0A090A8A890A0C080808000 +16A8:0080C0A090C8A0908880808080808000 +16A9:0080C2A498C2A4988080808080808000 +16AA:0080C2A498C0A0908080808080808000 +16AB:0080C0A090C8A0908880808080808000 +16AC:00101090503090583412181412101000 +16AD:00101010101018141218141210101000 +16AE:00080808080818284818284808080808 +16AF:00101012141812345890305090101000 +16B0:00101012141810305090305090101000 +16B1:0080C0A09088848890A0A09088848200 +16B2:00000004081020402010080400000000 +16B3:008080808080808080C0A09088848200 +16B4:0082848890A0C0808080808080808000 +16B5:00B2B48890A0C0808080808080808000 +16B6:0042444850E0E0E04040404040404000 +16B7:00828244442828101028284444828200 +16B8:00828244442828545428284444828200 +16B9:0080C0A0908890A0C080808080808000 +16BA:008282828282E2928E82828282828200 +16BB:0082828282E2928EE2928E8282828200 +16BC:00101010925438103854921010101000 +16BD:00101010101038383810101010101000 +16BE:00101010905030101814121010101000 +16BF:00202020202030282422202020202000 +16C0:00101010905038383814121010101000 +16C1:00101010101010101010101010101000 +16C2:00101010101038383810101010101000 +16C3:00000010204088442204081000000000 +16C4:00101010103854929254381010101000 +16C5:00101010121418103050901010101000 +16C6:00080808080808182848880808080800 +16C7:00101814121010101010109050301000 +16C8:0082C4A89080808080808090A8C48200 +16C9:00929254543838101010101010101000 +16CA:00081020402010081020402010080000 +16CB:0040404040444C546444040404040400 +16CC:00101010101010100000000000000000 +16CD:00101010101038383800000000000000 +16CE:00101010109254381000000000000000 +16CF:00103854921010101010101010101000 +16D0:00081828488808080808080808080800 +16D1:000818284888081C1C1C080808080800 +16D2:00605048444850606050484448506000 +16D3:00404044485064485060404040404000 +16D4:00C0A090A890A0C0C0A090A890A0C000 +16D5:0082848890A0C08080C0A09088848200 +16D6:0082C6C6AAAA92928282828282828200 +16D7:0082C6AA92AAC6828282828282828200 +16D8:00929254543838101010101010101000 +16D9:00383838101010101010101010101000 +16DA:00406050484442404040404040404000 +16DB:00406050484442E0E0E0404040404000 +16DC:00000000102844828244281000000000 +16DD:00824428102844828244281028448200 +16DE:0082C6C6AAAA92929292AAAAC6C68200 +16DF:00001028448282442810284482000000 +16E0:0000820847102AA0124002000200020002000200020002000200020002000000 +16E1:00101010925438103854921010101000 +16E2:00000208031002A0024002000200020002000200020012002A00460082000000 +16E3:00101010101010101038385454929200 +16E4:00929254543838545438385454929200 +16E5:0082C6AA92AAC68282C6AA92AAC68200 +16E6:00101010101010101038385454929200 +16E7:00000000000000001010101010101000 +16E8:00103854921010101010109254381000 +16E9:00040C14244424140C04040404040400 +16EA:004040E040444C546444040E04040400 +16EB:00000000000038383800000000000000 +16EC:00007070700000000000707070000000 +16ED:000000383810D6FED610383800000000 +16EE:00101814121010305090101010101000 +16EF:00925454383810101010383854549200 +16F0:00101010385492929292925438101000 +16F1:00404040404040404854644442424200 +16F2:000808080888C8A89888808080808000 +16F3:00081C2A492A1C080808080808080800 +16F4:0040404044464C5464C4440404040400 +16F5:00081020100810201008102010080000 +16F6:00808040402224181028488404020200 +16F7:00404040407048444242424242424200 +16F8:00080808080808080808142222414100 +16F9:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +16FA:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61866FB663866FB66FB67FFE0000 +16FB:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +16FC:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +16FD:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +16FE:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61866FBE638E6FBE6F867FFE0000 +16FF:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +1700:00000000000000006004100A7808081008100820084008800700000000000000 +1701:0000000000000000400030000FFC04020A8073400222001C0000000000000000 +1702:000000000000000003E0041000100020005000100010082007C0000000000000 +1703:0000000000000000400020021FFC0100010043FC3C0200020004000000000000 +1704:00000000000000001F6020900090011002900090009001103E0C000000000000 +1705:0000000000000000000000004E0C511221E201023E0C40000000000000000000 +1706:0000000000000000401C4022404220801F000800100010000000000000000000 +1707:000000000000000040FC43022C02303010480F80000000000000000000000000 +1708:000000000000000007C009201110121001000080010002000100000000000000 +1709:0000000000000000780C08120812101010182024204010800F00000000000000 +170A:00000000000000000FC010202010400840084008410822901C60000000000000 +170B:00000000000000000006000870080BD00C300820084008800700000000000000 +170C:00000000000000000004000A300A481C08100820084008800700000000000000 +170D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE738E6DB66DB66DB6738E7FFE0000 +170E:0000000000000000407C43823C82010000800100010000800300000000000000 +170F:000000000000000001C00220041000080008010803080C900060000000000000 +1710:0000000000000000000C001238220824084A0442048202840318000000000000 +1711:0000000000000000001C106221822602180C0000000000000000000000000000 +1712:0000000C000C0000000000000000000000000000000000000000000000000000 +1713:0000000000000000000000000000000000000000000000000000001800180000 +1714:0000000000000000000000000000000000000000000000000000010003800100 +1715:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8673BE7B867BF671867FFE0000 +1716:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000 +1717:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000 +1718:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000 +1719:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000 +171A:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8673B67B867BB671B67FFE0000 +171B:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000 +171C:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000 +171D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000 +171E:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000 +171F:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000 +1720:000000000000000000040008181068200840088009000A000C00000000000000 +1721:000000000000000000040008181068200848089009200A000C00000000000000 +1722:000000000000000007E000400080010007F00020004000800100000000000000 +1723:000000000000000010E011100A10062005C00800080008000000000000000000 +1724:0000000000000000101010301050109011101210141018101010000000000000 +1725:0000000000000000101010201040108011401220140018001000000000000000 +1726:00000000000000001080118811881290129014A014A018C01080000000000000 +1727:00000000000000000808081008200040388009000A000C000800000000000000 +1728:000000000000000047183AE80208020802080208020802080208000000000000 +1729:0000000000000000000478080808081008180824084008800700000000000000 +172A:00000000000000003FC000400080008001000100020002000200000000000000 +172B:00000000000000000C0436080508089008500820085008880F00000000000000 +172C:00000000000000001008281848280848088809080A080C080808000000000000 +172D:000000000000000000000000000000001FF80000000000000000000000000000 +172E:0000000000000000210023002300250025002960299031102020000000000000 +172F:0000000000000000304048C208A4091811001200120014001800000000000000 +1730:000000000000000000200060186068A008A00924094C0A740C02000000000000 +1731:0000000000000000100808100820084008800900120014001800000000000000 +1732:00000000003C0000000000000000000000000000000000000000000000000000 +1733:0000000000000000000000000000000000000000000000000000000000780000 +1734:0000000000020002000200020002000200020002000200040004000800301FC0 +1735:0000000000000000004000800080010001000200020004000400000000000000 +1736:0000000000000000010802100210042004200840084010801080000000000000 +1737:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63867DF671EE7DDE63DE7FFE0000 +1738:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000 +1739:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63CE7DB671C67DF663CE7FFE0000 +173A:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63867DB671867DB663B67FFE0000 +173B:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE638E7DB6718E7DB6638E7FFE0000 +173C:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000 +173D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE638E7DB671B67DB6638E7FFE0000 +173E:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63867DBE718E7DBE63867FFE0000 +173F:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63867DBE718E7DBE63BE7FFE0000 +1740:000000080008001038103820082008400FC00F80000000000000000000000000 +1741:000000080008001038103820082008400FC00F8000001F001F00000000000000 +1742:00000000000000000F800F80008000F001E00040004000800080000000000000 +1743:000000000000000003F003F0000000000000000000001F801F80000000000000 +1744:000000000000000002000200040007F007F00010002000200040000000000000 +1745:000000000000000007F007F000200020007C007C00801F801F80000000000000 +1746:000000000000000011E211E2112222442244224444887CF87CF8000000000000 +1747:00000000000000000108010801083E103E100210042007E007E0000000000000 +1748:000000000000000007F807F80040008000800080010001000100000000000000 +1749:00000000000000003C3C3C3C042008400840084010801F801F80000000000000 +174A:000000000000000000000FE00FE000200020004000400FC00FC0000000000000 +174B:00000000000800080010041007F007F00820082008201FE01FC0000000000000 +174C:00000000000000003E7C3E7C024404880488048809100F100F10000000000000 +174D:00000000000000000000000000001FF81FF80000000000000000000000000000 +174E:000000000000000001F001F00110221022203FE03FE004000400080008000000 +174F:000000000400040008F808F80888110810101FF01FF000000000000000000000 +1750:000000003E003E000200040007C007C00040008000F800F80008001000100020 +1751:000000000000000002000200020004000400040008000FE00FE0000000000000 +1752:0000007C007C0000000000000000000000000000000000000000000000000000 +1753:000000000000000000000000000000000000000000000000000000F800F80000 +1754:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61B66FB661867DF661F67FFE0000 +1755:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE61867DF661867FFE0000 +1756:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000 +1757:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FF661EE7DDE61DE7FFE0000 +1758:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000 +1759:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE6FB661C67DF661CE7FFE0000 +175A:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FB661867DB661B67FFE0000 +175B:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB6618E7DB6618E7FFE0000 +175C:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000 +175D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB661B67DB6618E7FFE0000 +175E:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE618E7DBE61867FFE0000 +175F:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE618E7DBE61BE7FFE0000 +1760:00000000000000000004000A3008481008100820084008801700200020001000 +1761:0000000000000010002600483008481008100820084008800700000000000000 +1762:00000000100810201008102010081000 +1763:0000000000000000301808200440028001000280044008201018000000000000 +1764:0000000000000FE0311840840100020001000080010002000100008001000000 +1765:000000000000000000000000401C20221FC22004400000000000000000000000 +1766:0000000000000000400020004000803840443F84400880004000200040000000 +1767:0000000000E00100020604083408481008100820084008800700000000000000 +1768:0000000000000FE0311841040100010001000100010001000100010001000000 +1769:0000000000000000000600083008481008100828084408820700000000000000 +176A:00000000000007F0080810042004200420042004200810100FE0000000000000 +176B:00000000000000000006000833C84C3008100820084008800700000000000000 +176C:0000000000000000000C00123012482408200840084008800700000000000000 +176D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE738E6FB663B66DB6738E7FFE0000 +176E:0000000000000000000E00103010482008200854085A08AC0716000800000000 +176F:000000000000000003C00C20102020004000400041FC46023802000000000000 +1770:0000000000000000002000503050489008A009180910090C0608000000000000 +1771:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000 +1772:0000000800040008000000000000000000000000000000000000000000000000 +1773:0000000000000000000000000000000000000000000000000010000800100000 +1774:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61B67DB67B8677F677F67FFE0000 +1775:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61867DBE7B8677F677867FFE0000 +1776:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000 +1777:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61867DF67BEE77DE77DE7FFE0000 +1778:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000 +1779:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE7DB67BC677F677CE7FFE0000 +177A:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61867DB67B8677B677B67FFE0000 +177B:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E7DB67B8E77B6778E7FFE0000 +177C:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000 +177D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E7DB67BB677B6778E7FFE0000 +177E:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61867DBE7B8E77BE77867FFE0000 +177F:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +1780:00000000000000000760089004000FF008100810081008100810000000000000 +1781:0000000000000000038004400420022000400380042004400380000000000000 +1782:00000000000000000760089004000FF00810081009900A900C10000000000000 +1783:000000000000000019982A202B300910091009100910091006E0000000000000 +1784:0000000004000200028003400180004006200A200AA003600220000000000000 +1785:00000000000000000EC011201000183008500850083008100FF0000000000000 +1786:0000000000000000076008901000087008901E702910291010E0000000000000 +1787:00000000000000200310049008600C0004400440054006C00440000000000000 +1788:00000000000000001C66228822CC2244224432442A442A4431B8000000000000 +1789:00000000000000000DB8124410441044104418441444144418440010070808F0 +178A:00000000038000400320042003C000000220022002A003600220000000000000 +178B:00000010002800080C18142014300410041004100410041003E0000000000000 +178C:00000000000000000EE011101010082000C003100C3010300FD0000000000000 +178D:00000000000000001B062488208C2084208431C42AA42AA43198000000000000 +178E:00000000000000001C38224422642224222432242AA42B643224000000000000 +178F:00000000000000000760089004000FE008200C200A200A200C20000000000000 +1790:0000000000200010031004E008000C6004A004A00460042007E0000000000000 +1791:000000000000000003F8040408080860049003E0008008800F80000000000000 +1792:00000000000000000EC01120100018300850085009300A900C70000000000000 +1793:000000000000000001C002200440040003C00040054006C00440000000000000 +1794:0000000000000000061808200C300410041004100410041003E0000000000000 +1795:000000000020031004900860080008300850085009300A900C70000000000000 +1796:0000000000000000077008880808080808080C080A080A080C08000000000000 +1797:0000000000000000076008900400000003F002100A1012100E10000000000000 +1798:00000000000000000C3010401860082008200FE00820082007C0000000000000 +1799:000000000000000008CC15101598188810881088108810881F70000000000000 +179A:000000000000000000C001000180008000800080028004800300000000000000 +179B:00000000000000000F0C10901098108810881888148814881870000000000000 +179C:0000004000A0002000E001200180008000800080028004800300000000000000 +179D:00000000000000000760089004000FE0082008A80A700D200C20000000000000 +179E:00000000000000000C3010401860082008A808700820082007C0000000000000 +179F:00000000000000000C18102018300F10111019101510151018E0000000000000 +17A0:00000000000000000C78108418C4084408440844084408440784000000000000 +17A1:00000000000000001FC62028404C430424841F0444047C0401C40254016C0044 +17A2:0000000000000000061808200C30041007F00410145024901C70000000000000 +17A3:0000000000000000061808200C30041007F00410145024901C70000000000000 +17A4:00000000000000000C78108418C408440FC4084429444A4439C4000000000000 +17A5:000000000020031004900260000007F004100610051005100610000000000000 +17A6:00000004000A0002000E00121F9810881C8812881C8800081F881888148818F8 +17A7:0000000000000000038004400420022000400390043004500390000000000000 +17A8:000000000000000007600890040003C0042000400390043003D0000000000000 +17A9:00000000000000000E0011001080089001100E5010D011500E50000000000000 +17AA:010000800040074008C00640010003C0042000400390043003D0000000000000 +17AB:0000000000000000061808200C300410041004100410041003E00030070808F0 +17AC:0000000000000000061808200C300410041004100410041003E00030070808F6 +17AD:0000000000000000077008880808080808080C080A080A080C080060071008E0 +17AE:0000000000000000077008880808080808080C080A080A080C080060071008EC +17AF:0000000000000000030001000170019000100710095005B00110000000000000 +17B0:000000000000000007700888080808080C080A080A080C08000003F804900360 +17B1:000000000000038004400620010003C0042000400390043003D0000000000000 +17B2:000000000000001007E0080008E00910091008200810081007E0000000000000 +17B3:000000000000038804500620010003C0042000400390043003D0000000000000 +17B4:AAAA0001A5442945B1282929A510000180000871948822A9BE98227980045555 +17B5:AAAA0001A5442945B1282929A51000018000081194282245BE7C224580005555 +17B6:000000000000001E002200020002000200020002000200020002000000000000 +17B7:00000380044003F8000000000000000000000000000000000000000000000000 +17B8:00000390045003F0000000000000000000000000000000000000000000000000 +17B9:00000390046803F8000000000000000000000000000000000000000000000000 +17BA:005003D0047003F8000000000000000000000000000000000000000000000000 +17BB:00000000000000000000000000010101 +17BC:00000000000000000000000000000000000000000000000000000240024003C0 +17BD:0000000000000000000000000000000000000000000000000000022002A00360 +17BE:00000390045003F0C000A000800080008000C000A000A000C000000000000000 +17BF:005003D0047003FEC001A001800180018001C001A001A001C0011007080107FE +17C0:001800080010003EC001A001800180018001C001A001A001C0011007080107FE +17C1:0000000000000000C000A000800080008000C000A000A000C000000000000000 +17C2:1800880070000000C000A000800080008000C000A000A000C000000000000000 +17C3:9800640044001800C000A000800080008000C000A000A000C000000000000000 +17C4:000000000000001EC022A002800280028002C002A002A002C002000000000000 +17C5:000400020002001EC022A002800280028002C002A002A002C002000000000000 +17C6:0180024001800000000000000000000000000000000000000000000000000000 +17C7:0000000000000000000200050005000200000002000500050002000000000000 +17C8:0000000000000000000000000000000200000002000000000000000000000000 +17C9:0000014001400140000000000000000000000000000000000000000000000000 +17CA:0760089004000000000000000000000000000000000000000000000000000000 +17CB:00010101000000000000000000000000 +17CC:0388045002200400000000000000000000000000000000000000000000000000 +17CD:03880450022001A0000000000000000000000000000000000000000000000000 +17CE:008003E000800080000000000000000000000000000000000000000000000000 +17CF:01E6021C02A00360000000000000000000000000000000000000000000000000 +17D0:000C004400380000000000000000000000000000000000000000000000000000 +17D1:00000FF000000000000000000000000000000000000000000000000000000000 +17D2:0000000000000000000000000000000000000000000000000100038001000000 +17D3:0380044003800000000000000000000000000000000000000000000000000000 +17D4:00000000000000000180098012800C8000800080008000800080000000000000 +17D5:0000000000000000068026804A80328002800280028002800280000000000000 +17D6:00000000304830007800304830000000 +17D7:00000000000000001EF0210838082408380800080008200820081FF000000000 +17D8:0000000000000000331BB4AB54A5149114911651155115511631000000000000 +17D9:00000000000000000380044009200AA00AA00AA0092004400380000000000000 +17DA:00000000000000000000000071008A88AA959252445038200000000000000000 +17DB:000000000000000000C001000180008003E00080028004800300000000000000 +17DC:00000000001C22201C02122418000000 +17DD:000003C004200810000000000000000000000000000000000000000000000000 +17DE:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63866DBE6D8E6DBE63867FFE0000 +17DF:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +17E0:000000000000000007C0082008200820082008200820082007C0000000000000 +17E1:000000000000000007C00820091006100010001000100E1011E0000000000000 +17E2:0000200020002000277028882C082A082A082C08200820081FF0000000000000 +17E3:00000000000000001EF021082108210821083108290829083108000000000000 +17E4:0000000000000004000803E8041808C0092008800840082007E0000000000000 +17E5:00000600091009200A2007E0040008C0092008800840082007E0000000000000 +17E6:0000000000000000180008000BE00C10001006100910082007C0000000000000 +17E7:00000002000400041DC422242024202420243024282428243018000000000000 +17E8:00000008001007D0083010001030105010901050101013D00C30000000000000 +17E9:000000000000000000080F1010D0103008001F00208024401830000000000000 +17EA:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FB663866FB661B67FFE0000 +17EB:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB6638E6FB6618E7FFE0000 +17EC:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000 +17ED:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB663B66FB6618E7FFE0000 +17EE:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE638E6FBE61867FFE0000 +17EF:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE638E6FBE61BE7FFE0000 +17F0:00000000000000003048484830000000 +17F1:00000000000000001028284444000000 +17F2:00000000000000002020202020000000 +17F3:00000000000000000000245A89000000 +17F4:00000000000000004444282810000000 +17F5:00000000000000442810282810000000 +17F6:00000000000000002010100808000000 +17F7:00000000000000000000225488000000 +17F8:00000000000000000810102020000000 +17F9:00000000000000182040780418000000 +17FA:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FB663866FB66FB67FFE0000 +17FB:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +17FC:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +17FD:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +17FE:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE638E6FBE6F867FFE0000 +17FF:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +1800:0000000003800440042004200420032000200040008001000200020002000000 +1801:0000000000000000000000000000666666660000000000000000000000000000 +1802:000000000000000000000080008001C003E001C0008000800000000000000000 +1803:00000000000000000000081008101C383E7C1C38081008100000000000000000 +1804:0000000000000000018001800000000000000000018001800000000000000000 +1805:00000080008001C003E011C81088389C7C3E389C108811C803E001C000800080 +1806:000000000000000000000000000007E007E00000000000000000000000000000 +1807:000000000000000000000000000007E007E00180018000800000000000000000 +1808:0000000000000400020001000180018001800180010002000400000000000000 +1809:0000000000001040082004100618061806180618041008201040000000000000 +180A:0000000000000000000000000000038003800000000000000000000000000000 +180B:AAAA0001BC442045B8282029A010000180001C11A03018118410387D80005555 +180C:AAAA0001BC442045B8282029A010000180001C79A00418398440387D80005555 +180D:AAAA0001BC442045B8282029A010000180001C79A00418398404387980005555 +180E:AAAA0001A2443645AA282229A2100001800001E1820001C1802003C180005555 +180F:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000 +1810:0000000003C0042004200810081008100810081008100420042003C000000000 +1811:0000000003C0042004200810081008100410041000100820042003C000000000 +1812:0000000003C00420042008100810081008100812081204240438020000000000 +1813:00000000034004A004A008900890089008900812081204240438020000000000 +1814:0000000003C0042000200210041004100810081008100420042003C000000000 +1815:0000000000000020002000500050004808480844084404420482030000000000 +1816:0000000003C0040004000880088008E00890089008100420042003C000000000 +1817:0000000007E00810031004880488088808880888088804900490006000000000 +1818:000000000000004000400080008001000100021002100420042007C000000000 +1819:0000000003C0042004200820084008400860080008000420042003C000000000 +181A:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7B8673B67B867BB671B67FFE0000 +181B:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000 +181C:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000 +181D:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000 +181E:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000 +181F:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000 +1820:00000000000030205010101010101E201E2012201240114000C0000000000000 +1821:00000000000030005000100010001F801FC01040104010400040018001000000 +1822:00000000000031C05220122012201E001E001200120011000080004000000000 +1823:00000000000030005000100010001FE01FE011201120112000C0000000000000 +1824:00000000000030005000100010001FF81FF811201120112000C0000000000000 +1825:00000000000030005000100010001FFC1FFE11261122112200C0000000000000 +1826:00000000000030005000100010001FFE1FFE11281124112200C0000000000000 +1827:00000000000030005000100010001FFC1FFE11061102112200C0000000000000 +1828:00000000000030005000100010001C001C001000100010000000100010000000 +1829:00000000007000880108010801081F001F001900110010800040000000000000 +182A:0000000000000F801040104010401E401E401200120012000C00000000000000 +182B:0000000000000F801040104010401E401E400240020002001E001C0000000000 +182C:00000000000003800440044004401FF01FF00440024006400040000000000000 +182D:00000000000003800440044004401FF01FF00440024006400040060000000600 +182E:00000400040018001000300050001C001C001000100010000000000000000000 +182F:00004000400030001000300050001C001C001000100010000000000000000000 +1830:0000000000000C00140014005400270007000400040004000000000000000000 +1831:00001B001B0000000C0014001400570027000400040004000000000000000000 +1832:0000000000000000100028004400878047802E00140004000000000000000000 +1833:00000000000000001000100010001FC01FC01000120015000900060000000000 +1834:00000000000000000000000000001FF01FF00040004003C007C0040000000000 +1835:00000000000000000000000000001F001F001000100008000800040004000000 +1836:00000000000000000000000000001F001F001000100008000400080000000000 +1837:00000000000000000000000000001F001F001000100008000800140024000000 +1838:00000000000000000000000000001F001F001000100012000C00000000000000 +1839:0000000000000F801040104010401E401E401200120012000C00100010000000 +183A:0000000000000F00108010801080108010801000100018001400140000000000 +183B:0000000000000F001080108010801C801C801000100018001400140000000000 +183C:00000000000000000000000000001FF01FF00100010001C007200EC000000000 +183D:00000000000000000000000000001FF01FF001000100010007200EC000000000 +183E:00000000000030005000100010001E781E781240124012200140008000000000 +183F:000000001800240044004C005400470047004400440050004800300000000000 +1840:00000000400030001000300050001E781E781240124012200140008000000000 +1841:000000000000000000000000000013C013C01200120011000A00040000000000 +1842:00000000000000000000000000001FFC1FFC1290129012900C60000000000000 +1843:00000000000000001000100010001C001C000000000000000000000000000000 +1844:00000000000030005000100010001FC01FC01200120012001180000000000000 +1845:00000000030032805240124012201E201E201220124012400000000000000000 +1846:00000000000030005000100010001FC01FC012401240124011C0000000000000 +1847:00000000000031E05210120812081FC81FC81240124012401180008000600000 +1848:00000000000030005100108010801FC01FC012401240124011C0000000000000 +1849:00000000000031E05210120812081FC81FC81240124012401180000000000000 +184A:00000000000000000000000000001FF81FFC1A04120412040188003000200000 +184B:00000000000000000000000000001FC01FE01220122012200C40018001000000 +184C:00000000000011801240142014207C207C201400140012001E00000000000000 +184D:00000000000030005000100010001FC01FC01B00120012000000120012000000 +184E:00000000000030005000100010001FC01FC01B00120000000C0012000C000000 +184F:0000000001800880148013001100310031000900050003000000000000000000 +1850:00000000000000000C00120012001380138012000A0006000000000000000000 +1851:00000000000000000000000000001F001F00140012000A000C00000000000000 +1852:00000000000000000000000000001FC01FC00100010001000E0012000C000000 +1853:00000000000000000000000000001FC01FC00100010001000600080007000000 +1854:00000000000000000000000000001FC01FC00100010001000600080000000000 +1855:00000000000000000000000000001E001E001000100008000800000000000000 +1856:00000000000000000000000000001F801F80100010000E000900060000000000 +1857:0000070008800840084008400800080008000800040002000600000000000000 +1858:000007000880084008400840080018001800080004000A000000000000000000 +1859:00000000000000000000000000001E781E7C1A4C124412240140008000000000 +185A:00000000070008801040104010401E701E701240124012400C80010003C00000 +185B:00000000000002001E00120012001F801F8010001000100012000C0000000000 +185C:00000000000000000000000000001FC01FC001000F000F000900030004000000 +185D:000000800040108011000100020012001200120012000A000A00060000000000 +185E:00000000000000000000000000001FC01FC01A00120011000100008000000000 +185F:00000000000000002200140008003F803F801800100010000000000000000000 +1860:00000000008031005100100010001FC01FC01240124012401180000000000000 +1861:00000000000000000000000000001FF01FF01280124012200C00000000000000 +1862:00000000000000000000000000001FF01FF01B10121012100020004000400000 +1863:000001000080010001000200020012001200120012400A800600004000800000 +1864:00000000031004A0048008400840387038700840084004801C80000000000000 +1865:00000060039004E0048008400840387838780840084004801C80000000000000 +1866:0000000000000D801240124010401E401E401200120012000C00000000000000 +1867:000000000000030005001500090001C001C00100110009000500000000000000 +1868:0000000001C002200420022001200FF80FF80020002000200000000000000000 +1869:0000000000000100120028004400878047802E00140004000000000000000000 +186A:00000000000000000000000000003F003F001000080004000400040018000000 +186B:000000000C00120002000100010001F801F80100010000800090006000000000 +186C:00000100020000000E0011001080108010801000180014001400000000000000 +186D:000006000900060000000E001100108010801000180014001400000000000000 +186E:0000040004001F0004000C001400178057802400040004000000000000000000 +186F:000000001F00040004000C001400178057802400040004000000000000000000 +1870:00000000000010001000100010001C001C001000100010001000000000000000 +1871:00000000000006000900060000001FC01FC00100010001000600080000000000 +1872:0000000000000C0012000C0000003F003F001000080004000400040018000000 +1873:00000000000000000000000000001FE01FE01100110008800880044004400000 +1874:00000008000400080010001000201F201F201920112010A000A0006001080210 +1875:00000000000000000000000000001F001F801180108008801400140000000000 +1876:000000000C0012000200010001003FF83FF80100010000800090006000000000 +1877:00000000000006000900060000001F801F801000100008000800000000000000 +1878:0000000000000D800D80000000001FC01FC00100010001000600080000000000 +1879:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61CE7DB67BC677F677CE7FFE0000 +187A:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61867DB67B8677B677B67FFE0000 +187B:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E7DB67B8E77B6778E7FFE0000 +187C:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000 +187D:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E7DB67BB677B6778E7FFE0000 +187E:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61867DBE7B8E77BE77867FFE0000 +187F:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +1880:000000000000020001000C8012C012C012C012C00C8001000200000000000000 +1881:0000000000000000000000000CC0132013200CC0000000000000000000000000 +1882:0000000000000000104018C0154012401240154018C010400000000000000000 +1883:0000000000000E0011000100010002001C0002000100010011000E0000000000 +1884:0000000000000E001100100010000800070008001000100011000E0000000000 +1885:000000000000000000000C62129421082108252818C800000000000000000000 +1886:000000040EE811101550089000040EE811101550089000040EE8111015500890 +1887:00000000000030005000100010001FF81FFC1004100810101000000000000000 +1888:0000000000C031205220140014001C001C001400140012401180000000000000 +1889:000000000600090008801080108010F010F01000100008000800040000000000 +188A:00000000000030005180124012201E201E001200120012000100100020000000 +188B:00000000000000000000000000001FF01FF00100010007C00820082000C00000 +188C:00000000000000000000000000003F003F000800040012000A00060000000000 +188D:00000000000000000000000000001FFC1FFC131012A012400C00000000000000 +188E:00000000000000000000000000001FF01FF01000118009400940060000000000 +188F:00000000000000000000000000001FF01FF01000100008000E00060000000000 +1890:00000000000000000000000000001FC01FC01400120009000900060000000000 +1891:00000000000000000000000000001F801F801000120009000A00040000000000 +1892:00000000060009000880104010401F401F000100010009000600000000000000 +1893:00000000060009000880104010401F401F00010001000E00100012000C000000 +1894:0000070008800840084008401040107010701040104008000000028002800000 +1895:0000070008800840084008400840087008700840084008000880070000000000 +1896:000000000000000000000000000007C007C00040004003800040018000000000 +1897:0000000000000700088008400840084008000800088008800700000000000000 +1898:00000000000000000000000000001FC01FC0140012000B800C00000000000000 +1899:00000000000000000F001080108013E017E01480148013000800078000000000 +189A:000000480054064809000880088078FE78FE0880088008003800000000000000 +189B:00000000000030005000100010001FC01FC01000130014801300000000000000 +189C:00000E0011000E001F000C000C00178017805400240004000000000000000000 +189D:00000000000000601E900C600C0017F817F85400240004000000000000000000 +189E:00000000100011800A400980040007F807F80400020002000100010000000000 +189F:00000000000004400AA0044000001FF81FF81000080008000400040000000000 +18A0:00000000000001000200020000001F801F801400120009000A00040000000000 +18A1:00000000024002A012402800440087F047F02E00140004000000000000000000 +18A2:000000000000030005001500090001C001C00100010000000000050005000000 +18A3:000000001000100008000800040007F807F80400020002000100010000000000 +18A4:000003000480030000000300050015C009C00100110009000500000000000000 +18A5:000003000480030000000300050015C009C00100010001000100000000000000 +18A6:00000000000000000000000000001F001F0011000A0004000000000000000000 +18A7:00000000000000000000000000001780178012000A000900050005000E000000 +18A8:0000000000300E481130108010801EFC1EFC1200120012000C00000000000000 +18A9:0000000000000000000000000000000000000000000000000000600010000800 +18AA:00004000400033001480330050001FC01FC01000100010001000000000000000 +18AB:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000 +18AC:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000 +18AD:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E6DB661B66DB66D8E7FFE0000 +18AE:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866DBE618E6DBE6D867FFE0000 +18AF:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000 +18B0:0300048004801B00140012001100108010401040108011001200140018000000 +18B1:06000900090006C0014002400440084010401040084004400240014000C00000 +18B2:18C024C0240018C0014002400440084010401040084004400240014000C00000 +18B3:01800240024001B0005000900110021064106410021001100090005000300000 +18B4:18242458201008040202040810204000 +18B5:1824241A040810204040201008040200 +18B6:18242458201008046262040810204000 +18B7:024002400180000007F00800100010001000100010001000080007F000000000 +18B8:30484830004040404078444444380000 +18B9:0C12120C00101010D0DE1111110E0000 +18BA:304848300040404040404040407C0000 +18BB:000000000000000000C00120012000C0000000E00110011001101FE000000000 +18BC:0000000000000000060009000900060000000E001100110011000FF000000000 +18BD:0000000000000000060009000900060000000E001000100010000FF000000000 +18BE:18242418000404041C20404040400000 +18BF:30484830004040407008040404040000 +18C0:0000000000000180024002400180000000000C601210111010900C6000000000 +18C1:0000000000000180024002400180000000000C601090111012100C6000000000 +18C2:0000000000000060009000900060000000000318348434440424031800000000 +18C3:182424180008080808F8402010080000 +18C4:6090906000404040407C081020400000 +18C5:18242418003E404040403E0202020000 +18C6:00000000000000000000000000000000000003FC344034400440038000000000 +18C7:0000000000000000000000000000000000001FE0220C220C22001C0000000000 +18C8:00000000000000000000000001800180000003FC344034400440038000000000 +18C9:0000000000000000000000000C000C0000001FE0220C220C22001C0000000000 +18CA:000000000000000000000000000000000000003830443044004407F800000000 +18CB:00000000000000000000000000000000000001C0022C022C02203FC000000000 +18CC:000000000000000000000000003000300000003830443044004407F800000000 +18CD:00000000000000000000000001800180000001C0022C022C02203FC000000000 +18CE:000000000000000000000000000000001E04020462046204010800F000000000 +18CF:0000000000000000000000000000000003C00420681068100810081E00000000 +18D0:0000000000000000000001800180000003C00420681068100810081E00000000 +18D1:000000000000000003C00020001000101810182003C002000200020000000000 +18D2:000001800180000003C00020001000101810182003C002000200020000000000 +18D3:000000000000000000F00100020002001A00190000F000100010001000000000 +18D4:00000010102828444400000000000000 +18D5:00000000384444444400000000000000 +18D6:00000000304848704040000000000000 +18D7:00000000304848404040000000000000 +18D8:00000000784040404040000000000000 +18D9:000000003E4848300000000000000000 +18DA:00000000080808106040400000000000 +18DB:0000000062928C000000000000000000 +18DC:00000008C8D414223E00000000000000 +18DD:0000002026565088F800000000000000 +18DE:18242418000000000000000000000000 +18DF:00181800000000000000000000000000 +18E0:000000000000000000000000000000007816081608100810042003C000000000 +18E1:0000060006000000040004000400078000400020002000200040078000000000 +18E2:000000600060000000200020002001E00200040004000400020001E000000000 +18E3:000000000000000000000E201120112C112C1220102010200840078000000000 +18E4:0000000000000000000000000FC01020202C222C21C0200010000FE000000000 +18E5:0000000000000000000022202220222C222C22202020202010400F8000000000 +18E6:000000000600060000001FC00020001000101F100010001000201FC000000000 +18E7:0000000000C000C0000007F008001000100011F010001000080007F000000000 +18E8:000000000000000000000E001100110011000F30053005000900090000000000 +18E9:0000060600090905050F1111110E0000 +18EA:000000000000000000000F001080128012800C98009800800080008000000000 +18EB:000006060002020202324A4A423C0000 +18EC:0000000000300030000000300050005008900890071000100010001000000000 +18ED:00000000000000000000000042104210421642164210421042103DE000000000 +18EE:000000000300030000000FE00010001000100FE00010001000100FE000000000 +18EF:0000000000C000C0000007F008000800080007F008000800080007F000000000 +18F0:000000000000000000001FC020002000200C1FCC2000200020001FC000000000 +18F1:00000180018000000FF00600018000400020039004500410022001C000000000 +18F2:00000000000000000000000000201860246C44AC44A0492022201C2000000000 +18F3:00000030101010103800000000000000 +18F4:00000000586440404000000000000000 +18F5:000000003C4038047800000000000000 +18F6:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +18F7:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +18F8:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +18F9:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +18FA:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866FB663866FB66FB67FFE0000 +18FB:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +18FC:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +18FD:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +18FE:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866FBE638E6FBE6F867FFE0000 +18FF:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +1900:000000000000FF801080208040807C800880108020804E807180000000000000 +1901:0000000000003E00020002000400040008000800100010001F00000000000000 +1902:0000000000003F8042008400840084008400840084004A403180000000000000 +1903:0000000000007880090012002400780014002200220022001C00000000000000 +1904:000000000000FF80208020802080208011800E80008000800080000000000000 +1905:0000000000005E004480494050805C0042004100210022001C00000000000000 +1906:0000000000007080088004800280028002802280528054803880000000000000 +1907:0000000000007F8008001000200078004E004000408021001E00000000000000 +1908:0000000000007F80008078800480048078800080008000800080000000000000 +1909:0000000000001F002000200020001F0020002000200020001F00020004000800 +190A:0000000000007F800400040034004C0046004940308001400240000000000000 +190B:0000000000001F00208040800100060001000080408020801F00000000000000 +190C:0000000000007C0004000400040004003F804440444044403880000000000000 +190D:00000000000060C01F0004000400070000800040404020801F00000000000000 +190E:0000000000007C80188020802080188020802080208011000E00000000000000 +190F:0000000000007C0004000400080008001E001000200020003E00000000000000 +1910:0000000000002200410041008080808080808080490049003600000000000000 +1911:0000000000000000770088800880088008800880888088807700000000000000 +1912:00000000000060C01F00040004001C0020004180424022801F00000000000000 +1913:0000000000003880448044804880508051802E80008000800080000000000000 +1914:0000000000007F80088008801080108020804080788006800180000000000000 +1915:0000000000007E00040008001C00020032004A003C0008000000000000000000 +1916:0000000000007C00040004000800080018001800240022004100000000000000 +1917:00000000000031802E80208010800E8000800080008000800080000000000000 +1918:0000000000001080308050809080108009800680008000800080000000000000 +1919:00000000000043C0420042004200420042004200420042003C00000000000000 +191A:0000000000001D002300210021002100210023001D0001000100000000000000 +191B:0000000000003F80448044804480448044803880008000800080000000000000 +191C:0000000000001F002100420044004F0040804000200010800F00000000000000 +191D:0000000000007F80100010001E00110011000100010001000100000000000000 +191E:0000000000007F80100010001F00010001001100290025001E00010000000000 +191F:00007FFE7BCE73B67BC67BF671CE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000 +1920:300048003F800000000000000000000000000000000000000000000000000000 +1921:0000003C00420004000700000000000000000000000000000000000000000000 +1922:000000000000000000000000000000000000000000000000000030804B003C00 +1923:000000000000000800140014000C000400040008000800100010000000000000 +1924:0000000000000012002D002D001B000900090012001200240024000000000000 +1925:300048003F80000800140014000C000400040008000800100010000000000000 +1926:300048003F800012002D002D001B000900090012001200240024000000000000 +1927:6000180006000000000000000000000000000000000000000000000000000000 +1928:008031000A000400000000000000000000000000000000000000000000000000 +1929:0000000000000000000000000000000000000000000100220052000C00000000 +192A:0000000000000000000000000000000000000000000000000000004000A00110 +192B:00000000000000000000000000000072000A00320046003A0002000000000000 +192C:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000 +192D:00007FFE7BCE73B67BC67BF671CE7FFE7FFE618E7DB661B66FB6618E7FFE0000 +192E:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DBE618E6FBE61867FFE0000 +192F:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DBE618E6FBE61BE7FFE0000 +1930:000000000000003E001000200022001C00000000000000000000000000000000 +1931:000000000000000000000000000000000000000C00120012000C000000000000 +1932:00000000000000000000000000000000000000000000000000000C0012000C00 +1933:0000000000000000000000000000000000000000000000000000003800440000 +1934:0000000000000080004000400044002A002A001C000000000000000000000000 +1935:0000000000000042002200220026001A00020000000000000000000000000000 +1936:0000000000000044002A002A001C000800080008000800080008000000000000 +1937:0000000000000000000000000000000000000000000000000020001000080000 +1938:0000000000000024002400240018000000000000000000000000000000000000 +1939:0000000000000000000000000000000000000000000000000010002000400000 +193A:0280000000000000000000000000000000000000000000000000000000000000 +193B:000000000000000000000000000000000000000000000000000000007F800000 +193C:00007FFE7BCE73B67BC67BF671CE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000 +193D:00007FFE7BCE73B67BC67BF671CE7FFE7FFE638E7DB671B67DB6638E7FFE0000 +193E:00007FFE7BCE73B67BC67BF671CE7FFE7FFE63867DBE718E7DBE63867FFE0000 +193F:00007FFE7BCE73B67BC67BF671CE7FFE7FFE63867DBE718E7DBE63BE7FFE0000 +1940:00000000000002000400080008000830084808480428021001E0000000000000 +1941:00007FFE7BCE73B67BC67BF671CE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000 +1942:00007FFE7BCE73B67BC67BF671CE7FFE7FFE6D866DF661867DBE7D867FFE0000 +1943:00007FFE7BCE73B67BC67BF671CE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000 +1944:0000000000000180024002400140004000400040004000000040000000000000 +1945:0000000000000460029001200100010001000100010000000100000000000000 +1946:0000000000000380044008200820082008200820082004400380000000000000 +1947:00000000000008000800080008000860089008900850042003C0000000000000 +1948:0000000000000100028002800440044008200820101010101010000000000000 +1949:00000000000007800840080004000380004000200020042003C0000000000000 +194A:0000000000001830044002800280010002800280044008203018000000000000 +194B:00000000000003C004A008A0084008000800084008A004A003C0000000000000 +194C:000000000000038004400820080008000800084008A004A003C0008000400020 +194D:0000000000000C4010A011000900060003000480044004400380000000000000 +194E:0000000000001010101010100820082004400440028002800100000000000000 +194F:0000000000001FE012200A200640024000800080010002000400000000000000 +1950:00000000000048542404040404000000 +1951:000000000000485424041C241C000000 +1952:00000000000058644444444444000000 +1953:000000000000A0561A1212161A000000 +1954:000000000000A052121212161A000000 +1955:0000000000004242424242562A000000 +1956:000000000000B6DA929292B2D2000000 +1957:000000000000B6DA929292B6DA000000 +1958:0000000000000202020242562A000000 +1959:00000000000044444444444C34000000 +195A:000000000000969A929292B6DA000000 +195B:00000000000044447C44444C34000000 +195C:000000000000969A929292B6DA020408 +195D:00000000000058644444444C34000000 +195E:000000000000B6DA929292B2D2102040 +195F:000000000000B65A1212121212102040 +1960:000000000000485424041C241C040810 +1961:000000000000A052121212161A020408 +1962:000000000000464A4A52526242000000 +1963:00000010101010101010101010000000 +1964:0000003C2424243C242424342C000000 +1965:0000003C242424242424242424000000 +1966:0000003C24242424242424242404041C +1967:0000002020202020202020203C003C00 +1968:0000002020202020202020203C000000 +1969:0000002424242424242424243C000000 +196A:0000003C2424243C242424342C202038 +196B:0000003C242424242424242424202038 +196C:0000003C202020202020202020000000 +196D:000000000000A052121212161A102040 +196E:00007FFE7BCE73B67BC67BF671CE7FFE7FFE73866FBE638E6DBE73867FFE0000 +196F:00007FFE7BCE73B67BC67BF671CE7FFE7FFE73866FBE638E6DBE73BE7FFE0000 +1970:000000000000F8484848484A84000000 +1971:0000000000001824447C404438000000 +1972:0000000000001C244444444C34000000 +1973:00000000000040242A2A26221C000000 +1974:00000000000018244040404438000000 +1975:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DBE7B8677F677867FFE0000 +1976:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000 +1977:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DF67BEE77DE77DE7FFE0000 +1978:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000 +1979:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61CE7DB67BC677F677CE7FFE0000 +197A:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DB67B8677B677B67FFE0000 +197B:00007FFE7BCE73B67BC67BF671CE7FFE7FFE618E7DB67B8E77B6778E7FFE0000 +197C:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000 +197D:00007FFE7BCE73B67BC67BF671CE7FFE7FFE618E7DB67BB677B6778E7FFE0000 +197E:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DBE7B8E77BE77867FFE0000 +197F:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +1980:00000000000000001C70228801040104010422081C3000080004008400780000 +1981:00000180024000001C70228801040104010422081C3000080004008400780000 +1982:00000000000000000E38114420822002200210040E3800000000000000000000 +1983:00000000384402021A241A0202423C00 +1984:00000000000000000E3810442082208211040E38000000F8010400E4021401F8 +1985:000000000000000003C004200810081008100420024000000000000000000000 +1986:03C00420081008000BC00C200810081008100420024000000000000000000000 +1987:000000000000000003C004200810081008100B100C9000100010042003C00000 +1988:000000000000000007C00820081006100810082007C000000000000000000000 +1989:00000000000000001C70220801040104010422881C7000000000000000000000 +198A:00300048004000400E40114010400C40104010800F0000000000000000000000 +198B:000000000000000003C004200810081008100420024000200010041003E00000 +198C:03C00420081008000BC00C200810081008100420024000200010041003E00000 +198D:00000000000000000E38100420022002208211440E3800000000000000000000 +198E:00000000000000000E38114420822082208211040E3800000000000000000000 +198F:000000003C4241314145390101221C00 +1990:00000000000000000E38104420822082208211040E38002000300208010800F0 +1991:1E2140404E51414641211E0000000000 +1992:000000000000000007F008081004100410840888077000000000000000000000 +1993:000000000000000007C00820080008000800080007C000200010082007C00000 +1994:0018002400200020062008201020102010200840078000000000000000000000 +1995:00000000000000001C70228820881850202020521F8C00000000000000000000 +1996:00000000000000000E38104420822082208211040E38002001E00204020801F0 +1997:00000000000000000E3811442082200210060E3A000203E2041205E2040403F8 +1998:00000000000000001C70228801040104010422081C7000000000000000000000 +1999:000000000000000002400420081008100BD0042003D000100010041003E00000 +199A:3E403F013945413141423C0000000000 +199B:00000000000000000E38104420822082208211040E38000003E00410041003E0 +199C:00000000000000000E38104420822082208211040E3800080308048804480230 +199D:0F001080204020002E38314420822002200210040E3800000000000000000000 +199E:000000001C22414141221C0000000000 +199F:00000000000000000E38110420822082208210440E3800000000000000000000 +19A0:00000000000000000E38104420822082208211040E3800000000000000000000 +19A1:00000000384402020204180402423C00 +19A2:000000000000000002400420081008100810042003C000000000000000000000 +19A3:00000000384442221151210202040000 +19A4:00182400384402020204180402423C00 +19A5:000001800240000002400420081008100810042003C000000000000000000000 +19A6:00000000000000000E38114420822002200210040E38000003E00410041003E0 +19A7:00000000384402023A443A003C42423C +19A8:000000000000000003C0042008100810081004200240000003C00420042003C0 +19A9:03C00420081008000BC00C2008100810081004200240000003C00420042003C0 +19AA:00000000000000001C70220801040104010422881C70000007C00820082007C0 +19AB:03C00420081008000BC00C200810081008100420024000200390046004400380 +19AC:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000 +19AD:00007FFE7BCE73B67BC67BF671CE7FFE7FFE618E6DB661B66DB66D8E7FFE0000 +19AE:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61866DBE618E6DBE6D867FFE0000 +19AF:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000 +19B0:00000000304926003049260000000000 +19B1:00000000384402020244380000000000 +19B2:1C224141415D634141221C0000000000 +19B3:00000000384402020244784040423C00 +19B4:00000000000000001040104010401040104008C0074000400040004800300000 +19B5:000000000000000003C004200810081008100420023000000000000000000000 +19B6:00000000000000001C1C22224141414141412222131300000000000000000000 +19B7:384440201820404040221C0000000000 +19B8:000000001C2222140814630000000000 +19B9:1C2A4949495D634141221C0000000000 +19BA:3C4202021E22404040221C0000000000 +19BB:00000000000000000F08108800480048004810C80F4800480048004800300000 +19BC:07000880104010401048174818C81048104808C8074800480048004800300000 +19BD:000000000000000007840844102410241024086407A400240024002400180000 +19BE:00180024002000201C2022202220142008201440638000000000000000000000 +19BF:07000A80124012401248174818C81048104808C8074800480048004800300000 +19C0:07000880104010401048174818C81048104808C8074800480048004800300000 +19C1:000000001C22414141231D010D120C00 +19C2:000000000000000003C004200810081008100B100C90001000D0012000C00000 +19C3:000000000000000007C00820080008000800080007C000200610092007C00000 +19C4:000000000000000002400420081008100BD0042003D000100310049003E00000 +19C5:00000000000000000E38114420822002200210060E3A0002001A002400180000 +19C6:000000003844020202041804324A3C00 +19C7:000000000000000002400420081008100810043003D0001000D0012000C00000 +19C8:000000001C20405C62221C0000000000 +19C9:000000001C22625C40201C0000000000 +19CA:00007FFE7BCE73B67BC67BF671CE7FFE7FFE71866FB66F866FB671B67FFE0000 +19CB:00007FFE7BCE73B67BC67BF671CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +19CC:00007FFE7BCE73B67BC67BF671CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +19CD:00007FFE7BCE73B67BC67BF671CE7FFE7FFE718E6FB66FB66FB6718E7FFE0000 +19CE:00007FFE7BCE73B67BC67BF671CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000 +19CF:00007FFE7BCE73B67BC67BF671CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +19D0:000000001C22414141221C0000000000 +19D1:00000000384402020244380000000000 +19D2:000000000E0202020202020202443800 +19D3:000000003C42010101423C1008040200 +19D4:000000001E21404040211E0408102000 +19D5:00000000000000000E38114420842004200410040C0400040024002400180000 +19D6:003C4240444A484442221C0000000000 +19D7:00000000000000001C7022884108400840082008180800080009000900060000 +19D8:00000000182424244242810000000000 +19D9:000000001C2241414946404040423C00 +19DA:000000000008000803D00420080008000800042003C000000000000000000000 +19DB:00007FFE7BCE73B67BC67BF671CE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +19DC:00007FFE7BCE73B67BC67BF671CE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +19DD:00007FFE7BCE73B67BC67BF671CE7FFE7FFE638E6DB66DB66DB6638E7FFE0000 +19DE:0000000C001200100C10121021102110211010900C6000000000000000000000 +19DF:0000000C001200100C10121021102110211010900C60000007C00820082007C0 +19E0:0000000001C0022002200220022001C0000803F8040008E0092008A00A200DE0 +19E1:000003800440054002400040044003800000024004C003400040004000400000 +19E2:00001000136014901410131010100FE00000024004C003400040004000400000 +19E3:000000000EE0111011101910151019100000024004C003400040004000400000 +19E4:00000200040009000A800A00090007800000024004C003400040004000400000 +19E5:04800B80040009000A800A00090007800000024004C003400040004000400000 +19E6:040005800640004002400540044003800000024004C003400040004000400000 +19E7:0000001006C8092808280C280A280C100000024004C003400040004000400000 +19E8:002003E0040008E0092008A00A200DC00000024004C003400040004000400000 +19E9:00000040004003C004000300044003800000024004C003400040004000400000 +19EA:00001C3822442A441244024422441C380000024004C003400040004000400000 +19EB:00001C3822442A541224020422441C380000024004C003400040004000400000 +19EC:00003900452C555225420522450238FC0000024004C003400040004000400000 +19ED:000038EC4512551225120592455239920000024004C003400040004000400000 +19EE:00001C1022202A481254025022481C3C0000024004C003400040004000400000 +19EF:00241C5C22202A481254025022481C3C0000024004C003400040004000400000 +19F0:002003E0040008E0092008A00A200DC0002003E0040008E0092008A00A200DC0 +19F1:0000048009800680008000800080000003800440054002400040044003800000 +19F2:000004800980068000800080008000001000136014901410131010100FE00000 +19F3:0000048009800680008000800080000000000EE0111011101910151019100000 +19F4:000004800980068000800080008000000200040009000A800A00090007800000 +19F5:000004800980068000800080008004200BE0040009000A800A00090007800000 +19F6:0000048009800680008000800080040005800640004002400540044003800000 +19F7:00000480098006800080008000800000001006C8092808280C280A280C100000 +19F8:0000048009800680008000800080002003E0040008E0092008A00A200DC00000 +19F9:000004800980068000800080008000000040004003C004000300044003800000 +19FA:000004800980068000800080008000001C3822442A441244024422441C380000 +19FB:000004800980068000800080008000001C3822442A541224020422441C380000 +19FC:000004800980068000800080008000003900452C555225420522450238FC0000 +19FD:0000048009800680008000800080000038EC4512551225120592455239920000 +19FE:000004800980068000800080008000001C1022202A481254025022481C3C0000 +19FF:000004800980068000800080008000241C5C22202A481254025022481C3C0000 +1A00:0000000000000000000000000000000000800110022004400880010000000000 +1A01:0000000000000000000000000000000001200120029002900460056000000000 +1A02:0000000000000000000000000000000002000100008000C00120021000000000 +1A03:00000000000000000000000000000000004000A0011002880440082000000000 +1A04:0000000000000000000000000000000001200120029002900460046000000000 +1A05:0000000000000000000000000100028004400220010001800240042000000000 +1A06:0000000000000000000000000000000004400440028002800100010000000000 +1A07:00000000000000000000000000000000084004200210031004A0084000000000 +1A08:0000000000000000000000000000000000800080014001400220022000000000 +1A09:0000000000000000000000000000000005400440028002800100010000000000 +1A0A:000000000000000000000000000000000080008001400140022002A000000000 +1A0B:0000000000000000000000000000002001100290028804480450092002800000 +1A0C:00000000000000000000000000000000012001200290021004A0044000000000 +1A0D:00000000000000000000000000000000004000A00110031004A0084000000000 +1A0E:0000000000000000000000000000000002200220055004900808094800800000 +1A0F:0000000000000000000000000000000002200220055004900948094800000000 +1A10:00000000000000000000000000000000042004200A500A50118815A800000000 +1A11:0000000000000000000000000000000001800240042001800240042000000000 +1A12:00000000000000000000000000000000042004200A500A101148118800000000 +1A13:00000000000000000000000000000000042004200A500A501188118800000000 +1A14:000000000000000000000000000000000180066008100408033000C000000000 +1A15:00000000000000000000000000000000042004200A500A50118811A800000000 +1A16:0000000000000000000000000000000004200A50118811880A50042000000000 +1A17:0000000000000000000008000000000000000000000000000000000000000000 +1A18:0000000000000000000000000000000000000000000000000000000000000010 +1A19:0000000000000000000000000000000000004000800080004000200000000000 +1A1A:0000000000000000000000000000000000000006000200020001000100000000 +1A1B:0000000010000800040008000000000000000000000000000000000000000000 +1A1C:00007FFE7B8673B67B867BB671B67FFE7FFE7BC673BE7BBE7BBE71C67FFE0000 +1A1D:00007FFE7B8673B67B867BB671B67FFE7FFE7B8E73B67BB67BB6718E7FFE0000 +1A1E:0000000000000000000030003000000000000180018000000000000C000C0000 +1A1F:0000000000000000000000000000100010003800440000004400380010001000 +1A20:0000000000000000000003700488084408440844048800300000000000000000 +1A21:0000000000000000000003C00420001003D00430043003C80000000000000000 +1A22:03E0040004000400040005C00620001003D00430043003C80000000000000000 +1A23:0000000000000000000001E00210040804080408021001200000000000000000 +1A24:03C0040004000400040005E00610040804080408021001200000000000000000 +1A25:0000000000000000000005000AA800A40124022402A401580000000000000000 +1A26:0000000000000000000001E0021004080208040804C803280000000000000000 +1A27:0000000000000000000001C00220011000900110022001C00000000000000000 +1A28:0000000000800080004003300488004400440044048803700000000000000000 +1A29:0000000000000000000000F00108020802100208010800C80000000000000000 +1A2A:03E0040004000400040005E00610041004200410021001900000000000000000 +1A2B:0000000000800080004003300488044402440444048803700000000000000000 +1A2C:00000000000000000000033004880044004400440488077004000404040403F8 +1A2D:0000000000000000000002200510040802080408049003600000000000000000 +1A2E:0000000000000000000002200510040802080408041803E8000803C8041003E0 +1A2F:0000000000000000000001C0022000100010002000C001300008000000000000 +1A30:0000000000000000000002800550004800880108015000A00000000000000000 +1A31:00000000000000000000011002A804A404A404A4024801100000000000000000 +1A32:0000000000000000000003700488084408440844048803300000000000000000 +1A33:0000000000000000000003E0041002080148022804A803480000000000000000 +1A34:0000000000000000000002700488041004200410020801F00000000000000000 +1A35:0000000000000000000001E0021004080408040802D001200000000000000000 +1A36:0000000000000000000001C0022004000400040002E001100008000000000000 +1A37:0000000000000000000001200210040804080408021001E00000000000000000 +1A38:0000000600080010001000100210041004100410022001C00000000000000000 +1A39:0000000000000000000002100528042802280428049003680000000000000000 +1A3A:03F004080400040003F800080208040802080408029001600000000000000000 +1A3B:00000000000000000000012002D0040804080408021001200000000000000000 +1A3C:03E00400040004000400052006D0040804080408021001200000000000000000 +1A3D:0000000000000000000003700488004400440044048803300000000000000000 +1A3E:00000000000000000000012002100408040804E8021001E80004000000000000 +1A3F:0000000000000000000000300488084408440844048803700000000000000000 +1A40:0006000800080008000803880408040803080408041003E00000000000000000 +1A41:0000000000000000000003800440022001100490044803880000000000000000 +1A42:0000000000000000000002200550048802080008000803E80418048803F40020 +1A43:0000000000000000000003300488088408840844044803300000000000000000 +1A44:0000000000000000000003C004200010001003E0001003D00430049003E80020 +1A45:0000000000000000000001E00210040804080408021001E00000000000000000 +1A46:0000000000000000000401E8021004E804080408021001200000000000000000 +1A47:0000000000000000000003300488004400440054048803740000000000000000 +1A48:0000000000000000000003300488004400440044048803700000000000000000 +1A49:0000000000000000000003300448084408840884048803300000000000000000 +1A4A:0000000000000000000001E0021004080208040804C8032802000270020801F0 +1A4B:0000000000000000000003700488004400440044048803300008000400000000 +1A4C:00000000000000000000033004480844088408840488033000100190021001E0 +1A4D:00000000000000000000033004C8040804080210000003E0041004C805480208 +1A4E:00FC0102010000FE0002033204CA040A040A0212000203E2041204CA054A020C +1A4F:0000000000000000000001E00210000800080408061005E004000400021001E0 +1A50:03C0040004000400040005E00610000800080408061005E004000400021001E0 +1A51:0000000000000000000001E00210040804080408041004E004000400021001E0 +1A52:0800100010001000100013701488104410441044148813301008100410000800 +1A53:0006000800080008000803080488088808880848044803300000000000000000 +1A54:000000000000000000000248052400920092009205B402480000000000000000 +1A55:0800100010001000100010001000100010001000100010001000100010000800 +1A56:00000000000000000000000000000000000000000000000000000C8012400980 +1A57:000000000000000600010001000100010001000100010001000100650092004D +1A58:000C0010000C0010000C00000000000000000000000000000000000000000000 +1A59:01E0021002D00150000000000000000000000000000000000000000000000000 +1A5A:00A00150011000A0000000000000000000000000000000000000000000000000 +1A5B:00000000000000000000000000000000000000000000000000400F4010400F80 +1A5C:0000000000000000000000000000000000000000000000000000094008C007A0 +1A5D:0000000000000000000000000000000000000000000000000000084008400780 +1A5E:00000000000000000000000000000000000000000000000000000C8002400D80 +1A5F:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE618E7DBE61BE7FFE0000 +1A60:00000000000000000000000000000000000000000000000000000008001C0008 +1A61:0000000000000000000000000003000000000000000300000000000000000000 +1A62:0000001000200040000000000000000000000000000000000000000000000000 +1A63:0000000000000000000000020001000100010001000100020000000000000000 +1A64:00000000000E0011001100010001000100010001000100010000000000000000 +1A65:01E0021002100120000000000000000000000000000000000000000000000000 +1A66:01E0021002200110000000000000000000000000000000000000000000000000 +1A67:01F0020802480110000000000000000000000000000000000000000000000000 +1A68:03B0044804480290000000000000000000000000000000000000000000000000 +1A69:0000000000000000000000000000000000000000000000000010001000180000 +1A6A:00000000000000000000000000000000000000000000000000280028002C0000 +1A6B:0000000000780064000200000000000000000000000000000000000000000000 +1A6C:0000000000000000000000000000000000000000000000000000002000480036 +1A6D:0000000100010001000100010001000100010001000100010005000900090006 +1A6E:0000000000000000000040008000800080008000800040000000000000000000 +1A6F:000000000000000000005000A000A000A000A000A00050000000000000000000 +1A70:0000400080008000800040008000800080008000800040000000000000000000 +1A71:0000000080004000200060008000800080008000800040000000000000000000 +1A72:00004000A0002000200060008000800080008000800040000000000000000000 +1A73:0040004000A00318000000000000000000000000000000000000000000000000 +1A74:0200050002000000000000000000000000000000000000000000000000000000 +1A75:0000080008000800000000000000000000000000000000000000000000000000 +1A76:0000020014000800000000000000000000000000000000000000000000000000 +1A77:0000001000280044000000000000000000000000000000000000000000000000 +1A78:0002000200020012000C00000000000000000000000000000000000000000000 +1A79:0018000400180010000C00000000000000000000000000000000000000000000 +1A7A:00700048012400E4000000000000000000000000000000000000000000000000 +1A7B:000C001600140014000000000000000000000000000000000000000000000000 +1A7C:00340048012000C0000000000000000000000000000000000000000000000000 +1A7D:00007FFE7B8673B67B867BB671B67FFE7FFE618E7DB67BB677B6778E7FFE0000 +1A7E:00007FFE7B8673B67B867BB671B67FFE7FFE61867DBE7B8E77BE77867FFE0000 +1A7F:0000000000000000000000000000000000000000000000000600090009000600 +1A80:0000000000000000000001C00220041004100410022001C00000000000000000 +1A81:0000000000000000000003800440002000200020044003800000000000000000 +1A82:00000000000000000000001000100010001000100010001004100410022001C0 +1A83:0000000000000000038004400020002000200440038002000100010000800040 +1A84:000000000000000001C00220040004000400022001C000400080008001000200 +1A85:0000000000000000000001C002200410071004900310001004100410022001C0 +1A86:01C00220041004000460049004E0048004700410022001C00000000000000000 +1A87:0000000000000000000003800440044004400440044002400040004000400030 +1A88:0000000000000000000001C00220041004100510029001200000000000000000 +1A89:000000000000000001C0022004100470048004E00490046004000410022001C0 +1A8A:00007FFE7B8673B67B867BB671B67FFE7FFE73866DB673866DB673B67FFE0000 +1A8B:00007FFE7B8673B67B867BB671B67FFE7FFE738E6DB6738E6DB6738E7FFE0000 +1A8C:00007FFE7B8673B67B867BB671B67FFE7FFE73C66DBE73BE6DBE73C67FFE0000 +1A8D:00007FFE7B8673B67B867BB671B67FFE7FFE738E6DB673B66DB6738E7FFE0000 +1A8E:00007FFE7B8673B67B867BB671B67FFE7FFE73866DBE738E6DBE73867FFE0000 +1A8F:00007FFE7B8673B67B867BB671B67FFE7FFE73866DBE738E6DBE73BE7FFE0000 +1A90:0000000000000000000001C00220041004100410022001C00000000000000000 +1A91:0000000000000000002001A00260040004000500028001000000000000000000 +1A92:01C0022004100410041004000400040004000600050002000000000000000000 +1A93:000000000100010000801C70220801040104010422881C700000000000000000 +1A94:0000000000000000000002600490042004400420021003E0020002E0021001E0 +1A95:0020002000400180020004600490042004400420021003E00000000000000000 +1A96:0010002000200020002002200520042002200420052002C00000000000000000 +1A97:0000000000000000000002400520041002100410052002C00000000000000000 +1A98:0000000000000000000018C02520421040102060004003F8044409F20A490431 +1A99:000000000000000000000E181104208220822882144408380000000000000000 +1A9A:00007FFE7B8673B67B867BB671B67FFE7FFE73866DB671867DB673B67FFE0000 +1A9B:00007FFE7B8673B67B867BB671B67FFE7FFE738E6DB6718E7DB6738E7FFE0000 +1A9C:00007FFE7B8673B67B867BB671B67FFE7FFE73C66DBE71BE7DBE73C67FFE0000 +1A9D:00007FFE7B8673B67B867BB671B67FFE7FFE738E6DB671B67DB6738E7FFE0000 +1A9E:00007FFE7B8673B67B867BB671B67FFE7FFE73866DBE718E7DBE73867FFE0000 +1A9F:00007FFE7B8673B67B867BB671B67FFE7FFE73866DBE718E7DBE73BE7FFE0000 +1AA0:0000000003E004900888108410841FFC108410840888049003E0000000000000 +1AA1:00000000038004800880108010801FFC108410840888049003E0000000000000 +1AA2:0012004C003800D000201CC0222001100110011022201DC00000000000000000 +1AA3:000000000080014001C002200C9815540C98022001C001400080000000000000 +1AA4:0000000000000FE0101027C8282829C8281027E0100C0FF00000000000000000 +1AA5:000003E00220094815540AA865535A2D44115A2D65530AA815540948022003E0 +1AA6:000001C00220041004100190026002000260019004100410022001C000000000 +1AA7:000000000000000003B004480A48040800080010006001800200040004000400 +1AA8:0000000000000000000002000200020002000200020002000000000000000000 +1AA9:0000000000000000000009000900090009000900090009000000000000000000 +1AAA:0000000000000000000004000800090007000100010001000000000000000000 +1AAB:000000000000000000000880108012800E800280028002800000000000000000 +1AAC:000000380004000401C4022800300E201140018011000E000000000000000000 +1AAD:00000000000000000000010002800500044002200410041004100410022001C0 +1AAE:00007FFE7B8673B67B867BB671B67FFE7FFE61866DBE618E6DBE6D867FFE0000 +1AAF:00007FFE7B8673B67B867BB671B67FFE7FFE61866DBE618E6DBE6DBE7FFE0000 +1AB0:00142A49000000000000000000000000 +1AB1:00081455080000000000000000000000 +1AB2:00364936000000000000000000000000 +1AB3:00082A1C080000000000000000000000 +1AB4:00000822000000000000000000000000 +1AB5:00000000000000000000000000552255 +1AB6:00000000000000000000000000002A55 +1AB7:00000000000000000000000000080804 +1AB8:00000000000000000000000000242412 +1AB9:00000000000000000000000000204080 +1ABA:0000000000000000000000000020C0C0 +1ABB:00004281814200000000000000000000 +1ABC:0024C3C3C3C324000000000000000000 +1ABD:00000000000000000000000042818142 +1ABE:00000000000000000000428181420000 +1ABF:00000000000000000000000000005428 +1AC0:00000000000000000000000000002854 +1AC1:00007FFE7B8673B67B867BB671B67FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000 +1AC2:00007FFE7B8673B67B867BB671B67FFE7FFE71866FF66F866FBE71867FFE0000 +1AC3:00007FFE7B8673B67B867BB671B67FFE7FFE718E6FF66FC66FF6718E7FFE0000 +1AC4:00007FFE7B8673B67B867BB671B67FFE7FFE71B66FB66F866FF671F67FFE0000 +1AC5:00007FFE7B8673B67B867BB671B67FFE7FFE71866FBE6F866FF671867FFE0000 +1AC6:00007FFE7B8673B67B867BB671B67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000 +1AC7:00007FFE7B8673B67B867BB671B67FFE7FFE71866FF66FEE6FDE71DE7FFE0000 +1AC8:00007FFE7B8673B67B867BB671B67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +1AC9:00007FFE7B8673B67B867BB671B67FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +1ACA:00007FFE7B8673B67B867BB671B67FFE7FFE71866FB66F866FB671B67FFE0000 +1ACB:00007FFE7B8673B67B867BB671B67FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +1ACC:00007FFE7B8673B67B867BB671B67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +1ACD:00007FFE7B8673B67B867BB671B67FFE7FFE718E6FB66FB66FB6718E7FFE0000 +1ACE:00007FFE7B8673B67B867BB671B67FFE7FFE71866FBE6F8E6FBE71867FFE0000 +1ACF:00007FFE7B8673B67B867BB671B67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +1AD0:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DB66DB66DB663CE7FFE0000 +1AD1:00007FFE7B8673B67B867BB671B67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000 +1AD2:00007FFE7B8673B67B867BB671B67FFE7FFE63866DF66D866DBE63867FFE0000 +1AD3:00007FFE7B8673B67B867BB671B67FFE7FFE638E6DF66DC66DF6638E7FFE0000 +1AD4:00007FFE7B8673B67B867BB671B67FFE7FFE63B66DB66D866DF663F67FFE0000 +1AD5:00007FFE7B8673B67B867BB671B67FFE7FFE63866DBE6D866DF663867FFE0000 +1AD6:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000 +1AD7:00007FFE7B8673B67B867BB671B67FFE7FFE63866DF66DEE6DDE63DE7FFE0000 +1AD8:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000 +1AD9:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DB66DC66DF663CE7FFE0000 +1ADA:00007FFE7B8673B67B867BB671B67FFE7FFE63866DB66D866DB663B67FFE0000 +1ADB:00007FFE7B8673B67B867BB671B67FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +1ADC:00007FFE7B8673B67B867BB671B67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +1ADD:00007FFE7B8673B67B867BB671B67FFE7FFE638E6DB66DB66DB6638E7FFE0000 +1ADE:00007FFE7B8673B67B867BB671B67FFE7FFE63866DBE6D8E6DBE63867FFE0000 +1ADF:00007FFE7B8673B67B867BB671B67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +1AE0:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663B66FB661CE7FFE0000 +1AE1:00007FFE7B8673B67B867BB671B67FFE7FFE61EE6FCE63EE6FEE61C67FFE0000 +1AE2:00007FFE7B8673B67B867BB671B67FFE7FFE61866FF663866FBE61867FFE0000 +1AE3:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FF663C66FF6618E7FFE0000 +1AE4:00007FFE7B8673B67B867BB671B67FFE7FFE61B66FB663866FF661F67FFE0000 +1AE5:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE63866FF661867FFE0000 +1AE6:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FBE638E6FB661CE7FFE0000 +1AE7:00007FFE7B8673B67B867BB671B67FFE7FFE61866FF663EE6FDE61DE7FFE0000 +1AE8:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663CE6FB661CE7FFE0000 +1AE9:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663C66FF661CE7FFE0000 +1AEA:00007FFE7B8673B67B867BB671B67FFE7FFE61866FB663866FB661B67FFE0000 +1AEB:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FB6638E6FB6618E7FFE0000 +1AEC:00007FFE7B8673B67B867BB671B67FFE7FFE61C66FBE63BE6FBE61C67FFE0000 +1AED:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FB663B66FB6618E7FFE0000 +1AEE:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE638E6FBE61867FFE0000 +1AEF:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE638E6FBE61BE7FFE0000 +1AF0:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663B66FB66FCE7FFE0000 +1AF1:00007FFE7B8673B67B867BB671B67FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000 +1AF2:00007FFE7B8673B67B867BB671B67FFE7FFE61866FF663866FBE6F867FFE0000 +1AF3:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FF663C66FF66F8E7FFE0000 +1AF4:00007FFE7B8673B67B867BB671B67FFE7FFE61B66FB663866FF66FF67FFE0000 +1AF5:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE63866FF66F867FFE0000 +1AF6:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +1AF7:00007FFE7B8673B67B867BB671B67FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +1AF8:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +1AF9:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +1AFA:00007FFE7B8673B67B867BB671B67FFE7FFE61866FB663866FB66FB67FFE0000 +1AFB:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +1AFC:00007FFE7B8673B67B867BB671B67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +1AFD:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FB663B66FB66F8E7FFE0000 +1AFE:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE638E6FBE6F867FFE0000 +1AFF:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +1B00:0FE0111012900920000000000000000000000000000000000000000000000000 +1B01:01000AA00AA007C0000000000000000000000000000000000000000000000000 +1B02:0100028000400020000000000000000000000000000000000000000000000000 +1B03:00000200010000F0000000000000000000000000000000000000000000000000 +1B04:0000000000000000000200050001000200010001000100010001000000000000 +1B05:000000000000000000000E70112824A42A2422FC24A412240CC4000000000000 +1B06:00000000000000000000380044389244A8828882928249443628000000000000 +1B07:000000000000000011B02A480A080A0804C8010000C0022001C0000000000000 +1B08:000000000000000046CCA9222821282113260400030008800700000000000000 +1B09:00000000000000000B800440004000800300040009C00A200410000000000000 +1B0A:0000000000000000173008880084010406180800138014400820000000000000 +1B0B:000000000000000008101428042803C801800200018004400380000000000000 +1B0C:00000000000000004098A14421421E420C0C10000C0022001C00000000000000 +1B0D:000000000000000011B02A480A0A0A7C04880110009000600040000000000000 +1B0E:000000000000000046C0A920282E29F112210442024901890106000000000000 +1B0F:000000000000000003800C001000138014400C20000000000000000000000000 +1B10:000000000000000046C5A92B282E282210420782080210C20F3C000000000000 +1B11:000000000000000046C0A9202820282010400780080011C00E20000000000000 +1B12:000000000000000046CCA9222821282110460780080011C00E20000000000000 +1B13:000000000000000023CC542A142A3F2A54AA2312000000000000000000000000 +1B14:000000000000000023C0542014203F2054A0231C000200000000000000000000 +1B15:0000000000000000239854541454145412940EE4000000000000000000000000 +1B16:00000000000000002338551415141514155408A4000000000000000000000000 +1B17:0000000000000000236054901410141014100C10000000000000000000000000 +1B18:00000000000000000870144804280E28152808C8000000000000000000000000 +1B19:00000000000000003C30422842284A284A2831C8000000000000000000000000 +1B1A:000000000000000011E02A100A100A600A100608000800000000000000000000 +1B1B:0000000C0012000F46C2A9222822282210420782080210C20F3C000000000000 +1B1C:000000000000000046C6A9292829282928291832000000000000000000000000 +1B1D:0000000000000000236054901010381054104800210022001C00000000000000 +1B1E:0000000000000000236054901010111011100E00000000000000000000000000 +1B1F:0000000000000000203050281028102813280CC8000000000000000000000000 +1B20:0000000000000000101028100810081009900660000000000000000000000000 +1B21:00000000000000009CE2A3154015001500150019000000000000000000000000 +1B22:000000000000000023CC542A172A10AA10AA0F12000000000000000000000000 +1B23:000000000000000011E0289008500A5009500790010000000000000000000000 +1B24:000000000000000008701488048809C812A80C48000000000000000000000000 +1B25:0000000000000000107828240814081409940664000000000000000000000000 +1B26:000000000000000008F0150805080FC8152808C8000000000000000000000000 +1B27:0000000000000000106028500850085008500790000000000000000000000000 +1B28:00000000000000001088295008E0084008400780000000000000000000000000 +1B29:000000000000000046CCA92A282A282A282A1832000000000000000000000000 +1B2A:000000000000000020F05108090803C8152808C8000000000000000000000000 +1B2B:00000000000000001FB024282428032804280448038800000000000000000000 +1B2C:0000000000000000200850141114111412940C64000000000000000000000000 +1B2D:000000000000000010E029100510051005100610000000000000000000000000 +1B2E:0000000000000000460CA90A290A290A290A10F2000000000000000000000000 +1B2F:000000000000000008F0144804280428042803C8000000000000000000000000 +1B30:000000000000000047E6A9152A95289524A51C39000000000000000000000000 +1B31:0000000000000000206050501250155011500FD0010000000000000000000000 +1B32:00000000000000001060285008501C502A501190000000000000000000000000 +1B33:000000000000000040CCA12A212A212A212A1E12000000000000000000000000 +1B34:0000010000000440000000000000000000000000000000000000000000000000 +1B35:0000000000000000000C00020001000100090006000000000000000000000000 +1B36:03C014200C200240000000000000000000000000000000000000000000000000 +1B37:03C015200EA00460000000000000000000000000000000000000000000000000 +1B38:000000000000000000000000000000010003000300030005000900110012000C +1B39:0000000000000000000000000000000100020004000400020001000100020004 +1B3A:000000000000000000000000000000000000002000100410099008A007C00080 +1B3B:0000000000000000000C0002000100010009002600100410099008A007C00080 +1B3C:00E0012012400A80000000000000000000000000000000002308548814880870 +1B3D:00E0012012400A80000C00020001000100090006000000002308548814880870 +1B3E:0000000000000000300048000800100010002000200020001000000000000000 +1B3F:38004000300008003000B000C800900010002000200020001000000000000000 +1B40:0000000000000000300C48020801100110092006200020001000000000000000 +1B41:3800400030000800300CB002C801900110092006200020001000000000000000 +1B42:00E0012012400A80000000000000000000000000000000000000000000000000 +1B43:00E0012012400A80000C00020001000100090006000000000000000000000000 +1B44:000E001100110001000200020002000200020002000200010001000000000000 +1B45:000000000000000023CC542A1C2A3F2A5CAA2B12080008800700000000000000 +1B46:00000000000000004716A8AD28AD7CADAAAD4444000000000000000000000000 +1B47:000000000000000023CC542A172A10AA14AA0F12040004400380000000000000 +1B48:00000000000000000830142804280528052803C80100011000E0000000000000 +1B49:000000000000000008F0144804280528052803C80100011000E0000000000000 +1B4A:00000000000000001060285008501D502B5011900100011000E0000000000000 +1B4B:00000000000000004302A2A522A572B5AAB544B5004D00000000000000000000 +1B4C:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000 +1B4D:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000 +1B4E:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE6D866DBE618E7DBE7D867FFE0000 +1B4F:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000 +1B50:0000000000000000018002400240018000000000000000000000000000000000 +1B51:00000004000A0007236254921412141214140C38000000000000000000000000 +1B52:000000000000000011B02A480A0A0A7C04880110009000600040000000000000 +1B53:000000000000000046C0A9202820282010400780080011C00E20000000000000 +1B54:0000000000000000000000000B00088009000880048003000000000000000000 +1B55:0000000000000000078008400B2008A0092008A004A003200020002000100000 +1B56:000000000000000003800C001000138014400C20000000000000000000000000 +1B57:00000000000000004622A95429382910291018E0000000000000000000000000 +1B58:00000000000000001088295008E0084008400780000000000000000000000000 +1B59:0000000000000000202250541138111012900C60000000000000000000000000 +1B5A:00000000000000000C3012481248924892486189000900060000000000000000 +1B5B:000000000000000046CCA92A282A282A282A180A023F124A118A100A118A0E72 +1B5C:0000000000000000018002400240018000000000000000000000000000000000 +1B5D:0000000000000000031004A003C00000031004A003C000000000000000000000 +1B5E:0000000000000000020005000080008000400040002000200020000000000000 +1B5F:0000000000000000104028A00410041002080208010401040104000000000000 +1B60:0000000000000000018000400180044003800000000000000000000000000000 +1B61:0000000000000000000C00020001000100090006000000000000000000000000 +1B62:0000000000000000058006400440008000800100010001000080000000000000 +1B63:0000000000000000004000C000C000C001400240044004800300000000000000 +1B64:0000000000000000000002000500008000800040004000000000000000000000 +1B65:00000000000000000000000002000200010000F0000000000000000000000000 +1B66:00000000000000000000000003C014200C200240000000000000000000000000 +1B67:0000000000000000000000000070009009200540000000000000000000000000 +1B68:0000000000000000080010002000200010000800080010002000000000000000 +1B69:000000000000000046CCA92A282A282A104A078A080A118A0E72000000000000 +1B6A:0000000000000000080014000400080004000400040008000800080004000400 +1B6B:0080010000800000000000000000000000000000000000000000000000000000 +1B6C:0000000000000000000000000000000000000000000000000000008001000080 +1B6D:0300010007C00100010000000000000000000000000000000000000000000000 +1B6E:000003C000000000000000000000000000000000000000000000000000000000 +1B6F:0100028004400000000000000000000000000000000000000000000000000000 +1B70:070001000FE00380054000000000000000000000000000000000000000000000 +1B71:07F0014002200410000000000000000000000000000000000000000000000000 +1B72:0440028001000000000000000000000000000000000000000000000000000000 +1B73:0380044005400440038000000000000000000000000000000000000000000000 +1B74:0000000000000000000010002800280044004400000000000000000000000000 +1B75:0000000000000000000030004800480048003000000000000000000000000000 +1B76:0000000000000000000090006800280054004400000000000000000000000000 +1B77:00000000000000000000B8004400640054003800000000000000000000000000 +1B78:0000000000000000000000000000000078000000000000000000000000000000 +1B79:0000000000000000000010001000200020004000780000000000000000000000 +1B7A:0000000000000000000000004000200078001000080000000000000000000000 +1B7B:00000000000000000000900050002000300048007C0000000000000000000000 +1B7C:0000000000000000000000000000300030000000000000000000000000000000 +1B7D:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE618E7DB67BB677B6778E7FFE0000 +1B7E:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61867DBE7B8E77BE77867FFE0000 +1B7F:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +1B80:0020005000200000000000000000000000000000000000000000000000000000 +1B81:0022005400080000000000000000000000000000000000000000000000000000 +1B82:0000000000000000000000000000000000040012000A00080000000000000000 +1B83:000000000000000005F00820084008E00810042003C000000000000000000000 +1B84:000000000000000000C00100010002000200042007E000000000000000000000 +1B85:000000000000000007000100010002300240042007E000000000000000000000 +1B86:00000000000000000BE0104010F011C810200840078000000000000000000000 +1B87:000000000000000007000500030002000220045007D000000000000000000000 +1B88:000000000000000000F00100010008F00810042003C000000000000000000000 +1B89:00000000000000500420080008F008200870041003E000000000000000000000 +1B8A:0000000000000000077001100110022002200440044000000000000000000000 +1B8B:000000000000000001F802480248049004900920092000000000000000000000 +1B8C:000000000000000007000100010002700210042007E000000000000000000000 +1B8D:000000000000000007000100010002400220041007F000000000000000000000 +1B8E:0000000000000000070401080108021006100B2004E000000000000000000000 +1B8F:00000000000000000180020002000400052009900F4800000000000000000000 +1B90:00000000000000000700010001000200024004A007A000000000000000000000 +1B91:00000000000000000E3E0242020204C404A409280F1800000000000000000000 +1B92:0000000000000000002000400C700490049009200F2000000000000000000000 +1B93:000000000000000001C002000200044004A008900F8800000000000000000000 +1B94:00000000000000000F000100010002000200040007E000000000000000000000 +1B95:000000000000000007700110011002200220044007C000000000000000000000 +1B96:000000000000000007080110011002200220044007C000000000000000000000 +1B97:000000000000000000880110011002200220044007C000000000000000000000 +1B98:0000000000000000019F022102010462045208940F8C00000000000000000000 +1B99:000000000000000007F000100E1002200220044007C000000000000000000000 +1B9A:0000000000000000002000400C4404A404A809280F1000000000000000000000 +1B9B:000000000000000003E0000007C0004003E00080008000000000000000000000 +1B9C:000000000000000001C20244024404880488091009F000000000000000000000 +1B9D:00000000000000000180020002000470041008200FE000000000000000000000 +1B9E:00000000000000000F780108010807BC02100420042000000000000000000000 +1B9F:000000000000000007F00110011007E002200440044000000000000000000000 +1BA0:0000000000000000003C00240E24024802480490079000000000000000000000 +1BA1:00000000000000000000000000000000000700050008000800100010041007E0 +1BA2:000000000000000000000000000000000000000000000000000004100A0801F0 +1BA3:0000000000000000000000000000000000000000000000000C00140016000000 +1BA4:0700010006000000000000000000000000000000000000000000000000000000 +1BA5:00000000000000000000000000000000000000000000000001C0004000800000 +1BA6:000000000000000000000000E000200070008000E00000000000000000000000 +1BA7:0000000000000000000000000000000700010002001C00070000000000000000 +1BA8:11000A0004000000000000000000000000000000000000000000000000000000 +1BA9:29001A0004000000000000000000000000000000000000000000000000000000 +1BAA:00000000000000000000001F0001000200040007000100020004000400040003 +1BAB:0000000000000000000000000000000000000000000000000100038001000000 +1BAC:0000000000000000000000000000000000000000000000001A0022001C000000 +1BAD:0000000000000000000000000000000000000000000000001B0009000D800000 +1BAE:00000000000000000FDF0251025104920492091409F400000000000000000000 +1BAF:00000000000000000FC8024802490FC904D50955097200000000000000000000 +1BB0:000000000000000003C00420081008100810042003C000000000000000000000 +1BB1:000000000000000007E00910010002700210042007E000000000000000000000 +1BB2:000000000000000007000900010002000390042007E000000000000000000000 +1BB3:000000000000000007000900010002300240042007E000000000000000000000 +1BB4:000000000000000001C00240005003E004800100010000000000000000000000 +1BB5:000000000000000006C00AA002800440044008200FE000000000000000000000 +1BB6:000000000000000000C00120010002300240042007E000000000000000000000 +1BB7:0000000000000000038C0490049009200920124033C000000000000000000000 +1BB8:00000000000000001C1824240420084018402C80138000000000000000000000 +1BB9:000000000000000003C00520010002300240042007E000000000000000000000 +1BBA:0000000000000000000007E00020002007C00040008000800100010002000200 +1BBB:000000000000000007700110011002200220044007C0000007C0000000000000 +1BBC:00000000000000000C0E100210022304228444887C49001100720092006C0000 +1BBD:00000000000000000F3E112219260240024002400FF800000000000000000000 +1BBE:00000000000000001F7C010419640A28124804101FFC00000000000000000000 +1BBF:00000000000000000FE000200F2000400E4000800C8000000000000000000000 +1BC0:000000000000000000000000000001C04220242018E000000000000000000000 +1BC1:000000000000000000000000000001C04220240018E000000000000000000000 +1BC2:0000000000000000000000003B80444008401080210000000000000000000000 +1BC3:000000000000000000000E0031804040000000000CC000000000000000000000 +1BC4:000000000000000000000E003180404008801100220000000000000000000000 +1BC5:000000000000000000000E003180404044404A40318000000000000000000000 +1BC6:000000000000000000001F8020404020402020401F8000000000000000000000 +1BC7:000000000000000000000000000000007FC00000000000000000000000000000 +1BC8:0000000000000000000000000000038044403800000000000000000000000000 +1BC9:00000000000000007E00000007C008201010082007C000000000000000000000 +1BCA:00000000000000007E0000001CE0030004800840078000000000000000000000 +1BCB:0000000000000000000000000E0031804040404071C000000000000000000000 +1BCC:0000000000000000000000000E0031804040000071C000000000000000000000 +1BCD:0000000000000000000000001F00100010000F00008000800000000000000000 +1BCE:0000000000000000000000000E00318040400080010000000000000000000000 +1BCF:0000000000000000000000000E0031804040000001C000000000000000000000 +1BD0:00000000000000000000000001800600180060E00C0003000000000000000000 +1BD1:00000000000000000000000001800600180060000C0003000000000000000000 +1BD2:000000000000000000000E00318040401F002080404000800000000000000000 +1BD3:0000000000000000000000007C0000007FC0000001C000000000000000000000 +1BD4:0000000000000000000000007CE01100120013000CC000000000000000000000 +1BD5:00000000000000000000380044C003000C003000060001800000000000000000 +1BD6:000000000000000000003FC0108009000600090030C000000000000000000000 +1BD7:000000000000000000000000000071802240244019C000000000000000000000 +1BD8:0000000000000000000000003BC0442008000C00030000000000000000000000 +1BD9:0000000000000000000000000E003180404000000E0000000000000000000000 +1BDA:0000000000000000000000000E00318048400400020000000000000000000000 +1BDB:0000000000000000000000000000718022402440180000000000000000000000 +1BDC:000000000000000000000000380044C0112012200C0000000000000000000000 +1BDD:0000000000000000000001800600180060001800060001800000000000000000 +1BDE:000000000000000000000000070018C020201000080000000000000000000000 +1BDF:0000000000000000000000000E00318040400000700000000000000000000000 +1BE0:000000000000000000000780184020004C006300180000000000000000000000 +1BE1:00000000000000000000000030004A004D2048C0300000000000000000000000 +1BE2:00000000000000000000000030000C00030000C0060018000000000000000000 +1BE3:000000000000000000001F8020404620462020401F8000000000000000000000 +1BE4:000000000000000000000E00318040400E00110000000E000000000000000000 +1BE5:000000000000000000000E00000011000E00404031800E000000000000000000 +1BE6:0700000007000000000000000000000000000000000000000000000000000000 +1BE7:0000000000000000000000000008000400020004000800000000000000000000 +1BE8:0040002000100020004000000000000000000000000000000000000000000000 +1BE9:0000000070000000000000000000000000000000000000000000000000000000 +1BEA:000000000000000000000000000C001200120012000C00000000000000000000 +1BEB:00000000000000000000000000000000000C0000000C00000000000000000000 +1BEC:0000000000000000000000000011000A0004000A001100000000000000000000 +1BED:0040002007100020004000000000000000000000000000000000000000000000 +1BEE:0000000000000000000000000000000000000000002000100008001000200000 +1BEF:0000000002000400080000000000000000000000000000000000000000000000 +1BF0:0000000000070000000000000000000000000000000000000000000000000000 +1BF1:0007000000070000000000000000000000000000000000000000000000000000 +1BF2:0000000000000000000000000000000000080004000200000000000000000000 +1BF3:00000000000000000000000000000000000E0000000000000000000000000000 +1BF4:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61B66FB663866FF66FF67FFE0000 +1BF5:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61866FBE63866FF66F867FFE0000 +1BF6:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +1BF7:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +1BF8:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +1BF9:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +1BFA:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61866FB663866FB66FB67FFE0000 +1BFB:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +1BFC:0000101020082388145008201450228821082288145008201450238820081010 +1BFD:00000000000001000280028004401AB021081AB0044002800280010000000000 +1BFE:0000000000000000111022202220222011100888088808881110000000000000 +1BFF:00000000000000000E0001000080008000800080008001000E00000000000000 +1C00:00000000000000000000000003E0040004000FE00400040007C0000000000000 +1C01:0000000000000000000000000FC0040005800640084000800100000000000000 +1C02:00000000000000000000000002600480088008400820042003C0000000000000 +1C03:000000000000000000000000040008401240122011200B400480000000000000 +1C04:0000000000000000000000000400084012403FF011200B400480000000000000 +1C05:000000000000000000000000080007C000800080010001000100000000000000 +1C06:0000000000000000000000000180024002401C20024002400180000000000000 +1C07:0000000000000000000000000060008007800980024004200FE0000000000000 +1C08:0000000000000000000000000360048009400940088004000200000000000000 +1C09:000000000000000000000000082007C00200052008C004000200000000000000 +1C0A:0000000000000000000000000200010004800A40098004000200000000000000 +1C0B:0000000000000000000000000800080005C0022005C008000800000000000000 +1C0C:000000000000000000000000010012400F8002000F8012400100000000000000 +1C0D:00000000000000000000000001800240044008200920092008C0000000000000 +1C0E:0000000000000000000000000FC000800080004000400C401380000000000000 +1C0F:000000000000000000000000062009C0080004000FE000000000000000000000 +1C10:0000000000000000000000001FE008401040102008200E2011C0000000000000 +1C11:0000000000000000000000000FC0100010001FC010800C401380000000000000 +1C12:00000000000000000000000004200A5012501130111008A004C0000000000000 +1C13:0000000000000000000000000300048008400820082004400380000000000000 +1C14:000000000000000000000000024005A008900810081004200240000000000000 +1C15:0000000000000000000000001FC0018002000F80124002400180000000000000 +1C16:0000000000000000000000000FE00100008007E0088009000600000000000000 +1C17:0000000000000000000000000FF00420084008400820042003C0000000000000 +1C18:0000000000000000000000000400088011401540148013600C00000000000000 +1C19:0000000000000000000000000240048004E007801C8002400120000000000000 +1C1A:0000000000000000000000000300040008800700084008800700000000000000 +1C1B:00000000000000000000000010400F8008000400040008001000000000000000 +1C1C:00000000000000000000000004400A2012101110111008A004C0000000000000 +1C1D:0000000000000000000000000030084004400FE0044004400380000000000000 +1C1E:0000000000000000000000001040088005000200050008801040000000000000 +1C1F:0000000000000000000000000300048008400FE0082004400380000000000000 +1C20:0000000000000000000000000400084011401540148013000C00000000000000 +1C21:00000000000000000000000004000800094009400A80042003C0000000000000 +1C22:0000000000000000000000000DD0122015501550122008000400000000000000 +1C23:00000000000000000000000007C009200140038004A0044003A0000000000000 +1C24:0000000000000000000000000000000000000002000A000A0004000000000000 +1C25:0000000000000000000000000010000800080008000800080010000000000000 +1C26:0000000000000000000000000001000200020002000200020001000000000000 +1C27:000000004000A000800040004000400040004000400040004000C00000000000 +1C28:0000000000000000000000002000400040004000400040002000000000000000 +1C29:00000000000000003FC040004000400040004000400040002000000000000000 +1C2A:000000000000000000000000000200010001000100010001000100010012000C +1C2B:000000000000000000000006000100020001000100010001000100010012000C +1C2C:0000000000000000000000000000000000000000000000000000020004000F00 +1C2D:0000010002000300000000000000000000000000000000000000000000000000 +1C2E:0000000002800000000000000000000000000000000000000000000000000000 +1C2F:0000010004400000000000000000000000000000000000000000000000000000 +1C30:000003C0042000C0000000000000000000000000000000000000000000000000 +1C31:0000010002800100000000000000000000000000000000000000000000000000 +1C32:0000032004C00000000000000000000000000000000000000000000000000000 +1C33:0000000007C00000000000000000000000000000000000000000000000000000 +1C34:00000000000000000000000080004000A000A000A00040008000000000000000 +1C35:0000000000000000000000000000000040008000800040000000000000000000 +1C36:0FE0100000000000000000000000000000000000000000000000000000000000 +1C37:0000000000000000000000000000000000000000000000000000000000400000 +1C38:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63CE7DB671CE7DB663CE7FFE0000 +1C39:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63CE7DB671C67DF663CE7FFE0000 +1C3A:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63867DB671867DB663B67FFE0000 +1C3B:0000000000000000000000000000008000800080008000800080000000000000 +1C3C:0000000000000000000000000000024002400240024002400240000000000000 +1C3D:0000000000000000000000000000000002200140008001400220000000000000 +1C3E:0000000000000000000000000000000002200140049001400220000000000000 +1C3F:0000000000000000000000001088091004A0042004A009101088000000000000 +1C40:0000000000000000000000000000038004400440044003800000000000000000 +1C41:0000000000000000000000000100028002C00140004000800100000000000000 +1C42:00000000000000000000000007C0082000C003000400030000C0000000000000 +1C43:0000000000000000000000000F80104007E00810002007C00020000000000000 +1C44:000000000000000000000000022005C004000800083007C00000000000000000 +1C45:00000000000000000000000008100420046004A0052006200810000000000000 +1C46:00000000000000000000000000200050008000400820061001E0000000000000 +1C47:0000000000000000000000000080044002400240014001800200000000000000 +1C48:0000000000000000000000000180024002000400040003800060000000000000 +1C49:0000000000000000000000000180024002800260020002000100000000000000 +1C4A:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE6D866DB661867DB67DB67FFE0000 +1C4B:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000 +1C4C:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000 +1C4D:0000000000000000000000001F80008003E00080008000800100000000000000 +1C4E:0000000000000000000000001F80008003E0008003E000800100000000000000 +1C4F:0000000000000000000000000D2013E00120012001200F201040000000000000 +1C50:00000038444444444444444444380000 +1C51:00000062524A464040404020100E0000 +1C52:00000018242414081020424224180000 +1C53:000000324A4A3E1020204040300C0000 +1C54:0000001E2040404060524E4224180000 +1C55:00000010204648505048464224180000 +1C56:0000005C22524C4040404020100C0000 +1C57:0000000C523204081020424224180000 +1C58:000000344A5A64404040404224180000 +1C59:0000001C204040404C52524A24180000 +1C5A:0000001C22660A1222424242221C0000 +1C5B:0000003C4242424242424242423C0000 +1C5C:0000001C2240404E50504E4224180000 +1C5D:0000001C2244481026104844221C0000 +1C5E:00000048546242424242625448400000 +1C5F:000000245ADA1232525292A2A4480000 +1C60:00000040485462424242422214080000 +1C61:00000048444242424242426254480000 +1C62:0000001222424242424242462A120000 +1C63:00000064928A0A0A12E2824224180000 +1C64:0000003844060A0A1212222242420000 +1C65:000000424244444848505060221C0000 +1C66:000000444482828282828292AA440000 +1C67:00000010284442424242462A12020000 +1C68:0000007804024222120A0622528C0000 +1C69:00000040485462420202422214080000 +1C6A:0000003844444444444444BA827C0000 +1C6B:00000010284482925410704044380000 +1C6C:00000044AA9282828282828244440000 +1C6D:000000304884848C90A0A0A2924C0000 +1C6E:000000384404080810102020423C0000 +1C6F:0000003C62A4A42424242525463C0000 +1C70:00000058949292929292929252340000 +1C71:0000003CC644444848505060221C0000 +1C72:0000003844060A0A12122222C37E0000 +1C73:0000001824420E1212120E4224180000 +1C74:00000048546242424242424244480000 +1C75:00000034529292929292929294580000 +1C76:000000629288080A12E2824224180000 +1C77:000000182422124E82828292AA440000 +1C78:00000000181800000000000000000000 +1C79:00000000000000000000001818000000 +1C7A:00000000181800000000001818000000 +1C7B:00000000000060920C00000000000000 +1C7C:00000000000000380000000000000000 +1C7D:000000304844241C0404044428100000 +1C7E:00000000001010101010101000000000 +1C7F:00000000002424242424242400000000 +1C80:00000000001C2A4A4440444A2A1C0000 +1C81:0000000000001E1222222222227F4141 +1C82:00000000000038444444444444380000 +1C83:0000000000001C2240404040221C0000 +1C84:00000000324E02020202020202020000 +1C85:0000000000007F494949494949490000 +1C86:000000007010101010101C12121C0000 +1C87:0000202078202020203C2222223C0000 +1C88:000000444A2A28103844444444380000 +1C89:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73CE6DB673C66DF673CE7FFE0000 +1C8A:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DB673866DB673B67FFE0000 +1C8B:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE738E6DB6738E6DB6738E7FFE0000 +1C8C:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73C66DBE73BE6DBE73C67FFE0000 +1C8D:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE738E6DB673B66DB6738E7FFE0000 +1C8E:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DBE738E6DBE73867FFE0000 +1C8F:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DBE738E6DBE73BE7FFE0000 +1C90:000000002020101008040242423C0000 +1C91:000000002038080834424242423C0000 +1C92:000000304848080834424242423C0000 +1C93:000000002C525252524C40201C620000 +1C94:000000003C42420202022242423C0000 +1C95:000000003C4242021C020242423C0000 +1C96:0000000020505054381C1212120C0000 +1C97:00000000344A4A4A4A4A4A4A4A320000 +1C98:000000003C4242424242424242240000 +1C99:000000000C0202021C020242423C0000 +1C9A:000000002A555555414142201E610000 +1C9B:000000003C424202023E4242423C0000 +1C9C:00000000023C4040407C4242423C0000 +1C9D:00000000285454545444444444240000 +1C9E:0000000020180402021C0242423C0000 +1C9F:00000000060A525222021222221C0000 +1CA0:00000000043840685454545444240000 +1CA1:00000000404040485048444444380000 +1CA2:000000001824243C66665A42423C0000 +1CA3:000000006C12120202020222221C0000 +1CA4:00000000344A4A4A4A340212221C0000 +1CA5:00000000040C04041C24040444380000 +1CA6:000000002C525252424440201C620000 +1CA7:00000000224242261A022242423C0000 +1CA8:0000000028545404041C242424180000 +1CA9:00000000384478405C62424242420000 +1CAA:000000004C4242425C424242423C0000 +1CAB:0000000004020202023E4242423C0000 +1CAC:0000000028545454407C442828100000 +1CAD:000000000818280819261D0444380000 +1CAE:00000000404040485078444444380000 +1CAF:00000000CCA2A2241418304A2AC40000 +1CB0:0000100C02120C02120C0242423C0000 +1CB1:00000000C8A6A1A9A6C1928C44380000 +1CB2:000000003C4242424224241824420000 +1CB3:000000003E0204081C020242423C0000 +1CB4:0000000008100C02021C0242423C0000 +1CB5:000000003844443E043E444444380000 +1CB6:00000000101010385454381010100000 +1CB7:000000003C42420408102042423C0000 +1CB8:000000004442424264584044423C0000 +1CB9:000000003C424242423C1012120C0000 +1CBA:000000003C42424040300C1C22400000 +1CBB:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE638E6DB6638E6DB6638E7FFE0000 +1CBC:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63C66DBE63BE6DBE63C67FFE0000 +1CBD:000000003C42422010080442423C0000 +1CBE:000000004224182424424242423C0000 +1CBF:000000003C42424242424242423C0000 +1CC0:00000000028001000380044029281AB029280440038001000280000000000000 +1CC1:000000000000000001C00220055004900550022001C000000000000000000000 +1CC2:000000000000000001C0022005D0041005D0022001C000000000000000000000 +1CC3:000000000000000001C00220041004100410022001C000000000000000000000 +1CC4:00000000000000001BBB200823CB481055969420F2AC002001C8024801B00000 +1CC5:00000000000000001CF8040004F0080009E0100013C000000000000000000000 +1CC6:00000000000000000EFF100010FE2200253C44807C5800000000000000000000 +1CC7:0000000000000000667D0884C8051188914B2250BE3600000000000000000000 +1CC8:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +1CC9:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +1CCA:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71866FB66F866FB671B67FFE0000 +1CCB:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +1CCC:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +1CCD:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE718E6FB66FB66FB6718E7FFE0000 +1CCE:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71866FBE6F8E6FBE71867FFE0000 +1CCF:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +1CD0:0080014002200000000000000000000000000000000000000000000000000000 +1CD1:008001C002A00000000000000000000000000000000000000000000000000000 +1CD2:000003E000000000000000000000000000000000000000000000000000000000 +1CD3:0000012002400480000000000000000000000000000000000000000000000000 +1CD4:0000000000000000000000000000003800000000000000000000000000000000 +1CD5:0000000000000000000000000000000000000000000000000000089004900360 +1CD6:00000000000000000000000000000000000000000000000000000000040007E0 +1CD7:00000000000000000000000000000000000000000000000000000300040003E0 +1CD8:00000000000000000000000000000000000000000000000000000420022001C0 +1CD9:0000000000000000000000000000000000000000000000000000008001400220 +1CDA:0140014001400000000000000000000000000000000000000000000000000000 +1CDB:02A002A002A00000000000000000000000000000000000000000000000000000 +1CDC:0000000000000000000000000000000000000000000000000000008000800080 +1CDD:0000000000000000000000000000000000000000000000000000000000800000 +1CDE:0000000000000000000000000000000000000000000000000000000001200000 +1CDF:0000000000000000000000000000000000000000000000000000000004900000 +1CE0:007C008000600000000000000000000000000000000000000000000000000000 +1CE1:000C0012001100100010001000100010001000100010001000100010001000F0 +1CE2:0000000000000000000000000240000007E00000024000000000000000000000 +1CE3:0000000000000000002000100008000800700000000000000000000000000000 +1CE4:000000000000000004000800100010000E000000000000000000000000000000 +1CE5:000000000000000000000000000000000E001000100008000400000000000000 +1CE6:0000000000000000000000000000000000700008000800100020000000000000 +1CE7:0000000000180024002000100008000800700000000000000000000000000000 +1CE8:000000000000000000000000000000000E001000100008000400240018000000 +1CE9:00000000000000000C6012902C682008200820081010082007C0000000000000 +1CEA:00000000000004400AA00AA004400820101010101010082007C0000000000000 +1CEB:00000000000004600A900A7004100810101010101010082007C0000000000000 +1CEC:00000000000004000A200A500450083010181014102408480780000000000000 +1CED:0000000000000000000000000000000000000000000000000100008000400020 +1CEE:0000000000000780080008000800072004000400044003800000000000000000 +1CEF:000000000000078008400900040003C004000500048003000000000000000000 +1CF0:0000018002400200011001800240042004200420024001800000000000000000 +1CF1:0000000000000000020004000840080007E00010021000200040000000000000 +1CF2:00000000000000000810042003C00000000003C0042008100000000000000000 +1CF3:0000000000000000081004200240024002400240042008100000000000000000 +1CF4:0000108008800700000000000000000000000000000000000000000000000000 +1CF5:AAAA000180000001901008218440028181000281844008219010000180005555 +1CF6:AAAA000180000001800000018000111191100EE1800000018000000180005555 +1CF7:0003000400080008000800080008000800080008000800080010001000100000 +1CF8:0000030004800480030000000000000000000000000000000000000000000000 +1CF9:0000183024482448183000000000000000000000000000000000000000000000 +1CFA:00000000000000000C6012901C700FE000000C6012901C700FE0000000000000 +1CFB:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +1CFC:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +1CFD:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE618E6FB663B66FB66F8E7FFE0000 +1CFE:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866FBE638E6FBE6F867FFE0000 +1CFF:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +1D00:000000000000102844447C4444440000 +1D01:0000000000001E28487E4848484E0000 +1D02:0000000000003E4909097E48493E0000 +1D03:000000000000784448FE484444780000 +1D04:0000000000003C4240404040423C0000 +1D05:00000000000078444444444444780000 +1D06:000000000000784444E4444444780000 +1D07:0000000000007C4040784040407C0000 +1D08:0000000000003C4202021C02423C0000 +1D09:0000000000007C101010101018001010 +1D0A:0000000000001F040404040444380000 +1D0B:00000000000022242830302824220000 +1D0C:000000000000202028302060203E0000 +1D0D:000000000000222236362A2A22220000 +1D0E:000000000000444C4C54546464440000 +1D0F:0000000000003C4242424242423C0000 +1D10:0000000000003C4202020202423C0000 +1D11:00000000000000003E414141413E0000 +1D12:00000000000000003E41414141220000 +1D13:00000000000000203E514949453E0200 +1D14:00000000000036490909794949360000 +1D15:00000000000044444438444444380000 +1D16:0000000000003C424242000000000000 +1D17:000000000000000000004242423C0000 +1D18:0000000000007C42427C404040400000 +1D19:0000000000003E42423E122242420000 +1D1A:000000000000424222123E42423E0000 +1D1B:0000000000007F080808080808080000 +1D1C:000000000000424242424242423C0000 +1D1D:00000000000000007F020101017E0000 +1D1E:00000000000000001F420101411E0000 +1D1F:000000000000007F01017E01017E0000 +1D20:00000000000041412222141408080000 +1D21:00000000000042425A5A666642420000 +1D22:0000000000007E0204081020407E0000 +1D23:0000000000007E04081C0202423C0000 +1D24:000000003C4242021C384040423C0000 +1D25:0000000000387CFEFE7C3810926C0000 +1D26:0000000000007E404040404040400000 +1D27:00000000000008081414222241410000 +1D28:0000000000007F222222222222220000 +1D29:0000000000007C42427C404040400000 +1D2A:000000000000494949493E0808080000 +1D2B:0000000000001E121212121222620000 +1D2C:000000102844447C4444000000000000 +1D2D:0000001E28487E48484E000000000000 +1D2E:00000078444478444478000000000000 +1D2F:000000784448FE484478000000000000 +1D30:00000078444444444478000000000000 +1D31:0000007C40407840407C000000000000 +1D32:0000007C04043C04047C000000000000 +1D33:0000003C40404E42463A000000000000 +1D34:0000004242427E424242000000000000 +1D35:0000007C10101010107C000000000000 +1D36:0000001F040404044438000000000000 +1D37:00000022242830282422000000000000 +1D38:0000002020202020203E000000000000 +1D39:0000002236362A222222000000000000 +1D3A:000000446464544C4C44000000000000 +1D3B:000000444C4C54646444000000000000 +1D3C:0000003C42424242423C000000000000 +1D3D:00000044443844444438000000000000 +1D3E:0000007C42427C404040000000000000 +1D3F:0000007C42427C484442000000000000 +1D40:0000007F080808080808000000000000 +1D41:0000004242424242423C000000000000 +1D42:000000444444546C6C44000000000000 +1D43:000000000038043C443C000000000000 +1D44:00000000007844784038000000000000 +1D45:00000000003A4642463A000000000000 +1D46:00000000007C12FC907C000000000000 +1D47:00000040404078444478000000000000 +1D48:0000000404043C44443C000000000000 +1D49:000000000038447C4038000000000000 +1D4A:000000000038047C4438000000000000 +1D4B:00000000003C4038403C000000000000 +1D4C:00000000007804380478000000000000 +1D4D:00000000003A44443C04380000000000 +1D4E:00000000007C10101018001000000000 +1D4F:00000040404850605048000000000000 +1D50:00000000007649494949000000000000 +1D51:00000000005C6242424A040000000000 +1D52:00000000003844444438000000000000 +1D53:00000000003844044438000000000000 +1D54:00000000003844440000000000000000 +1D55:00000000000000444438000000000000 +1D56:00000000007844444478404000000000 +1D57:00000010107C1010100C000000000000 +1D58:00000000004444444C34000000000000 +1D59:00000000007C08040478000000000000 +1D5A:00000000004949494937000000000000 +1D5B:00000000004444282810000000000000 +1D5C:000000387CFEFE7C38926C0000000000 +1D5D:0000003844447C42625C400000000000 +1D5E:00000000002252140810200000000000 +1D5F:00000038404038444438000000000000 +1D60:0000000000264949493E080800000000 +1D61:00000000006112141830488600000000 +1D62:00000000000000001000301010107C00 +1D63:00000000000000000000586440404000 +1D64:000000000000000000004444444C3400 +1D65:00000000000000000000444428281000 +1D66:00000000000000003844447C42625C40 +1D67:0000000000000000000022520C102020 +1D68:00000000000000000000384478403008 +1D69:00000000000000000000264949493E08 +1D6A:00000000000000000000611214183048 +1D6B:0000000000008E89898F8888996E0000 +1D6C:000000202870AC3222222222322C0000 +1D6D:000000050E14344C444444444C340000 +1D6E:0000000C1010107C1010143850100000 +1D6F:0000000000007C4A4A4A7BCE4A4A0000 +1D70:0000000000002C322222336E22220000 +1D71:0000000000002C3222336E22322C2020 +1D72:0000000000002C3220203966A0200000 +1D73:0000000000000E111110395610100000 +1D74:0000000000003C424033CC02423C0000 +1D75:0000000010107C1010325C10100C0000 +1D76:0000000000007E04086A9C10207E0000 +1D77:00000000003C42423C041C2222225C40 +1D78:00004242427E42424242000000000000 +1D79:0000000000007E04081010083C42423C +1D7A:000000000000004810501060105C7CE2114212421442184210422C4200000000 +1D7B:0000000000007C10107C1010107C0000 +1D7C:0000000000007010107C1010100C0000 +1D7D:0000000000002C3222227F22322C2020 +1D7E:0000000000002222227F2222221C0000 +1D7F:0000000000004224FF42424224180000 +1D80:0000004040405C6242424242635D0106 +1D81:0000000202023A4642424242463B0106 +1D82:0000000C1010107C1010101018180830 +1D83:0000000000003A44444444473D05857A +1D84:0000004040404448506050484642020C +1D85:000000180808080808080808083E020C +1D86:000000000000744A4A4A4A4A4B4B0106 +1D87:0000000000005C624242424243430106 +1D88:000000000000586444444444665A424C +1D89:0000000000002C322220202030301060 +1D8A:0000000000003C4240300C02433D0106 +1D8B:0000000C101010101010101E1212620C +1D8C:0000000000004242422424261A1A020C +1D8D:0000000000004444281010284646020C +1D8E:0000000000007E0204081020407E020C +1D8F:0000000000003844043C44444E320203 +1D90:000000000000344C444444444C360203 +1D91:000003040404344C44444444443C0403 +1D92:0000000000003C42427E4040423C0403 +1D93:0000000000003C42403C4040423C0403 +1D94:0000000000003C42023C0202427C4030 +1D95:00000000000070880808FE8A8A720203 +1D96:000000080800180808080808083C0403 +1D97:0000000000003C4202020202427C4030 +1D98:0000000C101010101010101010604030 +1D99:0000000000004444444444444C360203 +1D9A:0000000000007E0408101C02023C2018 +1D9B:00000000005C6242625C000000000000 +1D9C:00000000003840404038000000000000 +1D9D:00000000003840586438400000000000 +1D9E:0000641828043C444438000000000000 +1D9F:00000000007804380478000000000000 +1DA0:0000000C10107C101010000000000000 +1DA1:000000080808083E0848300000000000 +1DA2:00000000003A4642463A023C00000000 +1DA3:0000004444444C340404000000000000 +1DA4:0000001000301038107C000000000000 +1DA5:0000000000301010100C000000000000 +1DA6:0000007C10101010107C000000000000 +1DA7:0000007C10107C10107C000000000000 +1DA8:000000080018080808384C3200000000 +1DA9:00000070101010101010100C00000000 +1DAA:00000070101010101818083000000000 +1DAB:0000002020202020203E000000000000 +1DAC:00000000007649494949010600000000 +1DAD:00000000004949494937010100000000 +1DAE:00000000002C32222222204000000000 +1DAF:00000000005864444444040200000000 +1DB0:0000002232322A262622000000000000 +1DB1:000000000038447C4438000000000000 +1DB2:00000000103854545438100000000000 +1DB3:00000000003840380478403000000000 +1DB4:0000000C101010101010600000000000 +1DB5:00000010107C1010100E020C00000000 +1DB6:000000000022227F261A000000000000 +1DB7:00000042244242422418000000000000 +1DB8:0000002222222222221C000000000000 +1DB9:0000000000CC44444830000000000000 +1DBA:00000010282828444444000000000000 +1DBB:00000000007C0810207C000000000000 +1DBC:0000007C04081020447C040300000000 +1DBD:0000007E02041826497E080800000000 +1DBE:00000000007E0408103C027C00000000 +1DBF:0000001824427E422418000000000000 +1DC0:24100824000000000000000000000000 +1DC1:24081024000000000000000000000000 +1DC2:00000000000000000000000070381C0E +1DC3:00022418000000000000000000000000 +1DC4:00020478000000000000000000000000 +1DC5:0040201E000000000000000000000000 +1DC6:00780402000000000000000000000000 +1DC7:003C4080000000000000000000000000 +1DC8:00885422000000000000000000000000 +1DC9:00225488000000000000000000000000 +1DCA:0000000000000000000000002C302020 +1DCB:008E7000000000000000000000000000 +1DCC:00E21C00000000000000000000000000 +1DCD:0000018006600810000000000000000000000000000000000000000000000000 +1DCE:00300808100000000000000000000000 +1DCF:00000000000000000000001020380810 +1DD0:0000000000000000000000000000113F +1DD1:0064924C000000000000000000000000 +1DD2:00182414040810000000000000000000 +1DD3:00926C00000000000000000000000000 +1DD4:EC127C906E0000000000000000000000 +1DD5:EC1272926C0000000000000000000000 +1DD6:E1117A9A640000000000000000000000 +1DD7:1C2020201C0810000000000000000000 +1DD8:30081C24180000000000000000000000 +1DD9:2810281C241800000000000000000000 +1DDA:1C241C04380000000000000000000000 +1DDB:1C202C24180000000000000000000000 +1DDC:20242834240000000000000000000000 +1DDD:180808081C0000000000000000000000 +1DDE:202020203C0000000000000000000000 +1DDF:446C5444440000000000000000000000 +1DE0:58644444000000000000000000000000 +1DE1:4464544C440000000000000000000000 +1DE2:38243828240000000000000000000000 +1DE3:18240408040200000000000000000000 +1DE4:1C201804380000000000000000000000 +1DE5:18242060202000000000000000000000 +1DE6:3C0418203C0000000000000000000000 +1DE7:001C24241C0000000000000000000000 +1DE8:101C121C000000000000000000000000 +1DE9:18242824380000000000000000000000 +1DEA:38043C24180000000000000000000000 +1DEB:0C103810100000000000000000000000 +1DEC:10381038100000000000000000000000 +1DED:00182424588000000000000000000000 +1DEE:38243820000000000000000000000000 +1DEF:0C101010600000000000000000000000 +1DF0:0024245C800000000000000000000000 +1DF1:00925428000000000000000000000000 +1DF2:14001C241C0000000000000000000000 +1DF3:28001824180000000000000000000000 +1DF4:28002828380000000000000000000000 +1DF5:0010107C000000000000000000000000 +1DF6:0012120C000000000000000000000000 +1DF7:00484830000000000000000000000000 +1DF8:00303000000000000000000000000000 +1DF9:0000000000000000000000000000827C +1DFA:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61866FB663866FB66FB67FFE0000 +1DFB:49499292000000000000000000000000 +1DFC:000000000000000000000000000000000000000000000000000007E018182004 +1DFD:0000000000000000000000324C00324C +1DFE:08102010080000000000000000000000 +1DFF:000000000000000000000000004A2440 +1E00:0000000018242442427E424242182418 +1E01:0000000000003C42023E42463A182418 +1E02:001000007C4242427C424242427C0000 +1E03:0000004840405C6242424242625C0000 +1E04:000000007C4242427C424242427C0010 +1E05:0000004040405C6242424242625C0008 +1E06:000000007C4242427C424242427C003C +1E07:0000004040405C6242424242625C003C +1E08:081020003C42424040404042423C0830 +1E09:0000081020003C4240404040423C0830 +1E0A:00100000784442424242424244780000 +1E0B:0000001202023A4642424242463A0000 +1E0C:00000000784442424242424244780010 +1E0D:0000000202023A4642424242463A0010 +1E0E:0000000078444242424242424478003C +1E0F:0000000202023A4642424242463A003C +1E10:00000000784442424242424244781020 +1E11:0000000202023A4642424242463A0810 +1E12:00000000784442424242424244783048 +1E13:0000000202023A4642424242463A1824 +1E14:10083C007E4040407C404040407E0000 +1E15:201008003C003C42427E4040423C0000 +1E16:08103C007E4040407C404040407E0000 +1E17:081020003C003C42427E4040423C0000 +1E18:000000007E4040407C404040407E1824 +1E19:0000000000003C42427E4040423C1824 +1E1A:000000007E4040407C404040407E324C +1E1B:0000000000003C42427E4040423C324C +1E1C:00221C007E4040407C404040407E0418 +1E1D:0000221C00003C42427E4040423C0830 +1E1E:001000007E4040407C40404040400000 +1E1F:0800000C1010107C1010101010100000 +1E20:00003C003C424240404E4242463A0000 +1E21:0000000078023A44444438203C42423C +1E22:00001000444444447C44444444440000 +1E23:0000004840405C624242424242420000 +1E24:00000000444444447C44444444440010 +1E25:0000004040405C624242424242420008 +1E26:00240000424242427E42424242420000 +1E27:2400004040405C624242424242420000 +1E28:00000000424242427E42424262621060 +1E29:0000004040405C624242424262621060 +1E2A:0000000082828282FE82828282822838 +1E2B:0000004040404E51614141414141141C +1E2C:000000003E08080808080808083E324C +1E2D:000000080800180808080808083E324C +1E2E:04082A003E08080808080808083E0000 +1E2F:000204082200180808080808083E0000 +1E30:00040810424448506060504844420000 +1E31:00020448404044485060504844420000 +1E32:00000000424448506060504844420010 +1E33:00000040404044485060504844420010 +1E34:0000000042444850606050484442003C +1E35:0000004040404448506050484442003C +1E36:000000004040404040404040407E0010 +1E37:000000180808080808080808083E0008 +1E38:00003C004040404040404040407E0010 +1E39:003C00180808080808080808083E0008 +1E3A:000000004040404040404040407E003C +1E3B:000000180808080808080808083E001C +1E3C:000000004040404040404040407E1824 +1E3D:000000180808080808080808083E1824 +1E3E:00040810424266665A5A424242420000 +1E3F:00000408100076494949494949490000 +1E40:00001000424266665A5A424242420000 +1E41:00000008000076494949494949490000 +1E42:00000000424266665A5A424242420008 +1E43:00000000000076494949494949490008 +1E44:0000080042626252524A4A4646420000 +1E45:0000000800005C624242424242420000 +1E46:0000000042626252524A4A4646420008 +1E47:0000000000005C624242424242420008 +1E48:0000000042626252524A4A464642003C +1E49:0000000000005C62424242424242003C +1E4A:0000000042626252524A4A4646421824 +1E4B:0000000000005C624242424242421824 +1E4C:0408324C3C42424242424242423C0000 +1E4D:020408324C003C4242424242423C0000 +1E4E:2400324C3C42424242424242423C0000 +1E4F:002400324C003C4242424242423C0000 +1E50:10083C003C42424242424242423C0000 +1E51:201008003C003C4242424242423C0000 +1E52:08103C003C42424242424242423C0000 +1E53:081020003C003C4242424242423C0000 +1E54:000408107C4242427C40404040400000 +1E55:0000040810005C6242424242625C4040 +1E56:001000007C4242427C40404040400000 +1E57:0000000800005C6242424242625C4040 +1E58:001000007C4242427C48444442420000 +1E59:0000001000005C624240404040400000 +1E5A:000000007C4242427C48444442420008 +1E5B:0000000000005C624240404040400800 +1E5C:00003C007C4242427C48444442420008 +1E5D:000000003C005C624240404040400800 +1E5E:000000007C4242427C4844444242003C +1E5F:0000000000005C62424040404040003C +1E60:001000003C424240300C0242423C0000 +1E61:0000001000003C4240300C02423C0000 +1E62:000000003C424240300C0242423C0008 +1E63:0000000000003C4240300C02423C0008 +1E64:240810003C424240300C0242423C0000 +1E65:0020081020003C4240300C02423C0000 +1E66:082214083C424240300C0242423C0000 +1E67:0008002214083C4240300C02423C0000 +1E68:000800003C424240300C0242423C0008 +1E69:0000000800003C4240300C02423C0008 +1E6A:000800007F0808080808080808080000 +1E6B:001000001010107C10101010100C0000 +1E6C:000000007F0808080808080808080008 +1E6D:000000001010107C10101010100C0010 +1E6E:000000007F080808080808080808003E +1E6F:000000001010107C10101010100C003C +1E70:000000007F0808080808080800081422 +1E71:000000001010107C10101010120C1422 +1E72:000000004242424242424242423C0024 +1E73:000000000000424242424242463A0028 +1E74:000000004242424242424242423C324C +1E75:000000000000424242424242463A324C +1E76:000000004242424242424242423C1422 +1E77:000000000000424242424242463A1422 +1E78:0408324C0042424242424242423C0000 +1E79:020408324C00424242424242463A0000 +1E7A:24003C004242424242424242423C0000 +1E7B:000024003C00424242424242463A0000 +1E7C:0000324C004141222222141408080000 +1E7D:0000324C000042424224242418180000 +1E7E:00000000414141222222141408080008 +1E7F:00000000000044444428282810100010 +1E80:00201008424242425A5A666642420000 +1E81:00001008040041494949494949360000 +1E82:00040810424242425A5A666642420000 +1E83:00000408100041494949494949360000 +1E84:00240000424242425A5A666642420000 +1E85:00000022000041494949494949360000 +1E86:001000004444444454546C6C44440000 +1E87:00000008000041494949494949360000 +1E88:000000004444444454546C6C44440010 +1E89:00000000000041494949494949360008 +1E8A:00100000444428281010282844440000 +1E8B:00000010000044442810102844440000 +1E8C:00240000424224241818242442420000 +1E8D:00000024000042422418182442420000 +1E8E:00080000414122221408080808080000 +1E8F:0000000800004242424242261A02023C +1E90:182400007E02020408102040407E0000 +1E91:0000182400007E0204081020407E0000 +1E92:000000007E02020408102040407E0008 +1E93:0000000000007E0204081020407E0008 +1E94:000000007E02020408102040407E003C +1E95:0000000000007E0204081020407E003C +1E96:0000004040405C62424242424242003C +1E97:000044001010107C10101010100C0000 +1E98:00081408000041494949494949360000 +1E99:0008140800004242424242261A02023C +1E9A:0002010102003C42023E4242463A0000 +1E9B:0010000C101010301010101010100000 +1E9C:0000000C101010341830501010100000 +1E9D:0000000C107C10301010101010100000 +1E9E:0000003E424444484C424242524C0000 +1E9F:000000001C20202018244242423C0000 +1EA0:0000000010282844447C444444440010 +1EA1:0000000000003C42023E4242463A0010 +1EA2:4020204018242442427E424242420000 +1EA3:0008040408003C42023E4242463A0000 +1EA4:0214284410282844447C444444440000 +1EA5:0002142844003C42023E4242463A0000 +1EA6:4028142208141422223E222222220000 +1EA7:0040281422003C42023E4242463A0000 +1EA8:0402142854282844447C444444440000 +1EA9:02010A1422003C42023E4242463A0000 +1EAA:192608142208141422223E2222220000 +1EAB:1926081422003C42023E4242463A0000 +1EAC:0008142208141422223E222222220008 +1EAD:0000182400003C42023E4242463A0008 +1EAE:0810443810282844447C444444440000 +1EAF:0408104438003C42023E4242463A0000 +1EB0:2010443810282844447C444444440000 +1EB1:201008221C003C42023E4242463A0000 +1EB2:1008B27C10282844447C444444440000 +1EB3:0808104438003C42023E4242463A0000 +1EB4:324C827C10282844447C444444440000 +1EB5:324C00423C003C42023E4242463A0000 +1EB6:0000443810282844447C444444440010 +1EB7:0000002418003C42023E4242463A0010 +1EB8:000000007E4040407C404040407E0010 +1EB9:0000000000003C42427E4040423C0010 +1EBA:100808107E4040407C404040407E0000 +1EBB:1008081000003C42427E4040423C0000 +1EBC:00324C007E4040407C404040407E0000 +1EBD:000000324C003C42427E4040423C0000 +1EBE:021428447E4040407C404040407E0000 +1EBF:0002142844003C42427E4040423C0000 +1EC0:402814227E4040407C404040407E0000 +1EC1:0040281422003C42427E4040423C0000 +1EC2:04122A447E4040407C404040407E0000 +1EC3:0402122C44003C42427E4040423C0000 +1EC4:324C1028447E40407C404040407E0000 +1EC5:324C102844003C42427E4040423C0000 +1EC6:001824007E4040407C404040407E0008 +1EC7:0000182400003C42427E4040423C0008 +1EC8:080404083E08080808080808083E0000 +1EC9:001008081000180808080808083E0000 +1ECA:000000003E08080808080808083E0008 +1ECB:000000080800180808080808083E0008 +1ECC:000000003C42424242424242423C0008 +1ECD:0000000000003C4242424242423C0008 +1ECE:100808103C42424242424242423C0000 +1ECF:0010080810003C4242424242423C0000 +1ED0:021428443C42424242424242423C0000 +1ED1:0002142844003C4242424242423C0000 +1ED2:402814223C42424242424242423C0000 +1ED3:0040281422003C4242424242423C0000 +1ED4:04122A443C42424242424242423C0000 +1ED5:0402122C44003C4242424242423C0000 +1ED6:324C1028443C424242424242423C0000 +1ED7:324C102844003C4242424242423C0000 +1ED8:001824003C42424242424242423C0008 +1ED9:0000182400003C4242424242423C0008 +1EDA:08102201394644444444444444380000 +1EDB:00000810220139464444444444380000 +1EDC:20100A01394644444444444444380000 +1EDD:000020100A0139464444444444380000 +1EDE:10080A11394644444444444444380000 +1EDF:00100808120139464444444444380000 +1EE0:00324C02394546444444444444380000 +1EE1:00324C00020139464444444444380000 +1EE2:00000201394644444444444444380010 +1EE3:00000000020139464444444444380010 +1EE4:000000004242424242424242423C0008 +1EE5:000000000000424242424242463A0008 +1EE6:100808104242424242424242423C0000 +1EE7:001008081000424242424242463A0000 +1EE8:04081201454644444444444444380000 +1EE9:0000040812014546444444444C340000 +1EEA:40201201454644444444444444380000 +1EEB:0000402012014546444444444C340000 +1EEC:10080A11454644444444444444380000 +1EED:0010080812014546444444444C340000 +1EEE:324C0201454644444444444444380000 +1EEF:00324C0002014546444444444C340000 +1EF0:00000201454644444444444444380010 +1EF1:0000000002014546444444444C340010 +1EF2:20100800414122221408080808080000 +1EF3:0020100800004242424242261A02023C +1EF4:00000000414122221408080808080008 +1EF5:0000000000004242424242261A023C08 +1EF6:08040408414122221408080808080000 +1EF7:0010080810004242424242261A02023C +1EF8:00324C00414122221408080808080000 +1EF9:0000324C00004242424242261A02023C +1EFA:000000F0505050505050505050FE0000 +1EFB:0000006C2424247E2424242424FF0000 +1EFC:000000000408101020244242423C0000 +1EFD:00000000000008102020484444380000 +1EFE:00000000424222141408080808384830 +1EFF:00000000000042422214140808384830 +1F00:000030102000324A444444444A320000 +1F01:000030201000324A444444444A320000 +1F02:000068284400324A444444444A320000 +1F03:000068482400324A444444444A320000 +1F04:000064284800324A444444444A320000 +1F05:000064482800324A444444444A320000 +1F06:64980030102000324A4444444A320000 +1F07:64980030201000324A4444444A320000 +1F08:C040800018242442427E424242420000 +1F09:C080400018242442427E424242420000 +1F0A:D050880018242442427E424242420000 +1F0B:D090480018242442427E424242420000 +1F0C:C850900018242442427E424242420000 +1F0D:C890500018242442427E424242420000 +1F0E:6498602040182424427E424242420000 +1F0F:6498604020182424427E424242420000 +1F10:0000180810003C42403C4040423C0000 +1F11:0000181008003C42403C4040423C0000 +1F12:0000341422003C42403C4040423C0000 +1F13:0000342412003C42403C4040423C0000 +1F14:0000321424003C42403C4040423C0000 +1F15:0000322414003C42403C4040423C0000 +1F16:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000 +1F17:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000 +1F18:C04080007E4040407C404040407E0000 +1F19:C08040007E4040407C404040407E0000 +1F1A:D05088007E4040407C404040407E0000 +1F1B:D09048007E4040407C404040407E0000 +1F1C:C85090007E4040407C404040407E0000 +1F1D:C89050007E4040407C404040407E0000 +1F1E:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000 +1F1F:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000 +1F20:0000180810005C624242424242420202 +1F21:0000181008005C624242424242420202 +1F22:0000341422005C624242424242420202 +1F23:0000342412005C624242424242420202 +1F24:0000321424005C624242424242420202 +1F25:0000322414005C624242424242420202 +1F26:324C00180810005C6242424242420202 +1F27:324C00181008005C6242424242420202 +1F28:C0408000424242427E42424242420000 +1F29:C0804000424242427E42424242420000 +1F2A:D0508800424242427E42424242420000 +1F2B:D0904800424242427E42424242420000 +1F2C:C8509000424242427E42424242420000 +1F2D:C8905000424242427E42424242420000 +1F2E:64986020404242427E42424242420000 +1F2F:64986040204242427E42424242420000 +1F30:000018081000301010101010100C0000 +1F31:000018100800301010101010100C0000 +1F32:000068284400301010101010100C0000 +1F33:000068482400301010101010100C0000 +1F34:000064284800301010101010100C0000 +1F35:000064482800301010101010100C0000 +1F36:324C00180810003010101010100C0000 +1F37:324C00181008003010101010100C0000 +1F38:C04080003E08080808080808083E0000 +1F39:C08060003E08080808080808083E0000 +1F3A:D05088003E08080808080808083E0000 +1F3B:D09048003E08080808080808083E0000 +1F3C:C85090003E08080808080808083E0000 +1F3D:C89050003E08080808080808083E0000 +1F3E:64986020403E080808080808083E0000 +1F3F:64986040203E080808080808083E0000 +1F40:0000180810003C4242424242423C0000 +1F41:0000181008003C4242424242423C0000 +1F42:0000341422003C4242424242423C0000 +1F43:0000342412003C4242424242423C0000 +1F44:0000321424003C4242424242423C0000 +1F45:0000322414003C4242424242423C0000 +1F46:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000 +1F47:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000 +1F48:C04080003C42424242424242423C0000 +1F49:C08040003C42424242424242423C0000 +1F4A:D05088003C42424242424242423C0000 +1F4B:D09048003C42424242424242423C0000 +1F4C:C85090003C42424242424242423C0000 +1F4D:C89050003C42424242424242423C0000 +1F4E:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE6D866DBE618E7DBE7D867FFE0000 +1F4F:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000 +1F50:000018081000424242424242423C0000 +1F51:000018100800424242424242423C0000 +1F52:000034142200424242424242423C0000 +1F53:000034241200424242424242423C0000 +1F54:000032142400424242424242423C0000 +1F55:000032241400424242424242423C0000 +1F56:324C00180810424242424242423C0000 +1F57:324C00181008424242424242423C0000 +1F58:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000 +1F59:C0804000414122221408080808080000 +1F5A:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61866FB661867DB661B67FFE0000 +1F5B:D0904800414122221408080808080000 +1F5C:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000 +1F5D:C8905000414122221408080808080000 +1F5E:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61866FBE618E7DBE61867FFE0000 +1F5F:64986040204122221408080808080000 +1F60:00000C04080022414149494949360000 +1F61:00000C08040022414149494949360000 +1F62:00003414220022414149494949360000 +1F63:00003424120022414149494949360000 +1F64:00003214240022414149494949360000 +1F65:00003224140022414149494949360000 +1F66:324C0018081000224149494949360000 +1F67:324C0018100800224149494949360000 +1F68:C04080003E4141414141221414770000 +1F69:C08040003E4141414141221414770000 +1F6A:D05088003E4141414141221414770000 +1F6B:D09048003E4141414141221414770000 +1F6C:C85090003E4141414141221414770000 +1F6D:C89050003E4141414141221414770000 +1F6E:324C1808101C22414141221414770000 +1F6F:324C1810081C23414141221414770000 +1F70:000020201000324A444444444A320000 +1F71:000010202000324A444444444A320000 +1F72:0000101008003C42403C4040423C0000 +1F73:0000081010003C42403C4040423C0000 +1F74:0000101008005C624242424242420202 +1F75:0000081010005C624242424242420202 +1F76:000010100800301010101010100C0000 +1F77:000008101000301010101010100C0000 +1F78:0000101008003C4242424242423C0000 +1F79:0000081010003C4242424242423C0000 +1F7A:000010100800424242424242423C0000 +1F7B:000008101000424242424242423C0000 +1F7C:00001010080022414149494949360000 +1F7D:00000408080022414149494949360000 +1F7E:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61867DBE7B8E77BE77867FFE0000 +1F7F:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +1F80:000030102000324A444444444A322030 +1F81:000030201000324A444444444A322030 +1F82:000068284400324A444444444A322030 +1F83:000068482400324A444444444A322030 +1F84:000064284800324A444444444A322030 +1F85:000064482800324A444444444A322030 +1F86:324C0030102000324A4444444A322030 +1F87:324C0030201000324A4444444A322030 +1F88:C040800018242442427E42424242100C +1F89:C080400018242442427E42424242100C +1F8A:D050880018242442427E42424242100C +1F8B:D090480018242442427E42424242100C +1F8C:C850900018242442427E42424242100C +1F8D:C890500018242442427E42424242100C +1F8E:6498602040182424427E42424242100C +1F8F:6498604020182424427E42424242100C +1F90:0000180810005C624242424242422232 +1F91:0000181008005C624242424242422232 +1F92:0000341422005C624242424242422232 +1F93:0000342412005C624242424242422232 +1F94:0000321424005C624242424242422232 +1F95:0000322414005C624242424242422232 +1F96:324C00180810005C6242424242422232 +1F97:324C00181008005C6242424242422232 +1F98:C0408000424242427E42424242422018 +1F99:C0804000424242427E42424242422018 +1F9A:D0508800424242427E42424242422018 +1F9B:D0904800424242427E42424242422018 +1F9C:C8509000424242427E42424242422018 +1F9D:C8905000424242427E42424242422018 +1F9E:64986020404242427E42424242422018 +1F9F:64986040204242427E42424242422018 +1FA0:0000180810002241414949494936080C +1FA1:0000181008002241414949494936080C +1FA2:0000341422002241414949494936080C +1FA3:0000342412002241414949494936080C +1FA4:0000321424002241414949494936080C +1FA5:0000322414002241414949494936080C +1FA6:324C001808100022414949494936080C +1FA7:324C001810080022414949494936080C +1FA8:C04080003E4141414141221414770806 +1FA9:C08040003E4141414141221414770806 +1FAA:D05088003E4141414141221414770806 +1FAB:D09048003E4141414141221414770806 +1FAC:C85090003E4141414141221414770806 +1FAD:C89050003E4141414141221414770806 +1FAE:64986020401C22414141221414770806 +1FAF:64986040201C22414141221414770806 +1FB0:000044443800324A444444444A320000 +1FB1:000000007C00324A444444444A320000 +1FB2:000020201000324A444444444A322030 +1FB3:000000000000324A444444444A322030 +1FB4:000010202000324A444444444A322030 +1FB5:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE63866DBE63866DF663867FFE0000 +1FB6:000000324C00324A444444444A320000 +1FB7:000000324C00324A444444444A322030 +1FB8:42423C0018242442427E424242420000 +1FB9:003C000018242442427E424242420000 +1FBA:8080400018242442427E424242420000 +1FBB:4080800018242442427E424242420000 +1FBC:0000000018242442427E42424242100C +1FBD:00000000180810000000000000000000 +1FBE:00000000000000000000202020180000 +1FBF:18081000000000000000000000000000 +1FC0:324C0000000000000000000000000000 +1FC1:324C0066000000000000000000000000 +1FC2:0000101008005C624242424242422232 +1FC3:0000000000005C624242424242422232 +1FC4:0000081010005C624242424242422232 +1FC5:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE71866FBE6F866FF671867FFE0000 +1FC6:000000324C005C624242424242420202 +1FC7:000000324C005C624242424242422232 +1FC8:808040007E4040407C404040407E0000 +1FC9:408080007E4040407C404040407E0000 +1FCA:80804000424242427E42424242420000 +1FCB:40808000424242427E42424242420000 +1FCC:00000000424242427E4242424242100C +1FCD:68284400000000000000000000000000 +1FCE:64284800000000000000000000000000 +1FCF:324C0018081000000000000000000000 +1FD0:000044443800301010101010100C0000 +1FD1:000000003C00301010101010100C0000 +1FD2:101008006600301010101010100C0000 +1FD3:081010006600301010101010100C0000 +1FD4:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE63B66DB66D866DF663F67FFE0000 +1FD5:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE63866DBE6D866DF663867FFE0000 +1FD6:000000324C00301010101010100C0000 +1FD7:00324C006600301010101010100C0000 +1FD8:22221C003E08080808080808083E0000 +1FD9:003E00003E08080808080808083E0000 +1FDA:808040003E08080808080808083E0000 +1FDB:408080003E08080808080808083E0000 +1FDC:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +1FDD:68482400000000000000000000000000 +1FDE:64482800000000000000000000000000 +1FDF:324C0018100800000000000000000000 +1FE0:000042423C00424242424242423C0000 +1FE1:0000003C0000424242424242423C0000 +1FE2:101008006600424242424242423C0000 +1FE3:081010006600424242424242423C0000 +1FE4:0000180810003C4242424242625C4040 +1FE5:0000181008003C4242424242625C4040 +1FE6:000000324C00424242424242423C0000 +1FE7:00324C006600424242424242423C0000 +1FE8:22221C00414122221408080808080000 +1FE9:00003E00414122221408080808080000 +1FEA:80804000414122221408080808080000 +1FEB:40808000414122221408080808080000 +1FEC:C08040007C4242427C40404040400000 +1FED:10100800660000000000000000000000 +1FEE:08101000660000000000000000000000 +1FEF:10100800000000000000000000000000 +1FF0:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000 +1FF1:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000 +1FF2:0000101008002241414949494936080C +1FF3:0000000000002241414949494936080C +1FF4:0000040808002241414949494936080C +1FF5:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61866FBE63866FF66F867FFE0000 +1FF6:000000324C0022414149494949360000 +1FF7:000000324C002241414949494936080C +1FF8:808040003C42424242424242423C0000 +1FF9:408080003C42424242424242423C0000 +1FFA:808040003E4141414141221414770000 +1FFB:408080003E4141414141221414770000 +1FFC:000000003E4141414141221414770806 +1FFD:08101000000000000000000000000000 +1FFE:18100800000000000000000000000000 +1FFF:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +2000:00000000000000000000000000000000 +2001:00000000000000000000000000000000 +2002:00000000000000000000000000000000 +2003:00000000000000000000000000000000 +2004:00000000000000000000000000000000 +2005:00000000000000000000000000000000 +2006:00000000000000000000000000000000 +2007:00000000000000000000000000000000 +2008:00000000000000000000000000000000 +2009:00000000000000000000000000000000 +200A:00000000000000000000000000000000 +200B:AAAA00019E44024584540855906C1E4580000E3990240C3982201C2180005555 +200C:AAAA00019E44024584540855906C1E45800012099A0816499248123180005555 +200D:AAAA00019E44024584540855906C1E4580000041804002418240018180005555 +200E:AAAA000180000001C72244B7C72A4523F4A20001800000018000000180005555 +200F:AAAA000180000001F2224A37F22A5223CBA20001800000018000000180005555 +2010:0000000000000000003C000000000000 +2011:0000000000000000003C000000000000 +2012:0000000000000000007E000000000000 +2013:0000000000000000007E000000000000 +2014:000000000000000000FF000000000000 +2015:000000000000000000FF000000000000 +2016:00000014141414141414141414141400 +2017:00000000000000000000000000FF00FF +2018:00000810101800000000000000000000 +2019:00001808081000000000000000000000 +201A:00000000000000000000000018080810 +201B:00001810100800000000000000000000 +201C:00002244446600000000000000000000 +201D:00006622224400000000000000000000 +201E:00000000000000000000000066222244 +201F:00006644442200000000000000000000 +2020:0000081C082A7F2A081C080808080000 +2021:00081C082A7F2A08082A7F2A081C0800 +2022:00000000000000387C7C7C3800000000 +2023:0000000000002030383C383020000000 +2024:00000000000000000000000018180000 +2025:00000000000000000000000036360000 +2026:00000000000000000000000049490000 +2027:00000000000000000018180000000000 +2028:AAAA00018000020182000201820003C180003BDDC21233DD8A1073D180005555 +2029:AAAA000180000381824003818200020180003BDDC21233DD8A1073D180005555 +202A:AAAA000180000001C39E4251C39E4291FA5E0001800000018000000180005555 +202B:AAAA000180000001F21E4A11F21E5211CBDE0001800000018000000180005555 +202C:AAAA000180000001F39E4A51F25E4251C3900001800000018000000180005555 +202D:AAAA000180000001C38C4253C3924293FA4C0001800000018000000180005555 +202E:AAAA000180000001F20C4A13F2125213CBCC0001800000018000000180005555 +202F:00000000000000000000000000000000 +2030:0000000042A4A44810102A55558A0000 +2031:0000000040A0A04C30C02A55552A0000 +2032:000000000C1810200000000000000000 +2033:00000000336644880000000000000000 +2034:000000003F7E54A80000000000000000 +2035:00000000301808040000000000000000 +2036:00000000CC6622110000000000000000 +2037:00000000FC7E2A150000000000000000 +2038:00000000000000000000000000102844 +2039:00000000000404080810080804040000 +203A:00000000202010100808101020200000 +203B:00000000004922144914224900000000 +203C:00000000242424242424240024240000 +203D:000000003C4A4A0A0C08080008080000 +203E:7E000000000000000000000000000000 +203F:0000000000000000000000000000423C +2040:3C420000000000000000000000000000 +2041:00000000000000000000020408102844 +2042:000000000000081C0800227722000000 +2043:00000000000000003C3C000000000000 +2044:00000000020204080810102040400000 +2045:0000000E080808080E08080808080E00 +2046:00000070101010107010101010107000 +2047:000000EE111122CC8888880000880000 +2048:000000720A0A12624242420000420000 +2049:0000005C424244585050500000500000 +204A:0000000000007E020202020404040404 +204B:00000000FC5E5E5E5C50505050505000 +204C:000000001E3A3A3A1E00000000000000 +204D:00000000785C5C5C7800000000000000 +204E:0000000000000008492A1C2A49080000 +204F:00000000000018180000001810100800 +2050:0000003C424200000042423C00000000 +2051:0008492A1C2A49080008492A1C2A4908 +2052:00000000626204080810102046460000 +2053:000000000000000000718E0000000000 +2054:00000000000000000000000000003C42 +2055:00000000925438FE3854920000000000 +2056:00000000000006060060600006060000 +2057:0000000000000000333366664444888800000000000000000000000000000000 +2058:00000000000018180066660018180000 +2059:00000000000066660018180066660000 +205A:00000000181800000000000018180000 +205B:00000018180000006666000000181800 +205C:00000000000054107C10540000000000 +205D:00000000181800001818000018180000 +205E:00000000100000100000100000100000 +205F:00000000000000000000000000000000 +2060:AAAA00018000000180000001A2082209AA083689A27000018000000180005555 +2061:AAAA00018C001001908810899104110591047D05910411059088608980005555 +2062:AAAA000180000001800000018000042182400181824004218000000180005555 +2063:AAAA000180000001800000018000000180000001800018018800080190005555 +2064:AAAA00018000000180000101810001018FE00101810001018100000180005555 +2065:00007FFE61CE7DB661B66FB661CE7FFE7FFE73866FBE63866DF673867FFE0000 +2066:AAAA000180000001A39C2249A3882289BA5C0001800000018000000180005555 +2067:AAAA000180000001B91C2509B9082909A5DC0001800000018000000180005555 +2068:AAAA000180000001B9DC2209B9882049A39C0001800000018000000180005555 +2069:AAAA000180000001F39C4A49F2484249C39C0001800000018000000180005555 +206A:AAAA0001800007C181000101810007C180001E79A0801C7182083CF180005555 +206B:AAAA000180000381844007C18440044180001E79A0801C7182083CF180005555 +206C:AAAA0001800003E180800081808003E1800039F6C5087DE7C501450F80005555 +206D:AAAA0001800001C1822003E182200221800039F6C5087DE7C501450F80005555 +206E:AAAA000180002271B2882AF9A688228980003C79A2802271A2083CF180005555 +206F:AAAA000180002271B2882A89A688227180003C79A2802271A2083CF180005555 +2070:00000018244242422418000000000000 +2071:0000001000301010107C000000000000 +2072:00007FFE61CE7DB661B66FB661CE7FFE7FFE61867DF67B8677BE77867FFE0000 +2073:00007FFE61CE7DB661B66FB661CE7FFE7FFE618E7DF67BC677F6778E7FFE0000 +2074:0000000C1424447E0404000000000000 +2075:0000007C404078040478000000000000 +2076:00000018204078444438000000000000 +2077:0000007C040808101010000000000000 +2078:00000038444438444438000000000000 +2079:0000003844443C040830000000000000 +207A:0000000010107C101000000000000000 +207B:0000000000007C000000000000000000 +207C:00000000007C00007C00000000000000 +207D:00000408101010101008040000000000 +207E:00002010080808080810200000000000 +207F:00000000005864444444000000000000 +2080:00000000000000001824424242241800 +2081:00000000000000001030501010107C00 +2082:00000000000000003844041820407C00 +2083:00000000000000003844043804443800 +2084:00000000000000000C1424447E040400 +2085:00000000000000007C40407804047800 +2086:00000000000000001820407844443800 +2087:00000000000000007C04080810101000 +2088:00000000000000003844443844443800 +2089:00000000000000003844443C04083000 +208A:0000000000000000000010107C101000 +208B:0000000000000000000000007C000000 +208C:00000000000000000000007C00007C00 +208D:00000000000000040810101010100804 +208E:00000000000000201008080808081020 +208F:00007FFE61CE7DB661B66FB661CE7FFE7FFE73866DBE738E6DBE73BE7FFE0000 +2090:0000000000000000000038043C443C00 +2091:0000000000000000000038447C403C00 +2092:00000000000000000000384444443800 +2093:00000000000000000000442810284400 +2094:0000000000000000000078047C443800 +2095:00000000000000004040586444444400 +2096:00000000000000002020242830282400 +2097:00000000000000003010101010107C00 +2098:00000000000000000000764949494900 +2099:00000000000000000000586444444400 +209A:00000000000000000000586464584040 +209B:000000000000000000003C4038047800 +209C:000000000000000010107C1010100C00 +209D:00007FFE61CE7DB661B66FB661CE7FFE7FFE738E6DB671B67DB6738E7FFE0000 +209E:00007FFE61CE7DB661B66FB661CE7FFE7FFE73866DBE718E7DBE73867FFE0000 +209F:00007FFE61CE7DB661B66FB661CE7FFE7FFE73866DBE718E7DBE73BE7FFE0000 +20A0:000000003C40405E50503C10101E0000 +20A1:000000000A3E4A54546868725C100000 +20A2:000000001C22424056585050321C0000 +20A3:000000003F2020203E2020FC20200000 +20A4:000000000E10107E107E10103E610000 +20A5:000000000101764D4D49495969690000 +20A6:000000002222327F2A7F262622220000 +20A7:0000000068585F5C6C4A4949494E0000 +20A8:0000000070484B4C74545249494E0000 +20A9:0000002222227F2A7F36362222000000 +20AA:000000000000F28AAAAAAAAAA2BC0000 +20AB:000000020F023A4642424242463A007E +20AC:000000000C12207C207C2020120C0000 +20AD:000000004244485060FE504844420000 +20AE:000000007F08080E380E380808080000 +20AF:0000000070484848484E4D4D4E740404 +20B0:00000000384444442818546462420408 +20B1:00007C42FF42FF427C40404040400000 +20B2:000010103C52525050565252563A1010 +20B3:00000000182424FF42FF424242420000 +20B4:000000003C420202FF30FF40423C0000 +20B5:000010103C52525050505052523C1010 +20B6:000000002828287E2828282829260000 +20B7:000000003C424220180452AAAAFCA8A8 +20B8:000000000000FE00FE10101010100000 +20B9:0000000000000FF0018000400FF0004000800F00040002000100008000400000 +20BA:0000002020283060A83062A224380000 +20BB:0000000040A0FC224254E84044380000 +20BC:00000000000000101038545454540000 +20BD:000000003C2222227C207C2020200000 +20BE:0000287CAAAAAA808080804020FE0000 +20BF:00002828FC4242427C42424242FC2828 +20C0:00007FFE61CE7DB661B66FB661CE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000 +20C1:00007FFE61CE7DB661B66FB661CE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000 +20C2:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FF66F866FBE71867FFE0000 +20C3:00007FFE61CE7DB661B66FB661CE7FFE7FFE718E6FF66FC66FF6718E7FFE0000 +20C4:00007FFE61CE7DB661B66FB661CE7FFE7FFE71B66FB66F866FF671F67FFE0000 +20C5:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FBE6F866FF671867FFE0000 +20C6:00007FFE61CE7DB661B66FB661CE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000 +20C7:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000 +20C8:00007FFE61CE7DB661B66FB661CE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +20C9:00007FFE61CE7DB661B66FB661CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +20CA:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FB66F866FB671B67FFE0000 +20CB:00007FFE61CE7DB661B66FB661CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +20CC:00007FFE61CE7DB661B66FB661CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +20CD:00007FFE61CE7DB661B66FB661CE7FFE7FFE718E6FB66FB66FB6718E7FFE0000 +20CE:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000 +20CF:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +20D0:0010207E000000000000000000000000 +20D1:0008047E000000000000000000000000 +20D2:00000000101010101010101010100000 +20D3:00000000001010101010101000000000 +20D4:004C5260780000000000000000000000 +20D5:00324A061E0000000000000000000000 +20D6:10207E20100000000000000000000000 +20D7:08047E04080000000000000000000000 +20D8:00000000000000182424180000000000 +20D9:00000000000000383424180000000000 +20DA:000000000000001C2C24180000000000 +20DB:00002A2A000000000000000000000000 +20DC:00005555000000000000000000000000 +20DD:000003800C60301820084004400480028002800240044004200830180C600380 +20DE:00007FFE4002400240024002400240024002400240024002400240027FFE0000 +20DF:0000010002800440082010102008400480024004200810100820044002800100 +20E0:000003800C603018300858044C0486028302818240C44064203830180C600380 +20E1:2442FF42240000000000000000000000 +20E2:0000000000003FFC4002400240024002400240024002400240023FFC7FFE0000 +20E3:00003FFC60065FFA500A500A500A500A500A500A500A500A5FFA60063FFC0000 +20E4:008001C00140036002200410041008080808180C10041004200220023FFE0000 +20E5:00002020201010101010080808080000 +20E6:00002828282828282828282828280000 +20E7:00001FFF00010001000100010001000100010001000100010001000100010000 +20E8:00000000000000000000000000000054 +20E9:00FF8100000000000000000000000000 +20EA:000000000000000000000000040008001FFC0800040000000000000000000000 +20EB:00000A0A0A1414141414282828280000 +20EC:000000000000000000000000007E0408 +20ED:000000000000000000000000007E2010 +20EE:000000000000000000000010207E2010 +20EF:000000000000000000000008047E0408 +20F0:24187E18240000000000000000000000 +20F1:00007FFE61CE7DB661B66FB661CE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000 +20F2:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FF663866FBE6F867FFE0000 +20F3:00007FFE61CE7DB661B66FB661CE7FFE7FFE618E6FF663C66FF66F8E7FFE0000 +20F4:00007FFE61CE7DB661B66FB661CE7FFE7FFE61B66FB663866FF66FF67FFE0000 +20F5:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FBE63866FF66F867FFE0000 +20F6:00007FFE61CE7DB661B66FB661CE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +20F7:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +20F8:00007FFE61CE7DB661B66FB661CE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +20F9:00007FFE61CE7DB661B66FB661CE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +20FA:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FB663866FB66FB67FFE0000 +20FB:00007FFE61CE7DB661B66FB661CE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +20FC:00007FFE61CE7DB661B66FB661CE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +20FD:00007FFE61CE7DB661B66FB661CE7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +20FE:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FBE638E6FBE6F867FFE0000 +20FF:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +2100:00000000003051523408132444030000 +2101:0000000000305152340B142241060000 +2102:000000001E31505050505050311E0000 +2103:40A0A0403C42424040404042423C0000 +2104:0000000010103C505050503C101E0000 +2105:00000000003041423408162949060000 +2106:00000000003041423408102949060000 +2107:000000003E42404038404042423C0000 +2108:000000007C4202121E120202423C0000 +2109:40A0A0407E4040407C40404040400000 +210A:0000000000003A4642423E023F423C00 +210B:00000000127596141C34549494630000 +210C:000018B66068743666666666E6063408 +210D:00000000715151515F51515151710000 +210E:00000000000000400080008000F0018801080108021002100210042000000000 +210F:000000000000005000E0038004F0018801080108021002100210042000000000 +2110:000000000C14240404060C1424283000 +2111:00000000397FC68066086CA6663C0000 +2112:0000000C12123C101010107099660000 +2113:000000182424242830602020221C0000 +2114:000000004848FE484A4D494949360000 +2115:00000000715159595555535351710000 +2116:00000000929595D2D0B7B09090900000 +2117:000000003C42B9A5A5B9A1A1423C0000 +2118:000000000000204C5222222A54505020 +2119:000000007C525252525C505050700000 +211A:000000001C32515151515151361E0100 +211B:000000402E113151515E545252210000 +211C:00000000446EB233363C3636A2C30000 +211D:000000007E515151515E585452710000 +211E:000000007C4242427C504A444A500000 +211F:000038087C4A4A4A7C6858484C4A0800 +2120:00000000719B5531D100000000000000 +2121:00000000FE525A525F00000000000000 +2122:00000000F15B55515100000000000000 +2123:0000300C85894A525424287850800000 +2124:000000007E0A0A1214242848507E0000 +2125:000000003C08103E0408180402423C00 +2126:000000003E4141414141221414770000 +2127:000000007714142241414141413E0000 +2128:000000003C464606081E020666A6663C +2129:000000000000300808080808080C0000 +212A:00000000424448506060504844420000 +212B:1824180018242442427E424242420000 +212C:000000002E5151515E515151512E0000 +212D:000000001624686866666468221C0000 +212E:0000000000000000000007E00810181818181FF818001800081007E000000000 +212F:00000000000000182448704044380000 +2130:000000000E1220201C204044423C0000 +2131:000000003C42020404083E1020200000 +2132:0000000002020202023E0202027E0000 +2133:0000000063362A2A2A2A2A6AAA490000 +2134:0000000000001824534E424224180000 +2135:00000000000044462214286472620000 +2136:0000000000103E02020202023F7E0000 +2137:0000000000403C1E0202020E32320000 +2138:0000000000403E1F0202020203020000 +2139:0000000018180038181818187E000000 +213A:000000000000000000000000000000081FE820302050205020301FE000000000 +213B:00000000000000007C004000400040007222451448884F88489448A200000000 +213C:0000000000000000000000001FF80A500A500A500A500A480A240E1C00000000 +213D:0000000000000000000000000C040A08091004A0024002400480090012001C00 +213E:000000007F5553515050505050700000 +213F:00000000000000003FF8145014501450145014501450145014501C7000000000 +2140:00000000000000001FF81228091804880240024004800908121814281FF80000 +2141:000000005C62424272020202423C0000 +2142:000000007E0202020202020202020000 +2143:000000000202020202020202027E0000 +2144:00000000080808080814222241410000 +2145:000000000000000007E00530052809280A280A481250145014601FC000000000 +2146:0000000000000000003800280028004807D00A50129014A014A00FE000000000 +2147:00000000000000000000000003E00510091013F01400140014200FC000000000 +2148:00000000000000200040000000E00140014001400280028002800FE000000000 +2149:000000000000000800100000003800500050005000A000A000A000A008C00700 +214A:000010107C525252525C1010101E0000 +214B:000000004E3121514A0C1422221C0000 +214C:000000000000000034C04D20252005201FF825241FC405080500020000000000 +214D:0000000042A2E4A80813142241460000 +214E:000000000000000404043C04047C0000 +214F:0000000000000000000000000000000011102AA82AA82AA811106EEC00000000 +2150:0000000022622428281E122244440400 +2151:0000000022622428281E1A2E424C0000 +2152:0000000042C24448502255B595120000 +2153:0000000022622428281C1224424C0000 +2154:0000000062122448781C1224424C0000 +2155:0000000022622428281E182C424C0000 +2156:0000000062122448781E182C424C0000 +2157:0000000062122418681E182C424C0000 +2158:000000002262F428281E182C424C0000 +2159:00000000226224282816182E4A4E0000 +215A:00000000724264186816182E4A4E0000 +215B:000000002262242828141A244A4E0000 +215C:000000006212241868141A244A4E0000 +215D:000000007242641868141A244A4E0000 +215E:000000007212244848141A244A4E0000 +215F:00000000226224282810102040400000 +2160:000000001C08080808080808081C0000 +2161:000000007E24242424242424247E0000 +2162:000000007F2A2A2A2A2A2A2A2A7F0000 +2163:000000007F29292929292626267F0000 +2164:000000007F22222214141408083E0000 +2165:00000000FF4A4A4A4A4A3232327F0000 +2166:00000000FF55555555252525257F0000 +2167:00000000FFB5B5B5B555555555FF0000 +2168:000000007F2A2A2A24242A2A2A7F0000 +2169:000000007F22221408081422227F0000 +216A:000000007F2A2A2A12122A2A2A7F0000 +216B:000000007F55555525255555557F0000 +216C:000000007020202020202020227E0000 +216D:000000001A26404040404040221C0000 +216E:00000000782422222222222224780000 +216F:0000000063223636362A2A2A2A7F0000 +2170:000000000808000818080808081C0000 +2171:00000000242400246C242424247E0000 +2172:000000002A2A002A7E2A2A2A2A7F0000 +2173:000000002020003B69292926267F0000 +2174:000000000000007722222214083E0000 +2175:000000000202005A4E4A4A32327F0000 +2176:00000000050500555F555525257F0000 +2177:00000000151500B5BFB5555555FF0000 +2178:000000002020002A6A24242A2A7F0000 +2179:00000000000000772214081422770000 +217A:000000000202002A2E12122A2A7F0000 +217B:00000000050500555F252555557F0000 +217C:000000000818080808080808081C0000 +217D:000000000000001A26404040221C0000 +217E:000000000206021A26424242261B0000 +217F:000000000000742A2A2A2A2A2A7F0000 +2180:000000003E49494949494949493E0000 +2181:000000007824322A2A2A2A3224780000 +2182:000000000000000007C00920139015501550155015501390092007C000000000 +2183:000000003C42420202020242423C0000 +2184:0000000000003C4202020202423C0000 +2185:000000003A46808080808080463A0202 +2186:00000000101010101010925438100000 +2187:000000F8467149655565497146F80000 +2188:0000000000000FE0311847C44924539455545394492447C431180FE000000000 +2189:0000000022525458281C1224424C0000 +218A:000000007E02020408304042423C0000 +218B:000000003C42424040384042423C0000 +218C:00007FFE61EE7DCE61EE6FEE61C67FFE7FFE73C66DBE73BE6DBE73C67FFE0000 +218D:00007FFE61EE7DCE61EE6FEE61C67FFE7FFE738E6DB673B66DB6738E7FFE0000 +218E:00007FFE61EE7DCE61EE6FEE61C67FFE7FFE73866DBE738E6DBE73867FFE0000 +218F:00007FFE61EE7DCE61EE6FEE61C67FFE7FFE73866DBE738E6DBE73BE7FFE0000 +2190:0000000000000010207F201000000000 +2191:0000081C2A0808080808080808080808 +2192:000000000000000804FE040800000000 +2193:08080808080808080808082A1C080000 +2194:000000000000002442FF422400000000 +2195:0000081C2A0808080808082A1C080000 +2196:00000000007860504804020000000000 +2197:00000000001E060A1220400000000000 +2198:00000000004020120A061E0000000000 +2199:00000000000002044850607800000000 +219A:0000000000040414247F241404040000 +219B:000000000020202824FE242820200000 +219C:0000000000000000000000003800301C28220441038000000000000000000000 +219D:000000000000000000000000001C380C4414822001C000000000000000000000 +219E:000000000000002448FF482400000000 +219F:0000081C2A081C2A0808080808080808 +21A0:000000000000002412FF122400000000 +21A1:0808080808080808082A1C082A1C0800 +21A2:0000000000000011227C221100000000 +21A3:0000000000000088443E448800000000 +21A4:0000000000000012227E221200000000 +21A5:0000081C2A08080808080808083E0000 +21A6:0000000000000048447E444800000000 +21A7:00003E08080808080808082A1C080000 +21A8:0000081C2A08080808082A1C083E0000 +21A9:0000000000000211217E201000000000 +21AA:0000000000002044423F020400000000 +21AB:0000000000000215257E241400000000 +21AC:0000000000002054523F121400000000 +21AD:00000000000000245AE7422400000000 +21AE:000000000008082C4AFF4A2C08080000 +21AF:00004040404858684808082A1C080000 +21B0:00000000000000102078241404040404 +21B1:0000000000000008041E242820202020 +21B2:04040404040404142478201000000000 +21B3:2020202020202028241E040800000000 +21B4:000000000000000000FC04150E040000 +21B5:0404040404040414247C201000000000 +21B6:0000000000001E21A971200000000000 +21B7:0000000000007884958E040000000000 +21B8:0000007E007860504804020000000000 +21B9:00000050607E6050000A067E060A0000 +21BA:000000000000002E4C4A42423C000000 +21BB:0000000000000074325242423C000000 +21BC:0000000000000010207F000000000000 +21BD:0000000000000000007F201000000000 +21BE:0000080C0A0808080808080808080808 +21BF:00000818280808080808080808080808 +21C0:000000000000000804FE000000000000 +21C1:000000000000000000FE040800000000 +21C2:08080808080808080808080A0C080000 +21C3:08080808080808080808082818080000 +21C4:00000008047E04080010207E20100000 +21C5:00002474AC242424242424352E240000 +21C6:00000010207E20100008047E04080000 +21C7:00000010207E20100010207E20100000 +21C8:0000247EA52424242424242424240000 +21C9:00000008047E04080008047E04080000 +21CA:0000242424242424242424A57E240000 +21CB:00000000000010207E007E0408000000 +21CC:00000000000008047E007E2010000000 +21CD:00000000000808287E887E2808080000 +21CE:000000000008082C7E897E2C08080000 +21CF:00000000001010147E117E1410100000 +21D0:00000000000000103E403E1000000000 +21D1:00000814361414141414141414140000 +21D2:00000000000000087C027C0800000000 +21D3:00001414141414141414143614080000 +21D4:00000000000000247E817E2400000000 +21D5:00000814361414141414143614080000 +21D6:0000000000785068540A040000000000 +21D7:00000000001E0A162A50200000000000 +21D8:000000000020502A160A1E0000000000 +21D9:0000000000040A546850780000000000 +21DA:000000000000103E40FE403E10000000 +21DB:000000000000087C027F027C08000000 +21DC:000000000000002042F5482000000000 +21DD:000000000000000442AF120400000000 +21DE:0000081C2A0808083E083E0808080808 +21DF:08080808083E083E0808082A1C080000 +21E0:00000000000000102077201000000000 +21E1:0000081C2A0808000808080800080808 +21E2:000000000000000402EF020400000000 +21E3:08080800080808080008082A1C080000 +21E4:0000000000000050607F605000000000 +21E5:000000000000000A06FE060A00000000 +21E6:00000000000010305F815F3010000000 +21E7:000008142277141414141414141C0000 +21E8:000000000000080CFA81FA0C08000000 +21E9:00001C14141414141414772214080000 +21EA:0000081422771414141C001C141C0000 +21EB:000008142263222222222263417F0000 +21EC:000008143E63222222222263417F0000 +21ED:0000081C2A6B2A2A2A2A2A6B497F0000 +21EE:0008142A7722632222222222223E0000 +21EF:0008142A7722632222222263417F0000 +21F0:000000000000086C7A417A6C08000000 +21F1:00000000007F405C5854424140400000 +21F2:000000000001014121150D1D017F0000 +21F3:00000814361414141414143614080000 +21F4:000000000000000000000000000007080884FFFE088407080000000000000000 +21F5:0000242E35242424242424AC74240000 +21F6:0000000402FF020402FF020402FF0204 +21F7:000000000000002444FF442400000000 +21F8:000000000000002422FF222400000000 +21F9:0000000000000000000000000000092011103FF8111009200000000000000000 +21FA:0000000000000000000000000000114021407FFF214011400000000000000000 +21FB:000000000000000000000000000002880284FFFE028402880000000000000000 +21FC:0000000000000000000000000000129022887FFC228812900000000000000000 +21FD:000000000000002060BF602000000000 +21FE:000000000000000406FD060400000000 +21FF:0000000000000000000000000000081018182FF4181808100000000000000000 +2200:0000000041413E222214141408080000 +2201:00000000182424202020202424180000 +2202:000000001C2202021E22424444380000 +2203:000000007E0202027E020202027E0000 +2204:000004047E0A0A127E122222227E4040 +2205:000000000000001D22454951225C0000 +2206:000000000808141414222222417F0000 +2207:000000007F4122222214141408080000 +2208:000000000000003E40407E40403E0000 +2209:000000000004043E48487E50503E2020 +220A:0000000000000000003E407E403E0000 +220B:000000000000007C02027E02027C0000 +220C:000000000004047C0A0A7E12127C2020 +220D:0000000000000000007C027E027C0000 +220E:000000007E7E7E7E7E7E7E7E7E7E0000 +220F:000000007F2222222222222222227700 +2210:00000000772222222222222222227F00 +2211:000000007E4220100804081020427E00 +2212:0000000000000000007E000000000000 +2213:000000007F000808087F080808000000 +2214:0000081C08000808087F080808000000 +2215:00000000020404080810102020400000 +2216:00000000402020101008080404020000 +2217:000000000000082A1C081C2A08000000 +2218:00000000000000001824241800000000 +2219:0000000000000000183C3C1800000000 +221A:00000704040404047414140C0C040400 +221B:00006714641464047414140C0C040400 +221C:00005754741414047414140C0C040400 +221D:00000000000000364848360000000000 +221E:00000000000000364949360000000000 +221F:000000000000004040404040407E0000 +2220:000000000000000002040810207E0000 +2221:000000000000000002140814247E0400 +2222:000000000000000A0C1464140C0A0000 +2223:00000000181818181818181818180000 +2224:0000000018181A1C1818385818180000 +2225:00000000242424242424242424240000 +2226:00000000242426242C34246424240000 +2227:00000000000008081414222241410000 +2228:00000000000041412222141408080000 +2229:0000000000003C424242424242420000 +222A:000000000000424242424242423C0000 +222B:00060A08080808080808080808283000 +222C:000A1514141414141414141414546800 +222D:00152A2A2A2A2A2A2A2A2A2A2AAAD400 +222E:00060A0808081C2A2A1C080808283000 +222F:000A151414143E55553E141414546800 +2230:00152A2A2A7EABABAB7E2A2A2AAAD400 +2231:00060A0808081D2B2F08080808283000 +2232:00060A0808081D2B2F2A1C0808283000 +2233:00060A0808085C6A7A2A1C0808283000 +2234:00000000000018180000006666000000 +2235:00000000000066660000001818000000 +2236:00000000000018180000001818000000 +2237:00000000000066660000006666000000 +2238:0000000000001818007E000000000000 +2239:00000000000006060078000606000000 +223A:0000000000006666007E006666000000 +223B:0000000000181800324C001818000000 +223C:0000000000000000324C000000000000 +223D:00000000000000004C32000000000000 +223E:00000000000000003249260000000000 +223F:00000000000000304849090600000000 +2240:00000000001008080810101008000000 +2241:0000000000000404083A541020200000 +2242:00000000000000007E0000324C000000 +2243:00000000000000324C00007E00000000 +2244:000000040408083A5410107E20204040 +2245:00000000324C00007E00007E00000000 +2246:00000000324C02047E08107E20400000 +2247:000004043A4C08107E10207E20404000 +2248:00000000000000324C00324C00000000 +2249:000000000004043A4C103A5420200000 +224A:0000000000324C00324C007E00000000 +224B:0000000000324C00324C00324C000000 +224C:000000004C3200007E00007E00000000 +224D:000000000000423C00003C4200000000 +224E:00000000000018660000661800000000 +224F:00000000000000186600007E00000000 +2250:00000000181800007E00007E00000000 +2251:0000001818007E00007E001818000000 +2252:0000006060007E00007E000606000000 +2253:0000000606007E00007E006060000000 +2254:000000000000005E00005E0000000000 +2255:000000000000007A00007A0000000000 +2256:000000000000007E24247E0000000000 +2257:00000018242418007E00007E00000000 +2258:000000003C4200007E00007E00000000 +2259:00000018244200007E00007E00000000 +225A:00000042241800007E00007E00000000 +225B:0000083E1C1400007E00007E00000000 +225C:00000814223E00007E00007E00000000 +225D:0000121476547400007E00007E000000 +225E:00000068545454007E00007E00000000 +225F:0030480810100010007E00007E000000 +2260:00000000000002047E08107E20400000 +2261:000000000000007E007E007E00000000 +2262:000000000002047E087E107E20400000 +2263:0000000000007E007E007E007E000000 +2264:0000000000000618601806007E000000 +2265:0000000000006018061860007E000000 +2266:0000000618601806007E00007E000000 +2267:0000006018061860007E00007E000000 +2268:0000000618601806047E08107E204000 +2269:0000006018061862047E08107E204000 +226A:00000000000912244890482412090000 +226B:00000000009048241209122448900000 +226C:00000000241818242424241818240000 +226D:000000020204857E08107EA120404000 +226E:00000008080C18103050303018242000 +226F:00000000084828101814181020602020 +2270:0000000002020E1468181E107E202000 +2271:0000000008087018162870207E404000 +2272:000000000000061860180600324C0000 +2273:000000000000601806186000324C0000 +2274:0000000004040E1868181E103A642020 +2275:000000000808781816187010326C2020 +2276:00000000061860180660180618600000 +2277:00000000601806186006186018060000 +2278:000002020E1468181E70282E50608080 +2279:00000404681816187016386038264040 +227A:00000000000202041860180402020000 +227B:00000000004040201806182040400000 +227C:0000000000020204186018641A040200 +227D:00000000004040201806182658204000 +227E:000000000002020418601804669A0000 +227F:00000000004040201806182059660000 +2280:0000000004060A0C0870181422220000 +2281:0000000004444828180E183050602000 +2282:0000000000003E404040403E00000000 +2283:0000000000007C020202027C00000000 +2284:0000000004043E485050603E40400000 +2285:0000000002027C0A0A12127C20200000 +2286:0000000000003E404040403E007E0000 +2287:0000000000007C020202027C007E0000 +2288:0000000004043E484850503E207E4000 +2289:0000000002027C0A0A12127C207E4000 +228A:0000000000003E404040403E047E1000 +228B:0000000000007C020202027C087E2000 +228C:000000004242424A527E524A423C0000 +228D:0000000042424242425A5A42423C0000 +228E:0000000042424252527A5252423C0000 +228F:0000000000007E404040407E00000000 +2290:0000000000007E020202027E00000000 +2291:0000000000007E404040407E007E0000 +2292:0000000000007E020202027E007E0000 +2293:0000000000007E424242424200000000 +2294:00000000000042424242427E00000000 +2295:0000000000001C2A497F492A1C000000 +2296:0000000000001C22417F41221C000000 +2297:0000000000001C22554955221C000000 +2298:0000000000001C22454951221C000000 +2299:0000000000001C22414941221C000000 +229A:0000000000001C22495549221C000000 +229B:0000000000001C22495D49221C000000 +229C:0000000000001C225D415D221C000000 +229D:0000000000001C22415D41221C000000 +229E:0000000000007F49497F49497F000000 +229F:0000000000007F41417F41417F000000 +22A0:0000000000007F63554955637F000000 +22A1:0000000000007F41414941417F000000 +22A2:0000000000004040407E404040000000 +22A3:0000000000000202027E020202000000 +22A4:0000000000007F080808080808000000 +22A5:0000000000000808080808087F000000 +22A6:0000000000202020203C202020200000 +22A7:00000000002020203C203C2020200000 +22A8:00000000004040407E407E4040400000 +22A9:0000000000505050505E505050500000 +22AA:00000000005454545457545454540000 +22AB:00000000005050505E505E5050500000 +22AC:0000000000404048487E484840400000 +22AD:00000000004048487E487E4848400000 +22AE:0000000000505054545E545450500000 +22AF:00000000005054545E545E5454500000 +22B0:00000000000C020418601804020C0000 +22B1:00000000003040201806182040300000 +22B2:00000000000000061A621A0600000000 +22B3:00000000000000605846586000000000 +22B4:00000000000000061A621A06007E0000 +22B5:000000000000006058465860007E0000 +22B6:0000000000000000000000000000300C481E4FFE481E300C0000000000000000 +22B7:0000000000000000000000000000300C78127FF27812300C0000000000000000 +22B8:0000000000000000000000000000003800443FC4004400380000000000000000 +22B9:00000000000008080063000808000000 +22BA:000000003E0808080808080808080000 +22BB:000000000000002222141408003E0000 +22BC:0000000000003E000814142222000000 +22BD:0000000000003E002222141408000000 +22BE:000000000000004040407848487E0000 +22BF:000000000000000002060A12227E0000 +22C0:00000000081414142222224141410000 +22C1:00000000414141222222141414080000 +22C2:000000003C4242424242424242420000 +22C3:000000004242424242424242423C0000 +22C4:00000000000000081422140800000000 +22C5:00000000000000001818000000000000 +22C6:00000000000000083E1C140000000000 +22C7:0000000000001842247E244218000000 +22C8:00000000000041635549556341000000 +22C9:00000000000041625448546241000000 +22CA:00000000000041231509152341000000 +22CB:00000000000000201008142200000000 +22CC:00000000000000020408142200000000 +22CD:00000000000000004C3200007E000000 +22CE:00000000000041222214141408000000 +22CF:00000000000008141414222241000000 +22D0:0000000000003E404E50504E403E0000 +22D1:0000000000007C02720A0A72027C0000 +22D2:0000000000003E414955555555550000 +22D3:000000000000555555555549413E0000 +22D4:000000000808081C2A2A2A2A2A2A0000 +22D5:00000000242424247E24247E24240000 +22D6:00000000000204081022100804020000 +22D7:00000000004020100844081020400000 +22D8:0000000000000000000002220444088811102220111008880444022200000000 +22D9:0000000000000000000044402220111008880444088811102220444000000000 +22DA:00000618601806007E00601806186000 +22DB:00006018061860007E00061860180600 +22DC:0000000000007E000618601806000000 +22DD:0000000000007E006018061860000000 +22DE:0000000002041A641860180402020000 +22DF:00000000402058261806182040400000 +22E0:0000000414162ACC1868181412222020 +22E1:000000020A4A442B1816183060602020 +22E2:0000000202047E484850507E207E4000 +22E3:0000000202047E0A0A12127E207E4000 +22E4:0000000000007E404040407E087E2000 +22E5:0000000000007E020202027E087E2000 +22E6:00000000000618601806043A5C204000 +22E7:00000000006018061862043A5C204000 +22E8:00000002020418601804063A5C204000 +22E9:00004040201806182042443A5C204000 +22EA:000000000002020E166A1A1E10202000 +22EB:00000000000404685C56687020404000 +22EC:000000000002020E166A1A1E107E2000 +22ED:00000000000404685C566870207E4000 +22EE:00000000181800001818000018180000 +22EF:0000000000000000DBDB000000000000 +22F0:000000000303000018180000C0C00000 +22F1:00000000C0C000001818000003030000 +22F2:0000000000000000000007F00800100010007FF010001000080007F000000000 +22F3:0000000000000000000007F00800100010101FF010101000080007F000000000 +22F4:0000000000003E40427E42403E000000 +22F5:0000000001800180000007F00800100010001FF010001000080007F000000000 +22F6:0000000000001FF0000007F00800100010001FF010001000080007F000000000 +22F7:000000007E003E40407E40403E000000 +22F8:0000000000003E40407E40403E007E00 +22F9:000000000000000000001FC0200040007FC040007FC0400020001FC000000000 +22FA:000000000000000000003F800040002000203FF80020002000403F8000000000 +22FB:000000000000000000003F800040002020203FE02020002000403F8000000000 +22FC:0000000000007C02427E42027C000000 +22FD:0000000000003FE000003F800040002000203FE00020002000403F8000000000 +22FE:000000007E007C02027E02027C000000 +22FF:000000000000000000001FF81000100010001FF81000100010001FF800000000 +2300:0000000000000000000807D0082010501090111012101410082017C020000000 +2301:00000000000000009058341200000000 +2302:000000000000182442424242427E0000 +2303:00000000081422000000000000000000 +2304:00000000000000000000002214080000 +2305:000000003E0008142200000000000000 +2306:000000003E003E000814220000000000 +2307:00000010080408100804081008040000 +2308:00001E10101010101010101010100000 +2309:00007808080808080808080808080000 +230A:000010101010101010101010101E0000 +230B:00000808080808080808080808780000 +230C:00000000000000000007080808000000 +230D:00000000000000000070080808000000 +230E:00000000000008080807000000000000 +230F:00000000000008080870000000000000 +2310:000000000000000000007E4040400000 +2311:000000000000413E2222223E41000000 +2312:000000000000000000001C2241410000 +2313:000000000000000000001C22417F0000 +2314:00000000000000001C22412214080000 +2315:000000000000001C22414141225C8000 +2316:00000080008003E004900888108410047E3F100410840888049003E000800080 +2317:00000000002424FF2424FF2424000000 +2318:00000000000022553E143E5522000000 +2319:0000000000004040407E000000000000 +231A:0000282828283854929B824438282828 +231B:000000007E242424181824243C7E0000 +231C:00784040400000000000000000000000 +231D:001E0202020000000000000000000000 +231E:00000000000000000000004040407800 +231F:00000000000000000000000202021E00 +2320:00000000060A08080808080808080808 +2321:08080808080808080808283000000000 +2322:0000000000000000003C420000000000 +2323:0000000000000000423C000000000000 +2324:00000000000000007708142200000000 +2325:00000000000000006710080700000000 +2326:00000000000000FCAA91AAFC00000000 +2327:000000000000007F5549557F00000000 +2328:000000000000007E7E7E003C00000000 +2329:0000000800080010001000200020004000800040002000200010001000080008 +232A:0000200020001000100008000800040002000400080008001000100020002000 +232B:000000000000003F5589553F00000000 +232C:00000000008001400220049008480A280A080A28084804900220014000800000 +232D:00000000000000000081010201C40224041804100C10122011C0204040800000 +232E:000000000000000003C004200810100810FE110812080A1004202BC030003800 +232F:0000000000000000000000000FF0000000007FFE000000000FF0000000000000 +2330:000004020C061E0F080410081008201020104020402080408040FFC000000000 +2331:0000000000001F00248044408420842487FF84248420444024801F0000000000 +2332:000000000000000000003C0023802070200C7FFE200C207023803C0000000000 +2333:0000000000000000000000000000000060005C0043804070400C7FFE00000000 +2334:00000000000000000000000040024002400240024002400240027FFE00000000 +2335:0000000000000000000000004001200210040808041002200140008000000000 +2336:000000007F08080808080808087F0000 +2337:000000003E22222222222222223E0000 +2338:0000007F4141417F41417F41417F0000 +2339:0000007F414949417F414949417F0000 +233A:0000007F4149556341635549417F0000 +233B:0000007F4141414955554941417F0000 +233C:0000007F41415D634141635D417F0000 +233D:00000008081C2A4949492A1C08080000 +233E:00000000001C22495549221C00000000 +233F:000000000204040808FF102020400000 +2340:000000004020201010FF080404020000 +2341:0000007F4143454549515161417F0000 +2342:0000007F4161515149454543417F0000 +2343:0000007F4141475961594741417F0000 +2344:0000007F4141714D434D7141417F0000 +2345:00000008080808287F28080808080000 +2346:000000080808080A7F0A080808080000 +2347:0000007F414149517F514941417F0000 +2348:0000007F414149457F454941417F0000 +2349:000000000000005C22514945221D0000 +234A:00000000080808080808087F007F0000 +234B:000000000808081C1C2A2A3E08080000 +234C:00007F414141416363555549417F0000 +234D:00007F41414949555563637F417F0000 +234E:000000000808081C2A2A1C08087F0000 +234F:00000000081C2A087F08080808080000 +2350:00007F495D6B494949494949497F0000 +2351:000000003E003E080808080808080000 +2352:0000000008083E2A2A1C1C0808080000 +2353:00007F414955556363414141417F0000 +2354:00007F41417F636355554949417F0000 +2355:000000007F08081C2A2A1C0808080000 +2356:0000000808080808087F082A1C080000 +2357:00007F494949494949496B5D497F0000 +2358:000000000808080000000000003E0000 +2359:00000000000808141422223E003E0000 +235A:000000000008142241221408003E0000 +235B:000000000000001824241800003E0000 +235C:00000000001C22414141221C007F0000 +235D:000000001C2249554941414141410000 +235E:00007F414949494141414141417F0000 +235F:000000001C22497F5D55221C00000000 +2360:00007F414149494141494941417F0000 +2361:002424007F0808080808080808080000 +2362:00242400003E22221414080800000000 +2363:0024240000083E1C1400000000000000 +2364:00242400000000182424180000000000 +2365:002424000000001C22414141221C0000 +2366:00000000494949494949492A1C080000 +2367:00000008081F28484848281F08080000 +2368:00242400000000324C00000000000000 +2369:00242400402010080402040810204000 +236A:000000003C0000180808100000000000 +236B:00000000003E22221414394E00000000 +236C:000000001C222222336E2222221C0000 +236D:0000000008080808083A4C0808080000 +236E:000000001818000018080810003E0000 +236F:00007F4143457F497F516141417F0000 +2370:00007F414955554549494149417F0000 +2371:00000000324C00222214140800000000 +2372:0000000000324C000814142222000000 +2373:00000000000000180808080808060000 +2374:0000000000003C4242424242625C4040 +2375:00000000000014224949494949360000 +2376:0000000000324A4444444A32007E0000 +2377:00000000003E40407C40403E007E0000 +2378:000000000018080808080806001E0000 +2379:000000000022414949494936007F0000 +237A:000000000000324A444444444A320000 +237B:000000000000000200040008001001FC00400080410022001400080000000000 +237C:000000000A000C00080018002800180008000C000A000C004FFE500060007800 +237D:0000000000000000000000000000000000000000783C082008200FE000000000 +237E:000000000000000003C004200810100810081FF80420042004201C3800000000 +237F:000008080808081C3E1C080808080000 +2380:00000038043C44443A00824428100000 +2381:000000000000000000000000380004003C00440044003A5400007FFC00000000 +2382:000000000000000000000000387004083C78448844883A7400007EFC00000000 +2383:0000000000000000400420081390004073DC0440145023A84004000000000000 +2384:0000000000000000000000003FF02108220422042204220421083FF000000000 +2385:0000000000000000010001001D701110111011101110111011101D7001000100 +2386:00000100028004400820121003087E8440427E84030812100820044002800100 +2387:00000000000000000000000000000020003000E801300220040078FE00000000 +2388:00000100010023881D701930155023882388155019301D702388010001000000 +2389:000000000F8030604010401080088008F078888888884510451032600F800000 +238A:000000000F80306040107FF0A02890489048888888884510451032600F800000 +238B:0000000001807C6048105010680844080208810880884050401030600F800000 +238C:000000000000000007E0081010087C0828081008381C44224422381C00000000 +238D:000000000000000007E0042004200420042004200420042004203C3C00000000 +238E:000000000000000001FC021004200420042004200420042008403F8000000000 +238F:000000000000000000001FF00280044008201010082004400280010000000000 +2390:00000000000000000000010002800440082010100820044002801FF000000000 +2391:000000000000000000001FF00280044008201FF0082004400280010000000000 +2392:0000000000000000000001000280044008201FF00820044002801FF000000000 +2393:000000000000000000000000000000007FFC0000739C00000000000000000000 +2394:0000000000000000000007E0081010082004400220041008081007E000000000 +2395:00007F414141414141414141417F0000 +2396:0000000000007C7C7878707060604000 +2397:00006DB040104FFC48044A044E044BE450244BE44E047A0408040FFC00000000 +2398:00007FF040104EDC4804490449845F4050245F444980790408040CDC00000000 +2399:000001E0032005200F20082038384824882288228FE2800240043FF800000000 +239A:000000000000000000001FF020284244449449245244448428081FF000000000 +239B:000E1830303030303030303030303030 +239C:30303030303030303030303030303030 +239D:3030303030303030303030303030180E +239E:0070180C0C0C0C0C0C0C0C0C0C0C0C0C +239F:0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C +23A0:0C0C0C0C0C0C0C0C0C0C0C0C0C0C1870 +23A1:003E3030303030303030303030303030 +23A2:30303030303030303030303030303030 +23A3:3030303030303030303030303030303E +23A4:007C0C0C0C0C0C0C0C0C0C0C0C0C0C0C +23A5:0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C +23A6:0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C7C +23A7:00060C18181818181818181818181818 +23A8:18181818181810204020101818181818 +23A9:18181818181818181818181818180C06 +23AA:18181818181818181818181818181818 +23AB:00603018181818181818181818181818 +23AC:18181818181808040204081818181818 +23AD:18181818181818181818181818183060 +23AE:08080808080808080808080808080808 +23AF:000000000000000000FF000000000000 +23B0:060C1818181818181818181818183060 +23B1:60301818181818181818181818180C06 +23B2:00000000000000007FFE300E3006180218000C000C0006000600030003000180 +23B3:018003000300060006000C000C00180018023006300E7FFE0000000000000000 +23B4:00000000000000007FFE40024002000000000000000000000000000000000000 +23B5:0000000000000000000000000000000000000000000000000000400240027FFE +23B6:000000000000000000000000400240027FFE00007FFE40024002000000000000 +23B7:08080808080808086828281818080800 +23B8:80808080808080808080808080808080 +23B9:01010101010101010101010101010101 +23BA:FF000000000000000000000000000000 +23BB:00000000FF0000000000000000000000 +23BC:0000000000000000000000FF00000000 +23BD:000000000000000000000000000000FF +23BE:003F2020202020202020202020202000 +23BF:00202020202020202020202020203F00 +23C0:00000100010003800D601110111021082108111011100D600380010001000000 +23C1:0000FFFF010003800D601110111021082108111011100D600380010001000000 +23C2:00000100010003800D601110111021082108111011100D6003800100FFFF0000 +23C3:0000010001000380038005400540092009201110111021083FF8010001000000 +23C4:0000FFFF01000380038005400540092009201110111021083FF8010001000000 +23C5:0000010001000380038005400540092009201110111021083FF80100FFFF0000 +23C6:0000010001000100010001001D00230001880170010001000100010001000000 +23C7:0000FFFF01000100010001001D00230001880170010001000100010001000000 +23C8:0000010001000100010001001D002300018801700100010001000100FFFF0000 +23C9:0000FFFF01000100010001000100010001000100010001000100010001000000 +23CA:00000100010001000100010001000100010001000100010001000100FFFF0000 +23CB:00FC0404040404040404040404040400 +23CC:0004040404040404040404040404FC00 +23CD:00000080793C42044404400440044004400440044004400440047FFC00000000 +23CE:00000000003E00220022002204220C42178220024004200817F00C0004000000 +23CF:00000000000010387CFE00FEFEFE0000 +23D0:08080808080808080808080808080808 +23D1:00000000000000008244380000000000 +23D2:000000000000FE008244380000000000 +23D3:000000000000000082443800FE000000 +23D4:000000000000000000000000FFFE000082824444383800000000000000000000 +23D5:000000000000000000000000000000008282444438380000FFFE000000000000 +23D6:00000000000000000000000000000000418222441C3800000000000000000000 +23D7:0000000000000000000200020002000200027FFE000000000000000000000000 +23D8:0000000000000000400240024002400240027FFE000000000000000000000000 +23D9:0000000000000000410241024102410241027FFE000000000000000000000000 +23DA:08080808080808080808087F001C0008 +23DB:0000000000000000000000001FF810081008FFFF100810081FF8000000000000 +23DC:000000000000000000000000000000000000000007E0381C4002800100000000 +23DD:0000000080014002381C07E00000000000000000000000000000000000000000 +23DE:000000000000000000000000000000000000010002803C784004800200000000 +23DF:00000000800240043C7802800100000000000000000000000000000000000000 +23E0:00000000000000000000000000000000000000000FF010082004400200000000 +23E1:000000004002200410080FF00000000000000000000000000000000000000000 +23E2:000000000000000000007FC040204020401040104008400840047FFC00000000 +23E3:00000000008001400220041009C80A280A280A2809C804100220014000800000 +23E4:0000000000000000000000000000000000007FFE000000000000000000000000 +23E5:000000000000000000000000000000000FFC10081008201020107FE000000000 +23E6:0000000000000000000000001800240042007FFC008400480030000000000000 +23E7:000000002400240022002206A91871A021C003E001C002A00410080810040000 +23E8:0000000000000000246A2A2A2A240000 +23E9:00000000000000000000208030C038E03CF03EF83CF038E030C0208000000000 +23EA:00000000000000000000020806180E381E783EF81E780E380618020800000000 +23EB:00000000000000000100038007C00FE01FF000000100038007C00FE01FF00000 +23EC:00000000000000001FF00FE007C00380010000001FF00FE007C0038001000000 +23ED:000000000000000000004104618471C479E47DF479E471C46184410400000000 +23EE:000000000000000000004104430C471C4F3C5F7C4F3C471C430C410400000000 +23EF:00000000000000000000104818481C481E481F481E481C481848104800000000 +23F0:00000100193037D82828111021082108210822082408101008200FE01C700000 +23F1:00000300030007D808381110210821082108200820081010082007C000000000 +23F2:00000000000007C008201010240822082108200820081010082007C000000000 +23F3:000000007FFC1010101012900D6006C0028006C0082011101AB015507FFC0000 +23F4:0000000000000000004000C001C003C007C00FC007C003C001C000C000400000 +23F5:000000000000000008000C000E000F000F800FC00F800F000E000C0008000000 +23F6:0000000000000000000000000100038007C00FE01FF03FF80000000000000000 +23F7:0000000000000000000000003FF81FF00FE007C0038001000000000000000000 +23F8:0000000000000660066006600660066006600660066006600660066000000000 +23F9:00000000000000001FF81FF81FF81FF81FF81FF81FF81FF81FF81FF800000000 +23FA:000000000000000007E00FF01FF81FF81FF81FF81FF81FF80FF007E000000000 +23FB:01800180018001801998399C318C718E61866186700E300C381C1FF80FF003C0 +23FC:000007E01FF83C3C781E718E61866186618661866186718E381C1FF80FF003C0 +23FD:018003C003C003C003C003C003C003C003C003C003C003C003C003C003C00180 +23FE:0400080018003800380078007800780078007C003C003E001F000F8007E001F0 +23FF:000000000000001C007801940624182260221822062401940078001C00000000 +2400:000000000000000000004A506A505A50499E0000000000000000000000000000 +2401:0000000000000000000039924252325E0A527192000000000000000000000000 +2402:000000000000000000003BA44124311809247124000000000000000000000000 +2403:000000000000000000007BA44124791841247924000000000000000000000000 +2404:0000000000000000000079BE42487A4842487988000000000000000000000000 +2405:000000000000000000007A4C42527B5242D67A4E000000000000000000000000 +2406:0000000000000000000031A44A287A304A2849A4000000000000000000000000 +2407:0000000000000000000073D04A1073D04A1073DE000000000000000000000000 +2408:000000000000000000001E3811401E3011081E70000000000000000000000000 +2409:0000000000000000000022F822203E2022202220000000000000000000000000 +240A:0000000000000000000020F8208020F820803E80000000000000000000000000 +240B:0000000000000000000022F82220222014200820000000000000000000000000 +240C:000000000000000000003EF820803EF820802080000000000000000000000000 +240D:000000000000000000001EF0208820F020901E88000000000000000000000000 +240E:000000000000000000001E7020881C8802883C70000000000000000000000000 +240F:000000000000000000001EF820201C2002203CF8000000000000000000000000 +2410:00000000000000000000391C2510251C251039DC000000000000000000000000 +2411:0000000000000000000071884A184A084A08719C000000000000000000000000 +2412:0000000000000000000071984A044A084A10719C000000000000000000000000 +2413:0000000000000000000071984A044A184A047198000000000000000000000000 +2414:0000000000000000000071844A0C4A144A1C7184000000000000000000000000 +2415:0000000000000000000049926A546A585BD44A52000000000000000000000000 +2416:000000000000000000003452429A311609127112000000000000000000000000 +2417:000000000000000000007BB84124793841247938000000000000000000000000 +2418:00000000000000000000332444B447AC44A434A4000000000000000000000000 +2419:000000000000000000003E8820D83EA820883E88000000000000000000000000 +241A:000000000000000000003A5C4252325C0A52719C000000000000000000000000 +241B:0000000000000000000079CE4210799040507B8E000000000000000000000000 +241C:000000000000000000001E7010801E60101010E0000000000000000000000000 +241D:000000000000000000000E701080166012100EE0000000000000000000000000 +241E:000000000000000000001C7012801C60141012E0000000000000000000000000 +241F:0000000000000000000012701280126012100CE0000000000000000000000000 +2420:000000000000000000003B80424033800A007200000000000000000000000000 +2421:0000000000000000000073D04A104BD04A1073DE000000000000000000000000 +2422:00000000141810305C121212121C0000 +2423:000000000000000000000000427E0000 +2424:0000000048685848001010101E000000 +2425:0000000000010A152A54284000000000 +2426:000000003C4242402010100010100000 +2427:00007FFE61B67DB661866FF661F67FFE7FFE61867DF661EE6FDE61DE7FFE0000 +2428:00007FFE61B67DB661866FF661F67FFE7FFE61CE7DB661CE6FB661CE7FFE0000 +2429:00007FFE61B67DB661866FF661F67FFE7FFE61CE7DB661C66FF661CE7FFE0000 +242A:00007FFE61B67DB661866FF661F67FFE7FFE61867DB661866FB661B67FFE0000 +242B:00007FFE61B67DB661866FF661F67FFE7FFE618E7DB6618E6FB6618E7FFE0000 +242C:00007FFE61B67DB661866FF661F67FFE7FFE61C67DBE61BE6FBE61C67FFE0000 +242D:00007FFE61B67DB661866FF661F67FFE7FFE618E7DB661B66FB6618E7FFE0000 +242E:00007FFE61B67DB661866FF661F67FFE7FFE61867DBE618E6FBE61867FFE0000 +242F:00007FFE61B67DB661866FF661F67FFE7FFE61867DBE618E6FBE61BE7FFE0000 +2430:00007FFE61B67DB661866FF661F67FFE7FFE63CE7DB671B67DB663CE7FFE0000 +2431:00007FFE61B67DB661866FF661F67FFE7FFE63EE7DCE71EE7DEE63C67FFE0000 +2432:00007FFE61B67DB661866FF661F67FFE7FFE63867DF671867DBE63867FFE0000 +2433:00007FFE61B67DB661866FF661F67FFE7FFE638E7DF671C67DF6638E7FFE0000 +2434:00007FFE61B67DB661866FF661F67FFE7FFE63B67DB671867DF663F67FFE0000 +2435:00007FFE61B67DB661866FF661F67FFE7FFE63867DBE71867DF663867FFE0000 +2436:00007FFE61B67DB661866FF661F67FFE7FFE63CE7DBE718E7DB663CE7FFE0000 +2437:00007FFE61B67DB661866FF661F67FFE7FFE63867DF671EE7DDE63DE7FFE0000 +2438:00007FFE61B67DB661866FF661F67FFE7FFE63CE7DB671CE7DB663CE7FFE0000 +2439:00007FFE61B67DB661866FF661F67FFE7FFE63CE7DB671C67DF663CE7FFE0000 +243A:00007FFE61B67DB661866FF661F67FFE7FFE63867DB671867DB663B67FFE0000 +243B:00007FFE61B67DB661866FF661F67FFE7FFE638E7DB6718E7DB6638E7FFE0000 +243C:00007FFE61B67DB661866FF661F67FFE7FFE63C67DBE71BE7DBE63C67FFE0000 +243D:00007FFE61B67DB661866FF661F67FFE7FFE638E7DB671B67DB6638E7FFE0000 +243E:00007FFE61B67DB661866FF661F67FFE7FFE63867DBE718E7DBE63867FFE0000 +243F:00007FFE61B67DB661866FF661F67FFE7FFE63867DBE718E7DBE63BE7FFE0000 +2440:000000000E0A0A0A0808282828380000 +2441:0000000002020202023E222222220000 +2442:0000000022222222223E080808080000 +2443:0000000008080808083E222222220000 +2444:000000003E2A2A2A08082A2A2A3E0000 +2445:0000000022362A362200000000000000 +2446:00000000000E6E6E60606E6E0E000000 +2447:000000000303031B1818D8C0C0C00000 +2448:00000000075757505050505050500000 +2449:00000000006D6D6D6D6D6D6D6D6D0000 +244A:00000000A0A050282814140A05050000 +244B:00007FFE61B67DB661866FF661F67FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000 +244C:00007FFE61B67DB661866FF661F67FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000 +244D:00007FFE61B67DB661866FF661F67FFE7FFE6D8E6DB661B67DB67D8E7FFE0000 +244E:00007FFE61B67DB661866FF661F67FFE7FFE6D866DBE618E7DBE7D867FFE0000 +244F:00007FFE61B67DB661866FF661F67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000 +2450:00007FFE61B67DB661866FF661F67FFE7FFE61CE6FB661B67DB661CE7FFE0000 +2451:00007FFE61B67DB661866FF661F67FFE7FFE61EE6FCE61EE7DEE61C67FFE0000 +2452:00007FFE61B67DB661866FF661F67FFE7FFE61866FF661867DBE61867FFE0000 +2453:00007FFE61B67DB661866FF661F67FFE7FFE618E6FF661C67DF6618E7FFE0000 +2454:00007FFE61B67DB661866FF661F67FFE7FFE61B66FB661867DF661F67FFE0000 +2455:00007FFE61B67DB661866FF661F67FFE7FFE61866FBE61867DF661867FFE0000 +2456:00007FFE61B67DB661866FF661F67FFE7FFE61CE6FBE618E7DB661CE7FFE0000 +2457:00007FFE61B67DB661866FF661F67FFE7FFE61866FF661EE7DDE61DE7FFE0000 +2458:00007FFE61B67DB661866FF661F67FFE7FFE61CE6FB661CE7DB661CE7FFE0000 +2459:00007FFE61B67DB661866FF661F67FFE7FFE61CE6FB661C67DF661CE7FFE0000 +245A:00007FFE61B67DB661866FF661F67FFE7FFE61866FB661867DB661B67FFE0000 +245B:00007FFE61B67DB661866FF661F67FFE7FFE618E6FB6618E7DB6618E7FFE0000 +245C:00007FFE61B67DB661866FF661F67FFE7FFE61C66FBE61BE7DBE61C67FFE0000 +245D:00007FFE61B67DB661866FF661F67FFE7FFE618E6FB661B67DB6618E7FFE0000 +245E:00007FFE61B67DB661866FF661F67FFE7FFE61866FBE618E7DBE61867FFE0000 +245F:00007FFE61B67DB661866FF661F67FFE7FFE61866FBE618E7DBE61BE7FFE0000 +2460:07C0183020084104430485028102810281028102410447C42008183007C00000 +2461:07C0183020084384444484428042808281028202440447C42008183007C00000 +2462:07C0183020084384444484428042818280428442444443842008183007C00000 +2463:07C018302008408441848282848288828FC28082408440842008183007C00000 +2464:07C01830200847C4440484028402878280428042444443842008183007C00000 +2465:07C0183020084184420484028402878284428442444443842008183007C00000 +2466:07C01830200847C4404480428082808280828102410441042008183007C00000 +2467:07C0183020084384444484428442838284428442444443842008183007C00000 +2468:07C018302008438444448442844283C280428042408443042008183007C00000 +2469:07C018302008400444648C9294928492849284925F6440042008183007C00000 +246A:07C018302008400444448CC295428442844284425FF440042008183007C00000 +246B:07C018302008400444648C9294128422844284825FF440042008183007C00000 +246C:07C018302008400444648C9294128422841284925F6440042008183007C00000 +246D:07C018302008400444148C329452849284FA84125F1440042008183007C00000 +246E:07C018302008400444F48C82948284E2841284925F6440042008183007C00000 +246F:07C018302008400444748C82948284E2849284925F6440042008183007C00000 +2470:07C018302008400444F48C1294128422842284425F4440042008183007C00000 +2471:07C018302008400444648C9294928462849284925F6440042008183007C00000 +2472:07C018302008400444648C9294928472841284125F6440042008183007C00000 +2473:07C01830200840044C64929282928492889290925E6440042008183007C00000 +2474:00000000100820842184428240824082408240824082208423E4100800000000 +2475:00000000100823C424244422402240C2410242024402240427E4100800000000 +2476:00000000100823C424244422402241C2402240224422242423C4100800000000 +2477:000000001008204420C4414242424442444247E2404220442044100800000000 +2478:00000000100827E424044402440247C2402240224022242423C4100800000000 +2479:00000000100821C422044402440247C2442244224422242423C4100800000000 +247A:00000000100827E4202440224042404240424082408220842084100800000000 +247B:00000000100823C424244422442243C2442244224422242423C4100800000000 +247C:00000000100823C424244422442243E240224022402220442384100800000000 +247D:00000000400288319849A885888588858885888588858849BE31400200000000 +247E:00000000400288119831A851881188118811881188118811BE7D400200000000 +247F:00000000400288799885A885880588198821884188818881BEFD400200000000 +2480:00000000400288799885A885880588398805880588858885BE79400200000000 +2481:00000000400288099819A82988498889888988FD88098809BE09400200000000 +2482:00000000400288FD9881A881888188F98805880588058885BE79400200000000 +2483:00000000400288399841A881888188F98885888588858885BE79400200000000 +2484:00000000400289F99809A809881188118811882188218821BE21400200000000 +2485:00000000400288799885A885888588798885888588858885BE79400200000000 +2486:00000000400288799885A8858885887D8805880588058809BE71400200000000 +2487:0000000040029C31A249A2858285848588859085A085A049BE31400200000000 +2488:000000000000000001000300050001000100010001000100010007D000000000 +2489:00000000000000000780084008400040018002000400080008000FD000000000 +248A:0000000000000000078008400840004003800040004008400840079000000000 +248B:00000000000000000080018002800480088008800FC000800080009000000000 +248C:00000000000000000FC00800080008000F800040004000400840079000000000 +248D:000000000000000003800400080008000F800840084008400840079000000000 +248E:00000000000000000FC000400040008000800080010001000100011000000000 +248F:0000000000000000078008400840084007800840084008400840079000000000 +2490:0000000000000000078008400840084007C00040004000400080071000000000 +2491:00000000000000001060309051081108110811081108110810907C6200000000 +2492:00000000000000001020306050A01020102010201020102010207CFA00000000 +2493:000000000000000010F0310851081008103010401080110011007DFA00000000 +2494:000000000000000010F0310851081008107010081008110811087CF200000000 +2495:000000000000000010103030505010901110111011F8101010107C1200000000 +2496:000000000000000011F831005100110011F010081008100811087CF200000000 +2497:0000000000000000107030805100110011F011081108110811087CF200000000 +2498:000000000000000011F8300850081010101010101020102010207C2200000000 +2499:000000000000000010F031085108110810F011081108110811087CF200000000 +249A:000000000000000010F031085108110810F810081008100810107CE200000000 +249B:00000000000000003C304248428402840C8410842084408440487E3100000000 +249C:00000000000010082004200443C24422402243E244224422246423A410080000 +249D:00000000000014082404240445C246224422442244224422262425C410080000 +249E:00000000000010082004200443C244224402440244024402242423C410080000 +249F:00000000000010282024202443A244624422442244224422246423A410080000 +24A0:00000000000010082004200443C24422442247E244024402242423C410080000 +24A1:00000000000010C821042104410247C241024102410241022104210410080000 +24A2:00000000000010082004202443A24442444244424382420223C42424142803C0 +24A3:00000000000014082404240445C2462244224422442244222424242410080000 +24A4:000000000000111021082008430441044104410441044104210827C810100000 +24A5:00000000000010502048200840C4404440444044404440442048204814900300 +24A6:0000000000001408240424044442448245024602450244822444242410080000 +24A7:000000000000131021082108410441044104410441044104210827C810100000 +24A8:0000000000001004200220024761449144914491449144912492249210040000 +24A9:00000000000010082004200445C2462244224422442244222424242410080000 +24AA:00000000000010082004200443C244224422442244224422242423C410080000 +24AB:00000000000010082004200445C246224422442244224422262425C414080400 +24AC:00000000000010082004200443A244624422442244224422246423A410280020 +24AD:00000000000010082004200445C2462244224402440244022404240410080000 +24AE:00000000000010082004200443C244224402430240C24022242423C410080000 +24AF:00000000000010082104210447C241024102410241024102210420C410080000 +24B0:000000000000100820042004442244224422442244224422246423A410080000 +24B1:0000000000001008200420044422442244224242424242422184218410080000 +24B2:0000000000001004200220024411449144914491449144912492236210040000 +24B3:0000000000001008200420044422442242424182418242422424242410080000 +24B4:00000000000010082004200444224422442244224422426221A42024102803C0 +24B5:00000000000010082004200447E240224042408241024202240427E410080000 +24B6:07C0183020084104428482828442844287C28442444444442008183007C00000 +24B7:07C0183020084784444484428442878284428442444447842008183007C00000 +24B8:07C0183020084384444484428402840284028442444443842008183007C00000 +24B9:07C0183020084704448484428442844284428442448447042008183007C00000 +24BA:07C01830200847C4440484028402878284028402440447C42008183007C00000 +24BB:07C01830200847C4440484028402878284028402440444042008183007C00000 +24BC:07C018302008438444448442840285C28442844244C443442008183007C00000 +24BD:07C018302008444444448442844287C284428442444444442008183007C00000 +24BE:07C01830200847C4410481028102810281028102410447C42008183007C00000 +24BF:07C01830200843E4408480828082808280828482448443042008183007C00000 +24C0:07C0183020084444444484828502860285028482444444442008183007C00000 +24C1:07C0183020084404440484028402840284028402440447C42008183007C00000 +24C2:07C0183020084444444486C286C2854285428442444444442008183007C00000 +24C3:07C01830200840044444864286428542854284C244C444442008183007C00000 +24C4:07C0183020084384444484428442844284428442444443842008183007C00000 +24C5:07C0183020084784444484428442878284028402440444042008183007C00000 +24C6:07C018302008438444448442844284428442854246C443842068183007C00000 +24C7:07C0183020084784444484428442878285028482448444442008183007C00000 +24C8:07C0183020084384444484428402838280428442444443842008183007C00000 +24C9:07C0183020084FE4410481028102810281028102410441042008183007C00000 +24CA:07C0183020084444444484428442844284428442444443842008183007C00000 +24CB:07C0183020084824482484428442844282828282410441042008183007C00000 +24CC:07C0183020084444444484428542854286C286C2444444442008183007C00000 +24CD:07C0183020084444444482828282810282828282444444442008183007C00000 +24CE:07C0183020084824482484428442828281028102410441042008183007C00000 +24CF:07C01830200847C4404480428082810282028402440447C42008183007C00000 +24D0:07C018302008400443848442804283C2844284C2434440042008183007C00000 +24D1:07C0183024084404440485828642844284428442464445842008183007C00000 +24D2:07C0183020084004438484428402840284028442438440042008183007C00000 +24D3:07C01830204840444044834284C284428442844244C443442008183007C00000 +24D4:07C018302008400443848442844287C284028442438440042008183007C00000 +24D5:07C01830200840C441048102810287C281028102410441042108183007C00000 +24D6:07C0183020084044434484828482830282028382444444442388183007C00000 +24D7:07C0183024084404440485828642844284428442444444442008183007C00000 +24D8:07C0183021084104400483028102810281028102410447C42008183007C00000 +24D9:07C0183020484044400480C28042804280428042404444842308183007C00000 +24DA:07C0183020084404440484828502860286028502448444442008183007C00000 +24DB:07C0183020084304410481028102810281028102410447C42008183007C00000 +24DC:07C01830200840044EC489228922892289228922492440042008183007C00000 +24DD:07C0183020084004458486428442844284428442444440042008183007C00000 +24DE:07C0183020084004438484428442844284428442438440042008183007C00000 +24DF:07C0183020084004458486428442844284428642458444042408183007C00000 +24E0:07C0183020084004434484C2844284428442844244C443442048183007C00000 +24E1:07C0183020084004458486428442840284028402440440042008183007C00000 +24E2:07C0183020084004438484428402838280428442438440042008183007C00000 +24E3:07C0183020084104410487C28102810281028102410440C42008183007C00000 +24E4:07C01830200840044444844284428442844284C2434440042008183007C00000 +24E5:07C0183020084004444484428282828282828102410440042008183007C00000 +24E6:07C018302008400448248922892289228922892246C440042008183007C00000 +24E7:07C0183020084004444484428282810282828442444440042008183007C00000 +24E8:07C0183020084004444484428442844282C28142404440442388183007C00000 +24E9:07C018302008400447C48042808281028202840247C440042008183007C00000 +24EA:07C0183020084104428484428442844284428442428441042008183007C00000 +24EB:07C01FF03FF87FFC7BBCF33EEABEFBBEFBBEFBBE600C7FFC3FF81FF007C00000 +24EC:07C01FF03FF87FFC7B9CF36EEBEEFBDEFBBEFB7E600C7FFC3FF81FF007C00000 +24ED:07C01FF03FF87FFC7B9CF36EEBEEFBDEFBEEFB6E609C7FFC3FF81FF007C00000 +24EE:07C01FF03FF87FFC7BECF3CEEBAEFB6EFB06FBEE60EC7FFC3FF81FF007C00000 +24EF:07C01FF03FF87FFC7B0CF37EEB7EFB1EFBEEFB6E609C7FFC3FF81FF007C00000 +24F0:000007C01FF03FF83B88737C6B7C7B1C7B6C7B6C20983FF81FF007C000000000 +24F1:000007C01FF03FF83B0873EC6BEC7BDC7BDC7BBC20B83FF81FF007C000000000 +24F2:000007C01FF03FF83B98736C6B6C7B9C7B6C7B6C20983FF81FF007C000000000 +24F3:07C01FF03FF87FFC7B9CF36EEB6EFB8EFBEEFBEE609C7FFC3FF81FF007C00000 +24F4:07C01FF03FF87FFC739CED6EFD6EFB6EF76EEF6E619C7FFC3FF81FF007C00000 +24F5:07E0181823C44C32500A9089A185A085A08591C9500A4C3223C4181807E00000 +24F6:07E0181823C44C32500A9189A045A085A10591C9500A4C3223C4181807E00000 +24F7:07E0181823C44C32500A9189A045A185A0459189500A4C3223C4181807E00000 +24F8:07E0181823C44C32500A9289A285A3C5A0859089500A4C3223C4181807E00000 +24F9:07E0181823C44C32500A91C9A105A185A0459189500A4C3223C4181807E00000 +24FA:07E0181823C44C32500A9189A205A385A2459189500A4C3223C4181807E00000 +24FB:07E0181823C44C32500A91C9A045A045A0859089500A4C3223C4181807E00000 +24FC:07E0181823C44C32500A9189A245A185A2459189500A4C3223C4181807E00000 +24FD:07E0181823C44C32500A9189A245A1C5A0459189500A4C3223C4181807E00000 +24FE:07E0181823C44C32500A9269A695A295A2959769500A4C3223C4181807E00000 +24FF:07C01FF03FF87EFC7D7CFBBEFBBEFBBEFBBEFBBE7D7C7EFC3FF81FF007C00000 +2500:00000000000000FF0000000000000000 +2501:00000000000000FFFF00000000000000 +2502:08080808080808080808080808080808 +2503:18181818181818181818181818181818 +2504:00000000000000DB0000000000000000 +2505:00000000000000DBDB00000000000000 +2506:08080808000008080808000008080808 +2507:18181818000018181818000018181818 +2508:00000000000000AA0000000000000000 +2509:00000000000000AAAA00000000000000 +250A:08080800080808000808080008080800 +250B:18181800181818001818180018181800 +250C:000000000000000F0808080808080808 +250D:000000000000000F0F08080808080808 +250E:000000000000001F1818181818181818 +250F:000000000000001F1F18181818181818 +2510:00000000000000F80808080808080808 +2511:00000000000000F8F808080808080808 +2512:00000000000000F81818181818181818 +2513:00000000000000F8F818181818181818 +2514:080808080808080F0000000000000000 +2515:080808080808080F0F00000000000000 +2516:181818181818181F0000000000000000 +2517:181818181818181F1F00000000000000 +2518:08080808080808F80000000000000000 +2519:08080808080808F8F800000000000000 +251A:18181818181818F80000000000000000 +251B:18181818181818F8F800000000000000 +251C:080808080808080F0808080808080808 +251D:080808080808080F0F08080808080808 +251E:181818181818181F0808080808080808 +251F:080808080808081F1818181818181818 +2520:181818181818181F1818181818181818 +2521:181818181818181F1F08080808080808 +2522:080808080808081F1F18181818181818 +2523:181818181818181F1F18181818181818 +2524:08080808080808F80808080808080808 +2525:08080808080808F8F808080808080808 +2526:18181818181818F80808080808080808 +2527:08080808080808F81818181818181818 +2528:18181818181818F81818181818181818 +2529:18181818181818F8F808080808080808 +252A:08080808080808F8F818181818181818 +252B:18181818181818F8F818181818181818 +252C:00000000000000FF0808080808080808 +252D:00000000000000FFF808080808080808 +252E:00000000000000FF0F08080808080808 +252F:00000000000000FFFF08080808080808 +2530:00000000000000FF1818181818181818 +2531:00000000000000FFF818181818181818 +2532:00000000000000FF1F18181818181818 +2533:00000000000000FFFF18181818181818 +2534:08080808080808FF0000000000000000 +2535:08080808080808FFF800000000000000 +2536:08080808080808FF0F00000000000000 +2537:08080808080808FFFF00000000000000 +2538:18181818181818FF0000000000000000 +2539:18181818181818FFF800000000000000 +253A:18181818181818FF1F00000000000000 +253B:18181818181818FFFF00000000000000 +253C:08080808080808FF0808080808080808 +253D:08080808080808FFF808080808080808 +253E:08080808080808FF0F08080808080808 +253F:08080808080808FFFF08080808080808 +2540:18181818181818FF0808080808080808 +2541:08080808080808FF1818181818181818 +2542:18181818181818FF1818181818181818 +2543:18181818181818FFF808080808080808 +2544:18181818181818FF1F08080808080808 +2545:08080808080808FFF818181818181818 +2546:08080808080808FF1F18181818181818 +2547:18181818181818FFFF08080808080808 +2548:08080808080808FFFF18181818181818 +2549:18181818181818FFF818181818181818 +254A:18181818181818FF1F18181818181818 +254B:18181818181818FFFF18181818181818 +254C:00000000000000EE0000000000000000 +254D:00000000000000EEEE00000000000000 +254E:08080808080800000808080808080000 +254F:18181818181800001818181818180000 +2550:000000000000FF00FF00000000000000 +2551:14141414141414141414141414141414 +2552:0000000000000F080F08080808080808 +2553:000000000000001F1414141414141414 +2554:0000000000001F101714141414141414 +2555:000000000000F808F808080808080808 +2556:00000000000000FC1414141414141414 +2557:000000000000FC04F414141414141414 +2558:0808080808080F080F00000000000000 +2559:141414141414141F0000000000000000 +255A:14141414141417101F00000000000000 +255B:080808080808F808F800000000000000 +255C:14141414141414FC0000000000000000 +255D:141414141414F404FC00000000000000 +255E:0808080808080F080F08080808080808 +255F:14141414141414171414141414141414 +2560:14141414141417101714141414141414 +2561:080808080808F808F808080808080808 +2562:14141414141414F41414141414141414 +2563:141414141414F404F414141414141414 +2564:000000000000FF00FF08080808080808 +2565:00000000000000FF1414141414141414 +2566:000000000000FF00F714141414141414 +2567:080808080808FF00FF00000000000000 +2568:14141414141414FF0000000000000000 +2569:141414141414F700FF00000000000000 +256A:080808080808FF08FF08080808080808 +256B:14141414141414FF1414141414141414 +256C:141414141414F700F714141414141414 +256D:00000000000000030408080808080808 +256E:00000000000000E01008080808080808 +256F:08080808080810E00000000000000000 +2570:08080808080804030000000000000000 +2571:01010202040408081010202040408080 +2572:80804040202010100808040402020101 +2573:81814242242418181818242442428181 +2574:00000000000000F00000000000000000 +2575:08080808080808080000000000000000 +2576:000000000000000F0000000000000000 +2577:00000000000000000808080808080808 +2578:00000000000000F0F000000000000000 +2579:18181818181818180000000000000000 +257A:000000000000000F0F00000000000000 +257B:00000000000000001818181818181818 +257C:00000000000000FF0F00000000000000 +257D:08080808080808081818181818181818 +257E:00000000000000FFF000000000000000 +257F:18181818181818180808080808080808 +2580:FFFFFFFFFFFFFFFF0000000000000000 +2581:0000000000000000000000000000FFFF +2582:000000000000000000000000FFFFFFFF +2583:00000000000000000000FFFFFFFFFFFF +2584:0000000000000000FFFFFFFFFFFFFFFF +2585:000000000000FFFFFFFFFFFFFFFFFFFF +2586:00000000FFFFFFFFFFFFFFFFFFFFFFFF +2587:0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +2588:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +2589:FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE +258A:FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC +258B:F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 +258C:F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 +258D:E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0 +258E:C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0 +258F:80808080808080808080808080808080 +2590:0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +2591:88228822882288228822882288228822 +2592:AA55AA55AA55AA55AA55AA55AA55AA55 +2593:EEBBEEBBEEBBEEBBEEBBEEBBEEBBEEBB +2594:FFFF0000000000000000000000000000 +2595:01010101010101010101010101010101 +2596:0000000000000000F0F0F0F0F0F0F0F0 +2597:00000000000000000F0F0F0F0F0F0F0F +2598:F0F0F0F0F0F0F0F00000000000000000 +2599:F0F0F0F0F0F0F0F0FFFFFFFFFFFFFFFF +259A:F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0F +259B:FFFFFFFFFFFFFFFFF0F0F0F0F0F0F0F0 +259C:FFFFFFFFFFFFFFFF0F0F0F0F0F0F0F0F +259D:0F0F0F0F0F0F0F0F0000000000000000 +259E:0F0F0F0F0F0F0F0FF0F0F0F0F0F0F0F0 +259F:0F0F0F0F0F0F0F0FFFFFFFFFFFFFFFFF +25A0:000000000000007F7F7F7F7F7F7F0000 +25A1:0000000000007F41414141417F000000 +25A2:0000000000003E41414141413E000000 +25A3:0000000000007F415D5D5D417F000000 +25A4:0000000000007F417F417F417F000000 +25A5:0000000000007F55555555557F000000 +25A6:0000000000007F557F557F557F000000 +25A7:0000000000007F53496553497F000000 +25A8:0000000000007F65495365497F000000 +25A9:0000000000007F556B556B557F000000 +25AA:00000000000000003C3C3C3C00000000 +25AB:0000000000003C24243C000000000000 +25AC:0000000000007F7F7F7F000000000000 +25AD:0000000000007F41417F000000000000 +25AE:00000000003C3C3C3C3C3C3C00000000 +25AF:00000000003C24242424243C00000000 +25B0:000000000000003F7EFC000000000000 +25B1:000000000000003F42FC000000000000 +25B2:000000000018183C3C7E7E0000000000 +25B3:000000000018182424427E0000000000 +25B4:0000000000000000183C7E0000000000 +25B5:000000000000000018247E0000000000 +25B6:00000000000060787E7E786000000000 +25B7:00000000000060584646586000000000 +25B8:00000000000000303C3C300000000000 +25B9:00000000000000302C2C300000000000 +25BA:0000000000000060787E786000000000 +25BB:00000000000000605846586000000000 +25BC:00000000007E7E3C3C18180000000000 +25BD:00000000007E42242418180000000000 +25BE:00000000000000007E3C180000000000 +25BF:00000000000000007E24180000000000 +25C0:000000000000061E7E7E1E0600000000 +25C1:000000000000061A62621A0600000000 +25C2:000000000000000C3C3C0C0000000000 +25C3:000000000000000C34340C0000000000 +25C4:00000000000000061E7E1E0600000000 +25C5:00000000000000061A621A0600000000 +25C6:0000000000081C3E7F3E1C0800000000 +25C7:00000000000814224122140800000000 +25C8:000000000008142A5D2A140800000000 +25C9:00000000001C22595D4D221C00000000 +25CA:00000018182424424224241818000000 +25CB:00000000001C22414141221C00000000 +25CC:00000000001400410041001400000000 +25CD:00000000001C36555555361C00000000 +25CE:00000000001C22495549221C00000000 +25CF:00000000001C3E7F7F7F3E1C00000000 +25D0:00000000001C32717171321C00000000 +25D1:00000000001C26474747261C00000000 +25D2:00000000001C2241417F3E1C00000000 +25D3:00000000001C3E7F4141221C00000000 +25D4:00000000001C2E4F4F41221C00000000 +25D5:00000000001C2647477F3E1C00000000 +25D6:00000000001838787878381800000000 +25D7:00000000000C0E0F0F0F0E0C00000000 +25D8:FFFFFFFFFFFFE7C3C3E7FFFFFFFFFFFF +25D9:FFFFFFFFFFE7DBBDBDDBE7FFFFFFFFFF +25DA:FFFFFFFFFFE7DBBD0000000000000000 +25DB:0000000000000000BDDBE7FFFFFFFFFF +25DC:00000000001820404000000000000000 +25DD:00000000000C02010100000000000000 +25DE:00000000000000000101020C00000000 +25DF:00000000000000004040201800000000 +25E0:00000000001C22414100000000000000 +25E1:00000000000000004141221C00000000 +25E2:0101030307070F0F1F1F3F3F7F7FFFFF +25E3:8080C0C0E0E0F0F0F8F8FCFCFEFEFFFF +25E4:FFFFFEFEFCFCF8F8F0F0E0E0C0C08080 +25E5:FFFF7F7F3F3F1F1F0F0F070703030101 +25E6:00000000000000384444443800000000 +25E7:00000000007E727272727E0000000000 +25E8:00000000007E4E4E4E4E7E0000000000 +25E9:00000000007E7A7262427E0000000000 +25EA:00000000007E42464E5E7E0000000000 +25EB:00000000007F494949497F0000000000 +25EC:0000000000081414222A417F00000000 +25ED:00000000000018183434727E00000000 +25EE:000000000018182C2C4E4E7E00000000 +25EF:0000000001C00630080810041004200220022002100410040808063001C00000 +25F0:00000000000000007E527242427E0000 +25F1:00000000000000007E424272527E0000 +25F2:00000000000000007E42424E4A7E0000 +25F3:00000000000000007E4A4E42427E0000 +25F4:0000000000003C5291F18181423C0000 +25F5:0000000000003C428181F191523C0000 +25F6:0000000000003C4281818F894A3C0000 +25F7:0000000000003C4A898F8181423C0000 +25F8:00007E44485060400000000000000000 +25F9:00007E22120A06020000000000000000 +25FA:00000000000000000040605048447E00 +25FB:0000000000000000007E424242427E00 +25FC:00000000000000007E7E7E7E7E7E0000 +25FD:000000000000000000003C24243C0000 +25FE:00000000000000007C7C7C7C7C000000 +25FF:00000000000000000002060A12227E00 +2600:0000084922001C3E3E1C002249080000 +2601:000000002076FF7E0000000000000000 +2602:000000001C3E7F080808081000000000 +2603:8BC803C02FF104248A5028120A504994042147E008101088781E1088081007E0 +2604:00000022222424282902304848300000 +2605:000000000008087F1C36220000000000 +2606:00000000080877222A36220000000000 +2607:00000000000204081020100A060E0000 +2608:0000000000007E424448504A464E0000 +2609:0000000000003C4281999981423C0000 +260A:00000000000018242466A54200000000 +260B:00000000000042A56624241800000000 +260C:00000000000004083048483000000000 +260D:00000000000609090608304848300000 +260E:000000000000003E63002A637F000000 +260F:0000000000003E415D3E49417F000000 +2610:000000003FF820082008200820082008200820082008200820083FF800000000 +2611:000000003FF8200820082038286828C829882B082E082C0820083FF800000000 +2612:000000003FFC200420042C34266423C4218423C426642C3420043FFC00000000 +2613:00000000222214140808141422220000 +2614:055004411C3E7F080808081000000000 +2615:000009201240124009200920124000001FC83FF42FD4201420381FC000000000 +2616:00000100028004400820101020082008200820082008200820083FF800000000 +2617:00000100038007C00FE01FF03FF83FF83FF83FF83FF83FF83FF83FF800000000 +2618:00000000028007C007C03398793C3FF8793C3118020002000200040008000000 +2619:00000000000401C823E847E84FE87FD83FDC0FE407E403E401C4000800000000 +261A:00000000000000007E1F1F0E00000000 +261B:00000000000000003F7C7C3800000000 +261C:00000000000000007E11190E00000000 +261D:000000000004041C3424241800000000 +261E:00000000000000003F444C3800000000 +261F:00000000000000182424341C04040000 +2620:0000E7A57E81A5A5815A5A42BDE70000 +2621:000000003804040808101020201C0000 +2622:07E0181824245C3A5C3ABE7DBE7DBE7D8181818183C143C247E223C4181807E0 +2623:00000000044008201010101013900C603EF84444854283820280044018300000 +2624:0000030001007FFC23881FF001000D6011100FE0092007C00540038005400100 +2625:0000000000001C2214083E0808080000 +2626:0000000000103810FE1010701C100000 +2627:000000001C12121C1054381038540000 +2628:0000000000103810FE10101010100000 +2629:000000000000001C08497F49081C0000 +262A:000000001E2140C2C7C240211E000000 +262B:000000000000054006C0000015502928292829282548139007C0010000000000 +262C:000000000000008002A0049009C81AAC1AAC19CC1C9C1BEC11C402A000800000 +262D:0000000000000C0239790D3E63C10000 +262E:0000000000003E4949495D6B493E0000 +262F:07E018182004400240029C31BE31FF03E783E7C7FFFF7FFE7FFE3FFC1FF807E0 +2630:00000000000000007FFC7FFC000000007FFC7FFC000000007FFC7FFC00000000 +2631:00000000000000007C7C7C7C000000007FFC7FFC000000007FFC7FFC00000000 +2632:00000000000000007FFC7FFC000000007C7C7C7C000000007FFC7FFC00000000 +2633:00000000000000007C7C7C7C000000007C7C7C7C000000007FFC7FFC00000000 +2634:00000000000000007FFC7FFC000000007FFC7FFC000000007C7C7C7C00000000 +2635:00000000000000007C7C7C7C000000007FFC7FFC000000007C7C7C7C00000000 +2636:00000000000000007FFC7FFC000000007C7C7C7C000000007C7C7C7C00000000 +2637:00000000000000007C7C7C7C000000007C7C7C7C000000007C7C7C7C00000000 +2638:00000000000000493E3E773E3E490000 +2639:0000003C4281A58199A581423C000000 +263A:000000003C4281A581A599423C000000 +263B:000000003C7EFFDBFFDBE77E3C000000 +263C:0000000000492A1C771C2A4900000000 +263D:00000000380C0605050505060C380000 +263E:000000000E18305050505030180E0000 +263F:00000022221C2222221C083E08080000 +2640:00000000001C2222221C083E08080000 +2641:00000008083E08081C2222221C000000 +2642:00000000000703053844444438000000 +2643:000000000202023A46060A7E02020000 +2644:00000000202070202C32222424240000 +2645:00000000006B2A3E2A6B081C141C0000 +2646:000000000859CB4949493E083E080800 +2647:000000007C4242427C404040407E0000 +2648:00000000225514140808080808080000 +2649:0000000000000041221C2222221C0000 +264A:00000000413E1414141414143E410000 +264B:0000000000003E4948300609493E0000 +264C:00000000001C22221274949465020000 +264D:00000000547C555755555555067C0000 +264E:000000000000001C222277007F000000 +264F:00000000547C54545454545455030000 +2650:000000000000000F0345291028440000 +2651:00000000314E8408103C62A2A21C0000 +2652:0000000000002A5400002A5400000000 +2653:0000000000424224247E242442420000 +2654:000000081C08775D49492A7F417F0000 +2655:000000000808492A2A5D2A3E223E0000 +2656:0000000000557F4141222241417F0000 +2657:000000000814222222221477417F0000 +2658:000000021E2242423A122242427E0000 +2659:000000000000182424182424427E0000 +265A:000000081C08775D49492A7F7F7F0000 +265B:000000000808492A2A5D2A3E3E3E0000 +265C:0000000000557F7F7F3E3E7F7F7F0000 +265D:00000000081C3622363E1C7F7F7F0000 +265E:000000021E367E7E3E1E3E7E7E7E0000 +265F:000000000000183C3C183C3C7E7E0000 +2660:0000000008081C3E7F7F7F3E081C0000 +2661:00000000003649414141221408080000 +2662:00000000080814142222141408080000 +2663:000000001C1C1C087F7F6B08081C0000 +2664:00000000080814224141413E081C0000 +2665:0000000000367F7F7F7F3E1C08080000 +2666:0000000008081C1C3E3E1C1C08080000 +2667:000000001C141C08775D6B08081C0000 +2668:000000085192929249494952817E0000 +2669:00000000080808080808083878700000 +266A:00000000080C0A0A0808083878700000 +266B:0000001C171111111171F1E70F0E0000 +266C:0000001C17111D171171F1E70F0E0000 +266D:000040404040405C6646444850600000 +266E:00000040404E7E72424E7E7202020000 +266F:00000424263E7C6424263E7C64242000 +2670:00000000140808493E49080808140000 +2671:000000001C14086B5D6B080814080000 +2672:03C005200A9812480AD004303004480A8C115009A005AE26525852861E5C0020 +2673:0380044004400820002839181B382900210843844004802280427EFC00400020 +2674:038004400440082000283B1818B82900220843844004802280427EFC00400020 +2675:038004400440082000283B1818B82B00208843044004802280427EFC00400020 +2676:038004400440082000283A981AB82B80208840844004802280427EFC00400020 +2677:038004400440082000283B981A382B00208843044004802280427EFC00400020 +2678:0380044004400820002839981A382B80224841844004802280427EFC00400020 +2679:038004400440082000283B9818B82900210841044004802280427EFC00400020 +267A:03800440044008200028381818382800200840044004802280427EFC00400020 +267B:03C005E00EF81E780EF004303004780EFC1F700FE007EE265E785EFE1E7C0020 +267C:07E01FF83E7C7DBE7BDEFF8FF7DFE7FFF3EFF7EFEFF76FB6710E3FBC1FF807E0 +267D:07E018182184424244228071882198018C1188119009504A4EF22044181807E0 +267E:00000000000003800C601010200826C84924492426C8200810100C6003800000 +267F:0000000000000600060004000780040017E0202020102050108C0F0000000000 +2680:00000000000000001FF010101010101011101010101010101FF0000000000000 +2681:00000000000000001FF010101010141010101050101010101FF0000000000000 +2682:00000000000000001FF010101410101011101010105010101FF0000000000000 +2683:00000000000000001FF010101450101010101010145010101FF0000000000000 +2684:00000000000000001FF010101450101011101010145010101FF0000000000000 +2685:00000000000000001FF010101450101014501010145010101FF0000000000000 +2686:00000000000003C0042008101008200420642064200410080810042003C00000 +2687:00000000000003C0042008101008200426642664200410080810042003C00000 +2688:00000000000003C007E00FF01FF83FFC3F9C3F9C3FFC1FF80FF007E003C00000 +2689:00000000000003C007E00FF01FF83FFC399C399C3FFC1FF80FF007E003C00000 +268A:000000000000000000000000000000007FFC7FFC000000000000000000000000 +268B:000000000000000000000000000000007C7C7C7C000000000000000000000000 +268C:0000000000000000000000007FFC7FFC000000007FFC7FFC0000000000000000 +268D:0000000000000000000000007C7C7C7C000000007FFC7FFC0000000000000000 +268E:0000000000000000000000007FFC7FFC000000007C7C7C7C0000000000000000 +268F:0000000000000000000000007C7C7C7C000000007C7C7C7C0000000000000000 +2690:000000704E4242724E40404040400000 +2691:000000707E7E7E7E4E40404040400000 +2692:000008325C7C3E7E7C1FF8277443228101000280044008201010200840040000 +2693:000000000380044004400380010007C001002108711C210811100FE000000000 +2694:0000400420081010082004400280010002800440282810102828400400000000 +2695:0000010001000FF0113011000FC00120012007C0090007800140038001000000 +2696:000000000000010011107FFC39385454545492929292FEFE7C7C383800000000 +2697:000000000000000003E007F00BF80BF811F010E0100001F00248044400000000 +2698:0000000003800440044004400380010039383D781D700D600380010001000000 +2699:000000000100210817D0082010101010711C10101010082017D0210801000000 +269A:00000100028039387FFCFD7E0540038001000100010001000100010000000000 +269B:018002400240742E8E7185A14E7235AC35AC4E7285A18E71742E024002400180 +269C:01000280044034584C648442B29ACAA61AB010101BB00AA03AB826C819300100 +269D:010002800440044008006BFC8802882260241810065000882108264818300000 +269E:30000C00030000C00030000C00003FFC0000000C003000C003000C0030000000 +269F:000C003000C003000C00300000003FFC000030000C00030000C00030000C0000 +26A0:000001000280028004400440092009201110111021082008410440047FFC0000 +26A1:0000000002040810207E040810204000 +26A2:000000000000000000000EE011102288228811100EE004400EE0044000000000 +26A3:00000000000001C000C001400E38111823A825401A200C200440038000000000 +26A4:000000380018002801C0022007100A90116010C0088007000200070002000000 +26A5:0000000000000000007000300050038004400820082004400380010003800100 +26A6:00000000000000000038001800A800400EA011002080208011000E0000000000 +26A7:000000000000E00EC006A80A10102BA004400820082004400380010003800100 +26A8:00001038541038103844828244380000 +26A9:000000000000000000000000000000001C002208414441FE414422081C000000 +26AA:00000000000000003844828282443800 +26AB:0000000000000000387CFEFEFE7C3800 +26AC:0000000000000000001C2222221C0000 +26AD:000000000000000000000000000000000EE011102288228811100EE000000000 +26AE:0000000000000000000000000000000000800EB811C411C411C40EB800800000 +26AF:0000000000000000000000000000000000003838444447C44444383800000000 +26B0:000000000C0013C0203E4002400240024002603E53C22E3E1BC00C0000000000 +26B1:000007C002800FE010102008200810101010101008200820082007C000000000 +26B2:00000000001C2222221C080808080000 +26B3:0000000000384402020418107C100000 +26B4:0000000010284482442810107C100000 +26B5:00000000925438FE385492107C100000 +26B6:0000000000000100010001000100393804400280793C04400280010000000000 +26B7:00000012141814121038444444380000 +26B8:000000001C38707070381C083E080000 +26B9:000000000000422418FF182442000000 +26BA:00000000000044444428282810FE0000 +26BB:000000000000FE102828284444440000 +26BC:0000000000007E4242424A7E207E0000 +26BD:0000000001C007300F38173C100421C223E239CE1C1C180C09C807F001C00000 +26BE:0000000001C006300C1812241004214220022142100412240C18063001C00000 +26BF:000000007FFC4004438444444444438441044104410441C4410440047FFC0000 +26C0:0000000000000000000007E0181821842184381C2FF42A541A5807E000000000 +26C1:0000000007E0181821842184381C2FF42A543A5C2FF42A541A5807E000000000 +26C2:00000000000000000FF0381C67E65E7A5E7A47E2500A55AA65A6381C0FF00000 +26C3:00000FF0381C67E65E7A5E7A47E2500A55AA45A2500A55AA65A6381C0FF00000 +26C4:03C003C00FF004200A5008100A500990042007E008101088781E1088081007E0 +26C5:00000000000001200148001000C0072C09A010602010201010600F8000000000 +26C6:0000222244440088100022224444008810002222444400801012222444480000 +26C7:8BC803C02FF107E48DB02FF20DB04E7407E147E00FF01F787FFE1F780FF007E0 +26C8:0000072008CC10B22102208211040A1807E02000444000801010222044400000 +26C9:00003FF820082008200820082008200820081010082004400280010000000000 +26CA:00003FF83FF83FF83FF83FF83FF83FF83FF83FF81FF00FE00380010000000000 +26CB:0000000000007FF04510489050506030401060305050489045107FF000000000 +26CC:0000000000000000202010400880040002000100088010402020000000000000 +26CD:00003C00420042008100FF00FF00FF0042004200004000A00110020804040FFE +26CE:000000000000000000000440044004501E48254824F014400440066000000000 +26CF:000040C027001C001C003E003300218040C0406000300018000C000600000000 +26D0:000000E0031005C803F804E8003000401C00218022001AC002203C2000000000 +26D1:0000000007001DC038E07DF0FFF84010401040102020202018C0070000000000 +26D2:00000000070018C020205050489081088208840848905050202018C007000000 +26D3:000022102A381C5408441C442A54223822102A381C5408441C442A5422380010 +26D4:00000000000007001FC03FE07FF07FF0C018C0187FF07FF03FE01FC007000000 +26D5:000000000C301E302D300C3008E00BC00A000BC008E00C300CB40C780C300000 +26D6:00000000018003C007E00BD011D82ADC7BDE3B541B880FD007E003C001800000 +26D7:0000018002400420081014282E245522842144AA247410280810042002400180 +26D8:0000000007FC07FC07FC0FFC1FFC3FFC3FFC3FFC3FFC3FFC3FFC3FFC00000000 +26D9:00000000180619061906190630066106C106C106C006C106C106C10600000000 +26DA:00000000781E781E700E600600000000000000006006700E781E781E00000000 +26DB:00000000000000001FF018300C600C6006C007C0038003800100010000000000 +26DC:00000000180318431843184330036043C043C043C403C443C443C44300000000 +26DD:0000000000003FF83018282824482288210822882448282830183FF800000000 +26DE:00000000FDF8F8F8E038D018C818840802008108C098C058E038F8F8FDF80000 +26DF:000000007FF07FF07FFC7FF27FF27FFE7FFE7FFE6FF657EA381C100800000000 +26E0:00007FFE3E021C42084200020042004200020042004200020042004200020000 +26E1:0000400060007000780070006000400040804040422046104E085E047FFE0000 +26E2:00000010387C10107C82BABA827C0000 +26E3:00000100193019300100010003800C60082010101010101008200C6003800000 +26E4:0000010001000280028002807FFC244814500C600AA0092016D0183020080000 +26E5:0000010001000280028000807F5C2048141008600A00092014D0183020080000 +26E6:00000100010002800280020075FC240810500C2000A009201650183020080000 +26E7:00002008183016D009200AA00C60145024487FFC028002800280010001000000 +26E8:0000000000003FF02010231023102FD02FD023102310201030300CC003000000 +26E9:00000000FFFE1010101010101FF0101010101010101010101010101000000000 +26EA:0100010007C001000100038007C01FF07C7C3838339837D837D837D800000000 +26EB:0000000000000F80088078F04010401040104010401040104010401000000000 +26EC:000000000000000000000180018000000000000000000C300C30000000000000 +26ED:000000000000010011100BA0044008203838082004400BA01110010000000000 +26EE:000000000000010011100BA004440824783C482044400BA01110010000000000 +26EF:000000000000010011100BA004400BA03BB80BA004400BA01110010000000000 +26F0:00000000000000000100028004600410081813F83FFC3FFC7FFE7FFE00000000 +26F1:000007E01818282447E2791E41020200020002000400040004007FFE7FFE0000 +26F2:00001450228842844004438447C407C000007FFC3FF80FE00FE01FF03FF80000 +26F3:0000018001E001F8010001000100010001003D787D7CFC7E7EFC3FF807C00000 +26F4:0000000003000300030007E00A5012482248FFFC3FF81FF80FF0000000000000 +26F5:000001000180014005400D20152025104510FDF80100FFFC3FF81FF80FF00000 +26F6:0000381C400240024002000000000000000000000000400240024002381C0000 +26F7:0000000038003800380006000E207FF01C201C0C0E300FC003001C0000000000 +26F8:0000000000000000000000F000F000F000F01FF03FF03FE008403FF800000000 +26F9:0000038003800380000003FC07800B80138C238C038006C006C00C600C60783C +26FA:0000060005000E800E400E201F101F081F043F823F84318871C871D071E00000 +26FB:0000000007C01830200830180820044004400440082030182008183007C00000 +26FC:00000000010001000100010007C00000000010101010101010107C7C00000000 +26FD:000000000F801FD8104410421FF21FCA1FCA1FCA1FCA1FC41FC07FF000000000 +26FE:00007FFE7FFE7006701A701A701A7006780E7C1E4FF247E26006781E7FFE0000 +26FF:000000007FFC400440047FFC7FFC400440047FFC400040004000400040000000 +2700:0000000038047C1E6C3C7F783FF003E03FF07F786C3C7C1E3804000000000000 +2701:000038007C006C007C003C000E007FFCFFFED9C0F8E070000000000000000000 +2702:0000000038067C1C6C387F703FE003C03FE07F706C387C1C3806000000000000 +2703:00000000000000007000F8E0D9C0FFFE7FFC0E003C007C006C007C0038000000 +2704:00000000700C8832AE4481887910062078508188AE448832700C000000000000 +2705:00000000000000000004000A001200242048509051202A40248011000E000000 +2706:07C01830200841C447E48FF28F729E629C029F024F0446042008183007C00000 +2707:07C01930238843844104838287C287C287C28BA25C7458342008183007C00000 +2708:000008000F00060007C0C380E3C07FFE7FFEE3C0C38007C006000F0008000000 +2709:00000000000000007FFE6006500A499247E247E24992500A60067FFE00000000 +270A:000000000000000003600C90149035F8550454E454C43704280810100FE00000 +270B:00000A801540154035405540554C5552402240044008201010100FE000000000 +270C:18302448228812901110092008207CFC92829272922292427C0420081FF00000 +270D:00000008001C003803F70CF511CD238547056FE512052FFD7005600700000000 +270E:000000001800260055004A80714028A014500A28052802C8011800F800000000 +270F:00000000000000003FF050288FF4A8168FF450283FF000000000000000000000 +2710:0000000000F8011802C805280A28145028A071404A8055002600180000000000 +2711:000000000000000000F07908866C80FE866C790800F000000000000000000000 +2712:000000000000000000E079F0FF38FF0EFF3879F000E000000000000000000000 +2713:0000000000000000000000040008001040204040208021001200140008000000 +2714:00000000000000000004000E401CE038E07070E071C03B803F001E000C000000 +2715:00000000101038381C700EE007C0038007C00EE01C7038381010000000000000 +2716:101038387C7CFEFE7FFC3FF81FF00FE01FF03FF87FFCFEFE7C7C383810100000 +2717:00006018306031C01B000E000E001B00198030C0306060306018200000000000 +2718:00006018707031E03B801F000E001F001B8039C030E070706038601020000000 +2719:07C00440054005400540FD7E8102BFFA8102FD7E054005400540044007C00000 +271A:07C007C007C007C007C0FFFEFFFEFFFEFFFEFFFE07C007C007C007C007C00000 +271B:038003800380038003800380FC7EFC7EFC7E0380038003800380038003800000 +271C:07C007C007C007C007C0F83EF83EF83EF83EF83E07C007C007C007C007C00000 +271D:000000000380038003801FF01FF01FF003800380038003800380000000000000 +271E:078004C004C004C07CF8400C400C7CFC3CFC04C004C004C004C007C003C00000 +271F:00000FE008207BBC43845FF45FF45FF443847BBC0BA00BA00BA008200FE00000 +2720:00000FF803E021C221C231C63FFE3FFE3FFE31C621C221C203E00FF800000000 +2721:000000000100028004407FFC244818300820183024487FFC0440028001000000 +2722:038007C007C003800380610CF93EFFFEF93E610C0380038007C007C003800000 +2723:038007C007C007C00380711CF93EFFFEF93E711C038007C007C007C003800000 +2724:07C00FE00FE007C0638CF39EFFFEFFFEFFFEF39E638C07C00FE00FE007C00000 +2725:0100038007C007C00100310C710EFFFF710E310C010007C007C0038001000000 +2726:01000380038007C007C01FF07FFCFFFE7FFC1FF007C007C00380038001000000 +2727:010002800280044004401830600C8002600C1830044004400280028001000000 +2728:0000040004000A00110060C011100A10042804C6002800100110028001000000 +2729:0000010002800280FC7E4004383808201010111026C828283018000000000000 +272A:07C01FF03EF87EFC7C7CC006F01EF83EF01EF11E67CC6FEC3FF81FF007C00000 +272B:0000010003800380FFFE7C7C383808201C701FF03EF838383018000000000000 +272C:0000010002800280FC7E438427C817D01390101027C828283018000000000000 +272D:0000010002801C70E10E4FE4238817D01450111022882C683018000000000000 +272E:0000010002801D70E38E5FF42FE817D016D0155022882C683018000000000000 +272F:00000100038005C0F9FE5D8C27B813F00FD01D9019D032E82C78301800000000 +2730:00000100028002C0FC7E4007383E083C1010111827C82F2C3C1C180C00000000 +2731:00000380038003804384F39E3FFC0FF03FFCF39E438403800380038000000000 +2732:00000380038003804384F39E3C7C08303C7CF39E438403800380038000000000 +2733:01000100210811100D600FE007C0FFFE07C00FE00D6011102108010001000000 +2734:0100010021081BB01FF00FE01FE0FFFE1FF00FE01FF01BB02108010001000000 +2735:010002803CF82CC8269832B87D4C83864D7C3A9832C826683E78028001000000 +2736:000001000100010043843BB81FF00FE01FF03BB8438401000100010000000000 +2737:082008200C6006C0E6CE3BB81FF007C01FF03BB8E6CE06C00C60082008200000 +2738:08200C600EE00FE0FFFE7FFC3FF81FF03FF87FFCFFFE0FE00EE00C6008200000 +2739:010019300FE04FE47FFC3FF83FF8FFFE3FF83FF87FFC4FE40FE0193001000000 +273A:0920492425481550CBA637D80FE0FFFE0FE037D8CBA615502548492409200000 +273B:0100038003800380E10E711C0D6003800D60711CE10E03800380038001000000 +273C:038007C007C0638CF11EF39E3C7808203C78F39EF11E638C07C007C003800000 +273D:038007C007C0638CF39EF11E3D7807C03D78F11EF39E638C07C007C003800000 +273E:038004400440745CFC7EFEFE7FFC2108438487C28FE277DC07C007C003800000 +273F:038007C00FE077DCFFFEFC7EF01E701C18303EF87FFC7EFC7EFC3C7800000000 +2740:038004400920793C8542B39A8FE26FEC17D027C84924529442843C7800000000 +2741:03803C78454451144D646FEC86C2BC7A86C26FEC4D64511445443C7803800000 +2742:07C01EF03EF85C7467CCFC7EE82E8822E82EFC7E67CC5C743EF81EF007C00000 +2743:038004C004C074DCBCE69F9E4F3C3FF87264E672CE7A765C0640064003800000 +2744:0000010005400380C92631184D6403804D643118C92603800540010000000000 +2745:0000010005400BA0C92631184D6483824D643118C9260BA00540010000000000 +2746:09200D6007C01390C9263118ED6E0380ED6E3118C926111007C00D6009200000 +2747:000003C023C413C8099005A0700E7DBE7DBE700E05A0099013C823C403C00000 +2748:07C047C427C813900BA0E00EFBBEFBBEFBBEE00E0BA0139027C847C407C00000 +2749:038007C007C077DCFBBEF93E7D7C07C07D7CF93EFBBE77DC07C007C003800000 +274A:010003803398311809200540638CFFFE638C0540092031183398038001000000 +274B:0100038033983BB8193007C077DCFFFE77DC07C019303BB83398038001000000 +274C:0000000018303C781EF00FE007C007C00FE01EF03C7838381010000000000000 +274D:0000000003C00C301008100C2004200620062006100E100C0C3C03F801E00000 +274E:00007FFC6FEC47C4638C711C783C7C7C783C711C638C47C46FEC7FFC00000000 +274F:00001FF81008100E100E100E100E100E100E100E1FFE07FE07FE000000000000 +2750:000007FE07FE1FFE100E100E100E100E100E100E100E10081FF8000000000000 +2751:00001FF8100C100E100E100E100E100E100E100E1FFE0FFE07FE000000000000 +2752:000007FE0FFE1FFE100E100E100E100E100E100E100E100C1FF8000000000000 +2753:000003800FE01E70183018F001E0038003000300030000000300078007800300 +2754:07C0082013901450085000900120024002800280038000000380044004400380 +2755:038006C00C6008200C60044006C0028002800380000003800440044003800000 +2756:00000100038007C00380111038387C7C38381110038007C00380010000000000 +2757:018003C003C003C003C003C003C0018001800180018000000180018000000000 +2758:0180018001800180018001800180018001800180018001800180018001800000 +2759:03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C00000 +275A:0FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000 +275B:01C007000C000F800FC00FE00FE00FE007C00380000000000000000000000000 +275C:038007C00FE00FE00FE007E003E0006001C00700000000000000000000000000 +275D:1C1C7070C0C0F8F8FCFCFEFEFEFEFEFE7C7C3838000000000000000000000000 +275E:38387C7CFEFEFEFEFEFE7E7E3E3E06061C1C7070000000000000000000000000 +275F:000000000000000007000F801FC01FC01FC00FC007C000C003800E0000000000 +2760:000000000000000038387C7CFEFEFEFEFEFE7E7E3E3E06061C1C707000000000 +2761:0000001000100FFE3FF87E107E103F100FF0001030307820786031C01F000000 +2762:03800FE01FF01FF01FF00FE00380010001000000038007C007C007C003800000 +2763:00000EE01FF01FF01FF00FE0038001000000038007C007C007C0038000000000 +2764:000000003C787EFCFFFEFFFEFFFE7FFC7FFC3FF81FF00FE007C0038001000000 +2765:1C003F007F807FC07FE07FF03FF81FFC3FF87FF07FE07FC07F803F001C000000 +2766:000000001F0421F801800E701FF81FF81FF80FF007E003C00180019000E00000 +2767:000000002000138017C417E217F21BFE3BFC27F027E027C02380100000000000 +2768:00000002040C1818181818180C040200 +2769:0000002010180C0C0C0C0C0C18102000 +276A:000000060C1C3838383838381C0C0600 +276B:00000030181C0E0E0E0E0E0E1C183000 +276C:000000060C0C1818303018180C0C0600 +276D:0000003018180C0C06060C0C18183000 +276E:000000070E0E1C1C38381C1C0E0E0700 +276F:0000007038381C1C0E0E1C1C38387000 +2770:0000000F1E1E3C3C78783C3C1E1E0F00 +2771:000000F078783C3C1E1E3C3C7878F000 +2772:00000004081010101010101010080400 +2773:00000020100808080808080808102000 +2774:0000001E38303018187018183030381E +2775:000000781C0C0C18180E18180C0C1C78 +2776:07C01FF03FF87EFC7CFCFAFEFEFEFEFEFEFEFEFE7EFC783C3FF81FF007C00000 +2777:07C01FF03FF87C7C7BBCFBBEFFBEFF7EFEFEFDFE7BFC783C3FF81FF007C00000 +2778:07C01FF03FF87C7C7BBCFBBEFFBEFE7EFFBEFBBE7BBC7C7C3FF81FF007C00000 +2779:07C01FF03FF87F7C7E7CFD7EFB7EF77EF03EFF7E7F7C7F7C3FF81FF007C00000 +277A:07C01FF03FF8783C7BFCFBFEFBFEF87EFFBEFFBE7BBC7C7C3FF81FF007C00000 +277B:07C01FF03FF87E7C7DFCFBFEFBFEF87EFBBEFBBE7BBC7C7C3FF81FF007C00000 +277C:07C01FF03FF8783C7FBCFFBEFF7EFF7EFF7EFEFE7EFC7EFC3FF81FF007C00000 +277D:07C01FF03FF87C7C7BBCFBBEFBBEFC7EFBBEFBBE7BBC7C7C3FF81FF007C00000 +277E:07C01FF03FF87C7C7BBCFBBEFBBEFC3EFFBEFFBE7F7C7CFC3FF81FF007C00000 +277F:07C01FF03FF87FFC7B9CF36EEB6EFB6EFB6EFB6E609C7FFC3FF81FF007C00000 +2780:07C0183020084084418483828182818281828182418441842008183007C00000 +2781:07C01830200847C44FE48C62806281C287028C024FE44FE42008183007C00000 +2782:07C01830200847C44FE48C62806281C280628C624FE447C42008183007C00000 +2783:07C01830200840E441E4836286628C629FF29FF2406440642008183007C00000 +2784:07C0183020084FE44FE48C028FC28FE280628C624FE447C42008183007C00000 +2785:07C01830200847C44FE48C028FC28FE28C628C624FE447C42008183007C00000 +2786:07C0183020084FE44FE48062806280C283828602460446042008183007C00000 +2787:07C01830200847C44FE48C628C6287C28C628C624FE447C42008183007C00000 +2788:07C01830200847C44FE48C628C628FE287E280624FE447C42008183007C00000 +2789:07C01830200844E44DF49DB28DB28DB28DB28DB24DF44CE42008183007C00000 +278A:07C01FF03FF87F7C7E7CFC7EFE7EFE7EFE7EFE7E7E7C7E7C3FF81FF007C00000 +278B:07C01FF03FF8783C701CF39EFF9EFE3EF8FEF3FE701C701C3FF81FF007C00000 +278C:07C01FF03FF8783C701CF39EFF9EFE3EFF9EF39E701C783C3FF81FF007C00000 +278D:07C01FF03FF87F1C7E1CFC9EF99EF39EE00EE00E7F9C7F9C3FF81FF007C00000 +278E:07C01FF03FF8701C701CF3FEF03EF01EFF9EF39E701C783C3FF81FF007C00000 +278F:07C01FF03FF8783C701CF3FEF03EF01EF39EF39E701C783C3FF81FF007C00000 +2790:07C01FF03FF8701C701CFF9EFF9EFF3EFC7EF9FE79FC79FC3FF81FF007C00000 +2791:07C01FF03FF8783C701CF39EF39EF83EF39EF39E701C783C3FF81FF007C00000 +2792:07C01FF03FF8783C701CF39EF39EF01EF81EFF9E701C783C3FF81FF007C00000 +2793:07C01FF03FF87B1C720CE24EF24EF24EF24EF24E720C731C3FF81FF007C00000 +2794:00001F800FC007E003F0FFF8FFFCFFFEFFFCFFF803F007E00FC01F8000000000 +2795:0000000003800380038003803FF83FF83FF80380038003800380000000000000 +2796:0000000000000000000000007FFC7FFC7FFC0000000000000000000000000000 +2797:0000000003800380038000007FFC7FFC7FFC0000038003800380000000000000 +2798:0000000008001C003E001E000F20032000E000F003F000700008000000000000 +2799:00000000000001000180E0C0FCF0FFFEFCF0E0C0018001000000000000000000 +279A:0000000000000008007003F000F000E003200F201E003E001C00080000000000 +279B:0000000000000200010001C000F0FFFE00F001C0010002000000000000000000 +279C:000000C001E001F000F87FFCFFFEFFFEFFFE7FFC00F801F001E000C000000000 +279D:000000000010001000180018FFFCFFFEFFFC0018001800100010000000000000 +279E:00000010001000180018FFFCFFFCFFFEFFFCFFFC001800180010001000000000 +279F:000000000000002000300038AAFCAAFEAAFC0038003000200000000000000000 +27A0:00000000000000200030AAF8AAFCAAFEAAFCAAF8003000200000000000000000 +27A1:000000000000002000300038FFFCFFFEFFFC0038003000200000000000000000 +27A2:400070002C00230010C01030080C07FE0FFC1FF01FC03F003C00700040000000 +27A3:400070003C003F001FC01FF00FFC07FE080C103010C023002C00700040000000 +27A4:400070003C003F001FC01FF00FFC07FE0FFC1FF01FC03F003C00700040000000 +27A5:00000000000080008010C0187FFC7FFE3FFC0018001000000000000000000000 +27A6:0000000000000000001000183FFC7FFE7FFCC018801080000000000000000000 +27A7:00000080008000C007C007E007E007F007E007E007C000C00080008000000000 +27A8:00000000000000400040FFE0FFF0FFFEFFF0FFE0004000400000000000000000 +27A9:000000000000006000707FD8400C4006400C7FD8007000600000000000000000 +27AA:000000000000006000707FE86004600260047FE8007000600000000000000000 +27AB:0000000000080018002400443F8240028006FF1EFE7C05F00FC00F000C000000 +27AC:00000C000F000FC005F0FE7CFF1E800640023F82004400240018000800000000 +27AD:00000000008000C0FFA0801080088004800E801CFFB87FF000E0004000000000 +27AE:0000004000E07FF0FFB8801C800E800480088010FFA000C00080000000000000 +27AF:00000000004000600050FFC8400440024007FFCE7FDC00780070002000000000 +27B0:0000000000631C2222221C0000000000 +27B1:00000020007000787FDCFFCE400740024004FFC8005000600040000000000000 +27B2:07C01FF03F787F3C7F1C000E000600020006000E7F1C7F3C3F781FF007C00000 +27B3:0000000000000000FE004908248C1FFE248C4908FE0000000000000000000000 +27B4:000000000400060007003F001F000F08008800580038007801F8000000000000 +27B5:000000000000000000007C083E0C1FFE3E0C7C08000000000000000000000000 +27B6:00000000000001F800780038005800880F081F003F0007000600040000000000 +27B7:0000000002000300038003803F881F880FD800F8007800F803F8000000000000 +27B8:0000000000000020FC107E183FFC1FFE3FFC7E18FC1000200000000000000000 +27B9:00000000000003F800F8007800F80FD81F883F88038003800300020000000000 +27BA:00000000006000F000F07838FF0CFFFEFF0C783800F000F00060000000000000 +27BB:000000000000004060E078F0FC78FFFEFC7878F060E000400000000000000000 +27BC:0000000000000000F8107C183E1C1FFE3E1C7C18F81000000000000000000000 +27BD:000000000000F860FC707E787FFC3FFE7FFC7E78FC70F8600000000000000000 +27BE:000000000000022001100088FFC40002FFC40088011002200000000000000000 +27BF:00000000000000000000E3C71C382244224422441C3800000000000000000000 +27C0:000000000000000040444850607E0000 +27C1:000000000100028002800440044009200AA01290145027C820083FF800000000 +27C2:000000000000000010101010107C0000 +27C3:0000000000000000000007F808001030104810481030080007F8000000000000 +27C4:000000000000000000001FE000100C08120812080C0800101FE0000000000000 +27C5:000000001C22220404080810100E0000 +27C6:000000001C2222101008080404380000 +27C7:00000000000041412A22141408080000 +27C8:0000000000000000000040FE41002200220012001200090008FE000000000000 +27C9:000000000000000000007F020082004400440048004800907F10000000000000 +27CA:00000000101010103810101010100000 +27CB:0000000000000000000000100020004000800100020004000800000000000000 +27CC:000000003FFC2000100010000800080008000800080008001000100020002000 +27CD:0000000000000000000008000400020001000080004000200010000000000000 +27CE:0000000000001FFC1004108410841144114412241224141414141FFC00000000 +27CF:0000000000001FFC1414141412241224114411441084108410041FFC00000000 +27D0:0000000000000000000000800140022004100888041002200140008000000000 +27D1:00000000000008081414222A41410000 +27D2:000000000000000011101110111011101110111011101110092007C000000000 +27D3:000000000000000002021202027E0000 +27D4:00000000000000007E40404840400000 +27D5:000000000000000038040C0C0A14092408C408C409240A140C0C380400000000 +27D6:0000000000000000201C30302850249023102310249028503030201C00000000 +27D7:0000000000000000700E18181428124811881188124814281818700E00000000 +27D8:00000000010001000100010001000100010001000100010001001FF000000000 +27D9:000000001FF00100010001000100010001000100010001000100010000000000 +27DA:00000000000000000000028002807EFC02807EFC028002800000000000000000 +27DB:000000000000000000000280028002807EFC0280028002800000000000000000 +27DC:00000000000000000000000000001C00220023FC22001C000000000000000000 +27DD:0000000000000000000000004000400040007FFE400040004000000000000000 +27DE:0000000000000000000000000002000200027FFE000200020002000000000000 +27DF:000000003844443810101010107C0000 +27E0:0000001028284444FE44442828100000 +27E1:0000010002800280044008203018400430180820044002800280010000000000 +27E2:000000800140014002200410180CE002180C0410022001400140008000000000 +27E3:0000010002800280044008203018400730180820044002800280010000000000 +27E4:00001FFE10021002100210021002F002100210021002100210021FFE00000000 +27E5:00007FF840084008400840084008400F400840084008400840087FF800000000 +27E6:003E28282828282828282828283E0000 +27E7:007C14141414141414141414147C0000 +27E8:00000408081010202010100808040000 +27E9:00002010100808040408081010200000 +27EA:00000A141428285050282814140A0000 +27EB:000050282814140A0A14142828500000 +27EC:00000002040C1414141414140C040200 +27ED:00000040203028282828282830204000 +27EE:00000002040808080808080808040200 +27EF:00000040201010101010101010204000 +27F0:000000000100028006C00AA01AB02AA80AA00AA00AA00AA00AA00AA000000000 +27F1:000000000AA00AA00AA00AA00AA00AA02AA81AB00AA006C00280010000000000 +27F2:000000000000000001E00210040808042A041C0408040008021001E000000000 +27F3:0000000000000000078008401020201020542038201010000840078000000000 +27F4:0000000000000000038005480924FFFE09240548038000000000000000000000 +27F5:00000000000000000000100020007FFF20001000000000000000000000000000 +27F6:0000000000000000000000080004FFFE00040008000000000000000000000000 +27F7:00000000000000000000100820047FFE20041008000000000000000000000000 +27F8:0000000000000000100020007FFE80007FFE2000100000000000000000000000 +27F9:000000000000000000100008FFFC0002FFFC0008001000000000000000000000 +27FA:0000000000000000081010083FFC40023FFC1008081000000000000000000000 +27FB:00000000000000000000100220027FFE20021002000000000000000000000000 +27FC:00000000000000000000400840047FFE40044008000000000000000000000000 +27FD:0000000000000000080210023FFE40023FFE1002080200000000000000000000 +27FE:0000000000000000401040087FFC40027FFC4008401000000000000000000000 +27FF:0000000000000000000000082224D55E08840008000000000000000000000000 +2800:00000022000022000022000022000000 +2801:00000032300022000022000022000000 +2802:00000022000032300022000022000000 +2803:00000032300032300022000022000000 +2804:00000022000022000032300022000000 +2805:00000032300022000032300022000000 +2806:00000022000032300032300022000000 +2807:00000032300032300032300022000000 +2808:00000026060022000022000022000000 +2809:00000036360022000022000022000000 +280A:00000026060032300022000022000000 +280B:00000036360032300022000022000000 +280C:00000026060022000032300022000000 +280D:00000036360022000032300022000000 +280E:00000026060032300032300022000000 +280F:00000036360032300032300022000000 +2810:00000022000026060022000022000000 +2811:00000032300026060022000022000000 +2812:00000022000036360022000022000000 +2813:00000032300036360022000022000000 +2814:00000022000026060032300022000000 +2815:00000032300026060032300022000000 +2816:00000022000036360032300022000000 +2817:00000032300036360032300022000000 +2818:00000026060026060022000022000000 +2819:00000036360026060022000022000000 +281A:00000026060036360022000022000000 +281B:00000036360036360022000022000000 +281C:00000026060026060032300022000000 +281D:00000036360026060032300022000000 +281E:00000026060036360032300022000000 +281F:00000036360036360032300022000000 +2820:00000022000022000026060022000000 +2821:00000032300022000026060022000000 +2822:00000022000032300026060022000000 +2823:00000032300032300026060022000000 +2824:00000022000022000036360022000000 +2825:00000032300022000036360022000000 +2826:00000022000032300036360022000000 +2827:00000032300032300036360022000000 +2828:00000026060022000026060022000000 +2829:00000036360022000026060022000000 +282A:00000026060032300026060022000000 +282B:00000036360032300026060022000000 +282C:00000026060022000036360022000000 +282D:00000036360022000036360022000000 +282E:00000026060032300036360022000000 +282F:00000036360032300036360022000000 +2830:00000022000026060026060022000000 +2831:00000032300026060026060022000000 +2832:00000022000036360026060022000000 +2833:00000032300036360026060022000000 +2834:00000022000026060036360022000000 +2835:00000032300026060036360022000000 +2836:00000022000036360036360022000000 +2837:00000032300036360036360022000000 +2838:00000026060026060026060022000000 +2839:00000036360026060026060022000000 +283A:00000026060036360026060022000000 +283B:00000036360036360026060022000000 +283C:00000026060026060036360022000000 +283D:00000036360026060036360022000000 +283E:00000026060036360036360022000000 +283F:00000036360036360036360022000000 +2840:00000022000022000022000032300000 +2841:00000032300022000022000032300000 +2842:00000022000032300022000032300000 +2843:00000032300032300022000032300000 +2844:00000022000022000032300032300000 +2845:00000032300022000032300032300000 +2846:00000022000032300032300032300000 +2847:00000032300032300032300032300000 +2848:00000026060022000022000032300000 +2849:00000036360022000022000032300000 +284A:00000026060032300022000032300000 +284B:00000036360032300022000032300000 +284C:00000026060022000032300032300000 +284D:00000036360022000032300032300000 +284E:00000026060032300032300032300000 +284F:00000036360032300032300032300000 +2850:00000022000026060022000032300000 +2851:00000032300026060022000032300000 +2852:00000022000036360022000032300000 +2853:00000032300036360022000032300000 +2854:00000022000026060032300032300000 +2855:00000032300026060032300032300000 +2856:00000022000036360032300032300000 +2857:00000032300036360032300032300000 +2858:00000026060026060022000032300000 +2859:00000036360026060022000032300000 +285A:00000026060036360022000032300000 +285B:00000036360036360022000032300000 +285C:00000026060026060032300032300000 +285D:00000036360026060032300032300000 +285E:00000026060036360032300032300000 +285F:00000036360036360032300032300000 +2860:00000022000022000026060032300000 +2861:00000032300022000026060032300000 +2862:00000022000032300026060032300000 +2863:00000032300032300026060032300000 +2864:00000022000022000036360032300000 +2865:00000032300022000036360032300000 +2866:00000022000032300036360032300000 +2867:00000032300032300036360032300000 +2868:00000026060022000026060032300000 +2869:00000036360022000026060032300000 +286A:00000026060032300026060032300000 +286B:00000036360032300026060032300000 +286C:00000026060022000036360032300000 +286D:00000036360022000036360032300000 +286E:00000026060032300036360032300000 +286F:00000036360032300036360032300000 +2870:00000022000026060026060032300000 +2871:00000032300026060026060032300000 +2872:00000022000036360026060032300000 +2873:00000032300036360026060032300000 +2874:00000022000026060036360032300000 +2875:00000032300026060036360032300000 +2876:00000022000036360036360032300000 +2877:00000032300036360036360032300000 +2878:00000026060026060026060032300000 +2879:00000036360026060026060032300000 +287A:00000026060036360026060032300000 +287B:00000036360036360026060032300000 +287C:00000026060026060036360032300000 +287D:00000036360026060036360032300000 +287E:00000026060036360036360032300000 +287F:00000036360036360036360032300000 +2880:00000022000022000022000026060000 +2881:00000032300022000022000026060000 +2882:00000022000032300022000026060000 +2883:00000032300032300022000026060000 +2884:00000022000022000032300026060000 +2885:00000032300022000032300026060000 +2886:00000022000032300032300026060000 +2887:00000032300032300032300026060000 +2888:00000026060022000022000026060000 +2889:00000036360022000022000026060000 +288A:00000026060032300022000026060000 +288B:00000036360032300022000026060000 +288C:00000026060022000032300026060000 +288D:00000036360022000032300026060000 +288E:00000026060032300032300026060000 +288F:00000036360032300032300026060000 +2890:00000022000026060022000026060000 +2891:00000032300026060022000026060000 +2892:00000022000036360022000026060000 +2893:00000032300036360022000026060000 +2894:00000022000026060032300026060000 +2895:00000032300026060032300026060000 +2896:00000022000036360032300026060000 +2897:00000032300036360032300026060000 +2898:00000026060026060022000026060000 +2899:00000036360026060022000026060000 +289A:00000026060036360022000026060000 +289B:00000036360036360022000026060000 +289C:00000026060026060032300026060000 +289D:00000036360026060032300026060000 +289E:00000026060036360032300026060000 +289F:00000036360036360032300026060000 +28A0:00000022000022000026060026060000 +28A1:00000032300022000026060026060000 +28A2:00000022000032300026060026060000 +28A3:00000032300032300026060026060000 +28A4:00000022000022000036360026060000 +28A5:00000032300022000036360026060000 +28A6:00000022000032300036360026060000 +28A7:00000032300032300036360026060000 +28A8:00000026060022000026060026060000 +28A9:00000036360022000026060026060000 +28AA:00000026060032300026060026060000 +28AB:00000036360032300026060026060000 +28AC:00000026060022000036360026060000 +28AD:00000036360022000036360026060000 +28AE:00000026060032300036360026060000 +28AF:00000036360032300036360026060000 +28B0:00000022000026060026060026060000 +28B1:00000032300026060026060026060000 +28B2:00000022000036360026060026060000 +28B3:00000032300036360026060026060000 +28B4:00000022000026060036360026060000 +28B5:00000032300026060036360026060000 +28B6:00000022000036360036360026060000 +28B7:00000032300036360036360026060000 +28B8:00000026060026060026060026060000 +28B9:00000036360026060026060026060000 +28BA:00000026060036360026060026060000 +28BB:00000036360036360026060026060000 +28BC:00000026060026060036360026060000 +28BD:00000036360026060036360026060000 +28BE:00000026060036360036360026060000 +28BF:00000036360036360036360026060000 +28C0:00000022000022000022000036360000 +28C1:00000032300022000022000036360000 +28C2:00000022000032300022000036360000 +28C3:00000032300032300022000036360000 +28C4:00000022000022000032300036360000 +28C5:00000032300022000032300036360000 +28C6:00000022000032300032300036360000 +28C7:00000032300032300032300036360000 +28C8:00000026060022000022000036360000 +28C9:00000036360022000022000036360000 +28CA:00000026060032300022000036360000 +28CB:00000036360032300022000036360000 +28CC:00000026060022000032300036360000 +28CD:00000036360022000032300036360000 +28CE:00000026060032300032300036360000 +28CF:00000036360032300032300036360000 +28D0:00000022000026060022000036360000 +28D1:00000032300026060022000036360000 +28D2:00000022000036360022000036360000 +28D3:00000032300036360022000036360000 +28D4:00000022000026060032300036360000 +28D5:00000032300026060032300036360000 +28D6:00000022000036360032300036360000 +28D7:00000032300036360032300036360000 +28D8:00000026060026060022000036360000 +28D9:00000036360026060022000036360000 +28DA:00000026060036360022000036360000 +28DB:00000036360036360022000036360000 +28DC:00000026060026060032300036360000 +28DD:00000036360026060032300036360000 +28DE:00000026060036360032300036360000 +28DF:00000036360036360032300036360000 +28E0:00000022000022000026060036360000 +28E1:00000032300022000026060036360000 +28E2:00000022000032300026060036360000 +28E3:00000032300032300026060036360000 +28E4:00000022000022000036360036360000 +28E5:00000032300022000036360036360000 +28E6:00000022000032300036360036360000 +28E7:00000032300032300036360036360000 +28E8:00000026060022000026060036360000 +28E9:00000036360022000026060036360000 +28EA:00000026060032300026060036360000 +28EB:00000036360032300026060036360000 +28EC:00000026060022000036360036360000 +28ED:00000036360022000036360036360000 +28EE:00000026060032300036360036360000 +28EF:00000036360032300036360036360000 +28F0:00000022000026060026060036360000 +28F1:00000032300026060026060036360000 +28F2:00000022000036360026060036360000 +28F3:00000032300036360026060036360000 +28F4:00000022000026060036360036360000 +28F5:00000032300026060036360036360000 +28F6:00000022000036360036360036360000 +28F7:00000032300036360036360036360000 +28F8:00000026060026060026060036360000 +28F9:00000036360026060026060036360000 +28FA:00000026060036360026060036360000 +28FB:00000036360036360026060036360000 +28FC:00000026060026060036360036360000 +28FD:00000036360026060036360036360000 +28FE:00000026060036360036360036360000 +28FF:00000036360036360036360036360000 +2900:0000000000000000000002280214FFFE02140228000000000000000000000000 +2901:0000000000000000000005280514FFFE05140528000000000000000000000000 +2902:0000000000000000088010803FFF40803FFF1080088000000000000000000000 +2903:000000000000000001100108FFFC0102FFFC0108011000000000000000000000 +2904:0000000000000000049008881FFC20821FFC0888049000000000000000000000 +2905:00000000000000000000402840147FFE40144028000000000000000000000000 +2906:0000000000000000080010023FFE40023FFE1002080000000000000000000000 +2907:0000000000000000001040087FFC40027FFC4008001000000000000000000000 +2908:080808080808083E0808082A1C080000 +2909:0000081C2A08083E0808080808080808 +290A:000000000100038005400D601550054005400540054005400540054000000000 +290B:00000000054005400540054005400540054015500D6005400380010000000000 +290C:00000000000000000000100020007F7F20001000000000000000000000000000 +290D:0000000000000000000000080004FEFE00040008000000000000000000000000 +290E:00000000000000000000100020007DEF20001000000000000000000000000000 +290F:0000000000000000000000080004F7BE00040008000000000000000000000000 +2910:00000000000000000000402820141B7E20144028000000000000000000000000 +2911:0000000000000000000000080004AAAE00040008000000000000000000000000 +2912:00007F1C2A0808080808080808080808 +2913:08080808080808080808082A1C7F0000 +2914:00000000000000000000410821041FFE21044108000000000000000000000000 +2915:00000000000000000000428822841FFE22844288000000000000000000000000 +2916:00000000000000000000402820141FFE20144028000000000000000000000000 +2917:00000000000000000000412821141FFE21144128000000000000000000000000 +2918:00000000000000000000452825141FFE25144528000000000000000000000000 +2919:00000000000000000000000200047FF800040002000000000000000000000000 +291A:00000000000000000000400020001FFE20004000000000000000000000000000 +291B:00000000000000000000001200247FF800240012000000000000000000000000 +291C:00000000000000000000480024001FFE24004800000000000000000000000000 +291D:0000000000000000000011003A007FFF3A001100000000000000000000000000 +291E:000000000000000000000044002E7FFF002E0044000000000000000000000000 +291F:0000000000000000000011023A027FFE3A021102000000000000000000000000 +2920:000000000000000000004088405C7FFE405C4088000000000000000000000000 +2921:00003C00300028002400020001000080004000200012000A0006001E00000000 +2922:0000001E0006000A0012002000400080010002002400280030003C0000000000 +2923:00003C0030002800240002000100008000400020001000080024001800000000 +2924:0000007800180028004800800100020004000800100020004800300000000000 +2925:0000300048002000100008000400020001000080004800280018007800000000 +2926:0000003000480010002000400080010002000400480050006000780000000000 +2927:0000781E6006500A481204200240018001800240042008101008200400000000 +2928:0000001E2006100A08120420024001800180024004200812100A2006001E0000 +2929:00002004100808100420024001800180024004204812500A6006781E00000000 +292A:0000780060045008481004200240018001800240042048105008600478000000 +292B:0000000020041008081004200040008001000200042008101008200400000000 +292C:0000000020041008081004200200010000800040042008101008200400000000 +292D:0000001E2006100A08120420020001000080004004200812100A2006001E0000 +292E:0000001E2006100A08120420004000800100020004200812100A2006001E0000 +292F:0000001E2006100A081204200200010000800040042008101008200400000000 +2930:00002004100808100420004000800100020004200812100A2006001E00000000 +2931:0000781E6006500A481204200040008001000200042008101008200400000000 +2932:0000781E6006500A481204200200010000800040042008101008200400000000 +2933:000000000000000000003C08420481FE00040008000000000000000000000000 +2934:0000001000380054001000100020FFC000000000000000000000000000000000 +2935:00000000FFC00020001000100010005400380010000000000000000000000000 +2936:00080008000800080008040808101FE008000400000000000000000000000000 +2937:100010001000100010001020081007F800100020000000000000000000000000 +2938:000020100808040404042828303C0000 +2939:0000040810102020202014140C3C0000 +293A:00000000000000000000000023C02C3030083C04000000000000000000000000 +293B:000000000000000000000000203C100C0C3403C4000000000000000000000000 +293C:00000000000000000000000003C40C34100C203C070000000000000000000000 +293D:00000000000000000000000023C02C3030083C4400E000400000000000000000 +293E:00000000000000100008000400043C0430082C3023C000000000000000000000 +293F:0000000000000800100020002000203C100C0C3403C400000000000000000000 +2940:000000000080010003800D601090101020082008101010100C60038000000000 +2941:000000000200010003800D601210101020082008101010100C60038000000000 +2942:000000000000000800047FFE00040008100020007E0020001000000000000000 +2943:000000000000100020007FFE2000100000080004007E00040008000000000000 +2944:00000000000000080004007E00040008100020007FFE20001000000000000000 +2945:0000000000000000000000080004FFFE00040008080008003E00080008000000 +2946:0000000000000000000020004000FFFF400020000020002000F8002000200000 +2947:0000000000000000001011080A04FFFE0A041108001000000000000000000000 +2948:0000000000000000101023884444FFFE44442388101000000000000000000000 +2949:00001038543854101010384444380000 +294A:00000000000000000000100020007FFE00040008000000000000000000000000 +294B:00000000000000000000000800047FFE20001000000000000000000000000000 +294C:00001018141010101010105030100000 +294D:00001030501010101010101418100000 +294E:00000000000000000000100820047FFE00000000000000000000000000000000 +294F:00002030282020202020202830200000 +2950:00000000000000000000000000007FFE20041008000000000000000000000000 +2951:00000818280808080808082818080000 +2952:00000000000000000000480050007FFF40004000000000000000000000000000 +2953:000000000000000000000012000AFFFE00020002000000000000000000000000 +2954:00003E080C0A08080808080808080808 +2955:000008080808080808080A0C083E0000 +2956:00000000000000000000400040007FFF50004800000000000000000000000000 +2957:0000000000000000000000020002FFFE000A0012000000000000000000000000 +2958:00003E08182808080808080808080808 +2959:000008080808080808082818083E0000 +295A:00000000000000000000080210023FFE00020002000000000000000000000000 +295B:00000000000000000000401040087FFC40004000000000000000000000000000 +295C:000010181410101010101010107C0000 +295D:00007C10101010101010101418100000 +295E:00000000000000000000000200023FFE10020802000000000000000000000000 +295F:00000000000000000000400040007FFC40084010000000000000000000000000 +2960:000010305010101010101010107C0000 +2961:00007C10101010101010105030100000 +2962:000000000000100020007FFE0000000000007FFE200010000000000000000000 +2963:00000000022006300A2802200220022002200220022002200220022000000000 +2964:000000000000000800047FFE0000000000007FFE000400080000000000000000 +2965:000000000220022002200220022002200220022002200A280630022000000000 +2966:000000000000100020007FFE0000000800047FFE000000000000000000000000 +2967:000000000000000000007FFE2000100000007FFE000400080000000000000000 +2968:000000000000000800047FFE0000100020007FFE000000000000000000000000 +2969:000000000000000000007FFE0004000800007FFE200010000000000000000000 +296A:0000000000000000100020007FFE00007FFE0000000000000000000000000000 +296B:0000000000000000000000007FFE00007FFE2000100000000000000000000000 +296C:0000000000000000000800047FFE00007FFE0000000000000000000000000000 +296D:0000000000000000000000007FFE00007FFE0004000800000000000000000000 +296E:00000000022006200A2002200220022002200220022002280230022000000000 +296F:000000000220023002280220022002200220022002200A200620022000000000 +2970:000000000000000000007FFC000200027FFC0000000000000000000000000000 +2971:0000000000001F8000001F880004FFFE00040008000000000000000000000000 +2972:0000000000003800444003880004FFFE00040008000000000000000000000000 +2973:00000000000000000000100020007FFF200011C00222001C0000000000000000 +2974:0000000000000000000000080004FFFE00043808444003800000000000000000 +2975:0000000000000000000000080004FFFE38044448038038004440038000000000 +2976:0000000000180060018006000800060001800060021804000FF8040002000000 +2977:00000000000000060018106021807FF021801060001800060000000000000000 +2978:000000000C00030000C000300008003000C003000C2000100FF8001000200000 +2979:0000000003F80400080008000800040003F80000002000100FF8001000200000 +297A:00000000000000000000000001FE120024007FFE2400120001FE000000000000 +297B:000000000FE0001000080008000800100FE00000020004000FF8040002000000 +297C:0000000000204040201F204040200000 +297D:0000000000020101027C020101020000 +297E:000000000000000000000C601290010001000100010001000100000000000000 +297F:00000000000000000000000001000100010001000100010012900C6000000000 +2980:0000002A2A2A2A2A2A2A2A2A2A2A2A00 +2981:000000000000183C7E7E3C1800000000 +2982:00000000182424180000182424180000 +2983:00001E24241414244424141424241E00 +2984:00007824242828242224282824247800 +2985:0000000C181828282828282818180C00 +2986:00000030181814141414141418183000 +2987:0000000C141424242424242414140C00 +2988:00000030282824242424242428283000 +2989:000000040C0C1414242414140C0C0400 +298A:00000020303028282424282830302000 +298B:0000000E0808080808080808080E000E +298C:00000070101010101010101010700070 +298D:0000001E181412101010101010101E00 +298E:00000078080808080808084828187800 +298F:0000001E101010101010101214181E00 +2990:00000078182848080808080808087800 +2991:00000004080810102626101008080400 +2992:00000020101008086464080810102000 +2993:0000000000000040008C00F0018003000D0011000D000300018000F0008C0040 +2994:00000000000001001880078000C00060005800440058006000C0078018800100 +2995:00000000000000A019400740038002E0029802840298026001C0074018A00000 +2996:0000000000000280014C017000E003A00CA010A00CA0032001C00170028C0000 +2997:0000000C183838383838383838180C00 +2998:00000030181C1C1C1C1C1C1C1C183000 +2999:00000000080000080000080000080000 +299A:00201008102010081020100810201008 +299B:000000000000000040281028247E2000 +299C:000000000000004040404070507E0000 +299D:000000000000404040784454447F0000 +299E:0000000000000000001000200040009C012002180404083810003FFE00000000 +299F:000000000000000000000618207E0000 +29A0:00000000000000503028262830500000 +29A1:0000000000000000413E631408080000 +29A2:00000000000000007E20100804020000 +29A3:000000000000000040201008047E0000 +29A4:000000000000000002040810207E007E +29A5:000000000000000040201008047E007E +29A6:000000000000000000000040201E0000 +29A7:00000000000000000000001E20400000 +29A8:00000000000000780018012800C800C0012002200410081010103FFE00100000 +29A9:0000000000000F000C000A4009800180024002200410040804043FFE04000000 +29AA:00000000000000103FFE1010081004100220012000C000C80128001800780000 +29AB:00000000000004003FFE04040408041002200240018009800A400C000F000000 +29AC:00000000000010001000103C3E0C119410641060109011001200140018001000 +29AD:000000000000000800083C08307C298826080608090800880048002800180008 +29AE:0000000000001000180014001200110010901060106411943E0C103C10001000 +29AF:000000000000000800180028004800880908060826082988307C3C0800080008 +29B0:0000000000000000000017C0082014101210111010901050082007D000000000 +29B1:00000000000007C0000007D0082010501090111012101410082017C000000000 +29B2:0000010002800100000007D0082010501090111012101410082017C000000000 +29B3:010000800FC00080010007D0082010501090111012101410082017C000000000 +29B4:020004000FC00400020007D0082010501090111012101410082017C000000000 +29B5:0000000000000000000007C00820101010103FF810101010082007C000000000 +29B6:0000000000000000000007C0092011101110111011101110092007C000000000 +29B7:0000000000000000000007C0082012901290129012901290082007C000000000 +29B8:0000000000000000000007C0082014101210111010901050082007C000000000 +29B9:0000000000000000000007C00820111011101110111017D0082007C000000000 +29BA:0000000000000000000007C00920111011101FF010101010082007C000000000 +29BB:0000000000000000000017D0082014501290111012901450082017D000000000 +29BC:00000000000003E004100808122410441084110412240808041003E000000000 +29BD:0000010003800540010007C0092011101110111011101110092007C001000000 +29BE:00000000000003E0041009C81224141414141414122409C8041003E000000000 +29BF:00000000000003E0041009C813E417F417F417F413E409C8041003E000000000 +29C0:00000000000003E00410080810C413041404130410C40808041003E000000000 +29C1:00000000000003E004100808118410641014106411840808041003E000000000 +29C2:000000000000000000001F0020804040404840544048404020801F0000000000 +29C3:000000000000000000000F8010402020203C2020203C202010400F8000000000 +29C4:0000000000001FFC100C101410241044108411041204140418041FFC00000000 +29C5:0000000000001FFC18041404120411041084104410241014100C1FFC00000000 +29C6:0000000000001FFC10041084149412A411C412A41494108410041FFC00000000 +29C7:0000000000001FFC1004100411C412241224122411C4100410041FFC00000000 +29C8:0000000000001FFC1004100413E412241224122413E4100410041FFC00000000 +29C9:000000003FC020402040204023FC224422443FC402040204020403FC00000000 +29CA:000001000000010002800280044004400820082010101010200820087FFC0000 +29CB:00000000010002800280044004400820082010101010200820087FFC00007FFC +29CC:0000008001400140022002200410041009C80A0811841044238220027FFF0000 +29CD:0000000001000280028004400440082008201010101020082008FFFE00000000 +29CE:1800160011801060101010601180163018D003100C1010100C10031000D00030 +29CF:00000000000000000000006801A80628182820281828062801A8006800000000 +29D0:000000000000000000002C002B0028C028302808283028C02B002C0000000000 +29D1:00000000000041637579756341000000 +29D2:0000000000004163574F576341000000 +29D3:0000000000004163777F776341000000 +29D4:00000000000041627478746241000000 +29D5:0000000000004123170F172341000000 +29D6:00000000000000FE4428102844FE0000 +29D7:00000000000000FE7C3810387CFE0000 +29D8:00002010081020100810201008102000 +29D9:00000810201008102010081020100800 +29DA:0000000004400220011002200440022001100220044002200110022004400000 +29DB:0000000001100220044002200110022004400220011002200440022001100000 +29DC:00000000000000304949360000000000 +29DD:00000000001C22364949360000000000 +29DE:000000000000082A5D5D2A0800000000 +29DF:0000000000000000000000000000300C48124FF24812300C0000000000000000 +29E0:000000003FF83FFC3004300430043004300430043004300430043FFC00000000 +29E1:0000000000000000061A627E007E0000 +29E2:00000000000000000000000000000000210821082108210821083FF800000000 +29E3:00000000000000120024004800907FFE02407FFE090012002400480000000000 +29E4:00000000064009920024004800907FFE02407FFE090012002400480000000000 +29E5:00000000000000000012002400487FFE01207FFE04807FFE1200240048000000 +29E6:0000000000000000400240027FFE400240027FFE400240020000000000000000 +29E7:0000000000000000010001001FF0010001001FF0010001000000000000000000 +29E8:0000000000007FFC3F083F081F101F100F200F20074007400380038001000000 +29E9:0000000000007FFC21F821F811F011F009E009E005C005C00380038001000000 +29EA:0000000000000100038007C00FE01FF00FE007C0038001000540038001000000 +29EB:00001038387C7CFE7C7C383810000000 +29EC:000000000000000001C00220041004100410022001C0008002A001C000800000 +29ED:000000000000000001C003E007F007F007F003E001C0008002A001C000800000 +29EE:0000007C10FE8282828282FE107C0000 +29EF:0000007C10FEFEFEFEFEFEFE107C0000 +29F0:0000007C1010284482442810107C0000 +29F1:0000007C1010387CFE7C3810107C0000 +29F2:0000007C1038448282824438107C0000 +29F3:0000007C10387CFEFEFE7C38107C0000 +29F4:00000000000000000000400800041FFE00044008000000000000000000000000 +29F5:00000000404020201010080804040000 +29F6:00007800040408081010202040400000 +29F7:000000404020207C1008080404000000 +29F8:01010202040408081010202040400000 +29F9:80804040202010100808040402020000 +29FA:00000000002828FE2828000000000000 +29FB:00000000005454FE5454000000000000 +29FC:00000202041860806018040202000000 +29FD:0000808040300C020C30408080000000 +29FE:00000000000007C007C00380610C793C7FFC793C610C0380038007C007C00000 +29FF:00000000000000000000600C783C7FFC783C600C000000000000000000000000 +2A00:00000000000003E004100808100410041084100410040808041003E000000000 +2A01:00000000000003E004900888108410841FFC108410840888049003E000000000 +2A02:00000000000003E004100C18122411441084114412240C18041003E000000000 +2A03:0000000000001020102010201020102013201320102010200840078000000000 +2A04:00000000000010101010101010101110111017D011101110082007C000000000 +2A05:0000000000001FF0101010101010101010101010101010101010101000000000 +2A06:00000000000010101010101010101010101010101010101010101FF000000000 +2A07:000000000000024005A005A00990099012481248242424244812481200000000 +2A08:0000000000004812481224242424124812480990099005A005A0024000000000 +2A09:0000000000002008101008200440028001000280044008201010200800000000 +2A0A:00000000000000001FF010100B0004800A400A4004800B0010101FF000000000 +2A0B:00060A087E4A28180818284A7E082830 +2A0C:0000092416DA12481248124812481248124812481248124812485B6824900000 +2A0D:00060A08080808083E08080808283000 +2A0E:00060A080808083E083E080808283000 +2A0F:00060A0808080A0C0818280808283000 +2A10:00060A0808081C2A281C080808283000 +2A11:00060A08080808082F2B1D0808283000 +2A12:00060A0808080E020A020E0808283000 +2A13:00060A0808080C020A020C0808283000 +2A14:000C141010101E1105111E1010506000 +2A15:00060A0808081C222A221C0808283000 +2A16:00060A0808083E2A2A2A3E0808283000 +2A17:00060A08082848FE492A080808283000 +2A18:00060A0808492A1C081C2A4908283000 +2A19:00060A0808081C2A2A2A2A0808283000 +2A1A:00060A0808082A2A2A2A1C0808283000 +2A1B:00060A0808080808080808082830003E +2A1C:3E00060A080808080808080808283000 +2A1D:0000000000000000100818181428124811881188124814281818100800000000 +2A1E:0000000002060A122222120A06020000 +2A1F:000000000018242418001824241C0418 +2A20:0000000000001100088004400220011000880110022004400880110000000000 +2A21:20302824202020202020202020200000 +2A22:0000081408000808087F080808000000 +2A23:0000081422000808087F080808000000 +2A24:000000324C000808087F080808000000 +2A25:0000000000000808087F080808000800 +2A26:0000000000000808087F08080800324C +2A27:000000000000101010FE101611020407 +2A28:0000000000000808087F081C3E080000 +2A29:0000000018080810007E000000000000 +2A2A:0000000000000000007E000800000000 +2A2B:0000000000000040007E000200000000 +2A2C:0000000000000002007E004000000000 +2A2D:00000000000000000180060008800880108017F0108008800880060001800000 +2A2E:0000000000000000018000600110011001080FE8010801100110006001800000 +2A2F:00000000000000221408142200000000 +2A30:00000000181800422418244200000000 +2A31:000000000000004224182442007E0000 +2A32:0000000000000042241824427E000000 +2A33:0000000000000000000002200140088805500220055008880140022000000000 +2A34:00000000000000000180060008000A10112010C011200A100800060001800000 +2A35:0000000000000000018000600010085004880308048808500010006001800000 +2A36:000001800240000003C00C3010081428224421842244142810080C3003C00000 +2A37:000007E0181823C44C32500A9429A245A185A2459429500A4C3223C4181807E0 +2A38:0000000000000000000003E00410088808080BE808080888041003E000000000 +2A39:00000100028002800440044008200920111017D02108210840047FFC00000000 +2A3A:00000100028002800440044008200820101017D02008200840047FFC00000000 +2A3B:00000100028002800440044008200C60129011102288244840047FFC00000000 +2A3C:000000000000000002027E0000000000 +2A3D:000000000000000040407E0000000000 +2A3E:000000000008141408000814140C0418 +2A3F:000000002222222222222222227F0000 +2A40:0000000000003C42425A5A4242420000 +2A41:0000000000004141415D4141413E0000 +2A42:000000007E00424242424242423C0000 +2A43:000000007E003C424242424242420000 +2A44:0000000000003E414141414955550000 +2A45:000000000000555549414141413E0000 +2A46:00000000002424241800182424240000 +2A47:00000000001824242400242424180000 +2A48:00000024242418003C00182424240000 +2A49:00000018242424003C00242424180000 +2A4A:000000000000000000009292926C0000 +2A4B:000000000000000000006C9292920000 +2A4C:0000000000FF424242424242423C0000 +2A4D:0000000000003C424242424242FF0000 +2A4E:0000000000001FF0101017D01450145014501450145014501450145000000000 +2A4F:0000000000001450145014501450145014501450145017D010101FF000000000 +2A50:00000000000000003FFE1004100411441084155412241554108C094807F00000 +2A51:0000000000000100000001000280028004400440082008201010101000000000 +2A52:0000000000000100000010101010082008200440044002800280010000000000 +2A53:0000000000000100028002800440044008200920129012902448244800000000 +2A54:0000000000002448244812901290092008200440044002800280010000000000 +2A55:00000000000000000000024005A005A009900990124812482424242400000000 +2A56:0000000000000000000024242424124812480990099005A005A0024000000000 +2A57:0000000000000000100810101020104010801100120014001800100000000000 +2A58:00000000000000000004000C0014002400440084010402040404080400000000 +2A59:000000000000000000004004200811100AA004400AA011102008400400000000 +2A5A:0000000000000100038003800540054009200920111011102108210800000000 +2A5B:0000000000002108210811101110092009200540054003800380010000000000 +2A5C:000000000000010002800280044004403FF80820101010102008200800000000 +2A5D:000000000000200820081010101008203FF80440044002800280010000000000 +2A5E:00001FF000001FF0000001000280028004400440082008201010101000000000 +2A5F:00000000000001000280028004400440082008201010101000001FF000000000 +2A60:00000000000001000280028004400440082008201010101000001FF000001FF0 +2A61:00000000000000000000000000000000000004400280010000001FF000000000 +2A62:0000000000001FF000001FF00000101010100820082004400440028002800100 +2A63:00000000000010101010082008200440044002800280010000001FF000001FF0 +2A64:000000000000001800680188060818083FF81808060801880068001800000000 +2A65:00000000000030002C00230020C020303FF8203020C023002C00300000000000 +2A66:000000000000007F007F000800000000 +2A67:000000000008007F007F007F00000000 +2A68:00000000000000000000028002803FF802803FF802803FF80280000000000000 +2A69:00000000000000000000054005403FF805403FF805403FF80540000000000000 +2A6A:00000000000020006498000000000000 +2A6B:00000000000008006498004000000000 +2A6C:00000000000000649800FC0064980000 +2A6D:000000001000324C007E007E00000000 +2A6E:000000002A1C081C2A007F007F000000 +2A6F:00000030488400649800649800000000 +2A70:00000000649800649800FC00FC000000 +2A71:00000000007C007C0010107C10100000 +2A72:000000000010107C1010007C007C0000 +2A73:000000000000007E007E00324C000000 +2A74:00000000000000000000000000002BF8000000002BF800000000000000000000 +2A75:00000000000000000000000000007E7E0000000000007E7E0000000000000000 +2A76:00000000000000000000000000007BDE000000007BDE00000000000000000000 +2A77:00000000000024007E00007E00240000 +2A78:00000000000000000000124800003FFC00003FFC00003FFC0000000000000000 +2A79:0000000000000000003000C003000C4010A00C40030000C00030000000000000 +2A7A:000000000000000018000600018004600A100460018006001800000000000000 +2A7B:1800240008000800003008C003000C0010000C00030000C00030000000000000 +2A7C:0030004800100010180006100180006000100060018006001800000000000000 +2A7D:0000000000000000000000600180060008000600018008600600018000600000 +2A7E:000000000000000000000C00030000C0002000C003000C2000C003000C000000 +2A7F:0000000000000000000000600180060008400600018008600600018000600000 +2A80:000000000000000000000C00030000C0082000C003000C2000C003000C000000 +2A81:0000000000000000040000600180060008000600018008600600018000600000 +2A82:000000000000000000400C00030000C0002000C003000C2000C003000C000000 +2A83:0000000000000020000000600180060008000600018008600600018000600000 +2A84:000000000000080000000C00030000C0002000C003000C2000C003000C000000 +2A85:000000000000006001800600080006000180006000000000071008E0071008E0 +2A86:0000000000000C00030000C0002000C003000C00000000000E2011C00E2011C0 +2A87:00000000000000000060018006000800060001800060004000800FE002000400 +2A88:00000000000000000C00030000C0002000C003000C00004000800FE002000400 +2A89:0000006001800600080006000180006000100020075008E007100AE004000800 +2A8A:00000C00030000C0002000C003000C00002000400EA011C00E2015C008001000 +2A8B:00186080601800FC00FC006018041860 +2A8C:00601804186000FC00FC001860806018 +2A8D:000000000000006001800600080006000180006000000000071008E000000FF0 +2A8E:0000000000000C00030000C0002000C003000C00000000000E2011C000001FE0 +2A8F:00061820180600324C00601804186000 +2A90:00601804186000324C00061820180600 +2A91:000C3040300C6018041860007C007C00 +2A92:0060180418600C3040300C007C007C00 +2A93:000C3040300C40300C60180418620C30 +2A94:00300C020C30020C300618201846300C +2A95:0000000000000000000000600180060008600180060008000600018000600000 +2A96:000000000000000000000C00030000C00C20030000C0002000C003000C000000 +2A97:0000000000000000000000600180060008600180060008400600018000600000 +2A98:000000000000000000000C00030000C00C20030000C0042000C003000C000000 +2A99:00000000000000000FE000000FE0000000600180060008000600018000600000 +2A9A:00000000000000000FE000000FE000000C00030000C0002000C003000C000000 +2A9B:0000000000600180060008600180060008600180060008000600018000600000 +2A9C:000000000C00030000C00C20030000C00C20030000C0002000C003000C000000 +2A9D:00000000000000000000071008E00000003000C003000400030000C000300000 +2A9E:0000000000000000071008E0000000000C00030000C0002000C003000C000000 +2A9F:00000000071008E00000003000C003000400030000C0003000000FF000000FF0 +2AA0:0000000008E0071000000C00030000C0002000C003000C0000000FF000000FF0 +2AA1:00000000000000000000003000C003300CC011000CC0033000C0003000000000 +2AA2:0000000000000000000018000600198006600110066019800600180000000000 +2AA3:0000000000000000018C063018C0210018C00630018C00003FFC000000000000 +2AA4:0000000000000000060C01B000E0011000E001B0060C00000000000000000000 +2AA5:0000000000000000400430180C6002800C603018400400000000000000000000 +2AA6:000000000000000000000000000000C003200C1010100C10032000C000000000 +2AA7:0000000000000000000000000000060009801060101010600980060000000000 +2AA8:0000000000000000000000C003200C1010100C10032010C00C00030000C00000 +2AA9:0000000000000000000006000980106010101060098006100060018006000000 +2AAA:00000000000000000000003000C003000C001FF00C00030000C0003000000000 +2AAB:0000000000000000000018000600018000601FF0006001800600180000000000 +2AAC:000000000000003000C003000C001FF00C00030000C0003000001FF000000000 +2AAD:00000000000018000600018000601FF0006001800600180000001FF000000000 +2AAE:000000000000000000000000038004403C7800003FF800003FF8000000000000 +2AAF:0000000000000010002000C003001C00030000C00020001000001FF000000000 +2AB0:00000000000008000400030000C0003800C003000400080000000FF800000000 +2AB1:0000000000000010002000C003001C00030000C00020005000801FF002000400 +2AB2:00000000000010000800060001800070018006000800108001001FF004000800 +2AB3:00000010002000C003001C00030000C00020001000001FF000001FF000000000 +2AB4:000010000800060001800070018006000800100000001FF000001FF000000000 +2AB5:00000010002000C003001C00030000C00020003000401FF001001FF004000800 +2AB6:000010000800060001800070018006000800104000801FF002001FF008001000 +2AB7:0010002000C003001C00030000C000200010000007900860071008E000000000 +2AB8:10000800060001800070018006000800100000000E2011C00E2011C000000000 +2AB9:0010002000C003001C00030000C0002000500040079008E0071009E002000200 +2ABA:10000800060001800070018006000800108000800F2011C00E2013C004000400 +2ABB:0000000000000042008403180C6073800C600318008400420000000000000000 +2ABC:0000000000004200210018C0063001CE063018C0210042000000000000000000 +2ABD:0000000000000000000000000FF81000200026002600200010000FF800000000 +2ABE:0000000000000000000000003FE00010000800C800C8000800103FE000000000 +2ABF:0000003E4040403E0008083E08080000 +2AC0:0000007C0202027C0010107C10100000 +2AC1:0000003E4040403E0022140814220000 +2AC2:0000007C0202027C0044281028440000 +2AC3:000000001818003E4040403E007E0000 +2AC4:000000003030007C0202027C007E0000 +2AC5:00000000003E4040403E007E007E0000 +2AC6:00000000007C0202027C007E007E0000 +2AC7:0000000000003E404040403E00324C00 +2AC8:0000000000007C020202027C00324C00 +2AC9:00000000003E4040403E00324C324C00 +2ACA:00000000007C0202027C00324C324C00 +2ACB:000000003E4040403E00047E087E1000 +2ACC:000000007C0202027C00047E087E1000 +2ACD:00000000000000007FFE400040004000400040004000400040007F0000000000 +2ACE:00000000000000007FFE0002000200020002000200020002000200FE00000000 +2ACF:00000000000000000000000007F008101010101010101010081007F000000000 +2AD0:0000000000000000000000001FC01020101010101010101010201FC000000000 +2AD1:000000000000000007F008101010101010101010081007F000001FF000000000 +2AD2:00000000000000001FC01020101010101010101010201FC000001FF000000000 +2AD3:0000003E4040403E007C0202027C0000 +2AD4:0000007C0202027C003E4040403E0000 +2AD5:0000003E4040403E003E4040403E0000 +2AD6:0000007C0202027C007C0202027C0000 +2AD7:00000000000000000000000000003E3E0140014001403E3E0000000000000000 +2AD8:00000000000000000000000000003E3E014007F001403E3E0000000000000000 +2AD9:000000000000000007C009201110111011101110111011101110111000000000 +2ADA:000000000FE0010007C009201110111011101110111011101110111000000000 +2ADB:000000000100010007C009201110111011101110111011101110111001000100 +2ADC:000000000000000001000110012001400180111013101510092017C000000000 +2ADD:000000000000000001000100010001000100111011101110092007C000000000 +2ADE:0000000000040404043C040404040000 +2ADF:000000000000000000000000000000001FF00100010001000000000000000000 +2AE0:000000000000000000000000000000000100010001001FF00000000000000000 +2AE1:000000000000010001000138014001300108017001003FF80000000000000000 +2AE2:00000000000000000000200020003FF020003FF020003FF02000200000000000 +2AE3:0000000000000000000000140014001400143FF4001400140014001400000000 +2AE4:000000000000000000000008000800081FF800081FF800080008000800000000 +2AE5:000000000000000000000014001400143FF400143FF400140014001400000000 +2AE6:0000000000000000000028002800280028003FFC280028002800280000000000 +2AE7:0000000000000000000000001FF000001FF00100010001000000000000000000 +2AE8:0000000000000000000000000100010001001FF000001FF00000000000000000 +2AE9:0000000000000100010001001FF000001FF00100010001000000000000000000 +2AEA:00000000000000001FF002800280028002800280028002800280028000000000 +2AEB:00000000000000000280028002800280028002800280028002801FF000000000 +2AEC:000000000000000000000000000000001FF800081FF800080008000000000000 +2AED:000000000000000000000000000000001FF810001FF810001000000000000000 +2AEE:000000001818583818181C1A18180000 +2AEF:00000000384444381010101010100000 +2AF0:00000000101010101010384444380000 +2AF1:000000007C1010101010384444380000 +2AF2:0000000014141414147F141414140000 +2AF3:00000000000000000240024002400240024007500AE002400240024000000000 +2AF4:0000000000000000092009200920092009200920092009200920092000000000 +2AF5:0000000000000000092009200920092009203FF8092009200920092000000000 +2AF6:00000000181800001818000018180000 +2AF7:0000000000000018006001980660199822201998066001980060001800000000 +2AF8:00000000000030000C0033000CC03330088833300CC033000C00300000000000 +2AF9:0000000000600180060008000600018008600600018008600600018000600000 +2AFA:000000000C00030000C0002000C003000C2000C003000C2000C003000C000000 +2AFB:0000000000000000024802480490049009200920124012402480248000000000 +2AFC:0000000000000000092009200920092009200920092009200920092009200000 +2AFD:0000000000000000009000900120012002400240048004800900090000000000 +2AFE:00000000003828282828282828380000 +2AFF:00000000382828282828282828283800 +2B00:00000000000001F8010800880108022804580880110022001400080000000000 +2B01:0000000000003F00210022002100288034400220011000880050002000000000 +2B02:000000000000080014002200110008800458022801080088010801F800000000 +2B03:00000000000000200050008801100220344028802100220021003F0000000000 +2B04:0000000000000000081018182FF440022FF41818081000000000000000000000 +2B05:0000000000000000080018003FFC7FFC3FFC1800080000000000000000000000 +2B06:000010387CFE38383838383838380000 +2B07:00003838383838383838FE7C38100000 +2B08:00000000000001F801F800F801F803F807D80F801F003E001C00080000000000 +2B09:0000000000003F003F003E003F003F8037C003E001F000F80070002000000000 +2B0A:00000000000008001C003E001F000F8007D803F801F800F801F801F800000000 +2B0B:0000000000000020007000F801F003E037C03F803F003E003F003F0000000000 +2B0C:0000000000000000081018183FFC7FFE3FFC1818081000000000000000000000 +2B0D:000010387CFE38383838FE7C38100000 +2B0E:0000000000000000000000000000FFF80008002A001C00080000000000000000 +2B0F:0000000000000008001C002A0008FFF800000000000000000000000000000000 +2B10:00000000000000000000000000001FFF10005400380010000000000000000000 +2B11:00000000000010003800540010001FFF00000000000000000000000000000000 +2B12:000000000000000000001FF81FF81FF81FF81FF810081008100810081FF80000 +2B13:000000000000000000001FF810081008100810081FF81FF81FF81FF81FF80000 +2B14:000000000000000000001FF81FF817F813F811F810F81078103810181FF80000 +2B15:000000000000000000001FF818081C081E081F081F881FC81FE81FF81FF80000 +2B16:000000000000000000000180034007200F101F081F080F100720034001800000 +2B17:00000000000000000000018002C004E008F010F810F808F004E002C001800000 +2B18:00000000000000000000018003C007E00FF01FF8100808100420024001800000 +2B19:00000000000000000000018002400420081010081FF80FF007E003C001800000 +2B1A:0000000000002AA80000200800002008000020080000200800002AA800000000 +2B1B:00007FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE0000 +2B1C:00007FFE4002400240024002400240024002400240024002400240027FFE0000 +2B1D:00000000000000003C3C3C3C00000000 +2B1E:00000000000000003C24243C00000000 +2B1F:000000000000018003C007E00FF01FF83FFC1FF81FF80FF00FF007E000000000 +2B20:000000000000018002400420081010082004100810080810081007E000000000 +2B21:0000000000000000010006C0183020082008200820082008183006C001000000 +2B22:0000000000000000010007C01FF03FF83FF83FF83FF83FF81FF007C001000000 +2B23:000000000000000007E00FF01FF83FFC7FFE7FFE3FFC1FF80FF007E000000000 +2B24:0000000001C007F00FF81FFC1FFC3FFE3FFE3FFE1FFC1FFC0FF807F001C00000 +2B25:0000000000000010387CFE7C38100000 +2B26:00000000000000102844824428100000 +2B27:0000001038387C7CFE7C7C3838100000 +2B28:00000010282844448244442828100000 +2B29:00000000000010387C38100000000000 +2B2A:000000000000001038387C3838100000 +2B2B:00000000000000102828442828100000 +2B2C:000000000000000000000000000000000FE07FFCFFFEFFFE7FFC0FE000000000 +2B2D:000000000000000000000000000000000FE0701C80028002701C0FE000000000 +2B2E:00183C3C3C7E7E7E7E7E3C3C3C180000 +2B2F:00182424244242424242242424180000 +2B30:0000000000000000000010E021107FFF211010E0000000000000000000000000 +2B31:2040FF40202040FF40202040FF402000 +2B32:000000000000000001C012A024907FFF249012A001C000000000000000000000 +2B33:00000000000000000000100024447AAB21101000000000000000000000000000 +2B34:00000000000000000000142028207FFF28201420000000000000000000000000 +2B35:00000000000000000000145028507FFF28501450000000000000000000000000 +2B36:00000000000000000000140228027FFE28021402000000000000000000000000 +2B37:00000000000000000000140228047ED828041402000000000000000000000000 +2B38:0000000000000000000010002000755520001000000000000000000000000000 +2B39:00000000000000000000104220447FF820441042000000000000000000000000 +2B3A:0000000000000000000010A220A47FF820A410A2000000000000000000000000 +2B3B:00000000000000000000140228047FF828041402000000000000000000000000 +2B3C:00000000000000000000144228447FF828441442000000000000000000000000 +2B3D:0000000000000000000014A228A47FF828A414A2000000000000000000000000 +2B3E:00000000000000000800108820507FFF20501088080000000000000000000000 +2B3F:00000000000000000000103C20427F8120001000000000000000000000000000 +2B40:00000000000001F8000011F820007FFF20001000000000000000000000000000 +2B41:000000000000001C022211C020007FFF20001000000000000000000000000000 +2B42:00000000000000000000100020007FFF201C122201C0001C022201C000000000 +2B43:00000000000060001800060801840FFE01840608180060000000000000000000 +2B44:000000000000000000007F80004800247FFE002400487F800000000000000000 +2B45:00000000020004000FFF10003FFF40003FFF10000FFF04000200000000000000 +2B46:0000000000400020FFF00008FFFC0002FFFC0008FFF000200040000000000000 +2B47:0000000000000380444038080004FFFE00040008000000000000000000000000 +2B48:0000000000000000000000080004FFFE03844448380003804440380000000000 +2B49:00000000000001C00222101C20007FFF20001000000000000000000000000000 +2B4A:00000000000000000000100020007FFF21C01222001C01C00222001C00000000 +2B4B:00000000000000000000100020007FFF2000101C022201C00000000000000000 +2B4C:0000000000000000000000080004FFFE00040388444038000000000000000000 +2B4D:00000000008001000200040008001FF800100020004002800300038000000000 +2B4E:000000000000001C0C14102020000000 +2B4F:00000000000000202010140C1C000000 +2B50:000001000100028002807C7C20081010082004400820111026C8383800000000 +2B51:0000000000000100038003803FF81FF00FE00FE01EF03C783018000000000000 +2B52:0000000000000100028002803C7810100820092012902C683018000000000000 +2B53:00000000008003C00FE01FF01FF81FFC1FFC1FF81FF00FE003C0008000000000 +2B54:00000000008003400C201010100810041004100810100C200340008000000000 +2B55:000007C00FE018303018600C600C600C600C600C301818300FE007C000000000 +2B56:0000000000000FE01FF0301867CC682C682C67CC30181FF00FE0000000000000 +2B57:000007C00FE018303018638C644C644C644C638C301818300FE007C000000000 +2B58:000000000000000003800FE00C601830183018300C600FE00380000000000000 +2B59:000007C00FE018303838644C628C610C628C644C383818300FE007C000000000 +2B5A:00000000000003C0042004200840095008E01040100010002000200000000000 +2B5B:0000000000000F00108010800840084000200020001000540038001000000000 +2B5C:0000000000000020007000A800200040004000400040008000800F8000000000 +2B5D:0000000000000F80008000800040004000400040002000A80070002000000000 +2B5E:0000000000000100010001000100020002000220021004780590062000000000 +2B5F:0000000000000000000000000000020002000220041004780590062000000000 +2B60:00000000000000000000100030007FFE30001000000000000000000000000000 +2B61:000000000100038007C001000100010001000100010001000100010001000100 +2B62:000000000000000000000008000C7FFE000C0008000000000000000000000000 +2B63:000000000100010001000100010001000100010001000100010007C003800100 +2B64:000000000000000000002008600CFFFE600C2008000000000000000000000000 +2B65:000000000100038007C00100010001000100010001000100010007C003800100 +2B66:00000000000000001E001C001C00120001000080004000200010000800000000 +2B67:0000000000000000007800380038004800800100020004000800100000000000 +2B68:0000000000000000100008000400020001000080004800380038007800000000 +2B69:000000000000000000080010002000400080010012001C001C001E0000000000 +2B6A:00000000000000000000100030007DB630001000000000000000000000000000 +2B6B:000000000100038007C001000100000001000100000001000100000001000100 +2B6C:000000000000000000000008000C6DBE000C0008000000000000000000000000 +2B6D:000000000100010000000100010000000100010000000100010007C003800100 +2B6E:00000000000000001C000C101408200420042004200420041008081007E00000 +2B6F:0000000000000000003808301028200420042004200420041008081007E00000 +2B70:0000000000000000000044004C005FFE4C004400000000000000000000000000 +2B71:0000000007C000000100038007C0010001000100010001000100010001000100 +2B72:00000000000000000000002200327FFA00320022000000000000000000000000 +2B73:0000000001000100010001000100010001000100010007C003800100000007C0 +2B74:00007FFE618E7DB6618E6FB6618E7FFE7FFE61B67DB67B8677F677F67FFE0000 +2B75:00007FFE618E7DB6618E6FB6618E7FFE7FFE61867DBE7B8677F677867FFE0000 +2B76:00000000000000000FC000000780070007000480004000200010000800000000 +2B77:000000000000000001F8000000F0007000700090010002000400080000000000 +2B78:0000000000000000080004000200010000900070007000F0000001F800000000 +2B79:00000000000000000008001000200040048007000700078000000FC000000000 +2B7A:00000000000000000140114031407FFE31401140014000000000000000000000 +2B7B:000000000100038007C001000100010001000FE001000FE00100010001000100 +2B7C:000000000000000002800288028C7FFE028C0288028000000000000000000000 +2B7D:0000000001000100010001000FE001000FE0010001000100010007C003800100 +2B7E:000000000000000044004C005FFE4C004400002200327FFA0032002200000000 +2B7F:0000000004F804000420047004F804200420042004201F200E20042000201F20 +2B80:000000000000100030007FFE300010000008000C7FFE000C0008000000000000 +2B81:0000000004200E201F200420042004200420042004200420042004F804700420 +2B82:0000000000000008000C7FFE000C0008100030007FFE30001000000000000000 +2B83:000000000420047004F8042004200420042004200420042004201F200E200420 +2B84:00000000100030007FFE300010000000100030007FFE30001000000000000000 +2B85:0000000008201C703EF808200820082008200820082008200820082008200820 +2B86:000000000008000C7FFE000C000800000008000C7FFE000C0008000000000000 +2B87:00000000082008200820082008200820082008200820082008203EF81C700820 +2B88:000003E007F00EF81CFC38FC30002000300038FC1CFC0EF807F003E000000000 +2B89:0000000003E007700E381C1C380E30063E3E3E3E3E3E1E3C0E38063000000000 +2B8A:000007C00FE01F703F383F1C000C0004000C3F1C3F381F700FE007C000000000 +2B8B:0000000006300E381E3C3E3E3E3E3E3E3006380E1C1C0E38077003E000000000 +2B8C:00000000080018003FF0180808040002000200020002000400080FF000000000 +2B8D:0000000000000008001C103E1008100810081008100810080810042003C00000 +2B8E:0000000007F80800100020002000200020001008080C07FE000C000800000000 +2B8F:00000000000000F0010802040402040204020402040204021F020E0004000000 +2B90:00000000000000000000001E00020004100430087FF830001000000000000000 +2B91:000000000000000000007800400020002008100C1FFE000C0008000000000000 +2B92:000000000000000000007F7E00020002020206026FFE06000200000000000000 +2B93:000000000000000000007EFE40004000404040607FF600600040000000000000 +2B94:00000000002000403EFC20442024A8007004200E0015240422043F7C02000400 +2B95:0000000000000000002000307FF87FFC7FF80030002000000000000000000000 +2B96:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6DBE718E7DB673CE7FFE0000 +2B97:000000007FFC40044FE420082FE8111011100920092005400440028001000000 +2B98:00000004003800C803100C10302040403FE00FF003F000F80038000400000000 +2B99:00000000010002800280064006400E200E201E101F103E883C68301840040000 +2B9A:000040003800260011801060081804040FF81FE01F803E003800400000000000 +2B9B:00000000400430182C7822F811F010F008E008E004C004C00280028001000000 +2B9C:00000004003800F803F00FF03FE07FC03FE00FF003F000F80038000400000000 +2B9D:0000000001000380038007C007C00FE00FE01FF01FF03EF83C78301840040000 +2B9E:0000400038003E001F801FE00FF807FC0FF81FE01F803E003800400000000000 +2B9F:00000000400430183C783EF81FF01FF00FE00FE007C007C00380038001000000 +2BA0:00000002000200020002100230027FFE30001000000000000000000000000000 +2BA1:000040004000400040004008400C7FFE000C0008000000000000000000000000 +2BA2:00000000000000000000100030007FFE30021002000200020002000200000000 +2BA3:000000000000000000000008000C7FFE400C4008400040004000400000000000 +2BA4:0000000004000E001F0004000400040004000400040004000400040007F00000 +2BA5:00000000004000E001F00040004000400040004000400040004000401FC00000 +2BA6:0000000007F00400040004000400040004000400040004001F000E0004000000 +2BA7:000000001FC000400040004000400040004000400040004001F000E000400000 +2BA8:0000000000000002100230067FFCFFFC7FF83000100000000000000000000000 +2BA9:00000000000080008010C0187FFC7FFE3FFC0018001000000000000000000000 +2BAA:0000000000000000100030007FF8FFFC7FFC3006100200020000000000000000 +2BAB:0000000000000000001000183FFC7FFE7FFCC018801080000000000000000000 +2BAC:000000000000020007000F801FC0070007000700070007000700038000E00000 +2BAD:0000000000000100038007C00FE003800380038003800380038007001C000000 +2BAE:00000000000000E003800700070007000700070007001FC00F80070002000000 +2BAF:0000000000001C0007000380038003800380038003800FE007C0038001000000 +2BB0:000000220036002A0022002204220A2213FC20044008201013E00A0004000000 +2BB1:000044006C00540044004400442044503FC820041002080407C8005000200000 +2BB2:000004000A0013E020104008200413FC0A22042200220022002A003600220000 +2BB3:00000020005007C80804100220043FC8445044204400440054006C0044000000 +2BB4:000004000A00110020804040318011001100110011FE09040508030400FE0000 +2BB5:000000200050008801040202018C0088008800887F88209010A020C07F000000 +2BB6:000000FE03040508090411FE11001100110031804040208011000A0004000000 +2BB7:00007F0020C010A020907F88008800880088018C020201040088005000200000 +2BB8:00000100028004400FE010100C600440044007C0000007C0044007C000000000 +2BB9:0000000000007FFC4004410442844444482450144004400440047FFC00000000 +2BBA:0000000003FC0204020402043FC42244224423FC2040204020403FC000000000 +2BBB:0000000003FC03FC03FC03FC3FFC23FC23FC23FC2040204020403FC000000000 +2BBC:0000000003FC03FC03FC03FC3FFC3FFC3FFC3FFC3FC03FC03FC03FC000000000 +2BBD:000000003FFC20042004241422242144208421442224241420043FFC00000000 +2BBE:0000000007C00820101020082448428441044284244820081010082007C00000 +2BBF:0000000007C01FF038383018644C628C610C628C644C301838381FF007C00000 +2BC0:0000000000007FFC7FFC7FFC7FFC7FFC7FFC7FFC7FFC7FFC7FFC7FFC00000000 +2BC1:0000000000000100038007C00FE01FF03FF81FF00FE007C00380010000000000 +2BC2:00000000000007E00FF00FF01FF81FF83FFC3FFC1FF80FF007E003C001800000 +2BC3:0000000007C00FE01FF03FF87FFC7FFC7FFC7FFC7FFC3FF81FF00FE007C00000 +2BC4:0000038007C03FF83FF83FF87FFCFFFEFFFEFFFE7FFC3FF83FF83FF807C00380 +2BC5:0000000001000380038007C007C00FE00FE01FF01FF03FF83FF87FFC00000000 +2BC6:0000000000007FFC3FF83FF81FF01FF00FE00FE007C007C00380038001000000 +2BC7:00000008003800F803F80FF83FF87FF83FF80FF803F800F80038000800000000 +2BC8:0000400070007C007F007FC07FF07FF87FF07FC07F007C007000400000000000 +2BC9:0000404A4C58787E081C2222221C0000 +2BCA:0000000007C00FE01FF03FF83FF87FFC7FFC0000000000000000000000000000 +2BCB:000000000000000000000000000000007FFC7FFC3FF83FF81FF00FE007C00000 +2BCC:010001000380038007C00FE03FF8FFFE3FF80FE007C003800380010001000000 +2BCD:000000000000200810100C600FE007C007C007C00FE00C601010200800000000 +2BCE:0100010003800280044008203018E00E30180820044002800380010001000000 +2BCF:000000000000200810100C600BA00440044004400BA00C601010200800000000 +2BD0:00000000010001001FF01110111010107C7C1010111011101FF0010001000000 +2BD1:000000000100028004400BA01450204841842108101009200440028001000000 +2BD2:000000000000010001000FE0010001000FE0010001000FE00100010001000000 +2BD3:00000000000000000380044008202828282824481390082007C0010007C00100 +2BD4:000000001C702288210807C00100038004400820082008200440038000000000 +2BD5:00000000038004400820082008204444638C50144C6423881010082007C00000 +2BD6:00000000000007C008A0105020482028202820282048105008A007C000000000 +2BD7:0000000000000100038007C00100038004400BA0082008200440038000000000 +2BD8:00000000000000003C3C04200420042005A005A00420042004203C3C00000000 +2BD9:00000000000001800240027801C00040008000800100018002401E4001800000 +2BDA:000000001110210821082108193007C009201110092007C0092007C000000000 +2BDB:000000000000000001C00120012001C00100010007C00820082007C000000000 +2BDC:0000000000000000012001A0016001200100010007C00820082007C000000000 +2BDD:000000000000070002800140012000A000A00120014002800700010007C00100 +2BDE:0000000000000100038007C00FE01FF00FE007C003800100010007C001000100 +2BDF:0000000000000000000000000000200830182C681390082007C0010007C00100 +2BE0:000000000000380004000270028802880288047008203FF8002000F800200020 +2BE1:00000000000007C0082010102100210027C0210021001110092007C001000100 +2BE2:0000000000000100038007C0010001000100193007C0010006C0183000000000 +2BE3:00000000000007C0082010102108210827C80100010001000100010001000100 +2BE4:000000000000380004000200020002500250045008503FF80050005000500050 +2BE5:0000000000000000044004400380054007C00540038001000100010001000100 +2BE6:0000000000000100038007C00100010001000100010002800440082010103FF8 +2BE7:0000000000000000200820081110092007C00100010007C00920111020082008 +2BE8:00000040004000C000C001C01FC00FC007C003C001C003C00780060008000000 +2BE9:00000400040006000600070007F007E007C007800700078003C000C000200000 +2BEA:0000010001000380038007407F3C3F081F100F6007400F201ED0183020080000 +2BEB:0000010001000380038005C079FC21F811F00DE005C009E016F0183020080000 +2BEC:00000000020806180E381E783EF87FFE3EF81E780E3806180208000000000000 +2BED:00000100038007C00FE01FF03FF80100038007C00FE01FF03FF8010001000000 +2BEE:00000000104018601C701E781F7C7FFE1F7C1E781C7018601040000000000000 +2BEF:0000008000801FFC0FF807F003E001C000801FFC0FF807F003E001C000800000 +2BF0:0000000000003938054003800380010001000100038003800540393800000000 +2BF1:0000000000000380044008200820082004400380010007C00380010000000000 +2BF2:00000000000000001900250025001FC001000180004000200020002000000000 +2BF3:00000000000000003FF8200820082008200820083FF8010006C0183000000000 +2BF4:00000000000000007FFC410422881450082008201450228841047FFC00000000 +2BF5:0000000000000000410441042288145008200820145022884104410400000000 +2BF6:00000000000000003FF8200820082008200820083FF8010001001FF000000000 +2BF7:00000000000000001010082004400280010002800440082010103FF800000000 +2BF8:000000000000000001000100010001003FF80380054009201110210800000000 +2BF9:000000000000000000003FF800003FF800001C702288210822881C7000000000 +2BFA:00000000000000000000000000001C702288228822881C700000000000000000 +2BFB:0000000000000000000000000000701C88228AA28822701C0000000000000000 +2BFC:0000000000000380044004400440038000000380044004400440038000000000 +2BFD:0000000000000100038007C00100010001000380044004400440038000000000 +2BFE:00000000000000000000000000000020002000200020002000200FE000000000 +2BFF:000000007C7C10101C1C10107C7C0000 +2C00:00000000101010107C54541010100000 +2C01:0000000092929292FE80808080FE0000 +2C02:0000000044AA6C284444444444380000 +2C03:000000006090907020204C52928C0000 +2C04:00000000384444444444286CAA440000 +2C05:000000003844041C041C040444380000 +2C06:000000000000824428286C92926C0000 +2C07:000000003844824438FE926428100000 +2C08:000000000020508888FF8D8D55220000 +2C09:000000007C6C92927C10101010380000 +2C0A:000000007C6C92926C28444482FE0000 +2C0B:00000000FE8244285482828244380000 +2C0C:00000000626565669696969991000000 +2C0D:000000002020203C04043C2020200000 +2C0E:0000000038444444447CAAAAAA440000 +2C0F:00000000000000000FF812A412A40C98008003E0077009480948063000000000 +2C10:000000003C222222FCA0A02020200000 +2C11:000000001C221E020202021E221C0000 +2C12:000000003E2A2A2AE420202020200000 +2C13:00000000404040407C424242427C0000 +2C14:00000000384482828254284482FE0000 +2C15:00000000FEAAAAAAAAAAAAAAAA440000 +2C16:0000000048B46C242724246CB4480000 +2C17:00000000101038549292929254381010 +2C18:000000002020202020202C32528C0000 +2C19:000000007CAAAA92828292AAAA7C0000 +2C1A:000000001E1212127292929292720000 +2C1B:0000000092929292FE44828244380000 +2C1C:000000007191916A0A0A0A0404040000 +2C1D:0000000044447C92FE44828244380000 +2C1E:00000000929292929292929292FE0000 +2C1F:000000000000000003F8011000A000E01F10151008E000A0011003F800000000 +2C20:000000007E422418F898A424427E0000 +2C21:0000000010282844447C929292FE0000 +2C22:00002090786C4482828282446C3C1208 +2C23:000000007C4A4A4A4C50506060400000 +2C24:000000001C222060B8602020221C0000 +2C25:000000000C121030DCB01010120C0000 +2C26:0000000010284C92FE444444447C0000 +2C27:00000000000000001C38224402400EC003700EC00240024022441C3800000000 +2C28:0000000000000000387044883C80058006E0058004803C804488387000000000 +2C29:0000000000000000103828444C4092C0FF7038C0444082404444383800000000 +2C2A:0000000018242424FFA5242424180000 +2C2B:00000000F88850708E8A705088F80000 +2C2C:000000001C0404040404040408100000 +2C2D:0000000082C2B28AFE8AB2C282020000 +2C2E:00000000245456525252565A52520000 +2C2F:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61867DBE618E6FBE61BE7FFE0000 +2C30:0000000000001010107C545410100000 +2C31:0000000000002A2A2A3E2020203E0000 +2C32:00000000000044AA6C28444444380000 +2C33:000000000000609090702C52928C0000 +2C34:00000000000038444444286CAA440000 +2C35:00000000000038441C041C0444380000 +2C36:0000000000000000C6286C92926C0000 +2C37:0000000000001C221C7F493214080000 +2C38:00000000000000205088FF8D55220000 +2C39:0000000000007C6C92927C1010380000 +2C3A:0000000000007C6C92926C4482FE0000 +2C3B:000000000000FE824428544444380000 +2C3C:000000000000444A4AACACB2A2000000 +2C3D:00000000000020203C04043C20200000 +2C3E:000000000000182424243C5A5A240000 +2C3F:0000000000000000000000001FF025481930010007C00EE012900C6000000000 +2C40:0000000000001C12127C505010100000 +2C41:0000000000001C221E02021E221C0000 +2C42:0000000000003E2A2A2A642020200000 +2C43:00000000000040404078444444780000 +2C44:00000000000038444454284482FE0000 +2C45:000000000000FEAAAAAAAAAAAA440000 +2C46:00000000000048B46C26246CB4480000 +2C47:00000000000010103854929254381010 +2C48:000000000000202020202C32528C0000 +2C49:0000000000007CAA92828292AA7C0000 +2C4A:0000000000000E0A0A3A4A4A4A3A0000 +2C4B:0000000000002A2A2A3E1422221C0000 +2C4C:00000000000062A2A274141408080000 +2C4D:000000000000447C92FE444444380000 +2C4E:000000000000545454545454547C0000 +2C4F:00000000000000000000000003F8011000E01F10151008E0011003F800000000 +2C50:0000000000003E2214784854223E0000 +2C51:000000000000001028447C9292FE0000 +2C52:000000002090786C448282446C3C1208 +2C53:00000000000078545458505060400000 +2C54:0000000000000C12305C3010120C0000 +2C55:000000000000040A186E58080A040000 +2C56:00000000000010284C92FE44447C0000 +2C57:0000000000000000000000001C3822440EC003700EC0024022441C3800000000 +2C58:0000000000000000000000001C3822441EC0037002C01E4022441C3800000000 +2C59:000000000000000000000000081C1422266049B87F601C2022221C1C00000000 +2C5A:000000000000102828FEAA2828100000 +2C5B:0000000000007848304E4A3048780000 +2C5C:0000000000001C040404040408100000 +2C5D:0000000000000262524A7E4A52620000 +2C5E:00000000000024545652565A52520000 +2C5F:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61866FBE618E7DBE61BE7FFE0000 +2C60:000000002020207020702020203E0000 +2C61:000000180808081C081C0808083E0000 +2C62:000000001010101034581010101F0000 +2C63:000000003C2272223C20202020200000 +2C64:000000007C4242427C48444442425020 +2C65:0000000000003946043C54644CB40000 +2C66:000000001010117E14181030508C0000 +2C67:00000000444444447C44444444460202 +2C68:00000040404058644444444444460202 +2C69:00000000424448506060504844430101 +2C6A:00000040404044485060504844430101 +2C6B:000000007E02020408102040407E0202 +2C6C:0000000000007E0204081020407E0202 +2C6D:000000001A26424242424242261A0000 +2C6E:00000000424266665A5A424242420A04 +2C6F:00000000424242427E42422424180000 +2C70:000000004C52624242424242625C0000 +2C71:00000000000082858548484830300000 +2C72:00000000848A8A88A8A8D8D888880000 +2C73:00000000000042555554545454280000 +2C74:0000000020505262C224242418180000 +2C75:00000000202020203C20202020200000 +2C76:0000000000002020203C202020200000 +2C77:000000000000264949494949493E0808 +2C78:0000000000003844447C4045453A0000 +2C79:000000000C02020202020242463A0000 +2C7A:0000000000003E4141414955553E0000 +2C7B:0000000000003E0202021E02023E0000 +2C7C:000000000000000004000C0404041408 +2C7D:00000041412222141408000000000000 +2C7E:000000003C424040300C0202423C0906 +2C7F:000000007E020404081020204060100E +2C80:00000000C0201010384844444A310000 +2C81:000000000000C020103844444A310000 +2C82:000000007844444878444442427C0000 +2C83:00000000000070485070484444780000 +2C84:000000007E4040404040404040400000 +2C85:0000000000007C404040404040400000 +2C86:0000000010080C0C14121212A1FF0000 +2C87:000000000000201018181414A2FE0000 +2C88:000000003C664280FE808042663C0000 +2C89:0000000000003C4280FE8080423C0000 +2C8A:000000003A4440404020100804040800 +2C8B:0000000000003A444040201804040800 +2C8C:00000080FE0202040810204040FE0200 +2C8D:000000000080FE020408102040FE0200 +2C8E:00000000424242427E42424242420000 +2C8F:0000000000004242427E424242420000 +2C90:00000000182424A4FF25242424180000 +2C91:0000000000001824A4FF252424180000 +2C92:00000000301010101010101010080000 +2C93:00000000000030101010101010080000 +2C94:000000004C4448507048444242420000 +2C95:0000000000004C444850704844420000 +2C96:0000000060101808080C142442830000 +2C97:000000000000C0201010182844860000 +2C98:000000008282C6AA9282828282820000 +2C99:000000000000446C5444444444440000 +2C9A:000000008282C2A292928A8682820000 +2C9B:00000000000044646454544C4C440000 +2C9C:00000080FF020C30F80402020C7F0100 +2C9D:000000000080FC041860F008187E0200 +2C9E:00000000386C4482828282446C380000 +2C9F:000000000000386C448282446C380000 +2CA0:00000000FF4242424242424242420000 +2CA1:0000000000007E242424242424240000 +2CA2:000000007C4242427C40404040404040 +2CA3:0000000000007C4242427C4040404040 +2CA4:000000001C36224040404022361C0000 +2CA5:0000000000001C3622404022361C0000 +2CA6:00000000FE1010101010101010100000 +2CA7:000000000000FE101010101010100000 +2CA8:00000000838244281010101010100000 +2CA9:00000000000083442810101010100000 +2CAA:00001010387C5492929292547C381010 +2CAB:000000001010387C549292547C381010 +2CAC:00000000434224181818242442420000 +2CAD:00000000000043241818242442420000 +2CAE:00001010939254381010101010101000 +2CAF:00000000101093543810101010101000 +2CB0:000000004492929292929292926C0000 +2CB1:000000000000449292929292926C0000 +2CB2:0000000000101010FE00000000000000 +2CB3:000000000000000010107C0000000000 +2CB4:00000000040810204620100804000000 +2CB5:00000000000000081020442010080000 +2CB6:0000000002FE000002FE000002FE0000 +2CB7:000000000000027E00027E00027E0000 +2CB8:0000004040201008040810207C000000 +2CB9:000000000000202010080408103C0000 +2CBA:000000000000000002FE000000000000 +2CBB:000000000000000000027E0000000000 +2CBC:00000000929292929292929292920000 +2CBD:00000000000092929292929292920000 +2CBE:0000000092929292FF92929292920000 +2CBF:000000000000929292FF929292920000 +2CC0:000000003C2222223C20FEA020202020 +2CC1:0000000000003C2222223C20FEA02020 +2CC2:54107C1044929292929292926E027C80 +2CC3:000054107C104492929292926E027C80 +2CC4:000000407E020C307804020202047800 +2CC5:0000000000407C0408103C0202423C00 +2CC6:00000000040404080808081010102020 +2CC7:00000000000004040808081010102020 +2CC8:000000003C424202047E1020423C0000 +2CC9:0000000000003C4242047E30423C0000 +2CCA:000000003C424A320204081020400000 +2CCB:0000000000003C424A32040810200000 +2CCC:0000000078C4C202047C02020202827C +2CCD:00000000000078C4C2023C040202827C +2CCE:000000001E1111212220204040408080 +2CCF:0000000000001E112121224040408080 +2CD0:000000004040404040404040427E0000 +2CD1:000000000000404040404040447C0000 +2CD2:000000000204081020404C52423C0000 +2CD3:000000000000040810204C52423C0000 +2CD4:000C1020180808080808080808180000 +2CD5:0000000C102018080808080808180000 +2CD6:000000002020202020202020227EA040 +2CD7:000000000000101010101010123E5020 +2CD8:00000000424242424242424242FF0000 +2CD9:000000000000242424242424247E0000 +2CDA:0000000010080C0C54321A16A3FF0000 +2CDB:00000000000010080C2C1A0E537F0000 +2CDC:003C4040386C4482828282446C380000 +2CDD:0000003C4040386C448282446C380000 +2CDE:000000007E22202020202020223E0000 +2CDF:0000000000007E2220202020243C0000 +2CE0:00000000102649516224584080800000 +2CE1:00000000000010264972245880800000 +2CE2:00000000FC203C2222223C2020202020 +2CE3:000000000000FC203C2222223C202020 +2CE4:0000000000004C44485070484442021C +2CE5:00001E11111E1092D6BA929292921010 +2CE6:001E11111E10FE545454545454541010 +2CE7:01E00110011001E001007FFE391C6D3645228140814045226D36391C01000100 +2CE8:001E11111E107E101010101010101010 +2CE9:1E11111E101056545438383854541010 +2CEA:0000000000000000000000001FFC3636222241404140222236361C1C00000000 +2CEB:000000006C9292926C00FE0000000000 +2CEC:0000000000006C92926C00FE00000000 +2CED:00000000424242665A5A664242420000 +2CEE:0000000000004242665A5A6642420000 +2CEF:000000000C000FFC000C00000000000000000000000000000000000000000000 +2CF0:603E6000000000000000000000000000 +2CF1:067C0600000000000000000000000000 +2CF2:000810203C82424242424242423C0000 +2CF3:0000000810203C8242424242423C0000 +2CF4:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61B66FB663866FF66FF67FFE0000 +2CF5:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61866FBE63866FF66F867FFE0000 +2CF6:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +2CF7:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +2CF8:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +2CF9:00000000D8D848242424241212120000 +2CFA:0000000018181020202020404C4C0000 +2CFB:00000000303010080808080464640000 +2CFC:00000000363624484848489090900000 +2CFD:00000000000000040810100804380000 +2CFE:000000000000181010D6101030000000 +2CFF:00300804000000000000000000000000 +2D00:00000000000000007E222020203E0200 +2D01:0000000000000000C444447C0402423C +2D02:0000000000000000FC4444444442023C +2D03:0000000000407C141038444444380000 +2D04:0000000000000000FC44444444460202 +2D05:000000000000000000000000000000003FF01110111011101110111001000080 +2D06:00000040701010101C121212121C0000 +2D07:000000000000000000000000000000001FF808880888088808880F8800000000 +2D08:00000000000000007E32220202020000 +2D09:0000000020202038242424241C040404 +2D0A:000000000000000000000000000000001FF8088808880888088808F800000000 +2D0B:000000203C0404041E24242424180000 +2D0C:000000007C4440407C44444444440000 +2D0D:00000000000000000000000000000000311011101110111011101FF800000000 +2D0E:0000000000000000B2D21212121F0000 +2D0F:0000000000000000B2D21212121F0202 +2D10:0000000000000000010001000100010011F011101110111011101F1000000000 +2D11:000000004040404048484848487C0400 +2D12:0000000000000000FC44447C4040403C +2D13:00000000000000000008000800080008188808880888088808880FF800080008 +2D14:000000000000000000000000000000001FF808880888088808880FF800800080 +2D15:0000000010101016BAD0101010100000 +2D16:0000000000000000FC44444444460000 +2D17:0000000000000000622222223E020202 +2D18:00000000000000622222223E0202423C +2D19:000000002020203C2424242020202020 +2D1A:0000000000000000FC44444444444038 +2D1B:000000000000000001000100010001001FF011101110111011101F1000000000 +2D1C:000000000000000000000000000000001FF80888088808880888089808000800 +2D1D:00000000000000007C24203804242418 +2D1E:000000000000000066222222223E2020 +2D1F:00000000000000C0FE22140C12214080 +2D20:000000000000000000000000000000003F10111011101110111011F800000000 +2D21:00000000404040784C40404040400000 +2D22:00000000000000004078040404780000 +2D23:00000000040404046424243C04040404 +2D24:000000000000000000006222223E0808 +2D25:000000000000000000F00110010001001FF011101110111011101F1000000000 +2D26:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DBE618E6FB661CE7FFE0000 +2D27:00000000000000001824040830404438 +2D28:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DB661CE6FB661CE7FFE0000 +2D29:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DB661C66FF661CE7FFE0000 +2D2A:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DB661866FB661B67FFE0000 +2D2B:00007FFE618E7DB661B66FB6618E7FFE7FFE618E7DB6618E6FB6618E7FFE0000 +2D2C:00007FFE618E7DB661B66FB6618E7FFE7FFE61C67DBE61BE6FBE61C67FFE0000 +2D2D:00000000000000003C040810203C0000 +2D2E:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DBE618E6FBE61867FFE0000 +2D2F:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DBE618E6FBE61BE7FFE0000 +2D30:00000000000000000000182424180000 +2D31:00000000000000384482FE8244380000 +2D32:00000000000000385492FE9254380000 +2D33:000000000000FE442810102844820000 +2D34:00000000000082442810102844FE0000 +2D35:000000000000FE442810102844FE0000 +2D36:000000000000D6D61010101010100000 +2D37:00000000000010282828284444440000 +2D38:00000000000044444428282828100000 +2D39:00000000007E404040784040407E0000 +2D3A:00000000007E0202027E0202027E0000 +2D3B:00000018242418007E00182424180000 +2D3C:000000000000EE28282838282828EE00 +2D3D:000000000000FE84889090A8C4820000 +2D3E:0000000000606000000C0C0000606000 +2D3F:00000000000082C4A890908884FE0000 +2D40:00000000000000385492929254380000 +2D41:000000000000003A448A92A244B80000 +2D42:00001818000018180000181800001818 +2D43:00000000000001020408182442810000 +2D44:0000000000001010107C444444440000 +2D45:00000000000092543810102844820000 +2D46:00000000000000006666000066660000 +2D47:000000000000FE84889090A0C0FE0000 +2D48:0000000000000000000000000000000000001998199800000000000000000000 +2D49:00000000000810201008102010080000 +2D4A:00000000007C101010101010107C0000 +2D4B:00000000000000C62810101028C60000 +2D4C:000000000000282828FE28FE28282800 +2D4D:0000000000002424242C342424242400 +2D4E:00000000007E404040404040407E0000 +2D4F:00000000000010101010101010101000 +2D50:000000000000101010FE10FE10101000 +2D51:00000000101010101010101010001010 +2D52:000000000000003C0408182424180000 +2D53:00000000182424180000182424180000 +2D54:00000000000000384482828244380000 +2D55:00000000000000384482928A443A0000 +2D56:000000000000444444447C1010100000 +2D57:00000000181800001818000018180000 +2D58:0000000000C3C3000018180000C3C300 +2D59:000000000000003844BABABA44380000 +2D5A:000000000000003A448A928244380000 +2D5B:00000000001E294640404046291E0000 +2D5C:000000000000101010107C1010101000 +2D5D:00000000000082442810102844820000 +2D5E:00000000001E294650785046291E0000 +2D5F:00000000007E4048487C4848407E0000 +2D60:000000000000102828282844447C0000 +2D61:000000000000444444444444447C0000 +2D62:00000000000000081020100810200000 +2D63:00000092925438101010385492920000 +2D64:00000000000030282420202020200000 +2D65:0000009292543810FE10385492920000 +2D66:00000000000408102040201008040000 +2D67:000000000000000000EE000000000000 +2D68:00007FFE618E7DB661B66FB6618E7FFE7FFE73CE6FB663CE6DB673CE7FFE0000 +2D69:00007FFE618E7DB661B66FB6618E7FFE7FFE73CE6FB663C66DF673CE7FFE0000 +2D6A:00007FFE618E7DB661B66FB6618E7FFE7FFE73866FB663866DB673B67FFE0000 +2D6B:00007FFE618E7DB661B66FB6618E7FFE7FFE738E6FB6638E6DB6738E7FFE0000 +2D6C:00007FFE618E7DB661B66FB6618E7FFE7FFE73C66FBE63BE6DBE73C67FFE0000 +2D6D:00007FFE618E7DB661B66FB6618E7FFE7FFE738E6FB663B66DB6738E7FFE0000 +2D6E:00007FFE618E7DB661B66FB6618E7FFE7FFE73866FBE638E6DBE73867FFE0000 +2D6F:002424243C0000000000000000000000 +2D70:00000000000002020202040408106000 +2D71:00007FFE618E7DB661B66FB6618E7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000 +2D72:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DF67B8677BE77867FFE0000 +2D73:00007FFE618E7DB661B66FB6618E7FFE7FFE618E7DF67BC677F6778E7FFE0000 +2D74:00007FFE618E7DB661B66FB6618E7FFE7FFE61B67DB67B8677F677F67FFE0000 +2D75:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DBE7B8677F677867FFE0000 +2D76:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000 +2D77:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DF67BEE77DE77DE7FFE0000 +2D78:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000 +2D79:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DB67BC677F677CE7FFE0000 +2D7A:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DB67B8677B677B67FFE0000 +2D7B:00007FFE618E7DB661B66FB6618E7FFE7FFE618E7DB67B8E77B6778E7FFE0000 +2D7C:00007FFE618E7DB661B66FB6618E7FFE7FFE61C67DBE7BBE77BE77C67FFE0000 +2D7D:00007FFE618E7DB661B66FB6618E7FFE7FFE618E7DB67BB677B6778E7FFE0000 +2D7E:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DBE7B8E77BE77867FFE0000 +2D7F:00000000000000000000000000041F04 +2D80:000000000600060006000F000F8019C0D8C0F8FCD8D618DC18C018C000000000 +2D81:0000000007FC0FFC18A610A611461F7C0E3C0200020036003C00340000000000 +2D82:00000000000001F803E4063C6C007C006C000C000C000C00043003F000300000 +2D83:000000000600060006000F000F8019C0D8C0F800D80018001800180000000000 +2D84:0000000060607FE006000F000F8019C0D8C0F800D80018001800180000000000 +2D85:000000000000000000000F000F8019C0D8C0F800D80018001800180000000000 +2D86:00000000038006C00C600C600C600C600EC007803FF0333003003F0030000000 +2D87:000018301FF006C00C600C600C600C600EC007803FF0333003003F0030000000 +2D88:0000000007F80FCC187818001C000C0007C000C000C00CC00FC00C0000000000 +2D89:18181FF8018007F80FCC187818000C0007C000C000C00CC00FC00C0000000000 +2D8A:0000000003000300030003C000C001C031E03F70373006300630060000000000 +2D8B:000000000000000001803180B180FF80B1803180300030003000300000000000 +2D8C:0000000001C003E036203E20364007F801980300030006000E00000000000000 +2D8D:0180018001C003E036203E20364007F801980300030006000E00000000000000 +2D8E:0C300FF0018001C033E03E20364007F801980300030006000E00000000000000 +2D8F:00000000000001F003580358364C3E4C364C064C060006000600060000000000 +2D90:00000000000001FC03CC06CC0CAA0CEE6C007F006E800C4006C0038000000000 +2D91:0000000001C003E00230033001F0006000C007F006187E186300030000000000 +2D92:000000000C300FF01FF819980180018031803F80330006000C00080000000000 +2D93:01C063C07E000C001C003300638061C060C000FC00D400DC00C000C007F80E1C +2D94:00000000C0C0FFC00C001E003E007300636003E0037C030C0300030000000000 +2D95:0000000060607FE006000F001F00398031800180018001F001900FF00C000000 +2D96:01C063C07E000C001C003300638061D860D800FE00C600C000C000C007F80E1C +2D97:00007FFE618E7DB661B66FB6618E7FFE7FFE73866DF671EE7DDE73DE7FFE0000 +2D98:00007FFE618E7DB661B66FB6618E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000 +2D99:00007FFE618E7DB661B66FB6618E7FFE7FFE73CE6DB671C67DF673CE7FFE0000 +2D9A:00007FFE618E7DB661B66FB6618E7FFE7FFE73866DB671867DB673B67FFE0000 +2D9B:00007FFE618E7DB661B66FB6618E7FFE7FFE738E6DB6718E7DB6738E7FFE0000 +2D9C:00007FFE618E7DB661B66FB6618E7FFE7FFE73C66DBE71BE7DBE73C67FFE0000 +2D9D:00007FFE618E7DB661B66FB6618E7FFE7FFE738E6DB671B67DB6738E7FFE0000 +2D9E:00007FFE618E7DB661B66FB6618E7FFE7FFE73866DBE718E7DBE73867FFE0000 +2D9F:00007FFE618E7DB661B66FB6618E7FFE7FFE73866DBE718E7DBE73BE7FFE0000 +2DA0:000000001FF81998018003C003E0067036303E30363006300630063000000000 +2DA1:000000003FF033300300078007C00CE06C6C7C7C6C6C0C600C600C6000000000 +2DA2:000000003FF033300300078007C00CE06C607C606C600C600C6C0C7C000C0000 +2DA3:000000001FF81998018003C003E0067036303E30363000300030003000000000 +2DA4:000000003FF033300300078007C00CE06C607C606C600C7C0C640C7C00000000 +2DA5:000000007FE066600300078007C00CE06C607C606C600C600C600C6000000000 +2DA6:000000000FFC0CCC00C001E003E0073036303E30363006000600060000000000 +2DA7:00007FFE618E7DB661B66FB6618E7FFE7FFE61866DF661EE6DDE6DDE7FFE0000 +2DA8:000018181FF81998018001801FF81998018001801F8019800180000000000000 +2DA9:000018181FF81998018001801FF81998018001981FF819980180000000000000 +2DAA:000018181FF81998018001801FF81998018001801F80199801F8001800000000 +2DAB:000018181FF81998018001801FF81998018001801F8019800380070018001800 +2DAC:000018181FF81998018001801FF81998018001801FF0199001F0000000000000 +2DAD:000030303FF03330018001801FF81998018001801F8019800180000000000000 +2DAE:301830183BA006C00C600C600C600C600EC07FF8631803003F00330003000000 +2DAF:00007FFE618E7DB661B66FB6618E7FFE7FFE61866DBE618E6DBE6DBE7FFE0000 +2DB0:000000000000000000007C3E666606607FE06660066006600660000000000000 +2DB1:000000000000000000007C3E666606607FFE6666066006600660000000000000 +2DB2:000000000000000000007C3E666606607FE0666006600666067E000600000000 +2DB3:000000000000000000007C3E666606607FE06660066000600060000000000000 +2DB4:000000000000000000007C3E666606607FE06660067C0664067C000000000000 +2DB5:61807F800C000C007C3E666606607FE066600660066006600660000000000000 +2DB6:000000000000000000007C3E666606607FE06660066006000600000000000000 +2DB7:00007FFE618E7DB661B66FB6618E7FFE7FFE63866DF663EE6DDE63DE7FFE0000 +2DB8:000000000000000003E007F00C98188CF88CC88C1CCE1AAD1AAD1EEF00000000 +2DB9:000000000000000003E007F00C98188FF88BC8881CCC1AAA1AAA1EEE00000000 +2DBA:000000000000000003E007F00C98188CF88CC88C1CCC1AAC1AAC1EEF00030000 +2DBB:000000000000000003E007F00C981CCCFAACDAAC1EEC0018001C0032003E0000 +2DBC:000000000000000003F007F80C9B188EF88BC8881CCC1AAA1AAA1EEE00000000 +2DBD:000000000000000003F007F80CD81CCCFAEADA6A1E6E00500050007000000000 +2DBE:000000000000000003F007F80C9818CCF8AAC8AA1CEE1A001A001E0000000000 +2DBF:00007FFE618E7DB661B66FB6618E7FFE7FFE63866DBE638E6DBE63BE7FFE0000 +2DC0:00000C300E700180018003F00D98199819B00FC0018001800180018000000000 +2DC1:00000C300E700180018003F00D98199819B00FC0019801F80198018000000000 +2DC2:00000C300E700180018003F00D98199819B00FC001800180019801F800180000 +2DC3:000018601CE00300030007E01B30333033601F80030006000C00380038003800 +2DC4:00000C300E700180018003F00D98199819B00FC0018001F0019001F000000000 +2DC5:000030C039C00600018003F00D98199819B00FC0018001800180018000000000 +2DC6:00000C300E70018002400240018003F00D98199819B00FC00180018000000000 +2DC7:00007FFE618E7DB661B66FB6618E7FFE7FFE71866FF66FEE6FDE71DE7FFE0000 +2DC8:0000000000000D980DD80FF00E60066006600660066006600660066000000000 +2DC9:0000000000001B301BB01FE01CC00CC00CF80CD80CC00CC00CC00CC000000000 +2DCA:0000000000001B301BB01FE01CC00CC00CC00CC00CC00CC00CC00CF800180000 +2DCB:0000000000000D980DD80FF00E60066006600060006000600060006000000000 +2DCC:0000000000001B301BB01FE01CC00CC00CC00CC00CC00CF80CC80CF800000000 +2DCD:000000000000199819D81FF01860066006600660066006600660066000000000 +2DCE:0000000000000D980DD80FF00E60066006600660060006000600060000000000 +2DCF:00007FFE618E7DB661B66FB6618E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +2DD0:30C039C0C630FFF0C63001C003E0067006300630063006300630063000000000 +2DD1:30C039C0C630FFF0C63001C003E006700636063E063606300630063000000000 +2DD2:30C039C0C630FFF0C63001C003E0067036303E30363006300636063E00060000 +2DD3:30C039C0C630FFF0C63001C003E0067006300630003000300030003000000000 +2DD4:30C039C0C630FFF0C63001C003E00670063006300630063E0632063E00000000 +2DD5:30C039C0C630FFF0C63003C00FE0187006300630063006300630063000000000 +2DD6:30C039C0C630FFF0C63001C003E0067006300630060006000600060000000000 +2DD7:00007FFE618E7DB661B66FB6618E7FFE7FFE63866DF66DEE6DDE63DE7FFE0000 +2DD8:0000000018601CE00FC007803F8030C000C000C000C000C000C000C000000000 +2DD9:0000000030C039C01F800F007F00618001F001B0018001800180018000000000 +2DDA:0000000030C039C01F800F007F0061800180018001800180018001F000300000 +2DDB:0000000030C039C01F800F007F006180018001800180038007007C0060000000 +2DDC:0000000030C039C01F800F007F00618001800180018001F0019001F000000000 +2DDD:0000000030C039C01F800F003F0025803D800180018001800180018000000000 +2DDE:30C039C01F80060006000F007F00618001800180018001800180018000000000 +2DDF:00007FFE618E7DB661B66FB6618E7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +2DE0:04182038241800000000000000000000 +2DE1:38243824380000000000000000000000 +2DE2:38202020200000000000000000000000 +2DE3:1C1414243E4200000000000000000000 +2DE4:54543854540000000000000000000000 +2DE5:18240824180000000000000000000000 +2DE6:24283028240000000000000000000000 +2DE7:1E121252220000000000000000000000 +2DE8:446C5444440000000000000000000000 +2DE9:24243C24240000000000000000000000 +2DEA:18242418000000000000000000000000 +2DEB:3C242424240000000000000000000000 +2DEC:38243820200000000000000000000000 +2DED:18202018000000000000000000000000 +2DEE:7C101010100000000000000000000000 +2DEF:44281028440000000000000000000000 +2DF0:242424243E0200000000000000000000 +2DF1:24241C04040000000000000000000000 +2DF2:545454547C0000000000000000000000 +2DF3:545454547E0200000000000000000000 +2DF4:18243C24180000000000000000000000 +2DF5:3F444434000000000000000000000000 +2DF6:18041C241C0000000000000000000000 +2DF7:18243C201C0000000000000000000000 +2DF8:081C081C222200000000000000000000 +2DF9:04281028281000000000000000000000 +2DFA:107C101C121C00000000000000000000 +2DFB:4C5272524C0000000000000000000000 +2DFC:4C427E524E0000000000000000000000 +2DFD:10283854540000000000000000000000 +2DFE:7C442838545400000000000000000000 +2DFF:5F514A7E555500000000000000000000 +2E00:0000003C202020202000000000000000 +2E01:0000003C202420202000000000000000 +2E02:00000004081020202020000000000000 +2E03:00000020100804040404000000000000 +2E04:00000004081020242020000000000000 +2E05:00000020100804240404000000000000 +2E06:0000007C101010101000000000000000 +2E07:0000007C101410101000000000000000 +2E08:00000038444024108848300000000000 +2E09:00000038444020108848300000000000 +2E0A:00000070880810204448300000000000 +2E0B:0000007C4444447C0000000000000000 +2E0C:00000040201008040000000000000000 +2E0D:00000004081020400000000000000000 +2E0E:000000800100038000000FE0010002807FFC028001000FE00000038001000200 +2E0F:0000000000000000000000000000000000000000000000000000000000007FFE +2E10:0000000000000000000000000000000000000000000000007FFE100020004000 +2E11:0000000000000000000000000000000000000000000000007FFF000800040002 +2E12:00000000000000000000000000100810 +2E13:0000000000000008001000200440008001000200044008001000200000000000 +2E14:00000000000000080010002000400080010022002400280010000E0000000000 +2E15:00000000000000E0001000280048008801000200040008001000200000000000 +2E16:00000000000820100804081020080000 +2E17:00000000000000000618600618600000 +2E18:000000001010001010305052523C0000 +2E19:0000000000000A2BACAFB07EE0DC0000 +2E1A:0000000000240000007E000000000000 +2E1B:00001824241800314946000000000000 +2E1C:00000000000000000000004020100804 +2E1D:00000000000000000000000408102040 +2E1E:00000018180000314946000000000000 +2E1F:0000000000000031494600000C0C0000 +2E20:00000010101010101C10101010100000 +2E21:00000008080808083808080808080000 +2E22:0000000E080808080800000000000000 +2E23:00000070101010101000000000000000 +2E24:00000000000000000008080808080E00 +2E25:00000000000000000010101010107000 +2E26:000000000000003E4040403E00000000 +2E27:000000000000007C0202027C00000000 +2E28:00000012242448484848484824241200 +2E29:00000090484824242424242448489000 +2E2A:00000000000066660000001818000000 +2E2B:00000000000018180000006666000000 +2E2C:00000000000066660000006666000000 +2E2D:000000000000181800DBDB0018180000 +2E2E:000000003C4242402010100010100000 +2E2F:08101008081000000000000000000000 +2E30:00000000000000182424180000000000 +2E31:00000000000000183C3C180000000000 +2E32:00000000000000000000081010180000 +2E33:00000000000000000000181800000000 +2E34:00000000000000000000180808100000 +2E35:00000000081010180000001818000000 +2E36:00000818082878280818080808080000 +2E37:0000080C080A0F0A080C080808080000 +2E38:0000080808081C082A7F2A081C080000 +2E39:000000003C42403C42423C0000000000 +2E3A:0000000000000000000000000000000000003FFC000000000000000000000000 +2E3B:0000000000000000000000000000000000007FFF000000000000000000000000 +2E3C:00000000000000000000001408140000 +2E3D:00000008000800080008000800080000 +2E3E:000C1008040810080408100804180000 +2E3F:000A7F8A8AFF8A7F0A0A0A0A0A0A0000 +2E40:0000000000000000003C003C00000000 +2E41:00000000000000000000000018101008 +2E42:00000000000000000000000066444422 +2E43:0000000000000000000000000000180018001FFE000000000000000000000000 +2E44:00000008102000000000000000081020 +2E45:00000000000000001824240000000000 +2E46:00000000242418001824240000000000 +2E47:00000000000000002424180000000000 +2E48:00000000000000005444380000000000 +2E49:00000000000018080810001808081000 +2E4A:00000000020204183C3C182040400000 +2E4B:00082A7F2A08082A7F2A08082A7F2A08 +2E4C:00000000000060101060000060600000 +2E4D:000000007E4448506040404040400000 +2E4E:00000000000000046870000060600000 +2E4F:00000000006264081224081026060000 +2E50:00003FE00F8007080708071807F807F807F80718070807080F803FE000000000 +2E51:00000FF803E021C021C031C03FC03FC03FC031C021C021C003E00FF800000000 +2E52:000000007E02020202020202221C0000 +2E53:00007FFE61867DBE618E6FBE61867FFE7FFE618E6FF661C67DF6618E7FFE0000 +2E54:00007FFE61867DBE618E6FBE61867FFE7FFE61B66FB661867DF661F67FFE0000 +2E55:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE61867DF661867FFE0000 +2E56:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FBE618E7DB661CE7FFE0000 +2E57:00007FFE61867DBE618E6FBE61867FFE7FFE61866FF661EE7DDE61DE7FFE0000 +2E58:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FB661CE7DB661CE7FFE0000 +2E59:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FB661C67DF661CE7FFE0000 +2E5A:00007FFE61867DBE618E6FBE61867FFE7FFE61866FB661867DB661B67FFE0000 +2E5B:00007FFE61867DBE618E6FBE61867FFE7FFE618E6FB6618E7DB6618E7FFE0000 +2E5C:00007FFE61867DBE618E6FBE61867FFE7FFE61C66FBE61BE7DBE61C67FFE0000 +2E5D:00007FFE61867DBE618E6FBE61867FFE7FFE618E6FB661B67DB6618E7FFE0000 +2E5E:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE618E7DBE61867FFE0000 +2E5F:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE618E7DBE61BE7FFE0000 +2E60:00007FFE61867DBE618E6FBE61867FFE7FFE73CE6FB663B66DB673CE7FFE0000 +2E61:00007FFE61867DBE618E6FBE61867FFE7FFE73EE6FCE63EE6DEE73C67FFE0000 +2E62:00007FFE61867DBE618E6FBE61867FFE7FFE73866FF663866DBE73867FFE0000 +2E63:00007FFE61867DBE618E6FBE61867FFE7FFE738E6FF663C66DF6738E7FFE0000 +2E64:00007FFE61867DBE618E6FBE61867FFE7FFE73B66FB663866DF673F67FFE0000 +2E65:00007FFE61867DBE618E6FBE61867FFE7FFE73866FBE63866DF673867FFE0000 +2E66:00007FFE61867DBE618E6FBE61867FFE7FFE73CE6FBE638E6DB673CE7FFE0000 +2E67:00007FFE61867DBE618E6FBE61867FFE7FFE73866FF663EE6DDE73DE7FFE0000 +2E68:00007FFE61867DBE618E6FBE61867FFE7FFE73CE6FB663CE6DB673CE7FFE0000 +2E69:00007FFE61867DBE618E6FBE61867FFE7FFE73CE6FB663C66DF673CE7FFE0000 +2E6A:00007FFE61867DBE618E6FBE61867FFE7FFE73866FB663866DB673B67FFE0000 +2E6B:00007FFE61867DBE618E6FBE61867FFE7FFE738E6FB6638E6DB6738E7FFE0000 +2E6C:00007FFE61867DBE618E6FBE61867FFE7FFE73C66FBE63BE6DBE73C67FFE0000 +2E6D:00007FFE61867DBE618E6FBE61867FFE7FFE738E6FB663B66DB6738E7FFE0000 +2E6E:00007FFE61867DBE618E6FBE61867FFE7FFE73866FBE638E6DBE73867FFE0000 +2E6F:00007FFE61867DBE618E6FBE61867FFE7FFE73866FBE638E6DBE73BE7FFE0000 +2E70:00007FFE61867DBE618E6FBE61867FFE7FFE61CE7DB67BB677B677CE7FFE0000 +2E71:00007FFE61867DBE618E6FBE61867FFE7FFE61EE7DCE7BEE77EE77C67FFE0000 +2E72:00007FFE61867DBE618E6FBE61867FFE7FFE61867DF67B8677BE77867FFE0000 +2E73:00007FFE61867DBE618E6FBE61867FFE7FFE618E7DF67BC677F6778E7FFE0000 +2E74:00007FFE61867DBE618E6FBE61867FFE7FFE61B67DB67B8677F677F67FFE0000 +2E75:00007FFE61867DBE618E6FBE61867FFE7FFE61867DBE7B8677F677867FFE0000 +2E76:00007FFE61867DBE618E6FBE61867FFE7FFE61CE7DBE7B8E77B677CE7FFE0000 +2E77:00007FFE61867DBE618E6FBE61867FFE7FFE61867DF67BEE77DE77DE7FFE0000 +2E78:00007FFE61867DBE618E6FBE61867FFE7FFE61CE7DB67BCE77B677CE7FFE0000 +2E79:00007FFE61867DBE618E6FBE61867FFE7FFE61CE7DB67BC677F677CE7FFE0000 +2E7A:00007FFE61867DBE618E6FBE61867FFE7FFE61867DB67B8677B677B67FFE0000 +2E7B:00007FFE61867DBE618E6FBE61867FFE7FFE618E7DB67B8E77B6778E7FFE0000 +2E7C:00007FFE61867DBE618E6FBE61867FFE7FFE61C67DBE7BBE77BE77C67FFE0000 +2E7D:00007FFE61867DBE618E6FBE61867FFE7FFE618E7DB67BB677B6778E7FFE0000 +2E7E:00007FFE61867DBE618E6FBE61867FFE7FFE61867DBE7B8E77BE77867FFE0000 +2E7F:00007FFE61867DBE618E6FBE61867FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +2E80:00000000000000000E000180006000101C00030000C000200000000000000000 +2E81:0000007C1F801000100010001000100010001000100020002000200040008000 +2E82:000000000000000000003FF80008000800100010002000200000000000000000 +2E83:0000100010001000100010001000100010001000100010001010101010100FF0 +2E84:00000000FFE00020002000200020002000200020002000100012000A00060002 +2E85:0040004000800100010003000500090001000100010001000100010001000100 +2E86:00000FF008100810081008100810081008100810081010101010101020504020 +2E87:00001FF01010101010101010101010101010101010102008200A200A40068002 +2E88:0400040007F00820084010002000000000000000000000000000000000000000 +2E89:0004000400040044004400440044004400440044004400440004000400140008 +2E8A:040004000400040004000400040007F004000400040004000400040004000400 +2E8B:00000000000000000000000000003FF020102010201020502020200420041FFC +2E8C:0100111009200100000000000000000000000000000000000000000000000000 +2E8D:0208210810900820000000000000000000000000000000000000000000000000 +2E8E:000000000000FFFE0440044004400440044008400840104210422042403E8000 +2E8F:022002100408080410026422042004200420042004200420082208221022601E +2E90:01000100010001000100FFFE024002400240044004400840084210422042C03E +2E91:0220021004080804100267E2042004200420042004200420082208221022601E +2E92:000000003FF020102010201020103FF02000200020002004200420041FFC0000 +2E93:00000100010002100410082010401F80010002000420081010083FFC00040004 +2E94:000004000400040007F0042008200820082008401FC00040004000407FFC0000 +2E95:00000000000000003FF8000800083FF80008000800083FF80008000000000000 +2E96:08000800080008000C004A004A00880008000800080008000800080008000800 +2E97:000000000000000000000200020002200290124812242214221042000A000400 +2E98:0100010001001FC001000100010001C007001900010001000100010005000200 +2E99:0800080008000FFC18102410442082200140008001800240042008101008E006 +2E9A:00007FFE61867DBE618E6FBE61867FFE7FFE73866DB671867DB673B67FFE0000 +2E9B:3FF002000200420042007FFC0480048004800880088010842084407C80000000 +2E9C:3FF820082FE820082FE800000000000000000000000000000000000000000000 +2E9D:00001FF01010101010101FF01010101010101FF0101010101010101010501020 +2E9E:0080008000FE088008800FF8100814102210412001400080010002000C007000 +2E9F:00001FF01010121011101110FFFE20102210211021103FFC0010001000A00040 +2EA0:000000103FF82008200820083FF8200020883FFC2080204020202010380E3004 +2EA1:200010001000800040004800080010001000E000200020002000200000000000 +2EA2:01000100010021081110092001000140052009101108E1044104010005000200 +2EA3:0000000000000000000000000000000000000000248822444244800400000000 +2EA4:0010007C0780F808210818900890000000000000000000000000000000000000 +2EA5:007C1F9011101110210821044002000000000000000000000000000000000000 +2EA6:020002000200220012000A000200020006000A00120062002200020002000200 +2EA7:010011001FF821000100FFFE0000000000000000000000000000000000000000 +2EA8:4400280010002800480088000800180028004800880008000800500020000000 +2EA9:FE0010001000100010001000FE00100010001000100016003800C00000000000 +2EAA:00000000FC0008001000100010005C0050005000500050005C00F00040000000 +2EAB:3FF82448244824483FF800000000000000000000000000000000000000000000 +2EAC:00007E0000000000FE0010001000540052005200900010001000100050002000 +2EAD:200010001000F800080010001000380054009400100010001000100010001000 +2EAE:00001040104010403EFE289049108A1000000000000000000000000000000000 +2EAF:080008001000120022007C000800100024007E00020000005200490089000000 +2EB0:10001000200024004400F800100020004000FC00400000001C00E00040000000 +2EB1:3FF8200824482288210822882448200800000000000000000000000000000000 +2EB2:3FF82448244824483FF800000000000000000000000000000000000000000000 +2EB3:00003FFC20044008044008201010000000000000000000000000000000000000 +2EB4:00007FFE4444844804400440044004400440044008400842104210422042403E +2EB5:0000000000003FFC224422442244224422442244224422442244200400000000 +2EB6:101008203FF801001FF001000200FFFE040008001000E0000000000000000000 +2EB7:082004407FFC01001FF00100FFFE000000000000000000000000000000000000 +2EB8:0440044004407C7C044004400000FFFE010001003FF801000100010001000100 +2EB9:020002083FC802100220FFFE0080010002000C003000C0000000000000000000 +2EBA:010001003FF80108FFFE01083FF8010801000100010001000100010001000100 +2EBB:010001001FF80108FFFE01081FF80100FFFE0000000000000000000000000000 +2EBC:07F8040805080488044804680408041804280448058808880808100820284010 +2EBD:02000C00707C400440044004400440047CFC400440044004400440047CFC4004 +2EBE:08200820FFFE0820082000000000000000000000000000000000000000000000 +2EBF:08200820FEFE0820082000000000000000000000000000000000000000000000 +2EC0:0000082008200820082008200820F83E08200820082008200820082008200000 +2EC1:010001F801003FFC210421602F88210820F8200023E02220222044244824901C +2EC2:200010000000FC00080010001000340058009400140010001000100010001000 +2EC3:7FFC044004403FF8244824483FF8000000000000000000000000000000000000 +2EC4:00000000FFFE0480048004807FFC4484448444844484489448F4500440047FFC +2EC5:1FF01010101011101110111011101110129012900480048008823082C07E0000 +2EC6:080008001FE020204040BFF8210821083FF8210821083FF82108410841288010 +2EC7:0400040007F0082010403FF85108118812481528198812481428180810281010 +2EC8:20001000100000000000F0001000100010001000100014001800100000000000 +2EC9:1FF0101010101010111011101110111011101210028004400820101020080000 +2ECA:00007F004100410041007F004900080008004F004800480048004F00F0004000 +2ECB:0200020002007FFC04000900110021003FF801000100FFFE0100010001000100 +2ECC:20001000100000000000F000100010001000100010001000280047FE00000000 +2ECD:2000100008004000200010000000F000100010001000100010002800440083FE +2ECE:00002000100000000000F800080010002000780008000800100010002800C7FE +2ECF:0000003C00240028002800300028002400240024003400280020002000200020 +2ED0:100010001E00200020007C0090001000FE001000100012001400180010000000 +2ED1:0FF808000FF008000FF00800FFFE1200111010A0104012201418180610000000 +2ED2:0FF8080008000FF0080008000FF008000800FFFE0400082010103FF810080000 +2ED3:0800081008200840088009000800FFFE0A0009000880084009200A180C060800 +2ED4:200013FC10044004400440044004400440044004400440044004400440144008 +2ED5:020004001FF0101010101FF010001FF8100810081FF810001FF8100810081FF8 +2ED6:F800880090009000A000900090008800880088008800F0008000800080008000 +2ED7:7FFC0100FFFE91128D6201001D70610C00000000000000000000000000000000 +2ED8:020002007FF802003FF00200FFFC00001FE010201FE010201FE01020102010C0 +2ED9:010001000104FFFE010001103FF8010001047FFE010401040104012801100100 +2EDA:7FFC020004001FF0101011101110111011101110129002400420181060080000 +2EDB:3FF02010201028502450229022902110211022902292244A484A400680020000 +2EDC:FFC000400044004800500060005000480044002000200012000A000600020000 +2EDD:0100028004400A203118DFF610101FF010101FF0100811901060121014081804 +2EDE:080008001400120029007E00A2003E0022003E0020003E00200020003E002000 +2EDF:080008001400120029007E00A2003E0022003E002000280024002A0032002000 +2EE0:2000200020003E00440048008000100010001000100012001400180010000000 +2EE1:088808881110222011100888FFFE02001FF010101FF010101FF010101FF01010 +2EE2:7FE0002000201020102010201FFC000400040004FFE400040004002800100000 +2EE3:1FF010101F90109010907FFE40029FF410101FF010101FF01010101010501020 +2EE4:020004003FF8210821083FF8220822083FF8051009200948117C2102410280FE +2EE5:040004000FE0102020407FF8A10821083FF8210821083FF800000000FFFE0000 +2EE6:010002001FF01010121011101150102010001FFC000400047FE4000400280010 +2EE7:0100010001FE010001003FF8200828282448228821082288244828283FF82008 +2EE8:010001007FFC010001003FF801000100FFFE08001FF02820444003801C70E00E +2EE9:04403FF804400440FFFE01001FF0111011101FF0111011101FF0044008201010 +2EEA:1FF0101010101FF001003FF8210821083FF8210821083FF8210A0102010200FE +2EEB:020001007FFC0820044003801C70F01E10101FF0101010101FF0101020104010 +2EEC:020001007FFC0820044003800C603018C8260820082008200820102010202020 +2EED:0100010011F811001100FFFE00002928254823883FF823882548292821083FF8 +2EEE:0100010011F8110011001100FFFE00002108210822882448282820083FF80008 +2EEF:020001007FFC10100820FFFE01001FF011101FF0111011101FF01112010200FE +2EF0:0420041004100400FFFE048004880488049008A008C0108211822282447E8000 +2EF1:04003FF820083EF802807A800AFCFE940AD47AA402A47AD40A94FEFC0A8279FE +2EF2:04000FC010803FF0D1101FF011101FF001003FF821083FF821083FF8010200FE +2EF3:040004000FE0102020407FF8A10821083FF8210821083FF821080102010200FE +2EF4:00007FFE61867DBE618E6FBE61867FFE7FFE61B66FB663866FF66FF67FFE0000 +2EF5:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE63866FF66F867FFE0000 +2EF6:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +2EF7:00007FFE61867DBE618E6FBE61867FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +2EF8:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +2EF9:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +2EFA:00007FFE61867DBE618E6FBE61867FFE7FFE61866FB663866FB66FB67FFE0000 +2EFB:00007FFE61867DBE618E6FBE61867FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +2EFC:00007FFE61867DBE618E6FBE61867FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +2EFD:00007FFE61867DBE618E6FBE61867FFE7FFE618E6FB663B66FB66F8E7FFE0000 +2EFE:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE638E6FBE6F867FFE0000 +2EFF:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +2F00:000000000000000000047FFE0000000000000000000000000000000000000000 +2F01:0100018001000100010001000100010001000100010001000100010001000000 +2F02:0000000004000200010000800040004000000000000000000000000000000000 +2F03:0200020002000200020002000200020002000200040004000800100020000000 +2F04:00403FE000400080010002000400080010002004200420061FFC000000000000 +2F05:00400040004000400040004000400040004000400040004003C0004000000000 +2F06:00101FF80000000000000000000000000000000000047FFE0000000000000000 +2F07:000000000100008000847FFE0000000000000000000000000000000000000000 +2F08:0100010001000100010001000100010001000280044008201010200E40040000 +2F09:08400C60084008400840084008400840084008401040104420444046803C0000 +2F0A:1E000100010001000100028002800440044008201010200C4006800200000000 +2F0B:00C0004000400640044004400420082008200810101010082004400680020000 +2F0C:20043FFE20042004200420042004200420042004200420042024201C20080000 +2F0D:00000000000020023FFE20044008000000000000000000000000000000000000 +2F0E:0400030001000000004000800080010001000600020002000200020000000000 +2F0F:00200FF0082008200820082008200820082008200820082210222022401E0000 +2F10:2004300620042004200420042004200420042004200420043FFC200400000000 +2F11:00043FFE01040104010401040104010402040204040404040844103860100000 +2F12:01000100010001083FFC01080108010801080208020804080888107060200000 +2F13:1000100010041FFE100420044004000400040004000400040044003800100000 +2F14:08000C00080008100820084009800A000C003800C80008040804080607FC0000 +2F15:20083FFC20002000200020002000200020002000200020083FFC200000000000 +2F16:7FFC200020002000200020002000200020002000200020083FFC000000000000 +2F17:0100010001000100010001047FFE010001000100010001000100010001000000 +2F18:0200020002000200020003800240023002180208020002000200020002000000 +2F19:042007F0042004200420042004200420042004E0044004000400040004000000 +2F1A:20043FFE20002000200020002000200020002000200020004000400080000000 +2F1B:018001000100020002000400040008200810100811FCFE044004000000000000 +2F1C:00103FF80810081004200420024002400180018002400420181E600400000000 +2F1D:10081FFC1008100810081008100810081008100810081FF81008000000000000 +2F1E:20043FFE20042004200420042004200420042004200420043FFC200400000000 +2F1F:0100018001000100010001083FFC01000100010001000100010001047FFE0000 +2F20:0100018001000100010001047FFE01000100010001000100010001083FFC0000 +2F21:0400041007F80C101220214001800E70700E0000000000000000000000000000 +2F22:0200020012100BF8041004100A200A20114021404080014006201818E0060000 +2F23:02000200020803FC040804080C10121021204120004000800100060038000000 +2F24:010001800100010001047FFE0100010001000280044008201010200E40040000 +2F25:020003000200020002047FFE042004200820082010400E8001800670780E0000 +2F26:00083FFC0010002000C0008000847FFE00800080008000800480038001000000 +2F27:00000100008020843FFE20044008000000000000000000000000000000000000 +2F28:00200020002000247FFE0020002008200420042004200020012000E000400000 +2F29:008000800080008000800C900888108410862082408200800480038001000000 +2F2A:0200020002000208FFFC020002000280028004800484088410842086C07C0000 +2F2B:10081FFC1008100810081FF81008100010001000100020002000400080000000 +2F2C:010001000100210421042104210421043FFC21040100010002000C0070000000 +2F2D:01000100010001004104410441044104410441044104410441047FFC40040000 +2F2E:0444044408880888111011102220444022201110088808880444044404440000 +2F2F:00083FFC01000100010001000100010001000100010001047FFE000000000000 +2F30:00107FF800100010001000103FF020102000200020002004200420061FFC0000 +2F31:00800080008010841FFE10841084108410841084108410BC1088008000800000 +2F32:00083FFC010001000100010001047FFE01000100010001000100010001000000 +2F33:0300020004000430082010407F80210002000420081013E87C0C200400000000 +2F34:0100008000841FFE100010001000100010001000100020002000400080000000 +2F35:08007C0008000800100024003E00040084004400280010002800C40683FC0000 +2F36:0410041004100410041004107FFE041004100410041008100810101020100000 +2F37:0120011801080100011E01E07F003080008000800040004200220012000E0000 +2F38:00103FF80010001000101FF0100010083FFC000800080008010800F000200000 +2F39:00083FFC000800080008000800081FF8000800080008000800083FF800080000 +2F3A:00C0008001000200040000C00080010002000460004000800100020004000000 +2F3B:00C000800100020004C008800100030005000900110001000100010001000000 +2F3C:0100008000C00040040004002408240424062402440084100410041803F00000 +2F3D:0200024002200200021C02E07F000218021002200140018202440C24701E0000 +2F3E:001010381FC010081FFC1008100810081FF81008100020002000400080000000 +2F3F:001000787F80010001103FF8010001047FFE0100010001000900070002000000 +2F40:0080008000847FFE008000901FF80410041002200140008001400630380E0000 +2F41:01000100010401FE010001103FF80810042004200240018001800E70700E0000 +2F42:0100008000847FFE082008200820044004400240028001800660181860060000 +2F43:002008200420022002200820042002200224003E03E07C202020002000200000 +2F44:002010701F801000100010041FFE104010401040104020402040404080400000 +2F45:0100008000847FFE02000200020803FC02080208020804080888107060200000 +2F46:00081FFC01000100010001047FFE0240024002400240044208421042603E0000 +2F47:10101FF8101010101010101010101FF0101010101010101010101FF010100000 +2F48:20083FFC20082008200820083FF820082008200820083FF82008000000000000 +2F49:08100FF80810081008100FF00810081008100FF0081008101090207040200000 +2F4A:00800080008000847FFE0080028002A004A00490089008881086608400800000 +2F4B:0800080008040FFE100821104100010001000100018002400420181860060000 +2F4C:00800080008000800080088808FC08800880088008800880088008847FFE0000 +2F4D:00047FFE02000200021003F804100C1012202120414000800100060078000000 +2F4E:042007F00420042004200820101C20001FF808100420024001800E70700C0000 +2F4F:00081FFC10881088108810887FFE11081108210822087FFE041009F030200000 +2F50:0040104010401040104C12481F501060104010401040104413443C46103C0000 +2F51:001000383FC001000100011C3FE00100010E01F07F0001020102010200FE0000 +2F52:001010381FC01080108010881FFC1080108010801080124214227812200E0000 +2F53:080008080FFC10002FF04000BFF000100010001000100012000A000600020000 +2F54:010001000100011801107D2005400580094009201110210C4906870202000000 +2F55:0080008000800080088C0888089010A020C00080018002400420181860060000 +2F56:001010381FE01120112011201120112011101110111021082108410681020000 +2F57:044004200810100C2004402004200440024002800180018002400C30300E0000 +2F58:00181810062001C002300C0C30240420044002400280018002C00C30300E0000 +2F59:0010041004100410041007F0001000103FF00410041004100410081030100000 +2F5A:104010401040104010441FFE100010201FF01020102010201020202040200000 +2F5B:00047FFE00400840084010443FFE01400240044008401040224041C000800000 +2F5C:00800080108010881FFC10802080408000847FFE008000800080008000800000 +2F5D:010001A00110011001047FFE0100010001000280044008201010200E40040000 +2F5E:0100008000847FFE01000100023005E01E4008800100021005F81E0C08040000 +2F5F:00083FFC01000100010001101FF80100012001100110010001047FFE00000000 +2F60:0008103C1FE0112011201120112011201110111011501148214843A681220000 +2F61:00047FFE04000400042007F008200A20092009201020102213227C22201E0000 +2F62:0810081008147FFE08100810081008100FF008100810081008100FF008100000 +2F63:00801080108010881FFC10802080408000901FF800800080008000847FFE0000 +2F64:10041FFE1084108410841FFC1084108410841FFC1084208420A4409C80880000 +2F65:20043FFE20842084208420843FFC208420842084208420843FFC200400000000 +2F66:00047FFE0084008800801080108810FC10801080188014802280C18080FE0000 +2F67:008008440FFE4800280028000800180068004800080010001000200040000000 +2F68:00087F1002A22244142808101008200440020000000000000000000000000000 +2F69:0100010012081FFC10081008100810081FF810081008100810081FF810080000 +2F6A:0080008010841FFE1084108810801FF812101210112020C020C043309C0E0000 +2F6B:10081FFC12481248124812481248124812481248124812487FFE000000000000 +2F6C:10101FF81010101010101FF01010101010101FF01010101010101FF010100000 +2F6D:00101FF800200340008000847FFE018802900480088010802480438001000000 +2F6E:0800080008080FFC10802080008000847FFE0080014002200410180E60040000 +2F6F:00047FFE01000100020004080FFC1408240844080408040807F8040800000000 +2F70:00101FF800000000000000047FFE00800CA00890108820844484038001000000 +2F71:0100010021043FFE210422042244222424F43F14281420042004203C20080000 +2F72:0008003C1FC00080008000847FFE008001C002A0049008881086608200800000 +2F73:0100008020823FFE200440080440044004400420082008101008200C40060000 +2F74:02000100008000883FFC000008100810042004200240024000847FFE00000000 +2F75:10001060104012441F7E289049108A1008100810081008100890087008200000 +2F76:0080108C08880C9004A000C47FFE028002C004A0089010882086408200800000 +2F77:01800100023004201FC00880012002103FFC108400800C900888108620820000 +2F78:0800080008080FFC1080208000847FFE008010841084108410841FFC10040000 +2F79:20043FFE2004211421142A942464222425242954309421042024201C20080000 +2F7A:0830042002447FFE0100010001101FF8010001047FFE01000100010001000000 +2F7B:02047FFE02042244122412240204060C1A3462C40204020412240E1C04080000 +2F7C:01000100010C3FE8011001247FFE0080010006300CC017046404040603FC0000 +2F7D:00047FFE0080008021043FFE2244224422442244224422442244225C20080000 +2F7E:01000104FFFE010001103FF801000104FFFE054005200910110C2106C1020000 +2F7F:00047FFE082008200FE00820082008200FE00824083E0FE07820002000200000 +2F80:010001081FFC01087FFE01081FF8010801003FF801047FFE0100010001000000 +2F81:0100010021043FFE210421842244243429142104218422442424281C20080000 +2F82:20083FFC2100210021083FFC2008200820083FF82108210021043FFE20000000 +2F83:0180010002081FFC100810081FF81008100810081FF8100810081FF810080000 +2F84:00047FFE01000200042008107FF82104010001083FFC0100010001047FFE0000 +2F85:02002704387E20042004200420043E7C200420042004200420043FFC20040000 +2F86:001000783F80008000847FFE0080008008880FFC0808080808080FF808080000 +2F87:10101010101012141F7E1210225052500A900AFE041008101010201040100000 +2F88:010001000A100FF809100890089008147FFE091008900890081010F020200000 +2F89:10101FF8101010101FF0101010101FF01200110C113010C01660781820060000 +2F8A:0400042007F0084010883FFC5108110811081FF810081002100210020FFE0000 +2F8B:0810081008102A542A542A542A542A542A543E7C2A5408101010201040100000 +2F8C:010001FC010001003FFE200221042110213821C02F0021022102410280FE0000 +2F8D:00800080008010881FFC1088108810881FF810880080008800847FFE30020000 +2F8E:00C00080010012081FFC124812481248124812481248124812487FFE00000000 +2F8F:180811FC200040000C040BFE1010301050109010101010101090107010200000 +2F90:0100008000847FFE0180028C04880C50146024404420049005080E0604020000 +2F91:00047FFE0220022022243FFE222422242224222423E422242004200420040000 +2F92:00201FF0102010201FE0102010201FE0102010201FE014A408843086C07C0000 +2F93:042007F0042008441FFE288448840FFC088408840FFC10841084209C40880000 +2F94:02000104FFFE000000001FF000001FF0000010101FF8101010101FF010100000 +2F95:044004200810100C218402400420181860060FF00810081008100FF008100000 +2F96:00083FFC000008100FF80810081008100FF0081004600440024002847FFE0000 +2F97:00047FFE01000200040C1A08631004A019C062A00490188E6084048003000000 +2F98:006000C00188065C1A2001C003200C60109003301C50009003101D2000C00000 +2F99:08080FFC080808080FF8080808080FF8080808080FF8080803600C1830060000 +2F9A:0080008000881FFC008000847FFE02401248124422442442444209C030800000 +2F9B:0100010001101FF8010001047FFE01000900090809FC09001500230040FE0000 +2F9C:08100FF80810081008100FF008900080088808FC088014801280218640FC0000 +2F9D:008009100FF808100FF0081008160FF408187FF000500190061018F060200000 +2F9E:010001047FFE010011081FFC11081FF811081FF8110801047FFE010001000000 +2F9F:010000883FFC08200420024002447FFE010001083FFC01000100010001000000 +2FA0:10041FFE1000101017F8100010041FFE124012481250222022904F0884060000 +2FA1:006001801E3800C01F1800601F8000801080108818FC148022804180807E0000 +2FA2:1FF0101010101FF0101000003FF8210821083FF820082004200420061FFC0000 +2FA3:00047FFE024012441FFE124412441244143C180410041FFC10041FFC10040000 +2FA4:003000F83F0001101110092009447FFE0380054009201110210E410401000000 +2FA5:10081FFC110811081FF8110811081FF81108010001083FFC010001047FFE0000 +2FA6:0080018002400420081010086FF6010001083FFC01001118091009247FFE0000 +2FA7:08100FF808000FF008000FF0080008047FFE08880850082009900E0E38040000 +2FA8:7EFC428442847EFC428442847EFC400440044004400440044024401C40080000 +2FA9:010012101FF810101FF010001FF810081FF8108800847FFE0080008000800000 +2FAA:010001103FF801107FFE01103FF0011031880990076009207118270602000000 +2FAB:0480044004440FFE0840184028484FFC084008480FFC084008440FFE08000000 +2FAC:00047FFE010021043FFE21042944252425242104294425242524211C21080000 +2FAD:0104FFFE01003FF80104FFFE00003FF82108210821083FF82008207820100000 +2FAE:0240024002447E7E0240024002483E7C0240024002447E7E0240024002400000 +2FAF:00047FFE008021043FFE2244224423C42244224423C4224422443FFC20040000 +2FB0:08200824FFFE08200FE001003FF821083FF821080100FFFE0100010001000000 +2FB1:020002201FF004247FFE00000FF008100FF000803FFC10803FFC008000800000 +2FB2:02400240024002447E7E024002403E7C024002447E7E0240024002447FFE0000 +2FB3:030001087FFC102008200440FFFE000010101FF810101FF010101FF010100000 +2FB4:00047FFE008011081FFC10081FF810081FF810081FF8100803600C1830060000 +2FB5:20083FFC204821E82F0821082FE8292829282FE82928214A21EA4F2684020000 +2FB6:3FE0002400280D30392C092209127FEE092409280930112C1112210A41060000 +2FB7:008001800240052018986FF608100FF008100FF0080809900A603C1810060000 +2FB8:083004207FFE008011101FF8101010101FF010101FF0101010101FF010100000 +2FB9:002000703F8001047FFE054009203118C8160FF808100FF008100FF008100000 +2FBA:10081FFC110011101FF811001FF8110011041FFE002409142494248440380000 +2FBB:08100FF8081009F029123FFE20044FF408100FF008100FF00810087008200000 +2FBC:010000847FFE00000FF008100FF020043FFE200427E4242427E4243C20080000 +2FBD:22003F0C200820103F2620443F8820107F26104410082210FF20414001800000 +2FBE:8002BEFA8822BEFA8822BEFA8002800280028002800280028012800E80040000 +2FBF:02102924244432A42994224424A43FFC2004103010C01700180410040FFC0000 +2FC0:00047FFE00000FF008100FF000003FFC2004244422842FF42104211C21080000 +2FC1:010012081FFC110811081FF8110811081FF81088019002A804FE1882607E0000 +2FC2:042007F0042008401FF8288848880FF8088808880FF808082444222242220000 +2FC3:01000A100FF808100FF008100FF008080FFC08000FFC29242494449400180000 +2FC4:0100010401FE01003FFC22142924244432A429942244252428943FFC20040000 +2FC5:010020843FFE222022243FFE22243FFC280428202FA4283829A25E22883E0000 +2FC6:008000847FFE08880888149423E20490190863F604200B4030C001201E100000 +2FC7:010040847FFE441044107F7E4410555455545554555455546494A49684100000 +2FC8:04247FFE042007E000047FFE01001FF811081FF811081FF810080C30700E0000 +2FC9:00701F8001087FFE010007E0191862860D60711E0D6403800560191863060000 +2FCA:10081FFC1108192815481FF8110801003FF8010001007FFE2444222242220000 +2FCB:124812480A500A507FFE108820845FFE1084118412C414A41894109C10880000 +2FCC:3FFC224422443E7C224402403E7C22443E7C22443E7C22440242024201FE0000 +2FCD:07E0042027E4242427E4242427E424243E7C02407E7E12481248224842480000 +2FCE:08200820FF2408FE7E2000247FFE424442447E48422824101E30704E21840000 +2FCF:060838FC20083EF820083FF820080940252821082948252A210A294673820000 +2FD0:01000FF008100FF008100FF008101FF811081FF811087FFE0420042038200000 +2FD1:020001047FFE02483EB0152815282534592208100FF008100FF0101060100000 +2FD2:0080089008F80880FFFE044044444AA451147FFC44444AA451147FFC40040000 +2FD3:104008447F7E2240147C7F04007C3E40227C3E40227C3E40227E2E42243E0000 +2FD4:08400FE0084010807FFC11447F7C05447F6C05547D6C05447F7E05027CFC0000 +2FD5:01800660181863C600007BDE4A527BDE00003FFC22443FFC2244225C22480000 +2FD6:00007FFE61867DBE618E6FBE61BE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000 +2FD7:00007FFE61867DBE618E6FBE61BE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000 +2FD8:00007FFE61867DBE618E6FBE61BE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000 +2FD9:00007FFE61867DBE618E6FBE61BE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000 +2FDA:00007FFE61867DBE618E6FBE61BE7FFE7FFE63866DB66D866DB663B67FFE0000 +2FDB:00007FFE61867DBE618E6FBE61BE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +2FDC:00007FFE61867DBE618E6FBE61BE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +2FDD:00007FFE61867DBE618E6FBE61BE7FFE7FFE638E6DB66DB66DB6638E7FFE0000 +2FDE:00007FFE61867DBE618E6FBE61BE7FFE7FFE63866DBE6D8E6DBE63867FFE0000 +2FDF:00007FFE61867DBE618E6FBE61BE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +2FE0:00007FFE61867DBE618E6FBE61BE7FFE7FFE61CE6FB663B66FB661CE7FFE0000 +2FE1:00007FFE61867DBE618E6FBE61BE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000 +2FE2:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FF663866FBE61867FFE0000 +2FE3:00007FFE61867DBE618E6FBE61BE7FFE7FFE618E6FF663C66FF6618E7FFE0000 +2FE4:00007FFE61867DBE618E6FBE61BE7FFE7FFE61B66FB663866FF661F67FFE0000 +2FE5:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FBE63866FF661867FFE0000 +2FE6:00007FFE61867DBE618E6FBE61BE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000 +2FE7:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FF663EE6FDE61DE7FFE0000 +2FE8:00007FFE61867DBE618E6FBE61BE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000 +2FE9:00007FFE61867DBE618E6FBE61BE7FFE7FFE61CE6FB663C66FF661CE7FFE0000 +2FEA:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FB663866FB661B67FFE0000 +2FEB:00007FFE61867DBE618E6FBE61BE7FFE7FFE618E6FB6638E6FB6618E7FFE0000 +2FEC:00007FFE61867DBE618E6FBE61BE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000 +2FED:00007FFE61867DBE618E6FBE61BE7FFE7FFE618E6FB663B66FB6618E7FFE0000 +2FEE:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FBE638E6FBE61867FFE0000 +2FEF:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FBE638E6FBE61BE7FFE0000 +2FF0:EDB600008102810200008102810200008102810200008102810201008002B6DA +2FF1:EDB6000080028002800200008002800236D8800280020000800280020000EDB6 +2FF2:EDB600008442844280020440844280020440844280020440844284420000EDB6 +2FF3:EDB600008002800280020000B6DA800200008002B6DA0000800280020000EDB6 +2FF4:AAAA00008002155080021010800210108002101090120000955280020000AAAA +2FF5:DBB60000800280020D608822800208208002882288220000882288220000DBB6 +2FF6:DBB600008822882200008822882200008822800288220D60800280020000DBB6 +2FF7:DB6D000180008001056D84008001040180008401056D8000800100018000B6DB +2FF8:DB6D0001800080010B6D8800800108018800800108018800800108018800B6DB +2FF9:DB6D00018000800136D18010800100118010800100118010800100118010B6DB +2FFA:DB6D08018800800108018800800108018800800108018B6C800100018000B6DB +2FFB:0000DB60802000009B6C902400009024902400009024DB64000010041B6C0000 +2FFC:00007FFE61867DBE618E6FBE61BE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +2FFD:00007FFE61867DBE618E6FBE61BE7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +2FFE:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FBE638E6FBE6F867FFE0000 +2FFF:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +3000:0000000000000000000000000000000000000000000000000000000000000000 +3001:000000000000000000000000000010000C000600020000000000000000000000 +3002:000000000000000000000000000000000C00120012000C000000000000000000 +3003:0000000000000240024002400480048009000900000000000000000000000000 +3004:0000060018202030412841A881448D0493044908440824101860018000000000 +3005:00000000020001000100023003C8041008201240218000800040000000000000 +3006:0000000000100008001006200940088009401220141018003000200000000000 +3007:0000078018602010400840088004800480048004400840082010186007800000 +3008:0008000800100010002000200040008000400020002000100010000800080000 +3009:1000100008000800040004000200010002000400040008000800100010000000 +300A:0048004800900090012001200240048002400120012000900090004800480000 +300B:1200120009000900048004800240012002400480048009000900120012000000 +300C:00F8008000800080008000800080008000800080008000000000000000000000 +300D:000000000000000001000100010001000100010001000100010001001F000000 +300E:01F801080178014001400140014001400140014001C000000000000000000000 +300F:0000000000000000038002800280028002800280028002801E8010801F800000 +3010:00F800F000E000E000E000C000C000C000C000C000C000E000E000F000F80000 +3011:1F000F00070007000300030003000300030003000300070007000F001F000000 +3012:00007FFE000000007FFE01000100010001000100010001000100010000000000 +3013:3FFE3FFE3FFE3FFE3FFE0000000000003FFE3FFE3FFE3FFE3FFE000000000000 +3014:0008001000200040004000400040004000400040004000400020001000080000 +3015:1000080004000200020002000200020002000200020002000400080010000000 +3016:03F8021002200240024002800280028002800280024002400220021003F80000 +3017:1FC008400440024002400140014001400140014002400240044008401FC00000 +3018:0008003000500050005000500050005000500050005000500050003000080000 +3019:10000C000A000A000A000A000A000A000A000A000A000A000A000C0010000000 +301A:00F800A000A000A000A000A000A000A000A000A000A000A000A000A000F80000 +301B:1F0005000500050005000500050005000500050005000500050005001F000000 +301C:0000000000000000000000003E004182007C0000000000000000000000000000 +301D:0090004800240000000000000000000000000000000000000000000000000000 +301E:0900120024000000000000000000000000000000000000000000000000000000 +301F:0000000000000000000000000000000000000000000000000900120024000000 +3020:00003FFC3FFC00003FFC3FFC5596D9B9A5A5A5A5599A4182242413C8081007E0 +3021:0180010001000100010001000100010001000100010001000100010000000000 +3022:006000400C400840084008400840084008400840084000400040004000000000 +3023:0008200821082108210821082108210821082108210820082008000800000000 +3024:001000101020082004400240018000C001200210040808083000000000000000 +3025:00000420043008201CC003000480084008201020102010201040084007800000 +3026:00000100008000847FFE00000000000000000000000000000000000000000000 +3027:000001000100010001003FFC0000000000003FFC000000000000000000000000 +3028:0100010001007FFE0000000000003FFC00000000000000007FFE000000000000 +3029:0800080008000FFC10102810042002200140008000C0012002100C1030000000 +302A:0000000000000000000000000000000000000000000000006000900090006000 +302B:0000600090009000600000000000000000000000000000000000000000000000 +302C:0000000600090009000600000000000000000000000000000000000000000000 +302D:0000000000000000000000000000000000000000000000000006000900090006 +302E:00000000000000000000000000000000C000C000000000000000000000000000 +302F:000000000000000000000000C000C0000000C000C00000000000000000000000 +3030:000000000000000000000000618692490C300000000000000000000000000000 +3031:0100018001000200020004000800100010000800040002000100010000800080 +3032:0100018001100208024804200820100010000800040002000100010000800080 +3033:0400060004000800080008001000100010002000200020004000400080008000 +3034:0400060004400820088008401040100010002000200020004000400080008000 +3035:8000800040002000200010001000080008000400040002000200010001000000 +3036:07C0183020085FF45FF480029FF29FF2810281028102410441042108183007C0 +3037:8282828282824444444428282828101010102828282844444444828282828282 +3038:010001000100010001000100FFFE010001000100010001000100010001000000 +3039:082008200820082008200820FFFE082008200820082008200820082008200000 +303A:10881088108810881088FFFE1088108810881088108820882088408880080000 +303B:0000000002000100008000400080010000800040002000000000000000000000 +303C:0000000000003FF82018202820482088210822082408280830083FF800000000 +303D:0000000010002860449003100010001000100010001000100008000800040000 +303E:DB6D80010E00918980710000801180211FF8808181011FF8840188000001DB6D +303F:00FE82C6C6AAAA92AAAAC6C682FE0000 +3040:00007FFE63CE7DB671B67DB663CE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000 +3041:00000000000000000400020013800E00048007E00D10161026102A2010C00000 +3042:00000400020002C01F000480048007E00D101508220826082A10106000000000 +3043:000000000000000000000000000010401020101010300A000C00040000000000 +3044:0000000000000000400020602010200822082418140818000800000000000000 +3045:0000000000000000000002000180000013800C40004000400040008003000000 +3046:0000020001C00000000003C01C20002000200020002000400040008001000000 +3047:0000000000000000000002000180000001C00E80010002000700090010F00000 +3048:0000040003800000000011C00E800100020004000E001100210020F800000000 +3049:00000000000000000000104008300C2038000BC00C201820282018C008000000 +304A:00000000080004300508060C1C000460059006080C0834880C70040000000000 +304B:0000000008000400046047103C88089808800880108011002500220000000000 +304C:0000000808240410044047203C90088808980880108011002500220000000000 +304D:00000200010001600F80008000F01F400020002007F008100800060001C00000 +304E:00000408022402D01F00010001E03E80004000400FE0102010000C0003800000 +304F:0000008000400040008001000600080008000400020001000080004000400000 +3050:0000008000400040008801240610080008000400020001000080004000400000 +3051:00000080204010201020103C23E0202020202020202018201040104000800000 +3052:0000010840A420502040207847C0404040404040404030402080208001000000 +3053:00000000080007E00080010000000000000000002000200010100FE000000000 +3054:00000008080407F00088010000000000000000002000200010100FE000000000 +3055:000004000200013021C01E800040004007E00820100010000C0003C000000000 +3056:000004080204013021C81E800040004007E00820100010000C0003C000000000 +3057:0000000010000800080008000800080008000800080808100460038000000000 +3058:0000000010200890084008000800080008000800080808100460038000000000 +3059:00000100008040F83F800080038004C0044003C0004000800080010002000000 +305A:00000128009440F83F800080038004C0044003C0004000800080010002000000 +305B:0000000000801040084008784BC03C400840084008C00840040003E000000000 +305C:0000000800841050084808784BC03C400840084008C00840040003E000000000 +305D:0000000009C0064000800100023807C038800100020002000200010000E00000 +305E:0000000009C8066400900100023807C038800100020002000200010000E00000 +305F:000000000800048007003C0008F008180820100010001100210020F800000000 +3060:000000080824049007003C0008F008180820100010001100210020F800000000 +3061:00000800040004C047003C00080008C00B201C1010100010002000C007000000 +3062:00000800040804C447103C08080008C00B201C1010100010002000C007000000 +3063:000000000000000000000000000001C00620381000100010002000C007000000 +3064:000000000000000003E04C103008000800080008001000600380000000000000 +3065:000000080024001003E04C103008000800080008001000600380000000000000 +3066:00000000003843C03C800100010002000200020002000200010000E000000000 +3067:00000000003843C03C880124011002000200020002000200010000E000000000 +3068:000000000400020002000200027003800600080010001000080007F000000000 +3069:000000000408022402100200027003800600080010001000080007F000000000 +306A:00000400020002803F0004700818082010401040204003C00460045003800000 +306B:000000002000100010F01318202020002000200022002A0011F8100010000000 +306C:0000000001000080008013E01510190812082A084C084C685490206800000000 +306D:000010000800080008004CE03F100C1008101810181028F0591808E000000000 +306E:00000000000003C00D2011101108220822082408241028101060018000000000 +306F:0000004020201020143813E0202020202020202029E01230122811C000000000 +3070:0000008840442050287827C0404040404040404053C024602450238000000000 +3071:0000009840642064287827C0404040404040404053C024602450238000000000 +3072:00000000004004403C2008200830102810201020104010400880070000000000 +3073:00000008004404503C2808200830102810201020104010400880070000000000 +3074:00000030004804483C3008200830102810201020104010400880070000000000 +3075:00000000040003800080010002000200010002B04C88389C2480030000000000 +3076:000000000400038800A4011002000200010002B04C88389C2480030000000000 +3077:000000000400039800A4012402180200010002B04C88389C2480030000000000 +3078:0000000000000000000006000900108020400030000C00000000000000000000 +3079:0000000000000010004806200900108020400030000C00000000000000000000 +307A:0000000000300048004806300900108020400030000C00000000000000000000 +307B:00000000223011C01040103823E020202020202029E01230122811C000000000 +307C:00000000446823842090207847C040404040404053C024602450238000000000 +307D:00000018446423A42098207047C040404040404053C024602450238000000000 +307E:00000100008010F00F80008010E00F80008000800F8010E010900F0000000000 +307F:000000000880078001000100022002100FF03418442448203040008000000000 +3080:00000800040027001C3004081C0C240024002C2018100810081007E000000000 +3081:0000000001000080108013C01CA0111029082A08460844084A10306000000000 +3082:00000200010011000E000380120024201C200710041004100410022001C00000 +3083:000000000000000000000100088009E00E103C10046002000200010001000000 +3084:00000100008001C0180010F00B084C0834080270020001000100008000800000 +3085:000000000000000000000200010021E0271029103110232021C0010002000000 +3086:000000000300408021E022902488288830883488229021E00080010002000000 +3087:000000000000000002000100012001C00100010001000F0011C011200E000000 +3088:0000020001000100013001C001000100010001001F80216021101E0000000000 +3089:00000200010001C0060008000800080009E00E1008100810002000C003000000 +308A:0000100009800A400C200C200820082008200820004000400080010002000000 +308B:0000000008C0074000800100020007C00C201010201003900460044003800000 +308C:000000001000080009C00A201C206C2008201820182028204824181808000000 +308D:0000000011800E800100020004000FC00820101020100010002000C007000000 +308E:0000000000000000000008000400040006E01D1006100C100C10142004400000 +308F:000010000800080008004CE03F100C080808180818082810482018C008000000 +3090:00000000098006800100010003E00E1012082408240828C8193010E000000000 +3091:0000000009800700020007C008201020062009C0070008001CE0231040380000 +3092:00000400020012C00F00040004200F3818C02180028004800800080007E00000 +3093:000002000100010002000200040004000F000880108010882090206000000000 +3094:0000020001C80004001003C81C20002000200020002000400040008001000000 +3095:00000000000000000000040004603F1004880898108011002500220000000000 +3096:0000000000000080004008200820083811E01020102014201440084000800000 +3097:00007FFE63CE7DB671B67DB663CE7FFE7FFE73866DF671EE7DDE73DE7FFE0000 +3098:00007FFE63CE7DB671B67DB663CE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000 +3099:0000000400120008000000000000000000000000000000000000000000000000 +309A:0000000600090009000600000000000000000000000000000000000000000000 +309B:0000100048002000000000000000000000000000000000000000000000000000 +309C:0000300048004800300000000000000000000000000000000000000000000000 +309D:000000000000000000000C000300008000C00100000000000000000000000000 +309E:000000000000002000900C400300008000C00100000000000000000000000000 +309F:000000000600018008000800080008000FC0102000100010002000C003000000 +30A0:000000000000000000000000000007E000000000000007E00000000000000000 +30A1:000000000000000000000000000021E01E200240018001000100020004000000 +30A2:00000000000021F01E1000200240018001000100010002000200040008000000 +30A3:0000000000000000000000200040008003801C80008000800080008000800000 +30A4:00000000002000200040008003000D0030800080008000800080008000800000 +30A5:000000000000000000000200010001E01E200820084000400080010002000000 +30A6:0000000002000100010001F03E10101010200820084000400080010002000000 +30A7:000000000000000000000000000000E00F0001000100010001E01E1000000000 +30A8:000000000000000000701F800200010001000100010003F03C08000000000000 +30A9:000000000000000000000100008010E00F800180028004800880118000800000 +30AA:0000000000800040004020781FC000C00140024004400840104000C000400000 +30AB:0000000002000100010021F01F1002100210042004200820114020C000800000 +30AC:0000000802240114011021F01F1002100210042004200820114020C000800000 +30AD:0000000004000200027003801D000100017803803C8000800040004000400000 +30AE:0000000804240214027003801D000100017803803C8000800040004000400000 +30AF:0000000004000270039002200420044008401080008001000200040008000000 +30B0:00000008082404D4075004400840088010802100010002000400080010000000 +30B1:0000000008000400040004380FC0090010802080008001000100020004000000 +30B2:0000000808240414041004380FC0090010802080008001000100020004000000 +30B3:000000000000000021F01E100010001000100020002003E01C20000000000000 +30B4:000000080024001443D03C400040004000400080008007803880000000000000 +30B5:00000000008008400440044024F81F4004400440044000800080010002000000 +30B6:0000000800A408540450044024F81F4004400440044000800080010002000000 +30B7:0000000000000C000200000018000408001000200040008013000C0000000000 +30B8:0000000000080C240214001018000408001000200040008013000C0000000000 +30B9:00000000000010E00F200040004000800080014002200C103010000000000000 +30BA:00000008002421D41E5000800080010001000280044018206020000000000000 +30BB:000000000800040004000478058826101C20044004000400020001F000000000 +30BC:000000080824041404100478058826101C20044004000400020001F800000000 +30BD:0000000000201010081004100420042000400040008000800100020004000000 +30BE:0000000800A42054105008400840084000800080010001000200040008000000 +30BF:000000000200010001F002100220052008C010400080010002000C0030000000 +30C0:000000080424021403F0042004200A4011402080010002000400180060000000 +30C1:00000000004001801E00010000F823801C800080008001000100020004000000 +30C2:00000008006401941E10010000F823801C800080008001000100020004000000 +30C3:0000000000000000000000000000044012200A20084000400080010002000000 +30C4:0000000000000410220811080910081000200020004000800100020000000000 +30C5:0000000800241094085044402440104010800080010002000400080000000000 +30C6:00000000000011E00E000000007823801C800080010001000200040008000000 +30C7:00000008002411D40E10000020F01F0000800080010001000200040008000000 +30C8:0000000008000400040004000400070004C00420040004000400040004000000 +30C9:00000020109008500840080008000E0009800840080008000800080008000000 +30CA:0000000001000080008020F81F80008000800080010001000200040008000000 +30CB:000000000000000000E01F00000000000000000001F03E080000000000000000 +30CC:00000000000010F00F10002000200E4001C000C0012002100C10300000000000 +30CD:000000000200010001E01E2000400080010003400D3031080100010001000000 +30CE:0000000000400020002000200040004000800080010002000400080010000000 +30CF:0000000000000000000008800440042008100810100820084008000000000000 +30D0:0000000000080024001408900440042008100810100820084008000000000000 +30D1:0000001800240024001808800440042008100810100820084008000000000000 +30D2:00000000000010000800080008E00F000800080008000800040003F000000000 +30D3:000000000010104808280820080008E00F00080008000800040003F000000000 +30D4:000000000030104808480830080008E00F00080008000800040003F000000000 +30D5:00000000000010F00F1000100020002000400040008001000200040000000000 +30D6:00000008002423D41C5000400080008001000100020004000800100000000000 +30D7:00000018002423E41C5800400080008001000100020004000800100000000000 +30D8:0000000000000000000002000500488030400030000C00000000000000000000 +30D9:0000000000200090005002400500488030400030000C00000000000000000000 +30DA:0000000000600090009002600500488030400030000C00000000000000000000 +30DB:0000000002000100010021F01F00010001400920091011102100030001000000 +30DC:0000000802240114011021F01F00010001400920091011102100030001000000 +30DD:0000001802240124011821F01F00010001400920091011102100030001000000 +30DE:000000000000000020F01F080010002000400C80030000800040000000000000 +30DF:000000000400030000C00020080006000180004010000C00030000C000200000 +30E0:0000000002000100010001000200020002400420043029C81E08000000000000 +30E1:000000000040002000200020062001C0004000A00090010002000C0030000000 +30E2:00000000000010E00F000200020023F81E0002000200020001F0000000000000 +30E3:0000000000000000000000000400027003901E20014001000080008000800000 +30E4:00000000080004000478038826101A2001400100010000800080008000000000 +30E5:000000000000000000000000000001C00E400040008001E01E10000000000000 +30E6:0000000000000000000011C00E4000400080008001F03E080000000000000000 +30E7:00000000000000000000000001E00E20002001E00E40004001C00E2000000000 +30E8:00000000000001F01E100010001001E00E2000200020002001E00E1000000000 +30E9:00000000000011C00E00007023901C100010002000200040008003000C000000 +30EA:0000000000400820042004200420042004200420004000400080010002000000 +30EB:0000000000000100088004800480048804880490089008A010C0208000000000 +30EC:0000000010000800080008000800080008100820084008800B000C0000000000 +30ED:000000000000000021F01E10101010100820082009E00E100800000000000000 +30EE:000000000000000000000000000010F00F100820042004400040008001000000 +30EF:00000000000021F01E1010100810082008200040004000800100020004000000 +30F0:0000000001000080008001F01E800880048005F03E8800800080008000800000 +30F1:000000000000000001E01E20024001800100010001F03E080000000000000000 +30F2:00000000000001F01E100010002001E00E200040004000800100060018000000 +30F3:00000000000000001800040802080010001000200040008013000C0000000000 +30F4:0000000804240214021043E03C20202010401040008000800100020004000000 +30F5:0000000000000000000000000200010011E00E2002200220042008C010400000 +30F6:0000000000000000000000000800040004600780088010800100020004000000 +30F7:00040012000821F01E1010100810082008200040004000800100020004000000 +30F8:0000000801040090008801F01E800880048005F03E8800800080008000800000 +30F9:000000080004001001E81E20024001800100010001F03E080000000000000000 +30FA:00040002000801F41E100010002001E00E200040004000800100060018000000 +30FB:0000000000000000000000000300078007800300000000000000000000000000 +30FC:000000000000000000000000000040F83F000000000000000000000000000000 +30FD:000000000000000000000C000300008000400020000000000000000000000000 +30FE:000000000000002000900C400300008000400020000000000000000000000000 +30FF:0000000021E01E10001000100010001000100010001000100010001000100000 +3100:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE73CE6DB66DB66DB673CE7FFE0000 +3101:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000 +3102:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE73866DF66D866DBE73867FFE0000 +3103:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE738E6DF66DC66DF6738E7FFE0000 +3104:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE73B66DB66D866DF673F67FFE0000 +3105:0000000002000200040008001FF0001000100020004000400280010000000000 +3106:0000000001000100020007F00010001002200140008001400620380000000000 +3107:000000003FF81008100810081008100810081008100810080008000000000000 +3108:000000001FF810001000100010001000100010000FFC00000000000000000000 +3109:000002000200040008001FF8010801080208040808101010012000C000000000 +310A:0000000000400040008000807FFE010001000220021007F00008000800000000 +310B:000000000FE000200040008001F8000800100010002002200140008000000000 +310C:0000008000800480048008800FF80088010802100210041008A0104000000000 +310D:0000020802080410041008201040208010400820041004100208020800000000 +310E:000000003FFE01000200040007F8000800080010001002200140008000000000 +310F:000000000FFE0400040004000400080008000800100010002000000000000000 +3110:000000000020082008200820082008E00F200020002000200020002000000000 +3111:00000000001000200040008003000C0002000180004000300008000400000000 +3112:000000003FFE0080008000800080008000800080008000800080000000000000 +3113:0000010001002108210821082108210821083FF80100010001007FFC00000000 +3114:000000100060008001080610002000C003400440184000400040004000400000 +3115:000000000FFC00040004040407FC040004000400040008001000000000000000 +3116:0000000000003FF8200820082208210821082088208820083FF8000800000000 +3117:000000001FFC0104010401040108010801280110010001000100000000000000 +3118:000001000100010001003FFE01000100010001F8000800100020002000400000 +3119:000000000100010001000200020004000820101020083FFC0004000000000000 +311A:0000000020101020084004800300020002000200020002000200000000000000 +311B:000000003FFE00400040004007C00800100010001008081007E0000000000000 +311C:00000080008000803FFC0080008007800800100010001008081007E000000000 +311D:0000000004100410041004107FFE0410042004200440040003F0000000000000 +311E:000000001FFC0080088011001FF8010802080210041008201020004000000000 +311F:000000000180068038800080008000400040002000100010000C000000000000 +3120:00000000008001000200041008201FC000800100061018183FE4000400000000 +3121:000000000FF8000800100420024001C000C00130020804041804200000000000 +3122:000000001FF0041004200820084010803FF80008001000200040008000000000 +3123:0000100010001000100010001FFC000400080008001000100020000000000000 +3124:0000000000800080008001001FF8028002800480048008801080207E00000000 +3125:0000000000400040008001000100020004000400080010007FFC000000000000 +3126:000000000040044004400440044004400840084008401040203E000000000000 +3127:00000000000000000000000000003FFC00000000000000000000000000000000 +3128:00000008000804100220012000C000C001200210040808041004000000000000 +3129:000000001008100810081008100810081008100810081FF80008000000000000 +312A:000000007FFE020002000200020003F00410041004100810081010A020400000 +312B:000000007FFC04400440044004400440084008400840104010402040403C0000 +312C:00000100008000001FFE10001000100010001000100010002000200040000000 +312D:000000007FFC0100010001003FF8210821082108210821082108010001000000 +312E:00000180018000003FFC0080008007800800100010001008081007E000000000 +312F:000000001FE0004000800100020007F801080108010801080150012000000000 +3130:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE63CE7DB671B67DB663CE7FFE0000 +3131:00000000000020081FFC08080008000800080008000800080008000000000000 +3132:00000000000041083FFC11080108010801080108010801080000000000000000 +3133:00000000000082607F1022100210023002280248024402820301000000000000 +3134:0000000000000000000030000800080008000800080807FC0000000000000000 +3135:00000000000000000204C1FE20A02020205023881D0402020000000000000000 +3136:00000000000000400038C40223FF21002078208423841C840078000000000000 +3137:000000000000000070101FF8100010001000100010080FFC0000000000000000 +3138:000000000000000062883FFC208020802080208023841C7E0000000000000000 +3139:00000000000020101FF80810001030101FF81000100010100FF8000000000000 +313A:00000000000082047FFE22840204FF044004400443043C040000000000000000 +313B:00000000000041443FFE114401447FC42044204423C41C7E0040000000000000 +313C:00000000000042083F04028402847EFC2084208423841CFC0000000000000000 +313D:00000000000084607E1024100410FE3040284048468439020000000000000000 +313E:00000000000042C43F7E024002447F7E2040204023441C3E0000000000000000 +313F:00000000000085087EFC04000400FE8440484048464A3BFF0000000000000000 +3140:00000000000084407E38050204FFFE0040384044464438380000000000000000 +3141:00000000000038100FF80810081008100810081008100FF80800000000000000 +3142:00000000002000101010081008100FF00810081008100FF00810000000000000 +3143:00000000000802842144114411441F7C1144114411441F7C1144000000000000 +3144:00000000000004604210221022103E102228222822443E442282000000000000 +3145:0000000002000180008000800080014001400220041008083004000000000000 +3146:00000000000008400420042004200A200A5011482084C3020000000000000000 +3147:0000000000000200010007C008201010101010101010082007C0000000000000 +3148:00000000000020101FF809000100010002800440082010106008000000000000 +3149:000000000000000081047FFE242004200A50095010882104C602000000000000 +314A:00000000040003E0000020081FFC088001400220041008083004000000000000 +314B:00000000000010080FFC0408000800F83F081008000800080008000000000000 +314C:00000000000038200FF0080008200FF008000800081007F80000000000000000 +314D:00000000000020101FF80800000008100420022042483FFC1000000000000000 +314E:000000000000040003C040083FFC100003C0042008100810042003C000000000 +314F:004000300010001000100012001F001000100010001000100010001000100000 +3150:0020011800C80048004800480078004800480048004800480048004800080000 +3151:00400030001000100012001F00100012001F0010001000100010001000100000 +3152:0020011800C80048004800780048004800780048004800480048004800080000 +3153:004000300010001000100010001003F001100010001000100010001000100000 +3154:0010008C006400240024002403E4012400240024002400240024002400040000 +3155:0040003000100010001003F00110001003F00110001000100010001000100000 +3156:0010008C00640024002403E40124002403E40124002400240024002400040000 +3157:000000000000000000000000010000800080008040823FFF1000000000000000 +3158:00400030001000100010001008100412041F05F07E1020100010001000100000 +3159:0010008C00640024002408240424043C042407E47C2420240024002400040000 +315A:00200018000800080008040802080208020803F87E0820080008000800080000 +315B:000000000000000000000000004004200220022042223FFF1000000000000000 +315C:00000000000000000000000040023FFF10800080008000800080008000800000 +315D:00200018000800080008000801E87E08280809F8088808080808080800080000 +315E:002000980048004800480048004803C87C4828480BC808480848084800080000 +315F:002000180008000800080008000801E87E082408040804080408040800080000 +3160:00000000000000000000000040023FFF12200220022002200220022002200000 +3161:00000000000000000000000000000000000040023FFF10000000000000000000 +3162:0020001800080008000800080008000801F87E08200800080008000800080000 +3163:0040003000100010001000100010001000100010001000100010001000100000 +3164:AAAA00018000000180000001913C11219F381121912000018000000180005555 +3165:000000000000C1802040204020402040204023441C3E00000000000000000000 +3166:000000000000C0C4207E204020402040204023421C3F00000000000000000000 +3167:000000000000C0202010201020102010202823481C8401020000000000000000 +3168:000000000000C0102010202820282044204423821CFF00000000000000000000 +3169:00000000000088507FE808480848FC54405440623C4100000000000000000000 +316A:00000000000042C83F7C024002407F402040204023441C3E0000000000000000 +316B:00000000000088907C480A480A48FFD442544E6233C100000000000000000000 +316C:0000000084207E2004200450FC504088408847043BFE00000000000000000000 +316D:00000000000084007E00050404FEFE4040384044464438380000000000000000 +316E:000000000000000862843F442244227C2244224422443F7C2044000000000000 +316F:00000000000062203F10221022102210222822283E4422820000000000000000 +3170:00000000000062103F102228222822442244224422823FFF2000000000000000 +3171:000030081FFC1008100810081FFC1100008007E0081010081008081007E00000 +3172:00000000000004000282827F42227E024202420242027E024202000000000000 +3173:00000000040002C8827C424042407E404240424042447E3E4200000000000000 +3174:000000000000114288BF48824882798249424A427A224C120000000000000000 +3175:0000000000001132889F48904890799049504A507A524C2F0000000000000000 +3176:0000000000000800860445FE44A07C20442044507C8847060000000000000000 +3177:00000000040002C4827E424042447E7E4240424042447E3E4200000000000000 +3178:0010200810081FF8100810081FF81108008007E0081010081008081007E00000 +3179:0010248812481E78124812481E781248008007E0081010081008081007E00000 +317A:000000000000090404FE044404040A040A0411042104C0840000000000000000 +317B:00000000000008000580044006400A400A401140214440BE0000000000000000 +317C:00000000000010C4087E08400840144014402240414480BE0000000000000000 +317D:000000000004100208820842087E144214422242217E40C20000000000000000 +317E:000000000000120209FF08900810142814282244414281810000000000000000 +317F:000000000100010002800280044004400820082010103FF80000000000000000 +3180:00000000181808083C3C4242424242424242424242423C3C0000000000000000 +3181:0000030001000FE0101020082008200820082008200810100FE0000000000000 +3182:00003000120479FE84A08420842084508450848885047A020000000000000000 +3183:000030001020782084508450848884888488850485047BFE0000000000000000 +3184:000020101FF80000042042483FFC1100008007E0081010081008081007E00000 +3185:0000000020401C3881027FFF20001C382244224422441C380000000000000000 +3186:0000000040083FFC1200010007C0082008200820082007C00000000000000000 +3187:004000300010001000100912091F091009F27E1F201000100010001000100000 +3188:0020011800C800480048047802482248127813C87C4820480048004800080000 +3189:0020001800080008000802081108090809080BE87C0820080008000800080000 +318A:00200018000800080008000801E87F0829780908097809080908090800080000 +318B:0020011800C80048004800480348FC4855C8144815C814481448004800080000 +318C:002000180008000800080008000801E87F082908090809080908090800080000 +318D:0000000000000000000000000100038001000000000000000000000000000000 +318E:0020001800080008000800080008000802080708020800080008000800080000 +318F:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE73866DBE738E6DBE73BE7FFE0000 +3190:0000000000800080008000800080008000800000000000000000000000000000 +3191:0000000002000200020002200240028003000000000000000000000000000000 +3192:000000000000000000003FC00000000000000000000000000000000000000000 +3193:0000000000001F800000000000003FC000000000000000000000000000000000 +3194:000000001FE000000FC0000000003FF000000000000000000000000000000000 +3195:000000003FE02520252028E020203FE000000000000000000000000000000000 +3196:000000000400040007800400040004003FC00000000000000000000000000000 +3197:0000040004003FC0244024403FC0040004000400000000000000000000000000 +3198:000000003FC00400060005000400040004000000000000000000000000000000 +3199:000000003FC022403FC022403FC0224002000200000000000000000000000000 +319A:000000003F80030004000800104020401FC00000000000000000000000000000 +319B:000000003FE002003FE02220232024A028600000000000000000000000000000 +319C:000000003FE0020002000200020002000A000400000000000000000000000000 +319D:000000001FC0020002003FE00200050008E01040000000000000000000000000 +319E:0000084009503DF00B50095009280D0830F80000000000000000000000000000 +319F:000004000400040004000A000900108020400000000000000000000000000000 +31A0:00000800080010003FF800080008000800080008000800F00110012000C00000 +31A1:000000001FF8020802080208020802100290026002001E00220022001C000000 +31A2:0000002004200420042004200420086009A00E20002001E00220022001C00000 +31A3:0000000004400440088008801100110022001100110008B808C4044404380000 +31A4:000000000800080008007FFC080408080810080008000800080007F800000000 +31A5:000000000800080008007FFC080408080810080008180824082407F800080000 +31A6:000000007FFC0200020004000800100020002020104008800500020000000000 +31A7:000000007FFC0200020004000800100020C02120114008800560020000000000 +31A8:00000000101008200820044004400280028001FC028004401830600C00000000 +31A9:00000000201010200840048003000200020002000F801200220022001C000000 +31AA:00000000000000180024004400447FF800400040000000000000000000000000 +31AB:0000000010100820082004400440028002800100028C04521822605C00400000 +31AC:0000000020003FF8210821082108210821082108210821082108000000000000 +31AD:000000007FFC0920092009200920092009200920092009201120611E00000000 +31AE:000000007FFC01001100110021003FF801080108020832084C104A1032200000 +31AF:00000000008001000200041008201FC000800118062418243FF80010000C0000 +31B0:00001830044002807FFC41044104410441044104410441044104410441040000 +31B1:000000007FFC01007FFC41044704480450045044488445044204400440040000 +31B2:000000007FFC010001000100010001000100010001000100010001007FFC0000 +31B3:000000800080008000800080008000800080008003E004800880088007000000 +31B4:0000000000000000000000000100020007E00020002000200140008000000000 +31B5:0000000000000000000000000100020007E00120022004200940008000000000 +31B6:00000000000000000000000007E00100020007C0004000400140008000000000 +31B7:000000000000000000000000000007E002000200020002000400080000000000 +31B8:000000003FF80010002000400080010002000400080010003FF8000000000000 +31B9:0000000000002000200020002000200020003FF8000000000000000000000000 +31BA:00000000000001000100010001007FFC01000100010001000000000000000000 +31BB:0000000000000000000004400440088008801100088008800440044000000000 +31BC:000000000200043008300C4002C0018001800240046008301018201800000000 +31BD:00003FF80200043008300C4002C0018001800240046008301018201800000000 +31BE:000000001010101008200820082004403FF80440024002800280018001000000 +31BF:0000000000000440044004200420041004100810080808081008200800000000 +31C0:0000000000000000002000C003001C0008000000000000000000000000000000 +31C1:0400020002000100010001000100010001000100010001000100010005000200 +31C2:1000100010001000080008000800040004000200020001000090005000200000 +31C3:000000000000000000008000400020001804060201FC00000000000000000000 +31C4:00000800080008000800080008000800080008000800080008000FF000000000 +31C5:000000003F00010001000100010001000100010001000100010001F000000000 +31C6:0000000000003FF0001000100010001000100010001000100010005000200000 +31C7:000000001FF80008000800080008001000100020002000400040008001000200 +31C8:000000007F80008000800080008000800080008000800080008200820082007C +31C9:00002000200020002000200020003FF800080008000800080010001000A00040 +31CA:000000000F80008000800080008000800080009000A000C00080000000000000 +31CB:000000003FFC000800100020007C000400040004000800080010002000400080 +31CC:000003E000200040008000800040004000200020002000200140008000000000 +31CD:0000000000007F800080008000800080008000800040003E0000000000000000 +31CE:000000003F80008000800080008000F000100010001000100010001000100000 +31CF:0000080008000800080004000400020002000100010000800040002000140008 +31D0:00000000000000000000000000007FFE00000000000000000000000000000000 +31D1:0000010001000100010001000100010001000100010001000100010001000000 +31D2:0000000000200020004000400080010002000400000000000000000000000000 +31D3:0000004000400040004000400040004000800080010001000200040008000000 +31D4:0000000000000000040002000100008000400040000000000000000000000000 +31D5:0000000000001FF8000800080008000800080008000800080008000800000000 +31D6:0000000000007FFC000800100000000000000000000000000000000000000000 +31D7:00000000100010001000100010001000100010001000100010001FFC00000000 +31D8:0000001000100010001000100010001000100010001000103FF0001000000000 +31D9:0000040004000400040004000400040004200440048005000600040000000000 +31DA:0000008000800080008000800080008000800080008000800080028001000000 +31DB:0000004000400080008001000200040002000100008000400020000000000000 +31DC:00000040004000800080010001000200040008001FF800000000000000000000 +31DD:0000080008001400240002000200010001000080004000200010000A00040000 +31DE:00002000200020002000200020003FF800080008000800080008000800080000 +31DF:0000080008000800080008000800080008000800080008080808080807F80000 +31E0:00007FF00020004000800100020004000800100020004004400440063FFC0000 +31E1:000000003FF8001000100020007C000400040004000400040008002800100000 +31E2:0000000000100010002000200040004000800080010001002200240038000000 +31E3:0000000000001FF020084004400440044004400420081FF00000000000000000 +31E4:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61B66FB663866FF661F67FFE0000 +31E5:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61866FBE63866FF661867FFE0000 +31E6:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61CE6FBE638E6FB661CE7FFE0000 +31E7:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61866FF663EE6FDE61DE7FFE0000 +31E8:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61CE6FB663CE6FB661CE7FFE0000 +31E9:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61CE6FB663C66FF661CE7FFE0000 +31EA:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61866FB663866FB661B67FFE0000 +31EB:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE618E6FB6638E6FB6618E7FFE0000 +31EC:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61C66FBE63BE6FBE61C67FFE0000 +31ED:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE618E6FB663B66FB6618E7FFE0000 +31EE:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61866FBE638E6FBE61867FFE0000 +31EF:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61866FBE638E6FBE61BE7FFE0000 +31F0:00000000000000000000000040002E0032002400440008001000200040000000 +31F1:0000000000000000000000000000600010000000610012000400480030000000 +31F2:00000000000000000000000000008E00720004000400080014002200C2000000 +31F3:0000000000000000000000002000200020003000280024002000200020000000 +31F4:00000000000000000000000000008E00720004003400080014002200C2000000 +31F5:0000000000000000000000000000048002400220042008101010000000000000 +31F6:0000000000000000000000004000400040004E0070004000400040003E000000 +31F7:00000000000000000000000000008E00720004000400080010002000C0000000 +31F8:0000000000000000000000000000000000000200050008C00030000000000000 +31F9:00000000000000000000200010001E00F0001000540092001000500030000000 +31FA:000000000000000000000000020001000100010001000200022014D00F080000 +31FB:0000000000000000000000008C00700000008E00720002000400080070000000 +31FC:0000000000000000000000000000880044004400440004000400080030000000 +31FD:0000000000000000000000000240012001200120012001240224042808300000 +31FE:0000000000000000000000000000800040004000400044004800500060000000 +31FF:00000000000000000000000000F01F10101010101020102011F01E0000000000 +3200:00001818200440024FF240124012401240124012401240124002200418180000 +3201:000018182004400244024402440244024402440247FA40024002200418180000 +3202:000018182004400240024FF2480248024802480248024FF24002200418180000 +3203:00001818200440024FF2401240124FF24802480248024FFA4002200418180000 +3204:000018182004400240024FF248124812481248124FF240024002200418180000 +3205:00001818200440024812481248124FF24812481248124FF24002200418180000 +3206:0000181820044082408240824142414242224412480A40024002200418180000 +3207:000018182004400243C244224812481248124812442243C24002200418180000 +3208:00001818200440025FF241024102428242824442482250124002200418180000 +3209:00001818200443E2400240024FFA4082414242224412480A4002200418180000 +320A:00001818200440024FF2401240125FF240124012401240124012200418180000 +320B:00001818200440024FF2480248024FF24802480248024FF24002200418180000 +320C:000018182004400240024FF2400244224422424242425FFA4002200418180000 +320D:000018182004400243C240025FFA400243C244224422442243C2200418180000 +320E:00001818202440225FA240A2413E422244224822502260224022202418180000 +320F:0000181820244022502250225022503E50225FE2402240224022202418180000 +3210:00001818202440225FA250225022503E50225FA2402240224022202418180000 +3211:00001818202440225FA240A240A25FBE502250225FA240224022202418180000 +3212:000018182024402240225F225122513E51225F22402240224022202418180000 +3213:0000181820244022512251225F22513E51225F22402240224022202418180000 +3214:0000181820244022442244224A224A3E512260A2402240224022202418180000 +3215:00001818202440224E2251225122513E512251224E2240224022202418180000 +3216:00001818202440225FE242224222453E452248A2506240224022202418180000 +3217:000018182024472240225FE24222423E452248A2506240224022202418180000 +3218:00001818202440225FA240A27F22423E44224822502260224022202418180000 +3219:00001818202440225FA250225FA2503E50225FA2402260224022202418180000 +321A:00001818202440225FA2402250A2493E49224BE27C2240224022202418180000 +321B:0000181820244F2240227FE240224F3E50A250A24F2260224022202418180000 +321C:0000301840049FF2810282828C62B01A8002BFFA810281028102410431180000 +321D:00003018400499EAA44AA4DAA52A992A800A88828882BEFA8002400430180000 +321E:30184004806299FAA462A492A4929862800288FA8822BE228022400430180000 +321F:00007FFE63867DF671867DBE63867FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000 +3220:0000200840048002800280028012BFFA80028002800280028002400420080000 +3221:00002008400480229FF280028002800280028012BFFA80028002400420080000 +3222:0000200840249FF28002800280428FE2800280028012BFFA8002400420080000 +3223:0000200840048002BFFAA44AA44AA44AA44AA44ABFFA80028002400420080000 +3224:0000200840249FF28202820282229FF28422842284228422BFFA400420080000 +3225:000020084004820281028012BFFA800280028442842288129012400420080000 +3226:000020084204820282028212827A8382BE02820282028222822241E420080000 +3227:0000200840848482848284828482848288428822901AA0128002400420080000 +3228:000020084204820282429FE28242824282428442844A884A903A400420080000 +3229:000020084104810281028112BFFA810281028102810281028102400420080000 +322A:0000301847F48412841287F28412841287F28412841288529022400430180000 +322B:000030184104810289128922894291028282828284428822B01A400430180000 +322C:00003018410481028112BDA285428542892289229112A50A8202400430180000 +322D:00003018410481028102BFFA8102838285428922B11A81128102400430180000 +322E:000030184104828284428822B7DA81029FF2810289228542BFFA400430180000 +322F:0000301841048102810281029FF281028102810281028102BFFA400430180000 +3230:0000301840048FE28822882288228FE28822882288228FE28822400430180000 +3231:0000301848448942BDF28A429C429BFAA842A8E289528A4A8842400430180000 +3232:000030184204BFFA840287E28C2297E2A42287E2842284228462400430180000 +3233:0000301850448842BE42844289F28C429A42A842884288428BFA400430180000 +3234:00003018440487F284228A429182810287F2BC128412841287F2400430180000 +3235:000030184844A9F2BC42A842ABFA8C229BFAA92288A2882288E2400430180000 +3236:0000301840149E1293FA9E1292329E5292929F1280129252A122400430180000 +3237:0000301851F48912BF12831285F28CA29AA2AAA288AA892A8A1A400430180000 +3238:000030185214891289229FFA910AA1029FF28112821284129862400430180000 +3239:0000301844A48492888288FA9B82A88288828842884A882A881A400430180000 +323A:000030184034BBC2A84AAA4AA952AFFAB842A8428042804281C2400430180000 +323B:00003018491484A29FFA900A87E2804280829FFA808280828382400430180000 +323C:000030185F2494229F3A91429F52940A9F8280029FF29292BFFA400430180000 +323D:000030184104818282428422889AB08284E28482848284829FFA400430180000 +323E:0000301851048BFA844A9FE28C3A87E2842287E2842287E29C3A400430180000 +323F:00003018488489F28892BE92892289228FFA8AAA8AAA8CCA8912400430180000 +3240:0000301848FC8F9292A2AA4294228BD2900AAFF284A28A92B10A400430180000 +3241:000030184444844288428FFA9842A8E288E289528A4A8C428842400430180000 +3242:00003018420484028FE2882288228FE288228FE2882288228FE2400430180000 +3243:000030185FF48202844288229FF2810281028FE281028102BFF2400430180000 +3244:00003FF84004BEFAA28ABEFAA28ABEFAA00AA7CAA44AA44AA7CAA01A40043FF8 +3245:00003FF8400484428442884293FABE4A844A884A924ABD4A90AA811240043FF8 +3246:00003FF8400482028102BFFA84428442844282828282810286C2B83A40043FF8 +3247:00003FF840049EF2A5229FE289429FE28122BFFA81229FE28102830240043FF8 +3248:0000FC7EE00EC0068872988A088808880888888A888ABE72C006E00EFC7E0000 +3249:0000FC7EE00EC0069C72A28A028802881C88A08AA08ABE72C006E00EFC7E0000 +324A:0000FC7EE00EC0069C72A28A02880C880288828AA28A9C72C006E00EFC7E0000 +324B:0000FC7EE00EC006A472A48A24883E880488848A848A8472C006E00EFC7E0000 +324C:0000FC7EE00EC006BE72A08A20881C880288828AA28A9C72C006E00EFC7E0000 +324D:0000FC7EE00EC0069C72A28A20883C882288A28AA28A9C72C006E00EFC7E0000 +324E:0000FC7EE00EC006BE72A28A028804880488888A888A8872C006E00EFC7E0000 +324F:0000FC7EE00EC0069C72A28A22881C882288A28AA28A9C72C006E00EFC7E0000 +3250:000000000000000077DE491049104910711E4110411041104110411E00000000 +3251:00001FF0200840049C22A262822282229C22A022A022BEFA400420081FF00000 +3252:00001FF0200840049C72A28A820A820A9C72A082A082BEFA400420081FF00000 +3253:00001FF0200840049C72A28A820A82329C0AA00AA08ABE72400420081FF00000 +3254:00001FF0200840049C92A292829282FA9C12A012A012BE12400420081FF00000 +3255:00001FF0200840049CFAA282828282729C0AA00AA08ABE72400420081FF00000 +3256:00001FF0200840049C72A28A828282F29C8AA08AA08ABE72400420081FF00000 +3257:00001FF0200840049CFAA28A820A82129C12A022A022BE22400420081FF00000 +3258:00001FF0200840049C72A28A828A82729C8AA08AA08ABE72400420081FF00000 +3259:00001FF0200840049C72A28A828A828A9C7AA00AA08ABE72400420081FF00000 +325A:00001FF0200840049C72A28A828A8C8A828A828AA28A9C72400420081FF00000 +325B:00001FF0200840049C22A26282228C2282228222A2229CFA400420081FF00000 +325C:00001FF0200840049C72A28A820A8C0A82728282A2829CFA400420081FF00000 +325D:00001FF0200840049C72A28A820A8C32820A820AA28A9C72400420081FF00000 +325E:00001FF0200840049C92A29282928CFA82128212A2129C12400420081FF00000 +325F:00001FF0200840049CFAA28282828C72820A820AA28A9C72400420081FF00000 +3260:00000FF01008200440025FF2401240124012401240124012200410080FF00000 +3261:00000FF01008200440024802480248024802480248024FF2200410080FF00000 +3262:00000FF0100820044FF2480248024802480248024FF24002200410080FF00000 +3263:00000FF0100820044FF2401240124FF24802480248024FFA200410080FF00000 +3264:00000FF0100820044FF2481248124812481248124FF24002200410080FF00000 +3265:00000FF0100820044812481248124FF24812481248124FF2200410080FF00000 +3266:00000FF0100820844082408241424142422242224412480A200410080FF00000 +3267:00000FF01008200443C244224812481248124812442243C2200410080FF00000 +3268:00000FF01008200440024FFA40824082414242224412480A200410080FF00000 +3269:00000FF01008200443E240024FFA4082414242224412480A200410080FF00000 +326A:00000FF0100820044FF2401240125FF24012401240124012200410080FF00000 +326B:00000FF0100820044FE2480248024FE24802480248024FF2200410080FF00000 +326C:00000FF01008200440024FF2400244224222424242425FFA200410080FF00000 +326D:00000FF01008200447E240025FFA400243C24422442243C2200410080FF00000 +326E:00000FF0102820245FA240A2413E41224222442248225022202410280FF00000 +326F:00000FF010282024502250225022503E50225FE240224022202410280FF00000 +3270:00000FF0102820245FA250225022503E50225FA240224022202410280FF00000 +3271:00000FF0102820245FA240A240A25FBE502250225FA24022202410280FF00000 +3272:00000FF01028202440225F225122513E512251225F224022202410280FF00000 +3273:00000FF010282024512251225F22513E512251225F224022202410280FF00000 +3274:00000FF010282224422244224622493E50A2602240224022202410280FF00000 +3275:00000FF0102820244E2251225122513E512251224E224022202410280FF00000 +3276:00000FF0102820245FE242224222453E48A2506260224022202410280FF00000 +3277:00000FF0102827A440225FE24222453E48A2506260224022202410280FF00000 +3278:00000FF0102820245FA240A241225E3E4422482250226022202410280FF00000 +3279:00000FF0102820245FA250225FA2503E50225FA240226022202410280FF00000 +327A:00000FF0102820245FA2402250A2493E49224BE27C224022202410280FF00000 +327B:00000FF010282F2440227FE240224F3E50A250A24F224022202410280FF00000 +327C:00000FF010082E8440BA5E8A44EA4A8A51AA40AA5E2252223EFC10080FF00000 +327D:00000FF010083F6C429A449A4A9A516A400A7F8A440A44FA200C10080FF00000 +327E:00000FE010102388444444444444438440044FE441044104210810100FE00000 +327F:00001FF020085EF48C428C80ED0E0E020D028C828C425EF420081FF000000000 +3280:00001FF020084004800280028012BFFA8002800280028002400420081FF00000 +3281:00001FF0200840249FF280028002800280028012BFFA8002400420081FF00000 +3282:00001FF0200840249FF2800280428FE280028012BFFA8002400420081FF00000 +3283:00001FF020085FF4929292929292929294F2981290129FF2501420081FF00000 +3284:00001FF0200840049FF2810281028FE282228222822282227FFC20081FF00000 +3285:00001FF0220841048002BFFA8002844284228812900AA00A400420081FF00000 +3286:00000FF0100822044202423243C25E02420242024212421221F410080FF00000 +3287:00001FF0200840848482848284428442882288229012A00A400420081FF00000 +3288:00001FF02208420482029FC28242824282428442844A884A503C20081FF00000 +3289:00000FE010102108410441045FF441044104410441044104200810100FE00000 +328A:00001FF0200847F48412841287F28412841287F284128412485430281FF00000 +328B:00001FF02008410489128922894291028282828284428822701C20081FF00000 +328C:00001FF0210841048112BDA285428542892289229112A50A420420081FF00000 +328D:00001FF0210841048102BFFA8102838285428922B11A8112410420081FF00000 +328E:00001FF02108428484428822B7DA81029FF28102892285427FFC20081FF00000 +328F:00001FF021084104810281029FF2810281028102810281027FFC20081FF00000 +3290:000007F0080817F424122412241227F224122412241227F21414080807F00000 +3291:00001FF028484944BDF28A429C429BFAA842A8E289528A4A484420081FF00000 +3292:00001FF022087FFC840287E28C2297E2A42287E284228422446420081FF00000 +3293:00001FF030484844BE42844289F28C429A42A842884288424BFC20081FF00000 +3294:00001FF0240847F484228A429182810287F2BC128412841247F420081FF00000 +3295:00001FF0284869F4BC42A842ABFA8C229BFAA92288A2882248E420081FF00000 +3296:00001FF020185E1493FA9E1292329E5292929F1280129252612420081FF00000 +3297:00001FF0200851F48912BF12831285F28CA29AA2AAAA892A4A1C20081FF00000 +3298:00001FF03218491489229FFA910AA1029FF2811282128412586420081FF00000 +3299:00001FF0248878548892BE9288A28DA29AAAAACA889289924E7420081FF00000 +329A:00000FF010083FFC49124FF249124FF241025FFA410A420A244C18380FF00000 +329B:00001FF0220842048202BFFA8442844288428E82818282625C1420081FF00000 +329C:00001FF030484BFC88A283FABA4A8BFA8AAA8AEA8A1A940263FC20081FF00000 +329D:00001FF02BF8491489F289129BFAAC8A8B528DEA892288C24F3C20081FF00000 +329E:00000FF012083CFC508A508A5E8A508A508A528A5CB25082208410080FF00000 +329F:00001FF030884844A3FA94428442884289F2B0429042904253FC20081FF00000 +32A0:00001FF8200441FABE4189F9890989F989098FF9B10981F94092230C1FF80000 +32A1:00001FF02448444488428FFA9842A8E288E289528A4A8C42484420081FF00000 +32A2:00001FF020085FFC900AA41287E2840287F280129FD2801240A420481FF00000 +32A3:00001FF02008400480029FF28102810289E2890289029FF2400420081FF00000 +32A4:00001FF0210841048102810281F2810281028102810281027FFC20081FF00000 +32A5:000007F0088810842FFA288A288A288A2FFA288A208220821084080807F00000 +32A6:00001FF020087FFC81028102818281428122812281028102410420081FF00000 +32A7:00001FF022084204BFFA8202840287F2888288829082A0824FFC20081FF00000 +32A8:00001FF021084104BFFA8202840287E28C229422A42287E2442420081FF00000 +32A9:00000FF010083FFC520253F254825FFA50825142522254123FFC10080FF00000 +32AA:00001FF0200840849FFA900AA7E280029FFA808288A28892529421081FF00000 +32AB:00000FF0191824A45FFA500A47E2404240825FFA40824082238410080FF00000 +32AC:00001FF03E486844BE7AA282BEA2A812BF0280029FF292927FFC20081FF00000 +32AD:00001FF02108418482428422889AB08284E28482848284825FFC20081FF00000 +32AE:00000FF011082BFC444A5FE24C3A47E2442247E2442247E23C3C10080FF00000 +32AF:00000FF0188829F448927E92492249224FFA4AAA4AAA4CCA291410080FF00000 +32B0:00001FF021087FFC848284F289929A52AD2288A2884288A24B1C20081FF00000 +32B1:00001FF0200840049C72A28A82828CF2828A828AA28A9C72400420081FF00000 +32B2:00001FF0200840049CFAA28A820A8C1282128222A2229C22400420081FF00000 +32B3:00001FF0200840049C72A28A828A8C72828A828AA28A9C72400420081FF00000 +32B4:00001FF0200840049C72A28A828A8C8A827A820AA28A9C72400420081FF00000 +32B5:00001FF020084004A472A48AA48ABE8A848A848A848A8472400420081FF00000 +32B6:00001FF020084004A422A462A422BE2284228422842284FA400420081FF00000 +32B7:00001FF020084004A472A48AA40ABE0A84728482848284FA400420081FF00000 +32B8:00001FF020084004A472A48AA40ABE32840A840A848A8472400420081FF00000 +32B9:00001FF020084004A492A492A492BEFA8412841284128412400420081FF00000 +32BA:00001FF020084004A4FAA482A482BE72840A840A848A8472400420081FF00000 +32BB:00001FF020084004A472A48AA482BEF2848A848A848A8472400420081FF00000 +32BC:00001FF020084004A4FAA48AA40ABE128412842284228422400420081FF00000 +32BD:00001FF020084004A472A48AA48ABE72848A848A848A8472400420081FF00000 +32BE:00001FF020084004A472A48AA48ABE8A847A840A848A8472400420081FF00000 +32BF:00001FF020084004BE72A08AA08A9C8A828A828AA28A9C72400420081FF00000 +32C0:0000107C304410441044107C104410441044107C104410441044104410947C88 +32C1:0000007C184424442444047C044408440844087C104410441044204420943C88 +32C2:0000007C184424442444047C044404441844047C044404440444244424941888 +32C3:0000007C244424442444247C244424443C44047C044404440444044404940488 +32C4:0000007C3C4420442044207C204420443844047C044404440444244424941888 +32C5:0000007C184424442444207C204420443844247C244424442444244424941888 +32C6:0000007C3C4404440444047C084408440844107C104410441044104410941088 +32C7:0000007C184424442444247C244424441844247C244424442444244424941888 +32C8:0000007C184424442444247C244424441844047C044404440444244424941888 +32C9:0000003E232264A224A224BE24A224A224A224BE24A224A224A224A224CA7344 +32CA:0000003E222266222222223E222222222222223E2222222222222222224A7744 +32CB:0000003E232264A224A220BE20A221222122213E2222222222222422244A77C4 +32CC:000000000000000042004204427442887E884288427042404278428400840078 +32CD:000000000000000000000002651A96A494A4F42484188410941C64220022001C +32CE:0000000000000000008200823C82424442447E444028402842103C1000000000 +32CF:00000000000000004FB8422442224222422242224222422242247A3800000000 +32D0:000003800C60101020082FE840244144418441042208240810100C6003800000 +32D1:000003800C6010102048208841044304450449042108210810100C6003800000 +32D2:000003800C60111021082FE848244824402440442048208811100C6003800000 +32D3:000003800C6010102008200847C44104410441042FE8200810100C6003800000 +32D4:000003800C60101020882FE841844284448448842288218810100C6003800000 +32D5:000003800C60111021082FE841244224444448442288210810100C6003800000 +32D6:000003800C601010220823C84F04410441F44FC42048204810100C6003800000 +32D7:000003800C601010220823E842244424484440442088230810100C6003800000 +32D8:000003800C601010240827E844844884508440842108260810100C6003800000 +32D9:000003800C60101020082FE840244024404440442FE8200810100C6003800000 +32DA:000003800C601010224822484FF44244424442442088230810100C6003800000 +32DB:000003800C601010260821084C044224404440842908260810100C6003800000 +32DC:000003800C60101020082FC840444044408441842248244810100C6003800000 +32DD:000003800C60101022082FE84224424442844204220821E810100C6003800000 +32DE:000003800C6010102008282844244424404440842108260810100C6003800000 +32DF:000003800C601010220823E842244624454448C420A8230810100C6003800000 +32E0:000003800C60101020E82F8840F45F84408440842108260810100C6003800000 +32E1:000003800C6010102208292845244424404440842108260810100C6003800000 +32E2:000003800C60101027C820084FE44084408440842108260810100C6003800000 +32E3:000003800C6010102208220842044304428442442208220810100C6003800000 +32E4:000003800C60111020882FE840844084408440842108260810100C6003800000 +32E5:000003800C601010200821E84E04400440F44F042008200810100C6003800000 +32E6:000003800C60101020082FC840444644418441842248244810100C6003800000 +32E7:000003800C60101020082FC840444084410443442528210811100C6003800000 +32E8:000003800C6010102008202840244024404440842108260810100C6003800000 +32E9:000003800C6010102008228842444424582440042008200810100C6003800000 +32EA:000003800C6010102008280849844E0448044804280827C810100C6003800000 +32EB:000003800C60101020082FE840244024402440442048208811100C6003800000 +32EC:000003800C6010102008220845044884404440242008200810100C6003800000 +32ED:000003800C60111021082FE841044544492441242508230810100C6003800000 +32EE:000003800C60101020082FE840244344408440442048200810100C6003800000 +32EF:000003800C601010230820C8460441844004460421C8201810100C6003800000 +32F0:000003800C60111021082108420442044444442427E8282810100C6003800000 +32F1:000003800C6010102008202840244224414440C420A8230810100C6003800000 +32F2:000003800C6010102FC8220843C45E0442044204220821E810100C6003800000 +32F3:000003800C60121022082FE842244144410441042088208810900C6003800000 +32F4:000003800C6010102008200847E44024404440842FE8200810100C6003800000 +32F5:000003800C601010200827E8402447E44024402427E8200810100C6003800000 +32F6:000003800C60101027C820084FE44024402440442048208813100C6003800000 +32F7:000003800C6010102248224842444244424440442088230810100C6003800000 +32F8:000003800C6010102108250845044514452445442588290810100C6003800000 +32F9:000003800C6010102408240844044424444444842508260810100C6003800000 +32FA:000003800C601010200828E84F244824484449E42E08280810100C6003800000 +32FB:000003800C60101020082FE848244824402440442048208811100C6003800000 +32FC:000003800C60109020882FE8448444845FE440842088208810900C6003800000 +32FD:000003800C60101020082FE840244344408440443FF8200810100C6003800000 +32FE:000003800C60101020082FE8402447E4402440442088230810100C6003800000 +32FF:0000203050C0484E844ABBFA004AFCCA24EA255A254A244A2C4E204A20482040 +3300:7C04040A154A192411201220200000000040004000407C600050004000400000 +3301:3E0002100A500C50085408541058000000003E00027C02040218041018200000 +3302:3E0002400A200C040818086010000000013E2282528A090C0408000800100000 +3303:3E0002000A000C7C080008001000000000000800280028002A002A002C000000 +3304:02000438080018002800087C08000000010281E941240A203020C04001800000 +3305:020004400820180428180860080000000400380008003E000800080010000000 +3306:08003E002208227C021804280848000000002000100002000C00300000000000 +3307:00007CF810081010102010507C8800004022782948248BB00828102060200000 +3308:00003E000800087C080008003E00000010003E001200127C1200120024000000 +3309:04003E4004200C04141824600C00000000003E00020004000800140022000000 +330A:04003E0004000C7C140024000C000000080008001000200022003E0002000000 +330B:10043E0812101230125012102410000024002400240024000400080030000000 +330C:10383E00127C12041204120824300000002000202A202A300228042018200000 +330D:10003E7C124412441244127C24000000240024002400247C0400080030000000 +330E:4100FCBE4A2248224822483E9000000000004000200004001800600000000000 +330F:4080FA5049084802480C48309000000000007C00040004002800100008000000 +3310:20407D2010807C001000080008000000020407D2024802400240024004800000 +3311:4080FA5C2100F8002000103E100000000000000000007C000000000000000000 +3312:10003E0008003E380808047C04000000240024002400247C0400080030000000 +3313:4080FA442114F814201510151016000040807A404900A83E1800100060000000 +3314:10003E0008003E0008000400040000000000007C004400440044007C00000000 +3315:20007CF810887C88108808F80800000041327482527490141015202740410000 +3316:4002FBC22242FA54224813D410200000020002080228FB2802AA022A022C0000 +3317:10003E3E08223E220822043E040000000008F8088AA88AAC082A104861880000 +3318:408C7A40491E88020802100460080000100010002000400044007C0004000000 +3319:408C7A40491E8802080210046008000022002210420883028A8CFA300A000000 +331A:20003C2024A044A004A808A830B000004110FCAF4A4950C941494049384F0000 +331B:10001E7C124422440244047C180000000010007C00083E100038005400100000 +331C:10001E002400047C040004000800000000003E00020004000800140022000000 +331D:00003E1002500250025402543E580000080008003E0008000800100020000000 +331E:00003E000200027C020002003E00000008403EA008A02A402A00080018000000 +331F:14043E0814101430045008101010000010001E10125022500254045418580000 +3320:14003E401420140404180860100000001008E0082010FBA02022203E40020000 +3321:20901490449024900810702000C00000010281E941240A203020C04001800000 +3322:10003E4012201404101810600E0000000400380008003E000800080010000000 +3323:10003E4012201404101810600E00000010001000100018001400100010000000 +3324:40807A404900A83E180010006000000000007C00040008001000280044000000 +3325:1C2000903E400800080008001000000000200014004400240008007000000000 +3326:2100248022003000280020002000000000000010005000500054005400580000 +3327:1000100010001800140010001000000000000040002000040018006000000000 +3328:080008003E000800080010002000000000000008000800080008001000200000 +3329:040004000454045404040808103000000800080008000C000A00080008000000 +332A:0004000814101230125022100010000000002A002A0002000200040018000000 +332B:010002805280493E48008800000000004008FA084908502C40CA430838080000 +332C:010002805280493E480088000000000000005400540004000400080030000000 +332D:010004805200483E48008800000000000000402040A044A048A850A860B00000 +332E:813E9A82E28A810C80088008781000000200FA080A28132822AA522A8A2C0000 +332F:81109A9EE2928122800280047818000000001000500050005400540058000000 +3330:204026A038A02040200020001E0000000000007C0004000400040004007C0000 +3331:40404D2070804000400040003C00000000000010005000500054005400580000 +3332:00007C0004F804080430082030400000E0220029EAA42AB020A8412086200000 +3333:00003E000208021002300450181000000020002000203E300028002000200000 +3334:0100F480122A102A10022004C01800004000280488144FD41115E11507D60000 +3335:00383E00027C0204020404081830000000002000100002000C00300000000000 +3336:00402078504808880408001000600000400078044814ABD41815101560160000 +3337:0100228052800900040000000000000000000024001400140004000800300000 +3338:0100229C528009000400003E000000002000260038002000200020001E000000 +3339:0000101028500450025400540058000000002A002A0002000200040018000000 +333A:010022A052900902040C00300000000000003E00020004000800140022000000 +333B:010022805280093E040000000000000020401520448024000800700000000000 +333C:010024805200083E040000000000000010001E0012002A000600040018000000 +333D:10827D4411485498542810083008000000202020102002300C28302000200000 +333E:10407D2410945414541510153016000010001000100018001400100010000000 +333F:08003E0008002A002A0008001800000000000040002000040018006000000000 +3340:10807D5011485482540C10303000000010801240110018001400100010000000 +3341:08003E0008002A7C2A0008001800000000000800280028002A002A002C000000 +3342:08003E0008002A7C2A0008001800000000002000100002000C00300000000000 +3343:00043E0802100230145008100410000010001E7C124402440244047C18000000 +3344:00043E0802100230145008100410000000000800280028002A002A002C000000 +3345:00003E0002540254140408080430000000000000140012001200220000000000 +3346:00003E1002500250145408540458000010001E00120022000200040018000000 +3347:00007C8004400408283010C008000000000040202B9088824B8C10B0E3800000 +3348:1820043C30240844000430080C30000000003E402220220422183E6000000000 +3349:1800040030000800000030000C00000000480048004800480008001000600000 +334A:1848044830480848000830100C600000010004845214481449D5881500160000 +334B:04000400040028001000280040000000020407D2024802400240024004800000 +334C:09020BE90924512021205120824000002000208020403008283020C020000000 +334D:020002000200147C080014002000000010001010105018501454105410580000 +334E:100010003E00127C140010001000000021002480220030002800200020000000 +334F:100010003E00127C140010001000000000000800280028002A002A002C000000 +3350:007C1C040414041804103E100020000000002000100002000C00300000000000 +3351:2400240024542454040408083030000010001010105018501454105410580000 +3352:2400240024002400040008003000000000380000007C00040004000800300000 +3353:1102513551C551025500550058F000000000000000007C000000000000000000 +3354:000008002800287C2A002A002C0000000080FA44091408140815101560160000 +3355:0000200020002200240028003000000000100010002000400044007C00040000 +3356:0000408040404408483050C06000000088208E949442C400A401840688180000 +3357:00003E0022542254020404081830000010001000100018001400100010000000 +3358:001018102410241E24102410247C244424442444247C24442400245418AA00AA +3359:001010103010101E10101010107C104410441044107C1044100010547CAA00AA +335A:001018102410241E04100410087C084408441044107C1044200020543CAA00AA +335B:001018102410241E04100410047C184404440444047C04442400245418AA00AA +335C:001024102410241E24102410247C3C4404440444047C04440400045404AA00AA +335D:00103C102010201E20102010207C384404440444047C04442400245418AA00AA +335E:001018102410241E20102010207C384424442444247C24442400245418AA00AA +335F:00103C100410041E04100810087C084410441044107C10441000105410AA00AA +3360:001018102410241E24102410247C184424442444247C24442400245418AA00AA +3361:001018102410241E24102410247C184404440444047C04442400245418AA00AA +3362:001026106910291E29102910297C294429442944297C29442900295476AA00AA +3363:001022106610221E22102210227C224422442244227C22442200225477AA00AA +3364:001026106910291E21102110227C224422442444247C2444280028547FAA00AA +3365:001026106910291E21102110217C264421442144217C21442900295476AA00AA +3366:001029106910291E29102910297C2F4421442144217C21442100215471AA00AA +3367:00102F106810281E28102810287C2E4421442144217C21442900295476AA00AA +3368:001026106910291E28102810287C2E4429442944297C29442900295476AA00AA +3369:00102F106110211E21102210227C224424442444247C24442400245474AA00AA +336A:001026106910291E29102910297C264429442944297C29442900295476AA00AA +336B:001026106910291E29102910297C264421442144217C21442900295476AA00AA +336C:000863089488948F1488148824BE24A224A244A244BE44A2848084AAF3550055 +336D:000862089608920F12081208223E222222224222423E42228200822AF7550055 +336E:000863089488948F10881088213E212221224222423E42228400842AF7D50055 +336F:000863089488948F1088108820BE232220A240A240BE40A2848084AAF3550055 +3370:000864889488948F1488148824BE27A220A240A240BE40A2808080AAF0D50055 +3371:0000000043C042204220422053CC6A124A024A0E4A124A124A164A0A00000000 +3372:0000000002000200020002003A3C46424202423E4242424246463A3A00000000 +3373:000000000842144214421442224222423E422242414241424142413C00000000 +3374:00000000400040004000400071944A5A485249D04A504A504AD0715000000000 +3375:0000000000820082008200827882844484448444842884288410781000000000 +3376:0000000000000000000000005C3C6242424042404240424062425C3C40004000 +3377:0000000001000100010001001D682354415441544154415423541D5400000000 +3378:001E0002021E0210021E02003AD046A882A882A882A882A846A83AA800000000 +3379:001E0002020E0202021E02003AD046A882A882A882A882A846A83AA800000000 +337A:000000007C8410841084108410841084108410841084108410847C7800000000 +337B:0000000A0009FE091008927F524854481078FE551055109510D610B5110A0010 +337C:00001E300AEEEA4AAAFAAA4AEA4AB6CAA0EAAEDAEB4AAA4A0E4E0A4A00000000 +337D:0000000010FE10101010FE5010501050285E2850285044504450445082FE0000 +337E:000000010E81EA42AA02AA94EE55AA17AA21AA20EE6FAA290A29122F26290000 +337F:2A057F842A3F7702A23A27122AB90000104428F4441EBA2400D4FE4424447A5F +3380:0000000000100028002800285C446244427C4244428262825C82408240004000 +3381:00000000001000280028002858446444447C4444448244824482448200000000 +3382:00000000001000280028002811441144117C12442282228222823D8240004000 +3383:00000000001000280028002868445444547C5444548254825482548200000000 +3384:00000000801080288028802884448844907CA044D08288828482828200000000 +3385:00000000407C4042404240424242447C48425042684244424242417C00000000 +3386:00000000417C4142634263425542557C49424942414241424142417C00000000 +3387:000000003C7C42424242404240424E7C424242424242424246423A7C00000000 +3388:00000000000C00040004000471E48A14801481F4821482148A3471DE00000000 +3389:00000000800C80048004800493649494A414C474A49494948CB48F5E00000000 +338A:0000000000FE0080008000805C8062F842804280428062805C80408040004000 +338B:0000000000FE00800080008058F8648044804480448044804480448000000000 +338C:00000000007E004000400040227C2240224022404440444044407B4080008000 +338D:00000000000000000000000411341148114811482230222022383DC440444038 +338E:0000000000000000000000086868549054905490546054405470548800880070 +338F:0000000040004000400040044234444848485048683044204238414400440038 +3390:000041004100410041004100413E7F0241044108411041204140417E00000000 +3391:000084408440844084408440945E97C2A444C448A44894508C608C7E00000000 +3392:00008A408A40DA40DA40AA40AA5E8BC28A448A448A488A488A508A5E00000000 +3393:0000000072408A408A408240825E83C29E448A448A488A488A507A5E00000000 +3394:00000000FC8024802480248024BE2782248424882488249024A024BE00000000 +3395:00000000000800140014002411281148114822502252226222645DD840004000 +3396:000000000008001400140024762849484948495049524962496448D800000000 +3397:0000000002080214021402243A284648424842504252426246643BD800000000 +3398:000000004008401440144024422844484848505068524462426441D800000000 +3399:000000001C0022002000200078C8213421242124212421242124212400000000 +339A:00000000000000000000000059D8652445244524452445244524452400000000 +339B:00000000000000000000000022A422DA229242924492449244927B9280008000 +339C:00000000000000000000000034682A542A542A542A542A542A542A5400000000 +339D:0000000000000000000000001C682254405440544054405422541C5400000000 +339E:0000000040004000400040004268445448545054685444544254415400000000 +339F:001E0002001E0010001E000068D054A854A854A854A854A854A854A800000000 +33A0:001E0002001E0010001E000038D044A880A880A880A880A844A838A800000000 +33A1:003C0004003C0020003C00002CC0332022202220222022202220222000000000 +33A2:001E0002801E8010801E800084D088A890A8A0A8D0A888A884A882A800000000 +33A3:001E0002000E0002001E000068D054A854A854A854A854A854A854A800000000 +33A4:001E0002000E0002001E000038D044A880A880A880A880A844A838A800000000 +33A5:003C0004001C0004003C00002CC0332022202220222022202220222000000000 +33A6:001E0002800E8002801E800084D088A890A8A0A8D0A888A884A882A800000000 +33A7:0002D004A808A810A820A840A880A978AA840280047808041084207840008000 +33A8:0010D02EA822A84EA888A88EA900AA78AC840480087810041084207840008000 +33A9:000000003E0021002100210021783E842004207C20842084208C207400000000 +33AA:0000000081C0812081208120853C89C29102A11ED12289228526831A00000000 +33AB:0000000089C08920D920D920A93CA9C28902891E892289228926891A00000000 +33AC:0000000071C0892089208120813C81C29D02891E892289228926791A00000000 +33AD:0000000000020002000200025B1A64A640A247A248A248A249A646DA00000000 +33AE:008200840084B188CA889A90AA90AAA0AAAC9DD20090010C01020212040C0800 +33AF:0090009E0092B1AECAA89AAEAAC0AAC0AA989DA400A001180104022402180400 +33B0:0000000000000000000000005C786284428042704208420462845C7840004000 +33B1:0000000000000000000000005878648444804470440844044484447800000000 +33B2:000000000000000000000000113C1142114011382204220222423DBC40004000 +33B3:0000000000000000000000006878548454805470540854045484547800000000 +33B4:0000000000820082008200825C82624442444244422862285C10401040004000 +33B5:0000000001040104010401045888648844884450445044204420442000000000 +33B6:00000000008200820082008222822244224422444428442844107B1080008000 +33B7:00000000008200820082008234822A442A442A442A282A282A102A1000000000 +33B8:000000008104810481048104850488889088A088D05088508420822000000000 +33B9:0000000082828282C682C682AA82AA4492449244822882288210821000000000 +33BA:000000000222022202220122591465144494449444B464C85848404840004000 +33BB:000000000222022202220122591465144494449444B444C84448444800000000 +33BC:000000000222022202220122251425142494249448B448C84848764880008000 +33BD:000000000222022202220122691455145494549454B454C85448544800000000 +33BE:000000008222822282228122851489149094A094D0B488C88448834800000000 +33BF:0000000083228322C722C722AA94AA949294929482B482488248824800000000 +33C0:000000004070408841044104490449045104610451044888448847DE00000000 +33C1:00000000443844446C826C82548254824482448244824444444445EF00000000 +33C2:00000000000000000000000030D048A808A838A848A848A858A82AAA00000000 +33C3:000000003C0022002200220022343C4C224421442144214C22343C0400040004 +33C4:0000000000000000000000001C382244408040804080408022441C3800000000 +33C5:0000000400040004000400043C74428C4084408440844084428C3C7400000000 +33C6:001070208840808081008A0076010A4D125222924312828C0248024E0011000E +33C7:000000003C0042008100800080708088808880888088818842883C7200000000 +33C8:0000000004F804840484048474848CF884848482848284828C8474F800000000 +33C9:000000001E0021004100400040424042402243A44114411823081D1000100060 +33CA:0000000020002000200020002C7832842204227C22842284228C227400000000 +33CB:00000000427C42424242424242427E7C42404240424042404240424000000000 +33CC:00000000000010001000000030B810C4108410841084108410847C8400000000 +33CD:0000000041414242444448485050606060605050484844444242414100000000 +33CE:0000000045044504458C498C5154615451244924450445044504450400000000 +33CF:0000000040004020402040204278442048205020682044244224411800000000 +33D0:000000003000100010001000100010EC109210921092109210927C9200000000 +33D1:000000003000100010001000100010BC10C210821082108210827C8200000000 +33D2:000000006000200020002002271A28A428A428A428982890289CF7220022001C +33D3:00000000300010001000100011021084104810301030104810847D0200000000 +33D4:00000000008000800080008034B82AC42A842A842A842A842AC42AB800000000 +33D5:000000000018008800880008698854885488548854885488548857FE00000000 +33D6:00000000000C000400040004D1C4AA24AA24AA24AA24AA24AA24A9DF00000000 +33D7:000000007C4242424242424242427C7E40424042404240424042404200000000 +33D8:00000000000000000000000058D064A844A844A844A878A840A844AA40004000 +33D9:00000000E72294A294B694B694AAE72A84228422842284228422842200000000 +33DA:000000007C7C42424242424242427C7C40484048404440444042404200000000 +33DB:0000000000000000000000003C2C4232402038200420022042203C2000000000 +33DC:000000001E0021004000400030820C82034400C400A840A821101E1000000000 +33DD:0000000088A088A088A088A044BC45224D224D22552222222222223C00000000 +33DE:000000022204220822102220144014B4092A0A2A042A082A102A202A40000000 +33DF:00000802140422083E102220224022B4012A022A042A082A102A202A40000000 +33E0:0000107C30441044104410441044107C10441044104410441044107C7C440044 +33E1:0000187C24442444044404440844087C08441044104410442044207C3C440044 +33E2:0000187C24442444044404440444187C04440444044404442444247C18440044 +33E3:0000247C244424442444244424443C7C04440444044404440444047C04440044 +33E4:00003C7C20442044204420442044387C04440444044404442444247C18440044 +33E5:0000187C24442444204420442044387C24442444244424442444247C18440044 +33E6:00003C7C04440444044408440844087C10441044104410441044107C10440044 +33E7:0000187C24442444244424442444187C24442444244424442444247C18440044 +33E8:0000187C24442444244424442444187C04440444044404442444247C18440044 +33E9:0000267C69442944294429442944297C29442944294429442944297C76440044 +33EA:0000227C66442244224422442244227C22442244224422442244227C77440044 +33EB:0000267C69442944214421442244227C22442444244424442844287C7F440044 +33EC:0000267C69442944214421442144267C21442144214421442944297C76440044 +33ED:0000297C694429442944294429442F7C21442144214421442144217C71440044 +33EE:00002F7C684428442844284428442E7C21442144214421442944297C76440044 +33EF:0000267C694429442844284428442E7C29442944294429442944297C76440044 +33F0:00002F7C61442144214422442244227C24442444244424442444247C74440044 +33F1:0000267C69442944294429442944267C29442944294429442944297C76440044 +33F2:0000267C69442944294429442944267C21442144214421442944297C76440044 +33F3:0000319E4A524A520A520A521252125E12522252225222524252425E79920012 +33F4:0000311E4B124912091209121112111E11122112211221124112411E7B920012 +33F5:0000319E4A524A52085208521092109E10922112211221124212421E7BD20012 +33F6:0000319E4A524A52085208521052119E10522052205220524252425E79920012 +33F7:0000325E4A524A520A520A52125213DE10522052205220524052405E78520012 +33F8:000033DE4A124A120A120A121212139E10522052205220524252425E79920012 +33F9:0000319E4A524A520A120A121212139E12522252225222524252425E79920012 +33FA:000033DE48524852085208921092109E11122112211221124112411E79120012 +33FB:0000319E4A524A520A520A521252119E12522252225222524252425E79920012 +33FC:0000319E4A524A520A520A521252119E10522052205220524252425E79920012 +33FD:0000319E4A524A520A520A520A52325E0A520A520A520A524A524A5E31920012 +33FE:0000311E4B124912091209120912311E09120912091209124912491E33920012 +33FF:00000000000600020002040234E24912481248F231122112393244D744003800 +3400:0440044004400440044004407C7C0440044004400440044004400440FFFE0000 +3401:0000FFFE010001003FF82108210821082288224824282828200820083FF82008 +3402:0100010001F83F000104010400FC100010201020163CF8E010221122161E1800 +3403:0100028004400820101020084004FFFE01000100010001000100010001000100 +3404:01000100010001003FF801002100210041007FFE010001000100010001000100 +3405:0000001000102020102008400440028001000280044008201010200840000000 +3406:001000F81F0010001FF810081FF810081FF810001FFC10042004200440288010 +3407:020002003FE00420042008223022C01E00007FF0006001800600180420041FFC +3408:060001000280044008203018C0063FF80010006001800600180420041FFC0000 +3409:00007FFC01000100010001000100050002007FF0006001800600180420041FFC +340A:010001000100FFFE010001003FF8000000007FF0006001800600180420041FFC +340B:0100010001003FF801000100FFFE000000007FF0006001800600180420041FFC +340C:080008001FFC200041008100117013901D10F11011501122110210020FFE0000 +340D:00FC7F00020821081110102000003FF80010006001800600180420041FFC0000 +340E:020001007FFC0820044003801C70E00E00003FF80010006003801C0420041FFC +340F:00003FFC010001001FF0021004107FFE00007FF0006001800600180420041FFC +3410:10001000FEFC22844488285010202858C58600007FF0006003801C0420041FFC +3411:08001FF0282007C01830E18E0C40030000807FF0006001800600180420041FFC +3412:00007FF8040808503020DFF8100810081FF800007FF0006003801C0420041FFC +3413:0000FFFE00101F90109010901F90005000207FF0006001800600180420041FFC +3414:02000100FFFE00001FF0101010101FF000007FF0006001800600180420041FFC +3415:010001003FF8210821083FF8210821083FF800007FF0006003801C0420041FFC +3416:082008200820FFA0082008207F20002000207F204120412241227F22411E0000 +3417:02083FD00220FFFE02000C703F84C80407FC00007FF0006003801C0420041FFC +3418:010011100920FFFE054009203118C10600007FF0006001800600180420041FFC +3419:00007FFC00001FF010101FF008200440FFFE00007FF0006003801C0420041FFC +341A:7FFC02003FF00410FFFE00001FF010101FF000007FF0006003801C0420041FFC +341B:0840084017FC3080510093F81508110811F800007FF0006003801C0420041FFC +341C:1040144012401040FEF8104810489248544810483848548A928A110A52062400 +341D:11001100F9F8120819E83128D1E81008505020207FF0006003801C0420041FFC +341E:082008207FFC08200FE008200FE00820FFFE10102FE8404483820C0810080FF8 +341F:044004407C7C04403C7804407C7C044004407FF0006001800600180420041FFC +3420:07A0F82048A025207F20022007A2FC2244220C1E00003FF001C01E0420041FFC +3421:200027FC204023F8FAA82AA82AA82A1828402FFC28A029122A0A480247FE8000 +3422:203C17C08244492813F8E01027FE202020A000407FF0006003801C0420041FFC +3423:00803FFE20802FF8208027F0249027F024903FFC20802FF840604380840403FC +3424:204023F8204021F0F91029F0291029F0291029F029102BFA28A2491247FE8000 +3425:100829C8455EB94A11CA7D4A11CA55523D6AE38400003FF001C01E0420041FFC +3426:3BB822083BB82488FFFE10502788C1061FF0010003003FF001C01E0420041FFC +3427:0080108008800480048000807FFC01840288049008803080C080008002800100 +3428:00007CFC0404282810100808FEFE121214141010101010101010101050502020 +3429:24242424242424247E7E242424242424FEFE2424242424242424444444448484 +342A:020001000100FFFE0000010021082108210821083FF80288044008203018C006 +342B:020001000100FFFE00000820044022882108228824482828200820083FF80008 +342C:02000100FFFE0400082010103FF810080000111011101110211021124112800E +342D:02000100FFFE000000003FF82008200827C82448244827C8200820083FF82008 +342E:02000100FFFE1010244844441FF004401FF004407FFC04900C603518C6060400 +342F:01007FFC08201FF010101FF000001FE001007FFC09203FF8C8260FE008200FE0 +3430:080009FC0904110411043104310451049104110411041104110411FC11041000 +3431:0100010002800440082010502188C606382000C007003818006003807C000000 +3432:0840084008401040104037FE30405040904010A010A010901110110812041402 +3433:080008000BFC10901090309030905090909010901090109211121112120E1400 +3434:08800880088010FC110431043284544890281010101010201040108011001600 +3435:08000BFC08401040104030403FFE504090401040104010401040104011401080 +3436:080008000BFC120412043204320453FC92041200120012021202120211FE1000 +3437:08000FF00810101012103210321053FC90041004100417F41004100410281010 +3438:08800880088010FC1104310832405440904010A010A010901110110812041402 +3439:0900090009FC1200140031F83000500093F8100810081008100A100A10061002 +343A:1120112011202220222066206620AA2022202250225022502248228822842302 +343B:082008200820102013FE3222322252229252124A128A130212021202120A1204 +343C:080808680B88108810883088308853FE90881088108810881108110812081408 +343D:08000BF80A081208132832A832A85248924812A812A8132A140A140A18061002 +343E:080008000BF810001000300037FC5120912011201120112012221222141E1800 +343F:081008780BC01040104033F830405040904017FE104010401040104011401080 +3440:084008400840104017FE3040304050A090A010A0111011101288124814441802 +3441:084008400A4812481248324833F8504890401040144414441444144417FC1004 +3442:100017FC10402040204067FC6444A44424A42494251426042404240424142408 +3443:1220122012202420257C69246E24A2242424242429242F242144204420942108 +3444:080009F8090811481128312837FE520892481228122813FE1008100810501020 +3445:09000900090011FE1240324034405040907C1040104010401040104017FE1000 +3446:08000BFC0A0412041204320433FC5090909010901090111211121212140E1800 +3447:0880088008F811081210342033FC50049004100411FC10041004100413FC1004 +3448:08400840084017FE108031203120522093FC1020112811241222142210A01040 +3449:100017F81408240827F864886488A4E82528252826A8244A244A288A29063202 +344A:08400820082017FE109030903090529492921292149210901110111012501420 +344B:10A010A010A020A027FC64A464A4A4A424A427FC24A424A424A424A427FC2404 +344C:08000BFE0A00120013FC3220322052F892201220122013FC1200120013FE1000 +344D:1040104017FC2040204063F86040A04027FE20E0215021502248244428422040 +344E:1000124812482490249062486248A00020402444244424442444244427FC2004 +344F:084008200BFE120214143010301053FE90101110109010901010101010501020 +3450:084008400840107C1040304037FE500090401040125012481444184411401080 +3451:08400840088013FC12043204320453FC9204120413FC12041204120413FC1204 +3452:01000280044008203018CFE6010001001FF0111011101FF0028004401830E00E +3453:082008400888110413FE3042304057FE908010FC114411441228121014681186 +3454:08000BFE0820104011FC31043104512491241124112411441050108811041204 +3455:082008200A221222122233FE3040504090FC1104128414481050102010C01700 +3456:111011101110221022FE66926692AA92229222FE229222102210221022102210 +3457:088009000BF8120813F8320833FA520A920C17F810181028104811881E281010 +3458:1014101210102FFE201062906292A2922FD2229422942288228A249A24262842 +3459:10001FFE14802490249067906490A490249027902490249224D22F92208E2080 +345A:100017DE12522252225467D46258A25422522FD22252225A2254245025502890 +345B:084008400FFE1040104037FC3444544497FC104010E0115012481C4610401040 +345C:1208121C126022402FC06240627EA2C823482E4822482248224822482A882508 +345D:100017FC1040204023F860406040A7FC211021102FFE21102110221022102410 +345E:104010401244224424A861106208AC06211021102FFE21102110221022102410 +345F:0808081C09E01100110031FE311051109110111017FE10001090110812041402 +3460:08800AFC0AA412A412A8329032A850C69020102011FC10201020102013FE1000 +3461:100017BC14A424A424A467A464A4A4A424A427A42434252824A0256026202020 +3462:09000900091E139211123112311257D291121112121A129417D0125010101010 +3463:091009100910111017BC31103110533893B81554155419921110111011101110 +3464:111011101FFE21102110600067FCA4442444244427FC24442444244427FC2404 +3465:08000BF80A0813F8120833F83100510093FC1494189411241244148411281210 +3466:084008200BFC1204120433FC32005228922413FE122012501250148815041A02 +3467:103813C0104027FC20E061506248AC4623F02020204027FC2040204021402080 +3468:08000BF80A08120813F83100310053F8944010401FFE104010A0111012081C06 +3469:08000BFE0A521252125233FE3020504090FC1104128810501020104011801600 +346A:084008200FFE11081090306031985606910811F8110811F81108110812081408 +346B:0840084008A011101288344633F0501090A01040114815041514151418F01000 +346C:12101210121022102F7E65106510A510257C29442544224422442544257C2844 +346D:100017FC1444244427FC64446444A7FC200020002FFE22082208220824082808 +346E:08000BFE0A22102013FE302031FC512491FC112411FC102013FE102010201020 +346F:08000FFE0840108013FC3204320453FC920413FC1204120413FC100011081204 +3470:090009F80A0813F0101037FE30805144966810B01128166810A4112216A01040 +3471:08000BF80890106017FC30A4312852209460104017FC10E0115012481C461040 +3472:104010401FFE2040204067FC6514A4A425F42444244425F42444244424542408 +3473:090009000BFE1442125233F230825114960813FE14421A5213F2108211141608 +3474:0BF8080809F8100813F8300037FC544493F812481258104013F8111010E0171E +3475:0820081009FE110011203520333C51509190131015FE11101128122812441482 +3476:0900090009FC120015F8300033F8508892A811C817F8108A11CA16AA10861082 +3477:11101212145427D82010601267D2A44E244027D22454245827D024522552248E +3478:084008400FFC104013F8320833F850009FFE100813E8122813E8100810281010 +3479:0100028004400FE03118DFF611101FF011101FF000000FE008200FE008200FE0 +347A:08A0089009FE132015FC312031FC512091FE110013FC1088109E1102120A1404 +347B:1080104017FE2402289460506524A54A28FA2300204024442444244427FC2004 +347C:10101010103C2FA42AC46AA86A90AFA82AC62A802ABC2AA42FA428A4203C2024 +347D:1040144412482FFE280263F86208A20823F82040204027FC204020402FFE2000 +347E:084008FC09081650112030C033205FFE900013FC100013FC100013FC120413FC +347F:124814901248200023F8624863F8A24823F8204027FC20E0215022482C462040 +3480:1080104017FC211020A067FC6444A5F4244425F42514251425F4240424142408 +3481:100017FC1444244425F4644467FCA51424A425F4244427FC2444244427FC2404 +3482:090809080FFE1108104433F43048505097FE108011FC130415FC190411FC1104 +3483:08140BFE081013D0101033D0301053D0925013D0125013C8124A13CA11861242 +3484:0910091409D21250127E3550309052A89128114412441482100812A412521452 +3485:08200BFE084010F81348303033D0503C91C41048103013C410A8119016A810C6 +3486:084008A0091816E6100033F8320853F8900017BC108414A4129414A412941108 +3487:1100110013FC26A82AA862A867FCA2A822A822A82FFE200022A8225424542000 +3488:10081788108821102FDE649464A4A79424942794249424C827882C9420A420C2 +3489:08400A48095017FC140431F03110511091F0104017FC10E01150124814461040 +348A:100017BC129426B42AD464A465ACA8402108210825A8252C252825A82E7E2000 +348B:14801482149C2FD024906790649EA794249424942FD42014251428A430242044 +348C:1110155415B8291022A864446000A7FC240429E821202120212022222422281E +348D:088009100BF8121014A437BC3080511093E01040108817FC1044124815441080 +348E:08000BF8088017FC111032083CA650A097BC10A013B810A017BC10A010A010A0 +348F:084008200FFE149213FC309033FC509097FE1108120414621010118010601010 +3490:0910091009DE12A81444310031FC520495F4111411F4111411F4111410281010 +3491:100017FE14282624257E644864C8A47E2648257E24482448257E264027FE2000 +3492:10A014A412A820A027FC611060A0A7FC204023F8204027FC215022482C462040 +3493:10101410127C201020FE60446628A2FE2210227C221022FE2210221025FE2800 +3494:100017FC14A424A427FC620063FEA4422BFA224A23FA2052207A278A22142008 +3495:1040102017FE20282224627E64C8A748217E224824C82F7E21482248247E2840 +3496:1110111017FC211023F8624863F8A24823F8204027FC2444245425F42414240C +3497:111017FC111021F0211061F06110A7FE24022BFC211023F8204023F8204027FC +3498:100017BC15142794248867886514A7A22080204027FC2000220821102FFE2000 +3499:11081110123E22A224BE6F22613EA20824BE2FAA20AA202A2AAA2AAE28082008 +349A:103E17C01244212823F8604067FCA00023F8200823F8200823F82544252A28FA +349B:100017BC108424A4229464A46120A21027FC2A2023FC222023FC222023FE2200 +349C:09400A4C0A641244134C326432A453AC92A412A417FE10001110110812041404 +349D:09080FFE0908100013FC3294329453FC902813FE1220132412A81292142A18C6 +349E:08200A220BFE109011FE331035FE511091FE111011FE110013DE125212721206 +349F:104017FE100023FC224063F86240A3F8224023FC2004255420A823102D482186 +34A0:110011BC152427A824906AA86146A2A027BC20A023B820A027BC20A02FFE2000 +34A1:11821E3C10882A902522643C6788AA12223E2F8822082AAC2AAA2BCA2EA82090 +34A2:104010A0111022082DF660006EEEAAAA2EEE20002FFE29222FFE2922292A2804 +34A3:1040102017FE24A824FE6550677CA550257C2550257E254028A42A8A328A2478 +34A4:0BFC090809F8110811F8310E37F8500897FE1294139C1294139C12D617BC1084 +34A5:115013F8155427FC255467FC6554A7FC200027FC200023F8220823F821102FFE +34A6:17FC144417FC244427FC60006FBEAAAA2FBE2AAA2FBE2040204027FC20402FFE +34A7:141812141F90253E2AA86DE868BEAFA822282FBE2AA82AA82BA828BE2AA02920 +34A8:104015F6191229B22D5669B26912ADF620802FFE220825F4291221F0210420FC +34A9:11F0121013E0202027FC61886650A1A8266421A022482FBE2AAA2FBE228A2FBE +34AA:03800C603EF8E8A63EF822883EF828A03EF8100011FC5CA0515450B85D54E0B2 +34AB:00000FF8080008000FF008000800FFFE0440044004400440084408441044603C +34AC:00007DFC002000200020FCF8282028202820282029FC28002800480247FE8000 +34AD:00003E7C22442244224422443E7C1428142814281428144A254A268A44868100 +34AE:000001FE7820004000A20334FC5828942B34285228922B502822480247FE8000 +34AF:108813FE9088540059FC10A8FCA82BFE28A828A829FC28202BFE4C2048208020 +34B0:060001000280044008203018C00600001FF0010001000100010001007FFC0000 +34B1:060001000280044008203218C20607F00810141022200140008003001C00E000 +34B2:060001000280044008203018DFF61010101010101FF01010101010101FF01010 +34B3:00007FFC4104410441045144492449245554638C410441044104410441144108 +34B4:060001000280044008203118D116111011101FF001002108210821083FF80008 +34B5:040008003FF8200820083FF8200820083FF80000000004400820101020084004 +34B6:04400440082010102108C2061FF01010101010101FF01010101010101FF01010 +34B7:00001FF0101011101110111012901450101010107FFC00000440082010102008 +34B8:0820042004407FFC020006001908629004A018C061A002980C863080C2800100 +34B9:10101010FEFE10107C7C44447C7C44447C7C44447C7C4444FEFE282844448282 +34BA:00007FFC4004482444445FF440044884488449444A2448044FF4400440144008 +34BB:7FFC40045FF440045FF400001FF010101FF010101FF010101FF004421842E03E +34BC:08200820FFFE082008200FE001007FFC4104514449245554638C410441144108 +34BD:3FF820082FE820082FE8111009207FFC0400FFFE10102FE8C82608A0084807F8 +34BE:00003FF820082FE820082FE820401040FEFE21203CAC24F427A444AC54A2887E +34BF:3FF820082FE820082FE808007F281424497E55C87F7E08487F7E55485D7E4340 +34C0:00007FFE40028004020002000200020002800240022002100200020002000200 +34C1:000000007FFE4002844408201010000000000000000000000000000000000000 +34C2:00007FFE400280243E2001FE00447E4414C814281410146A2586240243FE8000 +34C3:00007FFE4002900408007F1C00E03E2000203E3E01E03E22222222223E1E2200 +34C4:101022107F10421094FEF79208923610C92830A8C428192862480C4A308AC106 +34C5:0000400023FE202000200820082010201020E020202020202020202020A00040 +34C6:0040404020A020A001100A080C0611101120E140218021002104210420FC0000 +34C7:0010407827C0204000400840084017FE1040E0A020A021102110220824040802 +34C8:0000400027FE204000400880088011F81308E508290821082108210821F80108 +34C9:0010407823C02040004007FE104010402040E3F8220822082208220823F80208 +34CA:000047FC2404240405F40404140415F42514E514251425F42404240424140408 +34CB:011041102110211007FC0110111011102110EFFE200021102108220824040804 +34CC:0040404020A021100208040613F810402040E04023F820402040204027FE0000 +34CD:00804040204027FE00800110120817FC2124E1202120212022222222241E0800 +34CE:000043F8200821F800080BF8080017FC1404E3F02110211020A0204021B0060E +34CF:000047FC240424A40514060C140415F42514E514251425F42514240424140408 +34D0:0040404023F82040004007FC111012082444E04023F820402040204027FC0000 +34D1:0040404027FC204000400FFE111010A027FCE04020402FFE2040204020400040 +34D2:2040104004780BC47044103C110012800C603118C10609901148214805000200 +34D3:004040402FFE2040004007FC151414A425F4E444244425F42444244424540408 +34D4:010842082788248807BE0488178814C824A8EFA8218822882488288822A80110 +34D5:00144012201027FE0410041017F214922492E5B426D42488254A293A2A261042 +34D6:000047FC244427FC044407FC124812482FFEE248224827FC20402FFE20400040 +34D7:010047BC21142394011407A4114C10802110E3E0204827FC2044224825440080 +34D8:00003FF820082FE8210823C824482A88210826083BE8210A2FEA414A41269FF2 +34D9:0200010001001FF040444844448442844104428444444824502440047FFC0004 +34DA:000400047F04082408240824082408240824082408240F24F004400400140008 +34DB:000001FC00447E440844084408440844084408440E84F0844104010402280410 +34DC:0800080010FC102422244224FC2404240824102424244224FE44424400940108 +34DD:22042204220422247F24222422242224FFA42224222422242204420442148208 +34DE:0800080008FC7F240824082408247F24082408240824FFA40844084408940908 +34DF:0404040404043FA424A4252424243FA420A42924252422242504488490940008 +34E0:08040804080408240FA40824082408247F24412441244124410441047F144108 +34E1:200420043F04482488240824FF24082408244924492449044F04790401140008 +34E2:100410041F042124612492240C2412242124C0A43F242124210421043F142108 +34E3:08040804140422244124BEA4002400243E2422242224222422043E0422140008 +34E4:080408040804FFA4082408247F24002400247F244124412441047F0441140008 +34E5:08044904290429242A240824FF240124012401247F24012401040104FF140108 +34E6:0004FFC40804082410247F244124412441247F2441244124410441047F144108 +34E7:0804080414042224512488A47E240224042408247F244124410441047F144108 +34E8:080408040804FFA408242A242A242A245D2488A4082414241204210441148008 +34E9:100410041F0421244224BFA424A424A43FA424A424A43FA42484448442948108 +34EA:100008007EFC422442247E24422442247E244024482444244A44524460944108 +34EB:08040804FFC41224212440A4BF241224122412247FA412241204220422144208 +34EC:080449042A047F2408241024FFA42224412480A47F241124110421044A148408 +34ED:00047F0441047F2441247F2420247FA488A448A454A440A47E84008405140208 +34EE:00043F84248424A42EA424A43FA420A42EA42AA42AA42EA42084408442948108 +34EF:2484248449049224492424A424A400247FA448A448A47FA4488448847F944088 +34F0:0004FF84080408243E24AAA4AAA4BEA4AAA4AAA4AAA4BEA480848F84F0940008 +34F1:0804140422044124BEA4002478A44AA44AA47AA44AA44AA47A8448844A945908 +34F2:080204023FC2204220523FD2201220123FD2355235525FD255425542944A10C4 +34F3:00083E0822483E4822483E480048FF48084808482F082828281058004FFE8000 +34F4:0004FF84080410247F2455245524552455244B240824FFA41404220441148088 +34F5:0004F784948494A4F7A400247F240024FFA4202440247F24010401040A140408 +34F6:20042F04F504252475242524F5242924232408240824FFA41404220441148088 +34F7:080410047F0441247F2441247F2441247F240824FFA41C242A04490488140808 +34F8:00047704550455247724142414247724412441247724142414041F04F0144008 +34F9:00047FC4440454A4652444244A24512460A4442454A4652444044A0491142088 +34FA:08040F8408047FA448A44F2478A447A4482444247FA441245A0444048A143108 +34FB:0004FF84948494A4FFA400240024FFA4082408244F24482448044F84F8140008 +34FC:08040804FF841C242B24C8A414242224492488A449242A244904888428141008 +34FD:0804490449047F2410240824FFA480A43F240024FFA408242A044904A8941008 +34FE:00027FC240427FC242124A9247124A9250524A124FD252124202BFE2820A0204 +34FF:070478040804FFA42A24492494A42224492488A449242A244904888428141008 +3500:00047F0441047F2441247F240824FFA400247F2441247F240804490488941808 +3501:050472041284512421245EA480A43F24212421243F2421241204078478142008 +3502:0404248415047FD4151424944454209420943BF44894AA8413E4208440948088 +3503:108010F825107BFC112425247DFC0102550294FE00007FF80408080810506020 +3504:00027FC20A027FC24A524A527FD2041224921512FFD20E1215022482444A0404 +3505:04023F8204827FC204923F920412555275D244527FD2445275C25542554A8444 +3506:0004F7842104A524F7A46324B5A421247FA440A440A47FA4408440847F944088 +3507:0904F6441284A12440A4F7641524152479A440248F24F1241504120455142908 +3508:22042204FF84222414241424F7A414241424772414241424F784140414141408 +3509:00027FC240427FCA400A5FCA420A5FCA524A5FCA420A7FEA62A26FA2A0AA2064 +350A:0402FFE200027FC240525F5251527FD200123F9220923F9220823F82000AFFE4 +350B:00047A0452047BA44A247B2454A478A400247F245524552455045784FC140008 +350C:FC044B8478844AA479244D24FAA40CA407A4F82428A44D241A042904C8940808 +350D:42047BC4A50410A47FA440A47FA440A47FA440A47FA42124FFC4210441148108 +350E:52107EFE28447E28A2FE3E1020103E7C22103E1000007FF80408080810506020 +350F:00027FC210023F8A508A108A1F8A000AFBEA208A79EA492ACB22492279EA4924 +3510:210221023DE2528288527FD20A127BD20A123B920A127BD20A020FC2F80A4004 +3511:0820FFFE28207DFC44887C5041FE7C2045FC7C2000007FF80408080810506020 +3512:44427FC212023FC26212BFD222123FD222123FD220127FD251426EC24A4A4EC4 +3513:04200E207820082008FC08240824FF2408240824082408440844088409280A10 +3514:100010007E7C1244124412442244227C4A4484001FF02008200820081FF00000 +3515:202020203F20402080FC7E24002400247C240424052405240344014400A80110 +3516:100010007E7C1244124412442244227C4A44840000003FF00010001000100010 +3517:1210121012107F9012FE12927F92521252127FD212521252235222A2422A8244 +3518:102010209220922092FC9224FE24102410249224922492449E44F28401280210 +3519:4220242000207E2024FC242424242424FF242424242424242444444444A88510 +351A:04200E203820082008FCFF24082408243E2422242224222422443E4422A80110 +351B:010001007FFC01001FF000001FF0101010101FF002007FF80408080810506020 +351C:02200F20F020012091FC4A240024FE24042408240F24F8444844088429281210 +351D:0010FF9008100810FF9088FE8892CC92AA92AA92DD929992889288A28AAA8144 +351E:02200F2078200820FF7C08242A242A24EBA42A242AA46B24AA44084408940908 +351F:082028203EF8482808A83E48084A0EAA7926020202007FF80408080810506020 +3520:00207E2042207E2042FC7E2420247F2489244924552441247D4401440AA80510 +3521:082010207F20552049FC552441247F2400244424772444245544664444A80110 +3522:108010F825107BFC112425247DFC0102550294FE02007FF80408080810506020 +3523:00083F8824883F8824BE3F8A000AFBEAAAAAAAAAFBEAAAAAAAB2FBF2002A0044 +3524:102008207F20412086FC782449242A24FF242A244124BE242A443E442AA83F10 +3525:0010FF10A510A510FF7E44129492F7120492F3929012F4929712F42294AAB3C4 +3526:2210FF9008107F10107EFF9222124912BE9222123E1222123E9225222A2A3144 +3527:08100F9008107F9048FE7E1248925F9255125F1255125F124012BFA22AAA7FC4 +3528:100010003FFC4524BDC405141CF464041FC410441FC410441FC4104411541088 +3529:100010003FFC22045FC482043FE4040408841FC400041FC4154415443FE80010 +352A:100010003FFC2204420483F402043FE42AA42524326425242AA43FE420280010 +352B:0400040004000400FFFE0480048004840488089008E0108210822082407E8000 +352C:203021C03E0820081FF800001FF010101FF010101FF00100FFFE010001000100 +352D:000043F84208420843F87A08420843F8400047FE40404A4052786240454008FE +352E:51105112FA5453D870102012FBD2AA4EFA4023D2FA542258FBD0225252528ACE +352F:00007FFC400047F044104410480C500047F044104410441047F040007FFE0000 +3530:00007FFC4220422043A044B044A844A44AA4512041204220442048207FFE0000 +3531:00007FFC400042804CB848884EB848884FF8414042204410580840007FFE0000 +3532:00007FFC422045204AA05F7869284F2849284F28482A4A2A4D4648807FFE0000 +3533:00007FFC420045384AA85F6869284F2849284F2A482A4A4A4D4648807FFE0000 +3534:00007FFC40004FF848884FF848884FF842204FF842205FFC441048087FFE0000 +3535:7FFE40005E7852485E7851444F3C42204FF8422042205FFC4220441048087FFE +3536:7FFE44207FBC4A647F9840665F7C51105FFE51445F7C44447FFC442844447FFE +3537:00007FFC40004FF8408040804FF8488849484A284C284808482848107FFE0000 +3538:7FFE4000403E4FC0487C48404BFE4A424A784AC44A3C520054F06494490C7FFE +3539:104010401040104011FC1044FE44104410441084108410841104110412281410 +353A:0100010001007FFC0100110011201020FFFE102010201022100210020FFE0000 +353B:00007FFC010003000560191861040100000001000100FFFE0100010001000100 +353C:10A01090FDFE13201DFC3120D1FC112051FE210000000100FFFE010001000100 +353D:0100010001FE010001003FF82008200827C82448244827C8200820083FF82008 +353E:00003FE02020202020202020202020202140208020002004200420041FFC0000 +353F:0000FFFE10101010101010101010101010101070119016101810001000100010 +3540:010001003FF821083FF821083FF800001FF0101010101052102210020FFE0000 +3541:010032000C7C124469440844FFC410442444244448448A5411483F4011400040 +3542:00003FFE208020802140222024102908308620802FF020102020402040408080 +3543:00003FFE2000200027FC21102110211021102FFE211021102210421044108810 +3544:00003FFE200020002FFC20802100221024202FC020802100221044084FFC8404 +3545:00003FFE2000200027FC2444244427FC2444244427FC24442040404040408040 +3546:00003FFE2000204020402FFE20402040204027FC240424042404440447FC8404 +3547:00003FFE20002080204020402FFC20002408220822102110212040005FFE8000 +3548:00003FFE2080204020003FFE20802100228426882A5032202210428843068200 +3549:00003FFE208020802140222024102BE83006200027F024102410441047F08410 +354A:00003FFE2000204820442FFE204027FC244427FC244427FC2444444444548408 +354B:00003FFE2080214022202410280837F6208020802FF82080249042A05FFE8000 +354C:00003FFE200027F8240827F8240827F820002FFC20103FFE2410421042508020 +354D:00003FFE22802240224027FC24402C4037F82440244027F82440444047FC8400 +354E:00003FFE208020802FFC20803FFE220024082FFC20002FFC292449247FFE8000 +354F:00003FFE20003F8820482F282908294829282F0E20782908260843885C088808 +3550:00003FFE2100263824082738240827F8220027FC280425542554480440288010 +3551:00003FFE220422043FC422042FBE20042FA428942F942884250443845C148808 +3552:3FFE240822103FFE20802FFC20803FFE20A02F2822243FFE42285F12822A06C6 +3553:00003FFE200027FC255424E427FC204027FC20402FFE24A4285247FC40408FFE +3554:3FFE20103F102AFE2E102AFE2EAA2AAA3EFE22003EFE2A205E144AA2BF280218 +3555:0100010002000420081010083FFC10040100010002000420081010083FFC1004 +3556:0400082010103FF80810102024487EFC02040100FFFE054009203118C1060100 +3557:41002210FF9008107F200820FFA0104010483E8442FC84040800140023FEC000 +3558:0400082010103FF80810102024487EFC010006C01830E10E0920111025080200 +3559:1080108020F04510FE2029FC4524A3243D2445FC4450A858109428924512820E +355A:00003FF01010121011200920082044402440228001000280044008203018C006 +355B:00003FF000201E40018006601818E0043FF010100820044003800C603018C006 +355C:010001003FF8210821083FF8010001003FF010100820044003800C603018C006 +355D:010001007FFC010001001FF0101010101FF000003FF00820044003801C70E00E +355E:00003F00217C21243F242424242424283F283528351055105528972804440482 +355F:080008000F0008FC08447F445544554455287F28551055105528512845444282 +3560:4140212003FE0A2017FCEA2023FC222023FE02003FF00820044003801C70E00E +3561:08000F00087CFFA480A47F2414242228492816282110FE10222822283E442282 +3562:10001E00107CFF4481447E4400447E2842287E2842107E1042287E2824444282 +3563:00400840082010201010200840049FF2101010101010101010101FF010100000 +3564:01000100790049004BF04910491049104910491079104A1202120412080E1000 +3565:004000407C404440444044404440444044A044A07CA045100110020804040802 +3566:00001FF01010101010101FF0010001000100FFFE02800440082010102008C006 +3567:000001FC790449044904490449FC490449004900790049000200020004000800 +3568:000001F0791049104910491049904950495049107910491202120212040E0800 +3569:0020002078204BFE48204820482049FC4820482078204BFE0020002000200020 +356A:0040004078404BFC4A444C484840484048A048A078A0492001220222041E0800 +356B:0080004078404FFE49004900490049F849084908790849080208020804500820 +356C:002001207920491049104A484A484C444882488079104908020807FC02040000 +356D:001000787BC048404840484048404FFE484048A078A048900110010802040402 +356E:0020011079084A044A044C104910491048A048A0784048A00110020804040802 +356F:0100010001007FFC410442844444482457D444444444444447C4444440144008 +3570:0008003C79E048204820483C49E048204820483E7BE04820002200220022001E +3571:00900088788848804FFE48A048A048A048A048A07920492201220222021E0400 +3572:00400040F040904097FE904090E090E091509150F24894440842004000400040 +3573:00000008790848884A524A524A224A224A524A927B0A4A0A020203FE00020000 +3574:000000007BFE4A024C04480049F04910491049107910491202120212040E0800 +3575:000003FE7820482048204820482049FC48204820482078204820002007FE0000 +3576:000003FC78404840484048404BF8488848884888788849080108010807FE0000 +3577:00200020784049FC490449044904490449FC4904490479044904010401FC0104 +3578:00800040784048004FFC480048084A084A08491079104910012000200FFE0000 +3579:00400048784448404BFE4880488048FC4944494479484A500220045008880306 +357A:00007CF84488448844887CF800000000FFFE080010001FF00010001000A00040 +357B:0200010000007FFC010003000D603118C10401001FF01010101010101FF01010 +357C:0100010079FE4A024A024C8A48524A224A524A8A7A024BFE0002000200140008 +357D:0008008878484A284A284A084A084A084A084A084A107A984B24022400420082 +357E:0100010009200910110821044104000000403E4422482270224022423E42223E +357F:00701F8001000100FFFE054009203118C0061FF010101010101010101FF01010 +3580:004000407BF848484FFE48484BF8484048404BF87840484007FC004000400040 +3581:00080190786048984B04484048404FFE48804890791049200248048409FC0084 +3582:004000407BF84A484A484BF84A484A484BF848407848483000640194060C0004 +3583:0008003C7BC04A004A004BFE4A004A004A004AFC7A844A840484048408FC0084 +3584:0104012479244924492449244BB44B6C4D244924792449240124022402040404 +3585:00280024782448204BFE4A204A244A244A244BA87A284A100212042A04460882 +3586:00500050785048504BFE4A524A524A524A524BFE7A524A520252025203FE0202 +3587:000003FE7820482048404BFE4A524A524A524A527A524A5202520242020A0204 +3588:02083FD00220FFFE02000C703F84C80407FC00001FF01010101010101FF01010 +3589:002000207850488849244A224C204920493C492079204920012007FE00000000 +358A:000003FC7804480449FC480448044BFC480848084FFE79084888008800280010 +358B:0100028004401830E44E0440044004400840104000007C8844B044C47C84447C +358C:0880088013F03090509090921112120E140000003E442258226022423E42223E +358D:0040044002401240084009FC7E400040004000003E442258226022423E42223E +358E:00807C8844B044C444847C7C0100028004401830E44E04400440044008401040 +358F:000001FC7904490449FC4904490449FC4820482079FC48200020002003FE0000 +3590:7CF8448844887CF800003FF002100210FFFE021004103FF0081010002000C000 +3591:0014001278104FFE48104A904A924A924FD24A947A944A88028A049A04260842 +3592:0108008878904BFC482448244BFC4A204A204BFE786248A2012A022404200020 +3593:010001F87B084C90486049984E4648404BF848407BF8484007FC004000400040 +3594:000001FC7820482048204BFE4850488849044AFA7C8848880088008800F80088 +3595:0040002079FC4800488848504BFE48204820482079FC48200020002000200020 +3596:020001003FF808200440FFFE010001003FF8010001003FF8200820083FF82008 +3597:004002487A484A484BF8484048A049104A884C4678404BF00010002000200040 +3598:000003FC7A004A004AF84A004A004BFC4AA04AA47AA84A900290048804A408C2 +3599:100010007E7C124412441244227C4A44840000003E442258226022423E42223E +359A:0810081017FE30105210911011101050102000003E442258226022423E42223E +359B:010001007FFC010001001FF0101010101FF000003E442258226022423E42223E +359C:02000100FFFE00001FF0101010101FF0000000003E442258226022423E42223E +359D:010001003FF801000100FFFE09203118C10600003E442258226022423E42223E +359E:000001FC79044904490449FC482048204BFE4A227A524A8A030A0202020A0204 +359F:001C03E0F08492449148911097FE9402900093F8F108911000A0004001B0060E +35A0:002000207BFE4850488849044AFA480048004BFE782049240122022200A00040 +35A1:00800040F7FE91209120923C9244966492949348F24892300220025002880306 +35A2:00800040EFFEA800A890A890AA90AA92AADCAA90EA90AA92129212D2270E0000 +35A3:0040002079FC48004908489048004BFE4800480079FC49040104010401FC0104 +35A4:000001FC780848104A224AAA4A724A224A724AAA7B264AA20242020203FE0002 +35A5:000007FCF404943495C49444944497FC944494E4F554964C0444044407FC0404 +35A6:00400040F7FC904093F8924893F8924893F89040F0E0915002480C4600400040 +35A7:001C03E07A204BFE4A204A924B0A4A0649FC4904790449FC0104010401FC0104 +35A8:000001F87808480849F8480848084BFE48204A22797448A80124022200A00040 +35A9:00000FC0F4BC94A494A497A494A494A897A894A8F49095D00EA800A800C40082 +35AA:0014001278104FFE481048104BD24A524A524A547BD4480800EA071A02260042 +35AB:0020002079FC482048204BFE488849444A4248F879884A500020005001880606 +35AC:0080031C7A044A044B9C4A044A044BFC480048007BF849080090006001980606 +35AD:000003FCF040904097FE90A09110920894469040F04892640252045201400080 +35AE:00400040F0A0911092089DF6900097FC94A494A4F7FC94A404A404A404140408 +35AF:3FF820082FE8200827C8244827C82028201000003E442258226022423E42223E +35B0:00807C8844B044C444847C7C00003FF820082FE8200827C8244827C820282010 +35B1:0100FFFE088010F83148D328149010601198160600003FF8200820083FF82008 +35B2:10001000FE7C2244444434440844147C2244C0003E442258226022423E42223E +35B3:1080088047FC21100A1011A070601090130800003E442258226022423E42223E +35B4:011001107BFE49104880488049FC49544A544C9478A449240244008401280210 +35B5:000001F87908490849F8490849F8490849F8490879084FFE0000011002080404 +35B6:000007FCF0A090A097FC94A494A494A497FC9040F04097FC004000400FFE0000 +35B7:000001FC7904490449FC4904490449FC48004BFE78204920013C012002A0047E +35B8:0040007C78404BFE4A424A784BC04A444A3C4A007AFC4A8003FE0480048008FC +35B9:0010011079084A044DFA488849084A284C104BF87AA84AA802A802A80FFE0000 +35BA:00400040F7FC904093F8908097FC9110920895F6F110911001F00110011001F0 +35BB:000003F8F090906097FC90A49128922094609040F7FC90E0015002480C460040 +35BC:008800887BFE4888488848F84888488848F848207BFE487000A8012402220020 +35BD:000003FE7820484049FC4904490449FC490449FC7904490401FC000000880104 +35BE:00007EFC428442847EFC10100820FFFE0100210821083FF8040808003000C000 +35BF:00000FDEF4929492949497949498949497929492F49295DA0E94009000900090 +35C0:00400040E148A148A94AAA52AAD6AB5AA94AAA52ED6AAF7A094A08420FFE0002 +35C1:000003DE7A524A524BDE480049FC48004BFE4880790049FC0004000400280010 +35C2:00200020792449224A2A483048C04F0049FC490479FC490401FC010401FC0104 +35C3:000003FC7A044BFC4A204BFE4A104A8A4B0648007BFC4A0403FC020403FC0204 +35C4:000003FC7A944A944A944BFC488048404FFE488078F848880108010802280410 +35C5:0100013C79244FE44924493C49244BA44AA44ABC7AA44AA403A4004400540088 +35C6:008800887BFE488848F8482049FC4924492449FC78204BFE0020002000200020 +35C7:000003DE7A424A424A424BDE4A004A3E4BD24A127A144BD40208021402240242 +35C8:000003FC788848504BFE4A224BFE4A224BFE4A2278404BFE0042008201140208 +35C9:08007F7C08243E2408447F54088804000FE0144003801C70EFEE08200FE00820 +35CA:00003EF822882288228822883EF8000000007EFC42844284428442847EFC4284 +35CB:0080008079FC4A044C084BFE4A004A804AFC4B207A204BFE0420045008881306 +35CC:0040002079FE49024A0449FC4840488849FC4824782049FC0020002003FE0000 +35CD:003803C0F040904097FC91509248944693F89208F20893F80208020803F80208 +35CE:02000200F7BC92A492A494A495BC9840904097FCF0E091500248044408420040 +35CF:000003FE78104820486848A44B22482048004BFE78204920013C0120012007FE +35D0:004000407BFC484048A049104A884C4648004BF87AA84AA802A802A80FFE0000 +35D1:010003BCEE10A210A23CAF90A210A23CA210AF90E27EA2100210021004100810 +35D2:00800040F7FE900093F892089208920893F890A4F12893100510094801860100 +35D3:00100420F2F89288908890F89E80928092FC9284F28492FC0284050008FE0000 +35D4:0040007C78404BFE4A424A784BC44A3C4A404A207BFE4A880250042004580986 +35D5:008800887BFE488849FC48884BFE482049FC492479FC492403FE010401140108 +35D6:003C03C078444A244928490048404B9C4A044A047B9C4A040204020403FC0204 +35D7:00407C8045FC452445247DFC212421447DFC2490251027FE4410441094100810 +35D8:002800247BFE482049FC492449FC492449FC492478084BFE0088004800480018 +35D9:0080008079FC4A44495449F4488449284A9049FC7A444D5401F4008401280210 +35DA:000007FCF0A090A097FC94A494A497FC90409040F7FC90E0015002480C460040 +35DB:02100210F3DE95289884903893C09040904097FCF04090A000A0011002080C06 +35DC:00800040F7FC9080910893F09060918497FE9002F7FC944407FC044407FC0404 +35DD:01040084788848004BFE4820482049FC482048207BFE480002A4025204520000 +35DE:000800087788527E524A544A57485D7C55545554755457540548008801140022 +35DF:2080104087FC4040104023F8E040204027FC200000007C8844B044C47C84447C +35E0:084008407E8413FE220214FC0884148462FC00003E442258226022423E42223E +35E1:0440FFFE0440100027F86110A13C21042214240800007C8844B044C47C84447C +35E2:01C8070871085FE8511E57CA554A57CA554A57CA710A57CA011201D20E2A0444 +35E3:02A802A877FC52A852AA54E6580057FC5444504073F852480248024802580040 +35E4:002800243FFE2220232422242FA822182A92522A464680820FF808080FF80808 +35E5:0200011E77D2501257D4545457D8501457D25092711251DA0714011005100210 +35E6:00101F20EACEAAAAAEAAAAAAAAAAAEAAAAAAAAAAEBEAAEAC1A28024802480288 +35E7:004000207BFE4A8A49044BFE4840488849FC4824782049FC0020002003FE0000 +35E8:00007F7848485F4C64805F7844484A4851307F4C00003FF8200820083FF82008 +35E9:000003DE78424A52494A4A524842482049FC4904790449FC0104010401FC0104 +35EA:009000927AD44A9A4AD24F4E488849F0482048447BFE48220128022404A20040 +35EB:010001107BDC4A544D544A8849084AF44C0248007BFC48400150024805440080 +35EC:111009207FFE40029FF410101FF002000FE034C00700388003F81D3001C03E00 +35ED:001C01E07820492448A84BFE487048A849244A227840482402A2028A04880078 +35EE:202020103DFE4510457CA9141914117E21147D14A57C251025283E2802440482 +35EF:01081FD001207FFC02000FF03810CFF008100FF000007C8844B044C47C84447C +35F0:01240124722454245954514A529256105A105250725C5250025002B0029E0300 +35F1:014001207BFE4E204BFC4A204BFC4A204BFE4A4078404FFE015002480C460040 +35F2:004003F878484FFE48484BF848404FFE48004BF87A484BF8024803F8000007FE +35F3:021002107BDE4A284D4448A049104A084DF6480078004BF80208020803F80208 +35F4:079E0492F79E9492979E940294F2949294F29492F4F294920492053204020406 +35F5:02100290EA90AB3EB222A544A890B210A290AB10EA28B228052808C410440082 +35F6:002403A878924D144A084C044BBA48A848C64B807A3C4B8400A8009002A80144 +35F7:002003FE7A5249FC485049FC48504BFE480049FC790449240124005800840302 +35F8:0280048EE8E0B140A040A24EA5F4AC44B444A554E554A5740594040404140408 +35F9:0140012073FE56205BFC522053FC5220522053FE724050240522050A08F80000 +35FA:000003F8708057FC511052085CA650A057BC50A073B850A007BC00A000A000A0 +35FB:000004F8728852E850A850A85DFC55045574555475745504051405080A0011FE +35FC:00A004A4F2A890A097FC911090A097FC904093F8F04097FC015002480C460040 +35FD:11002BDE4A5273D42A524BD27A1A12942350C24000003FF8200820083FF82008 +35FE:05100518EFA8A528A76AA2AAAFAAAAACAAACAFA8E238AFAA022A022A02260220 +35FF:0000079E7492579E5492579E540255FA541255D2755255D204120452042A0404 +3600:008003387A084BB84A084A084BF848404A4849504FFE78E0495002480C460040 +3601:000007FCF4A497FC904093F8904097FC911090A0F3F890400FFE004000400040 +3602:010800907BFE490849084A524B9C49084A524BDE784048A402AA028A04780000 +3603:008803FE788848204BFE484048F849884A8848F87840482402A2028A04880078 +3604:020002FEE2AAA2AAAFAAA2FEA620A710AAFEAA20F220A23C0224024402540288 +3605:02400240E4AEA890B300A2E0A45EAC44B5E4A444E554A4E4044404640584040C +3606:00400FFEE040A7FCA000A3F8A208AFFEA802A7FCE110A3F8004007FC00400FFE +3607:01100554F5B8991092A89444900097FC94449040F7FC90E0015002480C460040 +3608:0400057CF60494A89390907C941497949A5092509FDCF250955004B0089E0100 +3609:02100210F3DE95289084900097BC94A497A494A4F7A49434052806A004200020 +360A:07FC0040EFFEA842A358A040A358A080A040AFFEE000A7FC000007FC040407FC +360B:07DE051277D2545457C8551457E2500053FC520473FC520403FC020403FC0108 +360C:020203C2E202AFEAAA2AAB8AAE4AA9CAA80AAFEAEA0AAD4A0A820DC212AA2584 +360D:0108014CE52AA548A88EA138A288A7EABC8AA7ECE48CA7E8048A07FA04260442 +360E:040002FEE202A802AB92A892AFDEAAAAABCAAAAAEB92AAD20FAA08C608820806 +360F:211017FE108003F8F20813F8120813F8120813F8280047FE00903EE422843E7C +3610:001007C8753E57C0551457D25522550057D450547554554805480454005401A2 +3611:041004101F7CE414A414AEFEA014AE14A07CBF10E45404381654251214500820 +3612:0C3871E0102013FEFD2431FC392455FC502093FE10007C8844B044C47C84447C +3613:07BC04A4F7BC94A497BC944495F4944495F49554F5F4955405F404E40554044C +3614:004007FE749253FC509053FC509057FE510853FC750A51F8010801F800900108 +3615:009007FE78904BE84A884BCE4A504BD44AA24BE278004BFC0294029407FE0000 +3616:0200011EEFC4A448A29EAFD2A912AA1EAC92A91EEA12AC52089E0900120C0412 +3617:07BC04A4F7BC94A497BC94A497BC912093FE9220F7FC9A2003FC022003FE0200 +3618:210447C88812F3BC20084B92F83E0380AAAAABAA00003FF8200820083FF82008 +3619:07BC04A477BC500057FE54005590549E57D4556475D4555405D405680BC81054 +361A:0FBE08A2EFBEA8A2AFBEA802AB92A892AFDEAAAAEBCAAAAA0B920AD20FAA08C4 +361B:004000A073185DF6500053F8520853F8511057DC72844FFC045007DC045204CE +361C:51184B947C3ED3A87C7E53A87C3E53A87EBE43A000003FF8200820083FF82008 +361D:00007FFC400440044FC44044484444844284410442844444484440047FFC4004 +361E:00007FFC4204420442045FE4422442244224442444244824494450847FFC4004 +361F:00007FFC40044444444444445FF444444444444448444844504440047FFC4004 +3620:00007FFC4004420441444144448454A45514665444444BC4500440047FFC4004 +3621:00007FFC400440045FF4511451145FF4511451145FF45114410441047FFC4004 +3622:00007FFC41044924452445445FF442844284428444944894507440047FFC4004 +3623:7FFC400447C4444447C440044FE448244FE448244FE4482448A448447FFC4004 +3624:00007FFC4144655455544774641457F44414577465544554495450147FFC4004 +3625:FFFE8002861AF8E2AA42949290E2BE4AC8FABE2288AAAB26BE628002FFFE8002 +3626:104010401040104011FCFE44104410441044108416841884E104410402280410 +3627:100011F8100810501020FC1013FE10221024102010201C20E020402000A00040 +3628:202020202020202023FEFA22222222222252224A228A3B02E2024202020A0204 +3629:10101110111011121112FD1411D811101110111011101D12E1524192010E0000 +362A:1008103C11E010201020FC3C11E010201020103E13E01C20E02240220022001E +362B:108810881088108811FCFC881088108813FE108810881C88E088410801080208 +362C:21002100210021FCFA042484208421042144222427F43A14E004400400280010 +362D:20802080213E21022242FA4227C220822082210221423A22E7E24222000A0004 +362E:100011FC110411041104FD0411FC11241120112011101D10E208420804040802 +362F:10801080110011FE1200FC40104013FC1044104410841C84E104410402280410 +3630:10101110109010901010FD10109010901010101E13F01C10E010401000100010 +3631:10201020102011FC1124FD2411FC11241124112413FE1D04E104410401140108 +3632:200023FC2204220423FCFA402240224023F8224822483A48E488448A090A0206 +3633:044004447C48047004400C423442C43E010001003FF8010001000100FFFE0000 +3634:01000110791049104910492849247944010001003FF8010001000100FFFE0000 +3635:10401040104017FE1080FCA0112011FC1324152411241D24E134412800200020 +3636:081008101EFC221052900C9008FE10102010411001003FF801000100FFFE0000 +3637:1110111013FC11101110FC00120812081110111010A01C40E0A0411002080C06 +3638:0000FFFE104010443E484270A44018421042213EC1003FF801000100FFFE0000 +3639:0880088828902EA028C028842E84F07C010001003FF8010001000100FFFE0000 +363A:2120212821242224FA20263E2BE022242224222822283A10E212422A02460282 +363B:200023FE220222222222FA2223FE222222222252224A3A8AE302420203FE0202 +363C:1040104411F410481050FDFE1040108011FE124014801CFCE004400400280010 +363D:084008487F4408440840FFFE0040084408447F440828082A0F12F02A40460082 +363E:2040202023FE22022404F80021FC20202020202023FE3820E020402000A00040 +363F:100011FC1104110411FCFD04110411FC1020102011FC1C20E020402003FE0000 +3640:2080204027FC24042110FA082484208023F0209020903910E1124212040E0800 +3641:1080108010FE110012FCFC8410A4109413FE108411241D14E1FE400400280010 +3642:110410841088101011FCFD041104110411FC105010501C90E0924112020E0400 +3643:1010103811C011001100FDFC111011101110111013FE1C00E090410802040402 +3644:11101112111411D81110FD121152118E1120102011FC1C20E020402003FE0000 +3645:200023F8220822082208FBF82040204027FC20E021503A48E444484200400040 +3646:2040202023FE22022444F84023FE20402090209021103920E224424204FE0842 +3647:100013FE104010801144FE24106812B0113012A810681CA4E122422000A00040 +3648:20402040207C204023FCFA44227023C02244223C22003AF0E49044920912120E +3649:10501050105011FC1154FD54115411FC115411541D54E3FE4000008801040202 +364A:200021FC210021F82100F9F821002FFE2280224822503A20E210428803060200 +364B:1088108813FE10881088FCF81088108810F810881C88E3FE4000008801040202 +364C:1020102011FC102413FEFC2411FC10201124112411741DACE124412402240424 +364D:200027BC208422942108FA9424A42840200027BC20A43AA4E128429004A80846 +364E:2014201227FE2410F41027F02492249227D225543554E488454A0A1A08261042 +364F:1100110011FE120015FCFD0411FC110411FC108010FC1D08E290406001980606 +3650:102011241124112411FCFC0013FE1020104011FC11541D54E15441540154010C +3651:00F03F0001001FF011101FF001007FFC412441F45E14400801003FF80100FFFE +3652:00F87E084A504A207EFC4A244A287E2000A0014001003FF801000100FFFE0000 +3653:010001003FF80100FFFE08203EF808200E2078FC01003FF801000100FFFE0000 +3654:1040104011FC108413FEFC0011FC110411FC102013FE1C20E22043FE00200020 +3655:200023FE222223FE2222FBFE200021FC210421FC210439FCE104410401140108 +3656:1004101E13E0102011FCFD24112411FC102013FE12221E2AE2FA4202020A0204 +3657:200023F82248224823F8FA48224823F8200027FE22403A44E228429003080206 +3658:200023FE2050205023FEFA52225223FE2000204027FE3888E190406000D80304 +3659:2120111097FE4128493409281132E124223A2262259E01003FF801000100FFFE +365A:1088105013FE102011FCFC2013FE100010A010FC11201C20E3FE402000200020 +365B:1028102413FE102011FCFD2411FC112411FC11241C08E3FE4088004800480018 +365C:0100FFFE00001FF010101FF000007FFC40044FE448244FEC01003FF80100FFFE +365D:204021FC204420942108FBDE214A214A229421FC210439FCE10441FC0104010C +365E:1020104011FC110411FCFD0411FC110411FC102013FE1C70E0A8412402220020 +365F:2100209E23D222522252FBDE2252225223D2221E22923A52E2D24352022A0044 +3660:7F7848485F4C64805F7844484A4851307F4C000001003FF801000100FFFE0000 +3661:21242124222424242954F94A229226102A102250225C3A50E25042B0029E0300 +3662:2088208823FE20882088F8F8202023FE2222233222AA3B76E2224222022A0224 +3663:20002F3E2120213CF1202F3C282028FE28502F523154E148414801440A620440 +3664:2040207C204023FE2242FA7823C4223C220822F023243AA8E5FE442008A00040 +3665:2080204027FC2110FA482484212023F02010208821503B20E510494801860100 +3666:0808144822285C8888487F0E08F82A084908180801003FF801000100FFFE0000 +3667:200023FE205023DE2252FA5223DE205023FE222222223BFEE222422203FE0202 +3668:224822482554275C2248FD54275C22482FFE222022283A28E5144494042C0844 +3669:2040204027FC20A02514FA0827FC2A0A23F8220823F83840E248444409440080 +366A:202023FE202021FC2000FBFE220221FC200021FC210439FCE104408803FE0000 +366B:10A0109011FE132011FCFD2011FC112011FE11001C20E3FE407000A803260020 +366C:081408127F102AFE2A105D101C282A284944888201003FF801000100FFFE0000 +366D:20002FFE28002A28F9482BEE289228842AA02AA83BE8E8884894091409241242 +366E:2210221023DE22282544F8A02110220825F6200020003BF8E208420803F80208 +366F:08203E2008F87F282228496A3E2A08567E8200003FF80000FFFE082010103FF8 +3670:10001EFC22247F44A99C3F50297C3F9029FE29104510821001003FF80100FFFE +3671:00207C3C44207DFE0122FD3841E47D1C05702A54148C01003FF801000100FFFE +3672:2040202027FE20282224F27E24C82748217E224824C8377EE1484248047E0840 +3673:2014201227FE2410F5D0241425D4255825CA24163442E82442A2028A04780000 +3674:210021F8220827FE2288FB2423FE220022FC220022FC3A00E2FC448404FC0884 +3675:102013FE100010F81088FCF8100013FE120212FA128A1EFAE22641F8002003FE +3676:0100FFFE10101FF00000111009207FFE40029FF410101FF001003FF80100FFFE +3677:200023FE220223FE2202FBFE21082252239C210822523BDEE00042A402520452 +3678:212821AA216C2228FAFE264426282AFE2210227C22103AFEE210422802440282 +3679:2088208823FE208823FEFA5223FE200023FE224220F83908E290406000C00700 +367A:27FE242025FC252425FCFC2027FE250425FC250425FC3D04E5FC4488050407FE +367B:202027FE240025FC2524F5FC252425FC242025FC242037FEE5244AFA082013FE +367C:23F82248224823F82248FA4823F820002FBE2AAA2AAA3FBEEAAA4AAA0FBE08A2 +367D:2020202027FE202023AEF92423AE22AA23AE22AA23AE3850E050408801040602 +367E:22A0244C24A4260CF4A4264C24A42FFE280223F03020E04047FC004001400080 +367F:211027FC204023F82040F7FC200023D4211227FE23503534E78C42CA045608C2 +3680:210821EC210A27E8F52825DE272824EA240A27EA340CE7EC4A2A0BEA115607E2 +3681:101010107C7C1010FEFE4444EEEE44446464DEDE0000FEFE28282A284C4A8886 +3682:204027FC224823F8F0402FFE2AAA23B8211027FC3110EFFE412803100D480186 +3683:010001007FFC01001FF000007FFE400284442388244820083FF8082004407FFC +3684:01007FFC01001FF000007FFE51129FF411101FF000007FFC010411F0290047FE +3685:020007E00820144003801C70E00E1FF0010011001FF821005FF00100FFFE0000 +3686:02000100FFFE00001FF010101FF010101FF008000FF01420224041800E60701C +3687:044022882108228824483FF81210220847E4082014402280010006C01830E00E +3688:1010101010101E101210221022FE52108A100410041008100810101020104010 +3689:00003FF008100820083C120417E438544588068039F80610192000C003003C00 +368A:202020103C1045FE4820A824104428F84E12122224445588081010282044C182 +368B:200021FC3D2445244974A92411FC29044F74135425545574090412042214C408 +368C:200021FC3D24452449FCA924112429FC4E2013FE247054A8092412222020C020 +368D:202021FC3D2445FC4820ABFE100029FC4F0413FC250455FC090411FC2088C104 +368E:010001007FFC0280044008203018C0060000200820082008200820083FF80008 +368F:010001007FFC0280044008203018C006082008207FFC08200820102010202020 +3690:010001007FFC010002C004201810600801000100FFFE0280044008203018C006 +3691:00003FF8000800081FF8000800083FF801000100FFFE0280044008203018C006 +3692:0100010001007FFC01002120111011102928454402800280044008203018C006 +3693:010001007FFC028004400820311001007FFC0380054009203118C10601000100 +3694:020002007FFC044008203018C82604403FF801000100FFFE0100010001000100 +3695:020002007FFC044008203458C4467FF804483FF824403FFC0844105420484040 +3696:010002001FF0101010101FF0101010101FF0010001007FFC028004401830E00E +3697:020002007FFC044008203018DFF6101010101FF010101FF010101010FFFE0000 +3698:10201020102010207DFC102010201020FDFE1020105010502888248845048202 +3699:100010007E7C124412441244227C4A4485000100FFFE0280044008203018C006 +369A:020002007FFC044008203218C7E608203440028003001FF0E81008100FF00810 +369B:020002007FFC0440082038D8CF06081007F000001FF010101FF010101FF01010 +369C:020002007FFC044008203098C0A63FF800803E8022483E5000240E54718C0604 +369D:020002007FFC044008203018C806084013F8304057FC904013F8104017FC1000 +369E:020002007FFC044008203018C82608207EFC08201C702A6848A4892208200820 +369F:08001FC020807FF0A0103FF020883CF420843D7C01007FFC028004401830E00E +36A0:020002007FFC044008203458C2863FF801001FF001007FFC0000248822444244 +36A1:10101010FEFE101028284444FEFE040474745454545474745454040414140808 +36A2:10801080108020802FFE61086108A2082210261021A0204020A0211022082C04 +36A3:02000200FFFE08401C8003800470180862000200FFFE08201C4003800C707008 +36A4:1048104410441040FE4E23F02240224042402440142008221412220A42068002 +36A5:100011FC10201020FC202420242027FE24204820282010202820442084A00040 +36A6:100011FE10481048FC4824482448244824484848284810482888448885080208 +36A7:10201010101010FEFC8024802480248024804880288010802880450085000200 +36A8:100013F010901090FC902490249027F02490489028901092288A448A84860082 +36A9:100010FC10841084FC8425FE24842484248449FE288410842884448484940088 +36AA:1008103C11E01020FC20243C25E024202420483E2BE01020282244228422001E +36AB:200023FC20842088F8884890489C488489444944312811282A104A2884440182 +36AC:10401040108010FCFD0426042484244424444814282410442984440484280010 +36AD:1040105010481048FC4025FE24502450245048502890109028924512850E0200 +36AE:1000100011FE1102FD02240024782448244848482848104A284A448A84860100 +36AF:200023F822082208FB284AA84AA84A488A484AA832A8132A2C0A440A88061002 +36B0:100011FE10101010FC202420246824A425224A22282010202820440083FE0000 +36B1:1008101C10E01080FC802480248024FE24884888288810882888448885FE0000 +36B2:1020102010201020FC3E24202420242025FC4904290411042904450485FC0104 +36B3:210021002100211CFBD4495449544954895449543154115429544A5C83540480 +36B4:20402040204023FEF88048A0492049FC8B244D24312411242934492880200020 +36B5:10401040107C1084FD8826502420245024884B0628601010280844C084200010 +36B6:100011F811081108FD08250825F82500250049FC290411042904450485FC0104 +36B7:2020202020502050F88849044A22482048A890A4512421223222482048A08040 +36B8:100011FC10041004FDF42404240425F42514491429F411142804440484280010 +36B9:20002080231E2252FA524A524A524A524A5292D2535A22543090489049108210 +36BA:100011FC10441048FC8E2482257A2614242048202BFE10202820442084A00040 +36BB:00003FF8210821083FF8210821083FF804000400FFFE08201C4003800C703008 +36BC:1000100011FC1124FD2425242524252425FC4924292411242924452485FC0104 +36BD:00007DFE1040108011FC10041E04E00442280210FFFE08201C4003800C707008 +36BE:100011FC11041104FD04250425FC2450245048502850109228924512820E0400 +36BF:1040104010FC1084FD0426F42494249424F448842894108828824482847E0000 +36C0:1080108010F81108FE10242025FC24042404480429FC10042804440485FC0004 +36C1:100011FC10201020FD2424A424A8242027FE4820282010202820442084200020 +36C2:1008101C11E01100FD00257C2554255425544954297C1140294046428242043E +36C3:080008007F7C08243E2408247F4408540A880200FFFE08201C4003800C707008 +36C4:10401020102011FEFC40244024A024A225A44A982C901088288844A484C20080 +36C5:100013FE10881088FCF82488248824F824884888288E13F82808440884080008 +36C6:100011FC10441048FC5E2482248A252424204BFE2820107028A8452482220020 +36C7:10201010101011FEFD00251025102510257C4910291011102910461082FE0400 +36C8:1040104411F41048FC5025FE2440248025FE4A402C8010FC2804440484280010 +36C9:100013FE10501050FDFC25542554255425544954298C11042904450485FC0104 +36CA:100010F810881088FC8824882526262025FE4820287010A82924462284200020 +36CB:2040204020A020A0F9104A484C46484049449152524A244A3048484049408080 +36CC:2040204020902108FBFC48244920492049FC9220502027FE3020482048208020 +36CD:10201020102013FEFC2024202524252425244AAA282010502850448881040202 +36CE:100010FC10841084FC84248424FC2400240049FE290211022902450285FE0102 +36CF:1028102410241020FDFE2420252024B224B4486828A811242A22442084A00040 +36D0:100013FE10201020FDFC2524252425FC2524492429FC112028A0444080B0030E +36D1:08000F7C28443F44612892100C683186C0000400FFFE08201C4003800C707008 +36D2:100011FE10001000FCFC24842484248424FC4800288410442848440085FE0000 +36D3:21842068203020C8FB0448404BFE48A0492093FC552421243134492848208020 +36D4:1040104010FC1088FD50242024D8272624F8482028F810202BFE442080200020 +36D5:100010F810881088FCF8240025FC25242524492429FC110029004502850200FE +36D6:2040204020882104FBFE4802488849448A4248F8318812502820485081880606 +36D7:1020102010A810A8FCA8257426222420242049FC282010202820442083FE0000 +36D8:2020202023FE2020F8204BFE4A024C0449F89010502023FE3020482048A08040 +36D9:1040102011FC1000FC88245027FE24202420482029FC10202820442084200020 +36DA:100011F8100810D0FC2025FC2524252425FC4924292411FC292445248524010C +36DB:1040108011F81108FDF8250825FA250A250C4BF8281810282848458886280010 +36DC:1040104024FE6488A548245024202450228C0200FFFE08201C4003800C707008 +36DD:100011FC11041104FDFC2504250425FC2504490429FC10002888448481020202 +36DE:100013FE10201020FDFC2420242027FE248848882BFE10882888450881080208 +36DF:1080108010F81108FE1025FC25242524252449242BFE10502850448881040602 +36E0:210020BE22822202FA024AFA4A8A4A8A4AFA928A528A22FA32024A024A0A8204 +36E1:1040102013FE1202FC0425F82400240027FE48902890109029124512820E0400 +36E2:201C21E020202020FBFE48A849244A2289F84888309010BE2902490282140408 +36E3:100010F810881088FCF8240025FC250425244924292411242850444880840304 +36E4:200023FE20002000FBDE4A524A524A524B5A92D65252225232524A524A5282D6 +36E5:1020102213B410A8FCA8252426A2244025FC4904290411FC2904450485FC0104 +36E6:2110211021102110F7BC51105110533853B89554555429922110511051108110 +36E7:1020112411241124FDFC2400240027FE2440488028FC11842A84448484FC0084 +36E8:21082088209023FCF84048404BF8484088404FFE30A010A0292049228222041E +36E9:1040102013FE1080FD0427FE240225FC250449FC290411FC2904450485140108 +36EA:1020102013FE1050FC882524262225FC252449FC292411FC28224422841E0000 +36EB:100010FC10841084FCFC2484248424FC244048FE292A124A28924522844A0084 +36EC:2020202021FC2020F8204BFE488849044A22902051FC2020302048204BFE8000 +36ED:10881088108813FEFC88248827FE240025FC4904290411FC2904450485FC0104 +36EE:1040102013FE1222FCA4252824502488250448F8288810882850442080D80306 +36EF:22102210239024BCF91457D455545554555497D452A422AC22C25482547E8800 +36F0:100011FC110411FCFD1025FE2510254A2586480029FC110429FC450485FC0104 +36F1:100011FC11241124FDFC2524252425FC24004BFE292011222914454885840102 +36F2:100013FE10201040FDFC2504250425FC250449FC2904110429FC440084880104 +36F3:01007FFC082004407FFC41041FF01110115011200200FFFE08201C4003C03C38 +36F4:2092212422482124F892484048804BFE4A02928A5252222232524A8A4BFE8202 +36F5:101E13E010441124FC88242025FC2524252449FC292411242BFE450485140108 +36F6:1020112411241124FDFC2480248027FE24904910295212542AA8442888440082 +36F7:0C48704413FEFC50305058929492110E12000200FFFE08201C4003800C707008 +36F8:1020102013FE1020FC2025FC2400240025FC4904290411FC28004488845003FE +36F9:210021FE21102210FAFE4A924E924AFE4A92929252FE229032504A204A588286 +36FA:1040102013FE1000FD04248827FE240025FC4904290411FC2904450485FC0104 +36FB:2020202023FE2050F8884B2649FC4820482093FE5000202031FC4820482083FE +36FC:1008103C11E01020FC2027FE242024A0252C4924292411AC2924452485FC0104 +36FD:2040202023FE2202F820492448A848204BFE907050A820A831244A2248208020 +36FE:2008200C200A23FEFA084A084AE84A0A4A0A92EC52AC22A832EA4A1A4A268442 +36FF:20A820A823FE20A8F8A848004BFE4A22882049FC312411242934492880200020 +3700:21002100213C2124FBA44924493C4BA44B649524593C212431244924493C8124 +3701:1020102013FE1070FCA82524262225FC250449FC290411FC2904440083FE0000 +3702:08087E0808FEFE0808487E2808080F28F0100400FFFE08201C4003800C707008 +3703:2090208820FE2100F9004B3C4D004900493C91005100213C31244924493C8124 +3704:200027FC24042434F5C4544455F45554555495F45444245425F4549458069002 +3705:1040102013FE1040FC8825F02420244425FE480229FC112429FC452485FC0104 +3706:2010209224522254FA1048FE48104E388A544A92331012102A10450088FE0000 +3707:2020202021FC2020FBFE482049FC48208BFE4800304010242AA24A8A84880078 +3708:00207E7C14C40838FEC62A2048FCA844128C0200FFFE08201C4003800C707008 +3709:2124224822482124FBF84A084BF848004BF89248524823F832024A0249FE8000 +370A:200023FC22042204FBFC4A484A484AFC8A484A4833FE12A42AA8449084C80886 +370B:2104208420882000FBFE4800488849048A0249FC315411542954495487FE0000 +370C:10001078FE4810487C480086FE0082FC7C441044FC2824286810302848448582 +370D:1020101011FE1110FD7C251425FE2514257C4910297C114429444644827C0444 +370E:101E13E011221094FC40248825F0242024C449FE282210202BFE445084880306 +370F:100010FC10841084FCFC240025FE250225FE490229FE110229FE444884840102 +3710:1020112411241124FDFC240027FE240025FC4904290411FC2888445083FE0000 +3711:40482FFE004087FC544417FCE44427FC244420000200FFFE08201C4003C03C38 +3712:1040119C11041104FDDC2504250425FC248848882BFE10882888448885080208 +3713:1088108813FE1088FC2024502488250426FA4800280011FC2904450485FC0104 +3714:1080104013FC1108FC9027FE240025F82508490829F81090289045128212040E +3715:2010201022FE2110F97C4854487C4B54897C491031FE111029104A90847E0000 +3716:2090209027FE2090FBFC4A944BFC4A944BFC900051F8210831F8490849F88108 +3717:2040208821FC2108FA524BFE485049884E2690C0531020643388483048C08700 +3718:1020103C102011FEFD22253825E4251C2500497C2944117C2944457C854402FE +3719:2040202023FE2250FA504BFE4A524A528BFE4A00329212D42A98449284D2088E +371A:2040202027FE2402F90049FE4A104E204A7C92445244227C32444A444A7C8244 +371B:21082108210827C8F11E57D2556457C0554897C8510827C82114511451248142 +371C:21082108210827D0F11E579451245FD4521493D452542248224854D454248842 +371D:2020205020882124FAFA481048204BFE485091FC5154218C310449FC490481FC +371E:08047F7808407F40497E7F4849487F4808487F480A88FFFE08201C4003C03C38 +371F:2008238820882110F7DE529452A4539452949394529422C82388569450A480C2 +3720:1020122213FE1090FC8825FE2710251025FE4910291011FE2910451085FE0100 +3721:2124212422242424F954494A4A924E104A109250525C225032504AB04A9E8300 +3722:102011FC112413FEFD2425FC242025FC252449FC284013FE288845D08470038C +3723:2110211421D22250FA7E4D5048904AA8492891445244248230084AA44A528452 +3724:200023FE205023FEFA524BFE480049FC490491FC510421FC30204BFE48208020 +3725:200023FE22522252FBFE480049FC490449FC910451FC210431FC488849048202 +3726:200023FC200423FCF8044BFC48004BBC492497BC500823FE3108488848A88010 +3727:200027FE24002628F54857EE5492548456A096A857E824882494551459249242 +3728:200023FE220223FEFA104A544A384A548A824A50327C12902A1045FE84100810 +3729:2040208023FE2222FAAA4A224BFE4A724AAA9202502023FE3020485048888306 +372A:08047F782240FF40087E7F482A484948A8881400FFFE08201C4003800C707008 +372B:228822A826A82BF0F01E522455D45C14541495D4555425482568555456148422 +372C:210021F8220827FEFA884B244BFE4A008AFC4A0032FC12002AFC448484FC0884 +372D:1020112410A813FEFE0224F82488248824F8480029FC112429FC452485FC0104 +372E:200823E8228823EEFA284BF44A824BE2880049FC315411542954495487FE0000 +372F:200027DE24922492F5D2555E555055D05492949257CE20002000552454928892 +3730:21242174225822DAFBFE49544ADA4BFE88A2482033FE107028A8492482220020 +3731:2042239C221023DEFA944A944C204BFC4A0493FC520423FC32044BFC49088204 +3732:20402FFE240027FCF00057FC540457FC50809C9C57D43D54355C5C965556AE22 +3733:2080204027FC2000FBF84AA84BF848404A449118524420A831904A884CA680C0 +3734:210827FE210823FCFA944BFC48004FFE4C0291F8510821F8310849F8490881F8 +3735:204027FE200023FCFA404BF84A404BF84A4093FC5004255430A84B104D488186 +3736:21F0221027FC2204FBFC4A244BB84A2249FE921057FC224433FC48D0494A863E +3737:F7FC124817FCFC4686ECF55416EC155456EC24440200FFFE08201C4003C03C38 +3738:0820FFFE28207DFC44887C5041FE7C2045FC7C200200FFFE08201C4003C03C38 +3739:23DE225223DE2252FBDE4A524BDE489049FE911053FE251031FE491049FE8100 +373A:252827BE294827BEFB184DAA49464BFC4A0493FC520423FC32044BFC49088204 +373B:244424E42A0A2EEEF4045AEA5E0E50E05AAA9AEA504020242522550A590880F8 +373C:21FC212421FC2124FBFE4AAA4BFE4AAA4BFE900053FE228A30F84888488883FE +373D:0888111022201110088800001FE0004000800100FFFE01000100010005000200 +373E:0020FC200450085010881104160218883088D088108810881088110851082208 +373F:0000FDF8040808501020101015FE18223024D020102010201020102050A02040 +3740:00003E7C22042A08260822102210FF7E421052104A1042107F90021014500820 +3741:10001FF820085FC890481FC810481FE800103FE000800100FFFE010005000200 +3742:0104FD0E0530092017E01120153E196431A4D724112411241124112455442284 +3743:0080FC8004F80908121011FC152419243124D1FC10501050109010925112220E +3744:20201020FE2001FC7C2044A87CA800A87CA804A808F81E22F0221022501E2000 +3745:1000FE7810487C480048FE8682007CFC00447C4408281E28F010102850442182 +3746:0020FDFE042009FC100011FC150419FC3088D3FE100011FC1104110451FC2104 +3747:20201010FEFE00007C7C44447C7C00007C7C080810101EFEF010101050502020 +3748:210447C88812F3BC20084B92F83E0380AAAAABAA00007C7C0808FEFE10103030 +3749:0200010001007FFE400280040000000000000000000000007FFC000000000000 +374A:0200010001007FFE4002800400003FF01010082004400280010006C01830E00E +374B:0200010001007FFE400280041FE0004000800100010001000100010005000200 +374C:0200010001007FFE4202820407E004200840104000800180024004201810600C +374D:020001007FFE500290041FF8100020003FF800080008FFC80008000800500020 +374E:020001007FFE40028204010001007FF8003000C003000C003000480087FE0000 +374F:020001007FFE400281040280044008203458C446044004400840084010402040 +3750:0200010001007FFE40828484044008401020221042088406084010203FF01010 +3751:020001007FFE4002820401007FFC0400040007F0041008100810101020A04040 +3752:0200010001007FFE4002810401007FFC010001001FF01010101010101FF01010 +3753:020001007FFE4002810402800C603018CFE600001FF01010101010101FF01010 +3754:020001007FFE4002820401007FFC08201010244844440280010006C01830E00E +3755:020001007FFE4202810409002828282447E400003FF00820044003801C70E00E +3756:020001007FFE420287E41840648003200C4071F806081A10012000C007007800 +3757:020001007FFE420281041FF010101FF010101FF0110410881050122014181806 +3758:020001007FFE420281043FF800001FF000001FF000001FF0101010101FF01010 +3759:020001007FFE400280043FF801001FF001007FFC0000FFFE0000082010102008 +375A:020001007FFE4002801C7BE00840104022787A400A402BFC1000280047FE8000 +375B:020001007FFE400288040FFC1040304053F89248124812A81318120813F81208 +375C:020001007FFE444284443FF804400440FFFE00001FF010101FF010101FF01010 +375D:020001007FFE40028824082008207EFC08201C301A702A6848A4892208200820 +375E:020001007FFE400280047FFC044004403C78200820083C7804400440FFFE0000 +375F:020001007FFE4002BFFC00001FF010101FF010101FF010101FF004421842E03E +3760:020001007FFE40029FF410101FF010101FF012100100FFFE0000082010102008 +3761:020001007FFE400280047F0022FC3E4422443E44222822282F10F22842440282 +3762:020001007FFE400280F43F0001001FF011101FF001007FFC412441F45E144008 +3763:020001007FFE400288047F7C08243E2408447F5408880200FFFE04401830E00E +3764:01007FFE4822BFFC08203FF80820FFFE01003FF821083FF82108FFFE20082018 +3765:020001007FFE400284242420252424A83C2007FE0470FCA82524262224204420 +3766:01007FFE49029FFC31005FF091001FF011001FF810003FE0084008F810086030 +3767:01007FFE4402BFFC082007C0783811101110292845443FF801000100FFFE0000 +3768:020001007FFE41029FF401007FFC00001FF010101FF0048808503820CB180C06 +3769:01007FFE400281043FF820802FF820883FFE20882FF824C422A8449858868180 +376A:020001007FFE4002904410407C4011F8FE48444828C87C4810AAFEAA11061202 +376B:01007FFE4002810479F04A9050606198560649F04A406BF8544043F8404047FC +376C:20201020FE20822011FC7C2010207C2011FEFE2010507C50448844887D044602 +376D:01007FFE4002900413F812085BF8560853F8914013F8144011F0104017FC1000 +376E:01007FFE400288042A003E7C49447F4400443E2800287F1008102A2849441882 +376F:020001007FFE400280741F800200FFFE082037D8C4463FF8200827C8244827D8 +3770:01007FFE42029FF41490125011301FF00100FFFE92122FE8440407E008203060 +3771:01007FFE408A8BFC488849FC495479FC08000BFEFA4248784888495088600980 +3772:01007FFE411297FC511053F852A877FC141411F0F01057FC544453F892481258 +3773:0200020002000200FFFC0200020012901248122422242212421282000A000400 +3774:00087C08000801FE0008FE082488244824482408240824282412440243FE8000 +3775:00003FF820083FF820083FF800007FFC00200020FFFE08200420042000A00040 +3776:3FF8244824483FF80000044004420842303EC0000020FFFE0820042004A00040 +3777:3FF000101FF000103FF000407DF011501C94E14C0020FFFE0820042004A00040 +3778:010011102108450408003FF8200820083FF8200820083FF8044008421042603E +3779:01001110216843841C00E8001FE020204040BFF8210821083FF80492188AE07E +377A:22101410FF90141014147F521552FF9215107F1414043608551094A014401580 +377B:22102210FF9022103E5408527F5249907F1008147F0408087F0808100F20F0C0 +377C:200021FC20202020FC2028202BFE282028202820282028A02842480247FE8000 +377D:2020202020202024FDA828B028B0292829242A2428A028402802480247FE8000 +377E:20402040204023FCFC80288028F8292029202A20282029FC2802480247FE8000 +377F:2020202021FC2124FD28292029F82908295029202A502A882D0A480247FE8000 +3780:20402040204023FEFC802890291229542A902C28282428442982480247FE8000 +3781:200021F8210821F8FD0829F82800291829E02904290428FC2802480247FE8000 +3782:201C21E020442124FC88282028202BFE284828C8283028682986480247FE8000 +3783:2840244842449244104029FE445082507C5044504450445244527C92448E0100 +3784:2040204023FC20A0FD102A482DF4295029F0295029F42844283E480247FE8000 +3785:200021FC212421FCFD2429FC282029FE287028A829242A202822480247FE8000 +3786:2020202021FC2050FC882BFE280829E82928292829E829282808481A480287FE +3787:200021FC212421FCFD2429FC28002BFE29222914294829842902480247FE8000 +3788:2040202021FC2104FD0429FC290029FC2B542B542DFC29542954490E480287FE +3789:2088205023FE2020FDFC28402BFE288029FC2A202C202BFE2802480247FE8000 +378A:1040544054407C4092FC9250FE5000507C500050FE50105254929292510E2200 +378B:00003FFC200420043FFC200020002FF82408241022202140208041404630980E +378C:00003FFC200420043FFC200027F82010202020402FFE20402040404041408080 +378D:00003FFC200420043FFC210021002FE0212025202220232024A24422481E9000 +378E:00003FFC200420043FFC20002FF82888288828882FF8280028024802480287FE +378F:00003FFC200420043FFC200020782780208020402FF8201020604180460099FE +3790:00003FFC200420043FFC2000208020402FFC200024082210212040005FFE8000 +3791:00003FFC200420043FFC20002888249022A0208022A02492288A4082407E8000 +3792:00003FFC20043FFC210022002FF8280828082FF8280828084FF8480888080FF8 +3793:00003FFC20043FFC200028602F88280827F820002FF828084FF848088FF80808 +3794:00003FFC20043FFC210023F02C202240218022402CF821084690406081800E00 +3795:00003FFC20043FFC22202410280837F6241027F0241027F04410441084500420 +3796:00003FFC200420043FFC20803FFC20802FF8288828A829D022A04490588C8080 +3797:00003FFC200420043FFC209020882FFC2080288825D022A02490488C42808100 +3798:3FFC20043FFC20002FFC2100230824882D50226025E029504250444899440080 +3799:3FFC20043FFC200020F03F0021E02F0021F43F0420FC20884ED042A084981986 +379A:3FFC20043FFC2000203827C020402FFE20402140265C2444475C444487FC0404 +379B:00003FFC20043FFC2288249028E43284247C2C0034FC248444FC448484FC0484 +379C:3FFC20043FFC220C2470281030FE223824542C92342025FE444444C8843805C6 +379D:00243FFE222023A422243FA82B10529A462680421FF810081FF8100020004000 +379E:00003FFC20043FFC24482848305422A425002C103490249C44904550863E0400 +379F:3FFC20043FFC22202FF821402FF82A282DD828082FF820805FFC41408630180C +37A0:3FFC20043FFC20802FF821402A2827F02C1837F4241027F04080488892840100 +37A1:3FFC20043FFC2000273822102F7C20002738221023BC2EC8413043108D480186 +37A2:010001002108210821082108210821083FF801000100010001000100FFFE0000 +37A3:01002108210821083FF80100054008203018DFF6021002100210041008A01040 +37A4:010001002108210821083FF800000100010001000280044008203018C0060000 +37A5:01002108210821083FF80000060001000100028002800440082010102008C006 +37A6:100010F01090109054905490549054905490549054905C9264920112010E0200 +37A7:01002108210821083FF8000000003FF004100420087C08041004200440288010 +37A8:100011FC1004100854105420542057FE5420542054205C206420002000A00040 +37A9:0100210821083FF8000000000FE0082008200A200920092210221022201E4000 +37AA:00003FF0001000101FF000100010FFFE0100010021082108210821083FF80008 +37AB:01002108210821083FF80200010001007FF8003000C003000C003000480087FE +37AC:010001002108210821083FF8000000003FF801000100010001000100FFFE0000 +37AD:010001007FFC01000280044008203018C106010021082108210821083FF80008 +37AE:01002108210821083FF8080008001FF810082010402000400C80030000800040 +37AF:00003FF0001000103FF02000200420041FFC010001002108210821083FF80008 +37B0:10801080108011FC552056205420542057FE542054205C206420002000200020 +37B1:0100210821083FF8000000003FF82008200820083FF82008200820083FF82008 +37B2:102010201020102055FC552455245524552455FC55245C206420002000200020 +37B3:100810881048104854085488544854485408540E55F85C086408000800080008 +37B4:1004101E11F0111055105510551055FE5510551055105D08650A014A01860102 +37B5:01002108210821083FF8020001007FFC0820082004400280010006C01830E00E +37B6:10401020102013FE54885488548854885488545054505C206450008801040602 +37B7:01002108210821083FF80100010000007FFC010001003FF801000100FFFE0000 +37B8:01002108210821083FF8000000007FFC01000300056009103108C10401000100 +37B9:1000100013FE1008540855E8552855285528552855E85D286408000800280010 +37BA:01002108210821083FF8080008001FF0210001007FFC0280044008203018C006 +37BB:0100210821083FF800001FF010101FF00000FFFE10001FF00010001000A00040 +37BC:00003FF0002000C07D040588095011202118C50602000100210821083FF80008 +37BD:2028202420242020ABFEAA20AA24AA24AA24AA28AA28BA90CB12022A00460082 +37BE:100011FC11041104550455FC550055405544554855705D4065420242023E0400 +37BF:0100210821083FF8000001003FF801000100FFFE10100820044003801C70E00E +37C0:00701F8001000100FFFE054009203118C006010001002108210821083FF80008 +37C1:100011FE11001100557C551055105510551055FE55105D106510021002100410 +37C2:100010FC108410A454945484548457FE5504554455245D0465FE000400280010 +37C3:100011FC1004100455F45404540455F45514551455F45D146404000400280010 +37C4:108410441048100055FE5420542054FC5420542055FE5C206420002000200020 +37C5:10001088105011245554558C550455FC5400549054905C90651001120212040E +37C6:2090209421142118AB10AD32A952A90EA920A820ABFEB820C820002000200020 +37C7:10201020112411245524552456AA54725420542055FC5C206420002003FE0000 +37C8:102810241024102055FE5420552054B254B4546854A85D246222002000A00040 +37C9:2040202023FE2202AC24A920A9FCA920AA20A820ABFEB820C820002000200020 +37CA:1008103C11C01004554454A8540055F85410542057FE5C206420002000A00040 +37CB:110410841088101055FC55045504550455FC545054505C9064920112020E0400 +37CC:10901088108013FE54A054A854B054A454A854B055245D2A6532022202DE0400 +37CD:1040102011FC1104550455FC5504550455FC552055225D146508014401820100 +37CE:2008203C23C02044AA24A928A900A840ABFEA888A908BB90C860005001880604 +37CF:10201020105010885544562254F854085410542055FC5D046504010401FC0104 +37D0:1048104811FE104854485420541055FE5480548054805C806480008000FC0000 +37D1:2020202023FE2020A820ABFEAA02AC04A9F8A810A820BBFEC820002000A00040 +37D2:0100210821083FF800003FF80408FFFE04083FF808001FF8280848088FF80808 +37D3:21842068203020C8AB04A840ABFEA8A0A920ABFCAD24B924C934012800200020 +37D4:0100210821083FF8010002800C603118CFE6004000801FF0101010101FF01010 +37D5:0100210821083FF800000020792048A04A204920483C4BE07820482000200020 +37D6:0100210821083FF800003FF801001FF001007FFC00000820FFFE082010202020 +37D7:01000100410451445554638C41047DF455545554555465944D3441047FFC0004 +37D8:100011FC112411245574552455FC55045574555455545D746504020402140408 +37D9:10881088108813FE5488548857FE540055FC550455045DFC6504010401FC0104 +37DA:10201020FDFC1020302039F85488905010201050118C0100210821083FF80008 +37DB:0100210821083FF8000010881088FBFE108810881CF8F0881088108850F82088 +37DC:0100210821083FF800407C4004FC04847D28402040A87CA404A4052428A01040 +37DD:1040102011FC100055085490540057FE5400540055FC5D046504010401FC0104 +37DE:10481044105E11E054285412546A55965448545E55E05C2464280012006A0186 +37DF:0100210821083FF8000008207FFC0820FFFE10102FC848448FC20810081007F0 +37E0:200023FE2202228AAA52ABFEAA22AA22AAAAAAAAAAAABAFACA020202020A0204 +37E1:0100210821083FF80000111009207FFC0400FFFE10102FE8C82608A0084807F8 +37E2:0100210821083FF802003FF804800840FFFE00101F90109010901F9000500020 +37E3:2104211421142114ABD2A922A92AAB48AB88AD50AD10B914C922017E01220100 +37E4:0100210821083FF800003FF000101FF00010FFFE111009A005401930E50E0200 +37E5:0100210821083FF8040008201FF00210FFFE08A03318CC4603801C3001C03E00 +37E6:010041047FFC00007FFC41043FF801001FF011101FF011101FF00100FFFE0100 +37E7:010041047FFC00003EF822883EF800003FF80000FFFE08000FF0001000A00040 +37E8:102011241124112455FC540057FE5420544055FC55545D54655401540154010C +37E9:00207F20413E7F4448A47F24482845105328614600000100210821083FF80008 +37EA:100011FC1124112455FC5524552455FC540057FE55205D226514014801840102 +37EB:1040108011FC110455FC550455FC5420543257B454A85D286524022404A20040 +37EC:010041047FFC0500397821083D7821083FF801003FF00820044003801C70E00E +37ED:100011FC110411FC551055FE5510554A5586540055FC5D0465FC010401FC0104 +37EE:1040102013FE12025488550456225428542457FE54205C506450008801040202 +37EF:010041047FFC020001007FFE48029FF4282007C01830E00E1FF010101FF01010 +37F0:200023FE22022000A9FCA904A9FCA904A9FCA840A820BBFEC800008801040202 +37F1:2104208420882000ABFEA820A820A9FCA820A820ABFEB800CAA4025204520000 +37F2:100011FE11101120557C5544557C5544557C551055105D546552029202500420 +37F3:200023FE20502050ABFEAA52AA52ABFEA820A820ABFEB870C8A8012406220020 +37F4:2020204023FC2224AA24ABFCAA24AA44ABFCA840A8A8B8B4C93C01220222041E +37F5:0100210821083FF800003FF824483FF800007FFC010011F811001100FFFE0000 +37F6:010041047FFC00003FFC2080210027F0241027F0241027F0408044908A881104 +37F7:1088108813FE1088542054505488550456FA540054005DFC6504010401FC0104 +37F8:2020204021FC2104A9FCA904A9FCA840ABFEA888A924BA22CDFC002000200020 +37F9:20103F202ACE2AAAAEAAAAAAAAAAAEAAAAAAAAAAABEABEACDA28024802480288 +37FA:010041047FFC01003FF82108FFFE21083FF811101FF00400FFFE082007C07838 +37FB:08047F7808407F40497E7F4849487F4808487F4808880100210821083FF80008 +37FC:0100210821083FF8082008207F3E08443EA40824FF2810281E1022284A448482 +37FD:100013FE105011FC5554555455FC540055FC540057FE5C2064A8012402A20040 +37FE:101011FE1110117C551455FE5514557C5510557C55545D7C6554027C0254044C +37FF:2088208823FE2088A824ABFEA850A888A904AA8AA888BBFEC888008801080208 +3800:04001FF010101FF010101FF010001FFC10001FFC4924849C0100210821083FF8 +3801:2040208821FC2108AA52ABFEA850A988AE26A8C0AB10B864CB88003000C00700 +3802:21082108210827D0A91EAF94A924AFD4AA14ABD4AA54BA48CA4804D404240842 +3803:2040202023FE2088A850ABFEAA22AAFAAA22AAFAAA8ABA8ACAFA0202020A0204 +3804:0100210821083FF800007EFC22441A3462C404001FF010101FF010101FF01010 +3805:010041047FFC020013FC240043F88A0813F8320853F8910013F8151010E0171C +3806:200023DE22522252ABDEA800A9FCA924A9FCA924A9FCB820CBFE002000200020 +3807:0100210821083FF820501048FE4801FE7C5044507C501050545052929292310E +3808:200023DE225223DEAA52ABDEAA02AAFAAA22AA72AA22BA22CAFA0202020A0204 +3809:102011FC1088105055FE540055FC552455FC552455FC5C2065FC002003FE0000 +380A:2040207C204023FEAA42AA78ABC4AA3CAA00AA50AA54BB54C4D8045009FE0000 +380B:21083FF800001FF010107FFC44447C7C00003FF80000FFFE10001FF800080070 +380C:0100210821083FF800202220FFBE22423E9422103E102210FFA8242842448282 +380D:010041047FFC08801FFC30805FF890801FF810801FFC11007FFC05401930E10E +380E:20A0209021FE2320A9FCA920A9FCA920A9FEA900A820BBFEC87000A803260020 +380F:108813FE1088100055FC54A854A857FE54A854A855FC5C2063FE002000200020 +3810:010041047FFC000000701F800200FFFE082037D8C4463FF8200827C8244827D8 +3811:0100210821083FF800003FF824483FF802807EFC02803EF802807EFC02800280 +3812:20022FE222822FEAAAAAAAAAAFEAA80AABCAA80AAFEAB90AC5420522092A0304 +3813:208823FE208823FEAA02A9FCA800ABFEA840A8A2AB54B8B8CB54009203500020 +3814:0100210821083FF800403E2022FC22883E5021FE20203E2052FC52209E201220 +3815:010041047FFC004078804BF8524863F852484BF8484868B450BC41224222441E +3816:41047FFC08207FFC01003FF80100FFFE02403C500848FFFE08507E240854198C +3817:2040208023FE2222AAAAAA22ABFEAA72AAAAAA02A820BBFEC850008801040602 +3818:0100210821083FF80A0033B822083A38238820883AB82288FFFE082010102008 +3819:202023FE200021FCA904A9FCA800ABFEAA02A9FCA840BBA4C8D8033400D20330 +381A:2144214425542364A94EABE4A804AA2CA944ABE4A884BBE4C88400E407140008 +381B:108813FE10A8109055FE572055FC552055FC552055FE5D0063FC00880070038E +381C:220022BE23022254A9C8A83EAA0AABCAAD28A928AFEEB928CAA80258044E0080 +381D:108811DC108813DE54885554562255FC550455FC55045DFC650401FC00880104 +381E:22204AA08ABE1FC420A46F24A0282FA82210272822442F820100210821083FF8 +381F:10501190109E13EA548A55D2568A54A45450548857265CA8647000A801240060 +3820:2040207C204023FCAA44ABF0AA44AAFCAAA8AAF8AAA8BAF8CA0005FC05540BFE +3821:202023FE200023FCAA20ABF8AA20ABF8AA20ABFEA802BAAAC854018806A400C2 +3822:21083FF802001FF011101FF012101FF004A808BA3082C27E01007FFC0C48763E +3823:200023FE222222CCAA44ABEEAA44AAEEAB54AA44AA10BA90CA9E049004900BFE +3824:202023FE200021DCA954A9DCA888ABFEA888ABFEA888BBFEC894018802A400C2 +3825:27FC244427FC2444AFFCA800AFBEAAAAAFBEAAAAAFBEB840C84007FC00400FFE +3826:20A821FC22AA23FEAAAAABFEAAAAABFEA800ABFEA800B9FCC90401FC008803FE +3827:202023FE224823FEAA48AAECAB5AAA48AA50ABDEAA50BBDCCA5005DE04500850 +3828:2154212423DE2154ABAEAD54AFFEAC92AFFEAA44ABDEBA44CBD4020C0284034C +3829:0080008021402220241020003FFC0000092009200920112011222122411E8000 +382A:00007FFC0100010001000100010001F8010001000100010001000100FFFE0000 +382B:00007DF01110119011521D12E20E440001003FF80100FFFE028004401830600C +382C:00007CF81088108810881CF8E00041003FF801000100FFFE028004401830E00E +382D:00007C7C1010101010101010FEFE000000007C7C1010101010101E10F0FE4000 +382E:220014007F7C141055103610FF9000103E10221022103E10221022103EFE2200 +382F:00001FF01010101010101FF01000100010001FF81008100810081FF810080000 +3830:10007E7C124412441244227C4A4484001FF0001000101FF01000100410040FFC +3831:3FF000103FF020041FFC08207FFC08200FE008200FE00820FFFE082010102008 +3832:0840084008407F4249444948495049604940494049404B4208420842083E0800 +3833:060001000280044008203118C10601001FF01110111011101150112001000100 +3834:1000100011FC7C24542454A454A454A45524542454245C441044108411141208 +3835:02000100FFFE1000100010001FF8010001003FF8210821082128211001000100 +3836:1020102010407CF854885488548854885488548854885C8A108A110A11061200 +3837:100013FC10847C8854885490549C54845544554455285D281210122814441182 +3838:1020102010207C2055FC54205420542057FE542054505C501088108811041202 +3839:1020102010507C5054885504560254885488548854885C881088110811081208 +383A:1020102010207CA854A454A2552255205624542454285C081010102010C01300 +383B:020002083FD002200240FFFE010002800C801FF82888488888A8089000800080 +383C:1004100E10F07C805480548054FE54885488548854885C881088110811081208 +383D:10401040107C7C8455885650542054505488570654605C10100810C010201010 +383E:10001EF8228862A894920882307EC10001003FF8210821082128211001000100 +383F:0880088828902EA028C028842E84F17C01003FF8210821082128211001000100 +3840:0100210811080910092001007FFC410441044384454449244104410441144008 +3841:1020102013FE7C505488550456FA540057FE544054805DFC1004100410281010 +3842:00047FA410243F2451240A040C043114C1083FF8210821082128211001000100 +3843:1010111011107D285544550055FE540054A854A854A85CA810A810AA112A1206 +3844:1040104010807CFE5502560255F25512551255F255125D1211F2100210141008 +3845:10201020107C7C8455485430542054485590543E54425DA41018101010601180 +3846:1080104013FC7D005500550055F854005550555055505D50125012521452180E +3847:100013FE11207D28552855E855285528552855E855285D2A113A13EA10261020 +3848:1080108010F87D08561055FC55245524552455FC54505C50109010921112120E +3849:201023882088F8FEA890AB90AA24AA24AA38AB88A890B89020A420BE22822100 +384A:10401040107C7C8455085600542055CE5502550255CE5D021102110211FE1102 +384B:1020102013FE7C5054885524562255FC552455FC55245DFC10221022101E1000 +384C:100011FE11027D7A5502557A540054FC548454FC54845CFC1084108410941088 +384D:02001FF010101FF010101FF00200FFFE08203118DFF611101150112001000100 +384E:1040104810847DFE542057FE548855245642558854105C621184101810601380 +384F:204020A02110FA08ADF6A800ABC4AA54AA54ABD4AA54BA5423D42244225422C8 +3850:210820882090FBFEA800ABC4AA54AA54ABD4AA54AA54BBD422542244225422C8 +3851:0610381008527E5408901C282A284844088201003FF821082108212821100100 +3852:1008101C11F07D10551055FE5510557C5544557C55445D7C11441244127C1444 +3853:200023FE2222F820ABFEA820A9FCA924A9FCA924A9FCB82023FE202020202020 +3854:00407F40127E0C88FF4819482A504820A850118C01003FF82108212821100100 +3855:1088108813FE7C8854A8542055FC55245524552457FE5C201050108811041202 +3856:1008103C11E07C2057FE542055FC552455FC552455FC5C2011FC102013FE1000 +3857:2004201E23F0FA1EAA10AAFEAA92AA98AAF2AA8EAA80BAB822A824AA254A2A86 +3858:1088105010007DFE545055FC545457FE545455FC54505CD81154125210501050 +3859:1020104011FC7D04555455245554550455FC540055125DD4111811521192110E +385A:1088108813FE7C8855FC548857FE542055FC552455FC5D2413FE110411141108 +385B:1088108813FE7CA8541057FE5480548054FC540054A85CA810A810AA112A1206 +385C:2100211023DCFA54AD54AA88A908AAF4AC02A800ABFCB8402150224825442080 +385D:2020247C2284F948A830A8CEAE10AA7CAA10AA7CAA10BAFE2210221025FE2800 +385E:202021FC2124FBFEA924A9FCA820A9FCA924A9FCA840BBFE208821D02070238C +385F:2090209027FEF890ABFCAA94ABFCAA94ABFCA800A9F8B90821F8210821F82108 +3860:202027A420A8FA92A914AA08ADF4A802ABF8AA08AA08BBF8220821102FFE2000 +3861:200023FE2200FA04ABF4AA04AAEEAAA4AAA4AAECAA04BAA42244227425942008 +3862:21FC210421FCF904A9FCA800ABFEAA52ABFEA800ABFEB88020FC208421142208 +3863:102008207F3E0020223E1402FFBE88A0093E7F20493E49204D3E4A200822081E +3864:205022522154F850ABFEA888A850ABFEA820A9FCA820BBFE20A8212426222020 +3865:203E27C02244F928ABF8A840AFFCA800ABF8A808ABF8B80823F82544252A28FA +3866:1020101011FE7D0254FC54A8553054FC558454FC54845CFC108410FC10481084 +3867:2040202023FEFA8AA904A812ABD4A848AA8AA974AA02B9FC210421FC208823FE +3868:2148214C22AAF808AFFEA948AB68A94AAB6AA94CAB6CB948216A239A20262042 +3869:210447C88812F3BC20084B92F83E0380AAAAABAA01003FF82108212821100100 +386A:203E27C42128FBFEAA02ABFEAAA0AAEEAAAAAAEEABA8BA4622F82548243029CE +386B:100011FC210421FC450445FCF88009FE1222112229524502FDFA440200140008 +386C:1110212045447978111025247D7C05240110FFFE20803E88225222224A5A8586 +386D:441049245E7844104A285F7C40007FFE441049245E7844104A285F7C40007FFE +386E:49204920AABEEBA04940AABCEB802900FFB8240825082508228A528A45868882 +386F:010000803FFE2000201020F827802080208020FE3F802080408240828082007E +3870:010000803FFE2000200027F82080208020803FFE208020804080408082800100 +3871:010000803FFE21002100210023F0221024202820204020C0412042108C083006 +3872:010000803FFE20002090208820FE2F802080208820902060204241A24E1A8006 +3873:010000803FFE2000203C27C024402440244027FE242024202412450A46068402 +3874:010000803FFE2080204020402FFC20002408220822102110412040009FFE0000 +3875:010000803FFE20802140222024902848304627F0201020204340408080400020 +3876:010000803FFE2000200027F8240824082408240827F824084120421084080804 +3877:010000803FFE2000208020802FFC21C022A022A02490288857F4408080800080 +3878:010000803FFE2200220023FE2500290031F82100210021FC4100410081000100 +3879:010000803FFE2000200023F82208220823F82208220823F8420842088FFE0000 +387A:010000803FFE2000200027F82408240827F82408240827F8400040009FFE0000 +387B:010000803FFE20002180263C24A424A424A424A425A426B42528412042208420 +387C:010000803FFE208020802FF828882FF828882FF820842048203041D45E0C8004 +387D:010000803FFE2000204027F820483FFE204827F8204027FC40405FFE80400040 +387E:010000803FFE200027F8240827F8240827F82484248824502420451846068400 +387F:010000803FFE2208210821102FFE204024442444244427FC2084410046009800 +3880:010000803FFE204020402FFE204027FC2444245424E8215042484C4680400040 +3881:010000803FFE208021F022102D2020D023202C7C218426884050406081800E00 +3882:010000803FFE2040208027F82408240827F82400240027FC4404440487FC0404 +3883:010000803FFE2100208027F8240827F8240827F8248224442428451046088406 +3884:010000803FFE200020002FFC200023F822082208220823F82000420841109FFE +3885:010000803FFE200027FC204023F820402FFE211021102FFE2110421042108410 +3886:010000803FFE200027FC2444244427FC2444244427FC204027FC404040408FFE +3887:010000803FFE210020802FFC200027F8200027F8200027F82408440847F88408 +3888:010000803FFE2280224027FE24402C4037FC2440244027FC4440444087FE0400 +3889:010000803FFE2000218C2E70221022103F90261E27702A902A1252124212820E +388A:010000803FFE20802FF82140222024103FFE201027D0245047D0401080500020 +388B:010000803FFE22202278248825502C243448259E242224642598441044608580 +388C:010000803FFE20002EFC2A082AE82CA82AA82AA82AA82AE84EA8480888280810 +388D:010000803FFE200021102FFE2110204023F8224822482FFE20A0411046089806 +388E:010000803FFE2000203827C020402FFE20402140265C2444275C444447FC8404 +388F:010000803FFE204020A023182DF62000278424A427A424A427A4448444948588 +3890:010000803FFE200023F0221023D0225022502FFC280429E4292449E448148808 +3891:00803FFE2280224027FC24402FF8344027F8244027FC248040805FFE80800080 +3892:00803FFE2040207E20402FFE28422BF8284229FE290429FC490451FC910427FE +3893:00803FFE204027FC21102FFE200023F8220823F8220823F840404FFE80400040 +3894:010000803FFE220024482848305422A425002C103490249C44904550863E0400 +3895:010000803FFE22282224257E29482E4822FE254829482F7E42484448887E1040 +3896:010000803FFE200020782F80249022A03FFE2490280837F6449047F0849007F0 +3897:00803FFE203827C020802FFC211027F8391621F020002FFE480249F2891209F6 +3898:010000803FFE221021202FFC21202FF821283FFE21282FF820004A4849249124 +3899:00803FFE251025103FD0253C271422142F942A942F9422144FA4422483541C88 +389A:00803FFE208020F820802FFC28842BF028882BF82A482BF84A4857FC9084230C +389B:00803FFE204020A0211022082DF6200027BC24A424A427BC411042A884440882 +389C:00803FFE22083FFE220823F8200027FC244427FC244427FC40404524850A08FA +389D:010000803FFE24002706293832082F882ABE2F882A9C2FAA4008554895482008 +389E:00807FFE40007E7C52244A1452244FF848884FF848884FF842205FFC44108808 +389F:00000020F82008201020113C2120792009200920492031FC10002C0043FE8000 +38A0:000003FCFA040A0412F4129422947A940AF40A944A04321412082C0043FE8000 +38A1:0440247C24A83D5004287DFE24884448841808200820FFFE0820102020204020 +38A2:082049202A3E7F4841A85D2855105D28424608200820FFFE0820102020204020 +38A3:2420FF20247E7EC482287A104A287AC6040008200820FFFE0820102020204020 +38A4:084008487F4408440840FFFE104010401F401140112021222112410A4A068402 +38A5:00207F28412441245D20413E41E05D205520552055205D2441144114450C4204 +38A6:0020FF2802247A244A207A2E00F0FF2002207A204A204A107A12020A0A060402 +38A7:00007FF0001000103FF0200020003FF800080008FFE800080008000800500020 +38A8:00007DFC0420042004207C20402043FE40207C20042004200420042028201020 +38A9:00407C40048004FC05047E044004410440847C44044404040404040428281010 +38AA:0000F9FC0800080008007BFE40804080410079FC080408040804080450282010 +38AB:0020F8200820082009247924412441244124792409240924092409FC50042000 +38AC:0040F840084008400BFE7840408040904090792009200A480A440C8451FE2082 +38AD:00207C200420043E04207C20402041FC40847C88044804500420045029881606 +38AE:0080F88008FE09000A207920412C417443A47924093409280922090250FE2000 +38AF:0000FBFC0A040A040A047BFC4220422043FE7A200A200A100A120A8A53062202 +38B0:0010F810081009FE09127914411041FC414479440928092809100A2852442482 +38B1:0020F840088809040BFE780240204020412879240A240A220C22082050A02040 +38B2:00007CF804087CF840807CF804080408285010200000FFFE0000082010102008 +38B3:00807C8004FE050006007C1C41E0412041227D24052805100510054829841102 +38B4:00003FF8000800083FF8200020003FFC00043FE42AA424A42B2424A43FE80010 +38B5:0020F8200850088809047A0241FC4000400079FC090409040904090451FC2104 +38B6:0000FBFE08200820084079FC41044104410479FC090409040904090451FC2104 +38B7:00107C920492049204FE7C204020407E40827D42042404280410042028401180 +38B8:0020F7201120113E1144F744844484A48428F7281110111011281148AA844502 +38B9:00407C2005FC040004887C5043FE402040207C2005FC04200420042028201020 +38BA:0040F82009FC08000888785043FE404040407BFE088809880850083050C82304 +38BB:001CF9E0082008200BFE78A84124424240407BFE0888090808D0083050482184 +38BC:00207D2404A404A804207DFC4124412441747DAC052405240524050429141108 +38BD:0000F7EE124212421242F3CE8248824883C8F24E124212E217421042A0544048 +38BE:0000FBFE0850085009FC79544154415441FC7820082009FC0820082053FE2000 +38BF:0080F8BC0884090809FE7B204520417C4190791009FE09100928092851442182 +38C0:0020F8200BFE082009FC790441FC410441FC790409FC09040BFE088851042202 +38C1:0088F8880BFE088808887BFE408041FC43247DFC092409FC092409245124210C +38C2:0000FBFE080009FC0904790441FC400043FE7A8A0A520BFE0A220A22522A2204 +38C3:0200F11E17C212021482F7DE805087908490F79E1482178214821482A4944588 +38C4:0200F97E08400C7C0A4478FC4140467E422078200BFE087008A8092452222020 +38C5:0000FBDE08880AA80BFE798842DA44A641F87908090809F80908090851F82108 +38C6:07FCF24817FC1C4616ECF55486EC855486ECF454140817FC104013F8A0404FFE +38C7:08000FE010201FC000407FFC09003200CC803080CFF80888088808A808900080 +38C8:20203C3C444478780808FEFE5050A8A84848BEBE2A2A2A2A2A2A2E2E08080808 +38C9:000400047F08081008200844080408080810082208420F04F008401000600180 +38CA:040008001FF02820444003801C70E10E0600384001880610382000C007007800 +38CB:11001104110411087FD01122190215041108FFD0112211021104210821104160 +38CC:08000804080408080F900822080208047F08411041224102410441087F104160 +38CD:08000804100422084110FFA2008200047F08411041224102410441087F104160 +38CE:010002001FF010101FF010101FF001001150218846441990062018C007003800 +38CF:08000804FF84140822104122BE8222043E0822103E220802FF84080808100860 +38D0:080010047F0441087F1041227F0208040808E8902D222A024904888828101060 +38D1:02023FC222042F8822903FC222822F8422082F902A822F824A844F888A9009A0 +38D2:410022040004FF888890AAA29C828884FF8800107F2241027F0441087F104160 +38D3:08020DC228443D484490A9423242C404248815107FC20E0215042488C4500420 +38D4:0800080013FE2020482008201020302050209020102010201020102010A01040 +38D5:084008401040204048400FFE10403040504090A010A010901110110812041402 +38D6:08400840104020404BFE0840104030A050A090A0111011101288124814441802 +38D7:08400820102021FC49040904110431FC51049100110011001100120012001400 +38D8:08800880110021FC4A040C0411E431245124912411E411241004100410281010 +38D9:104010402040404097FC144424446444A44427FC244424442444244427FC2404 +38DA:08000BFC120422044AF40A04120432F452949294129412F41204120412141208 +38DB:0840084010A021104A080C0613F83000500093F8120812081208120813F81208 +38DC:100217E22242424A924A124A224A67EAA24A224A224A224A22422442244A2844 +38DD:08280824102420204BFE082011243124512493A8112811101212122A14461082 +38DE:08900890110821484A440C92110833FC509490901090109011121112120E1400 +38DF:08200820102023FE4820082011FC3000500091FC110411041104110411FC1104 +38E0:10401040207C40849588165024206450A488270624602410240820C020202010 +38E1:111011102110421092FE169226926A92A29222FE229222102210221022102210 +38E2:09080888109023FC4824082413FC3220522093FE106210A2112A122414201020 +38E3:10401040204047FE9040145022486248A55428A220A021102110220824042802 +38E4:08500848105E23E44828083210CA370650509048105E13E41028103210CA1706 +38E5:111011102110427C921016102AFE6208A20822FE220822482228220822282210 +38E6:08380BC0104020404FFC095012483486508097FC1110121011A0106010901308 +38E7:11001208244847889108124827C86008A7C8244827C8244827CA244A244A24C6 +38E8:12101210221042109F7E151025106510A57C29442544224422442544257C2844 +38E9:111011102110411097BC111021106338A3B82554255429922110211021102110 +38EA:083C0FC01244212848000BFC1080308057FE910011F812881250142018D81306 +38EB:0808083C11E020204BFE082011FC312451FC912411FC102011FC102013FE1000 +38EC:080009F81108210849F8080017FE310851F8910811F81108113E17C810081008 +38ED:08000888125222224A520A8A120233FE50889144127A10881150102010D81706 +38EE:0820082013FE202048200BFE128A325252FA9222122212FA12221222122A1204 +38EF:08000BFE120222024BFE0A101292325452FE928212FE128212FE1482148A1884 +38F0:081C09E01020212448A80BFE107030A8512492221040102412A2128A14881078 +38F1:08200BFE102021FC48200BFE100031FC510491FC110411FC110411FC10881104 +38F2:121012102A904A909FBE102420546F94A01420142F94288828882F9428942022 +38F3:1100110023FC46A89AA812A827FC62A8A2A822A82FFE200022A8225424542000 +38F4:1110111027FC411091101FFE204067FCA44427FC244427FC2000211022082404 +38F5:10101410227C401090FE1044262862FEA210227C221022FE2210221025FE2800 +38F6:10401FFE200047FC940415F4251467FCA00023F8220823F8220823F820002FFE +38F7:1080104027FC444492A8129424746000A3F822A82FFE200027FC204021402080 +38F8:150815482DA8453E9FA8124824486ABEA30825882988237E25402920251E2200 +38F9:1040102027FE44A894FE1550277C6550A57C2550257E254028A42A8A328A2478 +38FA:0400040004000400251024882444444404000400040004000400040004000400 +38FB:1010082004400280010002800C603018C0060100088848844812481287F00000 +38FC:1000100011FC1044184455445144514491441244104410841084110412281410 +38FD:02000200FFFE042008201C4003800C7070080100088848844812481287F00000 +38FE:100013FC11041144192454A85088508890501050102010201050108811041602 +38FF:10401040108018FC550452045004910410841044104410041004100410281010 +3900:030000802140222024102808300620003FFC0100088848844812481287F00000 +3901:00003FF801000100FFFE0280044008203018C106088848844812481287F00000 +3902:00003FE0082008400C780A081210112020C043308C0E02005104511290120FF0 +3903:10401020102013FE18805480508050FC90841084108410841104110412281410 +3904:10201020102013FE1820542051FC512491241124112411341128102010201020 +3905:7FF80200420042007FFC0480088010842084C07C010008844892481287F00000 +3906:1008101C11E01100190055FC5144514491441128112811101110122812441482 +3907:1010107813C0104018405440504057FE904010A010A010901110110812041402 +3908:1000104010201010189054805080528492821282128214881088108810781000 +3909:100013FC1010191055105110521093FE10301050109011101210141010501020 +390A:1004130810D01020185054885104500090041104108810501020105011881606 +390B:101010901090188855085104520495FA10881088108810881108110812281410 +390C:10881088108810881BFE548850885088908810F8108810881088108810F81088 +390D:00007DFE1040108011FC10041E04E00440280110088848844812481287F00000 +390E:100010007E7C1244124412442244227C4A448400010008844892481287F00000 +390F:1080108010F811081B1054A0504050A093181C0610C010201010118010601010 +3910:0100010001FE010001003FF8200820083FF82008010008844892481287F00000 +3911:10201020102010201BFE54405040508090FC1184128410841084108410FC1084 +3912:10201020102013FE18505450508851249222102011FC10201020102010201020 +3913:10401040104010401BFC544050E050E091501150124815F41842104010401040 +3914:1088108810881908557E53085508914811281128110811081108110811281110 +3915:10201020112411241924552451FC502090201124112411241124112411FC1004 +3916:10401020102013FE1A0254045000500093FE1020102010201020102010A01040 +3917:010001007FFC01003FF80200FFFE082012102208C2261290124822480A000400 +3918:1080108010F811081A10542053FC50049004100411FC10041004100413FC1004 +3919:3FF8200820083FC8204820483FC8200820083FF8010008844892481287F00000 +391A:10801080113C1A0054805080517E930815081108110811081108110811281110 +391B:10801088109C1970551053105510911011FE11101110111011101110117C1100 +391C:202820242024202033FEAA20A224A224A32422A8222822102212242A24462882 +391D:10401020102013FE18405488510453FE909210901090109011121112120E1400 +391E:1040102013FE1A025400503853C090401040107C17C0104010421042103E1000 +391F:044004403FF8244824483FF8244824483FF80100088848844812481287F00000 +3920:7F84082410243F2451240A24040408043014C008010008844892481287F00000 +3921:200420042FC422143214ABD4A254A454A6542554289420942104220424142808 +3922:1040104017FE1080190055FC5304550499FC1104110411FC1104110411141108 +3923:101008207FFC08200820FFFE0820102020204120088848844812481287F00000 +3924:1020102013FE12221A2257FE5222522293FE1020112010A0104010A011181606 +3925:10401020102017FE18405484510853F090221044118816101020105011881604 +3926:204020402FFE3040A840A7FCA444A44427FC2040224021402080214022302C0E +3927:1008101C11E01100190055FE51005100917C1144114411441144127C12441400 +3928:10881088108810881BFE548850885088908817FE100010881084110412021402 +3929:08000FF010202C4003801C70E00E1FF0101010101FF002005104511290120FF0 +392A:0000FFFE100010F83E884288A4A818941084207CC10008844892481287F00000 +392B:040004007FFC08001FF028104FF088100FF0081008500A205104511290120FF0 +392C:1020102011FC18205420502053FE90001020102011FC10201020102013FE1000 +392D:1010107813C01040184057FE50A0511092081516111011101110121012101410 +392E:2200140019FC24204C2014F82420442005FC2800110008844892481287F00000 +392F:100013FE120212521A8A5706520252FA928A128A128A12FA128A1202120A1204 +3930:0900090011FE1280348050FC9080108010FC1080108002005104511290120FF0 +3931:100013FC1000100019F855085108510891F81000110810881090100017FE1000 +3932:010001007FFC11101110292845440280044008203018C106088828A4282447E0 +3933:100013FE10101820546850A453229020100011FC110411041104110411FC1104 +3934:20002FFE248024903490AF90A490A490A49027902490249224D22F92208E2080 +3935:00407E40047E08880E881948E850082008502888130602005104511290120FF0 +3936:10901088108013FE18A054A850B050A490A810B01124112A1132122212DE1400 +3937:1040104010A011101A88544651F050109020104013F812081208120813F81208 +3938:1040104013FC18405440504057FE909012941292149219121110121014501820 +3939:105010481048184057FE504052449164116810D0115012481444104211401080 +393A:208020402FFE22003200AA00A3F8A000A2482248224822482248244A244A2806 +393B:0600387C224432642A5422442A54324804401840610008844892481287F00000 +393C:1110111011101390193C5514511457D4911411141214129417D4122410541088 +393D:1020102013FE182055FC504053FE9048108810FE110811481228140810281010 +393E:100013FE12021252188855045020502093FE1020107010A81124162210201020 +393F:1040108017FE11101A48544653F85248924813F81248124813F810421042103E +3940:1040104013FC1040184055F8510851F8910811F8110811F81108110817FE1000 +3941:010001007FFC01001FF01290129052905FF040007FFC02005104511290120FF0 +3942:100013F8120813F81A0857F8500053FC901017FE101012101110101010501020 +3943:100013DE125212521BDE5652525253DE920212021202120212021202120A1204 +3944:1020102011FC1820542053FE50889144124210F8118812501020105011881606 +3945:101C13E010841A445548511057FE9402100013F81108111010A0104011B0160E +3946:1040104013F81848544857FE5048904813F8144412E811501248144611401080 +3947:10501048105E13E41828543250CA570690501048105E13E41028103210CA1706 +3948:10201020FE3E9220922092FC9A84948410FC1100088848844812481287F00000 +3949:1040102011FC100019085490500053FE9000100011FC11041104110411FC1104 +394A:200027BC24A424A434A4AFBCA4A4A4A4A4A427BC24A424A424A424A42AA4314C +394B:0840082017FE104030A451A89290148810C41082010008844892481287F00000 +394C:1100110011FC1A045484549452A4908417FC108411C412A41494108410A81010 +394D:1108110817FE1108190855F85108510891F81108110817FE1000109011081204 +394E:0C80708011FCFD24322438445444508491041228111008844892481287F00000 +394F:10901090109013FC1A945694529453FC92941294129417FE1000109011081204 +3950:010002800C603018C7C600003EF8228822883EA8009002005104511290120FF0 +3951:00007FFC02001FF010101FF010101FF010107FFE410288844892481287F00000 +3952:1008103C13C010441A2455285100502093FE107010A810A81124122214201020 +3953:1040104013FC18A05510520857FE900813C812481248124813C8100810281010 +3954:1040102013FE1880550453FE500291FC110411FC110411FC1104110411141108 +3955:01000910092012C0043019086914091012A004401830600C01004884481287F2 +3956:00907890490849086A445C524888FDF84808484048244AA24A8A4C8888781800 +3957:11FC1104110411FC1904550451FC5040902013FE108810881050102010D81706 +3958:22002200227E27123212AA52A252AFD2A2522292241225122FA224A2204A2084 +3959:1020102011FC11241924552451FC50209040102010A41282128A128A14781000 +395A:20402140265C3444AC44A75CA444A44427FC244420A020A02110220824042802 +395B:100013FC10081810542053AE52A292AA12A412A413AA103210A0104017FE1000 +395C:100013FE12221BFE562253FE500091FC110411FC110411FC1104110411141108 +395D:2000277E21243124A93CA724A424A43C242427242126217C210421042A042404 +395E:11041088100013FE184054C25122525490981138125410941112161010501020 +395F:110011F8120813F0181057FE50805144966810B01128166810A4112216A01040 +3960:100013FE10221920553C512052FE940011FC110411FC110411FC110411141108 +3961:100013FC120413FC1A00569852E05284927C122013FE127014A815241A221020 +3962:11081088109017FE1890549053FC52949294130C120413FC1204120413FC1204 +3963:020002007FFC0440092037D8C1061FF001000FE001003FF801004884481287F2 +3964:00207E20145008887F442A2249F8880828101020010008844892481287F00000 +3965:11FC1124112411FC1924552451FC5020902013FE1222122A12FA120A12021206 +3966:3FFC20802FF82080249024902AA83144222024103FFE02005104511290120FF0 +3967:100013FE1020104019FC5504510451FC910411FC1104110411FC100010881104 +3968:102010F8FC20242025FC4800282010F82820442081FC02005104511290120FF0 +3969:1040104413F41848545057FE5040908011F81308150811F81108110811F81108 +396A:1020112410A810201BFE54A851245202904017FE108811081190106011981604 +396B:1040102017FE100019F8550851F8500093FC1204120413FC1204120413FC1204 +396C:2080204027FC3208A910A7FEA402A884204027FC210021F82108220822282410 +396D:1020102013FE102019FC544053FE508891241222112410A81124122210A01040 +396E:1080108011FC1244195455F450845128929011FC1244155411F4108411281210 +396F:007C7F80110808903FF80100FFFE00003FF800081FF800083FF8020851249FE4 +3970:10A0132E122212221BAE5622522253FE902013FE110410881050102010D81306 +3971:100013FE122812281AEE5628522852EE9228122812EE12281228122813FE1000 +3972:01007FFC01001FF010101FF010101FF01010FFFE1010200801004884481287F2 +3973:200027FE2420244035FCAD04A5FCA504A5FC2524242024A829242A2230A02040 +3974:2004203E27E0343EAC20A5FEA522A53825E2251E250029782A48324A248A2906 +3975:200027FE240225FA3442ACC2A52AA46AA4B2252A246A24AA2522244227FE2402 +3976:01007FFE44429FF404403FF80440FFFE082012102108C9062828282447E40000 +3977:010000803FFE20402FFE22482248255428A223182C0620804A444A4A920A01F8 +3978:0000FDFC85248524FDFC9124912491FCFD049000902090149552B542CE488438 +3979:1010545038881104FEFA10483848548891281210010008844892481287F00000 +397A:1020102011FC1820542053FE5080910413FE100213FC12941294129417FE1000 +397B:002800243FFE20A02F2422242FA822182B1252AA4A46848201004884481287F2 +397C:200027FC20403278AA40AFFEA100A1FC220023FC200425542554280420282010 +397D:102013FE102019FC542053FE500091FC110411FC110411FC110411FC10881104 +397E:100013FE124812481BFE5648522053FE924012FC13441244127C120013FE1000 +397F:08207F20087E7E4408A4FF2810101E2822444682810008844892481287F00000 +3980:2020247C22843148A830A0CEA610A27C2210227C221022FE2210221025FE2800 +3981:004027FC104013F8024873F8124813F8104017FC284047FE01004884481287F2 +3982:111009203FFC20044FE808200FE001003FF82108211802005104511290120FF0 +3983:1040102013FC18005508509053FE922012A012FC1320122012FC1420142019FE +3984:010000803FFE222022202F7C222027702AA83224208020484A444A1491F00000 +3985:22A822A827FC32A8AAAAA4E6A800A7FC2444204023F822482248224822582040 +3986:1040107C10401BFE5642527853C4923C120812F0132412A815FE142018A01040 +3987:1040102013FE12501A5057FE5252525293FE1200129212D41298149214D2188E +3988:22082110200027FC3040ABF8A040A7FCA00023F822A822A822A822A82FFE2000 +3989:102013FE102019FC540053FE520291FC100011FC110411FC1104108813FE1000 +398A:108813FE1088100019FC54A850A853FE90A810A811FC102013FE102010201020 +398B:2040204027FC3110AA48A446A3F8A05027FC208023F82D0821F8210821F82108 +398C:01F03E0003F03E0003FA7E0201FE0C20703C1DE2F0221C1E01004884481287F2 +398D:100013DE125212521BDE5488505053FE90201124112411FC1024104010801100 +398E:102011FC102413FE182455FC502053FE900011FC112411FC112411FC100013FE +398F:200027BC24A427BC3420ACA4A39CA000A11027FC211021102FFE211022082404 +3990:101417FE10101BD0541053D0501093D0125013D0125013C8124A13CA11861242 +3991:2008278820883110AFDEA494A4A4A79424942794249424C827882C9420A420C2 +3992:100013FE125212521BFE542053FE500091FC100011FC100011FC110411FC1104 +3993:1110111411D212501A7E5550509052A89128114412441482100812A412521452 +3994:3E1022143E1222103EFE00103E2822283E2822443E44228227004884481287F2 +3995:20202720253C254435A8AE10A528A546A53825102550267E2490247C241024FE +3996:2000279E2492279E3492AF9EA442A422A40A25462542255226322402240A2404 +3997:2110211027BC3110ABB8A554A912A00023F8200027FC20402248244429422080 +3998:10207E20423E7E4442A47E241028FF2820103E284244868201004884481287F2 +3999:11FC112411FC192455FC502053FE922A12FA120A1246102010A4128A128A1478 +399A:401020082108F8BE008050142208FA3E22082A487A3C2AA82AA8528841888008 +399B:0A0033B822083BB820883AB82288FFFE082012102108C9062828282447E40000 +399C:210827FE2148222037FEAA20A3FCA220A3FC222023FE220027F8211020E02F1E +399D:3C20D0404DFC3104C9FC150425FCCC5014502492D50E0A0001004884481287F2 +399E:01007FFC01003FF80000FFFE00023FF00100FFFE00107DFC44907D30489487F2 +399F:31FCCB242D2431FCC924152425FCCC2015FC2420D4200BFE01004884481287F2 +39A0:228422842AA426C4329EAFE4A004A454A28C2FE4210427C4210421C42E142008 +39A1:244424E428A83AAAAEEEA4A4AAAAAEEE224220402FFE20E0215022482C462040 +39A2:1108110811EE12941842540053DE525293D2125213D2121A1294135012101010 +39A3:2100479C828017C0203E6788A4882788210827C829082FE821104884481287F2 +39A4:1040FE40107C7C840028FE2082207C5000887D2644107C5445422F4AF2384000 +39A5:20402FFE284227FC3040ABF8A040A7FCA04027FC24A427FC20402524252A28FA +39A6:2000279E2492379EAC92A79EA482A532251225B2251225F224A2252A261A2404 +39A7:2108252827BE294837BEAB18A5AAA946A3F82208220823F82208220823F82208 +39A8:27BC24A427BC24A437BCAC44A5F4A444A5F4255425F4255425F424E42554244C +39A9:201C2EE02A542A283A7CAC10AAFEAA00AAFC2A042A7C2C0428FC2814294A2A38 +39AA:224822E8230836EAAA1CA2E8A208A2E825B428E2200023F8211020E023182C06 +39AB:252827BE294837BEAB18A5AAA946A3FC220423FC220423FC220423FC21082204 +39AC:200027FC24A424A437FCAA10A2A8A4BEAF68223C24A82FBC20282AA82ABE2020 +39AD:27FC20402FFE28423358A840A358A000AEEE2AAA2EEE20002FFE224825542FFE +39AE:0240022003F87E00020003F83E00020002FC7F100120014001840E447034000C +39AF:004800440040FFFE004008400844104422447F28012800120F32F04A40860302 +39B0:225022482248554088C00040FFFE00400040002400280012003200CA03060002 +39B1:004000487F4400440040FFFE0040084408447F440828082A0F12F02A40460082 +39B2:084008487F4408440840FFFE104010441F4411441128112A2112252A42468082 +39B3:084008487F4408440840FFFE0040084408447F440828082A0F12F02A40460082 +39B4:004800440040FFFE20403E404244B4440C443228C1287E124232424A7E864302 +39B5:0828482448247F20482E88F00820FFA418241C282A2829104912882A08460882 +39B6:004800440040FFFE00407F40104422447F4409283E2808120F32F04A00860302 +39B7:0028FC2404246820102EFEF092209224FE2492289228FE109212922A92468682 +39B8:082808240FA408207F2E41F07F2041247F2449280828FF900812082A08460882 +39B9:00207C2844247C2444207C3E01E0FE2440247E28AA282A104A32924A2A864502 +39BA:00287FA440245F20402E7FF055205224592450A842287F9052124A2A82460682 +39BB:0028EF242124A920652EA9F0212010247E24422842287E104212422A7E464282 +39BC:082808247F2410203E2E1070FFA02224412490A8262822103612222A3E462282 +39BD:20142012FC1023FE40107BD04A50CBD278124BD248147AAC4D4A4AAA48165822 +39BE:020001003FFC200420043FFC2080248024F027903C90249244B2440283FE0000 +39BF:020001003FFC200420043FFC208020802FF821C022A022A04490488890840080 +39C0:020001003FFC200420043FFC20002FF022102220233822884450442088D81306 +39C1:010000803FFC20043FFC208020802FFC208020803FFE2100421044088FFC0404 +39C2:020001003FFC200420043FFC200020002FFC288428842FFC488448848FFC0804 +39C3:1004100410841084FE841084108412841C8C30B4D0C410841004100450042004 +39C4:1000100011041104FD0411041104150419043104D1041104110411FC50042000 +39C5:1000100011FC1044FE441044104412441C443044D04410841084110452282410 +39C6:1020102010201020FDFC11241124152419243124D12411341128102050202020 +39C7:1000100011FC1104FD0411041104150419743104D10411041104110451142108 +39C8:100011FC10041004FC0410FC10801480190031FCD00410041004100450282010 +39C9:1100110011FC1200FC0011F8100014001BF83008D0081008100A100A50062002 +39CA:10201020102013FEFC20102011FC152419243124D12411341128102050202020 +39CB:1040104810441044FC4013FE10401440184030A0D0A010901110110852042402 +39CC:1008103C11E01020FC20103C11E014201820303ED3E01020102210225022201E +39CD:10401020102013FEFC801080108014FC18843084D08410841104110452282410 +39CE:100011FE10081088FC881088110815FE18183028D04810881108120850282010 +39CF:200023FC22042204FA94225422242A243254E2542294230422042204A2144208 +39D0:2000200027BC20A4F8A424A422A42AA83128E1282290229024A82828A0444082 +39D1:1020112010A010A0FC2013FE1022142218423052D04A108A1082110252142408 +39D2:20402020202023FEFA022404200028903090E0902088210821082104A2044402 +39D3:1008103C13D01290FE901290129016901A903288D28812C812A414D454922800 +39D4:2028202420242020FBFE222022242A243224E228222822102212242AA4464882 +39D5:20002080231E2252FA52225222522A523252E2D2235A225420902090A1104210 +39D6:1040102011FC1104FD0411FC11001500197C3108D110112011421282527E2400 +39D7:1090109010901290FE9212D4129816901A903290D290129212D21712520E2000 +39D8:088008882E9028E428842E7CF00000E01F0001003FF801007FFC010005000200 +39D9:1000104010201028FC08108814901A9432A2D2A214C210881188128854782000 +39DA:1000100013FC1100FD0011F01110151019903250D2501210121212925312220E +39DB:04402440247C248024902508040800E01F0001003FF801007FFC010005000200 +39DC:100013FE12101210FE1012FE129216921A923292D29A12941210121053FE2000 +39DD:100010007E7C124422442A7C440080E01F0001003FF801007FFC010005000200 +39DE:1008103C11E01020FC2011FE10401440187C30A4D0A811281110122854442082 +39DF:2200217E21402440FA402240204029403140E2402640224022402240A27E4000 +39E0:1020104010881104FBFE1002142018203128D124122412221422102050A02040 +39E1:10201010101013FEFC201042108415F818103022D0C413081010102850C42302 +39E2:200027FC24042444FC44244427FC2C443444E4A42494251426042404A7FC4404 +39E3:10201120112011FCFD201220102013FE187030A8D0A811241124122250202020 +39E4:10401020102013FEFC40108815041BFE3092D0901090109011121112520E2400 +39E5:10201120112011FCFD201220102013FE18903090D0901090111211125212240E +39E6:20802080210021FCFA04240423E42A243224E3E42224222423E42004A0284010 +39E7:1040102013FC1040FC90110813FC100419503150D1501150125012525452280E +39E8:1008101C11E01100FD0011FE11001500197C3144D14411441144127C52442400 +39E9:200027FC24042404F5F42444244425F43554E5542554255425742446A4464842 +39EA:1040104010FC1104FA0811FE1500197C3144D1441154114811421242523E2400 +39EB:100013FE10201020FC4011FC1154155419543154D15411541154114451142108 +39EC:00007DF0111011901D52F20E440000E01F0001003FF801007FFC010005000200 +39ED:7CFC1088109010881E84F094408800E01F0001003FF801007FFC010005000200 +39EE:10001040119C1104FD041104110415DC19043104D1041104110411FC51042000 +39EF:10401040104411F4FC48105013FE104018803184D29814E010821082507E2000 +39F0:1008103C13C01200FE201220122013FE18203020D12811241222142250A02040 +39F1:0808081C147022104110BEFC001000103E1022FE2210221022103E1022500020 +39F2:2080204027FC2404F848204020402BFC30E0E1502150224824442842A0404040 +39F3:1088FD0412FA1C48F0881128321000E01F0001003FF801007FFC010005000200 +39F4:101010D813941094FC9013FE10901494189430D8D398109010AA10CA52862102 +39F5:100013FE10101020FC6810A413221020180031FCD10411041104110451FC2104 +39F6:1040108011F81108FDF8110811FA150A190C33F8D01810281048118856282010 +39F7:100011FC10201020FC2013FE10501488190432FAD48810881088108850F82088 +39F8:1040102013FE1000FDF81108110815F8180033FCD00810301020102050A02040 +39F9:100011FC110411FCFD0411FC100015FE180833FED00811081088100850282010 +39FA:1020102213B410A8FCA8112412A2104019FC3104D10411FC1104110451FC2104 +39FB:100013FE10401080FD441224106812B0193032A8D06810A41122122050A02040 +39FC:1020102013FE1020FC2011FC102014201BFE3040D0A411A81290148850C62080 +39FD:100011FC11041124FD2411FC1124152419743154D15411741104110451FC2104 +39FE:1080108010FC1154FA5410A415241A443094D108104010A412AA128A54782000 +39FF:1088108810881088FD5412221442102018203120D13C112012A01260543E2800 +3A00:103C11E0102013FEFC2011FC14241BFE3024D1FC107010A81124162250202020 +3A01:1040104013FC1040FC4011F8110815F8190831F8D10811F81108110857FE2000 +3A02:1020102013FE1020FDFC112411FC152419FC3020D07010A81124162250202020 +3A03:1040102013FE1000FDFC110411FC140019FC3008D01013FE1020102050A02040 +3A04:200027FC24442444FDF4244424442FFC3404E5F42514251425F42404A4144808 +3A05:1088108813FE1088FCA8102011FC152419243154D14C11841104110451142108 +3A06:2110211021102110F7BC21102110233833B8E5542554299221102110A1104110 +3A07:102049FC212409F871481230144C00E01F0001003FF801007FFC010005000200 +3A08:1040102017FE1108F890106011981E063108D1F8110811F81108110852082408 +3A09:100013FC120413FCFE2013FE1210128A1B063000D3FC120413FC120453FC2204 +3A0A:1040104013FE1080FDFC122015FE100019FC3104D1FC110411FC110451142108 +3A0B:1040104413F41048F85017FE1040188031F8D308150811F81108110851F82108 +3A0C:08007F7808483E4800487F86410082FC3C4408447E2808287F10082828441182 +3A0D:08083EFE08087F4808283E0808287F1000201FC001003FF801007FFC01000300 +3A0E:100013FE10201040FDFC1154115415541954312CD02013FE1050108851042202 +3A0F:1020112411241124FDFC108014801BFE3090D1101152125412A8142858442082 +3A10:2100217C21442244F244267C2A10221032FEE2382254225422942312A2104210 +3A11:1000108812521222FE52128A120217FE18883144D27A10881150102050D82706 +3A12:1020102013FE1050FC88132611FC1420182033FED000102011FC1020502023FE +3A13:1040102013FE1202FC8811041222112019FC3220D02017FE1020102050202020 +3A14:20142012201027FEF410241025D024123412E5D42554254825DA242AA8465082 +3A15:100013F811081110F91C12E412A41A5434A8D10013FC12941294129457FE2000 +3A16:2008200827C82210FA1E24A427D429143114E7D42114210821C82E14A4144022 +3A17:10401040107E1040FBFC100415FC180433FCD0401240127C1240154054FE2800 +3A18:1020102010A410A2FD2A10101460198036FCD08410FC108410FC108450FC2084 +3A19:101E13E011221094FC40108811F0142018C431FED022102013FE105050882306 +3A1A:1090109013FE1090FD0011FC120411E4192431E4D12411E41124100450282010 +3A1B:100013DE125213DEFA5213DE12021A223222D2221252124A128A1202520A2204 +3A1C:1040107C104013FEFA42127813C41A3C3240D22013FE12881250142054582986 +3A1D:100013FE12021202FBFE121012921A5432FED28212FE128212FE1482548A2884 +3A1E:1020102013FE1020FDFC102013FE1440188831F0D02413FE1022112452A22040 +3A1F:1020112411241124FDFC100013FE140019FC3104D10411FC1088105053FE2000 +3A20:100013FE12021000FDFC110411FC150419FC3040D02013FE1000108851042202 +3A21:200027FE240225FAFC4224C2252A2C6A34B2E52A246A24AA25222442A7FE4402 +3A22:21102212245427D8F810201227D22C4E3440E7D22454245827D02452A552448E +3A23:2120211022082486F91023F82008280037BCE08424A4229424A42084A2944108 +3A24:200027FE24502488FDFE269024FC2C9034FCE490249024FE24802400A7FE4000 +3A25:2008210821082208F2BE24AA2F2A212A322AE4AA2FB620A220222AA2AAAA4824 +3A26:10A0109011FE1320FDFC112011FC152019FE3100D3F811081090106051982606 +3A27:10401048108411FEFC2013FE108815041BFE3524D12411FC1124112451FC2104 +3A28:104013BE12121292FE5212AA132410401BFE3222D22213FE1222122253FE2202 +3A29:1040102013FE1202FAEC122412441A4432EED22412A412A4124E1460549E2900 +3A2A:100011FC110411FCFD0411FC1020152418A83020D3FE1090109011125212240E +3A2B:20902290229C22A0FAD02288228828803000E3F822A822A822A822A8AFFE4000 +3A2C:2040204023F82040F7FE200023F822083208E3F820A4212823102D48A1864100 +3A2D:1040102013FC1204FBFC120012F81A8832F8D20013FC132415FC1502590220FE +3A2E:2020224024EC24A4F4A424E424A424A436E4E40C2110211021102112A212440E +3A2F:2200211E27D22012F7D4245427D8201437D2E092211221DA27142110A5104210 +3A30:1040102013FE1088FD241242109015F818083044D0A81190128814A450C22080 +3A31:204020FC21082650F92020C023202FFE3000E3FC200023FC200023FCA20443FC +3A32:2110211027FC2110F840202027FC2C043444E04027FC20E021502248AC464040 +3A33:1040102013FE1202FC2011FC105014881BFE3008D1E8112811E8100850282010 +3A34:2110211021102FDEF12027C0245C27C43448E7C821102FD021222122A11E4100 +3A35:1108109017FE1000FBC4125413D41A5433D4D24412CC100013FC108451142608 +3A36:1040108011FC1104FDFC110411FC150019FE3100D1FE100212AA12AA5202200C +3A37:1088108813FE1088FCF8102011FC152419FC3020D3FE102011FC102053FE2000 +3A38:1040102013FE1242FC28129412AA14CA18F83300D02011241124112451FC2004 +3A39:108813DE108811DCFC8813DE108814001BFC3004D00411FC1004100453FC2004 +3A3A:1088108813FE1088FC8810F814201BFE3222D33212AA137612221222522A2224 +3A3B:08047F7808403E402A7E3E482A48FF4808A81FC001003FF801007FFC01000300 +3A3C:00407CF8554854307DCE54F854887CF800201FC001003FF801007FFC01000300 +3A3D:200427C420042394FA94239420142FD43554E55427D42554254427C4A4544008 +3A3E:2208211027FC2040FBF8204027FC28403020E1C02044276821502248AD464080 +3A3F:2040207C204027FEF442247825C2243E3500E53825A826AA2AA62940B2FE4400 +3A40:2040207C204027FEF442247825C224BE3480E5FC255426D424B4292EAA24504C +3A41:1040102013FE1202FCA0109011FE15201B2031FCD12011FC1120112051FE2100 +3A42:220422042784F494290C27C425643554E7C42546257C27C425442544A44448C4 +3A43:2040202027FE2492FBFC209023FC289037FEE1082204246220102180A0604010 +3A44:10201124112411FCFC0011FC112415FC192431FCD040102412A2128A54782000 +3A45:100013FE105013DEFE52125213DE10501BFE3222D22213FE1222122253FE2202 +3A46:221421122FD22010F07E2790249024903790E12825A825682928214AA54A4286 +3A47:102011FC102413FEFC2411FC14201BFE3000D1FC112411FC112411FC500023FE +3A48:1040102013FE128AFD0411FC14441BFE3044D1FC108011FC1284148450FC2084 +3A49:204020A0211826E6F80023F822082BF83000E7BC208424A4229424A4A2944108 +3A4A:101C13E010441124FC8811FC1154155419FC3008D7FE11081088108850282010 +3A4B:204023F8204827FEF04823F820402554375CE44427FC2444275C2554A5544844 +3A4C:109017FC109413FCFA9013FE11121BFA350ED1F8110811F8110811F850902108 +3A4D:1210121013DE1528FCA4102013FE10201BFE3222D22A127410A8112456222020 +3A4E:20082788248C278AF48827BE200827883488E7882494279424942494A49445A2 +3A4F:100011FC112411ACFD74112411FC142019FC3020D3FE100012A4125254522000 +3A50:2210221023DE2528F8C4204023FC284037FCE0102FFE201022102110A0504020 +3A51:200023F8208027FCF11022082CA620A037BCE0A023B820A027BC20A0A0A040A0 +3A52:2110211027BC2110FBB825542912280033F8E00027FC204022482444A9424080 +3A53:2C7844486C4844867D7800487C301048FCA41FC001003FF801007FFC01000300 +3A54:40004FDC48544854EFD44A944AA64FC06A9CCA944FD44814528852486454C822 +3A55:100011FC102013FEFA2211AC142019AC3050D0C8132610F8100810D050202010 +3A56:100013FE100011FCFD2411FC15241BFE3000D1FC112411FC112411FC500023FE +3A57:244427FC212023FEF6202BFC222023FC3220E3FE220027FC2108211EA2024C1C +3A58:1104108813FE1020FDFC102013FE145419923090D3FE109010D4138A509621A2 +3A59:2080204027FE2512FBFC211027FC291037FEE110224825F428422040A7FC4000 +3A5A:211027FC211027FCF40423F8200027FC3080E14426A8217026A82126A6A04040 +3A5B:27FC244427FCF44425F4255425F43554E5F4244C27FC241427FC2514A4B447FC +3A5C:201027D0251027DEF45027E8250427C43000E3F822A822A822A822A8AFFE4000 +3A5D:204027FE200021F8F90821F820002FFE3402E3F82180264421B82668A1A64E60 +3A5E:2110255425B82910F2A82444200027FC3444E04027FC20E021502248AC464040 +3A5F:1040102013FE1252FDFC105011FC14501BFE3088D12412FA1020112452A22040 +3A60:2080204027FC24A0F7FC24A427FC24003524E5A8253025A4251C2800AAA45452 +3A61:200027FC2100F3F82508210821F83000EFBE2208279E24922CB22492A79E4492 +3A62:210827FE21082000FBFC229422942BFC3028E3FE2220232422A82292A42A48C6 +3A63:27BC24A42294F4A42FFE284227FC3040E3F8224823F8224823F82040A7FC4040 +3A64:214827C8210827D0F55E27E4255427D43554E11427D4220823C82254A55448A2 +3A65:2114211227D22110F1102FFE229026D23292E6D2229426D4228A22CAAF164022 +3A66:10A0109011FE1320FDFC112011FC152019FE3100D3FE1252128A137652522276 +3A67:11FC110411FC1104FDFC108811FC14881BFE3088D12412AA107010A851242060 +3A68:108813DE108811DCFC8813DE108817FC180431FCD00413FC104012A4528A247A +3A69:2400249E25042608F45E245223D2211E3112ED5E25522592295E2920B52C4212 +3A6A:2100213E22082290F4BE2F222122223E34A2EFBE20A220222ABE2A80A8144022 +3A6B:2042239C221023DEFA94229424202BFC3204E3FC220423FC220423FCA1084204 +3A6C:210821CC210A27E8F52E25D8274824CA340AE54C276C2548254A297AA7A64042 +3A6D:22A0244C24A4260CF4A4264C24A42FFE3802E3F02020204027FC2040A1404080 +3A6E:2140226C2244236CFAA423AC22A42FFE3108E2F4244223F8204027FCA04040C0 +3A6F:221023D0241E2FE4F5542FF4254827D431B2E22027C0208827FC2044A3504488 +3A70:211027FE211023F8FA0823F820002FBC34A4E7BC20402FFE21502248AC464040 +3A71:101E13E011221094FBFE125217FE180433C4D27E13C4125413CC128452D42348 +3A72:21102FFE211027BCFCA427BC2140292033FEE22027FC2A2023FC2220A3FE4200 +3A73:2108229423DE26B4FBDE229423DE2A9433DEE21027FC210820902060A1984606 +3A74:27BC24A427BC24A4F7BC24A427BC212033FEE22027FC2A2023FC2220A3FE4200 +3A75:210821EC210A2FEAF9282BC8293E2FE83948EBE82A282B682AA82BF4AAB452A2 +3A76:221023DE25282084F7FE224827FC2C4636ECE55426EC255426EC2444A4544408 +3A77:204027FE249223FCF89023FC20902FFE3108E3FC252221F8212021FEA0024556 +3A78:11FC112411FC1124FBFE12AA17FE1AAA33FED02013FE124210F81150502023FE +3A79:11FC112411FC1124FBFE12AA17FE1AAA33FED00013FE128A10F81088508823FE +3A7A:00100410441044FE4410441044FC774444444444442844285510662844440182 +3A7B:201020107E1042FE84107F1040FC5E44524452445A2854285010942898441182 +3A7C:101010103E1042FEA410181010FC2444C8441F442128D2280C1008283044C182 +3A7D:10101010FE1010FE1010FE1092FC9244FE441044382854289210102810441182 +3A7E:02100F10781008FEFF102A102AFCFF442A442A44FF28082808100E2870442182 +3A7F:1020102020203F3E404480443E4402A40428082810102010212821281F440082 +3A80:00407C401040108010FE11081288FC8810881050105010201050108851042202 +3A81:081008101410141E2210521088FC084400447E44022804280410082808440082 +3A82:201020107F10801E00107E1000FC0044FC440444042805280510032801440082 +3A83:00100010FF90021E02107A104AFC4A444A444A447A284A28021002280A440482 +3A84:282028202820FE3E2A442A44FE44A8A4A828FF28291029102D284A4848848902 +3A85:7FFC01003FF82108228824482118010001FC01003FF00820044003801C70E00E +3A86:021007107810481E481048107EFC484448444844482844284510632849440482 +3A87:0820282028203E3E4844084408447FA414281428141014102528264844848102 +3A88:08100810081E7F10081008FCFF440044084408287F28081008100F28F0444082 +3A89:082008201420223E4144BEC4004400A43E2822282210221022283E4822840102 +3A8A:00107E101210121EFF10121012FC7E44204420447E286228A21022283E442282 +3A8B:00107F1041107F1E41107F1000FC00447F4408440828FFA80810082808440882 +3A8C:0010FC100410681E1010FE1092FC9244FE4492449228FE289210922892448682 +3A8D:082008207F20083E08447F44414482A43C28042808100F107828082828441082 +3A8E:081008100810FF9E08102A102AFC2A445D4488C4082814281210212841448082 +3A8F:101020107F10491E49107F1049FC51447F4424444428FFA80410042804440482 +3A90:081004103F10211E21103F1024FC264425443F44242824284A10492891442082 +3A91:08100810FF90141E2210491088FC7F4449447F4449287F2808100A280C440882 +3A92:101067104110411E7710411041FC7F4414441444142814282510262844448082 +3A93:02100F107810081EFF9008102AFC2A44EBC42A442AA86B28AA10082808440882 +3A94:221022102210221EF790221022FC66447744AAC4AA2832282210222822442282 +3A95:081008100F9E08107F1041FC7F4441447F4449280828FF900810082808440882 +3A96:00107E1002103E1E0210FF9008FC094449442A441C282A28C910092828441082 +3A97:101008107F1E0010221014FCFF44004400443E282228221022103E2822440082 +3A98:082008201420223E4144BEC4084408A47F28492849107F100828144822844102 +3A99:00207F204920493E7F44494449447FA40828FF281C102A104928884808840902 +3A9A:242024207E20243E2444FF4400447EA4422842287E10421042287E4842840102 +3A9B:22102210FF10221E3E1022103EFC22442244FF4440285428621040287E440082 +3A9C:101092109210921EFE100010FEFC10442044FE44AA28AA28AA10AA28AA448682 +3A9D:08100810FF90081E7F1049106BFC5D4449447F4408281C282A10492888440882 +3A9E:0010FF108110BD1E8110BD1081FC00447E4442447E2842287E1042287E444282 +3A9F:10200820FF20003E3E4422443E4400A47F28412841107F10412841487F844102 +3AA0:441028100010FF1E2810FE102AFCFF442A44FE4428286C28AA10292828442882 +3AA1:101008107F10411E08103E1008FC3E4408447F4408283E28221022283E442282 +3AA2:28104B104910491E6B10491049FC7F4408447F44012832280C10122861440082 +3AA3:102008207F20003E3E4422443E4400A47F2841285D1055105D28412845444282 +3AA4:00207F2049207F3E49447F442A442AA4FFA82A282A107F100828FFA808440882 +3AA5:10101E1010107F1E51105C1072FC4E4440445F4451285F2851105F285144BF82 +3AA6:10200820FF20813E00447E4408447EA44A287E284A107E100028244842848102 +3AA7:0810141022105D1E80903E1022FC3E4400447744112855283310552811443382 +3AA8:22101410FF9E08107F1008FCFFC449442A44FFA800287F10411041287F444182 +3AA9:04083F8804887FEE04883F88043C555475D444547FD4444875C8555455548462 +3AAA:00107F101010FF9E2210411094FC1444F7C4144477281428F790142814441482 +3AAB:10101F101010FF9E80907F102AFC5544A2447F44A2A83E2822103E2822443E82 +3AAC:0010EE102210AA1E6610AA1000FC24447F44C8447E2848287E1048287F444082 +3AAD:10101F10101EFF109110FCFC9144BF44AA44BE28AA28BE1080107F285544FF82 +3AAE:00087FC80408FFEE84283588041C359400140014EEF4AAA8AAA8AAB4EEF4AAA2 +3AAF:020001007FFC0820044003801C70E10E01001FF801000100FFFE010001000100 +3AB0:020001007FFC0820044003801C70E10E1110092005407FFC054009203118C106 +3AB1:0080208010F80108FE1009FC092449242924112413FE28502850488881040202 +3AB2:00400440024012400840084001FC7E400040004000407FF80008000800080008 +3AB3:0040044002401240084009FC7E400040004000001FF02008200820081FF00000 +3AB4:00107C10009000500010FE9028502810281E29F028102A104C10481080100010 +3AB5:101010109490585010107C9010501010FE1E11F0101010102010201040108010 +3AB6:0010FE101090105020107C9044504410441E7DF04410441044107C1044100010 +3AB7:0010FE10009000507C104490445044107C1E01F04410241028100E10F0104010 +3AB8:22082248FFA8222822083E48222822283E0E22782208FF080008140822084108 +3AB9:08087F484928FFA849087F4808287F28490E7F781008FF08210872080C08F308 +3ABA:08080848FFA80828EB88AAC8EBA8AAA8EB8EAAF8EB8814081208220841088108 +3ABB:210447C88812F3BC20084B92F83E0380AAAAABAA04401240087EFFC000400040 +3ABC:00000004FF78044004407440547E544854485448744854480448048814880908 +3ABD:0000FFFE0000000C7CF04480448044807CFE4488448844887C88450801080208 +3ABE:100010041E78224062409440087E144822484148BE482248224822883E882308 +3ABF:08004904497849407F401040207E48488848494849487F480848108820884108 +3AC0:00007C0444787C4044407C40007EFE4882488248FE4882488248FE8882880108 +3AC1:11009102AABCBBA09120AAA0BBBE8024FFA492249224A1A48024FFC400440084 +3AC2:100008047F784040524052407F7E524852485E48404855485548558880880108 +3AC3:202010201020FF20202020203E202220225022502250225042884A8885040202 +3AC4:02000100FFFE100010003FF8480884087FE810081F8810882088208842A88110 +3AC5:2020102010500088FD04220220F83C00240027FE248824882488448855088A08 +3AC6:202010200050FE50208821043E22242024A824A4252425224622542088A00040 +3AC7:10100810FF2820443E822210220842204A10840800003FF80008000800080008 +3AC8:10100810FF2820443E822210220842204A1084081FF02008200820081FF00000 +3AC9:2040104010FC0104FE0821FE21003D7C254425442554254825424542553E8A00 +3ACA:2100110011FE0200FC0021FE20083C0825E825282528252825E8440854288810 +3ACB:2080108010FE0120FE2021FC21243D2425FC2524252427FE2504450455148908 +3ACC:2080108010FE0100FE00200021FE3C1024102490249C24902490449055FE8800 +3ACD:2100110011FE0200FC902090215E3D6427542554255425482548455455148922 +3ACE:2100110013FEFC0023FE222239FC282029FC292429FC292429FC48205BFE8020 +3ACF:2100110011FE0200FDFC205021FC3D54255425FC244027FE2488459054708B8C +3AD0:00001FF0101010101FF0101010101FF00000203823C03C04200420041FFC0000 +3AD1:004000407C40444045FC444444447C4444444484448444847D04450402280410 +3AD2:00001FF0101010101FF0101010101FF008200820FFFE08200820102020204020 +3AD3:004000407C8044FE4500460044FC7C0844104420444044807D02450200FE0000 +3AD4:00001FF0101010101FF0101010101FF00200020003F8020002000200FFFE0000 +3AD5:00001FF0101010101FF0101010101FF000007FFC04400440084010422042C03E +3AD6:0200020003F802000200FFFE000000001FF0101010101FF0101010101FF01010 +3AD7:00001FF010101FF010101FF000001FE000400180FFFE01000100010005000200 +3AD8:00007FFC010003000570190CE10201001FF0101010101FF0101010101FF01010 +3AD9:002000207C20442045FC442044207C2047FE4420445044507C88448801040202 +3ADA:08001FF82248444808881108222804101FF0101010101FD0101010101FF01010 +3ADB:000001FC7D0445044504450445FC7C5044504450445044927C924512020E0400 +3ADC:000001F8790849084908490879F8490849084908490879F84800000007FE0000 +3ADD:0008003C7BE04A204A204A204A207BFE4A204A104A104A127A0A4A8A03260212 +3ADE:002001247924492449FC482048207BFC49044888488848507820485001880606 +3ADF:000000F87C8844884488448845067E00440044FC448444847C84448400FC0084 +3AE0:002000207D2444A444A8442045FC7C204420442047FE44207C20442000200020 +3AE1:1FF010101FF010101FF008001FF02820444003801C70E30E00C00E0001800040 +3AE2:00200020782049FC4820482048207BFE482048404840488879044BFE01020000 +3AE3:1FF010101FF010101FF001003FF8210821083FF8210821083FFA0102010200FE +3AE4:00001FF010101FF010101FF0010000801F0001047D88095011202118C5060200 +3AE5:004000407CFC45044688445044207C40448045FC468444847C84448400FC0084 +3AE6:0840084010FC10883550542094D8170614F81488148814F81488108810F81088 +3AE7:00001FF010101FF010101FF0111009200100FFFE0380054009203118C1060100 +3AE8:0040002078204BFE4A024C4478404BFE48884888490878D04820005000880304 +3AE9:010001007FFC01000820FFFE082008201FF0101010101FF0101010101FF01010 +3AEA:01007FFC01003FF80200FFFE08203018D3F61210121013F01210121013F01210 +3AEB:00001FF010101FF010101FF000007FFC044004402448144814500440FFFE0000 +3AEC:00800080790049FC4A044C047BE44A244A244BE44A247A244BE4000400280010 +3AED:00001FF010101FF010101FF001003FF80100FFFE00407FFC0840044001400080 +3AEE:088008882E9028E028842E84F07C00001FF0101010101FF0101010101FF01010 +3AEF:1FF010101FF010101FF000003FF820083FF820083FF800007FFC04401842E03E +3AF0:008000407BF84A084A084BF84A087A084BF84A404A444A287A104A8803060200 +3AF1:00001FF010101FF010101FF001003FF80100FFFE044024484444884211402080 +3AF2:002000207BFE482048204BFE7A024C0449F8481048207BFE4820002000A00040 +3AF3:00003FFC20002FF820003FFC24482530260E20002FF828084FF848088FF80808 +3AF4:004000447BF4484848484FFE782048404BF849104A207DFE4820002000A00040 +3AF5:0090009078904F9E4890489048907B9C4890489048904F9E7890489000900090 +3AF6:000001FC780448FC480449FC78004BFE4A22482049FC79244924013401280020 +3AF7:08207FFC08200FE008200FE00820FFFE10102008DFF610101FF010101FF01010 +3AF8:00400040F7FE904093F8904897FEF04893F890409240927CF240954004FE0800 +3AF9:1FF010101FF010101FF00000061838E020803E8022FC3E902090209040908110 +3AFA:08200820082014502288492408201450228841061FF010101FF010101FF01010 +3AFB:00400040F0A0911092089DF69000F7FC94A494A497FC94A4F4A494A404140408 +3AFC:008200827A824BEA4C8A488A4FFA788A4BEA4AAA4AAA4AAA7AA24AE2008A0084 +3AFD:000001F87808480849F8480848087BFE48204A22497448A879244A2200A00040 +3AFE:0020012478A448A848204BFE4A027A024AFA4A8A4A8A4A8A7AFA4A02020A0204 +3AFF:00A00090788049FE49104B104DFC7910491049FC49104910791049FE01000100 +3B00:004000207BFE480049FC490479FC480049FC480848107BFE4820002000A00040 +3B01:00001FF010101FF010101FF0204010A0811042E8140623F8E208220823F82208 +3B02:01FC0124792449FC4924492479FC482048204BFE4A227A2A4AFA020A02020206 +3B03:3FF820083FF820083FF8100020087FFC00043FF820083FF8110822900C60F01E +3B04:1FF010101FF010101FF000003FFC20802FF820803FFC22204A285424A4A20840 +3B05:3FF820083FF820083FF800007FFC44447FFC0000FFFE08000FF810082028C010 +3B06:000003FC7A044BFC4A204BFE4A107A8A4B0648004BFC4A047BFC4A0403FC0204 +3B07:0080008078F849084A104DFC79244924492449244BFE78504850008801040602 +3B08:000001F87908490849F84908790849F848004BFC4A947A944A94029407FE0000 +3B09:000003FE7820484049FC4954795449544954492C48207BFE4850008801040202 +3B0A:1FF010101FF010101FF000FC7F0811103FF80200FFFE080017F02220C1C00E3C +3B0B:008000BC7884490849FE4B204D20797C4990491049FE49107928492801440182 +3B0C:1FF010101FF010101FF00100FFFE00001FF010101FF010101FF0092011102308 +3B0D:002800247BFE482049FC492479FC492449FC492448087BFE4888004800480018 +3B0E:00001FF010101FF010101FF0082012483CF0082014503EF80000248822444244 +3B0F:000003FE780049FC4904490479FC48004BFE4A8A4A527BFE4A220222022A0204 +3B10:000003FC78904A94499848904FFE780049F84908490849F87908490801F80108 +3B11:0200011EF7D2901297D4945497D8F01497D29092911291DAF714911005100210 +3B12:008800887BFE488848244BFE7850488849044A8A48887BFE4888008801080208 +3B13:000003FE785049FC4954495449FC780049FC48004BFE482078A8492402A20040 +3B14:000007BCF08494A4929494A49050F188962690C093109064F388903000C00700 +3B15:022201127914483E4F8848884908793E4B884D484908493E7908490801080108 +3B16:02100110F79E94A494D497949408F4149462980093F89208F208920803F80208 +3B17:0110011479D24A504A7E4D5048907AA8492849444A444C8278084AA402520452 +3B18:002001FC78244BFE482449FC48207AAA4BAE4A224BFE4A227BAE4AAA02AA0422 +3B19:000E03F078444A2449084BF87A084BFC4A044BFE4A027AAA4AAA050204140808 +3B1A:02080108F7C89210949E9FD49064F7949494979494949788F488949404A405C2 +3B1B:004000A0F11896E6900093F89208F3F8900097BC908494A4F29494A402940108 +3B1C:0000FEFE20204444FEFE12127C7C10101EFEE0001FF010101FF010101FF01010 +3B1D:0104008878004BFE4A224AAA4A727A224BFE480049FC490479FC490401FC0104 +3B1E:002002227BFE480049FC490449FC790449FC488049FE4A227D52490201FA0006 +3B1F:4044402440287EFEAA922AD62ABA4A924AFE9200127C2244227C4244947C0844 +3B20:02100210F3D0945E98A493D49054F05493C89048905497E2F00092A402520452 +3B21:000001FC78204BFE4A2249AC782049AC485048C84B2678F8480800D000200010 +3B22:010400887BFE482049FC48207BFE4854499248904BFE789048D4038A009601A2 +3B23:02840284FAA496C4929E97C49004F454928C97C4910497C4F10491C40E140008 +3B24:000003FE7A024BFE4A024BFE79084A524B9C49084A527BDE480002A402520452 +3B25:3FF820083FF820083FF811101FF041047FFC0200FFFE09203558DFF605400920 +3B26:008803FE78A8489049FE4B2079FC492049FC492049FE79004BFC00880070038E +3B27:3FF820083FF820083FF811101FF00100FFFE0A203458CF8601201FF009501320 +3B28:01100110F11097BC911091109FFEF2A892A896EC9AAA92AAF2A895A804480898 +3B29:008803DE788849DC48884BDE48887BFC480449FC48044BFC78404AA4028A047A +3B2A:0FE008200FE008200FE07C7C44447C7C4544FFFE88020FF010101FE00020FFFE +3B2B:0440FFFE044017D2F01C17D03452D7CE0000444482221FF010101FF010101FF0 +3B2C:07BC04A4F7BC94A497BC94A497BCF12093FE922097FC9A20F3FC922003FE0200 +3B2D:001E03E0792248944BFE4A527BFE48044BC44A7E4BC47A544BCC028402D40348 +3B2E:3FF820083FF820083FF84450FE4844FE7D9010FCFE9092FCFE901090FEFE2880 +3B2F:00803FFE0800EFF8A000AFF8A808EFF8A220BD5CB7F4BC94F5DC1C9617F62CA2 +3B30:0100010001003FF8210821083FF8210821083FF801000280044008203018C006 +3B31:28503E7C4890FEFE14281528264A44861FF0101010101FF0101010101FF01010 +3B32:00887C50100011FC7C50548855047DFC555455547D5493FE600020005FFE8000 +3B33:00803C80248025FC25203E202420242027FE3C20242024202420442054208820 +3B34:00907890489048904BFC78904890489048907BFE480048904888490849049A04 +3B35:00403C20242025FE24003C882504260224883C88245024502420445054888B06 +3B36:00207920492049FC49207A2048204BFE4800780049FC49044904490449FC9904 +3B37:00007BFE4A224A224A227BFE4A224A624A727AAA4B224A224A224A024BFE9A02 +3B38:00883C8825FE248824883C502450249425943E98249024B224D24492548E8880 +3B39:00803C8024F8250826103DFC2424242425FE3C24242425FC2424442054A08840 +3B3A:0020792448A849FC48407BFE49084A244C2279FC492449244934492848209820 +3B3B:008878884BFE48A848107BFE4880488048FC780048A848A848A848AA492A9A06 +3B3C:104010407EFE108021FC3E8424FC6484BCFC2440247C3CC42528241024682D86 +3B3D:00003CF8248824F824003DDC255425DC24003DFE248024FC2404440454288810 +3B3E:7F7848485F4C64805F784A4851307F4C00001FF010101FF010101FF010101070 +3B3F:010878884BC848104BDE7A644BD448144BD47854489448E84B8848944A949922 +3B40:0110791049DE4AA84C4478004BFC48204928792849284AB44C6248204BFE9800 +3B41:1000100013F81088FC90109030A038BC54845484910411041104120412281410 +3B42:1020102010201020FC2010A830A438A455225122922210201020102010A01040 +3B43:1020102010401040FC84108431083BF855105410902010401088110413FE1102 +3B44:100013F010901090FC90109030903BF05490549090901092108A108A10861082 +3B45:1000100013FC1000FC001000300039F85400540090001000100017FE10001000 +3B46:00003FE00420047C08043014C10801007FFC01003FF8054009203118C1060100 +3B47:1040104010801088FD0413FE30023890549054909090109011121112120E1400 +3B48:10401040104013F8FC4810483048384857FE544090A010A01110111012081406 +3B49:08200820FFFE08200920010001007FFC03800540092011102108C10601000100 +3B4A:1010111011101110FD1011FE31003900550055F8910811081108120812081408 +3B4B:10201020102013FEFC201020302039FC54205420902013FE1020102010201020 +3B4C:1020102011201120FDFC112032203820542053FE902010201020102010201020 +3B4D:40802080089C17E0E08020842084207C01000100FFFE054009203118C1060100 +3B4E:100013FC12041204FE94125432243A2456545254929413041204120412141208 +3B4F:10201020102011FEFC20102030FC3820542055FE90221022102A102410201020 +3B50:020002007FFC044008203018C10601007FFC01003FF8054009203118C1060100 +3B51:10201020102011FCFC20102030203BFE547054A890A811241124122210201020 +3B52:100011F811081108FD08110831F83900550055FC910411041104110411FC1104 +3B53:1020102010401088FD0413FE30023888548853FE908810881108110812081408 +3B54:1008103C13E01020FD2410A430A8382057FE5420902010201020102010A01040 +3B55:10201020102011FCFC20102030203BFE5420544090401088110413FE11021000 +3B56:10A010A810A41124FD20133E3BE03520512051209120112011141114110C1104 +3B57:010001007FFC0380054009203118C10600003FF82448244824482448FFFE0000 +3B58:1020102010501088FD04120231FC3800540055FC910411041104110411FC1104 +3B59:10201020102011FCFC20102033FE3808540855FE900810881048100810281010 +3B5A:1080108010FE1100FE00101C31E0392055225524912811101110114811841102 +3B5B:1004101E11E01100FD0611783150395055525554914811481144125412621440 +3B5C:1028102410241020FBFE102031243924552453A8912811101212122A14461082 +3B5D:082008207EFC08201C702AA8C826020002001FE00420042008221022201E4000 +3B5E:1020102011241122FA2A101030603B805440504093FC10441084108411141208 +3B5F:044004403FF8044004400440FFFE08203118C1061FF0030005C0193061080100 +3B60:10201120112011FCFD20122030203BFE5490549090901090111211121212140E +3B61:10201020104011FCFD0411043194395455245524915411941104110411FC1104 +3B62:200427C422842294FA942294229477D46A94A294A29422942284248424942888 +3B63:1100108010BC1204FE0412F432943A945694529492F412941204120412141208 +3B64:1020104011FC1104FD4411243124390C550055FE9002100213FA100210141008 +3B65:1040104010F81088FD1013FC3104392455245124912411241050108811041202 +3B66:1040102013FE1202FC00103833C038405440507C93C0104010421042103E1000 +3B67:020004001FF011101090FFFE101012102150402001007FFC05401930E10E0100 +3B68:200027DE20922492FC94249427D870946992A192A292229A2494289022902110 +3B69:1004101E11E01022FD1210943080380855FE5408908810481048100810281010 +3B6A:1028102413FE1020FC2011FC3124392455FC5524912411FC112411241124110C +3B6B:1020102010A810A8FCA8117432223820542055FC902010201020102013FE1000 +3B6C:100013FE10401080FD441224306838B055305228906810A41122122010A01040 +3B6D:200223E22222222AFA2A23EA210A710A6BEAA12AA12A212A2222222224AA2844 +3B6E:2124212422482248F9242124200077FE6880A1FCA10422882450202020C02700 +3B6F:100013FE11201128FD2811E831283928552855E89128112A113A13EA10261020 +3B70:088028882EF028842E84F17C0100FFFE01003FF821082388255809201110610C +3B71:100011FE1100117CFD541154317C39545554557C911011101110110011FE1000 +3B72:1000105010481084FD24102030503888550652F8908810881088108810F81088 +3B73:1020102211FA1024FC2413FE3010382055FC5488911012FE1410101010501020 +3B74:108012FC12A412A4FEA8129032A838C65420542091FC10201020102013FE1000 +3B75:1100110011FC1204FA0415F43154395455F45154915411F41114100410281010 +3B76:1104110417FE1104FD44102037FE3880548054FC908410841104110412141408 +3B77:11FC1124112411FCFD24112431FC3840544053FE904210821082110212141408 +3B78:1080108010F81108FA1011FC31243924552451FC90501058109410921112120E +3B79:10101388108810FEFC90139032243A24563853889090109010A410BE12821100 +3B7A:1020102013FE1050FC881124322239FC552455FC912411FC10221022101E1000 +3B7B:1020112410A410A8FC2013FE32023A0256FA528A928A128A12FA1202120A1204 +3B7C:1020102213B410A8FCA8112432A2384055FC5504910411FC1104110411FC1104 +3B7D:1040102013FE1200FE1C12F032903A9056FE52909290129012AA12CA14A61812 +3B7E:100013FE12021202FBFE121032923A92569252FE921012921292149214FE1802 +3B7F:200023FC220423FCFA0423FC200071806E3EA422A422242225A2262A24242020 +3B80:100011FC10081010FA2212AA32723A22567252AA932612A21242120213FE1002 +3B81:11841068103010C8FB24102033FE384054FC518492FC108410FC108410941088 +3B82:1FF010101FF010101FF010101FF01010FFFE08203118C1061FF0054009201110 +3B83:101C11E010201020FBFE10A831243A42544053FE9088110810D0103010481184 +3B84:1040102013FE1080FC8011FE31423A2255FA508290F2109211121152122A1004 +3B85:010001007FFC054009203118C90608801FFC30805FF890801FF810801FFC1000 +3B86:1020102010501088FD04128A305039FC542054F8902013FE1020102010201020 +3B87:100013FC10401040FBFE10A031103A0854465040904812641252145211401080 +3B88:1020102013FE1050FC88110432FA3800540053FE902011241122122210A01040 +3B89:211021102110227CFA10269236546A1062FEA210A22822282228224422442282 +3B8A:200827C820482288F93E208827D8715C692CA12AA14821082108210825082208 +3B8B:2100211E27F22112FA1423D4225876546BD2A252A25223DA22542250225022D0 +3B8C:100017FE10401080FBFC129432943AF45694529492F412941294129413FC1204 +3B8D:0820FFFE00003E0822483E4822483E482208261801007FFC05401930E10E0100 +3B8E:100013FE10101020FC6810A433223820540051FC915411541154115417FE1000 +3B8F:2040204027FC20E0F95022482C4673F86800A000A7FC20402248244429422080 +3B90:1020102010A410A2FD2A10103860358056FC508490FC108410FC108410FC1084 +3B91:1008103C11E01020FC2013FE302038A0552C5524912411AC1124112411FC1104 +3B92:100013FE10501050FDFC11543154395455FC5420902011FC1020102013FE1000 +3B93:1100117E11101110FD90115E3B22352A512651429152110C11041104117E1100 +3B94:1008103C11E01020FBFE102031FC392455FC512491FC102011FC102013FE1000 +3B95:100013FE10201040FDFC1154315439545554552C902013FE1050108811041202 +3B96:1088108813FE1088FCF8102031FC3924552455FC902013FE1020102010201020 +3B97:00207E20145008887F442A2249F888082810102001007FFC05401930E10E0100 +3B98:2008278820882290F91E211427E471546B14A314A51425082908211425242242 +3B99:100013DE12521252FBDE100031FC380057FE5080910011FC1004100410281010 +3B9A:010001F801003FF8210822C82D28228824483FF801007FFC05401930E10E0100 +3B9B:100011FC11041104FDFC1104310439FC540053FE90201120113C112012A0147E +3B9C:100013FE12001224FAA412A432E43A3E57E452A492A412A4132E120013FE1000 +3B9D:2000229E22522252F5522112229272526C32A3D2A25A22542250225023D02250 +3B9E:1020112010BE1042FC841310311039285544548290FC10841084108410FC1084 +3B9F:2008200827E82108F93E220823D8765C6A6CA26AA248224823C8224820082008 +3BA0:1088108813FE1088FC0013FE3A023424502053FE907010A810A8112412221020 +3BA1:080008FC2A802CF8488808F8148022FC40000100FFFE054009203118C1060100 +3BA2:108010BC10841108FDFE13203520397C5590511091FE11101128112811441182 +3BA3:00007DFC44207D2045FE7C5048525492650E0100FFFE054009203118C1060100 +3BA4:020001007FFC49241290244818306FEC082008200FE001007FFC05401930E10E +3BA5:10401048108411FEFC2013FE3888350453FE5524912411FC1124112411FC1104 +3BA6:1020102013FE1020FBFE1242348C39F05420504493FE10221128122414A41040 +3BA7:1040108011FC1104FD0411FC310039FE550055FE900212AA12AA140210141008 +3BA8:100011FC112411FCFD2411FC38883544524250F8918812501020105011881606 +3BA9:1020104011FC1104FDFC110431FC390455FC5440902010A4128A128A14781000 +3BAA:100013B811281128FD3A11AA37263A405420502093FE107010A8112412221020 +3BAB:1040102013FE1202FC2411FC382035FC502053FE902011FC1104110411FC1104 +3BAC:1090108811041242FC8811FC3804340053DE50429252114A12521042114A1084 +3BAD:100013FC100810D0FC2013FE328A3A5256FA5222922213FE1222122213FE1202 +3BAE:108013DE108A11CAFC8A13D230A6380854F0542091FC102013FE102010A01040 +3BAF:200027FE240225FAFC4224C2252A746A6CB2A52AA46A24AA2522244227FE2402 +3BB0:1020104011FC1104FD5411243154390455FC5400911211D4111811521192110E +3BB1:1088108813FE1088FC2010A038FC3520502053FE90501050109010921112120E +3BB2:1080108011FC1244FD5411F438843528529051FC9244155411F4108411281210 +3BB3:2044272425282500FD7C2710251075106DFEA710A5102528252825442B442082 +3BB4:10A0112C11241124FDAC1124312439FC542055FC908810501020105010881306 +3BB5:22202120213E27A0FA40223C23A472B46AACA2A4A2FE22A424A424A429A4304C +3BB6:2440225E22922012F7D2211E255275526D52A7DEA152211222122222242A2844 +3BB7:1050104813FC10A0FD22121E311039E0550454FC900011FC110411FC110411FC +3BB8:1044102412281100FD7C101030103B7E551051109128112411441280147E1000 +3BB9:2008200827C82210FA1E24A427D471146914A7D4A114210821C82E1424142022 +3BBA:010001007FFC03800540092037D8C10600007BBC4AA44AA44AA44AA47BBC4AA4 +3BBB:100011FC10A41088FC50102030D83B26542051FC9124112411FC102213FE1002 +3BBC:1040102013FC1204FA0413FC32003BDC5644535492CC124412CC1554144418CC +3BBD:2100223C27A424A4F6A425A424C27F806CBCA4A4A6A425A424942488249429A2 +3BBE:10007E7C42447E7C42447E7C484444445A94610801007FFC05401930E10E0100 +3BBF:100011FC112411FCFD2411FC30A838A857FE54A890A811FC102013FE10201020 +3BC0:22102110211027BEFA40220023BE728A6A88A2A8A2AE22A824A825A8285E3080 +3BC1:20202710257C2500FD442628250075FE6D00A500A57C264424442444247C2444 +3BC2:22A822A827FC22A8FAAA24E6280077FC6C44A040A3F822482248224822582040 +3BC3:1020102013FE1070FCAC13223850348851245222912410A81124122210A01040 +3BC4:08207EFC08701CA82B26C820087C3F8020003FFC20002FF828884FF8480287FE +3BC5:2040202027FE2420FC4025FC252475FC6D44A5FCA45024902BFE281030102010 +3BC6:1040102013FC1000FD08109033FE3A2056A052FC9320122012FC1420142019FE +3BC7:1050105013DE1050FDDC105033DE385054505420902011FC1020102013FE1000 +3BC8:2010201024FE2210FA1020FE209276926AFEA210A238225422922210251028FE +3BC9:1020103E102011FEFD20113C31E2391E550455789192115412FE121014501020 +3BCA:200027FC20402278F2402FFE210071FC6A00A3FCA00425542554280420282010 +3BCB:40004CFE7010422042FC3E84108410FCFE8430FC3884548452FC904810841102 +3BCC:2000227E21102130F84A209A262C724C6A9AA22AA24A22882228251028FE2000 +3BCD:20902290229E22A2FAD423A8209470A46FFEA284A2A422942294228424942888 +3BCE:22082108210827C8F83E27882018779C682CA7AAA4C824882488278824882008 +3BCF:08007F7808483E4800863E782A483E304048808401007FFC05401930E10E0100 +3BD0:00407BFC488049F852204DFC488868F8508840F8408801007FFC05401930E10E +3BD1:20002F3E2120213CF1202F3C282078FE6850AF52A1542148214821442A622440 +3BD2:200E27F020442224F90823FC220473FC6A04A3FCA20423FC2090211022122C0E +3BD3:204020A0211826E6F80023F8220873F86800A7BCA08424A4229424A422942108 +3BD4:01F03E0003F03E0003FA7E0201FE0C20703C1DE2F0221C1E0100FFFE0920711C +3BD5:22402242225C27F0FA5023D0225E73D46A54A254A7F420142294246428242044 +3BD6:1020102013FE1020FDFC1154315439FC540053FE9040102412A2128A14881078 +3BD7:200027BC24A427BCFCA427BC244474446DF4A444A4E42554264C244424542408 +3BD8:2108210827C82108F91E2392202473806808A7C8A10821082594295425242242 +3BD9:2208210827C82210F49E2FD4206477946C94A794A49427882488249424A425C2 +3BDA:1210121013DE1228FD4410A031103A0855F65000900013F81208120813F81208 +3BDB:1020102013FE1020FDFC100033FE3A52545051DC910411DC1050105013FE1000 +3BDC:1088108813FE1088FC2013FE3088388855545222902017FE1020102010201020 +3BDD:2010279024BC24A4F4C427A8211071286946A5C0A53C2524252425A42E3C2024 +3BDE:2080209E21122152FA5E2780209E71126A52A7DEA052201E2552255224122016 +3BDF:10101010FEFE3838545492823FF000101FF00010FFFE111009A005401930E30E +3BE0:102013FE104810F0FC2013FE3242389055F85028912011FC122017FE10201020 +3BE1:10401040FEFC3884550492F42894449492F410845494388854829282507E2000 +3BE2:100013DE125213DEFE10125231CE3800548853FE9088108813FE108811041202 +3BE3:21082FFE21082090F10823FC2C8A71286A50A040A7FC20E0215022482C462040 +3BE4:101010101010FEFE1010545454545454BABA1010383854549292101010101010 +3BE5:10101010FEFE10107C7C54547C7C54547C7C1010383854549292101010101010 +3BE6:211027FC211021F0F91021F0211077FC6910A248A44623F820E0215826442040 +3BE7:2100213C211427D4F91421242FCC7100693CA524A5E4253C2724250024FE2800 +3BE8:100013FE10501050FBFE125232523BFE552450A893FE107010A8112416221020 +3BE9:00107E1022FE1C10227C7714557C2250557E08127F121C162A28492888440882 +3BEA:100011FC102013FEFA2211AC302039AC545050C8932610F8100810D010201010 +3BEB:1040107C104013FEFA42127833C43A3C560053FE924013A4125815B4145219B0 +3BEC:1010FEFE5454929200407BF8084817FE20487BF808400BF8504027FC584087FE +3BED:1040107C104013FEFA4213F832443AFC56A852F892A812F8122015FC1444198C +3BEE:100011FC11541154FDFC108031FE3A4255F25152915211F2104A13FA100A1004 +3BEF:108011FC12881070FBAE10F8312039FC542051FC910411FC110411FC10881104 +3BF0:11FC1154115411FCFC2013FE302039FC550455FC910411FC110411FC110417FE +3BF1:01007FFC11101FF00100FFFE90021FF821007FFC11101FF00100FFFE0920711C +3BF2:2110211027BC2110FBB82554291270006BF8A000A7FC20402248244429422080 +3BF3:2288228827E8FA90241E27E474546854AF54A554255427482548205422942122 +3BF4:1088108813FE1088FC2013FE3202388855245450908811FC128A108810F81088 +3BF5:211027FE211023F8F84027FC204073F86A48A3F8A24823F8204027FC20402FFE +3BF6:1020108812521326FE52128A32223BFE54885144927A10881150102010D81706 +3BF7:212821AA216C2228FAFE264436286AFE6210A27CA21022FE2210222822442282 +3BF8:204023F8204827FEF84823F8204077FE6800A2A4A45223F822A822A82FFE2000 +3BF9:20042FE422842FE4FABE2AA42FE470046FD4A00CAFEC2104254425242924230C +3BFA:00407E40487E7EA043107EFE48AA48AA7EFE000001007FFC05401930E10E0100 +3BFB:01007FFC11101FF00100FFFE82120D2032C00DA032900D883100FFFE0920711C +3BFC:108813FE10881020FDFC102033FE3840548855FC900011FC1154115417FE1000 +3BFD:102017FE140213FCFE2413FC32003AFC568452FC928412FC128414FC14481884 +3BFE:202824FE222822FEF8AA20FE2EAA72FE6A00A27CA244227C2244227C250028FE +3BFF:1124124811241000FBFC129432643A9457FC524893681248136A124A12461362 +3C00:10501190109E13EAFC8A11D2328A38A454505088932610A8107010A811241060 +3C01:200027FC2100FBF82508210871F86800AFBEA208279E24922CB22492279E2492 +3C02:202023FE2202241CFBE0212420A873FE6924A202A5FC212421FC212421FC2104 +3C03:220624382F882892FFA428BC2F8872146FBEAA8AAA882AAC2AAA2BCA22282210 +3C04:20142792249E24F0F794248A249677E26C94A492A79E20702514248A28962062 +3C05:2020201024FE2244FA2820FE209276FE6A92A2BAA2AA22BA2286250028FE2000 +3C06:01007FFC11101FF00100FFFE82823EF802807EFC028001007FFC05401930E10E +3C07:2114211227D22110F1102FFE229076D26A92A6D2A29426D4228A22CA2F162022 +3C08:1010FEFE54549292004027FC104013F8024873F8124813F8104017FC284047FE +3C09:201020102F7E2410F43C29102F7E72246A4AAF30A210227E23382E5424922010 +3C0A:2108210827AA212CF1082FD4201274A26948A108A7AA212C210821942E242442 +3C0B:2100213E250825D0F53E25222FE2703E6922A57EA56225A228BE210022142C22 +3C0C:11FC102013FE1222FDAC102031AC389055FE532095FC112011FC112011FE1100 +3C0D:08407F7C1440FF7C22043E7C22403E7C2242263E01007FFC05401930E10E0100 +3C0E:1020122213FE1090FDFE131035FE391055FE551091FE110013DE125212721206 +3C0F:110811EE12941020FBFE100030F8388854F8500093FE120212FA128A12FA1206 +3C10:2008273E2590255EFD64265E250075DE6D52A55EA552265E2452245624A0251E +3C11:20202294228A247AF800228A31446A286AAAA186A0402FFE215022482C462040 +3C12:22A0244C24A4260CFCA4264C34A46FFE6802A3F0A020204027FC204021402080 +3C13:27D0251027DE2450F7E8250427C473F86A08A3F8A20823F8220823F821102208 +3C14:224822E8230826EAFA1C22E832086AE865B4A8E2A00023F8211020E023182C06 +3C15:211027FC204023F8F84027FC200073D46912A7FEA3502534238C208A22962102 +3C16:13D0129013DE1268FBC4128433F8390855F8510891F8110811F810901112160E +3C17:201427FE249024D4FC9427FA35AA6A9661A2A3F8A20823F82040227C254028FE +3C18:208020F8210821F0F81027FE255473BC6FCAA13EA388256A208827FE20882108 +3C19:251825142F90253EF72822682FBE7AA86FA8A23EAFA822283FE8253E28A03060 +3C1A:220C210A27C8229EF55426F4245E77D46914A7DEA554255425D4245E25502490 +3C1B:21102FFE255424E4F8A82AAA2EEE74A46AAAAEEEA2422FFE215022482C462040 +3C1C:2200221E2FC42208F79E24922792749E6F92A49EA79224922FDE2500248C2892 +3C1D:00403E402240227C2284228823203E2020202050205022502C88308821040202 +3C1E:082008200820087E49424984491049104910491049284F287948004400840102 +3C1F:202020207F20807E00427E8400100010FC100410042805280528034401440082 +3C20:102008200820FF7E004200843C10241024102410242825284648444480840102 +3C21:082008201420127E214240849210121012101210122812282228224442448282 +3C22:00207E202420247E244224842410FF1024102410242824282448244444848502 +3C23:142014201420547E55425E845410541054105410542854285D487644C4840102 +3C24:00200020FFA0027E02427A844A104A104A104A107A284A28024802440A840502 +3C25:122052205220527E5242FF845210521052105E104028402840487FC400840102 +3C26:0820082008207F7E084208840810FF901010101024284228FF48414400840102 +3C27:104010402040287C4484FE88432000207C2044504450445044887C8845040202 +3C28:002000207E20427E4242428442107E1042100010242822284248424480840102 +3C29:0820082008207F7E49424984491049107F10481008280A280F48F14440840102 +3C2A:0820082008207F7E08420884FF100010081008107F28082808480F44F0844102 +3C2B:0820282028203E7E4842088408107F1014101410142814282548264444848102 +3C2C:2020202020207F7E41428184791049104910791049284928792801440A440482 +3C2D:10401040FE40287C448482887D200020FE20205040507C500488048829041202 +3C2E:00207F204020407E5E42408440107F10501051105A2854285228914498441082 +3C2F:0020FF200020007E7E424284421042107E1000104228222824280F44F0444082 +3C30:082008207F20087E08422A842A102A105D108890082814281428224442448082 +3C31:072078200820087E7F4208847F10491049107F10492849287F28084408440882 +3C32:0420052004A0FFBE042204447550559055107310029032A8C5A808C410440082 +3C33:0040FE402840287C2884EE88832082208220EE50285028502E88F08841040202 +3C34:102008207F20007E22421484FF10001000103E102228222822483E4422840102 +3C35:1020082000207F7E004222842210551088900810FF2808280848084408840902 +3C36:222022203A204B3E4AA2AA4412502890479080103F102128212821443F442182 +3C37:00200020FFA0227E22423A844A104B904A10AA101228122822A8234442448082 +3C38:082008201420227E4142BE84081008107F10491049287F280848144422844102 +3C39:0110019001507F9E411241225D08414841485D48558855945D54415442D48462 +3C3A:002077205120513E512277444050409077104110491075284228424445444982 +3C3B:08200820FF20083E08227E4400507E90421042107E10422824280F44F0444082 +3C3C:0020FF208820887EFE428884AA10AA10DD10881094289228A128C044FF440082 +3C3D:0020FFA08020BF7EA142BF84A110BF108810FF909228B2288C289244A144FF82 +3C3E:082010207E20427E7E4242847E1010100810FF1020283E28224842444A848502 +3C3F:0E40F0402240927C448420884520F82010202450FE501050FE88288845048202 +3C40:202020207F20917E55427D8421104A10A4107F10912855287D2821444A448482 +3C41:08202A202A203E7E494249847F1000103E1000107F2808282A48494428841102 +3C42:041002103FD0221E2F9222A43FC822882F88220832482A9427144A9452548622 +3C43:082014202220497EBEC204840810FF9014107F105528632841487F4441847F02 +3C44:00207F2049206B7E5D4249847F1008107F1008100F28F0280128554454444082 +3C45:0820FFA008207F7E0042FF8480907F1000107F1041287F28412822440FC4F082 +3C46:08200F2008207F7E49424C847910471040105F1040285F2851285F448A443F82 +3C47:08207F202A202A3E5D220844FF5000907F1041105D1055285D2841447F444182 +3C48:22202220F7A0227E7742AA84225000107F100010FFA80828492888C428441082 +3C49:142055203620147EFF42228414107F1008107F100828FF281C282A4449440882 +3C4A:FF2010207E20427E7E424284FF1091104A10A5101C2820287E28A2441C44E282 +3C4B:3F9004107FD0445EB5920424358812083FC86408BF8824143F9424143FD42022 +3C4C:7F8821083F0821083F1E21D2FF240100FFC852887388528873945AD4F7A410C2 +3C4D:4848444840485E4EA0AAAEB2C0C44E4440448E84AAA4EAEA0A0AAEAAAAAA0010 +3C4E:7F2055207F202A7E49422A8461103E104410FF1049287F2849287F440044AA82 +3C4F:00001FF00000000000007FFC01000100110011F81100110011001100FFFE0000 +3C50:000000103F0800080000FFFE00000400040027002400240024002780F8004000 +3C51:0100010011F811001100FFFE020004000FF0101068200440028003001C00E000 +3C52:0100010011F811001100FFFE0000FFFE00101F90109010901F90001000500020 +3C53:08200820085048504E8849244A12481049FC4804480848884E50F02000100010 +3C54:044004441748147014421742783E020007F0081034200240008003000C007000 +3C55:100011FC100410FC50045DFC500053FE5222502051FC5D247124C13401280020 +3C56:1040102013FE100050885C88515452225000502053FE5C207020C02000200020 +3C57:1020104011FC110451FC5D0451FC510451FC502850245DFE7050C08801040202 +3C58:3FFE29142F1229102F7E20102F2829282F2829442F4429824B40447C84401FFE +3C59:000003FEFC40204020803C80450045FC64049404080408041004200440288010 +3C5A:000000FCFC84208420843CFC44844484648494FC088408841104210442148408 +3C5B:00000000FDFE202020203C7C44444484648495480A2808101010202040408080 +3C5C:00000020FC20202020203C204520453C652095200920092012A02260443E8800 +3C5D:00100010FF902210227E3A124A124B924A12AA121212121222922322422A8044 +3C5E:00800040FC40200023FC3C0044084508650894900890089010A0202047FE8000 +3C5F:00100010FC1021FE21123D14451045FC65449544092809281110222842448482 +3C60:00200020FC20202023FE3C204420442065FC9504090409041104210441FC8104 +3C61:00200120FD2021FC21203E20442047FE6490949008900890111221124212840E +3C62:00400020FDFC210421043DFC4504450465FC9520092209141108214441828100 +3C63:0004001EFDE0202221123C944480442065FE9444088409C81030202840C48302 +3C64:00800086F898209023D03890489E499469D49AB40A94149410942094409480A4 +3C65:00200020F9FC202020203BFE488849446A4298F8098812501020205041888606 +3C66:00200020FDFC205020883D0447FE440865E89528092809E81128200840288010 +3C67:00400020FBFE22022504390049DE4A526A529B520C9A1094111021124212840E +3C68:00400020FBFE2202240438004BFE482068209920093C112012A02260443E8800 +3C69:00200020F9FC202020203BFE4802489468509910089013FE1028204440828302 +3C6A:000001FCFD0421FC21103DFE4510454A6586940009FC090411FC210441FC8104 +3C6B:0020FC2023FE202021FC3D2445AC4574652495FC0820087010A8212442228020 +3C6C:000003F8FA48224823F83A484A484BF868009FFE0A4012441228229043088206 +3C6D:00800338FA28222823A83A464A004A7C6BA49A240A2813A81610222842448282 +3C6E:00200020FDFC212421FC3C2047FE440065FC9504092409241124205040888304 +3C6F:00200124FD24212421FC3C0047FE440065FC9504090409FC1088205043FE8000 +3C70:0040FC2023FE224220203DFC4488445067FE9420082009FC1020202040208020 +3C71:00200040FBFC222422243BFC4A244A446BFC984008A810B4113C21224222841E +3C72:02080108F910200027FC380049104A086C049BF80AA812A812A822A84FFE8000 +3C73:04407FFC04401FF010101FF010101FF00400FFFE10102FE8C2060FE004403F80 +3C74:002003FEF82021FC20203BFE480049FC690499FC090411FC110421FC40888104 +3C75:002001FCFC20208823FE3C8845FC450465FC950409FC090411FC208841048202 +3C76:00820082FBF4208820803BE248024BE46A289A200BE012221142207447888210 +3C77:00A00090FDFE232021FC3D2045FC452065FE950008200BFE107020A843268020 +3C78:001003C8FA7E224022623BD44A004A3E6BC89A480E7E1248124823C842488008 +3C79:000003FEFA2222CC22443BEE4A444AEE6B549A440A101290129E249044908BFE +3C7A:0040007CF84023FC22443BF04A444AFC6AA89AF80AA812F8120025FC45548BFE +3C7B:00401FFEE40047FC400077FC540497FC51102EAE2BFA2E4A4AEE4E4A8BFA1650 +3C7C:00003E78224822482248228622003EFC20442044202822282C10302820440182 +3C7D:0800087808487F4849480886080014FC14441444142825282610442880440182 +3C7E:100008780848FF480848108622007CFC094412442428C82814102228C0440182 +3C7F:10001078FE48104810487C86000000FCFE4482448228BA28821082288A448582 +3C80:00007F78404840485E48408640007EFC504451445A2854285210512898441182 +3C81:20001078FE48824828484486820000FC7C441044102810281E10F02840440182 +3C82:10009278524854481048FE86820082FCBA44AA44AA28AA28BA1082288A448582 +3C83:100010781E4810487E4842867E0042FC7E44004420283E28201022282C443182 +3C84:10001078FE4810487C480086FE0082FC00447C4410287C2810101E28F0444182 +3C85:20001078FE48824810487C8610007CFC1044FE4410287C28441044287C444582 +3C86:08007F7808483E4800863E782A483E30414882840C603118CFE6004006800180 +3C87:08007F7808483E4800863E782A483E3048489FF4282007C01830E18E0C400300 +3C88:08007F7808483E4800863E782A483E30404880867FF8080810303FF8D0081FF8 +3C89:1000FE7810487C480048FE8682007CFC2044CE44AA28EE28AA10EE2828444982 +3C8A:10001F381028FFA880A87F462A00557CA2247F24A2A83E2822103E2822443E82 +3C8B:080008001FE020204040BFF8200820083FF8000020843E9820E020842684387C +3C8C:08001DF87048104810501C5C7084108410841D04F1281212100210020FFE0000 +3C8D:1010103811C0FE40107811C0FC40447C47C0284428441044183C240043FE8000 +3C8E:04080E1C70E0102010201C3C70E0102010201E3CF0E0102214221822101E0000 +3C8F:0408243C25E0242024203E3C21E020203C20243E27E02420242244224422841E +3C90:08201C207050105010881D44722210F810081C10F0101022102210020FFE0000 +3C91:08201C207020102411A81CB070B0112811281D24F22410A0104010020FFE0000 +3C92:2008201C40E07E208220023C7AE04A204A204A3C7AE04A2202220222141E0800 +3C93:08281C24702411FE11201D2871A8115011141D34F14C1104120010020FFE0000 +3C94:1004080E7F7000102210141CFF7008100810081E7F700810081208120812080E +3C95:04081E1CE0E022209220543C40E00420FF20043C44E0242224220422141E0800 +3C96:0804490E29702A1008107F1C417041107F10411E41707F10411241124512420E +3C97:04081E1CE0E0022092204C3C00E0FE200420083C0EE0F82248220822281E1000 +3C98:00087E1C42E042207E20423C42E07E204220423C7EE0002224222222411E8100 +3C99:08401C2071FE104010881DFC700410A810A81CA8F12A1226100010020FFE0000 +3C9A:1020082040A824A4092A723010C0170000F03F0001F03F0001F87F02010200FE +3C9B:20003E7C48440844FF441444227C400000F03F0001F03F0001F87F02010200FE +3C9C:1008521C54E090202820443C82E010201020523C54E0902228222422421E8000 +3C9D:08501C4870FE119012901CFE7090109010FE1C90F09010FE108010020FFE0000 +3C9E:1004080E00707F100010221C227055108890081EFF700810081208120812080E +3C9F:2204220E7F7022102A10081C3E702A102A102A1EFF700810141212122212400E +3CA0:082008207E7E08C4FF281C102A2848C600F03F0001F03F0001F87F02010200FE +3CA1:0804080E7F701C102A10491C00707E100010FF1E08704A10491289122812100E +3CA2:1004080E7E70421042107E1C427040107F10551E55707F10D51255125512430E +3CA3:5008961C92E09220D620923C92E0FE201020FE3C02E0642218222422C21E0000 +3CA4:1004080E7F7000103E10221CFF7022103E10189E35705210911214921812100E +3CA5:1004080E7F7048105E104A1C7F704A105E10481E5E705210521252125E12920E +3CA6:102010201050FE8811067C1844E07C2044387CE01020FE3C11E010221022101E +3CA7:10003BF0E150211020A03840E1B0264E21F03950E1F0204823FA200A20021FFE +3CA8:2408241CFEE024200020FE3C24E03C2024203C3C24E02E22F4220422041E0400 +3CA9:10003BF8E20823F822083BF8E00027BC20843CA4E29424A42296210A20021FFE +3CAA:0A04740E157052102210211C5D7080107E10421E42707E10421224120F12F00E +3CAB:2808AA1C6CE02820FE20443C28E0FE2010207C3C10E0FE2210222822441E8200 +3CAC:2808241C7EE0C82048207E3C48E048207E20483C48E07E224022AA22AA1E0000 +3CAD:0804290E29704A101410221C4170001022102A9EB7706210221252124512888E +3CAE:12103A10E3DE252820843840E0A0211022E83C04E1F02110211221F220021FFE +3CAF:00047A0E52707B904A107B1C54F0789000107F1E5570551055125792FC12000E +3CB0:0804FF0E91704A10A5101C1C00707F105510FF9E00707F10081208122812100E +3CB1:11243A48E12423FC22943A64E29423FC22483B68E248236A2246236220021FFE +3CB2:7F04490E7F704910FF90AA9CFFF0AA90FF90001EFFF0A2903E1222122792F80E +3CB3:08201C20F120912091FC9120FE20902093FE902090508A50A688D28809040202 +3CB4:20003FFC40009FF000007FF0041004107FD0445044507FD2444A040A04060402 +3CB5:20003FFC40009FF000007FF0249015107FD040507FD040527FCA404A41464082 +3CB6:20003FFC40009FF000007FF0041007F004107FD055504A5264CA4A4A55467FC2 +3CB7:20003FFC40009FF000007FF02A903B9000103F9024903F92248AFFEA04060402 +3CB8:0000200013FC1008801040204840088010801100E10022022202220221FE0000 +3CB9:000021F011101110811041104910091011101110E210221222122412240E0800 +3CBA:00402040104010408040404E48700FC010401040E040204220422042203E0000 +3CBB:0840084008401044176831703160515091501248124814441842104011401080 +3CBC:0000200812081208820841104910091010A010A0E040204020A0211022080C06 +3CBD:000023FC10841084808442844A840A8414841084E08420842104210422280410 +3CBE:020001007FFE40028104010001003D8405880950092011102108C10605000200 +3CBF:00402020102013FE820042004A000A0012001200E20022002200240024000800 +3CC0:009020881088108080BE47C04080104410442048E03020222052218A26060002 +3CC1:000023FE12001220822042204A200A2012201250E25022502488248829041202 +3CC2:0020212011201110811042484248144418822080E1102108220827FC22040000 +3CC3:0080208013F010908090411249120A4E14401040EFFE20402040204020400040 +3CC4:00802080108010FC8104410842401440104020A0E0A021102110220824040802 +3CC5:0000200017FE102080204040484008D011481244E44220402040204020400040 +3CC6:00102110109010908010421049100910101E17F0E01020102010201020100010 +3CC7:0020211011081204820444104110111010A020A0E04020A02110220824040802 +3CC8:004020401040104087FC40404950095011501150E1522252224E244020400040 +3CC9:000021FC11041104810441FC49040904110411FCE10421042204220424140808 +3CCA:00802080110011FE8210421045101110111020A0E0A0204020A0211022080406 +3CCB:0008203C13C01200820042004A000BFC12201220E2202220222022202FFE0000 +3CCC:000027FC14441444844447FC44441444144427FCE44420402040204020400040 +3CCD:00402040104017FE808040A0492009FC13241524E12421242134212820200020 +3CCE:0040204010801110820847FC40041110111027FEE11021102210221024100810 +3CCF:00402040104017FC844444444444144417FC2040E24021402080214022300C0E +3CD0:011021101110111087D041104310139015502510E910211221122112210E0100 +3CD1:0000200013F812A882A842A84AA80AA812A812A8E2A822A822A82FFE20000000 +3CD2:00402040104017FE80A041104208142610202040E0802108220427FE22020000 +3CD3:004020401040104087FE40804880090013FC1504E90421042104210421FC0104 +3CD4:000420041784108480BE4484428412A411142114E28422842484280420140008 +3CD5:0000210810881090800043FE48000800100011FCE00020002000200023FE0000 +3CD6:00802040104017FE808040804940094413481530E92021102108214421820100 +3CD7:000023F81108115080A0404041B0160E10402040E3F820402040204027FC0000 +3CD8:00802040104017FE80804110420817FC11242120E120212022222222241E0800 +3CD9:004020801108120487FE400248000BFC120413FCE20423FC2204220422140208 +3CDA:002820241024102083FE42204A240A24132412A8E22822102212242A24460882 +3CDB:00402140165C14448444475C4444144417FC2444E0A020A02110220824040802 +3CDC:009020901090111081FE43104D10093811381154E15421922110211021100110 +3CDD:01002108111C1270821046104A10121012FE2210E210221022102210227C0200 +3CDE:011021101110121082FE469256921A92129222FEE29222102210221022100210 +3CDF:044004403FF804400440FFFE082011102928C546038005400920311005000200 +3CE0:001024101210121080FE40104610122812242244E24222822200250028FE0000 +3CE1:040842082208200800FE8E084248522812282208E20822282210250028FE0000 +3CE2:0010207813C01040804047FE48A0091012081516E11021102110221022100410 +3CE3:00402040104413F48048405047FE104010802184E29824E028822082207E0000 +3CE4:011049102510251001108FFE4110511015982554E95422102210241028101010 +3CE5:000027FC1040104083F84040404017FC11102110EFFE21102110221022100410 +3CE6:0014401220102FFE00108290429252921FD22294E2942288228A249A24260842 +3CE7:00002FFE14801490849047904490149014902790E490249224D22F92208E0080 +3CE8:012421241248124881244124400017FE108021FCE10422882450202020C00700 +3CE9:0000407C20442E44046484544454544415FE2444E7443C442044208420940108 +3CEA:000027FC1020104080D041485244144410402000E3F822082208220823F80208 +3CEB:010001087D1005A009603118C50602000C00307820083C78200820083FF82008 +3CEC:0100210011FE1200840041FE482208241120113CE1202120212022A0247E0800 +3CED:000023F812081208820843F84040104017FC20E0E15022482444284220400040 +3CEE:000023FC1204120483FC42004A200A2213B212B4E2A822A8252425242AA20040 +3CEF:0080204017FC1000811040A04FFE104010402040E7FC20402040204020400040 +3CF0:0040202013FC1040809041084BFC080411101110E7FE21102110211022100410 +3CF1:0000278014BC152485244624452414BC14A424A4E6A42524243C242424000400 +3CF2:0020482024202020082085FE4420502012202450EC502450248824C825240202 +3CF3:00402040104017FC804040404BF80A08120813F8E0A020A021222122221E0400 +3CF4:004020281088129082A442C2448A118816782000E04027FC204020402FFE0000 +3CF5:003823C0104017FC80E0415052481C4613F02020E04027FC2040204021400080 +3CF6:00E84F08222829280548800847C8508811082108E1E82F08210A210A250A0206 +3CF7:0100210011FC12A484A441244A44089411081000E3FC220423FC220423FC0204 +3CF8:0108210817FE1108810840004890089211141318E510213221522112210E0100 +3CF9:0200420022FE22100F9082104610577C16902A90EA103210221022FE22000200 +3CFA:02404240227E22800F00827842085308121026FEEA102210221022102A500420 +3CFB:01102110111017FC811041104FFE100013F82208E20823F82208220823F80208 +3CFC:00500048FFFE00403E4022243E2800120E2A70C6030A7D90096011202518C206 +3CFD:002027201120113E814047404490141014102754E15221522192211025500220 +3CFE:02082108111017FC8040404043F8104010802FFEE1202120222022222422081E +3CFF:0040202013FC1040809041084BFC0844104017FCE0E0215022482C4620400040 +3D00:0108210817FE11088000403C4BC00820101013FCE0082010206021802240043E +3D01:000023F8104010408FFE41104208151613F82110E11027FC2110211022100410 +3D02:0020402020202EF804A884A844F854A814A824A8E5FE26883888208820A80090 +3D03:0040202013FE1202820243FE4220122013B222B4E2A824A82524292432A20040 +3D04:000027FE14021492848A450A4402140214F22492E49224922492249227FE0402 +3D05:010001087D1005A009603118C50602003FF82448282837D8244827C820083FF8 +3D06:000023F8100811F8800843F8400017FE14422844E3F822482248224822580040 +3D07:1088108810881088D6EA52AC52A85AA856EC52AA52AA94C81088108852A82110 +3D08:0010203813C0120083FC4220422012201FFE2000E04024442444244427FC0004 +3D09:00402090110813FC8108421044A417BE10822000E3FC20002000200027FE0000 +3D0A:044422441284101487D4411445541554155427D4E15421142204220424140808 +3D0B:0040204013F8104887FE40484BF8084012481248E2E823582248224824480848 +3D0C:02104210221022100F7E851045105510157C2944E544224422442544257C0844 +3D0D:03F04010202020440E5883F04250524815E82448E4442BF43042204021400080 +3D0E:0040204017FC10A08110420845F61000100027FCE04022482244244421400080 +3D0F:0080204017FC140481104208440413F810402040E3F820402040204027FC0000 +3D10:000040FE2F1029100950895E4F52495219522F7EE902290229022F0229140008 +3D11:0040202017FE14008504448847FE142015242524E52425FC2844288031000200 +3D12:0080204017FE1090829844944114123014002110E1102FFE2110211022100410 +3D13:000023FC1244124483FC42444A440BFC10001040E0242522250A290820F80000 +3D14:0080208011F81208841043FC480409FC100413FCE00420402124252A250A08F8 +3D15:0108210817FE1108800040384BC00840104017FCE0E021502248244428420040 +3D16:0110211017FC111081F0404043F81248124823F8E0402FFE2040204020400040 +3D17:000023FE1050105083FE42524A520BFE10001040E7FE20882190206020D80304 +3D18:000027FE140215FA840245FA4402100013FC2204E3FC220423FC220423FC0204 +3D19:0008203C17C0104080404FFE40401140165C2444E444275C2444244427FC0404 +3D1A:02082110100017FE80804184424414A811302270E4A8212822242C2220A00040 +3D1B:0008200817C81210821E44A447D41114111427D4E114210821C82E1424140022 +3D1C:0080204017FC1404840447FC4400140017FC26A4EAA42BFC2AA42AA432A4020C +3D1D:060478440844FF441C442A44C9140A880C603118C92605400920111025080200 +3D1E:0008203C13C010448224412849000A7C12441244E27C224422442244227C0244 +3D1F:000023FE120012FC828442FC4A840AFC120012FCE208221023FE241024500820 +3D20:00008FF8401000208040577A554A156A35525552D76A504A514250825FFE0002 +3D21:003823C01040104087FC41505248144613F82208E20823F82208220823F80208 +3D22:0090909048900190917C4954495403542554497CD95449104910491049100110 +3D23:002090204BFE002091FC482449FC012025FE4822D82A48544850488849040202 +3D24:021042082200227E0F9082104210571016FC2A10EA102210221022FE22000200 +3D25:04108410445404389510557C55441544357C5544D544577C5944404440540048 +3D26:0040202017FE1402800041F84908090811F81000E3FC22042204220423FC0204 +3D27:0040208013FC120483FC420443FC120413FC2000E04020242522250A28F80000 +3D28:0044272415281500857C47104510151015FE2710E5102528252825442B440082 +3D29:012422481248112483F842084BF8080013F81248E24823F82202220221FE0000 +3D2A:0040208013F8120883F842084BF80A0813F81040E7FE20E02150224824460040 +3D2B:40002FDE225282525FF4425402582FD4241247D2CC524C5A545467D044500010 +3D2C:010822081788148887BE4488478814C814A82FA8E18822882488288822A80110 +3D2D:0080204017FC140480A041104A08080013F81208E3F8220823F8220823F80208 +3D2E:000027FC1404140487FC4420452414A815FC2504E5FC250425FC290429141108 +3D2F:002027A414A814B084A247A2449E148014BE27A2E4A224BE24A228A22ABE1122 +3D30:01102212145417D88010401247D2144E144027D2E454245827D024522552048E +3D31:0080204017FC140480A041104248104017FC2040E44422A820A0211022080C06 +3D32:0004203E17E0143E842045FE4522153815E2251EE50029782A48324A248A0906 +3D33:04484444244024FE04509F544458545214542458E45227543C9A2092212E0240 +3D34:002024A414A8152084504488450417FE142024A4E52824502488250427FE0000 +3D35:00402028109012A482C2448A41881678100023FCE2942294229422942FFE0000 +3D36:0080208017FE1522811043FC56201A2013FC2220E22023FC2220222023FE0200 +3D37:00104F9025102510077C855447545510151025A8E7282D28214A214A21860100 +3D38:000027BC14A417BC84A447BC4404144414442444E4A424942514240424140408 +3D39:0010209214521254821040FE4010163812542292E31022102210250028FE0000 +3D3A:00208820442005FC902048A848A804A825744A22D85048504888488849040202 +3D3B:00044FC42004200407BE8484448454A417942014E8842484250421C42E140008 +3D3C:0040202017FE1402810041FE421016201A7C2244E244227C22442244227C0244 +3D3D:0008403C27C02040024881504FFE515012482C46E08020442A422A1231F00000 +3D3E:010841082FC82110011E8FD44864401417942094E11421C82F08211425240242 +3D3F:0000407E2F902220027C82444244527C1244227CE2442244227C2A0024280044 +3D40:04204220223E2F4004A08420473C555015102510E5FE2510252829282B441082 +3D41:0108210817FE1148802047FE4880090813FC1004E1502150215022522252044E +3D42:0040202013FE1200824842484BFE0A4812481248E27822002554252A2A2A1000 +3D43:0410840844081F7E95425542552015243F284430C420452247A25CA2481E0000 +3D44:00142012101217FE801043D04A500BD4101417D4E11427F8210A228A24560822 +3D45:004020A0111012488DF6402048400BF8120813F8E20823F8220823F821100208 +3D46:000840282F28293E0928894849084F7E19002900E93E29222F222922203E0022 +3D47:01A44E2422242224027E8FA44224522412242FBCE8A428A428A42FA428BC0024 +3D48:008890884888008893DE494849480148255E4A52D95248924892495E49520200 +3D49:008890884888008893DE48884888019C25DC4AAADAAA4CC84888488848880088 +3D4A:000023F8120813F8820843F850001FFE148027BCE494279424D42F88209400A2 +3D4B:000027FC14A414A487FC40004BF80A0813F81208E3F8220823F8211022080404 +3D4C:0408841C49F01110A51045FE4910197C2944497CC944497C49444A444A7C0C44 +3D4D:0000279E1492179E8492479E44421422140A2546E542255226322402240A0404 +3D4E:079E2492179E1492879E440244F2149214F22492E4F224922492253224020406 +3D4F:0110211017FC1110804047FC4110111012A82444E0402FFE2040204020400040 +3D50:40002FFE28008A2849484BEE089228842AA04AA8CBE848884894491449241242 +3D51:0200420027BC22A404A485BC480053F8120823F8E20823F8220823F821100208 +3D52:009027FC109413FC829043FE49120BFA150E11F8E10821F8210821F820900108 +3D53:008040402FFE280203F8820843F8520813F82000EFFC2240227C254024FE0800 +3D54:0040204017FC11108248444643F8105017FC2080E3F82D0821F8210821F80108 +3D55:0080211013F8121084A447BC404010A013582C46E04822642252245221400080 +3D56:0100210017DE125286924112429E14C0111023E0E04827FC2254244829440080 +3D57:43FC22400BF80A4013F82240E3FC20042554200801087D90096011202518C206 +3D58:08100A146AD42C582A544A94A950102008100A146AD42C582A544A94A9521020 +3D59:004027FC104013F8800043F8420813F811102FFEE00023F82208220823F80208 +3D5A:01102208141411A080604198464410A013182DF6E04027FC224821502FFE0000 +3D5B:011020A017FC104083F8404047FC124811502FFEE00023F82208220823F80208 +3D5C:0010241012FE1210801048FE448214AA119222BAEE9222FE22922292228A0084 +3D5D:008080405FFE0148823046905B08020627FC4524C61445EC452445E444140408 +3D5E:00C84708212A212C0FC881084388555419142122E04020242522250A290800F8 +3D5F:028842A826A82BF0001E822445D45C14141425D4E55425482568255426140422 +3D60:004047FE24022914020887FC440457FC14202524E52425FC24202924292411FC +3D61:03F8204017FC1444835840404358120013F82408EBC8224823E82212220201FE +3D62:000047FC20402FFE0842835840405358100027FCE444244427FC2444244407FC +3D63:00109F1051101F3E91225F4448101F9024905490DAA850A85EA840C445440282 +3D64:000027BC108414A4829444A4404017FC10402248E248255420A0211022080C06 +3D65:0080204017FC1484805045285554199416F02000E3F822A822A822A82FFE0000 +3D66:002021FE144012FC811042FE400016FC128422FCE28422FC2284228C250008FE +3D67:011027FE111013F8820843F84A080BF8110013FCE4442AA4220423F420140008 +3D68:00407C2045FC44887C5043FE7C20A5FC24203C2001087D90096011202518C206 +3D69:010827FE1108100084884FFE448814F8140027FCE0402FFE215022482C460040 +3D6A:0208211017FC104083F8404047FC10001440227CE08422282C20245024880106 +3D6B:01F8201017FE10A0804047BC408411CE17382108E31827FC240427FC240407FC +3D6C:00009DF85488149014FC1D549524555416881C0015FC55549554255427FE4C00 +3D6D:0040204413F8105087FE404051FC170411FC2104E1FC20002524249228920000 +3D6E:004027FC10A013188D1643F8411011F0104023F8E24823F8204027FC20400040 +3D6F:40002FF828088BE849084BE80A282BE82A284BE8CA084BFA4A0A53FA55562032 +3D70:0140224C12641244834C42644AA40BAC12A412A4E7FE20002110210822040404 +3D71:00044FE422842FE40ABE8AA44FE4500417D4200CEFEC2104254425242924030C +3D72:0100420027FC2AA802A88FFE42A852A81FFE2208E3BE24882AA8213E22080C08 +3D73:00404FFE280227BC04A4829444E450A013182C46E090232020C8231020600380 +3D74:000C800A57FE140895E85D48454A05EA3D2A552CD5EC554C654A49EA48161022 +3D75:07E0225C13C4125483C8426847D41064103C27C0E144226820D0214826460040 +3D76:0110411427D221100FFE829044505FF4149427F4E49427E8248A27FA24260042 +3D77:2010110810887CBE020029141108FC3E108810887D1C13081108210821084008 +3D78:004020A01110120885F4480243B812A813B82000E7FC24A427FC24A424A4040C +3D79:0428842844FE04289500557C5544157C3544557CD510577E5910402840440082 +3D7A:0210221017DE152888C440804BFC0A2413FC1244E3FC2120222027FE20200020 +3D7B:40502E962A928A924AD64E920A922AFE2A104EFCCA444A444A285210522826C6 +3D7C:000027FC140410808338420843B8120813F82200E7FC28042554255428280010 +3D7D:03F82248124813F88248424843F810001FBE2AAAEAAA2FBE2AAA2AAA2FBE08A2 +3D7E:0200823C5FA402248FBC42245FE4003C2FA448A4CFBC48904F9848A848AA09C6 +3D7F:0080210013F8120883F8420843F8120814102FBEE8A228A22FBE28A228A20FBE +3D80:00004EEE2A222AAA0A668EAA4A104A281A442F92EA202AC82A322AC42A1816E0 +3D81:03909C10411E15108A7E4852425C02703F52424ED2404A5C42544A5444960122 +3D82:0088908849FC008890884BFE482001FC252449FCD92449FC4800488849040202 +3D83:0080908049FE0354915449544BFE015425544954DBFE48004954492A4A2A0000 +3D84:07BC24A417BC14A487BC448444F41514162425B4E51425B4251425F424140408 +3D85:42A0244C24A4860C44A4464C04A42FFE280243F0C020404047FC404041400080 +3D86:04104210227A2F1200148F7E40084F10103C2F64E9A4293C29242F24293C0024 +3D87:42282228227C82284F2842FE0610277C2AD44A7CD254427C4200422842440282 +3D88:0110455425B8291002A884444FFE4842104023F8E248224823F8204427FC0004 +3D89:0308BC1044BE11228432492A5E22042629205F3EC4025F02447A4A02510A2084 +3D8A:00004FBE2A082A100A3E8FA248A248BE18A22FBEEA222A222A3E2A002F940022 +3D8B:050855482DA8253E0FA8824844484ABE13082588E988237E25402920251E0200 +3D8C:00449F444AAA0AEE8E444AAA4AEE0E002A284AAACBAA4EEE5A28422842480288 +3D8D:0200422227922494093E87C84548555E17C82548E57E27C820082AA82AA80008 +3D8E:01FC495425FC240001FE80005CFC448414FC2452E4CC254824642B0030FE0000 +3D8F:001C4EE02A542A280A7C8C104AFE4A001AFC2A04EA7C2C0428FC2814294A0A38 +3D90:0040202017FE14A884FE4550477C1550157C2550E57E254028A42A8A328A0478 +3D91:021082104510089E90526FA2400800083DC85548D5485DD44894489455542222 +3D92:1F3E91225F3E11229F3E500257FA148237F25482D7F2548257FA500A5AAA1014 +3D93:02109FFE4214000A07FE140895E85D4805EA3D2A15EC554CA54A09EA08161022 +3D94:000043F822A822A803F880004FBE4AAA1AAA2FBEE0402FFE20A0211022080C06 +3D95:021043DE2528288407BC84A447BC54A417BC2404E5F4251425F4251425F4040C +3D96:088089F84A881070138E3400B5FC55AC157415FC142055FC942013FE1154122A +3D97:20287F78AA147F7C2A543FB206001FF010101FF010101FF001843D480930730E +3D98:021043DE2528288407FC80A047FC54A417FC2208E3F8220823F820402FFE0040 +3D99:0284AAA456D4029EA7D451245224055E298452C4F4C451BE52A05490528E0100 +3D9A:07FE209017FE149287FE428047DE12921392211EE7D2255227DE21122FD20126 +3D9B:1080888049FE3D0012A0112C9D3455AC1534155415DC5554A7FE24884D048202 +3D9C:0002BEFA628A3EFA208231C6AAAA60823FFE2AAA2AAA7FFEAAAA2AAA32CA4104 +3D9D:004090204BFE02A492BE4BE84ABE02A826BE4AA8DABE4AA04A144B524D4A0A38 +3D9E:03F8220813F8120883F840404FFE14A417BC2110E7FC21102FFE212423180D86 +3D9F:47FC244427FC84444FFE4AAA0FBE2AAA2FBE4220C7C040844FFE404245480884 +3DA0:00009EFE54AA1EAA94FE5E10547C14103FFE4128D57C551055FE511041100610 +3DA1:00003FF8210821082108292829282948310822882248244A242A482A50068002 +3DA2:01001110111022A0044008203018C20602003FE002200420042008223022C01E +3DA3:00003FF801000100FFFE01000100000001001110111022A0044008203018C006 +3DA4:10801080108010FC550459045284944810281010101028202440448041008600 +3DA5:100011FC1020102054205820502093FE10201020102028202420442040208020 +3DA6:100011F8100810505420581053FE902210241020102028202420442040A08040 +3DA7:10201020102011FE55225922512291221152114A118A290225024502410A8104 +3DA8:00007FFC008001000300056009183104C1020100010000002488224442448004 +3DA9:10201020102011FE55225A24502090201050105010502850249044924112820E +3DAA:00007FFC01000300056019186104000001001110111022A0044008203018C006 +3DAB:010001007FFC0100210412C80C30F00C01021110111022A0044008203018C006 +3DAC:10201020102015FE58205020502091FC107010A810A829242524422240208020 +3DAD:1010109010901110557E5A52539290921112111212522BD224624422404A8084 +3DAE:00007FFC010001003FF8210822882448200820180100111022A004401830E00E +3DAF:10001080131E125256525A5252529252125212D2135A2A542490449041108210 +3DB0:10881088108814885BFE508850889088108810F8108828882488448840F88088 +3DB1:102010201020102055FE58205070907010A810A811242AFA2420442040208020 +3DB2:100011FC11241124552459FC51249124112411FC11242924252445244104820C +3DB3:01003FF00110FFFE01103FF001003FF80100FFFE00000100111022A00C60701C +3DB4:10201020107C108455485830502090481190103E104229A42418441040608180 +3DB5:0810087813C0304050409FFE10401040104017FC100000002488224442448004 +3DB6:10201020102017FE5A42544450A090A211A4129814902888248444A240C08080 +3DB7:1080108011FC15045A0451E45124912411E41124112429E42504440440288010 +3DB8:1040104011FC14445884508451289210110813DE114A294A254A4252435A84A4 +3DB9:100011FC102014205BFE50005020902213B210B410A829282524422444A28040 +3DBA:100011FC1020102054205BFE50509088110412FA148828882488448840F88088 +3DBB:08001FF0282007C01830E10E1FF001001FF001007FFC01000100488844448444 +3DBC:10201040108815045BFE5082508091FC1220102013FE28202450448841048602 +3DBD:100011FC11041504590451FC5020902013FE122212522A8A270A4202420A8204 +3DBE:00007FFC04403FF8244824483FF800007FFC010011101120228004401830E00E +3DBF:1020102013FE102054205BFE5202940411F8101010202BFE2420442040A08040 +3DC0:08202AA42CA849201450228841047FF0041004100410FFD00412040A04060402 +3DC1:100011F8100810D0542059FC5124912411FC1124112429FC252445244124810C +3DC2:00007E7C48047E4442287E1048287EC401001110111022A0044008203018C006 +3DC3:010011081108229004401830EFEE08000FE008000FE00800FFFE111014E0181C +3DC4:100011FC1124152459FC5124512491FC102013FE107028A82524422240208020 +3DC5:7F00227C3E0422283E1023A8FE44020001001110111022A0044008203018C006 +3DC6:1020104011FC110455FC590051FC910411FC102010202BFE2420442040208020 +3DC7:204020403C4045FEA84010902090C89211523D5446908428282810442084C102 +3DC8:1020102013FE105054885924522291FC112411FC112429FC24224422401E8000 +3DC9:00043F84208420843FBE20042F8420243FD422142A442A845204450488941048 +3DCA:0820082008207EFC08201C301A702A6848A48922082008200000488844448444 +3DCB:102010A210A211245450588853049022102010A410A429282450448841048202 +3DCC:100011FC100414FC580451FC500093FE1222102011FC29242524453441288020 +3DCD:1020102010501488590452FA500091FC1154115411FC2954255445544104810C +3DCE:100011FC110411FC550459FC508091FE122211221152290225FA440240148008 +3DCF:0640387C08907E1008FE1C102A10481001001110111022A0044008203018C006 +3DD0:1040119C1104110455DC5904510491FC1020102011FC28202420442043FE8000 +3DD1:010011081108229004401830E00E3FF804403FF824483FF801003FF80100FFFE +3DD2:11FC1124112415FC5924512451FC9020102013FE12222A2A26FA420A42028206 +3DD3:1080108010FC15545AD450B4512C924410941108104028A426AA428A44788000 +3DD4:1008103C13C014445A2451285100927C12441244127C2A4426444244427C8244 +3DD5:221012101410FF92145214547F5855905510632841287F28414841447F844102 +3DD6:00007DFC444444447C44444444947C88110014FC588450849084288444FC8084 +3DD7:00002FBC28A42FA4283C2FA228A24F9E81001110111022A0044008203018C006 +3DD8:10401088110413FE540259FC5104910411FC102013FE287024A8452442228020 +3DD9:11081088109017FE580053C45254925413D4125412542BD426544244425482C8 +3DDA:1040102013FE100055FC590451FC900013FE120211FC28202420442040A08040 +3DDB:08000BF81208320853F8904017FE10E0115012481C4610400000488844448444 +3DDC:2080204027FE2090AA98B494A114A2302440204027FE204050A0491042088C06 +3DDD:1040102013FE12025488590452229028102413FE102028502450448841048202 +3DDE:200023FE220022FCAA84B2FCA284A2FC220022FC2208221053FE4C1044508820 +3DDF:10081210117C15445844507C57409140117E11421142297E25424280447E8000 +3DE0:0110092012E00C187104091012A00C60701C10103EFC4210149008FE3010C010 +3DE1:00007EFE42807EFC42847EFC42807EFE01001110111022A0044008203018C006 +3DE2:082004407FFC01003FF80200FFFE080037F0C0801FFC0100111022A00C60701C +3DE3:1088105013FE102055FC582053FE900010A010FC1120282027FE442040208020 +3DE4:10001078FE4810487C480086FE0082FC7C44104412285428A810242844448182 +3DE5:100015F854105820902429A844B090A815285924522290A02840440081FC0000 +3DE6:0020FF2024A43CA424A83D20242024502F50F488050406020400488844448444 +3DE7:100011FE11101520597C5144517C9144117C1110111029542552429242508420 +3DE8:1020122213FE148059F852885070938E102011FC102029FC242043FE40208020 +3DE9:000027DC25042784249C2790251247CE0000010011101120228004401830E00E +3DEA:10A0109011FE132055FC592051FC912011FE110013FC2888249E4502420A8404 +3DEB:08007F7808483E4800863E782A483E30404880840100111022A004401830E00E +3DEC:1088108813FE1088540059FC510491FC110411FC10202BFE2450448841048202 +3DED:210013F0151000E0775C11F0104013FC284047FE0100111022A004401830E00E +3DEE:1090109017FE109057FC5A9453FC929413FC100011F8290825F8450841F88108 +3DEF:1020102055FC584090F810402BFE4488912412227CF8102011FC1E20F0204020 +3DF0:1040102013FE140059545124515491FC102013FE12422A9226FA420A42028206 +3DF1:1010101022107F7C01103E1022103EFE22103E2022442AFE2442000024884244 +3DF2:21C8270821082FE8A91EB7CAA54AA7CA254A27CA210A27CA511249D24E2A8444 +3DF3:3FFE224824FE2D9036FC249024FC249024FE248020402248445040A083180C06 +3DF4:3FFE21042E3822102FBC27182AB432522000208024882890214042204C18B006 +3DF5:100011FC112415AC5974512451FC902011FC102013FE280026A4425244528000 +3DF6:111017FC21102FFE6100A3F826482BF8224823F8224822580000488844448444 +3DF7:100013DE125217DE5A10525251CE9000108813FE1088288827FE448841048202 +3DF8:100011FC110415FC590451FC500091FC10A813FE10A829FC242043FE40208020 +3DF9:108813FE10881020543E582051FC910411FC110411FC282027FE442040208020 +3DFA:20203E20443EA84446844228761042287E44010211101120228004401830E00E +3DFB:1080108011FE13545554595453FE91541154115417FE28002554452A422A8000 +3DFC:0440FFFE0440044017D01012F7DC14503452D7D2100E0100111022A00C60701C +3DFD:1088105013FE102055FC582053FE912410A813FE100029FC2504450441FC8104 +3DFE:2040207C204023FEAA42B278A3C4A23C220023FE224023A452584DB4445289B0 +3DFF:1020102010501488590452FA5000900011DC1154115429DC2488448841548222 +3E00:102013FE100014F8588850F8500093FE120212FA128A2AFA262641F8402083FE +3E01:10501252115414505BFE5088505093FE102011FC10202BFE24A8412446228020 +3E02:011027FC1080034870B0136810A4132010402FFE4100111022A004401830E00E +3E03:00107F1049106B1E5D1049107F7C08447F4408440F7CF0440000488844448444 +3E04:2040202023FE2088A852B7ACA2AAA2A825AC2000210421FC510449FC41048204 +3E05:2210221023DE2528A884B000A7BCA4A427A424A427A4243455284EA044208020 +3E06:112011FC122017FE580051FC510491FC105013DE105029DC245043DE40508050 +3E07:108811DC108813DE54885954522291FC110411FC110429FC250445FC40888104 +3E08:081024483F7E64C8BF7E24483F7E24483F7E20400100111022A004401830E00E +3E09:210827C8AAAAB12CAFE8210857D44912892200000100111022A004401830E00E +3E0A:2108210827CE2112A924B7DEA552A55E27D2211E2392255E5940491441128122 +3E0B:203C21E03D2444A8A9FE50A82124420291FC5524552459FC9124292425FC4504 +3E0C:11FC102013FE122255AC582051AC909011FE132015FC292025FC452041FE8100 +3E0D:210821EC210A27E8AD28B5DEA728A4EA240A27EA240C27EC5A2A4BEA515687E2 +3E0E:13FC110811F8150859F8510E57F8900817FE1294139C2A94279C42D647BC8084 +3E0F:00803FFE24103F7C26382D5435322F3C2120273821202F3C248849504630B80E +3E10:2850FE4828FE399012907CFE54907C9010FE7C901090FEFE2880440024884244 +3E11:2FEC48246BAC48246BAC4AA4FFFE88227EFC2C684AA40100111022A00C60701C +3E12:00FC7F00020821081110102000F83F0001000100FFFE0100010001003FF80000 +3E13:00FC7F0002082108111010203FF82008200820083FF82008200820083FF82008 +3E14:00F87F00211011101220FFFE040008001FF028104FF088100FF008100FF00810 +3E15:0228077E38482AFE2A482A7E2A482A7E2A40297E2922289C28624830480E8800 +3E16:000028F824884288408884F804884888288810F8188824882488408883FE0000 +3E17:084010202850448803001CE0E01E3FF820082FE8200827C8244827C820282010 +3E18:084010202850448803001CE0E01E1FF012901FF000007FFC0100010005000200 +3E19:084010202850448803001CE0E21E1FD00220FFFE03000FF03810CFF008100FF0 +3E1A:0008848844502820105028884500840800880488445028501020285044888506 +3E1B:040025FC2444244424443C4404940488FD0024FC248424842484448444FC8484 +3E1C:04202410241025FE25023E5404880504FC0024FC242024202420442045FE8400 +3E1D:044024402440247C24443E8820A021203C202450245024482488448445048602 +3E1E:041024902490249024903EFE208020803C8024F8248824882488448844888508 +3E1F:04802484249824E024823E82207E20003CFC2484248424FC2484448444FC8484 +3E20:0890489048904A9249947C98409041987A944C9248904890491249124A128C0E +3E21:08204920492049FC49207E20402043FE787048A848A8492449244A2248208820 +3E22:0844484449FE484448447DFE404040FE79924AFE489248FE4892489248928886 +3E23:08504A52495448504BFE7C88405043FE782049FC48204BFE48A849244E228820 +3E24:409022882288FABE028053D42208FA3E23882288729C22882288448844888888 +3E25:09F04A104FFC4A044BFC7E2443B8422279FE4A104FFC4A444BFC48D0494A8E3E +3E26:00003FF800801080108020803FFC0080108008800680018000F0008E02800100 +3E27:00007EFC0484248424FC248444847EFC0C92149214942488448884A414C20880 +3E28:08040804488448847E844884888408840E8CF89448E408840804080408040804 +3E29:080008FC482048207E204820882009FE0E20F820482008200820082008200820 +3E2A:11041124512451247D245124912411241D24F124512411241124122412041404 +3E2B:0804080E48F048807E80488088FE08880E88F888488808880888090809080A08 +3E2C:10201020502053FE7C20502091FC11241D24F124512411341128102010201020 +3E2D:1000100051FC51247D245124912411241DFCF100510011001102110210FE1000 +3E2E:10101090509050887D085104920415FA1C88F088508810881108110812281410 +3E2F:08080888484848487E084888884808480E08F80E49F808080808080808080808 +3E30:10201010501051FE7D025204908010881C90F0A050C0108210821082107E1000 +3E31:1080108050FE51007A205120912C11741BA43124D13411281122110210FE1000 +3E32:084008404840487E7EA048A08920083C0E20F8204820083E0820082008200820 +3E33:10201020505050507C885124921210101DFCF004500810881050102010101010 +3E34:0000FFFE040008001FF02810C8100FF0010011001FF821000100FFFE01000100 +3E35:10201020502053FE7C20502091FC10001C00F1FC510411041104110411FC1104 +3E36:100011FC510451247D24512491FC11241D24F154514C118C1104110411FC1104 +3E37:080008007F7C08243E2408447F540888090011001FF821000100FFFE01000100 +3E38:1008101C51E051007D0051FE910011001D7CF144514411441144127C12441400 +3E39:1004101E51E050227D125094908010081DFEF008508810481048100810281010 +3E3A:1020082040A824A4092A723010C01700010011001FF821000100FFFE01000100 +3E3B:10201040508851047DFE5002908010FC1D20F02053FE10201050108811041202 +3E3C:1040104050FC50887D50502090D813261CF8F02050F8102013FE102010201020 +3E3D:080008FC488448847EFC4884888408FC0E84F88448FC08000848084408820902 +3E3E:100013FC5044514479445284909411081A403020D0A41282128A128A14781000 +3E3F:1020102053FE50207DFC500093FE12021C04F0F050901090109011121112120E +3E40:1020102053FE5020782053FE9202140419F83010D02013FE1020102010A01040 +3E41:1040102053FE50007C0051FC910411041DFCF020512811241222142210A01040 +3E42:00007EFC48447E4442287E1048287EC6010011001FF821000100FFFE01000100 +3E43:044004407C7C04403C7804407C7C0440054011001FF821000100FFFE01000100 +3E44:100011FC512451FC7D2451FC908811441E42F0F8518812501020105011881606 +3E45:1080108050FC51547AD450B4912C124418943108D04010A412AA128A14781000 +3E46:100013FE522250207DFE502091FC11241DFCF12451FC102013FE102010201020 +3E47:100011FC510451FC7D0451FC908011FE1E22F1225152110211FA100210141008 +3E48:082008207E7E08C4FF281C102A2848C6010011001FF821000100FFFE01000100 +3E49:100011FE511051207D7C5144917C11441D7CF110511011541152129212501420 +3E4A:1040104053FE52A27C9051FE912013201DFCF120512011FC1120112011FE1100 +3E4B:1120113C514452A87A1056A89AC612801A8832B0D28412881232120412181260 +3E4C:1040102053FC50007D08509093FE12201EA0F2FC5320122012FC1420142019FE +3E4D:1040102053FE50887C5053FE922212FA1E22F2FA528A128A12FA1202120A1204 +3E4E:100011FC512451FC7D2451FC904010881DF0F020504413FE1022112412221060 +3E4F:1088108853FE50887CF8502091FC11241DFCF02053FE102011FC102013FE1000 +3E50:11102110CAA814443240D27C154014FE090011001FF821000100FFFE01000100 +3E51:101417FE501053D0781053D0901013D01A5033D0D25013C8124A13CA11861242 +3E52:10501252515450507BFE5088905013FE182031FCD02013FE1050108811041602 +3E53:1020102051FC50207BFE5108939C11081988363ED00013FE109010901112120E +3E54:100013FE500051FC7D2451FC912413FE1C00F1FC512411FC112411FC100013FE +3E55:7DFE002000FCFE8428FC288428FC4A844CFC884811841FF82100FFFE01000100 +3E56:1020112450A851FC784053FE908811041AFA3040D1A4105811B4105213901030 +3E57:102013FE502051FC7C0053FE900211FC1C20F3FE500013FE100413BE12A4138C +3E58:100011FC502053FE7E2251AC902011AC1C00F3FE502011FC115411541154110C +3E59:108812AA52DC54887954522293FE12021DFC3104D1FC110411FC110411FC1104 +3E5A:108812AA52DC54887954522293FE120218F83088D0F8100011FC110411FC1104 +3E5B:200027FEA040A2EEFAAAABEAAAAE2AE83BAAECE6228825F42290206021982606 +3E5C:08200A280924092408207EFE0820082008501450125012882088210442048402 +3E5D:0004441E29F0111029104910891009FE1910291049108908090A094A51862102 +3E5E:0008441C29E011002900490089FE0910191029104910891009100A1052102410 +3E5F:00404440284013F828484848884808481FFE284048A088A00910091052082406 +3E60:00204420282013FE2820492489240924192429FC4824882008220822501E2000 +3E61:00404420282013FE28404840888809081BF028204840888809040BFC51042000 +3E62:02008A005200221E57D292521252125232525252925212521452145EA9525080 +3E63:0080888050F82108531094A0104010A033185C0690C0102010101180A0604010 +3E64:00204420282011FC2820482088200BFE182028404840888809040BFE51022000 +3E65:00404420280013FE282048208820082019FC2820482088200820082053FE2000 +3E66:00008BFC508420845084910411141208340051FC9104110411041104A1FC4104 +3E67:00204420282011FC292449248924092419242BFE482088500850088851042202 +3E68:002044202820102029FC492489240924192429FC492489240924092451FC2104 +3E69:000045FC2884108828504820885008881B26282049FC88200820082053FE2000 +3E6A:000097BC54A424A454A494A414A41FFE34A454A494A414A414A415A4A8545088 +3E6B:002044202BFE102029FC482489FC092019FE2822482A88540850088851042202 +3E6C:004088405FFE2040504097FC1444144437FC50409240114010801140A2304C0E +3E6D:0020442029FC1124292449FC8924092419FC282048248818083208CA53062002 +3E6E:000045FE28201020284049FC89040904190429FC490489040904090451FC2104 +3E6F:009044902890111029FE4B108D10093819382954495489920910091051102110 +3E70:004044442A441148295048408FFE0890189028904890889209120912520E2400 +3E71:000045FC29041104290449FC882008201920293C492089200AA00A60543E2800 +3E72:0020442229FA102428244BFE8810082019FC288849108AFE0C10081050502020 +3E73:000047FE2840104029FC488488840BFE1800280049FC89040904090451FC2104 +3E74:000045FE2820102029FC4924892409FC1924292449FC892008A0084050B0230E +3E75:000045FE2800109229244A4889240892180029FE482088200820082053FE2000 +3E76:0000880653B8208850889108113E1388308852889288113E11001280A47E4800 +3E77:4210241418122412521010FEFF10201028107E28AA282A282A442E4408840902 +3E78:0020444029FC1104290449FC8904090419FC28504850885008920892510E2200 +3E79:0040882053FE222052FC9224122413FE3224522492FC122012501450A4884906 +3E7A:002044222BB410A828A849248AA2084019FC2904490489FC0904090451FC2104 +3E7B:001C45E0282010202BFE48A889240A4218402BFE4888890808D0083050482184 +3E7C:0080448028FE11022A424A4A895208421BFE284248E289520A4A084250542008 +3E7D:00504448285E13E42828483288CA0F0618502848485E8BE40828083250CA2706 +3E7E:0110891053D8225454529A90111012FE3C00500093F8120812081208A3F84208 +3E7F:00204420283E102029FC490489FC090419FC292448208BFE0820082050202020 +3E80:0080448028FC11542A5448A489240A4418942908484088A40AAA0A8A54782000 +3E81:009245242A4811242892484088800BFE1A022A8A4A528A220A520A8A53FE2202 +3E82:00148812501027FE5410941015D01412341255D49554154815DA142AA8465082 +3E83:008844882BFE1088290049FC89040A0419F42914491489F40914080450282010 +3E84:004044A0291012082DF648008BC40A541A542BD44A548A540BD40A44525422C8 +3E85:0080888051FC220454089BFE1200128032FC5320922013FE14201450A8885306 +3E86:02104510287E1310292849A88944080019FC2904492489240924085050882304 +3E87:001090145FD229126910A97E2B902A906A90AB982928292829242FC4A0444082 +3E88:00204524292411FC28204BFE8800082019FC2924492489FC0820082453FE2102 +3E89:10001078FE4810487C480086FE0082FC7C4400441428FE281010282844448182 +3E8A:01044488280013FE2820482089FC082018202BFE484088240AA20A8A54882078 +3E8B:0120891052082486591093F81008100037BC508494A4129414A41084A2944108 +3E8C:011088A0500027FE50A093F810A817FE30A853F890A011B012A814A6A0A040A0 +3E8D:0040882053FE2202541491E01100110031FC5110911017FE10001090A1084204 +3E8E:002097FE542025FC542497FE142415FC342055FC952415FC152419FCA924512C +3E8F:002045FC292413FE292449FC882009FC192429FC48408BFE088809D05070238C +3E90:012446482924100029FC492489FC092419FC28204BFE887008A8092456222020 +3E91:0040448829FC11082A524BFE885009881E2628C04B1088640B88083050C02700 +3E92:000097BC508424A4529494A410501188362650C09310106413881030A0C04700 +3E93:002047FE282011FC28204BFE880009FC190429FC490489FC090409FC50882104 +3E94:000E8BF050442224510893F8120813FC320453FE920212AA12AA1502A4144808 +3E95:007897C05248215057FC91501248140633F85248924813F812481248A3F84208 +3E96:00089788508821106FDEA49424A427946494A794249424C827882C94A0A440C2 +3E97:000047DE2A5212522BDE480089FC092419FC292449FC88200BFE082050202020 +3E98:0090448829FE11102B104DFE8910091019FE2910491089FE09000AA452522452 +3E99:0080884057FE240251F8914817FE122833FC501093F81248124812A8A1104608 +3E9A:00109410527C201050FE9044162812FE3210527C921012FE12101210A5FE4800 +3E9B:03FC8A4053F8224053F8924013FC10043554500891101FFE11101110A2104410 +3E9C:00908BFC529423FC529493FC100013FC320052F8920013FE15201514A5484986 +3E9D:001097D0551027DE545097E8150417C4300053F892A812A812A812A8AFFE4000 +3E9E:01408A4C52642244534C926412A413AC32A452A497FE100011101108A2044404 +3E9F:000097BC508424A4529494A41120121037FC5A2093FC122013FC1220A3FE4200 +3EA0:008090405FFE29126208A5842E0E2A746A54AB542AD42A542A522D54B75C4084 +3EA1:000097FE544425986488A7DE248825DC66AAA48824202520253C2920A92057FE +3EA2:07FC904057FE24425B5C9040175C112033FC56209BFC122013FC1220A3FE4200 +3EA3:010891EC510A27E86528A5DE272824EA640AA7EA240C27EC2A2A2BEAB15647E2 +3EA4:0148894C52AA200857FE91481368114A336A514C936C1148116A139AA0264042 +3EA5:01F08A1057FC220453FC922413B8122231FE521097FC124413FC10D0A14A463E +3EA6:00449F445AAA2AEE6E44AAAA2AEE2E006A28AAAA2BAA2EEE3A282228A2484288 +3EA7:07BC94A457BC200057FC908013F8120833F8520893F81110120817BCA4A447BC +3EA8:00200020FC201020102010407C4010401080108810841D04E3FE410200020000 +3EA9:00040004FE841084108410847C841084108C109410E41E84F004400400040004 +3EAA:00400040FE401040104010507C4810441044104010401E40F040404000400040 +3EAB:00080008FE081088108810887C8810881088108810881E08F008400800280010 +3EAC:000001F0FD101110111011107D9011501150111011101D12E2124212040E0800 +3EAD:000001FCFC041008101010207C2013FE1020102010201C20E020402000A00040 +3EAE:000001FCFC001000100013FE10407C40108010FC100410041C04E00440280010 +3EAF:00007FFC010001003FF801000100FFFE00000100FFFE0280044008203018C006 +3EB0:000003FEFC201020102011FC7D2411241124112411241D34E128402000200020 +3EB1:100017F82110613CA10422042414280820007FFC01003FF801200110FFFE0000 +3EB2:000001F8FC481048104810487C4811F81088108810881C88E088408803FE0000 +3EB3:00200020FE20103E102010207C2011FC1084108810481E50F020405001880606 +3EB4:00200028FE241024102011FE7C2010201020105010501E50F088408801040202 +3EB5:00800080FC8010FC1104110812407C40104010A010A011101D10E20844040802 +3EB6:00080088FE481048100810887C4810481008100E11F81E08F008400800080008 +3EB7:00200028FC24102011FC10207C70107010A810A811241D24E222402000200020 +3EB8:080009F011103190515091521112120E04007FFC01003FF801200110FFFE0000 +3EB9:00200020FC401088110413FE7C021088108813FE10881C88E108410802080408 +3EBA:000001FCFD041104110411FC11047D04110411FC110411041D04E10441FC0104 +3EBB:00200020FC2013FE102010207DFC11241124112411241D34E128402000200020 +3EBC:000003FEFC221024102010207D20113C1120112011201D20E2A04260043E0800 +3EBD:000001FEFC101010102010207C6810A41122122210201C20E020400003FE0000 +3EBE:000003FCFA042204220422F4FA9422942294229422F43A94E204420402140208 +3EBF:000001FEFD1011101110117C11447D4411441144117C11101D10E11041FE0000 +3EC0:00200020FBFE2222222223FE2222FA2223FE2020212038A0E04040A001180606 +3EC1:00000000FDFC1104110411747D5411541154115411741D04E10441FC01040000 +3EC2:01040084FC88100013FE10887C881088108817FE10881C88E108410802080408 +3EC3:044004403FF824483FF824483FF800007FFC010001003FF801200110FFFE0000 +3EC4:0008003CFDC01000100013FE7C2010201120113C11201D20E2A04260043E0800 +3EC5:00200020FC5010881104120210F87C00100013FE102010401C88E10443FE0102 +3EC6:00400080F908220427FE20022000FBFC220423FC220423FC3A04E20402140208 +3EC7:00200020FC501088110412027DFC10201020102011FC1C20E020402003FE0000 +3EC8:0008001CFDE01100110011FE7D001100117C114411441D44E144427C02440400 +3EC9:00200020F920213C2120212027FEF8002020212421243A28E410402000C00700 +3ECA:00800080FCF81108121011FC11247D24112411FC105010501C90E0924112020E +3ECB:00200020FDFE1020102011FC7D24112411FC102010701CA8E124422200200020 +3ECC:00200020FC501088110412FA7C20102013FE102011281D24E222442200A00040 +3ECD:000001FCFD04110411FC10007C0011FC1020102013FE1C20E050408801040202 +3ECE:010001007FFC0100FD7C111011107D7C11101D10E2FE4280044008203018C006 +3ECF:000001FCFC04100410FC10047C0411FC102010A410A41D28E050408801040202 +3ED0:00400040FC88110413FE100210887D44124210F8118812501C20E05041880606 +3ED1:001C00E0FC2011FE107010A87D24122210F8101010201DFEE020402000A00040 +3ED2:000003FEFA02221A22E222222222FBFE2222227222AA3B26E222422203FE0202 +3ED3:000007E0FA5E2252225223D22252FA5423D4225422483AE8E754405400620040 +3ED4:0008003CFDE0102013FE10A810A87CA813FE10A810A813FE1C20E02041FC0000 +3ED5:000003FEFA02220223FE22102292FA92229222FE22103A92E292449204FE0802 +3ED6:00400040FBF82048204827FE2048F84823F8244422E83950E248444601400080 +3ED7:044004407C7C04403C7804407C7C044004407FFC01003FF801200110FFFE0000 +3ED8:00400020FBFE2222202021FC2124F92421FC2124212439FCE124402000200020 +3ED9:00400020FBFE2080210423FEF80221FC210421FC210439FCE104410401140108 +3EDA:000003DEFA522252225223DE2252FA52225223DE22523A52E2524252055208A6 +3EDB:000001F8FD08110811F811087D0811F8108011FC12541C94E124424400940108 +3EDC:00880088F8882088215422222442F82020202120213C3920E2A04260043E0800 +3EDD:00820082FBE22082208A23EA22AAFAAA23EA208A21CA3AAAE4A24082008A0084 +3EDE:00400020FBFE2202220223FE2200FA0023FE235225523DFEE552455209520106 +3EDF:00400040FBFE208021FC222025FEF80021FC210421FC210439FCE10401140108 +3EE0:00400020FBFE220220882104FA222028202423FE20203850E050408801040202 +3EE1:00480148FD4813FE114811487D78110011FE102013FE1C70E0A8412406220020 +3EE2:02100110F91027BE2228224823AAFAAE22BA22EA22AE3AA8E4AA44A209A2101E +3EE3:00880088FBFE208820F8208820F8F888208823FE21003948E184410001FE0000 +3EE4:00880088FBFE2088210021FC2104FA0421F42114211439F4E114400400280010 +3EE5:00880048FC5013FE105010507DFC11541154118C11041DFCE104410401FC0104 +3EE6:01FC0124FD2411FC112411247DFC1020102013FE12221E2AE2FA420A02020206 +3EE7:01040104F9DE22442554209E2104FA24242423FE207038A8E124462200200020 +3EE8:00007EFC48447E5443287E9048287EC600007FFC01003FF801200110FFFE0000 +3EE9:011000A0F80027FE20A023F8F8A827FE20A823F820A039B0E2A84CA600A000A0 +3EEA:00A00090FDFE132015FC11207DFC112011FE110013FC1C88E09E4102020A0404 +3EEB:000001FCFD2411FC112411FC7CA810A813FE10A810A81DFCE02043FE00200020 +3EEC:01FC0020FBFE222221AC2020F9AC200021FC200023FE3880E0FC400400280010 +3EED:00400020FBFE2020204822F2F924225220F8200820203BFEE020402000200020 +3EEE:01000110FBDC225425542288F90822F42402200023FC3840E150424805440080 +3EEF:0040007CF84023FE22422278FBC4223C220822F023243AA8E5FE442008A00040 +3EF0:008803DEFC8811DC108813DE7C88100013FC100410041DFCE004400403FC0004 +3EF1:0020047CFA842148203020CE2610FA7C2210227C22103AFEE210421005FE0800 +3EF2:002001FCFD2413FE112411FC7C2011FC112411FC10401DFEE08841D00070038C +3EF3:00880088FBFE2088204220E2FB82208A208A27EA218A39CAE2AA4482008A0084 +3EF4:000001F8FD0811F8110811F87C0013FC129413FC10001DF8E090406001980606 +3EF5:03FE0202FBFE220022FC220823FEFA10223023CE22423A84E4EE47840884018C +3EF6:010801EEFA942042202021FC2024FBFE202421FC202039FEE02043FE00200020 +3EF7:02080208EFBE420842084FBE4AAAEAAA4AAA4BAE4208671CCAAA124802080208 +3EF8:000007BCF908252827BC231825AAF946200023F822083A08E3F84208020803F8 +3EF9:FDFC104021A27C54A5B824543D92246000007FFC01003FF801200110FFFE0000 +3EFA:3FFE21042E3822102FBC27182AB4325220002FFC208027F820A040905FFE8000 +3EFB:01080088FBC8201023DE226423D4F81423D42054209438E8E388409402940122 +3EFC:000003FEFC5013FE125213FE7C0011FC110411FC11041DFCE02043FE00200020 +3EFD:00A00090FDFE132011FC11207DFC112011FE110013DE1E52E252427202020206 +3EFE:0100FFFE104824FE799010FC22907CFC089030FEC0807FFC01003FF80120FFFE +3EFF:000003F8FAA822A823F82100FBFC248423E422A422A43BE4E09447F400140008 +3F00:00100410FA7C201020FE20442628FAFE2210227C22103AFEE210421005FE0800 +3F01:01040088FBFE202021FC2020FBFE20542192209023FE3890E0D4438A009601A2 +3F02:0A0033B822083BB820883AB82288FFFE80027FFC01003FF801200110FFFE0000 +3F03:01240248F924200023FC22942264FA9423FC224823683A48E36A424A02460362 +3F04:01240124FAAA23AE212422AAFBAE202427FE201027D43D54E7CA454A07D60022 +3F05:00200010FBFE224422FE224423FEFA1022FE229222FE3A92E2FE420002440482 +3F06:008802AAFADC24882154222227FEFC0221F82040204039F8E050404803FE0000 +3F07:00200222FBFE209021FE231025FEF91021FE211021FE21003BDEE25202720206 +3F08:000007FCF4A424A427FC221022A8F4BE2F68223C24A82FBC3028CAA80ABE0020 +3F09:0210071038102A7C2A542A542A102A282A282948294A288628404A304D0E8900 +3F0A:1008101C10E8FEA810A854A854A854A854A87CA410A410A414A2192811340224 +3F0B:1008101C10E810A8FEA810A810A810A87CA844A444A444A444A27D2845340224 +3F0C:08081C1C70E850A850A850A858A854A854A854A450A450A458A255289D340624 +3F0D:1008101C10E8FEA810A87CA810A8FEA830A838A454A454A490A2112811341224 +3F0E:0220071038102AFE2A002A442A822A282A1029282944288428404A304D0E8900 +3F0F:04081E1CE0E822A892A854A848A810A8FCA824A444A428A410A2292845348224 +3F10:0804040E7F74415441547F5440547F54555455527F52555255505594819A0312 +3F11:1008101CFEE810A8FEA892A8D6A8BAA892A8FEA410A438A454A2932811341224 +3F12:027C0744387C2A442A7C2A002AFE2A402A7E29AA295228AA28444A304D0E8900 +3F13:08881C50700053FE505051FC585457FE545455FC505050D8595456529C500450 +3F14:0008001C7CE844A87CA844A87CA800A87CA854A454A454A456A2F92801340224 +3F15:1008921C54E8FEA882A87CA844A87CA800A87CA454A47CA454A255287D344624 +3F16:11F03A10E3E0A020A7FCA188B650A9A8AE64A9A0A248AFBEBAAAAFBE3A8A0FBE +3F17:000001FCFE801080108010F81088108811481128112811081108114A518A2106 +3F18:100011FC10801080548054F8548854885548552855285D086508014A018A0106 +3F19:100010FC1040FE40924092789248924892A892989A88948810AA10CA108A1006 +3F1A:100008FC0840FF40004000783C48244824A824982488258846AA44CA808A0006 +3F1B:00007EFC24402440244024782448FF4824A824982488248824AA24CA448A8406 +3F1C:01001FF011101110FFFE02801C70E00E00007FFC08000FE0092010A41624181C +3F1D:10001EF8228862A894920882307EC00000007FFC08000FE0092010A41624181C +3F1E:00007EFC084008404A402A782C480848FFA808980888088808AA08CA088A0806 +3F1F:100010FC20407E4042404278424842487EA842984288428842AA7ECA428A0006 +3F20:100008FC08407F4041408278204820483EA820982088208826AA38CA208A0006 +3F21:080028FC28403E404840887808487F4818A81C982A882A8848AA88CA088A0806 +3F22:0000FEFC904090409040BC78A448A448A4A8A498BC88908890AA90CAFE8A0006 +3F23:0000FEFC1040104020407C784448444844A87C984488448844AA7CCA448A0006 +3F24:080008007F7C08243E2408447F54088800007FFC08000FE0092010A41624181C +3F25:100012FC7A4014401440FF78104820487EA8909820883C8804AA04CA148A0806 +3F26:00007DF01110119011521D12E20E440000007FFC08000FE0092010A41624181C +3F27:0000FCFC044068401040FE7892489248FEA892989288FE8892AA92CA928A8606 +3F28:080008FC14402240514088787E48024804A808987E88428842AA7ECA428A0006 +3F29:0400057C04A07F2044204438742855285558564856485448655A4D6A934A0106 +3F2A:080008FC7F40084008402A782A482A485DA888980888148814AA22CA428A8006 +3F2B:00007EFC4A404A407E404A784A487E4808A8FF9818882C882AAA4ACA888A0806 +3F2C:100010FC7C4010401040FE78444828487CA810981088FE8810AA10CA108A1006 +3F2D:1020103E7C2011FC11041D04E1FC010400007FFC08000FE0092010A41624181C +3F2E:100010FCFE4010407C401478FE4814487CA81098FC88248844AA28CA308AC806 +3F2F:0800087CFFA0082008207F3849287F2849587F4808481C482A5A496A884A0806 +3F30:0800107C7F20492049207F38492849287F5814482448FF48045A046A044A0406 +3F31:04447C5804621C42E43E00007FFC482410107FFC08000FE0092010A41624181C +3F32:0000FEFC10402040FE40AA78AA48AA48A2A896981088FE8810AA28CA448A8206 +3F33:100010FC52405140954008783048C0487EA842987E8842887EAA42CA7E8A4206 +3F34:00007CFC544054407C40547854487C4810A8FE9892889688BEAA82CA8A8A8406 +3F35:00003EFC22203E2022383E280048FF680858084A2F4A286A284658004FFE8000 +3F36:100010FC2840444082407C780048E248AAA8AA98EA88AA88AAAAE2CAAA8AA406 +3F37:100092FC92409240FE400078FE48104820A8FE98AA88AA88AAAAAACAAA8A8606 +3F38:1000087CFFA080A0142022384928142822584148BEC82248225A226A3E4A2206 +3F39:440044FCFF4054400840FF78404840487EA800985488548855AA56CA948A0006 +3F3A:100008FC7F4048405E404A787F484A485EA848985E88528852AA52CA5E8A9206 +3F3B:11102110CAA814443240D27C154014FE08007FFC08000FE0092010A41624181C +3F3C:0000FEFC2840FE40AA40AA78FE4800487CA80098FE88108854AA92CA508A2006 +3F3D:100010FCFE401040BA405478BA481048BAA85498BA88108828AA24CA428A8006 +3F3E:0800047C7FA0522052207FB852A852A87FD8524852485BC8525A52EA9B4A1206 +3F3F:1000087C7F202220FF2000387F2849287F5849487F4808487F5A086A0F4AF006 +3F40:2200147CFF2014207F20553863285D2841587F480848FF48145A226A414A8006 +3F41:3FFE21042E3822102FBC27182AB4325220003FFE240027F0249048524B128C0E +3F42:0800147C22205D2080A03E3822283E280058774811485548335A556A114A3306 +3F43:0E00F0FC92405440FE403878544882487CA8549854887C8854AA54CA7C8A4406 +3F44:240CFF7024403C40247E3C482448FF482448428800007FFC08000FE011241C9C +3F45:0A0074FC15405240224021785D4880487EA8429842887E8842AA24CA0F8AF006 +3F46:100092FC5440FE4082407C7844487C4800A87C9854887C8854AA54CA7C8A4406 +3F47:0A803138228838382288393822887FFE4002BFF408000FE0092010A41624181C +3F48:48F8705044203DFC20247CB890A07D7E2A007FFC08000FE0092010A41624181C +3F49:00007E40487E7E9043087EFE48AA7EFE00007FFC08000FE0092010A41624181C +3F4A:49005D7C6120DDA043205D3841285D28B6D89C4800487F48025A346A1C4A6306 +3F4B:210447C88812F3BC20084B92F83E0380AAAAABAA00007FFC08000FE011241C9C +3F4C:7F00087CFFA088A06B2010386F28452855586B4810487F48495A7F6A494A7F06 +3F4D:220022FC22402240FF402278224822483EA822982288228822AA3ECA228A0006 +3F4E:22102210FF1022103EFE22923E9222102228FF28402854286248404A7E8A0106 +3F4F:204010A083184DF61000E3F8220823F800001010FFFE10101FF010101FF01010 +3F50:48884850480049FEFC5049FC48544BFE485479FC485048D849547A5248500050 +3F51:4BFE48504BFE4A52FE524BFE480049FC790449FC490449FC48207BFE48200020 +3F52:00107C10549054907CFC549055107C101010FEFC12101210221022104AFE8400 +3F53:010011001FF821005FF00100FFFE081048507E7C489088107E7C08100F10F0FE +3F54:28102810AA506C7C2850FE901010307C4A109C102C10DAFE2900C8C0283E1000 +3F55:010001003FF821083FF821083FF800007FF8000810081FFE0002000200140008 +3F56:004000407C40544055FC544454447C4454445484548454847D04450402280410 +3F57:002000207C2054205420542054207C2054505450545054887C88450402040402 +3F58:004000207C0055FC5400540054F07C9054905490549054927C924512010E0200 +3F59:004000407C805488550457FE54027C9054905490549054907D124512020E0400 +3F5A:00003FF8210821083FF8210821083FF8000011003FF841000100FFFE01000100 +3F5B:008000807D0055FC5604540455E47D245524552455E455247C04440400280010 +3F5C:10001EF8228862A894920882307EC0003FF8210821083FF8210821083FF82008 +3F5D:7F0408441E44224454440844300CC0001FF0111011101FF0111011101FF01010 +3F5E:00003EF82288228822883EF8000000003FF8210821083FF8210821083FF82008 +3F5F:0004001E7DE054225512549454807C0855FE5408548854487C48440800280010 +3F60:002000207C2057FE5420542055247D24552456AA542054507C50448801040202 +3F61:00400080F9FCA924A924A9FCF924A944A9FCA890A910FBFE8810001000100010 +3F62:00400080FBFCA910AA48AC46FBF8AA48AA48ABF8AA48FA488BF800420042003E +3F63:00140012F810AFFEA810A810FBD2AA52AA52AA54ABD4F80888EA071A02260042 +3F64:008000807CFE5502562254AA54727C2255FE5422547254AA7D224422000A0004 +3F65:000000FC7C48543055FE545254947D105630542055FE54707CA8452402220020 +3F66:08202AA44D28145022887FFE400280043FF8210821083FF8210821083FF82008 +3F67:00840044F848ABFEA884A884F908A94AAA52AB9CA884F9088908025203DE0042 +3F68:01080088F890ABFCA840A9F8F840ABFEA880A900A9FCFA208C20082003FE0000 +3F69:00400088F9FCA908AA52ABFEF850A988AE26A8C0AB10F8648B88003000C00700 +3F6A:01040088F800ABFEAA22AAAAFA72AA22ABFEA800A9FCF90489FC010401FC0104 +3F6B:0100FFFE104824FE799010FC22907CFC089030FEC0803FF821083FF821083FF8 +3F6C:0000FEFE00007C7C444444447C7C0000FEFE92929292FEFE92929292FEFE8282 +3F6D:000001FCF820ABFEAA22A9ACF820A9ACA800ABFEA820F9FC895401540154010C +3F6E:0FE009200FE009200FE07C7C54547C7C54547D7C11001FF821005FF00100FFFE +3F6F:022203FEF890A9FEAB10ADFEF910A9FEA910A9FEA900FBFE8A8A037602520276 +3F70:0000777C55145514551077105550555C55507750555055505550B55089BE1300 +3F71:008000401FFE1000900852085208120832085208923813C82208200840088008 +3F72:008000401FFE1000900057FE50801100320053F8900810082008200840508020 +3F73:008000401FFE1000900057FC5040104030405FFE904010402040204041408080 +3F74:008000401FFE10009010501057FE101030105210912010A0204020A043188C06 +3F75:008000401FFE1000904050405040104037FC504090401040204020404FFE8000 +3F76:008000401FFE1000900053F850081008300853F8920012022202220241FE8000 +3F77:008000401FFE1040904050445768117031605150925012482444284241408080 +3F78:008000401FFE10009040504053FC1244344850A090A01120212022224422881E +3F79:008000401FFE1000901C53E05200120033F85288928812502420245048889306 +3F7A:008000401FFE100097F8510851101120313C5204928812502420245048889306 +3F7B:008000401FFE1040904057FC5040104037F85208911010A0204020A043188C06 +3F7C:008000401FFE1000900457E45024102433E45204940417E42024202441448084 +3F7D:008000401FFE10409040504057FE1040304053F8920812082208220843F88208 +3F7E:008000401FFE1000904052485248124833F85048904014442444244447FC8004 +3F7F:008000401FFE1000901C53E052901290329052909290128824C824A448D49092 +3F80:010000803FFE20002080A0806FFC208020806080BFFE2100221044084FFC8404 +3F81:008000401FFE104090505048504017FC30E05160915012482444284240408040 +3F82:008000401FFE108090805110520817FC3204500093F812082208220843F88208 +3F83:008000401FFE1080904057FC54041808320052109260138022002204420481FC +3F84:008000401FFE10009040504057FC14443444544497FC14442444244447FC8404 +3F85:008000401FFE1040905C53E05240124033FC504490C4115422482C4040408040 +3F86:008000401FFE1040904053F85248124833F8524892481FFE2208220842288210 +3F87:010000803FFE20002000A7F86408240827F86408A40827F82408440847F88408 +3F88:008000401FFE100091085108510812FE320856489A2812282208220842288210 +3F89:008000401FFE1040904050A0511012483426502093F81008211020A040408020 +3F8A:010000803FFE20402040AFFE604027FC24446454A4E8215022484C4640408040 +3F8B:008000401FFE11109110521052FE16103A385238925412542292221042108210 +3F8C:008000401FFE10009040524053FC144030405FFE91201120212022224422981E +3F8D:008000401FFE100090005FFE5040108037FC54A494A414A424A424A444948408 +3F8E:008000401FFE1000900057BC54A414A434A454A494E414042404240447FC8404 +3F8F:008000401FFE1000904057FC504010403FFE5000904017FC204020405FFE8000 +3F90:008000401FFE100090045FC45214121437D454549A5411942084210442148C08 +3F91:008000401FFE104090A0511052081DF63000500093F812082208220843F88208 +3F92:008000401FFE11009100511E5FD2125232525452949212922112229E44528840 +3F93:008000401FFE100093F0521053F0100037F8540897F8140827F8240844288410 +3F94:008000401FFE1000900053F85208120833F8500097FC14042404240447FC8404 +3F95:008000401FFE1080904057FC520811103FFE5040904017FC2040204040408040 +3F96:008000401FFE1000900057FC544417FC344457FC904017FC204020404FFE8000 +3F97:008000401FFE1100908057F8540817F8340857F8948214442428251046088406 +3F98:008000401FFE100097FC504053F8124833F8524893F812402140208043608C1E +3F99:008000401FFE1010972050C0513016883FFE5100924017F82A48226842508040 +3F9A:008000401FFE1120912455E85530152235A25E1E900013F8200020004FFE8000 +3F9B:008000401FFE100093F8500851F8100833F8500097FC140423F8211040E0871C +3F9C:008000401FFE10009040504057FC1040324852489554184220A0211046089806 +3F9D:010000803FFE20803FFCA0806FF828882FF86888AFF820803FFE408040808080 +3F9E:010000803FFE20002FFCA1206FFC292429246A1CAC042FFC280448044FFC8804 +3F9F:008000401FFE10009040527C524012403FFE5040914412482410206043809C00 +3FA0:008000401FFE10009880557C52101D103110517C93101D10211021104A7E8400 +3FA1:008000401FFE1100911E57D2511211123FF251129292145A2FD4245040108010 +3FA2:008000401FFE104090405FFE504012483248555498E2115022482C4640408040 +3FA3:00803FFE20802140A2206410280837F66080A0802FF82080249042A05FFE8000 +3FA4:008000401FFE1080904057FC540411103208540493F810402040204047FC8000 +3FA5:008000401FFE1000920053BC521412143FD45014920816882A4822144A148422 +3FA6:008000401FFE1080904057FC520811103FFE500093F812082208220843F88208 +3FA7:008000401FFE100093F8524853F8124833F8504097FC10E0215022484C468040 +3FA8:010000803FFE20802FF8A140622024103FFE6010A7D0245027D0401040508020 +3FA9:008000401FFE1000903853C050401FFE31505154975811542354254C40408040 +3FAA:008000401FFE104092485454586213803FF8520893F8120823F8220843F88208 +3FAB:008000401FFE104093FC5204520413FC320053FC9354155425FC29544144810C +3FAC:008000401FFE1000942457A854321522361E510093FC120423FC220443FC8204 +3FAD:010000803FFE20002310AE10625422543F586690A6102B282A28524442448282 +3FAE:008000401FFE1040908053F8520813F8320853F8900017FC204023FC40408FFE +3FAF:008000401FFE100093F8524853F8124833F8500097FE12442228229043088206 +3FB0:010000803FFE2200223CA2246FA4223C22246FA4A8BC28A42FA448C440548088 +3FB1:010000803FFE20402F50A1246A1824083BF66120A1202FFC212042244424881C +3FB2:010000803FFE22102F90A21E6FA422243FD46414A7942488248848944AA49142 +3FB3:010000803FFE288024FCA12464203850298C6100BFFE2210272040C043308C08 +3FB4:008000401FFE1040904057FC51501248344653F8920813F8220823F842088FFE +3FB5:008000401FFE120091085FC850081788303E5788900817882488248847888488 +3FB6:00803FFE200023F8A20863C822482FFE6802B3FC220823F8220843F842088218 +3FB7:00803FFE2000203EAFC0687C28402BFE6A42AA782AC42A3C320054F06494890C +3FB8:008000401FFE102097FE500051F8110831F8500097FE140225FA250A45FA8406 +3FB9:010000803FFE21202128A5B065242524259C6E40A04027FC20E0415042488C46 +3FBA:010000803FFE200027FCA44067F8244027F86440A7FC20042AA44AA450148008 +3FBB:008000401FFE1010972855445582167C3510551095FE15102754249245528420 +3FBC:010000803FFE200029F8A50865F821083DF86524A5182548258445044A0091FE +3FBD:010000803FFE20402880A5F8610821082DF86500A5FC2504250445FC4A0091FE +3FBE:008000401FFE120891105FFE512017FC31245FFE912417FC2330252859268120 +3FBF:010000803FFE22002100AFBE68A22FA428A86FA4AA2229222AAA4CA448208020 +3FC0:010000803FFE20202E2EA42464A424A424A46EAEA424242424444644588E8100 +3FC1:008000401FFE108093F8520853F8120833F8508097FC1210244829F640408040 +3FC2:008000401FFE11109550555057DE102437D45114911417D4210821084FD48022 +3FC3:008000401FFE12A892A857FC52AA14E6380057FC944413F82248224842588040 +3FC4:010000803FFE20002FDCAA146BD42D1629206FDCA9142A942C5448084FD48022 +3FC5:010000803FFE22102410A89C7090229025FE6C10B490249C24904550463E8400 +3FC6:00801FFE1000103893C0504017FC315052489486104017FC20A223144D488186 +3FC7:008000401FFE100097BC508454A4129434A4510093FC120423FC220443FC8204 +3FC8:010000803FFE22282224A57E69482E4822FE6548A9482F7E22484448487E9040 +3FC9:00803FFE204027FCA44467FC20403FFE6404A7FC240427FC240447FC42088404 +3FCA:00803FFE20002F78A2106A502F7C26306B54B28C27F8240827F8440847F88408 +3FCB:00801FFE100013F8920853F8100037BC54A497BC10401FFE215022484C468040 +3FCC:00803FFE20802140A22064103BEC20006F78A94829482F782220455048889104 +3FCD:010000803FFE2000287CAF1471242FCC2AA86FBEAAC82F882AFE4A885088A188 +3FCE:00801FFE104017FC91505FFE111037FC540497FC140417FC240427FC41108208 +3FCF:00803FFE200027F8A0886FFE210827F86310A4A02FFC304023F840404FFE8040 +3FD0:00803FFE2210223EAF4462A822103FA8625EA2222A542B082A104A605600A3FE +3FD1:00803FFE20002FBEA492628A2492222067FEAC2037FE242027FE442047FE8400 +3FD2:00803FFE20402FFCA04067FC20003FFE6002A7F820403FFE20084F7E49488F18 +3FD3:00803FFE204027FCA2486248255428A26318ADF6211021F02240427C454088FE +3FD4:010000803FFE200027FCA44467FC244427FC6000AFBE2AAA2FBE4AAA4FBE88A2 +3FD5:00803FFE20002F3CA9246F3C29242F3C69E4AA242C442B642A244B644A248BEC +3FD6:00803FFE2040207CA04067FE244225F86444A4FC24A824F824A849FC495493FE +3FD7:00803FFE20002300BCFE64103F7C2E44757CA4442E7C2A442A7C53285244A082 +3FD8:00803FFE22082AAAA248651428A22FFE6802A3F8220823F8200047FC440487FC +3FD9:010000803FFE200023F8A2A863F820002FBE6AAAAFBE20402FFE40A043188C06 +3FDA:00803FFE20002FFEA9126FFE2228244469FEAF48227E25482F7E4048557E9540 +3FDB:00803FFE20002FBEA514671C25542FFE6920AFFC29242FFC2A244BB85222A39E +3FDC:00803FFE210027F8A54864A827F8221067F8BD2E27F820002FFC49244FFC8924 +3FDD:040008003FF8200820083FF8200820083FF8020004000820101020087FFC2004 +3FDE:1008103C21E07C204420443C45E044207C20443E47E0442044227C224422001E +3FDF:1020102020407CFC44844484448444847CFC44844484448444847C8444FC0084 +3FE0:1040104422447948495048404FFE48907890489048904892491279124A0E0400 +3FE1:020004001FF010101FF010101FF00000244814500C601450644808421042603E +3FE2:00007CFC448444FC7C8444FC44847D14020808003FF820083FF820083FF82008 +3FE3:100013F822087BF84A084BF849004BFC7C444A444AA44A044BF4780448280010 +3FE4:1040104023FC784049F848804BFC49107A084DF64910491049F07910491001F0 +3FE5:1040104023FE7AA2489049FE49104B107DFE4910491049FE4910791049FE0100 +3FE6:08007F7808483E4800863E782A483E30404884861FF010101FF010101FF01010 +3FE7:102013FE202079FC48004BFE480249FC78204BFE48004BFE48047BBE4AA4038C +3FE8:100013FE22227ACC4A444BEE4A444AEE7B544A444A104A104A5E7A504A5005FE +3FE9:112410A823FE7A0248F848884BFE4AAA7A724BFE48204BFE48207FFE4AA40452 +3FEA:0820082008207F7849284A2848287EA84268422852584C48444A4A8A92862102 +3FEB:208020843E9820E42684387C00801FFC1084108817F01210212020C043301C0E +3FEC:08000800087C7F5449544A5448547E54427C424052404C4044424A42923E2000 +3FED:0C107010401040FE40927E94489048FC58A448A44CA84AA84890492889440282 +3FEE:1010101010107CFE54925494549054FC54A4FEA410A810A82890252845448282 +3FEF:010006C01830EFEE00001FF010101FF001003FFC21042FE82420424041809E7C +3FF0:201010100010FEFE00922894449082FC04A444A428A810A82890452885440282 +3FF1:100C11F0FD0011FE1D10F2101210341001003FFC21042FE82420424041809E7C +3FF2:10101010FE1010FE28924494FE9004FC74A454A454A874A85490052815440A82 +3FF3:082A082A08547F54492A4A2A482A7E0042FE429252924CFE44924A9292FE2082 +3FF4:10101010FF1024FE429281947E9024FC3CA424A43CA824A82E90F52805440682 +3FF5:080008FE08107F2049FE4AAA48AA7EAA42A2429652104CFE44104A2892442082 +3FF6:20101010FE1000FE44922894FE90A2FC10A4FEA420A83CA82490452855448A82 +3FF7:441024102810FEFE10927C941090FEFC20A43EA448A848A88E90792821440282 +3FF8:087C0844087C7F44497C4A0048FE7EAA42FE420052FC4C4444284A1092682186 +3FF9:10101210117C7C1054FE504453287DFE4510657C591049FE5510951022FE0400 +3FFA:7F0841087F08417E7F4A224A7F48227CFFD422544954AAD41C482A8849141822 +3FFB:00001FF0010001000100FFFE0100010001003FF82448244824482448FFFE0000 +3FFC:00003FF808200820FFFE082010202020402000003FF8244824482448FFFE0000 +3FFD:0440082010102FE8C40608000FE00020014000803FF8244824482448FFFE0000 +3FFE:020001007FFE400280043FF001000100050002003FF8244824482448FFFE0000 +3FFF:00007FFC0104110011F81100290047FE80003FF82448244824482448FFFE0000 +4000:100009F841082508092811107102110210FE00003FF8244824482448FFFE0000 +4001:0200FFFE04000FF018102FF0C8100FF00810083000003FF824482448FFFE0000 +4002:01007FFC40040400FFFE08201E4003C03C3800003FF8244824482448FFFE0000 +4003:00007FFC02000D08719002A00CC071A006981A86E1003FF824482448FFFE0000 +4004:020001007FFE42028924284849940E1077F000003FF8244824482448FFFE0000 +4005:20201020FC2009FC102038205420902013FE100000003FF824482448FFFE0000 +4006:01003FF80108FFFE01083FF801007FFC0000110826D01830E00E3FF82448FFFE +4007:1080108011FCFE20102011FC7C20452445247DFC00003FF824482448FFFE0000 +4008:7DFC44207D2045207DFE505048905512620E00003FF8244824482448FFFE0000 +4009:00701F800200FFFE082037D8C4463FF8200827C8244827D800003FF82448FFFE +400A:27BC14A4929444A4404011B02E4EE390206023882070038000003FF82448FFFE +400B:210021FE2220243EF82023FE22AA225223263A52E2AA43FE00003FF82448FFFE +400C:01003FF80108FFFE01083FF801007D7C11107D7C44447C7C44447FFC2448FFFE +400D:1040FEF82948FE3001CE7CF844207DFC44887CF81088FEF810503FF82448FFFE +400E:000003FE7C40444044807C80450045FC7C044404440444047C04440400280010 +400F:100010001FFC200420045FE490241FE410241FE410241FE41024000400280010 +4010:00087E084210422042447E044208421042227E424204420442087E10422000C0 +4011:000001F87C8844C844A87CA8448844507C504450442044207C50448801040202 +4012:0008003C7DE0442044207C20442047FE7C204420442044207C20442000200020 +4013:004000407C40444045F87C48444844487D4844C8444844A87CAA450A02060402 +4014:000000007DFC444444447D44454445447D444644444444847C84450402280410 +4015:000403E478244824482479E4490449047A044BE4482448247824482401440084 +4016:000000007DFC442044207C20442047FE7C204420445044507C88448801040202 +4017:0040004078404BF848487848484848487BFE484048A048A07910491002080406 +4018:000003FC789048904890789048904FFE78904890489048907910491002100410 +4019:00000100797E49124912791249D24F12791249124952499279224822004A0084 +401A:1FF010101FF010101FF010101FF000000C0070FC408440844C84709440880080 +401B:01000100790049FC4AA47CA448A4492479244A444C44488479044A0404280010 +401C:080008001FF82248444808881128221004001FF010101FF010101FF010101FF0 +401D:00100110791049124912791449D84910791049104910491279524992010E0000 +401E:001001107C90449044107D10449044907C10441E47F044107C10441000100010 +401F:0090009078904BFC489478944BFC4A907A904BFE48924892791A491402100410 +4020:00007CFC4484448444847CFC4484448444847CFC4484448444847CFC44840000 +4021:002000207C204420443E7C20442044207DFC4504450445047D04450401FC0104 +4022:00400040788048FC49207A20482048207BFE4820485048507888488801040202 +4023:00000040782048284808788848904A947AA24AA24CC2488879884A8804780000 +4024:102010203F304128A224142208203020DFF010101FF010101FF010101FF01010 +4025:0008001C7DE0450045207D20452045FE7C20442044A844A47D22462200A00040 +4026:00200020782048204BFE78204820482079FC4904490449047904490401FC0104 +4027:01100110791049104BFC79104910491079104FFE4800491079084A0804040804 +4028:0008003C79E0482048207BFE48204820782049FC490449047904490401FC0104 +4029:0080008078F849084B107CA0484048A079184A064DF849087908490801F80108 +402A:00800080793C4A004C807880497E4B087D084908490849087908490801280110 +402B:0040004078A049104A087C064BF8480078004BF84A084A087A084A0803F80208 +402C:0040004078A049104A087C064BF84840784048404BF848407840484007FE0000 +402D:002000107C1045FE44207C24444444F87C124422444445887C10442800440182 +402E:008000407BFC49004900790049F8480079504950495049507A504A520452080E +402F:004800447BFE484048407BFC4A444A447BFC4A444A444BFC7A444A4402540208 +4030:0088788449024A2248207850488849047A0249FC490449047904490401FC0104 +4031:0080008079F849104AA0784049B04E4E79F0484049F048407FFC484000400040 +4032:0100010079FC4A004DF87908494849287BFE49084A484A287BFC480800500020 +4033:002000207BFE4820482079FC4924492479FC4820487048A879244A2200200020 +4034:000003FC780049244A487C904A48492478004BFC484048407840484007FE0000 +4035:00200040788849044BFE7882488049FC7A2048204BFE48207850488801040602 +4036:008000407BF84A084A087BF84A084A087BF84A404A444A287A104A8803060200 +4037:00880088788849C8489E788A488A4BEA788A488A490A494A7BEA4912002A0044 +4038:080C08F07E8008800EFE78880888290812081FF010101FF010101FF010101FF0 +4039:0020002078204BFE482078204924492479244AAA482048507850488801040202 +403A:108020FC6910AA9028602890230C00001FF010101FF010101FF010101FF01010 +403B:0020002079FC492449FC792449FC48007BFE4880490049FC7804480400280010 +403C:000003FC7A004A004AF87A004A004BFC7AA04AA44AA84A907A904C8804A408C2 +403D:0004000E7BB8488848887928492E4BA878A84AA84AA8493E79004A80047E0800 +403E:0000FEFC104420287E10A2283EC600001FF010101FF010101FF010101FF01010 +403F:0104010EF130912097E0F120913E9164F1A4972491249124F124912405440284 +4040:1FF010101FF010101FF010101FF0080C08F07E8008800EFE7888088829081208 +4041:004000207BFE4800480079FC49044904790449FC482048A879244A2200A00040 +4042:7EFC48447E4442287E1048287EC600001FF010101FF010101FF010101FF01010 +4043:002000207BFE4820482079FC482048207BFE484048A449A87A904C8800C60080 +4044:0020002079FC482048207BFE4888485079FC482048204BFE7820482000200020 +4045:000001FC7808481048207BFE482048A0784049FC495449547954495407FE0000 +4046:004000807BFC49104A487C464BF84A487A484BF84A484A487BF848420042003E +4047:020001007FFE4202A96C49940E1077F000001FF010101FF010101FF010101FF0 +4048:104008403E7E228823503E20205841869FF010101FF010101FF010101FF01010 +4049:104808443E7E23C022243E282212206A41869FF210101FF010101FF010101FF0 +404A:000003F87948491048A0784049B04E0E79F8490849F8490879F8490801F80108 +404B:0048014879484BFE494879484978490079FE48204BFE487078A8492406220020 +404C:000003FE7A224BFE4A227BFE480049FC790449FC490449FC7904490401140108 +404D:00140012F01097FE9410F41095D09412F41295D495549548F5DA942A08461082 +404E:004000207BFE480049FC790449FC48007BFE4A0249FC48207820482000A00040 +404F:000003FE785048504BFE7A524A524BFE780048404FFE48887990486000D80304 +4050:008800887BFE488848A8782049FC4924792449244BFE48207850488801040202 +4051:000001F8790849F8490879F848004BFE790049FC4A544C9479244A4400A80110 +4052:000001F87908490849F878004FFE490879F8490849F84908793E4FC800080008 +4053:000000887A524A224A527A8A4A024BFE788849444A7A48887950482000D80706 +4054:001E03E078444924488879FC484048407BFE488048FC494479284A1000680186 +4055:000003FC7A044BFC4A207BFE4A104A8A7B0648004BFC4A047BFC4A0403FC0204 +4056:0020012478A848204BFE78A849244A0278404BFE488849087990486001980604 +4057:002001247924492449FC78004BFE480079FC4904490449FC7888485003FE0000 +4058:0008003C7BC048044A44792849FC4A2078204BFE482049247924492401FC0004 +4059:000001FC790449FC490479FC48204BFE7A0248404BFE48887990486000980304 +405A:000001F87908490849F878004BFC4A047BFC4A044BFC4A047BFC489001080204 +405B:002000407BFC4A244A247BFC4A244A447BFC484048A848B4793C49220222041E +405C:000001FC7D0445FC45047DFC442045247CA8442047FE44907C9045120212040E +405D:08202AA42CA84920145022887FFE40029FF410101FF010101FF010101FF01010 +405E:082014502288082014502288FFFE08001FF028104FF088100FF008100FF00810 +405F:0108008878904BFC484079F848404BFE7880490049FC4A207C20482003FE0000 +4060:011000A078004FFE48A07BF848A84FFE78A84BF848A049B07AA84CA600A000A0 +4061:000003DE7A524BDE4A527BDE4A024A227A224A224A524A4A7A8A4A02020A0204 +4062:02100110F11097BE9240F20093BE928AF28892A892AE92A8F4A895A8085E1080 +4063:00207BFE482049FC492479FC492449FC78224BFE48084BFE7908488800280010 +4064:004000207BFE488848507BFE4A224AFA7A224AFA4A8A4A8A7AFA4A02020A0204 +4065:000003FE7A484A484BFE7A484A204BFE7A404AFC4B444A447A7C4A0003FE0000 +4066:0040007C78404BFE4A427A784BC44A3C7A004AFC4A844AFC7A844CFC048409FE +4067:008800887BFE488848F8782049FC492479FC482049FC48207BFE485000880306 +4068:0200011EF7D2901297D4F45497D89014F7D29092911291DAF714911005100210 +4069:0040004078F849084A1079FC4924492479FC4924492449FC78004954012A022A +406A:02000202E23CAFA0A220EFA0AABEAFA4EAA4AFA4A224AFA4E224A24402440284 +406B:000001FC792449AC4974792449FC482079FC48204BFE48007AA44A5204520000 +406C:0104008878004BFE4A227AAA4A724A227BFE480049FC490479FC490401FC0104 +406D:002800247BFE4850488879044A024998795449104BBE49107AA84AA804440882 +406E:000007BCF108952897BCF31895AA9946F00093F892089208F3F89208020803F8 +406F:004000A0F11896E69000F3F8920893F8F00097BC908494A4F29494A402940108 +4070:000000FEF0109720927CF2449244927CF244927C93C49E44F07C902800440082 +4071:0020002079FC48204BFE79084B9C490879884E3E48004BFE789048900112020E +4072:000003FE7A524A524BFE780049FC490479FC490449FC490479FC488801040202 +4073:008800887BFE488848247BFE4850488879044A8A48884BFE7888488801080208 +4074:00400FFEF00097FC9404F5F4951497FCF00093F8920893F8F20893F800000FFE +4075:000001FC7954495449FC78004BFE480079FC490449FC48627894498802A400C2 +4076:01080208F7C8945097DEF46497D49214F11497D4921493C8F2489454055408A2 +4077:0A803138228838382288393822887FFE40029FF410101FF010101FF010101FF0 +4078:009003FCF29493FC9294F3FC900093FCF20092F8920093FEF520951405480986 +4079:001003C87A7E4A404A627BD44A004A3E7BC84A484E7E4A487A484BC802480008 +407A:000001FC795449FC482079FC48204BFE7888485049FC48207BFE482000200020 +407B:044404E4E8A8AAAAAEEEE4A4AAAAAEEEE242A040AFFEA0E0E150A2480C460040 +407C:01FC792449AC492449FC782049FC48207BFE49544A2A482079FC482003FE0000 +407D:01240248792448004BFC7A944A644A947BFC4A484B684A487B6A4A4A02460362 +407E:010807FE790848004BFC7A944A944BFC78284BFE4A204B247AA84A92042A08C6 +407F:7F146B125D107F7E08107F100828FFA855449FF210101FF010101FF010101FF0 +4080:011007FCF04093F89040F7FC900093D4F11297FE93509534F38C908A02960102 +4081:01F00210F7FC920493FCF22493B89222F1FE921097FC9244F3FC90D0014A063E +4082:07BC04A4F7BC94A497BCF4A497BC9120F3FE922097FC9A20F3FC922003FE0200 +4083:003C07C0F244912897FCF4A497FC9008F78894FE978894A8F798950805A80690 +4084:03DE7A524BDE4A524BDE78A049FE4B207DFC492049FE480079FC48880070078E +4085:044404E4EA0AAEEEA404EAEAAE0EA0E0EAAAAAEAA040A7FCE444A7FC00440FFE +4086:00407C400440287C10840884FF041A4428242824480448048804080428281010 +4087:00007CFC0424282410240824FE241AFC28442844484448448844084429FE1000 +4088:00107C10041028FE10920892FE921A9228FE289248104814881209FE28821000 +4089:0080F8BC0884510821FE1320FD20357C3190511051FE51109128112851442182 +408A:0080F8F8090853FE25121122FDFE344030A25354509853349054109253502020 +408B:100010FCFE4810307DFE44527C94111012307C2011FE50707CA8112412221020 +408C:0020F9FC0888505023FE1000FDFC352431FC512451FC502091FC102053FE2000 +408D:01FCF90409FC510421FC1088FDFC348833FE5088512452AA907010A851242060 +408E:0528FFBE094857BE231815AAFD4637FC320453FC520453FC920413FC51082204 +408F:200021FC3C445044904410441094FE88110010FC108428842484448440FC8084 +4090:2020202021247D245124912411FCFC2010201124112429242524452441FC8004 +4091:2048204820487D48514A916C1148FD48114811481148294A256A478A41068000 +4092:202020203C2053FE9020102011FCFE00100011FC110429042504450441FC8104 +4093:200021FC21047D0451FC91041104FDFC1104110411FC2850249044924112820E +4094:2020202021FC7C20502093FE1088FC5011FC102010202BFE2420442040208020 +4095:208020FC21047DF8500893FE1040FCA21334105810942B342452449043508020 +4096:0000FFFE020002100408040408000FF81808280848088808080808080FF80808 +4097:00400040FE401044104420483E5062606240A2C0234022443E442244003C0000 +4098:000003FCFD041144112420A83C8864886450A450242024203C50248821040602 +4099:0000007CFE441048104820503E4862486244A244224422683E50224000400040 +409A:00080088FC501020105020883D0064086488A488245024503C20245020880306 +409B:000001F8FC081050102020103DFE64226424A420242024203C20242020A00040 +409C:00200020FC2013FE102020203C2065FC6420A420242027FE3C20242020200020 +409D:00500048FC481040105E21E03C4064446444A448243024223C52248A23060002 +409E:0000FFFE040008001FF02810C8100FF001000100FFFE054009203118C1060100 +409F:080008007F7C094411441144257C42000000FFFE08001FF82808C8080FF80808 +40A0:00400040FC8010FC112022203C20642067FEA420245024503C88248821040202 +40A1:0008001CFCE01080108020803C8064FE6488A488248824883C88248821FE0000 +40A2:00400040FC7C1084118822503C2064506488A706246024103C0824C020200010 +40A3:00900090F8902290229242D47A98CA904A904A904A904A927AD24712020E0000 +40A4:00880088FC881108117E23083D0865486528A528250825083D08250821280110 +40A5:000001FCFD041104110421FC3D20652065FEA520252025103D12254A21860102 +40A6:00200020FC501088110422123C2064406588A410242024443D88241020600380 +40A7:00800080FC8011FE110222043C2064206528A524262426223C22242020A00040 +40A8:0008001CFDE01100110021003DFE65106510A530251825143D12221002100410 +40A9:000001FCFD041124112421243DFC65246524A554254C258C3D04250421FC0104 +40AA:00900090FC901292119420983C9065986694A492249024903D1225122212040E +40AB:00800080F8FC21082290406079984E26C82049FC48204A207BFE482000200020 +40AC:00007DF01110119011521D12E20E44000000FFFE08001FF82808C8080FF80808 +40AD:00400020FC2013FE100020883D0466026488A488245024503C20245020880306 +40AE:080008007F7C08243E2408447F5408880800FFFE08001FF82808C8080FF80808 +40AF:00200010FC1011FE110021103D106510657CA510251025103D10221002FE0400 +40B0:004200E2FB82208A208A408A7BEA488AC98A49CA4AAA4A827C824882008A0084 +40B1:01040084FC88101011FC21043D04650465FCA450245024903C922512220E0400 +40B2:08207E2008FCFF24102424447E5422880100FFFE08001FF82808C8080FF80808 +40B3:00200020FCA810A810A821743E2264206420A5FC242024203C20242023FE0000 +40B4:00400020FDFE1000100020FC3C00640064FCA400240024FC3C84248420FC0084 +40B5:000001FCFC20102013FE20003C0065FC6504A524252425243D54248821040602 +40B6:00880088F88821C8209E408A788A4BEAC88A488A490A494A7BEA4912002A0044 +40B7:001C01E0FC20102013FE20203CA864AA67ACA4A824AA25AA3EA6242020200020 +40B8:00140012F81027FE201040107BD2CA524A524A544BD4480878EA471A02260042 +40B9:00200040FCFE1124129820503C6067806420A42424A424A83D30245020880306 +40BA:000001FCFD24112411FC21243D2465FC6420A7FE247024A83D24222200200020 +40BB:000000FCFC8010F8108020F83C8067FE6540A524252825103D08254421820100 +40BC:00200020F85020882144422279F84808C850482048A44A827A8A4A8A04780000 +40BD:00200020FC3E102011FC21043DFC650465FCA524242027FE3C20242020200020 +40BE:00200020F82023FE2020412479244924CAAA487048A848A879244A2204200020 +40BF:00200022FBB420A820A841247AA24840C9FC4904490449FC7904490401FC0104 +40C0:00200020FBFE202021FC40247BFE4824C9FC48404BFE488479C8483000CC0302 +40C1:000001FEFC481048104821CE3D0265026502A5CE244824483C48244821FE0000 +40C2:000001FCFD04110411FC21043D0465FC6400A51225D425183D1025522192010E +40C3:000003FEFA02228A225243FE7A424A22CBFE4A824A824A827AFA4A02020A0204 +40C4:00400020FBFE2000200041FC79044904C90449FC482048A879244A2200A00040 +40C5:01040088FC5011FC112421243DFC65246524A5FC242024203DFE242020200020 +40C6:00840084FDFE1084108420FC3C84648464FCA484248425FE3C00244820840102 +40C7:00200040FCFC108410FC20843CFC64206420A5FE252225223D2A252420200020 +40C8:01100112FDD41118115221923D2E644065FCA504250425FC3D04250421FC0104 +40C9:000001FCFD0411FC111021FE3D10654A6586A40025FC25043DFC250421FC0104 +40CA:00900090FBFC2090200041F879084908C9F84908490849F87908490807FE0000 +40CB:004000A0F910220825F640007BC44A54CA544BD44A544A547BD44A44025402C8 +40CC:000003FEFC50105011FC21543D54655465FCA420242025FC3C20242023FE0000 +40CD:01040088F80023FE204040C27922CA54489849384A5448947912461000500020 +40CE:00000040FBFE20882104464278FC4B08C8B048D04F3E48C27B24481800600780 +40CF:000001FCFD0411FC110421FC3C20652065FEA620242025FC3C20242023FE0000 +40D0:00400020FBFE2202208841047A224828C8244BFE482048507850488801040202 +40D1:0100023CF7A424A426A445A474C2DF8054BC54A456A455A474945488049409A2 +40D2:000003FEF80021FC2104410479FC4800CBFE4A8A4A524BFE7A224A22022A0204 +40D3:00880088FBFE208821FC40887BFE4820C9FC492449FC49247BFE490401140108 +40D4:00200010FDFE1102100020FC3C84648464FCA40025FE25023D02250221FE0102 +40D5:08202AA42CA84920145022887FFE40028004FFFE08001FF82808C8080FF80808 +40D6:00400080F9FC2104210441FC7900C9FE490049FE48024AAA7AAA440200140008 +40D7:000203E2F82221EA202A47FA788A4AAAC9CA488A49CA4AA27C924882028A0104 +40D8:000003DCFA9423D4225443C87A884A94CBE24800482049FC7820482003FE0000 +40D9:00400020FBFE2250225043FE7A52CA524BFE4A004A924AD47A98449204D2088E +40DA:04200220F23E2F4024A04420773CD5505510551055FE5510752859280B441082 +40DB:00100010FAFE2110217C4054787C4B54C97C491049FE491079104A90047E0000 +40DC:00007F7848485F4C64805F7844484A4851307F4C00007FFC08001FF868080FF8 +40DD:02080248F7482290229E4FE47114D2145FD45494591451C87F08511405140222 +40DE:08407F4022F83E4800483EC804487EAA08AA290612027FFC08001FF868080FF8 +40DF:02880288F7C82290229E4FD47024D7D4545457D4545457C874485454046404C2 +40E0:02100110F11027BE2240420073BED28A528852A852AE52A874A855A8085E1080 +40E1:000003DEF88822A823FE41887ADA4CA6C9F84908490849F87908490801F80108 +40E2:02100210F51024BE282247447210D2105F1052105AA85728722853440C440082 +40E3:000E03F0F8442224210843F87A08CBFC4A044BFE4A024AAA7AAA450204140808 +40E4:004003F8F04827FE204843F87040D554575C544457FC5444775C555405540844 +40E5:002001FCFC88105013FE20003DFC652465FCA52425FC24203DFC242023FE0000 +40E6:08407F40227E3E8801483E4804507E200850288C10007FFC08001FF868080FF8 +40E7:008079F84A884870538E492049FC6A2050F84020FFFE04000FF83808CFF80808 +40E8:000003BEF8A220A220BE43887A08CA3E4A2A4BAA48AA48BE7888408A057E0202 +40E9:005001FCFD5411FC115421FC3C0065FE6500A57C250025FE3D50255421480266 +40EA:002003FEF80023FC220442F47A944BFCC80049F8490849F8790849F8000003FE +40EB:010001F8FA0827FE228843247BFECA004AFC4A004AFC4A007AFC448404FC0884 +40EC:00400248FA4823F8208043F87A484BF8CA484BF8484848B478BC49220222041E +40ED:00140012F7FE241025D0441475D4D55855CA54165442582472A2528A04780000 +40EE:00100410F27C201020FE40447628D2FE5210527C521052FE7210521005FE0800 +40EF:00200040F8F8228A218C40F8798C4A8AC8F848204BFE487078A8492406220020 +40F0:00800040F7FE24022A2443BC74A4DAA8551052E854045BFA70405248044400C0 +40F1:01140112F7D2211021104FFE7290D6D2529256D2529456D4728A52CA0F160022 +40F2:010003DCFA542366224047DC7A544B48CA544CA248004BFC7A944A9407FE0000 +40F3:01240248F924200023FC42947A644A94CBFC4A484B684A487B6A4A4A02460362 +40F4:04100210F07A27122014477E7008D710503C576455A4553C75245724053C0024 +40F5:004007FEF00023FC224043F87240D3F8524053FC5004555470A853100D480186 +40F6:00400020FDFE100011FC21543DFC64206522A48C252224543CC8254422520060 +40F7:00400FFEF40027FC200047FC7404D7FC50805C9C57D45D54755C5C9615562E22 +40F8:0148014CFAAA200827FE41487B68494ACB6A494C4B6C4948796A4B9A00260042 +40F9:03DE0252FBDE225223DE42227AFA4A22CAFA4AAA4AFA4AAA7AFA4A7202AA0226 +40FA:002007FEF48827DE248845DC76AAD488545057DE545055DC74505BDE08501050 +40FB:03FE0020F7FE242221AC428077DED2925392511E57D2555277DE51120FD20126 +40FC:1020082008207E200420082808241C222A224A20882008200820082008200820 +40FD:202010201020FBFE08201020102039FC54849488104810501020105011881606 +40FE:201011101110F9120912111411D83910551095101110111211521192110E1000 +40FF:202010201020F82009FC10201020382055FE9420105010501088108811041202 +4100:209010881088F88008BC13C010803888548894901060104410A41114120C1004 +4101:204811481148F948094813FE1148394855489548117811001100110011FE1000 +4102:202010201020F82009FC112411243924552495FC112411241124112411FC1104 +4103:202010201020F9FC0924112419243524512493FE102010501050108811041202 +4104:200011FC1104F9240924112411FC392455249554114C118C1104110411FC1104 +4105:0100111009203FF802007FFC082010102FE8C0063FF801001110210845040200 +4106:2008103C11E0F820082013FE10203820542095FC110411041104110411FC1104 +4107:200011FC1104F904090411FC1000380057FE9420102011FC1020102013FE1000 +4108:200013FC1000F80009F811081108390855F89400110810881090100017FE1000 +4109:201010D81394F894089013FE10903894549490D81398109010AA10CA12861102 +410A:202010201020FBFE08201020102039FC5440942010A41282128A128A14781000 +410B:2020102013FEF85008881124122239FC552495FC112411FC10221022101E1000 +410C:400023DE2042F94A1084114A225234206800ABDE205221522094214822542422 +410D:208810881088FBFE0888108817FE380055FC9504110411FC1104110411FC1104 +410E:2020102011FCF8500888110413FE380855E89528112811E81128100810281010 +410F:2088108813FEF8880800101C19E03420502093FE102010501050108811041202 +4110:1000540054FC7C8492849284FE8400FC7C800080FE80108254829282507E2000 +4111:201C13E01220FBFE0A201292130A3A0655FC9504110411FC1104110411FC1104 +4112:202010201050F8880944122211F838085450942010A41282128A128A14781000 +4113:2020104011FCF90409FC110411FC380057FE9420102011FC1020102013FE1000 +4114:2004101E13E0F82009FC1124192435FC502093FE1222122A12FA1202120A1204 +4115:2020102213B4F8A808A8112412A2384055FC9524112411FC1124112411FC1104 +4116:404020A02110FA0815F6100023C432546A54ABD42254225423D42244225422C8 +4117:405022522252FA5213DE1202220233FE6A02AA0223DE22522252225224522802 +4118:2020101011FEF884084811FE11023A24541095FE1040107C1044108410941108 +4119:200013FE1202F80009FC110411FC390455FC9440102013FE1000108811041202 +411A:4090209027FEF89013FC129423FC32946BFCA80021F8210821F8210821F82108 +411B:202011FC1124FBFE092411FC102039FC552495FC104013FE108811D01070138C +411C:2040102013FEF80009541124195435FC502093FE1242129212FA120A12021206 +411D:2020102013FEF82009FC10401BFE348851049242159C110411DC110411FC1104 +411E:4100211023DCFA5415541288210832F46C02A80023FC20402150224825442080 +411F:01F03E0003F03E0003FA7E0201FE0C20703C1DE2F0221C1E0000FFFE11102308 +4120:202013FE1000FBFC0A0412F412943BFC540095F8110811F8110811F8100013FE +4121:208010F81108FBFE0944119211FE3900557C9500117C1100117C1244127C1444 +4122:4080204027FCF91010A41F58255435526B58A800220823F8220823F822082408 +4123:202013FE1020F9FC080013FE12523BFE550495FC110411FC110411FC10881104 +4124:4108210827CEF912112417DE2552355E6FD2A91E2392255E2940211421122122 +4125:47FC20402FFEF84213581040235830006EEEAAAA2EEE20002FFE224825542FFE +4126:04000EFC780408080810FF20082018201C202A202A2048208820082008A00840 +4127:04000E0079FC08440848FF480850185E1C422A422A8248828882090209140A08 +4128:08001DFCF02010201020FC20102033FE38205420542090201020102010A01040 +4129:04200E28782408240820FF2E08F018201C202A202A2048108812080A08060802 +412A:08401C40F08010FC1104FE041004310438845444544490041004100410281010 +412B:04000E0078FC08040804FF04080418FC1C842A802A80488088820882087E0800 +412C:08201C20F0201120112CFD34116433A439245534552891221122110210FE1000 +412D:08081C3CF1E010201020FC20102033FE38205420542090201020102010201020 +412E:08201C20F020102011FCFC201020382035FE5420505090501088108811041202 +412F:04000EFC784808480848FF48084819FE1C482A482A4848488848084808880908 +4130:08001DFEF00810881088FC88110831FE38185428544890881108120810281010 +4131:08401C20F02013FE1080FC80108030FC38845484548490841104110412281410 +4132:08201C20F02011FE1122FD22112231223952554A558A910211021102110A1104 +4133:08201C20F02011201120FD20113C312039205520552091201120112017FE1000 +4134:08001CFCF08410841084FCFC10843084388454FC548490841104110412141408 +4135:00701F80010001007FFC054009203118C00601001FF011001100FFFE01000100 +4136:08901C90F09013FC1094FC9413FC3A90369053FE50929092111A111412101410 +4137:08001C00F3FE10201020FC40104038FC35845284548490841084108410FC1084 +4138:08201C20F04011FC1104FD041104310439FC5504550491041104110411FC1104 +4139:00F83F0001007FFC092011102288CC643018C1E61F000100FFFE010001000100 +413A:08201C20F3FE102011FCFC2411FC312039FE5422542A90541050108811041202 +413B:08901C90F09012921194FC98109031983A94549254909090111211121212140E +413C:08001DFEF02010201020FDFC112431243954554C558C91041104110411FC1104 +413D:08001DFCF05010501050FDFC1154315439545554555C91841104110411FC1104 +413E:08281C24F024102013FEFC2011243124392457A8552891101212122A14461082 +413F:08201C20F1FC11241124FDFC1124312439FC542054249018103210CA13061002 +4140:08021C02F3E2110A110AFDEA112A3A2A372A52AA544A904A10821102120A1404 +4141:01007FFC40040400FFFE08201E4003C03C3801E01F0001007FFC05401930610C +4142:08801C80F0F811081310FCA0104038A03518520655F891081108110811F81108 +4143:00007DF01110119011521D12E20E440000E01F0001007FFC05401930E10E0100 +4144:08401C40F1FC10441084FC8411283210390857DE554A914A114A1252135A14A4 +4145:08201C20F1FC10201020FC2013FE30003820542055FC90201020102013FE1000 +4146:08101C10F210113E1122FC441010389034905310512891281128114410441082 +4147:00007FFC04403FF8244824483FF8000000E01F0001007FFC05401930E10E0100 +4148:0100111009203FF802007FFC082010D02F08C1061FF005400920111061080100 +4149:08001DFEF04810481048FC481248314A394A554C544890481048104813FE1000 +414A:08401C20F3FE12001200FE0C12F032203A20563E53E0922014221422181E1000 +414B:08801C80F0F811081210FDFC11243124392455FC54509050109010921112120E +414C:08001CFCF084108410FCFC0011FE3102390255FE5502910211FE1102110A1104 +414D:08001C06F3B810881088FD08113E3B88348852885288913E11001280147E1800 +414E:081C1DE0F020102013FEFCA81124322239F85488549090BE1102110212141408 +414F:08001DFCF104110411FCFD00111831E0393855E0553C91E011221222121E1400 +4150:08001DF8F108110811F8FD08110831F83908550855F89090109011121212140E +4151:08081C3CF3C010441224FD28110030403BFE5488510893901060105011881604 +4152:08901C90F3FE10901090FC40102033FE39005500550091001100110011F81000 +4153:12003A00E23C27D42454F854275435546D546554A74825482048205422942122 +4154:08921C92F12412481124FC921092300039FE5522552291FE1122112211FE1102 +4155:08001DFEF102110211FEFD10111031FE39105510557E914211421242127E1442 +4156:08201C20F3FE10501088FD24122231FC392455FC552491FC10221022101E1000 +4157:081C1DE0F020102013FEFCA811243A42344053FE5088910810D0103010481184 +4158:08201C20F02013FE1020FD24112431243AAA547054A890A81124122214201020 +4159:08001DFCF104110411FCFD04110431FC3800551255D49118111011521192110E +415A:08201D24F0A8102011FCFC4013FE3888350452FA5488908810A810921082107E +415B:08FC1C84F08410FC1084FC8410FC300039FE5502550291FE1102110211FE1102 +415C:08081C3CF1E0102013FEFCA810A830A83BFE54A850A893FE1020102011FC1000 +415D:08401C20F02013FE1202FC9411083204380055FC542090201020102017FE1000 +415E:08001DF8F10811F81108FDF8100031FC381057FE541091101090101010501020 +415F:00401848708411FE1020FBFE108831243A425588501090621184101810601380 +4160:08001DFCF104110411FCFD04110439FC340053FE50209120113C112012A0147E +4161:08001DFEF020104011FCFD04110431FC390455FC5504910411FC100010881104 +4162:08201C20F3FE122213FEFE2213FE300039FC550455FC910411FC110411141108 +4163:08201C40F1FC110411FCFD0411FC30003BFE5420542091FC1020102013FE1000 +4164:08081C3CF1E010201020FDFE102030A0392C5524552491AC1124112411FC1104 +4165:08001DFCF10411FC1104FDFC108031FE3A2255225552910211FA100210141008 +4166:08881C88F3FE10881088FC0011FC31243924552455FC91241124112411FC1104 +4167:08401C20F3FC10001108FC9013FE300039F85508550891F81108110811F81108 +4168:081C1DE0F020102013FEFCA81124322239FC5504550491FC1104110411FC1104 +4169:08201C20F3FE102011FCFC881050302038585586540091FE110211FE10841102 +416A:08201C20F1FC112411FCFC2013FE300039FC5504552491241124105010881304 +416B:08401C20F3FE10001000FDFC110431FC390455FC542090A81124122210A01040 +416C:09041C84F088100013FEFC00108831043A0255FC555491541154115417FE1000 +416D:08201C10F1FE10841048FDFE11023224381055FE5440907C1044108410941108 +416E:08201C20F050104810A4FDFE128430FC388454FC548090FC11441144127C1044 +416F:08201C10F1FE1110117CFD1411FE3114397C5510557C914411441244127C1444 +4170:08001DFCF124112411FCFD241154318C390455FC5440902010A4128A128A1478 +4171:08201D24F124112411FCFC0013FE300039FC5504550491FC1088105013FE1000 +4172:08401C44F1F8105013FEFC4010F831823A7E540055FC910411FC110411FC1104 +4173:08801C80F1FC12441154FDF4108431283A9055FC5244955411F4108411281210 +4174:0020182073FE102013FEFA42148C31F03820544453FE90221128122414A41040 +4175:09041C84F088100013FEFC20102039FC3420542053FE900012A4125214521000 +4176:08001DFEF100117E1100FDFE1154314839645542550491FE114412241204140C +4177:08881C88F3FE108810A8FC50108831743A22542055FC902010A8112412A21040 +4178:08881C88F3FE10881040FC2011FC3888345053FE5020902011FC102010201020 +4179:08201DFCF12413FE1124FDFC102031FC392455FC504093FE108811D01070138C +417A:08001DFCF05011FC1154FD5411FC300039FC540057FE902010A8112412A21040 +417B:08401C20F3FE10001154FD24115439FC342053FE5242929212FA120A12021206 +417C:08001DF8F10811F81108FDF810003BFC369453FC500091F81090106011981606 +417D:08007F7808483E4800863E782A483E30404881E41F0001007FFC05401930610C +417E:00001BDE708812A813FEF98812DA34A639F85508510891F81108110811F81108 +417F:08881FFEF088100011FCFCA810A833FE38A854A855FC902013FE102010201020 +4180:08001DFCF12411AC1174FD2411FC382035FC502053FE900012A4125214521000 +4181:08001DFCF15411FC1020FDFC102033FE3888545055FC902013FE102010201020 +4182:10203BFEE288225023FEFA5022FC32546BFE6254A2FC225022D8255426522850 +4183:211017FC004073F8120813F812082FFE400001E01F0001007FFC05401930610C +4184:08101DFEF00011FE1102FD7A114A39FE340054FC508490FC108410FC100011FE +4185:0A201D3EF04210941310FD28104631FC390455FC550491FC110411FC10881104 +4186:08F81C88F08810F81000FDDC1154315439DC542057FE907010A8112412221020 +4187:1000E7FC248425E42524FDE4252435E46D0465F4A50425F42414255625562832 +4188:1000E4FE228222FE2080F8AA2E9C32AA6A8062A8A2BE22C822BE2288250828FE +4189:10003BFCE294229423FCF910225233DC681263CEA24023D2225C23D0225222CE +418A:00941B987092118E1280F9FC112431FC392455FC508891FC108813FE10881104 +418B:108039F8E20827FE2252FBDE2050335E695267DEA152235E215027D22152233E +418C:0394191077BE111813AAFD46102033FE380057FC500093FC100013FC120413FC +418D:12103910E7DE2010245EFA8227DE30106FDE6450A7DE245027DE2450245224CE +418E:1148394CE2AA200827FEF9482368314A6B6A614CA36C2148216A239A20262042 +418F:09241CA8F3FE10A81326FDFC112431FC392455FC548893FE108817FE11041202 +4190:01001FF002007FFC082037D8C1063FF811107D7C2020FEFE5454BABA10105454 +4191:020001007FFE400288241010200800007FFC0100010001000100010005000200 +4192:020001007FFE40028824121022081FE002200A200420062009221022201E4000 +4193:020001007FFE4002882411102208044008201FF004500440044008441044603C +4194:020001007FFE48229114210801003FF82108210821083FF82108010001000100 +4195:020001007FFE4822911401003FF0011001100110FFFE0280044008203018C006 +4196:020001007FFE48229014220802007FFC0400048008801100222044108FF80408 +4197:020001007FFE48229014200800007C8844884488448844987CE8448800080008 +4198:020001007FFE4822901420081FF0111011101FF0111011101FF0111001000100 +4199:020001007FFE4822901400007FFC01000100110011F8110011001100FFFE0000 +419A:020001007FFE4822901400003FF820082FE8200827C82448244827C820082018 +419B:020001007FFE482290140000001879E048404840487E4BC0484078444844003C +419C:020001007FFE4822941404007FFC08001FF028104FF088100FF0081008500820 +419D:020001007FFE400288241010210802003FF824482448244824482448FFFE0000 +419E:020001007FFE482290141FF010101FF010101FF0000010F01F00100410040FFC +419F:020001007FFE4822911422880C603018CFE600001FF01010101010101FF01010 +41A0:01007FFE4822901400003FFC210021003FF8200820083FF8210021003FFC0000 +41A1:020001007FFE4822921401001FF010101FF010101FF011081090126014181806 +41A2:020001007FFE482290141040FDF810481448184833FED04010A0111052082406 +41A3:020001007FFE4822901400003FFC20002FF820003FFE2908289048604A188C06 +41A4:01007FFE4822901402001FF010101FF010121FF410187FF001900E10F0500020 +41A5:020001007FFE482290147FFC02000D08719002A00CC071A006981886E2800100 +41A6:020001007FFE482291140910092012C0043019086914091012A004401830600C +41A7:01007FFE482290741F8001007FFC05401930E10E04007FFC08201C4003807C78 +41A8:01007FFE482290141FF010101FF010101FF000003FF801007FFC04401830E00E +41A9:01007FFE482290141FF010101FF010101FF010101FF002007FFC04401830E00E +41AA:1040102095FC550458501088FD04280028F828202820282029FC4800480287FE +41AB:01007FFE4822901408001FF82A4844480A88110822A8041001004884481287F2 +41AC:01007FFE482290140FE008203FF820083FF820083FF820083FF8082010102008 +41AD:01007FFE4822901408007F7C08107F1049107F1049FE7F100810FF9008100810 +41AE:01007FFE4822901423F8100811F8800843F8500017FC2404E3F8211020E0271C +41AF:01007FFE4822BEFC12480C3032C800003EF812480C3032C8FFFE082007C07838 +41B0:020001007FFE482290143FF8200027F0241027F020002F7829482F7820003FFC +41B1:020001007FFE482290142040124890B04108460410402244E44820A023182C06 +41B2:01007FFE482291143FF820802FF820883FFE20882FF824C422A8449858868180 +41B3:01007FFE4822901423FC10801144066870B01128166810A4112416A0284047FE +41B4:01007FFE48229FD410403FF051101FF011103FF821083FF821083FFA010200FE +41B5:020001007FFE4822901408207FFC511449247FFC00001FF010101FF010101FF0 +41B6:01007FFE4822911408801FFC30805FF810801FF810801FFC1000248822444244 +41B7:01007FFE482290141FF002207FFC04887A8001003FF8282837D8244827C82018 +41B8:020001007FFE482290947EA00444282817D02008DFF610101FF0082004407FFC +41B9:01007FFE49229FF404407FFC00001FF011101FF011101FF001003FF80100FFFE +41BA:01007FFE4822901400F83F0011100920FFFE09203018DFF611101FF011101FF0 +41BB:020001007FFE482290147C200420FF3E22443EA422283E282390FE2842440282 +41BC:01007FFE4822901421F8110811E8012873FC120412F4129412F412142A0847FE +41BD:01007FFE482291FC01003FFC21042FE021082FF823002C9023605CD843469CC0 +41BE:01007FFE482290143F2024203F3E21403F5024883F0800003FF824482448FFFE +41BF:01007FFE4822905409FC490449FC490479FC090409FCF8204BFE48A849248A22 +41C0:01007FFE482290142200FF7E22243E3C08247F24493C7F240826FF7C08040804 +41C1:01007FFE4822901420443E2844FEFF1049107F7C49107F1000FE55104A908A90 +41C2:0200010001007FFC00001010082004400000FFFE010001000100010001000100 +41C3:1000080008FC7E8400840484448444FC2484288028800E82F0824082007E0000 +41C4:1040084008407EFE00800500447C44082410282028400E80F102410200FE0000 +41C5:1050084808487E40005E05E0444044442444284828300E22F052408A03060002 +41C6:1008088808487E4800080488444844482408280E29F80E08F008400800080008 +41C7:200011FC1104FD04010409FC8920892049FE4920512051101D12E14A41860102 +41C8:200011FC1084FC880050082088D88B064820482051FC50201C20E02043FE0000 +41C9:2000100013FEFC2000200840884088FC49844A84548450841C84E08440FC0084 +41CA:202010101010FDFE010009108910891049104920512851241E44E2FE44420800 +41CB:10200820087C7E840148043044284448259E282228420EA4F018401000600180 +41CC:2020112410A4FCA8002009FC8904890449FC4904510451FC1D04E10441140108 +41CD:200011FC1104FD04010409FC882088204920493C512051201EA0E260443E0800 +41CE:204810481048FDFE0048084889FE880048FC4884508450FC1C84E08440FC0084 +41CF:2040102013FEFC0001FC090489FC880049FC4808501053FE1C20E02040A00040 +41D0:2020102011FCFC2400240BFE8824882449FC4A22517450A81D24E22240A00040 +41D1:2040108011FCFD24012409FC8924894449FC4890511053FE1C10E01040100010 +41D2:7DFC44207D2045FE7C5048525492650E020001003FF8000008200440FFFE0000 +41D3:0BFE104061FC090411FC610405FC090431FCC088030401003FF808200440FFFE +41D4:0100FFFE20003FF800003FF820083FF80200711C57D47014545C729651D6B622 +41D5:000021FC102013FEFA2201AC082089AC88004BFE502051FC1D54E1544154010C +41D6:104010403F7E48908508080008001FF821084108020802080408180860500020 +41D7:104010403F7E2890450880000440082010102108C2060400082010103FF81008 +41D8:104010403F7E2890450880007FFC04000FF00810082010201FC00040FFFE0000 +41D9:20403F7E4890850800007F08010801083F08200840087F08010801080A080408 +41DA:104010403F7E4890850800000840084010403050504890441044104010401040 +41DB:104010401F7E28902488450881000100110011F81100110011001100FFFE0000 +41DC:204020407EFE5110880808000FFC10042108410001000280044008203018C006 +41DD:104010403F7E2890450880400420040004FEFF000210016001840E447034000C +41DE:104010403F7E4890850810101010FFFE101010101FF01010101010101FF01010 +41DF:104010403F7E28904508902010203E2022FC4224A42414440844108421144208 +41E0:104010403F7E28904508820001007FFC010001003FF8010001000100FFFE0000 +41E1:204020407EFE51108A0801007FFE400280043FF8010001000100010005000200 +41E2:104010403F7E2890450881000100FFFE010001001FF01010101010101FF01010 +41E3:104010403F7E489085080280044009203118C106010009201110210805000200 +41E4:20403F7E489085080000FFFE010001007FFC4104428444444824400440144008 +41E5:104010403F7E4890850800007FFC01000100110011F8110011001100FFFE0000 +41E6:104010403F7E2890450881001FF0111011101110FFFE0280044008203018C006 +41E7:104010403F7E489085080000FFFE01003FF8210822882448282820083FF82008 +41E8:20403F7E4890850808001FF0282007C01830E10E1FF0010011001FF801000100 +41E9:104010403F7E4890850801003FF821083FF821083FF8010800B001C20E32700E +41EA:104010403F7E4890850800007FFC040008201FF0011001003FF801000100FFFE +41EB:20403F7E4890850800003FFC2080208027F82408240827F8208020803FFE0000 +41EC:104010403F7E48908508110011003FF841000100FFFE054009203118C1060100 +41ED:20403F7E48908508020002083FD00220FFFE0100061008E03F00C808080807F8 +41EE:104010403F7E489085080810087813C0304050409FFE10401040104017FC1000 +41EF:104010403F7E2890450880007FFC10101FF010101FF01010103EFFD000100010 +41F0:104010403F7E4890850800001FC000447D88055009203118C50602003FF80000 +41F1:104010403F7E4890850800003FF8220823C824482A882108228824083FF82008 +41F2:104010403F7E4890850801003FF8010011100920FFFE0280044008203018C006 +41F3:104010403F7E28904548822003F87E0003F03E0003FCFE20014000840764781C +41F4:104010403F7E489085080000FFFE04403FF8244824482848303820083FF82008 +41F5:104010403F7E48908508200C11F01100810049FE49101110E110221022102410 +41F6:20403F7E4890850808001FF020205FF811081FF811081FF81108210821284010 +41F7:20403F7E489085083F04210421243F24082408247FA408A410A4108422944108 +41F8:104010403F7E289045089FF0101010101FF000003FF801001FF001007FFC0000 +41F9:20403F7E4890850800003FF80408FFFE04083FF808001FF8280848088FF80808 +41FA:20403F7E4890850800007FFC00001FF0101010101FF0000008200440FFFE0000 +41FB:20403F7E489085083FF820083FF8200020702F8020F02F8020F85F824082807E +41FC:20403F7E489085081FF010101FF000003FF8210821083FF8200220021FFE0000 +41FD:104010403F7E48909508100C11F0FD00110011FE1D10F1101110121052102410 +41FE:104010403F7E4890850801007FFC00003FF800003FF800003FF820083FF82008 +41FF:20403F7E489085080100FFFE01003FF8210821083FF8238805601918E1060100 +4200:104010403F7E489085083F842A842A942A94FFD42A942A942A942A8420942188 +4201:20403F7E4890850802800C6037D8C0063FF8248824883FF82488248824A82010 +4202:104010403F7E48908508101008207FFC082008200820FFFE0820082010202020 +4203:20403F7E4890850823FC10841084808449144A0815FCE1042104210421FC2104 +4204:104010403F7E289045089FE040445194492443C445444924551442047FFC0004 +4205:104010403F7E4890852800907FFC00803E88228822503E5000240754788C2104 +4206:20403F7E4890850800803FFC200420043FFC20A020902FFC2120421044089806 +4207:20403F7E48908508010001FC01003FF820083FF820083FF80100FFFE01000100 +4208:104010403F7E489085083EFC22A422A43EA422FC22803E80228222824A7E8400 +4209:204020407EFE51108A0801003FF80820FFFE04007FFC08201C4003800C707008 +420A:20403F7E4890850801003FF80100FFFE1010220847E40820144003801C70E00E +420B:20403F7E4890850801047D9809603118C50602001FF010101FF010101FF01010 +420C:20403F7E48908508100009F80908410821F82908090811F87108110817FE1000 +420D:20403F7E489085080080FFFE10001FF800001FF010101FF010101FF010101FF0 +420E:20403F7E4890850812207FFC122013E010001FF80100FFFE05401930E10E0100 +420F:20403F7E4890850800007FFC00001FF010101FF000003FF821083FF821083FF8 +4210:104010403F7E48909548104013FE5880549051109152125414A8102810441082 +4211:20403F7E489085081FF010101F9010907FFC40044FE4482448244FE440144008 +4212:20403F7E489085080100FFFE01003FF8244822882FE821083FF8210821282010 +4213:104010403F7E489085081FF010101FF010101FF008001FFC2104528414541FE8 +4214:20403F7E489085087CF8440844087CF8400041F87C88405040207C5040884306 +4215:20403F7E489085081FF010101FF010101FF000007FFC110011F8290047FE8000 +4216:20403F7E489085080C10709010501010FC903050381E55F05010901010101010 +4217:20403F7E4890850809100A0817FC31105208948411F813081490106011981606 +4218:20403F7E4890850808200440FFFE1020102024487CF80810102024487EFC0204 +4219:104010403F7E4890850810001008240879FE100824887E48004854084A288A10 +421A:20403F7E48908508080010103FF800081FF0101010101FF001004884481287F2 +421B:20403F7E4890850808000F7C084408447F44552855287F105510552855444382 +421C:20403F7E489085080BF8080811F8300853F8900017FC140413F8111010E0171C +421D:20403E7E4890BFFC010411F011002FFE40009FF010101FF010101FF010101030 +421E:20403F7E4890850800807FFC00001FF010101FF000003FF820083FF820083FF8 +421F:204020407EFE511088083F0421243F2421243F24212421243F24120421144088 +4220:20403F7E4890850800FC7F00220811103FF80200FFFE04000FF0122021C0CE3C +4221:20403F7E4890850808001FF82A4844480A88110822A8041001004884481287F2 +4222:20403E7E4890900020087FFC00043FF820083FF80100FFFE054009203118C106 +4223:104010403F7E4890850800207F20043E044427A42428242824102F28F0444082 +4224:20403F7E4890850810881088FC8813FE3088388854F854889088108810F81088 +4225:20403F7E4890850810101F1022107FBEA4923F9224923F92249224A242AA8144 +4226:20403F7E489085082448238824483FF81010220847E40820144003801C70E00E +4227:20403E7E489080F87F00221011201FE010201FF010101FFC20042AA44AA4800C +4228:20403F7E4890850800007DF8450849F8510849F8452445285510494841864100 +4229:20403F7E489085080804140422245D248024112409244A2427A4F80440140008 +422A:20403F7E489085087FFC00001FF010101FF000007FFC482444445FF44104410C +422B:20403F7E489085081020102025FC7D2409241154254C7D840104550455148108 +422C:20403F7E48908508404427FE204087FC444457FC1444E7FC2444244424540408 +422D:204020407EFE51108A0804003FF821083FF821083FF8029004A808FA308AC07E +422E:20403F7E489085082080108010FCFD0402F44894489448F410941E04F0284010 +422F:20803EFE4910BFF801001FF010101FF010101FF010101FF01010FFFE08201010 +4230:20403F7E489085081020112410A8FC2011FC11041DFCF10451FC110451142108 +4231:104010403F7E4890850800FC7F00220811100C20307820083C7820083FF82008 +4232:20403F7E4890850810783E4822482A862300FEFC22442A44222842104A2884C6 +4233:20403F7E48909FF810081FF810081FF800007EFC224412240A1412246AD40408 +4234:20403F7E48908508102008407FFC04803FF00490FFFE04903FF00CA03498C486 +4235:20403F7E4890854808203218C4460FE000207EFC224412240A1412242A544488 +4236:104010403F7E4A9085087FFE400289241290244808203FF8C82608200FE00820 +4237:20403F7E48909508108010F8FD08129030603998560651F89108110811F81108 +4238:20403F7E4890850810041F2422147F84A4A43F9424863FBC2484248442848104 +4239:20403F7E489085087FFE48028BF4108033F85208920813F81208120813F81208 +423A:20403F7E48908508104010FC24887D50082010D827067C60001054C054308008 +423B:20403F7E48908508002878244BFE482079FC492449FC792449FC49244924990C +423C:20403F7E50908A0801007FFE42028924284849940E1077F00100210821083FF8 +423D:20403F7E4890850808207FFC08200FE001003FF821083FF801007FFC0100FFFE +423E:20403F7E4890850810201124FCA8102031FC390455FC910411FC110411141108 +423F:20403F7E489085087FFC40041FF010101FF010101FF00100FFFE082010102008 +4240:20403F7E4890850800803FFC222022203FFC2220222023E020004A4849249124 +4241:20403F7E489085080010FF9022283E4422923E08227C2384FE08023002080204 +4242:20403E7E48909FF011101FF011101FF0040008201FC003103FF8112025104208 +4243:20403F7E489085080440247C24A83D50042804487DFE24882448244844088418 +4244:20403F7E4890850878404BF8504067FC51104A884CF4691052A0404041B04E0E +4245:104010403F7E4890954810407C4011F8FE48444828C87C4810AAFEAA11061202 +4246:20403F7E489085081FF010101FF010101FF010001FFC10001FFC492484940008 +4247:20403F7E4890950811047FC411241F2411241F2411247FE42924308420143FC8 +4248:20403F7E4890850824207E20243EFF4400A47E2442287E2842107E2842444682 +4249:20403F7E4890850820003E1C44E87EA8AAA83EA82AA83EA82AA42B542B744612 +424A:20803EFE551088201FF00210FFFE09203FF8D1161FF011101FF001007FFC0100 +424B:20403F7E4890850811FC1124FDFC2500257C4944297C1144297C4644827C0444 +424C:20403F7E4890850878904BFC48805144566848B049284E6868A4512246A04040 +424D:20403F7E489085087C7C44447C7C44447D7C40844A244A14525441C440144008 +424E:20403F7E48908508111009203FFC20044FE808200FE001007FFC05401930610C +424F:20403F7E4890850810001EFC22247F44A99C3F50297C3F9029FE291045108210 +4250:20403F7E489085081020FE2010207DFC54207C2054F87C881088FE8810F81088 +4251:20403F7E4890850810003FFC4AA00AA07FFC0AA00AA07FFC0000248822444244 +4252:20803EFE491080F83F0011100920FFFE09203018DFF611101FF011101FF01010 +4253:20403F7E48908508100011FC1124FDFC312439FC542053FE90A8112412221020 +4254:20403F7E5090880800900088FBFE20483C3245CE4890A88813FE10482032C1CE +4255:20403F7E48908508082004403FF8292825483FF800001FF010101FF010101FF0 +4256:20403F7E4890850808107F1008287F4449927F08497C7F040808FFB008080804 +4257:20403F7E4890850811F81108FDF8100013FC11081DF8F10811F8110E57F82008 +4258:20403F7E489085081040102013FEFA0214FC300039FE542050A8912412A21040 +4259:20403E7E4890BFF801007FFE41029D7401001D7000003FF80000FFFE10103FF8 +425A:20403F7E489085083FF824483FF800007FFE4002BFF408000FE0112416A4181C +425B:20403E7E489084003FF8292825482FE8254828280100FFFE02800C603018C006 +425C:20403F7E4890850820A020907DFE9120132011FCFD2011FC2920252041FE8100 +425D:20403F7E4890951808203FF801007FFC02403C500848FFFE08507E240854198C +425E:20403F7E4890850800283FFE20202FA420282F9048AA4FC682820900282847E4 +425F:20403E7E4890812011FC1320FDF8112015F8192031F8D10013F8111050E0271E +4260:20403F7E4890850822204AA08ABE1FC420A46F24A0282F28291029A829443082 +4261:20803EFE4910FFFE00003FF8200827C824483FF810101FF010101FF00000FFFE +4262:20403E7E489081007FFC11102928FFFE00003FF8200827C8244827C820083FF8 +4263:20403E7E489082001CF010101EF010101FF008001FFC20044924249424944008 +4264:20403F7E4890850849202A20FF3E2A4449A41024FE282228641018282444C282 +4265:20403F7E4890854811FE1122FD7A118A155219223152D1FE104012A4528A247A +4266:20403E7E48908FF841402FF829480FF8E1002FFC24102BE8322423E052088FFE +4267:20403E7E4890F784428462A454A469A414242224DD2408247F244A042F94F008 +4268:20403E7E4890900008787F48224814867F0010FC694416446D281490642818C6 +4269:20403F7E48908508100013FE1200FE7C1244327C3A0056EE52AA92EE120013FE +426A:20403F7E489085083FF821083FF821083FF80000FEFE9292FEFE9292FEFE8282 +426B:20403E7E48908640387C08947E241C442A94490802C01D30E92E054009201310 +426C:20803EFE491080803FFE20202F2831102A0A277C294A378428784F484130874C +426D:20803EFE49109084210810843FF82448238824483FF829482528294A25263182 +426E:20403E7E4890FC7C44447C7C44447D7C44844FE459044FC449044FC449044FEC +426F:20403E7E4890BF7C24443F2821103F2824463FF010101FF010101FF008201010 +4270:20403E7E4890BE2022103AFE2A007F2841443E8222283E2822103E2822442682 +4271:20403F7E4890A508100003FEFA000A7C12442A7C7200AAEE2AAA22EE220023FE +4272:20403E7E48908000F7FC124817FCFC4686EC8554F6EC155416EC144454542408 +4273:20403F7E4890850820443E2844FEFF1049107F7C49107F1000FE55104A908A90 +4274:20403F7E489085087FFC00003EF822883EF804403FF80440FFFE04901C60671C +4275:20403F7E48909FF8149012501FF00200FFFE0AA03458CFE6155007C004A00670 +4276:20403E7E4890A4483F7E64C8BF7E24483F7E24483F7E20401FF0082007C0F83E +4277:20403F7E489085081E7812483FFC20202E20223C3FC829282F2849905F288144 +4278:204020407EFE5110880841102788F83E53942008FBBE2008739C228843888288 +4279:20403E7E4890BFF801007FFE492284143BB82AA83BB800007FFC11102928FFFE +427A:080008004AFC2A202C200820FE2018201C202A202A2048208820082009FE0800 +427B:1004101E95F0551059101110FD1031FE3910551055109108110A114A11861102 +427C:0804080E4AF02A802C800880FEFE18881C882A882A8848888888090809080A08 +427D:10201020952454A458A81020FDFC30203820542057FE90201020102010201020 +427E:044004447C78044004421C42E43E0000111009207FFC054009203118C1060100 +427F:1008103C95E05420592410A4FCA8302039FE5420542090201020102010A01040 +4280:10201020942054205BFE1020FC20302039FC5504550491041104110411FC1104 +4281:10201120952055FC59201220FC2033FE3890549054909090111211121212140E +4282:1020102097FE5420582011FCFD2431243924552C547090A81124162210201020 +4283:200027FC2404AC0475F42444FC4425F475546D54AD5425542574244624462842 +4284:00007DF01110119011521D12E20E4400111009207FFC054009203118C1060100 +4285:1040104094FC55045A881050FC203040388055FC568490841084108410FC1084 +4286:04003878200820083C78200820083FF80000111009207FFC054009203118C106 +4287:1028102495FE5420582011FCFD24312439FC5524552491FC112411241124110C +4288:1080108094FE55005AFC1084FCA430943BFE54845524911411FE100410281010 +4289:1040102095FC55045A281020FC2031FC3870546854A890A41124122210201020 +428A:100011FC9504550459FC1100FD1C3170391C5570551E91F0111011121112120E +428B:1048114895485548594811C8FC7E30483BC855485548914811481148125C1440 +428C:10201010941055FE59001148FD4A314A396C55485548914A114A126A12461400 +428D:0C8070FC1124FD2412243844548491281010111009207FFC054009203118C106 +428E:1020112494A8542059FC1040FDFE3088390456FA5488908810A810921082107E +428F:102010A494A4552858501088FD043024382054A854A891301050108811041202 +4290:100011FC9504550459FC1104FD0431FC3800551255D49118111011521192110E +4291:1020112494A454A8582011FCFD04310439745554555491541174110411141108 +4292:10A01090948055FE59101310FDFC3110391055FC55109110111011FE11001100 +4293:100011FC9504550459FC1104FD0431FC380057FE54209120113C112012A0147E +4294:2088208823FEA88870A82020F9FC212471246924ABFE20202050208821042202 +4295:20102010207CAB1471FE2114FA7C2210777C6910A9FE25102210230024FE2800 +4296:2020202023FEA820702023FEFA8A225272FA6A22AA2222FA22222222222A2204 +4297:1020104095FC550459FC1104FDFC30003BFE5420542091FC1020102013FE1000 +4298:1020102095FE552259FE1122FDFE300038FC548454FC908410FC108410941088 +4299:0000FDFE204840487DFEC44844887D080008111009207FFC054009203118C106 +429A:20102220217CA9447044207CFB402140717C6944A944217C21442280247E2000 +429B:2000245C2294A91472942454F926210077DC6914AD9425542948210825142222 +429C:102013FE942055FC592411FCFD2431FC382257FE540893FE1108108810281010 +429D:101C11E09420552458A813FEFC7030A8392456225440902412A2128A14881078 +429E:2040202023FEA888705023FEFA2222FA72226AFAAA8A228A22FA2202220A2204 +429F:2088208823FEA888708820F8F82023FE72226B32AAAA237622222222222A2224 +42A0:7DFC44207D2045FE7C5048525492650E111009207FFC054009203118C1060100 +42A1:100011F8950855F8590811F8FC0033FC3A9457FC540091F81090106011981606 +42A2:0440247C24A83D5004287DFE248844488418111009207FFC054009203118C106 +42A3:1088108895FC5488588813FEFC2031FC392455FC552491FC1000108811041202 +42A4:100013FE945057FE5A5213FEFC0031FC390455FC550491FC102013FE10201020 +42A5:202021FC2024ABFE702421FCF82022AA73AE6A22ABFE222223AE22AA22AA2422 +42A6:102013FE942055FC580013FEFE0231FC380055FC550491FC1104108813FE1000 +42A7:209027FC2094ABFC729023FEF91223FA750E69F8A90821F8210821F820902108 +42A8:0100FFFE20003FF800003FF820083FF80100755C539477D4511473965556B122 +42A9:103C13E0952454A85BFE10A8FD24320239FC5524552491FC1124112411FC1104 +42AA:1088108897FE548859FC1124FDFC312439FC542057FE9222122A12FA120A1206 +42AB:200023FC2294AA9473FC2000F890279E70906890AB9C20902090279E20902090 +42AC:0DFC712411FC1124FDFC30203BFE54A851248222111009207FFC05401930E10E +42AD:102013FE942055FC580013FEFC0231FC382057FE540093FE100413BE12A4138C +42AE:200023DE2042AA52714A2252F890210873FE6D10A9FE211021FE211021FE2100 +42AF:1020101095FE5528597C1128FDFE3110397C5554557C9154117C120012441482 +42B0:22102110203AAB92701423BEF8082390703C6BE4AAA422BC22A423A422BC2024 +42B1:2148214C22AAA80877FE2148FB68214A736A694CAB6C2148216A239A20262042 +42B2:0010FE0828FEFE00AA44AA28FEFE108854A838BEFEC8108838BE55089108127E +42B3:202023FE2248ABFE724822ECFB5A224872506BDEAA5023DC225025DE24502850 +42B4:1088108894EE55545A221050FC8831743A0255DC555491DC1088108811541222 +42B5:104010402040244045F8F848104820484848FC480448004A548A548A81060200 +42B6:1020102020202520452CF934116423A44924FD34052801225522550280FE0000 +42B7:080808081008120822FE7C080818101824287E28024800885208490889280010 +42B8:100011FC200024004400FBFE104020404880FCFC040400045404540480280010 +42B9:1008103C21E024204420F820102023FE4820FC20042000205420542080200020 +42BA:100011FE204024404440F87C108420844884FD0405FC00085408540881FE0000 +42BB:104010402040247E4482F884112022204820FC50045000485488548481020200 +42BC:10101010201024904490F890109E20904890FC90049000905490549083FE0000 +42BD:10201020202025FC4424F824102420244BFEFC20045000505488548881040202 +42BE:102010202020242045FEF8201070207048A8FCA8052401245622542080200020 +42BF:102010202020242045FCF820102020204BFEFC20045000505488548881040202 +42C0:010000803FFC20043FFC2080211023E02040208827FC20444250444889440080 +42C1:10401020200025FC4400F80010F020904890FC900490009254925512810E0200 +42C2:080408441028121022287C440880100424447E44022800285210492889440082 +42C3:1008103C21E024204420F83C11E020204820FC3E07E00020542254228022001E +42C4:100011FC210425044594F954115421244924FD54055401945504550481140108 +42C5:101010102090249044FEF890111020104810FDFE041000105410541080100010 +42C6:10401020202025FC4504F904110421FC4904FD00050001005500560082000400 +42C7:100011FC210425044504F90411FC21204920FD20052001105510550882040402 +42C8:08007F7C114432280C101228634604201FC0018006103FF80108112025104208 +42C9:1040102020202BFE4A02F404100020904890FC90048801085508550482040402 +42CA:1000100021FE24104410F81010902090489EFC90049000905490549083FE0000 +42CB:100011FC210425044504F9FC1120212049FEFD20052001105512554A81860102 +42CC:100011FE210025004500F9FC110421044904FD0405FC01005500550081FE0000 +42CD:1000100021FE24084408F9E8112821284928FD2805E801285408540880280010 +42CE:1000100021FC25044504F90411FC21044904FD0405FC01045400540083FE0000 +42CF:10801080208024FE4540F9401240207C4840FC400440007C5440544080400040 +42D0:10281024202428204BFEF220122422244A24FA280A280290AB12AA2A80460082 +42D1:100011FE202024204420F9FE112221224952FD4A058A010255025502810A0104 +42D2:100011F8200824504420F81013FE206248A4FCA0052002205420542080A00040 +42D3:1080108020F825084610FC2011FC20044804FC0405FC00045404540481FC0004 +42D4:100011FE201024104420F820106820A44922FE22042000205420540083FE0000 +42D5:081813E0304057FC904013F8020004201FC0018006103FF80108112025104208 +42D6:1020102020FC242445FEF82410FC20204820FCFC0420002055FE542080200020 +42D7:100011FE212025204520F9FC110421044904FD0405FC01205520552081FE0000 +42D8:1020102023FE28204820F1FC102020204BFEF87008A800A8A924AA2284200020 +42D9:100013FE210825084508F9F81108210849F8FD080508011E57E8540880080008 +42DA:100013DE204228424A52F14A114A204248C6F94A0A520042A842A842814A0084 +42DB:10201020212424A444A8F820102023FE4870FCA804A801245524562280200020 +42DC:100008FC3E44222822103E28224644209FC0018006103FF80108112025104208 +42DD:10401024222425084508F810104020404BFEFC88050801905460545081880604 +42DE:100011FC210425044504F9AC115421544954FD5405AC01045504550481140108 +42DF:100011F82008240845F8F9001104210448FCFC40042000A4AA8AAA8A84780000 +42E0:1028102421FE24204420F9FC1124212449FCFD24052401FC552455248124010C +42E1:10201020205028884904F2FA102020204BFEF82009280124AA22AC2280A00040 +42E2:080C08F07E8008800EFE788808882908164808801F0002103FF8010815202210 +42E3:201020103F244044BEF8221032202A44FF7E221252104A547F52029214500820 +42E4:084008407F40087C3E840884FF04104422247C240904FF8408844904A8A81010 +42E5:100011FC2124252445FCF924112421FC4820FC2005FC00205420542083FE0000 +42E6:1080108020FE250046FCF88410A4209449FEFC840524011455FE540480280010 +42E7:100011FC2104250445FCF910111021FE4910FD10057C014455445544817C0244 +42E8:1040102021FC24004508F890100023FE4800FC0005FC01045504550481FC0104 +42E9:10001040239C2A044A04F39C120422044BFCFC9004900090549055128212040E +42EA:2000277E450445049574E554265445549554F55405741554AE04A40484140408 +42EB:1080108020F825084610F9FC1024202449FEFC24042401FC5424542080A00040 +42EC:100013FC204028404BFEF0A0111022084C46F84008480264AA52AC5281400080 +42ED:1040102023FE28804904F3FE100221FC4904FDFC050401FC5504550481140108 +42EE:10201020205024884504FA0210F820204820FDFC0420012454A454A883FE0000 +42EF:104808443E7E23C022243E282212206A444688821F0002103FF8010815202210 +42F0:1FF010101FF010101FF010101FF01010FFFE11102248CF8602201FF009481320 +42F1:1020102020202BFE4820F124112421244AAAF87008A800A8A924AA2284200020 +42F2:100011F02110291049F0F04013F822484A48FBF80A480248ABFAA8428042003E +42F3:1050105223DC245044D2FB4E100021FC4904FDFC050401FC5504550481140108 +42F4:100010FC2048243045FEF852109421104A30FC2005FE007054A8552482220020 +42F5:100011FC210425FC4504F9FC108021FE4A22FD220552010255FA540280140008 +42F6:100013FE2020244045FCF904110421FC4904FDFC0504010455FC540080880104 +42F7:00207E20247E18A4FF2829104A2898C6044008801F0002103FF8010815202210 +42F8:1008101C21F025104510F9FE1110217C4944FD7C0544017CA944AA44827C0444 +42F9:100013FE200029FC4904F10411FC20004BFEFA220A2203FEAA22AA2283FE0202 +42FA:108811C827082908492AF12A17AC21484B08FB880D540514A914A92481240142 +42FB:1020102023FE28204820F3FE128A22524AFAFA220A2202FAAA22AA22822A0204 +42FC:100011F82088249044FCF954112421544A88FC0005FC0154A954A95483FE0000 +42FD:21042104410447C4913EE10427C440249114F11407C41104A904A1C48E140408 +42FE:1000104023FE28884904F64210FC230848B0F8D00F3E00C2AB24A81880600780 +42FF:100011FC2124292449FCF124112421FC4800FBFE09200122A914A94881840102 +4300:10C41704212429144914F784112421144B94FB460D3C0504A904A90481040104 +4301:100013FE205028504BFEF252125223FE4800FC4007FE00885590546080D80304 +4302:100013FC220422044BFCFA0013FC22404A88FBFC0A241220ADFCA420882013FE +4303:1082108222A229CA488AF3EA122A222A4BEAFA2A0A2A03EAAA22AA2282AA0244 +4304:11FC102021FC25244554F904112C2020483CFC2005F800885450542080D80306 +4305:1020101021FE2510457CF91411FE2114497CFD10057C0144A944AA44827C0444 +4306:1020104023FC2A244A24F3FC122422444BFCF84008A800B4A93CA9228222041E +4307:1020102023FE28204BFEF242148C21F04820F8440BFE0022A928AA2484A40040 +4308:100011FC210429FC4904F1FC100023DE4842FA52094A00C6AB5AA842814A0084 +4309:100013FE22522A524BFEF000100023FE4820F820093C0120A920A92087FE0000 +430A:1008103C23C028044A44F12811FC22204820FBFE08200124A924A92481FC0004 +430B:1088108823FE28884820F050108821044AFAFC00040001FC5504550481FC0104 +430C:100013DE20422A52494AF2521042202049FCFD04050401FC5504550481FC0104 +430D:1088108823FE248844F8F82011FC212449FCFC2005FC002055FC542083FE0000 +430E:00407CF8554854307DCE54F854887CF8044008801F0002103FF8010815202210 +430F:1040102023FE2A424828F29412AA24CA48F8FB0008200124A924A92481FC0004 +4310:100E13F020442A244908F3FC120423FC4A04FBFC0A0403FCA890A91082120C0E +4311:100013DC22942BD44A54F3C8128822944BE2F800082001FCA820A82083FE0000 +4312:1040102023FE22504A50FBFE125222524BFEFA000A9212D4AA98A49284D2088E +4313:20783F48404CBE802A78FF284A107F28044408801F0002103FF8010815202210 +4314:100013FE22002A7C4A44F244127C22004AEEFAAA0AAA02AAAAEEAA0083FE0000 +4315:2040202047FE44909490E49027FC449094D8F5B805B416D4A892A89090900090 +4316:10A0109021FE2B2049FCF12011FC212049FEFD00042003FE547054A883260020 +4317:2100210043FC46A89AA8E2A827FC42A892A8F2A80FFE1000AAA8A25484540000 +4318:082049202A3E7F4849485DA86B104928454608801F0002103FF8010815202210 +4319:1088108821FC24884488FBFE102021FC4924FDFC052401FC5400548881040202 +431A:100013FE205028504BFEF252125223FE4924F8A80BFE0070A8A8A92486220020 +431B:10001E0C22F05420284410F82810FF2400FE7E1200507E5400927F1242507E20 +431C:10501252215428504BFEF088105023FE4820F9FC082003FEA8A8A92486220020 +431D:2110211047BC411093B8E5542912400093F8F00007FC1040AA48A44489420080 +431E:10201020205024884504FAFA1000200049DCFD54055401DC5488548881540222 +431F:101013C8227E2A404A62F3D41200223E4BC8FA480E7E0248AA48ABC882480008 +4320:02907FD0421E5EA242885D0855485ED4846208801F0002103FF8010815202210 +4321:109013FC22942BFC4A94F3FC100023FC4800FBFC0A0403FCA908A89087FE0000 +4322:100011FC20202BFE4A22F1AC102021AC4850F8C80B2600F8A808A8D080200010 +4323:1108110821EE2A944842F01011FE210248F8FC8804F8008054FC548480FC0084 +4324:200027FC424844449FFEE44426EC455496ECF44406EC1554AEECA44484540408 +4325:103E17C0224421284BF8F84017FC20004BF8F8080BF81008ABF8A544852A08FA +4326:100013DE20422A52494AF252109021084BFEFD1009FE0110A9FEA91081FE0100 +4327:102013FE202029FC4800F3FE100221FC4820FBFE080003FEA804ABBE82A4038C +4328:1088108823FE28884910F1DE125225544A88F9740A0201FCA820A92482220060 +4329:110817FE210828004BFCF294129423FC4828FBFE0A200324AAA8AA92842A08C6 +432A:13DE125223DE2A524BDEF242127A228A4B12FADA0A8A02DAAA8AAAFA820A0204 +432B:13D0129023DE2A684BC4F28413F8210849F8FD0805F8010855F854908112060E +432C:1110109023DE28104A5EF18213DE20104BDEFA500BDE0250ABDEAA50825202CE +432D:1088108823FE28A84890F1FE112023FC4D20F9FC092001FEA900AAA482520452 +432E:11FC102023FE2A2249ACF02011AC2000489EFBF2089E01D2AABEAC92809E0092 +432F:108813FE20882BDE4A52F3DE10A0209049FEF9200BFC0520A9FCA92081FE0100 +4330:13FC110821F8290849F8F10E17F820084FFEFA940B9C0294AB9CAAD687BC0084 +4331:40807FFC48008FF8A000EFF848084FF8A100FC9C15D45C14555C5C9695D62C22 +4332:108813FE208829F04820F3FE102021FC49ACFD7405FC002055FC542083FE0154 +4333:27FC224847FC4C4696ECE55426EC455496ECF454040817FCA840A3F8805007FC +4334:40807FFC48008FF8A000EFF848084FF8A220FD5C17F45C9455DC5C9697F62CA2 +4335:13FE120223FE2A924A54F29212FE22AA4AFEFB220AFA02AAAAFAAA2285FA0004 +4336:101010102010241045FEF810103020304050FC50409001101C10E01040500020 +4337:102010202020242045FCF924112421244124FDFC412401241D24E12441FC0104 +4338:10201020202025FC4420F84013FE20404080FDFC400400881C50E02040100010 +4339:100013FC220422044A04FAF4129422944294FA9442F402941A04E20442140208 +433A:100013FE2088248844F8F888108820F84088FC88408E03F81C08E00840080008 +433B:100013DE204220424A52F94A114A204240C6F94A425200421842E042414A0084 +433C:110410842088241045FCF9041104210441FCFC50405000901C92E112420E0400 +433D:1008103C23C020444A24F9281100202043FEF87040A800A81924E22244200020 +433E:1020102023FE20204820FBFE128A225242FAFA22422202FA1A22E222422A0204 +433F:100013FE200021FC4904F90411FC200043FEFA22422203FE1A22E22243FE0202 +4340:10901290229C22A04AD0FA88128820804000FBF842A802A81AA8E2A84FFE0000 +4341:10881448225020FC4820F850169422384250FA98423402541A90E22045FE0800 +4342:200020FC3C20502090201020FE2011FE10205420542054205C20642004A00040 +4343:000801FC7E0022081108111008001FF821000100FFFE0100210821083FF80008 +4344:202020203C205020903E1020FE20102011FC5504550455045D04650405FC0104 +4345:202020203C50505090881124FE12101011FC5404540854885C50642004100010 +4346:204020203C2051FE91021204FE00100011FE5420542054205C20642004A00040 +4347:2004201E3CE0500090101008FEFE100210045408541054205C4064A0051E0000 +4348:200021FC3C205020912410A4FEA8102013FE5420542054205C20642004200020 +4349:200020003CFC508490841084FE84108410FC5484540054485C44648404820102 +434A:204020203C2051FE90001088FF04120210885488545054505C20645004880306 +434B:2008203C3DE0502091FE10A8FEA810A811FE54A854A855FE5C20642005FC0000 +434C:204020203CFC500090881048FE5011FE1000540054FC54845C84648404FC0084 +434D:1000FE7810487C480048FE8682007CFC20443C445028FE28101054287C440182 +434E:408843FE7888A02023FE2250FBFE225223FEAA80AAFEAA80BAFECC020AAA0004 +434F:00003FF824482448244824483FF8200820082008200820082008200820282010 +4350:00007FFC444444447FFC00003FF8010001000100FFFE01000100010001000100 +4351:00003FF822282AA824482AA8312800003FF801000100FFFE0100010001000100 +4352:00007FFC444444447FFC010001007FFC03800540092011102108C10601000100 +4353:00007FFC444444447FFC00003FFC0040104020403FFE01400640184061400080 +4354:00007FFC444444447FFC020002007FFC0400048008801100222044108FF80408 +4355:00007FFC444444447FFC000000F03F00210021003FFC208020402A243114210C +4356:00007FFC444444447FFC08001FF020105F90109010901F901050102410040FFC +4357:00007FFC444444447FFC020001007FFC040008201FC0008003200C103FF80008 +4358:00007FFC444444447FFC01001110092005407FFC0540092011102108C1060100 +4359:00007FFC44447FFC10003FFC40009FF012101110FFFE221021103FFC00100060 +435A:00007FFC444444447FFC01001FF010101FF010101FF011081090126014181806 +435B:00007FFC444444447FFC00003FF821082FE8210827C8244827C820083FF82008 +435C:7FFC44447FFC090008801FFC108030805FF8908010801FF8108010801FFC1000 +435D:7FFC44447FFC000001047D9809603118C50602001FF010101FF010101FF01010 +435E:7FFC40044AA444444AA400500048FFFE00403E4022243E2800120E2A70C60302 +435F:7FFC44447FFC00002448238824483FF81010220847E40820144003801C70E00E +4360:7FFC44447FFC01000080FFFE0440139014501FF001007FFC44444FE44424400C +4361:00007FFC44447FFC00803FFE22203FFC22243FFC284028482F7048444B448C3C +4362:00007FFC44447FFC10003FFC4AA00AA07FFC0AA00AA07FFC0000248822444244 +4363:7FFC44447FFC00003FF801007FFE41029D7400003FF821083FF821083FF82008 +4364:00007FFC44447FFC0100FFFE02887D7025484D6690101FF010101FF010102010 +4365:00007FFC44447FFC00007FFE40005F3C44107F7E4E345552609044F84480BFFE +4366:7FFC44447FFC100008287F24147E494855C87F7E08487F7E514855485D7E4340 +4367:10881048505050007DFC5020902010FC1C20F02051FE10201020102010201020 +4368:442024202820FDFE102010207DFC11241124FD24112411342128202040208020 +4369:444024402840FE8010FE11087E8810881088FE50105010202050208841048202 +436A:442024202820FDFE102010207C2011FC1070FCA810A811242124222240208020 +436B:442024102810FDFE110212047C8010881090FCA010C0108220822082407E8000 +436C:440025FC2820FC20112410A47CA8102013FEFC20102010202020202040208020 +436D:440024FC2884FEA4109410847C8413FE1104FF441124110421FE200440288010 +436E:445024502850FD5210D410587C50105810D4FD5210501050209220924112820E +436F:4440244028FCFD04120811FE7D00117C1144FD441154114821422242423E8400 +4370:440025FC2904FD24112411247DFC11241124FD54114C118C2104210441FC8104 +4371:442024202850FC88110412FA7C20102013FEFC20112811242222242240A08040 +4372:88004840539CFA042204239CFA04220423FCF89020902090209041124212840E +4373:88004BDE5042F94A2084214AFA5224202000FBDE205221522094414842548422 +4374:881C49E05020F82023FE20A8F92422422040FBFE2088210820D0403040488184 +4375:4440244028F8FD08101011FC7C24102413FEFC24102411FC2024202040A08040 +4376:442024202BFEFC2011FC11247DFC112411FCFC20107010A82124262240208020 +4377:4440244029FCFC8413FE10007DFC110411FCFC2013FE1020222023FE40208020 +4378:442824242BFEFC2011FC11247DFC112411FCFD24100813FE2088204840488018 +4379:4420244029FCFD0411FC11047DFC110411FCFC28102413FE2050208841048602 +437A:8820482051FCF92421FC2020FBFE222223FEF8202040202422A2428A44788000 +437B:88004BDE5252FBDE22102252F9CE20002088FBFE2088208823FE408841048202 +437C:88004BDE5088FAA823FE2188FADA24A621F8F908210821F82108410841F88108 +437D:88004BFE5222FACC224423EEFA4422EE2354FA4422102290229E449044908BFE +437E:00007EEE2422242224AA24662422FF222426246A24B224222422242244AA8444 +437F:00007EFC224412241A3462C4020400007FFC010001003FF801000100FFFE0000 +4380:0014EE1222122210AAFE66902292229226926A94B29422B422CA228AAA164422 +4381:100011DC10441044FF5410CC104410447C4C44D44564444444447C4445540088 +4382:0040EE4022FC2284AB0466F42294229426F46A84B294228822822282AA7E4400 +4383:100011DC10447C44555454CC7C445444544C54D4FF6444444444444455544888 +4384:0000FDDC24442444255424CC54444844804C7CD445644444444444447D544488 +4385:100011DC20447C44455444CC444444447C4C44D44564444444447C4445540088 +4386:00007EFC224412241A3462C4030402800C603218C1061FE00020064001800040 +4387:100021DC7C444444655454CC5444FC44444C64D4556454444444444455548888 +4388:0020EE2022FC22A4AAA466FC22A422A426FC6A20B22422182212226AAB864402 +4389:000CEE0A220822FEAA8866882288228A26EA6A8AB28C228C228A228AAA964522 +438A:100010EE1E22222262AA9466082214222226416ABEB22222222222223EAA2244 +438B:080028EE28223E2248AA0866FF22002200263E6A22B2222222223E2222AA0044 +438C:0000EE7C22442244AA446644227C221026106A50B25E225022502270AA9E4500 +438D:0028EC2425FE2420B4206DFC2524252425FC6D24B52425FC25242524B524490C +438E:0000EDFE24A024A8B4A86CE824A824A824A86CE8B4A824AA24BA25EAB4264820 +438F:080008EE1422222251AA88667E2202220426086A7EB2422242227E2242AA0044 +4390:100011DCFE4410447D5444CC7C4444447C4C54D41164FE441044104411541088 +4391:0000EEFC22042204AA7C6604220422FE26106A92B254223822542292AA504420 +4392:0048EE44225E23E0AA286612226A239626486A5EB3E0222422282212AA6A4586 +4393:0010EE1022DA2254AA5466922350222026FE6A82B28222FE22822282AAFE4482 +4394:0028EC2427FE2420B5FC6D2425FC252425FC6D24B40827FE24882448B4484818 +4395:08202AA44D28145022887FFE400280043EF8020812480A28124822880A280410 +4396:440024EE2822FE2292AAD666BA229222FE26006A7CB244227C2244227CAA4444 +4397:060078EE1022FFA222AA5D6694A21C2200267F6A41B25D2255225D2241AA4344 +4398:08007F7E0912FF92095A7F360812AA92EB9688BAFFD28892EB92AA92AA9208B6 +4399:200011DCFE4482447D5454CC98447C44C44C7CD445647C4444447C4429544488 +439A:0088EDDC248825DCB4886DDC248825FC24046CFCB40425FC24202554B54A4A3A +439B:020002083FD00220FFFE02000C703F84C80407FC00001FF0101010101FF01010 +439C:101012107E12147E1414FE1408FE100820307E22A06422B82D223022201E0000 +439D:02203FC00280FFFE02200FC03408C3F800007EFC224412240A1412246AD40408 +439E:010001081FD001207FFC02000FF03810CFF008100FF000003FF8000800080008 +439F:100013FE10201020FC4025FC2554255425544954295411542954454481140108 +43A0:200023FE20202040FDFC25542554A5546554255435442D16250A440243FE8000 +43A1:0000FFFE020004003FF82488248824A82010010011101120228004401830E00E +43A2:104010401080FCFE11007A0010FCFC0810103820344054809102110210FE1000 +43A3:100810481128FD28112879081108FD0811083908354855949114102210421082 +43A4:100011FC1104FD0411FC79001100FDFE1102397A354A554A927A120214141008 +43A5:100010501048FC84112478201050FC8811063AF8348854889088108810F81088 +43A6:102010A410A4FD28105078881104FC24102038A834A855309050108811041202 +43A7:1040102010FCFC00108878481050FDFE1000380034FC54849084108410FC1084 +43A8:1020102013FEFC50108879241222FDFC112439FC352455FC90221022101E1000 +43A9:109210921124FE48112478921092FC0011FE3922352255FE9122112211FE1102 +43AA:100011FC1104FDFC110479FC1000FDFE10083BFE340855089088100810281010 +43AB:105011241154FD0411FC78501088FD4410783888348855509020105010881106 +43AC:100013FE1252FE5213FE78201020FDFC1020382037FE54409088110413FE1102 +43AD:101010501250FD7C1090781010FEFF00117C39443544517C5144910012FE1400 +43AE:1040102011FCFC88105079FC1104FD2411FC392435745554915411741104110C +43AF:1088108813FEFC8810F8782011FCFD2411FC382035FC542093FE105010881306 +43B0:1142115C13F0FD501150795E13F4FC1411D43954355455D49154115411E41004 +43B1:200023FC2294FA9423FC71102252FBDC201273CE6A40A3D2225C23D0225222CE +43B2:0000FF0024FC24043C08241024203C20244024402E80F48244820482047E0400 +43B3:0000FF7C244424443C44247C24443C442444247C2E44F4444444048404940508 +43B4:0048FF48244824483CFC244824483C4825FE24482E48F4484448048804880508 +43B5:0040FF20242824083C08244824543D52255225602E60F44444C40544063C0400 +43B6:0020FC20482049FC79244924492479FC492449244D2479FCC924082008200820 +43B7:0020FD20492049FC79204A2048207BFE487048A84CA87924C9240A2208200820 +43B8:0000FDFE4820482078FC4844484479FE480048004CFC7884C884088408FC0884 +43B9:00F83F0011100920FFFE09203118C1063FF808200FE008200FE0083EFFE00020 +43BA:0082FC824A824BEA7C8A488A4FFA788A4BEA4AAA4EAA7AAACAA20AE2088A0884 +43BB:0000FDFC492449247974492449FC7904497449544D547974C9040A040A140C08 +43BC:0000FDF84808480879F8480848087BFE48204A224D7478A8C9240A2208A00840 +43BD:001CFDE04920492079FE4910494A7986480249FC4D047904C9FC0904090409FC +43BE:0020FC204850488879044AFA480079FC495449544DFC7954C95409540904090C +43BF:0008FCC84B084908792A492A4BAC794849084B884D547914C914092409240942 +43C0:0082FC824BE24882788A4BEA4AAA7AAA4BEA488A4DCA7AAACCA20882088A0884 +43C1:0040FC204BFE4A42782049FC488878504BFE48204C2079FCC820082008200820 +43C2:00A0FD2C4924492479AC4924492479FC482049FC4C887850C820085008880B06 +43C3:0000FDFE4902480078FC488448FC788448FC48204C1079FEC800084808840902 +43C4:0040FC204BFE4A8A79044BFE4840788849FC48244C2079FCC82008200BFE0800 +43C5:0080FC8849EE492A7AAA49444884797A4A0048004DFE7820C8A809240AA20840 +43C6:0050FC504BFE48507BFE4A524BFE7A524BFE48004DFC7904C9FC090409FC0904 +43C7:0000FDFC485049FC7954495449FC780049FC48004FFE7820C8A809240AA20840 +43C8:0108F9085254525474BC57085110722454BE578A580870ACD56A154A14281010 +43C9:0000FDFC490449FC790449FC4888795449DC48884D5479DCC80009A809540A54 +43CA:0110FC904BDE48107A5E49824BDE78104BDE4A504FDE7A50CBDE0A500A520ACE +43CB:01003FF80108FFFE01083FF8054009203118C10625781348A178A5441D3C0100 +43CC:084008201010200840069FF0101010101FF0101010101FF01010101010501020 +43CD:02000400082010103FF8100800001FF010101FF010101FF01010101010501020 +43CE:00003C0024F0249024903C90249024D024B03C902490249224924512550E8A00 +43CF:00003DFC2420242024203C2027FE242024203C20242024202420442054A08840 +43D0:00203C20242025FC24243C242424242427FE3C20245024502488448855048A02 +43D1:020004000FF81210692004C003000C0071003FF8228824482108228824482018 +43D2:00083C882488248824883CFE2480248024803CFC248424842484450455048A04 +43D3:00003CFC2400240034002DFE245024502C5034502450245224524492548E8900 +43D4:00003DF82448244824483C48244825F824883C88248824882488448857FE8800 +43D5:00083C3C25E0242024203C20242027FE24203C20242024202420442055FC8800 +43D6:00043DE42424242424243DE42504250425043DE4242424242424442455448884 +43D7:00803C8024FC250026003CF82400240025F83C0824082408240A440A54068802 +43D8:00003DFE2528252825283D2825282528252A3D2A254A25462580450055FE8800 +43D9:00203C20242025FE25223E242420242024503C50245024502490449255128A0E +43DA:00203C20242024A824A43CA22522252026243C24242824082410442054C08B00 +43DB:00403C40248024FC25043E042484244424443C14242424442584440454288810 +43DC:00007BFC4884488848887890489C488449447944492849284A104A284C449982 +43DD:00203C20242025FC24203C4027FE244024803DFC240424882450442054108810 +43DE:00203C20242027FE24203C20242025FC24703CA824A825242524462254208820 +43DF:00403C202428240824083C482454255225523D602660244424C44544563C8800 +43E0:00407820482048004BFC780048084908490878904890489048A048204BFE9800 +43E1:00003CFC2400240024003DFE2420242024A83CA4252425222622442054A08840 +43E2:00103C10241024FE24923C94249024FC24A43CA424A824A82490452855448A82 +43E3:00003CF82488248824883CF82488248824883CF8248824882488448857FE8800 +43E4:00003DFC2404240425F43C04240425F425143D1425F425142404440454288810 +43E5:00203C20242025FC25243D2425FC252425243D2427FE25042504450455148908 +43E6:00083C3C25E0242024203FFE2420242024203DFC250425042504450455FC8904 +43E7:00203C20247C248425483C302420244825903C3E244225A42418441054608980 +43E8:00403C8025F8250825083D0825F8250025003D0025FC25042504450455FC8904 +43E9:00203C202450245024883D0426FA240024003CF8248824882488448854F88888 +43EA:00003DFE2488248824883CF82488248824F83C882488249E27E8440854088808 +43EB:009078904890491049FE7B104D10493849387954495449924910491049109910 +43EC:00203C202448248425FE3C122490249024FE3D10241025FE2410441054108810 +43ED:00207920492049FC49207A2048204BFE487078A848A8492449244A2248209820 +43EE:00403C4025FC244424443C842494250824003D02248424482400444854848902 +43EF:0020782048204BFE48207820482049FC4840782048A44A824A8A4A8A4C789800 +43F0:00007BFC4844494449447A84489449084A40782048A44A824A8A4A8A4C789800 +43F1:000079FC4904490449FC7900490049FE4902797A494A494A4A7A4A024C149808 +43F2:01083C88249025FC24243C2425FC252025203DFE246224A2252A462454208820 +43F3:0104790E493049204FE07920493E496449A47F24492449244924492449449B84 +43F4:00203D2424A424A824203DFC2504250425FC3D04250425FC2504450455148908 +43F5:0090788848804BFE48A078A848B048A448A878B04924492A49324A224ADE9C00 +43F6:01103D12251425D825103D122552258E25203C2025FC24202420442057FE8800 +43F7:00003DFC250425FC25043DFC2400240025FC3C20242027FE2420442054208820 +43F8:00007BFC4840484049F8788848884BFE4800780049F849084908490849F89908 +43F9:00003DFC2504250425FC3D04250425FC25043D0425FC24502490449255128A0E +43FA:00403C4024FC248825503C2024D8272624F83C2024F8242027FE442054208820 +43FB:1020102020204420FEFC02207C20442045FE7C2044207C48448445FE54824800 +43FC:00483C44245E25E024283C12246A259624483C5E25E0242424284412546A8986 +43FD:00403C2025FC240025083C90240027FE24003C0025FC25042504450455FC8904 +43FE:00203C2025FE242024FC3C4025FE248825243E2224F8242025FE442054208820 +43FF:104008403E7E228823503E20205841869FF010101FF010101FF0101010501020 +4400:00203C2025FC245024883D0427FE240825E83D28252825E82528440854288810 +4401:00007BFE4840488049447A2448684AB049307AA8486848A449224A2048A09840 +4402:000079F84808480849F8780848084BFE48207A22497448A849244A2248A09840 +4403:00007BFE4A024A1A4AE27A224A224BFE4A227A724AAA4B264A224A224BFE9A02 +4404:00403C40247C248425083E00242025CE25023D0225CE25022502450255FE8902 +4405:00003DFC2504250425FC3D002540257C25903D1025FE25102528452855448A82 +4406:0008783C4BC048444A247928490048204BFE787048A848A849244A224C209820 +4407:00803C8024FC255426543C942524245424883C0025FC250425FC450455FC8904 +4408:004078404BFC4840484079F8490849F8490879F8490849F8490849084FFE9800 +4409:00923C922524264825243C922492240025FE3D22252225FE2522452255FE8902 +440A:00003DFC2504250425FC3D04250425FC24003D1225D42518251045525592890E +440B:00907890490849484A447C9249084BFC4844782048A44A824A8A4A8A4C789800 +440C:044004403FF824483FF82448FFFE10102008DFF610101FF010101FF010101030 +440D:00203C2027FE242024203DFC2400240025FC3D04250425FC2400448854508BFE +440E:000079FC4904490449FC7904490449FC48007BFE48204920493C49204AA09C7E +440F:00203C2027FE242025FC3C4027FE248825043EFA2488248824F84488548888F8 +4410:008871C857085108512A712A57AC51485308738855545514591451245124B142 +4411:00483D48254827FE25483D482578250025FE3C2027FE247024A8452456228820 +4412:00003C4025FE248825043E4224F8270824903C7027BE244225A4441854608B80 +4413:00003DFE2410242024FC3C84248424FC24843CFC2484248424FC444854848902 +4414:00203C1025FE250225023DFE2500250025FE3DAA26AA24FE24AA44AA54AA8886 +4415:00003CF82488248824F83C0025FE248824F83C8824F82488249E47E854088808 +4416:00007BFC4A044A044BFC7A204B244AA84A207BFE4A704AA84AA84D244A229820 +4417:00203C2024FA242424283DFE2420244024FC3D442644247C24444444547C8844 +4418:001E7BE048444924488879FC484048404BFE788048FC494449284A1048689986 +4419:008878884BFE488848F8782049FC4924492479FC48204BFE4820482048209820 +441A:00007BDE4A524A524A527BD24A524A524A527BD24A1A4A944A504AB04B109810 +441B:00203C2025FE245024883D0427FE248824F83C8824F82488249E47E854088808 +441C:002078204BFE482049FC790449FC490449FC790449FC49044BFE488849049A02 +441D:00203D2424A8242025FC3D04250425FC25043DFC2504250425FC440054888904 +441E:00007BDE484248424BDE7A104A104BDE48427A52494A494A4A5248424A949908 +441F:008878884BFE488849FC78884BFE482049FC792449FC49244BFE490449149908 +4420:00883C8827FE24A824103FFE2480248024FC3C0024A824A824A844AA552A8A06 +4421:02000100FFFE02847D78255025484D6401003FF8228824482108228824482018 +4422:0080788049FC4A44495479F4488449284A9079FC4A444D5449F4488449289A10 +4423:00003CF82488248824F83C0025FC250425FC3D0425FC250425FC445054888904 +4424:00843C44244825FE24203CFC242025FE24403C8024FE25102610441055FE8800 +4425:0090788849044A424C8879FC480448004BDE78424A52494A4A524842494A9884 +4426:00203C2024FC242024203DFE2440248425FE3C0225FC25542554455457FE8800 +4427:004078204BFC480049F8790849F848004BFC7A044AF44A944AF44A044A149A08 +4428:1000FE7810487C480048FE8682007CFC00447C4444287C2844107C2844444D82 +4429:00203D242524252425FC3C0027FE240025FC3D04250425FC2488445057FE8800 +442A:00A0789049FE4B204DFC792049FC492049FE79004BFC4888489E49024A0A9C04 +442B:012479244A244C244954794A4A924E104A107A504A5C4A504A504AB04A9E9B00 +442C:009078904FFE48904BFC7A944BFC4A944BFC780049F8490849F8490849F89908 +442D:02A872A857FC52A852AA74E6580057FC5444704053F85248524852485258B040 +442E:004078204BFC4800490878904BFE4A204AA07AFC4B204A204AFC4A204C2099FE +442F:00003DFC252425FC25243DFC2440248825F03C20244427FE2422452456228860 +4430:0120793C49444AA84A107EA84AC64ABC4AA47ABC4AA44ABC4A244A244A249A2C +4431:004078204BFE488848507BFE4A224AFA4A227AFA4A8A4A8A4AFA4A024A0A9A04 +4432:00007BDE48424A52494A7A524842482049FC7904490449FC4904490449FC9904 +4433:00403C4024F8250826103DFC2524252425FC3D24252425FC24004554552A8A2A +4434:7DFC44207D2045FE7C5048525492650E1FF010101FF010101FF0101010501020 +4435:00883C8825FC248824883FFE242025FC25243DFC252425FC2400448855048A02 +4436:00007BDE48884AA84BFE79884ADA4CA649F87908490849F84908490849F89908 +4437:00007BDE4A524A524BDE780049FC492449FC792449FC48204BFE482048209820 +4438:00203DFC242427FE24243DFC242027FE24003DFC252425FC252445FC54008BFE +4439:002079FC48244BFE482479FC48204AAA4BAE7A224BFE4A224BAE4AAA4AAA9C22 +443A:00007BFE48504BFE4A527BFE480049FC490479FC490449FC48204BFE48209820 +443B:00207BFE482049FC490479FC482049FC488878504BFE482049FC482048209820 +443C:00807BDE488A49CA488A7BD248A64840488879F048244BFE482249244AA29840 +443D:008878884BFE4888488878F848204BFE4A227B324AAA4B764A224A224A2A9A24 +443E:00003DFC255425FC24203DFC242027FE24883C5025FC242027FE442054208820 +443F:004078804BFE4A224AAA7A224BFE4A724AAA7A0248204BFE4820485048889B06 +4440:00107BC84A7E4A404A627BD44A004A3E4BC87A484E7E4A484A484BC84A489808 +4441:3AB821083AB82288393822887FFE40029FF410101FF010101FF0101010501020 +4442:01407A4C4A644A444B4C7A644AA44BAC4AA47AA44FFE4800491049084A049C04 +4443:00883DFE248825FE35022CFC240025FE2C20345025AA245C25AA444855A88810 +4444:00403CF8248824F824883CF8240025FC25243DFC252425FC240047FE54888908 +4445:00887BFE488849FC4954795449FC48004BFE7A4248F848884948483048609B80 +4446:010878904BFC484049F878804BFC494849FC7B0A4DF8490849FA4934498C9902 +4447:00427B9C4A104BDE4A947A944C204BFC4A047BFC4A044BFC4A044BFC49089A04 +4448:012479744A584ADA4BFE79544ADA4BFE48A278204BFE487048A849244A229820 +4449:E040BFFEA400A7FCA000E7FCA404A7FCA040EE4EABEAAEAAAAAEAE4A2AAA7710 +444A:0010787C4A54497C491078FE48444B7C4944797C4944497C492849444A809C7E +444B:00207BFE480049DC495479DC48884BFE48887BFE48884BFE489449884AA498C2 +444C:03DE7A524BDE4A524BDE7A224AFA4A224AFA7AAA4AFA4AAA4AFA4A724AAA9A26 +444D:03DE7A524BDE4A524BDE7A524BDE498C4A5278404FFE48884990486048D89B04 +444E:0148794C4AAA48084FFE79484B68494A4B6A794C4B6C4948496A4B9A48269842 +444F:00887BFE48884BDE4A527BDE48A0489049FE79204BFC4D2049FC492049FE9900 +4450:00407E40484048FE48807E804310421042587E5448944892491248107E500020 +4451:00287EAA486C482848FE7E44422842FE42107E7C481048FE481048287E440082 +4452:0000FE0011FC2024282444A4FEA412A4112410247C24104410441E84F1144208 +4453:08207FFC08200FE008200FE008207FFE4002BFFC08201FF001001FF001007FFC +4454:0020402098208BFE8820882089FCD9248924892489248934F928882000200020 +4455:060038F820083EF820083FF800003FF821083FF821083FF8210A410A41068102 +4456:002040209BFE882089FC88248BFED82489FC88208920893EF9208AA0027E0400 +4457:000041F8990889F8890889F88800DBFE890089FC8A548C94F9248A4400A80110 +4458:0108408898908BFC884089F88840DBFE8880890089FC8A20FC20882003FE0000 +4459:08001CFC708410841084FDFE108410847C8445FE4484448444847C8444940088 +445A:08001CFC708410841084FCFC108410847C8444FC4484448444847C8445140208 +445B:08041C1E71F011101110FD10111011FE7D10451045104508450A7D4A45A60112 +445C:08481D48714813FE1148FD48117811007DFE442047FE447044A87D2446220020 +445D:00003EF8228822883EF80000FFFE902210203DF84420A520192011FC20204020 +445E:3FFC24902960261038882290256022102C083FFC10103EFC4210149018FEE010 +445F:0F10F020117C8944427C0044FF7C810042FE771092105A7C2F10221042FE8200 +4460:080011FC3E04220832102A202A20FE20222032202A202A20222042204AA08440 +4461:100021F87C8844C864A854A85488FC5044506450542054204450448855048A02 +4462:100020007DFC4490649054905490FC90449064905490549244924492550E8A00 +4463:080410043F082110292025442504FF08211029222542250421084110452082C0 +4464:082010203E50225032882B442A22FE20220033FC2A042A08220842104A108420 +4465:080010FC3E44224832482A502A5CFE44224432442A682AA8229042984B248442 +4466:084010403E8022FC33042A042AF4FE94229432942AF42A94220442044A288410 +4467:1088208878884908697E5B084D08F94849284928690859084908490849289910 +4468:108020807CFE450066205520552CFD7447A46524553455284522450254FE8800 +4469:081010103E10221032FE2A102A10FE10227C32442A442A44224442444A7C8444 +446A:082010203E50225032882B042AFAFE00220032F82A882A88228842884AF88488 +446B:088410483E0022FC32482A482A48FE4823FE32482A482A48224842884A888508 +446C:085010503E50235232D42A582A50FE5822D433522A502A50229242924B12860E +446D:100021007CBE4488640856085508FD484448648857885488448844FE54808800 +446E:100020F87C884488648854885526FE2045FE6420547054A84524462254208820 +446F:110820887C9045FC6424542455FCFD20452065FE546254A2452A462454208820 +4470:081010103E90229E32902A902BFEFE00221032922A922B14220442084A3085C0 +4471:104020207BFE4A026D04590049DEFA524A524B526C9A5894491049124A129C0E +4472:082010203E3E222032FC2A842AFCFE8422FC32A42A202BFE222042204A208420 +4473:102020207C504488650456FA5400FDFC4554655455FC5554455445545504890C +4474:084410443EFE224432442A7C2A44FE44227C32442A442AFE220042284A448482 +4475:100021FE7D02457A6502557A5400FCFC448464FC548454FC4484448454948888 +4476:081010103EFE2210327C2A102AFEFE00227C32442A7C2A44227C42444A548448 +4477:102020107DFE4502650255FE5500FD7E4542657E5542557E45424542554A8A44 +4478:082010103EFE228232002A7C2A00FE0022FE32102A102A54225242924A508420 +4479:104020207BFE4A2268A459284850F888490448F8688858884850482048D89B06 +447A:100023FC7A044A346BC45A444BF4FB544B544BF46A445A544BF44A944C069802 +447B:1108208878884BDE6910592049DEF94249444944695E59444A444A444CD49808 +447C:104020407CFE452264AA54FA5442FC94454864FE552256AA44FA444254948908 +447D:100021FC790449FC690459FC4800FBDE48424A52694A58C64B5A4842494A9884 +447E:10A0209079FE4B2069FC592049FCF92049FE49006BF859084890486049989E06 +447F:102020107BFE4A02688058FE4910FB204D7C49446944597C49444944497C9944 +4480:1110211079DE4AA86C4458884888F9084B7E4D08694859284908490849289910 +4481:100023DE78424A52694A5A524842F82049FC4904690459FC4904490449FC9904 +4482:109022907A9E4AA26AD45BA84894F8A44FFE4A846AA45A944A944A844C949888 +4483:101020507A50497C6890581048FEFB00497C49446944597C494449004AFE9C00 +4484:100020007BFE4A0269FC580048F8F88848F8480069FC592449FC492449FC9904 +4485:102021247CA845FC644057FE5488FD0447FE650455FC550445FC450455FC8904 +4486:110820887BE849106A9E5FD44864FBD44A544BD46A545BC84A484A544A649AC2 +4487:104020207BFE4A0269FC580048F8F88848F8480069FC592449FC492449FC9904 +4488:102021FC7C20448867FE548855FCFD0445FC650455FC550445FC448855048A02 +4489:108021007BFE4D5469545BFE4954F9544BFE490469DE5A444954489E49049A04 +448A:0440244022FC2288431040FCBEA410A420A43EFC0280028002820282147E0800 +448B:1040104010FC7C88551054FC54A454A454A4FEFC1080108028822482447E8000 +448C:0020FF20817C00447E88427C7E5442547E54107C0840FF4000422442423E8100 +448D:20401040FEFC0088451028FCFEA4A2A410A4FEFC20803C8024824482547E8800 +448E:24202420FF7C24441288FE7C245442548154247C2440FF4024422442443E8400 +448F:4440244028FCFE889310D6FCBAA492A4FEA400FC7C8044807C8244827C7E4400 +4490:2220FFA0227C7F4455887F7C0054FFD480D43E7C22403E4022423E42223E3E00 +4491:00000000000000001010081008200000FFFE0000000000000000000000000000 +4492:08200820FFFE0820082000003FF8000800480188060818086008000800500020 +4493:08200820FFFE082008200000FFFE0400040008001FF000100010001000A00040 +4494:08200820FFFE0820082000400440044004200820082010101010200840048002 +4495:08200820FFFE0820092001000100010011101108210421044102810205000200 +4496:08200820FFFE0820082000007FF0041004100410FFD00412040A040604020400 +4497:04400440FFFE0440080008001FFC200040009FE0002000C003000C0410040FFC +4498:08200820FFFE08200820040004000FF01010282044400280010006C01830E00E +4499:08200820FFFE08200820010001000100010001F80100010001000100FFFE0000 +449A:08200820FFFE082008200100010011101108210421144120004001800E00F000 +449B:08200820FFFE0820100010FC22044204FC040804100422044104FF0441280010 +449C:08200820FFFE08200920110011001FF8210041000100FFFE0100010001000100 +449D:08200820FFFE08200008181006600180066018186C240240018006601818E006 +449E:08200820FFFE0820092001003FFC2104410802800280048008821082207E4000 +449F:08200820FFFE082000001FF01010121011101010FFFE10102010201040508020 +44A0:08200820FFFE0820092001007FFC010001003FF801000100FFFE010001000100 +44A1:08200820FFFE082000007F08010801083F08200840087F08010801080A080408 +44A2:08200820FFFE0820082000000C0070FC4084408440844C847094408800800080 +44A3:08200820FFFE082000001FF0101010107FFC101010107FFC1010101010501020 +44A4:08200820FFFE0820082000003FF82008200820083FF82008200820083FF82008 +44A5:08200820FFFE082000007FFC010001003FF82108210821082128211001000100 +44A6:08200820FFFE082001F03E00020001007FF8006001800E003000480087FE0000 +44A7:08200820FFFE0820092001003FF8010001000100FFFE0400082010103FF81008 +44A8:04400440FFFE0440080008001FF8210041000100FFFE0280044008203018C006 +44A9:08200820FFFE0820000000F01F00010001007FFC054009203118C10601000100 +44AA:0820FFFE08200400082010103FF8000808200820FFFE08200820102020204020 +44AB:08200820FFFE08200000085008481040307C57C09040102010201014100C1004 +44AC:08200820FFFE0820082000003FF800000000FFFE010011102108410485020200 +44AD:08200820FFFE082000001FF0001000107FFC00000020FFFE0820042004A00040 +44AE:08200820FFFE082000007FFE400280040FE008200A20092009221022201E4000 +44AF:08200820FFFE082000007FFE420282041FE002200C2004200A2011222022401E +44B0:04400440FFFE044000003FFE20002FFC2080208027F8208020802FFC20003FFE +44B1:04400440FFFE04403FF0002000C07D040588095011202118C5060200FFFE0000 +44B2:04400440FFFE04401008101CFEE0122022202220643E15E0082214222222C01E +44B3:08200820FFFE082000000FE008201020611C0100FFFE054009203118C1060100 +44B4:08200820FFFE0820040004007FFC08001FF028104FF088100FF0081008500820 +44B5:08200820FFFE0820100011F8FC082410242025FE442024201820182024A0C240 +44B6:08200820FFFE0820092001003FF821083FF821083FF8010800B001C20E32700E +44B7:08200820FFFE082000F01F0001000100FFFE010001001FF0101010101FF01010 +44B8:08200820FFFE0820092002003FF82448244824482448244824482448FFFE0000 +44B9:08200820FFFE0820092001007FFC01003FF80100FFFE054009203118C1060100 +44BA:08200820FFFE0A20040008201FC0008003200C103FF801081110210845040200 +44BB:04400440FFFE04400800087C080449044904497C494049404F427942003E0000 +44BC:08200820FFFE0820044004403FF82448244824483FF82448244824483FF82008 +44BD:08200820FFFE082000003FF820082AA82AA8244824482AA82AA8200820282010 +44BE:08200820FFFE08200A200100FFFE02000500090418882850C8200A180C060800 +44BF:08200820FFFE08207FFE40029FF4101010101FF0101010101FF0101010501020 +44C0:08200820FFFE0820092001007FFC010001001FF000001FF0101010101FF01010 +44C1:08200820FFFE082001003FF801000100FFFE000000207FFC0820042004A00040 +44C2:08200820FFFE08200A200100FFFE00003FF800003FF800003FF820083FF82008 +44C3:04400440FFFE04401FF010101FF000003FF8210821083FF8200220021FFE0000 +44C4:08200820FFFE08204400280C11F02900C90019FE2910491089100A1052102410 +44C5:08200820FFFE08200820200C11F01100810049FE49101110E110221022102410 +44C6:04400440FFFE04401000100C11F0FD00110011FE1D10F1101110121052102410 +44C7:08200820FFFE082001003FF801000100FFFE0440244844448842084011402080 +44C8:04400440FFFE0440100010F8208841088A06100031F850889050102010D81706 +44C9:08200820FFFE082000007E7C2444244844507F48144424444454844814400840 +44CA:0820FFFE082000007FFC020002003FF004100810FFFE00001FF0101010101FF0 +44CB:08200820FFFE08202008103C13E082204A204BFE1220E2102212228A23062202 +44CC:08200820FFFE0820092001007FFC010001003FF80000010008844892481287F0 +44CD:04400440FFFE04401FF010101FF010101FF000003FF80100FFFE010001000100 +44CE:04400440FFFE04401080108014FC55045A045084904410442804240444288010 +44CF:08200820FFFE082000007FFC010003000D603118C1041FF0101010101FF01010 +44D0:0820FFFE082001007FFC044008203118C1063FF80100111011141FF4010400FC +44D1:08200820FFFE0820200017FC91104110411017FE2110E1102210221024100810 +44D2:04400440FFFE044010001FF820085FC8924812481FC8124812481FC800280010 +44D3:0820FFFE0A2002007FFC02003FF80400FFFE08201FFC20204420822002A00040 +44D4:08200820FFFE082001081FD00120FFFE01001FF0082030C0CFFC008002800100 +44D5:08200820FFFE082023F01000100007FC7120112012241224141C280047FE0000 +44D6:08200820FFFE0A2001007FFE40028824121022081FF004100410081010A02040 +44D7:08200820FFFE08200440082011102208C44608201FF0011008844892481287F0 +44D8:0820FFFE0820000008401F6022505448084037FEC0001FF0101010101FF01010 +44D9:0820FFFE082000701F800100FFFE010009207924092809321922E91E01000100 +44DA:04400440FFFE0440100021F84108890811F83108510891F81108110817FE1000 +44DB:08200820FFFE082000003FF820083FF820802490249027F02080488848888FF8 +44DC:08200820FFFE08202008103C13E082204A204BFE1220E2102212228A23262212 +44DD:0820FFFE082000001FE0004001807FFC0100050002003FF824482448FFFE0000 +44DE:08200820FFFE092000803FFC200420043FFC20A020902FFC2120421044089806 +44DF:08200820FFFE082000003FF8210827C821082FE8200827C8244847C840288010 +44E0:08200820FFFE082001047D9809603118C50602001FF010101FF010101FF01010 +44E1:08200820FFFE0820282020003E7C484488440844FF4408441444227C41448000 +44E2:08200820FFFE082000003FF8210821082FE8210827C8244827C820083FF82008 +44E3:08200820FFFE0820FFFE010001007FFC41045144492455546594410441144108 +44E4:04400440FFFE044008001FF822484448088811082228041001004884481287F2 +44E5:0600010006C01830E44E3FF804401FF010101FF010101FF001007FFC01000100 +44E6:08200820FFFE0820044004403FF8244824483FF824482448FFFE082010102008 +44E7:0440FFFE044000003FF0002000C0793C4904496849107928014405000200FFFE +44E8:08200820FFFE08207FFE400288041FF821000100FFFE0100210821083FF80008 +44E9:04400440FFFE04401020102011FEFC20102031FC388454885050902010D81306 +44EA:08200820FFFE08201FF010101FF010101FF008001FF822484488090812282410 +44EB:08200820FFFE092001003FF804400820FFFE00101F9010901F90001000500020 +44EC:08200820FFFE0820010001FC01003FF820083FF820083FF80100FFFE01000100 +44ED:08200820FFFE0820010432040C243224C9240824FFA408242A244904A8941008 +44EE:08200820FFFE08203E400240147E0888FF480A48185028504820085028881104 +44EF:0820FFFE09203FF801001FF001007FFC00001FF01210FFFE20903FFC00100060 +44F0:0820FFFE082000007FFC04403FF8244824483FF8010001003FF801000100FFFE +44F1:0820FFFE08200440274C247024422F42F03E01007FFC054009203118C1060100 +44F2:04400440FFFE044009080890100013FC3204520493FC1090109011121212140E +44F3:04400440FFFE0440000009F8110821F8450809F8192429284910094809860900 +44F4:0820FFFE08200000FFFE02003FF8248824A821100100FFFE028004401830E00E +44F5:08200820FFFE082000001FF0101010101FF000007EFC4284428442847EFC4284 +44F6:04400440FFFE044008080808FF8808487F4849487F481C482A48490888280810 +44F7:08200820FFFE08A02100123C94804100437E15082108E1082108210821282110 +44F8:04400440FFFE044008007EF812202420182065FC08207E201220242018206420 +44F9:08200820FFFE092002800E603118DFE610201FE010201FE01008119014601810 +44FA:0820FFFE0820101008207FFC01003FF80100FFFE01007FFC028004401830E00E +44FB:08200820FFFE08207FFE4002BE24002001FC7E4814C81430146A2586240243FE +44FC:0820FFFE08201088108413FEFCA424A824B424A848B228A410AA2932452282DE +44FD:04400440FFFE0440200010FCFE0400047C0400FC7C8000807C8044827C82447E +44FE:08200820FFFE082020401248444420140860738020000400FFFE082007C07838 +44FF:0820FFFE082000003FE0044002807FFC444442845FF441047FFC410441047FFC +4500:0440FFFE0440103813C0204027FC6150A248244620802FFE2110232020E02718 +4501:08200820FFFE082000007FFC04403FF824483FF801007FFC05401930E10E0100 +4502:0820FFFE0A2001007FFE420281043FF808200440FFFE01003FF8010001000100 +4503:08200820FFFE0820200011F8FD08090811F83908550895F81108110817FE1000 +4504:0820FFFE082000FC7F002208111020203FF841000100FFFE0100210821083FF8 +4505:0820FFFE082000007FFC00201F2011201F200000FFFC00201F2011201F200060 +4506:08200820FFFE0820440029FC112429FC492499FC282049FC8820082053FE2000 +4507:0820FFFE08200100210821083FF800007FFC00001FF010101FF008200440FFFE +4508:0440FFFE04403FF801007FFC00001FF010101FF010101FF010101FF008201010 +4509:08200820FFFE08200C1C71E010201020FDFE307038A854A85124922210201020 +450A:08200820FFFE08200108FC9011FC109010907C9013FE10901C90F11041100210 +450B:04400440FFFE04401020102024207CA808A4112225227E280010542054C08300 +450C:0820FFFE082002001FF010101FF010101FF002007FFC08203118CFE601000100 +450D:08200820FFFE082000001FF811001FF011001FF011001FFC0004292444940008 +450E:08200820FFFE0820204017FC104003F87248124813F8115012481444284047FE +450F:0820FFFE08200040224013F81440004077FC100013F8120813F8280047FE0000 +4510:04400440FFFE04402120111017FC80904064539C11202110E7FC20902064239C +4511:04400440FFFE04400808144822285D0888C808287F0E08F82A084908A8881008 +4512:08200820FFFE0820008078404BFC5108609057FE480049F86908510841F84108 +4513:0820FFFE082020001040FE4000FE7C9001107C1001FE7C10441044107C104410 +4514:0820FFFE082001003FF80440FFFE00001FF010101FF010101FF004421842E03E +4515:04400440FFFE0440002878244BFE482079FC492449FC792449FC49244924990C +4516:0820FFFE0820000078404BF8504067FC51104A884CF4691052A0404041B04E0E +4517:08200820FFFE082020881050FBFE0820102039FC5420942013FE102010201020 +4518:04400440FFFE0440200020F83C88508810F8FC88108854F854885C8875FE0400 +4519:08200820FFFE08201080288044FCB90412047C841044944450041E04E0284010 +451A:0820FFFE08203FFC20002FF820003FFC24482630240E2FF848084FF888080818 +451B:08200820FFFE082023FC204021F821083DF8210821F8250829F8300020900108 +451C:04400440FFFE04400020FC2049FC7924492479FC49244D24FBFE090409140908 +451D:0440FFFE044008442F7828422F3EF40008201FC003100C083FFC010415102208 +451E:0820FFFE0A2001007FFC020044442F88111022484FE400200100FFFE01000100 +451F:0440FFFE044000200C4070FC13081090FC6030903B3E544255A4901810601380 +4520:04400440FFFE044010201124FCA8102031FC390455FC910411FC110411141108 +4521:04400440FFFE044008001FE020207FF8A1083FF821083FF80000248822444244 +4522:0820FFFE0820145022880820145022881FF00000FFFE10001FF8000800500020 +4523:0820FFFE082003043C2404247FA416242504440C11001FF82100FFFE01000100 +4524:08200820FFFE0820000013FE20207C4045FC450445047DFC450445047DFC4504 +4525:0820FFFE082001003FF00110FFFC01103FF0092025482FE82388254829284108 +4526:04400440FFFE0440110011FC1200FDF83148392857FE5148922813FC10501020 +4527:0820FFFE082003043C2404247FA416242504440C01007FFC05401930E10E0100 +4528:0820FFFE08201050104824FE45907A9010FC2490449078FC0890109020FEC080 +4529:04400440FFFE044008200820FFBE08447FA449247F281C282A10492888440882 +452A:0820FFFE082001007FFC01002928111029280100292811102AA804401830E00E +452B:04400440FFFE044000207C2007FE182051FC5D24512C50705CA87124C2220020 +452C:0820FFFE082000003FF821083FF821083FF804403FF80440FFFE082010102008 +452D:0820FFFE09207FFC41041490142823E800003FF821083FF821083FF821082118 +452E:08200820FFFE0820220C2270FF4022403E40227E3E482248FF48224841488088 +452F:0820FFFE082000107F10141014FE7F105510557C574461447F4441447F7C4144 +4530:0820FFFE09207FFC40043FF800001FF010101FF000003FF821083FF821083FF8 +4531:08200820FFFE082011F81108FDF8100013FC11081DF8F10811F8110E57F82008 +4532:08200820FFFE082000907EA00444282817D02008DFF610101FF0082004407FFC +4533:04400440FFFE044010281E2432FE4A20A450185010882106C000248822444244 +4534:0440FFFE044008002A003E7C49447F4400443E2800287F1008102A2849441882 +4535:0820FFFE082000007C7C44447C7C44447D7C41045FF44384454449245124410C +4536:0820FFFE0820000011FC1104FDFC110415FC180037FED020113C112052A0247E +4537:0820FFFE08200000FEFE10107C7C1010FEFE010006C01A30E10E1FE000400080 +4538:0440FFFE04400120FFFE02800C603018C00610281424FEFE1020285044888106 +4539:0820FFFE0820010878904BFC48805144566848B049284E6868A4512246A04040 +453A:0440FFFE04407BFC488049F8522055FC480049F8490869F8510841F841084118 +453B:0820FFFE08201040FE4000807CFE45087E8800887C500850FE20105050882306 +453C:0820FFFE082000007EFC122452A49324264C409008502E5C28502E50F1FE0000 +453D:0820FFFE082023F8120813F8820843F8510013FC2444EAA4220423F420142008 +453E:0820FFFE082023F8220823F8FA0823F8290033FC6444AAA4220423F4A0144008 +453F:0820FFFE08200440FFFE04403FF82848303827C820083FF80020FFFE08200460 +4540:04400440FFFE044008207F20083E3E4200943E1000107F1008282A2849441882 +4541:0820FFFE082004407C7C04403C7804407C7C05400100FFFE05401930E10E0100 +4542:0820FFFE082000802110120817FC000473F8120813F810C411A812902C8847FE +4543:0820FFFE0820004078A049104BF8550651F0490049F049006FFC5100421043F8 +4544:0820FFFE082000001FC000447D88055009203518C2061FF000003FF82448FFFE +4545:0820FFFE08200080112C1124FDAC252425FC482029F810882850442080D80306 +4546:0440FFFE044020A021102208F5F62000678474A4AFA4A4A427A4248424942588 +4547:0820FFFE092000803FFC208021002FF828882FF829082FF84254445C9842603E +4548:0820FFFE0820004809484BFE49487978090009FEF8204BFE487048A88B260820 +4549:0820FFFE08203FF824483FF801003FF80100FFFE04403FF80100FFFE01000100 +454A:0820FFFE0920FFFE00003FF8200827C824483FF810101FF010101FF00000FFFE +454B:0820FFFE08201040102013FE12207EFC122413FE12241EFCE22004FC048408FC +454C:0820FFFE082000000CA0709011FE1120FB2031FC392055FC5120912011FE1100 +454D:0820FFFE0A200100FFFE04881A70EC1808063FF824482FE8345827C820282010 +454E:08200820FFFE082001FC7C0044F844887CF8440045FC7D2445FC45247DFC4504 +454F:0440FFFE0440101008203FF801007FFC02403C500848FFFE08507E240854198C +4550:08200820FFFE082021FC1000FCF8088810F8380055FC952411FC112411FC1104 +4551:0440FFFE0440001C11E0104425247C880820102025FC7C4800C8543054688184 +4552:0820FFFE0920FFFE01003FF800001FF010101FF00820FFFE10007EF8228846F8 +4553:0820FFFE0A2001007FFE50829EFC22885450282017D82006DFF0010011102308 +4554:0820FFFE08202100411C828014402BBE7108A7C821082948250821C82E282410 +4555:0820FFFE082011F8090809F8410823FC2A940BFC100073F81090106011981606 +4556:0820FFFE0820400C2F70211002240278E3122E7E221022542A92243050008FFE +4557:0820FFFE0A201FF010101FF010101FF000003FF821083FF82108FFFE08201020 +4558:0440FFFE0440100013FC284045F8930809F8FD0805F8090851F8200010900108 +4559:0440FFFE044008207F280824FFFE12203FA46424BFA824183F92242A3FC62082 +455A:0820FFFE08203FFC208027F0249027F020803FFC241027F0241027F022203FFC +455B:0440FFFE044020201020FDFC002078A800A878A801747A224850488879044A02 +455C:0820FFFE08207CF824481428244801007FFC0820145022880100FFFE01000100 +455D:0820FFFE0820001E0DE07044112410A8FDFC312439FC552453FE910411141108 +455E:0820FFFE08207C7C44447C7C44447D7C47C4444447C4444447D444A44544462C +455F:0820FFFE082000002FEC48244BA4682C4BA46AAC4BA44824FFFE101020084004 +4560:0820FFFE082000803FFE20202F2831102A0A277C294A378428784F484130874C +4561:0820FFFE08207C7C44447C7C44447C7C47C4444447C440044FE448244FE4400C +4562:08200820FFFE082000887C5013FE102021FC3C4067FEA480257C26103C1025FE +4563:0820FFFE082023F8120803F8FA080BF811002BFC7444AAA42A0423F420142008 +4564:0820FFFE08207700557C774400487F5049487F4449447F540848FFC008400840 +4565:0440FFFE0440111025484924BFFA210835582928355821083558292835582118 +4566:0820FFFE082001007FFC10001FF808200FE079384FA87AA84AB8792A4AAA9C46 +4567:0440FFFE04403E2022103AFE2A007F2841443E8222283E2822103E2822442682 +4568:0440FFFE044001243CA825FC24403DFE248825443E8A24F0242445FC54A88964 +4569:0440FFFE04401000102013FE7850128A31FC3A8A54F8508890F8112412221060 +456A:04400440FFFE044023F812A893F8404043F8104027FCE11023F8204027FC2040 +456B:0820FFFE08A0111E13D25A5E53D05A52E3CE120827E44822144003801C70E00E +456C:0820FFFE082003FEF80009FC0924F9FC812487FEF80009FC092409FC512427FE +456D:0440FFFE0440101010547C581090FE280044549292547C5810901C28E0444182 +456E:0440FFFE0440110011FC7E441154FEE4444429F47C4410E4FF54104410541008 +456F:0820FFFE08200000FE1C28E8FEA8AAA8FEA800A87CA800A4FEA4554A92783008 +4570:0440FFFE0440101C13E0152454A85BFE5124920211FC112429FC252445FC8104 +4571:0820FFFE082000007DFE002000FC7E8442FC42847EFC428424FC0F00F0484084 +4572:0820FFFE08A03FFE20402FFE240425F4251427FC200027FC20004FFE424884C4 +4573:0820FFFE08200000F7FC124817FCFC4686EC8554F6EC155416EC144454542408 +4574:0440FFFE044000A00C9071FE112013FCFD2031FC392055FE500092A412521452 +4575:0440FFFE0450102010FCFE8410FC10847CFC008000FE7C8044FE44027D524406 +4576:0440FFFE0440209010FEFD9002FC789000FC789000FC788049FC488878704B8E +4577:0820FFFE092000803FFE24103F7C26382D543492212027C021104FF844A48990 +4578:0440FFFE04407F1049106BFE5D107F10087C7F0008000F7CF0440044557C5544 +4579:0440FFFE044020101048FE4044FE4590AA9010FCFE9010FC5490529092FE3080 +457A:0820FFFE0820244814507FFC082004407FFC0100FFFE22003E7C23A47E180266 +457B:0440FFFE04403F7E12241B3412A43FFC22403FF822483FF828442F7848428F3E +457C:0820FFFE08204450FE4844FE7D901290FEFE9290FE9010FEFE90289044FE8280 +457D:0820FFFE082001FC7D5445FC44807DFC124411F45D5451F450445DF4E0140008 +457E:0820FFFE082000001E7812483FFC20202E20223C3FC829282F2849905F288144 +457F:0440FFFE04504420FEFC44847CFC1084FEFC9280FEFE1080FEFE280245528206 +4580:0820FFFE08203C782448FFFE02001FF0149012501FF0082010107C7C44447C7C +4581:2810FEFE284400287CFE54007C7C54447C7C1044FE7C9210920ABAAA8AA4851C +4582:0820FFFE29284FD2F03C23884812FBBE0280ABAA00F03F000100FFFE01000300 +4583:0820FFFE0A207FFC08001FF068100FF04444FEFE5454FEFE20207C7CC4C47D7C +4584:0820FFFE08204450FE4844FE7D9010FCFE9092FCFE901090FEFE288044488224 +4585:0820FFFE08203FF801007FFE492284143BB82AA83BB800007FFC11102928FFFE +4586:0440FFFE04400020FBFE2154F9DCA888A9FCD88889FC8888FBFE898AFEA488C2 +4587:0820FFFE2A28F3BC2508739CAD6A27C80000FFFE950A6B7055047F3824823FBC +4588:010001F801003FFE210221F02F0420FC2000241824E027042404440443FC8000 +4589:010001F801003FFE210221F02F0420FC200023F8204020402FFE404041408080 +458A:0020043E042085FE4522293829E01122111E2900297845484548824A024A0486 +458B:0410079004103F90249027103C102490239020282F282928296449A491242042 +458C:0404078404043FD4245427143C5423D420142F14291429044944498491142008 +458D:010001F801003FFE210221F02F0420FC210021FC2210251028A0404041B0860C +458E:00407840487C504053FC624452704BC04A444A3C6A0052F0449044924912520E +458F:010001F801003FFE210221F02F0422FC220027F82D48334822E8449E49088218 +4590:04100E1E301020FE2092209C3EF02492248E248024B824A824A8452A452A8246 +4591:08000F00087C7F4449444E44787C4944474440444E7C4A444A02520291FE2000 +4592:010001F801003FFE210221F02F0420FC20002FF8200027F0241047F042209FFC +4593:1010101E921092FE9292929CFEF01092108E928092B892A89EA8F32A012A0246 +4594:1020103E10207DFE1122113811E0FD22111E110021784948FD48464A024A0486 +4595:08000F0008787F4849484E7878484948477840484E484AFC4A02520291FE2000 +4596:08000F00087C7F5449544E7C78544954477C40104E104A104A12520291FE2000 +4597:01FC01003FFE210221F02F0420FC20282FFE28202BA428282BAC2A944BAC9044 +4598:10401E4010787E8853105CFC70A452A44EFC40205C505458545456929492210E +4599:3F9024183F1421123F10247C3F8020802FFC288428F02F84287C49E04924921C +459A:10201E4010FC7E8452845CFC708052FE4E8040FE5C0254AA54AA560294142008 +459B:08100F10087C7F1049FE4EA278444978471440FE4E104A544AB2520291FE2000 +459C:1E3C10207EFE52A25CB872E44E9C40805CB8952A23465FF010101FF010101FF0 +459D:0008007C07807900010001003FF82108210821083FF82100011001F87F042004 +459E:0808080808087F0849FE4908490849087F48482808280A080F08F10840280010 +459F:02000100FFFE100010001FF8000001001FF0111011101FF0110001087FFC2004 +45A0:100011F011107D1055105510559055507D505110111015121D12E612420E0400 +45A1:100011F810487C4854485448544855F87C885088108814881C88E48843FE0000 +45A2:1020102010207CA854A454A2552255207E245024102814081E10E22040C00300 +45A3:1008101C11F07D5055505550555055507D505148114815481D44E64442420400 +45A4:100010F83E884288A4A818941084207CC1001FF0111011101FF001087FFC2004 +45A5:1FF0022001407FFC048418886280010001001FF0111011101FF001087FFC2004 +45A6:1020102011247D245524552455FC54207C205124112415241D24E52441FC0004 +45A7:1000100010FC7C845484548454FC54847C84508410FC14841E00E20041FE0000 +45A8:1000100011FE7C2054205440544054FC7C845184128414841E84E28440FC0084 +45A9:1040102010287C0854085448545455527D525160126014441CC4E544423C0000 +45AA:088008882E9028A028C028842E84F07C01001FF0111011101FF001087FFC2004 +45AB:1010105010507C885488550456FA54207C20502011FC14201E20E22040200020 +45AC:100011FC11247D24552455FC552455247D2451FC112414201C20E42040200020 +45AD:1110091009207FFC0200FFFE08203018C1061FF0111011101FF001087FFC2004 +45AE:1020102010407DFC55045504557455547D545154115415741D04E50441140108 +45AF:01003FF80100FFFE01003FF80100FFFE000001003FF821083FF801087FFC0004 +45B0:1004101E11E07D0055065578555055507D52115415481D48E544425402620440 +45B1:100011FE11007D0055FE55105510557C7D105110111015FE1D00E50041FE0000 +45B2:1080108011FC7D04560455E4552455247DE45124112415E41D04E40440280010 +45B3:1020101011FE7D025400541C54E054207C20503E11E014201E22E222401E0000 +45B4:1050105010507D5254D45458545054587CD45152105014501E92E2924112020E +45B5:1020102010207DFC55245524552455247DFC5124102014281C24E5FE40820000 +45B6:100013FE10407C8055445624546854B07D305228106814A41D22E62040A00040 +45B7:218420682030F8C8AB04A840ABFEA8A0F920A3FC252429243934E92840200020 +45B8:02403C500848FFFE08480E5078240854198C01003FF821083FF801087FFC0004 +45B9:208820882088FB8EA888A888A800A9FCF820A02023FE28203820E82040200020 +45BA:1080108011F821082A906C60A9982E4628402BF82A482A482BF8204427FC2004 +45BB:1020101011FE7C205448548455FE54027CA850A810A814A81EA8E2AA412A0206 +45BC:21002100211EFB92A912A912A912AFD2F912A112221A2A943FD0EA5040100010 +45BD:03083C0804487F480C4816482508442805101FF0111011101FF001087FFC2004 +45BE:1020101011FE7D02560454F8540054007DFE5050105014501E92E292410E0200 +45BF:0C8070FC1124FD241224384454849128101001003FF821083FF801087FFC0004 +45C0:2020202021FCF820A820ABFEA888A944FA42A0F821882A503820E85041880606 +45C1:1020102011FC7C505488550457FE54087DE85128112815E81D28E40840280010 +45C2:10201020103C7C2055FC5524553055E07D24511C110015701D50E5524292050E +45C3:10481044105E7DE054285412546A55967C48505E11E014241E28E212406A0186 +45C4:1050108811547C2054D85706540854F07C80508010FC14901C90E51042100010 +45C5:100010FC10807CF8548054F8548057FE7D405124112815101D08E54441820100 +45C6:1020101011FE7D02560454F8548854887CF85080108014FC1E84E28440FC0084 +45C7:1080108010FE7D02562254AA547254227DFE5022107214AA1D22E422400A0004 +45C8:1040102013FE7C805480548054FC54007CFC508410FC14841EFCE28440FC0084 +45C9:10F8108810887CF85488548854F854007DFC5104110415FC1D04E50441FC0104 +45CA:102010A210A27D2454505488570454227C2050A410A415281C50E48841040202 +45CB:1088108813FE7C88548854F8548854887CF8502013FE14701CA8E52442220020 +45CC:100011FC11047DFC550455FC542055207DFE5220102015FC1C20E42043FE0000 +45CD:0FE010201FC00040FFFE0C1073200DC072B00C8EF3003FF821083FF801047FFE +45CE:100013FE10507C5055FC5554555455547DFC5020102015FC1C20E42043FE0000 +45CF:1040102011FE7D2254A45528545054887D0450F8108814881E50E22040D80306 +45D0:1040FEFE21203CAC24F427A444AC54A2887E01003FF821083FF801087FFC0004 +45D1:100010FC10847CFC548454FC548454207C1051FE100014841E48E20041FE0000 +45D2:210820902000FBFCA890A890A892AC92FA94A298209028903890E89047FE0000 +45D3:2080208020FCF954AAD4A8B4A92CAA44F894A108204028A43AAAEA8A44780000 +45D4:108010BC10847D0855FE57205520557C7D90511011FE15101D28E52841440182 +45D5:01007FFC50043EF84288A2AA1492187EE1001FF0111011101FF001087FFC2004 +45D6:20A820A823FEF8A8A8A8A800ABFEAA22F820A1FC212429243934E92840200020 +45D7:2210221023DEFD28A884A800ABFCA890F890A09027FE28903890E91042100410 +45D8:1020102010FC7C20542055FE544054847DFE500211FC15541D54E55443FE0000 +45D9:01007FFE44429FF404403FF80440FFFE082011102FE8C9260FE001103FF81008 +45DA:1028102413FE7C2055FC552455FC55247DFC5124100817FE1C88E44840480018 +45DB:2120213C2144FAA8AA10AEA8AAC6AABCFAA4A2BC22A42ABC3A24EA244224022C +45DC:204023BE2212FA92AA52AAAAAB24A840FBFEA22222222BFE3A22EA2243FE0202 +45DD:20201020FDFC092411FC392455FC9020102001003FF821083FF801087FFC0004 +45DE:00003FF80100FFFE02800C603018C00610207EFC52A47EFC10201424FEFE0202 +45DF:7F7848485F4C64805F7844484A4851307F4C01003FF821083FF801087FFC0004 +45E0:20401040FEFE21003DFE242224A044BC55608A3E01003FF821083FF801047FFE +45E1:200023FE2020F93CA920AFFEA880A8FEF900A1FE20022AAA3AAAEC0240140008 +45E2:1010105012507D7C5490541054FE57007D7C51441144157C1D44E50042FE0400 +45E3:08200820FFFE08200FE008200FE0000010207EFC52A47EFC10201424FEFE0202 +45E4:101011FE11107D7C551455FE5514557C7D10117C15541D7CE554427C0254044C +45E5:212421242224FC24A954A94AAA92AE10FA10A250225C2A503A50EAB0429E0300 +45E6:2020247C2284F948A830A8CEAE10AA7CFA10A27C22102AFE3A10EA1045FE0800 +45E7:1020101011FE7D10557C551455FE55147D7C111015921D54E538425402920430 +45E8:1040104010F87D08561055FC552455247DFC5124112415FC1C00E554412A022A +45E9:200C200A2008FBFEAA08AA48AA6AAA4AFBFAA24C224C2AEC3B5AEC4A44D60822 +45EA:00803FFE222022203FFC222023E020002A48312420802FF848884FF880841FFE +45EB:1020101011FE7D485548554855FE55487D4851EC115A15681D48E54842480048 +45EC:210013F0151000E0775C11F0104013FC284047FE01003FF821083FF801047FFE +45ED:2020202021FCF924A9FCA820ABFEAA22FBFEA020204028243AA2EA8A44780000 +45EE:2020202023FEF820AAAAA924AAAAA820FAAAA12422AA28503850E88841040602 +45EF:20282224217EF9C8A948A87EAB48A948F97EA1482148297E3940EA80447E0000 +45F0:200021FC2124FBFEA924A9FCA800A9FCF904A1FC210429FC3904E9FC40880104 +45F1:205022522154F850ABFEA888A850ABFEF820A1FC20202BFE3850E88841040602 +45F2:2020212420A8FBFEA8A8A924AA22A904F904A1DE22442D54389EE90442040404 +45F3:201023D22054F948A88AA904AAFAAC00F9FCA104210429FC3904E88847FE0000 +45F4:2110211021DEFAA8AC44A806ABB8A888F908A3BE20882A88393EEAC0443E0000 +45F5:100013FE10007DFC552455FC552457FE7C0051FC112415FC1D24E5FC400003FE +45F6:108813FE10887DFC550455FC550455FC7C8051FE122215521D02E5FA400A0004 +45F7:1040102011FC7C88545057FE540055FC7D0451FC110415FC1C20E694428A047A +45F8:0100FFFE104824FE799010FC22907CFC089030FEC1803FF821083FF801047FFE +45F9:2108209023FEF908A908AA52AB9CA908FA52A3DE204028A43AAAEA8A44780000 +45FA:00187BE0104022787A400A402BFC10002FFE400010207CF854A87CF81224FEFC +45FB:2108210821EEFA94A842A800ABDEAA52FBD2A25223D22A1A3A94EB5042100010 +45FC:201C21E02020FBFEA820A9FCA9ACA974F9FCA02021FC28203BFEE8004154022A +45FD:10A0209045FE792013FC25207DFC012055FE81003FF821083FF801087FFC0004 +45FE:200023FE2202FBFEAA02ABFEA908AA52FB9CA10822522BDE3800EAA442520452 +45FF:2040202023FEFA22A954A94AAA3AA800F9FCA15423FE280039FCE82040A00040 +4600:08003FF020103FF020003FF820083FF80100FFFE11207CF854A87CF81224FEFC +4601:08287F240820FFFE12203FA46424BF2824123FAA01463FF821083FF801047FFE +4602:2088208C23EAF888A888ABFEA948AB6AF94AA36A214C2B6C394AE96A47960022 +4603:21FC212421ACF924A9FCA820A9FCA820FBFEA154222A282039FCE82043FE0000 +4604:01081FD001207FFC02000FF03810CFF008100FF010207CF854A87CF81224FEFC +4605:20444258FF6201427E3E42007E4C42727E42423E10207CF854A87CF81224FEFC +4606:102013FE12227DFC542054F8542055FC7C2011FC15541DFCE44042A4028A047A +4607:01007FFC082007C01930EFEE09200FE001103FF810207CF854A87CF81224FEFC +4608:2FE829482BE8F95EA80AABEAAAAAABEAFAAAABEA288A2BEA3AAAEBEA4A2A1276 +4609:3FF801007FFC04401930EFEE09200FE001103FF810207CF854A87CF81224FEFC +460A:221023DE2528F884ABFCAA94AA94ABFCF828A3FE22202B243AA8EA92442A08C6 +460B:2148214C22AAF808ABFEA948AB68A94AFB6AA14A236C294C396AEB8A40160022 +460C:3FFC24202FF825203FFC220027F02A1033F03FFC10207CF854A87CF81224FEFC +460D:0820FFFE08201FF011101FF011107FFC41245FEC10207CF854A87CF81224FEFC +460E:244428E82E0EFCE4AA0AAEEEA8A0AAEAF800A3F820082BF83A00EBFC40040038 +460F:0800083E10227F245524552855245524552255225522553457A8FC2000200020 +4610:0800080010787F2855285528556C556A55AA552A5528552857C8FC4800980100 +4611:0830080810007F705510551A55DA555C55585558555455545794FC1200500020 +4612:0810081010207F4455FE5528554455A2553C5544554455A85790FC2800440082 +4613:08100810101E7F225524554055105566554255425566554257C2FC42007E0042 +4614:08200810107E7F425510551C552455545508553655C0553C57A4FC24003C0024 +4615:12001100211C4FC08000100023BE6288A2882288228822A824C8248828282010 +4616:10001200221C43C085001100213E6FC8A10821082548254825C8264820282010 +4617:11001540254E47C0800017C0221E6444A784210422442FE42104254429342308 +4618:21002FE0410E47C081001FE0221E6444A784210422442FE42104254429342308 +4619:110017C0224E4FE0800017C0245E67C4A10423C4250427E4210427C425542548 +461A:02000100FFFE05000C883450C530060E040001000100FFFE0100010001000100 +461B:200011F00110FD100910111011103510591095101510111211121212120E1400 +461C:202010200020FC2009FC11241124352459249524152411341128102010201020 +461D:205010480048FC40087C13C010403440584094201420102010141014100C1004 +461E:200013F80008FC0809081108110835FE58029402140213FA1002100210141008 +461F:200011FC0024FC24082411FC11203520592095FE14221022102A102410201020 +4620:204010400040FC4009FE10401040348458A494A4152811281210142810441182 +4621:2080208820B03EC020842684387C22000100FFFE05000C883450C530060E0400 +4622:204010200020F9FE090212041000340059FE9420142010201020102010A01040 +4623:209010900090F290129222D422986A90B2902A902290229223D22E12240E2000 +4624:204010500048F8400BFC104014E038E055509150124814441842104010401040 +4625:200011FC0124FD24092411FC11243524592495FC152410201020102010201020 +4626:200011FC0104FD04090411FC11003540594495481570114011421242123E1400 +4627:202010200020FDFC0924112411243524592497FE142010501050108811041202 +4628:204010200020FBFE0800108815043A0254889088105010501020105010881306 +4629:2080108001FCFD040A0411E41124352459E49524152411E41104100410281010 +462A:204010200020FBFE0840108815043BFE549290901090109011121112120E1400 +462B:080008007F7C114421441A440C7C32000100FFFE05000C883450C530060E0400 +462C:202810240024F8200BFE102011243524592497A8152811101212122A14461082 +462D:200011FE0020FC200848108411FE34225820942015FC10201020102013FE1000 +462E:010001007FFC11101110292845440100FFFE1200111010A010401430180E1000 +462F:2020112400A4FCA8082011FC1104350459FC9504150411FC1104110411141108 +4630:2004100E03B8F08810882128212E6BA8B0A82AA822A8213E21002280247E2800 +4631:0100FFFE0820111022880C603018DFF6101010101FF004880C503530C60E0400 +4632:200011FC0004F8FC080411FC100033FE560299F8148810881050102010D81306 +4633:202010200050FC880904120210F83420582095FC1420112410A410A813FE1000 +4634:220812280228F2281FA4224422546E92B7102AA02A203228224422FC22442200 +4635:200011FC0004F80409FC100414043BFE54209222117410A81124122210A01040 +4636:200011FC0008F010122222AA22726A22B2722AAA232622A22242220223FE2002 +4637:2020112400A4FCA8082011FC11243524597495AC152411241124110411141108 +4638:2080104007FEF1201120223C22446E64B2942B48224822302220225022882306 +4639:2040102003FEF8000888108815543A225400902013FE10201020102010201020 +463A:2040102003FEF2021404200023FE6820B0202920213C212022A02260243E2800 +463B:2040102003FEF880090413FE100235FC590495FC150411FC1104110411141108 +463C:2040102003FEF2021504210021DE6A52B2522B52249A2094211021122212240E +463D:20001040039CFA040A04139C120436045BFC949014901090109011121212140E +463E:2040102003FEFA020C0411F81108350859F89500150011FC1104110411FC1104 +463F:200013FE0202F20213FE221022926A92B2922AFE221022922292249224FE2802 +4640:200013DE0252F252125223DE22526A52B2522BDE2252225222522252255228A6 +4641:20481044005EFDE008281012106A35965848945E15E0102410281012106A1186 +4642:209010900108F1481244249221086BFCB044282020A42282228A228A24782000 +4643:2040104003FEF88009FC122015FE300055FC990415FC110411FC110411141108 +4644:2008103C01E0F820082013FE102034A0592C9524152411AC1124112411FC1104 +4645:200013FE0050F8500BFE125216523BFE5400904017FE10881190106010D81304 +4646:201013D40058FA52098C108815043AFA5420902011FE10201050108811041202 +4647:200013FE0020FC4009FC1154115435545954952C142013FE1050108811041202 +4648:210011780108F20812FE26402A406A7CB2902A1022FE22102228222822442282 +4649:2008101C01F0FD10091011FE1110357C5944957C1544117C11441244127C1444 +464A:20A810A803FEF8A808A8100013FE3622582095FC152411241134112810201020 +464B:2040102003FEFA020C0411FC100035FC590495FC150411FC1104100013FE1000 +464C:2020102001FCF92409FC102013FE340059FC9504152411241124105010881304 +464D:200013FA000CF84A0B88112A112635225BF8952A152C112A1128122A12261422 +464E:201E13E00122FC940840108811F0342058C495FE1422102013FE105010881306 +464F:2028102403FEF82009FC112411FC352459FC9524140813FE1088104810481018 +4650:200013FE0000F9FC0904110415FC380057FE928A125213FE12221222122A1204 +4651:2080104007FEF00013F822082FFE6A08B3F828A4212823102510294821862100 +4652:2040102003FEF840088811F01020344459FE940215FC112411FC112411FC1104 +4653:200013FE0252FA520BFE1020142039FC5420902017FE10401088110413FE1102 +4654:200013FE0200FA7C0A441244167C3A0056EE92AA12AA12AA12EE120013FE1000 +4655:212411240224F4A41154214A23926D08B1082928212E212821282158214E2180 +4656:202012220222F3FE100023DE22526A52B3DE2A52225223DE22522252255A28A4 +4657:2040102003FEF888085013FE16223AFA562292FA128A128A12FA1202120A1204 +4658:201410120010F7FE1410249024D26C92B7F22C94249425C82AAA289A31A62042 +4659:200013FE0202F3FE1210225422386A54B2822A50227C2290221025FE24102810 +465A:02001FF010101FF010101FFC10001FFC0004492C0200FFFE06801C48E530060E +465B:2040102003FEF88809241242109035F85808944414A81190128814A410C21080 +465C:2020147C0284F148103020CE26106A7CB2102A7C221022FE2210221025FE2800 +465D:0100FFFE08207E2008F8FF2814287F6A082AFF560B8204880C503530C60E0400 +465E:202017A400A8F2921114220825F46802B3F82A08220823F8220821102FFE2000 +465F:200017FC0444F5F4149427FC24046DF4B5142DF4244424F4254425FC244427FC +4660:200017FE0400F628154827EE24926C84B6A02EA827E824882494251429243242 +4661:202011FC0124F9FC082013FE100035FC590495FC150411FC110411FC10881104 +4662:210410880000FBFE0A2212AA1272322257FE980015FC110411FC110411FC1104 +4663:200011FC0040FBFE088811041652305057DE985015DC105013DE105010501050 +4664:2000127C0144F1741054205426FE6A82B2BA2AAA22BA2282228A2284250028FE +4665:200011FC0020FBFE0A2211AC142039AC545090C8132610F8100810D010201010 +4666:208813FE0088F9FC0954115415FC380057FE924210F810881148103010601380 +4667:201C11E00020FBFE082011FC11AC357459FC942015FC102013FE10001154122A +4668:21FC112401FCF92409FC102013FE34A859249642142013FE10601194168810C6 +4669:208813FE0088FBFE0A0211FC14003BFE544090A2135410B81354109213501020 +466A:22882108FABE2008729CA92A2288FFFE0A203118CFE6028804501C2065180606 +466B:209413980092FD8E0A8011FC112435FC592495FC148811FC108813FE10881104 +466C:23DE125203DEFA520BDE125217DE398C5652904017FE10881190106010D81304 +466D:204017FE0492F3FC109023FC20906FFEB1082BFC250A21F82240227C254028FE +466E:208813FE0088FBDE0A5213DE14A0389055FE912013FC152011FC112011FE1100 +466F:201417FE0490F4D4149427FA25AA6A96B1A22BF8220823F82040227C254028FE +4670:220C110A07C8F29E155426F4245E6FD4B1142FDE2554255425D4245E25502490 +4671:23FE120203FEFA920A54129216FE3AAA56FE932212FA12AA12FA122215FA1004 +4672:00007FFC044004403FF8244824483FF801000100FFFE0280044008203018C006 +4673:00007FFC044004403FF8244824483FF801001110111022A0044008203018C006 +4674:7FFC04403FF8244824483FF80200FFFE08201FF02828C8260FE00808080807F8 +4675:00007FFC04403FF8244824483FF801003FF80100FFFE000001003FF80100FFFE +4676:0010FE10281029FE2922FE20AA50AA50AAD2AACCAF48C24482448252FE608240 +4677:1FF010101FF010101FF010101FF004421842E03E0020FFFE0820042004A00040 +4678:00087E08420842FE7E08420842887E48424842087E0824282412240243FE8000 +4679:00007EFC2484248424FC24842484FFFC2484248424FC2450245024924492850E +467A:100011FC1104110455FC5904510491FC1104110411FC2850245044924112820E +467B:0800087C0B447C44487C484448447F7C09441944297C49288B28084A084A0886 +467C:00007EFC1284128422FC2A84448480FC3E84228422FC225022503E922292010E +467D:01000100FFFE0280244818303FF8D0161FF010101FF010101FF004421842E03E +467E:200010FC1084FE8482FC0484408440FC7C84408440FC40504C5070924092010E +467F:100010FC10847C8410FC10841084FEFC1084388434FC5250905010921092110E +4680:0800107C3E442244327C2A442A44FE7C224432442A7C2A282228424A4A4A8486 +4681:0800087C10447F44417C41445D44557C55445544557C5D284128414A454A4286 +4682:100010FC10847C8410FC1084FE8428FC28846C84AAFC2850285048924892990E +4683:0800087C0F440844087C7E444244427C7A444A444A7C7A284228424A7E4A4286 +4684:00007E7C02443E44027CFFC40844097C49442A441C7C2A28C928094A284A1086 +4685:0800087C0844FF44087C2A442A442A7C5D4488441C7C2A284928884A084A0886 +4686:2200227C7F4422442A7C08443E442A7C2A442A44FF7C08281428124A224A4086 +4687:1000107C52445144957C08443044C07C7E4442447E7C42287E28424A7E4A4286 +4688:0000FF7C144414447F7C554455447F7C084408447F7C082808280F4AF04A4086 +4689:20002F7CF5442544757C2544F544297C23440844087CFFA81428224A414A8086 +468A:2200147C00447F44007C14442244417C00447F44557C5528552857CAFC4A0086 +468B:00003E7C224422443E7C00447F44417C7F4441447F7C41287F28144A224A4286 +468C:0800107C7F4441447F7C41447F44107CFFC42244497C88A87F68084A084A0886 +468D:0800FF7C08447E44087CFF4400447E7C42447E44427C7E2842287E4A244A4286 +468E:0800087C7F4410443E7C1044FFC4227C414490C4267C22283628224A3E4A2286 +468F:08004A7C2C440844FF7C2A444944887C42447744927C5A282F28224A424A8286 +4690:4000777CA5442544FD7C27445544807C7E444244427C7E284228424A7E4A4286 +4691:0000FEFCAA84AA84FEFC00847C8444FC7C8444847CFC44507C5000922892450E +4692:1000087C7F442244FF7C00447F44497C7F4449447F7C08287F28084A0F4AF086 +4693:0000FEFC2884FE84AAFCFE8400847CFC44847C8444FC7C501050FE921092110E +4694:200010FCFE8482847CFC548498847CFCC4847C8444FC7C5044507C922892450E +4695:7700007C77445544777C554408447F7C54447F44557C7F2855285E4A554A9B86 +4696:0000FEFC1084FE8492FC54840084EEFCAA84EE8400FCFE505450BA921092FF0E +4697:200820487848484890447C8454A455227C20544054407C48548455FE44828C00 +4698:12001380249C490087C01540257E67C8A548254827C8254825482548246828D0 +4699:100010FE3C002400487CBE442A442A7C3E442A442A7C3E442A004A0042FE8600 +469A:101010503C50247C4890BE102A102AFE3E282A282A283E282A4A4A4A42868700 +469B:101010503C50247C4850BE902A102AFE3E002A002A7C3E442A444A44427C8644 +469C:102010403CFE24924892BEFE2A922AA23EFE2A482A883FFE2A084A0842088608 +469D:2040202079FE480090887C88555456227C00542055FE7C205420542044208C20 +469E:2020202078204BFE90207D24552455247EAA547054A87CA85524562244208C20 +469F:100010FC3C8424FC4884BEFC2A002AFE3E082BFE2A083E882A484A0842288610 +46A0:200021FC7904490491FC7D04550455FC7C00551255D47D185510555245928D0E +46A1:200021FC7924492491FC7D24552455FC7C20541054547D425542554A46388C00 +46A2:2048214879484BFE91487D48557855007DFE542057FE7C7054A8552446228C20 +46A3:100010FC3C84248448FCBE842A842AFC3E002BFE2A203EA02ABC4AA04360863E +46A4:1000107C3C542454487CBE542A542A7C3E102AFE2A923E962ABE4A82428A8684 +46A5:100010EE3C22242248EEBE882A882AEE3E222AAA2A663E662AAA4A2242AA8644 +46A6:2008203C79D0491C91107D7C555455587D705554554C7D40567854A8442A8C46 +46A7:200021DC7844495490CC7D54542854447D92542054C87C3254C4541844608D80 +46A8:201221D478484A8A91047E0255DC54547C6255C0551E7DC25454544845548CA2 +46A9:201821E078404BFE90887D74565254707C0055FC55047D745554557445048D0C +46AA:200021FC7954495491FC7C0057FE54007DFC550455FC7C625494558846A48CC2 +46AB:10207E204A7E7EC41028FF1020283EC652001FE020405FF091101FF011102130 +46AC:2020212478A84BFE90A87D24562255087DC8565E55487CA854BE550845088E08 +46AD:208823FE7888480091DC7D5455DC54887DFE569054FC7C9054FC549044FE8C80 +46AE:2000100011FCFE4400487C4800507C5E00427C424482448244827D0245140208 +46AF:100408040804FFA400247F2400247F2400247F244124412441247F0441140008 +46B0:208010801080FE8400887C9000A07CC000807C804480448444847C84447C0000 +46B1:202010201020FE2000207CA800A47CA401227D224622442044207C2044A00040 +46B2:200810081010FE2000407C8800087C1000207C444484440844107C2044C00300 +46B3:202010200020FDFE00207820002079FC00847888484848504820785049880606 +46B4:200010FC1084FE8400847CFC00847C8400847CFC4484448444847C8445140208 +46B5:200810881048FE4800087C8800487C4800087C0E45F8440844087C0844080008 +46B6:2000100011FCFE2000207C2000207DFE00207C204450445044887C8845040202 +46B7:209010900108FD0802047C0203FC7880010079F8480848084808780848500020 +46B8:202010201050FE5000887D0402027C8800887C884488448844887D0845080208 +46B9:201011100110FD120112791401D87910011079104910491249527992490E0000 +46BA:204010401040FE8000FE7D0802887C8800887C504450442044507C8845040202 +46BB:020007F0182062400980060019007FFC00003FF800003FF800003FF820083FF8 +46BC:200011F81048FE4800487C4800487DF800887C884488448844887C8847FE0000 +46BD:2008103C11E0FE2000207C3C01E07C2000207C3E47E0442044227C224422001E +46BE:2008103C11E0FE2000207C2000207DFE00207C204420442044207C2045FC0000 +46BF:204010401040FE7C00847C8801207C2000207C504450445044887C8845040202 +46C0:2008101C01E0FD00010079FC01447944014479284928491049107A284A440482 +46C1:200010FC1084FE8400847DFE00847C8400847DFE4484448444847C8444940088 +46C2:200810680388FC880088788800887BFE0088788848884888490879084A080408 +46C3:2000100011FCFC0000007C0003FE7C9000907C904490449044927D124512020E +46C4:42002200023CFBA402A472A404A474A40AB471285120512252227222541E0800 +46C5:200011FC1124FD2401247DFC01247D2401247DFC4524442044207C2044200020 +46C6:202010201020FE2001FC7D2401247D2401247DFC4524452445247D2445FC0104 +46C7:200010F81088FE8800887C8801067E0000007DFC4504450445047D0445FC0104 +46C8:204010401080FCFC01207E2000207C2001FE7C204450445044887C8845040202 +46C9:200011FC1104FF0401047DFC01207D2001FE7D204520451045127D4A45860102 +46CA:2000100010FCFE8400847C8400847C8400FC7C844400444844447C8444820102 +46CB:202810240024FC2001FE792001247924012479284928491849127A1A4A260442 +46CC:2040104010FCFE8401047EF400947C9400F47C844494448844827C82447E0000 +46CD:209010900090FBFC0094789403FC7A9002907BFE48924892491A79144A100410 +46CE:204010200020FBFE02027C04000078900090789048884908490879044A040402 +46CF:200010FC1084FE8400847CFC00807CA000A27CA444B844A044A27D22451E0200 +46D0:00003FF800087FC800083F8820883FA80110FFFE00003FF800003FF820083FF8 +46D1:200010400020FC280008788800907A9402A27AA24CC2488849887A8844780000 +46D2:00007DFE108010FC1E04F02801107FFC00003FF800003FF800003FF820083FF8 +46D3:0480248024FC24A02510040001007FFC00003FF800003FF800003FF820083FF8 +46D4:200013FE1020FE2000407DFC01547D5401547D544554455445547D4445140108 +46D5:2020102003FEFE2202227BFE02227A2203FE7820492048A0484078A049180606 +46D6:2020102001FCFD24012479FC0124792401FC782048244818483278CA4B060002 +46D7:00407E2049FE480048007EFC4200420042FC7E00480048FC488448847EFC0084 +46D8:20801088009CFD7001107B100510791001FE79104910491049107910497C0100 +46D9:209010900090FD1001FE7B100510793801387954495449924910791049100110 +46DA:08007EF808483E4808887EA809107FFC00003FF800003FF800003FF820083FF8 +46DB:2000100011FCFF0401047D7401547D5401547D544574450445047DFC45040000 +46DC:202010200040FDFC010479040194795401247924495449944904790449FC0104 +46DD:200011FC0024FC2401FC784400447BFE00007820482049244924792449FC0004 +46DE:200011FC1104FDFC01047DFC00007C0001FC7C20442047FE44207C2044200020 +46DF:202010200020FBFE002078200124792401247AAA482048504850788849040202 +46E0:200011FE1000FE0000FC7C8400847C8400FC7C004484444444487C0045FE0000 +46E1:201C13E00220FE2003FE7A2002907B0A020679FA490849084908790849F80108 +46E2:201C11E00020FC2003FE78A801247A22000078F8488848884888788A490A0206 +46E3:2020102001FCFD2401FC792401FC780003FE7880490049FC4804780448280010 +46E4:200010FC1084FE8400847C8400FC7C1000107C90449E449044907CD0453E0200 +46E5:218410680030FCC80304784003FE78A001207BFC4D2449244934792848200020 +46E6:200010501048FE8401247C2000507C8801067EF84488448844887C8844F80088 +46E7:201011101110FD9201547D1001FE7D1001387D544592451045107D1045FE0000 +46E8:2040102011FCFE0000887C5003FE7C2000207C2045FC442044207C2044200020 +46E9:200011FE1048FE4800487DCE01027D0201027DCE4448444844487C4845FE0000 +46EA:2040102003FEFA0200887904020279FC000479FC490049FC4804780448280010 +46EB:200010FC0080FCF8008078F800807BFE01407924492849104908794449820100 +46EC:2080108001FCFD04028478F40144784403FC78444954495449F4780448280010 +46ED:2020102001FCFC2000207BFE0088785001FC782048204BFE4820782048200020 +46EE:2088108810E8FD2C012A7EA800487CA0011E7E0044FC448444847C8444FC0084 +46EF:200011FE0102FD0201FE7910011079FE01107910497E494249427A424A7E0442 +46F0:200011FC1104FF0401FC7D0401047DFC00007D1245D4451845107D524592010E +46F1:2020102001FCFD240124792401FC78200040782048A44A824A8A7A8A44780000 +46F2:2020104001FCFD0401FC790401FC782000207BFE4A224A224A2A7A2448200020 +46F3:2020102003FEFC5000887924022279FC012479FC492449FC48227822481E0000 +46F4:2020102001FCFC500088790403FE780801E87928492849E84928780848280010 +46F5:201C13E00044F92400A8789003FE7A02000079FC488448884850782048D80306 +46F6:2020102003FEFC2001FC782003FE7820000078204BFE487048A879244A220020 +46F7:2040102003FEFA020504790001DE7A5202527B524C9A4894491079124A12040E +46F8:2020101001FEFD0001107910011E79100110797E4942494249427A424A7E0442 +46F9:208010FC0104FDF800087BFE004078A20334785848944B34485278904B500020 +46FA:21FC11240124FDFC0124792401FC7850008879044A8A48884888788849080208 +46FB:2008101C01F0FD10011079FE0110797C0144797C4944497C49447A44427C0444 +46FC:2040119C0104FD0401DC7904010479FC0000780049FC4820482078204BFE0000 +46FD:2008103C01E0FC2000207BFE002078A0012C7924492449AC4924792449FC0104 +46FE:2020102003FEFC2001FC782003FE7840008879F048244BFE482279244AA20040 +46FF:200013FE0000FDFC0104790401FC780003FE7A8A4A524BFE4A227A224A2A0204 +4700:400023DE014AF94A035A756A014A72D6002070205120513C5120712057FE0000 +4701:202011FC0220FBFE02007A2003FC7A2003FE7A004BE048204BFE785048880306 +4702:2020104001FCFD0401FC790401FC784003FE788849244A224DFC782048200020 +4703:20501048FEFE00907DFE00907CFE00907C9044FE7C8001003FF80100FFFE0000 +4704:200011FE0102FDFE011079540138795401827950497C499049107AFE4A100410 +4705:2020122203FEFC90008879FE03107D1001FE7910491049FE4910791049FE0100 +4706:00803FFE24103F7C26382D5434923FFC20002FF820002FF820004FF848088FF8 +4707:2040102003FEFC8801247A42009079F80008784448A849904A887CA448C20080 +4708:212412480124FC0001FC792401FC792401FC78204BFE487048A8792446220020 +4709:2020102003FEFC7000AC7B220050788801247A22492448A849247A2248A00040 +470A:2090109007FEF89003FC7A9403FC7A9403FC780049F8490849F8790849F80108 +470B:202011FC0124FDFC00207BFE000079FC010479FC490449FC490479FC48880104 +470C:1204110420082B8A4812F3BC100423884812FBBE0A820280AAAAABAA82A20000 +470D:2020102001FCFC200154788801047AFA008878F8488848F8482078A849240060 +470E:208812AA02DCFC8801547A2200007BFE02427C444BFC48444844788449140208 +470F:4020272005FEFD40057C7690057E7500057C7544557C5644547C74445444044C +4710:00407BFC488051F84A204DFC688852F84188FFFE00003FF800003FF820083FF8 +4711:200013FE0050FDDC0104790401DC785000507BFE4840482048A47A8A4A8A0478 +4712:2040108003FEFE2202AA7A2203FE7A7202AA7A0248204BFE4850788849040602 +4713:208813FE0088FC0001487BFE01487978010079FC48204BFE487078A84B260020 +4714:202010FE0240FD7C0090797E00007B7C0144797C4944497C4944794C4A80047E +4715:2088108803FEFC8801FC792401FC792401FC78204BFE4A224A2A7AFA4A0A0206 +4716:200013FE0050FBFE02527BFE000079FC010479FC490449FC490479FC48880104 +4717:4014201207FEF41005D0741405D4755805CA74165442582452A2728A54780000 +4718:4288228807E8FA90041E77E40454785407547554555457485548705452940122 +4719:200013FE0202FBFE02027BFE01087A52039C79084A524BDE48007AA44A520452 +471A:440022FE02AAF8AA00FE70100E54729202107254529252105210750058FE0000 +471B:208011F80210FDFC012479FC00927B0E008079F84A1049FC492479FC4892030E +471C:2040107C0040FBFE020279FC00A87954028879FC4A8A48F8488878F8488800F8 +471D:2044128402EAFE4E02A47AEE02227BFE02447A844AEA4A4E4AA47AEE4A2203FE +471E:4040202003FEF888005277AC02AA72A805AC7000510451FC510471FC51040204 +471F:2088108C03EAF88800887BFE01487B6A014A7B6A494C4B6C494A796A4B960022 +4720:2042139C0210FBDE02947A9404207BFC02047BFC4A044BFC4A047BFC49080204 +4721:43FC204001F8F90801F8710807FE744202A4728A547A508051F872885070038E +4722:202013FE0222FDFC002078F8002079FC002079FC495449FC48407AA44A8A047A +4723:0008201C11E0110001000100F1FE111011101110111015101910121002100410 +4724:011041102110211007FC0110E110211021102FFE200029103108220804040804 +4725:0000407C2F442144027C0244E4442744217C250025002AFE3200250008FE0000 +4726:0110211017FE1110020003FCF40413E4122413E4122417E41A24100400280010 +4727:000023DE114A114A035A056AF14A12D6102010201120153C1920112007FE0000 +4728:0020202011FC112401FC0020F3FE122213FE1020104014241AA2128A04780000 +4729:0110411027FC211001F00208E2EA26AC22A822AA26EA2A06300022A402520452 +472A:0040244022404A4089F8144822484148BC4824482448244A248A3C8A25060200 +472B:0000240022F84A208820142022204120BC2024202420242024203DFC24000000 +472C:0020242022204A2089FC152423244124BD2425FC2524252425243D2425FC0104 +472D:010001F801007FFE40029FF40820111022880C603018DFF6101010101FF01010 +472E:0020241022FE4A8289141450227E4150BC90241025FE241024103C1024100010 +472F:00402440227E4A82892214AA22724122BCFE2422247224AA25223C22240A0004 +4730:0020484045FC950411FC290445FC80407BFE488849244A224DFC782048200020 +4731:000049F8450895F8110829F8440083FC7A944BFC480049F84890786049980606 +4732:01244A484524940013FC2A94466482947BFC4A484B684A484B6A7A4A4A460362 +4733:00007FFC000000001FF0101010101FF008200440FFFE1000100010001FF80000 +4734:0020FE200020003E7C204420442045FC7C840088444828502E20F05041880606 +4735:0010FE10001001FE7D124514451045FC7D440144452829282F10F22842440482 +4736:0020FE20003C00447CA84410442844D67C1000FC441028902EFEF01040100010 +4737:0000FEFC0004007C7C0444FC440045FE7D0200FC444428442E28F01040680186 +4738:0000FEFE008200827CFE4480448C44B07C9C00B0449E28F02E92F112410E0200 +4739:0020FE2001FE00207C2045FC452445247DFC0020447028A82F24F22240200020 +473A:0048FE48004801FE7C48444845FE44007CFC0084448428FC2E84F08440FC0084 +473B:0000FEFC008400847CFC4484448444FC7C0001FE442028A02EBCF0A04160023E +473C:00207E20247E18A4FF2829104A2898C600007FFC00001FF010101FF004407FFC +473D:0020FE50008801047EFA440045E2452A7D2A01EA452A292A2FEAF122412A0164 +473E:0020FE1001FE00007C84444845FE44007CFC0084448428FC2E84F08440FC0084 +473F:00003F2024203F3E21403F5024883F0800007FFC00001FF010101FF004407FFC +4740:0020FEDE008A00CA7CAA44D244A644007CFE0092449228FE2E92F09240FE0082 +4741:08202AA42CA84920145022887FFE40029FF400001FF010101FF008200440FFFE +4742:7E7848487E8E420042F87E4848307ECE00007FFC00001FF010101FF004407FFC +4743:0000FEFE008200FE7C8244FE444444AA7CEE004444AA28EE2E00F0D440AA012A +4744:0108FA9403DE06B47BDE529453DE529473DE021097FC510860903860C1980606 +4745:0020FE200820102030204A209DFC28204C209A202A204820882008202BFE1000 +4746:08001FF822484488095012207FFC02000D1072A00CC071A006981886E2800100 +4747:000025FC2220424080A425382450249825382454249425502422440243FE8000 +4748:001CFDE01100210061FE95003900517C994435445554914811421242523E2400 +4749:044024481450FFFE800200007FFC02000D1072A00CC071A006981886E2800100 +474A:0020FC2013FE202061FC94243BFE502499FC34205520913E112012A0527E2400 +474B:0040FC2013FE2202600095FC380050009BFE3420552891241222142250A02040 +474C:0000FBDE2042414AA084154A3A525420980037DE505291521094114852542422 +474D:0000FBFE22224020A1FE142039FC512499FC352451FC902013FE102050202020 +474E:0020FD241124212461FC94003BFE5020984035FC55549154115411545154210C +474F:0020FDFC112423FE612495FC382051FC992435FC544093FE108811D05070238C +4750:0010FB9022FE42A0A2BE17483ABE52809ABE36A252BE9322123E122252222226 +4751:0020FDFC1088205063FE940039FC512499FC352455FC902011FC102053FE2000 +4752:03F0FD2E11E2212A61E495343BEA5032981E35E054A29134106810A453222020 +4753:0124FA4821244000A3FC16943A6452949BFC364853689248136A124A52462362 +4754:0088FBFE208843DEA25217DE38A0509099FE352053FC952011FC112051FE2100 +4755:03FCF90811F8210865F8990E37F8500897FE3A94579C9294139C12D657BC2084 +4756:1008201CD5F0095051502150D15019502950C94819482948C9440A4452422400 +4757:0C203020C22014204BFE3020C870147024A8CCA815242622C420042028201020 +4758:0C0030F8C288148848883106CA0015FC2484CC8414482450C420045028881306 +4759:0C0031FEC300150449443128C92815102510CD2815282544C584050029FE1000 +475A:100021FCD5040904510421FCD10019402944C94819702940C9420A42523E2400 +475B:10102010D41009FE51122114D11019FC2944C94419282928C9100A2852442482 +475C:10402040D488090453FE2002D08819442A42C8F819882A50C820085051882606 +475D:0C203020C3FC145048883104CBFE140825E8CD28152825E8C528040828281010 +475E:10202020D43E082051FE2122D13819E02922C91E19002978CA480A4A548A2906 +475F:1080209ED7EA088A51CA208AD3EA189228A6C8201BFE2820C850088851042602 +4760:100021FED5100920517C2144D17C1944297CC91019102954C9520A9252502420 +4761:10882088D7FE0888508820F8D0201BFE2A22CB321AAA2B76CA220A22522A2224 +4762:100021F8D50809F8510821F8D0001BFC2A94CBFC180029F8C890086051982606 +4763:1200217ED4400C7C524420FCD1401E7E2A20C8201BFE2870C8A8092452222020 +4764:0C203020C3FC142049543088C90416FA2488CCF8148824F8C42004A829241060 +4765:104021FCD50409FC510421FCD10419FC2820C92418A82924C8200BFE50202020 +4766:10402080D7FE0A52525227FED000181E2BE0C8A219222A74C8A8092456222020 +4767:00407C40448044FC7D04460444847C44444444147C2400442984240444288010 +4768:040025FC2488245024202450008C1FF010101FF010101FF010101FF008201010 +4769:00207C20445044887D04461244207C40458844107C2000442988241044608380 +476A:00007C0045FE44127C14441044907C90449E44907C90009028D02530451E8200 +476B:00807C80448044FE7D40454046407C7C444044407C40007C2840244044408040 +476C:00407C20440045FC7C20442044207C2045FC44207C2000202820242047FE8000 +476D:00807C80450045FC7E04440445E47D24452445247DE401242804240444288010 +476E:00207C10441045FE7C20442044447C8445F844107C200044288225FE44828000 +476F:00807C8044FE45007E204520452C7D7447A445247D3401282922250244FE8000 +4770:00207C20442045FC7C20442047FE7C08440845FE7C0800882848240844288010 +4771:02001FF0081010307EFC2244468C1FF010101FF010101FF010101FF008201010 +4772:00007CFC448444847CFC449044907C88448445327D0802002860241844048000 +4773:08000F7C28447F28A11016283846DFF010101FF010101FF010101FF008201010 +4774:01007FFC01001FF011101FF001007FFE50129FF410101FF010101FF008201010 +4775:00287C2445FE44207C2045FC45247D2445FC45247D2401FC292425244524810C +4776:00407C2047FE44007C0045FC45047D0445FC44207D2801242A22242244A08040 +4777:20003E7C48440844FF44247C42001FF010101FF010101FF010101FF008201010 +4778:00887C8847FE44887CA8442047FE7C20442045FC7C8400882850242044D88306 +4779:004078204BFE4A027D04490049DE7A524A524B527C9A0094511049128A12040E +477A:102008107EFC04482448183064CC1FF010101FF010101FF010101FF008201010 +477B:00007DFC450445047DFC451045107DFE451045107D7C014429442544457C8244 +477C:00207C2047FE44207DFC442047FE7C0045FC45047DFC010429FC250445148108 +477D:000079FE49104910797C4910491079FE490049107910017C51104A108AFE0400 +477E:3F500048FFFE08402F2028122F0AF0063FFA20083FF820083FF820083FF80820 +477F:0500397821083D7822083FF808203FF8D0161FF010101FF010101FF008201010 +4780:00807CBC448445087DFE472045207D7C459045107DFE01102928252845448182 +4781:00007BFE4A004AFC7A844AFC4A847AFC4A204BFE7A4802C852304A488A8403FE +4782:00007DFC442044407DFC455445547D544544452C7C2003FE2850248845048202 +4783:0008700857C85210721E54A457D47114511457D47114010851C84E1484140022 +4784:2040FEFE21203CAC24F447AC54A2887E00001FF010101FF010101FF008201010 +4785:000079FE4900497E790049FE49547948496449427900017E51424A428A7E0442 +4786:00207D2444A844207DFC450445047DFC450445FC7D04010429FC240044888104 +4787:08203E2008F87F282A685D2A08563E8200001FF010101FF010101FF008201010 +4788:001E7BE0494448A879F84908490879FC4904490479FE010252AA4AAA8D0A0004 +4789:00207D2444A845FC7C4047FE44887DFC468A44F87C8800F8288824F844508088 +478A:007C78404BFE4A427A784BC44A3C7AA84B544AF87B8C02FA52884AF88A8804F8 +478B:0200713C57A4502474BC532457A4713C512457A4713C059055584968812A0346 +478C:00087C3C45E05420542057FE54205420542055FC550411042904250445FC8104 +478D:00207C2047FE442055FC542057FE540055FC550455FC110429FC250441148108 +478E:00F87C88448854F85488548854F8540055FC5504550411FC2904250445FC8104 +478F:00007DFC4524452455FC5524552455FC54205410545411422942254A42388000 +4790:00207C2047FE542055FC544057FE5488550456FA5488108828F82488448880F8 +4791:08000800087C7E1008100810FF10141014105610551095102410241054FE8800 +4792:080008FE08827E8208BA0882FF8214BA14AA56AA55AA94BA24822482548A8884 +4793:080008FE08007E5208A40928FF94144A140056FE551095102410241055FE8800 +4794:080008FE08827E8208FE0880FF8C14B0149C56B0559E94F024922512550E8A00 +4795:0800087C08107EFE08920854FF101454140056FE551094FE24AA24AA54AA8886 +4796:0850084808487E40085C09E0FE400840282028242E14280C280458004FFE8000 +4797:0808080808087E0808FE0818FE180828282828482E482888281858004FFE8000 +4798:08400840087C7E8009000800FEF80810282028402E842884287C58004FFE8000 +4799:100013FE10207C20102011FCFD241124112451245D2451345128702050208FFE +479A:0810081008FE7E10081008FCFF040804286828102E282844288258004FFE8000 +479B:080009FE08207EA008BC08A4FEA408FC280428042E042828281058004FFE8000 +479C:0800080009FE7E1008200820FE68086428A229222E202820282058004FFE8000 +479D:0800080008FC7E2008200820FE2008FC282828242E24282029FE58004FFE8000 +479E:1050105010507DFC10541054FDFC1150115051FE5C525052505A709451108FFE +479F:0820082008407EFC08840884FE8408FC288428842E8428FC288458004FFE8000 +47A0:080009FE08207E200840087CFEC40944284428442E44287C284458004FFE8000 +47A1:0800080008FC7E84088408FCFE84088428FC28842E0029FE280058004FFE8000 +47A2:0840084008407EFE08A00920FE3C08202820283E2E202820282058004FFE8000 +47A3:0808081C08E07E80088008FEFE90089028B028982E94291029105A004FFE8000 +47A4:1080108011007DFC12041004FDE41124112451245DE451245004702850108FFE +47A5:0810081009FE7E20084008FCFF44087C2844287C2E442854284858004FFE8000 +47A6:08200820083C7E4408A80810FF2808442882287C2E442844287C58004FFE8000 +47A7:0808081C08E07E8008FE0880FE8008BC28A428A42EA4293C29245A004FFE8000 +47A8:0820082008FC7E20082009FEFE00082028FC28202E20282029FE58004FFE8000 +47A9:0810081008287E440882087CFF000800287C28442E44287C284458004FFE8000 +47AA:080008FE08807E8408B808A0FFBE08A428A428A42EC4288028FE58004FFE8000 +47AB:100011FC10447C4413FE1044FC4411FC108050FC5D84528450FC708450008FFE +47AC:080C087008107EFE08380854FE920800287C28242E2E2842288A59044FFE8000 +47AD:1020104810847DFE10021048FC841142107C50845D6850105068718450008FFE +47AE:0810081008287E4408BA0810FEFE0810285828942F122850282058004FFE8000 +47AF:080E08F008227E9208540800FF7C0808281028FE2E102810285058204FFE8000 +47B0:1020102011FC7C20102013FEFC501050115451525E5250905090713050008FFE +47B1:0828084408927E1008280844FE82097C284428442E44287C284458004FFE8000 +47B2:101010D813947C94109013FEFC94109410D853925CAA50CA5286710250008FFE +47B3:0820081008FC7E0008840848FEFE080028FC28842E8428FC288458004FFE8000 +47B4:11FC112411247D74112411FCFD041174115451545D7451045204721454088FFE +47B5:100011EE10227CAA104410AAFD32120011EE50225CAA504450AA711252208FFE +47B6:11F8110811087DF811081108FDF8108011FC52545C9451245244709451088FFE +47B7:100011FC11047DFC11001110FD541154117C51105D5451545254747C50008FFE +47B8:100010F810007C0011FC1020FD241222106050005DFC5104510471FC50008FFE +47B9:0820084008FC7E8408FC0884FEFC080029FE28202EFC282029FE58004FFE8000 +47BA:081E09F009107F1009FE0910FF7E0942297E29422F7E2942297E5A004FFE8000 +47BB:11F8105010207DFC112411FCFD2411FC112450405DFC50445084712852108FFE +47BC:0820083C08447E78080808FEFF20085228AC28582EAC284A28AA58104FFE8000 +47BD:08100810087C7E1008FE08A2FE440878281428FE2E10285428B258004FFE8000 +47BE:101E13E0123C7A2012FE12A2FAB812E4129C52805AB85328554A728650008FFE +47BF:01007FFE44429FF404403FF80440FFFE092017D02108DFF6010011F8290047FE +47C0:0844082808FE7E10087C0810FEFE08202820287E2E882908287E58004FFE8000 +47C1:1124124811247C0011FC1124FDFC112411FC50205DFE507050A8712452208FFE +47C2:10FC108410FC7C8410FC1000FDFE114A11FE50005CFC5048503070CC53028FFE +47C3:1040108811FC7D08125213FEFC50118C162251C85C3251CC503071C050008FFE +47C4:102013FE10207DFC102013FEFC0011FC110451FC5D0451FC510471FC50888FFE +47C5:08047F7808403E402A7E3E482A48FF4809883FF00100FFFC110011F8290047FE +47C6:11FC112411FC7D2411FC10A8FCA813FE10A850A85DFC502053FE702050208FFE +47C7:0894091809DE7E94095A09DEFE9409FE289028D42EAA29162A2258004FFE8000 +47C8:109411D210907DFE101011D4FD5411D4101453E85C8A51CA509673E250008FFE +47C9:11FC115411547DFC108011FCFE4411F4115451545DF4504451F4701450088FFE +47CA:1020103E10207DFE112211F8FD2211FE112051525DAC525A52AA744850908FFE +47CB:1040107C10847D0813FE1144FD92117C1100517C5D00517C5244727C54008FFE +47CC:1048104C11FA7C4813FE10A8FDFA134A15EC514C5DEA514A51F6712250008FFE +47CD:104011FC11247D94114C1124FDFC102013FE528A5D2453FE508070FC51048FFE +47CE:108811DC10887DDE10881154FE2211FC110451FC5D0451FC510471FC50888FFE +47CF:1124117412587BFE115412DAFBFE1082102053FE587050A85124722250208FFE +47D0:13FE120012227ECC124413EEFE4412EE135452105E90529E549073FE50008FFE +47D1:1020105010887D74120211FCFD5411FC100051FC5D5451FC5154710C50008FFE +47D2:108813FE10887BDE125213DEF8A011FE112053FC5D2051FC512071FE51008FFE +47D3:00007C0045FE442044207C201020102010205C205020502050205C20E0A00040 +47D4:00407E404240424042407E60085008484E444844484048404E40F04000400040 +47D5:00007DF8448844C844A87CA8108810505C505050502050205C50E08801040202 +47D6:00207C204420442045247D24112411245D245124512451245D24E1FC00040000 +47D7:00047C1E45F0451045107D10111011FE11105D1051105108510A5D4AE1860102 +47D8:00807C40444047FC44007C0011F011105D105110511051125D12E212020E0400 +47D9:00007900497E49124912791211D2171251125D12515251925922E022004A0084 +47DA:00007CFC4400440044007DFE104810485C485048504850485C88E08801080208 +47DB:00207C20442047FE44207C2011FC11245D245124512451345D28E02000200020 +47DC:00207C20442045FE45227D221122112211525D4A518A510251025D02E10A0104 +47DD:00007CF84488448844887D06120011FC10845C845048505050205C50E0880306 +47DE:00207C20442044A844A47CA21122112012245C245028500850105C20E0C00300 +47DF:0200077C384420442044207C3F90241024502C5C24502650255044B0449E8500 +47E0:00287C244424442045FE7D201124112411245D285128516851945D14E02C0044 +47E1:00047C1E45F0451045107D10111011FE11105D1051105108510A5D4AE1A60112 +47E2:00807C80448044FE45027D04122010205CA850A4512451225E22E02000A00040 +47E3:00207C284424442045FC7C20107010705CA850A8512451245E22E02000200020 +47E4:00407C204428440844087C48105411525D525160526050445CC4E144023C0000 +47E5:00007DF84408445044207C1013FE10625CA450A0512052205C20E02000A00040 +47E6:00087C3C45E0442044207DFE104010405C7C50A450A851285D10E22804440082 +47E7:00007C0045FC452445247D241124112411FC5D245124512451245D24E1FC0104 +47E8:00007DFC4504450445047DFC1120112011FE5D205120511051125D4AE1860102 +47E9:00207C20442045FC44207C20102013FE5C205040504050885D04E3FE01020000 +47EA:00047C1E45E0440044207C1011FE100410085C105020504050805D40E23E0000 +47EB:0100111009207FFE40029FF4101010101FF00100110011F81100290047FE8000 +47EC:00087C1C45E0450045007D00110011FE5D105110511051105D10E11007FE0000 +47ED:00807C80448044FE45407D401240107C5C4050405040507C5C40E04000400040 +47EE:00907C944492451245107F7E1510111011105D285128512851285D44E1440182 +47EF:00087C3C45E0442044207DFE102010205C2051FC510451045D04E10401FC0104 +47F0:00407C40449C450046407C4010BE118812885C885088508850885C88E0A80090 +47F1:00207C2047FE442044207DFC112411245D24512C507050A85D24E62200200020 +47F2:00407C20442047FE44407C88110413FE10925C905090509051125D12E20E0400 +47F3:00003EEE2222222222AA3E660822086628AA2E22282228AA284458004FFE8000 +47F4:00007DFE45004500457C7D00110011FE5D505152515451485D48E24402520460 +47F5:00287C244424442045FE7C20112010B25CB4506850A851245E22E02000A00040 +47F6:00207C2044A844A844A87D741222102010205DFC5020502050205C20E3FE0000 +47F7:0104790E493049204FE07920113E11641DA457245124512451245D24E1440384 +47F8:00207C20447C44C445287C90106011805C48504851FE50485C48E08800880108 +47F9:00047C1E45E0442245127C941080100811FE5C085088504850485C08E0280010 +47FA:00007EFC4284428442FC7E84088408FC4E84488448FC48004E48F04400820102 +47FB:00207C204450448845047E0210F810205C2053FE502051245D22E22200A00040 +47FC:00087C0C44EA440A44087DFE1048104811485D6851485148514A5D6AE3860102 +47FD:00407C2045FC444044907D0813FC10045D505150515051505E50E2520452080E +47FE:00007BDE4842494A4884794A125214201C0053DE5052515250945D48E2540422 +47FF:00007DF84408440845F87C08100813FE5C205222517450A85D24E22200A00040 +4800:00207D2444A444A844207DFC1104110411745D545154515451745D04E1140108 +4801:0040789049084BFC49087A1014A417BE50825C0053FC50005800E00007FE0000 +4802:082008207EFC08301C682AA4C92208201FF010101FF0010011F81100290047FE +4803:00007BFE482048204BFE7A221222133252AA5EAA537652665A22E222022A0204 +4804:00507C50445045FC45547D54115411FC5D545154515453FE5C00E05000880104 +4805:00007DFE4502451A45627D22112211FA5D225132516A51A65D22E12201FE0102 +4806:00007CFC448044F844807CF8108013FE11405D245128511051085D44E1820100 +4807:00007DFE4502450245FE7D10115211525D52517E511051525D52E252027E0402 +4808:0020782049FC482448247BFE1024102451FC5E22517450A85924E22200A00040 +4809:00207C1045FE450246047CF8108810885CF85080508050FC5C84E08400FC0084 +480A:00907C904490479E44907C901090139C10905C905090539E50905C90E0900090 +480B:00407C8045FC452445247DFC112411445DFC5090511053FE5C10E01000100010 +480C:00207C2247B444A844A87D2412A210405DFC510451FC51045DFCE10401140108 +480D:00007BDE4A424A424A427BDE1200123E53D25E12521453D45A08E21402240242 +480E:00007DFE4502450245FE7D0011FE11205D4451FE511251105EFEE210041009FE +480F:00107BD448584A52498C7888110412FA10205C2053FE502050505C88E1040202 +4810:00007DFC450445FC45047DFC110411FC5C28502453FE50505C50E08801040202 +4811:002078204BFE485048887B2611FC10201C2053FE5000502051FC5C20E02003FE +4812:00807C9E449245D244927C9E109211D25D52515E515251525DD2E022002A0044 +4813:00887C48445047FE44507C5011FC11545D54518C510451FC5D04E10401FC0104 +4814:00007C844448440045FE7C20104411A810305C585198503450525D90E0500020 +4815:009078924AD44A984A927AD2170E10201C2053FE507050A851245E22E0200020 +4816:00207D2044BE444244847F101110112811445C8250FC508450845C84E0FC0084 +4817:00207C4045FC450445FC7D0411FC11045DFC5028502453FE5C50E08801040202 +4818:00207C4045FC450445547D241154110411FC5C00511251D451185D52E192010E +4819:00207C1045FE448444487DFE1102122410105DFE5040507C50445C84E0940108 +481A:0080F04097FC94049110F208203C23D0A290BA90A290A288A288B4A4C4D40892 +481B:0008783C4BC048044A44792811FC12201C2053FE5020512451245D24E1FC0004 +481C:00887C8845FE448844007DFE1088108810F85C8850F85088509E5DE8E0080008 +481D:00007CF84488448844F87C0011FC11045DFC510451FC51045DFCE05000880104 +481E:0014F012901097FE9410F49024D22492A7F2BC94A494A5C8BAAAE89A11A60042 +481F:08207E2008F8FF2814287F6A082AFF5608821FF010101FF0010011F83100CFFE +4820:14507FFC245247CE80007FFC41043FF821083FF810101FF0010011F83100CFFE +4821:00207C3C442045FE45227D3811E4111C11005D7C5144517C51445D7CE14402FE +4822:0820FFFE08203FF824483FF800007FFE40029FF410101FF0010011F83100CFFE +4823:00007BDE4A524BDE4A107A5211CE10001C8853FE5088508853FE5C88E1040202 +4824:00007DDC4554455445DC7C0011FC112411FC5D2451FC502053FE5C20E0200020 +4825:0108F10895489390911EF7D425642554A554BF54A5D4A548A548B554C46404C2 +4826:00807CEE454A444A45FA7C4E10AA110010FC5C84508450FC50845C84E0FC0084 +4827:00007BFC4A044A044BFC7A2212FC122813FE5E2052FC538452FC5C84E4FC0884 +4828:00807CF8450847FE45447D9211FE11005D7C5100517C51005D7CE244027C0444 +4829:0020F13C912097FE9010F01423FE2210A3F0BA54A254A2D4BB68E44A08960322 +482A:00447A844AEA4A4E4AA47AEE122213FE12445E8452EA524E52A45EEEE22203FE +482B:03F0792E49E2492A49E4793413EA10321C1E53E050A2513450685CA4E3220020 +482C:00A0F74E915A952A922AF21C25DA280AA1EAB92AA1EAA22CA148B068C3880008 +482D:0108F10897CE91129124F7DE2552255EA7D2B91EA392A55EA940B114C1120122 +482E:012478A849FC48404BFE790813FC152251FC5D2051FC512059FEE00202AA0004 +482F:0040F0A0911092089DF6F0002EEE2AAAAEEEB800AFFEA922AFFEB922C92A0804 +4830:00887BFE48884BDE4A527BDE10A0109011FE5D2053FC552051FC5D20E1FE0100 +4831:03FE7A024BFE4A924A547A9212FE12AA52FE5F2252FA52AA5AFAE22205FA0004 +4832:102020207C5044507C8845247E12441045FCFC040C0814882450442094100810 +4833:102020207D2445247D2445247DFC44204420FD240D2415242524452495FC0804 +4834:102020107C1044007DFE44007C0444844484FC480C4814482450441095FE0800 +4835:104420447C4444847CBE45847E8444A44494FC940C8414842484448494940888 +4836:104020407C8044FC7D2046207C20442047FEFC200C5014502488448895040A02 +4837:105020507C5045527CD444587C50445844D4FD520C5014502492449295120A0E +4838:102020207DFC44507C8845047EFA440047FEFC400C8015FC2404440494280810 +4839:102020107C1045FE7C2044247C4444F84412FC220C4415882410442894440982 +483A:108020407C5E45027D02457A7D4A454A454AFD4A0D7A154A25024502950A0904 +483B:102020107DFE45027C4844847D0244FC4404FCFC0C8014FC2404440494280810 +483C:102020507C8845047EFA44007DE2452A452AFDEA0D2A152A25EA4522952A0964 +483D:102021247924492479FC48007BFE480049FCF904190429FC488888502BFE1000 +483E:100023DE7A524BDE7A524BDE7A024A224A22FA221A522A4A4A8A8A022A0A1204 +483F:102021FC7D2445FC7C2047FE7C0045FC4504FDFC0D0415FC250445FC94880904 +4840:101021FE7C0045FE7D02457A7D4A45FE4400FCFC0C8414FC248444FC940009FE +4841:111020907BDE48107A5E49827BDE48104BDEFA501BDE2A504BDE8A502A5212CE +4842:080408040844FF4408447F4449447F4449447F4C0874FF440804080408040804 +4843:104010401040FE4011FC7C4454447C4454447C841084FE841104110412281410 +4844:100010F01090FE9010907C9054907C9054907C901090FE9210921112110E1200 +4845:108210921092FE9210927C9254927C9254927C921092FE921092111211021202 +4846:101010901090FE8810887D2455247E2254207C401048FE44108411FE10821000 +4847:1000100011FCFE0010007C0057FE7C9054907C901090FE9011121112120E1400 +4848:100810881050FE2010507C8855007C0854887C881050FE501020105010881306 +4849:104010201000FDFC10007C0054F07C9054907C901090FE9210921112110E1200 +484A:1008101C11E0FD0011007DFC55447D4455447D281128FF101110122812441482 +484B:102010201020FDFE10207C2054207DFC54847C881048FE501020105011881606 +484C:104010401040FC4013FE7C4054807C9054907D201120FE481244148411FE1082 +484D:102010201020FC2011FC7C2054207C2055FE7C201050FE501088108811041202 +484E:102010101010FEFE10827C8254827CFE54827C801080FE801080110011001200 +484F:100811C81048FE4810487DC855087D0855107DD01054FE541052105E12821100 +4850:102010101010FEFE10827D0454407C4854507C601040FE4210421042103E1000 +4851:100011FC1104FD0411047DFC55207D2055FE7D201120FD101112114A11861102 +4852:1000100011FCFD2411247D2455247D2455FC7D241124FD241124112411FC1104 +4853:11001100211C47C0810017C0257E67C8A54827C821082FE82108210821282110 +4854:10201020107CFC8411487C3054207C4855907C3E1042FDA41018101010601180 +4855:100011F81010FC2010247DA854B07CA855287D241222FCA01040100011FC1000 +4856:1000100011FCFE0010507C8855247C2054207DFC1020FE201020102013FE1000 +4857:7DF0111011901D52F20E05001FF001001FF011101FF011101FF00100FFFE0100 +4858:1080108010FEFD0211027EFA54AA7CAA54FA7CAA10AAFEFA108A100210141008 +4859:1020101010FCFE8410847CFC54847C8454FC7CA210A4FE981090108810C41082 +485A:1020104011FCFD0411047DFC55047D0455FC7C501050FE5010921092110E1200 +485B:10101010FEFE10107C7C545454547C7C545454547C7C1010FEFE101010101010 +485C:1020102011FCFC2010207DFE54887D0456227C2011FCFE201020102013FE1000 +485D:2040202023FEFA022504F900A9DEFA52AA52FB52249AF894211021122212240E +485E:1FF010101FF010101FF01010FFFE11103FF8C1061FF011101FF01110FFFE0100 +485F:1020104010FEFC9210927CFE54927CA254FE7C481088FDFE1008100810081008 +4860:10201020103EFE2010207CFC54847CFC54847CFC1084FEFC1000104810841102 +4861:1110111211D4FD1811527D92552E7C4055FC7D041104FDFC1104110411FC1104 +4862:1040102011FEFD0211027DFE55007D0055FE7DAA11AAFEFE12AA12AA14A21086 +4863:100013FE1222FC2011FE7C2055FC7D2455FC7D2411FCFC2013FE102010201020 +4864:02003FD00260FFFE1C10EFF008100FF001007FFC11101FF01110FFFE01000100 +4865:1040102013FEFE0210507C8855247C5054887D0412FAFC881088108810F81088 +4866:21F820882070F98C2000FBDEAA52F98CAA52F82023FEF87020A8212426222020 +4867:1040108011FCFD0411047DFC55007DFE55007DFE1002FEAA12AA140210141008 +4868:082004407FFC0100FFFE04001FF0E1003FFC01001FF011101FF01110FFFE0100 +4869:1020102013FEFC2011FC7D0455FC7D0455FC7D0411FCFD0413FE108811041202 +486A:1020101011FEFD0211027DFE55007DEE55227DAA1166FD22116612AA12221466 +486B:10201220117CFCA410187CE657107D7E55107D7C1110FDFE1110111012FE1400 +486C:200021F82108F9F82108F9F8A800FBFCAA94FBFC2000F9F82090206021982606 +486D:1084104811FEFE1010FC7C2055FE7C40547C7CA41124FEFC1044104411FE1000 +486E:112411241224FCA411547D4A57927D0855087D28112EFD2811281158114E1180 +486F:1020104011FCFD24117C7D8C55547D2455547DFC1040FC2412A2128A14881078 +4870:0878FF4808863E782A483E30404881043FF801001FF011101FF01110FFFE0100 +4871:200023FE2200FA7C2244FA44AA7CFA00AAEEFAAA22AAFAAA22EE220023FE2000 +4872:100013DE1252FE5213DE7C0055FC7D2455FC7D2411FCFC2013FE102010201020 +4873:214021442158FBF02150F9D0A95EF9D4A954F95423F4F8142154223424142024 +4874:102011FC1088FC5013FE7C0055FC7D2455FC7D2411FCFC2011FC102013FE1000 +4875:104412241128FC7E10107C28574A7D1C55287D4C111AFD2A1148111012FE1400 +4876:201023C8227EFA402262FBD4AA00FA3EABC8FA48267EFA48224823C822482008 +4877:108813FE1088FC2011FC7C2057FE7C4054887DFC1000FDFC1154115417FE1000 +4878:108813FE1088FDFC11547D5455FC7C2854247DFE1120FD241114114A11961122 +4879:102011FE1020FDFE11027EFC54A47CFC54A47CFC1000FDFE10A210BC1160123E +487A:208823DE2088F9DC2088FBDEA888FBFCA804F9FC2004FBFC204022A4228A247A +487B:204021FC2124F994214CF924A9FCF820ABFEFA8A2124FBFE208020FC2104220C +487C:200021FC2020FBFE2222F9ACA820F9ACA800FBEE22AAFAAA22AA22AA23EE22AA +487D:252827BE2948FFBE2318FDAAA946FBFCAA04FBFC2204FBFC220423FC21082204 +487E:210821EC210AFFEA2928FBC8A93EFFE8A948FBE82A28FB682AA82BF42AB432A2 +487F:21FC202023FEFA2221ACF820A9ACF800ABBEFAAA23BEF80023FE212422AA27FE +4880:104010401040FEFE2080290048F87E08081008200E40F8804902090208FE0800 +4881:100010FC1084FE84208428FC48847E84088408FC0E84F8844884088409140A08 +4882:104010201020FE0021FE280048047E84088408480E48F848485008100BFE0800 +4883:00407C2045FC44887C5043FE7C20A5FC24203C2010080810066001800E70F00E +4884:101024FE42447E2800FE7E10427C7E10082008207EFC08301C682AA4C9220820 +4885:02001C7810081E7810081FF800003FFC20002FF820003FFE288848504A308C0E +4886:000001FE7D00457C450001FE39542948296429422B082DFE4948412882080418 +4887:200011FE7D00457C450001FE39542948296429422B082DFE4948412882080418 +4888:3FFC20002FF820003FFE286849104A888C643FF8D55613901FF00A2009200FE0 +4889:111827C8244836D8254826C837D800003FFC20002FF820003FFC24484430860E +488A:000023F81010102000400040F7FE104010401040104011401080280047FE0000 +488B:000023FC1090109000900090F090109010901110111012101410280047FE0000 +488C:0040404020402FFE00400040E7FC244424442444245424482040204050008FFE +488D:00802040104017FE01000100F1F8110811081108120812081450282047FE0000 +488E:000023FC1090109000900090F7FE109010901110111012101410280047FE0000 +488F:001021101090109000100210F1101110101E17F0101010101010281047FE0000 +4890:000021F81108110801F80108F10811F811081108110817FE1000280047FE0000 +4891:0008203C13E0122002200220F3FE122012101212128A13261212280047FE0000 +4892:0080204017FC100001100208F414111010A0104010A011101208280047FE0000 +4893:0040202013FE1202040401FCF020102017FE10201020102010A0284047FE0000 +4894:004020A0111012080DF60000F00013F812081208120813F81000280047FE0000 +4895:002820241024102003FE0220F224122413A812281212121A14261442288047FE +4896:0040204013F8104807FE0048F3F8104013F81040104017FC1040284047FE0000 +4897:0120412021202FFC09240924E9242FFC2924292429242FFC200050008FFE0000 +4898:0040202013FE120204140010F3FE1010111010901090101010101050282047FE +4899:000023FC1204120403FC0204F20413FC1204120413FC100011081204280047FE +489A:00004FFE204027FC044407FCE44427FC2040274020C020B02108220450008FFE +489B:000023FC12041294030C0204F2F41294129412F4120412141208280047FE0000 +489C:03F8200811F8100803F80000F7FC144413F81248124812681250284047FE0000 +489D:000027FE10901090039C0204F204139C10901090109017FE1000280047FE0000 +489E:0210421022102F7C02100630E7382AD42A52329223102210221050008FFE0000 +489F:0420422020202FBE04480488E72825282510291029283544228450008FFE0000 +48A0:00404244224424A801100208EC06211021102FFE21102210221054108FFE0000 +48A1:029042902FFC229002F00200E3F82040204027FC21502248244450408FFE0000 +48A2:004040A0211022880C4603F8E20823F8220823F8220025FC250429FC50008FFE +48A3:002020FE134C107007A001FEF00011FC100011FC100011FC110411FC280047FE +48A4:03904E18221422100F7E0610E7382AB42A54325022902210221050008FFE0000 +48A5:000027FC1040127802400FFEF00013F8120813F8120813F8120813F8280047FE +48A6:0080204017FC1040009005E4F24814A411F01010104017FC10401040284047FE +48A7:000027BC108414A4029404A4F0501188162610C0131010641388103028C047FE +48A8:02244224242429240154024AE6922A102250225E2250225022B0229E53008FFE +48A9:00105F902210221E0FA404C4E4943FD420082F88289428A22FC250008FFE0000 +48AA:0078478020802FFC01200210E5E8292627F8240825E8252825E8241850008FFE +48AB:072025FE1540157C0690057EF500157C1544157C1644147C1444144C280047FE +48AC:003C47C020442224010807FEE4022A08220823BE24882AA8213E220854088FFE +48AD:0208411027FC204003F80040E7FC20002440227C208422282C20245054888FFE +48AE:000047FC20402FFE08420358E0402358200027FC244427FC244427FC50008FFE +48AF:0244444820B0230C0C420244E4A823183C06240827BE28883528223E54088FFE +48B0:07BC208414A4129404A40120F21017FC1A2013FC122013FC122013FE2A0047FE +48B1:004027FC104013F8000007FCF4A417FC120813F8120813F8120813F8291047FE +48B2:07BC24A417BC14A407BC0140F3FC124017FC1A4013FE129010601398280047FE +48B3:00003C7C24442448244824502448244824442444244425684650444080400040 +48B4:0000077C78440848084808500848FFC808440844104410682050204040408040 +48B5:00007E7C004400480048FF50104810482044204444444268FF50414000400040 +48B6:0800087C084408487F48085018481C482A442944484488680850084008400840 +48B7:00003F3E212221242924252825242124FFE22122212221342128412045208220 +48B8:00003F3E2122212421243F28212421243F2221222122213427A8F82040200020 +48B9:00007FBE4022402440247F2841244124412241227F224034402840207FA00020 +48BA:0800087C49444948494849507F48084808444944494449684F50794000400040 +48BB:00007FBE4822482448247F2841244124412241227F224834482848207FA00020 +48BC:1200123E122212247F241228122412241222FFA2002212341128212020A040A0 +48BD:044004407FFC0440FFFE10102FE8C8260FE000001FF011101FF0100410040FFC +48BE:0800287C28443E484848085008487F4814441444144414682550264044408040 +48BF:1000083E0822FFA480A411281024FFA42222222242223434082814202220C120 +48C0:1000107C3F4421484248BFD020482F48294429442D442A6828504A404C408840 +48C1:0000F7BE10A210A494A452A852A410A431A252A294A210B410A810A052A02120 +48C2:0800087C08447F4808483E5008487F4818441C442A442A684850884008400840 +48C3:2000207C3F444848884808507F48084808442E44284428682F50F04040400040 +48C4:0800087C144422484148BE50084808487F4408442A4429684950884028401040 +48C5:00003FBE202220242F24202820243FA4282228A22D222A34292848A04C208820 +48C6:00007FBE002224A449249228492424A400227FA20822083408280BA0FC200020 +48C7:08000A7C094408487F480850084849482A4408441C442A68C950084028401040 +48C8:00007CF8448844887CF800007DFC5524552455247DFC410041004D02710240FE +48C9:20401248444420140860738020001FF010101FF000003FF821083FF820021FFE +48CA:0800493E29222A2408247F28412441245D225522552255345D28412045204220 +48CB:010007BE782208A444A42528202404247FA20C221622153424A8442084200420 +48CC:0800041E7FD2401243945E14521852145FD252125212521A5554595094D00250 +48CD:0800083EFFA214242224492888A47F2449227F2249227F3408280A200C200820 +48CE:248024BE49229224492424A824A400247FA248A248A27FB448A848A07FA040A0 +48CF:1500153E152225242FA465286524A524252225223FE22034252824A028A03020 +48D0:2200227C7F4422482A4808503E482A482A442A44FF4408681450124022404040 +48D1:00003FBE20222FA42AA42AA82FA42AA42AA22FA222222FB4422843A09C200820 +48D2:0800083E7F2249247F240828FFA400247F22412249224934492814202220C120 +48D3:0000FFBE00227F24412441287F240024FFA2A2A294A2FFB488A888A08AA08120 +48D4:0800497C2A4408487F48415041487F4841447F44414441687F50004022404140 +48D5:00007FBE48227F2448247F28482448247FA200A2AAA2AAB4AAA880A005200220 +48D6:00007E7848487E4848787E0048FC48A47EA402A4AAFCAA80AA8082821482087E +48D7:0800103E7F2241247F2441287F241024FFA22222492288B47F68082008200820 +48D8:0800493E2A22FFA480A43E28222422243E2208227F22083408280F20F0204020 +48D9:0400445E44527FD200147BD44A584A547BD24A524A527BDA4A544A50AB501490 +48DA:08007F3E4922FFA449247F2808247F2449227F221022FF34212872200C20F320 +48DB:0800083EFFA21C242B24C8A814242224492288A249222A34492888A028201020 +48DC:08000F3E08227FA448A44E287924472440225F2251225F3451285F2051A0BE20 +48DD:00003FDE205220523FD422342FD822943FF222122FD2385A2FD448504FD08850 +48DE:0000F7BE94A294A4F7A422281424FFA40822492249227F340928102020204020 +48DF:0000F7BE2122A524F7A46328B5A421247FA240A240A27FB440A840A07FA040A0 +48E0:1100111E7BD21112FFF411142A9844543FB2209220923F9A209420903F902090 +48E1:4100223EFFA208247F240828FFA4152464A22422FFA224343528E2A025A068A0 +48E2:2280229E27D2FA922294729427F8F81427D274526C52A7DA2454245027D02450 +48E3:2480151E7FD240521F1411147FD855544E527FD204127FDA0414FFF02A504530 +48E4:7BC04A5E7BD24A527BD414143FD86414BF9224123FD2001A3F9410900F10F090 +48E5:0020FFA0142014227F225524552855305720612041207F22412241227F1E4100 +48E6:0020FFA0142014207F7C5524552455245724612441247F24414441447F944108 +48E7:0020FFA8142414247F20553E55E055205720612041207F20411441147F0C4104 +48E8:0010FF901410141C7F70551055105510571E61F041107F12411241127F0E4100 +48E9:0020FE20282029FCFE20AAA8AAA8AAA8AEA8C2A882F8FE2282228222FE1E8200 +48EA:0010FE10281028FEFE10AA10AAFEAA92AE92C2928292FE9A82948210FE108210 +48EB:0010FE10281028FEFE10AA10AAFCAA44AE44C2448228FE2882108228FE448282 +48EC:0048FE4428442840FE5EABE0AA40AA44AE44C2488230FE228252828AFF068202 +48ED:0010FE1428122812FE10AAFEAA10AA10AE10C2288228FE2882288244FE448282 +48EE:0028FE2428242820FEFEAA20AA20AA3CAE34C2548254FE5482888288FF148222 +48EF:0000FFBC142414247F24553C552455245724613C41247F24412441247F7E4100 +48F0:0000FFBE142014207F20553E5522552257226122413E7F20412041207F3E4100 +48F1:0020FFA01420147C7F445584557455545754615441747F54410441047F284110 +48F2:0020FE2028402848FE84AAFCAA04AA48AE48C2FE8248FE4882488288FE888308 +48F3:0000FEFC28042804FEFCAA04AA04AAF4AE94C2948294FEF482048204FE148208 +48F4:0000FE4428282892FEAAAAC6AA82AAFEAE28C2288228FE288248824AFE8A8306 +48F5:0000FEFE28482848FE78AA48AA48AA78AE48C248824EFEF882088208FE088208 +48F6:0008FE1C28702810FE10AAFEAA10AA10AE10C27C8244FE4482448244FE7C8244 +48F7:0010FE502850287CFE90AA10AA10AAFEAE10C2388238FE5482548292FE108210 +48F8:083813C0304057FC9040104013F81000FFFE04403FF82848303827C820083FF8 +48F9:0050FE5828542894FE90AA9CABF0AA94AE94C2948298FE9882948294FEAC82C4 +48FA:0000FE7C28442844FE7CAA00AAFEAA82AE82C2FE8282FE8282FE8282FE8A8284 +48FB:0010FE1028282844FE92AA08AA7CAA04AE08C210827CFE4482448244FE7C8244 +48FC:0020FE1028FE2800FE00AA7CAA44AA44AE7CC2108254FE5282928210FE508220 +48FD:20003E7C48440844FF441444227C4000FFFE04403FF82848303827C820083FF8 +48FE:0020FE1028FE2882FF04AA7CAA44AA44AE7CC2448244FE7C82448244FFFE8200 +48FF:0000FE7C28102810FEFEAA10AA10AA50AE20C2FE82AAFEAA82AA82AAFFFE8200 +4900:0044FE4429FE2844FE54AA10ABFEAA20AE40C27E82C2FF4282428242FE7E8242 +4901:0048FE4829FC2848FE78AA48AA78AA48AE48C3FE8280FEA882C48280FEFE8200 +4902:0088FE882BFE2888FE88AAF8AA88AA88AEF8C22083FEFE7082A88324FE228220 +4903:0040FE2029FE2800FE84AA48ABFEAA00AEFCC2848284FEFC82848284FEFC8284 +4904:0000FEFE28102820FEFEAAAAAAAAAABAAEAAC2AA82BAFEAA82AA82AAFEFE8282 +4905:0010FE1028282844FE82AA7CAA00AAE2AEAAC2AA82EAFEAA82AA82E2FEAA82A4 +4906:0010FED42848294AFE84AA84AB02AAF8AE20C22083FCFE2082508248FE848304 +4907:0020FE1028FE2882FE28AA44AA92AA28AE44C282827CFE0482288210FE2882C4 +4908:0044FE82297C2820FE40AA7CAA04AA28AE10C2FE82AAFEAA82AA82AAFFFE8200 +4909:0010FE0C282428AAFEB0AB24AA64AB9CAE00C2FE82AAFEAA82AA82AAFFFE8200 +490A:0044FE4428FE2844FE00AAFEAA44AA44AE7CC244827CFE44824E82F4FE048204 +490B:4408240C280AFE0829FE2808FE08AAEAAAAAAEAAC2ECFE0C822A82CAFE168222 +490C:0020FE2028502848FEA4ABFEAA84AAFCAE84C2FC8280FEFC83448344FE7C8244 +490D:0088F88823FE2088F888A8F8A820ABFEDA228B328AAAFB768A228A22FA2A8A24 +490E:00FCFE28281029FEFE52AA94AB50AA20AEFEC2AA82C6FEBA82AA82BAFE828286 +490F:0028FEEE282828EEFE28AAEEAA28AA06AEF8C21082FEFE1082FE8210FE508220 +4910:0000FBDE208822A8FBFEA988AADAACA6D9F889088908F9F889088908F9F88908 +4911:0028FE28287C2828FE28AAFEAA10AA7CAE54C27C8254FE7C82008228FE448282 +4912:0124F92422AA23AEF924AAAAABAEA924DBFE89108914F9148A8A8A4AFA168C22 +4913:0048FE4829FE2848FEFEAA82AB7CAA00AEFEC22082D2FE2C82D8822CFECA8230 +4914:42043FD88A904F9E2A945FD48224FFFE04803FF82488287830083FF820083FF8 +4915:0124F974225822DAFBFEA954AADAABFED8A288208BFEF87088A88924FA228820 +4916:01FCF90421FC2104F9FCA888A9FCA888DBFE88888924FAAA887088A8F9248860 +4917:08207F7C14C47F3822D63E3822507F7C0810FFFE04403FF8284837B820083FF8 +4918:0148F94C22AA2008FBFEA948AB68A94ADB6A894A8B6CF94C896A8B8AF8168822 +4919:00F8F90821F02010FBFEA8C4AB28A8D4DB3288D08A28FFBE8AAA8FBEFA8A8FBE +491A:00003DFC2524252425FC3D24252425FC24203C2025FC24202420442057FE8800 +491B:10041004288424844284BC8410841084FE8C109494E4588450041E04F0044004 +491C:102010202820243C41E0B82010201020FC3E13E09420582250221C22E01E4000 +491D:10001040299E25124112B91211121112FD121112955A599451101C10E0104010 +491E:10401050284824484040B9FE10501050FC5010509490589050921D12E10E4200 +491F:1000100029FE25024302BC0010781048FE4810489448584A504A1E8AF0864100 +4920:10101010281024904290BC90109E1090FE9010909490589050901E90F1FE4000 +4921:10201020282025FC4124B92411FC1124FD24112497FE590451041D04E1144108 +4922:100011FC290425044104B9FC10401040FDFC10449444588450841D04E2284410 +4923:1008103C29E024204124B8A410A81020FDFE10209420582050201C20E0A04040 +4924:10201010281025FE4220BC24104410F8FE1210229444598850101E28F0444182 +4925:1040104028FC25044208B9FE1100117CFD4411449554594851421E42E23E4400 +4926:10A810A428A42520412EBBF015201124FD2411249528591051321D4AE1864102 +4927:1000100029FC25044104B97411541154FD5411549574590451041DFCE1044000 +4928:1004101E29E025004106B97811501150FD5211549548594851441E54E2624440 +4929:1020101029FE25024000B81C10E01020FC20103E95E0582050221C22E01E4000 +492A:100010F8288824884088B88811261220FDFE1020947058A851241E22E0204020 +492B:102011242924252441FCB82010501088FD441222942059F850081C10E0104020 +492C:201022105110491084547A5222522090F81021142E04B20862083A10E22000C0 +492D:21842068503048C88304784023FE20A0F92023FC2D24B12461343928E0200020 +492E:101010102890249E4090B89013FE1000FC1010929492591452081C10E0604380 +492F:100213E2294425484140B942114213E4FD4811409542594251441E44E2484450 +4930:108010807DFC124410481CA0E11006C81830EFEE01003FF809200540FFFE0000 +4931:10201124292425FC4000B80C11F01100FD0011FE9510591051101E10E2104410 +4932:1020102029FC24204020B82013FE1048FC48114C954A5A4A50881C88E1284210 +4933:2080204057FE492081207A3C22442664FA9423482A48B23062203A50E2880306 +4934:200021FC5008481082227AAA22722222FA7222AA2B26B2A262423A02E3FE0002 +4935:109010902890279E4090B8901090139CFC90109094905B9E50901C90E0904090 +4936:102010202BFE24504088B924122211FCFD2411FC952459FC50221C22E01E4000 +4937:200023FE52004AFC82847AFC228422FCFA2023FE2A48B2C862303A48E28403FE +4938:208020FC510449F880087BFE204020A2FB3420582894B33460523890E3500020 +4939:104010202BFE262240A4B92810501088FD0410F89488588850501C20E0D84306 +493A:100010022BDC24904090B91011DE1354FD541154955459D451541C24E0244044 +493B:104010402BFE248041FCBA2015FE1000FDFC110495FC590451FC1D04E1144108 +493C:2040208051FC490481FC790421FC2020F83223B428A8B12861243A24E4A20040 +493D:100011FC295425544154B9FC102010A8FCA41124942058A850A41D24E0204020 +493E:101E11E0282225124094B880102011CEFD02110295CE590251021D02E1FE4102 +493F:108013DE288A25CA408ABBD210A61008FCF0102095FC582053FE1C20E0A04040 +4940:10201124292425FC4020BBFE10001020FDFC1124952459FC50201C24E3FE4102 +4941:200023FC500848D080207BFE228A2252FAFA22222A22B3FE62223A22E3FE0202 +4942:200023FE52024CFC800079FC204020A4FB3820582894B33460523890E3500020 +4943:104010402BFE26924088B9FE13101510FDFE1110951059FE51101D10E1FE4100 +4944:200023FE52004A4882487AFC22482248FBFE22002AFCB28462FC3A84E2FC0484 +4945:01007FFC01007D7C11107D7C11101CFEE10006C01830EFEE01003FF80920FFFE +4946:0100FFFE04407C7C04403C7804407D7C06C01830EFEE01003FF811100920FFFE +4947:1020101029FE25024102B9FE110011EEFD2211AA9566592251661EAAE2224466 +4948:2088208853FE488880247BFE20502088F904228A2888B3FE60883888E1080208 +4949:100013FE2A02244040F8B908121011FCFD24112495FC585050581C96E112420E +494A:102013FE282025FC4020BBFE100011FCFD0411FC950459FC51041DFCE0884104 +494B:1020101029FE240042FCBC8410FC1000FEFC10089410585050201E00F1544252 +494C:020001007FFC40043C7824483C7824483D7806C01830EFEE01003FF80920FFFE +494D:08207E2008F8FF2814287F6A082AFF56098206C01830EFEE01003FF80920FFFE +494E:23FE220052FC4A0083FE7A9422A822C4FA0022FC2A84B2FC62843CFCE484088C +494F:2280228E54EA494A804A724A25EA2C4AF44A256AA54A754E25683788C4080408 +4950:00207E7C14C40838FEC62A2048FCA844118C06C01830EFEE01003FF80920FFFE +4951:102010202BFE24A840A8B97412221070FCA811469478588851501C20E0504180 +4952:7CF8048804F87C2041FC7D2405FC04282BFC16C41830EFEE01003FF80920FFFE +4953:1088108829FE248840F8B88810F81088FDFE108895245AFA50201C20E1FE4000 +4954:200023FE5050485083FE7A52225223FEF92420A82BFEB07060A83924E6220020 +4955:2108210855484B90811E77D425642554F5542754A5D4754825483554C46404C2 +4956:108810502BFE245041FCB954118C1174FD0411FC94205BFE50501C88E1044202 +4957:2108210857C84908811E7B9220242380F80827C82908B10865943954E1240342 +4958:10881088295426224088B88811541222FDFC1104950459FC51041D04E1FC4104 +4959:2044272455284D7E85107630254A251AF52C254CA51A762A24483408C4280410 +495A:3FF820082EE82AA82EE82AA82EE82AA82FE8228824483BB8210A4FEA45469FF2 +495B:108013DE288A25CA408ABBD210A61040FC8811F094245BFE50221D24E2A24040 +495C:200023DE52524BDE82527BDE22222222FAFA22222A72B2AA63263A22E22A0204 +495D:202023FE52504BFE82527BFE229422D8FA9222CE2A00B28462983CE2E482087E +495E:2108220827C854508FDE746427D42214F91427D42A14B3C862483C54E55408A2 +495F:2200227C52444A7C87447A7C2220237EFA9226522A6AB242627A3A02E2140608 +4960:2088208853FE48888014781223FE2210FAF422142AF4B2A862AA3AFAE2160422 +4961:2114255455544DFE855477D4245C2440F77E2510A5FE751025383554C5920910 +4962:0810FF7E08107F7C41047F2822101F28E14406C01830EFEE01003FF80920FFFE +4963:2C7844486C4844867D7800487C301048FD8406C01830EFEE01003FF80920FFFE +4964:11FC10202BFE262241ACB82011AC1040FCFC110496F4589450F41C8AE082407E +4965:202023FE5088485083FE7A5023FC2254FBFE22542BFCB25062D83D54E6520850 +4966:202021FE54404AFC81107AFE200026FCFA8422FC2A84B2FC62843A8CE50008FE +4967:2040207C50404BFE820279FC20A82154FA8821FC2A8AB0F8608838F8E08800F8 +4968:200023DE52524BDE82527BDE220222FAFA8A22FA2A02B2FA628A3AFAE2020206 +4969:228822A856A84BF0801E722425D42C14F41425D4A554754825683554C6140422 +496A:200023FE52024BFE82027BFE21082252FB9C21082A52B3DE60003AA4E2520452 +496B:2110211457D249108FFE729024502FF4F49427F4A49477E8248A37FAC4260042 +496C:108813FE2888242443FEB82011FC1124FDFC112495FC592450081DFEE0884058 +496D:14141010FEFE10105454383854549292313006C01830EFEE01003FF80920FFFE +496E:200023FE50504BFE82527BFE200023DEFA9223D22A52B3D2629A3A94E3D00010 +496F:200023FC52944A9483FC7910225223DCF81223CE2A40B3D2625C3BD0E25202CE +4970:2040202057FE4900810079FC20002088FBFE22AA2AAAB3FE608838AAE3FE0022 +4971:202023FE52024840819C790421DC2104F9FC21002BFEB40262AA3AAAE4140008 +4972:200827E854084DC8855E755225E42400F7E826A8A6A877E8241437F4C0240042 +4973:23FC204051F8490881F8790827FE2442FAA4228A2C7AB08061F83A88E070038E +4974:2020222253FE489081FE7B1025FE2110F9FE211029FEB10063DE3A52E2720206 +4975:20102010577E4D1085FE754425EE2744F56425DEA50075FE2728352AC04A0086 +4976:200023FE52224ACC82447BEE224422EEFB5422442A10B210625E3A50E25005FE +4977:244227722AA2511A8BEA722A23EA222AFBEA222A2BEAB14A67F23942E24A0444 +4978:F7FC124817FCFC4686ECF55416EC155457EC26C41830EFEE01003FF80920FFFE +4979:208023DE508A49D280A67BD0209C2050FBFE20502AAAB3FE62523AAAE3FE0002 +497A:200023FC3810211041107910A21023FEF8302050209021102A10341020500020 +497B:100010003DFC20204020BC20102013FEFC5010501050109014921912120E0400 +497C:108010803C8020FC4154BE5410541094FC941124122410441444188411280010 +497D:204020483A44224043FE7880A08020FCF9442144214822502A20345028880306 +497E:200023FE3A022484408078FCA0802100F9FC2004200423F42804300420280010 +497F:1008101C3DE021004100BDFE11201120FD3C11241124112415241A4412540488 +4980:200027BC3884208444A47A94A2942084F98C229424A420842884308422940108 +4981:2100211E391227D241147914A7D82114F91227D22112211A2914321022100410 +4982:204020203BFC220442047BFCA20023DCFA44235422CC22442ACC3554244408CC +4983:208820883BFE20A8402279FAA0242028FBFE204020FC21842AFC348420FC0084 +4984:102013FE3C2021FC4124BDFC112411FCFC2213FE1050109415881AA814C40082 +4985:208820503BFE202041FC7820A3FE2124F8A823FE200021FC2904310421FC0104 +4986:23DE22523BDE225243DE78A0A1FE2320FDFC212021FE200029FC30882070078E +4987:00103E50205020483C8820A43D2422422040FE8010F820084408FE0802500020 +4988:00403E40204020403DFE20403C40204020FCFE90109021104510FE1002FE0000 +4989:00003EFE20AA20AA3CAA20AA3CAA20AA20AAFEAE10C220824482FEFE02820000 +498A:00203E202020203C3C2020203DFE20002020FE2010A820A44522FE2202A00040 +498B:00883C8820883BD0209E3BE4209427D4F91421D421544948F9484A5402D40422 +498C:00007C7C44447C7C44447C7C410441044FE44104410441045FF4400440144008 +498D:7C7C44447C7C44447C7C4004440447F4480457C4418442044414441443F4400C +498E:7C7C44447C7C44447C7C40044FC440045FE4450445044504492450E440144008 +498F:00007C7C44447C7C44447C7C410442844464581C444444444444484450544008 +4990:00007C7C44447C7C44447C7C400440E45F0441045FE441047FFC410445144208 +4991:7C7C44447C7C44447C7C420442044FC4424442445FF442044504448448545008 +4992:7C7C44447C7C44447C7C40045FE44104420447C44C445444444447C444544008 +4993:7C7C44447C7C44447C7C4104410441F4410441044FE4482448244FE440144008 +4994:7C7C44447C7C44447C7C400440044FE448244FE448244FE440045FF44004400C +4995:7C7C44447C7C44447C7C4004482444445FF4444444447FFC444448444844504C +4996:7C7C44447C7C44447C7C410441045FF441044FE440044FE448244FE44824400C +4997:7C7C44447C7C44447C7C410442044FE44AA44AA44AA44AA45FF4400440144008 +4998:7C7C44447C7C44447C7C40044FE448244FE448244FE4491448A44A444C24481C +4999:7C7C44447C7C44447C7C410441045FF441047FFC40445FF44844444441544088 +499A:7C7C44447C7C44447C7C400440E44F0441045FF441044FE448244FE440144008 +499B:7C7C44447C7C44447C7C420447C448845FE441245FF441244FE441044304400C +499C:7C7C44447C7C44447C7C40045FF442044FE444247FFC40044FE448244FF44008 +499D:7C7C44447C7C44447D7C41044FE441045FF442844AA44A945494448449944008 +499E:7C7C44447C7C44447C7C400449F44444504449F44444484458444BFC4804400C +499F:7C7C44447C7C44447C7C410449244924555441044FE4410441045FF44004400C +49A0:7C7C44447C7C44447C7C40045FF44204451459A44AC445A45A9444945A84410C +49A1:7C7C44447C7C44447C7C41045FF4501447C4444447C4440447E4442447E4400C +49A2:7C7C44447C7C44447C7C5084488463E45084488457F47104522457F45014400C +49A3:7C7C44447C7C44447E7C41045FF4482444447FFC40044FE4482448244FE4400C +49A4:7C7C44447C7C44447C7C40044EE44AA444444AA451044EE44AA444444AA4510C +49A5:7C7C44447C7C44447C7C4004444444445EF444444EE45554644C444444544008 +49A6:7C7C44447C7C44447C7C410442844C6477DC41045FF4492445447FFC4004400C +49A7:7C7C44447C7C44447C7C400442044CE448244EE448244FE4428444945874400C +49A8:7C7C44447C7C44447C7C41045FF441044FE449244FE449244FE445444924410C +49A9:7C7C44447C7C44447FFC48244FE448244FE448244FE444044FC4544443945C68 +49AA:7C7C44447C7C44447FFC48244FE448244FE444044FF459146A944FD44054402C +49AB:7C7C44447C7C44447C7C400444445FF4444441044FE449245FF442844444482C +49AC:7C7C44447C7C44447C7C44045EF444544E5444545EB445045FF442844444482C +49AD:7C7C44447C7C44447C7C40E44F0441045FF44544492457D4444447C4445447C8 +49AE:7C7C44447C7C44447D7C4FE441044FE442045FF444444FE4545C67C4444447CC +49AF:7C7C44447C7C44447C7C40047F444844527C5F9444545F54442447547C94510C +49B0:783C48247A3C4BA47CBC4FC4554447C445444FE449244FE449244FE4411440F4 +49B1:7C7C44447C7C44447C7C41E45E2445444F8448844FC448444FE448245524656C +49B2:7C7C44447C7C44447C7C420447C448445FF46A244C944FF448044BE44A2453EC +49B3:7C7C44447C7C44447C7C520457746D54775455646F547C545654556466C4444C +49B4:7C7C44447C7C44447FFC4AA44FE441044FE441045FF444444FE441045FF4410C +49B5:7C7C44447C7C44447C7C40045FF449245FF4711C5BB455545BB455545BB4511C +49B6:200013FC1004420447C4484450844FE441245FF441244FE44104450442144008 +49B7:200013FC10044004410449244924555441044FE4410441045FF4400440144008 +49B8:200017FC00044FE449244FE449244FE441045FF45114515457D450545034400C +49B9:00207C2044204820482050204BFE482044204420442068205020402040204020 +49BA:00007C0045FE4820482050204820482044204420442068205020402040A04040 +49BB:00007DFC440448084810502048204BFE44204420442068205020402040A04040 +49BC:00407C4044404BF8484850484848484847FE444044A068A05110411042084406 +49BD:00007DF844084850482050104BFE482244244420442068205020402040A04040 +49BE:1040104020807C88450447FE7C02409040907C90449044907D124512020E0400 +49BF:00207C204420482049FC512449244924452445FC452468205020402040204020 +49C0:00407C40444048404BFE5040488048904490452045206A485244448441FE4082 +49C1:00807C80450049FC4A04540449E449244524452445E469245004400440284010 +49C2:00007DFC444448444844504448944888450044FC448468845084408440FC4084 +49C3:00007C0045FC4924492451244924492445FC4524452469245124412441FC4104 +49C4:00807C8044F849084B1054A0484048A04518460645F869085108410841F84108 +49C5:004078404BFC484053F8504863F852404BFC4844485468A850A0411042084406 +49C6:00907C90449048904BFC509048904890449047FE440068905088410841044204 +49C7:0040782048204BFE5040504060A050A249A44A984C906888508440A240C04080 +49C8:00007BFE48505050505061FC5154495449544954695C51844104410441FC4104 +49C9:00007DFC4524492449FC5124492449FC4420442045FC68205020402043FE4000 +49CA:00207D20452049FC4920522048204BFE4400440045FC69045104410441FC4104 +49CB:00007DFC4504490449FC5104490449FC4504450445FC6850509040924112420E +49CC:0008783C4BC0504452246128510048404BFE4888690853904060405041884604 +49CD:00887C8445024A224820505048884904460245FC450469045104410441FC4104 +49CE:00007CFC4484488448FC500049FE4902450245FE4502690251FE4102410A4104 +49CF:00407C4044FC48884950502048D84B2644F8442044F8682053FE402040204020 +49D0:00407C2047FE480049FC510449FC480045FC440844106BFE5020402040A04040 +49D1:004078204BFE52025404600053FE482048204920693C512042A04260443E4800 +49D2:00207C2044204BFE482051244924492446AA447044A868A85124422244204020 +49D3:00007DFC452449244974512449FC490445744554455469745104420442144408 +49D4:00207C20445048884944522249F848084450442044A46A82528A428A44784000 +49D5:00147812481057FE5010601053D24A524A524A546BD4500840EA471A42264042 +49D6:00487C44445E49E048285012486A49964448445E45E0682450284012406A4186 +49D7:01007D0045FE4A004DFC510449FC490445FC448044FC69085290406041984606 +49D8:010079F84A0853F0501067FE508049444E6848B06928566840A4412246A04040 +49D9:00407A484A48524853F8604050A049104A884C86689052A84294449442804100 +49DA:00207C1045FE480048FC508448FC480045FE4502457A694A517A4102410A4104 +49DB:004078204BFC5108509063FE52024C4448204BFC688050F84088410841284210 +49DC:00207C1045FE4910497C511449FE4914457C4510457C694451444244427C4444 +49DD:00207D24452449FC482053FE4800482045FC4524452469FC5020402443FE4102 +49DE:00007DFE452049FC492051FC4920492045FE440246AA6AAA52AA420240144008 +49DF:001E7DE04422491248945080482049CE4502450245CE69025102410241FE4102 +49E0:00207BFE482051FC512461FC512449FC48224BFE680853FE4108408840284010 +49E1:00107DFE4510497C491451FE4914497C4510457C4554697C5154427C4254444C +49E2:00007BFE4A00527C52446244527C4A004AEE4AAA6AAA52AA42EE420043FE4000 +49E3:00007DFC445049FC4954515449FC480045FC440047FE682050A8412442A24040 +49E4:00507A524954505053FE608850504BFE482049FC682053FE4050408841044602 +49E5:002078204BFE502051FC612451FC492449FC48226BFE5042402442A2428A4478 +49E6:000E7BF048445224510863F852084BFC4A044BFE6A0252AA42AA450244144808 +49E7:010478884BFE482051FC502063FE5054499248904BFE689050D4438A409641A2 +49E8:00507A524954485053FE5088605053FE482049FC48206BFE50A8412446224020 +49E9:00087B884888511057DE629452A44B944A944B946A9452C84388469440A440C2 +49EA:002078104BFE4A1052FE5254625452BA4A284A444A826A2052FE4444443848C6 +49EB:00207BFE480051FC510461FC50004BFE4A0249FC684053A440D8433440D24330 +49EC:004078204BFE520251FC6148525049FC4B0449FC690451FC410441FC40884104 +49ED:004078804BFE5222528A625253264A524AAA4BFE6840502442A2428A44884078 +49EE:00207BFE4A2251FC502060F8502049FC482049FC695451FC404042A4428A447A +49EF:01F07A104FFC520453FC622453B84A2249FE4A106FFC524443FC40D0414A463E +49F0:0406E438AF08A910B224AFBCCA88AA94AFBEAA8AAA88AFACC02A954A95488018 +49F1:20502048208020FEFD90269024FC2490249024FC25902690449040FE80800080 +49F2:00507C48108010FE1190129010FCFE90109010FC10901090109010FE10801080 +49F3:08500848088008FE49904E9048FC4890489048FC48904E905890E0FE00800080 +49F4:105010481080FEFE11901290FCFC0490049048FC28901090289044FE82800080 +49F5:105010481080FEFE9390129010FC2890289028FC28904A904C9088FE00800080 +49F6:090008801FFC30805FF890801FF810801FFC12000100FFFE0000082010102008 +49F7:205020483C8044FEA990129028FC4490829030FC08900090609010FE08800080 +49F8:10501048108010FEFD90129010FC10907C9044FC4490449044907CFE44800080 +49F9:010000803FFE2250224824FE24902D9036FE2490249024FE4490449084FE0480 +49FA:082808240840FF7E10C81148207E3E486248A27E2248224822483E7E22400040 +49FB:08500848148022FE4190BE9000FC00903E9022FC2290229022903EFE22800080 +49FC:1050504850807CFE5190929010FCFE90009000FC7C904490449044FE7C804480 +49FD:0628782408404A7E2AC82D48087EFF4818481C7E2A482A484848887E08400840 +49FE:10501048284044FE82907D9012FC1090FE9010FC10907C90449044FE7C804480 +49FF:242824247E40247E24C8FF48007E7E484248427E7E48424842487E7E42400040 +4A00:20501048288044FE9190129054FC38901090FEFC10903890549094FE10801080 +4A01:7E20243E1848FFA829104A28984609001FFC30805FF890801FF810801FFC1000 +4A02:0620382008A47EA819202C504A8809041FFC30805FF890801FF810801FFC1000 +4A03:00287E2442407E7E42C87F48087EFF488148107EFF4822486448187E2440C240 +4A04:082814242240497EBEC80548087EFFC814487F7E5548634841487F7E41407F40 +4A05:10281024FE40107EAAC84548827E7D4844487C7E44487C481048547E92403040 +4A06:49202A3E7F4849485DA86B10492841460A001FF831005FF091001FF011001FF8 +4A07:285024487EFEC9907EFC48907EFC48907EFE40807DFC0488285010202858C586 +4A08:20501048FE8082FE7D90569098FC7C90C4907CFC44907C9044907CFE28804480 +4A09:002877245540777E55C87748557E77482248557E1048FF482248647E1C40E340 +4A0A:08801FFC3080DFF810801FFC14283F7E64C8BF7E24483F7E10041E7C12442244 +4A0B:00003FF801007FFE41029D7401001D70000000F03F00020003F87E02020201FE +4A0C:00003FF801007FFE41029D7401001D7000001FF000007FFC044008441044603C +4A0D:3FF801007FFE41029D7401001D70000008203FF808200820FFFE102020204020 +4A0E:3FF801007FFE41029D7401001D7000007F1001107F1040207F2401420AFE0442 +4A0F:3FF801007FFE41029D7401001D704080208009FC12042448E04020A023182C06 +4A10:3FF801007FFE41029D7401001D70010006C01830E7CE00001FF010101FF01010 +4A11:3FF801007FFE492284140100FFFE01007FF801083FF821003FFC0284044C1830 +4A12:3FF801007FFE41029D7401001D7000007EFC224412240A14122422444A940408 +4A13:3FF801007FFE41029D7401001D7000003FF8200827C8244827C820083FF82008 +4A14:00003FF801007FFE41029D7401001D70000011100920FFFE044008423042C03E +4A15:3FF801007FFE41029D7401001D70000011FC482020200BFE7020102010A00040 +4A16:3FF801007FFE41029D7404007FFC08001FF028104FF088100FF0081008500820 +4A17:3FF801007FFE41029D74000000FC7F00121009203FF00040FFFE010005000200 +4A18:3FF801007FFE41029D7400001FF010101FF010101FF010101FF004421842E03E +4A19:3FF801007FFE41029D7401001D700000203813C08040484017FEE040204023FC +4A1A:3FF801007FFE41029D7401001D7008001FF86488090836280110489487F20000 +4A1B:3FF801007FFE41029D7401001D700000100CFDF0110039FE5510921012101410 +4A1C:3FF801007FFE41029D7401001D7000003E7C22443E7C22443E7C22444A948508 +4A1D:3FF801007FFE41029D74000001003FF80100FFFE10101FF010101FF010101030 +4A1E:3FF801007FFE41029D74000001F87F0001001FF011107FFC412441F45E144008 +4A1F:3FF801007FFE41029D7401001D702000104083F8404017FC2040E3F820402FFE +4A20:3FF801007FFE492284141FF010101FF010101FF008001FFC2104528414541FE8 +4A21:3FF801007FFE41029D7401001D7000001FE0004051944924551442047FFC0004 +4A22:3FF801007FFE41029D7408207FFC08200FE008200FE00820FFFE124014201FF8 +4A23:3FF801007FFE41029D7408207FFC08200FE001003FF821083FF80100FFFE0100 +4A24:3FF801007FFE41029D7401001D702040104007FCF44417FC144417FC280047FE +4A25:3FF801007FFE41029D7409001FF831005FF091001FFC10003FF0082007C0F83E +4A26:3FF801007FFE41029D7402003FF808207FFC41043FF8040007F0081010502020 +4A27:3FF801007FFE41029D7401001D7020201050FE880526441028FC2E08F0704008 +4A28:3FF801007FFE41029D740080210013F80208F3F8120013FC120413FC280047FE +4A29:3FF801007FFE41029D7401001D7020201020FDFC092411FC392455FC90201020 +4A2A:3FF801007FFE41029D74000011FC112411FCFD2411FC10201DFCE02043FE0000 +4A2B:3FF801007FFE41029D74000001007FFC11102BA845641918E3E60E4001800E40 +4A2C:3FF801007FFE41029D7401001D702000111081104FBC1110E3B8255429122110 +4A2D:00107F100854FFB888906B7C08446B44007C7E440044FF7C104422447F540148 +4A2E:3FF801007FFE49229414FEFE10107C7C1010FEFE10103FF800081FF800083FF8 +4A2F:3FF801007FFE41029D7400207BFE482051FC612451FC492449FC687050A84124 +4A30:3FF801007FFE49228414211017FC911041F048400BF81248E3F820402FFE2040 +4A31:3FF801007FFE41029D74120027FC42088BF8120833F8510093F8151010E0171E +4A32:00207F20083CFFC488886B7E08526B52007EFF90082C7F2A5528554A554A4386 +4A33:3FF801007FFE41029D7400003EF822883EF822883EF822883EF814502692450E +4A34:3FF801007FFE41029D740000550836087F7E14087F4808283E2808080F287810 +4A35:3FF801007FFE4922A7FC10A017FC84A447FC520813F82208E3F8204027FC2040 +4A36:3FF801007FFE41029D7408201FF000104FE44AA449647FFC0440FC7C24444444 +4A37:3FF801007FFE41029D74000011087BCE11083B88557EBF9220943F88209421A2 +4A38:3FF801007FFE41029D7400187BE0495053F8604053F8480849F86840529444F4 +4A39:3FF801007FFE41029D74108011FC228828706B8EA9FC29AC297429FC28202154 +4A3A:3FF801007FFE49229FF404400FE000007C7C1010FEFE92925454FEFE28287C7C +4A3B:7C7C1010FEFE92927C7C54547C7C00007C7C1010FEFE92927C7C54547C7C0000 +4A3C:104411FEFE5410487CFE1190FEFE00907CFE44907CFE44807DFE4444543849C6 +4A3D:04407C7C04403C7804407C7C044004403FF0001000103FF02000200420041FFC +4A3E:010000803FFE2000212021202F3C212021202738212021204F3C412081200120 +4A3F:00003FF801000200FFFE08203018C44604407C7C04403C7804407C7C04400440 +4A40:04407C7C04403C7804407C7C04401FF010101FF010101FF010101FF008201010 +4A41:04407C7C04403C7804407C7C04403FF002007FF802020DFE70401C78F1C41C3C +4A42:0020FE2010202050FE50AA88AB44BA22AA20AAF8BA08AA08AA10FE1082200020 +4A43:0010FE9010902092FE92AA94AAF4BA98AA90AA90BA90AA92AAB2FED2828E0000 +4A44:0000FE7C10442044FE54AA54AA54BA54AA54AA54BA10AA28AA28FE4A828A0106 +4A45:0010FE10101020FEFE92AA94AA90BAFCAAA4AAA4BAA8AAA8AA90FEA883440282 +4A46:0040FE401040207EFEA0AAA0AB20BA3EAA20AA20BA20AA3EAA20FE2082200020 +4A47:0010FE1010102010FE1EAA10AA10BA10AAFEAA82BA82AA82AA82FE8282FE0082 +4A48:0040FE40107E2080FF7CAA44AA64BA54ABFEAA44BAA4AA94AAFEFE0482280010 +4A49:0014FE1210FE2010FE10AAFEAA92BA92AAFEAA92BA92AAFEAA92FE9282920086 +4A4A:0020FE1010FE2082FE40AA4EAA6ABAAAAAAAAAAABB6CAA28AA4AFE4A828A0106 +4A4B:0010FE0810FE20A4FEA4AAA4AAFEBAA4AAA4AAF6BAACAAB4AAA4FEA483240024 +4A4C:0028FE241040207EFEC8AB48AA7EBA48AA48AA7EBA48AA48AA7EFE4082AA012A +4A4D:0010FE1010FE2010FEAAAA44AA82BB7CAA44AA7CBA44AA7CAA10FE5482920030 +4A4E:0010FE1010282044FE82AA7CAA00BAEEAAAAAAAABAEEAA44AA44FEAA82AA0112 +4A4F:0024FEFE10242000FEFEAAAAAAAABAFEAA14AAFEBA90AAD2AAACFEAA82960122 +4A50:22202220FF20227E3E4008807F3C490449087F100820FFC008420842083E0800 +4A51:2200227EFF0222023E02083E7F20492049407F7E0802FF820802080208140808 +4A52:2200227EFF1022103E1008107F1049FE49107F100810FF900810081008500820 +4A53:28802880FC8028FE390212427C42548254A27D1213FAFD0A1002100210141008 +4A54:280028F8FE882888388811067E0055FC54847C841048FE501020105010881306 +4A55:28002840FD9E2912391211127D12551255127D12115AFD941110101010101010 +4A56:28202820FE2028A838A410A27D22552056247C241028FE081010102010C01300 +4A57:280028FCFE842884388410FC7C84548454847CFC1084FE841104110412141408 +4A58:22002200FF7E22083E1008107F24494449787F080810FF940822087E08220800 +4A59:28202810FE1029FE382010207C44548455F87C101020FE44108211FE10821000 +4A5A:2804281EFDF02910391011107D1055FE55107D101110FD08110A114A11A61112 +4A5B:28402820FC282808380810487C54555255527D601260FC4410C41144123C1000 +4A5C:28202820FE20282039FC11247D24552455247DFC1124FF241124112411FC1104 +4A5D:2808281CFDF02950395011507D50555055507D481148FD681154127412521400 +4A5E:28202820FE202820383E10207C20542055FC7D041104FF041104110411FC1104 +4A5F:28202820FDFE282039FC10247DFC552055FE7C22102AFC541050108811041202 +4A60:50005006FBB8508870882108F93EAB88A888FA882288F93E21002280247E2800 +4A61:28202820FC202BFE382010207D24552455247EAA1020FC501050108811041202 +4A62:5104510EF930512077E02120F93EA964A9A4FF242124F9242124212425442284 +4A63:28202820FC502888390412FA7C20542057FE7C201128FD241222142210A01040 +4A64:280028FCFE84288438FC10847C8454FC54847C8410FCFE50105010921112120E +4A65:5004500EFBB8508870882128F92EABA8A8A8FAA822A8F93E21002280247E2800 +4A66:108020FC6910AA9028602890230C04407FFC044007C001001FF01110FFFE0100 +4A67:28402820FDFE2800380010FC7C00540054FC7C001000FCFC1084108410FC1084 +4A68:280028FCFE8028F8388010F87C8057FE55407D241128FF101108114411821100 +4A69:50405020FBFE520275042100F9DEAA52AA52FB52249AF894211021122212240E +4A6A:28202810FDFE29023A0410F87C88548854F87C801080FCFC1084108410FC1084 +4A6B:500053FEF820502073FE2222FA22AB32AAAAFAAA2376FA6622222222222A2204 +4A6C:28202820FDFE282038FC10407DFE548855247E2210F8FC2011FE102010201020 +4A6D:28202820FDFC2850388811047FFE540855E87D281128FDE81128100810281010 +4A6E:280029F8FC08280839F810087C0857FE54207E221174FCA81124122210A01040 +4A6F:500053FCF8085010702023AEFAA2AAAAAAA4FAA423AAF83220A0204027FE2000 +4A70:280028F8FE88288838F810007DFE548854F87C8810F8FE88109E13E810081008 +4A71:504050A0F910520875F62000FBC4AA54AA54FBD42254FA5423D42244225422C8 +4A72:28402820FDFE2948394811FE7D48557855007DFC1144FD4811281210122814C6 +4A73:28402820FDFE292238A411287C50548855047CF81088FC881050102010D81306 +4A74:2880289EFC9229D23892109E7C9255D255527D5E1152FD5211D21022102A1044 +4A75:28002BFEFE2228203BFE10207DFC552455FC7D2411FCFC2013FE102010201020 +4A76:28202924FD2429FC382011FE7C00542055FC7D241124FDFC1020102413FE1102 +4A77:28202810FDFE2884384811FE7D02562454107DFE1040FC7C1044108410941108 +4A78:28882888FDFE2888380011FE7C88548854F87C8810F8FC88109E11E810081008 +4A79:280028FEFE00287C3844107C7C0054FE54827CAA1092FEFE1092109210921086 +4A7A:50905088F9045242748821FCF804A800ABDEF8422252F94A22522042214A2084 +4A7B:280029FEFD2029FC392011FC7D20552055FE7C0212AAFEAA12AA120210141008 +4A7C:28202A20FD7C28A4381810E67F10557E55107D7C1110FDFE1110111012FE1400 +4A7D:500053FEFA00527C72442244FA7CAA00AAEEFAAA22AAFAAA22EE220023FE2000 +4A7E:50405020FBFE520072482248FBFEAA48AA48FA482278FA002554252A2A2A3000 +4A7F:282029FCFC2028883BFE10887DFC550455FC7D0411FCFD0411FC108811041202 +4A80:282029FEFF0228F8388810F87C8054FC54847CFC1000FE2010541142114A1238 +4A81:28502952FCD4285039FE10887C5055FE54207CFC1020FDFE1050108811041202 +4A82:52085208FFBE520872082FBEFAAAAAAAAAAAFBAE2208FF1C2AAA324822082208 +4A83:51085088FBC8501073DE2264FBD4A814ABD4F8542094F8E82388209422942122 +4A84:28882888FDFC2888388813FE7C2055FC55247DFC1124FDFC1000108811041202 +4A85:280029FCFD54295439FC10807DFE564255F27D521152FDF2104A13FA100A1004 +4A86:285029FCFD5429FC395411FC7C0055FC54007DFC1104FDFC1088105013FE1000 +4A87:28882BFEFC8828243BFE10207DFC552455FC7D2411FCFD24100811FE10881058 +4A88:2810287CFE54297C391010FE7C00577C55447D7C1140FD7C1144117C1280147E +4A89:51245248F924500073FC2294FA64AA94ABFCFA482368FA48236A224A22462362 +4A8A:51105090FBDE5010725E2182FBDEA810ABDEFA5023DEFA5023DE2250225222CE +4A8B:2810287CFE54297C391010FE7C44577C55447D7C1144FD7C112811441280147E +4A8C:51F05210FBFC560473FC2224FBB8AA22A9FEFA1027FCFA4423FC20D0214A263E +4A8D:53DE5252FBDE525273DE2222FAFAAA22AAFAFAAA22FAFAAA22FA227222AA2226 +4A8E:522253FEF89051FE731025FEF910A9FEA910F9FE2100FBFE228A237622522276 +4A8F:101010107E1022FEFF9200927E9242AA7EAA08CA7E82088248827E82088A0884 +4A90:104010207C282408FE0800487C5445527D5211607E60104450C47D44123C1000 +4A91:102010107E1022FEFF8200847E4042447E4808507E60084248427E42083E0800 +4A92:102010107E0022FEFF1000107E1042107E7C08107E10081048107E1008FE0800 +4A93:102010207E202220FF3C00207E2042207EFC08847E84088448847E8408FC0884 +4A94:102810247DFE2420FE2001FC7D2445247DFC11247D2411FC51247D241124110C +4A95:108010807CFE2502FE2200AA7C7244227DFE10227C7210AA51227C22100A1004 +4A96:104010407E7E2280FF7C00447E7C42447E7C08207E3C084448A87E10082808C6 +4A97:100011DC7D442544FF4401DC7D0045007DDC11147D1411D451087D0811141122 +4A98:100010FC7C842484FEFC00847C8444FC7C0011FE7C101090509C7C901150123E +4A99:101410127DFE2410FEFE00927CFE44927CFE10927C0411FE50447C241024100C +4A9A:100011FC7D0425FCFF0401FC7C0047DE7C4212527D4A10C6535A7C42114A1084 +4A9B:101E10F07C922454FEFE00547C9245007CFE10927C9210FE50927C9210FE1082 +4A9C:104010787C8825FEFEA400D27CFE44807CBC10807CBC108050BC7D24113C1224 +4A9D:104411FE7C542448FEFE01907CFE44907CFE10907CFE108051FE7C44103811C6 +4A9E:00003FF80100FFFE028004401830E44E04407C7C04403C7804407C7C0440FFFE +4A9F:100011F8FE88105010207C50558C545055DC545055DC5C5011DC105013FE1000 +4AA0:1640F87C9084FE2832205250968C100004407C7C04403C7804407C7C0440FFFE +4AA1:11201CBE704250947D9034A85C46900004407C7C04403C7804407C7C0440FFFE +4AA2:12201D3E70425094531051287D46145035DC345055DC985011DC105013FE1000 +4AA3:1220113E1042FC94131011287C46545055DC54505DDC305051DC905013FE1000 +4AA4:281E29F02892EE5429FE2854EE92290028FE2892EE9228FE28922E92F0FE4082 +4AA5:10001EFC1044FF2881107E2800C67E2842EE7E2842EE7E2842EE7E2824FE4200 +4AA6:200010007CF8002044202820FE2000207C20442044207C20442044207DFC4400 +4AA7:202010207C2000A044AC28B4FEE401A47CA444B444A87CA244A244827C7E4400 +4AA8:204010407C4000FC44842904FE0400847C44444444447C04440444047C284410 +4AA9:202010207C20005044502888FF4402227C2044F844087C08441044107C204420 +4AAA:10007E7C124422444A7C844401003FF80820FFFE00001FF010101FF010101FF0 +4AAB:200010FE7C00005244A42928FE94004A7C0044FE44107C10441044107DFE4400 +4AAC:202010207DFE0020442029FEFF0202047CF8441044207DFE442044207CA04440 +4AAD:202010107CFE000044442828FEFE00007C7C444444447C7C444444447C7C4444 +4AAE:204010407CFE012244AA28FAFE4200947D4844FE45227EAA44FA44427C944508 +4AAF:08202AA44D28145022887FFE41029FF404407FFC00001FF010101FF010101FF0 +4AB0:2040102079FC0088485033FEFC0001FC790449FC490479FC48204A947A8A4C7A +4AB1:000001FEFC20044005FC050405047DFC410441FC4104450459FC608841040202 +4AB2:000000FEFE10282028FC2884288428FC288428FC28842A844CFC484880840102 +4AB3:000000FE7E10122012FCFF84128412FC7E8412FC1084108420FC204840848102 +4AB4:080008FE08107F20497C08440844147C1444147C14442544267C440080280044 +4AB5:00007EFE0410242024FC248444847FFC0C8414FC1484248444FC844814840902 +4AB6:00007CFE4410442044FC7C84448444FC7C8444FC448444844EFCF04800840102 +4AB7:200020FE40107E2082FC02847A844AFC4A844AFC7A844A8402FC024814840902 +4AB8:00007EFE421042207EFC4884488448FC7E8448FC488448844AFC4A4866844302 +4AB9:00007EFE0810082010FC1484328451FC908410FC108400840EFCF04840840102 +4ABA:100010FE10107E2010FC10841084FEFC108410FC2084288444FCFE4842840102 +4ABB:100010FE20104420FEFC0284248424FC2484FEFC2484248424FC444844848502 +4ABC:100010FE9210922092FC9284FE8410FC108492FC928492849EFCF24800840102 +4ABD:00007CFE4410442044FC7C840084FEFC208440FC7C84048404FC044828841102 +4ABE:0010FF10082810287E44428242087E1042647E08421242647E08243042C08100 +4ABF:080008FE10107F20417C41446544557C4944497C55446544417C7F0041280044 +4AC0:00007EFE421042207EFC428442847EFC408448FC44844A8452FC604840840102 +4AC1:100011FE20207C4045FC45047D0445FC45047DFC4504450445FC7C8845040202 +4AC2:100010FE3E104220A47C18441044247CC8441F7C2144D2440C7C08003028C044 +4AC3:00007F7E401040205E7C404440447F7C5044517C5A445444527C910098281044 +4AC4:440024FE281000207CFC4484448444FC7C8428FC288428842AFC4C4888840102 +4AC5:100008FE7F104120497C084408447F7C0844187C1C442A44497C880008280844 +4AC6:0400053E048804107FBE44224422753E5522553E5522522252BEA680899410A2 +4AC7:0C0030FEC6101820637C0C44F044007C7E44427CFF444244FF7C42004A284444 +4AC8:0800497E491049207F7C08441444227C514488FC08447E44027C040004280844 +4AC9:0C0030FEC210142048FC3084C88414FC2484CCFC14842484C4FC044828841102 +4ACA:0000FEFE08101020347C52449144107C00447E7C42444244427C42007E284244 +4ACB:0C0070FE1010FE2038FC5484928400FC1084FCFC2484448428FC10482884C502 +4ACC:080010FE7F104920497C7F444944497C7F44147C2444FF44047C040004280444 +4ACD:140014FE1410F720147C14441444777C1444147C1444F744147C140014281444 +4ACE:0000F77E11105520227C55448944107C0044F77C11445544227C550089281044 +4ACF:2200227EFF902220227C3E442244227C3E44227C2244FF44007C140022284144 +4AD0:2200227E22102220F7FC22442244667C7744AAFCAA443244227C220022282244 +4AD1:100010FEFE10102028FC4484FE8404FC748454FC5484748454FC044814840902 +4AD2:000006FE781048207F7C48444544537C6144007C7E4442447E7C42007E284244 +4AD3:200010FE7C10002044FC24842884FEFC008400FC7C84448444FC44487C844502 +4AD4:20002F7EF5102520757C2544F544297C2344087C0844FFC4147C2200412880C4 +4AD5:200010FEFE10002044FC2884FE8482FC10847CFC5484548454FC5C4810841102 +4AD6:220022FEFF1022203E7C22443E44227C2244FF7C40445444627C40007E280044 +4AD7:0000777E51105120517C77444044407C7744417C49447544427C420045284944 +4AD8:00007CFE44107C2044FC7C8420847EFC928452FC6A8442847AFC024814840902 +4AD9:080008FE7F1008202A7C2244FFC4227C2A44087C7F441C442A7C490089280844 +4ADA:00003EFE221022203A7C2A442A447F7C41445D7C554455445D7C410045284244 +4ADB:20002F3E210841105FBEC82248224FBE5222423E5FA24222453E448048945022 +4ADC:08002A3E2A08AA90CCBEDDA2FFA2AABEAAA2DDBEFFA299A288BE8F80F0940022 +4ADD:060078FE08100820FF7C1C442A44497CBE44227C22443E44227C22003E282244 +4ADE:440024FE28100020FEFC108410847CFC108410FCFE840084AAFCAA48AA840102 +4ADF:00007CFE441044207CFC0084FE8482FCFE8482FCFE848284FEFC284844848502 +4AE0:180060FE0C1070200CFC70840084FEFC108434FC528490847CFC44487C844502 +4AE1:2200147EFF901420147C7F441544FFFC15447F7C14443644557C948014281444 +4AE2:03007C7E471044205F7C554456445C7C5544537C50445744557C5500A9A80044 +4AE3:0E00F0FE2210922044FC20844484F8FC108424FCFE841084FEFC284844848302 +4AE4:0000FF7E811000207E7C42447E44427C7E44107C0844FF44007C240042288144 +4AE5:080010FE7F104920497C7F44497C49447F7C10441A7C2CA82FC44882480287FE +4AE6:0800083E7F080810083EFFA22022413EFFA240BE00227F22553E55005794FC22 +4AE7:100020FE7C1044207CFC44847C8410FCFE8428FC548492847CFC104810841102 +4AE8:1200123E12087A1013FE7CA210A2FCBE22A23ABE29222922293E4A805A9484A2 +4AE9:1000223E7F08421094BEF7A20822363EC92230BEC4221922623E0C003014C022 +4AEA:100010FEFE101020BAFC5484BA8410FCBA8454FCBA84108428FC244842848102 +4AEB:08007F7E4910FFA0497C7F4408447F7C49447F7C1044FF44217C72000C28F344 +4AEC:0000F7BE2108A510F7BE6322B5A2213E7FA240BE40A27FA240BE40807F9440A2 +4AED:10007CFE54107C2010FCFE8400847CFC44847CFC44847C8444FC7C4828844502 +4AEE:00007F7E01103F20017C7F440044777C2544F77C0244FFC4427C22002A280444 +4AEF:4100211E0FE4F108429E44527FF2505E5752555E55525752555E5040A14C0092 +4AF0:0020F92420A843FEF8A889248A22F9048904F9DE8A448D54F89E010452048C04 +4AF1:00007FBE08087F9054BE54A254A241BE00227FBE08227FA254BE5480549441A2 +4AF2:0280025E7FC442085E1E42925E92571E5D5242DE88520492545E51408F0C0012 +4AF3:00007F7E551055207F7C20447F44917C7D44557C55447D44117C7D0005280244 +4AF4:2200223EF7882210773EAAA22262003E7F22003EFFA20822493E4880A8941022 +4AF5:10007F3E49086510533E49227F22083EFFA2A2BE4922FFA2203E3F0041148322 +4AF6:20802A9EF5E42A8871DE6AB2A4922A9E2092041E04127FD20A1E1100208C4052 +4AF7:0000FFBE0808EB90AABEEBA20822FFBE0822EBBEAAA2EBA2083E0F80F8144022 +4AF8:00007FDE404A434A5C4A444A5F4A554A55525F52446A45445F404922801E0000 +4AF9:00007FC0407E43485C4844485F48554855485F484448457E5F404922801E0000 +4AFA:100011FC1104FD3411C4114421F42954295429F4514455545DF4851602060402 +4AFB:00007FDE405243525C52445E5F52555255525F52445E45405F404922801E0000 +4AFC:00107F1041104D7C711451147D1455FE7D10512855247D4444804042803E0000 +4AFD:00007FC6405843485C4E44585F4E5578554A5F4A444A45465F404922801E0000 +4AFE:00407C2044284C087448545455527D6256607C4454C4553C52007D004482807E +4AFF:001E7FCA404A434A5C5244665F40555E55525F52445E45525F404922801E0000 +4B00:00487C4844884CBE752A55CA544A7C8A54AA7DF25412542A52447D004482807E +4B01:00107F08417E4D42712051247D3855207D225122551E7D0044804042803E0000 +4B02:00287C2444204DFC7520552455247D2855287D105594552C52447D004482807E +4B03:00107F0841004D7C710051447D2455287D28511055FE7D0044804042803E0000 +4B04:00147C1244104DFE7510551455147DD455087D0A551A552652427D004482807E +4B05:00407C4045FC4C847484552856107D0857DE7D4A554A5652525A7DE44482807E +4B06:00447D8444944C9477F4549455947DD456B47C945484549452887D004482807E +4B07:440025FC290401347DC4454445F445547D5429F4294429542BF44D168A060402 +4B08:00007F4441284D00717C51447D44557C7D285128554A7D8644804042803E0000 +4B09:00207C2045FC4C20742057FE54507C5055547D525652549052907D304482807E +4B0A:00107F1041FE4D10715451547DBA55107D28512455427D8044804042803E0000 +4B0B:00207C2044F84C2075FC548855447C7854887D505420545052887D084482807E +4B0C:10001DFC11047D3455C4594471F455544D5441F45D44555457F4951622060402 +4B0D:00807C8044FC4D54765454A455547C8854207C145552554A52387D004482807E +4B0E:00147C1247FE4C10741055D455547D5455CC7C0A54CA571652227D404482807E +4B0F:00207F10417C4D44712851FE7D00557C7D445144557C7D4444804042803E0000 +4B10:00187CE044204DFC747054A855247C4057FE7C8855905470538C7D004482807E +4B11:007C7F54417C4D54717C51007D7C55447D7C5144557C7D4444CC4042803E0000 +4B12:00207DFC45044C507488552454507C8855067CF85408545052207D50448A807E +4B13:00207F1041FE4D44712851FE7D00557C7D44517C55447D7C44804042803E0000 +4B14:00207C5044884D0474F8540055C47D5455D47D5455D4554453547D484482807E +4B15:00007DFC45044D3475C455447DF4555455547DF4554455547DF4491682060402 +4B16:00107F20417C4D44717C51447D7C55007D7C5110557C7D1044FC4042803E0000 +4B17:00007CF844887C9844E87CA800A8FEF840A87EF8AAA82AAA4AAA92FA2A864502 +4B18:00207DFC44004CF8748854F854007DFC55047D7455545574530C7D004482807E +4B19:000E7F7041124D447120517C7D9055107DFE511055547D7C44804042803E0000 +4B1A:00007DFC45204DF8752055F855207DFC54047D545554540452287D104482807E +4B1B:01FC7D2445FC4D2475FC54A854A87FFE54A87CA855FC542053FE7D2044A2807E +4B1C:00407C2045FC4C507524555455FC7C2055FC7D4455545574530C7D004482807E +4B1D:00287F7C41284DFE7110517C7D54557C7D54517C55007D4444824042803E0000 +4B1E:00207DFE44204CFC740055FE54027CF854207DFE540455DE53547DCC4482807E +4B1F:00827D7A452A4DAA754A559A55427CA255F27C4A55F2555252E67DF84482807E +4B20:00003FF801007FFE41029D7401001D7000047FE808247212120EFFD0122A221E +4B21:02003FD00260FFFE1C10EFF008100FF000047FE808247212120EFFD0122A221E +4B22:0800080014FC122429247E24A2243E2422243E242024284424442A8433282210 +4B23:082008201420127E29407E80A23C3E0422083E102020284024422A42323E2000 +4B24:00003FFC200420043FFC208023602C9837F6241027F0241027F4446845188604 +4B25:04200210013EFFC00022011A02860D603FF8C8260FE008200FE808D00A300C08 +4B26:080008781448124829487E86A3003EFC22443E442028282824102A2832442182 +4B27:0800080014FC120029007E00A3FE3E5022503E502050285024522A92328E2100 +4B28:10801080288025FE5202FC8244827DE244A27CA2412A512A4A1A540264144008 +4B29:00007FFC010003600D18710402800D603FF8C8260FE008200FE808D00A300C08 +4B2A:0800080014FE121029107E20A2203E6822643EA22122282024202A2032202020 +4B2B:0804081E14F0129029907E90A2903EFE22903E9020902888248A2AAA32D6208A +4B2C:10201020282025FC5324FD2445247D2445247FFE402050504850548865044202 +4B2D:00007DFC444444447C94010802800D603FF8C8260FE008200FE808D00A300C08 +4B2E:10081048292825285328FD0845087D0845087D08414851944914542264424082 +4B2F:0810081014101210291E7E10A2103E1022FE3E822082288224822A8232FE2082 +4B30:080008FE1422122229227E22A24A3E4422803E7E2042284224422A42327E2042 +4B31:102010202820242053FEFC7044A87CA845247D24422250F84820542064204020 +4B32:08400840148012FC29047E04A2F43E9422943E9420F4289424042A0432282010 +4B33:10201020292424A452A8FC2045FC7C2044207C2043FE50204820542064204020 +4B34:10201020282025FE5220FC2044207DFC44707CA840A851244924562264204020 +4B35:10201010281025FE5220FC2444447CF844127C22404451884810542864444182 +4B36:080008FC1484128429FC7E84A2843EFC22A23EA42098289024882AA432C22080 +4B37:08200820147C128429487E30A2203E4823903E3E204229A424182A1032602180 +4B38:7F7C08041E282210542809443280CD603FF8C8260FE008200FE808D00A300C08 +4B39:100011FE282024205248FC8445FE7C2244207C2041FC50204820542067FE4000 +4B3A:110410842888240053FEFC2044207DFC44207C2043FE50204820542064204020 +4B3B:10281024283E25E05220FC3C45E07C20443E7DE0402250244818546A65864002 +4B3C:0800087C14441244297C7E00A2FE3E8222823EFE2082288224FE2A82328A2084 +4B3D:088408441448120029FC7E84A2843E8422FC3E482048284824482A8A328A2106 +4B3E:10881048285025FC5224FC2445FC7D2045207DFE40225022486A54A465204020 +4B3F:100011FC2904250453FCFD00451C7D70451C7D70411E51F0491055126512420E +4B40:100010782A2825285128F82848787B284928792A412A512649225A806C7E4000 +4B41:100CFEF010801CFEF088110832880D603FF8C8260FE008200FE808D00A300C08 +4B42:100010F82888248852F8FC0045FC7D2445247D2441FC510049005502650240FE +4B43:10201020285024885144FA2249F878084850782040A452824A8A5A8A6C784000 +4B44:102010202BFE242053FCFD2445FC7C2045FC7C2443FE502449FC542064A04040 +4B45:100011FC290425245324FDFC45247D2445747D54415451744904550465FC4104 +4B46:7F2048307E2842247E2049207E800D603FF8C8260FE008200FE808D00A300C08 +4B47:1080108028FC25045244FC4447FC7C4445F47C0441F4511449F4540464284010 +4B48:10101010287C271451FEF9144A7C7A104F7C791041FE55104A10530064FE4800 +4B49:1020102028FE244052FCFD1046FE7C0044FC7C8440FC508448FC548464944088 +4B4A:108810882BFE248852A8FC2045FC7D2445247D2443FE50204850548865044202 +4B4B:1100117C294426445244FE7C4A107A104AFE7A38425452544A945B126A104210 +4B4C:107CFF44107C7E44427C7F44028C0D603FF8C8260FE008200FE808D00A300C08 +4B4D:1020102029FC24205220FCF844207C2045FC7C0041FC51544954555467FE4000 +4B4E:10481148294827FE5148F9484978790049FE782043FE507048A859246E224020 +4B4F:1040102029FE25025102F9FE4900790049FE79AA41AA52FE4AAA5AAA6CA24086 +4B50:11041088280027FE5020F82049FC782048207BFE404050244AA25A8A6C884078 +4B51:10881050280025FE5250FDFC44547DFE44547DFC405050D84954565264504050 +4B52:1010102028FC248452FCFC8444FC7C8444FC7C20401050544942554A66384000 +4B53:102011242924252453FCFC0047FE7C0045FC7D04410451FC4888545067FE4000 +4B54:10101220297C25445044F87C4B407940497C79444144517C49445A806C7E4000 +4B55:100CFEF054807CFE5488FF0812880D603FF8C8260FE008200FE808D00A300C08 +4B56:1040102029FE25005148F94849FE794849487948417851004AD452AA652A4800 +4B57:1040102029FC24885050FBFE480079FC490479FC410451FC489058926912460E +4B58:100011FC290425FC5104F9FC48207BFE480079FC410451FC482059246A224060 +4B59:100013DE288826A853FEF9884ADA7CA649F87908410851F84908590869F84108 +4B5A:102011FC2888245053FEFC0045FC7D2445FC7D2441FC502049FC542067FE4000 +4B5B:100813882888251057DEFA944AA47B944A947B94429452C84B885E9468A440C2 +4B5C:1020102029FC24205354FC8845047EFA44887CF8408850F8482054A865244060 +4B5D:10201050288825745202FDFC45247DAC45247DFC400050F8488854F8648840F8 +4B5E:100011FC295425FC5220FDFC44207FFE44887C5041FC50204BFE542064204020 +4B5F:108813FE288824005148FBFE49487978490079FC402053FE487058A86B264020 +4B60:102013FE2A88265053FEFA504AFC7A544BFE7A5442FC52504AD8555466524850 +4B61:103C13C0294424A451F8F8204BFC780049F8780841F8500849F85AC46AAA447A +4B62:104010202BFE26225154F94A4A3A780049FC795443FE500049FC582068A04040 +4B63:104010202BFE24885052FFAC4AAA7AA84DAC7800410451FC490459FC69044204 +4B64:1010107C2A54257C5110F8FE48007B7C4944797C4140517C4944597C6A80447E +4B65:110810902BFC244051F8F8804BFC794849FC7B0A45F8510849FA5934698C4102 +4B66:108813FE2888241252FEF8104CFE7A924AFE789241FE52924E045AFE6A44422C +4B67:102013FE2A4827FE5248FAEC4B5A7A484A207A44427852144AFE5A106A5444B2 +4B68:122213FE289025FE5310FDFE491079FE491079FE410053FE4A8A5B766A524276 +4B69:102013FE2A4827FE5248FAEC4B5A7A484A507BDE425053DC4A5055DE64504850 +4B6A:200021FC21043DFC45044BFE800021FC212421FC212425FC282031FC202003FE +4B6B:4084444859FE6020424042FC3E8400847CFC448444847CFC448444847CFC4484 +4B6C:4092452459246092420042FE3E1000207CFC448444FC7C8444FC44847CFC4484 +4B6D:440028FEFE10102020FC7C84448444FC7C8444FC44847C8444FC44487C844502 +4B6E:3F042018FF62220C7F7010100820FFFE02003FF820083FF820083FF820083FF8 +4B6F:042078201124FF241124392455FC90207C20452445247D24452445247DFC4404 +4B70:0420782011FCFE4010F8384057FE90887D24462244F87C2045FC44207C204420 +4B71:0420792410A4FEA8102039FC552491247D7445AC45247D24452445047D144508 +4B72:0420782011FCFE501088390457FE90087DE8452845287DE8452844087C284410 +4B73:7C4011FCFD2439FC5524FDFC24681BA2651E7FF809203FF8C8260FE008200FE0 +4B74:00001FF811001FF011001FF011001FFC0004292444940108FFFE010001000100 +4B75:00007E7848487E4848487E48486848587E580248AA48AA4AAA4A828A14860900 +4B76:00007EFE48487E4848487E48484848487E480248AA48AA48AA88828815080A08 +4B77:00087F1C48707F1048107F1C487048107F90009EAAF0AA90AA9280920512020E +4B78:00107E8848847E8449027E02488848887E880250AA50AA20AA50828815040A02 +4B79:00007C40519E7D1251127D12511251127D120512555A55945510841014100810 +4B7A:00207E1048107EFE48007E00487848487E480248AA48AA4AAA4A828A14860900 +4B7B:00107E5048507E5048887E8849044AFA7E480248AA48AA48AA88828815280A10 +4B7C:00007F3C48007F0048007F7E482448247FA400A4AAA4AAA4AAA480A405440284 +4B7D:00087F2848287F28483E7F28484848087F8800FEAA88AA88AA88808805080208 +4B7E:00207E2848247E2448207E2048FC48207E200250AA50AA50AA88828815040A02 +4B7F:00107E1048507E50487C7E90491048107EFE0210AA28AA28AA28824414440882 +4B80:00407E4048FC7E8449047EF4489448947EF40284AA94AA88AA828282147E0800 +4B81:00207E2048407E4848847EFC480448487E4802FEAA48AA48AA48828814880908 +4B82:00287E2448247E2048FE7E204820483C7E340254AA54AA54AA88828815140822 +4B83:00107E1048107E7E48107E10481048FE7E100210AA20AA28AA4482FE14420800 +4B84:00107F0848087F7E48107F10482448247FB80088AA90AA90AAA480BE05020200 +4B85:00147E1248127E1048FE7E90489248927E920294AA94AAB4AACA828A14160822 +4B86:00007EFE48087E1048347E52489048107E000210AA10AAFEAA10821014100810 +4B87:00207E2048FC7E2449FE7E2448FC48207E2002FCAA20AA20ABFE822014200820 +4B88:00107F10481E7F2248547F08481048647F88009EAAA2AAC2AA94808805100260 +4B89:00407E40487E7E8049007E1C48E048A07EA202A4AAA8AA90AA9082A814C40882 +4B8A:00207C2051FE7C2051FC7C2451FC51207DFE0422542A54545450848815040A02 +4B8B:00027C0253E27C8A508A7CEA50AA512A7DAA056A564A544A54828482150A0A04 +4B8C:0090F890A090F910A1FEFB10A510A138F9380954A954A992A910891009103110 +4B8D:3FF821003FF021003FF021003FFC492486940108FFFE048808503A20CC180806 +4B8E:00C27C3450187C6451827C2051FE50507C9005FE56925492549A849414100810 +4B8F:00007EFE48107E10487C7E24482448FE7E000200AA7CAA44AA448244147C0844 +4B90:00007EFE48827E8248AA7EC6488248BA7EAA02AAAABAAAAAAA828282148A0884 +4B91:00047E1E48E07E12488A7E4C484048087EFE0208AA88AA48AA28820814280810 +4B92:00147E1248FE7E1048107EFE489248927EFE0292AA92AAFEAA92829214920886 +4B93:00207E20483E7E2048FC7E8448FC48847EFC02A4AA20ABFEAA20822014200820 +4B94:00047E1E48F07E1048FE7E54485448547EFE0254AA54AAFEAA10821014FE0800 +4B95:0000FBDEA042F94AA084F94AA252A420F8000BDEA852A952A89489480A543422 +4B96:007C7E4448447E7C48447E44487C48007EFE0282AA82AAFEAA82828214FE0882 +4B97:00107E9248927E9248FE7E0048FE48807EBE0288AA88AAFEAA88830815080A08 +4B98:00007E2048CE7E8248827EEE488248827EFE0228AA28AA28AA48824A148A0906 +4B99:00087E0C480A7E0849FE7E08480848EA7EAA02AAAAECAA0CAA2A82CA14160822 +4B9A:00107E10487E7E1048107EFE482448427E90023CAA44AAA4AA288210142808C6 +4B9B:0014FB94A294FAA4A2BEFAA4A364A2B4FAAC0AACAAA4AAA4AB248A240A24322C +4B9C:00147E5448547EFE48547E54485C48407E7E0210AAFEAA10AA38825414920810 +4B9D:00007EFE48927E1048FE7E10487C48547E7C0254AA7CAA10AAFE821014100810 +4B9E:00207E2049FE7E2048FC7E4049FE48887F0402FAAA88AA88AAF88288148808F8 +4B9F:00407C2051FE7D2250A47D28505050887D0404F8548854885450842014D80B06 +4BA0:00007EFE48007E7C48447E44487C48007EFE0292AA92AAFEAA92829214FE0882 +4BA1:00407E40487E7E80487C7E44487C48447E7C0220AA3CAA44AAA88210142808C6 +4BA2:00047E1E48F07E1048107EFE481048507E960292AA92AAD6AA92829214FE0882 +4BA3:00007EFC48447E3848447EEE48AA48447EAA0210AAFEAA38AA54829214100810 +4BA4:00207E2049FE7F5248487EFE489049907EFE0290AA90AAFEAA90829014FE0880 +4BA5:00007EFE48007E7C48447E7C480048FE7E8202AAAA92AAFEAA92829214920886 +4BA6:00207E1048FE7E00487C7E44487C48007EFE0282AABAAAAAAABA8282148A0884 +4BA7:101010281044FE8211FE7C9044FC7C9044FC7C9010FEFE0212AA12AA14141008 +4BA8:00207E1048FE7EA248107EFE484448287EFE0210AA10AA7CAA10821014100810 +4BA9:00007E7C48447E7448547EFE4882487C7E44027CAA44AA7CAA44824414540848 +4BAA:00847C8450DE7D4451547EDE504450847D24042055FE547054A8852416220820 +4BAB:0020F9FCA124FBFEA124F9FCA020A1FCF92409FCA840ABFEA88889D00870338C +4BAC:00487E4849FE7E4848007EFC488448FC7E8402FCAA20ABFEAA20825014880906 +4BAD:000E7EF048227E9248447EFE488248FE7E8202FEAA82AAFEAA288248148A0906 +4BAE:00207C2053FE7CA850A87D74522250707CA80546567854885550842014500980 +4BAF:0088F888A088FBD0A09EFBE4A094A7D4F91409D4A954A948A9488A540AD43422 +4BB0:00207E1048FE7E4448287EFE488248927EFE0292AABAAAAAAAAA82BA14820886 +4BB1:0000FA7EA110F930A04AF89AA62CA24CFA9A0A2AAA4AAA88AA288D1008FE3000 +4BB2:00287E28487C7E2848287EFE4810487C7E54027CAA54AA7CAA00822814440882 +4BB3:003CFBE0A124F8A8A3FEF8A8A124A202F9FC0924A924A9FCA924892409FC3104 +4BB4:00107ED448487F4A48847E84497A48007EFC0284AAFCAA00AA84824815FE0800 +4BB5:00207DFC50887C5053FE7C0051FC51247DFC052455FC542055FC842017FE0800 +4BB6:00507E4848FE7F9048FC7E9048FC48907EFE0280AA10AAFEAA38825414920810 +4BB7:00007EFE48AA7EAA48FE7E4048FE49227EFA02AAAAAAAAFAAA2282FA140A0804 +4BB8:0A803138228838382288393822887FFE51029FF411001FF011001FFC2A44492C +4BB9:0020F93CA120FBFEA010F814A3FEA210FBF00A54AA54AAD4AB688C4A08963322 +4BBA:0040F820A3FEF888A052FFACA2AAA2A8FDAC0800A904A9FCA90489FC09043204 +4BBB:0020FBFEA020F9FCA000FBFEA002A1FCF8200BFEA800ABFEA8048BBE0AA4338C +4BBC:00127E5448A87E4448927E54489848247EC20284AAEEAB24AAB4825E14440884 +4BBD:0040F820A3FEFA50A3FEFA52A3FEA200FA940AD8AA90AAD2AA8E8C000954322A +4BBE:0110F890A3DEF810A25EF982A3DEA010FBDE0A50ABDEAA50ABDE8A500A5232CE +4BBF:0020FBFEA24AF9FEA048F9FEA048A3FEF88409FEAA84A8FCA920893C0AA0347E +4BC0:03FCF908A1F8F908A1F8F90EA7F8A008FFFE0A94AB9CAA94AB9C8AD60FBC3084 +4BC1:00400FFEF200A3F8F000A7F8F408A7F8F2201D5C57F4BC9495DC1C9657F62CA2 +4BC2:3FF821003FF021003FF892487EFC48907EFC48907EFEAAAA0100FFFE0920711C +4BC3:0040F82008204BFE4A024C4448407FFE048804881D08E4D04420045028881304 +4BC4:0000F8FC08844884488448FC48207C2005FE05221D52E58A450A0502290A1104 +4BC5:0000F1FE108450FC508450FC50867BFC08040BDE3852C952089409482A541422 +4BC6:00207F20412079204920FFA080A07F2041207F2041207F2241224122451E4200 +4BC7:00207C204420742054FCFE2482247C2444247C4444447C444484448455284A10 +4BC8:00007CFC440074005400FEFE82507C5044507C5044507C5244524492548E4900 +4BC9:00407C404440747C5444FE8882A07D2044207C5044507C484488448455044A02 +4BCA:00007C0045FE74045404FEF482947C9444947C9444F47C944404440454144808 +4BCB:00507C484448744055FEFE4082407C7C44A47CA444A87D284510462854444882 +4BCC:00007CFE4482748254FEFEA082A07CA044F87CA844A87CA84528452A564A4886 +4BCD:00207C20445074505488FF2482127C1045FC7C0444087C884450442054104810 +4BCE:00207C20445074505488FF0482FA7C2044207C2045FC7C204420442054204820 +4BCF:00047C1E44F074105410FEFE82107C1044107CFE44827C824482448254FE4882 +4BD0:00107C10441074FE5492FE9282AA7CC644927C9244AA7CC644824482548A4884 +4BD1:00207C20452474A454A8FE2083FE7C5044507C5044507C5244524492548E4900 +4BD2:00207C20444E74805520FE20825E7CC445447C4444447C444444444454544848 +4BD3:00207C2044FC74205420FE2083FE7C0044207C2044FC7C204420442055FE4800 +4BD4:00207C1045FE75025400FE1C82E07C2044207C3E45E07C2044224422541E4800 +4BD5:00007C0645D874485448FE88829E7DC844487D4845487C9E44804540563E4C00 +4BD6:00207C1044FC74845484FEFC82847C8444FC7CA244A47C984490448854C44882 +4BD7:01107D12451475D85510FF1283527D8E45207C2045FC7C204420442057FE4800 +4BD8:00207C1045FE75025604FEF882007C0045FE7C5044507C5044924492550E4A00 +4BD9:00147C1244FE74105410FEFE82927C9244FE7C9244927CFE4492449254924886 +4BDA:00207C4444F874105424FEFE82027CFC44847CFC44847CFC4484448454944888 +4BDB:00407C2045FC75045480FE9C82D47D5445547D5446D87C504494449455144A0C +4BDC:00007CFC4484748454FCFE8482847CFC44407CFE452A7E4A44924522544A4884 +4BDD:00207C2044FE744054FCFF1082FE7C0044FC7C8444FC7C8444FC448454944888 +4BDE:00007CF84488748854E8FEA882A87DFC45047D7445547D544574450455144908 +4BDF:00007C844448740055FEFE2082447DA844307C5845987C344452459054504820 +4BE0:00007CF84488748854F8FE8882887CF844007DFC45547D544554455457FE4800 +4BE1:00887C50440075FE5450FFFC82547DFE44547DFC44507CD84554465254504850 +4BE2:00803FFE24103F7C26382D5437FA220823C822482FFE2A0A23F8420842288210 +4BE3:00207DFC452475FC5420FFFE82007DFC45047DFC45047DFC450445FC54884904 +4BE4:00107C28444474BA5500FEFE82927CD644927CFE44007C7C4444447C5444487C +4BE5:00007CFE448274FE5482FEFE82447CAA44EE7C4444AA7CEE440044D454AA492A +4BE6:00247CFE4424740054FEFEAA82AA7CFE44147CFE44907CD244AC44AA54964922 +4BE7:01007FFC00001FF010101FF000007FFE40029FF4101017D0145017D010101030 +4BE8:0100FFFE00001FF010101FF000007FFC40044FE448244FEC0200FFFE1830E00E +4BE9:0100FFFE00001FF010107FFC40044FE448244FEC00003FF821083FF820021FFE +4BEA:200011FEFE1000207CFC44847C8400FCFE8482FCBA84AA84AAFCBA4882848702 +4BEB:00207C1045FE7C0044FC7C8410FCFE0001FE7D02457A7D4A117A5502930A3104 +4BEC:1000FEEE44AA7CAA00EEFE00AA7CBA54827CFE54447C7C1010FEFE1010101010 +4BED:3E0420183E6020043E182062FF0422187F6000003FF00820044003801C70E00E +4BEE:3E0420183E6020043E182062FF0422187F6000003FE00420047C08043014C008 +4BEF:3E0420183E6020043E182062FF0422187F60010011102108416403801C00E000 +4BF0:3E0420183E6020043E182062FF0422187F60028004401C70E44E044008401040 +4BF1:3E0420183E6020043E182062FF0422187F6000007FFC01000770190CE1020100 +4BF2:3E0420183E6020043E182062FF0422187F6000003FF821083FF8200220021FFE +4BF3:3E0420183E6020043E182062FF0422187F60044008203218C44608201FF00810 +4BF4:3F0820303EC42018FF62220C7F7000000FE01020601C1FE0082004C00780F87E +4BF5:3E0420183E6020043E182062FF0422187F6001003FF801000820FFFE08201020 +4BF6:3F0820303EC42018FF62220C7F7000001FF010101FF010101FF01010FFFE0000 +4BF7:3E0420183E6020043E182062FF0422187F600090FFFE10887E50102420D4C70C +4BF8:3E0420183E6020043E182062FF0422187F60410021FC0A441048E0A021182606 +4BF9:3F042018FF62220C7F7000003FF000101FF000107FFE40029FF4082007C0F83E +4BFA:3F042018FF62220C7F7000183FE021003FFC20802C64301C1FF0101010101FF0 +4BFB:3F0820303EC42018FF62220C7F7011001FF82100FFFE00001FF010101FF01010 +4BFC:3E0420183E6020043E182062FF0422187F601400082014A46CA8155064881906 +4BFD:3F0820303EC42018FF62220C7F7001003FF80440FFFE00001FF010101FF01010 +4BFE:3F042018FF62220C7F7000003FF8210827C821082FE8200827C8444847C88018 +4BFF:3E0420183E6020043E182062FF0422187F6001003FF80820145001007FFC0100 +4C00:3F042018FF62220C7F7000001FF00100FFFE0920711C0200FFFE082007C07838 +4C01:3F042018FF62220C7F7000003FF000101FF00010FFFE111009A005401930E30E +4C02:3F0820303EC42018FF62220C7F7000183FE0121009207FFC05401930E10E0100 +4C03:3E0420183E6020043E182062FF0422187F60082004407FFC044024481450FFFE +4C04:3F0820303EC42018FF62220C7F7000003FF821083FF821083FF84904489287F2 +4C05:3F042018FF62220C7F7000007FFC02001FF010101FF010101FF010101FF00820 +4C06:3F042018FF62220C7F7000001FF0022001407FFC188462880100FFFE0920711C +4C07:3F042018FF62220C7F7002001FD00220FFFE03000FF03810CFF008100FF00810 +4C08:3F042018FF62220C7F70082004407FFC01003FF80200FFFE080037F0C0801FFC +4C09:3F042018FF62220C7F70000010783E4822482A86FF7822482A2842104A2884C6 +4C0A:3F042018FF62220C7F700110FFFE21083FF821083FF821080020FFFE08200460 +4C0B:3F042018FF62220C7F7000001FF010101FF010107FFC44043FF8082007C07838 +4C0C:3E0420183E6020043E182062FF0422187F60108821544A22113C312052A0147E +4C0D:3F042018FF62220C7F7001007FFC09103108C6C41930E92E05C0193061080300 +4C0E:3F042018FF62220C7F7001001FF011101FF00100FFFE10101FF010101FF00820 +4C0F:3F042018FF62220C7F7008287F240820FFFE12203FA46424BF2824123FAA2046 +4C10:3F042018FF62220C7F7024203F3E21403F5024883F0800003FF824482448FFFE +4C11:3F042018FF62220C7F7000003FF801007FFE492285147FFC02003FF824482458 +4C12:3F042018FF62220C7F7008207FFC08207FFE40029FF40600192006C038A00318 +4C13:3F042018FF62220C7F7002001FF014901250FFFE92122FE8440407E008203060 +4C14:3F042018FF62220C7F7008003E7822482A867E7822482A30464C3FF82448FFFE +4C15:3F042018FF62220C7F7001FC01003FFE210221F02F0420FC20004FFC4914BFFE +4C16:3F042018FF62220C7F7028503E7C4890FEFE1528264A5FF6149012501FF00820 +4C17:BEFA8822BEFA8822BEFA84028782888297C284428FE289228FE289228F1281F6 +4C18:BEFA8822BEFA8822BEFA8002BEFA924A8A2A934A82828C62B19A860280729F86 +4C19:0010FE1000107CFE44107C1000FCFE448244AA449228FE289210922892448682 +4C1A:0020FE1000107CFE44447C440044FE448244AA289228FE109210922892448682 +4C1B:0000FE0001FE7C4044407C780048FE488268AA989298FE88928A92AA92CA8686 +4C1C:0000EFEE200227C22442E7CE80088FE88828EAAE29222FE229222922A92A4864 +4C1D:0044FE2400287CFE44927CD600BAFE9282FEAA00927CFE44927C9244927C8644 +4C1E:713C17C4719C47F0725C17C45A5423C8FFFE00001FF010107FFC44445FF4410C +4C1F:3FF80000FFFE082010103FF802081FF011101FF012101FF004A808BA3082C07E +4C20:081010107F10497C49547F54497C49547F54107C1A102C902F904810480287FE +4C21:080810087F284928493E7F48490849087F7E10081A082C942F924820484287FE +4C22:102020407C8E550054207C5E54C455447C4410442A442D544F48480287FE0000 +4C23:100021FC7D04550455AC7D54555455547D5411AC2B042D144F08480287FE0000 +4C24:10201040FDFC11247D2455FC7D2455247DFC1040386854B292BE11201122121E +4C25:00507FFC00403E4822503E2000547FFC11141FF012101FF004A808BA3082C07E +4C26:080010087F10497E494A7F7E4952497E7F2810481A7E2C882F884808480287FE +4C27:1020203C7C2054FE54A27CB854E4549C7C8010B82AA82D2A4F464A0287FE0000 +4C28:100021FC7D2455FC55007D7C5544557C7D44117C2A442D7C4F00480287FE0000 +4C29:102010407DFC12941494FFFC10A420A47EFCA22022443E6A226E22A03EA2231E +4C2A:1020924054FCAA94449482FC7CA444A444FC7C204444446A7C6E44A044A24D1E +4C2B:1010207C7C1054FE54447CEE544454EE7C0010FE2A282D2A4F46488287FE0000 +4C2C:10FC20287C1055FE54527C9055FE54AA7CC610BA2AAA2DBA4F84480287FE0000 +4C2D:0020FE4010FCFE94AA94AAFCAAA486A400FCFE201044FE6AAA6EAAA0AAA2871E +4C2E:208843FEF820A9FCA820FBFEA854A992F89023FE209054D45B8A5E9651A28FFE +4C2F:1100215C7D84555854C87D3E55CA56A87DEC10A82B682D5E4F80480287FE0000 +4C30:00207C4010FCFE94929454FC10A454A400FCFE201044FE6AAA6EAAA0AAA2871E +4C31:0020FE4010FCFE94929454FC00A4EEA4AAFCEE200044FE6A546EBAA010A2FF1E +4C32:102010203E20422084207F20492049207F20492049207F22002255224A9E8A80 +4C33:200020007CFE441088107E10521052107E10521052107E100010AA10AA500020 +4C34:20402040788048FC91007E0054F854087C10542054407C800084AA84AA7C0000 +4C35:200021FC7C04440888107E20522053FE7E20522052207E200020AA20AAA00040 +4C36:202020107C10440089FE7E40524052407E40524052407E400040AA40AA7E0000 +4C37:20202020782049FE90207C20542054FC7C20542054207DFE0020AA20AA200020 +4C38:200820487848484890447C8454A455227C20544054407C480084ABFEAA820000 +4C39:202820247C244420882E7EF0522052247E24522852287E100032AA4AAB860002 +4C3A:2004200E7C70444088407E40527E52487E48524852487E480048AA88AA880108 +4C3B:102010203E20423E84447F44494449A47F28492849107F10002855284AC48A82 +4C3C:202020207820485090507C88554456227C2054F854087C080010AA10AA200020 +4C3D:2020202078204BFE90207C2055FC55247D24552455247D340128AA20AA200020 +4C3E:2000200078FC48A490A47CA454A454A47CFC548054807C800082AA82AA7E0000 +4C3F:20402040787E488091207CA054AC54B47DE454A454B47CA800A2AA82AA7E0000 +4C40:20202020782048FC90A47CA454A454A47CA455FE54207C500050AA88AB040202 +4C41:2020202078204BFE90507C50548855247E22542055FC7C200020AA20AA200020 +4C42:201020507850489090FC7D5455D454947C94551455547DD40054AA24AA340048 +4C43:201020107C504450887C7E90531052107EFE521052287E280028AA44AA440082 +4C44:2008201C79F0495091507D50555055507D50554855487D680154AA74AA520400 +4C45:2020202078204BFE90207C20542055FC7C7054A854A87D240124AA22AA200020 +4C46:200021FC78444848908E7C82557A56147C20542057FE7C200020AA20AAA00040 +4C47:200020007CFC448488847E8452FC52847E84528452FC7E840000AA00ABFE0000 +4C48:200020FC7800480090007DFC542054207CA854A455247D220222AA20AAA00040 +4C49:200020F87888488890887CF8548854887C8854F854887C880088AA88ABFE0000 +4C4A:20202020792448A490A87C20542057FE7C7054A854A87D240124AA22AA200020 +4C4B:204820487848484891FE7C48544854487C4855FE54007C480044AA84AA820102 +4C4C:200020FE7C90449088907EBC52A452A47EA452A452BC7E900090AA90AAFE0000 +4C4D:200021FE7840484090407C78548854A87C98550855487C300010AA10ABFE0000 +4C4E:200021FE7800480090FC7C84548454FC7C84548454FC7C840000AA00ABFE0000 +4C4F:200021FE7800480090FC7C84548454847CFC540054847C440048AA00ABFE0000 +4C50:2008203C79C0480491447CA8540055F87C10542057FE7C200020AA20AAA00040 +4C51:2080208C78B048A093E07CA054BE54E87CA857A854A87CA800A8AAA8AAC80188 +4C52:2000207C7C444444887C7E0052FE52927E92529252FE7E800080AA82AA82007E +4C53:2000200679D8484890487C88549E55C87C48554855487C9E0080AB40AA3E0400 +4C54:2088208878884910915E7D64575455547D54555455547D480148AB54AB140122 +4C55:2080208078FE490092FC7C8454A454947DFE548455247D1401FEAA04AA280010 +4C56:200020FE7C28442888287EEE52AA52AA7EAA52AA52EE7E280028AA28AA480088 +4C57:08000F7C28447F28A11016283846CFE010403FF051101FF011101FF024884244 +4C58:03043C2404247FA416242504440C0FE010403FF051101FF011101FF024884244 +4C59:20802080789C48F490947C9457F454147C94549455C87EA80088AA94AA9401A2 +4C5A:200021F87808480890F87C08540855FC7C20552454A87C7000A8AB24AAA20040 +4C5B:20142012781049FE90107C1055D255527D52555455D47C0800CAAB1AAA260042 +4C5C:20482048784849FE90487C4855FE54007CFC548454847CFC0084AA84AAFC0084 +4C5D:2020204078FE489290927CFE549254A27CFE544854887DFE0008AA08AA080008 +4C5E:2020202079FE485090887D0456FA54007C0055FE54207CA400A2AB22AA200060 +4C5F:200020FE7C82448288FE7E88528852FE7E88528852BE7EA200A2AAA2AABE0122 +4C60:20482044785E49E090287C12546A55967C48545E55E07C240028AA12AA6A0186 +4C61:2080208078FE490292227CAA547254227DFE542254727CAA0122AA22AA0A0004 +4C62:2080208078F8490892107DFC542454247DFE542454247DFC0024AA20AAA00040 +4C63:2040202079FE480090887C88555456227C00542055FE7C200020AA20AA200020 +4C64:20402040787C488491087E00542054CE7C82548254EE7C820082AA82AAFE0082 +4C65:24043FA44424FFA404243F8424942FE810403FF051101FF011101FF024884244 +4C66:20502048788048FE91907E9054FC54907C9054FC54907C900090AAFEAA800080 +4C67:2020212478A8482091FC7C4057FE54887D0456FA54887C8800A8AA92AA82007E +4C68:2082208273E2908A208AFBEAAAAAAAAAFAAAAAEAA88AF9CA02A2AC82A88A0084 +4C69:200020FE7C8244C688AA7EFE52A252927EFE52A252A27EBA0082AA82AA8A0084 +4C6A:2010201079FE481090107CFE541054107DFE542054527CD40148AA44AA620040 +4C6B:04047FC404243FA424A43FA4150424944FE810403FF051101FF011101FF02488 +4C6C:200021FE78124890909C7C90557E56007CFC548454FC7C8400FCAA84AA940088 +4C6D:208020FE7890489090D07CBC559456947CAC54A454B47C880088AA88AAFE0080 +4C6E:2080209E73EA908A21CAF88AABEAA892F8A6A820ABFEF8200050A888A9040602 +4C6F:7E20243E1848FFA829104A2898460FE010403FF051101FF011101FF024884244 +4C70:2008203C79E0482093FE7C2055FC55247DFC552455FC7C2001FCAA20ABFE0000 +4C71:202020107CFE440088447E2852FE52827E10527C52547E540054AA5CAA100010 +4C72:2040207C788448F890087DFE544054A47D38545854947D340054AA92AB500020 +4C73:200021FE7900497C91547D54557C55547D54557C55107D10017CAA10AA1004FE +4C74:2040205E78404860915E7D525552555E7C52545254527C5E0052AA40AA5E0040 +4C75:205020887924484090907DF8540854007DDC544455547CCC0154AA44AA5400C8 +4C76:2100209E79D2495491547DD8555455527DD25512559A7D5401D0AB50AA100010 +4C77:0F1008107F9048A04E3E79444F2451245F2475285F2855105F284028AAC40082 +4C78:20A0212C7924492491AC7D24552455FC7C2055FC54887C500020AA50AA880306 +4C79:204420247C2844FE88107E7C521052FE7E205220527C7E500090AB10AAFE0000 +4C7A:202021247924492491FC7C0057FE54007DFC550455047DFC0088AA50ABFE0000 +4C7B:2000207C7C44447488547EFE5282527C7E44527C52447E7C0044AA44AA540048 +4C7C:200021FE7902490291FE7D245524557E7D24552455FE7D520154AA48AA640442 +4C7D:202020207850484890A47DFE568454FC7C8454FC54807CFC0144AB44AA7C0044 +4C7E:202021FC79244BFE91247DFC542055FC7D2455FC54407DFE0088ABD0AA70038C +4C7F:21002102711C97D02110FFD0AD5EAFD4FD54AFD4A914FFD40114A924A9240144 +4C80:08207E2008F8FF2814287F6A082A0FE610423FF051101FF011101FF024884244 +4C81:200423E47224922423EEFA04AAE4AA04FA0CABF4AA44FA640554AD44AA5400C8 +4C82:22102110711097BE2240FA00ABBEAA8AFA88AAA8AAAEFAA804A8ADA8A85E1080 +4C83:209221247892480090FE7C9254FE54927CFE541055FE7C380054AA92AB100010 +4C84:2208220873C8921027DEFA54AB64AAD4FFF4AA54AD54FCC807C8A854AAA40142 +4C85:2100213C712493A4213CF924A924ABBCF924A924A93CF92802A8AACAAC4A0886 +4C86:202020207C78444888907E7C525452547E7C525452547E7C0000AAAAAAAA0000 +4C87:20102210797C4910907C7C545754557C7D10553855547D920110AA90AA7E0000 +4C88:2020201079FE494891487D4855FE55487D4855EC555A7D680148AB48AA480048 +4C89:21402144715893F02150F9D0A95EA9D4F954A954ABF4F8140154AA34AC140024 +4C8A:2010239072FE92A022BEFB48AABEAA80FABEAAA2AABEFB22023EAA22AA220226 +4C8B:2088208879DC488893DE7C88555456227CFC548454847CFC0084AA84AAFC0084 +4C8C:2108210877C89108211EFB92A824AB80F808AFC8A908F9080594A954A9240342 +4C8D:112420A879FC48406BFE59084A84FCFA49104BFC6D2459FC492449FC48009954 +4C8E:200823887088911027DEFA94AAA4AB94FA94AB94AA94FAC80388AE94A8A400C2 +4C8F:2048216A78DC484890B47D2255FE55027C20542054FC7C240044AA44AA940108 +4C90:2020203E782049FE91227DFC5522557E7D54557C55547D7C0110AAFEAA2204C6 +4C91:210420887BFE482091FC7C2057FE54547D92549057FE7C9000D4AB8AAA9601A2 +4C92:210021DE724A948A23EAFAB6AAA4ABF4FABEAAA4ABE4FABE02A4AAA4AA240464 +4C93:202020207850488891047EFA540054007DDC555455547DDC0088AA88AB540222 +4C94:200023FE700091FC2124F9FCA924ABFEF800A9FCA924F9FC0124A9FCA80003FE +4C95:2084204879FE4848914A7CCC544855FE7C0054FC54847C8400FCAA84AA8400FC +4C96:202023FE702091FC2000FBFEA802A9FCF820ABFEA800FBFE0004ABBEAAA4038C +4C97:21202120725692482580F970AA2EAA24FEF4AA24AAACFA740224AA34AAC4020C +4C98:2108210879EE4A9490427C1055FE55027CF8548854F87C8000FCAA84AAFC0084 +4C99:2108210871EE92942042F800ABDEAA52FBD2AA52ABD2FA1A0294AB50AA100010 +4C9A:2088208873EE90922084FBEEAAAAAAAEFBEAA88EA9CAFAAE04A0A88CA88A0092 +4C9B:208823FE788849FC91547DFC540057FE7E0254F854887CF80088AAF8AA8800F8 +4C9C:3C3C4848FCFC54547C7C54547C7CAAAA3C3C4848FCFC54547C7C54547C7CAAAA +4C9D:202020207C50445088887D04560254F87C88548854A87C9000821C82E07E4000 +4C9E:204020207C20440089FE7C00540454847C84544854487C4800501C10E3FE4000 +4C9F:200020407D9E451289127D1255D255127D125512555A7D9401101C10E0104010 +4CA0:202020207DFE442088FC7C4055FE54887D0456FA54887C8800F81C88E08840F8 +4CA1:208820487C5045FE88507C5055FC55547D54558C55047DFC01041D04E1FC4104 +4CA2:01243CA825FC244027FE3D08268424FA25103FFC252425FC252445FC54008BFE +4CA3:0F1008107F9048A04E3E79444F2451245F2475285F2855105F284028BF440082 +4CA4:400044FE7A28882814FEFAAAAAAAA8AAF9AEAAC2AE82FAFE02821A82E2FE4082 +4CA5:02003FE004221822E21E1FF010101FF010101FF010001FFC10001FFC2A44452C +4CA6:101020107F1041107F7E41107F1040107F9040287FA800A8AAA8AAC481440682 +4CA7:1040108011FC110411FCFD0411FC110011FE11001DFEE00242AA02AA0202000C +4CA8:004000807DFC110411FC110411FC110011FE110011FE1C02E2AA42AA0202000C +4CA9:3FFC20043FFC220027F0241027F0241027F0240027FC240047FC40048AA40AAC +4CAA:1040108011FC110411FCFD0411FC110011FE290025FE240242AA42AA8202000C +4CAB:0080FDF8290829F8290829F8290029FC290029FC280429542A5C480247FE8000 +4CAC:1004201E7CF044907C9044907C9040FE7E9040907E900288AA8AAAAA82C60C82 +4CAD:04200E40F0FC908490FC9084FCFC908090FE908090FE88028AAAC6AA8302000C +4CAE:00207C4000FC008400FCFE8428FC288028FE288028FE2A024EAA4AAA8202000C +4CAF:00207E4022FC248424FC28842EFC22802AFE248044FE4A0292AA20AA4102000C +4CB0:0040008079FC010401FC0104FDFC210021FE210041FE50028AAAFAAA0A02000C +4CB1:102020107F0041FE7F2041207F3C40247FA440247FA400A4AAA4AAA481540688 +4CB2:0020284024FC248442FC528490FC108020FE208048FE4402FCAA44AA0102000C +4CB3:1020084008FCFF8400FC00843CFC248024FE248024FE250246AA44AA8102000C +4CB4:1040108011FC150459FC510451FC910011FE110011FE280226AA42AA4202800C +4CB5:0100111021E84F04F2001FF010101FF010101FF010001FFC10001FFC2A44452C +4CB6:1FF00000FFFE0844323CDFF010101FF010101FF010001FFC10001FFC2A44452C +4CB7:04001FF010101FF010101FF010001FFC10001FFC492484940108FFFE0920711C +4CB8:1040108011FC290425FC4304A9FC290029FE290029FE28024AAA4AAA8A02000C +4CB9:00407E8009FC090411FC150433FC510091FE110011FE00020EAAF2AA4202000C +4CBA:4840488049FC4904FDFC490449FC490079FE490049FE48024AAA7AAA4A02000C +4CBB:2040108001FCFD0421FC410449FC8900F1FE110021FE20024AAAFAAA0A02000C +4CBC:1040108051FC51047DFC510491FC110011FE7D0011FE100212AA1EAAE202400C +4CBD:00400080F9FC210421FC410479FC4900C9FE490049FE48027AAA4AAA0202000C +4CBE:00007DFE108010FC1E04F02802101FF010101FF010101FFC10001FFC0004492C +4CBF:00203E4022FC228422FC3E8420FC288028FE2E8028FE28024AAA4CAA8902000C +4CC0:101020107C5044507C7C44907D1040107EFE40107E280228AA28AA4482440C82 +4CC1:105020487C4844407DFE44407C40407C7EA440A47EA80328AB10AA2882440C82 +4CC2:0020FC4024FC248444FC548488FC00807CFE448044FE440244AA7CAA4502000C +4CC3:02001FF010101FF010101FFC10001FFC0004492C08001EF8228854980882307E +4CC4:1420144014FC548455FC5E8454FC548054FE548054FE54025DAA76AAC502000C +4CC5:100020007F3E41227F2241227F22403E7FA240007F940094AAA2AAA281420600 +4CC6:1040108021FC790449FC490449FC490079FE490049FE48024AAA7AAA4A02000C +4CC7:00203C4024FC34842CFC248424FCFE8044FE648054FE44027EAA04AA2902100C +4CC8:104020407CFC44847D0446F47C9440947EF440847E940288AA82AA82827E0C00 +4CC9:204020803DFC4504A9FC110429FC450083FE310009FE000262AA12AA0A02000C +4CCA:2820244024FC2084FEFC208420FC3E8042FE448054FE880216AA22AA4202000C +4CCB:2040208021FCF904A9FCA904A9FCA900F9FEA10021FE28023AAAEAAA4202000C +4CCC:1040108021FC4904FDFC050479FC490049FE790049FE78024AAA4AAA4A02580C +4CCD:24102420247C24447F7C2444247C2440247EFF40007E240224AA42AA4302820C +4CCE:0040408099FC890489FC890489FCD90089FE890089FE8802FAAA8AAA0202000C +4CCF:1040108011FC7D0411FC1104FDFC010011FE11007DFE100212AA1EAAE202400C +4CD0:410021FC0A441048E0A0211826061FF010101FF010101FFC10001FFC0004492C +4CD1:10201040FEFC108420FC3E8422FC6280BEFE228022FE3E0222AA22AA2302260C +4CD2:08207F280824FFFE10207F2041247F2441247FA840287F900092AAAAAAC60182 +4CD3:102012407EFC148414FCFF8408FC108020FE7E80A0FE22022CAA30AA2102000C +4CD4:060038F820083CF820083FF802001FF010101FF010101FFC10001FFC0004492C +4CD5:0E20F04022FC928454FC0084FCFC088010FE168018FEF00252AA12AA5202200C +4CD6:100021FE7CA044A87CA844E87CA840A87EA840E87EA802AAAABAABEA82260C20 +4CD7:02001FF010101FF010101FFC5244892C02403C500848FFFE08507E240854198C +4CD8:201040D8F3949094F09093FEF0908094F89480D8FB980890A8AAA8CA8A863102 +4CD9:081008207F7C49447F7C49447F7C0040FF7E2040407E7E0202AA02AA1502080C +4CDA:00407C8045FC7D0445FC7D0401FC01007DFE110011FEFE0212AA12AA1202100C +4CDB:00207E4042FC42847EFC428442FC7E8010FE1080FEFE220264AA18AA2502C20C +4CDC:1020104028FC448482FC7C8410FC1080FEFE108054FE520292AA10AA5102200C +4CDD:202010407CFC008444FC288400FCFE8000FE00807CFE440244AA44AA7D02440C +4CDE:081008207F7C10443E7C1044FFFC2240497E88C03E7E08027FAA08AA0902080C +4CDF:00200E40EAFCAA84AAFCAE84EAFCAA80AAFEAE80EAFEAA020AAA12AA1302260C +4CE0:02100F20787C0844FF7C2A442A7CFF402A7E2A40FF7E080208AA0EAA7102200C +4CE1:2820244040FC7E84C8FC48847EFC488048FE7E8048FE480248AA7EAA4102400C +4CE2:4840488049FCFD0449FC490479FC490079FE490049FEFC0202AA52AA4A02840C +4CE3:08507F480840FFFE20403E502222465A82861FF010101FF010101FFC5244892C +4CE4:10109220527C5444107CFE44927C9240BA7ED640927E920292AA82AA8B02840C +4CE5:1020924092FCFE8410FC288444FC928008FEFC8004FE080252AA22AA1202000C +4CE6:20201040FEFC828400FC7C8400FC7C8044FE7C8044FE7C0202AA1EAAE202400C +4CE7:21004178F1089208F2FE9640FA40827CFA908210FAFE0A10AA28AA288A443282 +4CE8:102020407CFC44847CFC44847CFC0080FEFE108010FE7C0212AA1EAAF202400C +4CE9:0020FE4028FC2884FEFCAA84AAFCFE8010FEFC8024FE44022AAA12AA2A02C40C +4CEA:1020924092FC9284FEFC0084FEFC108020FEFE80AAFEAA02AAAAAAAAAB02860C +4CEB:0A107420157C5244227C2144417CBE40087E08407F7E080214AA12AA2302400C +4CEC:28402880FDFC290439FC11047DFC550055FE7D0011FEFC0212AA12AA1202100C +4CED:0020EE40AAFCAA84AAFCEA84AAFCAA80EAFE8A80CAFEAE02D8AA88AA0902080C +4CEE:00207C1045E07C2245B47CA8452456A28A401FF010101FF010101FFC5244892C +4CEF:1C20704010FCFE8410FC7C8454FC7C8054FE7C8010FE7C0210AA1EAAF102400C +4CF0:1008179014BC24A424BC67A4A23C22202FBE272026BE2A822AAA322A2202220C +4CF1:00207E7C14C40838FEC62A2048FCA844128C1FF010101FF010101FFC5244892C +4CF2:11FE1100FD7C11001DFEF1541248546422421FF010101FF010101FFC5244892C +4CF3:1020544054FC7C8492FC9284FEFC00807CFE0080FEFE100254AA92AA5102200C +4CF4:0020FE40AAFCAA84AAFCFE8410FC548052FE928010FE540252AA92AA1102100C +4CF5:11041108111E7D1213DE5552555E5550BB5E1150395E554292521252154A1884 +4CF6:100E20F07C2244927C4444207C4440F87E1040247EFE0210AAFEAA2882440C82 +4CF7:11102110CAA814443240D27C154014FE0A001FF010101FF010101FFC5244892C +4CF8:00803FFE24103F7C26382D543412210027F0241027F0241027FC40044AA4800C +4CF9:20404020F3FE9202F00893EEF008801CFBE48154F9480954A964A942893E3200 +4CFA:08101420227C4944BEFC0444087CFFC0147E7F40557E6302412A7F2A41427F0C +4CFB:08047F7808403E402A7E3E482A48FF480A881FF010101FF010101FFC5244892C +4CFC:100020FE7C8044807CBC44A47CA440BC7E8040EE7EAA02AAAAEEAA8082FE0C00 +4CFD:1020924092FCFE8428FC24847EFCC88048FE7E8048FE7E0248AA48AA7F02400C +4CFE:0A107420157C5244227C21445D7C80407E7E4240427E7E0242AA24AA0F02F00C +4CFF:24102620357C54445F7C7444947C64402A7E4940917E0002AAAAAAAAAB02000C +4D00:101008207F7C2244FF7C00447F7C49407F7E49407F7E08027F2A082A0F42F00C +4D01:20201040FEFC82847CFC54847CFC54807CFE1080FEFE920292AABAAA8B02840C +4D02:20103E20427CFF44497C49447F7C1040287ED540267ECD0215AA24AAD502080C +4D03:102010407CFC1084FEFC4484EEFC448064FEDE8000FEFE0228AA2AAA4D02880C +4D04:0F10F020117C8944427C0044FF7C8140427E7740927E5A022F2A222A4242820C +4D05:08107F20087C2244FFFC22447F7C41407F7E41407F7E41027F2A222A4142808C +4D06:2820AA406CFC2884FEFC448428FCFE8010FE7C8010FEFE0210AA28AA4502820C +4D07:00107F20087CFFC488FC6B44087C6B40147E2A40457EBE0202AA04AA1902040C +4D08:10202040FEFC9284D6FCBA84FEFC9280BAFED68082FE1002FEAA28AA4502820C +4D09:0020FE40AAFCAA84FEFC0084FEFC00807CFE44807CFE2A0264AAA2AA3102200C +4D0A:41082210FFBC08247F3C0824FFBC152064BE2420FFBE2402352AE2AA2582688C +4D0B:200043FCF2949294F3FC9000F7FE8000FBFC8204FBFC08A2A914AB088D443182 +4D0C:104820487DFE44487CFE44827D7C40007EFE40207ED2022CAAD8AA2C82CA0C30 +4D0D:00100020777C5544557C7744557C5540777E5540557E7702002A552A88C2000C +4D0E:00001FF011101FF011103FF82AA83EF82AA83FF810101FF010101FFC5244892C +4D0F:22082210FFBC22243E3C41245D3CD5E0553E5520DD7E4182002A552A4A828A8C +4D10:0808FF9084BC77242A3C77242ABCFFA0003E7F20413E7F02412A7F2A2202410C +4D11:7F0849107F3C4924FFBCAAA4FFBCAAA0FFBE0020FFBEA2823E2A222A2782F80C +4D12:7F080810FFBC88A46B3C08246B3C0020EFBEAAA0EFBE0002FFAA492AAA82FF8C +4D13:0010FFA0087C084408647F544944494C4940497E49024D024A7A0802080A0804 +4D14:2020104000FCFE8400A4288444948288048044FE2802100229FA440284140008 +4D15:7F0408441E44224454440844320CDFE01420126010001FF800087F8800280010 +4D16:10201040FEFC10847CA41084FE9400887C8044FE7C0244027DFA440254144808 +4D17:00207E4042FC7E8442A47E8442947E88148012FEFF02100229FA240242148008 +4D18:03107C20477C44445F64555456445C4C5540537E50025702557A5502A98A0004 +4D19:02087910493E4BA248327AAA412247E67920693EAB82A902297A3902290A0104 +4D1A:104010201E2010FC1000FE009278C648AA48D648AA48C64A924AFE8A82860100 +4D1B:101010921E5210541010FEFE9282C682AAFED682AA82C6FE9282FE82828A0084 +4D1C:101010201EFE10921092FEFE9292C692AAFED620AA24C65A925EFE908292010E +4D1D:1000107C1E44107C1044FE7C9200C7FEAAA0D6EEAAAAC6EA92BAFFE48224002A +4D1E:100011DC1E44115410CCFF549250C648AAFED790AAFEC69092FEFE9082FE0080 +4D1F:00803FFE22203FFC22243FFC242027BC2422279E200023F0221042904452980E +4D20:00803FFE22203FFC22243FFC242027BC2422279E203827C020405FFE41108E0E +4D21:00007FFE024012480A503FFE22203FFC22243FFC284028482F7048444B448C3C +4D22:00803FFE22203FFC22243FFC242027BC2422279E204020402FFE415042488C46 +4D23:08047F1E54F054107F92555255547F1054FE54105E10541054105C1056508020 +4D24:00803FFE22203FFC22243FFC242027BC242227DE224023FC24404BF840409FFE +4D25:00803FFE22203FFC22243FFC242027BC2422279E24003FBC24A444A44ABC9124 +4D26:00803FFE22203FFC22243FFC242227BE20403FFE200027F8200047F8440887F8 +4D27:081C7F70541054FE7F38555455927F10542054FE5E24544454285C10562880C4 +4D28:08007F7E544854507F5C555455547F5C545454545E5C5448545C5CAA568A8118 +4D29:00803FFE22203FFC22243FFC20003FFC21402FF829482FF820005FFC44908988 +4D2A:00803FFE22203FFC22243FFC280024F824083E78220824FE2E545538445484B2 +4D2B:08007F7C541054FE7F92555455107F54542854545E8A547C54045C0856308008 +4D2C:08480844FF442A402A5E5DE088401C402A4050401E2022225412080A14066002 +4D2D:08080808FF082A082AFE5D0888181C182A2850281E4822885408080814286010 +4D2E:08100810FF102A102A925D9288921C922A9250921E922292549208FE14026000 +4D2F:08400840FF402A7E2AAA5D2A882A1C4A2A4A50921F1222225422084214946008 +4D30:08480844FF442A402A5E5DE088401C442A4450481E3022225452088A15066002 +4D31:08200810FF102AFE2A825D0488401C482A5050601E40224254420842143E6000 +4D32:08100810FF102AFE2A105D1088101C7C2A1050381E3822545454089214106010 +4D33:08200810FF102AFE2A825D0488001C282A2850281E2822285444084414446082 +4D34:08100810FF102A102A1E5D1088101C102AFE50821E8222825482088214FE6082 +4D35:10841048FE0054FC5448BA481048384855FEA2483C484448A84810882888C108 +4D36:10401040FEFC54885550BA2010D83B2654F8A2203CF84420ABFE10202820C020 +4D37:10401020FE2055FE5502BA0410F838005400A3FE3C504450A89010922912C20E +4D38:080E08F0FF222A922A545D00887C1C082A1050101EFE22105410081014506020 +4D39:0800087CFF542A542A7C5D5488541C7C2A1050FE1E1022385454089214106010 +4D3A:08200810FF7C2A002A445D2888001CFE2A0050001E7C224454440844147C6044 +4D3B:0640387C08947E242CD44A0801007FFC11102BA845641918E3E60E4001800E40 +4D3C:10481044FE5E55E05428BA12106A39965448A25E3DE04424A8281012286AC186 +4D3D:10201040FEFE54925492BAFE109238A254FEA2483C8845FEA80810082808C008 +4D3E:10841044FE4855FE5420BAFC102039FE5440A2803CFE4510AA10141029FEC000 +4D3F:100011FEFF0254785400BAFC104038A45538A2583C944534A85210902950C020 +4D40:10101092FE54541054FEBA82108238FE5482A2FE3C824482A8FE10002844C082 +4D41:10481148FF5E556A5554BBC81050386455C4A37E3D444564A95411442954C248 +4D42:10201010FEFE54445428BAFE1082389254FEA2923CBA44AAA8AA10BA2882C086 +4D43:08280828FF7C2A282A285DFE88101C7C2A54507C1E54227C5400082814446082 +4D44:105011FCFF5455FC5554BBFC100039FC5400A3FC3D0445FCA88810502BFEC000 +4D45:08207F20083E3E4408A87F1010281E462280FFFE11C82AB40DD0764E01801E40 +4D46:10481048FEFE544854FEBA82117C380054FEA2203CD2442CA8D8102C28CAC030 +4D47:081004107FD04910493E49247FD4491459145D946B544D084908491489140922 +4D48:111023E040480BFC110033F0551010E0111012883FFE24103F7C26384D549412 +4D49:00803FFE24103F7C26382D543492214026303BEE20002FA428A44FA448A4898C +4D4A:0088788849FC488868885BFE4820FDFC492449FC492449FC4800488849049A02 +4D4B:282028207DFE28402840FEFC10847D8456FC54847C8454FC54847C8428944488 +4D4C:282028207C2029FC2820FEA810A87CA8557456227C50545054887C8829044602 +4D4D:282028107DFE280028FCFE8410FC7C0054FC54087C1055FE54107C1028504420 +4D4E:282029247D24292429FCFE0013FE7C20544055FC7D54555455547D542954450C +4D4F:280029DC7C44295428CCFF5410287C44559254207CC8543254C47C1828604580 +4D50:280029DC7D54295429DCFE0011FC7D2455FC55247DFC542057FE7C2028204420 +4D51:0C00700011FCFE24382454A490A428A455249024542438445444928451142208 +4D52:0C0070FC1084FE8438845484908428FC54849084548438845484928450FC2084 +4D53:0C1070101090FE9038FE549091102810541091FE541038105410921050102010 +4D54:0C20702013FEFE2039FC552491FC292455FC9020547038A85524962250202020 +4D55:0C0071FC1104FF0439FC5510911029FE55109110557C394455449344517C2244 +4D56:7E7C48047E2842107E2848FC7F0001007FFC09103288CC643938C54609203310 +4D57:0C0071FC1000FEF83888548890F8280055FC9124552439FC5524932451FC2104 +4D58:0C0070FC1084FEFC388454FC900029FE548090FE552A3A4A5492932250542088 +4D59:0C00702010FEFE4438825520907C288854509068559E382254D49208503021C0 +4D5A:0C1E71E01022FF1238945480902029CE5502910255CE39025502930251FE2102 +4D5B:0C0071EE114AFFEA392A55E49144294A55F09000541038FE5410921051FE2000 +4D5C:0C5071FC1154FFFC395455FC900029FE5500917C550039FE5550935451482266 +4D5D:00207F2049206B205D2049207F2008207F2008200F20F022002255224A9E8000 +4D5E:00047F0449046B245D2449247F2408247F2408240F24F024000455044A948008 +4D5F:0000FE7C9210D610BA109210FE1010FEFE1010101E10E0100210AA10A8108010 +4D60:0040FE409240D6FCBA849304FE041084FE4410441E44E0040204AA04A8288010 +4D61:00003FF801007FFC04401830E00E3FF8292825483FF801007FFC0100FFFE4444 +4D62:0010FE109210D67CBA109210FE1010FEFE1010381E38E0540254AA92A8108010 +4D63:0000FE0092FCD684BA849284FEFC1084FE8410841EFCE0840200AA00A9FE8000 +4D64:3FF808200820FFFE0820102020207FF8292825483FF801007FFC0100FFFE4444 +4D65:0040FE40927CD684BB0892FCFEA410A4FEA410FC1E80E0800282AA82A87E8000 +4D66:0000FE9C9248D608BA889248FE5E1008FE2810481EC8E0480248AA48A8488018 +4D67:08207F280824FFFE00207F2049246B2449247F2808287F100812FFAA0046AA82 +4D68:0048FE449240D6FEBA509254FE581052FE5410581E52E054029AAA92A92E8240 +4D69:03043C2404247FA416242504440C3FF8292825483FF801007FFC0100FFFE4444 +4D6A:0000FEFC9284D684BAFC9284FE8410FCFE0010901E92E0F40298AA92A8D2808E +4D6B:01007FFC50043EF84288A2AA1492187EE0003FF8292825483FF80100FFFE2448 +4D6C:0010FE1092DAD654BA549292FF501020FEFE10821E82E0FE0282AA82A8FE8082 +4D6D:0020FE2092FAD624BA2893FEFE201040FEFC11441E44E07C0244AA44A87C8044 +4D6E:0000FE7C9244D67CBA44927CFE0010FEFE40107E1EAAE12A024AAA92A82A8044 +4D6F:0008FE1C92E0D620BBFE9220FEFC10A4FEFC10A41EFCE02002FCAA20A9FE8000 +4D70:0040FE7E9280D77CBA44927CFE44107CFE0010FE1E40E0FE032AAA4AA8928026 +4D71:0010FE1092FED610BA7C9200FE7C1044FE7C10281EFEE000027CAA44A87C8044 +4D72:007CFE449244D67CBA0092EEFEAA10AAFEEE10101EFEE0380254AA92A9108010 +4D73:0010FE289244D6BABB0092FEFE9210D6FE9210FE1E00E07C0244AA7CA844807C +4D74:0000FEFE92AAD6AABAEE9228FEEE10AAFEAA10EE1EAAE0AA02EEAAA8A82A801E +4D75:20403F7E48909FF8149012501130FFFE08203FF8D55613901FF001007FFC2448 +4D76:200021FC21547D5445DC845075DC5554555455DC7554555405DC05502852103E +4D77:100011FC11547D5411DC1050FDDC0154115411DC7D54115411DC1D50E052403E +4D78:7C101052FE94382854449FF212901EF002803EF822883EF822883EFA028201FE +4D79:201C7DC8917EFDC828185FF092901EF002803EF822883EF822883EFA028201FE +4D7A:21F8210821F8250AF5FA250A25FA2402279E20903090EF9E4492049204920892 +4D7B:1C4414441CEE55445DEE55445DEE41447744140014FEF702557E550255FE9502 +4D7C:0440247C24A83D5004287DFE248844488FF848244FE448247FFC0440FC7C2444 +4D7D:0810FF7E08107E7C42447E282418FEE601003FF80100FFFE040008201FF00810 +4D7E:081017FE3210D15010200810FF1008FE7E1000FC7E4442487E2824101E28E0C6 +4D7F:0810FF1008FC7E1000FC7E4442287E1024281EC6E10001FC01003FF820083FF8 +4D80:0810FF7E08107E7C42047E4824381E44E10006C01830E7CE00001FF010101FF0 +4D81:0810FF7E08107E7C42447E3824447E8201187D6009183FF6D0101FF010101FF0 +4D82:2020CE208220EE7C82448284FE04008492449224DA249204DA0492049328D910 +4D83:2010CE108210EE2882288244FE4400A292109210DA7C9204DA0892089310D910 +4D84:2000CEFC8210EE1082948254FE58001093FE9210DA109210DA1092109310D910 +4D85:2020CE20823CEE4482A88210FE2800449282927CDA449244DA449244937CD944 +4D86:2028CE248240EE7E82C88348FE7E00489248927EDA489248DA48927E9340D940 +4D87:2010CE1082FEEE9282FE8292FEFE0000927C9244DA7C9244DA7C92449344D94C +4D88:2014CE1283FEEE1082FE8292FEFE009292FE9292DA0493FEDA4492249324D90C +4D89:2020CEDE828AEECA82AA82D2FEA6000092FE9292DA9292FEDA92929293FED982 +4D8A:20007CFC44247C2444247C240024FEFC9244FE449244FE440044FE4445FE8400 +4D8B:20007CFC44447C4844487C50005CFE449244FE449268FEA80090FE9845248442 +4D8C:20407C4044FC7C8445047EF40094FE9492F4FE849294FE880082FE82447E8400 +4D8D:0040FEF8208828F84488FCF8140011FC11247DFC112411FC1C00E3FE40880108 +4D8E:10103E1022283E2822443E82007C7F0049007F7C49447F440044FFC4227C4244 +4D8F:4420287C0044FC7C1444147CFC0090FE9092FEFE329232FE5A0054FE90441084 +4D90:20107C2844447CBA45007CFE0092FED69292FEFE9200FE7C0044FE7C4444847C +4D91:20207CF844207DFC45047CF800A8FEF892A8FEF89244FEFC0020FEB844A0857C +4D92:0100FFFE02847D78255025484D6420083FF820083FF822083FF8244843889C68 +4D93:2040202023FEF888A852AFACAAAAAAA8ADACA800A904B9FC210421FC21042204 +4D94:102050205C2050A0FEAC28B4AAE4D7A482A4FEB4AAA8AAA2D6A29E82E27E0200 +4D95:080028002F7C2854FF54145455546B54417C7F40554055406B424F42713E0100 +4D96:081028102F102828FF28144455446BA241107F10557C55046B084F0871100110 +4D97:0800287E2F042804FF74145455546B5441547F54557455546B044F0471140108 +4D98:082028102F1028FEFF00140455446B4441247F24552855286B084F1071FE0100 +4D99:0800287E2F402840FF40147C55446B4441447F44557C55406B404F40717E0100 +4D9A:081028102F10287CFF54145455546B54417C7F54551055146B124F7E71220100 +4D9B:7F0408441E44224454440844310CC9E009007FFC04402AA83FF824482AA83FF8 +4D9C:101050505C50507CFE502890AA10D6FE8200FE00AA7CAA44D6449E44E27C0244 +4D9D:102050205C2051FCFE2028A8AAA8D6A88374FE22AA50AA50D6889E88E3040202 +4D9E:082428242F7E2824FF24143C55246B24413C7F24552455FE6B004F2471220142 +4D9F:102050205C3C5044FE482880AA20D6CC8284FE84AACCAA84D6849E84E2FC0284 +4DA0:00283FFE20202FA420282F9048AA4FC68082010011F81100FFFE04402AA83FF8 +4DA1:100250E25CA250AAFEAA28EAAAAAD6AA82EAFEAAAAAAAAA2D6E29E02E24A02A4 +4DA2:100C500A5C0850FEFE882888AAFAD68A828AFEECAAACAAACD6EA9E8AE2960322 +4DA3:101050545C545054FE7C2800AAFED600827CFE44AA44AA7CD6449E28E2FE0200 +4DA4:1000507C5C445074FE5428FEAA82D67C8244FE7CAA44AA7CD6449E44E2540248 +4DA5:1020503C5C2050FEFEA228B8AAE4D69C8280FEBCAAA4AABCD6A49EBCE2A4037E +4DA6:102051FC5C2050FCFE2029FEAA00D6FC8284FEFCAA84AAFCD6849EFCE2480284 +4DA7:101050105C7E5010FEFE2844AAEED6448264FEDEAA00AAFED6289E28E24A0286 +4DA8:101050105C285044FE82287CAA00D6EE82AAFEAAAAEEAA44D6449EAAE2AA0312 +4DA9:102050105DFE5054FFA828ACABAAD6A883ACFE00AA84AAFCD6849EFCE2840304 +4DAA:104C51FA5C4851FEFE082868AA5AD6FA83AAFEFCAAACAAFCD6AA9EFAE2960222 +4DAB:13DE52525FDE5000FFFE2A00AAC8D64E83EAFEB2AAEAAAAAD6EA9EB4E3E4022A +4DAC:00007C7C1010FEFE1010101008407F7C1440FF7C22043E7C22403E7C2242263E +4DAD:140012FE12101010FF90147C14101510151016FE260024022C02540243FE8000 +4DAE:04400420FFFE0910116021844F0480FC00001FF001007FFC028004401830600C +4DAF:208027FC240427BCF0A056BE52A257B652AA96AA50B626A222BE57A052A2867E +4DB0:1000FF8680B8F7881408D7CE5458F6C85548D54E16F8D44857CAF40A544ACFC6 +4DB1:408047FC740497BC50A026BE52A28FB60AAA66AA10B606A282BE47A022A2067E +4DB2:104013FE12027FDE5450575E7D5257DA55565756FC5A4752455E47D055524B3E +4DB3:081008081400227E5D0080807F3855287F2800287F28552A7F2A554A55464380 +4DB4:08402A7C48941410212846C41830EFEE00003BB82AA87FFC44447FFC4444444C +4DB5:1004103E2BE0463CBA2002FCFEA4AAB8FEE4029CFE80AAB8FEA8AAAAAB2A8646 +4DB6:020003F802007FFE000011F811087DF811081DF8300057FE1090109C5150223E +4DB7:00000110791049104910491049104910491049107A104A1202120412040E0800 +4DB8:00000080788048804880492049204A204840484078884884010403FE01020000 +4DB9:000001000100210821082108210821083FF80100010002000200040008003000 +4DBA:3C102410241025FF3D112511251125293D252543258125012501450155058902 +4DBB:3C202420242025FE3D2224242420242824283C48244824882489450956078800 +4DBC:7848488449124A21784449824BFE480278204810495249414A458845A83C1000 +4DBD:3D5225222552258A3DFE2448244824873D102420247C24842548442054588984 +4DBE:000008100810681F8BA188AAEBC88888FF88081408140C1412222122C1410000 +4DBF:084808481448124828487E48A2483E4822483E482088288924892A8933072100 +4DC0:0000000000007FFC00007FFC00007FFC00007FFC00007FFC00007FFC00000000 +4DC1:0000000000007C7C00007C7C00007C7C00007C7C00007C7C00007C7C00000000 +4DC2:0000000000007C7C00007FFC00007C7C00007C7C00007C7C00007FFC00000000 +4DC3:0000000000007FFC00007C7C00007C7C00007C7C00007FFC00007C7C00000000 +4DC4:0000000000007C7C00007FFC00007C7C00007FFC00007FFC00007FFC00000000 +4DC5:0000000000007FFC00007FFC00007FFC00007C7C00007FFC00007C7C00000000 +4DC6:0000000000007C7C00007C7C00007C7C00007C7C00007FFC00007C7C00000000 +4DC7:0000000000007C7C00007FFC00007C7C00007C7C00007C7C00007C7C00000000 +4DC8:0000000000007FFC00007FFC00007C7C00007FFC00007FFC00007FFC00000000 +4DC9:0000000000007FFC00007FFC00007FFC00007C7C00007FFC00007FFC00000000 +4DCA:0000000000007C7C00007C7C00007C7C00007FFC00007FFC00007FFC00000000 +4DCB:0000000000007FFC00007FFC00007FFC00007C7C00007C7C00007C7C00000000 +4DCC:0000000000007FFC00007FFC00007FFC00007FFC00007C7C00007FFC00000000 +4DCD:0000000000007FFC00007C7C00007FFC00007FFC00007FFC00007FFC00000000 +4DCE:0000000000007C7C00007C7C00007C7C00007FFC00007C7C00007C7C00000000 +4DCF:0000000000007C7C00007C7C00007FFC00007C7C00007C7C00007C7C00000000 +4DD0:0000000000007C7C00007FFC00007FFC00007C7C00007C7C00007FFC00000000 +4DD1:0000000000007FFC00007C7C00007C7C00007FFC00007FFC00007C7C00000000 +4DD2:0000000000007C7C00007C7C00007C7C00007C7C00007FFC00007FFC00000000 +4DD3:0000000000007FFC00007FFC00007C7C00007C7C00007C7C00007C7C00000000 +4DD4:0000000000007FFC00007C7C00007FFC00007C7C00007C7C00007FFC00000000 +4DD5:0000000000007FFC00007C7C00007C7C00007FFC00007C7C00007FFC00000000 +4DD6:0000000000007FFC00007C7C00007C7C00007C7C00007C7C00007C7C00000000 +4DD7:0000000000007C7C00007C7C00007C7C00007C7C00007C7C00007FFC00000000 +4DD8:0000000000007FFC00007FFC00007FFC00007C7C00007C7C00007FFC00000000 +4DD9:0000000000007FFC00007C7C00007C7C00007FFC00007FFC00007FFC00000000 +4DDA:0000000000007FFC00007C7C00007C7C00007C7C00007C7C00007FFC00000000 +4DDB:0000000000007C7C00007FFC00007FFC00007FFC00007FFC00007C7C00000000 +4DDC:0000000000007C7C00007FFC00007C7C00007C7C00007FFC00007C7C00000000 +4DDD:0000000000007FFC00007C7C00007FFC00007FFC00007C7C00007FFC00000000 +4DDE:0000000000007C7C00007FFC00007FFC00007FFC00007C7C00007C7C00000000 +4DDF:0000000000007C7C00007C7C00007FFC00007FFC00007FFC00007C7C00000000 +4DE0:0000000000007FFC00007FFC00007FFC00007FFC00007C7C00007C7C00000000 +4DE1:0000000000007C7C00007C7C00007FFC00007FFC00007FFC00007FFC00000000 +4DE2:0000000000007FFC00007C7C00007FFC00007C7C00007C7C00007C7C00000000 +4DE3:0000000000007C7C00007C7C00007C7C00007FFC00007C7C00007FFC00000000 +4DE4:0000000000007FFC00007FFC00007C7C00007FFC00007C7C00007FFC00000000 +4DE5:0000000000007FFC00007C7C00007FFC00007C7C00007FFC00007FFC00000000 +4DE6:0000000000007C7C00007FFC00007C7C00007FFC00007C7C00007C7C00000000 +4DE7:0000000000007C7C00007C7C00007FFC00007C7C00007FFC00007C7C00000000 +4DE8:0000000000007FFC00007C7C00007C7C00007C7C00007FFC00007FFC00000000 +4DE9:0000000000007FFC00007FFC00007C7C00007C7C00007C7C00007FFC00000000 +4DEA:0000000000007C7C00007FFC00007FFC00007FFC00007FFC00007FFC00000000 +4DEB:0000000000007FFC00007FFC00007FFC00007FFC00007FFC00007C7C00000000 +4DEC:0000000000007C7C00007FFC00007FFC00007C7C00007C7C00007C7C00000000 +4DED:0000000000007C7C00007C7C00007C7C00007FFC00007FFC00007C7C00000000 +4DEE:0000000000007C7C00007FFC00007FFC00007C7C00007FFC00007C7C00000000 +4DEF:0000000000007C7C00007FFC00007C7C00007FFC00007FFC00007C7C00000000 +4DF0:0000000000007C7C00007FFC00007FFC00007FFC00007C7C00007FFC00000000 +4DF1:0000000000007FFC00007C7C00007FFC00007FFC00007FFC00007C7C00000000 +4DF2:0000000000007C7C00007C7C00007FFC00007C7C00007C7C00007FFC00000000 +4DF3:0000000000007FFC00007C7C00007C7C00007FFC00007C7C00007C7C00000000 +4DF4:0000000000007FFC00007FFC00007C7C00007FFC00007C7C00007C7C00000000 +4DF5:0000000000007C7C00007C7C00007FFC00007C7C00007FFC00007FFC00000000 +4DF6:0000000000007C7C00007C7C00007FFC00007FFC00007C7C00007FFC00000000 +4DF7:0000000000007FFC00007C7C00007FFC00007FFC00007C7C00007C7C00000000 +4DF8:0000000000007FFC00007FFC00007C7C00007FFC00007FFC00007C7C00000000 +4DF9:0000000000007C7C00007FFC00007FFC00007C7C00007FFC00007FFC00000000 +4DFA:0000000000007FFC00007FFC00007C7C00007C7C00007FFC00007C7C00000000 +4DFB:0000000000007C7C00007FFC00007C7C00007C7C00007FFC00007FFC00000000 +4DFC:0000000000007FFC00007FFC00007C7C00007C7C00007FFC00007FFC00000000 +4DFD:0000000000007C7C00007C7C00007FFC00007FFC00007C7C00007C7C00000000 +4DFE:0000000000007C7C00007FFC00007C7C00007FFC00007C7C00007FFC00000000 +4DFF:0000000000007FFC00007C7C00007FFC00007C7C00007FFC00007C7C00000000 +4E00:0000000000000000000000000000FFFE00000000000000000000000000000000 +4E01:00007FFC01000100010001000100010001000100010001000100010005000200 +4E02:0000FFFE040004000800080010001FF000100010001000100010001000A00040 +4E03:02000200020002000200023C07C0FA0002000200020002040204020401FC0000 +4E04:01000100010001000100010001000100010001000100010001000100FFFE0000 +4E05:0000FFFE01000100010001000100010001000100010001000100010001000100 +4E06:0000FFFE02000200040004000800080010002000400080000000000000000000 +4E07:00000000FFFE04000400040007F0041004100810081010101010201040A08040 +4E08:00800080008000807FFC0080108010800880048002800100028004401830E00E +4E09:000000007FFC00000000000000003FF800000000000000000000FFFE00000000 +4E0A:02000200020002000200020003F80200020002000200020002000200FFFE0000 +4E0B:0000FFFE02000200020002000240022002100208020802000200020002000200 +4E0C:0000FFFE08200820082008200820082008200820082010201020202040208020 +4E0D:00007FFC00800080010001000340052009101108210441048100010001000100 +4E0E:1000100010001FFC1000200020003FF8000800080008FFC80008000800500020 +4E0F:0000FFFE01000100210021FC2104210421043FFC000400040004000400280010 +4E10:0000FFFE01000100210021FC2100210021003FFC000400040004000400280010 +4E11:00003FF0021002100210021002103FF0041004100410041004100410FFFE0000 +4E12:00003FF8010801080908050802080308048804880808105020200000FFFE0000 +4E13:0100010001003FF802000200FFFE040008000FF0001000200640018000400020 +4E14:00001FF01010101010101FF01010101010101FF01010101010101010FFFE0000 +4E15:00007FFC0080010001000340052009103108C1040100010001000000FFFE0000 +4E16:02201220122012201220FFFE122012201220122013E01000100010001FFC0000 +4E17:111011101110111011101110FFFE11101110111011101110111011101FF01010 +4E18:001000781F8010001000100010001FFC104010401040104010401040FFFE0000 +4E19:0000FFFE0100010001007FFC4104410442844244442448244004400440144008 +4E1A:04400440044004404444244424481448145014600440044004400440FFFE0000 +4E1B:08200820082008200820082008201450125022882088410482020000FFFE0000 +4E1C:0200020002007FFC04000900110021003FF80100092011102108410405000200 +4E1D:0810081010201020224442847CF804080810102020407EFC00000000FFFE0000 +4E1E:00003FF00020004000807D0405880950092011102108410685000200FFFE0000 +4E1F:00007FFC0100010001003FF8010001000100FFFE02000400082010103FF81008 +4E20:04400440044004447C48045004600440044204421C42E43E44000000FFFE0000 +4E21:0000FFFE0100010001007FFC410449244924492449244FE44024400440144008 +4E22:001000F83F00010001003FF8010001000100FFFE02000400082010103FF81008 +4E23:0000FFFE0440044004407C7C4444444444447C7C044408400840104020404040 +4E24:0000FFFE0440044004407FFC4444444444444AA44A9451144204400440144008 +4E25:00007FFC024012480A5002403FFE200020002000200020002000400040008000 +4E26:1010082004407FFC0440044004404444244414481450044004400440FFFE0000 +4E27:010001007FFC01001110091009200100FFFE1200111010A010401430180E1000 +4E28:0100010001000100010001000100010001000100010001000100010001000100 +4E29:0040004010401040104010401040104010C013401C4010400040004000400040 +4E2A:0100010002800440082010102108C10601000100010001000100010001000100 +4E2B:0000201010200840048001000100010001000100010001000100010001000100 +4E2C:0100010001001100090009000100030005000900310001000100010001000100 +4E2D:01000100010001003FF8210821082108210821083FF821080100010001000100 +4E2E:00007FF00410041004107FD0041004100410FFD00412040A040A040604020400 +4E2F:0100010C017007807900010C017007807900010C017007807900010001000100 +4E30:0100010001007FFC0100010001003FF8010001000100FFFE0100010001000100 +4E31:04400440444444444444444444444C44547C644404400840084010402040C040 +4E32:010001003FF8210821083FF8010001007FFC410441047FFC4104010001000100 +4E33:044004403FF8244824483FF8044004407FFC444444447FFC4844104020404040 +4E34:08800880088049FE49404A204C20480049FC492449244924492409FC09040800 +4E35:0440244814500440FFFE0000082004403FF801000100FFFE0100010001000100 +4E36:0000000000000000000004000200010000800040004000000000000000000000 +4E37:0000000000000008200810100810042004400080000000000000000000000000 +4E38:02000200020002007FE0022012200A20042004200A20092211222022401E8000 +4E39:00001FF0101010101210111011101010FFFE1010101010102010201040508020 +4E3A:010021001100110001007FF80208020802880448044808081008200840508020 +4E3B:0200010000007FFC01000100010001003FF801000100010001000100FFFE0000 +4E3C:08200820082008207FFC08200A2009200820FFFE082008201020102020204020 +4E3D:0000FFFE000000003EF822882288228832C82AA82AA82288228822882AA82490 +4E3E:2208110811100020FFFE082011102108CFE6010001007FFC0100010001000100 +4E3F:0100010001000100010001000100010001000200020004000400080010002000 +4E40:000000000000080008001400140024004200010000C00030000E000000000000 +4E41:000000003F000100010001000100010001000080008000400020001000080006 +4E42:000000102010201010201020082008400440028001000280044008203018C006 +4E43:00003FF00410042004200440047C040408040804080410041004200440288010 +4E44:000000100010001000100220012000C0004000A0011022102400380020000000 +4E45:04000400040007E008200820104020404080008001400240042008103008C006 +4E46:0010081008101020102020407FC020800080014001400220042008103008C006 +4E47:002003F03E00020002000200020003FCFE000200020002040204020401FC0000 +4E48:01000100020002000440084010802080410002000420081010083FFC10040000 +4E49:020001102110201010201020082008400440028001000280044008203018C006 +4E4A:0000000801FC7E00000820081010101008200840000000000000000000000000 +4E4B:02000100010000007FF800100020004000800100020004001800240043FE0000 +4E4C:010002001FF01010101010101050102010001FFC000400047FE4000400280010 +4E4D:080008000FFE12001200220043F882000200020003FC02000200020002000200 +4E4E:001000F83F0001001110091009200100FFFE0100010001000100010005000200 +4E4F:001001F87E0000000200010001007FF8003000C003000C003000480087FE0000 +4E50:002000F01F0010001100210021003FFC01000920091011082104410405000200 +4E51:000801FC7F00010009040908119021A045408540092011102108410681000100 +4E52:002000F01F00100010001FF81080108010801080FFFE00000800100020004000 +4E53:002000F01F00100010001FF81080108010801080FFFE00000040002000100008 +4E54:001000F83F00010002007FFC044008203018C826082008200820102010202020 +4E55:000800FC3F8020802FF8208020803FFE208020802FF82888488848A888900080 +4E56:00701F8001000100FFFE0100092009247928093009221922E91E010001000100 +4E57:00F83F0001007FFC09200920FFFE092009207FFC0380054009203118C1060100 +4E58:00F83F0001007FFC01000924F93809223922CB9E054009203118C10601000100 +4E59:00007FF00020004000800100020004000800100010002004200420041FFC0000 +4E5A:100010001000100010001000100010001000100010001004100410040FFC0000 +4E5B:00000000FFFC0004000800100000000000000000000000000000000000000000 +4E5C:000000001000103010D017103810D0101010105010201002100210020FFE0000 +4E5D:04000400040004007FE0042004200420082008200820102210222022401E8000 +4E5E:080008001FFC1000200040009FE000200040018006000804100410040FFC0000 +4E5F:010001001100113011D017103910D1101110115011201102100210020FFE0000 +4E60:00007FF8000800080808040802080208006801880E0870082008000800500020 +4E61:020002000420082010403F800108020804101FE000400080010006001800E000 +4E62:082008200820082049204920492049204920492049204F2279220022001E0000 +4E63:084008401040104022404240FC4004400840104024404242FE424242003E0000 +4E64:0000FFFE02000240022002100208020000007FF0006001800600180420041FFC +4E65:000801FC7E000010101008200440008000007FF0006001800600180420041FFC +4E66:0220021002083FE00220022002200220FFFC0204020402040204022802100200 +4E67:0040044002401240084009FC7E400040004000007FF0006003801C0420041FFC +4E68:08200820102022204120FFA000A000207F20412041204122412241227F1E4100 +4E69:08200820082008200FA00820082008207F20412041204122412241227F1E4100 +4E6A:0000FDFC052405240924092411FC112421242124412441FC400240023FFE0000 +4E6B:100010007E7C124412441244227C4A4484007FF0006001800600180420041FFC +4E6C:00003FFC20003FF820083FF820003FFC00007FF0006001800600180420041FFC +4E6D:0000FFFE040008001FF02810C8100FF000007FF0006001800600180420041FFC +4E6E:0C0070FC408444845C8464944488088010807FF0006001800600180420041FFC +4E6F:00F87F0011100920FFFE01000100050002007FF0006001800600180420041FFC +4E70:00007FFC0004088804802480108010800100FFFE010002C0042008103008C004 +4E71:04400E40384008400840FF40084008403E4022402240224222423E42223E0000 +4E72:4080208009FC12042448E04020A023182C0600007FF0006003801C0420041FFC +4E73:02200F20F020012091204A200020FE20042008200F20F82248220822281E1000 +4E74:080C08F07E8008800EFE788808882908120800007FF0006003801C0420041FFC +4E75:102008207F20002022201420FFA00820082008207F20082208220822081E0800 +4E76:012001107FFC01003FF821083FF821083FF8210800003FF001C01E0420041FFC +4E77:1020082040A824A409221228703010C0170000007FF0006003801C0420041FFC +4E78:0800087C28442E643A54EAFE2A442AA42A942EFE2804282A201220021FFE0000 +4E79:08200820FFA008207F2041207F2041207F2049200820FFA208220822081E0800 +4E7A:061838E020803EFC22903E902090411080007FF0006001800600180420041FFC +4E7B:10100810FF2820443E822210220842204A1084087FF0006003801C0420041FFC +4E7C:2080104087FC4040104023F8E040204027FC20007FF0006003801C0420041FFC +4E7D:01081FD001207FFC02000FF03810CFF008100FF000003FF001C01E0420041FFC +4E7E:104010401080FEFE11007E0044FC7C0844107C201040FE801102110210FE1000 +4E7F:0F20F020112089204220102022207C2008201120FFA008A24A228922281E1000 +4E80:04000FE010403FF051101FF011101FF001003FF821083FF821083FFA010200FE +4E81:08200820FFA0087E7F4041807F7C41047F0800107F200840FFC20842083E0800 +4E82:0F20F02049202220FE2014200820FF209520BD208320BD2295228922951EA300 +4E83:082049202A20FFA02A20492088A04120412077A09120552227A24122811E0100 +4E84:0820FFA008207F200020FFA080A07F2000207F2041207F22412222220F9EF000 +4E85:0010001000100010001000100010001000100010001000100010001000500020 +4E86:00007FF800100020004001800100010001000100010001000100010005000200 +4E87:0800080008000FFC100411082110410001000100010001000100010005000200 +4E88:00001FF000100220014000807FFE008200840080008000800080008002800100 +4E89:080008001FE020204040BFF8010801087FFE010801083FF80108010005000200 +4E8A:010001007FFC111009203FF801080108FFFE010801083FF80108010005000200 +4E8B:01000100FFFE01003FF821083FF801003FF80108FFFE01083FF8010005000200 +4E8C:0000000000003FF800000000000000000000000000000000FFFE000000000000 +4E8D:00003FF80000000000000000FFFE010001000100010001000100010005000200 +4E8E:00003FF80100010001000100FFFE010001000100010001000100010005000200 +4E8F:00003FF8000000000000FFFE0400040008000FF0001000100010001000A00040 +4E90:00003FF8020002000200FFFE0400040008000FF0001000100010001000A00040 +4E91:00003FF80000000000000000FFFE0200040004000840102020107FF820080008 +4E92:00007FFC0400040004000FF008100810101010201FE0002000400040FFFE0000 +4E93:00003FF8000000000000FFFE0820082008200820082010201020202040208020 +4E94:00007FFC02000200020002003FF00410041004100410081008100810FFFE0000 +4E95:08200820082008207FFC0820082008200820FFFE082008201020102020204020 +4E96:000000003FF8000000000000FFFE0000000000003FF8000000000000FFFE0000 +4E97:010001002108210821083FF80000000000003FF80000000000000000FFFE0000 +4E98:00007FFC000000001FF0101010101FF0101010101FF0101000000000FFFE0000 +4E99:00007FFC0400040004000FF008100A10111010200420022000400040FFFE0000 +4E9A:00007FFC044004400440044044442444244814481450044004400440FFFE0000 +4E9B:04400440244427482470244224422F42F03E400000001FF0000000007FFC0000 +4E9C:00007FFC0440044004403FF824482448244824483FF8044004400440FFFE0000 +4E9D:0400082010103FF80810102024487EFC020400003FF8000000000000FFFE0000 +4E9E:00007FFC0440044004403C7820082008200820083C78044004400440FFFE0000 +4E9F:00003FF0002000400180793C49044944492849107928014405000200FFFE0000 +4EA0:020001000100FFFE000000000000000000000000000000000000000000000000 +4EA1:0200010001000000FFFE1000100010001000100010001000100010001FFC0000 +4EA2:020001000100FFFE000000000FE00820082008200820082210221022201E4000 +4EA3:020001000100FFFE042004200420042004200420042008200820102020204020 +4EA4:020001000100FFFE0000101010082024482404400280010002800C403030C00E +4EA5:0200010000007FFC02000400082010403F8801100620184060A003100C087004 +4EA6:020001000100FFFE044004402450244824484444444488440840104021404080 +4EA7:020001007FFC00000820042004403FFE20002000200020002000400040008000 +4EA8:02000100FFFE00001FF0101010101FF000003FF0006001800100010005000200 +4EA9:020001000100FFFE000000003FF82108210821083FF82108210821083FF82008 +4EAA:02000100FFFE0440145024484844094010807FE0002000200010001000080006 +4EAB:020001007FFC00001FF010101FF000001FE000400180FFFE0100010005000200 +4EAC:02000100FFFE000000001FF01010101010101FF0010011101108210445040200 +4EAD:020001007FFC00001FF010101FF000007FFE40029FF401000100010005000200 +4EAE:020001007FFC00000FE008200FE000007FFE400287C40440044008423042C03E +4EAF:02000100FFFE00001FF010101FF000003FF8200820083FF8200820083FF82008 +4EB0:02000100FFFE000000001FF010101FF010101FF0010011101108210445040200 +4EB1:02000100FFFE0800080013F81208320853F89208120813F81208100017FC1000 +4EB2:020001003FF8000008200440FFFE010001007FFC010009201110210845040200 +4EB3:01007FFC00001FF010101FF000007FFE400280F43F00020003F87E02020201FE +4EB4:01007FFC00001FF010101FF000007FFE41029FF401007FFC02003FE00822701E +4EB5:0100FFFE000008407DF808480CC8784A08AA2906130204880C503530C60E0400 +4EB6:0100FFFE00003FF8200827C824483FF800001FF010101FF010101FF00000FFFE +4EB7:010000803FFC041002203FFE22402FF822483FFE22482FF826604A50524C8240 +4EB8:20881048FC5001FC7D2445247DFC01247D2409FC10201C20F3FE102050202020 +4EB9:0100FFFE00002FEC48246BAC48246BAC4AA4FFFE90121FF010101FF01010FFFE +4EBA:0100010001000100010001000280028004400440082008201010200840048002 +4EBB:0800080008001000100030003000500090001000100010001000100010001000 +4EBC:01000100010001000280028004400440082010102008C00600000000FFFE0000 +4EBD:010001000100028002800440082010102008C006020001000080008000000000 +4EBE:008000800080208020802140214022202220241028083006200020003FFE0000 +4EBF:080008000BFC1008101030203040508090801100110012021202120211FE1000 +4EC0:08200820082010201020302037FE502090201020102010201020102010201020 +4EC1:08000800080013FC1000300030005000900010001000100017FE100010001000 +4EC2:084008400840104013FC30443044504490441084108410841104110412281410 +4EC3:080008000BFE1020102030203020502090201020102010201020102010A01040 +4EC4:00003FFE20002000208020802080208020802140214022204220441088081006 +4EC5:08000BFC09041104110430883088508890501050102010201050108811041602 +4EC6:0840084008401040104030503048504490441040104010401040104010401040 +4EC7:090009000900110017F0311031105110911011101110121212121412180E1000 +4EC8:0800082009201120112031203120512091201110111012101208140818041002 +4EC9:080009F0091011101110311031105110911011101110111211121212120E1400 +4ECA:0100010002800440082012102108C10600001FF0001000200020004000800100 +4ECB:0100010002800440082010102008C82608200820082008201020102020204020 +4ECC:010001000280024004200810110861040100028002800440082010102008C006 +4ECD:080008000BF810881090309030A050BC90841084110411041104120412281410 +4ECE:0820082008200820082008200820082008501450125012882088210442048402 +4ECF:08400840084010401040308030805080910011101108120817FC120410041000 +4ED0:0100010002800440082010102108C10601000100FFFE01000100010001000100 +4ED1:0100010002800440082010102008C806083008C00F0008080808080807F80000 +4ED2:0100010002800440082010102008C6060180004000000C00030000C000200000 +4ED3:010001000280044008203018C0060FE00820082008A008440804080407FC0000 +4ED4:08000BF80808101010203040304057FE90401040104010401040104011401080 +4ED5:084008400840104010403FFE304050409040104010401040104017FC10001000 +4ED6:084008400A401258126832C833485E4892481248125812421202120211FE1000 +4ED7:081008100810101013FE30103010511091101090109010501020105011881606 +4ED8:081008100810101017FE30103010501091101090109010101010101010501020 +4ED9:1040104010402040244464446444A4442444244424442444244427FC20042000 +4EDA:0100010002800440082010102108C1060100210821082108210821083FF80008 +4EDB:081008780BC01040104030403040507E97C010401040104210421042103E1000 +4EDC:08000800080013FE10203020302050209020102010201020102017FE10001000 +4EDD:0100010002800440082010102008C0061FF0010001000100010001007FFC0000 +4EDE:080008000BFC1044104432443244524494841084108411041104120414281810 +4EDF:081008780BC0104010403040304057FE90401040104010401040104010401040 +4EE0:08000BFC084010401040304030405FFE90401040104010401040104010401040 +4EE1:08800880090011FE1200340031F8500890101060108011001202120211FE1000 +4EE2:08800880090011FC120432043404590490841044104410041004100410281010 +4EE3:089008880888108010BE37C03080504090401040102010221012100A10061002 +4EE4:01000100028004400A2011102108C0061FF00010002004400280010000800080 +4EE5:0010041022102110211020102010202020202020244028503088210402020402 +4EE6:0820082008201020102031283124512492221222122214221020102010A01040 +4EE7:02000200020003F8020002000200FFFE0100010001000280044008203018C006 +4EE8:080008000BFC100010003000300051F89000100010001000100017FE10001000 +4EE9:084008400840104010403040307C504090401040104010401040104017FE1000 +4EEA:088008480A481208120831103110511090A010A01040104010A0111012081406 +4EEB:084008400880108011003110321054209020104010801108120417FE12021000 +4EEC:0900088008BC1204120432043204520492041204120412041204120412141208 +4EED:080008000BF81088108832883188508890C810A81098110E1108120814501820 +4EEE:0808083C0BC012001200320033F8528892881288125012501220145014881906 +4EEF:0840084008401148114432423242544890481048101010101020104011801600 +4EF0:080008800B3C122412243224322452249224122412B413281220102010201020 +4EF1:0840084008A010A01110328834465040900013F8100810101010102010201040 +4EF2:084008400840104017FC3444344454449444144417FC14441040104010401040 +4EF3:08200A200A2012221222322433A85230922012201220122212A21322121E1000 +4EF4:080009FC09041104110431FC31045104910411FC110411041204120414141808 +4EF5:11001100110023F8224062406440A04020402FFE204020402040204020402040 +4EF6:082008200920112011FC322032205420902017FE102010201020102010201020 +4EF7:0840084008A010A0111032083406511091101110111011101110121012101410 +4EF8:081008780FC0104010403040304057FE904010A010A011101110120814041802 +4EF9:08400840084017FC10403040304053FC9040104010401FFE1040104010401040 +4EFA:01000280044008203018C0061FF01000100010001FF01000100010001FF80000 +4EFB:081008780BC010401040304030405FFE90401040104010401040104017FC1000 +4EFC:080008000BFE1020102030203020502091FC1020102010201020102017FE1000 +4EFD:081008900890108811083104320455FA90881088108810881108110812281410 +4EFE:08000FFE08801080108030F8310851089108120813F810101010101017FE1000 +4EFF:08800840084017FE11003100310051F891081108110811081208120814501820 +4F00:082009200920111011103248324854449882108011101108120817FC12041000 +4F01:010001000280044008203118C1060100110011F81100110011001100FFFE0000 +4F02:1040104010402FFE2040604067FCA44424442444244424542448204020402040 +4F03:08000BF80808111010A0304037FE504290441040104010401040104011401080 +4F04:08000BFC08441044104433FC32405240944017FE10421042104A104410401040 +4F05:08400840084017FC1040324832485248924813F81048104010421042103E1000 +4F06:09000900090011FC12A434A430A4512491241244144410841104120414281010 +4F07:080009F0091011101110320E340053F891081110109010A0104010A013181C06 +4F08:0800088008401020112031003100550495021502150219081108110810F81000 +4F09:08800840084013FC1000300031F05110911011101110111211121212120E1400 +4F0A:08000BF808881088108837FE30885088908813F8108810801100110012001400 +4F0B:100017F81108211021106120613CA10421042288228822502420245028882306 +4F0C:08000BFE0A00120012F8328832885288928812A81290128214821482187E1000 +4F0D:08000BFC084010401040304033F8508890881088108811081108110817FE1000 +4F0E:08400840084017FE10403040304057F892081208111010A0104010A011181606 +4F0F:0840085008481048104037FE3040504090A010A010A011101110120814041802 +4F10:089008880888108010BE37C03080504490441048103010221052118A16061002 +4F11:084008400840104017FE304030E050E091501150124814441842104010401040 +4F12:0808081C09E011001100310031FE511091101110111011101110121012101410 +4F13:080008000BFE102010203040304050D091481244144410401040104010401040 +4F14:080008000BFE12021404300031F05110911011101110111212121212140E1800 +4F15:08400840084013FC10403040304057FE904010A010A011101110120814041802 +4F16:088008800880108017FE3080310051FC91441244124814501420185010881306 +4F17:0100010002800440082010102828C82608200820082014501250228841048202 +4F18:089008880888108017FE30A030A050A090A010A01120112211221222121E1400 +4F19:08400840084010401244324432485450904010A010A011101110120814041802 +4F1A:010001000280044008203018CFE6000000007FFC02000400082010103FF81008 +4F1B:08000BFC0A001208128832503250522092201250125012881308120013FE1000 +4F1C:088008800BF01090109031123112524E944010401FFE10401040104010401040 +4F1D:080008000BFC10001000300037FE50409040108010801108120417FE12021000 +4F1E:010001000280044008203018C1061110091009200100FFFE0100010001000100 +4F1F:08400840084017FE1040304033FC5040904017FE10421042104A104410401040 +4F20:08400840084013F81040308037FE5080910013F81008111010A0104010201020 +4F21:08400840084017FE108030A0312053FC90201020102017FE1020102010201020 +4F22:08000BFC0810111011103110321053FE90301050109011101210141010501020 +4F23:08000BF80A0812081248324832485248924812A812A81120112012221422181E +4F24:08800880090011FE12003440304053FC90441044108410841104110412281410 +4F25:090009080908111011203140310057FE91401120112011101108114411821100 +4F26:0840084008A010A0111032083406511091201140118011001104110410FC1000 +4F27:0840084008A01110120834043BF2521092101210125012201204120411FC1000 +4F28:0900090009FC1204120435043884508490141024104413841104100410281010 +4F29:08800840084017FC1110311031105110911010A010A0104010A0111012081C06 +4F2A:08400A4009401140104037FC30445044908410A4109411141104120414281810 +4F2B:084008200820100013FE3202340450009000100010001000100013FE10001000 +4F2C:080009FC090411041104310431FC512491201120111011101208120814041802 +4F2D:08800840084017FE104030803108521097E0104010801108120417FE12021000 +4F2E:12001200127C22242FA464A464A4A4A824A82928251022102528294830842102 +4F2F:08400840088013FC120432043204520493FC1204120412041204120413FC1204 +4F30:084008400840104017FE30403040504093F81208120812081208120813F81208 +4F31:0840084008A010A0111032083446504091501148124812441444104011401080 +4F32:08000BFC0A041204120433FC32005240924412481270124014421442183E1000 +4F33:08480A480A481248124837FE3248524892481248127812001200120013FE1000 +4F34:08400A4409481150104037FC3040504090401FFE104010401040104010401040 +4F35:1000100017FC24A424A464A464A4A4A424A42524251C26042404240427FC2404 +4F36:0840084008A010A0111032483426502093F810081010111010A0104010201020 +4F37:104010401040204027FC64446444A444244427FC244424442444244427FC2404 +4F38:08400840084017FC14443444344457FC94441444144417FC1444104010401040 +4F39:080009F809081108110831F831085108910811F8110811081108110817FE1000 +4F3A:08000BFC0804100417F43004300453E492241224122413E41004100410141008 +4F3B:08000BF808401040124831483150504097FE1040104010401040104010401040 +4F3C:1008110810882448244864086408A40824102410241025282624244420822102 +4F3D:140014001400243C2FA464A464A4A4A424A424A424A424A428A428BC32A42100 +4F3E:08000BFC082010201040304030D0514892441444104010401040100017FE1000 +4F3F:080008000BFC1204120432043204520493FC1204100010901088110412021402 +4F40:08000BF80A0812081208320833F85200920013FC120412041204120413FC1204 +4F41:08400840088010801110320837FC5004900013F8120812081208120813F81208 +4F42:080008000BFE10201020302031205120913C1120112011201120112017FE1000 +4F43:1000100017FC2444244464446444A7FC2444244424442444244427FC24042000 +4F44:090809080908110817FE310831085108910811F8110811081108110811F81108 +4F45:08400840084013FC10403040304057FE90E01150115012481444184210401040 +4F46:080008000BFC12041204320433FC52049204120413FC12041000100017FE1000 +4F47:08400820082013FE120234043000500093FE1020102010201020102010A01040 +4F48:08400840084017FE108030A0312051FC93241524112411241134112810201020 +4F49:084008400840104013FC30403040504097FE1040108010801110120817FC1204 +4F4A:08200820082013FE12223224322053FC92841288124812501220145014881906 +4F4B:08000BFC088410841084310431145208940011FC110411041104110411FC1104 +4F4C:1120112011202522252265E46528A530252025202520252225E23E22281E2000 +4F4D:088008400840100017FC3000300852089208111011101110112010201FFE1000 +4F4E:0808083C0BE0122012203220322053FE9220121012101212120A128A13261212 +4F4F:08800840080017FC104030403040504097FC104010401040104010401FFE1000 +4F50:088008800880108017FE30803100510091FC1220122014201420182013FE1000 +4F51:084008400840104017FE30803080510093FC1504190411041104110411FC1104 +4F52:08400840084013F81248324832485248924817FE104010A010A0111012081406 +4F53:084008400840104017FC304030E050E091501150124815F41842104010401040 +4F54:084008400840107E104030403040504093FC1204120412041204120413FC1204 +4F55:0800080017FE1008200833C8524892481248124813C812481008100810281010 +4F56:1000108010402028212861086110A51425222522254229882108230824F82800 +4F57:08400820082013FE12023404310051089110112011C011021102110210FE1000 +4F58:010001000280044008203018CFE6000000007FFC010011101108210445040200 +4F59:0100010002800440082010102FE8C10601003FF8010011101108210445040200 +4F5A:104010401240224023FC62406440A0402FFE204020A020A02110220824042802 +4F5B:1120112011202FFC2124612467FCA52029202FFE21222122222A222424202820 +4F5C:09000900090011FE12803280348050F890801080108010FC1080108010801080 +4F5D:11001100120023FC2404680463E4A22422242224222423E42224200420282010 +4F5E:100013F8100020002FFE60806080AFFE21082210261021A02060209023082C04 +4F5F:0880088008F81108131034A0304050A093181C0610C010201010118010601010 +4F60:08800880088011FE110232043420502091281124122412221422102010A01040 +4F61:1040104010A020A0211062086444A84220402444244424442444244427FC2004 +4F62:08000BFE0A001200120033FC320452049204120413FC12001200120013FE1000 +4F63:100017FC14442444244467FC6444A444244427FC244424442444284428543008 +4F64:080008000FFC1100110031F0311051109190125012501210121212921312120E +4F65:0100010002800440082010102FE8C0060210111009100920082000407FFC0000 +4F66:080008000FFE104010403080308051F893081508190811081108110811F81108 +4F67:084008400840107C10403040304057FE90401040105010481044104010401040 +4F68:0880088009FC1104120435F431145114911411F4110411281112110210FE1000 +4F69:100017FC1404240425F464446444A5F425542554255425542574244624462842 +4F6A:080008000BFC1204120432F4329452949294129412F41204120413FC12041000 +4F6B:0880088009F81208151030A0304050A093181C0613F812081208120813F81208 +4F6C:08400840084413F41048305037FE504090801184129814E018821082107E1000 +4F6D:0900090009F8131014A0304031B0564E904013FC1040144017FE104010401040 +4F6E:0840084008A011101208340633F85000900013F8120812081208120813F81208 +4F6F:0A0809080910100017FC3040304053F89040104017FE10401040104010401040 +4F70:08000BFE08201020104031FC31045104910411FC110411041104110411FC1104 +4F71:010001000280044008201010EFEE000000007FFC0100010011F811001100FFFE +4F72:0880088008FC1104128834503020504091FC13041D0411041104110411FC1104 +4F73:084008400BFC1040104030403FFE50009040104013FC1040104010401FFE1000 +4F74:08000BFE09081108110831F83108510891F811081108111E17E8100810081008 +4F75:090408840888100013FE308830885088908817FE108810881108110812081408 +4F76:0840084008401FFE1040304037FC5000900013F8120812081208120813F81208 +4F77:08000BF80A08120813F83208320853F892441248123012201210128813061200 +4F78:081008780BC01040104037FE30405040904013F8120812081208120813F81208 +4F79:1100110013F8220824106BFE6200A2F82288228822A8229022822482247E2800 +4F7A:0840084008A011101208340633F850409040104013F810401040104017FE1000 +4F7B:089008900890149212943098309051989294149210901090111211121212140E +4F7C:10801040104027FC200061106208A4042110211020A0204020A0211022082C06 +4F7D:102010201420227E224260846010A11021102E10222822282248224420842102 +4F7E:081009100908120814043BFA3208520893F81208120813F81208120812281210 +4F7F:104010401FFE2040204067FC6444A44427FC2040224021402080214022302C0E +4F80:10041FC414842494249464946494AFD424942494249424942484288428943088 +4F81:10401240124023FC244068406040A7FE212021202120212022222222241E2800 +4F82:084008200BFE12001200320C32F052209220123E13E0122014221422181E1000 +4F83:100017FC14042404240467FC6000A2482248224822482248224A244A244A2806 +4F84:100017FE104020802110620867FCA0442040204027FC2040204020402FFE2000 +4F85:08400820082017FE10403084310853F090221044118816101020105011881604 +4F86:0100010001007FFC010011101110292845440380054009203118C10601000100 +4F87:1040104017FE204027FC604463FCA240244027FE204220AA20A4211022082C06 +4F88:1080108011F82210252060C06090A3202C7C2084210826902060204021802E00 +4F89:1040104017FC20A0211062086DF6A00027FC2080210023F82008200820502020 +4F8A:084008440A4411481150304037FE5090909010901090109211121112120E1400 +4F8B:1004100417C42214221463D46254A45426542554289420942104220424142808 +4F8C:01000280044009203098CFE6004000803FF800000000FFFE082010103FF80008 +4F8D:08400840084013FC1040304037FE5010901017FE101012101110111010501020 +4F8E:084008400A4811481150304037FE504090E01150115012481444184210401040 +4F8F:08400A400A4013FC14403040304057FE90E01150115012481444184210401040 +4F90:084008400880110013FC3294329452949294129412941294129412941FFE1000 +4F91:084008400FFE1080110031FC3304550499FC1104110411FC1104110411141108 +4F92:08400820082013FE12023444304053FE90881088110810D01020105010881304 +4F93:084008400BF8104817FE304833F85040904017FC104010401FFE104010401040 +4F94:084008400890110813FC30243120512091FC1220102017FE1020102010201020 +4F95:100017FC10402040208067FC64A4A4A424A424A424A424A424A4248424142408 +4F96:010002800440082037D8C00600003FF82488248824883FF82488248824A82010 +4F97:100017FC1404240425F464046404A5F425142514251425F42404240424142408 +4F98:08400820082013FE12023404303853C090401040107E17C0104010421042103E +4F99:082808240824102017FE3020302057E0912011101110111011CA170A12061002 +4F9A:08800880090011FC1204340433E45224922413E41224122413E4100410281010 +4F9B:091009100910111013FC311031105110911017FE100011101108120814041804 +4F9C:088009000BF812081288324832485FFE92081288124812481208120814281810 +4F9D:08800840084017FE108030803140514493481530192011101108114411821100 +4F9E:090009000900111E17D232523252525292521492129211121292125E14521800 +4F9F:08400840084017FE10803080317C51089310151011FE11101110111011501120 +4FA0:08400840084017FC10403248315050409FFE10A010A011101110120814041802 +4FA1:100017FE10A020A020A067FC64A4A4A424A424A424A424A424A427FC24042000 +4FA2:08000FFC0840104013F83248324853F8924812481FFE12081208120812281210 +4FA3:100013F8120822082208620863F8A000200027FC240424042404240427FC2404 +4FA4:088008880BE8109010A037FE3080510093FC1480190011F81008100810501020 +4FA5:0880088008BC13C01050302430D4530C900017FE1090109011121112120E1400 +4FA6:08400840087E1040104033F832085248924812481248124810A0111012081404 +4FA7:100417C414442454255465546554A55425542554255421042284224424142808 +4FA8:081008780BC01040104037FE30A0511092081516111011101110121012101410 +4FA9:0840084008A011101208340631F05000900017FC104010801110120817FC1204 +4FAA:088008400FFE1208111030A0304051B0960E1110111011101110121012101410 +4FAB:088008401FFE12001200320033FC508090801FFE110812081390106011981604 +4FAC:10401040104027FC248468886140A14423482530292021102108214421822100 +4FAD:08000BF80A08120813F8322032205210920814C61420180011C0103010081000 +4FAE:0900090009FC120015F831083148512897FE11081248122813FC100810501020 +4FAF:08000BF80808100817FE3100310053F8944010401FFE104010A0111012081C06 +4FB0:08000BF80888108817FE3088308853F89100110013F815081908110811F81108 +4FB1:08000BF80A081208120833F83000500097FC1040104013F8104010401FFE1000 +4FB2:08000BFC0A00120012F83200320053FC92A012A412A812901290148814A418C2 +4FB3:084008400A4812481248355438E25040904017FC10401040104010401FFE1000 +4FB4:01000280044008203018CFE600003F04092409243F241124112417A47804200C +4FB5:08000BF8080811F8100833F8300057FC940413F01110111010A0104011B0160E +4FB6:080009F8090811081108310831F85040908013FC120412041204120413FC1204 +4FB7:08000BF80A08120813F83200320053FC920412F41294129414F4140418281010 +4FB8:08000FFC0800100013F8320832085208920813F810001208110811101FFE1000 +4FB9:1000100C1770211021106210627CA710211025102510227C2200250028FE3000 +4FBA:08400A480A48124813F8304030A0511092881446104013F01010102010201040 +4FBB:0A0809080910102013F832083208520893F810A010A0112011221222141E1800 +4FBC:082008200BFE1020102033FE3202540491F81010102013FE1020102010A01040 +4FBD:0BF80A480A4813F81248324833F85080908017FC108411041104120414281810 +4FBE:084008440BF41048104837FE3020504093F81110122015FE1820102010A01040 +4FBF:100017FE104027FC2444644467FCA444244427FC224021402080214022302C0E +4FC0:0808083C0BC01044122431283100504093FE1088110813901060105011881604 +4FC1:080008F80888108812F83200320053FC9044104417FE104010A0111012081406 +4FC2:0804081E0BE01080110833F030205048918417FE102211281124122214A21040 +4FC3:08000BF80A0812081208320833F8504090401240127C12401240154018FE1000 +4FC4:102811A41724212021206FFE6120A12421A423282D2821102112212A25462282 +4FC5:085008480848104017FE304032445164916810D0115012481444104211401080 +4FC6:0840084008A01110120835F63040504097FC1040125012481444184411401080 +4FC7:08000C400ABE110812883488308850BE918812881488108810881088153E1200 +4FC8:08400A400A4013FC14403840304057FE9000100013F812081208120813F81208 +4FC9:08000FFC0880108013F83108310857FE9000100013F812081208120813F81208 +4FCA:084008400888110413FE300230885144924210F8118812501020105011881606 +4FCB:08000BF80A08120813F8300037FC54449444144417FC14001402140213FE1000 +4FCC:1048104417FE2040204067FC6444A44427FC2444244427FC2444244424542408 +4FCD:088008400BF81208120833F83208520893F81240124412281210128813061200 +4FCE:100011F811082908250845F891081108110811F8290825084508810807FE0000 +4FCF:08400A4809481150104033F83208520893F81208120813F81208120812281210 +4FD0:108411C417042114211461146FD4A11423142394255425042904210421142108 +4FD1:100017F8101021A0204067FC6444A44427FC2444244427FC2444244424542408 +4FD2:084008200BFE1202140431F83000500093FE10901090109011121112120E1400 +4FD3:08000BFC080011241248349032485124900013FC104010401040104017FE1000 +4FD4:08000BF80A08120813F83208320853F89208120813F81120112012221422181E +4FD5:1080104017FE2402284460406040A7FC20E02150215022482444284220402040 +4FD6:100017FC1020204020D061486644A040200023F8220822082208220823F82208 +4FD7:091009080A041444104030A0311052089C0613F8120812081208120813F81208 +4FD8:0808083C0BC0100412443128300053F89010102017FE10201020102010A01040 +4FD9:1208111010E02110220860806FFEA140224027FC2A4422442254224820402040 +4FDA:100017FC1444244427FC64446444A7FC2040204027FC2040204020402FFE2000 +4FDB:0900090009F01210122037FC3A445244924413FC12A410A0112012221422181E +4FDC:1040104017FC244427FC644467FCA0003FFE2100220023FC2004200420282010 +4FDD:08000BF80A081208120833F83040504097FC10E0115012481444184210401040 +4FDE:01000280044008203018CFE600003E0822483E4822483E48224822082A282410 +4FDF:104010801110220827FC61046100A3F8244020402FFE204020A0211022082C06 +4FE0:08400840084017FE1040324832485248955418A210A011101110120814041802 +4FE1:084008200BFE1000100031FC3000500091FC1000100011FC1104110411FC1104 +4FE2:0880088009F8131014A0304031B05E4E90801320104411881610102010C01700 +4FE3:08000BF80A08120813F83000300057FC904010401FFE104010A0111012081406 +4FE4:09080888089013FC1024302433FC5220922013FE106210A2112A122414201020 +4FE5:104010401FFE204027FC64446444A7FC2444244427FC20403FFE204020402040 +4FE6:1040104017FC204023F8608067FEA090211021FE221022902450281020502020 +4FE7:08200820082013FE10203020302051FC9040102010A41282128A128A14781000 +4FE8:08000BFC089012941198309033FE520092001200120012001200140014001800 +4FE9:10001FFE1120212021206FFC6924A92429242AA42A542C4C2884280428142808 +4FEA:10001FFE1000200027BC64A464A4A4A426B425AC24A424A424A424A424A425AC +4FEB:08400840084017FC10403248314851509FFE10E0115011501248144418421040 +4FEC:108811C81F08210821086FD06110A3102390255425642922217E212221022100 +4FED:0840084008A010A01110320835F6500090881048124811501110102017FE1000 +4FEE:1080108011F821082A906C60A9982E2628C02B10282028C82B10206021802600 +4FEF:1040102017FE2400248864886508A57E27082548252825282908290831282110 +4FF0:100011801700211E21126FD26112A3122392235225522512291E211221002100 +4FF1:08000BF80A08120813F8320833F8520893F8120812081FFE1000111012081404 +4FF2:12101110111027D0203E62926252A452289222922112211222A224A2284A2084 +4FF3:089008900890179E109030903090539C909010901090179E1090109010901090 +4FF4:10A0109010BC27C8205060646194AE0C20A0209020BC27C82050206421942E0C +4FF5:1040104017FC2040204063F86040A0402FFE2088215023202510294821862100 +4FF6:0900090009DC11141114311437D4501491141114158815481948111415141222 +4FF7:100017BE14AA24AA24AA67AA64AAA4AA24BE27A024A024A024A228A22AA2311E +4FF8:084008400FFC104013F8308037FC51109248144611F0104017FC104010401040 +4FF9:08000FFE089010901090339C320452049204139C109010901090109017FE1000 +4FFA:084008800BFC11101248344633F85248924813F81248124813F810421042103E +4FFB:0880088009F81208151030E033185C0693F81248124813F81248124813F81208 +4FFC:088008400FFE1100120837FC300453F8920813F8120813F81208120812281210 +4FFD:101010901710243E242264446790A51025102510252825282528294429443082 +4FFE:084008800BFC1224122433FC3224524493FC1090111017FE1010101010101010 +4FFF:08400840087C104013FC3244327053C09244123C120012F0149014921912120E +5000:080009FC090011F8110031F831005FFE92801248125012201210128813061200 +5001:09000900090013DE129234923092509293F2109210921152115E122014201800 +5002:08840884090813DE110831083108510897BE1108110811081108120812081408 +5003:1110111013D8225424526A906110A2FE2C00200023F822082208220823F82208 +5004:09080890086011981644304037FE508091FC130415FC110411FC110411141108 +5005:088008400BFC10001110311032A854449000104017FE10401040104010401040 +5006:100017FC1040204027FC64446444A6642554255426EC24CC2444244424542408 +5007:1080104017FE24022A04620063BCA4A424A426A429342128222222222422281E +5008:08400840084017FC1040324832485248955410E0115011501248144418421040 +5009:0100028004400A203118DFF610101FF010101FF010002FF8280848088FF80808 +500A:089008900908114812443492310853FC9044102010A41282128A128A14781000 +500B:100017FC1444244427FC64446444A5F425142514251425F42514240427FC2404 +500C:084008200BFE1202140431F83108510891F81100110011FC1104110411FC1104 +500D:088008400BFC100012083108311057FE9000100013FC12041204120413FC1204 +500E:08900890089013FC12943294329453FC92941294129417FE1000109011081204 +500F:1080108011F821082A906C60A9982E46285028482BFC284028A0211022082404 +5010:0840084010FC10883550542094D81706142014A414A415281450104810841302 +5011:100017BC14A424A427BC64A464A4A7BC24042404240424042404240424142408 +5012:100410041FC422142214649467D4A114211427D42114211421C42E0424142008 +5013:08400A440A44144810A0311036085044904012481248145010A0111012081C06 +5014:100017FC1404240427FC64206524A524252425FC242025242524292429FC3004 +5015:081008780BC01040104037FC324852489FFE1248124817FC1040104017FC1000 +5016:084008400FFC1040104037FE311050A097FC104010401FFE1040104010401040 +5017:100017BC14A424A424A467BC64A4A4A424A427BC24A424A424A424A42AA4314C +5018:1040124811482150204067FC6404A40425F425142514251425F4240424142408 +5019:100013F8100828082FFE69006900ABF82C4028402FFE284028A0211022082C06 +501A:084008400BFC10A01110320837FE500893C812481248124813C8100810281010 +501B:090809080FFE1108110831F83108510891F81108110817FE1000109011081204 +501C:100017FC1444244425F464446444A7FC240425F42514251425F4240424142808 +501D:08100810FF9008107F1041107F1041107F1049100828FFA80848084408840902 +501E:088008400FFE1000100033F83208520893F81040125012481444184411401080 +501F:09100910091017FC111031103FFE500093F81208120813F81208120813F81208 +5020:09400920092013FE122036203BFC5220922013FC12201220122013FE12001200 +5021:09F80908090811F81108310831F8500093FC1204120413FC1204120413FC1204 +5022:1040104017FE204023F8604867FEA04823F820402240227C2240254024FE2800 +5023:1410121012102FA0243E644467A4A4A424A824A8249024902AA8292830442082 +5024:082008200BFE104011FC3504350455FC950415FC1504150415FC140017FE1000 +5025:08400820082013FE1202349431085204900011FC102010201020102017FE1000 +5026:10401248115027FC208061006FFEA21024082BF43212221022502224220421FC +5027:1080104017FE2402280463F06000A00027FC2040225022482444284421402080 +5028:08000BFC0A04120413FC3220322053FE9220122012FC12841284148414FC1884 +5029:084008400FFC104013F8304037FE500093F8120813F8120813F8120812281210 +502A:080008400B9C12041204339C3204520493FC109010901090109011121212140E +502B:1040104010A0211022086DF66000A7FC24A424A427FC24A424A424A424142408 +502C:08400840087E104013FC320433FC520493FC1244104017FE1040104010401040 +502D:08380BC00840104017FC315032485486908017FC1110121011A0106010901308 +502E:08000BF80A48124813F83248324853F8904017FC10E011501248144610401040 +502F:12081228122822282FA462446254A69227102AA02A203228224422FC22442200 +5030:1040104017FC204020406FFE6208A484288221F82208251020A0204021B02E0E +5031:100017FC1404240427FC64046404A7FC20002420242227AC2430242225A2261E +5032:104010401FFE2040204067FC6444A7FC244427FC24E421502248244438422040 +5033:104010401FFE204027FC644467FCA04027FC20443FFE204427FC204021402080 +5034:084008400FFE10A01150324835F650409150111017FE11101110111012101410 +5035:081008180BD41014101037FE30105090909012D012901290128A12EA17061202 +5036:08000BFC0A04120413FC320433FC5204920413FC100017FE1000110812041402 +5037:084008400FFC10A01110320835F65000900017FC104012481244144411401080 +5038:0808083C0BC01044122431283100502093FE107010A810A81124122214201020 +5039:0840084008A01110120835F63040504093F81248124813F810A0111012081406 +503A:084008400FFC104013F8304037FE500093F8120812481248124810A011101608 +503B:10001FDE14922492249467946498A49427922492249225DA2E94209020902090 +503C:084008400FFC1040104033F8320853F8920813F8120813F8120812081FFE1000 +503D:0840084008A01110120835F63040504097FC1040104013F81208120813F81208 +503E:100010FE14102420247C64446754A45424542454255426542420202820442082 +503F:088008400BFC10001108309037FE5040904017FE108811081090106011981604 +5040:1110111017FC21102150604063F8A248224822482FFE204020A0211022082406 +5041:103E17C0108424442208604067FCA444244427FC244424443FFE240424142408 +5042:09080888089017FE100033C43254525493D41254125413D412541244125412C8 +5043:08000BFE0A0012FC128432FC328452FC922013FE124812C812301248128413FE +5044:100017FC1040208027FC64A464A4A4A42484244C20402FFE20A0211022082C06 +5045:1008103C17C020402FFE604067FCA44427FC244427FC204027FC20402FFE2000 +5046:1040104017FC204023F860806FFEA110220827FC2A0A220823F82208220823F8 +5047:100017BC14842484248467BC6400A40027BC2424242427A82410242824442482 +5048:08000BF80A0813F8120833F8310053FC9444124412A4120413F4100410281010 +5049:088008800BF8110817FE300033F8520893F8104017FC1040144017FE10401040 +504A:0804081E0BE0102011FC3124312451FC902013FE1222122A12FA1202120A1204 +504B:08000BFC0A04120413FC32003284524892FC1248124813FE1448144818881108 +504C:1108110817FE21082148604067FEA080210023FC250429042104210421FC2104 +504D:08000BF80A08120813F83208320853F8900017FE1040124012781240154018FE +504E:08000BF80A48124813F83248324853F8900017FE124012441228129013081206 +504F:1080104017FC2404240467FC6400A40027FC26A42AA42BFC2AA42AA432A4220C +5050:084008200BFC10001108309033FE5210922012C81210122412C8141014601980 +5051:20002FF8280848684B884888C8884BE84AA84AA84BE8488A48AA50EA57266002 +5052:08000BF80A0813F8120833F830005FFE920013FC149419241244148411281210 +5053:08000BFC0A04120413FC320033FC5240928813FC1224122015FC1420182013FE +5054:08000BDE0A52125213DE300031FC500097FE1080110011FC1004100410281010 +5055:0A200A240BA8123012A23322325E508093FC1204120413FC1204120413FC1204 +5056:084008440BF41048105037FE3040508091F81308150811F81108110811F81108 +5057:0820082009241122122A303030C0570091FC110411FC110411FC110411FC1104 +5058:08000BF80A0812081208320833F85000900017BC14A414A414A414A417BC14A4 +5059:088008400BFC10001108309037FE5442984413FC124412441254124810401040 +505A:1210121012102FA0223E62446224AFA428A428A828A828902FA8282820442082 +505B:1008103C17C0204020406FFE6040A140265C24442444275C2444244427FC2404 +505C:1080104017FC200023F8620863F8A0002FFE280223F820402040204021402080 +505D:089008920F9C10901192368E300053FC920413FC120413FC1204120412141208 +505E:08900A900A9017FE1290329032F0520093FC104017FE10E0115012481C461040 +505F:084008800BF8120813F8320833F8500097FC1040104013F81040104017FC1000 +5060:08000BFE0850105013FE3252325253FE9000104017FE10881190106010D81304 +5061:090809080FFE110811F8310831F85108910817FE125012881304120013FC1000 +5062:13901E101210221222526FD46258A69027102AA82A2832282248224422842302 +5063:088008400FFC1000120831103FFE500093F81208120813F81208120813F81208 +5064:09080888089017FE1090309033FC52949294130C120413FC1204120413FC1204 +5065:1020102010FC2E2423FE622464FCA4202EFC222022202BFE2420262029FE3000 +5066:08000BFE08221120113C312032FE540091FC110411FC110411FC110411141108 +5067:1000108017FC211022086C8661F8A610216021A02E7E21842648203020C02F00 +5068:1120112415A82530252465A46E1CA040204027FC20E0215022482C4620402040 +5069:090009000BF8120814103BFC320453FC920413FC120413FC1000110812041402 +506A:100017FC100023F82208620863F8A00027FC2444244427FC2444244427FC2404 +506B:111011101210247C2910611062FEA6082A0822FE220822482228220822282210 +506C:1100110013FC24942B9461646254A4842128221020402124252A250A28F82000 +506D:08000FFE0840108013FC3294329452F49294129412F412941294129413FC1204 +506E:080009F80908110811F8300037FE510891F8110811F81108113E17C810081008 +506F:088008400FFE100013F832083208520893F810A4112813101510194811861100 +5070:0900093C0FD411141394311437D45124914C104017FE104010A0111012081C06 +5071:103C17E01420242027FE642065FCA504250425FC250425FC2904290431FC2104 +5072:08000BFC0A44124413FC3244324453FC9000104010241522150A190810F81000 +5073:104014441444244427FC60006FFEA040208027FC24A424A424A424A424A4240C +5074:100217C21442245227D264526452A7D22452245227D2200222822242244A2804 +5075:1040107E1040204027FC64046404A7FC240427FC2404240427FC211022082404 +5076:100017FC1444244427FC64446444A7FC20402FFE284228522BF22912280A2804 +5077:084008A00910120815F6300033C45254925413D41254125413D41244125412C8 +5078:09C008A00910120815F6300033CA524A925413D41268125413D4124A124A12C0 +5079:0840084010FC10883550542094D8170614F814A814A814A814F810A810A810F8 +507A:091009100BD8125414523A90311052FE9C0013F81208120813F81208120813F8 +507B:0820092408A8102013FE30A831245202904017FE108811081190106011981604 +507C:08400840087E104013FC300431FC500493FC10401240127C1240154014FE1800 +507D:08400A40094017F81088309030FC5104910813FE1202142A1AAA128214141008 +507E:1040104017FC204022486FFE6208A00027FC240424442444244420B0230C2C02 +507F:08400A480950104017FE3402380451F09000100017FC10801110120817FC1204 +5080:1040108017FC2444244467FC6444A48427FC208021502164227C24422842303E +5081:1140165C14442444275C64446444A7FC204027FC2208211020A0204021B02E0E +5082:1004103E17E0243E242065FE6522A53825E2251E250029782A48324A248A2906 +5083:084008400FFC104013F8304037FE5080911013E0104817FC1044124815441080 +5084:104010401FFE244422A861106208AC0623F8220823F8220823F8220823F82208 +5085:085008480FFE104017FC344437FC544497FC144410081FFE1208110811281010 +5086:100017FE1420244025FC650465FCA50425FC2524242024A829242A2230A02040 +5087:090809080FFE1108100037FE310851F8910811F81108113E17C8100810081008 +5088:100017FC10A020A027FC64A464A4A7FC2040204027FC20E0215022482C462040 +5089:08000BFE0A0012FC120033FE32A8529092C81286120813FE1288144814081818 +508A:080009F80908110811F8300033FC520493FC120413FC120413FC109011081204 +508B:091009100FFC111013F8311037FC504093F8124813F8124817FE120812281210 +508C:08000BFC0A4013F8124033F83240524093FC1004155415541554140410281010 +508D:1080104017FC2208211067FE6402A884204027FC210021F82108220822282410 +508E:1040104017FC204023F8620863F8A20823F8220823F822082FFE211022082404 +508F:1040102017FE242025FC642467FEA42425FC242025FC25042504290429FC3104 +5090:1080104017FE200023F8620863F8A00027FC240425F4251425F4240424142408 +5091:1208120813BE24882AA8613E6208A448284827FC20E0215022482C4620402040 +5092:083C0FC00A4411281080311033E05040918813FC1044104017FC10A01110160E +5093:1080104017FE2402240267FE6400A7DE24422652254A24C62B5A2842314A2084 +5094:0A080910080017FE10A037FC30A45FFE90A417FC10A011B012A81CA610A010A0 +5095:1080108017FE2522211063FC6620AA2023FC2220222023FC2220222023FE2200 +5096:0840084008A01190124837FE3A0853F8920813F8120013F81508150819F81108 +5097:088008400FFC1080110833F03060518497FE100217FC144417FC144417FC1404 +5098:01000280044008203118D116111029284544111029284544FFFE010001000100 +5099:088808880BFE1088108837FE308051FC932415FC112411FC112411241124110C +509A:1410121012102FA0203E654464A4A8A431282528221022102528292830442082 +509B:084008200BFE120214943108326450909108120415FA11081108110811F81108 +509C:1004103E17C02244212461286200A3FC244020402FFE20402444244427FC2004 +509D:08000BF80A0813F8120833F83000500097BC108414A4129414A4108412941108 +509E:09080888089013FC104031F8304053FE9080110011FC12201420182013FE1000 +509F:092009100A081486191033F83008500097BC108414A4129414A4108412941108 +50A0:1204110411042FC4203E67846004A7A420142794248424842484278424942008 +50A1:1410120812082FBE2000608268A2A8A22492251225142114220421882E3E2400 +50A2:1080104017FC2404200063F86080A144266820B02128266820A4212226A02040 +50A3:084008400FFC104013F8308037FC511092481446124811501248144411401080 +50A4:1110111417D221102FFE62106210AFD4241429142FD4210821CA2F1A25262142 +50A5:08400A480950104017FE3402380453F89208120813F810A0112011241224141C +50A6:080009F8090811E8112837FE340251F8910811F8110811F81108110811281110 +50A7:1080104017FE2402281463E06200A20023FC221022102FFE2000211022082404 +50A8:1020102018FA2424242861FE6020BC4024FC25442644247C25442644247C2044 +50A9:102810241740217E21C86948657EA5482248227E254825482948207E20402040 +50AA:1080111013F8221024A46FBE6042A0A023182C46219026642188263021C02E00 +50AB:100017FC144427FC244467FC6100A21027E020C823042FFE2042224825442882 +50AC:08200A220BFE1090108831FE3310551091FE1110111011FE1110111011FE1100 +50AD:102017FE142025FC242467FE6424A5FC242025FC252425FC252429FC2924312C +50AE:08A008A00FFE10A017FC34A437FC54A497FC100013F8120813F8120813F81208 +50AF:084008800BFC124412F4331432A4524492A413FC104010241522150A190810F8 +50B0:10401444144427FC200067BC64A4A4A427BC24A424A427BC24A424A42AB43148 +50B1:11241124122424242954614A6292A6102A102250225C2250225022B0229E2300 +50B2:121012101FD022202FBE6244BFA42424242427A824A8249024A829A828443082 +50B3:10401FFE104027FC244467FC6444A7FC20422FFE20102FFE2210211021502020 +50B4:100017FC140024F82488648864F8A40025DC25542554255425DC240027FE2000 +50B5:08200BFE082011FC102033FE300051FC910411FC110411FC110411FC10881104 +50B6:10141012101027FE2410649064D2A49227F22494249425C82AAA289A31A62042 +50B7:090009FC0A0015F8110831F8310851F8900017FE110013FC14A4112412541088 +50B8:1040104017FC2040255462486554A04025542248255420A020A0211022082C06 +50B9:088008400BF8111010A037FE300053F8920813F8120813F81120112212221C1E +50BA:090009100BDC125415543288310852F49402100013FC10401150124815441080 +50BB:084008800BFC12941264329433FC50909108128414FA11081290106011981606 +50BC:1110111017FE211021F0604063F8A24823F8204027FC20402FFE20A02110260C +50BD:104017FC111020A02FFE600063F8A20823F8220823F820402FFE204020402040 +50BE:100011FE1010242024FC64846784A4FC248424FC2584268424FC204820842102 +50BF:100017FC1040227822406FFE6100A1FC220023FC200425542554280420282010 +50C0:12A812A817FC22A822AA64E66800A7FC2444204023F822482248224822582040 +50C1:1008103C17C02040224861506FFEA15022482C46208020442A422A1231F02000 +50C2:104013F812482FFE224863F86040A3F8224823F820802FFE211020E023182C04 +50C3:111011101FFE2110240067FC6804B7F4249427F4249427F42494249424342008 +50C4:10001FFE10A027FC24A464A467FCA00027FC20002FFE20402248244429422080 +50C5:111011101FFE211021F0604067FCA44427FC20402FFE204027FC20402FFE2000 +50C6:1020182015FE242021FC61246DFCA52425FC242025FE242024202A2031FE2000 +50C7:08000FBC088414A4129434A430505188962610C0131010641388103010C01700 +50C8:13F8120813F8220823F8600067FCA4A424A427FC200023F8211020E023182C06 +50C9:010002800440082037D8C00600003EF8228822883EF808200820145022884104 +50CA:100017FC10A027FC24A467FC6040AFFE2110220827F62A1023F02204220421FC +50CB:084008A0091012481DF63020304053F8920813F8120813F8120813F811101208 +50CC:121012101F9022202FBE6AC46AA4AFA42AA42AA82FA822103FA8222822442282 +50CD:11C8170811082FE8211E67CA654AA7CA254A27CA210A27CA211221D22E2A2444 +50CE:100017BC14A427BC242064A4639CA000211027FC211021102FFE211022082404 +50CF:090009F00A1017FC1A24324433FC5080914416A81130166810A8112416A21040 +50D0:088808500BFE102011FC302033FE512490A817FE100011FC1104110411FC1104 +50D1:103813C0108027FE2110620865F6A91021F0200027FC240425F4251425F4240C +50D2:1080104017FC2514220863F86088A7FE208823F8210023F82508290821F82108 +50D3:08400BF80A4813F8104037FE300053F8920813F8120813F8120813F811101208 +50D4:090808900FFE109013FC3294331C520493FC120413FC100817FE110810A81010 +50D5:10A014A412A820A027FC611060A0A7FC204023F8204027FC20A0211022082C06 +50D6:104017FC104023F8200063F86208A3F821102FFE200023F82208220823F82208 +50D7:08880AAA0ADC148811543222300053FE9242144413FC10441044108411141208 +50D8:220832482A484A90421E5FE4D0545054575455545554554857485054515450A2 +50D9:1110111017FC211021106FFE6040A7FC244427FC244427FC2000211022082404 +50DA:1040104017FC20A02514620867FCAA0A23F8220823F820402248244429442080 +50DB:1510151015102F90253E67226544A790251025102F902028252828A430442082 +50DC:102017A410A822922114620865F4A80223F82208220823F8220821102FFE2000 +50DD:17FC140417FC240025F8641067FEA4202460279C2484250829DE2F0831082318 +50DE:1004103E17C02244212863F86208A3FC220423FE240226AA2AAA2A0230142008 +50DF:124812481554275C22486554675CA2482FFE22202228222825142494242C2844 +50E0:08780FC00A48115017FC31503248540693F81248124813F81248124813F81208 +50E1:104010401FFE204027FC644467FCA44427FC20442FFE204220242522250A28F8 +50E2:103C17C010442224210867FE6402AA08220823BE24882AA8213E220824082808 +50E3:1110111017BC21102FFE611062A8A44423FA2208220823F82208220823F82208 +50E4:08000BDE0A52125213DE300031FC512491FC112411FC102013FE102010201020 +50E5:1040104017FC20402FFE611067BCA1102190263E20002FFE2120212222222C1E +50E6:141412121F922010207E6F906890A8902F9022282B282AA83228224A2A4A2486 +50E7:09040888080013FE122232AA3272522293FE100011FC110411FC110411FC1104 +50E8:104017FC104021102FFE611063F8A20823F8220823F8220823F8211022082404 +50E9:179E1492179E2492279E640264F2A49224F2249224F224922492253224022406 +50EA:08000BFC0848103013FE305230945350902013FE1252128A1376125212721206 +50EB:08000FFE08901090139C32043204539C9090109017FE10401524150A190A10F8 +50EC:1140112013FE222026206BFC6220A22023FC2220222023FE2200252424922892 +50ED:100017BC1108252827BC631865AAA946200023F82208220823F82208220823F8 +50EE:08400BF8091010A017FC300033F8524893F8124813F8104013F8104017FE1000 +50EF:10401248115027FC215062486444A208220823BE24882AA8213E220824082808 +50F0:10101010FEFE1010FEFE929292923838545492921010111002800C603018C006 +50F1:084008200BFE1202120233FE3250524892FE139012FE129014FE149018FE1080 +50F2:100017FE10A027FC24A464A467FCA208220823BE24882AA8213E220824082808 +50F3:100017FC10A020A027FC64A464A4A7FC2248215027FC20E0215022482C462040 +50F4:100017BC14A427BC24A467BC6404A5F4251425F4251425F42514240424142408 +50F5:10001FFE100027FC244467FC6444AFFE200027FC244427FC244427FC20002FFE +50F6:100017FC14A424A427BC60A067BCA4A424A427BC24A424A427BC24A220A2207E +50F7:110817FE1108200024886FFE6488A4F8240027FC20402FFE215022482C462040 +50F8:1110111017BC211023B865546912A00023F8200027FC20402248244429422080 +50F9:10001FFE11202FFC29246FFC6000A7F8240827F8240827F8240827F822102408 +50FA:13F81208120823F8200067BC64A4A4A427BC20402FFE21602250244838462040 +50FB:10101008178824BE248064946788A47E2408278826BE2A882A882B8832882008 +50FC:10A010A017FC24A427FC64A467FCA00027FC200023F8220823F8211020A02FFE +50FD:10C81708112A212C2FC861086388A55429142122204020242522250A290820F8 +50FE:083C0BC008441224110837FE344252A4928A147A108010F8110812901060179E +50FF:1080104017FE25122BFC611067FCA11027FE2110224825F42842204027FC2000 +5100:111017FE104023FC204067FEA080272821242FFE212021A42F1A2112276E0000 +5101:1140112013FE222027FC6A2063FCA22023FE2200279E2492249224F224022406 +5102:08900BFC0A9413FC129433FC300053FC920012F8120013FE1520151415481986 +5103:10401FFE100027FC240465F46514A7FC200023F8220823F8220823F820002FFE +5104:088008400BFC1108109037FE300053FC920413FC120413FC10401524150A18FA +5105:10401248115027FE2402680463F8A20823F8200027FC244427FC244427FC2404 +5106:1288128817E82290241E67E46454A85427542554255427482548205422942122 +5107:08000BFC0A94129413FC300037FE500093FC120413FC10A2111413081D441182 +5108:104010A013182DF6200067FC6554A4E427FC200023F8220823F8220823F82208 +5109:1040104010A02110220865F66800A7BC24A424A427BC22102210252829443082 +510A:1110111017BC211023B865546912A00027FC2044224022782240254028FE3000 +510B:120013F8141027FE2D48762467FEA40025FC240025FC240025FC290429FC3104 +510C:121014101F9028902FBE68A46FD4A41422142FD424142788248828942A943122 +510D:082008880A5213261252328A322253FE90881144127A10881150102010D81706 +510E:111417D211102FFE21106FD06112A7D2255227D4255427C8210A2FDA21262142 +510F:108010DC128423D424486A946324AC402248215027FC20E0215022482C462040 +5110:1080104017FE24022BFC61486250A7FC220427FC2A0423FC220423FC21082204 +5111:08000BFE0A0213FE120233FE31085252939C1108125213DE100012A412521452 +5112:100017FC10402FFE284263586040A35820002FFE204027FC24A424A424A4240C +5113:10401FFE104027FC200063F86208AFFE280227FC211023F8204027FC20402FFE +5114:104017FC104023FC20006FFE6002A3F8204027FE200027FE200827FE24A82798 +5115:1080104017FC211020A46F586554A5522B582000220823F8220823F822082408 +5116:101017D0151027DE245067E86504A7C4200023F822A822A822A822A82FFE2000 +5117:1400157C160424A82390607C6414A7942A5022502FDC2250255024B0289E2100 +5118:08400BF8084817FE104833F8304057FE900012A4145213F812A812A81FFE1000 +5119:101014FE129222FE201061FE6000AEFE228222FE228022FE228222FE250028FE +511A:088808880BFE108813FE325233FE500093FE124210F811081290106010C01700 +511B:1100120017FC2AA822A86FFE62A8A2A82FFE220823BE24882AA8213E22082C08 +511C:1080104017FC244422A862946474A00023F822A82FFE200027FC204021402080 +511D:1110155415B8291022A864446000A7FC2444204027FC20E0215022482C462040 +511E:100017FC124824442FFE644466ECA55426EC244426EC255426EC244424542408 +511F:0A4809500FFE140211F8310833FC520493FC120413FC120413FC110812041402 +5120:09240A480924100013FC32943264529493FC124813681248136A124A12461362 +5121:13F81248124823F82248624863F8A0002FBE2AAA2AAA2FBE2AAA2AAA2FBE28A2 +5122:1020103E102027FE242265F86422A5FE252425FC252425FC28402AA4328A247A +5123:1040102017FE248825FC648867FEA42025FC252425FC252429FC288831042202 +5124:0BF80A080BF8120813F8311037FC51109FFE11101248155410E01150124810C0 +5125:08200BFE082011FC100033FE325253FE910411FC110411FC110411FC10881104 +5126:1080104017FC24A027FC64A467FCA400252425A8253025A4251C28002AA43452 +5127:12081FBE12082FBE2208651468A2A7FC240427FC240427FC240427FC21102208 +5128:08420B9C0A1013DE12943294342053FC920413FC120413FC120413FC11081204 +5129:10001F7C1944297C2F446944697CAF20297E29AA2F2A204A2A922922294A3104 +512A:17FC108013F8220823F862086FFEA8822548251428F4210023F8250820F02F0E +512B:104017FE100021F8210861F86000A7FE240223F82180264421B8266821A62E60 +512C:1200123C1FA422242FBC62247FE4A03C2FA428A42FBC28902F9828A828AA29C6 +512D:1400123C1FA4202428BC65246FA4A23C22242FA4223C2B102A9832A82A2A2446 +512E:100017FE14442598248867DE6488A5DC26AA248824202520253C2920292037FE +512F:1248115017FC20802FFE620867FCAA4223F8224023F8224023FC200425542008 +5130:11101FFE1110203C2FC064886250A7F8240827FC240427FE28022AAA32AA2004 +5131:142012201FBE2520223E7F82603EAFA028BE2FA028BE2FA028BE28A028A2299E +5132:14101210127A2F1220146F7E6008AF10203C2F6429A4293C29242F24293C2024 +5133:09F00A100FFC120413FC322433B8522291FE121017FC124413FC10D0114A163E +5134:104017FC100023B822A863B86110A7FC211027FC21102FFE212823102D482186 +5135:108011F812882070238E680069FCA92429AC292429FC282029FC202023FE2154 +5136:0A220BFE089011FE131035FE311051FE911011FE110013FE128A137612521276 +5137:17BE100017BC24A426B464A46040A7FE24A027FC24A427FC251229DC291231CE +5138:100017FC14A424A427FC621062A8A4BE2F68223C24A82FBC20282AA82ABE2020 +5139:152817BE194827BE231865AA6946A3FC220423FC220423FC220423FC21082204 +513A:151815141F90253E272862686FBEAAA82FA8223E2FA822283FE8253E28A03060 +513B:1248115017FC240421F0611067FCA55424E427FC204027FC20402FFE22A42452 +513C:17BC14A417BC200027FE64006590A49E27D4256425D4255425D425682BC83054 +513D:17FC144417FC24442FFE6AAA6FBEAAAA2FBE222027C020842FFE204225482884 +513E:104017FC124823F820406FFE6AAAA3B8211027FC21102FFE212823102D482186 +513F:08400840084008400840084008400840084008400840104210422042403E8000 +5140:00000000FFFE08400840084008400840084008400840104410442044403C8000 +5141:0100010002000440082010103FF804480440044004400840084210422042C03E +5142:0100010001007FFC01001100110021003FFE02800480048008841084207CC000 +5143:00003FF8000000000000FFFE04400440044004400840084210422042403E8000 +5144:00003FF8200820082008200820083FF80440044004400840084010422042C03E +5145:02000100FFFE04000400082010103FF80448044004400440084408441044603C +5146:04400440444424481450144004600C50144824444440084208421042203E4000 +5147:08202448228821082288244828283FF80440044004400440084408441044603C +5148:0100110011001FF8210041000100FFFE044004400440084008421042203EC000 +5149:010021081108091009200100FFFE0440044004400440084208421042203EC000 +514A:04400440082011102108C206044008201FF0045004400440084408441044603C +514B:01000100FFFE010001003FF82008200820083FF804400440084010422042C03E +514C:04400440082010102008DFF61010101010101FF004400440044008441044603C +514D:080008000FE0102020407FF8A108210821083FF822880480088010822082C07E +514E:000801FC7F00010001003FF82108210821083FF8228804A0089010922082C07E +514F:001000F81F80108010F81080108010801FFE11201120112022222222441E9800 +5150:000023F82208220823F82208220823F82208000004400440044008441044603C +5151:10100820044000001FF01010101010101FF0145004400440084408441044603C +5152:0000060038F8200820083CF8200820083FF8044004400440084408441044603C +5153:00007EFE081008104890489048907EFE08100810142814282548264A448A8106 +5154:080008000FE0102020407FF8A108210821083FF8228804A0089010922082C07E +5155:00003C7824482448244827C8200820083FF8244804400440084010422042C03E +5156:02000100FFFE082011102208444408201FF0045004400840084010422042C03E +5157:02000100FFFE0820101020085FF41010101010101FF00440044008441044603C +5158:00207C200048008401FEFE02240024FC2484248424FC24842402440243FE8000 +5159:08100810FF10081008107F7E411041107F101410141014102412240243FE8000 +515A:01001110091009207FFE400280041FF0101010101FF00440044008423042C03E +515B:0808081CFF70081008107F1041FE41107F101410141014102412240243FE8000 +515C:0100120067DC4444444447C44444444457C4601C04400440044008441044603C +515D:08080828FF24084408427F80417C41247F24144414441494250A240243FE8000 +515E:083808E0FF20083808E07F20413C41E07F2414241424141C2402240243FE8000 +515F:0810285028503E7C4890081008107EFE1428142814281428254A264A44868100 +5160:0100121017D2F454145817D014523452D7CE100004400440044008441044603C +5161:080008FEFF100820087C7F444144417C7F441444147C14442402240243FE8000 +5162:0820082008207EFE082008207EFC428442847EFC14501450255026924492810E +5163:100011FEFD00117C11547D7C4554457C7D10297C29102AFE2C00480247FE8000 +5164:101011FE9528557C592811FEFD10297C2954297C29542A7C2A284C44480287FE +5165:0400020001000100010002800280028004400440082008201010201040088006 +5166:040042004100410040804080414041404220422044104808500440007FFE0000 +5167:0400020002007FFC410441044284428444444824501440044004400440144008 +5168:0100010002800440082010102FE8C106010001001FF00100010001007FFC0000 +5169:0000FFFE0100010001007FFC4104514449244924555465944104410441144008 +516A:0600010002800C603018CFE600003E24222422483E4822903E48224822242624 +516B:0000004004400440044004400440042008200820081010101008200820044002 +516C:00800480048008400840102020104208820604000440082010203FF010100000 +516D:02000100008000800000FFFE0000000004400420081008081008200440040000 +516E:044004400820082010102008DFF6040008000FE0002000200020002001400080 +516F:201010100820084000007FF80208020802080208022802100200020002000200 +5170:101008100420044000007FFC0000000000003FF80000000000000000FFFE0000 +5171:04200420042004203FFC042004200420042004207FFE00000420081010082004 +5172:00007FFC010001003FF801000100FFFE0000044004400820082010102008C006 +5173:10100810082000003FF8010001000100FFFE010002800280044008203018C006 +5174:0408020821081110081008200040FFFE00000440042008100808100820044004 +5175:002000F01F00100010001FF81080108010801080FFFE00000840102020104008 +5176:082008207FFC082008200FE0082008200FE008200820FFFE0000082010102008 +5177:00001FF0101010101FF010101FF010101FF010101010FFFE0440082010102008 +5178:0440044004403FF82448244824483FF8244824482448FFFE0440082010102008 +5179:082004200440FFFE1020102020402448448878F008101020142822447EFC0204 +517A:0440082010102FE8C4260420082010A0604000003E442258226022423E42223E +517B:0820044002887FFC01003FF80200FFFE04400830344EC4440440044008401040 +517C:102008407FFC048004803FF00490FFFE04903FF00CC014A02498C48604800480 +517D:082004403FF821083FF821083FF80000FFFE00001FF01010101010101FF01010 +517E:082004403FF821083FF821083FF8000008207FFC08200820FFFE082010102008 +517F:08100420FFFE08203EF808283EAA0866389200001FF000007FFC040008101FF8 +5180:04447C7804421C3EE4003FF821083FF821083FF804403FF80440FFFE10102008 +5181:440025FE29027D0255FE55247D24557E55247D2411FE1152FD54124812641442 +5182:00007FFC40044004400440044004400440044004400440044004400440144008 +5183:00007FFC4004400440045FF44004400440045FF4400440044004400440144008 +5184:00003FF8200820082008FFFE200820082008FFFE200820082008200820282010 +5185:0100010001007FFC410441044104428442444424481450144004400440144008 +5186:00007FFC410441044104410441047FFC40044004400440044004400440144008 +5187:02000200FFFE040004000FF00810181028104810881008100810081008500820 +5188:00007FFC40044004400448244444428441044284444448244004400440144008 +5189:0100010001003FF8210821083FF8210821082108FFFE20082008200820282010 +518A:00003FF824482448244824482448FFFE24482448244824482448240820282010 +518B:00007FFC40044004400447C4444444444444444447C444444004400440144008 +518C:00001E7812481248124812481248FFFE12481248124812481248128826A84110 +518D:0000FFFE010001003FF8210821083FF821082108FFFE20082008200820282010 +518E:00001FF0101010101F90109010907FFC40044004400440044004400440144008 +518F:00007FFC400444444824501467CC444444444444444447C44444400440144008 +5190:00003FF820082FE820082FE800001FF010101FF010101FF01010101010501020 +5191:010001003FF821083FF821083FF800001FF0101017D0101017D0101010501020 +5192:00003FF820082FE820082FE8200800001FF010101FF010101FF010101FF01010 +5193:082008207FFC08203FF80820FFFE01003FF821083FF82108FFFE200820282010 +5194:00003FF820082FE820082FE800007DFC4420442047FE44207C20442000A00040 +5195:7FFC40045FF440045FF404000FE010203FF8510811081FF8028004821882607E +5196:00007FFE40028004000000000000000000000000000000000000000000000000 +5197:000000007FFE4002800400000FC00840084008400840104210422042403E8000 +5198:0100010001003FFC2104410801000280028002800480048008841084207C4000 +5199:00007FFE4002900410001FF8100020003FF800080008FFC80008000800500020 +519A:000000007FFE400281040100010021082108210821082108210821083FF80008 +519B:00007FFE4002820402003FF80400090011003FF801000100FFFE010001000100 +519C:0100010001007FFC4204820805000508089018A02840482088100A080C060800 +519D:00007FFE400280041FF0101010101FF0101010101FF0101010101010FFFE0000 +519E:00007FFE4002810411100920054001007FFC0540092011102108C10601000100 +519F:00007FFE410282041FF010101FF010101FF0000010F01F00100410040FFC0000 +51A0:00007FFE400280043E08000800FE7E08144814281408142A2412240243FE8000 +51A1:00007FFE40029FF400007FFC02000D08719002A00CC071A006981886E2800100 +51A2:00007FFE400280047FFC0200060819106AA004C01BA062980C863080C2800100 +51A3:00007FFE400280047F0022FC22443E44224422283E2822102790FA2842440282 +51A4:00007FFE400288040FE0102020405FF8110811081FF8028004A008921082607E +51A5:00007FFE400280041FF010101FF010101FF012100100FFFE0000082010102008 +51A6:000000007FFE400280243E38002000207EF814081450142014542484240443FC +51A7:00007FFE400280040820082008207EFC08201C301A702A6848A4892208200820 +51A8:00007FFE400280043FF800001FF010101FF000003FF821083FF821083FF82008 +51A9:00007FFE400282041CF010101EF010101FF008001FFC20044924249424944008 +51AA:FFFE84423FF804401FF010101FF010101FF002007FFC09203FF8D11611300100 +51AB:000040002000200000000800080010001000E000200020002000200020000000 +51AC:040004000FF010102820444003800C603018C006070000C000200E0001800040 +51AD:010001000100FFFE02800440082010102608C186004000000C00030000C00020 +51AE:0000400027FC204000400840084010401040E0402040204020402FFE20000000 +51AF:000047F02010201002100A100A1013FC1004E004200427F42004200420280010 +51B0:004040402040204400680770116011502150E248224824442842204021400080 +51B1:000047FE20802080008008F80908110811082208E3F820102010201027FE0000 +51B2:004040402040204007FC0444144414442444E44427FC24442040204020400040 +51B3:00804080208027F800880088108810882FFEE080214021402220241028081006 +51B4:000043FC20102110011009100A1013FE1030E050209021102210241020500020 +51B5:000047F8240824080408040817F811202120E1202120222022222422281E1000 +51B6:0040404020802110020807FC1004100023F8E208220822082208220823F80208 +51B7:0040404020A020A0011002481426102023F8E0082010211020A0204020200020 +51B8:0040424421482150004007FC104010402040EFFE204020402040204020400040 +51B9:009040882088208007FE0080110011FC2144E244224824502420285020880306 +51BA:000043FC2204220402040BFC0A20122013FEE220222022102212228A23060202 +51BB:00404040204027FE008009200920122013FCE020212821242222242220A00040 +51BC:00404240224023FC04400040104017FE2120E1202120212022222222241E0800 +51BD:000440042FC42224022403A412A414A426A4E5A4292421242204220424140808 +51BE:0040404020A021100208140613F81000200023F8E20822082208220823F80208 +51BF:0040404023F8204807FE004813F810402040E7FC204020402FFE204020400040 +51C0:0100410023F02410002017FC104410442FFE2044E04427FC2044204021400080 +51C1:004040402FFE2040004007FC1444144427FCE04020E0215022482C4620400040 +51C2:0100410021F02210022007FC1A4412442244E3FC22A420A0212022222422081E +51C3:0040404020A02110020805F61040104027FCE040225022482444284421400080 +51C4:0040404027FC204003F8004817FE104823F8E08027FE21082390206021980604 +51C5:000047FC2444244407FC0444144415F42514E514251425F42514240427FC0404 +51C6:01404120212023FE022016201BFC1220222023FCE2202220222023FE22000200 +51C7:02084228222822280FA40244125416922710EAA02A203228224422FC22440200 +51C8:003C47C02244212800000BF80848104817FEE048204823F82048204021400080 +51C9:008040402FFE2000000003F81208120823F8E040225022482444284421400080 +51CA:0040404027FC204003F8104017FE100023F82208E3F8220823F8220822280210 +51CB:000047FC2444244405F40444144417FC2404E5F42514251425F4240424140808 +51CC:0040404023F82040004007FE111012882484E1F0231024A0204020A023100C0C +51CD:0040404027FC204003F80A480BF8124813F8E04020E0215022482C4620400040 +51CE:0040404020A021100208040611F010402040E3F820402248214821502FFE0000 +51CF:00144012201027FE0410041015D014122412E5D42554254825DA242A28461082 +51D0:000047FC20A020A007FC04A414A414A427FCE040204027FC204020402FFE0000 +51D1:0040404027FC204003F8008017FC11102208E5F6204023F8204020A021100608 +51D2:004042482248224803F8000017FC100023F8E208220823F8211020A027FE0000 +51D3:000047FC20A020A007FC04A414A417FC2040E04027FC20E0215022482C460040 +51D4:0040404020A02190024817FE1A0813F8220823F8E20023F82508250829F80108 +51D5:000047FC2404200003F80A080BF8120813F8E080204027FC2000211022080404 +51D6:4140212003FE0A2017FCEA2023FC222023FE02000100FFFE0100010001000100 +51D7:0040444427FC2120011003FE122016202BFCE220222023FC2220222023FE0200 +51D8:04804482249C2FD004900790149E17942494E4942FD42014251428A430240044 +51D9:000047FC24A427FC004003F8104017FC2110E0A023F820402FFE204020400040 +51DA:0110411027BC211003B805541912100023F8E00027FC20402248244429420080 +51DB:00404FFE200027FC040405F4151415F42404E7FC200023F820002FFE224804C4 +51DC:00404FFE200027FC040405F4151415F42404E7FC200823F020402FFE21500E4E +51DD:0400457C260424A80390107C141417942A502250EFDC2250255024B0289E0100 +51DE:08008BDE4A924A920BD22A5E2A502BD04A92CA924BCE50004000452444920892 +51DF:00404FFE204027FC000007FC14A417FC2208E3F8220823F8220823F821100208 +51E0:00000FE0082008200820082008200820082008201020102220222022401E8000 +51E1:00000FE00820082008200A20092008A008A008201020102220222022401E8000 +51E2:0200020004001FE01020102010201020102010201020102220222022401E8000 +51E3:02000200020002001FE0102010201020102010201020102220222022401E8000 +51E4:00003FF8200820082FC8204828482488228821082288244A284A400A40068002 +51E5:00003FFC200420043FFC2000200023E02220222022202220242244224822901E +51E6:100010F010901E901290229022905290949414940894090C1400230040FE8000 +51E7:00003FF820082108210821082FE829282928292829A8294A210A410A41068002 +51E8:00003FF8200820082FC8200820083FE82208248828483FEA282A400A40068002 +51E9:00003FF820082108210821082FE82108238823482528252A290A510A41068002 +51EA:00003FF820082088208820882088248824E824882488248A248A5FFA40068002 +51EB:020004003FE02020242022A020403FF800081F8810A8109010822082407E8000 +51EC:00003FF8200820082FE82008200827C82448244827C8244A244A47CA44468002 +51ED:08380BC01040304057FE90401040104013F800000FE00820082010222022C01E +51EE:00003FF8200820082FE82108220827C82448244827C8244A244A47CA44468002 +51EF:100092F092909290FE900090FE90029002907E904090409246925912610E0200 +51F0:00003FF8220827C8244827C8244827C820082FE8210827CA210A4FEA40068002 +51F1:0800490049787F480048FF4800487F48414841487F484248244A0F4AF08A4106 +51F2:00003FF8244822883FF822882FE822A83FF822A82FE8228A26CA4AAA52968282 +51F3:00907EA004442BA810102FE8C8260FE004407FFC00000FE0082008221022601E +51F4:000043FC22400BF80A4013F82240E3FC2004255420080FE0082008221022601E +51F5:000000000000000040044004400440044004400440044004400440047FFC0004 +51F6:000000101010082044444284410442844444482450146014400440047FFC0004 +51F7:01000100010001004FE4410441044104410441045FF44004400440047FFC0004 +51F8:00000FE008200820082008200820783C4004400440044004400440047FFC4004 +51F9:00007C7C444444444444444444444444444447C440044004400440047FFC4004 +51FA:0100010021082108210821083FF801080100010041044104410441047FFC0004 +51FB:0100010001003FF8010001000100FFFE0100010021082108210821083FF80008 +51FC:01000100010001105D244544458449444924511461144504420440047FFC0004 +51FD:00003FF00020004051944924454441044544492451144504420440047FFC0004 +51FE:00003FF00020004041845D745594555455245D5441944504420440047FFC0004 +51FF:0440244814500440FFFE0000044022882FE8210821082FE8210821083FF80008 +5200:000000003FF80208020802080208020802080408040808080808100820504020 +5201:00003FF800080008000800480088010802080408080810086008000800500020 +5202:0004000400040044004400440044004400440044004400040004000400140008 +5203:00003FF802080208020822082208220842080208040804080808080810506020 +5204:00007FF004100410241014100C100410061005900870081E1010101020A0C040 +5205:00007FE00420042004200420242824244422842208200820102010202140C080 +5206:00400440042008201010200840049FE204200420042008200820102021404080 +5207:1000100011FC104410441E44F044104410441244144418841084010402280410 +5208:000401040104212411240A240A24042404240A240A2411242104400480140008 +5209:1004100420043FA4402480243F2402240424082410242024408440843F940008 +520A:00047F0408040824082408240824FFA408240824082408240804080408140808 +520B:0004070478040824082408240824FFA408240824102410242004200440148008 +520C:0404040404040424FFA404240424042444242424242404240404040414140808 +520D:040004000FF0101020204040BFF80008000800081FF80008000800083FF80008 +520E:2004200420043FA454A494A414A424A424A448A488A410A42084408485140208 +520F:200420043F84402480243F24002400247F240124012401240144014400D40048 +5210:00043F04210421242924252425242124FFE42124212421242104410445148208 +5211:00047F8412041224122412241224FFE412241224122412242204220442148208 +5212:100414041204102413A4FC2410241124112412240C2408A414842284C1940088 +5213:00043F04000400240024FFA41224122412241224122422A42304420480140008 +5214:0804080408047F240924092409240924FFE40824082414241204210441148008 +5215:00003FF80208020804080850302000007EFC122412241224224422444A948508 +5216:00043F042104212421243F242124212421243F24212421242104410445148208 +5217:00047F84080408241F2411242124212452248A24042404240804100420144008 +5218:100408040804FFA4022442242224142414240824082414242404420482140008 +5219:00047F0441044124492449244924492449244924492414241204210440948088 +521A:00047F0441044124652455245524492449245524552465244104410445144208 +521B:0804080414041224212440A4BE242224222422242A242424208420841F940008 +521C:1202120212027F82129212927F92521252127FD21252125223422282420A8204 +521D:2000100001FCFC44084410441044344458449444144410841084110412281410 +521E:00043F042104212421243F24212421243F242124212421242784F80440140008 +521F:00047F041104112421242524422480243F2421242124212421043F0421140008 +5220:00027BC24A424A4A4A4A4A4A4A4AFFEA4A4A4A4A4A4A4A4A4A425A42854A0884 +5221:00027F824082408240927F92441244127FD24412441242124242514260CA4044 +5222:0804080414041224212448A4842404247F240124222414240804040404140008 +5223:0804080408041024122421247FA420A400243F2421242124210421043F142108 +5224:040444842484252404247FA4042404240424FFE4042408240804100420144008 +5225:00047F044104412441247F240024102410241F2411241124210421044A148408 +5226:0804080408047F24082408240824FFA408241024102422244104FF8440940008 +5227:0800080008FC7F24082408240824FFA41024102424244224FF44414400940108 +5228:100410043F0421244124BD24252425243D24212425242224208420841F940008 +5229:010407847C04042404240424FFA40C241624152424A424244404840404140408 +522A:00047F0455045524552455245524FFA455245524552455245504510445144208 +522B:00047F044104412441247F2410241024FF24112411241124210421044A148408 +522C:14041204100417247824102417A4F824112412240C2408A414842284C1940088 +522D:00047F04020404240C2412242124C0A400247F240824082408040F04F0144008 +522E:02040F04780408240824FFA40824082408247F2441244124410441047F144108 +522F:00047F84000400243F24212421243F24212421243F24212400040784F8144008 +5230:0004FF840804102422244124FFA408A4082408247F24082408040F84F8144008 +5231:2400240025F824487E482448254C254AFE4A2448244824482448448844A88510 +5232:080408047F04082408240824FFA40024082408247F24082408040F04F0144008 +5233:08040804FF84142422244124BEA40024FFA4102420247F24010401040A140408 +5234:00047F041104122423A420A44AA489240824FFA418242C242A04490488940808 +5235:0004FF84220422243E24222422243E242224222427A4FA244204020402140208 +5236:0404240424043FA444240424FFE4042404243FA424A424A42684250404140408 +5237:00023FC2204220423FD22212221222123FD252525252525293421282020A0204 +5238:0100111009203FF8020002007FFC082010102FE8C42604200820082011402080 +5239:01046204140408241424222449240824FFA408242A2429244884888428141008 +523A:08040804FF84082408247F24492449244D244A241C242A244904888408140808 +523B:100408040004FFA40824112421247E240424092412242424CC0412042114C088 +523C:1000100010FC7E24102410A410A4FEA410A41124202428244444FE4442940108 +523D:08040804140422244124BEA400240024FFA41024102422244104FF0441140008 +523E:080408040804FFA40824492429242A24FFA40824082414241204210441148008 +523F:08044904490449247F24102410243F244124A12412241424080410042014C008 +5240:08044904490449247F2400247F24012401243F242024202423042C0430140008 +5241:00043E0422042224222449A488240824FFA408241C242A244904888408140808 +5242:10040804FF840224642418242624C12422A42224222422242204420442148208 +5243:420422042404FF2409240924FF2488248824FFA418A428A44A84890408140808 +5244:00047F84000424A449249224492424A400247FA40824082408040B84FC140008 +5245:00047F84000400243F242124212421243F240024212411241204078478142008 +5246:080404043F04212421243F24212421243F242024242422242504290430142008 +5247:00047F04410441247F24412441247F24412441247F2400242204210440948088 +5248:00043F04210421243F2400247FA440A440A47FA440A440A47F84408442944108 +5249:080408042A042A242A245D2488A4082408247F240824082408040F84F8144008 +524A:0804490429042A2408247F24412441247F24412441247F244104410445144208 +524B:08080808FF48084808487F48414841487F481448140814282412240243FE8000 +524C:08040804FF84082408247F24492449247F2408241C242A244904880408140808 +524D:101008100820FFFE00003E08224822483E48224822483E48220822082A282410 +524E:02046404180416242124CA2409240824FFA418241C242A242904488488940808 +524F:4200240000FC7E24242424A424A424A4FEA42524242424242444444444948508 +5250:00047F044104412441247F2408240824FFA488A494A4A2A4C284808482948108 +5251:0804080414041224212440A4BE24002411240924492422242204078478142008 +5252:1204120412047F2412241224FFA400243F24212421243F24210421043F142108 +5253:0C80708011FCFD2432243844548491041228101000007FF80408080810506020 +5254:00043F04210421243F24212421243F2410243FA44AA492A42484488412942108 +5255:120212021202F3C21212121212127392121212121212F3D212021202120A1204 +5256:100408047F84002421241224FFE4002400243F242124212421043F0421140008 +5257:240422042F04F024142409243524CB2424242F24F0241224140409043514C308 +5258:22042204FF84222422243E24222422243E2422242224FFA40004220441148088 +5259:4200240001F87E4824482448254C254AFE4A2448244824482448448844A88510 +525A:04020402FFC204023F9224923F9204123F920492FFD204923F820402140A0804 +525B:00027FC2404251424A527FD2445244525552555255525F5240424042414A4084 +525C:080404047F8440A420243BA42AA42AA42AA45AA44BA48A241204128423144208 +525D:20043E0442047C240424FFA40824092449242A241C242A24C904090428141008 +525E:080408047F84142422244124FFE4012479244924492449247904010405140208 +525F:00047B8408842AA411242AA444A4882400247BA408A42AA411042A8444948808 +5260:10040804FF84002400247F244124412441247F2408242A244904888428141008 +5261:0804090449044A2488241424222449248824492449248A241404220441148088 +5262:0004FF84080410242824C4A40D2456242524D5240CA414A42404C40414140808 +5263:08040804140422244124BEA4082408247F24492449247F240804140422144108 +5264:10040804FF840224642418242624C12422A43E24222422243E04420442148208 +5265:00047E0402043E240224FFA40824092449242A241C242A24C904090428141008 +5266:08040804FF8414242224492488A47F2449247F2449247F2408040A040C140808 +5267:00043F84208420A43FA4242424243FA4242424243FA450A4508490841F941088 +5268:08040804FF8408247F240824FFA40824FFA4102420247F24A10421043F142108 +5269:070278020802FF822A122A92EB122A926A92A9921C122A1249028882080A0804 +526A:0820FFFE00003E0822483E4822483E482208261800007FF80408080810506020 +526B:040202023FE2248224923FF22492279220122FD22052249222824102468A9844 +526C:08044904490449247F240024FFA4082410247F24552455245504550455144308 +526D:00043F84208420A43FA420243FA4242429242FA422242FA4220443845E148808 +526E:00047F0441044124792449244924FFA480A4BEA4A2A4A2A4BE84808482948108 +526F:00027FC200023F82209220923F9200127FD2445244527FD2444244427FCA4044 +5270:03823C0204027FC215121512FFD2151215127FD20E12151224824442840A0404 +5271:08000800147E22124112BED2085208527F52499249127F1208221422224A4184 +5272:10040804FF8480A409247F2408247F240824FFA408247F24410441047F144108 +5273:22042204FF8422240824142422244124BEA4002400247F24410441047F144108 +5274:0804490449047F240024FF2400247F24412441247F24422424040F04F0144008 +5275:08040C041204292444A4BF2421243F2421243F2420243F24510451049F141108 +5276:20043F0441047E240224FFA4102428A4CD2416242524CD2414842484D4140808 +5277:080404043F8411240A243FA422242A242FA4322422242FA42204420443949C08 +5278:0804FF8408047F2449247F2449247F2408A4FFA40224FFA4420422040A140408 +5279:0004770411045524332455240C243324C4A4182462240CA4710406041814E008 +527A:082008207E7E08C4FF281C102A2848C600003FFE20002FF82208420844289810 +527B:0202222222223FEA000A3DEA252A252A3DEA252A252A3DEA2522252255AA8A44 +527C:100422047F04422494A4F7A408243624C92430A4C424192462040C043014C008 +527D:0002FFE20A027FC24A524A527FD200127FD20012FFF2041224824442942A0804 +527E:00027FC240024F82489248924F9240125DD25552555255525DC240027FEA0004 +527F:49049204490400247F2449247F2449247F240824FFA41C242A04490488140808 +5280:00047F0412040C24FFA414A42524D4240824FFA494A4A2A4DD8494849C948188 +5281:120211023FC222026212BFD2221222123FD2221222123FD2200254824A4A8A44 +5282:00027FF24002514A4A4A5F7A449A442A550A554A5F4A444A44A248A2492A9204 +5283:08047F040904FFA409247F240824FFA400247F2449247F2449047F040014FF88 +5284:420442047BC44524A8A4142422244124BEA4002400247F24410441047F144108 +5285:00047F04550455247F2420247FA490A47CA454A454A47CA41284FE8402940108 +5286:02023FF22882250A3FEA250A2FCA254A3FEA254A2FCA250A2D825542652A8504 +5287:08040F0408047FA448A47E244924472440247FA4482455244A04B7040A943608 +5288:00407C2045FC44887C5043FE7C20A5FC24203C2000007FF80408080810506020 +5289:080277C252424A42555264920A1211123F92C4523F120492250217C27C0A2004 +528A:04020B0230C2DF2200127FD255524E527FD200123F9220923F8220823F8A2084 +528B:00047F0441047F240024F7A494A4F7A408240824FFA41C242A04490488940808 +528C:020213C212027FEA010A014A3FEA210A3F0A254A254A2D4A368244A2896A3224 +528D:08040804140422244124BEA40024002477245524552477242204220455148888 +528E:0800080014FC22244124BE240024002477245524552477242244224455948908 +528F:080449042A04FFA480A43E24222422243E2400247F2449247F0449047F144108 +5290:11027FC2150212023FD26412BF9224123F9224123FD220127F8211020E0A7184 +5291:080204027FC211020A52F59255525532B592001220923F9220823F82208A4084 +5292:08000800147E22124112BE5200520052775255925512771222222222554A8884 +5293:08023F8220823F8220923F9200127FD244527FD244527FD20002FFE2110A2104 +5294:08000800147C22244124BE2400A4006477245534552C7726222422245544888C +5295:0844738442047BE452A452A484247FA440A47FA440A47FA440847F8421144088 +5296:3E024202FF8240827F924492771244523FD24212FF9248927F821A02294AC7C4 +5297:52827BE294827BEA318A5AAA946A3FCA204A3FCA204A3FCA20423FC2108A2044 +5298:02023FF224823FEA248A2ECA35AA248A250A3DEA250A3DCA25025DE2450A8504 +5299:1F0221023E0202027FD2189265121A9266521A122492FBF2AAA2FBE228AAFBE4 +529A:7FC240427FC252424A9252525FD255525FD264525F5255525F424442BF4A0084 +529B:02000200020002007FF802080208020802080408040808080808108820504020 +529C:1020102010201020FF201120112011201120112021202122212241224A1E8400 +529D:004000400040FC4005FC04444844284410441084288424844504810402280410 +529E:02000200020002007FF002100210121812142412441208100810101020A04040 +529F:004000400040FE4011FC1044104410441044108410841E84F104410402280410 +52A0:100010001000107CFE4412441244124412441244124412442244227C4A448400 +52A1:040004000FF0182024C003000CC03230C20E1FF0021004100410081010A02040 +52A2:00200020FF20202020FC20243E24222422242224222422244244424494A80910 +52A3:0100111011082124414401800E00F10001003FF8020802080408080810506020 +52A4:022007203820202020FC20243F24242424242424242424442444448445288210 +52A5:102008200820FF2000FC00243C24242424242424242425444644448481280210 +52A6:020002003FF00410081010A06040102010207EFC12241224224422444A948508 +52A7:04200E207820082008FC7E24082408240824FF24082408440844088429281210 +52A8:004000407C40004001FC0044FE4420442044208448844484FD04450402280410 +52A9:00207C204420442044FC7C24442444247C244424442444444E44F08401280210 +52AA:10001000FEFC22844488285010202858C586020002007FF80408080810506020 +52AB:0820082008207E2008FC08240824FF241024102420244444FE44428401280210 +52AC:2020202020207E2042FC82247A244A244A244A247A244A440244028415280A10 +52AD:00207E201220122022FC2A24442480243E2422242224222422443E4422A80110 +52AE:08200820482048207EFC482488240824FF240824082414442244428481280210 +52AF:00200020FF20102010FC10243E2422246224A224222422443E44228401280210 +52B0:1020102020207E2042FC4224422442247E2442244224422442447E4442A80110 +52B1:00107FD0401040105F7E481248124F12491249124912491249125122952A2244 +52B2:00207E200420082018FC24244224812400247E240824084408440E84F1284210 +52B3:08200820FFFE082000007FFE420282043FF00210021004100410081010A02040 +52B4:22081108111000207FFE4002820402007FF80208020804080408080810506020 +52B5:0100111009203FF8020002007FFC082012102208DFF604100410081010A02040 +52B6:04200E207020402040FC7F24402440245E2452245224522452449E4492A80110 +52B7:2220122014207F2008FC08243E24082408247F24082408441044108421284210 +52B8:082008207F20082008FC0824FFA40024082408247F24082408440F44F0A84110 +52B9:102008200020FF2000FC24244224812424241424082414442244428481280210 +52BA:101010102410427EFF120912481248127F1288220822FFA20842084208940908 +52BB:00107F904010407E7F92441244125F12441244227FA2402240427FC200940108 +52BC:082008200820FF2008FC08247E24002400247E244224422442447E4442A80110 +52BD:7F84082410243F2451240A24040408043014C20802007FF80408080810506020 +52BE:102008200820FF2008FC102422247C24092412242424C82414442244C0A80110 +52BF:084008407DF808480C4819C8684A08AA2886130202007FF80408080810506020 +52C0:0820082008207F2008FC08247F24412441247F24142414242544264444A88110 +52C1:00207F20002025204AFC9224492424A400247F240824082408440F44F8A80110 +52C2:0820282028203E2048FC0824FF24002400243E242224222422443E4422A80110 +52C3:082008207F20082008FC7F24412482243C24042408240F447844088429281210 +52C4:201020103F904010BF7E211229122512FFD22112491245127F9201220A2A0444 +52C5:08200820FFA0082008FC7F24492449247F2408241C242A444944888409280A10 +52C6:102008207E20422042FC7E24422442247E244024482444444A44528461284210 +52C7:3FF0066001803FF821083FF821083FF82108220802007FF80408080810506020 +52C8:00107E1002103410087E7F12491249127F12491249127F1249124922492A4344 +52C9:202020203E20442088FC7F244924492449247F4414441494250A240243FE8000 +52CA:08200820FF20087C08247F24412441247F241444145414882502240243FE8000 +52CB:00203E20222022203EFC00247F2441244924492449244944144412842128C210 +52CC:082049202A207F2008FC1024FFA422244124BEA422242A24244420442CA83110 +52CD:10100810FF900010007E7F124112411241127F1208122A12491288A2282A1044 +52CE:082008207E20082008FCFF242224412488A408247E24082408440F44F8A84110 +52CF:102008207F20002022FC1424FFA4002400243E242224222422443E4422A80110 +52D0:00203E20042008207EFC08240824282410247F245524554455445784FD280210 +52D1:082008200820FF2008FC2A242A242A245D2488241C242A444944888409280A10 +52D2:22202220FFA022203EFC08247F24492449247F240824FFC40844088409280A10 +52D3:441044907510461054FE64924B9210127F12411241127F12411241227F2A4144 +52D4:0020FFA0082010207F7C552455245D24552455245D245524554455447F944108 +52D5:0F2078200820FFA0087C7F2449247F2449247F2408247F2408440FC4F8944108 +52D6:0020FF208120BD2081FCBD24812400247E2442247E2442247E4442447EA84310 +52D7:1FF010101FF010101FF000003E2022203EFC22243E2422242F44F04440940108 +52D8:22202220FF2022203EFC22243E2422242224FF2440245444624440847F280210 +52D9:0040FC4004FC688811500820FED813063440304053FC50449084108451142208 +52DA:52105210FF9052105E7E40127F1200127F1241124912491249121422222AC144 +52DB:00203E20222022203EFC00247F2441247F2441247F2441247F44144422A84110 +52DC:282044209220202048FCFC2404240024EE242224AA246624AA442244AAA84510 +52DD:0020792448A8482049FC78404BFE488849447A424DF848484888488849289A10 +52DE:08202AA42CA84920145022887FFE410281043FF8020802080408080810506020 +52DF:04407FFC04401FF010101FF010101FF00400FFFE10102208DFF6041008503020 +52E0:0020772011205520337C55240C243324C4A4182462240CA4714406441894E108 +52E1:0020FFA014207F2055FC55247F2400247F240024FFA408242A444944A8A81110 +52E2:10407C4011F8FE4844C892487CAA10AA1D06E20202007FF80408080810506020 +52E3:08107F1008107F10087EFF9200127F1241127F1241127F1241127F22222A4144 +52E4:22202220FFA022203EFC08247F2449247F2408247F2408447F4408840F28F210 +52E5:7CF8048804F87C2041FC7D2405FC04282BFC120402007FF80408080810506020 +52E6:49209220492000207F7C49247F2449247F240824FFA41C242A44494488940908 +52E7:202020203F20482088FC7F24142422247F24A4243F2424243F4424443FA82110 +52E8:20203E204220FF2049FC49247F2410242824D5242624CD2415442444D4A80910 +52E9:5220FFA052205E2040FC7F2400247E2442247E2442247E4442447E8425284210 +52EA:061078101010FF90227E5D1294921C1200127F1241125D1255125D22412A4344 +52EB:0F10F81049102A7EFF922A12491280927F12492249227F22494249427F944108 +52EC:081049102A107F10107EFF9222125112A2923C1209127F120812492288AA1844 +52ED:101008107F102210FF7E00127F1249127F1249127F1208127F1208220F2AF044 +52EE:08100F1008107F9048FE7E124912471240127F92481255124A12B7220AAA3644 +52EF:0820FF200020FF20817CBD24A524FF2400247E2442247E2442447E440094FF08 +52F0:100010FE7E92129222FE2A92449280FE4410FF0855285520556455AA5928B318 +52F1:22102210FF9022107F7E49127F1249127F120812FF9288928A92BEA282AA81C4 +52F2:7F200820FF2008FC7F2449247F2449247F2408447F440894FF08000024484224 +52F3:071078100810FF90087E7F126B125D127F1208127F120812FF920022552A8AC4 +52F4:08100F9008107F9048FE7E1248925F9255125F1255125F1248125522B2AA5E44 +52F5:00107F904A107F904A7E5F1255125F1255125F1244127F926492AEA2A2AA2144 +52F6:22104F90821E14A42FD46014AF9428882F88289429A202007FFC040418286010 +52F7:0810FF9000107710557E771222127F1222127F122212FF9228926522B22A2144 +52F8:2210FF902210F79094FEF792281224127F924812FF1248127F1248227FAA4044 +52F9:100010003FFC2004400480040004000400040004000400040004000400280010 +52FA:0800080010001FF8200840088008040802080108010800080008000800500020 +52FB:0800080010001FF82008400880081F880008000800083FC80008000800500020 +52FC:100010003FFC2004440484043F84048404840884089410942074400400280010 +52FD:0800080010001FF8200842088208020805080488048808481048200800500020 +52FE:0800080010001FF820084208820804080408088810483FE81028000800500020 +52FF:0800080008001FFC124422444244844404440884108421044204040408281010 +5300:080008000FFC10042004480484040204002400C403041C040804000400280010 +5301:0800080008001FF811082908450882080308048804480838100E200840500020 +5302:100010003FFC200448048844088409040E0408140814081407F4000400280010 +5303:080008000FFC1004210441049104128412441424182410041FE4000400280010 +5304:100010003FFC20044204810400043FF408040804080408040FE4000400280010 +5305:080008001FF0101020105F909090109010901F9010501020100410040FFC0000 +5306:0800080008001FFC1244224442449C440644098410C421244214040408281010 +5307:100010003FFC2204420487E40824102424440244028401040604180460280010 +5308:0800080010001FF820084088888825282228252828A820283FE8000800500020 +5309:100010003FFC20044004BFE4020412440A440A8402047FF40204020402280210 +530A:100010003FFC2004420492440A8402047FF407040A8412446224020402280010 +530B:100010003FFC200448048FC4120402047FF40204124412441FC4004400280010 +530C:100010003FFC22044504888410446FB400041FC4104410441FC4000400280010 +530D:100010001FFC22444224BFF402043FE422243FE422243FE42224222422B42048 +530E:100010001FFC24047FE48884124462341FC412441FC412441FC4022401F40008 +530F:10401040FEFC2884450482F47C940094FEF4208440947C8804820482287E1000 +5310:100010001FFC20047FE480041FC410441FC400043FE422243FE422243FF42028 +5311:100010003FFC28045EF492141E1412F41E8412847EF40A1412142A5444280010 +5312:100010001FFC28844884BFE40A8405040884174460341FC4104410441FD41048 +5313:100010003FFC4004BDE4252425243D34260425E43C2420A428442CA433282010 +5314:100010003FFC28045EF492941E9412F41E0412F47E940A9412F42A0444280010 +5315:1000100010001008103010C013001C001000100010001004100410040FFC0000 +5316:0880088008841088109030A030C05080918012801480108210821082107E1000 +5317:044004400440044404487C500460044004400440044004421C42E442443E0400 +5318:409241244248492448925040608043FE4202428A42524A224A524A8A3BFE0202 +5319:00003E4022403E4422483E500060FF40084408442F44283C280058004FFE8000 +531A:00007FFC4000400040004000400040004000400040004000400040007FFE0000 +531B:00007FFC4200420047F0441048205020404040A041104608580440007FFE0000 +531C:00007FFC40804080448044F047905C9044D044A44484440443FC40007FFE0000 +531D:00007FFC4080408040804FF8488848884888488848A84890408040807FFE0000 +531E:00007FFC400040004FF84080408040804080408040805FFC400040007FFE0000 +531F:00007FFC4000410040805FFC400043E04220422042244424481C50007FFE0000 +5320:00007FFC4000403847C04400440047FC4420442044204820482050207FFE0000 +5321:00007FFC400040004FF84080408047F04080408040804FF8400040007FFE0000 +5322:00007FFC4400440047F84928512862484448488851084250442040007FFE0000 +5323:00007FFC400040004FF8488848884FF8488848884FF84888408040807FFE0000 +5324:00007FFC400040005FFC408040804FF8408040A040905FFC400040007FFE0000 +5325:00007FFC4200441048085FFC4004441044107FFE44104410481050107FFE0000 +5326:00007FFC442044205FA0487852285FA8422843A85E2A4A2A424642807FFE0000 +5327:00007FFC408040805FFC4080449044904AA8514441204220441048107FFE0000 +5328:00007FFC4220522052205E2043FC42207E205220522052F8620042007FFE0000 +5329:00007FFC4080488848884FF840805FFC400040804FF840805FFC40007FFE0000 +532A:00007FFC424042407E7C424042405E78424042407E7C4240424042407FFE0000 +532B:00007FFC44004FFC5124624444A849104FF848084FF848084FF840007FFE0000 +532C:7FFE4080414042204C1873F640004FA448A44FA448A44FA448844A9449087FFE +532D:00007FFC44205F2044205F7855285F2855285F28442A5F2A444644807FFE0000 +532E:00007FFC40804FF848884FF840807FFE40004FF84888496842104C087FFE0000 +532F:00007FFC40A0489045FE612057FC452049FC7920492049FE490040007FFE0000 +5330:7FFE40005F7C51445F7C40004FF848884FF848884FF840807FFE408040807FFE +5331:7FFE40804FF848884FF840807FFE48084FF848084FF848084FF8441048087FFE +5332:00007FFC40805FFC42204C1877F6441047F040004F7849484F7840007FFE0000 +5333:7FFE4080414042204C1873E640005F7C514451445F7C44104A28514440007FFE +5334:7FFE48404F7C54906FF848084FF848084FF848084FF842205FFC442048207FFE +5335:7FFE40804FF840804FF849484FF8441047F0441047F0441047F0422044107FFE +5336:7FFE44105FFC44904FFC58806FF848804FF848804FFC4408473844087FFE0000 +5337:7FFE49484F7849484F7849484F78448047F84C8057F0648047FC44007FFE0000 +5338:00000000FFFE10001000100010001000100010001000100010001FFE00000000 +5339:00007FFC444044404440444044404440444444444844483C500040007FFE0000 +533A:00007FFC4000401044104220414040804140422044104810400040007FFE0000 +533B:00007FFC440044004FF8508040805FFC4080414042204410580840007FFE0000 +533C:00007FFC40804140422044105BEC400047F04410441047F0441040007FFE0000 +533D:7FFE40004FF848084FF848084FF841005FFE4210472040C043304C0840007FFE +533E:00007FFC40804FF848084FF848004FFC592469244FFC4924492C40007FFE0000 +533F:00007FFE422042205FFC422041005FFC420047F84A08520843F840007FFE0000 +5340:00007FFC40004FF0481048104FF040005E78524852485E78524840007FFE0000 +5341:010001000100010001000100FFFE010001000100010001000100010001000100 +5342:00007FF004100410041004100410FFD0041004100412040A040A040604020400 +5343:001000F83F000100010001000100FFFE01000100010001000100010001000100 +5344:084008400840084008400840FFFE084008400840084008400840084008400840 +5345:101011101110111011101110FFFE111011101110111011101110211020104010 +5346:020002003FE00420042008221022211E41000100FFFE01000100010001000100 +5347:012007A03C200420042004200420FFFE04200420042008200820102020204020 +5348:0800080008001FF811002100410001000100FFFE010001000100010001000100 +5349:0100010001007FFC01000100092008200820FFFE082008201020102020204020 +534A:0100210811080910092001003FF8010001000100FFFE01000100010001000100 +534B:0100010001007FFC01000100092008200820FFFE08200820082008200FE00820 +534C:201024902490249024902490FFFE249024902490249024902490249024902010 +534D:00043F84008400840084008400843FFC2084208020802080208020FE20002000 +534E:08800888109030E0518096841084107C11000100FFFE01000100010001000100 +534F:2080208020802080FBF020902090229822942492289220902110211022502420 +5350:200021FC210021002100210021003FFC01040104010401040104FF0400040000 +5351:020004003FF8210821083FF8220822083FF808801080FFFE0080008000800080 +5352:020001007FFC0820082008201450228801000100FFFE01000100010001000100 +5353:010001FC010001001FF010101FF010101FF011100100FFFE0100010001000100 +5354:2040204023FC2084F88421142208201024102FBE24922492249228A22AAA3144 +5355:1010082004403FF8210821083FF8210821083FF801000100FFFE010001000100 +5356:010001003FF8010001007FFC04040288128008800900FFFE0240042018106008 +5357:01000100FFFE010001007FFC482444444FE4410441045FF44104410441144008 +5358:2208110811103FF8210821083FF8210821083FF801000100FFFE010001000100 +5359:22102210FF9022103E1022103E7E22102210FFD040105210611040107F900010 +535A:205020482FFE204027FCFC4427FC244427FC244420082FFE2208210821282010 +535B:210447C88812F3BC20084B92F83E0380AAAAABAA01000100FFFE010001000100 +535C:0200020002000200020002800240022002100210020002000200020002000200 +535D:084008400840084008400840F87E084008400840084008400840084008400840 +535E:0200010001000000FFFE02000200024002200210021002000200020002000200 +535F:004000407C4044404440446044504448444444447C4044400040004000400040 +5360:01000100010001FE01000100010001003FF8200820082008200820083FF82008 +5361:0200020003F8020002000200FFFE020002000240022002100208020002000200 +5362:0100010001FC010001001FF81008100810081FF8100810002000200040008000 +5363:0100010001FE010001003FF8200820083F88208820883F88200820083FF82008 +5364:0100010001FE010001003FF8200824482288210822882448282820083FF82008 +5365:0100010001FE010001003FF8200829282528224825482888214822283FF82008 +5366:0840084008407F4008400860FFD0084808447F440840084008400FC0F0400040 +5367:00207FA04820482048207F304128412441227F224820482048207FA000200020 +5368:0100010001FC01001FF010101F9010907FFC40044FE4482448244FE440144008 +5369:000003F802080208020802080208020802080208022802100200020002000200 +536A:000003F802080208020802880248024802080208022802100200020002000200 +536B:00007FF8020802080208020802080208022802100200020002000200FFFE0000 +536C:0000060078FC408440844084408440844084408440844EA87090008000800080 +536D:00000000FEFC10841084108410841084108410841E84F0A84090008000800080 +536E:007C3F80200020003FFE2000200027F024102410245024242404440443FC8000 +536F:0C0070FC44844484448444844484448444844C8474A804900880088010802080 +5370:0000060078FC4084408440847E8440844084408440844EA87090008000800080 +5371:040004000FF0101020205FFC100013F012101210125012202204220441FC8000 +5372:000000007F7C1144114421442544424480443F4421442154214821403F402140 +5373:00007E7C424442447E44424442447E444044484444544A485240604000400040 +5374:08000800087C7F44084408440844FFC41044104424444254FF48414000400040 +5375:0C0070FC4484448464A454945494448444844C8474A804900880088010802080 +5376:100010003E7C4244A444184410442444C8441F442144D2540C4808403040C040 +5377:0100111009203FF8020002007FFC082010102FE8C826082008A80848080807F8 +5378:200020003F7C4844884408447F44084408442E44284428542F48F04040400040 +5379:08000800107C7F445544554455445544554455445544555457C8FC4000400040 +537A:1FC000447D88055009203118C50602003FF800001FF010101050102410040FFC +537B:14001200217C49440844144422444144BE4422442244225422483E4022400040 +537C:0080FC8029F82A082DFE2900297829482968295029442A442C3C480247FE8000 +537D:080010007E7C42447E4442447E440044404440447E44405440484C4070400040 +537E:00007700557C5544774400447F440044FFC420443F440154014801400A400440 +537F:080073DE42524A524A524BD24A524A524A525BD26A124A9A125412B023104210 +5380:080008007F7C1C442A44494414442244494488442A441C542A48C94028401040 +5381:0808144822285C8888487F0E08F82A08490818087FFC01040114010801000100 +5382:00003FFE20002000200020002000200020002000200020002000400040008000 +5383:040004000FF0101020205FFC1000100010001000100010002000200040008000 +5384:00003FFE2000200027F024102410241024102450242024042404440443FC8000 +5385:00003FFE2000200020002FFE2040204020402040204020402040404041408080 +5386:00003FFE20002080208020802FFC208420842104210422042204440448289010 +5387:00003FFE2000201020F827802080208020FE3F802080208220824082407E8000 +5388:00003FFE200020002FFC20802080208020803FFE208020802080408040808080 +5389:00003FFE200020002FFE2100210021F821082108210822082208440848509020 +538A:00003FFE2000200027FE201022102210241027FE20502090211042104C508020 +538B:00003FFE200020802080208020802FFC2080208020902088208840805FFE8000 +538C:00003FFE200020802090208820802FFC20802140214022202220441048089006 +538D:00003FFE2000208020802FFC21002240244027FC204020404FFE404080400040 +538E:00003FFE20002000203C27C024402440244027FE242024202412450A46468422 +538F:00003FFE20002200220023FE2480248028FC3080208020FC2080408040808080 +5390:00003FFE20002220221022002FFC22402240224824502460484248C2933E2000 +5391:00003FFE200020202FA028A228A428A828B028A028A028A22FA248A2401E8000 +5392:00003FFE20002100210023FC2240244020403FFE204024442444444447FC8004 +5393:00003FFE2040204027FC204020402FFE20002040204027FC204040404FFE8000 +5394:00003FFE2000200027FC20802110220827FC2044204027FC204040404FFE8000 +5395:00003FFE20002F8428A428A42AA42AA42AA42AA42AA422242504448448949008 +5396:00003FFE241024083FFE249024A024C8249024A424C8249228E24982567EA000 +5397:00003FFE2080204027FC2000211020A02FFE2040204027FC2040404040408040 +5398:00003FFE200027FC2444244427FC2444244427FC2040204027FC404040408FFE +5399:00003FFE204020402FFC204027FC244427FC244427FC20402FFE404040408040 +539A:00003FFE200027F8240827F8240827F8200027F8201020202FFE404041408080 +539B:00003FFE2000200C2F70294029402940297E2948294829482F48408840888108 +539C:00003FFE2000203827C0204027FC224822482FFE224822482FFE4040404087FC +539D:00003FFE221022102FFC221022103FFE200027F82408240847F84408840807F8 +539E:00003FFE2120212021203F3E212021202F3C212021203F3E2120412041208120 +539F:00003FFE2080210027F02410241027F02410241027F020802490488852848100 +53A0:00003FFE20002F84288428A42FA428A42FA428A428A42FA42024490448949088 +53A1:00003FFE2080210027FC240427FC240427FC2040274421682250444859468080 +53A2:00003FFE22002200227C2F442244267C27442AC42A7C324422444244427C8244 +53A3:00003FFE20A020903FFE21402630380E2FF828882FF828884FF8488880800080 +53A4:00003FFE2000230C2E70221022103FFE2210273826B42A542A52529042108210 +53A5:00003FFE2000289025102FBE222222442A902A902F9022104228442884440882 +53A6:3FFE20003FFC210027F8240827F8240827F8240827F8220047F84A0881F01E0E +53A7:00003FFE20802FFC208027F8240827F8240827F8240827F824087FFE42108408 +53A8:00003FFE20083F8820082F08297E290829082F4820282908260843885C288810 +53A9:00003FFE20002F7E291029102F502950297E2F1028282A2829284B4A4D4A8886 +53AA:00003FFE21102FFE211021F0204027FC244427FC20402FFE204047FC40408FFE +53AB:00003FFE221022102F90221E2FA422243FD4241427942488248848944AA49142 +53AC:3FFE200027F8240827F8240827F8222027B02D2827FE380047F8440887F80408 +53AD:00003FFE20102F9428922F9028FE2F9020102F9028902F9028A84FA848C48982 +53AE:00003FFE2900290C3FB0292029202F3E29282F28292829285FA840488A881108 +53AF:00003FFE221022103FFE27182AB4325222102210208024442452441243F08000 +53B0:00007FFE420852484A504A9E5FE4505457545554554857485048515450948022 +53B1:00003FFE204020A0211022082DF6200027BC24A424A427BC211042A844448882 +53B2:00003FFE21102FFE211023F8224823F8224823F8204027FC245445F44414840C +53B3:1104088408883FFE20002710211E2FD424A427942494278824E85F9440A480C2 +53B4:3FFE28882F8A20082FBE28882F88289429A2200027FC244427FC444447FC8040 +53B5:3FFE20802FF828082FF844904A8881007EFE48905EBC52A45EBC48906AD49930 +53B6:0200020002000200040004000400080008401020101020107FF8200800080000 +53B7:020002000200FFFE0400040004400840088010801100221044088FFC04040004 +53B8:080808080808080808081010101010102020242424244242FEFE424202020000 +53B9:020002003FE002200220042004220822311EC10002000420081010083FFC1004 +53BA:010001000100FFFE0280044009203118C20602000420081010083FFC10040004 +53BB:0100010001003FF80100010001000100FFFE020002000400082010103FF80008 +53BC:020002000400082010103FF81108010009200910110821044104010005000200 +53BD:020002000400082010103FF80008101010101010202024244242FEFE42420000 +53BE:00007FF00410041004103F90041004107FD0041008101112208A7FCA00460002 +53BF:00001FF0101010101FF0101010101FF010101010FFFE0400082010103FF81008 +53C0:01000100FFFE01003FF8210821083FF8210821083FF80400082010103FF80008 +53C1:0200044008201FF002007FFC0820101027C8C00600000FE0000000003FF80000 +53C2:0200044008201FF002007FFC082010902308CC4601800610182000C007007800 +53C3:040008201FF0102024487EFC010006C018B0E30E0C403190062038C007007800 +53C4:040008201FF0102024487EFC010006C01830E00E0FE000001FF000007FFC0000 +53C5:040008201FF0102024487EFC010006C01830E20E02201290124822480A000400 +53C6:000E03F078440224010803FEFE42104013FE208028FC4544FD28421004680186 +53C7:00100210797C001400FE0014FB7C21922154413851544992F930490002FE0400 +53C8:00003FF01010101010200820082004400440028001000280044008203018C006 +53C9:00003FF01010121011200920082004400440028001000280044008203018C006 +53CA:00003FE008200820084008400CF80A080A080910111010A0204020A043188C06 +53CB:020002000200FFFE040004000FF00A1012101120214040808140062018186006 +53CC:00000000FDFC0484448444842888288810501050282028204450448881040202 +53CD:001000F83F00200020003FF8240824102210222021402080414042208C183006 +53CE:0400040045FC448444844484448844884C505450642044200450048805040602 +53CF:020002003FF0021002100210FFFE020002003FF010100820044003801C70E00E +53D0:00FC3F00010001007FFE0200040007F80A080A08111020A0404080A003180C06 +53D1:01001110110822003FFC0200040007F80A080908111010A0204040A003181C06 +53D2:00003FF000201E40018006601818E00400003EF8028822881450082034D8C306 +53D3:01000100FFFE01003FF8210821083FF801003FF010100820044003801C70E00E +53D4:080008000EFC084408440844FF440028082808284A1049108928084828841102 +53D5:00003EF8020822881450082034D0C30800003EF8028822881450082034D8C306 +53D6:0000FF8022FC22443E44224422443E442228222827A8FA104210022802440282 +53D7:0008007C3F88110808907FFE400280043FF0082004400280010006C01830E00E +53D8:02000100FFFE044014502448444400003FF0082004400280010006C01830E00E +53D9:0800080014FC22444144BE44084408287F2808282A1029104928884828841102 +53DA:00003E7C2204220422043E7C200020003EFC204420443E282010202820C42302 +53DB:1008101C95E0590011007DFC11441144FF441128112811102110222842448482 +53DC:020001007FFE4112912422C00430180CE0023FF010100820044003801C70E00E +53DD:100010FC108410847C941088108010FCFEA410A410A824A84290FEA842C40082 +53DE:00007F00417C41247F2440245F24402840287FA84410551094A8A4A814440882 +53DF:010005003978210821083D78210821083FF801003FF00820044003801C70E00E +53E0:1FE0044003800C407EFC22441C3862440000FFFE90121FF010101FF01010FFFE +53E1:10001F00107CFFA480A47F242A245528A2287F28A2903E1022283E2822443E82 +53E2:24481450FFFE08207FFC01003FF80100FFFE22003EFC22443E282390FE2802C6 +53E3:000000003FF820082008200820082008200820082008200820083FF820080000 +53E4:0100010001000100FFFE0100010001001FF0101010101010101010101FF01010 +53E5:0800080010001FF8200840089F8810881088108810881F881088000800500020 +53E6:00001FF01010101010101FF0020002007FF80208040804080808100820504020 +53E7:00001FF01010101010101FF0000000007FF8040804080808080810082050C020 +53E8:000000007DFC44444444444444444444444444447C4444840084010402280410 +53E9:000000FC7C8444844484448444844484448444847C9444880080008000800080 +53EA:00001FF01010101010101010101010101FF01010000008200810100820044004 +53EB:000400047C8444844484448444844484448C44B47CC444840004000400040004 +53EC:00007FF804080408080808081050202040009FF810081008100810081FF81008 +53ED:000000207920492049204920492049204920491079104A100208040808041002 +53EE:000000007BFE4820482048204820482048204820782048200020002000A00040 +53EF:00007FFE001000101F10111011101110111011101F1011100010001000500020 +53F0:0200020004000820101020087FFC200400001FF010101010101010101FF01010 +53F1:004000407C4044424444444844504460444044C07D40444200420042003E0000 +53F2:0100010001003FF82108210821083FF82108010011000900060005801870E00E +53F3:020002000200FFFE04000400080008001FF8280848088808080808080FF80808 +53F4:020002003FE00220042004220822301EC0001FF010101010101010101FF01010 +53F5:00007FFC40004000400047F0441044104410441047F04410400040007FFE0000 +53F6:0020002078204820482048204BFE482048204820782048200020002000200020 +53F7:00001FF01010101010101FF00000FFFE080010001FF000100010001000A00040 +53F8:00003FF8000800087FE8000800081F8810881088108810881F88108800280010 +53F9:000007F87A084A084A0849104910491048A048A07840484000A0011002080C06 +53FA:020001007880488048404840484048A048A048A0791049100208020804040802 +53FB:00400040784048404BFC48444844484448444884788448840104010402280410 +53FC:000003FC780448044804481448244844488449044A0478044804000400280010 +53FD:000001F0791049104910491049104910491049107A104A1202120412040E0800 +53FE:00003FF800600180010001000100050002001FF010101010101010101FF01010 +53FF:000000007DFC44204420442044204420442044207C2044200020002003FE0000 +5400:0008003C7DE0442044204420442047FE442044207C2044200020002000200020 +5401:000001FC782048204820482048204BFE48204820782048200020002000A00040 +5402:02000100FFFE1000100010001FF8000000001FF010101010101010101FF01010 +5403:00800080790049FE4A004C0049F8480848104860788049000202020201FE0000 +5404:040004000FE0082014402280410006C01830E00E1FF01010101010101FF01010 +5405:000000007EFC4284428442844284428442844284428442847EFC428400000000 +5406:00200020784048404884488449084BF849104810782048400088010403FE0102 +5407:000003F8780848104820484048404FFE48404840784048400040004001400080 +5408:010001000280044008203018CFE6000000001FF010101010101010101FF01010 +5409:010001000100FFFE0100010001003FF8000000001FF01010101010101FF01010 +540A:00001FF01010101010101FF0010001003FF82108210821082128211001000100 +540B:00100010781048104BFE48104810481049104890789048100010001000500020 +540C:00003FFC200420042FF42004200427E424242424242427E42424200420142008 +540D:0200020007F00810142062400280010006001FF8E8080808080808080FF80808 +540E:001000F81F00100010001FFE10001000100017F8140824082408440887F80408 +540F:01000100FFFE010001003FF82108210821083FF811000900060005801870E00E +5410:0040004078404840484048404FFC48404840484078404840004000400FFE0000 +5411:0200040008007FFC4004400447C4444444444444444447C44444400440144008 +5412:0008003C7BC04840484048404840487E4BC048407840484200420042003E0000 +5413:000007FE78404840484048404850484848444844784048400040004000400040 +5414:0020002078204920492C493449644BA449244934792849220122010200FE0000 +5415:00001FF010101010101010101FF0000000003FF820082008200820083FF82008 +5416:0000020279044888485048204820482048204820782048200020002000200020 +5417:000003F07810481049104910491049FC4804480478044BF40004000400280010 +5418:00800080788049FC49204A20482048204BFE4820782048200020002000200020 +5419:00400040784048404A444A444A484C50484048A078A049100110020804040802 +541A:000003F87888488848884FFE4888488848884BF8788848800100010002000400 +541B:00003FF804080408FFFE040804083FF8080008001FF81808280848088FF80808 +541C:000003F8788848884888488848884FF849084908790849080108010807FE0000 +541D:020001007FFC0820044003800C603018C0061FF010101010101010101FF01010 +541E:00003FF801000100FFFE0280044008203018DFF610101010101010101FF01010 +541F:0040004078A048A049104A884C46484048004BF8780848100010002000200040 +5420:004000507848484848404FFE4840484048A048A048A079104910020804040802 +5421:002002207A204A224A224A244BA84A304A204A207A204A2202A20322021E0000 +5422:01000080088848044812481287F0000000001FF810081008100810081FF81008 +5423:00000040F0209010909090809080928492829282F28294880088008800780000 +5424:0040004078A048A049104A084C06491049104910791049100110021002100410 +5425:000000007BFE48104810482048204868486448A479224A220420002000200020 +5426:00007FFC008001000300056009183104C10200001FF01010101010101FF01010 +5427:000003F87A484A484A484A484A484BF84A084A007A004A020202020201FE0000 +5428:0040004078404BFC48404A484A484A484A484BF87848484000420042003E0000 +5429:0010009078904888490849044A044DFA48884888488878884908010802280410 +542A:00A000A078A0492449244B284D304920496049A07920492201220122011E0100 +542B:01000100028004400A203118C1060FE0004000801FF01010101010101FF01010 +542C:0008001C79E049004900490049FE491049104910791049100110021002100410 +542D:0080004078404FFC4800480049F04910491049107910491202120212040E0800 +542E:00800080790049104A084FFC48044920492049207920492002220222041E0800 +542F:010000801FFC1004100410041FFC10001000100017FC24042404440487FC0404 +5430:00400040784048404BFE4840488048904890492079204A480244048401FE0082 +5431:0020002078204BFE48204820482049FC48844888784848500020005001880606 +5432:000403E478244824482449E4490449044A044BE4782448240024002401440084 +5433:000007E00420142017E0100010001FF001100110FFFE0280044008203018C006 +5434:00001FF0101010101FF0000000003FF801000100FFFE0280044008203018C006 +5435:004000407840494849444A424A424C4848484848781048100020004001800600 +5436:004000200020FBFE8A228A228A328A4A8A4A8A86FB068A0202020202020A0204 +5437:0040004078404BF848484848484848484FFE484078A048A00110011002080406 +5438:000007F87908491049104920493C490449044A887A884A500420045008880306 +5439:00800080788048FC490449084A404C40484048A078A049100110020804040802 +543A:000001F07910491049104A0E4C004BF849084910789048A0004000A003180C06 +543B:01000100790049FC4AA44CA448A4492449244A447C4448840104020404280010 +543C:001007D078504890491049104950499049104F107910491201120112050E0200 +543D:002000207920492049FC49204A20482048204BFE782048200020002000200020 +543E:00007FFC020002003FF0041004100810FFFE00001FF01010101010101FF01010 +543F:0100110011001FF8210041000100FFFE010001001FF01010101010101FF01010 +5440:000003FC78104910491049104A104BFE48304850789049100210041000500020 +5441:00400040788048FC49044A044884484448444814482478444984000400280010 +5442:00001FF010101010101010101FF0020004003FF820082008200820083FF82008 +5443:000003FE7A004A004AF84A884A884A884A884AA87A904A8204820482087E1000 +5444:00003FE00420047C0804101461080100FFFE010001003FF8200820083FF82008 +5445:0080004078404FFC4910491049104910491048A078A0484000A0011002080C06 +5446:00001FF01010101010101FF0010001007FFC03800540092011102108C1060100 +5447:010001047D880550092011102108C50602001FF010101010101010101FF01010 +5448:00001FF01010101010101FF0000000007FFC010001003FF801000100FFFE0000 +5449:000007E00420142017E0100010001FF000100010FFFE00000440082010102008 +544A:0100110011001FF8210041000100FFFE000000001FF01010101010101FF01010 +544B:0040004078404BFC4840484048404FFE484048A078A049100110020804040802 +544C:001001107890489048104910489048904810481E7BF048100010001000100010 +544D:0000000079FC4800480048004BFE48204820484078404888010403FE01020000 +544E:000001FC790449044904490449FC492449204920791049100208020804040802 +544F:000800687B8848884888488848884BFE48884888788848880108010802080408 +5450:0040004078404BFC4A444A444A444A444AA44A947B144A040204020402140208 +5451:001000F83F00010002007FFC044008203018C0061FF01010101010101FF01010 +5452:000003FC78404840484048404FFE484048A048A078A0492001220222041E0800 +5453:009000907BFE4890489048004BF8481048204840788049000202020201FE0000 +5454:00400040784048404FFE4840484048A048A048A0791049100288024804440802 +5455:000003FC7A004A084A884A504A504A204A204A507A504A880308020003FE0000 +5456:000003FE7A004A204A204A204AFC4A244A244A247A444A440484048409281210 +5457:000001FC79044904492449244924492449244924792448500048008401020602 +5458:00001FF0101010101FF000003FF82008210821082108210822C8043018086004 +5459:00001FF01010101010101FF0010001007FFC4104428444444824400440144008 +545A:004000407C40448044FE450846884488448844507C5044200050008801040202 +545B:0040004078A048A049104A084C0649F049104910795049200104010400FC0000 +545C:0020004079FC49044904490449144908490049FE7802480203FA000200140008 +545D:0040002079FC4904490449FC49004900497C49087910492001420282027E0400 +545E:000001FC780448044BF44804480449F449144914791449F40004000400140008 +545F:0080004078404BFE48404840488849084BF0482078404888010403FE01020000 +5460:00400040784048404FFC484048E048E0495049504A487DF44842004000400040 +5461:000003FC7A044A044A044BFC4A204A204BFE4A207A204A100212028A03060202 +5462:000003FC7A044A044A044BFC4A004A404A444A487A704A4004420442083E1000 +5463:000001F8790849484928490849084FFE4A084A887A484A0803FE000800500020 +5464:0040004078A048A049104A484C2648204BF848087810491000A0004000200020 +5465:0040004078404BF84A484A484BF84A484A484A484FFE7A084A08020802280210 +5466:002001207120522052FC54A4572451245224522474A447A400C4004400940108 +5467:0008003C7BE04A204A204A204A204BFE4A204A107A104A12020A028A03260212 +5468:00003FF8210821082FE8210821083FF8200827C82448244827C8400840288010 +5469:000001FC7800480048004BFE48204820492849247A244A220422002000A00040 +546A:000003FC7A044A044A044A044BFC4890489048907890491201120212040E0800 +546B:0020002078204820483E48204820482049FC4904490479044904010401FC0104 +546C:000000007BFC4A944A944A944A944A944A944A944A9C7B044A04020403FC0204 +546D:004802487A484A484A484FFE4A484A484A484A487A784A000200020003FE0000 +546E:0000000079FC4904490449044904490449FC4904780048900088010402020402 +546F:000001FC78204820492448A448A848204BFE4820782048200020002000200020 +5470:0440044024442758246024422F42F03E40001FF010101010101010101FF01010 +5471:0008003C7BD04A904A904A904A904A904A904A887A884AC802A404D404920800 +5472:0090009078904A904A924AD44A984A904A904A907A904A9203D20E12040E0000 +5473:0040004078404BFC4840484048404FFE48E0495079504A480444084200400040 +5474:00800080790049FC4A044C0449E449244924492479E449240004000400280010 +5475:000000007BFE4808480849E8492849284928492879E849280008000800280010 +5476:02000200E27CA224AFA4A4A4A4A4A4A8A4A8A928E510A2100528094810840102 +5477:000007FCF4449444944497FC94449444944497FCF44490400040004000400040 +5478:000003FC782048204840484048D049484A444C44784048400040000007FE0000 +5479:004000407A404A404BFC4A404C4048404FFE484078A048A00110020804040802 +547A:000001F879084908490849F848004BFE4880490079F848080008000800500020 +547B:0040004078404BF84A484A484A484BF84A484A487A484BF80248004000400040 +547C:0008003C7BE04820492448A448A848204BFE4820782048200020002000A00040 +547D:0100010002800440082037D8C00600003EF82288228822883EA8229000800080 +547E:0000000079FC49044904490449FC49044904490479FC49040000000003FE0000 +547F:00200020782049FC4820482048204BFE4820484078404888010403FE01020000 +5480:000001F879084908490849F849084908490849F8790849080108010807FE0000 +5481:01080108790849084FFE490849084908490849F8790849080108010801F80108 +5482:000003FE7A104A104A104AFE4A924A924A924A927A9A4A940210021003FE0000 +5483:0120012079204AA04AAC4EB44AE44BA44AA44AB47AA84AA202A20282027E0200 +5484:00200020792449244924492449FC4824482048207A224A220222022203FE0002 +5485:020001003FF8000008200440FFFE000000001FF010101010101010101FF01010 +5486:0080008079FC49044A044DF449144914491449F4790449280112010200FE0000 +5487:00000040782048284808488848904A944AA24AA27CC248880188028804780000 +5488:0090009078904BFC489448944BFC4A904A904BFE78924892011A011402100410 +5489:0040004078404BF84A484A484A484A484A484FFE784048A000A0011002080406 +548A:003803C07840484048404FFC484048E048E0495079504A480444084200400040 +548B:01000100790049FE4A804A804C8048F848804880788048FC0080008000800080 +548C:04000E007800087C0844FF44084418441C442A442A444844887C084408000800 +548D:002000207840488849044BFE4802480049FC4904790449040104010401FC0104 +548E:104010401E502248224454440840144023FEC0001FF01010101010101FF01010 +548F:00400020781049E0482248344BB848B048A848A8792849240224042200A00040 +5490:0088008878884908497E4B084D08494849284928790849080108010801280110 +5491:01000100793E49084FC849084908494849884F08790849080108010805280210 +5492:00007CF84488448844887CF8000000000FC0084008400840104010422042C03E +5493:000000007BFC4900490049F04910491049904A507A504A10021202920312020E +5494:004000407840487C4840484048404FFE48404840785048480044004000400040 +5495:00200020782048204BFE48204820482049FC4904790449040104010401FC0104 +5496:04000400F400943C9FA494A494A494A494A494A4F4A494A408A408BC12A42100 +5497:00400040784048404BFE48404880488048FE491079104A100210041001FE0000 +5498:0040004078404BFE488048A0492049FC4B244D24792449240134012800200020 +5499:00900088788848804BFE48A048A048A448A449287928493202220262049E0800 +549A:0080008078F849084B104CA0484048A04B184C0678C048200010018000600010 +549B:0040002078204BFE4A024C04480048004BFE4820782048200020002000A00040 +549C:0040002078204BFE4A024C04490049084910492079C049020102010200FE0000 +549D:0108010871085210529454A457BC510851085210742057BC000000000FFE0000 +549E:000003FC789048904890489048904FFE48904890789048900110011002100410 +549F:000003FE78204820484049FC49044904490449FC490479044904010401FC0104 +54A0:00001FF0101010101FF000007FFC10101FF010101FF01010103EFFD000100010 +54A1:000003FE79084908490849F84908490849F849087908491E07E8000800080008 +54A2:00003EF8228822883EF800003FF80000FFFE040008000FF00010001000A00040 +54A3:004000447A444948495048404FFE4890489048907890489201120112020E0400 +54A4:0040002078204BFE4A024C0448384BC048404840787E4FC0004000420042003E +54A5:000003FE78204840488849044BFE4822482048207BFE48200020002007FE0000 +54A6:00400040F7FE904097FC904493FC9240944097FEF04290AA00A4011002080C06 +54A7:00040004EFC4A214A214A3D4A254A454A654A554E894A0940104020404140808 +54A8:4080208009FC12042448E04020A023182C0600001FF01010101010101FF01010 +54A9:01040084788848004BFE4820482049FC482048207BFE48200020002000200020 +54AA:004000407A484948495048404FFE484048E0495079504A480444084200400040 +54AB:00003E7C22442244224422443E7C2A002828282428442442248242004180807E +54AC:00800040F04097FC900091109208940491109110F0A0904000A0011002080C06 +54AD:0020002078204BFE4820482049FC4800480049FC790449040104010401FC0104 +54AE:00200120792049FC49204A2048204BFE487048A878A849240124022200200020 +54AF:0080008078F849084B104CA0484048A049184A067DF849080108010801F80108 +54B0:0080008079FC49044A0449E44924492449E44924792449E40104000400280010 +54B1:0020004079FC49044904490449FC49044904490449FC79044904010401FC0104 +54B2:02080108791048004BFC4840484048404FFE4840784048A000A0011002080406 +54B3:00400020F02097FE90409084910893F090229044F18896100020005001880604 +54B4:0040004078404BFE4880489048904912495249547A904A280428004400840102 +54B5:002000207BFE4850488849044AFA48004BFE4840788049FC0004000400280010 +54B6:0008003C79E0482048204BFE48204820482049FC790449040104010401FC0104 +54B7:0090009078904A9249944898489049984A944C9278904890011201120212040E +54B8:0050004800403FFE204020402F44204420442F28292829122F32494A40868102 +54B9:0040002078204BFE4A024C4448404BFE48884888790848D00020005000880304 +54BA:000003FE7800480049FC4904490449FC4904490479FC49040000000003FE0000 +54BB:009000907890491049FE4B104D10493849384954795449920110011001100110 +54BC:00001FF0101010101F90109010907FFC400440044FE4482448244FE44004400C +54BD:000007FCF40494449444944497FC9444944494A4F49495140604040407FC0404 +54BE:0040004078444BF4484848504FFE4840488049844A987CE048820082007E0000 +54BF:0100017CF1249224922496FE9A2492249224927CF22492200220022002400280 +54C0:02000100FFFE000000001FF0101010101FF0028004440C283410C50806060400 +54C1:00001FF010101010101010101FF0000000007C7C44444444444444447C7C4444 +54C2:000007FE7890489048904BFC4A944A944A944A947A9C4B040204020403FC0204 +54C3:000003FC7A044A044AF44A044A044AF44A944A947A944AF40204020402140208 +54C4:01100110791049104BFC49104910491049104FFE780049100108020804040804 +54C5:01000100790049FE4A024A024D1248A24A4A4AAA7B1A4A0A03FA000200140008 +54C6:00800080F1F89210952090C0909093209C7C9084F10896900060004001800E00 +54C7:0020002079FC4820482048204BFE48004820482079FC48200020002003FE0000 +54C8:0040004000A0F8A089108A088C0689F4880088008BF8FA088A08020803F80208 +54C9:0840084808447F4408400840FFFE004000443E442228222A22123E2A22460082 +54CA:00400040F7FE9080910091FC9304950499FC9104F10491FC0104010401140108 +54CB:021002507250525C5F7452D4525452545254525C725053520E420442003E0000 +54CC:0008003CF7C09400941C95E09520952295249528F51095100508094409821100 +54CD:0040004078804BFC4A044A044AF44A944A944A947A944AF40204020402140208 +54CE:011001107BFC4910491048004A084A084910491078A0484000A0011002080C06 +54CF:000003F87A084A084BF84A084A084BF84A444A487A304A200210028803060200 +54D0:000003FE7A004A004BFC4A204A204AF84A204A207A204BFC0200020003FE0000 +54D1:000003FC78904890489048924C924A944A944A98789048900090009007FE0000 +54D2:001002107910491048FE48104B104928492449447942498201000280047E0000 +54D3:0080008078BC4BC04850482448D44B0C48004BFE7890489001120112020E0400 +54D4:01100112791449D8491049124952498E492048207BFE48200020002000200020 +54D5:002001247924492449FC4840484048FC49044A84784848500020004000800300 +54D6:0080008078FE49104A10481048FC4890489048907BFE48100010001000100010 +54D7:00900094791449184B104D324952490E492048207BFE48200020002000200020 +54D8:00800080793C4A004C804880497E4B084D084908790849080108010801280110 +54D9:0040004078A049104A084C0649F0480048004FFC784048800110020807FC0204 +54DA:000001F079104910491049104A4E4C404BFC484078E049500248044600400040 +54DB:00807C8844B044C444847C7C00000440082010102FE8C4260420082010A06040 +54DC:004000207BFE490448884850482048D84B064888788848880088010801080208 +54DD:00400040F04097FC948498889140914493489530F92091100108014401820100 +54DE:00400040789049084BFC48244920492049FC4A2078204FFE0020002000200020 +54DF:02200220F220943C95449F449284922494149F94F404900401840E0404280010 +54E0:00200120792049FE4A204C2048204BFE4800480079FC49040104010401FC0104 +54E1:00001FF0101010101FF000003FF820083FF820083FF820083FF8082010102008 +54E2:000003FE7820482049FC482048204BFE488848887BFE48880088010801080208 +54E3:000003FC7800480049F849084908490849F84800790848880090000007FE0000 +54E4:0110010879004FFE494849504964494849504A647A484A520462044209BE1000 +54E5:00007FFC00101F90109010901F900000FFFE00101F90109010901F9000500020 +54E6:002801A4F724912091209FFE9120912491A49328FD2891100112012A05460282 +54E7:0020002079FC4820482048204BFE48484848494C794A4A4A0088008801280210 +54E8:0020012478A448A8482049FC4904490449FC4904790449FC0104010401140108 +54E9:000007FCF444944497FC9444944497FC90409040F7FC9040004000400FFE0000 +54EA:00000FDE72525252525457D45258525452525FD27252525A0254045005500890 +54EB:000001FC79044904490449FC482048204920493C7920492002A00260043E0800 +54EC:0100010079FE4A044A044EF44A944A944A944A947AF44A940204020402140208 +54ED:00003C782448244824483C78000001100108FFFE01000280044008203018C006 +54EE:004000447BF4484848484FFE482048404BF849107A204DFE0820002000A00040 +54EF:000001FC7904490449FC4904490449FC4904490479FC4850009000920112020E +54F0:004000207BFE4A024C24492049FC49204A2048207BFE48200020002000200020 +54F1:002000207BFE482048204BFE4A024C0449F8481078204BFE0020002000A00040 +54F2:080C08F07E8008800EFE788808882908120800001FF01010101010101FF01010 +54F3:0208021C726052405FC05240527E52C853485E4872485248024802480A880508 +54F4:008000407BF84A084A084BF84A084A084BF84A407A444A280210028803060200 +54F5:000203E27A224A2A4A2A4BEA490A490A4BEA492A792A492A0222022204AA0844 +54F6:0088008878884B8E48884888480049FC482048207BFE48200020002000200020 +54F7:0008003C7BC048444A244928490048104BFE4810791048900090001000500020 +54F8:0008003C7BC048444A244928490048404BFE488879084B900060005001880604 +54F9:0008003C7BC048044A44492848004BF8481048204FFE78204820002000A00040 +54FA:00480044F7FE9040904093FC9244924493FC9244F24493FC0244024402540208 +54FB:000001FC790449FC490449FC4800480049FC482078204BFE0020002000200020 +54FC:004000207BFE480049F84908490849F848004BFC780848300020002000A00040 +54FD:000007FEF04097FC9444944497FC9444944497FCF24091400080014002300C0E +54FE:010400847888481049FC49044904490449FC48507850489000920112020E0400 +54FF:080008007F7C114411442544427C0000FFFE00101F90109010901F9000500020 +5500:001C01E0782048204BFE48A849244A2249F84888789048BE0102010202140408 +5501:004000207BFE4800480049FC4800480049FC4800780049FC0104010401FC0104 +5502:01100108F2049444904090A0911092089C0693F8F20892080208020803F80208 +5503:010001007BF84A084C104BFC4A444A444BFC4A447A444BFC0244044404540808 +5504:000001FC7904490449FC4904490449FC4904490449FC78004888008401020202 +5505:0040004078A049104A884C4649F04810482048407BF84A080208020803F80208 +5506:00400040788849044BFE4802488849444A4248F879884A500020005001880606 +5507:00003FFC20002FF820003FFE248824502530260E20002FF8480848088FF80808 +5508:000001F87908490849F848004BFC4A444A444A447BFC4A000202020201FE0000 +5509:00400080F110920897FC9104910093F8944090409FFEF04090A0011002080C06 +550A:0020002078204BFE482048204924492449244AAA782048500050008801040202 +550B:002000207850488849044AFA482048204BFE4820792849240222042200A00040 +550C:0004000E7BB8488848884928492E4BA848A84AA87AA8493E01000280047E0800 +550D:004000207BFE4A024C0449F8480048004BFE48907890489001120112020E0400 +550E:004200E27B82488A488A488A4FEA488A498A49CA7AAA4A8204820082008A0084 +550F:01840068783048C84B0448404BFE48A049204BFC7D2449240134012800200020 +5510:010000803FFE20802FF820883FFE20882FF820802FF82808480848088FF80808 +5511:00400040F24892489248955498E29040904097FCF0409040004000400FFE0000 +5512:00000FFEF0A090A097FC94A494A494A4951C9604F40497FC0404040407FC0404 +5513:002000207BFE482049FC4924492449FC4924492449FC78204BFE002000200020 +5514:000007FCF040904093F89088908897FE90009000F3F892080208020803F80208 +5515:0020004079FC4904490449FC4904490449FC482078204BFE0020002000200020 +5516:000003FC7890489048904BFC4A944A944A944A947BFC48900090009007FE0000 +5517:0020002079FC4820482048204BFE482048204920793C492002A00260043E0800 +5518:0000FEFC104420443E286210A2283E44228200001FF01010101010101FF01010 +5519:001008907510521255525954515851905310552879285128014801440A840502 +551A:000001FC780448FC480449FC48004BFE4A0249F8788848880050002000D80306 +551B:00400040F7FC904093F8904097FE908090F89108F31094A0004000A003180C06 +551C:010001007FFC01003FF8054009203118C10600003E442258226022423E42223E +551D:000001FC782048204BFE4800480049FC49044924792449240154008801040602 +551E:01040124791449144FC449244914495449864F3C790449040104010405040204 +551F:010001003FF801000100FFFE040008201FF000103E442258226022423E42223E +5520:008800887BFE488848004BFE4A024C4448404BFC784448840084010402280410 +5521:000003FE7850485048504BFE4A524A524A524AAA7AA64B0202020202020A0204 +5522:0020012478A448A8482049FC4904492449244924792449240050008801040202 +5523:0020004079FC4904490449FC4904490449FC48407840487E07C000420042003E +5524:01000100F1F0921094209BF89248924892489248F7FE90A000A0011002080C06 +5525:001004107A284A2848444992490849084AFE4E027A044A440228021002080008 +5526:00100210791049104C544A524A524890481049147E044A0802080210022000C0 +5527:000007BC74A454A454A457A454A454A454A457A47434552804A0056006200020 +5528:000007BC74A455245524563C552454A454A454BC76A4552404240424047E0400 +5529:001C01E0782048204BFE48A849244A4248404BFE7888490800D0003000480184 +552A:00400040F7FC904093F8908097FC911092489446F1F0904007FC004000400040 +552B:0040004078A049104A084C0649F0484048404BF878404A48014801500FFE0000 +552C:00400040787C48404BFC4A444A704BC04A444A3C7A004AF0049004920912120E +552D:008800887BFE4888488848F84888488848F8488878884BFE0000008801040202 +552E:090008800FFC10803FF850809FF810801FFC00001FF81008100810081FF81008 +552F:00A00090788049FE49104B104DFC4910491049FC79104910011001FE01000100 +5530:000207E27422542A57EA548A548A548A57EA56AA76AA5AAA0AA212E2008A0084 +5531:01F80108790849F84908490849F848004BFC4A047A044BFC0204020403FC0204 +5532:000000407B9C4A044A044B9C4A044A044BFC489078904890009001120212040E +5533:004000207BFC4A044A044BFC4A004A284A244BFE7A204A500250048805040A02 +5534:02080108F11097FC9040904093F8904090809FFEF1209120022002220422081E +5535:004000807BFC49104A484C464BF84A484A484BF84A487A484BF800420042003E +5536:0088008878884BFE488848884FFE480049FC4904790449FC0104010401FC0104 +5537:004000207BFE488049044BFE480249FC490449FC790449FC0104010401140108 +5538:0040004078A049104A884C4648004BF048104820784049240522050A090800F8 +5539:0108008878084FD44A144A224A004BC84A444A447A404A500248044405440880 +553A:0090009078904BFC4A944A944A944BFC4A944A944A947FFE4800009001080204 +553B:0040004078404FFC48404A484A484A484D5448E0795049500248044408420040 +553C:008000407BFC4800490848904FFE484048404FFE788849080090006001980604 +553D:01000106F138912097A09120913E932493A49564F52499240124012401240144 +553E:00100078F3C09040904097FC9248924897FE9248F24897FC0040004007FC0000 +553F:01000100F3FC9494989491249244948491289210F0409124052A050A08F80000 +5540:000003FE7A104A104AFE4A104A104BFE4A004A107A104AFE0210041005FE0800 +5541:000007FCF444944495F49444944497FC940495F4F514951405F4040404140808 +5542:00E80F08E228A928A548A008A7C8A088A108A108E1E8AF08010A010A050A0206 +5543:00200120793C492049204FFE48004BFC4A044BFC7A044BFC0204020402140208 +5544:000003FE7840488049444A2448684AB049304AA8786848A40122022000A00040 +5545:00200020783E482049FC490449FC490449FC492448207BFE4820002000200020 +5546:020001007FFC082004403FF820082448282837D82448244827C8200820282010 +5547:020001007FFC082004403FF821082FE8210827C82448244827C8200820282010 +5548:0020002079FC482048204BFE4888485049FC482078204BFE0020002000200020 +5549:011001107110511057BC51105110533853B85554755459920110011001100110 +554A:00000EFCEA08AA08AAE8AAA8ACA8AAA8AAA8AAA8EAE8AAA80C08080808280810 +554B:0008003C7BC048444A244928490048204BFE487078A848A80124022204200020 +554C:0040002078204BFE4A024C9449084A04480049FC782048200020002007FE0000 +554D:004000207BFE480049FC490449FC480049FC480878104BFE0020002000A00040 +554E:200021FE20203E2049FC8844084409FEFE00080008FC08840884088408FC0884 +554F:00007CF844887CF844887CF8400840084FC8484848484FC84848400840284010 +5550:00800040F7FC90009110911092A8944490009040F7FE90400040004000400040 +5551:002000207BFE482049FC48244BFE482449FC48207920493E012002A0027E0400 +5552:000003FE7A024A024BFE4A104A924A924A924AFE7A104A920292049204FE0802 +5553:104008403E7E228823483E5020204058418680001FF01010101010101FF01010 +5554:104808443E7E23C022243E282212206A418680021FF01010101010101FF01010 +5555:0100010079FC4A044D0449E44A8448844FF448847AA44AA403E4000400280010 +5556:00400244F244944890A091109608904490409248F248945000A0011002080C06 +5557:0080008078F849084A104C0048404B9C4A044A047B9C4A040204020403FC0204 +5558:00800040F7FE94029A04920093BC94A494A496A4F9349128022202220422081E +5559:04400440244427582460244224422F42F03E00003E7C2244224422443E7C2244 +555A:00001FF0101010101FF00100FFFE02003FF8200827C8244827C820083FF82008 +555B:002000207BFE482049FC48244BFE482449FC48407BFE488401C8003000CC0302 +555C:000007BC708452945108529454A45840500057BC70A452A40128029004A80846 +555D:000001807700511E51125FD2511253125392535275525512091E011201000100 +555E:000007FE7890489048904B9C4A044A044A044B9C789048900090009007FE0000 +555F:082004203F20213E214421443F4420A420283F283110511051289F2811440082 +5560:060C3870204020403F7E244824482448448881001FF01010101010101FF01010 +5561:00900090F090979E909090909090939C90909090F090979E0090009000900090 +5562:000003FE782048204BFE4A224A224B324AAA4AAA7B764A6602220222022A0204 +5563:0400040077DE5912511251125FD25112511255D27512551A05D41E1008100010 +5564:004000807BFC4A244A244BFC4A244A444BFC489079104FFE0010001000100010 +5565:0040004078A049104A084DF6484048404FFC484078404BF80208020803F80208 +5566:012001107110517E57805104514451C4512453247528512801080110057E0200 +5567:002000207BFE482049FC48204BFE480049FC4904792449240124005000880304 +5568:002000207BFE482049FC48204BFE480049FC490479FC490401FC010401140108 +5569:01100110F7D09110911091189FF4901291129110F7D09110011001D00E100410 +556A:021002107220527C5FC45244524452C4537C5E4472445244024402440A7C0444 +556B:004000447BF4484848504FFE4840488049F84B087D0849F80108010801F80108 +556C:010001007FFC010011100920FFFE00003FF8200827C8244827C820083FF82008 +556D:0210021072105FBC52105510557E57905120513C71C45F080528011001080104 +556E:00400040F27C9240924092409FFE900094449444F4A494940514040407FC0004 +556F:000003FE7A024A024BFE4A224A224AFA4A224A327A2A4BFE0202020203FE0202 +5570:000003FE7A524A524A524BFE4820484048FC49047A8848500020004001800600 +5571:002001247924492449FC480048004BFE4840488078FC49840284048400FC0084 +5572:0088008879084BDE4A524A624A424A524BCA4A4A7A424A42024203C202540008 +5573:00400248F15097FC908091009FFE921094089BF4F212921002500224020401FC +5574:01040088785049FC4924492449FC4924492449FC7820482003FE002000200020 +5575:00100410721052FE58925494549052FC52A454A47CA854A80490052805440282 +5576:004000207BFE4A024C0448004BFE482048204920793C492002A00260043E0800 +5577:0100009E7BD24A524A544BD44A584A544BD24A127A924A5A02D4035002100010 +5578:004000407BF848484FFE48484BF848404A484A487AE84B580248024804480848 +5579:000003FC7A044A044BFC4A204A204BFE4A204A207AFC4A840284048404FC0884 +557A:000001FC790449FC490449FC48004BFE490049FE7A4A4C920122024200940108 +557B:01003FF8082004407FFE41029FF411101150112001003FF8200820083FF82008 +557C:0040002079FC4800488848504BFE4A224C2449FC492479244934012800200020 +557D:004000A079104A084DF648004BF84A084A084BF87910491007FC011002100410 +557E:008801C877085108512A512A57AC514853085388755455140914012401240142 +557F:008800887BFE488848F8488848F8488848884BFE790049480184010001FE0000 +5580:004000207BFE4A02488048F849084A90486049987E0649F80108010801F80108 +5581:01FC0124792449FC4924492449FC482048204BFE7A224A2A02FA020A02020206 +5582:000003F87A484A484BF84A484A484BF848004FFE7A404A440228029003080206 +5583:00400040F7FC9040904097FC951494A495F49444F44495F40444044404540408 +5584:082004407FFC01003FF801007FFC11100920FFFE00001FF0101010101FF01010 +5585:000001FC790449FC490449FC4904484048204BFE780049040088000007FE0000 +5586:101010101010FEFE101010107C7C000000007C7C44444444444444447C7C4444 +5587:0104010477C45104511457D45554555457D45114739455540944010401140108 +5588:022002247BA84A304AA24B224A5E48804BFC4A047A044BFC0204020403FC0204 +5589:010001787108520852FE56405A40527C5290521072FE52100228022802440282 +558A:00140012701057FE5410541055D05412541255D47554554805DA042A08461082 +558B:0048014879484BFE494849484978490049FE48207BFE487000A8012406220020 +558C:00007EFC428442847EFC00001008110811085548532891082108210841088108 +558D:009000927AD44A984A924AD24F0E482048204BFE787048A80124062200200020 +558E:000001FC7904490449E4492449244BFE4A024AFA7A8A4A8A02FA0202020A0204 +558F:01080108F7FE91089148904097FE9080910093FCF50499040104010401FC0104 +5590:0100011E77F25112521453D4525856545BD25252725253DA02540250025002D0 +5591:008000407BFC4800490848904FFE480049F84908790849F80108010801F80108 +5592:0088008879EC492A4A284D484888497E4E0049FC7904490401FC0104010401FC +5593:000003FE785048504BFE4A524A524BFE480048404FFE78884990006000D80304 +5594:000003FC7A044A044BFC4A004BFC4A404A884BFC7A244A2005FC0420082013FE +5595:000007FE784048804BFC4A944A944AF44A944A947AF44A940294029403FC0204 +5596:010801087108510857BE510853085388557E55227922512201220122013E0122 +5597:000003FE7A2248204BFE482049FC492449FC492479FC482003FE002000200020 +5598:00400444F444944497FC90009FFE9040908097FCF4A494A404A404A404A4040C +5599:010001F8F20893F0901097FE90809144966890B0F128966800A4012206A00040 +559A:01000100F3F09410982097FC940494A495149444F0409FFE00A0011002080C06 +559B:003C07C07A44492848004BFC488048804FFE490079F84A880250042008D80306 +559C:01007FFC01003FF800003FF820083FF80820FFFE00003FF8200820083FF82008 +559D:000003F87A084BF84A084BF849004BFC4C444A447AA44A0403F4000400280010 +559E:008001007BDE4A524A524BD24A524A524BD248127A5A4B940210025001D00010 +559F:000003FE7A224BFE4A224BFE480049FC490449FC790449FC0104010401140108 +55A0:0008003C79E048204BFE482049FC492449FC492479FC482001FC002003FE0000 +55A1:0040004079FC48844BFE480049FC490449FC48207BFE4820022003FE00200020 +55A2:0004001E7BE0482048204FFE482048A04B2E4A227A224BAE0222022203FE0202 +55A3:0100010079FC4A044C0449E44924492479E44804002800102488224442448004 +55A4:0020004079FC490449FC490449FC48004BFE4820782049FC0020002003FE0000 +55A5:004000207BFE4A484A484BFE4A484A784A004AFC7A444A480228041004680986 +55A6:00001FF0101010101FF000007D7C454445447D7C01002108210821083FF80008 +55A7:004000207BFE4A024C0449FC480049FC490449FC790449FC0104000003FE0000 +55A8:00800040F7FE900093F8920893F8900097FE9402F9F49110011002120412080E +55A9:01C000A079104A084DF648004BCA4A4A4A544BD47A684A5403D4024A024A02C0 +55AA:010001007FFC01003D7825483D780100FFFE1200111010A010401430180E1000 +55AB:0080009E7BEA488A49CA488A4BEA489248A648207BFE48200050008801040602 +55AC:00F83F000200FFFE04400FE03458C7C600003FF8200827C8244827C820282010 +55AD:004000207BFC4800490848904BFE4A104A204AC87A104A2402C8041004600980 +55AE:00007EFC428442847EFC00003FF821083FF821083FF80100FFFE010001000100 +55AF:002000207BFE485048A849244AFA482048A848887BFE48880088008801080208 +55B0:0040004078A049104A884C464BF84A084BF84A087BF84A440228029003080204 +55B1:000007FEF40095FC9524952495FC9524952495FCF420942005FC0820082013FE +55B2:011001107210529E54A25F2251425212548A5FCA744250020A82094211540008 +55B3:00400040F7FC90E091509248944693F8920893F8F20893F8020800000FFE0000 +55B4:0014001277FE5410541057F05492549257D2555475545488054A0A1A08261042 +55B5:008800887BFE48884888480049FC49244924492479FC49240124012401FC0104 +55B6:2208111000207FFE400280041FF0101010101FF000003FF8200820083FF82008 +55B7:002001FC782048884BFE4888480049FC49044924792449240124005000880304 +55B8:012001107FFC01003FF821083FF821083FF8210800007C8844B044C47C84447C +55B9:00400040F7FC90A0911092489DF69040904097FCF000904003F8004000400FFE +55BA:0106017871105222524456F85A14522252FE5212721052540292031202500220 +55BB:004000A079104A084DF648004BC44A544A544BD47A544A5403D40244025402C8 +55BC:0080008079F84A084C104BFC480449FC48044BFC780448400124052A050A08F8 +55BD:0020012478A848204BFE48A849244A0248404FFE788849080190006001980604 +55BE:2208111000207FFE410291041FF021000100FFFE00001FF0101010101FF01010 +55BF:00001FF0101010101FF000007C7C444444447C7C01007FFC05401930E10E0100 +55C0:10001078FE4810487C480086FE0082FC00447C4400287C28441044287C444582 +55C1:0004001E7BF04A1E4A104AFE4A924A984AF24A8E7A804AB802A804AA054A0A86 +55C2:0008003C7BC048044A44492849FC4A2048204BFE782049240124012401FC0004 +55C3:004000207BFE480049FC490449FC48004BFE4A027AFA4A8A02FA0202020A0204 +55C4:07FC0080F3F8920893F8920893F8920893F89080F1F8931004A0004001B00E0E +55C5:004000807BF84A084BF84A084BF84A084BF8485078484FFE00A0011002080C06 +55C6:00400040F0A09190924897FE9A0893F8920893F8F20093F80508050809F80108 +55C7:010001007FFC111029284544FFFE00003FF8200827C8244827C820083FF82008 +55C8:012402487A4849244BF84A084BF848004BF84A487A484BF80202020201FE0000 +55C9:002000207BFE482049FC48204BFE4840488849F078244BFE0022012402A20040 +55CA:000001FC782048204BFE480049FC490449FC490479FC490401FC008801040202 +55CB:004001FC7844489449084BDE494A494A4A9449FC790449FC010401FC0104010C +55CC:02080108F110900097FC900091109208940493F8F2A892A802A802A80FFE0000 +55CD:0440025E7292501257D2511E55525552555257DE7152511202120222042A0844 +55CE:000001FE792049FC492049FC4920492049FE48027AAA4AAA02AA020200140008 +55CF:008800887BFE488848A84850488849244A2249FC782048A80124022200A00040 +55D0:004000207BFE4A024C2449FC482049FC48204BFE782049FC0104010401FC0104 +55D1:0020002079FC482048204BFE488049044BFE48027BFC4A940294029407FE0000 +55D2:01100110F7FC9110904090A09110920895F69000F00093F80208020803F80208 +55D3:03F00110F0E09318900097BC94A4931894A49040F7FC90E0015002480C460040 +55D4:00400040F7FC904093F8920893F8920893F89208F3F892080FFE011002080404 +55D5:000003FE7A004AFC4A004BFE4AA84A904AC84A867A084BFE0288044804080818 +55D6:0140065CF4449444975C9444944497FC904097FCF208911000A0004001B00E0E +55D7:000001FC790449E449244BFE4A0249FC490449FC790449FC0104010401140108 +55D8:001E03E0792248944840488849F0482048C449FE7822482003FE005000880306 +55D9:004000207BFC490848904BFE4A024C4448204BFC788048F80088010801280210 +55DA:0040008079FC4904490449FC490049FE490049FE78024AAA02AA040200140008 +55DB:0108009078004BFE48A04BFC48A44FFE48A44BFC78A049B002A80CA600A000A0 +55DC:0040004479F848504BFE484048F849824A7E4C0079FC490401FC010401FC0104 +55DD:00000FFEF00093F89208920893F8900097FC9514F4A497FC0444044404540408 +55DE:0084004478484BFE488448844908494A4A524B9C788449080108025203DE0042 +55DF:0108008878904BFC484049F848404BFE4880490079FC4A200420082003FE0000 +55E0:0E40F04022789288555000207C500888110610F81E88F0885088108850F82088 +55E1:0090008879044A424C8849FC480448004BDE48427A52494A02520042014A0084 +55E2:000001F87908490849F84908490849F848004BFC7A944A940294029407FE0000 +55E3:00003E7C220422043EF400047F045574555455547F5455545574550451144308 +55E4:00200124792449FC48204BFE4800482049FC4924792449FC0020002403FE0102 +55E5:00400080F3F8920893F8920893F8908097FC9110F24894440BFA004000400040 +55E6:00400040F7FC904097FC9484991893E090409088F7FC90440250044809480080 +55E7:10007E7812482A48457882800C6037D8C0063FF8248824883FF8248824A82010 +55E8:00800880E4FEA100AAFCA484A4A4A094A3FEA484ED24A51405FE040404280010 +55E9:0020012478A8482049FC4904490449FC490449FC4904790449FC000000880104 +55EA:00400040F7FC904093F8908097FC9110926895C6F04093F800E0015806440040 +55EB:000003FC790849F8490849F8490E4FF848084FBC78A44AA40128029004A80846 +55EC:01100110F7FE9110910092FE920896089AE892A8F2A892E802A8020802280210 +55ED:01007FFC01001FF010101FF010101FF010101FF01010FFFE00903EE422843E7C +55EE:000000FEEE28AA28AA28AAFEAAAAAEAAAAAAAAAAEAAEAAC20E820A8200FE0082 +55EF:000007FCF444944497FC944494A49514940497FCF04090240522050A090800F8 +55F0:020003FC752455245D2455FC5524552455745554755455540574050405FC0504 +55F1:00200050788849744A0248F8488848F8480C49F0782049FC002003FE00200060 +55F2:00900108F29490609198964690FC930890B090D0F73E90C20324001800600780 +55F3:000E03F078444A2449084BFE4A4248404BFE488078FC49440128021004680186 +55F4:010800907BFC4840484049F8484048404BFC48A078A848B4013C01220222041E +55F5:01FC0808E450A420A1FCA124BD24A5FCA524A5FCE524A524052C0A0011FE0000 +55F6:000001FC792449FC492449FC48A848A84BFE48A878A849FC002003FE00200020 +55F7:01080108710857D0511E579451245FD4521453D472545248024804D404240842 +55F8:08207F20087E7E4408A4FF2810101E282244468280003FF8200820083FF82008 +55F9:0020082075FE542051FC51245DFC552455FC542075FE542004200A2011FE0000 +55FA:002002227BFE4890488849FE4B104D1049FE4910791049FE0110011001FE0100 +55FB:004000207BFE4A004A484A484BFE4A484A484A487A784A000554052A0A2A1000 +55FC:008800887BFE4888480049FC490449FC490449FC78204BFE0050008801040202 +55FD:01080108F7C89108911E97D29564954097C89108F38895480954011401240142 +55FE:04200220723E5F4054A05420573C55505510551075FE5510052809280B441082 +55FF:004000A079104A484DF6482048404BF84A084BF87A084BF8020803F801100208 +5600:00800040F7FC911090A097FC944495F4944495F4F514951405F4040404140408 +5601:00140012701057FE5410549054D2549257F25494749455C80AAA089A11A60042 +5602:0040785E48524A524A524A527A5E02407A5E4AD24B524A524852785E48520040 +5603:002007FE742055FC542457FE542455FC542055FC752455FC052409FC0924112C +5604:010003F87A084BF84A084BF84A004BFE4A004BFE78424FFA0164065818460040 +5605:000007BE7488548857A854A854A857BE54105518749855A806AA044A00460080 +5606:01100110F7FE911091F0904093F8924893F89040F7FC90400FFE00A00110060C +5607:00800110F3F8921094A49FBE904290A093189C46F19096640188063001C00E00 +5608:00A000A077FE50A057FC54A457FC54A457FC500073F8520803F8020803F80208 +5609:0100FFFE01003FF800001FF010101FF00820FFFE10007F7C11442144457C8244 +560A:002002227A224BFE48004BFE4A204BFC4A204BFE7A004A2005FC04200BFE0000 +560B:02080248E748A290A29EAFE4A114A214AFD4A494E914A1C80F08011405140222 +560C:00000FFEE0A0A7FCA4A4A4A4A7FCA000A7FCA000EFFEA0400248044409420080 +560D:004003F8F2489FFE924893F8904093F8924893F8F0809FFE011000E003180C04 +560E:07FC00807BF84A084BF84A084BF84A084BF84910797C4F800090006201B20E0E +560F:100011DC11441144FD4411DC110011007DDC4514451445D445087D0845140122 +5610:000007BCF08494A4929494A490509188962690C0F31090640388003000C00700 +5611:0040007C78404BFE4A424A784BC44A3C4A084AF07B244AA805FE042008A00040 +5612:008803DE788849DC48884BDE488848004BFC4804780449FC0004000403FC0004 +5613:00000FFEE82AA826AFFEA822ABAAAAAAABAAA832E996AE2E084608820FFE0802 +5614:000003FE7A004A7C4A444A444A7C4A004AEE4AAA7AAA4AAA02EE020003FE0000 +5615:000007FCF040927892409FFE910091FC920093FCF00495540554080400280010 +5616:002003FE782049FC48204BFE480049FC490449FC790449FC010401FC00880104 +5617:111009207FFE50129FF4000020F03F0420041FFC00001FF810081FF810081FF8 +5618:0040007C78404BFE4A424A784BC44A3C4A004A507A544B5404D8045009FE0000 +5619:04100210E8FEA492A2FCA4A4ACA8A510A528A6C6E080AFFE0110032000E00718 +561A:0200027C7444597C5144527C56005AFC520853FE720852880248020802280210 +561B:00400020F7FE94909490949097FC949094D895B8F5B496D40892089010900090 +561C:004007FC7150515052E8544450E053585C46508071F8520804D0002000D00708 +561D:0204020477845494590C57C45564555457C45546757C57C405440544044408C4 +561E:0290029077D0529053BC511457D45554555457D4711457D40124012401540188 +561F:0200023EEF62A264A2A4AFE8A124A224A7A2ACA2F4A2A7B404A804A007A004A0 +5620:07FC0080F3F8920893F8920893F8920897FE94A2F89C97F00050002400D4030C +5621:0020012478A84BFE4A0248F84888488848F84820782049FC0020002003FE0000 +5622:000007DE7542555457C85544557E57CA510A510877C85108010801C80E280410 +5623:00400444744457FC500057BC54A454A457BC54A474A457BC04A404A40AB41148 +5624:00000FBEE8A2AAAAAAAAAAAAA514A8A2A080AFFEE110A21003A0006001980E04 +5625:021002107450595C5150525056FE5A0052105250725C525002B00290030E0200 +5626:3FF820083FF8101020085FF404403FF824483FF80400FFFE08201E4003C03C38 +5627:00800040F7FE9402989490509524954A98FA9300F04094440444044407FC0004 +5628:0040004077FC50445FFE504457FC5040555454E4744457FC04E409540A4C1044 +5629:008803FE7888480049FC48A848A84BFE48A848A879FC482003FE002000200020 +562A:000003FE7A524A524BFE480049FC490449FC490479FC490401FC008801040202 +562B:0110011479D24A504A7E4D5048904AA8492849447A444C82000802A402520452 +562C:000003F8F20893F8920893F890009FFE948097BCF494979404D40F88009400A2 +562D:0104010477E85110510057C4500457C85450544277C25444028400E80F100420 +562E:008802AA7ADC4C8849544A2248004BFE4A424C447BFC48440044008401140208 +562F:004003F8F04897FE904893F890409554975C9444F7FC9444075C055405540844 +5630:024802487554575C52485554575C52485FFE52207228522805140494042C0844 +5631:000007FCF40497FC940095FC942095FC952495FCF42097FE062A06FA0A0A1206 +5632:0200023C0FA4E224A224AFBCA8A4AFA4A8A4AFBCA224E224AFA402240244028C +5633:002001FC792449FC48204BFE480049FC490449FC790449FC010401FC00880104 +5634:00900294F2D8929292D2970E91F0921097FC9A44F3FC924403FC044404540808 +5635:0020002079FC48204BFE49084B9C490849884E3E78004BFE009000900112020E +5636:04800482E49CAFD0A490A790A49EA794A494A494EFD4A014051408A410240044 +5637:004001FC790449FC490449FC490449FC4820492478A84924002003FE00200020 +5638:0080008079FE4B544D5449544BFE4954495449544FFE78004954012A022A0000 +5639:00400040F7FC90A09514920897FC9A0A93F89208F3F890400248044409440080 +563A:003803C0F08097FE9110920895F6991091F09000F7FC940405F4051405F4040C +563B:004007FCF04093F8900093F8920893F891109FFEF00093F80208020803F80208 +563C:3E7C22443E7C00003FF821083FF821083FF80000FFFE00003FF820083FF82008 +563D:000003DE7A524A524BDE480049FC492449FC492479FC482003FE002000200020 +563E:000003FE78504BFE4A524BFE480049FC490449FC790449FC002003FE00200020 +563F:000007FCF444955494E4944497FC904097FC9040F0409FFE0000052404920892 +5640:000003DE7A524BDE4A104A5249CE480048884BFE7888488807FE008801040202 +5641:000007FEF0909090939C92049204939C90909090F7FE90400524050A090A00F8 +5642:01080090F7FE909093FC9294931C920493FC9204F3FC900807FE010800A80010 +5643:003C03E0792448A84BFE48A849244A0249FC4924792449FC0124012401FC0104 +5644:008003DE788A49CA488A4BD248A64840488849F078244BFE0022012402A20040 +5645:0004003EF7C09244912893F8920893FC920493FEF40296AA0AAA0A0210140008 +5646:000007BC7108552857BC531855AA5946500053F87208520803F80208020803F8 +5647:002001FC788848504BFE480049FC492449FC492479FC482001FC002003FE0000 +5648:04140212EF92A010A07EAF90A890A890AF90A228EB28AAA81228024A0A4A0486 +5649:00080788708851105FDE549454A4579454945794749454C807880C9400A400C2 +564A:000003FC784848304BFE485248944B5048204BFE7A524A8A0376025202720206 +564B:0208010877C85010579E549457A4501457945094711451C80708011405240242 +564C:02080110F00097FC9444955494E4944497FC9000F3F8920803F8020803F80208 +564D:01400120F3FE922096209BFC9220922093FC9220F22093FE0200052404920892 +564E:002003FE782049FC48004BFE4A0249FC480049FC790449FC0104008803FE0000 +564F:004000A0F11896E6900093F8920893F8900097BCF08494A4029404A402940108 +5650:00003E7C224422443E7C00003FFC010001007FFE00003E7C224422443E7C2244 +5651:0020004079FC490449FC490449FC4820492448A87924482003FE002000200020 +5652:0020012478A84BFE48A849244A224904490449DE7A444D54009E010402040404 +5653:0040007C78404BFE4A424A784BC44A3C4A004A507B544B5405DC04500BFE0000 +5654:002007A4F0A892929114920895F4980293F89208F20893F8020801100FFE0000 +5655:00F83F2009401FE010201FF010101FFC20042AA4400CBFF8200820083FF82008 +5656:00000FBEF208971C92089FBE904090A093189C46F02093F80008001000200040 +5657:00A004A4F2A890A097FC911090A097FC904093F8F04097FC00A0011002080C06 +5658:00000FFEE800AA28A948ABEEA892A884AAA0AAA8EBE8A8880894091409241242 +5659:004000A0F11092489DF690A0924892A893F89040F7FC9484052405F40414040C +565A:000003FC78044BFC48044BFC48004BBC49244FBC78084BFE0108008800A80010 +565B:00200020793C492049204FFE480048204AAA4A227BFE4A7202AA022203FE0002 +565C:010003F0F4109FFC944497FC944497FC90009FFEF00093F8020803F8020803F8 +565D:01080108E214A294A4BCAF08A110A224A4BEAF8AE088A02C0AAA0ACA08280010 +565E:00400040F0A09110920895F6980097BC94A494A4F7BC92100210052809441082 +565F:010000803FFE224824FE2D9036FC249024FC249024FE24804FFC48048FFC0804 +5660:001004107A7C481048FE48444E284AFE4A104A7C7A104AFE0210021005FE0800 +5661:010001F87A084FFE4A884B244BFE4A004AFC4A007AFC4A0002FC048404FC0884 +5662:00800100F7FC94449554944497FC94E495549404F04097FE00A0011002080C06 +5663:000003F87AA84AA84BF849004BFC4C844BE44AA47AA44BE4009407F400140008 +5664:01100110F7BC911093B895549912900093F89000F7FC90400248044409420080 +5665:009003FC7A944BFC4A944BFC48004BFC4A004AF87A004BFE0520051405480986 +5666:0020013C79204FFE481048144BFE4A104BF04A547A544AD40368044A08960322 +5667:008800887BFE488849FC492449FC492449FC48207BFE4A22022A02FA020A0206 +5668:00003E7C224422443E7C01200110FFFE02800C603018C0063E7C224422443E7C +5669:00007FFC01003D78254825483D7801007FFC01003D78254825483D780100FFFE +566A:03F80208F20893F8900097BC94A494A497BC9040FFFE91600250044818460040 +566B:008000407BFC490848904FFE48004BFC4A044BFC7A044BFC00400524050A08FA +566C:02100210F3DE95289884900097FC904092489248F248955408E200400FFE0000 +566D:0108020877C8545057DE546457D45214511457D4721453C802480454055408A2 +566E:000003FC7A944A944BFC48004FFE48004BFC4A047BFC48A2011403080D440182 +566F:003C03C070445224510857FE544252A4528A547A708050F8010802900060079E +5670:0040002077FE50285224527E54C85748517E524874C8577E01480248047E0840 +5671:0040007C78404BFE4A424A784BC44A3C4A004BFE7A404BA4025805B4045209B0 +5672:004000A0F3189DF6900097FC955494E497FC9000F3F8920803F8020803F80208 +5673:0020003E78204BFE4A224BF84A224AFE4A844AFC7A004AFC022005FE04480986 +5674:002001FC782048884BFE488849FC490449FC490479FC490401FC008801040202 +5675:211017FE108003F8F20813F8120813F8120813F8280047FE00003FF820083FF8 +5676:008803FE788849FC490449FC490449FC488049FE7A224D52010201FA000A0004 +5677:021001107790503E54A253445F9050105790549077A854A804A807C400440082 +5678:0200023EE208BFD0A23EAAA2AAA2AABEAAA2AFBEE222A22202BE030002140022 +5679:00400248F15097FE9402980493F8920893F89000F7FC944407FC044407FC0404 +567A:0200010277DC50105450529057DE5114511457D4711455940554092405240244 +567B:00800040F7FE95129BFC911097FC911097FE9110F24895F40842004007FC0000 +567C:00100008778854BE548054945788547E5408578876BE5A880A880B8812880008 +567D:0800FF0008FE7E1000107E3042387E542492FF1000107E10421042007EFE4200 +567E:004000207BFE4A8A49444A2249FC48884BFE480079FC490401FC010401FC0104 +567F:03DE00427A52494A4A5248204BFE4888488849547A22482003FE002000200020 +5680:004000207BFE4A224954494A4A3A480049FC49547BFE480001FC002000A00040 +5681:000003DE78424A52494A4A52489049084BFE4D1079FE491001FE011001FE0100 +5682:001007D0751057DE545057E8550457C4500053F872A852A802A802A80FFE0000 +5683:040002FE7AAA48AA48FE48104E544A924A104A547A924A100210050008FE0000 +5684:008803FE78A8489049FE4B2049FC492049FC492079FE490003FC00880070038E +5685:000007FCE040AFFEA842A358A040A358A000AFFEE040A7FC04A404A404A4040C +5686:010807FEF108902097FE900091F8910891F89000F7FE940205FA050A05FA0406 +5687:01100110711057BC511051105FFE52A852A856EC7AAA52AA02A805A804480898 +5688:00000FFEE808ABC8AA4CABCAAA48ABDEA808ABC8EA48ABD40A540BD40A5412E2 +5689:02840284EAA4A6C4A29EAFE4A004A454A28CAFE4E104A7C4010401C40E140008 +568A:008003F8F20893F8920893F8900097FC944497FCF44497FC00000FFE01100210 +568B:004007FC704053FC500057FE500253F8504057FE700057FE000807FE04A80798 +568C:0080004077FC511050A45F58555455525B585000720853F8020803F802080408 +568D:004003F8704857FE504853F8504057FE500052A4745253F802A802A80FFE0000 +568E:004007FEF00091F8910891F8900097FE940293F8F180964401B8066801A60E60 +568F:004007FCF04097FE94029BFC924893F8924893F8F00097FC02440278054008FE +5690:012400A87BFE4A8A48F8490C49F0490248FE480079FC490401FC010401FC0104 +5691:003C07C0F0409FFE904097FC955494E497FC9040F7FC90400FFE000005240892 +5692:0040002077FE548857DE548855DC56AA54885440748855F00420044809FC1084 +5693:0080004077FE54025A2453BC54A45AA8551052E874045BFA00400248044400C0 +5694:004007FC704057FE54025BFC524853F8524853F8710857FC02440278054008FE +5695:010003F074105FFC544457FC544457FC5524589273F8520803F8020803F80208 +5696:008803DE788849DC48884BDE48884BFC480449FC78044BFC004002A4028A047A +5697:03F80208F3F8920893F8911097FC91109FFE9110F248955400E00150024800C0 +5698:07FC0080E3F8A208A3F8A208AFFEA882A548A514E8F4A10003F8050800F00F0E +5699:00200120793C49204FFE48904A944B6C4A044BFC7A944A94036C020403FC0004 +569A:00003E7C22443E7C00003FFC21003FF820083FF821003FFC00003E7C22443E7C +569B:044404E4E8A8AAAAAEEEA4A4AAAAAEEEA242A040EFFEA0E0015002480C460040 +569C:01FC012479AC492449FC482049FC48204BFE49547A2A482001FC002003FE0000 +569D:0040002077FE548855FC548857FE542055FC552475FC552409FC088811040202 +569E:0100FFFE01007FFC00003FF820083FF81010FEFE10107C7C00007C7C44447C7C +569F:0090031EF12A97CA910A93929522995690889124F22294A8007001AC06220060 +56A0:020205E274A256AA552A566A510A528A544A5BAA710A57CA0122054201EA0E04 +56A1:05080508EFBEA508A708A208AFBEAA80AA88AF88E23EAF8802080208023E0200 +56A2:01007FFC11101FF00100FFFE94522FE844441FF004407FFC05081890EA600C18 +56A3:3EF822883EF80000FFFE01001FF01010111002C00C30700800003EF822883EF8 +56A4:002007FE748857DE548855DC56AA548C55F0542075FC542007FE082008A01040 +56A5:0110011077FC511051F0520852EA56AC52A852AA76EA5A06000002A402520452 +56A6:000007FE74445598548857DE548855DC56AA548874205520053C0920092017FE +56A7:0040007C78404BFC4A444BF04A444AFC4AA84AF87AA84AF8020005FC05540BFE +56A8:0210011077DE5010545E528257DE501057DE545077DE545007DE0450045204CE +56A9:04140412E9FEAA10B2FEBC92A4FEA892B2FEBE92E20481FE2A442A242024000C +56AA:03DE02527BDE4A524BDE4A424A7A4A8A4B124ADA7A8A4ADA028A02FA020A0204 +56AB:0400023CEFA4A024A8BCA524AFA4A23CA224AFA4E23CAB100A9812A80A2A0446 +56AC:0100013E750855D0553E55225FE2503E5122557E756255A208BE010002140C22 +56AD:0800FF7E08087E0800107E3442527E922410FF10007C7E44424442447E7C4244 +56AE:11002BDE4A5273D42A524BD27A1A12942350CA403FFC200427E4242427E4200C +56AF:07FC0040F7FE94429B5C9040975C912093FC9620FBFC922003FC022003FE0200 +56B0:004000207BFE4A484BFE4A484AEC4B5A4A484BFE7A204A7C02C40344047C0844 +56B1:010801EC710A57E8552855DE572854EA540A57EA740C57EC0A2A0BEA115607E2 +56B2:200011DCFD5401547DDC44007DFC01247DFC092411FC1C20F3FE102050202020 +56B3:3AB821083AB82288393822887FFE400291041FF02100FFFE00001FF010101FF0 +56B4:3E7C22443E7C00003FFE20002E20223C3FA829482F2829282F1049D07F288144 +56B5:01F0021077FC520453FC522453B8522251FE521077FC524403FC00D0014A063E +56B6:03DE02527BDE4A524BDE4A524BDE498C4A5248407FFE48880190006000D80304 +56B7:004007FCF00093B892A893B8911097FC911097FCF1109FFE012803100D480186 +56B8:00080FE8E928AB68A9AEA928AFE8A108AFE8A11EE112BFF200121552155E2012 +56B9:0820083CEE20B4FEA4A2A4B8BFE2A49EB582B5BCF5AAB79C18FF010801280210 +56BA:01FC095475FC5488505053FE5C4054A25534545875B45452059204500A2011FE +56BB:00007BDE489249124BD24A527A5E03C07A5E4BD24A524A524BD2781E49920240 +56BC:003C07C07244512857FC54A457FC5008578854FE778854A80798050805A80690 +56BD:011007D0711E57A451545FD45208539454A25BFC720453FC020403FC01080204 +56BE:008803FE78884BDE4A524BDE48A0489049FE49207BFC4D2001FC012001FE0100 +56BF:010807FE712853FE522057FC5A2053FC522053FE7080531C0204039C020403FC +56C0:02080208E27EAF88A23EAFAAAABEAFAAAABEAF8AE27EAF84027E02240214020C +56C1:03FC010879F8490849F8490E4FF848084FFE4A947B9C4A94039C02D607BC0084 +56C2:3EF822883EF80000FFFE02001FF010101FF010101FF0082010103EF822883EF8 +56C3:04140212EFA0A53EA564AAA4A03EA224AFA4A23EEB24AAA412A4023E0A200420 +56C4:04180214EF90A53EAAA8ADE8A8BEAFA8A228AFBEEAA8AAA80BA808BE0AA00920 +56C5:0000EEFEAA82AA82EEFE00A4FEA492FEFEA492A4FEFE10A8FEAA112411321220 +56C6:008803FE788849FC492449FC49244BFE4A2A4AFA7A2649FC012401FC002203FE +56C7:0FBE000077BC54A456B454A4504057FE54A057FC74A457FC051209DC091211CE +56C8:010807FE71085390513C57D452B4555C5396512273FC500007FE0080010403FE +56C9:000007FC74A454A457FC521052A854BE5F68523C74A85FBC00280AA80ABE0020 +56CA:01007FFC11101FF00100FFFE92921EF004403FF80440FFFE04880C503530C60E +56CB:052807BE794857BE531855AA594653FC520453FC720453FC020403FC01080204 +56CC:01100FFEE510A400AF06B138AF88AA88AABEAF88EA9CAF9A0028154815480008 +56CD:10101010FEFE10107C7C00007C7C44447C7C2828FEFE00007C7C44447C7C4444 +56CE:00440E28EAFEAA92AED6AABAAAFEAE00AA7CAA44EE44A07C0A440944117C0044 +56CF:281029FEFE1028FC380010FC7C8454FC7C4811FE7C0010FCFE84288444FC8284 +56D0:010801ECE10AAFEAA928ABC8A93EAFE8A948ABE8EA28AB680AA80BF40AB412A2 +56D1:07FC040477FC552454A8552455FC555455FC564475F4555409F4084413F40008 +56D2:011007FE711057BC54A457BC54A457BC544457FC755455F4044404E405540448 +56D3:008003DE788A49D248A64BD0489C48504BFE48507AAA4BFE025202AA03FE0002 +56D4:004007FC724853F850405FFE5AAA53B8511057FC71104FFE012803100D480186 +56D5:0790051E77A8548457BE552A57BE500053F8520873F8520803F800A00124061C +56D6:021007DEE928AFFEA912AFFEA228A444A9FEAF48E27EA5480F7E0048157E1540 +56D7:00007FFC4004400440044004400440044004400440044004400440047FFC4004 +56D8:00007FFC400440044FC44844484448444FC448044824482447E4400440144008 +56D9:00007FFC4004400440047F8440844084408440847F844084400440047FFC4004 +56DA:00007FFC4004410441044104410442844244444444244824502440047FFC4004 +56DB:000000007FFC444444444444444444444844483C5004600440047FFC40040000 +56DC:00007FFC400440044104410442044204444448245FF44814400440047FFC4004 +56DD:00007FFC400440044FE44044408441045FF4410441044104450442047FFC4004 +56DE:00003FFC2004200427E42424242424242424242427E4200420043FFC20040000 +56DF:0200020004007FFC40044824444442844104428444444824400440047FFC4004 +56E0:00007FFC40044104410441045FF441044284424444244814501440047FFC4004 +56E1:00007FFC4204420442047FFC444444444884468441044284444448247FFC4004 +56E2:00007FFC4004408440845FF4408441844284448448845084428441047FFC4004 +56E3:00007FFC4004408440845FF4408448844484448440844084428441047FFC4004 +56E4:00007FFC410441045FF44104492449244FE441144114411440F440047FFC4004 +56E5:00007FFC4004420441045FF44004400447C4444444444454483450047FFC4004 +56E6:00007FFC4004410441045D1445A445444924491451146504420440047FFC4004 +56E7:00007FFC40044444442448145014600447C4444444444444444444447FFC4004 +56E8:00007FFC40045FF440844104410443844544492451146114410441047FFC4004 +56E9:00007FFC400440044FE4400440045FF44204444448245FF4481440047FFC4004 +56EA:040008007FFC4004408448944514422445444884514442244C2440047FFC4004 +56EB:00007FFC4404440447F449544954525442944494491442A4444440047FFC4004 +56EC:00007FFC44444444444447C444444444444447C444444444444444447FFC4004 +56ED:00007FFC40044FE4400440045FF444844484448448944894507440047FFC4004 +56EE:00007FFC4504450449245944698449044F144914491448F4480440047FFC4004 +56EF:00007FFC400440045FF4410441044FE44104410441045FF4400440047FFC4004 +56F0:00007FFC4104410441045FF4410443844344452449145114410441047FFC4004 +56F1:040008007FFC4204420447F4481452244144408441444624580440047FFC4004 +56F2:00007FFC4444444444445FF44444444444447FFC44444444484450447FFC4004 +56F3:00007FFC40044104448442A45224484444444284410446C4583440047FFC4004 +56F4:00007FFC410441045FF441044FE441045FF4411441144154412441047FFC4004 +56F5:00007FFC41044104428444444824549C650446044424442443E440047FFC4004 +56F6:00007FFC400444444824511441044FE44104410441045FF4400440047FFC4004 +56F7:00007FFC400440E44F04410441045FF44304458449445124410440047FFC4004 +56F8:00007FFC400440045FF44104410449E44904490449045FF4400440047FFC4004 +56F9:00007FFC41044104428444444A24511C6FE4402440444284410440847FFC4004 +56FA:00007FFC410441045FF4410441044FE44824482448244FE4482440047FFC4004 +56FB:00007FFC40045FE4502450245FE451045FF4510450945454583440047FFC4004 +56FC:00007FFC42044204444448245FF440144FE4482448244FE4482440047FFC4004 +56FD:00007FFC400440045FF4410441044FE44104414441245FF4400440047FFC4004 +56FE:00007FFC4204420447E44C445284410446C4783C43044084460441847FFC4004 +56FF:00007FFC420442045FF444044FE4542467E4442447E4442444A444447FFC4004 +5700:7FFC400444444824521441045FF44404440447E44424482448A450447FFC4004 +5701:00007FFC41045FF440044FE440044FE440044FE448244FE4482440047FFC4004 +5702:00007FFC40044FE44204451459A442C444A459A4429444945A8441047FFC4004 +5703:00007FFC414441245FF441044FE449244FE449244FE44924496440047FFC4004 +5704:00007FFC40045FF442044FE444247FFC40044FE4482448244FE440047FFC4004 +5705:3FF00020064001807FFC444442845FF4410441047FFC4104410441047FFC4004 +5706:00007FFC40044FE448244FE440045FF45014511451145294444448247FFC4004 +5707:00007FFC4104428444444BA450144FE44AA44AA44FE44AA44AA448647FFC4004 +5708:00007FFC492445445FF442047FFC482457D4644C44C4442443E440047FFC4004 +5709:00007FFC410441044FE441045FF4444442844FE441045FF4410441047FFC4004 +570A:7FFC41044FE441044FE441047FFC40044FE448244FE448244FE4482448647FFC +570B:00007FFC40A440947FFC40845E94529452A45EA4405446B4591440047FFC4004 +570C:00007FFC4104511451145FF440047FFC41045FF452945294503440047FFC4004 +570D:7FFC42044FE444245FFC40044FE448244FE441045FF4410451045FFC41047FFC +570E:7FFC440448245FF440144FE448244FE448244FE448244FE4444448247FFC4004 +570F:00007FFC492445445FF442047FFC482457D4604C47C4442443E440047FFC4004 +5710:00007FFC40045FF4529452945FF441047FFC440447F44814505460247FFC4004 +5711:7FFC41245FF441044FE449244FE449244FE4492440445FF44844454440847FFC +5712:00007FFC41044FE441045FF440044FE448244FE4411446A45A4442247FFC4004 +5713:7FFC40044FE448244FE440045FF450145FF450145FF450145FF4444448247FFC +5714:7FFC41044FE441045FF4420444444FE440044FE44AA44AA45FF440047FFC4004 +5715:7FFC410441044FE441245FF441244FE441045FF448244FE448244FE440047FFC +5716:7FFC40044FE448244FE441047FFC41045FF4501457D454545FF440047FFC4004 +5717:7FFC420444444FE441047FFC42045FF4545457D4545457D454545FF440047FFC +5718:7FFC41045FF441044FE449244FE449244FE441145FF440445FF4484444C47FFC +5719:00007FFC4444482457D441044FE44AA44BA44AA44BA44AA44FE440047FFC4004 +571A:7FFC41044FE449244FE441045FF448244FE448244FE448244FE4444448247FFC +571B:7FFC40045FF452945FF441044FE441045FF4444442844FE441047FFC41047FFC +571C:7FFC40045FF452945FF440047FFC40044FE448244FE445144CA4744446247FFC +571D:0000FFFE800291129392A82ABBBA9012ABAAB83A8382AAAAABAA8002FFFE8002 +571E:FFFE9112A3A2B83A9392A82ABBBA8282ABAA8102BFFA854289229112FFFE8002 +571F:0100010001000100010001003FF80100010001000100010001000100FFFE0000 +5720:10801080108010801080FE80108010801080108016801884E0844084007C0000 +5721:0100010001000100010001003FF80100010001200110011001000100FFFE0000 +5722:1000100013FE10201020FE20102010201020102016201820E020402000A00040 +5723:00003FF0082004400280010006C01830E10E01001FF00100010001007FFC0000 +5724:10401040104010401040FE60105010481044104416401840E040404000400040 +5725:0100010001003FF8010001000100FFFE0440044004400440084408441044603C +5726:12001100108010801040FC40104010A010A010A011101D10E208420804040802 +5727:00003FFE200020802080208020802FFC2080208020802080208040805FFE8000 +5728:020002000400FFFE080008401040304057FC904010401040104010401FFE1000 +5729:100011FC102010201020FC20102013FE1020102010201C20E020402000A00040 +572A:10401040108010FE1100FE0010FC10081010102010401C80E102410200FE0000 +572B:1008103C13C010401040FE401040107E13C0104016401842E0424042003E0000 +572C:200021FC200020002000FBFE20802080210021FC20043804E004400400280010 +572D:010001003FF8010001000100FFFE0000010001003FF8010001000100FFFE0000 +572E:1000100011F810081008FC08100811F81108110011001D00E102410200FE0000 +572F:100011FC110411041104FD04110411FC1100110011001D00E102410200FE0000 +5730:1020102010201120112CFD34116413A41124113411281D22E122410200FE0000 +5731:00200C2070201020102011FC1020FE201020102010201020202023FE40008000 +5732:1008103C11E010201020FC20102013FE1020102010201C20E020402000200020 +5733:11041124112411241124FD24112411241124112411241D24E124422402040404 +5734:10401040108010FC1104FD04120414841044102410241C04E004400400280010 +5735:10401040104010401040FE40107C10401040104016401840E040404007FE0000 +5736:010001007FFC0280044008203118C10601003FF80100010001000100FFFE0000 +5737:100013FE104010401040FE40105010481044104416401840E040404000400040 +5738:10201020102010201124FD24112411241124112411241D24E12441FC00040000 +5739:10401020102013FE1200FE0012001200120012001E00E2004200040004000800 +573A:200023F0202020402080F90023FC21242124212422243A44E444488401280210 +573B:1008101C11E011001100FD0011FE11101110111011101D10E110421002100410 +573C:00003FF8200820083FF8200820083FF8010001003FF8010001000100FFFE0000 +573D:11001100110011FC12A4FCA410A41124112412441C44E0844104020404280010 +573E:100017F8110811101110FD20113C1104110412881E88E2504420045008880306 +573F:10201020105010501088FD04120210881088108810881C88E088410801080208 +5740:10201020102011201120FD20113C11201120112011201D20E120412007FE0000 +5741:1004101E11F011101110FD10111011FE1110111011101D08E10A414A01860102 +5742:1008101C11E011001100FDFC114411441144112811281D10E110422802440482 +5743:1000100011FC10001000FC0013FE10901090109010901C90E1124112020E0400 +5744:200021F0211021102110FA0E240023F821082110209038A0E04040A003180C06 +5745:10201020105010501088FD4412221020100011FC10041C08E008401000100020 +5746:104010401040108010FEFD08128810881088105010501C20E050408801040202 +5747:10401040108010FC1104FE04108410441044101410241C44E184400400280010 +5748:1000100013FC12041408FC0011F011101110111011101D12E2124212040E0800 +5749:10201020102013FE1020FD2411241124112411FC10241C20E0224022001E0000 +574A:10401020102013FE1080FC80108010FC1084108410841C84E104410402280410 +574B:10101090109010881108FD04120415FA1088108810881C88E108410802280410 +574C:0440082010102FE8C4260420082010A0614001003FF8010001000100FFFE0000 +574D:100011F8110811081148FD281128110817FE110811081D08E108420802280410 +574E:10801080108010FC1104FD0812401440104010A010A01D10E110420804040802 +574F:1000100013FE10101010FC2010201068106410A41D22E2224420002000200020 +5750:01001110111011101110292825244544810001003FF8010001000100FFFE0000 +5751:10801040104013FC1000FC0011F011101110111011101D12E1124212020E0400 +5752:2080208820B03EC0208020842684387C210001003FF8010001000100FFFE0000 +5753:0820082008207FFC08200820FFFE10202020412001003FF801000100FFFE0000 +5754:010001047D880550092011102108C5060200010001003FF801000100FFFE0000 +5755:00781FA01120112011201110211021084004010001003FF801000100FFFE0000 +5756:00003FF800000000FFFE044004420842303EC10001003FF801000100FFFE0000 +5757:10401040104013FC1044FC441044104413FE104010A01CA0E110420804040802 +5758:100017FE108010801080FCF8110811081108120813F81C10E010401007FE0000 +5759:00007FFE0888088811102220111008880888010001003FF801000100FFFE0000 +575A:040025FC2504248824502420245825860400010001003FF801000100FFFE0000 +575B:1000100011FC10001000FC0013FE10201020104010401C88E10443FE01020000 +575C:200023FE220022202220FA2022FC22242224222422443A44E484448409281210 +575D:100011FC110411041124FD24112411241124112411241C50E048408401020602 +575E:1020104011FC11041104FD0411141108110011FE10021C02E3FA400200140008 +575F:10801040104017FC1110FD1011101110111010A010A01C40E0A0411002080C06 +5760:00407C404440484044A044A0551049084204450201003FF801000100FFFE0000 +5761:20202020202023FE2222FA24222023FC2284228822483A50E220445004880906 +5762:10201020112410A410A8FC2011FC10201020102013FE1C20E020402000200020 +5763:01001110092001007FFE40028104010001003FF80100010001000100FFFE0000 +5764:10201020102011FC1124FD24112411FC1124112411241DFCE124402000200020 +5765:100011F8110811081108FDF811081108110811F811081D08E108410807FE0000 +5766:1000100011FC11041104FD0411FC11041104110411FC1D04E000400003FE0000 +5767:1000100013FE10201020FC40104010FC1184128414841C84E084408400FC0084 +5768:10401020102013FE1202FC04110011081110112011C01D02E102410200FE0000 +5769:110811081108110817FEFD0811081108110811F811081D08E108410801F80108 +576A:100011FC102010201124FCA410A8102013FE102010201C20E020402000200020 +576B:1020102010201020103EFC201020102011FC110411041D04E104410401FC0104 +576C:2008203C23D022902290FA90229022902290228822883AC8E2A444D404920800 +576D:100011FC110411041104FDFC110011401144114811701D40E1424242023E0400 +576E:10201020104010401088FD0413FE1002100011FC11041D04E104410401FC0104 +576F:100013FC102010201040FE4010D011481244144416401840E040400007FE0000 +5770:100011FE110211021102FD7A114A114A114A114A117A1D4AE1024102010A0104 +5771:10201020102011FC1124FD2411241124112413FE10201C50E050408801040202 +5772:10901090109013FC1094FC9413FC1290129013FE10921C92E11A411402100410 +5773:202021202120222022FCF4A4272421242224222424A437A4E0C4404400940108 +5774:010001003FF801000100FFFE08201010210841043FF8010001000100FFFE0000 +5775:1008101C11E011001100FD00110011FE1110111011101D10E110411007FE0000 +5776:200021F8210821482128F908210827FE2208228822483A08E3FE400800500020 +5777:2000200027FE20082008FBC8224822482248224823C83A48E008400800280010 +5778:10801080110011FC1204FC0411E411241124112411E41D24E004400400280010 +5779:10401020102013FE1202FC04100010901090109010881D08E108410402040402 +577A:105010481048104013FEFC80108010FC1144114411281D28E210422804440182 +577B:1008103C13E012201220FE20122013FE1220121012101E12E20A428A03260212 +577C:1008101C11E011001100FD0011FE11101110113011181D14E112421002100410 +577D:10201020105010501088FD241212101011FC100410081C88E050402000100010 +577E:10401020102013FE1202FC041000100013FE102010201C20E020402000A00040 +577F:2088208820882108217EFB08250821482128212821083908E108410801280110 +5780:1008103C13E010201124FCA410A8102013FE102010201C20E020402000A00040 +5781:10401040108010FC1120FE201020102013FE102010501C50E088408801040202 +5782:001000F83F00010001007FFC09200920FFFE092009207FFC010001003FF80000 +5783:108010401040100013FCFC00100811081108109010901C90E0A0402007FE0000 +5784:04400420FFFE0910112011C023044D0480FC010001003FF801000100FFFE0000 +5785:109010881088108013FEFCA010A010A410A410A811281D32E1224262029E0400 +5786:20402040207E20402040FBFC22042204220423FC22043A00E200440004000800 +5787:2000200023DE22522252FA52225222522272220222023A02E20243FE02020000 +5788:089008881080309E57E0908010441034110C01003FF8010001000100FFFE0000 +5789:1080108011FC11041204FDF411141114111411F411041D28E112410200FE0000 +578A:200023FC220422042204FBFC2220222023FE222022203A10E212428A03060202 +578B:00047F84122412241224FFA4122422042214410881003FF801000100FFFE0000 +578C:200023FE2202220222FAFA02220222FA228A228A228A3AFAE2024202020A0204 +578D:10201020104011FC1104FD04110411FC1104110411FC1D04E104410401FC0104 +578E:2080208021F822082510F8A0204020A023182C0623F83A08E208420803F80208 +578F:1020102011FC102413FEFC2411FC1020102011FC10201C20E3FE402000200020 +5790:4080208009FC12042448E04020A023182C06010001003FF801000100FFFE0000 +5791:2040204020FC21082290F86020482190263E204220843B48E030402000C00700 +5792:0400082010103FF80810102024487EFC0204010001003FF801000100FFFE0000 +5793:20402020202027FE2040F884210823F0202220443988E6104020005001880604 +5794:00007FFC044004403FF8244824483FF8010001003FF8010001000100FFFE0000 +5795:007C3F8020003FFE20002FF8280828082FF8208020802FFC40804080BFFE0000 +5796:1040108011F811081108FD0811F811001100110011FC1D04E104410401FC0104 +5797:10901090109012921194FC98109011981294149210901C90E11241120212040E +5798:10901094109211121110FF7E151011101110112811281D28E128414401440182 +5799:10201020112410A410A8FC2013FE10901090109010901C92E1124112020E0400 +579A:010001003FF8010001000100FFFE1010101010107CFC101010101E10F0FE4000 +579B:100011F0111011101110FD10124E144013FC10401CE0E1504248044600400040 +579C:100013F81088109010BCFD0411141248104017FE10401CE0E150424804460040 +579D:1040104010FC11041208FDFE1100117C1144114411541D48E1424242023E0400 +579E:2040202023FE22022000F83823C020402040207C23C03840E0424042003E0000 +579F:110410841088100013FEFC20102011FC1020102013FE1C20E020402000200020 +57A0:100011F81108110811F8FD08110811F81144114811301D20E110414801860100 +57A1:08A00890108030FC57809048105010241054118C160401003FF801000100FFFE +57A2:1008101C11E011001100FDFE11001100117C114411441D44E144427C02440400 +57A3:100013FE1000100011FCFD04110411FC1104110411FC1D04E000400003FE0000 +57A4:200027FE204020802110FA0827FC20442040204027FC3840E04040400FFE0000 +57A5:2040204020A02110FA08240623F82000200023F822083A08E208420803F80208 +57A6:00003FF020103FF020103FF0220821902C60311C01003FF801000100FFFE0000 +57A7:20402040208023FC2204FA0422F422942294229422943AF4E204420402140208 +57A8:1040102013FE12021414FC10101013FE1010111010901C90E010401000500020 +57A9:00007FFC04402448144814500440FFFE0000010001003FF801000100FFFE0000 +57AA:110410841088100011FEFC8810881088108813FE10881C88E108410802080408 +57AB:084008407DF808480C4819C8684A08AA2886110201003FF801000100FFFE0000 +57AC:108810881088108811FEFC8810881088108813FE10001C88E084410402020402 +57AD:200023FC209020902090F892249222942294229820903890E090409007FE0000 +57AE:2040204027FC20A02110FA082DF6200027FC208021003BF8E008400800500020 +57AF:101012101110111010FEFC10131011281124114411421D82E1004280047E0000 +57B0:10201020103E10201020FDFE1000100011FE102010281C24E022402000200020 +57B1:1020112410A410A410A8FC2013FC10041004100411FC1C04E004400403FC0004 +57B2:102011241124112411FCFC0011FC1004100411FC11001D00E102410200FE0000 +57B3:20802080213C22002480F880217E23082508210821083908E108410801280110 +57B4:20402020202027FE2000F800209022542224222422543A94E204420403FC0004 +57B5:10401020102013FE1202FC44104013FE1088108811081CD0E020405000880304 +57B6:1040102011FC10001088FC5013FE10201020102011FC1C20E020402000200020 +57B7:100013F81208120813F8FE08120813F81208120813F81D20E12042220422181E +57B8:1040102013FE12021404FDF81000100013FE109010901C90E1124112020E0400 +57B9:2100211E21122FD22114F91427D8211421122FD22112391AE214421004100810 +57BA:1008103C11C010041144FCA8100011F81010102013FE1C20E020402000A00040 +57BB:100011FC1104110411FCFD04110411FC1104110411FC1C00E088408401020202 +57BC:10F8208841088A06100031F850889050102010D8170601003FF801000100FFFE +57BD:200C11F08100490009FE1110E11022102210251001003FF801000100FFFE0000 +57BE:100011FC110411FC1104FDFC1000100011FC10201C20E3FE4020002000200020 +57BF:2040202023FE22002200FAFE22042228221023FE3A12E2144210041004500820 +57C0:00F83F000100FFFE01000924F93809223922C91E01003FF801000100FFFE0000 +57C1:102011241124112411FCFC20105010881144122210201DF8E008401000100020 +57C2:100013FE1020102011FCFD24112411FC1124112411FC1D20E0A0404000B0030E +57C3:204020802110220827FCF904210023F82440204027FE3840E0A0411002080C06 +57C4:210021F8230824902060F9982646204023F8204023F83840E7FC404000400040 +57C5:004078204BFE508048F84488550849284210410001003FF801000100FFFE0000 +57C6:1080108010F811081210FDFC1124112411FC112411241DFCE124422402140408 +57C7:100011F8100810D01020FDFC1124112411FC112411241DFCE12441240124010C +57C8:104010401088110413FEFC0210881144124210F81D88E2504020005001880606 +57C9:10201020102013FE1020FC2011241124112412AA10201C50E050408801040202 +57CA:0100210821083FF8000001047D88095011202518C20601003FF801000100FFFE +57CB:100011FC1124112411FCFD24112411FC1020102011FC1C20E020402003FE0000 +57CC:1040102011FC11041104FDFC1104110411FC112011221D14E108414401820100 +57CD:100010FC1084108410FCFC0011FE1102110211FE11021D02E1FE4102010A0104 +57CE:20282024202027FE2420FC20242427A424A424A824A83C90E692492A08461082 +57CF:2008201C277021102110FA50225C27502150255025503A7CE200450008FE1000 +57D0:100011FC100410FC1004FDFC100013FE120211F810881C88E050402000D80306 +57D1:080C08F07E8008800EFE7888088829081208010001003FF801000100FFFE0000 +57D2:1008103C13C010441224FD281100101013FE101011101C90E090401000500020 +57D3:1008103C13C011241098FC601390101013FE101011101C90E090401000500020 +57D4:2048204427FE20402040FBFC2244224423FC224422443BFCE244424402540208 +57D5:100011FC110411041104FDFC1000100013FE102010201DFCE020402003FE0000 +57D6:2108210827FE21082108F800209020922114231825103932E1524112010E0100 +57D7:101010101090109E1090FC9013FE10001010109210921D14E208401000600380 +57D8:200820082788248824FEFC88248827C824A824A824883C88E788448800280010 +57D9:200023F82208220823F8F800200027FC2404244424443C44E4B4410806041802 +57DA:200023F8220822082208FBF82040204027FC244424A43D14E614440404140408 +57DB:200027FC240424A42514FE0C240425F42514251425143DF4E514440404140408 +57DC:082008207EFC08301C682AA4C9220820092001003FF8010001000100FFFE0000 +57DD:20202020205020882144FA2221F820082050202020A43A82E28A428A04780000 +57DE:1040102013FE12021404FC0013FE102010201120113C1D20E2A04260043E0800 +57DF:20142012201027FE2010F81023D222522252225423D43808E0EA471A02260042 +57E0:1020104011FC110411FCFD0011FC110411FC10201C20E3FE4020002000200020 +57E1:200027FE209020902090FB9C220422042204239C20903890E090409007FE0000 +57E2:204022482150204023F8F88027FC2110220825F429123910E1504124010400FC +57E3:1040102013FE10001088FC88115412221000102013FE1C20E020402000200020 +57E4:2040208023FC22242224FBFC2224224423FC20903910E7FE4010001000100010 +57E5:1020102013FE102011FCFC2013FE100011FC110411FC1D04E1FC410401140108 +57E6:2040202023FE22022504F90021DE225222522352249A3894E11041120212040E +57E7:100011F81108110811F8FD0811F8110811F811081D08E3FE4000009001080204 +57E8:2040204020A021102208FDF6200027FC24A424A427FC3CA4E4A444A404140408 +57E9:1080108011F811081210FDFC1024102413FE102410241DFCE024402000A00040 +57EA:10401020102013FE1202FC9411081204100011FC10201C20E020402007FE0000 +57EB:2020212420A420A82020FBFE2202220222FA228A228A3A8AE2FA4202020A0204 +57EC:2040204027FC204023F8FA4823F8224823F8204020E03950E2484C4600400040 +57ED:2040204023F82048F84827FE2048204823F8244422E83950E248444601400080 +57EE:10201122112212241050FC8813041022102011241D24E2284050008801040602 +57EF:2040208027FE21102248FC4623F82248224823F822483A48E3F840420042003E +57F0:1008103C13C010441224FD281100102013FE107010A81CA8E124422204200020 +57F1:2100210021DC2114F114211427D42014211421143588E5484948011405140222 +57F2:1020102013FE102011FCFC4013FE10881124122210F81C20E3FE402000200020 +57F3:2080208020F82108FA1024002040239C22042204239C3A04E204420403FC0204 +57F4:2040204027FC20402040FBF8220823F8220823F822083BF8E20842080FFE0000 +57F5:2008203C21E020202020FBFE2124212427FE212421243BFEE020402003FE0000 +57F6:104010407C40104011F8FE480048454892C810487C68105A108A1C8AE1064202 +57F7:104010407C4011F81048FE48444829487CC8104810A8FEA8108A110A11061202 +57F8:100011FC110411FC1104FDFC1080108011FE124A144A1C92E122424200940108 +57F9:1040102011FC10001108FC90100013FE1000100011FC1D04E104410401FC0104 +57FA:082008207FFC08200FE008200FE00820FFFE082011102108CFE6010001003FF8 +57FB:1040102013FE100011FCFD0411FC100011FC10081C10E3FE4020002000A00040 +57FC:2040204023FC20A02110FA0827FE200823C8224822483A48E3C8400800280010 +57FD:200023F8200821F82008FBF8200027FE2442284423F83A48E248424802580040 +57FE:00007F7C22443E4422283E1023A8FE440282010001003FF801000100FFFE0000 +57FF:23F8120882084BF80A401248E27022442444253C09003FF801000100FFFE0000 +5800:100013FE1202120213FEFE1012921292129212FE12101E92E292449204FE0802 +5801:100011FC1124112411FCFD24112411FC102013FE10701CA8E124422200200020 +5802:0100111009207FFE40029FF4101010101FF0010001003FF801000100FFFE0000 +5803:102008107EFE10201E3C1224122422444A94850801003FF801000100FFFE0000 +5804:20002040239C22042204FB9C2204220423FC209020903890E09041120212040E +5805:7F7C48447F44414841287F30481048287F44008201003FF801000100FFFE0000 +5806:21402120212023FE2220FE202BFC2220222023FC22203A20E22043FE02000200 +5807:08200820FFFE08200FE001003FF821083FF801007FFC01003FF80100FFFE0000 +5808:200023FE2202228A2252FBFE2222222222AA22AA22AA3AFAE2024202020A0204 +5809:2040202023FE20802104FBFE200221FC210421FC210439FCE104410401140108 +580A:00007FFC04403C78200820083C780440FFFE010001003FF801000100FFFE0000 +580B:200023DE225222522252FBDE22522252225223DE22523A52E2524252055208A6 +580C:200027FC2444244427FCFC44244425F42514251425143DF4E514440407FC0404 +580D:2100210021F02210FA2027FC2A442244224423FC22A438B0E128422A0422081E +580E:2020202021FC20202020FBFE20882144224220F821883A50E020405001880606 +580F:0820081009FE7E40187C2C442A8448948908080001003FF801000100FFFE0000 +5810:100013FE1210121012FEFE10121013FE1200121012101EFEE210441005FE0800 +5811:100CFEF0208048807EFE08880E88F9084A08090801003FF801000100FFFE0000 +5812:100011FC1104110411FCFD04110411FC1000111211D41D18E11041520192010E +5813:102011241124112411FCFC0011FE1100117C111011101DFEE110421002100410 +5814:100013FE120212521088FD041020102013FE102010701CA8E124422200200020 +5815:00207BFE484048FC51844AFC488468FC5084418C01003FF801000100FFFE0000 +5816:21242248249022482124F880210027FC2404251424A43C44E4A4451407FC0404 +5817:1040102013FE12021088FD0412221028102413FE10201C50E050408801040202 +5818:204022482150204023F8F88027FC2110224824443842E3F84040004007FC0000 +5819:200027FC20A020A027FCFCA424A424A427FC20403840E7FC404000400FFE0000 +581A:100013FE1222102013FEFC2011FC112411FC112411FC1C20E3FE402000200020 +581B:200023FE200021FC2104F90421FC200023FE222222223BFEE222422203FE0202 +581C:1020102013FE102011FCFD2411AC1174112411FC10201C70E0A8412402220020 +581D:100011FC1104110411E4FD24112413FE120212FA1E8AE28A42FA0202020A0204 +581E:20902290229027FE2290FA9022F0220023FC204027FE38E0E15042480C460040 +581F:208020FC210421F82008FBFE204020A22334205820943B34E052409003500020 +5820:2100217821082208FAFE26402A40227C2290221022FE3A10E228422802440282 +5821:08000BF8120833F8504097FC115012481446114001003FF801000100FFFE0000 +5822:2100217C21442244FA44267C2A10221022FE223822543A54E294431202100210 +5823:11FC1124112411FC1124FD2411FC1020102013FE12221E2AE2FA420A02020206 +5824:100011FC1104110411FCFD04110411FC100013FE10201D20E13C412002A0047E +5825:00407F40127E0C88FF4819482A504820A850118C01003FF801000100FFFE0000 +5826:1110111211D411181152FD92112E104011FC110411041DFCE104410401FC0104 +5827:100013FE1020104011FCFD54115411541154112C1C20E3FE4050008801040202 +5828:100011FC110411FC1104FDFC108011FE1222112211521D02E1FA400200140008 +5829:2100213C21002100F9BC25642524253C252421242124393CE1244100017E0100 +582A:1088108813FE108810F8FC8810F81088108813FE11001D48E184410001FE0000 +582B:20002088225222222252FA8A220223FE20882144227A3888E150402000D80706 +582C:204020A02110220825F6F80023C42254225423D422543A54E3D44244025402C8 +582D:1020104011FC110411FCFD0411FC100013FE102010201DFCE020402003FE0000 +582E:100013DE1252125213DEFC0011FC100013FE108011001DFCE004400400280010 +582F:010001003FF80100FFFE08203EF808200E2078FC0000FFFE044008421042603E +5830:200023FE220022FC2284FAFC228422FC222023FE22483AC8E2304248028403FE +5831:100010FC7C8410841094FE88448028FC7CA410A410A8FEA8109010A810C41082 +5832:7E7C42447E4442447E44484444545A486240404001003FF801000100FFFE0000 +5833:200023FC2224222423FCFA0022FC2284228422FC22843AFCE484448408FC1084 +5834:200023F8220823F82208FBF820002FFE220023FC24943924E244448401280210 +5835:2040204423F42048F85027FE2040208021F82B08350821F8C108010801F80108 +5836:2040204023FE208021FCFA2025FE200021FC210421FC3904E1FC410401140108 +5837:2080204027FC20002208F9102FFE200023F8220822083BF8E208420803F80208 +5838:20002FF828082868FB88288828882BE82AA82AA83BE8E88A48AA10EA17262002 +5839:1008103C11E0102013FEFC2011FC112411FC112411FC1C20E1FC402003FE0000 +583A:23F82248224823F82248FA4823F820A02110220825163910E110411002100410 +583B:204013F890484FFE404813F82040E3FC20402FFE2040204001003FF80100FFFE +583C:080808087E0808FEFE0808487E2808080F28F01001003FF801000100FFFE0000 +583D:100013FE1252125213FEFC00100013FE10201020113C1D20E120412007FE0000 +583E:2040204027FC204023F8F88027FE2110220827FC3A0AE20843F80208020803F8 +583F:20142012201027FE2410FC1025D02412241225D425543D48E5DA442A08461082 +5840:200023FC2204220423FCFA002284224822FC224822483BFEE448444808881108 +5841:3FF821083FF821083FF8600C183006C01830610C01003FF801000100FFFE0000 +5842:2110211027FC2110F1102FFE2110220827F42A123210E3F04204020401FC0000 +5843:2108210827FE2148F82027FE2200220023FC200022483A48E248444A044A0846 +5844:200023FC229422942294FBFC2080204027FE208020F83888E108410802280410 +5845:208023382228222823A8FA462200227C23A4222422283BA8E610422802440282 +5846:2080204027FE2090FA942492200023F8200823F822003BFCE004400400280010 +5847:1040102013FE12021404FDFC100011FC110411FC11041DFCE104400003FE0000 +5848:00007DFC44207D2045FE7C5048525492650E01003FF8010001000100FFFE0000 +5849:204022482150224824A4F918260623F8220823F822083BF8E208420802280210 +584A:2020204023FC22242224FBFC2224224423FC204020A838B4E13C41220222041E +584B:08202AA42CA84920145022887FFE4002810401003FF8010001000100FFFE0000 +584C:200023F8220823F82208FBF82000200027BC208424A43A94E4A4408402940108 +584D:0020792448A8482049FC78404BFE488849247A224C2049FC482048204BFE9800 +584E:1040102013FE12021050FC88112410501088110412FA1C88E088408800F80088 +584F:102011241124112411FCFC0013FE100011FC110411041DFCE088405003FE0000 +5850:1020102013FE102011FCFC2013FE1040108811F01C24E3FE4022012402A20040 +5851:2200147CFF44087C4944497C7F4408441094210841003FF801000100FFFE0000 +5852:201020102710257C2510F51025FE2708250825FE25083548E728400800280010 +5853:100013FE1202100011FCFD0411FC110411FC10401C20E3FE4000008801040202 +5854:2110211027FC21102040F8A02110220825F6200020003BF8E208420803F80208 +5855:21202110220824862910FBF82008200027BC208424A43A94E4A4408402940108 +5856:203823C0204027FC2150F954275821542354254C20E03950E248444408420040 +5857:204010A0911042084DF6104027FCE040224824442942208001003FF80100FFFE +5858:2040202027FE242025FCFC2427FE242425FC242025FC3D04E504490409FC1104 +5859:1040102013FE100011FCFD0411FC100013FE12021EFAE28A42FA0202020A0204 +585A:200027FE2402280427FEF8802184224426A821303AF0E4A8412802240CA20040 +585B:200027FC20A020A027FCFCA424A427FC2040204027FC38E0E15042480C460040 +585C:200027FE240229F42000FBF820802144266820B03928E66840A4012206A00040 +585D:2040202023FC21082090FBFE22022444202023FC208038F8E088410801280210 +585E:020001007FFE44429FF404403FF80440FFFE082011102108DFF6010001007FFC +585F:0820FFFE082000007FFC08401F48625014621842E03E01003FF801000100FFFE +5860:2010242022F82288F88820F82E80228022FC228422843AFCE284450008FE0000 +5861:111811E2110210FE1000FCFC128412FC128412FC12841EFCE20043FE01080204 +5862:1040108011FC11041104FDFC110011FE110011FE1C02E2AA42AA040200140008 +5863:200013F8920842084BF8080017FCE04023F8204027FC01003FF801000100FFFE +5864:100011F81108110811F8FC0013FC120413FC120413FC1E04E3FC409001080204 +5865:200023FE200021FC2104F90421FC200023FE228A22523BFEE2224222022A0204 +5866:7C2045FE482051FC492445FC452455FC482043FE402001003FF801000100FFFE +5867:220821082110200027FCF80021102208240423F822A83AA8E2A842A80FFE0000 +5868:2090209023FC20902090F89027FE209021482244244A3954E14A424A01400080 +5869:2100210021FE220025F8F908210821F8200023FC22943A94E294429407FE0000 +586A:101E11E0102211121094FC80102011CE1102110211CE1D02E102410201FE0102 +586B:2040204027FC204023F8FA0823F8220823F8220823F83A08EFFE411002080404 +586C:200027FE2420244025FCFD0425FC250425FC25243C20E4A849240A2210A00040 +586D:100011F81108110811F8FD08110811F8100013FC12941E94E294429407FE0000 +586E:2084210423C4224423DEFA4423C42264225427D420C43944E244444401540088 +586F:204023BE221222922252FAAA2324204023FE222222223BFEE222422203FE0202 +5870:210011FC920045F84148112823FEE148222823FC205001203FF801000100FFFE +5871:10007E7C42447E7C42447E7C484444445A94610801003FF801000100FFFE0000 +5872:210021FC220025F82108F9F8210821F8200027FE21003BFCE4A4412402540088 +5873:2020247C228421482030F8CE2610227C2210227C22103AFEE210421005FE0800 +5874:20202222222223FE2000FBDE2252225223DE225222523BDEE2524252055A08A4 +5875:010000803FFE22203FFC22243FFC28402F7828422F3E20802FF840807FFE8000 +5876:2040202023FE22502250FBFE2252225223FE220022923AD4E298449204D2088E +5877:20202020203E20202020FBFE22022326228A225223263A52E28A432603FE0202 +5878:200023FE2200227C2244FA44227C220022EE22AA22AA3AAAE2EE420003FE0000 +5879:08047F7808407F40497E7F4849487F4808487F48088801003FF801000100FFFE +587A:010000803FFE221022102FBC231826B42A52208020802FFC408040809FFE0000 +587B:1088108813FE10881000FDFC110411FC110411FC1C20E3FE4050008801040202 +587C:102013FE102011FC1124FDFC112411FC102213FE1C08E3FE4108008800280010 +587D:2040204027FC20402554FA482554204025542248255438A0E0A0411002080C06 +587E:1040FE4000407DF844487C4800C87C4808AAFEAA1106520221003FF80100FFFE +587F:102011FC112413FE1124FDFC102011FC112411FC1C40E3FE408801D00070038C +5880:200027FC240427FC2420FCA8247024A8250424A03CFCE52044200BFE08201020 +5881:23F8220823F8220823F8F80027FC24A424A427FC20003BF8E11040E003180C06 +5882:100013FE105011FC1154FD5411FC100011FC100013FE1C20E0A8412402A20040 +5883:2080204023F82110F8A027FE200023F8220823F822083BF8E120412202220C1E +5884:20142012201027FE2410FC9024D2249227F224943C94E5C84AAA089A11A60042 +5885:7F7C49047F2849107F7E08127F1408100F50F02001003FF801000100FFFE0000 +5886:22A822A827FC22A8FAAA24E6280027FC2444204023F83A48E248424802580040 +5887:102011FC1088105013FEFC0011FC110411FC110411FC1C20E3FE402000200020 +5888:224822482FE8224823DEF24A23CA224A224A2FEA240A354AE632441207EA0044 +5889:202027FE242025FCF42427FE242425FC242025FC3524E5FC452409FC0924112C +588A:08207E2008F8FF2814287F6A082AFF560882010001003FF801000100FFFE0000 +588B:2040208821FC21082252FBFE20502188262620C023103864E388403000C00700 +588C:2040202023FE22002248FA4823FE2248224822483A78E2004554052A0A2A1000 +588D:10007EFC42107E9042907EFE001040287E2840484C8A710601003FF80100FFFE +588E:2200211E27D2201227D4FC5427D8201427D22092211239DAE714411005100210 +588F:0420247E24943D48043005C87C0825FE24882448441881003FF801000100FFFE +5890:1088108813FE108810F8FC2011FC112411FC102013FE1C20E1FC402003FE0000 +5891:2040202023FE20882050FBFE222222FA222222FA228A3A8AE2FA4202020A0204 +5892:2040202023FE20882050FBFE2252228A230622FA228A3A8AE2FA4202020A0204 +5893:04407FFC04401FF010101FF010101FF00400FFFE10102108CFE6010001003FF8 +5894:1020122213FE10901088FDFE1310151011FE111011101DFEE110411001FE0100 +5895:200027FC20402278F2402FFE210021FC220023FC3004E5544554080400280010 +5896:204020A0211022082DF6F00023F8220823F8200027FC3444E7FC444407FC0404 +5897:21042088200023FE2222FBFE2222222223FE200021FC3904E1FC410401FC0104 +5898:2110211021102FDEF12027C0245C27C4244827C83110EFD041220122011E0100 +5899:2040204027FC20402248F95027FE200023F8220822E83AA8E2E8420803F80208 +589A:22782128246C22AA202AF94822982040204027FC20E03950E2484C4600400040 +589B:200427C42444244427DEFC0425C42404241427EC3C84E4C44AA40A8414940188 +589C:00887C5045FC484050A24B5444B8675458924350402001003FF801000100FFFE +589D:2020202021FC202023FEF908239C21082188263E20003BFEE09040900112020E +589E:22082110200027FC2444FD5424E4244427FC200023F83A08E3F8420803F80208 +589F:2040207C204023FE2242FA7823C4223C2200225022543B54E4D8445009FE0000 +58A0:100013DE1252125213DEFC0011FC112411FC112411FC1C20E3FE402000200020 +58A1:1088105013FE102011FCFC2013FE112410A813FE10001DFCE104410401FC0104 +58A2:202423A820922514F2082C0427BA20A827C6240037BCE08440A8009005280244 +58A3:20A024A422A820A027FCF91020A027FC204023F83840E7FC40A0011002080C06 +58A4:204023F8224823F8F84027FE200023F8220823F822083BF8E20843F801100208 +58A5:102011FC1088105013FEFC0011FC112411FC112411FC1C20E1FC402003FE0000 +58A6:103C13E0112410A813FEFCA81124120211FC112411241DFCE124412401FC0104 +58A7:203823C0208027FE2110FA0825F6291021F0200027FC3C04E5F4451405F4040C +58A8:00003FF8292825483FF801003FF80100FFFE2448422401003FF801000100FFFE +58A9:221021102FD0201027BEFCA427D4201427942094211439C8EF08411405140222 +58AA:08407F40007E3E8823483E4800503E5004207F500888290411003FF80100FFFE +58AB:2108209027FE209023FCFA94231C220423FC22043BFCE00847FE010800A80010 +58AC:00403C78248828F030102BFE244025A4345829B4205221B001003FF80100FFFE +58AD:2028202423FE22202224FBA42298249025AA284623FA3AA8E2A842A80FFE0000 +58AE:00407BFC488051F8622055FC488848F8688850F8408841003FF801000100FFFE +58AF:104013FE188055F8522095FC108810F8108810F8108801003FF801000100FFFE +58B0:200023FE205023FE2252FBFE200021FC210421FC210439FCE02043FE00200020 +58B1:202027A420A822922114FA0825F4280223F8220822083BF8E20841100FFE0000 +58B2:2100210023FC26A82AA8F2A827FC22A822A822A82FFE3000E2A8425404540000 +58B3:102011FC1020108813FEFC8811FC110411FC110411FC1D04E1FC408801040202 +58B4:2110211027FC21102110F7FE204027FC244427FC244437FCE000411002080404 +58B5:100011FC102013FE1222FDAC102011AC100011FC1C00E3FE4040008801FC0084 +58B6:20102410227C201020FEF844262822FE2210227C22103AFEE210421005FE0800 +58B7:108813FE1088100011FCFCA810A813FE10A810A811FC1C20E3FE402000200020 +58B8:2108210827FE21082044FBF42048205027FE208021FC3B04E5FC490401FC0104 +58B9:200027BC24A427BC24A4FFBC240425F4251425F425143DF4E514440404140408 +58BA:2080210027FC24442554FC4427FC24E4255424043840E7FE40A0011002080C06 +58BB:2040204027FC2248FA4825542FFE200023F8220822E83AA8E2E8420803F80208 +58BC:0800FF7808487F4849867F0049787F480828FF9049287F4401003FF80100FFFE +58BD:221024102F9028902FBEF8A42FD4241422142FD424143788E48848940A941122 +58BE:0600F8FC4A8424FC3884CCFC36A2CA9412A86AC4048201003FF801000100FFFE +58BF:200027FC24A427FC2040FBF8204027FC211020A03BF8E0404FFE004000400040 +58C0:20102008278824BEF48024942788247E2408278836BEEA884A880B8812880008 +58C1:00407C2045FC44887C5043FE7C20A5FC24203D2001003FF801000100FFFE0000 +58C2:3F7821483F4820862A783F482A483F2820104A289146200001003FF80100FFFE +58C3:100013FE100011FC1124FDFC112413FE100011FC11241DFCE12441FC000003FE +58C4:000027882088FABE210877D86B5CA52A29482508220801003FF801000100FFFE +58C5:02000100FFFE104824FE799010FC22907CFC089030FEC08001003FF80100FFFE +58C6:0A803138228838382288393822887FFE4002810401003FF801000100FFFE0000 +58C7:20402FFE200027FC2404FDF4251427FC200023F822083BF8E20843F800000FFE +58C8:20402FFE200027FC2404FDF4251425F4240427FC20083BF0E0404FFE01500E4E +58C9:2040207C204023FE2242FA7823C4223C220023FE22403BA4E25845B4045209B0 +58CA:2020202027FE202023FEFA52225223FE2040202027FE38A4E1A84290048800C6 +58CB:20402248215027FE2402F80423F8220823F8200027FC3C44E7FC444407FC0404 +58CC:2080204027FE2110FA08251423F8211023F8211027FC3928E3104D4801860100 +58CD:420C2FB082204FA00ABE2FA84AA8CFA842285FA84248028801003FF80100FFFE +58CE:203C27C020402FFEF04027FC255424E427FC204037FCE0404FFE000005240892 +58CF:201027D0251027DEFC5027E8250427C4200023F822A83AA8E2A842A80FFE0000 +58D0:7FFC111021087FFCB55A292835582108355829283458201801003FF80100FFFE +58D1:08000F00087CFFA480A47F24492494A822107F28A2443E0201003FF80100FFFE +58D2:211027FC2110204023F8F84027FC2080211023F820003BF8E2A842A80FFE0000 +58D3:00003FFE288C2F8A28882FBE20082F8828882F94289429A2404047FC80401FFE +58D4:204027FC204023FC2000F7FE200223F8204027FE200037FEE00847FE04A80798 +58D5:204027FE200021F8F90821F8200027FE240223F829803644E1B8466801A60E60 +58D6:100011FC102013FE1222FDAC102011AC100013FE10201DFCE15441540154010C +58D7:204023F8204827FE2048FBF8204027FE200022A424523BF8E2A842A80FFE0000 +58D8:00001FF011101FF011101FF000003EF82AA83EF82AA83EF801003FF80100FFFE +58D9:2040202027FE248825FCFC8827FE242025FC25243DFCE52445FC040004880904 +58DA:2040207C204023FC2244FBF0224422FC22A822F822A83AF8E20045FC05540BFE +58DB:27BC24A427BC24A427BCFC8424F42514262425B425143DB4E51445F404140408 +58DC:11FC110411FC110413FEFC2013FE122211AC102011FC1C00E3FE4040008801FC +58DD:202029FC252421FCF82023FE2D0425FC250425FC25043DFCE48845040BFE1000 +58DE:208020402FFE200027FCFCA427FC224821502208244438A8E11043080D460180 +58DF:08407E7C2440FF7C00047E7C42407E7C42407E7C4242463E01003FF80100FFFE +58E0:2210211027DE2010245EFA8227DE201027DE245027DE3C50E7DE4450045204CE +58E1:10001F7C1024FFA480A87F102A285546A2107F10A2BC3E1022103E1022FE3E00 +58E2:200027FE244425982488F7DE248825DC26AA248824203520E53C4920092017FE +58E3:40445F444AAA4AEE4E44EAAA4AEE4E004A284AAA6BAA4EEE9A28022802480288 +58E4:204027FC200023B8F2A823B8211027FC211027FC3110EFFE412803100D480186 +58E5:27FE240025FC25AC2574FDFC242025FC242027FE3C00E554482009FC102003FE +58E6:21102FFE211027BC24A4F7BC2140212023FE222027FC3A20E3FC422003FE0200 +58E7:27BC24A427BC200027FEFC002590249E27D4256425D43D54E5D445680BC81054 +58E8:00003EF82AA83EF82AA83EF800003EF82AA83EF82AA83EF801003FF80100FFFE +58E9:27FC20402FFE28422358F5002FBC25242724223C2FA43AA4EFBC42241FA4024C +58EA:244428E82E0E24E4FA0A2EEE20A02AEA200023F820083BF8E20043FC00040038 +58EB:010001000100010001000100FFFE01000100010001000100010001003FF80000 +58EC:001000F83F000100010001000100FFFE0100010001000100010001003FF80000 +58ED:01000100FFFE010001007FFC000000003FF80108010801280110010001000100 +58EE:0820082008204820282028200BFE182028204820882008200820082009FC0800 +58EF:042024202420242024203C2007FE0420FC20242024202420242045FC44008400 +58F0:01000100FFFE01007FFC00003FF8210821083FF8200020002000400040008000 +58F1:010001007FFC010001001FF000007FFE40028004101010E01F08100810080FF8 +58F2:010001007FFC010001001FF000007FFE4002844404400440044008441044203C +58F3:010001007FFC010001001FF000007FFE400280040FE00820082010222022C01E +58F4:01000100FFFE010001007FFC00001FF0101010101FF0000008200440FFFE0000 +58F5:010001007FFC0100010001003FF8000010101010FEFE1010101010107C7C0000 +58F6:010001007FFC010001001FF000007FFE40028444044024481448145004407FFC +58F7:010001007FFC01001FF000007FFE444284443FF8244824483FF804400440FFFE +58F8:010001007FFC01001FF000007FFE4002BFFC04402448144814500440FFFE0000 +58F9:010001007FFC01001FF000007FFE40029FF400001FF010101FF008200440FFFE +58FA:010001007FFC01001FF000007FFE444284443C7820083C7804400440FFFE0000 +58FB:100013FE10221120113CFD2012FE140011FC110411FC1D04E1FC410401140108 +58FC:010001007FFC01001FF000007FFE4002BFFC04403C7820083C780440FFFE0000 +58FD:01007FFC01003FF80000FFFE00023FF00100FFFE00007FFC00107DFC44907C30 +58FE:0800087EFF40084008407E7C00447E44424442447E7C424024400F40F07E4000 +58FF:1088105013FE105011FCFF54118C1174110411FC1C0873FE2108008800A80010 +5900:01003FF801001FF001007FFC01041FF011101FF00100FFFE00083EFE22483E18 +5901:0100FFFE01003FF800007FFC44447FFC00003FF821082FE8210827C824483FF8 +5902:0400040004000FF008101010302048208440028001000280044008203018C006 +5903:00003FF00410042004200440047C04040BE4082409441084114422244C288010 +5904:1040104010401E40126022502248524494441440084008401440230040FE8000 +5905:040004000FF01820644003801C70E10E01001FF0010021003FF8010001000100 +5906:040004000FF01820644003801C70E10E1FF001001FF001007FFC010001000100 +5907:040004000FF01820644003801C70E00E1FF0111011101FF0111011101FF01010 +5908:040004000FF01820644003801C70E10E111009207FFC05400920111061080100 +5909:01000100FFFE04401450244848C4140027F0082014402280410006C01830E00E +590A:0400040004002FF028101010302048208440028001000280044008203018C006 +590B:0400082010103FF8000808201210220847E4082014402280010006C01830E00E +590C:010001003FF801000100FFFE1210220847E4882214402280010006C01830E00E +590D:100010001FFC20005FF090101FF010101FF004000FF01820644003801C70E00E +590E:010011101110292845443FF801000100FFFE08000FF01420224041800E60701C +590F:7FFC02001FF010101FF010101FF010101FF008001FF02820444003801C70E00E +5910:10001FE020207FF8A30824881FF010101FF010101FF008001FF0282007C0F83E +5911:210827C820086B9AB02C2388200853944A928BA204000FE0144003801C70E00E +5912:0000FFFE110013DC52545BD4525C53D05A52E3CE24084FE4944203801C70E00E +5913:17C0621C47C4444477DC444447C4745C47C4000024084FE4944203801C70E00E +5914:0440FFFE110013DC52545BD4525C53D05A52E3CE24084FE4944203801C70E00E +5915:020002000200020007F80408080810102410422001400080010002000C007000 +5916:10401040104010403E40226042504248A4441444084008401040204040408040 +5917:1000100010F81E8812882288228852888AA804900480088208821082207E4000 +5918:10001000107C1E4412442244224452448A440444044408540848104020404040 +5919:00003FF8200820082FE82208220827C8244828483488228A210A420A44068802 +591A:0200020007F008203840048003400C8071F802080C103220014001800E007000 +591B:00003FF0001000101FF000100010FFFE020007F008103420024001800E007000 +591C:02000100FFFE0880088010F81108314852289510111010A0104010A011181606 +591D:2020202021203D2025FC45204620A420142009FC082010201020202043FE8000 +591E:102010203F304128A224142208203020C02000003E442258226022423E42223E +591F:20202020407C7E4482A802107A204AD04A1E4A227A644A9402080210142008C0 +5920:102010203E40427EA4821902107A284ACF4A114A327A4A4A040208023014C008 +5921:101010103E1042FEA4101810107C2800CF00117C32444A4404440844307CC044 +5922:0820FFFE08203FF824483FF800007FFE420287F408103420024001800E007000 +5923:0100FFFE10103FF800003FF824483FF800007FFE44028FF4342002C007007800 +5924:02000FF0346003801D007FFE4002BFFC01003FF821083FF821083FF810102008 +5925:00207E204A7C4A447EA84A104A207ED0081EFF2218642C942A084A10882008C0 +5926:22202220FF7C22443EA822103E2022D0221EFF2240645494620840107E2000C0 +5927:01000100010001000100FFFE010001000280028004400440082010102008C006 +5928:100010001000200020007F80008001000100FFFE01000280044008203018C006 +5929:00003FF80100010001000100FFFE01000280028004400440082010102008C006 +592A:01000100010001000100FFFE0100010002800280044004400A2011102108C006 +592B:01000100010001003FF8010001000100FFFE028004400440082010102008C006 +592C:0100010001001FF001100110011001100110FFFE02800280044008203018C006 +592D:001000F83F000100010001000100FFFE0100028002800440082010102008C006 +592E:0100010001001FF011101110111011101110FFFE02800280044008203018C006 +592F:010001007FFC0280044008203018C10601003FF8020802080408080810506020 +5930:010001007FFC0280044008203018C44604400440044004400840084010402040 +5931:01001100110011001FF8210041000100FFFE010002800280044008201010600C +5932:010001007FFC0280044008203118C10601000100FFFE01000100010001000100 +5933:010001000100FFFE02800440082010102008CFE600000000000000007FFC0000 +5934:00800080088004802480108010800080FFFE010001400220041008083004C004 +5935:010001007FFC0280044008203018C10601000920091011082104410405000200 +5936:082008200820082008207EFE0820082008501450125012882088210442048402 +5937:01000100FFFE01003FF8010801083FF8210021003FFC0284044C08203018C006 +5938:010001007FFC0440082017D02008C0063FF8040008000FF00010001000A00040 +5939:0100010001007FFC0100111009200100FFFE010002800280044008203018C006 +593A:010001007FFC0280044008203018C0460040FFFE004010400840084001400080 +593B:010001007FFC01000280044008203018C0061FF010101010101010101FF01010 +593C:010001007FFC0280044008203018C92609200920092009201120112021204020 +593D:020002007FFC044008203018CFE6000000007FFC02000400082010103FF81008 +593E:0100010001007FFC01001110111011102928454402800280044008203018C006 +593F:010001007FFC0280044008203018DFF61110111011101FF0100410040FFC0000 +5940:00007FFC01000300056019186104000001000100FFFE0280044008203018C006 +5941:020002007FFC044008203018DFF610001220114010801140122010001FF80000 +5942:080008000FE0102020405FF09110111011101110FFFE0280044008203018C006 +5943:020002007FFC044008203018C0F63F00210021003FFC208020402A243114210C +5944:020002007FFC044009203118DFF6111011101FF0111011101FF40104010400FC +5945:020002007FFC044008203018C60638F82088228822882E8832A8249004800880 +5946:020002007FFC044008203018DFF6100010001FE0102010201FE0100010001FF8 +5947:010001003FF8028004400820FFFE001000101F90109010901F90001000500020 +5948:020002007FFC044008203018CFE6000000007FFC010011101108210445040200 +5949:010001007FFC01003FF80200FFFE044009203118CFE6010001003FF801000100 +594A:00800FF840805FFC40804FF840805FFC40007F0001007FFC028004401830E00E +594B:010001007FFC0280044008203018C0061FF0111011101FF0111011101FF01010 +594C:0100010001FC010001001FF0101010101FF0010001007FFC028004401830E00E +594D:0100111009203FF8020002007FFC082010102448C44604400840084010402040 +594E:020002007FFC044009203118CFE6010001007FFC000001003FF801000100FFFE +594F:010001007FFC01003FF80200FFFE0440082037D8C1061FF0010002C00C303008 +5950:080008001FE020204040BFF822882448282821080100FFFE028004401830E00E +5951:080008007F7C08243E2408247F44085409880100FFFE0280044008203018C006 +5952:020002007FFC04400A203118DFF6040008401F8001100620384001A00E107008 +5953:020002007FFC044008203218C7E618400580068039F80610192000C003003C00 +5954:020002007FFC044009203118CFE60100092008207FFC08200820102010202020 +5955:020001007FFC0440245044488944108001000100FFFE0280044008203018C006 +5956:0840484028FC09041A8828504820884009800100FFFE0280044008203018C006 +5957:010001007FFC028004400FF03418C7E6040007E00400FFFE040008101FF80008 +5958:2420242024203DFC0420FC20242024F845000100FFFE0280044008203018C006 +5959:040008201FF00210FFFE08203118DFF611101FF011101FF40104010400FC0000 +595A:00FC7F002208151008401F8003200C103FF8010801007FFC028004401830E00E +595B:020002007FFC044008203018C0063CF824883CF8248824F83C88248801280210 +595C:044004407C7C04403C7804407C7C044005400100FFFE0280044008203018C006 +595D:020002007FFC044008203FF8D11617D011101FF0101017D0245027D040108030 +595E:020002007FFC044008203018C90608801FFC30805FF890801FF810801FFC1000 +595F:020002007FFC044008203E78D24E12481E78124812481E78124822882AA84510 +5960:08200440FFFE04403FF82848303827C820083FF801007FFC028004401830E00E +5961:7FFC02001FF010101FF010101FF010101FF00200FFFE08203458C44608401040 +5962:020002007FFC044008203218DFD60220FFFE03000FF03810CFF008100FF00810 +5963:00003FF802007FFC04401830E00E3CF8248824F83C8824F824883C8801280210 +5964:020002007FFC044008203FF8C10602003FF8244827C8244827C824483FF82008 +5965:020004003FF82008292825482FE82548292820080100FFFE02800C603018C006 +5966:00407EFC15440838FE441AA22CFC4844A894110801007FFC028004401830E00E +5967:020004003FF820682FA825482FE823482528280801007FFC02800C603018C006 +5968:083E4BC42A48292008081BFE2908C8880828091001007FFC028004401830E00E +5969:02007FFC04201818E0063FF8200027F0241027F020002F7829482F7820003FFC +596A:02007FFC04201898E8461FF830805FF810801FF810801FFC1020FFFE08200460 +596B:020002007FFC044008203018C14625481778840847F814082778E54825482808 +596C:0440247C24A83D5004287DFE2488444885180100FFFE0280044008203018C006 +596D:01000100FFFE01007D7C11107D7C45447D7C45447D7C0280044008203018C006 +596E:02007FFC04201818E9061FF831005FF891001FFC10003FF821083FF821083FF8 +596F:02007FFC04201918E9E609007FFC00283FFE20202FA422282A90532A46469882 +5970:00003FF824483FF80000FEFEAAAAAAAAFEFE010001007FFC028004401830E00E +5971:210447C88812F3BC20084B92F83E0380AAAAABAA01007FFC028004401830E00E +5972:100010EEFEAA28AA44EE90007AFE1492FEFE10927CFEC4107DFE44107C104410 +5973:02000200020002000400FFFE0420082008201040184006800180066018106008 +5974:1000100011FC1084FC8424842488248824504850282010202850448881040202 +5975:1000100013FE1020FC2024202420242024204820282010202820442084A00040 +5976:1000100013F81088FC90249024A024BC24844884290411042904460482280410 +5977:1008103C11E01020FC202420242027FE24204820282010202820442084200020 +5978:100011FC10201020FE202220222023FE42202420142008201420222042208020 +5979:1020102010201120FD2C2534256427A425244934292811222922450284FE0000 +597A:10801080108010F8FD0825082510261024204820285010502888450882040402 +597B:1020102010201020FEFE22442244224442442484144808281410222842448082 +597C:1010103811E01020FE2022202220223E43E024201420082214222222421E8000 +597D:100010FC10041008FC102420242025FE24204820282010202820442084A00040 +597E:1020102010201020FD242524252425242524492429241124292445FC80040000 +597F:20402040204023FEFC88248825082490645024203450248A2502440243FE8000 +5980:00400040FC40044007FE048804887C8840884108409044505820605040880304 +5981:10401040108010FCFD0426042404250424844844284410042804440484280010 +5982:100010001000107CFE4422442244224442442444144408441444227C42448000 +5983:1000100011F81008FC082408240825F825084900290011002902450284FE0000 +5984:02000100FFFE100010001FF802000200FFFE042008201E400180066018186004 +5985:1000100011FC1020FC2024202420242024204820282010202820442083FE0000 +5986:08400840084048402BFE28880888088818882908C89008500820085008880B04 +5987:1000100011FC1004FC042404240425FC2404480428041004280445FC80040000 +5988:100013F010101010FD102510251025FC24044804280413F42804440484280010 +5989:10201020102011FEFD222624242024202450485028501050289044928512020E +598A:1008103C11E01020FC202420242027FE24204820282010202820442085FC0000 +598B:1020102010201020FDFC24202420242027FE4820285010502888448885040202 +598C:1088108810881088FDFC24882488248827FE4888288810882888450885080208 +598D:100013FE10881088FC882488248827FE24884888288810882888448881080208 +598E:1020102010501050FC8825042602248824884888288810882888450881080208 +598F:10401020102013FEFC8824882488248824884850285010202850448881040602 +5990:1010109010901088FC882524252426222420484028481044288445FE84820000 +5991:1000100011FC1124FD2425242524252425FC4900290011002902450284FE0000 +5992:10401020102011FEFD022502250225FE25024900290011002A00460084000800 +5993:10201020102013FEFC202420242025FC24844888284810502820445081880606 +5994:10801040104013FCFC00240025F02510251049102910111229124612820E0400 +5995:1020102010201020FDFC252425242524252449FC292410202820442084200020 +5996:1008103C11E01020FC20242025FE242024204850285010502888448881040202 +5997:1020102010501050FC88254426222420240049FC280410082808441084100020 +5998:1000100010FC1000FC00240025FE24202420484028401088288445FE84820000 +5999:10201020102010A8FCA424A22522252026244824282810082810442080C00300 +599A:1000100011FE1010FC1024202420246824A449222A2210202820442084200020 +599B:01002108210821083FF801000100FFFE02000200FFFE08201C4003800C707008 +599C:10401040104013F8FC4824482448244827FE484028A010A02910451082080406 +599D:042024202420242025FE3C4404440444FC442484244824282410442844448582 +599E:100011F810481048FC482448244825F824884888288810882888448883FE0000 +599F:00001FF0101010101FF0101010101FF002000200FFFE08201C4003800C707008 +59A0:1020102010201020FDFE2522252225222552494A298A110229024502850A0104 +59A1:1008101C11E01100FD00250025FE251025104910291011102910461082100410 +59A2:1010109010901088FD082504260425FA24884888288810882908450882280410 +59A3:1010111011101112FD12251425D82510251049102910111229524592850E0000 +59A4:100011F810081050FC20241027FE242224244820282010202820442084A00040 +59A5:00FC7F00020821081110102002000200FFFE042008201E400180066018186004 +59A6:10201020102013FEFC202420242025FC24204820282013FE2820442084200020 +59A7:100011FC10001000FC0027FE24902490249048902890109229124512820E0400 +59A8:10401020102011FEFC4024402440247C24444844284410442884448481280210 +59A9:200023FC20402040F84048404FFE484088A048A030A0112029224A22841E0800 +59AA:100011FE11001104FD4425282528251025104928292811442984450085FE0000 +59AB:1020112010A010A0FC2027FE2422242224424852284A108A2882450282140408 +59AC:1000100013FE1020FC202440244024FC25844A842C8410842884448484FC0084 +59AD:2050204820482040FBFE4880488048FC89444944312811282A104A2884440182 +59AE:100011FC11041104FD0425FC25002540254449482970114029424642823E0400 +59AF:1020102010201020FDFC252425242524252449FC292411242924452485FC0104 +59B0:10801080108010FEFD4025402640247C244048402840107C2840444084400040 +59B1:100013FC10841084FC84250425142608240049FC290411042904450485FC0104 +59B2:1000100010FC1084FC84248424FC24842484488428FC10842800440085FE0000 +59B3:10801080108010FEFD0225042620242024A848A4292411222A22442080A00040 +59B4:100010F83E884288A4A818941084207CC2000200FFFE08201C4003800C707008 +59B5:10401020100013FEFC2024202420242025FC4820282010202820442083FE0000 +59B6:10201010101011FEFC2024202444248425F8481028201044288245FE84820000 +59B7:1020102011201120FDFC25202620242025FE4820285010502888448885040202 +59B8:1000100013FE1008FC0825E8252825282528492829E811282808440884280010 +59B9:10201020102011FCFC202420242027FE247048A828A811242924462284200020 +59BA:10201020102013FEFC202420242025FC247048A828A811242924462280200020 +59BB:010001007FFC01003FF80108FFFE01083FF80200FFFE08201C4003800C707008 +59BC:1040102010281008FC08244824542552255249602A60104428C44544823C0000 +59BD:10201020102011FCFD242524252425FC25244924292411FC2924442080200020 +59BE:020001003FF8000008200440FFFE020002007FFC042008401C8003800C707008 +59BF:100010007E7C1244124422444A7C844402000200FFFE08201C4003800C707008 +59C0:101C11E010201020FC2027FE24202470247048A828A811242A22442080200020 +59C1:10801080110011FCFE04240425E425242524492429E411242804440484280010 +59C2:1004101E11E01000FC20241025FE2404240848102820104028804540823E0000 +59C3:1000100013FE1020FC20242025202520253C4920292011202920452087FE0000 +59C4:100011FC11041104FD0425FC2520252025FE4920292011102912454A85860102 +59C5:10201020112410A4FCA8242025FC2420242048202BFE10202820442084200020 +59C6:100010FC108410A4FC942484248427FE250449442924110429FE440484280010 +59C7:0810081017FE3010521091101110105012200200FFFE08201C4003800C707008 +59C8:1020102010501050FC8825242612241025FC4804280810882850442084100010 +59C9:10201020102013FEFC20242025FC252425244924292411342928442084200020 +59CA:10201020102E11F0FD202520252025FE2422486228A2112A2E24442084200020 +59CB:1020102010201040FC48248425FE2482240048FC288410842884448480FC0084 +59CC:10201020102011FCFD24252425FC2524252449242BFE11042904450485140108 +59CD:100011FC11541154FD542554255427FE25544954295411542954454485140108 +59CE:10201020102011FCFD2425242524252425244BFE282010502850448881040202 +59CF:1088108810881088FDFE248824882488248848F8288810882888448884F80088 +59D0:100011F811081108FD0825F825082508250849F8290811082908450887FE0000 +59D1:1020102010201020FDFE24202420242025FC4904290411042904450485FC0104 +59D2:1008104811281128FD2825082508250825084908294811942914442284420082 +59D3:1020102011201120FDFC252026202420242049FC282010202820442083FE0000 +59D4:00701F8001000100FFFE054009203118C2060200FFFE08201C4003800C707008 +59D5:0880088828902EA028C028842E84F07C02000200FFFE08201C4003800C707008 +59D6:100011FE11001100FD0025FC250425042504490429FC11002900450085FE0000 +59D7:100011DC11541154FD542554255427FE2554495429541154295446D48224044C +59D8:1104108410881000FDFE24882488248824884BFE288810882908450882080408 +59D9:10801088109C1170FD1027102510251025FE49102910111029104510857C0100 +59DA:2090209020902292F9944898489049988A944C9230901090291249128212040E +59DB:100011FE11021102FD7A25022502257A254A494A294A117A29024502850A0104 +59DC:082004407FFC01003FF80100FFFE02000400FFFE082010201C4003800C707008 +59DD:20202120212021FCF9204A2048204BFE487090A850A8212431244A2248208020 +59DE:10201020102013FEFC20242025FC2400240049FC290411042904450485FC0104 +59DF:10201010101013FEFC202442248425F82410482228C413082810442880C40302 +59E0:10201020104011FEFD022502257A254A254A494A294A117A29024502850A0104 +59E1:1008103C11E01020FC2027FE24202420242049FC290411042904450485FC0104 +59E2:1020102010481084FDFE2402240024FC248448FC288410FC2884448484940088 +59E3:10401020102011FEFC0024882504260224884888285010502820445080880306 +59E4:1008101C11E01100FD0025FE25002500257C4944294411442944467C82440400 +59E5:10401040104411F4FC48245027FE2440248049842A9810E028824482847E0000 +59E6:04000400FFFE08201C4003800C70700800101010FEFE2224646418182434C2C2 +59E7:10001000FE7C2210641018102410C21010FE1010FE102210641018102410C210 +59E8:2040204027FC2040FBF848484BF84A408BFC4844305410A828A0491082080406 +59E9:1080108010FE1110FE10241024FC2490249048902BFE10102810441084100010 +59EA:100011FE10201040FC88250425FE24222420482029FE10202820442083FE0000 +59EB:100011FE11201120FD2025FC250425042504490429FC11202920452085FE0000 +59EC:100011FE11101110FD10257C2544254425444944297C11102910451085FE0000 +59ED:02001FF00410085010207EFC12242A5444880400FFFE08201C4003800C707008 +59EE:100013FE10001000FDFC2504250425FC2504490429FC11042800440083FE0000 +59EF:1040104412441148FD50244027FE2490249048902890109229124512820E0400 +59F0:1080108011FC1104FE0425E42524252425E44924292411E42904440484280010 +59F1:1020102013FE1050FC88250426FA240027FE4840288011FC2804440484280010 +59F2:20402020202023FEFA024C4448404BFE48889088510820D03020485048888304 +59F3:1040104010FC1104FE88245024202440248049FC2A8410842884448484FC0084 +59F4:00047FA410243F2451240A040C043014C2080200FFFE08201C4003800C707008 +59F5:200027FC24042404F5F45444544455F455549554555425542574544654468842 +59F6:1020102010501088FD04260225FC2400240049FC290411042904450485FC0104 +59F7:1020102011FE1040FC4024FC2484258426FC4884288410FC2884448484940088 +59F8:100011DC10881088FC882488248827DE24884888288810882888450881080208 +59F9:10401020102011FEFD022604241825E024404840287E13C0284044448444003C +59FA:10201120112011FCFD202620242027FE2490489028901090291245128212040E +59FB:100011FC11041124FD24252425FC252425244954294C118C2904450481FC0104 +59FC:10201020107C1084FD482430242024482590483E284211A42818441084600180 +59FD:1040104010FC1104FE0825FE2500257C254449442954114829424542853E0200 +59FE:1020102010501088FD04260225FC24202420482029FC10202820442083FE0000 +59FF:4080208009FC12042448E04020A023182C060400FFFE08201C4003800C707008 +5A00:2028202420242020FBFE48204924492489244BA8312811102A124A2A84460082 +5A01:0028002400203FFE202020203FE4222422243FA824A828902512422A45469882 +5A02:1088108810881088FDFE24882488248824884BFE280010882884450482020402 +5A03:1020102011FC1020FC20242027FE24002420482029FC10202820442083FE0000 +5A04:010011100920FFFE054009203118C0060200FFFE042008201C4003800C707008 +5A05:200023FC20902090F89048924C924A948A944A98309010902890489087FE0000 +5A06:2080208020BC23C0F850482448D44B0C88004BFE3090109029124912820E0400 +5A07:1008101C10E01020FC2025FE2450248825044A8A288810882888448884880108 +5A08:02000100FFFE0440145014482444420402007FFC042008401C8003800C707008 +5A09:1020102011FC1124FDFC252425FC240027FE4880290011FC2804440484280010 +5A0A:100011F811081108FDF82508250825F82508490829F81090289045128212040E +5A0B:1020112410A410A8FC2025FC2504250425FC4904290411FC2904450485140108 +5A0C:100011FC11241124FDFC2524252425FC2420482029FC10202820442087FE0000 +5A0D:2028202420242020FBFE4A204A244A248BA44AA832A812902A924DAA84460882 +5A0E:080C08F07E8008800EFE78880888290812080200FFFE08201C4003800C707008 +5A0F:10901088108013FEFCA024A824B024A424A848B02924112A2932462282DE0400 +5A10:1008103C11C01004FD4424A8240025F8241048202BFE10202820442084A00040 +5A11:1020082040A824A4092A723010C0170002007FFC042008401C8003800C707008 +5A12:1080108010FE1100FEFC248424A4249425FE48842924111429FE440484280010 +5A13:200023FC22042204FBFC4A004A184AE08A384AE0323C13E02A224C22841E0800 +5A14:1020102013FE1020FC2025FC25042504250449FC28501050289244928112020E +5A15:1020102013FE1020FC2025FC2524252425FC4820287010A82924462280200020 +5A16:100011FC11041104FD04250425FC242024204920293E1120292046A0847E0800 +5A17:2000200623B82088F8884908493E4B8888884A883288113E29004A80847E0800 +5A18:1040102011FC1104FD0425FC2504250425FC4920292211142908454485820100 +5A19:100011FE10001092FD24264825242492240049FE282010202820442083FE0000 +5A1A:11FC1124112411FCFD24252425FC244024404BFE284210822882450282140408 +5A1B:200020F820882088FAF84A004A004BFC8844484437FE104028A0491082080406 +5A1C:20002FDE22522252F25457D45258525452529FD25252225A2254545055508890 +5A1D:100013FE10101020FC6824A427222420240049FC290411042904450485FC0104 +5A1E:2008203C23C02044FA244928490048408BFE4888310813902860485081880604 +5A1F:200021F821082108F9F848004BFC4A044A0493FC5204220433FC4A044A148208 +5A20:200023FC22002200FAF84A004A004BFC8AA04AA432A812902A904C8884A408C2 +5A21:20202020202023FEF8204820482049FC8840482030A412822A8A4A8A84780000 +5A22:1020102010501088FD44262224F824082410482029FC11042904450485FC0104 +5A23:11081088109011FCFC24242425FC2520252049FE286210A2292A462484200020 +5A24:2420242024203DFC0420FC20242024F846000200FFFE08201C4003800C707008 +5A25:101010D813941094FC9027FE24902494249448D82B98109028AA44CA84860182 +5A26:1010103811C01100FD0025FC25102510251049102BFE10002890450882040402 +5A27:1104108410881010FDFC25042504250425FC48502850109028924512820E0400 +5A28:100011FC110411FCFD0425FC2400240025FC4820282013FE2820442084200020 +5A29:1080108010F81108FE1025FC25242524252449FC28501050289044928112020E +5A2A:100013FE10401040FDFC2484248427FE2400480029FC11042904450485FC0104 +5A2B:2004200E23B82088F8884928492E4BA888A84AA832A8113E29004A80847E0800 +5A2C:2010201823D42014F8104FFE4810489088904AD0329012902A8A4AEA87060202 +5A2D:2020204020882104FBFE4882488049FC8A20482033FE10202850488881040602 +5A2E:1040102013FE1000FC0025FC2400240025FC4800280011FC2904450485FC0104 +5A2F:200020F820882088FAF84A004A004BFC8804480437FE100028A0491082080406 +5A30:21082148212822A8FAA84E884A884A884A88928852A822D432944A224A428282 +5A31:200023F822082208FBF8480048004BF88840484037FE104028A0491082080406 +5A32:200021FC21042104F90449FC482048204BFE92225252228A330A4A024A0A8204 +5A33:204220E22382208AF88A488A4BEA488A498A91CA52AA228234824882488A8084 +5A34:110010BC10041124FD24252425FC2524257449AC292411242924450485140108 +5A35:200027E0225E2252FA524BD24A524A544BD49254524822E83754485448628040 +5A36:00007F7C22443E4422283E1023A8FE4402820400FFFE08201C4003800C707008 +5A37:1008103C11E01020FDFE24A824A824A827FE48A828A813FE2820442085FC0000 +5A38:1088108813FE1088FC8824F82488248824F84888288813FE2800448885040202 +5A39:20102388208820FEF8904B904A244A244A3893885090209030A448BE4A828100 +5A3A:200023DE2042214AF884494A4A524C2088004BDE305211522894494882540422 +5A3B:1020102013FE1020FDFC252425FC252425FC4820287010A82924462280200020 +5A3C:10FC1084108410FCFC84248424FC240025FE4902290211FE2902450285FE0102 +5A3D:100011F810081008FDF82408240827FE24204A22297410A82924462280A00040 +5A3E:100011FE11101110FD7C2510251025FE250049102910117C2910461082FE0400 +5A3F:00007BFE480851E8492845E85408482842100200FFFE08201C4003800C707008 +5A40:2000277E25042504F57455545654555455549554557425542604540454148408 +5A41:01001FF01110FFFE11101FF001001FF011101FF00200FFFE08201C4003C03C38 +5A42:2020204021FC2104F9FC490449FC4820482093FE52222222322A4A2448208020 +5A43:2040202023FE2202F80049FC480048004BFE90205128212432224C2248A08040 +5A44:1040102011FC1000FD082490240027FE2400480029FC11042904450485FC0104 +5A45:1100110011FC1204FC44255424E4244427FC484428E411542A44444484140008 +5A46:202013FE922242204BFC1284E448243029CE0400FFFE08201C4003800C707008 +5A47:2008203C23C02044FA244928490048208BFE487030A810A829244A2284200020 +5A48:2020202021FC2020F8204BFE488849448A4248F8318812502820485081880606 +5A49:2040202023FE2202FD04490049DE4A528A524B52349A1094291049128212040E +5A4A:1020102013FE1020FC2025FC2420242027FE484028A411A82A90448884C60080 +5A4B:10201020103E1020FDFE2522253825E02522491E290011782A48464A848A0906 +5A4C:2100210021DC2114F114511457D4501451149114558825482948511455148222 +5A4D:1020102011FC1050FC88250427FE240825E84928292811E82928440884280010 +5A4E:10A01090109011FEFD20252027FC2520252049FC29201120292045FE85000100 +5A4F:1080108010F81108FE1025FC25242524252449FC28501058289444928112020E +5A50:100011FC11241124FDFC2524252425FC24204BFE287010A82924462280200020 +5A51:201C21E020202020FBFE48A849244A42484093FE5088210830D0483048488184 +5A52:102010A210A21124FC50248827042422242048A428A411282850448885040202 +5A53:04400440FC7E04407C7C0440FC7E044006400200FFFE08201C4003800C707008 +5A54:209020902090279EF890489048904B9C489090905090279E3090489048908090 +5A55:2020202023FE2020F9FC48244BFE482489FC48203120113E29204AA0827E0400 +5A56:200023FC20402040FBFE48A049104A084C4690405048226432524C5249408080 +5A57:20002040239C2204FA044B9C4A044A048BFC489030901090289049128212040E +5A58:1020112410A81020FDFC244027FE248825044AFA2C88108828A844928482007E +5A59:1080108010F81108FE1025FC2424242425FE4824282411FC2824442084A00040 +5A5A:201C23E0222023FEFA204A924B0A4A0649FC9104510421FC3104490449FC8104 +5A5B:1040102013FE1000FC0025FC2504250425FC4820292811242A22442280A00040 +5A5C:00007F7C48447F4441287F1048287F4400820400FFFE08201C4003800C707008 +5A5D:2040202023FE2202FC0448004BFE482088204920313C11202AA04A60843E0800 +5A5E:1020102011FC1020FC2027FE2488245025FC4820282013FE2820442084200020 +5A5F:200023FE22222222FBFE4A224A224AFA4A8A928A528A22FA328A4A024BFE8202 +5A60:1040102013FE1202FC0425F82508250825F84900290011FC2904450485FC0104 +5A61:20202020202023FEF8204924492449248AAA487030A810A829244A2284200020 +5A62:1040108011FC1124FD2425FC2524254425FC4890291013FE2810441084100010 +5A63:2050225222522252FBDE4A024A024BFE8A024A0233DE12522A52425284520802 +5A64:200023FE22222222FAFA4A224A224BFE8A024AFA328A128A2AFA4A02820A0404 +5A65:10201020103E1020FDFC250425FC250425FC4924282013FE2820442084200020 +5A66:200021FC200420FCF80449FC48004BFE4A22902051FC21243124493449288020 +5A67:1020102013FE1020FDFC242027FE240025FC490429FC110429FC450485140108 +5A68:1020102010501088FD0426FA240025FC2554495429FC1154295445548504010C +5A69:1020112411241124FDFC240025FE2500257C4910291011FE2910461082100410 +5A6A:082008207EFC08301C682AA4C92208200A207FFC042008401C80038006703808 +5A6B:100011FC11041104FDFC2504250425FC2400491229D41118291045528592010E +5A6C:1008103C11C01044FD2424A82490241C25E04820282013FE2820442085FC0000 +5A6D:100011FE10481048FC4825CE25022502250249CE284810482848444885FE0000 +5A6E:100011FC11041104FDFC2510251025FE25104910297C114429444544857C0244 +5A6F:0000FEFE00007C7C444464645454444446440200FFFE08201C4003800C707008 +5A70:10501050105011FCFD542554255425FC25544954295413FE2800448881040202 +5A71:00407C2005FC7C4040887DF00420044829FC10040200FFFE08201C4003C03C38 +5A72:1088108813FE1088FC8824502450249425944A98289010B228D24492848E0080 +5A73:200023FE20002000F8F848A84AAA4AFA4AAA92AA52AA22FA32024A024BFE8002 +5A74:00003EF822882AA82AA82AA81450628802007FFC042008401C80038006703808 +5A75:11041088105011FCFD24252425FC2524252449FC282010202BFE442084200020 +5A76:2040202023FE2222F82049FC4924492449FC9124512421FC3124482048208020 +5A77:1040102013FE1000FDFC250425FC240027FE4A0229FC10202820442084A00040 +5A78:100010FC108410FCFC8424FC240025FE248048FE292A124A2892452284540088 +5A79:200023FE20502050FBFE4A524A524BFE4800904057FE20883190486048D88304 +5A7A:00207E20247E18A4FF2829104A2898C602007FFC042008401C80038006703808 +5A7B:2020202023FE2020F8204BFE4A8A4A524AFA9222522222FA32224A224A2A8204 +5A7C:1088108813FE1088FCA8242027FE2440248048FC298412842884448484FC0084 +5A7D:200023DE22422242FA424BDE4A004A3E4BD29212521423D432084A144A248242 +5A7E:21C020A021102208FDF648004BCA4A4A4A5493D45268225433D44A4A4A4A82C0 +5A7F:100013FE10221120FD3C252026FE240025FC490429FC110429FC450481140108 +5A80:21FC2124212421FCF924492449FC4820482093FE5222222A32FA4A0A4A028206 +5A81:2040204021FC2084FBFE480049FC490449FC902053FE202032204BFE48208020 +5A82:2040202021FC2000F88848504BFE4A224C2491FC512421243134492848208020 +5A83:200021FC20482030FBFE4852489449108A30482033FE107028A8492486220020 +5A84:1104108813FE1020FC2025FC2420242027FE4800282013FE2820445080880306 +5A85:1088108813FE1088FCF8248824F8248824884BFE290011482984450085FE0000 +5A86:100013FE10201040FDFC2554255425542554492C282013FE2850448881040202 +5A87:1040102011FC1000FC88245027FE2420242049FC282010A82924462280A00040 +5A88:200023FE22222020FBFE482049FC492449FC912451FC202033FE482048208020 +5A89:200023FC22042204FBFC4A004BFC4A408A884BFC322412202DFC4420882013FE +5A8A:21082088209027FEF8004BC44A544A544BD49254525423D432544A444A5482C8 +5A8B:1020102013FE1020FDFC244027FE248825044AFA2888108828F84488848800F8 +5A8C:1088108813FE1088FC88240025FC25242524492429FC11242924452485FC0104 +5A8D:1040104010F81108FE1025FC250425FC250449FC290411FC2800448881040202 +5A8E:1020102211FA1024FC2827FE2420244024FC49842A8410FC2884448484FC0084 +5A8F:1020112411241124FDFC240027FE2420244049FC29541154295445548554010C +5A90:00007F7C444444445F7C51405F4244427FBE0200FFFE08201C4003800C707008 +5A91:2008203C21E02020FBFE482049FC492449FC912451FC202031FC48204BFE8000 +5A92:21102110211027FCF91029F0291029F048404FFE284010E011502A4E44448040 +5A93:1020104011FC1104FDFC250425FC240027FE4820282011FC2820442083FE0000 +5A94:200027FE20402080FBFC4A944A944AF44A94929452F4229432944A944BFC8204 +5A95:1020105010881104FEFA240025FC2504250449FC288810882BFE448881080208 +5A96:2110211027FC2110F95048404BF84A488A484A4837FE104028A0491082080406 +5A97:2040202023FE2202FC0449FC480049FC490491FC510421FC310448004BFE8000 +5A98:1110111211D41118FD522592252E244025FC4904290411FC2904450485FC0104 +5A99:200C200A200823FEFA084BF84A4A4A4A8BEA4AAC32AC124C2AAA4B0A82160422 +5A9A:100011FC11241124FDFC2500257C25442544497C2944117C29444644827C0444 +5A9B:203C27C022442128F8004BFC488048804FFE910051F8228832504C2048D88306 +5A9C:10201020103E1020FC2025FC250425FC250449FC290411FC2800448885040202 +5A9D:0610381008527E5408901C282A2848440A820200FFFE08201C4003800C707008 +5A9E:100011FC11041104FDFC2504250425FC24004BFE28201120293C452082A0047E +5A9F:10481148114813FEFD4825482578250025FE48202BFE107028A8452486220020 +5AA0:1040104013FE1080FDFC262025FE240025FC490429FC110429FC450485140108 +5AA1:1020102013FE1020FDFC252425AC2574252449FC2820107028A8452482220020 +5AA2:100011FE1102117AFD02257A2502240024FC488428FC108428FC448484FC0084 +5AA3:212020A024782228F8A8492A4F2A494649A0902053FE207030A849244A228020 +5AA4:100011FC11241124FDFC2524252425FC24204810285411422942454A82380000 +5AA5:2040202021FE2102F90249FE4900490089FE49AA31AA12FE2AAA4AAA84A20086 +5AA6:200023FE222223FEFA224BFE480049FC490491FC510421FC3104490449148108 +5AA7:100010FC10841084FCF42494249425FE2502497A294A114A297A4502850A0104 +5AA8:21082088209027FEF89048904BFC4A944A94930C520423FC32044A044BFC8204 +5AA9:1080109E109213F2FC92249E249225D22552495E2952115229D24422842A0044 +5AAA:200021F821082108F9F84908490849F888004BFC329412942A944A9487FE0000 +5AAB:20402040207E2040FBFC480449FC48048BFC48403240127C2A40454084FE0800 +5AAC:2100217C21442244FA444E7C4A104A104AFE92385254225432944B124A108210 +5AAD:0BFE3020C1FC09043124C52409243050C08803040200FFFE08201C4003C03C38 +5AAE:204020A021102208FDF648004BC44A544A5493D45254225433D44A444A5482C8 +5AAF:20402240214027F8F888489048FC490489084BFE3202142A2AAA4A8284140008 +5AB0:2080208021FC2244F95449F4488449284A9091FC5244255431F4488449288210 +5AB1:2008203C23C02004FA44492849FC4A20482093FE502021243124492449FC8004 +5AB2:1020104011FC1154FD242554250425FC2400491229D41118291045528592010E +5AB3:2020204021FC2104F9FC490449FC490489FC4840302010A42A8A4A8A84780000 +5AB4:2020202021FC2020FBFE480049FC4904490491FC5052209431884EA448C28080 +5AB5:0020792448A8482049FC78404BFE488849447A424DFC488849D0483048489984 +5AB6:2108210827FE2108F8004FFE490849F8490891F85108213E37C8480848088008 +5AB7:200023FE220022FCFA004BFE4AA84A908AC84A86320813FE2A884C4884080818 +5AB8:20202124212421FCF8204BFE4800482049FC9124512421FC302048244BFE8102 +5AB9:204023BE22122292FA524AAA4B2448404BFE9222522223FE32224A224BFE8202 +5ABA:2108254825482550F7DE502450145FD450149794549424A824C8549458149022 +5ABB:10783E4822482A86FF7822482A2842104A2884C60200FFFE08201C4003C03C38 +5ABC:100010F810A810A8FCD8248824F82400240049FC295411542954455483FE0000 +5ABD:200021FE212021FCF92049FC4920492089FE480232AA12AA2AAA4A0280140008 +5ABE:1088108813FE1088FDFC248827FE242025FC492429FC11242BFE450485140108 +5ABF:2020204023FC2224FA244BFC4A244A448BFC484030A810B4293C49228222041E +5AC0:2040204027FC2040FBF848804FFC49108A684DC6304013F828E0495886440040 +5AC1:2040202023FE2202F80049FC484048A24B34905850942334305248904B508020 +5AC2:10A0112C11241124FDAC2524252425FC242049FC288810502820445080880306 +5AC3:1020102013FE1020FDFC250425FC250425FC490429FC11042BFE448881040202 +5AC4:100011FE11101120FD7C2544257C2544257C4910291011542952469282500420 +5AC5:21082088209023FCF84049F848404BFE4880910051FC2220342048204BFE8000 +5AC6:1040102013FE1202FC50248825242450248849042AFA10882888448884F80088 +5AC7:100013FE12021000FDFC250425FC250425FC4840282013FE2800448881040202 +5AC8:08202AA42CA84920145022887FFE400282040200FFFE08201C4003800C707008 +5AC9:2020201021FE2100F9204D204B3C495089904B1035FE111029284A2882440482 +5ACA:2020202023FE2020F9FC48204BFE4840488891F0502423FE302249244AA28040 +5ACB:200023DE20422042FBDE4A104A104BDE48429252514A214A325248424A948108 +5ACC:10881050100013FEFC5025FC245427FE245449FC285010D82954465284500050 +5ACD:101E11E010221112FC942480242025CE2502490229CE11022902450285FE0102 +5ACE:2040202023FC2108F8904BFE4A024C44482093FC508020F83088490849288210 +5ACF:2100209E23D22252FA544BD44A584A544BD292125292225A32D44B504A108010 +5AD0:200827C825482548F7FE5554555457D45214922457D4224822485254555488A0 +5AD1:7FFC03000D70710C01007FFC04403FF824483FF80400FFFE08201E4003C03C38 +5AD2:200E23F020442224F9084BFE4A4248404BFE908050FC214431284A104C688186 +5AD3:108010F811081210FDFC25242554258C25044810291211D4291845528592010E +5AD4:2040202023FE2202FC1449E04900490049FC9110511027FE3000489049088204 +5AD5:100011FE1140117CFD90251025FE2528254449FE2820101029444542824A0038 +5AD6:100013FE105011FCFD54255425FC240025FC48002BFE102028A8452482A20040 +5AD7:200023FE2200227CFA444A444A7C4A004AEE92AA52AA22AA32EE4A004BFE8000 +5AD8:100011FC112411FCFD2425FC2440248825F04820284413FE2822452482220060 +5AD9:2420222022202F7EF4805400577C551455109550555C255029505B5050BEA100 +5ADA:200021F8210821F8F90849F848004BFC4A9493FC500021F83090486049988606 +5ADB:7F7848485F4C64805F7844484A4851307F4C0400FFFE08201C4003800C707008 +5ADC:202021FC20882050FBFE480049FC490449FC910451FC202033FE482048208020 +5ADD:1020101011FE1110FD7C251425FE2514257C4910299211542938465482920430 +5ADE:202023FE222022FCFA244BFE4A244AFC8A204AFC32A412FC2AA44CFC84A408AC +5ADF:200023FE22482248FBFE4A484A204BFE4A4092FC53442244327C4A004BFE8000 +5AE0:08203E7E08A47F281C102A2849443FFE210021003FFE2210272040C043308C0C +5AE1:2040202023FE2088F8504BFE4A224AFA4A2292FA528A228A32FA4A024A0A8204 +5AE2:11F87D0811F81108FDF8110829F824904112860E0200FFFE08201C4003C03C38 +5AE3:200027FC20402278FA404FFE490049FC4A0093FC500425543554480448288010 +5AE4:1088108813FE1088FCF8242025FC252425FC48202BFE102029FC442083FE0000 +5AE5:102013FE102011FCFD2425FC252425FC24224BFE280813FE2908448884280010 +5AE6:2020212420A823FEFA0248F84888488848F8902051FC21243124493449288020 +5AE7:102013FE102011FCFC2027FE240025FC250449FC290411FC290445FC84880104 +5AE8:1088108813FE1088FCF8242025FC252425FC482029FC10202BFE445080880306 +5AE9:2108210827C82110F11E57E45554555457D49114539425482948511451148122 +5AEA:200027BC208424A4FA944CA4485049884E2690C0531020643388483048C08700 +5AEB:2110211027FC2110F8004BF84A084BF88A084BF8304017FC28A0491082080406 +5AEC:2040202023FE2200FA484A484BFE4A488A484A48327812002D54452A8A2A1000 +5AED:2040207C204023FEFA424A784BC44A3C8A084AF0332412A82DFE442088A00040 +5AEE:11FC102013FE1222FDAC242025AC240025FC48002BFE108028FC440484280010 +5AEF:08207F20087E7E4408A4FF2810101E28224446828200FFFE08201C4003C03C38 +5AF0:2108210827C82108F11E57D25564554057C89108538825482954511451248142 +5AF1:1020102013FE1020FD2424A827FE240025FC4904297411542974450485FC0104 +5AF2:2040202027FE2490F490549057FC549054D895B855B426D42892589050908090 +5AF3:082049202A3E7F4849485DA86B10492841460400FFFE08201C4003800C707008 +5AF4:102013FE102011FCFD0425FC242025FC248848502BFE102029FC442084200020 +5AF5:2080208021FE2354FD5449544BFE49544954915457FE20003154492A4A2A8000 +5AF6:2090208821FE2110FB104DFE4910491089FE4910311011FE29004AA482520452 +5AF7:2020272025FE2540F57C5690557E5500557C9544557C2644247C54445444844C +5AF8:1088105013FE1020FDFC242027FE252424A84BFE280011FC2904450485FC0104 +5AF9:1088108811FC1088FC8827FE242025FC252449FC292411FC2800448881040202 +5AFA:239C2294239C2294FB9C4A044AF44A944AF4929452F4229432944B344A04820C +5AFB:200023DE225223DEFA524BDE4A224A224AFA9222527222AA33264A224A2A8204 +5AFC:200021FC212421ACF974492449FC482089FC482033FE10002AA44A5284520000 +5AFD:2020202023FE2050FA8A49044BFE4D0449FC910451FC202031244A224CA28040 +5AFE:2020212420A823FEF8A849244A224904890449DE32441554289E490482040404 +5AFF:202021FC202423FEF82449FC48204BFE480091FC512421FC312449FC480083FE +5B00:2004203E27C02244F12853F8520853FC520493FE540226AA2AAA5A0250148008 +5B01:202027A420A82292F9144A084DF448028BF84A08320813F82A0841108FFE0000 +5B02:2110209423D22012FA5049904FFE48104BD29252525423D4324A4A4A4BD68022 +5B03:0BFE104061FC090411FC610405FC090431FCC0880504FFFE08201E4003C03C38 +5B04:202023FE202021FCF8004BFE4A0249FC480091FC510421FC310448884BFE8000 +5B05:108813FE10881000FDFC24A824A827FE24A848A829FC10202BFE442084200020 +5B06:204020A0211826E6F00053F8520853F8500097BC508424A4229454A452948108 +5B07:102011FC112411FCFC2027FE240025FC250449FC290411FC290445FC84880104 +5B08:2020202021FC2020FBFE49084B9C49084988963E500023FE309048904912820E +5B09:102013FE102011FCFC0025FC250425FC24884BFE280011FC2904450485FC0104 +5B0A:0440FFFE044017D0F01217DC3452D7D2100E0400FFFE08201C4003800C707008 +5B0B:200023DE22522252FBDE480049FC492449FC912451FC202033FE482048208020 +5B0C:101811E0104013FEFC88257426522470240049FC29041174295445748504010C +5B0D:2108254825482550F7DE501457E4501457D4911457D4210821085FD450248042 +5B0E:2200220823A824A8F93E57C85548555C554897C852BE228022825482547E8800 +5B0F:203C23E0212420A8FBFE48A849244A0249FC9124512421FC3124492449FC8104 +5B10:1020102010501088FD0426FA2400240025DC4954295411DC2888448885540222 +5B11:2040202021FC2088F8504BFE480049FC490491FC510421FC30204A944A8A847A +5B12:1020105010881174FE0225FC252425AC252449FC280010F8288844F8848800F8 +5B13:2108220827C82450F7DE546457D45214511497D4521423C822485454555488A2 +5B14:22002208238824A8F93E57C85548557E554897C852BE228022A25492547E8800 +5B15:100011FC115411FCFC2025FC242027FE2488485029FC10202BFE442084200020 +5B16:00407C2045FC44887C5043FE7C20A5FC24203C200200FFFE08201C4003C03C38 +5B17:202023FE200023FCFA044AF44A944BFC480091F8510821F8310849F8480083FE +5B18:20882448225020FCF82048504E944A388A504A98323412542A904A2085FE0800 +5B19:2020202023FE2124F9244AAA4FFE480049FC9104517421543174490449FC8104 +5B1A:202023FE22882250FBFE4A504AFC4A548BFE4A5432FC12502AD84D5486520850 +5B1B:200023FC22942294FBFC48004FFE48004BFC920453FC20A231144B084D448182 +5B1C:10207E20243EFF4200947E1042287E2842447E820200FFFE08201C4003C03C38 +5B1D:208023F8220823F8FA084BF84A004BFC8A004BFC304413FC28A0499486C80086 +5B1E:208823FE208821FCF8204BFE482049FC492491FC512421FC30204BFE482087FE +5B1F:2104208823FE2020F9FC48204BFE48544992909053FE209030D44B8A489681A2 +5B20:10F81088108810F8FC0025DC2554255425DC48202BFE107028A8452482220020 +5B21:203C23C020442224F10857FE544252A4528A947A508020F8210852905060879E +5B22:2080204027FE2110FA084D144BF849104BF8911057FC212833104D4849868100 +5B23:2040202023FE2222F954494A4A3A480049FC915453FE200031FC482048A08040 +5B24:2040202027FE2488F7DE548855DC56AA54889440548825F02420544859FC9084 +5B25:200023DE20422252F94A4A52489049084BFE951051FE211031FE491049FE8100 +5B26:204027FC204023FCF00057FE500253F8504097FE500027FE200857FE54A88798 +5B27:204023F8204827FEF8484BF848404FFE480092A4545223F832A84AA84FFE8000 +5B28:2108209023FE2108F9084A524B9C49088A524BDE304010A42AAA4A8A84780000 +5B29:2140224C22642244FB4C4A644AA44BAC8AA44AA437FE10002910490882040404 +5B2A:2040202023FE2202F9FC49484A5049FC4B0491FC510421FC310449FC48888104 +5B2B:208822AA22DC2488F9544A2248004BFE8A22482033FE107028A8492486220020 +5B2C:200021FC202023FEFA2249AC482049AC480093FE502021FC315449544954810C +5B2D:200027FC22482444FFFE544456EC555456EC944456EC255426EC544454548408 +5B2E:3FFE28882F8A20082FBE28882F88289429A220803FFE2208271040E0431C9C02 +5B2F:20402FFE204027FCF00053F852085FFE580297FC511023F8204057FC50408FFE +5B30:3EF822883EF822883EF822883EF8145022880400FFFE08201C4003800C707008 +5B31:420C2FB082204FA00ABE2FA84AA8CFA842285FA84248FFFE08201C4003C03C38 +5B32:0000F93EA92AA92AF93EAFAAAAAAFABE42904490FABE491249124A92ACAA1044 +5B33:108813FE10A81090FDFE272025FC252025FC492029FE11002BFC44888070038E +5B34:0100FFFE20003FF800003FF820083FF8010079384FA87AA84AB8792A4AAA9C46 +5B35:21082110223E2222F4BE5722513E520854BE97AA502A20AA256A552E54088008 +5B36:104010F8108810F8FC8824F8240025FC252449FC292411FC280047FE84880108 +5B37:2040202027FE2488F7DE548855DC56AA54889440549025202448548455FC8884 +5B38:202023FE2202241CFBE0492448A84BFE4924920255FC212431FC492449FC8104 +5B39:220024EC24A424A4F6EC54A454A456EC54A494A45FFE20002110510852048404 +5B3A:23FE224823FE2248FA204BFE4A404AFC8B444A7C320013FE28404AA4828A047A +5B3B:202023FE202021FCF8004BFE4A524BFE490491FC510421FC310449FC48888104 +5B3C:220225E224A226AAF52A566A510A528A544A9BAA510A27CA2122554251EA8E04 +5B3D:23FA22AA23FA2002F7FE540055FC555455FC940057FE204027FE50A051188606 +5B3E:2108210827CE2112F12457DE5552555E57D2911E5392255E2940511451128122 +5B3F:2110211027FC2110F1F0520852EA56AC52A892AA56EA2A06200052A452528452 +5B40:21FC202023FE2222F9AC482049AC4800489E93F2509E21D232BE4C92489E8092 +5B41:3FF801007FFE41029D7401001D7000003BB82AA83BB80400FFFE082007C07838 +5B42:221023DE25282084FBF84A084BF84A088BFA4A243298130628004BFC82940FFE +5B43:204027FC200023B8FAA84BB849104FFC491097FC511027FE31284B104D488186 +5B44:23DE225223DE2252FBDE4A224AFA4A224AFA92AA52FA22AA32FA4A724AAA8226 +5B45:2148214C22AA2008F7FE51485368514A536A914C536C2148216A539A50268042 +5B46:23DE225223DE2252FBDE4A524BDE498C4A52904057FE20883190486048D88304 +5B47:2108229423DE26B4FBDE4A944BDE4A944BDE921057FC21083090486049988606 +5B48:222223FE209021FEFB104DFE491049FE491091FE510023FE328A4B764A528276 +5B49:208823FE208823DEFA524BDE48A0489049FE912053FC252031FC492049FE8100 +5B4A:202023FE224823FEFA484AEC4B5A4A488A504BDE325013DC2A504DDE84500850 +5B4B:23DE200023DE2252FB5A4A5248204BFE4A5093FE525223FE32924ADC4A9284CE +5B4C:210447C88812F3BC20084B92F83E0380AAAAABAA0200FFFE08201C4003C03C38 +5B4D:27BC24A427BC2000F7FE54005590549E57D4956455D4255425D455685BC89054 +5B4E:23FE220223FE2292FA544A924AFE4AAA4AFE932252FA22AA32FA4A224DFA8004 +5B4F:208823FE208823DEFA524BDE4A524BDE4A2293FE52AA22FA32224A724AAA8224 +5B50:00007FF800100020004001800100FFFE01000100010001000100010005000200 +5B51:00007FF800100020004001840118016003801D00E10041000100010005000200 +5B52:00007FF80010002000400180010001FE01000100010001000100010005000200 +5B53:00007FF800100020204011800900050003000100018001400130010C05000200 +5B54:00407E4002400440084008400A400C403840C8400840084208420842283E1000 +5B55:00003FF008100820083C100417C4205440880100FFFE01000100010005000200 +5B56:00007EFC02040408081008200A200DFE3820C820082008200820082028A01040 +5B57:020001007FFE400280041FE0004000800100FFFE010001000100010005000200 +5B58:04000400FFFE0800080013F810103020504097FE104010401040104011401080 +5B59:00207E2002200420082008A80AA40CA43922C9220A2208200820082028A01040 +5B5A:00F87F0022101110112000001FE0004000800100FFFE01000100010005000200 +5B5B:010001003FF8010001007FFE400280040FE000400080FFFE0100010005000200 +5B5C:0040FC400440088010FE1108168818883088D050105010201050108851042202 +5B5D:020002083FD002200240FFFE010002003FE0104020805FFC8080008002800100 +5B5E:00001FE0004000800100FFFE0100010005000200091049084824482487E00000 +5B5F:00001FE000400180FFFE01000100050002003FF82448244824482448FFFE0000 +5B60:00003FF800087FC800083F8820883FA800103FE000800100FFFE010005000200 +5B61:00207E2002200440084808840BFE0C823800C8FC088408840884088428FC1084 +5B62:0080FC8005FC0904120415F4151419143114D1F4110411281112110250FE2000 +5B63:00701F80010001007FFC054009203118CFE600400080FFFE0100010005000200 +5B64:0008F83C0BD01290229022902A9032902290E288228822C822A424D4A4924800 +5B65:10001000FEFC2244642818102428C2C600003FE000800100FFFE010005000200 +5B66:22081108111000207FFE400280041FE000400180FFFE01000100010005000200 +5B67:0820102022FC7C24082412447F54008801003FE000800100FFFE010005000200 +5B68:00001FE000800100FFFE0100010005007A7C080810101EFEF010101050502020 +5B69:0020FC1004100BFE10201042148419F83010D02210C413081010102850C42302 +5B6A:02000100FFFE0440145014482444444400003FE000800100FFFE010005000200 +5B6B:000CFDF004200844108811F01420184431FED022102010A81124122250A02040 +5B6C:7FFC008003600D1871040100100010FCFE042208221064FE141008103450C220 +5B6D:0000FDFC0504090411FC1104150419FC3104D10411FC10001088108451022202 +5B6E:0040FC2007FE0A02100011FC1400180033FED020112811241222142250A02040 +5B6F:00007EFC48447E4442287E1048287EC600003FE000800100FFFE010005000200 +5B70:10400840FF4000407EF842487E4801487EC8044808680E5AF88A088A29061202 +5B71:3FFC20043FFC200023F020203FFE204020C02FBE210423885E7E42088A280410 +5B72:0000FDFE04480848104811CE150219023102D1CE104810481048104853FE2000 +5B73:082004407FFC12483CF0082014503EF800003FE000800100FFFE010005000200 +5B74:1FE00040FFFE010003007C7C08081EFEF010105030201FF010101FF010101FF0 +5B75:200ECEF08A22AA92AA54EE00AA7CAA08AA10AA10EEFEA8102810481048508820 +5B76:0820FFFE082012483CF0082014503EF800003FE000800100FFFE010005000200 +5B77:08203E7E08A47F281C102A2849443FFE200023F0202020402FFE404041408080 +5B78:0A803138228838382288393822887FFE4002BFE400800100FFFE010005000200 +5B79:3E1022FE3E4420287EFEA2103EFC221000003FE000800100FFFE010005000200 +5B7A:0000FDFC04200BFE122211AC142019AC3000D3FE102011FC115411545154210C +5B7B:0020FDFC04240BFE102411FC14201BFE3000D2A4145211FC1154115457FE2000 +5B7C:52107EFE28447E28A2FE3E1020103E7C22103E1000001FE00040FFFE01000300 +5B7D:0820FFFE28207DFC44887C5041FE7C2045FC7C2000001FE00040FFFE01000300 +5B7E:03DEFA520BDE125223DE22522BDE318C2252E04027FE208821902060A0D84304 +5B7F:210447C88812F3BC20084B92F83E0380AAAAABAA00001FE00040FFFE01000300 +5B80:0200010001007FFE400280040000000000000000000000000000000000000000 +5B81:0200010001007FFE4002800400003FF801000100010001000100010005000200 +5B82:0200010001007FFE4002800400000FE0082008200820102010222022401E8000 +5B83:020001007FFE4002800408000808083009C00E00080008040804080407FC0000 +5B84:0200010001007FFE4002820402001FE0022002200420042008221022201E4000 +5B85:020001007FFE40028004002003F03E00020003FCFE0002040204020401FC0000 +5B86:020001007FFE400280043FF8000800083FF8200020003FFC0004000400280010 +5B87:020001007FFE400280043FF8010001000100FFFE010001000100010005000200 +5B88:020001007FFE4002804400400040FFFE00400040104008400840004001400080 +5B89:020001003FFC2004420802000200FFFE0420082018400640018002600C107008 +5B8A:0200010001007FFE40028104012001107FFC010002800280044008203018C006 +5B8B:020001007FFE40028104010001007FFC03800540092011102108C10601000100 +5B8C:020001007FFE400280041FF0000000007FFC044004400440084408441044603C +5B8D:020001007FFE40028204010000800000FFFE0000044004200810100820044004 +5B8E:020001007FFE4002800400F03F0001000100FFFE01000280044008203018C006 +5B8F:020001007FFE4002820402007FFC04000480088009001100222044108FF80408 +5B90:020001007FFE40028404040007F00810081014202220014000400080FFFE0000 +5B91:020001007FFE4002882408203FF8082008200820FFFE08201020102020204020 +5B92:020001007FFE4002800400F83F00010001F83F00010001FC7F020102010200FE +5B93:0200010001007FFE400281040090089048244842488289020E101810E7F00000 +5B94:020001007FFE4002820401007FFC0100010001003FF8010001000100FFFE0000 +5B95:020001007FFE4002800400007FFC0400040008001FF82808C80808080FF80808 +5B96:020001007FFE400280047E10021002103E10202040287E24024402FE14420800 +5B97:0200010001007FFE400280041FF0000000007FFC010011101108210445040200 +5B98:020001007FFE400280041FF0101010101FF0100010001FF8100810081FF81008 +5B99:020001007FFE4002810401003FF82108210821083FF82108210821083FF82008 +5B9A:020001007FFE4002800400003FF801000100110011F811001100290047FE8000 +5B9B:020001007FFE400290041EF812882288228852A88C90048208821082207E4000 +5B9C:020001007FFE400280041FF0101010101FF0101010101FF010101010FFFE0000 +5B9D:020001007FFE4002800400007FFC0100010001003FF8010001200110FFFE0000 +5B9E:020001007FFE4002888404800480108008800880FFFE01400220041018086004 +5B9F:020001007FFE4002810401003FF801001FF001007FFC0280044008203018C006 +5BA0:020001007FFE4002842404100410FFFE04800888089010A010C220824182867E +5BA1:020001007FFE410281043FF8210821083FF8210821083FF82108010001000100 +5BA2:020001007FFE400288040FF010202C4003801C70E00E1FF0101010101FF01010 +5BA3:020001007FFE400280043FF800001FF010101FF010101FF010100000FFFE0000 +5BA4:020001007FFE400280043FF8040008201FF0011001003FF801000100FFFE0000 +5BA5:020001007FFE420282047FF804000FF018102FF048108FF00810081008500820 +5BA6:020001007FFE400280043FF8210021003FF02010201020103FF0210021003FFC +5BA7:020001007FFE400280043FFC2080208027F82408240827F8208020803FFE0000 +5BA8:020001007FFE4002800404404448245024600C403460C852084A1042203E4000 +5BA9:020001007FFE410291140920054001007FFC0540092011102108C10601000100 +5BAA:020001007FFE4002810411001FF821000100FFFE04400440044008423042C03E +5BAB:020001007FFE400280041FF0101010101FF000003FF82008200820083FF82008 +5BAC:020001007FFE4002809400883FFC208020883E88225022502A244454418C8604 +5BAD:020001007FFE400280043FF80408FFFE04083FF808001FF8280848088FF80808 +5BAE:020001007FFE400280041FF0101010101FF0020004003FF8200820083FF82008 +5BAF:020001007FFE4002810C1FD00120FFFE01001FF0082030C0CFFC008002800100 +5BB0:020001007FFE420281043FF8000008200440FFFE010001007FFC010001000100 +5BB1:020001007FFE40028884088010FE11403240547C90401040107E104010401040 +5BB2:020001007FFE400280041FF0101010101FF00100FFFE054009203118C1060100 +5BB3:020001007FFE400281043FF801001FF00100FFFE01001FF0101010101FF01010 +5BB4:020001007FFE40029FF410101FF010101FF00400FFFE08201C4003800C703008 +5BB5:020001007FFE40029114092001001FF010101FF010101FF01010101010501020 +5BB6:020001007FFE400280047FFC02000D08719002A00CC071A006981886E2800100 +5BB7:020001007FFE400280F43F00111009200100FFFE0380054009203118C1060100 +5BB8:020001007FFE400280043FF820002FF020003FFC248824504420451886060400 +5BB9:020001007FFE4002882411102288044008203018DFF61010101010101FF01010 +5BBA:020001007FFE40029FF4101010101FF00000FFFE09200920112011222122411E +5BBB:020001007FFE4002BFF410104824244803801C70E00E0100210821083FF80008 +5BBC:020001007FFE400280243E2001FE00447E4414C814281410146A2586240243FE +5BBD:020001007FFE400284443FF8044000001FF0101011101110129004821882E07E +5BBE:020001007FFE400280741F80100010001FF810801080FFFE0000084010202010 +5BBF:020001007FFE400288040FFC1040308053F89208120813F81208120813F81208 +5BC0:020001007FFE4002801400F83F001110082001007FFC054009203118C1060100 +5BC1:01007FFE400281047FFC01003FF80108FFFE01083FF8110011F8290047FE8000 +5BC2:020001007FFE400288040F7C08440844FF44002808282A104910892828441082 +5BC3:020001007FFE48028FE4102020405FF8110811081FF8028004A008921082607E +5BC4:020001007FFE420282043FF804800840FFFE00101F90109010901F9000500020 +5BC5:020001007FFE40029FF401001FF0111011101FF0111011101FF0044008201010 +5BC6:020001007FFE40028224094028884B141C10E7F001002108210821083FF80008 +5BC7:020001007FFE400280243E38002000207EF814081450142014542484240443FC +5BC8:01007FFE4102BFFC01001FF00100FFFE00001FF010101FF010101FF010101030 +5BC9:020001007FFE490288841FFC108030805FF8908010801FF8108010801FFC1000 +5BCA:020001007FFE420283F402003FF820083FF820083FF820083FF8082010102008 +5BCB:020001007FFE4822BFFC08203FF80820FFFE10102FE8C82608A00848080807F8 +5BCC:020001007FFE4002BFFC00001FF010101FF000003FF821083FF821083FF82008 +5BCD:020001007FFE4002820409084924482487E000003FF8244824482448FFFE0000 +5BCE:020001007FFE4002840425FC24203C2005FC05247D2425542594250445148508 +5BCF:020001007FFE48028FE410403FF852481428110801007FFC028004401830E00E +5BD0:020001007FFE40028424242025FC3C20042007FE7C6024B02528262644208420 +5BD1:020001007FFE40028BFC080811F8300853F8900017FC140413F8111010E0171C +5BD2:020001007FFE44429FF404403FF80440FFFE082013102088C046060001800040 +5BD3:020001007FFE40029FF411101FF011101FF001003FF8210821482FE824282010 +5BD4:020001007FFE40029FF410101FF010101FF000007FFC110011F8290047FE8000 +5BD5:020001007FFE4002BFFC02003FF8244824483FF80000FFFE0100010005000200 +5BD6:020001007FFE4002A3FC100811F8800843F8500017FC2404E3F8211020E0271C +5BD7:01007FFE420281440880292847E4180061003FF821083FF82108FFFE20082018 +5BD8:01007FFE4102BFFC01001FF010101FF010101FF010101FF01010FFFE08201010 +5BD9:020001007FFE40028004061C38E828A82CA82AA82AA82AA828A455545D748212 +5BDA:020001007FFE4002BFFC01001FF001007FFC10001FF02100FFFE010021083FF8 +5BDB:020001007FFE4822BFFC08201FF010101FF010101FF010101FF004421842E03E +5BDC:020001007FFE41029494142823E800003FF824482448FFFE0100010005000200 +5BDD:01007FFE4002800413F8100891F8500853F8100037FC540493F8111010E0171C +5BDE:01007FFE400284443FF804401FF010101FF010101FF002007FFC04401830E00E +5BDF:01007FFE400290841EF822885450282017D82006DFF001001110210845040200 +5BE0:020001007FFE4102BFFC2108FFFE21083FF811101FF00400FFFE082007C07838 +5BE1:01007FFE4002BFF404001FF010101FF010101FF01010FFFE082037D8C2460CC0 +5BE2:01007FFE4002840424FC2404247C3C0404FC04007DFE250224FC2448443085CE +5BE3:020001007FFE4042842425FC24003CF8040004F87C0024F82488248844F88488 +5BE4:020001007FFE400285FC242024F83C48044805FE7C0024FC2484248444FC8484 +5BE5:01007FFE4002BCFC24481428254806C01830E30E0C403180063038C007003800 +5BE6:01007FFE40029FF41110FFFE22103FF010101FF010101FF010101FF008201010 +5BE7:01007FFE4102949414A823E800003FF82448FFFE00003FF80100010005000200 +5BE8:01007FFE44429FF404403FF80440FFFE082011102FE8C1060920111025080200 +5BE9:01007FFE400280FC3F0011100920FFFE09203018DFF611101FF011101FF01010 +5BEA:01007FFE400280FC7F00221011201FE010201FF010101FFC20042AA44AA4800C +5BEB:01007FFE400282041CF010101EF010101FF008001FFC20044924249424944008 +5BEC:020001007FFE4822BFFC08201FF010101FF010101FF010101FF00452184AE03E +5BED:01007FFE4102BFFC01001FF011101FF011101FF001087FFC02044908482487E4 +5BEE:01007FFE400281047FFC044028281FF02828CFE608200FE00100111025080200 +5BEF:01007FFE490288841FFC30805FF890801FF810801FFC10003E7C224423D42008 +5BF0:01007FFE4002BFFC24483FF80000FFFE00001FF010101FF005081890EA600C1C +5BF1:020001007FFE404289FC490449FC490479FC090409FCF8204BFE48A849248A22 +5BF2:020001007FFE4002A47C3A0422281E1020FE3E124850085E7F5014B0229E4100 +5BF3:01007FFE4082BEFC09243EA809247EA000401FF010101FF010101FF008201010 +5BF4:020001007FFE400288047F7C2244147CFF44087C7F44087C2A28492AA94A1086 +5BF5:0100FFFE88427F7C2240147CFF04007C7F40417C7F40417C7F40417C4542423E +5BF6:01007FFE4082BEFC09203EFC08207EA400FC1FF010101FF010101FF008201010 +5BF7:01007FFE48229D7449245D7449245D7449247FFC00007FFC10101FF00820FFFE +5BF8:0040004000400040FFFE00400040004010400840084000400040004001400080 +5BF9:0010001000107E1002FE02102410149008500850141012102210401000500020 +5BFA:0100010001003FF801000100FFFE002000207FFC082004200420002000A00040 +5BFB:00003FF8000800081FF8000800083FF800200020FFFE08200420042000A00040 +5BFC:00003FF0201020103FF0200420041FFC00200020FFFE08200420042000A00040 +5BFD:000801FC7E0002082108111010400040FFFE0040104008400840004001400080 +5BFE:2010101010100010FEFE04100410489028501050101028102410441080500020 +5BFF:020002007FFC02003FF80400FFFE082008201FFC102024204220822000A00040 +5C00:000800087F884008407E5F0851085148512851285F08510840087F8800280010 +5C01:0808080808087F08087E0808FF080048082808287F08080808080F08F0284010 +5C02:01000100FFFE01003FF821083FF821083FF80020FFFE08200420042000A00040 +5C03:012001107FFC01003FF821083FF821083FF821080020FFFE0820042004A00040 +5C04:080810083E0822083EFE22083E0822082248FE2806280A08120822084A280410 +5C05:08080808FF08080808FE7F08414841287F281408140814282412240243FE8000 +5C06:088008F809084A1028A0284008900B1018102BFEC81009100890081008500820 +5C07:0440247C24C4252824903CA004480588FC0825FE240824882448440884280410 +5C08:01007FFC01003FF821083FF821083FF80104FFFE0022FFFE0820042004A00040 +5C09:00043F84208420843FBE20042F84202420143FD422042A844A4452448A140408 +5C0A:08200440FFFE04403FF82848303827C820083FF80020FFFE0820042004A00040 +5C0B:00003FF000101FF000103FF000003E7C08447F7C0020FFFE0820042004A00040 +5C0C:08080808FF880808087E7F0800087F48412841287F08000822081788F8284010 +5C0D:1408140855083608147EFF080008224814287F2808083E0808080F0878282010 +5C0E:211017FE108003F8F20813F8120813F8120813F8280047FE0020FFFE08200460 +5C0F:0100010001000100010011101108110421042102410281020100010005000200 +5C10:01000100010009200910110811042104410001000000180024000380007E0000 +5C11:010001000100092009101108110421144110012000400080010002000C007000 +5C12:010001000280044008203118C106010009200910110821044104010005000200 +5C13:0800080008001FFC100021004100810001001110110821044102810205000200 +5C14:0800080008001FFC100421084100810001001110110821044102810205000200 +5C15:00003FF008100820083C10041004211441080920091011082104410405000200 +5C16:01000100092009101108210800000104FFFE01000280028004400830300EC004 +5C17:0200020003F8020002000200FFFE010001000920111021084104010005000200 +5C18:01000100092009101108210441040000010001003FF8010001000100FFFE0000 +5C19:010011101108210441043FF82008200827C824482448244827C8200820282010 +5C1A:010021081110092001003FF82008200827C824482448244827C8200820282010 +5C1B:0100010009200910110821044104101010101010545452529292101050502020 +5C1C:010009201110210800000100FFFE02800C603018C10609200910110825080200 +5C1D:01001110092001007FFE400280041FF0000000007FFC0400082010103FF81008 +5C1E:010001007FFC2288145008203FF8D0161FF010101FF001001110210845040200 +5C1F:00103E1022103E5422523E520090FF12080408082F102860298058004FFE8000 +5C20:22102210FF1022103E5422523E5222902210FF1440045408620840107E2000C0 +5C21:100011FC9104550459FC1104FD0429FC2800291229D429182B104D524992810E +5C22:0400040004000400FFFE048004800480048008800880108210822082407E8000 +5C23:04400420081010082004444284420440044004400440084208421042203E4000 +5C24:0420041004100400FFFE048004800480048008800880108210822082407E8000 +5C25:20802080208021F8FD082A082888284828482808280828502822480247FE8000 +5C26:004024402240427C808425042444242424242404240424282412440243FE8000 +5C27:0200020002FC7F20014000840764381C0000FFFE04400440044008423042C03E +5C28:0420041004100400FFFE049004A004C8049008A408C8109210E221824E7E8000 +5C29:000024FC22204220802024F8242024202420242025FC24002402440243FE8000 +5C2A:200023F820402040FC40284029F028402840284028402BF82802480247FE8000 +5C2B:000001FCFE202420242025FC242024202420242027FE24002400440243FE8000 +5C2C:2020202020502088FD042A022888288828882888290829082A0A480247FE8000 +5C2D:010001007FFC010009200820FFFE082008207FFC04400440084010422042C03E +5C2E:200023F820882090FCBC290429142A4828402BFC28E029502A4A484247FE8000 +5C2F:2080208021F82208FDFE2900297829482968295029442A442C3E480247FE8000 +5C30:203C21E0202023FEFC2029FC292429FC292429FC282029FC28204BFE480287FE +5C31:20401050FE48004800407DFE4450445044507C501090549092921112510E2200 +5C32:2088205023FE2050FDFC28542BFE285429FC285028D829542A52485247FE8000 +5C33:20F8208820E820A8FDFC290428F8288828F8288828F82888288848AA489287FE +5C34:2090229022BC22D0FE882A8828002BF82AA82AA82AA82FFE2802480247FE8000 +5C35:202021FC212421FCFC202BFE290429FC290429FC290429FC28884906480287FE +5C36:03E8FE882BCE2A502BE42A822BE0280029FC2954295429542BFE480247FE8000 +5C37:23E8228823CE2250FFE42A822BE0280029FC2954295429542BFE480247FE8000 +5C38:00001FF810081008100810081FF8100810001000100010002000200040008000 +5C39:000000003FF004100410FFFE041004103FF00410040008000800100020004000 +5C3A:00001FF810081008100810081FF8108010801080104010402020201040088006 +5C3B:00003FF8200820083FF8210021002FE0212021202220222044224422881E1000 +5C3C:00001FFC1004100410041FFC10001200120C123013C012022202220241FE8000 +5C3D:00001FF81008100810081FF81048104010202310208840068C00030000800040 +5C3E:00003FFC200420043FFC200020F02F00210021F02F00210021F85F02410280FE +5C3F:00003FF8200820083FF82080208020882ED022E022A024A04490488892840100 +5C40:00003FF8200820083FF8200020003FFC200427E42424242447E4400480280010 +5C41:00003FF8200820083FF820002840284028442F4828502860484449448A440C3C +5C42:00003FFC200420043FFC200020002FFC200020003FFE2100221044084FFC8404 +5C43:00003FFC200420043FFC2000200027FC240424442444244424B4410846049802 +5C44:00003FFC200420043FFC208020402FFE28023124212022102210440848049002 +5C45:00003FF8200820083FF8208020803FFE208020802FF82808480848088FF80808 +5C46:00003FFC200420043FFC2000208028842BE4288428842FF4280448044FFC8004 +5C47:00003FFC200420043FFC200027FC24442444244427FC24442444444447FC8404 +5C48:00003FF8200820083FF820802888288828882FF820803084508450849FFC0004 +5C49:00003FF8200820083FF820902490249024903FFC2490249044F04400840007FE +5C4A:00003FF8200820083FF82080208020802FF8288828882FF8488848888FF80808 +5C4B:00003FFC200420043FFC20002FFC2100221027F8208820802FFC40804080BFFE +5C4C:00003FFC200420043FFC200027FC2404240427FC20402FFE2842484A48448040 +5C4D:00003FFC200420043FFC200020003FFE2420242427A828B0352042224422981E +5C4E:00003FFC200420043FFC2080249022A020803FFC21C022A02490488850868080 +5C4F:00003FF8200820083FF8241022202FF8222022203FFC22204220442084200820 +5C50:00003FFC20043FFC2020242029FE3020222025FC2C8434884450442084D80706 +5C51:00003FF8200820083FF82080249022A02FF828082FF828084FF8480888280810 +5C52:00003FFC20043FFC20002FF828002BF828002FFC2A482A5052205298A3060200 +5C53:00003FFC200420043FFC200027FC240427FC240427FC240427FC411042088404 +5C54:000002FE3C822082208220FE3E8024A024A224A424B82EA0F1224122021E0400 +5C55:3FFC200420043FFC222022203FFC222022203FFC244024442428451046088406 +5C56:00003FFC20043FFC210020802FF8241022203FFC208020804FF8408080800080 +5C57:00083F082108217E3F08204823283C2827083C0827A83C122402440243FE8000 +5C58:00003F7E210221043F082008237E3C0827083C0827883C2A2412440243FE8000 +5C59:00003FFC20043FFC20002EFC2A082AE82CA82AA82AA82AE84AA84E0888280810 +5C5A:00003FFC20043FFC20003FFE20802FFC28842CA42A9428844CA44A948884080C +5C5B:00003FFC200420043FFC210822102F7C221022103F7E22102210441044108810 +5C5C:00003FFC200420043FFC222824A82AA823FE24A82CA834A824B8448044FE8400 +5C5D:00003FFC200420043FFC212021202F3C212021202738212021204F3C41208120 +5C5E:00003FFC20043FFC20002FF820802FF828882FF820803FFC509457F490141008 +5C5F:3FFC20043FFC200024883FFE248824F8240027FC20402FFE415042488C460040 +5C60:00003FFC20043FFC2080208827F020A03FFE208023F826085BF8420883F80208 +5C61:3FFC20043FFC249022A03FFC22A02490288821003FFC2210472040C083300C08 +5C62:3FFC20043FFC20802FF828883FFE28882FF8249027F021005FFE441083E01C1C +5C63:3FFC20043FFC22102410289C3090229025FE2C103490249C44904550863E0400 +5C64:3FFC20043FFC221021202FFC2A9429A42FFC200027F8240847F8440887F80408 +5C65:3FFC20043FFC210029FE320021FC250429FC390429FC288049FC4A8888700B8E +5C66:00003FFC20043FFC2000252428A831FC24A8292438402BFE4888499088700B8C +5C67:3FFC20043FFC244825482BFE354825782D0035FE242027FE44A8452486220420 +5C68:3FFC20043FFC242029FC312423FE25242DFC34A824F8244045FE44888470058C +5C69:3FFC20043FFC220025FC284033FE24882D74365225FC2504457445548574050C +5C6A:3FFC20043FFC20402FFE288227FC21102BFA260C2BFA220843F84040844808C4 +5C6B:3FFC20043FFC200022FE2A202BFE2E4422BA23283EFE2A824ABA4AAA92BA2286 +5C6C:3FFC20043FFC249022A024902FF829482FFC24842FF4349447F440948FF40008 +5C6D:3FFC20043FFC220823F8220823F8211022082FBE28A22FBE48A24FBE851408A2 +5C6E:01000100210821082108210821083FF801080100010001000100010001000100 +5C6F:010001000100FFFE010021082108210821083FF8010001020102010200FE0000 +5C70:101008100820FFFE010001002108210821083FF802080400040008003000C000 +5C71:01000100010001002108210821082108210821082108210821083FF800080000 +5C72:0008007C078078000100010001002108210821082108210821083FF800080000 +5C73:060001000280044008203118C10601002108210821082108210821083FF80008 +5C74:010001002108210821083FF8020002007FF80208040804080808100820504020 +5C75:01002108210821083FF8000000003FFC20002000200020002000400040008000 +5C76:010001002108210821083FF8000000007FF8040804080808080810082050C020 +5C77:1000100013F810885490549054A054BC5484548455045D046504020402280410 +5C78:1000100011FC102054205420542054205420542054205C206420002003FE0000 +5C79:10401040108010FE5500560054FC54085410542054405C806502010200FE0000 +5C7A:1000100011F8100854085408540855F85508550055005D006502010200FE0000 +5C7B:1000100011FC104454445544554455445544564454445C846484010402280410 +5C7C:1000100013FC109054905490549054905490549054905C9265120112020E0400 +5C7D:100011FC1020102054205420542057FE5420542054205C206420002000200020 +5C7E:102010201020102055245524552455245524552455245D24652401FC00040000 +5C7F:104010401040107E54405480548054FC5404540454045DF46404000400280010 +5C80:0100010021082108210821083FF80000010041044104410441047FFC00040000 +5C81:01002108210821083FF80200020007F00810141022200140008003001C00E000 +5C82:01002108210821083FF8000000003FF00010001000103FF02000200420041FFC +5C83:01002108210821083FF8000000003FF802081208120822080408080810506020 +5C84:100010FC10841084548454FC54845484548454FC54845C846504010402140408 +5C85:1008101C11E01100550055FC554455445544552855285D106510022802440482 +5C86:1008103C11E010205420542057FE54205420545054505C506488008801040202 +5C87:01002108210821083FF800000C0070FC4084408440844C847094408800800080 +5C88:100011FE1008108854885488550855FE5418542854485C886508020800280010 +5C89:10801080108010FC55545654545454945494552456245C446444008401280010 +5C8A:00003FF8210821083FF82000200220021FFE010001002108210821083FF80008 +5C8B:100013FC1084108854885490549C54845544554455285D286610022804440182 +5C8C:0100210821083FF800003FF0082008400CF80A08111010A0204020A043188C06 +5C8D:100011FC1088108854885488548857FE5488548854885C886488010801080208 +5C8E:101010901090108855085504560455FA5488548854885C886508010802280410 +5C8F:100011FC10001000540057FE549054905490549054905C9265120112020E0400 +5C90:10201020102013FE54205420542055FC5484548854485C506420005001880606 +5C91:0100210821083FF80100028004400A203118C1061FE000200040004000800100 +5C92:10201020105010505488554456225420540055FC54045C086408001000100020 +5C93:1008101C10E010805480548054FE54885488548854885C886508010802080408 +5C94:0440082010102FE8C4260420082010A06040010001002108210821083FF80008 +5C95:01002108210821083FF801000280044008203458C44604400440084008401040 +5C96:100011FE1100110455445528552855105510552855285D446584010001FE0000 +5C97:0100210821083FF800003FF82008204824482288210822882448280820282010 +5C98:100011FC1104110455245524552455245524555454505C90649001120212040E +5C99:001000F83F00010002007FFC044008203018C10601002108210821083FF80008 +5C9A:0100210821083FF800001FF0101010501450129011101292244A284A40068002 +5C9B:010002001FF0101012101150102010001FFC0204222422243FE4000400280010 +5C9C:0100210821083FF800003FF82108210821083FF820002002200220021FFE0000 +5C9D:0100210821083FF8080008001FFC2400440087F00400040007F8040004000400 +5C9E:10801080108010FE554055405640547C5440544054405C7E6440004000400040 +5C9F:10201020102011FC5524552455245524552457FE54205C506450008801040202 +5CA0:100010FE10801080548054FC548454845484548454FC5C806480008000FE0000 +5CA1:00007FFC40044824442444445FF4410441044924492449244FE4400440144008 +5CA2:0100210821083FF800000000FFFE001000101F90109010901F90001000500020 +5CA3:10801080110011FC5604540455E455245524552455E45D246404000400280010 +5CA4:20402020202023FEAA02AC04A800A890A890A890A888B908C908010402040402 +5CA5:10101010101011FE55125514551055FC5544554455285D286510022802440482 +5CA6:01002108210821083FF80200010001007FFC00001010082004400000FFFE0000 +5CA7:0100210821083FF800007FF80408080810502020DFF81008100810081FF81008 +5CA8:100010F810881088548854F854885488548854F854885C886488008803FE0000 +5CA9:01002108210821083FF8000000007FFC040004000FF818082808C8080FF80808 +5CAA:0100210821083FF804403FF8044804481FF8144024403FFC0844105420484040 +5CAB:102010201020102055FC552455245524552455FC55245D246524012401FC0104 +5CAC:100011FC11241124552455FC55245524552455FC55245C206420002000200020 +5CAD:1020102010501050548855245612541055FC540454085C886450002000100010 +5CAE:10201010101011FE5502560454805488549054A054C05C8264820082007E0000 +5CAF:100011FE1010101054205420546854A45522562254205C206420000003FE0000 +5CB0:2010209020902110A97EAA52AB92A892A912A912AA52BBD2C8620022004A0084 +5CB1:089008881080309E57E0908010441034110C010021082108210821083FF80008 +5CB2:100011FC110411045504550455FC54505450545054505C9264920112020E0400 +5CB3:00701F80100010001FF8108010801080FFFE010001002108210821083FF80008 +5CB4:1008101C10E0108054805480548054FE5488548854885C886488008801FE0000 +5CB5:102010201020102055FE54205420542055FC550455045D046504010401FC0104 +5CB6:10201020104011FC550455045504550455FC550455045D046504010401FC0104 +5CB7:100011FC11041104550455FC5520552055FE552055205D106512014A01860102 +5CB8:0100210821083FF800003FFC20002FF8208020803FFE20804080408080800080 +5CB9:100013FC108410845484550455145608540055FC55045D046504010401FC0104 +5CBA:0100210821083FF8010002800C603218C1061FE0002000400C80030000800040 +5CBB:1004101E11F0111055105510551055FE5510551055105D08650A014A01A60112 +5CBC:100011FC10201020552454A454A8542057FE542054205C206420002000200020 +5CBD:0100210821083FF8020002007FFC0400090011003FF801001110210845040200 +5CBE:1020102010201020543E54205420542055FC550455045D046504010401FC0104 +5CBF:0100210821083FF8000008004BF848084808480849F848084808100813F82008 +5CC0:01002108210821083FF80000010001003FF8210821083FF8210821083FF82008 +5CC1:0100210821083FF800000C0070FC4084448444845C8464944888088010806080 +5CC2:10401040107C108455885650542054505488570654605C10640800C000200010 +5CC3:020821081110102000007FFE400281040100210821082108210821083FF80008 +5CC4:100013FC110410885450542054D85726542055FC54205C2067FE002000200020 +5CC5:1020102010401088550457FE54025488548857FE54885C886508010802080408 +5CC6:10201020105010885504560255FC5400540055FC55045D046504010401FC0104 +5CC7:0100210821083FF8010002800C603018CFE600001FF01010101010101FF01010 +5CC8:2080208020F82108AB10ACA0A840A8A0A918AA06ADF8B908C908010801F80108 +5CC9:0100210821083FF808000FF010202C4003801C70E00E1FF0101010101FF01010 +5CCA:040008003FF0201020103FF020003FF8200820083FF80100210821083FF80008 +5CCB:1080108011FC1104560455E45524552455E4552455245DE46504000400280010 +5CCC:100011FE102010405488550455FE54225420542055FE5C206420002003FE0000 +5CCD:2020202021FC2024ABFEA824A9FCA820A820A9FCA820B820CBFE002000200020 +5CCE:0100210821083FF800003FF020103FF020103FF02208211020A024402830300E +5CCF:100013FE10201020544055FC555455545554555455545D546554014401140108 +5CD0:10201010101013FE54205442548455F85410542254C45F086410002800C40302 +5CD1:0100210821083FF801000280044008203018CFE6010001001FF0010001007FFC +5CD2:100011FE11021102557A55025502557A554A554A554A5D7A65020102010A0104 +5CD3:1020102013FE102055FC542455FC552055FE5422542A5C546450008801040202 +5CD4:10401040104411F45448545057FE54405480558456985CE064820082007E0000 +5CD5:0100210821083FF802000100FFFE00001FF0101010101FF0101010101FF01010 +5CD6:20402020202023FEAA02AC44A840ABFEA888A888A908B8D0C820005000880304 +5CD7:1040104010FC1104560855FE5500557C5544554455545D4865420242023E0400 +5CD8:100013FE1000100055FC5504550455FC5504550455FC5D046400000003FE0000 +5CD9:10201020102011FC5420542057FE5408540855FE54085C886448000800280010 +5CDA:0100210821083FF8000002007FFC04401830E10E01001FF0010001007FFC0000 +5CDB:0100210821083FF800047F84082408241F24212451240A24040408043014C008 +5CDC:0100210821083FF801000280044008203118C10609F00900090009007FFC0000 +5CDD:0100210821083FF800003FF820082FE8200827C82448244827C8200820282010 +5CDE:0100210821083FF808001FE020205FFC900017F0141014542424240443FC8000 +5CDF:0100210821083FF8040004007FFC08001FF028104FF088100FF0081008500820 +5CE0:10201020103E1020542055FE5400540055FE542054285C246422002000200020 +5CE1:10201020102011FC5420552454A454A8542057FE54505C506488008801040202 +5CE2:2002200227E2210AA90AA9EAA92AAA2AAB2AAAAAAC4AB84AC8820102020A0404 +5CE3:1080108010BC13C05450542454D4570C540057FE54905C9065120112020E0400 +5CE4:1008103C11E01020542057FE545054885504568A54885C886488010801080208 +5CE5:1080108010F81108561055FC5424542455FE542454245DFC6424002000A00040 +5CE6:02000100FFFE044014501448244444440100010021082108210821083FF80008 +5CE7:10401020102013FE54005488550456025488548854505C506420005000880306 +5CE8:101010D813941094549057FE54905494549454D857985C9064AA00CA02860102 +5CE9:010041047FFC0000064038500848FFFE084008400E2478280812082A28C61302 +5CEA:10001050104810845524542054505488550656F854885C886488008800F80088 +5CEB:200027DE20922292AA94AA94ABD8A894A992A992AA92BA9ACC94089002900110 +5CEC:1028102413FE1020542055FC5524552455FC552455245DFC652401240124010C +5CED:1020112410A410A8542055FC5504550455FC550455045DFC6504010401140108 +5CEE:200023F820882088AFFEA888A888ABF8A900A900ABF8BD08C908010801F80108 +5CEF:010041047FFC08001FF0282007C01830E10E1FF001001FF001007FFC01000100 +5CF0:1040104010FC10885550542054D8572654F8542054F85C2067FE002000200020 +5CF1:000045FC2824102429FC484488440BFE18002820482089240924092451FC2004 +5CF2:0100210821083FF800000608780808480848FF481C482A484948880808280810 +5CF3:0100210821083FF8000010401040247E24886488A54824502420205020882306 +5CF4:100011FC1104110455FC5504550455FC5504550455FC5C50645000920112020E +5CF5:2040202023FE2202AC44A840ABFEA840A890A890A910B920CA24024204FE0842 +5CF6:020004001FF010101FF010101FF010001FFC10001FFC020422243FE400280010 +5CF7:0100210821083FF8020001003FF808200440FFFE010001007FFC010001000100 +5CF8:2028202420242020ABFEAA20AA24AA24ABA4AAA8AAA8BA90CA9205AA04460882 +5CF9:010002800C603018CFE601003FF801001110250802000100210821083FF80008 +5CFA:100013FE1020102055FC5524552455FC5524552455FC5D2064A0004000B0030E +5CFB:2040204020882104ABFEA802A888A944AA42A8F8A988BA50C820005001880606 +5CFC:10201120112011FC55205620542057FE5400540055FC5D046504010401FC0104 +5CFD:10201020102013FE5420542055245524552456AA54205C506450008801040202 +5CFE:200C11F08100490009FE1110E11022102210251001002108210821083FF80008 +5CFF:100013FE1040104055FC5484548457FE5400540055FC5D046504010401FC0104 +5D00:0100210821083FF8020001001FF010101FF010101FF011081090126014181806 +5D01:0100210821083FF81080108010FC7D041248104010401CA0E0A0411002080C06 +5D02:2088208823FE2088A800ABFEAA02AC44A840ABFCA844B884C884010402280410 +5D03:20402040204027FCA840AA48A948A950AFFEA8E0A950B950CA48044408420040 +5D04:10201020105010505488550456FA54005444542455245CA86488001003FE0000 +5D05:10401040107C1084550856FE5492549254FE549254925CFE64920112010A0204 +5D06:20402020202023FEAA02AC94A908AA04A800A9FCA820B820C820002007FE0000 +5D07:0100210821083FF8020001007FFE40029FF400007FFC01001110210845040200 +5D08:020001007FFE40029FF400007FFC11102108450402000100210821083FF80008 +5D09:1020102213B410A854A8552456A2544055FC550455045DFC6504010401FC0104 +5D0A:2088208820882088ABDEA888A888A99CA9DCAAAAAAAABCC8C888008800880088 +5D0B:0100210821083FF800007FFC11101110FFFE111011107FFC0100FFFE01000100 +5D0C:100011FE1102110255FE5510551055FE55105510557E5D4265420242027E0442 +5D0D:10201020102013FE542055245524552456AA547054A85CA86524022204200020 +5D0E:1020102011FC10505488550457FE540855E8552855285DE86528000800280010 +5D0F:201C23E0222023FEAA20AA92AB0AAA06A9FCA904A904B9FCC904010401FC0104 +5D10:100011FC1104110455FC5504550455FC5400551255D45D18651001520192010E +5D11:0100210821083FF800001FF810081FF810081FF82080208C3EF020822682387E +5D12:0100210821083FF8020001007FFC0820145022880100FFFE0100010001000100 +5D13:200023FE22222222ABFEAA22AA22AAFAAA8AAA8AAA8ABAFACA8A020203FE0202 +5D14:010041047FFC090008801FFC108030805FF8908010801FF8108010801FFC1000 +5D15:100011FE11101110557C5510551055FE5500551055105D7C6510021002FE0400 +5D16:0100210821083FF800003FFC20802FF820803FFC200020804FF840809FFE0000 +5D17:0100210821083FF800007FFC482444445FF441044924492449244FE440144008 +5D18:1020102010501088550456FA540055FC5554555455FC5D54655401540104010C +5D19:0100210821083FF802800C6037D8C0063FF8248824883FF82488248824A82010 +5D1A:2020202021FC2020A820ABFEA888A944AA42A8F8A988BA50C820005001880606 +5D1B:200023FE22022202ABFEAA10AA92AA92AA92AAFEAA10BA92CA92049204FE0802 +5D1C:2008203C21E02020ABFEA8A8A8A8A8A8ABFEA8A8A8A8BBFEC820002001FC0000 +5D1D:1020102013FE102055FC542057FE540055FC550455FC5D0465FC010401140108 +5D1E:2040202023FE2000A9FCA904A9FCA800A9FCA808A810BBFEC820002000A00040 +5D1F:0100210821083FF8010002800C603018CFE6010001003FF811100920FFFE0000 +5D20:1020102013FE102055FC552455FC552455FC542054705CA86124062200200020 +5D21:200021FC20082010AA22AAAAAA72AA22AA72AAAAAB26BAA2CA42020203FE0002 +5D22:101E13E011221094540055FC5424542457FE542454245DFC6424002000A00040 +5D23:010041047FFC00701F8001007FFC05401930E10E04007FFC08201C4003807C78 +5D24:21842068203020C8AB24A820ABFEA840A8FCA984AAFCB884C8FC008400940088 +5D25:1040108011FC1124552455FC5524554455FC549055105FFE6410001000100010 +5D26:2040208027FE2110AA48AC46ABF8AA48AA48ABF8AA48BA48CBF800420042003E +5D27:0100210821083FF8101010901090FD0831483A44544250909088110813FC1104 +5D28:1020102013FE102055FC542457FE542455FC542055205D3E652002A0027E0400 +5D29:0100210821083FF800003E7C224422443E7C224422443E7C224422444A948508 +5D2A:1040102013FE100054885488555456225400542057FE5C206420002000200020 +5D2B:0100210821083FF800003FF820083FF820802490249027F02080488848888FF8 +5D2C:0100210821083FF80100FFFE01003FF821083FF821083FF803800D603118C106 +5D2D:0100210821083FF81000100CFEF0208048807EFE08880E88F888490809080A08 +5D2E:0100210821083FF800003FF8210821082FE8210827C8244827C820083FF82008 +5D2F:10201020105010885504560254F85420542055FC54205D2464A400A803FE0000 +5D30:1092109211241248552454925492540055FE552255225DFE6522012201FE0102 +5D31:0100210821083FF800003F0421243F2421243F24212421243F24120421144088 +5D32:1020104011FC110455FC550455FC540057FE542054205DFC6420002003FE0000 +5D33:204020A021102208ADF6A800ABC4AA54AA54ABD4AA54BA54CBD40244025402C8 +5D34:0100210821083FF8002800243FFE20202FA422242FA824982D12422A45468882 +5D35:100010FC108410FC548454FC540055FE548054FE552A5E4A6492012200540088 +5D36:0100210821083FF8080008087F0808FEFF08084808287F2808080F08F0284010 +5D37:10881048105013FE5450545055FC55545554558C55045DFC6504010401FC0104 +5D38:100013FE1020104055FC5504550455FC550455FC55045D0465FC000000880104 +5D39:2040202021FC2000A888A850ABFEAA22AC24A9FCA924B924C934012800200020 +5D3A:0100210821083FF820401040FEFE212020AC3CB425E424AC24A044A25482887E +5D3B:211021102210247CA910A910AAFEAE08AA08AAFEAA08BA48CA28020802280210 +5D3C:100011FC1104110455FC5504550455FC540057FE54205D20653C012002A0047E +5D3D:0100210821083FF800001FF0111011101FF0111011101FF001004884481287F2 +5D3E:200023FE20502050ABFEAA52AA52ABFEA800A840AFFEB888C990006000D80304 +5D3F:100011DC1154115455DC540055FC540057FE548054FC5C046404000400280010 +5D40:0100210821083FF80000084008207EFC082018201CFC2A202A20482089FE0800 +5D41:1088108813FE108854F8548854F85488548857FE55005D486584010001FE0000 +5D42:0100210821083FF8004013F8204847FE884813F8304053FC904017FE10401040 +5D43:1020101011FE10005484544855FE55085510556455085D1265640208023004C0 +5D44:2104208823FE2020A820A9FCA820A820ABFEA800A820BBFEC820005000880306 +5D45:0100210821083FF8002800243FFE20202FA420242FA8289828924FAA40468082 +5D46:0C487044104013FEFC503890549091121212110E01002108210821083FF80008 +5D47:08481C44F04013FE1050FC5010923892350E5420502091241124112411FC1004 +5D48:203C27C022442128A800ABFCA880A880AFFEA900A9F8BA88CA50042008D80306 +5D49:2040202023FE2000A9FCA904A9FCA800ABFEAA02A9FCB820C820002000A00040 +5D4A:203823C0204027FCA950A954AF58A954AB54AD4CA8E0B950CA48044408420040 +5D4B:100011FE1112111255FE5500557E55425542557E55425D7E62420242047E0842 +5D4C:0100210821083FF800202220223EFF42229422103E10221022283E2822440082 +5D4D:00407F40127E0C88FF4819482A504820A850118C01002108210821083FF80008 +5D4E:21FC2124212421FCA924A924A9FCA820A820ABFEAA22BA2ACAFA020A02020206 +5D4F:010041047FFC00002448238824483FF81010220847E40820144003801C70E00E +5D50:0100210821083FF800001FF0101010D01710111017D0155027CA212A4FE68022 +5D51:100011FC110411FC550455FC548055FE5622552255525D0265FA000200140008 +5D52:00001FF0101010101FF000007C7C444444447D7C01002108210821083FF80008 +5D53:0100210821083FF800001FF0101010101FF000007EFC4284428442847EFC4284 +5D54:010041047FFC00001FF011101FF011101FF00000FFFE111010A014401830100E +5D55:2000208822522222AA52AA8AAA02ABFEA888A944AA7AB888C950002000D80706 +5D56:1020102013FE107054A85524562255FC550455FC55045DFC6504000003FE0000 +5D57:0100210821083FF8004800443FFE20402F4422442A282AA83112422A44C69B02 +5D58:2088208823FE2088A800ABFEAA02AC24A820ABFEA870B8A8C8A8012402220020 +5D59:0100210821083FF800000C1070901050FC903050381E55F05010901010101010 +5D5A:0100210821083FF8104010403E7C4084BD2810201020FE501050148819041202 +5D5B:0100210821083FF802800C6037D8C0063E0822483E4822483E48220822282610 +5D5C:010041047FFC020001003FF808200440FFFE00101F90109010901F9000500020 +5D5D:2020212420A82020ABFEA8A8A924AA02A840AFFEA888B908C990006001980604 +5D5E:010002800C603018CFE601003FF80100111025080200101092929292FEFE0202 +5D5F:010041047FFC00003FFC2280224027FC2C4037F8244027F82440444047FC8400 +5D60:101E13E0112210945440548855F0542054C455FE54225C2063FE005000880306 +5D61:010041047FFC044008203218C4460FE000207EFC224412240A1412242A544488 +5D62:102010201050104854A455FE568454FC548454FC54805CFC65440144027C0044 +5D63:1020101011FE1110557C551455FE5514557C5510557C5D4465440244027C0444 +5D64:08202AA42CA84920145022887FFE40028104010021082108210821083FF80008 +5D65:2104210421DE2244AD54A89EA904AA24AC24ABFEA870B8A8C924062200200020 +5D66:102011241124112455FC540057FE540055FC550455045DFC6488005003FE0000 +5D67:204023BE22122292AA52AAAAAB24A840ABFEAA22AA22BBFECA22022203FE0202 +5D68:2040208021FC2104A904A9FCA900A9FEA900A9FEA802BAAACAAA040200140008 +5D69:010041047FFC0200FFFE00001FF010101FF000007FFC40044FE448244FE4400C +5D6A:2040202023FC2000A9F8A908A9F8A800ABFCAA04AAF4BA94CAF4020402140208 +5D6B:20842044204823FEA884A884A908A94AAA52AB9CA884B908C908025203DE0042 +5D6C:0100210821083FF8020004003FF821083FF821083FF8029004A808FA308AC07E +5D6D:2040202023FC2108A890ABFEAA02AC44A820ABFCA880B8F8C888010801280210 +5D6E:1020102013FE102055FC550455FC550455FC550455FC5D0463FE008801040202 +5D6F:11081088109013FC544055F8544057FE5480550055FC5E206420082003FE0000 +5D70:10881050100011FE545055FC545457FE545455FC54505CD86554025200500050 +5D71:2040202023FE2202AC94A908AA64A890A908AA04ADFAB908C908010801F80108 +5D72:1020104011FC110455FC550455FC550455FC542057FE5C7064A8012402220020 +5D73:0100210821083FF8082004407FFC01003FF80200FFFE080037F0C0801FFC0000 +5D74:2040224821502248ACA4A918AE06ABF8AA08ABF8AA08BBF8CA08020802280210 +5D75:0100210821083FF8004078404BFC48404FFE78104FFE48104A10791048500020 +5D76:200023DE20422042ABDEAA10AA10ABDEA842AA52A94AB94ACA52004202940108 +5D77:2124212422242424A954A94AAA92AE10AA10AA50AA5CBA50CA5002B0029E0300 +5D78:0100210821083FF81110211041108AA8144430405240927C1240154014FE1800 +5D79:010041047FFC00007CF8048804F87C2041FC41247D2405FC042004242BFE1002 +5D7A:200027BC208424A4AA94ACA4A850A988AE26A8C0AB10B864CB88003000C00700 +5D7B:1020101011FE1110557C551455FE5514557C551055925D546538025402920430 +5D7C:2040202023FC2000A908A890ABFEAA20AAA0AAFCAB20BA20CAFC0420042009FE +5D7D:2154215423FE2154A954AA72AC00ABFEAA22A820A9FCB924C9240124012C0020 +5D7E:010041047FFC08201FF0102025487EFC04401930E64E1990062018C007003800 +5D7F:010041047FFC00000000FDFC104011F8110811F8110811F8110811F850902108 +5D80:11FC102013FE122255AC542055AC540055FC540057FE5C8064FC000400280010 +5D81:102011FC112413FE552455FC542055FC552455FC54405FFE648801D00070038C +5D82:102011FC1088105057FE540055FC550455FC550455FC5C2067FE002000200020 +5D83:22002202223C2FA0AA20AFA0AABEAFA4AAA4AFA4AA24BFA4CA24024402440284 +5D84:0100210821083FF808067F7808407F40497E7F4849487F4808487F4808880908 +5D85:082008207F20087E7E4408A4FF2810101E28224446828100210821083FF80008 +5D86:2090209027FE2090ABFCAA94ABFCAA94ABFCA800A9F8B908C9F8010801F80108 +5D87:200023FE2200227CAA44AA44AA7CAA00AAEEAAAAAAAABAAACAEE020003FE0000 +5D88:0100210821083FF80440247C24A83D50042804487DFE24882448244844088418 +5D89:0100210821083FF800A0009079FE49204B204DFC492049FC7920492001FE0100 +5D8A:0100210821083FF810A01090F9FE11201B2015FC3120D1FC1120112051FE2100 +5D8B:1040108011FC110455FC550455FC550055FE550055FE5C0262AA02AA0202000C +5D8C:010041047FFC04001FF010101FF010101FF010001FFC10001FFC492484940008 +5D8D:100013DE10421252554A56525442542055FC550455045DFC6504010401FC0104 +5D8E:0100210821083FF800003F0821083F0820FE2E0820483F2844285508A4A80C10 +5D8F:010041047FFC00007FFE40005FDC45045FC4554459DC50505FD050525FD2904E +5D90:010041047FFC010079F04A9050606198560649F04A406BF8544043F8404047FC +5D91:208020F8210823FEAD12A922A9FEA840A8A2AB54A898BB34C854009203500020 +5D92:21042088200023FEAA22AAAAAA72AA22ABFEA800A9FCB904C9FC010401FC0104 +5D93:103C13E0112410A855FE54A85524560255FC552455245DFC6524012401FC0104 +5D94:0100210821083FF808401440227C5C8489283E2008204A5028500E8871042202 +5D95:2090208821FE2110AB10ADFEA910A910A9FEA910A910B9FEC90002A402520452 +5D96:204020A0211826E6A800ABF8AA08ABF8A800AFBCA884BCA4C29404A402940108 +5D97:208822AA22DC2488A954AA22A800ABFEAA42AC44ABFCB844C844008401140208 +5D98:0100210821083FF81090108813FEFC48103231CE3890548853FE9048103211CE +5D99:2020212420A823FEA8A8A924AA22A904A904A9DEAA44BD54C89E010402040404 +5D9A:010041047FFC01007FFC044028281FF02828CFE608200FE00100111025080200 +5D9B:1020102011FC102055545488550456FA548854F854885CF8642000A801240060 +5D9C:010041047FFC00003E7C081048907EFE1428244A46863FF820083FF820083FF8 +5D9D:202027A420A82292A914AA08ADF4A802ABF8AA08AA08BBF8CA0801100FFE0000 +5D9E:00407BFC488051F8622055FC488848F8688850F840884100210821083FF80008 +5D9F:2088205023FE2050A9FCA954A98CA974A904A9FCA808BBFEC908008800A80010 +5DA0:101811E0104013FE5488557456525470540055FC55045D74655401740104010C +5DA1:010041047FFC00003FFE289025102FBE22222AD42A902F902228442844448882 +5DA2:2020202021FC2020ABFEA908AB9CA908A988AE3EA800BBFEC89000900112020E +5DA3:010041047FFC010008801FFC30805FF810801FF810801FFC1000248822444244 +5DA4:010041047FFC01003FF80100FFFE08203EF808207EFC00007FFC04401842E03E +5DA5:20002FFE28002A28A948ABEEA892A884AAA0AAA8ABE8B888C894091409241242 +5DA6:108010F8110813FE5544559255FE5500557C5500557C5D00657C0244027C0444 +5DA7:100011FC115411FC542055FC542057FE5488545055FC5C2067FE002000200020 +5DA8:0A803138228838382288393822887FFE4002810401002108210821083FF80008 +5DA9:105011FC115411FC555455FC540055FE5500557C55005DFE6550015401480266 +5DAA:010041047FFC24481450FFFE082004407FFC01003FF80100FFFE05401930E10E +5DAB:2050225221542050ABFEA888A850ABFEA820A9FCA820BBFEC8A8012406220020 +5DAC:2104208823FE2020A9FCA820ABFEA854A992A890ABFEB890C8D4038A009601A2 +5DAD:0100210821083FF810407C2045FC44887C5043FE40207C2045FC44207C204420 +5DAE:1020102010501088550456FA5400540055DC555455545DDC6488008801540222 +5DAF:41047FFC00003E2822243E240020FFFE22203E2822283E1022122F2AF2464282 +5DB0:210021DE224A248AABEAAAB6AAA4ABF4AABEAAA4ABE4BABECAA402A402240464 +5DB1:108813FE108811FC550455FC550455FC548055FE56225D52650201FA000A0004 +5DB2:010041047FFC08801FFC30805FF890801FF810801FFC10003E7C224423D42008 +5DB3:21083FF800007FFC06003B0804B019C062A00C98732610207CFC10201E20F1FE +5DB4:04003FF82008292825482FE8254829280200FFFE08203118D11611101FF00010 +5DB5:200023FC22942294ABFCA800A890AF9EA890A890AB9CB890C890079E00900090 +5DB6:010041047FFC000022204AA08ABE1FC420A46F24A0282F28291029A829443082 +5DB7:010041047FFC0000247C3A0422281E1020FE3E124850085E7F5014B0229E4100 +5DB8:208822AA22DC2488A954AA22A800ABFEAA22A820ABFEB870C8A8012406220020 +5DB9:202023FE202021FCA800ABFEA802A9FCA820ABFEA800BBFEC80403BE02A4038C +5DBA:010041047FFC100013FC284045F8930809F8FD0805F8090851F8200010900108 +5DBB:010041047FFC08207F280824FFFE12203FA46424BFA824183F92242A3FC62082 +5DBC:2140224C22642244AB4CAA64AAA4ABACAAA4AAA4AFFEB800C910010802040404 +5DBD:0100210821083FF8001052182F945014977E1010372850289728154457442082 +5DBE:203E27C022442128ABF8A840AFFCA800ABF8A808ABF8B808CBF80544052A08FA +5DBF:200021FC202023FEAA22A9ACA820A9ACA800ABFEA820B9FCC95401540154010C +5DC0:010041047FFC08002A284D240820142E3F706424BF2424283F12242A3F462082 +5DC1:200023FE224823FEAA48AAFCAAA4AAFCAAA4AAFCAA20BBFEC32A057A050A0906 +5DC2:21083FF808801FFC30805FF890801FF810801FFC10003FFC24242BD4224423CC +5DC3:41047FFC08407F7C2240147CFF04007C7F40417C7F40417C7F40417C4542423E +5DC4:2110209023DE2010AA5EA982ABDEA810ABDEAA50ABDEBA50CBDE0250025202CE +5DC5:21083FF808007EFE08103E20227C3E4422543E5422543E542254FF2824444282 +5DC6:208822AA22DC2488A954AA22ABFEAA02A8F8A888A8F8B800C9FC010401FC0104 +5DC7:208820CC208A23E8AAA8AADEABA8AA6AAA0AABEAAC0CBFECCA2A03EA015607E2 +5DC8:010041047FFC000029007DFC29043A4411547CE455F47C4410E4FD5410541008 +5DC9:21F0221027FC2204ABFCAA24ABB8AA22A9FEAA10AFFCBA44CBFC00D0014A063E +5DCA:23DE225223DE2252ABDEAA52ABDEA98CAA52A840AFFEB888C990006000D80304 +5DCB:010041047FFC10007DFC44047CFC40047DFC44007DFE11225CFC50A45EACF020 +5DCC:41047FFC220811103FFC20002E20223C3FA829482F2829282F1049D07F288144 +5DCD:010041047FFC0C20704011FCFD2439FC552493FCFC24245A685E10902912C60E +5DCE:200027FE204022EEAAAAABEAAAAEAAE8ABAAACE6AA88BDF4CA90006001980606 +5DCF:208823FE208823DEAA52ABDEA8A0A890A9FEA920ABFCBD20C9FC012001FE0100 +5DD0:010041047FFC08007F7C00443E7C22443E7C00107F6441245DFE55245D244344 +5DD1:252827BE294827BEAB18ADAAA946ABFCAA04ABFCAA04BBFCCA0403FC01080204 +5DD2:210447C88812F3BC20084B92F83E0380AAAAABAA01002108210821083FF80008 +5DD3:010041047FFC22003CFE21101F7C52445E7C52445E7C52447F7C002824444282 +5DD4:21083FF808007EFE08103E20227C3E44227C3E44227C3E44227CFF2824444282 +5DD5:2108209027FE2108ABFEAA54ABC8AA3EABC8AA5CABC8B840CBFE00880070038C +5DD6:010041047FFC00001E7812483FFC20202E20223C3FC829282F2849905F288144 +5DD7:23DE225223DE2000ABFEAA00AAC8AA4EABEAAAB2AAEABAAACAEA02B405E4082A +5DD8:210821EC210A2FEAA928ABC8A93EAFE8A948ABE8AA28BB68CAA80BF40AB412A2 +5DD9:211027FE204022EEAAAAABEAAAAEAAE8ABAAACE6AA88BDF4CA90006001980606 +5DDA:010041047FFC08000F9008147F9248FE7E1048905FA851285F28554455449382 +5DDB:0000000008880888088811101110222022201110111008880888088800000000 +5DDC:0000041004100820082010402080410020801040082008200410041000000000 +5DDD:1004108410841084108410841084108410841084108410842084208440048004 +5DDE:1004108410841084108454A45294529490841084108410842084208440048004 +5DDF:02000100FFFE1000100010001FF800001110111011101110211021124112800E +5DE0:00007FFE00000888111022201110088800003FF80100010001000100FFFE0000 +5DE1:000021241124112402480248F490124812481124112411241000280047FE0000 +5DE2:088811102220111008883FF821083FF821083FF80100FFFE054009203118C106 +5DE3:22081108111000003FF821083FF821083FF80100FFFE054009203118C1060100 +5DE4:1084210810843FF82448238824483FF80000294825282948252A210A29463182 +5DE5:000000007FFC0100010001000100010001000100010001000100FFFE00000000 +5DE6:020002000200FFFE04000400040008000FF8108010802080408080803FFE0000 +5DE7:000003FEFC40104010801080110011FC100410041E04E0044004000400280010 +5DE8:00003FF82000200020003FF02010201020103FF020002000200020003FFC0000 +5DE9:000001F07D1011101110111011901150115011101D10E11242120212040E0800 +5DEA:00003FF8200020003FF0201020103FF0200020003FFC00007FF8000800080008 +5DEB:000000007FFC01000100111011101110292829284544858401000100FFFE0000 +5DEC:00007DF01110111011121D12E20E440001003FF80100FFFE028004401830600C +5DED:00407C4013FC104410441C84E114420801003FF80100FFFE028004401830600C +5DEE:082004407FFC010001003FF802000200FFFE0400080017F82080408080801FFC +5DEF:00207C1005FE08201048288445FE820200A87CA810A810A810AA1D2AE1264200 +5DF0:0020FE1055FE5420A848548455FE0002FEA810A810A810A81EAAF12A41260200 +5DF1:00003FF0001000100010001000103FF02000200020002004200420041FFC0000 +5DF2:00003FF0001000100010201020103FF02000200020002004200420041FFC0000 +5DF3:00003FF0201020102010201020103FF02000200020002004200420041FFC0000 +5DF4:00003FF8210821082108210821083FF82008200020002002200220021FFE0000 +5DF5:007C3F80200020003FFE200020002FF82888288828882FF828084802480287FE +5DF6:0000FEFC2284228442844A84848400FC7E8042804280428242827E82427E0000 +5DF7:044004403FF804400440FFFE044008201FF02828C8260FE008200808080807F8 +5DF8:00007F7C4844484448445E445244527C524052405E404842484248427F3E0000 +5DF9:1FC000447D88055009203118C50602003FF800003FF000103FF0200420041FFC +5DFA:00007CF8448844887CF84080428442843E7C00000000FFFE0000082010102008 +5DFB:0100111009203FF802007FFC082010102FE8C02600200FE008000808080807F8 +5DFC:00003FF0211021103FF02000200420041FFC00003E442258226022423E42223E +5DFD:00007CF844887CF8408042843E7C044004403FF804400440FFFE082010102008 +5DFE:0100010001003FF8210821082108210821082108210821282110010001000100 +5DFF:01000100FFFE0100010001003FF8210821082108210821282110010001000100 +5E00:00007FFC0100010001003FF82108210821082108210821282110010001000100 +5E01:000801FC7F00010001003FF82108210821082108210821282110010001000100 +5E02:0200010000007FFC0100010001003FF821082108210821082128211001000100 +5E03:020002000200FFFE0400090011003FF851089108110811081128111001000100 +5E04:0800080008FE7F1049104910491049104910491049104B100810081008500820 +5E05:082008204820482049FC49244924492449244924492409341128102020204020 +5E06:100011F011107D1055105510559055505550551055105D1211121212120E1400 +5E07:010001003FF80108FFFE01083FF8010001003FF8210821082128211001000100 +5E08:08000BFE48204820482049FC4924492449244924492409341128102020204020 +5E09:1010109010907C8855085504560455FA5488548854885C881108110812281410 +5E0A:1000100011FC7D24552455245524552455FC550055005D001102110210FE1000 +5E0B:00783F80208020803FFC20402822311A21061FF0111011101150112001000100 +5E0C:18180660018006603A180200FFFE048008801FF82888488888A8089000800080 +5E0D:020001003FFC200420043FFC2040204027FC2444244424444454444880400040 +5E0E:1020102010207DFE55225624542054205450545054505C50109010921112120E +5E0F:1020102010207DFE5420542054FC5420542055FE54225C22102A102410201020 +5E10:1080108410847C88549054A0548057FE54A0549054905C88108410A210C01080 +5E11:10001000FEFC2244642818102428C34601003FF8210821082128211001000100 +5E12:08A0109030BE57C0904010241014110C01003FF8210821082128211001000100 +5E13:1020102010207DFE54205420542055FC547054A854A85D241124122210201020 +5E14:1010101010107DFE55125514551055FC5544554455285D281110122812441482 +5E15:1020102010407DFC550455045504550455FC550455045D041104110411FC1104 +5E16:1020102010207C20543E54205420542055FC550455045D041104110411FC1104 +5E17:1050104810487C4055FE54405440547C54A454A454A85D281110122810441082 +5E18:020001007FFE400288241010210801003FF82108210821082128211001000100 +5E19:1020102011207D2055FC55205620542057FE542054505C501088108811041202 +5E1A:00001FF000100FF000101FF000007FFE410281041FF011101110115011200100 +5E1B:010002001FF010101FF010101FF0010001003FF8210821082128211001000100 +5E1C:1000100011FC7D04550455045504550455FC550454005C901088110412021402 +5E1D:020001003FF80000082004407FFE410281041FF0111011101150112001000100 +5E1E:100013FE10207C20544055FC55045504550455FC55045D041104110411FC1104 +5E1F:020001007FFC0440245044488944108001003FF8210821082128211001000100 +5E20:02001CF0101010101EF0101010101FF001003FF8210821082128211001000100 +5E21:1104108410887C0055FE548854885488548857FE54885C881108110812081408 +5E22:1020102010507C885504560255FC5400540055FC55045D041104110411FC1104 +5E23:1110091009207FFC02000400FFFE11102108DFF6111011101150112001000100 +5E24:10001000FE7C224442443444087C3400C20001003FF821082108212821100100 +5E25:102020207C20442045FC45247D24412441247D244524453445287C2044200020 +5E26:092009207FFC0920092000007FFE410281041FF0111011101150112001000100 +5E27:10201020103E7C20542055FC550455245524552455245D241050104810841104 +5E28:1104108410887C1055FC55045504550455FC545054505C9010921112120E1400 +5E29:1020112410A47CA8542055FC5504550455FC550455045DFC1104110411141108 +5E2A:100011FE11007D00557C5500550055FE5550555255545D481148124412521460 +5E2B:100023FE7C204420442045FC7D24412441247D244524453445287C2044200020 +5E2C:00003FF80208FFFE04083FF808001FF82808CFF800801FFC1084109410880080 +5E2D:010000803FFE222022203FFC2220222023E020802FF82888488848A888900080 +5E2E:0800087CFF4808507E480844FF54104820404100BFF821082108212821100100 +5E2F:092009207FFC09200FE000007FFE410281041FF0111011101150112001000100 +5E30:080009FC480448FC480449FC48004BFE4A22482049FC09241124113421284020 +5E31:2040204027FCF840ABF8A880AFFEA890A910A9FEAA10BA902450281020502020 +5E32:1044104410887DDC548854885488548855DE548854885C881088108810881108 +5E33:100010FC10807CF8548054F8548057FE5540552455285D101108114411821100 +5E34:10481044105E7DE054285412546A55965448545E55E05C2410281012106A1186 +5E35:2040202023FEFA02AD04A900A9DEAA52AA52AB52AC9AB894211021122212240E +5E36:145014507FFC1450245247CE80007FFC41041FF0111011101150112001000100 +5E37:1050104810807CFE5590569054FC5490549054FC54905C90109010FE10801080 +5E38:0100111009207FFE40028FE4082008200FE001001FF011101110115011200100 +5E39:2080204023FCF800A908A890AFFEA840A840AFFEA888B9082090206021982604 +5E3A:1088108811FC7C88548854F85488548854F8548854885DFE1000108811041202 +5E3B:2040204027FCF840ABF8A840AFFEA800ABF8AA08AA48BA48224820A021102608 +5E3C:200023FE2202FA02ABFEAA22AA22AAFAAA22AA32AA2ABBFE2202220223FE2202 +5E3D:200023FC2204FAF4AA04AAF4AA04A800A9F8A908A9F8B90821F8210821F82108 +5E3E:1020102211FA7C24542857FE5420544054FC558456845CFC1084108410FC1084 +5E3F:210021782108FA08AAFEAE40AA40AA7CAA90AA10AAFEBA102228222822442282 +5E40:10201020103E7C20542055FC550455FC550455FC55045DFC1000108811041202 +5E41:100013FE10207C4055FC5504550455FC550455FC55045D0411FC100010881104 +5E42:00007FFE40029FF410101FF010101FF00200FFFE09203FF8D116115011200100 +5E43:1040104011FC7C8457FE540055FC550455FC542057FE5C20122013FE10201020 +5E44:200023FC2204FA04ABFCAA00ABFCAA40AA88ABFCAA24BA2025FC2420282033FE +5E45:100011FE10007CF85488548854F8540055FC552455245DFC1124112411FC1104 +5E46:100011FC11047DFC550455FC548055FE5622552255525D0211FA100210141008 +5E47:080808087E0808FEFE0808487E2808080F28F11001003FF82108212821100100 +5E48:200023FC2204FA04ABFCAA00AA84AA48AAFCAA48AA48BBFE2448244828883108 +5E49:204821482148FBFEA948A948A978A900A9FEA820ABFEB87020A8212426222020 +5E4A:100011FC10207C2057FE540055FC550455FC550455FC5D0411FC108811041202 +5E4B:10783E4822482A86FF7822482A2842104A28854601003FF82108212821100100 +5E4C:100011FC11047DFC550455FC5420552454A8542057FE5C50105010921112120E +5E4D:101E11E010227D1254945480542055CE5502550255CE5D021102110211FE1102 +5E4E:200023FE2202F800A9FCA904A9FCA904A9FCA840A820BBFE2000208821042202 +5E4F:2040202023FEFA02A800A9FCA840A8A2AB34A858A894BB342052209023502020 +5E50:0020792448A849FC48407BFE49084A244C2279FC492449244934492848209820 +5E51:12101A902A904AA08FBE10442FA46224A2242FA82AA82A902AA82BA822442282 +5E52:1020104011FC7D24557C558C55545524555455FC54405C2412A2128A14881078 +5E53:2040208821FCF908AA52ABFEA850A988AE26A8C0AB10B8642388203020C02700 +5E54:200021F82108F9F8A908A9F8A800ABFCAA94ABFCA800B9F82090206021982606 +5E55:04407FFC04401FF010101FF010101FF00400FFFE11103FF8D116115011200100 +5E56:100013FE10507DFC5554555455FC540055FC540057FE5C2010A8112412A21040 +5E57:200023FE221AFA16ABFEAA12AAEAAAAAAAAAAAEAAA0EBA6A239A222623FE2202 +5E58:102013FE10207DFC542057FE540055FC550455FC55045DFC110411FC10881104 +5E59:1088108813FE7C88540055FC550455FC550455FC54205DFE1050108811041202 +5E5A:087CFF4808507E480844FF54104822405FF090101FF010103FF8210821180100 +5E5B:102011FC10887C5057FE540055FC550455FC550455FC5C2013FE102010201020 +5E5C:100011FC11047DFC550455FC542057FE540055FC55045DFC1020112412221060 +5E5D:200023DE2252FA52ABDEA800A9FCA924A9FCA924A9FCB82023FE202020202020 +5E5E:205022522154F850ABFEA888A850ABFEA820A9FCA820BBFE2050208821042602 +5E5F:2110209423D2F812AA50A990AFFEA810ABD2AA52AA54BBD4224A224A23D62022 +5E60:2080208021FEFB54AD54A954ABFEA954A954A954AFFEB8002154212A222A2000 +5E61:207827C02248F950ABFCA950AA48AC06ABF8AA48AA48BBF82248224823F82208 +5E62:102011FC10887C5057FE540055FC552455FC552455FC5C2011FC102013FE1000 +5E63:49202A207F3E49485DA86B2849104928404601003FF821082108212821100100 +5E64:082049202A3E7F4841A85D2855105D28424601003FF821082108212821100100 +5E65:212420A823FEFA02A8F8A888A8F8A80CA9F0A820A9FCB82023FE202020A02040 +5E66:00407C2045FC44887C5043FE7C20A5FC24203D2001003FF82108212821100100 +5E67:10F8108810887CF8540055DC5554555455DC542057FE5C7010A8112412221020 +5E68:210021F82208FFFEAA88AB24ABFEAA00AAFCAA00AAFCBA0022FC248424FC2884 +5E69:102011FC10207C8857FE548855FC550455FC550455FC5D0411FC108811041202 +5E6A:208823FE2088FBFEAA02A9FCA800ABFEA840A8A2AB54B8B82354209223502020 +5E6B:08083EFE08087F4808283E0809287FF028200FE008200FE001003FF821082118 +5E6C:202023FE2020F9FCA800ABFEA802A9FCA820ABFEA800BBFE200423BE22A4238C +5E6D:210827FE2108F800ABFCAA94AA94ABFCA828ABFEAA20BB2422A82292242A28C6 +5E6E:2040202023FEFA44ABF4AA44AAEEAA04AAF4AAACAAE4BA1422A4247425942808 +5E6F:2108210821EEFA94A842A800ABDEAA52ABD2AA52ABD2BA1A2294235022102010 +5E70:102013FE12227DFC542054F8542055FC542055FC55545DFC104012A4128A147A +5E71:23DE225223DEFA52ABDEAA22AAFAAA22AAFAAAAAAAFABAAA22FA227222AA2226 +5E72:00003FF801000100010001000100FFFE01000100010001000100010001000100 +5E73:00007FFC010001001110091009200100FFFE0100010001000100010001000100 +5E74:100010001FFC2080208040801FF8108010801080FFFE00800080008000800080 +5E75:00007C7C10101010101010101010FEFE10101010101010102010201040108010 +5E76:10100810082000007FFC0820082008200820FFFE082008201020102020204020 +5E77:0808080810107C7C1010101010101010FCFE1010101010102010201040108010 +5E78:010001003FF801000100FFFE082004403FF801000100FFFE0100010001000100 +5E79:102010201050FE5010887D0446FA7C2044207C2011FCFE201020102010201020 +5E7A:0200020004000810101020207FC02080010002000400082010103FF810080000 +5E7B:0800080011FC100422044204FC0404040804100424044204FE04420400280010 +5E7C:104010402040204045FC4444F84408441044108428844484FD04450402280410 +5E7D:0100010009200920514455547DF44924492455547DF44514410441047FFC0004 +5E7E:1110212045447978111025247D7C15241110FFFE1080108828522422405A8186 +5E7F:0100008000803FFC200020002000200020002000200020002000400040008000 +5E80:010000803FFE2000200022002204221822602380220022022202420241FE8000 +5E81:010000803FFE2000200020002FFE204020402040204020404040404081400080 +5E82:010000803FFE2000208020802080208020802140214022204220441088081006 +5E83:010000803FFE20002080208020802100210021002210220844084FFC84040004 +5E84:0100008000803FFC20002080208020802FFC208020802080208040805FFE8000 +5E85:010000803FFE20002100210022202220244028802100220844044FFE84020000 +5E86:010000803FFE20002080208020802FFC20802140214022204220441088081006 +5E87:010000803FFE20002420242024242428273024202420242245224622841E0000 +5E88:010000803FFE20802140222024102908308620802FF020104020402080400080 +5E89:010000803FFE204020402FFE204024442444244427FC204220424042403E8000 +5E8A:010000803FFE2000208020802FFC208021C022A022A024904888508680800080 +5E8B:010000803FFE208020803FFC208020802FF02410222021404080416086183806 +5E8C:010000803FFE200020002FFC2020242028202FFE20A021204620582080A00040 +5E8D:010000803FFE2000201C27E02400240027FE2420242024204820482090202020 +5E8E:010000803FFE2040204020A0211022082D162110211021104110421082100410 +5E8F:010000803FFE200023F8201020A020402FFE2042204420404040404081400080 +5E90:010000803FFE2100208027F824082408240827F8240824004400480088001000 +5E91:010000803FFE200020002FFC208020803FFE21402140224042424442883E1000 +5E92:010000803FFE20802080208020802FFC2080208020902088408840809FFE0000 +5E93:010000803FFE210021003FFC2200248028802FF8208020805FFE408080800080 +5E94:010000803FFE200020002104288424842448224822102210402040409FFE0000 +5E95:010000803FFE2000203C27C024402440244027FE242024202412450A46468422 +5E96:010000803FFE2200220027F8280837C82448244827C824282412440243FE8000 +5E97:010000803FFE20802080208020FC2080208027F8240824084408440887F80408 +5E98:010000803FFE2000200027FC2444244427FC2444244427FC2444404040408040 +5E99:010000803FFE2000208020802FF82888288828882FF82888488848888FF80808 +5E9A:010000803FFE200020802FF8208820883FFE208820882FF8414042208C183006 +5E9B:010000803FFE2000211021102512251425D8251025102510251245D25E12880E +5E9C:010000803FFE200022082208240824FE2C083488244824484408440884280410 +5E9D:010000803FFE2100210023F82610292020C023303C0E20C04020430080C00020 +5E9E:010000803FFE2220221022002FFC22402240224824502460484248C2933E2000 +5E9F:010000803FFE2080249028882FFE210021FC2284228824502420485051888606 +5EA0:010000803FFE241022203FFC208020802FF8208020803FFE2080408040808080 +5EA1:010000803FFE208020403FFE20802100228426882A5032204210428883060200 +5EA2:010000803FFE200020002FFC2100221027F8208820802FFC40804080BFFE0000 +5EA3:010000803FFE212021202924252821302120233025282924222042224422881E +5EA4:010000803FFE2000204027FC204020403FFE200020102FFC4210411081500020 +5EA5:010000803FFE20002220222024202DFE347024A824A825242622442044208420 +5EA6:010000803FFE222022203FFC2220222023E020002FF02410422041C08630380E +5EA7:010000803FFE20802490249024902AA831C420802FF8208040804080BFFE0000 +5EA8:010000803FFE2080208827F020A03FFE20802FF02620384047FC404081400080 +5EA9:010000803FFE20802140222024103BEC208020802FF820804490488892840100 +5EAA:010000803FFE24102410247E3F102410257C26443C4424284410442894440882 +5EAB:010000803FFE20803FFC20802FF828882FF828882FF820805FFE408080800080 +5EAC:010000803FFE221022083FFE224822502264224822522264444A447288C2133E +5EAD:010000803FFE20002E0E22F0241024102EFE221022102AFE4400460089FE1000 +5EAE:010000803FFE20002FFC21202FFC292429242A1C2C042FFC480448048FFC0804 +5EAF:010000803FFE204820442FFE204027FC244427FC244427FC2444444444548408 +5EB0:010000803FFE22082108211027FC2110211021102FFE21104110421084100810 +5EB1:010000803FFE208020802FFC20803FFE2408290433F22610492040C08730380E +5EB2:010000803FFE204020402FFE204022482248255428E2215042484C4680400040 +5EB3:010000803FFE2080210027FC244427FC248427FC212022203FFE402040208020 +5EB4:00803FFE221022102FFC221022103FFE200027F82408240847F84408840807F8 +5EB5:010000803FFE200020802FFC2120221024882FF6349027F0249047F24082807E +5EB6:010000803FFE2000222022203FFC22202220222023E020004A48492491240000 +5EB7:010000803FFE20802FF820883FFE20882FF8288024C422A84490488892860100 +5EB8:00803FFE20802FF820883FFE20882FF820802FF828882FF848884FF888880898 +5EB9:010000803FFE221022103FFE221023F0200027F8240827F84420441088081006 +5EBA:010000803FFE221024882924221027F8208820802FFC21C042A0449898860080 +5EBB:010000803FFE222022203FFC2220222023E020002410241044104A2891442082 +5EBC:010000803FFE280029FC28202E4029FC2904292429242B242D24485040888304 +5EBD:010000803FFE200027F8248827F8248827F820802FFC288448A44BF489140808 +5EBE:010000803FFE200022802CB8288828882EB8288828882FF8414042208C183006 +5EBF:010000803FFE211021102FFE2110200027FC2444244427FC2444444447FC8404 +5EC0:010000803FFE20402FFE2842224824B023082C0427F82208211040E043189C06 +5EC1:010000803FFE20002F84288428A42FA428A42FA428A42FA44024490488941088 +5EC2:010000803FFE20002200227C3F442244267C27442AC42AFC52446244827C0244 +5EC3:010000803FFE20402F5021242A1824083BF6212021202FFC212042244424881C +5EC4:010000803FFE20002F78294829482F862900297C2F4428442A2849104B288D46 +5EC5:010000803FFE20802FFC20803FFE220024082FFC20002FFC49244924BFFE0000 +5EC6:010000803FFE208021002FFC28842FFC28842FFC21482154425C44468842303E +5EC7:00803FFE2080277C2424252424A425542648208027FC244447FC444487FC0404 +5EC8:010000803FFE20002FFC208027F8240827F8240827F8220027F84A0841F09E0E +5EC9:010000803FFE220821102FFE212027FC21243FFE212427FC2330452859268120 +5ECA:010000803FFE220021002FBE28A22FA428A82FA42A2229222AAA4CA448208020 +5ECB:010000803FFE2140265C2444275C244427FC20402FFC2208211040E043188C06 +5ECC:010000803FFE22203FFE22223FFE240027FC240027FE2002224A4926500A8004 +5ECD:010000803FFE2400221E2F922014289825143FD220122F9A489448908F900890 +5ECE:010000803FFE200029FE282028FC2E8428FC288428FC2A844CFC480080480084 +5ECF:010000803FFE24002FBC28A42FA428C22F80207E29222A222C94488847948062 +5ED0:00803FFE20002F7E291029102F502950297E2F1028282A2849284B4A8D4A0886 +5ED1:00803FFE24103FFE241027F020802FF828882FF820803FFC40804FF880803FFE +5ED2:010000803FFE22102F90221E2FA422243FD4241427942488448848948AA41142 +5ED3:00803FFE22003FBC20242FA428A82FA820242FA4212423F45E2842208A200420 +5ED4:010000803FFE20802FF828883FFE28882FF8249027F021003FFE441043E09C1C +5ED5:010000803FFE20102F2829442A922C7C2A082910297E2D002AFE4820484488FE +5ED6:00803FFE20002F7C2924251429A421602618388623202C4041884E3081C00E00 +5ED7:010000803FFE22A822A82FFC22AA24E628002FFE284223F84248424882580040 +5ED8:010000803FFE208020402FFC29202FFC29242FFC2A202A244BB8522492A4231C +5ED9:010000803FFE200027FC244427FC244427FC211027FC21102FFE400042088404 +5EDA:010000803FFE22043FC422042FBE20042FA428942F942884450443849C140808 +5EDB:00803FFE20002FF828882FF828882FF820802FF820803FFE488853E480803FFE +5EDC:00803FFE200027FC240427FC244425F8245027FE244024F849884AF8948800F8 +5EDD:00803FFE2900290C3FB0292029202F3E29282F28292829285FA840488A881108 +5EDE:010000803FFE22002220252028BE374222942F90221032904A2843A89C440882 +5EDF:010000803FFE22002FBC22242FA428BC2FA428A42FBC22245FA4424482540288 +5EE0:00807FFE420852484A504A9E5FE4505457545554554857485048515450948022 +5EE1:010000803FFE220024002FFC355025502FFC255025503FFE40004A4889241124 +5EE2:010000803FFE20402F5021242A1824083B7621502F8C28782F48413045488284 +5EE3:010000803FFE22202FF822203FFC20802FF828882FF828884FF8422084100808 +5EE4:00803FFE20803FFC20802FF828882FF828882FF820803FFC40A45F3A91221F1E +5EE5:00803FFE214026303BEC20002FF82AA829C82FF8200027F0441047F0841007F0 +5EE6:010000803FFE2010278824BE248027A22494243E2F882C8854BE478884880008 +5EE7:00803FFE204027FC2248224825543FFE200027FC240425F4451445F4840407FC +5EE8:00803FFE24002F3C311422242FCC2A802FA82ABE2FC82A884ABE4A8888881188 +5EE9:00803FFE20402FFE200027FC240425F4251427FC200823F040404FFE81500E4E +5EEA:00803FFE20402FFE200027FC240425F4251427FC200027FC40004FFE824804C4 +5EEB:00803FFE20002EEE2A222AAA2A662EAA2A102A282E542AAA4A50522492482610 +5EEC:00803FFE2040207C204027FE244225F8244424FC24A824F844A849FC895413FE +5EED:00803FFE2010237C2E10227C2F1022FE2644277C2AC42A7C5244427C82280244 +5EEE:00803FFE20002FBE28A22FBE28A22FBE28A22FBE251428A24FFE431080E00F1C +5EEF:010000803FFE240027222914323E2F882A882F9C2A882F88403E554895480008 +5EF0:00807FFE40207E2055FE54205DFC555455545DFC542056105C547542454A8638 +5EF1:00803FFE20002AA835242ABE2F6829682FBE20282FA82ABE4FA8482888BE07A0 +5EF2:00803FFE20002FBE2514271C25542FFE29202FFC29242FFC4A244BB89222239E +5EF3:00807FFE40107F1052FE5E1052FE5EAA52AA7EFE42007EFE4A245E124AA4BE9C +5EF4:00000000F80008001000100020007800080008004800300010002C0043FE8000 +5EF5:00000124F92409241248124824907A480A4809244924312410002C0043FE8000 +5EF6:0008003CF9E0082010201120213C792009200920492031FC10002C0043FE8000 +5EF7:0008003CF9E008201020102021FC782008200820482033FE10002C0043FE8000 +5EF8:00200020F82009FC11241124212479FC09240924492431FC10002C0043FE8000 +5EF9:00200020F84009FC11041104210479FC09040904490431FC11042C0043FE8000 +5EFA:00400040FBF8084817FE104823F878400BF80840484037FC10402C4043FE8000 +5EFB:000003FCFA040A0412F4129422947AF40A040A044BFC320410002C0043FE8000 +5EFC:000007FEF890089013FC129422947A940A9C0B044A0433FC12042C0043FE8000 +5EFD:000003FCFA940A9412F4129422947AF40A940A944A9433FC12042C0043FE8000 +5EFE:0000000008200820082008200820FFFE08200820082008201020102020204020 +5EFF:08100810081008100810FFFE081008100810081008100810081008100FF00810 +5F00:00007FFC08200820082008200820FFFE08200820082008201020102020204020 +5F01:02000400082010103FF80008082008200820FFFE082008201020102020204020 +5F02:00003FF0201020103FF0200420041FFC000008200820FFFE0820102020204020 +5F03:010000803FFC0200042008101FF80008042004207FFE04200420082010202020 +5F04:00007FFC010001003FF801000100FFFE000008200820FFFE0820102020204020 +5F05:0440082010102FE8C4260420082010A0604008200820FFFE0820102020204020 +5F06:010001003FF80100FFFE040008201FF0001008200820FFFE0820102020204020 +5F07:010002800C603018CFE600001FF010101FF008200820FFFE0820102020204020 +5F08:020001007FFC04402450444889441080000008200820FFFE0820102020204020 +5F09:2420242024203DFC0420FC20242024F8440008200820FFFE0820102020204020 +5F0A:082049202A3E7F4849485DA86B104928434608200820FFFE0820102020204020 +5F0B:022002100210020002FEFF0002000200020001000100008000420022001A0006 +5F0C:0048004400440040FFFE00400040004000400040002000227F92000A00060002 +5F0D:0048004400440040FFFE0040004000407E400040002000220F12F00A40060002 +5F0E:0048004400440040FFFE004000407F40004000403E2000220012078AF8064002 +5F0F:0048004400440040FFFE004000403E4008400840082008220F12780A20060002 +5F10:00483E4400440040FFFE0040004000407E400040002000220F12F00A40060002 +5F11:00144412281013FE28104410101011F0FC9010905890548894EA138A51062002 +5F12:441028141012281045FE1010141011D0FC9030903890548850EA938A10061002 +5F13:00007FF00010001000103FF02000200040007FF8000800080008000800500020 +5F14:00003FF80108010801081FF81100110021003FFC010401040114010801000100 +5F15:00087F080108010801083F082008200840087F0801080108010801080A080408 +5F16:00003FF8000800081FF8100020003FFC000400040004002800100000FFFE0000 +5F17:0440044004407FF8044804483FF8244024403FFC044408440854104820404040 +5F18:00207C200420042004207C404040404040807C880484050407FE050228021000 +5F19:00007CFE0410041004107C10401041FE40107C10041004100410041028501020 +5F1A:0820042004407FF8010801083FF8210021003FFC010401040114010801000100 +5F1B:0020F82008200920092C7934416443A441247934092809220922090250FE2000 +5F1C:00007DFC0404040404047CFC4080408041007DFC040404040404040428281010 +5F1D:00007DFC0524052405247D24412441FC41047D00050005000502050228FE1000 +5F1E:00407C400440047C04847C884120402040207C50045004500488048829041202 +5F1F:0820042004407FF8010801083FF8210021003FFC030405040914110861000100 +5F20:0100F9080908091009207940410047FE41407920092009100908094451822100 +5F21:00007CFE0480048004807CFC4084408440847C8404FC04800480048028FE1000 +5F22:00207D240524052405FC7C20402043FC41047C88048804500420045029881606 +5F23:0088F88808880908097E7B084508414841287928090809080908090851282110 +5F24:0004F81E09F0091009107910411041FE4110791009100908090A094A51A62112 +5F25:0080F880088009FE09027A0444204020412879240A240A220C22082050A02040 +5F26:0040F82008200BFE084078404088410843F078200840088809040BFC51042000 +5F27:0008F83C0BD00A900A907A904290429042907A880A880AC80AA40CD454922800 +5F28:0000FBFC088408840884790441144208440079FC090409040904090451FC2104 +5F29:08007F7C114432280C101228614600003FF000103FF020003FF8000800500020 +5F2A:00007DFC0408041004307C484084430240007DFC04200420042004202BFE1000 +5F2B:00007DFE0520052005207DFC4104410441047D0405FC05200520052029FE1000 +5F2C:00007DFE0510051005507D5C4144414441447D44055C05500510051029FE1000 +5F2D:0000FBFE09080908090879F84108410841F879080908091E0BE8080850082008 +5F2E:111009207FFC0400FFFE10102008DFF600100FF0080010001FF8000800280010 +5F2F:02000100FFFE044014502448444400003FF000103FF020003FF8000800500020 +5F30:00207D2404A404A804207DFC4104410441FC7D04050405FC0504050429141108 +5F31:00007EFC020402047EFC408040807EFC22441224060C1A3462C4020414280810 +5F32:0000F9F80908090809F8780043FC420442047BFC0A040A040BFC0A0452142208 +5F33:0000FBFC080009240A487C904248412440007BFC084008400840084057FE2000 +5F34:0040F8200BFE080009FC790441FC400041FC780808100BFE0820082050A02040 +5F35:0000F8FC088008F8088078F8408047FE41407924092809100908094451822100 +5F36:0040F8200BFE0800080079FC41044104410479FC082008A809240A2250A02040 +5F37:0020F840088809040BFE7822402043FE42227A220BFE08200824082257FE2002 +5F38:0000FBDE0A520A520A527BDE4252425242527BDE0A520A520A520A52555228A6 +5F39:0104F888085009FC0924792441FC4124412479FC082008200BFE082050202020 +5F3A:0000F9FC0904090479FC402083FE8222FA220A220BFE082008240822903F63C1 +5F3B:0000F01E17C211021102F7DE855085508550F6DE14421442144217C2A4544008 +5F3C:0000F01E17C211021202F7DE845084508450F7DE14421442144217C2A4544008 +5F3D:0048F94809480BFE094879484178410041FE78200BFE087008A8092456222020 +5F3E:0242F924080009FC0924792441FC4124412479FC082008200BFE082050202020 +5F3F:01007FFE44429FF404403FF80440FFFE08201FF02028DFE610001FF0001000E0 +5F40:1000FE7810487C480048FE8682007CFC00447C4404287C2840107C2804440D82 +5F41:0000FBFE080809E8092879E8400043FE400879E80928092809E8080850282010 +5F42:0440244814500440FFFE0000FC8004F87D20402081FCFC200450045028881104 +5F43:0000F9FC092409FC092479FC40A840A843FE78A808A809FC08200BFE50202020 +5F44:0000FBFE0A000A7C0A447A44427C420042EE7AAA0AAA0AAA0AEE0A0053FE2000 +5F45:0108F8900FFE08000BC47A5443D4425443D47A440ACC08000BFC088451142608 +5F46:49202A3E7F4849485DA86B10492841463FF000103FF020003FF8000800500020 +5F47:0020F9FC08240BFE082479FC402042AA43AE7A220BFE0A220BAE0AAA52AA2422 +5F48:0000FBDE0A520A520BDE780041FC412441FC792409FC08200BFE082050202020 +5F49:0088F88809FC088808887BFE402041FC412479FC092409FC0800088851042202 +5F4A:0000FBFE080009FC092479FC412443FE400079FC092409FC092409FC500023FE +5F4B:0000FBFC0A940A940BFC780047FE400043FC7A040BFC08A209140B085D442182 +5F4C:0000F7FC124814441FFEF44486EC855486ECF44416EC155416EC1444A4544408 +5F4D:0040F02017FE148815FCF48887FE842085FCF52415FC152415FC1400A4884904 +5F4E:21084FD2F03C23884812FBBE0280ABAA00003FF000103FF020003FF800080070 +5F4F:03DEFA520BDE0A520BDE78A041FE432045FC792009FE080009FC08885070278E +5F50:000000007FF800080008000800083FF800080008000800087FF8000800000000 +5F51:04000400040008000FF008101010102020203FE00040004000800080FFFE0000 +5F52:080008004BFC480448044804480449FC4804480448040804100413FC20044000 +5F53:0100210811080910092001007FF80008000800083FF80008000800087FF80008 +5F54:08000FE0082010201FC000400040FFFE010021081190056009203118C5060200 +5F55:00003FF0001000101FF000100010FFFE010021081190056009203118C5060200 +5F56:08000FF010101FE00020FFFE02000D08719002A00CC071A006981886E2800100 +5F57:1010FEFE10107C7C1010FEFE101000007FF8000800083FF8000800087FF80008 +5F58:08000FF010101FE00020FFFE0200421043D2751441184FD041126292444E0820 +5F59:08000FF010101FE000207FFE40029FF411101FF011101FF00100FFFE1110610C +5F5A:00003FF000101FF000107FFE40029FF411101FF011101FF00100FFFE1110610C +5F5B:3FF000101FF00010FFFE92485484FF7A3828544892980820FFFE082010202020 +5F5C:08000FF010101FE00020FFFE92485484FF7A3828544892980820FFFE08201020 +5F5D:08000FE010201FC00040FFFE92245478FE1238FE545492920820FFFE08201020 +5F5E:3FF000101FF00010FFFE92245478FE1238FE545492920820FFFE082010202020 +5F5F:0044FDFE04540448FCFE059004FEFC9000FE0890FEFE088049FE2844083819C6 +5F60:7E4403FE3E5402487EFE0190EEFE4A906EFEC09004FEFE8045FE244424380DC6 +5F61:0040008001000600180000200040018006001800001000200040018006003800 +5F62:00007F8412041208121012221202FFC412081210122212022204220842108260 +5F63:100408040808FF90222422442208221214221444080808101420230040FE8000 +5F64:00003F04210421082910252225022104FFC82110212221022104410845108260 +5F65:020001003FF8042003C004203FFC202021C02E10206021882E10406043809C00 +5F66:020001003FF8082004403FFC2000202021C02E10206021882E10406043809C00 +5F67:005000480040FFFE004000507C6045C8445044647DA800120E32F0CA43060002 +5F68:0002FFE2000400087BD04A424A424A446B485AD04A424A424A444A484A505AE0 +5F69:010007847804088844902522200204047F880C10162215022484440884100460 +5F6A:0400078404043FC8245027243C84238820102F24290429084912512290FE2000 +5F6B:00003F84248424882E9024A23F8220842E882A902AA22E822084408842908160 +5F6C:1082108210841088FBD01082308239C455A852909282148210841088109010A0 +5F6D:08000804FF84080808107F2200027F04410841107F22000222041788F8104060 +5F6E:10000804FF848088141022224902140422084110BEA22202220422083E102260 +5F6F:0000FF8414047F08551055227F0200047F080010FFA208022A044908A8901060 +5F70:100008047F0422081410FFA200027F0441087F1041227F020804FF8808100860 +5F71:00007F0441047F0841107F220802FFC400087F1041227F020804490888901860 +5F72:7BC200027BC44A486B504A4204027FC44A087FD04A427FC252445B88525099E0 +5F73:0800080010002000480008001000300050009000100010001000100010001000 +5F74:08400840108020FC490409041204348450449024102410041004100410281010 +5F75:08400840104022404A580A6812C8374852489268125012441244120411FC1000 +5F76:100017F82108411091101120213C6104A1042288228822502420245028882306 +5F77:08400820102023FE48800880108030FC50849084108410841104110412281410 +5F78:082009201120211049100A48124834445882908011101108120817FC12041000 +5F79:080009F01110211049100A0E140033F851089110109010A0104010A013181C06 +5F7A:0800080013FE2020482008201020302051FC9020102010201020102017FE1000 +5F7B:1000120022FC42249224122423A46E24A224222422A423242244204420942108 +5F7C:08200820102023FE4A220A24122033FC52849288124812501220145014881906 +5F7D:0808083C13E022204A200A20122033FE5220921012101212120A128A13261212 +5F7E:0840084010A020A049100A481426302053F890081010111010A0104010201020 +5F7F:08900890109023FC4894089413FC3290529093FE10921092111A111412101410 +5F80:08800840100027FC484008401040304057FC904010401040104010401FFE1000 +5F81:0800080013FE20204820082011203120513C9120112011201120112017FE1000 +5F82:080009F811082108490809F811083108510891F8110811081108110817FE1000 +5F83:082009201120212049FC0A2012203420502091FC102010201020102017FE1000 +5F84:08000BF8101020204860089811043602500093FC104010401040104017FE1000 +5F85:08400840104023FC4840084017FE3010501097FE101012101110111010501020 +5F86:08000FFE1090209048900BFC1294329452949294129C13041204120413FC1204 +5F87:08800880110021FC4A040C0413E43224522493E41224122413E4100410281010 +5F88:08000BF8120822084BF80A08120833F852449248123012201210128813061200 +5F89:09040884108820004BFE0820102031FC5020902013FE10201020102010201020 +5F8A:0800080013FC22044A040AF4129432945294929412F41204120413FC12041000 +5F8B:0840084013F820484FFE084813F83040504093F81040104017FC104010401040 +5F8C:08200840108821104BE00840108833FC5084908011F813081490106011981606 +5F8D:0820082011FC20204820082017FE30005020902011FC10201020102017FE1000 +5F8E:080009FC11042104490409FC1000300053FE9020102011FC1020102013FE1000 +5F8F:082008201120213C4920092017FE300050209124112412281410102010C01700 +5F90:1040104020A04110920815F620406040A7FC2040225022482444284421402080 +5F91:08000BFC100021244A480C9012483124500093FC104010401040104017FE1000 +5F92:0820082011FC20204820082013FE302050209120113C112012A01260143E1800 +5F93:080409041088209048000BFE102030205120913C1120112012A01260143E1800 +5F94:0888088813FE208848880840102033FC5008901010201040108011001280147E +5F95:10401040204047FC9040124821486150AFFE20E0215021502248244428422040 +5F96:0840082013FE2202480009FC1000300053FE9020112811241222142210A01040 +5F97:08000BF8120823F84A080BF8100033FC501097FE101012101110101010501020 +5F98:089008901090279E489008901090339C509090901090179E1090109010901090 +5F99:082008201120213C4920092017FE300050209120113C112012A01460183E1000 +5F9A:104010402FFE404097FC1444255464E4A44427FC20E0215022482C4620402040 +5F9B:0840084013FC20A049100A0817FE300853C892481248124813C8100810281010 +5F9C:0820092410A420A848200BFE1202320252FA928A128A128A12FA1202120A1204 +5F9D:0840084017FC204048400BF8120833F8520893F8120813F8120812081FFE1000 +5F9E:088808881088208849540A221442302050209120113C112012A01260143E1800 +5F9F:100017FC2444444495F41444244467FCA40425F42514251425F4240424142808 +5FA0:08400840104027FC48400A4812483248555490E0115011501248144418421040 +5FA1:1400140027DE4912911211122FD26112A11225D22512251A25D43E1028102010 +5FA2:1040104027FE404093F8104827FE6048A3F820402240227C2240254024FE2800 +5FA3:11101110211047FC911011102FFE6000A3F82208220823F82208220823F82208 +5FA4:08100810177C211449FE0A14127C3710517C951015FE12101210150018FE1000 +5FA5:080009FC1104210449FC0904110431FC500093FE10201120113C112012A0147E +5FA6:100017BC24844484948417BC24006400A7BC2424242427A82410242824442482 +5FA7:0840082013FE22024A020BFE1200320053FE9352155215FE1552155219521106 +5FA8:0840088013F822084BF80A0813F8300057FC9040104013F81040104017FC1000 +5FA9:0900090011FE22004DFC090411FC310451FC908010FC11081290106011981606 +5FAA:103C17E02420442097FE142025FC6504A50425FC250425FC2904290431FC2104 +5FAB:0880088013F821084FFE080013F8320853F8904017FC1040144017FE10401040 +5FAC:0840082013FC210848900BFE12023444502093FC108010F81088110811281210 +5FAD:0808083C13C020044A44092811FC3220502093FE102011241124112411FC1004 +5FAE:110815482548455097DE102420146FD4A0142794249424A824C8249428143022 +5FAF:083C0FC0124421284880091013E03040518893FC1044104017FC10A01110160E +5FB0:08000BFE1020213C4920092017FE300057FE90201120113C1120112017FE1000 +5FB1:100017FC20A047FC94A414A427FC6000A7FC20002FFE20402248244429422080 +5FB2:100017FC240447FC942014A8247064A8A50424A024FC252024202BFE28203020 +5FB3:0820082017FE204048400BFC1294329453FC904010241522150A190810F81000 +5FB4:12101A902A904AA08FBE104420246FA4A22422282FA8221022282FA820442082 +5FB5:110815482548455097DE101427E46014A7D4211427D4210821082FD420242042 +5FB6:1108110825484390911E17D425646554A554275425D4254825482554246424C2 +5FB7:104010402FFE404097FC14A424A467FCA0002FFE204020242522250A290820F8 +5FB8:08400BF8111020A04BFC080013F8324853F8924813F8104013F8104017FE1000 +5FB9:1210111027D0421094BE1FE420546794A49427942494278824882494249425A2 +5FBA:0820082011FC20204BFE0908139C31085188963E100013FE109010901112120E +5FBB:104010A023184DF6900017FC255464E4A7FC200023F8220823F8220823F82208 +5FBC:121014102F9048909FBE18A42FD46414A2142FD424142788248828942A943122 +5FBD:12101A902A904FA0803E1FC4242468A4AF24222824A83FD022282AA832442682 +5FBE:12101A902A904F90943E12242FD46014AF9420142F9420082F8828942F942022 +5FBF:0910089013DE20104A5E098213DE301053DE925013DE125013DE1250125212CE +5FC0:104017FC200043B892A813B8211067FCA11027FC21102FFE212823102D482186 +5FC1:0BF80A0813F822084BF80A4813F8344457FC90801FFE1248155418E2115016C8 +5FC2:17BC14A427BC44A497BC14A427BC6120A3FE222027FC2A2023FC222023FE2200 +5FC3:0000020001000080008004000408240424042402440244128410041003F00000 +5FC4:1000100010001000180054005000500090001000100010001000100010001000 +5FC5:00000400021001100120082028482844288449024A028C120810181027F04000 +5FC6:1000100013FC1008181054205040508090801100110012021202120211FE1000 +5FC7:104010401040104019FC54445044504490441084108410841104110412281410 +5FC8:00003FF80000000000000000FFFE000001000880088848044812481287F00000 +5FC9:1000100017FC1084188454845084508490841084110411041204120414281810 +5FCA:1000100013FE1020182054205020502090201020102010201020102010A01040 +5FCB:1000100013F8100818085408500853F892081200120012021202120211FE1000 +5FCC:00003FF0001000103FF02000200420041FFC0100088848844812481287F00000 +5FCD:00003FF802081208120824080808105060200100088848844812481287F00000 +5FCE:001000F83F0001000100FFFE0100010001000000010008844892481287F00000 +5FCF:1010107813C0104018405440504057FE90401040104010401040104010401040 +5FD0:02000200020003F8020002000200FFFE00000100088848844812481287F00000 +5FD1:0000FFFE02000240022002100208020000000100088848844812481287F00000 +5FD2:0048004400440040FFFE0040084004401440554050A050A29292120A0E060002 +5FD3:100011FC1020102018205420502053FE90201020102010201020102010201020 +5FD4:10801080110011FE1A00540051F8500890101060108011001202120211FE1000 +5FD5:1040104010401840544053FE50409040104010A010A010901110110812041402 +5FD6:10101010101010101BFE54105010501091101090109010101010101010501020 +5FD7:0100010001087FFC0100010001103FF800000A102908292C6824482407E00000 +5FD8:02000100FFFE10001000100010001FF800000100088848844812481287F00000 +5FD9:10201010101010001BFE54805080508090801080108010801080108010FE1000 +5FDA:1020102010201120192C5534516453A491241134112811221122110210FE1000 +5FDB:100011F0111011101910551051905150915011101110111211121212120E1400 +5FDC:010000803FFE2000210020802240220022002A082A042A145210421081F00000 +5FDD:00003FF801000100FFFE0280044009203118C106119011482124412405000200 +5FDE:020001007FFC0820044003800C603018C0060100088848844812481287F00000 +5FDF:10401020102013FE188854885088508890881050105010201050108811041602 +5FE0:010001003FF82108210821083FF8210801000100088848844812481287F00000 +5FE1:10201020102010201BFE5622522252229222122213FE12221020102010201020 +5FE2:00007FFC020002003FF0041004100810FFFE0000010008844892481287F00000 +5FE3:100013FC1084108818885490509C508491441144112811281210122814441182 +5FE4:10801080108011FC192056205020502093FE1020102010201020102010201020 +5FE5:100010003FFC20004FF080003FF000100810041014905050514A514A8F060002 +5FE6:1040104010A018A0551052085406911011101110111011101110121012101410 +5FE7:10901088108810801BFE54A050A050A090A010A01120112211221222121E1400 +5FE8:1000100013F818005400500057FC9120112011201120112012221222141E1800 +5FE9:04400440082010102208C44608201FF000100100088848844812481287F00000 +5FEA:102011201120191055105248524894441882108011101108120817FC12041000 +5FEB:10401040104013F8184854485048504897FE104010A010A01110111012081406 +5FEC:100013F81008191054A0504057FE904210441040104010401040104011401080 +5FED:10401020102010001BFE54405040506090501048104410441040104010401040 +5FEE:10401040104017FE18405440504057F892081208111010A0104010A011181606 +5FEF:1008103C13E012201A205620522053FE9220121012101212120A128A13061202 +5FF0:1080108013F01890549051125112924E144010401FFE10401040104010401040 +5FF1:10401040104013FC1A4454485040504090A010A010A0112011221222141E1800 +5FF2:10401040104010401BFE5440504050A090A010A0111011101288124814441802 +5FF3:10201020102013FE1820552451245124912411FC1024102010221022101E1000 +5FF4:1040104010A018A05510528854469040100013F8100810101010102010201040 +5FF5:01000100028004400A203118C1060FE000400080010008844892481287F00000 +5FF6:1000100011FC18005400500053FE90201020104010401088110413FE11021000 +5FF7:10001008110810881A5256525222522292521292130A120A120213FE10021000 +5FF8:100013F81088108818885488508857F891081108110811081108110817FE1000 +5FF9:1000100013FE1020182054205020502091FC1020102010201020102017FE1000 +5FFA:10801080108010FC1904550852405440904010A010A010901110110812041402 +5FFB:1008101C11E011001900550051FE511091101110111011101110121012101410 +5FFC:10801040104017FC1800540051F05110911011101110111211121212120E1400 +5FFD:080008001FF81248224844880888110822280410010008844892481287F00000 +5FFE:1100110011FC1A00540051F85000900013F8100810081008100A100A10061002 +5FFF:0440082010102FE8C4260420082010A060400100088848844812481287F00000 +6000:1000100017FE102018205440504050D091481244144210401040104010401040 +6001:010001007FFC0100028004400A203118C0060100088848844812481287F00000 +6002:0820082008200820145012502288208841048202010008844892481287F00000 +6003:100013FC104018405440504057FE904010A010A010A0112011221222141E1800 +6004:100013FC120012081A8856505250522092201250125012881308120013FE1000 +6005:110011081108111019205540510057FE91401120112011101108114411821100 +6006:1040104010A018A055105208540691F011101110115011201104110410FC1000 +6007:100013FE120012001A0057FC520452049204120413FC12001200120013FE1000 +6008:10481248124812481A4857FE5248524892481248127812001200120013FE1000 +6009:1080108011FC11041A0455F451145114911411F4110411281112110210FE1000 +600A:100013FC108410841884550451145208940011FC110411041104110411FC1104 +600B:100013FC120412041A0457FC5220522093FE1220122012101212128A13061202 +600C:100013FC102010201840544050D0514892441444104010401040100017FE1000 +600D:10801080108018FE554051405240907C104010401040107E1040104010401040 +600E:080008000FFC1400240047F00400040007F80400010008844892481287F00000 +600F:10401040104013F81A48564852485248924817FE104010A010A0111012081406 +6010:10801080110011FC1A04540451E451249124112411E411241004100410281010 +6011:2040224421483150A840A7FCA040A04020402FFE204020402040204020402040 +6012:10001000FEFC22844488285010202858C5860000010008844892481287F00000 +6013:21002100213E211237D2AA52A252A254A254249422882108229424A428422080 +6014:1000100013FE10201820542051205120913C1120112011201120112017FE1000 +6015:10201020104011FC190455045104510491FC1104110411041104110411FC1104 +6016:10401040104013FE188054A0512051FC93241524112411241134112810201020 +6017:104010401040187E544050405040904013FC1204120412041204120413FC1204 +6018:010001007FFC010001001FF0101010101FF00100088848844812481287F00000 +6019:10201020102010201BFE54205020502091FC1104110411041104110411FC1104 +601A:100011F811081108190855F851085108910811F8110811081108110817FE1000 +601B:1000100011FC11041904550451FC51049104110411FC11041000100013FE1000 +601C:1040104010A018A0551052485426902013F810081010111010A0104010201020 +601D:00003FF8210821083FF8210821083FF820080100088848844812481287F00000 +601E:10201020102010201BFE562252225222922213FE122212221222122213FE1202 +601F:1008103C13E012201A205620522053FE9220121012101212120A128A13261212 +6020:02000400082010103FF800081FF0101010101FF0010008844892481287F00000 +6021:10201020104018405488510453FE9002100011FC110411041104110411FC1104 +6022:102010201120112019FC55205220502093FE1020105010501088108811041202 +6023:090009001FF0210001007FFC0280044008203018C10608844892481287F00000 +6024:0810081017FE3010521091101110105010200100088848844812481287F00000 +6025:08000FE0102020405FF8000800081FF8000800083FF802005104511290120FF0 +6026:100013F8104010401A4855485150504097FE1040104010401040104010401040 +6027:102010201120112019FC552052205020902011FC102010201020102013FE1000 +6028:100010F83E884288A2A8149008841084207CC000010008844892481287F00000 +6029:100011FC11041104190455FC51005140914411481170114011421242123E1400 +602A:100017F81208111018A0544050A053189C46104017FC1040104010401FFE1000 +602B:10901090109013FC1894549453FC5290929013FE10921092111A111412101410 +602C:1000100013FE12521A5256525252525292521292128E13021202120213FE1202 +602D:1000104010201028180854885090529492A212A214C210881188128814781000 +602E:2220222022203420AD7CA924AE24A2242424242429242F242144204420942108 +602F:10401040104010401BFC54405040504097FE1040108010801110120817FC1204 +6030:10401020102013FE184054405088510893F0102010401088110413FC11041000 +6031:080008001FF812482A4844880A88110822A80410010008844892481287F00000 +6032:100013FE10201020182057FE522252229252124A128A130212021202120A1204 +6033:100013FC120412041A04560453FC5090909010901090111211121212140E1800 +6034:10281024102410201BFE56205224522492241228122812901312122A10461082 +6035:10201028102410201BFE54205070507090A810A8112412221420102010201020 +6036:10201020102013FE1A225624522053FC92841288124812501220145014881906 +6037:011001080100FFFE01001110111011102110C00E010008844892481287F00000 +6038:0120011001007FFC0380054009203118C1060000010008844892481287F00000 +6039:104010402240227863C8AE48226822522242220221FE02005104511290120FF0 +603A:10401020101019E05422503453B890B010A810A8112811241224142210A01040 +603B:10100820044000001FF01010101010101FF01010010008844892481287F00000 +603C:000800087E0802FE240814480828140822284010010008844892481287F00000 +603D:10401040104013FC18405440504057FE90E01150115012481444184210401040 +603E:1000100011FC1104190455045104510491FC1104100010901088110412021402 +603F:100017F81208111018A0544051B0564E904013F81040104017FC104010401040 +6040:1040104010FC11081A90546050485190963E1042108413481030102010C01700 +6041:08380BC01040304057FC90401040104013F80100088848844812481287F00000 +6042:10801080110011FC1A04540453E45224922413E41224122413E4100410281010 +6043:1040104010401BFC5440504057FE9010101017FE101012101110111010501020 +6044:10201020102013FE1820542051FC5000900011FC110411041104110411FC1104 +6045:10401040104419F45448505053FE904010801184129814E010821082107E1000 +6046:100017FE10801080188054F85108514891281208128810501010101017FE1000 +6047:100013FE120012001BFC5620522052F892201220122013FC1200120013FE1000 +6048:10401040109011081BFC54245120512091FC1220102017FE1020102010201020 +6049:11001104113811C01902550250FE500091FC1104110411FC1104110411FC1104 +604A:2040204023FC3084A884A114A208A01024102FBE24922492249228A22AAA3144 +604B:02000100FFFE0440145014482444444400000100088848844812481287F00000 +604C:109010901090129219945498509051989294149210901090111211121212140E +604D:10401044124419485550504057FE9090109010901090109211121112120E1400 +604E:100013FE102010401888550453FE50229020102013FE10201020102017FE1000 +604F:100010FCFE042208221064FE141008103450C220010008844892481287F00000 +6050:00007DF011101110119011501D12E212440E0800010008844892481287F00000 +6051:1040104010FC11041A0855FE5100517C914411441154114811421242123E1400 +6052:100013FE1000100019FC5504510451FC9104110411FC11041000100013FE1000 +6053:100017FE10901890549053FC5294929412941294129C13041204120413FC1204 +6054:10401020102013FE180054885104520290881088105010501020105010881306 +6055:10001000FE7C2244444434440844147C2244C000010008844892481287F00000 +6056:020004003FF8244822882108228824483FF80100088848844812481287F00000 +6057:1020102013FE10501888550452FA500093FE1040108011FC1004100410281010 +6058:109010901090191055FE53105510913811381154115411921110111011101110 +6059:082004407FFC010001003FF801000100FFFE0100088848844812481287F00000 +605A:01003FF801000100FFFE000001003FF801000100FFFE02005104511290120FF0 +605B:1000100013FC12041A0456F4529452949294129412F41204120413FC12041000 +605C:102810241024182057FE5020502097E0112011101110111011CA170A12061002 +605D:080008007F7C08243E2408247F44085408880100088848844812481287F00000 +605E:1040104017FC10401BF8544853F8524093FC1044105410A810A0111012081406 +605F:11001100110019FE56025202551298A2124A12AA131A120A13FA100210141008 +6060:10401040104013FE1880549051105110937C151011101110111011FE11001100 +6061:10081190106010981B045440504057FE90801090111011201248148419FC1084 +6062:10401040104013FE188054905090511291521154129012281428104410841102 +6063:4080208009FC12042448E04020A023182C060100088848844812481287F00000 +6064:10401040108011001BFC56945294529492941294129412941294129417FE1000 +6065:0000FF20241024103C00244024403D44254225422E42F4484448044804380400 +6066:10401040108013FC1A04560452F4529492941294129412F41204120412141208 +6067:0000FFFE020004003FF824882488248824A82010010008844892481287F00000 +6068:100013F8120812081BF85608520853F892441248123012201210128813061200 +6069:00003FF8210821082FE821082288244828283FF8010008844892481287F00000 +606A:1080108010F811081B1054A0504050A09118120615F811081108110811F81108 +606B:200027FC2404240435F4AC04A404A5F4A5142514251425F42404240424142408 +606C:1008103C11E01020182055FE50205020902011FC110411041104110411FC1104 +606D:044004403FF804400440FFFE0440082012102208C2261290124822480A000400 +606E:1040104010A011101A08540653F850409040104013F810401040104017FE1000 +606F:010002001FF010101FF010101FF010101FF01010010008844892481287F00000 +6070:1040104010A011101A08540653F85000900013F8120812081208120813F81208 +6071:10901090110811481A445492510853FC909410901090109011121112120E1400 +6072:11041084108810001BFE548850885088908817FE108810881108110812081408 +6073:00003FF020103FF020103FF0220821902C60301C010008844892481287F00000 +6074:02000100FFFE00003FF820083FF820083FF80100088848844812481287F00000 +6075:01000100FFFE01003FF821083FF821083FF80000010008844892481287F00000 +6076:00007FFC04402448144814500440FFFE00000100088848844812481287F00000 +6077:08400840104037FC50E091501150124814441842104002005104511290120FF0 +6078:2010201027903010A87EA012AFD2A21222122422252228A22FC2204220942108 +6079:100013FE122012281A24562053FE522092201250125012501488148819041202 +607A:102011241124112419FC540051FC5004900411FC110011001102110210FE1000 +607B:200427C4244424543554AD54A554A554A5542554255421042284224424142808 +607C:10401020102017FE180054005090525492241224125412941204120413FC1004 +607D:100013FE12021C44544053FC508090A0112011FC1020102017FE102010201020 +607E:1090109017FE109018905440502057FE91001100110011001100110011FC1000 +607F:3FF0066001803FF821083FF821083FF821082018010008844892481287F00000 +6080:100013FC100818D0542053FE5222922213FE1222122213FE12221222122A1204 +6081:100011F81108110819F8540053FC5204920413FC1204120413FC120412141208 +6082:12201224122813B01A20562252A2531E9040104013FC10401040104017FE1000 +6083:200027FC244424443444AFFCA444A4C4A4E42554264424442444240427FC2404 +6084:1020112410A410A8182055FC5104510491FC1104110411FC1104110411141108 +6085:10101090108811081A0455FA51085108910811F810901090109011121212140E +6086:010002800C603018CFE601003FF8111025080200010008844892481287F00000 +6087:1040104010A011101A0855F65040504097FC1040125012481444184411401080 +6088:10101014101210101BFE54105150515497F4115411541148124A125A14261042 +6089:00F83F00111009200100FFFE092011102108C006010008844892481287F00000 +608A:080C08F07E8008800EFE78880888290812080100088848844812481287F00000 +608B:1040102017FE11081890546050605198960611F8110811081108110811F81108 +608C:11081088109013FC1824542453FC5220922013FE106210A2112A122414201020 +608D:100011FC110411FC190455FC5000500091FC1020102013FE1020102010201020 +608E:10201120112011FE1A205420502053FE9000100011FC11041104110411FC1104 +608F:10201020102013FE1820542051245124912412AA102010501050108811041202 +6090:4420282010A428A448A8992028204850885008885104220201004884481287F2 +6091:1048104413FE1840544053FC5244924413FC1244124413FC1244124412541208 +6092:100011F81108110819F8540053FC52449244124413FC12001202120211FE1000 +6093:100013F8120812081BF85608520853F89208120813F81120112012221422181E +6094:1100110011FC1A0055F851085148912817FE11081248122813FC100810501020 +6095:2208211020E03110AA08A080AFFEA140224027FC2A4422442254224820402040 +6096:1020102013FE1820542053FE5202940411F81010102013FE1020102010A01040 +6097:1080108011F81A08541053FC52449244124413FC10A010A011221122121E1400 +6098:00003FF8240027F028803FFC2140222024103FFC010008844892481287F00000 +6099:1040102013FE100019F85508510851F8900013FC100810301020102010A01040 +609A:1020102013FE1020182055FC5124512491FC1020107010A81124122210201020 +609B:10401040108811041BFE540250885144924210F8118812501020105011881606 +609C:100011FC11041104190455FC5000500093FE1020102011FC1020102013FE1000 +609D:200027FC2444244437FCAC44A444A7FCA040204027FC2040204020402FFE2000 +609E:100010F8108810881AF85600520053FC9044104417FE104010A0111012081406 +609F:100013FE1040104019FC5484508453FE9000100011FC11041104110411FC1104 +60A0:10401040247E6488A54824502420205820862300010008844892481287F00000 +60A1:0604780408440844FF441C442A44490488140808010008844892481287F00000 +60A2:1080104013F812081A0857F85208520893F81240124412281210128813061200 +60A3:01001FF0111011101FF001003FF8210821083FF8010002005104511290120FF0 +60A4:020004003FF8220823C824482A882108228824083FF8200801004884481287F2 +60A5:02000100FFFE00003FF800003FF800003FF820083FF802005104511290120FF0 +60A6:12081108111010201BF856085208520893F810A010A0112011221222141E1800 +60A7:108411C4170411141914551457D4511493141394155415041904110411141108 +60A8:0900090011FC3204544899501148124414441140108002005104511290120FF0 +60A9:104212221124110418085400520A528A925212221252128A130A120213FE1002 +60AA:00007FFC04403FF8244824483FF80440FFFE0100088848844812481287F00000 +60AB:01007FFC01003FF800007FFE40028FE4082010222022C11E288828A4482407E0 +60AC:1FF010101FF010101FF01010FFFE082010103FF810080100288828A4482407E0 +60AD:108012FC12A412A41AA8569052A850C69020102011FC10201020102013FE1000 +60AE:200023F82208220833F8A800A000A7FCA04020402FFE204020A0211022082C06 +60AF:110010BE128212021A42562253FE5292925212221252128A130A1202120A1204 +60B0:1040102013FE1202180055FC5000500093FE1020112811241222142210A01040 +60B1:109010901090179E189054905090539C909010901090179E1090109010901090 +60B2:044004407C7C044004403C78044004407C7C0440010008844892481287F00000 +60B3:00803FFE008007F8240827F8240827F8240827F820003FFE01004884481287F2 +60B4:1080104013FC18005510511052A894441000104017FE10401040104010401040 +60B5:100010FC108018F8548050F8508097FE11401124112811101108114411821100 +60B6:00007C7C44447C7C44447C7C42044104450454245454645443C4400440144008 +60B7:1040102013FC12041A0457FC52005228922413FE122012501250148815041A02 +60B8:203823C0204027FC30E0A950A248AC46A3F02020204027FC2040204021402080 +60B9:01007FFE40029FE410201FE010001FF0101010101FF002005104511290120FF0 +60BA:1040102013FE1A02540451F85108910811F81100110011FC1104110411FC1104 +60BB:1020102013FE1020182057FE5088505093FE1020102017FE1020102010201020 +60BC:10401040107E10401BFC560453FC520493FC1244104017FE1040104010401040 +60BD:1040104017FC10401BF8544857FE504893F8108017FE11081390106011981604 +60BE:10401020102013FE1A02549451085204900011FC102010201020102017FE1000 +60BF:100013FC104010401BFE54A05110520894461040104812641252145211401080 +60C0:2040204020A03110AA08ADF6A000A7FC24A424A427FC24A424A424A424142408 +60C1:080C08F07E8018802CFE2A884888888809080100088848844812481287F00000 +60C2:1080108010F811081A1054005040539C92041204139C12041204120413FC1204 +60C3:100013FC120412041BFC5604520453FC90001220122413A81230122212A2131E +60C4:08000F7C08440844FF4808282A30491089282844108202005104511290120FF0 +60C5:1020102013FE102051FC582057FF940011FC110411FC110411FC11041114110C +60C6:100013FE122212221AFA5622522253FE920212FA128A128A12FA1202120A1404 +60C7:1040102013FE100019FC550451FC500091FC1008101013FE1020102010A01040 +60C8:100013F8124812481BF85648524853F8904017FC10E011501248144610401040 +60C9:10400840407E2040084013FC7204120413FC1000010008844892481287F00000 +60CA:1040102013FE1000180055FC5104510491FC1020112811241222142210A01040 +60CB:1040102013FE12021D04550051DE525292521352149A1094111011121212140E +60CC:020001007FFE400290041EF8228824A8549008841084607C01004884481287F2 +60CD:1040104010A011101A08540651F05040904013F8104012481148115017FC1000 +60CE:08207FFC08200FE008200FE00820FFFE10102208C10609002828282447E40000 +60CF:211021102110211037BCA910A110A338A3B82554255429922110211021102110 +60D0:10141012101017FE1810541053D252529252125413D4100810EA171A12261042 +60D1:00500048FFFE00403E4022243E2800120E2A70C603020100288828A4482407E0 +60D2:0600787C08440844FF441C442A44497C88440800010008844892481287F00000 +60D3:1020112410A81BFE5440508057FE9108120415FA1908110811281112110210FE +60D4:104012441244144818A0551056085044904012481248145010A0111012081C06 +60D5:100011FC110411FC190455FC5080508091FE124A144A10921122124210941108 +60D6:1FF010101FF010101FF008001FF82248448809081228241001004884481287F2 +60D7:2040204020A03110AA88A446A800A3F020102020204021242522250A290820F8 +60D8:100013FE1202128A1A5257FE5242522293FE12821282128212FA1202120A1204 +60D9:200027BC208422943108AA94A4A4A840A00027BC20A422A42128229024A82846 +60DA:1080108010FC11541A5454A45124524490941108104010A412AA128A14781000 +60DB:101C13E0122013FE1A205692530A520691FC1104110411FC1104110411FC1104 +60DC:10881088108813FE1888548857FE500091FC1104110411FC1104110411FC1104 +60DD:1020112410A410A8182057FE5202520292FA128A128A128A12FA1202120A1204 +60DE:201020902710243E3422AC44A790A510A5102510252825282528294429443082 +60DF:10A01090108011FE1910571055FC5110911011FC11101110111011FE11001100 +60E0:010001007FFC01003FF821083FF821083FF80104FFFE0102288828A4482407E0 +60E1:00007FFC04403C78200820083C780440FFFE0000010008844892481287F00000 +60E2:01000080088848044812481287F00000101008082220A124A4A2A4A41D1C0000 +60E3:108050807CFC515492541CA4F124124410941108010008844892481287F00000 +60E4:10101388108810FE1890579052245224923813881090109010A410BE12821100 +60E5:01000500397821083D7821083FF8028004401830E10E08844892481287F00000 +60E6:1040102013FE12001A205620523E5220922012FC128412841284148414FC1884 +60E7:100013F8120812081BF8560853F8520893F8120812081FFE1000111012081404 +60E8:20802090210833FCA840A7FEA110A2482C862310202020C42308203020C02700 +60E9:100023FE40208920113C31205120912017FE1000010008844892481287F00000 +60EA:01007FFC01001FF010101FF010101FF010101FF01010FFFE01004884481287F2 +60EB:08000FF010202C4003801C70E00E1FF011101FF011101FF001004884481287F2 +60EC:200027FE2420242035FCAC20A524A4A8A7FE2420245024482484250427FE2000 +60ED:21002102211C2FD03210AA10A51EA7D4A114211421D42F142514212421242144 +60EE:11041088105011FC1924552451FC5124912411FC1020102013FE102010201020 +60EF:11FC1124112413FE1924552451FC500091FC1104112411241124105810841302 +60F0:1040104013FE108019FC562055FE500091FC110411FC110411FC110411141108 +60F1:109211241248112418925440508053FE9202128A125212221252128A13FE1202 +60F2:100013FE122210201BFE542051FC512491FC112411FC102013FE102010201020 +60F3:080008F808887E8808F818881CF82A88488808F8010008844892481287F00000 +60F4:2040244424443444AFFCA000AFFEA040208027FC24A424A424A424A424A4240C +60F5:10901290129017FE1A90569052F0520093FC104017FE10E0115012481C461040 +60F6:1020104011FC110419FC550451FC500093FE1020102011FC1020102013FE1000 +60F7:01007FFC01003FF80200FFFE08201FF02828CFE608200FE001004884481287F2 +60F8:110011FE120215F2191255F2511251FA900413F81010102017FE102010A01040 +60F9:08207FFC08200200FFFE08001FF02810C8100FF0010008844892481287F00000 +60FA:100011FC110411FC190455FC5020512091FE1220102011FC1020102013FE1000 +60FB:200227C22442245237D2AC52A452A7D2A452245227D2200222822242244A2804 +60FC:1040102013FE12021A0257FE5200520093FE1352155215FE1552155219521106 +60FD:100013FC120413FC1A2057FE5210528A9306100013FC120413FC120413FC1204 +60FE:10001088125212221A52568A520253FE90881144127A10881150102010D81706 +60FF:100011FC1104110419FC5504510451FC900013FE10201120113C112012A0147E +6100:208821C827083108A92AA12AA7ACA14823082388255425142914212421242142 +6101:0E207820082408A4FEA819202C504A50888809040A020100288828A4482407E0 +6102:08107F1008107F7E41123E1204120F1278220822284A108401004884481287F2 +6103:1040102013FE1A02540451FC500091FC110411FC110411FC1104100013FE1000 +6104:100013F8124812481BF85648524853F8900017FE124012441228129013081206 +6105:2110211027FC211031F0A840A3F8A248A24823F820402FFE2040204020402040 +6106:1200213C48009400217E6208AE08220822282210210008844892481287F00000 +6107:1040104011FC10841BFE540051FC510491FC102013FE1020122013FE10201020 +6108:010002800C6037D8C0063E0822483E4822483E482208261801004884481287F2 +6109:104010A0111012081DF6540053C45254925413D41254125413D41244125412C8 +610A:100013FE100011FC1904550451FC500093FE1222122213FE1222122213FE1202 +610B:103C17C012441928540053FC5080908017FE110011F812881250142018D81306 +610C:1080108010F811081A1055FC51045154918C1124102013FE1050108811041602 +610D:00207F20413E7F4448A47F244828451053286146010008844892481287F00000 +610E:1100110011FE1A0055FC510451FC910411FC108010FC11081290106011981606 +610F:01003FF808200440FFFE00001FF010101FF010101FF002005104511290120FF0 +6110:100017FE104010801BFC5694529452F49294129412F412941294129413FC1204 +6111:100013FC108810501BFE562253FE522293FE1222104013FE1042108211141208 +6112:100013F812081BF8560853F8510093FC1444124412A4120413F4100410281010 +6113:200023F8220833F8AA08A3F8A000AFFE220023FC249429242244248421282210 +6114:2080204027FC3000AA08A110AFFEA00023F82208220823F82208220823F82208 +6115:200027BC24A424A437BCA800A3F8A000A7FC2100220023F82008200820502020 +6116:1110111017FC111019F0551051F05110911017FE120012901308120013FC1000 +6117:00407F40127E0C88FF4819482A504820A850108C010008844892481287F00000 +6118:1040102013FE1202188054F85108529090601198160611F81108110811F81108 +6119:020001007FFE48029FF4282007C01830E00E1FF010101FF001004884481287F2 +611A:1FF011101FF011101FF001003FF8210821482FE82428201001004884481287F2 +611B:007C3F80110808907FFE41029494142823E808000FF01420224041800E60701C +611C:200027FE2420242035FCAC20A4A8A4A8A5742420245024482484250027FE2000 +611D:100013FE120012FC1A8456FC528452FC922013FE124812C812301248128413FE +611E:100013FE102010401BFE56525252525292421226102017FE1050108811041602 +611F:002800243FFE20202FA420242FA8289828924FAA4046808201004884481287F2 +6120:100011F81108110819F85508510851F8900013FC129412941294129417FE1000 +6121:1080108010FC11541AD454B4512C524490941108104010A412AA128A14781000 +6122:100013FC124412441BFC5644524453FC9000104010241522150A190810F81000 +6123:100013FC12941A94569453FC5080904017FE108010F810881108110812281410 +6124:102011FC102010881BFE5488500051FC91041124112411241124105010881304 +6125:2110211027FC21103150A840A3F8A248A24822482FFE204020A0211022082406 +6126:1020102011FC192455FC502053FE900011FC1104112411241124105010881304 +6127:2040208027FC24443444AFFCA444A484A7FC208021502164227C24422842303E +6128:08007F7808483E4800867F78414800303ECE0000010008844892481287F00000 +6129:100011FC102010201BFE540051FC510491FC110411FC110411FC108811041202 +612A:100011F81108110819F8540053FC520493FC120413FC120413FC109011081204 +612B:1040104017FC10401BF8544057FE5080911013E0104817FC1044124815441080 +612C:2200147CFF44087C4944497C7F44084410942108410008844892481287F00000 +612D:1040104411F810501BFE544050F85182927E140011FC110411FC110411FC1104 +612E:1008103C13C010041A44552851FC5220902013FE102011241124112411FC1004 +612F:10A0109011FE1B2055FC512051FC912011FE110013F811081090106011981606 +6130:100011FC110411FC190455FC5020512490A8102013FE1090109011121212140E +6131:1020101011FE190055205120553C93501190131015FE11101128122812441482 +6132:100011F8110811E8192857FE540251F8910811F8110811F81108110811281110 +6133:00003E7C22443E7C22443E7C22443E7C00000100088848844812481287F00000 +6134:10201020105018C8552453FE550491FC110411FC110011FC1284128414FC1084 +6135:100013DE104210421BDE5610521053DE90421252114A114A1252104212941108 +6136:104011FC10441094190857DE514A514A929411FC110411FC110411FC1104110C +6137:1040124812481A4857F8500057FC900013F81208120813F8111010A017FE1000 +6138:082008207F7C2A242A245D2408241C442A944808010008844892481287F00000 +6139:2040202023FE22023494A908A264A090A108220425FA21082108210821F82108 +613A:1088108813FE1088180055FC510451FC910411FC1124102013FE102010201020 +613B:000C7DF00440088811F010201C44F3FE102211245222206001004884481287F2 +613C:120C13F2120219FE540051FC550495FC150415FC150415FC140017FE11041202 +613D:1028102413FE102019FC552451FC512491FC1124100813FE1088104810481018 +613E:1100110011FC1A0055F8500053F8908812A811C817F8108A11CA16AA10861082 +613F:00003FFE208027F8240827F8240827F8225024482944208020444A424A1291F0 +6140:103C17C0124419285480511053E09040118813FC1044104017FC10A01110160E +6141:3FF820082FF822082D2822C82DA822982D8820083FF802005104511290120FF0 +6142:200017F8911040A047FC144427FCE44427FC244424040100288828A4482407E0 +6143:2120211022083486A910A3F8A008A00027BC208424A4229424A4208422942108 +6144:200027FC20A020A037FCACA4A4A4A7FCA040204027FC20E0215022482C462040 +6145:100013F81148111018A0544051B0564E904013F81248124813F8104417FC1004 +6146:103C13C010441224192855005040539C92041204139C12041204120413FC1204 +6147:0600387820483E4822863E0022FC3E4420283E1022284A4685004884481287F2 +6148:08200440FFFE10201020244878F0102024487EFC02040100288828A4482407E0 +6149:2080204027FC20803108ABF0A060A184A7FE200227FC244427FC244427FC2404 +614A:211020A0200027FE30A0ABF8A0A8A7FEA0A823F820A021B022A82CA620A020A0 +614B:108024987EE000847E7C42007E9842E07E844284467C02005104511290120FF0 +614C:2108210827FE21483020AFFEA200A200A3FC2000224822482248244A244A2846 +614D:200023F8224822A83318AA08A3F8A000A00027FC24A424A424A424A42FFE2000 +614E:2040204027FC204033F8AA08A3F8A208A3F8220823F822082FFE211022082404 +614F:100013FE1202100019FC550451FC510491FC1040102013FE1000108811041202 +6150:3FF801007FFC00001FF010101FF010101FF010101FF0082011104884481287F2 +6151:200023FC210821F83108A9F8A10EA7F8A00827BC20A422A42128229024A82846 +6152:1050105013FE10501BFE565253FE525293FE100011FC110411FC110411FC1104 +6153:20002FFE20A027FC34A4ACA4A7FCA000A7FC20002FFE20402248244429422080 +6154:2110211027FC21103000ABF8A208A3F8A20823F8204027FC20A0211022082C06 +6155:04407FFC04401FF010101FF010101FF00400FFFE12102208CB2612902A900400 +6156:200027FE242A242637FEAC22A7AAA6AAA7AA24322596262E2446248227FE2402 +6157:08200820FFBE08447FA449247F281C282A1049288844088201004884481287F2 +6158:2080211023F8221034A4AFBEA042A0A0A3182C46219026642188263021C02E00 +6159:08047F7808407F40497E7F4849487F4808487F48088802005104511290120FF0 +615A:22002202223C2FA03220AFA0AABEAFA4AAA42FA422242FA42224224422442284 +615B:1020122213FE1090188855FE5310551091FE1110111011FE1110111011FE1100 +615C:20203FA0403EBF4429A425247FE8292845107FA8014402825104511290120FF0 +615D:3FFC24202FF825203FFC220027F02A1033F020003FFC02005104511290120FF0 +615E:102011FC108810501BFE540051FC510491FC110411FC102013FE102010201020 +615F:21C8270821082FE8311EAFCAA54AA7CAA54A27CA210A27CA211221D22E2A2444 +6160:21082108210827D0311EAF94A124AFD4A21423D422542248224824D424242842 +6161:2040204027FC20403554AA48A554A040A5542248255420A020A0211022082C06 +6162:23F8220823F83208ABF8A000A7FCA4A424A427FC200023F8211020E023182C06 +6163:100011FC112413FE192455FC500051FC910411FC110411FC110411FC10881104 +6164:08787F4808483E8600787F4841489C2815102628404602005104511290120FF0 +6165:10101450127C1290181054FE50005600927C12441244127C1244150018FE1000 +6166:0A2009207FBE08446AA41C242A28491028281046010008844892481287F00000 +6167:1010FEFE10107C7C1010FEFE10103FF800081FF800083FF801004884481287F2 +6168:200027BE2488248837A8ACA8A4A8A7BEA4102518249825A826AA244A20462080 +6169:2010241022FE3210A8FEA092A6FEA29222FE221022FE22102210251028FE2000 +616A:100013FE1200127C1A445644527C520092EE12AA12AA12AA12EE120013FE1000 +616B:1110211041108AA814443240527C9240154018FE110008844892481287F00000 +616C:1088108813FE108818F8542051FC512491FC102013FE102011FC102013FE1000 +616D:081408127F104AFE2C10FF101C282A2849448882010008844892481287F00000 +616E:010001FC01003FFE21022FF4210027F8244827F8244827F820804A44521281F0 +616F:110011FC120015F8190855F8510851F8900017FE110013FC14A4112412541088 +6170:3F0821083F7E20082F4820285FA8440895282C90010008844892481287F00000 +6171:102013FE102011FC192455FC512451FC902213FE100813FE1108108810281010 +6172:1088108813FE1088188854F8502053FE9222133212AA137612221222122A1224 +6173:200027DC251427D43454AFC8A508A514A7E22000204027FC204020402FFE2000 +6174:100013DE10421252194A56525042502091FC1104110411FC1104110411FC1104 +6175:202027FE242025FC3424AFFEA424A5FCA42025FC252425FC252429FC2924312C +6176:00803FFE22203FFC22243FFC20003FFE20822A5431F2220027F84A0841F09E0E +6177:2040202027FE242035FCAC24A7FEA424A5FC2420256224B429282A2630A02040 +6178:145014507FFC245247CE80007FFC41041FF011101150112001004884481287F2 +6179:10407C4011F8FE48444828C87C68109AFE8A1106120202005104511290120FF0 +617A:204023F822482FFE3248ABF8A040A3F8A24823F820802FFE211020E023182C04 +617B:10401248115013F8188057FC5110520897FC1A0A13F8120813F8120813F81208 +617C:002800243FFE2220232422242FA822282A92522A46468102288828A4482407E0 +617D:20142012201027FE3410AC90A4D2A492A7F22494249425C82AAA289A31A62042 +617E:14202220493E144222944110BE28222822443E82010008844892481287F00000 +617F:43FE222023FC0A200BFC1220E3FE212227FA2122022602005104511290120FF0 +6180:100017BC108414A41A9454A450505188962610C0131010641388103010C01700 +6181:1040108013FC12441AF4571452A4524492A413FC104010241522150A190810F8 +6182:7FFC02001FF010101FF010107FFE41029494142823E808001FF0682007C0F83E +6183:01007FFC01003FF80200FFFE08203CF8D0161CF010101FF001004884481287F2 +6184:104027FC40408BF8120833F8520893F8120813F8120817FE01004884481287F2 +6185:7F200820FF2008FC7F2449247F2449247F2408447F440894FF08020851249FE4 +6186:1020112410A813FE1A0254F85088508890F81020102011FC1020102013FE1000 +6187:0688388809FE7E88088808F83E88228822883EF8010008844892481287F00000 +6188:1040107C104013FE1A42567853C4523C920012501254135414D8145019FE1000 +6189:1082108217F41088188057E2500253E49228122013E012221142107417881210 +618A:111017FC21102FFE6100A3F826482BF8224823F82248225801004884481287F2 +618B:082049202A3E7F4449A45D286B28491049284346010008844892481287F00000 +618C:08401440227C5C8489443E2C08144A2428C40E28701022005104511290120FF0 +618D:203823C0208027FE3110AA08A5F6A910A1F0200027FC240425F4251425F4240C +618E:11041088100013FE1A2256AA5272522293FE100011FC110411FC110411FC1104 +618F:2100211023DC22543554AA88A108A2F4A402200023FC20402150224825442080 +6190:20402248215027FC3150AA48A444A208A20823BE24882AA8213E220824082808 +6191:43FC22400BF80A4013F82240E3FC200425542008010008844892481287F00000 +6192:104013F8124813F8184057FE500053F8920813F8120813F8120813F811101208 +6193:204020402FFE204037FCAC44A7FCA444A7FC20442FFE204220242522250A28F8 +6194:2140212023FE22203620ABFCA220A220A3FC2220222023FE2200252424922892 +6195:202027A420A822923114AA08A5F4A802A3F82208220823F8220821102FFE2000 +6196:081408127F102AFE2A105D101C282A2849448882010008844892481287F00000 +6197:082008207F3E2A442AA45D2408281C102A284846010008844892481287F00000 +6198:102013FE102019FC540051FC510491FC108817FE100011FC1104110411FC1104 +6199:01007FFC01003FF800003FF820083FF80820FFFE20083FF801004884481287F2 +619A:100013DE125212521BDE540051FC512491FC112411FC102013FE102010201020 +619B:100013FE10501BFE565253FE500091FC110411FC110411FC102013FE10201020 +619C:2020272025FE2540357CAE90A57EA500A57C2544257C2644247C24442444244C +619D:08407F40007E3E8823483E4800503E5004207F500888290411004884481287F2 +619E:221021102FD0201037BEACA4A7D4A014A7942094211421C82F08211425142222 +619F:200027FC20A020A037FCACA4A4A4A7FCA248215027FC20E0215022482C462040 +61A0:3FFE289025102FBE22222AD42A902F90222844284444888201004884481287F2 +61A1:1210121013DE152818A4542053FE502093FE1222122A127410A8112416221020 +61A2:1020102011FC10201BFE5508539C51089188163E100013FE109010901112120E +61A3:103C13E0112410A81BFE54A85124520291FC1124112411FC1124112411FC1104 +61A4:102011FC102010881BFE548851FC510491FC110411FC110411FC108811041202 +61A5:08202AA80820145022887FFC400402003FF804080850302001004884481287F2 +61A6:108812AA12DC148819545622500053FE9242144413FC10441044108411141208 +61A7:102011FC108810501BFE540051FC512491FC112411FC102011FC102013FE1000 +61A8:7C200420FF3E22443EA422283E282390FE28424402820100288828A4482407E0 +61A9:1C10702010FCFE8410FC7C8444FC44847CFC4400010008844892481287F00000 +61AA:279E2492279E2492379EAC02A4F2A492A4F2249224F224922492253224022406 +61AB:200027BC24A427BC34A4AFBCA484A444A5F4242424A4244424A4250424142408 +61AC:100013F812081BF8560853F8504097FE100013F8120813F810401248144410C0 +61AD:2040204027FC20A03514AA08A7FCAA0AA3F8220823F820402248244429442080 +61AE:2100210023FC36A8AAA8A2A8A7FCA2A822A822A82FFE200022A8225424542000 +61AF:200027BC2108252837BCAB18A5AAA946A00023F82208220823F82208220823F8 +61B0:100013FC104810301BFE545250945350902013FE1252128A1376125212721206 +61B1:221421122FD22010307EAF90A490A490A790212825A825682928214A254A2286 +61B2:01007FFC41043FF801001FF00100FFFE01003FF824483FF801004884481287F2 +61B3:100013FC100413FC180457FC500053BC912417BC100813FE1108108810A81010 +61B4:200027FC24A424A437BCA8A0A7BCA4A4A4A427BC24A424A427BC24A220A2207E +61B5:00407C2045FC44887C5043FE7C20A5FC24203C20010008844892481287F00000 +61B6:1080104013FC1908549057FE500093FC120413FC120413FC10401524150A18FA +61B7:2110211027BC3110ABB8A554A912A00027FC2044224022782240254028FE3000 +61B8:2040204020A03110AA08A5F6A800A7BC24A424A427BC22102210252829443082 +61B9:109013FC12941BFC569453FC500093FC120012F8120013FE1520151415481986 +61BA:110011F8120817FE1A88572453FE520092FC120012FC120012FC148414FC1884 +61BB:102017FE100013FE1A0256FA528A53FE900011FC110411FC110411FC100017FE +61BC:2220FFA0223E20447FA481287D2845107D280A44048202005104511290120FF0 +61BD:21102FFE21103200ABFCA4A4ABA4A164225424942108204020242522250A28F8 +61BE:2014201227FE241035D0AC14A5D4A558A5CA24162442282422A2228A24782000 +61BF:2108220827C8245037DEAC64A7D4A214A11427D4221423C822482454255428A2 +61C0:204020A023182DF63000AFFCA554A4E4A7FC200023F8220823F8220823F82208 +61C1:200023FC22943294ABFCA000A7FEA00023FC220423FC20A2211423082D442182 +61C2:211027FE211023F83040AFFCA040A3F8A24823F8224823F8204027FC20402FFE +61C3:2220FFA022203EFC08247F2449247F2408247F440854FF8801004884481287F2 +61C4:228822882FE8228833BEA90AA7CAA54AA7CA210A27CA210A27D2211221EA2E44 +61C5:1040107C104013FE1A42567853C4523C920013FE124013A4125815B4145219B0 +61C6:23F82208220833F8A800A7BCA4A4A4A427BC20402FFE21602250244838462040 +61C7:0600F8FC4A8424FC3884CCFC36A2CA9412A86AC4048202005104511290120FF0 +61C8:2200239E248A290A37D2AD66A540A7D4A55E256427C42544255E2544244428C4 +61C9:010000803FFE224824FE2D9034FC249024FC249024FE24804244524A920A21F8 +61CA:2080210027FC24443554AC44A7FCA4E4A554240420402FFE20A0211022082C06 +61CB:27882088FABE210877D86B5CA52A294825082208010008844892481287F00000 +61CC:200027FC24A427FC3040ABF8A040A7FCA11020A023F820402FFE204020402040 +61CD:20402FFE200027FC3404ADF4A514A5F4A40427FC200823F020402FFE21502E4E +61CE:2040204027FC3248AA48A554AFFEA00027FC240425F4251425F4240427FC2404 +61CF:10A0109011FE132019FC552051FC512091FE110013DE12521252127212021206 +61D0:1040102013FE100019FC5554515451FC902013FE10501094118812A814C41082 +61D1:01104FFE211027FC80A047FC54A414A4E56426542484240C01004884481287F2 +61D2:221022102F9C22243248AFBEAAA2AAAAAFAA222A272A2AAA3288221422222242 +61D3:103C13C010441224190857FE544252A4928A147A108010F8110812901060179E +61D4:20402FFE200037FCAC04A5F4A514A5F4240427FC200023F820002FFE224824C4 +61D5:00003FFE288C2F8A28882FBE20082F8828882F94289429A2408042408A1411F2 +61D6:080C147022105C1088FE3E1008104A7C28440E44707C22005104511290120FF0 +61D7:21102110211037BCA910A110AFFEA2A822A826EC2AAA22AA22A825A824482898 +61D8:42A827FC22AA84E6400057FC1444E3F822482258214008844892481287F00000 +61D9:1140124C126412441B4C566452A453AC92A412A417FE10001110110812041404 +61DA:203E27C02244212833F8A840A7FCA000A3F8200823F8200823F82544252A28FA +61DB:20402FFE204027FC3000ABF8A208AFFEA80227FC211023F8204027FC20402FFE +61DC:1088108813FE10881BFE565253FE500093FE124210F811081290106010C01700 +61DD:2400257C260434A8AB90A07CA414A7942A5022502FDC2250255024B0289E2100 +61DE:108813FE108813FE1A0255FC500053FE904010A2135410B81354109213501020 +61DF:140855083608147E7F0814487F2808283E0808080F28781021004884481287F2 +61E0:2080204027FC211030A4AF58A554A552AB582000220823F8220823F822082408 +61E1:2040202027FE248837DEAC88A5DCA6AAA4882440249025202448248425FC2884 +61E2:201027D0251027DE3450AFE8A504A7C4A00023F822A822A822A822A82FFE2000 +61E3:011047FC211081F0404017FC1664E55426EC2444244C02005104511290120FF0 +61E4:204027FC204033FCA800A7FEA002A3F8204027FE200027FE200827FE24A82798 +61E5:204027FC204027FE3402ABFCA248A3F8A24823F8200027FC22442278254028FE +61E6:200027FC20402FFE3842AB58A040A358A0002FFE204027FC24A424A424A4240C +61E7:2080204027FC244432A8AA94A474A000A3F822A82FFE200027FC204021402080 +61E8:20002FFE28082BC83A4CABCAAA48ABDEA8082BC82A482BD42A542BD42A5432E2 +61E9:2208211027FC3040ABF8A080A7FCA14823FC260A2BF8220823FA2234228C2302 +61EA:23F8220823F8220833F8A910A7FCA110AFFE21102248255420E02150224820C0 +61EB:1042139C12101BDE56945294542093FC120413FC120413FC120413FC11081204 +61EC:00803FFE22202FF822203FFC20802FF828882FF828882FF842205494924A23FA +61ED:2040202027FE248835FCAC88A7FEA420A5FC252425FC252425FC240024882904 +61EE:27FC208023F83208ABF8A208AFFEA8822548251428F4210023F8250820F02F0E +61EF:0A20FFA0493E7F4449A451240828FF2820103E284244868201004884481287F2 +61F0:220225E224A226AA352AAE6AA10AA28AA44A2BAA210A27CA2122254221EA2E04 +61F1:110817FE110810001BFC5694529453FC902813FE1220132412A81292142A18C6 +61F2:22204AA08ABE1FC420A46F24A0282FA822102FA822442F8201004884481287F2 +61F3:108813DE108819DC548853DE508893FC100411FC100413FC104012A4128A147A +61F4:2114211227D23110A910A7FEA290A6D2229226D2229426D4228A22CA2F162022 +61F5:110817FE110813FC1A9457FC500057FE940211F8110811F8110811F8110811F8 +61F6:2108210827CE21123124AFDEA552A55EA7D2211E2392255E2940211421122122 +61F7:208020402FFE200037FCACA4A7FCA248A1502208244420A8211023082D462180 +61F8:3E0E22F03E2022443EF822103E2422FE7F1008542A92595001204884481287F2 +61F9:204027FC200023B832A8ABB8A110A7FCA11027FC21102FFE212823102D482186 +61FA:2448244C2AAA3008AFFEA288AEE8A28A2EEA228C2EEC228822EA2F1A24262042 +61FB:109413981092118E1A8055FC512451FC912411FC108811FC108813FE10881104 +61FC:27BC24A427BC24A437BCACA4A7BCA120A3FE222027FC2A2023FC222023FE2200 +61FD:21102FFE211027BC34A4AFBCA140A120A3FE222027FC2A2023FC222023FE2200 +61FE:13FC110811F8190855F8510E57F8900817FE1294139C1294139C12D617BC1084 +61FF:1020FF2010BE7C440050FE9083907CA800A47CC244207C1045542F42F14A4238 +6200:210447C88812F3BC20084B92F83E0380AAAAABAA010008844892481287F00000 +6201:2850FE4828FE399012907CFE54907C9010FE7C901090FEFE28804504249243F0 +6202:202027FE248827DE3488ADDCA6AAA488A45027DE245025DC24502BDE28503050 +6203:2248215027FC240431F0A910A7FCA554A4E427FC204027FC20402FFE22A42452 +6204:13DE125213DE12521BDE54A051FE532095FC112011FE100011FC10881070178E +6205:1000FEF82820FEFC00007CF844887CF844887CF81088FEF81050020851249FE4 +6206:1040FEF82948FE3001CE7CF844207DFC44887CA810A8FE5011884884481287F2 +6207:1040FEF82948FE3001CE7CF844207DFC44887CF81088FEF81050028851249FE4 +6208:022002100210020002FEFF0002080208021001200140008003420C22701A0006 +6209:00900088008800807FFE408040804088408840904060484450A46114420C0404 +620A:0090008800803FFE208020802084204420482048203020222052408A43068C02 +620B:02400220022002FC7F0002000200023EFFC002100120014001840E447034000C +620C:0050004800403FFE20402040204420443E442028202820122032404A40868102 +620D:0050004800403FFE204020402044304428442428242820122032404A40868102 +620E:004800440040FFFE00400840084408447F440828082810121032204A40860302 +620F:0020002800247E240220023E25E0142408240828142812102232404A00860102 +6210:0050004800403FFE2040204020443E4422442228222822122A32444A40868102 +6211:04400E50784808480840FFFE084008440A440C48183068220852088A2B061002 +6212:004800440040FFFE00401240124412447F441228122812122232224A40860302 +6213:004800440040FFFE0040004000443E4422442228222822123E32224A00860302 +6214:0240022002FC7F10016003841C64E01C0240022002FC7F10016003841C64E01C +6215:042024282424242424203C3E05E00424FC242428242824102432444A84860502 +6216:004800440040FFFE004000403E442244224422283E2800120732784A20860302 +6217:0828082414241220212E40F0BE202224222422282A2824102112212A1F460082 +6218:1020102810241E241020103E11E010247E2442284228421042327E4A42860102 +6219:0028FF2481248120BD2E81F08120BD24A524A528A528BD108112812A85468282 +621A:0028002400203FFE222023A0222422243FE4202822282A903252422A4A468482 +621B:7FFC02001FF010101FF010101FF010101FF0024003F87E20014000840764381C +621C:005000480040FFFE00403E4022443E4400447F2808283E1208320F4A78862302 +621D:00287E24422442207E2E42F042207E24422442287E2800102412222A41468182 +621E:7FFC02001FF010101FF010101FF010107FFE424283FC7E20014000840764381C +621F:08200828FFA408247F20413E7FE041247F2449280828FF900832084A08860902 +6220:10400848FF44004442402440FFFE00407E44424442287E2A4212422A7E464282 +6221:22202228FF2422243E20223E3FE022242224FF28402854106232404A7E860102 +6222:3F28212421243F200020FFFE21203F2421243F28212827D0F912412A01460182 +6223:0A28742415245220222E21F04120BE24082408287F2808101412122A22464082 +6224:00107E14221224103F16557849125512A21200147F145508551A57AAFC460082 +6225:00207E2842247E2442207E3E09E048247F2488287E2808100F32F04A40860102 +6226:90A8492400247F20492E49F07F20492449247F2808280810FF92082A08460882 +6227:08280C241224292044AEBFF021203F2421243F2820283F105112512A9F461182 +6228:0028FF2402247A204A2E7AF00020FF2402247A284A284A107A12022A0A460482 +6229:0028FF2422245520F72E00F0FF2000247E24422842287E104212422A7E464282 +622A:082008287F240820FFFE142022247FA4A4243F2824283F1024123FAA20462082 +622B:10141012FE1011FE20103C1025D26552BD52255425D43C0824CA271A24262C42 +622C:00107F941212529033161278FFD200123F12211421143F08211A212A3F462182 +622D:10100814FF92809000167F7808127F1249127F1449147F08001A222A41468082 +622E:0010771411125510331655780C123312C492181462140C88711A062A1846E082 +622F:10281E2410247F20512E5CF072204E2440244A286AA85B104A128F2A78460082 +6230:0010F79494929490F79600787F1249127F1249147F140808FF9A082A08460882 +6231:08100F1408127F9048964E787912471240124A146A94AA88BB9A0A2A7F462082 +6232:08280F2408247F20492E4CF07920472440245F2840285F1051125F2A8A463F82 +6233:0020EE282224AA246620AA3E01E024247F24C8287E2848107E32484A7F864102 +6234:08207F280824FFFE00207F2049247F2449247F2822287F102212FFAA22464182 +6235:7728552477245520772E55F0772022247FA4A4283F2824103F12242A3FC62082 +6236:001000F81F0010001FF81008100810081FF81008100010002000200040008000 +6237:0200010001001FF810081008100810081FF81008100010001000200020004000 +6238:00007FFE000000001FF81008100810081FF81008100010002000200040008000 +6239:020001003FFC200420043FFC200020002FF0202020C0210042004404840403FC +623A:08000400047C3F442144214421443F44217C204020402040204240424042803E +623B:020001003FFC200420043FFC2080208020802FFC214021404220441088081006 +623C:0000FC7E0440044004407C7C4444444444447C7C044408400840104020404040 +623D:020001003FFC200420043FFC20002220212024202220207E5FA0402080200020 +623E:020001003FFC200420043FFC208020A020902FFC214021404220441088081006 +623F:020001003FFC200420043FFC210020803FFC2200220023F84408440888281010 +6240:0208071C38E0208020803E8022FE228822883E88208820884108410882080408 +6241:020001003FFC200420043FFC200020002FFC292429242FFC492449248924080C +6242:020001003FFC200420043FFC2080208020FC208020802FF8480848088FF80808 +6243:020001003FFC200420043FFC200020002FFC280429E42924492449E488140808 +6244:020001003FFC200420043FFC210022002FFC280429E42924492449E488140808 +6245:010000803FFC20043FFC210023F02C2022C023403CFC23084C90406081801E00 +6246:020001003FFC200420043FFC210020802FFC2140224426284A10528883060200 +6247:020001003FFC200420043FFC200020003F7C2104292425144924514485140208 +6248:010000803FFC20043FFC200027F0241027F020002FF828884FF84802880207FE +6249:010000803FFC20043FFC212021203F3E212021202F3C212041205F3E81200120 +624A:010000803FFC20043FFC24882490296022182C84348A2488495042208C183006 +624B:001000F83F00010001003FF8010001000100FFFE010001000100010005000200 +624C:1000100010001000F8001000140018003000D000100010001000100050002000 +624D:0080008000800080FFFE01800280028004800480088010802080408002800100 +624E:1080108010801080FE801080108012801C803080D080108410841084507C2000 +624F:1080108010801080FDF010901090149018903090D090109211121112520E2400 +6250:1040104010401040FDFC10441044144418443084D08410841104110452282410 +6251:1080108010801080FE8010A0109012881C843084D08010801080108050802080 +6252:1000102011201120FD2011201120152019203110D21012101208140854042802 +6253:1000100013FE1020FC2010201020142018203020D02010201020102050A02040 +6254:1000100013F81088FC90109010A014BC18843084D10411041104120452282410 +6255:1040104010401040FC4010801080148019003110D108120817FC120450042000 +6256:1200110010801080FC401040104014A018A030A0D11011101208120854042802 +6257:1020102010201020FC20102011FC142018203020D02010201020102053FE2000 +6258:1008103C13C01040FC4010401040147E1BC03040D040104210421042503E2000 +6259:1010101010101010FDFE10101010151019103090D09010501020105051882606 +625A:10401040108010FCFD0412041004150418843044D04410041004100450282010 +625B:1000100011FC1020FE201020102012201C203020D02010201020102053FE2000 +625C:100011FC10201020FC20102014201BFE3020D020102010201020102050A02040 +625D:100011FC10001000FC0013FE10401440188030FCD00410041004100450282010 +625E:100011FC10201020FC20102014201BFE3020D020102010201020102050202020 +625F:100013F010901090FC901090109013F018903090D0901092108A108A50862082 +6260:100017F812081288FE4811501110151018A030A0D040104010A0111052082C06 +6261:1020102010201120FD2C1134116417A419243134D12811221122110250FE2000 +6262:10401040108010FEFD00120010FC140818103020D04010801102110250FE2000 +6263:1000100011FC1104FD0411041104150419043104D1041104110411FC51042000 +6264:1000100013FC1090FC9010901090149018903090D090109211121112520E2400 +6265:102010201020103CFDE0102010201420183E33E0D020102210221022501E2000 +6266:1008103C11E01020FC201020102017FE18203020D02010201020102050202020 +6267:1040104010401040FDF8104810481448194830C8D04810A810AA110A52062402 +6268:1000100011FC1044FC4411441144154419443244D04410841084110452282410 +6269:10201010101011FEFD0011001100150019003100D10011001100120052002400 +626A:1100108010BC1204FA04120416041A043204D204120412041204120452142208 +626B:1000100013FC1004FC041004100415FC18043004D0041004100413FC50042000 +626C:100011F810101020FC40108011FE149218923092D11211221222144250942108 +626D:100011FC10441044FC441044104415FC18843084D08410841084108457FE2000 +626E:1010109010901088FD081104120415FA18883088D08810881108110852282410 +626F:1020102010201120FD201120113C152019203120D12011201120112057FE2000 +6270:1040105010481048FC4011FE1050145018503050D090109010921112510E2200 +6271:100013FC10841088FC881090109C148419443144D12811281210122854442182 +6272:1040104010A010A0FD10128814461040180033F8D00810101010102050202040 +6273:1008101C11E01100FD0011FC1144154419443128D12811101110122852442482 +6274:1020102010501050FC8811041202108818883088D08810881088110851082208 +6275:1020102010201050FC50108815041A023060D010100010C01020101050082000 +6276:1020102010201020FDFC1020102014201BFE3020D05010501088108851042202 +6277:1008103C11E01020FC20102013FE142018203050D05010501088108851042202 +6278:1010111011101110FD1011FE11001500190031F8D10811081108120852082408 +6279:1010111011101112FD12111411D8151019103110D110111211521192510E2000 +627A:1008103C13E01220FE201220122017FE1A203210D2101212120A128A53062202 +627B:10801080108010FCFD04110812401440184030A0D0A010901110110852042402 +627C:200023FE22002200FAF8228822882A883288E2A82290228224822482A87E5000 +627D:10201020102013FEFC20112411241524192431FCD024102010221022501E2000 +627E:1090108810881080FCBC13C01080148818883090D060104410A41114520C2004 +627F:1FE000400080010479280FF00920111017D0210821084FE48102010005000200 +6280:10201020102013FEFC201020102015FC18843088D04810501020105051882606 +6281:1040104010801088FD0413FE1002149018903090D090109011121112520E2400 +6282:1000100013FE1020FC2010201020142019FC3020D02010201020102057FE2000 +6283:1040102010201000FDFE10401040146018503048D04410441040104050402040 +6284:10201020102010A8FCA410A2112215201A243024D02810081010102050C02300 +6285:10801080108010FEFD0212421042148218A23112D3FA110A1002100250142008 +6286:10401020102013FEFC8810881088148818883050D05010201050108851042602 +6287:1000100011FE1102FD021102110215FA19023102D1021102110211FE51022000 +6288:100011FC11041104FD0411FC11041504190431FCD10411041204120454142808 +6289:10401040104013F8F84810481448184837FED04010A010A01110111052082406 +628A:100011FC11241124FD241124112415FC19043100D10011001102110250FE2000 +628B:1000104010201010FC901080108012841A823282D28214881088108850782000 +628C:10201020102011FEFD2212241020142018503050D0501050109010925112220E +628D:1008106813881088FC88108814881BFE3088D088108810881108110852082408 +628E:1000100011FC1000FC00100013FE142018203040D0401088110413FE51022000 +628F:1000100011FC1000FC00100013FE109018903090D090109011121112520E2400 +6290:1020102010201020FDFE1122112215221952314AD18A110211021102510A2104 +6291:10001080133C1224FE241224122416241A243224D2B413281220102050202020 +6292:100011F810081050FC20101013FE142218243020D02010201020102050A02040 +6293:1008101C11F01150FD5011501150155019503148D14811481144124452422400 +6294:1000100013FE1020FC201040104014D019483244D44410401040104050402040 +6295:100010F810881088FC881106120015FC18843084D04810501020105050882306 +6296:1010111010901090FC101110109014901810301ED3F010101010101050102010 +6297:10801040104013FCFC00100011F0151019103110D110111211121212520E2400 +6298:1008101C11E01100FD00110011FE151019103110D11011101110121052102410 +6299:1008103C11E01020FC2011FC10201420182033FED02010201020102050A02040 +629A:100013FC10401040FC40104017FE104018A030A0D0A0112011221222541E2800 +629B:121012101210127CFA14179412941A9432A4D2A412D4128A14821482587E3000 +629C:1040104010401040FBFE1080148018FC3144D144114812501220145058882306 +629D:20802080213E2102FA42224227C228823082E1022142222227E22222A00A4004 +629E:100011FC11041104FD04110411FC152419203120D11011101208120854042802 +629F:10201020102011FCFC20104011FE1440188031FCD00410881050102050102010 +62A0:100011FE11001104FD4411281128151019103128D12811441184110051FE2000 +62A1:1040104010A010A0FD1012081406111019203140D18011001104110450FC2000 +62A2:1040104010A010A0FD101208140611F019103110D15011201104110450FC2000 +62A3:10401040108010FCFD0412041084144418443014D02410441184100450282010 +62A4:10401020102011FEFD021102110215FE19023100D10011001200120054002800 +62A5:100011FC11041104FD141108110015FC19443144D12811281110112851442182 +62A6:100013FE10201020FC2013FE122216221A52324AD28A130212021202520A2204 +62A7:1000100011FC1104FD0411041104150419FC3104D00010901088110452022402 +62A8:100011FC10201020FD2410A410A814201BFE3020D02010201020102050202020 +62A9:10201020102011FCFD24112411FC152419243124D7FE11041104110451142108 +62AA:10401040104013FEFC8010A0152019FC3324D524112411241134112850202020 +62AB:10101010101011FEFD121114111015FC19443144D12811281110122852442482 +62AC:1020102010401088FD0413FE1002140019FC3104D10411041104110451FC2104 +62AD:10401020102013FEFA021404100018F03090D0901090109011121112520E2400 +62AE:1040104010A01110FA081426104018803310D020104010881310102050C02700 +62AF:100011F811081108FD0811F811081508190831F8D10811081108110857FE2000 +62B0:10201020102011FCFD24112411241524192433FED02010501050108851042202 +62B1:1080108011FC1104FA0415F4111419143114D1F4110411281112110250FE2000 +62B2:1000100017FE1008FC0813C8124816481A483248D3C812481008100850282010 +62B3:100011FC11041104FD0411FC1100154019443148D170114011421242523E2400 +62B4:2048224822482248FA4827FE22482A483248E2482278220022002200A3FE4000 +62B5:1008103C13E01220FE201220122013FE1A203210D2101212120A128A53262212 +62B6:1020102011201120FDFC1120122010201BFE3020D05010501088108851042202 +62B7:100013FC10201020FC40104014D019483244D444104010401040100057FE2000 +62B8:1008103C13C01000FC40102013FC140818103020D040108011001280547E2000 +62B9:10201020102013FEFC201020102015FC187030A8D0A811241124122250202020 +62BA:10201020102011FCFC201020102013FE187030A8D0A811241124122250202020 +62BB:10201020102013FEFA22122216221BFE3222D222122213FE1222102050202020 +62BC:100011FC11241124FD2411FC11241524192431FCD12410201020102050202020 +62BD:1020102010201020FDFC112411241524192431FCD12411241124112451FC2104 +62BE:1020102010201020FDFE1020102014201BFE3020D04010401088110453FE2102 +62BF:100013FC12041204FE0413FC122016201BFE3220D22012101212128A53062202 +62C0:100011FC11041104FD04110411FC145018503050D050109210921112520E2400 +62C1:220022002200221EF7D22252225222523252E252225222522452245EA9525080 +62C2:10901090109013FCFC94109413FC16901A9033FED0921092111A111452102410 +62C3:10801080108010FEFD4011401240107C18403040D040107E1040104050402040 +62C4:10401020100013FEFC2010201020142019FC3020D02010201020102053FE2000 +62C5:1000100011FC1104FD04110411FC150419043104D1FC11041000100053FE2000 +62C6:1008101C11E01100FD00110011FE151019103130D11811141112121052102410 +62C7:100011F811081148FD281108110817FE1A083288D248120813FE100850502020 +62C8:104010401040107EFC4010401440184033FCD204120412041204120453FC2204 +62C9:1040102010201000FBFE1000140419043104D088108810881090101057FE2000 +62CA:1088108810881108FD7E13081508114819283128D10811081108110851282110 +62CB:221022102210227CFA1427D422942A9432A4E2A422D4228A24822482A87E5000 +62CC:10201020112410A4FCA8102011FC142018203020D3FE10201020102050202020 +62CD:10201020104011FCFD0411041104150419FC3104D10411041104110451FC2104 +62CE:1040104010A010A0FD101248142610201BF83008D010111010A0104050202020 +62CF:10001000FEFC2244642818102428C2C600201FC001003FF801007FFC01000300 +62D0:100011FC11041104FD0411FC104014401BFC3044D04410841084110452282410 +62D1:1088108810881088FDFE108810881488188830F8D08810881088108850F82088 +62D2:100011FE11001100FD0011FC1104150419043104D1FC11001100110051FE2000 +62D3:1000100013FE1020FC201040104014FC19843284D48410841084108450FC2084 +62D4:1050104810481040FBFE1080148018FC3144D144112811281210122854442182 +62D5:10201010101011FEFD02120410801488189030A0D0C0108210821082507E2000 +62D6:1080108010FE1100FE201120112C15741BA43124D13411281122110250FE2000 +62D7:2020212021202220FAFC24A4272429243224E22424A427A420C42044A0944108 +62D8:10801080110011FCFA04140411E419243124D12411E411241004100450282010 +62D9:1020102011241124FD24112415FC18243020D020122212221222122253FE2002 +62DA:1020102010401088FD0413FE10021488188833FED08810881108110852082408 +62DB:100013FC10841084FC841104111412081C0031FCD10411041104110451FC2104 +62DC:04001EFCF020102010FCFE20102010FC1020FE2011FE10202020202040208020 +62DD:100013FE10201020FDFC1020102015FC18203020D3FE10201020102050202020 +62DE:1008101C11E01100FD001100110015FE19103110D11011101110111057FE2000 +62DF:1008108810481228FA28120812081A083208D208121012981324122450422082 +62E0:220022382228FBA822A822A834A826AAEAAA22AA2126214022802260A41E4800 +62E1:10201010101011FEFD0011101110151019103120D1281124124412FE54422800 +62E2:1090108810881080FBFE10A014A018A430A4D1281128113212221262549E2800 +62E3:1040104017FC1080FC8013E0112012201BFC3020D12811241222142250A02040 +62E4:104010401040107CFC40104014401BFE3040D040105010481044104050402040 +62E5:200027FC24442444FC4427FC24442C443444E7FC2444244424442844A8545008 +62E6:1000110810881090FC0013FE10001400180031FCD00010001000100053FE2000 +62E7:10401020102013FEFA0214041000180033FED020102010201020102050A02040 +62E8:1040104812441240FBFE1080148018FC3144D144114812501220145058882306 +62E9:200027F822082110F0A0204021B0264E3040E3F82040204027FC2040A0404040 +62EA:100017FE10901090FC9013FC129416941A943294D29C13041204120453FC2204 +62EB:100011F811081108FDF81108110815F819443148D13011201110114851862100 +62EC:1008103C11E01020FC2013FE10201420182031FCD10411041104110451FC2104 +62ED:1028102410241020FBFE102014201BA03120D1101110111011CA170A52062002 +62EE:10201020102013FEFC20102011FC1400180031FCD10411041104110451FC2104 +62EF:100011FC10081010FC2213B210B414A819283124D22214A01040100057FE2000 +62F0:10801088109C1170FD1013101510111019FE3110D110111011101110517C2100 +62F1:1088108810881088FDFE108810881488188833FED00010881084110452022402 +62F2:044004407FFC0440FFFE08203018C0E61F0001003FF801007FFC010005000200 +62F3:0100111009203FF802007FFC082010F03F08C1061FE001003FF8010005000200 +62F4:1020102010501088FD04120211FC142018203020D1FC10201020102053FE2000 +62F5:10401040104013FEFC801080117815081B103510D1FE11101110111051502120 +62F6:1124112412481124FD241000108014FC19043184D24814281010102050C02300 +62F7:1040104411F41048FC5013FE1040148019FE3240D48010FC1004100450282010 +62F8:1040104010FC1108FA90106014481990363ED042108413481030102050C02700 +62F9:1040104011FC1044FC84108415281A103108D3DE114A114A114A1252535A24A4 +62FA:1020102013FE1020FC2011FC112415241924312CD07010A81124162250202020 +62FB:10401040104013FEFC8010901090151219523154D29012281428104450842102 +62FC:1104108410881000FDFE108810881488188833FED08810881108110852082408 +62FD:1020102011FC1124FD2411FC1124152419FC3020D0241018103210CA53062002 +62FE:1020102010501088FD04120211FC1400180031FCD10411041104110451FC2104 +62FF:010006C01830EFEE00001FF010101FF000201FC001003FF801007FFC01000300 +6300:1004101E11E01100FD0611781150155019523154D14811481144125452622440 +6301:10201020102011FCFC20102013FE1008180833FED00810881048100850282010 +6302:1020102011FC1020FC20102013FE100018203020D1FC10201020102053FE2000 +6303:100011FE10201040FC88110411FE142218203020D1FE10201020102053FE2000 +6304:1040104412441148FD50104017FE109018903090D090109211121112520E2400 +6305:100013F810881090FCBC110415141A483040D7FE104010E01150124854462040 +6306:100011F011101110FD101110124E14401BFC3040D0E011501248144650402040 +6307:11001104113811C0FD02110210FE140019FC3104D10411FC1104110451FC2104 +6308:08007F7C08243E2408247F44085408F83F0001003FF801007FFC010005000200 +6309:10401020102013FEFA02144410401BFE3088D088110810D01020105050882304 +630A:10401040107C1040FC4013FE100010001BFE3040D05010481044104050402040 +630B:100013FE12201220FE2013FC120416041A043204D3FC12201220122053FE2000 +630C:1080108011F81208FD1010A0144018A03318DC0613F812081208120853F82208 +630D:10401020102013FEFC0010881104120218883088D05010501020105050882306 +630E:2040204027FC20A0F11022082DF6200037FCE080210023F820082008A0504020 +630F:100011FE11021102FD7A11021102157A194A314AD14A117A11021102510A2104 +6310:10001000FE7C224442443444087C3400C2201FC001003FF801007FFC01000300 +6311:1090109010901292FD941098109015981A943492D0901090111211125212240E +6312:200220022FC22212FA1223D222522C523652E5522892209221022202A40A4804 +6313:10401020102013FEFA02140410381BC03040D040107E17C0104010425042203E +6314:10401020102013FEFC40104010A014A219A43298D4901088108410A250C02080 +6315:100013FE11081108FD0811F81108150819F83108D108111E17E8100850082008 +6316:1040102013FE1202FC881104120214F818103020D04010801102110250FE2000 +6317:1020102013FE1020FDFC102411FC152019FE3022D02A10541050108851042202 +6318:1020102011241122FA2A101014601B803040D04013FC10441084108451142208 +6319:2208110811100020FFFE0820101020E8DF0601003FF801007FFC010005000200 +631A:1080FBF010901990F0941154520C24E41F0001003FF801007FFC010005000200 +631B:02000100FFFE044014502448444400F03F0001003FF801007FFC010005000200 +631C:100013FC10901090FC901092149212941A943298D09010901090109057FE2000 +631D:2408220822082008F8FE2E0822482A283228E2082208222822102500A8FE4000 +631E:1010121011101110FCFE10101310152819243144D142118211001280547E2000 +631F:10201020102011FCFC20112410A414A8182033FED05010501088108851042202 +6320:1080108010BC13C0FC50102410D4130C180033FED090109011121112520E2400 +6321:1040124411441144FD48104017FC100418043004D3FC10041004100457FC2004 +6322:2010207823C02040F84027FE20A029103208E5162110211021102210A2104410 +6323:1080108011F01210F82013FC1044184437FED044104413FC1044104051402080 +6324:1080104017FE1208FD1010A0144019B0360ED110111011101110121052102410 +6325:100013FE12021444FC4013FC108014A0192031FCD020102017FE102050202020 +6326:100013FC10041004FDFC1004100417FC18083008D7FE11081088108850282010 +6327:100013DE10421042FA52114A154A184230C6D14A1252104210421042514A2084 +6328:2040208021102208F7FC2104210023F83440E0402FFE204020A02110A2084C06 +6329:1010109010881108FA0415FA110819083108D1F810901090109011125212240E +632A:100017DE12521252FA5417D412581A543252DFD21252125A1254145055502890 +632B:2040204022482248F248255428E220403040E7FC2040204020402040AFFE4000 +632C:1020102013FE1020FC2013FE1202140419F83010D02013FE1020102050A02040 +632D:100013FE10201020FDFC1124112415FC19243124D1FC112010A0104050B0230E +632E:11081088109013FCFC24102413FC16201A2033FED06210A2112A122454202020 +632F:100013FC12001200FEF81200120017FC1AA032A4D2A812901290148854A428C2 +6330:100011FC11041104FD0411FC100014001BFE3020D02011FC1020102053FE2000 +6331:1010121011101110FC5412521252109018103114D604120812081210522020C0 +6332:204012484444201408607380200000F03F0001003FF801007FFC010005000200 +6333:100011FE10001092FD24124811241492180031FED02010201020102053FE2000 +6334:1100110011FC1200FDF81108114815281BFE3108D248122813FC100850502020 +6335:100013FE10201020FDFC102014201BFE3088D08813FE10881088110851082208 +6336:100011FC11041104FDFC1100110015FE1902317AD14A114A127A120254142008 +6337:2100211E211227D2F914211427D829143112E7D22112211A21142210A2104410 +6338:100011FC11041104FDFC1104150419FC3104D10411FC1050105010925112220E +6339:100011F811081108FDF8100013FC12441A443244D3FC12001202120251FE2000 +633A:2000200C27702110F9102210227C2F103110E5102510227C22002500A8FE5000 +633B:1004100E13B81088FC881128152E1BA830A8D2A812A8113E11001280547E2800 +633C:1008103C13C01044FA2411281500184033FED088110813901060105051882604 +633D:1080108011F81208FC1013FC124416441A4433FCD0A010A011221122521E2400 +633E:10201020102013FEFC20102011241524192432AAD02010501050108851042202 +633F:101C11E010201020FDFE102011FC1524192431FCD124112411FC102050202020 +6340:110011F813081490FC601198164610401BF83040D3F8104017FC104050402040 +6341:10201120112011FCFD201220102013FE18003000D1FC11041104110451FC2104 +6342:100013FE10401040FDFC1084108417FE18003000D1FC11041104110451FC2104 +6343:100011FC10441044FBFE1044144419FC3080D08011FC12841484108450FC2084 +6344:1028102410241020FDFE1020112014B218B43068D0A811241222102050A02040 +6345:200027F8201021A0F84027FC24442C4437FCE444244427FC24442444A4544408 +6346:200027FC24442444FC4427FC24442CC434E4E5542644244424442404A7FC4404 +6347:10201020102011FCFC20102013FE145018503154D15211521252109050902130 +6348:1020102010501088FD0412FA102014201BFE3020D12811241222142250A02040 +6349:100011FC11041104FD0411FC102014201920313CD120112012A01260543E2800 +634A:1008103C13C01004FA44112810001BF83010D02017FE10201020102050A02040 +634B:1008103C13C01044FA2411281500181033FED010111010901090101050502020 +634C:200427C424442454FC5427D422142A1437D4E2542254225424442444A9545088 +634D:100011FC110411FCFD0411FC1000140019FC3020D02013FE1020102050202020 +634E:1020112410A410A8FC2011FC1104150419FC3104D10411FC1104110451142108 +634F:100011FC11041104FDFC1104110415FC18203020D1FC10201020102053FE2000 +6350:100011F811081108FDF8100013FC16041A0433FCD204120413FC120452142208 +6351:100010FC10841284FEFC1284128416FC1A0033E0D02013FE1020105050882306 +6352:1020102013FE1020FC2011FC1124152419FC3020D07010A81124122250202020 +6353:200027DE20922492F494249427D820943192E1922292229A24942890A2904110 +6354:1080108011FC1104FA0815FE1122192231FED122112211FE11221222522A2404 +6355:1048104417FE1040FC4013FC124416441BFC3244D24413FC1244124452542208 +6356:1040102013FE1202FC0411F8100014001BFE3090D090109011121112520E2400 +6357:101010101090109EFC90109013FE140018103092D09211141208101050602380 +6358:1040104010881104FBFE1002148819443242D0F8118812501020105051882606 +6359:1020102013FE1020FDFC1124112415FC19243124D1FC102013FE102050202020 +635A:100011FC11241124FDFC1124112415FC18203020D1FC10201020102053FE2000 +635B:100011F811081108FD08110811F81400180033FCD20412041204120453FC2204 +635C:1020102011FC1124FD2411FC1124152419FC3020D3FC10881050102050D82306 +635D:1104108410881010FDFC11041104150419FC3050D050109010921112520E2400 +635E:1088108813FE1088FC0013FE12021444184033FCD04410841084110452282410 +635F:100010F810881088FCF8100011FC150419243124D12411241050104850842304 +6360:1008101C11E01100FD0011FE1110151019103110D7FE10001090110852042402 +6361:1040104010A010A0FD10120815F6100018883048D24811501110102057FE2000 +6362:1080108010F81108FA1015FC112419243124D12417FE10501050108851042602 +6363:2040208023F82208FA88224822182A0033FEE0822492249227F22002A0144008 +6364:200023FC22042204FBFC220022182AE03238E2E0223C23E022222422A41E4800 +6365:1040102013FE1202FD04110011DE12521A523352D49A1094111011125212240E +6366:1020102010501088FD04120210F81420182031FCD020112410A410A853FE2000 +6367:1020102013FE1020FDFC104013FE148819243222D0F8102013FE102050202020 +6368:1020102010501088FD0412FA102014201BFE3020D02011FC1104110451FC2104 +6369:1040102013FC1204FA0413FC16001A283224D3FE122012501250148855042A02 +636A:101C13E0122013FEFE201292130A120619FC3104D10411FC1104110451FC2104 +636B:200027BC24A424A4FFBC24A424A42FBC3404E4042404240424042404A4144408 +636C:2040202027FE2400FC88248825082D7E3708E5482528252829082908B1284110 +636D:1040108013FC1224FA2413FC16241A4433FCD090111017FE1010101050102010 +636E:11FE11021102FF0211FE1310151019FF1110311051FE928212821482548228FE +636F:200420042FC42214FA14249427D429143114E7D42114211421C42E04A4144008 +6370:100011FC11241124FDFC1124112415FC182033FED07010A81124122250202020 +6371:100013FE12101210FEFE1210121017FE1A003210D21012FE1210141055FE2800 +6372:1020112410A813FEFC40108017FE11081A0435FAD908110811281112510220FE +6373:1008101C11E01100FDFE11101510191037FED000102012221222122253FE2002 +6374:2090209021082148FA44249221082BFC3044E02020A42282228A228AA4784000 +6375:10901090109013FCFE941294129417FC1A943294D29417FE1000109051082204 +6376:1010107813C01040F84017FC12481A4837FED248124817FC1040104057FC2000 +6377:2040204027FE2040FBF8204827FE284833F8E0402240227C22402540A4FE4800 +6378:1020102011FC1024FC2413FE1024142419FC3222D17410A81124122250A02040 +6379:1020102013FE1050FCA8112412FA142018A83088D3FE10881088108851082208 +637A:1020102013FE1050FC88110412FA1000180033FED02011241122122250A02040 +637B:1020102010501088FD44122211F8140818503020D0A41282128A128A54782000 +637C:101C11E010201020FBFE10A815241A423040D3FE1088110810D0103050482184 +637D:1040102013FE1000FC88108815541A223000D02013FE10201020102050202020 +637E:1040102013FE1202FC0411F81108150819F83100D10011FC1104110451FC2104 +637F:1020102013FE1020FDFC102413FE142419FC3040D3FE108411C8103050CC2302 +6380:201020902710243EF4222444279025103510E5102528252825282944A9445082 +6381:100010FC108010F8FC8010F8108017FE19403124D12811101108114451822100 +6382:1040102013FE1200FE201220123E12201A2032FCD28412841284148454FC2884 +6383:100011FC100410FCFC0411FC100013FE1A223020D1FC11241124113451282020 +6384:2040204020A02110F2082DF6200027FC34A4E4A427FC24A424A424A4A4144408 +6385:1020102013FE1020FDFC102013FE140019FC3104D1FC110411FC110451142108 +6386:100013FE1202128AFE5213FE122216221AAA32AAD2AA12FA12021202520A2204 +6387:200027BC20842294F908229424A428403000E7BC20A422A421282290A4A84846 +6388:101C13E010841244FD48111017FE1402180033F8D108111010A0104051B0260E +6389:10201020103E1020FDFC110415FC190431FCD124102013FE1020102050202020 +638A:1040102011FC1000FD081090100013FE18003000D1FC11041104110451FC2104 +638B:1040102013FE1200FE1C12F0129016901AFE3290D290129012AA12CA54A62812 +638C:111009203FFC20044FE808200FE000F03F0001003FF801007FFC010005000200 +638D:100011FC11041104FDFC1104110415FC18003112D1D41118111011525192210E +638E:1040104013FC10A0FD10120817FE10081BC83248D248124813C8100850282010 +638F:1080108010FE1102FE8210F2114214421BFA3042D152115211F2100250142008 +6390:10401040107C1084FD081200102015CE19023102D1CE11021102110251FE2102 +6391:1088108813FE1088FC8810F81088148818F83088D08813FE1000108851042202 +6392:109010901090179EF890109010901B9C3090D0901090179E1090109050902090 +6393:2100210021DC2114F914211427D428143114E1142588254829482114A5144222 +6394:00007EFC48447E4442287E1048287EC600201FC001003FF801007FFC01000300 +6395:1020102011FC1020FC2013FE108815441A4230F8D18812501020105051882606 +6396:1080104017FE1120FD20123C124416641A943348D24812301220125052882306 +6397:100017FE10901090FC90139C120416041A04339CD09010901090109057FE2000 +6398:200027FC24042404F7FC2420252425243524E5FC2420252425242924A9FC5004 +6399:103C17C012441128FC0013F81448184837FED048104813F81048104051402080 +639A:100013FE10201020FBFE122212221B3232AAD2AA1376126612221222522A2204 +639B:1088108813E81088FC88108817EC140A188A3088D3E81088108810E853882108 +639C:10001040139C1204FE04139C120416041BFC3090D0901090109011125212240E +639D:10141012101017FEF810101017D21A523252D25413D4100810EA171A52262042 +639E:1020112211221224FC5010881304142218203124D12412281050108851042602 +639F:1040102013FE1202FC04100013FE142018203120D13C112012A01260543E2800 +63A0:1040102013FE1000FC0011FC1104150419FC3020D12811241222142250A02040 +63A1:1008103C13C01044FA2411281500182033FED07010A810A81124122254202020 +63A2:200027FC240424A4F91022082040284037FCE04020E0215022482C46A0404040 +63A3:24043FA44424FFA404243F842494258800201FC001003FF801007FFC01000300 +63A4:100013DE12521252FA5213DE12521A523252D3DE1252125212521252555228A6 +63A5:1080104013FC1000FD08109017FE1040184037FED08811081090106051982604 +63A6:100011FC110411FCFD0411FC1080148019FE324AD44A10921122124250942108 +63A7:10401020102013FEFA02149411081A043000D1FC102010201020102057FE2000 +63A8:10A01090108011FEFD10131015FC1110191031FCD1101110111011FE51002100 +63A9:1040108017FE1110FE48144613F816481A4833F8D248124813F810425042203E +63AA:10881088108813FEF888108817FE180031FCD104110411FC1104110451FC2104 +63AB:20002FC024BC24A4F4A427A424A424A837A8E4A8249025D02EA820A8A0C44082 +63AC:1100110011FC1204FC44115414E4184433FCD04410E411541244104450142008 +63AD:200023FC20402040FBFE20A021102A083446E0402048226422522452A1404080 +63AE:1040102013FC1204FE0413FC120012FC1A8432FCD28412FC1484148458942088 +63AF:10201120113C1120F92017FE10001BFC3204D3FC120413FC1204120452142208 +63B0:10003A86E2B824882448F85E202827882288FABE2288248824882A8851288010 +63B1:00F03F0001003FF801007FFC010005047A7810107CFC1010FEFE101050502020 +63B2:100011FC110411FCFD0411FC108015FE1A023112D1EA110A10FA100250142008 +63B3:2040207C204023FEFA42227823C42A3C3240E24023FC224424842484A9144208 +63B4:200023FE22022202FBFE222222222AFA3222E232222A23FE22022202A3FE4202 +63B5:1020102010501088FD0412FA100017DE1A523252D25213DA1254101050102010 +63B6:1040102013FE1220FEFC1224122417FE1A243224D2FC12201250145054882906 +63B7:2440225E22922012FFD421142118291437F2E1122112211A22942250A4504810 +63B8:11041088105011FCFD24112411FC1524192431FCD020102013FE102050202020 +63B9:100011FC10081010F82013FE142018A03040D1FC115411541154115457FE2000 +63BA:10801090110813FCFC4017FE111012481C863310D02010C41308103050C02700 +63BB:100011FC10841088FC50102014D81B263020D1FC1124112411FC102253FE2002 +63BC:11FC1124112413FEFD24112411FC140019FC3104D12411241124105850842302 +63BD:11081090100013FCFC901090109214921A943298D09010901090109057FE2000 +63BE:210021F8220823F0F81027FE208029443668E0B02128266820A42122A6A04040 +63BF:1088108813FE1088FCA8102013FE1440188030FCD18412841084108450FC2084 +63C0:1020102013FE1020FDFC112411AC1574192431FCD020107010A8112452222020 +63C1:10201020103E1020FC2011FC110415FC190431FCD10411FC1000108851042202 +63C2:21082088209027FEF890209023FC2A943294E30C220423FC22042204A3FC4204 +63C3:11081088109017FEF80013C412541A5433D4D254125413D412541244525422C8 +63C4:204020A021102208FDF6200023C42A543254E3D42254225423D42244A25442C8 +63C5:FDFE204840487DFEC44844887D0800E81F0001003FF801007FFC010005000200 +63C6:101013D410581252FD8C1088110412FA18203020D3FE10201050108851042202 +63C7:1020102013FE1020FC2013FE128A16521AFA3222D22212FA12221222522A2204 +63C8:1100110011FE1202FC8217F2100213F2180233F2D00213F2121213F250142008 +63C9:200021FC20482030FBFE2052209429103230E02023FE207020A82124A6224020 +63CA:100013FE100011FCFD04110411FC14001BFE3222D22213FE1222122253FE2202 +63CB:100011FC11241124FDFC1124112415FC180033FED12011221114114851842102 +63CC:100011FC11241124FDFC1124152419FC3000D040102412A2128A148850782000 +63CD:2040204027FC2040FBF8208027FC29103208E5F6204023F8204020A0A1104608 +63CE:1040102013FE1202FC0411FC140019FC3104D1FC110411FC1104100053FE2000 +63CF:1088108813FE1088FC88100011FC152419243124D1FC11241124112451FC2104 +63D0:100011FC11041104FDFC1104110415FC180033FED0201120113C112052A0247E +63D1:1040119C11041104FDDC1104110415FC18003000D1FC10201020102053FE2000 +63D2:2008203C27C02040F8402FFE20402940365CE4442444275C24442444A7FC4404 +63D3:22102110211027BEFA28224823AA2AAE32BAE2EA22AE22A824AA24A2A9A2501E +63D4:1080108010FC1154FAD410B4152C1A443094D108104010A412AA128A54782000 +63D5:1088108813FE1088FCF8108810F81488188833FED10011481184110051FE2000 +63D6:100011F811081108FDF8100017FE150819F83108D1F81108113E17C850082008 +63D7:101C13E012201220FBFE122012FC1A843284D2FC128412FC1484148458FC2084 +63D8:1020104011FC1104FDFC110411FC14001BFE3020D02011FC1020102053FE2000 +63D9:1040102013FE1202FE0213FE120016001BFE3352D55215FE1552155259522106 +63DA:100011F8110811F8FD0811F814001BFE3100D1FC125414941124124450A82110 +63DB:1080108011F81208FC1013FE12021A52328AD222102017FE1050108851042602 +63DC:1020105010881104FEFA100015FC19043104D1FC1088108813FE108851082208 +63DD:1088108811EC112AFA2815481088197E3600D1FC1104110411FC1104510421FC +63DE:1040102013FE1000FD04108817FE100019FC3104D10411FC1104110451FC2104 +63DF:100013FE10221120FD3C112012FE140019FC3104D1FC110411FC110451142108 +63E0:100013FE120012FCFA8412FC16841AFC3220D3FE124812C812301248528423FE +63E1:200023FC22042204FBFC220023FC2A403288E3FC2224222025FC2420A82053FE +63E2:1040102013FE1202FC8010F815081A903060D198160611F81108110851F82108 +63E3:2040244424442444F7FC20002FFE20403080E7FC24A424A424A424A4A4A4440C +63E4:100013DE12521252FA5213D212521A523252D3D2121A1294125012B053102010 +63E5:1080104013FC1000FD08109017FE1442184433FCD24412441254124850402040 +63E6:1082108217F21082FC8A13EA16AA1AAA33EAD08A11CA12AA14A21082508A2084 +63E7:04047FC404243FA424A43FA41504249444281FC001003FF801007FFC01000300 +63E8:1040102013FE1000FDFC110411FC14001BFE3202D1FC10201020102050A02040 +63E9:1110111211D41118FD521192112E144019FC3104D10411FC1104110451FC2104 +63EA:208821C827082108F92A212A27AC29483308E3882554251429142124A1244142 +63EB:0620382008A47EA819202C504A8809E41F0001003FF801007FFC010005000200 +63EC:1040102013FE1202FC88110412221028182433FED02010501050108851042202 +63ED:100013F8120813F8FE0813F8110013FC1C443244D2A4120413F4100450282010 +63EE:100013FE12221020FDFE102011FC152419FC3124D1FC102013FE102050202020 +63EF:220022FE22202220FB2022BC26442A54324CE28422A4221822082208A2FE4200 +63F0:1008103C11E01020FBFE102015FC192431FCD12411FC102011FC102053FE2000 +63F1:49042A247F2441247F2441247F244104432C1FC001003FF801007FFC01000300 +63F2:10481148114813FEFD4811481178150019FE3020D3FE107010A8112456222020 +63F3:1080109E13EA108AFDCA108A13EA149218A63020D3FE10201050108851042602 +63F4:203C27C022442128F80023FC2080288037FEE10021F8228822502420A8D84306 +63F5:20102010277C2114F9FE2214227C2F10317CE51025FE221022102500A8FE4000 +63F6:20002FDE24922492F4942794249824943792E492249225DA2E942090A0904090 +63F7:101C11E010201020FDFE10A0112C1524192431ACD124112411FC112450202020 +63F8:1020102013FE1070FCA81124122211FC190431FCD10411FC1104100057FE2000 +63F9:1050105213DC1050FCD2134E100015FC190431FCD10411FC1104110451142108 +63FA:1008103C13C01004FA44112815FC18203020D3FE102011241124112451FC2004 +63FB:2014201227FE2410FC1027F024922C9237D2E55425542488254A2A1AA8265042 +63FC:100013FE10401080FDFC1284108414FC18203022D3B410A81128122454A22040 +63FD:10901290129E12A8FAC4108015FC19043124D12411241154105010905112260E +63FE:100011F811081108FDF81108110815F8180033FCD29412941294129457FE2000 +63FF:22102210221023BEF422244427902A103210EF902228222822A82344A2444082 +6400:210021F022102420FBFC224422442BFC30A0E122261E20C020302180A0604010 +6401:2200217C25042484F4F4251426A4244434A4E71C25F42514251425F4A5144408 +6402:1020112410A81020FBFE10A811241A023040D7FE108811081190106051982604 +6403:11081088109013FCFE041204120413FC18403020D0A41282128A128A54782000 +6404:2100213C21002100F9BC256425242D3C3524E1242124213C21242100A17E4100 +6405:24842244224827FEFC02280423F82A083248E248224822A820A02122A2224C1E +6406:1088108813FE1088FDFC108813FE142019FC3124D1FC112413FE110451142108 +6407:204020A021182686F84023F0201028A03040E7FE2088215023202510A9484186 +6408:1040102013FE1202FC5010881124145018883104D2FA10881088108850F82088 +6409:1040104013FE12A2FC9011FE15101B1035FED110111011FE1110111051FE2100 +640A:1080108011FC1244FD5411F4108415281A9031FCD244155411F4108451282210 +640B:1004101E13F0121EFE1012FE129216981AF2328ED28012B812A814AA554A2A86 +640C:200023FC22042204FBFC224822482AFC3248E24823FE22A422A82490A4C84886 +640D:100011F811081108FDF8100013FC16041BFC3204D3FC120413FC109051082204 +640E:20062F7821102120FA44227823102A24367EEA122210225422522292AA504420 +640F:1028102413FE1020FDFC112411FC152419FC3124D00813FE1088104850482018 +6410:2080204027FC2080F90823F02060298437FEE00227FC244427FC2444A7FC4404 +6411:1108110817FE1108F80017FE110819F83108D1F81108113E17C8100850082008 +6412:1040102013FC1108FC9013FE12021444182033FCD08010F81088110851282210 +6413:11081088109013FCFC4011F8104017FE18803100D1FC12201420182053FE2000 +6414:200023F821482110F8A0204021B02E4E3040E3F82248224823F82044A7FC4004 +6415:1020102011FC1020FC2013FE108015041BFE3002D3FC12941294129457FE2000 +6416:1040108011FC1248FD3010C0130011FC1A203020D3FE10201124112451FC2004 +6417:1020104011FC1104FDFC110411FC150019FE3100D1FE1042124A13FA50142008 +6418:1040104411F81050FBFE104014F81982327ED40011FC110411FC110451FC2104 +6419:100013FE120012FCFE0013FE12A816901AC83286D20813FE1288144854082818 +641A:104011FC10441094FD0813DE114A154A1A9431FCD10411FC110411FC5104210C +641B:111010A0100017FEF8A013F810A81FFE30A8D3F810A011B012A814A650A020A0 +641C:10A0112C11241124FDAC1124112415FC182031FCD08810501020105050882306 +641D:1020104011FC1104FDFC110411FC150419FC3028D02413FE1050108851042202 +641E:1040102013FE1000FDFC110411FC14001BFE3202D2FA128A12FA1202520A2204 +641F:21002100213E27C8F90827C825482FC8357EE7C821082FE821082108A1084108 +6420:2440225E22922012F7D2211E255225523552E7DE2152211222122222A42A4844 +6421:23F0211020E02318F80027BC24A42B1834A4E04027FC20E021502248AC464040 +6422:100013FC10901294FD98109017FE180031F8D108110811F81108110851F82108 +6423:20142012201027FEFC10241027F22C923492E5B426D42488254A293AAA265042 +6424:1104108410881000FBFE1000148819043202D1FC115411541154115457FE2000 +6425:10101220117C1144FC44107C13401540197C3144D144117C11441280547E2000 +6426:200027BC20842084F7BC2420242027BC3084E4A42294229424A42084A5284210 +6427:2080204027FE2402FC0227FE24002FDE3442E652254A24C62B5A2842B14A4084 +6428:100011FC110411FCFD0411FC100014001BDE3042D252114A12521042514A2084 +6429:2208220823BEF4882AA8213E22083448E84827FC20E0215022482C46A0404040 +642A:2040202027FE2420FDFC242427FE2C2435FCE42025FC250425042904A9FC5104 +642B:08783E48228E2A007EF822482A3046CC80201FC001003FF801007FFC01000300 +642C:2100223C27A424A4F6A425A424C22F8034BCE4A426A425A424942488A49449A2 +642D:2110211027FC2110F84020A021102A0835F6E000200023F822082208A3F84208 +642E:100013FE10501050FBFE125216521BFE3020D02013FE107010A8112456222020 +642F:103C13C010441224F928110014401B9C3204D204139C12041204120453FC2204 +6430:100011FC110411E4FD2413FE120211FC190431FCD10411FC1104110451142108 +6431:100013FC12041204FBFC124012201BFC3288D25013FE122015FC142058202020 +6432:2080204027FC2404F9102208203C2BD03290E29022902288228824A4A4D44892 +6433:1040102013FE1202FC2411FC102015FC182033FED02011FC1104110451FC2104 +6434:01007FFE44429FF404403FF80440FFFE082017D02108DFF601007FF801000300 +6435:200023F8224822A8FB18220823F828003000E7FC24A424A424A424A4AFFE4000 +6436:10201020105010C8FD2413FE150411FC190431FCD10011FC1284128454FC2084 +6437:1020102013FE1020FDFC110411FC150419FC3104D1FC110413FE108851042202 +6438:1020102013FE1020FDFC104013FE1488193432E2D02011FC107010AC53222020 +6439:100013FE100011FCFD04110411FC14001BFE328AD25213FE12221222522A2204 +643A:10A0109011FE1320FDFC112011FC152019FE3100D3FC1088109E1102520A2404 +643B:010006C01830EFEE00001FF010101FF0040C78F010107CFC1010FEFE10103030 +643C:10401248115013F8F88017FC11101A2835C4D84213F8104017FC104051402080 +643D:1088108813FE1088FCA81050108815241A2231FCD02010A81124122250A02040 +643E:1040102013FE128AFD04108010FE15401A40307CD0401040107E104050402040 +643F:11003906E2B822882448F85E238820082008FBBE228822882288238842A88010 +6440:1040108011FC1104FD0411FC110015FE190031FED00212AA12AA140250142008 +6441:200027FC24442444F7FC244424A425143404E7FC204020242522250AA90840F8 +6442:100013FC110811F8FD0811F8110E17F818083008D20411081090110852042402 +6443:100011FC10201020FBFE100015FC190431FCD10411FC110411FC108851042202 +6444:100013FC110811F8FD0811F8110E17F8180837BCD0A412A41128129054A82846 +6445:2040207C204027FEF442247027C42444343CE4202410245425422942A94A5238 +6446:100013FE12521252FBFE1020142019FC3020D02017FE10401088110453FE2102 +6447:1008103C13C01004FA44112811FC1A203020D3FE102011241124112451FC2004 +6448:1040102013FE1202FC1411E01100150019FC3110D11017FE1000109051082204 +6449:1040102013FE1202FCA81124145018883346D0F8110812881050102050402380 +644A:202820242740217EF1C82948257E25483248E27E254825482948207EA0404040 +644B:2000245C22942114FA9424542126290037DCE1142594255429482108A5144222 +644C:1040102013FC1000FD08109017FE1A2032A0D2FC1320122012FC1420542029FE +644D:1040102017FE1402FD0011FE121016201A7C3244D244127C12441244527C2244 +644E:200027BC208424A4FA9424A4205029883626E0C02310206423882030A0C04700 +644F:1020102013FE1020FDFC104013FE148819043242D59C110411DC110451FC2104 +6450:212421242224F4242954214A22923610EA102250225C2250225022B0A29E4300 +6451:200027FE242A2426F7FE242227AA26AA37AAE4322596262E24462482A7FE4402 +6452:200023FC22042204FBFC220022842A4832FCE248224823FE24482448A8885108 +6453:1020147C12841148FC3010CE16101A7C3210D27C121012FE1210121055FE2800 +6454:1040102013FE1020FC4812F21124165218F83008D02013FE1020102050202020 +6455:22A822A827FC22A8FAAA24E628002FFC3444E04023F8224822482248A2584040 +6456:1100111013DC1254FD54128811081AF43402D00013FC10401150124855442080 +6457:2108210827C82108F91E27D225642D4037C8E1082388254829542114A1244142 +6458:2080204027FC2110F8A027FC24442DF43444E5F42514251425F42404A4144408 +6459:2010241022FE2210F8FE209226FE2A9232FEE21022FE221022102510A8FE4000 +645A:1020112410A813FEFA0210F81488188830F8D020102011FC1020102053FE2000 +645B:1040102013FE1000FD541124115415FC182033FED242129212FA120A52022206 +645C:100011FC112413FEFD2411FC100015FC190431FCD10411FC110411FC50882104 +645D:1040102013FE1250FE5013FE125216521BFE3200D29212D41298149254D2288E +645E:100013FC124413FCFE4413FC108015101BE03048D18413FE1022112852A42442 +645F:102011FC112413FEFD2411FC102015FC192431FCD04013FE108811D05070238C +6460:1040108013FC1244FAF4131412A41A4432A4D3FC104010241522150A590820F8 +6461:200027BE24882488F7A824A824A827BE3410E518249825A826AA244AA0464080 +6462:1040107C104013FEFA42127813C41A3C3208D2F0132412A815FE142058A02040 +6463:1040107C104013FEFA42127813C41A3C3200D2FC128412FC128414FC548429FE +6464:1020102013FE1020FAAA112412AA182032AAD12412AA10501050108851042602 +6465:110011FC120015F8F90811F8150819F83000D7FE110013FC14A4112452542088 +6466:2200220E2F74F254255428D427543054EFD424542754215421522154A55C4284 +6467:1020122213FE1090FC8811FE1310151019FE3110D11011FE1110111051FE2100 +6468:100013FE120213FEFE101254123816541A823250D27C1290121015FE54102810 +6469:00803FFE24103F7C26382D543412203827C0204027F820402FFE404041408080 +646A:20902290229E22A2FAD423A8209428A437FEE28422A4229422942284A4944888 +646B:2200227C22442744FA7C224422442F7C3244E244227C22282528254AA84A5086 +646C:1080104013F81110F8A017FE10001BF83208D3F8120813F81120112252222C1E +646D:2040202023FE2200FA48224823FE2A483248E248227822002554252AAA2A5000 +646E:08207F20087E7E4408A4FF2810101E2822645FC281003FF801007FFC01000300 +646F:08207E2008F8FF2814287F6A082AFF5608A21FC001003FF801007FFC01000300 +6470:08203E2008F87F282A685D2A08563E8200201FC001003FF801007FFC01000300 +6471:100011F8110811F8FD0811F8100017FC1A9433FCD00011F81090106051982606 +6472:22002202223C2FA0F2202FA02ABE2FA43AA4EFA422242FA422242244A2444284 +6473:100013FE1200127CFE441244127C16001AEE32AAD2AA12AA12EE120053FE2000 +6474:11FC102013FE1222FDAC102011AC140019FC3000D3FE108010FC100450282010 +6475:20142012201027FEFC10249024D22C9237F2E494249425C82AAA289AB1A64042 +6476:102013FE102011FCFD2411FC112415FC182233FED00813FE1108108850282010 +6477:1124124811241000FDFC112411FC152419FC3020D3FE107010A8112456222020 +6478:1110111017FC1110FC0013F8120817F81A0833F8D04017FC10A0111052082406 +6479:04407FFC04401FF010101FF010101FF00400FFFE10502788C1061FF001000300 +647A:200027BC208424A4FA9424A42084284033F8E208220823F822082208A3F84208 +647B:1040108811FC1108FA5213FE145019883626D0C0131010641388103050C02700 +647C:200027DC251427D4FC5427C825082D1437E2E000204027FC20402040AFFE4000 +647D:100013FE105011FCFD54115411FC140019FC3000D3FE102010A8112452A22040 +647E:2000277C21442144F97C271024102C7C3454E7542154217C21102114AAFE4402 +647F:1020105010881346FC2011FC108814501BFE3000D1FC110411FC110451FC2104 +6480:08007F7808483E4800863E782A483E3040689FC601003FF801007FFC01000300 +6481:102013FE104810F0FC2013FE1242109019F83028D12011FC122017FE50202020 +6482:200027FC244427FCFC4427FC21002BF83510E0E023182C0623F82208A3F84208 +6483:1078FE4810487C8654787C485430FECE10201FC001003FF801007FFC01000300 +6484:20002FBE28A22AAAFAAA2AAA251428A23080EFFE2110221023A02060A1984E04 +6485:20002FFE28002A28F9482BEE289228843AA0EAA82BE8288828942914A9245242 +6486:49202A3E7F4849485DA86B104928414600201FC001003FF801007FFC01000300 +6487:2108210825482390F91E27D425642D543554E75425D4254825482554A46444C2 +6488:208822AA22DC2488F954222220002BFE3242E44423FC204420442084A1144208 +6489:08407F40227E3E8801483E4804507E200850288C10F03F0001007FFC01000300 +648A:279E2492279E2492FF9E240224F22C9234F2E49224F2249224922532A4024406 +648B:200027BC24A427BCFCA427BC24042DF43444E4E42444244425F42404A4144408 +648C:104013F8124813F8F84017FE10001BF83208D3F8120813F8120813F851102208 +648D:200027BC21082528F7BC231825AA29463000E3F82208220823F82208A20843F8 +648E:102013FE102011FCFC0013FE120215FC180031FCD10411FC1104108853FE2000 +648F:100013FC100413FCFC0413FC100017BC192437BCD00813FE1108108850A82010 +6490:112410A813FE1202FCF8108810F8140019FC3010D11011FE1050109053102030 +6491:112410A813FE1202FCF8108810F8140C19F03020D1FC102013FE102050A02040 +6492:2288228827C82290FA9E27D420242FD43454E7D4245427C824482454A46444C2 +6493:1020102011FC1020FBFE1108179C19083188D63E100013FE109010905112220E +6494:100011FC110411FCFD0411FC14201BFE3000D1FC110411FC1020112452222060 +6495:24802482249C2FD0F4902790249E27943494E4942FD42014251428A4B0244044 +6496:2008278820882110FFDE249424A427943494E794249424C827882C94A0A440C2 +6497:1088108811FC1088FC8813FE102015FC192431FCD12411FC1000108851042202 +6498:1210121013DE1228FD4410A015101A0835F6D000100013F81208120853F82208 +6499:2108209027FE2090FBFC2294231C2A0433FCE20423FC200827FE2108A0A84010 +649A:2110211421D22250FA7E255020902AA83128E14422442482200822A4A2524452 +649B:1020112410A813FEFCA8112412221104190431DED2441554109E110452042404 +649C:202027A420A82292F914220825F4280233F8E208220823F822082110AFFE4000 +649D:2004203E27C02244F92823F822082BFC3204E3FE240226AA2AAA2A02B0144008 +649E:102011FC10881050FDFE100011FC152419FC3124D1FC102011FC102053FE2000 +649F:101C11E0104013FEFC88110412FA148818F83000D3FE120212FA128A52FA2206 +64A0:21102114211227D2F91027DE24702FD23452E7D421142FD8210A211AA1264142 +64A1:2080211023F82210FCA427BC204028A03358EC462048226422522452A1404080 +64A2:100013FE105013FEFE5213FE100015FC190431FCD10411FC102013FE50202020 +64A3:100013DE12521252FBDE100015FC192431FCD12411FC102013FE102050202020 +64A4:2208210827C82210F49E2FD4206427943494E7942494278824882494A4A445C2 +64A5:202423A820922514F2082C0427BA20A837C6E40027BC208420A82090A5284244 +64A6:1040104017FC1110FA48144613F8185037FCD08013F81D0811F8110851F82108 +64A7:21102110221C22A4F4C82F3E212A222A34AAEFBE20A020222AA22AA2A81E4000 +64A8:1090108811FE1110FB1015FE1110191031FED110111011FE110012A452522452 +64A9:2040204027FC20A0F514220827FC2A0A33F8E20823F8204022482444A9444080 +64AA:2080211023F82080F7FE224825F4284233F8E24823F8224823F82040A7FC4040 +64AB:1100110013FC16A8FAA812A817FC1AA832A8D2A81FFE100012A8125454542000 +64AC:103813C0107813C0FC7813C4103C140018C63738D1CE173811CE1738514A2186 +64AD:207827C022482150FBFC215022482C0633F8E248224823F822482248A3F84208 +64AE:200023F8220823F8FA0823F820002FFE3480E7BC2494279424D42F88A09440A2 +64AF:1088105013FE1020FDFC104013FE148019FC3284D4FC108410FC108450FC2084 +64B0:200027BC24A427BCFC2024A4239C28003110E7FC211021102FFE2110A2084404 +64B1:2020272025FE2540FD7C2690257E2D00357CE544257C2644247C2444A444444C +64B2:1050125211541050FBFE108814501BFE3020D1FC102013FE1050108851042602 +64B3:221022102510F4BE2822274422103210EF1022102AA8272822282344AC444082 +64B4:221021102FD02010F7BE24A427D420143794E094211421C82F082114A5144222 +64B5:1088108813DE1088FBDE108811541A2233FCD080112013FC102017FE50202020 +64B6:108813FE10881000FDFC10A810A817FE18A830A8D1FC102013FE102050202020 +64B7:220022FE22102FA0F27C2244275420543054E7542554255425282724A5424082 +64B8:210023F024102FFCF44427FC244427FC3000EFFE200023F8220823F8A20843F8 +64B9:12441124112813FEFA0211F8150819F83108D1F8110811F8109010905112260E +64BA:2080204027FC2514FA48244423F82A4833F8E04027FC244427FC2444A0404040 +64BB:20102410227C2010F8FE204426282AFE3210E27C221022FE22102210A5FE4800 +64BC:2014201227FE2410F5D0241425D4255835CAE4162442282422A2228AA4784000 +64BD:2108220827C82450F7DE246427D422143114E7D4221423C822482454A55448A2 +64BE:1000127C11441174FC54105416FE12821ABA32AAD2BA1282128A1284550028FE +64BF:1020102010501088FD0412FA1000140019DC3154D15411DC1088108851542222 +64C0:2108210821142FD4F12227C0245C27C83448E7C8213E2FC821082108A1084108 +64C1:2040202027FE2028FA24227E24C82F48317EE24824C82F7E21482248A47E4840 +64C2:200027FC20402FFEF842235820402B583000E7FC2444244427FC2444A44447FC +64C3:109013FC129413FCFE9413FC100017FC1A0032F8D20013FE1520151455482986 +64C4:1040107C104013FEFE4213F8124412FC1AA832F8D2A812F8122015FC5444298C +64C5:102013FF1000FDFE1102117A114A157A190231FED00010FC108410FC508433FF +64C6:1108110817FE1108F84413F41048185037FED08011FC130415FC190451FC2104 +64C7:100013FE125213FEFC2011FC14201BFE3088D05011FC102017FE102050202020 +64C8:1050125211541050FBFE108814501BFE3020D1FC102013FE10A8112456222020 +64C9:100013F812A812A8FBF8110013FC1C8433E4D2A412A413E4109417F450142008 +64CA:083C7F242A243E422A3CFFA449187F6600201FC001003FF801007FFC01000300 +64CB:20402248215027FEF402280423F8220833F8E00027FC244427FC2444A7FC4404 +64CC:2210221023DE2528F8C4204027FE28403248E248255428A220A02110A2084C06 +64CD:23F82208220823F8F80027BC24A42CA437BCE0402FFE216022502448B8464040 +64CE:2420FF20247E7EC482287A104A287AC604201FC001003FF801007FFC01000300 +64CF:2288228827E82290FC1E27E4245428543754E5542554274825482054A2944122 +64D0:100013FC12941294FBFC100017FE180033FCD20413FC10A2111413085D442182 +64D1:101013D412521252FBD0101017FE1A5033D2D25213D4125412EA174A50562062 +64D2:204020A021102248FDF620A022482AA833F8E04027FC2484252425F4A414440C +64D3:200027FE24282624FD7E244824C82C7E3648E57E24482448257E2640A7FE4000 +64D4:108010F8110813FEFD44119211FE1500197C3100D17C1100117C1244527C2444 +64D5:10A0109011FE1320FDFC112011FC152019FE3100D3DE12521252127252022206 +64D6:108813FE108811FCFD0411FC110415FC188031FED2221552110211FA500A2004 +64D7:20102008278824BEF48024942788247E3408E78826BE2A882A882B88B2884008 +64D8:3E1022FE3E4420287EFEA2103EFC221000201FC001003FF801007FFC01000300 +64D9:1040108013FE1222FEAA122213FE16721AAA3202D02013FE1020105050882306 +64DA:1040107C104013FEFE42127813C4163C1A0033FED24013A4125815B4545229B0 +64DB:108813FE10881000FD4813FE11481578190031FCD02013FE107010A853262020 +64DC:2108210827CC210AF90827DE24482EC83548E7C8255427D425542554A45444E2 +64DD:200027BC24A424BCF7A424BC24A427A43024E04C23F822A822A822A8AFFE4000 +64DE:22102A9027102220FFBE224427A42AA43228EFA82490289025282228A5444882 +64DF:200027FC2248F4442FFE244426EC3554E6EC244426EC255426EC2444A4544408 +64E0:2080204027FC2110F0A42F58255425523B58E000220823F8220823F8A2084408 +64E1:20402FFE204027FCF00023F822082FFE3802E7FC211023F8204027FCA0404FFE +64E2:200027BC208424A4FA9424A421202A1037FCEA2023FC222023FC2220A3FE4200 +64E3:204027FC204023FCF80027FE20022BF83040E7FE200027FE200827FEA4A84798 +64E4:208023F8220823F8FA0823F820002FFC3444E7FC244427FC20002FFEA1104210 +64E5:00007E40487E7E9043087EFE48AA7EFE00201FC001003FF801007FFC01000300 +64E6:2080204027FE2402FA2423BC24A42AA83510E2E824042BFA20402248A44440C0 +64E7:0A0033B822083BB820883AB82288FFFE082037D8C1061FF001007FFC01000300 +64E8:200820682F8828EEF88A2BF22AA42AC43B84EAA42A642A0A2AEA2AAAAAAA5530 +64E9:200027FC20402FFEF842235820402B583000EFFE204027FC24A424A4A4A4440C +64EA:3FFE28882F8A20082FBE28882F88289429A227F8204027FC20405FFE404080C0 +64EB:20002FFE28082BC8FA4C2BCA2A482BDE3808EBC82A482BD42A542BD4AA5452E2 +64EC:2400257C2604F4A82390207C24143794EA5022502FDC2250255024B0A89E4100 +64ED:108813FE10A81090FDFE132011FC152019FC3120D1FE110013FC10885070238E +64EE:2110211427D22110FFFE229024502FF43494E7F4249427E8248A27FAA4264042 +64EF:1040102013FE1202FDFC1148165019FC3304D1FC110411FC110411FC50882104 +64F0:1040102013FE1222FD54114A123A100019FC3154D3FE100011FC102050A02040 +64F1:200027BC24A427BCFCA427BC24842DF43694E4E4271C24E424A424A4A4E4440C +64F2:2440228E2FEAF28A2FEA2AAA2C6C3BAAE82A2FEA210A2FEA228C2448A8284008 +64F3:1108110811EE1294FC42100013DE16521BD23252D3D2121A1294135052102010 +64F4:2040202027FE2488FDFC248827FE2C2035FCE52425FC252425FC2400A4884904 +64F5:202027FE248827DEF48825DC26AA248C35F0E42025FC242027FE2820A8A05040 +64F6:121013DE15281084FD08109017FE10001BD43254D3D4125413D41244525422C8 +64F7:2200227E22102FA0F27C22442744207C3044E77C25442544257C2700A5284044 +64F8:1124124811241000FBFC129416641A9433FCD24813681248136A124A52462362 +64F9:2290229027D0229EFB92212227C82D4837C8E10827C821142FD42294A4544822 +64FA:200027FC24A424A4F7FC222024A427B83022EF9E28802FA428B82FA2A8A2499E +64FB:210827C825482FF0F55E27E4211427D43554E7D422142FC824482694A1944662 +64FC:210023F024102FFCF44427FC244427FC3524E89223F8220823F82208A3F84208 +64FD:244424E428A82AAAFEEE24A42AAA2EEE3242E0402FFE20E021502248AC464040 +64FE:27FC208023F82208F3F822082FFE28823548E51428F4210023F82508A0F04F0E +64FF:2020201024FE2244FA2820FE20922EFE3292E2BA22AA22BA22862500A8FE4000 +6500:22882108FABE2008729CA92A2288FFFE082037D8C1061FF001007FFC01000300 +6501:2208211027FC2040FBF8208027FC294833FCE60A2BF8220823FA2234A28C4302 +6502:23F82248224823F8F248224823F820003FBEEAAA2AAA2FBE2AAA2AAAAFBE48A2 +6503:1088108813FE1088FD1011DE125215541A883174D20211FC1020112452222060 +6504:2020203E202027FEFC2225F824222DFE3524E5FC252425FC28402AA4B28A447A +6505:108811DC108813DEFC881154122211FC190431FCD10411FC110411FC50882104 +6506:108813DE108813DEFD54122211FC142019FC3124D1FC112411FC102053FE2020 +6507:20402FFE284227FCF84023F820402FFC3040E7FC24A427FC20402524A52A48FA +6508:102013FE125013FEFA5213FE12941AD83292D2CE120812F0122015FC54A82B26 +6509:27FC204027FE2442FB5C2040275C292033FCE6202BFC222023FC2220A3FE4200 +650A:200027FE24442598FC8827DE24882DDC36AAE48824202520253C2920A92057FE +650B:2108210827CE2112F92427DE25522D5E37D2E11E2392255E29402114A1124122 +650C:2FFE28022BFA2AAAFBFA28022BFA280239F2E91229F228AA29922ACAA8824FFE +650D:40807FFC48004FF8E0004FF848084FF86080DC9C57D45D54555C5C965556EE22 +650E:1040107C104013FCFE4413F0124416FC1AA832F8D2A812F8120015FC55542BFE +650F:1110109013DE1010FA5E118217DE181033DED25013DE125013DE1250525222CE +6510:104017FE149213FCFC9013FC109017FE19483224D5FA10A411A8129054C82086 +6511:1140126C1244136CFEA413AC12A417FE19083244D5F2104017FC104050402040 +6512:2108252827BE2948F7BE231825AA29463000E3F822082248224820B0A1084604 +6513:204027FE249223FCF89023FC20902FFE3108E3FC250A21F82240227CA54048FE +6514:27BC24A427BC24A4FFBC244425F42C4435F4E55425F4255425F424E4A554444C +6515:2448244C2AAAF0082FFE22882EE8328AEEEA228C2EEC228822EA2F1AA4264042 +6516:13DE125213DE1252FBDE125213DE198C3252D04017FE10881190106050D82304 +6517:204027FE24A027FCFCA427FC25142DD83512E54E25A424A827FE28A8A9245222 +6518:204027FC200023B8FAA823B821102FFC3110E7FC21102FFE21282310AD484186 +6519:11F0121017FC1204FBFC122413B81A2231FED21017FC124413FC10D0514A263E +651A:108812AA12DC1488F954122217FE1A0230F8D08810F8100011FC110451FC2104 +651B:104017FE14921108FC80131C1204179C1A0433FCD24813681248136A52462362 +651C:122213FE109011FEFB1015FE111019FE3110D1FE110013FE128A137652522276 +651D:13FC110811F81108FDF8110E17F8180837FED294139C1294139C12D657BC2084 +651E:200027FC24A4F4A427FC221022A834BEEF68223C24A82FBC20282AA8AABE4020 +651F:204027FE24A027FCFCA427FC24002DFC3504E574252425FC257429ACA92451FC +6520:202027FE248827DEFC8825DC26AA2C883450E7DE245025DC24502BDEA8505050 +6521:241822142F90253EFAA82DE828BE2FA83228EFBE2AA82AA82BA828BEAAA04920 +6522:252827BE294827BEFB1825AA29462BFC3204E3FC220423FC220423FCA1084204 +6523:21084FD2F03C23884812FBBE0280ABAA00201FC001003FF801007FFC01000300 +6524:251825142F90253EF72822682FBE2AA83FA8E23E2FA822283FE8253EA8A05060 +6525:221023DE25282084FBFC22A422542BFC3080E7FE22A825E4285223F8A15042C8 +6526:2FBE200027BC24A4F6B424A4204027FE34A0E7FC24A427FC251229DCA91251CE +6527:2200221E2FC42208F79E24922792249E3792E49E279224922FDE2500A48C4892 +6528:20402FFE2A0A2434F3C02290228822A434D0E18E2E742B542AD42A52AB5A5294 +6529:2248215027FC2404F9F0211027FC2D5434E4E7FC204027FC20402FFEA2A44452 +652A:22AC244426AC2444F6AC24042FFE2A0A33F8E20823F8220823F820A0A124461C +652B:13DE125213DE1252FBDE10A011FE1B2035FCD12011FE100011FC10885070278E +652C:2790251E27A82484FFBE252A27BE280033F8E20823F8220823F820A0A124461C +652D:21F0221023E02020F7FC2188265021A83664E1A022482FBE2AAA2FBEA28A4FBE +652E:204027FC224823F8F0402FFE2AAA23B83110E7FC21102FFE21282310AD484186 +652F:0100010001007FFC0100010001003FF01010082004400280010006C01830E00E +6530:102010201020FE2010FC1024FC24442444242844284410941908240043FE8000 +6531:202010201020FDFE00200820882089FC48844888504850501C20E05041880606 +6532:10101010FE1010FE28104410FEFC044474445444542874285410042814440982 +6533:11FC100410FCFE0411FC1000FDDE449247DE28082BFE110818A8241043FE8000 +6534:01000100010001FC0100010001003FF01010082004400280010006C01830E00E +6535:0400040004000FFE08101010302048208440028001000280044008203018C006 +6536:084008404840488048FE49084A88488848885850685048200850088809040A02 +6537:00400040FE40208020FE210842887C8804880450045004200450048829041202 +6538:082008200820103E12443244524492A412281228121012101228104810841102 +6539:00400040FC8004FE0508050806887C8840884050405044205850608841040202 +653A:004000407C40448044FE4508468844887C884050405040204450588861040202 +653B:004000400040FE8010FE1108128810881088105010501E20F050408801040202 +653C:00407C401040108010FE11081288FE8810881050105010201050108811041202 +653D:002014201220123E214421444044BEA41228122812101210222822484A848502 +653E:204010400040FE8020FE21083E88248824882450245024204450548889040202 +653F:00200020FF20083E0844084448444EA448284828481048104F28F04800840102 +6540:1040104020407C8044FE4508468844887C8844504450442044507C8845040202 +6541:1020102010201E3E1020102010207DFC44844488444844507C20445001880606 +6542:1020102020203F3E414481443D4425A4252825283D102510012801480A840502 +6543:0020FE208220823E8244FE44904490A4FF289028901088108928A528C3448182 +6544:0040FC400440688010FE0908FE88128834883050505050209050108851042202 +6545:1040104010401080FEFE1108128810887C8844504450442044507C8845040202 +6546:08100810141E22104110BEFC004400443E4422282228221022103E2822440082 +6547:08100810FF900820083E7F44492449244D244A281C282A10492888A808440882 +6548:102008200020FF3E00442444424481A424281428081014102228424880840102 +6549:104010409440548058FE1108FE88308838885450545090201050108811041202 +654A:081008100E10081E08100810FEFC0044084408444A2849288910082828441082 +654B:204020403C404480C4FE290812882888448882507C504420445044887D044602 +654C:04200E203820083E0844FF44084408A43E2822282210221022283E4822840102 +654D:081008101410221E4110BE1008FC08447F4408442A2829284910882828441082 +654E:0240644018402480D2FE1108FE882088FE88445088500F20F850088829041202 +654F:402040207F20803E7E44424452444AA4FFA8422892108A10FF28024814840902 +6550:00207F204020403E5E44404440447FA4502851285A1054105228912898441082 +6551:1040144012401080FEFE11081088928854881050385054209250108851042202 +6552:1210121012102FA02ABE6AC46AA4AFA42AA42AA82AA82F902228222822442282 +6553:004028402440428080FE7D084688448844887C502850282028502A884D048A02 +6554:0020FF201020103E7E4422442244FFA4002800287E104210422842287E444282 +6555:08200820FFA0083E08447F44494449A47F2808281C102A104928884808840902 +6556:0820082008207F3E08443E440844FFA410281E281210121022282A4844848102 +6557:00407C40448044FE7D08450846887C88448844507C5000202850248845048202 +6558:082008201420223E4144BE44084408A47F2808282A1029104928884828841102 +6559:082008207EA0093E0A44FF4408447EA4242848288F1078100828084828841102 +655A:44402440284000807CFE4508468844887C882850285028202A504C8889040202 +655B:082008201420123E214440C4BE4400A411280928491022102228074878842102 +655C:082008201420223E514488447E4402A4142808282A10A110A128A5281C440082 +655D:0810491029102A20083E7F44492449245D246B28492849104928412845444282 +655E:0820492029202A3E08447F44414441A45D285528551055105D28412845444282 +655F:1420142014207F3E5544554455447FA4552855285510FF902428224842848102 +6560:0010F7101110551E2210551089FC10440044F744112855282210552889441082 +6561:00107E104210421E7E10421042FC7E4420447F44952825284910912825444282 +6562:00207E200220043EFF44224422443EA422283E28221022102F28F22842440282 +6563:242024207E20243E2444FF4400447EA442287E2842107E10422842284A444482 +6564:00107F104910491E7F10491049FC7F440844FF441C282A284910882808440882 +6565:0810091049104A1E8810141022FC49448844494449288A281410222841448082 +6566:10200820FF20003E7E4442447E4400A47E28042808100F10F828084828841102 +6567:081008107F1E1410221041FCFF4402447A444A284A287A104A1002280A440482 +6568:102008207F20003E22441444FF4400A400283E282210221022283E2822440082 +6569:511029102A100020FFBE80C401247E24042408280F28F8100828082828441082 +656A:0020F7201120553E22445544994400A4F7281128551022105528894810840102 +656B:082010207E20423E7E4442447E4410A40828FF2820103E10222842484A848502 +656C:22202220FFA0223E40447F44414481A47D28452845107D10452801280A440482 +656D:00207E2042207E3E42447E440044FFA440287F2895102510492891482A844502 +656E:02100F107810081E0810FF1028FC4B44494449446B28492849107F2841440082 +656F:0010FE108210FE1E8810FF1088FCA544C3440044FE288228FE108228FE448282 +6570:082049202A20083EFF442A44494488A41028FE2822104210642818283444C282 +6571:0810491049107F1E0010FF1000FC7F44414441447F28422824100F28F0444082 +6572:10100810FF10001E7E1042107EFC0044FF448144BD28A528BD10812885448282 +6573:0820492049207F3E0044FF4400447FA4412841287F10421024280F48F0844102 +6574:08200820FFBE08447FA449247F282A104928884600007FFC010011F81100FFFE +6575:102008207F20223E14447F44414449A47F2849285D10551055285D2841444382 +6576:0210E210BFD0A220AFBECAC4AFA4AAA4AFA4A228A728CA909268822882448282 +6577:0A200920FFA0083E7F4449447F4449A47F2849281010FF9020283E2842448682 +6578:08107F104910FFA0493E7F4408247F2449247F281028FF10212872280C44F382 +6579:082008200F20083EFF448144064478A449282A28FF1018102C284A4888840902 +657A:0010FF90801E9F10911091FC9F448044BBC4AAA8AAA8AA90BB908028FFC40082 +657B:10001FE020207FF8A30824881FF010101FF010101FF008001FF8282007C0F83E +657C:0810FF9008107F1E00107F1041FC7F442244FFC400287F28411041287F444182 +657D:061078101010FF9E22105D1094FC1C4400447F4441285D2855105D2841444382 +657E:22101410FF9008207F3E0844FFA449242A24FFA800287F10412841287F444182 +657F:061078101010FFA0223E5D4494A41C2400247F2841285D1055285D2841444382 +6580:00107F10551E55107F1020FC7F4491447D44552855287D1011107D2805440282 +6581:00207F2055207F3E08447F440844FFA4222814287F100810FFA8084808840902 +6582:082008201420223E4144BE44004400A477285528551077102228222855448882 +6583:49202A3E7F4849485DA86B10492841460000FFFE10803E9842E024841884E07C +6584:08203E3E08447FA82A10492808443FFE20802FFC249024902AA851C446B0988E +6585:34104B105510631E55106B10557CFFA480A47E2404280F28F810082828441082 +6586:34104B1055106320553E6B445524FFA480A47E2804280F10F828082828441082 +6587:020001000100FFFE10101010082008200440028001000280044008203018C006 +6588:020001007FFC0820044003801C70E00E0FE000400080FFFE0100010005000200 +6589:020001007FFC0820044003801C70F01E10101FF0101010101FF0101020104010 +658A:020001007FFC0820044003801C70E00E3FF808200FE008200FE0083EFFE00020 +658B:020001007FFC0820044003801C70E00E1FF0020004003FF82488248824A82010 +658C:0010201411D20012FC100BFE08104890289012D012902A902A8A4AEA87060202 +658D:01007FFC0820044003801C70E00E1FF010101FF010101FF010101FF00842F03E +658E:020001007FFC0820044003801C70E00E17D0101017D011101590255029104010 +658F:0040202011FC0104FD0409FC0904490429FC1120112229142908494481820100 +6590:04407C7C044004403C78044004407C7C04400100FFFE0820044003801C70E00E +6591:00000200F93E21082FC820882488FA8822BE210821083A88E2884448087E0000 +6592:0040202011FE0102FD0209FE0900490029FE11AA11AA2AFE2AAA4AAA84A20086 +6593:0200417C25040444FDF4144415F41554957455D4255425F454E455548444044C +6594:20201020FEA0052C6924112429ACD52411247DFC55247C5010501C88E5044202 +6595:03DE225213DE0252FFDE0A220AFA4A222AFA12AA12FA2AAA2AFA4A7282AA0226 +6596:01007FFC082007C01830E7CE244837D82448FFFE90121FF010101FF01010FFFE +6597:0040044002400240104008400840004000FE7F40004000400040004000400040 +6598:1010101010901E5012102290225052108A1E05F0041008100810101020104010 +6599:080808884A482A482C080888FE4818481C082A0E2AF848088808080808080808 +659A:1020102024487EFC224400007FFE4442824410400840007EFFC0004000400040 +659B:100810883C4824484808BE882A482A483E082A0E2AF83E082A084A0842088608 +659C:08080848142822284108BE48082808287F0E08782A0829084908880828081008 +659D:00003E7C224422443E7C00007FFE4442824410400840007EFFC0004000400040 +659E:080828484B28492849086B48492849287F0E4978080814081208210841088008 +659F:22082248FF2822283E0822483E282228220EFF7840085408620840087E080008 +65A0:22082248FFA822287F082248FFA808287F0E49787F084908FFC8410845084208 +65A1:102010201050FE8811047C1244907C5045107C90101EFEF01010101010101010 +65A2:220822487F2822282208FFC808287F28490E7F7849087F080008220841088088 +65A3:00087F48552855287F0820487FA890A87C8E54F854887C881288FE8802880108 +65A4:001000F81F001000100010001FFE104010401040104010402040204040408040 +65A5:001000F81F001000100010001FFE1040104011C0106010502048204040408040 +65A6:0200070438782040204020403F7E244824482448244824482448448844888108 +65A7:044008201850248803000CC03030C0EE1F00100010001FF81080108020804080 +65A8:0408241C24E0248024803C8004FE0488FC882488248824882508450846088408 +65A9:2008201C21E0FD004100510091FEFD10111011101D10F1105110121012101410 +65AA:2000200440787E40824002407A7E4A484A484A487A484A480248028814880908 +65AB:0008001CFCE01080108020803CFE64886488A488248824883D08250822080408 +65AC:1008101C10E0FE8010807C8054FE7C9054907C901090FE901090111011101210 +65AD:0400040455784E4044407F40447E4E48554865484448444840487F8800880108 +65AE:240024047E7824402440FF40007E7E48424842487E48424842487E8842880108 +65AF:220022047F78224022403E40227E22483E4822482248FF480448228841888108 +65B0:100008047F78004022401440FF7E084808487F4808482A484948888828881108 +65B1:100010047D7812401440FF40107E20487E48A24822483E48224822883E882308 +65B2:000077045578554077401440147E7748414841487748144814481F88F0884108 +65B3:22002202FFBC22203E2008207F3E49247F2408247F2408247F2408440F44F084 +65B4:080049022A3CFFA02A20492088BE4124412477A49124552427A4414481440184 +65B5:10006F044578554069404B40107EFFC8144877484148774814481788F8882108 +65B6:00000DFC7154415441FC40807DFC4A4449F44954495449F4484449F448148808 +65B7:0882509C5D5049D054905DDE44547FD4489450945D5449D454945DD444647FC4 +65B8:7FC2405C7FD052504A90525E5FD455545FD464545F5455545F544454BF640084 +65B9:020001000100FFFE04000400040007F004100410041008100810101020A04040 +65BA:202010200050FE50208821043E02248824882488248824884488550889080208 +65BB:208010800080FEFC210022003CF02490249024902490249244925512890E0200 +65BC:202010200020FE50205020883D04260224602410240024C04420541088080000 +65BD:2080108010FE0120FE202120212C3D7427A425242534252A2522450254FE8800 +65BE:208010800080FEFE212022203C2025FC25242524252425244534552888200020 +65BF:2080108010FE0100FE0020FC20043C08241025FE241024102410441054508820 +65C0:202010200048FE8421FE20023C20242024A824A4252425224622542088A00040 +65C1:020001003FF8082004407FFE420281043FF80400040007F00810081010502020 +65C2:2080108010FE0100FE0C20F020803C80248024FE248824882488450855088A08 +65C3:2080108010FE0100FE0020FC20843CA42494248425FE24842484450455148A08 +65C4:2080108010FE0100FE1C21E020203C3C25E02420243E27E0242044225422881E +65C5:2080108010FE0100FE0C20F020903C902492249424882488248444A454C28880 +65C6:2080108010FE0120FE2021FE20203C2025FC2524252425242534452854208820 +65C7:2080108010FE0100FE10201020FE3C92249024FC24A424A424A8451055288A46 +65C8:2020101001FEFE20204820843DFE240224A824A824A824A844A854AA892A0206 +65C9:01107FFC01003FF821083FF821083FF821080080FFFE08000FF810082028C010 +65CA:2080108010FE0100FE0020FC20403C402478244824A82498248844AA54CA888E +65CB:2080108010FE0100FE0021FC20243C2424A024A024BC24A024A04560553E8A00 +65CC:2080108010FE0110FE10209020FE3C902510241024FE24102410441055FE8800 +65CD:2080108010FE0120FE20205020883D242612241025FC24042488445054208810 +65CE:2080108010FE0100FE0020FC20843C8424FC248024A424A824B0452255228A1E +65CF:2080108010FE0100FE80208020FC3CA02520242027FE24202450445054888906 +65D0:2100110011FE0200FC50205022543D58245024D825542652245044505492890E +65D1:2020102011FC0050FC88210423FE3C0825E82528252825E82528440854288810 +65D2:2100110011FE0240FC2021FE20403C8425FE240224A824A824A844AA552A8A26 +65D3:2100110011FE0220FD2420A820203DFC250425FC250425FC2504450455148908 +65D4:40102010007CF71441FE4114727C5210577C511051FE551052105300B4FE0800 +65D5:10100810FF2820443E822210220842204A10840800007C8844B044C47C84447C +65D6:2100110011FE0200FC2021FC20503C8827FE240825E8252825E8440854288810 +65D7:2100110011FE0200FC8821FC20883CF8248824F82488248827FE445054888904 +65D8:2110109413D20012FA50219027FE38102BD22A522A542BD42A4A4A4A4BD69822 +65D9:203C13E0112400A8FDFE20A821243E0225FC2524252425FC2524452455FC8904 +65DA:210011FE120001FEFC5021FC21543DFC240025FC240027FE242044A855248A64 +65DB:2100110011FE0200FC1C23E021243CA827FE2524260225FC252445FC552489FC +65DC:210011FE122004FCFC0021FE21023D7A254A25FE248424FC248444FC540089FE +65DD:208010FE11300248FCB4210221FE3DAA257225FE240024FC248444FC548488FC +65DE:2080108010FE0100FE44202822FE3D2024542728255C252A254A452856908C7E +65DF:2100110001FEFE002540224C3A642B4C2A642AA42BAC2AA44FFE689091080204 +65E0:00003FF002000200020002007FFC0480048004800880088010842084407C8000 +65E1:00003FF002000200420042007FFC0480048004800880088010842084407C8000 +65E2:00007DFC442044207D20452045FE7C204020483044504A5052926092410E0200 +65E3:100021FC7C2044207D2045207DFE0020402040307C50405040924C92710E0200 +65E4:00007DFC442044207520552055FEFE208220BA30AA50AA50BA9282928B0E8600 +65E5:00001FF0101010101010101010101FF01010101010101010101010101FF01010 +65E6:00001FF010101010101010101FF010101010101010101FF000000000FFFE0000 +65E7:200023FC2204220422042204220423FC2204220422042204220423FC22042000 +65E8:2000207023803C08200820081FF800001FF0101010101FF0101010101FF01010 +65E9:00001FF0101010101FF0101010101FF001000100FFFE01000100010001000100 +65EA:002000207C2044204420442047FE7C2044204420442044207C20442000200020 +65EB:000000007DFC44444444444444447C4444444444444444847C84450402280410 +65EC:080008000FFC100410042FC4484488440FC4084408440FC40844000400280010 +65ED:200020F820882088FC8824F8248824882488248824F8248A2402440243FE8000 +65EE:020002003FE0042008223022C01E00001FF0101010101FF0101010101FF01010 +65EF:00001FF0101010101FF0101010101FF0020002007FE00420042008221022601E +65F0:000000FC7C2044204420442044207DFE44204420442044207C20442000200020 +65F1:1FF0101010101FF0101010101FF000003FF801000100FFFE0100010001000100 +65F2:00001FF0101010101FF0101010101FF001000100FFFE0280044008203018C006 +65F3:004000407C8044FC4504460444047D0444844444444444047C04440400280010 +65F4:000001FC7C2044204420442047FE7C2044204420442044207C20442000A00040 +65F5:00001FF0101010101FF0101010101FF00000010021082108210821083FF80008 +65F6:000800087C08440845FE440844087C0844884448444844087C08440800280010 +65F7:00400020782049FE490049007900490049004900490079004900020002000400 +65F8:000001F87C1044204440448045FE7C9244924492451245227E22444200940108 +65F9:01002108210821083FF80100FFFE00001FF0101010101FF0101010101FF01010 +65FA:000007FC784048404840484078404BFC4840484048407840484000400FFE0000 +65FB:1FF0101010101FF0101010101FF0020001007FFC08200440038004401830E00E +65FC:004000207C2047FE4488448844887C8844884450445044207C50448801040602 +65FD:0020002078204BFE4820492449247924492449FC4824482078224822001E0000 +65FE:01000100FFFE010021083FF80102010200FE00003FF820083FF820083FF82008 +65FF:008000807C8045FC4520462044207C2047FE4420442044207C20442000200020 +6600:004000407C8044FC4504460444847C4444444414442444447D84440400280010 +6601:0020002078204BFE4820482049FC792449244924492449347928482000200020 +6602:3FF820083FF820083FF800000C0070FC4084408440844C847094408800800080 +6603:00001FF010101FF010101FF000003FFC20802080214021402220441048089006 +6604:0008003C7BC04A004A004A007BF84A884A884A884A507A504A20045004880906 +6605:000003FC7884488848884890489C788449444944492849287A104A2804440182 +6606:00003FF0201020103FF0201020103FF00000208020843E9820E020842684387C +6607:00001FF010101FF010101FF000000720782008200820FFFE0820102010202020 +6608:002000107C1044FE4482448244827CFE44824480448044807C80450001000200 +6609:004000207C2047FE4480448044807CFC44844484448444847D04450402280410 +660A:00001FF010101FF010101FF0000000003FF801000100FFFE028004401830E00E +660B:3FF801000200FFFE044008203018C0061FF0101010101FF0101010101FF01010 +660C:1FF0101010101FF0101010101FF000003FF8200820083FF8200820083FF82008 +660D:000001FC7D0445044504450445047DFC45044504450445047D0445FC01040000 +660E:000000FC7C844484448444FC7C844484448444FC7C8444840104010402140408 +660F:00783F80208020803FFC20402822301A20061FF0101010101FF0101010101FF0 +6610:001000907C9044884508450446047DFA44884488448844887D08450802280410 +6611:002000207C5044504488454446227C20440045FC440444087C08441000100020 +6612:01000100790049FC4AA44CA448A4792449244A444C44488479044A0404280010 +6613:0FF0081008100FF0081008100FF0040008001FFC224442440484088411280210 +6614:044004403FF804400440FFFE000000001FF0101010101FF0101010101FF01010 +6615:0004000E7CF044804480448044FE7C8844884488448844887C88450801080208 +6616:00100090789048884888492449247A224C4048404888488479044BFE01020000 +6617:00001FF0101010101FF0101010101FF0020001007FFC00000440082010102008 +6618:00001FF010101FF010101FF002000100FFFE040007F004100810101020A04040 +6619:00001FF010101FF010101FF000003FF800000000FFFE0400082010103FF81008 +661A:01000100FFFE01002288145008203018DFF6101010101FF0101010101FF01010 +661B:000001FE7D004500450045FC45047D044504450445FC45007D00450001FE0000 +661C:00001FF010101FF010101FF00000FFFE08001FF8224844480888110822280410 +661D:104010403E5022485444084017FE2000DFF0101010101FF0101010101FF01010 +661E:000003FE7820482048204BFE7A224A224A524A4A4A8A7B024A020202020A0204 +661F:00001FF010101FF010101FF0010011001FF8210041001FF0010001007FFC0000 +6620:00200020782049FC492449247924492449244BFE482078504850008801040202 +6621:002000107C1045FE4420442044447C8445F84410442044447C8245FE00820000 +6622:002000207D2445244524452445FC7C2044204524452445247D24452401FC0004 +6623:002000207C5044884504461244207C4045884410442044447D88441000600380 +6624:002000207C5044504488452446127C1045FC4404440844887C50442000100010 +6625:010001007FFC01003FF80200FFFE082010102FE8C82608200FE0082008200FE0 +6626:00001FF010101FF010101FF002007FFC044008203458C4460440044008401040 +6627:00200020782049FC4820482048207BFE487048A848A8492479244A2200200020 +6628:01000100790049FE4A804A804C8078F848804880488048FC7880488000800080 +6629:0040004078404FFE4840484048407BFC484048E049504A487C46484000400040 +662A:00001FF010101FF010101FF0082010103FF808280820FFFE0820102020204020 +662B:00800080790049FC4A044C0449E479244924492449E449247804480400280010 +662C:00003FF820083FF820803FFC20402C243014200C1FF010101FF010101FF01010 +662D:000003FC788448844884490449147A084C0049FC490449047904490401FC0104 +662E:00001FF010101FF010101FF0004000407DFC1044104410841C84E10442280410 +662F:1FF0101010101FF0101010101FF00000FFFE0100110011F811002900450083FE +6630:00001FF010101FF010101FF0000000007FFC0100110011F811001100FFFE0000 +6631:1FF0101010101FF0101010101FF00200010001007FFC0000101008200440FFFE +6632:0090009078904BFC489448947BFC4A904A904BFE48927892491A011402100410 +6633:004000407A404A404BFC4A404C4078404FFE484048A048A079104A0804040802 +6634:00001FF010101FF010101FF000000C0070FC448444845C846494488810806080 +6635:000001FC79044904490449FC49007940494449484970494079424A42023E0400 +6636:08000400027C3C44044404C4757C164416441544257C248044408430140E0800 +6637:00001FF0101010101FF0101010101FF000003FF82448244824482448FFFE0000 +6638:004000407C7C44844588465044207C5044884706446044107C0844C000200010 +6639:00400020781049E0482248347BB848B048A848A8492879244A24042200A00040 +663A:00001FF010101FF010101FF000007FFC01003FF8210822882448282820082018 +663B:00001FF010101FF010101FF000007CFC10841084108410841E94F08840800080 +663C:00001FF8100810081FF81040102020102FE848268FE008200FE000007FFC0000 +663D:00900088788848804BFE48A048A078A448A44928492849327A224A62049E0800 +663E:00001FF0101010101FF0101010101FF0044044442444144814500440FFFE0000 +663F:00200010781049FE490049107910491049104920492879244A4402FE04420800 +6640:0090009078904A9249944898489079984A944C9248904890791249120212040E +6641:00001FF0101010101FF0101010101FF0244814500C601450644808421042603E +6642:002000207C2045FC4420442047FE7C08440845FE440844887C48440800280010 +6643:00001FF010101FF010101FF00100111009200100FFFE0440044008421042603E +6644:004000447A444948495048404FFE7890489048904890489279124912020E0400 +6645:000003FE7800480049FC4904490479FC4904490449FC49047800480003FE0000 +6646:002000207DFC44204420442047FE7C004420442045FC44207C20442003FE0000 +6647:002000207BFE4850488849047AFA48004BFE4840488079FC4804000400280010 +6648:004000207C2047FE4400448845047E0244884488445044507C20445000880306 +6649:00007FFC0810102024487EFC02040000FFFE00001FF010101FF010101FF01010 +664A:000003FE7840488049104A084BFC7844484048404BFC48407840484007FE0000 +664B:00007FFC0440244814500440FFFE00001FF0101010101FF0101010101FF01010 +664C:0040004078804BFC4A044A044AF47A944A944A944A944AF47A044A0402140208 +664D:000001FE7D024502457A450245027D7A454A454A454A457A7D024502010A0104 +664E:01100110791049104BFC49107910491049104FFE480079104908020804040804 +664F:00001FF010101FF010101FF001007FFC42040200FFFE08201C4003800C707008 +6650:0020001078104BFE48204842488479F84810482248C44B087810482800C40302 +6651:00001FF010101FF010101FF0020004003FF8200827C82448244827C820282010 +6652:000007FE7890489048904BFC4A947A944A944A944A9C4B047A044A0403FC0204 +6653:0080008078BC4BC04850482448D47B0C48004BFE4890489079124912020E0400 +6654:00900094791449184B104D324952790E492048204BFE48207820482000200020 +6655:1FF010101FF010101FF000007FFE42029FF4040009001FF001007FFC01000100 +6656:000003FE7A024C4448404BFC488078A0492049FC482048207BFE482000200020 +6657:0040004078A049104A884C4649F07810482048404BF84A087A084A0803F80208 +6658:000001FC7D0445FC450445FC44007C0045FC4420442047FE7C20442000200020 +6659:00400040788849044BFE4802488879444A4248F849884A507820485001880606 +665A:0080008079F84A084C104BFC4A447A444A444BFC48A048A079224922021E0400 +665B:000003F87A084A084BF84A087A084BF84A084A084BF87920492002220422181E +665C:00001FF010101FF010101FF004407FF801083FF821003FFC0304051419086100 +665D:01003FF80108FFFE01083FF801007FFC00003FF820083FF820083FF80000FFFE +665E:01840068783048C84B0448407BFE48A049204BFC4D2479244934012800200020 +665F:1FF010101FF010101FF000883FFC208020883E88225022502A244454418C8604 +6660:00280024782448204BFE4A207A244A244BA44AA84AA87A904A9205AA04460882 +6661:004800447BFE484048404BFC4A447A444BFC4A444A444BFC7A444A4402540208 +6662:080C08F07E8008800EFE788808882908120800001FF010101FF010101FF01010 +6663:0104010E793049204FE04920793E496449A44F24492479244924012405440284 +6664:000003FE7840484049FC488448847BFE4800480049FC49047904490401FC0104 +6665:004000207BFE4A024C0449F8780048004BFE48904890789049120112020E0400 +6666:0100010079FC4A004DF84908494879284FFE49084A484A287BFC480800500020 +6667:00200120792049FC49204A2078204BFE4800480049FC79044904010401FC0104 +6668:1FF010101FF010101FF000003FFC20002FF820003FFE2908289048604A188C06 +6669:0080008079F84A084C104BFC4A447A444A444BFC48A048A079224922021E0400 +666A:0090009078904BFC4A944A944A947BFC4A944A944A944FFE7800489001080204 +666B:00400040787E48404BFC4A044BFC7A044BFC4A4448404FFE7840484000400040 +666C:004000207BFE48004888488849547A22480048204BFE48207820482000200020 +666D:000003FE7A224A224AFA4A227A224BFE4A024AFA4A8A7A8A4AFA0202020A0404 +666E:082004407FFC044024481450FFFE00001FF0101010101FF0101010101FF01010 +666F:1FF010101FF010101FF00100FFFE00001FF0101010101FF00100210845040200 +6670:0200020CF27092409F409240927EF64897489AC89A489248F248924802480288 +6671:0020012279224A24485048887B0448224820492449247A284850008801040602 +6672:000000407B9C4A044A044B9C7A044A044BFC489048907890489001120212040E +6673:080C08F07E8018802CFE2A884888888809081FF0101010101FF0101010101FF0 +6674:002000207BFE482049FC48204BFE780049FC490449FC490479FC490401140108 +6675:104008403E7E228823503E20205841869FF0101010101FF0101010101FF01010 +6676:0FE0082008200FE0082008200FE000007EFC428442847EFC428442847EFC4284 +6677:1FF010101FF010101FF008401F6022505448084037FEC0001FF0101010101FF0 +6678:1FF010101FF010101FF000207F20043E044427A42428242824102F28F0444082 +6679:01FC010479FC4904490449FC7800490049FE4A4A4C4A789249120222004A0184 +667A:20003E7C48440844FF441444227C40001FF0101010101FF0101010101FF01010 +667B:004000807BFC49104A484C464BF87A484A484BF84A484A487BF848420042003E +667C:00800040F7FE94029A04920093BCF4A494A496A499349128F22292220422081E +667D:01100110F110911097BC91109110F33893B8955495549992F110911001100110 +667E:004000207BFE4800480049FC49047904490449FC482048A879244A2200A00040 +667F:00FC00847C8444FC4484448444FC7C0045FE4502450245FE7D02450201FE0102 +6680:0090008879004A7E4C90489049107B104D7E49104910491079104910017E0100 +6681:0020002079FC482048A848887BFE488848004BFE4890789049120112020E0400 +6682:100CFEF0208048807EFE08880E88F9084A081FF8101010101FF0101010101FF0 +6683:00001FF010101FF010101FF004407C7C044004407C7C04400440FC7E04400440 +6684:004000207BFE4A024C0449FC480079FC490449FC490449FC7904480003FE0000 +6685:0100013CF100910091BC95649524F53C952491249124913CF1249100017E0100 +6686:02100110F11097BE9228924893AAF2AE92BA92EA92AE92A8F4AA94A209A2101E +6687:000007BCF4849484948497BC9400F40097BC9424942497A8F410942804440482 +6688:1FF010101FF010107FFC41043FF801001FF011101FF011101FF00100FFFE0100 +6689:000003FE7A2248204BFE482079FC492449FC492449FC78204BFE002000200020 +668A:000003FE7C20444045FC450445047DFC450445FC450445047DFC440000880104 +668B:00207F20413E7F4448A47F2448284510532861461FF010101FF010101FF01010 +668C:001003D478584A52498C488849047AFA482048204BFE48207850488801040202 +668D:000001FC7D0445FC450445FC44807DFE46224522455245027DFA440200140008 +668E:008800887BFE488848A8482049FC7924492449244BFE48207850488801040202 +668F:004000447BF4484848504FFE4840788049F84B084D0849F87908490801F80108 +6690:0040004079FC48844BFE480049FC790449FC48204BFE48207A204BFE00200020 +6691:1FF010101FF010101FF002001FD00220FFFE03000FF03810CFF008100FF00810 +6692:000001FC790449FC490449FC7820492049FE4A20482079FC4820002003FE0000 +6693:00407F40127E0C88FF4819482A504820A850108C1FF010101FF010101FF01010 +6694:002000207BFE482048204BFE7A8A4A524AFA4A224A227AFA4A220222022A0204 +6695:002000207BFE482049FC492479AC4974492449FC4820787048A8012402220020 +6696:003C07C07A44492848004BFC788048804FFE490049F87A884A50042008D80306 +6697:008000407BFC4800490848904FFE780049F84908490849F87908490801F80108 +6698:000001F8790849F8490849F878004BFE490049FC4A547C944924024400A80110 +6699:00400040F7FC904093F8908097FCF110920895F691109110F1F09110011001F0 +669A:0008003C7BC048044A44492879FC4A2048204BFE482079244924012401FC0004 +669B:0108008878904BFC484049F848407BFE4880490049FC4A207C20482003FE0000 +669C:20201010FEFE00004444242428280EFEF00000001FF010101FF010101FF01010 +669D:000003FE7A02480049FC490449FC790449FC484048204BFE7800488801040202 +669E:0020004079FC490449FC490479FC490449FC48204BFE787048A8012402220020 +669F:002001247924492449FC48007BFE480049FC4904490479FC4888005003FE0000 +66A0:1FF010101FF010101FF00100FFFE10101FF000007FFC40044FE448244FE4400C +66A1:0090008879044A424C8849FC780448004BDE48424A52794A4A520042014A0084 +66A2:100011F811087DF8550855F87C0057FE550055FC7E5454941124124410A81110 +66A3:0100010079FC4A004DF848007BF848884AA849C84FF8788A49CA06AA00860082 +66A4:0020004079FC490449FC490479FC48404BFE488849247A224DFC002000200020 +66A5:000001FC790449FC490449FC78204BFE4A0248404BFE78884990006000980304 +66A6:00003FFE221022103FBE27182AB432522210200027F8240827F8440847F88408 +66A7:000E03F078444A2449084BFE7A4248404BFE488048FC79444928021004680186 +66A8:7DFC44207D2045FE7C5048525492650E1FF010101FF010101FF00000FFFE0000 +66A9:010001107BDC4A544D544A8879084AF44C0248004BFC78404950024805440080 +66AA:008800887BFE4888488848F878204BFE4A224B324AAA7B764A220222022A0224 +66AB:08047F7808407F40497E7F4849487F4808487F4808881FF010101FF010101FF0 +66AC:08203E2008F87F282228496A3E2A08567E8200001FF010101FF010101FF01010 +66AD:0020004079FC490449FC490449FC7820492448A8492448207BFE482000200020 +66AE:04407FFC04401FF010101FF010101FF00400FFFE10102FE8C8260FE008200FE0 +66AF:008800887BFE4888480049FC790449FC490449FC48207BFE4850008801040202 +66B0:01240124F22494249954914A9292F6109A109250925C9250F25092B0029E0300 +66B1:000003FE7A484A484BFE4A487A204BFE4A404AFC4B447A444A7C020003FE0000 +66B2:002001FC788848504BFE480049FC790449FC490449FC48207BFE482000200020 +66B3:008803DE788849DC48884BDE788848004BFC4804480479FC4804000403FC0004 +66B4:1FF010101FF010101FF008207FFC0820FFFE08203118C9260540092015102208 +66B5:008800887BFE488848F8482079FC492449FC482049FC78204BFE005000880306 +66B6:02100110F11097BE9240920093BEF28A928892A892AE92A8F4A895A8085E1080 +66B7:002003FE782049FC492449FC792449FC48224BFE48087BFE4908008800280010 +66B8:00400040F7FC90A09514920897FCFA0A93F8920893F89040F248944409440080 +66B9:07F8440827F8240807F80240E7FC2C4037F8244027F8244027FC54008FFE0000 +66BA:000003DE7A524A524BDE480079FC492449FC492449FC78204BFE002000200020 +66BB:000001FC790449FC490449FC78204BFE480049FC490479FC4820012402220060 +66BC:49202A3E7F4849485DA86B10492841461FF0101010101FF0101010101FF01010 +66BD:0020012478A84BFE48A849244A227904490449DE4A444D54789E490402040404 +66BE:02080108F7C89010979E949497A4F01497949094911491C8F708911405240242 +66BF:002003FE782049FC480049FC790449FC48884BFE480079FC4904010401FC0104 +66C0:002003FE782049FC48004BFE7A0249FC480049FC490479FC4904008803FE0000 +66C1:10007EFC42107E9042FE7E3040507C92410E5FF070101FF010101FF00000FFFE +66C2:0088008879FC488848884BFE782049FC492449FC492479FC4800008801040202 +66C3:00100210797C481448FE48144B7C799249544938495449927930490002FE0400 +66C4:008803FE7888480049FC48A848A87BFE48A848A849FC48207BFE482000200020 +66C5:1FF010101FF010101FF004407FFC04403FF809207FFC09203FF801007FFC0100 +66C6:3FFE2000218C2E7022103FBE27182AB43252221027F8240847F8440887F80408 +66C7:1FF010101FF010103FF801007FFE41029D7400003FF80000FFFE10103FF80008 +66C8:002001FC788848504BFE480079FC492449FC492449FC782049FC002003FE0000 +66C9:0020002079FC48204BFE49087B9C490849884E3E48007BFE489000900112020E +66CA:009007FC78944BFC4A904BFE79124BFA4D0E49F8490879F8490801F800900108 +66CB:000003FE78504BFE4A524BFE780049FC490449FC490479FC482003FE00200020 +66CC:00F87C8844F87C8844F87C8802A801107FFC482410102FE8010001007FFC0000 +66CD:004001FC790449FC490449FC790449FC4820492448A87924482003FE00200020 +66CE:000001FC795449FC482049FC78204BFE4888485049FC78204BFE002000200020 +66CF:1FF010101FF010101FF0210027DE545297D4E458245457D29512F49A25544610 +66D0:0FE008200FE008200FE07C7C44447C7C44447D7C11001FF821005FF00100FFFE +66D1:1FF010101FF010107FFC44447C7C44447D7C06C01930E64E01800E2000C01F00 +66D2:01080208F7C8945097DE946497D4F214911497D4921493C8F2489454055408A2 +66D3:3FF820083FF820083FF811101FF041047FFC0200FFFE09203FF8C5460BA01110 +66D4:02880288F7E89290941E97E49454F8549754955495549748F548905402940122 +66D5:010001F87A084FFE4A884B247BFE4A004AFC4A004AFC7A004AFC048404FC0884 +66D6:003C03C0F0449224910897FE9442F2A4928A947A908090F8F10892900060079E +66D7:00500252795448504BFE488878504BFE482049FC48207BFE48A8012406220020 +66D8:000001FC78204BFE4A2249AC782049AC48004BFE482079FC495401540154010C +66D9:000003FE7A524A524BFE482449FC78284BFE482048FC49847AFC488400FC0084 +66DA:011007FCF11097FC940493F89000F7FC9080914496A89170F6A8912606A00040 +66DB:003C07C0F0409FFE904097FC9554F4E497FC904097FC9040FFFE900005240892 +66DC:000007BCF08494A4929494A49120F21097FC9A2093FC9220F3FC922003FE0200 +66DD:03F80208F3F8920893F8911097FCF1109FFE911092489554F0E09150024800C0 +66DE:000003FE7A484BFE4A484AFC7AA44AFC4AA44AFC4A207BFE4B2A057A050A0906 +66DF:1FF010101FF010107FFC44447C7C44447FFC20002FF820003FFC24484430860E +66E0:00400020F7FE948895FC948897FEF42095FC952495FC9524F5FC940004880904 +66E1:0FE008200FE008200FE07C7C44447C7C4444FFFE90121FF010101FF01010FFFE +66E2:004000207BFE4A2249FC48507A8A49FC4A8A48F8488878F84820012402A20040 +66E3:01100110F7FC911091F0920892EAF6AC92A892AA96EA9A06F00092A402520452 +66E4:07FC0040F7FE94429B5C9040975CF12093FC96209BFC9220F3FC922003FE0200 +66E5:0040007C78404BFC4A444BF07A444AFC4AA84AF84AA87AF84A0005FC05540BFE +66E6:011007FCF04093F8904097FC9000F3D4911297FE93509534F38C908A02960102 +66E7:3FF820083FF820083FF800107F1000FE3E9222923EFE00107F1455127FFE4902 +66E8:02100110F7DE9010945E928297DEF01097DE945097DE9450F7DE9450045204CE +66E9:1FF010101FF010101FF00100FFFE22883EF804403FF80440FFFE04901C60671C +66EA:000003FEF252925293FE91089154F25E97B4911E925497DEF0149554055E0010 +66EB:210447C88812F3BC20084B92F83E0380AAAAABAA00001FF010101FF010101FF0 +66EC:0FBE0000F7BC94A496B494A49040F7FE94A097FC94A497FCF51299DC091211CE +66ED:02480150F7FC940491F0911097FCF55494E497FC904097FCF0409FFE02A40452 +66EE:07BC04A4F7BC900097FE94009590F49E97D4956495D49554F5D495680BC81054 +66EF:03FE02027BFE4A924A544A927AFE4AAA4AFE4B224AFA7AAA4AFA022205FA0004 +66F0:000000007FFC40044004400440047FE440044004400440047FFC400400000000 +66F1:00003FF82008200820083FF82108210821083FF8210801000100010001000100 +66F2:04400440044004407FFC44444444444444447FFC44444444444444447FFC4004 +66F3:0100010001003FF8210821083FF8210821083FF8009000A0004201A20E1AF006 +66F4:0000FFFE010001003FF8210821083FF8210821083FF811000A00060019C0E03E +66F5:0120011001003FF8210821083FF8210821083FF8009000A0004201A20E1AF006 +66F6:080008001FF8224844480888112822101FF0101010101FF0101010101FF01010 +66F7:00001FF010101FF010101FF0080008001FFC21045284944410041F8400280010 +66F8:01003FF00110FFFE01103FF001003FF80100FFFE00001FF010101FF010101FF0 +66F9:04400440FFFE04403FF824483FF824483FF800001FF010101FF010101FF01010 +66FA:01000100FFFE01003FF821083FF821083FF800001FF010101FF010101FF01010 +66FB:1FF010101FF010101FF00000101010103EFC4210A490149008FE101020104010 +66FC:00001FF010101FF010101FF000007FFC44447FFC00003FF0082007C01830E00E +66FD:082004403FF821083FF821083FF800001FF0101010101FF0101010101FF01010 +66FE:082004403FF82108292825483FF800001FF0101010101FF0101010101FF01010 +66FF:082008207EFC0820FEFE1450228841069FF0101010101FF0101010101FF01010 +6700:1FF010101FF010101FF00000FFFE22003EF822883E9022502F20F25042880306 +6701:3E7C081048907EFC1428244A468600001FF0101010101FF0101010101FF01010 +6702:1FF010101FF010101FF00000FFFE22203E2022FC3E2422242F24F24442540288 +6703:010002800C6037D8C0063FF8292825483FF800001FF010101FF010101FF01010 +6704:1020102013FE7C2055FC55247DAC5574552455FC7C20547010A8112412221020 +6705:100011FC11047DFC110411FC1080FDFE122211222152290245FAFC0244140008 +6706:444024402840FE7E92AAD72ABA2A924AFE4A00927D1244227C2244427C944408 +6707:1010282044FEBA920092FEFE9292D69292FEFE2800487DFE44087C0844087C08 +6708:07FC040404040404040407FC04040404040407FC040404040804080410142008 +6709:02000200FFFE040004000FF0081018102FF0481088100FF00810081008500820 +670A:0000780049FC4800480078004BFE489048907890489048904892491249129A0E +670B:00003E7C2244224422443E7C2244224422443E7C22442244224442844A948508 +670C:00103C502450245024883C88250426FA24483C48244824482488448855288A10 +670D:00003EFC2284228422943E88228022FC22A43EA422A822A8229042A84AC48482 +670E:00203C202450245024883D242612241025FC3C04240824882450442054108810 +670F:00203C202524252425243D2425FC242024203D24252425242524452455FC8804 +6710:00803C80250025FC26043C0425E4252425243D2425E425242404440454288810 +6711:00487A484A484A484A487FFE4A484A484A487A484A784A004A004A004BFE9800 +6712:00203C20242025FC25243D242554258C25243D242554258C2504450455148908 +6713:00503C502450255224D43C582450245824D43D52265024502492449255128A0E +6714:4200227C2444FF440844087C4944494449447F7C094410441084208441148208 +6715:00883C482450240025FC3C202420242027FE3C20245024502488448855048A02 +6716:00403C2025FC250425043DFC2504250425FC3D20252225142508454455828900 +6717:1000087C7E44424442447E7C424442447E44407C484444445A84628441140208 +6718:00407840488849044BFE7802488849444A4278F849884A504820485049889E06 +6719:0000FE7C8244AA44A644C67C8244BA44AA44AA7CAA44AA44FE84828401140208 +671A:02000100FFFE100010001FF800007CFC448444FC7C8444FC44847C8401140208 +671B:1000087CFF44207C2044267C3844209401087FFC010001003FF801000100FFFE +671C:00403C2027FE240025FC3D0425FC240025FC3C08241027FE2420442054A08840 +671D:0800083EFFA208227F22413E7F2241227F22493E0822FFA208420842088A0904 +671E:08207FFC08200FE008200FE00820FFFE10102FE8C8260FE008200FE008200860 +671F:2200227C7F44224422443E7C224422443E44227C2244FF440484228441148208 +6720:008878884BFE488848A8782049FC4924492479244BFE48204850488849049A02 +6721:000078884A524A224A527A8A4A024BFE488879444A7A48884950482048D89B06 +6722:00007F7C48447E7C42447E7C48447F5400887FFC01003FF801000100FFFE0000 +6723:00203DFC2488245027FE3C0025FC252425FC3D2425FC242025FC442057FE8800 +6724:3E7C22443E7C22443E7C22444A9485083E7C22443E7C22443E7C22444A948508 +6725:00887AAA4ADC4C8849547A2248004BFE4A427C444BFC48444844488449149A08 +6726:00887BFE48884BFE4A0279FC48004BFE484078A24B5448B84B5448924B509820 +6727:011078904BDE48104A5E79824BDE48104BDE7A504BDE4A504BDE4A504A529ACE +6728:01000100010001007FFC03800540054009201110210841048102010001000100 +6729:0100010001000100FFFE01000100092009101108110821044104810405000200 +672A:0100010001003FF8010001000100FFFE03800540092011102108C10601000100 +672B:010001000100FFFE0100010001007FFC03800540092011102108C10601000100 +672C:01000100010001007FFC0380054005400920111021084FE48102010001000100 +672D:0880088008800880FE80088018801C802A802A804880888408840884087C0800 +672E:0100012001100100FFFE01000920092009200920112011202120411E81000100 +672F:01000120011001107FFC03800540054009201110210841048102010001000100 +6730:010001007FFC0380054009203118C1063FF80010006003801C0420041FFC0000 +6731:0100110011001FF8210041000100FFFE03800540092011102108C10601000100 +6732:1040104010401040FC4010403040384054A054A090A011101110120814041802 +6733:1000102011201120FD2011203120392055205110911012101208140818041002 +6734:0840084008400840FE40085018481C442A442A40484088400840084008400840 +6735:00000FE00820082008201020201EC10001007FFC0380054009203118C1060100 +6736:00003FF008100820083C10041004201441080100FFFE054009203118C1060100 +6737:0800080009FC0844FE44084418441C442A442A44484488840884090409280A10 +6738:1040104010401040FDFC10443044384454445484908410841104110412281410 +6739:1080108010801080FDF0109030903890549054909090109211121112120E1400 +673A:100011F011101110FD10111031103910551055109110111211121212120E1400 +673B:0804080408840884FE84088418841C842A8C2AB448C488840804080408040804 +673C:0880088008800884FE88089018A01CC02A802A804880888408840884087C0800 +673D:100013FE10401040FC801080310039FC54045004900410041004100410281010 +673E:080008000BFE0820FE20082018201C202A202A20482088200820082008A00840 +673F:01000100FFFE010001003FF821082108210821282390054009203118C1060100 +6740:00081810066001800660181861040100FFFE0100112011102108210445040200 +6741:0880084008400820FE20082018201C502A502A50484888880888088409040A02 +6742:020002003FE0042004220822111E61000100FFFE010009201110210845040200 +6743:100013FC11041104FD0410883088388854505450902010201050108811041602 +6744:1008103C11E01020FC20102030203BFE54205420902010201020102010201020 +6745:100011FC10201020FC20102030203BFE54205420902010201020102010A01040 +6746:100011FC10201020FC20102030203BFE54205420902010201020102010201020 +6747:100011FC10001000FC0013FE30403840548054FC900410041004100410281010 +6748:100013FC11041144FD2410A83088388854505450902010201050108811041602 +6749:0804080408080810FE20084418041C082A102A224842880408080810082008C0 +674A:1104112411241124FD2411243124392455245124912411241124122412041404 +674B:100011F011101110FD10111031903950555055109110111211121212120E1400 +674C:1000100013FC1090FC90109030903890549054909090109211121112120E1400 +674D:100011FC10041008FC10102030203BFE54205420902010201020102010A01040 +674E:010001007FFC0380054009203118C1060FE000400080FFFE0100010005000200 +674F:010001007FFC0380054009203118C10600001FF010101010101010101FF01010 +6750:0808080808080808FEFE080818181C182A282A28484888880808080808280810 +6751:1010101010101010FDFE10103010381055105490909010101010101010501020 +6752:1000100011FC1044FC4411443944354452445044908410841104110412281410 +6753:10401040108010FCFD0412043004390454845444904410041004100410281010 +6754:1008103C13C01040FC4010403840347E53C050409040104210421042103E1000 +6755:0820082008200820FE2009FE18201C202A202A50485088500888088809040A02 +6756:1010101010101010FDFE10103010391055105490909010501020105011881606 +6757:02000100FFFE1000100010001FF801000100FFFE0380054009203118C1060100 +6758:00003FFC200420043FFC2000208020803FFE21C022A024902888508640808080 +6759:0848084408440840FE5E09E018401C402A402A40482088220812080A08060802 +675A:10401040108010FEFD00120030FC380854105420904010801102110210FE1000 +675B:100011FC10041004FC0410FC30803880550055FC900410041004100410281010 +675C:1020102010201020FC20102033FE382054205420902010201020102017FE1000 +675D:1020102010201120FD2C113431643BA455245534912811221122110210FE1000 +675E:1000100011F81008FC081008300839F855085500910011001102110210FE1000 +675F:01000100FFFE010001003FF82108210821083FF82388054009203118C1060100 +6760:1000100011FC1020FC2010203020382054205420902010201020102013FE1000 +6761:040004000FF01820644003801D70E10E01007FFC010009201110210845040200 +6762:010001007FFC0380054009203118C10600003FF80100010001000100FFFE0000 +6763:1020102010201020FD241124312439245524552491241124112411FC10041000 +6764:1000100013FE1080FC80108030FC388454845484910411041204120414281810 +6765:0100010001007FFC0100111009100920FFFE0380054009203118C10601000100 +6766:10801080108010F8FD08110831103A1054205020905010501088110812041402 +6767:1020101010101000FDFE10803080388054805480908010801080108010FC1000 +6768:100011F810101020FC40108031FE389254925492911211221222144210941108 +6769:100013F010101010FD101110311039FC54045404900413F41004100410281010 +676A:10201020102010A8FCA410A23122392056245424902810081010102010C01300 +676B:0810081008100890FE900890189E1C902A902A9048908890089008900BFE0800 +676C:100011FC10001000FC0013FE30903890549054909090109211121112120E1400 +676D:10801040104013FCFC00100031F03910551055109110111211121212120E1400 +676E:10201020102013FEFC20102031FC392455245524912411341128102010201020 +676F:1000100013FE1020FC201040384034D051485244944410401040104010401040 +6770:0100010001007FFC03800540092011102108C106010000002488224442448004 +6771:01000100FFFE010001003FF821083FF821083FF82388054009203118C1060100 +6772:1FF0101010101FF0101010101FF0010001007FFC0380054009203118C1060100 +6773:010001007FFC0380054009203118C1061FF0101010101FF0101010101FF01010 +6774:084008400840087CFE84088819201C202A202A50485088500888088809040A02 +6775:10801080108011FCFD2012203020382057FE5420902010201020102010201020 +6776:10201020102013FEFC20112431243924552455FC9024102010221022101E1000 +6777:100011FC11241124FD241124312439FC55045500910011001102110210FE1000 +6778:100010F810881088FC881106320039FC54845484904810501020105010881306 +6779:10A010A010A01124FD24132835303920556051A09120112211221122111E1100 +677A:1000104010201010FC90108030803A8456825282928214881088108810781000 +677B:080009F808480848FE48084818481DF82A882A8848888888088808880BFE0800 +677C:100011F810081050FC20101033FE382254245420902010201020102010A01040 +677D:1008103C11E01020FC2011FC38203420502053FE902010201020102010A01040 +677E:1010109010901088FC88112431243A225440544090881084110413FE11021000 +677F:1008101C11E01100FD0011FC3144394455445528912811101110122812441482 +6780:04400440082010102208C44608201FF001100100FFFE054009203118C1060100 +6781:100013FC10841088FC881090309C388455445544912811281210122814441182 +6782:080008FC08840884FE8408FC18841C842A842AFC488488840884088409140A08 +6783:10401040108010FCFD0412043084384454445414902410441184100410281010 +6784:10801080108010FCFD04110432443844548454A4911411F41014100410281010 +6785:100011FC10881088FC88108830883BFE54885088908810881088110811081208 +6786:1008103C11E01020FC20103C31E038205420503E93E01020102210221022101E +6787:1010111011101112FD12111431D83910551055109110111211521192110E1000 +6788:208020843E9820E020842684387C21000100FFFE0380054009203118C1060100 +6789:1000100013FE1020FC2010203020382055FC5020902010201020102017FE1000 +678A:10001040119E1112FD1211123112391255125512915A11941110101010101010 +678B:10401020102013FEFC801080308038FC54845484908410841104110412281410 +678C:1010109010901088FD0811043A0435FA50885088908810881108110812281410 +678D:1090109011081108FA04140233FC3880550051F8900810081008100810501020 +678E:1020102010201020FDFC10203020382057FE5420905010501088108811041202 +678F:100011F811081108FD0813FE31083908550853FE910811081108110811281110 +6790:1008101C11E01100FD00110031FE391055105110911011101110121012101410 +6791:100017FE10801080FC8010F8390835085108520893F810101010101017FE1000 +6792:080009FE08080888FE88088819081DFE2A182A284848888809080A0808280810 +6793:0808088808480848FE08088818481C482A082A0E49F888080808080808080808 +6794:1020102010501050FC88114432223820540055FC900410081008101010101020 +6795:10401040104013FCFA4414483040384054A050A090A0112011221222141E1800 +6796:0808083C09E00820FE20082019FE1C202A202A50485088500888088809040A02 +6797:1020102010201020FDFE10203070387054A850A8912412221420102010201020 +6798:10201020102011FEFD221122312239225552554A918A110211021102110A1104 +6799:100011FE11001100FD78114831483948554855689150114211421142123E1400 +679A:1040104010401080FCFE11083288388854885450905010201050108811041202 +679B:1008101C11F01150FD5011503150395055505548914811481144124412421400 +679C:00001FF0111011101FF0111011101FF011100100FFFE054009203118C1060100 +679D:10201020102013FEFC201020302039FC54845488904810501020105011881606 +679E:1110111011101110FD10111031103910551052A8926812281444144418841102 +679F:1000100011FC1000FC00100033FE38205420544090401088110413FE11021000 +67A0:1040104011F81048FC88108A310A3A265420502093FE10201020102010201020 +67A1:1008106813881088FC88108830883BFE54885488908810881108110812081408 +67A2:100013FC12001208FE88125032503A2056205250925012881308120013FE1000 +67A3:01000100FFFE01003FF821082388254809203018C606018000400E0001800040 +67A4:0820082808240824FE2009FE18201C202A202A50485088500888088809040A02 +67A5:200023FE22002220FA20222022FC72246A24A224A24422442484248429283210 +67A6:10401020102011FCFD041104310439FC55045500910011001100120012001400 +67A7:100011FC11041104FD241124312439245524555490501090109011121212140E +67A8:1080108410841088FC9010A030803BFE54A0549090901088108410A210C01080 +67A9:010001007FFC052009103108C5440440082011102108C206044008201FF00010 +67AA:1040104010A010A0FD101208340639F055105110915011201104110410FC1000 +67AB:200023F822082208FB2822A822A872486A48A2A8A2A8232A240A240A28063002 +67AC:100011F811081108FD4811283928350853FE5108910811081108120812281410 +67AD:010002001FF010101210115010201FFC010401047FF4038805401930E10E0100 +67AE:0810081008100810FE1E081018101C102AFE2A82488288820882088208FE0882 +67AF:1020102010201020FDFE10203020382055FC5504910411041104110411FC1104 +67B0:100011FC10201020FD2410A430A8382057FE5420902010201020102010201020 +67B1:0820082008200840FE48088419FE1C822A002AFC488488840884088408FC0884 +67B2:0400080010103FF800081FF0101010101FF00100FFFE054009203118C1060100 +67B3:1000100011FC1104FD0411043104390455FC5504900010901088110412021402 +67B4:100011F811081108FD0811F83000380057FC5444904410841084110412281410 +67B5:100011F811081108FD0811F830003BFE5480550091F810081008100810501020 +67B6:080008007F7C094411441144257C420001000100FFFE054009203118C1060100 +67B7:220022002200FA1E27D2225272526A52AA52A252225222522452245E29523080 +67B8:10801080108011FCFD04120431E4392455245524912411E41124100410281010 +67B9:1080108011FC1104FA0415F431143914551451F4910411281112110210FE1000 +67BA:10201020102013FEFC201020302039FC547054A890A811241124122210201020 +67BB:1048114811481148FD4813FE3148394855485548917811001100110011FE1000 +67BC:12201220FFFE1220122013E010001FF801000100FFFE054009203118C1060100 +67BD:010001007FFC01001010FFFE101010101FF00100FFFE054009203118C1060100 +67BE:10201020102013FEFC20102031243924552455FC912411241224122414241020 +67BF:10201020102013FEFC20102038A83488508857FE908810881108110812081408 +67C0:10101010101011FEFD121114311039FC55445544912811281110122812441482 +67C1:10201010101011FEFD02120430803888549054A090C0108210821082107E1000 +67C2:1080108010FE1100FA201120312C397457A45124913411281122110210FE1000 +67C3:1020102010501050FC8811243212381055FC5404900810881050102010101010 +67C4:100013FE10201020FC2013FE32223A225652524A928A130212021202120A1204 +67C5:100011FC11041104FD0411FC31003940554455489170114011421242123E1400 +67C6:1040102010201000FDFE10003004388454845448904810481050101013FE1000 +67C7:103811C010401040FC4013FC304038E054E05550915012481444184210401040 +67C8:10201020112410A4FCA8102031FC38205420542093FE10201020102010201020 +67C9:0804081E09E00800FE20081019FE1C042A082A1048208840088009400A3E0800 +67CA:10401040107C1084FD881250302038505488530690601010100810C010201010 +67CB:089008881080309E57E0908010441034110C0100FFFE054009203118C1060100 +67CC:100011FC10041004FDF41004300439F45514551491F411141004100410281010 +67CD:10201020102011FCFD24112431243924552453FE902010501050108811041202 +67CE:1088108810881108FD7E13083508394855285528910811081108110811281110 +67CF:10201020104011FCFD0411043104390455FC5504910411041104110411FC1104 +67D0:08200820FFFE082008200FE0082008200FE00100FFFE054009203118C1060100 +67D1:1088108810881088FDFE108830883888548854F8908810881088108810F81088 +67D2:20801080009C47E0208008841084607C21000100FFFE054009203118C1060100 +67D3:2080108003F04090211009121212640E29000100FFFE054009203118C1060100 +67D4:00001FF0022001407FFC04841888628001000100FFFE054009203118C1060100 +67D5:100011F810081050FC20101033FE386254A454A0912012201420102010A01040 +67D6:100013FC10841084FC84110431143A08540051FC910411041104110411FC1104 +67D7:1010109010901108FD081204340239F855085508910811081108110811F81108 +67D8:1000100013FE1020FC201040304038FC55845284948410841084108410FC1084 +67D9:100011FC11241124FD2411FC31243924552455FC912410201020102010201020 +67DA:1020102010201020FDFC112431243924552455FC912411241124112411FC1104 +67DB:10201020102011FCFD241124312439FC55245524912411FC1124102010201020 +67DC:100011FE11001100FD0011FC310439045504550491FC11001100110011FE1000 +67DD:1008101C11E01100FD00110031FE391055105530911811141112121012101410 +67DE:10801080108010FEFD4011403240387C544050409040107E1040104010401040 +67DF:10201020102011FCFD24112431FC39245524552493FE11041104110411141108 +67E0:20402020202023FEFA022404200070006BFEA020A02020202020202020A02040 +67E1:100011FC10001000FBFE10003020382257B250B490A811281124122414A21040 +67E2:1008103C13E01220FE20122032203BFE5620521092101212120A128A13261212 +67E3:1020102011201120FDFC11203220382057FE5420905010501088108811041202 +67E4:100011F811081108FD0811F831083908550855F8910811081108110817FE1000 +67E5:01000100FFFE0540092011103FF8D01610101FF0101010101FF00000FFFE0000 +67E6:0800080008FC0884FE84088418FC1C842A842A8448FC88840800080009FE0800 +67E7:1008101C11F01150FD5011503150395055505548914811681154127412521400 +67E8:10401040104013FEFC8010A0392035FC53245524912411241134112810201020 +67E9:100013FC12001240FE40127832883A9057105220925012881304120013FE1000 +67EA:1010109010901110FD7E12523392389255125112925213D210621022104A1084 +67EB:10901090109013FCFC94109433FC3A90569053FE90921092111A111412101410 +67EC:01000100FFFE010001003FF82108292825483FF82388054009203118C1060100 +67ED:1050104810481040FBFE1080308038FC55445144912811281210122814441182 +67EE:1020102011241124FD24112431FC382054205524912411241124112411FC1004 +67EF:1000100017FE1008FC0813C832483A485648524893C812481008100810281010 +67F0:010001007FFC054009203118CFE6000000007FFC010011101108210445040200 +67F1:10401020100013FEFC2010203020382055FC5420902010201020102013FE1000 +67F2:1000104010201028FC08108830903A9456A252A294C210881188128814781000 +67F3:10001080131E1252FE52125232523A52565252D2935A12541090109011101210 +67F4:0880088828902EA028C028842E84F07C01000100FFFE054009203118C1060100 +67F5:100011FC11541154FD54115431543BFE55545554915411541154114411141108 +67F6:1000100013FE1252FE52125232523A525652528E92821302120213FE12021000 +67F7:100011FC11041104FD04110431FC3850545054509050109210921112120E1400 +67F8:100011FE10101010FC201020306838A455225222902010201020100013FE1000 +67F9:10201020102E11F0FD201120312039FE5422546290A2112A1624102010201020 +67FA:100011FC11041104FD0411FC3040384055FC5444904410841084110412281410 +67FB:010001007FFC054009203118C1061FF010101FF010101FF010101010FFFE0000 +67FC:10401020102013FEFA0214043000389054905090908811081108110412041402 +67FD:100011FC10841088FC501020305038885726502091FC10201020102013FE1000 +67FE:1000100013FE1020FC20102031203920553C5520912011201120112017FE1000 +67FF:10401020100013FEFC20102031FC392455245524912411241134112810201020 +6800:101C11E011001100FDFE11003100397C554455449154114811421242123E1400 +6801:21002100211E21D2FA522252225275526892A092A11A21142210241028102010 +6802:100010FC108410A4FC94108430843BFE550455449124110411FE100410281010 +6803:1008101C11E01100FD0011FE31203920553C5524912411241124124412541488 +6804:22081108111000207FFE4002810401007FFC03800540092011102108C1060100 +6805:100011DC11541154FD54115431543BFE5554515491541154115412D41224144C +6806:010001007FFC01003FF8210821083FF80280044008203318C0C6060001800040 +6807:100011FC10001000FC0013FE3020382055285524922412221422102010A01040 +6808:105010481040105CFDE01040305E39E054445048903010221052108A13061002 +6809:1088108813FE1088FC88100033FE3842544254429042104A1044104010401040 +680A:1090108810881080FBFE10A030A038A454A451289128113212221262149E1800 +680B:10401040104017FEF880112031203A2057FC5020912811241222142210A01040 +680C:10201020103E1020FC2011FC31043904550455FC910411001100120012001400 +680D:1020102011201120FDFC112032203820542055FC902010201020102013FE1000 +680E:1008103C13C01200FE20122032203BFE54205420912811241222142210A01040 +680F:1000110810881090FC0013FE30003800540055FC900010001000100013FE1000 +6810:10401020101011E0FC22103433B838B054A854A8912811241224142210A01040 +6811:2004200427842084F8BE2484228472A46914A114A28422842484280420142008 +6812:1080108011FC1104FE0411E43124392455E45524912411E41104100410281010 +6813:1020102010501088FD04120231FC38205420502091FC10201020102013FE1000 +6814:080008007F7C08243E2408447F54088809000100FFFE054009203118C1060100 +6815:100011FE11201120FD2011FC310439045504550491FC11201120112011FE1000 +6816:100017FE10901090FC9013FC32943A9456945294929C13041204120413FC1204 +6817:00007FFC044004403FF8244824483FF801000100FFFE054009203118C1060100 +6818:10201020107C1084FD481030302038485590543E904211A41018101010601180 +6819:2080208020FC2108FA902060219876266820A1FCA020222023FE202020202020 +681A:1088104810501000FDFC10203020382055FE5420905010501088108811041202 +681B:1040104011FC1044FC84108431283A10550853DE914A114A114A1252135A14A4 +681C:1020102013FE1020FC2011FC312439245524552C907010A81124162210201020 +681D:1008103C11E01020FC2013FE30203820542055FC910411041104110411FC1104 +681E:00007EFC08200820FEFE08201020202041200100FFFE054009203118C1060100 +681F:1104108410881000FDFE108830883888548853FE908810881108110812081408 +6820:083813C03040504097FC1040104013F800000100FFFE054009203118C1060100 +6821:10401020102011FEFC00108831043A0254885088905010501020105010881306 +6822:100013FE10201020FC4011FC31043904550455FC910411041104110411FC1104 +6823:10801088109C1170FD1013103510391055FE55109110111011101110117C1100 +6824:2020242022202220F83221B220B472A86AA8A4A8A52429242A22202020A02040 +6825:0100410021FC0A441448E0A02110260801000100FFFE054009203118C1060100 +6826:1082109210921092FC92109232DA3AB654925092909210921092111211021202 +6827:1020102011FC1124FD2411FC3124392455FC542090241018103210CA13061002 +6828:101010101210113EFD2210443810349050905310912811281128114410441082 +6829:100013DE10421042FE52114A314A384254C6514A9252104210421042114A1084 +682A:10201120112011FCFD20122030203BFE547054A890A811241124122210201020 +682B:10401040104017FEF8801080317C39085710551091FE11101110111011501120 +682C:1040104010F81108FA1011FC31243924552451FC910011001102110210FE1000 +682D:100013FE10201020FC4011FC3154395455545554915411541154114411141108 +682E:100013FE11081108FD0811F83108390855F855089108111E17E8100810081008 +682F:1040104017FE1080FD0013FC3504390455FC5504910411FC1104110411141108 +6830:10A810A410A41120FD2E13F03520392455245524912811101132114A11861102 +6831:1088108810881088FDFE108830883888548853FE900010881084110412021402 +6832:1040104411F41048FC5013FE3040388055FE5240948010FC1004100410281010 +6833:10401040104411F4FC48105033FE384054805584929814E010821082107E1000 +6834:1080108010FE1100FA0010FC308438A45494508493FE10841084110411141208 +6835:1002100217E2110AF90A11EA312A3A2A572A52AA944A104A10821102120A1404 +6836:100013FC12041244FE44124433FC3A44564452A4929413141204120413FC1204 +6837:1104108410881000FBFE1020302039FC5420502093FE10201020102010201020 +6838:10201010101013FEFC201042308439F85410542290C413081010102810C41302 +6839:100013F812081208FBF8120832083BF856445248923012201210128813061200 +683A:11001104113811C0FD02110230FE380055FC5504910411FC1104110411FC1104 +683B:1028102410241020FBFE102030203BA0552051109110111011CA170A12061002 +683C:1080108010F81108FB1014A0304038A05518520695F811081108110811F81108 +683D:084008487F4408440840FFFE004008440844FF4418282C2A2A12492A88460882 +683E:02000100FFFE0440145014482444444400000100FFFE054009203118C1060100 +683F:1090109410921112FD10137E3110391055105528912811281128114411441182 +6840:101010103EFC4210A490149008FE101020104110FFFE054009203118C1060100 +6841:10801080113C1200FC801080317E3B0855085508910811081108110811281110 +6842:1020102011FC1020FC20102033FE38005420542091FC10201020102013FE1000 +6843:1090109010901292FD941098309039985694549290901090111211121212140E +6844:10201020112410A4FCA8102033FE3890549054909090109211121112120E1400 +6845:1040104010FC1104FE0811FE3100397C554451449154114811421242123E1400 +6846:100011FE11001100FDFE11103110397C55105510911011FE1100110011FE1000 +6847:10001000FE7C224442443444087C3400C3000100FFFE054009203118C1060100 +6848:01007FFC40040400FFFE08201E4003C03C380100FFFE054009203118C1060100 +6849:10401020102013FEFE02144430403BFE54885488910810D01020105010881304 +684A:0100111009203FF8020002007FFC082011102108DFF6030005C0193061080100 +684B:1020102013FE1020FDFC102431FC392055FE5422902A10541050108811041202 +684C:0100010001FC01001FF810081FF810081FF80100FFFE054009203118C1060100 +684D:1020102013FE1050FC88110432FA380057FE5440908011FC1004100410281010 +684E:100013FE10201040FC88110433FE38225420542093FE10201020102017FE1000 +684F:1000101E13F21092FC941094309838945492549290F2171A1214101010101010 +6850:100013FC12041204FEF4120432043AF456945294929412F41204120412141208 +6851:1FE0064001800E4000007CF82448183066CC01007FFC054009203118C1060100 +6852:010001007FFC010009200820FFFE082009200100FFFE054009203118C1060100 +6853:100013FE10001000FDFC1104310439FC5504550491FC11041000100013FE1000 +6854:10201020102013FEFC20102031FC3800540055FC910411041104110411FC1104 +6855:10001040119C1104FD041104310439DC5504550491041104110411FC11041000 +6856:1020102010401080FDFC11543154395455545554915411541154115413FE1000 +6857:100013F810881090FCBC110439143648504057FE904010E01150124814461040 +6858:1040108011F81108FD08110831F839005500550091FC11041104110411FC1104 +6859:1040104010901108FBFC10243120392055FC5220902017FE1020102010201020 +685A:1124112412481124FD241000308038FC55045184924814281010102010C01300 +685B:08200820083E0820FE2009FE18001C002BFE2A20482888240822082008200820 +685C:1040102412241108FD0810103040384057FE5488910811901060105011881604 +685D:2208220822082388FABE228824A874A86AA8A128A13E21082208220824082808 +685E:21002100211E21D2FA542254225875546892A092A112211A2214241028102010 +685F:10501048107E13C0FC40107C3BC03440507E53C090441028103210CA17061002 +6860:100011FE10481048FC4810483248394A554A554C904810481048104813FE1000 +6861:1080108010BC13C0FC50102430D43B0C540053FE9090109011121112120E1400 +6862:10201020103E1020FC2011FC3104392455245524912411241050104810841104 +6863:1020112410A410A4FCA8102033FC38045404500491FC10041004100413FC1004 +6864:1020112411241124FDFC100031FC3804540455FC910011001102110210FE1000 +6865:2010207823C02040F84027FE20A071106A08A516A11021102110221022102410 +6866:1090109411141118FB1015323152390E5520502093FE10201020102010201020 +6867:1020102010501088FD04120238F83400500053FE902010401088110413FE1102 +6868:0840484028FC09041A882850486089800100FFFE0380054009203118C1060100 +6869:10201010101011FEFD00111031103910557C5510911011101110121012FE1400 +686A:100013FC10041004FDFC100430043BFC5408500897FE11081088108810281010 +686B:2010221021102110F4542252225270906810A114A604220822082210222020C0 +686C:1020082040A824A409227228103010C007000100FFFE054009203118C1060100 +686D:100013FC12001200FEF8120032003BFC56A052A492A812901290148814A418C2 +686E:100013FE10101020FC6810A433223820540055FC910411041104110411FC1104 +686F:100011FC11041104FD0411FC3000380057FE5420902011FC1020102013FE1000 +6870:101C13E012201220FBFE122032903B0A560651FA910811081108110811F81108 +6871:100013FC10001124FA48149032483924540053FC904010401040104017FE1000 +6872:1020102013FE1020FC2013FE3A02340451F85010902013FE1020102010A01040 +6873:10401080110413FEFC22102033FE385054885124922211FC1020102010201020 +6874:1008103C11C01004FD4410A8300039F85410502093FE10201020102010A01040 +6875:2008203C23C02044FA242128210070406BFEA088A10823902060205021882604 +6876:200027F8201021A0F84027FC244474446FFCA444A44427FC2444244424542408 +6877:1080108010F81108FA1015FC3124392455FC5124912411FC1124122412141408 +6878:11841068103010C8FB04104033FE38A0552053FC952411241134112810201020 +6879:1040102011FC1104FD0411FC3104390455FC5520912211141108114411821100 +687A:100013FE10501050FC5013DE32523A525652525293DE10501090109011101210 +687B:210021F823082490F8602198264670406BF8A040A3F8204027FC204020402040 +687C:010001007FFC092011102108C284044009203118CB2605C01930610805000200 +687D:010001007FFC05401930E10E082009201550238801003FF801000100FFFE0000 +687E:100011FC10441044FBFE1044304439FC5480508091FC12841484108410FC1084 +687F:100011FC110411FCFD0411FC3000380055FC5420902013FE1020102010201020 +6880:1020102013FE1020FC2011FC3124392455FC5420907010A81124122210201020 +6881:000023F01090829452922492E110225025200100FFFE054009203118C1060100 +6882:1028102410241020FDFE1020312038B254B4546890A811241222102010A01040 +6883:2000200C27702110F9102210327C6F106110A510A510227C2200250028FE3000 +6884:100013FE10501050FDFC115431543954558C5504910411FC1104110411FC1104 +6885:1100110011FC1200FDF811083948352857FE51089248122813FC100810501020 +6886:2100211E21122FD2F114211427D871146912AFD2A112211A2214221024102810 +6887:100013FE10201020FDFC102030203BFE5488508893FE10881088110811081208 +6888:1040102013FE1000FDF81108310839F8540053FC900810301020102010A01040 +6889:1048114811481148FD4811C8307E384857C851489148114811481148125C1440 +688A:080C08F07E8008800EFE78880888290812080100FFFE054009203118C1060100 +688B:100011F811081108FDF8100033FC3A04560453FC9204120413FC120412141208 +688C:1020102010501088FD0412FA3020382057FE5420912811241222142210A01040 +688D:1020104011FC1104FD0411FC3104390455FC54409040107E17C010421042103E +688E:1020104011FC1104FDFC110431FC38005500550C91F011001102110210FE1000 +688F:10201120112011FCFD20122030203BFE5400540091FC11041104110411FC1104 +6890:12201224122813B0FE20122232A23B1E5440504093FC10401040104017FE1000 +6891:2010289025102212F5522954215871906B10A528A9282128214821442A842502 +6892:1020102010501088FD44122230F838085410542091FC11041104110411FC1104 +6893:1040102011FC1000FC88105033FE38205420542091FC10201020102010201020 +6894:1008101C11E01100FDFE1100317C3954555455549154117C114012421242143E +6895:100013FC10441144FD441284389435085240502090A41282128A128A14781000 +6896:080008FC08840884FEFC088418841CFC2A842A8448FC88000848084408820902 +6897:100013FE10201020FDFC1124312439FC5524552491FC112010A0104010B0130E +6898:100011FC11041104FDFC1104310439FC5504550491FC1050105010921112120E +6899:1020102011FC1124FD2411FC3020382057FE5222922213FE1222102010201020 +689A:1080108011F81208FC1013FC32443A44564453FC90A010A011221122121E1400 +689B:20002FDE22522252FA5427D432586A546252AFD2A252225A2254245025502890 +689C:10201020102013FEFC20102039243524512452AA902010501050108811041202 +689D:0840084010FC10883550542094D81726142015FC142014A81524122210A01040 +689E:100011F810081008FDF811003104390454FC5440902010A4128A128A14781000 +689F:04001FF010101FF010101FF010001FFC10001FFC01043FF405481930E10E0100 +68A0:100011F811081108FD08110831F83800540053FC920412041204120413FC1204 +68A1:1040102013FE1202FC0411F83800340053FE50909090109011121112120E1400 +68A2:1020112410A410A8FC2011FC3104390455FC5104910411FC1104110411141108 +68A3:1020112411241124FDFC10203050388855445222902011F81008101010101020 +68A4:1020112411241124FDFC100030883888550452FA904810481088108811281210 +68A5:020001007FFE48229214244808201FF001100100FFFE054009203118C1060100 +68A6:082008207EFC08201C702AA8C826040007F0081014202240018002000C007000 +68A7:100013FE10401040FDFC108430843BFE5400500091FC11041104110411FC1104 +68A8:03083C0804487F480C4816482508442805100100FFFE054009203118C1060100 +68A9:100011FC11241124FDFC1124312439FC5420542091FC10201020102013FE1000 +68AA:100013FC10001000FDF811083108390855F85400910810881090100017FE1000 +68AB:100011FC100410FCFC0411FC380037FE520251F8908810881050102010D81306 +68AC:1020102011FC1124FDFC112431FC380057FE5480910011FC1004100410281010 +68AD:1040104010881104FBFE100230883944564250F8918812501020105011881606 +68AE:100011FC11041104FDFC1100310039FE5502557A914A114A127A120214141008 +68AF:11081088109011FCFC24102431FC3920552051FE906210A2112A122414201020 +68B0:1010101410121010FBFE10103150395457F4515491541148124A125A14261042 +68B1:100013FE12221222FE2213FE32223A62567252AA932212221222120213FE1202 +68B2:1010109010881108FA0415FA31083908550851F890901090109011121212140E +68B3:1040102013FC1040FC90110833FC38045550515091501150125012521452180E +68B4:1004100E13B81088FC881128312E3BA854A852A892A8113E11001280147E1800 +68B5:082008207EFC08201C702AA8C82600000FE0082008200A20092011222022401E +68B6:100013FC12041204FBFC120032183AE0563852E0923C13E012221422141E1800 +68B7:100010FC1E0410487E28421042287EC401000100FFFE054009203118C1060100 +68B8:208421C427042114F914211427D471146B14A394A55425042904210421142108 +68B9:1008101C11E01100FD0011FE311039105510511097FE10001090110812041402 +68BA:082008207EFC08201C702AA8C8260000FFFE0200024002200210020802000200 +68BB:22502250225025FCF4542C5435FC75506D50A5FEA4522452245A249424902510 +68BC:1020102013FE1020FDFC104033FE3848548854FE910811481228140810281010 +68BD:10201020102013FEFC201020302039FC5440542090A41282128A128A14781000 +68BE:10201020102013FEFC20112430A438A855FE547090A810A81124122214201020 +68BF:101012101110117EFC2010283748397E5508550891FE110811081288147E1000 +68C0:1040104010A010A0FD10120835F6380054885048924811501110102017FE1000 +68C1:1104108410881010FDFC11043104390455FC54509050109010921112120E1400 +68C2:100013F810081008FDF8100830083BF8544051489148125010A0111012081406 +68C3:0C8070FC1124FD24122438445484912810100100FFFE054009203118C1060100 +68C4:020001007FFC10103FF801081110FFFE11101FF001007FFC05401930E10E0100 +68C5:207823C0204027FCF84023F8204877FE6848A3F8A0E0215022482C4620402040 +68C6:1020102010501088FD0412FA300039FC5554555491FC1154115411541104110C +68C7:1090109011081148FA44149231083BFC5444502090A41282128A128A14781000 +68C8:1020102013FE1020FDFC102033FE380055FC550491FC110411FC110411141108 +68C9:1020104011FC1104FDFC110431FC3820542053FE92221222122A122410201020 +68CA:08207FFC08200FE008200FE00820FFFE11102108DFF6030005C0193061080100 +68CB:1108110813FC1108FD0811F83108390855F85108910817FE1000109011081204 +68CC:2008203C23C02044FA242128210070206BFEA070A0A820A82124222224202020 +68CD:100011FC11041104FDFC1104310439FC5400551291D41118111011521192110E +68CE:100013FE12021252FC8811043020382057FE5420907010A81124162210201020 +68CF:100011FC110411FCFD0411FC300039FE540853FE900811081088100810281010 +68D0:044004407C7C04403C7804407C7C044005400100FFFE054009203118C1060100 +68D1:109010901090179EF890109030903B9C549050909090179E1090109010901090 +68D2:1020102013FE1020FDFC104033FE38885524522290F8102013FE102010201020 +68D3:1080104011FC1000FD08108830903BFE5400540091FC11041104110411FC1104 +68D4:101C13E0122013FEFE201292330A3A0655FC5104910411FC1104110411FC1104 +68D5:1040102013FE1202FC0011FC3000380057FE5420912811241222142210A01040 +68D6:100010FC108010F8FC8010F830803BFE55405524912811101108114411821100 +68D7:01007FFC01003FF823880D60301001007FFC01003FF82108238805601918E106 +68D8:10201020FDFC102010207CF854A854A854A85CB81020387054A8952610201020 +68D9:1040102013FC1204FE0413FC32003A28562453FE922012501250148815041A02 +68DA:100013DE12521252FE5213DE32523A52565253DE9252125212521252155218A6 +68DB:1040102013FE1080FD0413FE300239FC550455FC910411FC1104110411141108 +68DC:21082088200827D4FA142222220073C86A44A244A24022502248244425442880 +68DD:100011FC11041124FD2411FC3124392455745554915411741104110411FC1104 +68DE:100013FE1202121AFEE2122232223BFE5622527292AA13261222122213FE1202 +68DF:1020102013FE1020FDFC112431FC392455FC5420907010A81124162210201020 +68E0:0100111009207FFE40029FF4101010101FF00100FFFE054009203118C1060100 +68E1:100013FE1202128AFE5213FE32223A2256AA52AA92AA12FA12021202120A1204 +68E2:100013FE1202128AFE5213FE32423A2257FE52829282128212FA1202120A1204 +68E3:1020102011FC1024FC2413FE3824342451FC5222917410A81124122210A01040 +68E4:10881088108813FEFC88108837FE380055FC5104910411FC1104110411FC1104 +68E5:2088248822882108F93E22882498701C68ACA2AAA14821082288228824882808 +68E6:1080108011F01210FC2013FC3044384457FE5444904413FC1044104011401080 +68E7:10481044105E11E0FC281012306A39965448545E91E0102410281012106A1186 +68E8:102008203E3E224422843E282210402881440100FFFE054009203118C1060100 +68E9:1050125212521252FBDE120232023BFE5602520293DE12521252125214521802 +68EA:1020112211221224FC5010883304382254205524912412281050108811041602 +68EB:10141012101017FEF810101033D23A525652525493D4100810EA171A12261042 +68EC:1020112410A81020FDFC104033FE3888550452FA9488108810A810921082107E +68ED:2080204027FE2120F920223C224476646A94A348A24822302220225022882306 +68EE:010001007FFC054009203118C106082008207EFC08301C682AA4C92208200820 +68EF:1020102010501088FD44122231F838085450542090A41282128A128A14781000 +68F0:2010207823C02040F84027FC224872486FFEA248A24827FC2040204027FC2000 +68F1:1020102011FC1020FC2013FE30883944564254F8918812501020105011881606 +68F2:1020102013FE1020FDFC102433FE382455FC504093FE108411C8103010CC1302 +68F3:100013DE1042114AFC84114A3A523420500053DE905211521094114812541422 +68F4:200027BE24A224A2FCAA27A424A074BE6CAAA7AAA4AA24AA24A424A424AA29B0 +68F5:100011FC11241124FDFC1124312439FC542053FE907010A81124122210201020 +68F6:10401040104017FCF840124832483A48555450E0915011501248144418421040 +68F7:20002FC024BC24A4F4A427A424A474A86FA8A4A8A49025D02EA820A820C42082 +68F8:00007F00227C3E0422283E1023A8FE4402000100FFFE054009203118C1060100 +68F9:10201020103E1020FDFC110431FC390455FC5524902013FE1020102010201020 +68FA:1040102013FE1202FC0411F83108390855F85500910011FC1104110411FC1104 +68FB:0820FFFE08200460081037E8C22404A018400100FFFE054009203118C1060100 +68FC:082008207EFC08201C702AA8C8240440082010102FE8C4260420082010A06040 +68FD:082008207EFC08201C702AA8C92402800E603118C1061FE00020004000800100 +68FE:082008207EFC08201C702AA8C82600007FFE40028FE40820082010222022C01E +68FF:10001040139C1204FE04139C32043A0457FC549090901090109011121212140E +6900:1040102013FE1202FD04110031DE3A5256525352949A1094111011121212140E +6901:1040102013FE1000FDFC110431FC380055FC5408901013FE1020102010A01040 +6902:100011F810081008FDF8100830083BFE54205222917410A81124122210A01040 +6903:10401040107C1040FBFC124432703BC05644523C920012F0149014921912120E +6904:1080104013FC1000FD08109037FE3840544057FE908811081090106011981604 +6905:2040204023FC20A0F910220827FE70086BC8A248A248224823C8200820282010 +6906:100011FC11241124FD74112431FC390455745154915411741104120412141408 +6907:100011F811081108FDF8110831F8390855F85108910817FE1000109011081204 +6908:1100110011FC1204FC84149432A4388457FC508491C412A41494108410A81010 +6909:02000100FFFE10103EFC4210149018FEE0100110FFFE054009203118C1060100 +690A:1040102013FE1000FC88108831543A225400502093FE10201020102010201020 +690B:1040102013FE1000FC0011FC3104390455FC5420912811241222142210A01040 +690C:10401020102013FEFA02149431083A04540051FC902010201020102017FE1000 +690D:1020102013FE1020FC2011FC310439FC550455FC910411FC1104110417FE1000 +690E:10A01090109011FEFD10131035FE3910551055FE91101110111011FE11001100 +690F:100017FE10901090FC90139C32043A045604539C909010901090109017FE1000 +6910:100013FC12041204FBFC122032203BFE5620522092FC12841284148414FC1884 +6911:1040108011FC1124FD2411FC3124394455FC5490911013FE1010101010101010 +6912:2100210021DC2114F914211427D470146914A114A58825482948211425142222 +6913:100013FE10401080FD44122430683AB0553052A8906810A41122122010A01040 +6914:1092109211241248FD2410923092380055FE5522912211FE1122112211FE1102 +6915:2008208822882288FABE24482018779C6AACA2AAA2C822882288248824882988 +6916:1040102011FC1104FD0411FC3120391055FE55209120113C1124124412541488 +6917:1040102013FE1202FC04100033FE382054205520913C112012A01260143E1800 +6918:082008207EFC08201C702AA8C824020001007FF8006001800E003000480087FE +6919:11F81108110811F8FD08110831F8380057FC5204920413FC1204120413FC1204 +691A:100013DE12521252FBDE125232523BDE560252029202120212021202120A1204 +691B:1108110817FE1108FD08100038903492511453189510113211521112110E1100 +691C:1020102010501088FD0412FA3020382055FC5524912411FC1050108811041202 +691D:100011FC7D0411241124FC5010902912460E8100FFFE054009203118C1060100 +691E:080C08F07E8018802CFE2A884888888809080100FFFE054009203118C1060100 +691F:1020102011FC1020FC2013FE3002389454505510909013FE1028104410821302 +6920:100CFEF0208048807EFE08880E88F9084A080100FFFE054009203118C1060100 +6921:1002100217E2110AFD0A124A33EA388A548A53EA908A108A10E21702120A1004 +6922:100013FE12021202FBFE122232223AFA56225232922A13FE1202120213FE1202 +6923:10901090109013FCFE94129432943BFC56945294929417FE1000109011081204 +6924:100013FE12521252FE5213FE3020384054FC5104928810501020104011801600 +6925:11001100110013DEFA9214923092389257F2509290921152115E122014201800 +6926:1020112410A81020FDFC104033FE38885544524295F810481088108811281210 +6927:1020102010501088FD0412FA30003BDE56525252925213DA1254101010101010 +6928:1040102013FE1200FE44124432843ABE578452A4929412941284128414941088 +6929:1040102013FE1220FEFC122432243BFE5624522492FC12201250145014881906 +692A:10841048100011FEFC48104830483A48554A554C904810481048104813FE1000 +692B:11041088105011FCFD24112431FC3924552455FC9020102013FE102010201020 +692C:1040102013FE1202FC0411F83108390855F85508910811F81108110817FE1000 +692D:201027902490257EFD202620257C74A46CA4A4BCA6A4253C242424242424242C +692E:10401048108411FEFC2013FE3088392456425188901010621184101810601380 +692F:1020112411241124FDFC100033FE3820544055FC91541154115411541154110C +6930:20002FDE24922492F4942794249874946F92A492A49225DA2E94209020902090 +6931:1100110011FE1200FDFC110431FC390455FC548090FC11081290106011981606 +6932:1040104011FC1084FBFE100031FC390455FC502093FE1020122013FE10201020 +6933:100011FC11241124FDFC1124312439FC540053FE912011221114114811841102 +6934:102011DC11141114FD1411D43126390055DC5514911411D41708110811141122 +6935:100013DE12421242FE4213DE32003A3E57D25212921413D41208121412241242 +6936:1000108812521222FE52128A32023BFE54885144927A10881150102010D81706 +6937:20142012201027FEFC10241025D074126C12A5D4A554254825DA242A28463082 +6938:22102110211027BEFA28224823AA72AE6ABAA2EAA2AE22A824AA24A229A2301E +6939:1110111017FC1110FDF0111039F03510511057FE920012901308120013FC1000 +693A:2100217C21442244FA44267C2A1072106AFEA238A25422542294231222102210 +693B:100013FE120012FCFE8412FC32843AFC562053FE924812C812301248128413FE +693C:1080108E11201210FCC010AE31043B1455245164912411241124110411141108 +693D:210021F8220823F0F81027FE208071446E68A0B0A128266820A4212226A02040 +693E:11081088109017FEF80013C432543A5457D45254925413D412541244125412C8 +693F:1020102013FE1020FDFC104033FE3888550452FA9088108810F81088108810F8 +6940:1004101E13E01020FDFC1124312439FC542053FE9222122A12FA1202120A1204 +6941:1040102013FE1202FC8010F831083A9054605198960611F81108110811F81108 +6942:1020102013FE1070FCA81124322239FC550451FC910411FC1104100013FE1000 +6943:100013FC12041204FBFC120033FC3A40568853FC9224122015FC1420182013FE +6944:1040102013FE1202FE0213FE32003A0057FE5352955215FE1552155219521106 +6945:100013FE100011FCFD04110431FC380057FE5222922213FE1222122213FE1202 +6946:100013FE10501050FBFE125232523BFE5400504097FE10881190106010D81304 +6947:100011FC11041104FDE4112431243BFE560252FA928A128A12FA1202120A1204 +6948:100013FE10221120FD3C11203AFE340051FC510491FC110411FC110411141108 +6949:1088108813FE1088FCA8102033FE3840548054FC918412841084108410FC1084 +694A:100011F8110811F8FD0811F830003BFE550051FC925414941124124410A81110 +694B:1082108217F21082FC8A13EA32AA3AAA57EA508A91CA12AA14A21082108A1084 +694C:1040102013FC1000FD08109033FE3A10562052C89210122412C8141014601980 +694D:010001007FFC0380054009203118C10600007BBC4AA44AA44AA44AA47BBC4AA4 +694E:100013FE12221020FDFE102031FC392455FC552491FC102013FE102010201020 +694F:1020102013FE1050FC88132631FC3820542053FE9000102011FC1020102013FE +6950:11FC1124112411FCFD24112431FC385054885104928A10881088108811081208 +6951:101013D410581252FD8C108831043AFA5420502093FE10201050108811041202 +6952:100011FC11241124FDFC1124312439FC54005440902412A2128A148810781000 +6953:200027FC24042434FDC4244425F475546D54A5F4A444245425F4249428063002 +6954:2100213C27D42114FB94211427D47124694CA040A7FE204020A0211022082C06 +6955:1040104013FE1080FDFC122035FE380055FC550491FC110411FC110411141108 +6956:100013DE12521252FE5213D232523A52565253D2921A1294125012B013101010 +6957:2020202020FC2E24FBFE222424FC74206EFCA220A2202BFE2420262029FE3000 +6958:00207E20247E1884FF2829104A2899440100FFFE0380054009203118C1060100 +6959:2008278820882288F93E210827D8715C6B2CA32AA54825082908210825082208 +695A:082008207EFC08201C702AA8C82400007FFC0104110011F81100290047FE8000 +695B:1088108813FE1088FCA8102033FE38205420542091FC11041104110411FC1104 +695C:2100211E211227D2F912211E211277D26C52A45EA45227D224522022202A2044 +695D:1020102013FE1020FDFC112431AC3974552455FC9020107010A8112412221020 +695E:100013FC12941294FE9413FC3080384057FE548090F810881108110812281410 +695F:1040102013FE1000FDFC110439FC340053FE520291FC10201020102010A01040 +6960:1020102013FE1020FC2013FE328A3A5256FA5222922212FA12221222122A1204 +6961:11C010A011101208FDF6100033CA3A4A565453D49268125413D4124A124A12C0 +6962:11081088109017FEF890109033FC3A945694530C920413FC1204120413FC1204 +6963:100013FC12241224FBFC120032FC3A84568452FC928412FC1284128414FC1884 +6964:1080108010FC1154FAD410B4312C3A4454945108904010A412AA128A14781000 +6965:103C17C012441128FC0013FC3080388057FE550091F812881250142018D81306 +6966:1040102013FE1202FC0411FC300039FC550455FC910411FC1104100013FE1000 +6967:2110211027FC2110F950204023F872486A48A248A7FE204020A0211022082406 +6968:10201020103E1020FC2011FC310439FC550455FC910411FC1000108811041202 +6969:210021FE21102210FAFE2292269272FE6A92A292A2FE22902250222022582286 +696A:10481148114813FEFD4811483178390055FE542093FE107010A8112416221020 +696B:100011F811081108FDF8100037FE390855F8550891F81108113E17C810081008 +696C:100011FC110411FCFD0411FC388035FE522251229152110211FA100210141008 +696D:044024481450FFFE082004407FFC01003FF80100FFFE054009203118C1060100 +696E:1020102211FA1024FC2813FE3020384054FC5184928410FC1084108410FC1084 +696F:201C23E022202220FBFE222022FC72846A84A2FCA28422FC2484248428FC2084 +6970:1020102010A0112CFD24112431AC3924552455FC912410501050108811041202 +6971:2040204027FC2040FBF8208027FC71106A08A5F6A04023F8204020A021102608 +6972:2014201227FE2410FC1027F0249274926FD2A554A5542488254A2A1A28263042 +6973:1088108813FE1088FC8810F83088388854F8542093FE107010A8112412221020 +6974:1040102011FC1000FC88105033FE3A22542455FC912411241134112810201020 +6975:100013FC10081010FC2013AE32A23AAA56A452A493AA103210A0104017FE1000 +6976:410021FC0A441048E0A0211026081FF410101FF001007FFC05401930E10E0100 +6977:1110111211D41118FD521192312E384055FC5104910411FC1104110411FC1104 +6978:208821C827082108F92A212A27AC71486B08A388A55425142914212421242142 +6979:100013F811081110FD1C12E432A43A5454A8510093FC12941294129417FE1000 +697A:100010FC10481030FDFE1052389435105230502091FE107010A8112412221020 +697B:1020104011FC1104FDFC110439FC340053FE5020902011FC1020102013FE1000 +697C:2020212420A82020FBFE20A8212472026840A7FEA08821082190206021982604 +697D:0100420427C81450044017D02448C44407C00100FFFE054009203118C1060100 +697E:1040108011FC1104FDFC110431FC3820543253B490A811281124122414A21040 +697F:101C11E010201020FBFE10A831243A2255FC5104910411FC1104110411FC1104 +6980:100010F810881088FC88108830F83888540053DE925212521252125213DE1252 +6981:1040102011FE1102FE0411FC3040388855FC5424902011FC1020102013FE1000 +6982:200027BE24882488FFA824A824A877BE6C10A518A49825A826AA244A20462080 +6983:082008207EFC08201C702AA8C82600003FF8210821083FF8210821083FF82008 +6984:10901290129E12A8FEC4108031FC39045524552491241154105010901112160E +6985:100011F811081108FDF81108310839F8540053FC929412941294129417FE1000 +6986:104010A011101208FDF6100033C43A54565453D49254125413D41244125412C8 +6987:1040102011FC1000FC88105033FE3820542055FC902010A81124122210A01040 +6988:110010BC12841204FEF4129432943AF4560452F49294129412F4120412141208 +6989:1044112410881010FBFE108831243A2254F85020902013FE1020102010201020 +698A:120811081108103EFBAA10AA30BE392A55AA536A953E112A1108110811081108 +698B:100011FC100410FCFC0411FC3004380057DE5442904213DE1042104213DE1042 +698C:100013FA100C104AFB88112A3126392257F8512A912C112A1128122A12261422 +698D:200023FE22022202FBFE2210229272546AFEA282A2FE228222FE2482248A2884 +698E:13FE104011FC1104FDFC110431FC390455FC548090FC11081290106011981606 +698F:1104108410881000FBFE100030883904560251FC915411541154115417FE1000 +6990:100013FC12041204FBFC124832483AFC5648524893FE12A412A8149014C81886 +6991:1028102413FE1020FDFC112431FC392455FC5524900813FE1088104810481018 +6992:100013DE10421042FBDE121032103BDE54425252914A114A1252104212941108 +6993:20402028209022A4FAC2248A218876786800A3FCA29422942294229427FE2000 +6994:1100109E13D21252FE5413D432583A5457D252129292125A12D4135012101010 +6995:1040102013FE1202FC501088312438505488510492FA10881088108810F81088 +6996:08007F7808483E4800487F864100BEFC004408447E2818282C104A2888440982 +6997:100013FC10901294FD98109037FE380055F85508910811F81108110811F81108 +6998:200020FC3E8048F888887EF8148022FC40000100FFFE054009203118C1060100 +6999:1088108813FE1088FC2010503888350452FA5000900011FC1104110411FC1104 +699A:1104108410881000FBFE1020302039FC5420502093FE100012A4125214521000 +699B:1020102013FE1020FDFC10403BFE3488513452E2902011FC107010AC13221020 +699C:1040102013FC1108FC9013FE32023C44542053FC908010F81088110811281210 +699D:2000245C22942114FA942454212671006FDCA114A59425542948210825142222 +699E:100011FE11101120FD7C1144317C3944557C5510911011541152129212501420 +699F:1040102013FE1242FC2011FC3088385057FE5020902011FC1020102010201020 +69A0:100013FE12021000FDFC110431FC390455FC5440902013FE1000108811041202 +69A1:1020102013FE1020FDFC102033FE3840548855F0902413FE1022112412A21040 +69A2:1040102013FE1202FC0011FC304038A257345458909413341052109013501020 +69A3:1008103C13C01004FA44112831FC3A20542053FE902011241124112411FC1004 +69A4:2208220823BE2488FAA8213E220874486848A7FCA0E0215022482C4620402040 +69A5:100011FC110411FCFD0411FC3020392454A8502093FE1090109011121212140E +69A6:102010201050FE5010887D0446227C2045FC7C601070FEA810A4112412201020 +69A7:100013FE12281228FEEE122832283AEE5628522892EE12281228122813FE1000 +69A8:1040102013FE128AFD04108030FE39405640507C90401040107E104010401040 +69A9:1040107C104013FEFE42127833C43A3C5640522093FE12881250142014581986 +69AA:100011FE112011FCFD2011FC3120392055FE500292AA12AA12AA120210141008 +69AB:10A0109011FE1320FDFC112031FC392055FE5500902013FE1020102010201020 +69AC:1020102011FC1020FBFE100031FC3904550451FC90521094118816A410C21080 +69AD:2084210423C42244FBDE224433C46A646254A7D4A0C421442244244421542088 +69AE:08202AA44D28145022887FFE4002810401007FFC0380054009203118C1060100 +69AF:201020102710257CFD10251025FE77086D08A5FEA50825482728200820282010 +69B0:1040104411F81050FBFE104030F83982567E540091FC110411FC110411FC1104 +69B1:2080204027FE2000FBF822082FFE72086BF8A0A4A12823102510294821862100 +69B2:200023F8224822A8FB18220823F870006800A7FCA4A424A424A424A42FFE2000 +69B3:2040202023FE2202FAEC2224224472446AEEA224A2A422A4224E2460249E2900 +69B4:104013BE12121292FE5212AA3324384057FE5222922213FE1222122213FE1202 +69B5:1108110817FE1108F80017FE310839F8550851F89108113E17C8100810081008 +69B6:1020101013FE1220FAFC122433FE3A2456FC522092FC12841284148414FC1884 +69B7:1080108017FE1522FD1013FC36203A2057FC5220922013FC1220122013FE1200 +69B8:1100113E112A112AF93E17AA312A393E55085108913E118817081208107E1000 +69B9:1004101E13F0121EFE1012FE32923A9856F2528E928012B812A814AA154A1A86 +69BA:00203D2424A8242025FC3C4027FE248825243E2225FC247024A8452456248820 +69BB:100011FC110411FCFD0411FC3800340053DE50429252114A12521042114A1084 +69BC:1020102011FC1020FC2013FE3080390457FE540293FC12941294129417FE1000 +69BD:103C17C012441128FC80111033E03840558853FC9044104017FC10A01110160E +69BE:100011FC110411E4FD2413FE320239FC550455FC910411FC1104110411141108 +69BF:1020112411241124FDFC100033FE380055FC5504910411FC1088105013FE1000 +69C0:0100FFFE00001FF010101FF000007FFC40044FE448244FEC0100FFFE0920711C +69C1:1040102013FE1000FDFC110431FC380057FE520292FA128A12FA1202120A1204 +69C2:20062F7821102120FA44227833106A24667EAA12A2102254225222922A502420 +69C3:10003E7822482A48FE8623782A4842304A48848401007FFC05401930E10E0100 +69C4:103C13C010441224FD28110030403B9C56045204939C12041204120413FC1204 +69C5:100013FE100011FCFD04110431FC380057FE528A925213FE12221222122A1204 +69C6:1110111017FE1110FA0013FC34043BE4562453E4922413E41224100410281010 +69C7:111811E0110210FEFC00117C3144397C5544557C9144117C110011FE10881104 +69C8:100013FE120012FCFE0013FE32A83A9056C85286920813FE1288144814081818 +69C9:1020101011FE1100F9201520333C39505590531095FE11101128122812441482 +69CA:2200147CFF44087C4944497C7F44084410942108FFFE054009203118C1060100 +69CB:1088108813FE1088FDFC108833FE382055FC552491FC112413FE110411141108 +69CC:10101220117C1144FC44107C33403940557C55449144117C11441280147E1000 +69CD:10201020105010C8FD2413FE350439FC550451FC910011FC1284128414FC1084 +69CE:11081088109013FCFC4011F830403BFE5480550091FC12201420182013FE1000 +69CF:10881050100013FEFC5011FC30543BFE545455FC905010D81154125210501050 +69D0:1020104011FC1124FD2411FC3124394455FC544090B010A4113C11221222141E +69D1:00007CF84488448844887CF810201020FDFC307038A854A85124922210201020 +69D2:1040102013FE1040FC8811F03020384455FE540291FC112411FC112411FC1104 +69D3:100011FC10201020FBFE100031FC390455FC510491FC110411FC108811041202 +69D4:1040108013F81208FBF8120833F8388057FC5110924814441BFA104010401040 +69D5:10201020103E1020FDFC110431FC390455FC502093FE107010A8112412221020 +69D6:01007FFC01001FF000007FFE4002BFF408001FF068100FF00100FFFE0920711C +69D7:1040104017FE1080FDF8128834F8380057FE520292FA128A12FA1202120A1204 +69D8:1104108813FE1020FDFC102033FE3820552454A8907010A81124162210A01040 +69D9:1020102013FE1020FDFC110431FC390455FC550491FC110413FE108811041202 +69DA:100013FE105013FEFE52125233FE380055FC5504912411241124105010881304 +69DB:10481148114E1150FD68114431443840540055FC915411541154115417FE1000 +69DC:10A0109011FE1320FDFC112031FC392055FE510093FC1088109E1102120A1404 +69DD:1020104011FC1104FDFC110431FC390055FE550091FE1042124A13FA10141008 +69DE:1080104017FC1110F8A017FE30003BF8564853F8924813F8124A1042103E1000 +69DF:1040102013FE1202FC1411E03100390055FC5110911017FE1000109011081204 +69E0:2020242022FA2224F82821FE2E2072406AFCA344A244227C22C42344227C2044 +69E1:11F810881070118CFC0013DE3252398C5652502093FE107010A8112416221020 +69E2:100013DE10421252FD4A12523042382055FC5504910411FC1104110411FC1104 +69E3:1040102013FE1202FC2011FC3050388857FE540891E8112811E8100810281010 +69E4:1010101012FE1110FD7C1054307C3B54557C511091FE111011101290147E1000 +69E5:108813DE108811DCFC8813DE3888340053FC5004900411FC1004100413FC1004 +69E6:202027FE242025FCFC2427FE242475FC6C20A5FCA52425FC252429FC2924312C +69E7:08047F7808407F40497E7F4849487F4808487F48088801007FFC05401930E10E +69E8:2200211E27D22012F7D4245427D870146FD2A092A11221DA2714211025102210 +69E9:00007DFC44207D2045FE7C5048525492650E0100FFFE054009203118C1060100 +69EA:2100223E27882488FCA827A824BE74886F88A010A4982718242824AA23CA2086 +69EB:102013FE102011FCFD2411FC312439FC542253FE900813FE1108108810281010 +69EC:2200220E2F742254F55428D4275470546FD4A454A754215421522154255C2284 +69ED:20142012201027FEFC10249024D274926FF2A494A49425C82AAA289A31A62042 +69EE:1040108811FC1108FA5213FE30503988562650C0931010641388103010C01700 +69EF:1020122213FE1090FC8811FE3B10351051FE5110911011FE1110111011FE1100 +69F0:2020247C22842148F83020CE2610727C6A10A27CA21022FE2210221025FE2800 +69F1:100011FE10481048FDFE114A314A398E550255FE910211FE10001154112A122A +69F2:2204220427842494F90C27C4256475546FC4A546A57C27C425442544244428C4 +69F3:0440247C24A83D5004287DFE2488444885180100FFFE054009203118C1060100 +69F4:1040102013FC1204FBFC120032F83A8856F8520093FC132415FC1502190210FE +69F5:1020102011FC1124FDFC102033FE3A2257FE50209040102412A2128A14781000 +69F6:200027FE242A2426F7FE242227AA76AA6FAAA432A596262E2446248227FE2402 +69F7:08203E2008F87F282228496A3E2A08567E820100FFFE054009203118C1060100 +69F8:2110211027D02110F93C27D4201472B46D54A11CA7D42114211421E427262242 +69F9:1020104011FC1104FDFC110431FC3820552454A89124102013FE102010201020 +69FA:2040202027FE2420FDFC242427FE74246DFCA420A56224B429282A2630A02040 +69FB:2200227C22442744FA7C22442244777C6A44A244A27C22282528254A284A3086 +69FC:11F87D0811F81108FDF8110829F824904112860E01007FFC05401930E10E0100 +69FD:1090109017FE1090FBFC129433FC3A9457FC500091F8110811F8110811F81108 +69FE:100011F8110811F8FD0811F830003BFC569453FC900011F81090106011981606 +69FF:1088108817FE1088FCF8102031FC392455FC502093FE102011FC102017FE1000 +6A00:1040102013FE1088FC5013FE32223AFA562252FA928A128A12FA1202120A1204 +6A01:1020102013FE1020FDFC104033FE388855045242959C110411DC110411FC1104 +6A02:2104220447C89452E45C47C89452F45E17C20100FFFE054009203118C1060100 +6A03:1100109E13D21252FE5213DE32523A5257D2521E9292125212D21352122A1044 +6A04:2010271025FE2510FD7C2654257C75546D7CA510A53826542492241024102410 +6A05:2124212422242424F954214A229276106A10A250A25C2250225022B0229E2300 +6A06:1040102013FE1000FD541124315439FC542053FE9242129212FA120A12021206 +6A07:2120213C214422A8FA1026A82AC672BC6AA4A2BCA2A422BC222422242224222C +6A08:2080204023F82110F8A027FE200073F86A08A3F8A20823F82120212222222C1E +6A09:1020102013FE1020FAAA112432AA382056AA512492AA10501050108811041602 +6A0A:24482288F93E22886458729CA92A228825480100FFFE0280044008203018C006 +6A0B:20FE240422282210F8FE20922E9272FE6A92A2FEA29222922296250028FE2000 +6A0C:100011FC112413FEFD2411FC300039FC550455FC910411FC110411FC10881104 +6A0D:102013FE102011FCFC2013FE300039FC550455FC910411FC110411FC10881104 +6A0E:1020101013FE1202F88010FE31103B20557C51449144117C11441144117C1144 +6A0F:100011FC112411FCFD2411FC3040388855F05420904413FE1022112412221060 +6A10:10201020103E1020FC2013FE32023B26568A525293261252128A132613FE1202 +6A11:22782128246C22AAF82A2148229870406840A7FCA0E0215022482C4620402040 +6A12:1040102013FE1242FC2812943AAA34CA50F85300902011241124112411FC1004 +6A13:102011FC112413FEFD2411FC302039FC552455FC904013FE108811D01070138C +6A14:1124124811241000FDFC112431FC392455FC502093FE107010A8112416221020 +6A15:2108210827C82108F91E27D2256475406FC8A108A38825482954211421242142 +6A16:010006C01830EFEE00001FF010101FF0000013FEFC0811E8392855E890081018 +6A17:11FC102013FE1222FDAC102031AC380055FC500093FE108010FC100410281010 +6A18:1020112410A813FEFE0210F83088388854F85420902011FC1020102013FE1000 +6A19:100013FE105011FCFD54115431FC380055FC540093FE102010A8112412A21040 +6A1A:1040102013FE1250FE5013FE32523A5257FE5200929212D41298149214D2188E +6A1B:200027BC208424A4FA9424A4205071886E26A0C0A31020642388203020C02700 +6A1C:1040102013FE1200FE48124833FE3A4856485248927812001554152A1A2A1000 +6A1D:1040107C104013FEFE42127833C43A3C560052FC928412FC128414FC148419FE +6A1E:100013FE1200127CFE441244327C3A0056EE52AA92AA12AA12EE120013FE1000 +6A1F:102011FC10881050FBFE100031FC390455FC510491FC102013FE102010201020 +6A20:1088108813FE1088FC8810F830203BFE5622533292AA137612221222122A1224 +6A21:1110111017FC1110FC0013F832083BF8560853F8904017FC10A0111012081406 +6A22:1040108011FC1104FDFC110431FC390055FE550091FE100212AA12AA1202100C +6A23:1104108813FE1020FDFC102033FE3820541054E0902213B410A8112416A21040 +6A24:2110211E21222254F20826942AE272886A88A2BEA28822AC222A224A22282210 +6A25:108813FE10881080FDF8128830703B8E542055FC902011FC102013FE10201020 +6A26:1210121013DE1528F884102030103BFE5420502091FC10201020102013FE1000 +6A27:2000245C22942114FA94241420A67140691CA7D4A11423942548290821142122 +6A28:200023FE220223FEFA102254223872546A82A250A27C2290221025FE24102810 +6A29:1080108011FE1220FC4013FE3890350853FE551091FE111011FE111011FE1100 +6A2A:1110111013FCFD10111017FE30403BF8564853F8924813F81000111012081404 +6A2B:200027DC251427D4FC5427C8250875146FE2A000A04027FC204020402FFE2000 +6A2C:1040108013FC1244FEF4131432A43A4456A453FC904010241522150A190810F8 +6A2D:1088108813FE1088FCF8108830F8388857FE5088912412FA1020102013FE1000 +6A2E:100013FE10501050FBFE125232523BFE54205124912412281050108811041202 +6A2F:1020102013FE1020FD2410A833FE380055FC5504917411541174110411FC1104 +6A30:100011FC102013FEFE2211AC302039AC540055FC900411FC1004100411FC1004 +6A31:20002FBE28A22AAAFAAA2AAA251478A26880AFFEA110221023A0206021982E04 +6A32:101417FE101013D0FC1013D030103BD0565053D0925013C8124A13CA11861242 +6A33:100013FC100413FCFC0413FC30003BBC552457BC900813FE1108108810A81010 +6A34:1110109413D21012FA50119037FE381057D25252925413D4124A124A13D61022 +6A35:1090108811FE1110FB1015FE3110391055FE5110911011FE110012A412521452 +6A36:100011F8110811F8FD0811F8380037FE524053DC925413D4126817C810541062 +6A37:082008207EFC18302C684AA488207F7C22443E4422283E28221027A8FA440282 +6A38:1050125211541050FBFE108830503BFE542051FC902013FE1050108811041602 +6A39:210421042FE42104F93E27C4200477E46C54A454A7C42444228420E42F142408 +6A3A:108813FE10881000FDFC10A830A83BFE54A854A891FC102013FE102010201020 +6A3B:102011FC112411FCFC2013FE300039FC550455FC910411FC110411FC10881104 +6A3C:27FC240427FC2400FDF8241027FE74206C60A79CA484250829DE2F0831082318 +6A3D:1088105013FE1050FDFC1154318C3974550455FC900813FE1108108810A81010 +6A3E:2114211221122790F97E21502FD471546954A548A5EA25562722250024FE2800 +6A3F:100013DE12521252FBDE100031FC392455FC512491FC102013FE102010201020 +6A40:1040102013FE1040FC8411FE30A838AA5526520091FC11541154115413FE1000 +6A41:1110111011DE12A8FC44110031FC3A0455F4511491F4111411F4111410281010 +6A42:1088105013FE1050FDFC1154318C3974550455FC902013FE1050108811041202 +6A43:102413A810921514FA08140433BA38A854C65380923C138410A8109012A81144 +6A44:2008278820882110FFDE249424A477946C94A794A49424C827882C9420A420C2 +6A45:1080108011FE1354FD54115433FE39545554515497FE10001154112A122A1000 +6A46:20003FFC529092907FFC12901290FFFE082008207EFC18202C704AA889240820 +6A47:103813C0107813C0FC7813C4383C340050C6573891CE173811CE1738114A1186 +6A48:1020102011FC1020FBFE1108339C39085588563E900013FE109010901112120E +6A49:1020112410A813FEFCA8112432223904550451DE92441554109E110412041404 +6A4A:100013FE105013DEFA52125233DE385057FE5222922213FE1222122213FE1202 +6A4B:101811E0104013FEFC88117432523870540055FC91041174115411741104110C +6A4C:13DE125213DE1252FBDE120232F23A9256F2529292F212921292133212021206 +6A4D:100013DE125213DEFE5213DE32023AFA562252729222122212FA1202120A1204 +6A4E:103C13E0112410A8FBFE10A831243A0255FC5124912411FC1124112411FC1104 +6A4F:1088105013FE1020FDFC102033FE392454A853FE900011FC1104110411FC1104 +6A50:01007FFC11101FF00100FFFE80023FF804001FF068100FF00100FFFE0920711C +6A51:2040204027FCF8A02514220877FC6A0AABF8A20823F820402248244429442080 +6A52:100011FC102013FEFE2211AC302039AC540055FC900013FE1040108811FC1084 +6A53:203C27C02044FA24210827FE74026A08AA08A3BE24882AA8213E220824082808 +6A54:221021102FD02010F7BE24A427D470146F94A094A11421C82F08211425142222 +6A55:112410A813FE1202FCF8108830F8380055FC5410911011FE1050109013101030 +6A56:1020112410A813FEFE0210F83088388854F8502093FE107010A8112412221020 +6A57:1088108813FE1088FC0013DE32523A5257DE5252925213DE12521022102A1044 +6A58:100013FC10481030FBFE105230943B50542053FE9252128A1376125212721206 +6A59:102017A410A81292F914120835F4380257F85208920813F8120811101FFE1000 +6A5A:102011FC102413FEFC2411FC30203AAA57AE522293FE122213AE12AA12AA1422 +6A5B:20002FFE28002A28F9482BEE289278846AA0AAA8ABE828882894291429243242 +6A5C:3FFE289025103FDE22222A882F882294242228803FFE21C022A0449858868080 +6A5D:100013FE105013FEFE5213FE300039FC550455FC910411FC102013FE10201020 +6A5E:1020102013FE1020FDFC112431FC392455FC502293FE1042102412A2128A1478 +6A5F:1124112412AA13AEF92412AA33AE392457FE511091141114128A124A12161422 +6A60:102013FE104010F8FB48103033D0383C55C45048903013C410A8119016A810C6 +6A61:108010F8110813FEFD12112239FE344050A25354909813341054109213501020 +6A62:2020272025FE2540FD7C2690257E75006D7CA544A57C2644247C24442444244C +6A63:208020402FFE2882F548251428F470006FFCA444A7FC244427FC244424542408 +6A64:01002488242443E4000024241212A0A0A4A41C1C01007FFC05401930E10E0100 +6A65:282211FC28284BFE984029FC4E8488FC288410FC01007FFC05401930E10E0100 +6A66:102011FC10881050FBFE100031FC392455FC512491FC102011FC102013FE1000 +6A67:11041088100013FEFE2212AA32723A2257FE540091FC110411FC110411FC1104 +6A68:102011FC10201088FBFE108831FC390455FC510491FC110411FC108811041202 +6A69:108812AA12DC1488F954122233FE3A02540050F890881088108A110A12061400 +6A6A:1110111411D21250FA7E155030903AA85528514492441482100812A412521452 +6A6B:1088108813FE1088FCF8100033FE382055FC552491FC112411FC108811041202 +6A6C:100013DE108812A8FBFE118832DA3CA655F85108910811F81108110811F81108 +6A6D:102013FE102011FCFD0411FC302039FC5488505093FE102011FC102010201020 +6A6E:104013BE12921252FEAA1324304039FC550455FC910411FC110411FC10881104 +6A6F:208822AA22DC2488F9542222200073FE6A42A444A3FC20442044208421142208 +6A70:104011FC110411FCFD0411FC310439FC5420552490A81124102013FE10201020 +6A71:200027FE24002404F7E4240425DE75446D44A5D4A40C2544248424E42B142008 +6A72:102013FE102011FCFC0011FC390435FC508853FE900011FC1104110411FC1104 +6A73:2010275425382510FD7C271025FE75286D24A752A5FC2514252425242B542088 +6A74:1090109212D4129AFAD2174E308839F05420504493FE10221128122414A21040 +6A75:2288228827C82290FA9E27D4202477D46C54A7D4A45427C824482454246424C2 +6A76:21102114211227D2F91027DE247077D26C52A7D4A1142FD8210A211A21262142 +6A77:2040228822EA2EAAF2AC22E822AA76AA6AE6A000A1202120212022222422281E +6A78:10F81088108810F8FC88108830F8380057DE5252925213DE1252125213DE1252 +6A79:108010F8111013FCFD2411FC392435FC500053FE900011FC110411FC110411FC +6A7A:100013DE125213DEFE5213DE32023AFA568A52FA928A12FA128A1202120A1204 +6A7B:200023F820482048FBF82088208877FC6800A7BCA294229427BC229422D42F3E +6A7C:2220223C24442578F9082EFE222074D2681AAF2CA0CC201A232A2CC820282010 +6A7D:10101210117C1010FCFE1044332839FE5510557C911011FE1110111012FE1400 +6A7E:11FC1104110411FCFC0013DE32523A5257DE502093FE107010A8112416221020 +6A7F:100013FE100011FCFD2411FC31243BFE540055FC912411FC112411FC100013FE +6A80:20402FFE200027FCFC0425F4251477FC6800A3F8A20823F8220823F820002FFE +6A81:102013FE100011FCFD04117431543974550455FC900810F0102013FE10A81326 +6A82:109013FC129413FCFE9413FC30003BFC560052F8920013FE1520151415481986 +6A83:001E7BE4492853FC602053FE48004BFC680453FC400443FC0100FFFE0920711C +6A84:2108220827C82450FFDE246427D472146914A7D4A21423C822482454255428A2 +6A85:1020113C112013FEFC10101433FE3A1057F05254925412D41368144A18961322 +6A86:2108210821482548F58E290822887448693EA162A5A22522292222A2247E2822 +6A87:10A0109011FE1320FDFC112031FC392055FE510093DE12521252127212021206 +6A88:100013FC12941294FBFC100037FE380057FC520493FC10A2111413081D441182 +6A89:100017E0125E13D2FE5213D23A7237DE504053FE902011FC1020102013FE1000 +6A8A:2108210821142FD4F12227C0245C77C86C48A7C8A13E2FC82108210821082108 +6A8B:108813FE108813FEFC88112432FA382055FC552491FC112411FC102013FE1020 +6A8C:200023FC22942294FBFC20002090779E6890A090A39C20902090279E20902090 +6A8D:1040102011FC1088FC5013FE300039FC550455FC910411FC10201294128A147A +6A8E:1020105010881124FEFA10503124395455FC502093FE1242129212FA120A1206 +6A8F:1050125211541050FBFE108830503BFE542051FC902013FE10A8112416221020 +6A90:110011F8120817FEFA88132433FE3A0056FC520092FC120012FC148414FC1884 +6A91:100011FC102013FEFA2211AC302039AC540051FC9124112411FC1124112411FC +6A92:082008207EFC18302C684AA69FF010D01710111017D0155027CA212A4FE68022 +6A93:210026DC24542454F6D42454246677C0681CA014A7D42114210821C827142222 +6A94:1020112410A813FEFE0210F83088388854F8540091FC112411FC112411FC1104 +6A95:0800FF7808487F4849867F0049787F480828FF9049287F440100FFFE0920711C +6A96:104412241128107EFC101028334A391C5528554C911A112A1148111012FE1400 +6A97:00407C2045FC44887C5043FE7C20A5FC24203C2001007FFC05401930E10E0100 +6A98:20102008278824BEFC8024942788747E6C08A788A6BE2A882A882B8832882008 +6A99:21F8210821F8250AF5FA250A25FA74026F9EA090A0902F9E2492249224922892 +6A9A:2110211027BC2110FBB82554291270006FFCA044A24022782240254028FE3000 +6A9B:2000227C21442174F854205426FE72826ABAA2AAA2BA2282228A2284250028FE +6A9C:204020A023182DF6F00027FC255474E46FFCA000A3F8220823F8220823F82208 +6A9D:101013D412521252FBD0101037FE3A5057D2525293D4125412EA174A10561062 +6A9E:2200239E248A290AF7D22566254077D46D5EA564A7C42544255E2544244428C4 +6A9F:100013FE105013FEFE5213FE300039FC550455FC910411FC110411FC10881104 +6AA0:2420FF20243E7E4482847A284A107A2804440100FFFE054009203118C1060100 +6AA1:100011FC115411FCFC2011FC30203BFE5488545091FC102013FE102010201020 +6AA2:1020102010501088FD0412FA3000380055DC5554915411DC1088108811541222 +6AA3:2040204027FC2248FA4825542FFE70006BF8A208A2E822A822E8220823F82208 +6AA4:10441028120011FEFD20107C30443B7C5544517C9144117C11441280147E1000 +6AA5:1104108813FE1020FDFC10203BFE34545192509093FE109010D4138A109611A2 +6AA6:20022FE222822FEAFAAA2AAA2FEA700A6BCAA00AAFEA210A25422522292A2304 +6AA7:108813FE10881100FBFC155430D43B24545450949348102010A4128A128A1478 +6AA8:1104108813FE1020FDFC102033FE38005620513E904211141610122812441082 +6AA9:102013FE100011FCFD04117431543974550455FC900011FC100013FE11241262 +6AAA:1020104010F8128AFD8C10F8318C3A8A54F8502093FE107010A8112416221020 +6AAB:2080204027FE2402FA2423BC34A46AA86510A2E8A4042BFA20402248244420C0 +6AAC:211027FC211027FCF40423F8200077FC6880A144A6A8217026A8212626A02040 +6AAD:2200227C254424C4F87C27442244727C6F52A252AA542748224823542C622040 +6AAE:204027FC204023FCF80027FE200273F86840A7FEA00027FE200827FE24A82798 +6AAF:20402FFE204027FCF80023F832086FFE6802A7FCA11023F8204027FC20402FFE +6AB0:21082110223E2222F4BE2722213E72086CBEA7AAA02A20AA256A252E24082008 +6AB1:110811EE12941042FC88108833FE388854F8548890F8108813FE108811041202 +6AB2:13FE122213FE1222FEFA12AA32FA3AAA56FA522693FE120A13FE128A125A13FE +6AB3:2080204027FE2402FBFC2148225077FC6A04A7FCAA0423FC220423FC21082204 +6AB4:108813FE10A81090FDFE132031FC392055FC512091FE110013FC10881070138E +6AB5:1044128412EA124EFEA412EE32223BFE5644528492EA124E12A412EE122213FE +6AB6:1020102013FE1050FC8813FE32003A7C5644527C920012EE12AA12EE120013FE +6AB7:200027FC22482444FFFE244426EC75546EECA444A6EC255426EC244424542408 +6AB8:1040102013FE1222FD54114A323A380055FC515493FE100011FC102010A01040 +6AB9:24202220223E2F40F490247E272475426DFEA504A57425542974290433142008 +6ABA:204027FE200021F8F90821F8200077FE6C02A3F8A180264421B8266821A62660 +6ABB:100813E8128813EEFE2813F432823BE2540051FC915411541154115417FE1000 +6ABC:203E27C022442128FBF8204027FC70006BF8A008A3F8200823F82544252A28FA +6ABD:100011FC102013FEFA2211AC302039AC540053FE902011FC115411541154110C +6ABE:08202AA44D28145022887FFE4002882408207EFC08301C682AA4C92208200820 +6ABF:3FFE28942F9228902FFE20102F9028A82FA428C4298020404FFE416086581846 +6AC0:110817FE110811F8FD0811F8390837FE5108529495E2104813FC1040124814C4 +6AC1:1040102013FE1242FC2812943AAA34CA5378502091FC112411FC102213FE1002 +6AC2:200027BC208424A4F29424A4212072106FFCAA20A3FC222023FC222023FE2200 +6AC3:27FE242025FC2524FDFC242027FE75046DFCA504A5FC250425FC2488250427FE +6AC4:101C11E0102013FEFC2011FC31AC397455FC542091FC102013FE10001154122A +6AC5:2080204027FC2110F0A42F58255475526B58A000A20823F8220823F822082408 +6AC6:2104221427CC2544FD5427CC2546755C6FC4A104A2A422D424F02482287E2000 +6AC7:2080209E208427E8FCBE2492249277DE6E52A55EA5522492289E2940314C2252 +6AC8:202427A820922514F2E8240423FA72086BF8A110A7FC200021F021102212240E +6AC9:200027FE24842484F7E4249E25C474046DD4A54CA5C42544288428C433142008 +6ACA:200027BC24A427BCFCA427BC248475F46E94A4E4A71C24E424A424A424E4240C +6ACB:104011FC11241194FD4C112439FC342053FE528A912413FE108010FC1104120C +6ACC:23FC204021F82108F9F8210827FE74426AA4A28AA47A208021F822882070238E +6ACD:1042139C121013DEFE94129434203BFC560453FC920413FC120413FC11081204 +6ACE:2040202027FE2488FDFC248827FE74206DFCA524A5FC252425FC240024882904 +6ACF:200020FE242822FEFAAA20FE201071FE6E44A2FEA344227C2242223E250028FE +6AD0:1FF011101FF011101FF000003EF82AA83EF82AA83EF801007FFC05401930E10E +6AD1:23F82248224823F8FA48224823F870006FBEAAAAAAAA2FBE2AAA2AAA2FBE28A2 +6AD2:1088108813FE1088FD1011DE3A52355452885174920211FC1020112412221060 +6AD3:108011F8120815FCFD2411FC392435FC5154522A91FC110411FC110411FC1104 +6AD4:100013FE124813FEFE4812FC32A43AFC56A452FC922013FE132A157A150A1906 +6AD5:108811DC108813DEFC881154322239FC550455FC910411FC110411FC10881104 +6AD6:2020203E202027FEFC2225F8242275FE6D24A5FCA52425FC28402AA4328A247A +6AD7:110817FE11081000FBFC129432943BFC542853FE9220132412A81292142A18C6 +6AD8:108813DE108811DCFC8813DE30883BFC540451FC900413FC104012A4128A147A +6AD9:1088108817FE1088FBFE1200327C3A44567C520092EE12AA12AA12EE120013FE +6ADA:100013DE125213DEFE5213DE32023AFA568A52FA920212FA128A12FA12021206 +6ADB:1108110811EE1294FC42100033DE3A5257D2525293D2121A1294135012101010 +6ADC:01007FFC11101FF00100FFFE88421F6032504C4837FEC1007FFC05401930E10E +6ADD:102013FE102011FCFC0013FE32523BFE550455FC910411FC110411FC10881104 +6ADE:2120213C21442278FA8824FE2F2071526A1AA4ACAFCC209A202A2AC82AA82810 +6ADF:244424E428A82AAAFEEE24A42AAA7EEE6A42A040AFFE20E0215022482C462040 +6AE0:202027FE241027D4FD4A2484250277DC6C54A5E6A50025DC2844285431482094 +6AE1:2210221023DE2528F884204423F870506FFCA080A3F82D0821F8210821F82108 +6AE2:210827C825482FF0F55E27E4211477D46D54A7D4A2142FC82448269421942662 +6AE3:110817FE11081410FAFE1210307C3854567C5254927C121012FE1210151018FE +6AE4:121013DE15281084FD08109037FE380057D4525493D4125413D41244125412C8 +6AE5:1040102013FE1244FBF4124432EE3A0456F452AC92E4121412A4147415941808 +6AE6:102013FE125013FEFE5213FE32003BFE56925348923A124012FC1548143019CE +6AE7:24102210207A2712F814277E20087710683CA764A5A4253C25242724253C2024 +6AE8:1040107C104013FCFE4413F032443AFC56A852F892A812F8120015FC15541BFE +6AE9:13DE125213DE1252FBDE1242327A3A8A571252DA928A12DA128A12FA120A1204 +6AEA:200027FE24442598FC8827DE248875DC6EAAA488A4202520253C2920292037FE +6AEB:00207F2410FC28284DFE1620247C4EC4157C64440C7C01007FFC05401930E10E +6AEC:2200213C27A42024F4BC232427A4713C6924A7A4A13C259025582968252A2246 +6AED:2F7E29102F502950FF7E2A282B287D4A6886A7F8A40827F8240827F820002FFE +6AEE:100013FE102013AEFEAA12AA33AE382057FE502093AE12AA12AA13AE102013FE +6AEF:2206223827882488F90827DE254875486FDCA55AA56827E820082AA82AA82008 +6AF0:208020402FFE2000F7FC24A427FC72486950A208A44420A8211023082D462180 +6AF1:52107EFE28447E28A2FE3E1020103E7C22103E1001007FFC05401930E10E0100 +6AF2:20202F3C214425BEFA2A212A2FBE72906B2AA25AA22C225C222A22482A282410 +6AF3:2210211027DE2010F45E228227DE70106FDEA450A7DE245027DE2450245224CE +6AF4:2108210827CE2112F92427DE2552755E6FD2A11EA392255E2940211421122122 +6AF5:1088108813FE10A8FC9011FE31203BFC552051FC912011FE110012A412521452 +6AF6:102013FE122211FCFC2010F8302039FC542055FC915411FC104012A4128A147A +6AF7:208027FC240427BCF8A026BE22A277B66AAAA6AAA0B626A222BE27A022A2267E +6AF8:2140226C2244236CFAA423AC22A477FE6908A244A5F2204027FC204020402040 +6AF9:211027FE215023F8F84827FE204873F86D54A75CA44427FC2444275C25542954 +6AFA:200027FC20402FFEF8422358204073586800A000AEEE2AAA2AAA2AAA2EEE2AAA +6AFB:13DE125213DE1252FBDE125233DE398C5652504097FE10881190106010D81304 +6AFC:2148214C22AAF80827FE21487368694AAB6AA14C236C2148216A239A20262042 +6AFD:00187BE0495053F8604053F8480849F86840529444F401007FFC05401930E10E +6AFE:21822E3C20882A90F522243C27887A126A3EAF88A2082AAC2AAA2BCA2EA82090 +6AFF:108812AA12DC1488F954122233FE3A0254F8508890F8100011FC110411FC1104 +6B00:204027FC200023B8FAA823B8211077FC6910A7FCA1102FFE212823102D482186 +6B01:22882FE82AA82FE8FABE2FE830086FDC681AABE8A8282FC82AA82A482B283228 +6B02:108813FE10881412FAFE101034FE3A9256FE509291FE1292160412FE1244122C +6B03:11F0121017FC1204FBFC122433B83A2255FE521097FC124413FC10D0114A163E +6B04:13DE125213DE1252FBDE122232FA3A2256FA52AA92FA12AA12FA127212AA1226 +6B05:2140226C2244236CFAA423AC22A477FE6908A2F4A44223F8204027FC204020C0 +6B06:2108229423DE26B4FBDE229423DE72946BDEA210A7FC21082090206021982606 +6B07:13FC110811F81108FDF8110E37F8380857FE5294939C1294139C12D617BC1084 +6B08:122213FE109011FEFB1015FE311039FE551051FE910013FE128A137612521276 +6B09:249222942FFE2110F7FC204023F870406FFEA480A7BC2494279424C82F9420A2 +6B0A:108813FE108813DEFE5213DE30A0389055FE512093FC152011FC112011FE1100 +6B0B:13DE125213DE1252FBDE125233DE389055FE511093FE151011FE111011FE1100 +6B0C:2090209027FE2094F80A21FE250877E8694AA1EAAF2A25EA254C29EA22162462 +6B0D:210827FE212823FEFA2027FC2A2073FC6A20A3FEA080231C2204239C220423FC +6B0E:2288F93E2288729CA92A2288FFFE80023E0822FE3E0822483E28280824283A10 +6B0F:200027FC24A424A4F7FC221022A874BE6F68A23CA4A82FBC20282AA82ABE2020 +6B10:13DE100013DE1252FB5A125230203BFE565053FE925213FE129212DC129214CE +6B11:252827BE294827BEFB1825AA294673FC6A04A3FCA20423FC220423FC21082204 +6B12:210447C88812F3BC20084B92F83E0380AAAAABAA01007FFC05401930E10E0100 +6B13:2248215027FC2404F9F0211027FC75546CE4A7FCA04027FC20402FFE22A42452 +6B14:13DE125213DE1252FBDE10A031FE3B2055FC512091FE100011FC10881070178E +6B15:27BC24A427BC2000F7FE24002590749E6FD4A564A5D4255425D425682BC83054 +6B16:2790251E27A82484F7BE252A27BE70006BF8A208A3F8220823F820A02124261C +6B17:108813FE108813DEFE5213DE32523BDE562253FE92AA12FA1222127212AA1224 +6B18:13FE120213FE1292FE54129232FE3AAA56FE532292FA12AA14FA142219FA1004 +6B19:27FC244427FC2444FFFE2AAA2FBE7AAA6FBEA220A7C020842FFE204225482884 +6B1A:21F0221023E02020F7FC2188265071A86E64A1A0A2482FBE2AAA2FBE228A2FBE +6B1B:23FE202027FE2422F9AC228027DE72926B92A11EA7D2255227DE21122FD22126 +6B1C:204027FC224823F8F0402FFE2AAA73B86910A7FCA1102FFE212823102D482186 +6B1D:2288F93E2288729CA92A22887FFC44447FFC22083EFE22483E28280824283A10 +6B1E:27FC20402FFE2842FB582040235870006EEEAAAAAEEE20002FFE224825542FFE +6B1F:228027DE229227D2FD5E27D231126C9E67D2AD12B7DE250827CC251427D42422 +6B20:0800080008000FFC10041108211041000100028002800440082010102008C006 +6B21:00804080208020FC010409080A4014401040E0A020A021102110220824040802 +6B22:00800080FC8004FC050449082A401440104028A024A045108110020804040802 +6B23:022007203820207E204220843F10241024102410242824282448444444848102 +6B24:2020202020203F7E2042408440107E10021002101A28E2284248024414840902 +6B25:004000407C40447C4484448845207C2044204450445044507C88448801040202 +6B26:084008401440147C228452888920082000207E50025004500488088809040202 +6B27:00407E404040447C6484548849204820542054506450405040887E8801040202 +6B28:2040204040407E7C828402887B204A204A204A507A504A500288028815040A02 +6B29:00207F201120117E21422584421080103F1021102128212821283F4421440082 +6B2A:102010209220927E92429284FE10101010109210922892289E48F24400840102 +6B2B:202020203F20487E884208847F10081008102E10282828282F48F04440840102 +6B2C:102008200820FF7E0842108422107C10091012102428C82814482244C0840102 +6B2D:0020FE208220927E92429284FE1092109210AA10A628C2288248FE4482840102 +6B2E:422022202420FF7E084208844910491049107F10092810281048204440848102 +6B2F:104010401040FE7C108410887D20002000207C504450445044887C8845040202 +6B30:0820082010207F7E5542558455105510551055105528552857A8FC4400440082 +6B31:104010402840247C428480887D20002000207C504450445044887C8845040202 +6B32:142012202120497E0842148422104110BE1022102228222822483E4422840102 +6B33:082008200F20087E08427F845510551055107F10552855285528514445444282 +6B34:104008407E40427C42847E88432042207E204050485044504A88528861044202 +6B35:40404C407040447C44843C8841207C2090201050FE5010502888248845048202 +6B36:08200820FFA0087E08427F84491049107F1008101C282A284948884408840902 +6B37:422024201820247E52421084FF10201028107E10AA282A282A482E4408840902 +6B38:102010202020447EFE42028440107C1090101010FE2810281048284444848502 +6B39:082008207F20143E22224144FF5002907A104A104A107A284A2802440A440482 +6B3A:22202220FFA0227E22423E84221022103E1022102228FFA82448224442848102 +6B3B:104052405440907C288444888320102010205250545090502888248843048202 +6B3C:0020F7201120557E22425584891010100010F710112855282228554489441082 +6B3D:104010402840247C4284BC8811201020FE2010509450585050881E88F1044202 +6B3E:08200820FF20087E08427E8400107E100010FF1008284A284948894428841102 +6B3F:102010203E20227E4442808410106610421042106628422842487E4442840102 +6B40:082008207F201C7E2A42498400107E100010FF1008284A284948894428841102 +6B41:22202220FF20227E3E4222843E1022102210FF1040285428624840447E840102 +6B42:102092209220927EFE420084FE1010102010FE10AA28AA28AA28AA44AA448682 +6B43:02200F207820087E0842FF8428104B10491049106B28492849487F4441840102 +6B44:00203E202220227E3A422A842A107F1041105D10552855285D28414445444282 +6B45:0040FE402840287CFE84AA88AB20FE2010201050FE50105010881E88F1044202 +6B46:10200820FF20007E42422484FF1000107E10421042287E28424842447E844302 +6B47:00207E2042207E7E42427E8420107F1089104910552841287D2801440A440482 +6B48:102028204420827E7D420084F11095109510F51095289528F52891449544B282 +6B49:22201420FFA0147E14427F841510FF9015107F1014283628552894C414441482 +6B4A:10200820FF20007E7E4242847E100010FF108110BD28A528BD28814485448282 +6B4B:03207C204720447E5F42558456105C10551053105028572855485544A9840102 +6B4C:0020FF2002207A7E4A427A840010FF1002107A104A284A287A2802440A440482 +6B4D:102020207F20417E41427F8440107FD040107F9000A8AAA8AAA800C405440282 +6B4E:22202220FF20227E3E4208847F1049107F1008107F280828FF48144422844102 +6B4F:22202220FFA0227E3E4208847F1049107F1008107F2808287F2808440F44F082 +6B50:0020FFA080209F7E914291849F108010BB90AA90AAA8AAA8BBA88044FFC40082 +6B51:0410079004103FDE245227243C88238820882F0832482A945FD442148A140422 +6B52:20201020FE20447E2842FE8482109210FE109210BA28AA28AA28BA4482448682 +6B53:202020203F20483E88227F44145022907F10A4103F1024283F2824443F442082 +6B54:10201E2010207F3E51225C4472504E9040104A106A905B284A288F4478440082 +6B55:08207F200820223EFFA222447F5041907F1041107F1041287F28224441448082 +6B56:0820FF2008207E7E00427E8442107E102410FF1000287E28422842447E444282 +6B57:04103F9004907FDE04923FA40408554875C844487FC8445475D4555455548462 +6B58:0820292029204A7E144222844110001022102A90B72862282228524445448882 +6B59:0820142022205D3E80A23E4422503E9000107710111055283328554411443382 +6B5A:11100A107FD0041E3F9204247FC8248815087FC800083F94209420943F9420A2 +6B5B:082008201420227E4142BE840010001077105510552877282228224455448882 +6B5C:00207F205520557E7F4220847F1091107D10551055287D2811287D4405440282 +6B5D:00207F2055207F7E08427F840810FF90221014107F280828FFA8084408440882 +6B5E:00207F2041207F7E41427F842210551077102210552877280028554455440082 +6B5F:28204B204D20497E6B424D845510771055105510FFA800282228214441448082 +6B60:772055202220557EF742558422105510FF9014107F28552863285D4441447F82 +6B61:22202220FFA0227E77425584771012103F106410BF2824283F2824443F442082 +6B62:01000100010001001100110011F81100110011001100110011001100FFFE0000 +6B63:00007FFC0100010001000100110011F8110011001100110011001100FFFE0000 +6B64:0440044004402444244827502460244024402440244024422F42F042403E0000 +6B65:0100010011F8110011001100FFFE0100010011081110212040C003001C00E000 +6B66:004000503F4800480040FFFE0040044004402740242024222412278AF8064002 +6B67:0820082008200BFE48204E20482049FC4884488848484E505820E05001880606 +6B68:0100010011F8110011001100FFFE00000100110011F811001100290047FE8000 +6B69:0100010011F8110011001100FFFE0100011011081114212440C003001C00E000 +6B6A:00007FFC0100030005601918610400007FFC0100110011F811001100FFFE0000 +6B6B:080008FE0880088048804EFC488448844884488448FC4E805880E08000FE0000 +6B6C:010011F811001100FFFE010002001FF0101012101110FFFE1210211040508020 +6B6D:10201020102011FC50205C2053FE5008500851FE50085C887048C00800280010 +6B6E:0100010011F811001100FFFE00000810081048904E9C489048904E90F1FE0000 +6B6F:0100010011F811001100FFFE0000292825482FE823882548292820083FF80008 +6B70:00007EFC122452A4932422442A544488081008104E9C489048904E90F1FE0000 +6B71:1008103C11E0102053FE5C2051FC512451FC512451FC5C2071FCC02003FE0000 +6B72:008008FC088008807FFE002800243FFE20202FA422242A182A90512A46469882 +6B73:008008FC088008807FFE002800243FFE20202FA422242B182A9252AA4A468482 +6B74:3FFE221022103FBE261027382AD43292221022502040227C424042409FFE0000 +6B75:102011FE102011FC50205DFE500051FC510451FC51045DFC7104C1FC00880104 +6B76:08442F7828422F3EF0001FF011101FF011101FF001003FF821482FE824282018 +6B77:3FFE2000230C3C7024103F7E24102E3835542492208024F844804480BFFE0000 +6B78:10007DFC44047CFC40047DFC44007FFE122210205DFC512451245D34E1280020 +6B79:0000FFFE02000200040007F8080810102410422001400080010002000C007000 +6B7A:0080008000FE088008800FF8100814102210412001400080010002000C007000 +6B7B:0000FFFC1080108010841E88229022A052C08C800480088408841084207C4000 +6B7C:0008003CFDE0202020203C20442047FE64209420082008201020202040208020 +6B7D:0008001CFDE0210021003D0045FE451065109510091009101110221042108410 +6B7E:00800080FC8020FC21543E5444544494649495240A2408441044208441288010 +6B7F:00800080FCFC210421043E28441047FC65049488088808501020205041888606 +6B80:0008003CFDE0202020203C2045FE442064209450085008501088208841048202 +6B81:000000F8FC88208820883D06460045FC64849484084808501020205040888306 +6B82:000001F8FD08210821083DF845084508650895F8090809081108210847FE8000 +6B83:00200020FC2021FC21243D2445244524652497FE082008501050208841048202 +6B84:00200020FC50208821043E124420444065889410082008441188201040608380 +6B85:00200020FD20212021FC3D2046204420642095FC082008201020202043FE8000 +6B86:0020FC202020204020483C8445FE4482640094FC088408841084208440FC8084 +6B87:00800080FCFE210022F83C104420444065FC9494089409241224244440A88110 +6B88:00200020FC40208021FC3D544554455465549554095409541154215443FE8000 +6B89:0080FE8020FC210421043FF445144514A5F41914091411F41114200440148008 +6B8A:00200120FD2021FC21203E20442047FE647094A808A809241124222240208020 +6B8B:00500048FC40205C21E03C40445E47E064449448083008221052208A43068002 +6B8C:000003FCF800212422483C904A48492468009BFC084010401040204047FE8000 +6B8D:0008003CFDC0200421443CA8440045F8641094200BFE08201020202040A08040 +6B8E:00200020FC2023FE20203C2045244524652496AA082008501050208841048202 +6B8F:00280024FC24202023FE3C20452044B264B4946808A809241222202040A08040 +6B90:00200020FDFE202020203DFC4524452465FC9420087008A81124222240208020 +6B91:0020FC2023FE202020203DFC45044504650495FC08500850109220924112820E +6B92:000000F8FC88208820F83C0045FC450465249524092409241050204840848304 +6B93:00200020FC50205020883D0446FA440064449424092408A81088201043FE8000 +6B94:00200020F9FC202420243BFE4824482469FC9A22097410A81124222240A08040 +6B95:00400020FDFC200021083C90440047FE6400940009FC09041104210441FC8104 +6B96:0020FC2023FE202020203DFC450445FC650495FC090409FC1104210447FE8000 +6B97:00400080FBFC211022483C464BF84A486A489BF80A48124813F820424042803E +6B98:00900088FCBC23C020503C2444D4472C649094BC0BC008481050202440D4830C +6B99:001C03E0FA2023FE22203A924B0A4A0669FC9904090411FC1104210441FC8104 +6B9A:01040088FC5021FC21243D2445FC4524652495FC0820082013FE202040208020 +6B9B:000003FCF808201020203BAE4AA24AAA6AA49AA40BAA103210A0204047FE8000 +6B9C:00480148FD4823FE21483D484578450065FE94200BFE087010A8212446228020 +6B9D:00200020FBFE202021FC38404BFE488869349AE2082011FC107020AC43228020 +6B9E:000001F8F908210821F838004BFC4A046BFC9A040BFC120413FC209041088204 +6B9F:000001F8FD08210821F83D08450845F8640097FC0A940A941294229447FE8000 +6BA0:00200040FDFC210421FC3D0445FC450465FC942808240BFE1050208841048602 +6BA1:00400020FBFE2202241439E04900490069FC9910091017FE1000209041088204 +6BA2:01540154FBFE215421543A724C004BFE6A22982009FC112411242124412C8020 +6BA3:0088FC8823FE208820F83C2045FC452465FC94200BFE082011FC202043FE8000 +6BA4:008000FEFD0022FC20843CFC448444FC640097FE088009FE12522092412A8044 +6BA5:0040FC2023FE220220003DFC442045FC652495FC092409FC1000208841048202 +6BA6:00400080FDFC210421FC3D0445FC450065FE950009FE080212AA22AA4202800C +6BA7:02140112FBD22010203E3BD04A504A506BD099280BA813681528212A452A8246 +6BA8:002001FCFD2421FC20203FFE440045FC650495FC090409FC110421FC40888104 +6BA9:008000DCFA8423D424483A944B244C406A4899500FFC10E0115022484C468040 +6BAA:002003FEF82021FC20003BFE4A0249FC680099FC090411FC1104208843FE8000 +6BAB:000003DEFA52225223DE380049FC492469FC992409FC102013FE202040208020 +6BAC:000001FCFD5421FC20203DFC442047FE6488945009FC082013FE202040208020 +6BAD:000003FEFC0021FC21243DFC452447FE640095FC092409FC112421FC400083FE +6BAE:00200020FC50208821043EFA4400440065DC9554095409DC1088208841548222 +6BAF:00400020FBFE220221FC39484A5049FC6B0499FC090411FC110421FC40888104 +6BB0:002003FEF82021FC20003BFE4A524BFE690499FC090411FC110421FC40888104 +6BB1:0088008CFBEA208820883BFE49484B6A694A9B6A094C136C114A216A47968022 +6BB2:0148014CFAAA200827FE39484B68494A6B6A994C0B6C1148116A239A40268042 +6BB3:00000FE00820082008201020201EC0003FF010100820044003800C603018C006 +6BB4:00007EF840884488648854864900480055FC54846488405040207E5000880306 +6BB5:060038F82088208820883C86210020003DFC208420882C50F020205020882306 +6BB6:1000087800487F480848088608007EFC08440844082808280F10F02840440182 +6BB7:0600387820483E4822483E8622003EFC20443E442228222842104A2884440182 +6BB8:080008787F48084808483E8600003EFC2A442A443E2820282010402840448182 +6BB9:00007F78484848485F486486440044FC7F4444444A285128601040287E440182 +6BBA:040044782848104828484486920010FCFE441044582854289210122850442182 +6BBB:080008787F4808483E4800867F0041FC82443C44242824282510262844448182 +6BBC:080008787F4808483E4800867F0041FCBE4400443C2824282510262844448182 +6BBD:420024781848244852481086FF0020FC3E446244BE2822283E1022282A442582 +6BBE:100010787D4812481448FF86100020FC7E44A24422283E28221022283E442382 +6BBF:00003F78214821483F4820862A002AFC3F442A442A283F2820104A2891442182 +6BC0:2000CE7882488248EE4882868200FEFC10441044FE28102810101E28F0444182 +6BC1:2000CE7882488248EE4882868200FEFC00440044FE28102810101E28F0444182 +6BC2:1000FE7810487C480048FE86820010FC7C44204450287C281010FE2810441182 +6BC3:20001078FE4800487C4844867C0000FCFE448244BA28AA28BA1082288A448582 +6BC4:10007E7810487E4852487E8652007EFC1044FF4410287E28421042287E444382 +6BC5:100008787F4822481448FF86100029FCCE4414442628CD2815102428D4440982 +6BC6:0000FFB880289F28912891469F00807CBBA4AAA4AAA8AAA8BB908028FFC40082 +6BC7:1000673841287728412841467F00087C49242A24FFA81C282A10492888440882 +6BC8:2040CE9C8A94AA94AAD4EE94AAA6AAC0AA9CAA94EE94A8D42B884888489488A2 +6BC9:7F7848485F4C64805F784A4851307F4C00007FFC1110111029284544FFFE0000 +6BCA:0878FF4808863E782A483E3040489FF40200FFFE08203FF8D0161390129013B0 +6BCB:00001FF01110111011101110FFFE21102210221022103FFC0410081010A02040 +6BCC:00001FF011101110111011101110FFFE221022102210221022103FF000100010 +6BCD:00001FF01010121011101110FFFE20102210211021103FFC0010001000A00040 +6BCE:10001FFC200020005FF0911011101110FFFE2210221022103FFC001000A00040 +6BCF:10001FFC200020005FF0901012101110FFFE2010221021103FFC001000A00040 +6BD0:01000100FFFE01003FF800001FF011101110FFFE211022103FFC041008501020 +6BD1:00103E502250325C2A7422D42254FF544254525C4A5042507F420242143E0800 +6BD2:01003FF801001FF001007FFC00001FF012101110FFFE221021103FFC00100060 +6BD3:402040107DFE80207C48448465FE5402FEA844A8A4A894A8FEAA052A29261200 +6BD4:0080208020802084208820903EA020C0208020802080208226823882207E0000 +6BD5:2080208820B03EC0208020842684387C21000100FFFE01000100010001000100 +6BD6:2080208820B03EC0208020842684387C0100009048A4484289820E101810E7F0 +6BD7:001001107D1055125512551455D87D1055105510551055127D524592010E0000 +6BD8:00003FF8210821083FF8210821083FF80000208020843E9820E020842684387C +6BD9:410041187DE041044D0470FC0000FFFE108010883E9042E0148008843084C07C +6BDA:1FC020807FE0A0203FE020883CF420841FFC20407FF0A2103FF005441924E0FC +6BDB:001001F87E000200020003F03E000200020003FCFE00020002040204020401FC +6BDC:08201C207020102010A81CA47124112212221C20F02010A2104210020FFE0000 +6BDD:08041C08703011C010041C08703011C010041C08F03011C2100210020FFE0000 +6BDE:2080208820B03EC020842084267C380000F03F0001F03F0001F87F02010200FE +6BDF:0100111011082124414401800E00F00000F03F0001F03F0001F87F02010200FE +6BE0:080008007F7C094411441144257C420000F03F0001F03F0001F87F02010200FE +6BE1:08401C407040107C10401C40704011F811081D08F10811FA110A10020FFE0000 +6BE2:10003BF8E0A020A023F83AA8E2A822A822B83B08E20823F8220A200220021FFE +6BE3:00007EFC22441224060C1A3462C4000000F03F0001F03F0001F87F02010200FE +6BE4:281824E04220923810E02020443CFEE002222422241E24002402440243FE8000 +6BE5:11003900E1FC220424043BE4E22423E422243A24E3E42004202A201220021FFE +6BE6:0008FF1C44E0442044207C3C44E044207C20443C44E04F22F4220422041E0400 +6BE7:10503848E0402FFC20403A48E2482F5022503A20E2282468289A210A20021FFE +6BE8:08201CA070FC112010201DFE7050105010901C92F112120E100010020FFE0000 +6BE9:08201C20712410A410A81C2073FE102010701CA8F1241222102010020FFE0000 +6BEA:10403840E090210823FC3824E12021FC21203A20E7FE20202022202220221FFE +6BEB:01007FFC00001FF010101FF000007FFE400281F43E0003F03E0003FA7E0201FE +6BEC:08201C28702413FE10201D2470A8107010A81D24F22210A0104010020FFE0000 +6BED:0008FF1C00E000207E20423C42E042207E20003C42E0222224220F22F01E4000 +6BEE:1020102011241122FA2A101014601B80303CD3C0107C13C0107C17C25042203E +6BEF:10403A44E244244820A03910E608204420403A48E248245020A22112220A1FFE +6BF0:08401C2071FC100010881C5073FE100010F81C88F088108A10FA10020FFE0000 +6BF1:11003900E1FC220424843C94E2A427FC208439C4E2A4249420AA209220021FFE +6BF2:0004F70E117055102210551C897010100010F71E11705510221255128912100E +6BF3:01F03E0003F03E0003FA7E0201FE0000183071C01C7871C01C7871C41444183C +6BF4:10903890E090279E20903890E39C209020903890E79E20902092209220021FFE +6BF5:0808101C24E07E201020FF3C24E042208920303CC4E008223222C422381EC000 +6BF6:08401C8871FC102413FE1C88713412C210181CE0F00C103011C010020FFE0000 +6BF7:00047F0E41705D1041105D1C417000103E10221E3E7022103E1222123E12220E +6BF8:08001DFC712411FC11241DFC7020101411521D42F248103A100210020FFE0000 +6BF9:0804140E22704110BE90001C78F04A904A907A9E4AF04A907A9248924A92590E +6BFA:10203850E088210426FA3800E3C4225423D43A54E3D42244225622CA20021FFE +6BFB:1008101CFEE020207E20883C7EE000207E20423C7EE042227E2242224A1E4400 +6BFC:00087E1C42E07E2042207E3C20E07F209120513C69E041227D2201220A1E0400 +6BFD:10103810E77C211422FE3A14E77C2110217C3910E6FE2210251228FE20021FFE +6BFE:00047F0E41707F1041107F1C0070F7901090949E52F03190D69210925292210E +6BFF:1004220E7F7042109490F79C08703610C910309EC470191062120C123012C00E +6C00:08047F0E4970FF9049107F1C08707F1049107F1E1070FF10211272120C12F30E +6C01:11103910E7FC211023F83A08E3F8220823F83840E7FC20A02112220A20021FFE +6C02:08203E7E08A47F281C102A2849443FFE200020782F8020F0278040FA4F82807E +6C03:1004080E7F702210FF10001C7F7049107F10491E7F7008107F1208120F12F00E +6C04:7E04140E0870FF1029104A1CA87010107F10551E63705D1055125D124112430E +6C05:082049202A3E7F4841A85D2855105D2842F63F0001F03F0001F87F02010200FE +6C06:11083890E3FC209022943998E09027FE200039F8E10821F8210A21FA20021FFE +6C07:11003BF0E4102BF822483BF8E24827FC20003BF8E20823F8220A23FA20021FFE +6C08:1008FE1C00E0FE208220BA3CAAE0FE2000207C3C44E07C2244227C22001EFE00 +6C09:00047F0E41707F100010F79C94F0F7900810081EFF701C102A1249128892080E +6C0A:10203BFEE00023FC22043AF4E29423FC210839F8E10821F8200227FE20021FFE +6C0B:2404FF0E2470FF1081107E1C0070FF101010289ED5702E10D5122492D412080E +6C0C:108039F8E20825FC212439FCE12421FC21543AFAE08820F8208A20FA20021FFE +6C0D:7704550E777055107710551C777022107F90A41E3F7024103F1224123F92200E +6C0E:3F84248E3FF024907FD0555C7FF055507FD0041E7FF048501F122A1204127FCE +6C0F:001000F83F802080208020803FFE208020802040204020222012280A30062002 +6C10:001000F83F802080208020803FFE208020802040204020222112288A30462042 +6C11:00003FF82008200820083FF8208020803FFC20802040204024242814300C2004 +6C12:00F03F00210021003FFC2080204028243114210C0100FFFE0100010001000100 +6C13:200013FC12040204FA0443FC4220422043FE4220422042107A12028A03060202 +6C14:100010003FFC20004FF080003FF000100010001000100010000A000A00060002 +6C15:100010003FFC20004FF080003FF000100410041004100410080A080A10062002 +6C16:100010003FFC20004FF080003FF000103F101110121017D0204A204A42868102 +6C17:100010003FFC20004FF080003FF00010009030900D100210050A188A60460002 +6C18:100010003FFC20004FF080003FF000100010111011101110210A210A41068102 +6C19:100010003FFC20004FF080003FF000100410041044504450444A7FCA00460002 +6C1A:100010003FFC20004FF080003FF000102490249024902490248A448A44868082 +6C1B:20003FFC40009FF000007FF00010121021104090BF501112110A110A25064202 +6C1C:20003FFC40009FF000007FF000103F90209020903F902092208A208A3F862082 +6C1D:100010003FFC20004FF080003FF0041004107FD044504A50514A604A41464082 +6C1E:20003FFC40009FF000007FF000107FD004107FD044504A52514A604A41464082 +6C1F:20003FFC40009FF000007FF012107F9012907F9052107FD2124A134A22864202 +6C20:20003FFC40009FF000007FF0041004107FD044507FD044527FCA444A04060402 +6C21:20003FFC40009FF000007FF010101F90209051100E103192CC6A030A1C060302 +6C22:20003FFC40009FF000007FF000103FD003100CD070301FD2020A020A7FF60002 +6C23:100010003FFC20004FF080003FF00410249015107FD00E10150A248A44460402 +6C24:20003FFC40009FF000007FF000107FD0445044505F5044524A4A514A7FC64042 +6C25:20003FFC40009FF000007FF000107FD00A103F902A902A92338A208A3F862082 +6C26:20003FFC40009FF000007FF004107FD0081011103E100492190A620A0D063082 +6C27:20003FFC40009FF000007FF011100A107FD004103F900412FFEA040A04060402 +6C28:20003FFC40009FF000007FF004107FD040500810FFD01112320A0C0A1B066082 +6C29:20003FFC40009FF000007FF000107F901210125092905312520A120AFFC60002 +6C2A:20003FFC40009FF000007FF004107FD004103F9020903F920A0A124A224641C2 +6C2B:20003FFC40009FF000007FF000107FD02490491024907FD2040A040AFFE60002 +6C2C:20003FFC40009FF000007FF00010FFD01210739040904092738A120A1206FFE2 +6C2D:20003FFC40009FF000007FF004107FD004103F9024903F92248A3F8A15062482 +6C2E:20003FFC40009FF000007FF0041024900B10109060500412248A0B0A10866042 +6C2F:20003FFC40009FF000007FF000107F9000903F900090FFF2248A150A24864C42 +6C30:20003FFC40009FF000007FF004107FD004103F900410FFF2208A3F8A20862182 +6C31:20003FFC40009FF000007FF010901F9010903FF010103FD24A4A124A25460882 +6C32:20003FFC40009FF000007FF000103F9020903F9020903F92000A7FCA4A46FFE2 +6C33:20003FFC40009FF000007FF000103F9024902A903F9000127FCA4A4A4A46FFE2 +6C34:010001000100010801087D9005A0094009401120111021084106810005000200 +6C35:0000200010001000800040004800080010001000E00020002000200020000000 +6C36:00003FF000200040008401087D9005A005400940092011102108C10605000200 +6C37:0100010011000908090801907DA005400940092011102108C106010005000200 +6C38:0200010000801F00010401087D9005A005400940092011102108C10605000200 +6C39:00400040F84008440F480950116012502248244448444140408240023FFE0000 +6C3A:01000100010041082108111011200180054009201110E1084104010005000200 +6C3B:008020801080108087FC40844884088410841084E10421042104220422280410 +6C3C:010001047D880550092011102108C5060200010001000280044008203018C006 +6C3D:01000280044008203118C10601003D8405880950092011102108C10605000200 +6C3E:000023F812081208820842084A080A0812501220E20022022202220221FE0000 +6C3F:010021001100110087F041104910091011101110E110221222122412280E1000 +6C40:0000200013FE1020802040204820082010201020E02020202020202020A00040 +6C41:00402040104010408040404047FE104010402040E04020402040204020400040 +6C42:0120011001007FFC01002108111009A003400520091011086106010005000200 +6C43:0000202011201120812041204920092011201110E11022102208240828041002 +6C44:0040204010401040804040404840084010A010A0E0A021102110220824040802 +6C45:000027FE10801080810041004A000BF810081008E00820082008200820500020 +6C46:0600010002800C603118C10601003D8405880950092011102108C10605000200 +6C47:000023FE12001200820042004A000A0012001200E20022002200220023FE0000 +6C48:000027FC10041004800440144824084410841104E60420042004200420280010 +6C49:000027F812081208820841104910091010A010A0E040204020A0211022080C06 +6C4A:000027F812081288824841504910091010A010A0E040204020A0211022080C06 +6C4B:00802080110011FC820442045404190410842044E04420042004200420280010 +6C4C:0204224412441244824442444244124412442244E24422442244244424040804 +6C4D:008020801080108087F0409048900A9011901090E1502152220A220A24060802 +6C4E:000023F012101210821043105290125012502210E210221224122412280E1000 +6C4F:0040204010401040804047FE4840084010A010A0E0A021102110220824040802 +6C50:00802080108010FC810441044284144810282010E01020202040208021000600 +6C51:0010207813C01040804040404840087E17C01040E040204220422042203E0000 +6C52:004020201020100087FE41004900090011001100E10021002100210021FC0000 +6C53:000023F8100810108020404048400FFE10401040E04020402040204021400080 +6C54:00802080110011FE8200440041F8100810102060E08021002202220221FE0000 +6C55:0040204010401040844444444444144414442444E4442444244427FC20040000 +6C56:010001002108210821083FF80000010001047D880550092011102108C5060200 +6C57:0000200013FC1040804040404840084017FE1040E04020402040204020400040 +6C58:0010207813C010408040404048400FFE10401040E04020402040204020400040 +6C59:000021FC102010208020402048200BFE10201020E02020202020202020A00040 +6C5A:000023F810401040804047FE48800880110011F8E00820082008200820500020 +6C5B:000027F01110111081104110411017D011102110E1102112210A210A21060102 +6C5C:000023F812081208820842084A080BF812001200E20022022202220221FE0000 +6C5D:00802080108010808FFE41084108120812102610E1A0204020A0211022080C04 +6C5E:00003FF8010001000100FFFE0000010001047D880550092011102108C5060200 +6C5F:0000200017FC1040804040404840084010401040E040204020402FFE20000000 +6C60:0040204012401258826842C853481E4812482248E25822422202220221FE0000 +6C61:000023F810001000800047FE40801080110021F8E00820082008200820500020 +6C62:00402040104010408040404047FC104010402040E0402040204020402FFE0000 +6C63:00802080108010F88108410849100A1010201020E05020502088210822040402 +6C64:000023F0102010408080410043FC112411242124E22422442444288421280210 +6C65:00402040104017FE80404040404017FC12042208E11020A0204020A023180C06 +6C66:0008203C13E01220822042204A200BFE12201210E2102212220A228A23060202 +6C67:000027FC111011108110411049100FFE11101110E11021102110211022100410 +6C68:000023FC12041204820442044A040BFC12041204E2042204220423FC22040000 +6C69:0000200017FC140484044404440417F414042404E4042404240427FC24040000 +6C6A:000027FC1040104080404040404013FC10402040E0402040204020402FFE0000 +6C6B:011021101110111087FC41104110111011102FFEE11021102110221022100410 +6C6C:082008207FFC08200820FFFE10202020412001047D88095011202118C5060200 +6C6D:002020201020102083FE42224A220A221252124AE28A230222022202220A0204 +6C6E:0100410021FC2204020485044884408410142024E04423842104200420280010 +6C6F:0080408020802FFE008080804120512011202240E2402488248829FC20840004 +6C70:004020401040104087FE4040484008A010A010A0E11021102288224824440802 +6C71:0040205010481048804047FE4840084010A010A0E0A021102110220824040802 +6C72:000027F81108111081104120493C090411041288E28822502420245028880306 +6C73:0008203C13C01200820042004BF80A8812881288E25022502220245024880906 +6C74:008020401040100087FE4080488008C010A01090E08820882080208020800080 +6C75:0040204010A010A0811042884C460840100013F8E00820102010202020200040 +6C76:00802040104017FC8110411049100910111010A0E0A0204020A0211022080C06 +6C77:008020801080108081F841084A080D10111010A0E0A0204020A0211022080406 +6C78:00802040104017FE81004100490009F811081108E10821082208220824500820 +6C79:0000200811081088825242524A220A2212521292E30A220A220223FE20020000 +6C7A:00802080108017F8808840884888088817FE1080E14021402220241028081006 +6C7B:00802080108011FC812041204A200820102017FEE02020202020202020200020 +6C7C:002020201120112081FC422042201420102027FEE02020202020202020200020 +6C7D:0100210011FC1200840041F84800080013F81008E0082008200A200A20060002 +6C7E:001021101110120882084404580213F811082108E10821082208220824500820 +6C7F:000023F81008111080A0404047FE104210442040E04020402040204021400080 +6C80:0800087C080409280910EA082CFE2A1229144910489088900810081028501020 +6C81:0000208010401020812041004100150415022502E50229082108210820F80000 +6C82:0008203C13C012008200420043FE121012102210E21022102210241024100810 +6C83:0010207817C0104080404040404017FE104020A0E0A021102110220824040802 +6C84:0000200013FC10008000400047FE104010402080E0802108220427FE22020000 +6C85:0000200013F810008000400047FC112011202120E120212022222222241E0800 +6C86:00802040104017FC8000400049F0091011101110E110211222122212240E0800 +6C87:0080208011001110820847FC4004112011202120E120212022222222241E0800 +6C88:00402040104017FE84444848404010A010A020A0E120212022222222241E0800 +6C89:0000200013FE12028404400041F0111011102110E110211222122212240E0800 +6C8A:1020102010207E2453A894B010A8112429222A222C2028A22842480247FE8000 +6C8B:009020881088108087FE40A048A008A010A010A0E120212221222222221E0400 +6C8C:00402040104017FC804042484A480A48124813F8E048204020422042203E0000 +6C8D:000027FE10801080808040F84908090811081208E3F820102010201027FE0000 +6C8E:01202120112012248224462856301A20126022A0E220222222222222221E0200 +6C8F:0000220012FC12248224422453A41E2412242224E2A423242244204420940108 +6C90:004020401040104087FE404048E008E011501150E24824442842204020400040 +6C91:000023F8108810888088408848880BF811081108E1082108210821082FFE0000 +6C92:0080208010FC11048104422848100BFC11041088E08820502020205021880606 +6C93:010001087D1005A009603118C50602001FF0101010101FF0101010101FF01010 +6C94:000027FE104010408240427C4A440A44124413FCE00420042004200420280010 +6C95:01002100110011FC82A444A440A4112411242244E44420842104220424280010 +6C96:004020401040104087FC44444444144414442444E7FC24442040204020400040 +6C97:00003FF801000100FFFE028004401830E10E11100B2005C01930610805000200 +6C98:0020222012201222822242244BA80A3012201220E220222222A22322221E0000 +6C99:0040204010401148814442424242144810482048E01020102020204021800600 +6C9A:0040204010401040824042404A7C0A4012401240E2402240224022402FFE0000 +6C9B:0040404020402FFE0040804047FC544414442444E44424542448204020400040 +6C9C:0010221012101210821043FE4A000A00120013F8E20822082208240824080808 +6C9D:0820082008200A200A32EDB228B42CA82AA82AA8492449248A22082028A01040 +6C9E:00004FFE20402040004087FC4444544414442444E44424542448204020400040 +6C9F:01002100110011FC820444844084110411442224E7F422142004200420280010 +6CA0:0008203C17D01490849044904490149014902488E48824882484288428821000 +6CA1:000021F01110111081104210540E180013F82208E108211020A0204021B00E0E +6CA2:000021FC110411048104410449FC092411201120E11021102208220824040802 +6CA3:00202020102013FE80204020482009FC10201020E02027FE2020202020200020 +6CA4:000023FC12001208828842504A500A2012201250E25022882308220023FE0000 +6CA5:000023FE12001220822042204AFC0A2412241224E24422442484248429281210 +6CA6:0040204010A010A0811042084406111011202140E18021002104210420FC0000 +6CA7:0040404020A02110020884044BF2421012102210E25022202204220421FC0000 +6CA8:000023F812081208832842A84AA80A48124812A8E2A8232A240A240A28061002 +6CA9:0040224011401140804047FC40441044108420A4E09421142104220424280810 +6CAA:00802040104013FC82044204420413FC12042200E20022002400240028001000 +6CAB:00402040104017FE8040404048400BFC104010E0E15022482446284020400040 +6CAC:00402040104013FC8040404048400FFE10E01150E15022482444284220400040 +6CAD:004020501048104087FC404040E010E011502150E24824442842204020400040 +6CAE:000023F812081208820843F84A080A08120813F8E2082208220822082FFE0000 +6CAF:010001087D1005A009603118C50602007FFC040008001FF82808C8080FF80808 +6CB0:0000200017FE104080404080488009F813081508E90821082108210821F80108 +6CB1:00802040104017FC840448084200121012202240E38022042204220421FC0000 +6CB2:0100210013FC120084404840427812C813482E48E248225A2242220221FE0000 +6CB3:0000200017FE1008800843C84248124812482248E3C822482008200820280010 +6CB4:0040204010A01110820844264040108013102020E04020882310202020C00700 +6CB5:00802080108011FE810242045420102011282124E22422222422202020A00040 +6CB6:000023FC10001000800040004FFE104010402248E24424442442284221400080 +6CB7:009020881088108087FE4080490009FC11441244E24824502420285020880306 +6CB8:01202120112017F88128412847F81520152027FCE12421242234222824200820 +6CB9:004020401040104087FC444444441444144427FCE44424442444244427FC0404 +6CBA:000027FC1444144484444444444417FC14442444E4442444244427FC24040000 +6CBB:0040204010801110820847FC4004100013F82208E20822082208220823F80208 +6CBC:000027FC108410848084410441141208140023FCE20422042204220423FC0204 +6CBD:004020401040104087FE40404840084013F81208E20822082208220823F80208 +6CBE:004020401040107E804040404840084013FC1204E20422042204220423FC0204 +6CBF:000021F01110111081104110420E1400100023F8E20822082208220823F80208 +6CC0:000023FC1004100487F4400448040BE412241224E22423E42004200420140008 +6CC1:000027F8140814088408440847F8112011202120E120222022222422281E1000 +6CC2:000023FC12041204820442F44A940A9412941294E2F422942204220422140208 +6CC3:01002100120013FC8404480443E4122412242224E22423E42224200420280010 +6CC4:004822481248124882484FFE4248124812482248E27822002200220023FE0000 +6CC5:000027FC140414448444444444441444144424A4E49425142604240427FC0404 +6CC6:004020401240124083FC42404440104017FE2040E0A020A02110220824040802 +6CC7:020022001200121E87D242524A520A5212521252E25222522452245E29521080 +6CC8:0080208010F81108831044A0404010A013182C06E0C020202010218020600010 +6CC9:010002001FF0101010101FF0101010101FF001047D88095011202118C5060200 +6CCA:00402040108013FC820442044A040A0413FC1204E20422042204220423FC0204 +6CCB:00402040104017FC804040404150111011102FFEE11021102210221024100810 +6CCC:0000208010401028812841084110151415222522E54229882108230824F80800 +6CCD:004020401040104087FC404048E008E011501150E24825F42842204020400040 +6CCE:01002100110011FE82804280448010F810802080E08020FC2080208020800080 +6CCF:0040204012481248824842484BF8084810401040E44424442444244427FC0004 +6CD0:0010479024902510057E86124512549214922492E692251224222422244A0484 +6CD1:0220422022202420057C89244E24422414242424E9242F242144204420940108 +6CD2:0008203C13D01290829042904A900A9012901288E28822C822A424D424920800 +6CD3:0008278810881088808847884408141014102790E09420A420A220BE25020200 +6CD4:010821081108110887FE410841081108110821F8E10821082108210821F80108 +6CD5:004020401040104087FC4040404010401FFE2040E0802100221024082FFC0404 +6CD6:00002100163C14A484A444A444A414A414A425A4E6B424A82120212022200420 +6CD7:0000200017FC14A484A444A444A414A414A42524E51C26042404240427FC0404 +6CD8:0010207817C01040844442444248104017FE2040E04020402040204021400080 +6CD9:000023F810401040824841484950084017FE1040E04020402040204020400040 +6CDA:0120212011201524852445E84530152015202520E520252225E22E22241E0000 +6CDB:00102078178010008080404047F8101010202040E08021002200250028FC0000 +6CDC:0008203C13E01220822042204A200BFE12201210E2102212220A228A23260212 +6CDD:0008203C13C01200820042004BFE0A1012101270E21022182214241024100810 +6CDE:00802040104017FC840448084000100017FC2040E04020402040204021400080 +6CDF:000027FC10401040804040404A400A7812401240E2402240224022402FFE0000 +6CE0:0040204010A010A0811042484426102013F82008E010211020A0204020200020 +6CE1:0100210011FC1204820447E44A241224122423E4E21422082202220221FE0000 +6CE2:00202020102013FE822242244A200BFC12841288E24822502220245024880906 +6CE3:008020401040100087FC40004008120812082110E1102110212020202FFE0000 +6CE4:0008210810881448844844084408140814102410E41025282624244420820102 +6CE5:000023FC12041204820443FC4A000A4012441248E270224024422442283E1000 +6CE6:000023FC1204120483FC42404A400A4013F81248E24822482488248A290A0206 +6CE7:002820241024102083FE42204A240A2412241228E22822902312222A20460082 +6CE8:00802040100017FC804040404040104013FC2040E0402040204020402FFE0000 +6CE9:004022401240124083FC444054401840104023FCE0402040204020402FFE0000 +6CEA:000023FC12041204820443FC4A040A04120413FCE20422042204220423FC0204 +6CEB:00802040104017FE804040804108121017E02040E0802108220427FE22020000 +6CEC:00402020102013FE820244044000109010902090E08821082108210422040402 +6CED:010821081108120882FE46084A08120812882248E24822082208220822280210 +6CEE:0040204012481148815040404BF8084010401040E7FC20402040204020400040 +6CEF:000023FC12041204820443FC4A200A2013FE1220E22022102212228A23060202 +6CF0:010001007FFC01003FF80200FFFE044009203118CB2605C01930610805000200 +6CF1:00402040104013F8824842484A480A48124817FEE04020A020A0211022080406 +6CF2:00402040105C13E0824042404A400BFC104410C4E14422542C48204020400040 +6CF3:00802040102013C0804440444F48115011602160E25024482844304221400080 +6CF4:010001087D1005A009603118C506020000003FF82448244824482448FFFE0000 +6CF5:0000FFFE040008001FF02810C8100FF0010001047D88095011202118C5060200 +6CF6:22081108111000207FFE40028004010001047D880550092011102108C5060200 +6CF7:012021101110110087FE41404940094811481250E2502262244224C2293E1000 +6CF8:00402040107E1040804043FC4A040A04120413FCE20422002200240024000800 +6CF9:000023F812081208820842084BF80A0812081208E20823F8200020002FFE0000 +6CFA:0008203C17C0140084404440444017FE10402040E24822442442284221400080 +6CFB:000027FE14021904810041FC49000A0013FC1004E00427F42004200420280010 +6CFC:004020481244124083FE4080488008FC11441144E14822502220245028880306 +6CFD:000027F81208111080A0404041B0164E104023F8E040204027FC204020400040 +6CFE:000027F8101010208060409841041602100023FCE04020402040204027FE0000 +6CFF:000023F81208120883F842084A080BF812441248E23022202210228823060200 +6D00:0080210013F812088288424842481FFE12082288E24822482208220824280810 +6D01:0040404020402FFE0040804047FC5000100023F8E20822082208220823F80208 +6D02:00402020102017FE8090409048900A9412921292E49220902110211022500420 +6D03:00802080108017FE810041204A200AA414A41528EA5020502088210822040402 +6D04:000027FE1402140284F244924492149214922492E4F224922402240227FE0402 +6D05:000027FC1040104083F842484A480BF812481248EFFE22082208220822280210 +6D06:000023F810101020804447644168115012502248E4442942208020002FFE0000 +6D07:000027FC140414448444444447FC1444144424A4E49425142604240427FC0404 +6D08:0100210013F8120884104BFE420012F812882288E2A8229022822482247E0800 +6D09:0008203C13C01200820043FE4A000A00120012FCE28422842484248428FC0084 +6D0A:00402040104017FE80804080497C090813101510E1FE21102110211021500120 +6D0B:020821081110100087FC4040404013F810402040E7FE20402040204020400040 +6D0C:000240022FC22212021283D24252545216522552E892209221022202240A0804 +6D0D:000027FE14201420842044F84488148814882488E4F824202420242027FE0000 +6D0E:0040208013FC1204820442044BFC0A0412041204E3FC22042204220423FC0204 +6D0F:00002FFE10401040808047FC44A414A414A424A4E4A424A424A4248424140408 +6D10:00802080113C120084804080497E0B0815081108E10821082108210821280110 +6D11:0120412821242224022086204AFC422012202250E25022502288228823040202 +6D12:00002FFE10A010A087FC44A444A414A414A424A4E51C26042404240427FC0404 +6D13:0040204017FC1040804043F84A480A4812481258E0E0215022482C4620400040 +6D14:00402040104013FC8040404047FE1010101027FEE01022102110211020500020 +6D15:001021101108120884044BFA4208120813F82208E20823F82208220822280210 +6D16:000023F81208120883F84000400017FC10402040EFFE204020A0211022080C06 +6D17:00402240124013FC84404840404017FE11202120E120212022222222241E0800 +6D18:0080208813E8109080A047FE4880090013FC1480E90021F82008200820500020 +6D19:00402240124013FC84404040404017FE10E02150E15022482444284220400040 +6D1A:0100210011F8131084A0404051B0164E104023FCE040244027FE204020400040 +6D1B:0080208011F81208851040A0404010A013182C06E3F822082208220823F80208 +6D1C:08001FF0282007C01830E00E1FF010101FF001047D88095011202118C5060200 +6D1D:00802040104017FC84044888408017FC11102110E21021A0204020A021100608 +6D1E:000027FC1404140485F44404440415F415142514E51425F42404240424140408 +6D1F:0040204017FE104087FC404443FC1240144027FEE04220AA20A4211022080C06 +6D20:004020401090110883FC40244920092011FC1220E02027FE2020202020200020 +6D21:0040204017FC1040804043F84840084017FE10E0E15021502248244428420040 +6D22:0100217C11241224822446FE4A2412241224227CE22422202220222022400280 +6D23:00402040124811488150404047FE104010E02150E15022482444284220400040 +6D24:0040204010A011108208440643F8104010402040E3F820402040204027FE0000 +6D25:0040204013F8104887FE40484BF80840104013F8E040204027FC204020400040 +6D26:000027FE10201020804043FC4A040A04120413FCE20422042204220423FC0204 +6D27:0040204017FE1080810041FC4304150419FC2104E10421FC2104210421140108 +6D28:00802040104017FC800041104208140411102110E0A0204020A0211022080C06 +6D29:00402040104017FC8444444447FC1444144427FCE02820122032204A21860E02 +6D2A:011021101110111087FC41104110111011102FFEE00021102108220824040804 +6D2B:004020401080110083FC42944A940A9412941294E2942294229422942FFE0000 +6D2C:000027F81408140887F84488448814E815282528E6A8244A244A288A29061202 +6D2D:000023FE1200120083FC42204A200AF812201220E22023FC2200220023FE0000 +6D2E:0090209010901492829440984090119812942492E0902090211221122212040E +6D2F:080008007F7C08243E2408447F540888090001047D88095011202118C5060200 +6D30:000023FE12001200820043FC4A040A0412041204E3FC22002200220023FE0000 +6D31:000027FC1208120883F84208420813F812082208E20E23F82E08200820080008 +6D32:01042124112411248124412445B4156C19242124E12421242124222422040404 +6D33:010021001100111E87D242524252125212522492E29221122292225E24520800 +6D34:020821081110100087FC41104110111011102FFEE11021102210221024100810 +6D35:00802080110011FC8204440443E41224122423E4E224222423E4200420280010 +6D36:02002200120013FC840444044A24114414942554E634241427F4200420280010 +6D37:000027FE104010808110420847FC104410402040E7FC2040204020402FFE0000 +6D38:008020881488129082A040804FFC112011202120E120212422242224241C0800 +6D39:000027FC1000100083F84208420813F812082208E3F82208200020002FFE0000 +6D3A:0080208010FC1104828844504020104011FC2304ED0421042104210421FC0104 +6D3B:0010207813C01040804047FE40401040104023F8E20822082208220823F80208 +6D3C:0040204013F810408040404047FC100010402040E3F820402040204027FC0000 +6D3D:0040204010A011108208440643F81000100023F8E20822082208220823F80208 +6D3E:0008203C17C01400841C45E04520152215242528E51025102508294429821100 +6D3F:0040204017FC10A0811042084DF6100017FC2080E10023F82008200820500020 +6D40:005020501050105083FE42524A520A52125213FEE25222522252225223FE0202 +6D41:0080204017FE10808110420847FC100410002248E24822482248224A244A0846 +6D42:020821081110100083FC40404840084017FE1040E04020A020A0211022080406 +6D43:00402040104017FC80404248515010401FFE20A0E0A021102110220824040802 +6D44:0100210013F0121084204BFC4044104417FE2044E04423FC2044204021400080 +6D45:00A02090108010B887C0408040BC17C010882090E060204420A42114260C0004 +6D46:0840484028FC09041A8828504860898001047D880550092011102108C5060200 +6D47:0080208010BC13C08050402448D40B0C100017FEE090209021122112220E0400 +6D48:00402040107E1040804043F84A080A4812481248E248224820A0211022080404 +6D49:010021FE11101510857C45544554155415542554E5542154225C221024100810 +6D4A:00402040104017FC844444444444144417FC2444E040204820442FFE24020000 +6D4B:000427C414441454855445544554155415542554E55421042284224424140808 +6D4C:01202128112412248220463E4BE0122412242228E22822102212222A22460282 +6D4D:0040204010A011108208440641F01000100027FCE04020802110220827FC0204 +6D4E:0080204017FE1208811040A0404011B0160E2110E11021102110221022100410 +6D4F:0204410421042FE4009484944294529411142114E29422942444284430140008 +6D50:0040202013FC1000810840904BFE0A0012001200E20022002200240024000800 +6D51:000023FE12021444804043FC488008A0112011FCE020202027FE202020200020 +6D52:004044402240227C005080904E10521012FE2210E21022902310221020100010 +6D53:00402040104017FC848448884140114413482530E92021102108214421820100 +6D54:000027F81008100883F84008400817F810102010EFFE22102110211020500020 +6D55:000023F81208120883F842204A200A10120814C6E420280021C0203020080000 +6D56:0010207817801088844842504200102017FC2020E22021202120202020A00040 +6D57:005020481048104087FE40404A440964116810D0E15022482444204221400080 +6D58:000023FC1204120483FC42004A180AE0123812E0E23C23E022222422241E0800 +6D59:0208421C226022400FC08240427E52C813482E48E2482248224822482A880508 +6D5A:008020801110120887FC400441101288148421F0E31024A0204020A023100C0C +6D5B:0040204010A011108288444641F0101010202040E3F822082208220823F80208 +6D5C:0010203813C01200820043FC4220122012202220EFFE20002120221024080804 +6D5D:01102108110017FE814841504964094811501264E24822522462244229BE1000 +6D5E:000023F8120812088208420843F8104010402240E27C22402240254028FE1000 +6D5F:0210221012101420853E4D444DA4152415282528E51025102428242824440482 +6D60:0208211010E01110820840804FFE1140124027FCEA4422442254224820400040 +6D61:0040204013FC1040804047FE5402180411F02010E0202FFE2040204021400080 +6D62:000027FC1000100083F842084A080A08120813F8E0002208210821102FFE0000 +6D63:0080204017FC1404880843F04000100017FC2120E120212022242224241C0800 +6D64:0040202013FE1202844440404BFE084010901090E11021202224224224FE0842 +6D65:000023F81208120883F8400047FC144414442444E7FC24002402240223FE0000 +6D66:004840442FFE2040004087FC4444544417FC2444E44427FC2444244424540408 +6D67:000023F812081208820843F84800080017FC1040E04023F8204020402FFE0000 +6D68:0080204017FE140288444040404017FC10E02150E15022482444284220400040 +6D69:00402240124013FC84404840404017FE10002000E3F822082208220823F80208 +6D6A:0080204013F81208820843F84A080A0813F81240E24422282210228823060200 +6D6B:000047FE240229140208840443F8504010402040E7FC20402040204020400040 +6D6C:000027FC1444144487FC4444444417FC10402040E7FC2040204020402FFE0000 +6D6D:00002FFE104017FC8444444447FC1444144427FCE24021402080214022300C0E +6D6E:0008203C13C010048244412848000BF810101020E7FE20202020202020A00040 +6D6F:000027FC1040104083F84088408817FE10002000E3F822082208220823F80208 +6D70:008421C417041114811441144FD4111413142394E55425042904210421140108 +6D71:000023FC1200120082F842004A000BFC12A012A4E2A822902290248824A408C2 +6D72:010021F813081490806041984646104013F82040E3F8204027FC204020400040 +6D73:0088208410BE17C08032400E48000BFC120413FCE20423FC2204220422140208 +6D74:0110210812041444804040A041101208140623F8E20822082208220823F80208 +6D75:000227821484148886904582448214841FC82490E482248224842488289011A0 +6D76:0040202013FE12028424412049FC092012201020E7FE20202020202020200020 +6D77:0100210011FC120085F841084948092817FE1108E248222823FC200820500020 +6D78:000023F8100811F8800843F8400017FC140423F0E110211020A0204021B0060E +6D79:00402040104017FE8040424842481248155428A2E0A021102110220824040802 +6D7A:010821081108113E81AA456A452A152A192A213EE12A21082108210821080108 +6D7B:000027FC140414A48514460C540415F415142514E51425F42514240424140408 +6D7C:0100210011F01210822047FC4A441244124423FCE2A420A0212022222422081E +6D7D:0008203C13C01044822441284900084013FE1088E10823902060205021880604 +6D7E:0040204013FC10408040404047FE109012942292E49229122110221024500820 +6D7F:000023FC1204120483FC42044A040BFC12041204E3FC20002110210822040404 +6D80:000023F81208120883F84208420813F812082208E3F82120212022222422181E +6D81:01022102110411088FD041024302138415482550E90221022104210821100160 +6D82:0040204010A01110820845F64040104017FC2040E25022482444284421400080 +6D83:000027FC14441444844447FC444414C414E42554E64424442444240427FC0404 +6D84:0040204017FC144487FC444447FC10001FFE2100E20023FC2004200420280010 +6D85:000027FC1404140487FC4404440417FC10402040E7FC2040204020402FFE0000 +6D86:0000203E1788148884884488448817BE14882488E48824882788248820080008 +6D87:000023FC100011248248449052481124100023FCE04020402040204027FE0000 +6D88:0040224811481150804043F84A080A0813F81208E20823F82208220822280210 +6D89:002020201120113C8120412047FE100010202124E12422282410202020C00700 +6D8A:000023FC10441144814442844894090812401020E0A42282228A228A24780000 +6D8B:0040202013FE1202840440504048104017FE2040E0A020A02110211022080406 +6D8C:000027F8101011A0804047FC4444144417FC2444E44427FC2444244424540408 +6D8D:0040204413F41048804847FE4020104013F82110E22025FE2820202020A00040 +6D8E:0008201C1770111081104250425C175011502550E550227C2200250028FE1000 +6D8F:0000200C1770111081104210427C171011102510E510227C2200250028FE1000 +6D90:012043A82E24222402209FFE4220522412A42328E2282E102232224A2A860402 +6D91:004040402FFE2040004087FC4444544417FC2040E0E0215022482C4620400040 +6D92:000023F81088108887FE408848880BF811001100E3F825082908210821F80108 +6D93:000021F81108110881F840004BFC0A04120413FCE204220423FC220422140208 +6D94:004022481248124883F8404048A0091012881446E04023F02010202020200040 +6D95:02102110112017F88048404847F81440144027FCE0C421442254244828400040 +6D96:012021101110120082FE460056041A8412842248E24822482250221022FE0200 +6D97:0010209010881108820445FA41081108110821F8E0902090209021122212040E +6D98:004020801110120887FC4104410013F814402040EFFE204020A0211022080C06 +6D99:0040202013FC1204820443FC4A000A20122013FEE22022502250248825040A02 +6D9A:020821081110102083F842084A080A0813F810A0E0A0212021222222241E0800 +6D9B:0040204017FC104083F8408047FE1090111021FEE21022902450281020500020 +6D9C:0020202013FE102081FC40004BFE0A0214041090E0902090209021122112020E +6D9D:0108210817FE1108800047FE54021884108027FCE08421042104220424280810 +6D9E:00402040104017FC804042484148115017FE20E0E15021502248244428420040 +6D9F:00202420122012FE804040504E9012FE12102210E3FE22102210251028FE0000 +6DA0:000027FC1444144485F4444444E4144415F42454E45424742444244427FC0404 +6DA1:000023F812081208820843F84040104017FC2444E4A425142614240424140408 +6DA2:000023F81208120883F84000400017FC14042444E444244424B4210826041802 +6DA3:0100210011F0121084204BF84248124812482248EFFE20A020A0211022080C06 +6DA4:0080208011F813088490406041981646104027FCE04022482244244421400080 +6DA5:008040402FFE200003F88208420853F8100023F8E01020602040204021400080 +6DA6:0200217C1504140485F444444444144415F42444E444244425F4240424140408 +6DA7:0200217C15041404840445F44514151415F42514E51425F42404240424140408 +6DA8:00404F442144214801488F50484058FE18502F50E1482148214421442A620440 +6DA9:000023FC10441244824444844094110812202020E13C21202120212027FE0000 +6DAA:0080204013FC100082084108411017FE10002000E3FC22042204220423FC0204 +6DAB:0080404027FE2402080483F84208520813F82200E20023FC2204220423FC0204 +6DAC:0040204017FC104080404FFE411010A017FC2040E0402FFE2040204020400040 +6DAD:001C23E0108412448148411057FE1402100023F8E108211020A0204021B0060E +6DAE:000247E22422242A07EA848A448A548A17EA26AAE6AA2AAA2AA232E2208A0084 +6DAF:000027FE1420142085FC4420442017FE14002420E42025FC242028202BFE1000 +6DB0:000027BC108412948108429454A41840100027BCE0A422A42128229024A80846 +6DB1:000021FC110011F8810041F851001FFE12802248E25022202210228823060200 +6DB2:0080204017FE11208120423C4244166412942348E24822302220225022880306 +6DB3:00402020102013FE8202449441081204100021FCE02020202020202027FE0000 +6DB4:0080404027FE24020A04820043BC54A414A426A4E9342128222222222422081E +6DB5:000023F8101010208444455444E4144414E42554E64C25442484240427FC0004 +6DB6:0010207813C01040804047FC424812481FFE2248E24827FC2040204027FC0000 +6DB7:0040204017FC104083F842484BF80A4813F81040E0E0215022482C4620400040 +6DB8:000027FC1444144487FC4444444415F415142514E51425F42514240427FC0404 +6DB9:003823C01040104087FC415042481486108027FCE110221021A0206020900308 +6DBA:000023FC1204120483FC42204A200BFE12201220E2FC22842284248424FC0884 +6DBB:0040204010A01110820845F64040104017FC2040E04023F82208220823F80208 +6DBC:0080204017FE1000800043F84A080A0813F81040E25022482444284421400080 +6DBD:001C23E0122013FE822042924B0A0A0611FC1104E10421FC2104210421FC0104 +6DBE:0040204417681150815042484544108013F82208E20823F82208220823F80208 +6DBF:00004FFE20802184024484684AB0413012A82468E8A421242222242020A00040 +6DC0:0040202013FE12028404400043FE102010202120E13C212022A02260243E0800 +6DC1:0080204013FC10008108409047FE1040104027FEE08821082090206021980604 +6DC2:000023F8120813F8820843F848000BFC101017FEE01022102110201020500020 +6DC3:00402248115017FC808041004FFE121014082BF4F212221022502224220401FC +6DC4:0124212412481490824841244124100017FC2444E44427FC2444244427FC0404 +6DC5:0200420C227022400F408240427E564817482AC8EA4832482248224822480288 +6DC6:0210212010C013308C8840804FFE110013F82608EBF8220823F8220822280210 +6DC7:0108210817FE1108810841F84908090811F81108E10827FE2000209021080204 +6DC8:000023FE1202120283FE42104A920A92129212FEE21022922292249224FE0802 +6DC9:000023F81248124883F842484A480BF8104017FCE0E021502248244620400040 +6DCA:0100210011F81208841048204180163C14042404E7BC24042404240427FC0404 +6DCB:011021101110111087BC41104110133813B82554E55429922110211021100110 +6DCC:0040224811481150804047FC4404140415F42514E514251425F4240424140408 +6DCD:000027FC1444144485F44444444417FC140425F4E514251425F4240424140808 +6DCE:0040204017FC104083F8408047FC111012482446E1F0204027FC204020400040 +6DCF:000023FC120413FC820443FC48000BFC10401040E7FE204020A0211022080406 +6DD0:03F82208120813F88208420843F8100017FC2404E40427FC2404240427FC0404 +6DD1:0100210011DC11148114411447D4101411142114E58825482948211425140222 +6DD2:0040204017FC104083F8404847FE104813F82080E7FE21082390206021980604 +6DD3:020842082FFE2208028880404FFE4100110021F8E10821082208220824280810 +6DD4:0040204017FC1040804043F84A080BF8120813F8E20823F8220822082FFE0000 +6DD5:0040204013F81040804047FC4110120814442040E3F820402040204027FC0000 +6DD6:00402040107E104083FC42044BFC0A0413FC1244E04027FE2040204020400040 +6DD7:0100210011FC12048484449442A4108417FC2084E1C422A42494208420A80010 +6DD8:0100210011FC1204850441E44284108417F42084E2A422A423E4200420280010 +6DD9:0080404027FE2402080483F04000500017FC2040E25022482444284421400080 +6DDA:0040202013FC1204820443FC4A000A28122413FEE22022502250248825040A02 +6DDB:01042104150417D4891441144FF4111417D42554E5542554254425C421140108 +6DDC:000027BC14A414A484A447BC44A414A414A427BCE4A424A424A424A42AA4114C +6DDD:000027BE14AA14AA84AA47AA44AA14AA14BE27A0E4A024A024A228A22AA2111E +6DDE:02084228222822280FA482444254569217102AA0EA203228224422FC22440200 +6DDF:00902090109013FC829442944A940BFC12941294E29427FE2000209021080204 +6DE0:000027FC1444144487FC4444444417FC10002000EFFE22082208220824080808 +6DE1:004022441244144880A041104608104410402248E248245020A0211022080C06 +6DE2:00142012101017FE801040104BD20A5212521254E3D4200820EA271A22260042 +6DE3:00002040139C12048204439C4A040A0413FC1090E0902090209021122212040E +6DE4:0210411020102FA8042884444402579014882488E48024A0249028882A881100 +6DE5:008020F81088110881F0401048100BFE10201222E17420A82124222220A00040 +6DE6:0040204010A011108208440641F01040104023F8E0402248214821502FFE0000 +6DE7:0040202013FE12028444402048280888109012A4E2C224822188228824780000 +6DE8:003C27C012441128800043F84848084817FE1048E04823F82048204021400080 +6DE9:0040204017FC104080404FFE42081484188221F8E208251020A0204021B00E0E +6DEA:0040204010A0111082084DF6400017FC14A424A4E7FC24A424A424A424140408 +6DEB:0008203C17C01084844442484210103C17C02040E0402FFE2040204027FC0000 +6DEC:0080204017FC10008110411042A8144410002040E7FE20402040204020400040 +6DED:0080204017FC1404840447FC4440144017FE24E0E95029503248244428420040 +6DEE:01402120112013FE822046204BFC1220122023FCE2202220222023FE22000200 +6DEF:0080204017FE1100820847FC400413F8120823F8E20823F82208220822280210 +6DF0:0040204010A0111082884446400013F010102020E04021242522250A290800F8 +6DF1:000027FC140414A4811042084040104017FC2040E0E0215022482C4620400040 +6DF2:00402040107C104083FC42444A700BC01244123CE20022F0249024922912120E +6DF3:0080204017FC100083F842084BF8080013F81010E02027FC2040204021400080 +6DF4:0100210013FC1494889441244244148411282210E0402124252A250A28F80000 +6DF5:00A024A414A414A487BC4404440417FC14042404E7BC24A424A424A428A41004 +6DF6:00402040104017FC8040424842481248155420E0E15021502248244428420040 +6DF7:000027FC1404140487FC4404440417FC10002420E42227AC2430242225A2061E +6DF8:0040204017FC104083F8404047FE100013F82248E24823F82208220822280210 +6DF9:0040208017FE11108248444643F81248124823F8E248224823F820422042003E +6DFA:00A0209010BC17C88050406451941E0C10A02090E0BC27C82050206421940E0C +6DFB:000023FC1040104087FE40A04110120814462040E04822642252245221400080 +6DFC:010001087D1005A009603118C506020008100A146AD42C582A544A94A9521020 +6DFD:0108210817FE110881084020482009201120113CE1202120212021202FFE0000 +6DFE:010006C01830EFEE01003FF811100920FFFE000001087D90096011202518C206 +6DFF:0040208013F8120883F842084BF80840104017FCE44424442454244820400040 +6E00:0040204017FE10A08150424845F6104011502110E7FE21102110211022100410 +6E01:0040474421682150024884444940408010002040E74421682250244829460080 +6E02:03F82208120813F8820842084BF80880104017FCE110211020A0204021B00E0E +6E03:0108210817FE11088148404047FE1080110023FCE50429042104210421FC0104 +6E04:009020901090179E8090409048900B9C10901090E090279E2090209020900090 +6E05:2040104017FC004083F840404FFE080013F8120813F8E20823F8220822280210 +6E06:0844448420042FD404948494449454941FF42494E49424942484288428941088 +6E07:000023F8120813F8820843F849000BFC14041224E3D4221421F4200420280010 +6E08:0040202017FE11088090406041981606110821F8E10821F82108210822080408 +6E09:002020201120113C8120412047FE100010282124E122222A2410202020C00700 +6E0A:04442444165415548564444447FC144414C424E4E55425542644284428441044 +6E0B:002020201120113C8120412047FE100010002204E10820902108220424020000 +6E0C:000023F81008100883F84008400817FE10402444E2E821502248244621400080 +6E0D:0040204017FC104083F8404047FE100013F82208E2482248224820A021100608 +6E0E:0040204013F81040804047FC4004112810A02220E12027FC2050208821040604 +6E0F:0040204013FC10A08110420857FE100813C82248E248224823C8200820280010 +6E10:01004102211C2FD002108210451E57D411142114E1D42F142514212421240144 +6E11:000023F81208120883F8404047FC1444144427FCE444244427FC20422042003E +6E12:0040208013FC1224822443FC4A240A4413FC1090E11027FE2010201020100010 +6E13:003C27C010841444824842104840084013F81040E04027FC20A0211022080C06 +6E14:0100410023F0221004208FFC5444544417FC2444E44427FC200020002FFE0000 +6E15:04442244128417D48114411451141FF411142114E29422542444244428140008 +6E16:0080204017FC1444804043F84248124813F82248E24823F82248204020400040 +6E17:00802090110813FC804047FE411012481C862310E02020C42308203020C00700 +6E18:000023F81090106087FC40A44128122014602040E7FC20E0215022482C460040 +6E19:0100210013F01410882047FC440414A415142444E0402FFE20A0211022080C06 +6E1A:0080208817E8109080A04FFE4080110013F82608EA0823F82208220823F80208 +6E1B:00142012101017FE8410441045D01412141225D4E554254825DA242A28461082 +6E1C:000027FC1040108087FC44A444A414A41484244CE0402FFE20A0211022080C06 +6E1D:004020A01110120885F6480047C41454145427D4E454245427D4244425540488 +6E1E:0208211017FE1040808043F84A080A0813F81208E20823F82208220823F80208 +6E1F:0080204017FC100083F8420843F810001FFE2802E3F820402040204021400080 +6E20:23FC120083F84A080A0813F8E20023FC21000100FFFE054009203118C1060100 +6E21:0040202017FE1488848847FE448814F8140025FCE48424882450282028D81306 +6E22:40002FF8280888684B88488808882BE82AA84AA8CBE8488A48AA50EA57262002 +6E23:0040204017FC10E081504248444613F8120823F8E20823F8220820002FFE0000 +6E24:021082105FD00210823E5FD2505220922F124112C21243925E2242224A4A0484 +6E25:000023FC1204120483FC42004BFC0A40128813FCE224222025FC2420282013FE +6E26:000023F81208120883C84248424817FC140425F4E514251425F4240424140408 +6E27:0080204013FC10008108409047FE1442184423FCE24422442254224820400040 +6E28:000023F81248124883F842484A480BF8100017FEE24022442228229023080206 +6E29:000023F81208120883F84208420813F8100027FCE4A424A424A424A42FFE0000 +6E2A:0008203C17C0104083F842484A480BF8104017FCE444245425F4240424140408 +6E2B:00902290129017FE8290429042F0120013FC2040E7FE20E0215022482C460040 +6E2C:000227C21442145287D24452445217D214522452E7D2200222822242244A0804 +6E2D:000027FC144417FC844447FC400013F8120823F8E20823F82208220822280210 +6E2E:0110211017FE1110800047FE4008100813C82248E24823C82248200820280010 +6E2F:0110211017FC111081104FFE4110120817F42A12E21023F02204220421FC0000 +6E30:004020A0111012088DF6400043F81208120823F8E110211027FC211022100410 +6E31:01002100113E17C8854845484548154817C82508E108214821C82E48243E0000 +6E32:0080404027FC2404080883F8400053F8120823F8E20823F82208200027FC0000 +6E33:0000277E11241124813C47244424143C14242724E126217C210421042A040404 +6E34:000023F8120813F8820843F849000BFC14441244E2A4220423F4200420280010 +6E35:020842082FFE22080208800047FC544414442444E7FC24442444244427FC0404 +6E36:0110211017FC11108150404043F8124812482248EFFE204020A0211022080406 +6E37:0080204017FC11108208440443F81208120823F8E110211021122212240E0800 +6E38:02102110111017BE8220424043BC128412882288E2BE22882488248829A81010 +6E39:0200220013FE1402888247FA400217F2100227F2E00227F2241227F220140008 +6E3A:401020102F10891049144F52095229922F104914C9044F084910402040400180 +6E3B:00402040124812448454406049800E0013F81208E3F8220823F8220823F80208 +6E3C:0208211017FE1040804043FC4840084017FE1000E04027FC20A0211022080C06 +6E3D:0128212417A4112081204FFE4020102417A424A8E4A82490279224AA20460082 +6E3E:000027FC1444104087FE40404BF80A4813F81248E3F8204027FE204020400040 +6E3F:0040204017FC10E0815042484C4613F810002000E7FC20402248244429420080 +6E40:002027A810B014A483184110420815F410402040E7FC204020A0211022080404 +6E41:02102210122812288F444282427C130012002E7CE2442244224422442A7C0444 +6E42:000027BC14A414A487BC400043F810001FFE2100E20023F82008200820500020 +6E43:010043BC2E102210023C8F904210523C12102F90E27E22102210221024100810 +6E44:000023FC1224122483FC42004AFC0A84128412FCE28422FC2484248428FC1084 +6E45:004040402FFE204007FC8444455454E4144427FCE0E0215022482C4620400040 +6E46:0080204017FC1000820841104FFE100013F82208E20823F82208220823F80208 +6E47:0080204017FC120881104FFE400013F8120823F8E20823F82208220822280210 +6E48:020842082FFE2208020883F84208520813F82040EFFE20E0215022482C460040 +6E49:0208421C2270221003108AFE4A104A101210227CE244224422442244227C0244 +6E4A:0040204017FC104083F8408047FC1110120825F6E04023F8204020A021100608 +6E4B:0080208013F8110887FE40004BF80A0813F81040E7FC2040244027FE20400040 +6E4C:0040204010A01110828844464BF80A0813F81208E3F822442228229023080204 +6E4D:004024441444144487FC40004FFE1040108027FCE4A424A424A424A424A4040C +6E4E:000027FE1040108087FE4492449214F214922492E4F224922492249227FE0402 +6E4F:000027FE1040108083FC42044A040BFC120413FCE204220423FC200021080204 +6E50:021042102220227C0FC482444244574416FC2A44EA44324422442244227C0244 +6E51:000027FC104412408278424055FE180013F82208E3F8220823F8220822280210 +6E52:000023F81208120883F840004FFE120813F82208E3F82208227E2F8820080008 +6E53:001021101108120485FA408841081228141023F8E2A822A822A822A82FFE0000 +6E54:0208410821102FFE000087C44454545417D42454E45427D42454244425540488 +6E55:00102010177C111481FE4214427C1710117C2510E5FE22102210250028FE0000 +6E56:0100211E111217D28112411E411217D21452245EE45227D224522022202A0044 +6E57:01042104110417C4813E410447C4102411142114E7C42104210421C42E140408 +6E58:02004200227C22440F448244427C574416C42A44F27C224422442244227C0244 +6E59:0080204017FE1090829844944114123014402040E7FE204020A0211022080C06 +6E5A:00402488152815E8844844A845E8140815E82528E5E8252825EA292A292A1166 +6E5B:0108210817FE110881F8410849F80908110817FEE25022882304220023FC0000 +6E5C:000023F81208120883F842084A080BF8100017FEE040224022782240254008FE +6E5D:0220222413A8123082A243224A5E088013FC1204E20423FC2204220423FC0204 +6E5E:0040207E1040104087FC4404440417FC140427FCE404240427FC211022080404 +6E5F:0040208013F8120883F842084BF8080017FC1040E04023F82040204027FC0000 +6E60:004024441444144487FC4100410017FE11202220E2A422A82550245028880106 +6E61:03F82248124813F8824842484BF80840104017FCE444245425F424142404040C +6E62:000027FC100013F88208420843F8100017FC2444E44427FC2444244427FC0404 +6E63:000023FC120413FC822043FE4A100A8A13061000E3FC220423FC220423FC0204 +6E64:02102110111017BE822842484BAA0AAE12BA12EAE2AE22A824AA24A229A2101E +6E65:0080204017FC14048110420844441050104827FEE04020A020A0211022080406 +6E66:000023F8120813F8820843F848400A4013FC1440E04023F82040204027FE0000 +6E67:000027F8111010A087FC444447FC144417FC2444E08027FC2084210422280410 +6E68:000023FC120413FC820443FC4A040BFC10501048E7FE204020A0211022080C06 +6E69:0008203C17C010408FFE404047FC144417FC2444E7FC204027FC20402FFE0000 +6E6A:010021F8120813F0801047FE40801144166820B0E128266820A4212226A00040 +6E6B:43902E102210821242524FD40258269027104AA8CA2852284248424442840302 +6E6C:0610381008527E5408901C282A444882090001047D88095011202118C5060200 +6E6D:01082088109017FE809040904BFC0A941294130CE20423FC2204220423FC0204 +6E6E:000027FC10A010A087FC44A444A414A417FC2040E04027FC204020402FFE0000 +6E6F:000023F8120813F8820843F850001FFE120023FCE49429242244248421280210 +6E70:008021F81208151080E043184C0613F810402240E3FC244023F820402FFE0000 +6E71:0040204017FC104083F8404047FC104017FC2080E10023F82D08210821F80108 +6E72:003C27C012441128800043FC4880088017FE1100E1F822882250242028D80306 +6E73:004040402FFE2040004087FC451454A415F42444E44425F42444244424540408 +6E74:01082090100013FC809040904092149212942298E09020902090209027FE0000 +6E75:0208211017FC104083F8404047FC1100110023F8E4102820204020A023180C06 +6E76:0080210013F8120883F8420843F8104010402764E16821502248244429420080 +6E77:0040204017FC104083F8408047FE1110120827FCEA0A220823F82208220803F8 +6E78:0080204017FE100083F8420843F8100017FE2402E9F42110211022122412080E +6E79:000027FE140015FC8524452445FC1524152425FCE420242025FC2820282013FE +6E7A:0100217C114412448244467C4A10121012FE2238E25422542294231222100210 +6E7B:0040202017FE100081F8410849F8080013FC1204E20423FC2204220423FC0204 +6E7C:0100261C14041404871C4404440417FC10002000E7FC2040204020402FFE0000 +6E7D:0248424824902FFE049082484248500017FC2444E44427FC2444244427FC0404 +6E7E:010020801FFC112085284924400017F0101027F0E40027F82008200820500020 +6E7F:000027F81408140887F84408440817F811202120E9242528233021202FFE0000 +6E80:011041102FFE2110000087FC4040504017FC2444E554255425F4240424140408 +6E81:0088208813FE1088800043FE42021424102023FEE07020A820A8212422220020 +6E82:0102210217C21112811247D24552155217D22112E392254229222102210A0104 +6E83:0040204013F8124883F840404FFE100013F82208E2482248224820A021100608 +6E84:00402444144417FC808041F84208151010E02318EC4623F820402FFE20400040 +6E85:00104F94289228900A9E8AF04A905A9E1AF02A94EA942208250A249A28261042 +6E86:42002200257C84A448245724022422282FA84228CB104A9052A842284A440482 +6E87:004022481150104087FC41504248140410802FFEE1102210232020C023300C08 +6E88:00402240114017F88088409048FC0904110813FEE202242A2AAA228224140008 +6E89:000027BE1488148887A844A844A817BE14102518E49825A826AA244A20460080 +6E8A:000027BC14841484848447BC4400140017BC2424E42427A82410242824440482 +6E8B:000023F811081110811C42E442A4125414A82100E3FC22942294229427FE0000 +6E8C:001023D410581452828C4108420415FA10902090E7FE2090211021122212040E +6E8D:000027FC10A014A482A840A04FFE100013F82208E20823F82208220823F80208 +6E8E:02102210127C12108F90421042FE170016902A10EA7C32102210221022FE0200 +6E8F:0040202017FE142085FC442447FE142415FC2420E5FC25042504290429FC1104 +6E90:000027FE1420144085FC450445FC150415FC2524E42024A829242A2230A00040 +6E91:004022441148104083FC42044A040BFC120413FCE204220423FC200021080204 +6E92:0040204013F8104087FE40004BF80A08120813F8E0A4212823102D4821860100 +6E93:011020A0100017FE80A043F840A817FE10A823F8E0A021B022A82CA620A000A0 +6E94:020821081110100087FC404048400BF810401040E7FE2000254824A428A40000 +6E95:000047FE240229F4000083F840805144166820B0E128266820A4212226A00040 +6E96:2140112083FC524017F82A40E3F8224023FC22000100FFFE0100010001000100 +6E97:003823C0104017FC81504154475811541354254CE0E021502248244428420040 +6E98:0040204013FC104080404FFE4080111013F82008E7FC24A424A424A42FFE0000 +6E99:0040204017FC104083F8408047FC111012482446E24821502248244421400080 +6E9A:0110211017FC1110804040A049100A0815F61000E00023F82208220823F80208 +6E9B:0080204017FC140481104208483C0BD012901290E2902288228824A424D40892 +6E9C:0080277C1424152484A445544648108017FC2444E44427FC2444244427FC0404 +6E9D:0110211017FC111083FC41104FFE104013FC2244E3FC22442FFE220422140208 +6E9E:000023F81148111080A0404041B0164E104023F8E248224823F8204427FC0004 +6E9F:000027FC1404100083F842084BF80A0813F81080E04027FC2000211022080404 +6EA0:01082088109013FC804041F848400BFE10801100E1FC22202420282023FE0000 +6EA1:001020101710157C8510451045FE1708150825FEE50825482728200820280010 +6EA2:020821081110100087FC400041101208140423F8E2A822A822A822A82FFE0000 +6EA3:022042202250248805048EFA540055FC15542554E5FC2554255425542504050C +6EA4:000023FC124013F8824043F84A400A4013FC1004E55425542554240420280010 +6EA5:005040482FFE204007FC844447FC544417FC2444E0082FFE2208210821280010 +6EA6:010825481548155087DE402440141FD410142794E49424A824C8249428141022 +6EA7:000027FC10A010A087FC44A444A417FC10402040E7FC20E0215022482C460040 +6EA8:0110211417D2111081104FFE4010111417D42114E3942548290A211A21260142 +6EA9:0080210013F81208820843F84A000BFE120013FCE00425542554280420280010 +6EAA:003C27C0124411288080411043E01040118823FCE044204027FC20A02110060E +6EAB:400023F822480A488AA8530853F822082000C7FC44A444A444A444A44FFE0000 +6EAC:0208211017FC1040804043F84840088017FC10A0E1282134223C22222422081E +6EAD:000027FC144417FC844447FC41101208148421F8E20825082090206021980E06 +6EAE:020024FE17101510857C45544754145414542754E554255C2510271025100010 +6EAF:0440425E2292201207D2811E45525552155227DEE152211222122222242A0844 +6EB0:004022481248124883F8400047FC100013F82208E20823F8211020A027FE0000 +6EB1:0040204017FC104083F8408047FC1110126825C6E04023F820E0215826440040 +6EB2:00402140165C14448444475C4444144417FC2040E7F8211020A0206023981C06 +6EB3:000021F81108110881F840004BFC0A0413FC1204E3FC220423FC209021080204 +6EB4:0040208013F8120883F8420843F8120813F82050E04827FE20A0211022080C06 +6EB5:000021B81628142887A844A847CE148017B82428E7A824A8249028902AA81146 +6EB6:0040202013FE1202849441084A64089011081204E5FA21082108210821F80108 +6EB7:000027FE140215FA844244C2452A146A14B2252AE46A24AA2522244227FE0402 +6EB8:0040204017FC104083F8404047FE1080111023E0E04827FC2044224825440080 +6EB9:0040204017FC10408FFE4882411013E010402088E7FC20442248244429420080 +6EBA:000027BC1084108487BC4420442017BC108424A4E294229424A4208425280210 +6EBB:000023F8120813F8820843F8400017BC108424A4E294218C26B4208422940108 +6EBC:00002FFE1210121084A44738421014A417BC2040E04027FC204020402FFE0000 +6EBD:000023FE120012FC820043FE4AA80A9012C81286E20823FE2288244824080818 +6EBE:0080210017FC1444844447FC4444148417FC20C8E1502168227C22422442083E +6EBF:001080945F54155495585510557C1F10351055FED51055105F10511040100010 +6EC0:0080204017FC1080810843F04860098417FE1002E7FC244427FC244427FC0404 +6EC1:40102F1029288A284A444CBA0A10291029FE4910CD584A544892491248500820 +6EC2:0080404027FC221001208FFE4882504417FC2100E10021F82108220822280410 +6EC3:0120211012081486891043F84008100017BC2084E4A4229424A4208422940108 +6EC4:0040204010A01190824847FE4A0813F8120823F8E20023F82508250829F80108 +6EC5:00142012101017FE8410441047F21492149225B4E6D42488254A293A2A261042 +6EC6:00002FFE100013F88208420843F8100017FC2514E4A427FC2444244424540408 +6EC7:0040204017FC104083F8420843F8120813F82208E3F822082FFE211022080404 +6EC8:0080204017FE100083F8420843F8100017FC2404E5F4251425F4240424140408 +6EC9:000023F8120813F8820843F848400A4811501040E7FC2120212022242424081C +6ECA:0100210011FC120085F840004BF8088812A811C8E7F8208A21CA26AA20860082 +6ECB:01082088109017FE810841084210129414A42738E1082210221024A427BC0084 +6ECC:44202420247C88444AA84A101A282AD62A104AFECA104A544892491248500820 +6ECD:00402244124413FC80404FFE4000104013FC2244E24423FC2040204427FE0202 +6ECE:08202AA42CA84920145022887FFE4002810401047D88095011202118C5060200 +6ECF:01104208251420A000E083184C0653F810402040E7FC2040224821502FFE0000 +6ED0:0208220813BE14888AA8413E42081448184827FCE0E0215022482C4620400040 +6ED1:000023F8120813C882484FFE480213F8120823F8E20823F82208220822280210 +6ED2:000027FC100813C88248424843C810001FFE2008E3C82248224823C820280010 +6ED3:0080204017FC1484804043F8411010A017FC2040E04023F82040204020400040 +6ED4:003E4FC020842444024882104100561C14042404E71C24042404240427FC0404 +6ED5:0020792448A849FC482078404BFE488849247A224D2448A849244A2248A09840 +6ED6:0080204017FE100083F842084FFE120813F820A4E12823102510294821860100 +6ED7:0210221013DE1528888440784780108010F82780E08020F82F8420842084007C +6ED8:000047FE24022914020885F44040504017FC2000E00023F82208220823F80208 +6ED9:000027FE1450148885FE469044FC149014FC2490E49024FE2480240027FE0000 +6EDA:0080204017FC111082484484412013F010102088E15023202510294821860100 +6EDB:0004203E17C0124481244128420013FC14402040EFFE20402444244427FC0004 +6EDC:0040208013F8120883F842084BF8088017FC1110E24824442BFA204020400040 +6EDD:0080204017FC111080A047FE48000BF8124813F8E24823F8224A2042203E0000 +6EDE:0150215017FC11508150400047FE1442184423F8E24822482248225820400040 +6EDF:0420842044781F488490447C44541E542454447CC4405F4044424442443E0400 +6EE0:000023FC110811F8810841F8410E17F8100827BCE0A422A42128229024A80846 +6EE1:0108210817FE1108800047FE4090109017FE2492E492256A26462402240A0404 +6EE2:0110211017FE111080004FFE4802100017FC2040E04023F8205020482FFE0000 +6EE3:000023FE120012FC820043FE4AA80A9012C81286E20022FC2284248424FC0884 +6EE4:0040207C104017FE8442447047C41444143C2420E410245425422942294A1238 +6EE5:00902490149E149084A844A444C41080100027FCE4A424A424A424A42FFE0000 +6EE6:008040402FFE20A002A882A444A45040104027FEE0E021502248244428420040 +6EE7:4410221022108FA0403E454404A428A431284528C21042104528492850440082 +6EE8:0080204017FE1402881443E04A000A0013FC1210E2102FFE2000211022080404 +6EE9:005040482E8022FE039092904AFC5A90149024FCEA902A90329020FE20800080 +6EEA:00004FBE20882510023E81224FAA52AA122A222AE22A222A221022142A220442 +6EEB:4440244024FC88884B505A201AD82B062AF84A88CAF84A884AF8488848880898 +6EEC:0040202013FC120483FC42004AF80A8812F81200E3FC232425FC2502290200FE +6EED:000027FC144417FC844447FC5248124817FE2248E24827FC20402FFE20400040 +6EEE:420023C222028FE44A284B920E4229C428084B92CA824A844A8A4C92547E0800 +6EEF:02A822A817FC12A882AA44E6480017FC14442040E3F822482248224822580040 +6EF0:0080204013F8111080A047FE400013F8120823F8E20823F82120212222220C1E +6EF1:408020402FFE880250044F90001C20102F90457CC50445284910492A514220FE +6EF2:0080211013F8121084A44FBE404210A013182C46E19026642188263021C00E00 +6EF3:0080204017FC111080A047FC44A41514160C25F4E514251425F4240424140408 +6EF4:0080204017FC111080A047FC444415F4144425F4E514251425F4240424140408 +6EF5:0080404027FE2402089480504524554A18FA2300E04024442444244427FC0004 +6EF6:01082108110817D0811E479451241FD4121423D4E2542248224824D424240842 +6EF7:00402040107E1040804047FC4404164C151424A4E64C24A42514264C27FC0404 +6EF8:0210411021102FDE0028878840085788103E2788E48824882488278824880008 +6EF9:0040207C104017FE8442447845C4143C140824F0E52424A827FE282028A01040 +6EFA:02204220243E25480DA895104528544614802040E1242522250A250A28F80000 +6EFB:0040202013FC1000810840904BFE0A2012A012FCE320222022FC2420242009FE +6EFC:0110211017BE111083B845544912100013F02210E290225022522212240E0800 +6EFD:002027FE142015FC842447FE442415FC142025FCE52425FC252429FC2924112C +6EFE:0080204017FC1110820845F44110111011F02088E15023202510294821860100 +6EFF:0110211017FC1110811041F0404017FC14442664E55426EC2444244424540448 +6F00:08007F7808483E4800863E782A483E304048808401087D90096011202518C206 +6F01:0100210013F0121084204FFC5444144417FC2444E44427FC2000252424920892 +6F02:00004FFE20A027FC04A484A447FC500017FC2000EFFE20402248244429420080 +6F03:008040402FFE2802120483BC422452241FA42028E2282B10329022282A440482 +6F04:00202222122213FE800043FE4A200BFC122013FEE200222025FC24202BFE0000 +6F05:024824901248100083F842484BF80A4813F81040E7FC20E0215022482C460040 +6F06:0040204017FC10E08158464440A0111012482C46E24821502248244421400080 +6F07:021042102450295C0150825046FE5A0012102250E25C225022B02290230E0200 +6F08:0100211013DC125485544288410812F414022000E3FC20402150224825440080 +6F09:0080204017FC14A084A047FC44A414A417FC2400E52425A82530292429A4111C +6F0A:004043F822482FFE024883F8404053F8124823F8E0802FFE211020E023180C04 +6F0B:00204F3C29442AA80A108C284AC6493819102950ED7E2A90287C281028FE0800 +6F0C:011041102FFE211001F0804047FC544417FC2040EFFE204027FC20402FFE0000 +6F0D:00004FFE282A28260FFE88224BAA4AAA1BAA2832E9962E2E284628822FFE0802 +6F0E:01244124222424240954814A429256101A102250E25C2250225022B0229E0300 +6F0F:000047FE2402240207FE840047FE542017FE2622E6AA2A222AAA3222222A0204 +6F10:08207E2008F8FF2814287F6A082AFF56098201047D88095011202118C5060200 +6F11:0100423E2788248804A887A844BE548817882010E4982718242824AA23CA0086 +6F12:0000277C11441144817C47104410147C14542754E154217C211021142AFE0402 +6F13:0080204017FE100082A8424842A813F8104027FCE484252425F424142404040C +6F14:0080204017FC1404800043F8404013F8124823F8E24823F82000211022080404 +6F15:00A020A017FE10A087FC44A447FC14A417FC2000E3F8220823F8220823F80208 +6F16:0208224817481290829E4FE4411412141FD42494E91421C82F08211425140222 +6F17:0040208013FC124482F443144AA40A4412A413FCE04020242522250A290800F8 +6F18:07FE240015FC140087FE451445481586140025FCE50425FC250429FC2904110C +6F19:00404FFE204027FC044487FC444457FC10422FFEE0102FFE2210211021500020 +6F1A:000027FC140014F88488448844F8140015DC2554E554255425DC240027FE0000 +6F1B:00402248115017FC804040804FFE111012482446EA4821502248244421400080 +6F1C:0110211017BC111083B845544912111010402040E7FC2040204020402FFE0000 +6F1D:000027BC108414A4829444A44084104013F82208E20823F82208220823F80208 +6F1E:000E27F010441224810843FC4A040BFC120413FCE20423FC2090211022120C0E +6F1F:0040444422482FFE080283F84208520813F82040E04027FC204020402FFE0000 +6F20:0110211017FC1110800043F84A080BF8120813F8E04027FC20A0211022080C06 +6F21:010021FC120015F8810841F8490809F8100017FEE10023FC24A4212422540088 +6F22:0110211017FE111081F040404BF80A4813F81040E7FC20402FFE20A02110060C +6F23:0020482025FE242001FC81244DFC552415FC2420E5FE242024202A2031FE0000 +6F24:0110411027BC211003B885544912408010802FFCE1102210212020C023300C08 +6F25:008040402FFE29120248844443F8504010402FFEE000204023F8204020400FFE +6F26:08203E3E08447FA82A10492808443FFE200020882ED022A02490488852868100 +6F27:0110411021102FDE012087C0445C57C4144827C8E1102FD021222122211E0100 +6F28:0020247C12841148803040CE4610127C1210227CE21022FE2210221025FE0800 +6F29:0420422022202F7E04808400477C551415102550E55C255029502B5030BE2100 +6F2A:0020492025FC222006508A8843FE520816E82AA8E2A822E822A822082A280410 +6F2B:03F8220813F8120883F8400047FC14A414A427FCE00023F8211020E023180C06 +6F2C:004027FC104013F8804047FE48000BF8120813F8E20823F8220823F821100208 +6F2D:0110211017FC1110804847FC40A0111012082514E11027FE2110211022100410 +6F2E:0040202017FE142085FC442447FE142415FC2420E56224B429282A2630A00040 +6F2F:000027FC144417FC844447FC4100121017E020C8E3042FFE2042224825440882 +6F30:00402444144417FC800047BC44A414A417BC24A4E4A427BC24A424A42AB41148 +6F31:0108210817C81108811E47D24564154017C82108E38825482954211421240142 +6F32:00004F3E2120213C01208F3C482048FE18502F52E1542148214821442A620440 +6F33:004027FC111010A08FFE400043F8120813F82208E3F820402FFE204020400040 +6F34:00402444144417FC8080404047FE14021BF42000E7FC20402250244829440080 +6F35:0108210812881250841E4B944124111417D42114E59425482948211425240242 +6F36:0040204013F8124883F8404047FC144417FC2040E08020482544251428F00000 +6F37:0200211E17D2101287D4445447D8101417D22092E11221DA2714211025100210 +6F38:02004202223C2FA002208FA04ABE4FA41AA42FA4E2242FA42224224422440284 +6F39:000027FC1040127882404FFE410011FC120023FCE00425542554280420280010 +6F3A:0040204017FC1040855442484554104015542248E55420A020A0211022080C06 +6F3B:000027BC108414A4829444A440501188162620C0E31020642388203020C00700 +6F3C:0040244417FC1120811043FE522016201BFC2220E22023FC2220222023FE0200 +6F3D:000027FC140417FC842044A8447014A8150424A0E4FC252024202BFE28201020 +6F3E:0208211017FC104083F8404047FC1040102021C0E0442768215022482D460080 +6F3F:0440247C24A83D5004287DFE24884448851801047D88095011202118C5060200 +6F40:000027FC14A414A487FC4000401C17E012482248E24825542554286220400040 +6F41:200024FE3810222022FC1E84008408FC0A84ECFC28842C844AFC4A48A8841102 +6F42:00402444144417FC80004208411017FC11102110E5142318211021102FFE0000 +6F43:0240444028FC3088035084204CD8570614F82488E4F8248824F8248824880498 +6F44:0108210817C81110811E47E44554155417D42114E39425482948211421140122 +6F45:0100210013FC144080804FFE4120121017FC2A20E3FC222023FC222023FE0200 +6F46:01104FFE211020000FFE8882511443E010402088E7FC20442250244829440080 +6F47:011041102FFE2110004087FC40445FFE104427FCE04025642554265428441044 +6F48:000027FC14A414A484A447FC40801144166820B0E128266820A4212226A00040 +6F49:00402444144417FC800047FC440417FC140427FCE000242427A8243225A2061E +6F4A:421022102510849E48105710027C22242FA44224CB284AA8529042284A440482 +6F4B:42102210251084A0483E5744002424A432A44AA8C8A8411043A85C2840440082 +6F4C:0080204017FC1514820847FC4080111013F82048E04023F8204020402FFE0000 +6F4D:04508448448008FE8B905E9044FC049028905EFCC8904090469058FE40800080 +6F4E:0108210815481390811E47D44564155415542754E5D4254825482554246404C2 +6F4F:000027F81090106087FC40A4412816A0104027FCE4A4251426EC24A424E4040C +6F50:0140212013FE122086204BFC4220122013FC2220E22023FE2200252424920892 +6F51:002423A81092151482084C0447BA10A817C62400E7BC208420A8209025280244 +6F52:010041F0221027FC0A24824443FC5080114426A8E130266820A8212426A20040 +6F53:004040402FFE204007FC844447FC544417FC2044EFFE204220242522250A08F8 +6F54:010027BC11141394811447A4414C1080111023E0E04827FC2044224825440080 +6F55:0100210013FC16A88AA842A847FC12A812A822A8EFFE200022A8225424540000 +6F56:00004FBE220827BC02088FBE400057FC14442444E7FC24002402240223FE0000 +6F57:0140212013FE16208BFC422043FC122013FE2240E0402FFE215022482C460040 +6F58:007827C01248115087FC41504248140613F82248E24823F82248224823F80208 +6F59:0004203E17C01244812843F84A080BFC120413FEE40226AA2AAA2A0230140008 +6F5A:004023F8104817FE804843F840401554175C2444E7FC2444275C255425540844 +6F5B:000027BC1108152887BC431855AA1946100023F8E208220823F82208220803F8 +6F5C:0110411027BC21100FFE811042A8544413FA2208E20823F82208220823F80208 +6F5D:004020A0111816E6800043F84A080BF8100017BCE08424A4229424A422940108 +6F5E:0010279014BC14A484C447A841101128114625C0E53C2524252425A42E3C0024 +6F5F:010026381408140887384408440817F8120027FCE80425542554280420280010 +6F60:000027BC14A417BC842044A4439C1000111027FCE11021102FFE211022080404 +6F61:021041102FD0201007BE84A447D4501417942094E11421C82F08211425140222 +6F62:0110211017FC111081104FFE404017FC144427FCE44427FC2000211022080404 +6F63:000027BC14A417BC84A447BC4484144415F42424E4A4244424A4250424140408 +6F64:000027BC14A417BC84A447BC440415F4144424E4E444244425F4240424140408 +6F65:000027FC10A010A087FC44A444A417FC12482150E7FC20E0215022482C460040 +6F66:0040204017FC10A08514420847FC1A0A13F82208E3F820402248244429440080 +6F67:02082110100017FC8444455444E4144417FC2000E3F8220823F8220823F80208 +6F68:0080210017FC14A484A44FFE4000103C17C02144E24424E8215022482C460040 +6F69:000027FC144417FC844447FC4110111017FC2110E1102FFE2000211022080404 +6F6A:020043DE251221120FD28292425E540013FC2204E20423FC2204220423FC0204 +6F6B:00402248115013F8808047FC41101288151621E0E04823FC20442248244400C0 +6F6C:000027BC14A414A487BC40004BF80A4813F81248E3F8204027FC204020400040 +6F6D:000027FC10A017FC84A447FC400013F8120823F8E20823F8204027FC20400040 +6F6E:0100411E27D22112011287DE445257D2145227DEE11221122FD22122212A0144 +6F6F:000023FC100413FC800443FC48000BBC112417BCE00823FE2108208820A80010 +6F70:004023F8124813F8804047FE48000BF8120813F8E20823F8220823F821100208 +6F71:004027FC104013F8800047FC440413F8100023F8E20823F82208211027FC0000 +6F72:01104E102254223802108F7C4244534416FC2644EA44227C2244224422540248 +6F73:000023FC1204120483FC42224AFC0A2813FE1220E2FC238422FC248424FC0884 +6F74:0020492025FA222406288BFE4220524016FC2B44E244227C224422442A7C0444 +6F75:0288228817C81290829E4FD4402417D4145427D4E45427C824482454246404C2 +6F76:000027FC1444155484E4444447FC104017FC2040E0402FFE2000252424920892 +6F77:021023DE15281084804043F8404817FE104823F8E04023FC204027FE20400040 +6F78:042084205FFC0420956855AA652600002FF84808CFF848084FF8480848280810 +6F79:0040204017FC10E08150464C40401110111027BCE11023B82554291221100110 +6F7A:07FC240417FC140085F8441047FE14201460279CE484250829DE2F0831080318 +6F7B:003823C0104017FC8150424844A4111012482C46E24821502248244421400080 +6F7C:004023F8111010A087FC40004BF80A4813F81248E3F8204023F8204027FE0000 +6F7D:0208211017FC10A084A442A84FFE100013F82208E20823F82208220823F80208 +6F7E:00402248115017FC8150424844441208120823BEE4882AA8213E220824080808 +6F7F:000027FC144415F4849447FC440415F4151425F4E44424F4254425FC244407FC +6F80:00004FBC229426B40AD484A445AC584011082108E5A8252C252825A82E7E0000 +6F81:40402040227C824042404FFE0000220822084228CBAE4A284A284BA85E7E0000 +6F82:010825481548155087DE401447E4101417D42114E7D4210821082FD420240042 +6F83:0BFE104061FC090411FC610405FC090431FCC088010C7D90096011202518C206 +6F84:002027A410A812928114420855F4180213F82208E20823F8220821102FFE0000 +6F85:004023F8104817FE804843F8404017FE100023F8E24823F8224823F8200007FE +6F86:0040404027FC20400FFE811047BC51101190263EE0002FFE2120212222220C1E +6F87:0110455425B8291002A88444400057FC14842888E7F820882088210822280410 +6F88:0208210817C81210849E4FD44064179414942794E49427882488249424A405C2 +6F89:00084788208821100FDE849444A4579414942794E49424C827882C9420A400C2 +6F8A:0108209017FE109083FC42944B1C0A0413FC1204E3FC200827FE210820A80010 +6F8B:000023F8120813F8820843F8404017FE100023F8E20823F820402248244400C0 +6F8C:04804482249C2FD004908790449E579414942494EFD42014251428A430240044 +6F8D:010441042FE42104013E87C4400457E414542454E7C42444228420E42F140408 +6F8E:010441042FE82110010087C4400457C814502442E7C22444228420E82F100420 +6F8F:000023F81208120883F8400047BC14A414A427BCE04024442444244427FC0004 +6F90:000047FC20402FFE0842835840405358100027FCE0002FFE2100220827FC0204 +6F91:000027FE10A017BC84A444A447BC10A017FC2444E44427FC2444244427FC0404 +6F92:000020FE10101720827C42444244127C1244227CE3C42E44207C202820440082 +6F93:01402140127E1480897C4144427C16441A7C2220E23C224422A82210222802C6 +6F94:01082128122817BE84A844C8448814FE17802480E4BE24A224A227A224BE0022 +6F95:01102FFE1110100087FC415051501FFE11502150E7FC20402FFE204020400040 +6F96:000027BC14A417BC84A447BC4444144415F42444E4E42554264C244424540408 +6F97:000027BC14A417BC84A447BC440415F4151425F4E51425F42514240424140408 +6F98:0110211017BC111083B845544912100013F82208E20823F82208220823F80208 +6F99:00002080173C140487BC440447FC120013FC2400E7FE2002255224AA28AA0004 +6F9A:010027FC14441554844447FC44E4155410002FFEE20023FC2004200420280010 +6F9B:010043F024102FFC144487FC444457FC10002FFEE00023F8220823F8220803F8 +6F9C:0200217C1504144485F4444445F41554157425D4E55425F424E425542444044C +6F9D:008040402FFE28820548851448F4400017FC2444E7FC244427FC244424540408 +6F9E:0040207C104017FE844245F8444415FC150825F8E40025FE24202BFE28881306 +6F9F:00404FFE200027FC040485F4451455F4140427FCE00823F020402FFE21500E4E +6FA0:000027FC14A414A487BC40A047BC14A414A427BCE4A424A427BC24A220A2007E +6FA1:03F84208220823F8000087BC44A454A417BC2040EFFE21602250244838460040 +6FA2:00402248115017FE8402480443F8120813F82000E7FC244427FC244427FC0404 +6FA3:0108410821142FD4012287C0445C57C8144827C8E13E2FC82108210821080108 +6FA4:000027FC14A417FC804043F8404017FC111020A0E3F820402FFE204020400040 +6FA5:4400273C291492144FA44ACC0A802FA82ABE4AC8CF884A884ABE4A8848881188 +6FA6:00004FBE20882510023E81224FA252BE1222223EE2222222223E22002A140422 +6FA7:00A020A017FC14A487FC44A447FC100017FC2000E3F8220823F8211020A00FFE +6FA8:0210221013DE15288884400047FC104012482248E248255428E220402FFE0000 +6FA9:0A803138228838382288393822887FFE410281047D88095011202118C5060200 +6FAA:000047FC20402FFE084283584040535810A02398EC4623F02010232020C00020 +6FAB:0110211017FC111083F842484BF80A4813F81040E7FC2444245425F42414040C +6FAC:0440227C1084112886204250488C0BF8120813F8E20823F8220823F821100208 +6FAD:0040202017FE10288224427E44C81748117E2248E4C82F7E21482248247E0840 +6FAE:004040A023182DF6000087FC455454E417FC2000E3F8220823F8220823F80208 +6FAF:008040DC228423D404488A9443244C4012482150E7FC20E0215022482C460040 +6FB0:0040204010A01110820845F6400017BC14A424A4E7BC22102210252829441082 +6FB1:40002FDC285488544FD44A940AA62FC02A9C4A94CFD448145288524864540822 +6FB2:00A024A412A810A087FC411040A017FC104023F8E04027FC215022482C460040 +6FB3:0080210017FC14448554444447FC14E415542404E0402FFE20A0211022080C06 +6FB4:000023FC1294129483FC400047FE100013FC2204E3FC20A2211423082D440182 +6FB5:0200210217DC10108450429047DE1114111427D4E11425942554292425240244 +6FB6:00404FFE200027FC040485F4451457FC100023F8E20823F8220823F820000FFE +6FB7:03F8220813F8120883F8400047FC14A417FC2040E7FE210021F8210822280410 +6FB8:0014201217FE141085D0441445D4155815CA2416E442282422A2228A24780000 +6FB9:020043F8241027FE0D48962447FE540015FC2400E5FC240025FC290429FC1104 +6FBA:0080204013FC1108809047FE400013FC120423FCE20423FC20402524250A08FA +6FBB:00882448125010FC802040504694123812502298E23422542290222025FE0800 +6FBC:00102008178814BE848044944788147E14082788E6BE2A882A882B8832880008 +6FBD:0040207C104013FE824242784BC40A3C120013FEE24023A4225825B4245209B0 +6FBE:00102410127C101080FE4044462812FE1210227CE21022FE2210221025FE0800 +6FBF:0110211017BC111083B845544912100013F82000E7FC20402248244429420080 +6FC0:021044102F9028900FBE88A44FD4541412142FD4E4142788248828942A941122 +6FC1:000027FC14A414A487FC420053FE14421BFA224AE3FA2052207A278A22140008 +6FC2:002027FE1508149087FC445045FC145417FE2454E5FC245024D829542A521050 +6FC3:009023FC129413FC829443FC48000BFC120012F8E20023FE2520251425480986 +6FC4:000044F8228822E800A880A84DFC450415742554E5742504251425082A0011FE +6FC5:00404FFE280223F8000883F8400857FC144423F8E248204027F8211020E00F1E +6FC6:004027FC104011108FFE411043F8120813F82208E3F8220823F8211022080404 +6FC7:0040204017FC1248824845544FFE100017FC2404E5F4251425F4240427FC0404 +6FC8:03D42252125213D080104FFE425013D4125423D4E25422F82F4A244A20560062 +6FC9:002840242F40297E09C88F48497E59481F48297EE94829482F48297E20400040 +6FCA:0020213C112017FE801040144BFE0A1013F01254E25422D42368244A28960322 +6FCB:0110211017BC111083B845544912100017FC2044E24022782240254028FE1000 +6FCC:1C20702211B4FCA810A87D2456A27C4055FC7D0411047DFC11041F04F1FC4104 +6FCD:01104FFE2110220003FC84A44BA4416412542494E108204020242522250A08F8 +6FCE:01F8210811F8150A85FA450A45FA1402179E2090E0902F9E2492249224920892 +6FCF:000027BE1108110887BE4108410817BE10002080E0442512252229C023040CFC +6FD0:03FC220413FC120483FC40444BF8085017FE1040E1FC270421FC210421FC0104 +6FD1:021042102F9C222402488FBE4AA25AAA1FAA222AE72A2AAA3288221422220242 +6FD2:4200227E2A108BA04A7C4A441FD4205422544AD4CAD44B545120422844441882 +6FD3:004027FC111010A087FE44A047F814A817FE24A8E7F824A025B02AA82CA610A0 +6FD4:000027FC124814448FFE444446EC155416EC2444E6EC255426EC244424540408 +6FD5:000027FC140417FC840447FC421014A417382210E4A427BC2000254824A408A4 +6FD6:000027FC14A414A487FC404843F8105017FE2040E1F8230825F8210821F80108 +6FD7:01102FFE111013F8820843F8420813F810802FFEE24827FC2A4A224822580040 +6FD8:0080204017FC144482A842944474100013F822A8EFFE200027FC204021400080 +6FD9:0110455425B8291002A884444FFE480210402248E248245020A0211022080C06 +6FDA:0110455425B8291002A88444400057FC14442040E7FC20E0215022482C460040 +6FDB:011027FC111017FC840443F8400017FC10802144E6A8217026A8212626A00040 +6FDC:004023F8104817FE804843F8404017FE100022A4E45223F822A822A82FFE0000 +6FDD:010827FE110811F8810841F8410817FE11082294E5E2204823FC2040224804C4 +6FDE:008023F8120813F8820843F8400017FC144427FCE44427FC20002FFE21100210 +6FDF:0080204017FC111080A44F58455415521B582000E20823F8220823F822080408 +6FE0:004027FE100011F8810841F8400017FE140223F8E180264421B8266821A60E60 +6FE1:000047FC20402FFE084283584040535810002FFEE04027FC24A424A424A4040C +6FE2:07BC208414A4129484A4404047FC1110111022A8E44420402FFE204020400040 +6FE3:4210221022289FA842444F8A08A82F9828C84FA8C20E5FB84208420842080208 +6FE4:004027FC104013FC800047FE400213F8104027FEE00027FE200827FE24A80798 +6FE5:008041F82690206001A08FFE480247FC104027FCE44427FC244427FC22080404 +6FE6:003E27C01244112883F8404047FC100013F82008E3F8200823F82544252A08FA +6FE7:028442842AA426C4029E8FE440045454128C2FE4E10427C4210421C42E140008 +6FE8:0210212017FC1210821044A44738121014A427BCE08021482554251428F00000 +6FE9:010827FE1148122087FE4A2043FC122013FC2220E3FE220027F8211020E00F1E +6FEA:021042102F9C22240FC8823E4FAA502A1FAA28BEEFA028A02FA228A22AA2091E +6FEB:001027D0151017DE845047E8450417C4100023F8E2A822A822A822A82FFE0000 +6FEC:0040207C104017FE840243FC424814A4111023F8E60C2BFA220823F8220803F8 +6FED:011027FC1110104083F8404047FC1080111023F8E00023F822A822A82FFE0000 +6FEE:012821AA116C122882FE464456281AFE1210227CE21022FE2210222822440282 +6FEF:000027BC108414A4829444A44120121017FC2A20E3FC222023FC222023FE0200 +6FF0:422822242440857E49C85F48027E244829485F7EC14840485548557E50400040 +6FF1:0080404027FE24020BFC8148425057FC120427FCEA0423FC220423FC21080204 +6FF2:0200421C2F942214071480264F8048BC17142014E2142F8827082A9432240242 +6FF3:0108452827BE294807BE831845AA594613F82208E20823F82208220823F80208 +6FF4:0110455425B8291002A884444FFE484210402764E16821502248244429420080 +6FF5:002027FE140213FC822443FC4A000AFC128412FCE28422FC228424FC24480884 +6FF6:07BC24A417BC14A487BC4404443415C4144427FCE44425F4251425F424140408 +6FF7:0108799009603518C206011047FC211081F0404017FC1664E55426EC2444244C +6FF8:01102FFE1110104081B04E4E43F8120813F82208E3F8220025FC250429FC0104 +6FF9:000027FC144417FC844447FC404017FC10402FFEE5242892204027FC20400FFE +6FFA:00142792149E14F08794448A449617E214942492E79E20702514248A28960062 +6FFB:0010277C1554157C851046FE4500157C1544257CE544267C2444247C24280444 +6FFC:044444E428A82AAA0EEE84A44AAA4EEE12422040EFFE20E0215022482C460040 +6FFD:02084FBE22082FBE0208851448A257FC140427FCE40427FC240427FC21100208 +6FFE:0020203E102017FE842245F8442215FE152425FCE52425FC28402AA4328A047A +6FFF:000027FE148817FE848845FC452415FC152425FCE42027FE262A2AFA2A0A1206 +7000:07FC408023F8220803F882084FFE588215482514E8F4210023F8250820F00F0E +7001:0208211017FC104083F8408047FC114813FC260AEBF8220823FA2234228C0302 +7002:010043F024102FFC144487FC444457FC15242892E3F8220823F8220823F80208 +7003:40002F7C2944897C4F444944097C2F20297E49AACF2A404A4A924922494A1104 +7004:0210221013DE15288084400047BC14A417A424A4E7A42434252826A024200020 +7005:0110455425B8291002A884444FFE480213F82040E04023F8205020482FFE0000 +7006:00404FFE204027FC000087FC44A457FC120823F8E20823F8220823F821100208 +7007:0040202017FE148885FC448847FE142015FC2524E5FC252429FC288831040202 +7008:07BC24A4129414A48FFE484247FC104013F82248E3F8224823F8204027FC0040 +7009:00404FFE28822338020883B8420853F8120027FCE80425542554280420280010 +700A:010023DC12541366824047DC42541348125424A2E00023FC2294229427FE0000 +700B:004047FC2404283807C08248415057FC12482404EBFA224823F8224823F80208 +700C:0080204017FC14A087FC44A447FC1400152425A8E53025A4251C28002AA41452 +700D:002027FE140015FC852445FC452415FC142025FCE42027FE25242AFA282013FE +700E:010827FE1108100083FC42944A940BFC102813FEE220232422A82292242A08C6 +700F:020225E214A216AA852A466A410A128A144A2BAAE10A27CA2122254221EA0E04 +7010:0114211217D2111081104FFE429016D2129226D2E29426D4228A22CA2F160022 +7011:03F8220813F8120883F8411047FC11101FFE2110E248255420E02150224800C0 +7012:00404FFE2248255408E2815042484DF6100027FCE40425F4251425F4240407FC +7013:028842A826A82BF0001E822445D45C1415D42494E49425C82488249425D40422 +7014:02009FDC42140F9480145FD450660F80201C4F94C2145FD447084A8852540222 +7015:0100213E150815D0853E45224FE2103E1122257EE56225A228BE210022140C22 +7016:07FC204017FE14428B5C4040475C112013FC2620EBFC222023FC222023FE0200 +7017:00404FFE284227FC004083F8404057FC104027FCE4A427FC20402524252A08FA +7018:0040207C104013FC824443F04A440AFC12A812F8E2A822F8220025FC25540BFE +7019:4400223C2FA4802448BC45240FA4223C22244FA4C23C4B104A9852A84A2A0446 +701A:0410841044281F4484825F0051EE1F2231AA5F66C4225F6644AA442244AA0444 +701B:0080BFFC48000FF880004FF848080FF820805C9CD7D45D54555C5C9655562E22 +701C:00084F8820082708053E852A472A502A1FAA2DBEEAA82F882A8A2A8E2ABA0990 +701D:000027FE14441598848847DE448815DC16AA2488E4202520253C2920292017FE +701E:022042202FB822480F90827C4F9450141FFE2894EF9428FC2F9428902A900930 +701F:011027FE115013F8804847FE404813F81554275CE44427FC2444275C25540954 +7020:0110455425B8291002A8844447FC5484111023E0E04827FC2044224825440080 +7021:00104E7E2B202ABC0AC88CBE4A004BBC1AA42ABCEAA42CBC28A428AC29400A3E +7022:002049FC252421FC002083FE4D0445FC150425FCE50425FC248825042BFE1000 +7023:010041BC252427A804908AA8414652A017BC20A0E3B820A027BC20A02FFE0000 +7024:008040402FFE200007FC84A447FC524811502208E44420A8211023082D460180 +7025:07BC24A4129414A4804047FC400011F0111021F0E00027FC240424E424A404EC +7026:00109F90427A04128C1452FE47080A10333C46E4CAA4523C422442244A3C0424 +7027:0210211017DE1010845E428247DE101017DE2450E7DE245027DE2450245204CE +7028:0108210817CE1112812447DE4552155E17D2211EE392255E2940211421120122 +7029:01804E3E22083F90023E87224AA2527E1022273EE5222522257E298029141022 +702A:20207F3EAA447FA82A103F2804441FF010101FF010101FF001843D480930730E +702B:02009FDC42140F9480145FD450660F80241C4894CF1442945FC84A8852540622 +702C:4200223E2F888210423E4FA20AA22ABE2FA2423EC72246A24ABE520042140222 +702D:0410841044281F4484825F7C55001FE235AA5FAAC4EA5FAA44AA44E244AA04A4 +702E:07FC40402FFE2842035880404358500011102FBEE11023B82554291221100110 +702F:008822AA12DC14888154422247FE140211F82108E1F8200023FC220423FC0204 +7030:40002EFE2254829242FE4E9208D628BA28D64E92C2D642BA42D642924A9A0484 +7031:40002FFE29128FFE40004FFE08802AA2288A494ACA2A488A4AAA5082514A2224 +7032:0208820845080890905E6FA4401400143DD45554D5545DC84888489455542222 +7033:011027FE1110104087FE44A047FC14A417FC2500E5FC250025FC280435540008 +7034:07BC24A417BC14A487BC44A447BC131814A42080EFFC2110232020C021B00608 +7035:0248215017FC1150864C43F8424813F8124823F8E11027FC21102FFE22080404 +7036:00404F402A7E2A800A008F7C49444944197C2F00EAEE2AAA2AAA2AAA2FEE00AA +7037:000027BC14A4129484A443F8424813F8124823F8E11027FC21102FFE22080404 +7038:0448444C2AAA20080FFE82884EE8528A1EEA228CEEEC228822EA2F1A24260042 +7039:404020A0211082084DF640000EEE2AAA2EEE4000CFFE49224FFE4922492A0804 +703A:01F0221017FC120483FC42244BB80A2211FE1210E7FC224423FC20D0214A063E +703B:011447D221102FFE001087D0455257D2155227D4E29427C8228A2FFA22A60442 +703C:004027FC100013B882A843B8411017FC111027FCE1102FFE212823102D480186 +703D:004027FE149213FC809043FC409017FE110823FCE50A21F82240227C254008FE +703E:07BC24A417BC14A487BC444445F4144415F42554E5F4255425F424E42554044C +703F:021043D0241E2FE405548FF4454857D411B22220E7C0208827FC204423500488 +7040:07FC40402FFE28420358804043585000127C2FC4E27C27442AFC3244227C0244 +7041:4FBE28A22FBE88A24FBE484209F2291229F24912C9F248464F6A49524A4A0CC6 +7042:003C27C01244112887FC44A447FC1008178824FEE78824A82798250825A80690 +7043:015023F8155417FC855447FC455417FC100027FCE00023F8220823F821100FFE +7044:03FC210811F8110881F8410E47F8100817FE2294E39C2294239C22D627BC0084 +7045:07FC444427FC244407FC80004FBE5AAA1FBE2AAAEFBE2040204027FC20400FFE +7046:009027FE109013E8828843CE4A500BD412A213E2E00023FC2294229427FE0000 +7047:049242942FFE211007FC804043F850401FFE2480E7BC2494279424C82F9400A2 +7048:07BC24A417BC14A487BC44A447BC112013FE2220E7FC2A2023FC222023FE0200 +7049:0A98951454900A3E9F2851685F3E00283F28553ED5285F2850A850BE4FA00020 +704A:0FBE45282FBE2308059A892647FC500013F82208E3F8200027FC249425F4044C +704B:00404FFE29202FFC09248FFC49004BFE18022AAAE8442BF828402FFC291013F8 +704C:01104FFE211027BC04A487BC4140512013FE2220E7FC2A2023FC222023FE0200 +704D:0FBE48A22FBE28A20FBE8C424A924FDE19262D5AEFD22912292A2A462C0A0804 +704E:05089FC8555C1FC895485FFE40081FD020144FBEC8804FBE48AA452A43AA1C7E +704F:40002FBE28888F9048BE4FA202223FEA202A4FAAC8AA4FAA42084A9452520622 +7050:0110455425B8291002A884444FFE484210A02318EDF6204027FC224821500FFE +7051:0FBE400027BC24A406B484A4404057FE14A027FCE4A427FC251229DC291211CE +7052:052847BE294827BE031885AA494653FC120423FCE20423FC220423FC21080204 +7053:210447C88812F3BC20084B92F83E0380AAAAABAA01087D90096011202518C206 +7054:05109FD0555C1FE495485FFE402A1FEA202A4FBEC8A04FA048A2452243A21C1E +7055:040C820A5FC8051E92545574505E1FD422145FDED45455545754505E51501090 +7056:002027FE148817DE848845DC46AA1488145027DEE45025DC24502BDE28501050 +7057:081088FE48003EFE2A822ABAAAAA6AFE3E00287C08444A7C8E443A7C100000FE +7058:451825142F90853E472842680FBE2AA82FA8423ECFA842285FE8453E48A01060 +7059:0248215017FC140481F0411047FC155414E427FCE04027FC20402FFE22A40452 +705A:02AC444426AC244406AC84044FFE4A0A13F82208E3F8220823F820A02124061C +705B:4F1E29122F1E89124F1E4BBA0AAA2BBA29F24952C9F2495249F248424BFA0846 +705C:0080BFFC48000FF880004FF848080FF820005DDCD5545DD4555C5DD654962D62 +705D:40002FBE28888F9048BE4FA202223FFE20224FBEC8A24FA2423E4A8052540622 +705E:47FC20402FFE8842435845000FBC25242724423CCFA44AA44FBC42245FA4024C +705F:07FC240417FC152484A8452445FC155415FC2644E5F4255429F4284433F40008 +7060:0790251E17A8148487BE452A47BE100013F82208E3F8220823F820A02124061C +7061:011027FE111017BC84A447BC44A417BC144427FCE55425F4244424E425540448 +7062:004027FC124813F880404FFE4AAA13B8111027FCE1102FFE212823102D480186 +7063:444428E82E0E84E44A0A4EEE00A02AEA200047F8C00847F8440047FC40040038 +7064:444424E42A0A8EEE44044AEA0E0E20E02AAA4AEAC0404FFE415042484C460040 +7065:02001FF010101FF010101FF0092013107C7C44447C7C44447C7C92925454B2B2 +7066:00009FDE50441FC8905E5FD24892155E3DD2489ED5525DD2401E5540554C0012 +7067:42102A902F9C8AA44FC84ABE0FAA202A3FEA403ECFA048A04FA248A245221F9E +7068:04109F9C493406089FB6401C4F8808BE2F8048BECFA2423E5FA2423E42140222 +7069:42082A882F9C8A884F884ABE0F8820103FD4403ECF8048BE4FAA48AA452A1FFE +706A:428822E82F5E82EC475A4AE802082FFE29425494C55847F2420443E8420203E4 +706B:010001000100110811081110212021004280028004400440082010102008C006 +706C:0000000000000000000000000000000000000000000000002488224442448004 +706D:0000FFFE0100010011081108111021204280028004400440082010102008C006 +706E:010011081108229004401830E00E0440044004400440084010422042C03E0000 +706F:1000100013FE1020542058205020902010201020102028202420442040A08040 +7070:040004000400FFFE0480088008880A9012A014802140414082200210040E1804 +7071:1000100011FC1044544458445044904410441044104428842484450442288410 +7072:080408040804094449444A444C44884408440844144412442104210440148008 +7073:0800080008001FFC100422044244924412842204050404840844100460280010 +7074:1000100011FC1020542058205020902010201020102028202420442043FE8000 +7075:00003FF8000800081FF8000800083FF801001110111022A0044008203018C006 +7076:10201020102010205420582051FC902010201020102028202420442043FE8000 +7077:010011081108229004401830E00E082008200820FFFE08200820102020204020 +7078:040004000FE01040208003600C18700401001110111022A0044008203018C006 +7079:1010107813C01040544058405040907E17C010401040284224424442403E8000 +707A:1020102010201120552C5934516493A411241134112829222522450240FE8000 +707B:010001003FF8010001000100FFFE000001001110111022A0044008203018C006 +707C:10401040108010FC55045A045004910410841044104428042404440440288010 +707D:1110111022204440222011101110000001001110111022A0044008203018C006 +707E:020001007FFE400281040100110811081110212002800280044008203018C006 +707F:102010201020102055245924512491241124112411242924252445FC40048000 +7080:100011F8101014205840508051FE909210921092111229222622444240948108 +7081:00007FF80200420042007FFC0480088010842084C07C00002488224442448004 +7082:101010901090148858885124512492221440104010882884250443FE41028000 +7083:0440082010102FE8C4260420082010A06040010011101120228004401830E00E +7084:100013F81088148858885088508897F811081108110829082508410847FE8000 +7085:00001FF0101010101FF0101010101FF00100110811102280044008203018C006 +7086:10401020102013FE548858885088908810881050105028202450448841048602 +7087:104010401040148058FE51085288908810881050105028202450448841048202 +7088:100010F81088148858885106520091FC10841084104828502420445040888306 +7089:10801040104015FC59045104510491FC11041100110029002600420044008800 +708A:104010401040127C528454885920902010201050285028502488448841048202 +708B:1000100011FE1010541058205020906810A41122122228202420442040208020 +708C:1020102010501450588851045202908810881088108828882488450841088208 +708D:1008101C11E01500590051FC5144914411441128112829102510422842448482 +708E:010011081110212002C004301808600401001110111022A0044008203018C006 +708F:10401040104014405944514451489250104010A010A028902510410842048402 +7090:10201020102011FC54205820502091FC1020102010202BFE2420442040208020 +7091:10201020102014205BFE50205070907010A810A811242A222420442040208020 +7092:10201020102010A854A458A25122912012241024102828082410442040C08300 +7093:101011101090109054105910509090901010101E13F028102410441040108010 +7094:10401040104017F8584850485048904817FE104010A028A02510411042088406 +7095:10801040104013FC5400580051F09110111011101110291225124612420E8400 +7096:10201020102011FE5420592451249124112411FC1024282024224422401E8000 +7097:08200820FFFE0820082008200FE0082001001110111022A0044008203018C006 +7098:1008101C11E015005900510051FE911011101110111029102510421042108410 +7099:020004000FF81210692004C003000C0071001110111022A0044008203018C006 +709A:002000207C20442444A444A444A87D2044204450445044507C88448801040202 +709B:010011081108229004401830E00E08800888109030E0518096841084107C1000 +709C:10401040104013FE5440584051FC9040104013FE10422842244A444440408040 +709D:1040104010A014A059105208540691F011101110115029202504450440FC8000 +709E:10401020102014005BFE50405040906010501048104428442440444040408040 +709F:1000100011FC15045904510451FC91041104110411FC29042400400043FE8000 +70A0:100011FC11241124552459FC51249124112411FC112428202420442040208020 +70A1:1000100013FE14205820502051209120113C1120112029202520412047FE8000 +70A2:102010281024102055FE58205070907010A810A811242A222420442040208020 +70A3:1000100013FE1008540859E8512891281128112811E829282408440840288010 +70A4:100013FC108410845484590451149208140011FC110429042504450441FC8104 +70A5:10901090109013FC5494589453FC9290129013FE10922892251A451442108410 +70A6:10501048104814405BFE5080508090FC11441144112829282610422844448182 +70A7:1080108010FE15005A205120512C917413A41124113429282522450240FE8000 +70A8:10201010101015FE5902520450809088109010A010C0288224824482407E8000 +70A9:1040104010A014A0591052485426902013F810081010291024A0444040208020 +70AA:10201020112415245924512451FC902010201124112429242524452441FC8004 +70AB:10201010101015FE582050205044908411F8101010202844248245FE40828000 +70AC:100011FE11001100550059FC510491041104110411FC29002500450041FE8000 +70AD:0100210821083FF808000800FFFE10801088148824902940414082200C183006 +70AE:1080108011FC15045A0455F451149114111411F4110429282512450240FE8000 +70AF:100011FE110215025902517A514A914A114A114A117A294A25024502410A8104 +70B0:080008001FF020105F90109010901F901050102410040FFC0000488844448444 +70B1:02000400082010103FF800081FF0101010101FF00100111022A004401830E00E +70B2:102010201040108855045BFE5002900011FC1104110429042504450441FC8104 +70B3:100013FE10201420582053FE522292221252124A128A2B0226024202420A8204 +70B4:10201020102011FC5524592451249124112413FE102028502450448841048202 +70B5:10401040107C108455885A50502090501088130610602810240844C040208010 +70B6:1020102010201020543E58205020902011FC1104110429042504450441FC8104 +70B7:10401020100015FE582050205020902011FC1020102028202420402043FE8000 +70B8:11001100110015FE5A805280548090F810801080108028FC2480448040808080 +70B9:02000200020003FC020002003FF02010201020103FF000002488224442448004 +70BA:020012000A007FF0042004400FF8080810101FFC20042AA44AA4900400280010 +70BB:1000100013FE102054205840504090FC11841284148428842484448440FC8084 +70BC:1040104017FC108054805BE05120922013FC1020112829242622442240A08040 +70BD:1000100011FC1104550459045104910411FC1104100028902488450442028402 +70BE:100011FC110411045504590451FC9050105010501050289224924512420E8400 +70BF:1020104011F815085908514851289128110817FE110829082508410842288410 +70C0:1008103C13E01020552458A450A8902013FE1020102028202420442040A08040 +70C1:1008101C11E0110055205920512091FE1020102010A828A42522462240A08040 +70C2:1000110810881490580053FE50009000100011FC100028002400400043FE8000 +70C3:100011FC100810105430584850849302100011FC102028202420442043FE8000 +70C4:10401020102013FE540058885104920210881088105028502420445040888306 +70C5:102010201040148059FC51545154915411541154115429542554415443FE8000 +70C6:10801080113C120054805880517E930815081108110829082508450841288110 +70C7:10201020105014885904520251FC90201020102011FC28202420442043FE8000 +70C8:00047F84082408241F24212451240A24040408143008C0002488224442448004 +70C9:080008001FE020204040BFF820082288244828280100111022A004401830E00E +70CA:11041084108814005BFE5020502091FC1020102013FE28202420442040208020 +70CB:08400840104037FC50E091501150124814441842104000002488224442448004 +70CC:109010901090151059FE53105510913811381154115429922510451041108110 +70CD:10201120112011FC55205A20502093FE1090109010902890251245124212840E +70CE:00003FF808200820FFFE08201020202041201110111022A0044008203018C006 +70CF:020004001FF0101010101FF010001FFE10001FFC000409242494249440280010 +70D0:1020104011F8150859485128512893FE11081148112829282508420842288410 +70D1:10901090109014925A945098509091981294149210902890251241124212840E +70D2:10281024102414205BFE5020502093A0112011101110291025CA470A42068002 +70D3:1020102011FC14205820502053FE90001020102011FC28202420402043FE8000 +70D4:100011FE11021102557A59025102917A114A114A114A297A25024502410A8104 +70D5:0028002400203FFE202020202FA4222422642AA832282510249248AA50468082 +70D6:084008487F4408440840FFFE00400844294429442A28482A1412122A22464082 +70D7:10201010101013FE54205842508491F81010102210C42B082410442840C48302 +70D8:108810881088108855FE588850889088108813FE100028882484450442028402 +70D9:1080108010F815085B1054A0504090A01118120615F829082508450841F88108 +70DA:102010201050108855045A0251FC9000100011FC110429042504450441FC8104 +70DB:10201020102011FC552459245124912411FC112410202828242445FE40828000 +70DC:100013FE1000140059FC5104510491FC1104110411FC29042400400043FE8000 +70DD:00001FE0004000807D040588095011202118450682001FF00000488844448444 +70DE:10881088108814885BE85088518C91CA12AA1288148828882488448840888088 +70DF:100013FE120216225A22522253FE922212221252124A2A8A2702420243FE8202 +70E0:1040104017FE1080550059FC5304950419FC1104110429FC2504450441148108 +70E1:010011081108229004401830E44E04403FF804400440FFFE0000082010102008 +70E2:1040102013FE12025400583853C090401040107C13C0284024424442403E8000 +70E3:10401040104013FE54805890509091121152115412902A282428444440848102 +70E4:1040104411F4104854505BFE5040908011FE1240148028FC2404440440288010 +70E5:100011FE11201120552059FC510491041104110411FC29202520452041FE8000 +70E6:100013FE1020104055FC59045104912411241124112429442450448841048204 +70E7:2080208020BC23C0A850B024A0D4A30C200027FE2090209051124912420E8400 +70E8:10901094111415185B1055325152910E1120102013FE28202420442040208020 +70E9:10201020105014885904520250F89000100013FE102028402488410443FE8102 +70EA:108810481050100055FC58205020902013FE1020105028502488448841048202 +70EB:23F0102080C043FC11242124E2442484292820100100111022A004401830E00E +70EC:100011FC1104150459FC511051109108110412621410280024E0441840048000 +70ED:104010401040FDF8104810481CC83048D0AA10AA510622020000488844448444 +70EE:7F84082410243F2451240A24040408043014C10811101120228004401830E00E +70EF:11841068103014C85B04504053FE90A0112013FC152429242534412840208020 +70F0:1008103C11C01004554458A8500091F81010102013FE28202420442040A08040 +70F1:100013FE120216525A8A5306520292FA128A128A128A2AFA268A4202420A8204 +70F2:080C08F07E8008800EFE7888088829081208010011101120228004401830E00E +70F3:1028102413FE1020542059FC5124912411FC1124112429FC252445244124810C +70F4:100011FE100014925924524851249092100011FE102028202420442043FE8000 +70F5:1088108813FE10885400588050FC910412041484104428442404440440288010 +70F6:1000100613B8148858885108513E9388108812881288293E25004280447E8800 +70F7:1040102013FE16025C0451F85000900013FE10901090289025124112420E8400 +70F8:1080108010FE15005AFC508450A4909413FE10841124291425FE440440288010 +70F9:0100FFFE00001FF010101FF000003FF000600180010005000200488844448444 +70FA:1040102011FC1104550459FC5104910411FC1120112229142508454441828100 +70FB:1004100E13B8148858885128512E93A810A812A812A8293E25004280447E8800 +70FC:100013FE1040148059445224506890B011301228106828A42522422040A08040 +70FD:1040104010FC10885550582050D8932610F8102010F8282027FE442040208020 +70FE:01000910092012C0043019086914091012A004401830610C1FF0010001007FFC +70FF:100213C2124416485B5052C2524292441FE8125012422A4226444248445088E0 +7100:10001050104810845524582050509088110612F8108828882488448840F88088 +7101:0080008078FC49044A48484078B0030C0C02010011101120228004401830E00E +7102:1040104024FE6488A55024202450208801041110111022A0044008203018C006 +7103:1020102011FC10205420582053FE90481048114C114A2A4A2488448841288210 +7104:00003FF80408FFFE04083FF808001FF8280848088FF808080000488844448444 +7105:10201120112011FC55205A20502093FE1000100011FC29042504450441FC8104 +7106:100010FC1084108454FC580051FE9102110211FE1102290225FE4502410A8104 +7107:1020112410A410A8542059FC5104910411FC1104110429FC2504450441148108 +7108:1000087C3E442244227C3E4022422042413E9110111022A0044008203018C006 +7109:00007FFC010011F811001100FFFE08000FF810001FFC00042924249440280010 +710A:100011FC110411FC550459FC5000900011FC102010202BFE2420442040208020 +710B:2420242024203DFC0420FC20242024F84400010011101120228004401830E00E +710C:10401040108815045BFE500250889144124210F811882A502420405041888606 +710D:11081088109015FC5824502451FC9120112011FE106228A2252A422444208020 +710E:1000100C11F0FD00110011FE1D10F11011101210521024100000488844448444 +710F:00003FF0002000400180793C4944492849107928014405000200488844448444 +7110:100013FE1040104055FC5884508493FE1000100011FC29042504450441FC8104 +7111:100013FE122216225A2253FE52229262127212AA13222A222622420243FE8202 +7112:100010FC108410845484588450FC9000100011FE110229022502450241FE8102 +7113:10201020105014885944522250F890081010102011FC29042504450441FC8104 +7114:10401040107C148459085210513E912211221122113E292225224522413E8122 +7115:1080108010F815085A1055FC512491241124112413FE28502450448841048602 +7116:110010BE128216025A2252125252924212CA135612522A3226024202420A8204 +7117:100011FC1104150459FC5100510091FE1102117A114A294A267A420244148008 +7118:020002007FFC02003FF80400FFFE08201FFC20204420822002A0004024884244 +7119:1040102011FC100055085890500093FE1000100011FC29042504450441FC8104 +711A:082008207EFC08301C682AA4C922082009201110111022A0044008203018C006 +711B:7C7C44447C7C44447D7C4104410449244924494451844244422444244804500C +711C:100011FC1104110455FC5904510491FC1000111211D42918251045524192810E +711D:101C13E0122013FE56205A92530A920611FC1104110429FC2504450441FC8104 +711E:1040102013FE100055FC590451FC900011FC100810102BFE2420442040A08040 +711F:10881088108817FE5888508857FE900011FC1104110429FC2504450441FC8104 +7120:1040102013FE100054885888515492221000102013FE28202420442040208020 +7121:100010001FFC2AA04AA00AA07FFC0AA00AA00AA07FFC00002488224442448004 +7122:10201010101015FE5902525450889104100010FC102028202420442041FE8000 +7123:00007F0022FC3E4422443E44222822282F10F228424402820000488844448444 +7124:010000803FFE2210221025FE2C903450441044508520111022A004401830E00E +7125:1040102013FE12025504590051DE925212521352149A2894251045124212840E +7126:090008801FFC108030805FF8908010801FF8108010801FFC1000488844448444 +7127:10901090110815485A445492510893FC1044102010A42A82268A428A44788000 +7128:100013FC120412F456045AF4500091F8110811F8110829F82508450841288110 +7129:100013DE125216525A5253DE52529252125213DE12522A5226524252455288A6 +712A:1040102013FE120254885904520291FC100411FC110029FC2404440440288010 +712B:1088108813FE108854A8582051FC912411241154114C29842504450441148108 +712C:100011F81108150859F85108510891F8108011FC125428942524424440948108 +712D:08202AA42CA84920145022887FFE400280040FE00820082008221022201EC000 +712E:201020902710243EAC22B444A790A51025102510252825285528494449449082 +712F:10201020103E142059FC510451FC910411FC112410202BFE2420442040208020 +7130:10401040107C148459085200502091CE1102110211CE29022502450241FE8102 +7131:010011081108229004401830E00E08100A102A542C5448981410222842448082 +7132:2080204027FE2120A920B23CA244A664229423482248223052204A5042888306 +7133:10A01090108015FE5910531055FC9110111011FC11102910251045FE41008100 +7134:1040102013FE108055045BFE500291FC110411FC110429FC2504450441148108 +7135:100013FE1202168A5A5253FE5222922212AA12AA12AA2AFA26024202420A8204 +7136:102010281E24222033FE4A20A450145008881088210442020000488844448444 +7137:1040108011FC1124552459FC5124914411FC109011102BFE2410441040108010 +7138:00003E7C224422443E7C224422443E7C01001110111022A0044008203018C006 +7139:100013FE1202168A5A5253FE5242922213FE128212822A8226FA4202420A8204 +713A:100011FC110411FC550459FC5000902811C8108810882BFE2488448841088208 +713B:11F81108110815F85908510851F8900013FC120412042BFC2604420443FC8204 +713C:1020102011FC102054A8588853FE9088100013FE1090289025124512420E8400 +713D:00007CFC448444FC7C8444FC44847C84011402080100111022A004401830E00E +713E:10201020105014885944522251F890081050102010A42A82268A428A44788000 +713F:1040102013FE16205AFC5224522493FE1224122412FC2A202650445044888906 +7140:100013FE120216025BFE521052929292129212FE12102A922692449244FE8802 +7141:1088108813FE108854F8588850F89088108813FE110029482584450041FE8000 +7142:1088108813FE108854F8582051FC9124112411FC10202BFE2420442040208020 +7143:1020102013FE105054885B2651FC9020102013FE1000282025FC4420402083FE +7144:1008103C11E014205BFE502051FC912411FC112411FC282025FC442043FE8000 +7145:102011DC11141114551459D45126910011DC1114111429D42708450841148122 +7146:100013DE124216425A4253DE5200923E13D2121212142BD42608421442248242 +7147:100013FE1222102055FE582051FC912411FC112411FC282027FE442040208020 +7148:200027FC24042434ADC4B444A5F4A554255425F42444245455F44C9448069002 +7149:1020102013FE102055FC592451AC9174112411FC1020287024A8452442228020 +714A:1040102013FE1202540459FC500091FC110411FC110429FC2504440043FE8000 +714B:100011FC110415FC590451FC5020912011FE1220102029FC2420402043FE8000 +714C:1020104011FC150459FC510451FC900013FE1020102029FC2420402043FE8000 +714D:208821C827082108A92AB12AA7ACA14823082388255425145914492441248142 +714E:10100820FFFE00003E4822483E4822483E0822082A2824100000488844448444 +714F:100013FE100015FC5904510451FC900013FE122212222BFE2622422243FE8202 +7150:1088108813FE108854A8582051FC91241124112413FE28202450448841048202 +7151:01081FD001207FFC02000FF03810CFF008100FF00100111022A004401830E00E +7152:2040204021FC2084ABFEB000A1FCA10421FC202023FE202052204BFE40208020 +7153:102011241124112455FC580053FE9020104011FC11542954255445544154810C +7154:1020522054209020283C44208220102010FC5284548490842884248442FC8084 +7155:00007F7C444454445744517C51405740544244427F3E00002488224442448004 +7156:101E13E010441524588851FC5040904013FE108010FC29442528421040688186 +7157:100013FE1020104055FC5954515491541154112C10202BFE2450448841048202 +7158:20142012201027FEAC10B410A5D0A412241225D42554254855DA4C2A48469082 +7159:100013FE105014505BFE52525252925213FE102010202BFE2420402047FE8000 +715A:00007CFE448044FC7C8444FC44807CFE01001110111022A0044008203018C006 +715B:00003EF822883EF822883EF822883EF801001110111022A0044008203018C006 +715C:100011FC110415FC590451FC51049040102013FE100029042488400047FE8000 +715D:100013FC122416245BFC520052FC9284128412FC12842AFC2684428444FC8884 +715E:202020203C40447E88847F44024402287E2802100228FE440082488844448444 +715F:100013FE122213FE56225BFE500091FC110411FC110429FC2504450441148108 +7160:10481148114817FE594851485178910011FE102013FE287024A8412446228020 +7161:20102010207C2714A9FEB114A27CA210277C211021FE251052104B0044FE8800 +7162:08202AA44D28145022887FFE400280041FE0042004203FA004200414040C0404 +7163:100011FC104814305BFE5052509491101230102013FE287024A8412446228020 +7164:1088108813FE1088548858F85088908810F8102013FE287024A8452442228020 +7165:2080208020F82108AA10B5FCA104A154218C2124202023FE5050488841048602 +7166:0100790049FC4A044C0479E44924492449E44804782800102488224442448004 +7167:00007DFC44444444444444947D0844FC4484448444847CFC0000488844448444 +7168:100011FC1124112455FC5924512491FC100013FE112029222514454841848102 +7169:100013FE1020144059FC5104510491FC110411FC1104290425FC440040888104 +716A:11081088109017FE5890509053FC92941294130C12042BFC2604420443FC8204 +716B:2108209020002BFEB080A184A244A4A82130227024A8212852244C2248A08040 +716C:200023F822082BF8B208A3F8A000A7FE220023FC2494292452444C8449288210 +716D:2484490424A400247FA408241F24612412240C043014C0080000488844448444 +716E:020002083FD00220FFFE01000FF03810CFF0081008100FF00000488844448444 +716F:1110111211D4111855525992512E904011FC1104110429FC2504450441FC8104 +7170:100010F8108814885888508850F89088100013DE12522A522652425243DE8252 +7171:100011FC1104150459E45124512493FE120212FA128A2A8A26FA4202420A8204 +7172:08000BF8120833F8504097FC11501248144410400100111022A004401830E00E +7173:1100113C112417A45924513C512493A412A412BC12A42AA427A4444440548088 +7174:100011F81108150859F85108510891F8100013FC12942A942694429447FE8000 +7175:1020102013FE1420582053FE528A925212FA122212222AFA26224222422A8204 +7176:100011FC1104150459FC5104510491FC100013FE10202920253C412042A0847E +7177:2080204027FE2000ABF8B208A3F8A00027FE240229F4211051104A124412880E +7178:1040102011FE1102550259FE5100910011FE11AA12AA2AFE24AA44AA40A28086 +7179:1088108813FE148859FC508853FE902011FC112411FC292427FE410441148108 +717A:200024F822882288A8F8B088AE88A2F822A22294228822A852C44A84450088FE +717B:1020101013FE16205AFC522453FE922412FC122012FC2A842684448444FC8884 +717C:2080208021FC2A44B154A1F4A084A128229021FC2244255451F4488449288210 +717D:1020101011FE1502590251FE510091EE112211AA11662922256642AA42228466 +717E:100011FC1124152459FC51245154918C110411FC1040282024A4428A428A8478 +717F:1028102413FE102055FC592451FC912411FC112410082BFE2488444840488018 +7180:100011FC110411FC550459FC5020912410A8102013FE2890249045124212840E +7181:104011FC1044109455085BDE514A914A129411FC110429FC250445FC4104810C +7182:2100210021FC2A00B5F8A000A3F8A08822A821C827F8208A51CA4EAA48868082 +7183:00407EFC15440838FE441AA22CFC4844A89411080100111022A004401830E00E +7184:1020104011FC150459FC510451FC910411FC1040102028A4268A428A44788000 +7185:100013F8124812A857185A0853F89000100017FC14A42CA424A444A44FFE8000 +7186:1020102011FC1420582053FE5080910413FE100213FC2A942694429447FE8000 +7187:1040102013FE140059FC510451FC900013FE120212FA2A8A26FA4202420A8204 +7188:00002FBC2A242A242FA428BC28A02FA02A224A224F9E80002488224442448004 +7189:100010FC1084108454FC580051FE910211FE110211FE290225FE444840848102 +718A:1080249842E07E8400847E7C42807E9842E07E844284467C0000488844448444 +718B:108024987EE000847E7C42007E9842E07E844284467C0100111022A00C60701C +718C:100013DE125217DE5A5253DE520292221222122212522A4A268A4202420A8204 +718D:1020101011FE1102540058FC5084908410FC100011FE29022502450241FE8102 +718E:1008103C13C010045644592851FC9220102013FE102029242524452441FC8004 +718F:00F83F000100FFFE01003FF8292825483FF801003FF80100FFFE488844448444 +7190:100013FE1202100055FC590451FC910411FC104010202BFE2400448841048202 +7191:10881050100015FE585051FC505493FE105411FC105028D82554425240508050 +7192:08202AA42CA84920145022887FFE400281041110111022A0044008203018C006 +7193:2080210023F82208AA08B3F8A200A3FE220023FC200425545554480440288010 +7194:1040102013FE160258505088512490501088110412FA28882488448840F88088 +7195:100011FC102014205BFE500051FC910411FC110411FC290425FC448841048202 +7196:101E11E01022111254945880502091CE1102110211CE29022502450241FE8102 +7197:2040204020A02990B248A7FEAA08A3F8220823F8220023F855084D0849F88108 +7198:104013BE121216925A5252AA5324904013FE122212222BFE2622422243FE8202 +7199:00007F7C444444445F44517C51405F40444244427FBE00002488224442448004 +719A:100011FC112415FC592451FC50A890A813FE10A810A829FC242043FE40208020 +719B:100013FE105011FC5554595451FC900011FC100013FE282024A8452442A28040 +719C:1020104011FC1524597C518C51549124115411FC1020281025544542414A8238 +719D:1040102013FE125056505BFE5252925213FE120012922AD42698449244D2888E +719E:100013DC129417D45A5453C85288929413E21000102029FC2420402043FE8000 +719F:1040FE4000407DF844487C4800C87C4808AAFEAA110652022000488844448444 +71A0:100013DE10421252554A5A525042902011FC1104110429FC2504450441FC8104 +71A1:204023F822482FFEAA48B3F8A040A3F8224823F820802FFE511048E043188C04 +71A2:1020147C12841548583050CE5610927C1210127C12102AFE2610421045FE8800 +71A3:1020122213FE1090548859FE5310951011FE1110111029FE2510451041FE8100 +71A4:100013DE1042114A54C6594A525290021040102011FC280025084488409083FE +71A5:20FE240422282210A8FEB092AE92A2FE229222FE2292229252964D0048FE8000 +71A6:102011241122152A5A325060519097FE112011FC112029FC2520452041FE8100 +71A7:11102110CAA814443240D27C154014FE0800010011101120228004401830E00E +71A8:3F0821083F7E20082F4820285FA8440895282C900100111022A004401830E00E +71A9:1040102013FC16045BFC520052F8928812F8120013FC2B2425FC4502490280FE +71AA:20102190261E2222AA54B208AF90A2642208271E2AA2224252144A0842108260 +71AB:1040102013FE120056485A4853FE92481248124812782A002554452A4A2A9000 +71AC:082008207F20087E7E4408A4FF2810101E282244468280002488224442448004 +71AD:1010FEFE10107C7C1010FEFE10103FF800081FF800083FF8111022A00C60701C +71AE:200027BC208424A4AA94B4A4A050A188262620C0231020645388483040C08700 +71AF:1088108813FE108854F8582051FC912411FC102011FC282027FE445040888306 +71B0:100013FE1200167C5A445244527C920012EE12AA12AA2AAA26EE420043FE8000 +71B1:104010407C4010F8FE48444892C87C4810AA1CAAE10642020000488844448444 +71B2:400044FE7810422042FC3E84008410FC528452FC5484908428FC244844848102 +71B3:100011F8110811F8550859F8500093FC129413FC100029F82490446041988606 +71B4:20402444244427FCA800B7FCA404A7FC240427FC2000242457A84C3245A2861E +71B5:1040102013FE1488585053FE5252928A130612FA128A2A8A26FA4202420A8204 +71B6:200023F8220823F8AA08B3F8A000AFFE248027BC2494279454D44F88409480A2 +71B7:11041088100013FE56225AAA5272922213FE100011FC290425FC450441FC8104 +71B8:200027BC21082528AFBCB318A5AAA946200023F82208220853F84A08420883F8 +71B9:01007FFC01003FF800003FF820083FF80820FFFE00003FF820083FF824884244 +71BA:102013FE102011FC540059FC510491FC108813FE100029FC2504450441FC8104 +71BB:204020A021182EE6B000A3F8A208A3F8200027BC208424A452944CA44A948108 +71BC:200027FC244427FCAC44B7FCA110A11027FC211021102FFE5000491042088404 +71BD:102011FC102417FE582451FC502092AA13AE122213FE2A2227AE42AA42AA8422 +71BE:1110109413D214125A50519057FE901013D2125212542BD4264A424A43D68022 +71BF:1088108811FC108854885BFE502091FC112411FC112429FC2400448841048202 +71C0:100013DE1252125257DE580051FC912411FC112411FC282027FE442040208020 +71C1:108813FE1088100055FC58A850A893FE10A810A811FC282027FE442040208020 +71C2:100013FE105013FE56525BFE500091FC110411FC110429FC242047FE40208020 +71C3:1110111411D216505A7E5550509092A81128114412442C82240842A442528452 +71C4:101010523E5422904428804410826610425242546698421042287E2842440082 +71C5:081008527E5408900828FF4424824210895208547E98081008280F28F8444082 +71C6:101C11E0104017FE5888510452FA948810F8100013FE2A0226FA428A42FA8206 +71C7:1088105013FE105055FC5954518C9174110411FC10082BFE2508448840A88010 +71C8:202027A420A82A92B114A208A5F4A80223F82208220823F8520849104FFE8000 +71C9:2208210827C82010AF9EB494A7A4A01427942094211421C85708491445248242 +71CA:1108211002E00C1870040010525294942828C4C401007FFC05401930E10E0100 +71CB:1090108811FE15105B1055FE5110911011FE1110111029FE250042A442528452 +71CC:102011FC102014885BFE508851FC910411FC110411FC290425FC448841048202 +71CD:22402242225C27F0AA50B3D0A25EA3D42254225427F4201452944C6448248044 +71CE:2040204027FC20A0AD14B208A7FCAA0A23F8220823F8204052484C4449448080 +71CF:100013FC104814305BFE505250949350102013FE12522A8A2776425242728206 +71D0:20402248215027FCA950B248A444A210239024BC2A902150517E4A1042108410 +71D1:102011FC108814505BFE500051FC912411FC112411FC282025FC442043FE8000 +71D2:1020102011FC14205BFE5108539C91081188163E10002BFE249044904112820E +71D3:24482288F93E22886458729CA92A22882448010011101120228004401830E00E +71D4:103C13E0112410A855FE58A85124920211FC1124112429FC2524452441FC8104 +71D5:0440FFFE0440044017D01012F01C17D014503452D7D2100E0000488844448444 +71D6:100013FC100413FC54045BFC500093BC112417BC10082BFE2508448840A88010 +71D7:279E2492279E2492AF9EB402A4F2A49224F2249224F2249254924D3244028406 +71D8:100013DE125217DE5A5253DE5242922212FA121212522A2226524282420A8204 +71D9:23F8120893F8420843F810002FFEE20027FC292422540588111022A00C60701C +71DA:1010525254549090282844448282101010525254549890102828242842448082 +71DB:0000FEFE12907EFC42847EFC1290FEFE01001110111022A0044008203018C006 +71DC:2000279E2492279EAC92B79EA442A422240A25462542255256324C02440A8404 +71DD:100011FC110415FC590451FC502093FE100011FC110429FC2420452442228060 +71DE:142012203F3E24426494BF1024103F10242824283F4420820000488844448444 +71DF:08202AA44D28145022887FFE40029FF410101FF000003FF8200820083FF82008 +71E0:2080210027FC2444AD54B444A7FCA4E425542404204027FE50A0491042088C06 +71E1:100013FE125213FE542059FC502093FE1088105011FC282027FE442040208020 +71E2:0A803138228838382288393822887FFE41029114111022A0044008203018C006 +71E3:102013FE100011FC5504597451549174110411FC100828F0242047FE40A88326 +71E4:1088108813FE148859FC512451FC912411FC102013FE2A22262A42FA420A8206 +71E5:10F81088108814F8580051DC5154915411DC102013FE287024A8412442228020 +71E6:208020DC22842BD4B448AA94A324AC402248215027FC20E051504A484C468040 +71E7:104412241128147E58105028534A911C1128114C111A292A2548411042FE8400 +71E8:220821102FFE2840B7FCA040AFFEA054279221102FFE211051D44F0A49168322 +71E9:2108220827C82450AFDEB464A7D4A214211427D4221423C852484C54455488A2 +71EA:108813FE108815005BFC555450D49324105410941348282024A4428A428A8478 +71EB:102013FE1288125057FE5A5052FC925413FE125412FC2A5026D8455446528850 +71EC:210026DC24542454AED4B454A466A7C0201C201427D42114510849C847148222 +71ED:200023F822A82AA8B3F8A100A3FCA48423E422A422A423E450944FF448148008 +71EE:210827C820086B9AB02C2388200853944A928BA200003FF0082004C00780F87E +71EF:100011FC102013FE562259AC502091AC105010C8132628F8240844D040208010 +71F0:203C23C020442224A908B7FEA442A2A4228A247A208020F851084A904060879E +71F1:1040102011FC1488585053FE500091FC110411FC110429FC24204294428A847A +71F2:104013FC1044109455085BDE514A92D611FC110411FC290425FC450441FC8088 +71F3:200027BE24922492ACAAB7A4A4C0A4BE24A224A227BE24A250004AA442528452 +71F4:204020A023182DF6B000A7FCA554A4E427FC200023F8220853F84A084BF88208 +71F5:10101410127C141058FE5044562892FE1210127C12102AFE2610421045FE8800 +71F6:109013FC129417FC5A9453FC500093FC120012F812002BFE2520451445488986 +71F7:102013FE100015FC5904517451549174110411FC100029FC240043FE41248262 +71F8:100011FC102013FE562259AC502091AC100013FE102029FC255445544154810C +71F9:FEFE202050509A9A2C2C48489C9C2A2AC8C818180100111022A004401830E00E +71FA:102013FE100014F8588850F8500093FE1202127212522A76242043FE40A88326 +71FB:101C11E0102013FE542059FC51AC917411FC102011FC282027FE44004154822A +71FC:204023F8204827FEA848B3F8A040A7FE200022A4245223F852A84AA84FFE8000 +71FD:204027FC204023FCA800B7FEA002A3F8204027FE200027FE50084FFE44A88798 +71FE:01007FFC01003FF80000FFFE00023FF00100FFFE00107DFC44907C3024884244 +71FF:100013DE10421252554A5A525090910813FE151011FE291025FE451041FE8100 +7200:21102110211027BCA910B110AFFEA2A822A826EC2AAA22AA52A84DA844488898 +7201:100813E8128817EE5A2853F4528293E2100011FC115429542554415447FE8000 +7202:2FEC48244BA4682C4BA46AAC4BA44824FFFE810211101120228004401830E00E +7203:108812AA12DC148859545222500093FE1222102013FE287024A8412446228020 +7204:100013FE124817FE5A4852FC52A492FC12A412FC12202BFE272A457A450A8906 +7205:11FC112411AC152459FC502051FC902013FE1154122A282025FC402043FE8000 +7206:11FC110411FC150459FC508853FE908817FE108811242AAA247040A841248060 +7207:0820FFFE082010407C4011F8FE4844C892487CAA10AA1D06E202488844448444 +7208:2020203E202027FEAC22B5F8A422A5FE252425FC252425FC58404AA4528A847A +7209:11241248112414005BFC52945264929413FC124813682A48276A424A42468362 +720A:2080204027FC24A0AFFCB4A4A7FCA400252425A8253025A4551C48004AA49452 +720B:21C82708210827C8A93EB7CAA54AA7CA254A27CA210A27CA510A4FEA4AAA9156 +720C:2040202027FE2488ADFCB488A7FEA42025FC252425FC252455FC4C0044888904 +720D:244424E428A82AAAAEEEB4A4AAAAAEEE224220402FFE20E051504A484C468040 +720E:1040102013FE122255FC5850528A91FC128A10F8108828F82420452442A28040 +720F:200027FE24442598AC88B7DEA488A5DC26AA248824202520553C4920492097FE +7210:1040107C104013FC56445BF0524492FC12A812F812A82AF8260045FC45548BFE +7211:1088108813FE14A8589051FE512093FC152011FC112029FE250042A442528452 +7212:101010101EFE221054AAA8441082287CCA442A7C2C44487C1410125422924030 +7213:13DE125213DE16525BDE5242527A928A131212DA128A2ADA268A42FA420A8204 +7214:211027FC204023F8A840B7FCA000A3D4211227FE23502534538C488A42968102 +7215:210827C820086B9AB02C2388200853944A928BA20100111022A004401830E00E +7216:2210211027DE2010AC5EB282A7DEA01027DE245027DE245057DE4C50445284CE +7217:11FC110411FC150459FC508853FE908811FC10A813FE28A825FC442043FE8020 +7218:108010DE128213D454485AB4514A96A411FA128810F8288824FA449440A880C4 +7219:102013FE100015DC595451DC508893FE108813FE10882BFE2494418842A480C2 +721A:204020A021102208ADF6B000AEEEAAAA2EEE20002FFE29225FFE4922492A8804 +721B:13DE125213DE16525BDE522252FA922212FA12AA12FA2AAA26FA427242AA8226 +721C:249222942FFE2910B7FCA040A3F8A0402FFE248027BC249457944CC84F9480A2 +721D:101E13E0112214945BFE525253FE900413C4127E13C42A5427CC428442D48348 +721E:2040204023F82248ABF8B044A7FCA00422082FBE2AAA2FBE52084A8A4FBE8082 +721F:208823FE208823DEAA52B3DEA0A0A09021FE212023FC252051FC492041FE8100 +7220:27BC24A427BC24A4AFBCB4A4A7BCA12023FE222027FC2A2053FC4A2043FE8200 +7221:108813FE108811FC552459FC512493FE122A12FA122629FC252445FC402283FE +7222:00803FFE24103F7C26382D54341221202F3C2120273821202F3C41205244A122 +7223:2248215027FC2404A9F0B110A7FCA55424E427FC204027FC50404FFE42A48452 +7224:211027FE211027BCACA4B7BCA4A4A7BC244427FC255425F454444CE445548448 +7225:13FE120213FE16925A54529252FE92AA12FE132212FA2AAA24FA442249FA8004 +7226:2790251E27A82484AFBEB52AA7BEA00023F8220823F8220853F848A04124861C +7227:27FC20402FFE2842AB58B040A358A0002EEE2AAA2EEE20005FFE4A4845548FFE +7228:2FEC48246BAC48246BAC4AA4FFFE88227EFC2C684AA4FFFE11102928C6C61830 +7229:228822E82F5E22ECAF5ABAE8A208AFFE29423494255827F252044BE8420283E4 +722A:001000F81F201220122012201220122012201210121022102208420842048002 +722B:00000008007C07807A1021101120100000000000000000000000000000000000 +722C:0E00740055FC55245524552455FC550055005502550252FE5200510090FE1000 +722D:000801FC7E10221011203FF801080108FFFE010801083FF80108010005000200 +722E:024007403A7C2A842B742A542A542A742A482942294228BE28404830480E8800 +722F:000801FC7E102210112001003FF8210821083FF821082108FFFE200820282010 +7230:000801FC7E10221011203FF8020002007FFC04000FE01420224041808660381C +7231:000801FC7E10221011207FFE420282047FF8040007F00A10112020C043301C0E +7232:00FC7F00121009201FF0101010101FF8100810081FFE20022AA2495251548008 +7233:00F83F2009401FE010201FF010101FFC20042AA4400C9FE00040018005000200 +7234:0004FF0E8D748B54FF548954E954A954EB548554E5548B549154FF9200920100 +7235:00FC7F00220811107FFC44447FFC00087E0842FE7E0842487E28480874284210 +7236:044008201010200840240820082004400440028001000280044008203018C006 +7237:044008201850248803000CC03030C00E1FF00210021002100250022002000200 +7238:044008201850248803000CC03030C00E1FF0111011101FF01010100410040FFC +7239:044008201850248803000CC03230C7CE1A4001A01E7801880E90006003803C00 +723A:084010202850448803001CE0E01E00007F7822483E5022483E4423D4FE480240 +723B:00081810066001800660181860040020082004400280010002800C403030C00E +723C:040045F829081108290845F881080508450829F8110829084508810807FE0000 +723D:010001007FFC01002928111029280100292811102AA80280044008203018C006 +723E:00007FFC21084104BFFA21083558292835582108355829283558210821282010 +723F:00100810081008100FF00010001000107FF00810081008101010101020104010 +7240:042024202420242025FE3C2004700470FCA824A8252425242622442044208420 +7241:0400240025FE240824083DE805280528FD28252825E825282408440844288410 +7242:048424442448240025FE3C20042004FCFC20242025FE24202420442044208420 +7243:04482548254827FE25483D4805780500FDFE242027FE247024A8452446228420 +7244:042024202450244824A43DFE068404FCFC8424FC248024FC25444544467C8444 +7245:102057FE542055FC542477FE142415FCF42055FC552455FC552455FC5524892C +7246:082028202BFE292429243AAA0FFE0800F9FC2904297429542974490449FC8904 +7247:004010401040104010401FFC1000100010001FE0102010201020202020204020 +7248:0808481C49E0490049007DFC41444144794449284928491049104A284A448C82 +7249:04202420252424A424A83E2021FC20203C20242027FE24202420442044208420 +724A:040025FC2444244424443E44209420883D0024FC248424842484448444FC8484 +724B:04482444245E25E024283E12206A21963C48245E25E0242424284412446A8586 +724C:0840488049FC492449247DFC4124414479FC489049104BFE4810481048108810 +724D:0820482048FC482048207DFE4002409478504890485049FE4828484448828902 +724E:0880488048FC49544AD47CB4412C424478944908484048A44AAA4A8A4C788800 +724F:08204850488849044AFA7C0041E2412A792A49EA492A492A49EA4922492A8964 +7250:0808483C49E0482048207DFE402040A0792C4924492449AC4924492449FC8904 +7251:0840482049FE490249027DFE4100410079FE49AA4AAA4AFE4CAA48AA48A28886 +7252:0848494849484BFE49487D484178410079FE48204BFE487048A849244E228820 +7253:0820481049FE488448487DFE41024224781049FE4840487C4844488448948908 +7254:082848244BFE482049FC7D2441FC412479FC492448084BFE4888484848488818 +7255:0820484049FC4924497C7D8C41544124795449FC484048244AA24A8A4C888878 +7256:084048204BFE4A024BFE7E1443FE42107AFE4A924AFE4A924AFE4A924C928896 +7257:081049FE4910497C49147DFE4114417C7910497C4954497C49544A7C4A548C4C +7258:08204BFE482049FC48007FFE425243FE790449FC490449FC490449FC48888904 +7259:00003FFC004000401040104020403FFE01400240044008401040604001400080 +725A:111009207FFE40029FF410101FF000007FFC104020403FFE0240044019406080 +725B:01001100110011001FF82100410001000100FFFE010001000100010001000100 +725C:08000800480048007E004800880008000E00F800480008000800080008000800 +725D:08800880488048847E88489088A008C00E80F8804880088408840884087C0800 +725E:10401040504050407DFC5044904410441C44F084508410841104110412281410 +725F:02000400082010103FF80008010011001FF821000100FFFE0100010001000100 +7260:10201020502051207D2C5134916413A41D24F134512811221122110210FE1000 +7261:08200820482048207E20482089FC08200E20F82048200820082008200BFE0800 +7262:020001007FFE40028104110011001FF8210041000100FFFE0100010001000100 +7263:1000100051FC50447C445144914411441D44F244504410841084110412281410 +7264:10201010501050007DFE5080908010801C80F080508010801080108010FC1000 +7265:10401020502053FE7C805080908010FC1C84F084508410841104110412281410 +7266:0808083C49E048207E20483C89E008200E20F83E4BE00820082208220822081E +7267:08400840484048807EFE49088A8808880E88F850485008200850088809040A02 +7268:10801040504053FC7C00500091F011101D10F1105110111211121212120E1400 +7269:10801080508050FC7D545254905410941C94F124522410441044108411281010 +726A:08100810489048907EFE4890891008100E10F9FE481008100810081008100810 +726B:08500848484848407E5E49E0884008440E44F848483008220852088A0B060802 +726C:10201020502E51F07D205120912011FE1C22F06250A2112A1624102010201020 +726D:1000100053FC52947E945294929412941E94F294529C13041204120413FC1204 +726E:08A0109030BE57C0904010241014110C09001FF821000100FFFE010001000100 +726F:10201020502050207DFE5020902010201DFCF104510411041104110411FC1104 +7270:10201020502050207DFC5124912411241D24F1FC512411241124112411FC1104 +7271:1000100053FE50087C0851E8912811281D28F12851E811281008100810281010 +7272:10201020512051207DFC5120922010201C20F1FC502010201020102013FE1000 +7273:100010FC508450A47C945084908413FE1D04F1445124110411FE100410281010 +7274:1004101E51F051107D105110911011FE1D10F11051101108110A114A11A61112 +7275:010001003FF80280044008207FFE410289040FF0110001007FFC010001000100 +7276:0100111009203FF802007FFC082011102908CFF6110001007FFC010001000100 +7277:10201020505050887D04520291FC10201C20F02051FC10201020102013FE1000 +7278:1040102053FE52027C0451F8900810101C20F3FE502010201020102010A01040 +7279:10201020502051FC7C20502093FE10081C08F1FE500810881048100810281010 +727A:100017FE509050907C9053FC929412941E94F294529C13041204120413FC1204 +727B:10901088508051FE7CA050A890B010A41CA8F0B05124112A1132122212DE1400 +727C:100011FE500050927D245248912410921C00F1FE502010201020102013FE1000 +727D:01007FFC08201FC002007FFE48229FF4011011001FF821000100FFFE01000100 +727E:100013FE504050407DFC5084908413FE1C00F00051FC11041104110411FC1104 +727F:10201120512051FC7D205220902013FE1C00F00051FC11041104110411FC1104 +7280:00003FFC20043FFC2000288826B02808248027F8288020805FFE408080800080 +7281:03083C0804487F480C48164825084428051011001FF821000100FFFE01000100 +7282:0C8070FC1124FD241244388455289010010011001FF821000100FFFE01000100 +7283:1040102051FC50007D085090900013FE1C00F00051FC11041104110411FC1104 +7284:1020102051FC50507C88510493FE10081DE8F128512811E81128100810281010 +7285:100013FE5202528A7E5253FE922212221EAAF2AA52AA12FA12021202120A1204 +7286:1020102053FE50207C2051FC910411FC1D04F1FC510411FC1104110417FE1000 +7287:010009000FF0110001007FFC0100111051507C7C90901E10F0FE501010101010 +7288:1020112450A850207DFC504093FE10881D04F2FA5488108810A810921082107E +7289:1040102053FE50007DFC510491FC10001DFCF008501013FE1020102010A01040 +728A:1020102051FC50207C2053FE900210941C50F110509013FE1028104410821302 +728B:100011F8510851087DF8510891F811081DF8F108510817FE1000109011081204 +728C:100013DE524252427A4253DE9200123E1BD23212D21413D41208121412241242 +728D:10101010577C51147DFE5214927C17101D7CF51055FE12101210150018FE1000 +728E:08087E0808FEFE0808487E2808080F28F11011001FF821000100FFFE01000100 +728F:1080104053FC52047E0453FC920012001FFCF354535415FC155415541944110C +7290:10C417045124511479145784912411141B943346D53C15041104110411041104 +7291:100011FC510451FC7D0451FC910411FC1C28F02453FE10501050108811041202 +7292:1040102053FE50007DFC510491FC10001FFEF20252FA128A12FA1202120A1204 +7293:1080108051FC5244795451F4908411281A9031FCD244155411F4108411281210 +7294:1100110051FC52007DF8500093F810881AA831C8D7F8108A11CA16AA10861082 +7295:1088108853FE5088788857FE908011FC1B2435FCD12411FC112411241124110C +7296:08202AA42CA84920145022887FFE410289041FF821000100FFFE010001000100 +7297:1040102053FE52027C2451FC902011FC1C20F3FE502011FC1104110411FC1104 +7298:010000803FFE22102F7C26382B5432922040224023FC244020405FFE40408040 +7299:1040108851FC51087A5253FE905011881E2630C0D31010641388103010C01700 +729A:3F0821083F7E20082F4820285FA8440895282C9011001FF82100FFFE01000100 +729B:08203E7E08A47F281C102A2849443FFE2480248027F8288020805FFC40808080 +729C:1108108853C850107BDE526493D410141BD43054D09410E81388109412941122 +729D:102011FC508850507DFE500091FC11241DFCF12451FC102011FC102013FE1000 +729E:101811E0504053FE7C885174925210701C00F1FC51041174115411741104110C +729F:7CF8048804F87C2041FC7D2405FC04282BFC100411001FF82100FFFE01000100 +72A0:1104108853FE50207DFC502093FE10541D92F09053FE109010D4138A109611A2 +72A1:100013FE524853FE7E4852FC92A412FC1EA4F2FC522013FE132A157A150A1906 +72A2:102013FE502051FC7C0053FE925213FE1D04F1FC510411FC110411FC10881104 +72A3:11241248512450007BFC5294926412941BFC3248D3681248136A124A12461362 +72A4:100013FC529452947BFC5110925213DC181233CED24013D2125C13D0125212CE +72A5:1040102053FE52507BFE525293FE12001A9432D8D29012D2128E140015541A2A +72A6:13F8120853F852087BF8511097FC11101FFE3110D248155410E01150124810C0 +72A7:111017FC504053F8784057FC900013D4191237FED3501534138C108A12961102 +72A8:081024483F7E64C8BF7E24483F7E24483F7E204011001FF82100FFFE01000100 +72A9:7C4011FCFD2439FC5524FDFC246818A2651E11001FF821000100FFFE01000100 +72AA:211027FEA040A2EEFAAAABEAAAAE2AE83BAAECE6228825F42290206021982606 +72AB:51184B947C3ED3A87C7E53A87C3E53A87EBE43A011001FF82100FFFE01000100 +72AC:01000120011001100100FFFE010001000280028004400440082010102008C006 +72AD:0000440028001000280048008800080018002800480088000800080050002000 +72AE:01100108010801007FFE0200040007F80A080A08111020A0404080A003180C06 +72AF:0000440029F81108290849088908090819282910490089020902090250FE2000 +72B0:00804480288010802BF0489088900890189028904890889209120912520E2400 +72B1:004044402840104029F8484888480848194828C8484888A808AA090A52062402 +72B2:00104410281010102BFE48308830085018502890489089100A10081050502020 +72B3:00404440288010FC29044A048804090418842844484488040804080450282010 +72B4:000045FC282010202820482088200BFE18202820482088200820082050202020 +72B5:00804480290011FE2A004C0089F8080818102860488089000A020A0251FE2000 +72B6:084008480844484428402FFE08400840184028A0C8A00890091009080A040C02 +72B7:00204410281011FE2900490089000900190029004900890009000A0052002400 +72B8:000047F02810101029104910891009FC1804280448048BF40804080450282010 +72B9:00904488288810802BFE48A088A008A018A028A04920892209220A22521E2400 +72BA:00804440284013FC2800480089F00910191029104910891209120A12520E2400 +72BB:00204420282013FE2820482089FC092419242924492489340928082050202020 +72BC:00108FD0505020905110911011501190311057109110111211121112A50E4200 +72BD:000045FC28101110291049108A100BFE183028504850889009100A1050502020 +72BE:0040885050482048504097FE1040104030A050A090A0111011101208A4044802 +72BF:00404420282010002BFE48408840086018502848484488440840084050402040 +72C0:042024282424242424203DFE04200420FC202450245024502488448845048602 +72C1:004044402880108829044BFE88020890189028904890889009120912520E2400 +72C2:0000440029FC1020282048208820082019FC2820482088200820082053FE2000 +72C3:000045FC284410442844484488440BFC18842884488488840884088453FE2000 +72C4:00404440284010402944494489480A50184028A048A088900910090852042402 +72C5:0008443C29E010202820482088200BFE18202820482088200820082051FC2000 +72C6:002044202820102029FC492489240924192429FC492488200820082050202020 +72C7:00404440284010402BFE484088E008E0195029504A488C440842084050402040 +72C8:000045FC29041104292449248924092419242924492488500848088451022602 +72C9:000045FE2810101028204820886808A419222A22482088200820080053FE2000 +72CA:00003FF820083FF820083FF820083FF801100108FFFE0280044008203018C006 +72CB:000045FC2800100028004BFE88200820192829244A248A220C22082050A02040 +72CC:002044202920112029FC49208A200820182029FC482088200820082053FE2000 +72CD:0080448029FC11042A044DF489140914191429F4490489280912090250FE2000 +72CE:000045FC29241124292449FC89240924192429FC492488200820082050202020 +72CF:0080448028FE11002A204920892C09741BA42924493489280922090250FE2000 +72D0:0008883C53D02290529092901290129032905288928812C812A414D4A4924800 +72D1:0040444028A010A029104A488C2608201BF828084810891008A0084050202020 +72D2:00904490289013FC289448948BFC0A901A902BFE48928892091A091452102410 +72D3:00104410281011FE29124914891009FC194429444928892809100A2852442482 +72D4:000045FC29041104290449FC89000940194429484970894009420A42523E2400 +72D5:002089205120222052FC94A4172411243224522494A417A410C41044A0944108 +72D6:00404420282013FE2A024C048800089018902890488889080908090452042402 +72D7:00804480290011FC2A044C0489E409241924292449E489240804080450282010 +72D8:00284424282410202BFE4A208A240A241A242A284A288A900B120A2A50462082 +72D9:000045F829081108290849F889080908190829F8490889080908090857FE2000 +72DA:0000440029FC11042904490489FC09041904290449FC89040800080053FE2000 +72DB:00204420284011FC290449048904090419FC2904490489040904090451FC2104 +72DC:00204420282010202BFE48208820082019FC2904490489040904090451FC2104 +72DD:00804480288011FE29024A048C200820192829244A248A220C22082050A02040 +72DE:00404420282013FE2A024C04880008001BFE2820482088200820082050A02040 +72DF:000045FE2800100029FC4904890409FC1904290449FC89040800080053FE2000 +72E0:000045F82908110829F84908890809F819442948493089200910094851862100 +72E1:00404420282013FE2800488889040A0218882888485088500820085050882306 +72E2:0080448028F811082B104CA0884008A019182A064DF889080908090851F82108 +72E3:009044902890129229944898889009981A942C9248908890091209125212240E +72E4:00204420282013FE2820482089FC0800180029FC490489040904090451FC2104 +72E5:0080448029FC11042A0449E48924092419E42924492489E40904080450282010 +72E6:00008BF852A822A852A89FFE12A812A832A85FFE92A812A812A812A8A2084218 +72E7:0008443C29E0102028204BFE88200820182029FC490489040904090451FC2104 +72E8:00284424282410202BFE48208924092419242BA8492889100A120A2A54462082 +72E9:0040882053FE220254149010101013FE301051109090109010101010A0504020 +72EA:000045FE29021102297A49028902097A194A294A494A897A09020902510A2104 +72EB:00404440284413F4284848508FFE0840188029844A988CE008820882507E2000 +72EC:00204420282011FC292449248924092419FC29244820882808240BFE51022000 +72ED:00204420282011FC2820492488A408A818202BFE485088500888088851042202 +72EE:010089FE51102510557C9554155415543554555495541154125C1210A4104810 +72EF:0040884050A021105208940611F01000300057FC9040108011101208A7FC4204 +72F0:0080448029F0121028204BFC884408441FFE284448448BFC0844084051402080 +72F1:002094285224222450209E2012FC12203220525092D0135012881088A1044202 +72F2:00008810579020905110921012D81354325456929A92131212101210A2504620 +72F3:0040884050A02110520895F61040104037FC50409250124814441844A1404080 +72F4:02208A24522823B05220922212A2131E3040504093FC104010401040A7FE4000 +72F5:00904488288013FE28A048A888B008A418A828B04924892A09320A2252DE2400 +72F6:01844468283010C82B0448408BFE08A019202BFC4D2489240934092850202020 +72F7:000045F82908110829F848008BFC0A041A042BFC4A048A040BFC0A0452142208 +72F8:000045FC2924112429FC4924892409FC1820282049FC88200820082053FE2000 +72F9:00204420282013FE282048208924092419242AAA482088500850088851042202 +72FA:004044202BFE1000280049FC8800080019FC2800480089FC0904090451FC2104 +72FB:00404440288811042BFE4802888809441A4228F849888A500820085051882606 +72FC:0040442029FC1104290449FC8904090419FC2920492289140908094451822100 +72FD:000045FC2904110429FC4904890409FC1904290449FC88000888088451022202 +72FE:0104890E5130212057E09120113E116431A457249124112411241124A5444284 +72FF:0004440E2BB8108828884928892E0BA818A82AA84AA8893E09000A80547E2800 +7300:00108A10511021105454925212521090301051149604120812081210A22040C0 +7301:008489C457042114511491141FD41114331453949554150419041104A1144108 +7302:000045FC290411FC290449FC8800080019FC282048208BFE0820082050202020 +7303:0040884050A020A05110920815F61000308850489248115011101020A7FE4000 +7304:004044202BFE1000280049FC89040904190429FC482088A809240A2250A02040 +7305:009088905090279E509090901090139C309050909090179E10901090A0904090 +7306:044004407C7C04403C7804407C7C04400440012001107FFC028004401830E00E +7307:00204420283E102029FE4922893809E01922291E490089780A480A4A548A2906 +7308:0040448029FC1124292449FC8924094419FC289049108BFE0810081050102010 +7309:008844882BFE1088288848F88888088818F8288848888BFE0800088851042202 +730A:00009040539C22045204939C1204120433FC50909090109010901112A212440E +730B:01100108FFFE0280044008203018C00614281224FDFE10202850245044888106 +730C:081008140812FF1208102AFE2A102A105D1088281C282A284944884408840902 +730D:00408840504027FC5040924812481248355450E09150115012481444A8424040 +730E:00884488288813FE288848888FFE080019FC2904490489FC0904090451FC2104 +730F:0040882053FC2204520493FC120012FC328452FC928412FC14841484A8944088 +7310:02088908511027FC5040904013F8104030805FFE9120112012201222A422481E +7311:000045FC2904110429FC4904890409FC1800291249D48918091009525192210E +7312:00107E1442127E1242107EFE00107E1042107E2842287E28424442444A844502 +7313:00008BF85248224853F89248124813F8304057FC90E0115012481446A0404040 +7314:004044202BFE1202280049FC880008001BFE2820492889240A220C2250A02040 +7315:002097205120213E5142974414901410341057549152115211921110A5504220 +7316:01F84508290811F82908490889F808001BFC2A044A048BFC0A040A0453FC2204 +7317:0040884053FC20A05110920817FE100833C852489248124813C81008A0284010 +7318:00828882528223EA548A908A17FA108A33EA52AA92AA12AA12A212E2A08A4084 +7319:003C47C02A44112828004BF8884808481FFE284848488BF80848084051402080 +731A:00A04490288011FE29104B108DFC0910191029FC49108910091009FE51002100 +731B:000045FC2808101028204BFE882008A0184029FC495489540954095457FE2000 +731C:002044202BFE102029FC48208BFE080019FC290449FC890409FC090451142108 +731D:0080884057FC20005110911012A814443000504097FE104010401040A0404040 +731E:0040884050A02110520895F61040104037FC5040904013F812081208A3F84208 +731F:0000948452442248500093F81248124833F85248924813F8124A144AA4464802 +7320:00904490289013FC2A944A948A940BFC1A942A944A948FFE0800089051082204 +7321:00008BFE52522252525293FE1020104030FC51049288105010201040A1804600 +7322:0100891E511227D25112911E111217D23452545E945217D214521022A02A4044 +7323:000044882A5212222A524A8A8A020BFE188829444A7A88880950082050D82706 +7324:001045D428581252298C488889040AFA1820282049FE88200850088851042202 +7325:00008BF85248224853F89248124813F8300057FE9240124412281290A3084206 +7326:000097FC5404243465C4A44425F425546554A5F42444245425F42494A8065002 +7327:000045FC2904110429E4492489240BFE1A022AFA4A8A8A8A0AFA0A02520A2204 +7328:003C97C052442128500093FC1080108037FE510091F8128812501420A8D84306 +7329:00008BF8520823F8520893F81040124033FC5440904013F810401040A7FE4000 +732A:0040884453F42048505097FE1040108031F85308950811F811081108A1F84108 +732B:008844882BFE10882888480089FC09241924292449FC89240924092451FC2104 +732C:000097FC544427FC544497FC100013F8320853F8920813F812081208A2284210 +732D:010089F8520823F0501097FE10801144366850B09128166810A41122A6A04040 +732E:08100814FF92081208107F7E4110551049105D1049287F284928494445444282 +732F:004094445444244457FC90001FFE1040308057FC94A414A414A414A4A4A4440C +7330:0080449E2BEA108A29CA488A8BEA089218A628204BFE88200850088851042602 +7331:00008BF85090206057FC90A4112812203460504097FC10E011501248AC464040 +7332:000045FC290411FC290449FC888009FE1A2229224952890209FA080250142008 +7333:000097BC54842484548497BC1400140037BC5424942417A814101428A4444482 +7334:010089785108220852FE96401A40127C3290521092FE121012281228A2444282 +7335:0080884053FC2204520493FC1200120033FC5354935415FC15541554A944410C +7336:01084488289017FE289048908BFC0A941A942B0C4A048BFC0A040A0453FC2204 +7337:221012141412FF92141014FE7F1055105510632841287F28414441447F844102 +7338:00008BFC5224222453FC920012FC1284328452FC928412FC12841284A4FC4884 +7339:0040904057FC20E051509248144613F8320853F8920813F812081000A7FE4000 +733A:0008443C2BC010042A44492889FC0A2018202BFE482089240924092451FC2004 +733B:00068F78511021205244927813101224367E5A129210125412521292A2504620 +733C:002844242BFE102029FC492489FC092419FC292448088BFE0888084850482018 +733D:000047FE2A02100029FC490489FC090419FC284048208BFE0800088851042202 +733E:00008BF8520823C852489FFE180213F8320853F8920813F812081208A2284210 +733F:0040904053F8204057FE900013F81208320853F890A4112813101D48A1864100 +7340:0140965C54442444575C9444144417FC304057FC9208111010A01040A1B0460E +7341:00008BFC524023F8524093F81240124033FC50049554155415541404A0284010 +7342:000045FE29101120297C4944897C0944197C29104910895409520A9252502420 +7343:08104914491249127F1000FE7F1000107F1041287F28412822440F44F0844102 +7344:02109114511227D250109790103E17903010579094A814A814A817C4A0444082 +7345:020094FE57102510557C955417541454345457549554155C15101710A5104010 +7346:0020444029FC110429FC490489FC08401BFE288849248A220DFC082050202020 +7347:0208891057FC2040504093F81040108037FC50A091281134123C1222A422481E +7348:020889085110200057FC900011101208340453F892A812A812A812A8AFFE4000 +7349:0040884057FC204053F8908017FC1110326855C6904013F810E01158A6444040 +734A:0040884050A02190524897FE1A0813F8320853F8920013F815081508A9F84108 +734B:004045FC290411FC290449FC890409FC1820292448A8892408200BFE50202020 +734C:000045F8290811F8290849F888000BFC1A942BFC480089F80890086051982606 +734D:0080884053F8211050A097FE100013F8320853F8920813F811201122A2224C1E +734E:0440247C24A83D5004287DFE248844488418012001107FFC028004401830E00E +734F:008844882BFE1088280049FC890409FC190429FC48208BFE0850088851042202 +7350:002045FC288810502BFE480089FC090419FC290449FC88200BFE082050202020 +7351:01008902511C27D0511097D0155E17D4355457D4911417D411141124A1244144 +7352:08207F20083E7E440884FF2820103E284244872201107FFC028004401830E00E +7353:01089108510827D0511E979411241FD4321453D492541248124814D4A4244842 +7354:0020444029FC110429FC490489FC0820192428A8492488200BFE082050202020 +7355:002046222BFE1090288849FE8B100D1019FE2910491089FE0910091051FE2100 +7356:002045FC282010882BFE488889FC090419FC290449FC890409FC088851042202 +7357:00009FFE58002A286948ABEE289228846AA0AAA82BE8288828942914A9245242 +7358:082049202A3E7F4849485DA86B104928414440200110FFFE02800C603018C006 +7359:0108890855482390511E97D4156415543554575495D4154815481554A46444C2 +735A:0088448829FC108828884BFE882009FC192429FC492489FC0800088851042202 +735B:00A094A452A820A057FC911010A017FC304053F8904017FC10A01110A2084C06 +735C:0020452428A813FE28A849248A220904190429DE4A448D54089E090452042404 +735D:000045FC284810302BFE485288940B5018202BFE4A528A8A0B760A5252722206 +735E:002045FC288810502BFE480089FC092419FC292449FC882009FC082053FE2000 +735F:0020442029FC10202BFE49088B9C090819882E3E48008BFE089008905112220E +7360:0040904057FC20A05514920817FC1A0A33F8520893F8104012481444A9444080 +7361:00808B1C52042204539C9204120413FC310053FE940212AA12AA1402A0144008 +7362:00388BC0508027FE5110920815F6191031F0500097FC140415F41514A5F4440C +7363:9090491402127F1249107FFE49107F100010FFA800287F28414441447F844102 +7364:0208890857C82010579E949417A4101437945094911411C817081114A5244242 +7365:01088A0857C8245057DE946417D41214311457D4921413C812481454A55448A2 +7366:008847FE288811FC290449FC890409FC188029FE4A228D52090209FA500A2004 +7367:00008BFC5294229453FC900017FE100033FC520493FC10A211141308AD444182 +7368:000045FC2954115429FC488089FE0A4219F22952495289F2084A0BFA500A2004 +7369:0020893C512027FE5010901413FE121033F05254925412D41368144AA8964322 +736A:004088A053182DF6500097FC155414E437FC500093F8120813F81208A3F84208 +736B:0040444028A011102A084DF6880008001BB82AA84AA88BB80910091052A82444 +736C:0200939E548A290A67D2A566254027D4655EA56427C42544255E2544A44448C4 +736D:021092105F9C22246248AFBE2AA22AAA6FAAA22A272A2AAA32882214A2224242 +736E:000097FC524824446FFEA44426EC255466ECA44426EC255426EC2444A4544408 +736F:003C97C050402FFE504097FC155414E437FC504097FC10401FFE1000A5244892 +7370:0080884057FC244452A892941474100033F852A89FFE100017FC1040A1404080 +7371:004044202BFE120229FC49488A5009FC1B0429FC490489FC090409FC50882104 +7372:008847FE28A8109029FE4B2089FC092019FC292049FE89000BFC08885070238E +7373:000045FC282013FE2A2249AC882009AC18002BFE482089FC095409545154210C +7374:011097FC511027FC540493F8100017FC3080514496A8117016A81126A6A04040 +7375:01248A485124200053FC92941264129433FC524893681248136A124AA2464362 +7376:03FC884051F8210851F8910817FE144232A4528A947A108011F81288A070438E +7377:0040882057FE248855FC948817FE142035FC552495FC152415FC1400A4884904 +7378:77105514771200127F1049FE7F1049107F100028FFA800287F4441447F844102 +7379:0040887C504023FC524493F0124412FC32A852F892A812F8120015FCA5544BFE +737A:0108890857CE2112512497DE1552155E37D2511E9392155E19401114A1124122 +737B:08100F1408127F1249105EFE49107F104A105F2851285B2855445F4455849502 +737C:00009EFE5254229262FEAE9228D628BA68D6AE9222D622BA22D62292AA9A4484 +737D:004097FC500023B852A893B8111017FC311057FC91101FFE11281310AD484186 +737E:01108FFE511027BC54A497BC1140112033FE522097FC1A2013FC1220A3FE4200 +737F:000097FE504022EE62AAABEA2AAE2AE86BAAACE6228825F422902060A1984606 +7380:000097FC54A424A467FCA21022A824BE6F68A23C24A82FBC20282AA8AABE4020 +7381:07BC94A457BC200057FE94001590149E37D4556495D4155415D41568ABC85054 +7382:024097E2525C2EF06AB0AEF0201E27D46554A7D4255427D421142FE4A1244144 +7383:03DE46522BDE12522BDE48A089FE0B201DFC292049FE880009FC08885070278E +7384:020001000100FFFE02000420082010403F8011000200042008103FF810080008 +7385:101008100810FE101054105220524290FC104814100420084408FE10422000C0 +7386:101008080808FEFE1010101020204242FCFC4848101020204444FEFE42420000 +7387:020001007FFC020044442F88111022484FE400200100FFFE0100010001000100 +7388:10400840087EFE801100101C20E042A0FCA248A410A820904490FEA842C40082 +7389:00007FFC010001000100010001003FF8010001000120011001100100FFFE0000 +738A:000000007FFC010001200110011001003FF801000100010001000100FFFE0000 +738B:00007FFC010001000100010001003FF8010001000100010001000100FFFE0000 +738C:00400040FF4008400840084008407E4008400840084008420F42F042403E0000 +738D:1000100010003FFC21004100810001003FF801000100010001000100FFFE0000 +738E:00000000FEFE1010101010107C1010101010101010101E10F010401000500020 +738F:00400040FE40104011FC10447C4410441044108410841E84F104410402280410 +7390:00000020FD201120112011207D2011201120111011101E10E208440808041002 +7391:000001F0FD1011101110111011107D1011101110111011121D12E212420E0400 +7392:00000000FDFC1020102010207C2010201020102010201C20E020402003FE0000 +7393:00400040FE8010FC110412047C0411041084104410441E04F004400400280010 +7394:01040124FD241124112411247D2411241124112411241D24E124422402040404 +7395:000001FCFC201020102010207C2013FE1020102010201C20E020402000200020 +7396:00800080FC8010F8110811087D1012101020102010501C50E088410802040402 +7397:000001FCFC201020102010207C2013FE1020102010201C20E020402000A00040 +7398:00000000FDF810081008100810087DF811081100110011001D02E10240FE0000 +7399:00800080FC8010FE1080110011007DFC10041004100413F41C04E00440280010 +739A:000001F8FC101020104010807DFE10921092109211121D22E222444200940108 +739B:000003F8FC0810081108110811087DFE10021002100213FA1C02E00240140008 +739C:00100090FC901088108811247D2412221440104010881C84E10443FE01020000 +739D:00800080FC8011FC112012207C20102013FE102010201C20E020402000200020 +739E:00200020FC20102011FC10207C20102013FE102010501C50E088408801040202 +739F:00400020FC2013FE1088108810887C8810881050105010201C50E08841040602 +73A0:00200020FC501050108811047E0210881088108810881C88E088410801080208 +73A1:000001FEFE081088108810887D0811FE1018102810481E88F108420800280010 +73A2:00100090FC9010881108110412047DFA10881088108810881D08E10842280410 +73A3:00400020FE20100013FE10407C4010601050104810441E44F040404000400040 +73A4:00200020FC2013FE1020102010207DFC10201020102013FE1C20E02040200020 +73A5:000000FCFE841084108410FC7C841084108410FC10841E84F104410402140408 +73A6:00400040FC4013F8104810487C48104817FE104010A01CA0E110411002080406 +73A7:00400040FC801088110413FE7C0210901090109010901C90E1124112020E0400 +73A8:00000000FDFC1020102010207C20102011FC102010201C20E020402003FE0000 +73A9:00000000FDFC10001000100013FE7C9010901090109010901D12E112420E0400 +73AA:00200020FC5010501088114412227C20100011FC100410081C08E01040100020 +73AB:00400040FE40108010FE11087E8810881088105010501E20F050408801040202 +73AC:000001F8FD081108114811287D28110817FE110811081D08E108420802280410 +73AD:00100110FD101112111211147DD811101110111011101D12E1524192010E0000 +73AE:00400040FC4013FE1040104011FC7C40104013FE104210421C4AE04440400040 +73AF:00000000FDFE10101010102010207C6810A41122122210201C20E02040200020 +73B0:000001FCFD0411041124112411247D2411241154105010901C90E1124212040E +73B1:00200020FE501050108811047E0210F81088108810A81E90F0824082007E0000 +73B2:00200020FC5010501088112412127C1011FC1004100810881C50E02040100010 +73B3:00500054FC5210921090119E11F07E9010901090109010901C8AE08A40860082 +73B4:00480148FD481148114813FE7D4811481148114811781D00E100410001FE0000 +73B5:00880088FE88108813FE10887C881088108810F810881E88F088408800F80088 +73B6:000001FCFC201020112410A47CA8102013FE102010201C20E020402000200020 +73B7:00200020FC201020103E102010207C2011FC1104110411041D04E10441FC0104 +73B8:00800080FDFC1104120415F411147D14111411F4110411281D12E10240FE0000 +73B9:00400020FE2011FE102010207C44108411F8101010201E44F08241FE00820000 +73BA:080008001FFC2104410809201110250802007FFC01003FF801200110FFFE0000 +73BB:00200020F82023FE222222242220FBFC2284228822483A50E220445004880906 +73BC:00900090F8902290229222D4FA9822902290229022903A92E3D24E12040E0000 +73BD:00800080FD0011FC120414047DE411241124112411E41D24E004400400280010 +73BE:000001FCFD241124112411FC7D241124112411FC11241C20E020402000200020 +73BF:000001FCFE441044104410447C941088110010FC10841E84F084408400FC0084 +73C0:00200020FC4011FC1104110411047D0411FC1104110411041D04E10441FC0104 +73C1:00000000FBFC2100210021F02110F9102190225022503A10E21242920312020E +73C2:00000000FDFE1008100811E811287D281128112811E811281C08E00840280010 +73C3:00200020FC2011FC1124112411FC7D241124112413FE11041D04E10441140108 +73C4:00200020FD20112011FC112012207C20102011FC102010201C20E02043FE0000 +73C5:00200020FC2011FC112411247D2411FC1124112411241DFCE124402000200020 +73C6:00200020FC401088110413FE7C02100011FC110411041D04E104410401FC0104 +73C7:000001F8FD081108110811F87D081108110811F811081D08E108410807FE0000 +73C8:02000200FA00221E27D222522252FA522252225222523A52E452445E09521080 +73C9:000001FCFD041104110411FC11207D2011FE1120112011101D12E14A41860102 +73CA:0000F7BC24A424A424A424A4F4A42FFE24A424A424A434A4E4A445A408541088 +73CB:00000080FB1E2252225222522252FA52225222D2235A3A54E090409001100210 +73CC:00000040F8202028200820882090FA9422A222A224C23888E188428804780000 +73CD:00200020FC501088110412127C2010401188101010201C44E188401000600380 +73CE:00800080FC8010FE110211047E20102010A810A411241D22E222402000A00040 +73CF:00000000FDFC10201020102010207C2011FC1020102810241C24E02043FE0000 +73D0:00200020FC2011FC1020102010207DFE10201020104010481C84E1FE40820000 +73D1:00900088FC88108013FE10A010A07CA410A410A8112811321D22E262429E0400 +73D2:00200020FDFC102413FE10247DFC1020102011FC10201C20E3FE402000200020 +73D3:00400020FC2013FE100010887D0412021088108810501C50E020405000880306 +73D4:00400040F84027FE20802080F97C21082310251021FE3910E110411001500120 +73D5:00400040FDFC1044108410847D281210110813DE114A1D4AE14A4252035A04A4 +73D6:00200020FD2410A410A8102013FE7C9010901090109010921D12E112420E0400 +73D7:00200120FD2011FC112012207C2013FE1090109010901C90E11241120212040E +73D8:00200040FDF81108114811287D2813FE1108114811281D28E108420802280410 +73D9:00880088FC88108813FE108810887C88108817FE100010881C84E10442020402 +73DA:000001FCFD041124112411247DFC112411241154114C1D8CE104410401FC0104 +73DB:00200020FDFE1040104010FC7C84118412FC108410841CFCE084408400940088 +73DC:01040084FC88100013FE10207C2011FC1020102013FE1C20E020402000200020 +73DD:000003DEF84220422252214AF94A204220C6214A22523842E0424042014A0084 +73DE:00800080F8F82108231024A02040F8A02118220625F821083908E10801F80108 +73DF:000007F8F408240827F824882488F4E82528252826A8244A344AC88A09061202 +73E0:00200120FD2011FC112012207C2013FE107010A810A81D24E124422200200020 +73E1:0000FEFE101010107C7C10101010FEFE0100010001000280044008203018C006 +73E2:000001F8FD08110811F811087D0811F81144114811301D20E110414801860100 +73E3:00800080FDFC1104120411E47D24112411E4112411241DE4E104400400280010 +73E4:00800080FC8011FC112012207C20102017FE102011241D24E124412401FC0004 +73E5:000003FEFD081108110811F87D08110811F8110811081D1EE3E8400800080008 +73E6:00200020FC4011FE110211027D7A114A114A114A114A1D7AE1024102010A0104 +73E7:00900090F8902292219420982090F99822942492209020903912E1120212040E +73E8:00200020FC5010881104120211FC7C00100011FC110411041D04E10441FC0104 +73E9:00800080F93C220024802080217EFB082508210821083908E108410801280110 +73EA:00200020FDFC10201020102013FE7C001020102011FC10201C20E02043FE0000 +73EB:00400020FC2013FE104010887D0413FE1092109010901C90E1124112020E0400 +73EC:00280024F824202023FE22202224FA24222423A822283A10E212442A04460882 +73ED:00800080F8BE2288228822882288FABE2288248820883908E108423E04000800 +73EE:000007FCF404240425F424442444F5F425542554255425543574C44604460842 +73EF:00400040FC4411F41048105013FE7C4010801184129810E01C82E082407E0000 +73F0:00200124FCA410A410A8102011FC7C041004100411FC10041C04E00441FC0004 +73F1:00400024FA242108210820102040F84023FE208821083990E060405001880604 +73F2:000003FEFA022444204023FC2080F8A0212021FC20203820E3FE402000200020 +73F3:02040104F9082FE8229422A42288FA8A2292212421043908E2904240043E0800 +73F4:001000D8FB942094209023FEF8902094209420D823983890E0AA40CA02860102 +73F5:000001FCFD041104110411FC7C00100013FE102010201DFCE020402003FE0000 +73F6:01080088FC9011FC1024102411FC7D20112011FE106210A21D2AE22444200020 +73F7:00100018FBD42014201027FE2010F890209022D022903A90E28A42EA07060202 +73F8:000003FEF840204021FC20842084FBFE2000200021FC3904E104410401FC0104 +73F9:00280024F824202023FE22202224FA2423A422A822A83A90E29245AA04460882 +73FA:000001FCFC44104413FE10447C4411FC1080108011FC1E84E484408400FC0084 +73FB:00800080FCFE110012FC10847CA4109413FE108411241D14E1FE400400280010 +73FC:000001FCFD04110411FC11047D0411FC1104110411FC1C00E088408401020202 +73FD:00000006FBB8208820882108213EFB88208822882288393EE1004280047E0800 +73FE:000001FCFD04110411FC110411047DFC1104110411FC10501C90E0924112020E +73FF:000001FCFD041104110411FC7C2010201120113C11201D20E2A04260043E0800 +7400:00200020FC5010881144122210F87C081010102011FC11041D04E10441FC0104 +7401:01000100FDFE1200140011FE7C2210241120113C11201D20E12042A0047E0800 +7402:00200010FDFE1000100010FC10007C0010FC1000100010FC1C84E08440FC0084 +7403:00280024FC24102013FE102011207CB210B4106810A811241E22E02040A00040 +7404:000000FCFC84108410FC10007DFE1102110211FE11021D02E1FE4102010A0104 +7405:00400020FDFC1104110411FC11047D0411FC1120112211141D08E14441820100 +7406:000001FCFD24112411FC112411247DFC1020102011FC10201C20E02043FE0000 +7407:001C01E0FC20102013FE10A87D24122211F8108810901CBEE102410202140408 +7408:0008003CFDC01004114410A810007DF81010102013FE10201C20E02040A00040 +7409:00400020FBFC20402090210823FCF8042150215021503950E25042520452080E +740A:000007DEF89224922494249427D8F8942192219222923A9AE494489002900110 +740B:01840068F83020C823042040FBFE20A0212023FC25243924E134412800200020 +740C:00200124FD24112411FC10207C5010881144122210201DF8E008401000100020 +740D:004200E2FB82208A208A208A27EAF88A218A21CA22AA3A82E4824082008A0084 +740E:00240224FD24117E102410247C24137E1124112411241D24E144410002FE0400 +740F:00200420FA2022FE204020502E90FAFE2210221023FE3A10E210451008FE0000 +7410:00200124FCA410A8102011FC11047D2411241124112411241C50E08841040202 +7411:00200124FCA410A8102011FC7D04110411FC110411041DFCE104410401140108 +7412:00400040FCFC1088115010207CD8132610F8102010F81C20E3FE402000200020 +7413:00400020FBFE2202240421F82000F80023FE209020903890E1124112020E0400 +7414:00400020FBFE22022404200023FEF82020202120213C3920E2A04260043E0800 +7415:00400080FDFC1124112411FC11247D4411FC1090111013FE1C10E01040100010 +7416:00480044FC5E11E0102810127C6A11961048105E11E01C24E0284012006A0186 +7417:00400020FDFE1000108810887D5412221000102013FE1C20E020402000200020 +7418:001C03E0FA2023FE22202292230AFA0621FC2104210439FCE104410401FC0104 +7419:00140012F81027FE20102010FBD222522252225423D43808E0EA471A02260042 +741A:000003FCFA04220423FC22202220FBFE2220222022FC3A84E284448404FC0884 +741B:000007FCFC0424A4211022082040F84027FC204020E03950E2484C4600400040 +741C:00400040F84027FC204022482248FA48255420E021503950E248444408420040 +741D:01FC0104FD0411FC110411047DFC1040102013FE10881C88E050402000D80706 +741E:7CFC448444FC7C8444FC44847C84011402087FFC01003FF801200110FFFE0000 +741F:00A00090FC9011FE111013107DFE1110111011FE11101D10E11041FE01000100 +7420:00500050FC5011FC1154115411547DFC11541154115413FE1C00E08841040202 +7421:01000100F9DC21142114211427D4F8142114211425883D48E948411405140222 +7422:000003FEF8402080214422242068FAB0213022A8206838A4E122422000A00040 +7423:00400020F9FC2000210820902000FBFE2000200021FC3904E104410401FC0104 +7424:00800080FDF81108121015FC7C24102413FE102410241DFCE024402000A00040 +7425:00400040F87C204023FC22442270FBC02244223C22003AF0E49044920912120E +7426:00400040FBFC20A02110220827FEF80823C8224822483A48E3C8400800280010 +7427:00007FFC04403C7820083C780440FFFE00007FFC01003FF801200110FFFE0000 +7428:000001FCFD04110411FC110411047DFC1000111211D411181D10E1524192010E +7429:00FC0084FC8410FC108410847CFC100011FE110211021DFEE102410201FE0102 +742A:01080108FBFC2108210821F82108F90821F8210821083BFEE000409001080204 +742B:00200020FDFC104010F8104013FE7C881124122210F810201DFCE02040200020 +742C:00400020FBFE22022504210021DEFA5222522352249A3894E11041120212040E +742D:000001F8FC08100811F810087C0813FE1020122211741CA8E124422200A00040 +742E:00400020FBFE2202200021FC2000F80023FE202021283924E222442200A00040 +742F:00200010FDFE1102120410F87C88108810F8108010801CFCE084408400FC0084 +7430:00200122F9222224205020882304F82220202124212422283850E08801040602 +7431:000001FCFD241124117411247DFC11041174115411541D74E104420402140408 +7432:00900090F890239E209020902090FB9C209020902090239E3890E09000900090 +7433:01100110F910211027BC21102110FB3823B8255425543992E110411001100110 +7434:0000FEFE101010107C7C10101010FEFE010006C01A30E10E1FE0004000800100 +7435:0000FEFE101010107C7C10101010FEFE0000208020843E9820E020842684387C +7436:0000FEFE101010107C7C10101010FEFE00003FF8210821083FF8200220021FFE +7437:01080088F89023FC2040204021F8F840204027FE20A038A0E12041220222041E +7438:00200020FC3E102011FC110411FC7D0411FC1124102013FE1C20E02040200020 +7439:0000FEFE101010107C7C10101010FEFE010001007FFC054009203118C1060100 +743A:02100110F910247C221022102010F97E21102210262022243A42E2FE02420000 +743B:00200020FC5010881104120210F87C20102011FC102011241CA4E0A843FE0000 +743C:00400020FBFE2000200021FCF904210421FC202021283924E222442200A00040 +743D:00200022FDFA1024102813FE7C20104010FC118412841CFCE084408400FC0084 +743E:03F80248FA4823F82248224823F8F8A021102208251621103910E11002100410 +743F:000003FEFA22202023FE2020F9FC212421FC212421FC3820E3FE402000200020 +7440:0004001EFBE0202021FC21242124F9FC202023FE22223A2AE2FA4202020A0204 +7441:000001FEFD02117A1102117A11027C0010FC108410FC10841CFCE08440FC0084 +7442:000001FEFD12111211FE11007D7E11421142117E11421D7EE2424242047E0842 +7443:00400040FBFC204021F8208023FCF910220825F621103910E1F04110011001F0 +7444:00400020FBFE2202240421FC2000F9FC210421FC210439FCE104400003FE0000 +7445:000001FCFD04110411FC11047D0411FC100013FE10201D20E13C412002A0047E +7446:000001FCFD0411FC110411FC10207D2011FE1220102011FC1C20E02043FE0000 +7447:002001FEFC2010FC102011FE7C0010FC10A4109411FE1CA4E11441FE00040018 +7448:000001FCFC48103013FE10527C9411101230102013FE1C70E0A8412406220020 +7449:000001FCFD0411FC111011FE7D10114A1186100011FC1D04E1FC410401FC0104 +744A:0008000CF80A23FE2208220822E8FA0A220A22EC22AC3AA8E2EA421A02260442 +744B:00400040FDFC108413FE10007DFC110411FC102013FE1C20E22043FE00200020 +744C:000003FEFC20104011FC115411547D541154112C102013FE1C50E08841040202 +744D:00800080F8F82108221025FCF9042154218C212420203BFEE050408801040602 +744E:01100112FDD41118115211927D2E104011FC110411041DFCE104410401FC0104 +744F:00400020FBFE22022088210421FCF890211023FE20503890E110461000500020 +7450:01080088F89027FE200023C42254FA5423D4225422543BD4E2544244025402C8 +7451:008000FCFD0411F8100813FE10407CA213341058109413341C52E09043500020 +7452:000000FCFC8410FC108410FC10007DFE108010FE112A124A1C92E12240540088 +7453:00200020FBFE202021FC2124F9AC2174212421FC20203870E0A8412402220020 +7454:00400080FDFC110411FC11047DFC1020103213B410A81D28E124422404A20040 +7455:000003DEFA422242224223DE2200FA3E23D2221222143BD4E208421402240242 +7456:00800338FA28222823A822462200FA7C23A4222422283BA8E610422802440282 +7457:003C07C0FA442128200023FC2080F88027FE210021F83A88E250442008D80306 +7458:00000FDEF4922492249427942498F49427922492249225DA3E94C09000900090 +7459:00920124FA482124209220402080FBFE2202228A22523A22E252428A03FE0202 +745A:0100013CF92427E42124213C2124FBA422A422BC22A43AA4E3A4404400540088 +745B:00880088FBFE208820A8202021FCF9242124212423FE3820E050408801040202 +745C:004000A0F910220825F6200023C4FA54225423D422543A54E3D44244025402C8 +745D:00200040FDFC110411FC11047DFC100013FE102010201DFCE020402003FE0000 +745E:00200222FA22222223FE200027FEF820204023FE22523A52E252425202520206 +745F:0000FEFE101010107C7C10101010FEFE011008A0484449828E121810E7F00000 +7460:004003BEFA122292225222AA2324F84023FE222222223BFEE222422203FE0202 +7461:0100027EFB88228822BE22AA23AAFA2A222A23AA22AA3AAEE288438802880008 +7462:00400020FBFE2202249421082264F8902108220425FA3908E108410801F80108 +7463:00200124FCA8102011FC11047D0411FC110411FC11041D04E1FC400000880104 +7464:00400080FDFC1248113010C013007DFC1220102013FE10201D24E12441FC0004 +7465:000001F8FD08110811F811087D0811F8100013FC12941E94E294429407FE0000 +7466:00400080FDFC1104110411FC7D0011FE110011FE10021EAAE2AA440200140008 +7467:00200020FBFE202021FC204023FEF888213422E2202039FCE07040AC03220020 +7468:000003FCF89022942198209027FEF80021F82108210821F83908E10801F80108 +7469:08202AA44D28145022887FFE400280043FFC010001001FF80100012001107FFE +746A:000001FEFD2011FC112011FC7D20112011FE100212AA1EAAE2AA420200140008 +746B:001E01E0FC221112109410807C2011CE1102110211CE1D02E102410201FE0102 +746C:204017FE8090490813FCE1502252244E00007FFC01003FF801200110FFFE0000 +746D:00200010FBFE222022FC222423FEFA2422FC222022FC3A84E284448404FC0884 +746E:000003FEF850205023FE22522252FBFE2020202023FE3870E0A8412406220020 +746F:0100009EFBD22252225423D42258FA5423D2221222923A5AE2D4435002100010 +7470:00200040FBFC2224222423FC2224FA4423FC204020A838B4E13C41220222041E +7471:00200020FBFE202021FC210421FCF90421FC210421FC3904E3FE408801040202 +7472:00400040F8A02190224827FEFA0823F8220823F822003BF8E508450809F80108 +7473:00840044FC4811FE102010FC7C2011FE1040108010FE1D10E210441001FE0000 +7474:1000FE7810487C480048FE8682007CFC0044FE4410287C2810101E28F0444182 +7475:000001FCFCA41088105010207CD81326102011FC11241D24E1FC402203FE0002 +7476:0008003CFBC0200422442128F9FC2220202023FE20203924E124412401FC0004 +7477:000E03F0F8442224210823FE2242F84023FE208020FC3944E128421004680186 +7478:00400020FBFE2202241421E02100F90021FC2110211027FE3800E09001080204 +7479:00880088FBFE208820A820502088F9742222202021FC3820E0A8412402A20040 +747A:00200124FCA813FE120210F87C88108810F8102011FC1D24E124413401280020 +747B:000001FCFD2413FE112411FC7C0011FC110411FC11041DFCE10441FC00880104 +747C:002003FEFC2011FC112411FC11247DFC102213FE100813FE1D08E08840280010 +747D:01240124FA2424242954214AFA9226102A102250225C3A50E25042B0029E0300 +747E:00880088FBFE208820F8202021FCF92421FC202023FE3820E1FC402003FE0000 +747F:00007F7848485F4C64805F7844484A4851307F4C00007FFC01003FF80120FFFE +7480:00200222FBFE2090208821FE2310FD1021FE2110211039FEE110411001FE0100 +7481:00400080FBFC224422F4231422A4FA4422A423FC20403824E522450A090800F8 +7482:00880088FBFE208820F8208820F8F88823FE208821243AFAE020402003FE0000 +7483:00400020FBFE2000215421242154F9FC202023FE22423A92E2FA420A02020206 +7484:00400020FDFC1088105013FE7C0011FC110411FC11041DFCE09040920112060E +7485:01240248FD24100011FC11247DFC112411FC102013FE1C70E0A8412406220020 +7486:000007BCF88424A4229424A42050F988262620C023103864E388403000C00700 +7487:02100110F91027BE2240220023BEFA8A228822A822AE3AA8E4A845A8085E1080 +7488:01080108F90827D0211E2794F9242FD4221423D422543A48E24844D404240842 +7489:00100410FAFE221020FE209226FEFA9222FE221022FE3A10E210451008FE0000 +748A:00880088FBFE2088208820F82020FBFE2222233222AA3B76E2224222022A0224 +748B:002001FCFC88105013FE10007DFC110411FC110411FC1C20E3FE402000200020 +748C:00400020FBFE2202200021FC2020F9FC212421FC212439FCE000408801040202 +748D:008803FEF888200021FC20A820A8FBFE20A820A821FC3820E3FE402000200020 +748E:00000FBEF8A22AAA2AAA2AAA2514F8A220802FFE21103A10E3A0406001980E04 +748F:010001F8FA0823F020102FFE2080FC8824EA274A244C3DE8E44A464A04A60110 +7490:00100790FCBC24A424C427A82110F928214625C0253C3D24E52445A40E3C0024 +7491:00800080F9FE23542554215423FEF9542154215427FE20003954E12A022A0000 +7492:002007A4F8A822922114220825F4F80223F8220822083BF8E20841100FFE0000 +7493:008803FEFC88101C11E0102013FE7CA81124122211F810881C9EE082410A0204 +7494:01040088F80023FE222222AA2272FA2223FE200021FC3904E1FC410401FC0104 +7495:000003FCF80423FC200423FC2000FBBC212427BC20083BFEE108408800A80010 +7496:0200017EF840247C224420FCF940267E2220202023FE3870E0A8412402220020 +7497:21F8110841F821080BFE090073FC14A41154128800007FFC01003FF80120FFFE +7498:00200124F8A823FE20A821242222F904210421DE22442554389EE10402040404 +7499:00200020FBFE2050228A2104FBFE250421FC210421FC3820E124422204A20040 +749A:000003FCF848203023FE20522094FB50202023FE22523A8AE376425202720206 +749B:004003F8F84827FE204823F8F8402554275C244427FC3C44E75C455405540844 +749C:00880088FDFC1088108813FE10207DFC112411FC112411FC1C00E08841040202 +749D:002001FCFD2411FC102013FE7C0011FC110411FC11041DFCE10441FC00880104 +749E:00500252F954205023FE20882050FBFE202021FC20203BFEE050408801040602 +749F:000001FCFD0411FC110411FC7C2013FE100011FC11041DFCE020412402220060 +74A0:003C03E0FD2410A813FE10A87D24120211FC112411241DFCE124412401FC0104 +74A1:00280424FA7E22C82148207E2648FA48227E224822483A7EE240450008FE0000 +74A2:000003FEF85023DE2252225223DEF85023FE222222223BFEE222422203FE0202 +74A3:01240124FAAA23AE212422AA23AEF92427FE211021143914E28A424A02160422 +74A4:00200020FBFE202021FC2124F9FC212421FC202223FE3842E02442A2028A0478 +74A5:02880288F7E82290241E27E42454F8542754255425543748E548405402940122 +74A6:003C03C0F8442224210827FE2442FAA4228A247A208038F8E10842900060079E +74A7:3E1022FE3E4420287EFEA2103EFC221000007FFC01003FF801200110FFFE0000 +74A8:008000DCFA8423D424482A942324FC402248215027FC38E0E15042480C460040 +74A9:0040007CF84023FE2242227823C4FA3C220023FE22403BA4E25845B4045209B0 +74AA:01FC0104F90421FC200023DE2252FA5223DE202023FE3870E0A8412406220020 +74AB:00200124FCA813FE120210F810887C8810F8100011FC11241DFCE12441FC0104 +74AC:01080208F7C8245027DE246427D4F214211427D4221423C83248C454055408A2 +74AD:000004FEFA92227C2010207C2654FA7C2254227C221022FE3A10E51008FE0000 +74AE:002007FEF80023FE220222FA228AFBFE200021FC210439FCE10441FC000007FE +74AF:00200050FC881174120211FC7D2411AC112411FC10001CF8E08840F8008800F8 +74B0:000003FCFA94229423FC2000FBFE200023FC220423FC38A2E11443080D440182 +74B1:000007BEF108210827BE21082108F7BE20002080204425123522C9C003040CFC +74B2:00880448FA5020FC202020502694FA382250229822343A54E290422005FE0800 +74B3:00A000FCFD2013FE10A811247E2211FC110411FC11041DFCE10441FC00880104 +74B4:00880088FBDE208821DC22AA2488F80023FE20222120393CE12042A0047E0800 +74B5:0140024CFA642244234C226422A4FBAC22A422A427FE3800E110410802040404 +74B6:004003F8F84827FE204823F8F84027FE200022A424523BF8E2A842A80FFE0000 +74B7:014807C8F90827D0255E27E4FD5427D42554211427D43A08E3C84254055408A2 +74B8:00400020FBFE220221FC2148FA5021FC230421FC210439FCE10441FC00880104 +74B9:002003FEFC2011FC100013FE10027DFC102013FE100013FE1C04E3BE42A4038C +74BA:2FEC48244BA4682C4BA46AAC4BA44824FFFE80027FFC01003FF801200110FFFE +74BB:03DE0042FA52214A2252202023FEF8882088215422223820E7FE402000200020 +74BC:000803E8FA8823EE222823F42282FBE2200021FC21543954E154415407FE0000 +74BD:7FFC21087FFCB55A29283558210835582928355800007FFC01003FF80120FFFE +74BE:00400020FBFE2088205227AC22AAFAA825AC2000210439FCE10441FC01040204 +74BF:0040007CF84027FE240223FCFA4824A4211023F8260C3BFAE20843F8020803F8 +74C0:000001FCFC2013FE122211AC7C2011AC100013FE10201DFCE15441540154010C +74C1:008803FEFCA8109011FE13207DFC112011FC112011FE1D00E3FC40880070038E +74C2:008803FEFC88102011FC102013FE7C40108811FC100011FC1D54E15447FE0000 +74C3:03F80248FA4823F822482248FBF820002FBE2AAA2AAA3FBEEAAA4AAA0FBE08A2 +74C4:002003FEFC2011FC100013FE7E5213FE110411FC11041DFCE10441FC00880104 +74C5:044404E4F8A82AAA2EEE24A42AAAFEEE224220402FFE20E03150C2480C460040 +74C6:0042039CFA1023DE229422942420FBFC220423FC22043BFCE20443FC01080204 +74C7:03FC0040F9F8210821F8210827FEFC4222A4228A247A3880E1F842880070038E +74C8:00500190FC9E13EA108A11D2128A7CA410501088132610A81C70E0A841240060 +74C9:008801DCFC8813DE108811547E2211FC110411FC11041DFCE10441FC00880104 +74CA:010001F8FA0827FE22622292F9FC210421FC210421FC3880E1F842880070038E +74CB:00200010F4FE2244222820FE2092F6FE229222BA22AA22BA3286C50008FE0000 +74CC:00400020FDFE100011FC115411FC7C201122108C112210541CC8E14442520060 +74CD:0008073EF590255E2564265E2500F5DE2552255E2552265E3452C45604A0051E +74CE:01080108F7CE2112212427DE2552F55E27D2211E2392255E3940C11401120122 +74CF:01100090FBDE2010225E2182FBDE201023DE225023DE3A50E3DE4250025202CE +74D0:0040007CF84023FC224423F0FA4422FC22A822F822A83AF8E20045FC05540BFE +74D1:000007FEF4442598248827DE2488F5DC26AA248824202520353CC920092017FE +74D2:01040514F7DE29242FFF210CF3552DA723FC220422243A24E24400B001080604 +74D3:03DE0252FBDE225223DE222222FAFA2222FA22AA22FA3AAAE2FA427202AA0226 +74D4:03DE0252FBDE225223DE225223DEF98C2252204027FE3888E190406000D80304 +74D5:F7FC124817FCFC4686ECF55416EC155456EC244400007FFC01003FF80120FFFE +74D6:002003FEF80021DC215421DC2088FBFE208823FE208827FE3894E18806A400C2 +74D7:022203FEF89021FE231025FE2110F9FE211021FE210023FE3A8AE37602520276 +74D8:008803FEF88823DE225223DE20A0F89021FE212023FC3D20E1FC412001FE0100 +74D9:004003FCF84021F8200023FCF80421F0204023FC20083BBCE2A8439805240892 +74DA:052807BEF94827BE231825AAF94623FC220423FC22043BFCE20443FC01080204 +74DB:010801ECF10A2FEA29282BC8293EFFE829482BE82A282B683AA8CBF40AB412A2 +74DC:001000F81F2012201220122012201220122012101290225022A8432842048002 +74DD:02200720383C2A442A842A242A142A142A0429042928289028404A304D0E8900 +74DE:0210071038502A7C2A902B102AFE2A102A2829242942288228404A304D0E8900 +74DF:02400740387C2A842B742A542A542A742A482942294228BE28404A304D0E8900 +74E0:1008101CFEE828A844A882A87CA800A8FEA820A440A47CA404A2052829341224 +74E1:1008101C7CE810A810A8FEA844A828A87CA810A410A4FEA410A2112811341224 +74E2:0008FE1C28E8FEA8AAA8AAA8FEA800A87CA800A4FEA410A454A2932851342224 +74E3:409021C82708FD3E058055542548FD7E25482548755C25282508494849A89128 +74E4:1008FE1C00E8EEA8AAA8EEA844A8FEA844A8FEA444A4FEA450A2CB2865344224 +74E5:06FE38202C542AB42A5829B454545D9290307EFC52A47EFC10201424FEFE0202 +74E6:0000FFFE04000400040007E008200A20092009200820102213221C22101E0000 +74E7:0020FC202020202020203DFC2420242054204C20442044205422640243FE0000 +74E8:000001FC7C801080108010F8108810881148112811281D08E108414A018A0106 +74E9:0010FC3820E0202020203C2025FC242054204C20442044205422640243FE0000 +74EA:0004FC0E20F0208020803CFC248424C454A84C90452845445602640243FE0000 +74EB:044008203018DFE604200420082010A020407FFC08000FE0092010A41624181C +74EC:200011FC0080FE80208020F83C88248825482528252825084508554A898A0106 +74ED:000011FC10801080FE8092F81088108829482928292829084B084D4A898A0106 +74EE:0440082010102208C44608201FF0000000007FFC08000FE0092010A41624181C +74EF:00007EFC40404440644054784848484854A854986488408840AA7ECA008A0006 +74F0:0010FC502048208820843D0226F8244854484C88448845285612640243FE0000 +74F1:0020FC7021C0204020703DC02440247857C04C4844484448543A640243FE0000 +74F2:0020FC2021FE202021243D24252425FC54204C244424441C5402640243FE0000 +74F3:100011FC10801080FE8010F8108810887D4845284528450845087D4A458A0106 +74F4:100010FC284024404240917808480848FEA802984488288810AA08CA088A0006 +74F5:100011FC208028804480FEF8428800887D4845284528450845087D4A458A0106 +74F6:420024FC00407E402440247824482448FEA824982488248824AA44CA448A8406 +74F7:0100410021FC0A441448E0A02110260C00007FFC08000FE0092010A41624181C +74F8:0000FDFC2020204020F83C88248824F854884C8844F844885402640243FE0000 +74F9:00007EFC424042407E4000787E48424842A87E98428842887EAA42CA4A8A4406 +74FA:00003EFC204020403C40207820483C4820A82098FE88208824AA42CAFE8A4206 +74FB:420024FC1840244052401078FF48204828A87E98AA882A882AAA2ECA088A0806 +74FC:0000FDFC2124212421FC3D24252425FC54204DFC4420442055FE640243FE0000 +74FD:0100111009207FFE40029FF410101FF000007FFC08000FE0092010A41624181C +74FE:0C0071FC1080FE80388054F8928800881148FD28252845082908114A298AC506 +74FF:100008FC7F40004022401478FF48004800A83E982288228822AA3ECA228A0006 +7500:02000F7C78200820FFA02A382A28FFA82A582A48FFC80848085A0F6AF04A4006 +7501:220022FC4440EE404440447844484448EFA844984488448844AA44CA448A8406 +7502:1000087C7E20422042207E38422840287F58554855487F48D55A556A554A4306 +7503:0620382008A47EA819202C504A88090400007FFC08000FE0092010A41624181C +7504:0000FEFC28402840FE40AA78AA48FE4810A81098FE88108810AA1ECAF08A4006 +7505:0000FDFE2100217C21543D7C2554257C55104D7C451046FE5402640243FE0000 +7506:082004407FFC12483CF0082014503EF800007FFC08000FE0092010A41624181C +7507:08202AA42CA84920145022887FFE400280047FFC08000FE0092010A41624181C +7508:080010FC7E4042407E4042787E4842487EA80898FF8818882CAA4ACA888A0806 +7509:2200147CFFA0142014207F381528FFA815587F4814483648555A94EA144A1406 +750A:08007F7C4920FFA049207F3808287F2849587F481048FF48215A726A0C4AF306 +750B:200010FCFE4044402840FE7882489248FEA89298BA88AA88AAAABACA828A8606 +750C:0000FEFC80408040BC40A478A448BC4880A8EE98AA88AA88EEAA80CAFE8A0006 +750D:0820FFFE08203FF824483FF800007FFE4002BFF408000FE0092010A41624181C +750E:100010FCFE4010407C4054787C4854487CA81298FE880888FEAA48CA288A1806 +750F:08047F0808103E6400083E1022643E0814107F6000007FFC08000FE011241C9C +7510:0800497C2A200820FF202A38492888284258774892485A482F5A226A424A8206 +7511:440024FC2840FE409240D678BA489248FEA800987C8844887CAA44CA7C8A4406 +7512:2000207C7FA0D52055205538FFA8552855585548FFC800486A5A556A954A0006 +7513:00407C2045FC44887C5043FE7C20A5FC24203C2000007FFC08000FE011241C9C +7514:20003E7C4220FFA0512064B87FA840285F5840485F4840485F5A516A5F4A9106 +7515:0100FFFE104824FE799010FC22907CFC089030FEC0807FFC08000FE011241C9C +7516:3EF822883EF822883EF822883EF8145022887FFC08000FE0092010A41624181C +7517:08000F7C08207F2049205E3849287F284A585F4851485B48555A5F6A554A9506 +7518:08100810081008107FFE08100810081008100FF008100810081008100FF00810 +7519:005000480040FFFE004022402240FF40224022203E20221222123E0A22060002 +751A:082008207FFC082008200FE0082008200FE008200820FFFE1220141010001FF8 +751B:4404441E44F04410FE1044FE4410441044107CFE44824482448244827CFE4482 +751C:08881C887088108811FEFC88108810887C8844F84488448844887C8844F80088 +751D:08480F4808487F4849FE4E4878484948477840485E485248527A520291FE2000 +751E:0100111009207FFE40029FF410101FF000001010FFFE10101FF010101FF01010 +751F:01001100110011003FFC21004100810001003FF80100010001000100FFFE0000 +7520:002000207D20452045FC452046207C20442045FC442044207C20442003FE0000 +7521:08100810489048907EFE48908910081008107EFE0810081008100E10F1FE4000 +7522:010000803FFE022001C002203FFE2080248027FC2880308027F8408040809FFE +7523:010000803FFE041002203FFE2080248027FC2880308027F8408040809FFE0000 +7524:00100010FF50087C105030904A109C7C28104C109A1029FE48808860281E1000 +7525:11FC1124512451FC7D24512491FC10407C4013FE104210821C82E10242140408 +7526:0010FF101050107CFE5092909210FE7C92109210FE1090FE500020005FFE8000 +7527:101050507E7E90907C7C10101EFEE0001FF010101FF010101FF0101010501020 +7528:00003FF82108210821083FF82108210821083FF8210821082108410841288010 +7529:00003FF82108210821083FF82108210821083FF82108210821284112410280FE +752A:040008003FF82108210821083FF82108210821083FF821082108410841288010 +752B:01200110FFFE010001003FF8210821083FF8210821083FF82108210821282010 +752C:00003FF00020064001803FF8210821083FF8210821083FF82108210821282010 +752D:7FFC01000770190CE10200003FF8210821083FF8210821083FF8410841288110 +752E:08001FF822484488095012203FF8210821083FF8210821083FF8410841288110 +752F:020001007FFE41029494142823E800003FF821083FF821083FF8210821282010 +7530:00003FF8210821082108210821083FF8210821082108210821083FF820080000 +7531:01000100010001003FF821082108210821083FF821082108210821083FF82008 +7532:00003FF82108210821083FF82108210821083FF8210801000100010001000100 +7533:0100010001003FF82108210821083FF82108210821083FF82108010001000100 +7534:01000100010001003FF821082108210821083FF820082008200820083FF82008 +7535:0100010001003FF82108210821083FF82108210821083FF8210A0102010200FE +7536:0200020004003FF821082108210821083FF821082108210821083FF820080000 +7537:3FF8210821083FF8210821083FF8000001007FFC010401040204040418146008 +7538:0800080010001FF820084008BF88248824883F88248824883F88208800500020 +7539:010001003FF821083FF821083FF80000FFFE080010001FF00010001000A00040 +753A:000000007DFE54105410541054107C1054105410541054107C10441000500020 +753B:0000FFFE000000004FE4492449244FE44924492449244FE4400440047FFC0004 +753C:00003FF8210821083FF8210821083FF800000000FFFE01000100010005000200 +753D:008200927C9254925492549254927C9254925492549254927C92451201020202 +753E:0888111022201110088800003FF82108210821083FF82108210821083FF82008 +753F:002000107C10540055FE548054807C8054805480548054807C80448000FC0000 +7540:00001FF0111011101FF0111011101FF000000000FFFE08200820082010202020 +7541:010001001FF0111011101FF0111011101FF00000FFFE08200820082010202020 +7542:008000807C8054F85508550855107E1054205420545054507C88450802040402 +7543:104010401040FE7C92849284FF0492449224FE24920410041004100410281010 +7544:0408420821101110102000403FF82108210821083FF82108210821083FF82008 +7545:100011F810107C20544054807DFC5454545454947D2454241044108411281010 +7546:100008080808FF88000800087F104910491049207F244924494249FE7F424102 +7547:004000407C8054FC5504560454847C4454445414542454447D84440400280010 +7548:0008001C7DE05500550055FC55447D4455445528552855107D10462802440482 +7549:002000207C20542055FC542054207C2057FE5420545054507C88448801040202 +754A:008800887C88548855FE548854887C8857FE5488548854887C88450801080208 +754B:004000407C40548054FE550856887C8854885450545054207C50448801040202 +754C:00001FF0111011101FF0111011101FF002800C603458C4460440084008401040 +754D:002000207C5054505488550456027C8854885488548854887C88450801080208 +754E:002000287C245424542055FE54207C2054205450545054507C88448801040202 +754F:00001FF0111011101FF0111011101FF00000FFFE111010A010401430180E1000 +7550:0000FFFE00001FF0101010101FF000003FF8210821083FF8210821083FF82008 +7551:100011FC1124112455245924512491FC1124112411242924252445FC41048000 +7552:101008100810FF90001000107F104910491049287F284928494449447F844102 +7553:010001047D88095011202118C50602003FF8210821083FF8210821083FF82008 +7554:002000207D2454A454A8542055FC7C205420542057FE54207C20442000200020 +7555:1FF0111011101FF0111011101FF000003FF8210821083FF8210821083FF82008 +7556:0008001C7DF055505550555055507D5055505548554855687D54467402520400 +7557:02000100FFFE00001FF010101FF000003FF8210821083FF8210821083FF82008 +7558:002000207C2055FC5524552455FC7D245524552457FE55047D04450401140108 +7559:060078FC4044484444445A94610800003FF8210821083FF8210821083FF82008 +755A:0200044008201FF002007FFC082010103FF8D11611101FF0111011101FF01010 +755B:002000207C5054885504561254207C4055885410542054447D88441000600380 +755C:020001007FFC040008201FC003100C083FFC00043FF821083FF821083FF82008 +755D:102008200820FFBC002400447F444988490849107F104928492849447F844102 +755E:01000100FFFE012001207D205538554855487D885510551055287D4845840102 +755F:00003FF821083FF821083FF81210220847E4882214402280010006C01830E00E +7560:010002001FF010101FF010101FF000003FF8210821083FF8210821083FF82008 +7561:002000107C1055FE5420542454447CF854125422544455887C10442800440182 +7562:00003FF821083FF821083FF8092009207FFC092009203FF801007FFC01000100 +7563:010002800C603018CFE600001FF010101FF000003FF821083FF821083FF82008 +7564:002000207C2055FC5420542057FE7C08540855FE540854887C48440800280010 +7565:00800080F8F8A908AB10ACA0F840A8A0A918AA06ADF8F9088908010801F80108 +7566:002000207DFC54205420542057FE7C005420542055FC54207C20442003FE0000 +7567:00003FF821083FF821083FF808001FF0282007C01830E00E1FF010101FF01010 +7568:010011100920FFFE054009203118C0061FF0111011101FF0111011101FF01010 +7569:004000207C2055FE5440544054A07CA255A45698549054887C8844A400C20080 +756A:00F83F00111009200100FFFE092010103FF8D11611101FF0111011101FF01010 +756B:01003FF80108FFFE01083FF801007FFC00003FF821083FF821083FF80000FFFE +756C:010002800C603018CFE601003FF81110250802003FF821083FF821083FF82008 +756D:002000207C505488550456FA54207C2057FE5420552855247E22442200A00040 +756E:008000807CFE550056FC548454A47C9457FE5484552455147DFE440400280010 +756F:00400040F888A904ABFEA802F888A944AA42A8F8A988FA508820005001880606 +7570:00003FF821083FF821083FF8082008207FFC08200820FFFE0000082010102008 +7571:00007FFC02803EF8228822883EF802803FF8210821083FF8210821083FF82008 +7572:010002800C6037D8C0063FF809201110250802003FF821083FF821083FF82008 +7573:00003FF821083FF821083FF80000FFFE80021FF010101FF010101FF01010FFFE +7574:00200020FBFEA820A9FCA840FBFEA848A888A8FEA908F9488A28040800280010 +7575:01003FF80108FFFE01083FF80100FFFE00001FF051145FF451145FF440047FFC +7576:0100111009207FFE40029FF4101010101FF000003FF821083FF821083FF82008 +7577:000003DEF842A94AA884A94AFA52AC20A800ABDEA852F9528894014802540422 +7578:002000207DFC54505488550457FE7C0855E85528552855E87D28440800280010 +7579:00400020FBFEAA02AD04A900F9DEAA52AA52AB52AC9AF894891001120212040E +757A:00007FFC00003FF821083FF82108FFFE00003FF821083FF821083FF80000FFFE +757B:002001247CA8542055FC544057FE7C8855245622542055FC7C20442003FE0000 +757C:000000FC7C8454FC548454FC54007DFE548054FE552A564A7C92452200540088 +757D:0008003C7DE0542057FE542055FC7D2455FC552455FC54207DFC442003FE0000 +757E:1FF0111011101FF0111011101FF00000FEFE92929292FEFE92929292FEFE8282 +757F:1110212045447978111025247D7C05240110FFFE00807C8854527C22545A7D86 +7580:0020542055FEA82055FC542403FE7C2455FC54207CA054BC54A07D60453E0200 +7581:000007BCF884ACA4AA94ACA4F850A988AE26A8C0AB10F8648B88003000C00700 +7582:00003FF821083FF821083FF8183006C018307FFE50129FF410101FF01010FFFE +7583:002001FC7C88545057FE540055FC7D2455FC552455FC54207DFC442003FE0000 +7584:00200124F8A8ABFEA8A8A924FA22A904A904A9DEAA44FD54889E010402040404 +7585:000003FEF800A9FCA924A9FCF924ABFEA800A9FCA924F9FC892401FC000003FE +7586:0000FBFE080009FCF92481FC8124FBFE480049FCE92449FC692489FC500023FE +7587:002003FEF820A9FCA800ABFEF802A9FCA820ABFEA800FBFE880403BE02A4038C +7588:0080F8BE0080709C5294729C0280FABEAAAAACAAF8BEA8AAA8AAF93E89220200 +7589:1FF011101FF011103FF82AA83EF82AA8FFFE88020FF010101FE00020FFFE0000 +758A:1FF011101FF011103FF82AA83EF82AA8FFFE90121FF010101FF01010FFFE0000 +758B:000000007FFC0104010801001100110011F81100110011002900250043FE8000 +758C:010001007FFC01003FF80108FFFE01083FF80100110011F81100290047FE8000 +758D:00007FFC0104110011F0290047FE80001FF010101FF010101FF00000FFFE0000 +758E:002000207DFE0420082011FC512451245DFC5020507050A85D247222C0200020 +758F:002000107DFE04200848108451FE50025CA850A850A850A85D2A712AC22A0406 +7590:01003FF801007FFE40029FF411101FF011101FF000007FFC010411F02900C7FE +7591:40004DFC7008445044203DFE40247C2890A010B8FEA010A028E02520451E8200 +7592:008000401FFE1000900050005000100030005000900010002000200040008000 +7593:008000401FFE1000900057F8510811103120513C910411042204220444288810 +7594:008000401FFE1000900057FC5040104030405040904010402040204041408080 +7595:008000401FFE1000900052005208121032605380920012042204220441FC8000 +7596:008000401FFE1000900057FC5084108430845084909410882080208040808080 +7597:008000401FFE1000900057FC5008101030205040904010402040204041408080 +7598:008000401FFE10009000500057FC10403040504090401040204020404FFE8000 +7599:008000401FFE1100910053FC5400180033F850109060108021002202420281FE +759A:008000401FFE11009100510053F01210341058209020104020A0211046089806 +759B:008000401FFE10009010501057FE101030105210911011102010201040508020 +759C:008000401FFE10009000500057FE104030405050904810442040204040408040 +759D:008000401FFE100090405040504014443444544494441444244427FC40048000 +759E:008000401FFE1000900053F85000100037FE5080910013F82008200840508020 +759F:008000401FFE1000900053FC5200120032005FFE92001200220023FC40008000 +75A0:008000401FFE1000900057FC5100110031F85108910812082208240848509020 +75A1:008000401FFE100093F0502050C0110033FC5124912412242244244448A88110 +75A2:008000401FFE100090405040524412443248545090A010A02110220844048802 +75A3:008000401FFE100090905088508017FE30A0512091201120222222224422881E +75A4:008000401FFE1000900053F8524812483248524893F812002202220241FE8000 +75A5:008000401FFE1040904050A0511012083D165110911011102110221042108410 +75A6:008000401FFE10009040504053F810483048504897FE10A020A0211042088C06 +75A7:008000401FFE1000903C57C054401440344057FE942014202412250A46068402 +75A8:008000401FFE1000900057FC50101210341057FE90501090211022104C508020 +75A9:008000401FFE1080908057F0511011123212544E904017FE2040204040408040 +75AA:008000401FFE1020922052205222122433A852309220122222A22322421E8000 +75AB:008000401FFE100093F052105210140E380057F89208111020A0204041B08E0E +75AC:008000401FFE100093FE52005220122032FC5224922412442244248444A88910 +75AD:008000401FFE10009110511051101110311052A8926812282444244448849102 +75AE:008000401FFE104090A05110520814063BF052109210125022202204420481FC +75AF:008000401FFE1000900053F85208132832A85248924812A8252A240A48069002 +75B0:008000401FFE10809040500057FC10403040504093F81040204020404FFE8000 +75B1:008000401FFE1200920053FC54041BE43224522493E4121422082202420281FE +75B2:008000401FFE1040904057FC5444144037F85508951014A0244028A049189606 +75B3:008000401FFE1000920852085FFE12083208520893F812082208220843F88208 +75B4:008000401FFE1000900057FE5008100833C85248924813C82248200840288010 +75B5:008000401FFE1000911051105512151435D8551095101510251225D25E12880E +75B6:008000401FFE100090485248524812483FFE5248924812782200220043FE8000 +75B7:008000401FFE1000903C57C054401440344057FE942014202412250A46468422 +75B8:010000803FFE20002000A7F86408240827F86408A40827F8200040005FFE8000 +75B9:008000401FFE104090A051105208142630C05310902010C02308201040E08700 +75BA:008000401FFE1000907857805040102037FC5008903010C023002480487E9000 +75BB:008000401FFE1000900053FC520412043204520493FC12042090210842048402 +75BC:008000401FFE1100910053F85610192030C053309C0E10C02020230040C08020 +75BD:008000401FFE1000900053F85208120833F85208920813F8220822084FFE8000 +75BE:008000401FFE1200920053FC5240144030405FFE904010A020A0211042088C06 +75BF:010000803FFE21203FFCA12461242FFC29206920AFFE21222222422A44248820 +75C0:008000401FFE1200920053FC5404180433E45224922413E42224200440288010 +75C1:008000401FFE10809080508050FC1080308057F8940814082408240847F88408 +75C2:010000803FFE24002400A4006FBC24A424A464A4A4A424A428A448BC52A4A100 +75C3:008000401FFE108090405FFE50801108321057E0904010802110220847FC8204 +75C4:008000401FFE1200920053FE5500190031F85100910011FC2100210041008100 +75C5:008000401FFE1000900057FC5040104037FC544494A415142614240444148408 +75C6:008000401FFE100093FC5204520413FC3200524092441248227024424442883E +75C7:008000401FFE100090005FFC504010403240527C92401240224022405FFE8000 +75C8:008000401FFE1000900057FC5444144437FC5444944417FC2444284448549008 +75C9:008000401FFE100097F85010502010D833045C0293F81040204020404FFE8000 +75CA:008000401FFE104090A0511052081DF63040504093F81040204020404FFE8000 +75CB:008000401FFE10009040504057FC14443444544497FC10402048207C4F828402 +75CC:008000401FFE1000900057FC540415F4340455F49514151425F4240444148408 +75CD:008000401FFE10409FFE50405FFC104437FC544097FE104220AA211442088C06 +75CE:008000401FFE108090405FFE5080110833F05020904411882610206841848602 +75CF:008000401FFE1040904057FE5080110033FC550499FC110421FC210441148108 +75D0:008000401FFE1000900057FC5404140435F45514951415F42404240447FC8404 +75D1:008000401FFE108091F852105D2010C031A0567C908411082690206040C08700 +75D2:008000401FFE111090A057FC5040104033F85040904017FC2040204040408040 +75D3:008000401FFE100097FC50805110120837FC5044904017FC204020404FFE8000 +75D4:008000401FFE1040904057FC504010403FFE501090101FFE2210211041508020 +75D5:008000401FFE100097F8540857F8140837F85484948814502420251846068400 +75D6:008000401FFE1000900053FC5090109034925292929410982090209047FE8000 +75D7:008000401FFE1200920053FE54001BF8328852489FFE1488244827FC40088030 +75D8:008000401FFE1000900057FC500013F83208520893F81000211020A04FFE8000 +75D9:008000401FFE100097FC5000524814903248500097FC1040204020404FFE8000 +75DA:010000803FFE20802088A7F060A03FFE20806FF0A620384027FC404041408080 +75DB:010000801FFE100097F850A0504017FC344457FC944417FC2444244444548448 +75DC:008000401FFE1000903853C0504017FC31505248944611F02110211042128C0E +75DD:010000803FFE22102208BFFE6248225022646248A2522264244A447248C2933E +75DE:008000401FFE100097FC5020504011D036485044900013F822082208420883F8 +75DF:008000401FFE104092485150504013F8320853F8920813F82208220842288210 +75E0:008000401FFE10809108520457FE110A3284548291F813082490206041988E06 +75E1:008000401FFE105090485FFE504017FC344457FC944417FC2444244444548448 +75E2:008000401FFE100090C45704511411143FD45314939415542504290441148108 +75E3:008000401FFE10009040504057FC1040304053FC900010402124252A450A88F8 +75E4:008000401FFE1040904052485248155438E25040904017FC2040204040408FFE +75E5:008000401FFE10009210512057F814083408540897F81120212022224422981E +75E6:008000401FFE100097FC508053F8108831085FFE900013F82208220843F88208 +75E7:008000401FFE10109210511051541452329252109114160422082210422080C0 +75E8:008000401FFE1108910857FE5108100037FE5402904017FC2084210442288C10 +75E9:008000401FFE104097FC544457FC144437FC504097F81208211020E043188C06 +75EA:008000401FFE110091F0521054201BF83248524892481FFE20A0211042088C06 +75EB:008000401FFE10009200517C5404144435F4544494E415542644244444548408 +75EC:008000401FFE100093F8520853F8120833F8510093FC14942924224444A88110 +75ED:008000401FFE100097BC54A454A417BC34A454A497BC14A424A424A44AA4914C +75EE:008000401FFE100093FC520053F8120033F852009FFE14882450252046188406 +75EF:008000401FFE1080904057FC540413F03210521093F0120023F82208420883F8 +75F0:008000401FFE10409248525054A0111032085C449248125024A0211042088C06 +75F1:008000401FFE100090905090579E10903090539C90901090279E209040908090 +75F2:008000401FFE1110911051105FFE111035545554955415542554295641108110 +75F3:010000803FFE22102210A2107FBE221026106738AAB42A543292421042108210 +75F4:008000401FFE1200920053BC5524192431245FE49124112422A422BC44248800 +75F5:00801FFE1000103893C0504017FC315052489C4611F010202FFE204041408080 +75F6:008000401FFE10A090A057FC54A414A437FC54A494A41FFE2000211042088404 +75F7:010000803FFE20002080AFFC6120221024886FF6B49027F0249047F24082807E +75F8:010000803FFE21002504A7C469143FF4211467D4A5542554255445C441148108 +75F9:008000401FFE100093F8524853F8124833F850009FFE11102110211042108410 +75FA:008000401FFE1080910057FC544417FC348457FC914012403FFE204040408040 +75FB:00803FFE20002038AFC068402FFC28206B1AAC0627F8240827F8440847F88408 +75FC:008000401FFE100097FC5444544417FC344455F49514151425F4240447FC8404 +75FD:008000401FFE1120911053FE522016203BFC5220922013FC2220222043FE8200 +75FE:008000401FFE1000977E55045574165435545554955415742754240444148408 +75FF:008000401FFE103897C050405FFE115032485C4690801FFE2108231040E08F1C +7600:010000803FFE20002410A2106FA8242824446792A488248828A048905288A108 +7601:008000401FFE1000904057FC5110111032A8544490401FFE2040204040408040 +7602:008000401FFE10009FFC5120512017383408540897381120212021205FFE8000 +7603:010000803FFE20002FFCA100630824882D506260A5E029502250444859448080 +7604:010000803FFE22102FFCA21062103FFE200067F8A408240827F84408440887F8 +7605:008000401FFE1208911057FC544417FC344457FC944410402FFE204040408040 +7606:008000401FFE1090910853FC504017FE311052689D86103021C0201840608380 +7607:00803FFE200827F0A0406FFE204027FC6444A7FC244427FC204047FC40408FFE +7608:008000401FFE110097BC51145794111437A4514C90401FFE20A0211042088C06 +7609:008000401FFE104090A053185DF61000378454A497A414A427A4248444948588 +760A:010000803FFE200022F8A20864082DFE348064F8A520242025FE445044888506 +760B:010000803FFE20002FF8A80868682B8828886BE8AAA82BE8288A50EA5726A002 +760C:008000401FFE1100910457C4511417D4355457D4911413942554294441148108 +760D:008000401FFE100093F8520853F8120833F850009FFE120027FC292442548488 +760E:008000401FFE111097FC511051F0111031F0511097FE120022902308420083FC +760F:008000401FFE1040904453F45048105037FE508091F8130825F8290841F88108 +7610:010000803FFE20002280ACB8688828882EB86888A8882FF8214042204C18B006 +7611:010000803FFE200023F0A21063D0225022506FFCA80429E4292449E448148808 +7612:008000401FFE100097FE54425BFC104033F8524893F8124823F820404FFE8040 +7613:010000803FFE220023F0A4206FFC34A425146444A0402FFE20A0411042088C06 +7614:008000401FFE111091105FFE511010403FFE5040904017FC2404240447FC8404 +7615:008000401FFE100097BC5484548417BC3400547C97A414242428279044288446 +7616:008000401FFE1080904057FC521011203FFE500093F8120823F8220843F88208 +7617:010000803FFE20802FF8A49062A03FFE21406220AC9830862FF8408040809FFC +7618:008000401FFE124891505FFE51501248344450809FFE11082390206041988604 +7619:008000401FFE100097FC5248511010E033185C4693F8124823F8204447FC8004 +761A:010000803FFE28902510AFBE622222442A906A90AF9022102228442844448882 +761B:008000401FFE110097BC51145394111437A4514C9100104020242522450A88F8 +761C:010000803FFE210027F8A40867F8240827F86408A7F8208020444A424A1291F0 +761D:008000401FFE100097FC54A454A417FC30405150924814442150224844448040 +761E:010000803FFE204027FCA2486248255428A26318AC4623F8204040404FFE8000 +761F:010000803FFE200027F8A40867F8240827F86000AFFC2924292449247FFE8000 +7620:008000401FFE1444924854A45110120837FC5A0A93F8120823F8220842288210 +7621:008000401FFE104091B05E4E53F8120833F8520893F8120025FC250449FC8104 +7622:010000803FFE24002F78A9486D482B863F006978A9482D482B28491049289346 +7623:010000803FFE20802100AFFC68842FFC28846FFCA1482154225C44464842B03E +7624:008000401FFE1080977C542455A415543648508097FC144427FC244447FC8404 +7625:008000401FFE111090A057FC504013F8308057FC910013F82440284047FE8000 +7626:008000401FFE1140965C5444575C144437FC504097FC1208211020E043188C06 +7627:00803FFE208020FCA0806FFE288228F06F84A87C280029FC29004BFE490091FC +7628:00801FFE104017FC904053F8120833F8520893F8120813F822082FFE41108208 +7629:008000401FFE1110911057FC515010A0311052E89C0613F82208220843F88208 +762A:00803FFE210027F8A40867F8240827F86408A7F8212026183A664388420881F8 +762B:010000803FFE20502048BEFE72902A902BFE6490A4902AFE2A90529040FE8080 +762C:008000401FFE1000973C5120513C1720343C5420977E1128212A212445248232 +762D:00803FFE20003FFEA1206FFC29242FFC6000A7F820002FFC2248444449428080 +762E:008000401FFE111093F8521054A417FC30A053189C4613902064239840608380 +762F:008000401FFE142092205F7E544014A0373C5550951015FE251029284B449082 +7630:00803FFE200027FCA44467FC244427FC6100A20827F020C42FFE444849449082 +7631:010000803FFE20402FFEA2486248255428A26318AC0620802A444A4A520A81F8 +7632:010000803FFE22002448A848705422A425006C10B490249C24904550463E8400 +7633:00803FFE20002F7CA924651429A421606618B88623202C4021884E3041C08E00 +7634:00803FFE204027FCA1106FFE200023F86208A3F8220823F820404FFE40408040 +7635:010000803FFE222023BCA4A46AA82510220865F6A80027FC2250444849448080 +7636:010000803FFE22202220AFA0623E2FC22A946A90AF90221027284AA852448282 +7637:010000803FFE22102210AF90623E2FA42AD46A94AF94220827084A9452248242 +7638:008000401FFE120097BC52A454A415BC384057FC94A41554244424A44514840C +7639:010000803FFE22102520A8BC7744220422246F94A2142A84270443C45C288010 +763A:010000803FFE20002FFCA8046FFC28002FFE6820ABFE2B322AAA4B324AAA9206 +763B:010000803FFE20802FF8A8887FFE28882FF86490A7F021003FFE441043E09C1C +763C:008000401FFE111097FC511053F8120833F8520893F810402FFE20A043188C06 +763D:00803FFE22083FFEA20863F8204027FC6444A7FC20402FFE204047FC40409FFE +763E:00803FFE20402E78AA886B102CFC2A046AFCAA042BFC2E2028144952494A8A38 +763F:00803FFE20002FBEA8A26AAA2AAA2AAA6514A8A23FFE2208271040E0431C9C02 +7640:010000803FFE22202FF8A2207FFC20802FF86888AFF828882FF8422044108808 +7641:008000401FFE108094FC550058FC128432FC54849CFC144024FC2548443085CE +7642:008000401FFE104097FC50A0551413F8360C5BFA920813F82040244449428080 +7643:00803FFE20202F3CA9446AA82C102A286946A9382D502A7E2890487C481088FE +7644:008000401FFE1120911053FE56201BFC322053FC922013FE2200252444928892 +7645:008000401FFE100097FE50A057BC14A437BC50A097FC144427FC244447FC8404 +7646:010000803FFE21102554A5B8691022A824446FFEA88230842FF8410842288C10 +7647:00803FFE20002F3CA9246F3C29242F3C6804A9E4292429E4292449E449248A6C +7648:010000803FFE20402F50A1246A1824083B766150AF8C28782F48413045488284 +7649:00803FFE20002FBEA8A26FBE200027FC6444A7FC244427FC20407FFE40408040 +764A:010000803FFE20102F28A9446A922C7C2A086910A97E2D002AFE4820484488FE +764B:008000401FFE100097FC50A053B8120833B850A09FFE10402124252A450A88F8 +764C:008000401FFE100093F8520853F8100037BC54A497BC10402444244447FC8004 +764D:010000803FFE20802E4EA44465F4242425246EAEA444244424A446A4590E8200 +764E:008000401FFE100097BC54A457BC14A437BC540495F4151425F4251445F4840C +764F:00801FFE100017FC94A457FC10003FFE500093F8120813F8214423284D10818C +7650:00801FFE10A013189DF6500017FC355454E497FC100013F8220823F8420883F8 +7651:00803FFE212027F8A52867F825282FFE6800ABFC28002FFE2A444A285298A306 +7652:00803FFE204021A0A6187BF6200027A864A8A7A824A8278824A845904A5491F2 +7653:010000803FFE25102950B55067DE28243B946814AB942A942A884AC84A948C22 +7654:008000401FFE104097FC51105FFE100033F8520893F8120823F82544452A88FA +7655:008000401FFE1040902057FE5228127E34C8577E924814C8277E2248447E8840 +7656:010000803FFE20102788A4BE648027A22494643EAF882C8834BE478844888008 +7657:00803FFE200027FCA0406FFE284223586040A358200027FC244447FC444487FC +7658:00801FFE11101FFE911053F8124833F8524893F8104017FC245425F44414840C +7659:010000803FFE21002E78A8086F7828082FF86888ACC82AA82CCA4AAA4CC68882 +765A:00803FFE220023F8A4106FFE352426FA6400A5FC240025FC240049FC490491FC +765B:00803FFE20402FFEA00067FC240425F46514A7FC200823F020404FFE41508E4E +765C:010000803FFE20002FDCA8546FD42AA22A806FDCAA942FD4280852885454A862 +765D:00803FFE20402FFEA00067FC240425F46514A7FC200027FC20004FFE424884C4 +765E:00803FFE22102F9CA22462482FBE2AA26AAAAFAA222A272A2AAA529442228242 +765F:00803FFE210027F8A6486528249827F86210A5E8380627F8254847F845488558 +7660:010000803FFE20402FFEA0A06F5E255425546B5AA20823F8220843F844088808 +7661:010000803FFE2480273CA48463942408277E6A0AA2282FAE22284558484E9080 +7662:00801FFE1208111097FC504013F830805FFE921017F81A1623F0226443188204 +7663:010000803FFE24002744A928727E2F902A906FBCAA902F90207E43905C108010 +7664:008000401FFE121093DE5528588417BC34A457A494A417A42434252846A08420 +7665:010000803FFE25102950B55067DE28243B946814AFD429142B8849084FD48822 +7666:00803FFE200027FCA55464E427FC204067FCA0402FFE24A4285247FC40408FFE +7667:00803FFE20002FFCA8886B3029102FBC6BB8AD542912284029784940494097FC +7668:00803FFE200027FCA0406FFE284223586220A7FE2C2037FC242047FC442087FE +7669:010000803FFE2210221EBFA262442FBE2AA26ABEAFA2223E27224ABE52948222 +766A:00803FFE2010237CAE10627C2F1022FE6644A77C2AC42A7C3244427C42288244 +766B:00803FFE24003FBEA4086F10293E2F22692AAF2A292A2F2A292A7F94491290A2 +766C:010000803FFE24002722A914723E2F882A886F9CAA882F88203E554855488008 +766D:00803FFE20002FBEA8A26FBE28A22FBE68A2AFBE251428A22FFE431040E08F1C +766E:00803FFE20042EF8AA546AFE2C102AFE6A04AAFC2A042EFC282049544A4A8838 +766F:00801FFE14A417BC94A457BC14A437BC512093FE122017FC2A2023FC422083FE +7670:00803FFE20002AA8B5246ABE2F6829686FBEA0282FA82ABE2FA8482848BE87A0 +7671:00803FFE25182F94A53E672822682FBE6AA8AFA8223E2FA822285FBE452088A0 +7672:00803FFE22003FBEA2086F9028BE2FA268BEAFA228BE2FA228BE5FC0491490A2 +7673:00803FFE244427FCA4446FFE2AAA2FBE6AAAAFBE220827F020C44FFE424884C4 +7674:00803FFE24442AEAAE0E64E42AAA2EEE6000A7FC204027FC20404FFE404080C0 +7675:00803FFE244428E8AE0E64E42A0A2EEE60A0AAEA20402FFE28A24912484288A6 +7676:00887C9004A004C0448224442448085008201020101020084004800200000000 +7677:00907EA002444448283010102008DFF6010001000100FFFE0100010001000100 +7678:00907EA002444448283010102008CFE6010001007FFC010002C0042018106008 +7679:00907EA002444448283010102FE8C8260820101C2FE000200C4003800C707008 +767A:00907EA002444448283010102008DFF6044004407FFC0440084008441044603C +767B:00803E9002A424481450082017D02008DFF6101010101FF0082004407FFC0000 +767C:00907EA00444282810103CF8C49604903D0C200041F87C0804D0042028501188 +767D:0100020004003FF820082008200820083FF8200820082008200820083FF82008 +767E:0000FFFE0100020004003FF82008200820083FF820082008200820083FF82008 +767F:0820082010203F2021202120212021203F2021202120212221223F22211E0000 +7680:020004003FF8200820083FF8200820083FF80000203823C03C04200420041FFC +7681:020004001FF0101010101FF0101010101FF001000100FFFE0100010001000100 +7682:010002001FF0101010101FF0101010101FF00200020003FCFE000204020401FC +7683:040008003FF8200820083FF8200820083FF8044004400440084408441044603C +7684:1040104020407E7C42844284430442447E2442244204420442047E0442280010 +7685:1000100021FC7D2445244524452445247DFC45004500450045027D0244FE0000 +7686:208020883CB020C020842C84317C02001FF0101010101FF0101010101FF01010 +7687:020004001FF010101FF010101FF000007FFC010001003FF801000100FFFE0000 +7688:1004100E20F07C80448044FC44A444A47CA444A844A8449045107D2846440082 +7689:1090109020907A904A924AD44A984A907A904A904A904A924AD27F124A0E0000 +768A:1020102020507C5044884524461244107DFC44044408448844507C2044100010 +768B:020004001FF010101FF010101FF002007FFC044009203118CFE6010001000100 +768C:1020102020207DFE44204420442045FC7C7044A844A8452445247E2244200020 +768D:020004001FF010101FF010101FF0200020F83E882088208826A8389000800080 +768E:1040102020207BFE4800488849044A0278884888485048204850788849040602 +768F:1084104820007CFC44484448444844487DFE44484448444844487C8844880108 +7690:020004001FF010101FF010101FF021081110092011102108FFFE010001000100 +7691:1020112421247D2445FC440045FC44047C0445FC4500450045027D0244FE0000 +7692:101010D82394789448904BFE48904894789448D84B98489048AA78CA4A860102 +7693:1020112021207DFC45204620442047FE7C00440045FC450445047D0445FC0104 +7694:100011FC21047DFC450445FC440044007DFC4420442047FE44207C2044200020 +7695:00000000FEFE1020102020407EFC4284428442847EFC4284428442847EFC4284 +7696:1040102023FE7A024C0449F8480048007BFE489048904890491279124A0E0400 +7697:100011FC212479244974492449FC4904797449544954497449047A044A140408 +7698:1020102023FE7C2045FC442047FE44007DFC450445FC450445FC7D0445140108 +7699:080C08F07E8018802CFE2A8848888888090804001FF010101FF010101FF01010 +769A:102011242124792449FC48004BFE480079FC4904490449FC488878504BFE0000 +769B:020004001FF010101FF010101FF0081010207EFC428442847EFC428442847EFC +769C:1020101021FE7C0044FC448444FC44007DFE4502457A454A457A7D02450A0104 +769D:102020207D2444A47CA844207DFE0050FE50105010507C5210521E92F08E4100 +769E:1020104021FC790449FC490449FC48407BFE488849244A224DFC782048200020 +769F:102013FE20207DFC442047FE440045FC7D0445FC450445FC45047DFC44880104 +76A0:1020122223FE7890488849FE4B104D1079FE4910491049FE4910791049FE0100 +76A1:1020104021FC7D0445FC450445FC44207D2444A84524442047FE7C2044200020 +76A2:1020102021FC78204BFE49084B9C490879884E3E48004BFE489078904912020E +76A3:108813FE2088780049FC48A848A84BFE78A848A849FC48204BFE782048200020 +76A4:103C13E0212478A84BFE48A849244A0279FC4924492449FC4924792449FC0104 +76A5:104011FC210479FC490449FC490449FC7820492448A8492448207BFE48200020 +76A6:1088110823C87A504BDE4A644BD4491478944FF4491449C849487A544B5404A2 +76A7:103C13C020447A2449084FFE4C424AA47A8A4C7A488048F849087A904860079E +76A8:02001FF010101FF010101FF020407EFC42847EFC42847EFC01003FF80100FFFE +76A9:100021FC7D0445FC7D0445FC7C200124FCA8102013FE7C9010901D12E212440E +76AA:1124117422587ADA4BFE49544ADA4BFE78A248204BFE487048A879244A220020 +76AB:1040102023FE7A504BFE4A524BFE4A007A944AD84A904AD24A8E7C004954022A +76AC:11FC102023FE7A224DAC482049AC489079FE4B204DFC492049FC792049FE0100 +76AD:101E13E0212278944BFE4A524BFE48047BC44A7E4BC44A544BCC7A844AD40348 +76AE:0080008000803FFC2084208820802FF02410241022202140208041404630980E +76AF:0800087C08107F1049104A1048107EFE4210421052104C1044104A1092102010 +76B0:08200820087E7F4249824A7A484A7E4A427A4242524A4C4444424A42923E2000 +76B1:201020103E1042FE84920894FE9002FC02A47EA402A802A80290FF2802440082 +76B2:0010FF10911010FEFE922094289048FC7EA408A408A80EA8F890492809440A82 +76B3:10101410121010FEFE921094109092FC54A410A438A854A89290112851442282 +76B4:10101010201044FEFE9228944490A2FC3CA444A444A8A8A81090292845448282 +76B5:241024107E1024FE2492FF9400907EFC42A442A47EA842A842907F2842440082 +76B6:10101010FE1038FE5492929410907CFC44A47CA444A87CA800901D28E1444282 +76B7:08100810FF1008FE08927E9400907EFC42A442A47EA842A824900F28F1444282 +76B8:0010FE10921010FEFE9210947C9054FC7CA454A47CA810A8FE90112811441282 +76B9:080008FE08927F1049FE4A10487C7E54427C4254527C4C1044FE4A1092102010 +76BA:40104010FE1022FEAA92FA94429094FC48A4FEA422A8AAA8FA90432894440882 +76BB:10101E1010107EFE52925C9472904EFC40A45CA454A85CA854905D2896443882 +76BC:1010FE1010107CFE0092FE9482907CFC00A47CA444A87CA8449029280F44F282 +76BD:1010FE100010FEFE8292BA94AA90FEFC00A47CA444A87CA844907D280044FE82 +76BE:1010FE1010107CFE0092FE94AA90FEFC44A47CA444A87CA844907D2828444482 +76BF:000000003FF82448244824482448244824482448244824482448FFFE00000000 +76C0:0100010001800140012001100108010001003FF82448244824482448FFFE0000 +76C1:00003FF008100820083C10041004201440083FF82448244824482448FFFE0000 +76C2:00003FF801000100FFFE010001000500020000003FF8244824482448FFFE0000 +76C3:00007FFC010003000570090C3102C10000003FF82448244824482448FFFE0000 +76C4:00007FF801083FF821003FFC01040114010800003FF8244824482448FFFE0000 +76C5:010001003FF82108210821083FF82108010001003FF8244824482448FFFE0000 +76C6:0440082010102FE8C4260420082010A0604000003FF8244824482448FFFE0000 +76C7:010001007FFC028004400A203118C00600003FF82448244824482448FFFE0000 +76C8:00003FF008100FA008BC128411042294444800003FF8244824482448FFFE0000 +76C9:00701F8001000100FFFE054009203118C0063FF82448244824482448FFFE0000 +76CA:101008200000FFFE000008201010200840043FF82448244824482448FFFE0000 +76CB:024002207FFC04000BF0112020C043301C0E00003FF8244824482448FFFE0000 +76CC:100010F83E884288A2A8149008841084207CC0003FF8244824482448FFFE0000 +76CD:010001003FF801000100FFFE040008201FF000103FF8244824482448FFFE0000 +76CE:010001001FF011101110FFFE02800C603018C0063FF8244824482448FFFE0000 +76CF:0240022003F87E0003FCFE10016003821C62E01E00003FF8244824482448FFFE +76D0:082008207F20082808240F22F020402000003FF82448244824482448FFFE0000 +76D1:04402440247C2440249024882508040000003FF82448244824482448FFFE0000 +76D2:010002800C603018CFE600001FF010101FF000003FF8244824482448FFFE0000 +76D3:100009FC402020200BFE10207020102010A000403FF8244824482448FFFE0000 +76D4:040004007FFC08401248125024A0411082080C0600003FF8244824482448FFFE +76D5:100009F0411025900550095071121112120E14003FF8244824482448FFFE0000 +76D6:082004407FFC010001003FF801000100FFFE000000003FF8244824482448FFFE +76D7:4080208009FC12042448E04020A023182C0600003FF8244824482448FFFE0000 +76D8:020004001FF011101090FFFE10101210215040203FF8244824482448FFFE0000 +76D9:012001107FFC01003FF821083FF821083FF8210800003FF824482448FFFE0000 +76DA:011001087FFC0100211811A007401920E118450602003FF824482448FFFE0000 +76DB:009000883FFC208020883E48225022244A54448C81043FF824482448FFFE0000 +76DC:0080208011FC820454482040E0A023182C0600003FF8244824482448FFFE0000 +76DD:3FF000101FF00010FFFE111009A005401930E50E02003FF824482448FFFE0000 +76DE:021002FC7F4000840764781C021002FC7F4000840764781C00003FF82448FFFE +76DF:00007CFC448444FC7C8444FC44847C84011402083FF8244824482448FFFE0000 +76E0:08000FE010201FC000407FFC0600192006C039B0068C398000003FF82448FFFE +76E1:01003FF80108FFFE01083FF801007FFC248842443FF8244824482448FFFE0000 +76E2:00207C28542455FE7C20545054507C88010402023FF8244824482448FFFE0000 +76E3:00003F2024203F3E21403F5024883F0800003FF82448244824482448FFFE0000 +76E4:10783E4822482A86FF7822482A2842104A2884463FF8244824482448FFFE0000 +76E5:1100611C4D444544759C49844944755C420400003FF8244824482448FFFE0000 +76E6:010006C01930E7CE0080FFFE04403FF8284837B820083FF800003FF82448FFFE +76E7:010001F801003FFC21042FE0210827F8249027F0249027F020004FF84948BFFE +76E8:0BFE104061FC090411FC610405FC090431FCC08801043FF824482448FFFE0000 +76E9:08207F20083EFF4422A47F280828FF10082808463FF8244824482448FFFE0000 +76EA:23F8120893F8420843F810002FFEE20027FC2924225404883FF824482448FFFE +76EB:010006C01830EFEE00001FF010107FFC04401FF014501BB010103FF82448FFFE +76EC:00407E7C48907E1042FE7E10487C48447E7C00003FF8244824482448FFFE0000 +76ED:102022207C3E0A447FA408247F2814287F1008287F4408823FF824482448FFFE +76EE:00003FF82008200820083FF82008200820083FF820082008200820083FF82008 +76EF:000000007BFE4820482078204820482078204820482048207820482000A00040 +76F0:000001FC7C20442044207C20442047FE7C204420442044207C20442000200020 +76F1:000001FC7C20442044207C20442047FE7C204420442044207C20442000A00040 +76F2:02000100FFFE1000100010001FF800001FF010101FF010101FF010101FF01010 +76F3:002000107C10440045FE7C80448044807C804480448044807C80448000FC0000 +76F4:010001007FFC01001FF0101010101FF010101FF010101FF010101010FFFE0000 +76F5:004000407C8044FE45007E0044FC44087C104420444044807D02450200FE0000 +76F6:000000007DFC440044007C0047FE44907C904490449044907D124512020E0400 +76F7:004000407C8044FC45047E04448444447C444414442444447D84440400280010 +76F8:080008FC08840884FE8408FC18841C842A842AFC488488840884088408FC0884 +76F9:0020002078204BFE4820792449244924792449FC4824482078224822001E0000 +76FA:0008001C7CE0448044807C8044FE44887C884488448844887D08450802080408 +76FB:00900090790849084A047C024BFC4880790049F8480848087808480800500020 +76FC:0010009078904888490879044A044DFA78884888488848887908490802280410 +76FD:002000207C2045FC44207C20442045FC7C204420442047FE7C20442000200020 +76FE:007C3F8020803FFC20802FF8280828082FF8280828082FF8480848088FF80808 +76FF:004000207C2047FE44887C88448844887C884450445044207C50448801040602 +7700:000000FC7C84448444847CFC448444847C8444FC448444847D04450402140408 +7701:010011101108212440C003000C003FF8D0081FF810081FF8100810081FF81008 +7702:0004001E7DF0451045107D10451045FE7D104510451045087D0A454A01860102 +7703:0000000079FC4800480078004BFE4820782048404840488879044BFE01020000 +7704:000003FE7C20442045207D3E452245227D2245FE440244027C02440200140008 +7705:0008001C79E04900490079FC49444944794449284928491079104A2802440482 +7706:004000207C2045FE44407C404440447C7C444444444444447C84448401280210 +7707:004000407840494849447A424A424C4878484848481048107820484001800600 +7708:0040004078404BFC4A447C484840484078A048A048A0492079224A22041E0800 +7709:00003FF8210821083FF820002FF8280828082FF828082FF8480848088FF80808 +770A:0008003C7DE0442044207C3C45E044207C20443E47E044207C2244220022001E +770B:00F87F0001003FF80200FFFE040008001FF028104FF088100FF008100FF00810 +770C:00000FF048104FF048104FF048104FF040007FFC010011101108210445040200 +770D:000001FE7D00450445447D28452845107D104528452845447D84450001FE0000 +770E:000001FC7800480048007BFE48204820792849244A244A227C22482000A00040 +770F:002000207C2045FC45247D24452445247D2447FE442044507C50448801040202 +7710:000000007BFE48204820782049204920793C4920492049207920492007FE0000 +7711:0010009078904910497E7A524B924892791249124A524BD278624822004A0084 +7712:002000207C2045FC45247D24452445FC7D244524452445FC7D24442000200020 +7713:00280024782448204BFE7A204A244A247A244A284A284A907B124A2A00460082 +7714:00007FFC444444447FFC01000920111021084104092011102108410401000100 +7715:002000207C50448845047E12442044407D884410442044447D88441000600380 +7716:000001FC7D04450445047D0445FC44507C504450445044927C924512020E0400 +7717:008000807D0045FC46047C0445E445247D24452445E445247C04440400280010 +7718:01000100FFFE01002288145008203018DFF610101FF010101FF010101FF01010 +7719:002000207C20444044487C8445FE44827C0044FC448444847C84448400FC0084 +771A:010011001FF821005FF00100FFFE00001FF010101FF010101FF010101FF01010 +771B:002000207C2045FC44207C20442047FE7C7044A844A845247D24462200200020 +771C:002000207C2047FE44207C20442045FC7C7044A844A845247D24462200200020 +771D:0040002078204BFE4A027C04480048007BFE4820482048207820482000A00040 +771E:20703F8420041FFC00000FF848084FF848084FF848084FF840007FFE10102008 +771F:010001007FFC01001FF010101FF010101FF010101FF01010FFFE082010102008 +7720:000001FC7D04450445047DFC452045207DFE4520452045107D12454A01860102 +7721:0004001E7DF0451045107D10451045FE7D104510451045087D0A454A01A60112 +7722:10001EF8228862A894920882307EC0001FF010101FF010101FF010101FF01010 +7723:002000207D20452045FC7D20462044207DFE4420445044507C88448801040202 +7724:000001FC7D04450445047DFC450045407D444548457045407D424642023E0400 +7725:088008882E9028E028842E84F07C00001FF010101FF010101FF010101FF01010 +7726:0090009078904A904A927AD44A984A907A904A904A904A927AD24F12020E0000 +7727:000001FC7C44444444447C44449444887D0044FC448444847C84448400FC0084 +7728:0008003C7BC04800484078204BFC4808781048204840488079004A80047E0000 +7729:0040002078204BFE48407840488849087BF048204840488879044BFC01040000 +772A:000001FE7C20442044207DFE452245227D52454A458A45027D024502010A0104 +772B:002000207D2444A444A87C2045FC44207C20442047FE44207C20442000200020 +772C:00900088788848804BFE78A048A048A478A44928492849327A224A62049E0800 +772D:002000207DFC442044207C2047FE44007C20442045FC44207C20442003FE0000 +772E:000001FE7D024502457A7D024502457A7D4A454A454A457A7D024502010A0104 +772F:00200020792448A448A8782048204BFE787048A848A8492479244A2200200020 +7730:000001FE7C20444044887D0445FE44227C20442045FE44207C20442003FE0000 +7731:002000207BFE482049FC782449FC492079FE4822482A48547850488801040202 +7732:000003FE7C88448844F87C88448844F87C884488448E47F87C08440800080008 +7733:004000407CFC450446887C50442044407C8045FC468444847C84448400FC0084 +7734:0080008079FC49044A0479E44924492479E44924492449E47904480400280010 +7735:002000207C7C448445487C30442044487D90443E444245A47C18441000600180 +7736:000001FE7D00450045FE7D104510457C7D104510451045FE7D00450001FE0000 +7737:0100111009203FF802007FFC082010102FE8C8260FE008200FE008200FE00820 +7738:00400040789049084BFC78244920492079FC4A2048204FFE7820482000200020 +7739:008800487C50440045FC7C20442044207FFE4420445044507C88448801040202 +773A:0090009078904A9249947898489049987A944C9248904890791249120212040E +773B:010400847C88440047FE7C20442045FC7C20442047FE44207C20442000200020 +773C:000003F87A084A084BF87A084A084BF87A444A484A304A207A104A8803060200 +773D:0004001E7DE0450045067D78455045507D524554454845487D44465402620440 +773E:00007FFC444444447FFC000000FC7F0011101110111029282528454481820100 +773F:00400020781049E0482278344BB848B078A848A8492849247A244C2200A00040 +7740:082004407FFC01003FF80200FFFE04000FF018102FF0C8100FF008100FF00810 +7741:0100010079F04A104C207BF8484848487BFE484848484BF87848484001400080 +7742:0208050808881248050808883FF820002FF828082FF828082FF848084FF88808 +7743:00400040788849044BFE7802488849447A4248F849884A507820485001880606 +7744:002001247CA444A844207DFC450445047DFC4504450445FC7D04450401140108 +7745:000001FC7D0445FC45047DFC440044007DFC4420442047FE7C20442000200020 +7746:004000207BFE4A024C0479F8480048007BFE48904890489079124912020E0400 +7747:0108008878904BFC482478244BFC4A207A204BFE486248A2792A4A2404200020 +7748:000001FC7D04450445047DFC440044007DFE4420442045FC7C20442003FE0000 +7749:0020002079244924492479244AAA4C727820482049FC48207820482003FE0000 +774A:000000FC7C84448444FC7C0045FE45027D0245FE450245027DFE4502010A0104 +774B:001000D87B94489448907BFE48904894789448D84B98489078AA48CA02860102 +774C:0080008079F84A084C107BFC4A444A447A444BFC48A048A079224922021E0400 +774D:000003F87A084A084BF87A084A084BF87A084A084BF8492079204A220422181E +774E:01840068783048C84B0478404BFE48A079204BFC4D2449247934492800200020 +774F:000003FE7A224A224A227BFE4A224A627A724AAA4B224A227A224A0203FE0202 +7750:0020002078204BFE4820792448A448A87BFE487048A848A879244A2204200020 +7751:0040004078A048A049107A084DF64800788848484A4849507910482007FE0000 +7752:0020012279224A24485078884B0448227820492449244A287850488801040602 +7753:0090009078904BFC4A947A944A944BFC7A944A944A944FFE7800489001080204 +7754:002000207850488849047AFA480049FC7954495449FC4954795449540104010C +7755:004000207BFE4A024D04790049DE4A527A524B524C9A4894791049120212040E +7756:0020002079FC482048207BFE488849447A4248F849884A507820485001880606 +7757:000001F87908490849F87908490849F8788049FC4A544C9479244A4400940108 +7758:00003FF8244824483FF80000FFFE00001FF010101FF003040C881870EA180C06 +7759:004000207BFC4A044A047BFC4A004A287A244BFE4A204A507A504C8805040A02 +775A:000003FE7A104A104AFE7A104A104BFE7A004A104A104AFE7A104C1005FE0800 +775B:002000207BFE482049FC78204BFE480079FC490449FC490479FC490401140108 +775C:003C07C07A44492848007BF8484848487FFE484848484BF87848484001400080 +775D:0C8070FC1124FE24384454A8911000001FF010101FF010101FF010101FF01010 +775E:0020002078204BFE48207924492449247AAA487048A848A879244A2204200020 +775F:004000207BFE48004888788849544A22780048204BFE48207820482000200020 +7760:0020012478A8482049FC78404BFE488879044AFA4C88488878A848920082007E +7761:00100078F3C090409040F7FC92489248F7FE9248924897FCF040904007FC0000 +7762:00A00090788049FE49107B104DFC4910791049FC49104910791049FE01000100 +7763:08000EFC0844FF4408282A10492808441FF210101FF010101FF010101FF01010 +7764:000001FC7924492449FC7924492449FC780048004BFE48887888488801080208 +7765:004000807BFC4A244A247BFC4A244A447BFC489049104FFE7810481000100010 +7766:0020002079FC482048207BFE488849047A22482049FC48207820482003FE0000 +7767:001C03E07A204BFE4A207A924B0A4A0679FC4904490449FC7904490401FC0104 +7768:000000407B9C4A044A047B9C4A044A047BFC489048904890789049120212040E +7769:000001F87808480849F8780848084BFE78204A22497448A879244A2200A00040 +776A:00007FFC44447FFC01003FF80100FFFE082004403FF80100FFFE010001000100 +776B:002000207BFE482049FC78244BFE482479FC48204920493E79204AA0027E0400 +776C:0008003C7BC048444A247928490048207BFE487048A848A879244A2204200020 +776D:000001FC792449244974792449FC4904797449544954497479044A0402140408 +776E:004000A079104A084DF678004BC44A547A544BD44A544A547BD44A44025402C8 +776F:00207E20427E7EA448247F284810652843461FF010101FF010101FF010101FF0 +7770:008800887BFE488848A878204BFE4840788048FC49844A847884488400FC0084 +7771:000003DE7A424A424A427BDE4A004A3E7BD24A124A144BD47A084A1402240242 +7772:000001FC790449FC490479FC4820492079FE4A20482049FC7820482003FE0000 +7773:002000207BFE485048887B2649FC482078204BFE4800482079FC4820002003FE +7774:000003FE7A2248204BFE782049FC492479FC492449FC48207BFE482000200020 +7775:012801247BA4492049207FFE482048247BA44AA84AA84A907B92482A00460082 +7776:004000407BFC484049F878804BFC49107A084DF64910491079F04910011001F0 +7777:00200020F0FC9E2493FEF22494FC9420FEFC922092209BFEF420962009FE1000 +7778:000003FC7A244A244BFC7A004AFC4A847A844AFC4A844AFC7A844A8404FC0884 +7779:004000447BF4484848507FFE4840488079FC4B044D0449FC7904490401FC0104 +777A:008000BC7884490849FE7B204D20497C7990491049FE49107928492801440182 +777B:004000207BFE4A024C0479FC480049FC790449FC490449FC7904480003FE0000 +777C:000001FC7904490449FC7904490449FC78004BFE48204920793C492002A0047E +777D:001003D478584A52498C788849044AFA782048204BFE48207850488801040202 +777E:040008007FFC44447FFC01003FF80100FFFE082004403FF80100FFFE01000100 +777F:010001F801007FFE40029FF4092032900C603FF8D0161FF010101FF010101FF0 +7780:7E20243E1848FFA829104A28984600001FF010101FF010101FF010101FF01010 +7781:000003FC7A044BFC4A047BFC4A044BFC785048484FFE484078A0491002080C06 +7782:022807243C24242024FE3F2024202F3C29342F5429542F54298849884F148922 +7783:0008001C79F04910491079FE4910497C7944497C4944497C79444A44027C0444 +7784:008800887BFE48884888780049FC49247924492449FC49247924492401FC0104 +7785:008801C8F7089108912AF12A97AC9148F308938895549514F914912401240142 +7786:0020002079FC492449FC78204FFE480079FC4904492449247924485000880304 +7787:001000927A5249544910787E48104B38795449924910491079104A80047E0000 +7788:0090008879044A424C8879FC480448007BDE48424A52494A7A524842014A0084 +7789:1000FE7810487C480048FE8682007CFC00447C4444287C2844107C2844447D82 +778A:002000107BFE4A204AFC7A244BFE4A247AFC4A204AFC4A847A844C8404FC0884 +778B:002000207BFE482049FC790449FC490479FC490449FC49047BFE488801040202 +778C:0020002079FC482048207BFE488049047BFE48024BFC4A947A944A9407FE0000 +778D:0140065CF4449444975CF444944497FCF04097FC92089110F0A0904001B00E0E +778E:004000207BFE4A024C2479FC482049FC78204BFE482049FC7904490401FC0104 +778F:7FFC44447FFC01001FF001007FFC00001FF010101FF0048808503820CB180C06 +7790:1FF810081FF810081FF810081FF800007E7E42427E7E42427E7E42427E7E4242 +7791:000003FE7A02480049FC790449FC490479FC484048204BFE7800488801040202 +7792:01080108F7FE91089000F7FE90909090F7FE94929492956AF6469402040A0404 +7793:02020122782A4FEA482A7BAA482A4BAA782A4BAA4AAA4AAA7BAA4AAA00420082 +7794:002003FE782049FC48207BFE480049FC790449FC490449FC790449FC00880104 +7795:002001FC788848504BFE780049FC490479FC490449FC48207BFE482000200020 +7796:7F7848485F4C64805F784A4851307F4C00001FF010101FF010101FF010101FF0 +7797:0040008079FC490449FC790449FC490079FE490049FE48027AAA4AAA0202000C +7798:000003FE7A004A7C4A447A444A7C4A007AEE4AAA4AAA4AAA7AEE4A0003FE0000 +7799:008800887BFE4888480079FC490449FC790449FC48204BFE7850488801040202 +779A:004000207BFE4A02480079FC482049FC792449FC492449FC7800488801040202 +779B:01240124F22494249954F14A92929610FA109250925C9250F25092B0029E0300 +779C:002001FC79244BFE492479FC482049FC792449FC48404BFE788849D00070038C +779D:004000207BFE480049547924495449FC78204BFE4A424A927AFA4A0A02020206 +779E:008800887BFE4888488878F848204BFE7A224B324AAA4B767A224A22022A0224 +779F:000003FE785049FC4954795449FC480079FC48004BFE482078A8492402A20040 +77A0:0020012478A84BFE4A0278F84888488878F84820482049FC7820482003FE0000 +77A1:0200027CF2449744927CF2449244977CF2449244927C9228F528954A084A1086 +77A2:0820FFFE08203FF824483FF800007FFE40029FF410101FF010101FF010101FF0 +77A3:0020002079FC492449FC78204BFE4A227BFE4820484048247AA24A8A04780000 +77A4:00007BDE4A524BDE4A527BDE4A024AFA7A224A724A224A227AFA4A02020A0204 +77A5:082049202A3E7F4849485DA86B10492843461FF010101FF010101FF010101FF0 +77A6:002003FE782049FC480079FC490449FC78884BFE480049FC7904490401FC0104 +77A7:00A0009079FE49104B107DFE4910491079FE4910491049FE79004AA402520452 +77A8:00A004A4F2A890A097FCF11090A097FCF04093F8904097FCF0A0911002080C06 +77A9:000007FCF40497FC9400F5FC942095FCF52495FC942097FEF62A96FA0A0A1206 +77AA:002007A4F0A892929114F20895F49802F3F89208920893F8F20891100FFE0000 +77AB:000003FE78504BFE4A527BFE480049FC790449FC490449FC78204BFE00200020 +77AC:003C07C0F04492249108F7FE94029A08F20893BE94889AA8F13E920804080808 +77AD:00400040F7FC90A09514F20897FC9A0AF3F8920893F89040F248944409440080 +77AE:02080108F7C89210949EFFD490649794F494979494949788F488949404A405C2 +77AF:03DE7A524BDE4A524BDE7A024AF24A927AF24A924AF24A927A924B3202020206 +77B0:00080788F08891109FDEF49494A49794F4949794949494C8F7889C9400A400C2 +77B1:008803FE7888480049FC78A848A84BFE78A848A849FC48207BFE482000200020 +77B2:000003FC784848304BFE785248944B5078204BFE4A524A8A7B764A5202720206 +77B3:002001FC788848504BFE780049FC492479FC492449FC482079FC482003FE0000 +77B4:0080008079FE4B544D5479544BFE4954795449544FFE48007954492A022A0000 +77B5:00400248F15097FC9150F24894449208F20893BE94889AA8F13E920804080808 +77B6:002001FC792449FC48207BFE480049FC790449FC490449FC790449FC00880104 +77B7:00007BDE4A524BDE4A527BDE4A024AFA7A8A4AFA4A8A4AFA7A8A4A02020A0204 +77B8:008803FE7888480049487BFE49484978790049FC48204BFE787048A803260020 +77B9:003C03C0F04492249108F7FE944292A4F28A947A908090F8F10892900060079E +77BA:004000A0F3189DF69000F7FC955494E4F7FC900093F89208F3F8920803F80208 +77BB:010001F87A084FFE4A887B244BFE4A007AFC4A004AFC4A007AFC4C8404FC0884 +77BC:0040004078A049104A087DF6480048007BB84AA84AA84BB87910491002A80444 +77BD:0810FF7E08107E7C42447E282418FEE600001FF010101FF010101FF010101FF0 +77BE:00003EF822883EF822883EF822883EF801007FFC482410102FE8010001007FFC +77BF:3EF822883EF822883EF822883EF808801FFC30805FF890801FF810801FFC1000 +77C0:028802A8F6A89BF0901EF22495D49C14F41495D495549548F568955406140422 +77C1:00C80708F12A912C9FC8F10893889554F914912290409024F522950A090800F8 +77C2:01FC0104790449FC48007BDE4A524A527BDE48204BFE487078A8492406220020 +77C3:004000207BFE4A224954794A4A3A480079FC49544BFE480079FC482000A00040 +77C4:001C01E078204BFE482079FC49AC497479FC482049FC48207BFE48000154022A +77C5:000003DE78424A52494A7A52489049087BFE4D1049FE491079FE491001FE0100 +77C6:008803FE78A8489049FE7B2049FC492079FC492049FE49007BFC48880070038E +77C7:008803FE78884BFE4A0279FC48004BFE784048A24B5448B87B54489203500020 +77C8:004001FC790449FC490479FC48204BFE7A8A49244BFE488078FC488401140208 +77C9:004000207BFE4A0249FC79484A5049FC7B0449FC490449FC790449FC00880104 +77CA:01080110F23E922294BEF722913E9208F4BE97AA902A90AAF56A952E04080008 +77CB:000003FE7A484BFE4A487AFC4AA44AFC7AA44AFC4A204BFE7B2A4D7A050A0906 +77CC:002000107BFE4A444AFE7A444BFE4A107AFE4A924AFE4A927AFE4A0002440482 +77CD:7CF844887CF844887CF809001FF831005FF091001FFC10003FF0082007C0F83E +77CE:010001F87A084FFE4A627A9249FC490479FC490449FC488079F84A880070038E +77CF:004001FC79244994494C792449FC48207BFE4A8A49244BFE788048FC0104020C +77D0:01FC78204BFE4A224DAC782049AC489079FE4B204DFC492079FC492001FE0100 +77D1:0040007C78404BFC4A447BF04A444AFC7AA84AF84AA84AF87A004DFC05540BFE +77D2:010807FE79084BFC4A947BFC48004FFE7C0249F8490849F8790849F8010801F8 +77D3:011078904BDE48104A5E79824BDE48107BDE4A504BDE4A507BDE4A50025202CE +77D4:00887BFE48884BDE4A527BDE48A0489079FE49204BFC4D2079FC492001FE0100 +77D5:21084FD2F03C23884812FBBE0280ABAA00001FF010101FF010101FF010101FF0 +77D6:03DE78004BDE4A524B5A7A5248204BFE7A504BFE4A524BFE7A924ADC029204CE +77D7:01003FF801000FE00820092009207FFC08207EFC08203EF822882AA82AA8FFFE +77D8:02480150F7FC940491F0F11097FC9554F4E497FC904097FCF0409FFE02A40452 +77D9:0FBE08A2EFBEA8A2AFBEE802AB92A892EFDEAAAAABCAAAAAEB92AAD20FAA08C4 +77DA:03FE02027BFE4A924A547A924AFE4AAA7AFE4B224AFA4AAA7AFA4A2205FA0004 +77DB:00001FF000100220014000807FFE018202840480088010802080C08002800100 +77DC:00207E200250245018880944FE220A20180019FC280448088808081028101020 +77DD:00207C200450285010880924FE121A1029FC2804480848888850082028101010 +77DE:1FF0022001407FFC04841888628001003FF82448282837D82448244827C82018 +77DF:00107C9204522854101008FEFE821A8228FE2882488248FE88820882288A1084 +77E0:00487C48044829FE10480848FFFE1A0028FC2884488448FC8884088428FC1084 +77E1:03DEFA520BDE525223DE10A0FDFE372035FC512051FE500091FC10885070278E +77E2:0800080008001FF81100210041000100FFFE010002800280044008203018C006 +77E3:02000400082010103FF8080808001FF0210001007FFC0280044008203018C006 +77E4:00407C40048004FC05207E204020402043FE7C20045004500488048829041202 +77E5:20002000207C7E444844884408440844FF44084414441444227C224442008000 +77E6:080008001FE020204040BFFC240024002FF8308020803FFC414042208410180C +77E7:200421E43C245024902411E41104FF04110411E4102428242424442441448084 +77E8:2008203C21E07C205020902013FEFC2010201050105028502488448841048202 +77E9:200021FE3D005100910011FC1104FF041104110411FC29002500450041FE8000 +77EA:2010202020FC7C8450A490941094FDFE108410A4109428942484450441148208 +77EB:2008203C21E07C20502093FE1050FC881104128A108828882488450841088208 +77EC:2020202021247D245124912412AAFC721020102011FC28202420442043FE8000 +77ED:200021FE3C00500090FC10841084FE8410FC1000108428442448440041FE8000 +77EE:201C21E03C20502093FE10A81124FE42104013FE1088290824D0443040488184 +77EF:201821E03C4053FE908811741252FE70100011FC11042974255445744104810C +77F0:210420883C0053FE922212AA1272FE2213FE100011FC290425FC450441FC8104 +77F1:208823FE20A87C9051FE932011FCFD2011FC112011FE290027FC44884070838E +77F2:200023FE42527A52A3FE2110225223DCF81223CE224023D2525C4BD04A5282CE +77F3:0000FFFE020002000400040008000FF81808280848088808080808080FF80808 +77F4:00000000FEFE1010101020103E1062106210A210221022103E10221000500020 +77F5:00040004FE041044104420443E4462446244A244224422043E04220400140008 +77F6:000001F0F9102110211041107910C91049104910491049127A124212040E0800 +77F7:000001FCFC041008101020203C2067FE6420A420242024203C20242020A00040 +77F8:000001FCFC201020102020203C2067FE6420A420242024203C20242020200020 +77F9:00000000FDFC1090109020903C9064906490A490249024923C922492210E0200 +77FA:0008003CFDE01020102020203C20643E65E0A420242024223C222422201E0000 +77FB:00400040FE8010FE110022003CF86410A4202440244024823D02250200FE0000 +77FC:00000000FDFC1020102020203C2064206420A420242024203C20242023FE0000 +77FD:00400040FC40107E108220823D4266246414A408240824103C20244020800300 +77FE:000001F0F9102110211041107990C95049504910491049127A124212040E0800 +77FF:00200010FC1010FE108020803C8064806480A480248024803C80250021000200 +7800:000001F8FC101020104020803DFE64926492A492251225223E22244220940108 +7801:000001F8FC081008108820883C8864FE6402A402240225FA3C02240220140008 +7802:00200020FC2010A810A420A23D2265206624A424242824083C10242020C00300 +7803:000000FCFC84108410A420943C94648465FEA484248424843C84250421140208 +7804:00200020FC2011FC102420243C24642465FEA420245024503C88248821040202 +7805:00200020FC201020103221B23CB464A864A8A4A8252425243E22242020A00040 +7806:00200020FC20102011FC20203C20642067FEA420245024503C88248821040202 +7807:00400020FC2013FE108820883C8864886488A450245024203C50248821040602 +7808:000001FEFD001100117821483D4865486548A568255025423D422542223E0400 +7809:010001007FFC01003FF801007FFC01007FFC040008003FF0C81008100FF00810 +780A:00400020FC0011FC100020003CF064906490A490249024923C922512210E0200 +780B:00100010FC101090109020903C9E64906490A490249024903C90249023FE0000 +780C:00000100F97E21122112411279D24F12C91249124952499279224822004A0084 +780D:00400040FC40107C108420883D2064206420A450245024503C88248821040202 +780E:00200020FC501050108821043E0264886488A488248824883C88250821080208 +780F:00100050FC501050108820883D0466FA6448A448244824483C88248821280210 +7810:000003FCF884208820884090789CC88449444944492849287A10422804440182 +7811:000003FCF8102110211041107A10CBFE48304850489049107A10441000500020 +7812:00100110FD101112111221143DD865106510A510251025123D522592210E0000 +7813:000000F8FC881088108821063E0065FC6484A484244824503C20245020880306 +7814:000001FCFC881088108820883C8867FE6488A488248824883C88250821080208 +7815:00400040FDF810481088208A3D0A66266420A42027FE24203C20242020200020 +7816:00200020FC2011FC102020403DFE64406480A5FC240424883C50242020100010 +7817:00400040FC4013FE108020A03D2065FC6420A420242027FE3C20242020200020 +7818:00200020FC2013FE102021243D2465246524A5FC242424203C222422201E0000 +7819:00000000FBFC2100210041F079104910C9904A504A504A107A124A920312020E +781A:000001FCFD041104112421243D2465246524A554245024903C9025122212040E +781B:00200020FC501050108821443E2264206400A5FC240424083C08241020100020 +781C:000003F8FA082208232842A87AA8CA484A484AA84AA84B2A7C0A440A08061002 +781D:00200020FC2011FC102020203C2065FE6420A420244024483C8425FE20820000 +781E:00200020FC2013FE102020203C2065FC6470A4A824A825243D24262220200020 +781F:00800080FC8010FE114021403E40647C6440A4402440247E3C40244020400040 +7820:000000F8FC881088108820F83C8864886488A4F8248824883C88248823FE0000 +7821:00000000FDFC1020102020203C20642065FCA420242824243C24242023FE0000 +7822:00000000FDFE1008100821E83D2865286528A52825E825283C08240820280010 +7823:00200010FC1011FE110222043C8064886490A4A024C024823C822482207E0000 +7824:00800080FCFE1100122021203D2C657467A4A524253425283D22250220FE0000 +7825:0004001EFDF01110111021103D1065FE6510A510251025083D0A254A21A60112 +7826:088008882E9028E028842E84F07C00007FFC040008003FF0C81008100FF00810 +7827:00200020FC201020103E20203C20642065FCA504250425043D04250421FC0104 +7828:00400020FDFC1104110421FC3D006500657CA508251025203D422682227E0400 +7829:00900090F89023FC209440947BFC4A90CA904BFE48924892791A491402100410 +782A:000000FCFC8410A4109420843C8467FE6504A544252425043DFE240420280010 +782B:00400020FC0013FE102020203C20642065FCA420242024203C20242023FE0000 +782C:00400020FC20100011FE20003C0464846484A448244824483C50241023FE0000 +782D:0004001EFDE01000102020103DFE64046408A410242024403C802540223E0000 +782E:10001000FEFC2244642818102428C2C60000FFFE08001FF82808C8080FF80808 +782F:00200020FD2010A0103221B23CB464A864A8A4A8252425243E22242020A00040 +7830:000001FCFC201020112420A43CA8642067FEA420242024203C20242020200020 +7831:00200020FC501050108821243E12641065FCA404240824883C50242020100010 +7832:00800080FDFC1104120425F43D1465146514A5F4250425283D12250220FE0000 +7833:00000000FEFE1020102020403E7C62C462C4A3442244224422443E7C22440000 +7834:00100010FC1011FE111221143D1065FC6544A544252825283D10262822440482 +7835:00200020FC20102011FE20203C70647064A8A4A8252426FA3C20242020200020 +7836:00200020FC4011FC110421043D04650465FCA504250425043D04250421FC0104 +7837:00200020FC2011FC112421243D2465FC6524A524252425FC3D24242020200020 +7838:000003FEFA102210221042FE7A924A92CA924A924A9A4A947A104A1003FE0000 +7839:01100110FBFC2110211040007A08CA084910491048A0484078A0411002080C06 +783A:000001FEFD001100110021FE3D206520653CA524252425243D24224402540488 +783B:04400420FFFC0910116021844F0480FC0000FFFE08001FF82808C8080FF80808 +783C:00200020FC501050108821043E02640065FCA420242024203C20242023FE0000 +783D:000001FCFD241124112421FC3D2465246524A5FC252425243D2425242104020C +783E:0008001CFDE01100112021203D2065FE6420A42024A824A43D22262220A00040 +783F:00200010F81021FE2100411079104910C9104920492849247A444AFE04420800 +7840:00200020FD241124112421243DFC64206420A524252425243D24252421FC0004 +7841:000001FCFC081010103020483C8467026400A5FC242024203C20242023FE0000 +7842:00200020FC501088110422023DFC64206420A42025FC24203C20242023FE0000 +7843:00200120FD2011FC112022203C2067FE6470A4A824A825243D24262220200020 +7844:00200020FD2410A410A820203DFE64906490A490249024923D122512220E0400 +7845:00200020F9FC2020202040207BFE4800C820482049FC48207820482003FE0000 +7846:00200020FC501050108821043EFA64006400A4F8248824883C88248820F80088 +7847:00200020FC4011FC110421043D9465546524A524255425943D04250421FC0104 +7848:00200020FC2013FE102020203DFC64006400A5FC250425043D04250421FC0104 +7849:00200020FDFC102413FE202421FC7C206420A5FC2420242027FE3C2024200020 +784A:00400040FCFC1104120821FE3D00657C6544A544255425483D422542213E0200 +784B:00200010FC1013FE102020423C8465F86410A42224C427083C10242820C40302 +784C:00400040FC781088115020203C5064886506A4F8248824883C88248820F80088 +784D:000001F8FD08110811F821083D0865F86544A548253025203D10254821860100 +784E:000207E2FA42224A224A424A7A4A4FEACA4A4A4A4A4A4A4A7A424C42044A0844 +784F:000001DCFC881088108820883C8867DE6488A488248824883C88250821080208 +7850:000001FEFD021102117A21023D02657A654AA54A254A257A3D022502210A0104 +7851:01040084FC88100013FE20883C8864886488A7FE248824883D08250822080408 +7852:000003FEFC50105011FC21543D5465546554A554258C25043D04250421FC0104 +7853:00400040FC4411F41048205023FE7C406480A584269824E024823C82247E0000 +7854:00880088FC88108813FE20883C8864886488A7FE240024883C84250422020402 +7855:000003FEFC20104011FC21043D0465246524A524252425443C50248821040204 +7856:00200020FC2011FC102021243CA464A86420A7FE245024503C88248821040202 +7857:00800080F8BC23C02050402478D44B0CC8004BFE4890489079124912020E0400 +7858:00000000FDFC1104110421743D5465546554A554257425043D0425FC21040000 +7859:00200124FD24112411FC20003DFC64046404A5FC250025003D02250220FE0000 +785A:0008003CFDE01020102023FE3C5064886504A68A248824883C88250821080208 +785B:00400020F82027FE2090409078904A94CA924A924C9248907910491002500420 +785C:000001FEFC001092112422483D2464926400A5FE242024203C20242023FE0000 +785D:00200124FCA410A8102021FC3D04650465FCA504250425FC3D04250421140108 +785E:00200120FD2011FC112022203C2067FE6400A40025FC25043D04250421FC0104 +785F:0004000EFBB8208820884128792E4BA8C8A84AA84AA8493E79004A80047E0800 +7860:00400020FDFC1104110421FC3D04650465FCA520252225143D08254421820100 +7861:00400020FBFE2202244440407BFE4840C8904890491049207A244A4204FE0842 +7862:00200020FC501088110422FA3C20642067FEA420252825243E22242220A00040 +7863:00200022FDFA1024102423FE3C10642065FCA488251026FE3C10241020500020 +7864:00200020FC2013FE102020203D2465246524A6AA242024503C50248821040202 +7865:00900088FC8013FE10A020A83CB064A464A8A4B02524252A3D32222202DE0400 +7866:000003FEFC20102011FC20203C2067FE6488A48827FE24883C88250821080208 +7867:000001F8FC0810D0102021FC3D24652465FCA524252425FC3D2425242124010C +7868:00200020FDFE102011FC21243D2465FC6524A52425FC24203DFE242020200020 +7869:080C08F07E8008800EFE7888088829081208FFFE08001FF82808C8080FF80808 +786A:001000D8FB942094209043FE78904894C89448D84B98489078AA48CA02860102 +786B:00400020FBFC2040209041087BFC4804C9504950495049507A504A520452080E +786C:000001FEFC20102011FC21243D2465FC6524A52425FC25203CA0244020B0030E +786D:00480048FDFE1048104820203C1065FE6480A480248024803C80248020FC0000 +786E:00400040FC7C1084110822FE3C92649264FEA492249224FE3C922512210A0204 +786F:000001F8FD08110811F821083D0865F86508A50825F824903C9021120212040E +7870:1020082040A824A4092A723010C017000000FFFE08001FF82808C8080FF80808 +7871:000001FCFD241124112421FC3D2465646574A5AC252425243D24250421FC0104 +7872:00000050FC481084112420203C5064886506A6F8248824883C88248820F80088 +7873:00200020F9FC2020202040207BFE4848C848494C494A4A4A7888488801280210 +7874:00880088FDFE1088108820503C5064946594A698249024B23CD22492208E0080 +7875:00200020FC3E1020102021FE3D02654A652AA5122512252A3D4A250221FE0102 +7876:00200124FD24112411FC20203C5064886544A622242025F83C08241020100020 +7877:00400040F8A020A0211042087DF64800C88848484A4849507910482007FE0000 +7878:00200124FD24112411FC20003DFE6500657CA510251025FE3D10221002100410 +7879:02080228F22822282FA442447254D69257105AA05A205228724452FC02440200 +787A:000001FEFC20104010A221123C3465586498A554243424523C90251020500020 +787B:00007EFC48447E4442287E1048287EC60000FFFE08001FF82808C8080FF80808 +787C:000003DEFA522252225243DE7A524A52CA524BDE4A524A527A524A52055208A6 +787D:00400080FBFC2110224844467BF84A48CA484BF84A484A487BF848420042003E +787E:0008003CFDE0102013FE20A83CA864A867FEA4A824A827FE3C20242021FC0000 +787F:00400020F82023FE2202449479084A04C80049FC482048207820482007FE0000 +7880:00400040FCF81108101021FC3C24642467FEA424242425FC3C24242020A00040 +7881:08207FFC08200FE008200FE00820FFFE10103FF8C4060FE0182068200FE00820 +7882:00400020FBFE2202200041FC78004800CBFE4820492849247A224C2200A00040 +7883:00200020FBFE202021FC40207BFE4800C9FC490449FC490479FC490401140108 +7884:01100110F910211027BC411079104B38CBB84D544D5449927910491001100110 +7885:000003FEFA02221A22E242227A224BFECA224A724AAA4B267A224A2203FE0202 +7886:202013FC82244BF812882450E470298C2000FFFE08001FF82808C8080FF80808 +7887:00400020FBFE2202240440007BFE4820C8204920493C49207AA04A60043E0800 +7888:001C03E0FA2023FE222042927B0A4A06C9FC4904490449FC7904490401FC0104 +7889:000001FCFD241124117421243DFC65046574A554255425743D04220402140408 +788A:00480044FC5E11E0102820123C6A65966448A45E25E024243C282412206A0186 +788B:00200124FD24112411FC20003DFE640865E8A528252825E83D28240820280010 +788C:000001F8F808200821F8400878084BFEC8204A22497448A879244A2200A00040 +788D:000001F8FD0811F8110821F83C0065FC6410A7FE241025103C90241020500020 +788E:00400020FDFE1000108820883D5466226400A42027FE24203C20242020200020 +788F:00480048FC4811FE104820483DFE640064FCA484248424FC3C84248420FC0084 +7890:00200020F9FC2020202043FE78884944CA4248F849884A507820485001880606 +7891:00400080FDFC1124112421FC3D24654465FCA490251027FE3C10241020100010 +7892:00200020FC501088110422023CF864206420A5FC242025243CA424A823FE0000 +7893:00500048FC8010FE119022903CFC64906490A4FC249024903C9024FE20800080 +7894:0008000CFCEA100A100821FE3C4864486548A568254825483D4A256A23860102 +7895:00200020FDFC10501088210423FE7C0865E8A528252825E825283C0824280010 +7896:00200020FC501088110422FA3C0065FC6554A55425FC25543D5425542104010C +7897:00400020FBFE22022504410079DE4A52CA524B524C9A4894791049120212040E +7898:00500050FC5011FC115421543D5465FC6554A554255427FE3C00248821040202 +7899:000003FEFA02228A225243FE7A224A22CAAA4AAA4AAA4AFA7A024A02020A0204 +789A:00400020FDFC1000110820903C0067FE6400A40025FC25043D04250421FC0104 +789B:00200020FBFE202021FC40207BFE4800C9FC4904492449247924485000880304 +789C:00800090F90823FC204047FE79104A48CC864B10482048C47B08483000C00700 +789D:000003FEFC20104011FC21543D5465546554A52C242027FE3C50248821040202 +789E:00001FF010101FF000007C7C44447C7C0000FFFE08001FF82808C8080FF80808 +789F:00900290FA9027FE229042907AF0CA004BFC48404FFE48E0795042480C460040 +78A0:00400020FBFE200021FC410479FC4800CBFE4A0249FC48207820482000A00040 +78A1:002001FEFC2010FC102021FE3C0064FC64A4A49425FE24A43D1425FE20040018 +78A2:000000FCFC84108410F420943C9465FE6502A57A254A254A3D7A2502210A0104 +78A3:000001FCFD0411FC110421FC3C8065FE6622A522255225023DFA240220140008 +78A4:00880088FBFE208820A8402079FC4924C92449244BFE48207850488801040202 +78A5:00800040FBFC2204220443FC7A00CA004BFC4B544B544DFC7D5445540944010C +78A6:00400020FBFE2202208040F879084A90C86049984E0649F87908490801F80108 +78A7:0020FE4010FC7C8410FC1E84F0FC00007FFC040008003FF0C81008100FF00810 +78A8:000001FCFD24112411FC21243D2465FC6400A7FE252025223D14254821840102 +78A9:000003FEFC20104011FC21043D0465FC6504A5FC250425043DFC240020880104 +78AA:00880088FBFE208820F8408878F84888C8884BFE490049487984490001FE0000 +78AB:00800338FA28222823A842467A004A7CCBA44A244A284BA87E104A2802440282 +78AC:000003DEFA422242224243DE7A004A3ECBD24A124A144BD47A084A1402240242 +78AD:000001F8F90821F8210841F878004BFEC90049FC4A544C9479244A4400A80110 +78AE:000001FCFD04110411FC21043D0465FC6400A7FE242025203D3C252022A0047E +78AF:00920124FA4821242092404078804BFECA024A8A4A524A227A524A8A03FE0202 +78B0:01080090F80023FC2090409078924C92CA944A98489048907890489007FE0000 +78B1:00140012F01027FE2410441075D0D412541255D45554554875DA542A08461082 +78B2:00400020F9FC2000208840507BFE4A22CC2449FC492449247934492800200020 +78B3:00200124F924212421FC408078804BFEC890491049524A547AA84C2808440082 +78B4:00200020FBFE207020A841247A2249FCC90449FC490449FC7904480003FE0000 +78B5:00200020FC3E1020102021FC3D0465FC6504A5FC250425FC3C00248821040202 +78B6:0080009EFBEA208A21CA408A7BEA4892C8A648204BFE48207850488801040602 +78B7:0008001CFDF01110111021FE3D10657C6544A57C2544257C3D442244027C0444 +78B8:000007FCF404243425C4444475F4D554555455F45444545475F4549408061002 +78B9:00400020FBFE2202240441FC780049FCC90449FC490449FC7904480003FE0000 +78BA:00400040FBFE22A2209041FE79104B10CDFE4910491049FE7910491001FE0100 +78BB:00200010FDFE100010FC20843CFC640065FEA502257A254A3D7A2502210A0104 +78BC:000001FEF92021FC212041FC79204920C9FE48024AAA4AAA7AAA4A0200140008 +78BD:000001FCFC20102013FE20003DFC650465FCA50425FC25043DFC248821040202 +78BE:000001FEFD02110211FE21243D24657E6524A52425FE25523D54264822640442 +78BF:000003FEFA02220223FE42107A92CA544AFE4A824AFE4A827AFE4482048A0884 +78C0:02440124F928207E2010435479544954C97C49144920492079404A80047E0000 +78C1:01080088F09027FE210841087210D29454A4573851085210721054A407BC0084 +78C2:004003BEFA122292225242AA7B244840CBFE4A224A224BFE7A224A2203FE0202 +78C3:0004001EFBF0221E221042FE7A92CA984AF24A8E4A804AB87AA844AA054A0A86 +78C4:00200010FDFE1110117C21143DFE6514657CA510257C25443D442244027C0444 +78C5:00400020FBFC2108209043FE7A024C44C8204BFC488048F87888490801280210 +78C6:000001FCFD0411E4112423FE22027DFC6504A5FC250425FC25043D0425140108 +78C7:00200040FDFC1104115421243D54650465FCA400251225D43D1825522192010E +78C8:00200040FBFC2224222443FC7A244A44CBFC484048A848B4793C49220222041E +78C9:03F00110F0E02318200047BC74A4D31854A4504057FC50E0715052480C460040 +78CA:7FFC040008001FF0281048108FF000007EFE102020407EFCA34422443E7C2244 +78CB:00840044FC4811FE102020FC3C2065FE6440A48024FE25103E10241021FE0000 +78CC:00200020FBFE202021FC410479FC4904C9FC490449FC49047BFE488801040202 +78CD:00400020FBFE2202242441FC782049FCC8204BFE482049FC7904490401FC0104 +78CE:001E03E0FD2210941040208821F07C2064C4A5FE2422242027FE3C5024880306 +78CF:00880050FC0013FE105021FC3C5467FE6454A5FC245024D83D54265220500050 +78D0:08783E48228E2A007EF822482A3046CC0000FFFE08001FF82808C8080FF80808 +78D1:00200124FD24112411FC20003FFE640065FCA504250425FC3C88245023FE0000 +78D2:000000FCFC84108410FC20003DFE650265FEA50225FE25023DFE244820840102 +78D3:00100220F97C21442044407C7B404940C97C49444944497C79444A80047E0000 +78D4:02080208F3BE24882AA8413E7208D448584857FC50E0515072485C4600400040 +78D5:00200020FCFC1020102021FE3C40648465FEA40225FC25543D54255423FE0000 +78D6:000001DEFC42115210CA21523C42642064FCA484248424FC3C84248420FC0084 +78D7:00280024FBFE202021FC412479FC4924C9FC492448084BFE7888484800480018 +78D8:0008003CFBC020042244412879FC4A20C8204BFE482049247924492401FC0004 +78D9:00400020FBFE208821244242789049F8C808484448A849907A884CA400C20080 +78DA:002003FEFC2011FC112421FC3D2465FC6422A7FE240827FE3D08248820280010 +78DB:08047F7808407F40497E7F4849487F4808487F4808887FFC08001FF868080FF8 +78DC:01000110FBDC22542554428879084AF4CC0248004BFC484079504A4805440080 +78DD:00880088F88823D0209E43E478944FD4C91449D44954494879484A5402D40422 +78DE:00200222FA2223FE200043DE7A524A52CBDE4A524A524BDE7A524A52055A08A4 +78DF:000007BCF88424A4229444A478504988CE2648C04B1048647B88483000C00700 +78E0:00200020F83E2020202043FE7A024B26CA8A4A524B264A527A8A4B2603FE0202 +78E1:02480248F7E8224823DE424A73CAD24A524A5FEA540A554A7632541207EA0044 +78E2:00200020FBFE202022AA41247AAA4820CAAA49244AAA48507850488801040602 +78E3:00400088F9FC2108225243FE78504988CE2648C04B1048647B88483000C00700 +78E4:000000DCFB14221423D442547BE6CA404BDC4A144BD44A547A484448055408A2 +78E5:000001FCFD2411FC112421FC3C40648865F0A420244427FE3C22252422220060 +78E6:000003FEFC5011FC115421543DFC640065FCA40027FE24203CA8252422A20040 +78E7:002003FEFC2011FC102023FE3C0065FC6504A5FC250425FC3D0425FC20880104 +78E8:00803FFE22102F7C221027382AD422102FFC2100220027F84A08520883F80208 +78E9:000C000AF80823FE220842487A6ACA4A4BFA4A4C4A4C4AEC7B5A444A04D60822 +78EA:00200222FBFE2090208841FE7B104D10C9FE4910491049FE7910491001FE0100 +78EB:01240124F22424242954414A7292D6105A105250525C5250725052B0029E0300 +78EC:08007F7808483E4800863E782A483E304048FFFE08001FF82808C8080FF80808 +78ED:03FE0200FAFC220023FE42947AA8CAC44A004AFC4A844AFC7A8444FC0484088C +78EE:00200124FD2411FC102020503C8865746602A5FC255425543DFC25542154010C +78EF:01240124FAAA23AE212442AA7BAE4924CFFE4910491449147A8A4A4A02160422 +78F0:00880050FBFE202021FC40207BFE4924C8A84BFE480049FC7904490401FC0104 +78F1:008802AAFADC24882154422278004BFECA424C444BFC48447844488401140208 +78F2:0200017EF840247C224440FC79404E7ECA2048204BFE487078A8492402220020 +78F3:01040088F80023FE222242AA7A724A22CBFE480049FC490479FC490401FC0104 +78F4:002007A4F0A822922114420875F4D80253F85208520853F8720851100FFE0000 +78F5:000003DEFA5223DE225243DE7A024AFACA8A4AFA4A8A4AFA7A8A4A02020A0204 +78F6:0080031CFA042204239C42047A04CBFC49004BFE4C024AAA7AAA440200140008 +78F7:00200124F8A823FE20A841247A224904C90449DE4A444D54789E490402040404 +78F8:00880050FBFE205021FC4154798C4974C90449FC48204BFE7850488801040202 +78F9:000003FEFC5013FE125223FE3C0065FC6504A5FC250425FC3C2023FE00200020 +78FA:00880088FDFC1088108823FE3C2065FC6524A5FC252425FC3C00248821040202 +78FB:003C03E0FD2410A813FE20A83D24660265FCA524252425FC3D24252421FC0104 +78FC:00A00090FDFE132011FC21203DFC652065FEA500242027FE3C7024A823260020 +78FD:00200020F9FC202023FE41087B9C4908C9884E3E48004BFE789048900112020E +78FE:000003DEFA52225223DE400079FC4924C9FC492449FC48207BFE482000200020 +78FF:3FFE21042E3822102FBC27182AB4325220002FFC210023F826085A0843F88208 +7900:03DE0252FBDE225223DE42027AF24A92CAF24A924AF24A927A924B3202020206 +7901:00A00090F9FE2110231045FE79104910C9FE4910491049FE79004AA402520452 +7902:002003FEFC2011FC100021FC3D0465FC6488A7FE240025FC3D04250421FC0104 +7903:012400A8FBFE220220F8408878F8480CC9F0482049FC48207BFE482000A00040 +7904:001801E0FC4013FE108821743E5264706400A5FC250425743D5425742104010C +7905:02080108F7C82010279E449477A4D01457945094511451C87708511405240242 +7906:00200020FC501088110422FA3C00640065DCA554255425DC3C88248821540222 +7907:00400080FBFE222222AA42227BFE4A72CAAA4A0248204BFE7850488801040602 +7908:00440224F928207E201040287B4A491CC928494C491A492A7948491002FE0400 +7909:01080208F7C8245027DE446477D4D214511457D4521453C872485454055408A2 +790A:0878FFC808483E862B783E482A28FF9049287F4600007FFC08001FF868080FF8 +790B:000001FCFD5411FC102021FC3C2067FE6488A45025FC24203FFE242020200020 +790C:000001FCFC2013FE122221AC3C2065AC6400A5FC252425243DFC2524212401FC +790D:008803FEFC8811FC110421FC3D0465FC6480A5FE262225523D0225FA200A0004 +790E:00880088FBDE208821DC42AA7C884800CBFE48224920493C79204AA0047E0800 +790F:00500252F954205023FE408878504BFEC82049FC48204BFE78A8492406220020 +7910:0A803138228838382288393822887FFE4002BFF404000FF0181068100FF00810 +7911:00200124FCA813FE120220F83C88648864F8A40025FC25243DFC252421FC0104 +7912:01040088FBFE202021FC40207BFE4854C99248904BFE489078D44B8A009601A2 +7913:000003FEFC0011FC112421FC3D2467FE6400A5FC252425FC3D2425FC200003FE +7914:001003C8FA7E2240226243D47A004A3ECBC84A484E7E4A487A484BC802480008 +7915:3E1022FE3E4420287EFEA2103EFC22100000FFFE08001FF82808C8080FF80808 +7916:0140024CFA642244234C42647AA44BACCAA44AA44FFE48007910490802040404 +7917:00400020FBFE220221FC41487A5049FCCB0449FC490449FC790449FC00880104 +7918:000003FEFA0223FE220243FE79084A52CB9C49084A524BDE78004AA402520452 +7919:020002BEFB02225421C8403E7A0A4BCACD2849284FEE49287AA84A58044E0080 +791A:008803FEF888202021FC40207BFE4840C88849FC480049FC7954495407FE0000 +791B:000803E8FA8823EE222843F47A824BE2C80049FC495449547954495407FE0000 +791C:0A0033B822083BB820883AB82288FFFE10103FF8C4060FF0181068100FF00810 +791D:000001FCFC2013FE122221AC3C2065AC6400A7FE242025FC3D5425542154010C +791E:008803FEF88823FE220241FC78004BFEC84048A24B5448B87B54489203500020 +791F:000007C4F51427C8250847D47514D50057D450545554554875485454005401A2 +7920:01080090FBFE2108210842527B9C4908CA524BDE484048A47AAA4A8A04780000 +7921:008803FEFC88102413FE20203DFC652465FCA52425FC25243C0825FE20880058 +7922:01080090FBFC204021F840807BFC4948C9FC4B0A4DF8490879FA4934018C0102 +7923:004801FEFC48100011FE214A3D4A65FE6414A5FE251025923D4C254A21160222 +7924:00880088FBFE2088211041DE7A524D54CA8849744A0249FC7820492402220060 +7925:07DE0512F7D2245427C8451477E2D00053FC520453FC520473FC520403FC0108 +7926:00200010FBFE224422FE42447BFE4A10CAFE4A924AFE4A927AFE4A0002440482 +7927:000001FCF92421FC212441FC79044800CBFE4AAA4AAA4BFE7AAA4AAA03FE0222 +7928:00001FF011101FF011103FF82AA83EF82AA83EF800007FFC08001FF868080FF8 +7929:0042039CFA1023DE229442947C204BFCCA044BFC4A044BFC7A044BFC01080204 +792A:000001FEFD2811FE1128217C3D54657C6554A57C251025FE3D9222BA028A0484 +792B:01240174FA5822DA23FE41547ADA4BFEC8A248204BFE487078A8492402220020 +792C:22882108FABE2008729CA92A2288FFFE08203FF8C4060FF0181068100FF00810 +792D:01FC0020FBFE222225AC402079AC4890C9FE4B204DFC492079FC492001FE0100 +792E:001007C8F53E27C0251447D27522D50057D450545554554875485454005401A2 +792F:008802AAFADC2488215442227BFE4A42C88849F048244BFE7822492402A20040 +7930:000007FEF4442598248847DE7488D5DC56AA54885420542074BC54A004A00BFE +7931:08407F7C1440FF7C22043E7C22403E7C2242263E00007FFC08001FF868080FF8 +7932:01100090FBDE2010225E41827BDE4810CBDE4A504BDE4A507BDE4A50025202CE +7933:00400020FBFE224823FE42487AEC4B5ACA484BFE4A204A7C7AC44B44047C0844 +7934:008803FEF088241222FE401074FED29252FE509251FE5292760452FE0244022C +7935:01FC0020FBFE222221AC402079AC4800C89E4BF2489E49D27ABE4C92009E0092 +7936:008803FEF88823DE225243DE78A04890C9FE49204BFC4D2079FC492001FE0100 +7937:009007FEF89023E8228843CE7A504BD4CAA24BE248004BFC7A944A9407FE0000 +7938:052807BEF94827BE231845AA79464BFCCA044BFC4A044BFC7A044BFC01080204 +7939:07BC04A4F7BC200027FE44007590D49E57D4556455D4555475D455680BC81054 +793A:00003FF80000000000000000FFFE010001001110110821044102810205000200 +793B:200010001000F800080010001000380054009400100010001000100010001000 +793C:208010801080F8800880108010803880548094801080108410841084107C1000 +793D:2000100013F8F8880890109010A038BC54849484110411041104120412281410 +793E:202010201020F8200820102013FE382054209420102010201020102017FE1000 +793F:204010401080F8FC090412041004390454849444104410041004100410281010 +7940:2000100011FCF90409041104110439FC55049500110011021102110210FE1000 +7941:200010FC1084FC8804880890108838885484928410C410A81090108010801080 +7942:202010201020F920092C113411643BA455249534112811221122110210FE1000 +7943:200013F01010F81009101110111039FC54049404100413F41004100410281010 +7944:202010201050F850088811041202388854889488108810881088110811081208 +7945:2008103C11E0F8200820102013FE382054209450105010501088108811041202 +7946:2000100011FCF8200820102010203BFE54209420105010501088108811041202 +7947:2004101E11F0F91009101110111039FE5510951011101108110A114A11861102 +7948:2008101C11E0F9000900110011FE391055109510111011101110121012101410 +7949:202010201020F92009201120113C392055209520112011201120112017FE1000 +794A:204010201020FBFE08801080108038FC54849484108410841104110412281410 +794B:200010F81088F88808881106120039FC54849484104810501020105010881306 +794C:202010201020F82009FC112411243924552495FC112410201020102010201020 +794D:2008103C11E0F8200820102010203BFE54209420102010201020102011FC1000 +794E:202010201020FBFE0820102019FE3420502093FE10221022102A102410201020 +794F:2000100013FEF82008201040184034FC51849284148410841084108410FC1084 +7950:202010201020F8200BFE10401040388054FC9184128410841084108410FC1084 +7951:202010201120F92009FC11201220382057FE9420105010501088108811041202 +7952:200013FC1084F8840884110411143A08540095FC110411041104110411FC1104 +7953:205010481048F8400BFE1080108038FC55449544112811281210122814441182 +7954:208810881088F908097E13081508394855289528110811081108110811281110 +7955:200010401020F8280808108810903A9456A292A214C210881188128814781000 +7956:200011F81108F908090811F811083908550895F8110811081108110817FE1000 +7957:4008203C23E0FA2012201220222033FE6A20AA1022102212220A228A23262212 +7958:00003E7C0000000000007EFE081008102A542952495288900810081028501020 +7959:202010201020F9FC0820102010203BFE547094A810A811241124122210201020 +795A:208010801080F8FE094011401240387C544094401040107E1040104010401040 +795B:202010201020F9FC0820102010203BFE5420942010401048108411FE10821000 +795C:202010201020F8200BFE10201020382055FC9504110411041104110411FC1104 +795D:200013FC1204FA040A04120413FC3890549094901090111211121212140E1800 +795E:202010201020F9FC09241124112439FC55249524112411FC1124102010201020 +795F:0100111011101FF0410441047FFC00003FF80000FFFE01001110210845040200 +7960:200011FC1004F8040BF41004100439E455249524112411E41004100410141008 +7961:088008882E9028E028842E84F07C00003FF80000FFFE01001110210845040200 +7962:208010801080F8FE090211041220382054A894A4112411221222102010A01040 +7963:2080108010FEF9000A00101C11E0392055229524112811101110114811841102 +7964:200013DE1042F8420A52114A114A384254C6914A1252104210421042114A1084 +7965:210410841088F8000BFE1020102039FC5420902013FE10201020102010201020 +7966:200011FC1104F90409FC1000100039FC5420902013FE10201050108811041202 +7967:209010901090FA9209941098189035985294949210901090111211121212140E +7968:00007FFC04403FF8244824483FF800003FF80000FFFE01001110210845040200 +7969:202011201120F9FC0920122010203BFE547094A810A811241124122210201020 +796A:2040104010FCF9040A0811FE1100397C554495441154114811421242123E1400 +796B:202010201050F8880904120211FC3800540095FC110411041104110411FC1104 +796C:200013FE1020F8400888110413FE38225420902013FE10201020102017FE1000 +796D:100010801EBC22445448A83010102FE8C00600007FFC01001110210845040200 +796E:202010201020FBFE0820102011FC3800540095FC110411041104110411FC1104 +796F:20201020103EF820082011FC1104392455249524112411241050104810841104 +7970:202011201120F9FC0920122010203BFE5400940011FC11041104110411FC1104 +7971:210410841088F81009FC11041104390455FC94501050109010921112120E1400 +7972:200011FC1004F8FC080411FC10003BFE560291F8108810881050102010D81306 +7973:200013FC1200FA000AF8120012003BFC56A092A412A812901290148814A418C2 +7974:201010141012F8100BFE10101150395457F4955411541148124A125A14261042 +7975:400023FE2222FA22122213FE222232626A72AAAA232222222222220223FE2202 +7976:410820882090FBFC1024102423FC32206A20ABFE206220A2212A222424202020 +7977:2020102013FEF82009FC104013FE3848548894FE110811481228140810281010 +7978:200011FC1104F904090411FC1820342053FE92221252128A130A1202120A1204 +7979:2080108010FEF9020A8210F21142384257FA94421152115211F2100210141008 +797A:2108110813FCF908090811F81108390855F89508110817FE1000109011081204 +797B:200011FC1104F924092411FC1124392455749554115411741104110411FC1104 +797C:200011FC1124F92409FC1124192435FC502093FE107010A81124122210201020 +797D:2040102013FEF8000888108811543A225400902013FE10201020102010201020 +797E:2020102011FCF820082013FE18883544524290F8118812501020105011881606 +797F:208010F81088F90809F01010181037FE50209222117410A81124122210A01040 +7980:0100FFFE00003FF8200827C8244827C820083FF800003FF80000FFFE11102308 +7981:082008207EFC1C702AA849268A2000001FF000000000FFFE0100111025084204 +7982:200011FC1124F9240974112411FC390455749554115411741104120412141408 +7983:4040204027FCF840104013F8220833F86A08ABF8220823F8220822082FFE2000 +7984:400021F82008F80811F81008200833FE6820AA22217420A82124222220A02040 +7985:210410881050F9FC0924112411FC3924552495FC1020102013FE102010201020 +7986:2040108013FCFA240A2413FC1A24364453FC9090111017FE1010101010101010 +7987:2040104413F4F848085017FE1040388055F89308150811F81108110811F81108 +7988:200013FE1222F8200BFE102011FC392455FC952411FC102013FE102010201020 +7989:208810481050FBFE0850105011FC39545554958C110411FC1104110411FC1104 +798A:4100213C27D4F9141394111427D43124694CA84027FE204020A0211022082C06 +798B:200013FE1050F85009FC11541154395455FC9420102011FC1020102013FE1000 +798C:408420442048FBFE108410842108314A6A52AB9C208421082108225223DE2042 +798D:200011FC1104F90409E4112411243BFE560292FA128A128A12FA1202120A1204 +798E:20201020103EF820082011FC110439FC550495FC110411FC1000108811041202 +798F:400023FE2000F9FC1104110421FC30006BFEAA22222223FE2222222223FE2202 +7990:203C17C01244F928080013FC1080388057FE950011F812881250142018D81306 +7991:21FC11241124F9FC0924112419FC3420502093FE1222122A12FA120A12021206 +7992:210011F81208FBF0081017FE10803944566894B01128166810A4112216A01040 +7993:200011F81108F9F8090811F810003BFE550095FC125414941124124410A81110 +7994:200011FC1104F90409FC1104190435FC500093FE10201120113C112012A0147E +7995:2040104011FCF8840BFE100011FC390455FC902013FE1020122013FE10201020 +7996:2088108813FEF888088810F81088388854F8902013FE107010A8112412221020 +7997:200011FC1124F92409FC1124112439FC54009440102412A2128A148810781000 +7998:2040102011FCF8000888105013FE3A22542495FC112411241134112810201020 +7999:2050105213DCF85008D2134E100039FC550495FC110411FC1104110411141108 +799A:210410841088F8000BFE1020182035FC5020902013FE100012A4125214521000 +799B:2020102013FEF82009FC110411FC390455FC950411FC110413FE108811041202 +799C:08202AA44D28145022887FFE400280043FF80000FFFE01001110210845040200 +799D:200011FC1124F9FC092411FC18883544524290F8118812501020105011881606 +799E:2040102013FEF80009FC110419FC340053FE920212FA128A12FA1202120A1204 +799F:2020101011FEF910097C111411FE3914557C9510117C114411441244127C1444 +79A0:4004201E23F0FA1E121012FE229232986AF2AA8E228022B822A824AA254A2A86 +79A1:200011FE1120F9FC092011FC1120392055FE900212AA12AA12AA120210141008 +79A2:200011FC1104F9FC090411FC1800340053DE90421252114A12521042114A1084 +79A3:2028102413FEF82009FC112411FC392455FC9524100813FE1088104810481018 +79A4:200013FE1252FA520BFE100013DE38425652954A10C6135A10421042114A1084 +79A5:2088108813FEF88808F8108810F8388857FE9488112412FA1020102013FE1000 +79A6:020027DE491297D2211265DAA5142FD000003FF80000FFFE0100111025080200 +79A7:404027FC2040FBF8100013F8220833F86910AFFE200023F82208220823F82208 +79A8:4124212422AAFBAE112412AA23AE31246FFEA91021142114228A224A22162422 +79A9:400023FE2222FBFE122213FE208830886BFEA888208827FE2000208821042202 +79AA:200013DE1252FA520BDE100011FC392455FC952411FC102013FE102010201020 +79AB:200013FE1050FBFE0A5213FE100039FC550495FC110411FC102013FE10201020 +79AC:202010501088F9740A0211FC112439AC552495FC100010F8108810F8108810F8 +79AD:408824482250F8FC10201050269432386A50AA98223422542290222025FE2800 +79AE:409023FC2294FBFC129413FC200033FC6800ABFC220423FC2108209027FE2000 +79AF:409023FC2294FBFC129413FC200033FC6A00AAF8220023FE2520251425482986 +79B0:400023FE2124FA2217FE1222237632AA6B76AA22237622AA23762222222A2204 +79B1:404027FC2040FBFC100017FE200233F86840AFFE200027FE200827FE24A82798 +79B2:200013FE1248FBFE0A4812FC12A43AFC56A492FC122013FE132A157A150A1906 +79B3:202013FE1000F9DC095411DC188837FE508893FE108817FE1094118816A410C2 +79B4:404020A021100208F5F610002EEE2AAA6EEEB0002FFE29222FFE2922292A2804 +79B5:400023BE2288FB9012BE13A2203E37E2693EA92225BE2514252225002BFE3000 +79B6:452827BE2948FFBE131815AA294633FC6A04ABFC220423FC220423FC21082204 +79B7:4100255E2384F90817DE11122392355E6912A81E21522FF2211E2280244C2812 +79B8:0100010001007FFC420442044404444448245FF4481440044004400440144008 +79B9:001000F83F0001001FF0111011101FF001007FFC410441245FF448144004400C +79BA:00003FF8210821083FF8210821083FF801007FFC410441245FE4482440144008 +79BB:02000100FFFE00001450139014501FF001007FFC420444444FE4442440144008 +79BC:010001FC01001FF01450139014501FF001007FFC420444444FE4442440144008 +79BD:010002800C603118CFE60440139014501FF001007FFC420444444FE44424400C +79BE:001000F83F000100010001007FFC038005400540092011102108C10601000100 +79BF:00701F80010001007FFC054009203118C006044004400440044008421042603E +79C0:00701F80010001007FFC054009203118CFE60420044004780808080810506020 +79C1:04200E20782008200820FF40084018401C402A482A84488489FE088208020800 +79C2:00F83F0001000100FFFE0540092011102008C10401000280044008203018C006 +79C3:00701F80010001007FFC054009203118C0060FC00840084008441044203C4000 +79C4:04000EFC780408080810FF20082019FE1C202A202A2048208820082008A00840 +79C5:08081C3CF3C010401040FC401040307E3BC054405040904210421042103E1000 +79C6:08001DFCF02010201020FC20102033FE38205420542090201020102010201020 +79C7:08401C40F040104011F8FC4810483048394854C8544890A810AA110A12061402 +79C8:08201C20F02010201124FD24112431243924552455249124112411FC10041000 +79C9:00F83F0001007FFC01003FF80108FFFE01083FF80380054009203118C1060100 +79CA:00701F80010001007FFC054009203118C0E61F00010001007FFC010001000100 +79CB:08401C40F04010401144FD4411483250384054A054A090901110110812041402 +79CC:103811C010401440584053FC504090E010E0115011502A482444484240408040 +79CD:08201C20F020102011FCFD2411243124392455FC552490201020102010201020 +79CE:08101C90F09010881108FD04120435FA38885488548890881108110812281410 +79CF:08081C3CF1E010201020FC3C11E038203420503E53E09020102210221022101E +79D0:08001C00F1FC10001000FC0013FE30203820544054409088110413FE11021000 +79D1:08101D10F09010901010FD10109038903410501E53F090101010101010101010 +79D2:08201C20F02010A810A4FCA2112231203A245424542890081010102010C01300 +79D3:08201C20F02013FE1020FC20102031FC38845488544890501020105011881606 +79D4:08801C40F04013FC1000FC0011F03110391055105510911211121212120E1400 +79D5:08101D10F11011121112FD1411D83110391055105510911211521192110E1000 +79D6:08041C1EF1F011101110FD10111031FE3910551055109108110A114A11861102 +79D7:08081C3CF1E010201020FC2013FE302038205450545090501088108811041202 +79D8:08001C40F02010281008FC8810903A9436A252A254C290881188128814781000 +79D9:08201C20F020102013FEFC201020302039FC5504550491041104110411FC1104 +79DA:08201C20F12410A410A8FC2011FC38203420502053FE90201020102010201020 +79DB:08101C10F01011FE1112FD14111031FC39445544552891281110122812441482 +79DC:08001DFCF10411041104FDFC11003140394455485570914011421242123E1400 +79DD:08381DE0F02010201020FDFC10203070387054A854A891241124122210201020 +79DE:08201C20F020102011FCFD2411243124392455FC552491241124112411FC1104 +79DF:08001DF8F10811081108FDF811083108390855F8550891081108110817FE1000 +79E0:08001DFEF01010101020FC20106838A435225222502090201020100013FE1000 +79E1:08501C48F048104013FEFC80108030FC39445544552891281210122814441182 +79E2:08201C20F05010501088FD241212301039FC5404540890881050102010101010 +79E3:08201C20F02013FE1020FC20102031FC387054A854A891241124122210201020 +79E4:08001DFCF02010201124FCA410A830203BFE5420542090201020102010201020 +79E5:08201C20F0201020103EFC201020302039FC5504550491041104110411FC1104 +79E6:01007FFC01003FF80200FFFE082010D02F08C1061FF005400920111061080100 +79E7:08201C20F02011FC1124FD2411243124392457FE542090501050108811041202 +79E8:08801C80F08010FE1140FD401240307C384054405440907C1040104010401040 +79E9:08201C20F120112011FCFD201220302039FE5420545090501088108811041202 +79EA:08041C1EF1F011101110FD10111031FE3910551055109108110A114A11A61112 +79EB:08401C50F048104017FCFC4010E038E035505150524894441842104010401040 +79EC:08001DFEF10011001100FDFC110431043904550455FC91001100110011FE1000 +79ED:08201C20F02E11F01120FD20112039FE3422546250A2912A1624102010201020 +79EE:08201C20F04010401088FD0413FE3002380055FC550491041104110411FC1104 +79EF:04000E0078FC08840884FF84088418841CFC2A842A0048488844088408820902 +79F0:08801C80F08010FE1102FD041220302038A854A4512491221222102010A01040 +79F1:08001DFEF1021102117AFD021102317A394A554A554A917A11021102110A1104 +79F2:08201C20F02011FC1020FC2013FE3008380855FE540890881048100810281010 +79F3:08081C3CF1E010201020FDFE10203020382055FC550491041104110411FC1104 +79F4:08201C20F05010881104FE0211FC3000380055FC550491041104110411FC1104 +79F5:08001DFCF10411241124FD2411FC312439245554554C918C1104110411FC1104 +79F6:0100410021FC0A441448E0A02110260800E01F0001007FFC05401930E10E0100 +79F7:08001DFEF02010401088FD0411FE30223820542055FE90201020102013FE1000 +79F8:08201C20F02013FE1020FC2011FC3000380055FC550491041104110411FC1104 +79F9:00801888709C11701110FB101510311039FE55105110911011101110117C1100 +79FA:08401C20F3FE12021000FC3813C038403440507C53C0904010421042103E1000 +79FB:08201C20F07C10841148FC30102030483990543E544291A41018101010601180 +79FC:08201D20F12011FC1120FE20102033FE387054A850A891241124122210201020 +79FD:08201D24F124112411FCFC40104038FC35045284504890501020104010801300 +79FE:08201C20F02013FE1242FC4410A038A235A4529854909088108410A210C01080 +79FF:08281C24F3FE10201020FDFC1124312439FC5524552491FC112411241124110C +7A00:09841C68F03010C81304FC4013FE38A0352053FC552491241134112810201020 +7A01:01007FFC00001FF010101FF000007FFE400280741F800100FFFE05401930E10E +7A02:08401C20F1FC11041104FDFC1104310439FC5520552291141108114411821100 +7A03:08041C1EF1E010021122FC94100039FC3408501053FE90101010101010501020 +7A04:08401C40F088110413FEFC02108831443A4254F8518892501020105011881606 +7A05:08101C90F08811081204FDFA11083108390855F854909090109011121212140E +7A06:08001CFCF08410841084FC8410FC3800340055FE510291021102110211FE1102 +7A07:08001DFCF12411241124FDFC11243164397455AC552491241124110411FC1104 +7A08:08001DFCF10411FC1104FDFC1000380035FC5420502093FE1020102010201020 +7A09:08001DFEF020102011FCFD24112431FC3924552455FC912010A0104010B0130E +7A0A:09081C88F09011FC1024FC2411FC3120392055FE546290A2112A122414201020 +7A0B:00000DFCF10411041104FDFC1000380035FC5420502091FC10201020102017FE +7A0C:08201C20F05010881104FEFA102030203BFE5420552891241222142210A01040 +7A0D:08201D24F0A410A81020FDFC1104310439FC5504550491FC1104110411141108 +7A0E:09041C84F088101011FCFD041104310439FC54505450909010921112120E1400 +7A0F:08001DFEF04810481048FDCE11023102390255CE504890481048104813FE1000 +7A10:08201C20F05010881104FEFA100031FC3954555455FC9154115411541104110C +7A11:08201C20F1FC10201020FDFE108831043A22542051FC90201020102013FE1000 +7A12:08001DFCF10411241124FDFC1124312439745554555491741104110411FC1104 +7A13:08881C88F08813FE1088FC8817FE300039FC5504550491FC1104110411FC1104 +7A14:08201C20F05010881144FE2211F838083450542050A49282128A128A14781000 +7A15:08401C20F3FE100011FCFD0411FC380035FC5408501093FE1020102010A01040 +7A16:08801C40F1FC10001108FC88109033FE3800540055FC91041104110411FC1104 +7A17:08401C80F1FC11241124FDFC1124394435FC5490511093FE1010101010101010 +7A18:08881C88F3FE10881088FCF81088388834F85488508893FE1000108811041202 +7A19:08201C20F3FE10201020FDFC110431FC390455FC550491FC1104110417FE1000 +7A1A:08A01C90F09011FE1110FF1015FE3110391055FE55109110111011FE11001100 +7A1B:10003BFEE202221A22E2FA22222233FE6A226272A2AA23262222222223FE2202 +7A1C:10203820E1FC20202020FBFE208831446A4260F8A18822502020205021882606 +7A1D:10003BDEE25222522252FBDE225232526A5263DEA252225222522252255228A6 +7A1E:08001DFCF124112411FCFD24112431FC382057FE547090A81124122210201020 +7A1F:0100FFFE00003FF8200827C8244827C820083FF800001FF00100FFFE0920711C +7A20:08001DFCF12411241174FD2411FC310439745554555491741104120412141408 +7A21:08401C20F3FE10001088FC88115432223800542053FE90201020102010201020 +7A22:10143812E01027FE2010F81023D232526A526254A3D4200820EA271A22262042 +7A23:2008203C7DE0442088207C2055FE54207C70546854A87CA401221C20E0204020 +7A24:08401C20F3FE10001000FDFC1104310439FC5420552891241222142210A01040 +7A25:00701F8001007FFC054009203118C006149022481FF010101FF010101FF01010 +7A26:08401C40F1FC108413FEFC0011FC390435FC502053FE9020122013FE10201020 +7A27:08801C9EF3EA108A11CAFC8A13EA389234A6502053FE90201050108811041602 +7A28:08401C20F1FE11021102FDFE1100390035FE55AA51AA92FE12AA12AA14A21086 +7A29:08001DFEF12211FE1122FDFE100030FC388454FC548490FC1084108410941088 +7A2A:09001D00F1FE120015FCFD0411FC310439FC548054FC91081290106011981606 +7A2B:08001DFEF00010FC1084FC8410FC300039FE5522552291FE1122112211FE1102 +7A2C:08001DFCF020104011FCFD54115439543544552C502093FE1050108811041202 +7A2D:09101D12F1D411181152FD92112E304039FC5504550491FC1104110411FC1104 +7A2E:08081C3CF1E0102013FEFC2011FC312439FC552455FC902011FC102013FE1000 +7A2F:08001C88F25212221252FE8A12023BFE34885144527A90881150102010D81706 +7A30:08001DFEF0121090109CFC90117E320038FC548450FC908410FC108410941088 +7A31:081E1DE0F04411241088FC2011FC3924352455FC5124912413FE110411141108 +7A32:08041C1EF1E010221112FC941080313E39225522553E912211221122113E1122 +7A33:08401CF8F108121011FCFC04100439FC3404540451FC9040102412A2128A1478 +7A34:08881C50F00011FE1050FDFC105433FE385455FC545090D81154125210501050 +7A35:08841C44F04813FE1084FC841108314A3A52579C508491081108125213DE1042 +7A36:08141C12F01013FE1014FC18139032B43A98569053B2900C10CA171A10661002 +7A37:08001DFCF12411FC1124FDFC108831443A4254F8518892501020105011881606 +7A38:08401C20F3FE10401088FDF01020304439FE540255FC912411FC112411FC1104 +7A39:08201C20F3FE102011FCFD0411FC390435FC550451FC910417FE108811041202 +7A3A:10003BFCE204220423FCFA40222033FC6A886250A3FE222025FC242028202020 +7A3B:081E1DE0F02211121094FC80102031CE3902550255CE91021102110211FE1102 +7A3C:08401C20F3FE12021000FDFC104030A23B345458509493341052109013501020 +7A3D:08501C48F3FC10A01122FE1E111031E0390454FC540091FC110411FC110411FC +7A3E:01007FFC08200FE000007FFC48244FE440045FEC01007FFC05401930E10E0100 +7A3F:08401C20F3FE100011F8FD0811F8380037FC520452F49294129412F412141208 +7A40:1000FE7810487C480048FE8682007CFC00447C441028FE283810542892441182 +7A41:08881C88F1FE10881000FDFE1088308838F8548854F89088109E11E810081008 +7A42:08201C20F3FE102011FCFD2411FC392435FC5440502492A2128A148810781000 +7A43:08401C20F3FE12021050FC88112430503888550452FA90881088108810F81088 +7A44:11003910E3DC22542554FA88210832F46C026000A3FC20402150224825442080 +7A45:08201C10F1FE1110117CFD1411FE3914357C5510519291541138125412921430 +7A46:08201C40F1FC110411FCFD0411FC38203524563250C093181060118C103013C0 +7A47:10403888E1FC21082252FBFE205031886E2660C0A31020642388203020C02700 +7A48:010000803FFE22102F7C26382B543292203827C020402FFE215042484C468040 +7A49:08001DFEF10211FE1110FD541138395435825550517C9190111012FE12101410 +7A4A:1000E7BE2488248827A8FCA824A837BE6C106518A49825A826AA244A20462080 +7A4B:10003BDEE0422252214AFA52202830C46B126060A188203221C4201820602380 +7A4C:2008203C79E0482090207C2055FE54207C70546854A87CA40122AA20AA200020 +7A4D:08201DFEF02011FC1020FDFE100031FC390455FC550491FC110411FC10881104 +7A4E:40004CFE7010442044FC3C8400840CFC708410FCFE84108438FC544890841102 +7A4F:08081C3CF1C010441124FCA811FC300438FC540455FC904010A412AA128A1478 +7A50:1100E1F0222027F82A48FBF8224833F8684067FCA44427FC244427FE2042203E +7A51:08201C20F3FE10201124FCA813FE300039FC5504557491541174110411FC1104 +7A52:00701F800100FFFE05401930E20E1FF010101FF010101FFC10001FFC0004492C +7A53:10003BFEE22223FE2222FBFE208830886BFE6088A08827FE2000208821042202 +7A54:0088188871FC10881088FBFE102031FC392455FC512491FC1000108811041202 +7A55:08A01C90F1FE132011FCFD2011FC392035FE5500502093FE107010A813261020 +7A56:0124192472AA13AE1124FAAA13AE31243BFE551051149114128A124A12161422 +7A57:08201C20F3FE102011FCFD2411FC392435FC502253FE9042102412A2128A1478 +7A58:08201C20F1FC102013FEFD08139C31083988563E500093FE109010901112120E +7A59:08501E52F154105013FEFC88105033FE382055FC502093FE1050108811041602 +7A5A:08181DE0F04013FE1088FD7412523070380055FC55049174115411741104110C +7A5B:08901C88F1FE11101310FDFE1110391035FE5510511091FE110012A412521452 +7A5C:08201DFCF088105013FEFC0011FC312439FC552455FC902011FC102013FE1000 +7A5D:100039F8E10821F82108F9F8200037FE6A4063DCA25423D4226827C820542062 +7A5E:08801CF8F11013FC1524FDFC112431FC380057FE540091FC110411FC110411FC +7A5F:1088E448225020FC2020F850269432386A506298A23422542290222025FE2800 +7A60:08501DFCF15411FC1154FDFC100031FE3900557C550091FE1150115411481266 +7A61:0020182073FE11241124FAAA17FE300039FC5504517491541174110411FC1104 +7A62:08201D3CF12017FE1010FC1413FE32103BF05654525492D41368144A18961322 +7A63:10803840E7FE21102208FD1423F831106BF86110A7FC212823102D4821862100 +7A64:08001DFCF02013FE1222FDAC102031AC380057FE502091FC115411541154110C +7A65:11403A4CE2642244234CFA6422A433AC6AA462A4A7FE20002110210822042404 +7A66:08401C20F3FE120211FCFD48125039FC370455FC510491FC110411FC10881104 +7A67:10803840E7FC211020A4FF58255435526B586000A20823F8220823F822082408 +7A68:0C2071FC1124FDFC10203BFE540091FC010439FC290429FC29044DFC48888104 +7A69:103EE7C02244212823F8F84027FC30006BF86008A3F8200823F82544252A28FA +7A6A:10003BFEE124222227FEFA22237632AA6B766222A37622AA23762222222A2204 +7A6B:00881BFE70A8109011FEFB2011FC312039FC552051FE910013FC10881070138E +7A6C:10403820E7FE248825FCFC8827FE34206DFC6524A5FC252425FC240024882904 +7A6D:08801DF8F20815FC1124FDFC112431FC3954562A55FC910411FC110411FC1104 +7A6E:08401C20F3FE125013FEFE5213FE32003A9456D8529092D2128E140015541A2A +7A6F:00201BFE702013AE12AAFBAE102033FE380057FE520292FA128A12FA120213FE +7A70:1040E7FC200023B822A8FBB8211037FC691067FCA1102FFE212823102D482186 +7A71:001E1BE07122109413FEFA5213FE30043BC4567E53C4925413CC128412D41348 +7A72:13DE3800E3DE2252235AFA52202033FE6A5063FEA25223FE229222DC229224CE +7A73:1528E7BE294827BE2318FDAA294633FC6A0463FCA20423FC220423FC21082204 +7A74:0200010001007FFE400280440440044004200820082010101010200840048002 +7A75:020001007FFE40028824101020081FE000C0030004000800100810080FF80000 +7A76:020001007FFE400288241210220802003FE002200420042008221022201E4000 +7A77:020001007FFE400288241010220802007FF00210041004100810101020A04040 +7A78:020001007FFE400288241010220804000FF0101068200440028003001C00E000 +7A79:020001007FFE482290142FF8001000101FF0100020003FF80008000800500020 +7A7A:020001007FFE400288241010200800001FF0010001000100010001007FFC0000 +7A7B:020001007FFE4002882410102FE80100010001007FFC01000100010005000200 +7A7C:020001007FFE400288241010210801007FFC0540092011102108C10601000100 +7A7D:020001007FFE48229014282808203FF8082008200820FFFE0820102010202020 +7A7E:020001007FFE48229014200800F03F0001000100FFFE0280044008203018C006 +7A7F:020001007FFE4822901400003FFC0040104020403FFE01400640184061400080 +7A80:020001007FFE482291142108FFFE01002108210821083FF8010A0102010200FE +7A81:020001007FFE4002882411102148012001007FFC01000280044008203018C006 +7A82:020001007FFE48229014210811001FF8210041000100FFFE0100010001000100 +7A83:020001007FFE48229014200021FC2C44F0442044204424842884310422280410 +7A84:020001007FFE4822901428080FF81400240047F00400040007F8040004000400 +7A85:020001007FFE4822901420081FF0101010101FF010101FF0101010101FF01010 +7A86:020001007FFE4822901401F03E00020001007FF8006001800E003000480087FE +7A87:020001007FFE4822901408001FF020105F90109010901F901050102410040FFC +7A88:020001007FFE482290140840084012F822487C480848144822887E8821280210 +7A89:020001007FFE4822901420081FF0010001003FF8210822882448280820282010 +7A8A:020001007FFE4822901420781FA012201220122012101290224822A843248202 +7A8B:020001007FFE4822901421081110111011101FF001002108210821083FF80008 +7A8C:020001007FFE4822901420080C0070FC4084448444845C846494488808801080 +7A8D:020001007FFE48229014200800007DFE1040108011FC10041E04E00440280010 +7A8E:020001007FFE4822911422081FF010101210115010201FFC000400047FD40008 +7A8F:020001007FFE48229014100009FC4820202020200BFE10207020102010A01040 +7A90:020001007FFE4822901401003FF801000100FFFE000001003FF801000100FFFE +7A91:020001007FFE48229014200808001FF821000100FFFE0100210821083FF80008 +7A92:020001007FFE4822901400007FFC040008201FF0011001003FF801000100FFFE +7A93:020001007FFE482292142408082010103FF80008010008844892481287F00000 +7A94:020001007FFE4822921401007FFC08201010244844440280010006C01830E00E +7A95:020001007FFE4822901404404448245024600C403460C852084A1042203E4000 +7A96:020001007FFE4822911409000FF011000100FFFE00001FF0101010101FF01010 +7A97:020001007FFE4822921404003FF8220823C824482A882108228824083FF82008 +7A98:020001007FFE482290143FF80408FFFE04083FF808001FF8280848088FF80808 +7A99:020001007FFE4822911C0FD00120FFFE01001FF0082030C0CFFC008002800100 +7A9A:020001007FFE4822909400883FFC208020883E88225022502A244454418C8604 +7A9B:020001007FFE4822901420083E2001FE00247E4414E81410146A2586240243FE +7A9C:020001007FFE4822911401003FF821083FF801007FFC41047FFC410401000100 +7A9D:020001007FFE482290142FE8082008200FE001003FF821082288244820082018 +7A9E:020001007FFE4822941427E8082010402678180810081E78100810081FF81008 +7A9F:020001007FFE482290143FF820083FF820802490249027F02080488848888FF8 +7AA0:020001007FFE482290143FF811101FF011101FF00100FFFE054009203118C106 +7AA1:01007FFE482290143EF8020814D00820145062883EF80288145008203458C286 +7AA2:020001007FFE4822901400500048FFFE00403E4022243E2800120E2A70C60302 +7AA3:020001007FFE4822921401007FFC0820145022880100FFFE0100010001000100 +7AA4:020001007FFE482290143FF810081FF810081FF82080208C3EF020822682387E +7AA5:020001007FFE48229014000011FC7D0411241124FD241154285024904112860E +7AA6:020001007FFE482291142FE801007FFC048412880900FFFE0260041018086004 +7AA7:020001007FFE4822911401FC01003FF820083FF820083FF80100FFFE01000100 +7AA8:020001007FFE4A2291143FF808200440FFFE00001FF010101FF010101FF01010 +7AA9:020001007FFE482290143FF810101F9010907FFC40044FE448244FE44004400C +7AAA:020001007FFE48229014004023F81040804047FC10002040E3F82040204027FC +7AAB:01007FFE4822901408007F7C08243E2408447F5408880200FFFE04401830E00E +7AAC:020001007FFE492292940C6037D8C0063E0822483E4822483E48220822282610 +7AAD:020001007FFE4822911409207FFC05401930610C0400FFFE08201E4003C03C38 +7AAE:01007FFE4822901408003F7C21043F04217C3F4021407F7C05041904E5280210 +7AAF:020001007FFE48229014244802803FF801001FF001007FFC0000248822444244 +7AB0:01007FFE4822901401F87E002208111020003FF841000100FFFE010021083FF8 +7AB1:020001007FFE4822909411F822886870ABAE282029FC282028A8292422A42040 +7AB2:020001007FFE48229014080049482A280808FF48182E2CF84A08880808080808 +7AB3:020001007FFE48229014061C38E828A82CA82AA82AA82AA828A455545D748212 +7AB4:01007FFE4822901401007FFC01001FF010101FF010101FF01010FFFE10102008 +7AB5:01007FFE482294141FF010101FF010101FF010001FFC10001FFC492484940008 +7AB6:01007FFE482291143FF82108FFFE21083FF811101FF00400FFFE082007C07838 +7AB7:01007FFE482290140040FD9E4952495279524952795249DA5D54E89008900910 +7AB8:01007FFE4822901400F83F0011100920FFFE09203118C20609002908282447E4 +7AB9:01007FFE4822901405FC242024F83C48044805FE7C0024FC2484248444FC8484 +7ABA:020001007FFE48229014000011F87D0811F81108FDF8110829F824904112860E +7ABB:01007FFE4822911402003FF8220827E82A48218826483FF801004884481287F2 +7ABC:01007FFE48229114222011101FF011101FF011101FF001007FFC05401930E10E +7ABD:020001007FFE4822901422203C20213E1F4220943F104810FFA8142822444182 +7ABE:01007FFE4822901408207F20083E3E4200943E1000107F1008282A2849441882 +7ABF:01007FFE4822911479F04A9050606198560649F04A406BF8544043F8404047FC +7AC0:020001007FFE4822901401F8FD0811F8110851F85D0851F850905C90F112060E +7AC1:01007FFE4822901401F03E0003F03E0003FA7E0201FE0C20703C1DE2F0221C1E +7AC2:01007FFE482291147FFC044028281FF02828CFE608200FE00100111025080200 +7AC3:01007FFE492297D401007FFC11101FF011103FF821083FF821083FFA010200FE +7AC4:01007FFE4822961438F820083CF820083FF80000294825282948252A29463182 +7AC5:01007FFE482290143E2022203E3E22443EA408247F2810281E1022282A444482 +7AC6:01007FFE4822901408003E7C22443E44227C3E0022FEFE8212822282CAFE0482 +7AC7:01007FFE492297D401003FF824483FF810101FF010101FF010101FF008201010 +7AC8:01007FFE492297D401007FFC00001FF012903EF822883EF822883EFA028201FE +7AC9:01007FFE4822901408407E7C2440FF7C00047E7C42407E7C42407E7C4242463E +7ACA:01007FFE482290140C40707C104055FC39241154FD0433FE3A22564A92FA1206 +7ACB:02000100010000007FFC000000101010082008200440044004800000FFFE0000 +7ACC:1000080008F07E9000900490449044902490289028900E92F0924112010E0200 +7ACD:1020082008207E200020042047FE44202420282028200E20F020402000200020 +7ACE:020001003FF8000008200440FFFE0000044004407FFC04400840084010402040 +7ACF:1008083C09E07E2000200420442047FE2420282028200E20F020402000200020 +7AD0:100008F808887E8800880506460045FC2484288428480E50F020405000880306 +7AD1:204010401040FC4003FE08408880889048904920512052481E44E48441FE0082 +7AD2:020001003FF8000008200440FFFE001000101F90109010901F90001000500020 +7AD3:1008081C08E07E200020043C44E044202420283E29E00E20F02240220022001E +7AD4:200810681388FC880088088888888BFE48884888508850881D08E10842080408 +7AD5:201010901090FC88010809048A048DFA48884888508850881D08E10842280410 +7AD6:08004BF84A08491048A0484048B04B0C0A0001003FF8000008200440FFFE0000 +7AD7:1020082008207EA800A404A2452245202624282428280E08F010402000C00300 +7AD8:1040084008807EFE0102060244F244922492289228F20E92F002400200140008 +7AD9:1020082008207E20003E04204420442025FC290429040F04F104410401FC0104 +7ADA:204010201020FDFE01020A048800880049FE4820502050201C20E02040A00040 +7ADB:1020082008507E50008805244612441025FC280428080E88F050402000100010 +7ADC:020001003FF808200440FFFE00001FF011101FF011101FF01112010200FE0000 +7ADD:1020081008107EFE00000400448444842444284828480E10F01041FE00000000 +7ADE:020001003FF808200440FFFE00001FF0101010101FF00440044008423042C03E +7ADF:020001003FF808200440FFFE00001FF010101FF010101FF0044008421042603E +7AE0:020001003FF808200440FFFE00001FF010101FF010101FF00100FFFE01000100 +7AE1:100009FE08107E10002004FC44844484248428FC28840E84F084408400FC0084 +7AE2:202010401088FD0401FE0802888088FC4920482053FE50201C50E08841040202 +7AE3:204010401088FD0403FE0802888889444A4248F8518852501C20E05041880606 +7AE4:2040102013FE0202FC4400400BFE884088904890511051201A24E24204FE0842 +7AE5:020001003FF808200440FFFE00001FF011101FF011101FF001003FF80100FFFE +7AE6:2020102013FEFC20002009FC8924892449FC4820507050A81D24E22240200020 +7AE7:1020084008F87E8800F8048844F8448A248C29F828180E28F048408803280010 +7AE8:20201020103EFC2001FC090489FC890449FC4924502053FE1C20E02040200020 +7AE9:2020101011FEFD02020408F88888888848F84888508850F81C88E08843FE0000 +7AEA:00007EFC48447E4442287E1048287EC6020001003FF8000008200440FFFE0000 +7AEB:2040104010F8FD08001009FC882488244BFE4824502451FC1C24E02040A00040 +7AEC:2004101E13E0FC2001FC0924892489FC48204BFE5222522A1EFAE202420A0204 +7AED:200011FC1104FDFC010409FC888089FE4A224922515251021DFAE00240140008 +7AEE:200013FC1204FE0403FC0A008A848A484AFC4A48524853FE1C48E44848881108 +7AEF:202011241124FD2401FC08008BFE8820484049FC515451541D54E1544154010C +7AF0:100009FE09007F7C01540554457C45542554297C29100F10F17C4210021004FE +7AF1:202013FE1020FDFC012409FC892489FC48224BFE500853FE1D08E08840280010 +7AF2:21041088100003FEFA2202AA0A728A228BFE480051FC510419FCE10401FC0104 +7AF3:201013D21054FD48008A09048AFA8C0049FC4904510451FC1D04E08847FE0000 +7AF4:2088105013FEFC5001FC0954898C8974490449FC500853FE1D08E08840A80010 +7AF5:200013FE100803BEFA8802A80ABE8B8888084BFE528A52521BFEE222022A0224 +7AF6:20201010FEFE44442828FEFE00007EFC428442847EFC28502A502C924912820E +7AF7:1020FE7C44A42818FEE600107CFE44107C9044FE7C101020FE7C10C8103011CE +7AF8:20201010FEFE44442828FEFE00007C7C44447C7C44447C7C28282A284C4A8886 +7AF9:10401040104010403EFE289049108A1008100810081008100810081008500820 +7AFA:104010401F7E289024884508800000003FF800000000000000000000FFFE0000 +7AFB:104010401F7E289024884508820002007FF80208040804080808100820504020 +7AFC:104010401F7E28902488450880000FE0082008200A200920092210222022401E +7AFD:104010403F7E2890450880003FF801000100FFFE010001000100010005000200 +7AFE:104010401F7E2890248845088100117013901D10F11011501122110210020FFE +7AFF:104010403F7E4890850800003FF8010001000100FFFE01000100010001000100 +7B00:104010403F7E4890850802000100FFFE0800080008000800080008000FFC0000 +7B01:104010401F7E289024884508800000003FF801000100010001000100FFFE0000 +7B02:104010403F7E28904508820002007FE002200A200420062009221022201E4000 +7B03:104010403F7E28904508BFF00010101010101FFC000400047FE4000400280010 +7B04:104010403F7E4890850800007FFC082008200820FFFE08200820102020204020 +7B05:104010403F7E28904508981006600180066018186C240240018006601818E006 +7B06:104010403F7E2890450880003FF82108210821083FF820002002200220021FFE +7B07:104010403F7E289045088100008000007FFE0100012001100108010001000100 +7B08:104010403F7E2890450880003FE0082008400C780A081210112020C043308C0E +7B09:104010403F7E4890950810001FF820084C088208006801881E08080800500020 +7B0A:104010403F7E28904508801000F81F2012201220122012102210220842048202 +7B0B:104010403F7E489085083FF002100210FFFE021004103FF0081010002000C000 +7B0C:104010403F7E489085083FFC0020102020203FFE012002200C203020C0A00040 +7B0D:104010403F7E4890850801003FF8210821082288244828282008200820282010 +7B0E:104010403F7E4890850800001FF0000000007FFC04400440044408441044603C +7B0F:104010403F7E4890950810001FF8224842488488088811082208440808501020 +7B10:204020407EFE51108A0801007FFC000000000FE00820082008221022201EC000 +7B11:104010403F7E2890450880F03F0001000100FFFE01000280044008203018C006 +7B12:104010403F7E28904508828004400A203118C1061FE000200040004000800100 +7B13:104010403F7E489085082080208020883C9020A020C0208424842884307C0000 +7B14:104010403F7E4890850800F83F00010001F83F00010001FC7F020102010200FE +7B15:104010403F7E2890450880001FF010101110111011101290149008823082C07E +7B16:104010403F7E2890450880002410221021102110201024202830304821840602 +7B17:104010403F7E2890450888001FF02820444003801C70E30E00C00E0001800040 +7B18:104010401F7E289024884508810001FE010001003FF82008200820083FF82008 +7B19:104010403F7E28904508910011003FFC4100810001003FF8010001000100FFFE +7B1A:20403F7E4890850800003FF8210821083FF8210821083FF82108010001000100 +7B1B:104010403F7E2890450881003FF82108210821083FF82108210821083FF82008 +7B1C:104010403F7E2890450880000100210821083FF801000100410441047FFC0004 +7B1D:104010403F7E489085083FF820082FC820482688210822882C4820083FF82008 +7B1E:104010403F7E48908508082010103FF8000800001FF01010101010101FF01010 +7B1F:104010403F7E2890450880781FA012201220122012101290224822A843248202 +7B20:104010401F7E2890248845088200010001007FFC00001010082004400000FFFE +7B21:104010403F7E2890450880001FF0101010101FF010101FF010101010FFFE0000 +7B22:104010403F7E489085083FF8200820083FF8208020803FFC204020242C14300C +7B23:20403F7E4890850808001FF020105F90109010901F901050102410040FFC0000 +7B24:20403F7E4890850800007FF80408080810502020DFF81008100810081FF81008 +7B25:104010403F7E2890450880003FF800087FE800081F88108810881F8810A80010 +7B26:104010403F7E489085080810081013FE30105110909010901010101010501020 +7B27:20403F7E4890850800001E78124812481248FFFE124812481248128826A84110 +7B28:104010403F7E4890850801007FFC03800540092011102FE8C106010001000100 +7B29:104010403F7E28904508885008481040307C57C09040102010201014100C1004 +7B2A:104010403F7E2890450880001FF0101010101FF0101010101FF00000FFFE0000 +7B2B:104010403F7E2890450881701F80110021003FFC0304050409043128C1100100 +7B2C:20403F7E489085083FF8010801083FF8210021003FFC030405041928E1100100 +7B2D:104010403F7E28904508828004400A203118C1061FE0002000400C8003000080 +7B2E:104010403F7E28904508880008001FFC2400440087F00400040007F804000400 +7B2F:104010403F7E28904508900011F8FE881288228824506450182018502488C306 +7B30:20403F7E4890850804403FF8044804481FF8144024403FFC0844105420484040 +7B31:104010403F7E4890950810001FF8200840089F88108810881F88000800500020 +7B32:104010403F7E28904508882010103FF8000808200820FFFE0820082010202020 +7B33:104010403F7E489085081000107C7E441244124412441244224422444A7C8444 +7B34:104010403F7E489085080000FFFE001000101F90109010901F90001000500020 +7B35:104010403F7E48908508100009F84908210825080528091071021102110210FE +7B36:104010403F7E28904508880008001FF0210001007FFC0280044008203018C006 +7B37:104010403F7E489085080C0070FC4084448444845C8464944888088010806080 +7B38:104010403F7E2890450880003FFC2000200027F82408240827F8200020003FFE +7B39:104010403F7E28904508822012201220FFFE1220122013E0100010001FFC0000 +7B3A:20403F7E489085080240022003F87E00020003FCFE10012000C007443834000C +7B3B:104010403F7E2890450880007CFC10841084108410841E94F088408000800080 +7B3C:104010403F7E28904508804004207FFC04800488089008A010C223824C82807E +7B3D:104010401F7E28902488450880003FF8244824482448244824482448FFFE0000 +7B3E:104010403F7E489085082080108017F8008870881108110812281410280047FE +7B3F:20403F7E4890850808000FF010202C4003801C70E00E1FF0101010101FF01010 +7B40:104010403F7E2890450881003FF801000100FFFE000001003FF801000100FFFE +7B41:104010403F7E2890454884403FF82448244824483FF82448244824483FF82008 +7B42:104010403F7E4890854820401258926843C84E480A48125AE242220221FE2000 +7B43:104010403F7E489085083FF8210821082FE8210822882448282820083FF82008 +7B44:104010403F7E4890850804404448245024600C403460C852084A1042203E4000 +7B45:104010403F7E48908508110011003FF841000100FFFE0440084010422042C03E +7B46:104010403F7E489085083FF00110FFFE01103FF001003FF80100FFFE01000100 +7B47:104010403F7E2890450880007EFC088408880890088808840E84F0A840900080 +7B48:20403F7E4890850800F01F0001000100FFFE010001001FF0101010101FF01010 +7B49:20403F7E4890850801003FF801000100FFFE000000207FFC0820042004A00040 +7B4A:204020407EFE51108A0801007FFC08201010244844440280010006C01830E00E +7B4B:104010403F7E489085083E20222022FC3E24222422243E24224442444A948508 +7B4C:104010403F7E289045088280044008203018CFE6010001001FF0010001007FFC +7B4D:20403F7E4890950810001FF820085FC890481FC810481FC81048000800500020 +7B4E:104010403F7E489095081000FE7C124422442244644414440844147C2244C000 +7B4F:104010403F7E2890450888A00890108030FC57809048105010241054118C1604 +7B50:20403F7E4890850800003FFE20002FFC2080208027F8208020802FFC20003FFE +7B51:104010403F7E4890850800007DF011101110119011501D12E2124212040E0800 +7B52:104010403F7E28904508BFF820082FE8200827C82448244827C8200820282010 +7B53:104010403F7E2890450880007EFC082008200820FEFE08200820102020204020 +7B54:104010403F7E2890450882800C603018CFE600001FF01010101010101FF01010 +7B55:20403F7E48908508100021FC4000880013FE3020502090201020102010A01040 +7B56:104010403F7E489085080100FFFE01003FF821082388255809201110610C0100 +7B57:104010403F7E489085081040104027FC6444A444244427FC2444204020402040 +7B58:104010403F7E28904508880008007EFC088408840E847884088408FC28841000 +7B59:104010403F7E4890850801007FFC01003FF80100FFFE054009203118C1060100 +7B5A:20403F7E48908508208020883EB020C42084267C39000100FFFE010001000100 +7B5B:20403F7E4890850808004BFE4820482049FC4924492449241134112820204020 +7B5C:104010403F7E289045089110092001007FF8000800083FF8000800087FF80008 +7B5D:104010403F7E2890450888001FF020205FF80108FFFE01081FF8010805000200 +7B5E:204020407EFE51108A0801003FFC2004410801007FFC054009203118C1060100 +7B5F:20403F7E4890850800F87F00221011203FE000400080FFFE0100010005000200 +7B60:104010403F7E28904508908010FC7D041204108410541C24E044418400280010 +7B61:204020407EFE51108A880440082037D8C10601003FF801001110210845040200 +7B62:104010403F7E48908508100011FCFD24112411241DFCF10011001102510220FE +7B63:204020407EFE511088080608780808480848FF481C482A484948880808280810 +7B64:204020407EFE51108A0801001FF010101FF010101FF011081090126014181806 +7B65:104010403F7E2890450880001FF0101010101FF000003FF8200820083FF82008 +7B66:204020407EFE51108A0801003FFC20045FE800007FFC0440044008441044603C +7B67:104010403F7E289045089FF010101FF010101FF010101FF0044008421042603E +7B68:104010403F7E4890850802800C603118CFE6004000801FF0101010101FF01010 +7B69:104010403F7E489085083FE0044002803FF821083FF821083FF8210821282010 +7B6A:104010403F7E28904508BFFC20002FF828882FF828882FF8208020803FFE0000 +7B6B:104010403F7E2890450880003FF820083FF820083FF820083FF8082010102008 +7B6C:104010403F7E28904508809000883FFC208020883E48225022244A54448C8104 +7B6D:20403F7E4890850800003FF801001FF001007FFC00000820FFFE082010202020 +7B6E:104010403F7E4890850800007FFC01001110111011102928454485840100FFFE +7B6F:104010403F7E489085283E20222022FC3E2422243E24222422442F44F0944108 +7B70:104010403F7E289045088880088010FE11403240547C90401040107E10401040 +7B71:104010403F7E4890850810401040247E24886488A54824502420205020882306 +7B72:104010403F7E48908508111009201FF010101FF010101FF01010101010501020 +7B73:104010403F7E4890850800387BC00840104023F8784008402BFC1000280047FE +7B74:104010403F7E4890850801007FFC11101110292845440280044008203018C006 +7B75:20403F7E4890850800187BE00840104022787A400A402BFC1000280047FE8000 +7B76:104010403F7E4890850811001FF821000100FFFE00001FF0101010101FF01010 +7B77:104010403F7E48908508104011F818485448504853FE904010A0111012081406 +7B78:20403F7E489085081FF010101FF010101FF000003FF80100FFFE010001000100 +7B79:20403F7E4890850801007FFC02003FF80400FFFE08201FFC2420422080A00040 +7B7A:104010403F7E489085083FFE20002FFC2080208027F820A020902FFC20003FFE +7B7B:20403F7E489085087FFC01003FF821083FF821083FF821001A00060019C0603E +7B7C:20403F7E489085081FF0101010101FF000003FF820082108220804E01818E004 +7B7D:104010403F7E489085081FF010101FF000003FF80100FFFE028004401830E00E +7B7E:104010403F7E2890450882800440082037D8C00602101110092008407FFC0000 +7B7F:104010403F7E289045088FE0144003801C70E10E01003FF80100111025080200 +7B80:20403F7E4890850810000BF8200827C82448244827C82448244827C820082018 +7B81:204020407EFE51108A0801003FF808200440FFFE00001FF0101010101FF01010 +7B82:104010403F7E4890850801007FFC11101110292845440380054009203118C106 +7B83:20403F7E4890850800007F0022FC3E4422443E44222822282F10F22842440282 +7B84:204020407EFE51108A0804003FF821083FF822083FF808801080FFFE00800080 +7B85:104010403F7E489085083FF821083FF821083FF80000FFFE0820082010202020 +7B86:20403F7E4890850800003FF8210822882448000020843E9820E020842684387C +7B87:20403F7E4890850800003FF8210821082FE8210827C8244827C820083FF82008 +7B88:20403F7E4890850820801110120887FC4204500013F82208E208220823F82208 +7B89:20403F7E48908508100011F8FD08110815F8184033FCD0441084108451142208 +7B8A:104010403F7E4890952808207E50105010881F0612601210220022C04A308408 +7B8B:20403F7E48908508021002FC7F4000840764781C021002FC7F4000840764781C +7B8C:20403F7E489085087F84100422247F24092408247F24082408240F04F0144008 +7B8D:20403F7E48908508100013FE1220FE2012FC12A41EA4F2A412B412A8522023FE +7B8E:20403F7E4890850801F801003FFE210221F02F0420FC200027E044224822B01E +7B8F:20403F7E4890850800FC7F00220811103FF80108FFFE01083FF8010805000200 +7B90:20403F7E4990BFF801001FF00100FFFE00001FF010101FF010101FF010101030 +7B91:20403F7E489085087FFC01003FF80108FFFE01083FF8110011F8290047FE8000 +7B92:20403F7E489085081FF000100FF000101FF000007FFE41029FF4111011501120 +7B93:20403F7E489085083FF000101FF00010FFFE111009A005401930E10E05000200 +7B94:104010403F7E48908528104009FC49042104250405FC09047104110411FC1104 +7B95:20403F7E48908508082008207FFC08200FE008200FE00820FFFE082010102008 +7B96:104010403F7E48908508082008207EFC08200C701A682AA44922882008200820 +7B97:20403E7E489080003FF820083FF820083FF820083FF80820FFFE082010202020 +7B98:20403F7E489085083FF8200820C8270821082FE823882548292821083FF82008 +7B99:20403F7E489085083EFC228422943E88228022FC3EA422A422A822904AA884C6 +7B9A:104010403F7E289045088C04122421245EA480243F242124212421043F142108 +7B9B:20403F7E48908508001C7DF00950115011501D503148D14811441254525A2468 +7B9C:20403F7E4890850801007FFE40028824101020081FF00100010001007FFC0000 +7B9D:104010403F7E4890850810881088FBFE108810881CF8F0881088108850F82088 +7B9E:20403F7E48908508111009203FF802007FFC082010102FE8C8260868080807F8 +7B9F:104010403F7E289045089FF810081FF810081FF82080208C3EF020822682387E +7BA0:20803EFE491080F83F0001007FFC09200920FFFE092009207FFC010001003FF8 +7BA1:20403F7E4890850801007FFE40029FE410201FE010001FF0101010101FF01010 +7BA2:204020407EFE51108A0801007FFE400290041EF8228824A8549008841084607C +7BA3:204020407EFE511088080804FFA408247F2449244B241C242A24490488140808 +7BA4:204020407EFE51108A0801007FFC08200820145022880100FFFE010001000100 +7BA5:20403F7E489085082020102013FC822442204BF80A881288E25024202450298C +7BA6:20403F7E489085083FF801001FF001007FFC00001FF01010111002C00C307008 +7BA7:20403F7E4890850800003FFC208020802FF8249022A02FFC2140222024103FFE +7BA8:20403F7E48908508100011FC1088FC70138E10201DFC3020D3FE102050202020 +7BA9:20403F7E489085083FF8244824483FF8020007F008103420024001800E007000 +7BAA:20403F7E48908508082004403FF821083FF821083FF80100FFFE010001000100 +7BAB:10401F7C28A045103FF80108FFFE01083FF80100254825282528292821084108 +7BAC:20403F7E4890850808207FFC08200200FFFE040008001FF02810C8100FF00810 +7BAD:20403F7E4890850810100820FFFE00003E4822483E4822483E0822082A282410 +7BAE:20403F7E50908A0801007FFE40029FF400001FF010101FF010101FF00000FFFE +7BAF:20403F7E48908508080017FC304053F8924813F8124813F8114010C013301C0E +7BB0:20403E7E48909FF820085FC890481FC810681FD000001FE00040FFFE01000300 +7BB1:104010403F7E28904508880008FC7E84088418FC1C842A842AFC4884888408FC +7BB2:20403F7E489085281120092009FC422020202BFE08901090709011121112120E +7BB3:20403F7E489085083FF820083FF8241022202FF8222022202FFC422044208820 +7BB4:104010403F7E2890452880243FFE20202FA420242FA8289828924FAA40468082 +7BB5:20403F7E489085081110216843841C00FFF010101FF010101FF010101FF01010 +7BB6:204020407EFE51108808087C7F440844087C3E442244227C22443E8422940108 +7BB7:104010403F7E4890A5481040FEFE212020AC3CB425E424AC24A044A25482887E +7BB8:104010403F7E2890450882001FD00220FFFE03000FF03810CFF008100FF00810 +7BB9:20403F7E4890850810401440247C7884110424447E24002454044A048A280010 +7BBA:20403F7E489085087FFC01003FF80200FFFE08201FF02828CFE608200FE00820 +7BBB:20403F7E48908508004013F8204847FE884813F8304053FC904017FE10401040 +7BBC:20403F7E489085083FFC20043FFC20002FF8220024102FF820804FF84080BFFE +7BBD:20403E7E48909FF001007FFC01001FF011101FF011101FF001003FF80100FFFE +7BBE:20403F7E48908508080049042A247F2441247F2441247F244124410445144208 +7BBF:20403F7E489085081FF010101FF000007FFC10101FF010101FF0103EFFD00010 +7BC0:104010403F7E4890850800007E7C42447E4442447E44484444545A4862404040 +7BC1:204020407EFE51108A081FF010101FF010101FF000007FFC01003FF80100FFFE +7BC2:20403F7E489085081FF010101FF010101FF021003FF841009FF00100FFFE0000 +7BC3:20403F7E489085083FF821083FF820002FF828082FF828084FF848088FF80808 +7BC4:20403F7E4890850808007F7C08447F4449447F4449547F480842FFC20842083E +7BC5:20403F7E489085080100210821083FF80000FFFE02003FF82488248824A82010 +7BC6:20403E7E489088000FE010201FC00040FFFE06003B0804B019C062A00C987306 +7BC7:20403F7E4890850800803FFC20043FFC20002FFC292429242FFC49244924880C +7BC8:20403F7E48908508080008087F0808FEFF08084808287F2808080F08F0284010 +7BC9:20403F7E489085087DF01110119011521D12E20E01007FFC054009203118C106 +7BCA:104010403F7E489085082090109013FC80904890489017FEE000209021082204 +7BCB:104010403F7E489085083FFC20802FF82080249024902AA83144222024103FFE +7BCC:20403F7E4890850809F00810101037FC510091F81240104017FC10A01110120C +7BCD:20403F7E489085080C20702010A410A4FCA83120382054505050908811041202 +7BCE:104010403F7E4890850800207C2044A87CA445227D22462844107C6001800600 +7BCF:104010403F7E489085282220223EFF42229422103E10221022283E2822440082 +7BD0:20403F7E48908508100013FEFE20122032FC3AA456A492A412B412A8122013FE +7BD1:20403F7E489085081FF011101FF00100FFFE00001FF01010111002C00C307008 +7BD2:204020407EFE51108A880E603118DFE610201FE010201FE01008119014601810 +7BD3:20403F7E48908508111009207FFC05401930610C0400FFFE08201E4003C03C38 +7BD4:20803EFE49109FF010101FF000003FF820083FF820083FF820083FF808201010 +7BD5:20403F7E4890850801003FF801007FFC080010103FF800003FF824482448FFFE +7BD6:20803EFE491080803FFC20802FF820883FFE20882FF820804FF848088FF80808 +7BD7:20803EFE491088801FFC30805FF890801FF810801FFC10003FF00C6003807C7C +7BD8:20803EFE491090001FFC210451141FF4020814001FFC210451141FF404143808 +7BD9:20403E7E48908200FFFE00001FF010101FF000007FFC40044FE448244FE4400C +7BDA:20403F7E489085083FFC224022403E7822402E7022403E78224022403FFC0000 +7BDB:20403F7E4890850800007EFC02047EFC40807EFC020422441A3462C414280810 +7BDC:20403F7E489085081FC000447D88055009203118C50602003FF8000024884244 +7BDD:20403F7E489085487FFC04403FF80440FFFE11101FF01110FFFE101010501020 +7BDE:20403F7E48908508200017FC140487FC440457FC104027FCE04020402FFE2000 +7BDF:20403F7E4890850808400FFC104033F8504097FE120813F8120813F812081218 +7BE0:20403F7E48908508108011F822886870ABAE282029FC282028A8292422A42040 +7BE1:20403F7E48909FF810101FF010101FF010101FF002007FFC04401A30E44E0FE0 +7BE2:20803EFE4910BFF801007FFC00001FF010101FF010101FF010101FF008201010 +7BE3:20403F7E489085083FF8082004407FFE420281043FF8040007F0081010502020 +7BE4:20403F7E4890850800001FF811001FF011001FF011001FFC0004292444940008 +7BE5:104010403F7E489085087FFC04403FF824483FF801007FFC05401930E10E0100 +7BE6:20403E7E489082003FF82448238824483FF8000020843E9820E020842684387C +7BE7:20403F7E4890850804007FFC450408801FFC30805FF810801FF810801FFC1000 +7BE8:20403F7E48908508784048A05110620855F648404BFC68405150424845444080 +7BE9:20403E7E4890900023FE7C20442045FC7D2441247D24452445347D2844200020 +7BEA:20403F7E4890857C3F8020F820802FFC288428F02B882878480051E09224241C +7BEB:20403F7E489085087DF0111011901D52E20E5FF001001FF001007FFC01000300 +7BEC:20403F7E4890850806C01A30E10E1FF010101FF010101FF010002FF848088FF8 +7BED:20403F7E50908A0801003FF80820FFFE00003FF821083FF821083FFA010200FE +7BEE:20403F7E489085080480248024FC24A0251000003FF8244824482448FFFE0000 +7BEF:104010403F7E4890952810243C3E41E0BC20102E13F4FC281012106A15861802 +7BF0:20403F7E489085081000087C7F4422481450FFC800443E44225422483E402240 +7BF1:20403F7E489085080080FFFE0440139014501FF001007FFC44444FE44424400C +7BF2:20403F7E489085081010FEFE10107C7C1010FEFE10103FF800081FF800083FF8 +7BF3:20403F7E489085083FF821083FF821083FF80920FFFE09203FF801007FFC0100 +7BF4:20403F7E4890850823FC10801144066870B01128166810A4112416A0284047FE +7BF5:20403F7E489085081110211041108AA8144430405240927C1240154014FE1800 +7BF6:20403E7E4890FFFC010011F81100FFFE10001FF820003FFC0004492484940008 +7BF7:20403F7E4890850823F0151010E0071C704013F8104011F0104017FC284047FE +7BF8:20803EFE491088201FF0102025487EFC04401930E64E1990062018C007003800 +7BF9:20403F7E489085081FF0149012501FF00200FFFE08203FD8C84608C0080807F8 +7BFA:104010403F7E48909528104011FC7D2411FC11441DFC7050109013FE50102010 +7BFB:20403F7E489085087FFC04403FF824483FF800003FF80000FFFE111025080200 +7BFC:20403F7E48908508120067DC444447C4444457DC60000440044008421042603E +7BFD:20403F7E48908508140027DE4912811217D221126112A5D2251A25D42E102410 +7BFE:20403F7E489085083FF8244824483FF800903FFC208030482850242440D4830C +7BFF:20803EFE4910FFFC01003FF821083FF821083FF801047FFC0020FFFE08200460 +7C00:20803EFE4910BFF801003FF80100FFFE10101FF010101FF010101FF008201010 +7C01:20403F7E489085081020213C4120892017FE300050209120113E112012A0147E +7C02:20403F7E489085087FFC40A47FFC40845E9452945E64405446B459147FFC4004 +7C03:20403F7E489085280C4070FC13081090FC6030903B3E544255A4901810601380 +7C04:20803EFE4910BFF820083FF8200027F0241027F020002FF828884FF8480287FE +7C05:20403F7E4890850800803FFC041002203FFE208024802FFC308047F840809FFE +7C06:20403F7E50908A0801007FFE4022BE3C00207EF814081450142424D4440483FC +7C07:20403F7E4890850820401040FEFE212020403CFC2520242025FE445054888906 +7C08:20403F7E489085083FFC20043FFC220824102F78241024103F7C441044108810 +7C09:20403F7E48908548224013F81440004077FC100013F8120813F8280047FE0000 +7C0A:20403F7E4890850808207FFC08200FE008200FE00820FFFE11102FE8C1063FF8 +7C0B:20403F7E489085081FF010101FF010101FF410881470180E3FF824482448FFFE +7C0C:20403F7E489085080820FFA0083E7F42499449107F101C102A28492888440882 +7C0D:20403F7E489085083FF82108FFFE21083FF811101FF00400FFFE082007C07838 +7C0E:20403F7E489085081090109013FCFC9013FE10001DF8F10811F8110851F82108 +7C0F:20403F7E4890850800803FFE22203FFC22243FFC284028482F7048444B448C3C +7C10:20403F7E4890850808207F20083E7F4249847F1049107F100828FFA808440882 +7C11:20403F7E489085087FFC00001FF01010FFFE10101FF0048808503820CB180C06 +7C12:20803EFE49109FF010101FF010101FF010101FF00200FFFE08203518CA2617F0 +7C13:20403F7E4890850800047F0849105D6049047F0841105D6255045D0845108260 +7C14:20403F7E489085087FFC00003FF81010FFFE10103FF8048808503820CB180C06 +7C15:20403F7E4890850822207F2022203EFC08247F2449247F240844FF4408940908 +7C16:20403F7E48908508040C55704E4044405F7E44484E48554844487F8800880108 +7C17:20403F7E489095080BF040902A94129275121250142001007FFC05401930E10E +7C18:20403F7E489085083FF00110FFFC01103FF0092025482FE82388254829284108 +7C19:20803EFE4950804827FC204023F8FA4823F8224823F8224820102FFE211020B0 +7C1A:20403F7E489085087FFC444444447FFC0028FFFE08207F2449284D104A2A0846 +7C1B:20403F7E48908508220C2270FF4022403E40227E3E482248FF48224841488088 +7C1C:20403F7E4890850823F8120893F8420843F810002FFEE20027FC292422540488 +7C1D:20403F7E489085087FFC044028281FF02828CFE608200FE00100111025080200 +7C1E:20403F7E489085083EF822883EF800001FF011101FF011101FF00100FFFE0100 +7C1F:20403E7E4890FFFC04403FF824483FF810101FF010101FF00100FFFE01000100 +7C20:20403F7E489085283FF801001FF011101FF011101FF0111000003FF82448FFFE +7C21:20403F7E489085083E7C22443E7C22443E7C200427E4242427E4242427F42008 +7C22:20403F7E489085083E7C22443E7C22443F7C20842FF420442244218426542008 +7C23:20803EFE49109FF011101FF001007FFC10101FF010101FF010101FF008201010 +7C24:20403E7E4890BFF824483FF800001FF010101FF010101FF010101FF008201010 +7C25:20403F7E4890850800701F800200FFFE082037D8C4463FF8200827C8244827D8 +7C26:20403F7E4890850800907EA00444282817D02008DFF610101FF0082004407FFC +7C27:20403E7E489084403FF80440FFFE01003FF821083FF821083FF8082010102008 +7C28:20403F7E489085087CF844887CF842843E7C04403FF80440FFFE082010102008 +7C29:20403F7E4890850808202AA80820145022887FFC400402003FF8040808503020 +7C2A:20403F7E489085083E7C081048907EFE1428244A46863FF820083FF820083FF8 +7C2B:20803EFE4910BFF80108FFFE01083FF825483D7821083FF821083D7825484548 +7C2C:20403F7E48908508008078F849084A907860119812065DF8510851085DF8E108 +7C2D:20403F7E489085087FFC111029284544FFFE08203018DFF6101010101FF01010 +7C2E:20403F7E4890850808203EF808207EFC145022885FF410101FF010101FF01010 +7C2F:20403F7E489085081088108813FEFC8810F8388834F8508853FE908811041202 +7C30:20403F7E489085080820484049FC7D2441FC414479FC48A049204BFE48208820 +7C31:20403F7E48908508104808487EFC104810781E4812781248224823FE4A488484 +7C32:20403F7E4890850800203C4025FC25243DFC254425FC3C50249027FE54108810 +7C33:20403F7E4890850808107F2808443E82227C3E1022103EFE08107F1008100810 +7C34:20403F7E4890850801F801003FFE210221F02F0420FC292425285FFE42108408 +7C35:20403F7E489085081040FE7810887D5054207CD857067CF81088FE8810F81088 +7C36:20403F7E48908508200011F8FC0808F810083BFE5420953410A8112412A21040 +7C37:20403F7E48909FF820207FFEA4882BF4200027F8200027F8200047F8440887F8 +7C38:20403F7E4890850824102410FEFE24923C9024FC3CA424A4FEA8291045288246 +7C39:20403E7E4890911009203FFC20044FE808200FE000003FF821083FF821083FF8 +7C3A:20403F7E489085087FFE44429FF404403FF80440FFFE082011102FE8C1061FF0 +7C3B:20403F7E4890850821F8110811E8012873FC120412F4129412F412142A0847FE +7C3C:20403F7E48908508211027FCF91027FC291037FEE24823F822482FFEA2084218 +7C3D:20403F7E5090890802800440183067CC00003EF8228822883EF8082014502288 +7C3E:20403F7E489085083FFC22203FFC22402FF822483FFC22482FF846604A50B24C +7C3F:20403F7E4890854827FC104013F8824843F84A480BF81248F01027FC22102130 +7C40:20403F7E489085082080277CF4A425A436542088E7FC244427FC2444A7FC4404 +7C41:20403F7E4890850808207F3C08443E882A7C2A443E5408541C542A2848440882 +7C42:20403F7E48908508084014402AFE7F10A2103EFE22923E92289A24942A103010 +7C43:20403F7E489085083F2024203F3E21403F5024883F0800003FF824482448FFFE +7C44:20403F7E4890BFFC208027F0249027F020803FFC241027F0241027F022203FFC +7C45:20403F7E489085080A0033B822083A38238820883AB82288FFFE082010102008 +7C46:20803EFE491088207FFC09201FF831005FF091001FFC10003FF0082007C0F83E +7C47:20803EFE491080803FFC00000FF008107FFE40029FF40100069839E00690398C +7C48:20403F7E489085087F7C14207F20553855287F48086808587F4A084A0F6AF046 +7C49:20803EFE4910FFFE01003FF800001FF010107FFE48229FF401003FF80100FFFE +7C4A:20803EFE4910BEF812480A28124808801FFC30805FF890801FF810801FFC1000 +7C4B:20403E7E489080007FFC21084104BFFA21083558292835582108355829283558 +7C4C:20803EFE4910FFFC01003FF80000FFFE00023FF00100FFFE00107DFC44907C30 +7C4D:20403F7E4890850810487CFC10487C4811FEFE0010FC388454FC948410FC1084 +7C4E:20403F7E48908508247C3A0422281E1020FE3E124850085E7F5014B0229E4100 +7C4F:20403F7E48908508208011FEFE8821FE20883CF8248824F8248845FE54888904 +7C50:20403E7E489080203D2424A825FC3C4027FE24883D2426AA247044A855248A62 +7C51:20403E7E48909FF0149012501FF00200FFFE09203FF8CA2609200FE808D00E38 +7C52:20403F7E4890850827FE20A0F7BC24A437BC20A067FCA44427FC2444A7FC4404 +7C53:20803EFE4910A03817C01248815047FC524814042BFAE24823F8224823F82208 +7C54:20403E7E489088007F204920FFBE49447FA42A243E281028FF1022281C446282 +7C55:20403F7E48908508104011BC1114FD5411AC304039FC552451FC912411FC1104 +7C56:20403E7E489084203F280424FFFE122073A4122473A812287392121A17A6F842 +7C57:20403E7E4890BFF801007FFE41029D7408801FFC30805FF890801FF810801FFC +7C58:20403E7E489081243CA825FC24403DFE248825443E8A24F0242445FC54A88964 +7C59:20403F7E48908508100029F84408B8F810087DFE1020953450A81D24E2A24040 +7C5A:20803EFE491081F801003FFC21042FE0210827F8249027F024904FF849489FFC +7C5B:20403F7E48908508109010882BFE4448B83211CE7C90108897FE50481C32E1CE +7C5C:20403F7E4890850811FC1154FDFC102015FC182033FED08811FC102053FE2020 +7C5D:20403F7E489085087FFC10001FF808200FE079384FA87AA84AB8792A4AAA9C46 +7C5E:20403E7E4A90A7DE491297D2211265DAA5142FD000003FF80000FFFE11102308 +7C5F:20403F7E489095081080FEF811087EFC548454FC7C8410FC388454FC90481084 +7C60:20403F7E4890950808407E7C2440FF7C00047E7C42407E7C42407E7C4242463E +7C61:20403F7E48908508104010A0FD1012E814061BB832A8D3B81110111052A82444 +7C62:20403F7E4890850808201420223E5D4480A47724552877282210222855448882 +7C63:20403F7E4890FD7C44447C7C44447C7C41045FF441045FF455545FF44544592C +7C64:20403E7E4890912011282AA4FFFE122073A4122473A812287392121A17A6F842 +7C65:20803EFE491082800C6037D8C0063BB82AA83BB800003FF824883FF8248824B8 +7C66:20403F7E489085FC10202BFE4420B9FC11247DFC112495FC50201DFEE02047FE +7C67:20403F7E489085F840802FFC28840BF0E8882BF829402AA8317022A851608FFE +7C68:20403F7E4890850808201420223E5D4280847710551077102228222855448882 +7C69:20403E7E489087F8454824A827F80040EFFC2A1424882BF4210021F052108FFE +7C6A:20803EFE49108882511C5DD048905DD0445E7FF451145DD448945DD444547FE4 +7C6B:20403F7E4890850828503E7C4890FEFE1528264A5FF6149012501FF008201010 +7C6C:20403F7E4890950808287F24147E494855C87F7E08487F7E514855485D7E4340 +7C6D:20403E7E4890BF7E12241B3412A43FFC22403FF822483FF828442F7848428F3E +7C6E:20403E7E4890FFFC44447FFC10A0209045FE792013FC25207DFC012055FE8100 +7C6F:20403F7E489085087FFC10001FF808200FE07BB84AA87BA84AB87BAA492A9AC6 +7C70:20403F7E489085083EF822883EF822883FF831005FF091001FFC082007C0F83E +7C71:20403E7E4890BFF801007FFE41029D7401001D7048907EFCC9907EFC48907EFC +7C72:20403F7E4890850818FE24107E7C81447F7C55447F7C00447F7C55287F445582 +7C73:0100210811080910092001007FFC038005400540092011102108C10601000100 +7C74:06000100028004401830E10E1110092005407FFC0540092011102108C1060100 +7C75:081008104A102A102C100810FEFE18101C102A102A1048108810081008100810 +7C76:080008004AF02A902C900890FE9018901C902A902A90489288920912090E0A00 +7C77:0808081C4AE02A202C200820FE20183E1DE02A202A20482288220822081E0800 +7C78:100013F09490549058901090FC9033F03890549054909092108A108A10861082 +7C79:10401040944054405BFE1088FC88308838885508549090501020105010881304 +7C7A:084008404A402AFE2C800900FE7C18081C102A202A4048808902090208FE0800 +7C7B:01001110092001007FFC05400920111060080100FFFE0280044008203018C006 +7C7C:102010209420542059241124FD2431243924552455249124112411FC10041000 +7C7D:100011FC9404540858101020FC2033FE38205420542090201020102010A01040 +7C7E:1000100095FC544458441144FD44314439445644544490841084110412281410 +7C7F:080808084A082A082CFE0808FE0818081C882A482A4848088808080808280810 +7C80:10101010941054105BFE1010FC10311039105490549090501020105011881606 +7C81:0808081C4AE02A202C200820FE2019FE1C202A202A2048208820082008200820 +7C82:040004000FE01040208003600C187004111009207FFC054009203118C1060100 +7C83:101011109510551259121114FDD83110391055105510911211521192110E1000 +7C84:1008101C95E05500590011FCFD44314439445528552891101110122812441482 +7C85:10801080948054FC59541254FC54309438945524562490441044108411281010 +7C86:10201020942054A858A410A2FD2231203A245424542890081010102010C01300 +7C87:10801040944057FC58001000FDF03110391055105510911211121212120E1400 +7C88:100011F89448544858481048FC4831F838885488548890881088108813FE1000 +7C89:101010509450545058881088FD0432FA38485448544890481088108811281210 +7C8A:208020883CB020C020842C84307C0000111009207FFC054009203118C1060100 +7C8B:1040104095F854485888108AFD0A32263820542057FE90201020102010201020 +7C8C:100411E494245424582411E4FD043104390455E4542490241024102411441084 +7C8D:1008103C95E054205820103CFDE030203820543E57E09020102210221022101E +7C8E:080008FC4A842A842C840884FEFC18A01CA02AA02A904890890809080A040C02 +7C8F:082008204A202A202C2009FEFE2018201C202A502A504850888808C809240A02 +7C90:082008104A102AFE2C820882FE8218FE1C822A802A8048808880090009000A00 +7C91:1000100095FC552459241124FD24312439FC5500550091001102110210FE1000 +7C92:082008104A102A002DFE0800FE0418841C842A482A4848488850081009FE0800 +7C93:088808884A882A882DFE0888FE8818881C882AF82A8848888888088808F80888 +7C94:080008FE4A802A802C8008FCFE8418841C842A842AFC48808880088008FE0800 +7C95:10201020944055FC59041104FD04310439FC5504550491041104110411FC1104 +7C96:10201020942055FE58201020FC2031FC387054A854A891241124122210201020 +7C97:100011F895085508590811F8FD083108390855F8550891081108110817FE1000 +7C98:1020102094205420583E1020FC20302039FC5504550491041104110411FC1104 +7C99:102010209420542059FC1124FD243124392455FC552491241124112411FC1104 +7C9A:1080108094FE55005A201120FD2C31743BA45524553491281122110210FE1000 +7C9B:010001003FF80108FFFE01083FF80100292825482FE823882548292841088108 +7C9C:0100111011101FF0410441047FFC0000111009207FFC054009203118C1060100 +7C9D:100011FE95005500590011FEFD203120393C5524552491241124124412541488 +7C9E:100013FE9450545059FC1154FD54315439545554558C91041104110411FC1104 +7C9F:7FFC044004403FF8244824483FF80000111009207FFC054009203118C1060100 +7CA0:108810889488548859FE1088FC883088388857FE540090881084110412021402 +7CA1:100011FE95025502597A1102FD02317A394A554A554A917A11021102110A1104 +7CA2:0100410021FC0A441448E0A021102608111009207FFC054009203118C1060100 +7CA3:100011DC9554555459541154FD5433FE3954555455549154115412D41224144C +7CA4:02003FF8292825482FE82388254829283FF80000FFFE10001FF8000800500020 +7CA5:0100F93C09040D440B84793C412047E04120793C0B840D440904090451282110 +7CA6:0100111009207FFC054009203118C10610103EFC4210A290149008FE3010C010 +7CA7:10201010941055FE59001110FD103110397C5510551091101110121012FE1400 +7CA8:080009FE4A202A202C4008FCFE8418841C842AFC2A8448848884088408FC0884 +7CA9:10401040944455F458481050FDFE304038805584569890E010821082107E1000 +7CAA:0100111009207FFC054009203118C44604403FF804400440FFFE082010102008 +7CAB:100013FE94205420584011FCFD54315439545554555491541154114411141108 +7CAC:105010509450545059FC1154FD543154395455FC555491541154115411FC1104 +7CAD:082008204A502A482C840902FEFC18001C002AFC2A8448848884088408FC0884 +7CAE:1040102095FC5504590411FCFD04310439FC5520552291141108114411821100 +7CAF:100011F89508550859F81108FD0831F83908550855F89090109011121212140E +7CB0:1008103C95C05404594410A8FC0031F83810542057FE90201020102010A01040 +7CB1:000023F0909042941292E51222502420111009207FFC054009203118C1060100 +7CB2:08000F7C28043F44612892100C683184C000111009207FFC054009203118C106 +7CB3:100011FE9420542059FC1124FD2431FC3924552455FC912010A0104010B0130E +7CB4:100011FC9524552459FC1124FD2431FC3820542055FC90201020102013FE1000 +7CB5:04003FF820C82F2825483FF8254829283FF80000FFFE10001FF8000800500020 +7CB6:100011F89408540859F81008FC0833FE38205622557490A81124122210A01040 +7CB7:1080108094FE55025A42124AFD5230423BFE544254E29152124A104210541008 +7CB8:1088108897FE5488588810F8FC88308838F85488548893FE1000108811041202 +7CB9:1040102095FE540058881088FD5432223800542055FE90201020102010201020 +7CBA:1040108095FC5524592411FCFD24314439FC5490551093FE1010101010101010 +7CBB:100010FC948054F8588010F8FC8033FE39405524552891101108114411821100 +7CBC:080049122A120812FF242A24494888904248774892245A242F92221242128200 +7CBD:2040202023FEAA02700021FCF800200073FE6820A92821242222242220A02040 +7CBE:1020102095FE542058FC1020FDFE300038FC548454FC908410FC108410941088 +7CBF:100011FC9524552459FC1124FD2431FC382057FE547090A81124122210201020 +7CC0:1088108895FE548858881050FC50309439945698549090B210D21092108E1080 +7CC1:10401048948455FE582013FEFC8831243A425588541090621184101810601380 +7CC2:1088108897FE548858F81088FCF83088388857FE550091481184110011FE1000 +7CC3:100010FC948454FC588410FCFC0031FE388054FE552A924A1092112210541088 +7CC4:1040102095FE5502590211FEFD00310039FE55AA55AA92FE12AA12AA14A21086 +7CC5:200021FC2048A83073FE2052F894211072306820ABFE207020A8212426222020 +7CC6:100013FE9420544059FC1154FD54317439545554557491541154115411FC1104 +7CC7:108010BC9484550859FE1320FD20317C3990551055FE91101128112811441182 +7CC8:200023FE2022A920713C2120FAFE240071FC6904A9FC210421FC210421142108 +7CC9:200020882252AA227252228AFA0223FE70886944AA7A20882150202020D82706 +7CCA:1080109E949255D25892109EFC9231D23952555E5552915211D21022102A1044 +7CCB:210820882090ABFE700023C4FA54225473D46A54AA5423D422542244225422C8 +7CCC:2088208821ECA92A72282548F888217E760069FCA904210421FC2104210421FC +7CCD:210820882090AFFE71082108FA10229474A46F38A9082210221024A427BC2084 +7CCE:100011FE9500557C59541154FD7C31543954557C55109110117C1210121014FE +7CCF:200023FE2202AA0273FE2210FA92225472FE6A82AAFE228222FE2482248A2884 +7CD0:1028102497FE542059FC1124FDFC312439FC5524540893FE1088104810481018 +7CD1:200023DE2042A84273DE2210FA1023DE70426A52A94A214A2252204222942108 +7CD2:1088108897FE5488588813FEFC8031FC3B2455FC552491FC112411241124110C +7CD3:1000FE7810487C480048FE8682007CFC104454443828FE281010382854449182 +7CD4:100011FC94A4548858501020FCD83326382055FC5524912411FC102213FE1002 +7CD5:11041084948854005BFE1020FC2031FC3820542057FE900012A4125214521000 +7CD6:1020101095FE5510597C1114FDFE3114397C5510557C914411441244127C1444 +7CD7:2040208023F8AA0873F82208FBF8220873F86850A84827FE20A0211022082C06 +7CD8:1040102095FE5502580010FCFC4030A23B345458549493341052109013501020 +7CD9:101010509650557C58901010FCFE3300397C55445544917C1144110012FE1400 +7CDA:1048104895FE544858001048FD48314839FE5448544893C811481148117E1240 +7CDB:1020112494A857FE5A0210F8FC88308838F85420542091FC1020102013FE1000 +7CDC:010000803FFE22102F7C26382B5432922080249022A03FFC21C042A044989886 +7CDD:2040208821FCA908725223FEF8502188762668C0AB1020642388203020C02700 +7CDE:111009207FFC054019307FFC11101FF011101FF004403FF80440FFFE08201010 +7CDF:2090209027FEA89073FC2294FBFC229473FC6800A9F8210821F8210821F82108 +7CE0:1020101095FE5510597C1114FDFE3114397C5510559291541138125412921430 +7CE1:1040102095FC5488585013FEFC0031FC390455FC550491FC109010921112160E +7CE2:1088108897FE5488580011FCFD0431FC390455FC542093FE1050108811041202 +7CE3:200027BC2108AD2877BC2318FDAA294670006BF8AA08220823F82208220823F8 +7CE4:2288228827C8AA90729E27D4F82427D474546FD4AC5427C824482454246424C2 +7CE5:100011FE942055FE59521152FD523106380055FE542091FE1152115211521106 +7CE6:102013FE942055FC580011FCFD0431FC388857FE540091FC1104110411FC1104 +7CE7:100011FC950455FC590413FEFC0031FC392455FC552491FC102011FC102013FE +7CE8:200023BE20A2A8A270BE2388FA08223E722A6BAAA8AA20BE2088208A257E2202 +7CE9:10201050948855745A0211FCFD2431AC392455FC540090F8108810F8108810F8 +7CEA:00407C2045FC44887C5043FE7C20A5FC24203C20111009207FFC05401930E10E +7CEB:200023FC2294AA9473FC2000FBFE200073FC6A04ABFC20A2211423082D442182 +7CEC:200027FC24A4ACA477FC2048FBF8205077FE6840A9F8230825F8210821F82108 +7CED:202020882252AB267252228AFA2223FE70886944AA7A20882150202020D82706 +7CEE:201027D02510AFDE745027E8FD0427C470006BF8AAA822A822A822A82FFE2000 +7CEF:100011FC942057FE5A2211ACFC2031AC380057FE542091FC115411541154110C +7CF0:23FE222223FEAA2272FA22AAFAFA22AA72FA6A26ABFE220A23FE228A225A23FE +7CF1:52107EFE28447E28A2FE3E1020103E7C22103E10111009207FFC05401930E10E +7CF2:200023FE2248ABFE724822FCFAA422FC72A46AFCAA2023FE232A257A250A2906 +7CF3:553C1424FFA422427F00083CFF8408286B1049287F4410100920FFFE0920711C +7CF4:200011DC2844455490CC11545400384810FEFD9012FC389054FC949010FE1080 +7CF5:0820FFFE28207DFC44887C5041FE7C2045FC7C20111009207FFC05401930E10E +7CF6:540055DC7C44115454CC55547C00004854FE399012FCFC9038FC549092FE1080 +7CF7:208823FE2088ABDE725223DEFA5223DE72226BFEAAAA22FA2222227222AA2224 +7CF8:02000400082010403F800100061018087FFC0104092009101108210445040200 +7CF9:080008001000120022007C000800100024007E00020000005200490089000000 +7CFA:084008401040124022407C400840104024407E400240004452444944893C0000 +7CFB:00F83F000400082010403F800100061018087FFC010409201110210845040200 +7CFC:104010402040244045FCF844104420444844FC84048400845504550482280410 +7CFD:0800080010FE121022107C100810101024107E10021000105210491089500020 +7CFE:080408041044124422447C4408441044244C7E54026400445204490489040004 +7CFF:1000100021FC24444444F844104420444844FC44044400845484550482280410 +7D00:1000100021F824084408F808100821F84908FD00050001005502550280FE0000 +7D01:100013FC210425444524F8A8108820884850FC50042000205450548881040602 +7D02:080808081008120822FE7C080808100824487E28022800085208490889280010 +7D03:10821092209224924492F892109220924892FC92049200925492551281020202 +7D04:10401040208024FC4504FA04100421044884FC44044400045404540480280010 +7D05:1000100021FC24204420F820102020204820FC20042000205420542083FE0000 +7D06:100011FC202024204420F820102023FE4820FC20042000205420542080A00040 +7D07:10401040208024FE4500FA0010FC20084810FC20044000805502550280FE0000 +7D08:104010402040244045F8F848104820484948FCC8044800A854AA550A82060402 +7D09:1000100021FC24444444F944114421444944FE44044400845484550482280410 +7D0A:020001007FFC082007C01830E20E04201FC0018006103FF80108112025104208 +7D0B:10401020202027FE4488F888108820884888FC50045000205450548881040602 +7D0C:10401050204824484440F9FE105020504850FC500490009054925512810E0200 +7D0D:10201020202025FE4522F922112221224952FD4A058A010255025502810A0104 +7D0E:10401048204424444440FBFE104020404840FCA004A000905510550882040402 +7D0F:10081088204824484408F888104820484808FC0E05F800085408540880080008 +7D10:100011F8204824484448F848104821F84888FC88048800885488548883FE0000 +7D11:1000100021FE24104410F8201020206848A4FD22062200205420542080200020 +7D12:10201020205024504488F904120220884888FC88048800885488550881080208 +7D13:100011F8200824504420F81013FE20224824FC20042000205420542080A00040 +7D14:1020102020202BFE4820F124112421244924FDFC0424002054225422801E0000 +7D15:10101110211025124512F91411D821104910FD100510011255525592810E0000 +7D16:100411E4202424244424F9E4110421044904FDE4042400245424542481440084 +7D17:10201020202024A844A4F8A2112221204A24FC24042800085410542080C00300 +7D18:10401040204028404BFEF040108020904890F92009200248AA44AC8481FE0082 +7D19:1004101E21F025104510F910111021FE4910FD1005100108550A554A81860102 +7D1A:100013FC208424884488F890109C20844944FD4405280128AA10AA2884440182 +7D1B:10101090209024884508F904120425FA4888FC88048800885508550882280410 +7D1C:1000100020FC24004400F80011FE20204820FC4004400088548455FE80820000 +7D1D:1008103C21E024204420F820102023FE4820FC20042000205420542081FC0000 +7D1E:10201020202025FE4522FA24102020204850FC5004500050549054928112020E +7D1F:10201020205024504488F944122220204800FDFC040400085408541080100020 +7D20:01003FF801001FF00100FFFE020004201FC0018006103FF80108112025104208 +7D21:10401020202025FE4440F8401040207C4844FC44044400445484548481280210 +7D22:010001003FF8010001007FFE420284241FC0018006103FF80108112025104208 +7D23:1040104021F828484888F08A110A22264820F8200BFE0020A820A82080200020 +7D24:1004100E20F024804480F88010FE20884888FC88048800885488550881080208 +7D25:084008407F4008400E4078440844283C144008801F0002103FF8010815202210 +7D26:1000100021FC25244524F9241124212449FCFD00050001005502550280FE0000 +7D27:040025FC2488245024202450028C04201FC0018006103FF80108112025104208 +7D28:1088108820882908497EF308150821484928FD28050801085508550881280110 +7D29:102010202120252045FCF920122020204BFEFC20045000505488548881040202 +7D2A:1090109020902A904A92F2D4129822904A90FA900A900292AAD2AF12820E0000 +7D2B:088028882EF028842E84F07C020004201FC0018006103FF80108112025104208 +7D2C:102010202020242045FCF924112421244924FDFC052401245524552481FC0104 +7D2D:20082788408840889088E788240844109410F790009410A4A8A2A0BE85020200 +7D2E:042004207FA00E221522649E020004201FC0018006103FF80108112025104208 +7D2F:00003FF821083FF821083FF8020004201FC0018006103FF80108112025104208 +7D30:1000100021FC25244524F9241124212449FCFD24052401245524552481FC0104 +7D31:105010482048244047FEF880108020FC4944FD4405280128AA10AA2884440182 +7D32:10481148214825484548FBFE114821484948FD48057801005500550081FE0000 +7D33:10201020202025FC4524F924112421FC4924FD24052401FC5524542080200020 +7D34:10101010201025FE4512F914111021FC4944FD4405280128A910AA2882440482 +7D35:1040102020202BFE4A02F404100020004BFEFC20042000205420542080A00040 +7D36:10201020202025FC4420F820102023FE4820FC2004400048548455FE80820000 +7D37:10201020205024504488F9241212201049FCFC04040800885450542080100010 +7D38:10401020200025FE4420F8201020202049FCFC20042000205420542083FE0000 +7D39:100011FC204424444444F844109420884900FCFC048400845484548480FC0084 +7D3A:108810882088248847FEF888108820884888FCF8048800885488548880F80088 +7D3B:10201020202025FC4524F924112421244924FFFE042000505450548881040202 +7D3C:1090109020902BFC4894F09413FC22904A90FBFE08920092A91AA91482100410 +7D3D:10201010201025FE4502FA04108020884890FCA004C0008254825482807E0000 +7D3E:10201020205024884504FA12102020404988FC10042000445588541080600380 +7D3F:10201020204024404488F90413FE20024800FDFC050401045504550481FC0104 +7D40:10201020212425244524F92411FC20204820FD24052401245524552481FC0004 +7D41:1080108020FE25004620F920112C21744BA4FD24053401285522550280FE0000 +7D42:10401040207C28844988F250102020504888FB0608600010A808A8C080200010 +7D43:10201010201025FE4420F8201044208449F8FC1004200044548255FE80820000 +7D44:100011F8210825084508F9F8110821084908FDF805080108A908A90887FE0000 +7D45:100011FE210225024502F97A114A214A494AFD4A057A014A55025502810A0104 +7D46:10201020212424A444A8F82011FC20204820FC2007FE00205420542080200020 +7D47:10801080210029FC4A04F40411E421244924FD2405E401245404540480280010 +7D48:10201020204025FC4504F9041104210449FCFD04050401045504550481FC0104 +7D49:102010282024242045FEF8201070207048A8FCA8052402225420542080200020 +7D4A:102010202020242045FEF87010A820A84924FD24062200F85420542080200020 +7D4B:10201010201025FE4500F910111021104910FD2005280124AA44AAFE84420800 +7D4C:100011FC208424884450F820105020884B26FC2005FC00205420542083FE0000 +7D4D:10801088209C25704510FB101510211049FEFD100510011055105510817C0100 +7D4E:10401040209C25004640F84010BE21884A88FC88048800885488548880A80090 +7D4F:1020102021FC25244524F9FC1124212449FCFC2004240018543254CA83060002 +7D50:1020102020202BFE4820F02011FC20004800FDFC050401045504550481FC0104 +7D51:10201120212025FC4520FA20102023FE4870FCA804A801245524562280200020 +7D52:11041124212429244924F12415B4256C4924F92409240124A924AA2482040404 +7D53:1020102021FC24204420F82013FE20004820FC2005FC00205420542083FE0000 +7D54:100013FE202024204440F9FC110421044904FDFC050401045504550481FC0104 +7D55:100013FC204424444484F928121021FC4924FD2405FC01005502550280FE0000 +7D56:10401044224429484950F04017FE20904890FC900490009255125512820E0400 +7D57:1000100021FE25024502F97A114A214A494AFD4A057A0102550255FE81020000 +7D58:101010102210293E4922F044101020904890FB1009280128A928A94480440082 +7D59:100013FE2000240045FCF904110421FC4904FD0405FC01045400540083FE0000 +7D5A:100013FE204024404440F87C108420A44894FD04054400285408540883FE0000 +7D5B:108010F811082290206065986646A48825F02420244825FC2020212422A22040 +7D5C:08007F7C08243E2408447F540A8804201FC0018006103FF80108112025104208 +7D5D:1020102023FE24504488F90412FA20004BFEFC40048001FC5404540480280010 +7D5E:10401020202025FE4400F888110422024888FC88045000505420545080880306 +7D5F:10201020205024884504FA0211FC20204820FC2005FC00205420542083FE0000 +7D60:1020102021FE24404440F8FC108421844AFCFC84048400FC5484548480940088 +7D61:10401040207824884550F820105020884906FCF8048800885488548880F80088 +7D62:1080108021FC25044604F9E41124212449E4FD24052401E45504540480280010 +7D63:110410842088280049FEF088108820884888FBFE08880088A908A90882080408 +7D64:100013FE2050245045FCF954115421544954FD54058C01045504550481FC0104 +7D65:10901094209229124910F37E151021104910FD28052801285528554481440182 +7D66:10201020205024884504FA0211FC20004800FDFC050401045504550481FC0104 +7D67:100011FE21022502457AF9021102217A494AFD4A054A017A55025502810A0104 +7D68:10281024202428204BFEF020112421244924FBA809280110AA12AA2A84460082 +7D69:1090109020902A924994F098109021984A94FC9208900090A912A9128212040E +7D6A:100011FC210425244524F92411FC21244924FD54054C018C5504550481FC0104 +7D6B:040008201FF0102024487EFC020004201FC0018006103FF80108112025104208 +7D6C:1008103C21E024204420FBFE102020204820FDFC050401045504550481FC0104 +7D6D:111009207FFC0200FFFE08203218C4261FC0018006103FF80108112025104208 +7D6E:08007F7C114432440C44327CC20004201FC0018006103FF80108112025104208 +7D6F:10201010201025FE4420F824104420F84812FC22044401885410542880440182 +7D70:100011FE202024404488F90411FE20224820FC2005FE00205420542083FE0000 +7D71:1040102020202BFE4840F088110423FE4892FC900490009055125512820E0400 +7D72:102010202048248845F0F8201040208849FCFC24042000A85524562280A00040 +7D73:1080108020FC29084A90F060119826264820F9FC08200220ABFEA82080200020 +7D74:11041084208828004BFEF020102021FC4820FC2007FE00205420542080200020 +7D75:10201020205028884904F20210F820004800FBFE08200040A888A90483FE0102 +7D76:1040104020F825084610F9FC112421244924FDFC050001005502550280FE0000 +7D77:1080FBF010901990F0941154520C24241FC0018006103FF80108112025104208 +7D78:100011F82108250845F8F908110821F84908FD0805F80090549055128212040E +7D79:100010F82088248844F8F80011FC21044904FDFC0504010455FC550481140108 +7D7A:11841068203028C84B04F04013FE20A04920FBFC0D240124A934A92880200020 +7D7B:1080108020F825084610F9FC112421244924FDFC04500050549054928112020E +7D7C:1008103C21E024964448F830104821944824FC4C059400245444558480280010 +7D7D:100010FC208424844484F88410FC20004800FDFE050201025502550281FE0102 +7D7E:10281024202428204BFEF220122422244BA4FAA80AA80290AA92ADAA84460882 +7D7F:102810242024242045FEF820112020B248B4FC6804A801245622542080A00040 +7D80:1020102023FE24204420F9FC1124212449FCFC20047000A85524562280200020 +7D81:2100211E411247D29114E11427D841149112F7D20112111AA914A21082100410 +7D82:1040102023FE24004400F9FC110421044904FDFC04500050549054928112020E +7D83:1020112420A424A84420F9FC1104210449FCFD04050401FC5504550481140108 +7D84:1040102023FE2A024C04F1F8100020004BFEFC900490009055125512820E0400 +7D85:100011FC200424FC4404F9FC100023FE4A02FDF8048800885450542080D80306 +7D86:100013FE2020242045FCF924112421FC4924FD2405FC012054A0544080B0030E +7D87:100013FE2050245045FCF95411542154498CFD04050401FC5504550481FC0104 +7D88:11081088209025FC4424F82411FC21204920FDFE046200A2552A562484200020 +7D89:101C11E02020242047FEF8A81124222249F8FC88049000BE5502550282140408 +7D8A:1020102020202BFE4820F020112421244924FAAA08200050A850A88881040202 +7D8B:1040102023FE2A024C44F04013FE20404890F89009100120AA24AA4284FE0842 +7D8C:10001050204824844524F820105020884906FEF8048800885488548880F80088 +7D8D:1020102023FE28204820F3FE1202240449F8FC10042003FE5420542080A00040 +7D8E:1000100623B828884888F108113E23884888FA880A88013EA900AA80847E0800 +7D8F:1008103C23C028444A24F128110020404BFEF88809080390A860A85081880604 +7D90:110410842088241045FCF9041104210449FCFC500450009054925512820E0400 +7D91:100013FE22222A224A22F3FE122222624A72FAAA0B220222AA22AA0283FE0202 +7D92:1008103C21C024044544F8A8100021F84810FC2007FE00205420542080A00040 +7D93:100011FE200028924924F248112420924800FDFE042000205420542083FE0000 +7D94:1000100CFEF02820444482F87C100024FEFE201240507C540492051228501020 +7D95:1020102020202BFE4820F020102021FC4840F82008A40282AA8AAA8A84780000 +7D96:1004100E23B828884888F128112E23A848A8FAA80AA8013EA900AA80847E0800 +7D97:100013FE22022A524A8AF306120222FA4A8AFA8A0A8A02FAAA8AAA02820A0204 +7D98:1040104020FC24884550F82010D8232648F8FC2004F8002057FE542080200020 +7D99:10101110211025924554F91011FE21104938FD54059201105510551081FE0000 +7D9A:1020102023FE282049FCF00013FE22024C04F89008900090A890A9128112020E +7D9B:100013FC204429444944F284109421084A40F82008A40282AA8AAA8A84780000 +7D9C:1040102023FE2A024800F1FC100020004BFEF82009280124AA22AC2280A00040 +7D9D:10881088208828884BDEF0881088219C49DCFAAA0AAA04C8A888A88880880088 +7D9E:1008103C21E028204BFEF0A810A820A84BFEFCA804A803FE5420542081FC0000 +7D9F:1040102023FC2A044A04F3FC120022284A24FBFE0A200250AA50AC8885040A02 +7DA0:108010F82088290849F0F010101023FE4820FA22097400A8A924AA2280A00040 +7DA1:1040102023FE24004400F9FC110421044904FDFC042000A85524562280A00040 +7DA2:100011FC212425244574F92411FC21044974FD54055401745504560482140408 +7DA3:1020112420A8242045FCF84013FE20884904FEFA0488008854A854928082007E +7DA4:7E7C12442A484444BE44225422483E00044008801F0002103FF8010815202210 +7DA5:100011FC2124292449FCF124112421FC4800F8000BFE0088A888A88881080208 +7DA6:08207FFC08200FE008200FE00820FFFE14502888DF0602103FF8010815202210 +7DA7:1040102023FE240045FCF90411FC200049FCFC08041003FE5420542080A00040 +7DA8:1088108823FE24884488F8F81088208848F8FC88048803FE5400548881040202 +7DA9:1040102023FE2A024D04F10011DE22524A52FB520C9A0094A910A9128212040E +7DAA:1020102023FE242045FCF82013FE200049FCFD0405FC010455FC550481140108 +7DAB:10481044205E25E04428F812106A21964848FC5E05E0002454285412806A0186 +7DAC:101C13E020842A444948F11017FE24024800FBF809080110A8A0A84081B0060E +7DAD:10A01090208025FE4510FB1015FC21104910FDFC05100110551055FE81000100 +7DAE:104008403E7E228823503E2020584186844008801F0002103FF8010815202210 +7DAF:1080108021FC25044684F8F4114420444BFCFC440554015455F4540480280010 +7DB0:1040102023FE2A024C04F1F81108210849F8FD00050001FC5504550481FC0104 +7DB1:100013FE22022A8A4A52F3FE122222224AAAFAAA0AAA02FAAA02AA02820A0204 +7DB2:100011FE2102218A4952F9FE1122211221FE4942F542017A55025502550A8104 +7DB3:100013DE22522A524A52F3DE125222524A52FBDE0A520252AA52AA52855208A6 +7DB4:100013DE2042294A4884F14A125224204800FBDE08520152A894A94882540422 +7DB5:1008103C23C028444A24F128110020204BFEF87008A800A8A924AA2284200020 +7DB6:100011FC2124292449FCF124112421FC4820FBFE087000A8A924AA2280200020 +7DB7:1040102021FE24004488F888115422224800FC2005FE00205420542080200020 +7DB8:10201020205024884504FAFA100021FC4954FD5405FC0154555455548104010C +7DB9:1088108820E8252C452AFAA8104820A0491EFE0004FC00845484548480FC0084 +7DBA:1020102021FC24504488F90413FE200849E8FD28052801E85528540880280010 +7DBB:1040102023FE2A024C04F00013FE20204820F920093C0120AAA0AA60843E0800 +7DBC:1040108021FC25244524F9FC1124214449FCFC90051003FE5410541080100010 +7DBD:10201020203E242045FCF90411FC210449FCFD24042003FE5420542080200020 +7DBE:1020102021FC28204820F3FE108821444A42F8F809880250A820A85081880606 +7DBF:1020104021FC290449FCF10411FC20204820FBFE0A220222AA2AAA2480200020 +7DC0:1020102023FE242045FCF82413FE202449FCFC4007FE008455C8543080CC0302 +7DC1:1020102023FE242045FCF82413FE202449FCFC200520013EA920AAA0827E0400 +7DC2:1020112221222A244850F088130420224820F92409240228A850A88881040602 +7DC3:10881088208824884554FA22144220204820FD20053C0120AAA0AA60843E0800 +7DC4:100011FC2104250445FCF904110421FC4800FD1205D40118551055528192010E +7DC5:20002FC044BC44A494A4E7A424A444A897A8F4A8049015D0AEA8A0A880C40082 +7DC6:100011FC210425FC4504F9FC1080208049FEFE4A044A0092A922AA4280940108 +7DC7:1092109221242A484924F0921092200049FEFD22052201FE5522552281FE0102 +7DC8:1020102021FC24204420FBFE1088205049FCFC20042003FE5420542080200020 +7DC9:100013FE202028204BFEF222122223324AAAFAAA0B760266AA22AA22822A0204 +7DCA:7EFC48447E4442287E1048287EC604201FC0018006103FF80108112025104208 +7DCB:1090109020902B9E4890F0901090239C4890F8900890039EA890A89080900090 +7DCC:101C11E0202028204BFEF0A8112422424840FBFE08880108A8D0A83080480184 +7DCD:101C13E022202BFE4A20F292130A220649FCFD04050401FC5504550481FC0104 +7DCE:1014101220102BFE4810F01013D222524A52FA540BD4000CA86AAB8A81160022 +7DCF:10901090210829484A44F492110823FC4844F82008A40282AA8AAA8A84780000 +7DD0:4000400C7EF080207C4444F864105424FEFE4412A4509454FE92051228501020 +7DD1:100011F82008280849F8F008100823FE4820FA22097400A8A924AA2280A00040 +7DD2:1020102221FA24244428FBFE1020204048FCFD84068400FC5484548480FC0084 +7DD3:1088108823FE288848A8F02011FC21244924F9240BFE0020A850A88881040202 +7DD4:1020112420A428A84820F3FE120222024AFAFA8A0A8A028AAAFAAA02820A0204 +7DD5:1040102023FE24884450F82010D823064888FCF80488008854F8550881080208 +7DD6:1020102221FA24244428FBFE1024204248FCFD84068400FC5484548480FC0084 +7DD7:11001100213C29244BA4F124113C23A44B64FD24093C0124A924A924813C0124 +7DD8:1008100C200A2BFE4A08F20812E8220A4A0AFAEC0AAC02A8AAEAAA1A82260442 +7DD9:1088108823FE248844F8F82011FC21244924FDFC042003FE5420542080200020 +7DDA:1040108021FC290449FCF10411FC20204832FBB408A80128A924AA2484A20040 +7DDB:100013FE2020244045FCF954115421544954FD2C042003FE5450548881040202 +7DDC:1000200C7CF044207C4444F87C10102410FEFE12925092549292971210501020 +7DDD:100011F82108290849F8F00017FE210849F8F90809F80108A93EAFC880080008 +7DDE:1080133822282A284BA8F2461200227C4BA4FA240A2803A8AE10AA2882440282 +7DDF:1008103C21E028204BFEF02011FC212449FCFD2405FC002055FC542083FE0000 +7DE0:1080104023FC28004908F09017FE24424844FBFC0A440244AA54AA4880400040 +7DE1:100011FC210425FC4510F9FE1110214A4986FC0005FC010455FC550481FC0104 +7DE2:1088108823FE24884488F80011FC21244924FD2405FC01245524552481FC0104 +7DE3:108010FC210429F84808F3FE104020A24B34F85808940334A852A89083500020 +7DE4:1048114821482BFE4948F1481178210049FEF8200BFE0070A8A8A92486220020 +7DE5:1100117C21442A444A44F67C1A1022104AFEFA380A540254AA94AB1282100210 +7DE6:100011FC2124252445FCF924112421FC4820FC10045401425542554A82380000 +7DE7:1088104820502BFE4850F05011FC21544954FD8C050401FC5504550481FC0104 +7DE8:1040102021FE25024502F9FE1100210049FEFDAA05AA02FEAAAAAAAA84A20086 +7DE9:101E13E0204425244488F9FC104020404BFEFC8004FC01445528561080680186 +7DEA:1100117E211025104590F95E1322252A4926FD420552010C55045504817E0100 +7DEB:1080108020FC29544AD4F0B4112C22444894F908084000A4AAAAAA8A84780000 +7DEC:100017FE204028804BFCF294129422F44A94FA940AF40294AA94AA9483FC0204 +7DED:100013FE22222BFE4A22F3FE100021FC4904FDFC050401FC5504550481140108 +7DEE:1100110021FE2A004DFCF10411FC210449FCFC8004FC01085690546081980606 +7DEF:1040104021FC28844BFEF00011FC210449FCF8200BFE0020AA20ABFE80200020 +7DF0:104010A021102A084DF6F00013C422544A54FBD40A540254ABD4AA44825402C8 +7DF1:1100117821082A084AFEF6401A40227C4A90FA100AFE0210AA28AA2882440282 +7DF2:1010101023902A904A94F3B212B222D24B90FA940A840388AA90A82080400180 +7DF3:010000803FFE22003FBC22142F9422143FA4220C24202FC041085FFC88881184 +7DF4:1020102023FE242045FCF92411AC21744924FDFC0420007054A8552482220020 +7DF5:1000108822522A224A52F28A120223FE4888F9440A7A0088A950A82080D80306 +7DF6:110011FE21102A104AFEF292169222FE4A92FA920AFE0290AA50AA2082580286 +7DF7:100013FE2222242045FEF82011FC212449FCFD2405FC002057FE542080200020 +7DF8:100013FE2050245045FCF9541154215449FCFC20042001FC5420542083FE0000 +7DF9:100011FC2104290449FCF104110421FC4800FBFE08200120A93CA92082A0047E +7DFA:100010FC2084248444F4F894109421FE4902FD7A054A014A557A5502810A0104 +7DFB:2008200847C84210921EE4A427D441149114F7D401141108A9C8AE1484140022 +7DFC:100010F82088248844F8F888108820F84800FDFC055401545554555483FE0000 +7DFD:10201020203E24204420F9FC110421FC4904FDFC050401FC5400548881040202 +7DFE:100011FE2100257C4554F954117C21544954FD7C05100110557C5610821004FE +7DFF:1040109021082BFC4804F00011F821084908F9F808400024AAA2AA8A84880078 +7E00:100013DE22422A424A42F3DE1200223E4BD2FA120A1403D4AA08AA1482240242 +7E01:100011FC200428FC4804F3FE104020A24B34F85808940334A852A89083500020 +7E02:10881048205025FC4504F904110421FC4820FC10045401425542554A82380000 +7E03:100013FE20222520453CF92012FE240049FCFD0405FC010455FC550481140108 +7E04:100011FC212425FC4524F9FC102021FC4924FDFC052401FC542054228022001E +7E05:100C100A20082BFE4A08F3F8124A224A4BEAFAAC0AAC024CAAAAAB0A82160422 +7E06:2100213C4100410091BCE5642524453C9524F1240124113CA924A100817E0100 +7E07:1040102023FE2A024C04F1FC100021FC4904FDFC050401FC5504540083FE0000 +7E08:08202AA44D28145022887FFE420284241FC0018006103FF80108112025104208 +7E09:100013FC20902A944998F09017FE200049F8FD08050801F85508550881F80108 +7E0A:11041084208828004BFEF000108821044A02F9FC09540154A954A95487FE0000 +7E0B:10101220217C25444444F87C13402140497CFD440544017CA944AA80847E0000 +7E0C:124411242128247E4410FB5411542154497CFD1405200120A940AA80847E0000 +7E0D:1020101021FE24844448F9FE110222244810FDFE0440007C5444548480940108 +7E0E:100011FC210425E44524FBFE120221FC4904FDFC050401FC5504550481140108 +7E0F:08783E48228E2A007EF822482A3046CC844008801F0002103FF8010815202210 +7E10:1080108021FC2A444954F1F4108421284A90F9FC0A440554A9F4A88481280210 +7E11:10881050200025FE4450F9FC105423FE4854FDFC045000D85554565280500050 +7E12:10841044204825FE4420F8FC102021FE4840FC8004FE01105610541081FE0000 +7E13:100011FE21102520457CF944117C2144497CFD1005100154A952AA9282500420 +7E14:11F810882070298C4800F3DE1252218C4A52F8200BFE0070A8A8A92486220020 +7E15:100010F820A824A844D8F88810F820004800FDFC055401545554555483FE0000 +7E16:1040102023FE2A024C24F1FC102021FC4820FBFE082001FCA904A90481FC0104 +7E17:1040102023FE280049FCF10417FE210449FCFC5204940188568854A480C20080 +7E18:101E13E0212228944840F08811F0202048C4F9FE08220020ABFEA85080880306 +7E19:1088108821FE24884400F9FE1088208848F8FC8804F80088549E55E880080008 +7E1A:101E11E0202225124494F880102021CE4902FD0205CE01025502550281FE0102 +7E1B:1028102423FE242045FCF92411FC212449FCFD24040803FE5488544880480018 +7E1C:100010FC2084248444FCF80011FE210249FEFD0205FE010255FE544880840102 +7E1D:1020102023FE242045FCF90411FC210449FCFD0405FC010457FE548881040202 +7E1E:1040102023FC280049F8F10811F820004BFCFA040AF40294AAF4AA0482140208 +7E1F:100013FE220022FC4A00FBFE12A822904AC8FA860A0813FEAA88A44884080818 +7E20:1000FE7810487C480048FE8682007CFC2044444478281428FE10542892443182 +7E21:1040102023FE2A424820F1FC108820504BFEFC20042001FC5420542080200020 +7E22:0020792448A849FC48407BFE488849444A8A78F0482449FC482049244A229860 +7E23:00007C0C44F07C2044447CF844107C2444FEFE12105054545292931250502020 +7E24:1020102023FE242045FCF82013FE20404888FDF0042403FE5422552482A20040 +7E25:1020102023FE242045FCF84013FE20884934FEE2042001FC547054AC83220020 +7E26:108010A2211225144680F8FE110821084B28FD2E0528012855285558814E0180 +7E27:1110111E21222A544A08F6941AE222884A88FABE0A8802ACAA2AAA4A82280210 +7E28:100011FC210425FC4504F9FC1020212448A8FC2007FE0090549055128212040E +7E29:1100111023DC2A544D54F288110822F44C02F8000BFC0040A950AA4885440080 +7E2A:100011FC212425FC4524F9FC10A820A84BFEFCA804A801FCA820ABFE80200020 +7E2B:1020147C228429484830F0CE1610227C4A10FA7C0A1002FEAA10AA1085FE0800 +7E2C:100C100A200823FE4A08FA48126A224A4BFAFA4C0A4C12ECAB5AA44A84D60822 +7E2D:1040102023FE28004954F124115421FC4820FBFE0A420292AAFAAA0A82020206 +7E2E:1020101023FE2A024880F0FE111023204D7CF9440944017CA944A944817C0144 +7E2F:1040102023FE2A024800F1FC102021FC4924FDFC052401FC5400548881040202 +7E30:11081108222824AE44A8F928137E25004908FD28052E01285558554881860100 +7E31:1124112422242C244954F14A129226104A10FA500A5C0250AA50AAB0829E0300 +7E32:100011FC212425FC4524F9FC1040208849F0FC20044403FE5422552482220060 +7E33:102013FE202025FC4524F9FC112421FC4822FDFE040801FE5508548880280010 +7E34:102013FE204820F04820FBFE1242209049F8F828092011FCAA20A7FE80200020 +7E35:100011F8210829F84908F1F8100023FC4A94FBFC080001F8A890A86081980606 +7E36:08207E2008F8FF2814287F6A082AFF560A8204200FC002103FF8010815202210 +7E37:102011FC21242BFE4924F1FC102021FC4924FDFC044003FE548855D08070038C +7E38:1088108823FE24884400F9FC110421FC4904FDFC042003FE5450548881040202 +7E39:100013FE205025FC4554F95411FC200049FCFC0007FE002054A8552482A20040 +7E3A:1010101022FE2510457CF854107C2354497CFD1005FE0110A910AA90847E0000 +7E3B:010000803FFE22102F7C26382B543292210827F0206023842FFE404245488884 +7E3C:12101110211027BE4A40FA0013BE228A4A88FAA80AAE12A8ACA8A5A8885E1080 +7E3D:1020104021FC2524457CF98C115421244954FDFC0420001055545542814A0238 +7E3E:102013FE202025FC4420FBFE100021FC4904FDFC050401FC550455FC80880104 +7E3F:1040108821FC29084A52F3FE105021884E26F8C00B100064AB88A83080C00700 +7E40:1020122223FE28904888F1FE1310251049FEFD10051001FE5510551081FE0100 +7E41:20203F20403EBE482AA8FF284A107F28044608801F0002103FF8010815202210 +7E42:1040102023FE28204848F2F21124225248F8FC08042003FE5420542080200020 +7E43:1020122222222BFE4800F3DE125222524BDEFA520A5203DEAA52AA52855A08A4 +7E44:7F7848485F4C64805F784A4851307F4C044008801F0002103FF8010815202210 +7E45:112412482124280049FCF12411FC212449FCF8200BFE0070A8A8A92486220020 +7E46:100013DE20422A52494AF252102820C44B12F86009880032A9C4A81880600380 +7E47:00000E0CF0F02220924444F820103C2450FE1012FE501054549255125C506420 +7E48:10081388209028A448BEF38A1208223E4A2AFBAA08AA00BEA888A88A82BE0102 +7E49:11FC110421FC250445FCF90411FC20504954FCD804D80154565254908092010E +7E4A:1088108C23EA28884888F7FE1008214A494AFD5A0B6C014CA94AA9EA87160022 +7E4B:1078FE4810487C8654787C485430FECE144008801F0002103FF8010815202210 +7E4C:1040108023FC2A944A64F29413FC20904908FA840CFA0108AA90A86081980606 +7E4D:1020102021FC242447FEF82411FC202049ACFD74052401FCA964AAB4832C0424 +7E4E:1110111421D22A504A7EF550109022A84928F9440A440482A808AAA482520452 +7E4F:100013DE22522BDE4A10F25211CE20004888FBFE08880088ABFEA88881040202 +7E50:1020102023FE282049FCF12411FC212449FCF8220BFE0042A824AAA2828A0478 +7E51:101811E020402BFE4888F174125220704800FDFC05040174555455748104010C +7E52:1104108820002BFE4A22F2AA127222224BFEF80009FC0104A9FCA90481FC0104 +7E53:100011F8210821F84908F9F8100027FE4A40FBDC0A5413D4AA68A7C880540062 +7E54:1110109423D228124A50F19017FE20104BD2FA520A5403D4AA4AAA4A83D60022 +7E55:1088105023FE282049FCF02013FE212448A8FBFE080001FCA904A90481FC0104 +7E56:2288228847C84290929EEFD4202447D49454F7D4045417C8AC48A454846404C2 +7E57:1020112420A82BFE48A8F124122221044904F9DE0A440554A89EA90482040404 +7E58:100013FC204828304BFEF052109423504820FBFE0A52028AAB76AA5282720206 +7E59:103C13E0212428A84BFEF0A81124220249FCFD24052401FC5524552481FC0104 +7E5A:1020102021FC24204554F888110422FA4888FCF8048800F8542054A881240060 +7E5B:081008107F1E08103E7E0842FF7E22427C7E085212107F7E08102A1049101810 +7E5C:1088105023FE245045FCF954118C21744904FDFC040803FE5508548880A80010 +7E5D:13DE125223DE2A524BDEF20212F222924AF2FA920AF20292AA92AB3282020206 +7E5E:1020102021FC28204BFEF108139C21084988FE3E080003FEA890A8908112020E +7E5F:100013DE22522A524BDEF00011FC212449FCFD2405FC002057FE542080200020 +7E60:01002488242443E4000024241212A0A0A4A41C1C04201FC002103FF809201310 +7E61:204023F8404847FE9048E3F820404554975CF44407FC1444AF5CA55485540844 +7E62:102011FC212425FC4420FBFE100021FC4904FDFC050401FC550455FC80880104 +7E63:102011FC20242BFE4824F1FC102023FE4800FDFC052401FC552455FC800003FE +7E64:0820FFFE08201FF01490125011301FF00400FFFE12502F88C2261FF009481320 +7E65:102013FE202029FC4800F1FC110421FC4888FBFE080001FCA904A90481FC0104 +7E66:2000277C41444144917CE7102410447C9454F7540154117CA910A1148AFE0402 +7E67:100011FC20202BFE4A22F1AC102021AC4800FDFC040003FE5440548881FC0084 +7E68:10101210217C241044FEF844132821FE4910FD7C051001FE5510551082FE0400 +7E69:100011FC2154255445DCF85011DC21544954FDDC0554015455DC55508052003E +7E6A:10201050208829744A02F1FC112421AC4924FDFC040000F8548854F8808800F8 +7E6B:0878FFC808483E862B783E482A28FF9049287F4604201FC002103FF809201310 +7E6C:1020102023FE29244924F2AA17FE200049FCFD04057401545574550481FC0104 +7E6D:0820FFFE082000007FFC4924492455FC5DAC49FC55245D3C41CC6B0441144008 +7E6E:100013FE200025FC4524F9FC112423FE4800FDFC052401FC552455FC800003FE +7E6F:100013FC22942A944BFCF00017FE20004BFCFA040BFC00A2A914AB088D440182 +7E70:11FC1104210429FC4800F3DE125222524BDEF8200BFE0070A8A8A92486220020 +7E71:108813FE208829004BFCF55410D423244854F8940B480020A8A4AA8A828A0478 +7E72:110011DE224A2C8A4BEAF2B612A423F44ABEFAA40BE402BEAAA4AAA482240464 +7E73:2108220847C8445097DEE46427D442149114F7D4021413C8AA48A454855408A2 +7E74:3E1022FE3E4420287EFEA2103EFC2210045008801F0002103FF8010815202210 +7E75:102017FE20002BFE4A02F2FA128A23FE4800F9FC090401FCA904A9FC800007FE +7E76:1040102021FC24884450FBFE100021FC4904FDFC050401FCA820AA94828A047A +7E77:109013FC229423FC4A94FBFC100023FC4A00FAF80A0013FEAD20A51485480986 +7E78:10881448225028FC4820F050169422384A50FA980A340254AA90AA2085FE0800 +7E79:100011FC215425FC4420F9FC102023FE4888FC5005FC002057FE542080200020 +7E7A:1210121023D02C5E48A4F3D4105420544BC8F848085407E2A800AAA482520452 +7E7B:100011FC20202BFE4A22F1AC102021AC4800FBFE082001FCA954A9548154010C +7E7C:1044128422EA2A4E4AA4F2EE122223FE4A44FA840AEA024EAAA4AAEE822203FE +7E7D:1040102023FE2A0249FCF148125021FC4B04F9FC090401FCA904A9FC80880104 +7E7E:1010107C2254257C4510F8FE1000237C4944FD7C0540017C5544557C8280047E +7E7F:100813E822882BEE4A28F3F4128223E24800F9FC09540154A954A95487FE0000 +7E80:112811AA216C2A284AFEF64416282AFE4A10FA7C0A1002FEAA10AA2882440282 +7E81:101C11E020202BFE4820F1FC11AC217449FCFC2005FC002057FE54008154022A +7E82:20403E7E4890BFF8248822483FF80200FFFE092012502F88C2261FF009481320 +7E83:2080204047FC411090A4EF58255445529B58F000020813F8AA08A3F882080408 +7E84:108813FE208828204A3CF144103820D64B38F910097C0110A97EA910831004FE +7E85:244424E448A84AAA9EEEE4A42AAA4EEE9242F0400FFE10E0A950A2488C460040 +7E86:11FC112421AC252445FCF82011FC20204BFEFD54062A002055FC542083FE0000 +7E87:920054FEFE10302054FC9284208444FC788410FC2484FE8410FC544892843102 +7E88:1100113E21082FD0493EF12213A2203E4822FBBE0AA202A2AABEAB8082940022 +7E89:108811DC20882BDE4888F154122221FC4904FDFC050401FC550455FC80880104 +7E8A:1020101021FE2528457CF92811FE2110497CFD54057C0154A97CAA0082440482 +7E8B:13FC104021F8290849F8F10817FE24424AA4FA8A0C7A0080A9F8AA888070038E +7E8C:102013FE202029FC4800F3FE125223FE4904FDFC050401FC550455FC80880104 +7E8D:1FF011101FF011103FF82AA83EF82AA83EF808801F0002103FF8010815202210 +7E8E:1088108C23EA28884888F3FE1148236A494AFB6A094C036CA94AA96A87960022 +7E8F:202027FE440045FC9524E5FC252445FC9420F5FC042017FEAD24AAFA882013FE +7E90:1200113E27C828104ABEF262142220BE4AA2FABE09220122AABEAA8084140022 +7E91:1040107C20402BFC4A44F3F0124422FC4AA8FAF80AA802F8AA00ADFC85540BFE +7E92:13FE120022FE22924AFEFA9212FE22104AFEFA100BFE12AAAA10A2FE841009FE +7E93:13DE125223DE2A524BDEF25213DE218C4A52F8400FFE0088A990A86080D80304 +7E94:11F0121027FC2A044BFCF22413B8222249FEFA100FFC0244ABFCA8D0814A063E +7E95:102013FE200029DC4954F1DC108823FE4888FBFE088807FEA894A98886A400C2 +7E96:1148114C22AA28084FFEF1481368214A4B6AF94C0B6C0148A96AAB9A80260042 +7E97:122213FE209029FE4B10F5FE111021FE4910F9FE090003FEAA8AAB7682520276 +7E98:252827BE494847BE9318E5AA294643FC9204F3FC020413FCAA04A3FC81080204 +7E99:200023FE4252425293FEE1082154425E97B4F11E025417DEA814A554855E0010 +7E9A:13DE100023DE2A524B5AF252102023FE4A50FBFE0A5203FEAA92AADC829204CE +7E9B:0100FFFE01001FF01210FFFE10901FF0001C3EE022242AF82A24FFFE2A5459B2 +7E9C:1790151E27A82C844FBEF52A17BE20004BF8FA080BF80208ABF8A8A08124061C +7E9D:11FC112421FC29244BFEF2AA13FE22AA4BFEF88809F00064ABFEA92482220060 +7E9E:444444E44A0A4EEEA404AAEACE0E40E04AAA8AEAA040E0240522A50AA90800F8 +7E9F:10001000200024004400F800100020004000FC00400000001C00E00040000000 +7EA0:10041004208424844484F88410842084408CFCB440C400841C04E00440040004 +7EA1:100011FC202024204420F820102023FE4020FC20402000201C20E02040A00040 +7EA2:1000100021FC24204420F820102020204020FC20402000201C20E02043FE0000 +7EA3:100810082008240845FEF808100820084088FC48404800081C08E00840280010 +7EA4:1008103C21E024204420F820102023FE4020FC20402000201C20E02040200020 +7EA5:10401040208024FE4500FA0010FC20084010FC20404000801D02E10240FE0000 +7EA6:108010802080210445FEFA04140420844044FC24002400041C04E04440280010 +7EA7:100013FC208420884888F890109C20844144F944412801281A10E22844440182 +7EA8:104010402040244045F8F848104820484148FCC8404800A81CAAE10A42060402 +7EA9:10201010201025FE4500F900110021004100FD00410001001D00E20042000400 +7EAA:1000100023F820084808F008100823F84208FA00420002021A02E20241FE0000 +7EAB:1000100023FC20444844FA44124422444484F884408401041904E20444280810 +7EAC:10201020202025FE4420F82010FC20204020FDFE402200221C2AE02440200020 +7EAD:1000100021FC24004400F80013FE20204020FC40404000881D04E3FE41020000 +7EAE:10401040204020404BFEF840108020904090F920412002481A44E48441FE0082 +7EAF:10401040204023FC4840FA48124822484248FBF8404800401842E042403E0000 +7EB0:10101110211025124512F91411D821104110FD10411001121D52E192410E0000 +7EB1:10401040204021484944FA42124224484048F848401000101820E04041800600 +7EB2:100013FC220422044A94FA54122422244254FA54429403041A04E20442140208 +7EB3:10201020202020204BFEF222122222224252FA4A428A03021A02E202420A0204 +7EB4:1008103C21E024204420F820102023FE4020FC20402000201C20E02041FC0000 +7EB5:11101110211021104910F910111021104110FAA8426802281C44E44448841102 +7EB6:1040104020A020A04910FA08140621104120F940418001001904E10440FC0000 +7EB7:10101090209020884908F904120425FA4088F888408800881908E10842280410 +7EB8:1008103C23E022204A20FA20122023FE4220FA10421002121A0AE28A43060202 +7EB9:10801040204027FC4910F110111021104110F8A040A0004018A0E11042080C06 +7EBA:10401020202027FE4480F880108020FC4084FC84408400841D04E10442280410 +7EBB:104010202020240045FEF902120420004000FC00400000001C00E1FE40000000 +7EBC:100411E4202424244424F9E4110421044104FDE4402400241C24E02441440084 +7EBD:100011FC204424444444F844104421FC4084FC84408400841C84E08447FE0000 +7EBE:100011F8200824504420F81013FE20224024FC20402000201C20E02040A00040 +7EBF:105010482040245C45E0F840105E23E04044FC48403000221C52E08A43060002 +7EC0:110811082108250847FEF908110821084108FDF8410801081D08E10841F80108 +7EC1:10481248224822484A48F7FE124822484248FA48427802001A00E20043FE0000 +7EC2:10501048204820404BFEF880108020FC4144F944412801281A10E22844440182 +7EC3:1040104027FC20804880FBE01120222043FCF820412801241A22E42240A00040 +7EC4:100011F8210821084908F9F8110821084108F9F8410801081908E10847FE0000 +7EC5:10201020202025FC4524F924112421FC4124FD24412401FC1D24E02040200020 +7EC6:1000100021FC25244524F9241124212441FCFD24412401241D24E12441FC0104 +7EC7:1000100021FC25044504F9041104210441FCFD04400000901C88E10442020402 +7EC8:1080108020F821084B10FCA0104020A04318FC0640C000201810E18040600010 +7EC9:1080108020F821084A10FC2013FC20044004F80441FC00041804E00443FC0004 +7ECA:10201020212424A444A8F82011FC20204020FC2043FE00201C20E02040200020 +7ECB:10901090209023FC4894F89413FC22904290FBFE40920092191AE11442100410 +7ECC:10201020212425244524F92411FC20204020FD24412401241D24E12441FC0004 +7ECD:100013FC208420844884F904111422084400F9FC410401041904E10441FC0104 +7ECE:100013FC210420884850F82010D823264020F9FC402000201BFEE02040200020 +7ECF:100011FC200824104430F848108423024000FDFC402000201C20E02043FE0000 +7ED0:10201020204024884504FBFE1002200041FCFD04410401041D04E10441FC0104 +7ED1:2100211E211247D25114F11427D821144112F7D24112011A3114C21002100410 +7ED2:10281024202420204BFEF820112421244124FBA8412801101A12E22A44460082 +7ED3:10201020202027FE4420F82011FC20004000FDFC410401041D04E10441FC0104 +7ED4:1040104027FC20A04910FA081DF6200047FCF880410003F81808E00840500020 +7ED5:1080108020BC23C04850F82410D4230C4000FBFE409000901912E112420E0400 +7ED6:100011FE202024404488F90411FE20224020FC2041FE00201C20E02043FE0000 +7ED7:10801080213C22004C80F080117E23084508F908410801081908E10841280110 +7ED8:1040104020A021104A08F40611F020004000FBFC404000801910E20847FC0204 +7ED9:1040104020A021104A08F40613F820004000FBF8420802081A08E20843F80208 +7EDA:10801080210021FC4A04F40413E422244224FBE4422402241BE4E00440280010 +7EDB:1080108020FC21084A90F860119826264020F9FC402002201BFEE02040200020 +7EDC:1080108020F821084B10FCA0104020A04118FA0645F801081908E10841F80108 +7EDD:1080108020F821084A10F5FC112421244124F9FC410001001902E10240FE0000 +7EDE:10401020202025FE4400F888110422024088FC88405000501C20E05040880306 +7EDF:10401020202023FE4840F888110423FE4092F890409000901912E112420E0400 +7EE0:100013FE2020242045FCF924112421FC4124FD2441FC01201CA0E04040B0030E +7EE1:1020112420A424A84420F9FC1104210441FCFD04410401FC1D04E10441140108 +7EE2:100011F82108210849F8F80013FC22044204FBFC420402041BFCE20442140208 +7EE3:103813C0204020404FFCF9501248244643F0F9104120017C1A04E20444280810 +7EE4:10001050204824844524F820105020884106FCF8408800881C88E08840F80088 +7EE5:1008103C23C020444A24F9281100204043FEF888410803901860E05041880604 +7EE6:1080108021F823084C90F060119826464040FBFC404002481A44E44441400080 +7EE7:10201220222023244AA8F22013FC22204270FAA8432402201A20E22043FE0000 +7EE8:11081088209023FC4824F82413FC22204220FBFE406200A2192AE22444200020 +7EE9:1040104027FC20404BF8F04017FE200043F8FA08424802481A48E0A041100608 +7EEA:1040104423F420484850F7FE1040208041F8FB08450801F81908E10841F80108 +7EEB:1020102021FC20204820FBFE108821444242F8F8418802501820E05041880606 +7EEC:1088108823FE248844A8F82011FC21244124FD2443FE00201C50E08841040202 +7EED:1020102021FC24204420FBFE100220944050FD10409003FE1C28E04440820302 +7EEE:1020102021FC24504488F90413FE200841E8FD28412801E81D28E00840280010 +7EEF:109010902090279E4890F8901090239C4090F8904090079E1890E09040900090 +7EF0:10401040207E20404BFCFA0413FC220443FCFA44404007FE1840E04040400040 +7EF1:1020112420A420A84820FBFE1202220242FAFA8A428A028A1AFAE202420A0204 +7EF2:100011FC2104250445FCF904110421FC4000FD1241D401181D10E1524192010E +7EF3:100011F02110211049F0F84013F822484248FBF8424802481BFAE0424042003E +7EF4:10A01090208025FE4510FB1015FC21104110FDFC411001101D10E1FE41000100 +7EF5:1020104021FC210449FCF10411FC20204020FBFE422202221A2AE22440200020 +7EF6:101C13E0208422444948F91017FE24024000FBF84108011018A0E04041B0060E +7EF7:200027BC24A444A454A4F7BC24A424A444A4F7BC44A404A434A4C4A40AA4114C +7EF8:100013FE222222224AFAFA22122223FE4202FAFA428A028A1AFAE202420A0404 +7EF9:1080108020FE25024682F8F21142204243FAFC42415201521DF2E00240140008 +7EFA:1088108821EC212A4A28F5481088217E4600F80041FC01041904E10441FC0104 +7EFB:10401248215020404BF8F88017FC21104208FDF4491201101950E124410400FC +7EFC:1040102023FE22024800F9FC1000200043FEF820412801241A22E42240A00040 +7EFD:1040102023FE22024C04F80013FE20204020F920413C01201AA0E260443E0800 +7EFE:1040102023FE22024C04F9F81108210841F8F900410001FC1904E10441FC0104 +7EFF:100011F82008200849F8F808100823FE4020FA22417400A81924E22240A00040 +7F00:200027BC208442945108F29424A428404000F7BC40A402A43128C29004A80846 +7F01:11241124224824904A48F9241124200043FCFA44424403FC1A44E24443FC0204 +7F02:1088108823FE248844F8F82011FC21244124FDFC402003FE1C20E02040200020 +7F03:11001100213E21224FA2F122113E23A24362FD22493E01221922E122413E0122 +7F04:20142012201047FE5410F41025D024124412F5D44554054835DAC42A08461082 +7F05:100017FE204020804BFCF294129422F44294FA9442F402941A94E29443FC0204 +7F06:10901290229E22A84AC4F88011FC21044124F924412401541850E0904112060E +7F07:100011FC2104210449FCF904110421FC4000FBFE40200120193CE12042A0047E +7F08:20102010271045105514F752255225924710F514450807103520C04000800300 +7F09:100011F82108210849F8F00017FE210841F8F90841F80108193EE7C840080008 +7F0A:100011F82108210849F8F908110821F84000FBFC429402941A94E29447FE0000 +7F0B:1020102021FC252445FCF82013FE200041FCFD04412401241D24E05040880304 +7F0C:100011FC2124212449FCF924112421FC4000F840402402A21A8AE48840780000 +7F0D:1008103C21E020204820FBFE1124212447FEF924412403FE1820E02043FE0000 +7F0E:10801338222822284BA8FA461200227C43A4FA24422803A81E10E22842440282 +7F0F:110011FE211022104AFEF292169222FE4292FA9242FE02901A50E22042580286 +7F10:1040108021FC210449FCF90411FC20204032FBB440A801281924E22444A20040 +7F11:11001178210822084AFEF6401A40227C4290FA1042FE02101A28E22842440282 +7F12:10101220217C25444444F87C13402140417CFD444144017C1D44E280447E0000 +7F13:103C17C0224421284800FBFC1080208047FEF90041F802881A50E42048D80306 +7F14:1040102021FC24004488F85013FE22224424FDFC412401241D34E12840200020 +7F15:1020112420A820204BFEF8A8112422024040FBFE408801081990E06041980604 +7F16:1080104023FC22044A04FBFC1200220043FCFB54435405FC1D54E5544944010C +7F17:100013FC220423FC4A20FBFE1210228A4306F80043FC02041BFCE20443FC0204 +7F18:108010FC210421F84808FBFE104020A24334F858409403341852E09043500020 +7F19:100013FC209022944998F89017FE200041F8F908410801F81908E10841F80108 +7F1A:1050104827FE20404BFCFA4413FC224443FCFA44400803FE1908E08840A80010 +7F1B:100013FE220022FC4A00FBFE12A8229042C8FA86420803FE1A88E44844080818 +7F1C:1040104027FC20404BF8FA0813F8220843F8FA0843F802081FFEE11042080404 +7F1D:1020147C228421484830F8CE1610227C4210FA7C421002FE1A10E21045FE0800 +7F1E:1040102023FE200049FCF90417FE210441FCF852409401881A88E4A440C20080 +7F1F:1040102023FE200049FCF90411FC200043FEFA0242FA028A1AFAE202420A0204 +7F20:2040202027FE440055FCF524252425FC4524F52445FC042035FCC820082013FE +7F21:1040102023FE20004954F924115421FC4020FBFE424202921AFAE20A42020206 +7F22:11041084208820004BFEF800108821044202F9FC415401541954E15447FE0000 +7F23:10881050200025FE4450F9FC105423FE4054FDFC405000D81D54E25240500050 +7F24:1040102023FE22024C14F9E01100210041FCF910411007FE1800E09041080204 +7F25:100013FE205025FC4554F95411FC200041FCFC0043FE00201CA8E12442A20040 +7F26:100011F8210821F84908F9F8100023FC4294FBFC400001F81890E06041980606 +7F27:100011FC212425FC4524F9FC1040208841F0FC20404403FE1C22E12442220060 +7F28:20002FBE28A24AAA5AAAFAAA251428A24080F7FE4110021033A0C06001980E04 +7F29:2040202027FE44025100F1FE221026204A7CF2444244027C3244C244027C0244 +7F2A:100017BC208424A44A94F4A4105021884626F8C0431000641B88E03040C00700 +7F2B:112412482124240045FCF92411FC212441FCFC2043FE00701CA8E12446220020 +7F2C:220022FE22104FA0527CF244275420544054F754455405543528C72405420082 +7F2D:1020102023FE20504A8AF90413FE250441FCF90441FC00201924E22244A20040 +7F2E:1088105023FE202049FCF82013FE212440A8FBFE400001FC1904E10441FC0104 +7F2F:11041088200023FE4A22FAAA1272222243FEF80041FC010419FCE10441FC0104 +7F30:100013FE200025FC4524F9FC112423FE4000FDFC412401FC1D24E1FC400003FE +7F31:101014FE229222FE4810F9FE10002EFE4282FAFE428002FE1A82E2FE450008FE +7F32:11FC1104210421FC4800FBDE1252225243DEF82047FE007018A8E12446220020 +7F33:100013FC229422944BFCF80017FE200043FCFA0443FC00A21914E3084D440182 +7F34:2108220827C8445057DEF46427D422144114F7D4421403C83248C454055408A2 +7F35:2108252827BE494857BEF31825AA29464000F3F8420802483248C0B001080604 +7F36:0800080010001FF82100410001000100FFFE010021082108210821083FF80008 +7F37:200020003F3E482288220822FFA2082208224922492A49244F20792000200020 +7F38:200020003F7E481088100810FF10081008104910491049104F1079FE01000000 +7F39:080008001FF8210041000100FFFE01002108210821083FF80000488844448444 +7F3A:202020203C2051FC90241024FE24102413FE5420545054505C88648805040202 +7F3B:200020003DFE504090401078FE48104810685498549854885C8A64AA04CA0086 +7F3C:204020403C40507C90441088FEA0112010205450545054485C88648405040202 +7F3D:202020203C20502091FE1070FEA810A811245524562254F85C20642004200020 +7F3E:208420483C0050FC90481048FE48104811FE5448544854485C48648804880108 +7F3F:2008201C3CE05080908010FEFE80108010BC54A454A454A45CA4653C05240200 +7F40:205020503C50515290D41058FE50105810D45552565054505C9264920512020E +7F41:400043FE7A02A28A225223FEFA22222222AAAAAAAAAAAAFABA02CA02020A0204 +7F42:3EF822882AA82AA82AA81450228849041FF821000100FFFE010021083FF80008 +7F43:08202AA44D28145022887FFE400288041FF821000100FFFE0100210821083FF8 +7F44:08007F7808483E4800863E782A483E30404890861FF02100FFFE010021083FF8 +7F45:4040407C7840A3FE22422278FBC4223C2208AAF0AB24AAA8BDFECC2008A00040 +7F46:200021FC3D2453FE912411FCFE0011FC110455FC550455FC5D0465FC04880104 +7F47:410840907BFEA09023FC2294FB1C220423FCAA04ABFCA808BBFEC90800A80010 +7F48:400043FE7850A3FE225223FEF80021FC2104A9FCA904A9FCB820CBFE00200020 +7F49:412440A87BFEA20220F82088F8F8200C21F0A820A9FCA820BBFEC82000A00040 +7F4A:08787F4808483E862B783E482A28FF9049287F4620003FF84100FFFE21083FF8 +7F4B:0100FFFE104824FE799010FC22907CFC089030FEC8803FF84100FFFE21083FF8 +7F4C:3EF822883EF822883EF822883EF81450228810001FF02100FFFE010021083FF8 +7F4D:1FF011101FF011103FF82AA83EF82AA83EF810001FF02100FFFE010021083FF8 +7F4E:41FC410479FCA10423FE2020FBFE222221ACA820A9FCA800BBFEC840008801FC +7F4F:4040407C7840A3FC224423F0FA4422FC22A8AAF8AAA8AAF8BA00CDFC05540BFE +7F50:408843FE7888A3DE225223DEF8A0209021FEA920ABFCAD20B9FCC92001FE0100 +7F51:00007FFC40044004421452944A54442444244A544A5452946104400440144008 +7F52:00003FF82448244824483FF80000000000000000000000000000000000000000 +7F53:00003FF820082448228821082288244820080000000000000000000000000000 +7F54:00007FFC4004482444445FF4410440845FF444044404440447E4400440144008 +7F55:00007FFE40028824101020081FF0010001000100FFFE01000100010001000100 +7F56:00003FF82448244824483FF801000280044008203018C2060100008000800000 +7F57:00003FF82448244824483FF8020004000FF0101068200440028003001C00E000 +7F58:00003FF8244824483FF8000000007FFC010003000570090C3102C10001000100 +7F59:00007FFE400288241010210801000100FFFE03800540092011102108C1060100 +7F5A:00007FFC444444447FFC0000200810880088F088108810881488180810280010 +7F5B:00007FFC444444447FFC000000781FA01220122012101290124822A843248202 +7F5C:00007FFC444444447FFC020001007FFC010001003FF8010001000100FFFE0000 +7F5D:00007FFC444444447FFC00001FF0101010101FF010101FF010101010FFFE0000 +7F5E:00007FFC44447FFC00003FF0002006400180FFFE0282048408803080C2800100 +7F5F:00007FFC444444447FFC01000100FFFE010001001FF01010101010101FF01010 +7F60:7FFC444444447FFC00003FF8200820083FF8208020803FFC208020442C24301C +7F61:00007FFC444444447FFC000000007FFC0100110011F8110011001100FFFE0000 +7F62:00007FFC444444447FFC010001003FF801000100FFFE0400082010103FF81008 +7F63:00007FFC444444447FFC01003FF801000100FFFE000001003FF801000100FFFE +7F64:00007FFC444444447FFC082004407FF801083FF821003FFC0304051419086100 +7F65:7FFC44447FFC00001FF010101FF000003FF820083FF820083FF8200820282010 +7F66:7FFC44447FFC000000F87F00221011203FE000400080FFFE0100010005000200 +7F67:00007FFC444444447FFC082008207EFC08201C301A702A6848A4892208200820 +7F68:3FF8244824483FF802007FFC044009203FF8D1161FF011101FF40104010400FC +7F69:00007FFC44447FFC010001FC01003FF820083FF820083FF80100FFFE01000100 +7F6A:00007FFC444444447FFC000004407C7C044004407C7C04400440FC7E04400440 +7F6B:00007FFC444444447FFC000008207F200820FF30082808247F2408200F20F020 +7F6C:7FFC44447FFC00003EF8020814D00820145062883EF80288145008203458C286 +7F6D:00007FFC444444447FFC00500048FFFE00403E4022243E2800120E2A70C60302 +7F6E:7FFC444444447FFC0100FFFE02001FF010101FF010101FF010101FF01010FFFE +7F6F:00007FFC44447FFC01003FF808200440FFFE00001FF010101FF010101FF01010 +7F70:7FFC444444447FFC080004047FA400243F2400243F2400243F2421043F142108 +7F71:7FFC444444447FFC0100FFFE01003FF8244822882FE821083FF8210821282010 +7F72:00003FF8244824483FF802001FD00220FFFE03000FF03810CFF008100FF00810 +7F73:7FFC444444447FFC00001FF0111011101FF0111011101FF001004884481287F2 +7F74:3FF8244824483FF8010001003FF80100FFFE040008201FF00010488844448444 +7F75:7FFC444444447FFC00001FF811001FF011001FF011001FFC0004292444940008 +7F76:7FFC444444447FFC040079FC40444844545462883FF821083FF821083FF82008 +7F77:7FFC444444447FFC1080249842E07E8400847E7C42807E9842E07E844284467C +7F78:7FFC444444447FFC10080808FF0800FE7E0800887E4800487E0842087E284210 +7F79:00007FFC444444447FFC10A0109019FE552053FC952011FC1120112011FE1100 +7F7A:7FFC44447FFC1110222011101FF011101FF011101FF001007FFC05401930E10E +7F7B:7FFC444444447FFC00003F0821083F0820FE2E0820483F2844285508A4A80C10 +7F7C:7FFC44447FFC00003FF821083FF821083FF80920FFFE09203FF801007FFC0100 +7F7D:7FFC444444447FFC00007FFE42004A4452A4452448A452244AA4530444949848 +7F7E:3FF8244824483FF8082004403FF8292825483FF800001FF010101FF010101FF0 +7F7F:00007FFC44447FFC01003FF80440FFFE11101FF011101FF001003FF80100FFFE +7F80:3FF82AA824482AA80000FFFE02803EF822883EF802803FF821083FF821083FF8 +7F81:00007FFC44447FFC22007F7822083E4808487F7C49047F0408F4FF0408140808 +7F82:7FFC444444447FFC100011FC25047DFC080011FC25047DFC010455FC5504810C +7F83:7FFC44447FFC0820FFFE08201FF010101FF01010FFFE09203FF8D11611300100 +7F84:7FFC444444447FFC1020103C24207DFC090411FC25047DFC002055FE54208020 +7F85:00007FFC444444447FFC1050148825FE7A9010FC24907EFC009054904AFE8A80 +7F86:7FFC44447FFC108024987EE000847E7C42007E9842E07E844284467C24884244 +7F87:7FFC444444447FFC2820FDFC2820385010887DFE54087DE81128FDE810081018 +7F88:00007FFC444444447FFC2800FDFE292039FC11207DFC55207DFE1002FEAA1004 +7F89:7FFC444444447FFC000021082390482473B820104BA4783E0388AAACABCA8298 +7F8A:0820042004407FFC0100010001003FF8010001000100FFFE0100010001000100 +7F8B:092009200920F93E09200920082001007FFC01000100FFFE0100010001000100 +7F8C:0820042004407FFC010001003FF802000200FFFE04800480088010822082C07E +7F8D:020002007FFC044008203018C82604407FFC01003FF80100FFFE010001000100 +7F8E:1010081004207FFC010001003FF80100FFFE010001007FFC028004401830E00E +7F8F:220412041408FF90082008447F0408080810FFA208420804100810102060C180 +7F90:08200820F83E082001003FF801000100FFFE04000FE01040608003401C30E00E +7F91:082004407FFC01003FF80100FFFE040007E0082010406080014006201818E006 +7F92:441024502850FE50108810887D0412FA1048FE48104810482088208841288210 +7F93:4400240029FCFD24112411247D24112411FCFD00110011002102210240FE8000 +7F94:0820042004407FFC0100010001003FF8010001000100FFFE0000488844448444 +7F95:082004407FFC01003FF80100FFFE010000801F0001047D88095011202518C206 +7F96:440024F82888FE88108811067E0011FC1084FE84104810502020205040888306 +7F97:0820042004407FFC010001003FF802000200FFFE049004A408BC10822082C07E +7F98:01043C842488240027FE3C20242025FC24203C2027FE24202420442054208820 +7F99:082004407FFC010001003FF801000100FFFE010011101120228004401830E00E +7F9A:442024202850FC50108811247E12101011FCFC04100810882050202040108010 +7F9B:082004407FFC01003FF80100FFFE04407FF804483FF824403FFC084410542048 +7F9C:444024202820FDFE110212047C00100011FEFC20102010202020202040A08040 +7F9D:4404241E29F0FD10111011107D1011FE1110FD1011101108210A214A41A68112 +7F9E:082004407FFC01003FF80200FFFE04000FF011102110CFF0021002103FFE0000 +7F9F:440025FC2808FC10103010487C8413021000FDFC102010202020202043FE8000 +7FA0:442024202BFEFC2011FC10247DFC112011FEFC22102A10542050208841048202 +7FA1:082004407FFC01003FF80100FFFE4080208009FC12042448E04020A023182C06 +7FA2:441424122810FDFE101010907C92109213F2FC9410941088208A211A41268242 +7FA3:3FF80208FFFE04083FF808001FF82808CFF804407FFC01003FF80100FFFE0100 +7FA4:00827E44122812FEFF10121012107E7C201020107E1062FEA21022103E102210 +7FA5:440025FE2800FC92112412487D2410921000FDFE102010202020202043FE8000 +7FA6:4420241029FEFD02120410F87C00100011FEFC501050105020922092410E8200 +7FA7:444024402888FD0413FE10027C8811441242FCF8118812502020205041888606 +7FA8:082004407FFC01003FF80100FFFE0080208011FC820454482040E0A023182C06 +7FA9:082004407FFC01003FF80100FFFE02403C500848FFFE08480E5078240854198C +7FAA:4440242029FCFD04110411FC7D04110411FCFD20112211142108214441828100 +7FAB:4440242029FEFD02120410507C8811041000FDFC102010202020202043FE8000 +7FAC:8808480C500AFBFE22082208FAE8220A220AFAEC22AC22A822EA421A42268442 +7FAD:884048A05110FA0825F62000FBC422542254FBD42254225423D44244425482C8 +7FAE:04407FFC01003FF80100FFFE248842443FF801001FF00100FFFE02800C60701C +7FAF:440025FC2904FDFC110411FC7C8011FE1222FD221152110221FA200240148008 +7FB0:442025242924FD2411FC10807C8013FE1090FD101152125422A8242848448082 +7FB1:440025FE2910FD20117C11447D7C1144117CFD10111011542152229242508420 +7FB2:04407FFC01003FF80100FFFE00283E240824FFFE2A207D2490A81E12022A0C46 +7FB3:443C27E02924FCA813FE10A87D24120211FCFD24112411FC2124212441FC8104 +7FB4:082004407FFC01003FF80100FFFE454429287CFE10107C7C1010FEFE10102010 +7FB5:442025FC2820FC8813FE10887DFC110411FCFD0411FC110421FC208841048202 +7FB6:88204BFE5000FBFC220422F4FA9423FC2000F9F8210821F8210841F8400083FE +7FB7:442024202850FC88110412FA7C00100011DCFD54115411DC2088208841548222 +7FB8:0100FFFE20003FF800003FF820083FF80440729C57D47114539C711657D6B122 +7FB9:04407FFC01003FF80100FFFE482482823FF801001FF00100FFFE02800C60701C +7FBA:880049FC5020FBFE222221ACF82021AC2000FBFE202021FC215441544154810C +7FBB:88204BFE5250FBFE225223FEFA0023FE2292FB48223A224022FC4548443089CE +7FBC:3FFC20043FFC22202FF8208027F020803FFC2AA83F7C24105F7C4410BF7E0810 +7FBD:00007EFC0204020422441224122402040A14122462C422440204020414280810 +7FBE:0000EE00227C2210AA1066102210221026106A10B210221022102210AAFE4400 +7FBF:00007EFC22441224060C1A3462C40204042004207FFE04200420082010202020 +7FC0:0010EE1022102210AAFE66922292229226926AFEB292221022102210AA104410 +7FC1:0440082012102408C8261FF0001000007EFC224412240A14122422444A940408 +7FC2:0008EE2822282228AA4466442282237C26246A24B224222422442244AA944508 +7FC3:080008EE08227E2210AA1066202228224826486A90B2142222227E2222AA0044 +7FC4:0010EE10221022FEAA10661022FC224426446A44B228222822102228AA444482 +7FC5:100011DC1044FE44115410CCFC4444CC45542844284411541888240043FE8000 +7FC6:00007EFC224412241A3462C404003FC004400844113C2100FFFE010001000100 +7FC7:00007EFC224412241A3462C4022401107FFE020007F00A10112060C003301C0E +7FC8:00007DDC5444544455547CCC54445444544C7CD4556410441044104411541088 +7FC9:100011DC1044FC44115430CC38445444524C90D411647C441044104411541088 +7FCA:200013DE1042FC420252094A894A884248C6494A525250421C42E042414A0084 +7FCB:0020EE10221022FEAA0066042244224426246A24B228222822082210AAFE4400 +7FCC:00007EFC22441224060C1A3462C4010000807FFC0000101008200440FFFE0000 +7FCD:0010EE10221022FEAA926694229022FC26A46AA4B2A822A822902328AA444482 +7FCE:100011DC28442444435490CC08440044FC4C04D4096450442044104411540088 +7FCF:00007EFC224412241A3462C4030406C01830E30E0C403180063038C007003800 +7FD0:0010EE1022502250AA7C66902310221026FE6A10B228222822282244AA444482 +7FD1:0040EE40228022FCAB04660422F4229426946A94B2F4229422042204AA284410 +7FD2:00007EFC224412241A3462C4010402001FF8100810081FF8100810081FF81008 +7FD3:100011DC1044FE44115410CC7C440044004C7CD44564444444447C4445540088 +7FD4:440025DC2844FE44115410CC7C441044104CFED4116410442044204441548088 +7FD5:010006C01830EFEE00001FF010101FF000007EFC224412240A1412246AD40408 +7FD6:100011DC28442444435480CC7C440044004C7CD44564444444447C4445540088 +7FD7:100010EE3E224222A4AA186610222422C8261F6A21B2D2220C22082230AAC044 +7FD8:200021DCFE442444295412CC2A44C6CC0154FC4428442954288A480247FE8000 +7FD9:100092EE92229222FEAA206620223E224226426AA4B214220822102220AAC044 +7FDA:7EFC224412241A3462C400007FFE42029FF4040009001FF001007FFC01000100 +7FDB:108010F811082290286069986E06ABB828882AA8299829982AA8288822A82110 +7FDC:00007EFC224412241A3462C4020401007FFC092009201550228804401830E00E +7FDD:100008EE7F22412292AA10667F2210221426246A24B228224A225122BFAA1144 +7FDE:0020EE1022FE2200AA00667C22442244267C6A10B254225222922210AA504420 +7FDF:00007EFC224412241A3462C4020409001FFC30805FF890801FF810801FFC1000 +7FE0:00007EFC224412241A3462C4020401007FFC0820145022880100FFFE01000100 +7FE1:04407C7C04403C7804407C7C0440044000007EFC224412240A1412246AD40408 +7FE2:00007F6E492249225DAA49667F2241225D26556A55B25D2241224122452A8264 +7FE3:7EFC22441A3462C4020401003FF80820FFFE04007FFC08201C4003800C707008 +7FE4:00007CEE442244227CAA0066FE22AA22AA26AA6AFEB2AA22AA22AA22A2AA8644 +7FE5:01081FD001207FFC02000FF03810CFF008100FF000007EFC22441A3462C4060C +7FE6:0820FFFE00003E0822483E4822483E482208261800007EFC22441A3462C4060C +7FE7:200011DCFE44824401547CCC00447C44444C7CD445647C4400441C44E1544088 +7FE8:7EFC22441A3462C402041FF010101FF010101FF000007FFC110011F8290047FE +7FE9:100008EE7E22422242AA7E66422240227F26556A55B27F22D522552255AA4344 +7FEA:0028EE9222AA2282AAFE6628224422A2263C6A44B24422A822102228AA444482 +7FEB:0000EE7C2200AA006600AAFE225010507E50425042507E52425242927E8E4300 +7FEC:7CF82448142824487FFC41043FF801001FF011101FF011101FF00100FFFE0100 +7FED:0040EE5C22442284AABE66902390229E26A86A88B2BE228822882294AA9444A2 +7FEE:0000FEEE00227C2244AA7C660022FE228226AA6A92B2FE229222922292AA8644 +7FEF:7CF8244814282548FFFE00001FF010101FF000007FFC40044FE448244FE4400C +7FF0:102010201050FE8811067C0045DC7C4445547CCC1044FECC1154104411541088 +7FF1:100021DC7C4444447D5444CC7C441044FE4C28D4556492447C44104411541088 +7FF2:0000FEEE2822FE22AAAAAA66FE2200227C26006AFEB210225422922250AA2044 +7FF3:00007F7848485F4C64805F7844484A4851307F4C00007EFC22441A3462C4060C +7FF4:0010EC1026FE2510B57C6C54247C2754257C6D10B5FE251025102690B47E4800 +7FF5:0010EE20227C2244AA7C6644227C2240267E6A40B27E220222AA22AAAB02440C +7FF6:100021DC7C4444447D5444CC7C441044544C38D455641044FE44104411541088 +7FF7:080049EE2A220822FFAA2A66492288224226776A92B25A222F22222242AA8244 +7FF8:10007EEE10222422FEAA24667E2242227E26426A7EB242227E22242242AA8144 +7FF9:10007DDC1044FE444554EECC4444EECC0154FC4428442954288A480247FE8000 +7FFA:2000FEEE8222FE2282AAFE668222FE221026926A54B292221022FE2210AA1044 +7FFB:0E00F1DC92445444FF5438CC544482447C4C54D455647C44544454447D544488 +7FFC:7EFC22441A3462C402043FF821083FF821083FF804403FF80440FFFE08201010 +7FFD:08004E764812FF12045A05367F9244127C125536555A75125A12929225DAC8A4 +7FFE:0000FEEEAA22AA22FEAA0066FE2200227C26446A7CB22A226422A22231AA2044 +7FFF:1000FEEE10227C2200AAFE6602227C221026FE6A00B2FF220222FF22AAAAE644 +8000:100011DC9044555458CC1154FC00284828FE29902AFC28902AFC4C9048FE8080 +8001:020002083FD002200240FFFE010002000C1018E02F0048088808080807F80000 +8002:020002083FC802100220FFFE0080010002000C003000C0000000000000000000 +8003:020002083FD002200240FFFE010002000FF81200240047F08010001000A00040 +8004:02203FC00280FFFE02200FC03408C3F8000001F03E0003F03E0003FA7E0201FE +8005:020002083FD002200240FFFE010002000FF0181028104FF0881008100FF00810 +8006:02083FD00220FFFE02000C703F84C80407FC00001FF010101FF010101FF01010 +8007:020002083FD002200240FFFE03001C00EFF810082FC8C8480FC8000800500020 +8008:02203FC00280FFFE02200FC03408C3F810003FF840089F8810881F8800500020 +8009:020002103FE00240FFFE010007F81C00E7F800081F88108810881F8800500020 +800A:020002103FE00240FFFE010006001FF0E40008201FF001001FF001007FFC0000 +800B:02203FC00280FFFE02200FC03408C3F800007FFC08201FF001001FF001007FFC +800C:00007FFC0100010002003FF82488248824882488248824882488248820282010 +800D:0000FFFE020004003FF82488248824A822100200FFFE08201C4003800C707008 +800E:0000FFFE020004003FF824882488248824A8211001007FFC028004401830E00E +800F:0002FFE20404040808107FC24A424A444A484A504A424A424A444848415040A0 +8010:0008FF880808080810FE7F085508550855485528552855085508550841284310 +8011:01002108210821083FF800000000FFFE020004003FF824882488248824A82010 +8012:010001007FFC010001003FF801000100FFFE0380054009203118C10601000100 +8013:1000100011FEFE1010107C101010FE1010103810341054105010901010501020 +8014:100010FC1004FC08100878101010FDFE10103810341054109010101010501020 +8015:108810881088FE8811FC7C881088FE8813FE3888348854885088910811081208 +8016:102010201020FCA810A478A21122FD2012243824342854089010102010C01300 +8017:1008101C10E0FE2010207C3C10E0FE201020383E35E05420502290221022101E +8018:100010FC1000FE0010007C0011FEFE201020384034485484508491FE10821002 +8019:1000100011FCFD24112479241124FD2411FC3900350055009102110210FE1000 +801A:101010101010FDFE111279141110FDFC11443944352855289110122812441482 +801B:102010201020FE4010487C8411FEFE82100038FC348454845084908410FC1084 +801C:100011F81108FD081108790811F8FD00110039FC350455049104110411FC1104 +801D:100010F81088FE8810887CF81088FE88108838F8348854885088908813FE1000 +801E:110011001100FD1C13D479541154FD5411543954355455549154125C13541480 +801F:100011FE1100FF0011007DFC1104FF041104390435FC55005100910011FE1000 +8020:102010201050FC8811047A0211FCFC00100039FC350455049104110411FC1104 +8021:1008100813C8FE48125E7A4A13CAFE4A124A3BCA364A524A526A93D216121026 +8022:1088108813FEFC8810007BFE1202FC4410403BFC344454849084110412281410 +8023:102010201050FC8811047AFA1000FDFC1154395435FC5554915411541104110C +8024:104810481048FDFE1048784811FEFC0010FC3884348454FC9084108410FC1084 +8025:1020112410A4FCA810207BFE1202FE0212FA3A8A368A528A52FA9202120A1204 +8026:11FC11241124FDFC1124792411FCFC2010203BFE3622522A52FA920A12021206 +8027:1020112410A8FC2013FE78A81124FE0210403BFE348851085190906011981604 +8028:100011FE1100FD7E110079FE1154FD4811643942350851FE5148922812081418 +8029:1088108813FEFC8811FC788813FEFC2011FC392435FC512453FE910411141108 +802A:1040102013FCFD0810907BFE1202FC4410203BFC348054F89088110811281210 +802B:102013FE1020FDFC10207BFE1000FDFC110439FC350455FC910411FC10881104 +802C:102011FC1124FFFE112479FC1020FDFC112439FC344055FE908811D01070138C +802D:1124112412AAFFAE11247AAA13AEFD2413FE391035145114528A924A12161422 +802E:1048116A10DCFE4810B47D2211FEFF021020382034FC54245044904410941108 +802F:108813FE10A8FC9011FE7B2011FCFD2011FC392035FE550093FC10881070138E +8030:13FC104011F8FD0811F8790817FEFC4212A43A8A347A508051F892881070138E +8031:1040102013FEFE4813FE7A4812ECFF5A12483BFE3620527C52C49344147C1844 +8032:1040102013FEFC0011FC795411FCFC201122388C3522545490C8114412521060 +8033:00007FFC101010101FF0101010101FF010101010103E17D0F810001000100010 +8034:0020FFA0222022203E20222022203E202220222027A0FA2242220222021E0200 +8035:0000FF80227E22083E08220822083E08220822082788FA084208020802280210 +8036:0000FFBE222222243E24222822243E242222222227A2FA344228022002200220 +8037:010001007FFC0280044008203FF8C8260FE008200FE0082009F87E2000200020 +8038:0820082014502288410400007FFC10101FF010101FF01010103EFFD000100010 +8039:0020FF20242024503C50248825443E22242024F82E08F4084410041004200420 +803A:0000FF0024FC24003C00240025FE3C20242024402E40F488448405FE04820400 +803B:0010FF10241024903C902490249E3C90249024902E90F4904490049005FE0400 +803C:0000FF7C244424443C4424FE24443C44244424FE2E44F4444444044404540448 +803D:0040FC4048404BFC7A444C484840784048A048A04CA07920C9220A220C1E0800 +803E:0040FF40244024403DFE244024403C50249024902EA0F5284544064404FE0442 +803F:0020FF20242024243CA424A424A83D20242024502E50F4504488048805040602 +8040:0048FF44244424403C5E25E024403C44244424482E30F4224452048A05060402 +8041:0010FC9048904888790849044A047DFA488848884C887888C90809080A280C10 +8042:00007FFC08200FE008200FE0083EFFE000203EF8028822881450082034D8C306 +8043:0020FF20242025FC3D24252425FC3D24252425242FFEF5044504050405140508 +8044:0020FC204850488879044A1248207840498848104C207844C988081008600B80 +8045:0040FC40488048FC79204A20482078204BFE48204C507850C888088809040A02 +8046:0020FF20245024503C88252426123C1025FC24042E08F4884450042004100410 +8047:0000FF0024FE24103C10241024903C90249E24902E90F4904490049007FE0400 +8048:0010FC9048904910797E4A524B927892491249124E527BD2C8620822084A0884 +8049:0010FF10249224923C92249224FE3C10241024922E92F4924492049204FE0402 +804A:0000FC804B1E4A527A524A524A527A524A524AD24F5A7A54C890089009100A10 +804B:04800440FFFE0940118466FC00007FFC08200FE008200FE0083EFFE000200020 +804C:0000FF0024FC24843C84248424843C8424FC24842E00F4484444048404820502 +804D:0040FC2048204BFE7A024C04480078004BFE48204C207820C820082008A00840 +804E:0050FF50245025523CD4245824503C5824D425522E50F450449204920512060E +804F:0000FDFC48204820784049FC49547954495449544D547954C954094409140908 +8050:0020FC2048204BFE7820482049FC7800480049FC4D047904C904090409FC0904 +8051:0000FDFE48884888788848F84888788848F848884C88789ECBE8080808080808 +8052:0008FF1C24E024203C2025FE24203C20242024FC2E84F4844484048404FC0484 +8053:00007DF0111011901D52F20E04007FFC08200FE008200FE0083EFFE000200020 +8054:0088FC484850480079FC4820482078204BFE48204C507850C888088809040A02 +8055:0020FD20492049FC79204A2048207BFE480048004DFC7904C904090409FC0904 +8056:00007F00227C3E4422443E4423C4FE7C024402007FFC01003FF801000100FFFE +8057:0020FC2048204BFE782048204924792449244AAA4C207850C850088809040A02 +8058:0020FC2049FC492479FC492449FC78004BFE48804D0079FCC804080408280810 +8059:0020FC204BFE482079FC48204BFE780049FC49044DFC7904C9FC090409140908 +805A:7F00227C3E0422283E1023A8FE44020000F87F0009041188635005201918E106 +805B:0020FF4024FE24923C9224FE24923CA224FE24482E88F5FE4408040804080408 +805C:0020FF10241025FE3D02265424883D04240024FC2E20F4204420042005FE0400 +805D:0014FC12481049FE7810481049D27952495249544DD47808C8CA0B1A08260842 +805E:00007C7C44447C7C44447C7C40044FE4444447C4444447C444745FC440544048 +805F:20003E7C4844FF441444227C40007FFC08200FE008200FE0083EFFE000200020 +8060:0084FF48240024FC3C48244824483C4825FE24482E48F4484448048804880508 +8061:0090FC90490849487A444C9249087BFC484448204CA47A82CA8A0A8A0C780800 +8062:0020FF1024FE24823D04240024FE3C10241024902E9EF490449004D0053E0600 +8063:0000FF2024CE24823C8224EE24823C8224FE24282E28F4284448044A048A0506 +8064:0040FC204BFE480079FC490449FC78004BFE4A024DFC7820C820082008A00840 +8065:0004FC1E4BE0482079FC4924492479FC48204BFE4E227A2ACAFA0A020A0A0A04 +8066:0080FC8048FC49547AD448B4492C7A44489449084C4078A4CAAA0A8A0C780800 +8067:0010FDD448584A52798C488849047AFA482048204DFE7820C850088809040A02 +8068:0108FD4A4A524B9C79084A524BDE7842488848884FFE7888C888090809080A08 +8069:0020FC2049FC492479FC48204BFE780049FC49044D247924C924085008880B04 +806A:0088FC48485049FC79044904490479FC482048104C547942C942094A0A380800 +806B:0108FD4A4A524B9C79084A524BDE7842482048204FFE7820C850088809040A02 +806C:0090FC8849044A427C8849FC480478004BDE48424E52794ACA520842094A0884 +806D:0010FF2024FE24923C9224FE24923C9224FE24202E24F45A445E04900492050E +806E:0084FC844908494A7A524B9C48847908494A4BDE4C427800C954092A0A2A0800 +806F:0108FD4A4A524B9C79084A524BDE784248904A924E927B9EC890089008900910 +8070:0020FC4049FC4924797C498C49547924495449FC4C407824CAA20A8A0C880878 +8071:08207F20087E7E4408A4FF2810101E2822447FFE88200FE0083EFFE000200020 +8072:08007F7808483E4800863E782A483E304048FFFE08200FE0083EFFE000200020 +8073:11102110CAA814443278D24015FC18007FFC08200FE008200FE0083EFFE00020 +8074:0020FC204BFE4840784049FC4954795449FC48404C247AA2CA8A0C8808780800 +8075:0020FDFC492449FC78204BFE480079FC490449FC4D0479FCC90409FC08880904 +8076:7FFC08200FE008200FE0083EFFE000207EFC24483C7824483C78264EFDF80408 +8077:0110FC944BD248127A5049904FFE78104BD24A524E547BD4CA4A0A4A0BD60822 +8078:0080FCF849084BFE7944499249FE7900497C49004D7C7900C97C0A440A7C0C44 +8079:0040FC204BFE4A227954494A4A3A780049FC49544FFE7800C9FC082008A00840 +807A:0040FC204BFE4A02791049DE4A527D544A8849744E0279FCC82009240A220860 +807B:42043FD88A904F9E2A945FD482247FFC08200FE008200FE0083EFFE000200020 +807C:002078200BFE1020FDFC4954495479FC48007BFE48405C24EAA24A8A0C880878 +807D:0020FC204BFE782049FC79544954F9FC0800FBFE284078242AA2FA8A0C880878 +807E:08403E7C1440FF7822083E782242263E00007FFC08200FE0083EFFE000200020 +807F:010001003FF80108FFFE01083FF8010001003FF801000100FFFE010001000100 +8080:010001003FF80108FFFE01083FF8010801000100010001000100010001000100 +8081:010000803FFC20043FFC20802FF820883FFE20882FF820804FFC4080BFFE0080 +8082:00200020FDFC202423FE3C2445FC4420642095FC0820082013FE202040208020 +8083:010001003FF80108FFFE01083FF8010021082548252825282928410841088108 +8084:40204C2070FC442445FE3C2440FC7C20902011FCFE20102029FE242044208020 +8085:01003FF80108FFFE01083FF8054025483D7821083FF821083D78254845488108 +8086:00203E2020FC20243DFE202420FC3C20202021FCFE20202025FE4220FE204220 +8087:08403E7E22A83E10206E41009FF00110FFFE01101FF001003FF80100FFFE0100 +8088:08243E3E22E83E12202A41469FF00110FFFE01101FF001003FF80100FFFE0100 +8089:0100010001007FFC410442844444492451044104428442444444480440144008 +808A:00003E0022FC220422083E102220222022403E4022802282228242824A7E8400 +808B:00203E202220222022FE3E222222222222223E2222422242224242824A948508 +808C:00003CF02490249024903C902490249024903C902490249224924512550E8A00 +808D:00403C402440244025F83C482448244824483C482448244A248A448A55068A00 +808E:00007FFE4002800400001FF0101010101FF0101010101FF01010101010501020 +808F:0600010002800C603118C1063FF8228824482928210822882448200820282010 +8090:00403C40248024FE25003E0024FC240824103C20244024802502450254FE8800 +8091:00403C40248024FC25043E042404250424843C44244424042404440454288810 +8092:00403C402440244025F83C482448254824C83C482468245A248A448A55068A02 +8093:02000100FFFE100010001FF800001FF010101FF010101FF01010101010501020 +8094:00203C2024202520252C3D34256427A425243D34252825222522450254FE8800 +8095:00003C0024FC242424243CA424A424A424A43D24242424442444448455288A10 +8096:010021081110092001003FF8200820083FF8200820083FF82008200820282010 +8097:00403C402440244027FE3C882488248824883D08249024502420445054888B04 +8098:00083C082408240825FE3C082408240824883C48244824082408440854288810 +8099:1FF0101010101FF000003FF8200820083FF8200820083FF82008200820282010 +809A:00203C202420242024203C2025FC242024203C20242024202420442057FE8800 +809B:00003C0025FC242024203C202420242024203C20242024202420442057FE8800 +809C:00043E042208221022203E442204220822103E2222422204220842104A2084C0 +809D:00003DFC2420242024203C20242027FE24203C20242024202420442054208820 +809E:00403C242524250425043C882488248824503C50242024202450448855048A02 +809F:00003CFC2400240024003DFE2440244024803CFC240424042404440454288810 +80A0:00003DF82410242024403C8025FE249224923C92251225222622444254948908 +80A1:00003CF82488248824883D06260025FC24843C84244824502420445054888B06 +80A2:00203C20242025FE24203C20242025FC24843C88244824502420445055888E06 +80A3:00203C202450245024883D442622242024003DFC240424082408441054108820 +80A4:00203C202420242025FC3C202420242027FE3C20245024502488448855048A02 +80A5:00003DFC2524252425243D24252425FC25043D00250025002502450254FE8800 +80A6:00103C502450245034882C88250426FA2C483448244824482488448855288A10 +80A7:00003C0025FE241024103C202420246824A43D22262224202420442054208820 +80A8:00203C20242025FC24203C20242025FC24203C20242027FE2420442054208820 +80A9:010000801FF8100810081FF8100017F8140817F8140827F82408440884280410 +80AA:00403C20242025FE24403C402440247C24443C44244424442484448455288A10 +80AB:0040784048404BFC48407A484A484A484A487BF84848484048424842483E9800 +80AC:00403C502448244824403DFE2450245024503C502490249024924512550E8A00 +80AD:00203C20242025FE25223D222522252225523D4A258A250225024502550A8904 +80AE:00403C20240025FC24003C0024F0249024903C902490249224924512550E8A00 +80AF:0100010011F811001100FFFE00001FF010101FF010101FF01010101010501020 +80B0:00203C282424242424203DFE2420242024203C50245024502488448855048A02 +80B1:00407840484048404BFE7840488048904890792049204A484A444C8449FE9882 +80B2:02000100FFFE080010103FF800081FF010101FF010101FF01010101010501020 +80B3:00803C80248024FC25543E542454249424943D24262424442444448455288810 +80B4:18180660018006603A180200FFFE04000FF818082FF848088FF8080808280810 +80B5:00043C0E24F0248024803C8024FE248824883C88248824882488450855088A08 +80B6:00103D102510251225123D1425D8251025103D102510251225524592550E8800 +80B7:00403C402440247C24843C882520242024203C50245024502488448855048A02 +80B8:00103C902490248825083D042624242224203DFE242024202420442054208820 +80B9:00483C482484248425023E0025FE244024803CFC240424042404440454288810 +80BA:00203C20242027FE24203C2025FC252425243D24252425342528442054208820 +80BB:010001F8010001003FFC200440081FF010101FF010101FF01010101010501020 +80BC:00887888488848884BFE7888488848884FFE7888488848884888490849089A08 +80BD:00203C202420242024203DFE2420242024203C5024502450248844C855248A02 +80BE:040025F824882450242024D8270604001FF010101FF010101FF0101010501020 +80BF:00203C202420242025FC3D242524252425243DFC252424202420442054208820 +80C0:00803C842484248824903CA0248027FE24A03C9024902488248444A254C08880 +80C1:00807880488048804BF0789048904A984A947C9248924890491049104A509C20 +80C2:00203C20242025FC25243D24252425FC25243D24252425FC2524442054208820 +80C3:00003FF821083FF821083FF800001FF010101FF010101FF01010101010501020 +80C4:010001003FF821083FF821083FF800001FF010101FF010101FF0101010501020 +80C5:00203C202520252025FC3D202620242025FE3C20245024502488448855048A02 +80C6:00003C0024FC248424843C8424FC248424843C8424FC24842400440055FE8800 +80C7:00503C50245025FC24543C5425FC255025503DFE24522452245A449454908910 +80C8:00503C482448244025FE3C402440247C24A43CA424A825282510462854448882 +80C9:00103C10242024FC24843C842484248424FC3C84248424842484448454FC8884 +80CA:00803C80250025FC36042C0425E425242D24352425E425242404440454288810 +80CB:00203C2024202420243E3C202420242025FC3D04250425042504450455FC8904 +80CC:048004987CE004841C84E47C40001FF010101FF010101FF01010101010501020 +80CD:0008781C49F049504950795049504950495079484948496849544A744A529C00 +80CE:00203C202420244024483C8425FE248224003CFC248424842484448454FC8884 +80CF:00203C20242E25F025203D20252025FE24223C6224A2252A2624442054208820 +80D0:00203C202524252435242D2425FC24202C203524252425242524452455FC8804 +80D1:00003C0024FC248424843C842484248424FC3C84240024482444448454828902 +80D2:00003CFC2484248424843CFC248024A024A23CA424B824A024A24522551E8A00 +80D3:00003DFC2420242025243CA424A8242027FE3C20242024202420442054208820 +80D4:088008882E9028E028842E84F07C01003FF82288244829282108228824482018 +80D5:00443C442444248424BE3D84268424A424943C94248424842484448454948888 +80D6:00203C20252424A424A83C2025FC242024203C2027FE24202420442054208820 +80D7:00203C202450248825043E122420244025883C10242024442588441054608B80 +80D8:00203C10241025FE24203C202444248425F83C1024202444248245FE54828800 +80D9:00803C80248024FE25403D402640247C24403C402440247E2440444054408840 +80DA:00007BFC482048204840784048D049484A447C4448404840484048004FFE9800 +80DB:00003DFC2524252425243DFC2524252425243DFC252424202420442054208820 +80DC:002078204920492049FC79204A204820482079FC48204820482048204BFE9800 +80DD:00043C1E25F0251025103D10251025FE25103D1025102508250A454A55A68912 +80DE:0080788049FC49044A047DF449144914491479F4490449284912490248FE9800 +80DF:00003CFC248424A424943C84248427FE25043D442524250425FE440454288810 +80E0:00203C20242025FC24203C20242027FE24203C2024402448248445FE54828800 +80E1:0800087C084408447F44087C08443E442244227C224422443E84228401140208 +80E2:00003C0025FE240824083DE82528252825283D2825E825282408440854288810 +80E3:0080788048FE49004A207920492C49744BA47924493449284922490248FE9800 +80E4:01002208244827882108224827C8200827C8244827C8244827CA444A444A84C6 +80E5:7FFC0104110011F81100290047FE80001FF010101FF010101FF0101010501020 +80E6:00203C20242025FC25243D242524252425243FFE242024502450448855048A02 +80E7:00907888488848804BFE78A048A048A448A478A84928493249224A624A9E9C00 +80E8:0040784048404FFE4880792049204A204BFC7820492849244A224C2248A09840 +80E9:00403C402440247C24403C40244027FE24403C40245024482444444054408840 +80EA:00203C20243C242024203CFC2484248424843CFC248424802480450055008A00 +80EB:000079FC480848104830784848844B02480079FC48204820482048204BFE9800 +80EC:10001000FEFC2244642818102428C2C601003FF8228824482108228824482018 +80ED:00003DFC2504252425243D2425FC252425243D54254C258C2504450455FC8904 +80EE:0080788048FC49084A90786049984E26482079FC48204A204BFE482048209820 +80EF:00203C2025FC245024883D0426FA240027FE3C40248025FC2404440454288810 +80F0:004078404FFC48404BF878484BF84A404BFC7844485448A848A049104A089C06 +80F1:004078444A444948495078404FFE48904890789048904892491249124A0E9C00 +80F2:004078204BFE48404890789049244BE448447848488849104A30484848849B04 +80F3:00403C402478248825503C202450248825063CF8248824882488448854F88888 +80F4:00007BFC4A044A044AF47A044A044AF44A947A944A944AF44A044A044A149A08 +80F5:00003DFE2420244024883D0425FE242224203C2025FE24202420442057FE8800 +80F6:0040782048204BFE4800788849044A0248887888485048504820485048889B06 +80F7:10001FFC20045454939414541FF400081FF010101FF010101FF0101010501020 +80F8:01007900490049FE4A027A024D1248A24A4A7AAA4B1A4A0A4BFA480248149808 +80F9:00003DFC2420242024403DFC2554255425543D54255425542554454455148908 +80FA:0040782048204BFE4A027C4448404BFE48887888490848D04820485048889B04 +80FB:00807880493C4A004C807880497E4B084D087908490849084908490849289910 +80FC:00843C48240024FC24483C482448244825FE3C48244824482448448854888908 +80FD:104024444248FF70014000427E42423E42007E44424842707E4042424A42443E +80FE:082008287F240820FFFE002008247F24492455286B2849105512632A45464282 +80FF:00203C2025FC242024203C2027FE240024203C2025FC24202420442057FE8800 +8100:1FC000447D88055009203518C2063FF800001FF010101FF010101FF010101030 +8101:00503C502450255234D42C58245024582CD43552245024502492449255128A0E +8102:01003D04253825C025023D0224FE240025FC3D04250425FC2504450455FC8904 +8103:00803C8024F8250826103DFC2524252425243DFC250025002502450254FE8800 +8104:0040784048404BFE4880789048904912495279544A904A284C28484448849902 +8105:02001FF00410085010207EFC12242A5444881FF010101FF010101FF010101030 +8106:00403C4024FC250426083DFE2500257C25443D442554254825424542553E8A00 +8107:0040784049FC48444884788449284A1049087BDE494A494A494A4A524B5A9CA4 +8108:0004781E49E049004906797849504950495279544948494849444A544A629C40 +8109:00407820481049E0482278344BB848B048A878A8492849244A244C2248A09840 +810A:2108111009201290244808203FF8C82608200FE0082008200FE0082008A00840 +810B:00001FF00410045008207EFC12442A9445081FF010101FF010101FF010101030 +810C:00803C8024FE251026103C1024FC249024903C9027FE24102410441054108810 +810D:002078204850488849047A0248F8480048007BFE48204840488849044BFE9902 +810E:000479884850482048507888492448204BFE782048A848A449224A2248A09840 +810F:00207810481049FE4900791049104910497C79104910491049104A104AFE9C00 +8110:004078204BFE490448887850482048D84B067888488848884888490849089A08 +8111:0040782048204FFE4800780048904A544A247A244A544A944A044A044BFC9804 +8112:00203C20252424A424A83C20242027FE24703CA824A825242524462254208820 +8113:0020782048204BFE4A427C4448A048A249A47A984C904888488448A248C09880 +8114:02000100FFFE04401450254841043FF822882448292821082288244820082018 +8115:00803C8024F8250826103DFC2524252425243DFC245024502490449255128A0E +8116:002078204BFE482048207BFE4A024C0449F8781048204BFE4820482048A09840 +8117:00803C8024FC255426543CA42524264424943D0825FC25042504450455FC8904 +8118:004078204BFE4A024C0479F8480048004BFE789048904890491249124A0E9C00 +8119:00283C242424242027FE3C20252024B224B43C6824A825242622442054A08840 +811A:01007900491E4B924912791249124FD2491279124A1A4A944FD04A5048109810 +811B:00007BFC480049244A487C904A48492448007BFC48404840484048404FFE9800 +811C:00003DFE2410242024FC3C84248424FC24843C8424FC24842484448454FC8884 +811D:004078204BFE480049F87908490849F848007BFC480848304820482048A09840 +811E:00203C2024A824A824A83D742622242024203DFC242024202420442057FE8800 +811F:00043C1E25E0242225123C942480240825FE3C08248824482448440854288810 +8120:0004780E4BB8488848887928492E4BA848A87AA84AA8493E49004A804C7E9800 +8121:000078064BB8488848887908493E4B8848887A884A88493E49004A804C7E9800 +8122:00803C8024FE250026FC3C8424A4249427FE3C842524251425FE440454288810 +8123:3FFC20002FF820003FFC24482430260E2FF828082FF848084FF8880808280810 +8124:000079FE49004900497C7900490049FE495079524954494849484A444A529C60 +8125:0020782048204BFE482078204924492449247AAA482048504850488849049A02 +8126:00107814481248104BFE7810489048504848780848884AA84A9A4AAA4C669802 +8127:00403C402488250437FE2C02248825442E4234F8258826502420445055888E06 +8128:00203C2027FE242024203DFC2524252425FC3C20247024A82524462254208820 +8129:1080108011F821082A906C60A9982E0629F8290829F8290829F8210821282110 +812A:00C23C342418246425823C2025FE245024903DFE26922492249A449454108810 +812B:00107890488849084A047DFA49084908490879F848904890489049124A129C0E +812C:0008783C4BC048044A44792848004BF8481078204FFE48204820482048A09840 +812D:000079FC49044904490479FC480048004BFE7820482049FC482048204BFE9800 +812E:0008783C4BC048444A247928490048404BFE788849084B904860485049889E04 +812F:004878444BFE484048407BFC4A444A444BFC7A444A444BFC4A444A444A549A08 +8130:00003DFE2400240024FC3C842484248424FC3C00248424442448440055FE8800 +8131:010478844888481049FC79044904490449FC785048504890489249124A0E9C00 +8132:00007BFC4A044A044BFC7A004A204A224BB27AB44AA84AA84D244D244AA29840 +8133:00427A2249244904480878004A0A4A8A4A527A224A524A8A4B0A4A024BFE9802 +8134:00003DFE2410242024683CA42522242024003CFC248424842484448454FC8884 +8135:000079FC4904490449FC7800480049FC482078204BFE48204850488849049A02 +8136:000079FC49044904490479FC482048204BFE7A224A524A8A4B0A4A024A0A9A04 +8137:004278E24B82488A488A788A4FEA488A498A79CA4AAA4A824C824882488A9884 +8138:0020782048504850488879044AFA480048447824492448A8488848104BFE9800 +8139:00003CFC248024F824803CF8248027FE25403D24252825102508454455828900 +813A:004078204BFE48004888788849544A22480078204BFE48204820482048209820 +813B:002078204BFE482049FC78244BFE482449FC78204920493E49204AA04A7E9C00 +813C:00007BFE482048204BFE7A224A224B324AAA7AAA4B764A664A224A224A2A9A04 +813D:00503C48248024FE25903E9024FC249024903CFC24902490249044FE54808880 +813E:004078804BFC4A244A247BFC4A244A444BFC789049104FFE4810481048109810 +813F:00203C2027FE242024203DFC2420242027FE3C4024A425A82690448854C68880 +8140:00203C202450248825043EFA240025FC25543D5425FC2554255445545504890C +8141:0084788C49084FBE49087908490849084FBE79084908490849084A08AA089408 +8142:00003DFC2524252425FC3D24252425FC24203FFE247024A82524462254208820 +8143:00203D2424A8242025FC3C4027FE248825043EFA2488248824A844925482887E +8144:00083C3C25E0242027FE3CA824A824A827FE3CA824A827FE2420442055FC8800 +8145:00203CA224A2252424503C882704242224203CA424A425282450448855048A02 +8146:00507850485049FC49547954495449FC4954795449544BFE4800488849049A02 +8147:001C79E0482048204BFE78A849244A4248407BFE4888490848D0483048489984 +8148:002078204BFE482049FC78204BFE480049FC790449FC490449FC490449149908 +8149:000078404B9C4A044A047B9C4A044A044BFC789048904890489049124A129C0E +814A:0088788848884BFE488878884FFE480049FC7904490449FC4904490449FC9904 +814B:008078404FFE492049207A3C4A444E644A947B484A484A304A204A504A889B06 +814C:004078804BFC49104A487C464BF84A484A487BF84A484A484BF848424842983E +814D:002078204850488849447A2249F848084850782048A44A824A8A4A8A4C789800 +814E:7EFC48447E4442287E1048287EC600001FF010101FF010101FF0101010501020 +814F:00007BDE4842494A4884794A4A524C2048007BDE48524952489449484A549C22 +8150:00803FFE2208220825FE2C883448245820802FFC29442AA4488449448A24080C +8151:002078104BFE4A004A447A444A844ABE4B847AA44A944A944C844C8448949888 +8152:00003DFC2504250425FC3D10251025FE25103D10257C254425444544557C8A44 +8153:0090789048904F9E4890789048904B9C4890789048904F9E4890489048909890 +8154:0040782048204BFE4A027C9449084A04480079FC48204820482048204FFE9800 +8155:004078204BFE4A024D04790049DE4A524A527B524C9A4894491049124A129C0E +8156:002078204BFE482049FC792449FC492449FC7820487048A849244E2248209820 +8157:00203C2025FC252425243DFC2524252425FC3C0027FE24882488448855088A08 +8158:00007BFE4A024A024BFE7A224A224AFA4A227A324A2A4BFE4A024A024BFE9A02 +8159:004078204BFE4A02480079FC480048004BFE7820492849244A224C2248A09840 +815A:004078204BFE4A024C0478004BFE482048207920493C49204AA04A604C3E9800 +815B:00003DFE2502250225FE3D0025FC252025443DFE2512251025FC4510561089FE +815C:00883C8827FE248824883CF82488248824F83C2027FE247024A8452456228820 +815D:00003DFC2420244025FC3D542554255425443D2C242027FE2450448855048A02 +815E:00403C7C248424F824083DFE244024A425383C58249425342454449255508820 +815F:00403C2025FE250226043DFC2440248825FC3C24242025FC2420442057FE8800 +8160:002078204BFE482049FC78404BFE488849047AFA482049FC4820485048889B04 +8161:000079FC4904490449E4792449244BFE4A027AFA4A8A4A8A4AFA4A024A0A9A04 +8162:01FC7924492449FC4924792449FC482048207BFE4A224A2A4AFA4A0A4A029A06 +8163:0040782049FC4800488878504BFE4A224C2479FC492449244934492848209820 +8164:00203C1025FE240024843C4825FE240024FC3C84248424FC2484448454FC8884 +8165:00007BF84A084BF84A087BF848404A404BFC7C4048404BF8484048404FFE9800 +8166:009279244A4849244892784048804BFE4A027A8A4A524A224A524A8A4BFE9A02 +8167:004078A049104A084DF678004BC44A544A547BD44A544A544BD44A444A549AC8 +8168:00203D242524252425FC3C0027FE242024403DFC25542554255445545554890C +8169:002078204BFE482048207BFE4A8A4A524AFA7A224A224AFA4A224A224A2A9A04 +816A:00007BFE4A2248204BFE782049FC492449FC792449FC48204BFE482048209820 +816B:00083C3C25E0242027FE3C2025FC252425FC3D2425FC242025FC442057FE8800 +816C:00003CFC2448243025FE3C522494251026303C2025FE247024A8452456228820 +816D:00003DDC2554255425DC3C0025FC240025FE3C8024FC24042404440454288810 +816E:000079FC4924492449FC7924492449FC4800784048244AA24A8A4C8848789800 +816F:00043C1E25F0251025103DFE2510257C25443D7C2544257C25444544557C8A44 +8170:00007BFE485048504BFE7A524A524BFE480078404FFE48884990486048D89B04 +8171:00107810487C4B1449FE79144A7C4A104F7C791049FE4D104A104B004CFE9800 +8172:00003DFC2524252425FC3D24252425FC24003FFE252025222514454855848902 +8173:00007A9E4A524A524D5279124A924A524C327BD24A5A4A544A504A504BD09A50 +8174:00203C2024A0252C25243D2425AC252425243DFC252424502450448855048A02 +8175:00007BDE4A424A424A427BDE4A004A3E4BD27A124A144BD44A084A144A249A42 +8176:00203DDC2514251425143DD42526250025DC3D14251425D42708450855148922 +8177:00003DFC240024F824883C8824F8240025FC3D24252425FC2524452455FC8904 +8178:00003CFC248424FC24843CFC240025FE24803CFE252A264A2492452254548888 +8179:00403C4024FE248025FC3E8424FC248424FC3C40247C24C42528441054688986 +817A:0040788049FC490449FC790449FC482048327BB448A8492849244A244CA29840 +817B:001878144FFE48104BD078104BF048104BE87A284AA84AA84AAA494A4A269C22 +817C:00003DFE2420244025FC3D542554257425543D54257425542554455455FC8904 +817D:00003CF82488248824F83C88248824F824003DFC255425542554455457FE8800 +817E:0248794849504FFC48407FFE49104A084DF67810491049FC48044BE448149808 +817F:00007A7C49444944487C78444F44497C4950794A49444954496249424A809C7E +8180:004078204BFC490848907BFE4A024C4448207BFC488048F84888490849289A10 +8181:00883C50240025FE24503DFC245427FE24543DFC245024D82554465254508850 +8182:2040FEFE21003C1C24E0449454A888C61FF010101FF010101FF0101010501020 +8183:00003CF824A824A824D83C8824F8240024003DFC255425542554455457FE8800 +8184:00A03D2C2524252425AC3D24252425FC24203DFC248824502420445054888B06 +8185:00203C1025FE2510257C3D1425FE2514257C3D10257C254425444544557C8A44 +8186:002078204BFE482049FC78204BFE4840488879F048244BFE482249244AA29840 +8187:00107A20497C49444844787C4B404940497C79444944497C49444A804C7E9800 +8188:00007BFE480049FC4904790449FC48004BFE7A8A4A524BFE4A224A224A2A9A04 +8189:01043C842488240027FE3C002488250426023DFC255425542554455457FE8800 +818A:002878244BFE482049FC792449FC492449FC792448084BFE4888484848489818 +818B:08202AA44D28145022887FFE40029FF410101FF010101FF01010101010501020 +818C:00203D2424A8255424883D0426FA248824883CF82488248824F8448854888898 +818D:00203C4025FC250425543D242554250425FC3C00251225D4251845525592890E +818E:001E7BE0492248944840788849F0482048C479FE482248204BFE485048889B06 +818F:01007FFC08200FE000007FFE48228FE400001FF010101FF010101FF010101030 +8190:2040FEFE21003C1C24E0449454A888C601003FF8228824482108228824482018 +8191:004078204BFE4A024C1479E04900490049FC791049104FFE4800489049089A04 +8192:00007BFE4A004A7C4A447A444A7C4A004AEE7AAA4AAA4AAA4AEE4A004BFE9800 +8193:010079FC4A004DF8490879F8490849F848007FFE49004BFC4CA449244A549888 +8194:004078204BFE4A504A507BFE4A524A524BFE7A004A924AD44A984A924AD29C8E +8195:000077FE542A542657FE742257AA56AA57AA74325596562E5446548257FEB402 +8196:00207A20497C48A4481878E64B10497E4910797C491049FE491049104AFE9C00 +8197:00207A224BFE4890488879FE4B104D1049FE7910491049FE4910491049FE9900 +8198:00007BFE485049FC4954795449FC480049FC78004BFE482048A849244AA29840 +8199:00007BBE48A248A248BE7B884A084A3E4A2A7BAA48AA48BE4888488A4D7E9A02 +819A:010001FC01003FFE20022FFC28842FFC28842FFC240827F8240847F844088418 +819B:0020792448A84BFE4A0278F84888488848F87820482049FC482048204BFE9800 +819C:008878884BFE4888480079FC490449FC490479FC48204BFE4850488849049A02 +819D:002078204BFE487048AC7B224850488849247A22492448A849244A2248A09840 +819E:00203DFE242025FC25243DFC252425FC24223DFE240825FE2508448854288810 +819F:004078204BFE482048487AF249244A5248F8780848204BFE4820482048209820 +81A0:00007BDE48424A52494A7A52482848C44B1278604988483249C4481848609B80 +81A1:0020792448A849FC48407BFE488849044BFE7D0449FC490449FC490449FC9904 +81A2:002079FC49244BFE492479FC482049FC492479FC48404BFE488849D048709B8C +81A3:004078204BFE4A8A49047BFE4840488849FC7824482049FC482048204BFE9800 +81A4:000079FC48204BFE4A2279AC482049AC480079FC480449FC4804480449FC9804 +81A5:10141010FDFE11107DD43948554A929611223FF8228824482108228824482018 +81A6:0020792448A84BFE48A879244A224904490479DE4A444D54489E49044A049C04 +81A7:00203DFC2488245037FE2C0025FC25242DFC352425FC242025FC442057FE8800 +81A8:008278824FF4488848807BE248024BE44A287A204BE04A22494248744F889A10 +81A9:00147BFE48104BD048107BD048104BD04A507BD04A504BC84A4A4BCA49869A42 +81AA:0040782049FC488848507BFE4A224C2449FC7924492C482049FC490449FC9904 +81AB:00203C2025FC242025543C88250426FA24883CF8248824F8242044A855248860 +81AC:00387BC048784BC048787BC4483C480048C67B3849CE4F3849CE4F38494A9986 +81AD:00203DFC252425FC24203FFE240025FC25043DFC250425FC250445FC54888904 +81AE:0020782049FC48204BFE79084B9C490849887E3E48004BFE4890489049129A0E +81AF:00107BD248544948488A79044AFA4C0049FC7904490449FC490448884FFE9800 +81B0:003C7BE0492448A84BFE78A849244A0249FC7924492449FC4924492449FC9904 +81B1:011078944BD248124A5079904FFE48104BD27A524A544BD44A4A4A4A4BD69822 +81B2:00A0789049FE49104B107DFE4910491049FE7910491049FE49004AA44A529C52 +81B3:008878504BFE482049FC78204BFE492448A87BFE480049FC4904490449FC9904 +81B4:00803C8025FE275425543D5427FE255425543D5427FE24002554452A562A8800 +81B5:00883C8827FE248824203FFE2488248825543E22242027FE2420442054208820 +81B6:00007BDE4A524BDE4A527BDE4A024AFA4A227A724A224A224AFA4A024A0A9A04 +81B7:0280724E54EA55AA59AA7EEA52AC54AA55EA7F8A528A52AA54AC54E858A8B008 +81B8:002079FE4C404AFC49107AFE48004EFC4A847AFC4A844AFC4A844A8C4D0098FE +81B9:00203DFC2420248827FE3C8825FC250425FC3D0425FC250425FC448855048A02 +81BA:00803FFE225024FC2D9036FC249024FC200027F8240827F8440847F884080418 +81BB:00207BFE48004BFC4A047AF44A944BFC480079F8490849F8490849F848009BFE +81BC:00007A7C49444974485478544EFE4A824ABA7AAA4ABA4A824A8A4A844D0098FE +81BD:00803CF8250827FE25443D9225FE2500257C3D00257C2500257C4544557C8A44 +81BE:00203C502488257426023DFC252425AC25243DFC240024F8248844F8548888F8 +81BF:00503DFC255425FC25543DFC240025FE25003D7C250025FE2550455455488A66 +81C0:7E7842487E4854867E7854487E3094CE62001FF010101FF010101FF010101030 +81C1:00207BFE4A884A504BFE7A504AFC4A544BFE7A544AFC4A504AD84D544E529850 +81C2:3E1022FE3E4420287EFEA2103EFC221000001FF010101FF010101FF010101030 +81C3:004078204FFE48284A247A7E4CC84F48497E7A484CC84F7E49484A484C7E9840 +81C4:0040787C48404BFE4A427A784BC44A3C4A007BFE4A404BA44A584DB44C5299B0 +81C5:00003DFC2554255425FC3C8025FE264225F23D52255225F2244A47FA540A8804 +81C6:0040782049FC488848507BFE480049FC490479FC490449FC48204A944A8A9C7A +81C7:00A0789049FE4B2049FC792049FC492049FE79004BDE4A524A524A724A029A06 +81C8:00887BFE488849FC490479FC490449FC488079FE4A224D52490249FA480A9804 +81C9:00203C202450248825043EFA2400240025DC3D54255425DC2488448855548A22 +81CA:00F83C88248824F824003DDC2554255425DC3C2027FE247024A8452456228820 +81CB:7E7842487E4854867E7854487E3094CE63003FF8228824482108228824482018 +81CC:008878884FC848BE48887BC8481C4BD44A547A544BD44A48498848D44F149A22 +81CD:0080704057FC511050A47F58555455525B587000520853F8520853F85208B408 +81CE:03DE78424A52494A4A5278204BFE4888488879544A2248204BFE482048209820 +81CF:004078204BFE4A0249FC79484A5049FC4B0479FC490449FC490449FC48889904 +81D0:001C3DE0242027FE24203DFC25AC257425FC3C2025FC242027FE440055548A2A +81D1:000079FC48204BFE4A2279AC482049AC48007BFE482049FC495449544954990C +81D2:00887BFE48A8489049FE7B2049FC492049FC792049FE49004BFC488848709B8E +81D3:0090709057FE5094500A77FE540855E8554A75EA552A55EA554C55EA5416B862 +81D4:03DE7A924BD24A544BC87A944BE2480049FC790449FC490449FC490449FC9888 +81D5:004078204BFE4A504BFE7A524BFE4A004A947AD84A904AD24A8E4C0049549A2A +81D6:2FEC48244BA4682C4BA46AAC4BA4FFFE10103FF8D0161FF010101FF010101030 +81D7:00207BFE4A8A49FC488879FC490449FC490479FC490449FC4890489449129A0E +81D8:01247A48492448004BFC7A944A644A944BFC7A484B684A484B6A4A4A4A469B62 +81D9:0110711057FC511051F0720852EA56AC52A872AA56EA5A06500052A45252B452 +81DA:0040787C48404BFC4A447BF04A444AFC4AA87AF84AA84AF84A004DFC49549BFE +81DB:01FC78204BFE4A224DAC782049AC489049FE7B204DFC492049FC492049FE9900 +81DC:0108752857BE594857BE731855AA5946500073F852085248524850B05108B604 +81DD:0100FFFE20003FF800003FF820083FF8054077DC555477D4511C7FF65556B922 +81DE:03DE7A524BDE4A524BDE7A524BDE489049FE79104BFE4D1049FE491049FE9900 +81DF:0090709057FE5094500A71FE550857E8514A71EA5F2A55EA554C59EA5216B462 +81E0:210447C88812F3BC20084B92F83E0380AAAAABAA01003FF82288244821082298 +81E1:2450FF4824FE3D9008FC7E9052FC7E9024FE4280BFF822882448292822882458 +81E2:052877BE594857BE531875AA594653FC520473FC520453FC520453FC5108B204 +81E3:00003FFC2100210021003FF820082008200820083FF82100210021003FFC0000 +81E4:00007E0048FC484448447E444244422842287E2848104810482848487E840102 +81E5:00207E204820482048207E204220422042507E5048504850484848887E840102 +81E6:0000FE7E1248124812487E7E42424242424242427E7E124812481248FE7E0000 +81E7:002800245FFE502057A07520152017A4F4A454A857A85510951227AA20464082 +81E8:00407E40487E488049007E7C42444244427C7E0048EE48AA48AA48AA7EEE00AA +81E9:0000FEFE12907EFC42847EFC1290FEFE02007FFC04401830E44E044008401040 +81EA:0100020004001FF01010101010101FF0101010101FF01010101010101FF01010 +81EB:0820082010207F20412041207F20412041207F204120412241227F22411E0000 +81EC:020004001FF010101FF010101FF010101FF00100FFFE054009203118C1060100 +81ED:020004003FF820083FF820083FF820083FF801200110FFFE028004401830E00E +81EE:02001FF010101FF010101FF010101FF0000000FC7F0011101110292845440100 +81EF:02001FF010101FF010101FF010101FF021081110092011102108FFFE01000100 +81F0:02001FF010101FF010101FF010101FF00000FFFE08401F48625014621842E03E +81F1:02001FF01490125011301FF001007FFE4A2291143FF8040007F0081010502020 +81F2:102020207E7C42847F0842FE7E8042BC7EA410A4FEB418A834A25322911E1200 +81F3:00007FFC02000400082010103FF80008010001003FF8010001000100FFFE0000 +81F4:0040FE401040208028FE4508FE881288108810507C50102010501E88F1044202 +81F5:0040FE401078208829504420FE501288110610F87C88108810881E88F0F84088 +81F6:0020FE20102021FE28404440FEBC1284118812887CFE108810881E88F0A84090 +81F7:084008487F4408440840FFFE00407F44104422447F28092A3E12082A0F46F082 +81F8:0000FEFE1010202028444482FEFE1212101010107CFE101010101E10F1FE4000 +81F9:0028F8242024402053FE8A20FA242A2423A4FAA822A822903A92E5AA44460882 +81FA:0100FFFE01003FF800001FF010107FFE40029FF408201FF001003FF80100FFFE +81FB:0020F82023FE402051FC8840FBFE28882134FAE2202021FC3870E0AC43220020 +81FC:00000400387820082008200820083C78200820082008200820083FF820080000 +81FD:040004000FF01010202040408C003078200820083C782008200820083FF82008 +81FE:010005003978210821083D782108210821083FF821080280044008203018C006 +81FF:001001F83F000100FFFE01000D003178210821083D782108210821083FF82008 +8200:00FC7F0002082108111010200C003078200820083C782008200820083FF82008 +8201:060038F8200820083EF8200820083FF808200820FFFE08200820102020204020 +8202:010001007FFC01003FF80200FFFE044008203418D87610101C7010101FF01010 +8203:060038F8200820083EF8200820083FF810001FF820003FFC0004492484940008 +8204:060038F8200820083EF8200820083FF810003FFC400489242494249440280010 +8205:3E7820083C7820083FF800001FF011101FF011101FF002007FF8040818286010 +8206:1100611C47C44204751C47C4410477DC41044104FFFE00000820101020084004 +8207:0A003238238822083A38238820883AB822882288FFFE00000820101020084004 +8208:00002FEC48244BA4682C4BA44AA46AAC4BA44824FFFE00000820101020084004 +8209:0A0033B822083BB820883AB82288FFFE082011102FE8C1061FF0010001000100 +820A:0820FFFE09201FFC30805FF890801FF810801FFC02001C7810081E7810081FF8 +820B:2FEC48244BA4682C4BA46AAC4BA4FFFE80021FF010101FF010101FF01010FFFE +820C:001000F83F0001000100FFFE0100010001001FF010101010101010101FF01010 +820D:01000280044008203018CFE6010001003FF8010001001FF0101010101FF01010 +820E:01000280044009203118CFE6010001003FF8000000001FF0101010101FF01010 +820F:04040E04784408440844FF44084408443E4C22542264224422043E0422040004 +8210:08041C1E71F011101110FD10111011FE7D10451045104508450A7D4A45860102 +8211:08201C20702011FC1124FD2411FC11247D24452447FE450445047D0445140108 +8212:100011F82808445082207C1013FE1022FE24102010207C20442044207CA04440 +8213:08001DFC710411FC1104FDFC108010807DFE464A444A449245227E4244940108 +8214:08001DFC7020102011FEFC50105010887D244622442444B244AA7D2A44A00040 +8215:08201CA270A211241050FC88130410227C2044A444A4452844507C8845040202 +8216:102810242BFE442082207DFC11241124FFFC112411247DFC452445247D24450C +8217:102810242BFE542092207DFC11241124FDFC01247D2445FC452445247D24450C +8218:1020101029FE450282007CF810881088FEF8108010807CFC448444847CFC4484 +8219:00F83F000100FFFE01001FF010101FF00C0C70701010FEFE10107C7C44447C7C +821A:08801CF8710813FE1144FD9211FE11007D7C4500457C4500457C7D44457C0244 +821B:1010101010101E1012FE2210229052908A90049004FE08100810101020104010 +821C:007C3F800108108808907FFE481208101EFC221052900C9008FE101020104010 +821D:02003FF00410FFFE1110222011107FFE440288241FF001001FF021003FF80100 +821E:10003FFC4AA00AA07FFC0AA00AA07FFC101010103EFC4210149008FE3010C010 +821F:020004001FF01010121011101110FFFE10101210111011102010201040508020 +8220:080010003EFC222432242A242A24FE24222432242A242A44224442844B288610 +8221:080010003E7C221032102A102A10FE10221032102A102A10221042104AFE8400 +8222:102020207C204420652455245524FD244524652455245524452445FC54048800 +8223:104020247D244504650454885488FC8844506450542054204450448855048A02 +8224:080010003E78224832482A482A48FE68225832482A482A4A224A428A4A868500 +8225:100020007DFC4524652455245524FD2445FC6500550055004502450254FE8800 +8226:102020207C204420642055FE5420FC204420645054505450448844C855248A02 +8227:081010203E78224832482A482A48FE68225832482A482A4A224A428A4A868500 +8228:1004200E7CF04480648054FC54A4FCA444A464A854A854904510452856448882 +8229:101020907C904488648855245524FE224420644054485444448445FE54828800 +822A:104020207C0045FC6400540054F0FC90449064905490549244924512550E8A00 +822B:104020207C2045FE644054405440FC7C44446444544454444484448455288A10 +822C:080010783E48224832482A862A00FEFC224432442A282A28221042284A448582 +822D:101021107D1045126512551455D8FD10451065105510551245524592550E8800 +822E:102020107C1044FE648254825482FCFE44826480548054804480450055008A00 +822F:102020207C20442065FC55245524FD24452465FC552454204420442054208820 +8230:100021FC7D044504652455245524FD2445246554545054504490449255128A0E +8231:102020207C504450648855045602FCF84488648854A8549044824482547E8800 +8232:082010203E50225032882B242A12FE1023FC32042A082A88225042204A108410 +8233:102020207C20442065FC55245524FD24452465FC552455244524452455FC8904 +8234:108020807C8044FE654055405640FC7C444064405440547E4440444054408840 +8235:082010103E1022FE32822A842A40FE44224832502A602A42224242424A3E8400 +8236:081010103E2022FC32842A842A84FE8422FC32842A842A84228442844AFC8484 +8237:102020107C1045FE642054205444FC8445F8641054205444448245FE54828800 +8238:100020007DFE4408640855E85528FD284528652855E855284408440854288810 +8239:080010783E48224832482A482A8EFF00220032FC2A842A84228442844AFC8484 +823A:100021FC7D244524652455FC5524FD24452465FC552454204420442054208820 +823B:102020207C3C4420642054FC5484FC84448464FC548454804480450055008A00 +823C:104820487C48444865FE54485448FC48444865FE540054484444448454828902 +823D:082010203E3C224432A82A102A28FED6221032FC2A102A9022FE42104A108410 +823E:100023FE7C50445065FC55545554FD5445546554558C55044504450455FC8904 +823F:102020207BFE4850688859044AFAF8004BFE4840688059FC4804480448289810 +8240:1008203C7DC04404654454A85400FDF84410642057FE54204420442054A08840 +8241:081010503E50227C32502A902A10FEFE220032002A7C2A44224442444A7C8444 +8242:104020407CFC44886550542054D8FF2644F8642054F8542047FE442054208820 +8243:100021FC7D24452465FC55245524FDFC4420642055FC54204420442057FE8800 +8244:102021247CA444A8642055FC5504FD0445FC6504550455FC4504450455148908 +8245:102020207C504488650456FA5420FC2047FE6420552855244622442254A08840 +8246:082010103EFC228432842AFC2A84FE8422FC32A22AA42A98229042884AC48482 +8247:100020067BB8488868885908493EFB8848884A886A88593E49004A804C7E9800 +8248:102020107DFE44206448548455FEFC0244A864A854A854A844A844AA552A8A06 +8249:100021FC7D04450465FC5500551CFD70451C6570551E55F04510451255128A0E +824A:081010203E7C2244327C2A442A7CFE10221032FE2A922A92229242964A108410 +824B:100021FC7C084410642057FE5420FCA0444065FC555455544554455457FE8800 +824C:102020207850488869445A2249F8F8084850482068A45A824A8A4A8A4C789800 +824D:100021FC7D04450465FC55105510FDFE45106510557C554445444544557C8A44 +824E:102020407DFC450465FC550455FCFC0047FE6420542055FC4420442057FE8800 +824F:108420487DFE4420644054FC5484FC8444FC6484548454FC4484448454FC8884 +8250:105021247D54450465FC54505488FD4444786488548855504420445054888906 +8251:102020107DFE4502650255FE5500FD0045FE65AA56AA54FE44AA44AA54AA8886 +8252:100021FE7D02457A6502557A5502FC0044FC648454FC548444FC448454FC8884 +8253:104821487D4847FE654855485578FD0045FE642057FE547044A8452456228820 +8254:104020207DFE4548654855FE5548FD78450065FC554455484528451055288AC6 +8255:102020107DFE4484644855FE5502FE24441065FE5440547C4444448454948908 +8256:108420447C4845FE642054FC5420FDFE4440648054FE55104610441055FE8800 +8257:110420847C88440067FE54005488FD04460265FC555455544554455457FE8800 +8258:10A0212C7D24452465AC55245524FDFC442065FC548854504420445054888B06 +8259:102020207C50444864A455FE5684FCFC448464FC548054FC45444544567C8844 +825A:105020507DFE445065FC555455FCFD5445FC640054F8548844F8448854F88888 +825B:102021FC7D2447FE652455FC5420FDFC452465FC544057FE448845D054708B8C +825C:115421547BFE495469545A724C00FBFE4A22482069FC592449244924492C9820 +825D:100021FC78204BFE6A2259AC4820F9AC480049FC680459FC4804480449FC9804 +825E:111021107DDE46A8644454505554FCD8445064D8555456524490449255128A0E +825F:102021FC7C88445067FE540055FCFD2445FC652455FC542045FC442057FE8800 +8260:101023D278544948688A59044AFAFC0049FC4904690459FC490448884FFE9800 +8261:1020212478A84BFE6A0258F84888F88848F8480069FC592449FC492449FC9904 +8262:102020207BFE492469245AAA4FFEF80049FC4904697459544974490449FC9904 +8263:1040207C78404BFE6A425BF84A44FAFC4AA84AF86AA85AF84A204DFC4844998C +8264:110420887BFE482069FC58204BFEF854499248906BFE589048D44B8A489699A2 +8265:101023D47A524A526BD058104FFEFA504BD24A526BD45A544AEA4F4A48569862 +8266:100823E87A884BEE6A285BF44A82FBE2480049FC69545954495449544FFE9800 +8267:108823FE7CA8449065FE572055FCFD2045FC652055FE550047FC448854708B8E +8268:108823FE78884BFE6A0259FC4800FBFE484048A26B5458B84B5448924B509820 +8269:104020207BFE488868525FAC4AAAFAA84DAC4800690459FC490449FC49049A04 +826A:108021F87E0845FC652455FC5524FDFC4554662A55FC550445FC450455FC8904 +826B:1040207C78404BFC6A445BF04A44FAFC4AA84AF86AA85AF84A004DFC49549BFE +826C:11F022107BFC4E046BFC5A244BB8FA2249FE4A106FFC5A444BFC48D0494A9A3E +826D:110822947BDE4EB46BDE5A944BDEFA944BDE4A106FFC59084890486049989E06 +826E:00003FF0201020103FF0201020103FF022002208211020A02440282030182006 +826F:020001003FF0201020103FF0201020103FF02208211020A02040242028183006 +8270:000001F8FD08050845F84508290829F811441148293029204510454881860100 +8271:2200227CFF4422443E7C08447F44497C7F5208527F540848FF48144422624140 +8272:080008001FE020204040BFF82108210821083FF820002002200220021FFE0000 +8273:1080108010F8FD08121015FC11247D24112411FC1100FD001102110210FE1000 +8274:28202820287CFE442A882A7CFE54A854A854FF7C294029402D424A42483E8800 +8275:4240244000FC7E88251024FC24A424A4FFA424FC2480248024824482447E8400 +8276:28402840FEF8AA88FF10AAFCFEA400A4FEA400FC7C8044807C8248823E7EC000 +8277:2A107F10AA9CFFA4AAC8FFBEAAAAFFAA002AFFBE00207F2041227F222222FF9E +8278:10101010101092929292929292929292FEFE1212101010102010201040108010 +8279:08200820FFFE0820082000000000000000000000000000000000000000000000 +827A:08200820FFFE0820082000003FE000C00300040008001000200420041FFC0000 +827B:08200820FFFE08200A20020002007FF802080408040808080808100820504020 +827C:08200820FFFE0820082000007FFC010001000100010001000100010005000200 +827D:08200820FFFE08200820040004007FE0042004200820082010222022401E8000 +827E:04400440FFFE044000200820082004400440028001000280044008203018C006 +827F:04400440FFFE044000003FF8040804100420047C080408041004204440288010 +8280:08200820FFFE0820082000003FF8020802080208020804080408080810506020 +8281:08200820FFFE0820082000000FE00820082008200820102210222022401E8000 +8282:08200820FFFE0820082000007FF8020802080208020802500220020002000200 +8283:08200820FFFE0820082000000FE0082008200A200920092210221022201E4000 +8284:08200820FFFE08200820020002007FE002200A200420062009221022201E4000 +8285:08200820FFFE08200A200210021002FEFF00020001000100008000420032000E +8286:08200820FFFE082000003FF0121011200820044002800100028004401830E00E +8287:08200820FFFE08200820010001003FF821082108210821082128211001000100 +8288:09200920F93E0920092001003FF8010001000100FFFE01000100010001000100 +8289:08200820FFFE0820082000003FF8010001000100FFFE01000100010001000100 +828A:04400440FFFE0440000000F83F00010001000100FFFE01000100010001000100 +828B:08200820FFFE082000003FF8010001000100FFFE010001000100010005000200 +828C:0820FFFE082000003FF800000000FFFE040008000FF000100010001000A00040 +828D:04400440FFFE0440100010001FF8200840088808040802080208000800500020 +828E:04400440FFFE044000003FF8000800083FF8200020003FFC0004000400280010 +828F:08200820FFFE082009200100010001003FF801000100010001000100FFFE0000 +8290:08200820FFFE082008200000FFFE020002000240022002100208020002000200 +8291:08200820FFFE082000003FF00010001000103FF020002004200420041FFC0000 +8292:08200820FFFE0820082002000100FFFE0800080008000800080008000FFC0000 +8293:08200820FFFE0820082000001FE0004000800100FFFE01000100010005000200 +8294:01002108210821083FF8010011101010929292929292FEFE2212201040108010 +8295:08200820FFFE08200A20020007F808081010642002400280010006001800E000 +8296:08200820FFFE0820092001000100FFFE0100028002800440082010102008C006 +8297:08200820FFFE0A20040008101FE000C003040C083FF01020004001800E007000 +8298:08200820FFFE082008202080208020883C9020A020C0208424842884307C0000 +8299:08200820FFFE0820092001003FF801000100FFFE01000280044008203018C006 +829A:08200820FFFE082009200100FFFE01002108210821083FF8010A0102010200FE +829B:08200820FFFE082000003FF002100210FFFE021004103FF0081010002000C000 +829C:08200820FFFE082000003FF0020002007FFC02800480048008841084207CC000 +829D:08200820FFFE08200A20010001007FF8003000C003000C003000480087FE0000 +829E:04400440FFFE044010001FFC20005FF880003FF0001000100010000A00060002 +829F:08200820FFFE082000000FE008201020601C00001FE00820044003801C70E00E +82A0:08200820FFFE08200820020001007FFC0820082004400280010006C01830E00E +82A1:04400440FFFE0440080008000FFC10042108410001000280044008203018C006 +82A2:08200820FFFE082000000800080013FC3000500090001000100017FE10001000 +82A3:08200820FFFE0820082000007FFC008001000300056009183104C10201000100 +82A4:04400440FFFE044000007F400240044008400F40F840484208420842283E1000 +82A5:08200820FFFE082009200280044008203458C446044004400840084010402040 +82A6:08200820FFFE0820092000803FF8200820083FF8200820002000400040008000 +82A7:08200820FFFE082000003FF0002006400180FFFE008200840080008002800100 +82A8:04400440FFFE044000003FF0082008400CF80A08111010A0204020A043188C06 +82A9:08200820FFFE08200920028004400A203118C1061FE000200040004000800100 +82AA:08200820FFFE082000783F802080208020803FFE2040204020242814300C2004 +82AB:08200820FFFE082000001FF0000000007FFC044004400440084408441044603C +82AC:08200820FFFE082000400440082010102008DFE6042004200820102021404080 +82AD:08200820FFFE082000003FF82108210821083FF820002002200220021FFE0000 +82AE:08200820FFFE0820092001003FF8210821082288244828282008200820282010 +82AF:08200820FFFE0820082002000100008004082404240244028410041003F00000 +82B0:08200820FFFE092001007FFC010001003FF0082004400280010006C01830E00E +82B1:08200820FFFE082000000888089010A030C050809180128214821082107E1000 +82B2:08200820FFFE0820092002800C603018C80608E00F0078080808080807F80000 +82B3:08200820FFFE08200A200100FFFE0400040007F0041008100810101020A04040 +82B4:08200820FFFE0820100010001FF8224842488488088811082208440808501020 +82B5:08200820FFFE0820092001003FF0011001100110FFFE0280044008203018C006 +82B6:08200820FFFE082010001FF8200844088408090810883FC81048000800500020 +82B7:08200820FFFE08200820010001000100110011F81100110011001100FFFE0000 +82B8:08200820FFFE0820082000003FF800000000FFFE02000400082010103FF81008 +82B9:08200820FFFE082000381FC0100010001FFC1040104010402040204040408040 +82BA:08200820FFFE0820082000F03F0001000100FFFE01000280044008203018C006 +82BB:080008001FF8220852481FC80408085030201FF8220852489FC8040808503020 +82BC:08200820FFFE0820082000F83F00010001F83F00010001FC7F020102010200FE +82BD:08200820FFFE082000003FFC0020102020203FFE012002200C203020C0A00040 +82BE:08200820FFFE082009200100FFFE010001003FF8210821082108212821100100 +82BF:08200820FFFE0820100017F8210821106120A13C210421042204220424282810 +82C0:08200820FFFE08200A2001007FFC000000000FE00820082008221022201EC000 +82C1:08200820FFFE0820082000000820082008200820082014501250228841048202 +82C2:08200820FFFE082009200100110811081110212002800280044008203018C006 +82C3:08200820FFFE08200A200200FFFE040004000FF008101420224041808670380E +82C4:08200820FFFE08200A2001000100FFFE02000200024002200210020002000200 +82C5:08200820FFFE0820082002044244244414440844084414442404420482140008 +82C6:08200820FFFE08200820200021FC2C44F0442044204424842884310422280410 +82C7:08200820FFFE092001007FFC010001001FF0010001007FFC0104010401140108 +82C8:08200820FFFE082000003FFC210021002FF82108210822082208440848509020 +82C9:08200820FFFE082000003FFC22402240224022442444243C280020003FFC0000 +82CA:08200820FFFE082000003FFC2000200027E02420242024A024444404440483FC +82CB:08200820FFFE0820082000001FF010101110111011101290028004821882607E +82CC:04400440FFFE04400800083009C00E000800FFFE0900088008400A300C0E0800 +82CD:08200820FFFE082009200280044008203018CFE60820082008A80848080807F8 +82CE:08200820FFFE08200A2001007FFE4002800400000000000000007FFC00000000 +82CF:08200820FFFE08200A2002007FF0021002142212221224124410081010A02040 +82D0:0820FFFE082000003FF8010801083FF8210021003FFC030405041928E1100100 +82D1:04400440FFFE044010001EF812882288228852A88C90048208821082207E4000 +82D2:08200820FFFE0820082001003FF8210821083FF821082108FFFE200820282010 +82D3:08200820FFFE0920028004400A203118C1061FE0002000400C80030000800040 +82D4:08200820FFFE08200400082010103FF8000800001FF01010101010101FF01010 +82D5:08200820FFFE082000007FF80408080810502020DFF81008100810081FF81008 +82D6:08200820FFFE0820092001003FF82108210821083FF82108210821083FF82008 +82D7:08200820FFFE0820082000003FF82108210821083FF82108210821083FF82008 +82D8:04400440FFFE044000003FF82008200827C824482448244827C8200820282010 +82D9:08200820FFFE08200A20010000007FFC001010100820044004800000FFFE0000 +82DA:08200820FFFE082000003FF8210821083FF8210821083FF82108410841288010 +82DB:08200820FFFE082000007FFC001000101F10111011101F101110001000500020 +82DC:08200820FFFE082000003FF8200820083FF8200820083FF8200820083FF82008 +82DD:08200820FFFE082008200000044004447C480470044004420C423442C43E0400 +82DE:04400440FFFE044008001FF020105F90109010901F901050102410040FFC0000 +82DF:04400440FFFE044010001FF8200840089F88108810881F881088000800500020 +82E0:08200820FFFE08203FF8200820083FF8208020803FFC204020242414280C3004 +82E1:08200820FFFE0820000024102210211021102010202024202850308821040602 +82E2:08200820FFFE082000001FF0101010101FF0100010001FF8100810081FF81008 +82E3:08200820FFFE082000003FF8200020003FF0201020103FF02000200020003FFC +82E4:08200820FFFE082000007FFC00800100036005101908610401000100FFFE0000 +82E5:08200820FFFE08200A200200FFFE040008001FF028104810881008100FF00810 +82E6:08200820FFFE0820092001000100FFFE010001001FF01010101010101FF01010 +82E7:08200820FFFE08200A2001007FFE400280043FF8010001000100010005000200 +82E8:04400440FFFE04401FF8100810081FF810001200123813C02204220441FC8000 +82E9:08200820FFFE0820092002003FF82008200820083FF82008200820083FF82008 +82EA:08200820FFFE082000007FFC010001003FF82108228824482828200820282010 +82EB:08200820FFFE08200920010001FE0100010001003FF82008200820083FF82008 +82EC:08200820FFFE082000003FF8210821082108210822882448282820083FF82008 +82ED:08200820FFFE08201040104021FC24444444F844104420444884FC8445280210 +82EE:08200820FFFE0820000008200820102031245124912411241124112411FC1004 +82EF:08200820FFFE0820010001007FFC03800540092011102FE8C106010001000100 +82F0:08200820FFFE082000007E10021002103E10202040287E24024402FE14420800 +82F1:08200820FFFE0820010001001FF0111011101110FFFE0280044008203018C006 +82F2:04400440FFFE0440080008001FFC2400440087F00400040007F8040004000400 +82F3:08200820FFFE0820040008001FF02820444003801C70E30E00C00E0001800040 +82F4:08200820FFFE082000001FF0101010101FF0101010101FF010101010FFFE0000 +82F5:08200820FFFE0820010011001FF821000100FFFE01000280044008203018C006 +82F6:08200820FFFE082009200280044009203118C106010009201110210805000200 +82F7:04400440FFFE044010101010FFFE1010101010101FF01010101010101FF01010 +82F8:08200820FFFE0820001000F83F00111009200100FFFE01000100010005000200 +82F9:08200820FFFE082000007FFC01001110091009200100FFFE0100010001000100 +82FA:08200820FFFE082000001FF012101110FFFE1010221021103FFC001000A00040 +82FB:04400440FFFE044008100810101013FE30105110909010901010101010501020 +82FC:08200820FFFE0920110011003FFC4100810001003FF8010001000100FFFE0000 +82FD:08200820FFFE0820000000781FA012201220122012101290224822A843248202 +82FE:08200820FFFE0820082001000090089048244842488289020E101810E7F00000 +82FF:08200820FFFE0820092001003FF801000100FFFE0380054009203118C1060100 +8300:08200820FFFE082004403FF8044804481FF8144024403FFC0844105420484040 +8301:08200820FFFE082009202108210821083FF8010801004104410441047FFC0004 +8302:08200820FFFE0820009000883FFC2080208820882050205020244054418C8604 +8303:04400440FFFE0440100009F84908210825080528091071021102110210FE0000 +8304:08200820FFFE082000001000107C7E441244124412441244224422444A7C8444 +8305:08200820FFFE082000003FF0002006400180FFFE0282048408803080C2800100 +8306:08200820FFFE082000000C0070FC4084448444845C8464944888088010806080 +8307:04400440FFFE044002100208FFFE040004000FF008101420224041808670380E +8308:08200820FFFE08200440044024442448275024602440244224422F42F03E4000 +8309:08200820FFFE092001000100FFFE010001007FFC0380054009203118C1060100 +830A:04400440FFFE0440001000781F80100010001FFC1040104010401040FFFE0000 +830B:08200820FFFE082008783F802080208020803FFE2040204022242914308C2084 +830C:04400440FFFE0440080008401040104037FE5040904010401040104013FC1000 +830D:04400440FC7E0440144010001FF8200840089F88108810881F88000800500020 +830E:04400440FFFE044000003FF0006001800E70700C1FF0010001000100FFFE0000 +830F:08200820FFFE08200820004004207FFC04800488089008A010C223824C82807E +8310:04400440FFFE0440100010001FF822484A4884880A8811082288440808501020 +8311:08200820FFFE092002001FF012101110115010201FFC00047FE4000400280010 +8312:04400440FFFE044010001E7C12442248225052488C4404440854104820404040 +8313:08200820FFFE08200A2001007FFE40028004044004400820082010102008C006 +8314:08200820FFFE082000007FFE4002810401003FF80100010001000100FFFE0000 +8315:08200820FFFE082000007FFE400280041FE0042004203FA004200414040C0404 +8316:04400440FFFE044008000FF010202C4003801C70E00E1FF0101010101FF01010 +8317:08200820FFFE0820020007F808103420024001800FF81808E80808080FF80808 +8318:04400440FFFE044000003FF804080850302000007EFC1224122422444A948508 +8319:08200820FFFE082000900088FFFE0080108810887E50105010242054418C8604 +831A:08200820FFFE0820060078FC408440847E844084408440944E88708000800080 +831B:04400440FFFE044000003FF020103FF020103FF02208211020A024402830300E +831C:04400440FFFE04400000FFFE044004403FF8244824482848303820083FF82008 +831D:08200820FFFE082000003FFC2080208027F82408240827F8208020803FFE0000 +831E:08200820FFFE082000003FFC210021003FF8200820083FF8210021003FFC0000 +831F:08200820FFFE082001003FF00110FFFE01103FF001003FF80100FFFE01000100 +8320:04400440FFFE0440000008400840104037FC50E0915011501248144418421040 +8321:08200820FFFE0A2001007FFC400480081FE000400080FFFE0100010005000200 +8322:08200820FFFE082000047F84082408241F24212451240A24040408043014C008 +8323:04400440FFFE044000001FF010101FF000003FF80100FFFE028004401830E00E +8324:0820FFFE0820020007E01840648003200C4071F806081A10012000C007007800 +8325:08200820FFFE082001003FF801000100FFFE000001003FF801000100FFFE0000 +8326:08200820FFFE09200100FFFE01003FF8210821082128239005601918E1060100 +8327:08200820FFFE0820092001003FF82108210821083FF80100011001F87F042004 +8328:08200820FFFE08204080208020FC0904124814402040E0A020A0211022082C06 +8329:08200820FFFE082000781F80100010001FFC1000100017F82408240847F88408 +832A:08200820FFFE08200100111009100920FFFE04400440044008421042203EC000 +832B:08200820FFFE082008202040102087FE490009001100E1002100210021FC0000 +832C:08200820FFFE0A2002000400FFFE08001040304053FC90401040104017FE1000 +832D:08200820FFFE08200A2001007FFC08201010244844440280010006C01830E00E +832E:08200820FFFE0A20020003F802000200FFFE0000010011101108210445040200 +832F:08200820FFFE0820000008500848104037FE504090A010A01110111012081406 +8330:0820FFFE092001003FF8210821083FF8210821083FF811000A00060019C0E03E +8331:04400440FFFE0540110011003FF841000100FFFE0380054009203118C1060100 +8332:04400440FFFE04401020102020402448448878F008101020142822447EFC0204 +8333:08200820FFFE08200820200017FC90404040484008401040E04020402FFE2000 +8334:04400440FFFE044000003FF82008200827C82448244827C8200820083FF82008 +8335:04400440FFFE044000003FF8210821082FE8210822882448282820083FF82008 +8336:08200820FFFE082009200280044009203118DFF6010009201110210805000200 +8337:08200820FFFE0820000008A00890108030FC57809048105010241054118C1604 +8338:08200820FFFE082000007FFC10101FF010101FF01010103EFFD0001000100010 +8339:08200820FFFE082010001000FE7C124422442244644414440844147C2244C000 +833A:08200820FFFE0A200100FFFE0400082010103FF804480440044008441044603C +833B:1010929292929292FEFE2010401080001010929292929292FEFE221220104010 +833C:08200820FFFE082000003FF820082FE8200827C82448244827C8200820282010 +833D:08200820FFFE082000001040104027FC6444A444244427FC2444204020402040 +833E:08200820FFFE0820082000007FFC082008200820FFFE08200820102020204020 +833F:08200820FFFE0820082000007DF011101110119011501D12E2124212040E0800 +8340:04400440FFFE144010001FF820085FC890481FC810481FC81048000800500020 +8341:08200820FFFE082000007FFC00001FF010101FF010101FF010100000FFFE0000 +8342:0820FFFE0A2002007FFC0440082037D8C0063FF808000FE00020002001400080 +8343:08200820FFFE09200280044008203018CFE6010001001FF0010001007FFC0000 +8344:08200820FFFE08200A2001007FFC040008401F8001100620384001A00E107008 +8345:08200820FFFE0820092002800C603018CFE600001FF01010101010101FF01010 +8346:12041204FFC4122400247FA4122412241224FFE4122412242204220442148208 +8347:04400440FFFE0440100021FC4000880013FE3020502090201020102010A01040 +8348:04400440FFFE0440101010103E1022FC4210A490149008FE1010201040108010 +8349:04400440FFFE044000001FF010101FF010101FF00100FFFE0100010001000100 +834A:08200820FFFE082000047F84122412241224FFE4122412242204220442148208 +834B:08200820FFFE082000007FFC010002003FF82488248824882488248824A82010 +834C:08200820FFFE0A2001007FFE400282040200FFFE042008201C4003800C707008 +834D:08200820FFFE082004404440448044FE450846885C9064504420045004880506 +834E:08200820FFFE082000007FFC040008201FF0011001003FF801000100FFFE0000 +834F:04400440FFFE04400810087813C0304050409FFE104010401040104017FC1000 +8350:08200820FFFE0A2002007FFC040009F8081018202BFE48208820082008A00840 +8351:08200820FFFE08200100FFFE01007FF801083FF821003FFC0284044C1830E00E +8352:08200820FFFE0A200100FFFE100010001FF8000011101110111021124112810E +8353:04400440FFFE0440101008207FFC082008200820FFFE08200820102020204020 +8354:0820FFFE0A2002003FF0041018A06040102010207EFC1224224422444A948508 +8355:08200820FFFE082000003E20222022FC3E24222422243E24224442444A948508 +8356:08200820FFFE0A2002083FD002200240FFFE0100061018E02F00C808080807F8 +8357:08200820FFFE0820009000883FFC2080208830882850245020244054418C8604 +8358:08200820FFFE0820000008204820282028200BFE082018202820C82009FC0800 +8359:08200820FFFE082020401040104007FC704010A01090110812041404280047FE +835A:08200820FFFE0820010001003FF8010011100920FFFE0280044008203018C006 +835B:08200820FFFE0A2002FC7F20014000840764381C00007FFC044008421042603E +835C:08200820FFFE0820208020883EB020C42084267C39000100FFFE010001000100 +835D:08200820FFFE082000047F044124492449244924492449241424220441148088 +835E:08200820FFFE082000F03F000200FFFE044008203458C4460440044008401040 +835F:08200820FFFE092002800440082037D8C00600003FF80200044008201FF00810 +8360:08200820FFFE0A2001007FFC0820044003800C603018C4460440044008401040 +8361:08200820FFFE0820000023F01020104080804BFC48A41124E244248421282210 +8362:08200820FFFE0A2001007FFE400280043FF801000100FFFE0100010005000200 +8363:08200820FFFE082000007FFE4002810401007FFC0380054009203118C1060100 +8364:0820FFFE082000007FFE420282043FF8090011001FF001000100FFFE01000100 +8365:08200820FFFE082000007FFE4002810401047D880550092011102108C5060200 +8366:08200820FFFE082000007FFE4002810411001FF821000100FFFE010001000100 +8367:08200820FFFE082000007FFE400281041110111022A00280044008203018C006 +8368:08200820FFFE08203FF000101FF000103FF00020FFFE08200420042000A00040 +8369:04400440FFFE04401FF0101010101FF010801040162021102088460681800040 +836A:04400440FFFE044000007C200420082010A810A41D24F1221222102050A02040 +836B:04400440FFFE044000007CFC4484488450FC4884448444FC5484488441144208 +836C:04400440FFFE044000007FFC04040288128008800900FFFE0240042018106008 +836D:08200820FFFE08201000100021FC4420F82010202020FC2040201C20E3FE4000 +836E:04400440FFFE044010081008200845FEF80810882048FC4840081C08E0284010 +836F:04400440FFFE04401080108020FC4504FA0410842044FC4400041C04E0284010 +8370:04400440FFFE0440102010201020FC2031FC3820542050209020102013FE1000 +8371:08200820FFFE08203FF820083FF8200020702F8020F02F8020F85F824082807E +8372:0440FFFE044000001FF0111011101FF0111011101FF001003FF801000100FFFE +8373:08200820FFFE082000007FFC00001FF0101010101FF0000008200440FFFE0000 +8374:04400440FFFE044010201020FDFC10201420182033FED0501050108851042202 +8375:08200820FFFE082000007FF80208120824280810310008844892481287F00000 +8376:08200820FFFE08200040004078A049104A884C4648404BF07810482000200040 +8377:04400440FFFE0440100017FE20086008A7C824482448244827C8200820282010 +8378:08200820FFFE092001003FF801007FFE40029FE400400180FFFE010005000200 +8379:08200820FFFE0820010011F811001100FFFE010009081110606001800E00F000 +837A:08200820FFFE08200820108010FC7D041204108410541C24E044418400280010 +837B:04400440FFFE04404420282010A428A448A89920282048508850088851042202 +837C:08200820FFFE092002800440082037D8C10601003FF801001110210845040200 +837D:08200820FFFE082000F87F00221011200200FFFE042008201C4003800C707008 +837E:0820FFFE08200400082010103FF804480820121067E80820144003801C70E00E +837F:08200820FFFE0820009000883FFC208020883E88225022502A244454418C8604 +8380:08200820FFFE082000003FF820002FF020003FFC248824504420451886060400 +8381:08200820FFFE082000007FFC01001110111011102928454485840100FFFE0000 +8382:08200820FFFE08203F04210421243F24082408247FA408A410A4108422944108 +8383:0440FFFE044030100CE003000CC03230FFFE080011003FF0D110115011200100 +8384:0820FFFE082000007FFC01003FF821083FF821083FF821001A00060019C0603E +8385:08200820FFFE082008800840104033FC50009008120811101110102017FE1000 +8386:08200820FFFE09200110FFFE01003FF821083FF821083FF82108210821282110 +8387:04400440FFFE044000203E20222022FC3E2422243E24222422442F44F0944108 +8388:08200820FFFE082021F011101110820C440053F011102110E0A0204021B02E0E +8389:04400440FFFE044000000608780808480848FF481C482A484948880808280810 +838A:04400440FFFE044000002420242024203C2007FE0420FC202420242025FC4400 +838B:04400440FFFE04400880088010FE11403240547C90401040107E104010401040 +838C:04400440FFFE0440082004401FF01010101010101FF00440044008421042603E +838D:04400440FFFE0440011001087FFC0100211811A007401920E118410605000200 +838E:08200820FFFE082000001020082040A824A40522092272281010106011800600 +838F:08200820FFFE082010001020FC2010A814A419223122D2281010106051802600 +8390:08200820FFFE08202040104013FC8244444810A010A0E120212022222422281E +8391:0440FFFE044008001FF0282007C01830E10E1FF001001FF001007FFC01000100 +8392:08200820FFFE082000001FF0101010101FF000003FF82008200820083FF82008 +8393:04400440FFFE144010003FFC40009FF012101110FFFE221021103FFC00100060 +8394:04400440FFFE044000003FF8200824482828301827C82448244824483FF82008 +8395:08200820FFFE092001007FFC054009203118C1061FF01010101010101FF01010 +8396:08200820FFFE082000007FFE08881110222011103FF8010001000100FFFE0000 +8397:08200820FFFE082001007FFC01003FF821083FF821083FF80100FFFE01000100 +8398:08200820FFFE0A2001003FF8000008200440FFFE010001007FFC010001000100 +8399:08200820FFFE082000003FF80408FFFE04083FF808001FF8280848088FF80808 +839A:04400440FFFE044000187BE00840104022787A400A402BFC1000280047FE8000 +839B:04400440FFFE044000387BC00840104023F8784008402BFC1000280047FE8000 +839C:08200820FFFE0820000010401040247E24886488A54824502420205020882306 +839D:08200820FFFE082001001110111011102928454481003FF801000100FFFE0000 +839E:08200820FFFE0A2001003FFC200440081FE000007FFC0440044008441044603C +839F:08200820FFFE09200280044009203098CFE6004000801FF0101010101FF01010 +83A0:04400440FFFE04701F8001007FFC054009203118CFC6044004F0081010506020 +83A1:04400440FFFE044000001FF0101010101FF00100110011F81100290047FE8000 +83A2:08200820FFFE0820092001007FFC11101110292845440280044008203018C006 +83A3:08200820FFFE092000807FFC080008000FF80000010008844892481287F00000 +83A4:08200820FFFE08200000FFFE04403FF824482448283830083FF820083FF82008 +83A5:08200820FFFE082044002BF81048284848489BF8284848888888088857FE2000 +83A6:08200820FFFE08200100111009201FF010101FF010101FF01010101010501020 +83A7:08200820FFFE082000001FF010101FF010101FF010101FF0044008421042603E +83A8:08200820FFFE0A2001001FF010101FF010101FF0110410881050122014181806 +83A9:08200820FFFE082000F87F00221011203FE000400080FFFE0100010005000200 +83AA:08200820FFFE0820064038500848FFFE084008400E2478280812082A28C61302 +83AB:08200820FFFE082000001FF010101FF010101FF001007FFC028004401830E00E +83AC:08200820FFFE0820040007E0082010403FF8510811081FF8028004821882607E +83AD:08200820FFFE082000007E7C42447E4442447E44404450544848544062404040 +83AE:08200820FFFE082000003FF821083FF821083FF802007FFC0404080410286010 +83AF:08200820FFFE082008202040104097FE40E0415011502248E444284220402040 +83B0:04400440FFFE04401080108010FC7D041248104010401CA0E0A0411002080C06 +83B1:08200820FFFE092001003FF80100111009207FFC0380054009203118C1060100 +83B2:08200820FFFE0820208017FC1140024073FC1040104017FE1040284047FE0000 +83B3:04400440FFFE044000107C10441045FE44107D104490449044107C1044500020 +83B4:04400440FFFE04401FF0101010101FF001007FFC410442844444484440144008 +83B5:08200820FFFE092002003FF82108210821083FF8228804900888108A2082C07E +83B6:08200820FFFE0820092002800440082037D8C00602101110092008407FFC0000 +83B7:08200820FFFE082044402850104828404FFE984028A048A08910091052082406 +83B8:04400440FFFE04404490288810882BFE48A098A028A0492089200A225222241E +83B9:08200820FFFE082000007FFE400280043FF8010001001FF00100014001207FFC +83BA:08200820FFFE08207FFE42029FF410101210115010201FFC000400047FD40008 +83BB:04400440FFFE044000003FE00420047C08043014C0083E44225822623E42223E +83BC:04400440FFFE04401020102023FE44207924112421247DFC00221C22E022401E +83BD:0820FFFE0820024002207FFC044008203018C82608207FFC0820102020204020 +83BE:0820FFFE0A2002007FFC0440092037D8C106092008207FFC0820082010202020 +83BF:04400440FFFE044008000804FFA408247F2449244B241C242A24490488140808 +83C0:08200820FFFE0A2001007FFE400290041EF82288248854A8089008841084607C +83C1:0820FFFE09203FF801001FF00100FFFE00001FF010101FF010101FF010101030 +83C2:08200820FFFE0820104020407E7C4284430442447E244224420442047E284210 +83C3:08200820FFFE0820200013FE920042004BFC0A041204E3FC2200220023FE2000 +83C4:08200820FFFE08200100FFFE01003FF821083FF821083FF803800D603118C106 +83C5:08200820FFFE082001007FFE40029FE410201FE010001FF0101010101FF01010 +83C6:08200820FFFE08207F0022FC22443E44224422283E2822102790FA2842440282 +83C7:04400440FFFE044010101010FEFE12102210227C6444144408441444227CC044 +83C8:08200820FFFE082010401020FC2011FC140018083108D0901090102053FE2000 +83C9:08200820FFFE08203FF000101FF00010FFFE111009A005401930E10E05000200 +83CA:04400440FFFE044010001FFC220452448A8402047FF407040A84124462140208 +83CB:08200820FFFE0820004000407BF8484048404FFC48E079504A48044408420040 +83CC:0820FFFE082000003FF8200820C8270821082FE823882548292821083FF82008 +83CD:08200820FFFE09200280044009203098CFE60040028001004884481287F20000 +83CE:08200820FFFE082000001FF810081FF810081FF82080208C3EF020822682387E +83CF:04400440FFFE0440200017FE100880084BC84A481248E3C82248200820280010 +83D0:0440244814500440FFFE082004407FFC01003FF80100FFFE028004401830E00E +83D1:08200820FFFE08200888111022201110088800003FF821083FF821083FF82008 +83D2:08200820FFFE082000003FF820083FF820083FF80100FFFE054009203118C106 +83D3:08200820FFFE082000003FF821083FF821083FF80100FFFE054009203118C106 +83D4:08200820FFFE08203EFC228422943E88228022FC3EA422A422A822904AA884C6 +83D5:08200820FFFE092002800C6037D8C0063FF8248824883FF82488248824A82010 +83D6:04400440FFFE04401FF010101FF010101FF000003FF820083FF820083FF82008 +83D7:04400440FFFE04401020102011FCFD24112411241DFCF1241124112451FC2104 +83D8:04400440FFFE0440101010901090FD0831483A44544250909088110813FC1104 +83D9:0820FFFE082000F83F0001007FFC09200920FFFE092009207FFC010001003FF8 +83DA:08200820FFFE0820021002FC7F4000840764781C021002FC7F4000840764781C +83DB:08200820FFFE082000007C7C44447C7C44447C7C400440044004400440144008 +83DC:08200820FFFE0820001000F83F001110082001007FFC054009203118C1060100 +83DD:08200820FFFE082010481044FDFE1040144018FC30A4D12811281210542820C6 +83DE:08200820FFFE08200C80708010FC1124FD243224384454445084910412281010 +83DF:0440FFFE044008000FE0102020405FF8110811081FF8028004A008921082607E +83E0:04400440FFFE04402020102013FC822442204BF80A881288E25024202450298C +83E1:04400440FFFE044000001FE040445194492443C445444924551442047FFC0004 +83E2:08200820FFFE082010801080FDFC120415F411141D14F1F4110C1102510220FE +83E3:08200820FFFE082000007F7C484448447F44412841287F10481048287F440082 +83E4:04400440FFFE0540111009203FF802007FFC082010102FE8C8260868080807F8 +83E5:04400440FFFE04401000100C11F0FD00110031FE391055105110921012101410 +83E6:04400440FFFE0440201813E01200020073FC1220122012201420282047FE0000 +83E7:08200820FFFE092000803FFE200020782F80288028802FFC284048244A948C4C +83E8:08200820FFFE0A2001003FF808200440FFFE04007FFC08201C4003800C707008 +83E9:08200820FFFE082001003FF808200440FFFE000000001FF0101010101FF01010 +83EA:0820FFFE0A2001007FFE400280043FF0040008001FF02810481008100FF00810 +83EB:08200820FFFE08207FFC01003FF821083FF801007FFC01003FF80100FFFE0000 +83EC:08200820FFFE082023FC10841084808449144A0815FCE1042104210421FC2104 +83ED:08200820FFFE082020801110120887FC4204500013F82208E208220823F82208 +83EE:08200820FFFE092000803FFE20802FF820883FFE20882FF8214042204C18B006 +83EF:04400440FFFE04407FFC11101110FFFE111011107FFC0100FFFE010001000100 +83F0:08200820FFFE0820001C7DF00950115011501D503148D14811441254525A2468 +83F1:08200820FFFE082001003FF80100FFFE1010220847E40820144003801C70E00E +83F2:08200820FFFE0820082004407C7C044004407C7C04400440FC7E044004400440 +83F3:08200820FFFE0820092002800C603018CFE6010001003FF811100920FFFE0000 +83F4:08200820FFFE0A2002007FFC044009203FF8D1161FF011101FF40104010400FC +83F5:04400440FFFE04407FFC482444445FF4410440845FF44404440447E440144008 +83F6:04400440FFFE044001007FFC01003FF80200FFFE092017D02108DFF601000100 +83F7:0820FFFE08201FF000100FF000101FF000007FFE41029FF41110115011200100 +83F8:04400440FFFE0440102008207E50105010881F0612601210220022C04A308408 +83F9:04400440FFFE0440100009F80908410821F82908090811F87108110817FE1000 +83FA:0820FFFE092000801FFC10041FFC100017F8140817F8240827F8440884280410 +83FB:04400440FFFE04400820082008207EFC08201C301A702A6848A4892208200820 +83FC:08200820FFFE082001000910092012C0043019086914091012A004401830600C +83FD:04400440FFFE044008000F7C08440844FF44002808282A104910892828441082 +83FE:04400440FFFE04403FF801000200FFFE08203118C10609901148214805000200 +83FF:08200820FFFE08207F84100422247F24092408247F24082408240F04F0144008 +8400:08200820FFFE092001F801003FFE210221F02F0420FC200027E044224822B01E +8401:04400440FFFE0440082008207FFC08200FE008200FE00820FFFE082010102008 +8402:04400440FFFE04400E00787C08440844FF4418441C442A444A44887C08440800 +8403:08200820FFFE0A2001007FFC08200820145022880100FFFE0100010001000100 +8404:0820FFFE082020003FFC48049FE422040204FFFC0204222422243FE400280010 +8405:0820FFFE08200100FFFE010021083FFA010200FE00003FF820083FF820083FF8 +8406:08200820FFFE0A2004003FF821083FF822083FF808801080FFFE008000800080 +8407:04400440FFFE04400FF808000FF008000FF00800FFFE111010A014401830100E +8408:08200820FFFE082000001FF010101FF010101FF010101FF00450084A1042603E +8409:08200820FFFE082000003EFC22A422A43EA422FC22803E80228222824A7E8400 +840A:08200820FFFE092001007FFC11101110292845440380054009203118C1060100 +840B:0820FFFE09207FFC01003FF80108FFFE01083FF80200FFFE08201C4003C07C38 +840C:08200820FFFE082000007CFC448444847CFC448444847CFC4504010402140C08 +840D:08200820FFFE0820200017FC904042484950084017FEE0402040204020400040 +840E:0820FFFE082000701F8001007FFC05401930E10E04007FFC08201C4003807C78 +840F:04400440FFFE044008001FE020204440B878200820083C78200820083FF82008 +8410:0820FFFE082001007FFC01003FF80108FFFE01083FF8110011F8290047FE8000 +8411:08200820FFFE092008801FFC108030805FF8908010801FF8108010801FFC1000 +8412:08200820FFFE0A2001007FFC08201210244808201FF00440044008441044603C +8413:08200820FFFE0A2001007FFE40029FF4101010101FF010101FF010101010FFFE +8414:04400440FFFE0440100011FCFC4410441494190832FCD0841084108450FC2084 +8415:0820FFFE0A2001007FFC0820044003801C70E82E0FE008200FE0082010202020 +8416:0820FFFE0820060038F8200820083CF8200820083FF80440044008423042C03E +8417:08200820FFFE0A2001007FFE400280041FF0000000007FFC1110210845040200 +8418:08200820FFFE0A2002007FFC0440082037D8C0063FF801000920111025080200 +8419:04400440FFFE044010201020FDFE11223224385054505490909011121212140E +841A:08200820FFFE0820100011FC1088FC70138E10201DFC3020D3FE102050202020 +841B:08200820FFFE08203FF820083FF820083FF820083FF80820FFFE082010202020 +841C:04400440FFFE044010201020FE3E9220922092FC92849A849484108410FC1084 +841D:0820FFFE082000003FF8244824483FF8020007F008103420024001800E007000 +841E:08200820FFFE082000003FF8210822882448000020843E9820E020842684387C +841F:08200820FFFE08200640384009F808487E4818C81C482A68289A488A09060A02 +8420:08200820FFFE082000003E7C224422443E7C224422443E7C224422444A948508 +8421:04400440FFFE04400020104009FC49042104250405FC09047104110411FC1104 +8422:08200820FFFE08202100110013F884084BE85228122823E8E2182204220421FC +8423:08200820FFFE0A2001007FFE400280041FF00100110011F81100290047FE8000 +8424:08200820FFFE082000007FFE410281041FF0111011101FF0010001087FFC0004 +8425:08200820FFFE08207FFE40029FF4101010101FF000003FF8200820083FF82008 +8426:08200820FFFE082000007FFE440288441F8003200C103FF80108112025104208 +8427:08200820FFFE082001003FF80108FFFE01083FF8010025482528292841088108 +8428:04400440FFFE044000207DFC4488485051FE4900450045005500490042004400 +8429:04400440FFFE04400C20702010A410A4FCA83120382054505050908811041202 +842A:08200820FFFE08200C10709010501010FC903050381E55F05010901010101010 +842B:0820FFFE082000F83F000100FFFE054009203118DFF610101FF010101FF01010 +842C:04400440FFFE04401FF011101FF011101FF001003FF8210821482FE824282010 +842D:08200820FFFE082000F03F0001001FF011101FF001007FFC412441F45E144008 +842E:08200820FFFE092002800C6037D8C0063E0822483E4822483E48220822282610 +842F:0820FFFE082004000FE010203FF850081FF810081FF810081FF8042008101008 +8430:08200820FFFE092001007FFC01003FF8292825483FF8038005601918E1060100 +8431:08200820FFFE0A2001007FFE40029FF400001FF010101FF010101FF00000FFFE +8432:08200820FFFE082000FC7F00220811103FF80200FFFE04000FF0122021C0CE3C +8433:08200820FFFE08200100FFFE01003FF8244822882FE821083FF8210821282010 +8434:0820FFFE08203F04210421243F2421243F24212421243F240024120421144088 +8435:04400440FFFE04401FF010101F9010907FFC40044FE4482448244FE440144008 +8436:0820FFFE082001007FFC01003FF80200FFFE08201FF02828CFE608200FE00820 +8437:04400440FFFE0440080049042A247F2441247F2441247F244124410445144208 +8438:08200820FFFE082005003978210821083D78210821083FF8028004401830E00E +8439:08200820FFFE092000803FFC20043FFC20002FFC292429242FFC49244924880C +843A:0820FFFE08207FFC40045FF440045FF400001FF010101FF010101FF010101FF0 +843B:08200820FFFE0A2001003FF808200440FFFE00001FF010101FF010101FF01010 +843C:0820FFFE082000003EF822883EF800003FF80000FFFE08000FF0001000A00040 +843D:08200820FFFE0820208010F811088290486049981606E1F82108210821F82108 +843E:0820FFFE082000003FE008200BF80A88112822905FF8124812481248FFFE0000 +843F:04400440FFFE0440203813C01040804047FC5040104023F8E208220823F82208 +8440:04400440FFFE0440103813C0FC40104017FC18403040D3F81208120853F82208 +8441:0440FFFE0440082004407FFC01003FF80100FFFE0200FFFE08201C4003C03C38 +8442:04400440FFFE044020203E20442088FC7F24492449247F441454248A450283FE +8443:08200820FFFE082000807C8044FE454046407C7C44404440447E7C4044400040 +8444:08200820FFFE082000403E40227E22A03EA0233C22203E20223E22204A208420 +8445:04400440FFFE0440000011F81108290845F89108110829F82508410887FE0000 +8446:04400440FFFE044008000BF81208320853F8904017FE10E0115012481C461040 +8447:0440FFFE04401FF0022001407FFC0484188862800100FFFE05401930E10E0100 +8448:04400440FFFE144020087FFC00043FF820083FF80100FFFE054009203118C106 +8449:04400440FFFE044012207FFC122013E010001FF80100FFFE05401930E10E0100 +844A:08200820FFFE092006C01830EFEE00001FF010101FF00820FFFE082010202020 +844B:08200820FFFE082000803C8024FC25043EF4249424943CF42494240454288810 +844C:0820FFFE08200400FFFE08201E4003C03C381010FEFE2224646418182434C2C2 +844D:04400440FFFE04407FFC00001FF010101FF000003FF821083FF821083FF82008 +844E:08200820FFFE0820004013F8204847FE884813F8304053FC904017FE10401040 +844F:08200820FFFE0820204013F890484FFE404813F82040E3FC20402FFE20402040 +8450:08200820FFFE0820044008203018CFE6042018A060403FF8244824482448FFFE +8451:04400440FFFE0440080008087F0808FEFF08084808287F2808080F08F0284010 +8452:04400440FFFE04401000100025FC7C200820102024207E20002054204BFE8A00 +8453:08200820FFFE082008202090109013FC80904890489017FEE000209021082204 +8454:0820FFFE0820000009F00810101037FC510091F81240104017FC10A01110120C +8455:08200820FFFE08201200213C49009400247E6108A2082E082208220822282010 +8456:08200820FFFE0A2001007FFE48229114212801107FFC0280044008203018C006 +8457:0820FFFE082002083FD002200240FFFE03000C003FF0C8100FF008100FF00810 +8458:04400440FFFE044008881110FFFE1110088800003FF821083FF821083FF82008 +8459:04400440FFFE0440080008FC7E84088418FC1C842A842AFC4884888408FC0884 +845A:04400440FFFE044008207FFC08200FE008200FE00820FFFE1240142010001FF8 +845B:0820FFFE08201FF010101FF010101FF008001FFC21045284944410041FA80010 +845C:0440FFFE044008007F7C08243E2408447F5408880100FFFE02800C603018C006 +845D:04400440FFFE044000207F202A2054FC2A2400247E24082408440E44F0944108 +845E:0820FFFE082000007DFC048804887CF8408840887CF80488049E05E828081008 +845F:08200820FFFE092002001FF010101FF010101FF000007FFC01003FF80100FFFE +8460:04400440FFFE04400BF8080811F8300853F8900017FC140413F8111010E0171C +8461:04400440FFFE24403FFC42247FF482043FE422243FE422243FE4222422A4204C +8462:08200820FFFE092001007FFC04800A603118C0063FF8244824482448FFFE0000 +8463:0820FFFE08201FF001007FFC01001FF011101FF011101FF001003FF80100FFFE +8464:04400440FFFE04401008100824087DFE0808108824487E48000854084A288A10 +8465:04400440FFFE044010100820FFFE00003E4822483E4822483E0822082A282410 +8466:0820FFFE082002003FF00410FFFE00001FF010101FF001001FF021003FF80100 +8467:04400440FFFE044008107F1008107F7E41123E1204120F1278220822284A1084 +8468:04400440FFFE04401FF011101FF011101FF00000FFFE111010A014401830100E +8469:04400440FFFE0440100021FC7D244524452445247DFC4500450045027D0244FE +846A:04400440FFFE044010041F0422247FA4A4A43FA424A43FA424A4248442948108 +846B:04400440FFFE04400800087C7F440844087C3E442244227C22443E8422940108 +846C:0820FFFE0820FFFE10803E9842E024841884E07C08200820FFFE082010202020 +846D:0820FFFE082000007CF8440844087CF8400041F87C88405040207C5040884306 +846E:0820FFFE0820060038F8208820883D06220021F83C8820882C50F02020D82706 +846F:08200820FFFE082010401440247C7884110424447E24002454044A048A280010 +8470:04400440FFFE044009100A0817FC31105208948411F813081490106011981606 +8471:04400440FFFE044008001FF82A4844480A88110822A8041001004884481287F2 +8472:0820FFFE0A2004001FF010101FF010101FF001047D88095011202118C5060200 +8473:04400440FFFE0440002800243FFE20202FA422242FA824982D12422A45468882 +8474:04400440FFFE0440002800243FFE20202FA420242FA8289828924FAA40468082 +8475:0820FFFE082000907EA00444282810102FE8C10601007FFC010002C00C307008 +8476:0820FFFE09207FFC00001FF010101FF000007FFE40029FF40100010005000200 +8477:0820FFFE08207FFC41043FF801001FF011101FF011101FF00100FFFE01000100 +8478:0820FFFE082000003FF8210821083FF8210821083FF802005104511290120FF0 +8479:08200820FFFE082020401040FEFE212020AC3CB425E424AC24A044A25482887E +847A:0820FFFE08201FF010101FF000007FFC10101FF010101FF0103EFFD000100010 +847B:04400440FFFE044000001FF0101010D01710111017D0155027CA212A4FE68022 +847C:08200820FFFE08202448238824483FF81010220847E40820144003801C70E00E +847D:08200820FFFE08207FFC04403FF824483FF80400FFFE08201C4003800C703008 +847E:08200820FFFE082010001EF8228862A894920882307EC10008844892481287F0 +847F:08200820FFFE08203FF821083FF820002FF828082FF828084FF848088FF80808 +8480:04400440FFFE04401FF010101FF010101FF000003FF8244824482448FFFE0000 +8481:08200820FFFE08202050104817FC00C00160F150124814441040280047FE0000 +8482:0820FFFE0A2001003FF8082004407FFE410281041FF011101150112001000100 +8483:0440FFFE044008000FE010201FC00040FFFE06003B0804B019C062A00C987306 +8484:08200820FFFE08207FFE400280043E0800087EFE14481428140A242A241243FE +8485:0440FFFE04401080088043F0289011127212140E1100FFFE05401930E10E0100 +8486:0820FFFE082000007DF0111011901D52F20E0400FFFE08201C4003800C707008 +8487:04400440FFFE044800243FFE20202FA428A42AA82AA82A902A92452A49469082 +8488:04400440FFFE044020883C9020E42C84307C04001FF010101FF010101FF01010 +8489:0820FFFE082001001FF011101FF00100FFFE00001FF01010111002C00C307008 +848A:04400440FFFE04400880109830E057849084107C00007C8844B044C47C84447C +848B:08200820FFFE0820008008F849102AA0285008901BFE29104890889008100830 +848C:04400440FFFE0440111009207FFC05401930610C0400FFFE08201E4003C03C38 +848D:0820FFFE0820240014007FE0042008200FF8080810081FFE2002255249548008 +848E:04400440FFFE0440201C13E0920E42F04A900A901292E2942288248824A428C2 +848F:08200820FFFE08207FFE4002BFF404803FF82488287830083FF820083FF82008 +8490:08200820FFFE0A2004003FF821083FF821083FF8029002A804B8088A3082C07E +8491:0820FFFE08200600387820483E4822863F0022FC3E4420443E2822104A2884C6 +8492:0440FFFE0440100023FE7C20442045FC7D2441247D24452445347D2844200020 +8493:04400440FFFE04401020102025FE7C200924112425247DFC002254225422801E +8494:08200820FFFE0820004078404BFC48404FFE78104FFE48104A10791048500020 +8495:04400440FFFE04401FF01110129014501FF000003FF8244824482448FFFE0000 +8496:0820FFFE09207FFC01001FF010101FF010101FF010101FF01010FFFE08201010 +8497:08200820FFFE08A0204013F8920843F84A080BF81242E2442228229023082206 +8498:0440FFFE044008007F7C114432440C7C3220DFC001003FF801007FFC01000300 +8499:0820FFFE08207FFE40028FE400007FFC06003B0804B019C062A00C9872860100 +849A:0820FFFE082000007FFC00001FF010101FF000007FFC482444445FF44104410C +849B:04400440FFFE0440202020203DFC50241024FC2411FE542054505C5074880506 +849C:08200820FFFE082000007C7C00000000FEFE1010101054545252929250502020 +849D:0440FFFE044000003FFC2080210027F0241027F0241027F0408044908A881104 +849E:08200820FFFE082021401120120082FC46005A8812482248E250220022FC2200 +849F:08200820FFFE08202080108010FCFD0402F44894489448F410941E04F0284010 +84A0:0820FFFE082002003FF820083FF820083FF820083FF8010008844892481287F0 +84A1:0820FFFE082001003FF8082004407FFE420281043FF8040007F0081010502020 +84A2:08200820FFFE0820784048A05110620855F648404BFC68405150424845444080 +84A3:08200820FFFE0820104020A041108A0815F6304053FC90401150124815441080 +84A4:08200820FFFE0820204010A0911042084DF6104027FCE0402248244429422080 +84A5:08200820FFFE0820040079FC40444844545462883FF821083FF821083FF82008 +84A6:0440FFFE044008801FFC30805FF890801FF810801FFC10003FF00C6003807C7C +84A7:04400440FFFE0440002800243FFE222023A422242FA8289828924FAA40468082 +84A8:0440FFFE044013F8104023F820406FFEA00023F8220823F8220823F822082218 +84A9:08200820FFFE08200C0071F811081108FDF83108390855F85108910817FE1000 +84AA:0820FFFE092001107FFC01003FF821083FF821083FF821080020FFFE08200460 +84AB:0440FFFE0440082004407FFC01003FF80200FFFE080017F8208040809FFC0000 +84AC:08200820FFFE08207FFE44028FE410203FF8510811081FF802800492188AE07E +84AD:0820FFFE082010001FFC210451141FF4020814001FFC210451141FF404143808 +84AE:08200820FFFE082004007FFC450408801FFC30805FF810801FF810801FFC1000 +84AF:11021102FFE2110A000A7BCA4A4A4A4A7BCA4A4A4A4A7BCA4A424A42AB4A1484 +84B0:08200820FFFE082010783E4822482A862300FEFC22442A44222842104A2884C6 +84B1:04400440FFFE044010281024FDFE102015FC192431FCD12411FC11245124210C +84B2:08200820FFFE0828404427FE204087FC444457FC1444E7FC2444244424540408 +84B3:04400440FFFE04401020102025FC7D2409241154254C7D840104550455148108 +84B4:08200820FFFE08204100227CFFC40844497C494449447F7C1144204440948108 +84B5:0440FFFE044000387FC02208151008401F8001201FF002107FFC04401830E00E +84B6:04400440FFFE04401010109024887D040A0211F824487C480088548855288210 +84B7:0820FFFE08201FF010101FF000003FF820083FF820083FF820083FF808201010 +84B8:08200820FFFE08201FC000447D88055009203118C50602003FF8000024884244 +84B9:0820FFFE082010100820FFFE04403FF80448FFFE04483FF80C603458C4460440 +84BA:0820FFFE092000801FFC1000920053F8544010403FFE504090A0211022084C06 +84BB:08200820FFFE082000007EFC02047EFC40807EFC020422441A3462C414280810 +84BC:08200820FFFE092006C01A30E10E1FF010101FF010101FF010002FF848088FF8 +84BD:0820FFFE082000003FF821082FE82288244828283FF8010008844892481287F0 +84BE:08200820FFFE08202040124811500040F7FC10E01150124814441040280047FE +84BF:0820FFFE08200200FFFE00001FF010101FF000007FFC40044FE448244FE4400C +84C0:04400440FFFE0440000C7DF00440088811F010201C44F3FE1022112452222060 +84C1:0820FFFE082001007FFC01003FF80200FFFE082017D02108DFF6054009201110 +84C2:08200820FFFE08207FFE40029FF410101FF010101FF00100FFFE082010102008 +84C3:0820FFFE08200500397821083D7821083FF801003FF00820044003801C70E00E +84C4:0820FFFE08200100FFFE08201FC003100C083FFC00043FF821083FF821083FF8 +84C5:04400440FFFE0440202017FE1080810843FC500411502150E15022522252244E +84C6:0820FFFE092000803FFC222022203FFC222023E020802FF8488848A888900080 +84C7:0820FFFE08201FF010101F9010907FFE40029FF410101FF010101FF010101030 +84C8:08200820FFFE082004003F7C21443F4821503F48284424442A54324820400040 +84C9:08200820FFFE0A2001007FFE400289241290244808203FF8C82608200FE00820 +84CA:0820FFFE0820044008203218C4460FE000207EFC224412240A1412242A544488 +84CB:0820FFFE082001003FF801007FFC080010103FF800003FF824482448FFFE0000 +84CC:0440FFFE04401110111029287FFC0100FFFE08001FF02820444003801C70E00E +84CD:0820FFFE0A203FC00280FFFE02200FC03408C3F800001FF010101FF010101FF0 +84CE:0820FFFE092000803FFC20802FF820883FFE20882FF820804FF848088FF80808 +84CF:08200820FFFE08200000061C38E828A82CA82AA82AA82AA828A455545D748212 +84D0:0820FFFE08203FFC20002FF820003FFC24482430260E20205FFC442082A00040 +84D1:0820FFFE082001007FFC00001FF01010FFFE10101FF0048808503820CB180C06 +84D2:04400440FFFE044008007F7C08107F1049107F1049FE7F100810FF9008100810 +84D3:08200820FFFE08A0104017FC20006208A1102FFE200023F82208220823F82208 +84D4:04400440FFFE0440082004407FFC010001003FF801000100FFFE248822444244 +84D5:04400440FFFE04401020102011FCFC20102033FE3800542051FC9020102013FE +84D6:0820FFFE082002003FF82448238824483FF8000020843E9820E020842684387C +84D7:08200820FFFE0820104023F84040884017FC3040524092781240154018FE1000 +84D8:0820FFFE0A2001007FFC08201210244848241FF00510088818502920CA180C06 +84D9:08200820FFFE092000803FFE2080249024902AA831C420802FF8408040809FFE +84DA:08200820FFFE0820108011FC228828706B8EA8202848299028642988203021C0 +84DB:04400440FFFE044008200820FFBE08447FA449244B281C282A10492888440882 +84DC:08200820FFFE08207F7C140414047F04557C574061407F40414241427F3E4100 +84DD:08200820FFFE08200480248024FC24A0251000003FF8244824482448FFFE0000 +84DE:08200820FFFE082000FC7F00220811100C20307820083C78200820083FF82008 +84DF:04400440FFFE044010041F0422247FA4A4A43FA424A43FA40004078478142008 +84E0:08200820FFFE09200080FFFE0440139014501FF001007FFC44444FE44424400C +84E1:08200820FFFE082023F8100811F8800843F8500017FC2404E3F8211020E0271C +84E2:04400440FFFE144008003E7C22443E44227C3E442244287C24442A4432942108 +84E3:0820FFFE082000007DFC0420284011FCFD041524112411241124105050882304 +84E4:08200820FFFE0820404023F820400FFE1110128824F4E11022A0204021B02E0E +84E5:08200820FFFE082000007FFE410282840C603018DFF601003FF8111009207FFC +84E6:0440FFFE04401FF010101FF01010FFFE10102FC8C04608400FF800087FA80010 +84E7:08200820FFFE0820108011F822886870ABAE282029FC282028A8292422A42040 +84E8:0440FFFE0440108011FC228828706B8EA80029FC290429FC290429FC2104210C +84E9:0820FFFE082000807CF805082A901060FD981606304053F89048108851502620 +84EA:08200820FFFE082047F8211020A007FCE44427FC244427FC2444245454088FFE +84EB:0820FFFE082023FC10801144066870B01128166810A4112416A0284047FE0000 +84EC:0820FFFE0820010023F0151010E0071C704013F8104011F0104017FC284047FE +84ED:0820FFFE092000803FFC20803FFC222024902FF8349427F0249047F24082807E +84EE:0820FFFE0820004027FC104013F8024873F8124813F8104017FC284047FE0000 +84EF:04400440FFFE04401110211041108AA8144430405240927C1240154014FE1800 +84F0:04400440FFFE04401020213C4120892017FE300050209120113E112012A0147E +84F1:08200820FFFE08202108109093FC40904890089017FEE0902090211021100210 +84F2:0820FFFE082000003FF8200027F0241027F020002F7829482F7820003FFC0000 +84F3:0440FFFE044008207FFC08200FE001003FF821083FF801007FFC0100FFFE0000 +84F4:0820FFFE09207FFC01003FF821083FF821083FF801047FFC0020FFFE08200460 +84F5:04400440FFFE0440102013FE1020FDFC102413FE1C24F1FC1020113C512022FE +84F6:04400440FFFE044000A0009079FE49204B204DFC492049FC7920492001FE0100 +84F7:04400440FFFE044010A01090F9FE11201B2015FC3120D1FC1120112051FE2100 +84F8:0440FFFE04407FFC04403FF824483FF824483FF800001FF010101FF010101FF0 +84F9:04400440FFFE0440140027DE4912811217D221126112A5D2251A25D42E102410 +84FA:08200820FFFE0820104010407C4010F8FE48444892C87C4810AA1CAAE1064202 +84FB:08200820FFFE0820104010407C4011F8FE48444828C87C4810AAFEAA11061202 +84FC:0820FFFE08203CF824481428254806C01830E30E0C403180063038C007003800 +84FD:0820FFFE08203FF821083FF821083FF80920FFFE09203FF801007FFC01000100 +84FE:08200820FFFE092001FC01003FF829282448228829282288244829283FF82008 +84FF:0820FFFE082001007FFE48028BF4108033F85208920813F81208120813F81208 +8500:04400440FFFE04401000087C7F4422481450FFC800443E44225422483E402240 +8501:0820FFFE09203FF80440FFFE00001FF010101FF010101FF00100FFFE01000100 +8502:0820FFFE08201FF011101FF011101FF0040008201FC003103FF8112025104208 +8503:08200820FFFE08207CF8048804F87C2041FC41247D2405FC042004242BFE1002 +8504:08200820FFFE08207C7C44447C7C44447C7C40044FE4482448244FE440144008 +8505:0820FFFE08207C7C44447C7C44447C7C41044FF442444644418442444C24400C +8506:08200820FFFE0820204013F8104087FE4110528814F42110E2A0204021B02E0E +8507:08200820FFFE082000007DFC44207D20452045FE7C50505048925492610E4200 +8508:0820FFFE082000007FFC04403FF824483FF800003FF80000FFFE111025080200 +8509:0820FFFE08200100FFFE101020085FF4101010101FF0048808503820CB180C06 +850A:04400440FFFE044011FC110415FC550459FC500091FC10202BFE242044208020 +850B:08200820FFFE0820220013BE921242125FD210142214EA88324822142A242442 +850C:0820FFFE082000000820FFA0083E7F42499449107F101C102A28492888440882 +850D:08200820FFFE092000803FFE22203FFC22243FFC284028482F7048444B448C3C +850E:04400440FFFE244010F8FC8800887906020079F8008878884850482078D84B06 +850F:0820FFFE0A2001007FFC082004407FFC4444482457D4644C444447C440144008 +8510:0820FFFE0A2001007FFC082004407FFC41045FF441044FE448244FE44004400C +8511:0820FFFE082000003FF8244824483FF800903FFC208030482850242440D4830C +8512:0820FFFE082000003FF80208FFFE04083FF808001FF82808CFF8000024444222 +8513:0820FFFE08201FF010101FF010107FFC44447FFC00003FF0082007C01830E00E +8514:0820FFFE28203FFC4004BFE400041FC410441FC400043FE422243FE422243FEC +8515:0820FFFE0820145014507FFC245247CE80007FFC41041FF01110115011200100 +8516:0820FFFE092001F801003FFC21042FE0210827F8241027F0241047F044109FFC +8517:08200820FFFE092000803FFC222022203FFC2220222023E020004A4849249124 +8518:0440FFFE044008201FF0102025487EFC04401930E64E1990062018C007003800 +8519:08200820FFFE082020401040FEFE210020003DFE2422242024BC44A055608A3E +851A:08200820FFFE082000003F0821083F0820FE2E0820483F2844285508A4A80C10 +851B:08200820FFFE082010041F2422147F84A4A43F9424863FBC2484248442848104 +851C:04400440FFFE0440082008207F3E08443EA40824FF2810281E1022284A448482 +851D:04400440FFFE04400020792448A848207BFE487078A848A849247A2248200020 +851E:0820FFFE082001003FF82108FFFE21083FF811101FF00400FFFE082007C07838 +851F:08200820FFFE082020401040FEFE212020403CFC2520242025FE445054888906 +8520:08200820FFFE0820104010FC24887D50082010D827067C60001054C054308008 +8521:0440FFFE044010801EF822885450282017D82006DFF001001110210845040200 +8522:0440FFFE0440202013FC82244BF812882450E470298C2400FFFE082007C07838 +8523:08200820FFFE08200440247C24A83D50042804487DFE24882448244844088418 +8524:0820FFFE0A2001007FFE42028924284849940E1077F00100210821083FF80008 +8525:08200820FFFE092002003FF8220827E82A48218826483FF801004884481287F2 +8526:0820FFFE082004001FF010101FF010101FF010001FFC10001FFC492484940008 +8527:0820FFFE08201010FEFE10107C7C1010FEFE10103FF800081FF800083FF80008 +8528:0820FFFE08207FFC45445FF442047FFC482457D4644C44C4442443E440047FFC +8529:0820FFFE0A2001007FFE4002BFFC01003FF821083FF821083FF8101020084004 +852A:04400440FFFE044008067F7808407F40497E7F4849487F4808487F4808880908 +852B:0820FFFE08207FFC010011F81100FFFE10001FF820003FFC0004492484940008 +852C:0820FFFE082000107DFE0420184851FE50025CA850A850A85D2A712AC22A0406 +852D:0820FFFE0820004078A04910524865F4502048404BF8680057FC4080411043F8 +852E:04400440FFFE04407FFC40A47FFC40845E9452945E64405446B459147FFC4004 +852F:04400440FFFE044000207BFE482051FC612451FC492449FC687050A841244622 +8530:0820FFFE09203FF820083FF8200027F0241027F020002FF828884FF8480287FE +8531:0820FFFE082022001478084814482A8609007EFC08442A4449288910282810C6 +8532:0820FFFE0A2001007FFE400280443E40007C7E88155014201452248A43FE8000 +8533:0440FFFE044023F8104013F8804047FE500013F82208E3F8220823F822082218 +8534:08200820FFFE092000803FFC242024203F7C24202E702D6834A4452244208420 +8535:04400440FFFE044800243FFE20202FA42A242FA828A82F902A124FAA40468082 +8536:0820FFFE09207FFC01003FF80100FFFE10101FF010101FF010101FF008201010 +8537:0820FFFE082001003FF811100920FFFE00003FF8200827C8244827C820083FF8 +8538:08200820FFFE0920120067DC444447C4444457DC60000440044008421042603E +8539:04400440FFFE044008200820143E22445DA48024112809284A1027A8F8444082 +853A:0820FFFE0820200017FC050444844FF459046FE449044FE449044FF448144008 +853B:0820FFFE0A2001007FFE400280243E3800207EF81408145014242454248443FC +853C:0820FFFE082043F8220823F80208E3F8210023FC244422A42A0433F420140008 +853D:04400440FFFE0440082049202A3E7F4449A449245D286B284910412845444282 +853E:0820FFFE08200640387C08947E241C442A9449080100FFFE054009203118C106 +853F:0820FFFE082000F87F00221011201FE010201FF010101FFC20042AA44AA4800C +8540:0440FFFE044010101010FEFE1010FEFE92929292969638385454929210101010 +8541:0820FFFE08203FF000101FF000103FF000003E7C08447F7C0020FFFE08200460 +8542:0440FFFE044000203D2424A825FC3C4027FE24883D2426FA2448444854A88910 +8543:0820FFFE082000F83F0011100920FFFE09203018DFF611101FF011101FF01010 +8544:0820FFFE08207C7C44447C7C44447C7C410440844AA44A144A5451C440144008 +8545:08200820FFFE082023F8124893F842484BF8084017FCE444245425F42414040C +8546:04400440FFFE044800243FFE20202FA428A42FA828A82F9028924FAA45468882 +8547:0820FFFE08203EF822883EF800001FF011101FF011101FF00100FFFE01000100 +8548:0820FFFE08207FFC04403FF824483FF810101FF010101FF00100FFFE01000100 +8549:08200820FFFE092008801FFC30805FF810801FF810801FFC1000248822444244 +854A:08200820FFFE0820082001002488242443E4000024241212A0A0A4A41C1C0000 +854B:0820FFFE0820010011F811001100FFFE081008104E9C489048904E90F1FE0000 +854C:04400440FFFE04401FF010101FF010101FF000007EFC42847EFC42847EFC4284 +854D:0440FFFE044020A01110120885F64000578414A427A4E4A427A4248424942588 +854E:0820FFFE082000701F800200FFFE082037D8C4463FF8200827C8244827C82018 +854F:08200820FFFE0820004453F42048505097FE108031FC530495FC190451FC2104 +8550:0440FFFE04407FFC1110292845441110292845447FFC0100FFFE010001000100 +8551:0820FFFE08207C7C44447C7C44447C7C400447C4444447C4444447C4445448C8 +8552:0820FFFE08203FF824483FF800001FF010101FF010101FF010101FF008201010 +8553:0820FFFE08203FF801007FFE41029D7401001D7000003FF80000FFFE10103FF8 +8554:0440FFFE0440100010FC7C841094FE88448028FC7CA410A4FEA8109010A810C6 +8555:08200820FFFE0820228814500BFE145025FC4D54158C250445FC850429FC1104 +8556:0820FFFE082023FC120043F82A080BF8720013FC1100FFFE05401930E10E0100 +8557:08200820FFFE0820008078F849084A907860119812065DF8510851085DF8E108 +8558:0820FFFE082001003FF80100FFFE08203EF808207EFC00007FFC04401842E03E +8559:0820FFFE09203FF801001FF011101FF011101FF001087FFC02044908482487E4 +855A:0820FFFE08201FF010107FFC44447C7C00003FF80000FFFE10001FF800080070 +855B:08200820FFFE08200C88705011FC1024FDFC312039FE546250AA912412201020 +855C:08200820FFFE082004407C7C04403C7804407C7C0440020009084924482487E0 +855D:04400440FFFE0440108010F825087E1009FC112425247DFC01005502550280FE +855E:0820FFFE08201FF010101FF01010FFFE22003EFC22443E4422282F10F22842C6 +855F:0820FFFE08A03E900464282810103EF8C2961E90110C20F03E90026014900908 +8560:0440FFFE044008007F7C114432440C44367CC8801F0002103FF8010815202210 +8561:0440FFFE05407FFC0920FFFE08203FF820083FF820083FF820083FF808201010 +8562:0820FFFE09201FF011101FF00100FFFE10101FF010101FF010101FF008201010 +8563:0820FFFE082000FC7F00220811107FFE400290243DF84420A92011FC2020C020 +8564:0820FFFE08200010FF50107C29904E10967C2510CD1014FE2440C430140E0800 +8565:0820FFFE082000507E4804FE2490259044FE7E900C9014FE2490449094FE0880 +8566:0820FFFE082000000BFE102021FC490411FC210445FC090411FC2000C0880104 +8567:0820FFFE0820020013FC240043F88A0813F8320853F8910013F8151010E0171C +8568:0820FFFE082000003FFE289025102FBE22222AD42A902F902228442844448882 +8569:08200820FFFE082023F8120893F8420843F810002FFEE20027FC292422540488 +856A:04400440FFFE044010003FFC4AA00AA07FFC0AA00AA07FFC0000248822444244 +856B:0820FFFE09201FF004407FFC00001FF011101FF011101FF001003FF80100FFFE +856C:04400440FFFE04401020102024407C8809F0102024487DFC002054A855248060 +856D:0820FFFE09203FF80108FFFE01083FF825483D7821083FF821083D7825484548 +856E:0820FFFE082002001CF010101EF010101FF008001FFC20044924249424944008 +856F:0820FFFE0820010079F04A9050606198560649F04A406BF8544043F8404047FC +8570:04400440FFFE044023F8120893F842084BF8080017FCE524252425242FFE0000 +8571:04400440FFFE04400C20712410A81020FDFC310439FC550451FC910411141108 +8572:0820FFFE0820220C14707F4049407F40497E7F480848FF480848088808880908 +8573:08200820FFFE08207C7C44447C7C44447C7C40044FE448244FE448244FE4400C +8574:04400440FFFE044021F8210845F88908F1F8200043FCFA9402941A94E7FE4000 +8575:0440FFFE0440204020A021583A264DF8490849F8A90811F81144212841508188 +8576:0820FFFE08203FF801007FFE41029D7401001D7006C01930EFEE004006800100 +8577:0820FFFE082000007DFE042028FC1084FEFC128414FC108410FC100050482084 +8578:0820FFFE0820000047BC248427BC0400E7BC240427A82410242854448FFE0000 +8579:0820FFFE0A200100FFFE10A0209045FE7B2011FC25207DFC0920112021FEC100 +857A:0440FFFE04403E2822243E240020FFFE22203E2822283E1022122F2AF2464282 +857B:08200820FFFE082000483E4820483CFC20483C482048FEFE20004448FE844302 +857C:0440FFFE044000203EFC20243DFE20243CFC2020FEFC102025FE7E2022200020 +857D:0820FFFE082002401FF812481FF812483FFC20002FF820003FFE24484530860E +857E:0820FFFE08203FF801007FFE41029D7401001D7000003FF821083FF821083FF8 +857F:0440FFFE0440101E13E0152254945BFC504097FE108011FC2A48243044488186 +8580:08200820FFFE082023F81248924842A84BF8080017FCE4A424A424A42FFE0000 +8581:0820FFFE082004003FF8292825482FE8254828280100FFFE02800C603018C006 +8582:0820FFFE082010003E2022203E3E22443EA408247F2810281E1022282A444482 +8583:0440FFFE0440202017FE100081F8410851F8100027FEE40225FA250A25FA2406 +8584:0820FFFE0820004827FC104013F8824843F84A480BF81248F01027FC22102130 +8585:0820FFFE082023FE2200FAFC4A004BFE4AA4929852C6220853FE4A8884480818 +8586:0820FFFE082000F87F00221011207FFC4204292847E408001FF0282007C0F83E +8587:04400440FFFE044022204AA08ABE1FC420A46F24A0282F28291029A829443082 +8588:0820FFFE092002800C6037D8C0063FF829283FF800001FF010101FF010101FF0 +8589:0820FFFE092011F81100FFFE00243FFE20202FA422242A182A90512A46469882 +858A:04400440FFFE044010041F0422247FA4A4A43FA424A43FA400042A8445540008 +858B:0820FFFE492021FC0A44F0B0230E3FF010101FF010101FF010101FF008201010 +858C:08200820FFFE0820210027DE545297D4E458245457D29512F49A255446108410 +858D:0440FFFE04407F102A107F1012100C107F904A905E9040905E924A9244924B8E +858E:0820FFFE08207FFC44447FFC00007FFE4922911431FC5F1090A0104411A4161C +858F:0820FFFE082001003FF80820FFFE00001FF010101FF010101FF04904489287F2 +8590:04400440FFFE04400C2071FC102013FEFC8831443A7A54885150902010D81706 +8591:0820FFFE08207FFC00003FF821083FF82108FFFE00003FF821083FF82108FFFE +8592:0440FFFE044008000F7828087F28A110162838C4D11009207FFC05401930610C +8593:0820FFFE082023F8100813F8800847FC544413F82248E04027F8211020E02F1E +8594:0820FFFE09207FFC111029284544FFFE00003FF8200827C8244827C820083FF8 +8595:0820FFFE082001003FFC22203FFC22402FF822483FFC22482FF846604A50B24C +8596:08200820FFFE082021F8110811E8012873FC120412F4129412F412142A0847FE +8597:0820FFFE08207FFC41044FE441045FF440044FE448244FE446944A6452147FFC +8598:0820FFFE0820004023F8104017FC0110F7FC104013F8104017FC1040284047FE +8599:04400440FFFE044020A020907DFE9120132011FCFD2011FC2920252041FE8100 +859A:0820FFFE082000FC7E8410FC10843CFC240047FEA48019FE0A521092212A4044 +859B:08200820FFFE082010407C2045FC44887C5043FE40207C2045FC44207C204420 +859C:0820FFFE082000403E2022FC22883E5021FE20203E2052FC52209E2012200020 +859D:0820FFFE08201FF020207FFEA4882BF4200027F8200027F8200047F8440887F8 +859E:0820FFFE082000407EA0119812463DF8250845F8A50819F80944112821904108 +859F:08200820FFFE092002800440183067CC00003EF8228822883EF8082014502288 +85A0:08200820FFFE082013FC104015F8550859F8510891F8110829F8249045088204 +85A1:0820FFFE08201FF010101FF010105FF450145FF440047C7C0440FC7C24444444 +85A2:04400440FFFE044020FC3C244444BE8C2A503E7C2A903E102AFE2A1042108610 +85A3:0440FFFE04400810FF1008FE7E1000107EFE42427E44422824100E28F0444182 +85A4:0820FFFE082000507E5011DC10503C5025DC6450945009DC0850105023FE4000 +85A5:0820FFFE08203FF824483FF808001FFC2204DFC412441FC402243FE410280010 +85A6:0820FFFE09203FFC24403FF824483FF8240027FC28002FFC20044AA451548008 +85A7:0820FFFE09207FFC00001FF010107FFE4002BFF408401F48625014621842E03E +85A8:0820FFFE08207FFC44447FFC00007FFE4002BFF408401F48625014621842E03E +85A9:0440FFFE0440002079FC4888505063FE52204AA04AFC6B2052FC4420442049FE +85AA:0820FFFE0820100008047F7822401440FF7E08487F4808482A484988A8881108 +85AB:0820FFFE08203FF80100FFFE11101FF011101FF001003FF80100FFFE24884244 +85AC:0820FFFE0920020047C4244817D0244847C40100FFFE054009203118C1060100 +85AD:0440FFFE044000200C4071FC112411FCFD4431FC3850549051FE901010101010 +85AE:0440FFFE0440000049202A20FF3E2A4449A41024FE282228641018282444C282 +85AF:0820FFFE08203FF824483FF802001FD00220FFFE03000FF03810CFF008100FF0 +85B0:0820FFFE08203FF80100FFFE01003FF829283FF801003FF80100FFFE24484224 +85B1:08200820FFFE0820140855083608147E7F0814487F2808283E0808080F287810 +85B2:0820FFFE09207FFE40029FF4092011C006001FF868080FF808080FF804100808 +85B3:0820FFFE0820004023F8104017FC000073F8120813F810C411A812902C8847FE +85B4:0820FFFE09207FFC4204A92847E400003FF82448FFFE00007FFC010005000200 +85B5:0820FFFE09207FFC01003FF80000FFFE00023FF00100FFFE00107DFC44907C30 +85B6:0440FFFE0440080031FCCB242D2431FCC924152425FCCC2015FC2420D4200BFE +85B7:0820FFFE08203FF801007FFE41029D7401001D7000007FFC02003FF824482458 +85B8:0820FFFE0820200017FC10A087FC44A457FC100027FCE0002FFE2040224824C4 +85B9:0820FFFE0920FFFE01003FF800001FF010107FFE48229FF401003FF80100FFFE +85BA:0820FFFE08200100FFFE02887D7025484D6690101FF010101FF0101020104010 +85BB:0820FFFE082022481490124883F8424853F8124823F8E0402FFE215022482444 +85BC:0820FFFE09203FFC24403FF824483FF828402F7828442F3C20804FF840809FFC +85BD:0820FFFE082000007F7C14207F20553855287F48086808587F4A084A0F6AF046 +85BE:0820FFFE08207FFC111021087FFCB55A29283558210835582928355820082018 +85BF:08200820FFFE0820247C3A0422281E1020FE3E124850085E7F5014B0229E4100 +85C0:0440FFFE044008202AA44D28145022887FFE410291141120228004401830E00E +85C1:0820FFFE082001007FFC08200FE000007FFC48244FEC01007FFC05401930E10E +85C2:0820FFFE08207F00227C3E0422283E1023A8FE4403F87F04118863700D18F106 +85C3:0440FFFE044008207F2000203E3E22423E8400107F1041105D2855285D444382 +85C4:0440FFFE044008207FFC08200FE00820FFFE14502F8841241FF0011009201310 +85C5:0820FFFE08207FFC44447FFC0800FF8400247F2400247F2400247F0441147F08 +85C6:0820FFFE0A2001007FFE4442BFFC0440FFFE082031D8CF0601007FFC01000300 +85C7:04400440FFFE04400A0033B822083A38238820883AB82288FFFE082010102008 +85C8:0440FFFE04400020F7A490A89292F114920895F4F84293F89040F0A091100608 +85C9:08200820FFFE082010487CFC10487C4811FEFE0010FC388454FC948410FC1084 +85CA:0440FFFE044000200DFE7102110211FEFD0031FE39AA56AA52FE94AA10A21086 +85CB:0820FFFE08203EF812480A28124808801FFC30805FF890801FF810801FFC1000 +85CC:0820FFFE0A2001007FFC42442B904C2837E0C1001FF011101FF001087FFC2004 +85CD:0820FFFE082000003F2024203F3E21403F5024883F0800003FF824482448FFFE +85CE:0820FFFE09203FF80108FFFE01083FF801007FFC248842443FF824482448FFFE +85CF:0440FFFE044800241FFE502057A0752417A4F4A857A85510951227AA20464082 +85D0:0820FFFE082008103020CAFC2C843084C8FC14842484CCFC1448244AD48A0906 +85D1:0440FFFE14401FE020207FF8A30824881FF011101FF008001FF0282007C0F83E +85D2:08200820FFFE08200DFC710411FC1104FDFC308039FE56225552910211FA1006 +85D3:08200820FFFE082020443E2844FEFF1049107F7C49107F1000FE0F10F0104010 +85D4:0820FFFE0A207FFC4104BFF8044028281FF02828CFE608200FE0010015102208 +85D5:0820FFFE0820100011FC7D2411FC7D2411FCFC2013FE3A22562A92FA120A1206 +85D6:0820FFFE08203F7C24443F2821103F2824463FF010101FF010101FF008201010 +85D7:0440FFFE044042102F9022100F9E0AA2EA882F88220827142A94322252428FFE +85D8:0820FFFE092001F801003FFC21042FE0210827F8249027F0249047F44A4A93FA +85D9:0440FFFE0440100008787F48224814867F0010FC694416446D281490642818C6 +85DA:0820FFFE09207FFC01003FF824483FF810101FF010101FF010101FF008201010 +85DB:0820FFFE0A2001007FFE42029CF410101EF010101FF008001FFC20040AA412AC +85DC:0820FFFE08200640387C08947E241C442A94490802C01D30E92E054009201310 +85DD:0820FFFE08203E2008F87F282A285D6A082A3E5600823FF80000FFFE10103FF8 +85DE:0820FFFE082000007FFC08001FF02810CFF000007EFE20407EFCA3443E7C2244 +85DF:04400440FFFE04403FF821083FF821083FF80000FEFE9292FEFE9292FEFE8282 +85E0:0820FFFE092002001FF010101FF010101FF020407EFC42847EFC42847EFC4284 +85E1:0820FFFE08A0404027FC211000A007FCE44427FC244425F4251425F4540C8FFE +85E2:04400440FFFE044022204AA08ABE1FC420A46F24A0282FA822102FA822442F82 +85E3:0820FFFE08207FFC44447FFC24987EE000847E7C42007E9842E07E844284467C +85E4:0440FFFE044000203D2424A825FC3C4027FE24883D2426AA247044A855248A62 +85E5:04400440FFFE044021104BA472B823904AA47BBC0100FFFE05401930E10E0100 +85E6:0820FFFE08A03FFE24103F7C26382D5434122FF8208027F820805FFE40808180 +85E7:04400440FFFE0440103C13C025447CA809FC104027FE7C8000F85548563080CE +85E8:08200820FFFE09203FFC24403FF824483FF828402F7828442F3C40004A489124 +85E9:0820FFFE0820203817C01248815047FC524814042BFAE24823F8224823F82208 +85EA:0440FFFE044008007F204920FFBE49447FA42A243E281028FF1022281C446282 +85EB:0820FFFE0820000027FC10A017FC84A447FC520813F82208E3F8204027FC2040 +85EC:0820FFFE08207DFC452449FC482053FE490445FC450455FC490441FC40884104 +85ED:0820FFFE09207FFE5022A8143EF822083E0822F83E8022FCFE0412042228CE10 +85EE:0440FFFE044010A0109011FEFD2013FC312039FC552051FE900012A412521452 +85EF:0820FFFE08203F0821083F7E20082F4820285FA8440895282C900100489487F2 +85F0:0820FFFE08207784428462A454A469A414242224DD2408247F244A042F94F008 +85F1:08200820FFFE092000803FFC2100AFF868882FF86888AFF8215042F84C8AB07E +85F2:04400440FFFE0440100013FE1200FE7C1244327C3A0056EE52AA92EE120013FE +85F3:0440FFFE05407FFC08200FE000007FFC48244FEC00003FF80100FFFE0920711C +85F4:04400440FFFE144010F824887CF8088810F824007DFC01545554555483FE0000 +85F5:0820FFFE08200BF8120833F8504097FE115012480100FFFE06801C48E530060E +85F6:0820FFFE08203FFE21042E3822102FBC27182AB432522040247C444044409FFE +85F7:04400440FFFE044020201022FDFC00287BFE004079FC068478FC488478FC4884 +85F8:04400440FFFE04400022FCFA2024602895FE344058FC948435FC568490FC2084 +85F9:04400440FFFE0440200011FCFD0401FC790401FC788001FE7A224D5279FA4806 +85FA:0820FFFE08207C7C44447C7C44447D7C44844FE459044FC449044FC449044FEC +85FB:0820FFFE082023F8120813F8800047BC54A417BC2040EFFE215022482C462040 +85FC:0820FFFE09207FFC41043FF801001FF001007FFC24483FF801004884489287F2 +85FD:04400440FFFE044008007F7C2244147CFF44087C7F44087C2A28492AA94A1086 +85FE:04400440FFFE14401080FEF811087EFC548454FC7C8410FC388454FC90481084 +85FF:0820FFFE08203FF801007FFE41029D7408801FFC30805FF890801FF810801FFC +8600:08200820FFFE082011FC1154FDFC102015FC182033FED08811FC102053FE2020 +8601:0820FFFE08207FFC01003D7825483D7801007FFC01003D7825483D780100FFFE +8602:0820FFFE09202488242443E424281214A0A0A4A41C1C0100FFFE05401930E10E +8603:0820FFFE092011F81100FFFE08102E5C28502E50F0FE01007FFC05401930E10E +8604:0820FFFE0820770C5570774000407F7E49487F4849487F480848FF8808880908 +8605:0820FFFE0820220047DC888017C0257E67C8A54827C821082FE8210822A82450 +8606:0820FFFE092001F801003FFC21042FE0210827F8249027F024904FF849489FFC +8607:04400440FFFE0440200C3E704410FF1049FE7F1049387F34005455528A900010 +8608:0820FFFE0820060038FE08107F7C1C442A7C49441C7C1444157C262824444082 +8609:0820FFFE08203FF82448FFFE901213F020102FFC6804A7F02210212020C02738 +860A:0440FFFE0440100010F824A87CA808D810F824007DFC01545554555483FE0000 +860B:04400440FFFE044009FE28202EFC2884FEFC088428FC2A8444FC08003048C084 +860C:0820FFFE0A2027DE491297D2211265DAA5142FD000003FF80000FFFE11102308 +860D:0820FFFE08A03F1004107FD0043E7FD255527FD204127FD20412FFE22AAA4544 +860E:0820FFFE08203FF801007FFE41029D7400003EF822A83EA822F83E844284867C +860F:0820FFFE0820400049FE742044FC3C8400FC7C8400FCFE8410FC5400D2482084 +8610:04400440FFFE0440203C13C0FD4400A879FC00407BFE008078F849487A3048CE +8611:0820FFFE08A03FFE22102FBC231826B42A5220003FFC44004FF8940827F80408 +8612:0820FFFE08A01CF0F11012F810A8FCF810A831FC392455FC552491FC1022101E +8613:08200820FFFE08200C8070F811081210FDFC312439FC552451FC90001154122A +8614:0440FFFE0440480075FE44203CFC00840CFC708410FCFE8410FC380054489084 +8615:0440FFFE04402020247C4AA4F81810E626104AFEFA10027CAA10AAFE051008FE +8616:0440FFFE044020207DFC44887C5041FE7C2045FC7C2001007FFC05401930E10E +8617:0820FFFE082000407C2045FC7C5043FE7C20A5FC3C2001007FFC05401930E10E +8618:0820FFFE082001007FFC00003EF822883EF804403FF80440FFFE04901C60671C +8619:0820FFFE08207F7848485E8664785F484A307F4C00007EFC22441A3462C4060C +861A:08200820FFFE082020443E2844FEFF1049107F7C49107F1000FE55104A908A90 +861B:0820FFFE0820241024FEFF2024443CFE24023C7C2444FF7C5444627C40447E4C +861C:04400440FFFE044029007DFC29043A4411547CE455F47C4410E4FD5410541008 +861D:04400440FFFE044008201420223E5D4280847710551077102228222855448882 +861E:04400440FFFE044008201420223E5D4480A47724552877282210222855448882 +861F:0440FFFE044001FC7CA845FC482051FC480445FC440455FC484042A4428A447A +8620:0820FFFE0820104057FC524855547FFE100017FCF40455F4551455F4940417FC +8621:0820FFFE08203EF822883EF822883EF822883EF814502288FFFE082007C07838 +8622:0440FFFE0440100008407E7C2440FF7C00047E7C42407E7C42407E7C4242463E +8623:04400440FFFE044022207F10227EFF9008107F10497C7F1049107F1022FE4100 +8624:0440FFFE0440103C27C07A4449284BF84A087BFC4A044BFE7A024CAA04AA0906 +8625:0820FFFE092002800C6037D8C0063BB82AA83BB800003FF824883FF8248824B8 +8626:04400440FFFE04403FF801007FFE41029D7401001D7000003BB82AA83BB82AA8 +8627:0820FFFE08A000F840802FFC28840BF0E8882BF829402AA8317022A851608FFE +8628:0820FFFE0820070CF87051102A2420783E104824FF7E081249544F5271920030 +8629:0820FFFE28203F20403EBE482AA8FF284A107F2808461F8002103FF811102308 +862A:0820FFFE09203FFC24403FF824483FF828402F7828442F3C44905FFC82A01C9C +862B:08200820FFFE082027D01510179E84A047A8554417C42000E7F8252825282FFE +862C:0440FFFE044010007DFC44047CFC40047DFC44007DFE11225CFC50A45EACF020 +862D:0820FFFE08207C7C44447C7C44447C7C41045FF441045FF455545FF44544592C +862E:0820FFFE08203FF824483FF800003FFE22042A942514289422544A8445148888 +862F:0820FFFE082021F8110841F821080BFE090073FC14A4115412883FF82448FFFE +8630:04400440FFFE044021FC210449FCF90413FE22524BFEF80001FCA888A870038E +8631:0440FFFE0440100093FE5420FEFC388454FC928400FC1484FEFC280044488084 +8632:0440FFFE04401FF011101FF011103FF82AA83EF82AA83EF801003FF80100FFFE +8633:08200820FFFE082022107F7C2210FF90087E7F0049107F10497C7F10227E4100 +8634:0820FFFE08201D7049245D7449245D7449247FFC00007FFC10101FF00820FFFE +8635:0820FFFE08200094FDD2481249507BFE481049D4795449D44F48F9CA09560822 +8636:0440FFFE04400C20704011FCFD2439FC552493FCFC24245A685E10902912C60E +8637:0440FFFE0440FFFE110013DE5A5253DE52505BD2E40E0FE0544483821C70E00E +8638:0820FFFE08200050FE4810FE11907CFC549054FC6C9044FE7C8045547D2A462A +8639:0820FFFE08A0104017FC10005BF856A853F892441158124410A8119016A810C6 +863A:0440FFFE0440100008287F24147E494855C87F7E08487F7E514855485D7E4340 +863B:0820FFFE08207F3C2A243E422A3CFFA449187F6608401F8002103FF811102308 +863C:0820FFFE08A03FFE24103F7C26382D54341221203F3E21202F3C41205F3E8120 +863D:0820FFFE08201FF011101FF011103FF82AA83EF82AA83EF801007FFC0920711C +863E:0820FFFE08A0204027FC200023F8FAA823F822442118224438A8E19046A800C6 +863F:0820FFFE08207FFC44447FFC10A0209045FE792013FC25207DFC012055FE8100 +8640:0820FFFE0920FFFE02887D7025484D6682807EFC02803EF802807EFC0280FFFE +8641:0440FFFE0440FFFE110013DE5A5253DE52505BD2E64E0FE0544483821C70E00E +8642:0820FFFE08203FF801007FFE41029D7400403EFC23483E3009CE2E7828487E78 +8643:0820FFFE08202294129215508FFE42905EF412942EF4E2942EE8228A22F62F22 +8644:0820FFFE08A021F822882070FBAEA8F8A850FBFE22A02AFC3B20CA78042009FE +8645:0820FFFE082001243CA825FC24403FFE248825FC3EA224F824A044FC54048AAC +8646:0820FFFE08201FF011101FF011107FFC4AA47EFC4AA47EFC20087FFC11102308 +8647:0820FFFE08A87BFE08880BDE7A5243DE40A079FE09200BFC0D2009FC512021FE +8648:0820FFFE082000007BDE489249124BD27A5E03C07A5E4BD24A524BD2799E4A52 +8649:0820FFFE08207F10007C3E44227C3E44007C7F40557E49407F7E490249AA4306 +864A:0820FFFE082021084FD2F03C23884812FBBE0280ABAA01007FFC05401930E10E +864B:0820FFFE082077DC444477DC4444FFFE92921C7010101FF008201FF0642C0860 +864C:0820FFFE49202A3E7F4849485DA86B1049285FF612903EF822883EF8228A3DFE +864D:0100010001F8010001003FFC200421082100211821E02F002104410440FC8000 +864E:010001F801003FFC210421602F88210820F8200023E02220222044244824901C +864F:010001F801003FFC210421602F88210820F821002FF821082108420844509820 +8650:010001F801003FFC210421602F88210820F8200027F824003FFE440047F88000 +8651:010001F801003FFC210421602F88210820F82000208020442A424A12521081F0 +8652:0008007C3F80208020F820802FFE288228F02F84287C28004BE052229422281E +8653:2020203E202021FEF922293829E02922291E29002B782D484948424A824A0486 +8654:010001F801003FFE210221F02F0420FC210020802FF822202140408043608C1C +8655:010001F801003FFE210221F02F0420FC2400243827A828AA352A42464580987E +8656:010001F801003FFE210221F02F0420FC201027E0224821502FFE404041408080 +8657:010001F801003FFE210221F02F0420FC2000201C27E0240027FE442044209FFE +8658:010001F801003FFE210221F02F0420FC200027F8240827F8240847F84408BFFE +8659:010001F801003FFC210421602F88210820F8210020882A242A445380460899F8 +865A:010001F801003FFC210421602F88210820F8224032482A482A5042405FFC8000 +865B:010001F801003FFE210221F02F0420FC2120292429242F3C212041205FFE8000 +865C:010001F801003FFC21042FE0210827F8249027F0249027F041005FF884080818 +865D:08200F2008207F7E496A4EAA782A492A474A40924E224A544A0A520291FE2000 +865E:010001F801003FFC21042FE0210827F8241027F020002FF820805FFC42209C1C +865F:0020783E482049FE4922793801E0FD22211E41007978094809480A4A524A2486 +8660:2010101E0010FEFE0092289C44F08292048E448028B810A828A8452A852A0246 +8661:010001F801003FFE210221F02F0420FC200021202924252821205FFE42108408 +8662:04101E1EE01022FE9292549C40F00492FF8E048044B824A824A8052A152A0A46 +8663:08100C1EEA100AFE0892FE9C28F02892B88EA880AAB8AAA8B6A8C32A812A0246 +8664:10101E1E10107EFE52925C9C70F052924E8E40805CB854A854A8972A952A2246 +8665:10281E24102E7EF052285C12702A52D64E28402E5CF0542454285612942A20C6 +8666:2810241E2E10F0FE2892129C2AF0D692288E2E80F0B824A828A812AA2B2AC646 +8667:08000FBC08007FC048404F3E7890479052205FBE72025F8252025F8252149F88 +8668:08020F8208047FC848504F0278824784400848907DE248825DC46AA8489088A0 +8669:1020923E522055FE11227D3845E07D22451E7D00117859485548964A524A2486 +866A:2120213C39642318FA66AABEB2AAE6BEAAAA9ABE8288BABEAA88AE7E2A0042AA +866B:0100010001003FF821082108210821083FF8210801000110010801FC7E040000 +866C:0840084008407F4049404940494049407F40484008400A440F44F144403C0000 +866D:0800080008FE7F2249224922492249227F22482208220A420F42F18241140208 +866E:1000100010F07C9054905490549054907C905090109014921C92E512410E0200 +866F:0804080408447F4449444944494449447F44484C08740A440F04F10440040004 +8670:0800080008FE7F1049104910491049107F10481008100A100F10F11040500020 +8671:00007FF0009003D07C1004103F902490249024903F900412048A07CA78462002 +8672:0820082008207F2049204930492849247F22482208200A200F20F12040200020 +8673:0820082008207F7C49444984490449447F24481408140A040F04F10440280010 +8674:1008101C10E07C20542054205420543E7DE05020102014221E22E222401E0000 +8675:1020102010207D20552C5534556457A47D245134112815221D22E50240FE0000 +8676:100011FC10207C2054205420542057FE7C205020102014201E20E22040A00040 +8677:0800087C08107F1049104910491049FE7F10481008100A100F10F11040100010 +8678:100011FC10047C0854105420542057FE7C205020102014201E20E22040A00040 +8679:1000100011FC7C2054205420542054207C205020102014201E20E22043FE0000 +867A:00200020FE2025FC25242524252425FC24202420242825FC2404440243FE8000 +867B:1020101010107C0055FE5480548054807C805080108014801E80E28040FC0000 +867C:1040104010807CFE5500560054FC54087C105020104014801D02E50240FE0000 +867D:00001FF0101010101FF0010001003FF8210821083FF80120011001F87F042004 +867E:100013FE10407C4054405440545054487C445044104014401E40E24040400040 +867F:0000FFFE040007F00810101020A041403FF8210821083FF8010001087FFC2004 +8680:2020202020203DFC45244924A124212421FC212420202028282433FE21020000 +8681:1040102411247D0455045488548854887C505050102014201C50E48841040602 +8682:100011F810087C0854885488548854FE7C025002100215FA1C02E40240140008 +8683:040008401F8003080C103FE000C0070079001FF0111011101FF001087FFC2004 +8684:1040102010207DFE544054405440547C7C445044104414441E84E28441280210 +8685:100011FE11007D0055785548554855487D485168115015421D42E542423E0400 +8686:1000100011FC7D2455245524552455247DFC5100110015001D02E50240FE0000 +8687:100010FC10847C845484548454FC54A07CA050A0109014901D08E50842040402 +8688:100011FC10887C8854885488548857FE7C885088108814881C88E50841080208 +8689:020001007FFC0820044003801C70E10E1FF0111011101FF0110001087FFC2004 +868A:1040102010207DFE54885488548854887C885050105014201E20E25040880106 +868B:1020102010207DFE55225522552255227D52514A118A15021D02E502410A0104 +868C:1020102010207DFC54205420542055FC7C205020102017FE1C20E42040200020 +868D:1010111011107D125512551455D855107D105110111015121D52E592410E0000 +868E:1000100010FC7C8454845484548454847CFC5084108414841E84E28440FC0084 +868F:100010FC10847C84548454FC548454847C8450FC108414841E84E28441140208 +8690:1040104010807CFC55045604548454447C445014102414441D84E40440280010 +8691:1020102010207DFE54205420542055FC7C845088104814501E20E25041880606 +8692:100010FC10847C8454A45494549454847DFE5084108414841C84E50441140208 +8693:100411E410247C24542455E4550455047D0451E4102414241C24E42441440084 +8694:1004101E11F07D1055105510551055FE7D105110111015081D0AE54A41860102 +8695:00003FF801000200FFFE044008203118DFF6111011101FF0110001087FFC2004 +8696:1000100011FC7C005400540057FE54907C905090109014901D12E512420E0400 +8697:1020102010207DFC54245424542454247DFE5020105014501E88E28841040202 +8698:1048104410447C4057FE5450545054507C505050109014921C92E512410E0200 +8699:1020102010507C5054885544562254207C0051FC100414081E08E21040100020 +869A:1008101C10E07C805480548054FE54887C885088108814881D08E50842080408 +869B:1020102010207C2055FC5524552455247D2451FC112414201E20E22040200020 +869C:100011FE10087C8854885488550855FE7C185028104814881D08E60840280010 +869D:1008103C11E07C205420543C55E054207C20503E13E014201E22E2224022001E +869E:1020102010207C2055FE5420547054707CA850A8112415241E22E42040200020 +869F:1000100011FC7C2054205420542054207DFC5020102014201C20E42043FE0000 +86A0:044008203018DFE60420042008A0104021001FF0111011101FF001087FFC2004 +86A1:1010109010907C8855085504560455FA7C885088108814881D08E50842280410 +86A2:1040102010007DFC5400540054F054907C905090109014921C92E512410E0200 +86A3:1008104810487C485444548454A455227C205040104014481C84E5FE40820000 +86A4:00003FF012100920044003801C70E10E1FF0111011101FF0110001087FFC2004 +86A5:1010108810847C8455025602548854887C885050105014201E50E28841040202 +86A6:100010FC10847C84548455FE548454847C8451FE108414841E84E28440940088 +86A7:1020102010507C5054885504560254887C885088108814881C88E50841080208 +86A8:1020102010207C2055FC5420542054207DFE5020105014501E88E28841040202 +86A9:0100210821083FF80100FFFE000001003FF8210821083FF8010001087FFC2004 +86AA:1010111010907C9054105510549054907C10501E13F014101E10E21040100010 +86AB:1040104010FC7C84550456F4549454947CF45084109414881E82E282407E0000 +86AC:100011FC11047D0455245524552455247D245154105014901C90E5124212040E +86AD:100011FC11047D04550455FC550055407D445148117015401D42E642423E0400 +86AE:1050105410527C925490559E55F056907C905090109014901E8AE28A40860082 +86AF:1004100E10F07C8054805480548054FE7C885088108814881C88E48843FE0000 +86B0:1020102010207C2055FC5524552455247D2451FC112415241D24E52441FC0104 +86B1:1080108010807CFE554055405640547C7C4050401040147E1E40E24040400040 +86B2:100011FC10207C20552454A454A854207FFE5020102014201E20E22040200020 +86B3:1004101E11F07D1055105510551055FE7D105110111015081D0AE54A41A60112 +86B4:201020902090F910A97EAA52AB92A892F912A11222522BD23862E822404A0084 +86B5:1000100013FE7C08540855E8552855287D28512811E815281C08E40840280010 +86B6:1088108810887C8855FE5488548854887C8850F8108814881E88E28840F80088 +86B7:100010FE10807C80548054FC548454847C84508410FC14801E80E28040FE0000 +86B8:1008101C11E07D005500550055FE55107D105130111815141D12E61042100410 +86B9:1044104410447C8454BE5584568454A47C945094108414841E84E28440940088 +86BA:1020102010207DFC5524552455FC55247D24512417FE15041D04E50441140108 +86BB:042004207FA00E20152224A2441E01001FF0111011101FF0110001087FFC2004 +86BC:1080108010807DFC5504560455E455247D245124112415E41D24E40440280010 +86BD:100011FE10107C1054205420546854A47D225222102014201C20E40043FE0000 +86BE:1010101010107DFE55125514551055FC7D445144112815281D10E62842440482 +86BF:1020101010107DFE54205420544454847DF85010102014441C82E5FE40820000 +86C0:1040102010007DFE54205420542054207DFC5020102014201C20E42043FE0000 +86C1:100011FC10447C4454445444549454887D0050FC108414841E84E28440FC0084 +86C2:1050104810487C4055FE54405440547C7CA450A410A815281D10E62840440082 +86C3:100011FE10207C20542055FE552255227D52514A118A15021D02E502410A0104 +86C4:1020102010207C2055FE5420542054207DFC5104110415041D04E50441FC0104 +86C5:1020102010207C20543E5420542054207DFC5104110415041D04E50441FC0104 +86C6:100010FC10847C84548454FC548454847C8450FC108414841C84E48443FE0000 +86C7:1020101010107DFE55025604548054887C9050A010C014821E82E282407E0000 +86C8:1020102011207D2055FC5520562054207DFE5020105014501E88E28841040202 +86C9:1020102010507C5054885524561254107DFC5004100814881E50E22040100010 +86CA:010001003FF8210821083FF8010001087FFC00043FF8244824482448FFFE0000 +86CB:7FFC0104110011F81100290047FE81001FF0111011101FF0110001087FFC2004 +86CC:1008101C11F07D5055505550555055507D505148114815681D54E67442520400 +86CD:2208111000207FFE4002810401003FF8210821083FF80120011001F87F042004 +86CE:100011FE11007D00550055FE552055207D3C5124112415241D24E64442540488 +86CF:100011FC10847C8854505420545054887F26502011FC14201C20E42043FE0000 +86D0:1050105010507C5055FC5554555455547D5451FC115415541D54E55441FC0104 +86D1:1020102010487C8455FE5412549054907CFE5110101017FE1C10E41040100010 +86D2:1040104010787C8855505420545054887D0650F8108814881E88E28840F80088 +86D3:082008287F240820FFFE002008247F24492449287F28481009120FAAF0464082 +86D4:1000100011FE7D025502557A554A554A7D4A514A117A15021D02E5FE41020000 +86D5:1020102011FE7C40544054FC548455847EFC5084108414FC1E84E28440940088 +86D6:1090108810807DFE54A054A854B054A47CA850B01124152A1D32E62242DE0400 +86D7:040008003FF020103FF020003FF820083FF801003FF821083FF801087FFC0004 +86D8:1104108410887C0057FE5420542055FC7C20502013FE14201E20E22040200020 +86D9:1020102011FC7C205420542057FE54007C20502011FC14201C20E42043FE0000 +86DA:2002200223E2F90AA90AA9EAA92AAA2AFB2AA2AA244A284A3882E902420A0404 +86DB:1020112011207DFC55205620542057FE7C7050A810A815241D24E62240200020 +86DC:2100217C2124FA24AA24AEFEAA24AA24FA24A27C22242A203A20EA2042400280 +86DD:100011F811087D0855F85508550855F87D445148113015201D10E54841860100 +86DE:1008103C11E07C20542057FE542054207C2051FC110415041D04E50441FC0104 +86DF:1040102010207DFE54005488550456027C885088105014501C20E45040880306 +86E0:2040204021FCF844A884A884A928AA10F908A3DE214A294A394AEA52435A04A4 +86E1:100013DE10427C425652554A554A54427CC6514A125214421C42E442414A0084 +86E2:1104108410887C0055FE5488548854887C8853FE108814881D08E50842080408 +86E3:1020102010207DFE5420542054FC54007C0050FC108414841E84E28440FC0084 +86E4:1020102010507C505488550456FA54007C0050F8108814881E88E28840F80088 +86E5:10201020107C7C8455485430542054487D90503E104215A41E18E21040600180 +86E6:1020102013FE7C2055FC542455FC55207DFE5022102A14541E50E28841040202 +86E7:100011FC11047D04550455AC555455547D54515411AC15041D04E50441140108 +86E8:100011FE10207C20544054FC548454847C8450FC108414841E84E28440FC0084 +86E9:00007DF01110119011521D12E20E45001FF0111011101FF0110001087FFC2004 +86EA:080008007F7C08243E2408447F54088809001FF0111011101FF001087FFC2004 +86EB:1040104010FC7D04560855FE5500557C7D445144115415481D42E542413E0200 +86EC:044004407FFC04400440FFFE082010102108DFF6111011101FF001087FFC2004 +86ED:100011FE10207C405488550455FE54227C20502011FE14201C20E42043FE0000 +86EE:02000100FFFE044014502448444401001FF0111011101FF0110001087FFC2004 +86EF:1040104010447DF45448545057FE54407C805184129814E01C82E482407E0000 +86F0:10801080FBF010901990F0941154520C25041FF0111011101FF001087FFC2004 +86F1:1020102010207DFC5420552454A454A87C2053FE105014501E88E28841040202 +86F2:2080208020BCFBC0A850A824A8D4AB0CF800A3FE209028903912E912420E0400 +86F3:208020BE2088FA88AABEAAAAAAAAAAAAFAAAA2AA22AA28AA392EE90842080408 +86F4:1040102013FE7C8854505420545054887D065088108814881C88E50841080208 +86F5:100011FE10007C9255245648552454927C0051FE102014201C20E42043FE0000 +86F6:1004101E11E07C2255125494548054087DFE5008108814481E48E20840280010 +86F7:1028102410247C2055FE5420552054B27CB4506810A815241E22E42040A00040 +86F8:1020112410A47CA8542055FC550455047DFC5104110415FC1D04E50441140108 +86F9:100011F810087CD0542055FC552455247DFC5124112415FC1D24E5244124010C +86FA:1020102010207DFC542054A854A854A87D745222105014501E88E28841040202 +86FB:1010109010887D08560455FA550855087D0851F8109014901C90E5124212040E +86FC:1020102011FE7C2055FC5524552455FC7D24512411FC14201DFEE42040200020 +86FD:100010FC10847C8454FC5484548454FC7C84508410FC14001E48E24440820102 +86FE:201020D82394F894A890ABFEA890A894F894A0D82398289038AAE8CA42860102 +86FF:1020102010507C885544562254F854087C10502011FC15041D04E50441FC0104 +8700:00003FF8244824483FF810001FFC22045FC4924412441FC4022403F47C142008 +8701:2100210021FEFA00AC00A9FEA822A824F920A13C212029203920EAA0447E0800 +8702:1040104010FC7C885550542054D857267CF8502010F814201FFEE42040200020 +8703:3FFC20002FF820003FFC24482430260E20802FF8288848884FF880841FFE0802 +8704:100011FE11007D00557C5500550055FE7D505152115415481D48E64442520460 +8705:1028102413FE7C20542055FC552455247DFC5124112415FC1D24E5244124010C +8706:100011FC11047D0455FC5504550455FC7D04510411FC14501C50E4924112020E +8707:080C08F07E8008800EFE788808882908120801003FF821083FF801087FFC0004 +8708:100011FC11047D0455FC5400540055FC7C20502013FE14201C50E48841040202 +8709:1008103C11C07C04554454A8540055F87C10502013FE14201E20E22040A00040 +870A:208421C42704F914A914A914AFD4A914FB14A39425542D043904E90441140108 +870B:1040102011FC7D04550455FC550455047DFC5120112215141D08E54441820100 +870C:1110111211147DD8551055125552558E7D20502011FC14201C20E42043FE0000 +870D:1020102010507C885504560254F854207C2053FE102015241D22E62240A00040 +870E:1000107C10447C44547C540054FE54827C8250FE108214821EFEE282408A0084 +870F:101C11E010207C2057FE54A8552456227DF85088109014BE1D02E50242140408 +8710:1088108810887DC8549E548A548A57EA7C8A508A110A154A1FEAE512402A0044 +8711:00187BE0104022787A400A402BFC10002FFE41003FF821083FF801087FFC0004 +8712:2004200E23B8F888A888A928A92EABA8F8A8A2A822A8293E3900EA80447E0800 +8713:2000200623B8F888A888A908A93EAB88F888A2882288293E3900EA80447E0800 +8714:1080108010FE7D02550256FA54AA54AA7CFA50AA10AA14FA1E8AE20240140008 +8715:1104108410887C1055FC5504550455047DFC5050105014901C92E512420E0400 +8716:100011FE114A7D4A554A557A554A554A7D4A517A114A154A1D4AE5FE41020000 +8717:200021FC2104F904A904A9FCA820A820FBFEA22222522A8A3B0AEA02420A0204 +8718:210021002100FBDEAA92AC92A892A892FBF2A09220922952395EEA2044200800 +8719:210421142114F914AFD2A922A92AAB48FB88A550251029143922E97E41220100 +871A:044004407C7C04403C7804407C7C044001001FF0111011101FF001087FFC2004 +871B:100011FC11047D0455FC5510551055FE7D105110117C15441D44E544417C0244 +871C:020001007FFE42028924284849940E1077F001003FF821083FF801087FFC0004 +871D:08207FFC08200FE008200FE00820FFFE10102108DFF611101FF001087FFC0004 +871E:1088108811FC7C88548854F8548854887CF85088108815FE1C00E48841040202 +871F:1020101011FE7C40548455FE540254FC7C8450FC108414FC1E84E28440940088 +8720:200023FE2202FA1AAAE2AA22AA22ABFEFA22A27222AA2B263A22EA2243FE0202 +8721:1048104810487DFE5448544855FE54007CFC5084108414FC1E84E28440FC0084 +8722:100011FC10087C10542057FE542054A07C4051FC115415541D54E55443FE0000 +8723:1088104810507DFC5420542055FC54207C2053FE105014501C90E4924112020E +8724:080C08F07E8018802CFE2A884888888809081FF0111011101FF001087FFC2004 +8725:210021062138F920AFA0A920A93EAB24FBA4A564252429243924E92441240144 +8726:1020102010507C88550456FA540055FC7D54515411FC15541D54E5544104010C +8727:2040202023FCFA04AA04ABFCAA00AA28FA24A3FE22202A503A50EC8845040A02 +8728:1020102013FE7C2055FC542457FE54247DFC50201120153E1D20E6A0427E0400 +8729:100011FC11247D245574552455FC55047D745154115415741D04E60442140408 +872A:1080108010FE7D02568254F2554254427FFA5042115215521DF2E40240140008 +872B:100011FC11047D0455FC5504550455FC7C00511211D415181D10E5524192010E +872C:200021FC2008F810AA22AAAAAA72AA22FA72A2AA23262AA23A42EA0243FE0002 +872D:10401040107C7C8455085600542055CE7D02510211CE15021D02E50241FE0102 +872E:201420122010FBFEA810A810ABD2AA52FA52A25423D4280C386AEB8A41160022 +872F:1020102011FE7C2054FC544055FE54887D24522210F814201DFEE42040200020 +8730:00003EFC22A43EA422FC3E80228222824A7E85003FF821083FF801087FFC0004 +8731:1040108011FC7D24552455FC552455447DFC5090111017FE1C10E41040100010 +8732:101C11E010207C2057FE54A8552456427C4053FE108815081CD0E43040480184 +8733:1020101011FE7C0054FC548454FC54007CFC5008101015FE1E10E21040500020 +8734:100010FC10847C8454FC5484548454FC7C4050FE112A144A1C92E522404A0084 +8735:1050115411547D5455DC5504550455FC7D04510411DC15541D54E55442540404 +8736:1040102011FE7C0054885488555456227C00502013FE14201E20E22040200020 +8737:1020112410A87C2055FC544057FE54887D0452FA148814881CA8E4924082007E +8738:00007EFC48447E4442287E1048287EC601001FF0111011101FF001087FFC2004 +8739:1088108813FE7C8854A8542055FC55247D245154114C15841D04E50441140108 +873A:20002040239CFA04AA04AB9CAA04AA04FBFCA090209028903890E9124212040E +873B:1020102013FE7C2055FC542057FE54007DFC510411FC15041DFCE50441140108 +873C:10A0109010807DFE5510571055FC55107D1051FC111015101D10E5FE41000100 +873D:200023FE2020F820ABFEAA22AA22AB32FAAAA2AA23762A663A22EA22422A0204 +873E:100011FC11247D2455FC5524552455FC7C2053FE107014A81D24E62240200020 +873F:2040202023FEFA02AD04A900A9DEAA52FA52A352249A28943910E9124212040E +8740:1020102013FE7C2055FC552455FC55247DFC5020107014A81D24E62240200020 +8741:00007FFC04403C7820083C780440FFFE01001FF0111011101FF001087FFC2004 +8742:2080228622B8FAA0ABE0AA3EAA2AAA2AFBAAA2AA22A42AA43AA4ECCA448A0892 +8743:100013DE10427D4A5484554A565254207C0053DE105215521C94E54842540422 +8744:200023FE2202FA8AAA52ABFEAA42AA22FBFEA28222822A823AFAEA02420A0204 +8745:3EF8082008207EFC08201450228841049FF2111011101FF0110001087FFC2004 +8746:10A810A813AE7CA854A8542055FC54207C20502013FE14201E20E22040200020 +8747:200021F02110F910A9F0A840ABF8AA48FA48A3F822482A483BFAE8424042003E +8748:200023FE2202FA02ABFEAA22AA22AAFAFA22A232222A2BFE3A02EA0243FE0202 +8749:1104108810507DFC5524552455FC55247D2451FC102014201DFEE42040200020 +874A:2040202023FEFA02AC04A800ABFEA820F820A120213C29203AA0EA60443E0800 +874B:200024842244FA48A800ABF8AA48AA48FBF8A24822482BF83A4AEC4A44460802 +874C:20C427042124F914A914AF84A924A914FB94A346253C2D043904E90441040104 +874D:200023DE2252FA52AA52ABD2AA52AA52FA52A3D2221A2A943A50EAB043100010 +874E:100011FC11047DFC550455FC548055FE7E225122115215021DFAE40240140008 +874F:2040202023FEF800A9FCA904A9FCA800FBFEA20221FC28203820E82040A00040 +8750:100011FE11027D7A5502557A550254007CFC508410FC14841EFCE28440FC0084 +8751:100013FE10227D20553C552056FE54007DFC510411FC15041DFCE50441140108 +8752:100013FE10207C4055FC5554555455747D545154117415541D54E55441FC0104 +8753:204020A02110FA08ADF6A800ABC4AA54FA54A3D422542A543BD4EA44425402C8 +8754:1110111211D47D1855525592552E54407DFC5104110415FC1D04E50441FC0104 +8755:10201020282025FC5324FD2445247D2445FC7D2440205028482455FE64824000 +8756:1040102013FE7E02540455FC540055FC7D0451FC110415FC1D04E40043FE0000 +8757:2020204021FCF904A9FCA904A9FCA800FBFEA020202029FC3820E82043FE0000 +8758:100011FE11007D7C5544557C5544557C7D1051FE112415641D18E524414201FE +8759:1020101011FE7D02550255FE550055007DFE51AA12AA14FE1CAAE4AA40AA0086 +875A:100010FC10487C3055FE5452549455107E30502011FE14701CA8E52442220020 +875B:200C200A2008FBFEAA08ABF8AA4AAA4AFBEAA2AC22AC2A4C3AAAEB0A42160422 +875C:1040104010F87D08561055FC550455FC7D0451FC110415FC1C00E48841040202 +875D:1040107C10847CF8540855FE544054A47D385058109415341C54E49241500020 +875E:100011FC11247D2455FC5500557C55447D44517C1144157C1D44E644427C0444 +875F:100011FE11227DFE552255FE540054FC7C8450FC108414FC1E84E28440940088 +8760:100011FE10007CFC5484548454FC54007DFE5122112215FE1D22E52241FE0102 +8761:100013FE10207C4055FC5554555455547D54512C102015FE1C50E48841040202 +8762:100013FE10207C4055FC5504550455FC7D0451FC110415041DFCE40040880104 +8763:210820882088FBDEA910A920A9DEA942F944A144215E29443A44EA4444D40808 +8764:1088104810507DFE5450545055FC55547D54518C110415FC1D04E50441FC0104 +8765:00207E20247E18A4FF2829104A2898C601001FF0111011101FF001087FFC2004 +8766:200023DE2242FA42AA42ABDEAA00AA3EFBD2A21222142BD43A08EA1442240242 +8767:1088108813FE7C8854A8542055FC55247D24512413FE14201E50E28841040202 +8768:00003FF0021002107FEA0206020208207EFC4AA44AA47EFC08200A24FEFE0202 +8769:1008103C11E07C2057FE542055FC55247DFC512411FC14201DFCE42043FE0000 +876A:100010FC10847CFC548454FC540055FE7C8050FE112A164A1C92E52240540088 +876B:1020102211FA7C24542857FE542054407CFC5184128414FC1E84E28440FC0084 +876C:200020882252FA22AA52AA8AAA02ABFEF888A144227A28883950E82040D80706 +876D:100011FC11047D0455FC5504550455FC7C0053FE102015201D3CE52042A0047E +876E:1040104010FE7C8055FC568454FC54847CFC5040107C14C41D28E41040680186 +876F:101E13E010447D24548855FC544054407DFE508010FC15441D28E61040680186 +8770:1020102013FE7C505488572655FC54207C2053FE100014201DFCE420402003FE +8771:02000100FFFE100010001FF8000008207EFC4AA44AA47EFC08200A24FEFE0202 +8772:2082208227F2F882A88AABEAAAAAAAAAFBEAA08A21CA2AAA3CA2E882408A0084 +8773:102011FE10207CFC542055FE540054FC7CA4509411FE14A41D14E5FE40040018 +8774:2100213C2124FBA4A924A93CA924ABA4FAA4A2BC22A42AA43BA4E84440540088 +8775:0620382008A47EA819202C504A88090401001FF0111011101FF001087FFC2004 +8776:204821482148FBFEA948A948A978A900F9FEA02023FE287038A8E92446220020 +8777:1020101011FE7D005544552855FE55107D5451541154157C1D14E52042400080 +8778:100010FC10847C8454F45494549455FE7D02517A114A154A1D7AE502410A0104 +8779:100010F810887C8854F85488548854F87C0051FC115415541D54E55443FE0000 +877A:2004201E23E0F820A9FCA924A924A9FCF820A3FE22222A2A3AFAEA02420A0204 +877B:2020202023FEF820A820ABFEAA8AAA52FAFAA22222222AFA3A22EA22422A0204 +877C:2020212420A8F820ABFEA8A8A924AA02F840A7FE208829083990E86041980604 +877D:1020102013FE7C2055FC544057FE54887D0452FA108814881CF8E488408800F8 +877E:2088208823FEF888A800ABFEAA02AC24F820A3FE207028A838A8E92442220020 +877F:100011FC11247DFC552455FC542055FC7D2451FC112415FC1C20E4224022001E +8780:088049F82A90286008901FFE2A10C950092001003FF821083FF801087FFC0004 +8781:1000127C11447D44547C54445744557C7D50514A114415541D62E5424280047E +8782:2100209E23D2FA52AA54ABD4AA58AA54FBD2A21222922A5A3AD4EB5042100010 +8783:2040202023FCF908A890ABFEAA02AC44F820A3FC208028F83888E90841280210 +8784:2100227E2388FA88AABEAAAAABAAAA2AFA2AA3AA22AA2AAE3A88EB8842880008 +8785:2020204021FCF904A9FCA904A9FCA904F9FCA040202028A43A8AEA8A44780000 +8786:208420442048FBFEA884A884A908A94AFA52A39C208429083908EA5243DE0042 +8787:101E13E011227C945440548855F054207CC451FE102214201FFEE45040880306 +8788:100011FE11107D20557C5544557C55447D7C5110111015541F52E29242500420 +8789:209020882104FA42AC88A9FCA804A800FBDEA0422252294A3A52E842414A0084 +878A:1088105010007DFE545055FC545457FE7C5451FC105014D81D54E65240500050 +878B:10A0112C11247D2455AC5524552455FC7C2051FC108814501E20E25040880306 +878C:10783E4822482A86FF7822482A2842104A2885463FF821083FF801087FFC0004 +878D:0020FE2000207CFC44A47CA400A4FEA482FCAAA49220FE28922492FE92428600 +878E:200023FE2000F9FCA904A904A9FCA800FBFEA28A22522BFE3A22EA22422A0204 +878F:2020201021FEF900A920AD20AB3CA950F990A31025FE29103928EA2842440482 +8790:2040208021FCF904A904A9FCA900A9FEF900A1FE20022AAA3AAAEC0240140008 +8791:1020104011FC7D0455FC550455FC55047DFC5028102415FE1C50E48841040202 +8792:102010201050FE8811267C2045FC7D2445247D2411FCFE201028103C13C41104 +8793:2040204027FCF840ABF8A880AFFCA910FA68A5C620402BF838E0E95846440040 +8794:2004201E23F0FA1EAA10AAFEAA92AA98FAF2A28E22802AB83AA8ECAA454A0A86 +8795:1020104011FC7D0455545524555455047DFC5000111215D41D18E5524192010E +8796:100010FC10847CF4549455FE550254FC7C8450FC108414FC1E84E28440940088 +8797:1020101011FE7D10557C551455FE55147D7C5110117C15441D44E644427C0444 +8798:1020112411247D2455FC540057FE54007DFC5104110415FC1C88E45043FE0000 +8799:010001007FFC038005401930E10E08207EFC4AA44AA47EFC08200A24FEFE0202 +879A:20444258FF6201427E3E42007E4C42727E42423E01003FF821083FF801047FFE +879B:2040202023FEFA02AC24A9FCA820A9FCF820A3FE202029FC3904E90441FC0104 +879C:08007F7808483E4800867F78414800303ECE01003FF821083FF801087FFC0004 +879D:2020204023FCFA24AA24ABFCAA24AA44FBFCA04020A828B4393CE9224222041E +879E:200021FE2120F9FCA920A9FCA920A920F9FEA00222AA2AAA3AAAEA0240140008 +879F:200023FE2202F800A9FCA904A9FCA904F9FCA04020202BFE3800E88841040202 +87A0:210420842088F800ABFEA800A888A904FA02A1FC215429543954E95447FE0000 +87A1:020001007FFC082007C01830E00E08207EFC4AA44AA47EFC08200A24FEFE0202 +87A2:08202AA44D28145022887FFE410281041FF0111011101FF0010001087FFC0004 +87A3:00203D2424A8242025FC3C4027FE24A825243EFA24A824A824F8442455FC8804 +87A4:20201020FE2005FC6924112429FCD52411247DFC55247C5010501C88E5044202 +87A5:1020102010507C4854A455FE568454FC7C8450FC108014FC1D44E544427C0044 +87A6:1020102013FE7C2055FC542057FE54407C8851F0102417FE1C22E52442A20040 +87A7:1040104411F87C5057FE544054F855827E7E540011FC15041DFCE50441FC0104 +87A8:1048104811FE7C48540055FE544854487DFE514A114A15B61D22E502410A0104 +87A9:2110211E2122FA54AA08AE94AAE2AA88FA88A2BE22882AAC3A2AEA4A42280210 +87AA:2040202023FEF888A850ABFEAA52AA8AFB06A2FA228A2A8A3AFAEA02420A0204 +87AB:08207F20083EFF4414A85610A5284C4681001FF0111011101FF001087FFC2004 +87AC:2090209027FEF890ABFCAA94ABFCAA94FBFCA00021F8290839F8E90841F80108 +87AD:2040202023FEF800A954A924A954A9FCF820A3FE22422A923AFAEA0A42020206 +87AE:2154215423FEF954A954AA72AC00ABFEFA22A02021FC29243924E924412C0020 +87AF:08207F20087E7E4408A4FF2810101E282244468281003FF821083FF801047FFE +87B0:2040202023FEFA50AA50ABFEAA52AA52FBFEA20022922AD43A98EC9244D2088E +87B1:3F0821083F7E20082F4820285FA8440895282C9001003FF821083FF801047FFE +87B2:2040202023FEFA8AA904ABFEA840A888F9FCA024202029FC3820E82043FE0000 +87B3:2020212420A8FBFEAA02A8F8A888A888F8F8A020202029FC3820E82043FE0000 +87B4:00207BFE482051FC612451FC492449FC687050A841243FFA21083FF801047FFE +87B5:100013FE10507DFC5554555455FC54007DFC500013FE14201CA8E52442A20040 +87B6:00003FFC20003FF820083FF820003FFC10207EFC52A47EFC10201424FEFE0202 +87B7:00803FFE22002FF828882FF829082FF822203FFC20A02FF848884FF880843FFE +87B8:14202220493E144222944110BE28222822443E8201003FF821083FF801047FFE +87B9:20802080208EFBE8A888ABE8AAAEABEAFAAAA3EA208A2BEA388AE892409200A2 +87BA:100011FC11247DFC552455FC544054887DF05020104417FE1C22E52442220060 +87BB:202021FC2124FBFEA924A9FCA820A9FCF924A1FC20402BFE3888E9D04070038C +87BC:1088108813FE7C8854F8542055FC55247DFC502013FE14201DFCE42043FE0000 +87BD:08001FF0282007C01830E18E0C40030010A07EFC52A47EFC10201424FEFE0202 +87BE:1040102013FE7E02540055FC542055FC7D2451FC112415FC1C00E48841040202 +87BF:0440247C24A83D5004287DFE24884448841801003FF821083FF801087FFC0004 +87C0:2040202023FEF820A848AAF2A924AA52F8F8A00820202BFE3820E82040200020 +87C1:3FF820083FF821003FFC20802C64301C10207EFC52A47EFC10201424FEFE0202 +87C2:104011FC11047DFC550455FC550055FE7D0051FE102215FA1C76E4A843260020 +87C3:200021F82108F9F8A908A9F8A800ABFCFA94A3FC200029F83890E86041980606 +87C4:08207E2008F8FF2814287F6A082AFF56088201003FF821083FF801087FFC0004 +87C5:1040102011FE7D005548554855FE55487D48114815781D00E6D442AA052A0800 +87C6:1088108813FE7C88540055FC550455FC7D0451FC102017FE1C50E48841040202 +87C7:04407FFC04401FF010101FF010101FF00400FFFE11103FF8D1161FF001087FFC +87C8:200023FE221AFA16ABFEAA12AAEAAAAAFAAAA2EA220E2A6A3B9AEA2643FE0202 +87C9:200023DE2042FA52A94AAA52A828A8C4FB12A0602188283239C4E81840600380 +87CA:1FF0022001407FFC048418886280010010207EFC52A47EFC10201424FEFE0202 +87CB:201C21E02020F924A8A8ABFEA870A8A8F924A222204028243AA2EA8A44880078 +87CC:1020104011FC7D24557C558C555455247D5451FC102014101D54E542414A0238 +87CD:2062238A208AFFEAA88AA9CAAAA2AC8AF8A4A02023FE287038A8E92442220020 +87CE:2088208823FEF888A888A8F8A820ABFEFA22A33222AA2B763A22EA22422A0224 +87CF:2088208823FEF888A820ABFCA824AFFEF824A3FC20202AB43AACEB2C42240424 +87D0:2020212420A8FBFEAA02A8F8A888A888F8F8A02021FC29243924E93441280020 +87D1:102011FC10887C5057FE540055FC55047DFC510411FC14201FFEE42040200020 +87D2:2088208823FEF888A824ABFEA850A888F904A28A20882BFE3888E88841080208 +87D3:208020F82108FBFEAD12A922A9FEA840F8A2A35420982B343854E89243500020 +87D4:200021FC2124F9ACA974A924A9FCA820F9FCA02023FE28003AA4EA5244520000 +87D5:2090229422D8FA92AAD2AF0EA9F0AA10FFFCAA4423FC2A443BFCEC4444540808 +87D6:214021442158FBF0A950A9D0A95EA9D4F954A15423F428143954EA3444140024 +87D7:01007FFC11101FF00100FFFE91121FF041047FFC01003FF821083FF801047FFE +87D8:10541092119E7EF0548A5486540254FC7C8450FC108414FC1E84E2FC40480084 +87D9:2110209423D2F812AA50A990AFFEA810FBD2A25222542BD43A4AEA4A43D60022 +87DA:08047F0808103E6400083E1022643E0814107F6001003FF821083FF801047FFE +87DB:2082208227F4F888A880ABE2A802ABE4FA28A22023E02A223942E87447880210 +87DC:101811E010407FFE54885574565254707C0051FC110415741D54E5744104010C +87DD:2200217E2040FC7CAA44A8FCA940AE7EFA20A02023FE287038A8E92442220020 +87DE:082049202A3E7F4849485DA86B10492841461FF0111011101FF001087FFC2004 +87DF:1020102011FC7C2055545488550456FA7C8850F8108814F81E20E2A841240060 +87E0:203C23E02124F8A8ABFEA8A8A924AA02F9FCA124212429FC3924E92441FC0104 +87E1:200E23F02044FA24A908ABF8AA08ABFCFA04A3FE22022AAA3AAAED0244140808 +87E2:102013FE10207DFC540055FC550455FC7C8853FE100015FC1D04E50441FC0104 +87E3:2124212422AAFBAEA924AAAAABAEA924FBFEA110211429143A8AEA4A42160422 +87E4:200023DE2252FBDEAA10AA52A9CEA800F888A3FE208828883BFEE88841040202 +87E5:1088108811FC7C88548857FE542055FC7D2451FC112415FC1C00E48841040202 +87E6:102011FC10207C8857FE548855FC55047DFC510411FC15041DFCE48841040202 +87E7:208822AA22DCFC88A954AA22A800ABFEFA42A44423FC28443844E88441140208 +87E8:3FFE289025103FDE22222A882F8822942422284027FC244427FC40444FFE8002 +87E9:20002FFE2800FA28A948ABEEA892A884FAA0AAA82BE828883894E91449241242 +87EA:2020202023FEF820A9FCA924A9FCA924F9FCA02223FE28423824EAA2428A0478 +87EB:200023FE2050FBFEAA52ABFEA800A9FCF904A1FC210429FC3820EBFE40200020 +87EC:200023DE2252FA52ABDEA800A9FCA924F9FCA12421FC28203BFEE82040200020 +87ED:1090108811FE7D10571055FE551055107DFE111015101DFEE50042A402520452 +87EE:1088105013FE7C2055FC542057FE55247CA853FE100015FC1D04E50441FC0104 +87EF:2020202021FCF820ABFEA908AB9CA908F988A63E20002BFE3890E8904112020E +87F0:202021FC2024FBFEA824A9FCA820AAAAFBAEA22223FE2A223BAEEAAA42AA0422 +87F1:2080208021FEFB54AD54A954ABFEA954F954A15427FE28003954E92A422A0000 +87F2:010001003FF821083FF801087FFC000410207EFC52A47EFC10201424FEFE0202 +87F3:100011FC10047CFC540455FC540055DC7C9453DC100817FE1D08E48840A80010 +87F4:240CFF7024403C40247E3C482448FF482448428801003FF821083FF801047FFE +87F5:200023FE2200FA04ABF4AA04AAEEAAA4FAA4A2EC22042AA43A44EA7445940008 +87F6:200027E0225EFBD2AA52ABD2AA72AFDEF840A3FE202029FC3820E82043FE0000 +87F7:2020212420A8FBFEAA02A8F8A888A888F8F8A00021FC292439FCE92441FC0104 +87F8:7FFC06003B0804B019C062A00C98728611207EFC52A47EFC10201424FEFE0202 +87F9:20003EFC4424BE542A983E502AFC3E102AFE2A1045103FF821083FF801047FFE +87FA:101011FE10007DFE5502557A554A55FE7C0050FC108414FC1E84E2FC400001FE +87FB:2104208823FEF820A9FCA820ABFEA854F992A09023FE289038D4EB8A409601A2 +87FC:2420FF20247E7EC482287A104A287AC605001FF0111011101FF001087FFC2004 +87FD:10101210117C7C1054FE5444572855FE7D10517C111015FE1D10E51042FE0400 +87FE:108010F811087FFE5544559255FE55007D7C5100117C15001D7CE544417C0244 +87FF:0878FFC808483E862B783E482A28FF9049287F4601003FF821083FF801047FFE +8800:1220113E10427C9457105528544655FC7D0451FC110415FC1D04E5FC40880104 +8801:11002BDE4A5273D42A524BD27A1A12942350C24001003FF821083FF801047FFE +8802:108813FE10887C00554857FE554855787D0051FC102017FE1C70E4A843260020 +8803:0100FFFE20003FF800003FF820083FF80000711C57D4755457DC715657D6B062 +8804:202020502088F924AEFAA850A924A954F9FCA02023FE2A423A92EAFA420A0206 +8805:100011FC11547D5455DC545055DC55547D5451DC115415541DDCE5504052003E +8806:0820FFFE08201FF011101FF011107FFC41245FEC01003FF821083FF801047FFE +8807:2088208823FEF888A9FCA924A9FCA924F9FCA02023FE2A223A2AEAFA420A0206 +8808:00107C1445FE7C9044947DD4448A7C8A291645223FF821083FF801087FFC0004 +8809:100011FC11547D5455FC540057FE54007DFC510411FC14621C94E58842A400C2 +880A:202023FE2288FA50ABFEAA50AAFCAA54FBFEA25422FC2A503AD8ED5446520850 +880B:100011FC11547D5455FC548055FC56447DF45154115415F41C44E5F440140008 +880C:100011FC11547DFC542055FC542057FE7C88505011FC14201FFEE42040200020 +880D:200823C82248FBCEAA4AABD2A904ABE4FCA4A2A423642A2A3BEAE82A414A0090 +880E:108813FE10887C2057FE5450548857267CF85020108815FE1C88E48841080208 +880F:210021DE224AFC8AABEAAAB6AAA4ABF4FABEA2A423E42ABE3AA4EAA442240464 +8810:2040202023FEF888A852AFACAAAAAAA8FDACA000210429FC3904E9FC41040204 +8811:208822AA22DCFC88A954AA22A800ABFEFA22A02023FE287038A8E92446220020 +8812:7FFC21087FFCB55A29283558210835582928355801003FF821083FF801047FFE +8813:208823FE2088FBFEAA02A9FCA800ABFEF840A0A2235428B83B54E89243500020 +8814:202023FE2000F9FCA904A9FCA800ABFEFA02A1FC20402BA438D8EB3440D20330 +8815:200021FC2020FBFEAA22A9ACA820A9ACF800A3FE202029FC3954E9544154010C +8816:108813FE10A87C9055FE572055FC55207DFC512011FE15001FFCE4884070038E +8817:200023DE2042FA52A94AAA52A890A908FBFEA51021FE291039FEE91041FE0100 +8818:2110211423F2F910AFFEAA90AA50AFF4FA94A3F422942BE83A8AEBFA42260042 +8819:2040202023FEFA02A9FCA948AA50A9FCFB04A1FC210429FC3904E9FC40880104 +881A:08207FFC08200200FFFE08001FF02810C8100FF010207CF854A87CF81224FEFC +881B:104811FE10487C0055FE554A554A55FE7C1451FE111015921D4CE54A41160222 +881C:22882108FABE2008729CA92A2288FFFE08203018C1063FF821083FF801047FFE +881D:200021FC2124F9FCA924A9FCA904A800FBFEA2AA22AA2BFE3AAAEAAA43FE0222 +881E:20403F7E4890BF7C21443F4421443F5424483A4001003FF821083FF801047FFE +881F:212422482124F800ABFCAA94AA64AA94FBFCA24823682A483B6AEA4A42460362 +8820:00007FFC02003FF8244827C8244827C824483FF810207CF854A87CF81224FEFC +8821:0FE010201FC00040FFFE0C1073200DC072B00C8EF3207CF854A87CF81224FEFC +8822:01007FFC01003FF80200FFFE08203FF8C8260FE010207CF854A87CF81224FEFC +8823:100011FE11287DFE5528557C5554557C7D54117C15101DFEE59242BA028A0484 +8824:08200440FFFE04403FF82848303827C820083FF810207CF854A87CF81224FEFC +8825:52107EFE28447E28A2FE3E1020103E7C22103E1001003FF821083FF801047FFE +8826:2040207C2040FBFCAA44ABF0AA44AAFCFAA8A2F822A82AF83A00EDFC45540BFE +8827:01007FFC01001FF000007FFE48029FF42810CFF010207CF854A87CF81224FEFC +8828:208823FE20A8F9FCA824ABFEA824A9FCFAAAA3AE22222BFE3A22EBAE42AA04AA +8829:22102110203AFB92A814ABBEA808AB90F83CA3E422A42ABC3AA4EBA442BC0024 +882A:08407F7C1440FF7C22043E7C22403E7C2242263E01003FF821083FF801047FFE +882B:0704782425241E2464241A24652419046514020810207CF854A87CF81224FEFC +882C:2110209023DEF810AA5EA982ABDEA810FBDEA25023DE2A503BDEEA50425202CE +882D:210013F0151000E0775C11F0104013FC284047FE10207CF854A87CF81224FEFC +882E:23EE228A22EAFB50ABEEAA4AAAA4ABEAF800A3DE20422A52394AEA52414A0084 +882F:00807FFE42004FF848884FF849084FF842807FFC44905F7C55545F7C4492BFFE +8830:102013FE10007DDC555455DC548857FE7C8853FE108817FE1C94E58842A400C2 +8831:01001FF011101FF001087FFC10207CF854A87CF81224FEFC00003FF82448FFFE +8832:440024FE28AA00AAFEFE004028FE452282FA00AAFEAAAAFAAA22AAFAAF0AF804 +8833:23DE225223DEFA52ABDEAA52ABDEA98CFA52A04027FE28883990E86040D80304 +8834:108813FE10887DFC555455FC542255FC7C2853FE104015FC1E84E4FC408400FC +8835:222223FE2090F9FEAB10ADFEA910A9FEF910A1FE21002BFE3A8AEB7642520276 +8836:3E7C48907EFC142A66C63FF820083FF820083FF810207CF854A87CF81224FEFC +8837:23DE225223DEFA52ABDEAA52ABDEA890F9FEA11023FE2D1039FEE91041FE0100 +8838:208823FE2088FBDEAA52ABDEA8A0A890F9FEA12023FC2D2039FCE92041FE0100 +8839:01007FFC11101FF00100FFFE88021FF068100FF010207CF854A87CF81224FEFC +883A:7CF81020FDFC28504488BFF620103FF020103FF010207CF854A87CF81224FEFC +883B:210447C88812F3BC20084B92F83E0380AAAAABAA01003FF821083FF801047FFE +883C:23DE225223DEFA52ABDEA8A0A9FEAB20FDFCA12021FE280039FCE8884070078E +883D:08282A244D2E087014243F246428BF12242A3F4610207CF854A87CF81224FEFC +883E:23FE220223FEFA92AA54AA92AAFEAAAAFAFEA32222FA2AAA3AFAEA2245FA0004 +883F:249079E414547DFC0004FFFC249479E41454FFFC10207CF854A87CF81224FEFC +8840:0100010002003FF82448244824482448244824482448244824482448FFFE0000 +8841:02000100FFFE1000100010001FF8010002003FF82448244824482448FFFE0000 +8842:08000800107E7F125512555255525552555255925512552257A2FC4200940108 +8843:0800080010FE7F10551055205530555855545592551255105790FC1000100010 +8844:080008FC10247F2455245524552455FC554455445544554457C4FC4401FE0000 +8845:0810081010947F545558551055FC55105510551055FE55105790FC1000100010 +8846:040008003FF824482448FFFE000000F87F0009041188635005201918E1060100 +8847:0804080E10707F405546555855545554555655545554555457D2FC9200980110 +8848:0800087E10247F24553C55245524553C552455245526557C5784FC0400040004 +8849:08200820103C7F4455A85510552855445582557C5544554457C4FC44007C0044 +884A:102410FE2024FE00AAFEAAAAAAAAAAFEAA14AAFEAA90AAD2AFACF8AA00960122 +884B:01003FF80108FFFE01083FF801007D7C11107D7C44447C7C45447FFC2448FFFE +884C:080009FC100020004800080013FE302050209020102010201020102010A01040 +884D:10001200211C410080001400223E6288A0882108270821082108210821282010 +884E:1000100027DC410081001100213E6108AFE82108210821082108210821282110 +884F:100010002F9C400080001FC0253E6508A5082508254829882908300820282010 +8850:1000100027DC44008400178024BE6488A48827882408240827C8200820282010 +8851:11001100229C42408420190020BE6008AFC82048208825082208210821282010 +8852:12001100201C4FC08200140024BE6888AF0821082208220824882F8820A82010 +8853:11001180215C4140810017C0213E6308A3882348254825082908210821282110 +8854:12001200239C4200840017802A3E6208AF882208220822082288230822282010 +8855:20002FE0482E48208BA01820283E6BA4AAA42AA42AA42BA42824282428B42848 +8856:14801480249C44809FE0148024BE6488A4882FE8200824882448284830082018 +8857:1100110027DC4100810017C0203E6108A10827C82108210821C82E0824282010 +8858:1400140027EE4900910011002FDE6104A10425C42504250425C43E0428142008 +8859:10001FC0221C42008F80148024BE6FC8A0082008278824882488248827A82490 +885A:140014E024AE4EA084A014E024BE6EA4AAA42AE42AA42AA42EA4212421342268 +885B:120012002FCE44409FE010002FDE6844AFC421042FC4210429042FE421142108 +885C:144012802FEE4100820017C0245E6444A7C42444244427C42444244427D42448 +885D:108011C0271C410087C0110027FE6548A7C8254827C8210827C821082FE82010 +885E:110017C0224E4FE0800017C0245E67C4A0042FE421042FE42924292429742108 +885F:154015402A8E4540854010002FDE6104A7C4244427C4244427C4244427D42448 +8860:110011002FEE410087C0144027DE6444A7C4244427C424442FE4228424542828 +8861:120013C0244E488087C01540255E67C4A544254427C421042FE4210422942448 +8862:2EE02AA04EEE4AA08EE01AA02EFE6444AFF4348427E4248427E4248427F42408 +8863:020001000100FFFE0200020005000508089018A02840482088100A080C060800 +8864:200010000000FC00080010001000340058009400140010001000100010001000 +8865:1040084000407E400240046008501A482C444A440A4008400840084008400840 +8866:200011FC0020F8200820102014203BFE54209020102010201020102010201020 +8867:200011FC0020F8200820102014203BFE54209020102010201020102010A01040 +8868:010001007FFC010001003FF801000100FFFE0500088818502820C9180A060C00 +8869:200013FC0104F944092410A81088348858509450142010201050108811041602 +886A:202010200020F920092C1134116437A459249534152811221122110210FE1000 +886B:1004080400087E100220044408041A082C104A220A42080408080810082008C0 +886C:201010100010FC1009FE10101010341059109490149010101010101010501020 +886D:202010200020FC2009FC1020102034205BFE9420145010501088108811041202 +886E:02000100FFFE000008201210244848241FF0029004440C283410C50806060400 +886F:201010900090FC8809081104120435FA58889488148810881108110812281410 +8870:02000100FFFE00001FF01010FFFE10101FF0028004440C283410C50806060400 +8871:200013FC0084F88808881090109C348459449544152811281210122814441182 +8872:202010200020FDFE09221122112235225952954A158A110211021102110A1104 +8873:201010900090F8880888112415243A225440904010881084110413FE11021000 +8874:202010200020FDFE09221224102034205850945014501050109010921112120E +8875:2000100001FCFD04090411041104350459FC9504150411041104110411FC1104 +8876:202010200020FC2009FC112411243524592495FC152410201020102010201020 +8877:02000100FFFE01003FF8210821083FF80100028004440C283410C50806060400 +8878:2040104000A0F8A0091012081406311055109910151011101110121012101410 +8879:2004101E01F0FD1009101110111035FE5910951015101108110A114A11861102 +887A:02000100FFFE00007FFC20403FFE02400D407080030804900C603518C6060400 +887B:200010FC0084FC84088411FE10843484588495FE148410841084108410941088 +887C:202010200020FBFE08201020102035FC58849488144810501020105011881606 +887D:2008103C01E0FC2008201020102035FE58209420142010201020102011FC1000 +887E:01000280044009203098CFE6004002800100FFFE05000C883450C530060E0400 +887F:202010200050FC500888114412223420580095FC140410081008101010101020 +8880:204010400080FCFC090412041084344458449414142410441184100410281010 +8881:010001003FF80100FFFE00001FF0101010101FF0050408883850CA200C180806 +8882:202010200020F9FC082410241424382455FE9020105010501088108811041202 +8883:200021FC2C44F04420842484291432080100FFFE05000C883450C530060E0400 +8884:2008103C01E0FC200820102011FE342058209450145010501088108811041202 +8885:04001FE0142012A010401FFC000402140108FFFE05000C883450C530060E0400 +8886:202010200020FDFE0820102010FC3420582095FE14221022102A102410201020 +8887:200010FC0084FC8408A410941094348459FE9484148410841084110411141208 +8888:080008007F7C094411441144257C42000100FFFE05000C883450C530060E0400 +8889:202010100010F9FE0902120410803488589094A014C0108210821082107E1000 +888A:202010200050F850088811241212301055FC9804140810881050102010101010 +888B:08A0109030BE57C0904010241014120C0100FFFE05000C883450C530060E0400 +888C:0100FFFE08001FF020105F9010D01FA010040FFC030004880C503530C60E0400 +888D:2080108001FCF9040A0415F411143514591495F4150411281112110210FE1000 +888E:202011200120F22012FC24A427246924B2242A2424A427A420C4204420942108 +888F:204010400040FC400BFE10401080348058FE9510151012101210141011FE1000 +8890:200010400020F8280808108814903A9456A292A214C210881188128814781000 +8891:200013FC0084F8840884110415143A08540091FC110411041104110411FC1104 +8892:2000100001FCFD040904110411FC35045904950415FC11041000100013FE1000 +8893:200011F80108FD08090811F811083508590895F8150811081108110817FE1000 +8894:2000100003FEF808080811E8112835285928952815E811281008100810281010 +8895:204010200020FBFE0A0214041000349058909490148811081108110412041402 +8896:202010200020FC2009FC112411243524592495FC152411241124112411FC1104 +8897:202010200050FC88090412121020344059889410142010441188101010601380 +8898:2080108000FEFD000A201120112C35745BA49524153411281122110210FE1000 +8899:202010200040FDFC090411041104350459FC9504150411041104110411FC1104 +889A:205010480048FC400BFE1080108034FC59449544152811281210122814441182 +889B:2004101E01F0FD1009101110111035FE5910951015101108110A114A11A61112 +889C:202010200020FDFE08201020102035FC587094A814A811241124122210201020 +889D:208810880088F908097E13081508314855289928150811081108110811281110 +889E:02000100FFFE0820101020085FF4101010101FF004440C283410C50806060400 +889F:202010200120F92009FC11201220302055FE9820145010501088108811041202 +88A0:02000100FFFE11001FF822007FFC048008603298C4440C283410C50806060400 +88A1:202010200020F9FC0924112415FC39245524912413FE11041104110411141108 +88A2:202010200124F8A408A8102015FC38205420902013FE10201020102010201020 +88A3:204811480148F948094813FE1148354859489548157811001100110011FE1000 +88A4:0100FFFE00001FF0022001407FFC048418886280030004880C503530C60E0400 +88A5:2000100003FEF82008201040144038FC55849284148410841084108410FC1084 +88A6:202010200124FD240924112411FC342058209524152411241124112411FC1004 +88A7:208010800100F9FC0A04140411E435245924952415E411241004100410281010 +88A8:204010200020FBFE08401040108835085BF0942014401088110413FC11041000 +88A9:202010200020FC20083E10201020342059FC9504150411041104110411FC1104 +88AA:202010200020F9FC0820102014203BFE5420904010401088110413FE11021000 +88AB:201010100010F9FE09121114151039FC55449144112811281110122812441482 +88AC:02000100FFFE080010103FF800081FF0101010101FF0048808503820CB180C06 +88AD:04400420FFFE0910116021844F0482FC0100FFFE05000C883450C530060E0400 +88AE:208010800080F9FE090012001420302055289924162412221422102010A01040 +88AF:204010480244FA400BFE1080148038FC55449144114812501220145018881306 +88B0:1FF012101110FFFE121021103FFC001002A00140FFFE04880C503420C5180606 +88B1:209010940092F9120910137E1510311055109928152811281128114411441182 +88B2:0100FFFE02000FE034C00700388003F81D3001C03F0004880C503530C60E0400 +88B3:20201020007CFC8409481030102034485990943E144211A41018101010601180 +88B4:2020102003FEFC500888110412FA34005BFE9440148011FC1004100410281010 +88B5:20801088009CF970091013101510311055FE99101510111011101110117C1100 +88B6:2080108000FCF9080A90106011983626582095FC1420122013FE102010201020 +88B7:202010200050F8880904120211FC3400580095FC150411041104110411FC1104 +88B8:204010400040FBFE08801080117835085B10951015FE11101110111011501120 +88B9:200013FE0020FC20084011FC11043504590495FC150411041104110411FC1104 +88BA:202010200020FBFE0820102011FC3400580095FC150411041104110411FC1104 +88BB:200013FE0020FC20084011FC1154355459549554155411541154114411141108 +88BC:2080108000F8F9080B1014A0104034A05918960615F811081108110811F81108 +88BD:410021002100011EF7D2125222526A52B2522C92229221122292225E24522800 +88BE:202011200120F9FC09201220102033FE547098A814A811241124122210201020 +88BF:2020102001FCF8200820102013FE30005420982015FC10201020102013FE1000 +88C0:200011FE0102F9220922112211FE352259229552154A118A1102110211FE1102 +88C1:084008487F4408440840FFFE10400844FF4410442928662AA212292A30462082 +88C2:00047F8408241F24212452240C243004C20C0100FFFE04880C503420C5180606 +88C3:20401040007CFC40084013FE100034005BFE9440145010481044104010401040 +88C4:20401040009CF9000A40104010BE35885A889488148810881088108810A81090 +88C5:082048202BFE082018202820C9FC0A000100FFFE05000C883450C530060E0400 +88C6:2020112400A4FCA408A8102013FC34045804940415FC10041004100413FC1004 +88C7:202010200040F88009FC11541154355459549554155411541154115413FE1000 +88C8:200013FE0202FC44084013FC108034A0592095FC1420102013FE102010201020 +88C9:200011F80108F90809F81108110835F859449548153011201110114811861100 +88CA:04001FF010101FF010101FF010001FFC10001FFC01043FEC04801C486530060E +88CB:200013FC0000FC0009F811081108350859F89400150810881090100017FE1000 +88CC:202010200020FBFE0820102011243524592496AA142010501050108811041202 +88CD:200013FE0222FA220A2213FE16223A62567292AA132212221222120213FE1202 +88CE:200011FC0104F904090411FC1000340059FE9420142011FC1020102013FE1000 +88CF:0100FFFE00001FF011101FF011101FF001001FF001007FFC04880C503530C60E +88D0:200010FC0084FC8408FC100011FE3502590295FE1502110211FE1102110A1104 +88D1:2040108001F8F90809F8110815FA390A550C93F8101810281048118816281010 +88D2:02000100FFFE0400387820083C7820083FF8028004440C283410C50806060400 +88D3:201010140012F8100BFE10101550395457F4915411541148124A125A14261042 +88D4:02000100FFFE048808503A20CC1808063FF82448282837D8244827C820282010 +88D5:200010500048FC840924102010503488590694F8148810881088108810F81088 +88D6:200011FE0100FD00097C1100110035FE59509552155411481148124412521460 +88D7:2040102003FCF8400890110813FC30045550995015501150125012521452180E +88D8:012001107FFC111009A00540193062080100FFFE05000C883450C530060E0400 +88D9:200011FC0044F8440BFE1044104435FC5880948015FC12841484108410FC1084 +88DA:080C08F07E8008800EFE78880888290812080100FFFE04880C503420C5180606 +88DB:0100FFFE00001FF010101FF000003FF821083FF820021FFE04881850EB300C0E +88DC:2028102403FEF820082011FC1124352459FC9524152411FC112411241124110C +88DD:242024203C2005FCFC20242024F846000100FFFE05000C883450C530060E0400 +88DE:210410840088FC1009FC11041104350459FC94501450109010921112120E1400 +88DF:1020082040A824A409227228103010C007000100FFFE04880C503420C5180606 +88E0:3FF80208FFFE04083FF808001FF82808CFF80100FFFE04880C503420C5180606 +88E1:200011FC0124FD2409FC1124112435FC5820942015FC10201020102013FE1000 +88E2:201012100110F97E082010281748357E5908950815FE110811081288147E1000 +88E3:202010200050F8880904120211FC340058449424112410A81088101013FE1000 +88E4:2010100801FEFD10091011FE112035285948957E1508110811FE120812081408 +88E5:210010BE0282F202120222FA228A6A8AB2FA2A8A228A22FA22022202220A2204 +88E6:0100FFFE000019F8609040607BFC40A441287A60030004880C503530C60E0400 +88E7:202010A200A2F9240850108813043022542098A414A411281050108811041202 +88E8:2040108003FCFA240A2413FC16243A4457FC9090111017FE1010101010101010 +88E9:200011FC0104FD0409FC1104110435FC5800951215D41118111011521192110E +88EA:2080108000FEFD020A8210F2114234425BFA94421552115211F2100210141008 +88EB:205012520252F25213DE220222026BFEB2022A0223DE22522252225224522802 +88EC:2020102001FCFC20082013FE108835445A4294F8158812501020105011881606 +88ED:20201020003EFC2009FE1122113835E05922951E150011781248124A148A1906 +88EE:20FC10840084FCFC0884108410FC340059FE9502150211FE1102110211FE1102 +88EF:200011FC0124FD240974112411FC350459749554155411741104120412141408 +88F0:200017BC0084F2941108229424A46840B0002FBC20A422A42128229024A82846 +88F1:2020102003FEF820082011FC102034205BFE944014A411A81290148810C61080 +88F2:200013FE0020F02013FE222222226B32B2AA2AAA2376226622222222222A2204 +88F3:0100111009207FFE40029FF410101FF00100FFFE05000C883450C530060E0400 +88F4:044004407C7C04403C7804407C7C06400100FFFE05000C883450C530060E0400 +88F5:02000100FFFE04407C7C04403C7804407C7C0440030804900C603518C6060400 +88F6:209010900090F79E1090209020906B9CB09028902090279E2090209020902090 +88F7:2020112400A8F82009FC104017FE3888550492FA1488108810A810921082107E +88F8:200011FC0124F92409FC1124152439FC542093FE107010A81124122210201020 +88F9:0100FFFE00001FF011101FF011101FF00100FFFE131065880C503530C60E0400 +88FA:2020102003FEF85008881124122231FC552499FC152411FC10221022101E1000 +88FB:08000E7C08047F4408282A1049281A440100FFFE05000C883450C530060E0400 +88FC:200011F80108F90809F81108150839F8548091FC125414941124124410941108 +88FD:24043FA44424FFA404243F842494258802000100FFFE04880C503420C5180606 +88FE:200013FC0204F20413FC222022206BFEB2202A2022FC22842284248424FC2884 +88FF:2020102001FCFC500888110413FE340859E89528152811E81128100810281010 +8900:2088108803FEFC88088810F81088348858F89488148813FE1000108811041202 +8901:00001FF011101FF011101FF00100FFFE09201110630804900C603518C6060400 +8902:2110111007D0F110111021182FF46812B112291027D02110211021D02E102410 +8903:20201120013CFD20092013FE100035FC590495FC150411FC1104110411141108 +8904:2020102003FEF82009FC102413FE342459FC944017FE108411C8103010CC1302 +8905:2040102001FCF8000888105013FE3222542499FC152411241134112810201020 +8906:200011FC0104FD0409FC1104110435FC580097FE14201120113C112012A0147E +8907:2100110001FEFA000DFC110411FC350459FC948014FC11081290106011981606 +8908:2008103C01E0F8200BFE102011FC352459FC952415FC102011FC102013FE1000 +8909:2100113C07D4F1141394211427D46924B14C284027FE204020A0211022082C06 +890A:2080104003FCF204120423FC22006A00B3FC2B54235425FC255425542944210C +890B:204811480148FBFE094811481578390055FE902013FE107010A8112416221020 +890C:200013FE0222F8200BFE102011FC352459FC952415FC102013FE102010201020 +890D:202011240124FD2409FC100013FE3420584095FC15541154115411541154110C +890E:02000100FFFE00180CE0302021FC3CA821243C20030804900C603518C6060400 +890F:0100FFFE00200C2031FC21243DFC212421243DFC030004880C503530C60E0400 +8910:200013F80208F3F8120823F821006BFCB4442A4422A4220423F4200420282010 +8911:201E13E00044FD24088811FC104034405BFE948014FC11441128121010681186 +8912:0100FFFE08000BF8120833F8504097FE11501248030004880C503530C60E0400 +8913:2100117C0144F2441244267C2A106A10B2FE2A38225422542294231222102210 +8914:200013FE0000F9FC0904110415FC380057FE9222122213FE1222122213FE1202 +8915:204010A00110F20815F6200023C46A54B2542BD42254225423D42244225422C8 +8916:208010FC0104FDF8080813FE104034A25B349458149413341052109013501020 +8917:200013FE0200FAFC0A8412FC16843AFC562093FE124812C812301248128413FE +8918:2040104001FCF8840BFE100015FC390455FC902013FE1020122013FE10201020 +8919:2050105203DCF85008D2134E100035FC590495FC150411FC1104110411141108 +891A:2020102201FAF824082813FE1420384054FC9184128410FC1084108410FC1084 +891B:2020112400A8F02013FE20A821246A02B0402BFE208821082190206021982604 +891C:008079F84A087DE8492879E8491449049AFC0100FFFE04880C503420C5180606 +891D:224211240000FDFC0924112411FC3524592495FC1420102013FE102010201020 +891E:200011F80108F90809F81108150839F8540093FC129412941294129417FE1000 +891F:200011FC0104F9FC090411FC14003BDE54429252114A10C6135A1042114A1084 +8920:2088108803FEFC8809FC108813FE342059FC952415FC112413FE110411141108 +8921:2088108803FEF888082010501488390456FA9000100011FC1104110411FC1104 +8922:0100FFFE02001FF011101FF012101FF004A808BA3382C4FE0C503530C60E0400 +8923:2040102003FEFA0208501088152438505488910412FA10881088108810F81088 +8924:2020102001FCF8200BFE100011FC3504590495FC14521094118816A410C21080 +8925:200013FE0200F2FC120023FE22A86A90B2C82A86220823FE2288244824082818 +8926:211012120454F7D81010201227D26C4EB4402FD22454245827D024522552248E +8927:7E1024523C5424903C282744FC8206000100FFFE05000C883450C530060E0400 +8928:210810880090FBFC084011F814403BFE5480910011FC12201420182013FE1000 +8929:10003E7822482A48FE8623782A4842304A4886840100FFFE06801C48E530060E +892A:2000127C0144F944087C10441744357C5950954A15441154116211421280147E +892B:2004101E03F0F21E121022FE22926A98B2F22A8E228022B822A824AA254A2A86 +892C:21F810880070F18C100023DE2252698CB252282023FE207020A8212426222020 +892D:0100FFFE00003FFC21003FF821003FFE29224496030004880C503530C60E0400 +892E:08202AA44D28145022887FFE400282040100FFFE05000C883450C530060E0400 +892F:2040102007FEF488148827FE24886CF8B4202DFC252425242934292830202020 +8930:01007FFE44429FF404403FF80440FFFE0A2011102FE8C28E04501C2065180606 +8931:02000100FFFE00003FF824483FF8111009201110230804900C603518C6060400 +8932:2020101001FEFD10097C1110117C3554597C9554157C111011FE121012101410 +8933:2010101002FEF910097C1054147C3B54557C911011FE111011101290147E1000 +8934:20481148014EF9500968114411443440580095FC155411541154115417FE1000 +8935:2040102003FEF80009541124155439FC542093FE1242129212FA120A12021206 +8936:200013DE0042FA52094A12521042342059FC9504150411FC1104110411FC1104 +8937:221012100450F95C1150225026FE6A00B2102A50225C225022B02290230E2200 +8938:202011FC0124FBFE092411FC142039FC552491FC104013FE108811D01070138C +8939:2110111007D0F110113C27D420146AB4B554291C27D42114211421E427262242 +893A:08207E2008F8FF2814287F6A082AFF560A820100FFFE04880C503420C5180606 +893B:0100FFFE08203E2008F87F282A685D2A08563E82030004880C503530C60E0400 +893C:400023FE205003FEF25213FE20206FFEB088290423FA250821F82102210220FE +893D:3F0821083F7E20082F4820285FA8440895282E900100FFFE06801C48E530060E +893E:200013FE0050FDFC0954115411FC340059FC940017FE102010A8112412A21040 +893F:2090109007FEF8900BFC129413FC36945BFC940015F8110811F8110811F81108 +8940:202013FE0020FDFC082013FE100035FC590495FC150411FC110411FC10881104 +8941:200013BE00A2F0A210BE238822086A3EB22A2BAA20AA20BE2088208A257E2202 +8942:2040108801FCF9080A5213FE14503988562690C0131010641388103010C01700 +8943:0100FFFE00000CF8308820F83C2021FC20A83D24030004880C503530C60E0400 +8944:0100FFFE00003EF822883EF804407FFC04403FF80440FFFE04441C28E5180606 +8945:200011FC0124FDFC092411FC10A834A85BFE94A814A811FC102013FE10201020 +8946:205012520154F8500BFE108814503BFE542091FC102013FE1050108811041602 +8947:200013DE0252FBDE0A5213DE16023AFA568A92FA128A12FA128A1202120A1204 +8948:200013DE0252FBDE0A10125211CE3400588897FE1488108817FE108811041202 +8949:279E1492079EF492179E240224F26C92B4F22C9224F224922492253224022406 +894A:200013F80208F3F8120823F820006FFEB4802FBC2494279424D42F88209420A2 +894B:420822080FBEE20822082FBE4AAA5AAAEAAA5BAE4208471C4AAA524842084208 +894C:200013DE0252FA520BDE100011FC352459FC952415FC102013FE102010201020 +894D:20A0109001FEFB2009FC112011FC352059FE9500142013FE107010A813261020 +894E:203C13E00124F8A80BFE10A81124360259FC9524152411FC1124112411FC1104 +894F:202413A80092F5141208240423BA68A8B0C62B80223C238420A8209022A82144 +8950:208010F80108FBFE0D12112215FE384054A29354109813341054109213501020 +8951:200011FC0004FCFC080411FC100035DC589497DC140813FE1108108810A81010 +8952:210811080548F390111E27D425646D54B5542F5425D4254825482554246424C2 +8953:2020102001FCF8200BFE1108139C35085988963E140013FE109010901112120E +8954:2088108803FEF888088810F814203BFE5622933212AA137612221222122A1224 +8955:210010BE0282F22212FA222222FA6AAAB2BA2AEA22AA22FA227222AA22222226 +8956:2080110007FCF4441554244427FC6CE4B5542C0420402FFE20A0211022082C06 +8957:200011FC0154F9FC082011FC14203BFE5488905011FC102013FE102010201020 +8958:202010500088FD740A0211FC112435AC592495FC140010F8108810F8108810F8 +8959:20F810880088FCF8080011DC1154355459DC942015FE107010A8112412221020 +895A:204412240128FC7E08101028134A351C5928954C151A112A1148111012FE1400 +895B:209013FC0294FBFC0A9413FC14003BFC560092F8120013FE1520151415481986 +895C:208010F80108FBFE0944119211FE3500597C9500157C1100117C1244127C1444 +895D:202010200050FC88090412FA1000340059DC9554155411DC1088108811541222 +895E:00407C2045FC44887C5043FE7C20A5FC24203E200100FFFE06801C48E530060E +895F:2110111007BCF11013B8255429126800B3F8280027FC20402248244429422080 +8960:2020112400A8FBFE0A0210F81088348858F8940015FC112411FC112411FC1104 +8961:200013F802A8F2A813F8210023FC6C84B3E42AA422A423E4209427F420142008 +8962:202013FE0000FBFC0A0412F4129437FC580095F8150811F8110811F8100013FE +8963:204010F80088FCF8088810F8100035FC592495FC152411FC100013FE10881108 +8964:200813E80288FBEE0A2813F416823BE2540091FC115411541154115417FE1000 +8965:212811AA016CF22812FE264426286AFEB2102A7C221022FE2210222822442282 +8966:200011FC0020FBFE0A2211AC142039AC540093FE102011FC115411541154110C +8967:200017FC0248F4441FFE244426EC6D54B6EC2C4426EC255426EC244424542408 +8968:214411440554F364115E27E420046A34B14C2BE4208423E4208420E427142008 +8969:202013FE0020FDFC080013FE125237FE590495FC150411FC110411FC10881104 +896A:210817FE0108F00013FC229422946BFCB0282BFE2220232422A82292242A28C6 +896B:2020102007FEF02013AE212423AE6AAAB3AE2AAA23AE20502050208821042602 +896C:200013FC0294F29413FC211022526BDCB0122BCE224023D2225C23D0225222CE +896D:2100113E0108F7D0113E212223A2683EB0222BBE22A222A222BE238022942022 +896E:21FC110401FCFD0409FC108811FC34885BFE9488152412AA107010A811241060 +896F:4200213C27A40024F4BC132427A4693CB1242FA4213C259025582968252A2246 +8970:2108110807CEF112112427DE25526D5EB7D2291E2392255E2940211421122122 +8971:2210111007DEF010145E228227DE6810B7DE2C5027DE245027DE2450245224CE +8972:08407F7C1440FF7C22043E7C22403E7C2242263E0100FFFE06801C48E530060E +8973:4148214C22AA0008F7FE11482368694AB36A294C236C2148216A239A20262042 +8974:27BC14A407BCF4A417BC244425F46C44B5F42D5425F4255425F424E42554244C +8975:23FC110801F8F10811F8210E27F86808B7FE2A94239C2294239C22D627BC2084 +8976:411427D221100FFEF01017D025526FD2B5522FD4229427C8228A2FFA22A62442 +8977:2140126C0244F36C12A423AC22A46FFEB1082AF4244223F8204027FC204020C0 +8978:252817BE0948F7BE131825AA29466BFCB2042BFC220423FC220423FC21082204 +8979:27BE100007BCF4A416B424A420406FFEB4A02FFC24A427FC251229DC291231CE +897A:211017FE0110F00017FE254A254A6EFEB7EA2D6A267E27CA244E257225422406 +897B:22A8124807BEF2A8175C2AAA22886FFEB2182DE4284223F8204027FC204020C0 +897C:210817FE0108F390113C27D422B46D5CB396292223FC200027FE2080210423FE +897D:211017FE0110F7BC14A427BC24A46FBCB4442FFC255425F4244424E425542448 +897E:0000FFFE0440044004407FFC444444444444444447C444444004400440044004 +897F:0000FFFE0440044004403FF8244824482448244828383008200820083FF82008 +8980:00007FFC044004403FF8244824483FF800000000000000000000000000000000 +8981:00007FFC044004403FF8244824483FF802007FFC042008401C80038006703808 +8982:FFFE04403FF824483FF8000001F03E0001007FF80060018006001800E7FE0000 +8983:FFFE04403FF824483FF800001FF010101FF010101FF00100FFFE010001000100 +8984:00007FFC04403FF8244824483FF80850104837FE504090A010A0111012081406 +8985:0040FE402840287EFEAAAB2AAA2AFE4A104AFE9225124422282210422894C408 +8986:FFFE04403FF824483FF8120027FC42088BF8120833F8510093F8151010E0171E +8987:FFFE04403FF824483FF822007F7C22443E44087C7F4449447F7C0844FF540888 +8988:FFFE04403FF824483FF810207E20523E4A447EA41028FF2820103E2842448682 +8989:FFFE04403FF824483FF828207DFC2850388813FE7C0855E87D2811E8FE081018 +898A:FFFE04403FF824483FF82800FDFE292039FC11207DFC55207DFE1002FEAA1004 +898B:00001FF0101010101FF0101010101FF0101010101FF00440044008423042C03E +898C:000001F8FD08050805F84908290811F81108290825F844908090011202120C0E +898D:010009201110210841041FF010101FF010101FF010101FF0044008421042603E +898E:00007E7C420442087E10421042FE7E10421042107E1024502422240243FE8000 +898F:100010FC10847C8410FC10841084FEFC1084108410FC2850245044928092010E +8990:00007E88425042207E50428842007E88425042207E5024882402240243FE8000 +8991:080048FC4884488448FC7E84408440FC40847C8444FC4450445044924492850E +8992:04000EFC7084108410FC1C84708410FC10841E84F0FC1050145018921092010E +8993:000801FC7E102210112000001FF010101FF010101FF010101FF004421842E03E +8994:00007FFC010003600D1871041FF010101FF010101FF010101FF004421842E03E +8995:1000087C0A440244127C134454C454FC54449844197C112831284F4A804A0086 +8996:200011FC1104F90409FC1104110439FC5504950411FC1050109010921112120E +8997:00007F7C014401447D7C014401447D7C454445447D7C45280128014A0A4A0486 +8998:100010FC10841E8410FC1084108410FC7E84428442FC425042507E924292010E +8999:200020FC20847E8442FC4484908410FC5484548452FC5250925010925092210E +899A:2208111000207FFE40029FF410101FF010101FF010101FF0044008421042603E +899B:0200077C38442044237C2C44284428FC2D442A442A7C29282928494A4C4A8886 +899C:280028FC28842884AAFC6C84288428FC6C84AA8428FC28502A504C924892810E +899D:00007CFC10841084FEFC1084108400FC1084528452FC9450285024924492810E +899E:00007CFC448444847CFC448444847CFC448444847CFC28502A502C924892810E +899F:0800087C0844FF44087C084408447E7C104408442A7CA128A128A54A1C4A0086 +89A0:00007E7C12441244FF7C124412447E7C204420447E7C6228A228224A3E4A2286 +89A1:0000007C7F440844087C2A442A442A7C5D444944887C08280F28F04A404A0086 +89A2:100052FC5484908428FC4484828410FC1084528454FC9050285024924292810E +89A3:0C0070FC1084FE8438FC5484928400FC1084FC8424FC4450285010922892C50E +89A4:10001EFC10847E8452FC5C84708452FC4E8440845CFC5450545096929492210E +89A5:1400147C14447F44557C554455447F7C55445544557CFFA82428224A424A8086 +89A6:1000287C444482447D7C0044F144957C9544F544957C9528F528914A954AB286 +89A7:3F2024203F3E21403F5024883FF810101FF010101FF010101FF004421842E03E +89A8:0000777C55445544777C00447F44007CFFC420443F7C01280128014A0A4A0486 +89A9:1000107C7D441244147CFF441044207C7E44A244227C3E282228224A3E4A2286 +89AA:1000087C7F440044227C1444FF44087C08447F44087C2A28492888CA284A1086 +89AB:1000087C7F440044227C14447F44517C08447F44107C1E281228224A2A4A4486 +89AC:0800497C49447F44007CFF4400447F7C414441447F7C422824280F4AF04A4086 +89AD:0000FF7C814400447E7C42447E44427C7E441044087CFF280028244A424A8186 +89AE:08202AA44D28145022887FFE40029FF410101FF010101FF010101FF00842F03E +89AF:2200227CFFC422447F7C2244FFC4087C7F4449447F7C4928FFE8414A454A4286 +89B0:10001E7C10447F44517C5C4472444E7C40445E44527C5E2852285E4A524ABF86 +89B1:08047F7808403E402A7E3E482A48FF4808881FF010101FF010101FF00442783E +89B2:2200227CFFC422443E7C08447F44497C7F4408447F7C08287F28084A0F4AF086 +89B3:2000207C3F444844887C7F441444227C7F44A4443F7C24283F28244A3F4A2086 +89B4:0A00747C15445244227C21445D44807C7E444244427C7E284228244A0F4AF086 +89B5:E700A57CE744A544E77C8144BD44A57CBD44A544BD7CA528A528CD4A814A8386 +89B6:0F00F07C49442244FE7C14440844FF7C9544BD44837CBD289528894A954AA386 +89B7:10001E7C10447F44517C5C4472444E7C40444A446AFC5B284A288F4A784A0086 +89B8:0000777C55447744557C774441445D7C55445D44557C5D285528414A454A4286 +89B9:0144F9548B548DF8F80E89128AEAFE0A8A0A8AEAFAAA52A452B456AA5B0A9210 +89BA:3AB821083AB82288393822887FFE50129FF410101FF010101FF004421842E03E +89BB:08000F7C08447F44497C4C447944477C40445F44407C5F2851285F4A8A4A3F86 +89BC:0000FF7C52449144FFFC9144DB44B57CDB449144DB7CB528DB28914A954A8286 +89BD:7E40487E7E9043087EFE48AA7FFE10101FF010101FF010101FF004421842E03E +89BE:1000087C7F444144867C784449442A7CFF442A44417CBE282A283E4A2A4A3E86 +89BF:1000FEFC10847C8400FCFE84AA84FEFC44847C8444FC7C5044507C922892450E +89C0:2200227CFFC42244777C55447744127C3F446444BF7C24283F28244A3F4A2086 +89C1:00001FF01010101011101110111011101110129012900480048008823082C07E +89C2:000001FC0104FD0405240524492429241124115428502490449081120212040E +89C3:00003E7C220422082A102A102AFE2A102A102A10081014501422240243FE8000 +89C4:100011FC11047D04112411241124FF241124115410502890249045128212040E +89C5:01F87E0012100910092000001FF010101110111011101290028004821882607E +89C6:200011FC1104F90409241124112439245524955410501090109011121212140E +89C7:100011FC11041F0411241124112411247D2445544450449044907D124612040E +89C8:04402440247C2490250804001FF010101110111011101290028004841884607C +89C9:2208111000207FFE400280041FF010101110111011101290028004841884607C +89CA:0800497C494449447F5400547F54015401543F542010202823282C4A308A0106 +89CB:0000007C7F44084408542A542A542A545D544954881008280F28F04A408A0106 +89CC:0800087C7E4408440854FF5401542A54185448542810FF281428224A414A8186 +89CD:1400147C14447F445554555455547F54555455545510FFA82428224A428A8106 +89CE:1000287C444482447D540054F15495549554F55495109528F528914A954AB286 +89CF:2400247CFF4424447E542454FF5408547E544A547E104A28FF28424A4A4A4486 +89D0:2200227CFFC422443E5408547F5449547F5408547F1008287F28084A0F4AF086 +89D1:10001E7C10447F4451545C5472544E5440544A546A905B284A288F4A784A0086 +89D2:080008001FE020204040BFF8210821083FF8210821083FF82108410841288010 +89D3:100410041F2421244224BFA424A424A43FA424AC24B43FA42484448442848104 +89D4:101010101F102110427EBF92249224923F92249224923F92249244A242AA8144 +89D5:1080108050F851087E1055FC912411241DFCF124512411FC1124122412141408 +89D6:20202020782049FC90247C24542454247DFE542054507C505488548845048E02 +89D7:1004101E3CF024904890BE902A902AFE3E902A902A903E882A8A4AAA42C68682 +89D8:101010103C1024104854BE522A522A903E102A142A043E082A084A10422086C0 +89D9:100010FC3C4424484848BE502A5C2A443E442A442A683EA82A904A9843248642 +89DA:2008201C79F0495091507D50555055507D50554855487D685554567446528C00 +89DB:100010003CFC24844884BE842AFC2A843E842A842AFC3E842A004A0043FE8600 +89DC:088028882EF028842E84F07C08000FC010803FF851081FF811081FF811082118 +89DD:1004101E3CF024904890BE902A902AFE3E902A902A903E882A8A4AAA42D6868A +89DE:104010403C7E2480497CBE082A102A203EFE2A4A2A4A3E922B124A2242548688 +89DF:101010103C7C24104810BE102AFE2A003E102A102A7C3E102A104A1042FE8600 +89E0:111009207FFC0200FFFE08203818CFC610803FF851081FF811081FF811082118 +89E1:104010403C7824884950BE202A502A883F062AF82A883E882A884A8842F88688 +89E2:08007F7C08243E2408447F5408880FC010803FF851081FF811081FF811082118 +89E3:100010FC3C2424244854BE882A102A503E7C2A902A103EFE2A104A1042108610 +89E4:2040204078FC490492087DFE5500557C7D44554455547D4855425542453E8E00 +89E5:20202020792448A490A87C2055FE54907C90549054907C9255125512460E8C00 +89E6:20202020782049FC91247D24552455247DFC552454207C28542457FE45028C00 +89E7:108810483C50240049FCBE202A202AFC3E202A202BFE3E202A204A2042208620 +89E8:200021FC7820482093FE7C00542054227FB254B454A87D285524562444A28C40 +89E9:202820247824482093FE7C20552054B27CB4546854A87D245622542044A08C40 +89EA:104010203CFC24004888BE502BFE2A203E202A202AFC3E202A204A2042208620 +89EB:2020202079FE482090207DFC552455247DFC542054707CA85524562244208C20 +89EC:20002040799C490491047DDC550455047DFC545054507C505490549245128E0E +89ED:2020202079FC485090887D0457FE54087DE8552855287DE85528540844288C10 +89EE:100010FC3C042404487CBE042A042AFE3E102A922A543E382A544A9242508620 +89EF:21042088785049FC91247D2455FC55247D2455FC54207C2057FE542044208C20 +89F0:102010203CFA24244828BFFE2A202A403EFC2B442A443E7C2A444A44427C8644 +89F1:00283FFE20202FA420282F9048AA4FC690823FF851081FF811081FF811082118 +89F2:208820507BFE482091FC7C2057FE54007CA054FC55207C2057FE542044208C20 +89F3:0800FFB808287F280028FFC6A0803E7C4224FF2449287F2849107F2849448B82 +89F4:1040107E3C80257C4844BE7C2A442A7C3E002AFE2A403EFE2B2A4A4A42928626 +89F5:2048204879FC484890487DFE542055FC7D2455FC55247DFC5400544844848D02 +89F6:200021DC7954495491DC7C0055FC55247DFC552455FC7C2057FE542044208C20 +89F7:0A803138228839382288FFFE88020FC010803FF851081FF811081FF811082118 +89F8:200021FC7954495491FC7C8055FC56447DF4555455547DF4544455F444148C08 +89F9:105010483CFE259048FCBE902AFC2A903EFE2A002AEE3EAA2AAA4ABA42828686 +89FA:48F8705044203DFC20247CB890A07D7E2A004FF010202FF848880FF808881098 +89FB:212421747A584ADA93FE7D5456DA57FE7CA2542057FE7C7054A8552446228C20 +89FC:208020F879084BFE91227D5254FC54847CFC548454FC7C4054FC554444388CEE +89FD:2010211279FE484890FE7D9056FE54907CFE549054FE7C8055DE555245728D06 +89FE:208820887BFE488890F87D04557457567D54555457747D0654005554452A8E2A +89FF:222223FE789049FE93107DFE551055FE7D1055FE54007DFE554A55F645528D76 +8A00:02000100FFFE000000003FF8000000003FF8000000003FF8200820083FF82008 +8A01:200010001000FE0000007C0000007C0000007C004400440044007C0044000000 +8A02:2000100011FEFE2000207C2000207C2000207C204420442044207C2044A00040 +8A03:204010401040FE4000407C5000487C4400447C404440444044407C4044400040 +8A04:2040202023FC2000FDF8240025F8240025F82508250825FA250A440243FE8000 +8A05:204010401040FE4001F87C4800487C4800487C484448444A448A7C8A45060200 +8A06:200410041084FE8400847C8400847C84008C7C9444E4448444047C0444040004 +8A07:100010001FFC20044204BFE400041FC400041FC400041FC410441FC410540008 +8A08:202010201020FE2000207C2003FE7C2000207C204420442044207C2044200020 +8A09:200011F00110FD100110791001907950015079104910491249127A124A0E0400 +8A0A:200013F00090FC900090789000907BF00090789048904892488A788A48860082 +8A0B:204010401040FEFC00847D0400047D0400847C444444440444047C0444280010 +8A0C:2000100010FCFE2000207C2000207C2000207C204420442044207C2045FE0000 +8A0D:200011F81088FEC800A87CA800887C5000507C504420442044507C8845040202 +8A0E:201010101010FE1001FE7C1000107C1001107C904490441044107C1044500020 +8A0F:200010FC1020FE2000207C2000207DFE00207C204420442044207C2044A00040 +8A10:200010FC1020FE2000207C2000207DFE00207C204420442044207C2044200020 +8A11:202010201020FEA000AC7CB400E47DA400A47CB444A844A244A27C82447E0000 +8A12:2000100010FCFE2400247CA400A47CA400A47D244424444444447C8445280210 +8A13:210411240124FD240124792401247924012479244924492449247A244A040404 +8A14:0100210821083FF802000100FFFE00003FF800003FF800003FF820083FF82008 +8A15:202010201020FE2001247D2401247D2401247D244524452445247DFC44040000 +8A16:204010401080FEFE01007E0000FC7C0800107C204440448045027D0244FE0000 +8A17:2008103C11E0FE2000207C2000207C3E01E07C204420442244227C22441E0000 +8A18:2000100010FCFE0400047C0400047CFC00847C804480448044827C82447E0000 +8A19:204010401040FDF800487C4800487D4800C87C4844A844A8448A7D0A45060202 +8A1A:200017FC020441045FF440044FE440044FE440044FE4482448244FE44824400C +8A1B:20A010A000A0FD2401247B2805307920016079A04920492249227922491E0100 +8A1C:201010501050FE5000887C8801047EFA00487C484448444844887C8845280210 +8A1D:200011FC1010FE9000907C9001107DFE00307C504450449045107E1044500020 +8A1E:2008103C11E0FE2000207C2003FE7C2000207C504450445044887C8845040202 +8A1F:200810481048FE4800447C8400A47D2200207C404440444844847DFE44820000 +8A20:200411E40024FC24002479E401047904010479E4482448244824782449440084 +8A21:202010201050FE5000887D4402227C2000007DFC4404440844087C1044100020 +8A22:2004100E10F0FE8000807C8000FE7C8800887C884488448844887D0845080208 +8A23:202010201020FDFC00247C2400247C2403FE7C204450445044887C8845040202 +8A24:200810881050FE2000507C8801007C0800887C884450445044207C5044880306 +8A25:202010200020FC2003FE7A2202227A2202527A4A4A8A4B024A027A024A0A0204 +8A26:202010200020FDFE01227A24002078200050785048504850489078924912020E +8A27:204010501048FE4800407DFE00507C5000507C504490449044927D12450E0200 +8A28:201010101010FE9000907C90009E7C9000907C904490449044907C9045FE0000 +8A29:200010080108FC8802527A5202227A2202527A924B0A4A0A4A027BFE48020000 +8A2A:204010201020FDFE00407C4000407C7C00447C444444444444847C8445280210 +8A2B:200010400020FC100090788000807A8402827A824A824C884888788848780000 +8A2C:202010201020FEA800A47CA201227D2002247C244428440844107C2044C00300 +8A2D:200010F81088FE8800887D0602007DFC00847C844448445044207C5044880306 +8A2E:200011FC0088FC880088788800887BFE00887888488848884888790849080208 +8A2F:200013FC0084FC8800887890009C788401447944492849284A107A2844440182 +8A30:202010200020FBFE0020792401247924012479FC4824482048227822481E0000 +8A31:208010800080FDFC01207A200020782003FE7820482048204820782048200020 +8A32:202010200020FC2001FC792401247924012479FC492448204820782048200020 +8A33:200011FC0104FD040104790401FC792401207920491049104A087A0844040802 +8A34:2008101C01E0FD000100790001FE7910011079304918491449127A104A100410 +8A35:2000100003FCFE9402947A9402947A9402947A944A9C4B044A047A044BFC0204 +8A36:2000100003FEFC08000879E8012879280128792849E849284808780848280010 +8A37:202010200020FDFC01247924012479FC01247924492449FC4924782048200020 +8A38:201C10E01020FE2000207DFE00207C7000707CA844A8452446227C2044200020 +8A39:202010281024FC2003FE7C2000707C7000A87CA84524462244207C2044200020 +8A3A:202010200050FC8801047A120020784001887810482048444988781048600380 +8A3B:204010200000FDFE002078200020782001FC782048204820482078204BFE0000 +8A3C:2000100003FEFC200020782001207920013C7920492049204920792047FE0000 +8A3D:208010800100FDFC02047C0401E479240124792449E449244804780448280010 +8A3E:088028882EF028842E84F07C01007FFC00003FF800003FF800003FF820083FF8 +8A3F:209010900090FA9002927AD402987A9002907A904A904A924AD27F124A0E0000 +8A40:202010201020FE20003E7C2000207C2001FC7D044504450445047D0445FC0104 +8A41:202010200020FC2003FE78200020782001FC7904490449044904790449FC0104 +8A42:208810880088FD08017E7B080508794801287928490849084908790849280110 +8A43:202010101010FDFE00207C2000447C8401F87C104420444444827DFE44820000 +8A44:202010200120FD2001FC79200220782003FE7820485048504888788849040202 +8A45:202010201050FE5000887D2402127C1001FC7C044408448844507C2044100010 +8A46:2004101E11F0FF1001107D1001107DFE01107D1045104508450A7D4A45A60112 +8A47:202010200020FDFC012479240124792401247BFE482048504850788849040202 +8A48:00003FF8244824483FF80100FFFE00003FF800003FF800003FF820083FF82008 +8A49:41002100013EF91207D27252025272540254749452885108529474A458420080 +8A4A:202010201124FEA400A87C2001FC7C2000207C2047FE442044207C2044200020 +8A4B:200011FC0104FD040104790401FC78500050785048504892489279124A0E0400 +8A4C:208810881088FE8801FE7C8800887C8800887CF84488448844887C8844F80088 +8A4D:204811480148FD4801487BFE0148794801487948497849004900790049FE0000 +8A4E:200010FE1080FE8000807CFC00847C8400847C8444FC448044807C8044FE0000 +8A4F:201010900090FD10017E7A5203927892011279124A524BD248627822484A0084 +8A50:208010801080FCFE01407D4002407C7C00407C404440447E44407C4044400040 +8A51:202010101010FEFE00827D0400407C4800507C604440444244427C42443E0000 +8A52:202010201020FE4000487C8401FE7C8200007CFC4484448444847C8444FC0084 +8A53:202010201020FDFC00207C2000207DFE00207C204440444844847DFE44820000 +8A54:200011FC1044FE4400447C4400947C8801007CFC4484448444847C8444FC0084 +8A55:200011FC1020FE2001247CA400A87C2003FE7C204420442044207C2044200020 +8A56:201010100010FDFE01127914011079FC014479444928492849107A284A440482 +8A57:200011FE1102FF0201027D7A014A7D4A014A7D4A457A454A45027D02450A0104 +8A58:202010200124FD240124792401FC782000207924492449244924792449FC0004 +8A59:205010480048FC4003FE7880008078FC01447944492849284A107A2844440182 +8A5A:2000100010FCFE8400847C8400FC7C8400847C8444FC448444007C0045FE0000 +8A5B:200010F81088FE8800887CF800887C8800887CF84488448844887C8845FE0000 +8A5C:202011240124FD2401FC782000207BFC01047888488848504820785049880606 +8A5D:204010200020FDFE01027A040000780001FE7820482048204820782048A00040 +8A5E:200011FC1004FE0401F47C0400047DF401147D1445F4451444047C0444280010 +8A5F:04800440FFFE0940118466FC01007FFC00003FF800003FF800003FF820083FF8 +8A60:204010200010FDE00022783403B878B000A878A8492849244A247C2248A00040 +8A61:200013DE0042FC420252794A014A784200C6794A4A52484248427842494A0084 +8A62:2080108001FCFD04020479E40124792401E47924492449E44904780448280010 +8A63:208010841098FEE000827C82007E7C0000FC7C84448444FC44847C8444FC0084 +8A64:201011101110FF2801447D0001FE7C0000A87CA844A844A844A87CAA452A0206 +8A65:202010201050FE5000887D0402FA7C0000007CF84488448844887C8844F80088 +8A66:201010140012FC1003FE7810001079D0009078904890488848EA7B8A48060002 +8A67:108010803EFC62449448483031102FE8C0061FF000001FF000001FF010101FF0 +8A68:204010200020FDFE0000788801047A0200887888485048504820785048880306 +8A69:202010200020FDFC0020782003FE7808000879FE480848884848780848280010 +8A6A:200011F80108FD0801F87908010879F801447948493049204910794849860100 +8A6B:2040102003FEFA020000783803C078400040787C4BC0484048427842483E0000 +8A6C:2008101C01E0FD00010079FE01007900017C79444944494449447A7C4A440400 +8A6D:2040104000FCFD04020879FE0100797C014479444954494849427A424A3E0400 +8A6E:202010200050FC8801047A0201FC78200020782049FC4820482078204BFE0000 +8A6F:202010200040FDFC01047904010479FC0104790449FC49044904790449FC0104 +8A70:202010200020FBFE0020782001FC7800000079FC490449044904790449FC0104 +8A71:2008103C11E0FE2000207DFE00207C2000207DFC4504450445047D0445FC0104 +8A72:202010101010FDFE00207C2400447CF800127C224444458844107C2844440182 +8A73:210410840088FC0003FE7820002079FC002078204BFE48204820782048200020 +8A74:2020102011FEFE4000407CFC00847D8402FC7C84448444FC44847C8444940088 +8A75:202011200120FDFC01207A2000207BFE0090789048904890491279124A12040E +8A76:208210920092FC920092789202DA7AB604927892489248924892791249020202 +8A77:200011FE1102FF02017A7D0201027D7A014A7D4A454A457A45027D02450A0104 +8A78:202010200124FCA400A8782000207BFE007078A848A8492449247A2248200020 +8A79:08000FF010203FFE6508A8843FFE200027F8200027F8200027F8440847F88408 +8A7A:20201020107EFE8201447C2800107C2000407CFE4542444244427C42447E0042 +8A7B:2080108000F8FD0803107CA0004078A001187A064DF849084908790849F80108 +8A7C:204010400040FDFE0080789000907912015279544A904A284C28784448840102 +8A7D:200011DC0088FC880088788800887BDE00887888488848884888790849080208 +8A7E:210011000100FDFE02027A02051278A2024A7AAA4B1A4A0A4BFA780248140008 +8A7F:2020102001FCFC200020782003FE78000020782049FC4820482078204BFE0000 +8A80:200013FE1088FE8800F87C8800887CF800887C88448E47F844087C0844080008 +8A81:210410840088FC0001FE78880088788800887BFE48884888490879084A080408 +8A82:205010501050FD5200D47C5800507C5800D47D524650445044927C924512020E +8A83:20201020107CFE8401487C3000207C4801907C3E444245A444187C1044600180 +8A84:2020102003FEFC20002079FC0020782003FE787048A848A849247A2244200020 +8A85:202011200120FDFC01207A2000207BFE007078A848A8492449247A2248200020 +8A86:200013FE0200FE0003FC7A2002207AF802207A204A204BFC4A007A004BFE0000 +8A87:2020102003FEFC500088790402FA780003FE7840488049FC4804780448280010 +8A88:200011FE0020FC400088790401FE78220020782049FE4820482078204BFE0000 +8A89:2208110811100020FFFE082011102FE8C0061FF000001FF000001FF010101FF0 +8A8A:1110091009207FFC0200FFFE09203FF8C0061FF000001FF000001FF010101FF0 +8A8B:200011F80008FC0801F879000104790400FC7840482048A44A8A7A8A44780000 +8A8C:202010200020FBFE00207820002079FC0040782048A44A824A8A7A8A4C780000 +8A8D:200013FC0044FD4401447A84009479080240782048A44A824A8A7A8A44780000 +8A8E:2020102003FEFC20002079FC0124792401FC7820487048A849247A2248200020 +8A8F:2020101010FCFE8400847CFC00847C8400FC7CA244A4449844907C8844C40082 +8A90:201010D80394FC9400907BFE00907894009478D84B98489048AA78CA4A860102 +8A91:4000244002BEF90802887488008870BE018872885488508850887088553E0200 +8A92:202010400088FD0403FE7882008079FC022078204BFE48204850788849040602 +8A93:080C7EF008800EFE78880A8819087FFC00003FF800003FF800003FF820083FF8 +8A94:2000100603B8FC8800887908013E7B8800887A884A88493E49007A80447E0800 +8A95:2004100E03B8FC8800887928012E7BA800A87AA84AA8493E49007A80447E0800 +8A96:2020102003FEFC2000207BFE02027C0401F8781048204BFE4820782048A00040 +8A97:204210E20382FC8A008A788A03EA788A018A79CA4AAA4A824C827882488A0084 +8A98:201C11E00020FC2003FE78A801247A2201F87888489048BE490279024A140408 +8A99:200011FE0000FC9201247A4801247892000079FE48204820482078204BFE0000 +8A9A:2020112410A4FEA800207DFC01047D0401FC7D04450445FC45047D0445140108 +8A9B:200011FC0004FCFC000479FC00007BFE020279F8488848884850782048D80306 +8A9C:204010400088FD0403FE780200887944024278F849884A504820785049880606 +8A9D:202010201050FE8801447E2200F87C0800107C2045FC450445047D0445FC0104 +8A9E:200013FC0040FC4001F8788800887BFE0000780049F849084908790849F80108 +8A9F:2020102211FAFE2400247DFE00107C2001FC7C88451046FE44107C1044500020 +8AA0:202810240024FC2003FE7A2002247A2403A47AA84AA84A904A927DAA44460882 +8AA1:201010140012FC1003FE78100150795407F47954495449484A4A7A5A44260042 +8AA2:200011F80108FD0801F87908010879F80108790849F84890489079124A12040E +8AA3:200011FC0020FC20012479240124792402AA7AAA4CB24820482078204BFE0000 +8AA4:200011FC0104FD0401FC7800000079FC002078204BFE48204850788849040202 +8AA5:202011200120FDFC01207A2000207BFE0000780049FC49044904790449FC0104 +8AA6:200011F81008FED000207DFC01247D2401FC7D24452445FC45247D244524010C +8AA7:2028102411FEFE2000207DFC01247D2401FC7D24452445FC45247D244524010C +8AA8:2080108010FEFD0002FC7C8400A47C9403FE7C844524451445FE7C0444280010 +8AA9:202010101010FEFE00007C7C00007C7C00007C7C4444444444447C7C44440000 +8AAA:201010900088FD0802047DFA01087908010879F848904890489079124A12040E +8AAB:200011FE0100FD00017C7900010079FE015079524954494849487A444A520460 +8AAC:210410840088FC1001FC79040104790401FC785048504890489279124A0E0400 +8AAD:2020102003FEFC2001FC780003FE7A020404789048904890489079124912020E +8AAE:2088108813FEFC8800887C5000507C9401947E98449044B244D27C92448E0080 +8AAF:20FC10841084FEFC00847C8400FC7C0001FE7D02450245FE45027D0245FE0102 +8AB0:20A010900080FDFE01107B1005FC7910011079FC49104910491079FE49000100 +8AB1:2020102003FEFC2001FC782403FE782401FC78204920493E49207AA04A7E0400 +8AB2:200011FC0124FD2401FC7924012479FC00207BFE487048A849247A2248200020 +8AB3:400023FE0202FA0203FE721002927292029272FE521052925292749254FE0802 +8AB4:2040102003FEFA02000079FC0000780003FE7820492849244A227C2248A00040 +8AB5:218410680030FCC80324782003FE784000FC79844AFC488448FC788448940088 +8AB6:2040102003FEFC000088788801547A22000078204BFE48204820782048200020 +8AB7:200013FE0202FE8A02527BFE02427A2203FE7A824A824A824AFA7A024A0A0204 +8AB8:201013880088FCFE00907B9002247A2402387B884890489048A478BE4A820100 +8AB9:205010500050FBDE00507850005079DC00507850485048504BDE785048500050 +8ABA:202010200020FBFE002079240124792402AA787048A848A849247A224C200020 +8ABB:2020102203B4FCA800A8792402A2784001FC7904490449FC4904790449FC0104 +8ABC:2020101001FEFD02020478F80088788800F87888488848F8488878884BFE0000 +8ABD:20001040039CFA0402047B9C02047A0403FC789048904890489079124A12040E +8ABE:7C7C44447C7C44447C7C41045FF440044FE440044FE440044FE448244FE4400C +8ABF:200011FC0124FD240174792401FC7904017479544954497449047A044A140408 +8AC0:2040108001FCFD24012479FC0124794401FC789049104BFE4810781048100010 +8AC1:200013DE0042FD4A0084794A02527C2000007BDE48524952489479484A540422 +8AC2:20401040007CFC8401087A00002079CE0102790249CE49024902790249FE0102 +8AC3:208810880088FC8803DE78880088799C01DC7AAA4AAA4CC84888788848880088 +8AC4:2040102003FEFC0001FC790401FC780001FC780848104BFE4820782048A00040 +8AC5:08207FFC08200FE008200FE00820FFFE11103FF8C0061FF000001FF010101FF0 +8AC6:2088108813FEFC8800887CF800887C8800F87C88448847FE44007C8845040202 +8AC7:202010A200A2FD240050788803047822002078A448A449284850788849040202 +8AC8:2008103C01E0FC2003FE78A800A878A803FE78A848A84BFE4820782049FC0000 +8AC9:201C11E00020FC2003FE78A801247A4200407BFE4888490848D0783048480184 +8ACA:2080108000FEFD0202427A4A0152784203FE784248E249524A4A784248540008 +8ACB:2020102003FEFC2001FC782003FE780001FC790449FC490449FC790449140108 +8ACC:2020102013FEFC2001FC7D2401FC7D2401FC7C20447044A845247E2244200020 +8ACD:2080108001F8FD0802107DFC0024782403FE7824482449FC4824782048A00040 +8ACE:204810481048FDFE00487C4801FE7C0000FC7C84448444FC44847C8444FC0084 +8ACF:200017E0025EFA5202527BD202527A5403D47A544A484AE84F54785448620040 +8AD0:17F8240867F8A2A024A4289C01007FFC00003FF800003FF800003FF820083FF8 +8AD1:200013FE0040FC8001447A2400687AB001307AA8486848A449227A2048A00040 +8AD2:2040102003FEFC00000079FC01047904010479FC482048A849247A2248A00040 +8AD3:20481044105EFDE000287C12006A7D9600487C5E45E0442444287C12446A0186 +8AD4:4100210001DCF9140114711407D4701401147114558855485948711455140222 +8AD5:20201020003EFC2001FE7922013879E00122791E490049784A487A4A448A0906 +8AD6:202010200050FC8801047AFA000079FC0154795449FC4954495479544904010C +8AD7:202010200050FC8801447A2201F878080050782048A44A824A8A7A8A44780000 +8AD8:2020102003FEFC20002079FC0020782003FE784048A449A84A907C8848C60080 +8AD9:201C13E00220FBFE02207A92030A7A0601FC7904490449FC4904790449FC0104 +8ADA:2020101010FEFE8201047C0000FE7C1000107C90449E449044907CD0453E0200 +8ADB:2020102000A0FD2C0124792401AC7924012479FC492448504850788849040202 +8ADC:204811480148FBFE014879480178790001FE78204BFE487048A879244E220020 +8ADD:200013FE0022FD20013C792002FE7C0001FC790449FC490449FC790449140108 +8ADE:2040102001FEFD02010279FE0100790001FE79AA49AA4AFE4AAA7AAA44A20086 +8ADF:200011FC0104FD0401FC7904010479FC00007BFE48204920493C79204AA0047E +8AE0:2040102003FEFA02040479FC000079FC010479FC490449FC490478004BFE0000 +8AE1:2088110402FAFC40008078F800087850002079FC49544954495479544BFE0000 +8AE2:200013FE0222FC2003FE782001FC792401FC792449FC48204BFE782048200020 +8AE3:200010FC1084FE8400F47C9400947DFE01027D7A454A454A457A7D02450A0104 +8AE4:200013DE0252FE5203DE780001FC780003FE7880490049FC4804780448280010 +8AE5:2008103C01E0FC2003FE782001FC792401FC792449FC482049FC78204BFE0000 +8AE6:2040102001FCFC000088785003FE7A22042479FC492449244934792848200020 +8AE7:2110111201D4FD1801527992012E784001FC7904490449FC4904790449FC0104 +8AE8:200013FE0000FDFC0104790401FC780003FE7A224A224BFE4A227A224BFE0202 +8AE9:208410480000FDFE0048784800487A48014A794C48484848484878484BFE0000 +8AEA:2040102003FEFC0001FC790401FC780003FE7A0249FC48204820782048A00040 +8AEB:2020102003FEFC2001FC792401AC7974012479FC4820487048A879244A220020 +8AEC:0C28702411FEFE503852548E91007FFC00003FF800003FF800003FF820083FF8 +8AED:204010A00110FA0805F6780003C47A5402547BD44A544A544BD47A444A5402C8 +8AEE:2020112000BEFC4200847B10011079280144788248FC48844884788448FC0084 +8AEF:202011240124FD2401FC780003FE7820004079FC49544954495479544954010C +8AF0:200011FC0124FD2401FC7924012479FC0000784048244AA24A8A7C8848780000 +8AF1:2040104001FCFC8403FE780001FC790401FC78204BFE48204A207BFE48200020 +8AF2:200013FE0050FC5001FC79540154795401FC7820482049FC482078204BFE0000 +8AF3:2020101011FEFE0000847C4801FE7C0000FC7C84448444FC44847C8444FC0084 +8AF4:2008100C000AFBFE02087A0802E87A0A020A7AEC4AAC4AA84AEA7A1A4A260442 +8AF5:2020102003FEFC2000207BFE028A7A5202FA7A224A224AFA4A227A224A2A0204 +8AF6:2088108803FEFC8800F8788800F8788800887BFE490049484984790049FE0000 +8AF7:400027FC0404FC3405C4744405F47554055475F45444545455F4749458061002 +8AF8:2020102201FAFC2400287BFE0020784000FC79844A8448FC4884788448FC0084 +8AF9:200011F80108FDF8010879F800007BFE010079FC4A544C9449247A4448A80110 +8AFA:2020101001FEFC000084784801FE7908011079644908491249647A084A3004C0 +8AFB:2020104001FCFD0401FC790401FC780003FE7820482049FC482078204BFE0000 +8AFC:201E13E00044FD24008879FC0040784003FE788048FC494449287A1048680186 +8AFD:2088108803FEFC8800F8782001FC7924012479FC48204BFE4820782048200020 +8AFE:2088108803FEFC8800A8782003FE7840008078FC49844A844884788448FC0084 +8AFF:200010F81088FE8800F87C0001FE7C8800F87C8844F84488449E7DE844080008 +8B00:2088108803FEFC88008878F80088788800F878204BFE487048A879244A220020 +8B01:200011FC1104FDFC01047DFC00807DFE02227D224552450245FA7C0244140008 +8B02:200013FE0222FBFE02227BFE000079FC010479FC490449FC4904790449140108 +8B03:200011FC0104FDFC010479FC0020792001FE7A20482049FC482078204BFE0000 +8B04:024879504BF848804FFC79104A484FFC48027BF848004BF848004BF84A089BF8 +8B05:2040104010FEFD2200AA7CFA00427C9401487CFE452246AA44FA7C4244940108 +8B06:2020101001FEFD02010279FE010079EE012279AA4966492249667AAA4A220466 +8B07:01007FFE44429FF404403FF80440FFFE09201FF02008DFF600001FF010101FF0 +8B08:1FF010101FF010101FF008207FFC0820FFFE0A203118DFF600000FE008200FE0 +8B09:2020104003FCFE2402247BFC02247A4403FC784048A848B4493C79224A22041E +8B0A:2088108803FEFCA800107BFE0080788000FC780048A848A848A878AA492A0206 +8B0B:4208220803BEF4880AA8713E02087448084877FC50E0515052487C4650400040 +8B0C:200013FE0008FDE8012879E800007BFE000879E84928492849E8780848280010 +8B0D:08202AA44D28145022887FFE4102BFF400001FF000001FF000001FF010101FF0 +8B0E:201010940254FD580110787E00107B30013879544994491049107A804C7E0000 +8B0F:20A0112C1124FD2401AC7D2401247DFC00207DFC4488445044207C5044880306 +8B10:404020280090FAA402C2748A01887678000073FC529452945294729457FE0000 +8B11:201E13E00122FC940040788801F0782000C479FE482248204BFE785048880306 +8B12:202010200050FC4800A479FE028478FC008478FC488048FC494479444A7C0044 +8B13:2020102003FEFC2001FC790401FC790401FC790449FC49044BFE788849040202 +8B14:4040207C0040FBFE0242727803C07244023C720052FC528053FE7480548008FC +8B15:4004201E03F0FA1E021072FE0292729802F2728E528052B852A874AA554A0A86 +8B16:200011FC0124FDFC012479FC00887944024278F849884A504820785049880606 +8B17:2040102003FCFD0800907BFE02027C4400207BFC488048F84888790849280210 +8B18:200013FC0204FA0403FC7A4002207BFC02887A504BFE4A204DFC7C2048200020 +8B19:208810500000FDFE005079FC00547BFE005479FC485048D849547A5248500050 +8B1A:210410840088FC0003FE780000887904020279FC495449544954795447FE0000 +8B1B:2088108803FEFC8801FC788803FE782001FC792449FC49244BFE790449140108 +8B1C:200011FE0110FD20017C7944017C7944017C79104910495449527A924A500420 +8B1D:4084210403C4FA4403DE724403C47264025477D450C451445244744451540088 +8B1E:2040102003FEFC0001FC790401FC780003FE7A024AFA4A8A4AFA7A024A0A0204 +8B1F:203C13C00044FA240128790000407B9C02047A044B9C4A044A047A044BFC0204 +8B20:2040108001FCFA48013078C0030079FC022078204BFE48204924792449FC0004 +8B21:2008103C03C0F8040244792801FC7A2000207BFE482049244924792449FC0004 +8B22:20A0109001FEFB2001FC792001FC792001FE79004BF849084890786049980606 +8B23:21FC102003FEFE2201AC782001AC780001FC78004BFE488048FC780448280010 +8B24:200013FE0050FDFC0154795401FC780001FC78004BFE482048A879244AA20040 +8B25:2020104001FCFD24017C798C01547924015479FC4820481049547942494A0238 +8B26:0878FF4808863E782A483E304148FFFC00003FF800003FF800003FF820083FF8 +8B27:2040102003FEFC0001547924015479FC00207BFE4A424A924AFA7A0A4A020206 +8B28:2088108803FEFC88000079FC010479FC010479FC48204BFE4850788849040202 +8B29:04407FFC04401FF010101FF010101FF00400FFFE11102FE8C0060FE008200FE0 +8B2A:2040102003FEFC8800507BFE02527A8A03067AFA4A8A4A8A4AFA7A024A0A0204 +8B2B:2040102003FEFC8800507BFE02227AFA02227AFA4A8A4A8A4AFA7A024A0A0204 +8B2C:200013DE0042FA52014A7A52002878C4031278604988483249C4781848600380 +8B2D:2108109007FEF80003C47A5403D47A5403D47A444ACC48004BFC788449140608 +8B2E:202013FE0020FDFC00207BFE000079FC010479FC490449FC490479FC48880104 +8B2F:2020103C0020FDFE0122793801E4791C0100797C4944497C4944797C494402FE +8B30:2010101002FEFD10017C7854007C7B54017C791049FE491049107A90447E0000 +8B31:202011FC0124FBFE012479FC002079FC012479FC48404BFE488879D04870038C +8B32:2040108801FCFD0802527BFE00507988062678C04B1048644B88783048C00700 +8B33:200013FE0200FE7C02447A44027C7A0002EE7AAA4AAA4AAA4AEE7A004BFE0000 +8B34:200011FC0124FBFE012479FC000079FC010479FC490449FC490479FC48880104 +8B35:200013DE0042FA52014A7A520042782001FC7904490449FC4904790449FC0104 +8B36:2040102001FEFD000148794801FE794801487948497849004AD47AAA452A0800 +8B37:08207E20087EFEC410281E10222846C68100FFFE00003FF800003FF820083FF8 +8B38:410821080108F7D0011E779401247FD4021473D452545248524874D454240842 +8B39:2088108803FEFC8800F8782001FC792401FC78204BFE482049FC78204BFE0000 +8B3A:08207E2008F8FF2814287F6A082AFF560982FFFE00003FF800003FF820083FF8 +8B3B:40102190061EFA22025472080F9072640208771E5AA252425214720852100260 +8B3C:2040107C0040FDFC0144797801C4793C01047978499449584AFE7A1044500020 +8B3D:7CF804887CF840207DFC052415FC0A22FFFE00003FF800001FF010101FF01010 +8B3E:200011F80108FDF8010879F800007BFC02947BFC480049F84890786049980606 +8B3F:4100211E07D2F912011277DE045277D2045277DE511251125FD27122512A0144 +8B40:200813880088F91007DE7A9402A47B9402947B944A944AC84B887E9448A400C2 +8B41:208813FE0088FC0001FC78A800A87BFE00A878A849FC48204BFE782048200020 +8B42:200013DE0252FE5203DE780001FC792401FC792449FC48204BFE782048200020 +8B43:4040207C0040FBFE0242727803C4723C020072505254535454D8745059FE0000 +8B44:210410880000FBFE02227AAA02727A2203FE780049FC490449FC790449FC0104 +8B45:400027DE014AFB5A056A725202D674200084708452D45296529472D4573E0000 +8B46:202013FE0020FDFC000079FC010479FC00887BFE480049FC4904790449FC0104 +8B47:2020102003FEFC8801247A2201FC782803FE784049FC4E8448FC788448FC0084 +8B48:4208210807C8F810079E749407A4701407947094511451C85708711455240242 +8B49:202017A400A8FA9201147A0805F4780203F87A084A084BF84A0879104FFE0000 +8B4A:2020102001FCFC2003FE7908039C790801887E3E48004BFE489078904912020E +8B4B:239C1294039CFE94039C7A0402F47A9402F47A944AF44A944A947B344A04020C +8B4C:400E23F00044FA24010873F8020873FC020473FE520252AA52AA750254140808 +8B4D:00803FFE229025FE2E9034FE249024FE24402FFE200027FC400047FC840407FC +8B4E:200013FC0048FC3003FE785200947B5000207BFE4A524A8A4B767A524A720206 +8B4F:2124112402AAFBAE01247AAA03AE792407FE7910491449144A8A7A4A4A160422 +8B50:2088105003FEFC5001FC7954018C7974010479FC48084BFE4908788848A80010 +8B51:201811E00040FBFE0088797402527870000079FC49044974495479744904010C +8B52:203C13E00124FCA803FE78A801247A0201FC7924492449FC4924792449FC0104 +8B53:2020102003FEFC2001FC792401FC792401FC78224BFE484248247AA24A8A0478 +8B54:200013DE0252FBDE02107A5201CE780000887BFE488848884BFE788849040202 +8B55:2080108001FEFB540554795403FE7954015479544FFE48004954792A4A2A0000 +8B56:200013DE0088FAA803FE798802DA7CA601F87908490849F84908790849F80108 +8B57:2210121003DEFA28054478A001107A0805F6780048004BF84A087A084BF80208 +8B58:2110109403D2F8120250799007FE781003D27A524A544BD44A4A7A4A4BD60022 +8B59:2090108801FEFD1003107DFE0110791001FE7910491049FE49007AA44A520452 +8B5A:200013FE0050FBFE02527BFE000079FC010479FC490449FC48207BFE48200020 +8B5B:2088108803DEF88807FE788801547A2201FC7904490449FC4904790449FC0104 +8B5C:2108109003FCF8900294799800907BFE000079F84908490849F87908490801F8 +8B5D:400027FC04A4FCA407BC70A007BC74A404A477BC54A454A457BC74A250A2007E +8B5E:200011FC0154FD5401FC780003FE780001FC790449FC4862489479884AA400C2 +8B5F:20F810880088FCF8000079DC0154795401DC78204BFE487048A879244A220020 +8B60:202017FE0000FBFE02027AFA028A7BFE000079FC490449FC490479FC480007FE +8B61:2020112400A8FBFE020278F80088788800F8780049FC492449FC792449FC0104 +8B62:204412240128FC7E00107828034A791C0128794C491A492A494879104AFE0400 +8B63:202010200050FC8801047AFA0000780001DC7954495449DC4888788849540222 +8B64:4108220807C8F45007DE746407D47214011477D4521453C852487454555408A2 +8B65:10207E204A7E7EC41028FF1020283EC64300FFFE00003FF800003FF820083FF8 +8B66:2420FF20247E7EC482287A104A287AC60500FFFE00003FF800003FF820083FF8 +8B67:402023FE0288FA5003FE725002FC725403FE725452FC525052D8755456520850 +8B68:409023FC0294FBFC029473FC000073FC020072F8520053FE5520751455480986 +8B69:2040102001FCFC8800507BFE000079FC010479FC490449FC48207A944A8A047A +8B6A:208813FE0088FDFC010479FC010479FC008079FE4A224D52490279FA480A0004 +8B6B:208010F80108FBFE0144799201FE7900017C7900497C4900497C7A444A7C0444 +8B6C:3E1022FE3E4420287EFEA2103EFC22100100FFFE00003FF800003FF820083FF8 +8B6D:410026DC0454FC5406D47454046677C0001C701457D45114510871C857140222 +8B6E:202010501088FD7402027DFC01247DAC01247DFC440044F844887CF8448800F8 +8B6F:200011FC0154FDFC002079FC00207BFE0088785049FC48204BFE782048200020 +8B70:2104108803FEFC2001FC782003FE7854019278904BFE489048D47B8A489601A2 +8B71:08207FFC01003FF80100FFFE11107D7C01007D7C01007D7C01007D7C45447D7C +8B72:4080204007FEF9100208751403F8711003F8711057FC512853107D4851860100 +8B73:200011FC0020FBFE022279AC002079AC00007BFE482049FC495479544954010C +8B74:2010107C0254FD7C011078FE00007B7C0144797C4940497C4944797C4A80047E +8B75:414421440554FB64015E77E400047234014C77E4508453E4508470E457140008 +8B76:0100FFFE00003FF800003FF820083FF80810FEFE00007CFC00007CFC44847CFC +8B77:208813FE00A8FC9001FE7B2001FC792001FC792049FE49004BFC78884870038E +8B78:202013FE0020FDFC00007BFE000279FC00207BFE48004BFE48047BBE4AA4038C +8B79:202013FE0000FDFC010479FC00007BFE020279FC48404BA448D87B3448D20330 +8B7A:220012BE0302FA5401C8783E020A7BCA052879284FEE49284AA87A584C4E0080 +8B7B:3EF822883EF822883EF822883EF814502288FFFE00003FF800003FF820083FF8 +8B7C:7E40487E7E9043087EFE48AA7EFE02000100FFFE00003FF800003FF820083FF8 +8B7D:0A0033B822083BB820883AB82288FFFE11103FF840049FF200001FF010101FF0 +8B7E:208813FE0000FDE2012A79EA012A79EA0122796648004BDE4A52794A4A5200C6 +8B7F:208813DE0088FDDC00887BDE00887BFC000479FC48044BFC48407AA44A8A047A +8B80:202013FE0020FDFC00007BFE02527BFE010479FC490449FC490479FC48880104 +8B81:4020201004FEFA44022870FE009276FE029272BA52AA52BA5286750058FE0000 +8B82:210011F80208FFFE02627A9201FC790401FC790449FC488049F87A884870038E +8B83:208811DC0088FBDE00887954022279FC010479FC490449FC490479FC48880104 +8B84:83F842480248E3F80248E24803F8E0000FBEEAAAAAAAAFBEAAAAEAAAAFBE08A2 +8B85:202013FE0202FC1C03E0792400A87BFE01247A024DFC492449FC792449FC0104 +8B86:22004F9C94802FDE6108AFC8250827D80100FFFE00003FF800003FF820083FF8 +8B87:23DE125203DEFE5203DE7A42027A7A8A03127ADA4A8A4ADA4A8A7AFA4A0A0204 +8B88:400027FE0444FD98048875FE048875DC06AA748854205520553C752055200BFE +8B89:2010107C0254FD7C011078FE00447B7C0144797C4944497C492879444A80047E +8B8A:210447C88812F3BC20084B92F83E0380AAAAABAA08001FF8282007C01830E00E +8B8B:08407F7C1440FF7C22043E7C22403E7C2342FFFE00003FF800003FF820083FF8 +8B8C:4110211007FCF91001F0720802EA76AC02A872AA56EA5A06500072A452520452 +8B8D:200013FE0020FBAE02AA7AAA03AE782003FE78204BAE4AAA4AAA7BAE482003FE +8B8E:3218291440207BBED06853A8783E53A850287BBE52A852A852A87BBE42A04020 +8B8F:22004F9C94802FDE6208AFC82A482AD80100FFFE00003FF800003FF820083FF8 +8B90:48907EFCC9907EFC48907EFC48907EFC0100FFFE00003FF800003FF820083FF8 +8B91:804040A00110E2080DF6E0000EEEEAAA0EEEE000AFFEA922AFFEE922A92A0804 +8B92:21F0121007FCFA0403FC7A2403B87A2201FE7A104FFC4A444BFC78D0494A063E +8B93:202013FE0000FDDC015479DC00887BFE00887BFE48884BFE489479884AA400C2 +8B94:400E2770052AFD14053E7608057E7500057E7502553E5602547E741454AA04BA +8B95:23DE125203DEFE5203DE7A2202FA7A2202FA7AAA4AFA4AAA4AFA7A724AAA0226 +8B96:2148114C02AAFC0803FE79480368794A036A794A4B6C494C496A7B8A48160022 +8B97:222213FE0090F9FE03107DFE011079FE011079FE49004BFE4A8A7B764A520276 +8B98:43FC210801F8F90801F8710E07F8700807FE7294539C5294539C72D657BC0084 +8B99:208813FE0088FBDE02527BDE00A0789001FE79204BFC4D2049FC792049FE0100 +8B9A:452827BE0948F7BE031875AA094673FC020473FC520453FC520473FC51080204 +8B9B:410827FE0108FB90013C77D402B4755C0396712253FC500057FE7080510403FE +8B9C:4248215007FCF40401F0711007FC755404E477FC504057FC50407FFE52A40452 +8B9D:23DE125203DEFC0003FE7A0002C87A4E03EA7AB24AEA4AAA4AEA7AB445E4082A +8B9E:810841EC010AEFEA0928EBC8093EEFE80948EBE8AA28AB68AAA8EBF4AAB412A2 +8B9F:81084FE40100E7CE0000EFEE0AA0EFEE0440E7CEA44AA7CAA44AE7CEA28A0440 +8BA0:000020001000100000000000F000100010001000100010001400180010000000 +8BA1:004020401040104000400040F7FE104010401040104010401440184010400040 +8BA2:0000200013FE102000200020F020102010201020102010201420182010A00040 +8BA3:0080208010801080008000A0F090108810841084108010801480188010800080 +8BA4:004020401040104000400040F040104010A010A010A015101910120804040802 +8BA5:000021F01110111001100110F1101110111011101110151219121212020E0400 +8BA6:0000200013FC104000400040F040104017FE1040104010401440184010400040 +8BA7:0000200013FE102000200020F020102010201020102014201820102007FE0000 +8BA8:001020101010101003FE0010F010101011101090109010101410181010500020 +8BA9:004020401040104000400040F07C10401040104010401440184010400FFE0000 +8BAA:002020201020102001240124F12411241124112411241124152419FC10040000 +8BAB:00802080110011FE02000400F1F8100810101060108015001A02120201FE0000 +8BAC:0010207813C0104000400040F040107E17C010401040144218421042003E0000 +8BAD:010421241124112401240124F124112411241124112415241924122402040404 +8BAE:008020481248120802080110F110111010A010A01040144018A0111002080C06 +8BAF:000027F01110111001100110F11017D01110111011101112150A190A11060102 +8BB0:0000200011F8100800080008F00811F811081100110011001502190210FE0000 +8BB1:0000200013FC104400440244F244124414841084108415041904120404280810 +8BB2:011021101110111007FC0110F11011101FFE1110111015101910121002100410 +8BB3:00402040104017FE00400040F3FC1040104017FE10421042144A184410400040 +8BB4:000023FC1200120802880250F2501220122012501250128817081A0013FE0000 +8BB5:000023FE12001200020003FCF20412041204120413FC120016001A0013FE0000 +8BB6:000023FC1010111001100110F21013FE10301050109015101A10141000500020 +8BB7:002020201020102003FE0222F22212221252124A128A130216021A02120A0204 +8BB8:00802080108011FC01200220F020102013FE1020102010201420182010200020 +8BB9:00A020A010A0112401240328F5301120116011A01120112215221922111E0100 +8BBA:0040204010A010A001100208F406111011201140118011001504190410FC0000 +8BBB:000020081108108802520252F222122212521292130A160A1A0213FE00020000 +8BBC:002021201120111001100248F248144418821080111015081A0817FC02040000 +8BBD:000043F822082208032802A8E2A82248224822A822A82B2A340A240A08061002 +8BBE:000021F0111011100110020EF40013F811081110109014A0184010A003180C06 +8BBF:00802040104017FE01000100F10011F811081108110815081A08120804500820 +8BC0:00402040104013FC00440044F044104417FE104010A014A01910120804040802 +8BC1:0000200013FE102000200020F1201120113C1120112015201920112007FE0000 +8BC2:002020201020102003FE0020F020102011FC1104110411041504190411FC0104 +8BC3:0000200017FE1008000803C8F24812481248124813C812481408180810280010 +8BC4:000023F81040104002480148F150104017FE1040104014401840104000400040 +8BC5:000021F811081108010801F8F1081108110811F8110815081908110807FE0000 +8BC6:0000200011FC110401040104F104110411FC1104100014901888110402020402 +8BC7:000023FC12041204020402F4F29412941294129412F416941A04120402140208 +8BC8:01002100110011FE02800280F48010F810801080108014FC1880108000800080 +8BC9:0008201C11E0110001000100F1FE111011101130111815141912121002100410 +8BCA:0040404020A0211002080426E040208023102020204028883310202000C00700 +8BCB:0008203C13E0122002200220F22013FE1220121012101212160A1A8A13260212 +8BCC:0080208010F8110802100420F3FC10041004100411FC10041404180413FC0004 +8BCD:000023FC1004100407F40004F00413E412241224122413E41404180410140008 +8BCE:002020201124112401240124F1FC102010201124112411241524192411FC0004 +8BCF:000023FC1084108400840104F1141208140011FC110411041504190411FC0104 +8BD0:00202020102013FE02220224F22013FC12841288124816501A20145004880906 +8BD1:000023FC1104108800500020F0D81326102011FC102014201BFE102000200020 +8BD2:0020202010401088010403FEF002100011FC1104110411041504190411FC0104 +8BD3:000023FE1200120003FC0220F22012F812201220122013FC16001A0013FE0000 +8BD4:0040404027FC2040004003F8E040204027FE20E0215029503248244408420040 +8BD5:002820241024102007FE0020F02017E0112011101110151019CA170A02060002 +8BD6:0020202011FC102000200020F3FE10001020102011FC10201420182013FE0000 +8BD7:00402040104013FC00400040F7FE1010101017FE101012101510191010500020 +8BD8:00202020102017FE00200020F3FE1000100011FC110411041504190411FC0104 +8BD9:00802080108017FE01000120F22012A414A415281A5010501488190812040402 +8BDA:00284024202027FE04200420E42427A424A424A824A82C903692292A08461082 +8BDB:00202120112011FC01200220F02013FE107010A810A815241924122200200020 +8BDC:00202120112011FC01200220F02013FE1090109010901090151219121212040E +8BDD:0008203C11E01020002003FEF0201020102011FC110411041504190411FC0104 +8BDE:0008401C2F70211002100450EF5C21502950295025502A7C33002480087E1000 +8BDF:0008403C23C02200020003FEE2002200220022FC22842A843484248408FC0084 +8BE0:0040204010A0111002080406F3F810401040104013F810401440184017FE0000 +8BE1:0100410023F8220804100BFEE20022F82288228822A822902A823482247E0800 +8BE2:0200420023FC240404040BE4E224222423E42224222423E42A24300420140008 +8BE3:01002104113811C001020102F0FE100011FC1104110415FC1904110401FC0104 +8BE4:0080208011F01210002003FCF044104417FE1044104413FC1444184011400080 +8BE5:008040402FFE208001100110E22427E42048208821102A203450208803040C04 +8BE6:020821081110100007FC0040F04013F81040104017FE10401440184010400040 +8BE7:00402020102013FE02020404F03813C010401040107E17C0144018421042003E +8BE8:000023FE12021444004003FCF08010A0112011FC102014201BFE102000200020 +8BE9:000047BC2084208404A40294E2942084218C229424A420842884308422940108 +8BEA:0040404027FC204003F80080E7FE2090211021FE22102A903450281000500020 +8BEB:0014401220102FFE00100290E29222922FD2229422942A88328A249A04260842 +8BEC:000047FC2040204002480248E248255424D2286220402840304020400FFE0000 +8BED:000047FC2040204003F80088E08827FE2000200023F822082A08320823F80208 +8BEE:0020212410A410A8002001FCF104110411FC1104110411FC1504190411140108 +8BEF:000043F82208220803F80000E7FC204020402FFE204020A028A0311022080406 +8BF0:00202120112011FE02200420F02013FE1000100011FC11041504190411FC0104 +8BF1:001C47E0204020400FFE0150E2482C4623F021102120217C2A04320424280810 +8BF2:0100210011FC120005F80108F148112817FE11081248122817FC180810500020 +8BF3:0000444022BE210802880488E08820BE218822882488208828883088253E0200 +8BF4:020821081110102003F80208F208120813F810A010A0152019221222041E0800 +8BF5:000047F8201021A0004007FCE444244427FC2444244427FC2C44344424540408 +8BF6:004040802110220807FC0104E10023F8244020402FFE204028A0311022080C06 +8BF7:0040404027FC204003F80040E7FE200023F8220823F822082BF8320822280210 +8BF8:0040404423F42048005007FEE040208021F82308250821F82908310821F80108 +8BF9:00004FC024BC24A404A407A4E4A424A827A824A8249025D02EA830A820C40082 +8BFA:0108410827FE210801480040E7FE2080210023FC250429042904310421FC0104 +8BFB:0020202011FC1020002003FEF002109410501110109013FE1428184410820302 +8BFC:00004FFE2080218402440468EAB0213022A8246828A421242A22342020A00040 +8BFD:009020901090179E00900090F090139C109010901090179E1890109000900090 +8BFE:000043F82248224803F80248E24823F8204027FC20E029503248244600400040 +8BFF:003843C02040204007FC0150E2482486208027FC21102A1031A0206000900308 +8C00:00404140265C24440444075CE444244427FC244420A020A02910320824040802 +8C01:01404120212023FE02200620EBFC2220222023FC222022202A2033FE22000200 +8C02:0040404020A0211002880446E80023F020102020204029243522250A090800F8 +8C03:000047FC2444244405F40444E44427FC240425F425142D1435F4240404140808 +8C04:0080408020F8210802100400E040239C22042204239C22042A04320423FC0204 +8C05:0040202013FE1000000001FCF1041104110411FC102014A81924122200A00040 +8C06:0080204017FC100003F80208F3F8100013F81010102017FC1840104001400080 +8C07:0080404027FC200001100110E2A824442000204027FE20402840304020400040 +8C08:004022441244144800A00110F6081044104012481248145018A0111002080C06 +8C09:0040202013FE1222002001FCF124112411FC1124112415FC1924102000200020 +8C0A:0040202013FE1202040401F8F108110811F81108110815F81908110807FE0000 +8C0B:020842082FFE2208020803F8E208220823F820402FFE20E0295032482C460040 +8C0C:0110411027FC211001F00110E1F02110211027FE220022902B08320023FC0000 +8C0D:00904290229027FE02900290E2F0220023FC204027FE20E0295032482C460040 +8C0E:0108410827FE2148002007FEE200220023FC2000224822482A48344A244A0846 +8C0F:004040402FFE204007FC0444E55424E4244427FC20E029503248244600400040 +8C10:0220222413A8123002A20322F25E108013FC1204120413FC16041A0413FC0204 +8C11:0040207C104013FE02420278F3C01244123C120012FC16801BFE1480048008FC +8C12:000043F8220823F8020803F8E10023FC2444224422A422042BF4300420280010 +8C13:000047FC244427FC044407FCE00023F8220823F8220823F82A08320822280210 +8C14:000047BC24A424A407BC0000E3F820002FFE2100220023F82808300820500020 +8C15:004020A01110120805F60000F3C41254125413D41254125417D41A44125402C8 +8C16:003C47C022442128000003FCE080208027FE210021F82A883250242008D80306 +8C17:010021F01210142003FC0244F24413FC10A01122161E10C01430198010600010 +8C18:00402240117C108401080620F22012501288110611F811081508190811F80108 +8C19:0080404027FC200002080110EFFE200023F82208220823F82A08320823F80208 +8C1A:0040202013FC100001080090F3FE1210122012C8121016241AC8141004600980 +8C1B:0040202011FC100000880050F3FE1222142411FC112411241534192810200020 +8C1C:0010409224522254021000FEE010263822542292231022102A10350028FE0000 +8C1D:0080404027FC2404040407FCE400240027FC26A42AA42BFC3AA42AA412A4020C +8C1E:000023FE10221120013C0120F2FE140011FC110411FC150419FC110401140108 +8C1F:0110411027FC2110000003F8E20823F8220823F8204027FC28A0311022080C06 +8C20:004042482150204007FE0402E80423F82208220823F820A0292031242224041C +8C21:000047FC244427FC044407FCE1102208248421F8220825083090206001980E06 +8C22:010842082788248807BE0488E78824C824A82FA821882A883488288802A80110 +8C23:0008203C13C0100402440128F1FC1220102013FE102011241524192411FC0004 +8C24:0040202013FC1108009003FEF2021444102013FC108010F81488190811280210 +8C25:020841082110200007FC0000E1102208240423F822A822A82AA832A82FFE0000 +8C26:02084110200027FE00A007FCE0A42FFE20A427FC20A029B032A82CA600A000A0 +8C27:00404028209022A402C2048AE1882678200023FC229422942A94329427FE0000 +8C28:011041102FFE211001F00040E7FC244427FC20402FFE20402FFC30402FFE0000 +8C29:03F8420823F8220803F80000E7FC24A424A427FC200023F8291030E023180C06 +8C2A:0080404027FC211000A007FCE44425F4244425F4251425142DF4340424140408 +8C2B:0108209017FE100003C40254F3D4125413D4124412CC14001BFC108401140608 +8C2C:000047BC208424A4029404A4E0502188262620C0231020642B88303020C00700 +8C2D:000023FE105013FE025203FEF00011FC110411FC110415FC182013FE00200020 +8C2E:000047BC2108252807BC0318E5AA2946200023F8220822082BF83208220803F8 +8C2F:0140412023FE222006200BFCE220222023FC222022202BFE3200252404920892 +8C30:0200417C2504244405F40444E5F42554257425D4255425F42CE435542444044C +8C31:0208411027FC20A004A402A8EFFE200023F82208220823F82A08320823F80208 +8C32:000047F82090206007FC00A4E12826A0204027FC24A425142EEC34A424E4040C +8C33:0108410827CC210A010807DEE44826C8254827C8255427D42D543554245404E2 +8C34:001044FE229222FE001001FEE0002EFE228222FE228022FE2A8232FE250008FE +8C35:020043F8241027FE0D481624E7FE240025FC240025FC2C0035FC290409FC1104 +8C36:0448444C2AAA20080FFE0288EEE8228A2EEA228C2EEC2A8832EA2F1A04260042 +8C37:08200810110821044280044008203018C0061FF010101010101010101FF01010 +8C38:08881C84F102122210201050FC881104120211FC110411042104210441FC8104 +8C39:004048404440944013FE2840448080907890492049204A484A447C8449FE0082 +8C3A:000024FC22084A4888481448228841FEBC1824282428244824883D0824280010 +8C3B:000025F822484A48884815F822484148BC4825F824482448248A3C8A250A0206 +8C3C:0048244822484A4889FE144822484148BC4825FE2400244824443C8424820102 +8C3D:002048204450948811442A2244F880087810482049FC49044904790449FC0104 +8C3E:0040482045FE95021204285044888104780049FC48204820482078204BFE0000 +8C3F:0E00F05022489284452420204450F888110624F8FE881088FE88288844F88288 +8C40:001E4BE0452294941040288845F0802078C449FE482248204BFE785048880306 +8C41:20001050FE48828411247C2010507C881104FEFA10887C88448844887CF84488 +8C42:000024EE22224AAA886614AA22104128BC442592242024C824323CC4241800E0 +8C43:000853884888891027DE32944AA487947A944B944A944AC84B887E9448A400C2 +8C44:00204BFE442095FC10002BFE465283FE790449FC490449FC490479FC48880104 +8C45:011050904BDE8810225E31824BDE84107BDE4A504BDE4A504BDE7A504A5202CE +8C46:00007FFC000000001FF010101010101010101FF00000101008200440FFFE0000 +8C47:0000FE0001FC00207C204420442044207C200020442028202E20F02043FE0000 +8C48:0100210821083FF800007FFC00001FF0101010101FF0000008200440FFFE0000 +8C49:0020FE20002001FE7C204420442045FC7C840088444828502E20F05041880606 +8C4A:04403FF824483FF824483FF800007FFC00001FF010101FF008200440FFFE0000 +8C4B:108010803EFC62449448483030102FE8C0061FF010101FF008200440FFFE0000 +8C4C:0040FC2003FE02027D04490049DE4A527A5203528C9A489451101912E212040E +8C4D:0020FE4000FE00927C9244FE449244A27CFE0048448829FE2E08F00840080008 +8C4E:7EFC48447E4442287E1048287E4400827FFC00001FF010101FF008200440FFFE +8C4F:0088FE50000001FE7C5045FC445447FE7C5401FC445028D82F54F25240500050 +8C50:08201D7049245D7449245D7449247FFC00007FFC00001FF010101FF004407FFC +8C51:2844FE28AA00FEFCAA14FE1400FCFE9000907CFE44327C32445A28541E90E110 +8C52:2A227F14AABEFF8AAA8AFFBEAAA8FFA8003EFF9A001A7F2A412E7F482208FF88 +8C53:2A107F10AA90FFBCAA90FFA8AAA8FFA40054FF82007C7F5441547F542254FFFE +8C54:2A087F08AA9CFF88AA88FFBEAA88FF900014FFBE00007F3E412A7F2A222AFFFE +8C55:00007FFC020006000908119062A004C008C011A06290048808863080C2800100 +8C56:00007FFC020006000908119062A014C008C015A06290048808863080C2800100 +8C57:0000FDFE2820284028A22B34285828942B34285228922B102850482247FE8000 +8C58:0020FC20102023FE6020952439245124992435FC5424902010221022501E2000 +8C59:020001003FF808200440FFFE02000D08719002A00CC071A006981886E2800100 +8C5A:00007BFE4840488049447A24486848B049307A28486848A449224A2048A09840 +8C5B:0000FCF810882088608895063A0051FC98843484544890501020105050882306 +8C5C:0000FDFE1048204860489448384853FE98483448544890481088108851082208 +8C5D:0000FDFC1124212461249524392451FC99043500550091001102110250FE2000 +8C5E:0040FE40088010FC31044A049CF428944C949A942AF448948804080428281010 +8C5F:0040FC2011FC2104610495FC39005100997C35085510912011421282527E2400 +8C60:0000FEF80888108830884AF89C8828884C889AF82A884888888808882BFE1000 +8C61:08001FE020207FF8A10822083FF80600191062A00CC071A006901888E2860100 +8C62:111009207FFC0400FFFE10102FC8C606191062A00CC071B006881884E2800100 +8C63:0000FDDC1088208860889488388853DE98883488548890881088110851082208 +8C64:0000FDF81108210861F89508390851F899443548553091201110114851862100 +8C65:0020FE10081011FE30204A249C4428F84C129A222A4449888810082828441182 +8C66:010001F801003FFE210221F02F0420FC20002FF823002C9023605CD843469CC0 +8C67:0028FC2413FE2020602095FC3924512499FC3524552491FC112411245124210C +8C68:00C2FC34101820646182942039FE5050989035FE56929092109A109450102010 +8C69:0000FDFE1020204060A295123834505898983514543490521090111050502020 +8C6A:01007FFC00001FF010101FF000007FFE40029FF40600192006C039B0068C3980 +8C6B:0080F8F8090853FE25121122FDFE244028A223542098233420542092A3504020 +8C6C:0020FE2008FA102430284BFE9C2028404CFC9B442A44487C88440844287C1044 +8C6D:0000FDDC11442144614495DC3900510099DC3514551491D41108110851142122 +8C6E:0020FDFC1020208863FE9488380051FC99043524552491241124105050882304 +8C6F:000EFEF00822109230444A209C4428F84C109A242AFE481088FE082828441082 +8C70:1000FE7810487C480048FE8682007CFC0044FE44202854282810DC282A44D982 +8C71:0000FCF81088208860F89488388850F8980035FC555491541154115453FE2000 +8C72:0000FDFE11102120617C9544397C5144997C3510551091541152129252502420 +8C73:010041047DF4492451446BAC4D3459646DB44B2C596469A4596441047FFC0004 +8C74:0020FE1008FE104430284AFE9C8228924CFE9A922ABA48AA88AA08BA28821086 +8C75:0124F924222444A4A154154A3B92550899083528512E912811281158514E2180 +8C76:0020FDFC1020208863FE948839FC510499FC350455FC910411FC108851042202 +8C77:0020FBFE202041FCA00017FE3A0251FC980035FC510491FC1104108853FE2000 +8C78:00E007007A0C113008C00780784000A003300C507090011006101810E0A00040 +8C79:0C403040C28014FC49043204C80415042484CC4414442404C404040428281010 +8C7A:0C103010C210141049FE3010C83014302450CC5014902510C410041028501020 +8C7B:0C0030FCC220142048203020C82015FE2420CC2014202420C420042028201020 +8C7C:0C103110C310151249123114C9D815102510CD1015102512C5520592290E1000 +8C7D:0C203020C22015FE49223122C92215222552CD4A158A2502C5020502290A1104 +8C7E:0C0031FEC210141048203020C86814A42522CE2214202420C42004002BFE1000 +8C7F:0C803080C28015FC49043204C9E415242524CD24152425E4C524040428281010 +8C80:0C203020C324152449243124C9FC14202420CD2415242524C524052429FC1004 +8C81:10402020D4200BFE52022404D00018902890C89018882908C908090452042402 +8C82:0C0031FCC244144448443044C89414882500CCFC14842484C484048428FC1084 +8C83:0C203020C24015FC49043104C904150425FCCD0415042504C504050429FC1104 +8C84:0C203020C3FC14244BFE3024C9FC14202420CDFC14202420C7FE042028201020 +8C85:10902090D490091051FE2310D51019382938C95419542992C910091051102110 +8C86:0C0031FEC200140048FC3084C88414FC2484CC8414FC2484C400040029FE1000 +8C87:0C0031F8C308150849F83108C90815F82544CD4815302520C510054829861100 +8C88:0C103020C2FC148448A43094C89415FE2484CCA414942494C484050429141208 +8C89:10802080D4F80908531024A0D04018A02918CA061DF82908C908090851F82108 +8C8A:0C0030FEC2201420484030FCC88414842484CCFC14842484C484048428FC1084 +8C8B:0C0031FCC30415FC490431FCC800140025FCCC20142027FEC420042028201020 +8C8C:0C203040C3FC1504490431FCC904150425FCCC5014502450C4920492290E1200 +8C8D:0C0031FCC324152449FC3124C92415FC2420CC2015FC2420C42004202BFE1000 +8C8E:10002040D79C0A045204239CD2041A042BFCC89018902890C89009125212240E +8C8F:10402080D5FC0924512421FCD124194429FCC89019102BFEC810081050102010 +8C90:104020A0D5100A0855F62000D3C41A542A54CBD41A542A54CBD40A44525422C8 +8C91:100023DED6420A42524223DED2001A3E2BD2CA121A142BD4CA080A1452242242 +8C92:0C203124C324152449FC3000CBFE14202440CDFC15542554C55405542954110C +8C93:0C883088C3FE148848883000C9FC15242524CD2415FC2524C524052429FC1104 +8C94:0C203040C3FC150449543124C954150425FCCC00151225D4C51805522992110E +8C95:101E23E0D522089450402088D1F0182028C4C9FE18222820CBFE085050882306 +8C96:11042084D488080053FE2000D08819042A02C9FC19542954C954095457FE2000 +8C97:102021FCD5240BFE512421FCD02019FC2924C9FC18402BFEC88809D05070238C +8C98:0C883088C3FE1488480031FCC90415FC2504CDFC142025FEC450048829041202 +8C99:100023FED6000A7C52442244D27C1A002AEECAAA1AAA2AAACAEE0A0053FE2000 +8C9A:100023DED6520A5253DE2000D1FC192429FCC92419FC2820CBFE082050202020 +8C9B:108823FED4880BDE525223DED0A0189029FEC9201BFC2D20C9FC092051FE2100 +8C9C:13DE2252D7DE0A5253DE20A0D1FE1B202DFCC92019FE2800C9FC08885070278E +8C9D:00003FF8200820083FF8200820083FF8200820083FF800000820101020084004 +8C9E:010001FC010001003FF8200820083FF820083FF8200820083FF8082010102008 +8C9F:0800101020087FFC200400003FF820083FF820083FF820083FF8082010102008 +8CA0:080008001FE020204040BFF820083FF820083FF820083FF80000046018186004 +8CA1:00107C10441044107DFE441044307C30445044507C9001102810241044508020 +8CA2:00003FF801000100FFFE00003FF820083FF820083FF820083FF8082010102008 +8CA3:04200210013EFFC00022001A3FF620103FF020103FF020103FF0084010202010 +8CA4:0020782048204920792C493449647BA449244934792801225122490288FE0000 +8CA5:00407C20440045FC7C00440044F07C90449044907C90009228922512450E8200 +8CA6:00007C0045FC44007C00440047FE7C90449044907C900090289225124512820E +8CA7:044008203018CFE6042018A060401FF010101FF010101FF010101FF008201010 +8CA8:0880109830E057849084107C00001FF010101FF010101FF010101FF008201010 +8CA9:0008781C49E04900790049FC49447944494449287928011051104A288A440482 +8CAA:010002800C603118CFE6004000801FF010101FF010101FF010101FF008201010 +8CAB:00001FF01110FFFE11101FF000001FF010101FF010101FF010101FF008201010 +8CAC:01003FF801001FF00100FFFE00001FF010101FF010101FF010101FF008201010 +8CAD:0008007C3F80208020803FFE208027F8240827F8240827F8240847F842108408 +8CAE:00203F2800240020FFFE00207FA040A07FA040907F9040907F8A120A21064082 +8CAF:00407C20442045FE7D02460444007C0045FE44207C2000202820242044A08040 +8CB0:12207FFC122013E010001FF800001FF010101FF010101FF010101FF008201010 +8CB1:00107810481049FE79124914491079FC494449447928012851104A288A440482 +8CB2:088028882EF028842E84F07C00001FF010101FF010101FF010101FF008201010 +8CB3:0024FFFE00203FA000207FA000203FA020A03F9020903F90208A3F8A11062082 +8CB4:01001FF011101FF00100FFFE00001FF010101FF010101FF010101FF008201010 +8CB5:040008201FF00210FFFE08203018DFF610101FF010101FF010101FF008201010 +8CB6:00047C1E45E044007C20441045FE7C04440844107C20004028802540463E8000 +8CB7:00007FFC444444447FFC00003FF820083FF820083FF820083FF8082010102008 +8CB8:08901088307ED7C01022101A00061FF010101FF010101FF010101FF008201010 +8CB9:00107C10449044907CFE449045107C10441044FE7C1000102810241045FE8000 +8CBA:00007DFC450445047D04450445FC7C50445044507C50005028922492450E8200 +8CBB:04407FF804483FF824403FFC08441FF4301C5FF010101FF010101FF008201010 +8CBC:00207C20442044207C3E442044207C2045FC45047D0401042904250445FC8104 +8CBD:00207C20442044407C48448445FE7C82440044FC7C8400842884248444FC8084 +8CBE:00047C1E45F045107D10451045107DFE451045107D100108290A254A45A68112 +8CBF:060078FC4044484444445A9461081FF010101FF010101FF010101FF008201010 +8CC0:100010007E7C124422442A7C44009FF010101FF010101FF010101FF008201010 +8CC1:01003FF801000820FFFE082000001FF010101FF010101FF010101FF008201010 +8CC2:0080788048F849087B104CA0484078A049184A067DF801085108490889F80108 +8CC3:081813E0304057FC904013F800001FF010101FF010101FF010101FF008201010 +8CC4:00207C2045FE44407C4044FC44847D8446FC44847C8400FC2884248444948088 +8CC5:00207C10441045FE7C20442444447CF8441244227C4401882810242844448182 +8CC6:00827C42444444007CFE444444447C44444445FE7C4400442884248445048204 +8CC7:410021FC0A441048E0A0211826061FF010101FF010101FF010101FF008201010 +8CC8:00007FFC04403FF824483FF800001FF010101FF010101FF010101FF008201010 +8CC9:00207C20444044807DFC455445547D54455445547D5401542954255447FE8000 +8CCA:00147C12441045FE7C10449044927C9247F244947C940088288A251A45268242 +8CCB:00407C20442045FE7C00448845047E02448844887C5000502820245044888306 +8CCC:0100FFFE08401F90062038D007087FF410101FF010101FF010101FF008201010 +8CCD:00207810481049FE7900491049107910497C49107910011051104A108AFE0400 +8CCE:00287C24443E45E07C20443C45E07C20443E45E07C2200242818246A45868002 +8CCF:00007CFC448444847CFC448444847CFC448444847CFC00002848244444828102 +8CD0:00407840488849047BFE4802488879444A4248F8798802505020485089880606 +8CD1:000079FE49004900797C4900490079FE495049527954014851484A448A520460 +8CD2:00207C20445044887D0446FA44007C0047FE44207D2801242A22242244A08040 +8CD3:01007FFE4002BFFC0910316003803FF8E0083FF820083FF820083FF808201010 +8CD4:01007FFE4002BFFC21083FF820002FF828082FF828082FF828084FF844108808 +8CD5:00287C24442444207DFE442045207CB244B444687CA801242A22242044A08040 +8CD6:00207C20445044887D0446FA44207C2047FE44207D2801242A22242244A08040 +8CD7:0020782049FC4924792449FC482078204BFE4A227A2203FE5222482088200020 +8CD8:00207810481049FE7900491049107910497C49107914011251124A108AFE0400 +8CD9:00007CFE449244927CBA449244FE7C8244BA44AA7CAA00BA28822502450A8204 +8CDA:01007FFC092015502388054009203FF8D0161FF010101FF010101FF008201010 +8CDB:082008207EFC0820FEFE145022885FF690101FF010101FF010101FF008201010 +8CDC:00007CFC448444847CFC448444847CFC444044FE7D2A024A28922522444A8084 +8CDD:00007BFE4A024A5278884904482078204BFE4820787000A851244E2288200020 +8CDE:111009207FFE40029FF410103FF820083FF820083FF820083FF8082010102008 +8CDF:00507C50445045FC7D54455445547DFC455445547D5403FE2800248845048202 +8CE0:00407C2045FC44007D08449044007DFE440044007DFC01042904250445FC8104 +8CE1:00803FFE20802FF820883FFE21082FF824102FF8341627F0441047F082200410 +8CE2:00007EFC48447E4442287E1048287FF610101FF010101FF010101FF008201010 +8CE3:0100FFFE01003FF800007FFC44447FFC10101FF010101FF010101FF008201010 +8CE4:00487C44445E45E07C284412446A7D964448445E7DE0002428282412446A8186 +8CE5:00407C2045FE44007C88448845547E22440044207DFE00202820242044208020 +8CE6:00087C0C44EA440A7C0845FE44487C48454845687D480148294A256A47868102 +8CE7:00207CA244A245247C50448847047C22442044A47CA401282850248845048202 +8CE8:01007FFC40041FF000007FFC1110250842041FF010101FF010101FF008201010 +8CE9:004078204BFE4A02780049FC480078004BFE48207928012452224C2288A00040 +8CEA:060C387020403F7E2448244844889FF010101FF010101FF010101FF008201010 +8CEB:01007FFC0920092015507FFE40029FF410101FF010101FF010101FF008201010 +8CEC:00007CFC448044F87C8044F844807FFE454045247D2801102908254445828100 +8CED:00207C2245FA44247C2847FE44207C4044FC45847E8400FC2884248444FC8084 +8CEE:01003FF80108FFFE01083FF801007FFC24885FF410101FF010101FF008201010 +8CEF:010079FE4A024DF2791249F2491279FA48044BF87810002057FE482088A00040 +8CF0:00207C2047FE44207DFC444047FE7C88450446FA7C88008828F82488448880F8 +8CF1:00007BFE4A2248207BFE482049FC792449FC492479FC002053FE482088200020 +8CF2:13F8120823F86040A7FC215022481FF010101FF010101FF010101FF008201010 +8CF3:012879244BA4492079204FFE482078244BA44AA87AA802905392482A88460082 +8CF4:10201020FE7810881110FEFC928492FCFE8410FC388454FC9200104810841102 +8CF5:00007DFE4502457A7D02457A45027C0044FC44847CFC008428FC248444FC8084 +8CF6:00207C20445044487CA445FE46847CFC448444FC7C8000FC29442544467C8044 +8CF7:01007FFC01003D7825483D7801007FFE50129FF410101FF010101FF008201010 +8CF8:00203D2424A825FC24403FFE248825FC268A3CF8248824F8248844F854508888 +8CF9:01047884488848007BFE4800488879044A0249FC79540154515449548FFE0000 +8CFA:011078A048004BFC78A04BF848A87BFE48A84BF878A001B052A84CA688A000A0 +8CFB:00287C2447FE44207DFC452445FC7D2445FC45247C0803FE2888244844488018 +8CFC:008878884BFE488879FC48884BFE782049FC492479FC012453FE490489140108 +8CFD:01007FFE44429FF404403FF80440FFFE08201FF02828CFE608200FE004400820 +8CFE:00207DFE482048FC48205DFE540054FC54845CFC488448FC48847EFC00480084 +8CFF:00007BDE48424A52794A4A52482878C44B1248607988003251C4481888600380 +8D00:7F7848485F4C64805F784A4851307F4C00001FF010101FF010101FF008201010 +8D01:7E2042207E20423E7E4442447E4424A442287E2842107E1042287E4824844302 +8D02:0040788849FC49087A524BFE485079884E2648C07B1000645388483088C00700 +8D03:0020782049FC492479FC48204BFE7A224BFE48207840002452A24A8A8C780000 +8D04:08207E2008F8FF2814287F6A082AFF5608821FF010101FF010101FF008201010 +8D05:08207F20087E7E4408A4FF2810101E2822445FF290101FF010101FF008201010 +8D06:002878244BFE4850788849044A027998495449107BBE011052A84AA88C440882 +8D07:41D42010FBFE109052C8228A57E680021FF010101FF010101FF010101FF00820 +8D08:0104788848004BFE7A224AAA4A727A224BFE480079FC010451FC490489FC0104 +8D09:00007BFE48504BFE7A524BFE480079FC490449FC790401FC50204BFE88200020 +8D0A:28503E7C4890FEFE1528264A44861FF010101FF010101FF010101FF008201010 +8D0B:3FFE225024882DFE369024FC249024FE200027FC240427FC440447FC82080404 +8D0C:00507A52495448507BFE488848507BFE482049FC782003FE5050488889040602 +8D0D:008078F849084BFE7944499249FE7900497C4900797C0100517C4A448A7C0444 +8D0E:008878884BFE488879FC492449FC792449FC48207BFE0222522A4AFA8A0A0206 +8D0F:0100FFFE20003FF800003FF820083FF8000077DC545477D4545C77D65296B462 +8D10:002079FC48244BFE782449FC48207BFE48004AA47C5201FC515449548FFE0000 +8D11:1000FEFC44202820FEFE00007CFC44847CFC44847CFC1084FEFC104810841102 +8D12:7E2051FC7D2445FC7C24514A7EF800003FF820083FF820083FF820083FF80820 +8D13:000C700A51FE550875E85548574A71EA512A5FEC754C054C55EA4A0A82160422 +8D14:3FF820083FF820083FF820083FF8082010107EFC42847EFC42847EFC24484284 +8D15:2010CEFE8A10AA7CAA00EEFEAAAAAAFEAA44AA7CEE44A87C2844487C48288844 +8D16:00207BFE482049FC78004BFE4A527BFE490449FC790401FC510449FC88880104 +8D17:3FFE224025F82D0835F8250825FE26AA240627F8240827F8440847F882100408 +8D18:012478A84BFE4A0278F8488849FC790449FC490479FC010451FC480088880104 +8D19:0E1C08107EFC4A945CB84A945CB8952A22461FF010101FF010101FF008201010 +8D1A:011078904BDE48107A5E49824BDE78104BDE4A507BDE025053DE4A508A5202CE +8D1B:1040FE7C44C82830FECE00787C2045FC7C8844F87C8810F8FE8810F810501088 +8D1C:0090709057FE5094700A51FE550877E8514A51EA7F2A05EA554C49EA82160462 +8D1D:00001FF010101010101011101110111011101110121002800440082010102008 +8D1E:0100010001FC010001003FF820082108210821082208220804C008303008C004 +8D1F:040004000FE0102020405FF010101110111011101110121002C0042018106008 +8D20:02000400082010103FF8000800001FF01010111011101110121004C018306008 +8D21:00003FF8010001007FFC000000001FF01010111011101110121004C018306008 +8D22:00107C104410541055FE54105430543054505450549011102810241044508020 +8D23:010001007FFC01003FF80100FFFE00001FF0101011101110111002600C187004 +8D24:040025F824882450242024D8270604001FF0101011101110111002600C187004 +8D25:00407C404440548054FE55085688548854885450545010202850248845048202 +8D26:00807C8444845488549054A0548055FE54A054A054901090288824A444C28080 +8D27:08800880109830E057849084107C00001FF0101011101110111002600C187004 +8D28:007C3FC0204020403FFE2040204027FC240424442444244424B4410846049802 +8D29:00047C0E44F04480548054FC54A454A454A454A854A810902910252842448082 +8D2A:01000280044009203098CFE6004000801FF0101011101110111002600C187004 +8D2B:044008203018DFE60420042008A010403FF0101011101110111002600C187004 +8D2C:00087C3C45C044005420541055FC5404540854105420104028802540423E8000 +8D2D:00807C80448054FC5504550456445444548454A4551411F42814240444288010 +8D2E:00407C204420540055FE5502560454005400540054001000280025FE44008000 +8D2F:1FF011101110FFFE111011101FF000001FF0101011101110111002600C187004 +8D30:00280024FFFE00203FA000207FA000203FA0209024902490248A0A0A11066082 +8D31:00507C484440445C55E05440545E57E054445448543010222852248A43068002 +8D32:01003FF801000820FFFE082000001FF01010111011101110121004C018306008 +8D33:12201220FFFE122013E010001FF800001FF0101011101110111002600C187004 +8D34:00207C2044205420543E54205420542055FC5504550411042904250445FC8104 +8D35:01001FF0111011101FF00100FFFE00001FF0101011101110111002600C187004 +8D36:00007DFC450445045504550455FC5450545054505450109228922512420E8400 +8D37:08901088307ED7C01022101A00061FF01010111011101110121004C018306008 +8D38:060078FC4044484444445A94610800001FF0101011101110111002600C187004 +8D39:04407FF804483FF824403FFC0844105420085FF010101110111002C00C303008 +8D3A:100010007E7C124422442A7C44009FF01010111011101110121004C018306008 +8D3B:00207C20442054405448548455FE5482540054FC548410842884248444FC8084 +8D3C:00147C12441045FE541054905492549257F2549454941088288A251A41268242 +8D3D:10801080FBF010901990F0941154520C24041FF010101110111002C00C303008 +8D3E:00007FFC04403FF8244824483FF800001FF0101011101110111002600C187004 +8D3F:00207C2045FE5440544054FC5484558456FC5484548410FC2884248444948088 +8D40:088008882E9028E028842E84F07C00001FF0101011101110111002600C187004 +8D41:083813C03040504097FC1040104013F800001FF010101110111002C00C303008 +8D42:00407C40447854885550542054505488550654F8548810882888248844F88088 +8D43:00207C10441045FE5500551055105510557C5510551011102910261042FE8400 +8D44:0100410021FC0A441448E0A02110260C1FF0101011101110111002600C187004 +8D45:00207C10441047FE54205442548455F85410542254C413082810242840C48302 +8D46:00007CFC4484548454FC54905490548854845532550812002860241844048000 +8D47:00287C244424542055FE5420552054B254B4546854A811242A22242044A08040 +8D48:00007DFE45004500557C5500550055FE55505552555411482948264442528460 +8D49:010001007FFC11100920FFFE054009203018DFF610101110111002C00C303008 +8D4A:00207C2044505488550456FA5400540057FE5420552811242A22242244A08040 +8D4B:00087C0C44EA440A540855FE544854485548556855481148294A256A43868102 +8D4C:004000407C4445FC4448545057FE544054F85588568854F82888248844F88088 +8D4D:01007FFC0920092015507FFE400280041FF0101011101110111002600C187004 +8D4E:00207C2045FC4420542057FE5402549454505510549013FE2828244440828302 +8D4F:111009203FFC20044FE808200FE000001FF0101011101110111002600C187004 +8D50:00007CFC4484548454FC5484548454FC544054FE552A124A28922522444A8084 +8D51:1FF010101110111002C00C30700800003EF822882AA82AA82AA8145022884104 +8D52:00007DFC452445245574552455FC550455745554555411742904260442148408 +8D53:00803FFE20802FF820883FFE21082FF824102FF8341624904490416082100C08 +8D54:00407C2045FC540055085490540057FE5400540055FC11042904250445FC8104 +8D55:00207CA244A245245450548857045422542054A454A411282850248841048202 +8D56:10801080FEF8110812107DFC5504552455247D24112439245450908811041202 +8D57:00007DFE4502457A5502557A5502540054FC548454FC108428FC248440FC8084 +8D58:08207F20087E7E4408A4FF2810101E28224446829FF01010111002C00C307008 +8D59:00287C2447FE542055FC552455FC552455FC5524540813FE2888244844488018 +8D5A:00887C50440055FE545055FC545457FE545455FC545010D82954265244508050 +8D5B:01007FFE44429FF404403FF80440FFFE08201FF02928C92609200AA004401820 +8D5C:00207DFE482048FC48205DFE540055FC55045D244924492449247E5000880304 +8D5D:3FFE225024FE2D9036FC249024FC249024FE200027FC2444444440B0830C1C02 +8D5E:081028503E7C48907EFE14282548468A81061FF010101110111002C00C303008 +8D5F:41D42010FBFE109052C8228A57E680021FF0101011101110111002600C187004 +8D60:00887C48445055FC552455AC5574552455FC540054F8108828F8248844F88088 +8D61:00807CF8450847FE5544559255FE5500557C5500557C1100297C2644427C8444 +8D62:0100FFFE20003FF800003FF820083FF8000077DC54547554555C75565296B462 +8D63:1040FE7844D02920FE5801867CF844207DFC44007CF81088FEA810A810501188 +8D64:0100010001003FF801000100FFFE044004402448244444428842084011402080 +8D65:0810081008107E10083E0822FF44149014105610551095282428242454448882 +8D66:0820082008207E40087E0884FF44144414445628552895102410242854448882 +8D67:080008FC08847E8408940888FF8014FC14A456A455A894A8249024A854C48882 +8D68:0810081008107EFE08920892FF92149214FE5692551095142412241E54F28800 +8D69:0820082008787E480890087CFF5414541454567C5540954024422442543E8800 +8D6A:08100810081E7E10081008FEFF82149214925692559294922428242454428882 +8D6B:0820082008207EF808200820FEFE1450145056D8555494522450249054908930 +8D6C:08200820083E7E20082008FCFF8414FC148456FC558494FC2400244854848902 +8D6D:0820082408F47E28082808FEFF101420147C56C45544957C24442444547C8844 +8D6E:100011DC11447D44114411DCFF00290029DC6D14AB1429D42908490849149922 +8D6F:1020101011FE7D10117C1114FDFE2914297C6D10AB7C294429444A444A7C9C44 +8D70:0100010001003FF801000100FFFE01000100110011F811001100290047FE8000 +8D71:010001003FF8010001000100FFFE00002010102000C003000C00130020FE4000 +8D72:0820082008207E2008FC0824FF240824282428442E442894290858004FFE8000 +8D73:0804080408447E4408440844FF44084C285428642E042804280458004FFE8000 +8D74:0420042004203F20043004287FA404240420242027A02420242054004FFE8000 +8D75:0800080408847E4408280828FE100810282828282E442884280058004FFE8000 +8D76:080008FC08207E2008200820FE2009FE282028202E202820282058204FFE8000 +8D77:0800080008F87E0808080808FEF80888288028802E842884287C58004FFE8000 +8D78:0810081008107E1008920892FE920892289228922E9228FE280258004FFE8000 +8D79:0820082008407EFE09020842FE220822280A28322EC22802281458084FFE8000 +8D7A:0820082008507E5008880944FE2208F8280828102E102820282058004FFE8000 +8D7B:0810081008107E5408520852FE900812280428082E102860298058004FFE8000 +8D7C:0420042004203F3E044204047F9004100410242827A42442248254004FFE8000 +8D7D:0820082008207EFC08240824FE2409FE282028502E482884290458004FFE8000 +8D7E:0800080C08707E400840087EFF480848284828482E882888290858004FFE8000 +8D7F:1004101E11F07D1011101110FDFE1110111051105D10514A5186710250008FFE +8D80:0810081008167EF808900890FEFE0812283228522E962910281058104FFE8000 +8D81:0820082008507E5008880924FE420890282028442E882810282058404FFE8000 +8D82:0840084008407EFE08820924FE2008A828A429222E2228A0284058004FFE8000 +8D83:082008A008A07EFC08A00920FE2009FE282028502E482884290458004FFE8000 +8D84:080008F808887E8808F80888FF8808F8288828882E8829FE280058004FFE8000 +8D85:080009FC08447E4408440894FF0808FC288428842E8428FC280058004FFE8000 +8D86:0800081C08F07E90089008FEFE900890289028AA2ECA28A6281258004FFE8000 +8D87:0820081008107EFE08040844FF440828282828282E1028FE280058004FFE8000 +8D88:0820082008207E3E08200820FF2008FC288428842E8428FC288458004FFE8000 +8D89:0810081008927E92089208FEFF100892289228922E9228FE280258004FFE8000 +8D8A:1028102410207DFC11201124FD241128112851105D94512C704450004FFE8000 +8D8B:0840084008787E88091008FCFE04080428FC28042E0429FC280058004FFE8000 +8D8C:0810081008107EFE0810087CFF00087C284428442E44287C284458004FFE8000 +8D8D:10201020107C7C8813501024FCC8131E102250E45C1850105060738050008FFE +8D8E:0810085008507EFC09100810FEFE0830283828542E942910281058004FFE8000 +8D8F:081C08E008207E2009FE0820FE2008FC288428842E8428FC288458004FFE8000 +8D90:080009DC08447E44095408CCFE4408CC295428442E44285428C858004FFE8000 +8D91:1020122011207D3E10421084FC901090131051105D2851245142708250008FFE +8D92:0810085008507E50095408D8FE5008D8295428522E922892290E5A004FFE8000 +8D93:100010F810887C8810881088FD26122011FE50205C7050A85124722250208FFE +8D94:100213F210827C8A108A11EAFD2A112A12AA504A5C4A5082510A720450008FFE +8D95:0800087C08447E7C0844087CFF00087C281028102EFE2810281058104FFE8000 +8D96:0810081008547E54085408BAFF100810287C28102E1028FE280058004FFE8000 +8D97:080008F808887E88088808F8FE2008A028BC28A02EA029602A3C58004FFE8000 +8D98:080008FE08827EFE0880088CFEF0089C28F0289E2EF02912290E5A004FFE8000 +8D99:0810089208547E1008FE0882FEFE088228FE28822E82288A288458004FFE8000 +8D9A:0820082009FE7E20082009FCFF24092429FC28702EA829242A2258204FFE8000 +8D9B:0820082008507E8809040AFAFE20082029FC28202EA828702BFE58004FFE8000 +8D9C:0880088009FE7E2208AA0872FE2209FE282228722EAA2922282A58044FFE8000 +8D9D:1020102010507C8811441222FDF81008105050205CA4528A528A747850008FFE +8D9E:0848084808FC7E48084809FEFE0008FC288428FC2E8428FC288458004FFE8000 +8D9F:1020112410A47CA811FC1104FD041174115451545D745104710C50004FFE8000 +8DA0:10201020103E7C2011FC1104FDFC110411FC51245C2053FE5020702050208FFE +8DA1:0850084808807EFE09900A90FEFC0890289028FC2E90289028FE58804FFE8000 +8DA2:11F8100810F87C0813FE1020FC24112410A850705CA85324502470A050408FFE +8DA3:100013E0115E7D4211D2114AFD4A11C4114451645DCA534A705250404FFE8000 +8DA4:0820081008FE7E82080008FEFF20084028FC29442E44287C284458004FFE8000 +8DA5:1088105013FE7C50105011FCFD54118C110451FC5D04510451FC710450008FFE +8DA6:1220113E10427C9413101128FC46100011FC51045D04510451FC710450008FFE +8DA7:080008FC08847EFC088408FCFE0009FE2810289C2E902890297E5A004FFE8000 +8DA8:108011FC12447D5411F41084FD18108011FC52445D5451F45084711850008FFE +8DA9:100011FC11247DFC112411FCFC88108811FC50885C8853FE5088710450008FFE +8DAA:1088108811FC7C88108813FEFC2011FC112451FC5D2451FC5000708851048FFE +8DAB:103C13C010407BFE10901108FAF4149213FC52045AF4529452F4720C50008FFE +8DAC:0810087C08107EFE084408EEFE4408EE280028FE2E28282A284658804FFE8000 +8DAD:10A0109011FE7D2013FC1120FDFC1120112051FE5C0052A45252745250008FFE +8DAE:0800087C08447E7C080008EEFEAA08EE281028FE2E382854289258104FFE8000 +8DAF:080009EE08AA7E6608AA0850FEFE099028FC28902EFC289028FE58804FFE8000 +8DB0:100013FE11247A2217FE1376FAAA1376122253765AAA53765222720650008FFE +8DB1:1108152817BE794817BE1318FDAA194613F852085A48524850A0711052088FFE +8DB2:152817BE19487FBE131815AAF94613FC120453FC5A0453FC520473FC51088FFE +8DB3:00001FF010101010101010101FF001000100110011F811002900250043FE8000 +8DB4:00007C204520452045207D20112011205D205110511052105E08E40808041002 +8DB5:00407C40444044FC44847D04100411045C845044504450045C04E00400280010 +8DB6:00007DFC4420442044207C20102013FE5C205020502050205C20E02000A00040 +8DB7:00407C40448044FE45007E0010FC10085C105020504050805D02E10200FE0000 +8DB8:0000FFFE040007F0081010A0604000001FF010101FF0010011F81100290047FE +8DB9:00207C20442045FC44247C24102410245DFE5020505050505C88E08801040202 +8DBA:00207C204420442045FC7C20102010205DFE5020505050505C88E08801040202 +8DBB:00207C204450445044887D44122210205C0051FC500450085C08E01000100020 +8DBC:00007DFE4448444844487C48104813FE5C485048504850485C88E08801080208 +8DBD:00407C20442047FE44807C80108010FC5C845084508450845D04E10402280410 +8DBE:00207C204420452045207D20113C11205D205120512051205D20E12007FE0000 +8DBF:00007BFC4884488848887890109C108451445D44512851285A10E22804440182 +8DC0:00007CFC4484448444847CFC108410845C8450FC508450845D04E10402140408 +8DC1:00007DFC4524452445247D24112411FC11045D005100510051025D02E0FE0000 +8DC2:00207C20442045FE44207C20102011FC5C845088504850505C20E05001880606 +8DC3:00087C3C45E0442044207C2013FE10205C205050505050505C88E08801040202 +8DC4:00207C204450445044887D04120210F85C88508850A850905C82E082007E0000 +8DC5:00087C1C45E0450045007D0011FE11105D105130511851145D12E21002100410 +8DC6:00207C204440444044887D0413FE100210005DFC5104510451045D04E1FC0104 +8DC7:00487D484548454845487FFE114811485D485148517851005D00E10001FE0000 +8DC8:00207C204450448845047E121020104011885C105020504451885C10E0600380 +8DC9:00207C204450445044887D24121210105DFC5004500850885C50E02000100010 +8DCA:00207C20442045FC44207C20102013FE5C7050A850A851245D24E22200200020 +8DCB:00507C484448444047FE7C80108010FC5D445144512851285E10E22804440182 +8DCC:00207C204520452045FC7D201220102011FE5C205050505050885C88E1040202 +8DCD:00207C204420442047FE7C201020102011FC5D045104510451045D04E1FC0104 +8DCE:00207C10441045FE45027E04108010885C9050A050C050825C82E082007E0000 +8DCF:010079004900491C4BD479541154115451545D54515451545954E25C03540480 +8DD0:00487C4844484548454A7D6C114811485D4851485148514A5D6AE38A01060000 +8DD1:00807C8045FC450446047DF4111411145D1451F4510451285D12E10200FE0000 +8DD2:00007C0045FE440844087DE81128112811285D2851E8512850085C08E0280010 +8DD3:00407C20440047FE44207C20102010205DFC5020502050205C20E02003FE0000 +8DD4:00807C80450045FC46047C0411E411245D24512451E451245C04E00400280010 +8DD5:00207C2044204420443E7C201020102011FC5D045104510451045D04E1FC0104 +8DD6:00007C0045FE442044207C40104010FC10845D845284508450845C84E0FC0084 +8DD7:0088788848884908497E7B081508114851285D28510851085908E10801280110 +8DD8:00207C20452444A444A87C2011FC10205C20502053FE50205C20E02000200020 +8DD9:00007DF84508450845087DF8110811085D0851F8510851085D08E10807FE0000 +8DDA:00007DDC4554455445547D54115413FE5D545154515451545D54E2D40224044C +8DDB:00107C10441045FE45127D14111011FC5D445144512851285D10E22802440482 +8DDC:00007DFC4504450445047DFC110011405D445148517051405D42E242023E0400 +8DDD:00007DFE4500450045007DFC110411045D04510451FC51005D00E10001FE0000 +8DDE:00087C1C45E0450045207D20112011FE5C20502050A850A45D22E22200A00040 +8DDF:00007DF84508450845F87D08110811F85D445148513051205D10E14801860100 +8DE0:00207C2047FE442045FC7C2411FC112011FE5C22502A505450505C88E1040202 +8DE1:00407C20442047FE44907C90109012945E925292549250905D10E11002500420 +8DE2:00207C20447C448445487C30102010485D90503E504251A45C18E01000600180 +8DE3:00207920492049FC49207A20102013FE50905C90509050905912E1120212040E +8DE4:00407C20442045FE44007C881104120210885C885050505050205C50E0880306 +8DE5:00007DFC44444448445E7C82108A11245C2053FE502050705CA8E12402220020 +8DE6:00207D20452045FC45207E20102013FE5C7050A850A851245D24E22200200020 +8DE7:00207C204450448845047E0211FC10205C20502051FC50205C20E02003FE0000 +8DE8:002078204BFE48504888790416FA100053FE5C40508051FC5804E00400280010 +8DE9:00207C2045FC452445247DFC112411245DFC5020502450185C32E0CA03060002 +8DEA:00407C4044FC450446087DFE1100117C5D445144515451485D42E242023E0400 +8DEB:00007DF01110119011521D12E20E44001FF010101FF0010011F81100290047FE +8DEC:00207C2045FC442044207C2013FE10005C20502051FC50205C20E02003FE0000 +8DED:0080788048FC49084A9078601198162610205DFC5020522053FE5C20E0200020 +8DEE:00007DFE4420444044887D0411FE10225C20502051FE50205C20E02003FE0000 +8DEF:00407C404478448845507C201050108811065CF85088508850885C88E0F80088 +8DF0:01047C844488440045FE7C88108810885C8853FE508850885D08E10802080408 +8DF1:00207C20442045FC44207C2013FE100810085DFE5008508850485C08E0280010 +8DF2:00207C204450448845047E0211FC100010005DFC5104510451045D04E1FC0104 +8DF3:00507C504450455244D47C581050105810D45D525050505050925C92E112020E +8DF4:00007BFE48504850485079FC115411541D545154515C518451045D04E1FC0104 +8DF5:00507C484440445C45E07C40105E11E05C445048503050225C52E08A03060002 +8DF6:00107A104910491048FE78101310112851245D44514251825900E280047E0000 +8DF7:00807C8044BC47C044507C2410D4130C5C0053FE509050905D12E112020E0400 +8DF8:01107D12451445D845107D121152118E11205C2053FE502050205C20E0200020 +8DF9:00007A0C497049104810781010FE171051105D10511051105910E280047E0000 +8DFA:00007CF84488448844887C88112612205DFE5020507050A85D24E22200200020 +8DFB:00407C2045FE448844507C201050108811065C885088508850885D08E1080208 +8DFC:00007DFC4504450445FC7D00110011FE5D02517A514A514A5E7AE20204140008 +8DFD:00007DF84408440845F87D00110411045CFC5040502050A45E8AE28A04780000 +8DFE:1040104024FE6488A5502420245020881FF410101FF0010011F81100290047FE +8DFF:00207C2045FC442044207C2013FE10205C205120513C51205EA0E260043E0800 +8E00:00007DFC4504450445047DFC102010205D20513C512051205EA0E260043E0800 +8E01:00007DFE4400449245247E481124109210005DFE5020502050205C20E3FE0000 +8E02:00007BFE49204928492879E81128112851285DE85128512A593AE3EA00260020 +8E03:00207D2444A444A844207DFC110411045DFC5104510451FC5D04E10401140108 +8E04:00107C104490449E44907C9013FE10005C105092509251145E08E01000600380 +8E05:080C08F07E8008800EFE78880888290812081FF010101FF0010011F83100CFFE +8E06:00407C404488450447FE7C021088114412425CF85188525050205C50E1880606 +8E07:00807C8044FE450046FC7C8410A410945DFE5084512451145DFEE00400280010 +8E08:00207C2047FE442044207DFC112411245DFC5020507050A85D24E22200200020 +8E09:00407C2045FC450445047DFC1104110411FC5D205122511451085D44E1820100 +8E0A:00007DF8440844D044207DFC112411245DFC5124512451FC5D24E1240124010C +8E0B:0100F100911E93929112F112211227D2A112B912A21AA294A7D0B250C0100010 +8E0C:00207C2047FE442045FC7C4013FE10485C8850FE510851485E28E40800280010 +8E0D:00207C2245FA442444247DFE1010102011FC5C88511052FE54105C10E0500020 +8E0E:00007DFE4410442044687CA41122102010005CFC5084508450845C84E0FC0084 +8E0F:002078224BB448A848A8792412A2104051FC5D04510451FC5904E10401FC0104 +8E10:00487C44445E45E044287C12106A119610485C5E51E0502450285C12E06A0186 +8E11:00887C8847FE448844887CF8108810885CF85088508853FE5C00E08801040202 +8E12:001C7DE04420442047FE7CA8112412425C4053FE508851085CD0E03000480184 +8E13:00A07C90449045FE45207D2013FC112011205DFC5120512051205DFEE1000100 +8E14:00207C20443E442045FC7D0411FC11045DFC5124502053FE5C20E02000200020 +8E15:00207C2047FE442045FC7C2413FE10245DFC50205120513E5D20E2A0027E0400 +8E16:00487C48444845FE44487C4811FE100010FC5C84508450FC50845C84E0FC0084 +8E17:00207C204450448845447E2211F810085C50502050A452825E8AE28A04780000 +8E18:01007D0045FC460444447D5410E4104413FC5C4450E4515452445C44E0140008 +8E19:00007BE0495C495449D47954115411D451545D54516853C85848E05400540062 +8E1A:00207C204450448845047EFA100011FC11545D5451FC515451545D54E104010C +8E1B:00207C2045FC442044207DFE108811045E22502051FC50205C20E02003FE0000 +8E1C:0020782049FC482048207BFE1088114412425CF85188525050205C50E1880606 +8E1D:00007DFC4524452445FC7D24112411FC10205DFE507050A851245E22E0200020 +8E1E:00007DFE4502450245FE7D10111011FE5D105110517E51425D42E242027E0442 +8E1F:0100790049004BDE4A927C921092109253F25C9250925152595EE22004200800 +8E20:004078204BFE4A024D04790011DE12521E525352549A509451105D12E212040E +8E21:00207D2444A8442045FC7C4013FE10885D0452FA548850885CA8E0920082007E +8E22:00007CFC4484448444FC7C84108410FC5C4050FE512A524A5C92E122004A0084 +8E23:00407C2045FC440045087C90100013FE10005C0051FC510451045D04E1FC0104 +8E24:00407C2045FE440044887C881154122210005C2053FE502050205C20E0200020 +8E25:00407C2045FC440044887C5013FE10405C4053FE508851885C50E03000C80304 +8E26:00207C2045FC445044887D0413FE10085DE85128512851E85D28E00800280010 +8E27:00807C80449C44F444947C9413F4101410945C9451C852A850885C94E09401A2 +8E28:008878884888488849547A221442102050205D20513C51205AA0E260043E0800 +8E29:00087C3C45C0444445247CA8108010205DFE507050A850A85D24E22204200020 +8E2A:004078204BFE4A024C0479F81000100053FE5C20512851245A22E42200A00040 +8E2B:01087C90440045FC44907C901092129211945D985090509050905C90E3FE0000 +8E2C:001C7DE04510451045FE7D101110117C5D445154515451545D54E22802440482 +8E2D:00807C8044F8450846107DFC102410245DFE5024502451FC5C24E02000A00040 +8E2E:00207C1045FE450045207D20113C11205D20517C514451445D44E244027C0444 +8E2F:0440F25E9292901297D4F11421182114A7F2B912A112A11ABA94E25004500810 +8E30:00207C504488450446FA7C0011E2112A5D2A51EA512A512A5DEAE122012A0164 +8E31:00407C2045FE454845487DFE114811785D0051FC514451485D28E210022804C6 +8E32:00087C1C45F0451045107DFE1110117C5D44517C5144517C5D44E244027C0444 +8E33:00207C2047FE442045FC7C4013FE10885D0452FA508850885CF8E088008800F8 +8E34:00007DFC4448443045FC7D2411FC11245DFC5124504051FC5C44E08401140208 +8E35:00087C3C45E0442047FE7C2011FC11245DFC512451FC50205DFCE02003FE0000 +8E36:00007DFC4504450445FC7D04110411FC5C0053FE502051205D3CE12002A0047E +8E37:00207C2245FA442444287FFE1020104010FC5D84528450FC50845C84E0FC0084 +8E38:00887C8847FE448844F87C8810F810885C8853FE510051485D84E10001FE0000 +8E39:00207D244524452445FC7C0013FE10205C4051FC515451545D54E1540154010C +8E3A:001078104F7C491449FE7A14127C1710517C5D1055FE52105A10E50008FE0000 +8E3B:00007CFC4484448444F47C94109411FE5D02517A514A514A5D7AE102010A0104 +8E3C:00007CFC448444FC44847CFC100011FE5C8050FE512A524A5C92E12200540088 +8E3D:00047C1E47E0442045FC7D24112411FC5C2053FE5222522A5EFAE202020A0204 +8E3E:00007DFE440044FC44847C8410FC100011FE5D22512251FE51225D22E1FE0102 +8E3F:000878C84B084908492A792A13AC11481D0853885554511451145D24E1240142 +8E40:00487D48454847FE45487D48117811005DFE502053FE50705CA8E12406220020 +8E41:00407C2045FE450245027DFE110011005DFE51AA51AA52FE5EAAE2AA04A20086 +8E42:00007DFC4448443047FE7C52109411105E30502053FE50705CA8E12406220020 +8E43:00887C8847FE448844A87C2013FE104010805CFC5184528450845C84E0FC0084 +8E44:00407C2045FC440044887C5013FE12225C2451FC512451245D34E12800200020 +8E45:00207C2047FE447044A87D24122211FC5D0451FC510451FC5D04E00003FE0000 +8E46:00007A7C49444944487C78441744117C11505D4A5144515451625D42E280047E +8E47:01007FFE44429FF404403FF80440FFFE08201FF02828CFE6010009F0150023FC +8E48:001E7DE04422451244947C80102011CE11025D0251CE510251025D02E1FE0102 +8E49:00847C44444845FE44207CFC102011FE5C40508050FE51105E10E41001FE0000 +8E4A:001E7BE0492248944840788811F0102050C45DFE502250205BFEE05000880306 +8E4B:00007DFC450445FC45047DFC1000100013DE5C425252514A52525C42E14A0084 +8E4C:00207C204450444844A47DFE128410FC5C8450FC508050FC5D44E144027C0044 +8E4D:00007BFC4A044A044BFC7A48124812FC12485E4853FE52A452A85C90E4C80886 +8E4E:00207C2047FE442045FC7D0411FC110411FC5D0451FC510453FE5C88E1040202 +8E4F:0004781E4BF04A1E4A107AFE1292129852F25E8E528052B85AA8E4AA054A0A86 +8E50:00207D2444A8455444887D0412FA148810885CF85088508850F85C88E0880098 +8E51:00007DFE448444FC44847CFC108613FC5C0453DE505251525C94E14802540422 +8E52:00487C4845FE444844007DFE104810485DFE514A514A51B65D22E102010A0104 +8E53:00407DBC4514459445547DA4114C100011FC5D24512451FC51245D24E1FC0104 +8E54:08047F7808403E402A7E3E482A48FF4808881FF010101FF0010011F83100CFFE +8E55:00007DFC452445FC45247DFC10A810A85DFE50A850A851FC5C20E3FE00200020 +8E56:00207C2047FE442045FC7C4013FE10885D045242559C51045DDCE10401FC0104 +8E57:004078204BFE4A504A507BFE1252125253FE5E00529252D45A98E49204D2088E +8E58:00007BDE48424A52494A7A52102810C453125C605188503259C4E01800600380 +8E59:00243FFE222023A422243FA82B10529A46269FF210101FF0010011F83100CFFE +8E5A:0020792448A84BFE4A0278F8108810881CF85020502051FC50205C20E3FE0000 +8E5B:02A8F2A897FC92A892AAF4E6280027FCA444B840A3F8A248A248B248C2580040 +8E5C:002078104BFE4A02488078FE111013201D7C51445144517C51445D44E17C0144 +8E5D:010879084A284CAE48A87928137E15001D085128512E512851585D48E1860100 +8E5E:000078FE48104A204A7C7A4413C4127C52445E7C52C453445A7CE02800440082 +8E5F:00207BFE482049FC48207BFE100011FC1D0451FC510451FC51045DFCE0880104 +8E60:004078204BFE4A004A487A4813FE124852485E48527852005D54E52A0A2A1000 +8E61:00487D48455E456A45547DC81050106413C45D7E5144516451545D44E2540448 +8E62:004078204BFE488848507BFE122212FA52225EFA528A528A5AFAE202020A0204 +8E63:00887C8847FE448844887CF8102013FE5E22533252AA53765E22E222022A0224 +8E64:012479244A244CA44954794A1392150811085D28512E512851285D58E14E0180 +8E65:00107C1046FE4510457C7C54107C13545D7C511051FE51105D10E290047E0000 +8E66:00207A224A224BFE48007BDE1252125253DE5E52525253DE5A52E252055A08A4 +8E67:009078904FFE48904BFC7A9413FC129453FC5C0051F8510859F8E10801F80108 +8E68:0110791449D24A504A7E7D50109012A851285D44524454825808E2A402520452 +8E69:49202A3E7F4849485DA86B10492841461FF010101FF0010011F81100290047FE +8E6A:002079FC492449FC48207BFE100011FC11045DFC510451FC51045DFCE0880104 +8E6B:000079FC484848304BFE7852109413501C2053FE5252528A53765E52E2720206 +8E6C:00107BD248544948488A790412FA140051FC5D04510451FC5904E08807FE0000 +8E6D:0104788848004BFE4A227AAA1272122253FE5C0051FC510459FCE10401FC0104 +8E6E:00007DFC445045FC45547DFC102013FE5C48508451FA52885CF8E0840084007C +8E6F:003C7DE0452444A845FE7CA8112412025DFC5124512451FC5D24E12401FC0104 +8E70:00007BFE4A004A044BF47A0412EE12A452A45EEC520452A45A44E27405940008 +8E71:00207DFC4488445047FE7C0011FC11245DFC512451FC50205DFCE02003FE0000 +8E72:008878504BFE485049FC7954118C117451045DFC500853FE5908E08800A80010 +8E73:00247BA848924D144A087C0413BA10A81CC65380523C538450A85C90E2A80144 +8E74:0214F1129FD29010907EF79024902490A790B928A5A8A568A928B14AC54A0286 +8E75:08287F2400FE3E2022503E504952988E00001FF010101FF0010011F83100CFFE +8E76:0000F7FE940096289548F7EE24922484A6A0BEA8A7E8A488BC94E51409241242 +8E77:3FFE289025103FDE22222A882F88229424222BF8220823F82040427C454088FE +8E78:0020792448A84BFE48A879241222110411045DDE52445554509E5D04E2040404 +8E79:00207C504488457446027CF8108810F810005DDC5044515450CC5D54E04400CC +8E7A:0020782049FC48204BFE7908139C11081D88563E500053FE50905C90E112020E +8E7B:00187DE0444047FE44887D741252107010005DFC5104517451545D74E104010C +8E7C:00507A52495448504BFE7888105013FE50205DFC502053FE5850E08801040602 +8E7D:00207C2045FC442045547C88110412FA10885CF8508850F850205CA8E1240060 +8E7E:010878884BC848104BDE7A6413D4101413D45C54509450E853885C94E2940122 +8E7F:004078204BFE4A8A49247A2211FC112451FC5C2053FE52225BFEE22200200020 +8E80:00007DFC452447FE45247DFC100011FC5D0451FC510451FC5D04E1FC00880104 +8E81:00F87C88448844F844007DDC115411545DDC502053FE50705CA8E12402220020 +8E82:00107A10497C481048FE7844132811FE11105D7C511051FE51105D10E2FE0400 +8E83:001078084BC84A7E4A407A5413C8127E52085FC8537E55485D48E5C809480008 +8E84:3E1022FE3E4420287EFEA2103EFC221000001FF010101FF0010011F83100CFFE +8E85:00007DFC4554455445FC7C8011FC124411F45D54515451F450445DF4E0140008 +8E86:0040787C48404BFE4A427A7813C4123C1E0053FE524053A452585DB4E45209B0 +8E87:008878884BFE48A8482279FA1024102853FE5C4050FC51845AFCE48400FC0084 +8E88:008879084BC84A504BDE7A6413D4111450945FF4511451C85948E254035404A2 +8E89:0820FFFE08201FF011101FF011107FFC41245FFC10101FF0010011F83100CFFE +8E8A:00207BFE482049FC48007BFE100211FC1C2053FE500053FE50045FBEE2A4038C +8E8B:0080F04097FC911090A4FF5825542552AB58B800A208A3F8BA08E3F802080408 +8E8C:008079004BFE4D5449547BFE1154115413FE5D0451DE524451545C9EE1040204 +8E8D:00007BDE48424A52494A7A521090110813FE5D1051FE511051FE5D10E1FE0100 +8E8E:0000F7FC924894449FFEF44426EC2554A6ECBC44A6ECA554A6ECB444C4540408 +8E8F:00487DFE4448450044BE7C821152117E11D25D7E5152517E51525D7EE1420106 +8E90:01247A48492448004BFC7A941264129413FC5E4853685248536A5E4AE2460362 +8E91:0440F28E9FEA928A9FEAFAAA2C6C2BAAA82ABFEAA10AAFEAA28CB448C8280008 +8E92:012479744A584ADA4BFE795412DA13FE10A25C2053FE507050A85D24E2220020 +8E93:00427B9C4A104BDE4A947A94142013FC52045FFC520453FC5A04E3FC01080204 +8E94:0020F7FE940095FC9524F5FC252425FCA420BDFCA420A7FEBD24EAFA082013FE +8E95:004078204BFE4A444BF47A4412EE120452F45EAC52E452145AA4E47405940808 +8E96:01107A124BAA493A4A927BBA108A13FE1D12521253AA513A52925FBAE08A03FE +8E97:22004F9C94802FDE6108AFC8250827D801001FF010101FF0010011F83100CFFE +8E98:011078904BDE48104A5E798213DE101013DE5E5053DE525053DE5E50E25202CE +8E99:03DE7A524BDE4A524BDE7A22129212FA1FA252FA52A252FA52A25EFAE2820206 +8E9A:0000F0FE942892FE92AAF0FE201021FEA644BAFEA344A27CBA42E23E050008FE +8E9B:22004F9C94802FDE6208AFC82A482AD800001FF010101FF0010011F83100CFFE +8E9C:0108F52897BE994897BEF31825AA2946A000BBF8A208A248BA48E0B001080604 +8E9D:03DE7A524BDE4A524BDE7A2212FA122252FA5EAA52FA52AA5AFAE27202AA0226 +8E9E:0248F2E8930896EA9A1CF2E8220822E8A5B4B8E2A000A3F8B910E0E003180C06 +8E9F:00207BFE480049DC495479DC108813FE1C8853FE508853FE50945D88E2A400C2 +8EA0:0820FFFE28207DFC44887DFE40207DFC44207FF010101FF0010011F83100CFFE +8EA1:03FCF10891F8910891F8F10E27F82008A7FEBA94A39CA294A39CB2D6C7BC0084 +8EA2:079EF492979E949297FEF51225F22512A5F2BC02A7BAA6AAA59AB6AAC59A0406 +8EA3:03DE7A524BDE4A524BDE7A5213DE109011FE5D1053FE551051FE5D10E1FE0100 +8EA4:0108F7FE910890009114F7BE21142794B17EAF80A13EA3A2B57EC922013E0122 +8EA5:0040F7FE949291089080F31C2204239CA204BBFCA248A368A248B36AC2460362 +8EA6:0528F7BE994897BE9318F5AA294623FCA204BBFCA204A3FCBA04E3FC01080204 +8EA7:03DE78004BDE4A524B5A7A52102013FE1E5053FE525253FE52925EDCE29204CE +8EA8:0110F7FE904092EE92AAFBEA2AAE2AE8ABAABCE6A288A5F4A290B060C1980606 +8EA9:03DE7A524BDE4A524BDE78A011FE132015FC5D2051FE500051FC5C88E070078E +8EAA:00887BFE48884BDE4A527BDE125213DE124A5EFE539252FE52925EFEE2820206 +8EAB:020004001FF010101FF010101FF2101410187FF00050009003101C10E0500020 +8EAC:080010FC3E0422043E04227C3E4022402280FEFC06040A04120422044A280410 +8EAD:102020207C2045FE7D2246247C2044204450FC500C5014502490449295120A0E +8EAE:101020507C5044507C8844887D0446FA4448FC480C4814482488448895280A10 +8EAF:100021FE7D0045047D4445287D2845104510FD280D2815442584450095FE0800 +8EB0:102020207C2044207DFE44707CA844A84524FD240E2214F82420442094200820 +8EB1:100021FC7C4444487C5E44827C8A45244420FDFE0C20147024A8452496220820 +8EB2:100020F87C8844887C8844887D26462045FEFC200C7014A82524462294200820 +8EB3:0800107C3E4422443E4422443E7C22002200FEFE06820A82128222824AFE0482 +8EB4:082010103EFC22843E8422FC3E84228422FCFEA206A40A98129022884AC40482 +8EB5:100021FC7C2444A47CA445247C54444844A0FC100C5415422542454A96380800 +8EB6:100021FC7D2445247DFC45247D2445FC4420FDFE0C7014A82524462294200820 +8EB7:101C21E07C2044207FFE44A87D2446424440FFFE0C88150824D0443094480984 +8EB8:102020207DFC44507C8845047FFE440845E8FD280D2815E82528440894280810 +8EB9:108020807CFE45027E2244AA7C72442245FEFC220C7214AA25224422940A0804 +8EBA:102021247CA444A87C2045FC7D0445044574FD540D5415542574450495140908 +8EBB:104020207DFE45027E0444507C8845044400FDFC0C2014202420442097FE0800 +8EBC:100020FC7C8044F87C8044F87C8047FE4540FD240D2815102508454495820900 +8EBD:100023FE7A004AFC7A844AFC7A844AFC4A20FBFE1A482AC84A308A482A8413FE +8EBE:108420487DFE44207C2044FC7C20442045FEFC000C2015FE2420445094880B06 +8EBF:1020201079FE4910797C491479FE4914497CF9101992295449388A542A921430 +8EC0:100023FE7A004A7C7A444A447A7C4A004AEEFAAA1AAA2AAA4AEE8A002BFE1000 +8EC1:102021FC7D2447FE7D2445FC7C2045FC4524FDFC0C4017FE248845D094700B8C +8EC2:1048216A7CDC44487CB445227DFE45024420FC200CFC14242444444494940908 +8EC3:100021DC7D5445547DDC44007DFC452445FCFD240DFC142027FE442094200820 +8EC4:111020947BD248127A5049907FFE48104BD2FA521A542BD44A4A8A4A2BD61022 +8EC5:100023FE7A004A587A544ABE7BA84AE84ABEFAA81AA82ABE4AA88AA82ABE14A0 +8EC6:105021FC7D5445FC7D5445FC7C0045FC4400FDFC0D0415FC2488445097FE0800 +8EC7:102023FE782049FC78004BFE780249FC4820FBFE18002BFE48048BBE2AA4138C +8EC8:104020207BFE4A547A7E4AA87BBC4AA84ABCFAA81ABE2AA04A548B422D4A1238 +8EC9:102023FE7A1249DC78A849DC78AA4BFE4800F9FC190429FC490489FC28881104 +8ECA:010001007FFC01003FF8210821083FF8210821083FF80100FFFE010001000100 +8ECB:08200820FFA008207F20492049207F20492049207F200822FFA20822081E0800 +8ECC:108010801080FC8013F07C9054907C9054907C901090FE9211121112120E1400 +8ECD:00007FFE410281043FF801001FF011101FF011101FF00100FFFE010001000100 +8ECE:01007FFC01003FF821083FF821083FF80100FFFE01003FF8200820083FF82008 +8ECF:1000100013FCFC9010907C9054907C9054907C901090FE9211121112120E1400 +8ED0:100011F01090FE9010907C9054907DF054907C901090FE92108A108A10861082 +8ED1:102010201020FE2010207DFE54207C2054207C501050FE501088108811041202 +8ED2:0800087C0810FF1008107F1049107F7E49107F100810FF100810081008100810 +8ED3:1000100010F0FE9010907C9054907CD054B07C901090FE9210921112110E1200 +8ED4:1000100011FCFE2410247CA454A47CA455247C241024FE441044108411141208 +8ED5:102010201020FC2011247D2455247D2455247D241124FF24112411FC10041000 +8ED6:1000100011FCFE2010207C2054207C2055FC7C201020FE201020102013FE1000 +8ED7:100010F81088FE8810887D0656007DFC54847C841048FE501020105010881306 +8ED8:102010201020FDFE10207D2455247D2455247DFC1024FE2010221022101E1000 +8ED9:102010201020FE3E10207C2054207DFC54847C881048FE501020105011881606 +8EDA:102010201020FE2010207DFE54207C2054207C501050FE50108810C811241202 +8EDB:100011FE1100FD0011787D4855487D4855487D681150FD4211421142123E1400 +8EDC:102010201020FDFE11227D2255227D2255527D4A118AFF0211021102110A1104 +8EDD:1004101E10F0FE9010907C9054907CFE54907C901090FE88108A10AA10C61082 +8EDE:1008101C10E0FE2010207C3C54E07C2054207C3E11E0FE20102410241024101C +8EDF:104010401040FE7C10847C8855207C2054207C501050FE501088108811041202 +8EE0:1008103C11E0FE2010207C2054207DFE54207C201020FE201020102011FC1000 +8EE1:102010201050FE5010887D4456227C2054007DFC1004FE081008101010101020 +8EE2:1000100010FCFE0010007C0055FE7C2054207C401040FE88108411FE10821000 +8EE3:01007FFC01003FF821083FF821083FF80100FFFE0100600C183006C01830600C +8EE4:1008103C13E0FC2011247CA454A87C2057FE7C201020FE201020102010A01040 +8EE5:104010401040FEFC10847D0454F47C9454947C941094FEF41094100410281010 +8EE6:100011FC1104FD0411047D0455FC7C5054507C501050FE9210921112120E1400 +8EE7:1004101E10F0FE9010907C9054907CFE54907C901090FE88108A10AA10D6108A +8EE8:102010201050FE5010887D2456127C1055FC7C041008FE881050102010101010 +8EE9:102010201020FE4010487C8455FE7C8254007CFC1084FE841084108410FC1084 +8EEA:201020902090F910217EFA52AB92F892A912F9122252FBD220622022204A2084 +8EEB:102010201050FE8811047E1254207C4055887C101020FE441188101010601380 +8EEC:040008201FF00210FFFE09203FF8C1061FF011101FF011101FF00100FFFE0100 +8EED:100010FE1080FE8010FE7C9054907CBC54907C901090FEFE1080108010FE1000 +8EEE:102010201020FDFC11247D2455247D2455247FFE1020FE501050108811041202 +8EEF:100011FC1020FC2011247CA454A87C2057FE7C201020FE201020102010201020 +8EF0:04447C5804621C42E43E01007FFC01001FF011101FF011101FF00100FFFE0100 +8EF1:1008101C11F0FD5011507D5055507D5055507D481148FD681154127412521400 +8EF2:102010201020FE2011FE7C2054207C2054FC7C841084FE841084108410FC1084 +8EF3:1040104010FCFE8411047EF454947C9454F47C841094FE8810821082107E1000 +8EF4:104010201000FDFE10207C2054207C2055FC7C201020FE201020102013FE1000 +8EF5:104410441044FE8410BE7D8456847CA454947C941084FE841084108410941088 +8EF6:1040102011FCFD0411047DFC55007D00557C7D081110FD2011421282127E1400 +8EF7:105010481048FC4013FE7C8054807CFC55447D441128FD281210122814441182 +8EF8:102010201020FE2011FC7D2455247D2455247DFC1124FF241124112411FC1104 +8EF9:1000100011FCFF0411047D0455047D0455FC7D041000FE901088110412021402 +8EFA:100011FC1044FE4410447C4454947C8855007CFC1084FE841084108410FC1084 +8EFB:1000100013FEFC0810087DE855287D2855287D2811E8FD281008100810281010 +8EFC:102010201120FD2011FC7D2056207C2055FE7C201050FE501088108811041202 +8EFD:100011FC1084FE8810507C2054507C8857267C2011FCFE201020102013FE1000 +8EFE:101010141012FC1013FE7C1054107DD054907C901090FC8810EA138A10061002 +8EFF:108410481000FEFC10487C4854487C4855FE7C481048FE481048108810881108 +8F00:100013FE1020FE2010407DFC55547D5455547D541154FF541154114411141108 +8F01:104810481048FE4811FE7C4854487C4854487DFE1000FE481044108410821102 +8F02:08207FFC0820FFFE101021085FF481021FF011101FF011101FF00100FFFE0100 +8F03:104010201020FDFE10007C8855047E0254887C881050FE501020105010881306 +8F04:102010201124FEA410A87C2057FE7C9054907C901090FE9211121112120E1400 +8F05:104010401078FE8811507C2054507C8855067CF81088FE881088108810F81088 +8F06:102010101010FDFE10207C2454447CF854127C221044FD881010102810441182 +8F07:102010201050FE8811047E0255FC7C2054207C2011FCFE201020102013FE1000 +8F08:1010102010FCFE8410A47C9454947DFE54847CA41094FE941084110411141208 +8F09:08207F280824FFFE0820FFA008247F2449247F2849287F100812FFAA08460882 +8F0A:100011FE1020FE4010887D0455FE7C2254207C2011FEFE201020102013FE1000 +8F0B:010041047FFC0200FFFE09203FF8C1061FF011101FF011101FF00100FFFE0100 +8F0C:200023FE2020F8202020FBFEAA22FA22AAAAFAAA22AAFAFA22022202220A2204 +8F0D:100010501048FE8411247C2054507C8855067EF81088FE881088108810F81088 +8F0E:101010921052FE5410107CFE54827C8254FE7C821082FEFE10821082108A1084 +8F0F:100013FE1050FC5011FC7D5455547D54558C7D041104FDFC1104110411FC1104 +8F10:1020101011FEFD0212047CF854007C0055FE7C501050FE5010921092110E1200 +8F11:100010FC1024FE2411FE7C2454247CFC54407C4010FCFEC411441044107C1044 +8F12:100013FE1120FD2811287DE855287D2855287DE81128FD2A113A13EA10261020 +8F13:1080108010F8FD0812107DFC55247D2455247DFC1050FE50109010921112120E +8F14:1028102413FEFC2010207DFC55247D2455FC7D241124FDFC112411241124110C +8F15:100011FE1000FE9211247E4855247C9254007DFE1020FE201020102013FE1000 +8F16:100010FE1092FE9210BA7C9254FE7C8254BA7CAA10AAFEBA10821102110A1204 +8F17:10001040119CFF0411047DDC55047D0455FC7C501050FE50109010921112120E +8F18:1020102010FCFC2010207DFE54487C8455227C781088FD48105010201050118C +8F19:100013E0115CFD5411547DD455547D5455D47D541148FD6813C8105410541062 +8F1A:10481044105EFDE010287C12546A7D9654487C5E11E0FE2410281012106A1186 +8F1B:200023FE2020F82023FEFA22AA22FB32AAAAFAAA2376FA6622222222222A2204 +8F1C:109210921124FE4811247C9254927C0055FE7D221122FDFE1122112211FE1102 +8F1D:100013FE922254205BFE1020FDFC292429FC292429FC28202BFE4C2048208020 +8F1E:200023FE2202FA8A2252FBFEAA42FA22ABFEFA822282FA8222FA2202220A2204 +8F1F:200023DE2042F94A2084F94AAA52FC20A800FBDE2052F9522094214822542422 +8F20:100011FC1124FD2411FC7D2455247DFC54207DFE1070FEA81124122210201020 +8F21:10401040107CFC8411087E0054207DCE55027D0211CEFD021102110211FE1102 +8F22:1020102011FCFC5010887D0457FE7C0855E87D281128FDE81128100810281010 +8F23:100011DC1154FD5411547DDC55547D5455547DDC1154FD54115412D41224144C +8F24:1020102011FEFE2010FC7C2055FE7C0054FC7C8410FCFE8410FC108410941088 +8F25:100011FC1104FD0411FC7D0455047DFC54007D1211D4FD18111011521192110E +8F26:08203EF808207EFC145023885FF401001FF011101FF011101FF00100FFFE0100 +8F27:104410441088FDDC10887C8854887C8855DE7C881088FE881088108810881108 +8F28:1020101011FEFD0210007CF854887C8854F87C801080FEFC1084108410FC1084 +8F29:04407C7C04403C7804407C7C05403FF801001FF011101FF01110FFFE01000100 +8F2A:102010201050FE8811047EFA54007DFC55547D5411FCFF54115411541104110C +8F2B:104810481048FDCE10487C4854487DCE54487C481048FDCE1048104810481048 +8F2C:1040102013FEFC0010007DFC55047D0455047DFC1020FEA81124122210A01040 +8F2D:100013FE1020FC4011FC7D5455547D5455547D2C1020FDFE1050108811041202 +8F2E:100010FC1048FE3011FE7C5254947D1056307C2011FEFE7010A8112412221020 +8F2F:100010F81088FE8810F87C0055FE7C8854F87C8810F8FE88109E13E810081008 +8F30:100010FC1084FEFC10847CFC54007DFE54807CFE112AFE4A1092112210541088 +8F31:2008200C200AFBFE2208FA08AAE8FA0AAA0AFAEC22ACFAA822EA221A22262442 +8F32:102011241124FD2411FC7C0057FE7C2054407DFC1154FF54115411541154110C +8F33:1020102013FEFC2011FC7C4057FE7C8855047EFA1020FDFC1020105010881304 +8F34:1008101C11F0FD1011107DFE55107D7C55447D7C1144FD7C11441244127C1444 +8F35:100010FC1084FEFC10847CFC54407CFE55127C9210AAFE8210FA100210141008 +8F36:108810481050FDFE10507C5055FC7D5455547D8C1104FDFC1104110411FC1104 +8F37:1080108010FEFD0212427DFA54027DF254027DF21002FDF2111211F210141008 +8F38:204020A02110FA0825F6F800ABC4FA54AA54FBD42254FA5423D42244225422C8 +8F39:1040104010FEFE8011FC7E8454FC7C8454FC7C40107CFEC41128101010681186 +8F3A:1052105210A4FDFE10A47C5254527C0054FE7C921092FEFE1092109210FE1082 +8F3B:100010FE1000FE7C10447C44547C7C0054FE7C921092FEFE1092109210FE1082 +8F3C:100010F81088FE8810F87C8854887CF854007DFC1154FF541154115413FE1000 +8F3D:104010481084FDFE10207FFE54887D0457FE7D241124FDFC1124112411FC1104 +8F3E:200023FC2204FA0423FCFA48AA48FAFCAA48FA4823FEFAA422A8249024C82886 +8F3F:010017C0611C47C4454477DC454447C4711C47C44104FFFE0000101020084004 +8F40:100010F810A8FEA810D87C8854F87C0054007DFC1154FF541154115413FE1000 +8F41:101E11E01022FD1210947C8054207DCE55027D0211CEFF021102110211FE1102 +8F42:0800FFB808287F280028FFC688807F7C08247F2449287F284910FFA808440882 +8F43:1020102013FEFC2011FC7C4057FE7C8855347EE21020FDFC107010AC13221020 +8F44:2040202023FEFA022424F9FCA820F9FCA820FBFE2020F9FC2104210421FC2104 +8F45:1020102011FCFC2013FE7C0055FC7D0455047DFC1052FC94118816A410C21080 +8F46:2040202023FEFA502250FBFEAA52FA52ABFEFA002292FAD42298249224D2288E +8F47:200023DE2042FA52214AFA52A828F8C4AB12F8602188F83221C4201820602380 +8F48:112412481124FC0011FC7D2455FC7D2455FC7C2013FEFC7010A8112416221020 +8F49:102013FE1020FDFC11247DFC55247DFC54227DFE1008FDFE1108108810281010 +8F4A:108813DE1088FDDC10887FDE54887C0057FC7C041004FDFC1004100413FC1004 +8F4B:1010101012FEFD10117C7C54547C7F54557C7D1011FEFD1011101290147E1000 +8F4C:100011FC1020FFFE12227DAC54207DAC54007DFC1004FDFC1004100411FC1004 +8F4D:2108208823E8F910229EFFD4A864FBD4AA54FBD42254FBC822482254226422C2 +8F4E:201C21E02040FBFE2088F904AAFAFC88A8F8F80023FEFA0222FA228A22FA2206 +8F4F:23FE220223FEFA0022FCFA08ABFEFA10AA30FBCE2242FA8424EE27842884218C +8F50:1050115210D4FC5011FE7C8854507DFE54207CFC1020FDFE1050108811041202 +8F51:1020102011FCFC2011547C8855047EFA54887CF81088FEF8102010A811241060 +8F52:102011FC1020FC8813FE7C8855FC7D0455FC7D0411FCFD0411FC108811041202 +8F53:103C13E01124FCA813FE7CA855247E0255FC7D241124FDFC1124112411FC1104 +8F54:2020212420A8FBFE20A8F924AA22F904A904F9DE2244FD54209E210422042404 +8F55:108813FE1088FDFC11047DFC55047DFC54807DFE1222FD52110211FA100A1004 +8F56:2020202023FEF9242124FAAAAFFEF800A9FCF9042174F9542174210421FC2104 +8F57:2014201223FEFA1022F0FA14AAF4FAB8AAEAFA162442F82422A2228A24782000 +8F58:100011FC1154FD5411FC7C0057FE7C0055FC7D0411FCFC621094118812A410C2 +8F59:1104108813FEFC2011FC7C2057FE7C5455927C9013FEFC9010D4138A109611A2 +8F5A:08007F3C2A243E422A3CFFA449187F6601007FFC11101FF01110FFFE01000100 +8F5B:214421442554FB64215EFBE4A804FA34A94CFBE42084FBE4208420E427142008 +8F5C:200021FC2020FBFE2222F9ACA820F9ACA800FBFE2020F9FC215421542154210C +8F5D:1A3823883A38238838B82288FFFE11103FF8C1061FF011101FF01110FFFE0100 +8F5E:200823E82288FBEE2228FBF4AA82FBE2A800F9FC2154F9542154215427FE2000 +8F5F:01003FF801001FF011101FF01110FFFE01001110FEFE54547C7C5454FEFE1010 +8F60:200021FC2124F9FC2124F9FCA904F800ABFEFAAA22AAFBFE22AA22AA23FE2222 +8F61:210427C4410897D2E55C47C89552F7DE0100AFEAA92A01003FF820083FF82008 +8F62:212421742258FADA23FEF954AADAFBFEA8A2F82023FEF87020A8212422222020 +8F63:200023FE2222FACC2244FBEEAA44FAEEAB54FA442210FA90229E249024902BFE +8F64:2040207C2040FBFC2244FBF0AA44FAFCAAA8FAF822A8FAF8220025FC25542BFE +8F65:208823FE2088FBDE2252FBDEAA52FBDEAA4AFAFE2392FAFE229222FE22822206 +8F66:0200020002007FFC04000900110021003FF801000100FFFE0100010001000100 +8F67:104010401040FE402040284048407E40084008400E40F84248420842083E0800 +8F68:208020802080FC8043F050909090FC90109010901C90F09251121112120E1400 +8F69:1000100010FEFE102010281048107E1009FE08100E10F8104810081008100810 +8F6A:102010201020FE20202029FE48207E20082008500E50F8504888088809040A02 +8F6B:1000100010FCFE24202428A448A47EA408A409240E24F8444844088409280A10 +8F6C:202020202020FDFC4020504093FEFC40108011FC1C04F0885050102010101010 +8F6D:200021FE2100FD00417851489148FD48114811681D50F14251421142123E1400 +8F6E:2040204020A0FCA0411052089406FD10112011401D80F1005104110410FC1000 +8F6F:104010401040FE7C2084288849207E20082008500E50F8504888088809040A02 +8F70:020002007FFC080011003FF80100FFFE010001003EF80288145008203458C286 +8F71:102010201020FE2021FE282048207E2008FC08840E84F8844884088408FC0884 +8F72:2000200021FEFC08400851E89128FD28112811281DE8F1285008100810281010 +8F73:20202020203EFC20402051FC9104FD04110411FC1D04F1005100120012001400 +8F74:202020202020FC2041FC51249124FD24112411FC1D24F1245124112411FC1104 +8F75:2000200021FCFD04410451049104FD0411FC11041C00F0905088110412021402 +8F76:202020202120FD2041FC51209220FC2013FE10201C50F0505088108811041202 +8F77:2008203C23E0FC20412450A490A8FC2013FE10201C20F0205020102010A01040 +8F78:202020202050FC88410452129020FC40118810101C20F0445188101010601380 +8F79:2008201C21E0FD00412051209120FDFE102010201CA8F0A45122122210A01040 +8F7A:100011FC1044FE442044284448947E88090008FC0E84F8844884088408FC0884 +8F7B:200021FC2008FC10403050489084FF02100011FC1C20F0205020102013FE1000 +8F7C:201020142012FC1041FE50109010FDD0109010901C90F08850EA138A10061002 +8F7D:082008287F240820FFFE10201024FF24202448287F2808100F12F82A08460882 +8F7E:100010FE1010FE202044288248FE7E12081008100EFEF8104810081009FE0800 +8F7F:2008203C21E0FC20402053FE9050FC881104128A1C88F0885088110811081208 +8F80:2010202020FCFC8440A450949094FDFE108410A41C94F0945084110411141208 +8F81:202020202050FC884104520291FCFC20102010201DFCF0205020102013FE1000 +8F82:104010401078FE882150282048507E88090608F80E88F8884888088808F80888 +8F83:204020202020FDFE400050889104FE02108810881C50F0505020105010881306 +8F84:200023FE2120FD28412851E89128FD28112811E81D28F12A513A13EA10261020 +8F85:2028202423FEFC20402051FC9124FD2411FC11241D24F1FC512411241124110C +8F86:200023FE2050FC50405053FE9252FE52125212AA1EA6F30252021202120A1204 +8F87:082008207EFC0820FEFE145022884206BFF8050009001FF00100FFFE01000100 +8F88:04407C7C04403C7804407C7C064002003FF8050009001FF00100FFFE01000100 +8F89:100013FE92025444584013FCFC8028A0292029FC282028202BFE4C2048208020 +8F8A:200021FC2104FD0441FC51049104FDFC100011121DD4F118511011521192110E +8F8B:200023FE2202FA8A425253FE9242FE2213FE12821E82F28252FA1202120A1204 +8F8C:2040202023FEFC00400051FC9104FD0411FC10201D28F1245222142210A01040 +8F8D:200023DE2042FD4A4084514A9252FC20100013DE1C52F1525094114812541422 +8F8E:209220922124FA48412450929092FC0011FE11221D22F1FE5122112211FE1102 +8F8F:2020202023FEFC2041FC504093FEFC88110412FA1C20F1FC5020105010881304 +8F90:200021FE2000FCFC4084508490FCFC0011FE11221D22F1FE5122112211FE1102 +8F91:200021F82108FD0841F8500097FEFD0811F811081DF8F108513E17C810081008 +8F92:100010F81088FE8820F8288848887EF8080009FC0F54F954495409540BFE0800 +8F93:204020A02110FA0825F6400053C49254FA5413D41A54F25453D41244125412C8 +8F94:2208220847D08A22F53C27C84110F93E07C0193EE1003FF8200820083FF82008 +8F95:2020202021FCFC2043FE500091FCFD04110411FC1C52F094518816A410C21080 +8F96:2040202023FEFE02442451FC9020FDFC102013FE1C20F1FC5104110411FC1104 +8F97:200023FC2204FA0443FC52489248FEFC124812481FFEF2A452A8149014C81886 +8F98:2040202023FEFA50425053FE9252FE5213FE12001E92F2D45298149214D2188E +8F99:2208210827C8FA10249E4FD450649794FC9417941C94F7885488149414A415C2 +8F9A:2020212420A8FBFE20A8412452229104F90411DE1A44F554509E110412041404 +8F9B:020001003FF8000008200440FFFE0100010001007FFC01000100010001000100 +8F9C:01007FFC01001FF010101FF001003FF808200440FFFE01003FF8010001000100 +8F9D:10401020202029FC4400FE88425001FE7C20442045FC442044207C2044200020 +8F9E:00201E10F01011FF1000FE441024102811FF7C10441045FF441044107C104410 +8F9F:00407C20442045FC44007C88405041FE7C206420A5FCA42024203C2024200020 +8FA0:02001FF010101FF010101FF010101FF001003FF80820FFFE01003FF801000100 +8FA1:204010201020FDFC000044882850FDFE10201020FDFC10202020202040208020 +8FA2:10401020FE2011FC1000FE88925093FEFE20102039FC54209220102010201020 +8FA3:2020102011FCFC20002045FC2924FD2411FC1020FC7010A82124222240208020 +8FA4:04201E10E01022FE92005444FE2882FE00107C10047C68101010281044108210 +8FA5:08204A1052107EFE24004844BE2822FE22103E10207C3E10221022103E102210 +8FA6:421022082208FA3E078052942288FABE22882288729C2288248844884A889108 +8FA7:401020082788FABE028052942288FABE22882288729C2288248844884A889108 +8FA8:2010108810887CBE00802A941288FEBE128810887C9C11081108220824084008 +8FA9:2010120811087D3E00002B141108FD3E110811087D1C11481188210820084008 +8FAA:08204F10481048FEFF00084410287EFE42107E10407C7F1041107F1041100010 +8FAB:2010108810887D3E01402BD41088FCBE110813C87C1C100810C8230820084008 +8FAC:401022082108F93E000057D42088FCBE22882108711C22882288448848088008 +8FAD:0F20F010491022FEFE0014440828FFFE9510BD10837CBD10951089109510A310 +8FAE:411021082288FABE078051142108FABE27C82148711C25882548494845088208 +8FAF:421021082008FBBE000053942008FBBE20082388729C22882288438842888008 +8FB0:00003FFC200020002FF8200020003FFC24802488245024204410450886060400 +8FB1:00003FFC20002FF820003FFE288848504A308C0E0020FFFE0820042004A00040 +8FB2:04403FF824483FF824483FF800003FFC20002FF820003FFE288848504A308C0E +8FB3:082008207EFC08201C702AA8C8243FFC20002FF820003FFE288848504A308C0E +8FB4:0000EEFEAA80AA80EEBC0080FE8092FEFEA092B2FEB410A8FEA8112411321220 +8FB5:003803C07C00003803C03C0C007007807800010011F811001100290047FE8000 +8FB6:000020001000100000000000F000100010001000100010001000280047FE0000 +8FB7:0000200010001000000007FCF000100010001000100010001000280047FE0000 +8FB8:0000200017F8110801100120F13C110411041204120414281810280047FE0000 +8FB9:00402040104013FC00440044F044108410841104110412281410280047FE0000 +8FBA:0000200017F8108800880088F088108810881108110812281410280047FE0000 +8FBB:0040204010401040004007FEF040104010401040104010401040280047FE0000 +8FBC:0200210010801040004000A0F0A0111011101208140418021000280047FE0000 +8FBD:000023F81010102000400040F040104010401040104011401080280047FE0000 +8FBE:004020401040104007FE0040F04010A010901108120414041000280047FE0000 +8FBF:004020401040144404440444F44414441444144417FC10041000280047FE0000 +8FC0:000021FC1020102000200020F3FE102010201020102010201020280047FE0000 +8FC1:0010207813C0104000400040F7FE104010401040104010401040280047FE0000 +8FC2:000023F81040104000400040F7FC104010401040104010401140288047FE0000 +8FC3:000023F81000100007FE0080F10011F810081008100810501020280047FE0000 +8FC4:0100210011FE1200040001F8F010106010801104110410FC1000280047FE0000 +8FC5:00004FE02220222002200220EFA02220222422142214220C220450008FFE0000 +8FC6:004020401040125802E80748F248126812541244120411FC1000280047FE0000 +8FC7:00102010101017FE00100010F210111011101010101010501020280047FE0000 +8FC8:0000200017FE1080008000FCF084108410841104110412281410280047FE0000 +8FC9:000021FC11041104010401FCF104110011001100110012001400280047FE0000 +8FCA:00004FFE2040204007FC0444E44424442444245424482040204050008FFE0000 +8FCB:000027FC1040104000400040F3F8104010401040104017FC1000280047FE0000 +8FCC:000021FC1104110401FC0104F10411FC11041104110412141408280047FE0000 +8FCD:0040204017FC104002480248F24813F8104410441044103C1000280047FE0000 +8FCE:00002080133C122402240224F2241224122412B4132812201020282047FE0000 +8FCF:004020401040104007FE0040F04010A010901108124414241020280047FE0000 +8FD0:000023F810001000000007FCF04010801110120817FC12041000280047FE0000 +8FD1:0008201C11E01100010001FEF110111011101110121012101410280047FE0000 +8FD2:00802040104017FE00000000F1F011101110111012121212140E280047FE0000 +8FD3:000023FC1010111001100210F3FE103010501090111016501020280047FE0000 +8FD4:0008203C13C01200020003FCF204128812501220125014881504280047FE0000 +8FD5:00802080108011FC01200220F020102017FE1020102010201020282047FE0000 +8FD6:005020481048104007FE0040F04010A010901108120414041000280047FE0000 +8FD7:000023FC1040104000400040F7FE104010A01090110812041404280047FE0000 +8FD8:000023FC1020102000400040F0D0114812441444104010401040280047FE0000 +8FD9:00802040104017FC00100210F12010A0104010A0111012081408280047FE0000 +8FDA:00402040104017FC04440444F444144417FC1444104010401040280047FE0000 +8FDB:00902090109013FC00900090F09017FE10901090111011101210280047FE0000 +8FDC:000023F810001000000007FCF120112011201120112412241224141C280047FE +8FDD:008040802FFC2080008007F8E08020802FFC208420842094208850808FFE0000 +8FDE:0040204017FE108000A00120F3FC10201020102017FE10201020282047FE0000 +8FDF:000021F811081108010801F8F108112011101208120414041000280047FE0000 +8FE0:004020401040107E00400040F3FC120412041204120413FC1204280047FE0000 +8FE1:000023FC1204120403FC0200F2801284129812E012821282147E280047FE0000 +8FE2:000023FC1084108400840114F20811FC11041104110411FC1000280047FE0000 +8FE3:004822481248124807FE0248F248124812781200120013FE1000280047FE0000 +8FE4:0200220013FC144004400A58F2E81748126812501244120411FC280047FE0000 +8FE5:000023FC1204120402F40294F294129412F41294120412141208280047FE0000 +8FE6:04004400243C2FA404A404A4E4A424A424A428A428BC32A4210050008FFE0000 +8FE7:0040204017FC1444044407FCF444144417FC1444104010401040280047FE0000 +8FE8:008020801110120807FC0204F00013F812081208120813F81208280047FE0000 +8FE9:00802080110011FE02020424F020112811241222142210A01040280047FE0000 +8FEA:00404040204027FC04440444E44427FC24442444244427FC200050008FFE0000 +8FEB:00402040108013F802080208F20813F812081208120813F81208280047FE0000 +8FEC:00802040100017FC00400040F04013F81040104010401FFE1000280047FE0000 +8FED:00402240124013FC02400440F04017FE104010A0109011081208280047FE0000 +8FEE:01002100110013FE02800480F0F81080108010FC108010801080280047FE0000 +8FEF:01102110111011D002580254F252155218901090111012101410280047FE0000 +8FF0:004020501048104007FC00C0F0E0115011481244144410401040280047FE0000 +8FF1:0080404027FC240408080200E210226023802204220421FC200050008FFE0000 +8FF2:00402040104013FC00400040F7FE104010801110120817FC1204280047FE0000 +8FF3:000023F81010102000500188F60413F810401040104017FC1000280047FE0000 +8FF4:000023FC1204120402F40294F29412F41204120413FC12041000280047FE0000 +8FF5:000023FC120412F402040204F2F41294129412F4120412141208280047FE0000 +8FF6:0040204017FE1080010003FCF50419FC110411FC110411141108280047FE0000 +8FF7:0040224811481150004007FCF04010E011501248144410401040280047FE0000 +8FF8:02082110100017FC01100110F11017FE11101110121012101410280047FE0000 +8FF9:00402020102017FE00900090F294129214921110111012501420280047FE0000 +8FFA:00004FFE20A020A007FC04A4E4A424A4251C2604240427FC240450008FFE0000 +8FFB:0040208011F81610012000C0F120167C10841348103010C01700280047FE0000 +8FFC:00402040104017FC00400040F3F81000100013F81208120813F81208280047FE +8FFD:0020204013FC1204020403FCF200120013FE1202120213FE1202280047FE0000 +8FFE:000427E411041114011403D4F2541254155410941094110412141408280047FE +8FFF:0100210011FC1204040403E4F224122413E41224122413E410041028281047FE +9000:03F82208120813F802080208F3F8124412281210128813041204280047FE0000 +9001:020241043088101003FE0020F020102017FF10201050108811042A02440183FF +9002:007823C01040104007FE0040F04013F812081208120813F81208280047FE0000 +9003:00A020A014A412A801B000A0F1B012A814A4112011241224141C280047FE0000 +9004:0080208010FC110802900060F1981626102011FC1020122013FE1020282047FE +9005:003C23C01200120003FE0200F20012FC12841484148418FC1084280047FE0000 +9006:0208410821102FFE00400040E4442444244427FC20842100220054008FFE0000 +9007:021042502250225C0F7402D4E2542254225C23502E422442203E50008FFE0000 +9008:0040208013FC1204020402F4F2941294129412F4120412141208280047FE0000 +9009:00402240124013F804400040F7FC11201120112012241224141C280047FE0000 +900A:00104F9020902110021002D8E354225426922A92231222102A50242050008FFE +900B:004840442FFE204007FC0444E7FC244427FC244424442454240850008FFE0000 +900C:00402040107C1040004003FCF20413F4121413F4120413FC1204280047FE0000 +900D:0040224811481150004003F8F208120813F81208120813F8120812282A1047FE +900E:000027FE1090109003FC0294F294130C120413FC1204120413FC1204280047FE +900F:003823C0104017FC01500248F44613F01110113C110412141408280047FE0000 +9010:000023FC1040108001440668F0B01128166810A41124162010A0284047FE0000 +9011:00402050104817FC00400248F15010E011501248144411401080280047FE0000 +9012:011020A013F81048004803F8F240124013FC10C4114412541448284047FE0000 +9013:003C47E0242025FC042007FEE420242025FC2524252429342928302050008FFE +9014:004020A01110120805F60040F04017FC10401248124414441140288047FE0000 +9015:000027FC1000124804900248F00017FC1040104010401FFE1000280047FE0000 +9016:09104510221026520A520254E29026282A24324422422A82250050008FFE0000 +9017:000027FC1000100003F80208F20813F810001208111017FC1000280047FE0000 +9018:00802100120817FC01040100F3F81440104017FE104010A011102A0847FE0000 +9019:0080204017FC100003F80000F3F8100013F81208120813F81208280047FE0000 +901A:000047F8201021A0004007FCE444244427FC2444244427FC2444245454088FFE +901B:00004880257C22100D100110E17C23102D10211021102A7E240050008FFE0000 +901C:00004FF82080208007F00110E1102FFC200027F82408240827F850008FFE0000 +901D:0208421C226022400FC0027EE2C823482E48224822482A48248851008FFE0000 +901E:03F822081208120803F80000F7FC1040104013F81040104017FC280047FE0000 +901F:0040204017FC104003F80248F24813F810E01150124814441040280047FE0000 +9020:0040224013F81440004007FCF000100013F81208120813F81208280047FE0000 +9021:00802110120817FC00040110F208150411F812081590106011902E0847FE0000 +9022:010021F81308149000600198F606104013F8104013F8104017FC1040284047FE +9023:004040402FFE204007FC0444E7FC244427FC20402FFE2040204050408FFE0000 +9024:001022101110145402520092F0101114160412081210122010C0280047FE0000 +9025:000023FC1294129402F40294F29412F412941294129413FC1204280047FE0000 +9026:00004FFE2000200007BC04A4E4A426B425AC24A424A424A425AC50008FFE0000 +9027:01102248144410A001100208F40613F812081208120813F81208280047FE0000 +9028:0040204017FC104001500150F2E8144410E01150124814441040280047FE0000 +9029:0000208017FC111002480C46F3F810401150111017FE111012101410281047FE +902A:0110211017FC111001100FFEF00013F8120813F8120813F81208280047FE0000 +902B:000047BC2084252802100528E84027BC2084252822102528284450008FFE0000 +902C:00842084110817BC01080108F108110817BE11081108110811082A0847FE0000 +902D:0080204017FC140403F00210F21013F0120013F81208120813F8280047FE0000 +902E:0040204013F8104807FE0048F3F8144412481150124814441140288047FE0000 +902F:000047F8200823F800080FFEE040244422E8215022482444214050808FFE0000 +9030:02204220223E2F400280027CE30422082E7E2208220822082A28241050008FFE +9031:000047FC2444244405F40444E7FC240425F4251425F42404280C50008FFE0000 +9032:0140212013FE122006200BFCF220122013FC1220122013FE1200280047FE0000 +9033:0080204017FE1100020807FCF00413F8120813F8120813F8120812282A1047FE +9034:00402040107E104003F80208F3F8120813F810401FFE10401040284047FE0000 +9035:0040204013F81040004007FCF1101248144413F81040104017FC1000280047FE +9036:003823C0104017FC01500248F44410801FFE11081390106011981604280047FE +9037:000023F8120813F8020803F8F10013FC14941924124414A811102A0047FE0000 +9038:0100410021F0221004200FFCE444244427FC20A02130212A2222241E50008FFE +9039:0040204013F81040004007FCF11010A013F81040104017FC10401040284047FE +903A:0040204013F8104007FE0080F11013E0104411A81690108810C4280047FE0000 +903B:000047FC24A424A407FC0080E1F82208251020A0204021802E0050008FFE0000 +903C:000027FC100013F8020803F8F00017FC144417FC144417FC1404280047FE0000 +903D:0108210817FE1108004007FEF080110013FC1504190411FC1104280047FE0000 +903E:004040A0211022080DF60000E78424A427A424A427A424842494258850008FFE +903F:01F8210811F8110801F80000F7FE110013FC14A4112412541088280047FE0000 +9040:008027FC110013F804400BFCF00013F8120813F8120813F8120812282A1047FE +9041:001E23E01220122003FE0220F2FC128412FC128412FC148414FC280047FE0000 +9042:0110209010A017FC00800144F66810B01128166810A4112416A0284047FE0000 +9043:0040202013FC100001080090F3FE122012C81210122412C812101460298047FE +9044:004044442444244407FC0000EFFE208027FC24A424A424A424A4240C50008FFE +9045:00004FFC280428040FFC0910E8A02FFC28402BF8284037FC204050408FFE0000 +9046:0080204017FC111000A007FCF444104013F812481248126812501040284047FE +9047:000023F8124813F8024803F8F04017FC14441454147415941404140C280047FE +9048:000043F8220823F8020803F8E0002FFC204022782240254028FE50008FFE0000 +9049:00402040107C104003F80208F3F8120813F8120813F810A011102A0847FE0000 +904A:042042202FBE2440043C0784E488248824FE24882488288829A850108FFE0000 +904B:000027FC144413F8004003F8F24813F8124813F8104017FC1040284047FE0000 +904C:000027BC14A417BC000003F8F00017FE110011F8100810081050282047FE0000 +904D:0080204013FC1204020403FCF20013FC1354155415FC19541144110C280047FE +904E:01F8210811E81128012803FCF20412F4129412F4120412141208280047FE0000 +904F:000023F8120813F8020803F8F10013FC14441AA4120413F41014280847FE0000 +9050:000047BC2484248407BC0400E40027BC2404240427A82410242854448FFE0000 +9051:0040208013F8120803F80208F3F8100017FC104013F8104017FC280047FE0000 +9052:020841102FFE20A007FC04A4E4A42524261C240427FC240427FC50008FFE0000 +9053:02082110100017FC008003F8F20813F8120813F8120813F81208280047FE0000 +9054:0040204013F8104007FC0110F0A017FC104013F8104017FC1040284047FE0000 +9055:0040204013F8108807FE0000F3F8120813F8104013FC144017FE1040280047FE +9056:004040402FFE204007FC0514E4A425F4244425F424442454244850008FFE0000 +9057:004023F8124813F800400FFEF00013F812081248124810A011102A0847FE0000 +9058:011027FC111013F8011007FCF04013F8124813F8124817FE120812282A1047FE +9059:004020FC1324109800E00700F1F81240104017FC1040124413FC280047FE0000 +905A:00402140165C1444075C0444F7FC104017FC10081190106011981604280047FE +905B:0080477C2424252404A40554E648208027FC244427FC244427FC50008FFE0000 +905C:00064FB82090212002440278E3102E24227E221222542A92245050208FFE0000 +905D:000027FC14A414A407FC0040F150124814441150124814441040280047FE0000 +905E:001E47E0243C242005FE0522E53825E2251E250029782A48328A250650008FFE +905F:000023FC1204120403FC0240F22013FC1288125013FE122015FC1420282047FE +9060:0040204013F8104007FC0000F3F8120813F810C411A8129014881084280047FE +9061:0440225E1292101207D2011EF5521552155217DE115212121222142A284447FE +9062:000023F8120813F8020803F8F00017BC108414A4129414A412941108280047FE +9063:004023F8124813F8004007FEF00013F8120813F8120013F8120813F8280047FE +9064:000023FC124013F8024003F8F24013FC10041554155415541428281047FE0000 +9065:003C23C010041244012801FCF220102013FE102011241124112411FC280047FE +9066:03FC224417FE124403FC0000F3FC120413FC120413FC120413FC11082A0447FE +9067:004047FC21102FFE000003F8E20823F8220823F820402FFE204050408FFE0000 +9068:021042102F90221E07A40244EF9424142788248824942AA2294250008FFE0000 +9069:0080404027FC211000A007FCE44427FC244425F4251425F42404240C50008FFE +906A:0080211013F8121004A407FCF0A013181C4613901064139810601380280047FE +906B:021042102F90223E0FA40AC4EAA42F94220827082A943224224450008FFE0000 +906C:022042202FA0223C0FC40A90EA902F90221027282AA83244228450008FFE0000 +906D:00A02FFE10A017FC04A407FCF4A417FC100013F8120813F8120813F8280047FE +906E:0040402027FE240004880488E7FE2488248824F828002AA43252245250008FFE +906F:0000477E25102530074A059AE52C274C259A252A254A25A82B1050008FFE0000 +9070:02A822A817FC12AA04E60800F7FC1444104013F8124812481258284047FE0000 +9071:004043F822482FFE024803F8E04023F8224823F820802FFE211020E053188FFE +9072:07FC440427FC242004A80470E4A8250424A024FC252024202BFE282050208FFE +9073:0110211017FC111000400248F2481554104013F81040104017FC280047FE0000 +9074:00402248115017FC01500248F4441210139014BC1A901150117E12102A1047FE +9075:01104FFE20A027FC04A4051CE60427FC240427FC20102FFE211020B050008FFE +9076:0040204013F8104007FC0210F73812101F7C100017FC11201224141C280047FE +9077:07FC20A017FC14A407FC0080F7FE120815F4191211F0110410FC280047FE0000 +9078:0F3C49242F3C28A2079E0110E7FC211021102FFE21102208240450008FFE0000 +9079:000023F81090106007FC0124F6A8104017FC14A4151416EC14A414EC280047FE +907A:004023F8124813F800400FFEF00013F8120813F8120813F811101208280047FE +907B:000027BC14A414A407BC0110F0A017FC10401248124813F810401080290047FE +907C:004040402FFC20A0051403F8E60C2BFA220823F8204022482444294450808FFE +907D:0040407C204027FE044205F8E44427FC24C0272228D42B183074239250208FFE +907E:0210421023DE2528088407FCE04022482248255428E220402FFE50008FFE0000 +907F:0010478824BE248004A20794E43E28082F8834BE24882788248850008FFE0000 +9080:020044102F9028900F9E08A4EFC422143FD424082788289432A2214250008FFE +9081:01104FFE211023F8024803F8E24823F8204027FC245425F42414240C50008FFE +9082:04004F3C291432140F940AA8EAA82FBC2AC82A882FBE2A882A88318850088FFE +9083:008040402FFE2A12140C0120E7FC20802144266821B0266821A426A450408FFE +9084:000047FC24A427FC00000FFEE00023F8220823F8214423282D9051088FFE0000 +9085:002027FE100013FC020402F4F29413FC110811F8110811F8100017FE280047FE +9086:002423A810921514020805F4F00213F8120813F81208111017FC280047FE0000 +9087:07FC424824442FFE044406ECE55426EC244426EC255426EC2444240C50008FFE +9088:011042202D7C25C402440D7CE3442544297C23282528292A254652808FFE0000 +9089:008043F8220823F8020803F8E0402FFE2912220825F42912211021F050008FFE +908A:008047F8254824A807F80040EFFC2A1424882BF4210021F02210243050008FFE +908B:02484490224827F8052804C8E52827F8249026D0249026D4248C26C450008FFE +908C:0190461E222A2F8A031206AAEA4420A023182C46225021602250254850808FFE +908D:010043F0251020E0071C03F8E24823F8224823F820082FFE2248215052488FFE +908E:04004F8C35702A2004441A78EF9020242F7E20102F5429922F3050008FFE0000 +908F:00004FFE29122FFE02280424E97E2FC8227E25482F7E21482AFE2A4050008FFE +9090:0FBE40002FBE2CB20AAA0040EFFE29202FFC29242FFC2A282BB22A1E53808FFE +9091:00001FF0101010101FF000003FF82108210821083FF82008200220021FFE0000 +9092:0000FF7C08440848084808500848084808440844084408680850284010400040 +9093:00007E7C02440248424824501448084808441444144422684250804000400040 +9094:00007F7C01440148014801503F48214820442044204421682650384020400040 +9095:088811102220111008881FF010101FF000003FF8210821083FF8200220021FFE +9096:0800083E0822082449244928492449244922492249224F347928002000200020 +9097:00007F7C08440848084808500848FFC808440844084408680850084008400840 +9098:00007F7C08440848084808500848FFC808440844084408680850084028401040 +9099:1000083E08220024FFA4202820242024202220222022203420283F2000200020 +909A:1000107C10441048FE4822502248224842442444144408681450224042408040 +909B:0000007C7F44084808480850084808480844084408440F68F050404000400040 +909C:1000107C10441F482148215051488A480A440444044408681050204040408040 +909D:0800043E04223FA4202420282024202420222022202220342028402040208020 +909E:0800087C08447F48084808500848FFC808441444124422682150414080400040 +909F:1000087C0844FF48004800503C48244824442444244425684650444080400040 +90A0:0000147C12441248214821504048BE481244124412441268225022404A408440 +90A1:1000083E0822FFA4102410281F24112411221122112211342128252042208020 +90A2:00007FBE12221224122412281224FFE412221222122212342228222042208220 +90A3:00007E7C1244124812487E50124812487E4412441244226822504A4084400040 +90A4:0200077C38442048204820503FC8244824442444244424682450444044408440 +90A5:0800087C08447F48494808500848144814441444144425682650444080400040 +90A6:0800087C0844FF48084808507E4808480844FF44084410681050204040408040 +90A7:00003F3E002200240024FFA81224122412221222122222B42328422080200020 +90A8:0800083E0822FFA4082449284924492449227F220822083409280A200C200820 +90A9:0800087C0844094849484A504C48884808440844144412682150214040408040 +90AA:00007FBE022222242224222842247FE406220A2212222234422882200A200420 +90AB:100010F81088FC8810F810007DFC11241124FF2411FC110021002102410280FE +90AC:1000203E7E22422442244A28442440247F22012201221D34E12841200A200420 +90AD:1000103E20223F24412481283D242524252225223D222534012801200A200420 +90AE:0800087C08447F4849484950494849487F4449444944496849507F4041400040 +90AF:2200223E22222224FFA42228222422243E2222222222223422283E2022200020 +90B0:0800083E102222244124FFA800A400247F22412241224134412841207F204120 +90B1:0000033E3C222024202420283FA42224222222222222223427A8F82040200020 +90B2:1000083E0A2202241224132854A454A4542298221922113431284F2080200020 +90B3:0000FF7C08440848104814503248514890441044104400680E50F04040400040 +90B4:00007FBE0822082408247FA848A448A454A252A262A240B440A840A042A04120 +90B5:00007F3E1122112421242528422480243F2221222122213421283F2021200020 +90B6:1200123E122212241224F3A812241224122212221222323452A8932012200020 +90B7:0000FF7C204420483C482450244834484C444C44444445685550654043400040 +90B8:010007BE7C2244244424442844247FA4442244224422423442A852A069A044A0 +90B9:2000207C3E44424884480850FE48024802447E44024402680250FE4002400040 +90BA:1400143E142214A494A455285524562414221422142217B4F828402000200020 +90BB:0800087C14441248214848D0844804487F440144224414680850044004400040 +90BC:00007FBE402240247FA4442844245F24442244227FA2403440287FA000200020 +90BD:0800087C7F44084808480850FFC80048084408447F44086808500F40F0404040 +90BE:0800487C48447F48484888500848FFC818441C442A4429684950884008400840 +90BF:0800083E08227F2408240828FFA4022402227FA202222234122802200A200420 +90C0:0800083EFFA2142422244128BEA40024FFA2102220227F34012801200A200420 +90C1:0800083EFF22102410243F2821246124BF22212221223F342128212025202220 +90C2:1000083E0022FFA40824112821247E240422092212222434CC2812202120C0A0 +90C3:0800087C144422484148BED0004800483E4422442244226822503E4022400040 +90C4:0100323E0C22122469240828FFA410242422242248228A3411283F2011200020 +90C5:0000FFBE0822102422244128FFA408A4082208227F22083408280FA0F8204020 +90C6:0800083E0822FFA4082408287F24002400227F224122413441287F2041200020 +90C7:2000203E7F22412481247928492449247922492249227934412801200A200420 +90C8:0200073E7822402440247FA8402440245F2251225122513451289F2091200020 +90C9:0000773E22222224222422282224F7A422222222222222342228422042208220 +90CA:1000087C0044FF48004824504248814824441444084414682250424080400040 +90CB:0800083E10227F24412441287F24412441227F224122413441287F2041200020 +90CC:100010F810887C8810F81000FDFC0124112411247DFC110011001D02E10240FE +90CD:0800103E3F222124292425282524FF2421222922252225342128412045208220 +90CE:0800043E3F22212421243F28212421243F222022242222342528292030202020 +90CF:0800083E0822FFA40824492829242A24FFA20822082214341228212041208020 +90D0:0800083E142222244124BEA800240024FFA21022102222344128FF2041200020 +90D1:2200123E14227F24082408280824FFA408220822142212342128412080200020 +90D2:000020F810887C8844F844007DFC452445247D2441FC510049005502650240FE +90D3:00007FBE48A208247FA41028142424247FA20422042207B4FC28442004200420 +90D4:008001DE771211121114251425D8751415125512551227DA201450108FF00010 +90D5:0400053E04A204247FA4442844247524552255225522523452A8A6A089A010A0 +90D6:00007FBE002200243F242128212421243F22002221221134122807A078202020 +90D7:30800D3E0622192460A408287FE4142424227FA2A4A224B426A8252004200420 +90D8:00003E3E22222224222422283E24002400227F2241224134412841207F204120 +90D9:0A00093EFFA2082408247F28492449247F22492249227F344928492049204320 +90DA:0000FFBE082208247F2411281124FFE4002200227F224134412841207F204120 +90DB:02000F3EF022012491244A280024FE24042208220F22F8344828082028201020 +90DC:0800483E48227F24482488280824FFA4002200227F224134412841207F204120 +90DD:0800083E7F22082408240828FFA412241222532252A292B4222822204A208420 +90DE:1000087C7E44424842487E50424842487E4451444A4444684450524062404040 +90DF:0800083E0822FFA408242A282A242A245D2288A2082214341228212041208020 +90E0:00007FBE082208247F24492849247F24492249227F220834682818202620C120 +90E1:00007F3E11221124FFE4112811247F24202220227F22A134212821203F202120 +90E2:00007F7C4144414841487F5000487F48084408447F44086808500F40F0404040 +90E3:0800087C7F44084808487F50414882483C44044408440F687850084028401040 +90E4:1400127C214449480848145022484148BE4422442244226822503E4022400040 +90E5:00007E7C424442487E48425042487E48424442447E4400682450224041408140 +90E6:00007FDE001200127BD44A544A584A546B525AD24A524A5A4A544A504A505AD0 +90E7:00003E3E222222243E2400287F2441244922492249224934142812202120C120 +90E8:1000083E7FA2002421241228FFE4002400223F222122213421283F2021200020 +90E9:61001A3E0C223224C9240828FFA410243F226122BF2221343F28212025202220 +90EA:0800083EFFA208247F240928FFA409247F221022FF22213472280C203320C0A0 +90EB:1000203E7F22492449247F28492451247F2224224422FFB40428042004200420 +90EC:0800083EFFA208247F240828FFA400247F2241227F2241347F28412045204220 +90ED:1000087CFF4400487E4842507E4800487E44044408440F68F850084028401040 +90EE:00003FBE24A224A42EA424A83FA420A42EA22AA22AA22EB420A840A042A08120 +90EF:0800093E49224A2488241428222449248822492249228A3414282220412080A0 +90F0:0000FC1E48124BD278544A5449587954489248925C92E95A49540A5008100810 +90F1:2100113E122200247FA41228122412241222FFA2122212341228122022204220 +90F2:0800087C0844FF4808482A502A482A485D4488441C442A684950884008400840 +90F3:1000677C414441487748415041487F4814441444144414682550264044408040 +90F4:1100111E111211127BD41114111833143B9255525512991A1114111011101110 +90F5:02000F3E78220824FFA42A282A24FFA42A222A22FFA2083408280F20F0204020 +90F6:200010F87C88008844F8280001FCFF24012401247DFC4500450045027D0244FE +90F7:200023DE22524A524BD4F254125823D44A12FA920A5212DA1354221040108010 +90F8:4100223E14227F24492449287F24492449227F2208220834FFA8082008200820 +90F9:00007E7C42447E4842487E5042487E4814441244FF4410682850244042408040 +90FA:212422483D244400A8F8108820F8C80011FC3D24452485FC290011042104C0FC +90FB:3F00A13EBF22A124BF24A128BF248024FFA20022492249349228922049204920 +90FC:1000103E7F222124FFE400287F2441247F220822FFA208348828FFE008200820 +90FD:080008BE7EA209240A24FFE8082410243F226122A1223F34212821203F202120 +90FE:00007FDE40125F9250945F9450985F9444127FD24912591A4614491050907FD0 +90FF:00007F7C494449487F4840505F48514851445F4451445F68515051409F401140 +9100:2200223EFFA222242A240828FFA4102420223F226122A134212821203F202120 +9101:140014BEF722142434A4D3A800247F2441227F2241227F344128412045204220 +9102:0000773E55225524772400287F240024FFA220223F220134012801200A200420 +9103:0800143E22224124BEA4002878A44AA44AA27AA24AA24AB47AA848A04AA05920 +9104:0000FF7C144414487F48555055487F48084408447F44086808500F40F0404040 +9105:010007BEF82208247F24492849247F240822FFA288A28AB4BEA880A082A08120 +9106:0000FFBE88A20824FFA408287F2449247F2249227F220834FFA8082008200820 +9107:1000179E109220922FF46414A41827D4291221122FF2211A2294225024502810 +9108:0A00747C15445248224821504148BE48084408447F4408681450124022404040 +9109:2100209E23D24A524A54F3D4125822544BD2FA120A92125A12D4235042108010 +910A:200027FE22524A524BD4F254125823D44A52FA520A7217DA1054205040508050 +910B:28004B7C494449486B48495049487F4808447F44014432680C50124061400040 +910C:0800043E7FA244245F2445287FA445245F2244225F225134512851205F209120 +910D:0000FFBE80A200247F2441287F2441247F2210220822FFB400282220412080A0 +910E:0800103E7F2241247F2441287F2441247F22102208222934A2A8A2A01E200020 +910F:00007FBE40225F2440247FA855245224592250A242227FB452284A2082200620 +9110:1000083EFFA2102422247C28082411247FA200A27F2249347F2849207F204120 +9111:00007FBE122252A433241228FFE400243F22212221223F34212821203F202120 +9112:1000103E3FA248A42AA43EA810A4252452223FA248A2AAB43EA810A025204220 +9113:0800103E7F2241247F2441287F2441247F220A220922FFB40828142022204120 +9114:1000203E7F22412441247F2840247FE440227FA200A2AAB4AAA800A005200220 +9115:2080211E23D24A524A54F3D4125822544BD2F8120A52139A1214225041D08010 +9116:00003F3E212221243F2400287FA440A47FA240A27FA240B47FA81220212040A0 +9117:1000087CFF4400487E4842507E480048FF448144BD44A568BD50814085408240 +9118:02003FDE22122F9222943FD422982F9422122F922A922F9A4A944F908A900990 +9119:1F00113E11221F2404247FE804243FA420A22EA22AA22EB420A83FA020A00020 +911A:2200223EFFA222247F2441287F2441247F220822FFA208341428222041208120 +911B:4900927C494400487F4849507F4849487F440844FFC41C682A50494088400840 +911C:0800043E7FA2522452247FA852A452A47FA2522252225BB4522852A09B201220 +911D:0000773E11225524332455280C243324C4A2182262220CB4712806201820E020 +911E:2200227CFFC422483E4808507F4849487F4408447F4408687F5008400F40F040 +911F:0800FFBE08227F2449247F2849247F2408A2FFA20222FFB4422822200A200420 +9120:7F00083EFFA288A46B2408286B2400247F220022FFA220343F2801200A200420 +9121:10007F3E41227F2441247F2840247FA440227FA208A27EB41DA82A20C9200820 +9122:00007FBE042227242424FFA820243FA440227FA200A2AAB4AAA800A005200220 +9123:08007F3E22221424FFA400287F2441247F2241227F220834FFA8082008200820 +9124:7E00427C7E4442487E480050FF48A548FF4400447E4402683450084014406240 +9125:1000203E7F2241247F2441287F2440247FA240227FA200B4AAA8AAA080A00320 +9126:2000203E7FA2D52455245528FFA4552455225522FFA200346A28552095200020 +9127:0500723E12A2512421245EA880A43F24212221223F222134122807A078202020 +9128:49202A3E7F4449A85D106B2849461FF010101FF000003FF821083FF820021FFE +9129:00007F3E01223F2401247F28002477242522F7220222FFB4422822202A200420 +912A:1200FF9E12927F9252147FD422587F54A1D23F1221123F1A21143F1012102110 +912B:4100223E0022FFA488A4AAA89CA488A4FFA200227F2241347F2841207F204120 +912C:03C07C1E289215123F14211421183F94209220923FD2205A55545550A1500090 +912D:2200147CFF4414487F48555063485D4841447F440844FF681450224041408040 +912E:1000EFBEA4A294A4AAA4C92810247F2441227F2241227F3441287F2022204120 +912F:2200143EFFA208247F240828FFA449242A22FFA200227F34412841207F204120 +9130:0800493E2A22FFA42A24492888A44124412277A29122553427A8412081200120 +9131:0F00F83E49222A24FFA42A28492480A47F22492249227F34492849207F204120 +9132:0000F7BE94A294A4F7A400287F2449247F2249227F220834FFA8082008200820 +9133:00007F3E55225524772414287724552455227722552255347728542014A00FA0 +9134:1400557C36441448FF48225014487F4808447F440844FF681C502A4049400840 +9135:00007F3E41227F240024F7A894A4F7A408220822FFA21C342A28492088A00820 +9136:04000B1E30D2DF3200147FD455584E547FD200123F92209A3F9420903F902090 +9137:12007FBE52A27FA452A47FA800247FA400227FA240A27FB4212812200FA0F020 +9138:2200FFBE22227F24552455287F240024FFA290A23E22223452280C201820E020 +9139:FC004BBE78A24AA479244D28FAA40CA407A2F82228A24D341A282920C8A00820 +913A:0800043E7FA24A245F244A287FA444245F2255225F2255345F288020912020A0 +913B:2200F7BE2222F7A4552488A87F2408247F2249227F2249347F280820FFA00820 +913C:2200773E2222F7A42224552888A47F2441227F2241227F3441287F2022204120 +913D:04007FDE40125F9254945F9454985F9444125F9244127FDA5494AF5084103FD0 +913E:7F80083E3F2221243F2421287FA448A4252252A20E2210343F2851200E207120 +913F:2200FFBE222277245524772800247F2449227F2249227F340828FFA008200820 +9140:2200221EFF9222123E1441145D58D59455125552DD5240DA001454904A508A50 +9141:3E00421EFF9240927F944494771844543FD24212FF92489A7F941A102950C7D0 +9142:1080529E7BD29492FBF431945AD8949400123F922092249A24940B1010906050 +9143:00007FCE040AFFEA842A358A040C358A000A000AEEEAAAAAAAACAAA8EEE8AAA8 +9144:11007FDE11127BD24A547BD4141812143FD224127F92A41A3F9424103FD02010 +9145:44407FDE12123FD26214BFD422183FD422123FD220127FDA51546ED04A504ED0 +9146:2A007F3EAAA2FFA4AAA4FFA8AAA4FFA40022FFA200227F3441287F202220FFA0 +9147:52807BDE9492FBF231945AD494983F9420923F9220923F9A20943F9011102090 +9148:7BC0001E7BD24A526B544A5404187FD44A127FD24A527FDA52545B90525099D0 +9149:0000FFFE044004407FFC444444444844503C600440047FFC400440047FFC4004 +914A:0000FF80147E14107F105510551055105710611041107F10411041107F504120 +914B:101008100820FFFE044004407FFC44444844503C60047FFC400440047FFC4004 +914C:0020FE202820287CFE44AA84AA04AA44AE24C2148214FE0482048204FE288210 +914D:0000FE0028F82808FE08AA08AA08AAF8AE88C2808280FE8082828282FE7E8200 +914E:0008FE0828082808FEFEAA08AA08AA08AE48C2288228FE0882088208FE288210 +914F:0020FE20282028A0FEACAAB4AAE4ABA4AEA4C2B482A8FEA282A28282FE7E8200 +9150:0000FE7C28102810FE10AA10AA10AAFEAE10C2108210FE1082108210FE108210 +9151:0000FEFC28202820FE20AA20AA20ABFEAE20C2208220FE2082208220FEA08240 +9152:00004FFE20A020A007FC84A444A454A4151C2604E40427FC2404240427FC0404 +9153:010002800C603118CFE600400080FFFE04803FF82488287830083FF820083FF8 +9154:0040FE4029F82848FE88AA8AAB0AAA26AE20C22083FEFE2082208220FE208220 +9155:0008FE1C28F02810FE10AA1CAAF0AA10AE10C21E82F0FE1082128212FE12820E +9156:0010FE1028102810FEFEAA92AA92AA10AE28C2288228FE288248824AFE8A8306 +9157:0000FE4428442828FEAAAAAAAA92AA92AEAAC2AA82A6FEC682828282FEFE8202 +9158:0000FE7828482848FE48AA86AB00AAFCAE44C2448228FE2882108228FE448382 +9159:0008FE8828482848FE08AA88AA48AA48AE08C20E82F8FE0882088208FE088208 +915A:0008FE2828282828FE44AA44AA82AB7CAE24C2248224FE2482448244FE948308 +915B:0000FEFC28002800FE00AAFEAA50AA50AE50C2508250FE5282528292FE8E8300 +915C:0020FE20282028FCFE20AA20AA20ABFEAE20C2508250FE4882888284FF048202 +915D:0000FE00287C2800FE00AA00AAFEAA10AE10C2208220FE44824282FEFE428200 +915E:0020FE2028202820FE20ABFEAA20AA20AE20C2508250FE50828882C8FF248202 +915F:0010FF90141014107F1E551055105510577C614441447F44414441447F7C4144 +9160:0000FE0028FE2804FE04AAF4AA94AA94AE94C29482F4FE9482048204FE148208 +9161:0020FE10281028FEFE82AA84AA40AA44AE48C2508260FE4282428242FE3E8200 +9162:0040FE402840287EFEA0AAA0AB20AA3CAE20C2208220FE3E82208220FE208220 +9163:0044FE4428442844FEFEAA44AA44AA44AE44C27C8244FE4482448244FE7C8244 +9164:0010FE1028102810FEFEAA10AA10AA10AE7CC2448244FE4482448244FE7C8244 +9165:0004FE1E28F02810FE10AA10AAFEAA10AE38C2348254FE5282908210FE108210 +9166:0020FE2828A428A0FEFEAA40AA40AA7CAEA4C2A482A8FEA882908328FE448282 +9167:0020FE1028FE2882FF0CAA08AA08AAFEAE08C2488228FE2882088208FE288210 +9168:082008287F240820FFFE0020FFA414247F245528632841107F12412A7F464182 +9169:0020FE20287E2882FF44AA28AA10AA20AE40C2FE8342FE4282428242FE7E8242 +916A:0020FE20283C2844FEA8AA10AA28AA44AE82C27C8244FE4482448244FE7C8244 +916B:0010FE1028282828FE44AA82AA7CAA10AE10C210827CFE1082108210FEFE8200 +916C:0004FE4428542854FE54AA54AADCAB74AE54C2548254FE5482548254FE848304 +916D:0020FE2028FE2820FE40AA7CAA44AAC4AF7CC2448244FE7C82448244FE44824C +916E:0000FEFE28822882FEBAAA82AA82AABAAEAAC2AA82AAFEBA82828282FE8A8284 +916F:0080FE82288C28F0FE82AA82AA7EAA00AEFCC2848284FEFC82848284FEFC8284 +9170:0010FE502850287CFE90AA10AA10AAFEAE28C2288228FE28824A824AFE868300 +9171:0840488029FC1A482830C9C00800FFFE04803FF82488287830083FF820083FF8 +9172:0000FE7C28442844FE44AA7CAA00AA00AEFEC2108210FE7C82108210FEFE8200 +9173:0020FE4428F82810FE24AAFEAA02AAFCAE84C2FC8284FEFC82848284FE948288 +9174:0010FE1028282828FE44AABAAA10AA10AEFEC2108258FE5482928312FE508220 +9175:0020FE2229FA2824FE24ABFEAA10AA20AFFCC2888310FEFE82108210FE508220 +9176:0040FE40287E2880FF7CAA44AA64AA54AEFEC24482A4FE9482FE8204FE288210 +9177:0010FE502850287CFE50AA90AA10AAFEAE00C200827CFE4482448244FE7C8244 +9178:0010FE1028202844FEFEAA28AA44AAA2AE3CC2448244FEA882108228FE448282 +9179:0004FE1E28E02822FE92AA54AA40AA08AFFEC2088288FE4882488208FE288210 +917A:0014FE1228FE2810FE10AAFEAA92AA92AEFEC2928292FEFE82928292FE928286 +917B:000EFEF028222892FE54AA00AA7CAA08AE10C21082FEFE1082108210FE508220 +917C:0020FE1029FE2820FE48AA84ABFEAA02AEA8C2A882A8FEA882A882AAFF2A8206 +917D:0000FEFE282828AAFE6CAA28AAFEAA80AE80C2808280FE8082808300FF008200 +917E:0000FBFE20002000FBDEAA52AA52AA52DB5A8AD68A52FA528A528A52FA528AD6 +917F:0020FE1028FC2884FE84AAFCAA84AA84AEFCC2A282A4FE9882908288FEC48282 +9180:0050FE48288028FEFF90AA90AAFCAA90AE90C2FC8290FE90829082FEFE808280 +9181:0000FEFC28042804FE7CAA04AA04AAFEAE10C2928254FE3882548292FE508220 +9182:0048FE4828482848FEFEAA48AA48AAECAEDCC35A8248FE4882488248FE488248 +9183:0020FE2029FE2850FEA8AB26AAF8AAA8AEA8C2F882A8FEA882F882AAFE22821E +9184:0040FE4028FE2882FF42AA7AAAA2AA22AFFEC22282AAFEAA82FA8202FE148208 +9185:0020FE1028FC2800FE84AA48AA00AAFEAE00C20082FCFE8482848284FEFC8284 +9186:0028FE24282E28F0FE28AA12AA2AAAD6AE28C22E82F0FE2482288212FE2A82C6 +9187:0020FE1028FE2800FE7CAA44AA7CAA00AE7CC2088210FEFE82108210FE508220 +9188:0020FEA228A22924FE50AA88AB04AA22AE20C2A482A4FF2882508288FF048202 +9189:0040FE2029FE2800FE88AA88AB54AA22AE00C22083FEFE2082208220FE208220 +918A:0000FEEE282228AAFE44AAAAAB12AA00AEEEC22A82AAFE4A824482A4FF2A8210 +918B:0048FE48284829FEFE48AA48ABFEAA00AEFCC2848284FEFC82848284FEFC8284 +918C:0000FEFC28842884FEFCAA84AA84AAFCAE00C2908292FEF482988292FED2828E +918D:0000FE7C2844287CFE44AA7CAA00ABFEAE10C210825EFE50825082B0FE9E8300 +918E:0008F80C200A23FEFA08AA08AAE8AA0ADA0A8AEC8AACFAA88AEA8A1AFA268C42 +918F:0020FE2028FA2824FE28ABFEAA20AA40AEFCC3448244FE7C82448244FE7C8244 +9190:0100F93C212427E4F924A93CA924ABA4DAA48ABC8AA4FAA48BA48844F8548888 +9191:0000FEFC28142850FE5CAA50AA7EAA80AE7CC244827CFE44827C8244FE44824C +9192:0000FE7C2844287CFE44AA7CAA10AA50AE7CC2908210FE7C82108210FEFE8200 +9193:0010FE1028FE2892FE92AA28AA28AA4AAE86C30082FEFEAA82AA82AAFEAA83FE +9194:0620382008A47EA819202C504A880904FFFE04403FF82848303827C820083FF8 +9195:0020FE1029FE2800FE7CAA44AA7CAA00AEFEC2828282FEFE82828282FEFE8282 +9196:0000FE7C28442844FE7CAA44AA44AA7CAE00C2FE82AAFEAA82AA82AAFFFE8200 +9197:0008FEEC282828AAFE44AA44AA84AB7AAE28C22882FEFE288228824AFE4A8286 +9198:0010FE10287E2810FE10AAFEAA20AA42AEFEC20082FEFEAA82AA82AAFFFE8200 +9199:0050FE9628922892FED6AA92AA92AAFEAE10C2FC8244FE4482288210FE2882C6 +919A:0008FE4A292A28ACFE88AA3EAA08AB98AE9CC2AA82CAFE8882888340FE3E8200 +919B:0044FE4428FE2844FE10AA28AA44AA82AE7CC2108210FE7C82108210FEFE8200 +919C:0010FE2028FE2892FE92AAFEAA92AA92AEFEC2208224FE5A825E8290FE92830E +919D:0044FE24282828FEFE10AA7CAA10AAFEAE20C220827CFE5082908310FEFE8200 +919E:0000FE7C28542854FE6CAA44AA7CAA00AE00C2FE82AAFEAA82AA82AAFFFE8200 +919F:08202AA44D28145022887FFE4002BFF404803FF82488287830083FF820083FF8 +91A0:0010FE10287C2854FE54AAFEAA28AA44AE82C30082FEFEAA82AA82AAFFFE8200 +91A1:0040FE2029FE2902FE50AA88AB44AA40AEFEC320823CFE20823E8220FE208220 +91A2:0020F82023FC2040F880A9F8AA88AC88D8F8880089FCF95489548954FBFE8800 +91A3:0020FE1028FE2890FEBCAA94AAFEAA94AEBCC29082BCFEA482A482A4FEBC8324 +91A4:083E4BC42A4829281BFE2908C8A80810FFFE04403FF82848303827C820083FF8 +91A5:0000FEFE282828FEFEAAAAAAAAFEAA00AE7CC20082FEFE1082548292FE508220 +91A6:0010FE20284428FEFE44AAAAAAEEAA10AE28C25482AAFE5082248248FE108260 +91A7:0000FBFE2200227CFA44AA44AA7CAA00DAEE8AAA8AAAFAAA8AEE8A00FBFE8800 +91A8:0020FE1028FE2828FE92AAAAAA82AAFEAE10C2FE82A2FEAA82BA8282FE8A8284 +91A9:0028FE2828FE2828FEFEAAAAAAFEAAAAAEFEC200827CFE44827C8244FE7C8244 +91AA:0000FEEE282228AAFE66AAAAAA10AA28AE44C3928220FEC8823282C4FE1882E0 +91AB:7F7848485E8664785F484A307F480084FFFE04403FF82848303827C820083FF8 +91AC:0440247C3CA805507C2825FE44888058FFFE04403FF82848303827C820083FF8 +91AD:0028FEAA286C2828FEFEAA44AA28AAFEAE10C27C8210FEFE82108228FE448282 +91AE:0028FE242840287EFEC8AB48AA7EAA48AE48C27E8248FE48827E8240FEAA832A +91AF:0040F82023FE2040F884A9FEA8A8A8AAD9268A0089FCF95489548954FBFE8800 +91B0:0000FEFE282828FEFEAAAAFEAA00AA7CAE44C27C8244FE7C821082FEFE108210 +91B1:0024FBA820922514FA08AC04ABBAA8A8D8C68B808A3CFB8488A88890FAA88944 +91B2:0028FEFE28AA28FEFEAAAAFEAA00AAFEAE80C2BE8280FEFE82A882AAFEA48332 +91B3:0000FEFE28AA28FEFE10AAFEAA10ABFEAE44C22882FEFE1083FE8210FE108210 +91B4:0028FEFE28AA28FEFEAAAAFEAA00AAFEAE00C2FE8282FEFE82448228FEFE8200 +91B5:0040F87C204023FEFA42AA78ABC4AA3CDA008BFE8A40FBA48A588DB4FC5289B0 +91B6:0010FE1028282844FE82AA7CAA00AAEEAEAAC2AA82EEFE44824482AAFEAA8312 +91B7:0010FEFE28442828FEFEAA00AA7CAA44AE7CC244827CFE2082948342FE44823C +91B8:0020FE1029FE2848FE84AB4AAAFCAA48AEFCC24883FEFE5482C88354FE628240 +91B9:0000FE7C281028FEFE92AA54AA10AA54AE00C2FE8210FEFE82AA82AAFEAA8286 +91BA:001CF9E0202023FEF820A9FCA9ACA974D9FC882089FCF8208BFE8800F9548A2A +91BB:0020FBFE202021FCF800ABFEA802A9FCD8208BFE8800FBFE88048BBEFAA48B8C +91BC:0110F91027FC2110F9F0AA08AAEAAEACDAA88AAA8EEAFA0688008AA4FA528C52 +91BD:0000F9FC202023FEFA22A9ACA820A9ACD8008BEE8AAAFAAA8AAA8AAAFBEE8AAA +91BE:0040F82023FE2248FBFEAA48AAECAB5ADA488B248AA8FBFE8A708AA8FD268820 +91BF:0020FBFE224823FEFA48AAECAB5AAA48DA208A448A78FA148AFE8A10FA548CB2 +91C0:0010FEFE280028EEFEAAAAEEAA44AAFEAE44C2FE8244FEFE825082CAFF648242 +91C1:2FEC48246BAC48246BAC4AA4FFFE92921D7010101FF004401830EFEE04201860 +91C2:001EFBE021222094FBFEAA52ABFEA804DBC48A7E8BC4FA548BCC8A84FAD48B48 +91C3:03DEF80023DE2252FB5AAA52A820ABFEDA508BFE8A52FBFE8A928ADCFA928CCE +91C4:0020FBFE224823FEFA48AAECAB5AAA48DA508BDE8A50FBDC8A508BDEFA508C50 +91C5:03DEFA5223DE2000FBFEAA00AAC8AA4EDBEA8AB28AEAFAAA8AEA8AB4FDE4882A +91C6:001000F83F00010011100910092001007FFC03800540092011102108C1060100 +91C7:001000F83F00020011100910082001007FFC03800540092011102108C1060100 +91C8:0C00F1FC1104550439041104FDFC112031203920552051109110110812041402 +91C9:0C20F0201020542039FC1124FD241124312439FC552451249124112411FC1104 +91CA:0C00F3FC1104548838501020FCD81326302039FC5420502093FE102010201020 +91CB:0C00F1FC115455FC382011FCFC2013FE3088385055FC502093FE102010201020 +91CC:00003FF8210821083FF8210821083FF8010001003FF8010001000100FFFE0000 +91CD:001000F83F000100FFFE01001FF011101FF011101FF001003FF80100FFFE0000 +91CE:00007F7C490449287F104908497E7F12081408107F10081008100F10F0504020 +91CF:00001FF010101FF01010FFFE00001FF011101FF011101FF001001FF001007FFC +91D0:08203E7E08A47F281C102A2849443FFE20002FF828882FF828884FF840809FFC +91D1:0100010002800440082010102FE8C10601003FF80100111009100920FFFE0000 +91D2:10001000280024004200BC0010001000FE0010009400580050001E00F0004000 +91D3:10801080288024804280BC8010801080FE8010809480588450841E84F07C4000 +91D4:1000100028FE24044208BC1010201020FE4010409480588250821E82F07E4000 +91D5:100011FC280424084210BC2010201020FE2010209420582050201E20F0A04040 +91D6:1000100029FC24444244BC4410441044FE4410449444588450841F04F2284410 +91D7:10041004280424444244BC4410441044FE4410449444580450041E04F0144008 +91D8:100010002BFE24204220BC2010201020FE2010209420582050201E20F0A04040 +91D9:10401040284024404240BC5010481044FE4410409440584050401E40F0404040 +91DA:108010802880248043F0B89010901090FC9010909490589251121D12E20E4400 +91DB:102010202820242042FCBC2410241024FE2410449444584450841E84F1284210 +91DC:044008201850248803000CC03030C00E1FF0010001003FF80100111009207FFC +91DD:10201020282024204220BC2013FE1020FE2010209420582050201E20F0204020 +91DE:10801040284024204220BC2010201050FE5010509448588850881E84F1044202 +91DF:10001010289024904090B89010901090FC9010909508590851081E04E2044402 +91E0:100010F0289024904290BC9010901090FE9010909490589250921F12F10E4200 +91E1:0820101021084284044008203018CFE6010001003FF8010011100920FFFE0000 +91E2:1000100029FC24444248BC481050105EFE4210429482588250821F02F1144208 +91E3:104010402840247C4284BC8411041044FE2410249404580450041E04F0284010 +91E4:08040804140822104120BE44080408087F10082249422A0408080F10F02040C0 +91E5:10201020282024204020B8A810A410A4FD2211229622582050201C20E0A04040 +91E6:1000100028FC24844284BC8410841084FE8410849484588450841EFCF0844000 +91E7:11041124292425244124B92411241124FD2411249524592451241E24E2044404 +91E8:100010FC280424084210BC20102011FEFE2010209420582050201E20F0A04040 +91E9:100011F0291025104110B91011901150FD5011109510591251121E12E20E4400 +91EA:100010FC282024204220BC20102011FEFE2010209420582050201E20F0A04040 +91EB:100010FC280024004200BDFE10401040FE8010FC9404580450041E04F0284010 +91EC:100010FC282024204220BC20102011FEFE2010209420582050201E20F0204020 +91ED:1000100028FC24204220BC2010201020FE2010209420582050201E20F1FE4000 +91EE:101010102810241043FEBC1010301030FE5010509490591050101E10F0504020 +91EF:104010202820240043FEBC8010801080FE8010809480588050801E80F0FC4000 +91F0:1000100029FC24244024B8A410A410A4FD2410249424584450441C84E1144208 +91F1:10201020282024204220BDFE10201020FE2010509450585050881E88F1044202 +91F2:1000100028FC24844284BC84108410FCFE8410809480588250821E82F07E4000 +91F3:10401040288024FE4100BA0010FC1008FC1010209440588051021D02E0FE4000 +91F4:1050104828482440425EBDE010401040FE4010409420582250121E0AF0064002 +91F5:100011F8288824C842A8BCA810881050FE5010509420582050501E88F1044202 +91F6:1020102028202520412CB934116413A4FD2411349528592251221D02E0FE4000 +91F7:10201020282024204020B82011FC1020FC2010209420582050201C20E3FE4000 +91F8:104010402840247C4244BC8410C41124FE1810089410581050201E40F0804100 +91F9:104010402840244043FEB88810881088FC8811089490585050201C50E0884304 +91FA:1008103C29E024204020B820102013FEFC2010209420582050201C20E0204020 +91FB:104010402840244041F8B84810481048FD4810C8944858A850AA1D0AE2064402 +91FC:1000100029FC24444044B94410C41044FC641054944C588650841D04E2284410 +91FD:1008101C29F025504150B95011501150FD5011489548594851441E44E2424400 +91FE:100011FE280824884088B888110811FEFC1810289448588851081E08E0284010 +91FF:1004100E28F024804280BC8010FE1088FE8810889488588850881F08F1084208 +9200:1000100029FC25244124B92411241124FDFC11009500590051021D02E0FE4000 +9201:10401020282025FE4240BC401040107CFE4410449444584450841E84F1284210 +9202:10201020282025FE4122BA2410201020FC5010509450585050901C92E112420E +9203:100010FC284824484248BC48104811FEFE4810489448584850481E48F0884108 +9204:10081088284824484208BC8810481048FE08100E95F8580850081E08F0084008 +9205:100010FC288424844284BCFC10841084FE8410FC9484588450841E84F1144208 +9206:10081048284824484044B88410A41122FC2010409440584850841DFEE0824000 +9207:102010202820242041FCB82010201020FDFE10209450585050881C88E1044202 +9208:1000100029FE24104210BC2010201068FE6410A29522582050201E20F0204020 +9209:10201020282025FE4122B92211221122FD52114A958A590251021D02E10A4104 +920A:10001040282024104050B84010401144FD42114295425A4450441C44E03C4000 +920B:10A010A028A025244124BB2815301120FD6011A09520592251221D22E11E4100 +920C:10201020282025FC4024B82410241024FDFE10209450585050881C88E1044202 +920D:10201020282025FE4020B92411241124FD2411FC9424582050221C22E01E4000 +920E:10801080288024FC4104B90412441044FC8410A4951459F450141C04E0284010 +920F:100411E4282424244024B9E411041104FD0411E49424582450241C24E1444084 +9210:10201020285024504088B94412221020FC0011FC9404580850081C10E0104020 +9211:1008101C29E025004100B9FC11441144FD4411289528591051101E28E2444482 +9212:100013FC288424884088B890109C1084FD4411449528592852101E28E4444182 +9213:1008103C29E024204020B820102013FEFC2010209420582050201C20E1FC4000 +9214:10201020282024A842A4BCA211221120FE2410249428580850101E20F0C04300 +9215:100011F8284824484048B848104811F8FC8810889488588850881C88E3FE4000 +9216:10101090289024884108B904120415FAFC8810889488588851081D08E2284410 +9217:10401040288024884104BBFE10021090FC9010909490589051121D12E20E4400 +9218:10201020282025FE4020B820102011FCFC8410889448585050201C50E1884606 +9219:102010202820243E4220BC20102011FCFE8410889448585050201E50F1884606 +921A:10101110291025124112B91411D81110FD1011109510591251521D92E10E4000 +921B:1048104428442440425EBDE010401044FE4410489430582250521E8AF1064002 +921C:104010402840244043FEB84010801090FC90112095205A4852441C84E1FE4082 +921D:101010102890249042FEBC9011101010FE1011FE9410581050101E10F0104010 +921E:10401040288024FC4104BA0410841044FC4410149424584451841C04E0284010 +921F:100011FC282424244224BDFC11201120FF2011FE94225822502A1E24F0204020 +9220:100010F8288824884288BD06120011FCFE8410849448585050201E50F0884306 +9221:102010202820242041FCB92411241124FD2411FC9524582050201C20E0204020 +9222:102010202820242041FEB82010701070FCA810A89524592452221C20E0204020 +9223:100010FE281024104290BC9E10901090FE9010FE9402580250021E02F0144008 +9224:1000100028FC24844284BC8410841084FEFC10849484588450841E84F0FC4084 +9225:102010202820242442A4BCA410A81120FE2010509450585050881E88F1044202 +9226:10201020282024204220BDFE10201020FE2010509450585050881EC8F1244202 +9227:10401020280025FC4000B80010F01090FC9010909490589250921D12E10E4200 +9228:1000100029FC24004000B80013FE1090FC9010909490589051121D12E20E4400 +9229:10201010281024FE4282BC82108210FEFE8210809480588050801F00F1004200 +922A:100011FE290025004178B94811481148FD4811689550594251421D42E23E4400 +922B:10401020282025FE4288BC8810881088FE5010509420582050501E88F1044202 +922C:100010FC288424844284BC8410FC1090FE9010909490588850881E84F1044202 +922D:088008882E9028E028842E84F17C06C01830EFEE01003FF809200540FFFE0000 +922E:100011FC290425044104B9FC11001140FD4411489570594051421E42E23E4400 +922F:10201020292425244124B92411FC1020FC2011249524592451241D24E1FC4004 +9230:10401020280025FE4020B82011FC1124FD2411249524592451341D28E0204020 +9231:100011FC290425044104B9FC11201120FDFE11209520591051121D4AE1864102 +9232:1008101C29F025504150B95011501150FD5011489548596851541E74E2524400 +9233:100010002BFE24084008B9E811281128FD28112895E8592850081C08E0284010 +9234:10201020285024504088B92412121010FDFC10049408588850501C20E0104010 +9235:100011FE282024204020B9FE11221122FD52114A958A590251021D02E10A4104 +9236:10201020282024404248BC8411FE1082FE0010FC9484588450841E84F0FC4084 +9237:102010202820242043FEB82010201020FDFC11049504590451041D04E1FC4104 +9238:105010482848244043FEBC401040107CFEA410A494A8592851101E28F0444082 +9239:10101010281025FE4112B914111011FCFD4411449528592851101E28E2444482 +923A:1000100029FC24204020B82010201020FDFC10209428582450241C20E3FE4000 +923B:100010FC288424844284BC8410FC1080FE8010FE9482588250821E82F0FE4082 +923C:10801080288024FE4340BD401240107CFE4010409440587E50401E40F0404040 +923D:10201020282025FE4040B850109010FEFD92129294925892509A1C94E0104010 +923E:102010202820242041FCB92411241124FD2411FC9524592451241D24E1FC4104 +923F:1000100029FC25244124B92411241124FDFC11249524592451241D24E1FC4104 +9240:100011FC292425244124B9FC11241124FD2411FC9524582050201C20E0204020 +9241:10201020285024884104BA1210201040FD8810109420584451881C10E0604380 +9242:10201020282025FC4124B924112411FCFD241020952058C050401CA0E1184206 +9243:10401040288024FC4120BA2010201020FDFE10209450585050881C88E1044202 +9244:102010202920252041FCB92012201020FDFE10209450585050881C88E1044202 +9245:100010FE288024804280BCFC10841084FE84108494FC588050801E80F0FE4000 +9246:1020102028202420403EB82010201020FDFC11049504590451041D04E1FC4104 +9247:1080108028FE250042207D20912C11747BA411249534592851221D02E0FE4000 +9248:10201010281025FE4102BA0410801088FC9010A094C0588250821C82E07E4000 +9249:10201010281025FE4020B82010441084FDF810109420584450821DFEE0824000 +924A:100011FC284424444044B84410941088FD0010FC9484588450841C84E0FC4084 +924B:1080108029FC25044204BDF411141114FD1411F49504592851121D02E0FE4000 +924C:101C11E0282024204020BBFE10201070FC7010A894A8592452221C20E0204020 +924D:10401020282824084008B84810541152FD5211609660584450C41D44E23C4000 +924E:102010202920252041FCB92012201020FC2011FC9420582050201C20E3FE4000 +924F:100010F8288824884088B8F810881088FC8810F89488588850881C88E3FE4000 +9250:100010002BFE24204020B840104010FCFD8412849484588450841C84E0FC4084 +9251:10101010282024FC4284BC8410841084FEFC10849484588450841E84F0FC4084 +9252:10401020280025FE4020B82010201020FDFC10209420582050201C20E3FE4000 +9253:10801080288024FE4120BA20102011FCFD2411249524592451341D28E0204020 +9254:100011FE291025104110B97C11541154FD5411549554595C51101D10E1FE4000 +9255:100010FE2880248042BCBCA410A410A4FEA410A494BC58A450801E80F0FE4000 +9256:10401040287C24844188BA5010201050FC8813069460581050081CC0E0204010 +9257:108810882888248843FEBC8810881088FE8810F89488588850881E88F0F84088 +9258:10501050285025FC4054B85411FC1150FD5011FE94525852505A1C94E0904110 +9259:1000100029FC25044104B90411041104FDFC11049400589050881D04E2024402 +925A:20002080531E4A5282527A5222522252FA5222D22B5AB25460903890E1100210 +925B:100010F8288824884088B88811061200FC0010FC9484588450841C84E0FC4084 +925C:1088108828882508417EBB0815081148FD2811289508590851081D08E1284110 +925D:102010102810240041FEB80010041084FC8410489448584850501C10E1FE4000 +925E:202820245024482083FE7A2022242224FA2422282A28B29063123A2AE0460082 +925F:100010FE281024104220BC2010681064FEA211229420582050201E00F1FE4000 +9260:10201020282025FC4124B92411241124FD2413FE9420585050501C88E1044202 +9261:10201020292424A440A8B82011FC1020FC20102097FE582050201C20E0204020 +9262:102010202820242043FEB82010701070FCA810A895245AFA54201C20E0204020 +9263:10201020282025FC4020B820102013FEFC2010209440584850841DFEE0824000 +9264:10801080290025FC4204BC0411E41124FD24112495E4592450041C04E0284010 +9265:102010282824242041FCB82010701070FCA810A89524592452221C20E0204020 +9266:1000100029FE24104010B81010901090FC9E10909490589050901C90E3FE4000 +9267:100010FC288424A44094B884108413FEFD0411449524590451FE1C04E0284010 +9268:10801080288024FE4102B90412201020FCA810A49524592252221C20E0A04040 +9269:10201020285024504088B90412221020FCA810A49524592252221C20E0A04040 +926A:102410A428A424A442A4BDFE10A410A4FEA410A494BC588050801E80F0FE4000 +926B:110011002900251C43D4B95411541154FD5411549554595451541E5CE3544480 +926C:100011FC290425044104B9FC11041104FD0411FC9504590451041D04E1FC4104 +926D:1000100028FC24844284BC8410FC1084FE84108494FC588450001E00F1FE4000 +926E:10201020282025FC4124B924112411FCFD241124952459FC51241C20E0204020 +926F:10081048292825284128B90811081108FD0811089548599451141C22E0424082 +9270:100011FC2804240443F4B804100411E4FD241124952459E450041C04E0144008 +9271:10201010281025FE4100B91011101110FD1011209528592452441EFEE4424800 +9272:102010202820243C4220BC20102011FEFE2010209428582450221E20F0204020 +9273:10901090289024904090BB9210941098FC9010909490599252921C92E08E4080 +9274:04402440247C24902488250802800C603018CFE601003FF8092005407FFC0000 +9275:10201020282025FC4124B92411241124FDFC11249420582850241DFEE0824000 +9276:100213E22942254A414AB94A114A13EAFD4A114A954A594A51421E42E24A4444 +9277:104810482848244841FEB84810481048FC4811FE9400584850441C84E0824102 +9278:10401020282025FE4000B88811041202FC8810889450585050201C50E0884306 +9279:10201020287C24844148B83010201048FD90103E944259A450181C10E0604180 +927A:100013FE2888248840F8B888108810F8FC881088948E5BF850081C08E0084008 +927B:10401040287824884150B82010501088FD0610F89488588850881C88E0F84088 +927C:110410842888240041FEB88810881088FC8813FE9488588851081D08E2084408 +927D:201020145012481083FE7810201021D0F89020902890B08860EA3B8AE0060002 +927E:102010202848248441FEB81210901090FCFE1110941059FE50101C10E0104010 +927F:10201020285024884104BA0211FC1000FC0011FC9504590451041D04E1FC4104 +9280:100011F82908250841F8B908110811F8FD4411489530592051101D48E1864100 +9281:10401040288024FE4102BA0211F21112FD1211F29512591251F21C02E0144008 +9282:10821092289224924092B89212DA12B6FC9210929492589250921D12E1024202 +9283:10401020282025FE4040B888110411FEFC9210909490589051121D12E20E4400 +9284:10201020284025FC4104B90411741154FD5411549554597451041D04E1144108 +9285:100011FC290425044174B90411041174FD5411549554597451041D04E1144108 +9286:100013FE282024204040B9FC11041104FD0411FC9504590451041D04E1FC4104 +9287:1020102029FE24204020B8FC10201020FDFE107094A858A851241E22E4204020 +9288:1020102029FC24204020B82013FE1000FC20102095FC582050201C20E3FE4000 +9289:1020102029FC242443FEB82411FC1020FC2011FC9420582053FE1C20E0204020 +928A:202820245024482083FE7A2022242224FA2423A82A28B21062123C2AE4460882 +928B:10801088289C25704110BB1015101110FDFE11109510591051101D10E17C4100 +928C:10201020282025FE4040B84010BC1084FD88128894FE588850881C88E0A84090 +928D:100011FE282024404088B90411FE1022FC20102095FE582050201C20E3FE4000 +928E:00007DF01110119011521D12E20E450006C01830EFEE01003FF811100920FFFE +928F:100011DC295425544154B954115413FEFD5411549554595451541ED4E224444C +9290:00047F8408241F24212452240C243104C6CC1830EFEE01003FF811100920FFFE +9291:10201120292025FC4120BA20102013FEFC9010909490589051121D12E212440E +9292:100011DC288824884088B888108813DEFC8810889488588850881D08E1084208 +9293:10201020285024884104BA0211FC1020FC20102095FC582050201C20E3FE4000 +9294:100013FE281024204068B8A413221020FC00102094205BFE50201C20E0204020 +9295:102010202BFE242041FCB82411FC1120FDFE1022942A585450501C88E1044202 +9296:10201120292025FC4120BA20102013FEFC7010A894A8592451241E22E0204020 +9297:1008101C29E025004100B9FE11001100FD7C11449544594451441E7CE2444400 +9298:1040104028FC25044288B85010201040FC8011FC9684588450841C84E0FC4084 +9299:2020202053FE48508088790422FA2000FBFE20402880B1FC60043804E0280010 +929A:105010502850255242D4BC5810501058FED411529450585050921E92F112420E +929B:1008103C29E024204020BBFE10201020FC2011FC9504590451041D04E1FC4104 +929C:11001100229C424084201BC0213E6108AFC8210829482588250821C82E282410 +929D:109010902890251041FEBB1015101138FD3811549554599251101D10E1104110 +929E:10001FF820085FC890481FC810481FE8011006C01830EFEE01003FF80920FFFE +929F:101010922892249242FEBC0010101010FEFE10929492589A50941E10F0104010 +92A0:10401040284425F44048B85013FE1040FC801184969858E050821C82E07E4000 +92A1:10201020282027FE4020B82011FC1000FC0011FC9504590451041D04E1FC4104 +92A2:200021FC5000480083FE780020202022FBB220B428A8B12861243A24E4A20040 +92A3:210021005100491E87D27A5222522252FA5224922A92B11262923A5EE4520800 +92A4:10201020292424A440A8B820102013FEFC7010A894A8592451241E22E0204020 +92A5:10401020282025FE4040B84010A010A2FDA412989490588850881CA4E0C24080 +92A6:100011FE290225224122B92211FE1122FD221152954A598A51021D02E1FE4102 +92A7:104010442A4425484150B84017FE1090FC9010909490589251121D12E20E4400 +92A8:10401020282027FE4202BC44104013FEFC881088950858D050201C50E0884304 +92A9:1008103C29E024204020B9FC10201020FC2013FE9420584050881D04E3FE4102 +92AA:1020102029FE24404240BCFC10841184FEFC1084948458FC50841E84F0944088 +92AB:1080108028F825084210BDFC11241124FD2411FC9500590051021D02E0FE4000 +92AC:1040104429F424484050BBFE10401080FDFE1240948058FC50041C04E0284010 +92AD:10281024283E25E04220BC3C11E01020FE3E11E09422582450181E6AF1864002 +92AE:02000100FFFE0440145024484444010006C01830EFEE01003FF811100920FFFE +92AF:102010202848248841F0B82010401088FDFC1024942058A851241E22E0A04040 +92B0:1088108829FE24884088B80011041104FC8810889450582050501C88E1044202 +92B1:100010F82888248840F8B820102011FCFD2411249524592451341D28E0204020 +92B2:100011FC290425FC4104B9FC10001000FDFC102094205BFE50201C20E0204020 +92B3:10101090288825084204BDFA11081108FD0811F89490589050901D12E212440E +92B4:080C08F07E8008800EFE78880888290816C81830EFEE01003FF811100920FFFE +92B5:1020104028F8248840F8B88810F8108AFC8C13F89418582850481C88E3284010 +92B6:102810242824242043FEB820112010B2FCB4106894A8592452221C20E0A04040 +92B7:10101092285224544210BCFE10821082FEFE1082948258FE50821E82F08A4084 +92B8:100013FE292025284128B9E811281128FD2811E89528592A513A1FEAE0264020 +92B9:101C11E02820242043FEB8A811241222FDF81088949058BE51021D02E2144408 +92BA:242024203DFC0420FC2024F8450006C01830EFEE01003FF809200540FFFE0000 +92BB:11081088289025FC4024B82411FC1120FD2011FE946258A2512A1E24E4204020 +92BC:1020102028A824A840A8B97412221020FC2011FC9420582050201C20E3FE4000 +92BD:101C13E02A20262043FEBA201290130AFE0611FA9508590851081D08E1F84108 +92BE:200021FC5020482083FE780020202022FBB220B428A8B12861243A24E4A20040 +92BF:100011F8280824D04020B9FC11241124FDFC1124952459FC51241D24E124410C +92C0:100011FE2800240042FCBC8410841084FEFC10009484584450481E00F1FE4000 +92C1:100010FC288424844284BC8410FC1000FE0011FE9502590251021F02F1FE4102 +92C2:1080108028FE250042FCB88410A41094FDFE10849524591451FE1C04E0284010 +92C3:1040102029FC25044104B9FC11041104FDFC11209522591451081D44E1824100 +92C4:100013FE282024A44128B85010881104FC0010FC9484588850501C20E0D84706 +92C5:1040102029FC24004088B85013FE1020FC20102095FC582050201C20E0204020 +92C6:108010FC7D04104410341CC4E11406C81830EFEE01003FF809200540FFFE0000 +92C7:100011FC2904250441FCB904110411FCFD04110495FC580050881C84E1024202 +92C8:101C09E0402024200BFE70501088110406C01830EFEE01003FF811100920FFFE +92C9:102010202BFE24204020B9FC11241124FDFC1020947058A851241E22E0204020 +92CA:10881084290226224020B85010881104FE0210FC9484588450841C84E0FC4084 +92CB:2004200E53B8488880887928212E23A8F8A822A82AA8B13E61003A80E47E0800 +92CC:2000200653B8488880887908213E2388F88822882A88B13E61003A80E47E0800 +92CD:2020202053FE482080207BFE22022404F9F820102820B3FE60203820E0A00040 +92CE:1020101029FE25024204B8F810001000FDFE10509450585050921C92E10E4200 +92CF:10201020282025FC4020B8A810A810A8FD7412229450585050881C88E1044202 +92D0:1040102029FE25024244B84011FE1040FC501090949058A051241D42E27E4422 +92D1:104010402888250443FEB80210881144FE4210F895885A5050201C50E1884606 +92D2:1040104028FC24884150B82010D81326FCF8102094F8582053FE1C20E0204020 +92D3:204220E25382488A808A788A23EA208AF98A21CA2AAAB28264823882E08A0084 +92D4:1080108028F825084210B9FC11241124FD2411FC9450585050901C92E112420E +92D5:2020202050204BFE80207820202021FCF840202028A4B282628A3A8AE4780000 +92D6:1004101E29E024224112B89410801020FDFE1044948459C850301C28E0C44302 +92D7:100010F82888248840F8B80011FC1104FD0411FC9504590451FC1D04E1144108 +92D8:100011FC2904250441FCB800100011FCFC20102097FE582050501C88E1044202 +92D9:100011FE2820242042FCBC44104411FEFE00100094FC588450841E84F0FC4084 +92DA:1040104024FE6488A55024202450218806C41830EFEE01003FF811100920FFFE +92DB:2020202051FC4924812479FC20202020FBFE22222A22B3FE62223820E0200020 +92DC:100011FC290425044104B90411FC1020FC201120953E592051201EA0E47E4800 +92DD:1004101E29E024224112B89410801008FDFE10089488584850481C08E0284010 +92DE:100011FE280024924124BA4811241092FC0011FE9420582050201C20E3FE4000 +92DF:100011FC280424FC4004B9FC100013FEFE0211F89488588850501C20E0D84306 +92E0:100011FE29002500417CB900110011FEFD5011529554594851481E44E2524460 +92E1:10201020285024884144BA2210F81008FC10102095FC590451041D04E1FC4104 +92E2:1008103C29C024044144B8A8100011F8FC10102097FE582050201C20E0A04040 +92E3:200027DE50924C9284947C9427D82094F99221922A92B29A64943890E2900110 +92E4:2008200853C84A48825E7A4A23CA224AFA4A23CA2A4AB24A626A3BD2E6120026 +92E5:100011FC290425044104B9FC10001000FDFE1020942059FC50201C20E3FE4000 +92E6:100011FC2904250441FCB900110011FEFD02117A954A594A527A1E02E4144008 +92E7:100011F82908250841F8B908110811F8FD08110895F8589050901D12E212440E +92E8:201020D85394489480907BFE20902094F89420D82B98B09060AA38CAE2860102 +92E9:1048104829FE24484248BC20101011FEFE8010809480588050801E80F0FC4000 +92EA:102810242BFE24204020B9FC11241124FDFC1124952459FC51241D24E124410C +92EB:03043C0404247FA40E2415246484050C06C01830EFEE01003FF811100920FFFE +92EC:101C11E0FD0011FC1D04F1681210312806C41830EFEE01003FF811100920FFFE +92ED:110410842888241041FCB90411041104FDFC10509450589050921D12E20E4400 +92EE:202820245024482083FE7A2022242224FBA422A82AA8B29062923DAAE4460882 +92EF:10201120292025FC4120BA20102013FEFC00100095FC590451041D04E1FC4104 +92F0:100011FC2924252441FCB924112411FCFC20102095FC582050201C20E3FE4000 +92F1:201020145012481083FE781020902050F84820082888B2A8629A3AAAE4660002 +92F2:1010103829C025004100B9FC11101110FD10111097FE580050901D08E2044402 +92F3:102010202BFE242041FCB84013FE1048FC8810FE9508594852281C08E0284010 +92F4:102010202BFE24204020B9FC11041104FD0411FC9450585050921C92E112420E +92F5:101C11E02820242043FEB8A811241222FC0010F89488588850881C8AE10A4206 +92F6:1020101029FE24204248BC8411FE1002FEA810A894A858A850A81EAAF12A4206 +92F7:200027E0525E4A5282527BD222522254FBD422542A48B2E867543854E0620040 +92F8:100011FC2904250441FCB910111011FEFD101110957C594451441D44E17C4244 +92F9:100010FC288024F84080B8F8108013FEFD4011249528591051081D44E1824100 +92FA:2040202053FE4A028504790021DE2252FA5223522C9AB09461103912E212040E +92FB:7E7C48047E4442287E1048287EC4010006C01830EFEE01003FF811100920FFFE +92FC:200023FE52024A8A82527BFE22222222FAAA22AA2AAAB2FA62023A02E20A0204 +92FD:10201020283E242041FCB90411FC1104FDFC112494205BFE50201C20E0204020 +92FE:1040104028FE24824142B87A10A21022FDFE102294AA58AA50FA1C02E0144008 +92FF:1020112428A424A84020B9FC11041104FD7411549554595451741D04E1144108 +9300:10201020285024884104BAFA100011FCFD54115495FC595451541D54E104410C +9301:100011FC2924252441FCB924112411FCFC2011FE947058A851241E22E0204020 +9302:1020102029FC24204020BBFE10881144FE4210F895885A5050201C50E1884606 +9303:102009FE4122252009FC110472681410112806C41830EFEE01003FF80920FFFE +9304:108010F82888250841F0B810101013FEFC201222957458A851241E22E0A04040 +9305:0640387C08947E241C442A94490806C01830EFEE01003FF809200540FFFE0000 +9306:102010202BFE242041FCB82013FE1000FDFC110495FC590451FC1D04E1144108 +9307:1080104029FC24004108B888109013FEFC00100095FC590451041D04E1FC4104 +9308:1020112428A8242041FCB84013FE1088FD0412FA9488588850A81C92E082407E +9309:101C13E02A2027FE4220BA92130A1206FDFC1104950459FC51041D04E1FC4104 +930A:1040102029FE24004088B88811541222FC00102095FE582050201C20E0204020 +930B:200023DE52524A5282527BDE22522252FA5223DE2A52B25262523A52E55208A6 +930C:102011242924252441FCB80011FE1100FD7C1110951059FE51101E10E2104410 +930D:1040108029FC25244124B9FC11241144FDFC109095105BFE50101C10E0104010 +930E:10401040287C24844108BA00102011CEFD02110295CE590251021D02E1FE4102 +930F:100013FE285024504050B9DC11041104FD0411DC9450585050501C50E3FE4000 +9310:10A01090288025FE4110BB1015FC1110FD1011FC9510591051101DFEE1004100 +9311:2040202053FC4A0482047BFC22002228FA2423FE2A20B25062503C88E5040A02 +9312:2000277E55044D048574755426542554F5542554A574755426043404C4140408 +9313:10881048285025FC4020B82011FC1020FC2013FE9450585050901C92E112420E +9314:102010222BB424A840A8B92412A21040FDFC1104950459FC51041D04E1FC4104 +9315:100011FC2904250441FCB904110411FCFC00111295D4591851101D52E192410E +9316:08000E7C08047F4408282A104928194406C01830EFEE01003FF811100920FFFE +9317:101C11E02820242043FEB8A811241242FC4013FE9488590850D01C30E0484184 +9318:2008203C51E0482083FE78A820A820A8FBFE20A828A8B3FE60203820E1FC0000 +9319:10921092292426484124B89210921000FDFE1122952259FE51221D22E1FE4102 +931A:1080108028F825084210B9FC10241024FDFE1024942459FC50241C20E0A04040 +931B:102010202BFE245040A8B92412FA1020FCA8108897FE588850881C88E1084208 +931C:202020205050488881447A2221F82008F850202028A4B282628A3A8AE4780000 +931D:2040202053FE4A02800079FC20002000FBFE20202928B12462223C22E0A00040 +931E:104010202BFE240041FCB90411FC1000FDFC100894105BFE50201C20E0A04040 +931F:102010A228A225244050B88813041022FC2010A494A4592850501C88E1044202 +9320:2040202053FE4A028404780023FE2020F8202120293CB12062A03A60E43E0800 +9321:1020102029FC24504088B90413FE1008FDE81128952859E851281C08E0284010 +9322:10481044285E25E04228BC12106A1196FE48105E95E0582450281E12F06A4186 +9323:200023DE5042494A8084794A22522420F80023DE2852B15260943948E2540422 +9324:108810882BFE24884288BCF810881088FEF8108894885BFE50001E88F1044202 +9325:104010202BFE24804104BBFE100211FCFD0411FC950459FC51041D04E1144108 +9326:1020104028FC248440FCB88410FC1020FC2011FE95225922512A1D24E0204020 +9327:1020101029FE25024204BCF810881088FEF81080948058FC50841E84F0FC4084 +9328:108810882BFE24884088B80011FC1124FD24112495FC592451241D24E1FC4104 +9329:10F81088288824F84088B88810F81000FDFC1104950459FC51041D04E1FC4104 +932A:10501050285025FC4154B954115411FCFD54115495545BFE50001C50E0884104 +932B:100010FC2884248440FCB884108410FCFC4010FE952A5A4A50921D22E04A4084 +932C:102010202BFE242041FCB92411FC1124FDFC1020947058A851241E22E0204020 +932D:100011FC292425244174B92411FC1104FD7411549554597451041E04E2144408 +932E:100011FC290425244124B9FC11241124FD7411549554597451041D04E1FC4104 +932F:10481048284825FE4248BC4811FE1000FEFC1084948458FC50841E84F0FC4084 +9330:10201020282025FE4020B87010A810A8FD2412229420580051541D2AE22A4000 +9331:010002800C603018DFF601003FF8111009207FFC00007EFE08103E7C08107EFE +9332:100011F82808240841F8B808100813FEFC201222957458A851241E22E0A04040 +9333:100011FC280824104020BBFE102010A0FC4011FC9554595451541D54E3FE4000 +9334:1020102029FC24204020BBFE10881104FE22102095FC582050201C20E3FE4000 +9335:108810882BFE24884088B85010501094FD941298949058B250D21C92E08E4080 +9336:2020202053FE4820802079FC20202020FBFE204028A4B1A862903C88E0C60080 +9337:20882088208857E8888873E822A823E8FAA823E82888B7E8608A388AE08A0086 +9338:2020202050204BFE8020792421242124FAAA207028A8B0A861243A22E4200020 +9339:10201120293C25204120BBFE100011FCFD0411FC950459FC51041D04E1144108 +933A:110811082BFE25084148B82013FE1080FC8010F89488588850881D08E1284210 +933B:2010201451D2481280107BFE20102090F89022D02A90B290628A3AEAE7060202 +933C:2020202053FE48508088790422FA2000F80023FE2820B12461223A22E0A00040 +933D:100013FE282024A44128B85010881144FC4010FC95845A8850501C20E0D84706 +933E:1004FF7828407F7E08480F48F888090806C01830EFEE01003FF811100920FFFE +933F:10201020283E242041FEB922113811E0FD22111E9500597852481E4AE48A4906 +9340:100011FC290425FC4104B9FC100011FEFC0813FE9408590850881C08E0284010 +9341:2010209057104C3E8422744427902510F5102510A528752825283944C9441082 +9342:10201020285024884104BA0210F81020FC2011FC9420592450A41CA8E3FE4000 +9343:2080208050FC4954825478A421242244F89421082840B0A462AA3A8AE4780000 +9344:104010202BFE24004000B9FC11041104FDFC10209528592452221C22E0A04040 +9345:221021102110547C8A1072102010217EF91022102E20B22462423AFEE2420000 +9346:200023DE52524A5283DE7A52225223DEFA0222022A02B20262023A02E20A0204 +9347:1110111229D425184152B992112E1040FDFC1104950459FC51041D04E1FC4104 +9348:108810882BFE248840A8B82011FC1124FD24112497FE582050501C88E1044202 +9349:100011FC2904250441FCB904110411FCFC0013FE94205920513C1D20E2A0447E +934A:102010202BFE242041FCB92411AC1174FD2411FC9420587050A81D24E2224020 +934B:100010F82888248840E8B8A810A811FCFD0411749554595451741D04E1144108 +934C:0020112049FC22200BFE10907092110E16C01830EFEE01003FF811100920FFFE +934D:2040202053FE4A4882487BFE22482278FA0022FC2A44B24862283C10E4680986 +934E:1008101C29F025104110B9FE1110117CFD44117C9544597C51441E44E27C4444 +934F:1020102028FC244441FEB80010FC1084FCFC102095FE582051201DFEE0204020 +9350:2000208852524A2282527A8A220223FEF88821442A7AB08861503820E0D80706 +9351:1040104028FE248041FCBA8410FC1084FCFC1040947C58C451281C10E0684186 +9352:100010FC2848243041FEB85210941110FE30102095FE587050A81D24E2224020 +9353:100010F82888248840F8B80013FE1088FCF8108894F85888509E1DE8E0084008 +9354:200023DE52524A5283DE780021FC2000FBFE20802900B1FC60043804E0280010 +9355:100013FE2A22242043FEB82011FC1124FDFC112495FC582053FE1C20E0204020 +9356:108810882BFE248840F8B88810F81088FC8813FE9500594851841D00E1FE4000 +9357:1040102029FC24004088B85013FE1222FC2411FC9524592451341D28E0204020 +9358:200223C252424A5283D27A52225223D2FA5222522BD2B00261823942E24A0404 +9359:1090089043FC2090089017FE7090110816C41830EFEE01003FF811100920FFFE +935A:100010FC288424FC4084B8FC100011FEFC8010FE952A5A4A50921D22E0544088 +935B:2080233852284A2883A87A462200227CFBA422242A28B3A866103A28E2440282 +935C:200023DE52424A4282427BDE2200223EFBD222122A14B3D462083A14E2240242 +935D:11FC1124292425FC4124B92411FC1020FC2013FE96225A2A52FA1E0AE2024206 +935E:10201020283E24204020B9FC110411FCFD0411FC950459FC50001C88E1044202 +935F:100011FC290425FC4104B9FC10201120FDFE1220942059FC50201C20E3FE4000 +9360:1020104028FC248440FCB88410FC1000FDFE1020942058FC50201C20E1FE4000 +9361:100011FC2924252441FCB924112411FCFC0013FE9520592251141D48E1844102 +9362:100010FE2800247C4244BC44107C1000FEFE1092949258FE50921E92F0FE4082 +9363:1048104829FE24484200BDFC10441044FE94110896FC588450841E84F0FC4084 +9364:1008103C29E024204020BBFE102010A0FD2C1124952459AC51241D24E1FC4104 +9365:1080109E2BEA248A41CAB88A13EA1092FCA6102097FE582050501C88E1044602 +9366:22102110211057BE8A28724823AA22AEFABA22EA2AAEB2A864AA3CA2E9A2101E +9367:1080108028FE25024242B9FA100211F2FC0211F2940259F251121DF2E0144008 +9368:101011D428582652418CB888110412FAFC20102095FE582050501C88E1044202 +9369:108810882BFE248840A8B82013FE1040FC8010FC95845A8450841C84E0FC4084 +936A:00207E20247E1884FF2829104A28994406C01830EFEE01003FF811100920FFFE +936B:0620382008A47EA819202C504A88090406C01830EFEE01003FF811100920FFFE +936C:208821C857084908812A712A27AC2148F3082388A554751429143124C1240142 +936D:108010BC2884250841FEBB201520117CFD90111095FE591051281D28E1444182 +936E:204020A051104A0885F6780023C42254FA5423D42A54B25463D43A44E25402C8 +936F:2080208050FC495482D478B4212C2244F89421082840B0A462AA3A8AE4780000 +9370:101E13E0284425244088B9FC10401040FDFE108094FC594451281E10E0684186 +9371:2048214851484BFE8148794821782100F9FE20202BFEB07060A83924E6220020 +9372:100011FC290425FC4110B9FE1110114AFD86100095FC590451FC1D04E1FC4104 +9373:3F2024203F3E21403F5024883F08010006C01830EFEE01003FF811100920FFFE +9374:102011242924252441FCB80013FE1020FC4011FC9554595451541D54E154410C +9375:20102010577C491481FE7214227C2710F17C2510A5FE721022103500C8FE0000 +9376:100011FC2924252441FCB924112411FCFC2010109454594251421D4AE2384000 +9377:102010202BFE24504088BB2611FC1020FC2013FE9400582051FC1C20E02043FE +9378:1080109E289225D24092B89E109211D2FD52115E9552595251D21C22E02A4044 +9379:104010202BFE26024404B9FC100011FCFD0411FC950459FC51041C00E3FE4000 +937A:1020102229FA24244028BBFE10201040FCFC1184968458FC50841C84E0FC4084 +937B:100011FC290425FC4104B9FC108011FEFE2211229552590251FA1C02E0144008 +937C:2008200C500A4BFE82087A0822E8220AFA0A22EC2AACB2A862EA3A1AE2260442 +937D:1040102029FE25024102B9FE11001100FDFE11AA96AA5AFE54AA1CAAE0A24086 +937E:1008103C29E0242043FEB82011FC1124FDFC112495FC582051FC1C20E3FE4000 +937F:1052105228A425FE42A4BC5210521000FEFE1092949258FE50921E92F0FE4082 +9380:1090109E28A225544108BB5415621140FD4411589542594451181D02E10C4130 +9381:20002FDE54924C928494779424982494F7922492A49275DA2E943090C0900090 +9382:110410882BFE24204020B9FC10201020FDFE100094205BFE50201C50E0884306 +9383:2008241C52E04A80888C74B024A822AAF2AC24A8ACA874A824A43524C5320220 +9384:104010202BFE240041FCB90411041104FDFC10529494598852881CA4E0C24080 +9385:11FC1124292425FC4124B92411FC1050FC881104968A588850881C88E1084208 +9386:2108208850904BFE80007BC422542254FBD422542A54B3D462543A44E25402C8 +9387:100011FC2924252441FCB900117C1144FD44117C9544597C51441E44E27C4444 +9388:10841044284825FE4020B8FC102011FEFC40108094FE591052101C10E1FE4000 +9389:100011FC290425FC4104B9FC100013DEFC421252954A58C6535A1C42E14A4084 +938A:1020101029FE24844048B9FE11021224FC1011FE9440587C50441C84E0944108 +938B:2040202053FE4A02842479FC202021FCF82023FE2820B1FC61043904E1FC0104 +938C:10881050280025FE4050B9FC105413FEFC5411FC945058D851541E52E0504050 +938D:2020202053FE482083FE7A42248C21F0F82020442BFEB02261283A24E4A40040 +938E:2100210051FC4A0085F8780023F82088FAA821C82BF8B08A61CA3AAAE0860082 +938F:204017FE8090490813FCE1502252244E010006C01830EFEE01003FF80920FFFE +9390:1008103C2BC024044244B92811FC1220FC2013FE9420592451241D24E1FC4004 +9391:1020102028FC24204020B9FE10401084FDFE100295FC595451541D54E3FE4000 +9392:100011FE2900257E4100B9FE11541148FD641142950459FE51441E24E204440C +9393:2090208851044A42848879FC20042000FBDE20422A52B14A62523842E14A0084 +9394:104010202BFE26024050B88811241050FC88110496FA588850881C88E0F84088 +9395:1020101029FE2510417CB91411FE1114FD7C1110957C594451441E44E27C4444 +9396:1020112428A8242041FCB904110411FCFD0411FC9504590451FC1C00E0884104 +9397:102010202850244840A4B9FE128410FCFC8410FC948058FC51441D44E27C4044 +9398:200023FE500049FC8104790421FC2000FBFE228A2A52B3FE62223A22E22A0204 +9399:2440225E5292481287D2791E25522552FD5227DE2952B11262123A22E42A0844 +939A:10101220297C25444044B87C13401140FD7C11449544597C51441E80E47E4000 +939B:102810242BFE242041FCB92411FC1124FDFC112494085BFE50881C48E0484018 +939C:10003E782A482248FE862B7842484A30854806C41830EFEE01003FF80920FFFE +939D:108810882BFE24884020B85010881104FEFA1000940059FC51041D04E1FC4104 +939E:1020104029FC25044154B92411541104FDFC1000951259D451181D52E192410E +939F:21F820885070498C80007BDE2252218CFA5220202BFEB07060A83924E6220020 +93A0:200023FE52524A5283FE7800200023FEF8202020293CB12061203920E7FE0000 +93A1:2084204450484BFE808478842108214AFA52239C2884B10861083A52E3DE0042 +93A2:1040108029FC25044104B9FC110011FEFD0011FE94025AAA52AA1C02E0144008 +93A3:08202AA44D28145022887FFE410286C41830EFEE01003FF809200540FFFE0000 +93A4:100011FC290425FC4104B9FC10201124FCA8102097FE589050901D12E212440E +93A5:108011F822886870AB8E282029FC28A8216406C01830EFEE01003FF80920FFFE +93A6:204023BE52124A9282527AAA23242040FBFE22222A22B3FE62223A22E3FE0202 +93A7:102011242924252441FCB80013FE1000FDFC1104950459FC50881C50E3FE4000 +93A8:10A0109029FE272041FCB92011FC1120FDFE110094205BFE50201C20E0204020 +93A9:2000245C529449148294745421262100F7DC2114A594755429483108C5140222 +93AA:10A0112C2924252441ACB924112411FCFC2011FC9488585050201C50E0884306 +93AB:1020104029FC25044154B92411541104FC881144967A588851501C20E0D84706 +93AC:1020101029FE240040FCB88410FC1000FDFE1102957A594A517A1D02E10A4104 +93AD:111811E0290224FE4000B97C1144117CFD44117C9544597C51001DFEE0884104 +93AE:102010202BFE242041FCB90411FC1104FDFC110495FC590453FE1C88E1044202 +93AF:2100209E53D24A5282547BD422582254FBD222122A92B25A62D43B50E2100010 +93B0:10881050280025FC4000B85010881104FC0011FC9554595451541D54E3FE4000 +93B1:1020102029FC242043FEB80011FC1104FD0411FC9452589451881EA4E0C24080 +93B2:1020112428A8242043FEBA02100011FCFD04110495FC585050501C92E112420E +93B3:1020104029FC250441FCB90411FC1104FDFC102095FE587050A81D24E2224020 +93B4:1020104029FC250441FCB90411FC1104FDFC1040942058A4528A1E8AE4784000 +93B5:2040202053FE4A02800079FC204020A2FB3420582894B33460523890E3500020 +93B6:100013FE280825E84128B9E8100013FEFC0811E89528592851E81C08E0284010 +93B7:200021FE512049FC812079FC21202120F9FE20022AAAB2AA62AA3A02E0140008 +93B8:20A0209051FE4B2085FC792021FC2120F9FE21002BFCB088609E3902E20A0404 +93B9:102210122914248040BEB808100811BEFC8810889494589250A21D40E23E4000 +93BA:22002100513C482487A478A4213C2124FBA42564293CB12461243924E17E0100 +93BB:109211242A4825244092B80011FC1104FDFC110495FC590451FC1C88E1044202 +93BC:1020103C282025FE4122B93811E2111EFD0411789510597C51101EFEE2104430 +93BD:2020222253FE488081F87A882070238EF82021FC2820B1FC60203BFEE0200020 +93BE:100010F82888248840F8B888108810F8FC0011FC9554595451541D54E3FE4000 +93BF:10201050288825744202B8F8108810F8FC0C11F0942059FC50201DFEE0204060 +93C0:20202020503E482080207BFE22022326FA8A22522B26B252628A3B26E3FE0202 +93C1:112412482924240041FCB92411FC1124FDFC102097FE587050A81D24E6224020 +93C2:200023FE52004A7C82447A44227C2200FAEE22AA2AAAB2AA62EE3A00E3FE0000 +93C3:2220212051204FBE82407A2023BC22D0FA9022902AFEB29064A83DA8E8441082 +93C4:102013FE282025FC4124B9FC112411FCFC2213FE94085BFE51081C88E0284010 +93C5:2120213C214452A88A1076A82AC622BCFAA422BC2AA4B2BC62243A24E224022C +93C6:100011FC292427FE4124B9FC100011FCFD0411FC950459FC51041DFCE0884104 +93C7:22102110211057BE8A40720023BE228AFA8822A82AAEB2A864A83DA8E85E1080 +93C8:2010201052FE4910817C7854207C2354F97C211029FEB11061103A90E47E0000 +93C9:2108210857C84908811E77D225642540F7C82108A388754829543114C1240142 +93CA:08207F20083E7E440884FF2820103E28434486C21830EFEE01003FF80920FFFE +93CB:2088208853FE4888808878F8202023FEFA2223322AAAB37662223A22E22A0224 +93CC:108810882BFE24884000B9FC110411FCFD0411FC94205BFE50501C88E1044202 +93CD:100011FC292425FC4124B9FC10401088FDF0102094445BFE50221D24E2224060 +93CE:200021FC512449FC812479FC20A820A8FBFE20A828A8B1FC60203BFEE0200020 +93CF:208823DE508849DC80887BDE20882000FBFC20042804B1FC60043804E3FC0004 +93D0:200023DE50424A52814A7A52202820C4FB1220602988B03261C43818E0600380 +93D1:104010202BFE24884050BBFE122212FAFE2212FA968A5A8A52FA1E02E20A4204 +93D2:2040208851FC490882527BFE20502188FE2620C02B10B06463883830E0C00700 +93D3:1020104029FC2524417CB98C11541124FD5411FC9420581051541D42E14A4238 +93D4:104010202BFE26024000B9FC102011FCFD2411FC952459FC50001C88E1044202 +93D5:2040202053FE4A5082507BFE22522252FBFE22002A92B2D462983C92E4D2088E +93D6:00803FFE22203FFC22243FFC242027BC246227BE23182DF6204047FC42488FFE +93D7:200023DC52944BD482547BC822882294FBE220002820B1FC60203820E3FE0000 +93D8:20882288529E4AAA82947B88209020A4F88427BE2A84B2A462943A84E4940088 +93D9:102012222BFE24904088B9FE13101510FDFE1110951059FE51101D10E1FE4100 +93DA:200C200A50084BFE82087A48226A224AFBFA224C2A4CB2EC635A3C4AE4D60822 +93DB:1020112428A827FE4202B8F810881088FCF8102095FC592451241D34E1284020 +93DC:1020112428A827FE4202B8F810881088FCF81020942059FC50201C20E3FE4000 +93DD:100011F8290825F84108B9F8100013FCFE9413FC940059F850901C60E1984606 +93DE:101011FE2910257C4114B9FE1114117CFD10117C9554597C51541E7CE254444C +93DF:1020101029FE24004084B84811FE1110FD50117E95905910517E1E10E21044FE +93E0:2020247C52844948803078CE2610227CFA10227C2A10B2FE62103A10E5FE0800 +93E1:1040102029FC24884050BBFE100011FCFD0411FC950459FC50901C92E112460E +93E2:100013FE285025FC4154B95411FC1000FDFC100097FE582050A81D24E2A24040 +93E3:1040102029FE25004148B94811FE1148FD4811489578590052D41EAAE52A4800 +93E4:102011FC292427FE4124B9FC102011FCFD2411FC94405BFE50881DD0E070438C +93E5:102010102BFE26024080B8FE11101320FD7C11449544597C51441D44E17C4144 +93E6:112411242A2424A441547D4A9392150879081128952E592851281D58E14E4180 +93E7:08007F7808483E4800863E782A483E30414886C41830EFEE01003FF80920FFFE +93E8:08047F7808403E402A7E3E482A48FF48098806C01830EFEE01003FF80920FFFE +93E9:21002102511C4FD0811077D0255E27D4F55427D4A11477D421143124C1240144 +93EA:2090209057FE489083FC7A9423FC2294FBFC200029F8B10861F83908E1F80108 +93EB:2062238A208A57EA888A71CA22A2248AF8A420202BFEB07060A83924E2220020 +93EC:2040207C50404BFE82427A7823C4223CFA0822F02B24B2A865FE3C20E8A00040 +93ED:201C21E05020492480A87BFE207020A8F92422222840B02462A23A8AE4880078 +93EE:1020101029FE2510417CB91411FE1114FD7C11109592595451381E54E2924430 +93EF:2020202053FE482082AA792422AA2020FAAA21242AAAB05060503888E1040602 +93F0:2020222252224BFE80007BDE22522252FBDE22522A52B3DE62523A52E55A08A4 +93F1:102011FC2888245043FEB80011FC1104FDFC110495FC582053FE1C20E0204020 +93F2:202023FE504848F080207BFE22422090F9F820282920B1FC62203BFEE0200020 +93F3:2104208850004BFE82227AAA22722222FBFE200029FCB10461FC3904E1FC0104 +93F4:2010279054BC4CA484C477A821102128F14625C0A53C7524252435A4CE3C0024 +93F5:108813FE2888240041FCB8A810A813FEFCA810A895FC582053FE1C20E0204020 +93F6:10A0109029FE272041FCB92011FC1120FDFE110094205BFE50701CA8E3264020 +93F7:105012522954245043FEB888105013FEFC2011FC94205BFE50501C88E1044602 +93F8:2020202053FE482081FC792421FC2124F9FC20222BFEB04260243AA2E28A0478 +93F9:200023BE50A248A280BE7B882208223EFA2A23AA28AAB0BE6088388AE57E0202 +93FA:202423A8209255148A08740423BA20A8F8C623802A3CB38460A83890E2A80144 +93FB:2020212450A84BFE80A8792422222104F90421DE2A44B554609E3904E2040404 +93FC:2210221053DE4D2880A4782023FE2020FBFE22222A2AB27460A83924E6220020 +93FD:204023F850484FFE804873F820402554F75C2444A7FC7444275C3554C5540844 +93FE:2288228857C84A90829E77D4202427D4F45427D4A45477C824483454C46404C2 +93FF:2020212450A84BFE820278F820882088F8F820202BFEB07060A83924E2220020 +9400:102011FC292425FC4020BBFE100011FCFD0411FC950459FC51041DFCE0884104 +9401:22402242525C4FF082507BD0225E23D4FA5422542FF4B01462943C64E8240044 +9402:200023FE50504BDE82527A5223DE2050FBFE22222A22B3FE62223A22E3FE0202 +9403:2020202051FC482083FE7908239C2108F988263E2800B3FE60903890E112020E +9404:1088108829FC24884088BBFE102011FCFD2411FC952459FC50001C88E1044202 +9405:49202A3E7F4849485DA86B104928414406C01830EFEE01003FF811100920FFFE +9406:010878904BFC504049A4445855B4485241B046C01830EFEE01003FF80920FFFE +9407:103C13E0292424A843FEB8A811241202FDFC1124952459FC51241D24E1FC4104 +9408:101811E0284027FE4088B97412521070FC0011FC9504597451541D74E104410C +9409:100013DE2A5227DE4210BA5211CE1000FC8813FE9488588853FE1C88E1044202 +940A:2000277C55444D7C8544757C260025FEF540257EA5AA752A264A3492C42A0444 +940B:2000227C5144497C84447A7C220021FEF940227E2EAAB32A624A3A92E22A0044 +940C:208020F851084BFE8512792221FE2040F8A223542898B33460543892E3500020 +940D:11F81050282027FC40A4B92812A01040FDFC1154958C597451541D74E104410C +940E:1090108829FE25104310BDFE11101110FDFE1110951059FE51001EA4E2524452 +940F:108810502BFE245041FCB954118C1174FD0411FC94085BFE51081C88E0A84010 +9410:1020102029FC24204154B888110412FAFC8810F8948858F850201CA8E1244060 +9411:208820885108493E82487B88209C2100FA4023DC2814B05462B43A94E21C0014 +9412:208822AA22DC548889547222200023FEFA4224442BFCB04460443884E1140208 +9413:2108208853C8481083DE7A6423D42014FBD420542894B0E863883894E2940122 +9414:200023FE50504BFE82527BFE200021FCF90421FC2904B1FC60203BFEE0200020 +9415:200023DE50884AA883FE798822DA24A6F9F821082908B1F861083908E1F80108 +9416:2124212452AA4BAE81247AAA23AE2124FBFE21102914B114628A3A4AE2160422 +9417:23DE225253DE4A5283DE7A0222F22292FAF222922AF2B29262923B32E2020206 +9418:102011FC2888245043FEB80011FC1124FDFC112495FC582051FC1C20E3FE4000 +9419:101010D42848254A4284BC84117A1000FEFC108494FC580050841E48F1FE4000 +941A:100013FE285025DC4104B90411DC1050FC5013FE9440582050A41E8AE28A4478 +941B:100011FC290425FC4104B9FC102013FEFC0011FC950459FC50201D24E2224060 +941C:08207F20223E3E4400843E2804107E2809442EC21830EFEE01003FF80920FFFE +941D:200027FE54004E28854877EE24922484F6A026A8A7E8748824943514C9241242 +941E:100011FC280424FC4004B9FC100011DCFC9413DC94085BFE51081C88E0A84010 +941F:108810882BDE248847FEB88811541222FDFC1104950459FC51041D04E1FC4104 +9420:2108209053FC489082947998209027FEF80021F82908B10861F83908E10801F8 +9421:2094209253F2489087FE701023D22252F25223D4A454728C20EA370AC0160022 +9422:22882108FABE2008729CA92A2288210806C01830EFEE01003FF811100920FFFE +9423:112410A82BFE260240F8B88810F8100CFDF0102095FC582053FE1C20E0A04040 +9424:21F8210851F84D0A85FA750A25FA2402F79E2090A0907F9E24923492C4920892 +9425:108810502BFE242041FCB82013FE1124FCA813FE940059FC51041D04E1FC4104 +9426:200023DE52524BDE82527BDE220222FAFA5222522BFEB25262523A92E20A0204 +9427:200023DE52524BDE82527BDE220222FAFA8A22FA2A8AB2FA628A3A02E20A0204 +9428:109017FC289427FC4290BBFE111213FAFD0E11F8950859F851081DF8E0904108 +9429:104412242928247E4010B828134A111CFD28114C951A592A51481D10E2FE4400 +942A:1020103E282025FE4122B9FC1122117EFD54117C9554597C51101EFEE22244C6 +942B:20A0209051FE4B2081FC792021FC2120F9FE21002BDEB25262523A72E2020206 +942C:2020213C51204BFE8010781423FE2210FBF022542A54B2D463683C4AE8960322 +942D:2040208053FE4A2282AA7A2223FE2272FAAA22022820B3FE60503888E1040602 +942E:202023FE52884A5083FE7A5022FC2254FBFE22542AFCB25062D83D54E6520850 +942F:108810882BFE24A840227DFA902410287BFE104094FC598452FC1C84E0FC4084 +9430:10F81088288824F84000B9DC11541154FDDC102095FE587050A81D24E2224020 +9431:10201020285024884104BAFA10001000FDDC1154955459DC50881C88E1544222 +9432:100011FC2954255441FCB88011FC1244FDF41154955459F450441DF4E0144008 +9433:100011FC282027FE4222B9AC102011ACFC0011FC9524592451FC1D24E12441FC +9434:201023C8527E4A4082627BD42200223EFBC822482E7EB24862483BC8E2480008 +9435:208C23EA50884BFE80087BE8222A23EAF80A23EC288CB3EC608A38EAE3960022 +9436:100011FC2954255441FCB80013FE1000FDFC110495FC586250941D88E2A440C2 +9437:108813FE288824004148BBFE11481178FD0011FC94205BFE50701CA8E3264020 +9438:100011FC295425FC4020B9FC102013FEFC88105095FC582053FE1C20E0204020 +9439:2000227C514449748054785426FE2282FABA22AA2ABAB282628A3A84E50008FE +943A:1020112428A827FE4202B8F810881088FCF8100095FC592451FC1D24E1FC4104 +943B:2040207C50404BFE82427A7823C4223CFA0023FE2A40B3A462583DB4E45209B0 +943C:102011FC2820248843FEB88811FC1104FDFC110495FC590451FC1C88E1044202 +943D:10101210297C241040FEB844132811FEFD10117C951059FE51101D10E2FE4400 +943E:3E1022FE3E4420287EFEA2103EFC231006C01830EFEE01003FF811100920FFFE +943F:1040102029FC24884050BBFE100011FCFD0411FC950459FC50201E94E28A447A +9440:100E11F028A2245441FEB92210141152FD4A12389440587C50841D48E03041CE +9441:2020208852524B2682527A8A222223FEF88821442A7AB08861503820E0D80706 +9442:101C11E0282027FE4020B9FC11AC1174FDFC102095FC582053FE1C00E154422A +9443:100011DC2844255440CCB95410001048FCFE119096FC589050FC1C90E0FE4080 +9444:202023FE502049FC80007BFE200221FCF82023FE2800B3FE60043BBEE2A4038C +9445:208822AA22DC548889547222200023FEFA2220202BFEB07060A83924E6220020 +9446:2144214455544B64814E7BE42004222CF94423E42884B3E4608438E4E7140008 +9447:2040202053FE4888805277AC22AA22A8F5AC2000A10471FC210431FCC1040204 +9448:200027FC224854448FFE744426EC2554FEEC24442EECB55466EC3C44E4540408 +9449:108813FE2888242041FCB82013FE1040FC8811FC940059FC51541D54E7FE4000 +944A:108813FE28A8249041FEBB2011FC1120FDFC112095FE590053FC1C88E070438E +944B:1000FEFE10547CA854547C7C5410FEFE110006C01830EFEE01003FF80920FFFE +944C:2040202053FE4A0281FC7948225021FCFB0421FC2904B1FC610439FCE0880104 +944D:3EF822883EF822883EF822883EF81450238806C01830EFEE01003FF80920FFFE +944E:23FE222052FC4AA482FC7A2023FE2284FAFC22842AFCB28462FC3A48E28403FE +944F:104010202BFE26224154B94A123A1000FDFC115497FE580051FC1C20E0A04040 +9450:100011FC282027FE4222B9AC102011ACFC0013FE942059FC51541D54E154410C +9451:200823E852884BEE82287BF4228223E2F80021FC2954B15461543954E7FE0000 +9452:7E40487E7E9043087EFE48AA7EFE010006C01830EFEE01003FF811100920FFFE +9453:1010107C2A54257C4110B8FE1000137CFD44117C9540597C51441D7CE280447E +9454:2040202053FE4A02851479DE22522554FA8821742A02B1FC60203924E2220060 +9455:2042239C52104BDE82947A94242023FCFA0423FC2A04B3FC62043BFCE1080204 +9456:210827FE5108480083FC7A94229423FCF82823FE2A20B32462A83A92E42A08C6 +9457:10501190289E27EA408AB9D2128A10A4FC501088972658A850701CA8E1244060 +9458:23F8224852484BF88248724823F82000FFBE2AAAAAAA7FBE2AAA3AAACFBE08A2 +9459:2394211027BE51188BAA7546221823E0FA0421FC2800B3F862083BF8E20803F8 +945A:108811DC288825DE4088B954122211FCFD0411FC950459FC51041DFCE0884104 +945B:1020101029FE2528417CB92811FE1110FD7C1154957C5954517C1E00E2444482 +945C:112410A82BFE260240F8B88811FC1104FDFC110495FC590451FC1C00E0884104 +945D:208823FE50884820823C7944203820D6FB382110297CB110617E3910E31004FE +945E:212422485124480083FC7A9422642294FBFC22482B68B248636A3A4AE2460362 +945F:102013FE282025FC4000BBFE125213FEFD0411FC950459FC51041DFCE0884104 +9460:244424E458A84AAA8EEE74A42AAA2EEEF2422040AFFE70E021503248CC460040 +9461:20202120513C492087FE78902294236CFA0423FC2A94B294636C3A04E3FC0004 +9462:2020203C50204BFE82227AF8222422FCFAA422FC2AA4B2FC64203D54E94A023A +9463:2040202053FE4A5083FE7A5223FE2200FA9422D82A90B2D2628E3C00E5540A2A +9464:11FC110429FC250441FC7C8891FC10887BFE108895245AAA50701CA8E1244060 +9465:108011F82A0825FC4124B9FC112411FCFD54122A95FC590451FC1D04E1FC4104 +9466:27DE251227D254548FC8751427E22000FBFC22042BFCB20463FC3A04E3FC0108 +9467:102013FE2A8A25FC4088B9FC110411FCFD0411FC950459FC50901C94E112420E +9468:2110209053DE4810825E798223DE2010FBDE22502BDEB25063DE3A50E25202CE +9469:200023FE50204BAE82AA7AAA23AE2020FBFE20202BAEB2AA62AA3BAEE02003FE +946A:2040207C50404BFC82447BF0224422FCFAA822F82AA8B2F862003DFCE5540BFE +946B:010006C01830EFEE01001FF009203FF8101028287C7C92927C7C10105454FEFE +946C:13D012902BDE266843C4BA8413F81108FDF8110895F8590851F81C90E112460E +946D:23DE225253DE4A5283DE7A2222FA2222FAFA22AA2AFAB2AA62FA3A72E2AA0226 +946E:208823FE208854128AFE701024FE2292FAFE209229FEB29266043AFEE244022C +946F:2148214C52AA480883FE79482368214AFB6A214A2B6CB14C616A3B8AE0160022 +9470:10201050288825744202B9FC115411FCFC0011FC9554595451FC1D54E154410C +9471:21F0221057FC4A0483FC7A2423B82222F9FE22102FFCB24463FC38D0E14A063E +9472:102013FE280025DC4154B9DC108813FEFC8813FE94885BFE50941D88E2A440C2 +9473:204027FE54924BFC80907BFC209027FEF90823FC2D0AB1F862403A7CE54008FE +9474:222223FE209051FE8B1075FE211021FEF91021FE2900B3FE628A3B76E2520276 +9475:208823FE50884BDE82527BDE20A02090F9FE21202BFCB52061FC3920E1FE0100 +9476:2090209057FE4894800A71FE250827E8F14A21EAAF2A75EA254C39EAC2160462 +9477:23FC210851F8490881F8790E27F82008FFFE22942B9CB294639C3AD6E7BC0084 +9478:27FC244457FC4C4487FC70002FBE2AAAFFBE2AAAAFBE7040204037FCC0400FFE +9479:204027FE5492490880807B1C2204239CFA0423FC2A48B36862483B6AE2460362 +947A:23DE225253DE4A5283DE7A5223DE2090F9FE21102BFEB51061FE3910E1FE0100 +947B:22A8224857BE4AA8875C7AAA22882FFEF21825E4A84273F8204037FCC04000C0 +947C:200023FE52524A5283FE71082154225EF7B4211EA25477DE20143554C55E0010 +947D:252827BE294857BE8B1875AA294623FCFA0423FC2A04B3FC62043BFCE1080204 +947E:21084FD2F03C23884812FBBE0280ABAA010006C01830EFEE01003FF80920FFFE +947F:55781448FF4822867F7808486B2849107F2806C41830EFEE01003FF80920FFFE +9480:210821EC510A4FEA89287BC8293E2FE8F9482BE8AA287B682AA83BF4CAB412A2 +9481:23DE225253DE4A5283DE78A021FE2320FDFC212029FEB00061FC3888E070078E +9482:2248215057FC4C0481F0711027FC2554F4E427FCA04077FC20403FFEC2A40452 +9483:23FE220253FE4A9282547A9222FE22AAFAFE23222AFAB2AA62FA3A22E5FA0004 +9484:208823FE50884BDE82527BDE225223DEFA2223FE2AAAB2FA62223A72E2AA0224 +9485:100010001E00200020007C0090001000FE001000100012001400180010000000 +9486:108010801E80208020807C8090801080FE8010801080128414841884107C0000 +9487:100010003DFC20084010BC2010401040FC801080110011041504190410FC0000 +9488:102010201E20202020207C2093FE1020FE201020102012201420182010200020 +9489:100010003DFE20204020BC2010201020FC201020102010201420182010A00040 +948A:100410041E04204420447C4490441044FE441044104412041404180410140008 +948B:104010401E40204020407C6090501048FE441044104012401440184010400040 +948C:100011FC1E04200820107C2090201020FE201020102012201420182010A00040 +948D:102010203C2020204020BC2011FC1020FC201020102010201420182013FE0000 +948E:1008103C3DE020204020BC20102013FEFC201020102010201420182010200020 +948F:110411243D2421244124BD2411241124FD2411241124112415241A2412040404 +9490:100810081E10202020407C8890081010FE201044108412081410182010C00300 +9491:100013FC3C8420884088BC90109C1084FD4411441128112816101A2814440182 +9492:100011F03D1021104110BD1011901150FD5011101110111215121A12120E0400 +9493:104010403C8020FC4104BE0410041104FC841044104410041404180410280010 +9494:108010403C5E21024102BD0211021102FD0211021102110215021902110A0104 +9495:104010403C40204043FEBC8810881088FC881108109010501420185010880304 +9496:100011F83C1020204040BC8011FC1054FC541094112410241444188411280010 +9497:100013FC3D0421444124BCA810881088FC501050102010201450188811040602 +9498:100011FC3C8820884088BC88108813FEFC881088108810881488190811080208 +9499:100013FE3C2020204120BD3E11201120FD2011FE100210021402180210140008 +949A:100010003DFE20104010BC2010201068FCA41122122210201420182010200020 +949B:102010201E20202020207DFE90201020FE20105010501250148818C811240202 +949C:100011FE3D0021004100BDFC11041104FD04110411FC11001500190011FE0000 +949D:20402040384027FC40407A48A2482248FA4823F82048204028423042203E0000 +949E:102010203C2020A840A4BCA211221120FE241024102810081410182010C00300 +949F:102010203C20202041FCBD2411241124FD2411FC112410201420182010200020 +94A0:102010203C2021FE4122BD2211221122FD52114A118A110215021902110A0104 +94A1:100011FC3D0421044124BD2411241124FD241124112410501448188411020602 +94A2:100011FC3D0421044194BD5411541124FD241154115411941504190411140108 +94A3:1008101C3DE021004100BDFC11441144FD4411281128111015101A2812440482 +94A4:102010203C5020504088BD4412221020FC0011FC100410081408181010100020 +94A5:100010FC3C8420844084BCFC10841084FC8410FC108410841504190412140408 +94A6:104010403C40207C4084BC8811201020FC201050105010501488188811040202 +94A7:104010403C8020FC4104BE0410841044FC441014102410441584180410280010 +94A8:102010403CFC20844084BC8410941088FC8010FE1002100215FA180210140008 +94A9:108010803C8020FC4104BD0412441044FC8410A4111411F41414180410280010 +94AA:104010203C0021FC4000BC0010F01090FC9010901090109214921912110E0200 +94AB:104010203C2023FE4080BC80108010FCFC841084108410841504190412280410 +94AC:102010201E20202420A47CA490A81120FE201050105012501488188811040202 +94AD:101011103C9020904010BD1010901090FC10101E13F010101410181010100010 +94AE:100011F83C4820484048BC48104811F8FC881088108810881488188813FE0000 +94AF:100011FC3D2421244124BD24112411FCFD041100110011001502190210FE0000 +94B0:100010003DFC20204020BC2010201020FDFC1020102810241424182013FE0000 +94B1:105010483C40205C41E0BC40105E11E0FC441048103010221452188A13060002 +94B2:100010003DFE20104010BC1010901090FC9E1090109010901490189013FE0000 +94B3:108810883C88208843FEBC8810881088FC8810F8108810881488188810F80088 +94B4:102010203C20202043FEBC2010201020FDFC1104110411041504190411FC0104 +94B5:102010203C20202041FEBC7010A810A8FD241124122210F81420182010200020 +94B6:100010003DFE20084008BDE811281128FD28112811E811281408180810280010 +94B7:100011FE3D002100417CBD4411441144FD441144117C11441500190011FE0000 +94B8:20402040384023FE408078A0A12021FCFB242524212421242934312820200020 +94B9:105010483C48204043FEBC80108010FCFD4411441128112816101A2814440182 +94BA:202820243824202043FE7A20A2242224FA242228222822902B12322A20460082 +94BB:102010203C202020403EBC2010201020FDFC1104110411041504190411FC0104 +94BC:100011FC3D0421044104BDFC11041104FD0411FC110411041504190411FC0104 +94BD:100010003DFC21044104BD0411FC1104FD04110411FC11041400180013FE0000 +94BE:100011FC3D2421244124BDFC11241124FD2411FC112410201420182010200020 +94BF:100010003DFC21244124BD2411241124FDFC1124112411241524192411FC0104 +94C0:102010203C20202041FCBD2411241124FD2411FC112411241524192411FC0104 +94C1:102010203D20212041FCBD2012201020FDFE1020105010501488188811040202 +94C2:102010203C4021FC4104BD0411041104FDFC1104110411041504190411FC0104 +94C3:2040204038A020A041107A48A4262020FBF820082010211028A0304020200020 +94C4:2008203C3BC0220042207A20A22023FEF8202020212821242A22342220A00040 +94C5:100010F83C8820884088BC8811061200FC0011FC110411041504190411FC0104 +94C6:200020803B1E225242527A52A2522252FA5222D2235A22542890309021100210 +94C7:108010803DFC21044204BDF411141114FD1411F4110411281512190210FE0000 +94C8:104010203C0023FE4020BC2011FC1124FD241124112411241534192810200020 +94C9:102010103C1021FE4020BC2010441084FDF8101010201044148219FE10820000 +94CA:102010103C1021FE4102BE0410801088FC9010A010C0108214821882107E0000 +94CB:104010203C2820084008BC4810541152FD5211601260104414C41944123C0000 +94CC:100011FC3D0421044104BDFC11001140FD4411481170114015421A42123E0400 +94CD:101010103C1021FE4112BD14111011FCFD4411441128112815101A2812440482 +94CE:100013FC3D0420884050BC2010D81326FC2011FC1020102017FE182010200020 +94CF:200427C43A84229442947A94A29427D4FA942294229422942A84348424940888 +94D0:104010443DF420484050BDFE10401080FDFE1240148010FC1404180410280010 +94D1:104010403C4421F44048BC5013FE1040FC801184129810E014821882107E0000 +94D2:100011FE3C8820884088BCF810881088FCF810881088109E15E8180810080008 +94D3:104810483DFE20484048BC20101011FEFC801080108010801480188010FC0000 +94D4:200023FC3890209040907892A4922294FA942298209020902890309027FE0000 +94D5:102010203DFE20404040BCFC10841184FEFC1084108410FC1484188410940088 +94D6:202820243824202043FE7A20A2242224FBA422A822A822902A9235AA24460882 +94D7:102010203C2021FC4020BD2410A410A8FC2013FE105010501488188811040202 +94D8:200027DE3892449244947C94A7D82094F992219222922A9A3494289002900110 +94D9:2080208038BC23C040507824A0D4230CF80023FE2090209029123112220E0400 +94DA:100011FE3C2020404088BD0411FE1022FC20102011FE10201420182013FE0000 +94DB:102011243CA420A440A8BC2013FC1004FC04100411FC10041404180413FC0004 +94DC:200023FC3A04220442F47A04A20422F4FA942294229422F42A04320422140208 +94DD:100010FC3C8420844084BC8410FC1000FC0011FE110211021502190211FE0102 +94DE:200021FC3904210441FC7820A02023FEFA222222222222222A2A322420200020 +94DF:200023FE3A02222242227A22A3FE2222FA222252224A228A2B02320223FE0202 +94E0:102011243D24212441FCBC0011FC1004FC0411FC110011001502190210FE0000 +94E1:200223E23A22222A42AA7AAAA2AA22AAFAAA22AA22AA208229423122220A0404 +94E2:20202120392021FC41207A20A02023FEF87020A820A821242924322220200020 +94E3:102011203D2021FC4120BE20102013FEFC90109010901090151219121212040E +94E4:200020063BB8208840887908A13E2388F88822882288213E29003280247E0800 +94E5:1008103C3DE020204020BDFC10201020FC2013FE102010401488190413FE0102 +94E6:1008103C3DE020204020BDFE10201020FC2011FC110411041504190411FC0104 +94E7:109010943D1421184310BD321152110EFD20102013FE10201420182010200020 +94E8:2040204038A0211042087C06A3F82040F840204023F820402840304027FE0000 +94E9:100411883C5020204050BC8811241020FFFE102010A810A415221A2210A00040 +94EA:2040204038A0211042087C06A3F82000F80023F8220822082A08320823F80208 +94EB:105010503C50215240D4BC5810501058FCD4115212501050149218921112020E +94EC:104010403C7820884150BC2010501088FD0610F8108810881488188810F80088 +94ED:104010403CFC21044288BC5010201040FC8011FC128410841484188410FC0084 +94EE:2080208039F8220840107BFCA0242024FBFE2024202423FC2824302020A00040 +94EF:108010803CF821084210BDFC11241124FD2411FC110011001502190210FE0000 +94F0:104010203C2021FE4000BC8811041202FC881088105010501420185010880306 +94F1:104010203C2023FE4040BC4010A010A2FDA4129814901088148418A210C00080 +94F2:204020203BFC200041087890A3FE2200FA002200220022002A00340024000800 +94F3:104010203C2023FE4040BC88110413FEFC9210901090109015121912120E0400 +94F4:2200217C3904240842107A20A07E212AF92A222A264A22522A923322224A0084 +94F5:20402020382023FE42027C44A04023FEF8882088210820D02820305020880304 +94F6:100011F83D08210841F8BD08110811F8FD441148113011201510194811860100 +94F7:210021003900211E47D27A52A2522252FA522492229221122A92325E24520800 +94F8:102010203DFC202040FCBC2011FE1048FC4810FE1088114815281A0810280010 +94F9:208820883BFE208840007BFEA2022444F84023FC204420842884310422280410 +94FA:204820443BFE204040407BFCA2442244FBFC2244224423FC2A44324422540208 +94FB:100013FE3C40204041FCBC84108413FEFC00100011FC11041504190411FC0104 +94FC:20202020382023FE40207924A0A420A8FBFE207020A820A82924322224200020 +94FD:201020143812201043FE7810A0902050F8482008208822A82A9A32AA24660002 +94FE:201022103910217E40207828A748217EF908210821FE210829083288247E0000 +94FF:208022FC3AA422A442A87A90A2A820C6F820202021FC20202820302023FE0000 +9500:102011243CA420A84020BDFC11041104FDFC1104110411FC1504190411140108 +9501:102011243CA420A84020BDFC11041124FD241124112411241450188811040202 +9502:100011FC3D24212441FCBD24112411FCFC20102011FC10201420182013FE0000 +9503:100011FC3D0421044104BDFC10001000FDFE1020102011FC1420182013FE0000 +9504:200820083BC82248425E7A4AA3CA224AFA4A23CA224A224A2A6A33D226120026 +9505:200021FC39042104410479FCA0202020FBFE22222252228A2B0A3202220A0204 +9506:20202120392021FC41207A20A02023FEF800200021FC21042904310421FC0104 +9507:201020D83B94209440907BFEA0902094F89420D82398209028AA30CA22860102 +9508:101C11E03C20202043FEBCA811241222FDF81088109010BE1502190212140408 +9509:102010203D2421244124BD2412AA1472FC20102011FC10201420182013FE0000 +950A:1004101E3DE020224112BC9410801008FDFE1008108810481448180810280010 +950B:104010403CFC20884150BC2010D81326FCF8102010F8102017FE182010200020 +950C:104010203DFC20004088BC5013FE1020FC20102011FC10201420182010200020 +950D:204020203BFC204040907908A3FC2004F9502150215021502A5032522452080E +950E:210020BE3A82220242FA7A52A2522252FBFE2252225222922B123202220A0204 +950F:210020BE3A82220242027AFAA28A228AFAFA228A228A22FA2A023202220A0204 +9510:220821083910402043F87A08A2082208FBF820A020A0292031242224041C0800 +9511:21082088389023FC40247824A3FC2220FA2023FE206220A2292A322424200020 +9512:104010203DFC21044104BDFC11041104FDFC1120112211141508194411820100 +9513:100011FC3C0420FC4004BDFC100013FEFE0211F8108810881450182010D80306 +9514:200023F83A08420843F87A00A20023FCFA0422F422942A9434F4240408280010 +9515:2000277E3D04250445747D54A6542554FD542554257425542E04340424140408 +9516:202020203BFE202041FC7820A3FE2000F9FC210421FC210429FC310421140108 +9517:2020202239FA202440287BFEA0202040F8FC2184228420FC2884308420FC0084 +9518:208820883BFE208840A87820A3FE2040F88020FC218422842884308420FC0084 +9519:21102110391027FC41107910AFFE2000FBF82208220823F82A08320823F80208 +951A:208820883BFE208840887800A1FC2124F924212421FC21242924312421FC0104 +951B:202020203BFE205040A87924A2FA2020F8A8208823FE20882888308821080208 +951C:102010203DFC20504088BD0413FE1008FDE81128112811E81528180810280010 +951D:100011FC3D0421FC4104BDFC100011FEFC0813FE100811081488180810280010 +951E:100011FC3D24212441FCBD24112411FCFC2013FE107010A815241A2210200020 +951F:100011FC3D04210441FCBD04110411FCFC00111211D41118151019521192010E +9520:10FC10843C8420FC4084BC8410FC1000FDFE1102110211FE1502190211FE0102 +9521:100011F83D08210841F8BD08110811F8FC8011FC1254109415241A4410940108 +9522:100011FC3D0421244124BDFC11241124FD741154115411741504190411FC0104 +9523:200023FE3A52225242527BFEA0202040F8FC2104228820502820304021800600 +9524:2008203C39E0202040207BFEA1242124FBFE2124212423FE2820302023FE0000 +9525:105010483C8020FE4190BE9010FC1090FC9010FC10901090149018FE10800080 +9526:102010403DFC210441FCBD0411FC1020FC2013FE12221222162A1A2410200020 +9527:101C11E03D10211041FEBD101110117CFD4411541154115415541A2812440482 +9528:201020503B90221E42127A24A3C82288FA882288228822942A94349424940822 +9529:102011243CA8202041FCBC4013FE1088FD0412FA1488108814A818921082007E +952A:2080208038FC2154425478A4A1242244F8942108204020A42AAA328A24780000 +952B:104010203DFC20004108BC90100013FEFC00100011FC11041504190411FC0104 +952C:204022443A44244840A07910A6082044F84022482248245028A0311022080C06 +952D:204020203BFE220244047800A3FE2020F8202120213C21202AA03260243E0800 +952E:201020103B7C211441FE7A14A27C2710F97C251025FE22102A10350028FE0000 +952F:200023FC3A04220443FC7A20A22023FEFA20222022FC22842A84348424FC0884 +9530:200021FC3808201040207BFEA02020A0F84021FC215421542954315427FE0000 +9531:109210923D2422484124BC9210921000FDFE1122112211FE1522192211FE0102 +9532:2100213C3BD4211443947914A7D42124F94C204027FE204028A0311022080C06 +9533:208820883BFE208840A87820A1FC2124F924212427FE20202850308821040202 +9534:111011123DD421184152BD92112E1040FDFC1104110411FC1504190411FC0104 +9535:109010903C9E22A241D4BC88109410A4FDFE128414A410941494188410940088 +9536:200021FC3924212441FC7924A12421FCF8002040202422A22A8A348820780000 +9537:200023DE3A52225243DE7800A1FC2000FBFE2080210021FC2804300420280010 +9538:1008103C3DE020204020BDFE102010A0FD2C1124112411AC1524192411FC0104 +9539:200820C83B082108412A792AA3AC2148F9082388255421142914312421240142 +953A:1008103C3DE0202043FEBC2011FC1124FDFC112411FC102015FC182013FE0000 +953B:208023383A28222843A87A46A200227CFBA42224222823A82E10322822440282 +953C:10A0112C3D24212441ACBD24112411FCFC2011FC108810501420185010880306 +953D:102010403CFC208440FCBC8410FC1000FDFE1020102010FC1420182011FE0000 +953E:101E13E03C4421244088BDFC10401040FDFE108010FC114415281A1010680186 +953F:204020203BFE200041FC7904A1042104F9FC2052209421882A8834A420C20080 +9540:204020203BFE224842487BFEA2482278FA0022FC224422482A28341024680986 +9541:210420883BFE2020402079FCA0202020FBFE2000202023FE2820305020880306 +9542:102011243CA8202043FEBCA811241202FC4013FE108811081590186011980604 +9543:20842044384823FE40847884A108214AFA52239C208421082908325223DE0042 +9544:209027FC389423FC42907BFEA1122216FDFC2104212421242924305020880304 +9545:200023FC3A24422443FC7A00A2FC2284FA8422FC22842AFC3484248408FC1084 +9546:208820883BFE2088400079FCA10421FCF90421FC202023FE2850308821040202 +9547:202020203BFE402041FC7904A1FC2104F9FC210421FC290437FE208801040202 +9548:202820243BFE202041FC7924A1FC2124F9FC2124200823FE2888304820480018 +9549:200023FE380021FC41047904A1FC2000FBFE228A225223FE2A223222222A0204 +954A:200023FC390821F8410879F8A10E27F8F80827BC20A422A42928329024A80846 +954B:2020212438A8202043FE7A02A00021FCF904210421FC2050285030922112020E +954C:20A0209039FE232045FC7920A1FC2120F9FE210023FC2088289E3102220A0404 +954D:204020803BF8220843F87A08A3F82208FBF8204027FE20E02950324824460040 +954E:102010503C8821744202BCF8108810F8FC0C11F0102011FC14201BFE10200060 +954F:204023BE3A12229242527AAAA3242040FBFE2222222223FE2A22322223FE0202 +9550:204020203BFE200041FC7904A1FC2000FBFE220222FA228A2AFA3202220A0204 +9551:204020203BFC210840907BFEA2022444F82023FC208020F82888310821280210 +9552:210420843888200043FE7800A0882104FA0221FC215421542954315427FE0000 +9553:204020203BFE2202400079FCA04020A2FB342058209423342852309023500020 +9554:204020203BFE2202441479E0A1002100F9FC2110211027FE2800309021080204 +9555:204020203BFE220240507888A1242050F888210422FA20882888308820F80088 +9556:100013FE3C5021FC4154BD5411FC1000FDFC100013FE102014A8192412A20040 +9557:2020212438A823FE420278F8A0882088F8F82020202021FC2820302023FE0000 +9558:200021F8390821F8410879F8A00023FCFA9423FC200021F82890306021980606 +9559:100011FC3D2421FC4124BDFC10401088FDF01020104413FE1422192412220060 +955A:202022223A2223FE40007BDEA2522252FBDE2252225223DE2A523252255A08A4 +955B:202027FE3C2025FC442477FEA42425FCFC2025FC252425FC2D2439FC2924112C +955C:208020403BF8211040A077FEA00023F8FA0823F8220823F82920312222220C1E +955D:204020203BFE208840507BFEA22222FAFA2222FA228A228A2AFA3202220A0204 +955E:22202120392047BE42407A20A3BC22D0FA90229022FE2A9034A825A808441082 +955F:22102110391047BE42407A00A3BE228AFA8822A822AE2AA834A825A8085E1080 +9560:200023DE38422252414A7A52A02820C4FB1220602188203229C4301820600380 +9561:200023FE385023FE42527BFEA00021FCF90421FC210421FC282033FE20200020 +9562:20002FFE38004A2849487BEEA8922884FAA02AA82BE828883894291409241242 +9563:202020203BFE2050428A7904A3FE2504F9FC210421FC20202924322224A20040 +9564:20A024A43AA820A047FC7910A0A027FCF84023F8204027FC28A0311022080C06 +9565:208020F8391023FC452479FCA12421FCF80023FE200021FC290431FC210401FC +9566:210820883BC8201043DE7A64A3D42014FBD42054209420E82B88309422940122 +9567:2200217C3D04244445F47C44A5F42554FD7425D4255425F42CE435542444044C +9568:210820903BFC209042947998A09027FEF80021F82108210829F83108210801F8 +9569:204020203BFE228A41247A22A1FC2124F9FC202023FE22222BFE322220200020 +956A:200023BE38A220A240BE7B88A208223EFA2A23AA20AA20BE2888308A257E0202 +956B:202027A438A8229241147A08A5F42802FBF82208220823F82A0831102FFE0000 +956C:208823FE38A8209041FE7B20A1FC2120F9FC212021FE21002BFC30882070038E +956D:100011FC3C2023FE4222BDAC102011ACFC0011FC1124112415FC1924112401FC +956E:200023FC3A94229443FC7800A7FE2000FBFC220423FC20A2291433082D440182 +956F:200023F83AA822A843F87900A3FC2484FBE422A422A423E4289437F420140008 +9570:202023FE3A88225043FE7A50A2FC2254FBFE225422FC22502AD8355426520850 +9571:2040202039FC208840507BFEA00021FCF90421FC210421FC28203294228A047A +9572:2080204037FE44024A2473BCA4A42AA8F51022E8240423F828403248244400C0 +9573:204020203BFE225043FE7A52A3FE2200FA9422D8229022D22A8E340025540A2A +9574:212422483924200043FC7A94A2642294FBFC2248236822482B6A324A22460362 +9575:21F022103BFC260443FC7A24A3B82222F9FE221027FC22442BFC30D0214A063E +9576:204027FC380023B842A87BB8A11027FCF91027FC211027FE2928331025480186 +9577:00000FF808000FF008000FF00800FFFE1200111010A010401220141818061000 +9578:00000FF8080008000FF0080008000FF008000800FFFE0400082010103FF81008 +9579:00403E40204020783C8820883C8821102010FE10102820284448FE4402840102 +957A:00083E3C21E020203C2020203DFE20202020FE50105020504488FE8803040202 +957B:00203E2020A020A03CFC20A03D20202021FEFE20103020504448FE8803040202 +957C:00003EFE208220FE3C8820AA3CAA20AA20BEFE8810AA20AA44AAFEAA02BE0102 +957D:00203E2021FC20203D5420883D0422FA2088FEF8108820F84420FEA803240060 +957E:00003BFE21243A2227FE3A22237622AAFB76222223764AAAFB764A22022A0204 +957F:0800081008200840088009000800FFFE0A0009000880084009200A180C060800 +9580:00003E7C224422443E7C224422443E7C20042004200420042004200420142008 +9581:00007CF844887CF844887CF84008408840884108410842084408480840284010 +9582:00007C7C44447C7C44447C7C4004400440045FF4400440044004400440144008 +9583:00007C7C44447C7C44447C7C4004410441044104428442444424480440144008 +9584:0010771055105510771055105510771041104128412841284128414445444282 +9585:00007C7C44447C7C44447C7C40045FF441044104410441044104450442144008 +9586:00007C7C44447C7C44447C7C40045FF440044FE440045FF44004400440144008 +9587:00007C7C44447C7C44447C7C40045FF442044284424442244204420442144008 +9588:00007C7C44447C7C44447C7C40044FE4410441045FF441044104410441144008 +9589:00007C7C44447C7C44447C7C408440844FF44184428444844884428441144008 +958A:00007C7C44447C7C44447C7C4104410449244924492449244FE4400440144008 +958B:00007CF844887CF844887CF840084FC8448844885FE844884488488850A84010 +958C:7C7C44447C7C44447C7C420441045FF4400447C444444444485450344004400C +958D:00007C7C44447C7C44447C7C420441047FFC440447E444244824514460944008 +958E:7C7C44447C7C44447C7C410441045FF44204448444844904522467F44214400C +958F:00007C7C44447C7C44447C7C40045FF441044FE4410441045FF4400440144008 +9590:7C7C44447C7C44447C7C400441C45E0443C45E0443E45E04422441E440144008 +9591:7C7C44447C7C44447D7C410441045FF441044384454449245114410441144008 +9592:7C7C44447C7C44447C7C400447E4442447E4442447E4442448A4504440144008 +9593:00007CF844887CF844887CF840084FC848484FC848484FC84848400840284010 +9594:7C7C44447C7C44447C7C420441045FF440444444428441044284444448544008 +9595:00007C7C44447C7C44447C7C40044FE4408448844FF442844484588441944008 +9596:7C7C44447C7C44447C7C410441045D1445A44544492449145114650442144008 +9597:00007C7C44447C7C44447C7C4084448442844884448440F45F84408440944088 +9598:7C7C44447C7C44447C7C40044FE449244FE449244FE449244104410440144008 +9599:00007C7C44447C7C44447C7C420441045FF441044FE4492449A4494441144108 +959A:00007C7C44447C7C44447C7C420441044FE44444424442845FF4400440144008 +959B:7C7C44447C7C44447C7C40045FF44104492445445FF441044104410441144008 +959C:00007CF844887CF844887CF840085FE840484F4849484F484048414840A84010 +959D:7C7C44447C7C44447D7C4104428444444A24511C6FE440244044428441144088 +959E:7C7C44447C7C44447C7C440448245FF4445444445FF444444444444448544008 +959F:00007C7C44447C7C44447C7C4204414444845524561464544C4473C440144008 +95A0:00007C7C44447C7C44447C7C40045FF441044FE4410441445FF4400440144008 +95A1:7C7C44447C7C44447E7C41045FF4420444444F8441244644588443444C344008 +95A2:7C7C44447C7C44447C7C4004444442844FE441045FF44104428444444824400C +95A3:7C7C44447C7C44447C7C420447E44824544443844C64701C47C44444445447C8 +95A4:7C7C44447C7C44447C7C4104428444445BB4400447C44444444447C444544008 +95A5:7C7C44447C7C44447C7C40044544492459F46F244944488449544A344814400C +95A6:00007C7C44447C7C44447D7C4284444458344444444444444AA4511440144008 +95A7:7C7C44447C7C44447C7C400444445FF4444444447FFC4004444444244824400C +95A8:7C7C44447C7C44447C7C41044FE441045FF441044FE441045FF4400440144008 +95A9:7C7C44447C7C44447C7C410441044FE4492449244FE441145FF440144004400C +95AA:7C7C44447C7C44447C7C40045FF442844FE44AA44AA44CE448244FE44824400C +95AB:7C7C44447C7C44447C7C40045FF4511451145FF453945554593451145FF4400C +95AC:7C7C44447C7C44447E7C41044FE448244FE448244FE4491448A44A444C24481C +95AD:7C7C44447C7C44447C7C40044FE448244FE440045FF450145FF4400440144008 +95AE:7C7C44447C7C44447C7C40345DC4444448445DF44444544449F4560461F4400C +95AF:00007C7C44447C7C44447C7C5084488462A452944C8470245044518456144008 +95B0:7C7C44447C7C44447C7C400442044CE4482448244EE4482448244FE44004400C +95B1:7C7C44447C7C44447C7C444448245FF4682C48244FE44284428444944874500C +95B2:7C7C44447C7C44447C7C444442844FE448244FE442844284449458744004400C +95B3:7C7C44447C7C44447D7C41045FF441044FE449244FE449244FE441045FF4410C +95B4:7C7C44447C7C44447C7C40044FE448244FE448244FE448244FE444444824400C +95B5:7C7C44447C7C44447C7C450444844FF459046FE449044FE449044FF44804400C +95B6:7C7C44447C7C44447FFC48244FE448244FE440045FF450145FF450145FF44008 +95B7:08008BDE525223DE52528BDE22022222FA222222B252AA4A2A8A2202A20A4204 +95B8:7C7C44447C7C44447C7C40045FF442844EE4482448244EE4428442845FF4400C +95B9:7C7C44447C7C44447D7C42045FF449245FF4692C4FE449244FE4411440F4400C +95BA:7C7C44447C7C44447C7C40044FE448244FE448244FE441045FF4444443845C6C +95BB:7C7C44447C7C44447E7C420447E4482452444CE4482448244EE4482448244FEC +95BC:7C7C44447C7C44447C7C480444445E4448A44F144A4C4A244A8452446624400C +95BD:7C7C44447C7C44447C7C40645F8451045FE4509458744FE448244FE448244FEC +95BE:7C7C44447C7C44447C7C408440A45FF440844EA44AA44EA4405446B45914420C +95BF:7C7C44447C7C44447C7C40E45F2449445FF4501447C440444684410442844C4C +95C0:7C7C44447C7C44447C7C44445FF444447FFC482457D4644C47C4442443E4400C +95C1:7C7C44447C7C44447C7C40044EE44AA44EE44AA44EE44824482448244864400C +95C2:7C7C44447C7C44447C7C492445445FF442047FFC482457D4644C44C4442443EC +95C3:7C7C44447C7C44447C7C4FE448244FE448244FE448244FE441445FF44284444C +95C4:7C7C44447C7C44447C7C40045FF442844FE44AA44FE442045FF4444443845C6C +95C5:7C7C44447C7C44447FFC48244FE448244FE4420443F442045FE4444443845C6C +95C6:7C7C44447C7C44447C7C400447C4444447C440044EE44AA44AA44EE440144008 +95C7:7C7C44447C7C44447E7C41044FE4444442845FF440044FE448244FE448244FEC +95C8:7C7C44447C7C44447C7C42044FC444445FF448244FE441044FE451045FF44108 +95C9:7C7C44447C7C44447C7C40045FF442845FF452945FF441044FE441045FF4400C +95CA:7C7C44447C7C44447C7C4004483445C4404453FC484441F4451449F450144008 +95CB:7C7C44447C7C44447C7C40944EA4424C5454482457D4410C4FE442844444582C +95CC:7C7C44447C7C44447C7C41045FF441045FF4555453945FF4454449245114410C +95CD:7C7C44447C7C44447C7C41144FE441445FF442044FE4742447E4442447E4400C +95CE:7C7C44447C7C44447D7C42044FE448244FE448244FE441145DA445444924531C +95CF:FC7E8442FC7E8442FC7E8002BFE2A022AFA2A222AFA2AAAAAFAAA25ADFCA8046 +95D0:7C7C44447C7C44447D7C4FE441044FE448244FE448244FE448247FFC4444482C +95D1:7C7C44447D7C46447FFC48244FE448244FE448244FE441045FF445444924410C +95D2:7C7C44447C7C44447C7C47C4444447C4444447C440044EE44AA446644AA4466C +95D3:7C7C44447C7C44447D7C49244FE440045FF440044FE448244FE444445FF4400C +95D4:7C7C44447C7C44447C7C41044FE441045FF444444FE440044FE44AA45FF4400C +95D5:7C7C44447C7C44447C7C51444A445F744494552455445F44444448A449145208 +95D6:7C7C44447C7C44447C7C40044FF449044FE449044FE449044FF440145554402C +95D7:7C7C44447C7C44447C7C4844484452945CE4484452945EF440044AA45154400C +95D8:00007C7C44447C7C44447C7C40245E2440F45E2452A45E6452244F2478B45048 +95D9:7C7C44447C7C44447C7C480444445E7C52945E9451545E246A544E8C4004400C +95DA:7C7C44447C7C44447C7C480449E45D2449E449247DE4492449E454C45154623C +95DB:7C7C44447C7C44447C7C492445445FF4501447C4444447C441044FE441045FEC +95DC:7C7C44447C7C44447C7C484452945CE44A545EF4428452945EF4428444944888 +95DD:7C7C44447C7C44447C7C40245F24517C5F9451145F5451245F244A545194400C +95DE:7C7C44447C7C44447C7C40045C44447C7F5452945E1452545E2453A47E544298 +95DF:7C7C44447C7C44447D7C46C4583447C4444447C440044EE44AA446644AA4466C +95E0:7C7C44447C7C44447D7C4FE449244FE441047FFC48244FE448244FE44444482C +95E1:7C7C44447C7C44447EFC4AA44EE440044FE449244FE449244FE441045FF44108 +95E2:7C7C44447C7C44447C7C40845E4453F45EA450445EF46A444AE44E444A544008 +95E3:7C7C44447C7C44447C7C492445445FF4501447C444444FE449244FE449244FEC +95E4:7C7C44447C7C44447FFC4AA44FE440045FF440044FC448444FC445244CC4562C +95E5:7C7C44447C7C44447C7C50844BE4408447F459444BE448844FF44884488457EC +95E6:7C7C44447C7C44447C7C42844FE44AA44FE44AA45FF4444447C4444442844FEC +95E7:7C7C44447C7C44447C7C408463E4508447F4722453E45154532455146FF4400C +95E8:200013FC10044004400440044004400440044004400440044004400440144008 +95E9:200017FC000440044004400440045FF440044004400440044004400440144008 +95EA:200017FC00044004410441044104410442844244442448244004400440144008 +95EB:200017FC000440045FF44004400440044FE44004400440045FF4400440144008 +95EC:200017FC000440044FE44104410441045FF44104410441044104410440144008 +95ED:200017FC0004408440845FF44084418442844484488450844284410440144008 +95EE:200017FC00044004400447C44444444444444444444447C44444400440144008 +95EF:200013FC100440045F844084488448844FE4402440245FA44024414440944008 +95F0:200013FC1004400440045FF4410441044FE44104410441045FF4400440144008 +95F1:200017FC010441045FF4410441044FE4410441045FF44114411441544124400C +95F2:200017FC00044104410441045FF4410443844544492451144104410440144008 +95F3:200017FC0204420442045FF444044484488449045144522467F4421440144008 +95F4:200013FC1004400447C444444444444447C444444444444447C4400440144008 +95F5:200017FC0004420441045FF44044444442844104428444444844400440144008 +95F6:200017FC0004420441045FF44004400447C44444444444544834500440144008 +95F7:200017FC00044204410441044404542454146454444443C44004400440144008 +95F8:200017FC000440044FE4492449244FE4492449244FE449244104410441144008 +95F9:200017FC0004420441045FF4410441044FE44924492449A44944410441144008 +95FA:200017FC000441044FE4410441045FF4400441044FE4410441045FF44004400C +95FB:200017FC000440045FF4444447C4444447C4444444745FC44044404440544008 +95FC:200017FC00044844444445F440445C4444A4449445144A0451F4400440144008 +95FD:200017FC0004410441044FE44924492449244FE44904412441F45E144804400C +95FE:200017FC0004400447C44444444447C440044FE4482448244FE4400440144008 +95FF:200017FC0104492449244FE440044FE4402440244FE44804481447F44004400C +9600:200017FC000445444524490459F46F044924492448C4489449544A3448144008 +9601:200017FC0204420447E44C445284410442844C6477DC4444444447C440144008 +9602:200017FC0004420441045FF4420444444F8441244644588443444C244004400C +9603:200017FC000440045FF4511451145FF4511453945554593451145FF44004400C +9604:200017FC0004440447C4488451046FE449244FE449244FE44114411440F4400C +9605:200017FC00044444428440044FE4482448244FE4428442844484489450744008 +9606:200017FC020441044FE448244FE448244FE4491448A44A444C2448144004400C +9607:200017FC010441144FE441445FF442044FE4742447E4442447E4442440144008 +9608:200017FC008440A440945FF440844EA44AA44EA440C4465458B441144204400C +9609:200017FC000442045FF444444924711C4FE449244FE449244FE4411440F44008 +960A:200017FC00044FE448244FE448244FE440045FF450145FF450145FF44004400C +960B:200017FC000442044CE448244EE448244FE4428442844494449448745004400C +960C:200017FC000440E45F044A2445445FF4501447C440444684410442844444482C +960D:200017FC000440645F8451045FF450845C5450344FE448244FE448244FE4482C +960E:200017FC0204420447E4482452444CE4482448244EE4482448244FE440144008 +960F:200017FC0004484444445EA448A449144E0C4A444A244A044A8452445624600C +9610:200017FC0004444442844FE449244FE449244FE441045FF44104410440144008 +9611:200017FC010441045FF441045FF45114555453945FF44544492451244104410C +9612:200017FC00044FE448244FE448244FE448244FE441445FF4410442844444482C +9613:200017FC01044FE449244FE441047FFC40044FE448244924492442844444482C +9614:200017FC0004483445C46444504451F44444484479F44914491449F44004400C +9615:200017FC000440845E9442A44A4C4454482457D4610C4FE4410442844444582C +9616:200013FC11044FE441045FF4420444444FE440044FE44AA44AA45FF440144008 +9617:200017FC01045FF441044FE448244FE448244FE448244FE448247FFC4444482C +9618:200017FC00044FE448244FE448244FE440045EF4421452944A5452944A54442C +9619:200017FC000451444A445F744494552455445F44444448A44914520440144008 +961A:200017FC00045C44447C7F5452945E1452545E2453A47E544294430440144008 +961B:200017FC00045FF452945FF440047FFC40044FE448244FE445144CA47444462C +961C:020004003FF020103FF020003FF8200820083FF801000100FFFE010001000100 +961D:00007C0044004800480050004800480044004400440068005000400040004000 +961E:00407C40444048404BFC50444844484444444484448468845104410442284410 +961F:00407C4044404840484050404840484044A044A044A069105110420844044802 +9620:00007DF04490489048905090489049F04490449044906892508A408A40864082 +9621:00087C3C45E048204820502048204BFE44204420442068205020402040204020 +9622:00007C0047FC48904890509048904890449044904490689251124112420E4400 +9623:00407C40448048FE4900520048FC480844104420444068805102410240FE4000 +9624:00207C2044204920492C513449644BA445244534452869225122410240FE4000 +9625:0040784048405044506867705160495049504A486A4854444842404041404080 +9626:00407C40444048404944514449484A50444044A044A068905110410842044402 +9627:00107D104490489048105110489048904410441E45F068105010401040104010 +9628:00007DFE450049004978514849484948454845684550694251424142423E4400 +9629:00087C68478848884888508848884BFE44884488448868885108410842084408 +962A:00087C1C45E04900490051FC4944494445444528452869105110422842444482 +962B:00007C0045FE4810481050204820486844A44522462268205020402040204020 +962C:00807C4044404BFC4800500049F04910451045104510691251124212420E4400 +962D:00407C4044804888490453FE48024890449044904490689051124112420E4400 +962E:00007DFC44004800480053FE48904890449044904490689251124112420E4400 +962F:00207C204420492049205120493C492045204520452069205120412047FE4000 +9630:00107D10451049124912511449D84910451045104510691251524192410E4000 +9631:00887C88448848884BFE508848884888448847FE448868885088410841084208 +9632:00407C2044204BFE48805080488048FC44844484448468845104410442284410 +9633:00007C0045FC4904490451044904490445FC4504450469045104410441FC4104 +9634:00007DFC45044904490451FC49044904450445FC450469045204420444144808 +9635:00407C4044404BFE488050A0492049FC4420442044206BFE5020402040204020 +9636:00207C2044504850488851044A02488844884488448868885088410841084208 +9637:00007C0045FE48204820502049204920453C4520452069205120412047FE4000 +9638:00407C2045FC4904490451FC49004900457C45084510692051424282427E4400 +9639:00207C20442049FC4820502048204BFE4420444044406888510443FE41024000 +963A:00047C1E45F0491049105110491049FE4510451045106908510A414A41A64112 +963B:00007DF845084908490851F849084908450845F8450869085108410847FE4000 +963C:00807C80448048FE494051404A40487C444044404440687E5040404040404040 +963D:00207C2044204820483E50204820482045FC4504450469045104410441FC4104 +963E:00207C2044504850488851244A12481045FC4404440868885050402040104010 +963F:00007DFE4408480849E85128492849284528452845E869285008400840284010 +9640:00407C20442049FE49025204490049084510452045C069045104410440FC4000 +9641:00807C8044FE49004A205120492C497447A44524453469285122410240FE4000 +9642:00207820482053FE5222622452204BFC4A844A886A4852504220445044884906 +9643:00007DFE44204820482051FE492249224552454A458A690251024102410A4104 +9644:00887C8844884908497E53084D08494845284528450869085108410841284110 +9645:000079FC48005000500063FE50204820492849246A2452224422402040A04040 +9646:00207C20442049FC4820502048204BFE44204420452469245124412441FC4004 +9647:00907C88448848804BFE50A048A048A444A445284528693252224262449E4800 +9648:00407840484057FE5080612051204A204BFC4820692851244222442240A04040 +9649:00007DFC440848104830504848844B02440045FC442068205020402043FE4000 +964A:00207C20447C488449485030482048484590443E444269A45018401040604180 +964B:00007BFE4820502052FC62A452A44AA44AD44A846A8452944288420043FE4000 +964C:00007DFE44204820484051FC49044904450445FC450469045104410441FC4104 +964D:00807C8044FC49084A90506049984E26442045FC44206A2053FE402040204020 +964E:00207D20452049FC4920522048204BFE447044A844A869245124422240204020 +964F:00207C2045FE4840484050FC4884498446FC4484448468FC5084408440944088 +9650:00007BF84A08520853F8620852084BF84A444A486A3052204210428843064200 +9651:00007DFE44204820484051FE49524952455245524552695251524142410A4104 +9652:00407C4044FC49044A0851FE4900497C454445444554694851424242423E4400 +9653:002078204BFE48505088510462FA50004BFE4840488069FC5004400440284010 +9654:00407820482057FE5040608451084BF048224844698856104020405041884604 +9655:00407840484057FC50406248515048404FFE48A068A051104110420844044802 +9656:00407C40448849044BFE500248884944464244F845886A505020405041884606 +9657:00207D2444A448A8482051FC4904490445FC4504450469FC5104410441144108 +9658:00007BFC48005124524864905248492448004BFC684050404040404047FE4000 +9659:00007DFE45004900497C5100490049FE45504552455469485148424442524460 +965A:001078184BD45014501067FE5010489048904AD06A905290428A42EA47064202 +965B:02207A244A2853B05220622252A24B1E484048406BFC50404040404047FE4000 +965C:00207C2044204BFE4820502049244924452446AA442068505050408841044202 +965D:00407840484057FE5040645052484A484D5448A268A051104110420844044802 +965E:00287DC8448848884BFE5088488849084628442045FC68205020402043FE4000 +965F:002078204920513C5120612057FE480048204924692452284410402040C04700 +9660:00287C2445FE4820482051FC4924492445FC4524452469FC512441244124410C +9661:00207C2045FC4820482050204BFE482044204520453C692052A04260443E4800 +9662:004078204BFE5202540461F8500048004BFE48906890509041124112420E4400 +9663:00207C2045FE482049FC5124492449FC4524452445FC682053FE402040204020 +9664:00007840484050A05110620855F6484048404BFC684051504248444441444080 +9665:00407C40447C488449085210493E492245224522453E692251224122413E4122 +9666:00207C2047FE482049FC50404BFE4848448844FE450869485228440840284010 +9667:00007DFC4504490449FC5104490449FC4420442045FC68205020402043FE4000 +9668:00007CF84488488848F8500049FC490445244524452469245050404840844304 +9669:0040784048A050A05110620855F64800488848486A4851504110402047FE4000 +966A:00407C2045FC48004908509048004BFE4400440045FC69045104410441FC4104 +966B:00907C9044904B9E4890509048904B9C4490449044906B9E5090409040904090 +966C:00007FE04A5E5252525263D252524A544BD44A546A4852E84754405440624040 +966D:00207C2045FC4850488851044BFE480845E84528452869E85128400840284010 +966E:00A07C90448049FE491053104DFC4910451045FC45106910511041FE41004100 +966F:00207C2044504888490452FA480049FC4554455445FC6954515441544104410C +9670:00207C20445048884944522249F84808441045FC44006BFE5040408841FC4084 +9671:00807C8044FE49024A42524A4952484247FE444244E26952524A404240544008 +9672:0008783C49E05020502063FE512449244FFE4924692453FE4020402043FE4000 +9673:004078404FFC504053F8624853F84A484BF8484068E0515042484C4640404040 +9674:004078804BFC5224522463FC52244A444BFC4890691057FE4010401040104010 +9675:0020782049FC5020502063FE508849444A4248F8698852504020405041884606 +9676:0100790049FC5204550461E4528448844FF448846AA452A443E4400440284010 +9677:0080788048F851085210640050404B9C4A044A046B9C52044204420443FC4204 +9678:00207C2045FC4820482053FE488849044622442045FC68205020402043FE4000 +9679:00287DC8448848884BFE508848884908460045FC4504690451FC4104410441FC +967A:00207C2044504888490452FA4820482045FC4524452469FC5050408841044202 +967B:00007BFE4850505053FE625252524A524BFE4820682053FE4020402047FE4000 +967C:00207C2245FA4824482853FE4820484044FC4584468468FC5084408440FC4084 +967D:00007CFC448448FC488450FC480049FE448044FE452A6A4A5092412240544088 +967E:00007BFE4820504051FC6154515449544954492C682053FE4050408841044202 +967F:00007DFE4510491049FC51104954495445BA4510452869245142418041FE4000 +9680:00087C3C45E048204BFE502049FC492445FC452445FC682051FC402043FE4000 +9681:00007BFE4A0052FC528462FC52844AFC4A204BFE6A4852C842304248428443FE +9682:00207C50448849044AFE508048F8488044F8448047FE68405088410443FE4002 +9683:004078A04910520855F6600053C44A544A544BD46A54525443D44244425442C8 +9684:00007DFC4504490449FC5104490449FC440047FE44206920513C412042A0447E +9685:01FC7924492449FC5124512461FC502048204BFE4A226A2A52FA420A42024206 +9686:008079F84A08551050E063185C064BF848404A406BFC544043F840404FFE4000 +9687:000C780A48084BFE520853F8624A524A4BEA4AAC4AAC6A4C52AA430A42164422 +9688:00007BF84A484A4853F85248624853F848004FFE4A406A445228429043084206 +9689:00407D9C4504490449DC5104490449FC4400440045FC68205020402043FE4000 +968A:01047888480053FE504060C251224A54489849386A5450944112461040504020 +968B:004078404BFE508051FC622055FE480049FC490469FC510441FC410441144108 +968C:00407C2045FE4800488450484BFE480044FC4484448468FC5084408440FC4084 +968D:00207C4045FC490449FC510449FC480047FE4420442069FC5020402043FE4000 +968E:01107D1245D4491849525192492E484045FC4504450469FC5104410441FC4104 +968F:0010781049FE5420524060FC514448444E7C4A446A7C524442544248450048FE +9690:0080788049F84A08541053FC600451FC48044BFC480468405124452A450A48F8 +9691:00207D244524492449FC50004BFE480045FC4504450469FC5088405043FE4000 +9692:00887C50440049FE485051FC48544BFE445445FC445068D85154425240504050 +9693:00207C2045FE484048FC51104AFE4800442045FE444068FC5110421041FE4000 +9694:00007BFE480051FC5104610451FC48004BFE4A8A6A5253FE42224222422A4204 +9695:00007CFC4484488448FC500049FE490245FE450245FE690251FE404840844102 +9696:00407C8045FC4904490451FC490049FE450045FE44026AAA52AA440240144008 +9697:002078404BFC4A24522453FC622452444BFC484048A868B4513C41224222441E +9698:020879084910480057FC5000611052084C044BF84AA86AA852A842A84FFE4000 +9699:00207CA845244A22480051FC490449FC450445FC442068A85124422240A04040 +969A:00207D2444A84BFE4A0250F84888488844F84420442069FC5020402043FE4000 +969B:010079104BDC52545554628851084AF44C0248006BFC50404150424845444080 +969C:00207DFC448848504BFE500049FC490445FC450445FC682053FE402040204020 +969D:00407C8045FC490449FC510449FC490045FE450045FE680252AA42AA4202400C +969E:01087908490857D0511E679451244FD44A144BD46A545248424844D444244842 +969F:01247A484924500051FC612451FC492449FC48206BFE507040A8412446224020 +96A0:00087C3C45C04844492450A849FC480444FC440445FC684050A442AA428A4478 +96A1:004078204BFC50005108609053FE4A204AA04AFC6B20522042FC4420442049FE +96A2:00207C2045FC48204BFE51084B9C49084588463E44006BFE509040904112420E +96A3:0020792448A853FE50A8612452224904490449DE6A445554409E410442044404 +96A4:00207DFC452449FC482053FE480049FC450445FC450469FC510441FC40884104 +96A5:00107BD248545148508A610452FA4C0049FC4904690451FC4104408847FE4000 +96A6:00107BC84A7E5240526263D452004A3E4BC84A486E7E5248424843C842484008 +96A7:00887C484A5050FC5020605056944A384A504A986A3452544290422045FE4800 +96A8:002079FE4C404AFC511052FE600056FC4A844AFC4A846AFC5284428C450048FE +96A9:004078804BFE522252AA622253FE4A724AAA4A02682053FE4050408841044602 +96AA:00207C2044504888490452FA4800480045DC4554455469DC5088408841544222 +96AB:00207DFC442048884BFE508849FC490445FC450445FC690451FC408841044202 +96AC:00007BFE49244A2257FE5222637652AA4B764A224B766AAA53764222422A4204 +96AD:000079FC48204BFE522251AC602051AC48004BFE482069FC515441544154410C +96AE:004078204BFE4888505257AC62AA52A84DAC4800490469FC510441FC41044204 +96AF:00207BFE482049FC500053FE600251FC48204BFE48006BFE500443BE42A4438C +96B0:00007BFE4A024BFE520253FE610852524B9C49084A526BDE500042A442524452 +96B1:003E7FC04A44492853F8504067FC50004BF848084BF8680853F84544452A48FA +96B2:00207CA845244A2A483050C04BFE492045FC452045FC692051FE400242AA4004 +96B3:00407BFC488051F84A204DFC688850F8418846C01930E10E1190214845240200 +96B4:011078904BDE4810525E518263DE50104BDE4A504BDE6A5053DE4250425242CE +96B5:0108F1EC910AA7E8A528C5DEA72894EA940A97EAD40CA7EC8A2A8BEA915687E2 +96B6:010001003FF801080108FFFE010801083FF821081190056009203118C5060200 +96B7:10201020FCFC102411FE7C2400FC7C200124FCA8107054A85324922210A03040 +96B8:10201020FEFC382455FE922410FC7C200124FEA8107054A85324922250A02040 +96B9:0900088008801FFC108030805FF8908010801FF81080108010801FFC10001000 +96BA:020002007FFC450408801FFC308050809FF8108010801FF8108010801FFC1000 +96BB:090008801FFC30805FF890801FF810801FFC10003FF00820044003801C70E00E +96BC:090008801FFC30805FF890801FF810801FFC11000100FFFE0100010001000100 +96BD:090008801FFC30805FF890801FF810801FFC10003FE00420047C08043014C008 +96BE:00A00090FC8005FE05104B102DFC2910111011FC29102510451081FE01000100 +96BF:28502448248020FE3D90E29020FC2090209020FC20902090149014FE0C800480 +96C0:010011101108212440C003000C803040DFFC10801FF810801FF810801FFC1000 +96C1:00003FFE20002250224824FE24902D9036FE2490249024FE2490449044FE8480 +96C2:08500848148014FE2390529088FC089000907EFC02900490049008FE08800080 +96C3:00507E48248024FE2590269024FCFF90249024FC24902490249024FE44808480 +96C4:0850084808807EFE1190129020FC2890489048FC9090149022907EFE22800080 +96C5:00507E48048024FE2590269044FC7F900C9014FC14902490449084FE14800880 +96C6:090008801FFC30805FF890801FF810801FFC1100FFFE054009203118C1060100 +96C7:010000803FFC20043FFC2280224027FC2C4037F8244027F84440444087FC0400 +96C8:0440FC7E0440010008801FFC108030805FF8908010801FF8108010801FFC1000 +96C9:20A0209020807DFE5110931015FCFD10111011FC11102910251045FE41008100 +96CA:2050204820807EFE439082907AFC4A904A904AFC4A907A904A9002FE14800880 +96CB:090008801FFC30805FF890801FF810801FFC10003E7C2244224423C420142008 +96CC:14501448148054FE55905E9054FC5490549054FC549054905D9076FEC4800080 +96CD:02000100FFFE1050104824FE45907A9010FC2490449078FC0890109020FEC080 +96CE:00507C48448044FE45907E9044FC44907C9044FC449044904E90F0FE00800080 +96CF:205020483E8042FE85900A90FEFC029002907EFC029002900290FEFE02800080 +96D0:010001F801003FFE210221F02F0422FC224027FE2C4037FC244047FC444087FE +96D1:20502048F88028FE29902A9046FC90901090FEFC10903490529092FE50802080 +96D2:205020483C8044FEC5902A9010FC2890449082FC7C904490449044FE7C804480 +96D3:10501048288044FE83907E9010FC1090FE9010FC54905290929010FE50802080 +96D4:1428122420403F7E64C8A5483F7E244824483F7E2448244824483F7E20402040 +96D5:00287F244940497E5DC849487F7E41485D48557E55485D484148417E45408240 +96D6:00507C48448044FE7D90129010FCFE90929092FCFE901090149012FEFE800280 +96D7:10401040107EFE8011507C4844FE7D9046907CFC1090FEFC1090109010FE1080 +96D8:00443DFE2454244834FE2D9024FE2490FEFE249024FE248025FE244444388DC6 +96D9:081024483F7E64C8BF7E24483F7E24483F7E20401FF00820044003801C70E00E +96DA:0820FFFE08203EF822883EF8090008801FFC30805FF890801FF810801FFC1000 +96DB:202820247F40917E55C87D48217E4A48A4487F7E914855487D48217E4A408440 +96DC:10500848FE8000FE259026905AFC91901090FEFC10905490929012FE50802080 +96DD:492892244940007E7CC845487C7E0048FE48927E9248FE488148817E7F400040 +96DE:0E50F048228092FE4590229044FCF890109024FCFE901090FE9028FE44808280 +96DF:010042047FFC08803440CFFC18802FF848800FFE08003FFC24242BD4224423CC +96E0:30182A1441207D3ED06853287D3E512851287D3E5128516851A87D3E40204020 +96E1:0028EE242240AA7E66C8AB48187E66488948307EC4481948E2480C7E3040C040 +96E2:102808247F40147E49C85548417E7F4808487F7E514855485D48417E45404240 +96E3:22282224FF40227E3EC809487F7E49487F48087E7F480848FF48147E22404140 +96E4:3AB821083AB82288393822887FFE48829FFC30805FF890801FF810801FFC1000 +96E5:08801FFC30805FF890801FF810801FFC24483F7E64C8BF7E24483F7E24483F7E +96E6:318C294A22107BDE56B4D2947BDE529452947BDE5294529452947BDE42104210 +96E7:08801FFC3080DFF810801FFC14283F7E64C8BF7E24483F7E0100FFFE0920711C +96E8:0000FFFE0100010001007FFC4104410449444524410449444524410441144008 +96E9:3FF801007FFE41029D7401001D7000003FF80000FFFE04000FF0001000A00040 +96EA:3FF801007FFE41029D7401001D7000003FF8000800081FF8000800083FF80008 +96EB:00003FF801007FFE41029D7401001D700000FFFE020002400220021002000200 +96EC:00003FF801007FFE41029D7401001D70000001007FFC038005601918E1060100 +96ED:3FF801007FFE41029D7401001D7000003FE008400CF81210112020C043309C0E +96EE:00003FF801007FFE41029D7401001D70000001F03E0003F03E0003FA7E0201FE +96EF:3FF801007FFE41029D7401001D70020001007FFC08200440038004401830E00E +96F0:3FF801007FFE41029D7401001D70044008203018DFE604200420082010A02040 +96F1:3FF801007FFE41029D7401001D70020001007FFC040007F00410081010A06040 +96F2:3FF801007FFE41029D7401001D7000003FF800000000FFFE082010103FF80008 +96F3:3FF801007FFE41029D7401001D7000003FFC200021002FF82108420844509820 +96F4:00003FF801007FFE41029D7401001D70020001003FF8000008200440FFFE0000 +96F5:3FF801007FFE41029D7401001D70000001001FF011101110FFFE02801C70E00E +96F6:3FF801007FFE41029D7401001D7002800C603218C1061FE00020064001800040 +96F7:00003FF801007FFE41029D7401001D7000003FF8210821083FF8210821083FF8 +96F8:00003FF801007FFE41029D7401001D70000008207FFC08200FE008200FE00820 +96F9:3FF801007FFE41029D7401001D7008001FF020105F9010901FD0102010040FFC +96FA:3FF801007FFE41029D7401001D7000001FF0022001407FFC0484188862800100 +96FB:3FF801007FFE41029D7401001D7000003FF821083FF821083FF80102010200FE +96FC:3FF801007FFE41029D7401001D7000007FFC040008001FF82808C8080FF80808 +96FD:3FF801007FFE41029D7401001D70000000F87F0011100920FFFE010005000200 +96FE:3FF801007FFE41029D7401001D7004000FE0144003801C70E20E0FE004201860 +96FF:3FF801007FFE41029D7401001D700000244814500C601450644808421042603E +9700:00003FF801007FFE41029D7401001D700000FFFE02003FF82488248824A82010 +9701:3FF801007FFE41029D7401001D7000807FFC082007C01830E44E044008401040 +9702:00003FF801007FFE41029D7401001D702040104087FE50E02150E24824442842 +9703:3FF801007FFE41029D7401001D70204013FC824454A810A0E1222222241E2800 +9704:3FF801007FFE41029D7401001D70111009203FF820083FF820083FF820082018 +9705:3FF801007FFE41029D74000001007FFC00003FF800003FF800003FF820083FF8 +9706:3FF801007FFE41029D7401001D7000087C3C09E010203DFC44202BFE10006FFE +9707:3FF801007FFE41029D7401001D7000003FFC20002FF820003FFC24484430860E +9708:00003FF801007FFE41029D7401001D70204017FC40402BF80A48724812581040 +9709:3FF801007FFE41029D7401001D7010001FFC20005FF01210FFFE20903FFC0030 +970A:3FF801007FFE41029D7401001D7000001FF000007FFC044024481450FFFE0000 +970B:3FF801007FFE41029D7402001FF002107FFC02101FF004007FFC082007C07838 +970C:3FF801007FFE41029D7400003FF8210827C821082FE8200827C8444847C88018 +970D:3FF801007FFE41029D7401001D7008801FFC30805FF890801FF810801FFC1000 +970E:3FF801007FFE41029D7401001D7002003FF808207FFC0200FFFE082007C07838 +970F:00003FF801007FFE41029D7401001D7004407C7C04403C7804407C7C04400440 +9710:3FF801007FFE41029D7401001D70000027881088878854102790E0A422BE2102 +9711:3FF801007FFE41029D7401001D7020001040807C48400BF81208E20823F82208 +9712:00107F100810FFA888A86B4408A26B1000107E7C0004FF04100822087F100110 +9713:3FF801007FFE41029D7401001D70060038F820083CF820083FF808421042E03E +9714:3FF801007FFE41029D7401001D702080104087FC4040104023F8E040204027FC +9715:00107F10087EFF9088906B5408546B5400547F7C0014FF90101222127F12210E +9716:3FF801007FFE41029D7401001D70082008207EFC08301C682AA4C92208200820 +9717:3FF801007FFE41029D7401001D70204010A00158462629F0081070A010401020 +9718:3FF801007FFE41029D7401001D70200013FC020442F42A040AF4729412F4120C +9719:3FF801007FFE41029D7401001D700820FFFE09201FF01110FFFE02801C70E00E +971A:00003FF801007FFE41029D7401001D7000207E20247E18A4FF2829104A2898C6 +971B:3FF801007FFE41029D7401001D7000007BDE08427BDE42107BDE0842294A1084 +971C:3FF801007FFE41029D7401001D70000008FC7E8418FC2C844AFC888408FC0884 +971D:00003FF801007FFE41029D7401001D7000007BBC4AA44AA44AA44AA47BBC4AA4 +971E:3FF801007FFE41029D7401001D7000003EF822083EF820003EF820483E3020CC +971F:3FF801007FFE41029D7401001D701090089043FC2090089017FE709011081204 +9720:3FF801007FFE41029D7401001D7020201050FC8849444A2210F81E08F0104020 +9721:3FF801007FFE41029D7401001D7000203C1024E03C2225B43CA8252426A24C40 +9722:3FF801007FFE41029D7401001D70000C7DF045087D7045447D68455055488A66 +9723:3FF801007FFE492284140FE008203FF820083FF820083FF820083FF808201010 +9724:3FF801007FFE41029D74040079FC40444844545462883FF821083FF821083FF8 +9725:3FF801007FFE41029D7400007FFE40029FF406003B0804B019C062A00C987306 +9726:3FF801007FFE41029D7401001D7022042208F7B022047708AAB2224422182260 +9727:3FF801007FFE41029D74000000407EFC15440838FE441AA22CFC4844A8941108 +9728:3FF801007FFE41029D7400003F0821083F7E20082F4820285F88440895282C90 +9729:3FF801007FFE41029D740000087C7F4422483E5000483E4404647F5808401840 +972A:3FF801007FFE41029D7401001D70203C17C08244412817FC2040EFFE204027FC +972B:3FF801007FFE41029D7400007EFC22441A3462C404001FF010101FF010101FF0 +972C:3FF801007FFE492284143FF821083FF821083FF804403FF80440FFFE08201010 +972D:3FF801007FFE4922841423F8120803F8720813F8110013FC14441AA413F4000C +972E:3FF801007FFE49228414211017FC911041F0411011F02110E7FC2250228823FC +972F:3FF801007FFE41029D74000000907EA004442BA810102FE8C8260FE004407FFC +9730:3FF801007FFE41029D74000012203F20123E7F4400A43F2421283F1021282346 +9731:3FF801007FFE49229FF402207FFC04887A8001003FF8282837D8244827C82018 +9732:3FF801007FFE41029D7401001D7000407CF845487C3011CE5C0050F85C88E0F8 +9733:3FF801007FFE41029D74008079F84A884870538E492049FC6A2050F8402043FE +9734:00207C2010FCFE2493FE542410FC542001247CA80070FEA821244822FCA00440 +9735:3FF801007FFE41029D7400003E2822243E240020FFFE22243E282392FE2A0246 +9736:3FF801007FFE41029D74008047FC21100FFE884257FC1100E1F8220822282410 +9737:3FF801007FFE4922841401F8790849F849084BFE79004BFC4CA449247A544888 +9738:3FF801007FFE41029D7422007F7C22443E44087C7F4449447F7C0844FF540888 +9739:3FF801007FFE41029D7401001D7000107EFE42447E2840FE7E10627CBE102210 +973A:3FF801007FFE41029D7401001D702010455097DE20246FD4A014278824D428A2 +973B:3FF801007FFE41029D7404403FF824483FF824487FFC10101FF00820FFFE0000 +973C:00807C8010FCFF0092F8540011F8544801687CC801F8FE4A20EA495AFC460442 +973D:3FF801007FFE49228514FFFE02887D7025484D6690101FF010101FF010102010 +973E:3FF801007FFE41029D743000CBFC2D2431FCC92415FC64200DFC3420C5FE1800 +973F:3FF801007FFE41029D7400807DF8068828701088FD0634F8508890F8508820F8 +9740:3FF801007FFE41029D7408207FFC08207FFE40029FF40600192006C038A00318 +9741:3FF801007FFE492284143FF821083FF821083FF80000FEFE9292FEFE9292FEFE +9742:3FF801007FFE492284147FFE40005F3C44107F7E4E345552609044F84480BFFE +9743:3FF801007FFE41029D7401001D70081024483F7E64C8BF7E24483F7E24483F7E +9744:3FF801007FFE4922A41411FCFD0401FC790401FC788001FE7A224D5279FA4806 +9745:00287CFE102AFEFE92A854FE104A54FE00827CFE0082FEFE208248FEFC440482 +9746:00107E10117CFE1492FE5414137C559201547D380154FF9221304900FEFE0400 +9747:3FF801007FFE41029D74000008407F7C1440FF7C22043E7C22403E7C2242263E +9748:3FF801007FFE41029D7401001D7000003BB82AA83BB800007FFC11102928FFFE +9749:000E7DF010A2FE5493FE552210145552014A7E380040FE7C20844948FC3004CE +974A:3FF801007FFE41029D74000049245D7449247FFC00003FF808200FE004407FFC +974B:3FF801007FFE41029D74200017FE840047DC148827FEE5CC26AA293C292013FE +974C:3FF801007FFE492285147FFC40843CF809283CB009287FF011101FF008201010 +974D:3FF801007FFE41029D74284024FC7E8448FCFE8448FE7E8048FE48027EAA4004 +974E:3FF801007FFE41029D74084014FC22845CFC88843EFE08804AFE28020EAA7004 +974F:3FF801007FFE41029D7410407EFC528428FC3E8468FEBE8028FE3E0228AA3E04 +9750:3FF801007FFE49229FF411101FF000007C7C1010FEFE929254547C7C54547C7C +9751:010001007FFC01003FF80100FFFE00001FF0111011101FF01010101010501020 +9752:010001007FFC01003FF80100FFFE00001FF010101FF010101FF0101010501020 +9753:100010FCFE8410847CA410A4FEA400A47CA444A47C5044507C5044925492490E +9754:10401040FE7E10807D00107CFE0000007CF844087C0844087C0A440A54064802 +9755:00200020FDFE102010FC102051FE5C0050FC508450FC50845CFCF08400940088 +9756:2020102013FEFC2001FC08208BFE880049FC490451FC51041DFCE10441140108 +9757:10201020FD2410A47CA81020FDFE00507C5044507C5044507C924492550E4A00 +9758:10401040FCFC10887D1010FCFEA400A47CA444FC7C8044807C824482447E4C00 +9759:10401040FE7810887C1011FCFE2400247DFE44247C2445FC7C24442054A04840 +975A:100011FCFF0411047DFC1104FF0401FC7D0445047DFC44507C90449255124A0E +975B:10201010FEFE10827D041000FEFE00107C1044907C9E44907C9044D0553E4A00 +975C:101E11E0FE92104C7C0010FCFE2400247DFE44247C2444FC7C24442054A04840 +975D:10801080FCFC11007EF81000FDF800487D6844C87DF8444A7CEA475A54464842 +975E:044004400440FC7E0440044004407C7C0440044004400440FC7E044004400440 +975F:044004407C7C04403C7804407C7C044000F03F0001F03F0001F87F02010200FE +9760:11001FF02100FFFE00001FF010101FF004407C7C04403C7804407C7C04400440 +9761:00803FFE24103F7C26382D543412212021203F3E21202F3C21205F3E41208120 +9762:0000FFFE0200020004003FF82448244827C82448244827C8244824483FF82008 +9763:0000FFFE0200020004003FF82008200827C82448244827C8200820083FF82008 +9764:0040FE4010FC2084FF04AAF4AA94BA94AAF4AA84BA94AA88AA82FE82827E0000 +9765:3FFC20903FFC21402630380C27F020802FF82A282BE82A284BE84A288FF80808 +9766:0000FEFC10842084FEFCAA84AA84BAFCAA84AA84BAFCAA50AA50FE528292010E +9767:0010FEFE109220FEFE10ABFEAA00BAFEAA82AAFEBA82AAFEAA82FEFE82440082 +9768:3FFE28882F8A20082FBE28882F88289429A23FFE20802FFC292449E449248FFC +9769:082008207FFC082008200FE001003FF8210821083FF80100FFFE010001000100 +976A:22002200FF7E22083E0808087F08490849087F080808FF880808080808280810 +976B:280029F8FE8828C838A810A87C88545054507C501020FE201050108811041202 +976C:2200227CFF1022103E1008107F1049FE49107F100810FF900810081008100810 +976D:22002200FF7E22123E1208527F52495249527F920812FFA20822084208940908 +976E:22202220FF20227E3E4208827F02498249427F220822FF820802080208140808 +976F:22102210FF1022103E10087C7F10491049107F100810FF90081008FE08000800 +9770:28002800FDFC2890389010907C90549054907C901090FC9210921092110E1200 +9771:28002800FDFC2844384411447CC4544454647C54104CFC861084110412281410 +9772:28202820FE202850385010887D44562254207CF81008FE081010101010201020 +9773:2204220EFF7022403E4008407F7E494849487F480848FFC80848088808880908 +9774:28502850FE502892389211947E98549054B07CD01090FE9010921092108E1080 +9775:280029F8FE482848384810487C4855F854887C881088FE881088108813FE1000 +9776:280029FCFD242924392411247D2455FC55047D001100FD001102110210FE1000 +9777:280429E4FE242824382411E47D04550455047DE41024FE241024102411441084 +9778:28002BFCFC842888388810907C9C548455447D441128FD281210122814441182 +9779:28202820FE2029FE392211227D22552255527D4A118AFF0211021102110A1104 +977A:28202820FC202BFE382010207C2055FC54707CA810A8FD241124122210201020 +977B:280028F8FE882888388810F87C88548854887CF81088FE881088108813FE1000 +977C:28002800FEFC2884388410847CFC548454847C8410FCFE841000100011FE1000 +977D:28202820FD2428A438A810207DFC542054207C2013FEFC201020102010201020 +977E:282828A8FEA828A838A813FE7CA854A854A87CA810B8FE801080108010FE1000 +977F:50105090F8905110717E2252FB92A892A912F9122252FBD220622022204A2084 +9780:280029FCFE442844384410447C94548855007CFC1084FE841084108410FC1084 +9781:28102810FE1029FE391211147D1055FC55447D441128FF281110122812441482 +9782:2808283CFDE02820382010207DFE542054707C6810A8FCA41122102010201020 +9783:280829C8FE482848384811C87D08550855107DD01054FE541052105E12821100 +9784:28402840FEFC2884390412F47C94549454F47C841094FE8810821082107E1000 +9785:28202820FE2029FC392411247D24552455247FFE1020FE501050108811041202 +9786:280029FEFC202820382011FE7D22552255527D4A118AFD0211021102110A1104 +9787:280029FCFD042924392411247DFC552455247D54114CFD8C1104110411FC1104 +9788:28202820FE502848388411027CFC540054007CFC1084FE841084108410FC1084 +9789:28502850FE50295238D410587C50545854D47D521050FE50109210921112120E +978A:28202820FC202BFE382010207DFC540054007DFC1104FD041104110411FC1104 +978B:28202820FEFC2820382010207DFE540054207C2010FCFE201020102011FE1000 +978C:01007FFC44043FF8082007C0783804407FFC044007C001001FF01110FFFE0100 +978D:28402820FC202BFE3A0214447C4057FE54887C881108FCD01020105010881304 +978E:280028FCFE84288438FC10847C8454FC54A27CA41098FE90108810A410C21080 +978F:7CF8108810CA1D2AF20608207FFC08200FE001003FF821083FF80100FFFE0100 +9790:28202820FE3E2820382011FE7C00540055FE7C201028FE241022102010201020 +9791:28102910FC902890387E10107D90549054987CA810A4FCC410801140123E1000 +9792:2808281CFEE02820382011FE7C50548855047E8A1088FE881088108810881108 +9793:280028FCFE842884388410FC7C00540055FE7C201020FEFC1020102011FE1000 +9794:28802880FCF829083A1011FC7D24552455247DFC1050FC50109010921112120E +9795:280029FEFC20282039FC11247D2455FC55247D2411FCFD2010A0104010B0130E +9796:2804281EFDE02822391210947C80542055FE7C441084FDC81030102810C41302 +9797:108011F8128820702B8E68886BFEA88828F8282029FC292429FC202023FE2020 +9798:28102892FE522854381010FE7C82548254FE7C821082FEFE10821082108A1084 +9799:280028F8FE88288838F810007DFC550455047DFC1104FF0411FC110411141108 +979A:28202810FE1029FE390212547C88550454007CFC1020FE201020102011FE1000 +979B:28202810FEFC2800388810507C0055FE54007C0010FCFE841084108410FC1084 +979C:28202822FDB428A838A811247EA2544055FC7D041104FDFC1104110411FC1104 +979D:28202924FCA428A8382011FC7D04550455747D541154FD541174110411141108 +979E:28202840FCFE2892389210FE7C9254A254FE7C481088FDFE1008100810081008 +979F:28202810FDFE280038FC10847CFC540054FC7C081010FDFE1010101010501020 +97A0:28802880FEFE29023A2210AA7C72542255FE7C221072FEAA11221022100A1004 +97A1:28902888FC8828BE3BC010827CA254E254927D921294FC941084108812BE1100 +97A2:28482948FD482BFE394811487D78550055FE7C2013FEFC7010A8112416221020 +97A3:280029FCFC4828303BFE10527C94551056307C2013FEFC7010A8112416221020 +97A4:08087F0808FEFF0808487F2808080F28F01004407FFC04401FF01110FFFE0100 +97A5:28202830FE482884397A10007CFC548454847CFC1048FE4811FE104810881108 +97A6:500850C8FB085108712A212AFBACA948A908FB882554F9142114212421242142 +97A7:28882848FC502BFE385010507DFC555455547D8C1104FDFC1104110411FC1104 +97A8:280029FCFD0429FC390411FC7C8055FE56227D221152FD0211FA100210141008 +97A9:50825082FAA251CA708A23EAFA2AAA2AABEAFA2A222AFBEA2222222222AA2244 +97AA:7E20243E1848FFA829104A28984604407FFC044007C001001FF01110FFFE0100 +97AB:28802880FCFE29023A4211FA7C0255F254027DF21002FDF2111211F210141008 +97AC:50105010F87C571471FE2114FA7CAA10AF7CF91021FEFD102210230024FE2800 +97AD:288028FEFE90297C395413547D7C555455547D7C1190FF501120113011481186 +97AE:280028FCFE84288438FC10847C8454FC54007DFE1020FEA010BC10A01160123E +97AF:28482848FDFE2848382011FE7C40544054BC7D841288FCBE1088108810A81090 +97B0:280028F8FE88288838F810887C8854F854007DFC1154FF541154115413FE1000 +97B1:281E28E0FE222892385410407C2054CE54827C8210EEFE821082108210FE1082 +97B2:50885088FBFE508871FC2088FBFEA820A9FCF92421FCF92423FE210421142108 +97B3:28882888FDFE2888382010507C88550456FA7C001000FDFC1104110411FC1104 +97B4:50885088FBFE5088708827FEF880A9FCAB24FDFC2124F9FC212421242124210C +97B5:281E2BE0FD222894384010887DF0542054C47DFE1022FC2013FE105010881306 +97B6:08783E48228E2A007EF822482A3046CC7FFC044007C001001FF01110FFFE0100 +97B7:7FFC08200FE000003FF824482FE82108211804407FFC04401FF01110FFFE0100 +97B8:280029FCFD2429FC392411FC7CA854A857FE7CA810A8FDFC102013FE10201020 +97B9:5100509EFBD2501273D42254FBD8A814ABD2F8522092F8DA2394209022902110 +97BA:28202924FCA82BFE3A0210F87C88548854F87C201020FDFC1020102013FE1000 +97BB:282029FCFD242BFE392411FC7C2055FC55247DFC1040FDFE108811D01070138C +97BC:282029FCFD2429FC382013FE7C0055FC55047DFC1104FDFC110411FC10881104 +97BD:281829E0FC402BFE388811747E52547054007DFC1104FD74115411741104110C +97BE:28882BFEFC88280039FC10A87CA857FE54A87CA811FCFC2013FE102010201020 +97BF:51245124FAAA53AE712422AAFBAEA924AFFEF9102114F914228A224A22162422 +97C0:50405020FBFE525073FE2252FBFEAA80AAFEFA8022FEFA02255625562A022006 +97C1:28002BFEFC0029FC392411FC7D2457FE54007DFC1124FDFC112411FC100013FE +97C2:288028F8FD082BFE394411927DFE5500557C7D00117CFD00117C1244127C1444 +97C3:28102A10FD7C281038FE10447F2855FE55107D7C1110FDFE1110111012FE1400 +97C4:28882BFEFCA8289039FE13207DFC552055FC7D2011FEFD0013FC10881070138E +97C5:280029FCFD0429FC390411FC7C88555455DC7C881154FDDC100011A811541254 +97C6:500050FEFC2852FE72AA20FEF810A9FEAE44FAFE2344FA7C2242223E250028FE +97C7:28202BFEFC2029FC380013FE7E5257FE55047DFC1104FDFC110411FC10881104 +97C8:284829FEFC48280039FE114A7D4A55FE54147DFE1110FD92114C114A11161222 +97C9:508853FEF888502073FE2250FBFEAA52ABFEFA8022FEFA8022FE24022AAA2004 +97CA:508853FEF88853DE725223DEFA52ABDEAA22FBFE22AAFAFA2222227222AA2224 +97CB:020002003FF00410FFFE00001FF010101FF001003FF8010021003FFC01000100 +97CC:100010007EFE2212FF1200527E5242527E9208127E12082248227E42088A0904 +97CD:102810247E242220FF7E00207E20423C7E3408547E54085448887E8809140822 +97CE:101010107E1022FEFF1000107E10427C7E1008387E38085448547E9208100810 +97CF:111009207FFC0400FFFE12102FE8C4263FF810101FF001001FF021003FF80100 +97D0:102010207C502450FE8801047EFA44007C0010F87C88108850887C8810F81088 +97D1:102011FC944455FE580011FCFD0429FC282029FC2820292029FC4820482287FE +97D2:101010927E522254FF1000FE7E8242827EFE08827E8208FE48827E82088A0884 +97D3:1020102010FCFE4411FE7C0044FC7C8444FC7C1010FCFE10109010FE10101010 +97D4:1000107C7E402278FF4000787E4043FE7EA008A47E98089048887EA408C20880 +97D5:102010107EFE2200FF7C00447E7C42007E7C08087E1008FE48107E1008500820 +97D6:100010FC7C482430FEFE00527C9445507C2010107DFE103850547C9211101010 +97D7:100011FE7D022420FEFC00207DFC45247DFC11247DFC102053FE7C2010201020 +97D8:101410547E5422FEFF5400547E5C42407E7E08107EFE081048387E5408920810 +97D9:00103E7C22243EFE22003E7C0044FF7C0810083C2F50287E281058104FFE8000 +97DA:108810887DFE2488FEF800207DFC45247D2411FC7C2013FE50207C2010201020 +97DB:104410447DFE2444FE4401FE7C4044FE7D9212FE7C9210FE50927C9210921086 +97DC:101E11E07C222512FE9400807C2045CE7D0211027DCE110251027D0211FE1102 +97DD:104810487DFE2448FEFC00487DFE44107CFC10947CFC109451FE7C8410941088 +97DE:100010F87C882488FEF800887C8844F87C0011FC7D54115451547D5413FE1000 +97DF:101010207E7C2244FF7C00447E7C42107EFE08287E540892487C7E1008100810 +97E0:100010FE7E9222FEFF9200FE7E5442547EFE08547E5408FE48107EFE08100810 +97E1:104410FE7E442200FFFE00547E5442FE7E5408547EFE081048FE7E1008100810 +97E2:101010107DFE2410FEFC00947CFC44947CFC10127DFE102250147D52114A1238 +97E3:100011FC7D542554FFFC00807DFC46447DF411547D5411F450447DF410141008 +97E4:104811FE7C482400FFFE014A7D4A45FE7C1411FE7D101192514C7D4A11161222 +97E5:101010FE7E10227CFF0000FE7EAA42FE7E44087C7E44087C48447E7C08280844 +97E6:0100010001007FFE010001003FF8010001007FFC010401040104012801100100 +97E7:2000200021FCFC24202420A4F8A420A42124FC24242424443444288421142208 +97E8:205020482048FC4021FE2040F840207C20A4FCA424A8252835102A2820442082 +97E9:102010201020FEFE10207C2044FC7C2044207DFE1022FE22102A102410201020 +97EA:00203E2022FC3E2022203EF80020FF2008FC08242F242834282858204FFE8000 +97EB:200020F82088FC8820F82088F88820F82000FDFC255425543554295423FE2000 +97EC:201E21E02022FD1220942080F82021CE2102FD0225CE25023502290221FE2102 +97ED:044004407C7C0440044004407C7C0440044004407C7C044004400440FFFE0000 +97EE:08200820FFFE0820082004407C7C044004407C7C044004407C7C04400440FFFE +97EF:082008287F240820FFFE0020122473A4122473A812287390121217AAF8464082 +97F0:08000F7C28447F28A110162838C6C2807EFC02803EF802807EFC0280FFFE0000 +97F1:112011282AA444640020FFFE122073A4122473A812287390121217AAF8464082 +97F2:0100FFFE02847D78255025484D6402807EFC02803EF802807EFC0280FFFE0000 +97F3:020001003FF8000008200440FFFE00001FF0101010101FF0101010101FF01010 +97F4:200013FE7C200020442029FCFF2401247D24452445247D34452844207C204420 +97F5:204010407C8000FC45042A04FE8400447C44441444247C44458444047C284410 +97F6:200011FC7C44004444442844FE9400887D0044FC44847C84448444847CFC4484 +97F7:201010107C92009244922892FEFE00107C10449244927C92449244927CFE4402 +97F8:204010407CFC008845502820FED803267CF8442044F87C2047FE44207C204420 +97F9:202010407CFC008444FC2884FEFC00007DFE442044207CFC442044207DFE4400 +97FA:208810887DFC008844A82820FEF800A87CA844A844A87DFC442044507C884504 +97FB:2000107C7C440044447C2800FEFE00827CFE448244FE7C8244FE44287C444482 +97FC:20201220797C00A4481830E6FB10017E7910497C491079FE491049107AFE4C00 +97FD:1020281044FE92007C440828FEFE2800FE7CAA44CE44827CFE448244FE7C8244 +97FE:08007F7808483E4800863E782A483E30414EBFFC0440FFFE10101FF010101FF0 +97FF:110023DE7A5213D42A527BDA1294235001003FF80440FFFE10101FF010101FF0 +9800:204411FE7C54004844FE2990FEFE00907CFE449044FE7C8045FE44447C3845C6 +9801:00007FFE020004001FF8100810081FF810081FF8100810081FF8081010082004 +9802:000001FEFE20104011FC1104110411FC110411FC1104110411FC108851042202 +9803:000021FE2020204021FC3D04210421FC210425FC2904310421FC008801040202 +9804:200020FE20102020FCFC2484248424FC248424FC2584268444FC404880840102 +9805:000001FE0020FC4011FC1104110411FC110411FC11041D04E1FC408801040202 +9806:040045FE5420544055FC5504550455FC550455FC5504550455FC548885040602 +9807:00007CFE1010102010FC10841084FEFC108410FC1084108410FC104810841102 +9808:080009FE1020204041FC8904090411FC210445FC8504090411FC208841048202 +9809:080009FE0810082048FC4E84488448FC488448FC48844E8458FCE04800840102 +980A:000001FE7C20104011FC11047D0411FC110411FC11041D04E1FC408801040202 +980B:00007EFE401040205EFC5284528452FC5A8454FC5084528454FC584850848102 +980C:000028FE2410242042FC5284908410FC208420FC48844484FCFC444800840102 +980D:100011FE1020FE4011FC1104FD0405FC050449FC2904110429FC448881040202 +980E:08001DFE6020404041FC41047F0449FC490449FC4904490449FC488889040A02 +980F:100008FE0810FF2000FC00843C8424FC248424FC2484258446FC444880840102 +9810:00007CFE0410282010FC0884FE8412FC148410FC1084108410FC104850842102 +9811:00007CFE0010002000FCFE84288428FC288428FC28842A844CFC484880840102 +9812:000028FE2410242042FC428480847CFC248424FC2484248444FC444894840902 +9813:100011FE1020FE4011FC5504550455FC55047DFC1104110415FC188811040202 +9814:100011FE10207C4055FC5504550455FC7D0455FC5504550455FC7C8845040202 +9815:100010FE10101E2010FC1084108410FC7E8442FC4284428442FC7E4842840102 +9816:100011FE9420584011FC7D04110411FCFF0411FC1104110421FC208841048202 +9817:080008FE08107F20497C4A4448447F7C4144527C4A4444444A7C910021280044 +9818:100011FE2820244043FC9104090401FCFD0405FC0904510421FC108811040202 +9819:000001FEFC20104011FC110451045DFC510451FC510451045DFCF08801040202 +981A:00007CFE0410682010FC2884448492FC10847CFC108410841EFCF04840840102 +981B:100010FE1010FE2010FC7C841084FEFC308438FC5484548490FC104810841102 +981C:100011FE2820244043FC81047D0401FC01047DFC4504450445FC7C8845040202 +981D:200010FE0010FE2000FC2884448482FC048444FC2884108428FC444884840102 +981E:100008FE7E10422094FC10841084FEFC248424FC4884288410FC284844848102 +981F:200020FE3C104420C4FC2884108428FC448482FC7C84448444FC44487C844502 +9820:1000107E3F102120427CBFC420442F7C2944297C2D442A44287C4A004C288844 +9821:100010FE1010FE2010FC10847C8400FC00847CFC4484448444FC7C4844840102 +9822:08001DFE7020104011FCFD04110411FC7D0445FC4504450445FC7C8845040202 +9823:00007EFE4810482048FC7E84428442FC7E8448FC4884488448FC7E4800840102 +9824:00007DFE4820484049FC5D04550455FC55045DFC4904490449FC7E8801040202 +9825:40005F7E54105420547C5F445144517C51445F7C54445444547C54005F284044 +9826:100008FE0810FF2008FC108422847CFC098412FC2484C88414FC2248C0840102 +9827:080011FE7C20444045FC45047D0441FC41047DFC4504450445FC7C8845040202 +9828:0000EEFE22102220AAFC6684228422FC26846AFCB284228422FC2248AA844502 +9829:420024FE00107E2024FC2484248424FCFF8424FC2484248424FC444844848502 +982A:080008FE4A102A202CFC0884FE8418FC1C842AFC2A84488488FC084808840902 +982B:280028FE28102820AAFC6C84288428FC6C84AAFC288428842AFC4C4848848102 +982C:080008FE08107E2008FC4A842A842CFC0884FEFC0884148412FC224840848102 +982D:0000FEFE002000407CFC4484448444FC7C8400FC448428842EFCF00040480084 +982E:0800097EEA102C204A7C4944A844107C2444247CFF442444247C440044288444 +982F:100010FE3E10622094FC48843084C0FC248424FCFF84248424FC444844848502 +9830:080008FE0810FFA0087C2A442A442A7C5D4488FC08441444127C210041288044 +9831:04001EFEE010222092FC5484408404FCFF8404FC4484248424FC044814840902 +9832:000001BE76081210123E222227A2723E1222523E522227A2203E50008F940022 +9833:100010FE10107C2010FC1084FE8428FC28846CFCAA84288428FC484848849902 +9834:40004CFE7010422042FC3E8400847CFC0084FEFC1084548452FC924850842102 +9835:00007EFE12101220FF7C124412447E7C2044207C7E446244A27C22003E282244 +9836:080028FE28103E2048FC0884FF8400FC00843EFC2284228422FC3E4822840102 +9837:080008FE1410222051FC88847E8402FC048408FC7E84428442FC7E4842840102 +9838:0000FEFE54105420A8FC5484548400FCFE8410FC108410841EFCF04840840102 +9839:0C0070FE1010FE2010FC3884548492FC008428FC288428842AFC4C4848848102 +983A:0C0070FE1010FE2010FC3884548492FC7C8424FC28842E8422FC42484A848502 +983B:080008FE28102E2028FC2884FF8400FC08842AFC2A844C8484FC08483084C102 +983C:100010FEFE10102010FCFE84928492FCFE8410FC3884548492FC104810841102 +983D:0C0070FE1010FE2010FC3884548492FC008438FC288428842AFC4C4848848102 +983E:0BFE104061FC090411FC610405FC090431FCC088090428802E9828E22E82F07E +983F:060018FE62100C20737C0C44F444147C55445E7C54445544557C5D00F3280044 +9840:140012FE20103F20647CA4443F44247C24443F7C24442444247C3F0020282044 +9841:1000087E7F104120827C00447F44087C0844287C2E442844287C58004F288044 +9842:100010FE1010FE2010FC5484548454FCBA8410FC3884548492FC104810841102 +9843:100052FE5410902028FC4484828410FC108452FC5484908428FC244842848102 +9844:00007F7E02100420497C6B445D44497C5D446B7C49446944517C470079280044 +9845:100008FE7E10422042FC7E8440845EFC52845EFC52845E8452FC524892841702 +9846:00007F7E491049207F7C494449447F7C0844FF7C1C442A44497C880008280844 +9847:100008FE00107F20007C22442244557C88C4087CFF440844087C080008280844 +9848:40004CFE7010422042FC3E84208444FC788410FC2484FE8410FC544892843102 +9849:100010FE2810242042FCBC84108410FCFE8410FC9484588450FC1E48F0844102 +984A:100020FE7E1042207EFC40847E8442FC7E8410FC1084FE8410FC104810841102 +984B:00007F7E491049207F7C494449447F7C0844047C154450C450FC52808E280044 +984C:00003EFE22103E20227C3E44007CFF44087C08442F7C2828284458824FFE8000 +984D:200010FEFE10822020FC3C844484A8FC108428FC4484FE8444FC44487C844502 +984E:0000EEFEAA10AA20EEFC00847C8400FCFE8420FC40847C8404FC044828841102 +984F:100008FE7F1022201CFC22847F8444FC488472FC4484488471FC42488C847102 +9850:0000FEFE92101020FEFC10847C8454FC7C8454FC7C841084FEFC104810841102 +9851:020002BE02087F90423E42225E2242BE42A25EBE56A255225D7E414042D48462 +9852:00007CFE541054207CFC548454847CFC1084FEFC92849684BEFC82488A848502 +9853:100092FE92109220FEFC0084FE8410FC2084FEFCAA84AA84AAFCAA48AA848702 +9854:100008FE7F102220147C7F444444487C5244447C48445144427C440088283044 +9855:00007CFE441044207CFC448444847CFC288428FCAA846C8428FC2E48F0844102 +9856:0800107E7F104120557C49445544417C7F44087C054454C450FC92000E280044 +9857:0800497E49107F20007CFF4400447F7C4144417C7F444244247C0F00F0284044 +9858:00007F7E441048205F7C51445F44517C5F44447C56445544657C450094280844 +9859:00007EFE22101C20227C77445544227C5544087C7F441C442A7C490088280844 +985A:4600787E40903FA0007C5F4451445F7C51445F7C51445F44407C7F8022284144 +985B:100010FEFE1010207CFC44847C8444FC7C8444FC7C844484FEFC284844848302 +985C:2200223EFF8822107F3E2222FFA2083E7F22493E7F224922FFBE410045144222 +985D:00007CFE4410742054FCFE8482847CFC44847CFC44847C8444FC444854844902 +985E:100092FE5410FE2030FC5484928400FC148412FCFE84108428FC244844848102 +985F:0000777E11105520337C55440C44337CC4C4187C62440CC4717C06001828E044 +9860:0000FEFE2810FE20AAFCAA84FE8400FC7C8400FCFE84108454FC924850842102 +9861:100008FE7F102220147CFF441044297CCE44147C2644CD44157C2400D4280844 +9862:2200223EFF882210223E3E220822FFBE88A2CCBEAAA2DDA288BE88808A948922 +9863:0200029E02047FC8421E4A124E124A9E7E924A9E4A925D126B5E49405ACC8452 +9864:100010FE7C101020FEFC4484EE8444FC6484DEFC0084FE8428FC2A484C848902 +9865:00007CFE44107C2044FC7C841084FEFC00847CFC44847C8410FC544892843102 +9866:280024FE7E10C82048FC7E84488448FC7E8448FC48847E8440FCAA48AA840102 +9867:100008FE7F104120417C7F445444527C7F44547C5F4454445F7C54009F281044 +9868:FEFE10207EFC42847EFC42847EFC42847EFC244842840000FFFE082010202020 +9869:080008FE14102220417CBE440044007C7744557C55447744227C220055288844 +986A:040027BE2408FFD0023E02A27FE2423E7E224ABE4AA25AA26D3E894012D46462 +986B:1000FEFE0010FE2082FCBA84AA84FEFC00847CFC44847C8444FC7C480084FF02 +986C:00007F3E0808FF9088BE6B2208226B3E0022FFBE08227F22553E550055144322 +986D:2200FFBE22087F10553E55227F22003EFFA290BE3E222222523E0C001814E022 +986E:1000087EFF9080A07F7C524494447F7CC1447F7C41447F44417C7F0022284144 +986F:0000FEFE8210FE2082FCFE844484AAFCEE8444FCAA84EE8400FCAA48AA840102 +9870:087E2E10287EFF422A7E4C42327EC4243FFA21083FF822083FF80880FFFE0080 +9871:08000FBE08087F9048BE7E2248A25FBE55225F3E55225F22403EBF802A947FE2 +9872:29004A7E14106220097C2A445444227C4844FF7C00447F44417C5D0055287F44 +9873:7F80213E3F0821103F3E21E2FF22013EFFE252BE73A252A273BE5AC0F79410A2 +9874:2200227EFF902220777C55447744127C3F44647CBF4424443F7C24003F282044 +9875:00007FFC020004001FF010101110111011101110111012900240042018106008 +9876:000001FEFE20104011FC11041124112411241124112411441050508821040202 +9877:000021FE2020204021FC3D042124212421242524292431442050008801040202 +9878:000079FE1020104011FC11041124FD2411241124112411441050108811041202 +9879:000001FE0020FC4011FC1104112411241124112411241D44E050408801040202 +987A:040045FE5420544055FC55045524552455245524552455445450548885040602 +987B:080009FE1020204041FC89040924112421244524852409441050208841048202 +987C:000001FE7C20104011FC11047D2411241124112411241D44E050408801040202 +987D:00007CFE0020004000FCFE84289428942894289428942AA44C30484880840302 +987E:00007EFE402040405EFC5284529452945A945494509452A45430584850848302 +987F:100011FE1020FE4011FC55045524552455247D24112411441450188811040202 +9880:08001CFE6020404040FC40847E94489448944894489448A44830484888840B02 +9881:000029FE2820244045FC450481247D2425242524252425442450448855048A02 +9882:000028FE2420244042FC52849094109420942094489444A4FC30444800840302 +9883:100008FE0820FF4000FC00843C94249424942494249425A44630444880840302 +9884:0000F9FE0820504021FC1104FD242524292421242124214420502088A1044202 +9885:100010FE1E20104010FC7C844494449444947C94449440A44030404880840302 +9886:100011FE2820244043FC910409240124FD240524092451442050108811040202 +9887:080008FE08107F20497C4A4448547F54415452544A5444544A28912421420082 +9888:00007EFE04100820187C24444254815400547E540854085408280E24F0424082 +9889:100010FE1020FE4010FC10847C94009400947C94449444A444307C4844840302 +988A:080008FE08207E4008FC4A842A942C940894FE94089414A41230224840848302 +988B:0000037EEC102420247C44444F54E4542454A454A4544F544020A0281F440082 +988C:100010FE2820244042FC80847C94009400947C94449444A444307C4844840302 +988D:200024FE3820224022FC1E84009408940A94EC9428942CA44A304A48A8841302 +988E:400044FE7820424042FC3E840094109452945294549490A42830244844848302 +988F:100008FE0820FF4008FC108422947C94099412942494C8A414302248C0840302 +9890:00007DFE4820484049FC5D045524552455245D244924494448507E8801040202 +9891:100011FE50205C4051FC5104FF2401241124552455245544845008883104C202 +9892:080009FEEA102C204A7C4944A854105424542454FF5424542428442444428482 +9893:0C0071FE1020FE4011FC39045524932401243924292429442A504C8849048202 +9894:080008FE14102220517C88447E540254045408547E54425442287E2442420082 +9895:40004CFE7020424042FC3E8400947C940094FE94109454A45230924850842302 +9896:40004DFE7020444045FC3D0401240D2471241124FF2411443850548891041202 +9897:00007F7E491049207F7C494449547F540854FF541C542A544920882808440882 +9898:00003EFE22103E20227C3E440054FF54085408542F282844288258004FFE8000 +9899:00003EFE2A102A203E7C2A442A543E5408547F5449544B545F28412445424282 +989A:0000EEFEAA10AA20EE7C0044FE540054FF5440547E5402540228022414420882 +989B:0800497E491049207F7C0044FFD4085410547F54555455545520552855444382 +989C:100008FE7F102220147C7F444454485452544454485451544228442488423082 +989D:100008FE7F104120107C1E44225454540854145422547F54A22822243E422282 +989E:00007F7E22103E20227C3E4423D4FE540254F754115455542220552889441082 +989F:240024FEFF102420007CFF4424542454FF54A554A554DB549128812485428282 +98A0:080008FE7F1008203E7C22443E5422543E5422543E5422547F28142422424182 +98A1:00007EFE22101C20227C774455542254555408547F541C542A28492488420882 +98A2:00007F7E41107F20417C7F440854FFD400547F5441547F540820492888C41882 +98A3:920054FEFE103020547C924420544454785410542454FE541028542492423082 +98A4:0800FF7E0010FF20817CBD44A554FF5400547E5442547E5442207E280044FE82 +98A5:00007F7E0810FFA088FC6B4408546B540054FFD408547F545520552855444382 +98A6:08002EFE2820FF7C2A544C543228C4443FF821083FF822083FF80880FFFE0080 +98A7:2200227EFF902220777C5544775412543F546454BF5424543F2024283F442082 +98A8:00003FF8200820E82F0821082FE8292829282FE82908214A21EA5E2A48068002 +98A9:00027FC2404443485C5244425F44554855505F42444445485F504922801E0000 +98AA:00007FFC01000160011001001FF010D01710111017D0155027CA212A4FE68022 +98AB:00087FC84048435C5C4844485F7E554855485F54445245625F404922801E0000 +98AC:00007FDE404443545C5444645F7E5544554C5F54446445545F484922801E0000 +98AD:00087FC84048434E5C4844485F48555C55545F544454455C5F544922801E0000 +98AE:00407F40417C4D84717451547D5455747D48514255427D3E44804042803E0000 +98AF:80004FF848080868EB880888A888ABE8AAA8AAA84BE8388AC8AA10EA17262002 +98B0:00087FCA4048437E5C4844505F5E5552556A5F44444A45525F404922801E0000 +98B1:00087FC8404843525C5E44425F40555E55525F52445E45525F404922801E0000 +98B2:00027DF244824C8A748A55EA552A7D2A56AA7C4A544A5482530A7D044482807E +98B3:00047FD8404843485C7E44485F48555C55545F544454455C5F404922801E0000 +98B4:00207F20413E4D407180517E7D1255507D5C515055507DBE44804042803E0000 +98B5:00107F5441384D10717C51447D7C55447D7C514455447D4C44804042803E0000 +98B6:00007F7C41444D7C7144517C7D44557C7D4451FE55007D2844C44042803E0000 +98B7:00107F5241944D28714451847D1055127D5451A855247D4444804042803E0000 +98B8:00007F7C41544D7C7154517C7D0055247D12516055A47D1C44804042803E0000 +98B9:00107F7C41244DFE7100517C7D44557C7D10513C55507D7E44904052803E0000 +98BA:007C7F44417C4D44717C51007DFE55407D7E51AA55527D2A44844042803E0000 +98BB:0E00F1FC2304933445C421443DF451541154FFF41144555455F45D1662060402 +98BC:00A07D2C45244DAC752455FC54207DFC54047CC85430544853847D004482807E +98BD:100055FC550455347DC401447DF401547D5445F47D44455429F41D16E2064402 +98BE:00007DF844A84C887450542054D87F2654F87CA854F8542453FC7D044482807E +98BF:00007DFC51047D3451C47D4451F451547D5405F45544555455F4851616060C02 +98C0:00407DBC45144D5475A4552C54407DFC55247DFC552455FC52007D004482807E +98C1:0000FDFC2504B5346DC4B54425F411547D5445F445447D5445F445167E064402 +98C2:00007DDC44444D5474CC555454207C5054A87D5454A0544852907D2044C2807E +98C3:00007DFC44504DFC755455FC54007CF854007DFC54A8552452607D004482807E +98C4:0000FEF82888FE98AAE8AAA8FEF800A87CF800A8FEA810BA54CA928A51062202 +98C5:00007DFE44504DDC755455DC54507DFC55247DFC552455FC52007D004482807E +98C6:140011FCFF04293445C4834425F437542554FFF4254455544BF4891612060402 +98C7:00287C2045FC4C507488550454487C6C54487DFE544854A852947D1244A2807E +98C8:00207CA444A44D287450548855047C8856AA7DDC5488555452227D004482807E +98C9:00207C2045FC4D54748855FC568A7CF854887CF854A8552452607D004482807E +98CA:08002AF82C88489814E822A841F824A82DF8B6A864A824BA54CA4A8A91060202 +98CB:00007DDE44844DCE748455DE54207C1854487CD45562544853B87D004482807E +98CC:4400FEF844880098EEE8AAA8EEF824A87EF8C8A87EA848BA7ECA488A7F064202 +98CD:1FF010D01710111017D0155027CA212A4FE680227CF854A87CF854AA7DFE8202 +98CE:00003FF02010201028502450229022902110211022902292244A484A40068002 +98CF:00007DF84410442044C04DFC6C545494552454446C8445284410420241FE8000 +98D0:00103F10211E21102510357C294429442944297C3544250020824062401E8000 +98D1:00407C4044FC450446F44C946CF454845494548A6C82447E4400420241FE8000 +98D2:200013F81208FE0803280AA88AA88A484A484AA852A8532A1C0AE40A48061002 +98D3:00007CF8448844F844884CF86C8854F8548855FC6C0044504488420241FE8000 +98D4:00007DFC452445FC45244DFC6C205414555255426E4844384400420241FE8000 +98D5:00A07D2C452445AC45244DFC6C2055FC540454C86C3044484584420241FE8000 +98D6:0E00F0F822889288448820983CD850A810A8FEA810D8548A548A5D0A65060202 +98D7:00407DBC4514455445A44D2C6C4055FC552455FC6D2445FC4400420241FE8000 +98D8:0000FEF82888FE88AA88AA98FED800A87CA800A8FED8108A548A930A51062202 +98D9:000014F81088FE882888449882D824A836A824A8FFD8248A548A4B0A89061202 +98DA:00207CA444A4452844504C886D04548856AA55DC6C8845544622420241FE8000 +98DB:00007FE000240A28722412201212120AFFC6124812501248224022244214820C +98DC:08001DFAF00C544A3988FEAA34A652A281F87CAA54AC54AA7CA854AA54A67D22 +98DD:00047FE808247212120EFFD0122A221EFDF82448D5AA56ACFDFA54A855AA9326 +98DE:0000FFC000400044004800500060005000480044002000200012000A00060002 +98DF:0100028004400A203118DFF610101FF010101FF0100811901060121014081804 +98E0:080008001400120029007E00A2003E0022003E002000280024002A0032002000 +98E1:0040404020A0211002880C460BF8120813F8E20823F822442228229023080204 +98E2:080008781448124829487E48A2483E4822483E482048284A244A2A8A32862100 +98E3:0800080014FE121029107E10A2103E1022103E102010281024102A1032502020 +98E4:082008201420122029207E20A2203E2022503E502050285024482A8832842102 +98E5:0808081C14E0122029207E20A2203E3E22E03E202020282224222A22321E2000 +98E6:0800087C1410121029107E10A2103EFE22103E102010281024102A1032102010 +98E7:2020202020503C4824A445FA4688A4F8148808F808A21094108820A440C48080 +98E8:102010201050244824A479FA0A8810F824887CF804A20894088810A420C44080 +98E9:10201020282025FC5220FCA844A87CA844A87CA840F8502248225422641E4000 +98EA:08000808141C127029107E10A2103E1022FE3E102010281024102A10327C2000 +98EB:1008103C29E024205220FC2045FE7C2044207C50405050504888548865044202 +98EC:0100111009203FF802007FFC082011102FE8C8260FE008200FE808D00A300C08 +98ED:10401040284024FE5280FD2044207DFC44247C24404450444844548464A84110 +98EE:082008201420127E28424484BE1022103E1022103E2820283E4820443E842102 +98EF:1004100E28F024805280FCFC44A47CA444A47CA840A850904910552866444082 +98F0:082008101410120029FE7E20A2203E3022283E282024282424202A2032202020 +98F1:00200020FC50208821443E2245FC450465FC950409FC09221114214841848102 +98F2:104010402840247C5284FC8845207C2044207C50405050504888548865044202 +98F3:10201010280024FE5210FC1044107C1044FE7C10401050104810541065FE4000 +98F4:10201020282024405248FC8445FE7C8244007CFC408450844884548464FC4084 +98F5:084008401440127E29A07EA0A3203E3C22203E202020283E24202A2032202020 +98F6:10401020282824085208FC4844547D5245527D604260504448C45544663C4000 +98F7:0800087C1444124429447E7CA2443E4422443E7C2044284424442A4432FE2000 +98F8:00207C204450444844A47DFA0288FEF8208840F87CA20494048804A428C41080 +98F9:100010802B1E26525252FA524A527A524A527AD2435A52544890589069104210 +98FA:088028882EF028842E84F17C02800D603FF8C8260FE008200FE808D00A300C08 +98FB:10201020285024885304FE1244207C4045887C10402050444988541064604380 +98FC:080008FE1402120229FA7E02A2023EFA228A3E8A20FA288A24022A0232142008 +98FD:0840084014FC128429047EF4A2943E9422F43E842094288824822A82327E2000 +98FE:10801080288024FE5320FE2044207DFC45247D24412451244934552864204020 +98FF:081008101492129229927E92A2FE3E1022103E922092289224922A9232FE2002 +9900:1088108829FE24885288FC0045047D0444887C88405050204850548865044202 +9901:10401044284E24B85288FD8846887C8844FE7C88408850884888548864BE4080 +9902:1008103C29E024205220FDFE44207C2044207DFC410451044904550465FC4104 +9903:10401020282025FE5200FC8845047E0244887C88405050504820545064884306 +9904:081008101428122829447E82A27C3E0022003E7C2044284424442A44327C2044 +9905:08840848140012FC29487E48A2483E4823FE3E482048284824482A8832882108 +9906:105010502850255252D4FC5844507C5844D47D5240505050489254926512420E +9907:080008FE1482128229BA7E82A2823EBA22AA3EAA20AA28BA24822A82328A2084 +9908:410021FC0A441440E0B0210822842D603FF8C8260FE008200FE808D00A300C08 +9909:08100810142012FE29827E82A2BA3EAA22AA3EAA20AA28BA24822A82328A2084 +990A:082004407FFC01003FF80400FFFE11102FE8C8260FE008200FE808D00A300C08 +990B:111009207FFC0400FFFE111022C8CD363FE8C8240FE008200FE808D00A300C08 +990C:080008FE1444124429447E7CA2443E44227C3E442044284E24F42A0432042004 +990D:00003FFE21083FFC2410288833642C9837F6241027F0241027F4446845188604 +990E:084008401478128829507E20A2503E8823063EF82088288824882A8832F82088 +990F:10401020282025FE5240FC4044A07CA245A47E9844905088488854A464C24080 +9910:08000F7828087F28A11017283AC4CD603FF8C8260FE008200FE808D00A300C08 +9911:1020102029FE24205220FDFE45027E0444F87C10402051FE4820542064A04040 +9912:1004101E29E024225312FC9444807C2045FE7C44408451C84830542864C44302 +9913:101010D82B9424945090FBFE48907894489478D84398509048AA58CA6A864102 +9914:102810242BFE24205220FDFC45247D2445FC7D24412451FC492455246524410C +9915:081008101420124429FE7E28A2443EA2223C3E44204428A824102A2832442082 +9916:100011FE2800240052FCFC8444847C8444FC7C00408450444848540065FE4000 +9917:102010202BFE24205220FDFC45247D2445FC7C20407050A84924562264204020 +9918:081008101428122829447EBAA2103E1022FE3E102058285424922B1232502020 +9919:10C21034281824645382FC2045FE7C5044907DFE42925092489A549464104010 +991A:11841068283024C85324FC2047FE7C4044FC7D8442FC508448FC548464944088 +991B:100011FC2904250453FCFD0445047DFC44007D1241D45118491055526592410E +991C:100011FC2924252453FCFD2445247DFC44207DFE407050A84924562264204020 +991D:1084108429FE248452A4FC1045FE7C4044407C7C404450444844548464944108 +991E:10481044285E25E05228FC12446A7D9644487C5E41E0502448285412646A4186 +991F:100013DE2842254A5084F94A4A527C2048007BDE40525152489459486A544422 +9920:10441044288825DC5288FC8844887C8845DE7C88408850884888548864884108 +9921:10401040287C24845308FE0044207DCE45027D0241CE51024902550265FE4102 +9922:08200810147C120029447E24A2283EFE22003E00207C284424442A44327C2044 +9923:102010202BFE24505288FD2446227DFC45247DFC412451FC48225422641E4000 +9924:102010A228A225245250FC8847047C2244207CA440A451284850548865044202 +9925:04407C7C04403C7804407D7C06C00D603FF8C8260FE008200FE808D00A300C08 +9926:100010FC288024F85280FCF844807FFE45407D24412851104908554465824100 +9927:103810E0282025FC5270FCA845247C2044407DFE404850884850542064504188 +9928:0820081014FE128229047E7CA2443E44227C3E402040287E24422A42327E2042 +9929:082008201450128829267E10A3FE3E2022443EF82012286425882A1832642182 +992A:100013FE2820244053FCFD5445547D5445547D2C402053FE4850548865044202 +992B:100013FE2A22242053FEFC2045FC7D2445FC7D2441FC50204BFE542064204020 +992C:1080109E289225D25292FC9E44927DD245527D5E4152515249D25422642A4044 +992D:1020104028FC248452FCFC8444FC7C0045FE7C20402050FC4820542065FE4000 +992E:7F2010501E882346549009241048619006601FF8E8160FF008100FF408680C1C +992F:1040107C288424F85208FDFE44407CA445387C58409451344854549265504020 +9930:1080108E2920261054C0F8AE49047B144D247964412451244924590469144108 +9931:108010BC2884250851FEFB204D20797C4990791041FE51104928592869444182 +9932:080008FC148412FC29847EFCA2403EFE23123E9220AA288224FA2A0232142008 +9933:0800087C1444127C29447E7CA2003EFE22403E7E20AA292A244A2A92322A2044 +9934:102010202BFE245050A8F9244AFA782048A8788843FE50884888588869084208 +9935:100010FC28A424A452FCFCA444A47CFC44007DFE40905094488854A864C44082 +9936:100010FC288424F45294FDFE45027CFC44847CFC408450FC4884548464944088 +9937:0810081014FE123829547E92A2003E7C22443E7C2044287C24442A0032FE2000 +9938:102210122914248052BEFC0844087DBE44887C884094509248A25540663E4000 +9939:0820081014FE129029BC7E94A2FE3E9422BC3E9020BC28A424A42AA432BC2124 +993A:102810242BFE242053FCFD2445FC7D2445FC7D24400853FE4888544864484018 +993B:084408241428120029FE7E10A2103E7C22103E1020FE280024AA2AAA32AA2000 +993C:1080108028FC250052F8FC0045F87C4845687CC841F8504A48EA555A64464042 +993D:1020104029FC25245324FDFC45247D4445FC7C4040B050A4493C55226622441E +993E:104013BE2A1226925252FAAA4B2478404BFE7A22422253FE4A225A226BFE4202 +993F:10A0112C2924252453ACFD2445247DFC44207DFC408850504820545064884306 +9940:101E11E0282225125294FC8044207DCE45027D0241CE51024902550265FE4102 +9941:1020102028FC24205220FDFE44407C8445FE7C0241FC51544954555467FE4000 +9942:100010F82888248852F8FC8844887CF844007DFC415451544954555467FE4000 +9943:108810882BFE24885200FDFC45047DFC45047DFC402053FE4850548865044202 +9944:1020112428A827FE5202FCF844887C8844F87C20402051FC4820542067FE4000 +9945:087C0844147C1244297C7E00A2FE3EAA22FE3E0020FC284424282A1032682186 +9946:100011FC292425FC5324FDFC44A87CA847FE7CA840A851FC482057FE64204020 +9947:100013FE2A00267C5244FA444A7C7A004AEE7AAA42AA52AA4AEE5A006BFE4000 +9948:1084104829FE241052FCFC2045FE7C40447C7CA4412450FC4844544465FE4000 +9949:108810882BFE248852F8FC2045FC7D2445FC7C2043FE502049FC542067FE4000 +994A:114811482BE82550515EFBE448147BD44A547BD4425453C84A485A546A5442E2 +994B:102011FC292425FC5220FFFE44007DFC45047DFC410451FC490455FC64884104 +994C:100013DE2A5227DE5210FA5249CE780048887BFE408850884BFE588869044202 +994D:108810502BFE242051FCF8204BFE792448A87BFE400051FC4904590469FC4104 +994E:102013FE282025FC5200FDFC45047DFC44887FFE400051FC4904550465FC4104 +994F:3C20043EFF4422A83E1023287E44038006601FF8E8160FF008100FF408680C1C +9950:102013FE282025FC5000FBFE4A0279FC480079FC410451FC490458886BFE4000 +9951:112411242AAA27AE5124FAAA4BAE79244FFE7910411451144A8A5A4A6A164422 +9952:1020102029FC242053FEF9084B9C790849887E3E400053FE489058906912420E +9953:1020112428A827FE5202FCF844887C8844F87C2043FE507048A8552466224020 +9954:0100FFFE10A025FE7B2015FC792011FEE6601FF8E8160FF008100FF408680C1C +9955:7C1C4410FEFE20927CF8049428BC11AA06661FF8E8160FF008100FF408680C1C +9956:1020113C292027FE5010F8144BFE7A104BF07A54425452D44B68544A68964322 +9957:110023DE7A5213D42A527BDA129423D006601FF8E8160FF008100FF408680C1C +9958:101011FE280025FE5302FD7A454A7DFE44007CFC408450FC488454FC640041FE +9959:102011FC2820248853FEFC8845FC7D0445FC7D0441FC510449FC548865044202 +995A:108813FE2888242053FCFC2047FE7C4044887DFC400051FC4954555467FE4000 +995B:108813FE288827FE5202F9FC48007BFE484078A2435450B84B5458926B504020 +995C:3FFE28882F8A20082FBE28882F8828D429A223F826162BF0221043F44268831C +995D:104010202BFE264853FEFA484AEC7B5A4A487BFE4220527C4AC45344647C4844 +995E:11F012102BFC260453FCFA244BB87A2249FE7A1047FC52444BFC58D0694A423E +995F:102013FE280025DC5154F9DC48887BFE48887BFE408853FE489459886AA440C2 +9960:100013FE2A52265253FEF90849547A5E4FB4791E425457DE48145554655E4010 +9961:152817BE294827BE5318FDAA49467BFC4A047BFC420453FC4A045BFC69084204 +9962:104017FC2A4827F85040FFFE4AAA7BB849107BFC411057FE492853106D484186 +9963:2000200020003E00440048008000100010001000100012001400180010000000 +9964:2000200020FE3E10441048108010101010101010101012101410181010500020 +9965:200021F021103D1045104910A1102110211021102110211229123212220E0400 +9966:2010207823C03C40444048408040207E27C020402040244228423042203E0000 +9967:200021F820103C2044404880A1FE209220922092211221222A22344220940108 +9968:2040204020403BFC4840524882482248224823F82048204028423042203E0000 +9969:2080208020FC3D00460048F88000200021F8200820082408280A300A20060002 +996A:2008203C21E03C2044204820802023FE20202020202024202820302021FC0000 +996B:2008203C21E03C204420482083FE202020202050205024502888308821040202 +996C:20802080210039FE4A005440804023FC20442044208420842904310422280410 +996D:2008201C21E03D00450049FCA144214421442128212821102910322822440482 +996E:2040204020403E7C448448888120102010201050105012501488188811040202 +996F:2050204820403C5C45E04840A05E23E020442048203020222852308A23060002 +9970:2080208020803CFE45204A20802021FC21242124212425242934312820200020 +9971:2080208021FC39044A0455F481142114211421F4210421282912310220FE0000 +9972:200023FC20043C0447F44804A00423E422242224222423E42804300420140008 +9973:2020202021243D244524492481FC202020202124212425242924312421FC0004 +9974:2020202020403C8845044BFE8002200021FC2104210425042904310421FC0104 +9975:200023FE21083D08450849F8A108210821F821082108211E2BE8300820080008 +9976:2080208020BC3BC04850502480D4230C200027FE2090209029123112220E0400 +9977:2040204020803BFC4A04520482F4229422942294229422F42A04320422140208 +9978:2020202020503C8845044A0281FC2000200021FC210425042904310421FC0104 +9979:2080208020F839084B1054A0804020A02118220625F821082908310821F80108 +997A:2040202020203DFE44004888A104220220882088205020502820305020880306 +997B:2040202020203BFE4840504080A020A221A4229824902088288430A220C00080 +997C:21042084208838004BFE508880882088208827FE208820882908310822080408 +997D:2020202023FE3C2044204BFEA202240421F82010202023FE2820302020A00040 +997E:200023FC20003C0045F849088108210821F82000210824882890300027FE0000 +997F:201020D823943C9444904BFEA0902094209420D82398209028AA30CA22860102 +9980:2020202020503C8845044AFAA020202023FE2020212821242A22342220A00040 +9981:2008203C23C038444A2451288100204023FE2088210823902860305021880604 +9982:2040204020883D0447FE4802A0882144224220F8218822502820305021880606 +9983:200021FC21243D2445FC4924812421FC202023FE207024A82924322220200020 +9984:200021FC21043D0445FC4904A10421FC2000211221D42118291031522192010E +9985:2080208020F839084A1054008040239C22042204239C22042A04320423FC0204 +9986:2040202023FE3A024C0451F88108210821F82100210021FC2904310421FC0104 +9987:2040204027FC38E049505248844623F8220823F8220823F82A08300027FE0000 +9988:2020202021FC3D2445FC482083FE200021FC2104212425242924305020880304 +9989:200021FC21043DE445244BFE820221FC210421FC210425FC2904310421140108 +998A:20A0232E22223E2247AE4A22A22223FE202023FE210420882850302020D80706 +998B:210021F022103C204BFC5244824423FC20A02122261E20C02830318020600010 +998C:2020202021FC3C2044204BFEA080210423FE200223FC22942A94329427FE0000 +998D:2110211027FC3910480053F8820823F8220823F8204023FC28A0311022080406 +998E:2028202423FE3C2045FC4924A1FC212421FC2124200823FE2888304820480018 +998F:204023BE22123A924A5252AA8324204023FE2222222223FE2A22322223FE0202 +9990:2208211027FC38404BF8508087FC210023F82488288823F82908310827FE0000 +9991:2088208823FE3C8844F84820A1FC212421FC202023FE202029FC302023FE0000 +9992:23F8220823F83A084BF8500087FC24A424A427FC200023F8291030E023180C06 +9993:2288228827C83A904A9E57D4802427D4245427D4245427C82C483454246404C2 +9994:200023DE22523BDE4A10525281CE2000208823FE208820882BFE308821040202 +9995:204027FC22483BF848405FFE8AAA23B8211027FC21102FFE292833102D480186 +9996:10100820FFFE020004003FF8200820083FF8200820083FF8200820083FF82008 +9997:211020A0200023FCFC8025F8250825F8250825F8250825FA250A440243FE8000 +9998:441424122810FDFE101020107DD2455245527D5445D47C0844CA471A7C264442 +9999:00701F8001000100FFFE054009203118DFF6101010101FF0101010101FF01010 +999A:041078501050FE5010883888550492FA7C48444844487C48448844887D284610 +999B:045078481048FE4011FE38405440907C7CA444A444A87D28451046287C444482 +999C:040078FC1084FE84108438FC548090A07CA444A844B07CA044A245227D1E4600 +999D:044078201028FE0810083848545491527D52456046607C4444C445447E3C4400 +999E:0420782011FEFE20102039FE550292047CF8441044207DFE442044207CA04440 +999F:0408783C11C0FE04114438A8540091F87C10442047FE7C20442044207CA04440 +99A0:042078201050FE8811443A2254F890087C10442045FC7D04450445047DFC4504 +99A1:044878481048FDCE10483848544891CE7C48444844487DCE444844487C484448 +99A2:04487844105EFDE010283812546A91967C48445E45E07C24442844127C6A4586 +99A3:0420782011FEFE5010A8392654F890A87CA844F844A87CA844F844AA7C22441E +99A4:040079FC1104FDFC110439FC548091FE7E22452245527D0245FA44027C144408 +99A5:0440784010FEFE8011FC3A8454FC90847CFC4440447C7CC4452844107C684586 +99A6:048878501000FDFE105039FC545493FE7C5445FC44507CD8455446527C504450 +99A7:040078F81088FE8810F83888548890F87C0045FC45547D54455445547FFE4400 +99A8:0878FF4808863E782A483E3040489FE401007FFC09203FF8C8260FE008200FE0 +99A9:042079FC1020FC8813FE388855FC91047DFC450445FC7D0445FC44887D044602 +99AA:0420781011FEFF0210FC38A8553090FC7D8444FC44847CFC448444FC7C484484 +99AB:1FE001007FFC09203FF8C8260FE008247FF81010FEFE545492927C7C44447C7C +99AC:00003FF821003FF021003FF0210021003FF80008124849284928800800500020 +99AD:00007F00487C7F2448247F24482448287FA800A8AA90AA90AAA880A805440282 +99AE:000043FC224023F802400BF80A40124013FCE004255425542554240420280010 +99AF:00007F7C48107F1048107F104810487E7F900090AA90AA90AA90809005100210 +99B0:00107F1048107F3C48247F44480448247F940094AA84AA84AA84808405280210 +99B1:00107F1048107F10487E7F10481048107F9000A8AAA8AAA8AAA880C405440282 +99B2:00087F1C48707F1048107F104810481E7FF00090AA90AA92AA928092050E0200 +99B3:00207E2048207EA048AC7EB448E449A47EA402B4AAA8AAA2AAA28282147E0800 +99B4:00027F22482A7F2A482A7F2A482A482A7FAA00AAAAAAAAAAAAAA80AA05420282 +99B5:3FF821003FF021003FF021003FFC4924849408280820FFFE0820102020204020 +99B6:00107E1048107EFE48107E1048FC48447E440244AA28AA28AA10822814440882 +99B7:00087F0848087F3E48087F08483E482A7FAA00AAAAAAAAAAAAAE808805080208 +99B8:00007F0C48307F2048207F20483E48247FA400A4AAA4AAA4AAA480A405440284 +99B9:00007F3E48227F2248227F224822483E7FA200A2AAA2AAA2AAA280BE05220200 +99BA:00007EFC48447E4848487E50485C48447E440244AA68AAA8AA90829815240842 +99BB:00107F1048207F2848447F7C480448287FA800A8AAA8AAA8AAAA80CA05460280 +99BC:00207E1048107EFE48447E44484448447E440228AA28AA10AA10822814440882 +99BD:3FF821003FF021003FF021003FFC4924849401083FF8210821083FF801000100 +99BE:00107E1048107E1048FE7E92489248107E280228AA28AA28AA48824A148A0906 +99BF:00107F0848007F3E48227F224822483E7FA200A0AAA0AAA0AAA080A005400280 +99C0:00487E4448447E4049FE7E50485048507E500250AA50AA52AA528292148E0900 +99C1:00027F2248147F0848147F22484248007FA200A2AA94AA94AA88809405240242 +99C2:400049FC5120612045FC45203DFC1120112011FEFC0212AA12AA120210141008 +99C3:00107F1048107F10487C7F14481448147F9400FEAA90AA90AAA880A805440282 +99C4:00207E2048207E2048FE7E20482048307E500250AA48AA48AAC882A415240A02 +99C5:00007E7C48447E4448447E44487C48547E500250AA48AA48AA48828414840902 +99C6:00007DFE51007D0451447D28512851107D100528552855445584850015FE0800 +99C7:00107F1048107F20483E7F4448A448247FA800A8AA90AA90AAA880A805440282 +99C8:00087E1C48607E4048407E404840487E7E480248AA48AA48AA48824815FE0800 +99C9:00007EFE48827E8248827EBA48AA48AA7EAA02AAAABAAAAAAA828282148A0884 +99CA:00107E1048107EFE48927E94489048FC7EA402A4AAA8AAA8AA90832815440A82 +99CB:00007F7E48127F1248127F22482A48447F8000BEAAA2AAA2AAA280A2053E0222 +99CC:10003EF84288A2AA1492187EE0001FF011001FF011001FF011001FFC2A44492C +99CD:00007F7C48107F1048547F34483848107FFE0090AA90AA90AA90809005100210 +99CE:00087F0848087F08483E7F2A482A482A7FAA00BEAAAAAAAAAAAA80AA053E0222 +99CF:00007F3E48207F2048207F3E482248227FA200A2AABEAAA0AAA080A0053E0200 +99D0:00107F0848007F3E48087F08480848087FBE0088AA88AA88AA888088057E0200 +99D1:08007F7C114432280C10122861461FF011001FF011001FF011001FFC2A44492C +99D2:00207F2048207F7E48427F82483A482A7FAA00AAAABAAAAAAA82808205140208 +99D3:00007F3E48087F0848087F18481C482A7FAA00CAAA88AA88AA888080053E0200 +99D4:00007F3C48247F2448247F3C482448247FA400BCAAA4AAA4AAA480A4057E0200 +99D5:100010007E7C124422442A7C44009FF011001FF011001FF011001FFC2A44492C +99D6:00107F1048287F2848447F92480848007FBC0084AA88AAA8AA90808805040200 +99D7:00107F1048287F2848447F92482048407F880090AAA0AA84AA88809005200240 +99D8:00087F0848107F1048247F7E482248007FBC00A4AAA4AAA4AAA480A4053C0224 +99D9:00487E4848487E8848FE7E88498848887EC802A8AAA8AA88AA88828814A80890 +99DA:00207C2050207DFC51247D24512451247D2407FE542054505450848815040A02 +99DB:00087F0848087F3E482A7F2A482A482A7FBE0088AAC8AAA8AA90809805240242 +99DC:00107E0848087E0248227E24482448A87EAC02B2AB32AA20AA6282A2151E0800 +99DD:00107F0848087F7E48427F42482048247FA800B0AAA0AAA2AAA280A2051E0200 +99DE:00407C40507E7C8051207CA050AC50B47DE404A454B454A854A28482147E0800 +99DF:00007E0048FE7EAA48AA7EAA48AA48AA7EAA02AAAAAEAAC2AA82828214FE0882 +99E0:00007E2048CE7EAA48AA7EAA48AA48AA7EAA02AAAAEAAAACAA28824814480888 +99E1:00003EF822883EF800001FF811001FF011001FF011001FFC0004292444940008 +99E2:00847E4848007EFC48487E48484848487FFE0248AA48AA48AA48828814880908 +99E3:00507E5048507F5248D47E58485048587ED40352AA50AA50AA92829215120A0E +99E4:00007F7E48107F1048247F22487E480A7F880088AABEAA88AA888088057E0200 +99E5:00147E1248127E1048FE7E10485248527E5202F4AA54AA54AA8A828A15160822 +99E6:111009207FFC0200FFFE08203018DFF611001FF011001FF011001FFC2A44492C +99E7:00007EFE48827E8248BA7E82488248BA7EAA02AAAAAAAABAAA828282148A0884 +99E8:00107F1048107F3E48227F42483A482A7FAA00BAAAAAAAAAAABA808205140208 +99E9:00087F0848147F1448227F40483E48087F880088AABEAA88AA888088057E0200 +99EA:00107E5048507E7C48907E10481048FE7E280228AA28AA28AA4A824A14860900 +99EB:00207E2049247EA448A87E2049FE48507E500250AA50AA52AA528292148E0900 +99EC:00007F7E48247F2448247F3C482448247FBC00A4AAA4AAAEAAF4808405040204 +99ED:00207C1050107DFE50207C24504450F87C120422544455885410842814440982 +99EE:00207E1048107EFE48007E44488249007E440244AA28AA28AA10822814440982 +99EF:00107E5048507E7C48907E10481048FE7E100238AA38AA54AA54829214100810 +99F0:00007EFE48827E9248927E9248FE48927E9202AAAAA6AAC6AA82828214FE0882 +99F1:00407E4048787E8849507E20485048887F0602F8AA88AA88AA88828814F80888 +99F2:00827C9250927C9250927C9252DA52B67C920492549254925492851215020A02 +99F3:0004F80EA3B8F888A088F928A12EA3A8F8A80AA8AAA8A93EA9008A800C7E3800 +99F4:0010F814A012F810A3FEF810A150A154FFF40954A954A948AA4A8A5A0C263042 +99F5:00007EFE48287E2848287EEE48AA48AA7EAA02AAAAEEAA28AA28822814480888 +99F6:00007EFC48847E8448FC7E8048FE48827EBA02AAAAAAAABAAA82828214940908 +99F7:00107E1048FE7E1048107EFE489248927EFE0210AA38AA54AA92831014100810 +99F8:00007EFC48047E7C48047EFC480049FE7F0202FCAA44AA44AA28821014680986 +99F9:00487E4448407EFE48507E54485848527E540258AA52AA54AA9A8292152E0A40 +99FA:00207E1048FC7E8448847EFC488448847EFC02A2AAA4AA98AA90828814C40882 +99FB:00007F3E48227F3E48227F3E480048007FBE0088AA88AAFEAA88808805080208 +99FC:00107E1048287E2848447EBA481048107EFE0210AA58AA54AA92831214500820 +99FD:00007F3E48227F22483E7F00483E48227FA200BEAAA2AABEAAA280A2052A0224 +99FE:00847E4448487E0048FC7E84488448847EFC0248AA48AA48AA48828A148A0906 +99FF:00107E1048207E4448FE7E28484448A27E3C0244AA44AAA8AA10822814440882 +9A00:0010F8D8A394F894A090FBFEA090A094F89408D8AB98A890A8AA88CA0A863102 +9A01:00107E1048FC7E9448FC7E9448FC48007FFE0240AA80AAFCAA04820414280810 +9A02:00207F1048107F7C48007F28481048FE7F900090AAFCAA90AA90809005100210 +9A03:00107E2048447E8248FE7E004840487E7E900210AAFEAA10AA28824414820900 +9A04:00007EFC48047E04487C7E04480448FE7E100292AA54AA38AA54829214500820 +9A05:00507E4848807EFE49907E9048FC48907E9002FCAA90AA90AA9082FE14800880 +9A06:00007EFE48927E9248BA7E9248FE48827EBA02AAAAAAAABAAA828282148A0904 +9A07:0020F820A050F888A104FAFAA020A020FBFE0820A820A9FCA904890409FC3104 +9A08:00227E2248447EEE48447E44484448447EEE0244AA44AA44AA44824414440884 +9A09:00007EFC48847E8448FC7E84488448FC7E000290AA92AAF4AA98829214D2088E +9A0A:00407E4048FE7E8249427E7A48A248227EFA0222AAAAAAAAAAFA820214140808 +9A0B:00107E1048107EFE48107E54485448547EBA0210AA38AA54AA92821014100810 +9A0C:00207E1048FE7E8248007E7C480048007EFE0210AA10AA54AA52829214500820 +9A0D:00007E7C48547E54487C7E544854487C7E1002FEAA10AA38AA54829214100810 +9A0E:00207E2049FC7E2048507E8849FE48087EE802A8AAA8AAE8AAA8820814280810 +9A0F:00247F24487E7F2448247F3C482448247FBC00A4AAA4AAFEAA8080A405220242 +9A10:0020F820A050F888A144FA22A1F8A008F8500820A8A4AA82AA8A8A8A0C783000 +9A11:00287E2848287EEE48287E28482848EE7E280228AA28AAEEAA28822814280828 +9A12:00007EFC48447E2848107E68499648107EFE0292AA92AAFEAA10821415FE0882 +9A13:00107E2848447E82487C7E10481048FE7E920292AAFEAA10AA28822814440882 +9A14:00007EFC48847EFC48847EFC484048FE7F120292AAAAAA82AAFA820214140808 +9A15:00007EFE48287E2848FE7EAA48AA48FE7E1003FEAA24AA44AA68821814640982 +9A16:7E20243E1848FFA829104A2898461FF011001FF011001FF011001FFC2A44492C +9A17:1000087C7E50427C42507E7C425040507F7C550455547F54D554558455144308 +9A18:00407E40487E7EAA496A7E5A489649227E4A0284AA20AA94AB428244143C0800 +9A19:00407C2051FE7D0251027DFE510051007DFE05AA56AA56FE54AA84AA14A20886 +9A1A:00847C4450487DFE50007DE2512A512A7DEA052A552A55EA552A8522152A0964 +9A1B:00007DFA500C7C4A51887CAA50A650A27DF804AA54AC54AA54A8852A15260A22 +9A1C:00107E20487C7E44487C7E44487C48007EFE0210AA10AA7CAA10821014FE0800 +9A1D:0010F810A03CFB94A0FEF894A13CA110FBBC0890A8FEAA90A91089800A7E3400 +9A1E:00107E1048FE7E1048FC7E1048FE48107EFE0220AA40AAFCAB448244147C0844 +9A1F:00207C5050887D0452FA7C0051E2512A7D2A05EA552A552A55EA8522152A0964 +9A20:00007EFC48847E8448FC7E84488448FC7E0003FEAA20AAA0AABC82A015600A3E +9A21:00107E2048FE7E8248FE7E8248FE48107E1202D4AA58AA54AA94829215500820 +9A22:00007DDC51447D4451447DDC510051007DDC0514551455D45508850815140922 +9A23:00287E9248AA7E8248FE7E28484448A27E3C0244AA44AAA8AA10822814440882 +9A24:00107ED448487F4A48847E84490248F87E200220ABFCAA20AA50824814840904 +9A25:00007CFC50487C3051FE7C52509451107E30042055FE547054A8852416220820 +9A26:00007DFC51247D2451FC7D24512451FC7C200410545455425542854A16380800 +9A27:00007E7C48447E4448747E54485448FE7E8202BAAAAAAAAAAABA8282148A0884 +9A28:02427D2450007DFC51247D2451FC51247D2405FC5420542057FE842014200820 +9A29:00107E2048FE7E9248927EFE489248927EFE0220AA24AA5AAA5E82901492090E +9A2A:00507E9648927E9248D67E92489248FE7E1002FCAA44AA44AA288210142808C6 +9A2B:01007FFE44429FF404403FF80440FFFE09201FF02908CFE609000FF800081558 +9A2C:001CF9E0A020FBFEA0A8F8AAA3ACA0AAF9AA0AA6A870A8A8A9248A220C203020 +9A2D:0020793C492053FE48A46B285070438000003FF821003FF821003FFE29224496 +9A2E:00207EDE488A7ECA48AA7ED248A648007EFE0292AA92AAFEAA92829214FE0882 +9A2F:00207E1048FE7E0048447E2848FE48A27E1002FEAA20AA3CAA24824414540888 +9A30:012478A849FC48404BFE79084BFC4D2249FC792049FC492049FE48024AAA9804 +9A31:000E7EF048227E9248447E20484448F87E100224AAFEAA10AAFE822814440882 +9A32:00887C8853FE7C8850007DFC510451FC7D0405FC5524542057FE842014200820 +9A33:00007EFE48907EFC48907EFC489048907EFE0202AAAAAAAAAAAA828214140808 +9A34:00007E7C48447E7C48447E7C481048FE7E820220AAFEAA44AA68821014280844 +9A35:00007EFE48887E9048BE7EA248BE48A27EBE0288AAACAAAAAACA828A15280A10 +9A36:00407E4048FE7F2248AA7EFA484248947F4802FEAB22AAAAAAFA824214940908 +9A37:00007DFC50A47C8850507C2050D853267C2005FC5524552455FC842217FE0802 +9A38:00207C1051FE7D0251027DFE510051EE7D2205AA55665522556686AA16220C66 +9A39:00887C8853FE7C8850F87C2051FC51247DFC042055FC542055FC842017FE0800 +9A3A:08207E2008F8FF2814287F6A082AFF5608823FF821003FF821003FFE29224496 +9A3B:00107E1048FE7E1048BA7E5448BA48107EBA0254AABAAA10AA28822814440882 +9A3C:00207E1048FE7EA848A87EFE48AA48AA7EFE0280AACAAAECAB48824A146A0846 +9A3D:00007DDE50427D5250CA7D52504250207CFC0484548454FC5484848414FC0884 +9A3E:00007DFC51247DFC51247DFC504050887DF00420544457FE5422852416220860 +9A3F:00107EFE48447E2848FE7E00487C48447E7C0244AA7CAA10AAFE821014100810 +9A40:0820FFFE08201FF010101FF01010FFFE08203FF8D1061FF011001FFC2A44452C +9A41:08207F20087E7E4408A4FF2810101E2822447FFAA1003FF821003FFE29224496 +9A42:00107E2048447EFE48447EAA48EE48107E280254AAAAAA50AA24824814100860 +9A43:00007EFE48287EFE48AA7EAA48FE48007E7C0200AAFEAA10AA54829214500820 +9A44:00207C4051FC7D24517C7D8C515451247D5405FC5420541055548542154A0A38 +9A45:0000FBFEA200FA7CA244FA44A27CA200FAEE0AAAAAAAAAAAAAEE8A000BFE3000 +9A46:00007EFE48927EFE48927EFE485448547EFE0254AA54AAFEAA1082FE14100810 +9A47:08203E2008F87F282A685D2A08563E8200003FF821003FF821003FFE29224496 +9A48:00FC7E2848107FFE48527E94495048207EFE02AAAAC6AABAAAAA82BA14820886 +9A49:00207C3C50207DFE51227D3851E4511C7D00052855AA556C5528862814FE0800 +9A4A:00447EFE48447E0048FE7E54485448FE7E540254AAFEAA10AAFE821014100810 +9A4B:0024FBA8A092FD14A208FC04A3BAA0A8F8C60B80AA3CAB84A8A888900AA83144 +9A4C:0020F9FCA024FBFEA024F9FCA020A2AAFBAE0A22ABFEAA22ABAE8AAA0AAA3422 +9A4D:0020F820A1FCF820A3FEF908A39CA108F9880E3EA800ABFEA89088900912320E +9A4E:0020F924A0A8FBFEA0A8F924A222A104F90409DEAA44AD54A89E89040A043404 +9A4F:03FEFA02A3FEFA00A2FCFA08A3FEA210FA300BCEAA42AA84ACEE8F840884318C +9A50:0108F888A3C8F810A3DEFA64A3D4A014FBD40854A894A8E8AB8888940A943122 +9A51:00007EFE48287EEE48AA7EAA48EE48287EFE0292AA92AAFEAA92829214FE0882 +9A52:00007EEE48AA7EAA48EE7E0048FE48927EFE0292AAFEAA10ABFE821014100810 +9A53:00447E2448287EFE48927ED648BA48927EFE0200AA7CAA44AA7C8244147C0844 +9A54:00007EFE48287EFE48AA7EFE4800487C7E44027CAA44AA7CAA1082FE14100810 +9A55:0018F9E0A040FBFEA088F974A252A070F80009FCA904A974A95489740904310C +9A56:008CFBEAA088FBFEA008FBE8A22AA3EAF80A0BECA88CABECA88A88EA0B963022 +9A57:00207C2050507C8851047EFA500050007DDC0554555455DC5488848815540A22 +9A58:0100FFFE20003FF800003FF820083FF8000077DC551477D4551C77D65056B562 +9A59:00107EFE48007EFE48827EBA48AA48FE7E00027CAA44AA7CAA44827C140008FE +9A5A:2420FF20247E7EC482287A104A287AC604003FF821003FF821003FFE29224496 +9A5B:00007DFC51547DFC50207DFC502053FE7C88045055FC542057FE842014200820 +9A5C:00507D5250D47C5051FE7C88505051FE7C2004FC542055FE54A8852416220820 +9A5D:00107EFE48107E7C48007EFE4882487C7E20027CAAC4AB7CAA1082FE14540992 +9A5E:0040F820A3FEFA02A1FCF948A250A1FCFB0409FCA904A9FCA90489FC08883104 +9A5F:03F07D2E51E27D2A51E47D3453EA50327C1E07E054A25534546884A417220820 +9A60:0110F910A7FCF910A1F0FA08A2EAA6ACFAA80AAAAEEAAA06A8008AA40A523452 +9A61:10407E7C2440FF7C42047E7C42407E7842423FFE21003FF821003FFE29224496 +9A62:0040F87CA040FBFCA244FBF0A244A2FCFAA80AF8AAA8AAF8AA008DFC095433FE +9A63:01247CA851FC7C4053FE7D0853FC55227DFC052055FC552055FE840216AA0804 +9A64:00107EFE48007EEE48AA7EEE484448FE7E4402FEAA44AAFEAA5082CA15640842 +9A65:0094FB98A092F98EA280F9FCA124A1FCF92409FCA888A9FCA8888BFE08883104 +9A66:01FCF820A3FEFA22A1ACF820A1ACA000F89E0BF2A89EA9D2AABE8C92089E3092 +9A67:0290FA90A7D0FABEA3CAF92EA7DAA54AFD7E0FCAA91EAFEAA90A8902090A3104 +9A68:0222FBFEA090F9FEA310FDFEA110A1FEF91009FEA900ABFEAA8A8B760A523276 +9A69:0088FBFEA088FBDEA252FBDEA0A0A090F9FE0920ABFCAD20A9FC892009FE3100 +9A6A:03DEF800A3DEFA52A35AFA52A020A3FEFA500BFEAA52ABFEAA928ADC0A9234CE +9A6B:7FF842007FF042007FFC5244892C7E7E48487E7E48487E7E48487E7E02029696 +9A6C:00007FE0002000201020102010201FFC000400040004FFE40004000400280010 +9A6D:00007C0005FC24842484248424883E88025002501A20E2204250028815040A02 +9A6E:00207C2004202420242025FE24203E20022002501A50E2504288028815040A02 +9A6F:0104F924092449244924492449247D24052405241D24E524452406242A041404 +9A70:0020F82008204920492C493449647FA4052405341D28E5224522050228FE1000 +9A71:0000F9FE090049044944492849287D10051005281D28E5444584050029FE1000 +9A72:00007CFC048424842484248424843EFC028402841A84E2844284028414FC0884 +9A73:0008F888085048204850488849007C08048804881C50E4504420045028881306 +9A74:0040F820082048FC4884488448847CFC048404801C80E4804480050029001200 +9A75:0000F8F808884888488848F848887C88048804F81C88E488448804882BFE1000 +9A76:0020F820082049FC4924492449247D2405FC04201CA0E4604460049029081206 +9A77:0000F9FC095449544954495449547D540594058C1D04E504450405FC29041000 +9A78:0088F88808884908497E4B084D087D48052805281D08E5084508050829281110 +9A79:0080F880090049FC4A044C0449E47D24052405241DE4E5244404040428281010 +9A7A:0080F88008F849084A104C204BFC7C04040404041DFCE404440404042BFC1004 +9A7B:0040F82008004BFE4820482048207C2005FC04201C20E420442004202BFE1000 +9A7C:0020F810081049FE49024A0448807C88049004A01CC0E48244820482287E1000 +9A7D:08007F7C114432280C10122861461FE00020082008200FFC00047FC400140008 +9A7E:080008007F7C11441144257C42001FE00020082008200FFC00047FC400140008 +9A7F:0000FBFC090448884850482048D87F26042005FC1C20E42047FE042028201020 +9A80:0020F8200840488849044BFE48027C0005FC05041D04E5044504050429FC1104 +9A81:0080F88008BC4BC04850482448D47F0C040007FE1C90E490451205122A0E1400 +9A82:00007CF8448844887CF800003FE00020082008200FFC00047FE4000400280010 +9A83:0000F9FC090449244924492449FC7D24052405541D4CE58C4504050429FC1104 +9A84:0008F83C09E0482048204BFE48507C880504068A1C88E4884488050829081208 +9A85:0090F894091449184B104D3249527D0E052004201FFEE4204420042028201020 +9A86:0080F88008F849084B104CA048407CA0051806061DF8E5084508050829F81108 +9A87:0020F810081049FE4820482448447CF8041204221C44E5884410042828441182 +9A88:0084F8440848480049FE484848487C48044807FE1C48E4484448044828881108 +9A89:3FF0001010101FFC00047FE400280010FCFC040444447E7E0202F2F20A0A0404 +9A8A:0000F3FE1000500053DE525252527A520B5A0AD63A52CA520A520A522A5212D6 +9A8B:0020F82009FC492449FC492449FC7C0007FE04801D00E5FC4404040428281010 +9A8C:0020F82008504850488849044AFA7C00044404241D24E4A8448804102BFE1000 +9A8D:0040F82009FC4800488848504BFE7C20042004201DFCE4204420042028201020 +9A8E:0000F8FC0804487C480448FC48007DFE050204FC1C44E4444428041028681186 +9A8F:0040F840088849044BFE480248887D44064204F81D88E6504420045029881606 +9A90:0088F8880BFE4888488848F848887C8804F804881C88E7FE4400048828841104 +9A91:0020F82009FC4850488849044BFE7C0805E805281D28E5E84528040828281010 +9A92:0000F9FC0924492449FC492449247DFC042007FE1C70E4A84524062228201020 +9A93:0050F848088048FE49904A9048FC7C90049004FC1C90E490449004FE28801080 +9A94:0040F8200BFE4A024C0448F848007C0005FE04201CA8E4A44522062228A01040 +9A95:0020F82009FC48244BFE482449FC7C20052405241D74E5AC452405242A241424 +9A96:0040F848088449FE48204BFE48887D24064205881C10E4624584041828601380 +9A97:0040F82009FE4902490249FE49007D0005FE05AA1EAAE6FE44AA04AA28A21086 +9A98:0020793C492053FE48A46B28507043801FE0002008200FFC00047FC400140008 +9A99:0010FBD408584A52498C488849047EFA042004201DFEE4204450048829041202 +9A9A:0000F9FC08A448884850482048D87F26042005FC1D24E52445FC04222BFE1002 +9A9B:7E20243E1848FFA829104A28984600001FE0002008200FFC00047FC400140008 +9A9C:08207F20087E7E4408A4FF2810101E2822445FE2802008200FFC00047FD40008 +9A9D:0040F9BC09144994495449A4494C7C0005FC05241D24E5FC4524052429FC1104 +9A9E:01007FFE44429FF404403FF80440FFFE08201FD02048C8460FF800087FA80010 +9A9F:0020F81009FE4902490249FE49007DEE052205AA1D66E522456606AA2A221466 +9AA0:0000FBFE085049FC4954495449FC7C0005FC04001FFEE42044A805242AA21040 +9AA1:0000F9FC092449FC492449FC48407C8805F004201C44E7FE442205242A221060 +9AA2:0020F84009FC4924497C498C49547D24055405FC1C20E41045540542294A1238 +9AA3:03FEF20213FE520052FC520853FE7A100A300BCE3A42CA840CEE0F842884118C +9AA4:07E0F25C13C4525453C8526857D47864083C0FC03944CA6808D009482E461040 +9AA5:0094FB980892498E4A8049FC49247DFC052405FC1C88E5FC448807FE28881104 +9AA6:01FCF8200BFE4A2249AC482049AC7C00049E07F21C9EE5D246BE0492289E1092 +9AA7:0020F3FE100051DC515451DC50887BFE08880BFE3888CBFE089409882AA410C2 +9AA8:1FF010101F90109010907FFE40029FF410101FF010101FF01010101010501020 +9AA9:00407C404440744055F8FE4882487C4844487C4844487C4A448A448A55064A00 +9AAA:00007C0044F074905490FE9082907CD044B07C9044907C9244924512550E4A00 +9AAB:00407C40444075F85448FE4882487D4844C87C4844A87CA8448A450A55064A02 +9AAC:00007CFC442074205420FE2082207DFE44207C2044207C204420442054A04840 +9AAD:00007CFC442074205420FE2082207DFE44207C2044207C204420442054204820 +9AAE:3F1021143D12251225107F9640B8BF1021103F1021103F10210A210A25062202 +9AAF:00407C20440075FC5400FE0082F07C9044907C9044907C9244924512550E4A00 +9AB0:00007CF8448874885488FF0682007DFC44847C8444487C504420445054884B06 +9AB1:00207C20442074505450FE8883067C4844487C4844487C484448448854884908 +9AB2:00407C4044FC74845504FEF482947C9444F47C8444947C8844824482547E4800 +9AB3:00107C10441074FE5492FE9482907CFC44A47CA444A87CA84490452855444A82 +9AB4:00087C284428742854A8FEAA82BC7CA844A87CA844A87CA844AA44BA54EA4986 +9AB5:00207C204420742055FEFE7082A87CA845247D2446227CF84420442054204820 +9AB6:00047C1E44F074905490FE9082907CFE44907C9044907C88448A44AA54D6488A +9AB7:00207C204420742055FEFE2082207C2044FC7C8444847C844484448454FC4884 +9AB8:00207C10441075FE5420FE2482447CF844127C2244447D884410442854444982 +9AB9:00207C10441074FE5400FE4482827D0044447C4444287C284410442854444882 +9ABA:00087C1C44E074805480FEFE82807C8044BC7CA444A47CA444A4453C55244A00 +9ABB:00207C2045FC74505488FF0482FA7C0047FE7C4044807DFC4404440454284810 +9ABC:00407C40447874885550FE2082507C8845067CF844887C884488448854F84888 +9ABD:00047C1E45E074225512FE9482807C2045FE7C4444847DC84430442854C44B02 +9ABE:00007DFE4420742055FCFF2483247DFC45247D2445FC7D2044A0444054B04B0E +9ABF:00847C48440074FC5448FE4882487C4845FE7C4844487C484448448854884908 +9AC0:00207C4044FE74925492FEFE82927CA244FE7C4844887DFE4408440854084808 +9AC1:00007CF844A874A854F8FEA882A87CF844207DFC44207C7044A8452654204820 +9AC2:00407C2045FC75045440FE7882887D5044207CD847067CF84488448854F84888 +9AC3:00FC7CA444A474FC54A4FEA482FC7C2044207DFE45227D2A45FA450A55024906 +9AC4:00087C0844FE751054A0FE7E82A27C2245BE7CA244BE7CA244AA44A455404A3E +9AC5:00207D2444A8742055FEFE6882A47D0244207DFE44487C8844D04430544C4982 +9AC6:00147C1245FE741054FEFE9282FE7C9244FE7C9244047DFE444444245424480C +9AC7:00207C1045FE740054FCFE8482FC7C0045FE7D02457A7D4A457A4502550A4904 +9AC8:00207C1044FE74005444FE2882FE7CA244107CFE44207C3C4424444454544888 +9AC9:00207C2045FE75525448FEFE82907D9044FE7C9044907CFE4490449054FE4880 +9ACA:00847C44444875FE5420FEFC82207DFE44407C8044FE7D104610441055FE4800 +9ACB:00207C1045FE75025448FEFC82487C0044FC7C8444A47CA444A4445054924B0E +9ACC:00407C2045FE75025418FEE082807CFC44907C9044907DFE4400448855044A02 +9ACD:00207C1045FE75485548FF4883FE7D4845487DEC455A7D684548454856484848 +9ACE:00007CEE442274AA5466FEAA82107C2844447D9244207CC8443244C4541848E0 +9ACF:00207DFC452477FE5524FFFC82207DFC45247DFC44407DFE448845D054704B8C +9AD0:00207C2044FC742055FEFE8883DC7C8844C87DBC44007DFE445044505494490C +9AD1:00007CFE44AA74AA54FEFE4082FE7D2244FA7CAA44AA7CFA442244FA540A4804 +9AD2:00487DFE4448740055FEFE8882EA7D2C44CA7C8645487DFE4448444854884908 +9AD3:00107C7E452074BC54C8FEBE82007DBC44A47CBC44A47CBC44A444AC55404A3E +9AD4:00507DFC455475FC5554FFFC82007DFC44007DFC45047DFC4488445057FE4800 +9AD5:00207C1045FE750254FCFEA883307CFC45847CFC44847CFC448444FC54484884 +9AD6:00207DFE454A74FC5448FEFC82847CFC44847CFC44847CFC445044545492490E +9AD7:00207C3E442075FE5522FFF883227D7E45547D7C45547D7C450046FE54AA49FE +9AD8:02000100FFFE00000FE0082008200FE000007FFC40044FE4482448244FE4400C +9AD9:020001007FFC10101FF010101FF010107FFC40044FE4482448244FE44004400C +9ADA:20201010FE1001FE7C0044007C780048FE488248BA48AA4AAA4ABA8A82868700 +9ADB:200010FCFE8400847CFC44A07CA000A0FEF882A8BAA8AAA8AAA8BAAA834A8686 +9ADC:2000107EFE42007E7C42447E7C000014FE648224BA24AAFEAA24BA2482448684 +9ADD:2048116AFEDC00487CB445227DFE0102FE208220BAFCAA24AA44BA4482948708 +9ADE:207C1044FE44007C7C0044EE7CAA00AAFEEE8210BAFEAA38AA54BA9283108610 +9ADF:3F04200420083E10202020443E0420082010FF22104224044208FF10412000C0 +9AE0:3E0420183E6020043E182062FF0422187F6000000FE00820082010222022C01E +9AE1:3E0420183E6020043E182062FF0422187F6000007FFC0440044008423042C03E +9AE2:3E0420183E6020043E182062FF0422187F60013011D01F107152112210020FFE +9AE3:3E0420183E6020043E182062FF0422187F6002007FFC040007F0081010A06040 +9AE4:3E0420183E6020043E182062FF0422187F6001007FFC0380054009203118C106 +9AE5:3F0820303EC42018FF62220C7F7000000FF008107FFE08107FFE081008500820 +9AE6:3E0420183E6020043E182062FF0422187F6001F03E0003F03E0003FA7E0201FE +9AE7:3E0420183E6020043E182062FF0422187F6001007FFC4104028004821882E07E +9AE8:3E0420183E6020043E182062FF0422187F6000003FF80000FFFE04401842E03E +9AE9:3F0820303EC42018FF62220C7F700000FFFE010021FC21043FFC000400280010 +9AEA:3E0420183E6020043E182062FF0422187F600100FFFE04000FF0122061C00E3C +9AEB:3E0420183E6020043E182062FF0422187F6000007FF8080810303FF8D0081FF8 +9AEC:3E0420183E6020043E182062FF0422187F6000007FFC03000D70710C0100FFFE +9AED:3E0420183E6020043E182062FF0422187F60088008882E9028E028842E84F07C +9AEE:3E0420183E6020043E182062FF0422187F600110FFFE04000FF0122061C00E3C +9AEF:3F0820303EC42018FF62220C7F7001003FF821083FF82108FFFE200820282010 +9AF0:3E0420183E6020043E182062FF0422187F6000001220FFFE122013E010001FFC +9AF1:3F0820303EC42018FF62220C7F7008001FF020105F9010901FD0102010040FFC +9AF2:3E0420183E6020043E182062FF0422187F6000803FFC208427F0222041C09E3C +9AF3:3E0420183E6020043E182062FF0422187F6000003FE00440FFFC04841888E180 +9AF4:3F0820303EC42018FF62220C7F7004407FF804483FF824403FFC084410542048 +9AF5:3E0420183E6020043E182062FF0422187F600000FFFE02003FF8248824A82010 +9AF6:3F0820303EC42018FF62220C7F7000003FF808200FE008200FE0083EFFE00020 +9AF7:3E0420183E6020043E182062FF0422187F6004403FF824483FF824483FF82008 +9AF8:3E0420183E6020043E182062FF0422187F6004403FF80440FFFE082010102008 +9AF9:3E0420183E6020043E182062FF0422187F600840104037FCD0E013581C461040 +9AFA:3F0820303EC42018FF62220C7F70000000F83F000100FFFE01001FF010101FF0 +9AFB:3F0820303EC42018FF62220C7F700100FFFE01003FF800003FF820083FF82008 +9AFC:3F042018FF62220C7F7008001FF0282007C01830E10E1FF001007FFC01000100 +9AFD:3E0420183E6020043E182062FF0422187F6011101110292845443FF80100FFFE +9AFE:3F0820303EC42018FF62220C7F70111009203FF820083FF820083FF820082018 +9AFF:3E0420183E6020043E182062FF0422187F60102048A825240A227028103017C0 +9B00:3F042018FF62220C7F70082004407FF801083FF821003FFC0304051419086100 +9B01:3E0420183E6020043E182062FF0422187F6000083E4808487F481C482A084918 +9B02:3F0820303EC42018FF62220C7F7000201FC010001FF810801080FFFE10202010 +9B03:3F0820303EC42018FF62220C7F7001007FFC40041FF000007FFC111025084204 +9B04:3F0820303EC42018FF62220C7F7000001FF010101FF010101FFC644408943308 +9B05:3F0820303EC42018FF62220C7F7000003E7C22443E7C22443E7C22444A948508 +9B06:3E0420183E6020043E182062FF0422187F6010101088FD443242589095F81008 +9B07:3F042018FF62220C7F7008001FF020205FF80108FFFE01081FF8010805000200 +9B08:3F042018FF62220C7F70111009207FFC0400FFFE10102FE8C82608A0084807F8 +9B09:3F0820303EC42018FF62220C7F700440238824483FF814102FE8144003807C78 +9B0A:3F042018FF62220C7F7001007FFC01003FF80200FFFE08201FF02828CFE60820 +9B0B:3F042018FF62220C7F7010100820FFFE00003E0822483E4822483E4822082618 +9B0C:3F042018FF62220C7F7004007FFC08801FFC28104FF088100FF0081008500820 +9B0D:3E0420183E6020043E182062FF0422187F60107CFF44107C7E44427C7E44428C +9B0E:3F0820303EC42018FF62220C7F7004047FC404243FA424A43FA4150424944408 +9B0F:3E0420183E6020043E182062FF0422187F6000007C101052FE94382854449282 +9B10:3F042018FF62220C7F7001081FD001207FFC06201C4463FC00001FF811081FF8 +9B11:3F042018FF62220C7F7008407FFC04803FF00490FFFE04903FF00CA03498C486 +9B12:3F042018FF62220C7F7001007FFC01001FF0101011101110FFFE082010102008 +9B13:3F042018FF62220C7F70020001007FFE40229FC410001FF81080FFFE10202010 +9B14:3F042018FF62220C7F70210013F0151000E0775C11F0104013FC284047FE0000 +9B15:3F042018FF62220C7F700820FFFE08201FF010101FF01010FFFE08203018C006 +9B16:3F042018FF62220C7F7008201FF0102025487EFC044018B0E30E0C6003801C00 +9B17:3F042018FF62220C7F7008207FFC08200FE001007FFC5144492455546184410C +9B18:3F042018FF62220C7F7000001FF010101FF010107FFC44447FFC082007C0F83E +9B19:3F042018FF62220C7F7008207FFC511449247FFC00001FF010101FF010101FF0 +9B1A:3F042018FF62220C7F7000000BFE104061FC090411FC610405FC090431FCC088 +9B1B:3F042018FF62220C7F7002003FF82448238824483FF829482528294A25263182 +9B1C:3F042018FF62220C7F7000007C7C44447C7C47C47C7C47C4444447C4444448CC +9B1D:3F042018FF62220C7F7C44447C7C44447C7C40044FE448244FE448244FE4400C +9B1E:3F042018FF62220C7F7002401FF812481FF812483FFC20003FFC28884A708C0E +9B1F:3F0820303EC42018FF62220C7F7001003FF82448FFFE10101FF00C883470C60E +9B20:3F0820303EC42018FF62220C7F7002800C603FF8D55613901FF00A2009200FE0 +9B21:3F042018FF62220C7F7001007FFC4204A92847E400003FF82448FFFE01000300 +9B22:3F042018FF62220C7F7001007FFE40029FF4092011C00FF818886FF804100808 +9B23:3F042018FF62220C7F701084210810843FF82448238824483FF8294A25263182 +9B24:3F042018FF62220C7F700100FFFE22883EF804403FF80440FFFE04901C60671C +9B25:00005E7A44225E7A44225E7A40024002400240024002400240024002400A4004 +9B26:00005E7A44225E7A44225E7A4082448242824882448240F25F824082408A4084 +9B27:00005E7A44225E7A44225E7A420241025FF241024FE2492249A24942410A4104 +9B28:00005E7A44225E7A44225E7A4002444244424FE2444244425FF24442482A4004 +9B29:00005E7A44225E7A44225E7A42024CE248224EE248224FE242824492587A4004 +9B2A:BEFA8822BEFA8822BEFA8002BF1280129EFE921292929E5292128F12B8529026 +9B2B:BEFA8822BEFA8822BEFA80029C42847ABF5292929E1292529E2293A2FE528296 +9B2C:BEFA8822BEFA8822BEFA8806B3BAAAA2BBA28A3EBBAAA0AABBAA8A2A8BAABC46 +9B2D:BEFA8822BEFA8822BEFA8006BBBAAAA2BBA28A3EBBAAA0AABBAA8A2A8BAABC46 +9B2E:BEFA8822BEFA8822BEFA8102BFF2A012BCF28482B4F29492FCF29482B49283F6 +9B2F:09202448228829282288244829283FF81000103811C01E04100410040FFC0000 +9B30:2288F93E2288729CA92A228800007FFE4A12A4A42AC83F9010241F4810101F20 +9B31:2208F3BC2508739CAD6A27C800007FFE4A12A4A42AC83F9010241F4810101F20 +9B32:0000FFFE00001FF0101010101FF000007FFC482444445FF44104410441144008 +9B33:01FC01003FFE210221F02F0420FC20003FFE220823F820002FFE29124BFA8842 +9B34:0014FE1200FE7C1044107CFE0092FE9282FEAA929292FEFE9292929292928686 +9B35:3E7C48907EFC142A66C60400FFFE00001FF010101FF000007FFC44444FE4410C +9B36:10F87CA810A8FE52288E4500FFFE00001FF010101FF000007FFC44444FE4410C +9B37:0028FE9200AA7C8244FE7C280044FEA2823CAA449244FEA89210922892448682 +9B38:0020FEDE008A7CCA44AA7CD200A6FE0082FEAA929292FEFE9292929292FE8682 +9B39:08F83E8808F87E8808F81452228E4100FFFE10101FF000007FFC44444FE4410C +9B3A:0040FE7E00807D7C44447C7C0044FE7C8200AAFE9240FEFE932A924A92928626 +9B3B:711C1544711C47D0739C1544310C0000FFFE10101FF000007FFC44444FE4410C +9B3C:020004003FF8210821083FF8220822083FF8051009200948117C2102410280FE +9B3D:080410047F08491049247F04490849107F2210021A042C882F904820480287FE +9B3E:081010107F7E491049107F10497C49047F4410281A102CA82FC44884480287FE +9B3F:0808101C7F60494049407F7E494849487F4810481A482C882F884800480287FE +9B40:081010107F28492849447F82492849287F2810281A282CA82FA84848480287FE +9B41:080810487F28492849087F48492849287F0E10F81A082C882F884808480287FE +9B42:002000407DFC0124012401FCFF24212421FC2040486844B2FCBE45200122021E +9B43:102820247C2055FE54207C20547C54447C5410882A942D244F40480287FE0000 +9B44:1020104021FC7D24452445FC45247D2445FC4440446844B27CBE45200122021E +9B45:081010107F10497C49107F1049FE49107F3810541A922C902F904810480287FE +9B46:101420127C1054FE54907C94549454887C8A10DA2AA62D424F00480287FE0000 +9B47:3FFC20903FFC21402630388C21002FF828882FF828882FF8415042FA8C8A307E +9B48:081010547F384910497C7F444944497C7F4410441A7C2CC42FC4484C480287FE +9B49:100021FC7C50545055FC7D54555455547DAC11042B042D144F08480287FE0000 +9B4A:101020147C1257FE54107DD4555455D47C1810CA2B162D224F40480287FE0000 +9B4B:082810247F40497E49C87F48497E49487F48107E1A482CC82FFE4840480287FE +9B4C:082410247F7E492449247F3C4924493C7F2410241A7E2C802FA84844480287FE +9B4D:100021FC7D04558C55547DFC554455247DFC11442B742D044F0C480287FE0000 +9B4E:23FE4020F820ABFEAA22FB32AAAAAB76FA66222256225A2A5E0450024FFE8000 +9B4F:0C20704011FCFF24392455FC9324012411FCFC40246844B228BE11202922C61E +9B50:108820507DFE545055FC7C5457FE54547DFC10502AD82D544F52485287FE0000 +9B51:104020207DFC545055247D5455FC54207DFC11442B542D744F0C480287FE0000 +9B52:100021FC7C5055FC55547DFC540054F87C0011FC2AA82D244F60480287FE0000 +9B53:11FC21247DFC552455FC7CA855FC54A87CA811FC2A202DFC4F20482287FE0000 +9B54:00803FFE24103F7C26382D5435122FF828882FF828882FF8215042F84C8AB07E +9B55:109421187DDE5494555A7DDE549455FE7C9010D42AAA2D164F20480287FE0000 +9B56:1020203E7C2055FE55227D3C55E2551E7D2811AA2A6C2D284F7C480287FE0000 +9B57:1020FE4010FC7C940094FEFC02A47CA410FCFE200044FF6A026EFFA0AAA2E71E +9B58:3FFE28882F8A20082FBE28882F88289429A227F8248827F8248847F842528C3E +9B59:42043FD88A904F9E2A945FD482241FF011101FF012101FF004A808BA3082C07E +9B5A:040004000FE0102020407FF8A10821083FF8210821083FF80000488844448444 +9B5B:200020007CFE442288227E22522252227E22522252227E420042AA82AA940108 +9B5C:202020207C20442088207E20522052207E50525052507E500048AA88AA840102 +9B5D:100410043E04422484247F24492449247F24492449247F24000455044A948A88 +9B5E:208020407C20442088107E10521052287E28522852287E480044AA44AA840102 +9B5F:200020007C7C441088107E10521052107E10521052107E100010AA10AAFE0000 +9B60:2008203C79E0482090207C205420543E7DE0542054207C220022AA22AA1E0000 +9B61:204020407C40447C88847E84530452447E24522452047E040004AA04AA280010 +9B62:200020007CFC440488047E04520452FC7E84528052807E800082AA82AA7E0000 +9B63:200021F87C08445088207E1053FE52227E24522052207E200020AA20AAA00040 +9B64:205020507850489290927D94569854907CB054D054907C900092AA92AA8E0080 +9B65:200020FC7C44444888487E50525C52447E44524452687EA80090AA98AB240042 +9B66:201020107C10441088547E52525252907E10521452047E080008AA10AA2000C0 +9B67:202020107C1044FE88007E00527852487E48524852487E4A004AAA8AAA860100 +9B68:202020207C2045FC88207EA852A852A87EA852A852F87E220022AA22AA1E0000 +9B69:204020407C40447E88AA7F2A522A524A7E4A529253127E220022AA42AA940008 +9B6A:201020107C10442888287E44528252487E48524852487E480048AA88AA880108 +9B6B:201020107C10441088FE7E92529252107E28522852287E280048AA4AAA8A0106 +9B6C:2008201C79E0490091007DFC554455447D44552855287D100110AA28AA440482 +9B6D:200020FC7C00440088007EFE525052507E50525052507E520052AA92AA8E0100 +9B6E:201020907C90449288927E9452F452987E90529052907E9200B2AAD2AA8E0000 +9B6F:08001FE020207FF8A1083FF821083FF8444482221FF010101FF010101FF01010 +9B70:204020207C2045FE88887E88528852887E88525052507E200020AA50AA880106 +9B71:200021FE7C20442088207E3C524452447E44528452FC7E080008AA08ABFE0000 +9B72:202020107C10447E88427E425242527E7E42524052407E400040AA80AA800100 +9B73:200023FE7820482090207DFC552455247D24552455247D340128AA20AA200020 +9B74:202020107C1045FE88407E405240527C7E44524452447E440044AA44AAA80110 +9B75:200820287C28442888447E445282537C7E24522452247E240044AA44AA940108 +9B76:201020107C1044FE88927E92529252AA7EAA52CA52827E820082AA82AA8A0084 +9B77:204820447844484091FE7C50545054507C50545054507C520052AA92AA8E0100 +9B78:201020907890489090907CFE548054807C8054F854887C880088AA88AA880108 +9B79:2008201C7CE0442088207E3C52E052207E20523E53E07E200022AA22AA22001E +9B7A:200020007DFE440488047EF4529452947E94529452F47E940004AA04AA140008 +9B7B:200021FC7924492491247DFC552455247D2455FC55247C200020AA20AA200020 +9B7C:20202020782049FC90207C20542055FE7C20542054407C480084ABFEAA820000 +9B7D:204420447C44444488FE7E44524452447E44527C52447E440044AA44AA7C0044 +9B7E:200021FE7C10441088207E20526852A47F22522252207E200020AA00ABFE0000 +9B7F:202020207850485090887D24561254107DFC540454087C880050AA20AA100010 +9B80:202020107C1044FE88827E84524052447E48525052607E420042AA42AA3E0000 +9B81:205020487848484091FE7C405440547C7CA454A454A87D280110AA28AA440082 +9B82:200020FE7C82449288927E92529252927E9252AA52A67EC60082AA82AAFE0082 +9B83:200021FC7C20442089247EA452A852207FFE522052207E200020AA20AA200020 +9B84:20502050785049FC90547C5455FC55507D5055FE54527C52005AAA94AA900110 +9B85:201020087C08440288227E24522452A87EAC52B253327E200062AAA2AB1E0000 +9B86:088028882EF028842E84F07C08000FE010403FF051101FF011101FF024884244 +9B87:20202020782049FC90207C20542057FE7C7054A854A87D240124AA22AA200020 +9B88:204020407C4044FC88847F0452F452947E94529452947EF40094AA04AA280010 +9B89:200021FC7C44444488447E44529452887F0052FC52847E840084AA84AAFC0084 +9B8A:201020107C2044FE88827E82528252827EFE528252827E820082AA82AAFE0082 +9B8B:201020107C10441088FE7E92529252927E9252FE52927E920092AA92AAFE0082 +9B8C:201020087C0844FE88107E10522052427EFC524852107E200044AAFEAA420000 +9B8D:20102010781049FE91127D14551055FC7D44554455287D280110AA28AA440482 +9B8E:201020107C104410881E7E10521052107EFE528252827E820082AA82AAFE0082 +9B8F:202020207920492091FC7D20562054207C2055FC54207C200020AA20ABFE0000 +9B90:202020207C20444088487E8453FE52827E0052FC52847E840084AA84AAFC0084 +9B91:204020407CFC448489047EF4529452947EF4528452947E880082AA82AA7E0000 +9B92:204420447844488490BE7D84568454A47C94549454847C840084AA84AA940088 +9B93:204020407C40447E88A07EA05320523C7E20522052207E3E0020AA20AA200020 +9B94:200020FE7C80448088807EFC528452847E84528452FC7E800080AA80AAFE0000 +9B95:201020107C10441088FE7E10521052107E7C524452447E440044AA44AA7C0044 +9B96:200020007DFE441088107E205220527C7E4452C453447E440044AA44AA7C0044 +9B97:20402040787C488491887E50542054507C88570654607C100008AAC0AA200010 +9B98:205020547852489290907D9655F856907C90549054907C90008AAA8AAA860082 +9B99:200020EE7C22442288AA7E66522252227E26526A52B27E220022AA22AAAA0044 +9B9A:201020107C1044FE88107E10527C52007E00527C52447E440044AA44AA7C0044 +9B9B:202020207820483C90207C2055FE54007C20542054A87CA40122AA22AAA00040 +9B9C:2008201C79E0490091007DFE550055007D7C554455447D440144AA7CAA440400 +9B9D:111009207FFC0200FFFE08203418CFE610403FF051101FF011101FF024884244 +9B9E:200020FE7C10441088207EFE52AA52AA7EAA52AA52AA7EAA00AAAAA2AA8A0084 +9B9F:2040202078204BFE92027C44544057FE7C88548855087CD00020AA50AA880304 +9BA0:2040204078FC490492087DFE5500557C7D44554455547D480142AA42AA3E0400 +9BA1:205020507850495290D47C58545054587CD4555254507C500092AA92AB12020E +9BA2:20202120792049FC91207E20542057FE7C7054A854A87D240124AA22AA200020 +9BA3:20002040799E491291127D1255D255127D125512555A7D940110AA10AA100010 +9BA4:7F8408241F24212456241804E4140FE810403FF051101FF011101FF024884244 +9BA5:204020407C78448889507E20525052887F0652F852887E880088AA88AAF80088 +9BA6:200020FE7C82448288BA7E82528252BA7EAA52AA52AA7EBA0082AA82AA8A0084 +9BA7:202020207BFE482091FC7C2455FC55207DFE5422542A7C540050AA88AB040202 +9BA8:20802084789848E090827C82547E54007CFC548454847CFC0084AA84AAFC0084 +9BA9:208420487C0044FC88487E48524852487FFE524852487E480048AA88AA880108 +9BAA:2020202079FE484090407CFC548455847EFC548454847CFC0084AA84AA940088 +9BAB:20402020782049FC90007C88550456027C88548854507C500020AA50AA880104 +9BAC:201020107CFE442888447E82527C52007EFE522052407E7C0004AA04AA280010 +9BAD:201020107C7C441088107E1052FE52007E105210527C7E100010AA10AAFE0000 +9BAE:208420447848480091FE7C20542054FC7C20542055FE7C200020AA20AA200020 +9BAF:202020207850485090887D0456FA54007C0054F854887C880088AA88AAF80088 +9BB0:200020007CFE448288827EBA52AA52AA7EAA52AA52BA7E820082AAFEAA820000 +9BB1:20402040784449F490487C5057FE54407C80558456987CE00082AA82AA7E0000 +9BB2:205020547852489290907DBE569054907C9054A854A87CA800A8AAA4AAA400C2 +9BB3:2040204479F4484890507DFE544054807DFE564054807CFC0004AA04AA280010 +9BB4:204820487848488890FE7D885688549C7C9C54AA54AA7CC80088AA88AA880088 +9BB5:208420447C48440088FC7E84528452847EFC524852487E480048AA8AAA8A0106 +9BB6:200020FC7C24442489FE7E24522452FC7E40524052FC7EC40144AA44AA7C0044 +9BB7:20882048785049FC90247C2455FC55207D2055FE54227C22006AAAA4AB200020 +9BB8:2080208078F8490892107DFC552455247D2455FC54507C500090AA92AB12020E +9BB9:201020927C52445488107EFE528252827EFE528252827EFE0082AA82AA8A0084 +9BBA:04407FFC01003FF80400FFFE14002FE0D0403FF051101FF011101FF024884244 +9BBB:201020107C20444488FE7E28524452A27E3C524452447EA80010AA28AA440082 +9BBC:200020FC7804487C90047CFC540055FE7D0254FC54447C440028AA10AA680186 +9BBD:201020107C28442888447EBA521052107EFE521052587E540092AB12AA500020 +9BBE:2004201E79E0482291127C94548054207DFE544454847DC80030AA28AAC40302 +9BBF:200023FE7920492891287DE8552855287D2855E855287D2A013AABEAAA260020 +9BC0:200C21F07820484490887DF0542054447DFE542254207CA80124AA22AAA00040 +9BC1:200021FE7820482091FC7D24552455FC7D24552455FC7D2000A0AA40AAB0030E +9BC2:200021FE7C28442888FE7EAA52AA52AA7EC6528252827EFE0082AA82AAFE0082 +9BC3:200021FE7820482090FC7C44544455FE7C00540054FC7C840084AA84AAFC0084 +9BC4:202820247824482091FE7C20552054B27CB4546854A87D240222AA20AAA00040 +9BC5:2004200E7BB8488890887D28552E57A87CA856A856A87D3E0100AA80AA7E0000 +9BC6:201420127CFE441088107EFE529252927EFE529252927EFE0092AA92AA920086 +9BC7:2020201079FE490292047CF8540054007DFE545054507C500092AA92AB0E0200 +9BC8:108011F8128820702B8E688068F8A9102BFC2D2429FC292429FC20002154222A +9BC9:200021FC7924492491FC7D24552455FC7C20542055FC7C200020AA20ABFE0000 +9BCA:20401248444420140860738028000FE010403FF051101FF011101FF024884244 +9BCB:2008210878884808912C7CAA54AA54487C48548A558A7C840084AA88AA900060 +9BCC:201020507C50447C88507E90521052FE7E005200527C7E440044AA44AA7C0044 +9BCD:2020201079FE482090487C8455FE54027CA854A854A87CA800A8AAAAAB2A0206 +9BCE:201020147812481091FC7D10551055D47D54555455547D48014AAA9AAA260442 +9BCF:2002203278C2484A904A7C4A55FA544A7CCA54EA555A7D420242AA42AA4A0044 +9BD0:201020107C7C441088107E1052FE52107E105250525C7E500070AA90AA8E0100 +9BD1:20C220347818486491827C2055FE54507C9055FE56927C92009AAA94AA100010 +9BD2:200020FC7C04446888107EFE529252927EFE529252927EFE0092AA92AA920086 +9BD3:2020204078F8488890F87C8854F8548A7C8C55F854187C280048AA88AB280010 +9BD4:200020927C92452489247E92529252007EFE529252927EFE0092AA92AAFE0082 +9BD5:2088208879FC488890887CF8548854887CF8548854887DFE0000AA50AA880104 +9BD6:2020202079FE482090FC7C2055FE54007CFC548454FC7C8400FCAA84AA940088 +9BD7:04407FFC01003FF80400FFFE14102FE8D0463FF051101FF011101FF024884244 +9BD8:201C21E07820482093FE7CA8552456427C4057FE54887D0800D0AA30AA480184 +9BD9:2020201079FE480090FC7C8454FC54007CFC540854107DFE0010AA10AA500020 +9BDA:201C20E0782049FE90707CA8552456227CF8541054207DFE0020AA20AAA00040 +9BDB:200020FE7C92449288BA7E9252FE52827EBA52AA52AA7EBA0082AA82AA8A0104 +9BDC:202020107CFE440088447E2853FE52207E2053FE52447EC40028AA18AA640182 +9BDD:200020FE7C82449288927EFE529252927EBA52AA52AA7EBA0082AA82AAFE0082 +9BDE:200020FC7804487C90047CFC540055FE7D22542054FC7CA400A4AAB4AAA80020 +9BDF:201020107CFE441088107EFE529252FE7E9252FE52107E380054AA92AA100010 +9BE0:201020107C1044FE88107E54525452547EBA521052387E540092AA10AA100010 +9BE1:2050205078504BDE90507C50545055DC7C50545054507C5003DEAA50AA500050 +9BE2:200020207CCE448288827EEE528252827EFE522852287E280048AA4AAA8A0106 +9BE3:200020FC7C84448488FC7E84528452FC7E4052FE532A7E4A0092AB22AA4A0084 +9BE4:200020FC7884488490FC7C84548454FC7C00549054927CF40098AA92AAD2008E +9BE5:2020202078FC482090207DFE544854847D22542054FC7C200020AA20ABFE0000 +9BE6:2088208878E8492C912A7EA8544854A07D1E560054FC7C840084AA84AAFC0084 +9BE7:207C20447C44447C88447E44527C52007EFE528252827EFE0082AA82AAFE0082 +9BE8:204020207DFE440088007EF8528852887E8852F852207EA80124AA22AAA00040 +9BE9:201020107C28444488827F7C520052FE7EAA52AA52FE7EAA00AAAAAAAA820086 +9BEA:2020202078FC482090207DFE544854847D22547854887D480050AA20AA50018C +9BEB:200023E0795C495491547DD4555455547DD4555455487D6803C8AA54AA540062 +9BEC:0640387C08947E241C442A9448080FE010403FF051101FF011101FF024884244 +9BED:200020FC7C08441088FE7E10521052507E2052FE52AA7EAA00AAAAAAABFE0000 +9BEE:202020107CFE448288007E7C520052007EFE521052107E540052AA92AA500020 +9BEF:20822082728293EA248AF88AAFFAA88AFBEAAAAAAAAAFAAA02A2AAE2A88A0084 +9BF0:201020107C28444488A27F1052FC52047E08522052107E0400A2AAA2AAAA0118 +9BF1:201020107C1E441088FE7E92529852F07E92528E52807EB800A8AAAAAB4A0286 +9BF2:2088204878084BF491147D22550055E87D24552455207D300128AA24AAA40440 +9BF3:2040202073FE9200221CFAF0AA90AA90FAFEAA90AA90FA9002AAAACAACA60812 +9BF4:200021FC7804483491C47C44544455F47D54555455F47C440054AA76AB960002 +9BF5:20402048788449FE90207DFE548855247E42558854107C2200C4AA18AA600180 +9BF6:200020FE7C92441088FE7E10527C52547E7C5254527C7E1000FEAA10AA100010 +9BF7:2000207C7C44447C88447E7C520053FE7E105210525E7E500050AAB0AA9E0100 +9BF8:2040205C7C44448488BE7E905390529E7EA8528852BE7E880088AA94AA9400A2 +9BF9:200021FC790449FC91047DFC542055207DFE562054207DFC0020AA20ABFE0000 +9BFA:2020202479F4482890287DFE542054407CFC558456847CFC0084AA84AAFC0084 +9BFB:2082208273E29082208AFBEAAAAAAAAAFBEAA88AA9CAFAAA04A2A882A88A0084 +9BFC:202820927CAA448288FE7E28524452A27E3C524452447EA80010AA28AA440082 +9BFD:200020EE7CAA44AA88AA7EEA52AA52AA7EEA528A52CA7EAE00D8AA88AA080008 +9BFE:2040207E784848BE90AA7DAA56BE54AA7CAA54BE54C87CA80090AA98AAA400C2 +9BFF:2020201079FE490291027DFE550055007DFE55AA56AA7CFE00AAAAAAAAAA0086 +9C00:201E23E07844492490887DFC544054407DFE548054FC7D440128AA10AA680186 +9C01:201020207CFE448288FE7E8252FE52107E1252D452587E540094AA92AB500020 +9C02:200221E27922492A91EA7D2A552A55EA7D2A552A55EA7C0200C2AAA2AB2A0204 +9C03:200020FC78A448A490FC7CA454A454FC7C0055FE54907C940088AAA8AAC40082 +9C04:200C200A700893FE2208FBF8AA4AAA4AFBEAAAACAAACFA4C02AAAB0AAA160422 +9C05:2000207C7C544454887C7E545254527C7E1052FE52927E9600BEAA82AA8A0084 +9C06:2020202079FE482090FC7C4055FE54887D0456FA54887C8800F8AA88AA8800F8 +9C07:200020FC7848483091FE7C52549455107E30542055FE7C7000A8AB24AA220020 +9C08:201420547C5444FE88547E54525C52407E7E521052FE7E100038AA54AA920010 +9C09:201020207C7C4444887C7E44527C52007EFE521052107E7C0010AA10AAFE0000 +9C0A:202020207BFE482091FC7D2455AC55747D2455FC54207C7000A8AB24AA220020 +9C0B:200021FE7900497E91427D7E5542557E7D1055FE55247D640118AB24AB4201FE +9C0C:204420247C2844FE88287E2852FE52AA7EAA52C652827EFE0082AA82AAFE0082 +9C0D:200820687988488890AA7CAC55E854A87C8855C856A87C880094AA94AA9400A2 +9C0E:20102010783C4B9490FE7C94553C55107FBC549054FE7E900190AAC0AABE0100 +9C0F:200020FE7C00447C88447E44527C52007EFE529252927EFE0092AA92AAFE0082 +9C10:200021DC7954495491DC7C0055FC54007DFE548054FC7C040004AA04AA280010 +9C11:200020FC788448FC90847CFC540055FE7C8054FE552A7E4A0092AB22AA540088 +9C12:204020407CFE448089FC7E8452FC52847EFC5240527C7EC40128AA10AA680186 +9C13:200021FC7924492491FC7D24552455FC7C20541054547D420142AB4AAA380000 +9C14:2008200C700A93FE2208FA08AAE8AA0AFA0AAAECAAACFAA802EAAA1AAA260442 +9C15:200021DC7944494491447DDC550055007DDC551455147DD40108AB08AB140122 +9C16:2020202079FE484090FE7D1056FE54007CFE548254FE7C8200FEAA82AA8A0084 +9C17:2080209E78924BF290927C9E549255D27D52555E55527D5201D2AA22AA2A0044 +9C18:2040202079FE490292047DFC544054887DFC542454207DFC0020AA20ABFE0000 +9C19:2084208479FE488490A47C2055FE54407C8054FC55847E840084AA84AAFC0084 +9C1A:2020201079FE490292047CFC540054FC7C8454FC54847CFC0084AA00AAFE0000 +9C1B:200020F87888488890F87C88548854F87C0055FC55547D540154AB54ABFE0000 +9C1C:20882050780049FE90507DFC545457FE7C5455FC54507CD80154AA52AA500050 +9C1D:202020107CFE4400887C7E44527C52007EFE528252BA7EAA00BAAA82AA8A0084 +9C1E:202020407CFC448488847EFC528052FE7E8052FE52027EAA00AAAA02AA140008 +9C1F:202020107CFE440088447E2852FE52A27E1052FE52207E3C0024AA44AA540088 +9C20:200021FC78A4488890507C2054D857267C2055FC55247D2401FCAA22ABFE0002 +9C21:202020DE7C8A44CA88AA7ED252A652007EFE529252927EFE0092AA92AAFE0082 +9C22:200020FE789048FC90907CFC549054907CFE540254AA7CAA00AAAA82AA140008 +9C23:2008200879C8497E91487D48557E55C47D44557E55447D6401D4AA04AA140008 +9C24:2100227E7388928822BEFAAAABAAAA2AFA2AABAAAAAAFAAE0288AB88AA880008 +9C25:200020FE7CAA44AA88AA7EFE521052547E52529252107E540052AA92AA100010 +9C26:2084204478484BFE90847C845508554A7E52579C54847D080108AA52ABDE0042 +9C27:012478A849FC48404BFE79084A844CFA49107BFC4D2449FC492449FC48009954 +9C28:200021F8790849F891087DF8540054007DDC544455547CCC0154AA44AA5400C8 +9C29:2004201E79E0480291227C9454FE55107C1055FE54107C920092AA92AAFE0002 +9C2A:201020107C7E441088107EFE522052427EFE520052FE7EAA00AAAAAAABFE0000 +9C2B:2040202079FE490290507C88552454507C88550456FA7C880088AA88AAF80088 +9C2C:2020203C782049FE91227D3855E4551C7D20551055FE7D440128AA10AA2804C6 +9C2D:2020202478F4482891FE7C20547854C27D3E560054FC7C8400FCAA84AAFC0084 +9C2E:200020F878A848A890D87C8854F854007C0055FC55547D540154AB54ABFE0000 +9C2F:200021DC7844484491DC7D10551055DC7C44555454CC7CCC0154AA44AA5400C8 +9C30:220821087908483E93AA7CAA54BE552A7DAA576A553E7D2A0108AB08AB080108 +9C31:201020107AFE4910917C7C54547C57547D7C551055FE7D100110AA90AA7E0000 +9C32:08207E20087EFEC410281E102A284FE690403FF051101FF011101FF024884244 +9C33:2148214873E8914821DEF88AABEAAAAAFAAAABEAA88AFBEA0092A892A8AA00C4 +9C34:11101550255047D0903E17A422546394A49427D42D5427C8254827D420142AA2 +9C35:20203F20403EBE482AA8FF284A107FE810463FF051101FF011101FF024884244 +9C36:2080208879EE492A92AA7D445484557A7E00540055FE7C2000A8AB24AAA20040 +9C37:2110211E712292542208FE94AAE2AA88FA88AABEAA88FAAC022AAA4AAA280210 +9C38:200023FE7200927C2244FA44AA7CAA00FAEEAAAAAAAAFAAA02EEAA00ABFE0000 +9C39:200021EE794A49EA912A7DE45544554A7DF0540054107CFE0010AA10ABFE0000 +9C3A:201020207C4444FE88447EAA52EE52107E28525452AA7E500024AA48AA100060 +9C3B:207C20447C7C4444887C7E0052FE52AA7EFE520052FC7E440028AA10AA680186 +9C3C:200021DE7842495290CA7D52544254207CFC548454847CFC0084AA84AAFC0084 +9C3D:2050205079FE485091FC7D5455FC55547DFC540054F87C8800F8AA88AAF80088 +9C3E:200023FE785049FC91547D5455FC54007DFC540057FE7C2000A8AB24AAA20040 +9C3F:201021FE781048FC90107DFE540054FC7C8454FC54847CFC0084AAFCAA480084 +9C40:7DFC44207D2045FE7C50485254926FEE10403FF051101FF011101FF024884244 +9C41:2000213E78884890902A7C4A571C552C7D4A551A552A7D480128AA90AA7E0000 +9C42:20482148795E496A91547DC8545054647FC4557E55447D640154AB44AA540448 +9C43:2084204879FE481090FC7C2055FE54407C7C54A455247CFC0044AA44ABFE0000 +9C44:202023FE782049FC91247DFC552455FC7C2255FE54087DFE0108AA88AA280010 +9C45:201021FE7910497C91147DFE5514557C7D10557C55547D7C0154AA7CAA54044C +9C46:201020FE7C44442888FE7E00527C52447E7C5244527C7E1000FEAA10AA100010 +9C47:2020201079FE4910917C7D1455FE55147D7C551055927D540138AA54AA920430 +9C48:200021FC78204BFE92227DAC542055AC7C0055FC54047DFC0004AA04ABFC0004 +9C49:49202A3E7F4849485DA86B1049284FE610403FF051101FF011101FF024884244 +9C4A:20FC2028781049FE90527C94555054207CFE54AA54C67CBA00AAAABAAA820086 +9C4B:2020203C782049FE91227D3855E4551C7D00552855AA7D6C0128AA28AAFE0000 +9C4C:208020F0791049FC93247D2455FC54407CA4555854987D340054AA92AB500020 +9C4D:201221D478484A8A91047E0255DC54547C6255C0551E7DC20054AA48AB5400A2 +9C4E:201821E078404BFE90887D74565254707C0055FC55047D740154AB74AB04010C +9C4F:200020FE7C2844FE88AA7EFE5200527C7E44527C52447E7C0010AAFEAA100010 +9C50:202021FC702493FE2024F9FCA820AAAAFBAEAA22ABFEFA2203AEAAAAAAAA0422 +9C51:2048204878FC484890487DFE542054FC7CA454FC54A47CFC0000AA48AA840102 +9C52:2088205079FE485091FC7D54559C55047DFC550455FC7C0801FEAA88AA480018 +9C53:200021DC7954495491DC7C0055FC55247DFC552455FC7C2003FEAA20AA200020 +9C54:2044202879FE481090FE7C1055FE54927C5455FE54007CFE0082AA82AAFE0082 +9C55:201C21E078A4486891FE7CA8552456027CFC54A454A47CFC00A4AAA4AAFC0084 +9C56:200023FE7200931422A4FBF6AA4AAA42FB50AB54ABF4FA44024AAA8AAC920920 +9C57:201020927854481091FE7C54549255107C8454EE55247CB4005EAA44AA840104 +9C58:200021FE780249FE90027DFE540055DE7C9257DE54047DFE0084AA44AA540008 +9C59:2020202078FC482091FE7C8855DC54887CC855BC54007DFE0050AA50AA94010C +9C5A:201020107CFE4410887C7E00527C52447E7C522852FE7E00007CAA44AA7C0044 +9C5B:204420247C2844FE88927ED652BA52927EFE5200527C7E44007CAA44AA7C0044 +9C5C:2280224E74EA95AA29AAFEEAAAACACAAFDEAAF8AAA8AFAAA04ACACE8A8A80008 +9C5D:202021FC7820488893FE7C8855FC55047DFC550455FC7D0401FCAA88AB040202 +9C5E:200021FC7954495491FC7C0057FE54007DFC550455FC7C620094AB88AAA400C2 +9C5F:0A803138228839382288FFFE88020FE010403FF051101FF011101FF024884244 +9C60:202020507888497492027DFC552455AC7D2455FC54007CF80088AAF8AA8800F8 +9C61:2008200C738A92FE2288FBA8AAA8AAAAFBFAAAAAAAACFBAC002AAAAAAC560022 +9C62:20F82088788848F890007DDC555455547DDC542057FE7C7000A8AB24AA220020 +9C63:201021FE780049FE91027D7A554A55FE7C0054FC54847CFC0084AAFCAA0001FE +9C64:2014201273FE921022F0FA14AAF4AAB8FAEAAA16AC42F82402A2AA8AAC780000 +9C65:2020213879204BFE90107C1455FE55107DF0555455547DD40168AA4AAA960122 +9C66:200021FC7954495491DC7C5055DC55547D5455DC55547D5401DCAB50AA52003E +9C67:205021FC795449FC91547DFC540055FC7C0055FC55047DFC0088AA50ABFE0000 +9C68:212420A87BFE4A8A90F87D0C55F055027CFE540055FC7D0401FCAB04ABFC0104 +9C69:200021FC78204BFE92227DAC542055AC7C0055FC55247D2401FCAB24AB2401FC +9C6A:21FC210479FC490491FC7C2255FC54287FFE544055FC7E8400FCAA84AAFC0084 +9C6B:200E21F078A2485491FE7D22541455527D4A563854407C7C0084AB48AA3001CE +9C6C:200021FC78204BFE92227DAC542055AC7C0057FE54207DFC0154AB54AB54010C +9C6D:2040202073FE90882052FFACAAAAAAA8FDACA800A904F9FC0104A9FCA9040204 +9C6E:20A0212C7934492491AC7D34555455DC7D54555457FE7C000048AA44AA820102 +9C6F:204421FE7854484890FE7D9054FE54907CFE549054FE7C8001FEAA44AA3801C6 +9C70:200023FE7A524A5293FE7C2455FC54287FFE542054FC7D8402FCAA84AAFC0084 +9C71:200021FE792849FE91287D7C5554557C7D54557C55107DFE0192AABAAA8A0484 +9C72:212422487124900023FCFA94AA64AA94FBFCAA48AB68FA48036AAA4AAA460362 +9C73:21242174725892DA23FEF954AADAABFEF8A2A820ABFEF87000A8A924AA220020 +9C74:204421FE7C44440088FE7EAA52AA52FE7E1452FE52907ED200ACAAAAAA960122 +9C75:2110211071DE92A82454F812ABFEAA10FAF4AA14AAF4FAA802AAAAFAAA160422 +9C76:208823FE782049FC90407FFE548855247EFA548854F87C8800FAAA94AAA800C4 +9C77:200023FE702093AE22AAFAAAABAEA820FBFEA820ABAEFAAA02AAABAEA82003FE +9C78:2020203E782049FE91227DF85522557E7D54557C55547D7C0100AAFEAAAA05FE +9C79:208823FE7888480091DC7D5455DC54887DFE569054FC7C9000FCAA90AAFE0080 +9C7A:20EE20007CEE44AA88EE7EAA521052FE7EA852FE52AA7EFE00AAAABCAAAA0136 +9C7B:0FE010403FF051101FF011101FF024A85E3424507EFC2A543E7C2A54BE7C95AA +9C7C:040004000FE0102020407FF8A10821083FF8210821083FF800000000FFFE0000 +9C7D:200020007DFC444488447C44544454447C44544454447C8400841D04E1284210 +9C7E:100010001EF8220824087E08AA082AF83E882A802A803E8000820E82707E2000 +9C7F:204020507C48444888407DFE545054507C50545054907C9000921D12E10E4200 +9C80:202020207C2045FE88207D24552455247D2455FC54247C2000221C22E01E4000 +9C81:08001FE020207FF8A1083FF821083FF80000FFFE00001FF010101FF010101FF0 +9C82:102010101E1023FE24407E40AA402A7C3E442A442A443E4400840E8471282210 +9C83:200020007DFC452489247D24552455247DFC550055007D0001021D02E0FE4000 +9C84:200020007DFE440888087DE8552855287D28552855E87D2800081C08E0284010 +9C85:205020487C48444089FE7C405440547C7CA454A454A87D2801101E28E0444082 +9C86:200020007DFC442088207D2454A454A87C2057FE54207C2000201C20E0204020 +9C87:101010101E102210241E7E10AA102A103EFC2A842A843E8400840E8470FC2084 +9C88:101010101E1E221024107EFEAA822A823E822AFE2A823E8000800F0071002200 +9C89:202020207C20442089FC7D24552455247D2455FC55247D2401241D24E1FC4104 +9C8A:104010401E40227E24A07EA0AB202A3E3E202A202A203E3E00200E2070202020 +9C8B:204420447C44448488BE7D84568454A47C94549454847C8400841C84E0944088 +9C8C:101010101E2022FC24847E84AA842A843EFC2A842A843E8400840E8470FC2084 +9C8D:204020407CFC448489047EF4549454947CF4548454947C8800821C82E07E4000 +9C8E:2208111000207FFC440484080FC010403FF051101FF011101FF00000FFFE0000 +9C8F:201020107C1045FE89127D14551055FC7D44554455287D2801101E28E2444482 +9C90:102010201E20224024487E84ABFE2A823E002AFC2A843E8400840E8470FC2084 +9C91:202020207DFC442088207C2057FE54007C20542055FC7C2000201C20E3FE4000 +9C92:202020207C2047FE88207C2055FC54007C0055FC55047D0401041D04E1FC4104 +9C93:204020447DF4444888507DFE544054807DFE564054807CFC00041C04E0284010 +9C94:202020207DFE444088407CFC548455847EFC548454847CFC00841C84E0944088 +9C95:200021FE7C20442088407DFC555455547D54555455547D5401541D54E104410C +9C96:200021FC7D04450489747D04550455747D54555455547D7401041D04E1144108 +9C97:400243E27A228A2A12AAFAAAAAAAAAAAFAAAAAAAAAAAF88201421922E20A4404 +9C98:2008201C7DE0450089007DFE550055007D7C554455447D4401441E7CE2444400 +9C99:202020207C50448889047E0254F854007C0057FE54207C4000881D04E3FE4102 +9C9A:204020207DFE448888507C20545054887D06548854887C8800881D08E1084208 +9C9B:204020207C2045FE88007C88550456027C88548854507C5000201C50E0884306 +9C9C:108210441E2822FE24107E10AA102A7C3E102A102A103EFE00100E1070102010 +9C9D:04407FFC01003FF80400FFFE14002FC0D0403FF051101FF011101FF00000FFFE +9C9E:111009207FFC0200FFFE08203418CFC610403FF051101FF011101FF00000FFFE +9C9F:200021FC7C04440488FC7C04540455FC7C08540855FE7C8800481C48E0084018 +9CA0:200021FE7C20442089FC7D24552455FC7D24552455FC7D2000A01C40E0B0430E +9CA1:400043FE7800880013DEFA52AA52AA52FB5AAAD6AA52FA5202521A52E25242D6 +9CA2:401042107910897E1020F828AF48A97EF908A908A9FEF90801081A88E47E4000 +9CA3:2040217E7D52455289547D48555454627C10541054FE7C1000101C10E1FE4000 +9CA4:200021FC7D24452489FC7D24552455FC7C20542055FC7C2000201C20E3FE4000 +9CA5:400440047BC48A44127EFA44AA44ABE4FA54AA54AA44FA4403C41A44E0144008 +9CA6:204020407CF8448889507C2054D857267C2055FC54207D2801241E24E0A04040 +9CA7:200C21F07C20444488887DF0542054447DFE542254207CA801241E22E0A04040 +9CA8:20401248444420140860738028000FC010403FF051101FF011101FF00000FFFE +9CA9:202020107DFE45028A047CF8540054007DFE545054507C5000921C92E10E4200 +9CAA:100010FC1E24222425FE7E24AA242AFC3E402A402AFC3EC401440E44707C2044 +9CAB:400043DE7A528A521252FBD2AA52AA52FA52ABD2AA1AFA9402501AB0E3104010 +9CAC:200021F87C0844D088207DFC552455247DFC552455247DFC01241D24E124410C +9CAD:202020207DFE442088FC7C2055FE54007CFC548454FC7C8400FC1C84E0944088 +9CAE:202020207CFC442088207DFE544854847D22547854887D4800501C20E050418C +9CAF:208820887DFC448888887CF8548854887CF8548854887DFE00001C88E1044202 +9CB0:200023E07D5C455489547DD4555455547DD4555455487D6803C81C54E0544062 +9CB1:205020507C5047DE88507C50545055DC7C50545054507C5003DE1C50E0504050 +9CB2:200021FC7D04450489FC7D04550455FC7C00551255D47D1801101D52E192410E +9CB3:20FC20847C8444FC88847C8454FC54007DFE550255027DFE01021D02E1FE4102 +9CB4:200021FC7D04452489247DFC552455247D74555455547D7401041D04E1FC4104 +9CB5:200020407D9C450489047DDC550455047DFC545054507C5000901C92E112420E +9CB6:40204020785088881144FA22A9F8A808F850A820A8A4FA82028A1A8AE4784000 +9CB7:200021FC7D24452489747D2455FC55047D74555455547D7401041E04E2144408 +9CB8:204020207DFE440088007CF8548854887C8854F854207CA801241E22E0A04040 +9CB9:204020487C8445FE88207FFE548855247E42558854107C6201841C18E0604380 +9CBA:200021FC7C04443489C47C44544455F47D54555455F47C4400541C76E1964002 +9CBB:209220927D24464889247C92549254007DFE552255227DFE01221D22E1FE4102 +9CBC:202021FC7C2044888BFE7C88540055FC7D04552455247D2401241C50E0884304 +9CBD:4048414879488BFE1148F948A978A900F9FEA820ABFEF87000A81924E6224020 +9CBE:100010FE1E00227C24447E44AA7C2A003EFE2A922A923EFE00920E9270FE2082 +9CBF:202021247CA8442089FE7D02540054F87C00540055FE7C2000401C88E1FC4084 +9CC0:100010FC1E84228424FC7E84AA842AFC3E002BFE2A203EA000BC0EA07160223E +9CC1:200020F87C88448888F87C88548854F87C0055FC55547D5401541D54E3FE4000 +9CC2:200021FC7D24452489FC7D24552455FC7C0057FE55207D2201141D48E1844102 +9CC3:200021FC7D24452489FC7D24552455FC7C20541054547D4201421D4AE2384000 +9CC4:200021DC7D54455489DC7C0055FC54007DFE548054FC7C0400041C04E0284010 +9CC5:400840C87B088908112AF92AABACA948F908AB88AD54F91401141924E1244142 +9CC6:204020407CFE448089FC7E8454FC54847CFC5440547C7CC401281C10E0684186 +9CC7:202020407DFC450489FC7D0455FC54007FFE542054207DFC00201C20E3FE4000 +9CC8:204020807DFC450489FC7D0455FC54207C3257B454A87D2801241E24E4A24040 +9CC9:209020907C9E46A289D47C88549454A47DFE568454A47C9400941C84E0944088 +9CCA:202020107DFE450289027DFE550055007DFE55AA56AA7CFE00AA1CAAE0AA4086 +9CCB:200021FC7CA4448888507C2054D857267C2055FC55247D2401FC1C22E3FE4002 +9CCC:08207E20087EFEC410281E1022284FC690403FF051101FF011101FF00000FFFE +9CCD:204020447DF844508BFE7C4054F855827E7E540055FC7D0401FC1D04E1FC4104 +9CCE:200020FC7C8444FC88847CFC540054007DDC544455547CCC01541C44E1544088 +9CCF:200021FC7D54455489547DFC542054A87CA4552454207CA800A41D24E0204020 +9CD0:2004201E7DE0440289227C9454FE55107C1055FE54107C9200921C92E0FE4002 +9CD1:202020107DFE448488487DFE550256247C1055FE54407C7C00441C84E0944108 +9CD2:208820507C0045FE88507DFC545457FE7C5455FC54507CD801541E52E0504050 +9CD3:414841487BE8894811DEF88AABEAAAAAFAAAABEAA88AFBEA00921892E0AA40C4 +9CD4:200023FE7C5045FC89547D5455FC54007DFC540057FE7C2000A81D24E2A24040 +9CD5:200021FC7C2047FE8A227DAC542055AC7C0055FC54047DFC00041C04E1FC4004 +9CD6:49202A3E7F4849485DA86B1049284FC610403FF051101FF011101FF00000FFFE +9CD7:400041F8790889F81108F9F8A800ABFCFA94ABFCA800F9F800901860E1984606 +9CD8:20203F20407EBEA82A28FF104A287FC610403FF051101FF011101FF00000FFFE +9CD9:201021FE7D10457C89147DFE5514557C7D10557C55547D7C01541E7CE254444C +9CDA:400443E47A248A2413EEFA04AAE4AA04FA0CABF4AA44FA6405541D44EA5440C8 +9CDB:200021DE7C42455288CA7D52544254207CFC548454847CFC00841C84E0FC4084 +9CDC:400043FE7A008B1412A4FBF6AA4AAA42FB50AB54ABF4FA44024A1A8AE4924920 +9CDD:408840507BFE882011FCF820ABFEA924F8A8ABFEA800F9FC01041904E1FC4104 +9CDE:4020412478A88BFE10A8F924AA22A904F904A9DEAA44FD54009E1904E2044404 +9CDF:208820507DFE445089FC7D54559C55047DFC550455FC7C0801FE1C88E0484018 +9CE0:208823FE7CA8449089FE7F2055FC55207DFC552055FE7D0003FC1C88E070438E +9CE1:401440127BFE8A1012F0FA14AAF4AAB8FAEAAA16AC42F82402A21A8AE4784000 +9CE2:205021FC7D5445FC89547DFC540055FC7C0055FC55047DFC00881C50E3FE4000 +9CE3:201021FE7C0045FE89027D7A554A55FE7C0054FC54847CFC00841CFCE00041FE +9CE4:210821087DEE469488427C1055FE55027CF8548854F87C8000FC1C84E0FC4084 +9CE5:020004001FF010101FF010101FF010001FFC10001FFC09242494249440280010 +9CE6:100020007F3E41027F0441047F0840087F9040107FA000A2AAA2AAA2811E0600 +9CE7:08003FE020203FE020203FE020003FF820003FF8524889281FD810422042C03E +9CE8:101020107F1041107F7E41127F1240127F9240127F920092AAA2AAA2814A0684 +9CE9:2040208021FC2104F9FC290429FC290029FE29002BFE2C024AAA42AA8202000C +9CEA:2040208021FC210421FC290425FC250025FE210021FE200222AA22AA2202200C +9CEB:00003FFE2100220027F0241027F0241027F0240027FC240027FC40044AA48AAC +9CEC:04001FF010101FF010101FF010001FFC10001FFC00040F94088808821082607E +9CED:00400080F9FC290429FC290429FC290029FE290029FE28024AAA4AAA9A02000C +9CEE:0040008001FCFD0405FC050449FC290011FE110029FE240246AA82AA0202000C +9CEF:00007FF844085FC850485FC850485FC850085FE850085FEA402AAAAAAAA60042 +9CF0:0040008081FC410421FC210411FC110029FE290025FE240242AA42AA8202000C +9CF1:00407C8011FC110411FC110411FCFF0011FE110011FE100212AA12AA1202100C +9CF2:004000803DFC250425FC25043DFC250021FE210021FE200222AA42AA4202800C +9CF3:3FF820082FE822082FE828282FE828282FE828082FF828082FFA401A55568032 +9CF4:0040008079FC490449FC490449FC490049FE490049FE78024AAA02AA0202000C +9CF5:0040F88049FC490449FC490449FCF90049FE490049FE48024AAA4AAA4602420C +9CF6:04200210013EFFC002221FFA10161FF010101FF010001FFC10001FFC2A44452C +9CF7:1040108011FCFF0411FC1104FDFC050005FE490029FE10022AAA46AA8202000C +9CF8:01007FFC40047FFC42005FF050105FF050105FF050005FFC50005FFCAA44452C +9CF9:1040108029FC290445FCA50411FC110001FEFD0005FE08020AAA12AA1202000C +9CFA:1040108011FC7D0411FC110411FCFD0011FE110011FE280226AA42AA8202000C +9CFB:0020284024FC248442FC428480FC7C8024FE248024FE240244AA44AA9502080C +9CFC:0040208011FC0104FDFC090409FC490029FE110011FE28022AAA4AAA8202000C +9CFD:00407C8029FC290429FC290429FCFF0029FE290029FE28022AAA2AAA4A02880C +9CFE:0040FE8011FC11047DFC550455FC550055FE550055FE5C0212AA12AA1202100C +9CFF:004000807DFC110411FC11047DFC110011FE110011FE1C02E2AA42AA0202000C +9D00:0040FC8011FC110421FC310469FC6500A5FE210021FE200222AA22AA2202200C +9D01:00400C8071FC110411FC1104FDFC110011FE110029FE280242AA42AA8202000C +9D02:2040208021FCF90429FC290429FC2900FDFE210021FE200232AA4AAA4A02800C +9D03:101020107F1041107F7C41147F1440147F94407E7F900090AAA8AAA881440682 +9D04:00200040FEFCA884A8FCA884A8FCA880AAFEAA80A6FEC00282AAFAAA0202000C +9D05:0040788049FC490469FC590449FCFD0049FE490049FE48024AAA4AAA4A02980C +9D06:1040108011FC7D0455FC910411FC290029FE290029FE2C024AAA42AA8202000C +9D07:4040488051FC610445FC45043DFC110011FE1100FDFE100212AA12AA1202100C +9D08:00007FFE444045FC490449FC590469FC490049FE490049FE48024AAA8AAA0804 +9D09:0040FC8009FC490449FC490489FCFF0019FE190029FE28024AAA8AAA2A02100C +9D0A:00400080FDFC110411FC110451FC5D0051FE510051FE50025EAAF2AA0202000C +9D0B:2020104000FCFE8420FC20843CFC248024FE248024FE240244AA54AA8902000C +9D0C:00003FF801007FFC04401830E20E1FF010101FF010101FFC10001FFC0004492C +9D0D:020001007FFC082007C01830E20E1FF010101FF010101FFC10001FFC0004492C +9D0E:0040FC8081FC8904C9FCA90491FC9100A9FEA900C9FE800282AAFEAA0202000C +9D0F:105020547C5244927C90459E7DF042907E9040907E900290AA8AAA8A82860C82 +9D10:10007E7812482678C2001FF010101FF010101FF010001FFC10001FFC2A44452C +9D11:08007E7812480C3032CEDFF010101FF010101FF010001FFC10001FFC2A44452C +9D12:1040108029FC250443FC910409FC0100FDFE050009FE500222AA12AA1202000C +9D13:2020104014FC048424FC2484AAFCAA80A8FE308032FE220222AA5EAA8102000C +9D14:08401C80E1FC010421FC1104FDFC050009FE090011FE200242AAA2AA1E02000C +9D15:101020087F08417E7F4241427F2040247FA840307FA000A2AAA2AAA2811E0600 +9D16:00207E4042FC42847EFC488448FC48807EFE488048FE48024AAA4AAA6702420C +9D17:2040108011FCFD0401FC090489FC890049FE490051FE50021EAAE2AA4202000C +9D18:1040108021FC4904FDFC050429FC290029FEFD0029FE28022AAA4AAA4A02880C +9D19:2040208021FC7D0451FC910411FC1100FDFE110011FE280226AA42AA8202000C +9D1A:100020007DFE44047C0444F47C9440947E9440947EF40294AA04AA0482140C08 +9D1B:20F83E88449AA882127E3FF0D0101FF010101FF010001FFC10001FFC2A44452C +9D1C:08442F7828422F3EF2001FF010101FF010101FF010001FFC10001FFC2A44452C +9D1D:2020204020FC7E8442FC82847AFC4A804AFE4A807AFE4A0202AA02AA1502080C +9D1E:0040788049FC490449FC790401FCFD0021FE410079FE08020AAA0AAA5202200C +9D1F:04400E80F1FC910491FC9104FDFC910091FE910091FE88028AAAC6AA9202080C +9D20:004000807DFC450445FC7D0445FC45007DFE010001FE1C02E2AA42AA0202000C +9D21:0040788049FC490449FC790449FC490079FE490049FE48024EAAF2AA0202000C +9D22:04082410243C44245FBC94A4E4BC24A044BE44A094BEF48218AA08AA1282210C +9D23:1020104010FC1084FEFC108410FC10807CFE448044FE440244AA7CAA4502000C +9D24:102020207F3C41447F6841A87F1040287FC440827FA00090AA88AAA081100608 +9D25:102020107C1044FE7C8245047C0040287E2840287E280228AA44AA4482440C82 +9D26:01001FF01110FFFE02801C70E20E1FF010101FF010101FFC10001FFC0004492C +9D27:2020104010FCFE8482FC848400FC788048FE488048FE4A024EAA4AAA8202000C +9D28:00407C8055FC550455FC7D0455FC550055FE7D0055FE100212AA12AA1202100C +9D29:1040108051FC51047DFC910411FC1100FDFE110011FE280226AA42AA8202000C +9D2A:2020104010FCFE8482FC828428FC288024FE248044FE400242AA82AA0202000C +9D2B:00400080F9FCA904A9FCA904A9FCF900A9FEA900A9FEA802FAAA8AAA0202000C +9D2C:2208111000207FFE42029FF410101FF010101FF010001FFC10001FFC2A44452C +9D2D:1040208079FC490449FC490479FC410041FE790049FE48024AAA7AAA4A02000C +9D2E:10201040FEFC288444FC82847CFC0080FEFE208040FE7C0204AA04AA2902100C +9D2F:0020FE4010FC108420FCFE84AAFCAA80AAFEAA80AAFEAA02AAAAA2AA8B02840C +9D30:08201C4070FC108410FCFC8410FC10807CFE448044FE440244AA7CAA4502000C +9D31:28402880FDFC290429FC010405FC450029FE290011FE10022AAA2AAA4A02800C +9D32:80208840B0FCC08484FC84847CFC0080F8FE888088FEF8028AAA8AAAFA02880C +9D33:102008407EFC428494FC108410FCFE8024FE248048FE280212AA2AAA4602800C +9D34:10101020277C4044907C10442FFC6240A27E2240227E220222AA22AA2B02240C +9D35:2820284028FC2884AAFC6C8428FC28806CFEAA8028FE28022AAA4CAA4902800C +9D36:1020104010FCFE8410FC10847CFC008000FE7C8044FE440244AA7CAA4502000C +9D37:7F0408441E44224454440844320CDFF010101FF010101FFC10001FFC0004492C +9D38:1040508051FC7D0491FC110411FCFF0031FE390055FE540292AA12AA1202100C +9D39:4440248029FCFF0411FC11047DFC110011FEFF0011FE100222AA22AA4202800C +9D3A:10201040FEFC10847CFC14847CFC50807EFE128012FE160228AA24AA4502800C +9D3B:0020804040FC1F8484FC448444FC048024FE4480C4FE47025CAA48AA4102000C +9D3C:101020107F3C41247F4441287F1040287FC640007FBC00A4AAA4AAA4813C0624 +9D3D:1000FE7C22441C7CE2001FF010101FF010101FF010001FFC10001FFC2A44452C +9D3E:1040108021FC4904FDFC450411FC51007DFE910011FEFC0212AA12AA1202100C +9D3F:2040208051FC490485FC0104F9FC010001FEF90089FE88028AAAFAAA8A02000C +9D40:081813E0304057FC904013F802001FF010101FF010101FFC10001FFC0004492C +9D41:2040108001FCFD0401FC290445FC830009FE490029FE10022AAA4AAA8202000C +9D42:12081210123C22242FBC6224A63C27202ABE2AA0323E2202222A222A2202220C +9D43:1040208079FC490469FC590449FCF90049FE490069FE58024AAA4AAA4A02980C +9D44:0040FE8021FC290445FCFD0415FC110011FE7D0011FE10021EAAE2AA4202000C +9D45:2040208039FC490449FCA90411FC290045FE850079FE48024AAA4AAA7A02480C +9D46:11001200279C44808780148027BE6408A7C8240827C820482548254828682190 +9D47:202020403EFC288448FC08843CFC288028FE2880FEFE08020AAA0AAA0A02080C +9D48:0040FC8049FC490479FC490449FC790049FE49004DFE7802CAAA0AAA0A02080C +9D49:02000100FFFE04401450244842041FF010101FF010101FFC10001FFC0004492C +9D4A:10201040FEFC108410FC548454FC5480BAFE118010FE280228AA44AA8502000C +9D4B:00107E20027C02447E7C4044417C41403F7E1040087E2902A2AAA2AA1F02000C +9D4C:101020107C2844287C4444BA7C1040107EFE40107E580254AA92AB1282500C20 +9D4D:20201040FEFC828400FC7C8400FC0080FEFE288028FE280228AA4AAA4D02800C +9D4E:04201E40E0FC228492FC548448FC1080FCFE248044FE280210AA28AA4502800C +9D4F:1020144010FCFE8410FC7C8454FC54807CFE548054FE7C0254AA54AA55024C0C +9D50:002000407CFC108410FC548454FC5480BAFE108010FE1C02E2AA42AA0202000C +9D51:0040F88089FC8904F9FC0104F9FC890089FEF90089FE8802FAAA8AAA8A02980C +9D52:0040488045FC950411FC290445FC810079FE490049FE48024AAA7AAA4A02000C +9D53:10201040FEFC108410FCFE8482FC048078FE088010FE1E02F0AA10AA5102200C +9D54:101020107C2044447CFE44287C4440A27E3C40447E4402A8AA10AA2882440C82 +9D55:1020104020FC4484FEFC288444FCA2803CFE448044FEA80212AA2AAA4602800C +9D56:004000807DFC450445FC7D0445FC45007DFE410051FE480256AA62AA4202000C +9D57:42102420187C2444527C1044FF7C2040287E7E40AA7E2A022AAA2EAA0902080C +9D58:00107E20127C1244FF7C1244127C7E40207E20407E7E6202A2AA22AA3F02220C +9D59:0040788049FC490479FC490449FC790049FE490079FE000252AA4AAA8A02000C +9D5A:0C20704010FCFE8410FC388454FC928000FE388028FE28022AAA4CAA4902800C +9D5B:0020FE4054FC5484A8FC548454FC0080FEFE108010FE10021EAAF2AA4202000C +9D5C:4420244028FCFC8414FC1484FCFC908090FEFE8032FE320252AA96AA1102100C +9D5D:04103620E57C2544247CFFC4247C2540257E3640E67E24022AAA32AAA1C2408C +9D5E:02403C500848FFFE08480E50782408541A8C1FF010101FF010101FFC5244892C +9D5F:280011FC682014F82420D5FC0A001FF010101FF010101FFC10001FFC0004492C +9D60:1020504050FC7C8490FC1084FEFC008000FE7C8044FE440244AA7CAA4502000C +9D61:04100620757C0544047CFF44047C1440147E5C40547E5402552A5D2AE342410C +9D62:1040208079FC490479FC490479FC490049FEF90019FE28024AAA8AAA2A02100C +9D63:10201040FEFC108410FC7C8454FC548054FE7C8010FE380256AA92AA1202100C +9D64:202020403CFC448448FCBE842AFC2A803EFE2A802AFE3E022AAA2AAA2B02440C +9D65:49042A247F240824FFA4080C02001FF010101FF010101FFC10001FFC0004492C +9D66:100020FC7C0444047C7C44047C0440FE7E1040927E540238AA54AA9282500C20 +9D67:4440288001FC7D0429FC290429FC2900FDFE290029FE28022AAA4AAA4A02880C +9D68:1020104028FC248442FCB88410FC1080FEFE108010FE7C0244AA44AA7D02440C +9D69:0008779054BC54A454BC75A4543C57A054BE74A056BE5502552A56AA5482B40C +9D6A:10201040FEFC288454FC92847CFC54807CFE54807CFE100216AA1AAA1202000C +9D6B:102010401EFC10847CFC44847CFC44807CFE548010FEFE0212AA12AA1202100C +9D6C:00107720557C5544557C7744557C5540557E7740557E5502552AB52A8942130C +9D6D:1020104028FC248442FCBC8410FC1080FEFE108094FE580252AA1EAAF202400C +9D6E:102010403EFC228444FC808410FC668042FE428066FE420242AA7EAA4302000C +9D6F:104020807DFC550455FC7D0455FC55007DFE210051FEFC0212AA12AA1202100C +9D70:00107F20497C49445D7C49447F7C41405D7E5540557E5D02412A412A4542820C +9D71:102010407CFC108410FCFE8400FC448092FE10807CFE100212AA1EAAE202400C +9D72:2820284028FCFC8428FC2884FEFC00807CFE448044FE7C0244AA44AA7D02440C +9D73:102008407EFC428442FC7E8440FC5E8052FE5E8052FE5E0252AA52AA9302160C +9D74:402040407EFC828422FCAA8472FC2280FEFE228072FEAA0222AA22AA0B02040C +9D75:202020403CFC448488FC7E8452FC52807EFE10802CFE2A0228AA4AAA4B02860C +9D76:0020FE4028FC288428FCEE8482FC828082FEEE8028FE28022EAAF0AA4102000C +9D77:10100820FF7C8144407C7744557C5540557EB540977E1402242A252A4642840C +9D78:10201040FEFC108428FC4484FEFC048074FE548054FE740254AA04AA1502080C +9D79:0640387C08947E241C442A944A081FF010101FF010101FFC10001FFC0004492C +9D7A:20201040FEFC288428FC4E8452FCDA8056FE628054FE4C0248AA54AA6502400C +9D7B:105020487C8044FE7D9046907CFC40907E9040FC7E900290AA90AAFE82800C80 +9D7C:20201040FEFC828428FC448482FC00807CFE108010FE10021EAAF2AA4202000C +9D7D:0010F720117C5544227C5544897C1040007EF740117E5502222A552A8942100C +9D7E:0020FC4084FC8484FCFC848484FCFC8000FE8880EEFE880288AAAAAACD02880C +9D7F:100020FE7C8244FE7C8244FE7C0040147EE440447E4403FEAA44AA4482840D04 +9D80:102420247F7E41247F24413C7F2440247FBC40247FA400FEAA80AAA481220642 +9D81:20201040FEFC008400FC7C8444FC44807CFE108054FE520292AA10AA5102200C +9D82:2020CE4082FC8284EEFC828482FCFE8028FE288028FE28024AAA4CAA8902000C +9D83:100020207CCE44827C8244EE7C8240827EFE40287E280228AA48AA4A828A0D06 +9D84:10201040FEFC10847CFC1084FEFC00807CFE44807CFE44027CAA44AA5502480C +9D85:0040548055FCA904A9FC550455FC0100F9FEA900A9FEF802AAAAAAAAFA02880C +9D86:1040108011FC7D0411FC550455FC5500BBFE110039FE540292AA12AA1202100C +9D87:10201040FEFC10847CFC54847CFC54807CFE108038FE540292AA12AA1202100C +9D88:10201040FEFC10847CFC1484FEFC14807CFE1080FCFE240244AA28AA3102C80C +9D89:20201040FEFC00847CFC44847CFC00807CFE048008FE1E02F2AA12AA5202200C +9D8A:101008207F7C48445E7C4A444A7C7F404A7E4A405E7E4802542A922A2242400C +9D8B:00207E4042FC42847EFC488448FC7E8048FE48805CFE540254AA54AA5D02940C +9D8C:00107F20417C41447F7C4444557C5540557E5F40447E5502552A572A9D42000C +9D8D:00207C4044FC7C8444FC44847CFC20807EFEAA802AFE4A0292AA22AA4B02040C +9D8E:20201040FEFC828400FC7C8400FC0080FEFE108010FE540252AA92AA5102200C +9D8F:0E20F04022FC928444FC108410FC7C8010FE1080FCFE10022AAA26AA4202800C +9D90:08208C404AFC48843EFC0884C8FC5C806AFE488048FE48024AAA62AA9A02000C +9D91:2AA42CA84920145022885FF410101FF010101FF010001FFC10001FFC2A44452C +9D92:22082210FA3C222427BCFAA4AABCAAA0FABE22A072BEAA822AAA24AA2482298C +9D93:50405080F9FC510451FC0104F9FCA900A9FEA900F9FEA802AAAAAAAAFA02880C +9D94:00107E20247C18447F7C29444A7CA840107E0840FF7E1C022A2A492A8842080C +9D95:2040108079FC010449FC3104FDFC010079FE490049FE78024AAA4AAA7A02480C +9D96:0610381008527E5408901C282A2848440A821FF010101FF010101FFC5244892C +9D97:00407CFC44847CFC44847CFC0080FEFE108010FE5E0252AA52AAB0049FFE0000 +9D98:20102720257C7544257C2744257C7540557E5740557E5502752A492A0942130C +9D99:20201040FEFC008444FC2884FEFC828010FE7C8054FE540254AA5CAA1102100C +9D9A:0020EE40AAFCAA84EEFC008478FC0080FCFE208040FE78020AAA0AAA2A02100C +9D9B:48204A406CFC48844AFC6A8456FC20807EFE428042FE7E0242AA42AA7F02420C +9D9C:4420FE4044FC00847CFC048428FC1080FEFE328054FE900212AA12AA5202200C +9D9D:0020FE4000FC7C8444FC44847CFC0080FEFE928092FEFE0292AA92AAFF02820C +9D9E:021007203C7C2444247C3F44247C2F40297E2F40297E2F02292A492A4F42890C +9D9F:20201040FEFC828428FC448492FC148012FEFE8010FE10022AAA26AA4202800C +9DA0:0010FFA0807CBF44A17CBF44A17CBF40887EFFC0927EB2028CAA92AAA102FF8C +9DA1:00207C4044FC7C8444FC7C8420FC7E8092FE52806AFE42027AAA02AA1502080C +9DA2:0E20F04022FC928454FC48847CFC1080FEFE20803EFE420254AA88AA1502620C +9DA3:101008207E7C4244427C7E44427C40407F7E5540557E7F02D52A552A5542430C +9DA4:0020FE4092FC1084FEFC10847CFC54807CFE54807CFE1002FEAA12AA1202100C +9DA5:00107F20497C49447F7C40445F7C5140517E5F40517E5F02512A512A9F42110C +9DA6:107CFF44107C7E44427C7E44028C1FF010101FF010101FFC10001FFC0004492C +9DA7:221022207F7C22442A7C08443E7C2A402A7E2A40FF7E0802142A122A2242400C +9DA8:20203C4044FC788408FCFE8420FC52809CFE2C804AFE98022AAA4AAAAA02100C +9DA9:00207E20247E18A4FF2829104A2898C602001FF010101FF010101FFC5244892C +9DAA:00207E4042FC7E8442FC7E8442FC7E8014FE1280FEFE10022AAA26AA4202800C +9DAB:10201040FEFC1084FEFC9284D6FCBA8092FEFE8010FE380254AA92AA1102100C +9DAC:08100C20127C294444FCBF44217C3F40217E3F40207E3F02512A512A9F42110C +9DAD:20204410F9FE1040247CFE840084551482081FF010101FF010101FFC5244892C +9DAE:20201040FEFC00847CFC44847CFC0080FEFE8280BAFEAA02BAAA82AA8B02840C +9DAF:08202AA44D28145022887FFE42029FF410101FF010101FFC10001FFC0004492C +9DB0:00207C4044FC44847CFC0084FEFC8280FEFE8280FEFE8202FEAA28AA4502840C +9DB1:01007FFE44429FF404403FF80440FFFE0A201FF02828CFE608200FF800081558 +9DB2:2820444092FC208448FCFC8404FC0080EEFE2280AAFE6602AAAA22AAAB02440C +9DB3:2100427EF3889288F2BE92AAF3AA822AFA2A83AAFAAA0AAEAA88AB888A883008 +9DB4:081008207F7C5544127C3F44647CA4403F7E2440247E3F0224AA24AA3F02200C +9DB5:201020207F7C9144557C7D44217C4A40A47E7F40917E55027D2A212A4A42840C +9DB6:101008207F7C48445E7C4A447F7C4A405E7E48405E7E520252AA52AA5F02920C +9DB7:20201040FEFC828410FC7C8410FC7C8010FEFE8010FE7C0244AA44AA7D02440C +9DB8:0020EE4022FC2284EEFC888488FCEE8022FEAA8066FE6602AAAA22AAAB02440C +9DB9:2020DE408AFCCA84AAFCD284A6FC0080FEFE928092FEFE0292AA92AAFF02820C +9DBA:1020924054FCAA8444FC82847CFC448044FE7C8044FE44027CAA44AA45024C0C +9DBB:00207C4044FC748454FCFE8482FC7C8044FE7C8044FE7C0244AA44AA5502480C +9DBC:22101420007C7FC4147C7F44157CFFC0157E7F40147E3602552A94AA1442140C +9DBD:282024407EFCC8847EFC48847EFC48807EFE508010FEFE0212AA12AA1202100C +9DBE:108010FE1140FEFC10847CFC44847CFC44807CFE1080FEFE100212AA12AA1004 +9DBF:082004407FFC12483CF0082014503EF802001FF010101FF010101FFC5244892C +9DC0:21081110123CFFE4213C2124423C52A094BEE720213E4202422A94AAF782108C +9DC1:22101420007C7F44007C1444227C4140007E7F40557E5502552A57AAFC42000C +9DC2:0E20F04022FC928444FC20843CFC508010FEFE8010FE540254AA5CAA6502000C +9DC3:00107E20427C7E44427C7E44087CFF40817E1040FF7E220264AA18AA2502C20C +9DC4:0E20F04022FC928444FC208444FCF88010FE2480FEFE1002FEAA28AA4502820C +9DC5:0020FE4028FC2884FEFCAA84AAFCFE8010FE1080FEFE380254AA92AA1102100C +9DC6:4610782040FC3FC4007C5F44517C5F40517E5F40517E5F02402A7FAA2242410C +9DC7:1000FE7810487C480048FE8692007CFC44447C4444287E2840107F280144AB82 +9DC8:2004401EF3F0921EF21092FEF2928298FAF2828EFA800AB8AAA8ACAA8D4A3A86 +9DC9:03107C20477C44445F7C5544567C5C40557E5340507E5702552A552AA9C2000C +9DCA:0020FE4000FC7C8444FC7C8400FCFE8082FEAA8092FEFE0292AA92AA9302860C +9DCB:22082210FFBC22242A3C1424223C5D2088BE08207F3E08022A2A492AA882100C +9DCC:100020FE7C9044FC7C9044FC7C9040907EFE40027EAA02AAAAAAAA8282140C08 +9DCD:104020807DFC45047DFC45047DFC45007DFE1100FDFE10023AAA56AA9202100C +9DCE:102020407CFC44847CFC44847CFC1080FEFE288054FE92027CAA10AA1102100C +9DCF:10201040FEFC10847CFC44847CFC44807CFE44807CFE4402FEAA28AA4502820C +9DD0:00107E20427C7E44427C7E44007C7F40407E5E40407E7F02552A522A5942910C +9DD1:44104420777CAA44117C2044107CFF40007E0440447E240228AA0EAAF102400C +9DD2:10201040FEFC10847CFC54847CFC54807CFE1280FEFE0802FEAA48AA2902180C +9DD3:101008207F7C4044527C52447F7C5240527E5E40407E5502552A552A8042000C +9DD4:08207F20087E7E4408A4FF2810101E2822445FF290101FF010101FFC5244892C +9DD5:009079FE4B204DFC492049FC792001FE02001FF010101FF010101FFC5244892C +9DD6:7F7848485F4C64805F784A4851307F4C02001FF010101FF010101FFC5244892C +9DD7:0020FE4080FC8084BCFCA484A4FCBC8080FEEE80AAFEAA02EEAA80AAFF02000C +9DD8:0820FFA0083E7F4449A87F102A28494682001FF010101FF010101FFC5244892C +9DD9:08207E2008F8FF2814287F6A082AFF560A821FF010101FF010101FFC5244892C +9DDA:0020EE4022FCAA8466FCAA8410FC288044FE928020FEC80232AAC4AA1902E00C +9DDB:02083FD0223C2FA422BC3FE422BC2FA0223E2FA02ABE2F824AAA4FAA8A82098C +9DDC:08107F20497CFFC4497C7F44087C7F40497E7F40107EFF02212A722A0C42F30C +9DDD:0020FE4092FCFE8492FCFE8454FC5480FEFE548054FEFE0210AAFEAA1102100C +9DDE:10201040FEFC1084BAFC5484BAFC1080BAFE5480BAFE10022AAA26AA4202800C +9DDF:208010FCFD4020F83D2024FC445055888A041FF010101FF010101FFC5244892C +9DE0:2040208079FC490491FC7D0455FC55007DFE550055FE7C0202AAAAAAAA02000C +9DE1:200820107FBCD524553C5524FFBC5520553E5520FFBE00026A2A552A9502000C +9DE2:3FFE289025103FDE22222A882F88229425222FF0241027F0241047FC40048AAC +9DE3:0020FE4028FCFE84AAFCFE8400FC7C8044FE7C8044FE7C0210AAFEAA1102100C +9DE4:0020EE40AAFCAA84EEFC00847CFC54807CFE54807CFE1002FEAA12AA1202100C +9DE5:1020244878F014287EFC002054A8556402001FF010101FF010101FFC5244892C +9DE6:282024407EFCC88448FC7E8448FC48807EFE488048FE7E0240AAAAAAAB02000C +9DE7:1020FE4010FC7C8400FCFE8482FC7C8000FE7C8044FE7C0244AA28AA0F02F00C +9DE8:44204440FEFC448400FCFE8454FC5480FEFE548054FEFE0210AAFEAA1102100C +9DE9:49202A3E7F4849485DA86B104928414602001FF010101FF010101FFC5244892C +9DEA:00003EF822883EF822883EF822887FFE42029FF410101FF010101FFC5244892C +9DEB:08087F10093CFFA4093C7F24083CAAA0EBBE88A0FFBE8882EBAAAAAAAA82088C +9DEC:282028407CFC288428FCFE8410FC7C8054FE7C8054FE7C0200AA28AA4502820C +9DED:0E20F04092FC5484FEFC388454FC82807CFE548054FE7C0254AA54AA7D02440C +9DEE:06107820107CFFC4227C5D4494FC1C40007E7F40417E5D02552A5D2A4142430C +9DEF:081008207F7C0844557C2244417CBEC0227E3E40227E3E0208AA2AAA4902180C +9DF0:0440FFFE044017D2F01C17D03452D7CE02001FF010101FF010101FFC5244892C +9DF1:2020FE4082FCFE8482FCFE8482FCFE8010FE928054FE920210AAFEAA1102100C +9DF2:08287F2400FE3E2022503E504952988E02001FF010101FF010101FFC5244892C +9DF3:EE20AA40EEFCAA84EEFC8284BAFCAA80BAFEAA80BAFEAA02AAAADAAA8302860C +9DF4:0020EE40AAFCEE84AAFCEE8492FC9280FEFE9280BAFED60292AA92AA8B02840C +9DF5:00107F20417C41447F7C48445D7C4A407F7E48405E7E72025EAA52AA5F02920C +9DF6:0020FE40AAFCAA84FEFC00847CFC44807CFE44807CFE44027CAA00AA2902440C +9DF7:22101420FF7C14447F7C5544637C5D40417E7F40047EFF0244AA24AA25020C0C +9DF8:7E101420087CFF44297C4A44A87C10407F7E5540637E5D02552A5D2A4142430C +9DF9:00803FFE225024FC2D9036FC249024FC210027F0241027F0441047FC80040AAC +9DFA:00403EFC23483E3009CE2E7828487E7802001FF010101FF010101FFC5244892C +9DFB:21084088F3C89010F3DE9264F3D48014FBD48054F89408E8AB88A8948A943122 +9DFC:0020EE40AAFCEE84AAFCEE8482FCBA80AAFEBA80AAFEBA02AAAA82AA8B02840C +9DFD:0A803138228838382288393822887FFE42029FF410101FF010101FFC5244892C +9DFE:1020FE4044FC2884FEFC00847CFC44807CFE44807CFE10020AAAA9AAA5021C0C +9DFF:3E1022FE3E4420287EFEA2103EFC221002001FF010101FF010101FFC5244892C +9E00:00107F20557C55447F7C20447F7C91407D7E5540557E7D02112A7D2A0542020C +9E01:0100FFFE20003FF800003FF820083FF80200779C54947794549C77D65056B562 +9E02:0310BC2044FC1144847C49445E7C0440297E5F40C47E5F0244AA4AAA5102208C +9E03:21044088F3FE9020F1FC9020F3FE8054F9928090FBFE0890A8D4AB8A889631A2 +9E04:10207E204A7E7EC41028FF1020283EC642001FF010101FF010101FFC5244892C +9E05:00107F20557C7F44087C7F44087CFFC0227E14407F7E0802FFAA08AA0902080C +9E06:08100F20087C7F44497C7C44497C5F40527E5E40407E5E02482A7F2A5242A10C +9E07:1020FE4000FCFE8482FCBA84AAFCFE8000FE7C8044FE7C0244AA7CAA0102FE0C +9E08:14105520367C1444FF7C2244147C7F40087E7F40087EFF021CAA2AAA4902080C +9E09:11FC1104FDFC310459FC948011FE125202AA1FF410101FF010101FFC5244892C +9E0A:02087910493C4BA4483C7AA4413C47E0793E6920ABBEA902292A392A2902010C +9E0B:0810FF20917C4A44A57C1C44007C7F40557EFFC0007E7F0208AA08AA2902100C +9E0C:104421FE7C5444487CFE45907CFE40907EFE40907EFE0280ABFEAA4482380DC6 +9E0D:0008FF90493C88A4FFFC88A4DDBCAAA0DDBE88A0DDBEAA82DDAA88AA8A82810C +9E0E:3EF822883EF822883EF822883EF8145022881FF010101FF010101FFC5244892C +9E0F:2410FF20247CFF44817C7E44007CFF40107E28C0D57E2E02D5AA24AAD502080C +9E10:0010EE20227CAA44667CAA44007C24407F7EC8407E7E48027EAA48AA7F02400C +9E11:510C278A500897BE30085788949457A422021FF010101FF010101FFC5244892C +9E12:1A3823883A38238838B82288FFFE10102208DFF610101FF010101FFC5244892C +9E13:00087F10493C7F24493C7F24413C0020FFBEAAA0AABEFF82AAAAAAAAFF82888C +9E14:21FC4104F9FC8904F9FC8888F9FC8088FDFE8088FD2406AA547054A885241860 +9E15:08080F90083C7FA448BC7E2448BC5FA0553E5F20553E5F02402ABFAA2A827FCC +9E16:7F080810FFBC88A46B3C08246B3C24207FBEC8207F3E48027F2A482A7F82400C +9E17:08403E7C1440FF7822083E782242263E02001FF010101FF010101FFC5244892C +9E18:FE201040FEFC928454FC108454FC00802EFEFA802EFE7A02AEAA2AAA2F022A0C +9E19:1020284044FCBA8400FCFE84AAFCFE8000FEFE80AAFEAA02FEAAAAAAAB02860C +9E1A:00107720557C7744557C7744557C7740227E5540107EFF0222AA64AA1D02E30C +9E1B:4420FE4044FC0084EEFCAA84EEFC24807EFEC8807EFE48027EAA48AA7F02400C +9E1C:77105520777C5544777C5544777C22407FFEA4403F7E24023F2A242A3FC2200C +9E1D:77100020777C5544777C5544087C7F40547E7F40557E7F02552A5E2A55429B0C +9E1E:21084FD2F03C23884812FBBE0280ABAA02001FF010101FF010101FFC5244892C +9E1F:010002001FF01010121011101150102010001FFC000400047FE4000400280010 +9E20:2020204020FC2084FCA4248424942488248024FE2502260245FA400280140008 +9E21:0020004000FCFC8404A4048448942888108010FE2802240245FA800200140008 +9E22:04200410023EFFC00080004202321FEE1420126010001FF800087F8800280010 +9E23:0020004079FC4904494449244924490C490049FE7802480203FA000200140008 +9E24:002000403EFC228422A422843E942288208020FE2002200221FA400240148008 +9E25:00207E4040FC448464A4548448944888548054FE6402400241FA7E0200140008 +9E26:00207E4004FC248424A4248444947F880C8014FE1402240245FA840214140808 +9E27:08100820147C124421644054BE44224C2240227E2A022402217A21021F0A0004 +9E28:4020484050FC608444A444843C941088108010FEFE02100211FA100210141008 +9E29:08100820087C7F44496408540844144C1440147E14022502267A4402800A0004 +9E2A:1020104010FC1084FEA41084109410887C8044FE4402440245FA7C0244140008 +9E2B:10101020107CFF44206428544844484C7E40087E2C022A02497A8902280A1004 +9E2C:102010401EFC108410A47C844494448844807CFE4402400241FA400280140008 +9E2D:0020FE4092FC928492A4FE84929492889280FEFE9202100211FA100210141008 +9E2E:00207E4042FC428442A47E840094FF88208040FE7E02020203FA020214140808 +9E2F:01001FF011101110FFFE02801C70E20E04001FE0122011601FFC00047FD40008 +9E30:1020104028FC248442A4918408940888FE8002FE4402280211FA080208140008 +9E31:011007A07C7C44444464445444447F4C4440447E4402420242FA5282698A4484 +9E32:2020204040FC7E8482A402847A944A884A804AFE7A024A0203FA020214140808 +9E33:10003EF84288A2AA1492187EE2001FE01420126010001FF800087F8800280010 +9E34:2208111000207FFE410282041FF010101210115010201FFC000400047FD40008 +9E35:102020107C1044FE548245045440484840507E6002400242FA420242143E0800 +9E36:1020244878F010207EFC0000FFFE020004001FE0122011601FFC00047FD40008 +9E37:10801080FBF010901990F0941154520C24041FE0122011601FFC00047FD40008 +9E38:00107F20087C084410647F545544554C5540557E55025502557A5102450A4204 +9E39:04200E4038FC088408A4FF84089408883E8022FE2202220223FA3E0222140008 +9E3A:12081210123E22222FB2622AA62227262AA02ABE32022202227A2202220A2204 +9E3B:10101020277C4044906410542FC4624CA240227E22022202227A22022A0A2404 +9E3C:082010403EFC228432A42A842A94FE88228032FE2A022A0223FA42024A148408 +9E3D:1020104028FC248442A480847C94008800807CFE4402440245FA7C0244140008 +9E3E:02000100FFFE04401450244842041FE01420126010001FF800087F8800280010 +9E3F:00108020407C1F44846444544444044C2440447EC40247025C7A4802400A0004 +9E40:001000207F7C084408642A542A442A4C5D40497E880208020F7AF002400A0004 +9E41:10201040FEFC108410A4FE8482940488788008FE10021E02F1FA100250142008 +9E42:0008FF90003E0022F7B294AA94A294A6D6A0B5BE9482948294FA9482948AB584 +9E43:00103E20227C22443E6400547F44414C41407F7E410241027F7A4102450A4204 +9E44:08104820487C7F44886408540844FF4C0040007E7E024202427A42027E0A4204 +9E45:04103620E57C25442464FFD42444254C2540367EE60224022AFA3282A18A4084 +9E46:2820244042FC928410A42884449482887C8044FE4402440245FA7C0244140008 +9E47:40102F20017C4944496449547F44494C5D406B7E49024902497A4102450A4204 +9E48:4420244028FCFC8414A41484FC9490889080FEFE3202320253FA960210141008 +9E49:04100620757C05440464FF540444144C14405C7E54025402557A5D02E30A4104 +9E4A:24102420247CFF4424642454FFC4004C7E40427E42027E02427A42027E0A4204 +9E4B:22082210FFBE22222232002A7F2249264920493E7F024902497A49027F0A4104 +9E4C:08080810FFBE14222232492A88A27F2649207F3E49027F02087A0A020C0A0804 +9E4D:00107E20427C42447E64425442447E4C0040447E77024402447A5502660A4404 +9E4E:101020207F7C494449647F544944514C7F40247E4402FF82047A0402040A0404 +9E4F:00107720557C5544556477545544554C5540777E55025502557AB502890A1304 +9E50:102010403EFC228444A4808410946688428042FE6602420243FA7E0242140008 +9E51:10100820FF7C00447E6442547E44004C7E40047E08020F02F87A0802280A1004 +9E52:101008207F7C48445E644A544A447F4C4A404A7E5E024802547A9202220A4004 +9E53:10100820FF7C8144406477545544554C5540B57E97021402247A2502460A8404 +9E54:081008207F7C0944FFE409547F44084C4940497E5D026B02497A4902890A0904 +9E55:2008279024BEFCA224B227AA24A274A654A057BE5482548274FA08820A8A1104 +9E56:00107E20427C7E4442647E5420447F4C8940497E550241027D7A01020A0A0404 +9E57:00107720557C5544776400547F44004CFFC0207E3F020102017A01020A0A0404 +9E58:00207C4044FC748454A4FE9482947C8C44807CFE44027C0245FA440254144808 +9E59:0620382008A47EA819202C504A881FE41420126010001FF800087F8800280010 +9E5A:21081110123EFFE22132212A422252A694A0E73E21024202427A9482F78A1084 +9E5B:00107F20497C49447F6440545F44514C51405F7E51025F02517A51029F0A1104 +9E5C:00207E20247E18A4FF2829104A289AC604001FE0122011601FFC00047FD40008 +9E5D:0020FE4000FC7C8444A47C840094FE888280AAFE9202FE0293FA920292148608 +9E5E:0E20F04022FC928444A420843C9450881080FEFE1002540255FA5C0264140008 +9E5F:2820444092FC208448A4FC8404940088EE8022FEAA026602ABFA2202AA144408 +9E60:2020DE408AFCCA84AAA4D284A6940088FE8092FE9202FE0293FA9202FE148208 +9E61:1020924054FCAA8444A482847C94448844807CFE440244027DFA440244144C08 +9E62:22101420007C7F44006414542244414C00407F7E55025502557A5782FC0A0004 +9E63:22101420007C7FC414647F541544FFCC15407F7E14023602557A9482140A1404 +9E64:081008207F7C554412643F546444A44C3F40247E24023F02247A24023F0A2004 +9E65:7F7848485F4C64805F784A4851307F4C04001FE0122011601FFC00047FD40008 +9E66:00107720557C5544556455542244554C0840FF7E12022202347A0C02320AC104 +9E67:101008207F7C4044526452547F44524C52405E7E40025502557A5502800A0004 +9E68:00107720117C5544336455540C44334CC4C0187E62020C82717A0602180AE004 +9E69:081008207F7C0844556422544144BECC22403E7E22023E02087A2A02490A1804 +9E6A:282024407EFCC88448A47E84489448887E8048FE48027E0241FAAA02AA140008 +9E6B:08287F2400FE3E2022503E5049529A8E04001FE0122011601FFC00047FD40008 +9E6C:7E101420087CFF4429644A54A844104C7F40557E63025D02557A5D02410A4304 +9E6D:00403EFC23483E3009CE2E7828487E7804001FE0122011601FFC00047FD40008 +9E6E:0020FE40AAFCAA84FEA40084FE9400887C8044FE7C022A0265FAA20231142008 +9E6F:1020FE4000FCFE8482A4BA84AA94FE8800807CFE44027C0245FA7C020014FE08 +9E70:00803FFE225024FC2D9036FC249024FC210027F02490242047FC40049FD40008 +9E71:104421FE7C54444864FE559044FE4C9040FE7C9004FE0480F5FE0444143809C6 +9E72:2410FF20247CFF4481647E540044FF4C104028FED5022E02D57A2482D40A0804 +9E73:2208FF90223EF7A294B2F7AA282224267FA0483EFF0248027F7A48027F8A4004 +9E74:7F1008207F7C49442A6408542A44004C2740FD7E27027502AF7A2502270A2504 +9E75:0100010001FE010001003FF8200829282448228829282288244829283FF82008 +9E76:102010201E2010501050FE889344C622AA20D6F8AA08C6089210FE1082200020 +9E77:102010201E5010501088FF249212C610ABFCD604AA08C6889250FE2082100010 +9E78:101010281E441082107CFE109210C6FEAA92D692AAFEC6109228FE2882440082 +9E79:100C100A1E0810FE1088FE8892FAC68AAA8AD6ECAAACC6AC92EAFE8A82960122 +9E7A:104410241E2810FE1010FE7C9210C6FEAA20D620AA7CC6509290FF1082FE0000 +9E7B:108810501E0011FE1050FEFC9254C7FEAA54D6FCAA50C6D89354FE5282500050 +9E7C:101010101E2810441082FE7C9200C6EEAAAAD6AAAAEEC6449244FEAA82AA0112 +9E7D:0100F9FEA220A43EF8208BFE8AAAFA52A326A252A2AAFBFE00003FF82448FFFE +9E7E:208420443C4821FE2020FCFC842095FED440A480D4FE95108610FC1085FE0000 +9E7F:010000803FFE222022203FFC222422243FFC284028442F58486048448B440C3C +9E80:010000803FFE22203FFC22243FFC28402F7828422F3E200028784F82480287FE +9E81:010002000FF0706003801D00E0803FFC22403FF822483FF828442F7848428F3E +9E82:010000803FFE22203FFC22243FFC28402F7828422F3E200023F042104412980E +9E83:010000803FFE22203FFC22243FFC28442F4828742B442C3C40004A4889241124 +9E84:044008203018DFF60410095010A03FFC22403FF822483FF828442F7848428F3E +9E85:00803FFE22203FFC22243FFC242227BE24002FF830082FC828684FD0480287FE +9E86:00803FFE22203FFC22243FFC242227BE200027F8240827F8240847F84408BFFE +9E87:00803FFE22203FFC22243FFC242027BC2422279E200823F020404FFE41508E4E +9E88:00803FFE22203FFC22243FFC242027BC2422279E20802FFE204047FC40409FFE +9E89:00007C7C10101010FEFE111010903FFC22403FF822483FF828442F7848428F3E +9E8A:111009207FFC05401930610C00803FFC22403FF822483FF828442F7848428F3E +9E8B:00803FFE22203FFC22243FFC242027BC2422279E224821502FFE415042488C46 +9E8C:00803FFE22203FFC22243FFC200027F0241027F020002FF820805FFC42209C1C +9E8D:00803FFE22203FFC22243FFC242227BE20403FFE220024082FFC44944892908E +9E8E:00803FFE22203FFC22243FFC242227BE20002FFC28002BFC28004FFE4A28939E +9E8F:00803FFE22203FFC22243FFC20002FFC21043FFE21042FFC220047FC4A0493FC +9E90:00803FFE22203FFC22243FFC242227BE20402FFE211020E02F1E43F8420883F8 +9E91:00803FFE22203FFC22243FFC242227BE21002E7828082F7828084FF842229C1E +9E92:08447F4455FE54447F44557C55447F44547C54445E4455FE54005C2856448082 +9E93:082008207EFC1C702AA8C92608A03FFC22403FF822483FF828442F7848428F3E +9E94:00803FFE22203FFC22243FFC222027B02D2832242DFE300027F84408440887F8 +9E95:00803FFE22203FFC22243FFC20002FFC28242BC428842FF42AA44C944FFC8804 +9E96:00803FFE22203FFC22243FFC20803FFE20002FF828082FF82080488852848100 +9E97:3F7E00003E7C224432642B5400803FFC22403FF822483FF828442F7848428F3E +9E98:00803FFE22203FFC22243FFC20102FE020803FFC24902FF8341647F0441087F0 +9E99:00803FFE22203FFC22243FFC200020282FFE28202BA428282BAC4A944BAC9044 +9E9A:00803FFE22203FFC22243FFC20002F7C29042F7C28002F7C28444F28483088CE +9E9B:00803FFE22203FFC22243FFC20002F7E21242F3C28242F3C2126417C45048204 +9E9C:00803FFE22203FFC22243FFC20002FFE211027FC251427FC20404FFE4150864C +9E9D:00803FFE22203FFC22243FFC242027BC24222F9E29082F7E29485F2845089B18 +9E9E:00803FFE22203FFC22243FFC204027FC21102FFE220823F822084FFE40408040 +9E9F:08107F54543854FE7F10553855567F90548454EE5EA454B4555E5C4456848104 +9EA0:00803FFE22203FFC22243FFC28882FF828883FFE20002FF828884FF84888BFFE +9EA1:00803FFE22203FFC22243FFC20402FFE20A02F5E255425542B5A440847F88808 +9EA2:00803FFE22203FFC22243FFC200027FC20402FFE2842235820004EEE4AAA8EEE +9EA3:13DEFE52ABDEA800FFFEAA00AAC8FE4EABEAAAB2BEEAAAAAAAEABAB4ADE4002A +9EA4:00803FFE22203FFC22243FFC4810FF7E54487F7E554A7F7E52645B7652A49B36 +9EA5:01007FFC0920092015502388054009203218C7E6082013400080014006203800 +9EA6:010001007FFC010001003FF801000100FFFE08001FF02820444003801C70E00E +9EA7:08200820FF402A7E2A805D00887C1C042A0850101E20224054420842143E6000 +9EA8:08100810FF102A102A545D5288521C902A1050141E04220854080810142060C0 +9EA9:10201020FE20542055FCBA201020382055FEA2203C504450A88810882904C202 +9EAA:100011FEFE20542054A0BABC10A438A454A4A2FC3C044404A80410042828C010 +9EAB:080008FEFF102A102A505D5E88501C502A50507E1E0222025402080214146008 +9EAC:10101010FE1054FE5492BA94109038FC54A4A2A43CA844A8A89011282944C282 +9EAD:10401040FEFC54845504BAF41094389454F4A2843C944488A8821082287EC000 +9EAE:08100810FF102A7E2A105D1088101CFE2A1050101E202228544408FE14426000 +9EAF:10501050FE50545055FCBB54115439545554A3FC3D544554A954115429FCC104 +9EB0:10201020FE48548455FEBA121090389054FEA3103C1045FEA81010102810C010 +9EB1:10141012FEFE54105410BAFE1092389254FEA2923C9244FEA89210922892C086 +9EB2:080008FCFF842A842AFC5D8488841CFC2A8450841EFC2250545008521492610E +9EB3:08100810FF102AFE2A105D5488541C542ABA50101E3822545492081014106010 +9EB4:10801080FEFE55025622BAAA1072382255FEA2223C7244AAA9221022280AC004 +9EB5:080008FEFF102A202AFE5DAA88AA1CBA2AAA50AA1EBA22AA54AA08AA14FE6082 +9EB6:10201010FEFE54285492BAAA108238FE5410A2FE3CA244AAA8BA1082288AC084 +9EB7:10A811FCFEAA57FE56AABBFE12AA3BFE5400A3FE3C0045FCA90411FC2888C3FE +9EB8:10201020FE2010207DFC1020FE2020203DFE44204850A8501088288841048202 +9EB9:10801080FEFE11027E2210AAFE7220223DFE44224872A8AA11222822400A8004 +9EBA:100011FEFE2010407DFC1154FF5421743D5445544974A9541154295441FC8104 +9EBB:010000803FFE2210221022103FBE2210261027382AB42A545292421082100210 +9EBC:010000803FFE221022102FBC231826B42A522100221027E040C043088FFC0004 +9EBD:010000803FFE221022102FBC231826B42A522100224024804910420887FC0004 +9EBE:010000803FFE22102F7C26382B54329220782F8020F82F8020FC5F824082807E +9EBF:00803FFE24103F7C26382D543412200027F8240827F820002FFC480448048FFC +9EC0:010000803FFE22102F7C26382B5432923F80297C2F2429242F2849905F288146 +9EC1:00803FFE24103F7C26382D5434122FE020803FFC24902FF8341647F0441087F0 +9EC2:00803FFE24103F7C26382D5434922FF822A02FFC22202FF828884FF844108808 +9EC3:08207FFC08200FE00000FFFE01001FF0111011101FF0111011101FF008201010 +9EC4:044004403FF804400440FFFE01001FF011101FF011101FF0000008201010600C +9EC5:221022107F1022282228FFC408447FA249107F10497C7F040008220821104110 +9EC6:221022107F10221022FEFF9208927F1049287F2849287F280048224A218A4106 +9EC7:221022107F102210221EFF9008107F10497C7F4449447F4400442244217C4144 +9EC8:222022107F0022FE2210FF9008107F10497C7F1049107F100010221021FE4100 +9EC9:110808907FFE44429FF404407FFC01001FF011101FF011101FF0044008201010 +9ECA:282028207CF828202820FE2011FC7C00542054207CF8542054207C2029FC4400 +9ECB:1088108895FC5488588813FEFC2029FC292429FC292429FC288849044A0287FE +9ECC:0A803138228839382288FFFE84423FF80440FFFE11101FF011101FF008201010 +9ECD:00F83F0001007FFC092011102288C44409203118CB2605C01930610805000200 +9ECE:0640387C08947E241C442A94490802800C603118C92605400920111025080200 +9ECF:0C2070201020FE20383E54209020282055FC9104550439045504930451FC2104 +9ED0:0C40702011FCFE5039245554910429FC542091FC554439545574930451142108 +9ED1:00003FF82108292825483FF8010001003FF801000100FFFE0000488844448444 +9ED2:00003FF821083FF821083FF801003FF801000100FFFE00002488224442448004 +9ED3:00287F2449246B205D2E49F07F2008207F2008200FA0F0100012550A4A868002 +9ED4:0020FE209220D650BA509288FF441222FE2010F81E08E0080210AA10A8208020 +9ED5:0010FE109210D610BAFE9292FE921010FE2810281E28E0280248AA4AA88A8106 +9ED6:0000FEFE9210D610BA909290FE9010FEFE1010101E28E0280248AA4AA88A8106 +9ED7:0020FE209220D7FCBA2092A8FEA810A8FEA810A81EF8E0220222AA22A81E8000 +9ED8:0020FE289224D624BA2093FEFE201020FE2010501E50E0500288AA88A9048202 +9ED9:00107F1449127F10497E7F1008287F2808440F44F08200002488224442448004 +9EDA:0044FE449244D644BAFE9244FE441044FE44107C1E44E0440244AA44A87C8044 +9EDB:08901088307ED7C01022101A00063FF8292825483FF801007FFC0100FFFE4444 +9EDC:0010FE109292D692BA929292FEFE1010FE1010921E92E0920292AA92A8FE8002 +9EDD:0010FE509250D690BAFC9354FFD41094FE9411141F54E1D40254AA24A8348048 +9EDE:0010FE109210D610BA1E9210FE101010FEFE10821E82E0820282AA82A8FE8082 +9EDF:0020FE20927CD684BB489230FE201048FE90103E1E42E0A40218AA10A82080C0 +9EE0:0020FE209220D7FEBA209220FEFC1000FE0010FC1E84E0840284AA84A8FC8084 +9EE1:3FFC20903FFC21402630380C2FF82AA829C82FF820802FF840805FFC8A481124 +9EE2:0010FE109220D644BAFE9228FE4410A2FE3C10441E44E0A80210AA28A8448082 +9EE3:0040FE40927ED680BB7C9244FE641054FEFE10441EA4E09402FEAA04A8288010 +9EE4:0020FE2093FED650BAA89326FEF810A8FEA810F81EA8E0A802F8AAAAA822801E +9EE5:0020FE1092FED600BA00927CFE441044FE7C10101E54E0520292AA10A8508020 +9EE6:0020FE1092FED682BA40924EFE6A10AAFEAA10AA1F6CE028024AAA4AA88A8106 +9EE7:0640387C08947E241C442A9448083FF8292825483FF801007FFC0100FFFE4444 +9EE8:111009207FFE40029FF410103FF8292825483FF801003FF80100FFFE24484224 +9EE9:0010FE1092FCD610BA1093FEFE021054FE3010901E50E1FE0228AA44A8828102 +9EEA:0020FE289244D6FEBA2093FEFE881114FE2210481E10E02202C4AA18A8608180 +9EEB:0000FEFE9228D628BAFE92AAFEAA10AAFEFE10101E10E0FE0210AA10A9FE8000 +9EEC:000CFE0A9208D6FEBA889288FEFA108AFE8A10EC1EACE0AC02EAAA8AA8968122 +9EED:0020FE309248D684BB7A9200FEFC1084FE8410FC1E48E04803FEAA48A8888108 +9EEE:0048FE4893FCD648BA789248FE781048FE4811FE1E80E0A802C4AA80A8FE8000 +9EEF:0020FE1092FED600BA449228FEFE1000FE7C10441E44E07C0244AA44A87C8044 +9EF0:0010FE1092FED610BA7C9244FE7C1044FE7C10441E7CE04402FEAA28A8448082 +9EF1:012478A849FC48404BFE79084BFC4DAE497479FC482049FC48204BFE49549A2A +9EF2:0010FE209244D6FEBA4492AAFEEE1010FE2810541EAAE0500224AA48A8108060 +9EF3:7F7848485E8664785F484A307F4C00003FF8292825483FF80100FFFE24484224 +9EF4:11101550255047D0903E17A420546FD4A9542DD42B542FC821082FD420142AA2 +9EF5:0040FE7C9284D7FEBAA292C8FEFE1080FEBE10801EBEE08002BEAAA2A8BE8122 +9EF6:3FFE28882F8A20082FBE28882F88289429A220002FFE29522FFE40405FFE8924 +9EF7:0010FEFE9210D67CBA0092FEFEAA10FEFE44107C1E44E07C0244AA7CA8288044 +9EF8:0040F87CA840ABFCFA44ABF0FA4422FCFAA822F83AA8E2F80A00A5FCA5540BFE +9EF9:0440244814500440FFFE0100111009203FF82108254825282928210821282110 +9EFA:1408552836281428FF4449442A827F7C492449245D246B244944494449944B08 +9EFB:1428552436241420FF7E49202A207F3C493449545D546B544988498849144B22 +9EFC:14145512367E1410FF10497E2A527F52497E49525D526B7E4952495249524B46 +9EFD:00003FF8228822883EF802803EF8228822883EF8228822883EF8228A028201FE +9EFE:1FF0101010101FF001003FF8210821083FF8210821083FF8210A0102010200FE +9EFF:1FF00000FFFE0844303CDFF012901EF002803EF822883EF822883EFA028201FE +9F00:01003FF80100FFFE10103FF852941EF002803EF822883EF822883EFA028201FE +9F01:01003FF80100FFFE04201FF000001FF012903EF822883EF822883EF8028201FE +9F02:00001FF010101FF01010FFFE00001FF012903EF822883EF822883EF8028201FE +9F03:01003FF80100FFFE01003FF80100FFFE12903EF822883EF822883EF8028201FE +9F04:09000FF011007FFC05401930E10E1FF012903EF822883EF822883EF8028201FE +9F05:20003F7C4844FFC4147C224441001FF012903EF822883EF822883EF8028201FE +9F06:0000FDFC8554015479DC485079DC4954795421DC1154FD5401DC51504852883E +9F07:08207E20087EFEC410281E1022285FF692903EF822883EF822883EF8028201FE +9F08:49202A3E7F4849485DA86B1049285FF612903EF822883EF822883EF8028201FE +9F09:00003EF822883FF811101FF01110FFFE12903EF822883EF822883EF8028201FE +9F0A:00107E7C42287EFE40107E7CA2103FF012903EF822883EF822883EF8028201FE +9F0B:1FF00000FFFE0844303CDFF010101FF001003FF821083FF821083FFA010200FE +9F0C:00001FF010101FF01010FFFE00001FF010103FF821083FF821083FFA010200FE +9F0D:00003EF822883FF811101FF01110FFFE01003FF821083FF821083FFA010200FE +9F0E:0FE008200FE048244FE448244FE440047C7C04400440FC7C2444244444448444 +9F0F:7FFE40028FE408200FE008204FE448244FE440047C7C0440FC7C244444448444 +9F10:7FF81008101E2FE2482A8FE408204FE448244FE440047C7C0440FC7C24444444 +9F11:010001FC01001FF010101FF010105FF450145FF440047C7C0440FC7C24444444 +9F12:00807FFC048019806FE008200FE048244FE448244FE47C7C0440FC7C2444C444 +9F13:08100810FF1008FE08107E1000FC7E44424442447E28422824100F28F0444082 +9F14:08100810FF10081E08107E1000FC7E44424442447E28422824100F28F0444082 +9F15:0810FF7E08107E7C42047E4824381E44E8001FF0282007C01830E18E0C400300 +9F16:01007FFC0920FFFE08200810FF1008FE7E1000FC7E4442487E2824101E28E0C6 +9F17:249014A024940884707C0810FF1008FE7E1000FC7E4442487E2824101E28E0C6 +9F18:0810FF7E08107E7C42447E282418FEE624483C7820083FF820083C7824484448 +9F19:0810FF7E08107F7C41447F2822101F28FFF611101FF012101FF004407FFC0040 +9F1A:0810FF7E08107E7C42047E4824381E44EFF008000FF00800FFFE111014E0181C +9F1B:0810FF7E08107E7C42447E3824447EA222385424082037FEC0001FF010101FF0 +9F1C:0810FF7E08107E7C42447E3824447FF2092007C0F93E1FF011101FF001087FFC +9F1D:24A414A487BC440417FC24044FBC90A40810FF7E08107E7C42447E282418FEE6 +9F1E:0810FF7E08107E7C42447E282418FEE611107FFE48228FE401001FF001007FFC +9F1F:0810FF7E08107E7C42447E3824D47EA204442BA810102FE8C8260FE004407FFC +9F20:060038F820083EF8200820083FF800002948252821082948252A210A2D663182 +9F21:22081108111000003FF8210821083FF8210821083FF82108210A410A41068002 +9F22:2008CE288228EE2882448244FE82017C92249224DA249224DA4492449394D908 +9F23:2010CE148212EE12821082FEFE10001092109228DA289228DA2892449344D982 +9F24:2020CE108210EEFE82448244FE44004492449228DA289210DA1092289344D982 +9F25:2028CE248224EE2082FE8220FE20003C92349254DA549254DA8892889314D922 +9F26:2000CEFC8224EE2482248224FE5400489280927CDA449244DA449244937CD944 +9F27:2020CE108210EEFE82828284FE40004492489250DA609242DA429242933ED900 +9F28:2020CE20823EEE4282C48328FE10002892449382DA309208DA0492609310D908 +9F29:2040CE408240EEFC82848304FEF4009492949294DA9492F4DA9492049328D910 +9F2A:2010CE108250EE50827C8250FE9000109210927CDA109210DA10921093FED900 +9F2B:2000CE0082FEEE1082108220FE20007C924492C4DB449244DA449244937CD944 +9F2C:2010CE108210EE1082FE8292FE920092929292FEDA929292DA92929293FED982 +9F2D:2010CE108210EE7C82108210FEFE0008920892FEDA089248DA2892089328D910 +9F2E:2000CC0685D8EC4884488488FC9E01C8A848F948A948F89EA880A940FA3EA400 +9F2F:2000CEFE8210EE10827C8224FE2400FE92009200DA7C9244DA449244937CD944 +9F30:2000CE7C8244EE44827C8244FE44007C92449244DA7C9200DA2892249342D982 +9F31:2010CE1082FEEE10827C8210FEFE0000927C9244DA7C9244DA7C92449354D948 +9F32:2000CEFE8292EE1082FE8210FE7C0054927C9254DA7C9210DAFE92109310D910 +9F33:2000CEFE8282EEFE828282FEFE8200FE92149212DAFE9210DA2892289344D982 +9F34:2000CDFE8500ED7E8542857EFD42017EA910F9FEA924F964A918A924FB42A5FE +9F35:2020CE1082FEEE8282448292FE14001292FE9210DA289228DA2892449344D982 +9F36:2008CC3C85D0ED1C8510857CFD540158A970F954A94CF940AA78A8A8FA2AA446 +9F37:200ECEF08222EE9282448220FE4400F892109224DAFE9210DAFE92289344D982 +9F38:2088CC508400EDFE845085FCFC5403FEA854F9FCA850F8D8A954AA52FA50A450 +9F39:2000CE7C8244EE7C8244827CFE1000FE92829210DAFE9224DA6892109328D944 +9F3A:2000CDFC8524EDFC852485FCFD040000ABFEFAAAAAAAFBFEAAAAAAAAFBFEA622 +9F3B:02001FF010101FF010101FF000003FF821083FF821083FF80000FFFE08201020 +9F3C:10043E0422443E4422443E4400447F4449447F4C49747F440004FF8422044204 +9F3D:10203E2022203E2022F83E2800287F2849287F2849287F2A002AFFCA22464280 +9F3E:10003E00227C3E1022103E1000107F1049FE7F1049107F100010FF9022104210 +9F3F:10003E00227C3E2822283E2800287F2849287F2849287F2A002AFFAA22464280 +9F40:10003E7C22203E2022203E3800287F2849587F4849487F48005AFFEA224A4206 +9F41:10403E4022403EFC22843F0400747F5449547F5449747F540004FF8422284210 +9F42:20207C2044FC7C2445FE7C2400FCFE209324FEA89270FEA80124FE2244A08440 +9F43:20007CFC44847CFC44847CFC0040FEFE9312FE9292AAFE8200FAFE0244148408 +9F44:10103E1022FE3E3822543E9200007F7C49447F7C49447F7C0044FF8022FE4200 +9F45:20207C4044FC7C8444FC7C8400FCFE8492FCFE289224FEFE0020FE5044888506 +9F46:20927D2444927C00447C7C44007CFE0092FEFE929292FEFE0080FE824482847E +9F47:20207C3C44207CFE44A27CB800E4FE9C9280FEBC92A4FEBC00A4FEBC44A4857E +9F48:20287CFE44AA7CFE44AA7CFE0000FEFE9280FEBE9280FEFE00A8FEAA44A48532 +9F49:2020FBFE8924F9FC8820FBFE0356F9DCA888FBFEA888FBFE0094F98852A490C2 +9F4A:020001007FFC0440028C7D702550255045488D6610101FF010101FF010102010 +9F4B:0100FFFE02847D78255025484D6420083FF820083FF821082548252849288108 +9F4C:0100FFFE02847D78255025484D6420083FF820083FF820082528294842888C48 +9F4D:0100FFFE02847D78255025484D6420083FF820083FF840083FF824482448FFFE +9F4E:0100FFFE02847D78255025484D6420083FF820082FE828282FE828284FE88448 +9F4F:0100FFFE02887D7025484D66A0083FF822882EE822882EE822884EE842888FE8 +9F50:020001007FFC0820044003800C603018C8260820082008200820102010202020 +9F51:020001007FFC0820044003801C70E28E2EE822882EE822882EE822885FF88008 +9F52:0100110011F811001100FFFE044024482AA831183FF824482AA831183FF80008 +9F53:082028202F202820FF20142055206B2041207F20552055226B224F22711E0100 +9F54:082028202F202820FF22142455286B3041207F6055A055226B224F22711E0100 +9F55:082028202F20287EFF401480553C6B0441087F10552055406B424F42713E0100 +9F56:100050FC5C085048FE482848AA88D6FE8218FE28AA28AA48D6889F08E2280210 +9F57:0800280C2F702840FF401440557E6B4841487F48554855486B484F4871480188 +9F58:081028102F102828FF28144455AA6B2841287F28552855286B284F4871480188 +9F59:104050405CFC5084FF042AF4AA94D69482F4FE84AA94AA88D6829E82E27E0200 +9F5A:082028202F20283EFF50145055906B1E41107F105510551E6B104F1071100110 +9F5B:102850A85CA850A8FEA829FEAAA8D6A882A8FEA8AAB8AA80D6809E80E2FE0200 +9F5C:100850285C285028FEA828AAAABCD6A882A8FEA8AAA8AAA8D6AA9EBAE2EA0386 +9F5D:102050205C205040FE482884ABFED6828200FEFCAA84AA84D6849E84E2FC0284 +9F5E:080028002F7C2844FF44144455446B44417C7F44550055286B244F4471420182 +9F5F:0800287C2F442844FF44147C55446B4441447F7C554455446B444F4471FE0100 +9F60:080028FC2F242824FF24142455546B4841807F7C554455446B444F44717C0144 +9F61:081028102F102828FF281454558A6B08417C7F04550855286B104F1071080108 +9F62:081028102E1028282828FF54008A49086B7C49047F085D286B104F1079080008 +9F63:082028202F20287CFF44148455746B5441547F54557455546B044F0471280110 +9F64:111009207FFC0400FFFE111029E8C9067FFC04402AA83FF824482AA83FF80008 +9F65:102050205CFC50A4FEA428FCAAA4D6A482FCFE20AA24AA18D6129E6AE3860202 +9F66:0800087C2F442844FF7C144455446B7C41507F52555455486B5441667F420000 +9F67:08007F7C08243E2408447F5409E809007FFC04402AA83FF824482AA83FF80008 +9F68:080028202F4C2844FF44144455446B6C41447F44554455446B444F7C71440100 +9F69:102050105C1050FEFE002844AA82D7008244FE44AA28AA28D6109E28E2440282 +9F6A:0800287C2F442844FF441444557C6B1041107F50555E55506B504F70719E0100 +9F6B:100050FE5C925092FE9228FEAA92D6B282BAFED6AA92AA92D6929E82E2FE0282 +9F6C:080028FC2F102810FF7C142455246BFE41007F00557C55446B444F44717C0144 +9F6D:100050325CCC5088FE8828E8AAAED6AA82AAFEEAAA8AAA8AD68A9E8AE3120222 +9F6E:102050205DFC5020FE502888ABFED60882E8FEA8AAA8AAE8D6A89E08E2280210 +9F6F:100050205CCE5082FE8228EEAA82D68282FEFE28AA28AA28D6489E4AE28A0306 +9F70:104850485C4851FEFE482848ABFED60082FCFE84AA84AAFCD6849E84E2FC0284 +9F71:100051F05CAE50AAFEEA28AAAAAAD6EA82AAFEAAAAB4ABE4D6249E2AE22A0230 +9F72:100E51F05C1050FEFE922892AAFED61082FEFE92AA9AAA96D6FE9E82E28A0284 +9F73:100050FE5C925010FEFE2810AA7CD654827CFE54AA7CAA10D6FE9E10E2100210 +9F74:102050105CFE5044FE2828FEAA88D69082A4FE88AA90AAA2D6849E88E3100260 +9F75:1000507C5C545054FE7C2854AA54D67C8210FEFEAA92AA96D6BE9E82E28A0284 +9F76:100050EE5CAA50AAFEEE2800AA7CD60082FEFE20AA40AA7CD6049E04E2280210 +9F77:100050FE5C825082FEFE2880AABED6908294FEBEAA8AAA88D6BE9E88E308027E +9F78:104450285C0050FEFE002828AA44D6828200FEFEAAAAAAAAD6AA9EAAE3FE0200 +9F79:082004407FFC0100FFFE04001FF8E0801FFC010009F009007FFC24482AA83FF8 +9F7A:104050405CFE5122FEAA28FAAA42D6948348FEFEAB22AAAAD6FA9E42E2940308 +9F7B:101050105CFE5010FE7C2844AA7CD644827CFE44AA7CAA44D6FE9E28E2440282 +9F7C:108850885DFE5088FEDC29AAAA88D60083FEFE22AAA0AABCD6A09F60E23E0200 +9F7D:104450445DEE5044FEEE2954AA44D600827CFE00AAFEAA10D6549E92E2500220 +9F7E:0F1408127F10497E7E1049287F2852449EFA04807FFE04402AA431143FFC0004 +9F7F:0100010011F8110011001100FFFE00002108210822882448282820083FF80008 +9F80:0820082028202F2228222824FF2800304920496055A0632241224722791E0100 +9F81:0820082028202F7E28402880FF3C0004490849105520634041424742793E0100 +9F82:0800080C28702F4028402840FF7E004849484948554863484148474879480188 +9F83:0800087C28442F442844287CFF4400444944497C554463444144474479FE0100 +9F84:1020102050505E5050885124FE12001093FC9204AA08C68882508E20F2100210 +9F85:10401040507C5E84508451F4FE940094929492F4AA84C6A882928E82F27E0200 +9F86:080008FE28222F2228222822FF4A00444980497E5542634241424742797E0142 +9F87:1008102850285E2850A850AAFEBC00A892A892A8AAA8C6A882AA8EBAF2EA0386 +9F88:100010FC50845E8450FC5084FE8400FC92A292A4AA98C69082888EA4F2C20280 +9F89:100011FC50205E2050FC5044FE4401FE92009200AAFCC68482848E84F2FC0284 +9F8A:0800087C28442F4428442844FF7C001049104950555E635041504770799E0100 +9F8B:100E11F050105EFE50925092FEFE001092FE9292AA9AC69682FE8E82F28A0284 +9F8C:100010FE50825E8250FE5080FEFE009092A492FEAA92C69082FC8E90F31002FE +9F8D:104008407E7E2440187EFF02007E7E40427E7E40427E7E40427E42404A42443E +9F8E:00003FFE22202FBC2520223C3F84203C2FA028BC2FA028BC2FA048BC48A2899E +9F8F:08407F7C1440FF7C22043E7C22403E782242263E08200820FFFE082010202020 +9F90:00807FFE42205FBC4920463C7F84403C5FA050BC5FA050BC5FA050BC52A2911E +9F91:08407F7C1440FF7C22043E7C22403E782242263E00003FF80200FFFE0860701C +9F92:08407F7C1440FF7C22043E7C22403E7C2242263E00003FF80000FFFE11102308 +9F93:21102090FBDE2010425E79824BDEC8107BDE4A504BDE7A504BDE4A504A525ACE +9F94:08407F7C1440FF7C22043E7C22403E782242263E04403FF80440FFFE08201010 +9F95:010006C01830EFEE00001FF010101FF008403E7C1440FF7822083E782242263E +9F96:88884E4EF8F8A8A84E4EF2F20E0EE8E8AEAEA8A8EEEEA8A8EEEEA8A8AAAAA6A6 +9F97:3FF801007FFE492284143BB82AA83BB808403E7C1440FF7822083E782242263E +9F98:08403E7C1440FF7822083E782242487EE8E8AEAEF8F80E0EE2E2AEAEE8E8AEAE +9F99:0420041004100400FFFE048004880488049008A008C0108211822282447E8000 +9F9A:042004107FFC092009C4170420FCC44004403FF804400440FFFE082010102008 +9F9B:010006C01830EFEE00001FF010101FF004400420FFFE0910116021844F0480FC +9F9C:04003FF820083EF802807A800AFCFE940AD47AA402A47AD40A94FEFC0A8279FE +9F9D:1080E7FC240427BC20A0FEBE22A237B66AAA66AAA0B626A222BE27A022A2267E +9F9E:49202A3E7F485DA86B10456E3FF820083EF802807AF80AD8FEA80AD87A8A01FE +9F9F:040004000FE0102020407FF8A10821083FF8210821083FF821080102010200FE +9FA0:010002800C603018DFF600003BB82AA83BB800003FF824883FF8248824A82010 +9FA1:08100810141022105D3E80A27F4455907F1000107F1055287F28552455444382 +9FA2:0808081C14F022105D1080907F7C55107F3800347F5455547F92551055104310 +9FA3:080008FC140422045D7C80847F0455FE7F1000927F5455387F54559255504320 +9FA4:0848084A146C22485D4A80EA7F5655207F7E00427F42557E7F425542557E4342 +9FA5:0800087E140822105D7C80C47F44557C7F44007C7F4455447F7C552855444382 +9FA6:112410A410A813FE16025AFA508890F8102011FC112429242524452C40208020 +9FA7:01FC010479FC490449FC484479F848504FFF48804BFC7D0449FC010401FC0104 +9FA8:00003FFC228024402FFC3440244027F8244027F82440244027FC24003FFC0000 +9FA9:04200420FFFF0420240CFF7024403C40087F7E484A487E480848FF8808880908 +9FAA:0820082008207E2008200820FF20085008500E502848288828845B02480087FF +9FAB:10101010FF1010287E445282537C7E10521052107EFE1010FF10101010101010 +9FAC:100013FE1A02268A22527FFE924212227FFE128216825A8232FA1E02E20A0204 +9FAD:7DFE51227DFE512251227DFE504850487EFC0248564853FE8200024814840902 +9FAE:7FDE514A7CC6514A52527CFC50A450FC7EA402FC564852FE824803FE14840902 +9FAF:10281024282025FE4120B920112411247D28111815105910312A1E2AF2464482 +9FB0:0000000000000100010001000100010011F011001100110011002D00430080FC +9FB1:00007FFC4004402448244424424441444084414442244414581440047FFC4004 +9FB2:1020101029FE251041FEBD10117C11547D7C1154157C591031FE1E10E2104410 +9FB3:101010107EFC10101010FEFE2448529410107E7C1010101010101E10E1FE0000 +9FB4:00000000000000007FFC00080010032000C00020001000000000000000000000 +9FB5:00F87F0001003FF80100FFFE0200040008003000C00000000000000000000000 +9FB6:010001007FFC01003FF80100FFFE000000000000000000000000000000000000 +9FB7:082008207FFC08200820FFFE0000000000000000000000000000000000000000 +9FB8:01001110092001007FFE40048008000000000000000000000000000000000000 +9FB9:1110092001003FFC010002007FFE082010102008C00600000000000000000000 +9FBA:10001000FE0010007C00440044007C0044007C0054001000FE00100010001000 +9FBB:208827E84812F3DC20084BD2F83E03C0AA52ABD2000000000000000000000000 +9FBC:0040207C204027FE240223FCFA642492210823FC250A21F83908C1F8010801F8 +9FBD:1080108010FC1108561055FC5524992411FC1124112429FC24004554412A822A +9FBE:08400840087E7F424AA248AA48727EFE4222627254AA4D2288229402220A4004 +9FBF:08200820FFFE0820044008400BF81040304057FC904013F81040104017FE1000 +9FC0:0420FFFE04207F7850485E8665784A487F3000C8FFFE04403FF824482BA83FF8 +9FC1:209010900090FC9003FC78900090789000907BFE48004800489079084A040404 +9FC2:10201040FEFC10847CFC54847CFC548054FE7C8054FE1002FEAA10AE1152100C +9FC3:00400040F7FC90409250F148914892D4F460904090A090A0F110920804040802 +9FC4:10000BF840882288098850C82108222825100100FFFE05400920111C61080100 +9FC5:21FC102003FEFA2209AC1020118C382054509188162611F8100810D010201010 +9FC6:404020400040FBFE0880108020F830886948A150215022202220245028882104 +9FC7:088008F81110122035FC5044904417FE1044104413FC10441040104011401080 +9FC8:080009FC11042104490409FC1124312051209110111011101208120814041802 +9FC9:08000BFE104020404840084013F8304850489088108810881088108817FE1000 +9FCA:08200820FFFE082008204000202090204120293C11201120E1202120212027FE +9FCB:204017FE0040FBFC08001BF816083BF855109FFE100013F81208120813F81208 +9FCC:008040402FFE2000800043F84A080BF8120813F8E04022482244244229420080 +9FCD:2080208020FC21082290F86021982626202021FC3C20E22043FE002000200020 +9FCE:00100010FA102110217E401078104F28C92849244944494279024A80447E0000 +9FCF:102010203DFE202041FCBC20102013FEFC40107C108411481450182010D80706 +9FD0:200024FE72285228A0FE74AA52AA53AA79AE52C256827AFE0282AA82AAFE0082 +9FD1:000047FE2040204000400840084013FC1040E040204820442044204027FE0000 +9FD2:08200820FFFE08207FFC02001FF0101011101110111012100280046018106008 +9FD3:08200820FFFE08207FFC04001FF010101FF010101FF010101FF0082010102008 +9FD4:200023FE3C0821E841287DE8900013FEFC0811E81128112815E8180810280010 +9FD5:200020FC7C84448488A47C94549454847FFE548454847C8401041D04E2144408 +9FD6:010001000280044008203018CFE600001FF01010101010101FF010100000FFFE +9FD7:01000280044008203018C8060BF0089017FE309053F09080110012000000FFFE +9FD8:10101F101528252825447F44A5BA250025002F7C2544244424442844287C3044 +9FD9:10101F1015FE2510257C7FC4A5442544257C2F28252824282448284A288A3306 +9FDA:20503E502A5C4A544AF4FF484A484A744AD45F624A5C485448545054505C6054 +9FDB:040084FE5E54449205FE3E924AD651BA68D6CE9252D66ABA44D64C92529A2184 +9FDC:480044FE44544092FFFE409272D652BA52D6CA924AD64ABA44D644925F9AC084 +9FDD:40005FFE55545592F5FE5F9248D6C4BAFFD6C8924ED64ABA4AD652925A9A6484 +9FDE:0200E2FE42544A926BFEAA92AAD6AABAEAD6AA922AD62ABA42D642924A9A8484 +9FDF:11203920E120253E25422544FD902510655475546D52A592A192211025502220 +9FE0:120032FEE2542A922BFE2A92FAD62ABA6AD67A926AD6AABAA2D622922A9A2484 +9FE1:0000FEFEAA54AA92FFFE24922AD65FBADAD62F925AD6FFBA0AD6AA92AF9A8884 +9FE2:0010FF10552855287544564456BA75005500557C55447D44D6441444147C1444 +9FE3:0010FF1055FE5510757C564456447544557C552855287D28D648144A148A1506 +9FE4:0050FF50555C555475F456485648757455D45562555C7D54D6541454145C1454 +9FE5:40002EFEEA54AA92ABFEEC92ACD6AABAEAD69A92EAD6AABA9CD6B892D89A8884 +9FE6:51445154FA54525425FEF91AAA0AAAFAAE0AFAEA22AA22A452B44AAA4B0A820A +9FE7:0400EEFEAA54BA92A4FECA92D1D6AEBAA4D6A492BFD6C4BA8ED684929F9A8084 +9FE8:00007EFE1054FE9291FE569210D6D6BA00D67E924AD64ABA7ED64A924A9A7E84 +9FE9:20003CFE24547E92D3FE7E9252D67EBA2AD6D5927ED642BA7ED642927E9A4284 +9FEA:211010A017FC0080F14816D0116816A8112416A4284047FE0000244422224222 +9FEB:20003FFC40009FF000007FF008107FD055504E507FD04E52554AFFEA0A06F1E2 +9FEC:000000007DFF1111111121113D1165FFA5112511251125113DFF210100000000 +9FED:104010401C7F208121127A1090101054FC521092109111111410181010500020 +9FEE:00803FFE200024442FFE244427FC200027FE284223FC2244424C424080400040 +9FEF:000050807EFE50AA952A384AD11212860C603118C92605407FFC03800D60711C +9FF0:01082108110817DF810847C8545E17C8244827DFC10947C9410D410A41080108 +9FF1:00000000FDFC11241124112411247DFC11041100110011001D02E10240FE0000 +9FF2:0044FDFF004400007CFF4511441044FE7C120012441228222E42F08441080000 +9FF3:204420823DE2452F49297DAAD56855E97D2A55AC55687D295529B2292AA70040 +9FF4:102010201E7E228225447E28AA182A243E422A812A303E0800040E6070102008 +9FF5:202020203C2045FE48207C20D42055FC7C00542054127D5101451A45E03C4000 +9FF6:204020203DF8450849087DF8D50855087DF8554455487D3001101D48E1864100 +9FF7:102010101E7C220024443E286AFE2A003E7C2A442A443E7C00440E44707C2044 +9FF8:204420823DE2452F49297DAAD56855E97D2A55AC55687D2901291E29E2A74040 +9FF9:202020103CFF4481494A7C28D55256657CC4553C54107C9200921C92E0FE4002 +9FFA:081008207F7C08443E6408547F44104C1E40227E24025402087A1402200A4004 +9FFB:2010CE108210EEFE82208248FE48008892FF92C9DB499249DA4D924A9308D908 +9FFC:2040CE408240EE4782F58255FE55005592559255DA559255DA9592D793A5D900 +9FFD:00007FFE73866DBE718E7DBE73BE7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +9FFE:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FBE638E6FBE6F867FFE0000 +9FFF:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +A000:000000000000000010101FF010101010101010107C101010082007C000000000 +A001:000003800440000010101FF010107C10121012107C101010082007C000000000 +A002:000000000000000010101FF010107C10121012107C101010082007C000000000 +A003:000000000000000000600050004800403BC004400A400A4004403BC000000000 +A004:0000000000000000139014500C6007C0044004400E4004400440038000000000 +A005:0000038004400000018001600100038004400440038001000D00030000000000 +A006:0000000000000000018001600100038004400440038001000D00030000000000 +A007:0000000000000000071008F009900A800A800A800A80099008F0071000000000 +A008:000000000000000000080008018831680D180300010001000100010000000000 +A009:000003800440000001A0016001200D2003200120012001200D20032000000000 +A00A:000000000000000001A0016001200D2003200120012001200D20032000000000 +A00B:0000000000300040034002C002401A3006000200020002001A00060000000000 +A00C:0000038004400000101011101110111010101FF0101011101110111000000000 +A00D:0000000000000000101011101110111010101FF0101011101110111000000000 +A00E:00000000000004200A500A50042004200420042004200420042003C000000000 +A00F:00000000000000000FE0111011100FE001000700080007000800070000000000 +A010:00000380044000000C700A880988088808A808A808A848882888187000000000 +A011:00000000000000000C700A880988088808A808A808A848882888187000000000 +A012:00000000000000000C700A880988088808880888088848882888187000000000 +A013:000003800440000000603858044008401FC0084004403840034000C000000000 +A014:000000000000000000603858044008401FC0084004403840034000C000000000 +A015:00000000000000001110111011100EE000000000044004400440044000000000 +A016:0000000000000000038004400440055004E004E0055004400440038000000000 +A017:000003800440000010F011001200120012001FF012001200110010F000000000 +A018:000000000000000010F011001200120012001FF012001200110010F000000000 +A019:0000000000000000062005A00460040004F0050007F0050004F0040000000000 +A01A:00000000000000001C18222022402240224023F82240224022201C1800000000 +A01B:000003800440000007D00820105010901110111012101410082007C000000000 +A01C:000000000000000007D00820105010901110111012101410082007C000000000 +A01D:00000000000000000700089008880888089008E0089008880888071000000000 +A01E:0000000000000000082008200FE0082008200380044004400440038000000000 +A01F:0000038004400000082008200FE00820082000001110111011100EE000000000 +A020:0000000000000000082008200FE00820082000001110111011100EE000000000 +A021:0000000000000000082008200FE0082008200000000004400820101000000000 +A022:000003800440000003E0041009D00090009001D000100E100990086000000000 +A023:000000000000000003E0041009D00090009001D000100E100990086000000000 +A024:00000000000000000FE0010001000100010001000100010001000FE000000000 +A025:000000000000000000F01700090014801070148009001700010000F000000000 +A026:000003800440000007C0082008200BA0092009200BA00820082007C000000000 +A027:000000000000000007C0082008200BA0092009200BA00820082007C000000000 +A028:00000000000000001FF0010001001FF0000000001FF0010001001FF000000000 +A029:00000380044000000EE01110111001000100000011101110082007C000000000 +A02A:00000000000000000EE01110111001000100000011101110082007C000000000 +A02B:00000000000000000FE0010009200540038003800540092001000FE000000000 +A02C:00000000000000000FE01010101010100FE00100012001200100010000000000 +A02D:0000038004400000010001000100010001200120012001200D20030000000000 +A02E:0000000000000000010001000100010001200120012001200D20030000000000 +A02F:000000000000000001E0020004E0050005000500050004E0020001E000000000 +A030:00000380044000000860088008800BE008800BE0088008800880070000000000 +A031:00000000000000000860088008800BE008800BE0088008800880070000000000 +A032:0000000000000000030002C00200039002500220022002501B90060000000000 +A033:0000038004400000018001600100016001800160011001600D80036000000000 +A034:0000000000000000018001600100016001800160011001600D80036000000000 +A035:00000000000000000CC00AA00990088008801C800880088022801C8000000000 +A036:00000380044000000030002800241FE022204AA042204AA022201FE000000000 +A037:00000000000000000030002800241FE022204AA042204AA022201FE000000000 +A038:00000000000000000060005000480FC010403FC020403FC010400FC000000000 +A039:000003800440000001C002201220122012E017201A200220022001C000000000 +A03A:000000000000000001C002201220122012E017201A200220022001C000000000 +A03B:00000000000000000000110011000A500A5004500A500A501100110000000000 +A03C:00000380044000000E0011001100115011501F501150115011000E0000000000 +A03D:00000000000000000E0011001100115011501F501150115011000E0000000000 +A03E:000000000000000007C0082011101110082007C00100111011100EE000000000 +A03F:0000000000000000000010101010101010101FF0101010101010101000000000 +A040:00000380044000001110111011101FF01110111011101110092007C000000000 +A041:00000000000000001110111011101FF01110111011101110092007C000000000 +A042:0000000000000000088008900890089008F00890089008900880070000000000 +A043:000003800440000007F008000FF0080007F000800AA00AA00AA0008000000000 +A044:000000000000000007F008000FF0080007F000800AA00AA00AA0008000000000 +A045:000000000000000007F009100FF0091007F0001008100810042003C000000000 +A046:0000000000000000070008A0089008901CA008C01CA008900890072000000000 +A047:00000380044000000920092009200540038000000FE0000000000FE000000000 +A048:00000000000000000920092009200540038000000FE0000000000FE000000000 +A049:000000000000000007F008000FF0080007F0008007F0008007F0008000000000 +A04A:0000000000000000062005A004600400040004000400046005A0062000000000 +A04B:00000380044000000FE0102010200FE0102010200FE0102010200FE000000000 +A04C:000000000000000007F00810081007F00810081007F00810081007F000000000 +A04D:00000000000000C000B0078008800A800A800880078000800680018000000000 +A04E:00000380044000000E0011001150155015F015501150110011000E0000000000 +A04F:00000000000000000E0011001150155015F015501150110011000E0000000000 +A050:000000000000000000C000A00090078008801080108010800880078000000000 +A051:0000038004400000000030182828244822A8212822A824482828301800000000 +A052:0000000000000000000030182828244822A8212822A824482828301800000000 +A053:00000000000000000CC00AA0099008801CA008A008A008A022801C8000000000 +A054:000003800440000008C008A00890008007800890109010900880078000000000 +A055:000000000000000008C008A00890008007800890109010900880078000000000 +A056:00000000000000000380044007C0044007C004400380111011100EE000000000 +A057:0000038004400000010011100920054003800380054009201110010000000000 +A058:0000000000000000010011100920054003800380054009201110010000000000 +A059:000000000000000037D80820145012901290129012901450082037D800000000 +A05A:000000000000000007C008200820082007C011100EE000000100010001000000 +A05B:00000380044000000000007800800D180B200978092009186880187800000000 +A05C:0000000000000000003C0040008C069005BC0490048C0440343C0C0000000000 +A05D:0000000000000000181804200240024002400FF0024002400420181800000000 +A05E:00000000000000000000300C0FF00420024003C0024004200FF0300C00000000 +A05F:000003800440000000000406020A47122AA212422AA24712020A040600000000 +A060:000000000000000000000406020A47122AA212422AA24712020A040600000000 +A061:00000000000000001110111011100EE0000000000FE0000000001FF000000000 +A062:00000380044000000CA00AA009A000200FA000200FA0002001A0006000000000 +A063:00000000000000000CA00AA009A000200FA000200FA0002001A0006000000000 +A064:0000000000000000038014501450145004400440145014501450038000000000 +A065:0000000000000000008000800790089010901090089007900080008000000000 +A066:000003800440000001000920054003800540092001000FE001000FE000000000 +A067:000000000000000001000920054003800540092001000FE001000FE000000000 +A068:00000000000000000EE01110010007C00820111011100100082007C000000000 +A069:00000380044000000640054034D02C10231020D0203007800000078000000000 +A06A:0000000000000000032002A01A68160811881068101803C0000003C000000000 +A06B:0000000000000000314029442548235000603F4000400240014000C000000000 +A06C:0000000000000000304C08500850304C034002C0320C0A100A10320C00000000 +A06D:00000380044000000010019001500D300B000920092029201900010000000000 +A06E:0000000000000000000800C800A8069805800490049014900C80008000000000 +A06F:000000000000000000C018B01688118000900090189016801180100000000000 +A070:0000038004400000002000201820162011A0106001C0022002A002A000000000 +A071:0000000000000000002000201820162011A0106001C0022002A002A000000000 +A072:0000000000000000066005D0044005400540044007C0044015400CC000000000 +A073:0000038004400000019001700110010001000100010011001D00130000000000 +A074:0000000000000000019001700110010001000100010011001D00130000000000 +A075:0000000000000000018001600D00030001000100018001600D00030000000000 +A076:000000000000000003000AC00A300A0002A002A00BE00AA00AA0020000000000 +A077:000003800440000007C009200FE0092007C0010001400150011000E000000000 +A078:000000000000000007C009200FE0092007C0010001400150011000E000000000 +A079:00000000000000001860165011C81040104011F0104011F01040104000000000 +A07A:00000700088000001FC00220021002001FC0020002001FC00200020000000000 +A07B:00000000000000001FC00220021002001FC0020002001FC00200020000000000 +A07C:0000000000000000010001000FE001000100010001000FE00100010000000000 +A07D:00000000000000000E0011141114208420FC20842094249424801B0000000000 +A07E:00000380044000000000044004401FF00280010002801FF00440044000000000 +A07F:00000000000000000000044004401FF00280010002801FF00440044000000000 +A080:0000000000001010145014501290129011101290129014501450101000000000 +A081:0000000000000000038802680E18124022402240224002180268038800000000 +A082:038004400000111011100EE000000100010007C00100010010100FE000000000 +A083:000000000000111011100EE000000100010007C00100010010100FE000000000 +A084:00000000000000001110111011100EE0000001000100111010100FE000000000 +A085:000000000000000003D005300910090009F0090009000910052003C000000000 +A086:000003800440000009C00A2002200E20122012200E2002200A2009C000000000 +A087:000000000000000009C00A2002200E20122012200E2002200A2009C000000000 +A088:0000000000000000010007C009201110115011501110092007C0010000000000 +A089:00000380044000003838454445444444444447C4444444444544393800000000 +A08A:00000000000000003838454445444444444447C4444444444544393800000000 +A08B:0000000000000770088009A00AA00A800BE00A800AA009A00880077000000000 +A08C:000003800440000011501150111011501F50111011501150092007C000000000 +A08D:000000000000000011501150111011501F50111011501150092007C000000000 +A08E:00000000000000006360145813461440634000400C400B4008C0080000000000 +A08F:000003800440000031182928254823883FF82388254829283118010000000000 +A090:000000000000010031182928254823883FF82388254829283118010000000000 +A091:0000000000000000018001600100092009200920092001000D00030000000000 +A092:00000380044000001110092007C001001FF0010007C009201110111000000000 +A093:00000000000011101110092007C001001FF0010007C009201110111000000000 +A094:000000000000000007C00920111012901290129013901450082007C000000000 +A095:0000038004400000155015501110092007C001000100110011000E0000000000 +A096:0000000000000000155015501110092007C001000100110011000E0000000000 +A097:0000000000000000001001900150013001000920092009200100010000000000 +A098:00000000000000000600058004000400058004200710048034480C4800000000 +A099:0000038004400000001030102C10231020D02038204400440044003800000000 +A09A:0000000000000000001030102C10231020D02038204400440044003800000000 +A09B:000000000000000000C030B0088C048004803F80048004800880308000000000 +A09C:00000380044000000240024012480A50046000400C400B4008C0080000000000 +A09D:00000000000000000240024012480A50046000400C400B4008C0080000000000 +A09E:000000000000000009800960091809000180016031182D002300200000000000 +A09F:000000000000000000600050004807C00840124015401240084007C000000000 +A0A0:000003800440000001801160111801000F8811482520250011000F0000000000 +A0A1:000000000000000001801160111801000F8811482520250011000F0000000000 +A0A2:000000000000000003C004200400020001800040012002A0092007C000000000 +A0A3:0000000000000FE008200440028002A0012002A00280044008200FE000000000 +A0A4:00000380044000000020092009200020092009200020062001A0006000000000 +A0A5:00000000000000000020092009200020092009200020062001A0006000000000 +A0A6:000000000000000007C00920155015501110111015501550092007C000000000 +A0A7:0000038004400000111011101010082007C00000082008200820082000000000 +A0A8:0000000000000000111011101010082007C00000082008200820082000000000 +A0A9:000003800440000001000100012009200920090001C001200D10031000000000 +A0AA:000000000000000001000100012009200920090001C001200D10031000000000 +A0AB:00000000000008500850001008500850001008500850031002D0023000000000 +A0AC:000003800440000007C009200FE0092007C001000540155011100EE000000000 +A0AD:000000000000000007C009200FE0092007C001000540155011100EE000000000 +A0AE:000000000000000007C0082016D01290111017D010101390082007C000000000 +A0AF:0000038004400000031002D002300200023002C0030012C00A30060000000000 +A0B0:0000000000000000031002D002300200023002C0030012C00A30060000000000 +A0B1:00000000000000C800A8009800800FF800800FF8008018800680018000000000 +A0B2:000003800440000007C00820145022882128212822881450082007C000000000 +A0B3:000000000000000007C00820145022882128212822881450082007C000000000 +A0B4:0000000000000000000800C800A8109810801090009018900680018000000000 +A0B5:00000000000000001860175012C81240124012401FC012401240124000000000 +A0B6:0000038004400000038004400440044004401FF0044004400440038000000000 +A0B7:0000000000000000038004400440044004401FF0044004400440038000000000 +A0B8:00000000000000001110111011100EE00000010007C0010007C0010000000000 +A0B9:000000000000121011101090121011101090121011101090082007C000000000 +A0BA:000003800440000000C006B0058004C004B014800CC000B00680018000000000 +A0BB:000000000000000000C006B0058004C004B014800CC000B00680018000000000 +A0BC:00000000000000000638054404C404541F5404541F54044434440C3800000000 +A0BD:000000000000000000C000A00090008007800880128012800880078000000000 +A0BE:000003800440000001800160011801C0012001C0010007C00920092000000000 +A0BF:000000000000000001800160011801C0012001C0010007C00920092000000000 +A0C0:000000000000000003C00420081000100010001000100E100990086000000000 +A0C1:000003800440000001000118012401240FE40124012431180D00030000000000 +A0C2:000000000000000001000118012401240FE40124012431180D00030000000000 +A0C3:0000000000000000009000880A880A900AE00090008818880690018000000000 +A0C4:0000038004400000042004200420042007E004200420242014200C2000000000 +A0C5:0000000000000000021002100210021003F00210021012100A10061000000000 +A0C6:00000000000000000388045003E0004001F0024801F018400640018000000000 +A0C7:00000380044000000080008008F008800880008000F018800680018000000000 +A0C8:00000000000000000080008008F008800880008000F018800680018000000000 +A0C9:00000000000000000C200B2008E008000F700880094008800F70080000000000 +A0CA:0000038004400000101010101010082007C00000082008200820082000000000 +A0CB:0000000000000000101010101010082007C00000082008200820082000000000 +A0CC:0000000000000000020002200220022002000FF0020002200220022000000000 +A0CD:00000000000000000380044004401EF008201EF008200920092006C000000000 +A0CE:000003800440000000C000B00480078004800080008000800680018000000000 +A0CF:0000000000000000018000B00480078004800080008000800680018000000000 +A0D0:000000000000000000C000B008800F800880008000800E800980080000000000 +A0D1:00000000000009200AB00AAC092008200FE0082009200AA06AA0192000000000 +A0D2:000003800440000018081608118810681018014009480948041003E000000000 +A0D3:000000000000000018081608118810681018014009480948041003E000000000 +A0D4:00000000000000001808160811881068101802200AA80888041003E000000000 +A0D5:0000038004400000012000A018E0052002200220052018E000A0012000000000 +A0D6:0000000000000000009000500C7002900110011002900C700050009000000000 +A0D7:0000000000000000092005200720090011F01100092007200520090000000000 +A0D8:0000000000000000030012C01230120002200220122012001200020000000000 +A0D9:00000380044000000820282828282828183008200FE008200820082000000000 +A0DA:00000000000000000820282828282828183008200FE008200820082000000000 +A0DB:0000000000000000000002400240181016601180166018100240024000000000 +A0DC:0000038004400000000801883968051823002300050039000100010000000000 +A0DD:0000000000000000000801883968051823002300050039000100010000000000 +A0DE:0000000000000000009000A000C0009000A000C0188016801180100000000000 +A0DF:0000038004400000111011101510092017C0010031002D002300200000000000 +A0E0:0000000000000000111011101510092017C0010031002D002300200000000000 +A0E1:000000000000000010101010082007C00100012031402D802300200000000000 +A0E2:000000000000000011101110082007C001001900150013001000000000000000 +A0E3:0000038004400000001800200040064005C004400440044034200C1800000000 +A0E4:0000000000000000001800200040064005C004400440044034200C1800000000 +A0E5:00000000000000001C1013901170010001C009200920092001C0010000000000 +A0E6:000000000000000011101110111011100110012001C031000D00030000000000 +A0E7:000003800440000009200540139013900540092001000FE001000FE000000000 +A0E8:000000000000000009200540139013900540092001000FE001000FE000000000 +A0E9:00000000000000003FF80100010009C00920092009C0010001003FF800000000 +A0EA:000000000000000007C0082010101FF0101010101FF01010082007C000000000 +A0EB:0000038004400000101010101390145008201450139010101010101000000000 +A0EC:0000000000000000101010101390145008201450139010101010101000000000 +A0ED:0000000000000000030002C0020032380EC803080EC832381A00060000000000 +A0EE:0000000000000000024002401A48164813C81268125802400240018000000000 +A0EF:000003800440000000800C88129012A012C00C80008018800680018000000000 +A0F0:000000000000000000800C88129012A012C00C80008018800680018000000000 +A0F1:000000000000002401A41F74212C212011000F001100210021001F0000000000 +A0F2:000003800440000001E000100C10102011C010200C100010001001E000000000 +A0F3:000000000000000001E000100C10102011C010200C100010001001E000000000 +A0F4:0000000000000000003000280224142008A015202220052008A0004000000000 +A0F5:0380044000001C700380044008203E2008203E200820044003801C7000000000 +A0F6:0000000000001C700380044008203E2008203E200820044003801C7000000000 +A0F7:000000000000008000400FE00820044002800100028004400920111000000000 +A0F8:000003800440000000200020002001E002201F2004201F20022001E000000000 +A0F9:000000000000000000200020002001E002201F2004201F20022001E000000000 +A0FA:000000000000018001402128210811104FE441044FE411102108210800000000 +A0FB:000003800440000010101010082007C000000820082009200100010000000000 +A0FC:000000000000000010101010082007C000000820082009200100010000000000 +A0FD:000000000000000001802148210811100FE401040FE411102508230800000000 +A0FE:000003800440000011101110092007C01110111001001FF001001FF000000000 +A0FF:000000000000000011101110092007C01110111001001FF001001FF000000000 +A100:0000000000000000008832842A84268800F0008832842A842688008000000000 +A101:000003800440000000C004A0029012800C800080188016801180100000000000 +A102:000000000000000000C004A0029012800C800080188016801180100000000000 +A103:000000000100020001000080111011100EE00440054005400440038000000000 +A104:0000038004400000001C0020004C065005D004500450044C34200C1C00000000 +A105:0000000000000000001C0020004C065005D004500450044C34200C1C00000000 +A106:00000000000000000420042072424E4241824272424E04200420042000000000 +A107:0000000000000000110011201120112011001FF81100112011200E2000000000 +A108:0000000003800440000010180828044812881108128804480828101800000000 +A109:0000000000000000000010180828044812881108128804480828101800000000 +A10A:00000000000000000000080C04141A2415441084514432240414080C00000000 +A10B:0000038004400000002000A000A008A00EA009A00020062001A0006000000000 +A10C:0000000000000000002000A000A008A00EA009A00020062001A0006000000000 +A10D:00000000000000000100010007C009200920082008200820082007C000000000 +A10E:000003800440000001800160011801001FF0010031002D002300200000000000 +A10F:000000000000000001800160011801001FF0010031002D002300200000000000 +A110:000000000000000001800160011801001FF00100010031000D00030000000000 +A111:03800440000001C00130010007C0054003800380054007C00100190007000000 +A112:0000000001C00130010007C0054003800380054007C001001900070000000000 +A113:000000000000000018081608118810E81098008003E004900888088800000000 +A114:0000000000000000041008900910071009100890041000100190007000000000 +A115:00000380044000001E20212021C01E8000F0088008F008800088007000000000 +A116:00000000000000001E20212021C01E8000F0088008F008800088007000000000 +A117:00000000000000000FE01010101010100FE0010001F00100010000F000000000 +A118:000003800440000001800160011801001FF00100050005000500010000000000 +A119:000000000000000001800160011801001FF00100050005000500010000000000 +A11A:000000000FE0000001800160011801001FF00100010031000D00030000000000 +A11B:00000380044000000080008027F02080208027F0008018800680018000000000 +A11C:00000000000000000040004013F81040104013F800400C40034000C000000000 +A11D:00000000000000000008018801680118010001001FF001000100010000000000 +A11E:000003800440000008C004B024801880008007F0008000800680018000000000 +A11F:000000000000000008C004B024801880008007F0008000800680018000000000 +A120:00000000000000000850085007900010079008500850031000D0003000000000 +A121:00000000000000000FE0001003900410041004100410039000100FE000000000 +A122:00000380044000000820082000001FE0001000101FE000000840084000000000 +A123:00000000000000000820082000001FE0001000101FE000000840084000000000 +A124:0000000000000FE0001000100F9000100F9000100F90001000100FE000000000 +A125:0000000000000000711C092009201010600C1010092009200920701C00000000 +A126:03800440000000100FF000100FF000100FF00010031002D00230020000000000 +A127:00000000000000100FF000100FF000100FF00010031002D00230020000000000 +A128:000000000000000008040AC40AB4088C0A800A8008804A802A80188000000000 +A129:0000000000000000018001600100018001600100018001600D00030000000000 +A12A:000003800440000001801160111811800160011831802D602318200000000000 +A12B:000000000000000001801160111811800160011831802D602318200000000000 +A12C:00000000000000003C78410441043C78410441043C78410441043C7800000000 +A12D:000003800440000012480A88070807080A8812480F8802080788007800000000 +A12E:000000000000000012480A88070807080A8812480F8802080788007800000000 +A12F:0000000000000000030002C00230030002C0023002000F801240124000000000 +A130:00000000000000000E00117011801100112011201100118011700E0000000000 +A131:000003800440000007C00820101010101010101010101010082007C000000000 +A132:000000000000000007C00820101010101010101010101010082007C000000000 +A133:000000000000000007F008080808080807F000401650155014D0040000000000 +A134:000003800440000001800D600B000928092829F8192801280D00030000000000 +A135:000000000000000001800D600B000928092829F8192801280D00030000000000 +A136:000000000000000018081608118810E810980080049004900490008000000000 +A137:000003800440000010C008B00480108008800480008000800680018000000000 +A138:000000000000000010C008B00480108008800480008000800680018000000000 +A139:000000000000000018881688118810E8109800800FF8008000800FF800000000 +A13A:0000038004400000210821083FF82108210801000FE0010001000FE000000000 +A13B:0000000000000000210821083FF82108210801000FE0010001000FE000000000 +A13C:0000000000000000010021083FF82108010007C0092011101110111000000000 +A13D:00000000000000001FF0010007C0092009200920092007C001001FF000000000 +A13E:0380044000001FF00100311C0D6403840D64311C01001FF001001FF000000000 +A13F:0000000000001FF00100311C0D6403840D64311C01001FF001001FF000000000 +A140:000000000FE001000FE001003908270821C8213801000FE001000FE000000000 +A141:00000380044000000FE001000380054009200920092009200540038000000000 +A142:00000000000000000FE001000380054009200920092009200540038000000000 +A143:00000000000000000FE001000FE0082004400280010002800440082000000000 +A144:000000000000000001800140012001000100092007C000000920092000000000 +A145:0000038004400000111011101FF011101110092007C000000920092000000000 +A146:0000000000000000111011101FF011101110092007C000000920092000000000 +A147:000000000000031002D002300F800200020010400F8000001240124000000000 +A148:00000380044000000EE0010002800440054005400440028001000EE000000000 +A149:00000000000000000EE0010002800440054005400440028001000EE000000000 +A14A:000000000000000008600FD02848184003C0044008400840044003C000000000 +A14B:0000000000001FC0104008800510051003F005100510088010401FC000000000 +A14C:0000038004400000111011101110092007C00100110011001100010000000000 +A14D:0000000000000000111011101110092007C00100110011001100010000000000 +A14E:00000000000000000F8010801088088807F808881088108010800F8000000000 +A14F:000003800440000011101110111011101110111011101110092007C000000000 +A150:000000000000000011101110111011101110111011101110092007C000000000 +A151:0000000000000000008000801808160811881068101800000490049000000000 +A152:0000038004400000002008200FE008200020002008200E2009A0006000000000 +A153:0000000000000000002008200FE008200020002008200E2009A0006000000000 +A154:000000000000000003800440044009200920082008200920092006C000000000 +A155:000003800440000001800160210817D0111017D0210801000D00030000000000 +A156:000000000000000001800160210817D0111017D0210801000D00030000000000 +A157:00000000000000000C60125013C812400C4000400C400B4008C0080000000000 +A158:00000380044000000C60125012480C4000401FF80040074004C0040000000000 +A159:00000000000000000C60125012480C4000401FF80040074004C0040000000000 +A15A:0000000000000000188824A824A824A818A800F000A018A006A0018000000000 +A15B:0000000000000000004007F008400FF0084007F000400E4009C0080000000000 +A15C:0380044000000400099012501250125011900810031002D00230020000000000 +A15D:0000000000000400099012501250125011900810031002D00230020000000000 +A15E:0000000004000800101014501450111011100810031002D00230020000000000 +A15F:0000038004400000183024282424242019E0022004200420022001E000000000 +A160:0000000000000000183024282424242019E0022004200420022001E000000000 +A161:00000000000000000660095829402940264010400FC00040034000C000000000 +A162:00000000000000000000088008800520052003E0052005200880088000000000 +A163:00000380044000000120012001200120012001C00100111011100FE000000000 +A164:00000000000000000120012001200120012001C00100111011100FE000000000 +A165:00000000000000000FE01010101010100FE001001FF001001FF0010000000000 +A166:00000380044000000FE01010101010100FE001001F2001201F20010000000000 +A167:00000000000000000FE01010101010100FE001001F2001201F20010000000000 +A168:0000000000000000098011601118090001001FF001001FF00100010000000000 +A169:0000038004400000018001600118010001001FF001001FF00100010000000000 +A16A:0000000000000000018001600118010001001FF001001FF00100010000000000 +A16B:0000000000000000018001402128210811100FE001000FE01110210821080000 +A16C:000000000000000001800140012001001FF001000FE010102108210800000000 +A16D:000003800440000011101110092007C001001900150013401040018000000000 +A16E:000000000000000011101110092007C001001900150013401040018000000000 +A16F:000000000000046025582546044064401C4000400C400B4008C0080000000000 +A170:00000000000000000010031002D0023002001FC802081FC80200020000000000 +A171:000003800440000000080188016801180D000B80296019180100010000000000 +A172:000000000000000000080188016801180D000B80296019180100010000000000 +A173:00000000000000000FE008200440038004400820018001400500030000000000 +A174:000003800440000003800540054035482F4825E8255805400540038000000000 +A175:000000000000000003800540054035482F4825E8255805400540038000000000 +A176:0000000000000000223055285524222008201420142009A00160010000000000 +A177:000003800440000000C022B0228C088008800080188016801180100000000000 +A178:000000000000000000C022B0228C088008800080188016801180100000000000 +A179:03800440000001800540030000000EE00100028001000EE00000018005400300 +A17A:000001800540030000000EE00100028001000EE0000001800540030000000000 +A17B:0000000000000000000020C412A8118808100FF0081010C812A8218400000000 +A17C:00000000000003600458334640403340044003401840164011C0100000000000 +A17D:0000000000000000006000500048004023C8244808400840244823C800000000 +A17E:000003800440000000900A900A900A9000F00E90009004900290019000000000 +A17F:000000000000000000900A900A900A9000F00E90009004900290019000000000 +A180:000000000000000000C000A00090008007A008C0118012800C80078000000000 +A181:000003800440000000E0011001100710059015500D300110011000E000000000 +A182:000000000000000000E0011001100710059015500D300110011000E000000000 +A183:00000000000000000600058004000798046005C00640078034000C0000000000 +A184:0380044000000660055014C80C600050004001F00C400B4008C0080000000000 +A185:0000000000000660055014C80C600050004001F00C400B4008C0080000000000 +A186:000000000000000001800160011817C0110017C001000D000B00080000000000 +A187:00000380044000001D8003600118010003001D00010031000D00030000000000 +A188:00000000000000001D8003600118010003001D00010031000D00030000000000 +A189:000000000000000008E00910091009500950095009500910091008E000000000 +A18A:00000000000000000700089008900FF0089008900FF008900890070000000000 +A18B:0380044000003E60415808463E40084041403E4000400E4009C0080000000000 +A18C:0000000000003E60415808463E40084041403E4000400E4009C0080000000000 +A18D:000000000000000024C018B0008C248018800080188016801180100000000000 +A18E:0000038004400000018001600D00030001000D00030001000D00030000000000 +A18F:0000000000000000018001600D00030001000D00030001000D00030000000000 +A190:000000000000000031800D60031831000D00030031002D002300200000000000 +A191:000000000000000000C000B000800A800A800A80008000800680018000000000 +A192:03800440000012C00CB0008012800C80008012800C8000801C80038000000000 +A193:00000000000012C00CB0008012800C80008012800C8000801C80038000000000 +A194:000000000000000000600A580A400A40004011400E400040034000C000000000 +A195:000003800440000000C014B01480148000E01C90009000900680018000000000 +A196:000000000000000000C014B01480148000E01C90009000900680018000000000 +A197:000000000410041003E018881688118810E81098008003E00490049000000000 +A198:0380044000000820082007C001100FF0110011000FF0010007C0082008200000 +A199:000000000820082007C001100FF0110011000FF0010007C00820082000000000 +A19A:000000000000000017D0082017D0101010101010082007C010100FE000000000 +A19B:038004400000038004400440038031102D10231021D021300380054005400000 +A19C:0000000001C00220022001C018881688118810E8109801C002A002A000000000 +A19D:0000000000000000089007100010031002D00230020007000A800A8000000000 +A19E:000000000000000007000880088008800B900AD00AB008800880070000000000 +A19F:0000038004400000008007900890108010901090108008900790008000000000 +A1A0:0000000000000000008007900890108010901090108008900790008000000000 +A1A1:000000000000000007800840102000A800A800A800701C20132010C000000000 +A1A2:0380044000000EE001000280044004400FE0044005400540028001000EE00000 +A1A3:000000000EE001000280044004400FE0044005400540028001000EE000000000 +A1A4:000000000000000027C828281010183017D0101011101110082007C000000000 +A1A5:000003800440000001000124012401F801200124012431F80D20032000000000 +A1A6:000000000000000001000124012401F801200124012431F80D20032000000000 +A1A7:000000000000000027C828281010183017D0101010101010082007C000000000 +A1A8:03800440000007C0082010101E1011D0103011D01E101010082007C000000000 +A1A9:00000000000007C0082010101E1011D0103011D01E101010082007C000000000 +A1AA:000000000000000007C008201010101010101FF010101010082007C000000000 +A1AB:00000000000001800160011801001FF001001FF001001D001300100000000000 +A1AC:000003800440000004F00900090004800070048009000900090004F000000000 +A1AD:000000000000000004F00900090004800070048009000900090004F000000000 +A1AE:00000000000000000FE0101010100FE00100090008E00100090008E000000000 +A1AF:000003800440000007C00820101010101010101010101450082017D020080000 +A1B0:000000000000000007C00820101010101010101010101450082017D020080000 +A1B1:00000000000000000110011000E00040034002C0020007000880088000000000 +A1B2:0000038004400000111011101110092007C00100390027002100210000000000 +A1B3:0000000000000000088808880888049003E000801C8013801080108000000000 +A1B4:000000000000000001C0022006300528042004200420042014A00C6000000000 +A1B5:000003800440000002C01AB0168C538032800280188016801180100000000000 +A1B6:000000000000000002C01AB0168C538032800280188016801180100000000000 +A1B7:0000000000000000001001900170010031482D4823C821780140010000000000 +A1B8:000003800440000000400440044004400440044000400C40034000C000000000 +A1B9:000000000000000000400440044004400440044000400C40034000C000000000 +A1BA:000000000000000007C009201110111011101FF011101110092007C000000000 +A1BB:00000000000000000020022002200AA008A008A00020062001A0006000000000 +A1BC:00000380044000000040044004400440004004400A400A400640098000000000 +A1BD:00000000000000000040044004400440004004400A400A400640098000000000 +A1BE:00000000000000000020062009200920092006200020062001A0006000000000 +A1BF:0000000000000000102010281028102010281FE8102010281028102000000000 +A1C0:00000380044000000C200A2009200820082008200820092008A0086000000000 +A1C1:00000000000000000C200A2009200820082008200820092008A0086000000000 +A1C2:00000000000000C000B0188C23E0188023E0188000800E800980080000000000 +A1C3:000005500550001003D00430081008000800080008000810042003C000000000 +A1C4:000003800440000001800160011803800540054013901110092007C000000000 +A1C5:000000000000000001800160011803800540054013901110092007C000000000 +A1C6:0000000000000000044004400FE01450244824480FE014502448238800000000 +A1C7:0000000000000000145015501110082007C001000FE001000900060000000000 +A1C8:000003800440000001800160010007C00920092007C001000D00030000000000 +A1C9:000000000000000001800160010007C00920092007C001000D00030000000000 +A1CA:000000000000000003800540054009200FE009200FE00920092006C000000000 +A1CB:0000038004400000042009200920082004200020062005A00460040000000000 +A1CC:0000000000000000042009200920082004200020062005A00460040000000000 +A1CD:00000000000000001808170810E81018010001000000111011100EE000000000 +A1CE:000000000000000007C00820129012901010101011101110082007C000000000 +A1CF:00000380044000001110111011100EE004400440054005400440038000000000 +A1D0:00000000000000001110111011100EE004400440054005400440038000000000 +A1D1:000000000000100408081C10222049404880494022201C100808100400000000 +A1D2:0000038004402008111009200440028001000280044009201110200800000000 +A1D3:0000000000002008111009200440028001000280044009201110200800000000 +A1D4:000000000000000010841084088807F000800C800B8008806A801A8000000000 +A1D5:000003800440000018081608118810E81098008000800000041003E000000000 +A1D6:000000000000000018081608118810E81098008000800000041003E000000000 +A1D7:000000000000000018081608118810E810980080008006800580040000000000 +A1D8:000003C00420000003C00420040004000200018000400020042003C000000000 +A1D9:000000000000000003C00420040004000200018000400020042003C000000000 +A1DA:00000000000000000F0010802048004800480078004838482648218000000000 +A1DB:000007C00820000003C00420081001100110011000100E100990086000000000 +A1DC:000000000000000003C00420081001100110011000100E100990086000000000 +A1DD:00000000000000000008018801680118010007C02108210810100FE000000000 +A1DE:000000000000000007C0092011101110010007C011101110092007C000000000 +A1DF:0000038004400000145014501390082007C00100010001000900060000000000 +A1E0:0000000000000000145014501390082007C00100010001000900060000000000 +A1E1:000000000000000001880168011801001FF001002548254810100FE000000000 +A1E2:000000000000000014501390082007C00000000007C008201390145000000000 +A1E3:000003800440000010101010082007C00000000007C008201010101000000000 +A1E4:000000000000000010101010082007C00000000007C008201010101000000000 +A1E5:00000000000007C008201010145013901010139014501010082007C000000000 +A1E6:00000000000000000000406020A0112C0A3004300A30113020AC406000000000 +A1E7:00000380044000000000406C20B011300A2C04200A2C113020B0406C00000000 +A1E8:00000000000000000000406C20B011300A2C04200A2C113020B0406C00000000 +A1E9:00000000000007C008201290129010101FF0101011101110082007C000000000 +A1EA:000000000000000044444444444444443BB811101550155011100EE000000000 +A1EB:000003800440000031000D08011031200D400180010031000D00030000000000 +A1EC:000000000000000031000D08011031200D400180010031000D00030000000000 +A1ED:0000000000000000000008200820082000001FF0000001000100010000000000 +A1EE:00000000000000000180016001180100011001F031102D002300200000000000 +A1EF:0000038004400000018001600100090009000900010001000D00030000000000 +A1F0:0000000000000000018001600100090009000900010001000D00030000000000 +A1F1:000000000000000001800960091809000100010031002D002300200000000000 +A1F2:00000000000000E0191005500350031003F0031003500550191000E000000000 +A1F3:0000038004400000101010101FF010101010101010101010082007C000000000 +A1F4:0000000000000000101010101FF010101010101010101010082007C000000000 +A1F5:000000000000000007C008201010145017D0145014501390082007C000000000 +A1F6:0000038004400000101010101FF010101010101010101450082017D020080000 +A1F7:0000000000000000101010101FF010101010101010101450082017D020080000 +A1F8:0000000000000000040005E0040005E0040005E0040004600580060000000000 +A1F9:000003800440000001C00220022004101F100410041004900490036000000000 +A1FA:000000000000000001C00220022004100F100410041004900490036000000000 +A1FB:0000000000001FF01010092005400280010002800540092010101FF000000000 +A1FC:0000038004400000000801880168011831002D08238821682118010000000000 +A1FD:0000000000000000000801880168011831002D08238821682118010000000000 +A1FE:0000000000000000010031182928254823882388254829283118010000000000 +A1FF:0000000000000000038002601218124012401E40124012181260038000000000 +A200:0000000003800440000010180828044802881FF8028804480828101800000000 +A201:0000000000000000000010180828044802881FF8028804480828101800000000 +A202:00000000000000000180096009180900011001F031102D002300200000000000 +A203:000003800440000000601158114011400440047004480048034800C000000000 +A204:000000000000000000601158114011400440047004480048034800C000000000 +A205:0000000001800160010003800540038001000D00030007C00820082000000000 +A206:0000000000000000031002D01E300200020003C002001E000200020000000000 +A207:038004400000180006C000B018800680008018E0069000900690018000000000 +A208:000000000000180006C000B018800680008018E0069000900690018000000000 +A209:000000000000030002C0023002000FF01200120012000FF00200020000000000 +A20A:0000000000000000044004401390111011100EE0044004400440038000000000 +A20B:0000038004400000082008200820082000000000010001000100010000000000 +A20C:0000000000000000082008200820082000000000010001000100010000000000 +A20D:0000000000000000101010101010082007C00000111011101110111000000000 +A20E:0000000000000000111011101110092007C0010001001FF00100010000000000 +A20F:000003800440000000101A5016501250135012D00010031000D0003000000000 +A210:00000000000002101A5016501250135012D002100010031000D0003000000000 +A211:000000000000000003E004900490008000800080188016801180100000000000 +A212:03800440000000400640054004401F40044014400C400040034000C000000000 +A213:0000000000000020032002A002200FA002200A200620002001A0006000000000 +A214:00000000000007C008201010101010100C601010111011100D60010000000000 +A215:0000038004400000002008A005200520052008A00020062001A0006000000000 +A216:0000000000000000002008A005200520052008A00020062001A0006000000000 +A217:00000380044000000F6010D01648094016401040164009401640004000000000 +A218:00000000000000000F6010D01648094016401040164009401640004000000000 +A219:00000000000000000400040004001C0816081188106810380020002000000000 +A21A:0000000000000000020802080208020803F8020802081A081608100800000000 +A21B:03800440000007E00810080007E00010081007E0008007F0008007F000800000 +A21C:00000000000007E00810080007E00010081007E0008007F0008007F000800000 +A21D:000000000000000021382140218021800180014031382D002300200000000000 +A21E:000000000000000008400840084000400C40034000C001E00210021000000000 +A21F:00000380044000001830244804400440044004400FE014502448238800000000 +A220:00000000000000001830244804400440044004400FE014502448238800000000 +A221:000000000FE010101110111010100FE001001FF001001FF00500030000000000 +A222:00000000000000000180016031082D0823882168211801000D00030000000000 +A223:000003800440000000200020002000200020082008200E2009A0086000000000 +A224:000000000000000000200020002000200020082008200E2009A0086000000000 +A225:00000000000000000840084008400840004000400C400B4008C0080000000000 +A226:00000000000000000AC00AB000801F8000800A800A8000800680018000000000 +A227:0000038004400000111011101010101011101110101010101110111000000000 +A228:0000000000000000111011101010101011101110101010101110111000000000 +A229:000000000000000019602558244027C02440254025401840034000C000000000 +A22A:0000000000000000000809881568151815000F00050009001100010000000000 +A22B:038004400000183006D0011006D018300000183006D0011006D0183000000000 +A22C:000000000000183006D0011006D018300000183006D0011006D0183000000000 +A22D:0000000000000000183006D0011006D01830010001001FF00100010000000000 +A22E:0380044000000FE01010101010100FE000000FE01010101010100FE000000000 +A22F:0000000000000FE01010101010100FE000000FE01010101010100FE000000000 +A230:000003800440000006183D944472441024101C102410441044103C1000000000 +A231:000000000000000006183D944472441024101C102410441044103C1000000000 +A232:000000000000000003E00410041007F00410051006100C10141003E000000000 +A233:0000038004400000186016581040104010401FC0124012401240124000000000 +A234:0000000000000000186016581040104010401FC0124012401240124000000000 +A235:0000000000000000010C01100120012001E0012031202D10230C200000000000 +A236:0380044001000FE0111011100FE0210821080FE0111011100FE0010000000000 +A237:0000000001000FE0111011100FE0210821080FE0111011100FE0010000000000 +A238:0000000000000000000007C008200820082007C0010007C00920092000000000 +A239:0000000000000000000007C009200FE0092007C0010007C00920092000000000 +A23A:03800440000003E004100410041003E00080038002000F801240124000000000 +A23B:00000000000003E004100410041003E00080038002000F801240124000000000 +A23C:000000000000000000780080038004401E380440038000800080007800000000 +A23D:0380044000000070008000900790088012701200127008800790009000800070 +A23E:0000007000800090079008801270120012700880079000900080007000000000 +A23F:00000000000000000FB8104020A020A020B820A020A020A010400FB800000000 +A240:000000000000000008202AA81AB0193018301AB01AB02928082007C000000000 +A241:0000000003800440000006E0010002C002000FE0020002C0010006E000000000 +A242:0000000000000000000006E0010002C002000FE0020002C0010006E000000000 +A243:00000000000000000410041003E0008007F0008007F0108010800F0000000000 +A244:00000380044000001410141014101590169014901090109008A007C000000000 +A245:00000000000000001410141014101590169014901090109008A007C000000000 +A246:000000000000000000000E1009900870000000000E1009900870000000000000 +A247:0380044000000100311829282448228821082288244829283118010000000000 +A248:0000000000000100311829282448228821082288244829283118010000000000 +A249:0000000000001FF0004007C008400840084007C008400840084007C000000000 +A24A:0000000000000000004009400940094000400F4000400C40034000C000000000 +A24B:0000038004400000003000400090039002F00280028002401A30060000000000 +A24C:0000000000000000003000400090039002F00280028002401A30060000000000 +A24D:0000000000000000070008A008A0088008F0088008A008A00880070000000000 +A24E:000000000000000010C020B0248C22801180008007E008800880070000000000 +A24F:000003800440000010C020B0248C228011800080008018800680018000000000 +A250:000000000000000010C020B0248C228011800080008018800680018000000000 +A251:000000000000000012C022B0248C228011800280028018800680018000000000 +A252:00000000000000002288228822881C7000000820082008200440038000000000 +A253:000003800440000001E00200040004000400040004000400020001E000000000 +A254:000000000000000001E00200040004000400040004000400020001E000000000 +A255:00000000000000001110111011100EE000000380044004400440038000000000 +A256:00000000000000000FC0002007A00820072000A00F20002000200FC000000000 +A257:0000038004400000018001600900050003000100010001000D00030000000000 +A258:0000000000000000018001600900050003000100010001000D00030000000000 +A259:0000000000000000000030182828244822882108228824482828301800000000 +A25A:0380044000000920092007C00FE01110111011100FE007C00920092000000000 +A25B:0000000000000920092007C00FE01110111011100FE007C00920092000000000 +A25C:0000000000000000018031602D1823002100010031002D002300210000000000 +A25D:00000380044000000180056005180500014009400540131011100FE000000000 +A25E:00000000000000000180056005180500014009400540131011100FE000000000 +A25F:000000000000000001800160110811087D3E1108110801000D00030000000000 +A260:0000000000000000202020203828262821A820702020202010400F8000000000 +A261:000003800440000018881688118810E810980080008006800580040000000000 +A262:000000000000000018881688118810E810980080008006800580040000000000 +A263:0000000000000000008008E008903E8808880888009018E00680018000000000 +A264:00000000000000000FE0101024482288010001002288244810100FE000000000 +A265:0380044000000380044005400540044007C00440028001000280044000000000 +A266:0000000000000380044005400540044007C00440028001000280044000000000 +A267:00000000000000001C70028001000100010001000100010002801C7000000000 +A268:0000038004400000038004400440044007C0082009200920082007C000000000 +A269:0000000000000000038004400440044007C0082009200920082007C000000000 +A26A:00000000000000000088029002A002C012E00C900090189006E0018000000000 +A26B:00000380044000000020022002200FA0022002200020062001A0006000000000 +A26C:00000000000000000020022002200FA0022002200020062001A0006000000000 +A26D:00000000000000000E00110011001F2011501FD011501F2011000E0000000000 +A26E:0000000000000000098011601118090007000900110011000900010000000000 +A26F:0000038004400000118011600918070009001100110001000D00030000000000 +A270:0000000000000000118011600918070009001100110001000D00030000000000 +A271:00000000000000000050035002D002700240024002000F801240124000000000 +A272:000003800440000001C002A003E002A031C02C8023C002200490049000000000 +A273:000000000000000000E0015001F0015018E0164011E001100248024800000000 +A274:000000000000000000E001100110011018E0164011E001100248024800000000 +A275:0000000000000000098015601518090001001FF001001FF00100010000000000 +A276:000003800440000001801960051813002B002B00130005001900010000000000 +A277:000000000000000001801960051813002B002B00130005001900010000000000 +A278:000000000000000001001FE00910151009101FE0010007C00920092000000000 +A279:00000000000000000F00103810400880078008801040103810000F0000000000 +A27A:000003800440000007C00820139014501450145014501390082007C000000000 +A27B:000000000000000007C00820139014501450145014501390082007C000000000 +A27C:0000000000000000000020201040089005280228052808901040202000000000 +A27D:00000380044000000C300B2808E4082008201C202A202A202A20082000000000 +A27E:00000000000000000C300B2808E4082008201C202A202A202A20082000000000 +A27F:0000000000000000038004400E4004400E400440038004400920092000000000 +A280:0000000000000000022002200E240BA42A741A2C02A002A0022001C000000000 +A281:000003800440000018081608118810681018000007E00000000007E000000000 +A282:000000000000000018081608118810681018000007E00000000007E000000000 +A283:0000000000000000180816081188106810180000042004200420042000000000 +A284:00000380044000000E70018001800250025002500180058002400D3000000000 +A285:00000000000000000E70018001800250025002500180058002400D3000000000 +A286:00000000000001C001300F8001400F4001400F80010003800540054000000000 +A287:00000380044000000710089008A007C0008003E000800BE00880070000000000 +A288:00000000000000000710089008A007C0008003E000800BE00880070000000000 +A289:0000000000000000000004400440028002A001200AA006800640054000000000 +A28A:038004400000180006C000B01888068000801880068003E00490049000000000 +A28B:00000000180006C000B018880680008018800680008003E00490049000000000 +A28C:0000000000000000018001600118014001401D10139011700100010000000000 +A28D:00000000000011101110092007C00100150015001F0015001500010000000000 +A28E:00000380044000000440044004401390111011100EE004400AA00AA000000000 +A28F:00000000000000000440044004401390111011100EE004400AA00AA000000000 +A290:000000000000000003D00430081009000900090009000810042003C000000000 +A291:00000380044000001440144014401FF814401440144001F0004001F000000000 +A292:00000000000000001440144014401FF814401440144001F0004001F000000000 +A293:000000000000000001801560151815001FE01500150001000100010000000000 +A294:000000000000000801881D6803180B000B7003801DA001A00180017000000000 +A295:0000038004400000007807800880107814801480107808800780007800000000 +A296:0000000000000000007807800880107814801480107808800780007800000000 +A297:00000000000000000440044004401390111011100EE0000000000EE000000000 +A298:00000380044000000380044004400E40044004400E4004400440038000000000 +A299:00000000000000000380044004400E40044004400E4004400440038000000000 +A29A:0000000000000000010001180124013C012401FC012431180D00030000000000 +A29B:000000000000000001000280044008200FE001000280044008200FE000000000 +A29C:00000380044000000804087408AC09200A200C200A20692058A0406000000000 +A29D:00000000000000000804087408AC09200A200C200A20692058A0406000000000 +A29E:00000000000000000FE0101010100FE0101010100FE0101010100FE000000000 +A29F:0000038004400000018001600118010017D01110111017D00100010000000000 +A2A0:0000000000000000018001600118010017D01110111017D00100010000000000 +A2A1:00000000000000400C400B4008C008000BE00A20094008800940022000000000 +A2A2:0000000000000000070008A008A008C0088008A008A008C00880070000000000 +A2A3:00000000038004400000064001C0064001C00000064001C0064001C000000000 +A2A4:00000000000000000000064001C0064001C00000064001C0064001C000000000 +A2A5:000000000000000007C00820111011100000000007C008201110111000000000 +A2A6:0000000003800440000060305054489405180210051408941058203000000000 +A2A7:0000000000000000000060305054489405180210051408941058203000000000 +A2A8:0000000000000248015000E001500248034012C00A8007000A80124000000000 +A2A9:000000000380044000000440044002800280010002800A800840074000000000 +A2AA:000000000000000000000440044002800280010002800A800840074000000000 +A2AB:000000000000000000F00900090000F00900090000F00900090000F000000000 +A2AC:000003800440000003C0240C2410022021E022200410240C240003C000000000 +A2AD:000000000000000003C0240C2410022021E022200410240C240003C000000000 +A2AE:00000000000000001860165011C8104012401240124010401040104000000000 +A2AF:0000038004400000030002C002300200020002001FC002000200020000000000 +A2B0:0000000000000000030002C002300200020002001FC002000200020000000000 +A2B1:0000000000000FE00820044002800280010002800280044008200FE000000000 +A2B2:0000000000001E0811CC103A1188114811081108110815085308300000000000 +A2B3:0000038004400000038004400450045004500460044004400440038000000000 +A2B4:0000000000000000038004400450045004500460044004400440038000000000 +A2B5:0000000000000000030002C00230020002000F8010401FC010400F8000000000 +A2B6:000000000000000007C00820109016901190109016901190082007C000000000 +A2B7:000003800440000007C00820101011901150111015101310082007C000000000 +A2B8:000000000000000007C00820101011901150111015101310082007C000000000 +A2B9:000000000000000007800840132802A802280A3006201C20132010C000000000 +A2BA:03800440000001C00130010001C0012007C00900070001001900070000000000 +A2BB:00000000000001C00130010001C0012007C00900070001001900070000000000 +A2BC:00000000000000000C6002800100028002800440044009200920092000000000 +A2BD:000000000000000002200220022802280F282AE81A380228022801C000000000 +A2BE:000003800440000001C00220022802280F282AE81A380228022801C000000000 +A2BF:000000000000000001C00220022802280F282AE81A380228022801C000000000 +A2C0:0000000000000000071008900890089008901FF0089008900890071000000000 +A2C1:000003800440000007C00820139010501390105013901010082007C000000000 +A2C2:000000000000000007C00820139010501390105013901010082007C000000000 +A2C3:00000000000000001110111011100EE0000004401550155011100EE000000000 +A2C4:000000000000000011C42224222412240E3C122422242224122401C400000000 +A2C5:00000000038004400000406020A011244A24443C4A24112420A0406000000000 +A2C6:00000000000000000000406020A011244A24443C4A24112420A0406000000000 +A2C7:000000000000000010C013B01080088007800080188016801180100000000000 +A2C8:0000038004400000070008900890089008F00890089008900880070000000000 +A2C9:0000000000000000070008900890089008F00890089008900880070000000000 +A2CA:000000000000000008200420022001200CA00A60090008800840082000000000 +A2CB:0000000003800440000004400440028002A0012002A002800440044000000000 +A2CC:0000000000000000000004400440028002A0012002A002800440044000000000 +A2CD:0000000000000000018001600100010001000100010001000D00030000000000 +A2CE:0000038004400000183006C0010006C018300100010007C00100010000000000 +A2CF:0000000000000000183006C0010006C018300100010007C00100010000000000 +A2D0:000000000000000018081608158814681458044007C004400440044000000000 +A2D1:0000038004401000086024501048084003C0044008400840044003C000000000 +A2D2:0000000000001000086024501048084003C0044008400840044003C000000000 +A2D3:00000000000000000020062005A0046004000520052004000520052000000000 +A2D4:0000000000000FE0010011400920051011400920051011400920051000000000 +A2D5:000003800440000007C00820101017D001000100054005400540010000000000 +A2D6:000000000000000007C00820101017D001000100054005400540010000000000 +A2D7:0000000000000000180816081188106811180100010004400440044000000000 +A2D8:00000000000000001FC00200020012680AA807380AA8126802001FC000000000 +A2D9:00000000038004400000110011000A500A5004000A500A501100110000000000 +A2DA:00000000000000000000110011000A500A5004000A500A501100110000000000 +A2DB:00000000000000000000110011000A500A5004000A700A001100110000000000 +A2DC:038004400010031002D002300F8002000F800200070008800880070000000000 +A2DD:000000000010031002D002300F8002000F800200070008800880070000000000 +A2DE:00000000000000000100010007C011101110092007C004400820082000000000 +A2DF:000003800440000007C008200FE008200FE0082007C00100011000E000000000 +A2E0:000000000000000007C008200FE008200FE0082007C00100011000E000000000 +A2E1:00000000000000000F00114011400F40114011000F000110011000E000000000 +A2E2:0000038004400000030002C002300200070008800880070010400F8000000000 +A2E3:0000000000000000030002C002300200070008800880070010400F8000000000 +A2E4:000000000180016001000F28112811F811280F28010001000D00030000000000 +A2E5:0000038004400000060005800460040004A004A007E004A004A0040000000000 +A2E6:0000000000000000060005800460040004A004A007E004A004A0040000000000 +A2E7:0000000000000000000004400820101004400820101004400820101000000000 +A2E8:0380044000000010031002D0023002000A6006A0032006A00A60020000000000 +A2E9:0000000000000010031002D0023002000A6006A0032006A00A60020000000000 +A2EA:000000000000000001E0022004200420022001E0006009A00E20082000000000 +A2EB:000003800440000003800440044004400FC01440144014401440044000000000 +A2EC:000000000000000001C002200220022007E00A200A200A200A20022000000000 +A2ED:000000000000000007F0008001C0013001000120012001200D00030000000000 +A2EE:0000000003800440000004400440044000000FE0000004400440044000000000 +A2EF:0000000000000000000004400440044000000FE0000004400440044000000000 +A2F0:0000000000000000012009100910092001C00120091009100920010000000000 +A2F1:000003800440000011201510151011201FC011201510151011200E0000000000 +A2F2:000000000000000011201510151011201FC011201510151011200E0000000000 +A2F3:0000000000000000112011101110112011C011201110111011200E0000000000 +A2F4:0000000000000000010007C00100000001800160010001000D00030000000000 +A2F5:000003800440010007C00100000001800160010007C001000D00030000000000 +A2F6:000000000000010007C00100000001800160010007C001000D00030000000000 +A2F7:0000000000000000098011601118090007480948110011480948010000000000 +A2F8:0000038004400000044004400380111013900D6001000D6003800D6000000000 +A2F9:0000000000000000044004400380111013900D6001000D6003800D6000000000 +A2FA:00000380044000000010031002D0023002000F801240124012400F8000000000 +A2FB:00000000000000000010031002D0023002000F801240124012400F8000000000 +A2FC:0000038004400000008003E00080060005800460040004400440040000000000 +A2FD:0000000000000000008003E00080060005800460040004400440040000000000 +A2FE:0000038004400000010007C00100111011100EE00000010007C0010000000000 +A2FF:0000000000000000010007C00100111011100EE00000010007C0010000000000 +A300:00000000010007C041044C64345804400380010007C0010007C0010000000000 +A301:0000038004400000101010101FF011101110111011101110092007C000000000 +A302:0000000000000000101010101FF011101110111011101110092007C000000000 +A303:0000000000000000000009F012101210091000F009101210121009F000000000 +A304:000003800440000002400280030003C00220022003C003000280024000000000 +A305:000000000000000002400280030003C00220022003C003000280024000000000 +A306:000000000000000007C0082014501FF0145014501FF01450082007C000000000 +A307:000003800440000010101450145014501010111011101110082007C000000000 +A308:000000000000000010101450145014501010111011101110082007C000000000 +A309:000000000000000000880088008800880C8810F8208824882288118800000000 +A30A:000003800440000007C008201FF010101FF0082007C008201110111000000000 +A30B:000000000000000007C008201FF010101FF0082007C008201110111000000000 +A30C:0000000000000000030012C01230120002000200120012001200020000000000 +A30D:000003800440000004440444024801F018402040404048404640218000000000 +A30E:000000000000000004440444024801F018402040404048404640218000000000 +A30F:000000000000000011101110092007C001000100078009400640004000000000 +A310:000000000000000000B808C008C008B8088000B800C018C006B8018000000000 +A311:00000380044000000080089008F0089008800080009018F00690018000000000 +A312:00000000000000000080089008F0089008800080009018F00690018000000000 +A313:00000F901050001003D00430081008000800080008000810042003C000000000 +A314:0000038004400000060005800460040005200520052005200400040000000000 +A315:0000000000000000060005800460040005200520052005200400040000000000 +A316:00000000000000000C000B0008C008000A200940088009400A20080000000000 +A317:00000000000003C004200500048002000180004002200120042003C000000000 +A318:0000038004400000118009600500110009400520011001400D20031000000000 +A319:0000000000000000118009600500110009400520011001400D20031000000000 +A31A:00000000000007C008200A800A80080007C0002002A002A0082007C000000000 +A31B:000003800440000008C008A00090078008800880078000800880088000000000 +A31C:000000000000000008C008A00090078008800880078000800880088000000000 +A31D:0000000000000000004010501050135002C00200121012101210020000000000 +A31E:0000000000000820082007C00000111011100EE0000007C00820082000000000 +A31F:0000038004400000024002400240020003E00200024002401A40060000000000 +A320:0000000000000000012001200120010001F00100012001200D20030000000000 +A321:000000000000000003C00420081008103E10081008100810042003C000000000 +A322:00000380044000000100092009201D20090009F0010001200D20032000000000 +A323:00000000000000000100092009201D20090009F0010001200D20032000000000 +A324:00000000000000001010101010101010082007C00000010007C0010000000000 +A325:00000380044000001010101010101010082007C00100110011000E0000000000 +A326:00000000000000001010101010101010082007C00100110011000E0000000000 +A327:0000000000000000008007F00080008007F00080188016801180100000000000 +A328:0000038004400000101010101010082007C00000010001000100010000000000 +A329:0000000000000000101010101010082007C00000010001000100010000000000 +A32A:0000000000000000000811881F6811180100011011101F101110010000000000 +A32B:00000380044000000020062005A0046004000440044005F00440044000000000 +A32C:00000000000000000020062005A0046004000440044005F00440044000000000 +A32D:0000000000000000001003101ED002300200022002201EF80220022000000000 +A32E:000003800440000018081608118811681518054001400540051000E000000000 +A32F:000000000000000018081608118811681518054001400540051000E000000000 +A330:000000000000000018081608118810E81098008002A002A0008007F000000000 +A331:00000000000000001110111013900D60010005401550155011100EE000000000 +A332:00000380044000000FE0101010100FE0210821080FE0101010100FE000000000 +A333:00000000000000000FE0101010100FE0210821080FE0101010100FE000000000 +A334:0000000000000FE0101010100FE001001FF001000FE0101010100FE000000000 +A335:0000000000000000000811881F681118110011001F0011000100010000000000 +A336:000003800440000007C00820101010101FF0111011101110092007C000000000 +A337:000000000000000007C00820101010101FF0111011101110092007C000000000 +A338:00000000000000001860165011C0104012401540154015401240104000000000 +A339:00000380044000000180016001000100010001C0012001200D20030000000000 +A33A:00000000000000000180016001000100010001C0012001200D20030000000000 +A33B:000000000000000007C00820119011501110119015501350082007C000000000 +A33C:000000000000000000401FF800400440047800400C400B4008C0080000000000 +A33D:00000380044000001C60135010C002400FC002400C400B4008C0080000000000 +A33E:00000000000000001C60135010C002400FC002400C400B4008C0080000000000 +A33F:000000000000049003E00080049003E01880168013E014100490049000000000 +A340:0000000000000000112015101510112015C01520111015101510112000000000 +A341:00000380044000000180016007D8090009C0090037C02D002300200000000000 +A342:00000000000000000180016007D8090009C0090037C02D002300200000000000 +A343:00000000000000000F001088224802400FC80248024038482648218000000000 +A344:0380044000000EE0111011101110010001000FE0000009200920092000000000 +A345:0000000000000EE0111011101110010001000FE0000009200920092000000000 +A346:0000000000700E8011A011A01180157015001570118011A011A00E8000700000 +A347:03800440010001000440044018101610111010D0103004400540010000000000 +A348:00000000010001000440044018101610111010D0103004400540010000000000 +A349:000000000000000003883A680618120012001200120006183A68038800000000 +A34A:00000380044000000580056025181900010001003FF801000100010000000000 +A34B:00000000000000000580056025181900010001003FF801000100010000000000 +A34C:000000000000000007E008200820082007E0002001200920082007C000000000 +A34D:000000000000000005800560251819000100010007C009201110111000000000 +A34E:00000380044000001860165011C010401240124010401FC01040104000000000 +A34F:00000000000000001860165011C010401240124010401FC01040104000000000 +A350:000000000000000001000540044002801E90111012F002800440054001000000 +A351:00000000000000000008018801680118010005402548210811100FE000000000 +A352:00000380044000000100010001000100054005402548210811100FE000000000 +A353:00000000000000000100010001000100054005402548210811100FE000000000 +A354:000000000000000015501550155011101550155015501110092007C000000000 +A355:00000000000000000638054404C40444044404440444245414540C3800100000 +A356:000003800440000001900F6811281128091007000900110011000F0000000000 +A357:000000000000000001900F6811281128091007000900110011000F0000000000 +A358:000000000000000000000100028002800100000004400AA00AA0044000000000 +A359:0000038004400000031002E81A28062802101A00060002001A00060000000000 +A35A:0000000000000000031002E81A28062802101A00060002001A00060000000000 +A35B:00000000000007C00820080007C00020082007C000000FE000000FE000000000 +A35C:000003800440000011101110092007C00110011007C009201110111000000000 +A35D:000000000000000011101110092007C00110011007C009201110111000000000 +A35E:0000000000000E100990087000000E100990087000000E100990087000000000 +A35F:0000038004400000038002601218120013E01200120012180260038000000000 +A360:0000000000000000038002601218120013E01200120012180260038000000000 +A361:00000000000000000180016001000FE009200540038003800540092000000000 +A362:000003800440000001800160010007C0092007C0010007C00920092000000000 +A363:000000000000000001800160010007C0092007C0010007C00920092000000000 +A364:0000000000000100038005400440054003800100038005400920092000000000 +A365:000000000000000030C02CA8239820882480248020803F802080208000000000 +A366:00000380044000000C300A280820282018A00C600A20082028A0186000000000 +A367:00000000000000000C300A280820282018A00C600A20082028A0186000000000 +A368:000000000000000000002230125008900510021C051008901250223000000000 +A369:000000000000000018181514111210101FF01010111091105050303000000000 +A36A:03800440000018081608118810E81098008018881688118810E8109800000000 +A36B:00000000000018081608118810E81098008018881688118810E8109800000000 +A36C:00000000000000000C300B2C082008200FE008200820082069A0186000000000 +A36D:00000000000000001FF011100920054013901110139005400920111000000000 +A36E:00000380044000001FF011100920054003801FF0028004400920111000000000 +A36F:00000000000000001FF011100920054003801FF0028004400920111000000000 +A370:00000000000000001FF01110092005403B8827C822B804400920111000000000 +A371:00000380044000000E001128112815F8152815F81528112811000E0000000000 +A372:00000000000000000E001128112815F8152815F81528112811000E0000000000 +A373:0000000000000000072008A008800AF00A800A800AF0088008A0072000000000 +A374:00000380044000000C040B34082C082008203E200820082C6834180400000000 +A375:00000000000000000C040B34082C082008203E200820082C6834180400000000 +A376:000000001C1001C805A8059801800E8000800FF8008018800680018000000000 +A377:000003800440000018081608118810E81098008001C00220022001C000000000 +A378:000000000000000018081608118810E81098008001C00220022001C000000000 +A379:000000000000000005500550011007D00110055004500C100390007000000000 +A37A:0380044000001C0803880B680B1803001D0001001FF001001FF0010000000000 +A37B:0000000000001C0803880B680B1803001D0001001FF001001FF0010000000000 +A37C:0000038004400000033012E812243A2012201220022002201A20062000000000 +A37D:0000000000000000033012E812243A2012201220022002201A20062000000000 +A37E:0000038004400000010001200920150015F01500092001200D00030000000000 +A37F:0000000000000000010001200920150015F01500092001200D00030000000000 +A380:0000000000000000014811481130110011F80100013031480D48030000000000 +A381:00000380044000000380044007C008200FE0082008200920092006C000000000 +A382:00000000000000000380044007C008200FE0082008200920092006C000000000 +A383:00000000000007C008201010045004500110011000100E100990086000000000 +A384:0000000000000000000801880168011801003FF8010011007D00110000000000 +A385:00000380044000000FC00020002000200FE000200020002000200FC000000000 +A386:00000000000000000FC00020002000200FE000200020002000200FC000000000 +A387:000000000000000018081608118810E81098008003E008800880070000000000 +A388:0000000000000000181014101210101011101110101010901050103000000000 +A389:0000038004400000082014501450145008200540028002800280010000000000 +A38A:0000000000000000082014501450145008200540028002800280010000000000 +A38B:000000000000000036D808201450145014503FF814501450082036D800000000 +A38C:0000038004400000018000400620082009200920082006200040018000000000 +A38D:0000000000000000018000400620082009200920082006200040018000000000 +A38E:0000000000000000008000A800A800A800F800A818A816A81180100000000000 +A38F:00000380044000000040004000400040004000500C500B5008D0080000000000 +A390:00000000000000000040004000400040004000500C500B5008D0080000000000 +A391:000000000000000000C007A00890088004A003A004A008800880078000000000 +A392:0000038004400000080809881D6809180900010007C009201110111000000000 +A393:0000000000000000080809881D6809180900010007C009201110111000000000 +A394:00000000000007C008201110111010101FF0101011101110082007C000000000 +A395:000003800440000003801450145004400FE00440145014500440038000000000 +A396:000000000000000003801450145004400FE00440145014500440038000000000 +A397:0000000000000000024002500260024002400240024006400A40024000000000 +A398:000003800440000003C004200910011007D0011001100E100990086000000000 +A399:000000000000000003C004200910011007D0011001100E100990086000000000 +A39A:000000000220022003E006300A3001D00010001000100E100990086000000000 +A39B:0000000000000000000801880168011801001FF0010009200920010000000000 +A39C:000003800440000004040434042C0420042007E0042034202C20202000000000 +A39D:000000000000000004040434042C0420042007E0042034202C20202000000000 +A39E:000000000000000000C000A00090008007B008C010F010C008B0078000000000 +A39F:0000000000000000070008800BA00AE0088008800BA00AE00880070000000000 +A3A0:000003800440100028C02FB0288C10800080108028802F802880108000000000 +A3A1:000000000000100028C02FB0288C10800080108028802F802880108000000000 +A3A2:000000000000082008200440139011107D7C111011100D000B00080000000000 +A3A3:00000380044000000FE01010101010100FE001000100110011000E0000000000 +A3A4:00000000000000000FE01010101010100FE001000100110011000E0000000000 +A3A5:000000000000000009300550039003900550093001000D000B00080000000000 +A3A6:00000380044000000810081008100FF008100A100C1018102810081000000000 +A3A7:00000000000000000810081008100FF008100A100C1018102810081000000000 +A3A8:00000000000000000080088008800F80088008800080008000800FF800000000 +A3A9:0000038004400000030002C00200020003E00210024802A81AA0064000000000 +A3AA:0000000000000000030002C00200020003E00210024802A81AA0064000000000 +A3AB:0000000000000000000010180828044802880108028804480828101800000000 +A3AC:0000038004400000018001602918290029003F00290029002900010000000000 +A3AD:0000000000000000018001602918290029003F00290029002900010000000000 +A3AE:0000000000000000093009280FE40920092009200FE049202920192000000000 +A3AF:00000380044000000FE001000FE0010009200540038003800540092000000000 +A3B0:00000000000000000FE001000FE0010009200540038003800540092000000000 +A3B1:000000000000000018081608118810E81098008002A001C001C002A000000000 +A3B2:000000000000000009C01130110009200720092011201100093001C000000000 +A3B3:0380044000000540054004401390111011100EE0054005400440038000000000 +A3B4:0000000000000540054004401390111011100EE0054005400440038000000000 +A3B5:00000000000000000000190C251422241D4400841D4422242514190C00000000 +A3B6:0000000000000000008002A002A002A01880168011C012200490049000000000 +A3B7:000003800440100011801F601118114001401950171011D01130010000000000 +A3B8:000000000000100011801F601118114001401950171011D01130010000000000 +A3B9:0000000000001C0003800B600B1803401D4001401910171011D0113000000000 +A3BA:0000000000000000010009200540038009200540038009200540038000000000 +A3BB:0000038004400000012801280128012801280128013031E00D20032000000000 +A3BC:0000000000000000012801280128012801280128013031E00D20032000000000 +A3BD:000000000000000007E008100810081007E00080068009000680008000000000 +A3BE:000003800440000007900860086007A00020002007A008600860079000000000 +A3BF:000000000000000007900860086007A00020002007A008600860079000000000 +A3C0:0000000000000000022002201A28162813A81268123802200220022000000000 +A3C1:000003800440000003E004000400020001E0020004000400040003E000000000 +A3C2:000000000000000003E004000400020001E0020004000400040003E000000000 +A3C3:0000000000000490049002A001C0008000801880168011801000100000000000 +A3C4:000003800440100011E012000400140017E0140004001400120011E000000000 +A3C5:000000000000080008F0090002000A000BF00A0002000A00090008F000000000 +A3C6:000000000000018001600118010007C00920111017D011101110010000000000 +A3C7:00000380044000000E0011481148113011F811301148114811000E0000000000 +A3C8:00000000000000000E0011481148113011F811301148114811000E0000000000 +A3C9:00000000000000000760088009800A800A800A800A8009800880076000000000 +A3CA:00000380044000000C200A20082009200AA00AA00920082008A0086000000000 +A3CB:00000000000000000C200A20082009200AA00AA00920082008A0086000000000 +A3CC:000000000000000010001210112010C01FF010C0112012101000100000000000 +A3CD:0000000000000440028001002288145008201450228801000280044000000000 +A3CE:00000380044000000700088009C00AA00AA00AA00AA009C00880070000000000 +A3CF:00000000000000000700088009C00AA00AA00AA00AA009C00880070000000000 +A3D0:000000000000000000000440044012902AA829282AA812900440044000000000 +A3D1:0000038004400000038004400440038009300550039003900550093000000000 +A3D2:0000000000000000038004400440038009300550039003900550093000000000 +A3D3:000000000000000001E00210021012D00B5006500B5012D0021001E000000000 +A3D4:000000000920054003800380054009200540054001000FE001000FE000000000 +A3D5:000003800440000007C031102D10231021D02130010005400540010000000000 +A3D6:000000000000000003E018881688118810E81098008002A002A0008000000000 +A3D7:00000000000000001E00010009300550039003900550093001001E0000000000 +A3D8:0000038004400000092005400380038005400920010005400540010000000000 +A3D9:0000000000000000092005400380038005400920010005400540010000000000 +A3DA:000000000000000002480248015000E0034002C007000A801240124000000000 +A3DB:0000038004400000062005A004600400052007F00520052007F0052000000000 +A3DC:0000000000000000062005A004600400052007F00520052007F0052000000000 +A3DD:000000000000000000300028262415200CA03FA00620052004A0006000000000 +A3DE:0000038004400000007818800480027802800280027804801880007800000000 +A3DF:0000000000000000007818800480027802800280027804801880007800000000 +A3E0:000000000000000007C0082001000D200B2009A009600100082007C000000000 +A3E1:00000380044000000100010031102C10231020D0203001000100010000000000 +A3E2:0000000000000000008000801888160811881068101800800080008000000000 +A3E3:000000001FF8002000A000A0062005A0046004000480048004001FF800000000 +A3E4:000000000000073004E8042435A00C60042035A00C60042035A00C6000000000 +A3E5:000003800440000008040934092C08200FE00820092069205820402000000000 +A3E6:000000000000000008040934092C08200FE00820092069205820402000000000 +A3E7:00000000000000000EF0010002800FE0028002800FE0028001000EF000000000 +A3E8:00000000101017D0082017D0101011101110101017D0082017D0101000000000 +A3E9:0000038004400000044004401390111011100EE0000001000100010000000000 +A3EA:0000000000000000044004401390111011100EE0000001000100010000000000 +A3EB:00000000000000000F801058136012C0124012401A40166010580F8000000000 +A3EC:00000000000000001110111011100EE000000100010007C00100010000000000 +A3ED:00000380044000001110111011100EE000000100010009000900060000000000 +A3EE:00000000000000001110111011100EE000000100010009000900060000000000 +A3EF:000000000000044004400380111011100EE000000100110011000E0000000000 +A3F0:00000000000007C0082011901150111017D0111015101310082007C000000000 +A3F1:000003800440000001E00200044004A004A004A004A00440020001E000000000 +A3F2:000000000000000001E00200044004A004A004A004A00440020001E000000000 +A3F3:000000000000000003D0043009100A800A800A800A800910042003C000000000 +A3F4:000003800440000010101190115011101110111015101310082007C000000000 +A3F5:000000000000000010101190115011101110111015101310082007C000000000 +A3F6:00000000000000000180016009181100110017C0110011000900010000000000 +A3F7:00000380044000000380026002000A000A000A000A000A000260038000000000 +A3F8:00000000000000000380026002000A000A000A000A000A000260038000000000 +A3F9:0000000000000E0009C00800088008800BE008800880080009C00E0000000000 +A3FA:0000038004400000000801880968111811001700110011000900010000000000 +A3FB:0000000000000000000801880968111811001700110011000900010000000000 +A3FC:0000000000000000003000280024102023E024201CA024A0242013E000000000 +A3FD:000000000380044000000440044002800AA009200AA002800440044000000000 +A3FE:000000000000000000000440044002800AA009200AA002800440044000000000 +A3FF:000000000000000007C00820101010101110111010101010082007C000000000 +A400:000000000000000000003F8020A411240A1807F80A18112420A43F8000000000 +A401:00000380044000000400048804880450042007F80420245014880C8800000000 +A402:00000000000000000400048804880450042007F80420245014880C8800000000 +A403:000000000000000000001100114811480A3007F80A3011481148110000000000 +A404:000000000000000003F00410041003F0001003F000100BF0081007E000000000 +A405:000003800440000010101010101011F010101F101010101011F0101000000000 +A406:000000000000000010101010101011F010101F101010101011F0101000000000 +A407:00000000000000001010101011F010101F10101011F01010082007C000000000 +A408:0000000000000000010011001100111001100110111011001100010000000000 +A409:00000380044000000E00190015001120115017D01150152019000E0000000000 +A40A:00000000000000000E00190015001120115017D01150152019000E0000000000 +A40B:000000000000000007C00920111010101010101012901450082007C000000000 +A40C:00000000000000000700088008F0088008F0088008F008800880070000000000 +A40D:000003800440000007C00820101010101010101010101110092007C000000000 +A40E:000000000000000007C00820101010101010101010101110092007C000000000 +A40F:000000000000000000100810101010900E90109010100B1000D0003000000000 +A410:000003800440000007C008201010101010101010101012900AA007C000000000 +A411:000000000000000007C008201010101010101010101012900AA007C000000000 +A412:0000000000000000010011180928054803880388054809281118010000000000 +A413:0000038004400000082008200440038001000D000B0008000800080000000000 +A414:0000000000000000082008200440038001000D000B0008000800080000000000 +A415:00000000000009200AA009200440038001000D000B0008000800080000000000 +A416:0380044000001830145013901390155019300100092005400380054009200000 +A417:0000000018301450139013901550193001000920054003800540092000000000 +A418:0000000000000000082008200440038009200920038004400820082000000000 +A419:0000038004400000044004401FF004400440044004401FF00440044000000000 +A41A:0000000000000000044004401FF004400440044004401FF00440044000000000 +A41B:000000000000180004C01FA00490188000800F801080108010800F8000000000 +A41C:00000000000000000820082004400380010005400540110011000E0000000000 +A41D:0000038004400000183024480440044003800FE0010001000900060000000000 +A41E:0000000000000000183024480440044003800FE0010001000900060000000000 +A41F:0000000000000000092009200440038001000920092009200100010000000000 +A420:0380044000001830044012901290129004401830038004400920092000000000 +A421:0000000000001830044012901290129004401830038004400920092000000000 +A422:000000000000000002080208011008E01400140008E001100208020800000000 +A423:00000000000000000C040AC409B41C8C2A802A8008801C802A802A8000000000 +A424:000003800440000018C016B0118C10807C8010807C8010801080108000000000 +A425:000000000000000018C016B0118C10807C8010807C8010801080108000000000 +A426:0000000000001830044002800280028004401830038004400820082000000000 +A427:00000000000000000FE01010101010100FE0010007000800082007C000000000 +A428:038004400000001007F008800FF0088007F0010001C002A00490049000000000 +A429:000000000000001007F008800FF0088007F0008001C002A00490049000000000 +A42A:0000000000000000000007C0082009200920044009200920082007C000000000 +A42B:0000038004400000008007F00880088007F0008001C002A00490049000000000 +A42C:0000000000000000008007F00880088007F0008001C002A00490049000000000 +A42D:00000000000000003808260821C82538050001403948270821C8203800000000 +A42E:00000380044000000EE00440044004400380010007C001000900060000000000 +A42F:00000000000000000EE00440044004400380010007C001000900060000000000 +A430:000000000AC00AA00F900A800A8000800A800A800F800A800A80008000000000 +A431:00000000000000000FF01080108010800FF00080008008800880070000000000 +A432:000003800440000011101110092007C0010001000100110011000E0000000000 +A433:000000000000000011101110092007C0010001000100110011000E0000000000 +A434:0000000000000000202020203FF82024202420382020202010400F8000000000 +A435:00000000000000001110111011100EE0000009200920092000000FE000000000 +A436:03800440000003800440054005401E50155014F0054005400440038000000000 +A437:00000000000003800440054005401E50155014F0054005400440038000000000 +A438:00000000000007C00820082007C001000FE001000540155010100FE000000000 +A439:0000038004400000066005D00440044007C004400000111011100EE000000000 +A43A:0000000000000000066005D00440044007C004400000111011100EE000000000 +A43B:0000000000000000000060305054489445104214451448905054603400000000 +A43C:000000000380044000006030505448924512421C451248925054603000000000 +A43D:000000000000000000006030505448924512421C451248925054603000000000 +A43E:00000000000000000EE00100028002800EA00BA00AE0028001000EE000000000 +A43F:03800440000001E0020004400440040007E0040004400440020001E000000000 +A440:00000000000001E0020004400440040007E0040004400440020001E000000000 +A441:000000000000000003C00400082008100F90081008200800040003C000000000 +A442:000003800440000000600058004003F8184020404C404B4008C0080000000000 +A443:00000000000000000030002C002001FC0C201020262025A00460040000000000 +A444:00000000000000000F2010D010501020080006000100008010800F0000000000 +A445:038004400000049002A001C001C002A004900080188016801180100000000000 +A446:000000000000049002A001C001C002A004900080188016801180100000000000 +A447:0000000000000000082008200180014001200100010009000500030000000000 +A448:03800440000002C01AA0069002801A8006800080188016801180100000000000 +A449:00000000000002C01AA0069002801A8006800080188016801180100000000000 +A44A:000000000000111011100FE001000FE01110111001000D000B00080000000000 +A44B:000003800440000001800160011801001FF001001FF001001FF0010000000000 +A44C:000000000000000001800160011801001FF001001FF001001FF0010000000000 +A44D:00000000000000000C000B0008C0080008400840084008400800080000000000 +A44E:0000000000000000600612480A50099008100FF0081009901248624600000000 +A44F:0000038004400000088608880890081008100FF0081049902A481A4600000000 +A450:0000000000000000088608880890081008100FF0081049902A481A4600000000 +A451:0000000000000000610C11100920082008200FE0082009201110610C00000000 +A452:03800440000003800440092009200440038000000FF00060018006000FF00000 +A453:0000000003800440092009200440038000000FF00060018006000FF000000000 +A454:00000000082028282448238810100FE0210821083FF821082108010000000000 +A455:0000000000000000311809200540054005400540054005400920311800000000 +A456:00000380044000000D200BA0096001000D200BA0096001001900070000000000 +A457:00000180016001000D200BA0096001000D200BA0096001001900070000000000 +A458:000000000000000003800440044008200820082008200920092006C000000000 +A459:000000000000000007C00820111011101FF0111011101010082007C000000000 +A45A:0000038004400000088008800E8009C008B00880089008900890088000000000 +A45B:0000000000000000088008800E8009C008B00880089008900890088000000000 +A45C:0000000000000000008007F008800880088007F0008000900090009000000000 +A45D:00000000000000001110111011100EE000000440028001000280044000000000 +A45E:00000000038004400000110811080A080A0804680A580A401140114000000000 +A45F:00000000000000000000110811080A080A0804680A580A401140114000000000 +A460:00000000000006200920062000200620092006200020062001A0006000000000 +A461:00000000000000001110111011100EE004400540038001000900060000000000 +A462:00000380044000001110111011100EE004400440044015401540088000000000 +A463:00000000000000001110111011100EE004400440044015401540088000000000 +A464:000000000000000000002208220814681458084014E0144022E0224000000000 +A465:00000380044000000920092004400380044008200FE008200440038000000000 +A466:00000000000000000920092004400380044008200FE008200440038000000000 +A467:000000000000111011100EE0000004400380000014501390082007C000000000 +A468:00000380044000000660055004C804400E40154015400E400440044000000000 +A469:00000000000000000660055004C804400E40154015400E400440044000000000 +A46A:00000000000000001860165811C6104096405A4032405A409640104000000000 +A46B:000000000000000004400440038001000D200BA00960010001000FE000000000 +A46C:00000380044000000100010031102D10231021D0213001000100010000000000 +A46D:00000000000000000080008018881688118810E8109800800080008000000000 +A46E:00000000000000000220022001C018881688118810E810980080008000000000 +A46F:0000038004400000111011101110092007C031102D10231021D0213000000000 +A470:0000000000000000088808880888049003E018881688118810E8109800000000 +A471:0000000000000000000800C800A8009800801F8024803F8024801F8000000000 +A472:000003800440000028F029083A04280428040004000403840264021800000000 +A473:000000000000000028F029083A04280428040004000403840264021800000000 +A474:0000000000000180016001000920054003800540092001000D00030000000000 +A475:0000000000000000000400640054004C0FC038E01540154038E007C000000000 +A476:00000380044000000010031002D0023002001FC002001FC00200020000000000 +A477:00000000000000000010031002D0023002001FC002001FC00200020000000000 +A478:000001C00130010007C00920155013901550092007C001001900070000000000 +A479:000000000000000012C012B00C8000C00CB0128012C000B00680018000000000 +A47A:00000380044000000CC012B012801E80128012E00C9000900690018000000000 +A47B:00000000000000000CC012B012801E80128012E00C9000900690018000000000 +A47C:00000000000002000FA0022000200FA0106010001F00102010400F8000000000 +A47D:00000000000000000CC012B012800080128012800C8000800680018000000000 +A47E:000003800440000003D00430081008000F80080008000810042003C000000000 +A47F:000000000000000003D00430081008000F80080008000810042003C000000000 +A480:000000000000000008200820044003800120014001800110011000E000000000 +A481:000000000180016001000D200BA00960010007C001000D000B00080000000000 +A482:0380044000001110111017D011101110082007C00100111011100EE000000000 +A483:0000000000001110111017D011101110082007C00100111011100EE000000000 +A484:00000000000000000020092009200FE0092009200020062001A0006000000000 +A485:0380044000000180016001000D200BA00960010007C001000D00030000000000 +A486:0000000000000180016001000D200BA00960010007C001000D00030000000000 +A487:000000000000092009200440038000000FE00000038004400920092000000000 +A488:00000380044000000040004003C0044008400840044003C00040004000000000 +A489:00000000000000000040004003C0044008400840044003C00040004000000000 +A48A:000000000000000000F00700090010801070108009000700010000F000000000 +A48B:038004400000393805400540393801001FF00100393805400540393800000000 +A48C:000000000000393805400540393801001FF00100393805400540393800000000 +A48D:00007FFE61B66DB661866DF66DF67FFE7FFE738E6DB673B66DB6738E7FFE0000 +A48E:00007FFE61B66DB661866DF66DF67FFE7FFE73866DBE738E6DBE73867FFE0000 +A48F:00007FFE61B66DB661866DF66DF67FFE7FFE73866DBE738E6DBE73BE7FFE0000 +A490:0000000000000000010001000100010001000100010001000100010000000000 +A491:000000000000000000400040004000400040004000400C40034000C000000000 +A492:0000000000000000040004000400040004000400040004600580060000000000 +A493:0000000000000000060005800460040004000400040004000400040000000000 +A494:0000000000000000018001600100010001000100010001000D00030000000000 +A495:00000000000000000020062005A0046004000400040004000400040000000000 +A496:00000000000000000040004000400040004000400C400B4008C0080000000000 +A497:000000000000000001800160011801000100010031002D002300200000000000 +A498:000000000000000000C800A80098008000800080008018800680018000000000 +A499:0000000000000000180816081188106810180000000000000000000000000000 +A49A:000000000000000003C00420040004000200018000400020042003C000000000 +A49B:0000000000000000004000400040034002C00200020002000200020000000000 +A49C:000000000000000003C00420081000100010001000100E100990086000000000 +A49D:000000000000000003D00430081008000800080008000810042003C000000000 +A49E:00000000000000000E2009A008600800080008000800086009A00E2000000000 +A49F:000000000000000001E00200040004000400040004000400020001E000000000 +A4A0:00000000000000000FC0002000200020002000200020002000200FC000000000 +A4A1:0000000000000000082008200440038000000000000000000000000000000000 +A4A2:0000000000000000000000000000000000000000038004400820082000000000 +A4A3:0000000000000000180806080188006800180000000000000000000000000000 +A4A4:000000000000000010101010101010101010101010101010082007C000000000 +A4A5:0000000000000000086008800880088008800880088008800880070000000000 +A4A6:0000000000000000183024480440044004400440044004400440038000000000 +A4A7:000000000000000003800440044008200820082008200920092006C000000000 +A4A8:000000000000000007C00820101010101010101010101010082007C000000000 +A4A9:0000000000000000038004400440044004400440044004400440038000000000 +A4AA:00000000000000000FE01010101010100FE00000000000000000000000000000 +A4AB:000000000000000001000280044008200FE00000000000000000000000000000 +A4AC:000000000000000000C000A00090008007800880108010800880078000000000 +A4AD:000000000000000000C000A00090008007C008A0109010800880078000000000 +A4AE:0000000000000000000800C800A8009807800880108010800880078000000000 +A4AF:0000000000000000002000200020002001E0022004200420022001E000000000 +A4B0:000000000000000003C004000400020001C0020004000400040003C000000000 +A4B1:0000000000000000078000400040008007000080004000400040078000000000 +A4B2:000000000000000003E00400040003E00400040003E00400040003E000000000 +A4B3:00000000000000001110111011100EE000000000000000000000000000000000 +A4B4:0000000000000000444444444C64345804400440038000000000000000000000 +A4B5:00000000000000001C7008200820044003800000000000000000000000000000 +A4B6:00000000000000004444444444443BB800000000000000000000000000000000 +A4B7:0000000000000000183024480440044003800000000000000000000000000000 +A4B8:00000000000000000710089008A007C000800080008000800C80030000000000 +A4B9:00000000000000000E20112011400F800100010001000120012000C000000000 +A4BA:000000000000000007900860086007A00020002007A008600860079000000000 +A4BB:000000000000000000200020002000200020022005200520032004C000000000 +A4BC:0000000000000000000004400440028002800100028002800440044000000000 +A4BD:00000000000000000C6002800100028002800440044008200820082000000000 +A4BE:0000000000000FE00820044002800280010002800280044008200FE000000000 +A4BF:0000000000000000000030182828244822882108228824482828301800000000 +A4C0:0000000000000000000010180828044802880108028804480828101800000000 +A4C1:0000000000000000000030182828244802880108028804480828101800000000 +A4C2:00000000000000000000190C251422241D4400841D4422242514190C00000000 +A4C3:0000000000000FE0082004400440028002800100028002800440044000000000 +A4C4:00000000000000000FE001000100010001000100010001000100010000000000 +A4C5:00000000000000001FC002200210020002000200020002000200020000000000 +A4C6:0000000000000000000004400440044000000000000000000000000000000000 +A4C7:00007FFE61B66DB661866DF66DF67FFE7FFE71866FF66FEE6FDE71DE7FFE0000 +A4C8:00007FFE61B66DB661866DF66DF67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +A4C9:00007FFE61B66DB661866DF66DF67FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +A4CA:00007FFE61B66DB661866DF66DF67FFE7FFE71866FB66F866FB671B67FFE0000 +A4CB:00007FFE61B66DB661866DF66DF67FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +A4CC:00007FFE61B66DB661866DF66DF67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +A4CD:00007FFE61B66DB661866DF66DF67FFE7FFE718E6FB66FB66FB6718E7FFE0000 +A4CE:00007FFE61B66DB661866DF66DF67FFE7FFE71866FBE6F8E6FBE71867FFE0000 +A4CF:00007FFE61B66DB661866DF66DF67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +A4D0:000000007C4242427C424242427C0000 +A4D1:000000007C4242427C40404040400000 +A4D2:0000000002020202023E4242423E0000 +A4D3:00000000784442424242424244780000 +A4D4:000000007F0808080808080808080000 +A4D5:000000000808080808080808087F0000 +A4D6:000000003C424240404E4242463A0000 +A4D7:00000000424448506060504844420000 +A4D8:000000004222120A06060A1222420000 +A4D9:00000000040404040404044444380000 +A4DA:000000003C42424040404042423C0000 +A4DB:000000003C42420202020242423C0000 +A4DC:000000007E02020408102040407E0000 +A4DD:000000007E4040407C40404040400000 +A4DE:0000000002020202023E0202027E0000 +A4DF:00000000424266665A5A424242420000 +A4E0:0000000042626252524A4A4646420000 +A4E1:000000004040404040404040407E0000 +A4E2:000000003C424240300C0242423C0000 +A4E3:000000007C4242427C48444442420000 +A4E4:0000000042422222123E4242423E0000 +A4E5:00000000080814142222224141410000 +A4E6:00000000414141222222141408080000 +A4E7:00000000424242427E42424242420000 +A4E8:000000005C62424272020242423C0000 +A4E9:00000000384444404040404040400000 +A4EA:00000000424242425A5A666642420000 +A4EB:00000000424224241818242442420000 +A4EC:00000000414122221408080808080000 +A4ED:000000003E424242423E4242423E0000 +A4EE:0000000018242442427E424242420000 +A4EF:00000000424242427E42422424180000 +A4F0:000000007E4040407C404040407E0000 +A4F1:000000007E0202023E020202027E0000 +A4F2:00000000080808080808080808080000 +A4F3:000000003C42424242424242423C0000 +A4F4:000000004242424242424242423C0000 +A4F5:000000003C4242424242424242420000 +A4F6:000000007E0202020202020202020000 +A4F7:000000001E22424242424242221E0000 +A4F8:00000000000000000000000018180000 +A4F9:00000000000000000000000018080810 +A4FA:00000000000000000000000066660000 +A4FB:00000000000000000000000066620204 +A4FC:00000000000018180000001808081000 +A4FD:00000000000018180000001818000000 +A4FE:00000000000000000070000006060000 +A4FF:000000000000007E0000007E00000000 +A500:0000000000000FE00100010001001930254825481930010001000FE000000000 +A501:0000000000000FE001000FE0010019302548193001000FE001000FE000000000 +A502:000000000000242024401A800100010002000200022001480090016000000000 +A503:0000000000003E0008000800046003A0012001E000200020002000F800000000 +A504:0000000000003E0008003E00046003A0012001E0002000F8002000F800000000 +A505:0000000000003838444447C44544393801000380044004400440038000000000 +A506:0000000000000380044004400440139001003938454447C44444383800000000 +A507:00000000000004200860086004A003200020002000200020002000F800000000 +A508:00000000000004200860086004A003200020002000A80020002000F800000000 +A509:0000000000001FF0010001000540010001000100010001000100010000000000 +A50A:0000000000001FF0010001000540010001000FE0010001000100010000000000 +A50B:0000000000001FF0010001000100010001000100010001000100010000000000 +A50C:000000000000038004400440044003800100010001000100010007C000000000 +A50D:0000000000000380044004400440038001000100010007C0010007C000000000 +A50E:000000000000124012400DC00040004000400078004000400040007800000000 +A50F:000000000000124012400DF80040004000400078004000400040007800000000 +A510:00000000000049004900370001000150015403A8050009000900060000000000 +A511:00000000000049004900372001000150015403A8050009200900060000000000 +A512:000000000000124012400DC00040004000480078004800400040004000000000 +A513:000000000000124012400DC0004000480078004800400040071008E000000000 +A514:00000000000006180A2812482288020802080208020802080208020800000000 +A515:0000000000001F800080008000800080008007F8088808880888070800000000 +A516:0000000000000920092009200920092009200920092009200920092000000000 +A517:00000000000009200920092009200920092009200920092000000FE000000000 +A518:0000000000001010101010100000010001000100000010101010101000000000 +A519:00000000000010101FF010100000010001000100000010101FF0101000000000 +A51A:000000000000000000001C703EF83EF83EF83EF83EF81C70482437D800000000 +A51B:000000000000000000001C70228822882288228822881450482437D800000000 +A51C:00000000000000002000204020003FE020083FE0200020402000000000000000 +A51D:000000000000000020002000204020003FE82000204020002000000000000000 +A51E:000000000000A00AA00AA00AA44AAAAAAAAAAAAAA44AFBBEA00AA00A00000000 +A51F:0000000000002008200820082C68329821082288228822882108200800000000 +A520:000000000000042004200420042004203FFC0420042004200420042000000000 +A521:000000000000062009600A6004A0032000200020002000200020007800000000 +A522:0000000000000810142822440990024002400240024002400240018000000000 +A523:000000000000082000001C70228822882288228822881450482437D800000000 +A524:000000000000124012400DC0004000480078004800400040004001F000000000 +A525:000000000000124012400DC000500044007C004400500040004001F000000000 +A526:000000000000124012400DC00040044407FC044400400040004001F000000000 +A527:000000000000000003800440004001800240024001800200022001C000000000 +A528:000000000000124012400DC00040124012400DC0007000C80548023001000000 +A529:000000000000124012400DC00040124012400DC0007000CA0532020C01000000 +A52A:0000000000000E000F800FE00F800E000C000E000F800FE00F800E0000000000 +A52B:000000000000308C49523E3C0410041004100410041004100808100400000000 +A52C:0000000000000E001100110011100A100FF00A101110110011000E0000000000 +A52D:0000000000000E001100110011500A100FF00A101150110011000E0000000000 +A52E:00000000000003800D6011101390244824482388145018300C60038000000000 +A52F:0000000000003FF801000100054001000FE00100054001000100010000000000 +A530:000000000000010001000100054001003FF80100054001000100010000000000 +A531:0000000000001110111011101EE01000100010001110111011100EE000000000 +A532:00000000000000C00100111011101EE01000111011100EE00080030000000000 +A533:000000000000121012200DC00080008001100100012401040088007000000000 +A534:000000000000121012200DC00088008001100100012401040088007000000000 +A535:00000000000008000800080009E00A500C900860080008000800080000000000 +A536:00000000000008000A00080009E00A500C9008600A0008000800080000000000 +A537:00000000000000000000018003C007E007E003C0018000000000000000000000 +A538:00000000000000000000018003C007E007E003C001800000071008E000000000 +A539:00000000000000000000018003C007E017E803C0018000000000000000000000 +A53A:00000000000001000200010044A245223BDC0100008001000200010000000000 +A53B:0000000000001C0022002200222814281FE814282228220022001C0000000000 +A53C:0000000000001C002200220022A814281FE8142822A8220022001C0000000000 +A53D:0000000000000060018006000180186024101860018006000180006000000000 +A53E:0000000000000060018006000180186024141860018006000180006000000000 +A53F:00000000000003E004000FC008000800080009800A400C400440038000000000 +A540:00000000000000000000000004404C6433980000000000000000000000000000 +A541:0000000000000000000004400000000004404C64339800000000000000000000 +A542:00000000000000000100000004404C6433980000000001000000000000000000 +A543:00000000000001000200040004000800080009C00A200C20042003C000000000 +A544:00000000000001000200040004000800080009C00A200CA0042003C000000000 +A545:000000000000248024801B80008000A8008801F8028804A80480030000000000 +A546:0000000000000738084010801080210021002100108010800840073800000000 +A547:00000000000007E0001007E00400043005D00610001003F0040003F000000000 +A548:00000000000000800080008000800080008007F8088808880888070800000000 +A549:0000000000000380044004400440038001000540010005400100010000000000 +A54A:00000000000000000380044004400440044004402288210812900C6000000000 +A54B:00000000000000000380044004400444044004402288210812900C6400000000 +A54C:000000000000442244224E7235AC042004200420042004200420042000000000 +A54D:00000000000000000100444444444EE437D80440044005400440044000000000 +A54E:000000000000121012200DC00080008001000100010401040088007000000000 +A54F:000000000000248024801B8000800080008000B000C8008000B000C800000000 +A550:000000000000222022201DE00020002000A80020002000200020002000000000 +A551:000000000000380E44104220424032400FF0024C024204420822701C00000000 +A552:0000000000003FE020202020203C202422242024203C202020203FE000000000 +A553:00000000000000003FF02088208824B0208020803FF000080008003000000000 +A554:00000000000001000100028002800440044008200820101010101FF000000000 +A555:0000000003800C6018301450228821082288145018300C600380000000000000 +A556:00000000000001000100028012900440044008200820101010101FF000000000 +A557:0000000000000FC008200810081008200FC008200810081008200FC000000000 +A558:00000000000003C00420082001C001000100010001C00820042003C000000000 +A559:00000000000010F011081208107010401FC0104010701208110810F000000000 +A55A:0000000000001110111013900D60010001000100010001000100010000000000 +A55B:00000000000017D0111013900D6001000100010001000100010007C000000000 +A55C:0000000000000008010800081108110812980C68000801080008000800000000 +A55D:00000000000000140214001422142214253418D4001402140014001400000000 +A55E:0000000000000A000A000A000BF00A000A000BF00A000A000A000A0000000000 +A55F:0000000000000A000A000A000BF00A000A000BF00A000200071008E000000000 +A560:0000000000000030000800083FF02220222022202220222022203FE000000000 +A561:0000000000000030008800083FF02220222422202220222022203FE000000000 +A562:0000000000000EE01110111011100FE003800440044004400380000000000000 +A563:0000000000000EE01110111011100FE003800440044014500380000000000000 +A564:000000000000000000000EE0111011100FE0111011100EE00000000000000000 +A565:000000000000010000000EE0111011104FE4111011100EE00000010000000000 +A566:000000000000003001C006401880010007001930014801880088007000000000 +A567:0000000000001FF0038003800540054009200920111011102108210800000000 +A568:0000000000000EE0111011101FF0038005400540092009201110111000000000 +A569:000000000000121012200DC00080488049003700010401040088007000000000 +A56A:00000000000004000800086004A0032000200020002000200020002000000000 +A56B:0000000000000E00110011000100010002000C3810443FC40044003800000000 +A56C:0000000000001FF022882288228822881FF022882288228822881FF000000000 +A56D:000000000000442244224E7235AC042004200420442244224A52318C00000000 +A56E:0000000000003018482444443FF8044004400440044008200820101000000000 +A56F:0000000000000FE00100010001000100010001000100010001000FE000000000 +A570:000000000000444044403BC000400040007C0044004400440044007C00000000 +A571:00000000000010001F8010800080008800F8008800800080008001C000000000 +A572:00000000000010001F80108000A0008800F8008800A00080008001C000000000 +A573:00000000000010001F801080008008880FF8088800800080008001C000000000 +A574:0000000000001C0008000800080008080FF8008800800080008001C000000000 +A575:0000000000001C0008000800082008080FF8008800A00080008001C000000000 +A576:0000000000000390045008300810040003800040002008200C400B8000000000 +A577:0000000000000390045009300810040003800040002009200C400B8000000000 +A578:0000000000000000006001900610186010001200106011901610186000000000 +A579:000000000000000000000000381C7C3E7FFE7C3C381C00000000000000000000 +A57A:0000000000000100028002800440044008200440044002800280010000000000 +A57B:0000000000000100028002800440044028280440044002800280010000000000 +A57C:000000000000002000200FE0082008200820082008200FE00020002000000000 +A57D:0000000000002108210823881D70010001000FE0010001000100010000000000 +A57E:0000000000002108210823881D70010001000FE001000FE00100010000000000 +A57F:00000000000000E011000200020002001200020002000200110000E000000000 +A580:00000000000000E011000200020002001220020002000200110000E000000000 +A581:000000000000442244224E7235AC0420042004200420042004200E7000000000 +A582:000000000000442244224E7235AC0420042004A00420042004200E7000000000 +A583:000000000000248024801B80009800A800C80188028004800480030000000000 +A584:000000000000248024981BA800C8018802800480048003001C40238000000000 +A585:0000000000000FE001004104410441047FFC41044104410401000FE000000000 +A586:000000000000248024801B800080008000F001A802A804900480030000000000 +A587:000000000000222022202220222022203FE0002000200020002000F800000000 +A588:000000000000222022202220222022203FE00020002000A8002000F800000000 +A589:0000000000000380044004400440028001000280044004400440038000000000 +A58A:0000000000000380044014500440028001000280044014500440038000000000 +A58B:0000000000000100010001000920010001000100092001000100010000000000 +A58C:0000000000000100010001000100010009200100010001000100010000000000 +A58D:0000000000001040104010401040104012481040104010401040104000000000 +A58E:0000000000000400040004000480040004000400048004000400040000000000 +A58F:0000000000003018482444443FF80440044004400440082008201FF000000000 +A590:0000000000003018482444443FF8044004400440082008281FF8000800000000 +A591:0000000000003F800080008007F8008800880088008800880008000800000000 +A592:00000000000000000000010038387C7C7FFC7C7C383801000000000000000000 +A593:0000000000004900490037200100017801840324050809000900060000000000 +A594:0000000000000FE00100010009200100010001000920010001000FE000000000 +A595:0000000000002108210823881D700100010005F4001000100010001000000000 +A596:0000000000004210421047103AE0020002000BE8002000F8002000F800000000 +A597:0000000000004210421047103AE00200020003E000200020002000F800000000 +A598:00000000000003800C6010101390244824482288911292924C64339800000000 +A599:0000000000002108210823881D700100010001F0001000100010001000000000 +A59A:0000000000004210421047103AE00200020003E0002000F8002000F800000000 +A59B:0000000000000420042004203FFC0420042004203FFC04200420042000000000 +A59C:0000000000003838444444444444383800000380044004400440038000000000 +A59D:0000000000000E001100110011000A0007F00A081108111011000E0000000000 +A59E:0000000000000E001100110011400A0007F00A081148111011000E0000000000 +A59F:000000000000100029082B881D700100010001000100010001000FE000000000 +A5A0:000000000000100029082B881D700100010001000540010001000FE000000000 +A5A1:000000000000101029282BA81D700100010001000100010001000FE000000000 +A5A2:0000000000000060008001003938454447C445443938010002000C0000000000 +A5A3:000000000000001800200040385C446247E246623A5C024004801B0000000000 +A5A4:000000000000070008800880088007000240020003E002000240020000000000 +A5A5:0000000000000E001100110011000E0004A0042007E0042004A0040000000000 +A5A6:0000000000001130115011501190119011101310131015101510191000000000 +A5A7:0000000000001130115011501190119051141310131015101510191000000000 +A5A8:000000000000000000001000100010001FF01008100810080030000000000000 +A5A9:0000000000001000100010001FF010081008100800300000071008E000000000 +A5AA:000000000000000000001000120010001FF01008120810080030000000000000 +A5AB:000000000000000000001000100010001FF01008100810480070004000000000 +A5AC:0000000000000C30145004100410041000000080008000800080008000000000 +A5AD:0000000000000C30145004100410041000000080008002A00080008000000000 +A5AE:0000000000000C3014500410041004100000008000800080008003E000000000 +A5AF:0000000000000C30145004100410041000000080008002A0008003E000000000 +A5B0:000000000000000000001100150011001FF01108150811080030000000000000 +A5B1:000000000000000000001100110011001FF01108110811080030000000000000 +A5B2:000000000000000000001500150015001FF01508150815080030000000000000 +A5B3:000000000000000000001400150014001FF01408150814080030000000000000 +A5B4:00000000000003800C6010101010200821082008101010100C60038000000000 +A5B5:000000000000038004400540044003800100010005400100010007C000000000 +A5B6:000000000000038004400540044003800100010001000100010007C000000000 +A5B7:00000000000004000860086004A0032004200420042004200420042000000000 +A5B8:0000000000001FF0111011101110111011F011101110111011101FF000000000 +A5B9:0000000000000820082008200920082008200920082008200440038000000000 +A5BA:000000000000111011101EE01000111011101EE01000111011100EE000000000 +A5BB:0000000000003838044002800280028022900280028002800440383800000000 +A5BC:0000000000003938044002800280028002800280028002800440393800000000 +A5BD:00000000000022301DD022301DD022301DD00010001000100010007C00000000 +A5BE:0000000000007C7C044004400440044007C004400440044004407C7C00000000 +A5BF:000000000000111011100EE00000111011100EE00000111011100EE000000000 +A5C0:00000000000022301DD022301DD022301DD000100010007C0010007C00000000 +A5C1:000000000000000000000000381C442247E246623A5C024004801B0000000000 +A5C2:00000000000000D8012002403A5C466247E246623A5C024004801B0000000000 +A5C3:0000000000000030004800880110020007000F801FC00F800700020000000000 +A5C4:0000000000000030004800880110124007000F801FC00F800700020000000000 +A5C5:000000000000221022301DD00010221022301DD0001000100010007C00000000 +A5C6:000000000000221022301DD00010221022301DD0001000540010007C00000000 +A5C7:0000000000000FE002800280044004400820482430181FF00820044000000000 +A5C8:00000000000007C0000007C001000280044028285FF428281450082000000000 +A5C9:000000000000000003C004200FF0042003C004200420042003C0000000000000 +A5CA:000000000000000003C004200FF0042003C004200FF0042003C0000000000000 +A5CB:0000000000001FF010001000100010001FF010001000100010001FF000000000 +A5CC:000000000000124012400DC000480050006000C0014002400240018000000000 +A5CD:0000000000001FF010001080100010001FF010001080100010001FF000000000 +A5CE:000000000000124012400DC000480050006004C8014002400240018000000000 +A5CF:000000000000000003C004200400040003C004200420042003C0000000000000 +A5D0:00000000000003C004200400040003C00420042003C00000071008E000000000 +A5D1:0000000000000C6012902108228802800280010001000100010007C000000000 +A5D2:0000000000000C6012902108228802800280010001000540010007C000000000 +A5D3:00000000000000E001300230020002E0033002300200020002000F8000000000 +A5D4:00000000000000E001300230020002E00B3402300200020002000F8000000000 +A5D5:00000000000000E001300230020002E00330023002000F8002000F8000000000 +A5D6:00000000000000E001300230020002E00B34023002000F8002000F8000000000 +A5D7:00000000000003E00210021003E00210021003E002000A8002000F8000000000 +A5D8:00000000000007F00508050805F00508050805F00500050005001FC000000000 +A5D9:00000000000007F00508050805F00508050805F00500154005001FC000000000 +A5DA:000000000000000003E004100490041003E004100490041003E0000000000000 +A5DB:00000000000001E006100860080009C00E2008C0080008F00B080C3000000000 +A5DC:00000000000000000000044040044444644C5BB4400444200000000000000000 +A5DD:0000000000000000010000000380044008200820082004400380101000000000 +A5DE:0000000000001FF00000038004400820082008200440038000001FF000000000 +A5DF:00000000000003D00450087008500400038000400A200A200E400B8000000000 +A5E0:0000000000003870448842840204020407F808101020204059B266CC00000000 +A5E1:000000000000044004A004A004A004C807500C20145014501450082000000000 +A5E2:000000000000000000020002309248924C924B6E300200020002000000000000 +A5E3:0000000000003E100808083408C00B000C000B0008C0083408083E1000000000 +A5E4:000000000000084014A014A014A008C8155026200A500A500A50042000000000 +A5E5:000000000000084014A014A014A048CA155026200A500A500A50042000000000 +A5E6:0000000000000C6012902108228802800280010001000120012000C000000000 +A5E7:0000000000000C6012902108228802800280010001000128013000C000000000 +A5E8:00000000000000C003000C00030000C0002000C003000C00030000C000000000 +A5E9:00000000000000C003000C00030000C0082400C003000C00030000C000000000 +A5EA:00000000000010E011001200120012001200120012001200110010E000000000 +A5EB:0000000000001070148011001100110011001100110011001480107000000000 +A5EC:000000000000000000000000381C442247E24422381C00000000000000000000 +A5ED:000000000000000000000000381C442247E24422381C00000240000000000000 +A5EE:0000000000000000000001003838444447C44444383801000000000000000000 +A5EF:000000000000000C0014002470444C8443844264441C48005000600000000000 +A5F0:000000000000000C0114002470444C8443844264441C48005100600000000000 +A5F1:00000000000000F0030804300800080008000800080008F00B080C3000000000 +A5F2:00000000000000F0030806300A000A000A000A000A000AF00B080C3000000000 +A5F3:000000000000038004400440428441047FFC4104428404400440038000000000 +A5F4:000000000000038004400440529441047FFC4104529404400440038000000000 +A5F5:000000000000000003C014281FF8142803C014281FF8142803C0000000000000 +A5F6:000000000000000003C044227FFE442213C844227FFE442203C0000000000000 +A5F7:0000000000001010101010101010101000000100010001000100010000000000 +A5F8:000000000000101010101010101001000100010001000000071008E000000000 +A5F9:0000000000001010101010101010101000000100010009200100010000000000 +A5FA:0000000000000100010001001110101010101010111001000100010000000000 +A5FB:0000000000000100010001000100454445443BB8010001000100010000000000 +A5FC:0000000000000100010001000100454445443BB8010011100100010000000000 +A5FD:0000000000000100010011100100454445443BB8010011100100010000000000 +A5FE:00000000000007C0010011100100454405443BB801001110010007C000000000 +A5FF:0000000000000F00108020800700040007F804000700208010800F0000000000 +A600:0000000000000F00108020800720040007E804000720208010800F0000000000 +A601:0000000000000F00108020800728040807F804080728208010800F0000000000 +A602:0000000000000F00108020880708040807F804080708208810800F0000000000 +A603:0000000000002108210813900D6001000100010001000100010007C000000000 +A604:0000000000002108210813900D6001000100010005400100010007C000000000 +A605:0000000000002108210813900D60010001000540010007C0010007C000000000 +A606:0000000000002108210813900D6001000100010007C00100010007C000000000 +A607:0000000000002108210813900D60010001000100010009200FE0082000000000 +A608:0000000000001248124812481248124812481248124812481248124800000000 +A609:0000000000001EF00100028002800280028002800280028001001EF000000000 +A60A:0000000000002108210813900D600100010001F0015001F0015001F000000000 +A60B:000000000000121012200DC00080008001000138014401440088007000000000 +A60C:0000000000000000000000003FFC0000000000003FFC00000000000000000000 +A60D:0000000000000000000000000000000001000100028002800440044000000000 +A60E:000000000000000000000420024001800FF00180024004200000000000000000 +A60F:0000000000000000000000000000000000003A884694438452C422B800000000 +A610:00000000000001C002200410641064161C1E04100410041002D601CE00000000 +A611:000000000000111011100EE004400440044004400440155015500EE000000000 +A612:000000000000060C183060C01830060C01FE060C183060C01830060C00000000 +A613:00000000000003C004200400040004000380040004000400042003C000000000 +A614:000000000000222022601DA00020002000E40138002000200020002000000000 +A615:0000000000000014071408940894089445144214251418FC0014001400000000 +A616:0000000000000FE00820092008200820092008200820092008200FE000000000 +A617:0000000000000218022802480288020802080208220812080A08060800000000 +A618:00000000000003700D983118010001700198011801000100010007C000000000 +A619:0000000000000FE001000100010001F0010801080130010001000FE000000000 +A61A:0000000000001110000019982220222022202220222019980000111000000000 +A61B:000000000000121012200DC0008000800100010001FC01040088007000000000 +A61C:0000000000003FF8210811101110092009200540054003800380010000000000 +A61D:0000000000000FF008900C900B600800080008000800080008003E0000000000 +A61E:000000000000442044603BA000240020003E0020002400200020002000000000 +A61F:0000000000001C00220022001C6008900510031004E004000200018000000000 +A620:000000000000111011100EE0000007C00820101010101010082007C000000000 +A621:0000000000000080008000800080008000800080008000800080008000000000 +A622:0000000000000380044004400380010005400100054001000164019800000000 +A623:0000000000003800440047804440384003800040004003800200020000000000 +A624:0000000000000C000A00090008000900090009000FE001200120012000000000 +A625:0000000000000C000A00090008000800080009C00A200C100C10082000000000 +A626:00000000000001C002001F8004000400040004C005200620022001C000000000 +A627:0000000000000CC01340004000400040004000E001100110011000E000000000 +A628:00000000000004200000000004200420042003C004200420042003C000000000 +A629:0000000000000070008800880C701220114011800E4000400080030000000000 +A62A:0000000000003018482444443FF8044004400440044048242828101000000000 +A62B:000000000000038004400440044003800100010001000110011000E000000000 +A62C:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000 +A62D:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE618E7DB661B66FB6618E7FFE0000 +A62E:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61867DBE618E6FBE61867FFE0000 +A62F:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61867DBE618E6FBE61BE7FFE0000 +A630:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63CE7DB671B67DB663CE7FFE0000 +A631:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000 +A632:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DF671867DBE63867FFE0000 +A633:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE638E7DF671C67DF6638E7FFE0000 +A634:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63B67DB671867DF663F67FFE0000 +A635:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DBE71867DF663867FFE0000 +A636:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000 +A637:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DF671EE7DDE63DE7FFE0000 +A638:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000 +A639:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63CE7DB671C67DF663CE7FFE0000 +A63A:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DB671867DB663B67FFE0000 +A63B:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE638E7DB6718E7DB6638E7FFE0000 +A63C:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000 +A63D:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE638E7DB671B67DB6638E7FFE0000 +A63E:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DBE718E7DBE63867FFE0000 +A63F:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DBE718E7DBE63BE7FFE0000 +A640:000000007E02020408102040407E3A44 +A641:0000000000007E0204081020407E3A44 +A642:000000007E020204087C2040407E3A44 +A643:0000000000007E02047E1020407E3A44 +A644:000000003C4242020C304042423C0000 +A645:0000000000003C42020C3040423C0000 +A646:00000000202020202020202024180000 +A647:00000000000020202020202024180000 +A648:00000000103810103844828282820000 +A649:00000000000010381038444444440000 +A64A:000000000000424224183C4A524A423C +A64B:00000000020244442810282828100000 +A64C:00000000000000003C78428442844004400440044004410442843C7800000000 +A64D:00000000000000000000000030184004400440044004410442843C7800000000 +A64E:00000000205050101E111111111E0000 +A64F:0000000000002050501E1111111E0000 +A650:00000000E2222222322A2A2A2A320000 +A651:000000000000E22222322A2A2A320000 +A652:00000000507E50505C525252525C0000 +A653:000000000000507E50505C52525C0000 +A654:00000000324A4A4A4E4A4A4A4A320000 +A655:000000000000324A4A4E4A4A4A320000 +A656:000000008894A2A2FEA2A2A2A2A20000 +A657:0000000000004C42424E7252524E0000 +A658:0000000008081414223E2241417F0000 +A659:000000000000081414223E41417F0000 +A65A:000000003E222214081C227F49490000 +A65B:0000000000003E22143E417F49490000 +A65C:0000000048485454527E6241417F0000 +A65D:000000000000444A4A517F51515F0000 +A65E:0000000000000100038005400540092009202910111001000100010000000000 +A65F:0000000000081C2A2AA9490808080000 +A660:000000002121212121212121217F4040 +A661:000000000000222222222222227E4040 +A662:000000000000000003FC048004800480088008800880108010803FC020402040 +A663:00000000000000000000000007F80480088008801080108010801FC010400000 +A664:00000000000000000FFC08800880088008800880088010801080208000000000 +A665:0000000000000000000000000FF8088008800880088010801080208000000000 +A666:000000000000000021FC2100330033002D002D00210021002100210000000000 +A667:00000000000000000000000021F8330033002D002D0021002100210000000000 +A668:000000003C4242425A5A4242423C0000 +A669:0000000000003C42425A5A42423C0000 +A66A:000000007C82828282AA8282827C0000 +A66B:0000000000003E4141415541413E0000 +A66C:00000000000000001E782184218421842DB42DB42184218421841E7800000000 +A66D:0000000000000000000000001E78218421842DB42DB4218421841E7800000000 +A66E:0E70118815A811880E7039CE463156B5463139CE0E70118815A811880E700000 +A66F:007E4200000000000000000000000000 +A670:0000028001002AA8101028280000A0144008A014000000002828129029280280 +A671:007E420000000000000000000000427E +A672:0100010007C0010001000000F01E00000000F01E00000000F01E054005400540 +A673:1028EE824482EE281000000000000000 +A674:001C2238221C00000000000000000000 +A675:0022262A322200000000000000000000 +A676:00140008080800000000000000000000 +A677:00221408102000000000000000000000 +A678:0030101C121C00000000000000000000 +A679:004242724A7200000000000000000000 +A67A:00202038243800000000000000000000 +A67B:00545454280000000000000000000000 +A67C:00242418000000000000000000000000 +A67D:000A0A06020000000000000000000000 +A67E:00242418000000000000000000000000 +A67F:000A0A06020000000000000000000000 +A680:001010101E1212122222224242FF8181 +A681:0000000010101E1222224242427F4100 +A682:000000003C424240201008040242423C +A683:00000000182424201010080804242418 +A684:00000000000000003C464248024802503FE004600250024842443C4200000000 +A685:0000000000000000000000003C46424802503FE00450024842443C4200000000 +A686:0000000092929292926E020202020000 +A687:000000000000929292926E0202020000 +A688:000000001C1414142424244649FA8186 +A689:0000000000001C1424244446497A4106 +A68A:00000000FE1010101619111111110502 +A68B:000000000000FE101016191111110502 +A68C:00000000FE10101010101010120C0000 +A68D:000000000000FE1010101010120C0000 +A68E:0000000042424242424242427E39413E +A68F:0000000000004242424242427E39413E +A690:000000007F0808080808080808384030 +A691:0000000000007F080808080808384030 +A692:00000000FA22222222261A0202020000 +A693:000000000000FA222222261A02020000 +A694:00000000304840405864424242420000 +A695:00000000000030484040586444440000 +A696:000000009292929292929292FE39413E +A697:000000000000929292929292FE39413E +A698:00000000000000001E78218421842184218421842184218421841E7800000000 +A699:0000000000000000000000001E782184218421842184218421841E7800000000 +A69A:000000007C929292FE929292927C0000 +A69B:0000000000003E49497F4949493E0000 +A69C:0070501C121C00000000000000000000 +A69D:00202038243800000000000000000000 +A69E:081C2A2A2A1C08000000000000000000 +A69F:004C507C504C00000000000000000000 +A6A0:00000000080C0A080808084848300000 +A6A1:000000004246464A4A52526262420000 +A6A2:0000007C007C00384482828244380000 +A6A3:00000000043448485250202040400000 +A6A4:000000000020000020242262528C0000 +A6A5:00000000404040404048407C00080000 +A6A6:000000000020007C02027C0020000000 +A6A7:000000007C0408081010303048460000 +A6A8:000000007E0204040408080808040000 +A6A9:00000000408C92A2A284780000100000 +A6AA:000000001C2222A47820242024200000 +A6AB:00000000103054901050102020200000 +A6AC:00000000401C22222A2A242020200000 +A6AD:0000000002020202027E2212227E0000 +A6AE:00000000405040780404784050400000 +A6AF:00000000001860004860504840400000 +A6B0:00000000704C424C7040404040400000 +A6B1:00000000404040407C40404040400000 +A6B2:00000000928244442828101010100000 +A6B3:000000004444444444444440407E0000 +A6B4:000000008888888A888E505220200000 +A6B5:00000000828282443810101010100000 +A6B6:00000000484848484A48484A48784800 +A6B7:0000000002002C3464A6202820200000 +A6B8:00000000304080988442320204180000 +A6B9:00000000201008041210101010100000 +A6BA:00000000601218244444241810600000 +A6BB:000000004000007848484E4040400000 +A6BC:000000000010C0300C020C30C0100000 +A6BD:00000002040818240202024244380000 +A6BE:00000000505050507C14141414140000 +A6BF:00000000182442422272020204040000 +A6C0:00000000182442427E02020204040000 +A6C1:00000000182442424202020204040000 +A6C2:00000000405E405E4040404040400000 +A6C3:00000000000202020204545428280000 +A6C4:00000000465A62625A46404040400000 +A6C5:0000000008084A485868484840400000 +A6C6:0000000002020202027A0606067A0000 +A6C7:00000002040810204220100804020000 +A6C8:00000000384492925410101010100000 +A6C9:000000007C04080810102020407C0000 +A6CA:0000000010101010242A22524C800000 +A6CB:000000003E1828480808080808080000 +A6CC:00000000100038441804443800100000 +A6CD:0000000070080404083020F820200000 +A6CE:00000000102828284444444482820000 +A6CF:00000000380082C6AAAA920010100000 +A6D0:000000003E4040403E00080808080000 +A6D1:00000000320804040404080810600000 +A6D2:00000000384402020204042810080000 +A6D3:000000001C2222A47820242424240000 +A6D4:00000000101210103854929292920000 +A6D5:00000000605048444040444850600000 +A6D6:00000000404040407848484848440000 +A6D7:00000000385492929280808080800000 +A6D8:00000000C2A29286864A4A5252220000 +A6D9:0000000018284A0C1828480808080000 +A6DA:000000004040404040404840407E0000 +A6DB:000000007E4242424242424242420000 +A6DC:00000000100018244454542404040000 +A6DD:000000003048888A4838080808100000 +A6DE:000000007E0202027E40404040400000 +A6DF:00000000828244444444282828100000 +A6E0:000000003028242224283060A0200000 +A6E1:00000000006294888A7400007E000000 +A6E2:000000201008102020404040221C0000 +A6E3:00000000407C44040404040404040000 +A6E4:000000046211090A0808101020C00000 +A6E5:000000000E1070504E40404040400000 +A6E6:000000003E0808780402020204080000 +A6E7:00000000380808780402020204080000 +A6E8:000000007050501010101010107C0000 +A6E9:00000000080808780402020204080000 +A6EA:00000000182848083C02020204080000 +A6EB:00000000700804040830202020200000 +A6EC:000000001018141210101010107C0000 +A6ED:00000000700804044830282420200000 +A6EE:000000001E1212121212121212720000 +A6EF:000000003844422204182042423C0000 +A6F0:00102844000000000000000000000000 +A6F1:003E0000000000000000000000000000 +A6F2:00000000200008040402020244380000 +A6F3:00000000040408081010242040400000 +A6F4:00000000222222224455448888880000 +A6F5:00000000000000003E08101020200000 +A6F6:0000000000000000F424484A90900000 +A6F7:00000000101010109254381000100000 +A6F8:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +A6F9:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +A6FA:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61866FB663866FB66FB67FFE0000 +A6FB:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +A6FC:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +A6FD:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +A6FE:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61866FBE638E6FBE6F867FFE0000 +A6FF:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +A700:0000000000000000001C20201C000000 +A701:0000000000000000001C20201C003C00 +A702:000000001C20201C0000000000000000 +A703:000000001C20201C003C000000000000 +A704:00000000380404380000000000000000 +A705:0000000038040438003C000000000000 +A706:00000000000000000038040438000000 +A707:00000000000000000038040438003C00 +A708:00000000501010101010101010100000 +A709:00000000101050101010101010100000 +A70A:00000000101010105010101010100000 +A70B:00000000101010101010105010100000 +A70C:00000000101010101010101010500000 +A70D:00000000141010101010101010100000 +A70E:00000000101014101010101010100000 +A70F:00000000101010101410101010100000 +A710:00000000101010101010101410100000 +A711:00000000101010101010101010140000 +A712:000000001E1010101010101010100000 +A713:0000000010101E101010101010100000 +A714:00000000101010101E10101010100000 +A715:00000000101010101010101E10100000 +A716:000000001010101010101010101E0000 +A717:00000000101050101000000000000000 +A718:00000000001204081000000000000000 +A719:00000000000010007C00000000000000 +A71A:00000000000004047C00000000000000 +A71B:0000000010387C101010000000000000 +A71C:000000001010107C3810000000000000 +A71D:00000000101010100010000000000000 +A71E:00000000100010101010000000000000 +A71F:00000000000000001000101010100000 +A720:007E5050000000000000000000000000 +A721:00000000000000000000000050507E00 +A722:00007078040438000070780404380000 +A723:00000030380404180030380404180000 +A724:00000000387C604040403C0000000000 +A725:000000000000387C604040403C000000 +A726:00000000424242427E4242424242120C +A727:0000004040405C62424242424242120C +A728:00000000000000003F800400040007F8041004200440047004080008010800F0 +A729:00000000000000000800080008003FFC08080810082008380804060400840078 +A72A:000000003C424850304C4040423C0000 +A72B:000000001C22202018202020221C0000 +A72C:00000000040C1424447C040424180000 +A72D:000000000000040C14247C0404042418 +A72E:000000000818284888FE08084B310102 +A72F:00000000000008182848FE080B094932 +A730:0000000000007C404078404040400000 +A731:0000000000003C4240300C02423C0000 +A732:00000000000000000C6012901290210821083FF8210821082108210800000000 +A733:0000000000000000000000001EF0210801081FF82108210823181DE800000000 +A734:00000000000000000CF013081308210821083F0821082108210820F000000000 +A735:0000000000000000000000001EF0210801081F082108210823081CF000000000 +A736:00000000000000000C0812081208210821083F0821082108210820F000000000 +A737:0000000000000000000000001E08210801081F082108210823181CE800000000 +A738:00000000000000000E0812081208211021103F1020A020A02040204000000000 +A739:0000000000000000000000001E08210801081F902190219022601C6000000000 +A73A:00000000000000000E0812081208211021103FF820A020A02040204000000000 +A73B:0000000000000000000000001E08210801081FFC2190219022601C6000000000 +A73C:00000000000000000E0812081208211021103F1020A020A02040204004800300 +A73D:0000000000000000000000001E08210801081F902190219022601C60012000C0 +A73E:000000003C4242021A1A0242423C0000 +A73F:0000000000003C42021A1A02423C0000 +A740:0000000042E448506060504844420000 +A741:00000040F04044485060504844420000 +A742:00000000424448506060544854420000 +A743:00000040404044485060544854420000 +A744:0000000042E448506060544854420000 +A745:00000040F04044485060544854420000 +A746:000000004040404040202020203E0000 +A747:000000301010101008080808083E0000 +A748:0000000040F0404040404040407E0000 +A749:0000001808081C0808080808083E0000 +A74A:000000003C424242FF424242423C0000 +A74B:0000000000003C4242FF4242423C0000 +A74C:0000000275898E888888888888700000 +A74D:00000000000275898E88888888700000 +A74E:00000000000000001EF0210821082108210821082108210821081EF000000000 +A74F:0000000000000000000000001EF02108210821082108210821081EF000000000 +A750:000000007C4242427C404040F0400000 +A751:0000000000005C6242424242625CF040 +A752:000000001E1111117E90909050100000 +A753:00000000000016191111111179969050 +A754:000000004EA929291E08080808080000 +A755:0000000000004AAD292929291D0A0808 +A756:000000003C4242424242425A643D0205 +A757:0000000000003A4642424242463A0702 +A758:00000000000000000F00108010901088108810881090169019200F4000800140 +A759:0000000000000000000000000E901188108810881090109011A00EC001800280 +A75A:000000003C4242020408080404020000 +A75B:0000000000003C4202021C1008040000 +A75C:00000000788404040810224284FE0408 +A75D:000000000000384404081222447E0408 +A75E:00000000494949323222545488880000 +A75F:0000000000004A4A5234646498980000 +A760:00000000424242425A5A66664242020C +A761:00000000000041494949494949370106 +A762:0000003C4040403E0408101C0202423C +A763:00000000003040403C08102038044438 +A764:00005060C07844424244784040400000 +A765:000000506040DC6242424242625C4040 +A766:000000404078444242447840F0400000 +A767:0000004040405C6242424242625CF040 +A768:00000000444444484850506040400000 +A769:00000000000022222424283020200000 +A76A:00000000384404041804040404380000 +A76B:00000000000038440404180404040438 +A76C:0000000C1212127C1010101050200000 +A76D:0000000C1212127C1010101010105020 +A76E:00000000182442424A32020204380000 +A76F:000000000000182442424A3202020438 +A770:00001824424A32020438000000000000 +A771:0000000000000100010001001D002300210021082108211023241DF800400080 +A772:00000000000018000800080008000800080008100810082008483FF000800100 +A773:000000000000000000000000760049004900490849084910492449F800400080 +A774:0000000000000000000000005C0062004200421042104220424843F000800100 +A775:00000000002000200040009017E0190012001000100010001000100000000000 +A776:0000000000000000000000007C00420042007C1050104820444843F000800100 +A777:00000000000000201020104010907FE0110012001000100010000C0000000000 +A778:0000000038444444381C224202FC0000 +A779:00000000FC22424242424242423C0000 +A77A:000040300804023E42424242423C0000 +A77B:000000005C6240404040407840404040 +A77C:0000000000002C322020202038202020 +A77D:000000007E0408101008384444443800 +A77E:000000001C2222221C10080810207E00 +A77F:0000000000003C42423C10080810207E +A780:000000007E0202020202020202020000 +A781:00000000003E0808080808080808080C +A782:000000005C6242424242414040400000 +A783:00000000000058644444424040404040 +A784:000000002E3020202020202020202020 +A785:0000000000002E302020202020202020 +A786:000000007E10204040404040221C0000 +A787:0000000000007E1020404040221C0000 +A788:00000000000000000000000000182442 +A789:00000000000000181800001818000000 +A78A:00000000000000003C00003C00000000 +A78B:00000000080808080808080000000000 +A78C:00000000080808080800000000000000 +A78D:00000000424242427E02020202020000 +A78E:00000018080838483E08080808080600 +A78F:0000000000183C3C1800000000000000 +A790:0000000044646454544C4C4444460202 +A791:00000000000058644444444444460202 +A792:000000001C22222070202022221C0000 +A793:0000000000001C2220702020221C0000 +A794:0000000000003C4240404040423E020C +A795:0000004040405C624242424242430106 +A796:000000001C1212123C525252121C0000 +A797:00000000101010101C325252525C4030 +A798:000000001E1010107C10101010101060 +A799:0000000C1010107C107C101010100000 +A79A:000000003A46422212224242463A0000 +A79B:0000000000003A4642322242463A0000 +A79C:00000000384442221222424244380000 +A79D:00000000000038444232224244380000 +A79E:000000004242422212224242463A0000 +A79F:000000000000424242322242463A0000 +A7A0:000000003D424648506642C2463A0000 +A7A1:0000000000023A477CC438203C42423C +A7A2:000000004244485062645868C4420000 +A7A3:000000404040444850605678C4420000 +A7A4:00000000426263565A6ACA4646420000 +A7A5:0000000000005C634E72C24242420000 +A7A6:000000007C475AE27C48444442420000 +A7A7:0000000000005C6242506040C0400000 +A7A8:000000003C42404C30CC0242423C0000 +A7A9:0000000000001E2026186601211E0000 +A7AA:0000000062A2A2223E22222222220000 +A7AB:000000003C4202021C020202423C0000 +A7AC:000000003C424242424242464A320478 +A7AD:000000001010103050543810101E0000 +A7AE:000000007F49490808080849497F0000 +A7AF:0000000000003C424242425A663C0300 +A7B0:000000004222120A06060A1222420000 +A7B1:000000000808080808080808087F0000 +A7B2:000000001F040404040424544C380400 +A7B3:00000000424224241818182424424200 +A7B4:000000007C4242427C424242427C4040 +A7B5:000000003844444858444242524C4040 +A7B6:00000000225541414141494949360000 +A7B7:00000000000022554141494949360000 +A7B8:0000000042424342464A526242BC0000 +A7B9:0000000000004342464A526246BA0000 +A7BA:0000006028541422223E222222220000 +A7BB:0000180810003C42023E4242463A0000 +A7BC:000000603E48080808080808083E0000 +A7BD:000018081000180808080808083E0000 +A7BE:000000C062A2222222222222221C0000 +A7BF:000018081000424242424242463A0000 +A7C0:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000 +A7C1:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000 +A7C2:0000000000800100417041884108220822702208150815080888087000000000 +A7C3:00000000000000000100020042F0430842082670250825081888187000000000 +A7C4:000000003C42424040404042463A020C +A7C5:000000003C424240300C0242625C4030 +A7C6:000000007E02020408102040427E020C +A7C7:00000000784442427E42424244780000 +A7C8:0000000202023A46427E4242463A0000 +A7C9:000000003C424220107E0442423C0000 +A7CA:0000000000003C42307E0C02423C0000 +A7CB:00007FFE61866DF661EE6DDE6DDE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +A7CC:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +A7CD:00007FFE61866DF661EE6DDE6DDE7FFE7FFE718E6FB66FB66FB6718E7FFE0000 +A7CE:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71866FBE6F8E6FBE71867FFE0000 +A7CF:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +A7D0:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000 +A7D1:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000 +A7D2:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DF66D866DBE63867FFE0000 +A7D3:00007FFE61866DF661EE6DDE6DDE7FFE7FFE638E6DF66DC66DF6638E7FFE0000 +A7D4:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63B66DB66D866DF663F67FFE0000 +A7D5:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DBE6D866DF663867FFE0000 +A7D6:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000 +A7D7:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000 +A7D8:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000 +A7D9:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000 +A7DA:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DB66D866DB663B67FFE0000 +A7DB:00007FFE61866DF661EE6DDE6DDE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +A7DC:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +A7DD:00007FFE61866DF661EE6DDE6DDE7FFE7FFE638E6DB66DB66DB6638E7FFE0000 +A7DE:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DBE6D8E6DBE63867FFE0000 +A7DF:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +A7E0:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61CE6FB663B66FB661CE7FFE0000 +A7E1:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000 +A7E2:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FF663866FBE61867FFE0000 +A7E3:00007FFE61866DF661EE6DDE6DDE7FFE7FFE618E6FF663C66FF6618E7FFE0000 +A7E4:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61B66FB663866FF661F67FFE0000 +A7E5:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FBE63866FF661867FFE0000 +A7E6:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000 +A7E7:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FF663EE6FDE61DE7FFE0000 +A7E8:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000 +A7E9:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61CE6FB663C66FF661CE7FFE0000 +A7EA:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FB663866FB661B67FFE0000 +A7EB:00007FFE61866DF661EE6DDE6DDE7FFE7FFE618E6FB6638E6FB6618E7FFE0000 +A7EC:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000 +A7ED:00007FFE61866DF661EE6DDE6DDE7FFE7FFE618E6FB663B66FB6618E7FFE0000 +A7EE:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FBE638E6FBE61867FFE0000 +A7EF:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FBE638E6FBE61BE7FFE0000 +A7F0:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000 +A7F1:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000 +A7F2:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FF663866FBE6F867FFE0000 +A7F3:00007FFE61866DF661EE6DDE6DDE7FFE7FFE618E6FF663C66FF66F8E7FFE0000 +A7F4:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61B66FB663866FF66FF67FFE0000 +A7F5:00000000040404043C04040404040000 +A7F6:0000000000000404043C040404040000 +A7F7:0000000000000000427E420000000000 +A7F8:00000042FF427E424242000000000000 +A7F9:000000000036494F4837000000000000 +A7FA:000000000000494949494949497F0000 +A7FB:000000007E0202023E02020202020000 +A7FC:000000003E4242423E02020202020000 +A7FD:00000000424242425A5A666642420000 +A7FE:00003E080808080808080808083E0000 +A7FF:000000000000000010411041104128A228A228A2451445148208820800000000 +A800:000000000000FFFF003000500090011002100410081010106008000000000000 +A801:000000000000FFFF040005000680048001000600010000800040000000000000 +A802:0480024001200000000000000000000000000000000000000000000000000000 +A803:000000000000FFFF080011E02210241020E02110201010200FC0000000000000 +A804:0E0001000080FFFF10801080108011001E001000100010000800000000000000 +A805:000000000000FFFF0040034004C00840084004C0034018401840000000000000 +A806:004000A001100000000000000000000000000000000000000000000000000000 +A807:000000000000FFFF226022A023202E2032200220022002200110000000000000 +A808:000000000000FFFF26602AA03320222000200020002000200010000000000000 +A809:000000000000FFFF0840084004400C4014401440084000400020000000000000 +A80A:000000000000FFFF00C003400440034000C003400440034000E0000000000000 +A80B:0030004800300000000000000000000000000000000000000000000000000000 +A80C:000000000000FFFF004000C00140024004400840064001C00020000000000000 +A80D:000000000000FFFF100011801280148019E00290046008000800000000000000 +A80E:000000000000FFFF0820102021E0212011200E20002000200010000000000000 +A80F:000000000000FFFF200026002A28322802480248029002900320000000000000 +A810:000000000000FFFF0700088008400480010002400420082007C0000000000000 +A811:000000000000FFFF080008000B000C800880088009000A000C00000000000000 +A812:000000000000FFFF010001000960119011101010102008400780000000000000 +A813:000000000000FFFF0800080009800A400A400880088009000600000000000000 +A814:000000000000FFFF0040004018C01F4008400840084010402020000000000000 +A815:000000000000FFFF0020026006A02B2012200020002000200010000000000000 +A816:000000000000FFFF100011801280148018800080008000400030000000000000 +A817:000000000000FFFF2010203013500D9001100010001000100008000000000000 +A818:000000000000FFFF006000A00120022005200520052002200010000000000000 +A819:000000000000FFFF206020A02120222024202820302020200010000000000000 +A81A:000000000000FFFF40C041704248445048605050604840400020000000000000 +A81B:000000000000FFFF00400040074008C008C00740004000400020000000000000 +A81C:000000000000FFFF01E0022004201E2025200220002000200010000000000000 +A81D:000000000000FFFF406020A011200A2004200A200A2004200010000000000000 +A81E:000000000000FFFF006000A0012012200C200020002000200010000000000000 +A81F:000000000000FFFF006000A0012012200C2000A0012002200190000000000000 +A820:000000000000FFFF010001000160019001100010002000400780000000000000 +A821:000000000000FFFF00100E301150119002100510009000900008000000000000 +A822:000000000000FFFF206020A021202220242028A0312022200190000000000000 +A823:000000000000000F000200020002000200020002000200020001000000000000 +A824:000C00120002000F000200020002000200020002000200020001000000000000 +A825:0000000000000000000000000000000000000000000000080008001001E00000 +A826:0200010000800000000000000000000000000000000000000000000000000000 +A827:000800040002000F000200020002000200020002000200020001000000000000 +A828:00000000000030484830000000000000 +A829:00000000304848300030484830000000 +A82A:0000000000000000301848244824301800000180024002400180000000000000 +A82B:00000000000000000C60129012900C6000000C60129012900C60000000000000 +A82C:0000000000000000000000000000000000000000000000000000018000400020 +A82D:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE618E7DB661B66FB6618E7FFE0000 +A82E:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61867DBE618E6FBE61867FFE0000 +A82F:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61867DBE618E6FBE61BE7FFE0000 +A830:0000000000000080008000800080008000800080008000800080000000000000 +A831:0000000000000120012001200120012001200120012001200120012000000000 +A832:0000000000000920092009200920092009200920092009200920092000000000 +A833:00000000000000000000000000000000007003801C0000000000000000000000 +A834:000000000000000000000000007003801C000000007003801C00000000000000 +A835:0000000000000000007003801C00007003801C00007003801C00000000000000 +A836:00000000000001C002200220022001C000000000000000000000000000000000 +A837:0000000000000000004000800100020004000E001100110011000E0000000000 +A838:000000000000001000100010001000100010001000100010002001C000000000 +A839:00000000000000700080008000800040004000400040004001800E0000000000 +A83A:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63867DB671867DB663B67FFE0000 +A83B:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE638E7DB6718E7DB6638E7FFE0000 +A83C:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000 +A83D:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE638E7DB671B67DB6638E7FFE0000 +A83E:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63867DBE718E7DBE63867FFE0000 +A83F:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63867DBE718E7DBE63BE7FFE0000 +A840:0000000000007FFF400040007FFE400040007FFE408040804080000000000000 +A841:0000000000004FF84808480848087808480848084FF840007FFE000000000000 +A842:0000000000007FFF40004FF84808480878084808480848084FF8000000000000 +A843:0000000000007F044104410441044104410441044104410441FC000000000000 +A844:0000000000007FFC4104410441044104410441044104410441FC000000000000 +A845:00000000000041FC41044104410441047F0441044104410441FC000000000000 +A846:0000000000004104410441044104410441044104410441047FFC000000000000 +A847:0000000000007FFC4100408040404020401C4000400040004000000000000000 +A848:000000000000407440884100410040C07FFC4000400040007FFE000000000000 +A849:0000000000007FFF41044104410471C449244514430C430C4104000000000000 +A84A:0000000000004060408041004100710049004500430043004100000000000000 +A84B:0000000000007FF0406040804100428044404440444044404380000000000000 +A84C:0000000000007FFC0004000400047F04410441044104410441FC000000000000 +A84D:0000000000007FFC0004000400047E04010401040104010400F8000000000000 +A84E:0000000000007FFC4004400440047F04410441044104410441FC000000000000 +A84F:0000000000007FF0006000807F00428044404440444044404380000000000000 +A850:0000000000007FFF4080408041E042107E0842484188401047E0000000000000 +A851:0000000000007FFF40404080410043E0401040084008401043E0000000000000 +A852:0000000000007FFF40024002400241FE410241027F0241024102000000000000 +A853:0000000000004000443044D047107C10471044D0443040007FFF000000000000 +A854:0000000000007C1F43604080414042204220422041C040007FFE000000000000 +A855:0000000000007FFC410441044104410441044104410441044104000000000000 +A856:0000000000007F04410441044104410441FC4000400040004000000000000000 +A857:0000000000001FF80010002000401FE000100008000800101FE0000000000000 +A858:0000000000000410041004100410041007F00410041004100410000000000000 +A859:0000000000007FFC000400047F044104410441FC400040007FFC000000000000 +A85A:0000000000007FFC40004000400041FC41044104410441047F04000000000000 +A85B:0000000000007FFF003000C023002C0030002800244022802100000000000000 +A85C:00000000000041E242144408440042004100608051004A004400000000000000 +A85D:0000000000007FF8003000C023002C0030F02B08240800087FF0000000000000 +A85E:0000000000007FF0418042004400484048204820482044404380000000000000 +A85F:000000000000400041E0421044087C08440843884008401040E0000000000000 +A860:0000000000007FFF410041004100410041104120414041804100000000000000 +A861:0000000000004008403043C04C00700070004C0043C040304008000000000000 +A862:0000000000007FF0401040107810471040F04000400040007FFF000000000000 +A863:0000000000007FFF41044104410471C449244514430C40007FFF000000000000 +A864:00000000000043CF44314411440942094105608551034A034401000000000000 +A865:0000000000007FFF40004000400040F047107810401040107FF0000000000000 +A866:0000000000004003400440084008401040104010401040107FF0000000000000 +A867:0000000000001FFC08040404020401040084004400240014000C000000000000 +A868:0000000000000804040404040208020802080410041008203FC0000000000000 +A869:0000000000007FFE4000400040007FFC40C04100410040884074000000000000 +A86A:0000000000004104430C430C4514492471C44104410441047FFF000000000000 +A86B:0000000000004100430043004500490071004100410040804060000000000000 +A86C:0000000000004380444044404440444042804100408040607FF0000000000000 +A86D:0000000000007FFE000600180860068001FC00020002000201FC060008000000 +A86E:0000000000007FFC40004000400041FC41044104460458046004000000000000 +A86F:00000000000041E042104408440442004100608051004A004400000000000000 +A870:000000000000403F43514491440942094105608551034A034401000000000000 +A871:0000000000007FFF000600180060008001000100020002000200000000000000 +A872:000000000000080008000800080008000FE00800080008000800000000000000 +A873:00000000000000000040002006101F183F181F18061000200040000000000000 +A874:0000000000007FFF400140014101410141017F01000100017FFF000000000000 +A875:000000007FFF400141017F0100017FFF400141017F0100017FFF000000000000 +A876:0000000000000080008000800080008000800080008000800080000000000000 +A877:0000000000000220022002200220022002200220022002200220000000000000 +A878:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000 +A879:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61CE7DB67BC677F677CE7FFE0000 +A87A:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61867DB67B8677B677B67FFE0000 +A87B:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE618E7DB67B8E77B6778E7FFE0000 +A87C:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000 +A87D:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE618E7DB67BB677B6778E7FFE0000 +A87E:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61867DBE7B8E77BE77867FFE0000 +A87F:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +A880:000000000000000000000004000A000A00040000000000000000000000000000 +A881:00000000000000000004000A000A000400000004000A000A0004000000000000 +A882:000000000000000036004900490002007C008000808081007E00000000000000 +A883:000000000000000036004900490002007C008100808081407E00000000000000 +A884:000000000000000063009480A400820061008100810082007C00000000000000 +A885:000000000000000063009480A700820061008100810082007C00000000000000 +A886:0000000000000000CF00308029004C0092008200820084007800000000000000 +A887:0000000000000000CE00310028804C8092808280828084807880000000000000 +A888:00000000000000004C8092809280628004807880808081007E00000000000000 +A889:00000000000000004C0092009200620004007900808081407E00000000000000 +A88A:000000000000000077008880888080808080BE80848088804700000000000000 +A88B:000000000000000077008880888080808080BE80848088804700060021001E00 +A88C:00000000000000003F00408080009300948094808F0044003800000000000000 +A88D:00000000000000003F0040808080A480AA80AA809C8048803080000000000000 +A88E:00000000000000003F0040808000A900AA80AA80970042003C00000000000000 +A88F:00000000000000003F0040809E00A10091008600990041003E00000000000000 +A890:00000000000000003F0040809C80A280928084809A8042803C80000000000000 +A891:00000000000000003F0040809000A9008A80B2808F8049803180000000000000 +A892:0000000000000000270058805080288008800880088008800880000000000000 +A893:000000000000000084404AA027C02440484049209220922061C0000000000000 +A894:0000000000000000670088808880888088808880888088807300000000000000 +A895:000000000000000062009500A500820065008500888088807300000000000000 +A896:00000000000000007F0080808080B8804480B880808080804300000000000000 +A897:00000000000000006100928050801080F8804100810082007C00000000000000 +A898:000000000000000063009480A280808070808100810082007C00000000000000 +A899:00000000000000007700888088808080A080D080908094806300000000000000 +A89A:0000000000000000770088809480A280A2809480888094804900000000000000 +A89B:00000000000000003C0042008900950095008F80910092004C00000000000000 +A89C:0000000000000000FF8040003800060071008880908081007E00000000000000 +A89D:00000000000000003E0041008080808080808080808041003E00000000000000 +A89E:00000000000000007F8001002200470088808080808041003E00000000000000 +A89F:0000000000000000020085004480258052804080408021001E00000000000000 +A8A0:00000000000000003E0041008C8092809280BA80828044803900000000000000 +A8A1:00000000000000003E0041008080808080808080808040803080000000000000 +A8A2:0000000000000000330048801080210042003400080014000800000000000000 +A8A3:0000000000000000780084008400480010006200810083007C80000000000000 +A8A4:000000000000000063009480A080808060808080808081007E00000000000000 +A8A5:00000000000000003D004280830082008200A200520052002200000000000000 +A8A6:00000000000000004300A0801080110021002200420044003800000000000000 +A8A7:0000000000000000180025804380420084009480888041003E00000000000000 +A8A8:0000000000000000B600B900610002007C008100808080807F00000000000000 +A8A9:00000000000000004D8092409240904090409040904090406180000000000000 +A8AA:00000000000000006C80928092804480188060808080B8804700000000000000 +A8AB:00000000000000004300A0805080110021002200420044003800000000000000 +A8AC:0000000000000000F780140012002200210041004080F880C700000000000000 +A8AD:0000000000000000770088808880808080808080808080806300000000000000 +A8AE:0000000000000000E30080804100220014000800140014000800000000000000 +A8AF:00000000000000003900448084809480A8809480848084806300000000000000 +A8B0:000000000000000061009280D280A10082808280848044803900000000000000 +A8B1:00000000000000004880B5009900910088808880848084808300000000000000 +A8B2:0000000000000000FF00100020007100A8809080808041003E00000000000000 +A8B3:00000000000000006B0094809480808080808080808081006600000000000000 +A8B4:00000000000000000012001200120012000E0002000200020002000000000000 +A8B5:0000000000000000002E0012001400040008000800100010000C000000000000 +A8B6:003C004200240000000000000000000000000000000000000000000000000000 +A8B7:00700088000800080008000800080008000800080008000A0004000000000000 +A8B8:00000000000000000044002A003A003400100028002800280010000000000000 +A8B9:000000000000000800500034003A003400100028002800280010000000000000 +A8BA:0000000000000000001C002A00240020001C000200020022001C000000000000 +A8BB:0000000000000000001C002A00240020001C000200020022001C0040003C0002 +A8BC:000000000000000000DC0122012201220126012A012A012A00A4000000000000 +A8BD:000000000000000000DC0122012201220126012A012A012A00A4020001F00008 +A8BE:0000000000000000000C001200120016000A0002000200040008000000000000 +A8BF:0000000000000000003E0022001400040008000800120012000C000000000000 +A8C0:0000000000000000001800240026001A00020002000A0016000C000000000000 +A8C1:0000000000000000003E002200120004003800080008000A0004000000000000 +A8C2:0000000000000000007E0046002A000A0072000A000A000A0004000000000000 +A8C3:000000000000000000E4009A001A001C001800180038005A0024000000000000 +A8C4:0000000000000000000000000000000000000000000000000000002000100008 +A8C5:00000004000A000A00040011000E000000000000000000000000000000000000 +A8C6:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000 +A8C7:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000 +A8C8:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +A8C9:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +A8CA:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71866FB66F866FB671B67FFE0000 +A8CB:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +A8CC:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +A8CD:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE718E6FB66FB66FB6718E7FFE0000 +A8CE:0000000000000000008000800080008000800080008000800080000000000000 +A8CF:0000000000000000024002400240024002400240024002400240000000000000 +A8D0:000000000000000003C0042008100810081008100810042003C0000000000000 +A8D1:000000000000000001C00220022001C000400080008000800060000000000000 +A8D2:000000000000000007C008200020022001C00100008000400030000000000000 +A8D3:0000000000000000038004400040018000400040084008400780000000000000 +A8D4:00000000000000000140022002200140008001400220022001C0000000000000 +A8D5:0000000000000000062008200840087007880088010801080110000000000000 +A8D6:000000000000000003C004200400030002000400040002400180000000000000 +A8D7:0000000000000000024004A004A0046004200220024001400080000000000000 +A8D8:0000000000000000010002800240044004200620052005200240000000000000 +A8D9:00000000000000000800040004000440088009400820042003C0000000000000 +A8DA:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63866DB66D866DB663B67FFE0000 +A8DB:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +A8DC:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +A8DD:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE638E6DB66DB66DB6638E7FFE0000 +A8DE:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63866DBE6D8E6DBE63867FFE0000 +A8DF:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +A8E0:0000018002400240018000000000000000000000000000000000000000000000 +A8E1:0180024001800300008000400000000000000000000000000000000000000000 +A8E2:0180024000800100008000400000000000000000000000000000000000000000 +A8E3:0180004001800040018000400020000000000000000000000000000000000000 +A8E4:0000044002800100028001000000000000000000000000000000000000000000 +A8E5:01000100012000E0002000100010000800080000000000000000000000000000 +A8E6:00C0010000C0010000E000200010000000000000000000000000000000000000 +A8E7:044004A00460022001C000000000000000000000000000000000000000000000 +A8E8:004000800100012000C000000000000000000000000000000000000000000000 +A8E9:00C0012000C00040002000200000000000000000000000000000000000000000 +A8EA:1CE002400C4023C01C4000000000000000000000000000000000000000000000 +A8EB:07E0004004800240018000000000000000000000000000000000000000000000 +A8EC:0FF00080038004E0039000900000000000000000000000000000000000000000 +A8ED:07E0004003C00440004000400040000000000000000000000000000000000000 +A8EE:0FC0048004800380008000800000000000000000000000000000000000000000 +A8EF:07E0008001800100008000400000000000000000000000000000000000000000 +A8F0:030004000FE004C0054004C00440000000000000000000000000000000000000 +A8F1:007000800040012000C000000000000000000000000000000000000000000000 +A8F2:000000000000000008900410031000E000000000000000000000000000000000 +A8F3:000000000000000008900410031000E0000000E0001000080008000800000000 +A8F4:00000000000000000450031000E000000450031000E000000060001000080008 +A8F5:000000000000000008900410031000E0000000E0001000100060001000080000 +A8F6:000000000000000008900410031000E0000000E0001000E0001000E000400020 +A8F7:000000000000000008900410031000E0000000E0010000800240018000000000 +A8F8:00000000000000000718082408240714080C08040808041003E0000000000000 +A8F9:00000000000000000038004400040004070408040808041003E0000000000000 +A8FA:0000000002200140008000000000000000000000000000000000000000000000 +A8FB:000000000000FFFF000000000000000000000000000000000000000000000000 +A8FC:0000000000000000000000000078008C60E618E60C06060C03F801F000000000 +A8FD:0000253811640E6400601FE0006000601FE01860186008600060406030600F80 +A8FE:13E0081007F8FFFF0C300C300C300C300C600400020001800060001000180018 +A8FF:13E0081007F80000000000000000000000000000000000000000000000000000 +A900:00000000000000001FF820042004200420042004200420041FF8000000000000 +A901:00000000000000003FFC000400041FFC20042000203C20441FF8000000000000 +A902:0000000000000000101010100820082004400440028002800100000000000000 +A903:00000000000000000FF8081008200040008001180228044807F0000000000000 +A904:0000000000000000107011901610181010101010001000100060000000000000 +A905:00000000000000001FF810001000100010001000100010001C00000000000000 +A906:0000000000000000101810681188160818081038104810481030000000000000 +A907:0000000000000000003800081008100810081008100810080FF0000000000000 +A908:0000000000000000100010001000100010001000100810081FF8000000000000 +A909:00000000000000001C0010001000100410041004100410040FF8000000000000 +A90A:00000000000000003C780488050806080C081408240824083808000000000000 +A90B:00000000000000001FF82004200420043FFC0004000420041FF8000000000000 +A90C:000000000000000011F01210141018101FF01010101010101010000000000000 +A90D:00000000000000001FF820042004200020002000200420041FF8000000000000 +A90E:00000000000000000FF0100810080B0804880B08100820083E08000000000000 +A90F:00000000000000001FF800080008038802480228022802180C08000000000000 +A910:0000000000000000106011901610182010401020101010701000000000000000 +A911:00000000000000001FF820040004000420043FF8200020041FF8000000000000 +A912:00000000000000000C000B0008C0083009800A400CC009400880000000000000 +A913:0000000000000000000800080008103810081008100810080FF0000000000000 +A914:00000000000000000FF010080F0000F0180810081FF010000F80000000000000 +A915:00000000000000001FF820042018206021802600380420041FF8000000000000 +A916:00000000000000000FC010201020100013E01420182010201010000000000000 +A917:0000000000000000200820082008210822882448282830181FF0000000000000 +A918:00000000000000000FF8001000200040008001180228044807F0000000000000 +A919:000000000000000008F009100A100C1008100870089008900860000000000000 +A91A:000000000000000008F009100A100C1008100810081008100810001000100060 +A91B:000000000000000020F021082108210821082108210821081E08000000000000 +A91C:000000000000000020F021082108210821081E08000820081FF0000000000000 +A91D:00000000000000001000100010001C0810081008100810080FF0000000000000 +A91E:00000000000000001FF820042000200020041FFC000420041FF8000000000000 +A91F:00000000000000000E1012101410183010501F90001000100060000000000000 +A920:0000000000000000600C583446C4410400040004400440043FF8000000000000 +A921:00000000000000000FF010081008000818081608118810681018000000000000 +A922:00000000000000001FF82004200420001E002000200420041FF8000000000000 +A923:000000000000000010081008100810081018102810C813081C08000000000000 +A924:00000000000000001FF8200C20340044018402040C0430041FF8000000000000 +A925:00000000000000001FF82004300C2C3423C42004200420041FF8000000000000 +A926:0000010000000000000000000000000000000000000000000000000000000000 +A927:0C00030000C00000000000000000000000000000000000000000000000000000 +A928:010006C018300000000000000000000000000000000000000000000000000000 +A929:0820082007C00000000000000000000000000000000000000000000000000000 +A92A:0920082007C00000000000000000000000000000000000000000000000000000 +A92B:0000000000000000000000000000000000000000000000000000000001000000 +A92C:0000000000000000000000000000000000000000000000000000080010200FC0 +A92D:0000000000000000000000000000000000000000000000000000090010200FC0 +A92E:000000000000000000000000000003C00C301008000000000000000000000000 +A92F:0000000000000000008000800080008000800080008000800080000000000000 +A930:0000000000000000010002800240052004800800080010001000000000000000 +A931:0000000000000000010002800240042004000800080010001000000000000000 +A932:000000000000000004440A880A881110111022A022A044404440000000000000 +A933:0000000000000000010002800240062005400880080010001000000000000000 +A934:00000000000000000180024002200610054008A0080010001000000000000000 +A935:0000000000000000030C05140514092409241144114421842184000000000000 +A936:0000000000000000001000100020002000400840048002800100000000000000 +A937:0000000000000000001000200040008001000200040008001000000000000000 +A938:000000000000000004400440028002800100210812900AA00440000000000000 +A939:0000000000000000008001400120029002480620051008A00840000000000000 +A93A:000000000000000004200A500948148412802100200040004000000000000000 +A93B:000000000000000004440AA80AA8111010002000200040004000000000000000 +A93C:00000000000000000210052804E4084008401080108021002100000000000000 +A93D:00000000000000000210052804E4084008401080188025002300000000000000 +A93E:0000000000000000018802880290049004A008A008C010C01080000000000000 +A93F:00000000000000004004400420082008101011100AA00AA00440000000000000 +A940:00000000000000000210052004E0084008401080108021002100000000000000 +A941:0000000000000000004000A0009001080100220012000C000400000000000000 +A942:00000000000000000108021002100420042008400C4012801180000000000000 +A943:0000000000000080014002200220041004900948094812241224000000000000 +A944:00000000000000000D4415441484148815481548262826282410000000000000 +A945:000000000000000004440AA80AA811101100220032004C004400000000000000 +A946:0000000000000000011002A002A0044006000A00090011001000000000000000 +A947:0000000000000000000000000000000000008000000000000000000000000000 +A948:0000000000000000000000000000000000000000000000000000800000000000 +A949:0000000000000000000000000000800080008000800000000000000000000000 +A94A:0008001400220000000000000000000000000000000000000000000000000000 +A94B:0000000000000000000000000000800080008000800000000000000080000000 +A94C:0000000000000000000000000000000000000000000000000000800080006000 +A94D:0000000000000000000000000000000000000000000000000000A000A000A000 +A94E:0000000000000000000000000000000000000000000000000000000A000A000A +A94F:0002000400000000000000000000000000000000000000000000000000000000 +A950:0012002400000000000000000000000000000000000000000000000000000000 +A951:0022001400080000000000000000000000000000000000000000000000000000 +A952:0000000000000000000000000000000000000000000000000000000200000002 +A953:0004000A00040000000000000000000000000000000000000000000000000000 +A954:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61B66FB661867DF661F67FFE0000 +A955:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FBE61867DF661867FFE0000 +A956:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000 +A957:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FF661EE7DDE61DE7FFE0000 +A958:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000 +A959:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FB661C67DF661CE7FFE0000 +A95A:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FB661867DB661B67FFE0000 +A95B:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E6FB6618E7DB6618E7FFE0000 +A95C:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000 +A95D:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E6FB661B67DB6618E7FFE0000 +A95E:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FBE618E7DBE61867FFE0000 +A95F:0000000000000000008009300940058012700E4801A002900C90010000000000 +A960:00003E7C2044204420443E7C0000000000000000000000000000000000000000 +A961:00003E442044207C20443E7C0000000000000000000000000000000000000000 +A962:00003E102010201020283E440000000000000000000000000000000000000000 +A963:00003E7C2008201020283E440000000000000000000000000000000000000000 +A964:00007CF804087C0840087C080000000000000000000000000000000000000000 +A965:00003DDC04443C4420443C440000000000000000000000000000000000000000 +A966:00003E7C02403E4020403E7C0000000000000000000000000000000000000000 +A967:00003DDC05103D1021103DDC0000000000000000000000000000000000000000 +A968:00003E7C02443E4420443E7C0000000000000000000000000000000000000000 +A969:00003E4402443E7C20443E7C0000000000000000000000000000000000000000 +A96A:00003D5405543DDC21543DDC0000000000000000000000000000000000000000 +A96B:00443E7C02443E7C20383E440038000000000000000000000000000000000000 +A96C:00003E1002103E1020283E440000000000000000000000000000000000000000 +A96D:00003E7C02083E1020283E440000000000000000000000000000000000000000 +A96E:00003E7C02043E7C20043E040000000000000000000000000000000000000000 +A96F:00003E7C2204220422043E040000000000000000000000000000000000000000 +A970:00003E7C2240224022403E7C0000000000000000000000000000000000000000 +A971:00003E102210221022283E440000000000000000000000000000000000000000 +A972:0000293C2920393C2AA03C7C0000000000000000000000000000000000000000 +A973:0000227C22043E7C22043E040000000000000000000000000000000000000000 +A974:0000223022FC3E3022483E300000000000000000000000000000000000000000 +A975:000008920892089E1552223E0000000000000000000000000000000000000000 +A976:00000E3E1102113E11200E3E0000000000000000000000000000000000000000 +A977:00001C3022FC223022481C300000000000000000000000000000000000000000 +A978:00003FEC047F088C1552222C0000000000000000000000000000000000000000 +A979:00003E7C20403E7C20403E7C0000000000000000000000000000000000000000 +A97A:00003E3014FC143014483E300000000000000000000000000000000000000000 +A97B:00000C103F100C1012280C440000000000000000000000000000000000000000 +A97C:00003EFC00000C3012480C300000000000000000000000000000000000000000 +A97D:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E7DB67BB677B6778E7FFE0000 +A97E:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61867DBE7B8E77BE77867FFE0000 +A97F:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000 +A980:11880A5007E00000000000000000000000000000000000000000000000000000 +A981:0240038000000000000000000000000000000000000000000000000000000000 +A982:0040008001000200000000000000000000000000000000000000000000000000 +A983:0000000000000000000600090009000500020006000100010001000100010002 +A984:0000000000000000300040008000B03C88A4B0FE882489A47264000000000000 +A985:000000000000000038D845244524440444044404450424842784018002600010 +A986:0000000000000000228855545554505450545054545452545E74060009800040 +A987:0000000000000000228855545554505450545054545458545B74040002000C00 +A988:000000000000000038D845244524440444044404450424842788003000460078 +A989:000000000000000030C049204920492049204920492049204E2004000F000080 +A98A:000000000000000031B04A484A4848084A08491C4F2800480788080809880670 +A98B:000000000000000031B04A484A4848084A0C491A4F2A004C078A080A098C0670 +A98C:000000000000000000000000000007800A401180100010700F88000000000000 +A98D:000003000400038000400180000007800A401180100010700F88000000000000 +A98E:000000000000000039C0492090909090909090904F2000400380043809C00E00 +A98F:00000000000000002388545454545454545454545E5455545574020000000000 +A990:00000000000000002388545454545454545454545E5455545574060009800040 +A991:00000000000000002384544854505450545054505E5055505560020000000000 +A992:000000000000000031104AA84AA84AA84AA82AA80AA80AA80EE8000000000000 +A993:0000000000000000231855145514551455145514555455545CA0000000000000 +A994:000000000000000038D8452445244404440444044484244427C4000000000000 +A995:0000000000000000387044484448444844484E485548554848C8000000000000 +A996:000000000000000010002200452049524A55529654A5552A2210000000000000 +A997:000000000000000038784484451C45E045C04530450824882780000000000000 +A998:000000000000000038784484451C45E045C04530450824882780018002600010 +A999:000800140014000E31454AA54AA648244A2449244F2400440784080808C80730 +A99A:0000000000008000457EAADAAADAA0DAA8DAA4DABCDA00000000000000000000 +A99B:000000000000000031B04A484A484808480848084B084C884708084008400780 +A99C:000000000000000031B04A484A4848084808480849884A484F88000000000000 +A99D:000000000000000038F048909050905090509050925092504D90000000000000 +A99E:0000000000000000398048409040904090409040924092404D80000000000000 +A99F:0000000000000000224855B455B455B455B435B415B415B41DB4000000000000 +A9A0:000000000000000027CC543454345434533450B450B450B45F34000000000000 +A9A1:000000000000000038F048909050905090509250955091504F90010001400080 +A9A2:000000000000000039E04A109210921092109210939096504990000000000000 +A9A3:000000000000000038F048909050905090509050925092504D90000000000000 +A9A4:000000000000000039E04A109210921092109F10929092905110000000000000 +A9A5:0000000000000000387044484448444844484448444844482388000000000000 +A9A6:0000000000000000386048909090905090209030924892484D90000000000000 +A9A7:0000000000000000629C95549554905490549054945492545F64000000000000 +A9A8:00000000000000003C782448244804404F4074E00258014400C0000000000000 +A9A9:00000000000000003F18482448244824472448244824482427C4000000000000 +A9AA:000000000000000039CE494A494A494A494A494A494A494A2E32000000000000 +A9AB:00000000000000003C78228412840284048408841C8402840184000000000000 +A9AC:000C0012000E000264929B6A9B6A9B6A5B6A1B6A1B6A1B6A1B6E000000000000 +A9AD:000000000000000039DC4A549254925492549254925492544E64000000000000 +A9AE:00000000000000001CF024884848484848484848484848482788000000000000 +A9AF:0000000000000000233054C854C854C855C836C817FC14CA1CC8000000000000 +A9B0:00000000000000003878484890489148924893FC904A90484F88000000000000 +A9B1:00000000000000003C3C44248424842484248E249524952448C4000000000000 +A9B2:000000000000000039FC49649164916491649164916491644E64000000000000 +A9B3:0000024001802424181800000000000000000000000000000000000000000000 +A9B4:0000000000000000000600090009000100020002000400050007000000000000 +A9B5:0000000000000000000000040004000200020001000900060000000000000000 +A9B6:01E0021004100410047003900000000000000000000000000000000000000000 +A9B7:01E00210053004D0047003900000000000000000000000000000000000000000 +A9B8:000000000000000000000000000000050005000500050005000500050019003E +A9B9:000000000000000000000004000F00140014000E00050005000500050019003E +A9BA:00000000000000004800B400B400B400B400B400B400B4003400040004000300 +A9BB:1800200010000800300000004800B400B400B400B400B4003400040004000300 +A9BC:0780084008200610000000000000000000000000000000000000000000000000 +A9BD:0000000000000000000000000000000100060002000100010001003200340058 +A9BE:000E000A000A000A000A000A000A000A000A002A002A00CA030A040A04CA0331 +A9BF:180020004000800080008000800080008000800080048008401C2002180207FC +A9C0:000E000A000A000A000A000A000A000A000A000A000A030A048A040A04CA0331 +A9C1:00000006060A04080408020861E04004206A1F8400100612042203C2000A000C +A9C2:00003000500043C044204860080021F856042002078610401020102050606000 +A9C3:2800D586C586C586D586F58601861D8621862F86A5E6999F818781C741D73EA9 +A9C4:6800D586C586C586D586F58681869D86A186AF86A5E6999F818781C741D73EA9 +A9C5:30004006E806D586C586F58681869D86A186AF86A5E6999F818781C741D73EA9 +A9C6:0000000000000000000001C0022002200220022001C000000000000000000000 +A9C7:0000000000000000000000000240038000000000024003800000000000000000 +A9C8:00000000000000001800040002000100008000800040034000C0000000000000 +A9C9:0000000000000000330008800440022001100110008806E80198000000000000 +A9CA:00000000000000000600010001000100010001000100010001000100010000C0 +A9CB:0000000000000000198004400440044004400440044004400440044004400330 +A9CC:0000001000200140010000C006000100010001000100010001000100010000C0 +A9CD:0000018000400040004000400040004000400040003001800040014002000400 +A9CE:00007FFE61CE6DB661C66DF66DCE7FFE7FFE71866FBE6F8E6FBE71867FFE0000 +A9CF:0000000000000000000000000820072002C00200010001000100000000000000 +A9D0:0000000000000000000001C0022002200220022001C000000000000000000000 +A9D1:000000000000000031104AA84AA84AA84AA82AA80AA80AA80EE8000000000000 +A9D2:000000000000000031B04A484A4848084A08491C4F2800480788080809880670 +A9D3:00000000000000002367549554955015541552255E4500850F05100511850E79 +A9D4:000000000000000000C00100020002C0022002C00220022001C0000000000000 +A9D5:00000000000000000380044008200B2008A00B2008A008A00720002000200018 +A9D6:000000000000000000000000000007800A401180100010700F88000000000000 +A9D7:000000000000000039DC4A549254925492549254925492544E64000000000000 +A9D8:0000000000000000386048909090905090209030924892484D90000000000000 +A9D9:000000000000000039CE494A494A494A494A494A494A494A2E32000000000000 +A9DA:00007FFE61CE6DB661C66DF66DCE7FFE7FFE63866DB66D866DB663B67FFE0000 +A9DB:00007FFE61CE6DB661C66DF66DCE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +A9DC:00007FFE61CE6DB661C66DF66DCE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +A9DD:00007FFE61CE6DB661C66DF66DCE7FFE7FFE638E6DB66DB66DB6638E7FFE0000 +A9DE:000000000000000000800140022002200220022001C000000000000000000000 +A9DF:00000000000000001C7022882288228822882288228822882388000000000000 +A9E0:0000000000000000000000F801440082000200F2008C00780000000000000000 +A9E1:00000000000000000000018C024203A1002100210252018C0000000000000000 +A9E2:00000000000000000000018C024A0029002500230252018C0000000000000000 +A9E3:00000000000000000000018C02D20120002001FC0252018C0000000000000000 +A9E4:0000000000000000000000C60108021002100216012900C60000000000000000 +A9E5:0070008800800070008800000000000000000000000000000000000000000000 +A9E6:0000000000900120024004800000000000000000000000000000000000000000 +A9E7:00000000000000000000018C02520421042102210122062C0020002000200038 +A9E8:0000000000180020002001AC0232042104210421027201AC00200020002000E0 +A9E9:00000000000000000000018C02520421042D04210242000C0000000000000000 +A9EA:00000000000000000000018C02120421042D04210242018C0000000000000000 +A9EB:00000000000000000000018C02520421042D04210212018C0000000000000000 +A9EC:00000000000000000000000001020201022502510251018E0000000000000000 +A9ED:00000000000000000000018C0252042105AD04210242018C0000000000000000 +A9EE:00000000000000000000018C0252042105AD04210252018C0000000000000000 +A9EF:0000000000000000000000380244028201CA00A2004400000000000000000000 +A9F0:000003C00420081008100810081008100810081008100810042003C000000000 +A9F1:000003C004200E1009100620000003C004200E10091006200040007000000000 +A9F2:0000081008100810042003D0001003D00420080008000800042003C000000000 +A9F3:000003E0041000100010061005E0040005E0061000100010041003E000000000 +A9F4:000007C0082008000800086007A0002007A0086008000800082007C000000000 +A9F5:000003C0042008100800080008000BC00C200810081008100420024000000000 +A9F6:0000000002400420081008100810043003D00010001000100810042003C00000 +A9F7:000000000780084010201C2012200C2000200020002000200020003800000000 +A9F8:000003C00420080008000800040003C00420081008100810042003C000000000 +A9F9:000000000000000000000070008841044104410422881C700000000000000000 +A9FA:00000000000000000000018C0242042105A104210212018C0000000000000000 +A9FB:00000000000000000000018C02520421042D04210242018C0000000000000000 +A9FC:00000000000000000000018C02520421042D04210252018C0000000000000000 +A9FD:0000000000000000000000480084010201320102008400780000000000000000 +A9FE:0000000000180020002001AC02320421042D04210252018C0000000000000000 +A9FF:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +AA00:00000000000000000E0611C9222929323480188013C004A00300000000000000 +AA01:00000000000000000CC013201020282050400780082008500790000000000000 +AA02:0000000000000000038004400820082004400180020002400180000000000000 +AA03:00380044004400480E20111011080928025804300420024001E0000000000000 +AA04:00000000000000000E70118818081408083000C00110011000E0000000000000 +AA05:00000000000000000380044008201C200AC0042000F0012800C0000000000000 +AA06:00000000000000000EE011101110102008000800080008001000000000000000 +AA07:00000000000000001B0C24922452206411C01280148015002200000000000000 +AA08:000000000000000007700888108810101000100011000A800700000000000000 +AA09:0000000000000000186C24922492148404800880090006000200000000000000 +AA0A:00000000000000001C2822502230161001100120014003800400000000000000 +AA0B:00000000000000001C2822502230161001100120014003800430044804900300 +AA0C:00000000000000001C3022482248114001800F00120012000C00000000000000 +AA0D:00000000000000001886254925491544064C1C94248828901060000000000000 +AA0E:000000000000000038D8452445242C8802800280028007000800000000000000 +AA0F:0000000000000000031804A404A404A8052013902B5027301CE0000000000000 +AA10:00000000000000001986264940314022406040A02920152028C0000000000000 +AA11:00000000000000001986264940314022406040A02920152028C4004A00480030 +AA12:00000000000000001986264940314022406040A02920152029C4024A01480230 +AA13:0000000000000000077008880888101010001600190009000600000000000000 +AA14:00000000000000000E0C111211120928025804300420024001C0000000000000 +AA15:00000000000000001C7022882288165001400140014003800400000000000000 +AA16:00000000000000000C70128812880A5002400440048003000100000000000000 +AA17:00000000000000001C0C22122212110801080F08129012600C40000000000000 +AA18:00000000000000001C0C22122212110801080F08129012600C48009400900060 +AA19:00000000000000001C0C22122212110801080F08129012600C0008C009200600 +AA1A:0000000000000000077008880888040004002400540048003000000000000000 +AA1B:00000000000000001C1822242224162801200120014003800400000000000000 +AA1C:00000000000000000E0C1112111209080A284A58AA30911060E0000000000000 +AA1D:0000000000000000183024482448085010401040104008400780000000000000 +AA1E:0000000000000000306C48924892108020802080208010800F00000000000000 +AA1F:0000000000000000306C4892489228840A80110012800C800400000000000000 +AA20:0000000000000000183824442444144805400880094006400248009400900060 +AA21:0000000000000000183824442444144805400880095006200250005000200000 +AA22:0000000000000000306C48924892248404400240024002800700000000000000 +AA23:000000000000000000F001080108009000800680098009000600000000000000 +AA24:0000000000000000073808C4080410041008101012000D000600000000000000 +AA25:00000000000000001838244424441448044008D0092006500250002000000000 +AA26:00000000000000000C1C12222A22522402200440048003000100000000000000 +AA27:0000000000000000073808C408040408020012002A0024001800000000000000 +AA28:00000000000000000770088808980428021412002A0024001800000000000000 +AA29:0038004400480020001800040004000000000000000000000000000000000000 +AA2A:001C00220041004D003200040000000000000000000000000000000000000000 +AA2B:001C002200490041004D00320004000000000000000000000000000000000000 +AA2C:00380045008E009A006400080000000000000000000000000000000000000000 +AA2D:00000000000000000000000000000000000000000000000000000002001C0020 +AA2E:00000011000E0000000000000000000000000000000000000000000000000000 +AA2F:0000000000000000000000006000900090008000A0005000A000000000000000 +AA30:0000000000000000000000006000900090008000A00050002000080070008000 +AA31:0002001C00200024001800100020000000000000000000000000000000000000 +AA32:0000000000000000000000000000000000000000000000000000000C00040008 +AA33:0000000000000000000000000000000600090009000800040032000A0012003C +AA34:5800A8008800100020004000800080008000800080008000800082004A003400 +AA35:000000000000000000000000000000000000000000000000000000040008000C +AA36:0000000000000000000000000000000000000008000500020005000500050002 +AA37:00007FFE61866DB661866DB66DB67FFE7FFE63867DF671EE7DDE63DE7FFE0000 +AA38:00007FFE61866DB661866DB66DB67FFE7FFE63CE7DB671CE7DB663CE7FFE0000 +AA39:00007FFE61866DB661866DB66DB67FFE7FFE63CE7DB671C67DF663CE7FFE0000 +AA3A:00007FFE61866DB661866DB66DB67FFE7FFE63867DB671867DB663B67FFE0000 +AA3B:00007FFE61866DB661866DB66DB67FFE7FFE638E7DB6718E7DB6638E7FFE0000 +AA3C:00007FFE61866DB661866DB66DB67FFE7FFE63C67DBE71BE7DBE63C67FFE0000 +AA3D:00007FFE61866DB661866DB66DB67FFE7FFE638E7DB671B67DB6638E7FFE0000 +AA3E:00007FFE61866DB661866DB66DB67FFE7FFE63867DBE718E7DBE63867FFE0000 +AA3F:00007FFE61866DB661866DB66DB67FFE7FFE63867DBE718E7DBE63BE7FFE0000 +AA40:00000000000000000EE011101110101008100820082008401080000000000000 +AA41:00000000000000000EE01110111020102010202020202C401C80000000000000 +AA42:00000000000000001C2022502250163001180124014403880410000000000000 +AA43:0004000800300000000000000000000000000000000000000000000000000000 +AA44:00000000000000001C3822442244114401840F08120812100C20000000000000 +AA45:0000000000000000077008880888100810081610191009200640000000000000 +AA46:0000000000000000381C44224422221202121E14252424C81890000000000000 +AA47:00000000000000000770088808880408020812102A1024201840000000000000 +AA48:0000000000000000306C48924892248204420244024402880710000000000000 +AA49:000000000000000000F801040104008400840688098809100620000000000000 +AA4A:00000000000000000E701188100820082008201024102A201C40000000000000 +AA4B:00000000000000001C7812842A84524402440448048803100120000000000000 +AA4C:0000002000000000000000000000000000000000000000000000000000000000 +AA4D:0000000000000000000000000006000900050001000200040004000000000000 +AA4E:00007FFE61866DB661866DB66DB67FFE7FFE6D866DBE618E7DBE7D867FFE0000 +AA4F:00007FFE61866DB661866DB66DB67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000 +AA50:000000000000000003C0042008100810081008100810042003C0000000000000 +AA51:00000000000000000FE0101010103C200CC00100010001000100000000000000 +AA52:000203840478080013B824442444280429042A88270810100FE0000000000000 +AA53:00000000000000000E7011881008200820102024244A2A4A1C30000000000000 +AA54:0000000000000000000406080908109020507C20220022001C00000000000000 +AA55:00000000000000000F0010801080090002800040034004800340000000000000 +AA56:000000000000000000F001080108009000800680098009000600000000000000 +AA57:000000000000000000F801040104008400840688098809100660008800940060 +AA58:00000000000000001C3822442244114401840F08120812100C60008800940060 +AA59:0000000000000000183824442444084410841088108809100660008800940060 +AA5A:00007FFE61866DB661866DB66DB67FFE7FFE61866FB661867DB661B67FFE0000 +AA5B:00007FFE61866DB661866DB66DB67FFE7FFE618E6FB6618E7DB6618E7FFE0000 +AA5C:0000000000000000000001C00220041024101310082007C00000000000000000 +AA5D:0000000000000000008000800080008000800080008000800080000000000000 +AA5E:0000000000000000024002400240024002400240024000400040000000000000 +AA5F:0000000000000000049004900490049004900090009000100010000000000000 +AA60:00000000000000000000018C0252042304250429024A000C0000000000000000 +AA61:00000000000000000000018C02520421042102210152060C0000000000000000 +AA62:000000000000000000000118010401020102014201A401180000000000000000 +AA63:00000000000000000000018C025204A104A104A10252060C0000000000000000 +AA64:00000000000000000000000C02520421042104210252018C0000000000000000 +AA65:00000000000000000000010C0212042104210421026201AC00200020002000E0 +AA66:00000000000000000000018C0252042105A104210242018C0000000000000000 +AA67:00000000000000000000018C0252042105A104210252018C0000000000000000 +AA68:00000000000000000000018C0252042305A50429024A018C0000000000000000 +AA69:00000000000000000000018C0252042105B904250252018C0000000000000000 +AA6A:00000000000000000000018C02520421043904250252018C0000000000000000 +AA6B:0000000000000000000000380244028201C200A2004400000000000000000000 +AA6C:0000000000000000000000000102020102310249024901860000000000000000 +AA6D:00000000000000000000000C005200A1006100210022002C00200020012000C0 +AA6E:00000000000000000000018C02420621052104A10292018C0000000000000000 +AA6F:00000000000000000000011801A4014201420142012401180000000000000000 +AA70:000003E00410000003E004100000000000000000000000000000000000000000 +AA71:00000000000000000000018C02520521052105210242000C0000000000000000 +AA72:00000000000000000000004C00B2011101110711052A030C0000000000000000 +AA73:00000000000000000000010C01820181014101210112010C0000000000000000 +AA74:00300048004000200010040808C810A810A810A808C807880088038804C80330 +AA75:0018002400200010000818C42524421442142214142460C40084038404E40318 +AA76:000C001200100008000438E24512020A020A020A020A02320222326242B23C4C +AA77:000006000900080004000FF0109020502050205010500F5C0040004000400070 +AA78:000000000000000C001208A02720102010401040274008C00000000000000000 +AA79:0000000000000000000007800840102010201020082007A00020002000200038 +AA7A:00000000002007C00800098C0A420C210C210C210A12099C08100810081007E0 +AA7B:0000000000000000000000000000000000000100028003000200010000000000 +AA7C:00000000000001FE000000000000000000000000000000000000000000000000 +AA7D:0000000000000000000000000000000007E00000000000000000000000000000 +AA7E:0000000000000000000000710089000501E501150089007900090009000D001A +AA7F:00000000000000000000011102A90045074504C502AD011500050005000D001A +AA80:00000000000000001830085008900890091009100A100C100000000000000000 +AA81:000000000000000003E00410082808480888090806101E200000000000000000 +AA82:0000000000000E04110820882088208820882088110809F00008000800880070 +AA83:000000000000661C222222422242224222422242224C1D82000200020022001C +AA84:0000000000000E0811102090209020907110291C293210CC0000000000000000 +AA85:00000000000008F00508020802080208000800080030000800080208010800F0 +AA86:000000000000038004400820082008201C200A200A2004200020002004400380 +AA87:000000000000038004400820082008200820046003A000200020002004400380 +AA88:00060008000EDB094C86488848884888488849EA4A95310A0000000000000000 +AA89:02000400080013C0142014101010101010100810042003C00000000000000000 +AA8A:000000300048008000801880248004800480048004E003D00060000000000000 +AA8B:0000000000000210052804F0042004200420042004200820002000200012000C +AA8C:0000003C0042008000803060488008800880088008C0092006C0000000000000 +AA8D:0000003C00420080008030604880088008800880088008800700008000800300 +AA8E:0000000000003008081004200240018001802240142008180000000000000000 +AA8F:0007000800100E1011102090209020907110291C293210CC0000000000000000 +AA90:00000000000066D823242224222422242224222422241C240004000400840078 +AA91:0000000000000770088810881008780814080C080008000800080008010800F0 +AA92:000000000000000003E00410080808080808080804101E200000000000000000 +AA93:00000000000060E021102210221022102210239026501990001000100012000C +AA94:0000000000000770088810881008780814080C10000000000000000000000000 +AA95:0000000000003040484008400840084008400840084807B00000000000000000 +AA96:0000000000000E00110020802080208070802880288010800080008800880070 +AA97:0000000000000C1004100410041004100410043004500390001000100012000C +AA98:000200040008DB084C88488848884888488849EA4A95310A0000000000000000 +AA99:000000000000000018202440048004800480048004E003D00060000000000000 +AA9A:0000002000400080008018802480048004800480048003000000000000000000 +AA9B:000400080008000832481248124812481248124812480DB00000000000000000 +AA9C:0018002400403040084008400840084008400840048003000000000000000000 +AA9D:000800100010001031101110111011101110111011100EE00000000000000000 +AA9E:0000003C004200800080606014801A801080108010C011200EC0000000000000 +AA9F:000400080008010862882288228822882288228822881C700008000800300000 +AAA0:0000042004401B80308008800900090009000960089007600000000000000000 +AAA1:0000001C00220020632025202520292029203138316420980000000000000000 +AAA2:0000000000016D822644244424442444244224E22552188C0000000000000000 +AAA3:0000000000043808441004100410041004080E08150808F00000000000000000 +AAA4:020C02120DA03820442004200420042004200420024001800000000000000000 +AAA5:020802100DA03820442004200420042004200420024001800000000000000000 +AAA6:0000000000002300148008400840084008400840102420180000000000000000 +AAA7:0000000000002300148008400840084008400858103420380010000800000000 +AAA8:000000000000CDC046204420442044204420442044203820002000200012000C +AAA9:0000000000000780084008400090012000C000800D0002000000000000000000 +AAAA:000000000000DB704C884884488448844884488448A430980000000000000000 +AAAB:00000000000003C0042004100010001000100810042003C00000000000000000 +AAAC:000000000000CCC055204E104410441044104422442438180000000000000000 +AAAD:00000000000030E0111012081208120814081408144808300000000000000000 +AAAE:00000000000003C0042004100250019000100410042003C00000000000000000 +AAAF:000003C004200410021001F800140414042403C4000400040004000400880070 +AAB0:0000042008400880070000000000000000000000000000000000000000000000 +AAB1:0000000000000780044000400040004000400040004000400000000000000000 +AAB2:00000100010006C0000000000000000000000000000000000000000000000000 +AAB3:080014E017100800100008000000000000000000000000000000000000000000 +AAB4:0000000000000000000000000000000000000000000C0012000E0022001C0000 +AAB5:000000000000042008401080108010801080108010800C600000000000000000 +AAB6:000001E002100400040004000400040004000400040003000000000000000000 +AAB7:0010002000400280010000000000000000000000000000000000000000000000 +AAB8:001000A0004002A0010000000000000000000000000000000000000000000000 +AAB9:0000000000000080010002000200020002000200020001800000000000000000 +AABA:0000000000E0010002000200010000C0010001C002A004400000000000000000 +AABB:00000600090008800880049003E0008000800080008003000000000000000000 +AABC:00000000000001C00220040004000400020001C0008001000200020004000600 +AABD:0000002000400080009031E04A8008800880088008C0092006C0000000000000 +AABE:038802700E2009C0388027000000000000000000000000000000000000000000 +AABF:0040004000400080008000800000000000000000000000000000000000000000 +AAC0:0000000000000180024004400440048007000420044003800000000000000000 +AAC1:0000003006400980030004000000000000000000000000000000000000000000 +AAC2:0000000000000780044000400040004000400040004000400040008001000200 +AAC3:00007FFE61866DB661866DB66DB67FFE7FFE718E6FF66FC66FF6718E7FFE0000 +AAC4:00007FFE61866DB661866DB66DB67FFE7FFE71B66FB66F866FF671F67FFE0000 +AAC5:00007FFE61866DB661866DB66DB67FFE7FFE71866FBE6F866FF671867FFE0000 +AAC6:00007FFE61866DB661866DB66DB67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000 +AAC7:00007FFE61866DB661866DB66DB67FFE7FFE71866FF66FEE6FDE71DE7FFE0000 +AAC8:00007FFE61866DB661866DB66DB67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +AAC9:00007FFE61866DB661866DB66DB67FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +AACA:00007FFE61866DB661866DB66DB67FFE7FFE71866FB66F866FB671B67FFE0000 +AACB:00007FFE61866DB661866DB66DB67FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +AACC:00007FFE61866DB661866DB66DB67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +AACD:00007FFE61866DB661866DB66DB67FFE7FFE718E6FB66FB66FB6718E7FFE0000 +AACE:00007FFE61866DB661866DB66DB67FFE7FFE71866FBE6F8E6FBE71867FFE0000 +AACF:00007FFE61866DB661866DB66DB67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +AAD0:00007FFE61866DB661866DB66DB67FFE7FFE63CE6DB66DB66DB663CE7FFE0000 +AAD1:00007FFE61866DB661866DB66DB67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000 +AAD2:00007FFE61866DB661866DB66DB67FFE7FFE63866DF66D866DBE63867FFE0000 +AAD3:00007FFE61866DB661866DB66DB67FFE7FFE638E6DF66DC66DF6638E7FFE0000 +AAD4:00007FFE61866DB661866DB66DB67FFE7FFE63B66DB66D866DF663F67FFE0000 +AAD5:00007FFE61866DB661866DB66DB67FFE7FFE63866DBE6D866DF663867FFE0000 +AAD6:00007FFE61866DB661866DB66DB67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000 +AAD7:00007FFE61866DB661866DB66DB67FFE7FFE63866DF66DEE6DDE63DE7FFE0000 +AAD8:00007FFE61866DB661866DB66DB67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000 +AAD9:00007FFE61866DB661866DB66DB67FFE7FFE63CE6DB66DC66DF663CE7FFE0000 +AADA:00007FFE61866DB661866DB66DB67FFE7FFE63866DB66D866DB663B67FFE0000 +AADB:0007000800100E12110C208420B823C87D08291C292A10CC0000000000000000 +AADC:0007000800100E12110C2084208820887108291C292A10CC0000000000000000 +AADD:02000400080008000B8004400A20092008E01C500A480A480430000000000000 +AADE:1F7C21844508105001020A0405545AAC4AA44AA464980000145041043EF80000 +AADF:0000007000800100012000C00040008000801FE0209007E0088011C00EA000C0 +AAE0:000000000000000001C002200410081008100010001013900C70000000000000 +AAE1:00000000000000001FF008000800080008100810082004400380000000000000 +AAE2:00000000000000001CE0249017A0102010200840084008403030000000000000 +AAE3:000000000000000001900190016002000200020034004C004C00000000000000 +AAE4:0000000000000000070C089210A2204250A28912850A48923062000000000000 +AAE5:00000000000000001FF00100010001000FE009200FE009200FE0000000000000 +AAE6:00000000000000000700088018C0252042104010202020201040000000000000 +AAE7:0000000000000000183024482288210822882448282824482388000000000000 +AAE8:00000000000000003FF0100013F0101010201040104010801080000000000000 +AAE9:00000000000000007FFC22881450082014502288228814500820000000000000 +AAEA:000000000000000007C00820082008200FE00820082008200FE0000000000000 +AAEB:00006000900090007C0020002000200020002000200020002000000000000000 +AAEC:0000000000000000000000000000000000000000000000000490049003600000 +AAED:008000400020006000A000400000000000000000000000000000000000000000 +AAEE:0000600090007000200020003800200020002000200020002000000000000000 +AAEF:0000000C0012001C000800080038000800080008000800080008000000000000 +AAF0:0000000000000000008000800080008000800080008000800080000000000000 +AAF1:000000000000000010100C600380000003800C60101000000000000000000000 +AAF2:00000080022001C0000001C002200020004001800200022001C0000000000000 +AAF3:000000000000000007C008200820044002800100028004400820000000000000 +AAF4:0000000000000000038000400020002000400080010000800060000000000000 +AAF5:000000000000000000000004000A000A00040004000400000000000000000000 +AAF6:0000000000000000000000000000000000000000000000000000008001C00080 +AAF7:00007FFE61866DB661866DB66DB67FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +AAF8:00007FFE61866DB661866DB66DB67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +AAF9:00007FFE61866DB661866DB66DB67FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +AAFA:00007FFE61866DB661866DB66DB67FFE7FFE61866FB663866FB66FB67FFE0000 +AAFB:00007FFE61866DB661866DB66DB67FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +AAFC:00007FFE61866DB661866DB66DB67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +AAFD:00007FFE61866DB661866DB66DB67FFE7FFE618E6FB663B66FB66F8E7FFE0000 +AAFE:00007FFE61866DB661866DB66DB67FFE7FFE61866FBE638E6FBE6F867FFE0000 +AAFF:00007FFE61866DB661866DB66DB67FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +AB00:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DB66DB66DB673CE7FFE0000 +AB01:000000000600060007000F8018C018C01FC01FFC18CC18C018C018C000000000 +AB02:000000000600060007000F8018C018C01FC01FC018C018C018CC18FC00000000 +AB03:000000000180018001C003E00630063007F007F0063000300030003000000000 +AB04:000000000600060007000F8018C018C01FC01FC018C018F818CC18F800000000 +AB05:000000000300038001C003E00630063007F007F0063006300630063000000000 +AB06:000000000180018001C003E00630063007F007F0063006000600060000000000 +AB07:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DF66DEE6DDE73DE7FFE0000 +AB08:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000 +AB09:0600060007000F8018801F8018800D0006001FC030C030FC018C018000000000 +AB0A:0600060007000F8018801F8018800D0006001FC030C030C0019801F800000000 +AB0B:03000300038007C00C400FC00C40068003000FF00C300C300030003000000000 +AB0C:0600060007000F8018801F8018800D0006000600060003F03F9830F000000000 +AB0D:0600060007000F8018801FF818980D0006000600060003003FF0303000000000 +AB0E:0300038007C00C400FC00C400680030007F00C30180018001800180000000000 +AB0F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000 +AB10:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7BCE73B67BB67BB671CE7FFE0000 +AB11:60307FF0401018C018C018C018C01FC01FC018FC18CC18CC18C018C000000000 +AB12:60307FF0401018C018C018C018C01FC01FC018C018C018C018CC18FC00000000 +AB13:30183FF820080C600C600C600C600FE00FE00C600C6000600060006000000000 +AB14:60307FF0401018C018C018C018C01FC01FC018C018C018F818CC18F800000000 +AB15:30183FF8200800001C3036303630063007F007F0063006300630063000000000 +AB16:30183FF820080C600C600C600C600FE00FE00C600C600C000C000C0000000000 +AB17:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000 +AB18:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000 +AB19:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7BCE73B67BC67BF671CE7FFE0000 +AB1A:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8673B67B867BB671B67FFE0000 +AB1B:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000 +AB1C:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000 +AB1D:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8E73B67BB67BB6718E7FFE0000 +AB1E:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8673BE7B8E7BBE71867FFE0000 +AB1F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000 +AB20:60307FF0401000001F803FC06260C230C230C230F338DAB6CAB2FBBE00000000 +AB21:60307FF0401000001F803FC06260C230C23FC233F338DAB4CAB2FBBE00000000 +AB22:60307FF0401000001F803FC06260C230C230C230F330DAB0CAB3FBBF00000000 +AB23:30183FF820080FE01FF031186118799865587DD8001800340032003E00000000 +AB24:60307FF0401000001F803FC06260C23FC239C237F330DABCCAB2FBBE00000000 +AB25:60307FF040101FC07FE0C630E6389724F33C030003800340032003E000000000 +AB26:30183FF820080FE01FF01A183218231862946252739C680064007C0000000000 +AB27:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61867DF661EE6FDE61DE7FFE0000 +AB28:000018181FF81008018003C00660066003C007E00E700C300C300C3000000000 +AB29:000060607FE0402006000F00198019800F001F8039C030FC30CC30C000000000 +AB2A:000060607FE0402006000F00198019800F001F8039C030C030CC30FC00000000 +AB2B:30303FF02010030007800CC00CC007800FC01CC018E018600060006000000000 +AB2C:000030603FE02020030007800CC00CC007800FC01CE01878186C187800000000 +AB2D:000030603FE0202006000F0019F819980F001F8039C030C030C030C000000000 +AB2E:30603FE02020030007800CC00CC007800FC01CE0186018601800180000000000 +AB2F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61867DBE618E6FBE61BE7FFE0000 +AB30:000000000000344C44FE44444C340000 +AB31:0000000000007C9210709E92927C0000 +AB32:00000000000018244244485224180000 +AB33:0000000000003C42427E40FE403E0000 +AB34:0000000000001C22227EA0A0A21C0000 +AB35:0000000C1010107C1010101010000000 +AB36:0000000000003A4642423E02122A1C08 +AB37:00000000301014127C905010107C0000 +AB38:000000003010127C90127C90107C0000 +AB39:000000003010103854543810107C0000 +AB3A:0000000000006C52525252575A540000 +AB3B:0000000000005C62424242474A440000 +AB3C:0000000000005C6242424244444E1408 +AB3D:00000000000010284444444428100000 +AB3E:00000000000014284C54546428500000 +AB3F:0000000000023C460A0A1212623C4000 +AB40:0000000000006C9290909E92926C0000 +AB41:0000000000025CA6262AEAB2B25C0000 +AB42:0000000000006C921212FE92926C0000 +AB43:0000000000004C9292929292926C0000 +AB44:0000000000429CA6A6AAAAB2A25C0000 +AB45:00000000000010101038444444440000 +AB46:0000000000007C42427C505048480906 +AB47:00000000000028302020202020200000 +AB48:000000000000546A4A40404040400000 +AB49:0000000000002C3222202070A0A04000 +AB4A:0000000000002A3525202070A0A04000 +AB4B:000000000000665A4202020202020000 +AB4C:000000000000CCB48406050505020000 +AB4D:0000000C101010101010101010600000 +AB4E:000000000000404040424242463A0000 +AB4F:000000000000404040FE44444C340000 +AB50:000000000000928282929292926E0000 +AB51:000000000000EC929292928282920000 +AB52:00000000000042A2A2222222261A0000 +AB53:00000000000042422424181824244242 +AB54:0000000000008484484830304C4A8A84 +AB55:00000000000042422424181824A4C282 +AB56:00000000000084844830304A85850200 +AB57:0000000000002121120C0C1221418000 +AB58:000000000000424224181A2545820000 +AB59:0000000000002121120C0C1221A1C080 +AB5A:0000000000004040424242261A02023C +AB5B:00000000000044380038440000000000 +AB5C:00000020203824242424040800000000 +AB5D:0000007014127C9050107C0000000000 +AB5E:0000003808083A4C08083E0000000000 +AB5F:000000000042A222261A000000000000 +AB60:0000000000007050505C5252525C0000 +AB61:0000000000004C52527E5050524C0000 +AB62:0000000000006C92121E1010926C0000 +AB63:0000000000008C9292929292926C0000 +AB64:000000000000324A46424242463A0000 +AB65:0000000000007C828282442828EE0000 +AB66:0000000000000200020002003BF84608421042204240428047083BF800080006 +AB67:00000000000000001000100010F07F08110010C01030100813080DF0010000C0 +AB68:00000000000004051E2404444C340000 +AB69:00000000002236554949000000000000 +AB6A:0000000000000404047C040404000000 +AB6B:0000000000004040407C404040000000 +AB6C:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73C66FBE63BE6DBE73C67FFE0000 +AB6D:00007FFE618E6DB6618E6DB66D8E7FFE7FFE738E6FB663B66DB6738E7FFE0000 +AB6E:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866FBE638E6DBE73867FFE0000 +AB6F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866FBE638E6DBE73BE7FFE0000 +AB70:00000000000078444242424244780000 +AB71:0000000000007C42427C504844430000 +AB72:0000000000007F080808080808080000 +AB73:0000000000001C081412215155260000 +AB74:00000000000030484B494E4848300000 +AB75:00000000000008080008080808080000 +AB76:0000000000003C42207F0442423C0000 +AB77:0000000000001C0222525262423C0000 +AB78:000000000000404C5476404040400000 +AB79:00000000000042424242261A023C0000 +AB7A:000000000000182442427E4242420000 +AB7B:00000000000004040404044444380000 +AB7C:0000000000007E40407C4040407E0000 +AB7D:000000000000080848A8BB490A0C0000 +AB7E:0000000000003C0202427C4040400000 +AB7F:0000000000001C22223E2222AACC0000 +AB80:0000000000002020203E202020200000 +AB81:0000000000007E424040404040400000 +AB82:0000000000003048484830B7B4480000 +AB83:0000000000004242425A5A6666420000 +AB84:00000000000006090838444444380000 +AB85:0000000000003C42524C404040400000 +AB86:0000000000001E2040505C5244380000 +AB87:0000000000004266665A5A4242420000 +AB88:00000000000038440202721E02020000 +AB89:000000000000180A15203C52520C0000 +AB8A:000000000000324A4A4E4A4A4A320000 +AB8B:0000000000004242427E424242420000 +AB8C:000000000000381038440202423C0000 +AB8D:000000000000474242261A02E2443800 +AB8E:0000000000003C4242427E42423C0000 +AB8F:0000000000004040F040404E443C0418 +AB90:000000000000788480809E8484780000 +AB91:0000000000000C12121222A2A2420000 +AB92:0000000000004040405C624242420000 +AB93:0000000000007E0204081020407E0000 +AB94:0000000000003844E404E4443C040400 +AB95:0000000000003048484A4D4948300000 +AB96:000000000000FE101010101010FE0000 +AB97:0000000000000C1202424A4A4A340000 +AB98:0000000000006619292A484848300000 +AB99:000000000000F1A12222242428100000 +AB9A:0000000000001C22029AA2A2A25C0000 +AB9B:0000000000003C42403C4042423C0000 +AB9C:000000000000424242427E42423C0000 +AB9D:0000000000001C2222021AD2B26C0000 +AB9E:000000000000040C1424447E04040000 +AB9F:000000000000404040407C42427C0000 +ABA0:0000000000000808080B5D6808080000 +ABA1:000000000000649AE240988484780000 +ABA2:0000000000007C42425C484442420000 +ABA3:000000000000202020202022221C0000 +ABA4:000000000000AAAA92B2CACA86820000 +ABA5:0000000000003C4247201F44423C0000 +ABA6:000000000000F09010101211110E0000 +ABA7:000000000000040404040C1424440000 +ABA8:0000000000007C0404040C1424440000 +ABA9:00000000000082824444282810100000 +ABAA:0000000000003C4240300C02423C0000 +ABAB:00000000000036494260504848300000 +ABAC:00000000000018241824225555220000 +ABAD:0000000000001C2242404040407E0000 +ABAE:000000000000404040404040407E0000 +ABAF:0000000000003C4240404040423C0000 +ABB0:0000000000000444A47E242424180000 +ABB1:00000000000066999A28444444380000 +ABB2:0000000000007C42427C404040400000 +ABB3:0000000000003C4247404042423C0000 +ABB4:000000000000F1911212141418100000 +ABB5:0000000000404040434D744444440000 +ABB6:00000000000044485060605048440000 +ABB7:0000000000000202023E4242423C0000 +ABB8:000000000000304A454040454A300000 +ABB9:00000000000038444440404E443B0000 +ABBA:00000000000022555351311995620000 +ABBB:0000000000003C4272525E42423C0000 +ABBC:000000000000324949714141221C0000 +ABBD:0000000000000C12120A064244380000 +ABBE:0000000000003C4240407C42423C0000 +ABBF:0000000000001E2101015D4949360000 +ABC0:00000000000000007FF824B024D02590269024902C9034903FF0000000000000 +ABC1:0000000000000000063009481084100410040808080804100220000000000000 +ABC2:00000000000000001FF80020002007A008601000100008400780000000000000 +ABC3:00000000000000007FF82400240024003FE024C02500251024E0000000000000 +ABC4:00000000000000007FF844882490249014A014A014A054A86498000000000000 +ABC5:00000000000000001FFC041008100820104010080810042003C0000000000000 +ABC6:00000000000000003FF020101020102008400FC0084028503030000000000000 +ABC7:00000000008001001FF011080890086004000400240024001800000000000000 +ABC8:00000000000000001FF8100008C0052006280410040004001800000000000000 +ABC9:000000000000000007F004900490049064909490149024907FF0000000000000 +ABCA:00000000000000001FFC00800080008008881084108409480630000000000000 +ABCB:00000000000000003FF8200810101010092008A0086008203018000000000000 +ABCC:00000000000000007FFF0808100413640D580240042008241018000000000000 +ABCD:00000000000000007FFC000001800240042008200920112060C0000000000000 +ABCE:00000000000000003FFC10001070089007E00010088815481230000000000000 +ABCF:00000000000000001FF8100008000600058004600410051018E0000000000000 +ABD0:00000000000000001FF01000102010401F801000101010201FC0000000000000 +ABD1:00000000000000003FF8124012401240124012400A480A5007E0000000000000 +ABD2:00000000000000001FF009200924092409180900090009000900000000000000 +ABD3:00000000000000000FF800100020004000800100020004300FC0004000300000 +ABD4:00000000000000000E70118810881F8010801080108010801F80000000000000 +ABD5:00000000000000000FE004400280010002800440082004400380000000000000 +ABD6:00000000000000001FF0001000E0030004000820082004400380000000000000 +ABD7:00000000000000000FFC04480288011002900450083004480384000000000000 +ABD8:00000000000000001FF004000400040004001FC0248024901860000000000000 +ABD9:00000000000000001FFC0040004000400840104010C009400640000000000000 +ABDA:00000000000000001FF00220022012200C200020002000200020000000000000 +ABDB:00000000000000003FF812481248124012401240124012401FC0000000000000 +ABDC:00000000000000000FF80010001000100010071000D000300010000000000000 +ABDD:00000000000000003FF8108010801FE010801080108010801080000000000000 +ABDE:00000000000000003FF821081110111009200920092029283118000000000000 +ABDF:00000000000000003FF8049009201200122011C00808081007E0000000000000 +ABE0:000000000000000020402080210022003F800240024002400180000000000000 +ABE1:00000000000000001FF009200920092009200920092009200FE0000000000000 +ABE2:00000000000000001FF01000080007C0042004100910092010C0000000000000 +ABE3:00180004001C0024002400180000000000000000000000000000000000000000 +ABE4:0000000600090009003E00080008000800080008000800080008000000000000 +ABE5:0040002000100000000000000000000000000000000000000000000000000000 +ABE6:0000000000000000000000000006000900090006000000000000000000000000 +ABE7:00020015000E0004000C00000000000000000000000000000000000000000000 +ABE8:0000000000000000000000000000000000000000000000000360049004100220 +ABE9:000200250015000E000400000000000000000000000000000000000000000000 +ABEA:0002000500050003000100020004000000000000000000000000000000000000 +ABEB:0000000000000000044004400440044004400440044004400440000000000000 +ABEC:0000000000000000000000000000000000000000000000060006000000000000 +ABED:000000000000000000000000000000000000000000000000000000007FFE0000 +ABEE:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FBE638E6FBE61867FFE0000 +ABEF:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FBE638E6FBE61BE7FFE0000 +ABF0:0000000003000CC01020102020102010102010200CC003000000000000000000 +ABF1:000000000000000003800440082008C004000300008004400380000000000000 +ABF2:000000000000000003800440082008C004000360049004500390000000000000 +ABF3:000000000000000003800440082008CC0412036A04A804A80310000000000000 +ABF4:00000000000000000380044000800300040008C0082004400380000000000000 +ABF5:00000000000000000FC010202210251015000E00040004000400000000000000 +ABF6:00000000000000000FC010202210252015000E00048005000600040000000000 +ABF7:00000000000000000C3011480950012003D00508088809100620000000000000 +ABF8:00000000000000000FC010202210252015000E00040014000C00040000000000 +ABF9:00000000000000000FC010202210252015000E0004001F802400180000000000 +ABFA:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FB663866FB66FB67FFE0000 +ABFB:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +ABFC:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +ABFD:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +ABFE:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FBE638E6FBE6F867FFE0000 +ABFF:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +AC00:00000000001000101F9000900090009E01100110021004101810001000100000 +AC01:000000083E0802080208040E080830080008000007F800080008000800080000 +AC02:000000083E0802080208040E080830080008000000003EF80208020802080000 +AC03:000000083E0802080208040E080830080008000000001F080108011401620000 +AC04:000000083E0802080208040E080830080008000808000800080008000FF80000 +AC05:000000083E0802080208040E0808300800080000000010F8101010301ECC0000 +AC06:000000083E0802080208040E08083008000800000808087F081C08220F9C0000 +AC07:000000083E0802080208040E080830080008000003F802000200020003F80000 +AC08:000000083E0802080208040E080830080008000007F8000807F8040007F80000 +AC09:000000083E0802080208040E08083008000800003EF802083E0820083E080000 +AC0A:000000083E0802080208040E08083008000800003EF802883E8820883EF80000 +AC0B:000000083E0802080208040E08083008000800003E8802883EF820883EF80000 +AC0C:000000083E0802080208040E08083008000800001F0801081F0810141F620000 +AC0D:000000083E0802080208040E08083008000800003EF802803EF820803EF80000 +AC0E:000000083E0802080208040E08083008000800003EFC02483E4820483EFC0000 +AC0F:000000083E0802080208040E08083008000800001F08017F1F1C10221F1C0000 +AC10:000000083E0802080208040E080830080008000003F802080208020803F80000 +AC11:000000083E0802080208040E08083008000800000208020803F8020803F80000 +AC12:000000083E0802080208040E0808300800080000110811081F0811141F620000 +AC13:000000083E0802080208040E0808300800080000001000100010006801840000 +AC14:000000083E0802080208040E08083008000800000048004800A8011406620000 +AC15:000000083E0802080208040E0808300800080000000003F00408040803F00000 +AC16:000000083E0802080208040E080830080008000003F80020002000D003080000 +AC17:000000083E0802080208040E0808300800080000004003F8004000A003180000 +AC18:000000083E0802080208040E080830080008000003F8000803F8000800080000 +AC19:000000083E0802080208040E080830080008000003F8020003F8020003F80000 +AC1A:000000083E0802080208040E080830080008000000000FF8022002200FF80000 +AC1B:000000083E0802080208040E080830080008000000800FF803E0041003E00000 +AC1C:00000000001200121F9200920092009E01120112021204121812001200120000 +AC1D:000000283E28022802280438082830280028000007F800080008000800080000 +AC1E:000000283E28022802280438082830280028000000003EF80208020802080000 +AC1F:000000283E28022802280438082830280028000000003E100210022802C40000 +AC20:000000283E28022802280438082830280028002808000800080008000FF80000 +AC21:000000283E280228022804380828302800280000000020F8201020303ECC0000 +AC22:000000283E280228022804380828302800280000202021FC207020883E700000 +AC23:000000283E28022802280438082830280028000003F802000200020003F80000 +AC24:000000283E28022802280438082830280028000007F8000807F8040007F80000 +AC25:000000283E2802280228043808283028002800003EF802083E0820083E080000 +AC26:000000283E2802280228043808283028002800003EF802883E8820883EF80000 +AC27:000000283E2802280228043808283028002800003E8802883EF820883EF80000 +AC28:000000283E2802280228043808283028002800001F0801081F0810141F620000 +AC29:000000283E2802280228043808283028002800003EF802803EF820803EF80000 +AC2A:000000283E2802280228043808283028002800003EFC02483E4820483EFC0000 +AC2B:000000283E2802280228043808283028002800003E1002FE3E3820443E380000 +AC2C:000000283E28022802280438082830280028000003F802080208020803F80000 +AC2D:000000283E2802280228043808283028002800000208020803F8020803F80000 +AC2E:000000283E280228022804380828302800280000110811081F0811141F620000 +AC2F:000000283E280228022804380828302800280000000800080008003400C20000 +AC30:000000283E2802280228043808283028002800000048004800A8011406620000 +AC31:000000283E280228022804380828302800280000000001F00208020801F00000 +AC32:000000283E28022802280438082830280028000003F80020002000D003080000 +AC33:000000283E280228022804380828302800280000004003F8004000A003180000 +AC34:000000283E28022802280438082830280028000003F8000803F8000800080000 +AC35:000000283E28022802280438082830280028000003F8020003F8020003F80000 +AC36:000000283E28022802280438082830280028000000000FF8022002200FF80000 +AC37:000000283E28022802280438082830280028000000800FF803E0041003E00000 +AC38:00000000001000101F900090009E00900110011E021004101810001000100000 +AC39:000000083E080208020E0408080E30080008000007F800080008000800080000 +AC3A:000000083E080208020E0408080E30080008000000003EF80208020802080000 +AC3B:000000083E080208020E0408080E30080008000000001F080108011401620000 +AC3C:000000083E080208020E0408080E30080008000008000800080008000FF80000 +AC3D:000000083E080208020E0408080E300800080000000010F8101010301ECC0000 +AC3E:000000083E080208020E0408080E3008000800000808087F081C08220F9C0000 +AC3F:000000083E080208020E0408080E30080008000003F802000200020003F80000 +AC40:000000083E080208020E0408080E30080008000007F8000807F8040007F80000 +AC41:000000083E080208020E0408080E3008000800003EF802083E0820083E080000 +AC42:000000083E080208020E0408080E3008000800003EF802883E8820883EF80000 +AC43:000000083E080208020E0408080E3008000800003E8802883EF820883EF80000 +AC44:000000083E080208020E0408080E3008000800001F0801081F0810141F620000 +AC45:000000083E080208020E0408080E3008000800003EF802803EF820803EF80000 +AC46:000000083E080208020E0408080E3008000800003EFC02483E4820483EFC0000 +AC47:000000083E080208020E0408080E3008000800001F08017F1F1C10221F1C0000 +AC48:000000083E080208020E0408080E30080008000003F802080208020803F80000 +AC49:000000083E080208020E0408080E3008000800000208020803F8020803F80000 +AC4A:000000083E080208020E0408080E300800080000110811081F0811141F620000 +AC4B:000000083E080208020E0408080E300800080000001000100010006801840000 +AC4C:000000083E080208020E0408080E3008000800000048004800A8011406620000 +AC4D:000000083E080208020E0408080E300800080000000003F00408040803F00000 +AC4E:000000083E080208020E0408080E30080008000003F80020002000D003080000 +AC4F:000000083E080208020E0408080E300800080000004003F8004000A003180000 +AC50:000000083E080208020E0408080E30080008000003F8000803F8000800080000 +AC51:000000083E080208020E0408080E30080008000003F8020003F8020003F80000 +AC52:000000083E080208020E0408080E30080008000000000FF8022002200FF80000 +AC53:000000083E080208020E0408080E30080008000000800FF803E0041003E00000 +AC54:00000000001200121F920092009E00920112011E021204121812001200120000 +AC55:000000283E28022802380428083830280028000007F800080008000800080000 +AC56:000000283E28022802380428083830280028000000003EF80208020802080000 +AC57:000000283E28022802380428083830280028000000003E100210022802C40000 +AC58:000000283E28022802380428083830280028002808000800080008000FF80000 +AC59:000000283E280228023804280838302800280000000020F8201020303ECC0000 +AC5A:000000283E280228023804280838302800280000202021FC207020883E700000 +AC5B:000000283E28022802380428083830280028000003F802000200020003F80000 +AC5C:000000283E28022802380428083830280028000007F8000807F8040007F80000 +AC5D:000000283E2802280238042808383028002800003EF802083E0820083E080000 +AC5E:000000283E2802280238042808383028002800003EF802883E8820883EF80000 +AC5F:000000283E2802280238042808383028002800003E8802883EF820883EF80000 +AC60:000000283E2802280238042808383028002800001F0801081F0810141F620000 +AC61:000000283E2802280238042808383028002800003EF802803EF820803EF80000 +AC62:000000283E2802280238042808383028002800003EFC02483E4820483EFC0000 +AC63:000000283E2802280238042808383028002800003E1002FE3E3820443E380000 +AC64:000000283E28022802380428083830280028000003F802080208020803F80000 +AC65:000000283E2802280238042808383028002800000208020803F8020803F80000 +AC66:000000283E280228023804280838302800280000110811081F0811141F620000 +AC67:000000283E280228023804280838302800280000000800080008003400C20000 +AC68:000000283E2802280238042808383028002800000048004800A8011406620000 +AC69:000000283E280228023804280838302800280000000001F00208020801F00000 +AC6A:000000283E28022802380428083830280028000003F80020002000D003080000 +AC6B:000000283E280228023804280838302800280000004003F8004000A003180000 +AC6C:000000283E28022802380428083830280028000003F8000803F8000800080000 +AC6D:000000283E28022802380428083830280028000003F8020003F8020003F80000 +AC6E:000000283E28022802380428083830280028000000000FF8022002200FF80000 +AC6F:000000283E28022802380428083830280028000000800FF803E0041003E00000 +AC70:00000000000200021F8200820082009E01020102020204021802000200020000 +AC71:000000083E080208020804380808300800080000000007F80008000800080000 +AC72:000000083E08020802080438080830080008000000003EF80208020802080000 +AC73:000000083E08020802080438080830080008000000001F080108011401620000 +AC74:000000083E08020802080438080830080008000000001000100010001FF80000 +AC75:000000083E080208020804380808300800080000000020F8201020303ECC0000 +AC76:000000083E080208020804380808300800080000202021FC207020883E700000 +AC77:000000083E08020802080438080830080008000003F802000200020003F80000 +AC78:000000083E08020802080438080830080008000007F8000807F8040007F80000 +AC79:000000083E0802080208043808083008000800003EF802083E0820083E080000 +AC7A:000000083E0802080208043808083008000800003EF802883E8820883EF80000 +AC7B:000000083E0802080208043808083008000800003E8802883EF820883EF80000 +AC7C:000000083E0802080208043808083008000800000F8800880F8808140FA20000 +AC7D:000000083E0802080208043808083008000800003EF802803EF820803EF80000 +AC7E:000000083E0802080208043808083008000800003EFC02483E4820483EFC0000 +AC7F:000000083E0802080208043808083008000800003E1002FE3E3820443E380000 +AC80:000000083E08020802080438080830080008000003F802080208020803F80000 +AC81:000000083E0802080208043808083008000800000208020803F8020803F80000 +AC82:000000083E080208020804380808300800080000210821083F0821143F620000 +AC83:000000083E080208020804380808300800080000001000100010006801840000 +AC84:000000083E0802080208043808083008000800000048004800A8011406620000 +AC85:000000083E080208020804380808300800080000000003F00408040803F00000 +AC86:000000083E08020802080438080830080008000003F80020002000D003080000 +AC87:000000083E080208020804380808300800080000004003F8004000A003180000 +AC88:000000083E08020802080438080830080008000003F8000803F8000800080000 +AC89:000000083E08020802080438080830080008000003F8020003F8020003F80000 +AC8A:000000083E08020802080438080830080008000000000FF8022002200FF80000 +AC8B:000000083E08020802080438080830080008000000800FF803E0041003E00000 +AC8C:00000000000A000A1F8A008A008A00BA010A010A020A040A180A000A000A0000 +AC8D:000000283E280228022804E8082830280028000007F800080008000800080000 +AC8E:000000283E280228022804E8082830280028000000003EF80208020802080000 +AC8F:000000283E280228022804E8082830280028000000003E100210022802C40000 +AC90:000000283E280228022804E8082830280028000008000800080008000FF80000 +AC91:000000283E280228022804E80828302800280000000020F8201020303ECC0000 +AC92:000000283E280228022804E80828302800280000202021FC207020883E700000 +AC93:000000283E280228022804E8082830280028000003F802000200020003F80000 +AC94:000000283E280228022804E8082830280028000007F8000807F8040007F80000 +AC95:000000283E280228022804E808283028002800003EF802083E0820083E080000 +AC96:000000283E280228022804E808283028002800003EF802883E8820883EF80000 +AC97:000000283E280228022804E808283028002800003E8802883EF820883EF80000 +AC98:000000283E280228022804E808283028002800001F0801081F0810141F620000 +AC99:000000283E280228022804E808283028002800003EF802803EF820803EF80000 +AC9A:000000283E280228022804E808283028002800003EFC02483E4820483EFC0000 +AC9B:000000283E280228022804E808283028002800003E1002FE3E3820443E380000 +AC9C:000000283E280228022804E8082830280028000003F802080208020803F80000 +AC9D:000000283E280228022804E808283028002800000208020803F8020803F80000 +AC9E:000000283E280228022804E80828302800280000110811081F0811141F620000 +AC9F:000000283E280228022804E80828302800280000000800080008003400C20000 +ACA0:000000283E280228022804E808283028002800000048004800A8011406620000 +ACA1:000000283E280228022804E80828302800280000000001F00208020801F00000 +ACA2:000000283E280228022804E8082830280028000003F80020002000D003080000 +ACA3:000000283E280228022804E80828302800280000004003F8004000A003180000 +ACA4:000000283E280228022804E8082830280028000003F8000803F8000800080000 +ACA5:000000283E280228022804E8082830280028000003F8020003F8020003F80000 +ACA6:000000283E280228022804E8082830280028000000000FF8022002200FF80000 +ACA7:000000283E280228022804E8082830280028000000800FF803E0041003E00000 +ACA8:00000000000200021F820082009E00820102011E020204021802000200020000 +ACA9:000000083E080208023804080838300800080000000007F80008000800080000 +ACAA:000000083E08020802380408083830080008000000003EF80208020802080000 +ACAB:000000083E08020802380408083830080008000000001F080108011401620000 +ACAC:000000083E08020802380408083830080008000800001000100010001FF80000 +ACAD:000000083E080208023804080838300800080000000020F8201020303ECC0000 +ACAE:000000083E080208023804080838300800080000202021FC207020883E700000 +ACAF:000000083E08020802380408083830080008000003F802000200020003F80000 +ACB0:000000083E08020802380408083830080008000007F8000807F8040007F80000 +ACB1:000000083E0802080238040808383008000800003EF802083E0820083E080000 +ACB2:000000083E0802080238040808383008000800003EF802883E8820883EF80000 +ACB3:000000083E0802080238040808383008000800003E8802883EF820883EF80000 +ACB4:000000083E0802080238040808383008000800000F8800880F8808140FA20000 +ACB5:000000083E0802080238040808383008000800003EF802803EF820803EF80000 +ACB6:000000083E0802080238040808383008000800003EFC02483E4820483EFC0000 +ACB7:000000083E0802080238040808383008000800003E1002FE3E3820443E380000 +ACB8:000000083E08020802380408083830080008000003F802080208020803F80000 +ACB9:000000083E0802080238040808383008000800000208020803F8020803F80000 +ACBA:000000083E080208023804080838300800080000210821083F0821143F620000 +ACBB:000000083E080208023804080838300800080000001000100010006801840000 +ACBC:000000083E0802080238040808383008000800000048004800A8011406620000 +ACBD:000000083E080208023804080838300800080000000003F00408040803F00000 +ACBE:000000083E08020802380408083830080008000003F80020002000D003080000 +ACBF:000000083E080208023804080838300800080000004003F8004000A003180000 +ACC0:000000083E08020802380408083830080008000003F8000803F8000800080000 +ACC1:000000083E08020802380408083830080008000003F8020003F8020003F80000 +ACC2:000000083E08020802380408083830080008000000000FF8022002200FF80000 +ACC3:000000083E08020802380408083830080008000000800FF803E0041003E00000 +ACC4:00000000000A000A1F8A008A00BA008A010A013A020A040A180A000A000A0000 +ACC5:000000283E28022802E8042808E830280028000007F800080008000800080000 +ACC6:000000283E28022802E8042808E830280028000000003EF80208020802080000 +ACC7:000000283E28022802E8042808E830280028000000003E100210022802C40000 +ACC8:000000283E28022802E8042808E830280028002808000800080008000FF80000 +ACC9:000000283E28022802E8042808E8302800280000000020F8201020303ECC0000 +ACCA:000000283E28022802E8042808E8302800280000202021FC207020883E700000 +ACCB:000000283E28022802E8042808E830280028000003F802000200020003F80000 +ACCC:000000283E28022802E8042808E830280028000007F8000807F8040007F80000 +ACCD:000000283E28022802E8042808E83028002800003EF802083E0820083E080000 +ACCE:000000283E28022802E8042808E83028002800003EF802883E8820883EF80000 +ACCF:000000283E28022802E8042808E83028002800003E8802883EF820883EF80000 +ACD0:000000283E28022802E8042808E83028002800001F0801081F0810141F620000 +ACD1:000000283E28022802E8042808E83028002800003EF802803EF820803EF80000 +ACD2:000000283E28022802E8042808E83028002800003EFC02483E4820483EFC0000 +ACD3:000000283E28022802E8042808E83028002800003E1002FE3E3820443E380000 +ACD4:000000283E28022802E8042808E830280028000003F802080208020803F80000 +ACD5:000000283E28022802E8042808E83028002800000208020803F8020803F80000 +ACD6:000000283E28022802E8042808E8302800280000110811081F0811141F620000 +ACD7:000000283E28022802E8042808E8302800280000000800080008003400C20000 +ACD8:000000283E28022802E8042808E83028002800000048004800A8011406620000 +ACD9:000000283E28022802E8042808E8302800280000000001F00208020801F00000 +ACDA:000000283E28022802E8042808E830280028000003F80020002000D003080000 +ACDB:000000283E28022802E8042808E8302800280000004003F8004000A003180000 +ACDC:000000283E28022802E8042808E830280028000003F8000803F8000800080000 +ACDD:000000283E28022802E8042808E830280028000003F8020003F8020003F80000 +ACDE:000000283E28022802E8042808E830280028000000000FF8022002200FF80000 +ACDF:000000283E28022802E8042808E830280028000000800FF803E0041003E00000 +ACE0:00000000000000003FF0001000100010001002100200020002007FFC00000000 +ACE1:000000001FF0001000100010011001007FFC00001FF000100010001000100000 +ACE2:000000001FF0001000100010011001007FFC000000003EF80208020802080000 +ACE3:000000001FF0001000100010011001007FFC000000001E100210022802C40000 +ACE4:000000001FF0001000100010011001007FFC000000001000100010001FF00000 +ACE5:000000001FF0001000100010011001007FFC0000000020F8201020303ECC0000 +ACE6:000000001FF0001000100010011001007FFC0000202021FC207020883E700000 +ACE7:000000001FF0001000100010011001007FFC00001FF01000100010001FF00000 +ACE8:000000001FF0001000100010011001007FFC00001FF000101FF010001FF00000 +ACE9:000000001FF0001000100010011001007FFC00003EF802083E0820083E080000 +ACEA:000000001FF0001000100010011001007FFC00003EF802883E8820883EF80000 +ACEB:000000001FF0001000100010011001007FFC00003E8802883EF820883EF80000 +ACEC:000000001FF0001000100010011001007FFC00003E1002103E1020283EC40000 +ACED:000000001FF0001000100010011001007FFC00003EF802803EF820803EF80000 +ACEE:000000001FF0001000100010011001007FFC00003EFC02483E4820483EFC0000 +ACEF:000000001FF0001000100010011001007FFC00003E2003FC3E7020883E700000 +ACF0:000000001FF0001000100010011001007FFC00001FF01010101010101FF00000 +ACF1:000000001FF0001000100010011001007FFC0000101010101FF010101FF00000 +ACF2:000000001FF0001000100010011001007FFC0000222022203E2022503E880000 +ACF3:000000001FF0001000100010011001007FFC000000000100010002800C400000 +ACF4:000000001FF0001000100010011001007FFC00000000024002400DA033100000 +ACF5:000000001FF0001000100010011001007FFC0000000007C00820082007C00000 +ACF6:000000001FF0001000100010011001007FFC0000000007E00080014006200000 +ACF7:000000001FF0001000100010011001007FFC0000008007E00080014006200000 +ACF8:000000001FF0001000100010011001007FFC00001FF000101FF0001000100000 +ACF9:000000001FF0001000100010011001007FFC00001FF010001FF010001FF00000 +ACFA:000000001FF0001000100010011001007FFC000000001FF0044004401FF00000 +ACFB:000000001FF0001000100010011001007FFC000001001FF007C0082007C00000 +ACFC:00000000001000103FD000500050005E0450041004107FD00010001000100000 +ACFD:000000081F880088008E0088048804087FE8000007F800080008000800080000 +ACFE:000000081F880088008E0088048804087FE8000000003EF80208020802080000 +ACFF:000000081F880088008E0088048804087FE8000000001F080108011401620000 +AD00:000000081F880088008E0088048804087FE8000008000800080008000FF80000 +AD01:000000081F880088008E0088048804087FE80000000010F8101010301ECC0000 +AD02:000000081F880088008E0088048804087FE800000808087F081C08220F9C0000 +AD03:000000081F880088008E0088048804087FE8000003F802000200020003F80000 +AD04:000000081F880088008E0088048804087FE8000007F8000807F8040007F80000 +AD05:000000081F880088008E0088048804087FE800003EF802083E0820083E080000 +AD06:000000081F880088008E0088048804087FE800003EF802883E8820883EF80000 +AD07:000000081F880088008E0088048804087FE800003E8802883EF820883EF80000 +AD08:000000081F880088008E0088048804087FE800001F0801081F0810141F620000 +AD09:000000081F880088008E0088048804087FE800003EF802803EF820803EF80000 +AD0A:000000081F880088008E0088048804087FE800003EFC02483E4820483EFC0000 +AD0B:000000081F880088008E0088048804087FE800001F08017F1F1C10221F1C0000 +AD0C:000000081F880088008E0088048804087FE8000003F802080208020803F80000 +AD0D:000000081F880088008E0088048804087FE800000208020803F8020803F80000 +AD0E:000000081F880088008E0088048804087FE80000110811081F0811141F620000 +AD0F:000000081F880088008E0088048804087FE80000001000100010006801840000 +AD10:000000081F880088008E0088048804087FE800000048004800A8011406620000 +AD11:000000081F880088008E0088048804087FE80000000003F00408040803F00000 +AD12:000000081F880088008E0088048804087FE8000003F80020002000D003080000 +AD13:000000081F880088008E0088048804087FE80000004003F8004000A003180000 +AD14:000000081F880088008E0088048804087FE8000003F8000803F8000800080000 +AD15:000000081F880088008E0088048804087FE8000003F8020003F8020003F80000 +AD16:000000081F880088008E0088048804087FE8000000000FF8022002200FF80000 +AD17:000000081F880088008E0088048804087FE8000000800FF803E0041003E00000 +AD18:00000000001200123FD200520052005E0452041204127FD20012001200120000 +AD19:000000281FA800A800B800A804A804287FA8000007F800080008000800080000 +AD1A:000000281FA800A800B800A804A804287FA8000000003EF80208020802080000 +AD1B:000000281FA800A800B800A804A804287FA8000000001F080108011401620000 +AD1C:000000281FA800A800B800A804A804287FA8000008000800080008000FF80000 +AD1D:000000281FA800A800B800A804A804287FA80000000010F8101010301ECC0000 +AD1E:000000281FA800A800B800A804A804287FA800000808087F081C08220F9C0000 +AD1F:000000281FA800A800B800A804A804287FA8000003F802000200020003F80000 +AD20:000000281FA800A800B800A804A804287FA8000007F8000807F8040007F80000 +AD21:000000281FA800A800B800A804A804287FA800003EF802083E0820083E080000 +AD22:000000281FA800A800B800A804A804287FA800003EF802883E8820883EF80000 +AD23:000000281FA800A800B800A804A804287FA800003E8802883EF820883EF80000 +AD24:000000281FA800A800B800A804A804287FA800001F0801081F0810141F620000 +AD25:000000281FA800A800B800A804A804287FA800003EF802803EF820803EF80000 +AD26:000000281FA800A800B800A804A804287FA800003EFC02483E4820483EFC0000 +AD27:000000281FA800A800B800A804A804287FA800001F08017F1F1C10221F1C0000 +AD28:000000281FA800A800B800A804A804287FA8000003F802080208020803F80000 +AD29:000000281FA800A800B800A804A804287FA800000208020803F8020803F80000 +AD2A:000000281FA800A800B800A804A804287FA80000110811081F0811141F620000 +AD2B:000000281FA800A800B800A804A804287FA80000001000100010006801840000 +AD2C:000000281FA800A800B800A804A804287FA800000048004800A8011406620000 +AD2D:000000281FA800A800B800A804A804287FA80000000003F00408040803F00000 +AD2E:000000281FA800A800B800A804A804287FA8000003F80020002000D003080000 +AD2F:000000281FA800A800B800A804A804287FA80000004003F8004000A003180000 +AD30:000000281FA800A800B800A804A804287FA8000003F8000803F8000800080000 +AD31:000000281FA800A800B800A804A804287FA8000003F8020003F8020003F80000 +AD32:000000281FA800A800B800A804A804287FA8000000000FF8022002200FF80000 +AD33:000000281FA800A800B800A804A804287FA8000000800FF803E0041003E00000 +AD34:00000000000400043FC40044004400440444040404047FF40004000400040000 +AD35:000000081F88008800880088048804087FE8000007F800080008000800080000 +AD36:000000081F88008800880088048804087FE8000000003EF80208020802080000 +AD37:000000081F88008800880088048804087FE8000000001F080108011401620000 +AD38:000000081F88008800880088048804087FE8000008000800080008000FF80000 +AD39:000000081F88008800880088048804087FE80000000010F8101010301ECC0000 +AD3A:000000081F88008800880088048804087FE800000808087F081C08220F9C0000 +AD3B:000000081F88008800880088048804087FE8000003F802000200020003F80000 +AD3C:000000081F88008800880088048804087FE8000007F8000807F8040007F80000 +AD3D:000000081F88008800880088048804087FE800003EF802083E0820083E080000 +AD3E:000000081F88008800880088048804087FE800003EF802883E8820883EF80000 +AD3F:000000081F88008800880088048804087FE800003E8802883EF820883EF80000 +AD40:000000081F88008800880088048804087FE800001F0801081F0810141F620000 +AD41:000000081F88008800880088048804087FE800003EF802803EF820803EF80000 +AD42:000000081F88008800880088048804087FE800003EFC02483E4820483EFC0000 +AD43:000000081F88008800880088048804087FE800001F08017F1F1C10221F1C0000 +AD44:000000081F88008800880088048804087FE8000003F802080208020803F80000 +AD45:000000081F88008800880088048804087FE800000208020803F8020803F80000 +AD46:000000081F88008800880088048804087FE80000110811081F0811141F620000 +AD47:000000081F88008800880088048804087FE80000001000100010006801840000 +AD48:000000081F88008800880088048804087FE800000048004800A8011406620000 +AD49:000000081F88008800880088048804087FE80000000003F00408040803F00000 +AD4A:000000081F88008800880088048804087FE8000003F80020002000D003080000 +AD4B:000000081F88008800880088048804087FE80000004003F8004000A003180000 +AD4C:000000081F88008800880088048804087FE8000003F8000803F8000800080000 +AD4D:000000081F88008800880088048804087FE8000003F8020003F8020003F80000 +AD4E:000000081F88008800880088048804087FE8000000000FF8022002200FF80000 +AD4F:000000081F88008800880088048804087FE8000000800FF803E0041003E00000 +AD50:00000000000000003FF0001000100010001008900880088008807FFC00000000 +AD51:000000001FF0001000100010049004807FFC00001FF000100010001000100000 +AD52:000000001FF0001000100010049004807FFC000000003EF80208020802080000 +AD53:000000001FF0001000100010049004807FFC000000001E100210022802C40000 +AD54:000000001FF0001000100010049004807FFC000000001000100010001FF00000 +AD55:000000001FF0001000100010049004807FFC0000000020F8201020303ECC0000 +AD56:000000001FF0001000100010049004807FFC0000202021FC207020883E700000 +AD57:000000001FF0001000100010049004807FFC00001FF01000100010001FF00000 +AD58:000000001FF0001000100010049004807FFC00001FF000101FF010001FF00000 +AD59:000000001FF0001000100010049004807FFC00003EF802083E0820083E080000 +AD5A:000000001FF0001000100010049004807FFC00003EF802883E8820883EF80000 +AD5B:000000001FF0001000100010049004807FFC00003E8802883EF820883EF80000 +AD5C:000000001FF0001000100010049004807FFC00003E1002103E1020283EC40000 +AD5D:000000001FF0001000100010049004807FFC00003EF802803EF820803EF80000 +AD5E:000000001FF0001000100010049004807FFC00003EFC02483E4820483EFC0000 +AD5F:000000001FF0001000100010049004807FFC00003E2003FC3E7020883E700000 +AD60:000000001FF0001000100010049004807FFC00001FF01010101010101FF00000 +AD61:000000001FF0001000100010049004807FFC0000101010101FF010101FF00000 +AD62:000000001FF0001000100010049004807FFC0000222022203E2022503E880000 +AD63:000000001FF0001000100010049004807FFC000000000100010002800C400000 +AD64:000000001FF0001000100010049004807FFC00000000024002400DA033100000 +AD65:000000001FF0001000100010049004807FFC0000000007C00820082007C00000 +AD66:000000001FF0001000100010049004807FFC0000000007E00080014006200000 +AD67:000000001FF0001000100010049004807FFC0000008007E00080014006200000 +AD68:000000001FF0001000100010049004807FFC00001FF000101FF0001000100000 +AD69:000000001FF0001000100010049004807FFC00001FF010001FF010001FF00000 +AD6A:000000001FF0001000100010049004807FFC000000001FF0044004401FF00000 +AD6B:000000001FF0001000100010049004807FFC000001001FF007C0082007C00000 +AD6C:0000000000003FE00020002000200020002000003FF801000100010001000000 +AD6D:000000001FF000100010001000007FFC010001001FF000100010001000100000 +AD6E:000000001FF000100010001000007FFC0100010000003EF80208020802080000 +AD6F:000000001FF000100010001000007FFC0100010000001E100210022802C40000 +AD70:000000001FF0001000100010000000007FFC010001001100100010001FF00000 +AD71:000000001FF000100010001000007FFC01000100000020F8201020303ECC0000 +AD72:000000001FF000100010001000007FFC01000100202021FC207020883E700000 +AD73:000000001FF000100010001000007FFC010001001FF01000100010001FF00000 +AD74:000000001FF000100010001000007FFC010001001FF000101FF010001FF00000 +AD75:000000001FF000100010001000007FFC010001003EF802083E0820083E080000 +AD76:000000001FF000100010001000007FFC010001003EF802883E8820883EF80000 +AD77:000000001FF000100010001000007FFC010001003E8802883EF820883EF80000 +AD78:000000001FF000100010001000007FFC010001003E1002103E1020283EC40000 +AD79:000000001FF000100010001000007FFC010001003EF802803EF820803EF80000 +AD7A:000000001FF000100010001000007FFC010001003EFC02483E4820483EFC0000 +AD7B:000000001FF000100010001000007FFC010001003E2003FC3E7020883E700000 +AD7C:000000001FF000100010001000007FFC010001001FF01010101010101FF00000 +AD7D:000000001FF000100010001000007FFC01000100101010101FF010101FF00000 +AD7E:000000001FF000100010001000007FFC01000100222022203E2022503E880000 +AD7F:000000001FF000100010001000007FFC0100010000000100010002800C400000 +AD80:000000001FF000100010001000007FFC010001000000024002400DA033100000 +AD81:000000001FF000100010001000007FFC01000100000007C00820082007C00000 +AD82:000000001FF000100010001000007FFC01000100000007E00080014006200000 +AD83:000000001FF000100010001000007FFC01000100008007E00080014006200000 +AD84:000000001FF000100010001000007FFC010001001FF000101FF0001000100000 +AD85:000000001FF000100010001000007FFC010001001FF010001FF010001FF00000 +AD86:000000001FF000100010001000007FFC0100010000001FF0044004401FF00000 +AD87:000000001FF000100010001000007FFC0100010001001FF007C0082007C00000 +AD88:00000008000800083FE8002800280028002800087FE8040804F8040804080000 +AD89:000800083F080108010801087FE8027802080000000007F80008000800080000 +AD8A:000800083F080108010801087FE802780208000000003EF80208020802080000 +AD8B:000800083F080108010801087FE802780208000000001F080108011401620000 +AD8C:000800083F0801080108010800087FE80278020802081000100010001FF80000 +AD8D:000800083F080108010801087FE8027802080000000020F8201020303ECC0000 +AD8E:000800083F080108010801087FE8027802080000202021FC207020883E700000 +AD8F:000800083F080108010801087FE802780208000003F802000200020003F80000 +AD90:000800083F080108010801087FE802780208000007F8000807F8040007F80000 +AD91:000800083F080108010801087FE80278020800003EF802083E0820083E080000 +AD92:000800083F080108010801087FE80278020800003EF802883E8820883EF80000 +AD93:000800083F080108010801087FE80278020800003E8802883EF820883EF80000 +AD94:000800083F080108010801087FE80278020800000F8800880F8808140FA20000 +AD95:000800083F080108010801087FE80278020800003EF802803EF820803EF80000 +AD96:000800083F080108010801087FE80278020800003EFC02483E4820483EFC0000 +AD97:000800083F080108010801087FE80278020800003E1002FE3E3820443E380000 +AD98:000800083F080108010801087FE802780208000003F802080208020803F80000 +AD99:000800083F080108010801087FE80278020800000208020803F8020803F80000 +AD9A:000800083F080108010801087FE8027802080000210821083F0821143F620000 +AD9B:000800083F080108010801087FE8027802080000001000100010006801840000 +AD9C:000800083F080108010801087FE80278020800000048004800A8011406620000 +AD9D:000800083F080108010801087FE8027802080000000003F00408040803F00000 +AD9E:000800083F080108010801087FE802780208000003F80020002000D003080000 +AD9F:000800083F080108010801087FE8027802080000004003F8004000A003180000 +ADA0:000800083F080108010801087FE802780208000003F8000803F8000800080000 +ADA1:000800083F080108010801087FE802780208000003F8020003F8020003F80000 +ADA2:000800083F080108010801087FE802780208000000000FF8022002200FF80000 +ADA3:000800083F080108010801087FE802780208000000800FF803E0041003E00000 +ADA4:0000000A000A000A3FEA002A002A002A002A000A7FEA040A047A040A040A0000 +ADA5:002800283F280128012801287FA805E804280000000007F80008000800080000 +ADA6:002800283F280128012801287FA805E80428000000003EF80208020802080000 +ADA7:002800283F280128012801287FA805E80428000000001F080108011401620000 +ADA8:002800283F2801280128012800287FA8042805E804281428100010001FF80000 +ADA9:002800283F280128012801287FA805E804280000000020F8201020303ECC0000 +ADAA:002800283F280128012801287FA805E804280000202021FC207020883E700000 +ADAB:002800283F280128012801287FA805E80428000003F802000200020003F80000 +ADAC:002800283F280128012801287FA805E80428000007F8000807F8040007F80000 +ADAD:002800283F280128012801287FA805E8042800003EF802083E0820083E080000 +ADAE:002800283F280128012801287FA805E8042800003EF802883E8820883EF80000 +ADAF:002800283F280128012801287FA805E8042800003E8802883EF820883EF80000 +ADB0:002800283F280128012801287FA805E8042800000F8800880F8808140FA20000 +ADB1:002800283F280128012801287FA805E8042800003EF802803EF820803EF80000 +ADB2:002800283F280128012801287FA805E8042800003EFC02483E4820483EFC0000 +ADB3:002800283F280128012801287FA805E8042800003E1002FE3E3820443E380000 +ADB4:002800283F280128012801287FA805E80428000003F802080208020803F80000 +ADB5:002800283F280128012801287FA805E8042800000208020803F8020803F80000 +ADB6:002800283F280128012801287FA805E804280000210821083F0821143F620000 +ADB7:002800283F280128012801287FA805E804280000001000100010006801840000 +ADB8:002800283F280128012801287FA805E8042800000048004800A8011406620000 +ADB9:002800283F280128012801287FA805E804280000000003F00408040803F00000 +ADBA:002800283F280128012801287FA805E80428000003F80020002000D003080000 +ADBB:002800283F280128012801287FA805E804280000004003F8004000A003180000 +ADBC:002800283F280128012801287FA805E80428000003F8000803F8000800080000 +ADBD:002800283F280128012801287FA805E80428000003F8020003F8020003F80000 +ADBE:002800283F280128012801287FA805E80428000000000FF8022002200FF80000 +ADBF:002800283F280128012801287FA805E80428000000800FF803E0041003E00000 +ADC0:00000008000800083FE8002800280028002800087FE804080408040804080000 +ADC1:000800083F080108010801087FE8020802000000000007F80008000800080000 +ADC2:000800083F080108010801087FE802080200000000003EF80208020802080000 +ADC3:000800083F080108010801087FE802080200000000001F080108011401620000 +ADC4:000800083F0801080108010800087FE80208020802081008100010001FF80000 +ADC5:000800083F080108010801087FE8020802000000000020F8201020303ECC0000 +ADC6:000800083F080108010801087FE8020802000000202021FC207020883E700000 +ADC7:000800083F080108010801087FE802080200000003F802000200020003F80000 +ADC8:000800083F080108010801087FE802080200000007F8000807F8040007F80000 +ADC9:000800083F080108010801087FE80208020000003EF802083E0820083E080000 +ADCA:000800083F080108010801087FE80208020000003EF802883E8820883EF80000 +ADCB:000800083F080108010801087FE80208020000003E8802883EF820883EF80000 +ADCC:000800083F080108010801087FE80208020000000F8800880F8808140FA20000 +ADCD:000800083F080108010801087FE80208020000003EF802803EF820803EF80000 +ADCE:000800083F080108010801087FE80208020000003EFC02483E4820483EFC0000 +ADCF:000800083F080108010801087FE80208020000003E1002FE3E3820443E380000 +ADD0:000800083F080108010801087FE802080200000003F802080208020803F80000 +ADD1:000800083F080108010801087FE80208020000000208020803F8020803F80000 +ADD2:000800083F080108010801087FE8020802000000210821083F0821143F620000 +ADD3:000800083F080108010801087FE8020802000000001000100010006801840000 +ADD4:000800083F080108010801087FE80208020000000048004800A8011406620000 +ADD5:000800083F080108010801087FE8020802000000000003F00408040803F00000 +ADD6:000800083F080108010801087FE802080200000003F80020002000D003080000 +ADD7:000800083F080108010801087FE8020802000000004003F8004000A003180000 +ADD8:000800083F080108010801087FE802080200000003F8000803F8000800080000 +ADD9:000800083F080108010801087FE802080200000003F8020003F8020003F80000 +ADDA:000800083F080108010801087FE802080200000000000FF8022002200FF80000 +ADDB:000800083F080108010801087FE802080200000000800FF803E0041003E00000 +ADDC:0000000000003FE00020002000200020002000007FFC04400440044004400000 +ADDD:000000001FF000100010001000007FFC044004401FF000100010001000100000 +ADDE:000000001FF000100010001000007FFC0440044000003EF80208020802080000 +ADDF:000000001FF000100010001000007FFC0440044000001E100210022802C40000 +ADE0:000000001FF0001000100010000000007FFC044004401440100010001FF00000 +ADE1:000000001FF000100010001000007FFC04400440000020F8201020303ECC0000 +ADE2:000000001FF000100010001000007FFC04400440202021FC207020883E700000 +ADE3:000000001FF000100010001000007FFC044004401FF01000100010001FF00000 +ADE4:000000001FF000100010001000007FFC044004401FF000101FF010001FF00000 +ADE5:000000001FF000100010001000007FFC044004403EF802083E0820083E080000 +ADE6:000000001FF000100010001000007FFC044004403EF802883E8820883EF80000 +ADE7:000000001FF000100010001000007FFC044004403E8802883EF820883EF80000 +ADE8:000000001FF000100010001000007FFC044004403E1002103E1020283EC40000 +ADE9:000000001FF000100010001000007FFC044004403EF802803EF820803EF80000 +ADEA:000000001FF000100010001000007FFC044004403EFC02483E4820483EFC0000 +ADEB:000000001FF000100010001000007FFC044004403E2003FC3E7020883E700000 +ADEC:000000001FF000100010001000007FFC044004401FF01010101010101FF00000 +ADED:000000001FF000100010001000007FFC04400440101010101FF010101FF00000 +ADEE:000000001FF000100010001000007FFC04400440222022203E2022503E880000 +ADEF:000000001FF000100010001000007FFC0440044000000100010002800C400000 +ADF0:000000001FF000100010001000007FFC044004400000024002400DA033100000 +ADF1:000000001FF000100010001000007FFC04400440000007C00820082007C00000 +ADF2:000000001FF000100010001000007FFC04400440000007E00080014006200000 +ADF3:000000001FF000100010001000007FFC04400440008007E00080014006200000 +ADF4:000000001FF000100010001000007FFC044004401FF000101FF0001000100000 +ADF5:000000001FF000100010001000007FFC044004401FF010001FF010001FF00000 +ADF6:000000001FF000100010001000007FFC0440044000001FF0044004401FF00000 +ADF7:000000001FF000100010001000007FFC0440044001001FF007C0082007C00000 +ADF8:00000000000000003FF00010001000100010001000007FFC0000000000000000 +ADF9:000000001FF0001000100010001000007FFC00001FF000100010001000100000 +ADFA:000000001FF0001000100010001000007FFC000000003EF80208020802080000 +ADFB:000000001FF0001000100010001000007FFC000000001E100210022802C40000 +ADFC:000000001FF0001000100010001000007FFC000000001000100010001FF00000 +ADFD:000000001FF0001000100010001000007FFC0000000020F8201020303ECC0000 +ADFE:000000001FF0001000100010001000007FFC0000202021FC207020883E700000 +ADFF:000000001FF0001000100010001000007FFC00001FF01000100010001FF00000 +AE00:000000001FF0001000100010001000007FFC00001FF000101FF010001FF00000 +AE01:000000001FF0001000100010001000007FFC00003EF802083E0820083E080000 +AE02:000000001FF0001000100010001000007FFC00003EF802883E8820883EF80000 +AE03:000000001FF0001000100010001000007FFC00003E8802883EF820883EF80000 +AE04:000000001FF0001000100010001000007FFC00003E1002103E1020283EC40000 +AE05:000000001FF0001000100010001000007FFC00003EF802803EF820803EF80000 +AE06:000000001FF0001000100010001000007FFC00003EFC02483E4820483EFC0000 +AE07:000000001FF0001000100010001000007FFC00003E2003FC3E7020883E700000 +AE08:000000001FF0001000100010001000007FFC00001FF01010101010101FF00000 +AE09:000000001FF0001000100010001000007FFC0000101010101FF010101FF00000 +AE0A:000000001FF0001000100010001000007FFC0000222022203E2022503E880000 +AE0B:000000001FF0001000100010001000007FFC000000000100010002800C400000 +AE0C:000000001FF0001000100010001000007FFC00000000024002400DA033100000 +AE0D:000000001FF0001000100010001000007FFC0000000007C00820082007C00000 +AE0E:000000001FF0001000100010001000007FFC0000000007E00080014006200000 +AE0F:000000001FF0001000100010001000007FFC0000008007E00080014006200000 +AE10:000000001FF0001000100010001000007FFC00001FF000101FF0001000100000 +AE11:000000001FF0001000100010001000007FFC00001FF010001FF010001FF00000 +AE12:000000001FF0001000100010001000007FFC000000001FF0044004401FF00000 +AE13:000000001FF0001000100010001000007FFC000001001FF007C0082007C00000 +AE14:00000000000800083FC80048004800480048000800087FE80008000800080000 +AE15:000000081F88008800880088008800087FE8000007F800080008000800080000 +AE16:000000081F88008800880088008800087FE8000000003EF80208020802080000 +AE17:000000081F88008800880088008800087FE8000000001F080108011401620000 +AE18:000000081F88008800880088008800087FE8000008000800080008000FF80000 +AE19:000000081F88008800880088008800087FE80000000010F8101010301ECC0000 +AE1A:000000081F88008800880088008800087FE800000808087F081C08220F9C0000 +AE1B:000000081F88008800880088008800087FE8000003F802000200020003F80000 +AE1C:000000081F88008800880088008800087FE8000007F8000807F8040007F80000 +AE1D:000000081F88008800880088008800087FE800003EF802083E0820083E080000 +AE1E:000000081F88008800880088008800087FE800003EF802883E8820883EF80000 +AE1F:000000081F88008800880088008800087FE800003E8802883EF820883EF80000 +AE20:000000081F88008800880088008800087FE800001F0801081F0810141F620000 +AE21:000000081F88008800880088008800087FE800003EF802803EF820803EF80000 +AE22:000000081F88008800880088008800087FE800003EFC02483E4820483EFC0000 +AE23:000000081F88008800880088008800087FE800001F08017F1F1C10221F1C0000 +AE24:000000081F88008800880088008800087FE8000003F802080208020803F80000 +AE25:000000081F88008800880088008800087FE800000208020803F8020803F80000 +AE26:000000081F88008800880088008800087FE80000110811081F0811141F620000 +AE27:000000081F88008800880088008800087FE80000001000100010006801840000 +AE28:000000081F88008800880088008800087FE800000048004800A8011406620000 +AE29:000000081F88008800880088008800087FE80000000003F00408040803F00000 +AE2A:000000081F88008800880088008800087FE8000003F80020002000D003080000 +AE2B:000000081F88008800880088008800087FE80000004003F8004000A003180000 +AE2C:000000081F88008800880088008800087FE8000003F8000803F8000800080000 +AE2D:000000081F88008800880088008800087FE8000003F8020003F8020003F80000 +AE2E:000000081F88008800880088008800087FE8000000000FF8022002200FF80000 +AE2F:000000081F88008800880088008800087FE8000000800FF803E0041003E00000 +AE30:00000000000800081F8800880088008801080108020804081808000800080000 +AE31:000000083E080208020804080808300800080000000007F80008000800080000 +AE32:000000083E08020802080408080830080008000000003EF80208020802080000 +AE33:000000083E08020802080408080830080008000000001F080108011401620000 +AE34:000000083E08020802080408080830080008000800001000100010001FF80000 +AE35:000000083E080208020804080808300800080000000020F8201020303ECC0000 +AE36:000000083E080208020804080808300800080000202021FC207020883E700000 +AE37:000000083E08020802080408080830080008000003F802000200020003F80000 +AE38:000000083E08020802080408080830080008000007F8000807F8040007F80000 +AE39:000000083E0802080208040808083008000800003EF802083E0820083E080000 +AE3A:000000083E0802080208040808083008000800003EF802883E8820883EF80000 +AE3B:000000083E0802080208040808083008000800003E8802883EF820883EF80000 +AE3C:000000083E0802080208040808083008000800000F8800880F8808140FA20000 +AE3D:000000083E0802080208040808083008000800003EF802803EF820803EF80000 +AE3E:000000083E0802080208040808083008000800003EFC02483E4820483EFC0000 +AE3F:000000083E0802080208040808083008000800003E1002FE3E3820443E380000 +AE40:000000083E08020802080408080830080008000003F802080208020803F80000 +AE41:000000083E0802080208040808083008000800000208020803F8020803F80000 +AE42:000000083E080208020804080808300800080000210821083F0821143F620000 +AE43:000000083E080208020804080808300800080000001000100010006801840000 +AE44:000000083E0802080208040808083008000800000048004800A8011406620000 +AE45:000000083E080208020804080808300800080000000003F00408040803F00000 +AE46:000000083E08020802080408080830080008000003F80020002000D003080000 +AE47:000000083E080208020804080808300800080000004003F8004000A003180000 +AE48:000000083E08020802080408080830080008000003F8000803F8000800080000 +AE49:000000083E08020802080408080830080008000003F8020003F8020003F80000 +AE4A:000000083E08020802080408080830080008000000000FF8022002200FF80000 +AE4B:000000083E08020802080408080830080008000000800FF803E0041003E00000 +AE4C:00000000001000107B9008900890089E11101110221044100810001000100000 +AE4D:00000008F78810881088108E2108C6080008000007F800080008000800080000 +AE4E:00000008F78810881088108E2108C6080008000000003EF80208020802080000 +AE4F:00000008F78810881088108E2108C6080008000000001F080108011401620000 +AE50:00000008F78810881088108E2108C6080008000808000800080008000FF80000 +AE51:00000008F78810881088108E2108C60800080000000010F8101010301ECC0000 +AE52:00000008F78810881088108E2108C608000800000808087F081C08220F9C0000 +AE53:00000008F78810881088108E2108C6080008000003F802000200020003F80000 +AE54:00000008F78810881088108E2108C6080008000007F8000807F8040007F80000 +AE55:00000008F78810881088108E2108C608000800003EF802083E0820083E080000 +AE56:00000008F78810881088108E2108C608000800003EF802883E8820883EF80000 +AE57:00000008F78810881088108E2108C608000800003E8802883EF820883EF80000 +AE58:00000008F78810881088108E2108C608000800001F0801081F0810141F620000 +AE59:00000008F78810881088108E2108C608000800003EF802803EF820803EF80000 +AE5A:00000008F78810881088108E2108C608000800003EFC02483E4820483EFC0000 +AE5B:00000008F78810881088108E2108C608000800001F08017F1F1C10221F1C0000 +AE5C:00000008F78810881088108E2108C6080008000003F802080208020803F80000 +AE5D:00000008F78810881088108E2108C608000800000208020803F8020803F80000 +AE5E:00000008F78810881088108E2108C60800080000110811081F0811141F620000 +AE5F:00000008F78810881088108E2108C60800080000001000100010006801840000 +AE60:00000008F78810881088108E2108C608000800000048004800A8011406620000 +AE61:00000008F78810881088108E2108C60800080000000003F00408040803F00000 +AE62:00000008F78810881088108E2108C6080008000003F80020002000D003080000 +AE63:00000008F78810881088108E2108C60800080000004003F8004000A003180000 +AE64:00000008F78810881088108E2108C6080008000003F8000803F8000800080000 +AE65:00000008F78810881088108E2108C6080008000003F8020003F8020003F80000 +AE66:00000008F78810881088108E2108C6080008000000000FF8022002200FF80000 +AE67:00000008F78810881088108E2108C6080008000000800FF803E0041003E00000 +AE68:00000000001200127B9208920892089E11121112221244120812001200120000 +AE69:00000028F7A810A810A810B82128C6280028000007F800080008000800080000 +AE6A:00000028F7A810A810A810B82128C6280028000000003EF80208020802080000 +AE6B:00000028F7A810A810A810B82128C6280028000000003E100210022802C40000 +AE6C:00000028F7A810A810A810B82128C6280028002808000800080008000FF80000 +AE6D:00000028F7A810A810A810B82128C62800280000000020F8201020303ECC0000 +AE6E:00000028F7A810A810A810B82128C62800280000202021FC207020883E700000 +AE6F:00000028F7A810A810A810B82128C6280028000003F802000200020003F80000 +AE70:00000028F7A810A810A810B82128C6280028000007F8000807F8040007F80000 +AE71:00000028F7A810A810A810B82128C628002800003EF802083E0820083E080000 +AE72:00000028F7A810A810A810B82128C628002800003EF802883E8820883EF80000 +AE73:00000028F7A810A810A810B82128C628002800003E8802883EF820883EF80000 +AE74:00000028F7A810A810A810B82128C628002800001F0801081F0810141F620000 +AE75:00000028F7A810A810A810B82128C628002800003EF802803EF820803EF80000 +AE76:00000028F7A810A810A810B82128C628002800003EFC02483E4820483EFC0000 +AE77:00000028F7A810A810A810B82128C628002800003E1002FE3E3820443E380000 +AE78:00000028F7A810A810A810B82128C6280028000003F802080208020803F80000 +AE79:00000028F7A810A810A810B82128C628002800000208020803F8020803F80000 +AE7A:00000028F7A810A810A810B82128C62800280000110811081F0811141F620000 +AE7B:00000028F7A810A810A810B82128C62800280000000800080008003400C20000 +AE7C:00000028F7A810A810A810B82128C628002800000048004800A8011406620000 +AE7D:00000028F7A810A810A810B82128C62800280000000001F00208020801F00000 +AE7E:00000028F7A810A810A810B82128C6280028000003F80020002000D003080000 +AE7F:00000028F7A810A810A810B82128C62800280000004003F8004000A003180000 +AE80:00000028F7A810A810A810B82128C6280028000003F8000803F8000800080000 +AE81:00000028F7A810A810A810B82128C6280028000003F8020003F8020003F80000 +AE82:00000028F7A810A810A810B82128C6280028000000000FF8022002200FF80000 +AE83:00000028F7A810A810A810B82128C6280028000000800FF803E0041003E00000 +AE84:00000000001000107B900890089E08901110111E221044100810001000100000 +AE85:00000008F7881088108E1088210EC6080008000007F800080008000800080000 +AE86:00000008F7881088108E1088210EC6080008000000003EF80208020802080000 +AE87:00000008F7881088108E1088210EC6080008000000001F080108011401620000 +AE88:00000008F7881088108E1088210EC6080008000008000800080008000FF80000 +AE89:00000008F7881088108E1088210EC60800080000000010F8101010301ECC0000 +AE8A:00000008F7881088108E1088210EC608000800000808087F081C08220F9C0000 +AE8B:00000008F7881088108E1088210EC6080008000003F802000200020003F80000 +AE8C:00000008F7881088108E1088210EC6080008000007F8000807F8040007F80000 +AE8D:00000008F7881088108E1088210EC608000800003EF802083E0820083E080000 +AE8E:00000008F7881088108E1088210EC608000800003EF802883E8820883EF80000 +AE8F:00000008F7881088108E1088210EC608000800003E8802883EF820883EF80000 +AE90:00000008F7881088108E1088210EC608000800001F0801081F0810141F620000 +AE91:00000008F7881088108E1088210EC608000800003EF802803EF820803EF80000 +AE92:00000008F7881088108E1088210EC608000800003EFC02483E4820483EFC0000 +AE93:00000008F7881088108E1088210EC608000800001F08017F1F1C10221F1C0000 +AE94:00000008F7881088108E1088210EC6080008000003F802080208020803F80000 +AE95:00000008F7881088108E1088210EC608000800000208020803F8020803F80000 +AE96:00000008F7881088108E1088210EC60800080000110811081F0811141F620000 +AE97:00000008F7881088108E1088210EC60800080000001000100010006801840000 +AE98:00000008F7881088108E1088210EC608000800000048004800A8011406620000 +AE99:00000008F7881088108E1088210EC60800080000000003F00408040803F00000 +AE9A:00000008F7881088108E1088210EC6080008000003F80020002000D003080000 +AE9B:00000008F7881088108E1088210EC60800080000004003F8004000A003180000 +AE9C:00000008F7881088108E1088210EC6080008000003F8000803F8000800080000 +AE9D:00000008F7881088108E1088210EC6080008000003F8020003F8020003F80000 +AE9E:00000008F7881088108E1088210EC6080008000000000FF8022002200FF80000 +AE9F:00000008F7881088108E1088210EC6080008000000800FF803E0041003E00000 +AEA0:00000000001200127B920892089E08921112111E221244120812001200120000 +AEA1:00000028F7A810A810B810A82138C6280028000007F800080008000800080000 +AEA2:00000028F7A810A810B810A82138C6280028000000003EF80208020802080000 +AEA3:00000028F7A810A810B810A82138C6280028000000003E100210022802C40000 +AEA4:00000028F7A810A810B810A82138C6280028002808000800080008000FF80000 +AEA5:00000028F7A810A810B810A82138C62800280000000020F8201020303ECC0000 +AEA6:00000028F7A810A810B810A82138C62800280000202021FC207020883E700000 +AEA7:00000028F7A810A810B810A82138C6280028000003F802000200020003F80000 +AEA8:00000028F7A810A810B810A82138C6280028000007F8000807F8040007F80000 +AEA9:00000028F7A810A810B810A82138C628002800003EF802083E0820083E080000 +AEAA:00000028F7A810A810B810A82138C628002800003EF802883E8820883EF80000 +AEAB:00000028F7A810A810B810A82138C628002800003E8802883EF820883EF80000 +AEAC:00000028F7A810A810B810A82138C628002800001F0801081F0810141F620000 +AEAD:00000028F7A810A810B810A82138C628002800003EF802803EF820803EF80000 +AEAE:00000028F7A810A810B810A82138C628002800003EFC02483E4820483EFC0000 +AEAF:00000028F7A810A810B810A82138C628002800003E1002FE3E3820443E380000 +AEB0:00000028F7A810A810B810A82138C6280028000003F802080208020803F80000 +AEB1:00000028F7A810A810B810A82138C628002800000208020803F8020803F80000 +AEB2:00000028F7A810A810B810A82138C62800280000110811081F0811141F620000 +AEB3:00000028F7A810A810B810A82138C62800280000000800080008003400C20000 +AEB4:00000028F7A810A810B810A82138C628002800000048004800A8011406620000 +AEB5:00000028F7A810A810B810A82138C62800280000000001F00208020801F00000 +AEB6:00000028F7A810A810B810A82138C6280028000003F80020002000D003080000 +AEB7:00000028F7A810A810B810A82138C62800280000004003F8004000A003180000 +AEB8:00000028F7A810A810B810A82138C6280028000003F8000803F8000800080000 +AEB9:00000028F7A810A810B810A82138C6280028000003F8020003F8020003F80000 +AEBA:00000028F7A810A810B810A82138C6280028000000000FF8022002200FF80000 +AEBB:00000028F7A810A810B810A82138C6280028000000800FF803E0041003E00000 +AEBC:00000000000200027B8208820882089E11021102220244020802000200020000 +AEBD:00000008F7881088108810B82108C60800080000000007F80008000800080000 +AEBE:00000008F7881088108810B82108C6080008000000003EF80208020802080000 +AEBF:00000008F7881088108810B82108C6080008000000001F080108011401620000 +AEC0:00000008F7881088108810B82108C6080008000000001000100010001FF80000 +AEC1:00000008F7881088108810B82108C60800080000000020F8201020303ECC0000 +AEC2:00000008F7881088108810B82108C60800080000202021FC207020883E700000 +AEC3:00000008F7881088108810B82108C6080008000003F802000200020003F80000 +AEC4:00000008F7881088108810B82108C6080008000007F8000807F8040007F80000 +AEC5:00000008F7881088108810B82108C608000800003EF802083E0820083E080000 +AEC6:00000008F7881088108810B82108C608000800003EF802883E8820883EF80000 +AEC7:00000008F7881088108810B82108C608000800003E8802883EF820883EF80000 +AEC8:00000008F7881088108810B82108C608000800000F8800880F8808140FA20000 +AEC9:00000008F7881088108810B82108C608000800003EF802803EF820803EF80000 +AECA:00000008F7881088108810B82108C608000800003EFC02483E4820483EFC0000 +AECB:00000008F7881088108810B82108C608000800003E1002FE3E3820443E380000 +AECC:00000008F7881088108810B82108C6080008000003F802080208020803F80000 +AECD:00000008F7881088108810B82108C608000800000208020803F8020803F80000 +AECE:00000008F7881088108810B82108C60800080000210821083F0821143F620000 +AECF:00000008F7881088108810B82108C60800080000001000100010006801840000 +AED0:00000008F7881088108810B82108C608000800000048004800A8011406620000 +AED1:00000008F7881088108810B82108C60800080000000003F00408040803F00000 +AED2:00000008F7881088108810B82108C6080008000003F80020002000D003080000 +AED3:00000008F7881088108810B82108C60800080000004003F8004000A003180000 +AED4:00000008F7881088108810B82108C6080008000003F8000803F8000800080000 +AED5:00000008F7881088108810B82108C6080008000003F8020003F8020003F80000 +AED6:00000008F7881088108810B82108C6080008000000000FF8022002200FF80000 +AED7:00000008F7881088108810B82108C6080008000000800FF803E0041003E00000 +AED8:00000000000A000A7B8A088A088A08BA110A110A220A440A080A000A000A0000 +AED9:00000028F7A810A810A810E82128C6280028000007F800080008000800080000 +AEDA:00000028F7A810A810A810E82128C6280028000000003EF80208020802080000 +AEDB:00000028F7A810A810A810E82128C6280028000000003E100210022802C40000 +AEDC:00000028F7A810A810A810E82128C6280028000008000800080008000FF80000 +AEDD:00000028F7A810A810A810E82128C62800280000000020F8201020303ECC0000 +AEDE:00000028F7A810A810A810E82128C62800280000202021FC207020883E700000 +AEDF:00000028F7A810A810A810E82128C6280028000003F802000200020003F80000 +AEE0:00000028F7A810A810A810E82128C6280028000007F8000807F8040007F80000 +AEE1:00000028F7A810A810A810E82128C628002800003EF802083E0820083E080000 +AEE2:00000028F7A810A810A810E82128C628002800003EF802883E8820883EF80000 +AEE3:00000028F7A810A810A810E82128C628002800003E8802883EF820883EF80000 +AEE4:00000028F7A810A810A810E82128C628002800001F0801081F0810141F620000 +AEE5:00000028F7A810A810A810E82128C628002800003EF802803EF820803EF80000 +AEE6:00000028F7A810A810A810E82128C628002800003EFC02483E4820483EFC0000 +AEE7:00000028F7A810A810A810E82128C628002800003E1002FE3E3820443E380000 +AEE8:00000028F7A810A810A810E82128C6280028000003F802080208020803F80000 +AEE9:00000028F7A810A810A810E82128C628002800000208020803F8020803F80000 +AEEA:00000028F7A810A810A810E82128C62800280000110811081F0811141F620000 +AEEB:00000028F7A810A810A810E82128C62800280000000800080008003400C20000 +AEEC:00000028F7A810A810A810E82128C628002800000048004800A8011406620000 +AEED:00000028F7A810A810A810E82128C62800280000000001F00208020801F00000 +AEEE:00000028F7A810A810A810E82128C6280028000003F80020002000D003080000 +AEEF:00000028F7A810A810A810E82128C62800280000004003F8004000A003180000 +AEF0:00000028F7A810A810A810E82128C6280028000003F8000803F8000800080000 +AEF1:00000028F7A810A810A810E82128C6280028000003F8020003F8020003F80000 +AEF2:00000028F7A810A810A810E82128C6280028000000000FF8022002200FF80000 +AEF3:00000028F7A810A810A810E82128C6280028000000800FF803E0041003E00000 +AEF4:00000000000200027B820882089E08821102111E220244020802000200020000 +AEF5:00000008F788108810B810882138C60800080000000007F80008000800080000 +AEF6:00000008F788108810B810882138C6080008000000003EF80208020802080000 +AEF7:00000008F788108810B810882138C6080008000000001F080108011401620000 +AEF8:00000008F788108810B810882138C6080008000800001000100010001FF80000 +AEF9:00000008F788108810B810882138C60800080000000020F8201020303ECC0000 +AEFA:00000008F788108810B810882138C60800080000202021FC207020883E700000 +AEFB:00000008F788108810B810882138C6080008000003F802000200020003F80000 +AEFC:00000008F788108810B810882138C6080008000007F8000807F8040007F80000 +AEFD:00000008F788108810B810882138C608000800003EF802083E0820083E080000 +AEFE:00000008F788108810B810882138C608000800003EF802883E8820883EF80000 +AEFF:00000008F788108810B810882138C608000800003E8802883EF820883EF80000 +AF00:00000008F788108810B810882138C608000800000F8800880F8808140FA20000 +AF01:00000008F788108810B810882138C608000800003EF802803EF820803EF80000 +AF02:00000008F788108810B810882138C608000800003EFC02483E4820483EFC0000 +AF03:00000008F788108810B810882138C608000800003E1002FE3E3820443E380000 +AF04:00000008F788108810B810882138C6080008000003F802080208020803F80000 +AF05:00000008F788108810B810882138C608000800000208020803F8020803F80000 +AF06:00000008F788108810B810882138C60800080000210821083F0821143F620000 +AF07:00000008F788108810B810882138C60800080000001000100010006801840000 +AF08:00000008F788108810B810882138C608000800000048004800A8011406620000 +AF09:00000008F788108810B810882138C60800080000000003F00408040803F00000 +AF0A:00000008F788108810B810882138C6080008000003F80020002000D003080000 +AF0B:00000008F788108810B810882138C60800080000004003F8004000A003180000 +AF0C:00000008F788108810B810882138C6080008000003F8000803F8000800080000 +AF0D:00000008F788108810B810882138C6080008000003F8020003F8020003F80000 +AF0E:00000008F788108810B810882138C6080008000000000FF8022002200FF80000 +AF0F:00000008F788108810B810882138C6080008000000800FF803E0041003E00000 +AF10:00000000000A000A7B8A088A08BA088A110A113A220A440A080A000A000A0000 +AF11:00000028F7A810A810E810A821E8C6280028000007F800080008000800080000 +AF12:00000028F7A810A810E810A821E8C6280028000000003EF80208020802080000 +AF13:00000028F7A810A810E810A821E8C6280028000000003E100210022802C40000 +AF14:00000028F7A810A810E810A821E8C6280028002808000800080008000FF80000 +AF15:00000028F7A810A810E810A821E8C62800280000000020F8201020303ECC0000 +AF16:00000028F7A810A810E810A821E8C62800280000202021FC207020883E700000 +AF17:00000028F7A810A810E810A821E8C6280028000003F802000200020003F80000 +AF18:00000028F7A810A810E810A821E8C6280028000007F8000807F8040007F80000 +AF19:00000028F7A810A810E810A821E8C628002800003EF802083E0820083E080000 +AF1A:00000028F7A810A810E810A821E8C628002800003EF802883E8820883EF80000 +AF1B:00000028F7A810A810E810A821E8C628002800003E8802883EF820883EF80000 +AF1C:00000028F7A810A810E810A821E8C628002800001F0801081F0810141F620000 +AF1D:00000028F7A810A810E810A821E8C628002800003EF802803EF820803EF80000 +AF1E:00000028F7A810A810E810A821E8C628002800003EFC02483E4820483EFC0000 +AF1F:00000028F7A810A810E810A821E8C628002800003E1002FE3E3820443E380000 +AF20:00000028F7A810A810E810A821E8C6280028000003F802080208020803F80000 +AF21:00000028F7A810A810E810A821E8C628002800000208020803F8020803F80000 +AF22:00000028F7A810A810E810A821E8C62800280000110811081F0811141F620000 +AF23:00000028F7A810A810E810A821E8C62800280000000800080008003400C20000 +AF24:00000028F7A810A810E810A821E8C628002800000048004800A8011406620000 +AF25:00000028F7A810A810E810A821E8C62800280000000001F00208020801F00000 +AF26:00000028F7A810A810E810A821E8C6280028000003F80020002000D003080000 +AF27:00000028F7A810A810E810A821E8C62800280000004003F8004000A003180000 +AF28:00000028F7A810A810E810A821E8C6280028000003F8000803F8000800080000 +AF29:00000028F7A810A810E810A821E8C6280028000003F8020003F8020003F80000 +AF2A:00000028F7A810A810E810A821E8C6280028000000000FF8022002200FF80000 +AF2B:00000028F7A810A810E810A821E8C6280028000000800FF803E0041003E00000 +AF2C:00000000000000003EF8020802080208020800000100010001007FFC00000000 +AF2D:000000003EF8020802080208010001007FFC00001FF000100010001000100000 +AF2E:000000003EF8020802080208010001007FFC000000003EF80208020802080000 +AF2F:000000003EF8020802080208010001007FFC000000001E100210022802C40000 +AF30:000000003EF8020802080208010001007FFC000000001000100010001FF00000 +AF31:000000003EF8020802080208010001007FFC0000000020F8201020303ECC0000 +AF32:000000003EF8020802080208010001007FFC0000202021FC207020883E700000 +AF33:000000003EF8020802080208010001007FFC00001FF01000100010001FF00000 +AF34:000000003EF8020802080208010001007FFC00001FF000101FF010001FF00000 +AF35:000000003EF8020802080208010001007FFC00003EF802083E0820083E080000 +AF36:000000003EF8020802080208010001007FFC00003EF802883E8820883EF80000 +AF37:000000003EF8020802080208010001007FFC00003E8802883EF820883EF80000 +AF38:000000003EF8020802080208010001007FFC00003E1002103E1020283EC40000 +AF39:000000003EF8020802080208010001007FFC00003EF802803EF820803EF80000 +AF3A:000000003EF8020802080208010001007FFC00003EFC02483E4820483EFC0000 +AF3B:000000003EF8020802080208010001007FFC00003E2003FC3E7020883E700000 +AF3C:000000003EF8020802080208010001007FFC00001FF01010101010101FF00000 +AF3D:000000003EF8020802080208010001007FFC0000101010101FF010101FF00000 +AF3E:000000003EF8020802080208010001007FFC0000222022203E2022503E880000 +AF3F:000000003EF8020802080208010001007FFC000000000100010002800C400000 +AF40:000000003EF8020802080208010001007FFC00000000024002400DA033100000 +AF41:000000003EF8020802080208010001007FFC0000000007C00820082007C00000 +AF42:000000003EF8020802080208010001007FFC0000000007E00080014006200000 +AF43:000000003EF8020802080208010001007FFC0000008007E00080014006200000 +AF44:000000003EF8020802080208010001007FFC00001FF000101FF0001000100000 +AF45:000000003EF8020802080208010001007FFC00001FF010001FF010001FF00000 +AF46:000000003EF8020802080208010001007FFC000000001FF0044004401FF00000 +AF47:000000003EF8020802080208010001007FFC000001001FF007C0082007C00000 +AF48:00000010001000107BD008500850085E08500010041004107FD0001000100000 +AF49:00000008F7881088108E1088148804087FE8000007F800080008000800080000 +AF4A:00000008F7881088108E1088148804087FE8000000003EF80208020802080000 +AF4B:00000008F7881088108E1088148804087FE8000000001F080108011401620000 +AF4C:00000008F7881088108E1088148804087FE8000008000800080008000FF80000 +AF4D:00000008F7881088108E1088148804087FE80000000010F8101010301ECC0000 +AF4E:00000008F7881088108E1088148804087FE800000808087F081C08220F9C0000 +AF4F:00000008F7881088108E1088148804087FE8000003F802000200020003F80000 +AF50:00000008F7881088108E1088148804087FE8000007F8000807F8040007F80000 +AF51:00000008F7881088108E1088148804087FE800003EF802083E0820083E080000 +AF52:00000008F7881088108E1088148804087FE800003EF802883E8820883EF80000 +AF53:00000008F7881088108E1088148804087FE800003E8802883EF820883EF80000 +AF54:00000008F7881088108E1088148804087FE800001F0801081F0810141F620000 +AF55:00000008F7881088108E1088148804087FE800003EF802803EF820803EF80000 +AF56:00000008F7881088108E1088148804087FE800003EFC02483E4820483EFC0000 +AF57:00000008F7881088108E1088148804087FE800001F08017F1F1C10221F1C0000 +AF58:00000008F7881088108E1088148804087FE8000003F802080208020803F80000 +AF59:00000008F7881088108E1088148804087FE800000208020803F8020803F80000 +AF5A:00000008F7881088108E1088148804087FE80000110811081F0811141F620000 +AF5B:00000008F7881088108E1088148804087FE80000001000100010006801840000 +AF5C:00000008F7881088108E1088148804087FE800000048004800A8011406620000 +AF5D:00000008F7881088108E1088148804087FE80000000003F00408040803F00000 +AF5E:00000008F7881088108E1088148804087FE8000003F80020002000D003080000 +AF5F:00000008F7881088108E1088148804087FE80000004003F8004000A003180000 +AF60:00000008F7881088108E1088148804087FE8000003F8000803F8000800080000 +AF61:00000008F7881088108E1088148804087FE8000003F8020003F8020003F80000 +AF62:00000008F7881088108E1088148804087FE8000000000FF8022002200FF80000 +AF63:00000008F7881088108E1088148804087FE8000000800FF803E0041003E00000 +AF64:00000012001200127BD208520852085E08520012041204127FD2001200120000 +AF65:00000028F7A810A810B810A814A804287FA8000007F800080008000800080000 +AF66:00000028F7A810A810B810A814A804287FA8000000003EF80208020802080000 +AF67:00000028F7A810A810B810A814A804287FA8000000001F080108011401620000 +AF68:00000028F7A810A810B810A814A804287FA8000008000800080008000FF80000 +AF69:00000028F7A810A810B810A814A804287FA80000000010F8101010301ECC0000 +AF6A:00000028F7A810A810B810A814A804287FA800000808087F081C08220F9C0000 +AF6B:00000028F7A810A810B810A814A804287FA8000003F802000200020003F80000 +AF6C:00000028F7A810A810B810A814A804287FA8000007F8000807F8040007F80000 +AF6D:00000028F7A810A810B810A814A804287FA800003EF802083E0820083E080000 +AF6E:00000028F7A810A810B810A814A804287FA800003EF802883E8820883EF80000 +AF6F:00000028F7A810A810B810A814A804287FA800003E8802883EF820883EF80000 +AF70:00000028F7A810A810B810A814A804287FA800001F0801081F0810141F620000 +AF71:00000028F7A810A810B810A814A804287FA800003EF802803EF820803EF80000 +AF72:00000028F7A810A810B810A814A804287FA800003EFC02483E4820483EFC0000 +AF73:00000028F7A810A810B810A814A804287FA800001F08017F1F1C10221F1C0000 +AF74:00000028F7A810A810B810A814A804287FA8000003F802080208020803F80000 +AF75:00000028F7A810A810B810A814A804287FA800000208020803F8020803F80000 +AF76:00000028F7A810A810B810A814A804287FA80000110811081F0811141F620000 +AF77:00000028F7A810A810B810A814A804287FA80000001000100010006801840000 +AF78:00000028F7A810A810B810A814A804287FA800000048004800A8011406620000 +AF79:00000028F7A810A810B810A814A804287FA80000000003F00408040803F00000 +AF7A:00000028F7A810A810B810A814A804287FA8000003F80020002000D003080000 +AF7B:00000028F7A810A810B810A814A804287FA80000004003F8004000A003180000 +AF7C:00000028F7A810A810B810A814A804287FA8000003F8000803F8000800080000 +AF7D:00000028F7A810A810B810A814A804287FA8000003F8020003F8020003F80000 +AF7E:00000028F7A810A810B810A814A804287FA8000000000FF8022002200FF80000 +AF7F:00000028F7A810A810B810A814A804287FA8000000800FF803E0041003E00000 +AF80:00000008000800087BC808480848084808480008040804087FE8000800080000 +AF81:00000008F788108810881088148804087FE8000007F800080008000800080000 +AF82:00000008F788108810881088148804087FE8000000003EF80208020802080000 +AF83:00000008F788108810881088148804087FE8000000001F080108011401620000 +AF84:00000008F788108810881088148804087FE8000008000800080008000FF80000 +AF85:00000008F788108810881088148804087FE80000000010F8101010301ECC0000 +AF86:00000008F788108810881088148804087FE800000808087F081C08220F9C0000 +AF87:00000008F788108810881088148804087FE8000003F802000200020003F80000 +AF88:00000008F788108810881088148804087FE8000007F8000807F8040007F80000 +AF89:00000008F788108810881088148804087FE800003EF802083E0820083E080000 +AF8A:00000008F788108810881088148804087FE800003EF802883E8820883EF80000 +AF8B:00000008F788108810881088148804087FE800003E8802883EF820883EF80000 +AF8C:00000008F788108810881088148804087FE800001F0801081F0810141F620000 +AF8D:00000008F788108810881088148804087FE800003EF802803EF820803EF80000 +AF8E:00000008F788108810881088148804087FE800003EFC02483E4820483EFC0000 +AF8F:00000008F788108810881088148804087FE800001F08017F1F1C10221F1C0000 +AF90:00000008F788108810881088148804087FE8000003F802080208020803F80000 +AF91:00000008F788108810881088148804087FE800000208020803F8020803F80000 +AF92:00000008F788108810881088148804087FE80000110811081F0811141F620000 +AF93:00000008F788108810881088148804087FE80000001000100010006801840000 +AF94:00000008F788108810881088148804087FE800000048004800A8011406620000 +AF95:00000008F788108810881088148804087FE80000000003F00408040803F00000 +AF96:00000008F788108810881088148804087FE8000003F80020002000D003080000 +AF97:00000008F788108810881088148804087FE80000004003F8004000A003180000 +AF98:00000008F788108810881088148804087FE8000003F8000803F8000800080000 +AF99:00000008F788108810881088148804087FE8000003F8020003F8020003F80000 +AF9A:00000008F788108810881088148804087FE8000000000FF8022002200FF80000 +AF9B:00000008F788108810881088148804087FE8000000800FF803E0041003E00000 +AF9C:00000000000000003EF8020802080208020804400440044004407FFC00000000 +AF9D:000000003EF8020802080208044004407FFC00001FF000100010001000100000 +AF9E:000000003EF8020802080208044004407FFC000000003EF80208020802080000 +AF9F:000000003EF8020802080208044004407FFC000000001E100210022802C40000 +AFA0:000000003EF8020802080208044004407FFC000000001000100010001FF00000 +AFA1:000000003EF8020802080208044004407FFC0000000020F8201020303ECC0000 +AFA2:000000003EF8020802080208044004407FFC0000202021FC207020883E700000 +AFA3:000000003EF8020802080208044004407FFC00001FF01000100010001FF00000 +AFA4:000000003EF8020802080208044004407FFC00001FF000101FF010001FF00000 +AFA5:000000003EF8020802080208044004407FFC00003EF802083E0820083E080000 +AFA6:000000003EF8020802080208044004407FFC00003EF802883E8820883EF80000 +AFA7:000000003EF8020802080208044004407FFC00003E8802883EF820883EF80000 +AFA8:000000003EF8020802080208044004407FFC00003E1002103E1020283EC40000 +AFA9:000000003EF8020802080208044004407FFC00003EF802803EF820803EF80000 +AFAA:000000003EF8020802080208044004407FFC00003EFC02483E4820483EFC0000 +AFAB:000000003EF8020802080208044004407FFC00003E2003FC3E7020883E700000 +AFAC:000000003EF8020802080208044004407FFC00001FF01010101010101FF00000 +AFAD:000000003EF8020802080208044004407FFC0000101010101FF010101FF00000 +AFAE:000000003EF8020802080208044004407FFC0000222022203E2022503E880000 +AFAF:000000003EF8020802080208044004407FFC000000000100010002800C400000 +AFB0:000000003EF8020802080208044004407FFC00000000024002400DA033100000 +AFB1:000000003EF8020802080208044004407FFC0000000007C00820082007C00000 +AFB2:000000003EF8020802080208044004407FFC0000000007E00080014006200000 +AFB3:000000003EF8020802080208044004407FFC0000008007E00080014006200000 +AFB4:000000003EF8020802080208044004407FFC00001FF000101FF0001000100000 +AFB5:000000003EF8020802080208044004407FFC00001FF010001FF010001FF00000 +AFB6:000000003EF8020802080208044004407FFC000000001FF0044004401FF00000 +AFB7:000000003EF8020802080208044004407FFC000001001FF007C0082007C00000 +AFB8:00000000000000007DF0041004100410041000003FF801000100010001000000 +AFB9:000000003EF802080208020800007FFC010001001FF000100010001000100000 +AFBA:000000003EF802080208020800007FFC0100010000003EF80208020802080000 +AFBB:000000003EF802080208020800007FFC0100010000001E100210022802C40000 +AFBC:000000003EF8020802080208000000007FFC010001001100100010001FF00000 +AFBD:000000003EF802080208020800007FFC01000100000020F8201020303ECC0000 +AFBE:000000003EF802080208020800007FFC01000100202021FC207020883E700000 +AFBF:000000003EF802080208020800007FFC010001001FF01000100010001FF00000 +AFC0:000000003EF802080208020800007FFC010001001FF000101FF010001FF00000 +AFC1:000000003EF802080208020800007FFC010001003EF802083E0820083E080000 +AFC2:000000003EF802080208020800007FFC010001003EF802883E8820883EF80000 +AFC3:000000003EF802080208020800007FFC010001003E8802883EF820883EF80000 +AFC4:000000003EF802080208020800007FFC010001003E1002103E1020283EC40000 +AFC5:000000003EF802080208020800007FFC010001003EF802803EF820803EF80000 +AFC6:000000003EF802080208020800007FFC010001003EFC02483E4820483EFC0000 +AFC7:000000003EF802080208020800007FFC010001003E2003FC3E7020883E700000 +AFC8:000000003EF802080208020800007FFC010001001FF01010101010101FF00000 +AFC9:000000003EF802080208020800007FFC01000100101010101FF010101FF00000 +AFCA:000000003EF802080208020800007FFC01000100222022203E2022503E880000 +AFCB:000000003EF802080208020800007FFC0100010000000100010002800C400000 +AFCC:000000003EF802080208020800007FFC010001000000024002400DA033100000 +AFCD:000000003EF802080208020800007FFC01000100000007C00820082007C00000 +AFCE:000000003EF802080208020800007FFC01000100000007E00080014006200000 +AFCF:000000003EF802080208020800007FFC01000100008007E00080014006200000 +AFD0:000000003EF802080208020800007FFC010001001FF000101FF0001000100000 +AFD1:000000003EF802080208020800007FFC010001001FF010001FF010001FF00000 +AFD2:000000003EF802080208020800007FFC0100010000001FF0044004401FF00000 +AFD3:000000003EF802080208020800007FFC0100010001001FF007C0082007C00000 +AFD4:00000008000800087BC8084808480848000800087FE8040804F8040804080000 +AFD5:00080008F7881088108810887FE8027802080000000007F80008000800080000 +AFD6:00080008F7881088108810887FE802780208000000003EF80208020802080000 +AFD7:00080008F7881088108810887FE802780208000000001F080108011401620000 +AFD8:00080008F78810881088108800087FE80278020802081000100010001FF80000 +AFD9:00080008F7881088108810887FE8027802080000000020F8201020303ECC0000 +AFDA:00080008F7881088108810887FE8027802080000202021FC207020883E700000 +AFDB:00080008F7881088108810887FE802780208000003F802000200020003F80000 +AFDC:00080008F7881088108810887FE802780208000007F8000807F8040007F80000 +AFDD:00080008F7881088108810887FE80278020800003EF802083E0820083E080000 +AFDE:00080008F7881088108810887FE80278020800003EF802883E8820883EF80000 +AFDF:00080008F7881088108810887FE80278020800003E8802883EF820883EF80000 +AFE0:00080008F7881088108810887FE80278020800000F8800880F8808140FA20000 +AFE1:00080008F7881088108810887FE80278020800003EF802803EF820803EF80000 +AFE2:00080008F7881088108810887FE80278020800003EFC02483E4820483EFC0000 +AFE3:00080008F7881088108810887FE80278020800003E1002FE3E3820443E380000 +AFE4:00080008F7881088108810887FE802780208000003F802080208020803F80000 +AFE5:00080008F7881088108810887FE80278020800000208020803F8020803F80000 +AFE6:00080008F7881088108810887FE8027802080000210821083F0821143F620000 +AFE7:00080008F7881088108810887FE8027802080000001000100010006801840000 +AFE8:00080008F7881088108810887FE80278020800000048004800A8011406620000 +AFE9:00080008F7881088108810887FE8027802080000000003F00408040803F00000 +AFEA:00080008F7881088108810887FE802780208000003F80020002000D003080000 +AFEB:00080008F7881088108810887FE8027802080000004003F8004000A003180000 +AFEC:00080008F7881088108810887FE802780208000003F8000803F8000800080000 +AFED:00080008F7881088108810887FE802780208000003F8020003F8020003F80000 +AFEE:00080008F7881088108810887FE802780208000000000FF8022002200FF80000 +AFEF:00080008F7881088108810887FE802780208000000800FF803E0041003E00000 +AFF0:0000000A000A000A7BCA084A084A084A000A000A7FEA040A047A040A040A0000 +AFF1:00280028F7A810A810A810A87FA805E804280000000007F80008000800080000 +AFF2:00280028F7A810A810A810A87FA805E80428000000003EF80208020802080000 +AFF3:00280028F7A810A810A810A87FA805E80428000000001F080108011401620000 +AFF4:00280028F7A810A810A810A800287FA8042805E804281428100010001FF80000 +AFF5:00280028F7A810A810A810A87FA805E804280000000020F8201020303ECC0000 +AFF6:00280028F7A810A810A810A87FA805E804280000202021FC207020883E700000 +AFF7:00280028F7A810A810A810A87FA805E80428000003F802000200020003F80000 +AFF8:00280028F7A810A810A810A87FA805E80428000007F8000807F8040007F80000 +AFF9:00280028F7A810A810A810A87FA805E8042800003EF802083E0820083E080000 +AFFA:00280028F7A810A810A810A87FA805E8042800003EF802883E8820883EF80000 +AFFB:00280028F7A810A810A810A87FA805E8042800003E8802883EF820883EF80000 +AFFC:00280028F7A810A810A810A87FA805E8042800000F8800880F8808140FA20000 +AFFD:00280028F7A810A810A810A87FA805E8042800003EF802803EF820803EF80000 +AFFE:00280028F7A810A810A810A87FA805E8042800003EFC02483E4820483EFC0000 +AFFF:00280028F7A810A810A810A87FA805E8042800003E1002FE3E3820443E380000 +B000:00280028F7A810A810A810A87FA805E80428000003F802080208020803F80000 +B001:00280028F7A810A810A810A87FA805E8042800000208020803F8020803F80000 +B002:00280028F7A810A810A810A87FA805E804280000210821083F0821143F620000 +B003:00280028F7A810A810A810A87FA805E804280000001000100010006801840000 +B004:00280028F7A810A810A810A87FA805E8042800000048004800A8011406620000 +B005:00280028F7A810A810A810A87FA805E804280000000003F00408040803F00000 +B006:00280028F7A810A810A810A87FA805E80428000003F80020002000D003080000 +B007:00280028F7A810A810A810A87FA805E804280000004003F8004000A003180000 +B008:00280028F7A810A810A810A87FA805E80428000003F8000803F8000800080000 +B009:00280028F7A810A810A810A87FA805E80428000003F8020003F8020003F80000 +B00A:00280028F7A810A810A810A87FA805E80428000000000FF8022002200FF80000 +B00B:00280028F7A810A810A810A87FA805E80428000000800FF803E0041003E00000 +B00C:00000008000800087BC8084808480848000800087FE804080408040804080000 +B00D:00080008F7881088108810887FE8020802000000000007F80008000800080000 +B00E:00080008F7881088108810887FE802080200000000003EF80208020802080000 +B00F:00080008F7881088108810887FE802080200000000001F080108011401620000 +B010:00080008F78810881088108800087FE80208020802081008100010001FF80000 +B011:00080008F7881088108810887FE8020802000000000020F8201020303ECC0000 +B012:00080008F7881088108810887FE8020802000000202021FC207020883E700000 +B013:00080008F7881088108810887FE802080200000003F802000200020003F80000 +B014:00080008F7881088108810887FE802080200000007F8000807F8040007F80000 +B015:00080008F7881088108810887FE80208020000003EF802083E0820083E080000 +B016:00080008F7881088108810887FE80208020000003EF802883E8820883EF80000 +B017:00080008F7881088108810887FE80208020000003E8802883EF820883EF80000 +B018:00080008F7881088108810887FE80208020000000F8800880F8808140FA20000 +B019:00080008F7881088108810887FE80208020000003EF802803EF820803EF80000 +B01A:00080008F7881088108810887FE80208020000003EFC02483E4820483EFC0000 +B01B:00080008F7881088108810887FE80208020000003E1002FE3E3820443E380000 +B01C:00080008F7881088108810887FE802080200000003F802080208020803F80000 +B01D:00080008F7881088108810887FE80208020000000208020803F8020803F80000 +B01E:00080008F7881088108810887FE8020802000000210821083F0821143F620000 +B01F:00080008F7881088108810887FE8020802000000001000100010006801840000 +B020:00080008F7881088108810887FE80208020000000048004800A8011406620000 +B021:00080008F7881088108810887FE8020802000000000003F00408040803F00000 +B022:00080008F7881088108810887FE802080200000003F80020002000D003080000 +B023:00080008F7881088108810887FE8020802000000004003F8004000A003180000 +B024:00080008F7881088108810887FE802080200000003F8000803F8000800080000 +B025:00080008F7881088108810887FE802080200000003F8020003F8020003F80000 +B026:00080008F7881088108810887FE802080200000000000FF8022002200FF80000 +B027:00080008F7881088108810887FE802080200000000800FF803E0041003E00000 +B028:00000000000000007DF0041004100410041000007FFC04400440044004400000 +B029:000000003EF802080208020800007FFC044004401FF000100010001000100000 +B02A:000000003EF802080208020800007FFC0440044000003EF80208020802080000 +B02B:000000003EF802080208020800007FFC0440044000001E100210022802C40000 +B02C:000000003EF8020802080208000000007FFC044004401440100010001FF00000 +B02D:000000003EF802080208020800007FFC04400440000020F8201020303ECC0000 +B02E:000000003EF802080208020800007FFC04400440202021FC207020883E700000 +B02F:000000003EF802080208020800007FFC044004401FF01000100010001FF00000 +B030:000000003EF802080208020800007FFC044004401FF000101FF010001FF00000 +B031:000000003EF802080208020800007FFC044004403EF802083E0820083E080000 +B032:000000003EF802080208020800007FFC044004403EF802883E8820883EF80000 +B033:000000003EF802080208020800007FFC044004403E8802883EF820883EF80000 +B034:000000003EF802080208020800007FFC044004403E1002103E1020283EC40000 +B035:000000003EF802080208020800007FFC044004403EF802803EF820803EF80000 +B036:000000003EF802080208020800007FFC044004403EFC02483E4820483EFC0000 +B037:000000003EF802080208020800007FFC044004403E2003FC3E7020883E700000 +B038:000000003EF802080208020800007FFC044004401FF01010101010101FF00000 +B039:000000003EF802080208020800007FFC04400440101010101FF010101FF00000 +B03A:000000003EF802080208020800007FFC04400440222022203E2022503E880000 +B03B:000000003EF802080208020800007FFC0440044000000100010002800C400000 +B03C:000000003EF802080208020800007FFC044004400000024002400DA033100000 +B03D:000000003EF802080208020800007FFC04400440000007C00820082007C00000 +B03E:000000003EF802080208020800007FFC04400440000007E00080014006200000 +B03F:000000003EF802080208020800007FFC04400440008007E00080014006200000 +B040:000000003EF802080208020800007FFC044004401FF000101FF0001000100000 +B041:000000003EF802080208020800007FFC044004401FF010001FF010001FF00000 +B042:000000003EF802080208020800007FFC0440044000001FF0044004401FF00000 +B043:000000003EF802080208020800007FFC0440044001001FF007C0082007C00000 +B044:00000000000000003EF80208020802080208000000007FFC0000000000000000 +B045:000000003EF8020802080208000000007FFC00001FF000100010001000100000 +B046:000000003EF8020802080208000000007FFC000000003EF80208020802080000 +B047:000000003EF8020802080208000000007FFC000000001E100210022802C40000 +B048:000000003EF8020802080208000000007FFC000000001000100010001FF00000 +B049:000000003EF8020802080208000000007FFC0000000020F8201020303ECC0000 +B04A:000000003EF8020802080208000000007FFC0000202021FC207020883E700000 +B04B:000000003EF8020802080208000000007FFC00001FF01000100010001FF00000 +B04C:000000003EF8020802080208000000007FFC00001FF000101FF010001FF00000 +B04D:000000003EF8020802080208000000007FFC00003EF802083E0820083E080000 +B04E:000000003EF8020802080208000000007FFC00003EF802883E8820883EF80000 +B04F:000000003EF8020802080208000000007FFC00003E8802883EF820883EF80000 +B050:000000003EF8020802080208000000007FFC00003E1002103E1020283EC40000 +B051:000000003EF8020802080208000000007FFC00003EF802803EF820803EF80000 +B052:000000003EF8020802080208000000007FFC00003EFC02483E4820483EFC0000 +B053:000000003EF8020802080208000000007FFC00003E2003FC3E7020883E700000 +B054:000000003EF8020802080208000000007FFC00001FF01010101010101FF00000 +B055:000000003EF8020802080208000000007FFC0000101010101FF010101FF00000 +B056:000000003EF8020802080208000000007FFC0000222022203E2022503E880000 +B057:000000003EF8020802080208000000007FFC000000000100010002800C400000 +B058:000000003EF8020802080208000000007FFC00000000024002400DA033100000 +B059:000000003EF8020802080208000000007FFC0000000007C00820082007C00000 +B05A:000000003EF8020802080208000000007FFC0000000007E00080014006200000 +B05B:000000003EF8020802080208000000007FFC0000008007E00080014006200000 +B05C:000000003EF8020802080208000000007FFC00001FF000101FF0001000100000 +B05D:000000003EF8020802080208000000007FFC00001FF010001FF010001FF00000 +B05E:000000003EF8020802080208000000007FFC000000001FF0044004401FF00000 +B05F:000000003EF8020802080208000000007FFC000001001FF007C0082007C00000 +B060:00000008000800087BC80848084808480848000800087FE80008000800080000 +B061:00000008F788108810881088108800087FE8000007F800080008000800080000 +B062:00000008F788108810881088108800087FE8000000003EF80208020802080000 +B063:00000008F788108810881088108800087FE8000000001F080108011401620000 +B064:00000008F788108810881088108800087FE8000008000800080008000FF80000 +B065:00000008F788108810881088108800087FE80000000010F8101010301ECC0000 +B066:00000008F788108810881088108800087FE800000808087F081C08220F9C0000 +B067:00000008F788108810881088108800087FE8000003F802000200020003F80000 +B068:00000008F788108810881088108800087FE8000007F8000807F8040007F80000 +B069:00000008F788108810881088108800087FE800003EF802083E0820083E080000 +B06A:00000008F788108810881088108800087FE800003EF802883E8820883EF80000 +B06B:00000008F788108810881088108800087FE800003E8802883EF820883EF80000 +B06C:00000008F788108810881088108800087FE800001F0801081F0810141F620000 +B06D:00000008F788108810881088108800087FE800003EF802803EF820803EF80000 +B06E:00000008F788108810881088108800087FE800003EFC02483E4820483EFC0000 +B06F:00000008F788108810881088108800087FE800001F08017F1F1C10221F1C0000 +B070:00000008F788108810881088108800087FE8000003F802080208020803F80000 +B071:00000008F788108810881088108800087FE800000208020803F8020803F80000 +B072:00000008F788108810881088108800087FE80000110811081F0811141F620000 +B073:00000008F788108810881088108800087FE80000001000100010006801840000 +B074:00000008F788108810881088108800087FE800000048004800A8011406620000 +B075:00000008F788108810881088108800087FE80000000003F00408040803F00000 +B076:00000008F788108810881088108800087FE8000003F80020002000D003080000 +B077:00000008F788108810881088108800087FE80000004003F8004000A003180000 +B078:00000008F788108810881088108800087FE8000003F8000803F8000800080000 +B079:00000008F788108810881088108800087FE8000003F8020003F8020003F80000 +B07A:00000008F788108810881088108800087FE8000000000FF8022002200FF80000 +B07B:00000008F788108810881088108800087FE8000000800FF803E0041003E00000 +B07C:00000000000800087B8808880888088811081108220844080808000800080000 +B07D:00000008F7881088108810882108C60800080000000007F80008000800080000 +B07E:00000008F7881088108810882108C6080008000000003EF80208020802080000 +B07F:00000008F7881088108810882108C6080008000000001F080108011401620000 +B080:00000008F7881088108810882108C6080008000800001000100010001FF80000 +B081:00000008F7881088108810882108C60800080000000020F8201020303ECC0000 +B082:00000008F7881088108810882108C60800080000202021FC207020883E700000 +B083:00000008F7881088108810882108C6080008000003F802000200020003F80000 +B084:00000008F7881088108810882108C6080008000007F8000807F8040007F80000 +B085:00000008F7881088108810882108C608000800003EF802083E0820083E080000 +B086:00000008F7881088108810882108C608000800003EF802883E8820883EF80000 +B087:00000008F7881088108810882108C608000800003E8802883EF820883EF80000 +B088:00000008F7881088108810882108C608000800000F8800880F8808140FA20000 +B089:00000008F7881088108810882108C608000800003EF802803EF820803EF80000 +B08A:00000008F7881088108810882108C608000800003EFC02483E4820483EFC0000 +B08B:00000008F7881088108810882108C608000800003E1002FE3E3820443E380000 +B08C:00000008F7881088108810882108C6080008000003F802080208020803F80000 +B08D:00000008F7881088108810882108C608000800000208020803F8020803F80000 +B08E:00000008F7881088108810882108C60800080000210821083F0821143F620000 +B08F:00000008F7881088108810882108C60800080000001000100010006801840000 +B090:00000008F7881088108810882108C608000800000048004800A8011406620000 +B091:00000008F7881088108810882108C60800080000000003F00408040803F00000 +B092:00000008F7881088108810882108C6080008000003F80020002000D003080000 +B093:00000008F7881088108810882108C60800080000004003F8004000A003180000 +B094:00000008F7881088108810882108C6080008000003F8000803F8000800080000 +B095:00000008F7881088108810882108C6080008000003F8020003F8020003F80000 +B096:00000008F7881088108810882108C6080008000000000FF8022002200FF80000 +B097:00000008F7881088108810882108C6080008000000800FF803E0041003E00000 +B098:0000000000100010001040104010401E4010401040107F900010001000100000 +B099:00000008000800084008400E400840087E08000007F800080008000800080000 +B09A:00000008000800084008400E400840087E08000000003EF80208020802080000 +B09B:00000008000800084008400E400840087E08000000001F080108011401620000 +B09C:00000008000800084008400E400840087E08000808000800080008000FF80000 +B09D:00000008000800084008400E400840087E080000000010F8101010301ECC0000 +B09E:00000008000800084008400E400840087E0800000808087F081C08220F9C0000 +B09F:00000008000800084008400E400840087E08000003F802000200020003F80000 +B0A0:00000008000800084008400E400840087E08000007F8000807F8040007F80000 +B0A1:00000008000800084008400E400840087E0800003EF802083E0820083E080000 +B0A2:00000008000800084008400E400840087E0800003EF802883E8820883EF80000 +B0A3:00000008000800084008400E400840087E0800003E8802883EF820883EF80000 +B0A4:00000008000800084008400E400840087E0800001F0801081F0810141F620000 +B0A5:00000008000800084008400E400840087E0800003EF802803EF820803EF80000 +B0A6:00000008000800084008400E400840087E0800003EFC02483E4820483EFC0000 +B0A7:00000008000800084008400E400840087E0800001F08017F1F1C10221F1C0000 +B0A8:00000008000800084008400E400840087E08000003F802080208020803F80000 +B0A9:00000008000800084008400E400840087E0800000208020803F8020803F80000 +B0AA:00000008000800084008400E400840087E080000110811081F0811141F620000 +B0AB:00000008000800084008400E400840087E080000001000100010006801840000 +B0AC:00000008000800084008400E400840087E0800000048004800A8011406620000 +B0AD:00000008000800084008400E400840087E080000000003F00408040803F00000 +B0AE:00000008000800084008400E400840087E08000003F80020002000D003080000 +B0AF:00000008000800084008400E400840087E080000004003F8004000A003180000 +B0B0:00000008000800084008400E400840087E08000003F8000803F8000800080000 +B0B1:00000008000800084008400E400840087E08000003F8020003F8020003F80000 +B0B2:00000008000800084008400E400840087E08000000000FF8022002200FF80000 +B0B3:00000008000800084008400E400840087E08000000800FF803E0041003E00000 +B0B4:0000000000120012001240124012401E4012401240127F920012001200120000 +B0B5:000000280028002840284038402840287E28000007F800080008000800080000 +B0B6:000000280028002840284038402840287E28000000003EF80208020802080000 +B0B7:000000280028002840284038402840287E28000000003E100210022802C40000 +B0B8:000000280028002840284038402840287E28002808000800080008000FF80000 +B0B9:000000280028002840284038402840287E280000000020F8201020303ECC0000 +B0BA:000000280028002840284038402840287E280000202021FC207020883E700000 +B0BB:000000280028002840284038402840287E28000003F802000200020003F80000 +B0BC:000000280028002840284038402840287E28000007F8000807F8040007F80000 +B0BD:000000280028002840284038402840287E2800003EF802083E0820083E080000 +B0BE:000000280028002840284038402840287E2800003EF802883E8820883EF80000 +B0BF:000000280028002840284038402840287E2800003E8802883EF820883EF80000 +B0C0:000000280028002840284038402840287E2800001F0801081F0810141F620000 +B0C1:000000280028002840284038402840287E2800003EF802803EF820803EF80000 +B0C2:000000280028002840284038402840287E2800003EFC02483E4820483EFC0000 +B0C3:000000280028002840284038402840287E2800003E1002FE3E3820443E380000 +B0C4:000000280028002840284038402840287E28000003F802080208020803F80000 +B0C5:000000280028002840284038402840287E2800000208020803F8020803F80000 +B0C6:000000280028002840284038402840287E280000110811081F0811141F620000 +B0C7:000000280028002840284038402840287E280000000800080008003400C20000 +B0C8:000000280028002840284038402840287E2800000048004800A8011406620000 +B0C9:000000280028002840284038402840287E280000000001F00208020801F00000 +B0CA:000000280028002840284038402840287E28000003F80020002000D003080000 +B0CB:000000280028002840284038402840287E280000004003F8004000A003180000 +B0CC:000000280028002840284038402840287E28000003F8000803F8000800080000 +B0CD:000000280028002840284038402840287E28000003F8020003F8020003F80000 +B0CE:000000280028002840284038402840287E28000000000FF8022002200FF80000 +B0CF:000000280028002840284038402840287E28000000800FF803E0041003E00000 +B0D0:000000000010001000104010401E40104010401E40107F900010001000100000 +B0D1:0000000800080008400E4008400E40087E08000007F800080008000800080000 +B0D2:0000000800080008400E4008400E40087E08000000003EF80208020802080000 +B0D3:0000000800080008400E4008400E40087E08000000001F080108011401620000 +B0D4:0000000800080008400E4008400E40087E08000008000800080008000FF80000 +B0D5:0000000800080008400E4008400E40087E080000000010F8101010301ECC0000 +B0D6:0000000800080008400E4008400E40087E0800000808087F081C08220F9C0000 +B0D7:0000000800080008400E4008400E40087E08000003F802000200020003F80000 +B0D8:0000000800080008400E4008400E40087E08000007F8000807F8040007F80000 +B0D9:0000000800080008400E4008400E40087E0800003EF802083E0820083E080000 +B0DA:0000000800080008400E4008400E40087E0800003EF802883E8820883EF80000 +B0DB:0000000800080008400E4008400E40087E0800003E8802883EF820883EF80000 +B0DC:0000000800080008400E4008400E40087E0800001F0801081F0810141F620000 +B0DD:0000000800080008400E4008400E40087E0800003EF802803EF820803EF80000 +B0DE:0000000800080008400E4008400E40087E0800003EFC02483E4820483EFC0000 +B0DF:0000000800080008400E4008400E40087E0800001F08017F1F1C10221F1C0000 +B0E0:0000000800080008400E4008400E40087E08000003F802080208020803F80000 +B0E1:0000000800080008400E4008400E40087E0800000208020803F8020803F80000 +B0E2:0000000800080008400E4008400E40087E080000110811081F0811141F620000 +B0E3:0000000800080008400E4008400E40087E080000001000100010006801840000 +B0E4:0000000800080008400E4008400E40087E0800000048004800A8011406620000 +B0E5:0000000800080008400E4008400E40087E080000000003F00408040803F00000 +B0E6:0000000800080008400E4008400E40087E08000003F80020002000D003080000 +B0E7:0000000800080008400E4008400E40087E080000004003F8004000A003180000 +B0E8:0000000800080008400E4008400E40087E08000003F8000803F8000800080000 +B0E9:0000000800080008400E4008400E40087E08000003F8020003F8020003F80000 +B0EA:0000000800080008400E4008400E40087E08000000000FF8022002200FF80000 +B0EB:0000000800080008400E4008400E40087E08000000800FF803E0041003E00000 +B0EC:000000000012001200124012401E40124012401E40127F920012001200120000 +B0ED:000000280028002840384028403840287E28000007F800080008000800080000 +B0EE:000000280028002840384028403840287E28000000003EF80208020802080000 +B0EF:000000280028002840384028403840287E28000000003E100210022802C40000 +B0F0:000000280028002840384028403840287E28002808000800080008000FF80000 +B0F1:000000280028002840384028403840287E280000000020F8201020303ECC0000 +B0F2:000000280028002840384028403840287E280000202021FC207020883E700000 +B0F3:000000280028002840384028403840287E28000003F802000200020003F80000 +B0F4:000000280028002840384028403840287E28000007F8000807F8040007F80000 +B0F5:000000280028002840384028403840287E2800003EF802083E0820083E080000 +B0F6:000000280028002840384028403840287E2800003EF802883E8820883EF80000 +B0F7:000000280028002840384028403840287E2800003E8802883EF820883EF80000 +B0F8:000000280028002840384028403840287E2800001F0801081F0810141F620000 +B0F9:000000280028002840384028403840287E2800003EF802803EF820803EF80000 +B0FA:000000280028002840384028403840287E2800003EFC02483E4820483EFC0000 +B0FB:000000280028002840384028403840287E2800003E1002FE3E3820443E380000 +B0FC:000000280028002840384028403840287E28000003F802080208020803F80000 +B0FD:000000280028002840384028403840287E2800000208020803F8020803F80000 +B0FE:000000280028002840384028403840287E280000110811081F0811141F620000 +B0FF:000000280028002840384028403840287E280000000800080008003400C20000 +B100:000000280028002840384028403840287E2800000048004800A8011406620000 +B101:000000280028002840384028403840287E280000000001F00208020801F00000 +B102:000000280028002840384028403840287E28000003F80020002000D003080000 +B103:000000280028002840384028403840287E280000004003F8004000A003180000 +B104:000000280028002840384028403840287E28000003F8000803F8000800080000 +B105:000000280028002840384028403840287E28000003F8020003F8020003F80000 +B106:000000280028002840384028403840287E28000000000FF8022002200FF80000 +B107:000000280028002840384028403840287E28000000800FF803E0041003E00000 +B108:0000000000020002000240024002401E4002400240027F820002000200020000 +B109:000000080008000840084038400840087E080000000007F80008000800080000 +B10A:000000080008000840084038400840087E08000000003EF80208020802080000 +B10B:000000080008000840084038400840087E08000000001F080108011401620000 +B10C:000000080008000840084038400840087E08000000001000100010001FF80000 +B10D:000000080008000840084038400840087E080000000020F8201020303ECC0000 +B10E:000000080008000840084038400840087E080000202021FC207020883E700000 +B10F:000000080008000840084038400840087E08000003F802000200020003F80000 +B110:000000080008000840084038400840087E08000007F8000807F8040007F80000 +B111:000000080008000840084038400840087E0800003EF802083E0820083E080000 +B112:000000080008000840084038400840087E0800003EF802883E8820883EF80000 +B113:000000080008000840084038400840087E0800003E8802883EF820883EF80000 +B114:000000080008000840084038400840087E0800000F8800880F8808140FA20000 +B115:000000080008000840084038400840087E0800003EF802803EF820803EF80000 +B116:000000080008000840084038400840087E0800003EFC02483E4820483EFC0000 +B117:000000080008000840084038400840087E0800003E1002FE3E3820443E380000 +B118:000000080008000840084038400840087E08000003F802080208020803F80000 +B119:000000080008000840084038400840087E0800000208020803F8020803F80000 +B11A:000000080008000840084038400840087E080000210821083F0821143F620000 +B11B:000000080008000840084038400840087E080000001000100010006801840000 +B11C:000000080008000840084038400840087E0800000048004800A8011406620000 +B11D:000000080008000840084038400840087E080000000003F00408040803F00000 +B11E:000000080008000840084038400840087E08000003F80020002000D003080000 +B11F:000000080008000840084038400840087E080000004003F8004000A003180000 +B120:000000080008000840084038400840087E08000003F8000803F8000800080000 +B121:000000080008000840084038400840087E08000003F8020003F8020003F80000 +B122:000000080008000840084038400840087E08000000000FF8022002200FF80000 +B123:000000080008000840084038400840087E08000000800FF803E0041003E00000 +B124:00000000000A000A000A400A400A403A400A400A400A7F8A000A000A000A0000 +B125:0000002800280028402840E8402840287E28000007F800080008000800080000 +B126:0000002800280028402840E8402840287E28000000003EF80208020802080000 +B127:0000002800280028402840E8402840287E28000000003E100210022802C40000 +B128:0000002800280028402840E8402840287E28000008000800080008000FF80000 +B129:0000002800280028402840E8402840287E280000000020F8201020303ECC0000 +B12A:0000002800280028402840E8402840287E280000202021FC207020883E700000 +B12B:0000002800280028402840E8402840287E28000003F802000200020003F80000 +B12C:0000002800280028402840E8402840287E28000007F8000807F8040007F80000 +B12D:0000002800280028402840E8402840287E2800003EF802083E0820083E080000 +B12E:0000002800280028402840E8402840287E2800003EF802883E8820883EF80000 +B12F:0000002800280028402840E8402840287E2800003E8802883EF820883EF80000 +B130:0000002800280028402840E8402840287E2800001F0801081F0810141F620000 +B131:0000002800280028402840E8402840287E2800003EF802803EF820803EF80000 +B132:0000002800280028402840E8402840287E2800003EFC02483E4820483EFC0000 +B133:0000002800280028402840E8402840287E2800003E1002FE3E3820443E380000 +B134:0000002800280028402840E8402840287E28000003F802080208020803F80000 +B135:0000002800280028402840E8402840287E2800000208020803F8020803F80000 +B136:0000002800280028402840E8402840287E280000110811081F0811141F620000 +B137:0000002800280028402840E8402840287E280000000800080008003400C20000 +B138:0000002800280028402840E8402840287E2800000048004800A8011406620000 +B139:0000002800280028402840E8402840287E280000000001F00208020801F00000 +B13A:0000002800280028402840E8402840287E28000003F80020002000D003080000 +B13B:0000002800280028402840E8402840287E280000004003F8004000A003180000 +B13C:0000002800280028402840E8402840287E28000003F8000803F8000800080000 +B13D:0000002800280028402840E8402840287E28000003F8020003F8020003F80000 +B13E:0000002800280028402840E8402840287E28000000000FF8022002200FF80000 +B13F:0000002800280028402840E8402840287E28000000800FF803E0041003E00000 +B140:000000000002000200024002401E40024002401E40027F820002000200020000 +B141:000000080008000840384008403840087E080000000007F80008000800080000 +B142:000000080008000840384008403840087E08000000003EF80208020802080000 +B143:000000080008000840384008403840087E08000000001F080108011401620000 +B144:000000080008000840384008403840087E08000800001000100010001FF80000 +B145:000000080008000840384008403840087E080000000020F8201020303ECC0000 +B146:000000080008000840384008403840087E080000202021FC207020883E700000 +B147:000000080008000840384008403840087E08000003F802000200020003F80000 +B148:000000080008000840384008403840087E08000007F8000807F8040007F80000 +B149:000000080008000840384008403840087E0800003EF802083E0820083E080000 +B14A:000000080008000840384008403840087E0800003EF802883E8820883EF80000 +B14B:000000080008000840384008403840087E0800003E8802883EF820883EF80000 +B14C:000000080008000840384008403840087E0800000F8800880F8808140FA20000 +B14D:000000080008000840384008403840087E0800003EF802803EF820803EF80000 +B14E:000000080008000840384008403840087E0800003EFC02483E4820483EFC0000 +B14F:000000080008000840384008403840087E0800003E1002FE3E3820443E380000 +B150:000000080008000840384008403840087E08000003F802080208020803F80000 +B151:000000080008000840384008403840087E0800000208020803F8020803F80000 +B152:000000080008000840384008403840087E080000210821083F0821143F620000 +B153:000000080008000840384008403840087E080000001000100010006801840000 +B154:000000080008000840384008403840087E0800000048004800A8011406620000 +B155:000000080008000840384008403840087E080000000003F00408040803F00000 +B156:000000080008000840384008403840087E08000003F80020002000D003080000 +B157:000000080008000840384008403840087E080000004003F8004000A003180000 +B158:000000080008000840384008403840087E08000003F8000803F8000800080000 +B159:000000080008000840384008403840087E08000003F8020003F8020003F80000 +B15A:000000080008000840384008403840087E08000000000FF8022002200FF80000 +B15B:000000080008000840384008403840087E08000000800FF803E0041003E00000 +B15C:00000000000A000A000A400A403A400A400A403A400A7F8A000A000A000A0000 +B15D:000000280028002840E8402840E840287E28000007F800080008000800080000 +B15E:000000280028002840E8402840E840287E28000000003EF80208020802080000 +B15F:000000280028002840E8402840E840287E28000000003E100210022802C40000 +B160:000000280028002840E8402840E840287E28002808000800080008000FF80000 +B161:000000280028002840E8402840E840287E280000000020F8201020303ECC0000 +B162:000000280028002840E8402840E840287E280000202021FC207020883E700000 +B163:000000280028002840E8402840E840287E28000003F802000200020003F80000 +B164:000000280028002840E8402840E840287E28000007F8000807F8040007F80000 +B165:000000280028002840E8402840E840287E2800003EF802083E0820083E080000 +B166:000000280028002840E8402840E840287E2800003EF802883E8820883EF80000 +B167:000000280028002840E8402840E840287E2800003E8802883EF820883EF80000 +B168:000000280028002840E8402840E840287E2800001F0801081F0810141F620000 +B169:000000280028002840E8402840E840287E2800003EF802803EF820803EF80000 +B16A:000000280028002840E8402840E840287E2800003EFC02483E4820483EFC0000 +B16B:000000280028002840E8402840E840287E2800003E1002FE3E3820443E380000 +B16C:000000280028002840E8402840E840287E28000003F802080208020803F80000 +B16D:000000280028002840E8402840E840287E2800000208020803F8020803F80000 +B16E:000000280028002840E8402840E840287E280000110811081F0811141F620000 +B16F:000000280028002840E8402840E840287E280000000800080008003400C20000 +B170:000000280028002840E8402840E840287E2800000048004800A8011406620000 +B171:000000280028002840E8402840E840287E280000000001F00208020801F00000 +B172:000000280028002840E8402840E840287E28000003F80020002000D003080000 +B173:000000280028002840E8402840E840287E280000004003F8004000A003180000 +B174:000000280028002840E8402840E840287E28000003F8000803F8000800080000 +B175:000000280028002840E8402840E840287E28000003F8020003F8020003F80000 +B176:000000280028002840E8402840E840287E28000000000FF8022002200FF80000 +B177:000000280028002840E8402840E840287E28000000800FF803E0041003E00000 +B178:00000000200020002000200020003FF8000000000100010001007FFC00000000 +B179:000000001000100010001FF0010001007FFC00001FF000100010001000100000 +B17A:000000001000100010001FF0010001007FFC000000003EF80208020802080000 +B17B:000000001000100010001FF0010001007FFC000000001E100210022802C40000 +B17C:000000001000100010001FF0010001007FFC000000001000100010001FF00000 +B17D:000000001000100010001FF0010001007FFC0000000020F8201020303ECC0000 +B17E:000000001000100010001FF0010001007FFC0000202021FC207020883E700000 +B17F:000000001000100010001FF0010001007FFC00001FF01000100010001FF00000 +B180:000000001000100010001FF0010001007FFC00001FF000101FF010001FF00000 +B181:000000001000100010001FF0010001007FFC00003EF802083E0820083E080000 +B182:000000001000100010001FF0010001007FFC00003EF802883E8820883EF80000 +B183:000000001000100010001FF0010001007FFC00003E8802883EF820883EF80000 +B184:000000001000100010001FF0010001007FFC00003E1002103E1020283EC40000 +B185:000000001000100010001FF0010001007FFC00003EF802803EF820803EF80000 +B186:000000001000100010001FF0010001007FFC00003EFC02483E4820483EFC0000 +B187:000000001000100010001FF0010001007FFC00003E2003FC3E7020883E700000 +B188:000000001000100010001FF0010001007FFC00001FF01010101010101FF00000 +B189:000000001000100010001FF0010001007FFC0000101010101FF010101FF00000 +B18A:000000001000100010001FF0010001007FFC0000222022203E2022503E880000 +B18B:000000001000100010001FF0010001007FFC000000000100010002800C400000 +B18C:000000001000100010001FF0010001007FFC00000000024002400DA033100000 +B18D:000000001000100010001FF0010001007FFC0000000007C00820082007C00000 +B18E:000000001000100010001FF0010001007FFC0000000007E00080014006200000 +B18F:000000001000100010001FF0010001007FFC0000008007E00080014006200000 +B190:000000001000100010001FF0010001007FFC00001FF000101FF0001000100000 +B191:000000001000100010001FF0010001007FFC00001FF010001FF010001FF00000 +B192:000000001000100010001FF0010001007FFC000000001FF0044004401FF00000 +B193:000000001000100010001FF0010001007FFC000001001FF007C0082007C00000 +B194:0000001000104010401040104010401E7F900010041004107FD0001000100000 +B195:0000000820082008200E20083F8804087FE8000007F800080008000800080000 +B196:0000000820082008200E20083F8804087FE8000000003EF80208020802080000 +B197:0000000820082008200E20083F8804087FE8000000001F080108011401620000 +B198:0000000820082008200E20083F8804087FE8000008000800080008000FF80000 +B199:0000000820082008200E20083F8804087FE80000000010F8101010301ECC0000 +B19A:0000000820082008200E20083F8804087FE800000808087F081C08220F9C0000 +B19B:0000000820082008200E20083F8804087FE8000003F802000200020003F80000 +B19C:0000000820082008200E20083F8804087FE8000007F8000807F8040007F80000 +B19D:0000000820082008200E20083F8804087FE800003EF802083E0820083E080000 +B19E:0000000820082008200E20083F8804087FE800003EF802883E8820883EF80000 +B19F:0000000820082008200E20083F8804087FE800003E8802883EF820883EF80000 +B1A0:0000000820082008200E20083F8804087FE800001F0801081F0810141F620000 +B1A1:0000000820082008200E20083F8804087FE800003EF802803EF820803EF80000 +B1A2:0000000820082008200E20083F8804087FE800003EFC02483E4820483EFC0000 +B1A3:0000000820082008200E20083F8804087FE800001F08017F1F1C10221F1C0000 +B1A4:0000000820082008200E20083F8804087FE8000003F802080208020803F80000 +B1A5:0000000820082008200E20083F8804087FE800000208020803F8020803F80000 +B1A6:0000000820082008200E20083F8804087FE80000110811081F0811141F620000 +B1A7:0000000820082008200E20083F8804087FE80000001000100010006801840000 +B1A8:0000000820082008200E20083F8804087FE800000048004800A8011406620000 +B1A9:0000000820082008200E20083F8804087FE80000000003F00408040803F00000 +B1AA:0000000820082008200E20083F8804087FE8000003F80020002000D003080000 +B1AB:0000000820082008200E20083F8804087FE80000004003F8004000A003180000 +B1AC:0000000820082008200E20083F8804087FE8000003F8000803F8000800080000 +B1AD:0000000820082008200E20083F8804087FE8000003F8020003F8020003F80000 +B1AE:0000000820082008200E20083F8804087FE8000000000FF8022002200FF80000 +B1AF:0000000820082008200E20083F8804087FE8000000800FF803E0041003E00000 +B1B0:0000001200124012401240124012401E7F920012041204127FD2001200120000 +B1B1:0000002820282028203820283FA804287FA8000007F800080008000800080000 +B1B2:0000002820282028203820283FA804287FA8000000003EF80208020802080000 +B1B3:0000002820282028203820283FA804287FA8000000001F080108011401620000 +B1B4:0000002820282028203820283FA804287FA8000008000800080008000FF80000 +B1B5:0000002820282028203820283FA804287FA80000000010F8101010301ECC0000 +B1B6:0000002820282028203820283FA804287FA800000808087F081C08220F9C0000 +B1B7:0000002820282028203820283FA804287FA8000003F802000200020003F80000 +B1B8:0000002820282028203820283FA804287FA8000007F8000807F8040007F80000 +B1B9:0000002820282028203820283FA804287FA800003EF802083E0820083E080000 +B1BA:0000002820282028203820283FA804287FA800003EF802883E8820883EF80000 +B1BB:0000002820282028203820283FA804287FA800003E8802883EF820883EF80000 +B1BC:0000002820282028203820283FA804287FA800001F0801081F0810141F620000 +B1BD:0000002820282028203820283FA804287FA800003EF802803EF820803EF80000 +B1BE:0000002820282028203820283FA804287FA800003EFC02483E4820483EFC0000 +B1BF:0000002820282028203820283FA804287FA800001F08017F1F1C10221F1C0000 +B1C0:0000002820282028203820283FA804287FA8000003F802080208020803F80000 +B1C1:0000002820282028203820283FA804287FA800000208020803F8020803F80000 +B1C2:0000002820282028203820283FA804287FA80000110811081F0811141F620000 +B1C3:0000002820282028203820283FA804287FA80000001000100010006801840000 +B1C4:0000002820282028203820283FA804287FA800000048004800A8011406620000 +B1C5:0000002820282028203820283FA804287FA80000000003F00408040803F00000 +B1C6:0000002820282028203820283FA804287FA8000003F80020002000D003080000 +B1C7:0000002820282028203820283FA804287FA80000004003F8004000A003180000 +B1C8:0000002820282028203820283FA804287FA8000003F8000803F8000800080000 +B1C9:0000002820282028203820283FA804287FA8000003F8020003F8020003F80000 +B1CA:0000002820282028203820283FA804287FA8000000000FF8022002200FF80000 +B1CB:0000002820282028203820283FA804287FA8000000800FF803E0041003E00000 +B1CC:000000080008400840084008400840087F880008040804087FE8000800080000 +B1CD:0000000820082008200820083F8804087FE8000007F800080008000800080000 +B1CE:0000000820082008200820083F8804087FE8000000003EF80208020802080000 +B1CF:0000000820082008200820083F8804087FE8000000001F080108011401620000 +B1D0:0000000820082008200820083F8804087FE8000008000800080008000FF80000 +B1D1:0000000820082008200820083F8804087FE80000000010F8101010301ECC0000 +B1D2:0000000820082008200820083F8804087FE800000808087F081C08220F9C0000 +B1D3:0000000820082008200820083F8804087FE8000003F802000200020003F80000 +B1D4:0000000820082008200820083F8804087FE8000007F8000807F8040007F80000 +B1D5:0000000820082008200820083F8804087FE800003EF802083E0820083E080000 +B1D6:0000000820082008200820083F8804087FE800003EF802883E8820883EF80000 +B1D7:0000000820082008200820083F8804087FE800003E8802883EF820883EF80000 +B1D8:0000000820082008200820083F8804087FE800001F0801081F0810141F620000 +B1D9:0000000820082008200820083F8804087FE800003EF802803EF820803EF80000 +B1DA:0000000820082008200820083F8804087FE800003EFC02483E4820483EFC0000 +B1DB:0000000820082008200820083F8804087FE800001F08017F1F1C10221F1C0000 +B1DC:0000000820082008200820083F8804087FE8000003F802080208020803F80000 +B1DD:0000000820082008200820083F8804087FE800000208020803F8020803F80000 +B1DE:0000000820082008200820083F8804087FE80000110811081F0811141F620000 +B1DF:0000000820082008200820083F8804087FE80000001000100010006801840000 +B1E0:0000000820082008200820083F8804087FE800000048004800A8011406620000 +B1E1:0000000820082008200820083F8804087FE80000000003F00408040803F00000 +B1E2:0000000820082008200820083F8804087FE8000003F80020002000D003080000 +B1E3:0000000820082008200820083F8804087FE80000004003F8004000A003180000 +B1E4:0000000820082008200820083F8804087FE8000003F8000803F8000800080000 +B1E5:0000000820082008200820083F8804087FE8000003F8020003F8020003F80000 +B1E6:0000000820082008200820083F8804087FE8000000000FF8022002200FF80000 +B1E7:0000000820082008200820083F8804087FE8000000800FF803E0041003E00000 +B1E8:00000000200020002000200020003FF8000004400440044004407FFC00000000 +B1E9:000000001000100010001FF0044004407FFC00001FF000100010001000100000 +B1EA:000000001000100010001FF0044004407FFC000000003EF80208020802080000 +B1EB:000000001000100010001FF0044004407FFC000000001E100210022802C40000 +B1EC:000000001000100010001FF0044004407FFC000000001000100010001FF00000 +B1ED:000000001000100010001FF0044004407FFC0000000020F8201020303ECC0000 +B1EE:000000001000100010001FF0044004407FFC0000202021FC207020883E700000 +B1EF:000000001000100010001FF0044004407FFC00001FF01000100010001FF00000 +B1F0:000000001000100010001FF0044004407FFC00001FF000101FF010001FF00000 +B1F1:000000001000100010001FF0044004407FFC00003EF802083E0820083E080000 +B1F2:000000001000100010001FF0044004407FFC00003EF802883E8820883EF80000 +B1F3:000000001000100010001FF0044004407FFC00003E8802883EF820883EF80000 +B1F4:000000001000100010001FF0044004407FFC00003E1002103E1020283EC40000 +B1F5:000000001000100010001FF0044004407FFC00003EF802803EF820803EF80000 +B1F6:000000001000100010001FF0044004407FFC00003EFC02483E4820483EFC0000 +B1F7:000000001000100010001FF0044004407FFC00003E2003FC3E7020883E700000 +B1F8:000000001000100010001FF0044004407FFC00001FF01010101010101FF00000 +B1F9:000000001000100010001FF0044004407FFC0000101010101FF010101FF00000 +B1FA:000000001000100010001FF0044004407FFC0000222022203E2022503E880000 +B1FB:000000001000100010001FF0044004407FFC000000000100010002800C400000 +B1FC:000000001000100010001FF0044004407FFC00000000024002400DA033100000 +B1FD:000000001000100010001FF0044004407FFC0000000007C00820082007C00000 +B1FE:000000001000100010001FF0044004407FFC0000000007E00080014006200000 +B1FF:000000001000100010001FF0044004407FFC0000008007E00080014006200000 +B200:000000001000100010001FF0044004407FFC00001FF000101FF0001000100000 +B201:000000001000100010001FF0044004407FFC00001FF010001FF010001FF00000 +B202:000000001000100010001FF0044004407FFC000000001FF0044004401FF00000 +B203:000000001000100010001FF0044004407FFC000001001FF007C0082007C00000 +B204:00000000200020002000200020003FF8000000003FF801000100010001000000 +B205:000000001000100010001FF000007FFC010001001FF000100010001000100000 +B206:000000001000100010001FF000007FFC0100010000003EF80208020802080000 +B207:000000001000100010001FF000007FFC0100010000001E100210022802C40000 +B208:000000001000100010001FF0000000007FFC010001001100100010001FF00000 +B209:000000001000100010001FF000007FFC01000100000020F8201020303ECC0000 +B20A:000000001000100010001FF000007FFC01000100202021FC207020883E700000 +B20B:000000001000100010001FF000007FFC010001001FF01000100010001FF00000 +B20C:000000001000100010001FF000007FFC010001001FF000101FF010001FF00000 +B20D:000000001000100010001FF000007FFC010001003EF802083E0820083E080000 +B20E:000000001000100010001FF000007FFC010001003EF802883E8820883EF80000 +B20F:000000001000100010001FF000007FFC010001003E8802883EF820883EF80000 +B210:000000001000100010001FF000007FFC010001003E1002103E1020283EC40000 +B211:000000001000100010001FF000007FFC010001003EF802803EF820803EF80000 +B212:000000001000100010001FF000007FFC010001003EFC02483E4820483EFC0000 +B213:000000001000100010001FF000007FFC010001003E2003FC3E7020883E700000 +B214:000000001000100010001FF000007FFC010001001FF01010101010101FF00000 +B215:000000001000100010001FF000007FFC01000100101010101FF010101FF00000 +B216:000000001000100010001FF000007FFC01000100222022203E2022503E880000 +B217:000000001000100010001FF000007FFC0100010000000100010002800C400000 +B218:000000001000100010001FF000007FFC010001000000024002400DA033100000 +B219:000000001000100010001FF000007FFC01000100000007C00820082007C00000 +B21A:000000001000100010001FF000007FFC01000100000007E00080014006200000 +B21B:000000001000100010001FF000007FFC01000100008007E00080014006200000 +B21C:000000001000100010001FF000007FFC010001001FF000101FF0001000100000 +B21D:000000001000100010001FF000007FFC010001001FF010001FF010001FF00000 +B21E:000000001000100010001FF000007FFC0100010000001FF0044004401FF00000 +B21F:000000001000100010001FF000007FFC0100010001001FF007C0082007C00000 +B220:00000008000840084008400840087F88000800087FE8040804F8040804080000 +B221:00082008200820083F8800087FE8027802080000000007F80008000800080000 +B222:00082008200820083F8800087FE802780208000000003EF80208020802080000 +B223:00082008200820083F8800087FE802780208000000001F080108011401620000 +B224:00082008200820083F88000800087FE80278020802081000100010001FF80000 +B225:00082008200820083F8800087FE8027802080000000020F8201020303ECC0000 +B226:00082008200820083F8800087FE8027802080000202021FC207020883E700000 +B227:00082008200820083F8800087FE802780208000003F802000200020003F80000 +B228:00082008200820083F8800087FE802780208000007F8000807F8040007F80000 +B229:00082008200820083F8800087FE80278020800003EF802083E0820083E080000 +B22A:00082008200820083F8800087FE80278020800003EF802883E8820883EF80000 +B22B:00082008200820083F8800087FE80278020800003E8802883EF820883EF80000 +B22C:00082008200820083F8800087FE80278020800000F8800880F8808140FA20000 +B22D:00082008200820083F8800087FE80278020800003EF802803EF820803EF80000 +B22E:00082008200820083F8800087FE80278020800003EFC02483E4820483EFC0000 +B22F:00082008200820083F8800087FE80278020800003E1002FE3E3820443E380000 +B230:00082008200820083F8800087FE802780208000003F802080208020803F80000 +B231:00082008200820083F8800087FE80278020800000208020803F8020803F80000 +B232:00082008200820083F8800087FE8027802080000210821083F0821143F620000 +B233:00082008200820083F8800087FE8027802080000001000100010006801840000 +B234:00082008200820083F8800087FE80278020800000048004800A8011406620000 +B235:00082008200820083F8800087FE8027802080000000003F00408040803F00000 +B236:00082008200820083F8800087FE802780208000003F80020002000D003080000 +B237:00082008200820083F8800087FE8027802080000004003F8004000A003180000 +B238:00082008200820083F8800087FE802780208000003F8000803F8000800080000 +B239:00082008200820083F8800087FE802780208000003F8020003F8020003F80000 +B23A:00082008200820083F8800087FE802780208000000000FF8022002200FF80000 +B23B:00082008200820083F8800087FE802780208000000800FF803E0041003E00000 +B23C:0000000A000A400A400A400A400A7F8A000A000A7FEA040A047A040A040A0000 +B23D:00282028202820283FA800287FA805E804280000000007F80008000800080000 +B23E:00282028202820283FA800287FA805E80428000000003EF80208020802080000 +B23F:00282028202820283FA800287FA805E80428000000001F080108011401620000 +B240:00282028202820283FA8002800287FA8042805E804281428100010001FF80000 +B241:00282028202820283FA800287FA805E804280000000020F8201020303ECC0000 +B242:00282028202820283FA800287FA805E804280000202021FC207020883E700000 +B243:00282028202820283FA800287FA805E80428000003F802000200020003F80000 +B244:00282028202820283FA800287FA805E80428000007F8000807F8040007F80000 +B245:00282028202820283FA800287FA805E8042800003EF802083E0820083E080000 +B246:00282028202820283FA800287FA805E8042800003EF802883E8820883EF80000 +B247:00282028202820283FA800287FA805E8042800003E8802883EF820883EF80000 +B248:00282028202820283FA800287FA805E8042800000F8800880F8808140FA20000 +B249:00282028202820283FA800287FA805E8042800003EF802803EF820803EF80000 +B24A:00282028202820283FA800287FA805E8042800003EFC02483E4820483EFC0000 +B24B:00282028202820283FA800287FA805E8042800003E1002FE3E3820443E380000 +B24C:00282028202820283FA800287FA805E80428000003F802080208020803F80000 +B24D:00282028202820283FA800287FA805E8042800000208020803F8020803F80000 +B24E:00282028202820283FA800287FA805E804280000210821083F0821143F620000 +B24F:00282028202820283FA800287FA805E804280000001000100010006801840000 +B250:00282028202820283FA800287FA805E8042800000048004800A8011406620000 +B251:00282028202820283FA800287FA805E804280000000003F00408040803F00000 +B252:00282028202820283FA800287FA805E80428000003F80020002000D003080000 +B253:00282028202820283FA800287FA805E804280000004003F8004000A003180000 +B254:00282028202820283FA800287FA805E80428000003F8000803F8000800080000 +B255:00282028202820283FA800287FA805E80428000003F8020003F8020003F80000 +B256:00282028202820283FA800287FA805E80428000000000FF8022002200FF80000 +B257:00282028202820283FA800287FA805E80428000000800FF803E0041003E00000 +B258:00000008000840084008400840087F88000800087FE804080408040804080000 +B259:00082008200820083F8800087FE8020802000000000007F80008000800080000 +B25A:00082008200820083F8800087FE802080200000000003EF80208020802080000 +B25B:00082008200820083F8800087FE802080200000000001F080108011401620000 +B25C:00082008200820083F88000800087FE80208020802081008100010001FF80000 +B25D:00082008200820083F8800087FE8020802000000000020F8201020303ECC0000 +B25E:00082008200820083F8800087FE8020802000000202021FC207020883E700000 +B25F:00082008200820083F8800087FE802080200000003F802000200020003F80000 +B260:00082008200820083F8800087FE802080200000007F8000807F8040007F80000 +B261:00082008200820083F8800087FE80208020000003EF802083E0820083E080000 +B262:00082008200820083F8800087FE80208020000003EF802883E8820883EF80000 +B263:00082008200820083F8800087FE80208020000003E8802883EF820883EF80000 +B264:00082008200820083F8800087FE80208020000000F8800880F8808140FA20000 +B265:00082008200820083F8800087FE80208020000003EF802803EF820803EF80000 +B266:00082008200820083F8800087FE80208020000003EFC02483E4820483EFC0000 +B267:00082008200820083F8800087FE80208020000003E1002FE3E3820443E380000 +B268:00082008200820083F8800087FE802080200000003F802080208020803F80000 +B269:00082008200820083F8800087FE80208020000000208020803F8020803F80000 +B26A:00082008200820083F8800087FE8020802000000210821083F0821143F620000 +B26B:00082008200820083F8800087FE8020802000000001000100010006801840000 +B26C:00082008200820083F8800087FE80208020000000048004800A8011406620000 +B26D:00082008200820083F8800087FE8020802000000000003F00408040803F00000 +B26E:00082008200820083F8800087FE802080200000003F80020002000D003080000 +B26F:00082008200820083F8800087FE8020802000000004003F8004000A003180000 +B270:00082008200820083F8800087FE802080200000003F8000803F8000800080000 +B271:00082008200820083F8800087FE802080200000003F8020003F8020003F80000 +B272:00082008200820083F8800087FE802080200000000000FF8022002200FF80000 +B273:00082008200820083F8800087FE802080200000000800FF803E0041003E00000 +B274:00000000200020002000200020003FF8000000007FFC04400440044004400000 +B275:000000001000100010001FF000007FFC044004401FF000100010001000100000 +B276:000000001000100010001FF000007FFC0440044000003EF80208020802080000 +B277:000000001000100010001FF000007FFC0440044000001E100210022802C40000 +B278:000000001000100010001FF0000000007FFC044004401440100010001FF00000 +B279:000000001000100010001FF000007FFC04400440000020F8201020303ECC0000 +B27A:000000001000100010001FF000007FFC04400440202021FC207020883E700000 +B27B:000000001000100010001FF000007FFC044004401FF01000100010001FF00000 +B27C:000000001000100010001FF000007FFC044004401FF000101FF010001FF00000 +B27D:000000001000100010001FF000007FFC044004403EF802083E0820083E080000 +B27E:000000001000100010001FF000007FFC044004403EF802883E8820883EF80000 +B27F:000000001000100010001FF000007FFC044004403E8802883EF820883EF80000 +B280:000000001000100010001FF000007FFC044004403E1002103E1020283EC40000 +B281:000000001000100010001FF000007FFC044004403EF802803EF820803EF80000 +B282:000000001000100010001FF000007FFC044004403EFC02483E4820483EFC0000 +B283:000000001000100010001FF000007FFC044004403E2003FC3E7020883E700000 +B284:000000001000100010001FF000007FFC044004401FF01010101010101FF00000 +B285:000000001000100010001FF000007FFC04400440101010101FF010101FF00000 +B286:000000001000100010001FF000007FFC04400440222022203E2022503E880000 +B287:000000001000100010001FF000007FFC0440044000000100010002800C400000 +B288:000000001000100010001FF000007FFC044004400000024002400DA033100000 +B289:000000001000100010001FF000007FFC04400440000007C00820082007C00000 +B28A:000000001000100010001FF000007FFC04400440000007E00080014006200000 +B28B:000000001000100010001FF000007FFC04400440008007E00080014006200000 +B28C:000000001000100010001FF000007FFC044004401FF000101FF0001000100000 +B28D:000000001000100010001FF000007FFC044004401FF010001FF010001FF00000 +B28E:000000001000100010001FF000007FFC0440044000001FF0044004401FF00000 +B28F:000000001000100010001FF000007FFC0440044001001FF007C0082007C00000 +B290:00000000200020002000200020003FF80000000000007FFC0000000000000000 +B291:000000001000100010001FF0000000007FFC00001FF000100010001000100000 +B292:000000001000100010001FF0000000007FFC000000003EF80208020802080000 +B293:000000001000100010001FF0000000007FFC000000001E100210022802C40000 +B294:000000001000100010001FF0000000007FFC000000001000100010001FF00000 +B295:000000001000100010001FF0000000007FFC0000000020F8201020303ECC0000 +B296:000000001000100010001FF0000000007FFC0000202021FC207020883E700000 +B297:000000001000100010001FF0000000007FFC00001FF01000100010001FF00000 +B298:000000001000100010001FF0000000007FFC00001FF000101FF010001FF00000 +B299:000000001000100010001FF0000000007FFC00003EF802083E0820083E080000 +B29A:000000001000100010001FF0000000007FFC00003EF802883E8820883EF80000 +B29B:000000001000100010001FF0000000007FFC00003E8802883EF820883EF80000 +B29C:000000001000100010001FF0000000007FFC00003E1002103E1020283EC40000 +B29D:000000001000100010001FF0000000007FFC00003EF802803EF820803EF80000 +B29E:000000001000100010001FF0000000007FFC00003EFC02483E4820483EFC0000 +B29F:000000001000100010001FF0000000007FFC00003E2003FC3E7020883E700000 +B2A0:000000001000100010001FF0000000007FFC00001FF01010101010101FF00000 +B2A1:000000001000100010001FF0000000007FFC0000101010101FF010101FF00000 +B2A2:000000001000100010001FF0000000007FFC0000222022203E2022503E880000 +B2A3:000000001000100010001FF0000000007FFC000000000100010002800C400000 +B2A4:000000001000100010001FF0000000007FFC00000000024002400DA033100000 +B2A5:000000001000100010001FF0000000007FFC0000000007C00820082007C00000 +B2A6:000000001000100010001FF0000000007FFC0000000007E00080014006200000 +B2A7:000000001000100010001FF0000000007FFC0000008007E00080014006200000 +B2A8:000000001000100010001FF0000000007FFC00001FF000101FF0001000100000 +B2A9:000000001000100010001FF0000000007FFC00001FF010001FF010001FF00000 +B2AA:000000001000100010001FF0000000007FFC000000001FF0044004401FF00000 +B2AB:000000001000100010001FF0000000007FFC000001001FF007C0082007C00000 +B2AC:000000080008400840084008400840087F88000800087FE80008000800080000 +B2AD:0000000820082008200820083F8800087FE8000007F800080008000800080000 +B2AE:0000000820082008200820083F8800087FE8000000003EF80208020802080000 +B2AF:0000000820082008200820083F8800087FE8000000001F080108011401620000 +B2B0:0000000820082008200820083F8800087FE8000008000800080008000FF80000 +B2B1:0000000820082008200820083F8800087FE80000000010F8101010301ECC0000 +B2B2:0000000820082008200820083F8800087FE800000808087F081C08220F9C0000 +B2B3:0000000820082008200820083F8800087FE8000003F802000200020003F80000 +B2B4:0000000820082008200820083F8800087FE8000007F8000807F8040007F80000 +B2B5:0000000820082008200820083F8800087FE800003EF802083E0820083E080000 +B2B6:0000000820082008200820083F8800087FE800003EF802883E8820883EF80000 +B2B7:0000000820082008200820083F8800087FE800003E8802883EF820883EF80000 +B2B8:0000000820082008200820083F8800087FE800001F0801081F0810141F620000 +B2B9:0000000820082008200820083F8800087FE800003EF802803EF820803EF80000 +B2BA:0000000820082008200820083F8800087FE800003EFC02483E4820483EFC0000 +B2BB:0000000820082008200820083F8800087FE800001F08017F1F1C10221F1C0000 +B2BC:0000000820082008200820083F8800087FE8000003F802080208020803F80000 +B2BD:0000000820082008200820083F8800087FE800000208020803F8020803F80000 +B2BE:0000000820082008200820083F8800087FE80000110811081F0811141F620000 +B2BF:0000000820082008200820083F8800087FE80000001000100010006801840000 +B2C0:0000000820082008200820083F8800087FE800000048004800A8011406620000 +B2C1:0000000820082008200820083F8800087FE80000000003F00408040803F00000 +B2C2:0000000820082008200820083F8800087FE8000003F80020002000D003080000 +B2C3:0000000820082008200820083F8800087FE80000004003F8004000A003180000 +B2C4:0000000820082008200820083F8800087FE8000003F8000803F8000800080000 +B2C5:0000000820082008200820083F8800087FE8000003F8020003F8020003F80000 +B2C6:0000000820082008200820083F8800087FE8000000000FF8022002200FF80000 +B2C7:0000000820082008200820083F8800087FE8000000800FF803E0041003E00000 +B2C8:000000000008000800084008400840084008400840087F880008000800080000 +B2C9:000000080008000840084008400840087E080000000007F80008000800080000 +B2CA:000000080008000840084008400840087E08000000003EF80208020802080000 +B2CB:000000080008000840084008400840087E08000000001F080108011401620000 +B2CC:000000080008000840084008400840087E08000800001000100010001FF80000 +B2CD:000000080008000840084008400840087E080000000020F8201020303ECC0000 +B2CE:000000080008000840084008400840087E080000202021FC207020883E700000 +B2CF:000000080008000840084008400840087E08000003F802000200020003F80000 +B2D0:000000080008000840084008400840087E08000007F8000807F8040007F80000 +B2D1:000000080008000840084008400840087E0800003EF802083E0820083E080000 +B2D2:000000080008000840084008400840087E0800003EF802883E8820883EF80000 +B2D3:000000080008000840084008400840087E0800003E8802883EF820883EF80000 +B2D4:000000080008000840084008400840087E0800000F8800880F8808140FA20000 +B2D5:000000080008000840084008400840087E0800003EF802803EF820803EF80000 +B2D6:000000080008000840084008400840087E0800003EFC02483E4820483EFC0000 +B2D7:000000080008000840084008400840087E0800003E1002FE3E3820443E380000 +B2D8:000000080008000840084008400840087E08000003F802080208020803F80000 +B2D9:000000080008000840084008400840087E0800000208020803F8020803F80000 +B2DA:000000080008000840084008400840087E080000210821083F0821143F620000 +B2DB:000000080008000840084008400840087E080000001000100010006801840000 +B2DC:000000080008000840084008400840087E0800000048004800A8011406620000 +B2DD:000000080008000840084008400840087E080000000003F00408040803F00000 +B2DE:000000080008000840084008400840087E08000003F80020002000D003080000 +B2DF:000000080008000840084008400840087E080000004003F8004000A003180000 +B2E0:000000080008000840084008400840087E08000003F8000803F8000800080000 +B2E1:000000080008000840084008400840087E08000003F8020003F8020003F80000 +B2E2:000000080008000840084008400840087E08000000000FF8022002200FF80000 +B2E3:000000080008000840084008400840087E08000000800FF803E0041003E00000 +B2E4:00000000001000107F9040104010401E401040107F9000100010001000100000 +B2E5:0000000800087E084008400E40087E080008000007F800080008000800080000 +B2E6:0000000800087E084008400E40087E080008000000003EF80208020802080000 +B2E7:0000000800087E084008400E40087E080008000000001F080108011401620000 +B2E8:0000000800087E084008400E40087E080008000808000800080008000FF80000 +B2E9:0000000800087E084008400E40087E0800080000000010F8101010301ECC0000 +B2EA:0000000800087E084008400E40087E08000800000808087F081C08220F9C0000 +B2EB:0000000800087E084008400E40087E080008000003F802000200020003F80000 +B2EC:0000000800087E084008400E40087E080008000007F8000807F8040007F80000 +B2ED:0000000800087E084008400E40087E08000800003EF802083E0820083E080000 +B2EE:0000000800087E084008400E40087E08000800003EF802883E8820883EF80000 +B2EF:0000000800087E084008400E40087E08000800003E8802883EF820883EF80000 +B2F0:0000000800087E084008400E40087E08000800001F0801081F0810141F620000 +B2F1:0000000800087E084008400E40087E08000800003EF802803EF820803EF80000 +B2F2:0000000800087E084008400E40087E08000800003EFC02483E4820483EFC0000 +B2F3:0000000800087E084008400E40087E08000800001F08017F1F1C10221F1C0000 +B2F4:0000000800087E084008400E40087E080008000003F802080208020803F80000 +B2F5:0000000800087E084008400E40087E08000800000208020803F8020803F80000 +B2F6:0000000800087E084008400E40087E0800080000110811081F0811141F620000 +B2F7:0000000800087E084008400E40087E0800080000001000100010006801840000 +B2F8:0000000800087E084008400E40087E08000800000048004800A8011406620000 +B2F9:0000000800087E084008400E40087E0800080000000003F00408040803F00000 +B2FA:0000000800087E084008400E40087E080008000003F80020002000D003080000 +B2FB:0000000800087E084008400E40087E0800080000004003F8004000A003180000 +B2FC:0000000800087E084008400E40087E080008000003F8000803F8000800080000 +B2FD:0000000800087E084008400E40087E080008000003F8020003F8020003F80000 +B2FE:0000000800087E084008400E40087E080008000000000FF8022002200FF80000 +B2FF:0000000800087E084008400E40087E080008000000800FF803E0041003E00000 +B300:00000000001200127F9240124012401E401240127F9200120012001200120000 +B301:0000002800287E284028403840287E280028000007F800080008000800080000 +B302:0000002800287E284028403840287E280028000000003EF80208020802080000 +B303:0000002800287E284028403840287E280028000000003E100210022802C40000 +B304:0000002800287E284028403840287E280028002808000800080008000FF80000 +B305:0000002800287E284028403840287E2800280000000020F8201020303ECC0000 +B306:0000002800287E284028403840287E2800280000202021FC207020883E700000 +B307:0000002800287E284028403840287E280028000003F802000200020003F80000 +B308:0000002800287E284028403840287E280028000007F8000807F8040007F80000 +B309:0000002800287E284028403840287E28002800003EF802083E0820083E080000 +B30A:0000002800287E284028403840287E28002800003EF802883E8820883EF80000 +B30B:0000002800287E284028403840287E28002800003E8802883EF820883EF80000 +B30C:0000002800287E284028403840287E28002800001F0801081F0810141F620000 +B30D:0000002800287E284028403840287E28002800003EF802803EF820803EF80000 +B30E:0000002800287E284028403840287E28002800003EFC02483E4820483EFC0000 +B30F:0000002800287E284028403840287E28002800003E1002FE3E3820443E380000 +B310:0000002800287E284028403840287E280028000003F802080208020803F80000 +B311:0000002800287E284028403840287E28002800000208020803F8020803F80000 +B312:0000002800287E284028403840287E2800280000110811081F0811141F620000 +B313:0000002800287E284028403840287E2800280000000800080008003400C20000 +B314:0000002800287E284028403840287E28002800000048004800A8011406620000 +B315:0000002800287E284028403840287E2800280000000001F00208020801F00000 +B316:0000002800287E284028403840287E280028000003F80020002000D003080000 +B317:0000002800287E284028403840287E2800280000004003F8004000A003180000 +B318:0000002800287E284028403840287E280028000003F8000803F8000800080000 +B319:0000002800287E284028403840287E280028000003F8020003F8020003F80000 +B31A:0000002800287E284028403840287E280028000000000FF8022002200FF80000 +B31B:0000002800287E284028403840287E280028000000800FF803E0041003E00000 +B31C:00000000001000107F904010401E40104010401E7F9000100010001000100000 +B31D:0000000800087E08400E4008400E7E080008000007F800080008000800080000 +B31E:0000000800087E08400E4008400E7E080008000000003EF80208020802080000 +B31F:0000000800087E08400E4008400E7E080008000000001F080108011401620000 +B320:0000000800087E08400E4008400E7E080008000008000800080008000FF80000 +B321:0000000800087E08400E4008400E7E0800080000000010F8101010301ECC0000 +B322:0000000800087E08400E4008400E7E08000800000808087F081C08220F9C0000 +B323:0000000800087E08400E4008400E7E080008000003F802000200020003F80000 +B324:0000000800087E08400E4008400E7E080008000007F8000807F8040007F80000 +B325:0000000800087E08400E4008400E7E08000800003EF802083E0820083E080000 +B326:0000000800087E08400E4008400E7E08000800003EF802883E8820883EF80000 +B327:0000000800087E08400E4008400E7E08000800003E8802883EF820883EF80000 +B328:0000000800087E08400E4008400E7E08000800001F0801081F0810141F620000 +B329:0000000800087E08400E4008400E7E08000800003EF802803EF820803EF80000 +B32A:0000000800087E08400E4008400E7E08000800003EFC02483E4820483EFC0000 +B32B:0000000800087E08400E4008400E7E08000800001F08017F1F1C10221F1C0000 +B32C:0000000800087E08400E4008400E7E080008000003F802080208020803F80000 +B32D:0000000800087E08400E4008400E7E08000800000208020803F8020803F80000 +B32E:0000000800087E08400E4008400E7E0800080000110811081F0811141F620000 +B32F:0000000800087E08400E4008400E7E0800080000001000100010006801840000 +B330:0000000800087E08400E4008400E7E08000800000048004800A8011406620000 +B331:0000000800087E08400E4008400E7E0800080000000003F00408040803F00000 +B332:0000000800087E08400E4008400E7E080008000003F80020002000D003080000 +B333:0000000800087E08400E4008400E7E0800080000004003F8004000A003180000 +B334:0000000800087E08400E4008400E7E080008000003F8000803F8000800080000 +B335:0000000800087E08400E4008400E7E080008000003F8020003F8020003F80000 +B336:0000000800087E08400E4008400E7E080008000000000FF8022002200FF80000 +B337:0000000800087E08400E4008400E7E080008000000800FF803E0041003E00000 +B338:00000000001200127F924012401E40124012401E7F9200120012001200120000 +B339:0000002800287E284038402840387E280028000007F800080008000800080000 +B33A:0000002800287E284038402840387E280028000000003EF80208020802080000 +B33B:0000002800287E284038402840387E280028000000003E100210022802C40000 +B33C:0000002800287E284038402840387E280028002808000800080008000FF80000 +B33D:0000002800287E284038402840387E2800280000000020F8201020303ECC0000 +B33E:0000002800287E284038402840387E2800280000202021FC207020883E700000 +B33F:0000002800287E284038402840387E280028000003F802000200020003F80000 +B340:0000002800287E284038402840387E280028000007F8000807F8040007F80000 +B341:0000002800287E284038402840387E28002800003EF802083E0820083E080000 +B342:0000002800287E284038402840387E28002800003EF802883E8820883EF80000 +B343:0000002800287E284038402840387E28002800003E8802883EF820883EF80000 +B344:0000002800287E284038402840387E28002800001F0801081F0810141F620000 +B345:0000002800287E284038402840387E28002800003EF802803EF820803EF80000 +B346:0000002800287E284038402840387E28002800003EFC02483E4820483EFC0000 +B347:0000002800287E284038402840387E28002800003E1002FE3E3820443E380000 +B348:0000002800287E284038402840387E280028000003F802080208020803F80000 +B349:0000002800287E284038402840387E28002800000208020803F8020803F80000 +B34A:0000002800287E284038402840387E2800280000110811081F0811141F620000 +B34B:0000002800287E284038402840387E2800280000000800080008003400C20000 +B34C:0000002800287E284038402840387E28002800000048004800A8011406620000 +B34D:0000002800287E284038402840387E2800280000000001F00208020801F00000 +B34E:0000002800287E284038402840387E280028000003F80020002000D003080000 +B34F:0000002800287E284038402840387E2800280000004003F8004000A003180000 +B350:0000002800287E284038402840387E280028000003F8000803F8000800080000 +B351:0000002800287E284038402840387E280028000003F8020003F8020003F80000 +B352:0000002800287E284038402840387E280028000000000FF8022002200FF80000 +B353:0000002800287E284038402840387E280028000000800FF803E0041003E00000 +B354:00000000000200027F8240024002401E400240027F8200020002000200020000 +B355:0000000800087E084008403840087E0800080000000007F80008000800080000 +B356:0000000800087E084008403840087E080008000000003EF80208020802080000 +B357:0000000800087E084008403840087E080008000000001F080108011401620000 +B358:0000000800087E084008403840087E080008000000001000100010001FF80000 +B359:0000000800087E084008403840087E0800080000000020F8201020303ECC0000 +B35A:0000000800087E084008403840087E0800080000202021FC207020883E700000 +B35B:0000000800087E084008403840087E080008000003F802000200020003F80000 +B35C:0000000800087E084008403840087E080008000007F8000807F8040007F80000 +B35D:0000000800087E084008403840087E08000800003EF802083E0820083E080000 +B35E:0000000800087E084008403840087E08000800003EF802883E8820883EF80000 +B35F:0000000800087E084008403840087E08000800003E8802883EF820883EF80000 +B360:0000000800087E084008403840087E08000800000F8800880F8808140FA20000 +B361:0000000800087E084008403840087E08000800003EF802803EF820803EF80000 +B362:0000000800087E084008403840087E08000800003EFC02483E4820483EFC0000 +B363:0000000800087E084008403840087E08000800003E1002FE3E3820443E380000 +B364:0000000800087E084008403840087E080008000003F802080208020803F80000 +B365:0000000800087E084008403840087E08000800000208020803F8020803F80000 +B366:0000000800087E084008403840087E0800080000210821083F0821143F620000 +B367:0000000800087E084008403840087E0800080000001000100010006801840000 +B368:0000000800087E084008403840087E08000800000048004800A8011406620000 +B369:0000000800087E084008403840087E0800080000000003F00408040803F00000 +B36A:0000000800087E084008403840087E080008000003F80020002000D003080000 +B36B:0000000800087E084008403840087E0800080000004003F8004000A003180000 +B36C:0000000800087E084008403840087E080008000003F8000803F8000800080000 +B36D:0000000800087E084008403840087E080008000003F8020003F8020003F80000 +B36E:0000000800087E084008403840087E080008000000000FF8022002200FF80000 +B36F:0000000800087E084008403840087E080008000000800FF803E0041003E00000 +B370:00000000000A000A7F8A400A400A403A400A400A7F8A000A000A000A000A0000 +B371:0000002800287E28402840E840287E280028000007F800080008000800080000 +B372:0000002800287E28402840E840287E280028000000003EF80208020802080000 +B373:0000002800287E28402840E840287E280028000000003E100210022802C40000 +B374:0000002800287E28402840E840287E280028000008000800080008000FF80000 +B375:0000002800287E28402840E840287E2800280000000020F8201020303ECC0000 +B376:0000002800287E28402840E840287E2800280000202021FC207020883E700000 +B377:0000002800287E28402840E840287E280028000003F802000200020003F80000 +B378:0000002800287E28402840E840287E280028000007F8000807F8040007F80000 +B379:0000002800287E28402840E840287E28002800003EF802083E0820083E080000 +B37A:0000002800287E28402840E840287E28002800003EF802883E8820883EF80000 +B37B:0000002800287E28402840E840287E28002800003E8802883EF820883EF80000 +B37C:0000002800287E28402840E840287E28002800001F0801081F0810141F620000 +B37D:0000002800287E28402840E840287E28002800003EF802803EF820803EF80000 +B37E:0000002800287E28402840E840287E28002800003EFC02483E4820483EFC0000 +B37F:0000002800287E28402840E840287E28002800003E1002FE3E3820443E380000 +B380:0000002800287E28402840E840287E280028000003F802080208020803F80000 +B381:0000002800287E28402840E840287E28002800000208020803F8020803F80000 +B382:0000002800287E28402840E840287E2800280000110811081F0811141F620000 +B383:0000002800287E28402840E840287E2800280000000800080008003400C20000 +B384:0000002800287E28402840E840287E28002800000048004800A8011406620000 +B385:0000002800287E28402840E840287E2800280000000001F00208020801F00000 +B386:0000002800287E28402840E840287E280028000003F80020002000D003080000 +B387:0000002800287E28402840E840287E2800280000004003F8004000A003180000 +B388:0000002800287E28402840E840287E280028000003F8000803F8000800080000 +B389:0000002800287E28402840E840287E280028000003F8020003F8020003F80000 +B38A:0000002800287E28402840E840287E280028000000000FF8022002200FF80000 +B38B:0000002800287E28402840E840287E280028000000800FF803E0041003E00000 +B38C:00000000000200027F824002401E40024002401E7F8200020002000200020000 +B38D:0000000800087E084038400840387E0800080000000007F80008000800080000 +B38E:0000000800087E084038400840387E080008000000003EF80208020802080000 +B38F:0000000800087E084038400840387E080008000000001F080108011401620000 +B390:0000000800087E084038400840387E080008000800001000100010001FF80000 +B391:0000000800087E084038400840387E0800080000000020F8201020303ECC0000 +B392:0000000800087E084038400840387E0800080000202021FC207020883E700000 +B393:0000000800087E084038400840387E080008000003F802000200020003F80000 +B394:0000000800087E084038400840387E080008000007F8000807F8040007F80000 +B395:0000000800087E084038400840387E08000800003EF802083E0820083E080000 +B396:0000000800087E084038400840387E08000800003EF802883E8820883EF80000 +B397:0000000800087E084038400840387E08000800003E8802883EF820883EF80000 +B398:0000000800087E084038400840387E08000800000F8800880F8808140FA20000 +B399:0000000800087E084038400840387E08000800003EF802803EF820803EF80000 +B39A:0000000800087E084038400840387E08000800003EFC02483E4820483EFC0000 +B39B:0000000800087E084038400840387E08000800003E1002FE3E3820443E380000 +B39C:0000000800087E084038400840387E080008000003F802080208020803F80000 +B39D:0000000800087E084038400840387E08000800000208020803F8020803F80000 +B39E:0000000800087E084038400840387E0800080000210821083F0821143F620000 +B39F:0000000800087E084038400840387E0800080000001000100010006801840000 +B3A0:0000000800087E084038400840387E08000800000048004800A8011406620000 +B3A1:0000000800087E084038400840387E0800080000000003F00408040803F00000 +B3A2:0000000800087E084038400840387E080008000003F80020002000D003080000 +B3A3:0000000800087E084038400840387E0800080000004003F8004000A003180000 +B3A4:0000000800087E084038400840387E080008000003F8000803F8000800080000 +B3A5:0000000800087E084038400840387E080008000003F8020003F8020003F80000 +B3A6:0000000800087E084038400840387E080008000000000FF8022002200FF80000 +B3A7:0000000800087E084038400840387E080008000000800FF803E0041003E00000 +B3A8:00000000000A000A7F8A400A403A400A400A403A7F8A000A000A000A000A0000 +B3A9:0000002800287E2840E8402840E87E280028000007F800080008000800080000 +B3AA:0000002800287E2840E8402840E87E280028000000003EF80208020802080000 +B3AB:0000002800287E2840E8402840E87E280028000000003E100210022802C40000 +B3AC:0000002800287E2840E8402840E87E280028002808000800080008000FF80000 +B3AD:0000002800287E2840E8402840E87E2800280000000020F8201020303ECC0000 +B3AE:0000002800287E2840E8402840E87E2800280000202021FC207020883E700000 +B3AF:0000002800287E2840E8402840E87E280028000003F802000200020003F80000 +B3B0:0000002800287E2840E8402840E87E280028000007F8000807F8040007F80000 +B3B1:0000002800287E2840E8402840E87E28002800003EF802083E0820083E080000 +B3B2:0000002800287E2840E8402840E87E28002800003EF802883E8820883EF80000 +B3B3:0000002800287E2840E8402840E87E28002800003E8802883EF820883EF80000 +B3B4:0000002800287E2840E8402840E87E28002800001F0801081F0810141F620000 +B3B5:0000002800287E2840E8402840E87E28002800003EF802803EF820803EF80000 +B3B6:0000002800287E2840E8402840E87E28002800003EFC02483E4820483EFC0000 +B3B7:0000002800287E2840E8402840E87E28002800003E1002FE3E3820443E380000 +B3B8:0000002800287E2840E8402840E87E280028000003F802080208020803F80000 +B3B9:0000002800287E2840E8402840E87E28002800000208020803F8020803F80000 +B3BA:0000002800287E2840E8402840E87E2800280000110811081F0811141F620000 +B3BB:0000002800287E2840E8402840E87E2800280000000800080008003400C20000 +B3BC:0000002800287E2840E8402840E87E28002800000048004800A8011406620000 +B3BD:0000002800287E2840E8402840E87E2800280000000001F00208020801F00000 +B3BE:0000002800287E2840E8402840E87E280028000003F80020002000D003080000 +B3BF:0000002800287E2840E8402840E87E2800280000004003F8004000A003180000 +B3C0:0000002800287E2840E8402840E87E280028000003F8000803F8000800080000 +B3C1:0000002800287E2840E8402840E87E280028000003F8020003F8020003F80000 +B3C2:0000002800287E2840E8402840E87E280028000000000FF8022002200FF80000 +B3C3:0000002800287E2840E8402840E87E280028000000800FF803E0041003E00000 +B3C4:000000003FF820002000200020003FF8000000000100010001007FFC00000000 +B3C5:000000001FF0100010001FF0010001007FFC00001FF000100010001000100000 +B3C6:000000001FF0100010001FF0010001007FFC000000003EF80208020802080000 +B3C7:000000001FF0100010001FF0010001007FFC000000001E100210022802C40000 +B3C8:000000001FF0100010001FF0010001007FFC000000001000100010001FF00000 +B3C9:000000001FF0100010001FF0010001007FFC0000000020F8201020303ECC0000 +B3CA:000000001FF0100010001FF0010001007FFC0000202021FC207020883E700000 +B3CB:000000001FF0100010001FF0010001007FFC00001FF01000100010001FF00000 +B3CC:000000001FF0100010001FF0010001007FFC00001FF000101FF010001FF00000 +B3CD:000000001FF0100010001FF0010001007FFC00003EF802083E0820083E080000 +B3CE:000000001FF0100010001FF0010001007FFC00003EF802883E8820883EF80000 +B3CF:000000001FF0100010001FF0010001007FFC00003E8802883EF820883EF80000 +B3D0:000000001FF0100010001FF0010001007FFC00003E1002103E1020283EC40000 +B3D1:000000001FF0100010001FF0010001007FFC00003EF802803EF820803EF80000 +B3D2:000000001FF0100010001FF0010001007FFC00003EFC02483E4820483EFC0000 +B3D3:000000001FF0100010001FF0010001007FFC00003E2003FC3E7020883E700000 +B3D4:000000001FF0100010001FF0010001007FFC00001FF01010101010101FF00000 +B3D5:000000001FF0100010001FF0010001007FFC0000101010101FF010101FF00000 +B3D6:000000001FF0100010001FF0010001007FFC0000222022203E2022503E880000 +B3D7:000000001FF0100010001FF0010001007FFC000000000100010002800C400000 +B3D8:000000001FF0100010001FF0010001007FFC00000000024002400DA033100000 +B3D9:000000001FF0100010001FF0010001007FFC0000000007C00820082007C00000 +B3DA:000000001FF0100010001FF0010001007FFC0000000007E00080014006200000 +B3DB:000000001FF0100010001FF0010001007FFC0000008007E00080014006200000 +B3DC:000000001FF0100010001FF0010001007FFC00001FF000101FF0001000100000 +B3DD:000000001FF0100010001FF0010001007FFC00001FF010001FF010001FF00000 +B3DE:000000001FF0100010001FF0010001007FFC000000001FF0044004401FF00000 +B3DF:000000001FF0100010001FF0010001007FFC000001001FF007C0082007C00000 +B3E0:0000001000107F904010401040107F9E00100010041004107FD0001000100000 +B3E1:000000083F882008200E3F88040804087FE8000007F800080008000800080000 +B3E2:000000083F882008200E3F88040804087FE8000000003EF80208020802080000 +B3E3:000000083F882008200E3F88040804087FE8000000001F080108011401620000 +B3E4:000000083F882008200E3F88040804087FE8000008000800080008000FF80000 +B3E5:000000083F882008200E3F88040804087FE80000000010F8101010301ECC0000 +B3E6:000000083F882008200E3F88040804087FE800000808087F081C08220F9C0000 +B3E7:000000083F882008200E3F88040804087FE8000003F802000200020003F80000 +B3E8:000000083F882008200E3F88040804087FE8000007F8000807F8040007F80000 +B3E9:000000083F882008200E3F88040804087FE800003EF802083E0820083E080000 +B3EA:000000083F882008200E3F88040804087FE800003EF802883E8820883EF80000 +B3EB:000000083F882008200E3F88040804087FE800003E8802883EF820883EF80000 +B3EC:000000083F882008200E3F88040804087FE800001F0801081F0810141F620000 +B3ED:000000083F882008200E3F88040804087FE800003EF802803EF820803EF80000 +B3EE:000000083F882008200E3F88040804087FE800003EFC02483E4820483EFC0000 +B3EF:000000083F882008200E3F88040804087FE800001F08017F1F1C10221F1C0000 +B3F0:000000083F882008200E3F88040804087FE8000003F802080208020803F80000 +B3F1:000000083F882008200E3F88040804087FE800000208020803F8020803F80000 +B3F2:000000083F882008200E3F88040804087FE80000110811081F0811141F620000 +B3F3:000000083F882008200E3F88040804087FE80000001000100010006801840000 +B3F4:000000083F882008200E3F88040804087FE800000048004800A8011406620000 +B3F5:000000083F882008200E3F88040804087FE80000000003F00408040803F00000 +B3F6:000000083F882008200E3F88040804087FE8000003F80020002000D003080000 +B3F7:000000083F882008200E3F88040804087FE80000004003F8004000A003180000 +B3F8:000000083F882008200E3F88040804087FE8000003F8000803F8000800080000 +B3F9:000000083F882008200E3F88040804087FE8000003F8020003F8020003F80000 +B3FA:000000083F882008200E3F88040804087FE8000000000FF8022002200FF80000 +B3FB:000000083F882008200E3F88040804087FE8000000800FF803E0041003E00000 +B3FC:0000001200127F924012401240127F9E00120012041204127FD2001200120000 +B3FD:000000283FA8202820383FA8042804287FA8000007F800080008000800080000 +B3FE:000000283FA8202820383FA8042804287FA8000000003EF80208020802080000 +B3FF:000000283FA8202820383FA8042804287FA8000000001F080108011401620000 +B400:000000283FA8202820383FA8042804287FA8000008000800080008000FF80000 +B401:000000283FA8202820383FA8042804287FA80000000010F8101010301ECC0000 +B402:000000283FA8202820383FA8042804287FA800000808087F081C08220F9C0000 +B403:000000283FA8202820383FA8042804287FA8000003F802000200020003F80000 +B404:000000283FA8202820383FA8042804287FA8000007F8000807F8040007F80000 +B405:000000283FA8202820383FA8042804287FA800003EF802083E0820083E080000 +B406:000000283FA8202820383FA8042804287FA800003EF802883E8820883EF80000 +B407:000000283FA8202820383FA8042804287FA800003E8802883EF820883EF80000 +B408:000000283FA8202820383FA8042804287FA800001F0801081F0810141F620000 +B409:000000283FA8202820383FA8042804287FA800003EF802803EF820803EF80000 +B40A:000000283FA8202820383FA8042804287FA800003EFC02483E4820483EFC0000 +B40B:000000283FA8202820383FA8042804287FA800001F08017F1F1C10221F1C0000 +B40C:000000283FA8202820383FA8042804287FA8000003F802080208020803F80000 +B40D:000000283FA8202820383FA8042804287FA800000208020803F8020803F80000 +B40E:000000283FA8202820383FA8042804287FA80000110811081F0811141F620000 +B40F:000000283FA8202820383FA8042804287FA80000001000100010006801840000 +B410:000000283FA8202820383FA8042804287FA800000048004800A8011406620000 +B411:000000283FA8202820383FA8042804287FA80000000003F00408040803F00000 +B412:000000283FA8202820383FA8042804287FA8000003F80020002000D003080000 +B413:000000283FA8202820383FA8042804287FA80000004003F8004000A003180000 +B414:000000283FA8202820383FA8042804287FA8000003F8000803F8000800080000 +B415:000000283FA8202820383FA8042804287FA8000003F8020003F8020003F80000 +B416:000000283FA8202820383FA8042804287FA8000000000FF8022002200FF80000 +B417:000000283FA8202820383FA8042804287FA8000000800FF803E0041003E00000 +B418:0000000800087F884008400840087F8800080008040804087FE8000800080000 +B419:000000083F88200820083F88040804087FE8000007F800080008000800080000 +B41A:000000083F88200820083F88040804087FE8000000003EF80208020802080000 +B41B:000000083F88200820083F88040804087FE8000000001F080108011401620000 +B41C:000000083F88200820083F88040804087FE8000008000800080008000FF80000 +B41D:000000083F88200820083F88040804087FE80000000010F8101010301ECC0000 +B41E:000000083F88200820083F88040804087FE800000808087F081C08220F9C0000 +B41F:000000083F88200820083F88040804087FE8000003F802000200020003F80000 +B420:000000083F88200820083F88040804087FE8000007F8000807F8040007F80000 +B421:000000083F88200820083F88040804087FE800003EF802083E0820083E080000 +B422:000000083F88200820083F88040804087FE800003EF802883E8820883EF80000 +B423:000000083F88200820083F88040804087FE800003E8802883EF820883EF80000 +B424:000000083F88200820083F88040804087FE800001F0801081F0810141F620000 +B425:000000083F88200820083F88040804087FE800003EF802803EF820803EF80000 +B426:000000083F88200820083F88040804087FE800003EFC02483E4820483EFC0000 +B427:000000083F88200820083F88040804087FE800001F08017F1F1C10221F1C0000 +B428:000000083F88200820083F88040804087FE8000003F802080208020803F80000 +B429:000000083F88200820083F88040804087FE800000208020803F8020803F80000 +B42A:000000083F88200820083F88040804087FE80000110811081F0811141F620000 +B42B:000000083F88200820083F88040804087FE80000001000100010006801840000 +B42C:000000083F88200820083F88040804087FE800000048004800A8011406620000 +B42D:000000083F88200820083F88040804087FE80000000003F00408040803F00000 +B42E:000000083F88200820083F88040804087FE8000003F80020002000D003080000 +B42F:000000083F88200820083F88040804087FE80000004003F8004000A003180000 +B430:000000083F88200820083F88040804087FE8000003F8000803F8000800080000 +B431:000000083F88200820083F88040804087FE8000003F8020003F8020003F80000 +B432:000000083F88200820083F88040804087FE8000000000FF8022002200FF80000 +B433:000000083F88200820083F88040804087FE8000000800FF803E0041003E00000 +B434:000000003FF820002000200020003FF8000004400440044004407FFC00000000 +B435:000000001FF0100010001FF0044004407FFC00001FF000100010001000100000 +B436:000000001FF0100010001FF0044004407FFC000000003EF80208020802080000 +B437:000000001FF0100010001FF0044004407FFC000000001E100210022802C40000 +B438:000000001FF0100010001FF0044004407FFC000000001000100010001FF00000 +B439:000000001FF0100010001FF0044004407FFC0000000020F8201020303ECC0000 +B43A:000000001FF0100010001FF0044004407FFC0000202021FC207020883E700000 +B43B:000000001FF0100010001FF0044004407FFC00001FF01000100010001FF00000 +B43C:000000001FF0100010001FF0044004407FFC00001FF000101FF010001FF00000 +B43D:000000001FF0100010001FF0044004407FFC00003EF802083E0820083E080000 +B43E:000000001FF0100010001FF0044004407FFC00003EF802883E8820883EF80000 +B43F:000000001FF0100010001FF0044004407FFC00003E8802883EF820883EF80000 +B440:000000001FF0100010001FF0044004407FFC00003E1002103E1020283EC40000 +B441:000000001FF0100010001FF0044004407FFC00003EF802803EF820803EF80000 +B442:000000001FF0100010001FF0044004407FFC00003EFC02483E4820483EFC0000 +B443:000000001FF0100010001FF0044004407FFC00003E2003FC3E7020883E700000 +B444:000000001FF0100010001FF0044004407FFC00001FF01010101010101FF00000 +B445:000000001FF0100010001FF0044004407FFC0000101010101FF010101FF00000 +B446:000000001FF0100010001FF0044004407FFC0000222022203E2022503E880000 +B447:000000001FF0100010001FF0044004407FFC000000000100010002800C400000 +B448:000000001FF0100010001FF0044004407FFC00000000024002400DA033100000 +B449:000000001FF0100010001FF0044004407FFC0000000007C00820082007C00000 +B44A:000000001FF0100010001FF0044004407FFC0000000007E00080014006200000 +B44B:000000001FF0100010001FF0044004407FFC0000008007E00080014006200000 +B44C:000000001FF0100010001FF0044004407FFC00001FF000101FF0001000100000 +B44D:000000001FF0100010001FF0044004407FFC00001FF010001FF010001FF00000 +B44E:000000001FF0100010001FF0044004407FFC000000001FF0044004401FF00000 +B44F:000000001FF0100010001FF0044004407FFC000001001FF007C0082007C00000 +B450:000000003FF820002000200020003FF8000000003FF801000100010001000000 +B451:000000001FF0100010001FF000007FFC010001001FF000100010001000100000 +B452:000000001FF0100010001FF000007FFC0100010000003EF80208020802080000 +B453:000000001FF0100010001FF000007FFC0100010000001E100210022802C40000 +B454:000000001FF0100010001FF0000000007FFC010001001100100010001FF00000 +B455:000000001FF0100010001FF000007FFC01000100000020F8201020303ECC0000 +B456:000000001FF0100010001FF000007FFC01000100202021FC207020883E700000 +B457:000000001FF0100010001FF000007FFC010001001FF01000100010001FF00000 +B458:000000001FF0100010001FF000007FFC010001001FF000101FF010001FF00000 +B459:000000001FF0100010001FF000007FFC010001003EF802083E0820083E080000 +B45A:000000001FF0100010001FF000007FFC010001003EF802883E8820883EF80000 +B45B:000000001FF0100010001FF000007FFC010001003E8802883EF820883EF80000 +B45C:000000001FF0100010001FF000007FFC010001003E1002103E1020283EC40000 +B45D:000000001FF0100010001FF000007FFC010001003EF802803EF820803EF80000 +B45E:000000001FF0100010001FF000007FFC010001003EFC02483E4820483EFC0000 +B45F:000000001FF0100010001FF000007FFC010001003E2003FC3E7020883E700000 +B460:000000001FF0100010001FF000007FFC010001001FF01010101010101FF00000 +B461:000000001FF0100010001FF000007FFC01000100101010101FF010101FF00000 +B462:000000001FF0100010001FF000007FFC01000100222022203E2022503E880000 +B463:000000001FF0100010001FF000007FFC0100010000000100010002800C400000 +B464:000000001FF0100010001FF000007FFC010001000000024002400DA033100000 +B465:000000001FF0100010001FF000007FFC01000100000007C00820082007C00000 +B466:000000001FF0100010001FF000007FFC01000100000007E00080014006200000 +B467:000000001FF0100010001FF000007FFC01000100008007E00080014006200000 +B468:000000001FF0100010001FF000007FFC010001001FF000101FF0001000100000 +B469:000000001FF0100010001FF000007FFC010001001FF010001FF010001FF00000 +B46A:000000001FF0100010001FF000007FFC0100010000001FF0044004401FF00000 +B46B:000000001FF0100010001FF000007FFC0100010001001FF007C0082007C00000 +B46C:0000000800087FC84008400840087FC8000800087FE8040804F8040804080000 +B46D:00083F88200820083F8800087FE8027802080000000007F80008000800080000 +B46E:00083F88200820083F8800087FE802780208000000003EF80208020802080000 +B46F:00083F88200820083F8800087FE802780208000000001F080108011401620000 +B470:00083F88200820083F88000800087FE80278020802081000100010001FF80000 +B471:00083F88200820083F8800087FE8027802080000000020F8201020303ECC0000 +B472:00083F88200820083F8800087FE8027802080000202021FC207020883E700000 +B473:00083F88200820083F8800087FE802780208000003F802000200020003F80000 +B474:00083F88200820083F8800087FE802780208000007F8000807F8040007F80000 +B475:00083F88200820083F8800087FE80278020800003EF802083E0820083E080000 +B476:00083F88200820083F8800087FE80278020800003EF802883E8820883EF80000 +B477:00083F88200820083F8800087FE80278020800003E8802883EF820883EF80000 +B478:00083F88200820083F8800087FE80278020800000F8800880F8808140FA20000 +B479:00083F88200820083F8800087FE80278020800003EF802803EF820803EF80000 +B47A:00083F88200820083F8800087FE80278020800003EFC02483E4820483EFC0000 +B47B:00083F88200820083F8800087FE80278020800003E1002FE3E3820443E380000 +B47C:00083F88200820083F8800087FE802780208000003F802080208020803F80000 +B47D:00083F88200820083F8800087FE80278020800000208020803F8020803F80000 +B47E:00083F88200820083F8800087FE8027802080000210821083F0821143F620000 +B47F:00083F88200820083F8800087FE8027802080000001000100010006801840000 +B480:00083F88200820083F8800087FE80278020800000048004800A8011406620000 +B481:00083F88200820083F8800087FE8027802080000000003F00408040803F00000 +B482:00083F88200820083F8800087FE802780208000003F80020002000D003080000 +B483:00083F88200820083F8800087FE8027802080000004003F8004000A003180000 +B484:00083F88200820083F8800087FE802780208000003F8000803F8000800080000 +B485:00083F88200820083F8800087FE802780208000003F8020003F8020003F80000 +B486:00083F88200820083F8800087FE802780208000000000FF8022002200FF80000 +B487:00083F88200820083F8800087FE802780208000000800FF803E0041003E00000 +B488:0000000A000A7FCA400A400A400A7FCA000A000A7FEA040A047A040A040A0000 +B489:00283FA8202820283FA800287FA805E804280000000007F80008000800080000 +B48A:00283FA8202820283FA800287FA805E80428000000003EF80208020802080000 +B48B:00283FA8202820283FA800287FA805E80428000000001F080108011401620000 +B48C:00283FA8202820283FA8002800287FA8042805E804281428100010001FF80000 +B48D:00283FA8202820283FA800287FA805E804280000000020F8201020303ECC0000 +B48E:00283FA8202820283FA800287FA805E804280000202021FC207020883E700000 +B48F:00283FA8202820283FA800287FA805E80428000003F802000200020003F80000 +B490:00283FA8202820283FA800287FA805E80428000007F8000807F8040007F80000 +B491:00283FA8202820283FA800287FA805E8042800003EF802083E0820083E080000 +B492:00283FA8202820283FA800287FA805E8042800003EF802883E8820883EF80000 +B493:00283FA8202820283FA800287FA805E8042800003E8802883EF820883EF80000 +B494:00283FA8202820283FA800287FA805E8042800000F8800880F8808140FA20000 +B495:00283FA8202820283FA800287FA805E8042800003EF802803EF820803EF80000 +B496:00283FA8202820283FA800287FA805E8042800003EFC02483E4820483EFC0000 +B497:00283FA8202820283FA800287FA805E8042800003E1002FE3E3820443E380000 +B498:00283FA8202820283FA800287FA805E80428000003F802080208020803F80000 +B499:00283FA8202820283FA800287FA805E8042800000208020803F8020803F80000 +B49A:00283FA8202820283FA800287FA805E804280000210821083F0821143F620000 +B49B:00283FA8202820283FA800287FA805E804280000001000100010006801840000 +B49C:00283FA8202820283FA800287FA805E8042800000048004800A8011406620000 +B49D:00283FA8202820283FA800287FA805E804280000000003F00408040803F00000 +B49E:00283FA8202820283FA800287FA805E80428000003F80020002000D003080000 +B49F:00283FA8202820283FA800287FA805E804280000004003F8004000A003180000 +B4A0:00283FA8202820283FA800287FA805E80428000003F8000803F8000800080000 +B4A1:00283FA8202820283FA800287FA805E80428000003F8020003F8020003F80000 +B4A2:00283FA8202820283FA800287FA805E80428000000000FF8022002200FF80000 +B4A3:00283FA8202820283FA800287FA805E80428000000800FF803E0041003E00000 +B4A4:0000000800087FC84008400840087FC8000800087FE804080408040804080000 +B4A5:00083F88200820083F8800087FE8020802000000000007F80008000800080000 +B4A6:00083F88200820083F8800087FE802080200000000003EF80208020802080000 +B4A7:00083F88200820083F8800087FE802080200000000001F080108011401620000 +B4A8:00083F88200820083F88000800087FE80208020802081008100010001FF80000 +B4A9:00083F88200820083F8800087FE8020802000000000020F8201020303ECC0000 +B4AA:00083F88200820083F8800087FE8020802000000202021FC207020883E700000 +B4AB:00083F88200820083F8800087FE802080200000003F802000200020003F80000 +B4AC:00083F88200820083F8800087FE802080200000007F8000807F8040007F80000 +B4AD:00083F88200820083F8800087FE80208020000003EF802083E0820083E080000 +B4AE:00083F88200820083F8800087FE80208020000003EF802883E8820883EF80000 +B4AF:00083F88200820083F8800087FE80208020000003E8802883EF820883EF80000 +B4B0:00083F88200820083F8800087FE80208020000000F8800880F8808140FA20000 +B4B1:00083F88200820083F8800087FE80208020000003EF802803EF820803EF80000 +B4B2:00083F88200820083F8800087FE80208020000003EFC02483E4820483EFC0000 +B4B3:00083F88200820083F8800087FE80208020000003E1002FE3E3820443E380000 +B4B4:00083F88200820083F8800087FE802080200000003F802080208020803F80000 +B4B5:00083F88200820083F8800087FE80208020000000208020803F8020803F80000 +B4B6:00083F88200820083F8800087FE8020802000000210821083F0821143F620000 +B4B7:00083F88200820083F8800087FE8020802000000001000100010006801840000 +B4B8:00083F88200820083F8800087FE80208020000000048004800A8011406620000 +B4B9:00083F88200820083F8800087FE8020802000000000003F00408040803F00000 +B4BA:00083F88200820083F8800087FE802080200000003F80020002000D003080000 +B4BB:00083F88200820083F8800087FE8020802000000004003F8004000A003180000 +B4BC:00083F88200820083F8800087FE802080200000003F8000803F8000800080000 +B4BD:00083F88200820083F8800087FE802080200000003F8020003F8020003F80000 +B4BE:00083F88200820083F8800087FE802080200000000000FF8022002200FF80000 +B4BF:00083F88200820083F8800087FE802080200000000800FF803E0041003E00000 +B4C0:000000003FF820002000200020003FF8000000007FFC04400440044004400000 +B4C1:000000001FF0100010001FF000007FFC044004401FF000100010001000100000 +B4C2:000000001FF0100010001FF000007FFC0440044000003EF80208020802080000 +B4C3:000000001FF0100010001FF000007FFC0440044000001E100210022802C40000 +B4C4:000000001FF0100010001FF0000000007FFC044004401440100010001FF00000 +B4C5:000000001FF0100010001FF000007FFC04400440000020F8201020303ECC0000 +B4C6:000000001FF0100010001FF000007FFC04400440202021FC207020883E700000 +B4C7:000000001FF0100010001FF000007FFC044004401FF01000100010001FF00000 +B4C8:000000001FF0100010001FF000007FFC044004401FF000101FF010001FF00000 +B4C9:000000001FF0100010001FF000007FFC044004403EF802083E0820083E080000 +B4CA:000000001FF0100010001FF000007FFC044004403EF802883E8820883EF80000 +B4CB:000000001FF0100010001FF000007FFC044004403E8802883EF820883EF80000 +B4CC:000000001FF0100010001FF000007FFC044004403E1002103E1020283EC40000 +B4CD:000000001FF0100010001FF000007FFC044004403EF802803EF820803EF80000 +B4CE:000000001FF0100010001FF000007FFC044004403EFC02483E4820483EFC0000 +B4CF:000000001FF0100010001FF000007FFC044004403E2003FC3E7020883E700000 +B4D0:000000001FF0100010001FF000007FFC044004401FF01010101010101FF00000 +B4D1:000000001FF0100010001FF000007FFC04400440101010101FF010101FF00000 +B4D2:000000001FF0100010001FF000007FFC04400440222022203E2022503E880000 +B4D3:000000001FF0100010001FF000007FFC0440044000000100010002800C400000 +B4D4:000000001FF0100010001FF000007FFC044004400000024002400DA033100000 +B4D5:000000001FF0100010001FF000007FFC04400440000007C00820082007C00000 +B4D6:000000001FF0100010001FF000007FFC04400440000007E00080014006200000 +B4D7:000000001FF0100010001FF000007FFC04400440008007E00080014006200000 +B4D8:000000001FF0100010001FF000007FFC044004401FF000101FF0001000100000 +B4D9:000000001FF0100010001FF000007FFC044004401FF010001FF010001FF00000 +B4DA:000000001FF0100010001FF000007FFC0440044000001FF0044004401FF00000 +B4DB:000000001FF0100010001FF000007FFC0440044001001FF007C0082007C00000 +B4DC:000000003FF820002000200020003FF80000000000007FFC0000000000000000 +B4DD:000000001FF0100010001FF0000000007FFC00001FF000100010001000100000 +B4DE:000000001FF0100010001FF0000000007FFC000000003EF80208020802080000 +B4DF:000000001FF0100010001FF0000000007FFC000000001E100210022802C40000 +B4E0:000000001FF0100010001FF0000000007FFC000000001000100010001FF00000 +B4E1:000000001FF0100010001FF0000000007FFC0000000020F8201020303ECC0000 +B4E2:000000001FF0100010001FF0000000007FFC0000202021FC207020883E700000 +B4E3:000000001FF0100010001FF0000000007FFC00001FF01000100010001FF00000 +B4E4:000000001FF0100010001FF0000000007FFC00001FF000101FF010001FF00000 +B4E5:000000001FF0100010001FF0000000007FFC00003EF802083E0820083E080000 +B4E6:000000001FF0100010001FF0000000007FFC00003EF802883E8820883EF80000 +B4E7:000000001FF0100010001FF0000000007FFC00003E8802883EF820883EF80000 +B4E8:000000001FF0100010001FF0000000007FFC00003E1002103E1020283EC40000 +B4E9:000000001FF0100010001FF0000000007FFC00003EF802803EF820803EF80000 +B4EA:000000001FF0100010001FF0000000007FFC00003EFC02483E4820483EFC0000 +B4EB:000000001FF0100010001FF0000000007FFC00003E2003FC3E7020883E700000 +B4EC:000000001FF0100010001FF0000000007FFC00001FF01010101010101FF00000 +B4ED:000000001FF0100010001FF0000000007FFC0000101010101FF010101FF00000 +B4EE:000000001FF0100010001FF0000000007FFC0000222022203E2022503E880000 +B4EF:000000001FF0100010001FF0000000007FFC000000000100010002800C400000 +B4F0:000000001FF0100010001FF0000000007FFC00000000024002400DA033100000 +B4F1:000000001FF0100010001FF0000000007FFC0000000007C00820082007C00000 +B4F2:000000001FF0100010001FF0000000007FFC0000000007E00080014006200000 +B4F3:000000001FF0100010001FF0000000007FFC0000008007E00080014006200000 +B4F4:000000001FF0100010001FF0000000007FFC00001FF000101FF0001000100000 +B4F5:000000001FF0100010001FF0000000007FFC00001FF010001FF010001FF00000 +B4F6:000000001FF0100010001FF0000000007FFC000000001FF0044004401FF00000 +B4F7:000000001FF0100010001FF0000000007FFC000001001FF007C0082007C00000 +B4F8:0000000800087F884008400840087F880008000800087FE80008000800080000 +B4F9:000000083F88200820083F88000800087FE8000007F800080008000800080000 +B4FA:000000083F88200820083F88000800087FE8000000003EF80208020802080000 +B4FB:000000083F88200820083F88000800087FE8000000001F080108011401620000 +B4FC:000000083F88200820083F88000800087FE8000008000800080008000FF80000 +B4FD:000000083F88200820083F88000800087FE80000000010F8101010301ECC0000 +B4FE:000000083F88200820083F88000800087FE800000808087F081C08220F9C0000 +B4FF:000000083F88200820083F88000800087FE8000003F802000200020003F80000 +B500:000000083F88200820083F88000800087FE8000007F8000807F8040007F80000 +B501:000000083F88200820083F88000800087FE800003EF802083E0820083E080000 +B502:000000083F88200820083F88000800087FE800003EF802883E8820883EF80000 +B503:000000083F88200820083F88000800087FE800003E8802883EF820883EF80000 +B504:000000083F88200820083F88000800087FE800001F0801081F0810141F620000 +B505:000000083F88200820083F88000800087FE800003EF802803EF820803EF80000 +B506:000000083F88200820083F88000800087FE800003EFC02483E4820483EFC0000 +B507:000000083F88200820083F88000800087FE800001F08017F1F1C10221F1C0000 +B508:000000083F88200820083F88000800087FE8000003F802080208020803F80000 +B509:000000083F88200820083F88000800087FE800000208020803F8020803F80000 +B50A:000000083F88200820083F88000800087FE80000110811081F0811141F620000 +B50B:000000083F88200820083F88000800087FE80000001000100010006801840000 +B50C:000000083F88200820083F88000800087FE800000048004800A8011406620000 +B50D:000000083F88200820083F88000800087FE80000000003F00408040803F00000 +B50E:000000083F88200820083F88000800087FE8000003F80020002000D003080000 +B50F:000000083F88200820083F88000800087FE80000004003F8004000A003180000 +B510:000000083F88200820083F88000800087FE8000003F8000803F8000800080000 +B511:000000083F88200820083F88000800087FE8000003F8020003F8020003F80000 +B512:000000083F88200820083F88000800087FE8000000000FF8022002200FF80000 +B513:000000083F88200820083F88000800087FE8000000800FF803E0041003E00000 +B514:00000000000800087F88400840084008400840087F8800080008000800080000 +B515:0000000800087E084008400840087E0800080000000007F80008000800080000 +B516:0000000800087E084008400840087E080008000000003EF80208020802080000 +B517:0000000800087E084008400840087E080008000000001F080108011401620000 +B518:0000000800087E084008400840087E080008000800001000100010001FF80000 +B519:0000000800087E084008400840087E0800080000000020F8201020303ECC0000 +B51A:0000000800087E084008400840087E0800080000202021FC207020883E700000 +B51B:0000000800087E084008400840087E080008000003F802000200020003F80000 +B51C:0000000800087E084008400840087E080008000007F8000807F8040007F80000 +B51D:0000000800087E084008400840087E08000800003EF802083E0820083E080000 +B51E:0000000800087E084008400840087E08000800003EF802883E8820883EF80000 +B51F:0000000800087E084008400840087E08000800003E8802883EF820883EF80000 +B520:0000000800087E084008400840087E08000800000F8800880F8808140FA20000 +B521:0000000800087E084008400840087E08000800003EF802803EF820803EF80000 +B522:0000000800087E084008400840087E08000800003EFC02483E4820483EFC0000 +B523:0000000800087E084008400840087E08000800003E1002FE3E3820443E380000 +B524:0000000800087E084008400840087E080008000003F802080208020803F80000 +B525:0000000800087E084008400840087E08000800000208020803F8020803F80000 +B526:0000000800087E084008400840087E0800080000210821083F0821143F620000 +B527:0000000800087E084008400840087E0800080000001000100010006801840000 +B528:0000000800087E084008400840087E08000800000048004800A8011406620000 +B529:0000000800087E084008400840087E0800080000000003F00408040803F00000 +B52A:0000000800087E084008400840087E080008000003F80020002000D003080000 +B52B:0000000800087E084008400840087E0800080000004003F8004000A003180000 +B52C:0000000800087E084008400840087E080008000003F8000803F8000800080000 +B52D:0000000800087E084008400840087E080008000003F8020003F8020003F80000 +B52E:0000000800087E084008400840087E080008000000000FF8022002200FF80000 +B52F:0000000800087E084008400840087E080008000000800FF803E0041003E00000 +B530:00000000001000107BD042104210421E421042107BD000100010001000100000 +B531:00000008000877084408440E440877080008000007F800080008000800080000 +B532:00000008000877084408440E440877080008000000003EF80208020802080000 +B533:00000008000877084408440E440877080008000000001F080108011401620000 +B534:00000008000877084408440E440877080008000808000800080008000FF80000 +B535:00000008000877084408440E4408770800080000000010F8101010301ECC0000 +B536:00000008000877084408440E44087708000800000808087F081C08220F9C0000 +B537:00000008000877084408440E440877080008000003F802000200020003F80000 +B538:00000008000877084408440E440877080008000007F8000807F8040007F80000 +B539:00000008000877084408440E44087708000800003EF802083E0820083E080000 +B53A:00000008000877084408440E44087708000800003EF802883E8820883EF80000 +B53B:00000008000877084408440E44087708000800003E8802883EF820883EF80000 +B53C:00000008000877084408440E44087708000800001F0801081F0810141F620000 +B53D:00000008000877084408440E44087708000800003EF802803EF820803EF80000 +B53E:00000008000877084408440E44087708000800003EFC02483E4820483EFC0000 +B53F:00000008000877084408440E44087708000800001F08017F1F1C10221F1C0000 +B540:00000008000877084408440E440877080008000003F802080208020803F80000 +B541:00000008000877084408440E44087708000800000208020803F8020803F80000 +B542:00000008000877084408440E4408770800080000110811081F0811141F620000 +B543:00000008000877084408440E4408770800080000001000100010006801840000 +B544:00000008000877084408440E44087708000800000048004800A8011406620000 +B545:00000008000877084408440E4408770800080000000003F00408040803F00000 +B546:00000008000877084408440E440877080008000003F80020002000D003080000 +B547:00000008000877084408440E4408770800080000004003F8004000A003180000 +B548:00000008000877084408440E440877080008000003F8000803F8000800080000 +B549:00000008000877084408440E440877080008000003F8020003F8020003F80000 +B54A:00000008000877084408440E440877080008000000000FF8022002200FF80000 +B54B:00000008000877084408440E440877080008000000800FF803E0041003E00000 +B54C:00000000001200127BD242124212421E421242127BD200120012001200120000 +B54D:000000280028772844284438442877280028000007F800080008000800080000 +B54E:000000280028772844284438442877280028000000003EF80208020802080000 +B54F:000000280028772844284438442877280028000000003E100210022802C40000 +B550:000000280028772844284438442877280028002808000800080008000FF80000 +B551:0000002800287728442844384428772800280000000020F8201020303ECC0000 +B552:0000002800287728442844384428772800280000202021FC207020883E700000 +B553:000000280028772844284438442877280028000003F802000200020003F80000 +B554:000000280028772844284438442877280028000007F8000807F8040007F80000 +B555:00000028002877284428443844287728002800003EF802083E0820083E080000 +B556:00000028002877284428443844287728002800003EF802883E8820883EF80000 +B557:00000028002877284428443844287728002800003E8802883EF820883EF80000 +B558:00000028002877284428443844287728002800001F0801081F0810141F620000 +B559:00000028002877284428443844287728002800003EF802803EF820803EF80000 +B55A:00000028002877284428443844287728002800003EFC02483E4820483EFC0000 +B55B:00000028002877284428443844287728002800003E1002FE3E3820443E380000 +B55C:000000280028772844284438442877280028000003F802080208020803F80000 +B55D:00000028002877284428443844287728002800000208020803F8020803F80000 +B55E:0000002800287728442844384428772800280000110811081F0811141F620000 +B55F:0000002800287728442844384428772800280000000800080008003400C20000 +B560:00000028002877284428443844287728002800000048004800A8011406620000 +B561:0000002800287728442844384428772800280000000001F00208020801F00000 +B562:000000280028772844284438442877280028000003F80020002000D003080000 +B563:0000002800287728442844384428772800280000004003F8004000A003180000 +B564:000000280028772844284438442877280028000003F8000803F8000800080000 +B565:000000280028772844284438442877280028000003F8020003F8020003F80000 +B566:000000280028772844284438442877280028000000000FF8022002200FF80000 +B567:000000280028772844284438442877280028000000800FF803E0041003E00000 +B568:00000000001000107BD04210421E42104210421E7BD000100010001000100000 +B569:0000000800087708440E4408440E77080008000007F800080008000800080000 +B56A:0000000800087708440E4408440E77080008000000003EF80208020802080000 +B56B:0000000800087708440E4408440E77080008000000001F080108011401620000 +B56C:0000000800087708440E4408440E77080008000008000800080008000FF80000 +B56D:0000000800087708440E4408440E770800080000000010F8101010301ECC0000 +B56E:0000000800087708440E4408440E7708000800000808087F081C08220F9C0000 +B56F:0000000800087708440E4408440E77080008000003F802000200020003F80000 +B570:0000000800087708440E4408440E77080008000007F8000807F8040007F80000 +B571:0000000800087708440E4408440E7708000800003EF802083E0820083E080000 +B572:0000000800087708440E4408440E7708000800003EF802883E8820883EF80000 +B573:0000000800087708440E4408440E7708000800003E8802883EF820883EF80000 +B574:0000000800087708440E4408440E7708000800001F0801081F0810141F620000 +B575:0000000800087708440E4408440E7708000800003EF802803EF820803EF80000 +B576:0000000800087708440E4408440E7708000800003EFC02483E4820483EFC0000 +B577:0000000800087708440E4408440E7708000800001F08017F1F1C10221F1C0000 +B578:0000000800087708440E4408440E77080008000003F802080208020803F80000 +B579:0000000800087708440E4408440E7708000800000208020803F8020803F80000 +B57A:0000000800087708440E4408440E770800080000110811081F0811141F620000 +B57B:0000000800087708440E4408440E770800080000001000100010006801840000 +B57C:0000000800087708440E4408440E7708000800000048004800A8011406620000 +B57D:0000000800087708440E4408440E770800080000000003F00408040803F00000 +B57E:0000000800087708440E4408440E77080008000003F80020002000D003080000 +B57F:0000000800087708440E4408440E770800080000004003F8004000A003180000 +B580:0000000800087708440E4408440E77080008000003F8000803F8000800080000 +B581:0000000800087708440E4408440E77080008000003F8020003F8020003F80000 +B582:0000000800087708440E4408440E77080008000000000FF8022002200FF80000 +B583:0000000800087708440E4408440E77080008000000800FF803E0041003E00000 +B584:00000000001200127BD24212421E42124212421E7BD200120012001200120000 +B585:000000280028772844384428443877280028000007F800080008000800080000 +B586:000000280028772844384428443877280028000000003EF80208020802080000 +B587:000000280028772844384428443877280028000000003E100210022802C40000 +B588:000000280028772844384428443877280028002808000800080008000FF80000 +B589:0000002800287728443844284438772800280000000020F8201020303ECC0000 +B58A:0000002800287728443844284438772800280000202021FC207020883E700000 +B58B:000000280028772844384428443877280028000003F802000200020003F80000 +B58C:000000280028772844384428443877280028000007F8000807F8040007F80000 +B58D:00000028002877284438442844387728002800003EF802083E0820083E080000 +B58E:00000028002877284438442844387728002800003EF802883E8820883EF80000 +B58F:00000028002877284438442844387728002800003E8802883EF820883EF80000 +B590:00000028002877284438442844387728002800001F0801081F0810141F620000 +B591:00000028002877284438442844387728002800003EF802803EF820803EF80000 +B592:00000028002877284438442844387728002800003EFC02483E4820483EFC0000 +B593:00000028002877284438442844387728002800003E1002FE3E3820443E380000 +B594:000000280028772844384428443877280028000003F802080208020803F80000 +B595:00000028002877284438442844387728002800000208020803F8020803F80000 +B596:0000002800287728443844284438772800280000110811081F0811141F620000 +B597:0000002800287728443844284438772800280000000800080008003400C20000 +B598:00000028002877284438442844387728002800000048004800A8011406620000 +B599:0000002800287728443844284438772800280000000001F00208020801F00000 +B59A:000000280028772844384428443877280028000003F80020002000D003080000 +B59B:0000002800287728443844284438772800280000004003F8004000A003180000 +B59C:000000280028772844384428443877280028000003F8000803F8000800080000 +B59D:000000280028772844384428443877280028000003F8020003F8020003F80000 +B59E:000000280028772844384428443877280028000000000FF8022002200FF80000 +B59F:000000280028772844384428443877280028000000800FF803E0041003E00000 +B5A0:00000000000200027BC242024202421E420242027BC200020002000200020000 +B5A1:0000000800087708440844384408770800080000000007F80008000800080000 +B5A2:000000080008770844084438440877080008000000003EF80208020802080000 +B5A3:000000080008770844084438440877080008000000001F080108011401620000 +B5A4:000000080008770844084438440877080008000000001000100010001FF80000 +B5A5:0000000800087708440844384408770800080000000020F8201020303ECC0000 +B5A6:0000000800087708440844384408770800080000202021FC207020883E700000 +B5A7:000000080008770844084438440877080008000003F802000200020003F80000 +B5A8:000000080008770844084438440877080008000007F8000807F8040007F80000 +B5A9:00000008000877084408443844087708000800003EF802083E0820083E080000 +B5AA:00000008000877084408443844087708000800003EF802883E8820883EF80000 +B5AB:00000008000877084408443844087708000800003E8802883EF820883EF80000 +B5AC:00000008000877084408443844087708000800000F8800880F8808140FA20000 +B5AD:00000008000877084408443844087708000800003EF802803EF820803EF80000 +B5AE:00000008000877084408443844087708000800003EFC02483E4820483EFC0000 +B5AF:00000008000877084408443844087708000800003E1002FE3E3820443E380000 +B5B0:000000080008770844084438440877080008000003F802080208020803F80000 +B5B1:00000008000877084408443844087708000800000208020803F8020803F80000 +B5B2:0000000800087708440844384408770800080000210821083F0821143F620000 +B5B3:0000000800087708440844384408770800080000001000100010006801840000 +B5B4:00000008000877084408443844087708000800000048004800A8011406620000 +B5B5:0000000800087708440844384408770800080000000003F00408040803F00000 +B5B6:000000080008770844084438440877080008000003F80020002000D003080000 +B5B7:0000000800087708440844384408770800080000004003F8004000A003180000 +B5B8:000000080008770844084438440877080008000003F8000803F8000800080000 +B5B9:000000080008770844084438440877080008000003F8020003F8020003F80000 +B5BA:000000080008770844084438440877080008000000000FF8022002200FF80000 +B5BB:000000080008770844084438440877080008000000800FF803E0041003E00000 +B5BC:00000000000A000A7BCA420A420A423A420A420A7BCA000A000A000A000A0000 +B5BD:0000002800287728442844E8442877280028000007F800080008000800080000 +B5BE:0000002800287728442844E8442877280028000000003EF80208020802080000 +B5BF:0000002800287728442844E8442877280028000000003E100210022802C40000 +B5C0:0000002800287728442844E8442877280028000008000800080008000FF80000 +B5C1:0000002800287728442844E84428772800280000000020F8201020303ECC0000 +B5C2:0000002800287728442844E84428772800280000202021FC207020883E700000 +B5C3:0000002800287728442844E8442877280028000003F802000200020003F80000 +B5C4:0000002800287728442844E8442877280028000007F8000807F8040007F80000 +B5C5:0000002800287728442844E844287728002800003EF802083E0820083E080000 +B5C6:0000002800287728442844E844287728002800003EF802883E8820883EF80000 +B5C7:0000002800287728442844E844287728002800003E8802883EF820883EF80000 +B5C8:0000002800287728442844E844287728002800001F0801081F0810141F620000 +B5C9:0000002800287728442844E844287728002800003EF802803EF820803EF80000 +B5CA:0000002800287728442844E844287728002800003EFC02483E4820483EFC0000 +B5CB:0000002800287728442844E844287728002800003E1002FE3E3820443E380000 +B5CC:0000002800287728442844E8442877280028000003F802080208020803F80000 +B5CD:0000002800287728442844E844287728002800000208020803F8020803F80000 +B5CE:0000002800287728442844E84428772800280000110811081F0811141F620000 +B5CF:0000002800287728442844E84428772800280000000800080008003400C20000 +B5D0:0000002800287728442844E844287728002800000048004800A8011406620000 +B5D1:0000002800287728442844E84428772800280000000001F00208020801F00000 +B5D2:0000002800287728442844E8442877280028000003F80020002000D003080000 +B5D3:0000002800287728442844E84428772800280000004003F8004000A003180000 +B5D4:0000002800287728442844E8442877280028000003F8000803F8000800080000 +B5D5:0000002800287728442844E8442877280028000003F8020003F8020003F80000 +B5D6:0000002800287728442844E8442877280028000000000FF8022002200FF80000 +B5D7:0000002800287728442844E8442877280028000000800FF803E0041003E00000 +B5D8:00000000000200027BC24202421E42024202421E7BC200020002000200020000 +B5D9:0000000800087708443844084438770800080000000007F80008000800080000 +B5DA:000000080008770844384408443877080008000000003EF80208020802080000 +B5DB:000000080008770844384408443877080008000000001F080108011401620000 +B5DC:000000080008770844384408443877080008000800001000100010001FF80000 +B5DD:0000000800087708443844084438770800080000000020F8201020303ECC0000 +B5DE:0000000800087708443844084438770800080000202021FC207020883E700000 +B5DF:000000080008770844384408443877080008000003F802000200020003F80000 +B5E0:000000080008770844384408443877080008000007F8000807F8040007F80000 +B5E1:00000008000877084438440844387708000800003EF802083E0820083E080000 +B5E2:00000008000877084438440844387708000800003EF802883E8820883EF80000 +B5E3:00000008000877084438440844387708000800003E8802883EF820883EF80000 +B5E4:00000008000877084438440844387708000800000F8800880F8808140FA20000 +B5E5:00000008000877084438440844387708000800003EF802803EF820803EF80000 +B5E6:00000008000877084438440844387708000800003EFC02483E4820483EFC0000 +B5E7:00000008000877084438440844387708000800003E1002FE3E3820443E380000 +B5E8:000000080008770844384408443877080008000003F802080208020803F80000 +B5E9:00000008000877084438440844387708000800000208020803F8020803F80000 +B5EA:0000000800087708443844084438770800080000210821083F0821143F620000 +B5EB:0000000800087708443844084438770800080000001000100010006801840000 +B5EC:00000008000877084438440844387708000800000048004800A8011406620000 +B5ED:0000000800087708443844084438770800080000000003F00408040803F00000 +B5EE:000000080008770844384408443877080008000003F80020002000D003080000 +B5EF:0000000800087708443844084438770800080000004003F8004000A003180000 +B5F0:000000080008770844384408443877080008000003F8000803F8000800080000 +B5F1:000000080008770844384408443877080008000003F8020003F8020003F80000 +B5F2:000000080008770844384408443877080008000000000FF8022002200FF80000 +B5F3:000000080008770844384408443877080008000000800FF803E0041003E00000 +B5F4:00000000000A000A7BCA420A423A420A420A423A7BCA000A000A000A000A0000 +B5F5:000000280028772844E8442844E877280028000007F800080008000800080000 +B5F6:000000280028772844E8442844E877280028000000003EF80208020802080000 +B5F7:000000280028772844E8442844E877280028000000003E100210022802C40000 +B5F8:000000280028772844E8442844E877280028002808000800080008000FF80000 +B5F9:000000280028772844E8442844E8772800280000000020F8201020303ECC0000 +B5FA:000000280028772844E8442844E8772800280000202021FC207020883E700000 +B5FB:000000280028772844E8442844E877280028000003F802000200020003F80000 +B5FC:000000280028772844E8442844E877280028000007F8000807F8040007F80000 +B5FD:000000280028772844E8442844E87728002800003EF802083E0820083E080000 +B5FE:000000280028772844E8442844E87728002800003EF802883E8820883EF80000 +B5FF:000000280028772844E8442844E87728002800003E8802883EF820883EF80000 +B600:000000280028772844E8442844E87728002800001F0801081F0810141F620000 +B601:000000280028772844E8442844E87728002800003EF802803EF820803EF80000 +B602:000000280028772844E8442844E87728002800003EFC02483E4820483EFC0000 +B603:000000280028772844E8442844E87728002800003E1002FE3E3820443E380000 +B604:000000280028772844E8442844E877280028000003F802080208020803F80000 +B605:000000280028772844E8442844E87728002800000208020803F8020803F80000 +B606:000000280028772844E8442844E8772800280000110811081F0811141F620000 +B607:000000280028772844E8442844E8772800280000000800080008003400C20000 +B608:000000280028772844E8442844E87728002800000048004800A8011406620000 +B609:000000280028772844E8442844E8772800280000000001F00208020801F00000 +B60A:000000280028772844E8442844E877280028000003F80020002000D003080000 +B60B:000000280028772844E8442844E8772800280000004003F8004000A003180000 +B60C:000000280028772844E8442844E877280028000003F8000803F8000800080000 +B60D:000000280028772844E8442844E877280028000003F8020003F8020003F80000 +B60E:000000280028772844E8442844E877280028000000000FF8022002200FF80000 +B60F:000000280028772844E8442844E877280028000000800FF803E0041003E00000 +B610:000000003EF820802080208020803EF8000000000100010001007FFC00000000 +B611:000000001EF0108010801EF0010001007FFC00001FF000100010001000100000 +B612:000000001EF0108010801EF0010001007FFC000000003EF80208020802080000 +B613:000000001EF0108010801EF0010001007FFC000000001E100210022802C40000 +B614:000000001EF0108010801EF0010001007FFC000000001000100010001FF00000 +B615:000000001EF0108010801EF0010001007FFC0000000020F8201020303ECC0000 +B616:000000001EF0108010801EF0010001007FFC0000202021FC207020883E700000 +B617:000000001EF0108010801EF0010001007FFC00001FF01000100010001FF00000 +B618:000000001EF0108010801EF0010001007FFC00001FF000101FF010001FF00000 +B619:000000001EF0108010801EF0010001007FFC00003EF802083E0820083E080000 +B61A:000000001EF0108010801EF0010001007FFC00003EF802883E8820883EF80000 +B61B:000000001EF0108010801EF0010001007FFC00003E8802883EF820883EF80000 +B61C:000000001EF0108010801EF0010001007FFC00003E1002103E1020283EC40000 +B61D:000000001EF0108010801EF0010001007FFC00003EF802803EF820803EF80000 +B61E:000000001EF0108010801EF0010001007FFC00003EFC02483E4820483EFC0000 +B61F:000000001EF0108010801EF0010001007FFC00003E2003FC3E7020883E700000 +B620:000000001EF0108010801EF0010001007FFC00001FF01010101010101FF00000 +B621:000000001EF0108010801EF0010001007FFC0000101010101FF010101FF00000 +B622:000000001EF0108010801EF0010001007FFC0000222022203E2022503E880000 +B623:000000001EF0108010801EF0010001007FFC000000000100010002800C400000 +B624:000000001EF0108010801EF0010001007FFC00000000024002400DA033100000 +B625:000000001EF0108010801EF0010001007FFC0000000007C00820082007C00000 +B626:000000001EF0108010801EF0010001007FFC0000000007E00080014006200000 +B627:000000001EF0108010801EF0010001007FFC0000008007E00080014006200000 +B628:000000001EF0108010801EF0010001007FFC00001FF000101FF0001000100000 +B629:000000001EF0108010801EF0010001007FFC00001FF010001FF010001FF00000 +B62A:000000001EF0108010801EF0010001007FFC000000001FF0044004401FF00000 +B62B:000000001EF0108010801EF0010001007FFC000001001FF007C0082007C00000 +B62C:0000001000107BD0421042104210421E7BD00010041004107FD0001000100000 +B62D:000000083B882208220E3B88040804087FE8000007F800080008000800080000 +B62E:000000083B882208220E3B88040804087FE8000000003EF80208020802080000 +B62F:000000083B882208220E3B88040804087FE8000000001F080108011401620000 +B630:000000083B882208220E3B88040804087FE8000008000800080008000FF80000 +B631:000000083B882208220E3B88040804087FE80000000010F8101010301ECC0000 +B632:000000083B882208220E3B88040804087FE800000808087F081C08220F9C0000 +B633:000000083B882208220E3B88040804087FE8000003F802000200020003F80000 +B634:000000083B882208220E3B88040804087FE8000007F8000807F8040007F80000 +B635:000000083B882208220E3B88040804087FE800003EF802083E0820083E080000 +B636:000000083B882208220E3B88040804087FE800003EF802883E8820883EF80000 +B637:000000083B882208220E3B88040804087FE800003E8802883EF820883EF80000 +B638:000000083B882208220E3B88040804087FE800001F0801081F0810141F620000 +B639:000000083B882208220E3B88040804087FE800003EF802803EF820803EF80000 +B63A:000000083B882208220E3B88040804087FE800003EFC02483E4820483EFC0000 +B63B:000000083B882208220E3B88040804087FE800001F08017F1F1C10221F1C0000 +B63C:000000083B882208220E3B88040804087FE8000003F802080208020803F80000 +B63D:000000083B882208220E3B88040804087FE800000208020803F8020803F80000 +B63E:000000083B882208220E3B88040804087FE80000110811081F0811141F620000 +B63F:000000083B882208220E3B88040804087FE80000001000100010006801840000 +B640:000000083B882208220E3B88040804087FE800000048004800A8011406620000 +B641:000000083B882208220E3B88040804087FE80000000003F00408040803F00000 +B642:000000083B882208220E3B88040804087FE8000003F80020002000D003080000 +B643:000000083B882208220E3B88040804087FE80000004003F8004000A003180000 +B644:000000083B882208220E3B88040804087FE8000003F8000803F8000800080000 +B645:000000083B882208220E3B88040804087FE8000003F8020003F8020003F80000 +B646:000000083B882208220E3B88040804087FE8000000000FF8022002200FF80000 +B647:000000083B882208220E3B88040804087FE8000000800FF803E0041003E00000 +B648:0000001200127BD2421242124212421E7BD20012041204127FD2001200120000 +B649:000000283BA8222822383BA8042804287FA8000007F800080008000800080000 +B64A:000000283BA8222822383BA8042804287FA8000000003EF80208020802080000 +B64B:000000283BA8222822383BA8042804287FA8000000001F080108011401620000 +B64C:000000283BA8222822383BA8042804287FA8000008000800080008000FF80000 +B64D:000000283BA8222822383BA8042804287FA80000000010F8101010301ECC0000 +B64E:000000283BA8222822383BA8042804287FA800000808087F081C08220F9C0000 +B64F:000000283BA8222822383BA8042804287FA8000003F802000200020003F80000 +B650:000000283BA8222822383BA8042804287FA8000007F8000807F8040007F80000 +B651:000000283BA8222822383BA8042804287FA800003EF802083E0820083E080000 +B652:000000283BA8222822383BA8042804287FA800003EF802883E8820883EF80000 +B653:000000283BA8222822383BA8042804287FA800003E8802883EF820883EF80000 +B654:000000283BA8222822383BA8042804287FA800001F0801081F0810141F620000 +B655:000000283BA8222822383BA8042804287FA800003EF802803EF820803EF80000 +B656:000000283BA8222822383BA8042804287FA800003EFC02483E4820483EFC0000 +B657:000000283BA8222822383BA8042804287FA800001F08017F1F1C10221F1C0000 +B658:000000283BA8222822383BA8042804287FA8000003F802080208020803F80000 +B659:000000283BA8222822383BA8042804287FA800000208020803F8020803F80000 +B65A:000000283BA8222822383BA8042804287FA80000110811081F0811141F620000 +B65B:000000283BA8222822383BA8042804287FA80000001000100010006801840000 +B65C:000000283BA8222822383BA8042804287FA800000048004800A8011406620000 +B65D:000000283BA8222822383BA8042804287FA80000000003F00408040803F00000 +B65E:000000283BA8222822383BA8042804287FA8000003F80020002000D003080000 +B65F:000000283BA8222822383BA8042804287FA80000004003F8004000A003180000 +B660:000000283BA8222822383BA8042804287FA8000003F8000803F8000800080000 +B661:000000283BA8222822383BA8042804287FA8000003F8020003F8020003F80000 +B662:000000283BA8222822383BA8042804287FA8000000000FF8022002200FF80000 +B663:000000283BA8222822383BA8042804287FA8000000800FF803E0041003E00000 +B664:0000000800087BC842084208420842087BC80008040804087FE8000800080000 +B665:000000083B88220822083B88040804087FE8000007F800080008000800080000 +B666:000000083B88220822083B88040804087FE8000000003EF80208020802080000 +B667:000000083B88220822083B88040804087FE8000000001F080108011401620000 +B668:000000083B88220822083B88040804087FE8000008000800080008000FF80000 +B669:000000083B88220822083B88040804087FE80000000010F8101010301ECC0000 +B66A:000000083B88220822083B88040804087FE800000808087F081C08220F9C0000 +B66B:000000083B88220822083B88040804087FE8000003F802000200020003F80000 +B66C:000000083B88220822083B88040804087FE8000007F8000807F8040007F80000 +B66D:000000083B88220822083B88040804087FE800003EF802083E0820083E080000 +B66E:000000083B88220822083B88040804087FE800003EF802883E8820883EF80000 +B66F:000000083B88220822083B88040804087FE800003E8802883EF820883EF80000 +B670:000000083B88220822083B88040804087FE800001F0801081F0810141F620000 +B671:000000083B88220822083B88040804087FE800003EF802803EF820803EF80000 +B672:000000083B88220822083B88040804087FE800003EFC02483E4820483EFC0000 +B673:000000083B88220822083B88040804087FE800001F08017F1F1C10221F1C0000 +B674:000000083B88220822083B88040804087FE8000003F802080208020803F80000 +B675:000000083B88220822083B88040804087FE800000208020803F8020803F80000 +B676:000000083B88220822083B88040804087FE80000110811081F0811141F620000 +B677:000000083B88220822083B88040804087FE80000001000100010006801840000 +B678:000000083B88220822083B88040804087FE800000048004800A8011406620000 +B679:000000083B88220822083B88040804087FE80000000003F00408040803F00000 +B67A:000000083B88220822083B88040804087FE8000003F80020002000D003080000 +B67B:000000083B88220822083B88040804087FE80000004003F8004000A003180000 +B67C:000000083B88220822083B88040804087FE8000003F8000803F8000800080000 +B67D:000000083B88220822083B88040804087FE8000003F8020003F8020003F80000 +B67E:000000083B88220822083B88040804087FE8000000000FF8022002200FF80000 +B67F:000000083B88220822083B88040804087FE8000000800FF803E0041003E00000 +B680:000000003EF820802080208020803EF8000004400440044004407FFC00000000 +B681:000000001EF0108010801EF0044004407FFC00001FF000100010001000100000 +B682:000000001EF0108010801EF0044004407FFC000000003EF80208020802080000 +B683:000000001EF0108010801EF0044004407FFC000000001E100210022802C40000 +B684:000000001EF0108010801EF0044004407FFC000000001000100010001FF00000 +B685:000000001EF0108010801EF0044004407FFC0000000020F8201020303ECC0000 +B686:000000001EF0108010801EF0044004407FFC0000202021FC207020883E700000 +B687:000000001EF0108010801EF0044004407FFC00001FF01000100010001FF00000 +B688:000000001EF0108010801EF0044004407FFC00001FF000101FF010001FF00000 +B689:000000001EF0108010801EF0044004407FFC00003EF802083E0820083E080000 +B68A:000000001EF0108010801EF0044004407FFC00003EF802883E8820883EF80000 +B68B:000000001EF0108010801EF0044004407FFC00003E8802883EF820883EF80000 +B68C:000000001EF0108010801EF0044004407FFC00003E1002103E1020283EC40000 +B68D:000000001EF0108010801EF0044004407FFC00003EF802803EF820803EF80000 +B68E:000000001EF0108010801EF0044004407FFC00003EFC02483E4820483EFC0000 +B68F:000000001EF0108010801EF0044004407FFC00003E2003FC3E7020883E700000 +B690:000000001EF0108010801EF0044004407FFC00001FF01010101010101FF00000 +B691:000000001EF0108010801EF0044004407FFC0000101010101FF010101FF00000 +B692:000000001EF0108010801EF0044004407FFC0000222022203E2022503E880000 +B693:000000001EF0108010801EF0044004407FFC000000000100010002800C400000 +B694:000000001EF0108010801EF0044004407FFC00000000024002400DA033100000 +B695:000000001EF0108010801EF0044004407FFC0000000007C00820082007C00000 +B696:000000001EF0108010801EF0044004407FFC0000000007E00080014006200000 +B697:000000001EF0108010801EF0044004407FFC0000008007E00080014006200000 +B698:000000001EF0108010801EF0044004407FFC00001FF000101FF0001000100000 +B699:000000001EF0108010801EF0044004407FFC00001FF010001FF010001FF00000 +B69A:000000001EF0108010801EF0044004407FFC000000001FF0044004401FF00000 +B69B:000000001EF0108010801EF0044004407FFC000001001FF007C0082007C00000 +B69C:000000003EF820802080208020803EF8000000003FF801000100010001000000 +B69D:000000001EF0108010801EF000007FFC010001001FF000100010001000100000 +B69E:000000001EF0108010801EF000007FFC0100010000003EF80208020802080000 +B69F:000000001EF0108010801EF000007FFC0100010000001E100210022802C40000 +B6A0:000000001EF0108010801EF0000000007FFC010001001100100010001FF00000 +B6A1:000000001EF0108010801EF000007FFC01000100000020F8201020303ECC0000 +B6A2:000000001EF0108010801EF000007FFC01000100202021FC207020883E700000 +B6A3:000000001EF0108010801EF000007FFC010001001FF01000100010001FF00000 +B6A4:000000001EF0108010801EF000007FFC010001001FF000101FF010001FF00000 +B6A5:000000001EF0108010801EF000007FFC010001003EF802083E0820083E080000 +B6A6:000000001EF0108010801EF000007FFC010001003EF802883E8820883EF80000 +B6A7:000000001EF0108010801EF000007FFC010001003E8802883EF820883EF80000 +B6A8:000000001EF0108010801EF000007FFC010001003E1002103E1020283EC40000 +B6A9:000000001EF0108010801EF000007FFC010001003EF802803EF820803EF80000 +B6AA:000000001EF0108010801EF000007FFC010001003EFC02483E4820483EFC0000 +B6AB:000000001EF0108010801EF000007FFC010001003E2003FC3E7020883E700000 +B6AC:000000001EF0108010801EF000007FFC010001001FF01010101010101FF00000 +B6AD:000000001EF0108010801EF000007FFC01000100101010101FF010101FF00000 +B6AE:000000001EF0108010801EF000007FFC01000100222022203E2022503E880000 +B6AF:000000001EF0108010801EF000007FFC0100010000000100010002800C400000 +B6B0:000000001EF0108010801EF000007FFC010001000000024002400DA033100000 +B6B1:000000001EF0108010801EF000007FFC01000100000007C00820082007C00000 +B6B2:000000001EF0108010801EF000007FFC01000100000007E00080014006200000 +B6B3:000000001EF0108010801EF000007FFC01000100008007E00080014006200000 +B6B4:000000001EF0108010801EF000007FFC010001001FF000101FF0001000100000 +B6B5:000000001EF0108010801EF000007FFC010001001FF010001FF010001FF00000 +B6B6:000000001EF0108010801EF000007FFC0100010000001FF0044004401FF00000 +B6B7:000000001EF0108010801EF000007FFC0100010001001FF007C0082007C00000 +B6B8:000000087BC842084208420842087BC8000800087FE8040804F8040804080000 +B6B9:0008770844084408770800087FE8027802080000000007F80008000800080000 +B6BA:0008770844084408770800087FE802780208000000003EF80208020802080000 +B6BB:0008770844084408770800087FE802780208000000001F080108011401620000 +B6BC:00087708440844087708000800087FE80278020802081000100010001FF80000 +B6BD:0008770844084408770800087FE8027802080000000020F8201020303ECC0000 +B6BE:0008770844084408770800087FE8027802080000202021FC207020883E700000 +B6BF:0008770844084408770800087FE802780208000003F802000200020003F80000 +B6C0:0008770844084408770800087FE802780208000007F8000807F8040007F80000 +B6C1:0008770844084408770800087FE80278020800003EF802083E0820083E080000 +B6C2:0008770844084408770800087FE80278020800003EF802883E8820883EF80000 +B6C3:0008770844084408770800087FE80278020800003E8802883EF820883EF80000 +B6C4:0008770844084408770800087FE80278020800000F8800880F8808140FA20000 +B6C5:0008770844084408770800087FE80278020800003EF802803EF820803EF80000 +B6C6:0008770844084408770800087FE80278020800003EFC02483E4820483EFC0000 +B6C7:0008770844084408770800087FE80278020800003E1002FE3E3820443E380000 +B6C8:0008770844084408770800087FE802780208000003F802080208020803F80000 +B6C9:0008770844084408770800087FE80278020800000208020803F8020803F80000 +B6CA:0008770844084408770800087FE8027802080000210821083F0821143F620000 +B6CB:0008770844084408770800087FE8027802080000001000100010006801840000 +B6CC:0008770844084408770800087FE80278020800000048004800A8011406620000 +B6CD:0008770844084408770800087FE8027802080000000003F00408040803F00000 +B6CE:0008770844084408770800087FE802780208000003F80020002000D003080000 +B6CF:0008770844084408770800087FE8027802080000004003F8004000A003180000 +B6D0:0008770844084408770800087FE802780208000003F8000803F8000800080000 +B6D1:0008770844084408770800087FE802780208000003F8020003F8020003F80000 +B6D2:0008770844084408770800087FE802780208000000000FF8022002200FF80000 +B6D3:0008770844084408770800087FE802780208000000800FF803E0041003E00000 +B6D4:0000000A7BCA420A420A420A420A7BCA000A000A7FEA040A047A040A040A0000 +B6D5:0028772844284428772800287FA805E804280000000007F80008000800080000 +B6D6:0028772844284428772800287FA805E80428000000003EF80208020802080000 +B6D7:0028772844284428772800287FA805E80428000000001F080108011401620000 +B6D8:00287728442844287728002800287FA8042805E804281428100010001FF80000 +B6D9:0028772844284428772800287FA805E804280000000020F8201020303ECC0000 +B6DA:0028772844284428772800287FA805E804280000202021FC207020883E700000 +B6DB:0028772844284428772800287FA805E80428000003F802000200020003F80000 +B6DC:0028772844284428772800287FA805E80428000007F8000807F8040007F80000 +B6DD:0028772844284428772800287FA805E8042800003EF802083E0820083E080000 +B6DE:0028772844284428772800287FA805E8042800003EF802883E8820883EF80000 +B6DF:0028772844284428772800287FA805E8042800003E8802883EF820883EF80000 +B6E0:0028772844284428772800287FA805E8042800000F8800880F8808140FA20000 +B6E1:0028772844284428772800287FA805E8042800003EF802803EF820803EF80000 +B6E2:0028772844284428772800287FA805E8042800003EFC02483E4820483EFC0000 +B6E3:0028772844284428772800287FA805E8042800003E1002FE3E3820443E380000 +B6E4:0028772844284428772800287FA805E80428000003F802080208020803F80000 +B6E5:0028772844284428772800287FA805E8042800000208020803F8020803F80000 +B6E6:0028772844284428772800287FA805E804280000210821083F0821143F620000 +B6E7:0028772844284428772800287FA805E804280000001000100010006801840000 +B6E8:0028772844284428772800287FA805E8042800000048004800A8011406620000 +B6E9:0028772844284428772800287FA805E804280000000003F00408040803F00000 +B6EA:0028772844284428772800287FA805E80428000003F80020002000D003080000 +B6EB:0028772844284428772800287FA805E804280000004003F8004000A003180000 +B6EC:0028772844284428772800287FA805E80428000003F8000803F8000800080000 +B6ED:0028772844284428772800287FA805E80428000003F8020003F8020003F80000 +B6EE:0028772844284428772800287FA805E80428000000000FF8022002200FF80000 +B6EF:0028772844284428772800287FA805E80428000000800FF803E0041003E00000 +B6F0:000000087BC842084208420842087BC8000800087FE804080408040804080000 +B6F1:0008770844084408770800087FE8020802000000000007F80008000800080000 +B6F2:0008770844084408770800087FE802080200000000003EF80208020802080000 +B6F3:0008770844084408770800087FE802080200000000001F080108011401620000 +B6F4:00087708440844087708000800087FE80208020802081008100010001FF80000 +B6F5:0008770844084408770800087FE8020802000000000020F8201020303ECC0000 +B6F6:0008770844084408770800087FE8020802000000202021FC207020883E700000 +B6F7:0008770844084408770800087FE802080200000003F802000200020003F80000 +B6F8:0008770844084408770800087FE802080200000007F8000807F8040007F80000 +B6F9:0008770844084408770800087FE80208020000003EF802083E0820083E080000 +B6FA:0008770844084408770800087FE80208020000003EF802883E8820883EF80000 +B6FB:0008770844084408770800087FE80208020000003E8802883EF820883EF80000 +B6FC:0008770844084408770800087FE80208020000000F8800880F8808140FA20000 +B6FD:0008770844084408770800087FE80208020000003EF802803EF820803EF80000 +B6FE:0008770844084408770800087FE80208020000003EFC02483E4820483EFC0000 +B6FF:0008770844084408770800087FE80208020000003E1002FE3E3820443E380000 +B700:0008770844084408770800087FE802080200000003F802080208020803F80000 +B701:0008770844084408770800087FE80208020000000208020803F8020803F80000 +B702:0008770844084408770800087FE8020802000000210821083F0821143F620000 +B703:0008770844084408770800087FE8020802000000001000100010006801840000 +B704:0008770844084408770800087FE80208020000000048004800A8011406620000 +B705:0008770844084408770800087FE8020802000000000003F00408040803F00000 +B706:0008770844084408770800087FE802080200000003F80020002000D003080000 +B707:0008770844084408770800087FE8020802000000004003F8004000A003180000 +B708:0008770844084408770800087FE802080200000003F8000803F8000800080000 +B709:0008770844084408770800087FE802080200000003F8020003F8020003F80000 +B70A:0008770844084408770800087FE802080200000000000FF8022002200FF80000 +B70B:0008770844084408770800087FE802080200000000800FF803E0041003E00000 +B70C:000000003EF820802080208020803EF8000000007FFC04400440044004400000 +B70D:000000001EF0108010801EF000007FFC044004401FF000100010001000100000 +B70E:000000001EF0108010801EF000007FFC0440044000003EF80208020802080000 +B70F:000000001EF0108010801EF000007FFC0440044000001E100210022802C40000 +B710:000000001EF0108010801EF0000000007FFC044004401440100010001FF00000 +B711:000000001EF0108010801EF000007FFC04400440000020F8201020303ECC0000 +B712:000000001EF0108010801EF000007FFC04400440202021FC207020883E700000 +B713:000000001EF0108010801EF000007FFC044004401FF01000100010001FF00000 +B714:000000001EF0108010801EF000007FFC044004401FF000101FF010001FF00000 +B715:000000001EF0108010801EF000007FFC044004403EF802083E0820083E080000 +B716:000000001EF0108010801EF000007FFC044004403EF802883E8820883EF80000 +B717:000000001EF0108010801EF000007FFC044004403E8802883EF820883EF80000 +B718:000000001EF0108010801EF000007FFC044004403E1002103E1020283EC40000 +B719:000000001EF0108010801EF000007FFC044004403EF802803EF820803EF80000 +B71A:000000001EF0108010801EF000007FFC044004403EFC02483E4820483EFC0000 +B71B:000000001EF0108010801EF000007FFC044004403E2003FC3E7020883E700000 +B71C:000000001EF0108010801EF000007FFC044004401FF01010101010101FF00000 +B71D:000000001EF0108010801EF000007FFC04400440101010101FF010101FF00000 +B71E:000000001EF0108010801EF000007FFC04400440222022203E2022503E880000 +B71F:000000001EF0108010801EF000007FFC0440044000000100010002800C400000 +B720:000000001EF0108010801EF000007FFC044004400000024002400DA033100000 +B721:000000001EF0108010801EF000007FFC04400440000007C00820082007C00000 +B722:000000001EF0108010801EF000007FFC04400440000007E00080014006200000 +B723:000000001EF0108010801EF000007FFC04400440008007E00080014006200000 +B724:000000001EF0108010801EF000007FFC044004401FF000101FF0001000100000 +B725:000000001EF0108010801EF000007FFC044004401FF010001FF010001FF00000 +B726:000000001EF0108010801EF000007FFC0440044000001FF0044004401FF00000 +B727:000000001EF0108010801EF000007FFC0440044001001FF007C0082007C00000 +B728:000000003EF820802080208020803EF80000000000007FFC0000000000000000 +B729:000000001EF0108010801EF0000000007FFC00001FF000100010001000100000 +B72A:000000001EF0108010801EF0000000007FFC000000003EF80208020802080000 +B72B:000000001EF0108010801EF0000000007FFC000000001E100210022802C40000 +B72C:000000001EF0108010801EF0000000007FFC000000001000100010001FF00000 +B72D:000000001EF0108010801EF0000000007FFC0000000020F8201020303ECC0000 +B72E:000000001EF0108010801EF0000000007FFC0000202021FC207020883E700000 +B72F:000000001EF0108010801EF0000000007FFC00001FF01000100010001FF00000 +B730:000000001EF0108010801EF0000000007FFC00001FF000101FF010001FF00000 +B731:000000001EF0108010801EF0000000007FFC00003EF802083E0820083E080000 +B732:000000001EF0108010801EF0000000007FFC00003EF802883E8820883EF80000 +B733:000000001EF0108010801EF0000000007FFC00003E8802883EF820883EF80000 +B734:000000001EF0108010801EF0000000007FFC00003E1002103E1020283EC40000 +B735:000000001EF0108010801EF0000000007FFC00003EF802803EF820803EF80000 +B736:000000001EF0108010801EF0000000007FFC00003EFC02483E4820483EFC0000 +B737:000000001EF0108010801EF0000000007FFC00003E2003FC3E7020883E700000 +B738:000000001EF0108010801EF0000000007FFC00001FF01010101010101FF00000 +B739:000000001EF0108010801EF0000000007FFC0000101010101FF010101FF00000 +B73A:000000001EF0108010801EF0000000007FFC0000222022203E2022503E880000 +B73B:000000001EF0108010801EF0000000007FFC000000000100010002800C400000 +B73C:000000001EF0108010801EF0000000007FFC00000000024002400DA033100000 +B73D:000000001EF0108010801EF0000000007FFC0000000007C00820082007C00000 +B73E:000000001EF0108010801EF0000000007FFC0000000007E00080014006200000 +B73F:000000001EF0108010801EF0000000007FFC0000008007E00080014006200000 +B740:000000001EF0108010801EF0000000007FFC00001FF000101FF0001000100000 +B741:000000001EF0108010801EF0000000007FFC00001FF010001FF010001FF00000 +B742:000000001EF0108010801EF0000000007FFC000000001FF0044004401FF00000 +B743:000000001EF0108010801EF0000000007FFC000001001FF007C0082007C00000 +B744:0000000800087BC842084208420842087BC8000800087FE80008000800080000 +B745:000000083B88220822083B88000800087FE8000007F800080008000800080000 +B746:000000083B88220822083B88000800087FE8000000003EF80208020802080000 +B747:000000083B88220822083B88000800087FE8000000001F080108011401620000 +B748:000000083B88220822083B88000800087FE8000008000800080008000FF80000 +B749:000000083B88220822083B88000800087FE80000000010F8101010301ECC0000 +B74A:000000083B88220822083B88000800087FE800000808087F081C08220F9C0000 +B74B:000000083B88220822083B88000800087FE8000003F802000200020003F80000 +B74C:000000083B88220822083B88000800087FE8000007F8000807F8040007F80000 +B74D:000000083B88220822083B88000800087FE800003EF802083E0820083E080000 +B74E:000000083B88220822083B88000800087FE800003EF802883E8820883EF80000 +B74F:000000083B88220822083B88000800087FE800003E8802883EF820883EF80000 +B750:000000083B88220822083B88000800087FE800001F0801081F0810141F620000 +B751:000000083B88220822083B88000800087FE800003EF802803EF820803EF80000 +B752:000000083B88220822083B88000800087FE800003EFC02483E4820483EFC0000 +B753:000000083B88220822083B88000800087FE800001F08017F1F1C10221F1C0000 +B754:000000083B88220822083B88000800087FE8000003F802080208020803F80000 +B755:000000083B88220822083B88000800087FE800000208020803F8020803F80000 +B756:000000083B88220822083B88000800087FE80000110811081F0811141F620000 +B757:000000083B88220822083B88000800087FE80000001000100010006801840000 +B758:000000083B88220822083B88000800087FE800000048004800A8011406620000 +B759:000000083B88220822083B88000800087FE80000000003F00408040803F00000 +B75A:000000083B88220822083B88000800087FE8000003F80020002000D003080000 +B75B:000000083B88220822083B88000800087FE80000004003F8004000A003180000 +B75C:000000083B88220822083B88000800087FE8000003F8000803F8000800080000 +B75D:000000083B88220822083B88000800087FE8000003F8020003F8020003F80000 +B75E:000000083B88220822083B88000800087FE8000000000FF8022002200FF80000 +B75F:000000083B88220822083B88000800087FE8000000800FF803E0041003E00000 +B760:00000000000800087BC8420842084208420842087BC800080008000800080000 +B761:0000000800087708440844084408770800080000000007F80008000800080000 +B762:000000080008770844084408440877080008000000003EF80208020802080000 +B763:000000080008770844084408440877080008000000001F080108011401620000 +B764:000000080008770844084408440877080008000800001000100010001FF80000 +B765:0000000800087708440844084408770800080000000020F8201020303ECC0000 +B766:0000000800087708440844084408770800080000202021FC207020883E700000 +B767:000000080008770844084408440877080008000003F802000200020003F80000 +B768:000000080008770844084408440877080008000007F8000807F8040007F80000 +B769:00000008000877084408440844087708000800003EF802083E0820083E080000 +B76A:00000008000877084408440844087708000800003EF802883E8820883EF80000 +B76B:00000008000877084408440844087708000800003E8802883EF820883EF80000 +B76C:00000008000877084408440844087708000800000F8800880F8808140FA20000 +B76D:00000008000877084408440844087708000800003EF802803EF820803EF80000 +B76E:00000008000877084408440844087708000800003EFC02483E4820483EFC0000 +B76F:00000008000877084408440844087708000800003E1002FE3E3820443E380000 +B770:000000080008770844084408440877080008000003F802080208020803F80000 +B771:00000008000877084408440844087708000800000208020803F8020803F80000 +B772:0000000800087708440844084408770800080000210821083F0821143F620000 +B773:0000000800087708440844084408770800080000001000100010006801840000 +B774:00000008000877084408440844087708000800000048004800A8011406620000 +B775:0000000800087708440844084408770800080000000003F00408040803F00000 +B776:000000080008770844084408440877080008000003F80020002000D003080000 +B777:0000000800087708440844084408770800080000004003F8004000A003180000 +B778:000000080008770844084408440877080008000003F8000803F8000800080000 +B779:000000080008770844084408440877080008000003F8020003F8020003F80000 +B77A:000000080008770844084408440877080008000000000FF8022002200FF80000 +B77B:000000080008770844084408440877080008000000800FF803E0041003E00000 +B77C:00000000001000103F90009000903F9E2010201020103F900010001000100000 +B77D:0000000800083F0801083F0E20083F080008000007F800080008000800080000 +B77E:0000000800083F0801083F0E20083F080008000000003EF80208020802080000 +B77F:0000000800083F0801083F0E20083F080008000000001F080108011401620000 +B780:0000000800083F0801083F0E20083F080008000808000800080008000FF80000 +B781:0000000800083F0801083F0E20083F0800080000000010F8101010301ECC0000 +B782:0000000800083F0801083F0E20083F08000800000808087F081C08220F9C0000 +B783:0000000800083F0801083F0E20083F080008000003F802000200020003F80000 +B784:0000000800083F0801083F0E20083F080008000007F8000807F8040007F80000 +B785:0000000800083F0801083F0E20083F08000800003EF802083E0820083E080000 +B786:0000000800083F0801083F0E20083F08000800003EF802883E8820883EF80000 +B787:0000000800083F0801083F0E20083F08000800003E8802883EF820883EF80000 +B788:0000000800083F0801083F0E20083F08000800001F0801081F0810141F620000 +B789:0000000800083F0801083F0E20083F08000800003EF802803EF820803EF80000 +B78A:0000000800083F0801083F0E20083F08000800003EFC02483E4820483EFC0000 +B78B:0000000800083F0801083F0E20083F08000800001F08017F1F1C10221F1C0000 +B78C:0000000800083F0801083F0E20083F080008000003F802080208020803F80000 +B78D:0000000800083F0801083F0E20083F08000800000208020803F8020803F80000 +B78E:0000000800083F0801083F0E20083F0800080000110811081F0811141F620000 +B78F:0000000800083F0801083F0E20083F0800080000001000100010006801840000 +B790:0000000800083F0801083F0E20083F08000800000048004800A8011406620000 +B791:0000000800083F0801083F0E20083F0800080000000003F00408040803F00000 +B792:0000000800083F0801083F0E20083F080008000003F80020002000D003080000 +B793:0000000800083F0801083F0E20083F0800080000004003F8004000A003180000 +B794:0000000800083F0801083F0E20083F080008000003F8000803F8000800080000 +B795:0000000800083F0801083F0E20083F080008000003F8020003F8020003F80000 +B796:0000000800083F0801083F0E20083F080008000000000FF8022002200FF80000 +B797:0000000800083F0801083F0E20083F080008000000800FF803E0041003E00000 +B798:00000000001200123F92009200923F9E2012201220123F920012001200120000 +B799:0000002800283F2801283F3820283F280028000007F800080008000800080000 +B79A:0000002800283F2801283F3820283F280028000000003EF80208020802080000 +B79B:0000002800283F2801283F3820283F280028000000003E100210022802C40000 +B79C:0000002800283F2801283F3820283F280028002808000800080008000FF80000 +B79D:0000002800283F2801283F3820283F2800280000000020F8201020303ECC0000 +B79E:0000002800283F2801283F3820283F2800280000202021FC207020883E700000 +B79F:0000002800283F2801283F3820283F280028000003F802000200020003F80000 +B7A0:0000002800283F2801283F3820283F280028000007F8000807F8040007F80000 +B7A1:0000002800283F2801283F3820283F28002800003EF802083E0820083E080000 +B7A2:0000002800283F2801283F3820283F28002800003EF802883E8820883EF80000 +B7A3:0000002800283F2801283F3820283F28002800003E8802883EF820883EF80000 +B7A4:0000002800283F2801283F3820283F28002800001F0801081F0810141F620000 +B7A5:0000002800283F2801283F3820283F28002800003EF802803EF820803EF80000 +B7A6:0000002800283F2801283F3820283F28002800003EFC02483E4820483EFC0000 +B7A7:0000002800283F2801283F3820283F28002800003E1002FE3E3820443E380000 +B7A8:0000002800283F2801283F3820283F280028000003F802080208020803F80000 +B7A9:0000002800283F2801283F3820283F28002800000208020803F8020803F80000 +B7AA:0000002800283F2801283F3820283F2800280000110811081F0811141F620000 +B7AB:0000002800283F2801283F3820283F2800280000000800080008003400C20000 +B7AC:0000002800283F2801283F3820283F28002800000048004800A8011406620000 +B7AD:0000002800283F2801283F3820283F2800280000000001F00208020801F00000 +B7AE:0000002800283F2801283F3820283F280028000003F80020002000D003080000 +B7AF:0000002800283F2801283F3820283F2800280000004003F8004000A003180000 +B7B0:0000002800283F2801283F3820283F280028000003F8000803F8000800080000 +B7B1:0000002800283F2801283F3820283F280028000003F8020003F8020003F80000 +B7B2:0000002800283F2801283F3820283F280028000000000FF8022002200FF80000 +B7B3:0000002800283F2801283F3820283F280028000000800FF803E0041003E00000 +B7B4:00000000001000103F900090009E3F902010201E20103F900010001000100000 +B7B5:0000000800083F08010E3F08200E3F080008000007F800080008000800080000 +B7B6:0000000800083F08010E3F08200E3F080008000000003EF80208020802080000 +B7B7:0000000800083F08010E3F08200E3F080008000000001F080108011401620000 +B7B8:0000000800083F08010E3F08200E3F080008000008000800080008000FF80000 +B7B9:0000000800083F08010E3F08200E3F0800080000000010F8101010301ECC0000 +B7BA:0000000800083F08010E3F08200E3F08000800000808087F081C08220F9C0000 +B7BB:0000000800083F08010E3F08200E3F080008000003F802000200020003F80000 +B7BC:0000000800083F08010E3F08200E3F080008000007F8000807F8040007F80000 +B7BD:0000000800083F08010E3F08200E3F08000800003EF802083E0820083E080000 +B7BE:0000000800083F08010E3F08200E3F08000800003EF802883E8820883EF80000 +B7BF:0000000800083F08010E3F08200E3F08000800003E8802883EF820883EF80000 +B7C0:0000000800083F08010E3F08200E3F08000800001F0801081F0810141F620000 +B7C1:0000000800083F08010E3F08200E3F08000800003EF802803EF820803EF80000 +B7C2:0000000800083F08010E3F08200E3F08000800003EFC02483E4820483EFC0000 +B7C3:0000000800083F08010E3F08200E3F08000800001F08017F1F1C10221F1C0000 +B7C4:0000000800083F08010E3F08200E3F080008000003F802080208020803F80000 +B7C5:0000000800083F08010E3F08200E3F08000800000208020803F8020803F80000 +B7C6:0000000800083F08010E3F08200E3F0800080000110811081F0811141F620000 +B7C7:0000000800083F08010E3F08200E3F0800080000001000100010006801840000 +B7C8:0000000800083F08010E3F08200E3F08000800000048004800A8011406620000 +B7C9:0000000800083F08010E3F08200E3F0800080000000003F00408040803F00000 +B7CA:0000000800083F08010E3F08200E3F080008000003F80020002000D003080000 +B7CB:0000000800083F08010E3F08200E3F0800080000004003F8004000A003180000 +B7CC:0000000800083F08010E3F08200E3F080008000003F8000803F8000800080000 +B7CD:0000000800083F08010E3F08200E3F080008000003F8020003F8020003F80000 +B7CE:0000000800083F08010E3F08200E3F080008000000000FF8022002200FF80000 +B7CF:0000000800083F08010E3F08200E3F080008000000800FF803E0041003E00000 +B7D0:00000000001200123F920092009E3F922012201E20123F920012001200120000 +B7D1:0000002800283F2801383F2820383F280028000007F800080008000800080000 +B7D2:0000002800283F2801383F2820383F280028000000003EF80208020802080000 +B7D3:0000002800283F2801383F2820383F280028000000003E100210022802C40000 +B7D4:0000002800283F2801383F2820383F280028002808000800080008000FF80000 +B7D5:0000002800283F2801383F2820383F2800280000000020F8201020303ECC0000 +B7D6:0000002800283F2801383F2820383F2800280000202021FC207020883E700000 +B7D7:0000002800283F2801383F2820383F280028000003F802000200020003F80000 +B7D8:0000002800283F2801383F2820383F280028000007F8000807F8040007F80000 +B7D9:0000002800283F2801383F2820383F28002800003EF802083E0820083E080000 +B7DA:0000002800283F2801383F2820383F28002800003EF802883E8820883EF80000 +B7DB:0000002800283F2801383F2820383F28002800003E8802883EF820883EF80000 +B7DC:0000002800283F2801383F2820383F28002800001F0801081F0810141F620000 +B7DD:0000002800283F2801383F2820383F28002800003EF802803EF820803EF80000 +B7DE:0000002800283F2801383F2820383F28002800003EFC02483E4820483EFC0000 +B7DF:0000002800283F2801383F2820383F28002800003E1002FE3E3820443E380000 +B7E0:0000002800283F2801383F2820383F280028000003F802080208020803F80000 +B7E1:0000002800283F2801383F2820383F28002800000208020803F8020803F80000 +B7E2:0000002800283F2801383F2820383F2800280000110811081F0811141F620000 +B7E3:0000002800283F2801383F2820383F2800280000000800080008003400C20000 +B7E4:0000002800283F2801383F2820383F28002800000048004800A8011406620000 +B7E5:0000002800283F2801383F2820383F2800280000000001F00208020801F00000 +B7E6:0000002800283F2801383F2820383F280028000003F80020002000D003080000 +B7E7:0000002800283F2801383F2820383F2800280000004003F8004000A003180000 +B7E8:0000002800283F2801383F2820383F280028000003F8000803F8000800080000 +B7E9:0000002800283F2801383F2820383F280028000003F8020003F8020003F80000 +B7EA:0000002800283F2801383F2820383F280028000000000FF8022002200FF80000 +B7EB:0000002800283F2801383F2820383F280028000000800FF803E0041003E00000 +B7EC:00000000000200023F82008200823F9E2002200220023F820002000200020000 +B7ED:0000000800083F0801083F3820083F0800080000000007F80008000800080000 +B7EE:0000000800083F0801083F3820083F080008000000003EF80208020802080000 +B7EF:0000000800083F0801083F3820083F080008000000001F080108011401620000 +B7F0:0000000800083F0801083F3820083F080008000000001000100010001FF80000 +B7F1:0000000800083F0801083F3820083F0800080000000020F8201020303ECC0000 +B7F2:0000000800083F0801083F3820083F0800080000202021FC207020883E700000 +B7F3:0000000800083F0801083F3820083F080008000003F802000200020003F80000 +B7F4:0000000800083F0801083F3820083F080008000007F8000807F8040007F80000 +B7F5:0000000800083F0801083F3820083F08000800003EF802083E0820083E080000 +B7F6:0000000800083F0801083F3820083F08000800003EF802883E8820883EF80000 +B7F7:0000000800083F0801083F3820083F08000800003E8802883EF820883EF80000 +B7F8:0000000800083F0801083F3820083F08000800000F8800880F8808140FA20000 +B7F9:0000000800083F0801083F3820083F08000800003EF802803EF820803EF80000 +B7FA:0000000800083F0801083F3820083F08000800003EFC02483E4820483EFC0000 +B7FB:0000000800083F0801083F3820083F08000800003E1002FE3E3820443E380000 +B7FC:0000000800083F0801083F3820083F080008000003F802080208020803F80000 +B7FD:0000000800083F0801083F3820083F08000800000208020803F8020803F80000 +B7FE:0000000800083F0801083F3820083F0800080000210821083F0821143F620000 +B7FF:0000000800083F0801083F3820083F0800080000001000100010006801840000 +B800:0000000800083F0801083F3820083F08000800000048004800A8011406620000 +B801:0000000800083F0801083F3820083F0800080000000003F00408040803F00000 +B802:0000000800083F0801083F3820083F080008000003F80020002000D003080000 +B803:0000000800083F0801083F3820083F0800080000004003F8004000A003180000 +B804:0000000800083F0801083F3820083F080008000003F8000803F8000800080000 +B805:0000000800083F0801083F3820083F080008000003F8020003F8020003F80000 +B806:0000000800083F0801083F3820083F080008000000000FF8022002200FF80000 +B807:0000000800083F0801083F3820083F080008000000800FF803E0041003E00000 +B808:00000000000A000A3F8A008A008A3FBA200A200A200A3F8A000A000A000A0000 +B809:0000002800283F2801283FE820283F280028000007F800080008000800080000 +B80A:0000002800283F2801283FE820283F280028000000003EF80208020802080000 +B80B:0000002800283F2801283FE820283F280028000000003E100210022802C40000 +B80C:0000002800283F2801283FE820283F280028000008000800080008000FF80000 +B80D:0000002800283F2801283FE820283F2800280000000020F8201020303ECC0000 +B80E:0000002800283F2801283FE820283F2800280000202021FC207020883E700000 +B80F:0000002800283F2801283FE820283F280028000003F802000200020003F80000 +B810:0000002800283F2801283FE820283F280028000007F8000807F8040007F80000 +B811:0000002800283F2801283FE820283F28002800003EF802083E0820083E080000 +B812:0000002800283F2801283FE820283F28002800003EF802883E8820883EF80000 +B813:0000002800283F2801283FE820283F28002800003E8802883EF820883EF80000 +B814:0000002800283F2801283FE820283F28002800001F0801081F0810141F620000 +B815:0000002800283F2801283FE820283F28002800003EF802803EF820803EF80000 +B816:0000002800283F2801283FE820283F28002800003EFC02483E4820483EFC0000 +B817:0000002800283F2801283FE820283F28002800003E1002FE3E3820443E380000 +B818:0000002800283F2801283FE820283F280028000003F802080208020803F80000 +B819:0000002800283F2801283FE820283F28002800000208020803F8020803F80000 +B81A:0000002800283F2801283FE820283F2800280000110811081F0811141F620000 +B81B:0000002800283F2801283FE820283F2800280000000800080008003400C20000 +B81C:0000002800283F2801283FE820283F28002800000048004800A8011406620000 +B81D:0000002800283F2801283FE820283F2800280000000001F00208020801F00000 +B81E:0000002800283F2801283FE820283F280028000003F80020002000D003080000 +B81F:0000002800283F2801283FE820283F2800280000004003F8004000A003180000 +B820:0000002800283F2801283FE820283F280028000003F8000803F8000800080000 +B821:0000002800283F2801283FE820283F280028000003F8020003F8020003F80000 +B822:0000002800283F2801283FE820283F280028000000000FF8022002200FF80000 +B823:0000002800283F2801283FE820283F280028000000800FF803E0041003E00000 +B824:00000000000200023F820082009E3F822002201E20023F820002000200020000 +B825:0000000800083F0801383F0820383F0800080000000007F80008000800080000 +B826:0000000800083F0801383F0820383F080008000000003EF80208020802080000 +B827:0000000800083F0801383F0820383F080008000000001F080108011401620000 +B828:0000000800083F0801383F0820383F080008000800001000100010001FF80000 +B829:0000000800083F0801383F0820383F0800080000000020F8201020303ECC0000 +B82A:0000000800083F0801383F0820383F0800080000202021FC207020883E700000 +B82B:0000000800083F0801383F0820383F080008000003F802000200020003F80000 +B82C:0000000800083F0801383F0820383F080008000007F8000807F8040007F80000 +B82D:0000000800083F0801383F0820383F08000800003EF802083E0820083E080000 +B82E:0000000800083F0801383F0820383F08000800003EF802883E8820883EF80000 +B82F:0000000800083F0801383F0820383F08000800003E8802883EF820883EF80000 +B830:0000000800083F0801383F0820383F08000800000F8800880F8808140FA20000 +B831:0000000800083F0801383F0820383F08000800003EF802803EF820803EF80000 +B832:0000000800083F0801383F0820383F08000800003EFC02483E4820483EFC0000 +B833:0000000800083F0801383F0820383F08000800003E1002FE3E3820443E380000 +B834:0000000800083F0801383F0820383F080008000003F802080208020803F80000 +B835:0000000800083F0801383F0820383F08000800000208020803F8020803F80000 +B836:0000000800083F0801383F0820383F0800080000210821083F0821143F620000 +B837:0000000800083F0801383F0820383F0800080000001000100010006801840000 +B838:0000000800083F0801383F0820383F08000800000048004800A8011406620000 +B839:0000000800083F0801383F0820383F0800080000000003F00408040803F00000 +B83A:0000000800083F0801383F0820383F080008000003F80020002000D003080000 +B83B:0000000800083F0801383F0820383F0800080000004003F8004000A003180000 +B83C:0000000800083F0801383F0820383F080008000003F8000803F8000800080000 +B83D:0000000800083F0801383F0820383F080008000003F8020003F8020003F80000 +B83E:0000000800083F0801383F0820383F080008000000000FF8022002200FF80000 +B83F:0000000800083F0801383F0820383F080008000000800FF803E0041003E00000 +B840:00000000000A000A3F8A008A00BA3F8A200A203A200A3F8A000A000A000A0000 +B841:0000002800283F2801E83F2820E83F280028000007F800080008000800080000 +B842:0000002800283F2801E83F2820E83F280028000000003EF80208020802080000 +B843:0000002800283F2801E83F2820E83F280028000000003E100210022802C40000 +B844:0000002800283F2801E83F2820E83F280028002808000800080008000FF80000 +B845:0000002800283F2801E83F2820E83F2800280000000020F8201020303ECC0000 +B846:0000002800283F2801E83F2820E83F2800280000202021FC207020883E700000 +B847:0000002800283F2801E83F2820E83F280028000003F802000200020003F80000 +B848:0000002800283F2801E83F2820E83F280028000007F8000807F8040007F80000 +B849:0000002800283F2801E83F2820E83F28002800003EF802083E0820083E080000 +B84A:0000002800283F2801E83F2820E83F28002800003EF802883E8820883EF80000 +B84B:0000002800283F2801E83F2820E83F28002800003E8802883EF820883EF80000 +B84C:0000002800283F2801E83F2820E83F28002800001F0801081F0810141F620000 +B84D:0000002800283F2801E83F2820E83F28002800003EF802803EF820803EF80000 +B84E:0000002800283F2801E83F2820E83F28002800003EFC02483E4820483EFC0000 +B84F:0000002800283F2801E83F2820E83F28002800003E1002FE3E3820443E380000 +B850:0000002800283F2801E83F2820E83F280028000003F802080208020803F80000 +B851:0000002800283F2801E83F2820E83F28002800000208020803F8020803F80000 +B852:0000002800283F2801E83F2820E83F2800280000110811081F0811141F620000 +B853:0000002800283F2801E83F2820E83F2800280000000800080008003400C20000 +B854:0000002800283F2801E83F2820E83F28002800000048004800A8011406620000 +B855:0000002800283F2801E83F2820E83F2800280000000001F00208020801F00000 +B856:0000002800283F2801E83F2820E83F280028000003F80020002000D003080000 +B857:0000002800283F2801E83F2820E83F2800280000004003F8004000A003180000 +B858:0000002800283F2801E83F2820E83F280028000003F8000803F8000800080000 +B859:0000002800283F2801E83F2820E83F280028000003F8020003F8020003F80000 +B85A:0000002800283F2801E83F2820E83F280028000000000FF8022002200FF80000 +B85B:0000002800283F2801E83F2820E83F280028000000800FF803E0041003E00000 +B85C:000000001FF0001000101FF0100010001FF000000100010001007FFC00000000 +B85D:00001FF000101FF010001FF0010001007FFC00001FF000100010001000100000 +B85E:00001FF000101FF010001FF0010001007FFC000000003EF80208020802080000 +B85F:00001FF000101FF010001FF0010001007FFC000000001E100210022802C40000 +B860:00001FF000101FF010001FF0010001007FFC000000001000100010001FF00000 +B861:00001FF000101FF010001FF0010001007FFC0000000020F8201020303ECC0000 +B862:00001FF000101FF010001FF0010001007FFC0000202021FC207020883E700000 +B863:00001FF000101FF010001FF0010001007FFC00001FF01000100010001FF00000 +B864:00001FF000101FF010001FF0010001007FFC00001FF000101FF010001FF00000 +B865:00001FF000101FF010001FF0010001007FFC00003EF802083E0820083E080000 +B866:00001FF000101FF010001FF0010001007FFC00003EF802883E8820883EF80000 +B867:00001FF000101FF010001FF0010001007FFC00003E8802883EF820883EF80000 +B868:00001FF000101FF010001FF0010001007FFC00003E1002103E1020283EC40000 +B869:00001FF000101FF010001FF0010001007FFC00003EF802803EF820803EF80000 +B86A:00001FF000101FF010001FF0010001007FFC00003EFC02483E4820483EFC0000 +B86B:00001FF000101FF010001FF0010001007FFC00003E2003FC3E7020883E700000 +B86C:00001FF000101FF010001FF0010001007FFC00001FF01010101010101FF00000 +B86D:00001FF000101FF010001FF0010001007FFC0000101010101FF010101FF00000 +B86E:00001FF000101FF010001FF0010001007FFC0000222022203E2022503E880000 +B86F:00001FF000101FF010001FF0010001007FFC000000000100010002800C400000 +B870:00001FF000101FF010001FF0010001007FFC00000000024002400DA033100000 +B871:00001FF000101FF010001FF0010001007FFC0000000007C00820082007C00000 +B872:00001FF000101FF010001FF0010001007FFC0000000007E00080014006200000 +B873:00001FF000101FF010001FF0010001007FFC0000008007E00080014006200000 +B874:00001FF000101FF010001FF0010001007FFC00001FF000101FF0001000100000 +B875:00001FF000101FF010001FF0010001007FFC00001FF010001FF010001FF00000 +B876:00001FF000101FF010001FF0010001007FFC000000001FF0044004401FF00000 +B877:00001FF000101FF010001FF0010001007FFC000001001FF007C0082007C00000 +B878:0000001000103F90009000903F90201E20103F90041004107FD0001000100000 +B879:000000083F8800883F8E20083F8804087FE8000007F800080008000800080000 +B87A:000000083F8800883F8E20083F8804087FE8000000003EF80208020802080000 +B87B:000000083F8800883F8E20083F8804087FE8000000001F080108011401620000 +B87C:000000083F8800883F8E20083F8804087FE8000008000800080008000FF80000 +B87D:000000083F8800883F8E20083F8804087FE80000000010F8101010301ECC0000 +B87E:000000083F8800883F8E20083F8804087FE800000808087F081C08220F9C0000 +B87F:000000083F8800883F8E20083F8804087FE8000003F802000200020003F80000 +B880:000000083F8800883F8E20083F8804087FE8000007F8000807F8040007F80000 +B881:000000083F8800883F8E20083F8804087FE800003EF802083E0820083E080000 +B882:000000083F8800883F8E20083F8804087FE800003EF802883E8820883EF80000 +B883:000000083F8800883F8E20083F8804087FE800003E8802883EF820883EF80000 +B884:000000083F8800883F8E20083F8804087FE800001F0801081F0810141F620000 +B885:000000083F8800883F8E20083F8804087FE800003EF802803EF820803EF80000 +B886:000000083F8800883F8E20083F8804087FE800003EFC02483E4820483EFC0000 +B887:000000083F8800883F8E20083F8804087FE800001F08017F1F1C10221F1C0000 +B888:000000083F8800883F8E20083F8804087FE8000003F802080208020803F80000 +B889:000000083F8800883F8E20083F8804087FE800000208020803F8020803F80000 +B88A:000000083F8800883F8E20083F8804087FE80000110811081F0811141F620000 +B88B:000000083F8800883F8E20083F8804087FE80000001000100010006801840000 +B88C:000000083F8800883F8E20083F8804087FE800000048004800A8011406620000 +B88D:000000083F8800883F8E20083F8804087FE80000000003F00408040803F00000 +B88E:000000083F8800883F8E20083F8804087FE8000003F80020002000D003080000 +B88F:000000083F8800883F8E20083F8804087FE80000004003F8004000A003180000 +B890:000000083F8800883F8E20083F8804087FE8000003F8000803F8000800080000 +B891:000000083F8800883F8E20083F8804087FE8000003F8020003F8020003F80000 +B892:000000083F8800883F8E20083F8804087FE8000000000FF8022002200FF80000 +B893:000000083F8800883F8E20083F8804087FE8000000800FF803E0041003E00000 +B894:0000001200123F92009200923F92201E20123F92041204127FD2001200120000 +B895:000000283FA800A83FB820283FA804287FA8000007F800080008000800080000 +B896:000000283FA800A83FB820283FA804287FA8000000003EF80208020802080000 +B897:000000283FA800A83FB820283FA804287FA8000000001F080108011401620000 +B898:000000283FA800A83FB820283FA804287FA8000008000800080008000FF80000 +B899:000000283FA800A83FB820283FA804287FA80000000010F8101010301ECC0000 +B89A:000000283FA800A83FB820283FA804287FA800000808087F081C08220F9C0000 +B89B:000000283FA800A83FB820283FA804287FA8000003F802000200020003F80000 +B89C:000000283FA800A83FB820283FA804287FA8000007F8000807F8040007F80000 +B89D:000000283FA800A83FB820283FA804287FA800003EF802083E0820083E080000 +B89E:000000283FA800A83FB820283FA804287FA800003EF802883E8820883EF80000 +B89F:000000283FA800A83FB820283FA804287FA800003E8802883EF820883EF80000 +B8A0:000000283FA800A83FB820283FA804287FA800001F0801081F0810141F620000 +B8A1:000000283FA800A83FB820283FA804287FA800003EF802803EF820803EF80000 +B8A2:000000283FA800A83FB820283FA804287FA800003EFC02483E4820483EFC0000 +B8A3:000000283FA800A83FB820283FA804287FA800001F08017F1F1C10221F1C0000 +B8A4:000000283FA800A83FB820283FA804287FA8000003F802080208020803F80000 +B8A5:000000283FA800A83FB820283FA804287FA800000208020803F8020803F80000 +B8A6:000000283FA800A83FB820283FA804287FA80000110811081F0811141F620000 +B8A7:000000283FA800A83FB820283FA804287FA80000001000100010006801840000 +B8A8:000000283FA800A83FB820283FA804287FA800000048004800A8011406620000 +B8A9:000000283FA800A83FB820283FA804287FA80000000003F00408040803F00000 +B8AA:000000283FA800A83FB820283FA804287FA8000003F80020002000D003080000 +B8AB:000000283FA800A83FB820283FA804287FA80000004003F8004000A003180000 +B8AC:000000283FA800A83FB820283FA804287FA8000003F8000803F8000800080000 +B8AD:000000283FA800A83FB820283FA804287FA8000003F8020003F8020003F80000 +B8AE:000000283FA800A83FB820283FA804287FA8000000000FF8022002200FF80000 +B8AF:000000283FA800A83FB820283FA804287FA8000000800FF803E0041003E00000 +B8B0:0000000800083F88008800883F88200820083F88040804087FE8000800080000 +B8B1:000000083F8800883F8820083F8804087FE8000007F800080008000800080000 +B8B2:000000083F8800883F8820083F8804087FE8000000003EF80208020802080000 +B8B3:000000083F8800883F8820083F8804087FE8000000001F080108011401620000 +B8B4:000000083F8800883F8820083F8804087FE8000008000800080008000FF80000 +B8B5:000000083F8800883F8820083F8804087FE80000000010F8101010301ECC0000 +B8B6:000000083F8800883F8820083F8804087FE800000808087F081C08220F9C0000 +B8B7:000000083F8800883F8820083F8804087FE8000003F802000200020003F80000 +B8B8:000000083F8800883F8820083F8804087FE8000007F8000807F8040007F80000 +B8B9:000000083F8800883F8820083F8804087FE800003EF802083E0820083E080000 +B8BA:000000083F8800883F8820083F8804087FE800003EF802883E8820883EF80000 +B8BB:000000083F8800883F8820083F8804087FE800003E8802883EF820883EF80000 +B8BC:000000083F8800883F8820083F8804087FE800001F0801081F0810141F620000 +B8BD:000000083F8800883F8820083F8804087FE800003EF802803EF820803EF80000 +B8BE:000000083F8800883F8820083F8804087FE800003EFC02483E4820483EFC0000 +B8BF:000000083F8800883F8820083F8804087FE800001F08017F1F1C10221F1C0000 +B8C0:000000083F8800883F8820083F8804087FE8000003F802080208020803F80000 +B8C1:000000083F8800883F8820083F8804087FE800000208020803F8020803F80000 +B8C2:000000083F8800883F8820083F8804087FE80000110811081F0811141F620000 +B8C3:000000083F8800883F8820083F8804087FE80000001000100010006801840000 +B8C4:000000083F8800883F8820083F8804087FE800000048004800A8011406620000 +B8C5:000000083F8800883F8820083F8804087FE80000000003F00408040803F00000 +B8C6:000000083F8800883F8820083F8804087FE8000003F80020002000D003080000 +B8C7:000000083F8800883F8820083F8804087FE80000004003F8004000A003180000 +B8C8:000000083F8800883F8820083F8804087FE8000003F8000803F8000800080000 +B8C9:000000083F8800883F8820083F8804087FE8000003F8020003F8020003F80000 +B8CA:000000083F8800883F8820083F8804087FE8000000000FF8022002200FF80000 +B8CB:000000083F8800883F8820083F8804087FE8000000800FF803E0041003E00000 +B8CC:000000001FF0001000101FF0100010001FF004400440044004407FFC00000000 +B8CD:00001FF000101FF010001FF0044004407FFC00001FF000100010001000100000 +B8CE:00001FF000101FF010001FF0044004407FFC000000003EF80208020802080000 +B8CF:00001FF000101FF010001FF0044004407FFC000000001E100210022802C40000 +B8D0:00001FF000101FF010001FF0044004407FFC000000001000100010001FF00000 +B8D1:00001FF000101FF010001FF0044004407FFC0000000020F8201020303ECC0000 +B8D2:00001FF000101FF010001FF0044004407FFC0000202021FC207020883E700000 +B8D3:00001FF000101FF010001FF0044004407FFC00001FF01000100010001FF00000 +B8D4:00001FF000101FF010001FF0044004407FFC00001FF000101FF010001FF00000 +B8D5:00001FF000101FF010001FF0044004407FFC00003EF802083E0820083E080000 +B8D6:00001FF000101FF010001FF0044004407FFC00003EF802883E8820883EF80000 +B8D7:00001FF000101FF010001FF0044004407FFC00003E8802883EF820883EF80000 +B8D8:00001FF000101FF010001FF0044004407FFC00003E1002103E1020283EC40000 +B8D9:00001FF000101FF010001FF0044004407FFC00003EF802803EF820803EF80000 +B8DA:00001FF000101FF010001FF0044004407FFC00003EFC02483E4820483EFC0000 +B8DB:00001FF000101FF010001FF0044004407FFC00003E2003FC3E7020883E700000 +B8DC:00001FF000101FF010001FF0044004407FFC00001FF01010101010101FF00000 +B8DD:00001FF000101FF010001FF0044004407FFC0000101010101FF010101FF00000 +B8DE:00001FF000101FF010001FF0044004407FFC0000222022203E2022503E880000 +B8DF:00001FF000101FF010001FF0044004407FFC000000000100010002800C400000 +B8E0:00001FF000101FF010001FF0044004407FFC00000000024002400DA033100000 +B8E1:00001FF000101FF010001FF0044004407FFC0000000007C00820082007C00000 +B8E2:00001FF000101FF010001FF0044004407FFC0000000007E00080014006200000 +B8E3:00001FF000101FF010001FF0044004407FFC0000008007E00080014006200000 +B8E4:00001FF000101FF010001FF0044004407FFC00001FF000101FF0001000100000 +B8E5:00001FF000101FF010001FF0044004407FFC00001FF010001FF010001FF00000 +B8E6:00001FF000101FF010001FF0044004407FFC000000001FF0044004401FF00000 +B8E7:00001FF000101FF010001FF0044004407FFC000001001FF007C0082007C00000 +B8E8:000000001FF0001000101FF0100010001FF000003FF801000100010001000000 +B8E9:00001FF000101FF010001FF000007FFC010001001FF000100010001000100000 +B8EA:00001FF000101FF010001FF000007FFC0100010000003EF80208020802080000 +B8EB:00001FF000101FF010001FF000007FFC0100010000001E100210022802C40000 +B8EC:00001FF000101FF010001FF0000000007FFC010001001100100010001FF00000 +B8ED:00001FF000101FF010001FF000007FFC01000100000020F8201020303ECC0000 +B8EE:00001FF000101FF010001FF000007FFC01000100202021FC207020883E700000 +B8EF:00001FF000101FF010001FF000007FFC010001001FF01000100010001FF00000 +B8F0:00001FF000101FF010001FF000007FFC010001001FF000101FF010001FF00000 +B8F1:00001FF000101FF010001FF000007FFC010001003EF802083E0820083E080000 +B8F2:00001FF000101FF010001FF000007FFC010001003EF802883E8820883EF80000 +B8F3:00001FF000101FF010001FF000007FFC010001003E8802883EF820883EF80000 +B8F4:00001FF000101FF010001FF000007FFC010001003E1002103E1020283EC40000 +B8F5:00001FF000101FF010001FF000007FFC010001003EF802803EF820803EF80000 +B8F6:00001FF000101FF010001FF000007FFC010001003EFC02483E4820483EFC0000 +B8F7:00001FF000101FF010001FF000007FFC010001003E2003FC3E7020883E700000 +B8F8:00001FF000101FF010001FF000007FFC010001001FF01010101010101FF00000 +B8F9:00001FF000101FF010001FF000007FFC01000100101010101FF010101FF00000 +B8FA:00001FF000101FF010001FF000007FFC01000100222022203E2022503E880000 +B8FB:00001FF000101FF010001FF000007FFC0100010000000100010002800C400000 +B8FC:00001FF000101FF010001FF000007FFC010001000000024002400DA033100000 +B8FD:00001FF000101FF010001FF000007FFC01000100000007C00820082007C00000 +B8FE:00001FF000101FF010001FF000007FFC01000100000007E00080014006200000 +B8FF:00001FF000101FF010001FF000007FFC01000100008007E00080014006200000 +B900:00001FF000101FF010001FF000007FFC010001001FF000101FF0001000100000 +B901:00001FF000101FF010001FF000007FFC010001001FF010001FF010001FF00000 +B902:00001FF000101FF010001FF000007FFC0100010000001FF0044004401FF00000 +B903:00001FF000101FF010001FF000007FFC0100010001001FF007C0082007C00000 +B904:000000083FC8004800483FC8200820083FC800087FE8040804F8040804080000 +B905:7F8800887F8840087F8800087FE8027802080000000007F80008000800080000 +B906:7F8800887F8840087F8800087FE802780208000000003EF80208020802080000 +B907:7F8800887F8840087F8800087FE802780208000000001F080108011401620000 +B908:7F8800887F8840087F88000800087FE80278020802081000100010001FF80000 +B909:7F8800887F8840087F8800087FE8027802080000000020F8201020303ECC0000 +B90A:7F8800887F8840087F8800087FE8027802080000202021FC207020883E700000 +B90B:7F8800887F8840087F8800087FE802780208000003F802000200020003F80000 +B90C:7F8800887F8840087F8800087FE802780208000007F8000807F8040007F80000 +B90D:7F8800887F8840087F8800087FE80278020800003EF802083E0820083E080000 +B90E:7F8800887F8840087F8800087FE80278020800003EF802883E8820883EF80000 +B90F:7F8800887F8840087F8800087FE80278020800003E8802883EF820883EF80000 +B910:7F8800887F8840087F8800087FE80278020800000F8800880F8808140FA20000 +B911:7F8800887F8840087F8800087FE80278020800003EF802803EF820803EF80000 +B912:7F8800887F8840087F8800087FE80278020800003EFC02483E4820483EFC0000 +B913:7F8800887F8840087F8800087FE80278020800003E1002FE3E3820443E380000 +B914:7F8800887F8840087F8800087FE802780208000003F802080208020803F80000 +B915:7F8800887F8840087F8800087FE80278020800000208020803F8020803F80000 +B916:7F8800887F8840087F8800087FE8027802080000210821083F0821143F620000 +B917:7F8800887F8840087F8800087FE8027802080000001000100010006801840000 +B918:7F8800887F8840087F8800087FE80278020800000048004800A8011406620000 +B919:7F8800887F8840087F8800087FE8027802080000000003F00408040803F00000 +B91A:7F8800887F8840087F8800087FE802780208000003F80020002000D003080000 +B91B:7F8800887F8840087F8800087FE8027802080000004003F8004000A003180000 +B91C:7F8800887F8840087F8800087FE802780208000003F8000803F8000800080000 +B91D:7F8800887F8840087F8800087FE802780208000003F8020003F8020003F80000 +B91E:7F8800887F8840087F8800087FE802780208000000000FF8022002200FF80000 +B91F:7F8800887F8840087F8800087FE802780208000000800FF803E0041003E00000 +B920:0000000A3FCA004A004A3FCA200A200A3FCA000A7FEA040A047A040A040A0000 +B921:7FA800A87FA840287FA800287FA805E804280000000007F80008000800080000 +B922:7FA800A87FA840287FA800287FA805E80428000000003EF80208020802080000 +B923:7FA800A87FA840287FA800287FA805E80428000000001F080108011401620000 +B924:7FA800A87FA840287FA8002800287FA8042805E804281428100010001FF80000 +B925:7FA800A87FA840287FA800287FA805E804280000000020F8201020303ECC0000 +B926:7FA800A87FA840287FA800287FA805E804280000202021FC207020883E700000 +B927:7FA800A87FA840287FA800287FA805E80428000003F802000200020003F80000 +B928:7FA800A87FA840287FA800287FA805E80428000007F8000807F8040007F80000 +B929:7FA800A87FA840287FA800287FA805E8042800003EF802083E0820083E080000 +B92A:7FA800A87FA840287FA800287FA805E8042800003EF802883E8820883EF80000 +B92B:7FA800A87FA840287FA800287FA805E8042800003E8802883EF820883EF80000 +B92C:7FA800A87FA840287FA800287FA805E8042800000F8800880F8808140FA20000 +B92D:7FA800A87FA840287FA800287FA805E8042800003EF802803EF820803EF80000 +B92E:7FA800A87FA840287FA800287FA805E8042800003EFC02483E4820483EFC0000 +B92F:7FA800A87FA840287FA800287FA805E8042800003E1002FE3E3820443E380000 +B930:7FA800A87FA840287FA800287FA805E80428000003F802080208020803F80000 +B931:7FA800A87FA840287FA800287FA805E8042800000208020803F8020803F80000 +B932:7FA800A87FA840287FA800287FA805E804280000210821083F0821143F620000 +B933:7FA800A87FA840287FA800287FA805E804280000001000100010006801840000 +B934:7FA800A87FA840287FA800287FA805E8042800000048004800A8011406620000 +B935:7FA800A87FA840287FA800287FA805E804280000000003F00408040803F00000 +B936:7FA800A87FA840287FA800287FA805E80428000003F80020002000D003080000 +B937:7FA800A87FA840287FA800287FA805E804280000004003F8004000A003180000 +B938:7FA800A87FA840287FA800287FA805E80428000003F8000803F8000800080000 +B939:7FA800A87FA840287FA800287FA805E80428000003F8020003F8020003F80000 +B93A:7FA800A87FA840287FA800287FA805E80428000000000FF8022002200FF80000 +B93B:7FA800A87FA840287FA800287FA805E80428000000800FF803E0041003E00000 +B93C:000000083FC8004800483FC8200820083FC800087FE804080408040804080000 +B93D:7F8800887F8840087F8800087FE8020802000000000007F80008000800080000 +B93E:7F8800887F8840087F8800087FE802080200000000003EF80208020802080000 +B93F:7F8800887F8840087F8800087FE802080200000000001F080108011401620000 +B940:7F8800887F8840087F88000800087FE80208020802081008100010001FF80000 +B941:7F8800887F8840087F8800087FE8020802000000000020F8201020303ECC0000 +B942:7F8800887F8840087F8800087FE8020802000000202021FC207020883E700000 +B943:7F8800887F8840087F8800087FE802080200000003F802000200020003F80000 +B944:7F8800887F8840087F8800087FE802080200000007F8000807F8040007F80000 +B945:7F8800887F8840087F8800087FE80208020000003EF802083E0820083E080000 +B946:7F8800887F8840087F8800087FE80208020000003EF802883E8820883EF80000 +B947:7F8800887F8840087F8800087FE80208020000003E8802883EF820883EF80000 +B948:7F8800887F8840087F8800087FE80208020000000F8800880F8808140FA20000 +B949:7F8800887F8840087F8800087FE80208020000003EF802803EF820803EF80000 +B94A:7F8800887F8840087F8800087FE80208020000003EFC02483E4820483EFC0000 +B94B:7F8800887F8840087F8800087FE80208020000003E1002FE3E3820443E380000 +B94C:7F8800887F8840087F8800087FE802080200000003F802080208020803F80000 +B94D:7F8800887F8840087F8800087FE80208020000000208020803F8020803F80000 +B94E:7F8800887F8840087F8800087FE8020802000000210821083F0821143F620000 +B94F:7F8800887F8840087F8800087FE8020802000000001000100010006801840000 +B950:7F8800887F8840087F8800087FE80208020000000048004800A8011406620000 +B951:7F8800887F8840087F8800087FE8020802000000000003F00408040803F00000 +B952:7F8800887F8840087F8800087FE802080200000003F80020002000D003080000 +B953:7F8800887F8840087F8800087FE8020802000000004003F8004000A003180000 +B954:7F8800887F8840087F8800087FE802080200000003F8000803F8000800080000 +B955:7F8800887F8840087F8800087FE802080200000003F8020003F8020003F80000 +B956:7F8800887F8840087F8800087FE802080200000000000FF8022002200FF80000 +B957:7F8800887F8840087F8800087FE802080200000000800FF803E0041003E00000 +B958:000000001FF0001000101FF0100010001FF000007FFC04400440044004400000 +B959:00001FF000101FF010001FF000007FFC044004401FF000100010001000100000 +B95A:00001FF000101FF010001FF000007FFC0440044000003EF80208020802080000 +B95B:00001FF000101FF010001FF000007FFC0440044000001E100210022802C40000 +B95C:00001FF000101FF010001FF0000000007FFC044004401440100010001FF00000 +B95D:00001FF000101FF010001FF000007FFC04400440000020F8201020303ECC0000 +B95E:00001FF000101FF010001FF000007FFC04400440202021FC207020883E700000 +B95F:00001FF000101FF010001FF000007FFC044004401FF01000100010001FF00000 +B960:00001FF000101FF010001FF000007FFC044004401FF000101FF010001FF00000 +B961:00001FF000101FF010001FF000007FFC044004403EF802083E0820083E080000 +B962:00001FF000101FF010001FF000007FFC044004403EF802883E8820883EF80000 +B963:00001FF000101FF010001FF000007FFC044004403E8802883EF820883EF80000 +B964:00001FF000101FF010001FF000007FFC044004403E1002103E1020283EC40000 +B965:00001FF000101FF010001FF000007FFC044004403EF802803EF820803EF80000 +B966:00001FF000101FF010001FF000007FFC044004403EFC02483E4820483EFC0000 +B967:00001FF000101FF010001FF000007FFC044004403E2003FC3E7020883E700000 +B968:00001FF000101FF010001FF000007FFC044004401FF01010101010101FF00000 +B969:00001FF000101FF010001FF000007FFC04400440101010101FF010101FF00000 +B96A:00001FF000101FF010001FF000007FFC04400440222022203E2022503E880000 +B96B:00001FF000101FF010001FF000007FFC0440044000000100010002800C400000 +B96C:00001FF000101FF010001FF000007FFC044004400000024002400DA033100000 +B96D:00001FF000101FF010001FF000007FFC04400440000007C00820082007C00000 +B96E:00001FF000101FF010001FF000007FFC04400440000007E00080014006200000 +B96F:00001FF000101FF010001FF000007FFC04400440008007E00080014006200000 +B970:00001FF000101FF010001FF000007FFC044004401FF000101FF0001000100000 +B971:00001FF000101FF010001FF000007FFC044004401FF010001FF010001FF00000 +B972:00001FF000101FF010001FF000007FFC0440044000001FF0044004401FF00000 +B973:00001FF000101FF010001FF000007FFC0440044001001FF007C0082007C00000 +B974:000000001FF0001000101FF0100010001FF0000000007FFC0000000000000000 +B975:00001FF000101FF010001FF0000000007FFC00001FF000100010001000100000 +B976:00001FF000101FF010001FF0000000007FFC000000003EF80208020802080000 +B977:00001FF000101FF010001FF0000000007FFC000000001E100210022802C40000 +B978:00001FF000101FF010001FF0000000007FFC000000001000100010001FF00000 +B979:00001FF000101FF010001FF0000000007FFC0000000020F8201020303ECC0000 +B97A:00001FF000101FF010001FF0000000007FFC0000202021FC207020883E700000 +B97B:00001FF000101FF010001FF0000000007FFC00001FF01000100010001FF00000 +B97C:00001FF000101FF010001FF0000000007FFC00001FF000101FF010001FF00000 +B97D:00001FF000101FF010001FF0000000007FFC00003EF802083E0820083E080000 +B97E:00001FF000101FF010001FF0000000007FFC00003EF802883E8820883EF80000 +B97F:00001FF000101FF010001FF0000000007FFC00003E8802883EF820883EF80000 +B980:00001FF000101FF010001FF0000000007FFC00003E1002103E1020283EC40000 +B981:00001FF000101FF010001FF0000000007FFC00003EF802803EF820803EF80000 +B982:00001FF000101FF010001FF0000000007FFC00003EFC02483E4820483EFC0000 +B983:00001FF000101FF010001FF0000000007FFC00003E2003FC3E7020883E700000 +B984:00001FF000101FF010001FF0000000007FFC00001FF01010101010101FF00000 +B985:00001FF000101FF010001FF0000000007FFC0000101010101FF010101FF00000 +B986:00001FF000101FF010001FF0000000007FFC0000222022203E2022503E880000 +B987:00001FF000101FF010001FF0000000007FFC000000000100010002800C400000 +B988:00001FF000101FF010001FF0000000007FFC00000000024002400DA033100000 +B989:00001FF000101FF010001FF0000000007FFC0000000007C00820082007C00000 +B98A:00001FF000101FF010001FF0000000007FFC0000000007E00080014006200000 +B98B:00001FF000101FF010001FF0000000007FFC0000008007E00080014006200000 +B98C:00001FF000101FF010001FF0000000007FFC00001FF000101FF0001000100000 +B98D:00001FF000101FF010001FF0000000007FFC00001FF010001FF010001FF00000 +B98E:00001FF000101FF010001FF0000000007FFC000000001FF0044004401FF00000 +B98F:00001FF000101FF010001FF0000000007FFC000001001FF007C0082007C00000 +B990:0000000800083F88008800883F88200820083F8800087FE80008000800080000 +B991:000000083F8800883F8820083F8800087FE8000007F800080008000800080000 +B992:000000083F8800883F8820083F8800087FE8000000003EF80208020802080000 +B993:000000083F8800883F8820083F8800087FE8000000001F080108011401620000 +B994:000000083F8800883F8820083F8800087FE8000008000800080008000FF80000 +B995:000000083F8800883F8820083F8800087FE80000000010F8101010301ECC0000 +B996:000000083F8800883F8820083F8800087FE800000808087F081C08220F9C0000 +B997:000000083F8800883F8820083F8800087FE8000003F802000200020003F80000 +B998:000000083F8800883F8820083F8800087FE8000007F8000807F8040007F80000 +B999:000000083F8800883F8820083F8800087FE800003EF802083E0820083E080000 +B99A:000000083F8800883F8820083F8800087FE800003EF802883E8820883EF80000 +B99B:000000083F8800883F8820083F8800087FE800003E8802883EF820883EF80000 +B99C:000000083F8800883F8820083F8800087FE800001F0801081F0810141F620000 +B99D:000000083F8800883F8820083F8800087FE800003EF802803EF820803EF80000 +B99E:000000083F8800883F8820083F8800087FE800003EFC02483E4820483EFC0000 +B99F:000000083F8800883F8820083F8800087FE800001F08017F1F1C10221F1C0000 +B9A0:000000083F8800883F8820083F8800087FE8000003F802080208020803F80000 +B9A1:000000083F8800883F8820083F8800087FE800000208020803F8020803F80000 +B9A2:000000083F8800883F8820083F8800087FE80000110811081F0811141F620000 +B9A3:000000083F8800883F8820083F8800087FE80000001000100010006801840000 +B9A4:000000083F8800883F8820083F8800087FE800000048004800A8011406620000 +B9A5:000000083F8800883F8820083F8800087FE80000000003F00408040803F00000 +B9A6:000000083F8800883F8820083F8800087FE8000003F80020002000D003080000 +B9A7:000000083F8800883F8820083F8800087FE80000004003F8004000A003180000 +B9A8:000000083F8800883F8820083F8800087FE8000003F8000803F8000800080000 +B9A9:000000083F8800883F8820083F8800087FE8000003F8020003F8020003F80000 +B9AA:000000083F8800883F8820083F8800087FE8000000000FF8022002200FF80000 +B9AB:000000083F8800883F8820083F8800087FE8000000800FF803E0041003E00000 +B9AC:00000000000800083F88008800883F882008200820083F880008000800080000 +B9AD:0000000800083F0801083F0820083F0800080000000007F80008000800080000 +B9AE:0000000800083F0801083F0820083F080008000000003EF80208020802080000 +B9AF:0000000800083F0801083F0820083F080008000000001F080108011401620000 +B9B0:0000000800083F0801083F0820083F080008000800001000100010001FF80000 +B9B1:0000000800083F0801083F0820083F0800080000000020F8201020303ECC0000 +B9B2:0000000800083F0801083F0820083F0800080000202021FC207020883E700000 +B9B3:0000000800083F0801083F0820083F080008000003F802000200020003F80000 +B9B4:0000000800083F0801083F0820083F080008000007F8000807F8040007F80000 +B9B5:0000000800083F0801083F0820083F08000800003EF802083E0820083E080000 +B9B6:0000000800083F0801083F0820083F08000800003EF802883E8820883EF80000 +B9B7:0000000800083F0801083F0820083F08000800003E8802883EF820883EF80000 +B9B8:0000000800083F0801083F0820083F08000800000F8800880F8808140FA20000 +B9B9:0000000800083F0801083F0820083F08000800003EF802803EF820803EF80000 +B9BA:0000000800083F0801083F0820083F08000800003EFC02483E4820483EFC0000 +B9BB:0000000800083F0801083F0820083F08000800003E1002FE3E3820443E380000 +B9BC:0000000800083F0801083F0820083F080008000003F802080208020803F80000 +B9BD:0000000800083F0801083F0820083F08000800000208020803F8020803F80000 +B9BE:0000000800083F0801083F0820083F0800080000210821083F0821143F620000 +B9BF:0000000800083F0801083F0820083F0800080000001000100010006801840000 +B9C0:0000000800083F0801083F0820083F08000800000048004800A8011406620000 +B9C1:0000000800083F0801083F0820083F0800080000000003F00408040803F00000 +B9C2:0000000800083F0801083F0820083F080008000003F80020002000D003080000 +B9C3:0000000800083F0801083F0820083F0800080000004003F8004000A003180000 +B9C4:0000000800083F0801083F0820083F080008000003F8000803F8000800080000 +B9C5:0000000800083F0801083F0820083F080008000003F8020003F8020003F80000 +B9C6:0000000800083F0801083F0820083F080008000000000FF8022002200FF80000 +B9C7:0000000800083F0801083F0820083F080008000000800FF803E0041003E00000 +B9C8:00000000001000107F9040904090409E4090409040907F900010001000100000 +B9C9:000000087E0842084208420E42087E080008000007F800080008000800080000 +B9CA:000000087E0842084208420E42087E080008000000003EF80208020802080000 +B9CB:000000087E0842084208420E42087E080008000000001F080108011401620000 +B9CC:000000087E0842084208420E42087E080008000808000800080008000FF80000 +B9CD:000000087E0842084208420E42087E0800080000000010F8101010301ECC0000 +B9CE:000000087E0842084208420E42087E08000800000808087F081C08220F9C0000 +B9CF:000000087E0842084208420E42087E080008000003F802000200020003F80000 +B9D0:000000087E0842084208420E42087E080008000007F8000807F8040007F80000 +B9D1:000000087E0842084208420E42087E08000800003EF802083E0820083E080000 +B9D2:000000087E0842084208420E42087E08000800003EF802883E8820883EF80000 +B9D3:000000087E0842084208420E42087E08000800003E8802883EF820883EF80000 +B9D4:000000087E0842084208420E42087E08000800001F0801081F0810141F620000 +B9D5:000000087E0842084208420E42087E08000800003EF802803EF820803EF80000 +B9D6:000000087E0842084208420E42087E08000800003EFC02483E4820483EFC0000 +B9D7:000000087E0842084208420E42087E08000800001F08017F1F1C10221F1C0000 +B9D8:000000087E0842084208420E42087E080008000003F802080208020803F80000 +B9D9:000000087E0842084208420E42087E08000800000208020803F8020803F80000 +B9DA:000000087E0842084208420E42087E0800080000110811081F0811141F620000 +B9DB:000000087E0842084208420E42087E0800080000001000100010006801840000 +B9DC:000000087E0842084208420E42087E08000800000048004800A8011406620000 +B9DD:000000087E0842084208420E42087E0800080000000003F00408040803F00000 +B9DE:000000087E0842084208420E42087E080008000003F80020002000D003080000 +B9DF:000000087E0842084208420E42087E0800080000004003F8004000A003180000 +B9E0:000000087E0842084208420E42087E080008000003F8000803F8000800080000 +B9E1:000000087E0842084208420E42087E080008000003F8020003F8020003F80000 +B9E2:000000087E0842084208420E42087E080008000000000FF8022002200FF80000 +B9E3:000000087E0842084208420E42087E080008000000800FF803E0041003E00000 +B9E4:00000000001200127F9240924092409E4092409240927F920012001200120000 +B9E5:000000287E2842284228423842287E280028000007F800080008000800080000 +B9E6:000000287E2842284228423842287E280028000000003EF80208020802080000 +B9E7:000000287E2842284228423842287E280028000000003E100210022802C40000 +B9E8:000000287E2842284228423842287E280028002808000800080008000FF80000 +B9E9:000000287E2842284228423842287E2800280000000020F8201020303ECC0000 +B9EA:000000287E2842284228423842287E2800280000202021FC207020883E700000 +B9EB:000000287E2842284228423842287E280028000003F802000200020003F80000 +B9EC:000000287E2842284228423842287E280028000007F8000807F8040007F80000 +B9ED:000000287E2842284228423842287E28002800003EF802083E0820083E080000 +B9EE:000000287E2842284228423842287E28002800003EF802883E8820883EF80000 +B9EF:000000287E2842284228423842287E28002800003E8802883EF820883EF80000 +B9F0:000000287E2842284228423842287E28002800001F0801081F0810141F620000 +B9F1:000000287E2842284228423842287E28002800003EF802803EF820803EF80000 +B9F2:000000287E2842284228423842287E28002800003EFC02483E4820483EFC0000 +B9F3:000000287E2842284228423842287E28002800003E1002FE3E3820443E380000 +B9F4:000000287E2842284228423842287E280028000003F802080208020803F80000 +B9F5:000000287E2842284228423842287E28002800000208020803F8020803F80000 +B9F6:000000287E2842284228423842287E2800280000110811081F0811141F620000 +B9F7:000000287E2842284228423842287E2800280000000800080008003400C20000 +B9F8:000000287E2842284228423842287E28002800000048004800A8011406620000 +B9F9:000000287E2842284228423842287E2800280000000001F00208020801F00000 +B9FA:000000287E2842284228423842287E280028000003F80020002000D003080000 +B9FB:000000287E2842284228423842287E2800280000004003F8004000A003180000 +B9FC:000000287E2842284228423842287E280028000003F8000803F8000800080000 +B9FD:000000287E2842284228423842287E280028000003F8020003F8020003F80000 +B9FE:000000287E2842284228423842287E280028000000000FF8022002200FF80000 +B9FF:000000287E2842284228423842287E280028000000800FF803E0041003E00000 +BA00:00000000001000107F904090409E40904090409E40907F900010001000100000 +BA01:000000087E084208420E4208420E7E080008000007F800080008000800080000 +BA02:000000087E084208420E4208420E7E080008000000003EF80208020802080000 +BA03:000000087E084208420E4208420E7E080008000000001F080108011401620000 +BA04:000000087E084208420E4208420E7E080008000008000800080008000FF80000 +BA05:000000087E084208420E4208420E7E0800080000000010F8101010301ECC0000 +BA06:000000087E084208420E4208420E7E08000800000808087F081C08220F9C0000 +BA07:000000087E084208420E4208420E7E080008000003F802000200020003F80000 +BA08:000000087E084208420E4208420E7E080008000007F8000807F8040007F80000 +BA09:000000087E084208420E4208420E7E08000800003EF802083E0820083E080000 +BA0A:000000087E084208420E4208420E7E08000800003EF802883E8820883EF80000 +BA0B:000000087E084208420E4208420E7E08000800003E8802883EF820883EF80000 +BA0C:000000087E084208420E4208420E7E08000800001F0801081F0810141F620000 +BA0D:000000087E084208420E4208420E7E08000800003EF802803EF820803EF80000 +BA0E:000000087E084208420E4208420E7E08000800003EFC02483E4820483EFC0000 +BA0F:000000087E084208420E4208420E7E08000800001F08017F1F1C10221F1C0000 +BA10:000000087E084208420E4208420E7E080008000003F802080208020803F80000 +BA11:000000087E084208420E4208420E7E08000800000208020803F8020803F80000 +BA12:000000087E084208420E4208420E7E0800080000110811081F0811141F620000 +BA13:000000087E084208420E4208420E7E0800080000001000100010006801840000 +BA14:000000087E084208420E4208420E7E08000800000048004800A8011406620000 +BA15:000000087E084208420E4208420E7E0800080000000003F00408040803F00000 +BA16:000000087E084208420E4208420E7E080008000003F80020002000D003080000 +BA17:000000087E084208420E4208420E7E0800080000004003F8004000A003180000 +BA18:000000087E084208420E4208420E7E080008000003F8000803F8000800080000 +BA19:000000087E084208420E4208420E7E080008000003F8020003F8020003F80000 +BA1A:000000087E084208420E4208420E7E080008000000000FF8022002200FF80000 +BA1B:000000087E084208420E4208420E7E080008000000800FF803E0041003E00000 +BA1C:00000000001200127F924092409E40924092409E40927F920012001200120000 +BA1D:000000287E2842284238422842387E280028000007F800080008000800080000 +BA1E:000000287E2842284238422842387E280028000000003EF80208020802080000 +BA1F:000000287E2842284238422842387E280028000000003E100210022802C40000 +BA20:000000287E2842284238422842387E280028002808000800080008000FF80000 +BA21:000000287E2842284238422842387E2800280000000020F8201020303ECC0000 +BA22:000000287E2842284238422842387E2800280000202021FC207020883E700000 +BA23:000000287E2842284238422842387E280028000003F802000200020003F80000 +BA24:000000287E2842284238422842387E280028000007F8000807F8040007F80000 +BA25:000000287E2842284238422842387E28002800003EF802083E0820083E080000 +BA26:000000287E2842284238422842387E28002800003EF802883E8820883EF80000 +BA27:000000287E2842284238422842387E28002800003E8802883EF820883EF80000 +BA28:000000287E2842284238422842387E28002800001F0801081F0810141F620000 +BA29:000000287E2842284238422842387E28002800003EF802803EF820803EF80000 +BA2A:000000287E2842284238422842387E28002800003EFC02483E4820483EFC0000 +BA2B:000000287E2842284238422842387E28002800003E1002FE3E3820443E380000 +BA2C:000000287E2842284238422842387E280028000003F802080208020803F80000 +BA2D:000000287E2842284238422842387E28002800000208020803F8020803F80000 +BA2E:000000287E2842284238422842387E2800280000110811081F0811141F620000 +BA2F:000000287E2842284238422842387E2800280000000800080008003400C20000 +BA30:000000287E2842284238422842387E28002800000048004800A8011406620000 +BA31:000000287E2842284238422842387E2800280000000001F00208020801F00000 +BA32:000000287E2842284238422842387E280028000003F80020002000D003080000 +BA33:000000287E2842284238422842387E2800280000004003F8004000A003180000 +BA34:000000287E2842284238422842387E280028000003F8000803F8000800080000 +BA35:000000287E2842284238422842387E280028000003F8020003F8020003F80000 +BA36:000000287E2842284238422842387E280028000000000FF8022002200FF80000 +BA37:000000287E2842284238422842387E280028000000800FF803E0041003E00000 +BA38:00000000000200027F8240824082409E4082408240827F820002000200020000 +BA39:000000087E0842084208423842087E0800080000000007F80008000800080000 +BA3A:000000087E0842084208423842087E080008000000003EF80208020802080000 +BA3B:000000087E0842084208423842087E080008000000001F080108011401620000 +BA3C:000000087E0842084208423842087E080008000000001000100010001FF80000 +BA3D:000000087E0842084208423842087E0800080000000020F8201020303ECC0000 +BA3E:000000087E0842084208423842087E0800080000202021FC207020883E700000 +BA3F:000000087E0842084208423842087E080008000003F802000200020003F80000 +BA40:000000087E0842084208423842087E080008000007F8000807F8040007F80000 +BA41:000000087E0842084208423842087E08000800003EF802083E0820083E080000 +BA42:000000087E0842084208423842087E08000800003EF802883E8820883EF80000 +BA43:000000087E0842084208423842087E08000800003E8802883EF820883EF80000 +BA44:000000087E0842084208423842087E08000800000F8800880F8808140FA20000 +BA45:000000087E0842084208423842087E08000800003EF802803EF820803EF80000 +BA46:000000087E0842084208423842087E08000800003EFC02483E4820483EFC0000 +BA47:000000087E0842084208423842087E08000800003E1002FE3E3820443E380000 +BA48:000000087E0842084208423842087E080008000003F802080208020803F80000 +BA49:000000087E0842084208423842087E08000800000208020803F8020803F80000 +BA4A:000000087E0842084208423842087E0800080000210821083F0821143F620000 +BA4B:000000087E0842084208423842087E0800080000001000100010006801840000 +BA4C:000000087E0842084208423842087E08000800000048004800A8011406620000 +BA4D:000000087E0842084208423842087E0800080000000003F00408040803F00000 +BA4E:000000087E0842084208423842087E080008000003F80020002000D003080000 +BA4F:000000087E0842084208423842087E0800080000004003F8004000A003180000 +BA50:000000087E0842084208423842087E080008000003F8000803F8000800080000 +BA51:000000087E0842084208423842087E080008000003F8020003F8020003F80000 +BA52:000000087E0842084208423842087E080008000000000FF8022002200FF80000 +BA53:000000087E0842084208423842087E080008000000800FF803E0041003E00000 +BA54:00000000000A000A7F8A408A408A40BA408A408A408A7F8A000A000A000A0000 +BA55:000000287E284228422842E842287E280028000007F800080008000800080000 +BA56:000000287E284228422842E842287E280028000000003EF80208020802080000 +BA57:000000287E284228422842E842287E280028000000003E100210022802C40000 +BA58:000000287E284228422842E842287E280028000008000800080008000FF80000 +BA59:000000287E284228422842E842287E2800280000000020F8201020303ECC0000 +BA5A:000000287E284228422842E842287E2800280000202021FC207020883E700000 +BA5B:000000287E284228422842E842287E280028000003F802000200020003F80000 +BA5C:000000287E284228422842E842287E280028000007F8000807F8040007F80000 +BA5D:000000287E284228422842E842287E28002800003EF802083E0820083E080000 +BA5E:000000287E284228422842E842287E28002800003EF802883E8820883EF80000 +BA5F:000000287E284228422842E842287E28002800003E8802883EF820883EF80000 +BA60:000000287E284228422842E842287E28002800001F0801081F0810141F620000 +BA61:000000287E284228422842E842287E28002800003EF802803EF820803EF80000 +BA62:000000287E284228422842E842287E28002800003EFC02483E4820483EFC0000 +BA63:000000287E284228422842E842287E28002800003E1002FE3E3820443E380000 +BA64:000000287E284228422842E842287E280028000003F802080208020803F80000 +BA65:000000287E284228422842E842287E28002800000208020803F8020803F80000 +BA66:000000287E284228422842E842287E2800280000110811081F0811141F620000 +BA67:000000287E284228422842E842287E2800280000000800080008003400C20000 +BA68:000000287E284228422842E842287E28002800000048004800A8011406620000 +BA69:000000287E284228422842E842287E2800280000000001F00208020801F00000 +BA6A:000000287E284228422842E842287E280028000003F80020002000D003080000 +BA6B:000000287E284228422842E842287E2800280000004003F8004000A003180000 +BA6C:000000287E284228422842E842287E280028000003F8000803F8000800080000 +BA6D:000000287E284228422842E842287E280028000003F8020003F8020003F80000 +BA6E:000000287E284228422842E842287E280028000000000FF8022002200FF80000 +BA6F:000000287E284228422842E842287E280028000000800FF803E0041003E00000 +BA70:00000000000200027F824082409E40824082409E40827F820002000200020000 +BA71:000000087E0842084238420842387E0800080000000007F80008000800080000 +BA72:000000087E0842084238420842387E080008000000003EF80208020802080000 +BA73:000000087E0842084238420842387E080008000000001F080108011401620000 +BA74:000000087E0842084238420842387E080008000800001000100010001FF80000 +BA75:000000087E0842084238420842387E0800080000000020F8201020303ECC0000 +BA76:000000087E0842084238420842387E0800080000202021FC207020883E700000 +BA77:000000087E0842084238420842387E080008000003F802000200020003F80000 +BA78:000000087E0842084238420842387E080008000007F8000807F8040007F80000 +BA79:000000087E0842084238420842387E08000800003EF802083E0820083E080000 +BA7A:000000087E0842084238420842387E08000800003EF802883E8820883EF80000 +BA7B:000000087E0842084238420842387E08000800003E8802883EF820883EF80000 +BA7C:000000087E0842084238420842387E08000800000F8800880F8808140FA20000 +BA7D:000000087E0842084238420842387E08000800003EF802803EF820803EF80000 +BA7E:000000087E0842084238420842387E08000800003EFC02483E4820483EFC0000 +BA7F:000000087E0842084238420842387E08000800003E1002FE3E3820443E380000 +BA80:000000087E0842084238420842387E080008000003F802080208020803F80000 +BA81:000000087E0842084238420842387E08000800000208020803F8020803F80000 +BA82:000000087E0842084238420842387E0800080000210821083F0821143F620000 +BA83:000000087E0842084238420842387E0800080000001000100010006801840000 +BA84:000000087E0842084238420842387E08000800000048004800A8011406620000 +BA85:000000087E0842084238420842387E0800080000000003F00408040803F00000 +BA86:000000087E0842084238420842387E080008000003F80020002000D003080000 +BA87:000000087E0842084238420842387E0800080000004003F8004000A003180000 +BA88:000000087E0842084238420842387E080008000003F8000803F8000800080000 +BA89:000000087E0842084238420842387E080008000003F8020003F8020003F80000 +BA8A:000000087E0842084238420842387E080008000000000FF8022002200FF80000 +BA8B:000000087E0842084238420842387E080008000000800FF803E0041003E00000 +BA8C:00000000000A000A7F8A408A40BA408A408A40BA408A7F8A000A000A000A0000 +BA8D:000000287E28422842E8422842E87E280028000007F800080008000800080000 +BA8E:000000287E28422842E8422842E87E280028000000003EF80208020802080000 +BA8F:000000287E28422842E8422842E87E280028000000003E100210022802C40000 +BA90:000000287E28422842E8422842E87E280028002808000800080008000FF80000 +BA91:000000287E28422842E8422842E87E2800280000000020F8201020303ECC0000 +BA92:000000287E28422842E8422842E87E2800280000202021FC207020883E700000 +BA93:000000287E28422842E8422842E87E280028000003F802000200020003F80000 +BA94:000000287E28422842E8422842E87E280028000007F8000807F8040007F80000 +BA95:000000287E28422842E8422842E87E28002800003EF802083E0820083E080000 +BA96:000000287E28422842E8422842E87E28002800003EF802883E8820883EF80000 +BA97:000000287E28422842E8422842E87E28002800003E8802883EF820883EF80000 +BA98:000000287E28422842E8422842E87E28002800001F0801081F0810141F620000 +BA99:000000287E28422842E8422842E87E28002800003EF802803EF820803EF80000 +BA9A:000000287E28422842E8422842E87E28002800003EFC02483E4820483EFC0000 +BA9B:000000287E28422842E8422842E87E28002800003E1002FE3E3820443E380000 +BA9C:000000287E28422842E8422842E87E280028000003F802080208020803F80000 +BA9D:000000287E28422842E8422842E87E28002800000208020803F8020803F80000 +BA9E:000000287E28422842E8422842E87E2800280000110811081F0811141F620000 +BA9F:000000287E28422842E8422842E87E2800280000000800080008003400C20000 +BAA0:000000287E28422842E8422842E87E28002800000048004800A8011406620000 +BAA1:000000287E28422842E8422842E87E2800280000000001F00208020801F00000 +BAA2:000000287E28422842E8422842E87E280028000003F80020002000D003080000 +BAA3:000000287E28422842E8422842E87E2800280000004003F8004000A003180000 +BAA4:000000287E28422842E8422842E87E280028000003F8000803F8000800080000 +BAA5:000000287E28422842E8422842E87E280028000003F8020003F8020003F80000 +BAA6:000000287E28422842E8422842E87E280028000000000FF8022002200FF80000 +BAA7:000000287E28422842E8422842E87E280028000000800FF803E0041003E00000 +BAA8:000000003FF820082008200820083FF8000000000100010001007FFC00000000 +BAA9:00001FF01010101010101FF0010001007FFC00001FF000100010001000100000 +BAAA:00001FF01010101010101FF0010001007FFC000000003EF80208020802080000 +BAAB:00001FF01010101010101FF0010001007FFC000000001E100210022802C40000 +BAAC:00001FF01010101010101FF0010001007FFC000000001000100010001FF00000 +BAAD:00001FF01010101010101FF0010001007FFC0000000020F8201020303ECC0000 +BAAE:00001FF01010101010101FF0010001007FFC0000202021FC207020883E700000 +BAAF:00001FF01010101010101FF0010001007FFC00001FF01000100010001FF00000 +BAB0:00001FF01010101010101FF0010001007FFC00001FF000101FF010001FF00000 +BAB1:00001FF01010101010101FF0010001007FFC00003EF802083E0820083E080000 +BAB2:00001FF01010101010101FF0010001007FFC00003EF802883E8820883EF80000 +BAB3:00001FF01010101010101FF0010001007FFC00003E8802883EF820883EF80000 +BAB4:00001FF01010101010101FF0010001007FFC00003E1002103E1020283EC40000 +BAB5:00001FF01010101010101FF0010001007FFC00003EF802803EF820803EF80000 +BAB6:00001FF01010101010101FF0010001007FFC00003EFC02483E4820483EFC0000 +BAB7:00001FF01010101010101FF0010001007FFC00003E2003FC3E7020883E700000 +BAB8:00001FF01010101010101FF0010001007FFC00001FF01010101010101FF00000 +BAB9:00001FF01010101010101FF0010001007FFC0000101010101FF010101FF00000 +BABA:00001FF01010101010101FF0010001007FFC0000222022203E2022503E880000 +BABB:00001FF01010101010101FF0010001007FFC000000000100010002800C400000 +BABC:00001FF01010101010101FF0010001007FFC00000000024002400DA033100000 +BABD:00001FF01010101010101FF0010001007FFC0000000007C00820082007C00000 +BABE:00001FF01010101010101FF0010001007FFC0000000007E00080014006200000 +BABF:00001FF01010101010101FF0010001007FFC0000008007E00080014006200000 +BAC0:00001FF01010101010101FF0010001007FFC00001FF000101FF0001000100000 +BAC1:00001FF01010101010101FF0010001007FFC00001FF010001FF010001FF00000 +BAC2:00001FF01010101010101FF0010001007FFC000000001FF0044004401FF00000 +BAC3:00001FF01010101010101FF0010001007FFC000001001FF007C0082007C00000 +BAC4:0000001000103F90209020902090209E20903F90041004107FD0001000100000 +BAC5:000000083F882088208E20883F8804087FE8000007F800080008000800080000 +BAC6:000000083F882088208E20883F8804087FE8000000003EF80208020802080000 +BAC7:000000083F882088208E20883F8804087FE8000000001F080108011401620000 +BAC8:000000083F882088208E20883F8804087FE8000008000800080008000FF80000 +BAC9:000000083F882088208E20883F8804087FE80000000010F8101010301ECC0000 +BACA:000000083F882088208E20883F8804087FE800000808087F081C08220F9C0000 +BACB:000000083F882088208E20883F8804087FE8000003F802000200020003F80000 +BACC:000000083F882088208E20883F8804087FE8000007F8000807F8040007F80000 +BACD:000000083F882088208E20883F8804087FE800003EF802083E0820083E080000 +BACE:000000083F882088208E20883F8804087FE800003EF802883E8820883EF80000 +BACF:000000083F882088208E20883F8804087FE800003E8802883EF820883EF80000 +BAD0:000000083F882088208E20883F8804087FE800001F0801081F0810141F620000 +BAD1:000000083F882088208E20883F8804087FE800003EF802803EF820803EF80000 +BAD2:000000083F882088208E20883F8804087FE800003EFC02483E4820483EFC0000 +BAD3:000000083F882088208E20883F8804087FE800001F08017F1F1C10221F1C0000 +BAD4:000000083F882088208E20883F8804087FE8000003F802080208020803F80000 +BAD5:000000083F882088208E20883F8804087FE800000208020803F8020803F80000 +BAD6:000000083F882088208E20883F8804087FE80000110811081F0811141F620000 +BAD7:000000083F882088208E20883F8804087FE80000001000100010006801840000 +BAD8:000000083F882088208E20883F8804087FE800000048004800A8011406620000 +BAD9:000000083F882088208E20883F8804087FE80000000003F00408040803F00000 +BADA:000000083F882088208E20883F8804087FE8000003F80020002000D003080000 +BADB:000000083F882088208E20883F8804087FE80000004003F8004000A003180000 +BADC:000000083F882088208E20883F8804087FE8000003F8000803F8000800080000 +BADD:000000083F882088208E20883F8804087FE8000003F8020003F8020003F80000 +BADE:000000083F882088208E20883F8804087FE8000000000FF8022002200FF80000 +BADF:000000083F882088208E20883F8804087FE8000000800FF803E0041003E00000 +BAE0:0000001200123F92209220922092209E20923F92041204127FD2001200120000 +BAE1:000000283FA820A820B820A83FA804287FA8000007F800080008000800080000 +BAE2:000000283FA820A820B820A83FA804287FA8000000003EF80208020802080000 +BAE3:000000283FA820A820B820A83FA804287FA8000000001F080108011401620000 +BAE4:000000283FA820A820B820A83FA804287FA8000008000800080008000FF80000 +BAE5:000000283FA820A820B820A83FA804287FA80000000010F8101010301ECC0000 +BAE6:000000283FA820A820B820A83FA804287FA800000808087F081C08220F9C0000 +BAE7:000000283FA820A820B820A83FA804287FA8000003F802000200020003F80000 +BAE8:000000283FA820A820B820A83FA804287FA8000007F8000807F8040007F80000 +BAE9:000000283FA820A820B820A83FA804287FA800003EF802083E0820083E080000 +BAEA:000000283FA820A820B820A83FA804287FA800003EF802883E8820883EF80000 +BAEB:000000283FA820A820B820A83FA804287FA800003E8802883EF820883EF80000 +BAEC:000000283FA820A820B820A83FA804287FA800001F0801081F0810141F620000 +BAED:000000283FA820A820B820A83FA804287FA800003EF802803EF820803EF80000 +BAEE:000000283FA820A820B820A83FA804287FA800003EFC02483E4820483EFC0000 +BAEF:000000283FA820A820B820A83FA804287FA800001F08017F1F1C10221F1C0000 +BAF0:000000283FA820A820B820A83FA804287FA8000003F802080208020803F80000 +BAF1:000000283FA820A820B820A83FA804287FA800000208020803F8020803F80000 +BAF2:000000283FA820A820B820A83FA804287FA80000110811081F0811141F620000 +BAF3:000000283FA820A820B820A83FA804287FA80000001000100010006801840000 +BAF4:000000283FA820A820B820A83FA804287FA800000048004800A8011406620000 +BAF5:000000283FA820A820B820A83FA804287FA80000000003F00408040803F00000 +BAF6:000000283FA820A820B820A83FA804287FA8000003F80020002000D003080000 +BAF7:000000283FA820A820B820A83FA804287FA80000004003F8004000A003180000 +BAF8:000000283FA820A820B820A83FA804287FA8000003F8000803F8000800080000 +BAF9:000000283FA820A820B820A83FA804287FA8000003F8020003F8020003F80000 +BAFA:000000283FA820A820B820A83FA804287FA8000000000FF8022002200FF80000 +BAFB:000000283FA820A820B820A83FA804287FA8000000800FF803E0041003E00000 +BAFC:0000000800083F88208820882088208820883F88040804087FE8000800080000 +BAFD:000000083F882088208820883F8804087FE8000007F800080008000800080000 +BAFE:000000083F882088208820883F8804087FE8000000003EF80208020802080000 +BAFF:000000083F882088208820883F8804087FE8000000001F080108011401620000 +BB00:000000083F882088208820883F8804087FE8000008000800080008000FF80000 +BB01:000000083F882088208820883F8804087FE80000000010F8101010301ECC0000 +BB02:000000083F882088208820883F8804087FE800000808087F081C08220F9C0000 +BB03:000000083F882088208820883F8804087FE8000003F802000200020003F80000 +BB04:000000083F882088208820883F8804087FE8000007F8000807F8040007F80000 +BB05:000000083F882088208820883F8804087FE800003EF802083E0820083E080000 +BB06:000000083F882088208820883F8804087FE800003EF802883E8820883EF80000 +BB07:000000083F882088208820883F8804087FE800003E8802883EF820883EF80000 +BB08:000000083F882088208820883F8804087FE800001F0801081F0810141F620000 +BB09:000000083F882088208820883F8804087FE800003EF802803EF820803EF80000 +BB0A:000000083F882088208820883F8804087FE800003EFC02483E4820483EFC0000 +BB0B:000000083F882088208820883F8804087FE800001F08017F1F1C10221F1C0000 +BB0C:000000083F882088208820883F8804087FE8000003F802080208020803F80000 +BB0D:000000083F882088208820883F8804087FE800000208020803F8020803F80000 +BB0E:000000083F882088208820883F8804087FE80000110811081F0811141F620000 +BB0F:000000083F882088208820883F8804087FE80000001000100010006801840000 +BB10:000000083F882088208820883F8804087FE800000048004800A8011406620000 +BB11:000000083F882088208820883F8804087FE80000000003F00408040803F00000 +BB12:000000083F882088208820883F8804087FE8000003F80020002000D003080000 +BB13:000000083F882088208820883F8804087FE80000004003F8004000A003180000 +BB14:000000083F882088208820883F8804087FE8000003F8000803F8000800080000 +BB15:000000083F882088208820883F8804087FE8000003F8020003F8020003F80000 +BB16:000000083F882088208820883F8804087FE8000000000FF8022002200FF80000 +BB17:000000083F882088208820883F8804087FE8000000800FF803E0041003E00000 +BB18:000000003FF820082008200820083FF8000004400440044004407FFC00000000 +BB19:00001FF01010101010101FF0044004407FFC00001FF000100010001000100000 +BB1A:00001FF01010101010101FF0044004407FFC000000003EF80208020802080000 +BB1B:00001FF01010101010101FF0044004407FFC000000001E100210022802C40000 +BB1C:00001FF01010101010101FF0044004407FFC000000001000100010001FF00000 +BB1D:00001FF01010101010101FF0044004407FFC0000000020F8201020303ECC0000 +BB1E:00001FF01010101010101FF0044004407FFC0000202021FC207020883E700000 +BB1F:00001FF01010101010101FF0044004407FFC00001FF01000100010001FF00000 +BB20:00001FF01010101010101FF0044004407FFC00001FF000101FF010001FF00000 +BB21:00001FF01010101010101FF0044004407FFC00003EF802083E0820083E080000 +BB22:00001FF01010101010101FF0044004407FFC00003EF802883E8820883EF80000 +BB23:00001FF01010101010101FF0044004407FFC00003E8802883EF820883EF80000 +BB24:00001FF01010101010101FF0044004407FFC00003E1002103E1020283EC40000 +BB25:00001FF01010101010101FF0044004407FFC00003EF802803EF820803EF80000 +BB26:00001FF01010101010101FF0044004407FFC00003EFC02483E4820483EFC0000 +BB27:00001FF01010101010101FF0044004407FFC00003E2003FC3E7020883E700000 +BB28:00001FF01010101010101FF0044004407FFC00001FF01010101010101FF00000 +BB29:00001FF01010101010101FF0044004407FFC0000101010101FF010101FF00000 +BB2A:00001FF01010101010101FF0044004407FFC0000222022203E2022503E880000 +BB2B:00001FF01010101010101FF0044004407FFC000000000100010002800C400000 +BB2C:00001FF01010101010101FF0044004407FFC00000000024002400DA033100000 +BB2D:00001FF01010101010101FF0044004407FFC0000000007C00820082007C00000 +BB2E:00001FF01010101010101FF0044004407FFC0000000007E00080014006200000 +BB2F:00001FF01010101010101FF0044004407FFC0000008007E00080014006200000 +BB30:00001FF01010101010101FF0044004407FFC00001FF000101FF0001000100000 +BB31:00001FF01010101010101FF0044004407FFC00001FF010001FF010001FF00000 +BB32:00001FF01010101010101FF0044004407FFC000000001FF0044004401FF00000 +BB33:00001FF01010101010101FF0044004407FFC000001001FF007C0082007C00000 +BB34:000000003FF8200820082008200820083FF800003FF801000100010001000000 +BB35:00001FF01010101010101FF000007FFC010001001FF000100010001000100000 +BB36:00001FF01010101010101FF000007FFC0100010000003EF80208020802080000 +BB37:00001FF01010101010101FF000007FFC0100010000001E100210022802C40000 +BB38:00001FF01010101010101FF0000000007FFC010001001100100010001FF00000 +BB39:00001FF01010101010101FF000007FFC01000100000020F8201020303ECC0000 +BB3A:00001FF01010101010101FF000007FFC01000100202021FC207020883E700000 +BB3B:00001FF01010101010101FF000007FFC010001001FF01000100010001FF00000 +BB3C:00001FF01010101010101FF000007FFC010001001FF000101FF010001FF00000 +BB3D:00001FF01010101010101FF000007FFC010001003EF802083E0820083E080000 +BB3E:00001FF01010101010101FF000007FFC010001003EF802883E8820883EF80000 +BB3F:00001FF01010101010101FF000007FFC010001003E8802883EF820883EF80000 +BB40:00001FF01010101010101FF000007FFC010001003E1002103E1020283EC40000 +BB41:00001FF01010101010101FF000007FFC010001003EF802803EF820803EF80000 +BB42:00001FF01010101010101FF000007FFC010001003EFC02483E4820483EFC0000 +BB43:00001FF01010101010101FF000007FFC010001003E2003FC3E7020883E700000 +BB44:00001FF01010101010101FF000007FFC010001001FF01010101010101FF00000 +BB45:00001FF01010101010101FF000007FFC01000100101010101FF010101FF00000 +BB46:00001FF01010101010101FF000007FFC01000100222022203E2022503E880000 +BB47:00001FF01010101010101FF000007FFC0100010000000100010002800C400000 +BB48:00001FF01010101010101FF000007FFC010001000000024002400DA033100000 +BB49:00001FF01010101010101FF000007FFC01000100000007C00820082007C00000 +BB4A:00001FF01010101010101FF000007FFC01000100000007E00080014006200000 +BB4B:00001FF01010101010101FF000007FFC01000100008007E00080014006200000 +BB4C:00001FF01010101010101FF000007FFC010001001FF000101FF0001000100000 +BB4D:00001FF01010101010101FF000007FFC010001001FF010001FF010001FF00000 +BB4E:00001FF01010101010101FF000007FFC0100010000001FF0044004401FF00000 +BB4F:00001FF01010101010101FF000007FFC0100010001001FF007C0082007C00000 +BB50:000000083FC8204820482048204820483FC800087FE8040804F8040804080000 +BB51:00083F88208820883F8800087FE8027802080000000007F80008000800080000 +BB52:00083F88208820883F8800087FE802780208000000003EF80208020802080000 +BB53:00083F88208820883F8800087FE802780208000000001F080108011401620000 +BB54:00083F88208820883F88000800087FE80278020802081000100010001FF80000 +BB55:00083F88208820883F8800087FE8027802080000000020F8201020303ECC0000 +BB56:00083F88208820883F8800087FE8027802080000202021FC207020883E700000 +BB57:00083F88208820883F8800087FE802780208000003F802000200020003F80000 +BB58:00083F88208820883F8800087FE802780208000007F8000807F8040007F80000 +BB59:00083F88208820883F8800087FE80278020800003EF802083E0820083E080000 +BB5A:00083F88208820883F8800087FE80278020800003EF802883E8820883EF80000 +BB5B:00083F88208820883F8800087FE80278020800003E8802883EF820883EF80000 +BB5C:00083F88208820883F8800087FE80278020800000F8800880F8808140FA20000 +BB5D:00083F88208820883F8800087FE80278020800003EF802803EF820803EF80000 +BB5E:00083F88208820883F8800087FE80278020800003EFC02483E4820483EFC0000 +BB5F:00083F88208820883F8800087FE80278020800003E1002FE3E3820443E380000 +BB60:00083F88208820883F8800087FE802780208000003F802080208020803F80000 +BB61:00083F88208820883F8800087FE80278020800000208020803F8020803F80000 +BB62:00083F88208820883F8800087FE8027802080000210821083F0821143F620000 +BB63:00083F88208820883F8800087FE8027802080000001000100010006801840000 +BB64:00083F88208820883F8800087FE80278020800000048004800A8011406620000 +BB65:00083F88208820883F8800087FE8027802080000000003F00408040803F00000 +BB66:00083F88208820883F8800087FE802780208000003F80020002000D003080000 +BB67:00083F88208820883F8800087FE8027802080000004003F8004000A003180000 +BB68:00083F88208820883F8800087FE802780208000003F8000803F8000800080000 +BB69:00083F88208820883F8800087FE802780208000003F8020003F8020003F80000 +BB6A:00083F88208820883F8800087FE802780208000000000FF8022002200FF80000 +BB6B:00083F88208820883F8800087FE802780208000000800FF803E0041003E00000 +BB6C:0000000A3FCA204A204A204A204A204A3FCA000A7FEA040A047A040A040A0000 +BB6D:00283FA820A820A83FA800287FA805E804280000000007F80008000800080000 +BB6E:00283FA820A820A83FA800287FA805E80428000000003EF80208020802080000 +BB6F:00283FA820A820A83FA800287FA805E80428000000001F080108011401620000 +BB70:00283FA820A820A83FA8002800287FA8042805E804281428100010001FF80000 +BB71:00283FA820A820A83FA800287FA805E804280000000020F8201020303ECC0000 +BB72:00283FA820A820A83FA800287FA805E804280000202021FC207020883E700000 +BB73:00283FA820A820A83FA800287FA805E80428000003F802000200020003F80000 +BB74:00283FA820A820A83FA800287FA805E80428000007F8000807F8040007F80000 +BB75:00283FA820A820A83FA800287FA805E8042800003EF802083E0820083E080000 +BB76:00283FA820A820A83FA800287FA805E8042800003EF802883E8820883EF80000 +BB77:00283FA820A820A83FA800287FA805E8042800003E8802883EF820883EF80000 +BB78:00283FA820A820A83FA800287FA805E8042800000F8800880F8808140FA20000 +BB79:00283FA820A820A83FA800287FA805E8042800003EF802803EF820803EF80000 +BB7A:00283FA820A820A83FA800287FA805E8042800003EFC02483E4820483EFC0000 +BB7B:00283FA820A820A83FA800287FA805E8042800003E1002FE3E3820443E380000 +BB7C:00283FA820A820A83FA800287FA805E80428000003F802080208020803F80000 +BB7D:00283FA820A820A83FA800287FA805E8042800000208020803F8020803F80000 +BB7E:00283FA820A820A83FA800287FA805E804280000210821083F0821143F620000 +BB7F:00283FA820A820A83FA800287FA805E804280000001000100010006801840000 +BB80:00283FA820A820A83FA800287FA805E8042800000048004800A8011406620000 +BB81:00283FA820A820A83FA800287FA805E804280000000003F00408040803F00000 +BB82:00283FA820A820A83FA800287FA805E80428000003F80020002000D003080000 +BB83:00283FA820A820A83FA800287FA805E804280000004003F8004000A003180000 +BB84:00283FA820A820A83FA800287FA805E80428000003F8000803F8000800080000 +BB85:00283FA820A820A83FA800287FA805E80428000003F8020003F8020003F80000 +BB86:00283FA820A820A83FA800287FA805E80428000000000FF8022002200FF80000 +BB87:00283FA820A820A83FA800287FA805E80428000000800FF803E0041003E00000 +BB88:000000083FC8204820482048204820483FC800087FE804080408040804080000 +BB89:00083F88208820883F8800087FE8020802000000000007F80008000800080000 +BB8A:00083F88208820883F8800087FE802080200000000003EF80208020802080000 +BB8B:00083F88208820883F8800087FE802080200000000001F080108011401620000 +BB8C:00083F88208820883F88000800087FE80208020802081008100010001FF80000 +BB8D:00083F88208820883F8800087FE8020802000000000020F8201020303ECC0000 +BB8E:00083F88208820883F8800087FE8020802000000202021FC207020883E700000 +BB8F:00083F88208820883F8800087FE802080200000003F802000200020003F80000 +BB90:00083F88208820883F8800087FE802080200000007F8000807F8040007F80000 +BB91:00083F88208820883F8800087FE80208020000003EF802083E0820083E080000 +BB92:00083F88208820883F8800087FE80208020000003EF802883E8820883EF80000 +BB93:00083F88208820883F8800087FE80208020000003E8802883EF820883EF80000 +BB94:00083F88208820883F8800087FE80208020000000F8800880F8808140FA20000 +BB95:00083F88208820883F8800087FE80208020000003EF802803EF820803EF80000 +BB96:00083F88208820883F8800087FE80208020000003EFC02483E4820483EFC0000 +BB97:00083F88208820883F8800087FE80208020000003E1002FE3E3820443E380000 +BB98:00083F88208820883F8800087FE802080200000003F802080208020803F80000 +BB99:00083F88208820883F8800087FE80208020000000208020803F8020803F80000 +BB9A:00083F88208820883F8800087FE8020802000000210821083F0821143F620000 +BB9B:00083F88208820883F8800087FE8020802000000001000100010006801840000 +BB9C:00083F88208820883F8800087FE80208020000000048004800A8011406620000 +BB9D:00083F88208820883F8800087FE8020802000000000003F00408040803F00000 +BB9E:00083F88208820883F8800087FE802080200000003F80020002000D003080000 +BB9F:00083F88208820883F8800087FE8020802000000004003F8004000A003180000 +BBA0:00083F88208820883F8800087FE802080200000003F8000803F8000800080000 +BBA1:00083F88208820883F8800087FE802080200000003F8020003F8020003F80000 +BBA2:00083F88208820883F8800087FE802080200000000000FF8022002200FF80000 +BBA3:00083F88208820883F8800087FE802080200000000800FF803E0041003E00000 +BBA4:000000003FF8200820082008200820083FF800007FFC04400440044004400000 +BBA5:00001FF01010101010101FF000007FFC044004401FF000100010001000100000 +BBA6:00001FF01010101010101FF000007FFC0440044000003EF80208020802080000 +BBA7:00001FF01010101010101FF000007FFC0440044000001E100210022802C40000 +BBA8:00001FF01010101010101FF0000000007FFC044004401440100010001FF00000 +BBA9:00001FF01010101010101FF000007FFC04400440000020F8201020303ECC0000 +BBAA:00001FF01010101010101FF000007FFC04400440202021FC207020883E700000 +BBAB:00001FF01010101010101FF000007FFC044004401FF01000100010001FF00000 +BBAC:00001FF01010101010101FF000007FFC044004401FF000101FF010001FF00000 +BBAD:00001FF01010101010101FF000007FFC044004403EF802083E0820083E080000 +BBAE:00001FF01010101010101FF000007FFC044004403EF802883E8820883EF80000 +BBAF:00001FF01010101010101FF000007FFC044004403E8802883EF820883EF80000 +BBB0:00001FF01010101010101FF000007FFC044004403E1002103E1020283EC40000 +BBB1:00001FF01010101010101FF000007FFC044004403EF802803EF820803EF80000 +BBB2:00001FF01010101010101FF000007FFC044004403EFC02483E4820483EFC0000 +BBB3:00001FF01010101010101FF000007FFC044004403E2003FC3E7020883E700000 +BBB4:00001FF01010101010101FF000007FFC044004401FF01010101010101FF00000 +BBB5:00001FF01010101010101FF000007FFC04400440101010101FF010101FF00000 +BBB6:00001FF01010101010101FF000007FFC04400440222022203E2022503E880000 +BBB7:00001FF01010101010101FF000007FFC0440044000000100010002800C400000 +BBB8:00001FF01010101010101FF000007FFC044004400000024002400DA033100000 +BBB9:00001FF01010101010101FF000007FFC04400440000007C00820082007C00000 +BBBA:00001FF01010101010101FF000007FFC04400440000007E00080014006200000 +BBBB:00001FF01010101010101FF000007FFC04400440008007E00080014006200000 +BBBC:00001FF01010101010101FF000007FFC044004401FF000101FF0001000100000 +BBBD:00001FF01010101010101FF000007FFC044004401FF010001FF010001FF00000 +BBBE:00001FF01010101010101FF000007FFC0440044000001FF0044004401FF00000 +BBBF:00001FF01010101010101FF000007FFC0440044001001FF007C0082007C00000 +BBC0:000000003FF820082008200820083FF80000000000007FFC0000000000000000 +BBC1:00001FF01010101010101FF0000000007FFC00001FF000100010001000100000 +BBC2:00001FF01010101010101FF0000000007FFC000000003EF80208020802080000 +BBC3:00001FF01010101010101FF0000000007FFC000000001E100210022802C40000 +BBC4:00001FF01010101010101FF0000000007FFC000000001000100010001FF00000 +BBC5:00001FF01010101010101FF0000000007FFC0000000020F8201020303ECC0000 +BBC6:00001FF01010101010101FF0000000007FFC0000202021FC207020883E700000 +BBC7:00001FF01010101010101FF0000000007FFC00001FF01000100010001FF00000 +BBC8:00001FF01010101010101FF0000000007FFC00001FF000101FF010001FF00000 +BBC9:00001FF01010101010101FF0000000007FFC00003EF802083E0820083E080000 +BBCA:00001FF01010101010101FF0000000007FFC00003EF802883E8820883EF80000 +BBCB:00001FF01010101010101FF0000000007FFC00003E8802883EF820883EF80000 +BBCC:00001FF01010101010101FF0000000007FFC00003E1002103E1020283EC40000 +BBCD:00001FF01010101010101FF0000000007FFC00003EF802803EF820803EF80000 +BBCE:00001FF01010101010101FF0000000007FFC00003EFC02483E4820483EFC0000 +BBCF:00001FF01010101010101FF0000000007FFC00003E2003FC3E7020883E700000 +BBD0:00001FF01010101010101FF0000000007FFC00001FF01010101010101FF00000 +BBD1:00001FF01010101010101FF0000000007FFC0000101010101FF010101FF00000 +BBD2:00001FF01010101010101FF0000000007FFC0000222022203E2022503E880000 +BBD3:00001FF01010101010101FF0000000007FFC000000000100010002800C400000 +BBD4:00001FF01010101010101FF0000000007FFC00000000024002400DA033100000 +BBD5:00001FF01010101010101FF0000000007FFC0000000007C00820082007C00000 +BBD6:00001FF01010101010101FF0000000007FFC0000000007E00080014006200000 +BBD7:00001FF01010101010101FF0000000007FFC0000008007E00080014006200000 +BBD8:00001FF01010101010101FF0000000007FFC00001FF000101FF0001000100000 +BBD9:00001FF01010101010101FF0000000007FFC00001FF010001FF010001FF00000 +BBDA:00001FF01010101010101FF0000000007FFC000000001FF0044004401FF00000 +BBDB:00001FF01010101010101FF0000000007FFC000001001FF007C0082007C00000 +BBDC:0000000800083F88208820882088208820883F8800087FE80008000800080000 +BBDD:000000083F882088208820883F8800087FE8000007F800080008000800080000 +BBDE:000000083F882088208820883F8800087FE8000000003EF80208020802080000 +BBDF:000000083F882088208820883F8800087FE8000000001F080108011401620000 +BBE0:000000083F882088208820883F8800087FE8000008000800080008000FF80000 +BBE1:000000083F882088208820883F8800087FE80000000010F8101010301ECC0000 +BBE2:000000083F882088208820883F8800087FE800000808087F081C08220F9C0000 +BBE3:000000083F882088208820883F8800087FE8000003F802000200020003F80000 +BBE4:000000083F882088208820883F8800087FE8000007F8000807F8040007F80000 +BBE5:000000083F882088208820883F8800087FE800003EF802083E0820083E080000 +BBE6:000000083F882088208820883F8800087FE800003EF802883E8820883EF80000 +BBE7:000000083F882088208820883F8800087FE800003E8802883EF820883EF80000 +BBE8:000000083F882088208820883F8800087FE800001F0801081F0810141F620000 +BBE9:000000083F882088208820883F8800087FE800003EF802803EF820803EF80000 +BBEA:000000083F882088208820883F8800087FE800003EFC02483E4820483EFC0000 +BBEB:000000083F882088208820883F8800087FE800001F08017F1F1C10221F1C0000 +BBEC:000000083F882088208820883F8800087FE8000003F802080208020803F80000 +BBED:000000083F882088208820883F8800087FE800000208020803F8020803F80000 +BBEE:000000083F882088208820883F8800087FE80000110811081F0811141F620000 +BBEF:000000083F882088208820883F8800087FE80000001000100010006801840000 +BBF0:000000083F882088208820883F8800087FE800000048004800A8011406620000 +BBF1:000000083F882088208820883F8800087FE80000000003F00408040803F00000 +BBF2:000000083F882088208820883F8800087FE8000003F80020002000D003080000 +BBF3:000000083F882088208820883F8800087FE80000004003F8004000A003180000 +BBF4:000000083F882088208820883F8800087FE8000003F8000803F8000800080000 +BBF5:000000083F882088208820883F8800087FE8000003F8020003F8020003F80000 +BBF6:000000083F882088208820883F8800087FE8000000000FF8022002200FF80000 +BBF7:000000083F882088208820883F8800087FE8000000800FF803E0041003E00000 +BBF8:00000000000800087F884088408840884088408840887F880008000800080000 +BBF9:000000087E0842084208420842087E0800080000000007F80008000800080000 +BBFA:000000087E0842084208420842087E080008000000003EF80208020802080000 +BBFB:000000087E0842084208420842087E080008000000001F080108011401620000 +BBFC:000000087E0842084208420842087E080008000800001000100010001FF80000 +BBFD:000000087E0842084208420842087E0800080000000020F8201020303ECC0000 +BBFE:000000087E0842084208420842087E0800080000202021FC207020883E700000 +BBFF:000000087E0842084208420842087E080008000003F802000200020003F80000 +BC00:000000087E0842084208420842087E080008000007F8000807F8040007F80000 +BC01:000000087E0842084208420842087E08000800003EF802083E0820083E080000 +BC02:000000087E0842084208420842087E08000800003EF802883E8820883EF80000 +BC03:000000087E0842084208420842087E08000800003E8802883EF820883EF80000 +BC04:000000087E0842084208420842087E08000800000F8800880F8808140FA20000 +BC05:000000087E0842084208420842087E08000800003EF802803EF820803EF80000 +BC06:000000087E0842084208420842087E08000800003EFC02483E4820483EFC0000 +BC07:000000087E0842084208420842087E08000800003E1002FE3E3820443E380000 +BC08:000000087E0842084208420842087E080008000003F802080208020803F80000 +BC09:000000087E0842084208420842087E08000800000208020803F8020803F80000 +BC0A:000000087E0842084208420842087E0800080000210821083F0821143F620000 +BC0B:000000087E0842084208420842087E0800080000001000100010006801840000 +BC0C:000000087E0842084208420842087E08000800000048004800A8011406620000 +BC0D:000000087E0842084208420842087E0800080000000003F00408040803F00000 +BC0E:000000087E0842084208420842087E080008000003F80020002000D003080000 +BC0F:000000087E0842084208420842087E0800080000004003F8004000A003180000 +BC10:000000087E0842084208420842087E080008000003F8000803F8000800080000 +BC11:000000087E0842084208420842087E080008000003F8020003F8020003F80000 +BC12:000000087E0842084208420842087E080008000000000FF8022002200FF80000 +BC13:000000087E0842084208420842087E080008000000800FF803E0041003E00000 +BC14:00000000001000102090209020903F9E2090209020903F900010001000100000 +BC15:000000080008420842087E0E42087E080008000007F800080008000800080000 +BC16:000000080008420842087E0E42087E080008000000003EF80208020802080000 +BC17:000000080008420842087E0E42087E080008000000001F080108011401620000 +BC18:000000080008420842087E0E42087E080008000808000800080008000FF80000 +BC19:000000080008420842087E0E42087E0800080000000010F8101010301ECC0000 +BC1A:000000080008420842087E0E42087E08000800000808087F081C08220F9C0000 +BC1B:000000080008420842087E0E42087E080008000003F802000200020003F80000 +BC1C:000000080008420842087E0E42087E080008000007F8000807F8040007F80000 +BC1D:000000080008420842087E0E42087E08000800003EF802083E0820083E080000 +BC1E:000000080008420842087E0E42087E08000800003EF802883E8820883EF80000 +BC1F:000000080008420842087E0E42087E08000800003E8802883EF820883EF80000 +BC20:000000080008420842087E0E42087E08000800001F0801081F0810141F620000 +BC21:000000080008420842087E0E42087E08000800003EF802803EF820803EF80000 +BC22:000000080008420842087E0E42087E08000800003EFC02483E4820483EFC0000 +BC23:000000080008420842087E0E42087E08000800001F08017F1F1C10221F1C0000 +BC24:000000080008420842087E0E42087E080008000003F802080208020803F80000 +BC25:000000080008420842087E0E42087E08000800000208020803F8020803F80000 +BC26:000000080008420842087E0E42087E0800080000110811081F0811141F620000 +BC27:000000080008420842087E0E42087E0800080000001000100010006801840000 +BC28:000000080008420842087E0E42087E08000800000048004800A8011406620000 +BC29:000000080008420842087E0E42087E0800080000000003F00408040803F00000 +BC2A:000000080008420842087E0E42087E080008000003F80020002000D003080000 +BC2B:000000080008420842087E0E42087E0800080000004003F8004000A003180000 +BC2C:000000080008420842087E0E42087E080008000003F8000803F8000800080000 +BC2D:000000080008420842087E0E42087E080008000003F8020003F8020003F80000 +BC2E:000000080008420842087E0E42087E080008000000000FF8022002200FF80000 +BC2F:000000080008420842087E0E42087E080008000000800FF803E0041003E00000 +BC30:00000000001200122092209220923F9E2092209220923F920012001200120000 +BC31:000000280028422842287E3842287E280028000007F800080008000800080000 +BC32:000000280028422842287E3842287E280028000000003EF80208020802080000 +BC33:000000280028422842287E3842287E280028000000003E100210022802C40000 +BC34:000000280028422842287E3842287E280028002808000800080008000FF80000 +BC35:000000280028422842287E3842287E2800280000000020F8201020303ECC0000 +BC36:000000280028422842287E3842287E2800280000202021FC207020883E700000 +BC37:000000280028422842287E3842287E280028000003F802000200020003F80000 +BC38:000000280028422842287E3842287E280028000007F8000807F8040007F80000 +BC39:000000280028422842287E3842287E28002800003EF802083E0820083E080000 +BC3A:000000280028422842287E3842287E28002800003EF802883E8820883EF80000 +BC3B:000000280028422842287E3842287E28002800003E8802883EF820883EF80000 +BC3C:000000280028422842287E3842287E28002800001F0801081F0810141F620000 +BC3D:000000280028422842287E3842287E28002800003EF802803EF820803EF80000 +BC3E:000000280028422842287E3842287E28002800003EFC02483E4820483EFC0000 +BC3F:000000280028422842287E3842287E28002800003E1002FE3E3820443E380000 +BC40:000000280028422842287E3842287E280028000003F802080208020803F80000 +BC41:000000280028422842287E3842287E28002800000208020803F8020803F80000 +BC42:000000280028422842287E3842287E2800280000110811081F0811141F620000 +BC43:000000280028422842287E3842287E2800280000000800080008003400C20000 +BC44:000000280028422842287E3842287E28002800000048004800A8011406620000 +BC45:000000280028422842287E3842287E2800280000000001F00208020801F00000 +BC46:000000280028422842287E3842287E280028000003F80020002000D003080000 +BC47:000000280028422842287E3842287E2800280000004003F8004000A003180000 +BC48:000000280028422842287E3842287E280028000003F8000803F8000800080000 +BC49:000000280028422842287E3842287E280028000003F8020003F8020003F80000 +BC4A:000000280028422842287E3842287E280028000000000FF8022002200FF80000 +BC4B:000000280028422842287E3842287E280028000000800FF803E0041003E00000 +BC4C:000000000010001020902090209E3F902090209E20903F900010001000100000 +BC4D:0000000800084208420E7E08420E7E080008000007F800080008000800080000 +BC4E:0000000800084208420E7E08420E7E080008000000003EF80208020802080000 +BC4F:0000000800084208420E7E08420E7E080008000000001F080108011401620000 +BC50:0000000800084208420E7E08420E7E080008000008000800080008000FF80000 +BC51:0000000800084208420E7E08420E7E0800080000000010F8101010301ECC0000 +BC52:0000000800084208420E7E08420E7E08000800000808087F081C08220F9C0000 +BC53:0000000800084208420E7E08420E7E080008000003F802000200020003F80000 +BC54:0000000800084208420E7E08420E7E080008000007F8000807F8040007F80000 +BC55:0000000800084208420E7E08420E7E08000800003EF802083E0820083E080000 +BC56:0000000800084208420E7E08420E7E08000800003EF802883E8820883EF80000 +BC57:0000000800084208420E7E08420E7E08000800003E8802883EF820883EF80000 +BC58:0000000800084208420E7E08420E7E08000800001F0801081F0810141F620000 +BC59:0000000800084208420E7E08420E7E08000800003EF802803EF820803EF80000 +BC5A:0000000800084208420E7E08420E7E08000800003EFC02483E4820483EFC0000 +BC5B:0000000800084208420E7E08420E7E08000800001F08017F1F1C10221F1C0000 +BC5C:0000000800084208420E7E08420E7E080008000003F802080208020803F80000 +BC5D:0000000800084208420E7E08420E7E08000800000208020803F8020803F80000 +BC5E:0000000800084208420E7E08420E7E0800080000110811081F0811141F620000 +BC5F:0000000800084208420E7E08420E7E0800080000001000100010006801840000 +BC60:0000000800084208420E7E08420E7E08000800000048004800A8011406620000 +BC61:0000000800084208420E7E08420E7E0800080000000003F00408040803F00000 +BC62:0000000800084208420E7E08420E7E080008000003F80020002000D003080000 +BC63:0000000800084208420E7E08420E7E0800080000004003F8004000A003180000 +BC64:0000000800084208420E7E08420E7E080008000003F8000803F8000800080000 +BC65:0000000800084208420E7E08420E7E080008000003F8020003F8020003F80000 +BC66:0000000800084208420E7E08420E7E080008000000000FF8022002200FF80000 +BC67:0000000800084208420E7E08420E7E080008000000800FF803E0041003E00000 +BC68:000000000012001220922092209E3F922092209E20923F920012001200120000 +BC69:000000280028422842387E2842387E280028000007F800080008000800080000 +BC6A:000000280028422842387E2842387E280028000000003EF80208020802080000 +BC6B:000000280028422842387E2842387E280028000000003E100210022802C40000 +BC6C:000000280028422842387E2842387E280028002808000800080008000FF80000 +BC6D:000000280028422842387E2842387E2800280000000020F8201020303ECC0000 +BC6E:000000280028422842387E2842387E2800280000202021FC207020883E700000 +BC6F:000000280028422842387E2842387E280028000003F802000200020003F80000 +BC70:000000280028422842387E2842387E280028000007F8000807F8040007F80000 +BC71:000000280028422842387E2842387E28002800003EF802083E0820083E080000 +BC72:000000280028422842387E2842387E28002800003EF802883E8820883EF80000 +BC73:000000280028422842387E2842387E28002800003E8802883EF820883EF80000 +BC74:000000280028422842387E2842387E28002800001F0801081F0810141F620000 +BC75:000000280028422842387E2842387E28002800003EF802803EF820803EF80000 +BC76:000000280028422842387E2842387E28002800003EFC02483E4820483EFC0000 +BC77:000000280028422842387E2842387E28002800003E1002FE3E3820443E380000 +BC78:000000280028422842387E2842387E280028000003F802080208020803F80000 +BC79:000000280028422842387E2842387E28002800000208020803F8020803F80000 +BC7A:000000280028422842387E2842387E2800280000110811081F0811141F620000 +BC7B:000000280028422842387E2842387E2800280000000800080008003400C20000 +BC7C:000000280028422842387E2842387E28002800000048004800A8011406620000 +BC7D:000000280028422842387E2842387E2800280000000001F00208020801F00000 +BC7E:000000280028422842387E2842387E280028000003F80020002000D003080000 +BC7F:000000280028422842387E2842387E2800280000004003F8004000A003180000 +BC80:000000280028422842387E2842387E280028000003F8000803F8000800080000 +BC81:000000280028422842387E2842387E280028000003F8020003F8020003F80000 +BC82:000000280028422842387E2842387E280028000000000FF8022002200FF80000 +BC83:000000280028422842387E2842387E280028000000800FF803E0041003E00000 +BC84:00000000000200022082208220823F9E2082208220823F820002000200020000 +BC85:000000080008420842087E3842087E0800080000000007F80008000800080000 +BC86:000000080008420842087E3842087E080008000000003EF80208020802080000 +BC87:000000080008420842087E3842087E080008000000001F080108011401620000 +BC88:000000080008420842087E3842087E080008000000001000100010001FF80000 +BC89:000000080008420842087E3842087E0800080000000020F8201020303ECC0000 +BC8A:000000080008420842087E3842087E0800080000202021FC207020883E700000 +BC8B:000000080008420842087E3842087E080008000003F802000200020003F80000 +BC8C:000000080008420842087E3842087E080008000007F8000807F8040007F80000 +BC8D:000000080008420842087E3842087E08000800003EF802083E0820083E080000 +BC8E:000000080008420842087E3842087E08000800003EF802883E8820883EF80000 +BC8F:000000080008420842087E3842087E08000800003E8802883EF820883EF80000 +BC90:000000080008420842087E3842087E08000800000F8800880F8808140FA20000 +BC91:000000080008420842087E3842087E08000800003EF802803EF820803EF80000 +BC92:000000080008420842087E3842087E08000800003EFC02483E4820483EFC0000 +BC93:000000080008420842087E3842087E08000800003E1002FE3E3820443E380000 +BC94:000000080008420842087E3842087E080008000003F802080208020803F80000 +BC95:000000080008420842087E3842087E08000800000208020803F8020803F80000 +BC96:000000080008420842087E3842087E0800080000210821083F0821143F620000 +BC97:000000080008420842087E3842087E0800080000001000100010006801840000 +BC98:000000080008420842087E3842087E08000800000048004800A8011406620000 +BC99:000000080008420842087E3842087E0800080000000003F00408040803F00000 +BC9A:000000080008420842087E3842087E080008000003F80020002000D003080000 +BC9B:000000080008420842087E3842087E0800080000004003F8004000A003180000 +BC9C:000000080008420842087E3842087E080008000003F8000803F8000800080000 +BC9D:000000080008420842087E3842087E080008000003F8020003F8020003F80000 +BC9E:000000080008420842087E3842087E080008000000000FF8022002200FF80000 +BC9F:000000080008420842087E3842087E080008000000800FF803E0041003E00000 +BCA0:00000000000A000A208A208A208A3FBA208A208A208A3F8A000A000A000A0000 +BCA1:000000280028422842287EE842287E280028000007F800080008000800080000 +BCA2:000000280028422842287EE842287E280028000000003EF80208020802080000 +BCA3:000000280028422842287EE842287E280028000000003E100210022802C40000 +BCA4:000000280028422842287EE842287E280028000008000800080008000FF80000 +BCA5:000000280028422842287EE842287E2800280000000020F8201020303ECC0000 +BCA6:000000280028422842287EE842287E2800280000202021FC207020883E700000 +BCA7:000000280028422842287EE842287E280028000003F802000200020003F80000 +BCA8:000000280028422842287EE842287E280028000007F8000807F8040007F80000 +BCA9:000000280028422842287EE842287E28002800003EF802083E0820083E080000 +BCAA:000000280028422842287EE842287E28002800003EF802883E8820883EF80000 +BCAB:000000280028422842287EE842287E28002800003E8802883EF820883EF80000 +BCAC:000000280028422842287EE842287E28002800001F0801081F0810141F620000 +BCAD:000000280028422842287EE842287E28002800003EF802803EF820803EF80000 +BCAE:000000280028422842287EE842287E28002800003EFC02483E4820483EFC0000 +BCAF:000000280028422842287EE842287E28002800003E1002FE3E3820443E380000 +BCB0:000000280028422842287EE842287E280028000003F802080208020803F80000 +BCB1:000000280028422842287EE842287E28002800000208020803F8020803F80000 +BCB2:000000280028422842287EE842287E2800280000110811081F0811141F620000 +BCB3:000000280028422842287EE842287E2800280000000800080008003400C20000 +BCB4:000000280028422842287EE842287E28002800000048004800A8011406620000 +BCB5:000000280028422842287EE842287E2800280000000001F00208020801F00000 +BCB6:000000280028422842287EE842287E280028000003F80020002000D003080000 +BCB7:000000280028422842287EE842287E2800280000004003F8004000A003180000 +BCB8:000000280028422842287EE842287E280028000003F8000803F8000800080000 +BCB9:000000280028422842287EE842287E280028000003F8020003F8020003F80000 +BCBA:000000280028422842287EE842287E280028000000000FF8022002200FF80000 +BCBB:000000280028422842287EE842287E280028000000800FF803E0041003E00000 +BCBC:000000000002000220822082209E3F822082209E20823F820002000200020000 +BCBD:000000080008420842387E0842387E0800080000000007F80008000800080000 +BCBE:000000080008420842387E0842387E080008000000003EF80208020802080000 +BCBF:000000080008420842387E0842387E080008000000001F080108011401620000 +BCC0:000000080008420842387E0842387E080008000800001000100010001FF80000 +BCC1:000000080008420842387E0842387E0800080000000020F8201020303ECC0000 +BCC2:000000080008420842387E0842387E0800080000202021FC207020883E700000 +BCC3:000000080008420842387E0842387E080008000003F802000200020003F80000 +BCC4:000000080008420842387E0842387E080008000007F8000807F8040007F80000 +BCC5:000000080008420842387E0842387E08000800003EF802083E0820083E080000 +BCC6:000000080008420842387E0842387E08000800003EF802883E8820883EF80000 +BCC7:000000080008420842387E0842387E08000800003E8802883EF820883EF80000 +BCC8:000000080008420842387E0842387E08000800000F8800880F8808140FA20000 +BCC9:000000080008420842387E0842387E08000800003EF802803EF820803EF80000 +BCCA:000000080008420842387E0842387E08000800003EFC02483E4820483EFC0000 +BCCB:000000080008420842387E0842387E08000800003E1002FE3E3820443E380000 +BCCC:000000080008420842387E0842387E080008000003F802080208020803F80000 +BCCD:000000080008420842387E0842387E08000800000208020803F8020803F80000 +BCCE:000000080008420842387E0842387E0800080000210821083F0821143F620000 +BCCF:000000080008420842387E0842387E0800080000001000100010006801840000 +BCD0:000000080008420842387E0842387E08000800000048004800A8011406620000 +BCD1:000000080008420842387E0842387E0800080000000003F00408040803F00000 +BCD2:000000080008420842387E0842387E080008000003F80020002000D003080000 +BCD3:000000080008420842387E0842387E0800080000004003F8004000A003180000 +BCD4:000000080008420842387E0842387E080008000003F8000803F8000800080000 +BCD5:000000080008420842387E0842387E080008000003F8020003F8020003F80000 +BCD6:000000080008420842387E0842387E080008000000000FF8022002200FF80000 +BCD7:000000080008420842387E0842387E080008000000800FF803E0041003E00000 +BCD8:00000000000A000A208A208A20BA3F8A208A20BA208A3F8A000A000A000A0000 +BCD9:000000280028422842E87E2842E87E280028000007F800080008000800080000 +BCDA:000000280028422842E87E2842E87E280028000000003EF80208020802080000 +BCDB:000000280028422842E87E2842E87E280028000000003E100210022802C40000 +BCDC:000000280028422842E87E2842E87E280028002808000800080008000FF80000 +BCDD:000000280028422842E87E2842E87E2800280000000020F8201020303ECC0000 +BCDE:000000280028422842E87E2842E87E2800280000202021FC207020883E700000 +BCDF:000000280028422842E87E2842E87E280028000003F802000200020003F80000 +BCE0:000000280028422842E87E2842E87E280028000007F8000807F8040007F80000 +BCE1:000000280028422842E87E2842E87E28002800003EF802083E0820083E080000 +BCE2:000000280028422842E87E2842E87E28002800003EF802883E8820883EF80000 +BCE3:000000280028422842E87E2842E87E28002800003E8802883EF820883EF80000 +BCE4:000000280028422842E87E2842E87E28002800001F0801081F0810141F620000 +BCE5:000000280028422842E87E2842E87E28002800003EF802803EF820803EF80000 +BCE6:000000280028422842E87E2842E87E28002800003EFC02483E4820483EFC0000 +BCE7:000000280028422842E87E2842E87E28002800003E1002FE3E3820443E380000 +BCE8:000000280028422842E87E2842E87E280028000003F802080208020803F80000 +BCE9:000000280028422842E87E2842E87E28002800000208020803F8020803F80000 +BCEA:000000280028422842E87E2842E87E2800280000110811081F0811141F620000 +BCEB:000000280028422842E87E2842E87E2800280000000800080008003400C20000 +BCEC:000000280028422842E87E2842E87E28002800000048004800A8011406620000 +BCED:000000280028422842E87E2842E87E2800280000000001F00208020801F00000 +BCEE:000000280028422842E87E2842E87E280028000003F80020002000D003080000 +BCEF:000000280028422842E87E2842E87E2800280000004003F8004000A003180000 +BCF0:000000280028422842E87E2842E87E280028000003F8000803F8000800080000 +BCF1:000000280028422842E87E2842E87E280028000003F8020003F8020003F80000 +BCF2:000000280028422842E87E2842E87E280028000000000FF8022002200FF80000 +BCF3:000000280028422842E87E2842E87E280028000000800FF803E0041003E00000 +BCF4:000000001010101010101FF0101010101FF000000100010001007FFC00000000 +BCF5:0000101010101FF010101FF0010001007FFC00001FF000100010001000100000 +BCF6:0000101010101FF010101FF0010001007FFC000000003EF80208020802080000 +BCF7:0000101010101FF010101FF0010001007FFC000000001E100210022802C40000 +BCF8:0000101010101FF010101FF0010001007FFC000000001000100010001FF00000 +BCF9:0000101010101FF010101FF0010001007FFC0000000020F8201020303ECC0000 +BCFA:0000101010101FF010101FF0010001007FFC0000202021FC207020883E700000 +BCFB:0000101010101FF010101FF0010001007FFC00001FF01000100010001FF00000 +BCFC:0000101010101FF010101FF0010001007FFC00001FF000101FF010001FF00000 +BCFD:0000101010101FF010101FF0010001007FFC00003EF802083E0820083E080000 +BCFE:0000101010101FF010101FF0010001007FFC00003EF802883E8820883EF80000 +BCFF:0000101010101FF010101FF0010001007FFC00003E8802883EF820883EF80000 +BD00:0000101010101FF010101FF0010001007FFC00003E1002103E1020283EC40000 +BD01:0000101010101FF010101FF0010001007FFC00003EF802803EF820803EF80000 +BD02:0000101010101FF010101FF0010001007FFC00003EFC02483E4820483EFC0000 +BD03:0000101010101FF010101FF0010001007FFC00003E2003FC3E7020883E700000 +BD04:0000101010101FF010101FF0010001007FFC00001FF01010101010101FF00000 +BD05:0000101010101FF010101FF0010001007FFC0000101010101FF010101FF00000 +BD06:0000101010101FF010101FF0010001007FFC0000222022203E2022503E880000 +BD07:0000101010101FF010101FF0010001007FFC000000000100010002800C400000 +BD08:0000101010101FF010101FF0010001007FFC00000000024002400DA033100000 +BD09:0000101010101FF010101FF0010001007FFC0000000007C00820082007C00000 +BD0A:0000101010101FF010101FF0010001007FFC0000000007E00080014006200000 +BD0B:0000101010101FF010101FF0010001007FFC0000008007E00080014006200000 +BD0C:0000101010101FF010101FF0010001007FFC00001FF000101FF0001000100000 +BD0D:0000101010101FF010101FF0010001007FFC00001FF010001FF010001FF00000 +BD0E:0000101010101FF010101FF0010001007FFC000000001FF0044004401FF00000 +BD0F:0000101010101FF010101FF0010001007FFC000001001FF007C0082007C00000 +BD10:0000001000102090209020903F90209E20903F90041004107FD0001000100000 +BD11:00000008208820883F8E20883F8804087FE8000007F800080008000800080000 +BD12:00000008208820883F8E20883F8804087FE8000000003EF80208020802080000 +BD13:00000008208820883F8E20883F8804087FE8000000001F080108011401620000 +BD14:00000008208820883F8E20883F8804087FE8000008000800080008000FF80000 +BD15:00000008208820883F8E20883F8804087FE80000000010F8101010301ECC0000 +BD16:00000008208820883F8E20883F8804087FE800000808087F081C08220F9C0000 +BD17:00000008208820883F8E20883F8804087FE8000003F802000200020003F80000 +BD18:00000008208820883F8E20883F8804087FE8000007F8000807F8040007F80000 +BD19:00000008208820883F8E20883F8804087FE800003EF802083E0820083E080000 +BD1A:00000008208820883F8E20883F8804087FE800003EF802883E8820883EF80000 +BD1B:00000008208820883F8E20883F8804087FE800003E8802883EF820883EF80000 +BD1C:00000008208820883F8E20883F8804087FE800001F0801081F0810141F620000 +BD1D:00000008208820883F8E20883F8804087FE800003EF802803EF820803EF80000 +BD1E:00000008208820883F8E20883F8804087FE800003EFC02483E4820483EFC0000 +BD1F:00000008208820883F8E20883F8804087FE800001F08017F1F1C10221F1C0000 +BD20:00000008208820883F8E20883F8804087FE8000003F802080208020803F80000 +BD21:00000008208820883F8E20883F8804087FE800000208020803F8020803F80000 +BD22:00000008208820883F8E20883F8804087FE80000110811081F0811141F620000 +BD23:00000008208820883F8E20883F8804087FE80000001000100010006801840000 +BD24:00000008208820883F8E20883F8804087FE800000048004800A8011406620000 +BD25:00000008208820883F8E20883F8804087FE80000000003F00408040803F00000 +BD26:00000008208820883F8E20883F8804087FE8000003F80020002000D003080000 +BD27:00000008208820883F8E20883F8804087FE80000004003F8004000A003180000 +BD28:00000008208820883F8E20883F8804087FE8000003F8000803F8000800080000 +BD29:00000008208820883F8E20883F8804087FE8000003F8020003F8020003F80000 +BD2A:00000008208820883F8E20883F8804087FE8000000000FF8022002200FF80000 +BD2B:00000008208820883F8E20883F8804087FE8000000800FF803E0041003E00000 +BD2C:0000001200122092209220923F92209E20923F92041204127FD2001200120000 +BD2D:0000002820A820A83FB820A83FA804287FA8000007F800080008000800080000 +BD2E:0000002820A820A83FB820A83FA804287FA8000000003EF80208020802080000 +BD2F:0000002820A820A83FB820A83FA804287FA8000000001F080108011401620000 +BD30:0000002820A820A83FB820A83FA804287FA8000008000800080008000FF80000 +BD31:0000002820A820A83FB820A83FA804287FA80000000010F8101010301ECC0000 +BD32:0000002820A820A83FB820A83FA804287FA800000808087F081C08220F9C0000 +BD33:0000002820A820A83FB820A83FA804287FA8000003F802000200020003F80000 +BD34:0000002820A820A83FB820A83FA804287FA8000007F8000807F8040007F80000 +BD35:0000002820A820A83FB820A83FA804287FA800003EF802083E0820083E080000 +BD36:0000002820A820A83FB820A83FA804287FA800003EF802883E8820883EF80000 +BD37:0000002820A820A83FB820A83FA804287FA800003E8802883EF820883EF80000 +BD38:0000002820A820A83FB820A83FA804287FA800001F0801081F0810141F620000 +BD39:0000002820A820A83FB820A83FA804287FA800003EF802803EF820803EF80000 +BD3A:0000002820A820A83FB820A83FA804287FA800003EFC02483E4820483EFC0000 +BD3B:0000002820A820A83FB820A83FA804287FA800001F08017F1F1C10221F1C0000 +BD3C:0000002820A820A83FB820A83FA804287FA8000003F802080208020803F80000 +BD3D:0000002820A820A83FB820A83FA804287FA800000208020803F8020803F80000 +BD3E:0000002820A820A83FB820A83FA804287FA80000110811081F0811141F620000 +BD3F:0000002820A820A83FB820A83FA804287FA80000001000100010006801840000 +BD40:0000002820A820A83FB820A83FA804287FA800000048004800A8011406620000 +BD41:0000002820A820A83FB820A83FA804287FA80000000003F00408040803F00000 +BD42:0000002820A820A83FB820A83FA804287FA8000003F80020002000D003080000 +BD43:0000002820A820A83FB820A83FA804287FA80000004003F8004000A003180000 +BD44:0000002820A820A83FB820A83FA804287FA8000003F8000803F8000800080000 +BD45:0000002820A820A83FB820A83FA804287FA8000003F8020003F8020003F80000 +BD46:0000002820A820A83FB820A83FA804287FA8000000000FF8022002200FF80000 +BD47:0000002820A820A83FB820A83FA804287FA8000000800FF803E0041003E00000 +BD48:0000000800082088208820883F88208820883F88040804087FE8000800080000 +BD49:00000008208820883F8820883F8804087FE8000007F800080008000800080000 +BD4A:00000008208820883F8820883F8804087FE8000000003EF80208020802080000 +BD4B:00000008208820883F8820883F8804087FE8000000001F080108011401620000 +BD4C:00000008208820883F8820883F8804087FE8000008000800080008000FF80000 +BD4D:00000008208820883F8820883F8804087FE80000000010F8101010301ECC0000 +BD4E:00000008208820883F8820883F8804087FE800000808087F081C08220F9C0000 +BD4F:00000008208820883F8820883F8804087FE8000003F802000200020003F80000 +BD50:00000008208820883F8820883F8804087FE8000007F8000807F8040007F80000 +BD51:00000008208820883F8820883F8804087FE800003EF802083E0820083E080000 +BD52:00000008208820883F8820883F8804087FE800003EF802883E8820883EF80000 +BD53:00000008208820883F8820883F8804087FE800003E8802883EF820883EF80000 +BD54:00000008208820883F8820883F8804087FE800001F0801081F0810141F620000 +BD55:00000008208820883F8820883F8804087FE800003EF802803EF820803EF80000 +BD56:00000008208820883F8820883F8804087FE800003EFC02483E4820483EFC0000 +BD57:00000008208820883F8820883F8804087FE800001F08017F1F1C10221F1C0000 +BD58:00000008208820883F8820883F8804087FE8000003F802080208020803F80000 +BD59:00000008208820883F8820883F8804087FE800000208020803F8020803F80000 +BD5A:00000008208820883F8820883F8804087FE80000110811081F0811141F620000 +BD5B:00000008208820883F8820883F8804087FE80000001000100010006801840000 +BD5C:00000008208820883F8820883F8804087FE800000048004800A8011406620000 +BD5D:00000008208820883F8820883F8804087FE80000000003F00408040803F00000 +BD5E:00000008208820883F8820883F8804087FE8000003F80020002000D003080000 +BD5F:00000008208820883F8820883F8804087FE80000004003F8004000A003180000 +BD60:00000008208820883F8820883F8804087FE8000003F8000803F8000800080000 +BD61:00000008208820883F8820883F8804087FE8000003F8020003F8020003F80000 +BD62:00000008208820883F8820883F8804087FE8000000000FF8022002200FF80000 +BD63:00000008208820883F8820883F8804087FE8000000800FF803E0041003E00000 +BD64:000000001010101010101FF0101010101FF004400440044004407FFC00000000 +BD65:0000101010101FF010101FF0044004407FFC00001FF000100010001000100000 +BD66:0000101010101FF010101FF0044004407FFC000000003EF80208020802080000 +BD67:0000101010101FF010101FF0044004407FFC000000001E100210022802C40000 +BD68:0000101010101FF010101FF0044004407FFC000000001000100010001FF00000 +BD69:0000101010101FF010101FF0044004407FFC0000000020F8201020303ECC0000 +BD6A:0000101010101FF010101FF0044004407FFC0000202021FC207020883E700000 +BD6B:0000101010101FF010101FF0044004407FFC00001FF01000100010001FF00000 +BD6C:0000101010101FF010101FF0044004407FFC00001FF000101FF010001FF00000 +BD6D:0000101010101FF010101FF0044004407FFC00003EF802083E0820083E080000 +BD6E:0000101010101FF010101FF0044004407FFC00003EF802883E8820883EF80000 +BD6F:0000101010101FF010101FF0044004407FFC00003E8802883EF820883EF80000 +BD70:0000101010101FF010101FF0044004407FFC00003E1002103E1020283EC40000 +BD71:0000101010101FF010101FF0044004407FFC00003EF802803EF820803EF80000 +BD72:0000101010101FF010101FF0044004407FFC00003EFC02483E4820483EFC0000 +BD73:0000101010101FF010101FF0044004407FFC00003E2003FC3E7020883E700000 +BD74:0000101010101FF010101FF0044004407FFC00001FF01010101010101FF00000 +BD75:0000101010101FF010101FF0044004407FFC0000101010101FF010101FF00000 +BD76:0000101010101FF010101FF0044004407FFC0000222022203E2022503E880000 +BD77:0000101010101FF010101FF0044004407FFC000000000100010002800C400000 +BD78:0000101010101FF010101FF0044004407FFC00000000024002400DA033100000 +BD79:0000101010101FF010101FF0044004407FFC0000000007C00820082007C00000 +BD7A:0000101010101FF010101FF0044004407FFC0000000007E00080014006200000 +BD7B:0000101010101FF010101FF0044004407FFC0000008007E00080014006200000 +BD7C:0000101010101FF010101FF0044004407FFC00001FF000101FF0001000100000 +BD7D:0000101010101FF010101FF0044004407FFC00001FF010001FF010001FF00000 +BD7E:0000101010101FF010101FF0044004407FFC000000001FF0044004401FF00000 +BD7F:0000101010101FF010101FF0044004407FFC000001001FF007C0082007C00000 +BD80:000000001010101010101FF0101010101FF000003FF801000100010001000000 +BD81:0000101010101FF010101FF000007FFC010001001FF000100010001000100000 +BD82:0000101010101FF010101FF000007FFC0100010000003EF80208020802080000 +BD83:0000101010101FF010101FF000007FFC0100010000001E100210022802C40000 +BD84:0000101010101FF010101FF0000000007FFC010001001100100010001FF00000 +BD85:0000101010101FF010101FF000007FFC01000100000020F8201020303ECC0000 +BD86:0000101010101FF010101FF000007FFC01000100202021FC207020883E700000 +BD87:0000101010101FF010101FF000007FFC010001001FF01000100010001FF00000 +BD88:0000101010101FF010101FF000007FFC010001001FF000101FF010001FF00000 +BD89:0000101010101FF010101FF000007FFC010001003EF802083E0820083E080000 +BD8A:0000101010101FF010101FF000007FFC010001003EF802883E8820883EF80000 +BD8B:0000101010101FF010101FF000007FFC010001003E8802883EF820883EF80000 +BD8C:0000101010101FF010101FF000007FFC010001003E1002103E1020283EC40000 +BD8D:0000101010101FF010101FF000007FFC010001003EF802803EF820803EF80000 +BD8E:0000101010101FF010101FF000007FFC010001003EFC02483E4820483EFC0000 +BD8F:0000101010101FF010101FF000007FFC010001003E2003FC3E7020883E700000 +BD90:0000101010101FF010101FF000007FFC010001001FF01010101010101FF00000 +BD91:0000101010101FF010101FF000007FFC01000100101010101FF010101FF00000 +BD92:0000101010101FF010101FF000007FFC01000100222022203E2022503E880000 +BD93:0000101010101FF010101FF000007FFC0100010000000100010002800C400000 +BD94:0000101010101FF010101FF000007FFC010001000000024002400DA033100000 +BD95:0000101010101FF010101FF000007FFC01000100000007C00820082007C00000 +BD96:0000101010101FF010101FF000007FFC01000100000007E00080014006200000 +BD97:0000101010101FF010101FF000007FFC01000100008007E00080014006200000 +BD98:0000101010101FF010101FF000007FFC010001001FF000101FF0001000100000 +BD99:0000101010101FF010101FF000007FFC010001001FF010001FF010001FF00000 +BD9A:0000101010101FF010101FF000007FFC0100010000001FF0044004401FF00000 +BD9B:0000101010101FF010101FF000007FFC0100010001001FF007C0082007C00000 +BD9C:000000082088208820883F88208820883F8800087FE8040804F8040804080000 +BD9D:208820883F8820883F8800087FE8027802080000000007F80008000800080000 +BD9E:208820883F8820883F8800087FE802780208000000003EF80208020802080000 +BD9F:208820883F8820883F8800087FE802780208000000001F080108011401620000 +BDA0:208820883F8820883F88000800087FE80278020802081000100010001FF80000 +BDA1:208820883F8820883F8800087FE8027802080000000020F8201020303ECC0000 +BDA2:208820883F8820883F8800087FE8027802080000202021FC207020883E700000 +BDA3:208820883F8820883F8800087FE802780208000003F802000200020003F80000 +BDA4:208820883F8820883F8800087FE802780208000007F8000807F8040007F80000 +BDA5:208820883F8820883F8800087FE80278020800003EF802083E0820083E080000 +BDA6:208820883F8820883F8800087FE80278020800003EF802883E8820883EF80000 +BDA7:208820883F8820883F8800087FE80278020800003E8802883EF820883EF80000 +BDA8:208820883F8820883F8800087FE80278020800000F8800880F8808140FA20000 +BDA9:208820883F8820883F8800087FE80278020800003EF802803EF820803EF80000 +BDAA:208820883F8820883F8800087FE80278020800003EFC02483E4820483EFC0000 +BDAB:208820883F8820883F8800087FE80278020800003E1002FE3E3820443E380000 +BDAC:208820883F8820883F8800087FE802780208000003F802080208020803F80000 +BDAD:208820883F8820883F8800087FE80278020800000208020803F8020803F80000 +BDAE:208820883F8820883F8800087FE8027802080000210821083F0821143F620000 +BDAF:208820883F8820883F8800087FE8027802080000001000100010006801840000 +BDB0:208820883F8820883F8800087FE80278020800000048004800A8011406620000 +BDB1:208820883F8820883F8800087FE8027802080000000003F00408040803F00000 +BDB2:208820883F8820883F8800087FE802780208000003F80020002000D003080000 +BDB3:208820883F8820883F8800087FE8027802080000004003F8004000A003180000 +BDB4:208820883F8820883F8800087FE802780208000003F8000803F8000800080000 +BDB5:208820883F8820883F8800087FE802780208000003F8020003F8020003F80000 +BDB6:208820883F8820883F8800087FE802780208000000000FF8022002200FF80000 +BDB7:208820883F8820883F8800087FE802780208000000800FF803E0041003E00000 +BDB8:0000000A208A208A208A3F8A208A208A3F8A000A7FEA040A047A040A040A0000 +BDB9:20A820A83FA820A83FA800287FA805E804280000000007F80008000800080000 +BDBA:20A820A83FA820A83FA800287FA805E80428000000003EF80208020802080000 +BDBB:20A820A83FA820A83FA800287FA805E80428000000001F080108011401620000 +BDBC:20A820A83FA820A83FA8002800287FA8042805E804281428100010001FF80000 +BDBD:20A820A83FA820A83FA800287FA805E804280000000020F8201020303ECC0000 +BDBE:20A820A83FA820A83FA800287FA805E804280000202021FC207020883E700000 +BDBF:20A820A83FA820A83FA800287FA805E80428000003F802000200020003F80000 +BDC0:20A820A83FA820A83FA800287FA805E80428000007F8000807F8040007F80000 +BDC1:20A820A83FA820A83FA800287FA805E8042800003EF802083E0820083E080000 +BDC2:20A820A83FA820A83FA800287FA805E8042800003EF802883E8820883EF80000 +BDC3:20A820A83FA820A83FA800287FA805E8042800003E8802883EF820883EF80000 +BDC4:20A820A83FA820A83FA800287FA805E8042800000F8800880F8808140FA20000 +BDC5:20A820A83FA820A83FA800287FA805E8042800003EF802803EF820803EF80000 +BDC6:20A820A83FA820A83FA800287FA805E8042800003EFC02483E4820483EFC0000 +BDC7:20A820A83FA820A83FA800287FA805E8042800003E1002FE3E3820443E380000 +BDC8:20A820A83FA820A83FA800287FA805E80428000003F802080208020803F80000 +BDC9:20A820A83FA820A83FA800287FA805E8042800000208020803F8020803F80000 +BDCA:20A820A83FA820A83FA800287FA805E804280000210821083F0821143F620000 +BDCB:20A820A83FA820A83FA800287FA805E804280000001000100010006801840000 +BDCC:20A820A83FA820A83FA800287FA805E8042800000048004800A8011406620000 +BDCD:20A820A83FA820A83FA800287FA805E804280000000003F00408040803F00000 +BDCE:20A820A83FA820A83FA800287FA805E80428000003F80020002000D003080000 +BDCF:20A820A83FA820A83FA800287FA805E804280000004003F8004000A003180000 +BDD0:20A820A83FA820A83FA800287FA805E80428000003F8000803F8000800080000 +BDD1:20A820A83FA820A83FA800287FA805E80428000003F8020003F8020003F80000 +BDD2:20A820A83FA820A83FA800287FA805E80428000000000FF8022002200FF80000 +BDD3:20A820A83FA820A83FA800287FA805E80428000000800FF803E0041003E00000 +BDD4:000000082088208820883F88208820883F8800087FE804080408040804080000 +BDD5:208820883F8820883F8800087FE8020802000000000007F80008000800080000 +BDD6:208820883F8820883F8800087FE802080200000000003EF80208020802080000 +BDD7:208820883F8820883F8800087FE802080200000000001F080108011401620000 +BDD8:208820883F8820883F88000800087FE80208020802081008100010001FF80000 +BDD9:208820883F8820883F8800087FE8020802000000000020F8201020303ECC0000 +BDDA:208820883F8820883F8800087FE8020802000000202021FC207020883E700000 +BDDB:208820883F8820883F8800087FE802080200000003F802000200020003F80000 +BDDC:208820883F8820883F8800087FE802080200000007F8000807F8040007F80000 +BDDD:208820883F8820883F8800087FE80208020000003EF802083E0820083E080000 +BDDE:208820883F8820883F8800087FE80208020000003EF802883E8820883EF80000 +BDDF:208820883F8820883F8800087FE80208020000003E8802883EF820883EF80000 +BDE0:208820883F8820883F8800087FE80208020000000F8800880F8808140FA20000 +BDE1:208820883F8820883F8800087FE80208020000003EF802803EF820803EF80000 +BDE2:208820883F8820883F8800087FE80208020000003EFC02483E4820483EFC0000 +BDE3:208820883F8820883F8800087FE80208020000003E1002FE3E3820443E380000 +BDE4:208820883F8820883F8800087FE802080200000003F802080208020803F80000 +BDE5:208820883F8820883F8800087FE80208020000000208020803F8020803F80000 +BDE6:208820883F8820883F8800087FE8020802000000210821083F0821143F620000 +BDE7:208820883F8820883F8800087FE8020802000000001000100010006801840000 +BDE8:208820883F8820883F8800087FE80208020000000048004800A8011406620000 +BDE9:208820883F8820883F8800087FE8020802000000000003F00408040803F00000 +BDEA:208820883F8820883F8800087FE802080200000003F80020002000D003080000 +BDEB:208820883F8820883F8800087FE8020802000000004003F8004000A003180000 +BDEC:208820883F8820883F8800087FE802080200000003F8000803F8000800080000 +BDED:208820883F8820883F8800087FE802080200000003F8020003F8020003F80000 +BDEE:208820883F8820883F8800087FE802080200000000000FF8022002200FF80000 +BDEF:208820883F8820883F8800087FE802080200000000800FF803E0041003E00000 +BDF0:000000001010101010101FF0101010101FF000007FFC04400440044004400000 +BDF1:0000101010101FF010101FF000007FFC044004401FF000100010001000100000 +BDF2:0000101010101FF010101FF000007FFC0440044000003EF80208020802080000 +BDF3:0000101010101FF010101FF000007FFC0440044000001E100210022802C40000 +BDF4:0000101010101FF010101FF0000000007FFC044004401440100010001FF00000 +BDF5:0000101010101FF010101FF000007FFC04400440000020F8201020303ECC0000 +BDF6:0000101010101FF010101FF000007FFC04400440202021FC207020883E700000 +BDF7:0000101010101FF010101FF000007FFC044004401FF01000100010001FF00000 +BDF8:0000101010101FF010101FF000007FFC044004401FF000101FF010001FF00000 +BDF9:0000101010101FF010101FF000007FFC044004403EF802083E0820083E080000 +BDFA:0000101010101FF010101FF000007FFC044004403EF802883E8820883EF80000 +BDFB:0000101010101FF010101FF000007FFC044004403E8802883EF820883EF80000 +BDFC:0000101010101FF010101FF000007FFC044004403E1002103E1020283EC40000 +BDFD:0000101010101FF010101FF000007FFC044004403EF802803EF820803EF80000 +BDFE:0000101010101FF010101FF000007FFC044004403EFC02483E4820483EFC0000 +BDFF:0000101010101FF010101FF000007FFC044004403E2003FC3E7020883E700000 +BE00:0000101010101FF010101FF000007FFC044004401FF01010101010101FF00000 +BE01:0000101010101FF010101FF000007FFC04400440101010101FF010101FF00000 +BE02:0000101010101FF010101FF000007FFC04400440222022203E2022503E880000 +BE03:0000101010101FF010101FF000007FFC0440044000000100010002800C400000 +BE04:0000101010101FF010101FF000007FFC044004400000024002400DA033100000 +BE05:0000101010101FF010101FF000007FFC04400440000007C00820082007C00000 +BE06:0000101010101FF010101FF000007FFC04400440000007E00080014006200000 +BE07:0000101010101FF010101FF000007FFC04400440008007E00080014006200000 +BE08:0000101010101FF010101FF000007FFC044004401FF000101FF0001000100000 +BE09:0000101010101FF010101FF000007FFC044004401FF010001FF010001FF00000 +BE0A:0000101010101FF010101FF000007FFC0440044000001FF0044004401FF00000 +BE0B:0000101010101FF010101FF000007FFC0440044001001FF007C0082007C00000 +BE0C:000000001010101010101FF0101010101FF0000000007FFC0000000000000000 +BE0D:0000101010101FF010101FF0000000007FFC00001FF000100010001000100000 +BE0E:0000101010101FF010101FF0000000007FFC000000003EF80208020802080000 +BE0F:0000101010101FF010101FF0000000007FFC000000001E100210022802C40000 +BE10:0000101010101FF010101FF0000000007FFC000000001000100010001FF00000 +BE11:0000101010101FF010101FF0000000007FFC0000000020F8201020303ECC0000 +BE12:0000101010101FF010101FF0000000007FFC0000202021FC207020883E700000 +BE13:0000101010101FF010101FF0000000007FFC00001FF01000100010001FF00000 +BE14:0000101010101FF010101FF0000000007FFC00001FF000101FF010001FF00000 +BE15:0000101010101FF010101FF0000000007FFC00003EF802083E0820083E080000 +BE16:0000101010101FF010101FF0000000007FFC00003EF802883E8820883EF80000 +BE17:0000101010101FF010101FF0000000007FFC00003E8802883EF820883EF80000 +BE18:0000101010101FF010101FF0000000007FFC00003E1002103E1020283EC40000 +BE19:0000101010101FF010101FF0000000007FFC00003EF802803EF820803EF80000 +BE1A:0000101010101FF010101FF0000000007FFC00003EFC02483E4820483EFC0000 +BE1B:0000101010101FF010101FF0000000007FFC00003E2003FC3E7020883E700000 +BE1C:0000101010101FF010101FF0000000007FFC00001FF01010101010101FF00000 +BE1D:0000101010101FF010101FF0000000007FFC0000101010101FF010101FF00000 +BE1E:0000101010101FF010101FF0000000007FFC0000222022203E2022503E880000 +BE1F:0000101010101FF010101FF0000000007FFC000000000100010002800C400000 +BE20:0000101010101FF010101FF0000000007FFC00000000024002400DA033100000 +BE21:0000101010101FF010101FF0000000007FFC0000000007C00820082007C00000 +BE22:0000101010101FF010101FF0000000007FFC0000000007E00080014006200000 +BE23:0000101010101FF010101FF0000000007FFC0000008007E00080014006200000 +BE24:0000101010101FF010101FF0000000007FFC00001FF000101FF0001000100000 +BE25:0000101010101FF010101FF0000000007FFC00001FF010001FF010001FF00000 +BE26:0000101010101FF010101FF0000000007FFC000000001FF0044004401FF00000 +BE27:0000101010101FF010101FF0000000007FFC000001001FF007C0082007C00000 +BE28:0000000800082088208820883F88208820883F8800087FE80008000800080000 +BE29:00000008208820883F8820883F8800087FE8000007F800080008000800080000 +BE2A:00000008208820883F8820883F8800087FE8000000003EF80208020802080000 +BE2B:00000008208820883F8820883F8800087FE8000000001F080108011401620000 +BE2C:00000008208820883F8820883F8800087FE8000008000800080008000FF80000 +BE2D:00000008208820883F8820883F8800087FE80000000010F8101010301ECC0000 +BE2E:00000008208820883F8820883F8800087FE800000808087F081C08220F9C0000 +BE2F:00000008208820883F8820883F8800087FE8000003F802000200020003F80000 +BE30:00000008208820883F8820883F8800087FE8000007F8000807F8040007F80000 +BE31:00000008208820883F8820883F8800087FE800003EF802083E0820083E080000 +BE32:00000008208820883F8820883F8800087FE800003EF802883E8820883EF80000 +BE33:00000008208820883F8820883F8800087FE800003E8802883EF820883EF80000 +BE34:00000008208820883F8820883F8800087FE800001F0801081F0810141F620000 +BE35:00000008208820883F8820883F8800087FE800003EF802803EF820803EF80000 +BE36:00000008208820883F8820883F8800087FE800003EFC02483E4820483EFC0000 +BE37:00000008208820883F8820883F8800087FE800001F08017F1F1C10221F1C0000 +BE38:00000008208820883F8820883F8800087FE8000003F802080208020803F80000 +BE39:00000008208820883F8820883F8800087FE800000208020803F8020803F80000 +BE3A:00000008208820883F8820883F8800087FE80000110811081F0811141F620000 +BE3B:00000008208820883F8820883F8800087FE80000001000100010006801840000 +BE3C:00000008208820883F8820883F8800087FE800000048004800A8011406620000 +BE3D:00000008208820883F8820883F8800087FE80000000003F00408040803F00000 +BE3E:00000008208820883F8820883F8800087FE8000003F80020002000D003080000 +BE3F:00000008208820883F8820883F8800087FE80000004003F8004000A003180000 +BE40:00000008208820883F8820883F8800087FE8000003F8000803F8000800080000 +BE41:00000008208820883F8820883F8800087FE8000003F8020003F8020003F80000 +BE42:00000008208820883F8820883F8800087FE8000000000FF8022002200FF80000 +BE43:00000008208820883F8820883F8800087FE8000000800FF803E0041003E00000 +BE44:00000000000800082088208820883F882088208820883F880008000800080000 +BE45:000000080008420842087E0842087E0800080000000007F80008000800080000 +BE46:000000080008420842087E0842087E080008000000003EF80208020802080000 +BE47:000000080008420842087E0842087E080008000000001F080108011401620000 +BE48:000000080008420842087E0842087E080008000800001000100010001FF80000 +BE49:000000080008420842087E0842087E0800080000000020F8201020303ECC0000 +BE4A:000000080008420842087E0842087E0800080000202021FC207020883E700000 +BE4B:000000080008420842087E0842087E080008000003F802000200020003F80000 +BE4C:000000080008420842087E0842087E080008000007F8000807F8040007F80000 +BE4D:000000080008420842087E0842087E08000800003EF802083E0820083E080000 +BE4E:000000080008420842087E0842087E08000800003EF802883E8820883EF80000 +BE4F:000000080008420842087E0842087E08000800003E8802883EF820883EF80000 +BE50:000000080008420842087E0842087E08000800000F8800880F8808140FA20000 +BE51:000000080008420842087E0842087E08000800003EF802803EF820803EF80000 +BE52:000000080008420842087E0842087E08000800003EFC02483E4820483EFC0000 +BE53:000000080008420842087E0842087E08000800003E1002FE3E3820443E380000 +BE54:000000080008420842087E0842087E080008000003F802080208020803F80000 +BE55:000000080008420842087E0842087E08000800000208020803F8020803F80000 +BE56:000000080008420842087E0842087E0800080000210821083F0821143F620000 +BE57:000000080008420842087E0842087E0800080000001000100010006801840000 +BE58:000000080008420842087E0842087E08000800000048004800A8011406620000 +BE59:000000080008420842087E0842087E0800080000000003F00408040803F00000 +BE5A:000000080008420842087E0842087E080008000003F80020002000D003080000 +BE5B:000000080008420842087E0842087E0800080000004003F8004000A003180000 +BE5C:000000080008420842087E0842087E080008000003F8000803F8000800080000 +BE5D:000000080008420842087E0842087E080008000003F8020003F8020003F80000 +BE5E:000000080008420842087E0842087E080008000000000FF8022002200FF80000 +BE5F:000000080008420842087E0842087E080008000000800FF803E0041003E00000 +BE60:00000000001000102490249024903F9E249024903F9000100010001000100000 +BE61:000000084908490849087F0E49087F080008000007F800080008000800080000 +BE62:000000084908490849087F0E49087F080008000000003EF80208020802080000 +BE63:000000084908490849087F0E49087F080008000000001F080108011401620000 +BE64:000000084908490849087F0E49087F080008000808000800080008000FF80000 +BE65:000000084908490849087F0E49087F0800080000000010F8101010301ECC0000 +BE66:000000084908490849087F0E49087F08000800000808087F081C08220F9C0000 +BE67:000000084908490849087F0E49087F080008000003F802000200020003F80000 +BE68:000000084908490849087F0E49087F080008000007F8000807F8040007F80000 +BE69:000000084908490849087F0E49087F08000800003EF802083E0820083E080000 +BE6A:000000084908490849087F0E49087F08000800003EF802883E8820883EF80000 +BE6B:000000084908490849087F0E49087F08000800003E8802883EF820883EF80000 +BE6C:000000084908490849087F0E49087F08000800001F0801081F0810141F620000 +BE6D:000000084908490849087F0E49087F08000800003EF802803EF820803EF80000 +BE6E:000000084908490849087F0E49087F08000800003EFC02483E4820483EFC0000 +BE6F:000000084908490849087F0E49087F08000800001F08017F1F1C10221F1C0000 +BE70:000000084908490849087F0E49087F080008000003F802080208020803F80000 +BE71:000000084908490849087F0E49087F08000800000208020803F8020803F80000 +BE72:000000084908490849087F0E49087F0800080000110811081F0811141F620000 +BE73:000000084908490849087F0E49087F0800080000001000100010006801840000 +BE74:000000084908490849087F0E49087F08000800000048004800A8011406620000 +BE75:000000084908490849087F0E49087F0800080000000003F00408040803F00000 +BE76:000000084908490849087F0E49087F080008000003F80020002000D003080000 +BE77:000000084908490849087F0E49087F0800080000004003F8004000A003180000 +BE78:000000084908490849087F0E49087F080008000003F8000803F8000800080000 +BE79:000000084908490849087F0E49087F080008000003F8020003F8020003F80000 +BE7A:000000084908490849087F0E49087F080008000000000FF8022002200FF80000 +BE7B:000000084908490849087F0E49087F080008000000800FF803E0041003E00000 +BE7C:00000000001200122492249224923F9E249224923F9200120012001200120000 +BE7D:000000284928492849287F3849287F280028000007F800080008000800080000 +BE7E:000000284928492849287F3849287F280028000000003EF80208020802080000 +BE7F:000000284928492849287F3849287F280028000000003E100210022802C40000 +BE80:000000284928492849287F3849287F280028002808000800080008000FF80000 +BE81:000000284928492849287F3849287F2800280000000020F8201020303ECC0000 +BE82:000000284928492849287F3849287F2800280000202021FC207020883E700000 +BE83:000000284928492849287F3849287F280028000003F802000200020003F80000 +BE84:000000284928492849287F3849287F280028000007F8000807F8040007F80000 +BE85:000000284928492849287F3849287F28002800003EF802083E0820083E080000 +BE86:000000284928492849287F3849287F28002800003EF802883E8820883EF80000 +BE87:000000284928492849287F3849287F28002800003E8802883EF820883EF80000 +BE88:000000284928492849287F3849287F28002800001F0801081F0810141F620000 +BE89:000000284928492849287F3849287F28002800003EF802803EF820803EF80000 +BE8A:000000284928492849287F3849287F28002800003EFC02483E4820483EFC0000 +BE8B:000000284928492849287F3849287F28002800003E1002FE3E3820443E380000 +BE8C:000000284928492849287F3849287F280028000003F802080208020803F80000 +BE8D:000000284928492849287F3849287F28002800000208020803F8020803F80000 +BE8E:000000284928492849287F3849287F2800280000110811081F0811141F620000 +BE8F:000000284928492849287F3849287F2800280000000800080008003400C20000 +BE90:000000284928492849287F3849287F28002800000048004800A8011406620000 +BE91:000000284928492849287F3849287F2800280000000001F00208020801F00000 +BE92:000000284928492849287F3849287F280028000003F80020002000D003080000 +BE93:000000284928492849287F3849287F2800280000004003F8004000A003180000 +BE94:000000284928492849287F3849287F280028000003F8000803F8000800080000 +BE95:000000284928492849287F3849287F280028000003F8020003F8020003F80000 +BE96:000000284928492849287F3849287F280028000000000FF8022002200FF80000 +BE97:000000284928492849287F3849287F280028000000800FF803E0041003E00000 +BE98:000000000010001024902490249E3F902490249E3F9000100010001000100000 +BE99:0000000849084908490E7F08490E7F080008000007F800080008000800080000 +BE9A:0000000849084908490E7F08490E7F080008000000003EF80208020802080000 +BE9B:0000000849084908490E7F08490E7F080008000000001F080108011401620000 +BE9C:0000000849084908490E7F08490E7F080008000008000800080008000FF80000 +BE9D:0000000849084908490E7F08490E7F0800080000000010F8101010301ECC0000 +BE9E:0000000849084908490E7F08490E7F08000800000808087F081C08220F9C0000 +BE9F:0000000849084908490E7F08490E7F080008000003F802000200020003F80000 +BEA0:0000000849084908490E7F08490E7F080008000007F8000807F8040007F80000 +BEA1:0000000849084908490E7F08490E7F08000800003EF802083E0820083E080000 +BEA2:0000000849084908490E7F08490E7F08000800003EF802883E8820883EF80000 +BEA3:0000000849084908490E7F08490E7F08000800003E8802883EF820883EF80000 +BEA4:0000000849084908490E7F08490E7F08000800001F0801081F0810141F620000 +BEA5:0000000849084908490E7F08490E7F08000800003EF802803EF820803EF80000 +BEA6:0000000849084908490E7F08490E7F08000800003EFC02483E4820483EFC0000 +BEA7:0000000849084908490E7F08490E7F08000800001F08017F1F1C10221F1C0000 +BEA8:0000000849084908490E7F08490E7F080008000003F802080208020803F80000 +BEA9:0000000849084908490E7F08490E7F08000800000208020803F8020803F80000 +BEAA:0000000849084908490E7F08490E7F0800080000110811081F0811141F620000 +BEAB:0000000849084908490E7F08490E7F0800080000001000100010006801840000 +BEAC:0000000849084908490E7F08490E7F08000800000048004800A8011406620000 +BEAD:0000000849084908490E7F08490E7F0800080000000003F00408040803F00000 +BEAE:0000000849084908490E7F08490E7F080008000003F80020002000D003080000 +BEAF:0000000849084908490E7F08490E7F0800080000004003F8004000A003180000 +BEB0:0000000849084908490E7F08490E7F080008000003F8000803F8000800080000 +BEB1:0000000849084908490E7F08490E7F080008000003F8020003F8020003F80000 +BEB2:0000000849084908490E7F08490E7F080008000000000FF8022002200FF80000 +BEB3:0000000849084908490E7F08490E7F080008000000800FF803E0041003E00000 +BEB4:000000000012001224922492249E3F922492249E3F9200120012001200120000 +BEB5:000000284928492849387F2849387F280028000007F800080008000800080000 +BEB6:000000284928492849387F2849387F280028000000003EF80208020802080000 +BEB7:000000284928492849387F2849387F280028000000003E100210022802C40000 +BEB8:000000284928492849387F2849387F280028002808000800080008000FF80000 +BEB9:000000284928492849387F2849387F2800280000000020F8201020303ECC0000 +BEBA:000000284928492849387F2849387F2800280000202021FC207020883E700000 +BEBB:000000284928492849387F2849387F280028000003F802000200020003F80000 +BEBC:000000284928492849387F2849387F280028000007F8000807F8040007F80000 +BEBD:000000284928492849387F2849387F28002800003EF802083E0820083E080000 +BEBE:000000284928492849387F2849387F28002800003EF802883E8820883EF80000 +BEBF:000000284928492849387F2849387F28002800003E8802883EF820883EF80000 +BEC0:000000284928492849387F2849387F28002800001F0801081F0810141F620000 +BEC1:000000284928492849387F2849387F28002800003EF802803EF820803EF80000 +BEC2:000000284928492849387F2849387F28002800003EFC02483E4820483EFC0000 +BEC3:000000284928492849387F2849387F28002800003E1002FE3E3820443E380000 +BEC4:000000284928492849387F2849387F280028000003F802080208020803F80000 +BEC5:000000284928492849387F2849387F28002800000208020803F8020803F80000 +BEC6:000000284928492849387F2849387F2800280000110811081F0811141F620000 +BEC7:000000284928492849387F2849387F2800280000000800080008003400C20000 +BEC8:000000284928492849387F2849387F28002800000048004800A8011406620000 +BEC9:000000284928492849387F2849387F2800280000000001F00208020801F00000 +BECA:000000284928492849387F2849387F280028000003F80020002000D003080000 +BECB:000000284928492849387F2849387F2800280000004003F8004000A003180000 +BECC:000000284928492849387F2849387F280028000003F8000803F8000800080000 +BECD:000000284928492849387F2849387F280028000003F8020003F8020003F80000 +BECE:000000284928492849387F2849387F280028000000000FF8022002200FF80000 +BECF:000000284928492849387F2849387F280028000000800FF803E0041003E00000 +BED0:00000000000200022482248224823F9E248224823F8200020002000200020000 +BED1:000000084908490849087F3849087F0800080000000007F80008000800080000 +BED2:000000084908490849087F3849087F080008000000003EF80208020802080000 +BED3:000000084908490849087F3849087F080008000000001F080108011401620000 +BED4:000000084908490849087F3849087F080008000000001000100010001FF80000 +BED5:000000084908490849087F3849087F0800080000000020F8201020303ECC0000 +BED6:000000084908490849087F3849087F0800080000202021FC207020883E700000 +BED7:000000084908490849087F3849087F080008000003F802000200020003F80000 +BED8:000000084908490849087F3849087F080008000007F8000807F8040007F80000 +BED9:000000084908490849087F3849087F08000800003EF802083E0820083E080000 +BEDA:000000084908490849087F3849087F08000800003EF802883E8820883EF80000 +BEDB:000000084908490849087F3849087F08000800003E8802883EF820883EF80000 +BEDC:000000084908490849087F3849087F08000800000F8800880F8808140FA20000 +BEDD:000000084908490849087F3849087F08000800003EF802803EF820803EF80000 +BEDE:000000084908490849087F3849087F08000800003EFC02483E4820483EFC0000 +BEDF:000000084908490849087F3849087F08000800003E1002FE3E3820443E380000 +BEE0:000000084908490849087F3849087F080008000003F802080208020803F80000 +BEE1:000000084908490849087F3849087F08000800000208020803F8020803F80000 +BEE2:000000084908490849087F3849087F0800080000210821083F0821143F620000 +BEE3:000000084908490849087F3849087F0800080000001000100010006801840000 +BEE4:000000084908490849087F3849087F08000800000048004800A8011406620000 +BEE5:000000084908490849087F3849087F0800080000000003F00408040803F00000 +BEE6:000000084908490849087F3849087F080008000003F80020002000D003080000 +BEE7:000000084908490849087F3849087F0800080000004003F8004000A003180000 +BEE8:000000084908490849087F3849087F080008000003F8000803F8000800080000 +BEE9:000000084908490849087F3849087F080008000003F8020003F8020003F80000 +BEEA:000000084908490849087F3849087F080008000000000FF8022002200FF80000 +BEEB:000000084908490849087F3849087F080008000000800FF803E0041003E00000 +BEEC:00000000000A000A248A248A248A3FBA248A248A3F8A000A000A000A000A0000 +BEED:000000284928492849287FE849287F280028000007F800080008000800080000 +BEEE:000000284928492849287FE849287F280028000000003EF80208020802080000 +BEEF:000000284928492849287FE849287F280028000000003E100210022802C40000 +BEF0:000000284928492849287FE849287F280028000008000800080008000FF80000 +BEF1:000000284928492849287FE849287F2800280000000020F8201020303ECC0000 +BEF2:000000284928492849287FE849287F2800280000202021FC207020883E700000 +BEF3:000000284928492849287FE849287F280028000003F802000200020003F80000 +BEF4:000000284928492849287FE849287F280028000007F8000807F8040007F80000 +BEF5:000000284928492849287FE849287F28002800003EF802083E0820083E080000 +BEF6:000000284928492849287FE849287F28002800003EF802883E8820883EF80000 +BEF7:000000284928492849287FE849287F28002800003E8802883EF820883EF80000 +BEF8:000000284928492849287FE849287F28002800001F0801081F0810141F620000 +BEF9:000000284928492849287FE849287F28002800003EF802803EF820803EF80000 +BEFA:000000284928492849287FE849287F28002800003EFC02483E4820483EFC0000 +BEFB:000000284928492849287FE849287F28002800003E1002FE3E3820443E380000 +BEFC:000000284928492849287FE849287F280028000003F802080208020803F80000 +BEFD:000000284928492849287FE849287F28002800000208020803F8020803F80000 +BEFE:000000284928492849287FE849287F2800280000110811081F0811141F620000 +BEFF:000000284928492849287FE849287F2800280000000800080008003400C20000 +BF00:000000284928492849287FE849287F28002800000048004800A8011406620000 +BF01:000000284928492849287FE849287F2800280000000001F00208020801F00000 +BF02:000000284928492849287FE849287F280028000003F80020002000D003080000 +BF03:000000284928492849287FE849287F2800280000004003F8004000A003180000 +BF04:000000284928492849287FE849287F280028000003F8000803F8000800080000 +BF05:000000284928492849287FE849287F280028000003F8020003F8020003F80000 +BF06:000000284928492849287FE849287F280028000000000FF8022002200FF80000 +BF07:000000284928492849287FE849287F280028000000800FF803E0041003E00000 +BF08:000000000002000224822482249E3F822482249E3F8200020002000200020000 +BF09:000000084908490849387F0849387F0800080000000007F80008000800080000 +BF0A:000000084908490849387F0849387F080008000000003EF80208020802080000 +BF0B:000000084908490849387F0849387F080008000000001F080108011401620000 +BF0C:000000084908490849387F0849387F080008000800001000100010001FF80000 +BF0D:000000084908490849387F0849387F0800080000000020F8201020303ECC0000 +BF0E:000000084908490849387F0849387F0800080000202021FC207020883E700000 +BF0F:000000084908490849387F0849387F080008000003F802000200020003F80000 +BF10:000000084908490849387F0849387F080008000007F8000807F8040007F80000 +BF11:000000084908490849387F0849387F08000800003EF802083E0820083E080000 +BF12:000000084908490849387F0849387F08000800003EF802883E8820883EF80000 +BF13:000000084908490849387F0849387F08000800003E8802883EF820883EF80000 +BF14:000000084908490849387F0849387F08000800000F8800880F8808140FA20000 +BF15:000000084908490849387F0849387F08000800003EF802803EF820803EF80000 +BF16:000000084908490849387F0849387F08000800003EFC02483E4820483EFC0000 +BF17:000000084908490849387F0849387F08000800003E1002FE3E3820443E380000 +BF18:000000084908490849387F0849387F080008000003F802080208020803F80000 +BF19:000000084908490849387F0849387F08000800000208020803F8020803F80000 +BF1A:000000084908490849387F0849387F0800080000210821083F0821143F620000 +BF1B:000000084908490849387F0849387F0800080000001000100010006801840000 +BF1C:000000084908490849387F0849387F08000800000048004800A8011406620000 +BF1D:000000084908490849387F0849387F0800080000000003F00408040803F00000 +BF1E:000000084908490849387F0849387F080008000003F80020002000D003080000 +BF1F:000000084908490849387F0849387F0800080000004003F8004000A003180000 +BF20:000000084908490849387F0849387F080008000003F8000803F8000800080000 +BF21:000000084908490849387F0849387F080008000003F8020003F8020003F80000 +BF22:000000084908490849387F0849387F080008000000000FF8022002200FF80000 +BF23:000000084908490849387F0849387F080008000000800FF803E0041003E00000 +BF24:00000000000A000A248A248A24BA3F8A248A24BA3F8A000A000A000A000A0000 +BF25:000000284928492849E87F2849E87F280028000007F800080008000800080000 +BF26:000000284928492849E87F2849E87F280028000000003EF80208020802080000 +BF27:000000284928492849E87F2849E87F280028000000003E100210022802C40000 +BF28:000000284928492849E87F2849E87F280028002808000800080008000FF80000 +BF29:000000284928492849E87F2849E87F2800280000000020F8201020303ECC0000 +BF2A:000000284928492849E87F2849E87F2800280000202021FC207020883E700000 +BF2B:000000284928492849E87F2849E87F280028000003F802000200020003F80000 +BF2C:000000284928492849E87F2849E87F280028000007F8000807F8040007F80000 +BF2D:000000284928492849E87F2849E87F28002800003EF802083E0820083E080000 +BF2E:000000284928492849E87F2849E87F28002800003EF802883E8820883EF80000 +BF2F:000000284928492849E87F2849E87F28002800003E8802883EF820883EF80000 +BF30:000000284928492849E87F2849E87F28002800001F0801081F0810141F620000 +BF31:000000284928492849E87F2849E87F28002800003EF802803EF820803EF80000 +BF32:000000284928492849E87F2849E87F28002800003EFC02483E4820483EFC0000 +BF33:000000284928492849E87F2849E87F28002800003E1002FE3E3820443E380000 +BF34:000000284928492849E87F2849E87F280028000003F802080208020803F80000 +BF35:000000284928492849E87F2849E87F28002800000208020803F8020803F80000 +BF36:000000284928492849E87F2849E87F2800280000110811081F0811141F620000 +BF37:000000284928492849E87F2849E87F2800280000000800080008003400C20000 +BF38:000000284928492849E87F2849E87F28002800000048004800A8011406620000 +BF39:000000284928492849E87F2849E87F2800280000000001F00208020801F00000 +BF3A:000000284928492849E87F2849E87F280028000003F80020002000D003080000 +BF3B:000000284928492849E87F2849E87F2800280000004003F8004000A003180000 +BF3C:000000284928492849E87F2849E87F280028000003F8000803F8000800080000 +BF3D:000000284928492849E87F2849E87F280028000003F8020003F8020003F80000 +BF3E:000000284928492849E87F2849E87F280028000000000FF8022002200FF80000 +BF3F:000000284928492849E87F2849E87F280028000000800FF803E0041003E00000 +BF40:000000002108210821083FF8210821083FF800000100010001007FFC00000000 +BF41:0000210821083FF821083FF8010001007FFC00001FF000100010001000100000 +BF42:0000210821083FF821083FF8010001007FFC000000003EF80208020802080000 +BF43:0000210821083FF821083FF8010001007FFC000000001E100210022802C40000 +BF44:0000210821083FF821083FF8010001007FFC000000001000100010001FF00000 +BF45:0000210821083FF821083FF8010001007FFC0000000020F8201020303ECC0000 +BF46:0000210821083FF821083FF8010001007FFC0000202021FC207020883E700000 +BF47:0000210821083FF821083FF8010001007FFC00001FF01000100010001FF00000 +BF48:0000210821083FF821083FF8010001007FFC00001FF000101FF010001FF00000 +BF49:0000210821083FF821083FF8010001007FFC00003EF802083E0820083E080000 +BF4A:0000210821083FF821083FF8010001007FFC00003EF802883E8820883EF80000 +BF4B:0000210821083FF821083FF8010001007FFC00003E8802883EF820883EF80000 +BF4C:0000210821083FF821083FF8010001007FFC00003E1002103E1020283EC40000 +BF4D:0000210821083FF821083FF8010001007FFC00003EF802803EF820803EF80000 +BF4E:0000210821083FF821083FF8010001007FFC00003EFC02483E4820483EFC0000 +BF4F:0000210821083FF821083FF8010001007FFC00003E2003FC3E7020883E700000 +BF50:0000210821083FF821083FF8010001007FFC00001FF01010101010101FF00000 +BF51:0000210821083FF821083FF8010001007FFC0000101010101FF010101FF00000 +BF52:0000210821083FF821083FF8010001007FFC0000222022203E2022503E880000 +BF53:0000210821083FF821083FF8010001007FFC000000000100010002800C400000 +BF54:0000210821083FF821083FF8010001007FFC00000000024002400DA033100000 +BF55:0000210821083FF821083FF8010001007FFC0000000007C00820082007C00000 +BF56:0000210821083FF821083FF8010001007FFC0000000007E00080014006200000 +BF57:0000210821083FF821083FF8010001007FFC0000008007E00080014006200000 +BF58:0000210821083FF821083FF8010001007FFC00001FF000101FF0001000100000 +BF59:0000210821083FF821083FF8010001007FFC00001FF010001FF010001FF00000 +BF5A:0000210821083FF821083FF8010001007FFC000000001FF0044004401FF00000 +BF5B:0000210821083FF821083FF8010001007FFC000001001FF007C0082007C00000 +BF5C:0000001000104450445044507FD0445E44507FD0041004107FD0001000100000 +BF5D:0000248824883F88248E3F88040804087FE8000007F800080008000800080000 +BF5E:0000248824883F88248E3F88040804087FE8000000003EF80208020802080000 +BF5F:0000248824883F88248E3F88040804087FE8000000001F080108011401620000 +BF60:0000248824883F88248E3F88040804087FE8000008000800080008000FF80000 +BF61:0000248824883F88248E3F88040804087FE80000000010F8101010301ECC0000 +BF62:0000248824883F88248E3F88040804087FE800000808087F081C08220F9C0000 +BF63:0000248824883F88248E3F88040804087FE8000003F802000200020003F80000 +BF64:0000248824883F88248E3F88040804087FE8000007F8000807F8040007F80000 +BF65:0000248824883F88248E3F88040804087FE800003EF802083E0820083E080000 +BF66:0000248824883F88248E3F88040804087FE800003EF802883E8820883EF80000 +BF67:0000248824883F88248E3F88040804087FE800003E8802883EF820883EF80000 +BF68:0000248824883F88248E3F88040804087FE800001F0801081F0810141F620000 +BF69:0000248824883F88248E3F88040804087FE800003EF802803EF820803EF80000 +BF6A:0000248824883F88248E3F88040804087FE800003EFC02483E4820483EFC0000 +BF6B:0000248824883F88248E3F88040804087FE800001F08017F1F1C10221F1C0000 +BF6C:0000248824883F88248E3F88040804087FE8000003F802080208020803F80000 +BF6D:0000248824883F88248E3F88040804087FE800000208020803F8020803F80000 +BF6E:0000248824883F88248E3F88040804087FE80000110811081F0811141F620000 +BF6F:0000248824883F88248E3F88040804087FE80000001000100010006801840000 +BF70:0000248824883F88248E3F88040804087FE800000048004800A8011406620000 +BF71:0000248824883F88248E3F88040804087FE80000000003F00408040803F00000 +BF72:0000248824883F88248E3F88040804087FE8000003F80020002000D003080000 +BF73:0000248824883F88248E3F88040804087FE80000004003F8004000A003180000 +BF74:0000248824883F88248E3F88040804087FE8000003F8000803F8000800080000 +BF75:0000248824883F88248E3F88040804087FE8000003F8020003F8020003F80000 +BF76:0000248824883F88248E3F88040804087FE8000000000FF8022002200FF80000 +BF77:0000248824883F88248E3F88040804087FE8000000800FF803E0041003E00000 +BF78:0000001200124452445244527FD2445E44527FD2041204127FD2001200120000 +BF79:000024A824A83FA824B83FA8042804287FA8000007F800080008000800080000 +BF7A:000024A824A83FA824B83FA8042804287FA8000000003EF80208020802080000 +BF7B:000024A824A83FA824B83FA8042804287FA8000000001F080108011401620000 +BF7C:000024A824A83FA824B83FA8042804287FA8000008000800080008000FF80000 +BF7D:000024A824A83FA824B83FA8042804287FA80000000010F8101010301ECC0000 +BF7E:000024A824A83FA824B83FA8042804287FA800000808087F081C08220F9C0000 +BF7F:000024A824A83FA824B83FA8042804287FA8000003F802000200020003F80000 +BF80:000024A824A83FA824B83FA8042804287FA8000007F8000807F8040007F80000 +BF81:000024A824A83FA824B83FA8042804287FA800003EF802083E0820083E080000 +BF82:000024A824A83FA824B83FA8042804287FA800003EF802883E8820883EF80000 +BF83:000024A824A83FA824B83FA8042804287FA800003E8802883EF820883EF80000 +BF84:000024A824A83FA824B83FA8042804287FA800001F0801081F0810141F620000 +BF85:000024A824A83FA824B83FA8042804287FA800003EF802803EF820803EF80000 +BF86:000024A824A83FA824B83FA8042804287FA800003EFC02483E4820483EFC0000 +BF87:000024A824A83FA824B83FA8042804287FA800001F08017F1F1C10221F1C0000 +BF88:000024A824A83FA824B83FA8042804287FA8000003F802080208020803F80000 +BF89:000024A824A83FA824B83FA8042804287FA800000208020803F8020803F80000 +BF8A:000024A824A83FA824B83FA8042804287FA80000110811081F0811141F620000 +BF8B:000024A824A83FA824B83FA8042804287FA80000001000100010006801840000 +BF8C:000024A824A83FA824B83FA8042804287FA800000048004800A8011406620000 +BF8D:000024A824A83FA824B83FA8042804287FA80000000003F00408040803F00000 +BF8E:000024A824A83FA824B83FA8042804287FA8000003F80020002000D003080000 +BF8F:000024A824A83FA824B83FA8042804287FA80000004003F8004000A003180000 +BF90:000024A824A83FA824B83FA8042804287FA8000003F8000803F8000800080000 +BF91:000024A824A83FA824B83FA8042804287FA8000003F8020003F8020003F80000 +BF92:000024A824A83FA824B83FA8042804287FA8000000000FF8022002200FF80000 +BF93:000024A824A83FA824B83FA8042804287FA8000000800FF803E0041003E00000 +BF94:0000000800084448444844487FC8444844487FC8040804087FE8000800080000 +BF95:0000248824883F8824883F88040804087FE8000007F800080008000800080000 +BF96:0000248824883F8824883F88040804087FE8000000003EF80208020802080000 +BF97:0000248824883F8824883F88040804087FE8000000001F080108011401620000 +BF98:0000248824883F8824883F88040804087FE8000008000800080008000FF80000 +BF99:0000248824883F8824883F88040804087FE80000000010F8101010301ECC0000 +BF9A:0000248824883F8824883F88040804087FE800000808087F081C08220F9C0000 +BF9B:0000248824883F8824883F88040804087FE8000003F802000200020003F80000 +BF9C:0000248824883F8824883F88040804087FE8000007F8000807F8040007F80000 +BF9D:0000248824883F8824883F88040804087FE800003EF802083E0820083E080000 +BF9E:0000248824883F8824883F88040804087FE800003EF802883E8820883EF80000 +BF9F:0000248824883F8824883F88040804087FE800003E8802883EF820883EF80000 +BFA0:0000248824883F8824883F88040804087FE800001F0801081F0810141F620000 +BFA1:0000248824883F8824883F88040804087FE800003EF802803EF820803EF80000 +BFA2:0000248824883F8824883F88040804087FE800003EFC02483E4820483EFC0000 +BFA3:0000248824883F8824883F88040804087FE800001F08017F1F1C10221F1C0000 +BFA4:0000248824883F8824883F88040804087FE8000003F802080208020803F80000 +BFA5:0000248824883F8824883F88040804087FE800000208020803F8020803F80000 +BFA6:0000248824883F8824883F88040804087FE80000110811081F0811141F620000 +BFA7:0000248824883F8824883F88040804087FE80000001000100010006801840000 +BFA8:0000248824883F8824883F88040804087FE800000048004800A8011406620000 +BFA9:0000248824883F8824883F88040804087FE80000000003F00408040803F00000 +BFAA:0000248824883F8824883F88040804087FE8000003F80020002000D003080000 +BFAB:0000248824883F8824883F88040804087FE80000004003F8004000A003180000 +BFAC:0000248824883F8824883F88040804087FE8000003F8000803F8000800080000 +BFAD:0000248824883F8824883F88040804087FE8000003F8020003F8020003F80000 +BFAE:0000248824883F8824883F88040804087FE8000000000FF8022002200FF80000 +BFAF:0000248824883F8824883F88040804087FE8000000800FF803E0041003E00000 +BFB0:000000002108210821083FF8210821083FF804400440044004407FFC00000000 +BFB1:0000210821083FF821083FF8044004407FFC00001FF000100010001000100000 +BFB2:0000210821083FF821083FF8044004407FFC000000003EF80208020802080000 +BFB3:0000210821083FF821083FF8044004407FFC000000001E100210022802C40000 +BFB4:0000210821083FF821083FF8044004407FFC000000001000100010001FF00000 +BFB5:0000210821083FF821083FF8044004407FFC0000000020F8201020303ECC0000 +BFB6:0000210821083FF821083FF8044004407FFC0000202021FC207020883E700000 +BFB7:0000210821083FF821083FF8044004407FFC00001FF01000100010001FF00000 +BFB8:0000210821083FF821083FF8044004407FFC00001FF000101FF010001FF00000 +BFB9:0000210821083FF821083FF8044004407FFC00003EF802083E0820083E080000 +BFBA:0000210821083FF821083FF8044004407FFC00003EF802883E8820883EF80000 +BFBB:0000210821083FF821083FF8044004407FFC00003E8802883EF820883EF80000 +BFBC:0000210821083FF821083FF8044004407FFC00003E1002103E1020283EC40000 +BFBD:0000210821083FF821083FF8044004407FFC00003EF802803EF820803EF80000 +BFBE:0000210821083FF821083FF8044004407FFC00003EFC02483E4820483EFC0000 +BFBF:0000210821083FF821083FF8044004407FFC00003E2003FC3E7020883E700000 +BFC0:0000210821083FF821083FF8044004407FFC00001FF01010101010101FF00000 +BFC1:0000210821083FF821083FF8044004407FFC0000101010101FF010101FF00000 +BFC2:0000210821083FF821083FF8044004407FFC0000222022203E2022503E880000 +BFC3:0000210821083FF821083FF8044004407FFC000000000100010002800C400000 +BFC4:0000210821083FF821083FF8044004407FFC00000000024002400DA033100000 +BFC5:0000210821083FF821083FF8044004407FFC0000000007C00820082007C00000 +BFC6:0000210821083FF821083FF8044004407FFC0000000007E00080014006200000 +BFC7:0000210821083FF821083FF8044004407FFC0000008007E00080014006200000 +BFC8:0000210821083FF821083FF8044004407FFC00001FF000101FF0001000100000 +BFC9:0000210821083FF821083FF8044004407FFC00001FF010001FF010001FF00000 +BFCA:0000210821083FF821083FF8044004407FFC000000001FF0044004401FF00000 +BFCB:0000210821083FF821083FF8044004407FFC000001001FF007C0082007C00000 +BFCC:000000002108210821083FF8210821083FF800003FF801000100010001000000 +BFCD:0000210821083FF821083FF800007FFC010001001FF000100010001000100000 +BFCE:0000210821083FF821083FF800007FFC0100010000003EF80208020802080000 +BFCF:0000210821083FF821083FF800007FFC0100010000001E100210022802C40000 +BFD0:0000210821083FF821083FF8000000007FFC010001001100100010001FF00000 +BFD1:0000210821083FF821083FF800007FFC01000100000020F8201020303ECC0000 +BFD2:0000210821083FF821083FF800007FFC01000100202021FC207020883E700000 +BFD3:0000210821083FF821083FF800007FFC010001001FF01000100010001FF00000 +BFD4:0000210821083FF821083FF800007FFC010001001FF000101FF010001FF00000 +BFD5:0000210821083FF821083FF800007FFC010001003EF802083E0820083E080000 +BFD6:0000210821083FF821083FF800007FFC010001003EF802883E8820883EF80000 +BFD7:0000210821083FF821083FF800007FFC010001003E8802883EF820883EF80000 +BFD8:0000210821083FF821083FF800007FFC010001003E1002103E1020283EC40000 +BFD9:0000210821083FF821083FF800007FFC010001003EF802803EF820803EF80000 +BFDA:0000210821083FF821083FF800007FFC010001003EFC02483E4820483EFC0000 +BFDB:0000210821083FF821083FF800007FFC010001003E2003FC3E7020883E700000 +BFDC:0000210821083FF821083FF800007FFC010001001FF01010101010101FF00000 +BFDD:0000210821083FF821083FF800007FFC01000100101010101FF010101FF00000 +BFDE:0000210821083FF821083FF800007FFC01000100222022203E2022503E880000 +BFDF:0000210821083FF821083FF800007FFC0100010000000100010002800C400000 +BFE0:0000210821083FF821083FF800007FFC010001000000024002400DA033100000 +BFE1:0000210821083FF821083FF800007FFC01000100000007C00820082007C00000 +BFE2:0000210821083FF821083FF800007FFC01000100000007E00080014006200000 +BFE3:0000210821083FF821083FF800007FFC01000100008007E00080014006200000 +BFE4:0000210821083FF821083FF800007FFC010001001FF000101FF0001000100000 +BFE5:0000210821083FF821083FF800007FFC010001001FF010001FF010001FF00000 +BFE6:0000210821083FF821083FF800007FFC0100010000001FF0044004401FF00000 +BFE7:0000210821083FF821083FF800007FFC0100010001001FF007C0082007C00000 +BFE8:000000084448444844487FC8444844487FC800087FE8040804F8040804080000 +BFE9:248824883F8824883F8800087FE8027802080000000007F80008000800080000 +BFEA:248824883F8824883F8800087FE802780208000000003EF80208020802080000 +BFEB:248824883F8824883F8800087FE802780208000000001F080108011401620000 +BFEC:248824883F8824883F88000800087FE80278020802081000100010001FF80000 +BFED:248824883F8824883F8800087FE8027802080000000020F8201020303ECC0000 +BFEE:248824883F8824883F8800087FE8027802080000202021FC207020883E700000 +BFEF:248824883F8824883F8800087FE802780208000003F802000200020003F80000 +BFF0:248824883F8824883F8800087FE802780208000007F8000807F8040007F80000 +BFF1:248824883F8824883F8800087FE80278020800003EF802083E0820083E080000 +BFF2:248824883F8824883F8800087FE80278020800003EF802883E8820883EF80000 +BFF3:248824883F8824883F8800087FE80278020800003E8802883EF820883EF80000 +BFF4:248824883F8824883F8800087FE80278020800000F8800880F8808140FA20000 +BFF5:248824883F8824883F8800087FE80278020800003EF802803EF820803EF80000 +BFF6:248824883F8824883F8800087FE80278020800003EFC02483E4820483EFC0000 +BFF7:248824883F8824883F8800087FE80278020800003E1002FE3E3820443E380000 +BFF8:248824883F8824883F8800087FE802780208000003F802080208020803F80000 +BFF9:248824883F8824883F8800087FE80278020800000208020803F8020803F80000 +BFFA:248824883F8824883F8800087FE8027802080000210821083F0821143F620000 +BFFB:248824883F8824883F8800087FE8027802080000001000100010006801840000 +BFFC:248824883F8824883F8800087FE80278020800000048004800A8011406620000 +BFFD:248824883F8824883F8800087FE8027802080000000003F00408040803F00000 +BFFE:248824883F8824883F8800087FE802780208000003F80020002000D003080000 +BFFF:248824883F8824883F8800087FE8027802080000004003F8004000A003180000 +C000:248824883F8824883F8800087FE802780208000003F8000803F8000800080000 +C001:248824883F8824883F8800087FE802780208000003F8020003F8020003F80000 +C002:248824883F8824883F8800087FE802780208000000000FF8022002200FF80000 +C003:248824883F8824883F8800087FE802780208000000800FF803E0041003E00000 +C004:0000000A444A444A444A7FCA444A444A7FCA000A7FEA040A047A040A040A0000 +C005:24A824A83FA824A83FA800287FA805E804280000000007F80008000800080000 +C006:24A824A83FA824A83FA800287FA805E80428000000003EF80208020802080000 +C007:24A824A83FA824A83FA800287FA805E80428000000001F080108011401620000 +C008:24A824A83FA824A83FA8002800287FA8042805E804281428100010001FF80000 +C009:24A824A83FA824A83FA800287FA805E804280000000020F8201020303ECC0000 +C00A:24A824A83FA824A83FA800287FA805E804280000202021FC207020883E700000 +C00B:24A824A83FA824A83FA800287FA805E80428000003F802000200020003F80000 +C00C:24A824A83FA824A83FA800287FA805E80428000007F8000807F8040007F80000 +C00D:24A824A83FA824A83FA800287FA805E8042800003EF802083E0820083E080000 +C00E:24A824A83FA824A83FA800287FA805E8042800003EF802883E8820883EF80000 +C00F:24A824A83FA824A83FA800287FA805E8042800003E8802883EF820883EF80000 +C010:24A824A83FA824A83FA800287FA805E8042800000F8800880F8808140FA20000 +C011:24A824A83FA824A83FA800287FA805E8042800003EF802803EF820803EF80000 +C012:24A824A83FA824A83FA800287FA805E8042800003EFC02483E4820483EFC0000 +C013:24A824A83FA824A83FA800287FA805E8042800003E1002FE3E3820443E380000 +C014:24A824A83FA824A83FA800287FA805E80428000003F802080208020803F80000 +C015:24A824A83FA824A83FA800287FA805E8042800000208020803F8020803F80000 +C016:24A824A83FA824A83FA800287FA805E804280000210821083F0821143F620000 +C017:24A824A83FA824A83FA800287FA805E804280000001000100010006801840000 +C018:24A824A83FA824A83FA800287FA805E8042800000048004800A8011406620000 +C019:24A824A83FA824A83FA800287FA805E804280000000003F00408040803F00000 +C01A:24A824A83FA824A83FA800287FA805E80428000003F80020002000D003080000 +C01B:24A824A83FA824A83FA800287FA805E804280000004003F8004000A003180000 +C01C:24A824A83FA824A83FA800287FA805E80428000003F8000803F8000800080000 +C01D:24A824A83FA824A83FA800287FA805E80428000003F8020003F8020003F80000 +C01E:24A824A83FA824A83FA800287FA805E80428000000000FF8022002200FF80000 +C01F:24A824A83FA824A83FA800287FA805E80428000000800FF803E0041003E00000 +C020:000000084448444844487FC8444844487FC800087FE804080408040804080000 +C021:248824883F8824883F8800087FE8020802000000000007F80008000800080000 +C022:248824883F8824883F8800087FE802080200000000003EF80208020802080000 +C023:248824883F8824883F8800087FE802080200000000001F080108011401620000 +C024:248824883F8824883F88000800087FE80208020802081008100010001FF80000 +C025:248824883F8824883F8800087FE8020802000000000020F8201020303ECC0000 +C026:248824883F8824883F8800087FE8020802000000202021FC207020883E700000 +C027:248824883F8824883F8800087FE802080200000003F802000200020003F80000 +C028:248824883F8824883F8800087FE802080200000007F8000807F8040007F80000 +C029:248824883F8824883F8800087FE80208020000003EF802083E0820083E080000 +C02A:248824883F8824883F8800087FE80208020000003EF802883E8820883EF80000 +C02B:248824883F8824883F8800087FE80208020000003E8802883EF820883EF80000 +C02C:248824883F8824883F8800087FE80208020000000F8800880F8808140FA20000 +C02D:248824883F8824883F8800087FE80208020000003EF802803EF820803EF80000 +C02E:248824883F8824883F8800087FE80208020000003EFC02483E4820483EFC0000 +C02F:248824883F8824883F8800087FE80208020000003E1002FE3E3820443E380000 +C030:248824883F8824883F8800087FE802080200000003F802080208020803F80000 +C031:248824883F8824883F8800087FE80208020000000208020803F8020803F80000 +C032:248824883F8824883F8800087FE8020802000000210821083F0821143F620000 +C033:248824883F8824883F8800087FE8020802000000001000100010006801840000 +C034:248824883F8824883F8800087FE80208020000000048004800A8011406620000 +C035:248824883F8824883F8800087FE8020802000000000003F00408040803F00000 +C036:248824883F8824883F8800087FE802080200000003F80020002000D003080000 +C037:248824883F8824883F8800087FE8020802000000004003F8004000A003180000 +C038:248824883F8824883F8800087FE802080200000003F8000803F8000800080000 +C039:248824883F8824883F8800087FE802080200000003F8020003F8020003F80000 +C03A:248824883F8824883F8800087FE802080200000000000FF8022002200FF80000 +C03B:248824883F8824883F8800087FE802080200000000800FF803E0041003E00000 +C03C:000000002108210821083FF8210821083FF800007FFC04400440044004400000 +C03D:0000210821083FF821083FF800007FFC044004401FF000100010001000100000 +C03E:0000210821083FF821083FF800007FFC0440044000003EF80208020802080000 +C03F:0000210821083FF821083FF800007FFC0440044000001E100210022802C40000 +C040:0000210821083FF821083FF8000000007FFC044004401440100010001FF00000 +C041:0000210821083FF821083FF800007FFC04400440000020F8201020303ECC0000 +C042:0000210821083FF821083FF800007FFC04400440202021FC207020883E700000 +C043:0000210821083FF821083FF800007FFC044004401FF01000100010001FF00000 +C044:0000210821083FF821083FF800007FFC044004401FF000101FF010001FF00000 +C045:0000210821083FF821083FF800007FFC044004403EF802083E0820083E080000 +C046:0000210821083FF821083FF800007FFC044004403EF802883E8820883EF80000 +C047:0000210821083FF821083FF800007FFC044004403E8802883EF820883EF80000 +C048:0000210821083FF821083FF800007FFC044004403E1002103E1020283EC40000 +C049:0000210821083FF821083FF800007FFC044004403EF802803EF820803EF80000 +C04A:0000210821083FF821083FF800007FFC044004403EFC02483E4820483EFC0000 +C04B:0000210821083FF821083FF800007FFC044004403E2003FC3E7020883E700000 +C04C:0000210821083FF821083FF800007FFC044004401FF01010101010101FF00000 +C04D:0000210821083FF821083FF800007FFC04400440101010101FF010101FF00000 +C04E:0000210821083FF821083FF800007FFC04400440222022203E2022503E880000 +C04F:0000210821083FF821083FF800007FFC0440044000000100010002800C400000 +C050:0000210821083FF821083FF800007FFC044004400000024002400DA033100000 +C051:0000210821083FF821083FF800007FFC04400440000007C00820082007C00000 +C052:0000210821083FF821083FF800007FFC04400440000007E00080014006200000 +C053:0000210821083FF821083FF800007FFC04400440008007E00080014006200000 +C054:0000210821083FF821083FF800007FFC044004401FF000101FF0001000100000 +C055:0000210821083FF821083FF800007FFC044004401FF010001FF010001FF00000 +C056:0000210821083FF821083FF800007FFC0440044000001FF0044004401FF00000 +C057:0000210821083FF821083FF800007FFC0440044001001FF007C0082007C00000 +C058:000000002108210821083FF8210821083FF8000000007FFC0000000000000000 +C059:0000210821083FF821083FF8000000007FFC00001FF000100010001000100000 +C05A:0000210821083FF821083FF8000000007FFC000000003EF80208020802080000 +C05B:0000210821083FF821083FF8000000007FFC000000001E100210022802C40000 +C05C:0000210821083FF821083FF8000000007FFC000000001000100010001FF00000 +C05D:0000210821083FF821083FF8000000007FFC0000000020F8201020303ECC0000 +C05E:0000210821083FF821083FF8000000007FFC0000202021FC207020883E700000 +C05F:0000210821083FF821083FF8000000007FFC00001FF01000100010001FF00000 +C060:0000210821083FF821083FF8000000007FFC00001FF000101FF010001FF00000 +C061:0000210821083FF821083FF8000000007FFC00003EF802083E0820083E080000 +C062:0000210821083FF821083FF8000000007FFC00003EF802883E8820883EF80000 +C063:0000210821083FF821083FF8000000007FFC00003E8802883EF820883EF80000 +C064:0000210821083FF821083FF8000000007FFC00003E1002103E1020283EC40000 +C065:0000210821083FF821083FF8000000007FFC00003EF802803EF820803EF80000 +C066:0000210821083FF821083FF8000000007FFC00003EFC02483E4820483EFC0000 +C067:0000210821083FF821083FF8000000007FFC00003E2003FC3E7020883E700000 +C068:0000210821083FF821083FF8000000007FFC00001FF01010101010101FF00000 +C069:0000210821083FF821083FF8000000007FFC0000101010101FF010101FF00000 +C06A:0000210821083FF821083FF8000000007FFC0000222022203E2022503E880000 +C06B:0000210821083FF821083FF8000000007FFC000000000100010002800C400000 +C06C:0000210821083FF821083FF8000000007FFC00000000024002400DA033100000 +C06D:0000210821083FF821083FF8000000007FFC0000000007C00820082007C00000 +C06E:0000210821083FF821083FF8000000007FFC0000000007E00080014006200000 +C06F:0000210821083FF821083FF8000000007FFC0000008007E00080014006200000 +C070:0000210821083FF821083FF8000000007FFC00001FF000101FF0001000100000 +C071:0000210821083FF821083FF8000000007FFC00001FF010001FF010001FF00000 +C072:0000210821083FF821083FF8000000007FFC000000001FF0044004401FF00000 +C073:0000210821083FF821083FF8000000007FFC000001001FF007C0082007C00000 +C074:0000000800084448444844487FC8444844487FC800087FE80008000800080000 +C075:0000248824883F8824883F88000800087FE8000007F800080008000800080000 +C076:0000248824883F8824883F88000800087FE8000000003EF80208020802080000 +C077:0000248824883F8824883F88000800087FE8000000001F080108011401620000 +C078:0000248824883F8824883F88000800087FE8000008000800080008000FF80000 +C079:0000248824883F8824883F88000800087FE80000000010F8101010301ECC0000 +C07A:0000248824883F8824883F88000800087FE800000808087F081C08220F9C0000 +C07B:0000248824883F8824883F88000800087FE8000003F802000200020003F80000 +C07C:0000248824883F8824883F88000800087FE8000007F8000807F8040007F80000 +C07D:0000248824883F8824883F88000800087FE800003EF802083E0820083E080000 +C07E:0000248824883F8824883F88000800087FE800003EF802883E8820883EF80000 +C07F:0000248824883F8824883F88000800087FE800003E8802883EF820883EF80000 +C080:0000248824883F8824883F88000800087FE800001F0801081F0810141F620000 +C081:0000248824883F8824883F88000800087FE800003EF802803EF820803EF80000 +C082:0000248824883F8824883F88000800087FE800003EFC02483E4820483EFC0000 +C083:0000248824883F8824883F88000800087FE800001F08017F1F1C10221F1C0000 +C084:0000248824883F8824883F88000800087FE8000003F802080208020803F80000 +C085:0000248824883F8824883F88000800087FE800000208020803F8020803F80000 +C086:0000248824883F8824883F88000800087FE80000110811081F0811141F620000 +C087:0000248824883F8824883F88000800087FE80000001000100010006801840000 +C088:0000248824883F8824883F88000800087FE800000048004800A8011406620000 +C089:0000248824883F8824883F88000800087FE80000000003F00408040803F00000 +C08A:0000248824883F8824883F88000800087FE8000003F80020002000D003080000 +C08B:0000248824883F8824883F88000800087FE80000004003F8004000A003180000 +C08C:0000248824883F8824883F88000800087FE8000003F8000803F8000800080000 +C08D:0000248824883F8824883F88000800087FE8000003F8020003F8020003F80000 +C08E:0000248824883F8824883F88000800087FE8000000000FF8022002200FF80000 +C08F:0000248824883F8824883F88000800087FE8000000800FF803E0041003E00000 +C090:00000000000800082488248824883F88248824883F8800080008000800080000 +C091:000000084908490849087F0849087F0800080000000007F80008000800080000 +C092:000000084908490849087F0849087F080008000000003EF80208020802080000 +C093:000000084908490849087F0849087F080008000000001F080108011401620000 +C094:000000084908490849087F0849087F080008000800001000100010001FF80000 +C095:000000084908490849087F0849087F0800080000000020F8201020303ECC0000 +C096:000000084908490849087F0849087F0800080000202021FC207020883E700000 +C097:000000084908490849087F0849087F080008000003F802000200020003F80000 +C098:000000084908490849087F0849087F080008000007F8000807F8040007F80000 +C099:000000084908490849087F0849087F08000800003EF802083E0820083E080000 +C09A:000000084908490849087F0849087F08000800003EF802883E8820883EF80000 +C09B:000000084908490849087F0849087F08000800003E8802883EF820883EF80000 +C09C:000000084908490849087F0849087F08000800000F8800880F8808140FA20000 +C09D:000000084908490849087F0849087F08000800003EF802803EF820803EF80000 +C09E:000000084908490849087F0849087F08000800003EFC02483E4820483EFC0000 +C09F:000000084908490849087F0849087F08000800003E1002FE3E3820443E380000 +C0A0:000000084908490849087F0849087F080008000003F802080208020803F80000 +C0A1:000000084908490849087F0849087F08000800000208020803F8020803F80000 +C0A2:000000084908490849087F0849087F0800080000210821083F0821143F620000 +C0A3:000000084908490849087F0849087F0800080000001000100010006801840000 +C0A4:000000084908490849087F0849087F08000800000048004800A8011406620000 +C0A5:000000084908490849087F0849087F0800080000000003F00408040803F00000 +C0A6:000000084908490849087F0849087F080008000003F80020002000D003080000 +C0A7:000000084908490849087F0849087F0800080000004003F8004000A003180000 +C0A8:000000084908490849087F0849087F080008000003F8000803F8000800080000 +C0A9:000000084908490849087F0849087F080008000003F8020003F8020003F80000 +C0AA:000000084908490849087F0849087F080008000000000FF8022002200FF80000 +C0AB:000000084908490849087F0849087F080008000000800FF803E0041003E00000 +C0AC:0000000000100010021002100410041E0A101110609000100010001000100000 +C0AD:000000080008040804080C0E120861080008000007F800080008000800080000 +C0AE:000000080008040804080C0E120861080008000000003EF80208020802080000 +C0AF:000000080008040804080C0E120861080008000000001F080108011401620000 +C0B0:000000080008040804080C0E120861080008000808000800080008000FF80000 +C0B1:000000080008040804080C0E1208610800080000000010F8101010301ECC0000 +C0B2:000000080008040804080C0E12086108000800000808087F081C08220F9C0000 +C0B3:000000080008040804080C0E120861080008000003F802000200020003F80000 +C0B4:000000080008040804080C0E120861080008000007F8000807F8040007F80000 +C0B5:000000080008040804080C0E12086108000800003EF802083E0820083E080000 +C0B6:000000080008040804080C0E12086108000800003EF802883E8820883EF80000 +C0B7:000000080008040804080C0E12086108000800003E8802883EF820883EF80000 +C0B8:000000080008040804080C0E12086108000800001F0801081F0810141F620000 +C0B9:000000080008040804080C0E12086108000800003EF802803EF820803EF80000 +C0BA:000000080008040804080C0E12086108000800003EFC02483E4820483EFC0000 +C0BB:000000080008040804080C0E12086108000800001F08017F1F1C10221F1C0000 +C0BC:000000080008040804080C0E120861080008000003F802080208020803F80000 +C0BD:000000080008040804080C0E12086108000800000208020803F8020803F80000 +C0BE:000000080008040804080C0E1208610800080000110811081F0811141F620000 +C0BF:000000080008040804080C0E1208610800080000001000100010006801840000 +C0C0:000000080008040804080C0E12086108000800000048004800A8011406620000 +C0C1:000000080008040804080C0E1208610800080000000003F00408040803F00000 +C0C2:000000080008040804080C0E120861080008000003F80020002000D003080000 +C0C3:000000080008040804080C0E1208610800080000004003F8004000A003180000 +C0C4:000000080008040804080C0E120861080008000003F8000803F8000800080000 +C0C5:000000080008040804080C0E120861080008000003F8020003F8020003F80000 +C0C6:000000080008040804080C0E120861080008000000000FF8022002200FF80000 +C0C7:000000080008040804080C0E120861080008000000800FF803E0041003E00000 +C0C8:0000000000120012021202120412041E0A121112609200120012001200120000 +C0C9:000000280028042804280C38122861280028000007F800080008000800080000 +C0CA:000000280028042804280C38122861280028000000003EF80208020802080000 +C0CB:000000280028042804280C38122861280028000000003E100210022802C40000 +C0CC:000000280028042804280C38122861280028002808000800080008000FF80000 +C0CD:000000280028042804280C381228612800280000000020F8201020303ECC0000 +C0CE:000000280028042804280C381228612800280000202021FC207020883E700000 +C0CF:000000280028042804280C38122861280028000003F802000200020003F80000 +C0D0:000000280028042804280C38122861280028000007F8000807F8040007F80000 +C0D1:000000280028042804280C3812286128002800003EF802083E0820083E080000 +C0D2:000000280028042804280C3812286128002800003EF802883E8820883EF80000 +C0D3:000000280028042804280C3812286128002800003E8802883EF820883EF80000 +C0D4:000000280028042804280C3812286128002800001F0801081F0810141F620000 +C0D5:000000280028042804280C3812286128002800003EF802803EF820803EF80000 +C0D6:000000280028042804280C3812286128002800003EFC02483E4820483EFC0000 +C0D7:000000280028042804280C3812286128002800003E1002FE3E3820443E380000 +C0D8:000000280028042804280C38122861280028000003F802080208020803F80000 +C0D9:000000280028042804280C3812286128002800000208020803F8020803F80000 +C0DA:000000280028042804280C381228612800280000110811081F0811141F620000 +C0DB:000000280028042804280C381228612800280000000800080008003400C20000 +C0DC:000000280028042804280C3812286128002800000048004800A8011406620000 +C0DD:000000280028042804280C381228612800280000000001F00208020801F00000 +C0DE:000000280028042804280C38122861280028000003F80020002000D003080000 +C0DF:000000280028042804280C381228612800280000004003F8004000A003180000 +C0E0:000000280028042804280C38122861280028000003F8000803F8000800080000 +C0E1:000000280028042804280C38122861280028000003F8020003F8020003F80000 +C0E2:000000280028042804280C38122861280028000000000FF8022002200FF80000 +C0E3:000000280028042804280C38122861280028000000800FF803E0041003E00000 +C0E4:000000000010001002100210041E04100A10111E609000100010001000100000 +C0E5:0000000800080408040E0C08120E61080008000007F800080008000800080000 +C0E6:0000000800080408040E0C08120E61080008000000003EF80208020802080000 +C0E7:0000000800080408040E0C08120E61080008000000001F080108011401620000 +C0E8:0000000800080408040E0C08120E61080008000008000800080008000FF80000 +C0E9:0000000800080408040E0C08120E610800080000000010F8101010301ECC0000 +C0EA:0000000800080408040E0C08120E6108000800000808087F081C08220F9C0000 +C0EB:0000000800080408040E0C08120E61080008000003F802000200020003F80000 +C0EC:0000000800080408040E0C08120E61080008000007F8000807F8040007F80000 +C0ED:0000000800080408040E0C08120E6108000800003EF802083E0820083E080000 +C0EE:0000000800080408040E0C08120E6108000800003EF802883E8820883EF80000 +C0EF:0000000800080408040E0C08120E6108000800003E8802883EF820883EF80000 +C0F0:0000000800080408040E0C08120E6108000800001F0801081F0810141F620000 +C0F1:0000000800080408040E0C08120E6108000800003EF802803EF820803EF80000 +C0F2:0000000800080408040E0C08120E6108000800003EFC02483E4820483EFC0000 +C0F3:0000000800080408040E0C08120E6108000800001F08017F1F1C10221F1C0000 +C0F4:0000000800080408040E0C08120E61080008000003F802080208020803F80000 +C0F5:0000000800080408040E0C08120E6108000800000208020803F8020803F80000 +C0F6:0000000800080408040E0C08120E610800080000110811081F0811141F620000 +C0F7:0000000800080408040E0C08120E610800080000001000100010006801840000 +C0F8:0000000800080408040E0C08120E6108000800000048004800A8011406620000 +C0F9:0000000800080408040E0C08120E610800080000000003F00408040803F00000 +C0FA:0000000800080408040E0C08120E61080008000003F80020002000D003080000 +C0FB:0000000800080408040E0C08120E610800080000004003F8004000A003180000 +C0FC:0000000800080408040E0C08120E61080008000003F8000803F8000800080000 +C0FD:0000000800080408040E0C08120E61080008000003F8020003F8020003F80000 +C0FE:0000000800080408040E0C08120E61080008000000000FF8022002200FF80000 +C0FF:0000000800080408040E0C08120E61080008000000800FF803E0041003E00000 +C100:000000000012001202120212041E04120A12111E609200120012001200120000 +C101:000000280028042804380C28123861280028000007F800080008000800080000 +C102:000000280028042804380C28123861280028000000003EF80208020802080000 +C103:000000280028042804380C28123861280028000000003E100210022802C40000 +C104:000000280028042804380C28123861280028002808000800080008000FF80000 +C105:000000280028042804380C281238612800280000000020F8201020303ECC0000 +C106:000000280028042804380C281238612800280000202021FC207020883E700000 +C107:000000280028042804380C28123861280028000003F802000200020003F80000 +C108:000000280028042804380C28123861280028000007F8000807F8040007F80000 +C109:000000280028042804380C2812386128002800003EF802083E0820083E080000 +C10A:000000280028042804380C2812386128002800003EF802883E8820883EF80000 +C10B:000000280028042804380C2812386128002800003E8802883EF820883EF80000 +C10C:000000280028042804380C2812386128002800001F0801081F0810141F620000 +C10D:000000280028042804380C2812386128002800003EF802803EF820803EF80000 +C10E:000000280028042804380C2812386128002800003EFC02483E4820483EFC0000 +C10F:000000280028042804380C2812386128002800003E1002FE3E3820443E380000 +C110:000000280028042804380C28123861280028000003F802080208020803F80000 +C111:000000280028042804380C2812386128002800000208020803F8020803F80000 +C112:000000280028042804380C281238612800280000110811081F0811141F620000 +C113:000000280028042804380C281238612800280000000800080008003400C20000 +C114:000000280028042804380C2812386128002800000048004800A8011406620000 +C115:000000280028042804380C281238612800280000000001F00208020801F00000 +C116:000000280028042804380C28123861280028000003F80020002000D003080000 +C117:000000280028042804380C281238612800280000004003F8004000A003180000 +C118:000000280028042804380C28123861280028000003F8000803F8000800080000 +C119:000000280028042804380C28123861280028000003F8020003F8020003F80000 +C11A:000000280028042804380C28123861280028000000000FF8022002200FF80000 +C11B:000000280028042804380C28123861280028000000800FF803E0041003E00000 +C11C:0000000000020002020202020402041E0A021102608200020002000200020000 +C11D:000000080008040804080C381208610800080000000007F80008000800080000 +C11E:000000080008040804080C38120861080008000000003EF80208020802080000 +C11F:000000080008040804080C38120861080008000000001F080108011401620000 +C120:000000080008040804080C38120861080008000000001000100010001FF80000 +C121:000000080008040804080C381208610800080000000020F8201020303ECC0000 +C122:000000080008040804080C381208610800080000202021FC207020883E700000 +C123:000000080008040804080C38120861080008000003F802000200020003F80000 +C124:000000080008040804080C38120861080008000007F8000807F8040007F80000 +C125:000000080008040804080C3812086108000800003EF802083E0820083E080000 +C126:000000080008040804080C3812086108000800003EF802883E8820883EF80000 +C127:000000080008040804080C3812086108000800003E8802883EF820883EF80000 +C128:000000080008040804080C3812086108000800000F8800880F8808140FA20000 +C129:000000080008040804080C3812086108000800003EF802803EF820803EF80000 +C12A:000000080008040804080C3812086108000800003EFC02483E4820483EFC0000 +C12B:000000080008040804080C3812086108000800003E1002FE3E3820443E380000 +C12C:000000080008040804080C38120861080008000003F802080208020803F80000 +C12D:000000080008040804080C3812086108000800000208020803F8020803F80000 +C12E:000000080008040804080C381208610800080000210821083F0821143F620000 +C12F:000000080008040804080C381208610800080000001000100010006801840000 +C130:000000080008040804080C3812086108000800000048004800A8011406620000 +C131:000000080008040804080C381208610800080000000003F00408040803F00000 +C132:000000080008040804080C38120861080008000003F80020002000D003080000 +C133:000000080008040804080C381208610800080000004003F8004000A003180000 +C134:000000080008040804080C38120861080008000003F8000803F8000800080000 +C135:000000080008040804080C38120861080008000003F8020003F8020003F80000 +C136:000000080008040804080C38120861080008000000000FF8022002200FF80000 +C137:000000080008040804080C38120861080008000000800FF803E0041003E00000 +C138:00000000000A000A020A020A040A043A0A0A110A608A000A000A000A000A0000 +C139:000000280028042804280CE8122861280028000007F800080008000800080000 +C13A:000000280028042804280CE8122861280028000000003EF80208020802080000 +C13B:000000280028042804280CE8122861280028000000003E100210022802C40000 +C13C:000000280028042804280CE8122861280028000008000800080008000FF80000 +C13D:000000280028042804280CE81228612800280000000020F8201020303ECC0000 +C13E:000000280028042804280CE81228612800280000202021FC207020883E700000 +C13F:000000280028042804280CE8122861280028000003F802000200020003F80000 +C140:000000280028042804280CE8122861280028000007F8000807F8040007F80000 +C141:000000280028042804280CE812286128002800003EF802083E0820083E080000 +C142:000000280028042804280CE812286128002800003EF802883E8820883EF80000 +C143:000000280028042804280CE812286128002800003E8802883EF820883EF80000 +C144:000000280028042804280CE812286128002800001F0801081F0810141F620000 +C145:000000280028042804280CE812286128002800003EF802803EF820803EF80000 +C146:000000280028042804280CE812286128002800003EFC02483E4820483EFC0000 +C147:000000280028042804280CE812286128002800003E1002FE3E3820443E380000 +C148:000000280028042804280CE8122861280028000003F802080208020803F80000 +C149:000000280028042804280CE812286128002800000208020803F8020803F80000 +C14A:000000280028042804280CE81228612800280000110811081F0811141F620000 +C14B:000000280028042804280CE81228612800280000000800080008003400C20000 +C14C:000000280028042804280CE812286128002800000048004800A8011406620000 +C14D:000000280028042804280CE81228612800280000000001F00208020801F00000 +C14E:000000280028042804280CE8122861280028000003F80020002000D003080000 +C14F:000000280028042804280CE81228612800280000004003F8004000A003180000 +C150:000000280028042804280CE8122861280028000003F8000803F8000800080000 +C151:000000280028042804280CE8122861280028000003F8020003F8020003F80000 +C152:000000280028042804280CE8122861280028000000000FF8022002200FF80000 +C153:000000280028042804280CE8122861280028000000800FF803E0041003E00000 +C154:000000000002000202020202041E04020A02111E608200020002000200020000 +C155:000000080008040804380C081238610800080000000007F80008000800080000 +C156:000000080008040804380C08123861080008000000003EF80208020802080000 +C157:000000080008040804380C08123861080008000000001F080108011401620000 +C158:000000080008040804380C08123861080008000800001000100010001FF80000 +C159:000000080008040804380C081238610800080000000020F8201020303ECC0000 +C15A:000000080008040804380C081238610800080000202021FC207020883E700000 +C15B:000000080008040804380C08123861080008000003F802000200020003F80000 +C15C:000000080008040804380C08123861080008000007F8000807F8040007F80000 +C15D:000000080008040804380C0812386108000800003EF802083E0820083E080000 +C15E:000000080008040804380C0812386108000800003EF802883E8820883EF80000 +C15F:000000080008040804380C0812386108000800003E8802883EF820883EF80000 +C160:000000080008040804380C0812386108000800000F8800880F8808140FA20000 +C161:000000080008040804380C0812386108000800003EF802803EF820803EF80000 +C162:000000080008040804380C0812386108000800003EFC02483E4820483EFC0000 +C163:000000080008040804380C0812386108000800003E1002FE3E3820443E380000 +C164:000000080008040804380C08123861080008000003F802080208020803F80000 +C165:000000080008040804380C0812386108000800000208020803F8020803F80000 +C166:000000080008040804380C081238610800080000210821083F0821143F620000 +C167:000000080008040804380C081238610800080000001000100010006801840000 +C168:000000080008040804380C0812386108000800000048004800A8011406620000 +C169:000000080008040804380C081238610800080000000003F00408040803F00000 +C16A:000000080008040804380C08123861080008000003F80020002000D003080000 +C16B:000000080008040804380C081238610800080000004003F8004000A003180000 +C16C:000000080008040804380C08123861080008000003F8000803F8000800080000 +C16D:000000080008040804380C08123861080008000003F8020003F8020003F80000 +C16E:000000080008040804380C08123861080008000000000FF8022002200FF80000 +C16F:000000080008040804380C08123861080008000000800FF803E0041003E00000 +C170:00000000000A000A020A020A043A040A0A0A113A608A000A000A000A000A0000 +C171:000000280028042804E80C2812E861280028000007F800080008000800080000 +C172:000000280028042804E80C2812E861280028000000003EF80208020802080000 +C173:000000280028042804E80C2812E861280028000000003E100210022802C40000 +C174:000000280028042804E80C2812E861280028002808000800080008000FF80000 +C175:000000280028042804E80C2812E8612800280000000020F8201020303ECC0000 +C176:000000280028042804E80C2812E8612800280000202021FC207020883E700000 +C177:000000280028042804E80C2812E861280028000003F802000200020003F80000 +C178:000000280028042804E80C2812E861280028000007F8000807F8040007F80000 +C179:000000280028042804E80C2812E86128002800003EF802083E0820083E080000 +C17A:000000280028042804E80C2812E86128002800003EF802883E8820883EF80000 +C17B:000000280028042804E80C2812E86128002800003E8802883EF820883EF80000 +C17C:000000280028042804E80C2812E86128002800001F0801081F0810141F620000 +C17D:000000280028042804E80C2812E86128002800003EF802803EF820803EF80000 +C17E:000000280028042804E80C2812E86128002800003EFC02483E4820483EFC0000 +C17F:000000280028042804E80C2812E86128002800003E1002FE3E3820443E380000 +C180:000000280028042804E80C2812E861280028000003F802080208020803F80000 +C181:000000280028042804E80C2812E86128002800000208020803F8020803F80000 +C182:000000280028042804E80C2812E8612800280000110811081F0811141F620000 +C183:000000280028042804E80C2812E8612800280000000800080008003400C20000 +C184:000000280028042804E80C2812E86128002800000048004800A8011406620000 +C185:000000280028042804E80C2812E8612800280000000001F00208020801F00000 +C186:000000280028042804E80C2812E861280028000003F80020002000D003080000 +C187:000000280028042804E80C2812E8612800280000004003F8004000A003180000 +C188:000000280028042804E80C2812E861280028000003F8000803F8000800080000 +C189:000000280028042804E80C2812E861280028000003F8020003F8020003F80000 +C18A:000000280028042804E80C2812E861280028000000000FF8022002200FF80000 +C18B:000000280028042804E80C2812E861280028000000800FF803E0041003E00000 +C18C:00000000008000800100010002800440182000000100010001007FFC00000000 +C18D:000000800080018002400C20010001007FFC00001FF000100010001000100000 +C18E:000000800080018002400C20010001007FFC000000003EF80208020802080000 +C18F:000000800080018002400C20010001007FFC000000001E100210022802C40000 +C190:000000800080018002400C20010001007FFC000000001000100010001FF00000 +C191:000000800080018002400C20010001007FFC0000000020F8201020303ECC0000 +C192:000000800080018002400C20010001007FFC0000202021FC207020883E700000 +C193:000000800080018002400C20010001007FFC00001FF01000100010001FF00000 +C194:000000800080018002400C20010001007FFC00001FF000101FF010001FF00000 +C195:000000800080018002400C20010001007FFC00003EF802083E0820083E080000 +C196:000000800080018002400C20010001007FFC00003EF802883E8820883EF80000 +C197:000000800080018002400C20010001007FFC00003E8802883EF820883EF80000 +C198:000000800080018002400C20010001007FFC00003E1002103E1020283EC40000 +C199:000000800080018002400C20010001007FFC00003EF802803EF820803EF80000 +C19A:000000800080018002400C20010001007FFC00003EFC02483E4820483EFC0000 +C19B:000000800080018002400C20010001007FFC00003E2003FC3E7020883E700000 +C19C:000000800080018002400C20010001007FFC00001FF01010101010101FF00000 +C19D:000000800080018002400C20010001007FFC0000101010101FF010101FF00000 +C19E:000000800080018002400C20010001007FFC0000222022203E2022503E880000 +C19F:000000800080018002400C20010001007FFC000000000100010002800C400000 +C1A0:000000800080018002400C20010001007FFC00000000024002400DA033100000 +C1A1:000000800080018002400C20010001007FFC0000000007C00820082007C00000 +C1A2:000000800080018002400C20010001007FFC0000000007E00080014006200000 +C1A3:000000800080018002400C20010001007FFC0000008007E00080014006200000 +C1A4:000000800080018002400C20010001007FFC00001FF000101FF0001000100000 +C1A5:000000800080018002400C20010001007FFC00001FF010001FF010001FF00000 +C1A6:000000800080018002400C20010001007FFC000000001FF0044004401FF00000 +C1A7:000000800080018002400C20010001007FFC000001001FF007C0082007C00000 +C1A8:00000010001002100210041004100A1E11106090041004107FD0001000100000 +C1A9:0000020802080608090E3088040804087FE8000007F800080008000800080000 +C1AA:0000020802080608090E3088040804087FE8000000003EF80208020802080000 +C1AB:0000020802080608090E3088040804087FE8000000001F080108011401620000 +C1AC:0000020802080608090E3088040804087FE8000008000800080008000FF80000 +C1AD:0000020802080608090E3088040804087FE80000000010F8101010301ECC0000 +C1AE:0000020802080608090E3088040804087FE800000808087F081C08220F9C0000 +C1AF:0000020802080608090E3088040804087FE8000003F802000200020003F80000 +C1B0:0000020802080608090E3088040804087FE8000007F8000807F8040007F80000 +C1B1:0000020802080608090E3088040804087FE800003EF802083E0820083E080000 +C1B2:0000020802080608090E3088040804087FE800003EF802883E8820883EF80000 +C1B3:0000020802080608090E3088040804087FE800003E8802883EF820883EF80000 +C1B4:0000020802080608090E3088040804087FE800001F0801081F0810141F620000 +C1B5:0000020802080608090E3088040804087FE800003EF802803EF820803EF80000 +C1B6:0000020802080608090E3088040804087FE800003EFC02483E4820483EFC0000 +C1B7:0000020802080608090E3088040804087FE800001F08017F1F1C10221F1C0000 +C1B8:0000020802080608090E3088040804087FE8000003F802080208020803F80000 +C1B9:0000020802080608090E3088040804087FE800000208020803F8020803F80000 +C1BA:0000020802080608090E3088040804087FE80000110811081F0811141F620000 +C1BB:0000020802080608090E3088040804087FE80000001000100010006801840000 +C1BC:0000020802080608090E3088040804087FE800000048004800A8011406620000 +C1BD:0000020802080608090E3088040804087FE80000000003F00408040803F00000 +C1BE:0000020802080608090E3088040804087FE8000003F80020002000D003080000 +C1BF:0000020802080608090E3088040804087FE80000004003F8004000A003180000 +C1C0:0000020802080608090E3088040804087FE8000003F8000803F8000800080000 +C1C1:0000020802080608090E3088040804087FE8000003F8020003F8020003F80000 +C1C2:0000020802080608090E3088040804087FE8000000000FF8022002200FF80000 +C1C3:0000020802080608090E3088040804087FE8000000800FF803E0041003E00000 +C1C4:00000012001202120212041204120A1E11126092041204127FD2001200120000 +C1C5:0000022802280628093830A8042804287FA8000007F800080008000800080000 +C1C6:0000022802280628093830A8042804287FA8000000003EF80208020802080000 +C1C7:0000022802280628093830A8042804287FA8000000001F080108011401620000 +C1C8:0000022802280628093830A8042804287FA8000008000800080008000FF80000 +C1C9:0000022802280628093830A8042804287FA80000000010F8101010301ECC0000 +C1CA:0000022802280628093830A8042804287FA800000808087F081C08220F9C0000 +C1CB:0000022802280628093830A8042804287FA8000003F802000200020003F80000 +C1CC:0000022802280628093830A8042804287FA8000007F8000807F8040007F80000 +C1CD:0000022802280628093830A8042804287FA800003EF802083E0820083E080000 +C1CE:0000022802280628093830A8042804287FA800003EF802883E8820883EF80000 +C1CF:0000022802280628093830A8042804287FA800003E8802883EF820883EF80000 +C1D0:0000022802280628093830A8042804287FA800001F0801081F0810141F620000 +C1D1:0000022802280628093830A8042804287FA800003EF802803EF820803EF80000 +C1D2:0000022802280628093830A8042804287FA800003EFC02483E4820483EFC0000 +C1D3:0000022802280628093830A8042804287FA800001F08017F1F1C10221F1C0000 +C1D4:0000022802280628093830A8042804287FA8000003F802080208020803F80000 +C1D5:0000022802280628093830A8042804287FA800000208020803F8020803F80000 +C1D6:0000022802280628093830A8042804287FA80000110811081F0811141F620000 +C1D7:0000022802280628093830A8042804287FA80000001000100010006801840000 +C1D8:0000022802280628093830A8042804287FA800000048004800A8011406620000 +C1D9:0000022802280628093830A8042804287FA80000000003F00408040803F00000 +C1DA:0000022802280628093830A8042804287FA8000003F80020002000D003080000 +C1DB:0000022802280628093830A8042804287FA80000004003F8004000A003180000 +C1DC:0000022802280628093830A8042804287FA8000003F8000803F8000800080000 +C1DD:0000022802280628093830A8042804287FA8000003F8020003F8020003F80000 +C1DE:0000022802280628093830A8042804287FA8000000000FF8022002200FF80000 +C1DF:0000022802280628093830A8042804287FA8000000800FF803E0041003E00000 +C1E0:00000008000802080208040804080A0811086088040804087FE8000800080000 +C1E1:000002080208060809083088040804087FE8000007F800080008000800080000 +C1E2:000002080208060809083088040804087FE8000000003EF80208020802080000 +C1E3:000002080208060809083088040804087FE8000000001F080108011401620000 +C1E4:000002080208060809083088040804087FE8000008000800080008000FF80000 +C1E5:000002080208060809083088040804087FE80000000010F8101010301ECC0000 +C1E6:000002080208060809083088040804087FE800000808087F081C08220F9C0000 +C1E7:000002080208060809083088040804087FE8000003F802000200020003F80000 +C1E8:000002080208060809083088040804087FE8000007F8000807F8040007F80000 +C1E9:000002080208060809083088040804087FE800003EF802083E0820083E080000 +C1EA:000002080208060809083088040804087FE800003EF802883E8820883EF80000 +C1EB:000002080208060809083088040804087FE800003E8802883EF820883EF80000 +C1EC:000002080208060809083088040804087FE800001F0801081F0810141F620000 +C1ED:000002080208060809083088040804087FE800003EF802803EF820803EF80000 +C1EE:000002080208060809083088040804087FE800003EFC02483E4820483EFC0000 +C1EF:000002080208060809083088040804087FE800001F08017F1F1C10221F1C0000 +C1F0:000002080208060809083088040804087FE8000003F802080208020803F80000 +C1F1:000002080208060809083088040804087FE800000208020803F8020803F80000 +C1F2:000002080208060809083088040804087FE80000110811081F0811141F620000 +C1F3:000002080208060809083088040804087FE80000001000100010006801840000 +C1F4:000002080208060809083088040804087FE800000048004800A8011406620000 +C1F5:000002080208060809083088040804087FE80000000003F00408040803F00000 +C1F6:000002080208060809083088040804087FE8000003F80020002000D003080000 +C1F7:000002080208060809083088040804087FE80000004003F8004000A003180000 +C1F8:000002080208060809083088040804087FE8000003F8000803F8000800080000 +C1F9:000002080208060809083088040804087FE8000003F8020003F8020003F80000 +C1FA:000002080208060809083088040804087FE8000000000FF8022002200FF80000 +C1FB:000002080208060809083088040804087FE8000000800FF803E0041003E00000 +C1FC:00000000008000800100010002800440182004400440044004407FFC00000000 +C1FD:000000800080018002400C20044004407FFC00001FF000100010001000100000 +C1FE:000000800080018002400C20044004407FFC000000003EF80208020802080000 +C1FF:000000800080018002400C20044004407FFC000000001E100210022802C40000 +C200:000000800080018002400C20044004407FFC000000001000100010001FF00000 +C201:000000800080018002400C20044004407FFC0000000020F8201020303ECC0000 +C202:000000800080018002400C20044004407FFC0000202021FC207020883E700000 +C203:000000800080018002400C20044004407FFC00001FF01000100010001FF00000 +C204:000000800080018002400C20044004407FFC00001FF000101FF010001FF00000 +C205:000000800080018002400C20044004407FFC00003EF802083E0820083E080000 +C206:000000800080018002400C20044004407FFC00003EF802883E8820883EF80000 +C207:000000800080018002400C20044004407FFC00003E8802883EF820883EF80000 +C208:000000800080018002400C20044004407FFC00003E1002103E1020283EC40000 +C209:000000800080018002400C20044004407FFC00003EF802803EF820803EF80000 +C20A:000000800080018002400C20044004407FFC00003EFC02483E4820483EFC0000 +C20B:000000800080018002400C20044004407FFC00003E2003FC3E7020883E700000 +C20C:000000800080018002400C20044004407FFC00001FF01010101010101FF00000 +C20D:000000800080018002400C20044004407FFC0000101010101FF010101FF00000 +C20E:000000800080018002400C20044004407FFC0000222022203E2022503E880000 +C20F:000000800080018002400C20044004407FFC000000000100010002800C400000 +C210:000000800080018002400C20044004407FFC00000000024002400DA033100000 +C211:000000800080018002400C20044004407FFC0000000007C00820082007C00000 +C212:000000800080018002400C20044004407FFC0000000007E00080014006200000 +C213:000000800080018002400C20044004407FFC0000008007E00080014006200000 +C214:000000800080018002400C20044004407FFC00001FF000101FF0001000100000 +C215:000000800080018002400C20044004407FFC00001FF010001FF010001FF00000 +C216:000000800080018002400C20044004407FFC000000001FF0044004401FF00000 +C217:000000800080018002400C20044004407FFC000001001FF007C0082007C00000 +C218:00000000008000800100010002800440182000003FF801000100010001000000 +C219:000000800080018002400C2000007FFC010001001FF000100010001000100000 +C21A:000000800080018002400C2000007FFC0100010000003EF80208020802080000 +C21B:000000800080018002400C2000007FFC0100010000001E100210022802C40000 +C21C:000000800080018002400C20000000007FFC010001001100100010001FF00000 +C21D:000000800080018002400C2000007FFC01000100000020F8201020303ECC0000 +C21E:000000800080018002400C2000007FFC01000100202021FC207020883E700000 +C21F:000000800080018002400C2000007FFC010001001FF01000100010001FF00000 +C220:000000800080018002400C2000007FFC010001001FF000101FF010001FF00000 +C221:000000800080018002400C2000007FFC010001003EF802083E0820083E080000 +C222:000000800080018002400C2000007FFC010001003EF802883E8820883EF80000 +C223:000000800080018002400C2000007FFC010001003E8802883EF820883EF80000 +C224:000000800080018002400C2000007FFC010001003E1002103E1020283EC40000 +C225:000000800080018002400C2000007FFC010001003EF802803EF820803EF80000 +C226:000000800080018002400C2000007FFC010001003EFC02483E4820483EFC0000 +C227:000000800080018002400C2000007FFC010001003E2003FC3E7020883E700000 +C228:000000800080018002400C2000007FFC010001001FF01010101010101FF00000 +C229:000000800080018002400C2000007FFC01000100101010101FF010101FF00000 +C22A:000000800080018002400C2000007FFC01000100222022203E2022503E880000 +C22B:000000800080018002400C2000007FFC0100010000000100010002800C400000 +C22C:000000800080018002400C2000007FFC010001000000024002400DA033100000 +C22D:000000800080018002400C2000007FFC01000100000007C00820082007C00000 +C22E:000000800080018002400C2000007FFC01000100000007E00080014006200000 +C22F:000000800080018002400C2000007FFC01000100008007E00080014006200000 +C230:000000800080018002400C2000007FFC010001001FF000101FF0001000100000 +C231:000000800080018002400C2000007FFC010001001FF010001FF010001FF00000 +C232:000000800080018002400C2000007FFC0100010000001FF0044004401FF00000 +C233:000000800080018002400C2000007FFC0100010001001FF007C0082007C00000 +C234:0000000802080208040804080A081108608800087FE8040804F8040804080000 +C235:0208020806080908308800087FE8027802080000000007F80008000800080000 +C236:0208020806080908308800087FE802780208000000003EF80208020802080000 +C237:0208020806080908308800087FE802780208000000001F080108011401620000 +C238:02080208060809083088000800087FE80278020802081000100010001FF80000 +C239:0208020806080908308800087FE8027802080000000020F8201020303ECC0000 +C23A:0208020806080908308800087FE8027802080000202021FC207020883E700000 +C23B:0208020806080908308800087FE802780208000003F802000200020003F80000 +C23C:0208020806080908308800087FE802780208000007F8000807F8040007F80000 +C23D:0208020806080908308800087FE80278020800003EF802083E0820083E080000 +C23E:0208020806080908308800087FE80278020800003EF802883E8820883EF80000 +C23F:0208020806080908308800087FE80278020800003E8802883EF820883EF80000 +C240:0208020806080908308800087FE80278020800000F8800880F8808140FA20000 +C241:0208020806080908308800087FE80278020800003EF802803EF820803EF80000 +C242:0208020806080908308800087FE80278020800003EFC02483E4820483EFC0000 +C243:0208020806080908308800087FE80278020800003E1002FE3E3820443E380000 +C244:0208020806080908308800087FE802780208000003F802080208020803F80000 +C245:0208020806080908308800087FE80278020800000208020803F8020803F80000 +C246:0208020806080908308800087FE8027802080000210821083F0821143F620000 +C247:0208020806080908308800087FE8027802080000001000100010006801840000 +C248:0208020806080908308800087FE80278020800000048004800A8011406620000 +C249:0208020806080908308800087FE8027802080000000003F00408040803F00000 +C24A:0208020806080908308800087FE802780208000003F80020002000D003080000 +C24B:0208020806080908308800087FE8027802080000004003F8004000A003180000 +C24C:0208020806080908308800087FE802780208000003F8000803F8000800080000 +C24D:0208020806080908308800087FE802780208000003F8020003F8020003F80000 +C24E:0208020806080908308800087FE802780208000000000FF8022002200FF80000 +C24F:0208020806080908308800087FE802780208000000800FF803E0041003E00000 +C250:0000000A020A020A040A040A0A0A110A608A000A7FEA040A047A040A040A0000 +C251:022802280628092830A800287FA805E804280000000007F80008000800080000 +C252:022802280628092830A800287FA805E80428000000003EF80208020802080000 +C253:022802280628092830A800287FA805E80428000000001F080108011401620000 +C254:022802280628092830A8002800287FA8042805E804281428100010001FF80000 +C255:022802280628092830A800287FA805E804280000000020F8201020303ECC0000 +C256:022802280628092830A800287FA805E804280000202021FC207020883E700000 +C257:022802280628092830A800287FA805E80428000003F802000200020003F80000 +C258:022802280628092830A800287FA805E80428000007F8000807F8040007F80000 +C259:022802280628092830A800287FA805E8042800003EF802083E0820083E080000 +C25A:022802280628092830A800287FA805E8042800003EF802883E8820883EF80000 +C25B:022802280628092830A800287FA805E8042800003E8802883EF820883EF80000 +C25C:022802280628092830A800287FA805E8042800000F8800880F8808140FA20000 +C25D:022802280628092830A800287FA805E8042800003EF802803EF820803EF80000 +C25E:022802280628092830A800287FA805E8042800003EFC02483E4820483EFC0000 +C25F:022802280628092830A800287FA805E8042800003E1002FE3E3820443E380000 +C260:022802280628092830A800287FA805E80428000003F802080208020803F80000 +C261:022802280628092830A800287FA805E8042800000208020803F8020803F80000 +C262:022802280628092830A800287FA805E804280000210821083F0821143F620000 +C263:022802280628092830A800287FA805E804280000001000100010006801840000 +C264:022802280628092830A800287FA805E8042800000048004800A8011406620000 +C265:022802280628092830A800287FA805E804280000000003F00408040803F00000 +C266:022802280628092830A800287FA805E80428000003F80020002000D003080000 +C267:022802280628092830A800287FA805E804280000004003F8004000A003180000 +C268:022802280628092830A800287FA805E80428000003F8000803F8000800080000 +C269:022802280628092830A800287FA805E80428000003F8020003F8020003F80000 +C26A:022802280628092830A800287FA805E80428000000000FF8022002200FF80000 +C26B:022802280628092830A800287FA805E80428000000800FF803E0041003E00000 +C26C:0000000802080208040804080A081108608800087FE804080408040804080000 +C26D:0208020806080908308800087FE8020802000000000007F80008000800080000 +C26E:0208020806080908308800087FE802080200000000003EF80208020802080000 +C26F:0208020806080908308800087FE802080200000000001F080108011401620000 +C270:02080208060809083088000800087FE80208020802081008100010001FF80000 +C271:0208020806080908308800087FE8020802000000000020F8201020303ECC0000 +C272:0208020806080908308800087FE8020802000000202021FC207020883E700000 +C273:0208020806080908308800087FE802080200000003F802000200020003F80000 +C274:0208020806080908308800087FE802080200000007F8000807F8040007F80000 +C275:0208020806080908308800087FE80208020000003EF802083E0820083E080000 +C276:0208020806080908308800087FE80208020000003EF802883E8820883EF80000 +C277:0208020806080908308800087FE80208020000003E8802883EF820883EF80000 +C278:0208020806080908308800087FE80208020000000F8800880F8808140FA20000 +C279:0208020806080908308800087FE80208020000003EF802803EF820803EF80000 +C27A:0208020806080908308800087FE80208020000003EFC02483E4820483EFC0000 +C27B:0208020806080908308800087FE80208020000003E1002FE3E3820443E380000 +C27C:0208020806080908308800087FE802080200000003F802080208020803F80000 +C27D:0208020806080908308800087FE80208020000000208020803F8020803F80000 +C27E:0208020806080908308800087FE8020802000000210821083F0821143F620000 +C27F:0208020806080908308800087FE8020802000000001000100010006801840000 +C280:0208020806080908308800087FE80208020000000048004800A8011406620000 +C281:0208020806080908308800087FE8020802000000000003F00408040803F00000 +C282:0208020806080908308800087FE802080200000003F80020002000D003080000 +C283:0208020806080908308800087FE8020802000000004003F8004000A003180000 +C284:0208020806080908308800087FE802080200000003F8000803F8000800080000 +C285:0208020806080908308800087FE802080200000003F8020003F8020003F80000 +C286:0208020806080908308800087FE802080200000000000FF8022002200FF80000 +C287:0208020806080908308800087FE802080200000000800FF803E0041003E00000 +C288:00000000008000800100010002800440182000007FFC04400440044004400000 +C289:000000800080018002400C2000007FFC044004401FF000100010001000100000 +C28A:000000800080018002400C2000007FFC0440044000003EF80208020802080000 +C28B:000000800080018002400C2000007FFC0440044000001E100210022802C40000 +C28C:000000800080018002400C20000000007FFC044004401440100010001FF00000 +C28D:000000800080018002400C2000007FFC04400440000020F8201020303ECC0000 +C28E:000000800080018002400C2000007FFC04400440202021FC207020883E700000 +C28F:000000800080018002400C2000007FFC044004401FF01000100010001FF00000 +C290:000000800080018002400C2000007FFC044004401FF000101FF010001FF00000 +C291:000000800080018002400C2000007FFC044004403EF802083E0820083E080000 +C292:000000800080018002400C2000007FFC044004403EF802883E8820883EF80000 +C293:000000800080018002400C2000007FFC044004403E8802883EF820883EF80000 +C294:000000800080018002400C2000007FFC044004403E1002103E1020283EC40000 +C295:000000800080018002400C2000007FFC044004403EF802803EF820803EF80000 +C296:000000800080018002400C2000007FFC044004403EFC02483E4820483EFC0000 +C297:000000800080018002400C2000007FFC044004403E2003FC3E7020883E700000 +C298:000000800080018002400C2000007FFC044004401FF01010101010101FF00000 +C299:000000800080018002400C2000007FFC04400440101010101FF010101FF00000 +C29A:000000800080018002400C2000007FFC04400440222022203E2022503E880000 +C29B:000000800080018002400C2000007FFC0440044000000100010002800C400000 +C29C:000000800080018002400C2000007FFC044004400000024002400DA033100000 +C29D:000000800080018002400C2000007FFC04400440000007C00820082007C00000 +C29E:000000800080018002400C2000007FFC04400440000007E00080014006200000 +C29F:000000800080018002400C2000007FFC04400440008007E00080014006200000 +C2A0:000000800080018002400C2000007FFC044004401FF000101FF0001000100000 +C2A1:000000800080018002400C2000007FFC044004401FF010001FF010001FF00000 +C2A2:000000800080018002400C2000007FFC0440044000001FF0044004401FF00000 +C2A3:000000800080018002400C2000007FFC0440044001001FF007C0082007C00000 +C2A4:000000000080008001000100028004401820000000007FFC0000000000000000 +C2A5:000000800080018002400C20000000007FFC00001FF000100010001000100000 +C2A6:000000800080018002400C20000000007FFC000000003EF80208020802080000 +C2A7:000000800080018002400C20000000007FFC000000001E100210022802C40000 +C2A8:000000800080018002400C20000000007FFC000000001000100010001FF00000 +C2A9:000000800080018002400C20000000007FFC0000000020F8201020303ECC0000 +C2AA:000000800080018002400C20000000007FFC0000202021FC207020883E700000 +C2AB:000000800080018002400C20000000007FFC00001FF01000100010001FF00000 +C2AC:000000800080018002400C20000000007FFC00001FF000101FF010001FF00000 +C2AD:000000800080018002400C20000000007FFC00003EF802083E0820083E080000 +C2AE:000000800080018002400C20000000007FFC00003EF802883E8820883EF80000 +C2AF:000000800080018002400C20000000007FFC00003E8802883EF820883EF80000 +C2B0:000000800080018002400C20000000007FFC00003E1002103E1020283EC40000 +C2B1:000000800080018002400C20000000007FFC00003EF802803EF820803EF80000 +C2B2:000000800080018002400C20000000007FFC00003EFC02483E4820483EFC0000 +C2B3:000000800080018002400C20000000007FFC00003E2003FC3E7020883E700000 +C2B4:000000800080018002400C20000000007FFC00001FF01010101010101FF00000 +C2B5:000000800080018002400C20000000007FFC0000101010101FF010101FF00000 +C2B6:000000800080018002400C20000000007FFC0000222022203E2022503E880000 +C2B7:000000800080018002400C20000000007FFC000000000100010002800C400000 +C2B8:000000800080018002400C20000000007FFC00000000024002400DA033100000 +C2B9:000000800080018002400C20000000007FFC0000000007C00820082007C00000 +C2BA:000000800080018002400C20000000007FFC0000000007E00080014006200000 +C2BB:000000800080018002400C20000000007FFC0000008007E00080014006200000 +C2BC:000000800080018002400C20000000007FFC00001FF000101FF0001000100000 +C2BD:000000800080018002400C20000000007FFC00001FF010001FF010001FF00000 +C2BE:000000800080018002400C20000000007FFC000000001FF0044004401FF00000 +C2BF:000000800080018002400C20000000007FFC000001001FF007C0082007C00000 +C2C0:00000008000802080208040804080A081108608800087FE80008000800080000 +C2C1:000002080208060809083088000800087FE8000007F800080008000800080000 +C2C2:000002080208060809083088000800087FE8000000003EF80208020802080000 +C2C3:000002080208060809083088000800087FE8000000001F080108011401620000 +C2C4:000002080208060809083088000800087FE8000008000800080008000FF80000 +C2C5:000002080208060809083088000800087FE80000000010F8101010301ECC0000 +C2C6:000002080208060809083088000800087FE800000808087F081C08220F9C0000 +C2C7:000002080208060809083088000800087FE8000003F802000200020003F80000 +C2C8:000002080208060809083088000800087FE8000007F8000807F8040007F80000 +C2C9:000002080208060809083088000800087FE800003EF802083E0820083E080000 +C2CA:000002080208060809083088000800087FE800003EF802883E8820883EF80000 +C2CB:000002080208060809083088000800087FE800003E8802883EF820883EF80000 +C2CC:000002080208060809083088000800087FE800001F0801081F0810141F620000 +C2CD:000002080208060809083088000800087FE800003EF802803EF820803EF80000 +C2CE:000002080208060809083088000800087FE800003EFC02483E4820483EFC0000 +C2CF:000002080208060809083088000800087FE800001F08017F1F1C10221F1C0000 +C2D0:000002080208060809083088000800087FE8000003F802080208020803F80000 +C2D1:000002080208060809083088000800087FE800000208020803F8020803F80000 +C2D2:000002080208060809083088000800087FE80000110811081F0811141F620000 +C2D3:000002080208060809083088000800087FE80000001000100010006801840000 +C2D4:000002080208060809083088000800087FE800000048004800A8011406620000 +C2D5:000002080208060809083088000800087FE80000000003F00408040803F00000 +C2D6:000002080208060809083088000800087FE8000003F80020002000D003080000 +C2D7:000002080208060809083088000800087FE80000004003F8004000A003180000 +C2D8:000002080208060809083088000800087FE8000003F8000803F8000800080000 +C2D9:000002080208060809083088000800087FE8000003F8020003F8020003F80000 +C2DA:000002080208060809083088000800087FE8000000000FF8022002200FF80000 +C2DB:000002080208060809083088000800087FE8000000800FF803E0041003E00000 +C2DC:000000000008000802080208040804080A081108608800080008000800080000 +C2DD:000000080008040804080C081208610800080000000007F80008000800080000 +C2DE:000000080008040804080C08120861080008000000003EF80208020802080000 +C2DF:000000080008040804080C08120861080008000000001F080108011401620000 +C2E0:000000080008040804080C08120861080008000800001000100010001FF80000 +C2E1:000000080008040804080C081208610800080000000020F8201020303ECC0000 +C2E2:000000080008040804080C081208610800080000202021FC207020883E700000 +C2E3:000000080008040804080C08120861080008000003F802000200020003F80000 +C2E4:000000080008040804080C08120861080008000007F8000807F8040007F80000 +C2E5:000000080008040804080C0812086108000800003EF802083E0820083E080000 +C2E6:000000080008040804080C0812086108000800003EF802883E8820883EF80000 +C2E7:000000080008040804080C0812086108000800003E8802883EF820883EF80000 +C2E8:000000080008040804080C0812086108000800000F8800880F8808140FA20000 +C2E9:000000080008040804080C0812086108000800003EF802803EF820803EF80000 +C2EA:000000080008040804080C0812086108000800003EFC02483E4820483EFC0000 +C2EB:000000080008040804080C0812086108000800003E1002FE3E3820443E380000 +C2EC:000000080008040804080C08120861080008000003F802080208020803F80000 +C2ED:000000080008040804080C0812086108000800000208020803F8020803F80000 +C2EE:000000080008040804080C081208610800080000210821083F0821143F620000 +C2EF:000000080008040804080C081208610800080000001000100010006801840000 +C2F0:000000080008040804080C0812086108000800000048004800A8011406620000 +C2F1:000000080008040804080C081208610800080000000003F00408040803F00000 +C2F2:000000080008040804080C08120861080008000003F80020002000D003080000 +C2F3:000000080008040804080C081208610800080000004003F8004000A003180000 +C2F4:000000080008040804080C08120861080008000003F8000803F8000800080000 +C2F5:000000080008040804080C08120861080008000003F8020003F8020003F80000 +C2F6:000000080008040804080C08120861080008000000000FF8022002200FF80000 +C2F7:000000080008040804080C08120861080008000000800FF803E0041003E00000 +C2F8:0000000000100010089008900890191E15102290CC5000100010001000100000 +C2F9:00000008000812081208340E2A0849080008000007F800080008000800080000 +C2FA:00000008000812081208340E2A0849080008000000003EF80208020802080000 +C2FB:00000008000812081208340E2A0849080008000000001F080108011401620000 +C2FC:00000008000812081208340E2A0849080008000808000800080008000FF80000 +C2FD:00000008000812081208340E2A08490800080000000010F8101010301ECC0000 +C2FE:00000008000812081208340E2A084908000800000808087F081C08220F9C0000 +C2FF:00000008000812081208340E2A0849080008000003F802000200020003F80000 +C300:00000008000812081208340E2A0849080008000007F8000807F8040007F80000 +C301:00000008000812081208340E2A084908000800003EF802083E0820083E080000 +C302:00000008000812081208340E2A084908000800003EF802883E8820883EF80000 +C303:00000008000812081208340E2A084908000800003E8802883EF820883EF80000 +C304:00000008000812081208340E2A084908000800001F0801081F0810141F620000 +C305:00000008000812081208340E2A084908000800003EF802803EF820803EF80000 +C306:00000008000812081208340E2A084908000800003EFC02483E4820483EFC0000 +C307:00000008000812081208340E2A084908000800001F08017F1F1C10221F1C0000 +C308:00000008000812081208340E2A0849080008000003F802080208020803F80000 +C309:00000008000812081208340E2A084908000800000208020803F8020803F80000 +C30A:00000008000812081208340E2A08490800080000110811081F0811141F620000 +C30B:00000008000812081208340E2A08490800080000001000100010006801840000 +C30C:00000008000812081208340E2A084908000800000048004800A8011406620000 +C30D:00000008000812081208340E2A08490800080000000003F00408040803F00000 +C30E:00000008000812081208340E2A0849080008000003F80020002000D003080000 +C30F:00000008000812081208340E2A08490800080000004003F8004000A003180000 +C310:00000008000812081208340E2A0849080008000003F8000803F8000800080000 +C311:00000008000812081208340E2A0849080008000003F8020003F8020003F80000 +C312:00000008000812081208340E2A0849080008000000000FF8022002200FF80000 +C313:00000008000812081208340E2A0849080008000000800FF803E0041003E00000 +C314:0000000000120012089208920892191E15122292CC5200120012001200120000 +C315:0000002800281228122834382A2849280028000007F800080008000800080000 +C316:0000002800281228122834382A2849280028000000003EF80208020802080000 +C317:0000002800281228122834382A2849280028000000003E100210022802C40000 +C318:0000002800281228122834382A2849280028002808000800080008000FF80000 +C319:0000002800281228122834382A28492800280000000020F8201020303ECC0000 +C31A:0000002800281228122834382A28492800280000202021FC207020883E700000 +C31B:0000002800281228122834382A2849280028000003F802000200020003F80000 +C31C:0000002800281228122834382A2849280028000007F8000807F8040007F80000 +C31D:0000002800281228122834382A284928002800003EF802083E0820083E080000 +C31E:0000002800281228122834382A284928002800003EF802883E8820883EF80000 +C31F:0000002800281228122834382A284928002800003E8802883EF820883EF80000 +C320:0000002800281228122834382A284928002800001F0801081F0810141F620000 +C321:0000002800281228122834382A284928002800003EF802803EF820803EF80000 +C322:0000002800281228122834382A284928002800003EFC02483E4820483EFC0000 +C323:0000002800281228122834382A284928002800003E1002FE3E3820443E380000 +C324:0000002800281228122834382A2849280028000003F802080208020803F80000 +C325:0000002800281228122834382A284928002800000208020803F8020803F80000 +C326:0000002800281228122834382A28492800280000110811081F0811141F620000 +C327:0000002800281228122834382A28492800280000000800080008003400C20000 +C328:0000002800281228122834382A284928002800000048004800A8011406620000 +C329:0000002800281228122834382A28492800280000000001F00208020801F00000 +C32A:0000002800281228122834382A2849280028000003F80020002000D003080000 +C32B:0000002800281228122834382A28492800280000004003F8004000A003180000 +C32C:0000002800281228122834382A2849280028000003F8000803F8000800080000 +C32D:0000002800281228122834382A2849280028000003F8020003F8020003F80000 +C32E:0000002800281228122834382A2849280028000000000FF8022002200FF80000 +C32F:0000002800281228122834382A2849280028000000800FF803E0041003E00000 +C330:000000000010001008900890089E19101510229ECC5000100010001000100000 +C331:0000000800081208120E34082A0E49080008000007F800080008000800080000 +C332:0000000800081208120E34082A0E49080008000000003EF80208020802080000 +C333:0000000800081208120E34082A0E49080008000000001F080108011401620000 +C334:0000000800081208120E34082A0E49080008000008000800080008000FF80000 +C335:0000000800081208120E34082A0E490800080000000010F8101010301ECC0000 +C336:0000000800081208120E34082A0E4908000800000808087F081C08220F9C0000 +C337:0000000800081208120E34082A0E49080008000003F802000200020003F80000 +C338:0000000800081208120E34082A0E49080008000007F8000807F8040007F80000 +C339:0000000800081208120E34082A0E4908000800003EF802083E0820083E080000 +C33A:0000000800081208120E34082A0E4908000800003EF802883E8820883EF80000 +C33B:0000000800081208120E34082A0E4908000800003E8802883EF820883EF80000 +C33C:0000000800081208120E34082A0E4908000800001F0801081F0810141F620000 +C33D:0000000800081208120E34082A0E4908000800003EF802803EF820803EF80000 +C33E:0000000800081208120E34082A0E4908000800003EFC02483E4820483EFC0000 +C33F:0000000800081208120E34082A0E4908000800001F08017F1F1C10221F1C0000 +C340:0000000800081208120E34082A0E49080008000003F802080208020803F80000 +C341:0000000800081208120E34082A0E4908000800000208020803F8020803F80000 +C342:0000000800081208120E34082A0E490800080000110811081F0811141F620000 +C343:0000000800081208120E34082A0E490800080000001000100010006801840000 +C344:0000000800081208120E34082A0E4908000800000048004800A8011406620000 +C345:0000000800081208120E34082A0E490800080000000003F00408040803F00000 +C346:0000000800081208120E34082A0E49080008000003F80020002000D003080000 +C347:0000000800081208120E34082A0E490800080000004003F8004000A003180000 +C348:0000000800081208120E34082A0E49080008000003F8000803F8000800080000 +C349:0000000800081208120E34082A0E49080008000003F8020003F8020003F80000 +C34A:0000000800081208120E34082A0E49080008000000000FF8022002200FF80000 +C34B:0000000800081208120E34082A0E49080008000000800FF803E0041003E00000 +C34C:000000000012001208920892089E19121512229ECC5200120012001200120000 +C34D:0000002800281228123834282A3849280028000007F800080008000800080000 +C34E:0000002800281228123834282A3849280028000000003EF80208020802080000 +C34F:0000002800281228123834282A3849280028000000003E100210022802C40000 +C350:0000002800281228123834282A3849280028002808000800080008000FF80000 +C351:0000002800281228123834282A38492800280000000020F8201020303ECC0000 +C352:0000002800281228123834282A38492800280000202021FC207020883E700000 +C353:0000002800281228123834282A3849280028000003F802000200020003F80000 +C354:0000002800281228123834282A3849280028000007F8000807F8040007F80000 +C355:0000002800281228123834282A384928002800003EF802083E0820083E080000 +C356:0000002800281228123834282A384928002800003EF802883E8820883EF80000 +C357:0000002800281228123834282A384928002800003E8802883EF820883EF80000 +C358:0000002800281228123834282A384928002800001F0801081F0810141F620000 +C359:0000002800281228123834282A384928002800003EF802803EF820803EF80000 +C35A:0000002800281228123834282A384928002800003EFC02483E4820483EFC0000 +C35B:0000002800281228123834282A384928002800003E1002FE3E3820443E380000 +C35C:0000002800281228123834282A3849280028000003F802080208020803F80000 +C35D:0000002800281228123834282A384928002800000208020803F8020803F80000 +C35E:0000002800281228123834282A38492800280000110811081F0811141F620000 +C35F:0000002800281228123834282A38492800280000000800080008003400C20000 +C360:0000002800281228123834282A384928002800000048004800A8011406620000 +C361:0000002800281228123834282A38492800280000000001F00208020801F00000 +C362:0000002800281228123834282A3849280028000003F80020002000D003080000 +C363:0000002800281228123834282A38492800280000004003F8004000A003180000 +C364:0000002800281228123834282A3849280028000003F8000803F8000800080000 +C365:0000002800281228123834282A3849280028000003F8020003F8020003F80000 +C366:0000002800281228123834282A3849280028000000000FF8022002200FF80000 +C367:0000002800281228123834282A3849280028000000800FF803E0041003E00000 +C368:0000000000020002088208820882191E15022282CC4200020002000200020000 +C369:0000000800081208120834382A08490800080000000007F80008000800080000 +C36A:0000000800081208120834382A0849080008000000003EF80208020802080000 +C36B:0000000800081208120834382A0849080008000000001F080108011401620000 +C36C:0000000800081208120834382A0849080008000000001000100010001FF80000 +C36D:0000000800081208120834382A08490800080000000020F8201020303ECC0000 +C36E:0000000800081208120834382A08490800080000202021FC207020883E700000 +C36F:0000000800081208120834382A0849080008000003F802000200020003F80000 +C370:0000000800081208120834382A0849080008000007F8000807F8040007F80000 +C371:0000000800081208120834382A084908000800003EF802083E0820083E080000 +C372:0000000800081208120834382A084908000800003EF802883E8820883EF80000 +C373:0000000800081208120834382A084908000800003E8802883EF820883EF80000 +C374:0000000800081208120834382A084908000800000F8800880F8808140FA20000 +C375:0000000800081208120834382A084908000800003EF802803EF820803EF80000 +C376:0000000800081208120834382A084908000800003EFC02483E4820483EFC0000 +C377:0000000800081208120834382A084908000800003E1002FE3E3820443E380000 +C378:0000000800081208120834382A0849080008000003F802080208020803F80000 +C379:0000000800081208120834382A084908000800000208020803F8020803F80000 +C37A:0000000800081208120834382A08490800080000210821083F0821143F620000 +C37B:0000000800081208120834382A08490800080000001000100010006801840000 +C37C:0000000800081208120834382A084908000800000048004800A8011406620000 +C37D:0000000800081208120834382A08490800080000000003F00408040803F00000 +C37E:0000000800081208120834382A0849080008000003F80020002000D003080000 +C37F:0000000800081208120834382A08490800080000004003F8004000A003180000 +C380:0000000800081208120834382A0849080008000003F8000803F8000800080000 +C381:0000000800081208120834382A0849080008000003F8020003F8020003F80000 +C382:0000000800081208120834382A0849080008000000000FF8022002200FF80000 +C383:0000000800081208120834382A0849080008000000800FF803E0041003E00000 +C384:00000000000A000A088A088A088A193A150A228ACC4A000A000A000A000A0000 +C385:0000002800281228122834E82A2849280028000007F800080008000800080000 +C386:0000002800281228122834E82A2849280028000000003EF80208020802080000 +C387:0000002800281228122834E82A2849280028000000003E100210022802C40000 +C388:0000002800281228122834E82A2849280028000008000800080008000FF80000 +C389:0000002800281228122834E82A28492800280000000020F8201020303ECC0000 +C38A:0000002800281228122834E82A28492800280000202021FC207020883E700000 +C38B:0000002800281228122834E82A2849280028000003F802000200020003F80000 +C38C:0000002800281228122834E82A2849280028000007F8000807F8040007F80000 +C38D:0000002800281228122834E82A284928002800003EF802083E0820083E080000 +C38E:0000002800281228122834E82A284928002800003EF802883E8820883EF80000 +C38F:0000002800281228122834E82A284928002800003E8802883EF820883EF80000 +C390:0000002800281228122834E82A284928002800001F0801081F0810141F620000 +C391:0000002800281228122834E82A284928002800003EF802803EF820803EF80000 +C392:0000002800281228122834E82A284928002800003EFC02483E4820483EFC0000 +C393:0000002800281228122834E82A284928002800003E1002FE3E3820443E380000 +C394:0000002800281228122834E82A2849280028000003F802080208020803F80000 +C395:0000002800281228122834E82A284928002800000208020803F8020803F80000 +C396:0000002800281228122834E82A28492800280000110811081F0811141F620000 +C397:0000002800281228122834E82A28492800280000000800080008003400C20000 +C398:0000002800281228122834E82A284928002800000048004800A8011406620000 +C399:0000002800281228122834E82A28492800280000000001F00208020801F00000 +C39A:0000002800281228122834E82A2849280028000003F80020002000D003080000 +C39B:0000002800281228122834E82A28492800280000004003F8004000A003180000 +C39C:0000002800281228122834E82A2849280028000003F8000803F8000800080000 +C39D:0000002800281228122834E82A2849280028000003F8020003F8020003F80000 +C39E:0000002800281228122834E82A2849280028000000000FF8022002200FF80000 +C39F:0000002800281228122834E82A2849280028000000800FF803E0041003E00000 +C3A0:000000000002000208820882089E19021502229ECC4200020002000200020000 +C3A1:0000000800081208123834082A38490800080000000007F80008000800080000 +C3A2:0000000800081208123834082A3849080008000000003EF80208020802080000 +C3A3:0000000800081208123834082A3849080008000000001F080108011401620000 +C3A4:0000000800081208123834082A3849080008000800001000100010001FF80000 +C3A5:0000000800081208123834082A38490800080000000020F8201020303ECC0000 +C3A6:0000000800081208123834082A38490800080000202021FC207020883E700000 +C3A7:0000000800081208123834082A3849080008000003F802000200020003F80000 +C3A8:0000000800081208123834082A3849080008000007F8000807F8040007F80000 +C3A9:0000000800081208123834082A384908000800003EF802083E0820083E080000 +C3AA:0000000800081208123834082A384908000800003EF802883E8820883EF80000 +C3AB:0000000800081208123834082A384908000800003E8802883EF820883EF80000 +C3AC:0000000800081208123834082A384908000800000F8800880F8808140FA20000 +C3AD:0000000800081208123834082A384908000800003EF802803EF820803EF80000 +C3AE:0000000800081208123834082A384908000800003EFC02483E4820483EFC0000 +C3AF:0000000800081208123834082A384908000800003E1002FE3E3820443E380000 +C3B0:0000000800081208123834082A3849080008000003F802080208020803F80000 +C3B1:0000000800081208123834082A384908000800000208020803F8020803F80000 +C3B2:0000000800081208123834082A38490800080000210821083F0821143F620000 +C3B3:0000000800081208123834082A38490800080000001000100010006801840000 +C3B4:0000000800081208123834082A384908000800000048004800A8011406620000 +C3B5:0000000800081208123834082A38490800080000000003F00408040803F00000 +C3B6:0000000800081208123834082A3849080008000003F80020002000D003080000 +C3B7:0000000800081208123834082A38490800080000004003F8004000A003180000 +C3B8:0000000800081208123834082A3849080008000003F8000803F8000800080000 +C3B9:0000000800081208123834082A3849080008000003F8020003F8020003F80000 +C3BA:0000000800081208123834082A3849080008000000000FF8022002200FF80000 +C3BB:0000000800081208123834082A3849080008000000800FF803E0041003E00000 +C3BC:00000000000A000A088A088A08BA190A150A22BACC4A000A000A000A000A0000 +C3BD:000000280028122812E834282AE849280028000007F800080008000800080000 +C3BE:000000280028122812E834282AE849280028000000003EF80208020802080000 +C3BF:000000280028122812E834282AE849280028000000003E100210022802C40000 +C3C0:000000280028122812E834282AE849280028002808000800080008000FF80000 +C3C1:000000280028122812E834282AE8492800280000000020F8201020303ECC0000 +C3C2:000000280028122812E834282AE8492800280000202021FC207020883E700000 +C3C3:000000280028122812E834282AE849280028000003F802000200020003F80000 +C3C4:000000280028122812E834282AE849280028000007F8000807F8040007F80000 +C3C5:000000280028122812E834282AE84928002800003EF802083E0820083E080000 +C3C6:000000280028122812E834282AE84928002800003EF802883E8820883EF80000 +C3C7:000000280028122812E834282AE84928002800003E8802883EF820883EF80000 +C3C8:000000280028122812E834282AE84928002800001F0801081F0810141F620000 +C3C9:000000280028122812E834282AE84928002800003EF802803EF820803EF80000 +C3CA:000000280028122812E834282AE84928002800003EFC02483E4820483EFC0000 +C3CB:000000280028122812E834282AE84928002800003E1002FE3E3820443E380000 +C3CC:000000280028122812E834282AE849280028000003F802080208020803F80000 +C3CD:000000280028122812E834282AE84928002800000208020803F8020803F80000 +C3CE:000000280028122812E834282AE8492800280000110811081F0811141F620000 +C3CF:000000280028122812E834282AE8492800280000000800080008003400C20000 +C3D0:000000280028122812E834282AE84928002800000048004800A8011406620000 +C3D1:000000280028122812E834282AE8492800280000000001F00208020801F00000 +C3D2:000000280028122812E834282AE849280028000003F80020002000D003080000 +C3D3:000000280028122812E834282AE8492800280000004003F8004000A003180000 +C3D4:000000280028122812E834282AE849280028000003F8000803F8000800080000 +C3D5:000000280028122812E834282AE849280028000003F8020003F8020003F80000 +C3D6:000000280028122812E834282AE849280028000000000FF8022002200FF80000 +C3D7:000000280028122812E834282AE849280028000000800FF803E0041003E00000 +C3D8:0000000000000220022002200640054008A033100100010001007FFC00000000 +C3D9:000000000220022004400AA0111001007FFC00001FF000100010001000100000 +C3DA:000000000220022004400AA0111001007FFC000000003EF80208020802080000 +C3DB:000000000220022004400AA0111001007FFC000000001E100210022802C40000 +C3DC:000000000220022004400AA0111001007FFC000000001000100010001FF00000 +C3DD:000000000220022004400AA0111001007FFC0000000020F8201020303ECC0000 +C3DE:000000000220022004400AA0111001007FFC0000202021FC207020883E700000 +C3DF:000000000220022004400AA0111001007FFC00001FF01000100010001FF00000 +C3E0:000000000220022004400AA0111001007FFC00001FF000101FF010001FF00000 +C3E1:000000000220022004400AA0111001007FFC00003EF802083E0820083E080000 +C3E2:000000000220022004400AA0111001007FFC00003EF802883E8820883EF80000 +C3E3:000000000220022004400AA0111001007FFC00003E8802883EF820883EF80000 +C3E4:000000000220022004400AA0111001007FFC00003E1002103E1020283EC40000 +C3E5:000000000220022004400AA0111001007FFC00003EF802803EF820803EF80000 +C3E6:000000000220022004400AA0111001007FFC00003EFC02483E4820483EFC0000 +C3E7:000000000220022004400AA0111001007FFC00003E2003FC3E7020883E700000 +C3E8:000000000220022004400AA0111001007FFC00001FF01010101010101FF00000 +C3E9:000000000220022004400AA0111001007FFC0000101010101FF010101FF00000 +C3EA:000000000220022004400AA0111001007FFC0000222022203E2022503E880000 +C3EB:000000000220022004400AA0111001007FFC000000000100010002800C400000 +C3EC:000000000220022004400AA0111001007FFC00000000024002400DA033100000 +C3ED:000000000220022004400AA0111001007FFC0000000007C00820082007C00000 +C3EE:000000000220022004400AA0111001007FFC0000000007E00080014006200000 +C3EF:000000000220022004400AA0111001007FFC0000008007E00080014006200000 +C3F0:000000000220022004400AA0111001007FFC00001FF000101FF0001000100000 +C3F1:000000000220022004400AA0111001007FFC00001FF010001FF010001FF00000 +C3F2:000000000220022004400AA0111001007FFC000000001FF0044004401FF00000 +C3F3:000000000220022004400AA0111001007FFC000001001FF007C0082007C00000 +C3F4:0000001000100890089008901910151E2290CC50041004107FD0001000100000 +C3F5:00000888088811082A8E4448040804087FE8000007F800080008000800080000 +C3F6:00000888088811082A8E4448040804087FE8000000003EF80208020802080000 +C3F7:00000888088811082A8E4448040804087FE8000000001F080108011401620000 +C3F8:00000888088811082A8E4448040804087FE8000008000800080008000FF80000 +C3F9:00000888088811082A8E4448040804087FE80000000010F8101010301ECC0000 +C3FA:00000888088811082A8E4448040804087FE800000808087F081C08220F9C0000 +C3FB:00000888088811082A8E4448040804087FE8000003F802000200020003F80000 +C3FC:00000888088811082A8E4448040804087FE8000007F8000807F8040007F80000 +C3FD:00000888088811082A8E4448040804087FE800003EF802083E0820083E080000 +C3FE:00000888088811082A8E4448040804087FE800003EF802883E8820883EF80000 +C3FF:00000888088811082A8E4448040804087FE800003E8802883EF820883EF80000 +C400:00000888088811082A8E4448040804087FE800001F0801081F0810141F620000 +C401:00000888088811082A8E4448040804087FE800003EF802803EF820803EF80000 +C402:00000888088811082A8E4448040804087FE800003EFC02483E4820483EFC0000 +C403:00000888088811082A8E4448040804087FE800001F08017F1F1C10221F1C0000 +C404:00000888088811082A8E4448040804087FE8000003F802080208020803F80000 +C405:00000888088811082A8E4448040804087FE800000208020803F8020803F80000 +C406:00000888088811082A8E4448040804087FE80000110811081F0811141F620000 +C407:00000888088811082A8E4448040804087FE80000001000100010006801840000 +C408:00000888088811082A8E4448040804087FE800000048004800A8011406620000 +C409:00000888088811082A8E4448040804087FE80000000003F00408040803F00000 +C40A:00000888088811082A8E4448040804087FE8000003F80020002000D003080000 +C40B:00000888088811082A8E4448040804087FE80000004003F8004000A003180000 +C40C:00000888088811082A8E4448040804087FE8000003F8000803F8000800080000 +C40D:00000888088811082A8E4448040804087FE8000003F8020003F8020003F80000 +C40E:00000888088811082A8E4448040804087FE8000000000FF8022002200FF80000 +C40F:00000888088811082A8E4448040804087FE8000000800FF803E0041003E00000 +C410:0000001200120892089208921912151E2292CC52041204127FD2001200120000 +C411:000008A808A811282AB84468042804287FA8000007F800080008000800080000 +C412:000008A808A811282AB84468042804287FA8000000003EF80208020802080000 +C413:000008A808A811282AB84468042804287FA8000000001F080108011401620000 +C414:000008A808A811282AB84468042804287FA8000008000800080008000FF80000 +C415:000008A808A811282AB84468042804287FA80000000010F8101010301ECC0000 +C416:000008A808A811282AB84468042804287FA800000808087F081C08220F9C0000 +C417:000008A808A811282AB84468042804287FA8000003F802000200020003F80000 +C418:000008A808A811282AB84468042804287FA8000007F8000807F8040007F80000 +C419:000008A808A811282AB84468042804287FA800003EF802083E0820083E080000 +C41A:000008A808A811282AB84468042804287FA800003EF802883E8820883EF80000 +C41B:000008A808A811282AB84468042804287FA800003E8802883EF820883EF80000 +C41C:000008A808A811282AB84468042804287FA800001F0801081F0810141F620000 +C41D:000008A808A811282AB84468042804287FA800003EF802803EF820803EF80000 +C41E:000008A808A811282AB84468042804287FA800003EFC02483E4820483EFC0000 +C41F:000008A808A811282AB84468042804287FA800001F08017F1F1C10221F1C0000 +C420:000008A808A811282AB84468042804287FA8000003F802080208020803F80000 +C421:000008A808A811282AB84468042804287FA800000208020803F8020803F80000 +C422:000008A808A811282AB84468042804287FA80000110811081F0811141F620000 +C423:000008A808A811282AB84468042804287FA80000001000100010006801840000 +C424:000008A808A811282AB84468042804287FA800000048004800A8011406620000 +C425:000008A808A811282AB84468042804287FA80000000003F00408040803F00000 +C426:000008A808A811282AB84468042804287FA8000003F80020002000D003080000 +C427:000008A808A811282AB84468042804287FA80000004003F8004000A003180000 +C428:000008A808A811282AB84468042804287FA8000003F8000803F8000800080000 +C429:000008A808A811282AB84468042804287FA8000003F8020003F8020003F80000 +C42A:000008A808A811282AB84468042804287FA8000000000FF8022002200FF80000 +C42B:000008A808A811282AB84468042804287FA8000000800FF803E0041003E00000 +C42C:000000080008088808880888190815082288CC48040804087FE8000800080000 +C42D:00000888088811082A884448040804087FE8000007F800080008000800080000 +C42E:00000888088811082A884448040804087FE8000000003EF80208020802080000 +C42F:00000888088811082A884448040804087FE8000000001F080108011401620000 +C430:00000888088811082A884448040804087FE8000008000800080008000FF80000 +C431:00000888088811082A884448040804087FE80000000010F8101010301ECC0000 +C432:00000888088811082A884448040804087FE800000808087F081C08220F9C0000 +C433:00000888088811082A884448040804087FE8000003F802000200020003F80000 +C434:00000888088811082A884448040804087FE8000007F8000807F8040007F80000 +C435:00000888088811082A884448040804087FE800003EF802083E0820083E080000 +C436:00000888088811082A884448040804087FE800003EF802883E8820883EF80000 +C437:00000888088811082A884448040804087FE800003E8802883EF820883EF80000 +C438:00000888088811082A884448040804087FE800001F0801081F0810141F620000 +C439:00000888088811082A884448040804087FE800003EF802803EF820803EF80000 +C43A:00000888088811082A884448040804087FE800003EFC02483E4820483EFC0000 +C43B:00000888088811082A884448040804087FE800001F08017F1F1C10221F1C0000 +C43C:00000888088811082A884448040804087FE8000003F802080208020803F80000 +C43D:00000888088811082A884448040804087FE800000208020803F8020803F80000 +C43E:00000888088811082A884448040804087FE80000110811081F0811141F620000 +C43F:00000888088811082A884448040804087FE80000001000100010006801840000 +C440:00000888088811082A884448040804087FE800000048004800A8011406620000 +C441:00000888088811082A884448040804087FE80000000003F00408040803F00000 +C442:00000888088811082A884448040804087FE8000003F80020002000D003080000 +C443:00000888088811082A884448040804087FE80000004003F8004000A003180000 +C444:00000888088811082A884448040804087FE8000003F8000803F8000800080000 +C445:00000888088811082A884448040804087FE8000003F8020003F8020003F80000 +C446:00000888088811082A884448040804087FE8000000000FF8022002200FF80000 +C447:00000888088811082A884448040804087FE8000000800FF803E0041003E00000 +C448:0000000000000220022002200640054008A037500440044004407FFC00000000 +C449:000000000220022004400AA0155004407FFC00001FF000100010001000100000 +C44A:000000000220022004400AA0155004407FFC000000003EF80208020802080000 +C44B:000000000220022004400AA0155004407FFC000000001E100210022802C40000 +C44C:000000000220022004400AA0155004407FFC000000001000100010001FF00000 +C44D:000000000220022004400AA0155004407FFC0000000020F8201020303ECC0000 +C44E:000000000220022004400AA0155004407FFC0000202021FC207020883E700000 +C44F:000000000220022004400AA0155004407FFC00001FF01000100010001FF00000 +C450:000000000220022004400AA0155004407FFC00001FF000101FF010001FF00000 +C451:000000000220022004400AA0155004407FFC00003EF802083E0820083E080000 +C452:000000000220022004400AA0155004407FFC00003EF802883E8820883EF80000 +C453:000000000220022004400AA0155004407FFC00003E8802883EF820883EF80000 +C454:000000000220022004400AA0155004407FFC00003E1002103E1020283EC40000 +C455:000000000220022004400AA0155004407FFC00003EF802803EF820803EF80000 +C456:000000000220022004400AA0155004407FFC00003EFC02483E4820483EFC0000 +C457:000000000220022004400AA0155004407FFC00003E2003FC3E7020883E700000 +C458:000000000220022004400AA0155004407FFC00001FF01010101010101FF00000 +C459:000000000220022004400AA0155004407FFC0000101010101FF010101FF00000 +C45A:000000000220022004400AA0155004407FFC0000222022203E2022503E880000 +C45B:000000000220022004400AA0155004407FFC000000000100010002800C400000 +C45C:000000000220022004400AA0155004407FFC00000000024002400DA033100000 +C45D:000000000220022004400AA0155004407FFC0000000007C00820082007C00000 +C45E:000000000220022004400AA0155004407FFC0000000007E00080014006200000 +C45F:000000000220022004400AA0155004407FFC0000008007E00080014006200000 +C460:000000000220022004400AA0155004407FFC00001FF000101FF0001000100000 +C461:000000000220022004400AA0155004407FFC00001FF010001FF010001FF00000 +C462:000000000220022004400AA0155004407FFC000000001FF0044004401FF00000 +C463:000000000220022004400AA0155004407FFC000001001FF007C0082007C00000 +C464:000000000220022002200640054008A0331000003FF801000100010001000000 +C465:000000000220022004400AA011107FFC010001001FF000100010001000100000 +C466:000000000220022004400AA011107FFC0100010000003EF80208020802080000 +C467:000000000220022004400AA011107FFC0100010000001E100210022802C40000 +C468:000000000220022004400AA0111000007FFC010001001100100010001FF00000 +C469:000000000220022004400AA011107FFC01000100000020F8201020303ECC0000 +C46A:000000000220022004400AA011107FFC01000100202021FC207020883E700000 +C46B:000000000220022004400AA011107FFC010001001FF01000100010001FF00000 +C46C:000000000220022004400AA011107FFC010001001FF000101FF010001FF00000 +C46D:000000000220022004400AA011107FFC010001003EF802083E0820083E080000 +C46E:000000000220022004400AA011107FFC010001003EF802883E8820883EF80000 +C46F:000000000220022004400AA011107FFC010001003E8802883EF820883EF80000 +C470:000000000220022004400AA011107FFC010001003E1002103E1020283EC40000 +C471:000000000220022004400AA011107FFC010001003EF802803EF820803EF80000 +C472:000000000220022004400AA011107FFC010001003EFC02483E4820483EFC0000 +C473:000000000220022004400AA011107FFC010001003E2003FC3E7020883E700000 +C474:000000000220022004400AA011107FFC010001001FF01010101010101FF00000 +C475:000000000220022004400AA011107FFC01000100101010101FF010101FF00000 +C476:000000000220022004400AA011107FFC01000100222022203E2022503E880000 +C477:000000000220022004400AA011107FFC0100010000000100010002800C400000 +C478:000000000220022004400AA011107FFC010001000000024002400DA033100000 +C479:000000000220022004400AA011107FFC01000100000007C00820082007C00000 +C47A:000000000220022004400AA011107FFC01000100000007E00080014006200000 +C47B:000000000220022004400AA011107FFC01000100008007E00080014006200000 +C47C:000000000220022004400AA011107FFC010001001FF000101FF0001000100000 +C47D:000000000220022004400AA011107FFC010001001FF010001FF010001FF00000 +C47E:000000000220022004400AA011107FFC0100010000001FF0044004401FF00000 +C47F:000000000220022004400AA011107FFC0100010001001FF007C0082007C00000 +C480:00000008088808880888190815082288CC4800087FE8040804F8040804080000 +C481:00080888088811082A8844487FE8027802080000000007F80008000800080000 +C482:00080888088811082A8844487FE802780208000000003EF80208020802080000 +C483:00080888088811082A8844487FE802780208000000001F080108011401620000 +C484:00080888088811082A88444800087FE80278020802081000100010001FF80000 +C485:00080888088811082A8844487FE8027802080000000020F8201020303ECC0000 +C486:00080888088811082A8844487FE8027802080000202021FC207020883E700000 +C487:00080888088811082A8844487FE802780208000003F802000200020003F80000 +C488:00080888088811082A8844487FE802780208000007F8000807F8040007F80000 +C489:00080888088811082A8844487FE80278020800003EF802083E0820083E080000 +C48A:00080888088811082A8844487FE80278020800003EF802883E8820883EF80000 +C48B:00080888088811082A8844487FE80278020800003E8802883EF820883EF80000 +C48C:00080888088811082A8844487FE80278020800000F8800880F8808140FA20000 +C48D:00080888088811082A8844487FE80278020800003EF802803EF820803EF80000 +C48E:00080888088811082A8844487FE80278020800003EFC02483E4820483EFC0000 +C48F:00080888088811082A8844487FE80278020800003E1002FE3E3820443E380000 +C490:00080888088811082A8844487FE802780208000003F802080208020803F80000 +C491:00080888088811082A8844487FE80278020800000208020803F8020803F80000 +C492:00080888088811082A8844487FE8027802080000210821083F0821143F620000 +C493:00080888088811082A8844487FE8027802080000001000100010006801840000 +C494:00080888088811082A8844487FE80278020800000048004800A8011406620000 +C495:00080888088811082A8844487FE8027802080000000003F00408040803F00000 +C496:00080888088811082A8844487FE802780208000003F80020002000D003080000 +C497:00080888088811082A8844487FE8027802080000004003F8004000A003180000 +C498:00080888088811082A8844487FE802780208000003F8000803F8000800080000 +C499:00080888088811082A8844487FE802780208000003F8020003F8020003F80000 +C49A:00080888088811082A8844487FE802780208000000000FF8022002200FF80000 +C49B:00080888088811082A8844487FE802780208000000800FF803E0041003E00000 +C49C:0000000A088A088A088A190A150A228ACC4A000A7FEA040A047A040A040A0000 +C49D:002808A808A811282AA844687FA805E804280000000007F80008000800080000 +C49E:002808A808A811282AA844687FA805E80428000000003EF80208020802080000 +C49F:002808A808A811282AA844687FA805E80428000000001F080108011401620000 +C4A0:002808A808A811282AA8446800287FA8042805E804281428100010001FF80000 +C4A1:002808A808A811282AA844687FA805E804280000000020F8201020303ECC0000 +C4A2:002808A808A811282AA844687FA805E804280000202021FC207020883E700000 +C4A3:002808A808A811282AA844687FA805E80428000003F802000200020003F80000 +C4A4:002808A808A811282AA844687FA805E80428000007F8000807F8040007F80000 +C4A5:002808A808A811282AA844687FA805E8042800003EF802083E0820083E080000 +C4A6:002808A808A811282AA844687FA805E8042800003EF802883E8820883EF80000 +C4A7:002808A808A811282AA844687FA805E8042800003E8802883EF820883EF80000 +C4A8:002808A808A811282AA844687FA805E8042800000F8800880F8808140FA20000 +C4A9:002808A808A811282AA844687FA805E8042800003EF802803EF820803EF80000 +C4AA:002808A808A811282AA844687FA805E8042800003EFC02483E4820483EFC0000 +C4AB:002808A808A811282AA844687FA805E8042800003E1002FE3E3820443E380000 +C4AC:002808A808A811282AA844687FA805E80428000003F802080208020803F80000 +C4AD:002808A808A811282AA844687FA805E8042800000208020803F8020803F80000 +C4AE:002808A808A811282AA844687FA805E804280000210821083F0821143F620000 +C4AF:002808A808A811282AA844687FA805E804280000001000100010006801840000 +C4B0:002808A808A811282AA844687FA805E8042800000048004800A8011406620000 +C4B1:002808A808A811282AA844687FA805E804280000000003F00408040803F00000 +C4B2:002808A808A811282AA844687FA805E80428000003F80020002000D003080000 +C4B3:002808A808A811282AA844687FA805E804280000004003F8004000A003180000 +C4B4:002808A808A811282AA844687FA805E80428000003F8000803F8000800080000 +C4B5:002808A808A811282AA844687FA805E80428000003F8020003F8020003F80000 +C4B6:002808A808A811282AA844687FA805E80428000000000FF8022002200FF80000 +C4B7:002808A808A811282AA844687FA805E80428000000800FF803E0041003E00000 +C4B8:00000008088808880888190815082288CC4800087FE804080408040804080000 +C4B9:00080888088811082A8844487FE8020802000000000007F80008000800080000 +C4BA:00080888088811082A8844487FE802080200000000003EF80208020802080000 +C4BB:00080888088811082A8844487FE802080200000000001F080108011401620000 +C4BC:00080888088811082A88444800087FE80208020802081008100010001FF80000 +C4BD:00080888088811082A8844487FE8020802000000000020F8201020303ECC0000 +C4BE:00080888088811082A8844487FE8020802000000202021FC207020883E700000 +C4BF:00080888088811082A8844487FE802080200000003F802000200020003F80000 +C4C0:00080888088811082A8844487FE802080200000007F8000807F8040007F80000 +C4C1:00080888088811082A8844487FE80208020000003EF802083E0820083E080000 +C4C2:00080888088811082A8844487FE80208020000003EF802883E8820883EF80000 +C4C3:00080888088811082A8844487FE80208020000003E8802883EF820883EF80000 +C4C4:00080888088811082A8844487FE80208020000000F8800880F8808140FA20000 +C4C5:00080888088811082A8844487FE80208020000003EF802803EF820803EF80000 +C4C6:00080888088811082A8844487FE80208020000003EFC02483E4820483EFC0000 +C4C7:00080888088811082A8844487FE80208020000003E1002FE3E3820443E380000 +C4C8:00080888088811082A8844487FE802080200000003F802080208020803F80000 +C4C9:00080888088811082A8844487FE80208020000000208020803F8020803F80000 +C4CA:00080888088811082A8844487FE8020802000000210821083F0821143F620000 +C4CB:00080888088811082A8844487FE8020802000000001000100010006801840000 +C4CC:00080888088811082A8844487FE80208020000000048004800A8011406620000 +C4CD:00080888088811082A8844487FE8020802000000000003F00408040803F00000 +C4CE:00080888088811082A8844487FE802080200000003F80020002000D003080000 +C4CF:00080888088811082A8844487FE8020802000000004003F8004000A003180000 +C4D0:00080888088811082A8844487FE802080200000003F8000803F8000800080000 +C4D1:00080888088811082A8844487FE802080200000003F8020003F8020003F80000 +C4D2:00080888088811082A8844487FE802080200000000000FF8022002200FF80000 +C4D3:00080888088811082A8844487FE802080200000000800FF803E0041003E00000 +C4D4:000000000220022002200640054008A0331000007FFC04400440044004400000 +C4D5:000000000220022004400AA011107FFC044004401FF000100010001000100000 +C4D6:000000000220022004400AA011107FFC0440044000003EF80208020802080000 +C4D7:000000000220022004400AA011107FFC0440044000001E100210022802C40000 +C4D8:000000000220022004400AA0111000007FFC044004401440100010001FF00000 +C4D9:000000000220022004400AA011107FFC04400440000020F8201020303ECC0000 +C4DA:000000000220022004400AA011107FFC04400440202021FC207020883E700000 +C4DB:000000000220022004400AA011107FFC044004401FF01000100010001FF00000 +C4DC:000000000220022004400AA011107FFC044004401FF000101FF010001FF00000 +C4DD:000000000220022004400AA011107FFC044004403EF802083E0820083E080000 +C4DE:000000000220022004400AA011107FFC044004403EF802883E8820883EF80000 +C4DF:000000000220022004400AA011107FFC044004403E8802883EF820883EF80000 +C4E0:000000000220022004400AA011107FFC044004403E1002103E1020283EC40000 +C4E1:000000000220022004400AA011107FFC044004403EF802803EF820803EF80000 +C4E2:000000000220022004400AA011107FFC044004403EFC02483E4820483EFC0000 +C4E3:000000000220022004400AA011107FFC044004403E2003FC3E7020883E700000 +C4E4:000000000220022004400AA011107FFC044004401FF01010101010101FF00000 +C4E5:000000000220022004400AA011107FFC04400440101010101FF010101FF00000 +C4E6:000000000220022004400AA011107FFC04400440222022203E2022503E880000 +C4E7:000000000220022004400AA011107FFC0440044000000100010002800C400000 +C4E8:000000000220022004400AA011107FFC044004400000024002400DA033100000 +C4E9:000000000220022004400AA011107FFC04400440000007C00820082007C00000 +C4EA:000000000220022004400AA011107FFC04400440000007E00080014006200000 +C4EB:000000000220022004400AA011107FFC04400440008007E00080014006200000 +C4EC:000000000220022004400AA011107FFC044004401FF000101FF0001000100000 +C4ED:000000000220022004400AA011107FFC044004401FF010001FF010001FF00000 +C4EE:000000000220022004400AA011107FFC0440044000001FF0044004401FF00000 +C4EF:000000000220022004400AA011107FFC0440044001001FF007C0082007C00000 +C4F0:0000000000000220022002200640054008A0331000007FFC0000000000000000 +C4F1:000000000220022004400AA0111000007FFC00001FF000100010001000100000 +C4F2:000000000220022004400AA0111000007FFC000000003EF80208020802080000 +C4F3:000000000220022004400AA0111000007FFC000000001E100210022802C40000 +C4F4:000000000220022004400AA0111000007FFC000000001000100010001FF00000 +C4F5:000000000220022004400AA0111000007FFC0000000020F8201020303ECC0000 +C4F6:000000000220022004400AA0111000007FFC0000202021FC207020883E700000 +C4F7:000000000220022004400AA0111000007FFC00001FF01000100010001FF00000 +C4F8:000000000220022004400AA0111000007FFC00001FF000101FF010001FF00000 +C4F9:000000000220022004400AA0111000007FFC00003EF802083E0820083E080000 +C4FA:000000000220022004400AA0111000007FFC00003EF802883E8820883EF80000 +C4FB:000000000220022004400AA0111000007FFC00003E8802883EF820883EF80000 +C4FC:000000000220022004400AA0111000007FFC00003E1002103E1020283EC40000 +C4FD:000000000220022004400AA0111000007FFC00003EF802803EF820803EF80000 +C4FE:000000000220022004400AA0111000007FFC00003EFC02483E4820483EFC0000 +C4FF:000000000220022004400AA0111000007FFC00003E2003FC3E7020883E700000 +C500:000000000220022004400AA0111000007FFC00001FF01010101010101FF00000 +C501:000000000220022004400AA0111000007FFC0000101010101FF010101FF00000 +C502:000000000220022004400AA0111000007FFC0000222022203E2022503E880000 +C503:000000000220022004400AA0111000007FFC000000000100010002800C400000 +C504:000000000220022004400AA0111000007FFC00000000024002400DA033100000 +C505:000000000220022004400AA0111000007FFC0000000007C00820082007C00000 +C506:000000000220022004400AA0111000007FFC0000000007E00080014006200000 +C507:000000000220022004400AA0111000007FFC0000008007E00080014006200000 +C508:000000000220022004400AA0111000007FFC00001FF000101FF0001000100000 +C509:000000000220022004400AA0111000007FFC00001FF010001FF010001FF00000 +C50A:000000000220022004400AA0111000007FFC000000001FF0044004401FF00000 +C50B:000000000220022004400AA0111000007FFC000001001FF007C0082007C00000 +C50C:000000080008088808880888190815082288CC4800087FE80008000800080000 +C50D:00000888088811082A884448000800087FE8000007F800080008000800080000 +C50E:00000888088811082A884448000800087FE8000000003EF80208020802080000 +C50F:00000888088811082A884448000800087FE8000000001F080108011401620000 +C510:00000888088811082A884448000800087FE8000008000800080008000FF80000 +C511:00000888088811082A884448000800087FE80000000010F8101010301ECC0000 +C512:00000888088811082A884448000800087FE800000808087F081C08220F9C0000 +C513:00000888088811082A884448000800087FE8000003F802000200020003F80000 +C514:00000888088811082A884448000800087FE8000007F8000807F8040007F80000 +C515:00000888088811082A884448000800087FE800003EF802083E0820083E080000 +C516:00000888088811082A884448000800087FE800003EF802883E8820883EF80000 +C517:00000888088811082A884448000800087FE800003E8802883EF820883EF80000 +C518:00000888088811082A884448000800087FE800001F0801081F0810141F620000 +C519:00000888088811082A884448000800087FE800003EF802803EF820803EF80000 +C51A:00000888088811082A884448000800087FE800003EFC02483E4820483EFC0000 +C51B:00000888088811082A884448000800087FE800001F08017F1F1C10221F1C0000 +C51C:00000888088811082A884448000800087FE8000003F802080208020803F80000 +C51D:00000888088811082A884448000800087FE800000208020803F8020803F80000 +C51E:00000888088811082A884448000800087FE80000110811081F0811141F620000 +C51F:00000888088811082A884448000800087FE80000001000100010006801840000 +C520:00000888088811082A884448000800087FE800000048004800A8011406620000 +C521:00000888088811082A884448000800087FE80000000003F00408040803F00000 +C522:00000888088811082A884448000800087FE8000003F80020002000D003080000 +C523:00000888088811082A884448000800087FE80000004003F8004000A003180000 +C524:00000888088811082A884448000800087FE8000003F8000803F8000800080000 +C525:00000888088811082A884448000800087FE8000003F8020003F8020003F80000 +C526:00000888088811082A884448000800087FE8000000000FF8022002200FF80000 +C527:00000888088811082A884448000800087FE8000000800FF803E0041003E00000 +C528:0000000000080008088808880888190815082288CC4800080008000800080000 +C529:0000000800081208120834082A08490800080000000007F80008000800080000 +C52A:0000000800081208120834082A0849080008000000003EF80208020802080000 +C52B:0000000800081208120834082A0849080008000000001F080108011401620000 +C52C:0000000800081208120834082A0849080008000800001000100010001FF80000 +C52D:0000000800081208120834082A08490800080000000020F8201020303ECC0000 +C52E:0000000800081208120834082A08490800080000202021FC207020883E700000 +C52F:0000000800081208120834082A0849080008000003F802000200020003F80000 +C530:0000000800081208120834082A0849080008000007F8000807F8040007F80000 +C531:0000000800081208120834082A084908000800003EF802083E0820083E080000 +C532:0000000800081208120834082A084908000800003EF802883E8820883EF80000 +C533:0000000800081208120834082A084908000800003E8802883EF820883EF80000 +C534:0000000800081208120834082A084908000800000F8800880F8808140FA20000 +C535:0000000800081208120834082A084908000800003EF802803EF820803EF80000 +C536:0000000800081208120834082A084908000800003EFC02483E4820483EFC0000 +C537:0000000800081208120834082A084908000800003E1002FE3E3820443E380000 +C538:0000000800081208120834082A0849080008000003F802080208020803F80000 +C539:0000000800081208120834082A084908000800000208020803F8020803F80000 +C53A:0000000800081208120834082A08490800080000210821083F0821143F620000 +C53B:0000000800081208120834082A08490800080000001000100010006801840000 +C53C:0000000800081208120834082A084908000800000048004800A8011406620000 +C53D:0000000800081208120834082A08490800080000000003F00408040803F00000 +C53E:0000000800081208120834082A0849080008000003F80020002000D003080000 +C53F:0000000800081208120834082A08490800080000004003F8004000A003180000 +C540:0000000800081208120834082A0849080008000003F8000803F8000800080000 +C541:0000000800081208120834082A0849080008000003F8020003F8020003F80000 +C542:0000000800081208120834082A0849080008000000000FF8022002200FF80000 +C543:0000000800081208120834082A0849080008000000800FF803E0041003E00000 +C544:00000000001000101E1021104090409E409021101E1000100010001000100000 +C545:000000081E0821082108210E21081E080008000007F800080008000800080000 +C546:000000081E0821082108210E21081E080008000000003EF80208020802080000 +C547:000000081E0821082108210E21081E080008000000001F080108011401620000 +C548:000000081E0821082108210E21081E080008000808000800080008000FF80000 +C549:000000081E0821082108210E21081E0800080000000010F8101010301ECC0000 +C54A:000000081E0821082108210E21081E08000800000808087F081C08220F9C0000 +C54B:000000081E0821082108210E21081E080008000003F802000200020003F80000 +C54C:000000081E0821082108210E21081E080008000007F8000807F8040007F80000 +C54D:000000081E0821082108210E21081E08000800003EF802083E0820083E080000 +C54E:000000081E0821082108210E21081E08000800003EF802883E8820883EF80000 +C54F:000000081E0821082108210E21081E08000800003E8802883EF820883EF80000 +C550:000000081E0821082108210E21081E08000800001F0801081F0810141F620000 +C551:000000081E0821082108210E21081E08000800003EF802803EF820803EF80000 +C552:000000081E0821082108210E21081E08000800003EFC02483E4820483EFC0000 +C553:000000081E0821082108210E21081E08000800001F08017F1F1C10221F1C0000 +C554:000000081E0821082108210E21081E080008000003F802080208020803F80000 +C555:000000081E0821082108210E21081E08000800000208020803F8020803F80000 +C556:000000081E0821082108210E21081E0800080000110811081F0811141F620000 +C557:000000081E0821082108210E21081E0800080000001000100010006801840000 +C558:000000081E0821082108210E21081E08000800000048004800A8011406620000 +C559:000000081E0821082108210E21081E0800080000000003F00408040803F00000 +C55A:000000081E0821082108210E21081E080008000003F80020002000D003080000 +C55B:000000081E0821082108210E21081E0800080000004003F8004000A003180000 +C55C:000000081E0821082108210E21081E080008000003F8000803F8000800080000 +C55D:000000081E0821082108210E21081E080008000003F8020003F8020003F80000 +C55E:000000081E0821082108210E21081E080008000000000FF8022002200FF80000 +C55F:000000081E0821082108210E21081E080008000000800FF803E0041003E00000 +C560:00000000001200121E1221124092409E409221121E1200120012001200120000 +C561:000000281E2821282128213821281E280028000007F800080008000800080000 +C562:000000281E2821282128213821281E280028000000003EF80208020802080000 +C563:000000281E2821282128213821281E280028000000003E100210022802C40000 +C564:000000281E2821282128213821281E280028002808000800080008000FF80000 +C565:000000281E2821282128213821281E2800280000000020F8201020303ECC0000 +C566:000000281E2821282128213821281E2800280000202021FC207020883E700000 +C567:000000281E2821282128213821281E280028000003F802000200020003F80000 +C568:000000281E2821282128213821281E280028000007F8000807F8040007F80000 +C569:000000281E2821282128213821281E28002800003EF802083E0820083E080000 +C56A:000000281E2821282128213821281E28002800003EF802883E8820883EF80000 +C56B:000000281E2821282128213821281E28002800003E8802883EF820883EF80000 +C56C:000000281E2821282128213821281E28002800001F0801081F0810141F620000 +C56D:000000281E2821282128213821281E28002800003EF802803EF820803EF80000 +C56E:000000281E2821282128213821281E28002800003EFC02483E4820483EFC0000 +C56F:000000281E2821282128213821281E28002800003E1002FE3E3820443E380000 +C570:000000281E2821282128213821281E280028000003F802080208020803F80000 +C571:000000281E2821282128213821281E28002800000208020803F8020803F80000 +C572:000000281E2821282128213821281E2800280000110811081F0811141F620000 +C573:000000281E2821282128213821281E2800280000000800080008003400C20000 +C574:000000281E2821282128213821281E28002800000048004800A8011406620000 +C575:000000281E2821282128213821281E2800280000000001F00208020801F00000 +C576:000000281E2821282128213821281E280028000003F80020002000D003080000 +C577:000000281E2821282128213821281E2800280000004003F8004000A003180000 +C578:000000281E2821282128213821281E280028000003F8000803F8000800080000 +C579:000000281E2821282128213821281E280028000003F8020003F8020003F80000 +C57A:000000281E2821282128213821281E280028000000000FF8022002200FF80000 +C57B:000000281E2821282128213821281E280028000000800FF803E0041003E00000 +C57C:00000000001000101E102110409E40904090211E1E1000100010001000100000 +C57D:000000081E082108210E2108210E1E080008000007F800080008000800080000 +C57E:000000081E082108210E2108210E1E080008000000003EF80208020802080000 +C57F:000000081E082108210E2108210E1E080008000000001F080108011401620000 +C580:000000081E082108210E2108210E1E080008000008000800080008000FF80000 +C581:000000081E082108210E2108210E1E0800080000000010F8101010301ECC0000 +C582:000000081E082108210E2108210E1E08000800000808087F081C08220F9C0000 +C583:000000081E082108210E2108210E1E080008000003F802000200020003F80000 +C584:000000081E082108210E2108210E1E080008000007F8000807F8040007F80000 +C585:000000081E082108210E2108210E1E08000800003EF802083E0820083E080000 +C586:000000081E082108210E2108210E1E08000800003EF802883E8820883EF80000 +C587:000000081E082108210E2108210E1E08000800003E8802883EF820883EF80000 +C588:000000081E082108210E2108210E1E08000800001F0801081F0810141F620000 +C589:000000081E082108210E2108210E1E08000800003EF802803EF820803EF80000 +C58A:000000081E082108210E2108210E1E08000800003EFC02483E4820483EFC0000 +C58B:000000081E082108210E2108210E1E08000800001F08017F1F1C10221F1C0000 +C58C:000000081E082108210E2108210E1E080008000003F802080208020803F80000 +C58D:000000081E082108210E2108210E1E08000800000208020803F8020803F80000 +C58E:000000081E082108210E2108210E1E0800080000110811081F0811141F620000 +C58F:000000081E082108210E2108210E1E0800080000001000100010006801840000 +C590:000000081E082108210E2108210E1E08000800000048004800A8011406620000 +C591:000000081E082108210E2108210E1E0800080000000003F00408040803F00000 +C592:000000081E082108210E2108210E1E080008000003F80020002000D003080000 +C593:000000081E082108210E2108210E1E0800080000004003F8004000A003180000 +C594:000000081E082108210E2108210E1E080008000003F8000803F8000800080000 +C595:000000081E082108210E2108210E1E080008000003F8020003F8020003F80000 +C596:000000081E082108210E2108210E1E080008000000000FF8022002200FF80000 +C597:000000081E082108210E2108210E1E080008000000800FF803E0041003E00000 +C598:00000000001200121E122112409E40924092211E1E1200120012001200120000 +C599:000000281E2821282138212821381E280028000007F800080008000800080000 +C59A:000000281E2821282138212821381E280028000000003EF80208020802080000 +C59B:000000281E2821282138212821381E280028000000003E100210022802C40000 +C59C:000000281E2821282138212821381E280028002808000800080008000FF80000 +C59D:000000281E2821282138212821381E2800280000000020F8201020303ECC0000 +C59E:000000281E2821282138212821381E2800280000202021FC207020883E700000 +C59F:000000281E2821282138212821381E280028000003F802000200020003F80000 +C5A0:000000281E2821282138212821381E280028000007F8000807F8040007F80000 +C5A1:000000281E2821282138212821381E28002800003EF802083E0820083E080000 +C5A2:000000281E2821282138212821381E28002800003EF802883E8820883EF80000 +C5A3:000000281E2821282138212821381E28002800003E8802883EF820883EF80000 +C5A4:000000281E2821282138212821381E28002800001F0801081F0810141F620000 +C5A5:000000281E2821282138212821381E28002800003EF802803EF820803EF80000 +C5A6:000000281E2821282138212821381E28002800003EFC02483E4820483EFC0000 +C5A7:000000281E2821282138212821381E28002800003E1002FE3E3820443E380000 +C5A8:000000281E2821282138212821381E280028000003F802080208020803F80000 +C5A9:000000281E2821282138212821381E28002800000208020803F8020803F80000 +C5AA:000000281E2821282138212821381E2800280000110811081F0811141F620000 +C5AB:000000281E2821282138212821381E2800280000000800080008003400C20000 +C5AC:000000281E2821282138212821381E28002800000048004800A8011406620000 +C5AD:000000281E2821282138212821381E2800280000000001F00208020801F00000 +C5AE:000000281E2821282138212821381E280028000003F80020002000D003080000 +C5AF:000000281E2821282138212821381E2800280000004003F8004000A003180000 +C5B0:000000281E2821282138212821381E280028000003F8000803F8000800080000 +C5B1:000000281E2821282138212821381E280028000003F8020003F8020003F80000 +C5B2:000000281E2821282138212821381E280028000000000FF8022002200FF80000 +C5B3:000000281E2821282138212821381E280028000000800FF803E0041003E00000 +C5B4:00000000000200021E0221024082409E408221021E0200020002000200020000 +C5B5:000000081E0821082108213821081E0800080000000007F80008000800080000 +C5B6:000000081E0821082108213821081E080008000000003EF80208020802080000 +C5B7:000000081E0821082108213821081E080008000000001F080108011401620000 +C5B8:000000081E0821082108213821081E080008000000001000100010001FF80000 +C5B9:000000081E0821082108213821081E0800080000000020F8201020303ECC0000 +C5BA:000000081E0821082108213821081E0800080000202021FC207020883E700000 +C5BB:000000081E0821082108213821081E080008000003F802000200020003F80000 +C5BC:000000081E0821082108213821081E080008000007F8000807F8040007F80000 +C5BD:000000081E0821082108213821081E08000800003EF802083E0820083E080000 +C5BE:000000081E0821082108213821081E08000800003EF802883E8820883EF80000 +C5BF:000000081E0821082108213821081E08000800003E8802883EF820883EF80000 +C5C0:000000081E0821082108213821081E08000800000F8800880F8808140FA20000 +C5C1:000000081E0821082108213821081E08000800003EF802803EF820803EF80000 +C5C2:000000081E0821082108213821081E08000800003EFC02483E4820483EFC0000 +C5C3:000000081E0821082108213821081E08000800003E1002FE3E3820443E380000 +C5C4:000000081E0821082108213821081E080008000003F802080208020803F80000 +C5C5:000000081E0821082108213821081E08000800000208020803F8020803F80000 +C5C6:000000081E0821082108213821081E0800080000210821083F0821143F620000 +C5C7:000000081E0821082108213821081E0800080000001000100010006801840000 +C5C8:000000081E0821082108213821081E08000800000048004800A8011406620000 +C5C9:000000081E0821082108213821081E0800080000000003F00408040803F00000 +C5CA:000000081E0821082108213821081E080008000003F80020002000D003080000 +C5CB:000000081E0821082108213821081E0800080000004003F8004000A003180000 +C5CC:000000081E0821082108213821081E080008000003F8000803F8000800080000 +C5CD:000000081E0821082108213821081E080008000003F8020003F8020003F80000 +C5CE:000000081E0821082108213821081E080008000000000FF8022002200FF80000 +C5CF:000000081E0821082108213821081E080008000000800FF803E0041003E00000 +C5D0:00000000000A000A1E0A210A408A40BA408A210A1E0A000A000A000A000A0000 +C5D1:000000281E282128212821E821281E280028000007F800080008000800080000 +C5D2:000000281E282128212821E821281E280028000000003EF80208020802080000 +C5D3:000000281E282128212821E821281E280028000000003E100210022802C40000 +C5D4:000000281E282128212821E821281E280028000008000800080008000FF80000 +C5D5:000000281E282128212821E821281E2800280000000020F8201020303ECC0000 +C5D6:000000281E282128212821E821281E2800280000202021FC207020883E700000 +C5D7:000000281E282128212821E821281E280028000003F802000200020003F80000 +C5D8:000000281E282128212821E821281E280028000007F8000807F8040007F80000 +C5D9:000000281E282128212821E821281E28002800003EF802083E0820083E080000 +C5DA:000000281E282128212821E821281E28002800003EF802883E8820883EF80000 +C5DB:000000281E282128212821E821281E28002800003E8802883EF820883EF80000 +C5DC:000000281E282128212821E821281E28002800001F0801081F0810141F620000 +C5DD:000000281E282128212821E821281E28002800003EF802803EF820803EF80000 +C5DE:000000281E282128212821E821281E28002800003EFC02483E4820483EFC0000 +C5DF:000000281E282128212821E821281E28002800003E1002FE3E3820443E380000 +C5E0:000000281E282128212821E821281E280028000003F802080208020803F80000 +C5E1:000000281E282128212821E821281E28002800000208020803F8020803F80000 +C5E2:000000281E282128212821E821281E2800280000110811081F0811141F620000 +C5E3:000000281E282128212821E821281E2800280000000800080008003400C20000 +C5E4:000000281E282128212821E821281E28002800000048004800A8011406620000 +C5E5:000000281E282128212821E821281E2800280000000001F00208020801F00000 +C5E6:000000281E282128212821E821281E280028000003F80020002000D003080000 +C5E7:000000281E282128212821E821281E2800280000004003F8004000A003180000 +C5E8:000000281E282128212821E821281E280028000003F8000803F8000800080000 +C5E9:000000281E282128212821E821281E280028000003F8020003F8020003F80000 +C5EA:000000281E282128212821E821281E280028000000000FF8022002200FF80000 +C5EB:000000281E282128212821E821281E280028000000800FF803E0041003E00000 +C5EC:00000000000200021E022102409E40824082211E1E0200020002000200020000 +C5ED:000000081E0821082138210821381E0800080000000007F80008000800080000 +C5EE:000000081E0821082138210821381E080008000000003EF80208020802080000 +C5EF:000000081E0821082138210821381E080008000000001F080108011401620000 +C5F0:000000081E0821082138210821381E080008000800001000100010001FF80000 +C5F1:000000081E0821082138210821381E0800080000000020F8201020303ECC0000 +C5F2:000000081E0821082138210821381E0800080000202021FC207020883E700000 +C5F3:000000081E0821082138210821381E080008000003F802000200020003F80000 +C5F4:000000081E0821082138210821381E080008000007F8000807F8040007F80000 +C5F5:000000081E0821082138210821381E08000800003EF802083E0820083E080000 +C5F6:000000081E0821082138210821381E08000800003EF802883E8820883EF80000 +C5F7:000000081E0821082138210821381E08000800003E8802883EF820883EF80000 +C5F8:000000081E0821082138210821381E08000800000F8800880F8808140FA20000 +C5F9:000000081E0821082138210821381E08000800003EF802803EF820803EF80000 +C5FA:000000081E0821082138210821381E08000800003EFC02483E4820483EFC0000 +C5FB:000000081E0821082138210821381E08000800003E1002FE3E3820443E380000 +C5FC:000000081E0821082138210821381E080008000003F802080208020803F80000 +C5FD:000000081E0821082138210821381E08000800000208020803F8020803F80000 +C5FE:000000081E0821082138210821381E0800080000210821083F0821143F620000 +C5FF:000000081E0821082138210821381E0800080000001000100010006801840000 +C600:000000081E0821082138210821381E08000800000048004800A8011406620000 +C601:000000081E0821082138210821381E0800080000000003F00408040803F00000 +C602:000000081E0821082138210821381E080008000003F80020002000D003080000 +C603:000000081E0821082138210821381E0800080000004003F8004000A003180000 +C604:000000081E0821082138210821381E080008000003F8000803F8000800080000 +C605:000000081E0821082138210821381E080008000003F8020003F8020003F80000 +C606:000000081E0821082138210821381E080008000000000FF8022002200FF80000 +C607:000000081E0821082138210821381E080008000000800FF803E0041003E00000 +C608:00000000000A000A1E0A210A40BA408A408A213A1E0A000A000A000A000A0000 +C609:000000281E28212821E8212821E81E280028000007F800080008000800080000 +C60A:000000281E28212821E8212821E81E280028000000003EF80208020802080000 +C60B:000000281E28212821E8212821E81E280028000000003E100210022802C40000 +C60C:000000281E28212821E8212821E81E280028002808000800080008000FF80000 +C60D:000000281E28212821E8212821E81E2800280000000020F8201020303ECC0000 +C60E:000000281E28212821E8212821E81E2800280000202021FC207020883E700000 +C60F:000000281E28212821E8212821E81E280028000003F802000200020003F80000 +C610:000000281E28212821E8212821E81E280028000007F8000807F8040007F80000 +C611:000000281E28212821E8212821E81E28002800003EF802083E0820083E080000 +C612:000000281E28212821E8212821E81E28002800003EF802883E8820883EF80000 +C613:000000281E28212821E8212821E81E28002800003E8802883EF820883EF80000 +C614:000000281E28212821E8212821E81E28002800001F0801081F0810141F620000 +C615:000000281E28212821E8212821E81E28002800003EF802803EF820803EF80000 +C616:000000281E28212821E8212821E81E28002800003EFC02483E4820483EFC0000 +C617:000000281E28212821E8212821E81E28002800003E1002FE3E3820443E380000 +C618:000000281E28212821E8212821E81E280028000003F802080208020803F80000 +C619:000000281E28212821E8212821E81E28002800000208020803F8020803F80000 +C61A:000000281E28212821E8212821E81E2800280000110811081F0811141F620000 +C61B:000000281E28212821E8212821E81E2800280000000800080008003400C20000 +C61C:000000281E28212821E8212821E81E28002800000048004800A8011406620000 +C61D:000000281E28212821E8212821E81E2800280000000001F00208020801F00000 +C61E:000000281E28212821E8212821E81E280028000003F80020002000D003080000 +C61F:000000281E28212821E8212821E81E2800280000004003F8004000A003180000 +C620:000000281E28212821E8212821E81E280028000003F8000803F8000800080000 +C621:000000281E28212821E8212821E81E280028000003F8020003F8020003F80000 +C622:000000281E28212821E8212821E81E280028000000000FF8022002200FF80000 +C623:000000281E28212821E8212821E81E280028000000800FF803E0041003E00000 +C624:000007C00820101010101010082007C0000000000100010001007FFC00000000 +C625:000007C008200820082007C0010001007FFC00001FF000100010001000100000 +C626:000007C008200820082007C0010001007FFC000000003EF80208020802080000 +C627:000007C008200820082007C0010001007FFC000000001E100210022802C40000 +C628:000007C008200820082007C0010001007FFC000000001000100010001FF00000 +C629:000007C008200820082007C0010001007FFC0000000020F8201020303ECC0000 +C62A:000007C008200820082007C0010001007FFC0000202021FC207020883E700000 +C62B:000007C008200820082007C0010001007FFC00001FF01000100010001FF00000 +C62C:000007C008200820082007C0010001007FFC00001FF000101FF010001FF00000 +C62D:000007C008200820082007C0010001007FFC00003EF802083E0820083E080000 +C62E:000007C008200820082007C0010001007FFC00003EF802883E8820883EF80000 +C62F:000007C008200820082007C0010001007FFC00003E8802883EF820883EF80000 +C630:000007C008200820082007C0010001007FFC00003E1002103E1020283EC40000 +C631:000007C008200820082007C0010001007FFC00003EF802803EF820803EF80000 +C632:000007C008200820082007C0010001007FFC00003EFC02483E4820483EFC0000 +C633:000007C008200820082007C0010001007FFC00003E2003FC3E7020883E700000 +C634:000007C008200820082007C0010001007FFC00001FF01010101010101FF00000 +C635:000007C008200820082007C0010001007FFC0000101010101FF010101FF00000 +C636:000007C008200820082007C0010001007FFC0000222022203E2022503E880000 +C637:000007C008200820082007C0010001007FFC000000000100010002800C400000 +C638:000007C008200820082007C0010001007FFC00000000024002400DA033100000 +C639:000007C008200820082007C0010001007FFC0000000007C00820082007C00000 +C63A:000007C008200820082007C0010001007FFC0000000007E00080014006200000 +C63B:000007C008200820082007C0010001007FFC0000008007E00080014006200000 +C63C:000007C008200820082007C0010001007FFC00001FF000101FF0001000100000 +C63D:000007C008200820082007C0010001007FFC00001FF010001FF010001FF00000 +C63E:000007C008200820082007C0010001007FFC000000001FF0044004401FF00000 +C63F:000007C008200820082007C0010001007FFC000001001FF007C0082007C00000 +C640:0000001000101F10209040504050405E20901F10041004107FD0001000100000 +C641:000000081F082088208E20881F0804087FE8000007F800080008000800080000 +C642:000000081F082088208E20881F0804087FE8000000003EF80208020802080000 +C643:000000081F082088208E20881F0804087FE8000000001F080108011401620000 +C644:000000081F082088208E20881F0804087FE8000008000800080008000FF80000 +C645:000000081F082088208E20881F0804087FE80000000010F8101010301ECC0000 +C646:000000081F082088208E20881F0804087FE800000808087F081C08220F9C0000 +C647:000000081F082088208E20881F0804087FE8000003F802000200020003F80000 +C648:000000081F082088208E20881F0804087FE8000007F8000807F8040007F80000 +C649:000000081F082088208E20881F0804087FE800003EF802083E0820083E080000 +C64A:000000081F082088208E20881F0804087FE800003EF802883E8820883EF80000 +C64B:000000081F082088208E20881F0804087FE800003E8802883EF820883EF80000 +C64C:000000081F082088208E20881F0804087FE800001F0801081F0810141F620000 +C64D:000000081F082088208E20881F0804087FE800003EF802803EF820803EF80000 +C64E:000000081F082088208E20881F0804087FE800003EFC02483E4820483EFC0000 +C64F:000000081F082088208E20881F0804087FE800001F08017F1F1C10221F1C0000 +C650:000000081F082088208E20881F0804087FE8000003F802080208020803F80000 +C651:000000081F082088208E20881F0804087FE800000208020803F8020803F80000 +C652:000000081F082088208E20881F0804087FE80000110811081F0811141F620000 +C653:000000081F082088208E20881F0804087FE80000001000100010006801840000 +C654:000000081F082088208E20881F0804087FE800000048004800A8011406620000 +C655:000000081F082088208E20881F0804087FE80000000003F00408040803F00000 +C656:000000081F082088208E20881F0804087FE8000003F80020002000D003080000 +C657:000000081F082088208E20881F0804087FE80000004003F8004000A003180000 +C658:000000081F082088208E20881F0804087FE8000003F8000803F8000800080000 +C659:000000081F082088208E20881F0804087FE8000003F8020003F8020003F80000 +C65A:000000081F082088208E20881F0804087FE8000000000FF8022002200FF80000 +C65B:000000081F082088208E20881F0804087FE8000000800FF803E0041003E00000 +C65C:0000001200121F12209240524052405E20921F12041204127FD2001200120000 +C65D:000000281F2820A820B820A81F2804287FA8000007F800080008000800080000 +C65E:000000281F2820A820B820A81F2804287FA8000000003EF80208020802080000 +C65F:000000281F2820A820B820A81F2804287FA8000000001F080108011401620000 +C660:000000281F2820A820B820A81F2804287FA8000008000800080008000FF80000 +C661:000000281F2820A820B820A81F2804287FA80000000010F8101010301ECC0000 +C662:000000281F2820A820B820A81F2804287FA800000808087F081C08220F9C0000 +C663:000000281F2820A820B820A81F2804287FA8000003F802000200020003F80000 +C664:000000281F2820A820B820A81F2804287FA8000007F8000807F8040007F80000 +C665:000000281F2820A820B820A81F2804287FA800003EF802083E0820083E080000 +C666:000000281F2820A820B820A81F2804287FA800003EF802883E8820883EF80000 +C667:000000281F2820A820B820A81F2804287FA800003E8802883EF820883EF80000 +C668:000000281F2820A820B820A81F2804287FA800001F0801081F0810141F620000 +C669:000000281F2820A820B820A81F2804287FA800003EF802803EF820803EF80000 +C66A:000000281F2820A820B820A81F2804287FA800003EFC02483E4820483EFC0000 +C66B:000000281F2820A820B820A81F2804287FA800001F08017F1F1C10221F1C0000 +C66C:000000281F2820A820B820A81F2804287FA8000003F802080208020803F80000 +C66D:000000281F2820A820B820A81F2804287FA800000208020803F8020803F80000 +C66E:000000281F2820A820B820A81F2804287FA80000110811081F0811141F620000 +C66F:000000281F2820A820B820A81F2804287FA80000001000100010006801840000 +C670:000000281F2820A820B820A81F2804287FA800000048004800A8011406620000 +C671:000000281F2820A820B820A81F2804287FA80000000003F00408040803F00000 +C672:000000281F2820A820B820A81F2804287FA8000003F80020002000D003080000 +C673:000000281F2820A820B820A81F2804287FA80000004003F8004000A003180000 +C674:000000281F2820A820B820A81F2804287FA8000003F8000803F8000800080000 +C675:000000281F2820A820B820A81F2804287FA8000003F8020003F8020003F80000 +C676:000000281F2820A820B820A81F2804287FA8000000000FF8022002200FF80000 +C677:000000281F2820A820B820A81F2804287FA8000000800FF803E0041003E00000 +C678:0000000800081F08208840484048404820881F08040804087FE8000800080000 +C679:000000081F082088208820881F0804087FE8000007F800080008000800080000 +C67A:000000081F082088208820881F0804087FE8000000003EF80208020802080000 +C67B:000000081F082088208820881F0804087FE8000000001F080108011401620000 +C67C:000000081F082088208820881F0804087FE8000008000800080008000FF80000 +C67D:000000081F082088208820881F0804087FE80000000010F8101010301ECC0000 +C67E:000000081F082088208820881F0804087FE800000808087F081C08220F9C0000 +C67F:000000081F082088208820881F0804087FE8000003F802000200020003F80000 +C680:000000081F082088208820881F0804087FE8000007F8000807F8040007F80000 +C681:000000081F082088208820881F0804087FE800003EF802083E0820083E080000 +C682:000000081F082088208820881F0804087FE800003EF802883E8820883EF80000 +C683:000000081F082088208820881F0804087FE800003E8802883EF820883EF80000 +C684:000000081F082088208820881F0804087FE800001F0801081F0810141F620000 +C685:000000081F082088208820881F0804087FE800003EF802803EF820803EF80000 +C686:000000081F082088208820881F0804087FE800003EFC02483E4820483EFC0000 +C687:000000081F082088208820881F0804087FE800001F08017F1F1C10221F1C0000 +C688:000000081F082088208820881F0804087FE8000003F802080208020803F80000 +C689:000000081F082088208820881F0804087FE800000208020803F8020803F80000 +C68A:000000081F082088208820881F0804087FE80000110811081F0811141F620000 +C68B:000000081F082088208820881F0804087FE80000001000100010006801840000 +C68C:000000081F082088208820881F0804087FE800000048004800A8011406620000 +C68D:000000081F082088208820881F0804087FE80000000003F00408040803F00000 +C68E:000000081F082088208820881F0804087FE8000003F80020002000D003080000 +C68F:000000081F082088208820881F0804087FE80000004003F8004000A003180000 +C690:000000081F082088208820881F0804087FE8000003F8000803F8000800080000 +C691:000000081F082088208820881F0804087FE8000003F8020003F8020003F80000 +C692:000000081F082088208820881F0804087FE8000000000FF8022002200FF80000 +C693:000000081F082088208820881F0804087FE8000000800FF803E0041003E00000 +C694:000007C00820101010101010082007C0000004400440044004407FFC00000000 +C695:000007C008200820082007C0044004407FFC00001FF000100010001000100000 +C696:000007C008200820082007C0044004407FFC000000003EF80208020802080000 +C697:000007C008200820082007C0044004407FFC000000001E100210022802C40000 +C698:000007C008200820082007C0044004407FFC000000001000100010001FF00000 +C699:000007C008200820082007C0044004407FFC0000000020F8201020303ECC0000 +C69A:000007C008200820082007C0044004407FFC0000202021FC207020883E700000 +C69B:000007C008200820082007C0044004407FFC00001FF01000100010001FF00000 +C69C:000007C008200820082007C0044004407FFC00001FF000101FF010001FF00000 +C69D:000007C008200820082007C0044004407FFC00003EF802083E0820083E080000 +C69E:000007C008200820082007C0044004407FFC00003EF802883E8820883EF80000 +C69F:000007C008200820082007C0044004407FFC00003E8802883EF820883EF80000 +C6A0:000007C008200820082007C0044004407FFC00003E1002103E1020283EC40000 +C6A1:000007C008200820082007C0044004407FFC00003EF802803EF820803EF80000 +C6A2:000007C008200820082007C0044004407FFC00003EFC02483E4820483EFC0000 +C6A3:000007C008200820082007C0044004407FFC00003E2003FC3E7020883E700000 +C6A4:000007C008200820082007C0044004407FFC00001FF01010101010101FF00000 +C6A5:000007C008200820082007C0044004407FFC0000101010101FF010101FF00000 +C6A6:000007C008200820082007C0044004407FFC0000222022203E2022503E880000 +C6A7:000007C008200820082007C0044004407FFC000000000100010002800C400000 +C6A8:000007C008200820082007C0044004407FFC00000000024002400DA033100000 +C6A9:000007C008200820082007C0044004407FFC0000000007C00820082007C00000 +C6AA:000007C008200820082007C0044004407FFC0000000007E00080014006200000 +C6AB:000007C008200820082007C0044004407FFC0000008007E00080014006200000 +C6AC:000007C008200820082007C0044004407FFC00001FF000101FF0001000100000 +C6AD:000007C008200820082007C0044004407FFC00001FF010001FF010001FF00000 +C6AE:000007C008200820082007C0044004407FFC000000001FF0044004401FF00000 +C6AF:000007C008200820082007C0044004407FFC000001001FF007C0082007C00000 +C6B0:0000000007C00820101010101010082007C000003FF801000100010001000000 +C6B1:000007C008200820082007C000007FFC010001001FF000100010001000100000 +C6B2:000007C008200820082007C000007FFC0100010000003EF80208020802080000 +C6B3:000007C008200820082007C000007FFC0100010000001E100210022802C40000 +C6B4:000007C008200820082007C0000000007FFC010001001100100010001FF00000 +C6B5:000007C008200820082007C000007FFC01000100000020F8201020303ECC0000 +C6B6:000007C008200820082007C000007FFC01000100202021FC207020883E700000 +C6B7:000007C008200820082007C000007FFC010001001FF01000100010001FF00000 +C6B8:000007C008200820082007C000007FFC010001001FF000101FF010001FF00000 +C6B9:000007C008200820082007C000007FFC010001003EF802083E0820083E080000 +C6BA:000007C008200820082007C000007FFC010001003EF802883E8820883EF80000 +C6BB:000007C008200820082007C000007FFC010001003E8802883EF820883EF80000 +C6BC:000007C008200820082007C000007FFC010001003E1002103E1020283EC40000 +C6BD:000007C008200820082007C000007FFC010001003EF802803EF820803EF80000 +C6BE:000007C008200820082007C000007FFC010001003EFC02483E4820483EFC0000 +C6BF:000007C008200820082007C000007FFC010001003E2003FC3E7020883E700000 +C6C0:000007C008200820082007C000007FFC010001001FF01010101010101FF00000 +C6C1:000007C008200820082007C000007FFC01000100101010101FF010101FF00000 +C6C2:000007C008200820082007C000007FFC01000100222022203E2022503E880000 +C6C3:000007C008200820082007C000007FFC0100010000000100010002800C400000 +C6C4:000007C008200820082007C000007FFC010001000000024002400DA033100000 +C6C5:000007C008200820082007C000007FFC01000100000007C00820082007C00000 +C6C6:000007C008200820082007C000007FFC01000100000007E00080014006200000 +C6C7:000007C008200820082007C000007FFC01000100008007E00080014006200000 +C6C8:000007C008200820082007C000007FFC010001001FF000101FF0001000100000 +C6C9:000007C008200820082007C000007FFC010001001FF010001FF010001FF00000 +C6CA:000007C008200820082007C000007FFC0100010000001FF0044004401FF00000 +C6CB:000007C008200820082007C000007FFC0100010001001FF007C0082007C00000 +C6CC:000000081F08208840484048404820881F0800087FE8040804F8040804080000 +C6CD:1F082088208820881F0800087FE8027802080000000007F80008000800080000 +C6CE:1F082088208820881F0800087FE802780208000000003EF80208020802080000 +C6CF:1F082088208820881F0800087FE802780208000000001F080108011401620000 +C6D0:1F082088208820881F08000800087FE80278020802081000100010001FF80000 +C6D1:1F082088208820881F0800087FE8027802080000000020F8201020303ECC0000 +C6D2:1F082088208820881F0800087FE8027802080000202021FC207020883E700000 +C6D3:1F082088208820881F0800087FE802780208000003F802000200020003F80000 +C6D4:1F082088208820881F0800087FE802780208000007F8000807F8040007F80000 +C6D5:1F082088208820881F0800087FE80278020800003EF802083E0820083E080000 +C6D6:1F082088208820881F0800087FE80278020800003EF802883E8820883EF80000 +C6D7:1F082088208820881F0800087FE80278020800003E8802883EF820883EF80000 +C6D8:1F082088208820881F0800087FE80278020800000F8800880F8808140FA20000 +C6D9:1F082088208820881F0800087FE80278020800003EF802803EF820803EF80000 +C6DA:1F082088208820881F0800087FE80278020800003EFC02483E4820483EFC0000 +C6DB:1F082088208820881F0800087FE80278020800003E1002FE3E3820443E380000 +C6DC:1F082088208820881F0800087FE802780208000003F802080208020803F80000 +C6DD:1F082088208820881F0800087FE80278020800000208020803F8020803F80000 +C6DE:1F082088208820881F0800087FE8027802080000210821083F0821143F620000 +C6DF:1F082088208820881F0800087FE8027802080000001000100010006801840000 +C6E0:1F082088208820881F0800087FE80278020800000048004800A8011406620000 +C6E1:1F082088208820881F0800087FE8027802080000000003F00408040803F00000 +C6E2:1F082088208820881F0800087FE802780208000003F80020002000D003080000 +C6E3:1F082088208820881F0800087FE8027802080000004003F8004000A003180000 +C6E4:1F082088208820881F0800087FE802780208000003F8000803F8000800080000 +C6E5:1F082088208820881F0800087FE802780208000003F8020003F8020003F80000 +C6E6:1F082088208820881F0800087FE802780208000000000FF8022002200FF80000 +C6E7:1F082088208820881F0800087FE802780208000000800FF803E0041003E00000 +C6E8:0000000A1F0A208A404A404A404A208A1F0A000A7FEA040A047A040A040A0000 +C6E9:1F2820A820A820A81F2800287FA805E804280000000007F80008000800080000 +C6EA:1F2820A820A820A81F2800287FA805E80428000000003EF80208020802080000 +C6EB:1F2820A820A820A81F2800287FA805E80428000000001F080108011401620000 +C6EC:1F2820A820A820A81F28002800287FA8042805E804281428100010001FF80000 +C6ED:1F2820A820A820A81F2800287FA805E804280000000020F8201020303ECC0000 +C6EE:1F2820A820A820A81F2800287FA805E804280000202021FC207020883E700000 +C6EF:1F2820A820A820A81F2800287FA805E80428000003F802000200020003F80000 +C6F0:1F2820A820A820A81F2800287FA805E80428000007F8000807F8040007F80000 +C6F1:1F2820A820A820A81F2800287FA805E8042800003EF802083E0820083E080000 +C6F2:1F2820A820A820A81F2800287FA805E8042800003EF802883E8820883EF80000 +C6F3:1F2820A820A820A81F2800287FA805E8042800003E8802883EF820883EF80000 +C6F4:1F2820A820A820A81F2800287FA805E8042800000F8800880F8808140FA20000 +C6F5:1F2820A820A820A81F2800287FA805E8042800003EF802803EF820803EF80000 +C6F6:1F2820A820A820A81F2800287FA805E8042800003EFC02483E4820483EFC0000 +C6F7:1F2820A820A820A81F2800287FA805E8042800003E1002FE3E3820443E380000 +C6F8:1F2820A820A820A81F2800287FA805E80428000003F802080208020803F80000 +C6F9:1F2820A820A820A81F2800287FA805E8042800000208020803F8020803F80000 +C6FA:1F2820A820A820A81F2800287FA805E804280000210821083F0821143F620000 +C6FB:1F2820A820A820A81F2800287FA805E804280000001000100010006801840000 +C6FC:1F2820A820A820A81F2800287FA805E8042800000048004800A8011406620000 +C6FD:1F2820A820A820A81F2800287FA805E804280000000003F00408040803F00000 +C6FE:1F2820A820A820A81F2800287FA805E80428000003F80020002000D003080000 +C6FF:1F2820A820A820A81F2800287FA805E804280000004003F8004000A003180000 +C700:1F2820A820A820A81F2800287FA805E80428000003F8000803F8000800080000 +C701:1F2820A820A820A81F2800287FA805E80428000003F8020003F8020003F80000 +C702:1F2820A820A820A81F2800287FA805E80428000000000FF8022002200FF80000 +C703:1F2820A820A820A81F2800287FA805E80428000000800FF803E0041003E00000 +C704:000000081F08208840484048404820881F0800087FE804080408040804080000 +C705:1F082088208820881F0800087FE8020802000000000007F80008000800080000 +C706:1F082088208820881F0800087FE802080200000000003EF80208020802080000 +C707:1F082088208820881F0800087FE802080200000000001F080108011401620000 +C708:1F082088208820881F08000800087FE80208020802081008100010001FF80000 +C709:1F082088208820881F0800087FE8020802000000000020F8201020303ECC0000 +C70A:1F082088208820881F0800087FE8020802000000202021FC207020883E700000 +C70B:1F082088208820881F0800087FE802080200000003F802000200020003F80000 +C70C:1F082088208820881F0800087FE802080200000007F8000807F8040007F80000 +C70D:1F082088208820881F0800087FE80208020000003EF802083E0820083E080000 +C70E:1F082088208820881F0800087FE80208020000003EF802883E8820883EF80000 +C70F:1F082088208820881F0800087FE80208020000003E8802883EF820883EF80000 +C710:1F082088208820881F0800087FE80208020000000F8800880F8808140FA20000 +C711:1F082088208820881F0800087FE80208020000003EF802803EF820803EF80000 +C712:1F082088208820881F0800087FE80208020000003EFC02483E4820483EFC0000 +C713:1F082088208820881F0800087FE80208020000003E1002FE3E3820443E380000 +C714:1F082088208820881F0800087FE802080200000003F802080208020803F80000 +C715:1F082088208820881F0800087FE80208020000000208020803F8020803F80000 +C716:1F082088208820881F0800087FE8020802000000210821083F0821143F620000 +C717:1F082088208820881F0800087FE8020802000000001000100010006801840000 +C718:1F082088208820881F0800087FE80208020000000048004800A8011406620000 +C719:1F082088208820881F0800087FE8020802000000000003F00408040803F00000 +C71A:1F082088208820881F0800087FE802080200000003F80020002000D003080000 +C71B:1F082088208820881F0800087FE8020802000000004003F8004000A003180000 +C71C:1F082088208820881F0800087FE802080200000003F8000803F8000800080000 +C71D:1F082088208820881F0800087FE802080200000003F8020003F8020003F80000 +C71E:1F082088208820881F0800087FE802080200000000000FF8022002200FF80000 +C71F:1F082088208820881F0800087FE802080200000000800FF803E0041003E00000 +C720:0000000007C00820101010101010082007C000007FFC04400440044004400000 +C721:000007C008200820082007C000007FFC044004401FF000100010001000100000 +C722:000007C008200820082007C000007FFC0440044000003EF80208020802080000 +C723:000007C008200820082007C000007FFC0440044000001E100210022802C40000 +C724:000007C008200820082007C0000000007FFC044004401440100010001FF00000 +C725:000007C008200820082007C000007FFC04400440000020F8201020303ECC0000 +C726:000007C008200820082007C000007FFC04400440202021FC207020883E700000 +C727:000007C008200820082007C000007FFC044004401FF01000100010001FF00000 +C728:000007C008200820082007C000007FFC044004401FF000101FF010001FF00000 +C729:000007C008200820082007C000007FFC044004403EF802083E0820083E080000 +C72A:000007C008200820082007C000007FFC044004403EF802883E8820883EF80000 +C72B:000007C008200820082007C000007FFC044004403E8802883EF820883EF80000 +C72C:000007C008200820082007C000007FFC044004403E1002103E1020283EC40000 +C72D:000007C008200820082007C000007FFC044004403EF802803EF820803EF80000 +C72E:000007C008200820082007C000007FFC044004403EFC02483E4820483EFC0000 +C72F:000007C008200820082007C000007FFC044004403E2003FC3E7020883E700000 +C730:000007C008200820082007C000007FFC044004401FF01010101010101FF00000 +C731:000007C008200820082007C000007FFC04400440101010101FF010101FF00000 +C732:000007C008200820082007C000007FFC04400440222022203E2022503E880000 +C733:000007C008200820082007C000007FFC0440044000000100010002800C400000 +C734:000007C008200820082007C000007FFC044004400000024002400DA033100000 +C735:000007C008200820082007C000007FFC04400440000007C00820082007C00000 +C736:000007C008200820082007C000007FFC04400440000007E00080014006200000 +C737:000007C008200820082007C000007FFC04400440008007E00080014006200000 +C738:000007C008200820082007C000007FFC044004401FF000101FF0001000100000 +C739:000007C008200820082007C000007FFC044004401FF010001FF010001FF00000 +C73A:000007C008200820082007C000007FFC0440044000001FF0044004401FF00000 +C73B:000007C008200820082007C000007FFC0440044001001FF007C0082007C00000 +C73C:000007C00820101010101010082007C00000000000007FFC0000000000000000 +C73D:000007C008200820082007C0000000007FFC00001FF000100010001000100000 +C73E:000007C008200820082007C0000000007FFC000000003EF80208020802080000 +C73F:000007C008200820082007C0000000007FFC000000001E100210022802C40000 +C740:000007C008200820082007C0000000007FFC000000001000100010001FF00000 +C741:000007C008200820082007C0000000007FFC0000000020F8201020303ECC0000 +C742:000007C008200820082007C0000000007FFC0000202021FC207020883E700000 +C743:000007C008200820082007C0000000007FFC00001FF01000100010001FF00000 +C744:000007C008200820082007C0000000007FFC00001FF000101FF010001FF00000 +C745:000007C008200820082007C0000000007FFC00003EF802083E0820083E080000 +C746:000007C008200820082007C0000000007FFC00003EF802883E8820883EF80000 +C747:000007C008200820082007C0000000007FFC00003E8802883EF820883EF80000 +C748:000007C008200820082007C0000000007FFC00003E1002103E1020283EC40000 +C749:000007C008200820082007C0000000007FFC00003EF802803EF820803EF80000 +C74A:000007C008200820082007C0000000007FFC00003EFC02483E4820483EFC0000 +C74B:000007C008200820082007C0000000007FFC00003E2003FC3E7020883E700000 +C74C:000007C008200820082007C0000000007FFC00001FF01010101010101FF00000 +C74D:000007C008200820082007C0000000007FFC0000101010101FF010101FF00000 +C74E:000007C008200820082007C0000000007FFC0000222022203E2022503E880000 +C74F:000007C008200820082007C0000000007FFC000000000100010002800C400000 +C750:000007C008200820082007C0000000007FFC00000000024002400DA033100000 +C751:000007C008200820082007C0000000007FFC0000000007C00820082007C00000 +C752:000007C008200820082007C0000000007FFC0000000007E00080014006200000 +C753:000007C008200820082007C0000000007FFC0000008007E00080014006200000 +C754:000007C008200820082007C0000000007FFC00001FF000101FF0001000100000 +C755:000007C008200820082007C0000000007FFC00001FF010001FF010001FF00000 +C756:000007C008200820082007C0000000007FFC000000001FF0044004401FF00000 +C757:000007C008200820082007C0000000007FFC000001001FF007C0082007C00000 +C758:0000000800081F08208840484048404820881F0800087FE80008000800080000 +C759:000000081F082088208820881F0800087FE8000007F800080008000800080000 +C75A:000000081F082088208820881F0800087FE8000000003EF80208020802080000 +C75B:000000081F082088208820881F0800087FE8000000001F080108011401620000 +C75C:000000081F082088208820881F0800087FE8000008000800080008000FF80000 +C75D:000000081F082088208820881F0800087FE80000000010F8101010301ECC0000 +C75E:000000081F082088208820881F0800087FE800000808087F081C08220F9C0000 +C75F:000000081F082088208820881F0800087FE8000003F802000200020003F80000 +C760:000000081F082088208820881F0800087FE8000007F8000807F8040007F80000 +C761:000000081F082088208820881F0800087FE800003EF802083E0820083E080000 +C762:000000081F082088208820881F0800087FE800003EF802883E8820883EF80000 +C763:000000081F082088208820881F0800087FE800003E8802883EF820883EF80000 +C764:000000081F082088208820881F0800087FE800001F0801081F0810141F620000 +C765:000000081F082088208820881F0800087FE800003EF802803EF820803EF80000 +C766:000000081F082088208820881F0800087FE800003EFC02483E4820483EFC0000 +C767:000000081F082088208820881F0800087FE800001F08017F1F1C10221F1C0000 +C768:000000081F082088208820881F0800087FE8000003F802080208020803F80000 +C769:000000081F082088208820881F0800087FE800000208020803F8020803F80000 +C76A:000000081F082088208820881F0800087FE80000110811081F0811141F620000 +C76B:000000081F082088208820881F0800087FE80000001000100010006801840000 +C76C:000000081F082088208820881F0800087FE800000048004800A8011406620000 +C76D:000000081F082088208820881F0800087FE80000000003F00408040803F00000 +C76E:000000081F082088208820881F0800087FE8000003F80020002000D003080000 +C76F:000000081F082088208820881F0800087FE80000004003F8004000A003180000 +C770:000000081F082088208820881F0800087FE8000003F8000803F8000800080000 +C771:000000081F082088208820881F0800087FE8000003F8020003F8020003F80000 +C772:000000081F082088208820881F0800087FE8000000000FF8022002200FF80000 +C773:000000081F082088208820881F0800087FE8000000800FF803E0041003E00000 +C774:00000000000800081E08210840884088408821081E0800080008000800080000 +C775:000000081E0821082108210821081E0800080000000007F80008000800080000 +C776:000000081E0821082108210821081E080008000000003EF80208020802080000 +C777:000000081E0821082108210821081E080008000000001F080108011401620000 +C778:000000081E0821082108210821081E080008000800001000100010001FF80000 +C779:000000081E0821082108210821081E0800080000000020F8201020303ECC0000 +C77A:000000081E0821082108210821081E0800080000202021FC207020883E700000 +C77B:000000081E0821082108210821081E080008000003F802000200020003F80000 +C77C:000000081E0821082108210821081E080008000007F8000807F8040007F80000 +C77D:000000081E0821082108210821081E08000800003EF802083E0820083E080000 +C77E:000000081E0821082108210821081E08000800003EF802883E8820883EF80000 +C77F:000000081E0821082108210821081E08000800003E8802883EF820883EF80000 +C780:000000081E0821082108210821081E08000800000F8800880F8808140FA20000 +C781:000000081E0821082108210821081E08000800003EF802803EF820803EF80000 +C782:000000081E0821082108210821081E08000800003EFC02483E4820483EFC0000 +C783:000000081E0821082108210821081E08000800003E1002FE3E3820443E380000 +C784:000000081E0821082108210821081E080008000003F802080208020803F80000 +C785:000000081E0821082108210821081E08000800000208020803F8020803F80000 +C786:000000081E0821082108210821081E0800080000210821083F0821143F620000 +C787:000000081E0821082108210821081E0800080000001000100010006801840000 +C788:000000081E0821082108210821081E08000800000048004800A8011406620000 +C789:000000081E0821082108210821081E0800080000000003F00408040803F00000 +C78A:000000081E0821082108210821081E080008000003F80020002000D003080000 +C78B:000000081E0821082108210821081E0800080000004003F8004000A003180000 +C78C:000000081E0821082108210821081E080008000003F8000803F8000800080000 +C78D:000000081E0821082108210821081E080008000003F8020003F8020003F80000 +C78E:000000081E0821082108210821081E080008000000000FF8022002200FF80000 +C78F:000000081E0821082108210821081E080008000000800FF803E0041003E00000 +C790:00000000001000103F9001100110021E06100910309000100010001000100000 +C791:0000000800087E080408040E1A0861080008000007F800080008000800080000 +C792:0000000800087E080408040E1A0861080008000000003EF80208020802080000 +C793:0000000800087E080408040E1A0861080008000000001F080108011401620000 +C794:0000000800087E080408040E1A0861080008000808000800080008000FF80000 +C795:0000000800087E080408040E1A08610800080000000010F8101010301ECC0000 +C796:0000000800087E080408040E1A086108000800000808087F081C08220F9C0000 +C797:0000000800087E080408040E1A0861080008000003F802000200020003F80000 +C798:0000000800087E080408040E1A0861080008000007F8000807F8040007F80000 +C799:0000000800087E080408040E1A086108000800003EF802083E0820083E080000 +C79A:0000000800087E080408040E1A086108000800003EF802883E8820883EF80000 +C79B:0000000800087E080408040E1A086108000800003E8802883EF820883EF80000 +C79C:0000000800087E080408040E1A086108000800001F0801081F0810141F620000 +C79D:0000000800087E080408040E1A086108000800003EF802803EF820803EF80000 +C79E:0000000800087E080408040E1A086108000800003EFC02483E4820483EFC0000 +C79F:0000000800087E080408040E1A086108000800001F08017F1F1C10221F1C0000 +C7A0:0000000800087E080408040E1A0861080008000003F802080208020803F80000 +C7A1:0000000800087E080408040E1A086108000800000208020803F8020803F80000 +C7A2:0000000800087E080408040E1A08610800080000110811081F0811141F620000 +C7A3:0000000800087E080408040E1A08610800080000001000100010006801840000 +C7A4:0000000800087E080408040E1A086108000800000048004800A8011406620000 +C7A5:0000000800087E080408040E1A08610800080000000003F00408040803F00000 +C7A6:0000000800087E080408040E1A0861080008000003F80020002000D003080000 +C7A7:0000000800087E080408040E1A08610800080000004003F8004000A003180000 +C7A8:0000000800087E080408040E1A0861080008000003F8000803F8000800080000 +C7A9:0000000800087E080408040E1A0861080008000003F8020003F8020003F80000 +C7AA:0000000800087E080408040E1A0861080008000000000FF8022002200FF80000 +C7AB:0000000800087E080408040E1A0861080008000000800FF803E0041003E00000 +C7AC:00000000001200123F9201120112021E06120912309200120012001200120000 +C7AD:0000002800287E28042804381A2861280028000007F800080008000800080000 +C7AE:0000002800287E28042804381A2861280028000000003EF80208020802080000 +C7AF:0000002800287E28042804381A2861280028000000003E100210022802C40000 +C7B0:0000002800287E28042804381A2861280028002808000800080008000FF80000 +C7B1:0000002800287E28042804381A28612800280000000020F8201020303ECC0000 +C7B2:0000002800287E28042804381A28612800280000202021FC207020883E700000 +C7B3:0000002800287E28042804381A2861280028000003F802000200020003F80000 +C7B4:0000002800287E28042804381A2861280028000007F8000807F8040007F80000 +C7B5:0000002800287E28042804381A286128002800003EF802083E0820083E080000 +C7B6:0000002800287E28042804381A286128002800003EF802883E8820883EF80000 +C7B7:0000002800287E28042804381A286128002800003E8802883EF820883EF80000 +C7B8:0000002800287E28042804381A286128002800001F0801081F0810141F620000 +C7B9:0000002800287E28042804381A286128002800003EF802803EF820803EF80000 +C7BA:0000002800287E28042804381A286128002800003EFC02483E4820483EFC0000 +C7BB:0000002800287E28042804381A286128002800003E1002FE3E3820443E380000 +C7BC:0000002800287E28042804381A2861280028000003F802080208020803F80000 +C7BD:0000002800287E28042804381A286128002800000208020803F8020803F80000 +C7BE:0000002800287E28042804381A28612800280000110811081F0811141F620000 +C7BF:0000002800287E28042804381A28612800280000000800080008003400C20000 +C7C0:0000002800287E28042804381A286128002800000048004800A8011406620000 +C7C1:0000002800287E28042804381A28612800280000000001F00208020801F00000 +C7C2:0000002800287E28042804381A2861280028000003F80020002000D003080000 +C7C3:0000002800287E28042804381A28612800280000004003F8004000A003180000 +C7C4:0000002800287E28042804381A2861280028000003F8000803F8000800080000 +C7C5:0000002800287E28042804381A2861280028000003F8020003F8020003F80000 +C7C6:0000002800287E28042804381A2861280028000000000FF8022002200FF80000 +C7C7:0000002800287E28042804381A2861280028000000800FF803E0041003E00000 +C7C8:00000000001000103F900110011E02100610091E309000100010001000100000 +C7C9:0000000800087E08040E04081A0E61080008000007F800080008000800080000 +C7CA:0000000800087E08040E04081A0E61080008000000003EF80208020802080000 +C7CB:0000000800087E08040E04081A0E61080008000000001F080108011401620000 +C7CC:0000000800087E08040E04081A0E61080008000008000800080008000FF80000 +C7CD:0000000800087E08040E04081A0E610800080000000010F8101010301ECC0000 +C7CE:0000000800087E08040E04081A0E6108000800000808087F081C08220F9C0000 +C7CF:0000000800087E08040E04081A0E61080008000003F802000200020003F80000 +C7D0:0000000800087E08040E04081A0E61080008000007F8000807F8040007F80000 +C7D1:0000000800087E08040E04081A0E6108000800003EF802083E0820083E080000 +C7D2:0000000800087E08040E04081A0E6108000800003EF802883E8820883EF80000 +C7D3:0000000800087E08040E04081A0E6108000800003E8802883EF820883EF80000 +C7D4:0000000800087E08040E04081A0E6108000800001F0801081F0810141F620000 +C7D5:0000000800087E08040E04081A0E6108000800003EF802803EF820803EF80000 +C7D6:0000000800087E08040E04081A0E6108000800003EFC02483E4820483EFC0000 +C7D7:0000000800087E08040E04081A0E6108000800001F08017F1F1C10221F1C0000 +C7D8:0000000800087E08040E04081A0E61080008000003F802080208020803F80000 +C7D9:0000000800087E08040E04081A0E6108000800000208020803F8020803F80000 +C7DA:0000000800087E08040E04081A0E610800080000110811081F0811141F620000 +C7DB:0000000800087E08040E04081A0E610800080000001000100010006801840000 +C7DC:0000000800087E08040E04081A0E6108000800000048004800A8011406620000 +C7DD:0000000800087E08040E04081A0E610800080000000003F00408040803F00000 +C7DE:0000000800087E08040E04081A0E61080008000003F80020002000D003080000 +C7DF:0000000800087E08040E04081A0E610800080000004003F8004000A003180000 +C7E0:0000000800087E08040E04081A0E61080008000003F8000803F8000800080000 +C7E1:0000000800087E08040E04081A0E61080008000003F8020003F8020003F80000 +C7E2:0000000800087E08040E04081A0E61080008000000000FF8022002200FF80000 +C7E3:0000000800087E08040E04081A0E61080008000000800FF803E0041003E00000 +C7E4:00000000001200123F920112011E02120612091E309200120012001200120000 +C7E5:0000002800287E28043804281A3861280028000007F800080008000800080000 +C7E6:0000002800287E28043804281A3861280028000000003EF80208020802080000 +C7E7:0000002800287E28043804281A3861280028000000003E100210022802C40000 +C7E8:0000002800287E28043804281A3861280028002808000800080008000FF80000 +C7E9:0000002800287E28043804281A38612800280000000020F8201020303ECC0000 +C7EA:0000002800287E28043804281A38612800280000202021FC207020883E700000 +C7EB:0000002800287E28043804281A3861280028000003F802000200020003F80000 +C7EC:0000002800287E28043804281A3861280028000007F8000807F8040007F80000 +C7ED:0000002800287E28043804281A386128002800003EF802083E0820083E080000 +C7EE:0000002800287E28043804281A386128002800003EF802883E8820883EF80000 +C7EF:0000002800287E28043804281A386128002800003E8802883EF820883EF80000 +C7F0:0000002800287E28043804281A386128002800001F0801081F0810141F620000 +C7F1:0000002800287E28043804281A386128002800003EF802803EF820803EF80000 +C7F2:0000002800287E28043804281A386128002800003EFC02483E4820483EFC0000 +C7F3:0000002800287E28043804281A386128002800003E1002FE3E3820443E380000 +C7F4:0000002800287E28043804281A3861280028000003F802080208020803F80000 +C7F5:0000002800287E28043804281A386128002800000208020803F8020803F80000 +C7F6:0000002800287E28043804281A38612800280000110811081F0811141F620000 +C7F7:0000002800287E28043804281A38612800280000000800080008003400C20000 +C7F8:0000002800287E28043804281A386128002800000048004800A8011406620000 +C7F9:0000002800287E28043804281A38612800280000000001F00208020801F00000 +C7FA:0000002800287E28043804281A3861280028000003F80020002000D003080000 +C7FB:0000002800287E28043804281A38612800280000004003F8004000A003180000 +C7FC:0000002800287E28043804281A3861280028000003F8000803F8000800080000 +C7FD:0000002800287E28043804281A3861280028000003F8020003F8020003F80000 +C7FE:0000002800287E28043804281A3861280028000000000FF8022002200FF80000 +C7FF:0000002800287E28043804281A3861280028000000800FF803E0041003E00000 +C800:00000000000200023F8201020102021E06020902308200020002000200020000 +C801:0000000800087E08040804381A08610800080000000007F80008000800080000 +C802:0000000800087E08040804381A0861080008000000003EF80208020802080000 +C803:0000000800087E08040804381A0861080008000000001F080108011401620000 +C804:0000000800087E08040804381A0861080008000000001000100010001FF80000 +C805:0000000800087E08040804381A08610800080000000020F8201020303ECC0000 +C806:0000000800087E08040804381A08610800080000202021FC207020883E700000 +C807:0000000800087E08040804381A0861080008000003F802000200020003F80000 +C808:0000000800087E08040804381A0861080008000007F8000807F8040007F80000 +C809:0000000800087E08040804381A086108000800003EF802083E0820083E080000 +C80A:0000000800087E08040804381A086108000800003EF802883E8820883EF80000 +C80B:0000000800087E08040804381A086108000800003E8802883EF820883EF80000 +C80C:0000000800087E08040804381A086108000800000F8800880F8808140FA20000 +C80D:0000000800087E08040804381A086108000800003EF802803EF820803EF80000 +C80E:0000000800087E08040804381A086108000800003EFC02483E4820483EFC0000 +C80F:0000000800087E08040804381A086108000800003E1002FE3E3820443E380000 +C810:0000000800087E08040804381A0861080008000003F802080208020803F80000 +C811:0000000800087E08040804381A086108000800000208020803F8020803F80000 +C812:0000000800087E08040804381A08610800080000210821083F0821143F620000 +C813:0000000800087E08040804381A08610800080000001000100010006801840000 +C814:0000000800087E08040804381A086108000800000048004800A8011406620000 +C815:0000000800087E08040804381A08610800080000000003F00408040803F00000 +C816:0000000800087E08040804381A0861080008000003F80020002000D003080000 +C817:0000000800087E08040804381A08610800080000004003F8004000A003180000 +C818:0000000800087E08040804381A0861080008000003F8000803F8000800080000 +C819:0000000800087E08040804381A0861080008000003F8020003F8020003F80000 +C81A:0000000800087E08040804381A0861080008000000000FF8022002200FF80000 +C81B:0000000800087E08040804381A0861080008000000800FF803E0041003E00000 +C81C:00000000000A000A3F8A010A010A023A060A090A308A000A000A000A000A0000 +C81D:0000002800287E28042804E81A2861280028000007F800080008000800080000 +C81E:0000002800287E28042804E81A2861280028000000003EF80208020802080000 +C81F:0000002800287E28042804E81A2861280028000000003E100210022802C40000 +C820:0000002800287E28042804E81A2861280028000008000800080008000FF80000 +C821:0000002800287E28042804E81A28612800280000000020F8201020303ECC0000 +C822:0000002800287E28042804E81A28612800280000202021FC207020883E700000 +C823:0000002800287E28042804E81A2861280028000003F802000200020003F80000 +C824:0000002800287E28042804E81A2861280028000007F8000807F8040007F80000 +C825:0000002800287E28042804E81A286128002800003EF802083E0820083E080000 +C826:0000002800287E28042804E81A286128002800003EF802883E8820883EF80000 +C827:0000002800287E28042804E81A286128002800003E8802883EF820883EF80000 +C828:0000002800287E28042804E81A286128002800001F0801081F0810141F620000 +C829:0000002800287E28042804E81A286128002800003EF802803EF820803EF80000 +C82A:0000002800287E28042804E81A286128002800003EFC02483E4820483EFC0000 +C82B:0000002800287E28042804E81A286128002800003E1002FE3E3820443E380000 +C82C:0000002800287E28042804E81A2861280028000003F802080208020803F80000 +C82D:0000002800287E28042804E81A286128002800000208020803F8020803F80000 +C82E:0000002800287E28042804E81A28612800280000110811081F0811141F620000 +C82F:0000002800287E28042804E81A28612800280000000800080008003400C20000 +C830:0000002800287E28042804E81A286128002800000048004800A8011406620000 +C831:0000002800287E28042804E81A28612800280000000001F00208020801F00000 +C832:0000002800287E28042804E81A2861280028000003F80020002000D003080000 +C833:0000002800287E28042804E81A28612800280000004003F8004000A003180000 +C834:0000002800287E28042804E81A2861280028000003F8000803F8000800080000 +C835:0000002800287E28042804E81A2861280028000003F8020003F8020003F80000 +C836:0000002800287E28042804E81A2861280028000000000FF8022002200FF80000 +C837:0000002800287E28042804E81A2861280028000000800FF803E0041003E00000 +C838:00000000000200023F820102011E02020602091E308200020002000200020000 +C839:0000000800087E08043804081A38610800080000000007F80008000800080000 +C83A:0000000800087E08043804081A3861080008000000003EF80208020802080000 +C83B:0000000800087E08043804081A3861080008000000001F080108011401620000 +C83C:0000000800087E08043804081A3861080008000800001000100010001FF80000 +C83D:0000000800087E08043804081A38610800080000000020F8201020303ECC0000 +C83E:0000000800087E08043804081A38610800080000202021FC207020883E700000 +C83F:0000000800087E08043804081A3861080008000003F802000200020003F80000 +C840:0000000800087E08043804081A3861080008000007F8000807F8040007F80000 +C841:0000000800087E08043804081A386108000800003EF802083E0820083E080000 +C842:0000000800087E08043804081A386108000800003EF802883E8820883EF80000 +C843:0000000800087E08043804081A386108000800003E8802883EF820883EF80000 +C844:0000000800087E08043804081A386108000800000F8800880F8808140FA20000 +C845:0000000800087E08043804081A386108000800003EF802803EF820803EF80000 +C846:0000000800087E08043804081A386108000800003EFC02483E4820483EFC0000 +C847:0000000800087E08043804081A386108000800003E1002FE3E3820443E380000 +C848:0000000800087E08043804081A3861080008000003F802080208020803F80000 +C849:0000000800087E08043804081A386108000800000208020803F8020803F80000 +C84A:0000000800087E08043804081A38610800080000210821083F0821143F620000 +C84B:0000000800087E08043804081A38610800080000001000100010006801840000 +C84C:0000000800087E08043804081A386108000800000048004800A8011406620000 +C84D:0000000800087E08043804081A38610800080000000003F00408040803F00000 +C84E:0000000800087E08043804081A3861080008000003F80020002000D003080000 +C84F:0000000800087E08043804081A38610800080000004003F8004000A003180000 +C850:0000000800087E08043804081A3861080008000003F8000803F8000800080000 +C851:0000000800087E08043804081A3861080008000003F8020003F8020003F80000 +C852:0000000800087E08043804081A3861080008000000000FF8022002200FF80000 +C853:0000000800087E08043804081A3861080008000000800FF803E0041003E00000 +C854:00000000000A000A3F8A010A013A020A060A093A308A000A000A000A000A0000 +C855:0000002800287E2804E804281AE861280028000007F800080008000800080000 +C856:0000002800287E2804E804281AE861280028000000003EF80208020802080000 +C857:0000002800287E2804E804281AE861280028000000003E100210022802C40000 +C858:0000002800287E2804E804281AE861280028002808000800080008000FF80000 +C859:0000002800287E2804E804281AE8612800280000000020F8201020303ECC0000 +C85A:0000002800287E2804E804281AE8612800280000202021FC207020883E700000 +C85B:0000002800287E2804E804281AE861280028000003F802000200020003F80000 +C85C:0000002800287E2804E804281AE861280028000007F8000807F8040007F80000 +C85D:0000002800287E2804E804281AE86128002800003EF802083E0820083E080000 +C85E:0000002800287E2804E804281AE86128002800003EF802883E8820883EF80000 +C85F:0000002800287E2804E804281AE86128002800003E8802883EF820883EF80000 +C860:0000002800287E2804E804281AE86128002800001F0801081F0810141F620000 +C861:0000002800287E2804E804281AE86128002800003EF802803EF820803EF80000 +C862:0000002800287E2804E804281AE86128002800003EFC02483E4820483EFC0000 +C863:0000002800287E2804E804281AE86128002800003E1002FE3E3820443E380000 +C864:0000002800287E2804E804281AE861280028000003F802080208020803F80000 +C865:0000002800287E2804E804281AE86128002800000208020803F8020803F80000 +C866:0000002800287E2804E804281AE8612800280000110811081F0811141F620000 +C867:0000002800287E2804E804281AE8612800280000000800080008003400C20000 +C868:0000002800287E2804E804281AE86128002800000048004800A8011406620000 +C869:0000002800287E2804E804281AE8612800280000000001F00208020801F00000 +C86A:0000002800287E2804E804281AE861280028000003F80020002000D003080000 +C86B:0000002800287E2804E804281AE8612800280000004003F8004000A003180000 +C86C:0000002800287E2804E804281AE861280028000003F8000803F8000800080000 +C86D:0000002800287E2804E804281AE861280028000003F8020003F8020003F80000 +C86E:0000002800287E2804E804281AE861280028000000000FF8022002200FF80000 +C86F:0000002800287E2804E804281AE861280028000000800FF803E0041003E00000 +C870:000000000FE0004000400080018002400C2000000100010001007FFC00000000 +C871:00000FC0008003400C200000010001007FFC00001FF000100010001000100000 +C872:00000FC0008003400C200000010001007FFC000000003EF80208020802080000 +C873:00000FC0008003400C200000010001007FFC000000001E100210022802C40000 +C874:00000FC0008003400C200000010001007FFC000000001000100010001FF00000 +C875:00000FC0008003400C200000010001007FFC0000000020F8201020303ECC0000 +C876:00000FC0008003400C200000010001007FFC0000202021FC207020883E700000 +C877:00000FC0008003400C200000010001007FFC00001FF01000100010001FF00000 +C878:00000FC0008003400C200000010001007FFC00001FF000101FF010001FF00000 +C879:00000FC0008003400C200000010001007FFC00003EF802083E0820083E080000 +C87A:00000FC0008003400C200000010001007FFC00003EF802883E8820883EF80000 +C87B:00000FC0008003400C200000010001007FFC00003E8802883EF820883EF80000 +C87C:00000FC0008003400C200000010001007FFC00003E1002103E1020283EC40000 +C87D:00000FC0008003400C200000010001007FFC00003EF802803EF820803EF80000 +C87E:00000FC0008003400C200000010001007FFC00003EFC02483E4820483EFC0000 +C87F:00000FC0008003400C200000010001007FFC00003E2003FC3E7020883E700000 +C880:00000FC0008003400C200000010001007FFC00001FF01010101010101FF00000 +C881:00000FC0008003400C200000010001007FFC0000101010101FF010101FF00000 +C882:00000FC0008003400C200000010001007FFC0000222022203E2022503E880000 +C883:00000FC0008003400C200000010001007FFC000000000100010002800C400000 +C884:00000FC0008003400C200000010001007FFC00000000024002400DA033100000 +C885:00000FC0008003400C200000010001007FFC0000000007C00820082007C00000 +C886:00000FC0008003400C200000010001007FFC0000000007E00080014006200000 +C887:00000FC0008003400C200000010001007FFC0000008007E00080014006200000 +C888:00000FC0008003400C200000010001007FFC00001FF000101FF0001000100000 +C889:00000FC0008003400C200000010001007FFC00001FF010001FF010001FF00000 +C88A:00000FC0008003400C200000010001007FFC000000001FF0044004401FF00000 +C88B:00000FC0008003400C200000010001007FFC000001001FF007C0082007C00000 +C88C:0000001000103F90011001100210061E09103090041004107FD0001000100000 +C88D:000000083F0802080D0E3088040804087FE8000007F800080008000800080000 +C88E:000000083F0802080D0E3088040804087FE8000000003EF80208020802080000 +C88F:000000083F0802080D0E3088040804087FE8000000001F080108011401620000 +C890:000000083F0802080D0E3088040804087FE8000008000800080008000FF80000 +C891:000000083F0802080D0E3088040804087FE80000000010F8101010301ECC0000 +C892:000000083F0802080D0E3088040804087FE800000808087F081C08220F9C0000 +C893:000000083F0802080D0E3088040804087FE8000003F802000200020003F80000 +C894:000000083F0802080D0E3088040804087FE8000007F8000807F8040007F80000 +C895:000000083F0802080D0E3088040804087FE800003EF802083E0820083E080000 +C896:000000083F0802080D0E3088040804087FE800003EF802883E8820883EF80000 +C897:000000083F0802080D0E3088040804087FE800003E8802883EF820883EF80000 +C898:000000083F0802080D0E3088040804087FE800001F0801081F0810141F620000 +C899:000000083F0802080D0E3088040804087FE800003EF802803EF820803EF80000 +C89A:000000083F0802080D0E3088040804087FE800003EFC02483E4820483EFC0000 +C89B:000000083F0802080D0E3088040804087FE800001F08017F1F1C10221F1C0000 +C89C:000000083F0802080D0E3088040804087FE8000003F802080208020803F80000 +C89D:000000083F0802080D0E3088040804087FE800000208020803F8020803F80000 +C89E:000000083F0802080D0E3088040804087FE80000110811081F0811141F620000 +C89F:000000083F0802080D0E3088040804087FE80000001000100010006801840000 +C8A0:000000083F0802080D0E3088040804087FE800000048004800A8011406620000 +C8A1:000000083F0802080D0E3088040804087FE80000000003F00408040803F00000 +C8A2:000000083F0802080D0E3088040804087FE8000003F80020002000D003080000 +C8A3:000000083F0802080D0E3088040804087FE80000004003F8004000A003180000 +C8A4:000000083F0802080D0E3088040804087FE8000003F8000803F8000800080000 +C8A5:000000083F0802080D0E3088040804087FE8000003F8020003F8020003F80000 +C8A6:000000083F0802080D0E3088040804087FE8000000000FF8022002200FF80000 +C8A7:000000083F0802080D0E3088040804087FE8000000800FF803E0041003E00000 +C8A8:0000001200123F92011201120212061E09123092041204127FD2001200120000 +C8A9:000000283F2802280D3830A8042804287FA8000007F800080008000800080000 +C8AA:000000283F2802280D3830A8042804287FA8000000003EF80208020802080000 +C8AB:000000283F2802280D3830A8042804287FA8000000001F080108011401620000 +C8AC:000000283F2802280D3830A8042804287FA8000008000800080008000FF80000 +C8AD:000000283F2802280D3830A8042804287FA80000000010F8101010301ECC0000 +C8AE:000000283F2802280D3830A8042804287FA800000808087F081C08220F9C0000 +C8AF:000000283F2802280D3830A8042804287FA8000003F802000200020003F80000 +C8B0:000000283F2802280D3830A8042804287FA8000007F8000807F8040007F80000 +C8B1:000000283F2802280D3830A8042804287FA800003EF802083E0820083E080000 +C8B2:000000283F2802280D3830A8042804287FA800003EF802883E8820883EF80000 +C8B3:000000283F2802280D3830A8042804287FA800003E8802883EF820883EF80000 +C8B4:000000283F2802280D3830A8042804287FA800001F0801081F0810141F620000 +C8B5:000000283F2802280D3830A8042804287FA800003EF802803EF820803EF80000 +C8B6:000000283F2802280D3830A8042804287FA800003EFC02483E4820483EFC0000 +C8B7:000000283F2802280D3830A8042804287FA800001F08017F1F1C10221F1C0000 +C8B8:000000283F2802280D3830A8042804287FA8000003F802080208020803F80000 +C8B9:000000283F2802280D3830A8042804287FA800000208020803F8020803F80000 +C8BA:000000283F2802280D3830A8042804287FA80000110811081F0811141F620000 +C8BB:000000283F2802280D3830A8042804287FA80000001000100010006801840000 +C8BC:000000283F2802280D3830A8042804287FA800000048004800A8011406620000 +C8BD:000000283F2802280D3830A8042804287FA80000000003F00408040803F00000 +C8BE:000000283F2802280D3830A8042804287FA8000003F80020002000D003080000 +C8BF:000000283F2802280D3830A8042804287FA80000004003F8004000A003180000 +C8C0:000000283F2802280D3830A8042804287FA8000003F8000803F8000800080000 +C8C1:000000283F2802280D3830A8042804287FA8000003F8020003F8020003F80000 +C8C2:000000283F2802280D3830A8042804287FA8000000000FF8022002200FF80000 +C8C3:000000283F2802280D3830A8042804287FA8000000800FF803E0041003E00000 +C8C4:0000000800083F88010801080208060809083088040804087FE8000800080000 +C8C5:000000083F0802080D083088040804087FE8000007F800080008000800080000 +C8C6:000000083F0802080D083088040804087FE8000000003EF80208020802080000 +C8C7:000000083F0802080D083088040804087FE8000000001F080108011401620000 +C8C8:000000083F0802080D083088040804087FE8000008000800080008000FF80000 +C8C9:000000083F0802080D083088040804087FE80000000010F8101010301ECC0000 +C8CA:000000083F0802080D083088040804087FE800000808087F081C08220F9C0000 +C8CB:000000083F0802080D083088040804087FE8000003F802000200020003F80000 +C8CC:000000083F0802080D083088040804087FE8000007F8000807F8040007F80000 +C8CD:000000083F0802080D083088040804087FE800003EF802083E0820083E080000 +C8CE:000000083F0802080D083088040804087FE800003EF802883E8820883EF80000 +C8CF:000000083F0802080D083088040804087FE800003E8802883EF820883EF80000 +C8D0:000000083F0802080D083088040804087FE800001F0801081F0810141F620000 +C8D1:000000083F0802080D083088040804087FE800003EF802803EF820803EF80000 +C8D2:000000083F0802080D083088040804087FE800003EFC02483E4820483EFC0000 +C8D3:000000083F0802080D083088040804087FE800001F08017F1F1C10221F1C0000 +C8D4:000000083F0802080D083088040804087FE8000003F802080208020803F80000 +C8D5:000000083F0802080D083088040804087FE800000208020803F8020803F80000 +C8D6:000000083F0802080D083088040804087FE80000110811081F0811141F620000 +C8D7:000000083F0802080D083088040804087FE80000001000100010006801840000 +C8D8:000000083F0802080D083088040804087FE800000048004800A8011406620000 +C8D9:000000083F0802080D083088040804087FE80000000003F00408040803F00000 +C8DA:000000083F0802080D083088040804087FE8000003F80020002000D003080000 +C8DB:000000083F0802080D083088040804087FE80000004003F8004000A003180000 +C8DC:000000083F0802080D083088040804087FE8000003F8000803F8000800080000 +C8DD:000000083F0802080D083088040804087FE8000003F8020003F8020003F80000 +C8DE:000000083F0802080D083088040804087FE8000000000FF8022002200FF80000 +C8DF:000000083F0802080D083088040804087FE8000000800FF803E0041003E00000 +C8E0:000000000FE0004000400080018002400C2004400440044004407FFC00000000 +C8E1:00000FC0008003400C200000044004407FFC00001FF000100010001000100000 +C8E2:00000FC0008003400C200000044004407FFC000000003EF80208020802080000 +C8E3:00000FC0008003400C200000044004407FFC000000001E100210022802C40000 +C8E4:00000FC0008003400C200000044004407FFC000000001000100010001FF00000 +C8E5:00000FC0008003400C200000044004407FFC0000000020F8201020303ECC0000 +C8E6:00000FC0008003400C200000044004407FFC0000202021FC207020883E700000 +C8E7:00000FC0008003400C200000044004407FFC00001FF01000100010001FF00000 +C8E8:00000FC0008003400C200000044004407FFC00001FF000101FF010001FF00000 +C8E9:00000FC0008003400C200000044004407FFC00003EF802083E0820083E080000 +C8EA:00000FC0008003400C200000044004407FFC00003EF802883E8820883EF80000 +C8EB:00000FC0008003400C200000044004407FFC00003E8802883EF820883EF80000 +C8EC:00000FC0008003400C200000044004407FFC00003E1002103E1020283EC40000 +C8ED:00000FC0008003400C200000044004407FFC00003EF802803EF820803EF80000 +C8EE:00000FC0008003400C200000044004407FFC00003EFC02483E4820483EFC0000 +C8EF:00000FC0008003400C200000044004407FFC00003E2003FC3E7020883E700000 +C8F0:00000FC0008003400C200000044004407FFC00001FF01010101010101FF00000 +C8F1:00000FC0008003400C200000044004407FFC0000101010101FF010101FF00000 +C8F2:00000FC0008003400C200000044004407FFC0000222022203E2022503E880000 +C8F3:00000FC0008003400C200000044004407FFC000000000100010002800C400000 +C8F4:00000FC0008003400C200000044004407FFC00000000024002400DA033100000 +C8F5:00000FC0008003400C200000044004407FFC0000000007C00820082007C00000 +C8F6:00000FC0008003400C200000044004407FFC0000000007E00080014006200000 +C8F7:00000FC0008003400C200000044004407FFC0000008007E00080014006200000 +C8F8:00000FC0008003400C200000044004407FFC00001FF000101FF0001000100000 +C8F9:00000FC0008003400C200000044004407FFC00001FF010001FF010001FF00000 +C8FA:00000FC0008003400C200000044004407FFC000000001FF0044004401FF00000 +C8FB:00000FC0008003400C200000044004407FFC000001001FF007C0082007C00000 +C8FC:000000000FE0004000400080018002400C2000003FF801000100010001000000 +C8FD:00000FC00080008003400C2000007FFC010001001FF000100010001000100000 +C8FE:00000FC00080008003400C2000007FFC0100010000003EF80208020802080000 +C8FF:00000FC00080008003400C2000007FFC0100010000001E100210022802C40000 +C900:00000FC00080008003400C20000000007FFC010001001100100010001FF00000 +C901:00000FC00080008003400C2000007FFC01000100000020F8201020303ECC0000 +C902:00000FC00080008003400C2000007FFC01000100202021FC207020883E700000 +C903:00000FC00080008003400C2000007FFC010001001FF01000100010001FF00000 +C904:00000FC00080008003400C2000007FFC010001001FF000101FF010001FF00000 +C905:00000FC00080008003400C2000007FFC010001003EF802083E0820083E080000 +C906:00000FC00080008003400C2000007FFC010001003EF802883E8820883EF80000 +C907:00000FC00080008003400C2000007FFC010001003E8802883EF820883EF80000 +C908:00000FC00080008003400C2000007FFC010001003E1002103E1020283EC40000 +C909:00000FC00080008003400C2000007FFC010001003EF802803EF820803EF80000 +C90A:00000FC00080008003400C2000007FFC010001003EFC02483E4820483EFC0000 +C90B:00000FC00080008003400C2000007FFC010001003E2003FC3E7020883E700000 +C90C:00000FC00080008003400C2000007FFC010001001FF01010101010101FF00000 +C90D:00000FC00080008003400C2000007FFC01000100101010101FF010101FF00000 +C90E:00000FC00080008003400C2000007FFC01000100222022203E2022503E880000 +C90F:00000FC00080008003400C2000007FFC0100010000000100010002800C400000 +C910:00000FC00080008003400C2000007FFC010001000000024002400DA033100000 +C911:00000FC00080008003400C2000007FFC01000100000007C00820082007C00000 +C912:00000FC00080008003400C2000007FFC01000100000007E00080014006200000 +C913:00000FC00080008003400C2000007FFC01000100008007E00080014006200000 +C914:00000FC00080008003400C2000007FFC010001001FF000101FF0001000100000 +C915:00000FC00080008003400C2000007FFC010001001FF010001FF010001FF00000 +C916:00000FC00080008003400C2000007FFC0100010000001FF0044004401FF00000 +C917:00000FC00080008003400C2000007FFC0100010001001FF007C0082007C00000 +C918:000000083F8801080108020806080908308800087FE8040804F8040804080000 +C919:3F08020802080D08308800087FE8027802080000000007F80008000800080000 +C91A:3F08020802080D08308800087FE802780208000000003EF80208020802080000 +C91B:3F08020802080D08308800087FE802780208000000001F080108011401620000 +C91C:3F08020802080D083088000800087FE80278020802081000100010001FF80000 +C91D:3F08020802080D08308800087FE8027802080000000020F8201020303ECC0000 +C91E:3F08020802080D08308800087FE8027802080000202021FC207020883E700000 +C91F:3F08020802080D08308800087FE802780208000003F802000200020003F80000 +C920:3F08020802080D08308800087FE802780208000007F8000807F8040007F80000 +C921:3F08020802080D08308800087FE80278020800003EF802083E0820083E080000 +C922:3F08020802080D08308800087FE80278020800003EF802883E8820883EF80000 +C923:3F08020802080D08308800087FE80278020800003E8802883EF820883EF80000 +C924:3F08020802080D08308800087FE80278020800000F8800880F8808140FA20000 +C925:3F08020802080D08308800087FE80278020800003EF802803EF820803EF80000 +C926:3F08020802080D08308800087FE80278020800003EFC02483E4820483EFC0000 +C927:3F08020802080D08308800087FE80278020800003E1002FE3E3820443E380000 +C928:3F08020802080D08308800087FE802780208000003F802080208020803F80000 +C929:3F08020802080D08308800087FE80278020800000208020803F8020803F80000 +C92A:3F08020802080D08308800087FE8027802080000210821083F0821143F620000 +C92B:3F08020802080D08308800087FE8027802080000001000100010006801840000 +C92C:3F08020802080D08308800087FE80278020800000048004800A8011406620000 +C92D:3F08020802080D08308800087FE8027802080000000003F00408040803F00000 +C92E:3F08020802080D08308800087FE802780208000003F80020002000D003080000 +C92F:3F08020802080D08308800087FE8027802080000004003F8004000A003180000 +C930:3F08020802080D08308800087FE802780208000003F8000803F8000800080000 +C931:3F08020802080D08308800087FE802780208000003F8020003F8020003F80000 +C932:3F08020802080D08308800087FE802780208000000000FF8022002200FF80000 +C933:3F08020802080D08308800087FE802780208000000800FF803E0041003E00000 +C934:0000000A3F8A010A010A020A060A090A308A000A7FEA040A047A040A040A0000 +C935:3F28022802280D2830A800287FA805E804280000000007F80008000800080000 +C936:3F28022802280D2830A800287FA805E80428000000003EF80208020802080000 +C937:3F28022802280D2830A800287FA805E80428000000001F080108011401620000 +C938:3F28022802280D2830A8002800287FA8042805E804281428100010001FF80000 +C939:3F28022802280D2830A800287FA805E804280000000020F8201020303ECC0000 +C93A:3F28022802280D2830A800287FA805E804280000202021FC207020883E700000 +C93B:3F28022802280D2830A800287FA805E80428000003F802000200020003F80000 +C93C:3F28022802280D2830A800287FA805E80428000007F8000807F8040007F80000 +C93D:3F28022802280D2830A800287FA805E8042800003EF802083E0820083E080000 +C93E:3F28022802280D2830A800287FA805E8042800003EF802883E8820883EF80000 +C93F:3F28022802280D2830A800287FA805E8042800003E8802883EF820883EF80000 +C940:3F28022802280D2830A800287FA805E8042800000F8800880F8808140FA20000 +C941:3F28022802280D2830A800287FA805E8042800003EF802803EF820803EF80000 +C942:3F28022802280D2830A800287FA805E8042800003EFC02483E4820483EFC0000 +C943:3F28022802280D2830A800287FA805E8042800003E1002FE3E3820443E380000 +C944:3F28022802280D2830A800287FA805E80428000003F802080208020803F80000 +C945:3F28022802280D2830A800287FA805E8042800000208020803F8020803F80000 +C946:3F28022802280D2830A800287FA805E804280000210821083F0821143F620000 +C947:3F28022802280D2830A800287FA805E804280000001000100010006801840000 +C948:3F28022802280D2830A800287FA805E8042800000048004800A8011406620000 +C949:3F28022802280D2830A800287FA805E804280000000003F00408040803F00000 +C94A:3F28022802280D2830A800287FA805E80428000003F80020002000D003080000 +C94B:3F28022802280D2830A800287FA805E804280000004003F8004000A003180000 +C94C:3F28022802280D2830A800287FA805E80428000003F8000803F8000800080000 +C94D:3F28022802280D2830A800287FA805E80428000003F8020003F8020003F80000 +C94E:3F28022802280D2830A800287FA805E80428000000000FF8022002200FF80000 +C94F:3F28022802280D2830A800287FA805E80428000000800FF803E0041003E00000 +C950:000000083F8801080108020806080908308800087FE804080408040804080000 +C951:3F08020802080D08308800087FE8020802000000000007F80008000800080000 +C952:3F08020802080D08308800087FE802080200000000003EF80208020802080000 +C953:3F08020802080D08308800087FE802080200000000001F080108011401620000 +C954:3F08020802080D083088000800087FE80208020802081008100010001FF80000 +C955:3F08020802080D08308800087FE8020802000000000020F8201020303ECC0000 +C956:3F08020802080D08308800087FE8020802000000202021FC207020883E700000 +C957:3F08020802080D08308800087FE802080200000003F802000200020003F80000 +C958:3F08020802080D08308800087FE802080200000007F8000807F8040007F80000 +C959:3F08020802080D08308800087FE80208020000003EF802083E0820083E080000 +C95A:3F08020802080D08308800087FE80208020000003EF802883E8820883EF80000 +C95B:3F08020802080D08308800087FE80208020000003E8802883EF820883EF80000 +C95C:3F08020802080D08308800087FE80208020000000F8800880F8808140FA20000 +C95D:3F08020802080D08308800087FE80208020000003EF802803EF820803EF80000 +C95E:3F08020802080D08308800087FE80208020000003EFC02483E4820483EFC0000 +C95F:3F08020802080D08308800087FE80208020000003E1002FE3E3820443E380000 +C960:3F08020802080D08308800087FE802080200000003F802080208020803F80000 +C961:3F08020802080D08308800087FE80208020000000208020803F8020803F80000 +C962:3F08020802080D08308800087FE8020802000000210821083F0821143F620000 +C963:3F08020802080D08308800087FE8020802000000001000100010006801840000 +C964:3F08020802080D08308800087FE80208020000000048004800A8011406620000 +C965:3F08020802080D08308800087FE8020802000000000003F00408040803F00000 +C966:3F08020802080D08308800087FE802080200000003F80020002000D003080000 +C967:3F08020802080D08308800087FE8020802000000004003F8004000A003180000 +C968:3F08020802080D08308800087FE802080200000003F8000803F8000800080000 +C969:3F08020802080D08308800087FE802080200000003F8020003F8020003F80000 +C96A:3F08020802080D08308800087FE802080200000000000FF8022002200FF80000 +C96B:3F08020802080D08308800087FE802080200000000800FF803E0041003E00000 +C96C:000000000FE0004000400080018002400C2000007FFC04400440044004400000 +C96D:00000FC00080008003400C2000007FFC044004401FF000100010001000100000 +C96E:00000FC00080008003400C2000007FFC0440044000003EF80208020802080000 +C96F:00000FC00080008003400C2000007FFC0440044000001E100210022802C40000 +C970:00000FC00080008003400C20000000007FFC044004401440100010001FF00000 +C971:00000FC00080008003400C2000007FFC04400440000020F8201020303ECC0000 +C972:00000FC00080008003400C2000007FFC04400440202021FC207020883E700000 +C973:00000FC00080008003400C2000007FFC044004401FF01000100010001FF00000 +C974:00000FC00080008003400C2000007FFC044004401FF000101FF010001FF00000 +C975:00000FC00080008003400C2000007FFC044004403EF802083E0820083E080000 +C976:00000FC00080008003400C2000007FFC044004403EF802883E8820883EF80000 +C977:00000FC00080008003400C2000007FFC044004403E8802883EF820883EF80000 +C978:00000FC00080008003400C2000007FFC044004403E1002103E1020283EC40000 +C979:00000FC00080008003400C2000007FFC044004403EF802803EF820803EF80000 +C97A:00000FC00080008003400C2000007FFC044004403EFC02483E4820483EFC0000 +C97B:00000FC00080008003400C2000007FFC044004403E2003FC3E7020883E700000 +C97C:00000FC00080008003400C2000007FFC044004401FF01010101010101FF00000 +C97D:00000FC00080008003400C2000007FFC04400440101010101FF010101FF00000 +C97E:00000FC00080008003400C2000007FFC04400440222022203E2022503E880000 +C97F:00000FC00080008003400C2000007FFC0440044000000100010002800C400000 +C980:00000FC00080008003400C2000007FFC044004400000024002400DA033100000 +C981:00000FC00080008003400C2000007FFC04400440000007C00820082007C00000 +C982:00000FC00080008003400C2000007FFC04400440000007E00080014006200000 +C983:00000FC00080008003400C2000007FFC04400440008007E00080014006200000 +C984:00000FC00080008003400C2000007FFC044004401FF000101FF0001000100000 +C985:00000FC00080008003400C2000007FFC044004401FF010001FF010001FF00000 +C986:00000FC00080008003400C2000007FFC0440044000001FF0044004401FF00000 +C987:00000FC00080008003400C2000007FFC0440044001001FF007C0082007C00000 +C988:000000000FE0004000400080018002400C20000000007FFC0000000000000000 +C989:00000FC0008003400C200000000000007FFC00001FF000100010001000100000 +C98A:00000FC0008003400C200000000000007FFC000000003EF80208020802080000 +C98B:00000FC0008003400C200000000000007FFC000000001E100210022802C40000 +C98C:00000FC0008003400C200000000000007FFC000000001000100010001FF00000 +C98D:00000FC0008003400C200000000000007FFC0000000020F8201020303ECC0000 +C98E:00000FC0008003400C200000000000007FFC0000202021FC207020883E700000 +C98F:00000FC0008003400C200000000000007FFC00001FF01000100010001FF00000 +C990:00000FC0008003400C200000000000007FFC00001FF000101FF010001FF00000 +C991:00000FC0008003400C200000000000007FFC00003EF802083E0820083E080000 +C992:00000FC0008003400C200000000000007FFC00003EF802883E8820883EF80000 +C993:00000FC0008003400C200000000000007FFC00003E8802883EF820883EF80000 +C994:00000FC0008003400C200000000000007FFC00003E1002103E1020283EC40000 +C995:00000FC0008003400C200000000000007FFC00003EF802803EF820803EF80000 +C996:00000FC0008003400C200000000000007FFC00003EFC02483E4820483EFC0000 +C997:00000FC0008003400C200000000000007FFC00003E2003FC3E7020883E700000 +C998:00000FC0008003400C200000000000007FFC00001FF01010101010101FF00000 +C999:00000FC0008003400C200000000000007FFC0000101010101FF010101FF00000 +C99A:00000FC0008003400C200000000000007FFC0000222022203E2022503E880000 +C99B:00000FC0008003400C200000000000007FFC000000000100010002800C400000 +C99C:00000FC0008003400C200000000000007FFC00000000024002400DA033100000 +C99D:00000FC0008003400C200000000000007FFC0000000007C00820082007C00000 +C99E:00000FC0008003400C200000000000007FFC0000000007E00080014006200000 +C99F:00000FC0008003400C200000000000007FFC0000008007E00080014006200000 +C9A0:00000FC0008003400C200000000000007FFC00001FF000101FF0001000100000 +C9A1:00000FC0008003400C200000000000007FFC00001FF010001FF010001FF00000 +C9A2:00000FC0008003400C200000000000007FFC000000001FF0044004401FF00000 +C9A3:00000FC0008003400C200000000000007FFC000001001FF007C0082007C00000 +C9A4:0000000800083F8801080108020806080908308800087FE80008000800080000 +C9A5:000000083F0802080D083088000800087FE8000007F800080008000800080000 +C9A6:000000083F0802080D083088000800087FE8000000003EF80208020802080000 +C9A7:000000083F0802080D083088000800087FE8000000001F080108011401620000 +C9A8:000000083F0802080D083088000800087FE8000008000800080008000FF80000 +C9A9:000000083F0802080D083088000800087FE80000000010F8101010301ECC0000 +C9AA:000000083F0802080D083088000800087FE800000808087F081C08220F9C0000 +C9AB:000000083F0802080D083088000800087FE8000003F802000200020003F80000 +C9AC:000000083F0802080D083088000800087FE8000007F8000807F8040007F80000 +C9AD:000000083F0802080D083088000800087FE800003EF802083E0820083E080000 +C9AE:000000083F0802080D083088000800087FE800003EF802883E8820883EF80000 +C9AF:000000083F0802080D083088000800087FE800003E8802883EF820883EF80000 +C9B0:000000083F0802080D083088000800087FE800001F0801081F0810141F620000 +C9B1:000000083F0802080D083088000800087FE800003EF802803EF820803EF80000 +C9B2:000000083F0802080D083088000800087FE800003EFC02483E4820483EFC0000 +C9B3:000000083F0802080D083088000800087FE800001F08017F1F1C10221F1C0000 +C9B4:000000083F0802080D083088000800087FE8000003F802080208020803F80000 +C9B5:000000083F0802080D083088000800087FE800000208020803F8020803F80000 +C9B6:000000083F0802080D083088000800087FE80000110811081F0811141F620000 +C9B7:000000083F0802080D083088000800087FE80000001000100010006801840000 +C9B8:000000083F0802080D083088000800087FE800000048004800A8011406620000 +C9B9:000000083F0802080D083088000800087FE80000000003F00408040803F00000 +C9BA:000000083F0802080D083088000800087FE8000003F80020002000D003080000 +C9BB:000000083F0802080D083088000800087FE80000004003F8004000A003180000 +C9BC:000000083F0802080D083088000800087FE8000003F8000803F8000800080000 +C9BD:000000083F0802080D083088000800087FE8000003F8020003F8020003F80000 +C9BE:000000083F0802080D083088000800087FE8000000000FF8022002200FF80000 +C9BF:000000083F0802080D083088000800087FE8000000800FF803E0041003E00000 +C9C0:00000000000800083F8801080108020806080908308800080008000800080000 +C9C1:0000000800087E08040804081A08610800080000000007F80008000800080000 +C9C2:0000000800087E08040804081A0861080008000000003EF80208020802080000 +C9C3:0000000800087E08040804081A0861080008000000001F080108011401620000 +C9C4:0000000800087E08040804081A0861080008000800001000100010001FF80000 +C9C5:0000000800087E08040804081A08610800080000000020F8201020303ECC0000 +C9C6:0000000800087E08040804081A08610800080000202021FC207020883E700000 +C9C7:0000000800087E08040804081A0861080008000003F802000200020003F80000 +C9C8:0000000800087E08040804081A0861080008000007F8000807F8040007F80000 +C9C9:0000000800087E08040804081A086108000800003EF802083E0820083E080000 +C9CA:0000000800087E08040804081A086108000800003EF802883E8820883EF80000 +C9CB:0000000800087E08040804081A086108000800003E8802883EF820883EF80000 +C9CC:0000000800087E08040804081A086108000800000F8800880F8808140FA20000 +C9CD:0000000800087E08040804081A086108000800003EF802803EF820803EF80000 +C9CE:0000000800087E08040804081A086108000800003EFC02483E4820483EFC0000 +C9CF:0000000800087E08040804081A086108000800003E1002FE3E3820443E380000 +C9D0:0000000800087E08040804081A0861080008000003F802080208020803F80000 +C9D1:0000000800087E08040804081A086108000800000208020803F8020803F80000 +C9D2:0000000800087E08040804081A08610800080000210821083F0821143F620000 +C9D3:0000000800087E08040804081A08610800080000001000100010006801840000 +C9D4:0000000800087E08040804081A086108000800000048004800A8011406620000 +C9D5:0000000800087E08040804081A08610800080000000003F00408040803F00000 +C9D6:0000000800087E08040804081A0861080008000003F80020002000D003080000 +C9D7:0000000800087E08040804081A08610800080000004003F8004000A003180000 +C9D8:0000000800087E08040804081A0861080008000003F8000803F8000800080000 +C9D9:0000000800087E08040804081A0861080008000003F8020003F8020003F80000 +C9DA:0000000800087E08040804081A0861080008000000000FF8022002200FF80000 +C9DB:0000000800087E08040804081A0861080008000000800FF803E0041003E00000 +C9DC:00000000001000107B9008900890191E15102290CC5000100010001000100000 +C9DD:00000008000877082208220E550888880008000007F800080008000800080000 +C9DE:00000008000877082208220E550888880008000000003EF80208020802080000 +C9DF:00000008000877082208220E550888880008000000001F080108011401620000 +C9E0:00000008000877082208220E550888880008000808000800080008000FF80000 +C9E1:00000008000877082208220E5508888800080000000010F8101010301ECC0000 +C9E2:00000008000877082208220E55088888000800000808087F081C08220F9C0000 +C9E3:00000008000877082208220E550888880008000003F802000200020003F80000 +C9E4:00000008000877082208220E550888880008000007F8000807F8040007F80000 +C9E5:00000008000877082208220E55088888000800003EF802083E0820083E080000 +C9E6:00000008000877082208220E55088888000800003EF802883E8820883EF80000 +C9E7:00000008000877082208220E55088888000800003E8802883EF820883EF80000 +C9E8:00000008000877082208220E55088888000800001F0801081F0810141F620000 +C9E9:00000008000877082208220E55088888000800003EF802803EF820803EF80000 +C9EA:00000008000877082208220E55088888000800003EFC02483E4820483EFC0000 +C9EB:00000008000877082208220E55088888000800001F08017F1F1C10221F1C0000 +C9EC:00000008000877082208220E550888880008000003F802080208020803F80000 +C9ED:00000008000877082208220E55088888000800000208020803F8020803F80000 +C9EE:00000008000877082208220E5508888800080000110811081F0811141F620000 +C9EF:00000008000877082208220E5508888800080000001000100010006801840000 +C9F0:00000008000877082208220E55088888000800000048004800A8011406620000 +C9F1:00000008000877082208220E5508888800080000000003F00408040803F00000 +C9F2:00000008000877082208220E550888880008000003F80020002000D003080000 +C9F3:00000008000877082208220E5508888800080000004003F8004000A003180000 +C9F4:00000008000877082208220E550888880008000003F8000803F8000800080000 +C9F5:00000008000877082208220E550888880008000003F8020003F8020003F80000 +C9F6:00000008000877082208220E550888880008000000000FF8022002200FF80000 +C9F7:00000008000877082208220E550888880008000000800FF803E0041003E00000 +C9F8:00000000001200127B9208920892191E15122292CC5200120012001200120000 +C9F9:000000280028772822282238552888A80028000007F800080008000800080000 +C9FA:000000280028772822282238552888A80028000000003EF80208020802080000 +C9FB:000000280028772822282238552888A80028000000003E100210022802C40000 +C9FC:000000280028772822282238552888A80028002808000800080008000FF80000 +C9FD:000000280028772822282238552888A800280000000020F8201020303ECC0000 +C9FE:000000280028772822282238552888A800280000202021FC207020883E700000 +C9FF:000000280028772822282238552888A80028000003F802000200020003F80000 +CA00:000000280028772822282238552888A80028000007F8000807F8040007F80000 +CA01:000000280028772822282238552888A8002800003EF802083E0820083E080000 +CA02:000000280028772822282238552888A8002800003EF802883E8820883EF80000 +CA03:000000280028772822282238552888A8002800003E8802883EF820883EF80000 +CA04:000000280028772822282238552888A8002800001F0801081F0810141F620000 +CA05:000000280028772822282238552888A8002800003EF802803EF820803EF80000 +CA06:000000280028772822282238552888A8002800003EFC02483E4820483EFC0000 +CA07:000000280028772822282238552888A8002800003E1002FE3E3820443E380000 +CA08:000000280028772822282238552888A80028000003F802080208020803F80000 +CA09:000000280028772822282238552888A8002800000208020803F8020803F80000 +CA0A:000000280028772822282238552888A800280000110811081F0811141F620000 +CA0B:000000280028772822282238552888A800280000000800080008003400C20000 +CA0C:000000280028772822282238552888A8002800000048004800A8011406620000 +CA0D:000000280028772822282238552888A800280000000001F00208020801F00000 +CA0E:000000280028772822282238552888A80028000003F80020002000D003080000 +CA0F:000000280028772822282238552888A800280000004003F8004000A003180000 +CA10:000000280028772822282238552888A80028000003F8000803F8000800080000 +CA11:000000280028772822282238552888A80028000003F8020003F8020003F80000 +CA12:000000280028772822282238552888A80028000000000FF8022002200FF80000 +CA13:000000280028772822282238552888A80028000000800FF803E0041003E00000 +CA14:00000000001000107B900890089E19101510229ECC5000100010001000100000 +CA15:0000000800087708220E2208550E88880008000007F800080008000800080000 +CA16:0000000800087708220E2208550E88880008000000003EF80208020802080000 +CA17:0000000800087708220E2208550E88880008000000001F080108011401620000 +CA18:0000000800087708220E2208550E88880008000008000800080008000FF80000 +CA19:0000000800087708220E2208550E888800080000000010F8101010301ECC0000 +CA1A:0000000800087708220E2208550E8888000800000808087F081C08220F9C0000 +CA1B:0000000800087708220E2208550E88880008000003F802000200020003F80000 +CA1C:0000000800087708220E2208550E88880008000007F8000807F8040007F80000 +CA1D:0000000800087708220E2208550E8888000800003EF802083E0820083E080000 +CA1E:0000000800087708220E2208550E8888000800003EF802883E8820883EF80000 +CA1F:0000000800087708220E2208550E8888000800003E8802883EF820883EF80000 +CA20:0000000800087708220E2208550E8888000800001F0801081F0810141F620000 +CA21:0000000800087708220E2208550E8888000800003EF802803EF820803EF80000 +CA22:0000000800087708220E2208550E8888000800003EFC02483E4820483EFC0000 +CA23:0000000800087708220E2208550E8888000800001F08017F1F1C10221F1C0000 +CA24:0000000800087708220E2208550E88880008000003F802080208020803F80000 +CA25:0000000800087708220E2208550E8888000800000208020803F8020803F80000 +CA26:0000000800087708220E2208550E888800080000110811081F0811141F620000 +CA27:0000000800087708220E2208550E888800080000001000100010006801840000 +CA28:0000000800087708220E2208550E8888000800000048004800A8011406620000 +CA29:0000000800087708220E2208550E888800080000000003F00408040803F00000 +CA2A:0000000800087708220E2208550E88880008000003F80020002000D003080000 +CA2B:0000000800087708220E2208550E888800080000004003F8004000A003180000 +CA2C:0000000800087708220E2208550E88880008000003F8000803F8000800080000 +CA2D:0000000800087708220E2208550E88880008000003F8020003F8020003F80000 +CA2E:0000000800087708220E2208550E88880008000000000FF8022002200FF80000 +CA2F:0000000800087708220E2208550E88880008000000800FF803E0041003E00000 +CA30:00000000001200127B920892089E19121512229ECC5200120012001200120000 +CA31:000000280028772822382228553888A80028000007F800080008000800080000 +CA32:000000280028772822382228553888A80028000000003EF80208020802080000 +CA33:000000280028772822382228553888A80028000000003E100210022802C40000 +CA34:000000280028772822382228553888A80028002808000800080008000FF80000 +CA35:000000280028772822382228553888A800280000000020F8201020303ECC0000 +CA36:000000280028772822382228553888A800280000202021FC207020883E700000 +CA37:000000280028772822382228553888A80028000003F802000200020003F80000 +CA38:000000280028772822382228553888A80028000007F8000807F8040007F80000 +CA39:000000280028772822382228553888A8002800003EF802083E0820083E080000 +CA3A:000000280028772822382228553888A8002800003EF802883E8820883EF80000 +CA3B:000000280028772822382228553888A8002800003E8802883EF820883EF80000 +CA3C:000000280028772822382228553888A8002800001F0801081F0810141F620000 +CA3D:000000280028772822382228553888A8002800003EF802803EF820803EF80000 +CA3E:000000280028772822382228553888A8002800003EFC02483E4820483EFC0000 +CA3F:000000280028772822382228553888A8002800003E1002FE3E3820443E380000 +CA40:000000280028772822382228553888A80028000003F802080208020803F80000 +CA41:000000280028772822382228553888A8002800000208020803F8020803F80000 +CA42:000000280028772822382228553888A800280000110811081F0811141F620000 +CA43:000000280028772822382228553888A800280000000800080008003400C20000 +CA44:000000280028772822382228553888A8002800000048004800A8011406620000 +CA45:000000280028772822382228553888A800280000000001F00208020801F00000 +CA46:000000280028772822382228553888A80028000003F80020002000D003080000 +CA47:000000280028772822382228553888A800280000004003F8004000A003180000 +CA48:000000280028772822382228553888A80028000003F8000803F8000800080000 +CA49:000000280028772822382228553888A80028000003F8020003F8020003F80000 +CA4A:000000280028772822382228553888A80028000000000FF8022002200FF80000 +CA4B:000000280028772822382228553888A80028000000800FF803E0041003E00000 +CA4C:00000000000200027B8208820882191E15022282CC4200020002000200020000 +CA4D:0000000800087708220822385508888800080000000007F80008000800080000 +CA4E:000000080008770822082238550888880008000000003EF80208020802080000 +CA4F:000000080008770822082238550888880008000000001F080108011401620000 +CA50:000000080008770822082238550888880008000000001000100010001FF80000 +CA51:0000000800087708220822385508888800080000000020F8201020303ECC0000 +CA52:0000000800087708220822385508888800080000202021FC207020883E700000 +CA53:000000080008770822082238550888880008000003F802000200020003F80000 +CA54:000000080008770822082238550888880008000007F8000807F8040007F80000 +CA55:00000008000877082208223855088888000800003EF802083E0820083E080000 +CA56:00000008000877082208223855088888000800003EF802883E8820883EF80000 +CA57:00000008000877082208223855088888000800003E8802883EF820883EF80000 +CA58:00000008000877082208223855088888000800000F8800880F8808140FA20000 +CA59:00000008000877082208223855088888000800003EF802803EF820803EF80000 +CA5A:00000008000877082208223855088888000800003EFC02483E4820483EFC0000 +CA5B:00000008000877082208223855088888000800003E1002FE3E3820443E380000 +CA5C:000000080008770822082238550888880008000003F802080208020803F80000 +CA5D:00000008000877082208223855088888000800000208020803F8020803F80000 +CA5E:0000000800087708220822385508888800080000210821083F0821143F620000 +CA5F:0000000800087708220822385508888800080000001000100010006801840000 +CA60:00000008000877082208223855088888000800000048004800A8011406620000 +CA61:0000000800087708220822385508888800080000000003F00408040803F00000 +CA62:000000080008770822082238550888880008000003F80020002000D003080000 +CA63:0000000800087708220822385508888800080000004003F8004000A003180000 +CA64:000000080008770822082238550888880008000003F8000803F8000800080000 +CA65:000000080008770822082238550888880008000003F8020003F8020003F80000 +CA66:000000080008770822082238550888880008000000000FF8022002200FF80000 +CA67:000000080008770822082238550888880008000000800FF803E0041003E00000 +CA68:00000000000A000A7B8A088A088A193A150A228ACC4A000A000A000A000A0000 +CA69:0000002800287728222822E8552888A80028000007F800080008000800080000 +CA6A:0000002800287728222822E8552888A80028000000003EF80208020802080000 +CA6B:0000002800287728222822E8552888A80028000000003E100210022802C40000 +CA6C:0000002800287728222822E8552888A80028000008000800080008000FF80000 +CA6D:0000002800287728222822E8552888A800280000000020F8201020303ECC0000 +CA6E:0000002800287728222822E8552888A800280000202021FC207020883E700000 +CA6F:0000002800287728222822E8552888A80028000003F802000200020003F80000 +CA70:0000002800287728222822E8552888A80028000007F8000807F8040007F80000 +CA71:0000002800287728222822E8552888A8002800003EF802083E0820083E080000 +CA72:0000002800287728222822E8552888A8002800003EF802883E8820883EF80000 +CA73:0000002800287728222822E8552888A8002800003E8802883EF820883EF80000 +CA74:0000002800287728222822E8552888A8002800001F0801081F0810141F620000 +CA75:0000002800287728222822E8552888A8002800003EF802803EF820803EF80000 +CA76:0000002800287728222822E8552888A8002800003EFC02483E4820483EFC0000 +CA77:0000002800287728222822E8552888A8002800003E1002FE3E3820443E380000 +CA78:0000002800287728222822E8552888A80028000003F802080208020803F80000 +CA79:0000002800287728222822E8552888A8002800000208020803F8020803F80000 +CA7A:0000002800287728222822E8552888A800280000110811081F0811141F620000 +CA7B:0000002800287728222822E8552888A800280000000800080008003400C20000 +CA7C:0000002800287728222822E8552888A8002800000048004800A8011406620000 +CA7D:0000002800287728222822E8552888A800280000000001F00208020801F00000 +CA7E:0000002800287728222822E8552888A80028000003F80020002000D003080000 +CA7F:0000002800287728222822E8552888A800280000004003F8004000A003180000 +CA80:0000002800287728222822E8552888A80028000003F8000803F8000800080000 +CA81:0000002800287728222822E8552888A80028000003F8020003F8020003F80000 +CA82:0000002800287728222822E8552888A80028000000000FF8022002200FF80000 +CA83:0000002800287728222822E8552888A80028000000800FF803E0041003E00000 +CA84:00000000000200027B820882089E19021502229ECC4200020002000200020000 +CA85:0000000800087708223822085538888800080000000007F80008000800080000 +CA86:000000080008770822382208553888880008000000003EF80208020802080000 +CA87:000000080008770822382208553888880008000000001F080108011401620000 +CA88:000000080008770822382208553888880008000800001000100010001FF80000 +CA89:0000000800087708223822085538888800080000000020F8201020303ECC0000 +CA8A:0000000800087708223822085538888800080000202021FC207020883E700000 +CA8B:000000080008770822382208553888880008000003F802000200020003F80000 +CA8C:000000080008770822382208553888880008000007F8000807F8040007F80000 +CA8D:00000008000877082238220855388888000800003EF802083E0820083E080000 +CA8E:00000008000877082238220855388888000800003EF802883E8820883EF80000 +CA8F:00000008000877082238220855388888000800003E8802883EF820883EF80000 +CA90:00000008000877082238220855388888000800000F8800880F8808140FA20000 +CA91:00000008000877082238220855388888000800003EF802803EF820803EF80000 +CA92:00000008000877082238220855388888000800003EFC02483E4820483EFC0000 +CA93:00000008000877082238220855388888000800003E1002FE3E3820443E380000 +CA94:000000080008770822382208553888880008000003F802080208020803F80000 +CA95:00000008000877082238220855388888000800000208020803F8020803F80000 +CA96:0000000800087708223822085538888800080000210821083F0821143F620000 +CA97:0000000800087708223822085538888800080000001000100010006801840000 +CA98:00000008000877082238220855388888000800000048004800A8011406620000 +CA99:0000000800087708223822085538888800080000000003F00408040803F00000 +CA9A:000000080008770822382208553888880008000003F80020002000D003080000 +CA9B:0000000800087708223822085538888800080000004003F8004000A003180000 +CA9C:000000080008770822382208553888880008000003F8000803F8000800080000 +CA9D:000000080008770822382208553888880008000003F8020003F8020003F80000 +CA9E:000000080008770822382208553888880008000000000FF8022002200FF80000 +CA9F:000000080008770822382208553888880008000000800FF803E0041003E00000 +CAA0:00000000000A000A7B8A088A08BA190A150A22BACC4A000A000A000A000A0000 +CAA1:000000280028772822E8222855E888A80028000007F800080008000800080000 +CAA2:000000280028772822E8222855E888A80028000000003EF80208020802080000 +CAA3:000000280028772822E8222855E888A80028000000003E100210022802C40000 +CAA4:000000280028772822E8222855E888A80028002808000800080008000FF80000 +CAA5:000000280028772822E8222855E888A800280000000020F8201020303ECC0000 +CAA6:000000280028772822E8222855E888A800280000202021FC207020883E700000 +CAA7:000000280028772822E8222855E888A80028000003F802000200020003F80000 +CAA8:000000280028772822E8222855E888A80028000007F8000807F8040007F80000 +CAA9:000000280028772822E8222855E888A8002800003EF802083E0820083E080000 +CAAA:000000280028772822E8222855E888A8002800003EF802883E8820883EF80000 +CAAB:000000280028772822E8222855E888A8002800003E8802883EF820883EF80000 +CAAC:000000280028772822E8222855E888A8002800001F0801081F0810141F620000 +CAAD:000000280028772822E8222855E888A8002800003EF802803EF820803EF80000 +CAAE:000000280028772822E8222855E888A8002800003EFC02483E4820483EFC0000 +CAAF:000000280028772822E8222855E888A8002800003E1002FE3E3820443E380000 +CAB0:000000280028772822E8222855E888A80028000003F802080208020803F80000 +CAB1:000000280028772822E8222855E888A8002800000208020803F8020803F80000 +CAB2:000000280028772822E8222855E888A800280000110811081F0811141F620000 +CAB3:000000280028772822E8222855E888A800280000000800080008003400C20000 +CAB4:000000280028772822E8222855E888A8002800000048004800A8011406620000 +CAB5:000000280028772822E8222855E888A800280000000001F00208020801F00000 +CAB6:000000280028772822E8222855E888A80028000003F80020002000D003080000 +CAB7:000000280028772822E8222855E888A800280000004003F8004000A003180000 +CAB8:000000280028772822E8222855E888A80028000003F8000803F8000800080000 +CAB9:000000280028772822E8222855E888A80028000003F8020003F8020003F80000 +CABA:000000280028772822E8222855E888A80028000000000FF8022002200FF80000 +CABB:000000280028772822E8222855E888A80028000000800FF803E0041003E00000 +CABC:0000000000001EE0022002200640054008A033100100010001007FFC00000000 +CABD:00003DE00440088015402220010001007FFC00001FF000100010001000100000 +CABE:00003DE00440088015402220010001007FFC000000003EF80208020802080000 +CABF:00003DE00440088015402220010001007FFC000000001E100210022802C40000 +CAC0:00003DE00440088015402220010001007FFC000000001000100010001FF00000 +CAC1:00003DE00440088015402220010001007FFC0000000020F8201020303ECC0000 +CAC2:00003DE00440088015402220010001007FFC0000202021FC207020883E700000 +CAC3:00003DE00440088015402220010001007FFC00001FF01000100010001FF00000 +CAC4:00003DE00440088015402220010001007FFC00001FF000101FF010001FF00000 +CAC5:00003DE00440088015402220010001007FFC00003EF802083E0820083E080000 +CAC6:00003DE00440088015402220010001007FFC00003EF802883E8820883EF80000 +CAC7:00003DE00440088015402220010001007FFC00003E8802883EF820883EF80000 +CAC8:00003DE00440088015402220010001007FFC00003E1002103E1020283EC40000 +CAC9:00003DE00440088015402220010001007FFC00003EF802803EF820803EF80000 +CACA:00003DE00440088015402220010001007FFC00003EFC02483E4820483EFC0000 +CACB:00003DE00440088015402220010001007FFC00003E2003FC3E7020883E700000 +CACC:00003DE00440088015402220010001007FFC00001FF01010101010101FF00000 +CACD:00003DE00440088015402220010001007FFC0000101010101FF010101FF00000 +CACE:00003DE00440088015402220010001007FFC0000222022203E2022503E880000 +CACF:00003DE00440088015402220010001007FFC000000000100010002800C400000 +CAD0:00003DE00440088015402220010001007FFC00000000024002400DA033100000 +CAD1:00003DE00440088015402220010001007FFC0000000007C00820082007C00000 +CAD2:00003DE00440088015402220010001007FFC0000000007E00080014006200000 +CAD3:00003DE00440088015402220010001007FFC0000008007E00080014006200000 +CAD4:00003DE00440088015402220010001007FFC00001FF000101FF0001000100000 +CAD5:00003DE00440088015402220010001007FFC00001FF010001FF010001FF00000 +CAD6:00003DE00440088015402220010001007FFC000000001FF0044004401FF00000 +CAD7:00003DE00440088015402220010001007FFC000001001FF007C0082007C00000 +CAD8:0000001000107B90089008901910151E2290CC50041004107FD0001000100000 +CAD9:00007BC8088811082A8E4448040804087FE8000007F800080008000800080000 +CADA:00007BC8088811082A8E4448040804087FE8000000003EF80208020802080000 +CADB:00007BC8088811082A8E4448040804087FE8000000001F080108011401620000 +CADC:00007BC8088811082A8E4448040804087FE8000008000800080008000FF80000 +CADD:00007BC8088811082A8E4448040804087FE80000000010F8101010301ECC0000 +CADE:00007BC8088811082A8E4448040804087FE800000808087F081C08220F9C0000 +CADF:00007BC8088811082A8E4448040804087FE8000003F802000200020003F80000 +CAE0:00007BC8088811082A8E4448040804087FE8000007F8000807F8040007F80000 +CAE1:00007BC8088811082A8E4448040804087FE800003EF802083E0820083E080000 +CAE2:00007BC8088811082A8E4448040804087FE800003EF802883E8820883EF80000 +CAE3:00007BC8088811082A8E4448040804087FE800003E8802883EF820883EF80000 +CAE4:00007BC8088811082A8E4448040804087FE800001F0801081F0810141F620000 +CAE5:00007BC8088811082A8E4448040804087FE800003EF802803EF820803EF80000 +CAE6:00007BC8088811082A8E4448040804087FE800003EFC02483E4820483EFC0000 +CAE7:00007BC8088811082A8E4448040804087FE800001F08017F1F1C10221F1C0000 +CAE8:00007BC8088811082A8E4448040804087FE8000003F802080208020803F80000 +CAE9:00007BC8088811082A8E4448040804087FE800000208020803F8020803F80000 +CAEA:00007BC8088811082A8E4448040804087FE80000110811081F0811141F620000 +CAEB:00007BC8088811082A8E4448040804087FE80000001000100010006801840000 +CAEC:00007BC8088811082A8E4448040804087FE800000048004800A8011406620000 +CAED:00007BC8088811082A8E4448040804087FE80000000003F00408040803F00000 +CAEE:00007BC8088811082A8E4448040804087FE8000003F80020002000D003080000 +CAEF:00007BC8088811082A8E4448040804087FE80000004003F8004000A003180000 +CAF0:00007BC8088811082A8E4448040804087FE8000003F8000803F8000800080000 +CAF1:00007BC8088811082A8E4448040804087FE8000003F8020003F8020003F80000 +CAF2:00007BC8088811082A8E4448040804087FE8000000000FF8022002200FF80000 +CAF3:00007BC8088811082A8E4448040804087FE8000000800FF803E0041003E00000 +CAF4:0000001200127B92089208921912151E2292CC52041204127FD2001200120000 +CAF5:00007BE808A811282AB84468042804287FA8000007F800080008000800080000 +CAF6:00007BE808A811282AB84468042804287FA8000000003EF80208020802080000 +CAF7:00007BE808A811282AB84468042804287FA8000000001F080108011401620000 +CAF8:00007BE808A811282AB84468042804287FA8000008000800080008000FF80000 +CAF9:00007BE808A811282AB84468042804287FA80000000010F8101010301ECC0000 +CAFA:00007BE808A811282AB84468042804287FA800000808087F081C08220F9C0000 +CAFB:00007BE808A811282AB84468042804287FA8000003F802000200020003F80000 +CAFC:00007BE808A811282AB84468042804287FA8000007F8000807F8040007F80000 +CAFD:00007BE808A811282AB84468042804287FA800003EF802083E0820083E080000 +CAFE:00007BE808A811282AB84468042804287FA800003EF802883E8820883EF80000 +CAFF:00007BE808A811282AB84468042804287FA800003E8802883EF820883EF80000 +CB00:00007BE808A811282AB84468042804287FA800001F0801081F0810141F620000 +CB01:00007BE808A811282AB84468042804287FA800003EF802803EF820803EF80000 +CB02:00007BE808A811282AB84468042804287FA800003EFC02483E4820483EFC0000 +CB03:00007BE808A811282AB84468042804287FA800001F08017F1F1C10221F1C0000 +CB04:00007BE808A811282AB84468042804287FA8000003F802080208020803F80000 +CB05:00007BE808A811282AB84468042804287FA800000208020803F8020803F80000 +CB06:00007BE808A811282AB84468042804287FA80000110811081F0811141F620000 +CB07:00007BE808A811282AB84468042804287FA80000001000100010006801840000 +CB08:00007BE808A811282AB84468042804287FA800000048004800A8011406620000 +CB09:00007BE808A811282AB84468042804287FA80000000003F00408040803F00000 +CB0A:00007BE808A811282AB84468042804287FA8000003F80020002000D003080000 +CB0B:00007BE808A811282AB84468042804287FA80000004003F8004000A003180000 +CB0C:00007BE808A811282AB84468042804287FA8000003F8000803F8000800080000 +CB0D:00007BE808A811282AB84468042804287FA8000003F8020003F8020003F80000 +CB0E:00007BE808A811282AB84468042804287FA8000000000FF8022002200FF80000 +CB0F:00007BE808A811282AB84468042804287FA8000000800FF803E0041003E00000 +CB10:0000000800087B8808880888190815082288CC48040804087FE8000800080000 +CB11:00007BC8088811082A884448040804087FE8000007F800080008000800080000 +CB12:00007BC8088811082A884448040804087FE8000000003EF80208020802080000 +CB13:00007BC8088811082A884448040804087FE8000000001F080108011401620000 +CB14:00007BC8088811082A884448040804087FE8000008000800080008000FF80000 +CB15:00007BC8088811082A884448040804087FE80000000010F8101010301ECC0000 +CB16:00007BC8088811082A884448040804087FE800000808087F081C08220F9C0000 +CB17:00007BC8088811082A884448040804087FE8000003F802000200020003F80000 +CB18:00007BC8088811082A884448040804087FE8000007F8000807F8040007F80000 +CB19:00007BC8088811082A884448040804087FE800003EF802083E0820083E080000 +CB1A:00007BC8088811082A884448040804087FE800003EF802883E8820883EF80000 +CB1B:00007BC8088811082A884448040804087FE800003E8802883EF820883EF80000 +CB1C:00007BC8088811082A884448040804087FE800001F0801081F0810141F620000 +CB1D:00007BC8088811082A884448040804087FE800003EF802803EF820803EF80000 +CB1E:00007BC8088811082A884448040804087FE800003EFC02483E4820483EFC0000 +CB1F:00007BC8088811082A884448040804087FE800001F08017F1F1C10221F1C0000 +CB20:00007BC8088811082A884448040804087FE8000003F802080208020803F80000 +CB21:00007BC8088811082A884448040804087FE800000208020803F8020803F80000 +CB22:00007BC8088811082A884448040804087FE80000110811081F0811141F620000 +CB23:00007BC8088811082A884448040804087FE80000001000100010006801840000 +CB24:00007BC8088811082A884448040804087FE800000048004800A8011406620000 +CB25:00007BC8088811082A884448040804087FE80000000003F00408040803F00000 +CB26:00007BC8088811082A884448040804087FE8000003F80020002000D003080000 +CB27:00007BC8088811082A884448040804087FE80000004003F8004000A003180000 +CB28:00007BC8088811082A884448040804087FE8000003F8000803F8000800080000 +CB29:00007BC8088811082A884448040804087FE8000003F8020003F8020003F80000 +CB2A:00007BC8088811082A884448040804087FE8000000000FF8022002200FF80000 +CB2B:00007BC8088811082A884448040804087FE8000000800FF803E0041003E00000 +CB2C:0000000000001EE0022002200640054008A037500440044004407FFC00000000 +CB2D:00003DE00440088015402220044004407FFC00001FF000100010001000100000 +CB2E:00003DE00440088015402220044004407FFC000000003EF80208020802080000 +CB2F:00003DE00440088015402220044004407FFC000000001E100210022802C40000 +CB30:00003DE00440088015402220044004407FFC000000001000100010001FF00000 +CB31:00003DE00440088015402220044004407FFC0000000020F8201020303ECC0000 +CB32:00003DE00440088015402220044004407FFC0000202021FC207020883E700000 +CB33:00003DE00440088015402220044004407FFC00001FF01000100010001FF00000 +CB34:00003DE00440088015402220044004407FFC00001FF000101FF010001FF00000 +CB35:00003DE00440088015402220044004407FFC00003EF802083E0820083E080000 +CB36:00003DE00440088015402220044004407FFC00003EF802883E8820883EF80000 +CB37:00003DE00440088015402220044004407FFC00003E8802883EF820883EF80000 +CB38:00003DE00440088015402220044004407FFC00003E1002103E1020283EC40000 +CB39:00003DE00440088015402220044004407FFC00003EF802803EF820803EF80000 +CB3A:00003DE00440088015402220044004407FFC00003EFC02483E4820483EFC0000 +CB3B:00003DE00440088015402220044004407FFC00003E2003FC3E7020883E700000 +CB3C:00003DE00440088015402220044004407FFC00001FF01010101010101FF00000 +CB3D:00003DE00440088015402220044004407FFC0000101010101FF010101FF00000 +CB3E:00003DE00440088015402220044004407FFC0000222022203E2022503E880000 +CB3F:00003DE00440088015402220044004407FFC000000000100010002800C400000 +CB40:00003DE00440088015402220044004407FFC00000000024002400DA033100000 +CB41:00003DE00440088015402220044004407FFC0000000007C00820082007C00000 +CB42:00003DE00440088015402220044004407FFC0000000007E00080014006200000 +CB43:00003DE00440088015402220044004407FFC0000008007E00080014006200000 +CB44:00003DE00440088015402220044004407FFC00001FF000101FF0001000100000 +CB45:00003DE00440088015402220044004407FFC00001FF010001FF010001FF00000 +CB46:00003DE00440088015402220044004407FFC000000001FF0044004401FF00000 +CB47:00003DE00440088015402220044004407FFC000001001FF007C0082007C00000 +CB48:000000001EE0022002200640054008A0331000003FF801000100010001000000 +CB49:00003DE0044008801540222000007FFC010001001FF000100010001000100000 +CB4A:00003DE0044008801540222000007FFC0100010000003EF80208020802080000 +CB4B:00003DE0044008801540222000007FFC0100010000001E100210022802C40000 +CB4C:00003DE00440088015402220000000007FFC010001001100100010001FF00000 +CB4D:00003DE0044008801540222000007FFC01000100000020F8201020303ECC0000 +CB4E:00003DE0044008801540222000007FFC01000100202021FC207020883E700000 +CB4F:00003DE0044008801540222000007FFC010001001FF01000100010001FF00000 +CB50:00003DE0044008801540222000007FFC010001001FF000101FF010001FF00000 +CB51:00003DE0044008801540222000007FFC010001003EF802083E0820083E080000 +CB52:00003DE0044008801540222000007FFC010001003EF802883E8820883EF80000 +CB53:00003DE0044008801540222000007FFC010001003E8802883EF820883EF80000 +CB54:00003DE0044008801540222000007FFC010001003E1002103E1020283EC40000 +CB55:00003DE0044008801540222000007FFC010001003EF802803EF820803EF80000 +CB56:00003DE0044008801540222000007FFC010001003EFC02483E4820483EFC0000 +CB57:00003DE0044008801540222000007FFC010001003E2003FC3E7020883E700000 +CB58:00003DE0044008801540222000007FFC010001001FF01010101010101FF00000 +CB59:00003DE0044008801540222000007FFC01000100101010101FF010101FF00000 +CB5A:00003DE0044008801540222000007FFC01000100222022203E2022503E880000 +CB5B:00003DE0044008801540222000007FFC0100010000000100010002800C400000 +CB5C:00003DE0044008801540222000007FFC010001000000024002400DA033100000 +CB5D:00003DE0044008801540222000007FFC01000100000007C00820082007C00000 +CB5E:00003DE0044008801540222000007FFC01000100000007E00080014006200000 +CB5F:00003DE0044008801540222000007FFC01000100008007E00080014006200000 +CB60:00003DE0044008801540222000007FFC010001001FF000101FF0001000100000 +CB61:00003DE0044008801540222000007FFC010001001FF010001FF010001FF00000 +CB62:00003DE0044008801540222000007FFC0100010000001FF0044004401FF00000 +CB63:00003DE0044008801540222000007FFC0100010001001FF007C0082007C00000 +CB64:000000087B8808880888190815082288CC4800087FE8040804F8040804080000 +CB65:7BC8088811082A88444800087FE8027802080000000007F80008000800080000 +CB66:7BC8088811082A88444800087FE802780208000000003EF80208020802080000 +CB67:7BC8088811082A88444800087FE802780208000000001F080108011401620000 +CB68:7BC8088811082A884448000800087FE80278020802081000100010001FF80000 +CB69:7BC8088811082A88444800087FE8027802080000000020F8201020303ECC0000 +CB6A:7BC8088811082A88444800087FE8027802080000202021FC207020883E700000 +CB6B:7BC8088811082A88444800087FE802780208000003F802000200020003F80000 +CB6C:7BC8088811082A88444800087FE802780208000007F8000807F8040007F80000 +CB6D:7BC8088811082A88444800087FE80278020800003EF802083E0820083E080000 +CB6E:7BC8088811082A88444800087FE80278020800003EF802883E8820883EF80000 +CB6F:7BC8088811082A88444800087FE80278020800003E8802883EF820883EF80000 +CB70:7BC8088811082A88444800087FE80278020800000F8800880F8808140FA20000 +CB71:7BC8088811082A88444800087FE80278020800003EF802803EF820803EF80000 +CB72:7BC8088811082A88444800087FE80278020800003EFC02483E4820483EFC0000 +CB73:7BC8088811082A88444800087FE80278020800003E1002FE3E3820443E380000 +CB74:7BC8088811082A88444800087FE802780208000003F802080208020803F80000 +CB75:7BC8088811082A88444800087FE80278020800000208020803F8020803F80000 +CB76:7BC8088811082A88444800087FE8027802080000210821083F0821143F620000 +CB77:7BC8088811082A88444800087FE8027802080000001000100010006801840000 +CB78:7BC8088811082A88444800087FE80278020800000048004800A8011406620000 +CB79:7BC8088811082A88444800087FE8027802080000000003F00408040803F00000 +CB7A:7BC8088811082A88444800087FE802780208000003F80020002000D003080000 +CB7B:7BC8088811082A88444800087FE8027802080000004003F8004000A003180000 +CB7C:7BC8088811082A88444800087FE802780208000003F8000803F8000800080000 +CB7D:7BC8088811082A88444800087FE802780208000003F8020003F8020003F80000 +CB7E:7BC8088811082A88444800087FE802780208000000000FF8022002200FF80000 +CB7F:7BC8088811082A88444800087FE802780208000000800FF803E0041003E00000 +CB80:0000000A7B8A088A088A190A150A228ACC4A000A7FEA040A047A040A040A0000 +CB81:7BE808A811282AA8446800287FA805E804280000000007F80008000800080000 +CB82:7BE808A811282AA8446800287FA805E80428000000003EF80208020802080000 +CB83:7BE808A811282AA8446800287FA805E80428000000001F080108011401620000 +CB84:7BE808A811282AA84468002800287FA8042805E804281428100010001FF80000 +CB85:7BE808A811282AA8446800287FA805E804280000000020F8201020303ECC0000 +CB86:7BE808A811282AA8446800287FA805E804280000202021FC207020883E700000 +CB87:7BE808A811282AA8446800287FA805E80428000003F802000200020003F80000 +CB88:7BE808A811282AA8446800287FA805E80428000007F8000807F8040007F80000 +CB89:7BE808A811282AA8446800287FA805E8042800003EF802083E0820083E080000 +CB8A:7BE808A811282AA8446800287FA805E8042800003EF802883E8820883EF80000 +CB8B:7BE808A811282AA8446800287FA805E8042800003E8802883EF820883EF80000 +CB8C:7BE808A811282AA8446800287FA805E8042800000F8800880F8808140FA20000 +CB8D:7BE808A811282AA8446800287FA805E8042800003EF802803EF820803EF80000 +CB8E:7BE808A811282AA8446800287FA805E8042800003EFC02483E4820483EFC0000 +CB8F:7BE808A811282AA8446800287FA805E8042800003E1002FE3E3820443E380000 +CB90:7BE808A811282AA8446800287FA805E80428000003F802080208020803F80000 +CB91:7BE808A811282AA8446800287FA805E8042800000208020803F8020803F80000 +CB92:7BE808A811282AA8446800287FA805E804280000210821083F0821143F620000 +CB93:7BE808A811282AA8446800287FA805E804280000001000100010006801840000 +CB94:7BE808A811282AA8446800287FA805E8042800000048004800A8011406620000 +CB95:7BE808A811282AA8446800287FA805E804280000000003F00408040803F00000 +CB96:7BE808A811282AA8446800287FA805E80428000003F80020002000D003080000 +CB97:7BE808A811282AA8446800287FA805E804280000004003F8004000A003180000 +CB98:7BE808A811282AA8446800287FA805E80428000003F8000803F8000800080000 +CB99:7BE808A811282AA8446800287FA805E80428000003F8020003F8020003F80000 +CB9A:7BE808A811282AA8446800287FA805E80428000000000FF8022002200FF80000 +CB9B:7BE808A811282AA8446800287FA805E80428000000800FF803E0041003E00000 +CB9C:000000087B8808880888190815082288CC4800087FE804080408040804080000 +CB9D:7BC8088811082A88444800087FE8020802000000000007F80008000800080000 +CB9E:7BC8088811082A88444800087FE802080200000000003EF80208020802080000 +CB9F:7BC8088811082A88444800087FE802080200000000001F080108011401620000 +CBA0:7BC8088811082A884448000800087FE80208020802081008100010001FF80000 +CBA1:7BC8088811082A88444800087FE8020802000000000020F8201020303ECC0000 +CBA2:7BC8088811082A88444800087FE8020802000000202021FC207020883E700000 +CBA3:7BC8088811082A88444800087FE802080200000003F802000200020003F80000 +CBA4:7BC8088811082A88444800087FE802080200000007F8000807F8040007F80000 +CBA5:7BC8088811082A88444800087FE80208020000003EF802083E0820083E080000 +CBA6:7BC8088811082A88444800087FE80208020000003EF802883E8820883EF80000 +CBA7:7BC8088811082A88444800087FE80208020000003E8802883EF820883EF80000 +CBA8:7BC8088811082A88444800087FE80208020000000F8800880F8808140FA20000 +CBA9:7BC8088811082A88444800087FE80208020000003EF802803EF820803EF80000 +CBAA:7BC8088811082A88444800087FE80208020000003EFC02483E4820483EFC0000 +CBAB:7BC8088811082A88444800087FE80208020000003E1002FE3E3820443E380000 +CBAC:7BC8088811082A88444800087FE802080200000003F802080208020803F80000 +CBAD:7BC8088811082A88444800087FE80208020000000208020803F8020803F80000 +CBAE:7BC8088811082A88444800087FE8020802000000210821083F0821143F620000 +CBAF:7BC8088811082A88444800087FE8020802000000001000100010006801840000 +CBB0:7BC8088811082A88444800087FE80208020000000048004800A8011406620000 +CBB1:7BC8088811082A88444800087FE8020802000000000003F00408040803F00000 +CBB2:7BC8088811082A88444800087FE802080200000003F80020002000D003080000 +CBB3:7BC8088811082A88444800087FE8020802000000004003F8004000A003180000 +CBB4:7BC8088811082A88444800087FE802080200000003F8000803F8000800080000 +CBB5:7BC8088811082A88444800087FE802080200000003F8020003F8020003F80000 +CBB6:7BC8088811082A88444800087FE802080200000000000FF8022002200FF80000 +CBB7:7BC8088811082A88444800087FE802080200000000800FF803E0041003E00000 +CBB8:000000001EE0022002200640054008A0331000007FFC04400440044004400000 +CBB9:00003DE0044008801540222000007FFC044004401FF000100010001000100000 +CBBA:00003DE0044008801540222000007FFC0440044000003EF80208020802080000 +CBBB:00003DE0044008801540222000007FFC0440044000001E100210022802C40000 +CBBC:00003DE00440088015402220000000007FFC044004401440100010001FF00000 +CBBD:00003DE0044008801540222000007FFC04400440000020F8201020303ECC0000 +CBBE:00003DE0044008801540222000007FFC04400440202021FC207020883E700000 +CBBF:00003DE0044008801540222000007FFC044004401FF01000100010001FF00000 +CBC0:00003DE0044008801540222000007FFC044004401FF000101FF010001FF00000 +CBC1:00003DE0044008801540222000007FFC044004403EF802083E0820083E080000 +CBC2:00003DE0044008801540222000007FFC044004403EF802883E8820883EF80000 +CBC3:00003DE0044008801540222000007FFC044004403E8802883EF820883EF80000 +CBC4:00003DE0044008801540222000007FFC044004403E1002103E1020283EC40000 +CBC5:00003DE0044008801540222000007FFC044004403EF802803EF820803EF80000 +CBC6:00003DE0044008801540222000007FFC044004403EFC02483E4820483EFC0000 +CBC7:00003DE0044008801540222000007FFC044004403E2003FC3E7020883E700000 +CBC8:00003DE0044008801540222000007FFC044004401FF01010101010101FF00000 +CBC9:00003DE0044008801540222000007FFC04400440101010101FF010101FF00000 +CBCA:00003DE0044008801540222000007FFC04400440222022203E2022503E880000 +CBCB:00003DE0044008801540222000007FFC0440044000000100010002800C400000 +CBCC:00003DE0044008801540222000007FFC044004400000024002400DA033100000 +CBCD:00003DE0044008801540222000007FFC04400440000007C00820082007C00000 +CBCE:00003DE0044008801540222000007FFC04400440000007E00080014006200000 +CBCF:00003DE0044008801540222000007FFC04400440008007E00080014006200000 +CBD0:00003DE0044008801540222000007FFC044004401FF000101FF0001000100000 +CBD1:00003DE0044008801540222000007FFC044004401FF010001FF010001FF00000 +CBD2:00003DE0044008801540222000007FFC0440044000001FF0044004401FF00000 +CBD3:00003DE0044008801540222000007FFC0440044001001FF007C0082007C00000 +CBD4:0000000000001EE0022002200640054008A0331000007FFC0000000000000000 +CBD5:00003DE00440088015402220000000007FFC00001FF000100010001000100000 +CBD6:00003DE00440088015402220000000007FFC000000003EF80208020802080000 +CBD7:00003DE00440088015402220000000007FFC000000001E100210022802C40000 +CBD8:00003DE00440088015402220000000007FFC000000001000100010001FF00000 +CBD9:00003DE00440088015402220000000007FFC0000000020F8201020303ECC0000 +CBDA:00003DE00440088015402220000000007FFC0000202021FC207020883E700000 +CBDB:00003DE00440088015402220000000007FFC00001FF01000100010001FF00000 +CBDC:00003DE00440088015402220000000007FFC00001FF000101FF010001FF00000 +CBDD:00003DE00440088015402220000000007FFC00003EF802083E0820083E080000 +CBDE:00003DE00440088015402220000000007FFC00003EF802883E8820883EF80000 +CBDF:00003DE00440088015402220000000007FFC00003E8802883EF820883EF80000 +CBE0:00003DE00440088015402220000000007FFC00003E1002103E1020283EC40000 +CBE1:00003DE00440088015402220000000007FFC00003EF802803EF820803EF80000 +CBE2:00003DE00440088015402220000000007FFC00003EFC02483E4820483EFC0000 +CBE3:00003DE00440088015402220000000007FFC00003E2003FC3E7020883E700000 +CBE4:00003DE00440088015402220000000007FFC00001FF01010101010101FF00000 +CBE5:00003DE00440088015402220000000007FFC0000101010101FF010101FF00000 +CBE6:00003DE00440088015402220000000007FFC0000222022203E2022503E880000 +CBE7:00003DE00440088015402220000000007FFC000000000100010002800C400000 +CBE8:00003DE00440088015402220000000007FFC00000000024002400DA033100000 +CBE9:00003DE00440088015402220000000007FFC0000000007C00820082007C00000 +CBEA:00003DE00440088015402220000000007FFC0000000007E00080014006200000 +CBEB:00003DE00440088015402220000000007FFC0000008007E00080014006200000 +CBEC:00003DE00440088015402220000000007FFC00001FF000101FF0001000100000 +CBED:00003DE00440088015402220000000007FFC00001FF010001FF010001FF00000 +CBEE:00003DE00440088015402220000000007FFC000000001FF0044004401FF00000 +CBEF:00003DE00440088015402220000000007FFC000001001FF007C0082007C00000 +CBF0:0000000800087B8808880888190815082288CC4800087FE80008000800080000 +CBF1:00007BC8088811082A884448000800087FE8000007F800080008000800080000 +CBF2:00007BC8088811082A884448000800087FE8000000003EF80208020802080000 +CBF3:00007BC8088811082A884448000800087FE8000000001F080108011401620000 +CBF4:00007BC8088811082A884448000800087FE8000008000800080008000FF80000 +CBF5:00007BC8088811082A884448000800087FE80000000010F8101010301ECC0000 +CBF6:00007BC8088811082A884448000800087FE800000808087F081C08220F9C0000 +CBF7:00007BC8088811082A884448000800087FE8000003F802000200020003F80000 +CBF8:00007BC8088811082A884448000800087FE8000007F8000807F8040007F80000 +CBF9:00007BC8088811082A884448000800087FE800003EF802083E0820083E080000 +CBFA:00007BC8088811082A884448000800087FE800003EF802883E8820883EF80000 +CBFB:00007BC8088811082A884448000800087FE800003E8802883EF820883EF80000 +CBFC:00007BC8088811082A884448000800087FE800001F0801081F0810141F620000 +CBFD:00007BC8088811082A884448000800087FE800003EF802803EF820803EF80000 +CBFE:00007BC8088811082A884448000800087FE800003EFC02483E4820483EFC0000 +CBFF:00007BC8088811082A884448000800087FE800001F08017F1F1C10221F1C0000 +CC00:00007BC8088811082A884448000800087FE8000003F802080208020803F80000 +CC01:00007BC8088811082A884448000800087FE800000208020803F8020803F80000 +CC02:00007BC8088811082A884448000800087FE80000110811081F0811141F620000 +CC03:00007BC8088811082A884448000800087FE80000001000100010006801840000 +CC04:00007BC8088811082A884448000800087FE800000048004800A8011406620000 +CC05:00007BC8088811082A884448000800087FE80000000003F00408040803F00000 +CC06:00007BC8088811082A884448000800087FE8000003F80020002000D003080000 +CC07:00007BC8088811082A884448000800087FE80000004003F8004000A003180000 +CC08:00007BC8088811082A884448000800087FE8000003F8000803F8000800080000 +CC09:00007BC8088811082A884448000800087FE8000003F8020003F8020003F80000 +CC0A:00007BC8088811082A884448000800087FE8000000000FF8022002200FF80000 +CC0B:00007BC8088811082A884448000800087FE8000000800FF803E0041003E00000 +CC0C:00000000000800087B8808880888190815082288CC4800080008000800080000 +CC0D:0000000800087708220822085508888800080000000007F80008000800080000 +CC0E:000000080008770822082208550888880008000000003EF80208020802080000 +CC0F:000000080008770822082208550888880008000000001F080108011401620000 +CC10:000000080008770822082208550888880008000800001000100010001FF80000 +CC11:0000000800087708220822085508888800080000000020F8201020303ECC0000 +CC12:0000000800087708220822085508888800080000202021FC207020883E700000 +CC13:000000080008770822082208550888880008000003F802000200020003F80000 +CC14:000000080008770822082208550888880008000007F8000807F8040007F80000 +CC15:00000008000877082208220855088888000800003EF802083E0820083E080000 +CC16:00000008000877082208220855088888000800003EF802883E8820883EF80000 +CC17:00000008000877082208220855088888000800003E8802883EF820883EF80000 +CC18:00000008000877082208220855088888000800000F8800880F8808140FA20000 +CC19:00000008000877082208220855088888000800003EF802803EF820803EF80000 +CC1A:00000008000877082208220855088888000800003EFC02483E4820483EFC0000 +CC1B:00000008000877082208220855088888000800003E1002FE3E3820443E380000 +CC1C:000000080008770822082208550888880008000003F802080208020803F80000 +CC1D:00000008000877082208220855088888000800000208020803F8020803F80000 +CC1E:0000000800087708220822085508888800080000210821083F0821143F620000 +CC1F:0000000800087708220822085508888800080000001000100010006801840000 +CC20:00000008000877082208220855088888000800000048004800A8011406620000 +CC21:0000000800087708220822085508888800080000000003F00408040803F00000 +CC22:000000080008770822082208550888880008000003F80020002000D003080000 +CC23:0000000800087708220822085508888800080000004003F8004000A003180000 +CC24:000000080008770822082208550888880008000003F8000803F8000800080000 +CC25:000000080008770822082208550888880008000003F8020003F8020003F80000 +CC26:000000080008770822082208550888880008000000000FF8022002200FF80000 +CC27:000000080008770822082208550888880008000000800FF803E0041003E00000 +CC28:000000000010041004103F900110021E06100910309000100010001000100000 +CC29:00000008000808087E08080E140862080008000007F800080008000800080000 +CC2A:00000008000808087E08080E140862080008000000003EF80208020802080000 +CC2B:00000008000808087E08080E140862080008000000001F080108011401620000 +CC2C:00000008000808087E08080E140862080008000808000800080008000FF80000 +CC2D:00000008000808087E08080E1408620800080000000010F8101010301ECC0000 +CC2E:00000008000808087E08080E14086208000800000808087F081C08220F9C0000 +CC2F:00000008000808087E08080E140862080008000003F802000200020003F80000 +CC30:00000008000808087E08080E140862080008000007F8000807F8040007F80000 +CC31:00000008000808087E08080E14086208000800003EF802083E0820083E080000 +CC32:00000008000808087E08080E14086208000800003EF802883E8820883EF80000 +CC33:00000008000808087E08080E14086208000800003E8802883EF820883EF80000 +CC34:00000008000808087E08080E14086208000800001F0801081F0810141F620000 +CC35:00000008000808087E08080E14086208000800003EF802803EF820803EF80000 +CC36:00000008000808087E08080E14086208000800003EFC02483E4820483EFC0000 +CC37:00000008000808087E08080E14086208000800001F08017F1F1C10221F1C0000 +CC38:00000008000808087E08080E140862080008000003F802080208020803F80000 +CC39:00000008000808087E08080E14086208000800000208020803F8020803F80000 +CC3A:00000008000808087E08080E1408620800080000110811081F0811141F620000 +CC3B:00000008000808087E08080E1408620800080000001000100010006801840000 +CC3C:00000008000808087E08080E14086208000800000048004800A8011406620000 +CC3D:00000008000808087E08080E1408620800080000000003F00408040803F00000 +CC3E:00000008000808087E08080E140862080008000003F80020002000D003080000 +CC3F:00000008000808087E08080E1408620800080000004003F8004000A003180000 +CC40:00000008000808087E08080E140862080008000003F8000803F8000800080000 +CC41:00000008000808087E08080E140862080008000003F8020003F8020003F80000 +CC42:00000008000808087E08080E140862080008000000000FF8022002200FF80000 +CC43:00000008000808087E08080E140862080008000000800FF803E0041003E00000 +CC44:000000000012041204123F920112021E06120912309200120012001200120000 +CC45:00000028002808287E280838142862280028000007F800080008000800080000 +CC46:00000028002808287E280838142862280028000000003EF80208020802080000 +CC47:00000028002808287E280838142862280028000000003E100210022802C40000 +CC48:00000028002808287E280838142862280028002808000800080008000FF80000 +CC49:00000028002808287E2808381428622800280000000020F8201020303ECC0000 +CC4A:00000028002808287E2808381428622800280000202021FC207020883E700000 +CC4B:00000028002808287E280838142862280028000003F802000200020003F80000 +CC4C:00000028002808287E280838142862280028000007F8000807F8040007F80000 +CC4D:00000028002808287E28083814286228002800003EF802083E0820083E080000 +CC4E:00000028002808287E28083814286228002800003EF802883E8820883EF80000 +CC4F:00000028002808287E28083814286228002800003E8802883EF820883EF80000 +CC50:00000028002808287E28083814286228002800001F0801081F0810141F620000 +CC51:00000028002808287E28083814286228002800003EF802803EF820803EF80000 +CC52:00000028002808287E28083814286228002800003EFC02483E4820483EFC0000 +CC53:00000028002808287E28083814286228002800003E1002FE3E3820443E380000 +CC54:00000028002808287E280838142862280028000003F802080208020803F80000 +CC55:00000028002808287E28083814286228002800000208020803F8020803F80000 +CC56:00000028002808287E2808381428622800280000110811081F0811141F620000 +CC57:00000028002808287E2808381428622800280000000800080008003400C20000 +CC58:00000028002808287E28083814286228002800000048004800A8011406620000 +CC59:00000028002808287E2808381428622800280000000001F00208020801F00000 +CC5A:00000028002808287E280838142862280028000003F80020002000D003080000 +CC5B:00000028002808287E2808381428622800280000004003F8004000A003180000 +CC5C:00000028002808287E280838142862280028000003F8000803F8000800080000 +CC5D:00000028002808287E280838142862280028000003F8020003F8020003F80000 +CC5E:00000028002808287E280838142862280028000000000FF8022002200FF80000 +CC5F:00000028002808287E280838142862280028000000800FF803E0041003E00000 +CC60:000000000010041004103F90011E02100610091E309000100010001000100000 +CC61:00000008000808087E0E0808140E62080008000007F800080008000800080000 +CC62:00000008000808087E0E0808140E62080008000000003EF80208020802080000 +CC63:00000008000808087E0E0808140E62080008000000001F080108011401620000 +CC64:00000008000808087E0E0808140E62080008000008000800080008000FF80000 +CC65:00000008000808087E0E0808140E620800080000000010F8101010301ECC0000 +CC66:00000008000808087E0E0808140E6208000800000808087F081C08220F9C0000 +CC67:00000008000808087E0E0808140E62080008000003F802000200020003F80000 +CC68:00000008000808087E0E0808140E62080008000007F8000807F8040007F80000 +CC69:00000008000808087E0E0808140E6208000800003EF802083E0820083E080000 +CC6A:00000008000808087E0E0808140E6208000800003EF802883E8820883EF80000 +CC6B:00000008000808087E0E0808140E6208000800003E8802883EF820883EF80000 +CC6C:00000008000808087E0E0808140E6208000800001F0801081F0810141F620000 +CC6D:00000008000808087E0E0808140E6208000800003EF802803EF820803EF80000 +CC6E:00000008000808087E0E0808140E6208000800003EFC02483E4820483EFC0000 +CC6F:00000008000808087E0E0808140E6208000800001F08017F1F1C10221F1C0000 +CC70:00000008000808087E0E0808140E62080008000003F802080208020803F80000 +CC71:00000008000808087E0E0808140E6208000800000208020803F8020803F80000 +CC72:00000008000808087E0E0808140E620800080000110811081F0811141F620000 +CC73:00000008000808087E0E0808140E620800080000001000100010006801840000 +CC74:00000008000808087E0E0808140E6208000800000048004800A8011406620000 +CC75:00000008000808087E0E0808140E620800080000000003F00408040803F00000 +CC76:00000008000808087E0E0808140E62080008000003F80020002000D003080000 +CC77:00000008000808087E0E0808140E620800080000004003F8004000A003180000 +CC78:00000008000808087E0E0808140E62080008000003F8000803F8000800080000 +CC79:00000008000808087E0E0808140E62080008000003F8020003F8020003F80000 +CC7A:00000008000808087E0E0808140E62080008000000000FF8022002200FF80000 +CC7B:00000008000808087E0E0808140E62080008000000800FF803E0041003E00000 +CC7C:000000000012041204123F92011E02120612091E309200120012001200120000 +CC7D:00000028002808287E380828143862280028000007F800080008000800080000 +CC7E:00000028002808287E380828143862280028000000003EF80208020802080000 +CC7F:00000028002808287E380828143862280028000000003E100210022802C40000 +CC80:00000028002808287E380828143862280028002808000800080008000FF80000 +CC81:00000028002808287E3808281438622800280000000020F8201020303ECC0000 +CC82:00000028002808287E3808281438622800280000202021FC207020883E700000 +CC83:00000028002808287E380828143862280028000003F802000200020003F80000 +CC84:00000028002808287E380828143862280028000007F8000807F8040007F80000 +CC85:00000028002808287E38082814386228002800003EF802083E0820083E080000 +CC86:00000028002808287E38082814386228002800003EF802883E8820883EF80000 +CC87:00000028002808287E38082814386228002800003E8802883EF820883EF80000 +CC88:00000028002808287E38082814386228002800001F0801081F0810141F620000 +CC89:00000028002808287E38082814386228002800003EF802803EF820803EF80000 +CC8A:00000028002808287E38082814386228002800003EFC02483E4820483EFC0000 +CC8B:00000028002808287E38082814386228002800003E1002FE3E3820443E380000 +CC8C:00000028002808287E380828143862280028000003F802080208020803F80000 +CC8D:00000028002808287E38082814386228002800000208020803F8020803F80000 +CC8E:00000028002808287E3808281438622800280000110811081F0811141F620000 +CC8F:00000028002808287E3808281438622800280000000800080008003400C20000 +CC90:00000028002808287E38082814386228002800000048004800A8011406620000 +CC91:00000028002808287E3808281438622800280000000001F00208020801F00000 +CC92:00000028002808287E380828143862280028000003F80020002000D003080000 +CC93:00000028002808287E3808281438622800280000004003F8004000A003180000 +CC94:00000028002808287E380828143862280028000003F8000803F8000800080000 +CC95:00000028002808287E380828143862280028000003F8020003F8020003F80000 +CC96:00000028002808287E380828143862280028000000000FF8022002200FF80000 +CC97:00000028002808287E380828143862280028000000800FF803E0041003E00000 +CC98:000000000002040204023F820102021E06020902308200020002000200020000 +CC99:00000008000808087E0808381408620800080000000007F80008000800080000 +CC9A:00000008000808087E080838140862080008000000003EF80208020802080000 +CC9B:00000008000808087E080838140862080008000000001F080108011401620000 +CC9C:00000008000808087E080838140862080008000000001000100010001FF80000 +CC9D:00000008000808087E0808381408620800080000000020F8201020303ECC0000 +CC9E:00000008000808087E0808381408620800080000202021FC207020883E700000 +CC9F:00000008000808087E080838140862080008000003F802000200020003F80000 +CCA0:00000008000808087E080838140862080008000007F8000807F8040007F80000 +CCA1:00000008000808087E08083814086208000800003EF802083E0820083E080000 +CCA2:00000008000808087E08083814086208000800003EF802883E8820883EF80000 +CCA3:00000008000808087E08083814086208000800003E8802883EF820883EF80000 +CCA4:00000008000808087E08083814086208000800000F8800880F8808140FA20000 +CCA5:00000008000808087E08083814086208000800003EF802803EF820803EF80000 +CCA6:00000008000808087E08083814086208000800003EFC02483E4820483EFC0000 +CCA7:00000008000808087E08083814086208000800003E1002FE3E3820443E380000 +CCA8:00000008000808087E080838140862080008000003F802080208020803F80000 +CCA9:00000008000808087E08083814086208000800000208020803F8020803F80000 +CCAA:00000008000808087E0808381408620800080000210821083F0821143F620000 +CCAB:00000008000808087E0808381408620800080000001000100010006801840000 +CCAC:00000008000808087E08083814086208000800000048004800A8011406620000 +CCAD:00000008000808087E0808381408620800080000000003F00408040803F00000 +CCAE:00000008000808087E080838140862080008000003F80020002000D003080000 +CCAF:00000008000808087E0808381408620800080000004003F8004000A003180000 +CCB0:00000008000808087E080838140862080008000003F8000803F8000800080000 +CCB1:00000008000808087E080838140862080008000003F8020003F8020003F80000 +CCB2:00000008000808087E080838140862080008000000000FF8022002200FF80000 +CCB3:00000008000808087E080838140862080008000000800FF803E0041003E00000 +CCB4:00000000000A040A040A3F8A010A023A060A090A308A000A000A000A000A0000 +CCB5:00000028002808287E2808E8142862280028000007F800080008000800080000 +CCB6:00000028002808287E2808E8142862280028000000003EF80208020802080000 +CCB7:00000028002808287E2808E8142862280028000000003E100210022802C40000 +CCB8:00000028002808287E2808E8142862280028000008000800080008000FF80000 +CCB9:00000028002808287E2808E81428622800280000000020F8201020303ECC0000 +CCBA:00000028002808287E2808E81428622800280000202021FC207020883E700000 +CCBB:00000028002808287E2808E8142862280028000003F802000200020003F80000 +CCBC:00000028002808287E2808E8142862280028000007F8000807F8040007F80000 +CCBD:00000028002808287E2808E814286228002800003EF802083E0820083E080000 +CCBE:00000028002808287E2808E814286228002800003EF802883E8820883EF80000 +CCBF:00000028002808287E2808E814286228002800003E8802883EF820883EF80000 +CCC0:00000028002808287E2808E814286228002800001F0801081F0810141F620000 +CCC1:00000028002808287E2808E814286228002800003EF802803EF820803EF80000 +CCC2:00000028002808287E2808E814286228002800003EFC02483E4820483EFC0000 +CCC3:00000028002808287E2808E814286228002800003E1002FE3E3820443E380000 +CCC4:00000028002808287E2808E8142862280028000003F802080208020803F80000 +CCC5:00000028002808287E2808E814286228002800000208020803F8020803F80000 +CCC6:00000028002808287E2808E81428622800280000110811081F0811141F620000 +CCC7:00000028002808287E2808E81428622800280000000800080008003400C20000 +CCC8:00000028002808287E2808E814286228002800000048004800A8011406620000 +CCC9:00000028002808287E2808E81428622800280000000001F00208020801F00000 +CCCA:00000028002808287E2808E8142862280028000003F80020002000D003080000 +CCCB:00000028002808287E2808E81428622800280000004003F8004000A003180000 +CCCC:00000028002808287E2808E8142862280028000003F8000803F8000800080000 +CCCD:00000028002808287E2808E8142862280028000003F8020003F8020003F80000 +CCCE:00000028002808287E2808E8142862280028000000000FF8022002200FF80000 +CCCF:00000028002808287E2808E8142862280028000000800FF803E0041003E00000 +CCD0:000000000002040204023F82011E02020602091E308200020002000200020000 +CCD1:00000008000808087E3808081438620800080000000007F80008000800080000 +CCD2:00000008000808087E380808143862080008000000003EF80208020802080000 +CCD3:00000008000808087E380808143862080008000000001F080108011401620000 +CCD4:00000008000808087E380808143862080008000800001000100010001FF80000 +CCD5:00000008000808087E3808081438620800080000000020F8201020303ECC0000 +CCD6:00000008000808087E3808081438620800080000202021FC207020883E700000 +CCD7:00000008000808087E380808143862080008000003F802000200020003F80000 +CCD8:00000008000808087E380808143862080008000007F8000807F8040007F80000 +CCD9:00000008000808087E38080814386208000800003EF802083E0820083E080000 +CCDA:00000008000808087E38080814386208000800003EF802883E8820883EF80000 +CCDB:00000008000808087E38080814386208000800003E8802883EF820883EF80000 +CCDC:00000008000808087E38080814386208000800000F8800880F8808140FA20000 +CCDD:00000008000808087E38080814386208000800003EF802803EF820803EF80000 +CCDE:00000008000808087E38080814386208000800003EFC02483E4820483EFC0000 +CCDF:00000008000808087E38080814386208000800003E1002FE3E3820443E380000 +CCE0:00000008000808087E380808143862080008000003F802080208020803F80000 +CCE1:00000008000808087E38080814386208000800000208020803F8020803F80000 +CCE2:00000008000808087E3808081438620800080000210821083F0821143F620000 +CCE3:00000008000808087E3808081438620800080000001000100010006801840000 +CCE4:00000008000808087E38080814386208000800000048004800A8011406620000 +CCE5:00000008000808087E3808081438620800080000000003F00408040803F00000 +CCE6:00000008000808087E380808143862080008000003F80020002000D003080000 +CCE7:00000008000808087E3808081438620800080000004003F8004000A003180000 +CCE8:00000008000808087E380808143862080008000003F8000803F8000800080000 +CCE9:00000008000808087E380808143862080008000003F8020003F8020003F80000 +CCEA:00000008000808087E380808143862080008000000000FF8022002200FF80000 +CCEB:00000008000808087E380808143862080008000000800FF803E0041003E00000 +CCEC:00000000000A040A040A3F8A013A020A060A093A308A000A000A000A000A0000 +CCED:00000028002808287EE8082814E862280028000007F800080008000800080000 +CCEE:00000028002808287EE8082814E862280028000000003EF80208020802080000 +CCEF:00000028002808287EE8082814E862280028000000003E100210022802C40000 +CCF0:00000028002808287EE8082814E862280028002808000800080008000FF80000 +CCF1:00000028002808287EE8082814E8622800280000000020F8201020303ECC0000 +CCF2:00000028002808287EE8082814E8622800280000202021FC207020883E700000 +CCF3:00000028002808287EE8082814E862280028000003F802000200020003F80000 +CCF4:00000028002808287EE8082814E862280028000007F8000807F8040007F80000 +CCF5:00000028002808287EE8082814E86228002800003EF802083E0820083E080000 +CCF6:00000028002808287EE8082814E86228002800003EF802883E8820883EF80000 +CCF7:00000028002808287EE8082814E86228002800003E8802883EF820883EF80000 +CCF8:00000028002808287EE8082814E86228002800001F0801081F0810141F620000 +CCF9:00000028002808287EE8082814E86228002800003EF802803EF820803EF80000 +CCFA:00000028002808287EE8082814E86228002800003EFC02483E4820483EFC0000 +CCFB:00000028002808287EE8082814E86228002800003E1002FE3E3820443E380000 +CCFC:00000028002808287EE8082814E862280028000003F802080208020803F80000 +CCFD:00000028002808287EE8082814E86228002800000208020803F8020803F80000 +CCFE:00000028002808287EE8082814E8622800280000110811081F0811141F620000 +CCFF:00000028002808287EE8082814E8622800280000000800080008003400C20000 +CD00:00000028002808287EE8082814E86228002800000048004800A8011406620000 +CD01:00000028002808287EE8082814E8622800280000000001F00208020801F00000 +CD02:00000028002808287EE8082814E862280028000003F80020002000D003080000 +CD03:00000028002808287EE8082814E8622800280000004003F8004000A003180000 +CD04:00000028002808287EE8082814E862280028000003F8000803F8000800080000 +CD05:00000028002808287EE8082814E862280028000003F8020003F8020003F80000 +CD06:00000028002808287EE8082814E862280028000000000FF8022002200FF80000 +CD07:00000028002808287EE8082814E862280028000000800FF803E0041003E00000 +CD08:0000010001000FE000400080018002400C2000000100010001007FFC00000000 +CD09:000001000FC0010002800C40010001007FFC00001FF000100010001000100000 +CD0A:000001000FC0010002800C40010001007FFC000000003EF80208020802080000 +CD0B:000001000FC0010002800C40010001007FFC000000001E100210022802C40000 +CD0C:000001000FC0010002800C40010001007FFC000000001000100010001FF00000 +CD0D:000001000FC0010002800C40010001007FFC0000000020F8201020303ECC0000 +CD0E:000001000FC0010002800C40010001007FFC0000202021FC207020883E700000 +CD0F:000001000FC0010002800C40010001007FFC00001FF01000100010001FF00000 +CD10:000001000FC0010002800C40010001007FFC00001FF000101FF010001FF00000 +CD11:000001000FC0010002800C40010001007FFC00003EF802083E0820083E080000 +CD12:000001000FC0010002800C40010001007FFC00003EF802883E8820883EF80000 +CD13:000001000FC0010002800C40010001007FFC00003E8802883EF820883EF80000 +CD14:000001000FC0010002800C40010001007FFC00003E1002103E1020283EC40000 +CD15:000001000FC0010002800C40010001007FFC00003EF802803EF820803EF80000 +CD16:000001000FC0010002800C40010001007FFC00003EFC02483E4820483EFC0000 +CD17:000001000FC0010002800C40010001007FFC00003E2003FC3E7020883E700000 +CD18:000001000FC0010002800C40010001007FFC00001FF01010101010101FF00000 +CD19:000001000FC0010002800C40010001007FFC0000101010101FF010101FF00000 +CD1A:000001000FC0010002800C40010001007FFC0000222022203E2022503E880000 +CD1B:000001000FC0010002800C40010001007FFC000000000100010002800C400000 +CD1C:000001000FC0010002800C40010001007FFC00000000024002400DA033100000 +CD1D:000001000FC0010002800C40010001007FFC0000000007C00820082007C00000 +CD1E:000001000FC0010002800C40010001007FFC0000000007E00080014006200000 +CD1F:000001000FC0010002800C40010001007FFC0000008007E00080014006200000 +CD20:000001000FC0010002800C40010001007FFC00001FF000101FF0001000100000 +CD21:000001000FC0010002800C40010001007FFC00001FF010001FF010001FF00000 +CD22:000001000FC0010002800C40010001007FFC000000001FF0044004401FF00000 +CD23:000001000FC0010002800C40010001007FFC000001001FF007C0082007C00000 +CD24:00000010041004103F9001100210061E09103090041004107FD0001000100000 +CD25:000002081F880208050E1888040804087FE8000007F800080008000800080000 +CD26:000002081F880208050E1888040804087FE8000000003EF80208020802080000 +CD27:000002081F880208050E1888040804087FE8000000001F080108011401620000 +CD28:000002081F880208050E1888040804087FE8000008000800080008000FF80000 +CD29:000002081F880208050E1888040804087FE80000000010F8101010301ECC0000 +CD2A:000002081F880208050E1888040804087FE800000808087F081C08220F9C0000 +CD2B:000002081F880208050E1888040804087FE8000003F802000200020003F80000 +CD2C:000002081F880208050E1888040804087FE8000007F8000807F8040007F80000 +CD2D:000002081F880208050E1888040804087FE800003EF802083E0820083E080000 +CD2E:000002081F880208050E1888040804087FE800003EF802883E8820883EF80000 +CD2F:000002081F880208050E1888040804087FE800003E8802883EF820883EF80000 +CD30:000002081F880208050E1888040804087FE800001F0801081F0810141F620000 +CD31:000002081F880208050E1888040804087FE800003EF802803EF820803EF80000 +CD32:000002081F880208050E1888040804087FE800003EFC02483E4820483EFC0000 +CD33:000002081F880208050E1888040804087FE800001F08017F1F1C10221F1C0000 +CD34:000002081F880208050E1888040804087FE8000003F802080208020803F80000 +CD35:000002081F880208050E1888040804087FE800000208020803F8020803F80000 +CD36:000002081F880208050E1888040804087FE80000110811081F0811141F620000 +CD37:000002081F880208050E1888040804087FE80000001000100010006801840000 +CD38:000002081F880208050E1888040804087FE800000048004800A8011406620000 +CD39:000002081F880208050E1888040804087FE80000000003F00408040803F00000 +CD3A:000002081F880208050E1888040804087FE8000003F80020002000D003080000 +CD3B:000002081F880208050E1888040804087FE80000004003F8004000A003180000 +CD3C:000002081F880208050E1888040804087FE8000003F8000803F8000800080000 +CD3D:000002081F880208050E1888040804087FE8000003F8020003F8020003F80000 +CD3E:000002081F880208050E1888040804087FE8000000000FF8022002200FF80000 +CD3F:000002081F880208050E1888040804087FE8000000800FF803E0041003E00000 +CD40:00000012041204123F9201120212061E09123092041204127FD2001200120000 +CD41:000002281FA80228053818A8042804287FA8000007F800080008000800080000 +CD42:000002281FA80228053818A8042804287FA8000000003EF80208020802080000 +CD43:000002281FA80228053818A8042804287FA8000000001F080108011401620000 +CD44:000002281FA80228053818A8042804287FA8000008000800080008000FF80000 +CD45:000002281FA80228053818A8042804287FA80000000010F8101010301ECC0000 +CD46:000002281FA80228053818A8042804287FA800000808087F081C08220F9C0000 +CD47:000002281FA80228053818A8042804287FA8000003F802000200020003F80000 +CD48:000002281FA80228053818A8042804287FA8000007F8000807F8040007F80000 +CD49:000002281FA80228053818A8042804287FA800003EF802083E0820083E080000 +CD4A:000002281FA80228053818A8042804287FA800003EF802883E8820883EF80000 +CD4B:000002281FA80228053818A8042804287FA800003E8802883EF820883EF80000 +CD4C:000002281FA80228053818A8042804287FA800001F0801081F0810141F620000 +CD4D:000002281FA80228053818A8042804287FA800003EF802803EF820803EF80000 +CD4E:000002281FA80228053818A8042804287FA800003EFC02483E4820483EFC0000 +CD4F:000002281FA80228053818A8042804287FA800001F08017F1F1C10221F1C0000 +CD50:000002281FA80228053818A8042804287FA8000003F802080208020803F80000 +CD51:000002281FA80228053818A8042804287FA800000208020803F8020803F80000 +CD52:000002281FA80228053818A8042804287FA80000110811081F0811141F620000 +CD53:000002281FA80228053818A8042804287FA80000001000100010006801840000 +CD54:000002281FA80228053818A8042804287FA800000048004800A8011406620000 +CD55:000002281FA80228053818A8042804287FA80000000003F00408040803F00000 +CD56:000002281FA80228053818A8042804287FA8000003F80020002000D003080000 +CD57:000002281FA80228053818A8042804287FA80000004003F8004000A003180000 +CD58:000002281FA80228053818A8042804287FA8000003F8000803F8000800080000 +CD59:000002281FA80228053818A8042804287FA8000003F8020003F8020003F80000 +CD5A:000002281FA80228053818A8042804287FA8000000000FF8022002200FF80000 +CD5B:000002281FA80228053818A8042804287FA8000000800FF803E0041003E00000 +CD5C:00000008040804083F8801080208060809083088040804087FE8000800080000 +CD5D:000002081F88020805081888040804087FE8000007F800080008000800080000 +CD5E:000002081F88020805081888040804087FE8000000003EF80208020802080000 +CD5F:000002081F88020805081888040804087FE8000000001F080108011401620000 +CD60:000002081F88020805081888040804087FE8000008000800080008000FF80000 +CD61:000002081F88020805081888040804087FE80000000010F8101010301ECC0000 +CD62:000002081F88020805081888040804087FE800000808087F081C08220F9C0000 +CD63:000002081F88020805081888040804087FE8000003F802000200020003F80000 +CD64:000002081F88020805081888040804087FE8000007F8000807F8040007F80000 +CD65:000002081F88020805081888040804087FE800003EF802083E0820083E080000 +CD66:000002081F88020805081888040804087FE800003EF802883E8820883EF80000 +CD67:000002081F88020805081888040804087FE800003E8802883EF820883EF80000 +CD68:000002081F88020805081888040804087FE800001F0801081F0810141F620000 +CD69:000002081F88020805081888040804087FE800003EF802803EF820803EF80000 +CD6A:000002081F88020805081888040804087FE800003EFC02483E4820483EFC0000 +CD6B:000002081F88020805081888040804087FE800001F08017F1F1C10221F1C0000 +CD6C:000002081F88020805081888040804087FE8000003F802080208020803F80000 +CD6D:000002081F88020805081888040804087FE800000208020803F8020803F80000 +CD6E:000002081F88020805081888040804087FE80000110811081F0811141F620000 +CD6F:000002081F88020805081888040804087FE80000001000100010006801840000 +CD70:000002081F88020805081888040804087FE800000048004800A8011406620000 +CD71:000002081F88020805081888040804087FE80000000003F00408040803F00000 +CD72:000002081F88020805081888040804087FE8000003F80020002000D003080000 +CD73:000002081F88020805081888040804087FE80000004003F8004000A003180000 +CD74:000002081F88020805081888040804087FE8000003F8000803F8000800080000 +CD75:000002081F88020805081888040804087FE8000003F8020003F8020003F80000 +CD76:000002081F88020805081888040804087FE8000000000FF8022002200FF80000 +CD77:000002081F88020805081888040804087FE8000000800FF803E0041003E00000 +CD78:0000010001000FE000400080018002400C2004400440044004407FFC00000000 +CD79:000001000FC0010002800C40044004407FFC00001FF000100010001000100000 +CD7A:000001000FC0010002800C40044004407FFC000000003EF80208020802080000 +CD7B:000001000FC0010002800C40044004407FFC000000001E100210022802C40000 +CD7C:000001000FC0010002800C40044004407FFC000000001000100010001FF00000 +CD7D:000001000FC0010002800C40044004407FFC0000000020F8201020303ECC0000 +CD7E:000001000FC0010002800C40044004407FFC0000202021FC207020883E700000 +CD7F:000001000FC0010002800C40044004407FFC00001FF01000100010001FF00000 +CD80:000001000FC0010002800C40044004407FFC00001FF000101FF010001FF00000 +CD81:000001000FC0010002800C40044004407FFC00003EF802083E0820083E080000 +CD82:000001000FC0010002800C40044004407FFC00003EF802883E8820883EF80000 +CD83:000001000FC0010002800C40044004407FFC00003E8802883EF820883EF80000 +CD84:000001000FC0010002800C40044004407FFC00003E1002103E1020283EC40000 +CD85:000001000FC0010002800C40044004407FFC00003EF802803EF820803EF80000 +CD86:000001000FC0010002800C40044004407FFC00003EFC02483E4820483EFC0000 +CD87:000001000FC0010002800C40044004407FFC00003E2003FC3E7020883E700000 +CD88:000001000FC0010002800C40044004407FFC00001FF01010101010101FF00000 +CD89:000001000FC0010002800C40044004407FFC0000101010101FF010101FF00000 +CD8A:000001000FC0010002800C40044004407FFC0000222022203E2022503E880000 +CD8B:000001000FC0010002800C40044004407FFC000000000100010002800C400000 +CD8C:000001000FC0010002800C40044004407FFC00000000024002400DA033100000 +CD8D:000001000FC0010002800C40044004407FFC0000000007C00820082007C00000 +CD8E:000001000FC0010002800C40044004407FFC0000000007E00080014006200000 +CD8F:000001000FC0010002800C40044004407FFC0000008007E00080014006200000 +CD90:000001000FC0010002800C40044004407FFC00001FF000101FF0001000100000 +CD91:000001000FC0010002800C40044004407FFC00001FF010001FF010001FF00000 +CD92:000001000FC0010002800C40044004407FFC000000001FF0044004401FF00000 +CD93:000001000FC0010002800C40044004407FFC000001001FF007C0082007C00000 +CD94:00000080008007F00020004000C00120061000003FF801000100010001000000 +CD95:000001000FC0010002800C4000007FFC010001001FF000100010001000100000 +CD96:000001000FC0010002800C4000007FFC0100010000003EF80208020802080000 +CD97:000001000FC0010002800C4000007FFC0100010000001E100210022802C40000 +CD98:000001000FC0010002800C40000000007FFC010001001100100010001FF00000 +CD99:000001000FC0010002800C4000007FFC01000100000020F8201020303ECC0000 +CD9A:000001000FC0010002800C4000007FFC01000100202021FC207020883E700000 +CD9B:000001000FC0010002800C4000007FFC010001001FF01000100010001FF00000 +CD9C:000001000FC0010002800C4000007FFC010001001FF000101FF010001FF00000 +CD9D:000001000FC0010002800C4000007FFC010001003EF802083E0820083E080000 +CD9E:000001000FC0010002800C4000007FFC010001003EF802883E8820883EF80000 +CD9F:000001000FC0010002800C4000007FFC010001003E8802883EF820883EF80000 +CDA0:000001000FC0010002800C4000007FFC010001003E1002103E1020283EC40000 +CDA1:000001000FC0010002800C4000007FFC010001003EF802803EF820803EF80000 +CDA2:000001000FC0010002800C4000007FFC010001003EFC02483E4820483EFC0000 +CDA3:000001000FC0010002800C4000007FFC010001003E2003FC3E7020883E700000 +CDA4:000001000FC0010002800C4000007FFC010001001FF01010101010101FF00000 +CDA5:000001000FC0010002800C4000007FFC01000100101010101FF010101FF00000 +CDA6:000001000FC0010002800C4000007FFC01000100222022203E2022503E880000 +CDA7:000001000FC0010002800C4000007FFC0100010000000100010002800C400000 +CDA8:000001000FC0010002800C4000007FFC010001000000024002400DA033100000 +CDA9:000001000FC0010002800C4000007FFC01000100000007C00820082007C00000 +CDAA:000001000FC0010002800C4000007FFC01000100000007E00080014006200000 +CDAB:000001000FC0010002800C4000007FFC01000100008007E00080014006200000 +CDAC:000001000FC0010002800C4000007FFC010001001FF000101FF0001000100000 +CDAD:000001000FC0010002800C4000007FFC010001001FF010001FF010001FF00000 +CDAE:000001000FC0010002800C4000007FFC0100010000001FF0044004401FF00000 +CDAF:000001000FC0010002800C4000007FFC0100010001001FF007C0082007C00000 +CDB0:0000040804083F880108020806080908308800087FE8040804F8040804080000 +CDB1:04083F0804080A08310800087FE8027802080000000007F80008000800080000 +CDB2:04083F0804080A08310800087FE802780208000000003EF80208020802080000 +CDB3:04083F0804080A08310800087FE802780208000000001F080108011401620000 +CDB4:04083F0804080A083108000800087FE80278020802081000100010001FF80000 +CDB5:04083F0804080A08310800087FE8027802080000000020F8201020303ECC0000 +CDB6:04083F0804080A08310800087FE8027802080000202021FC207020883E700000 +CDB7:04083F0804080A08310800087FE802780208000003F802000200020003F80000 +CDB8:04083F0804080A08310800087FE802780208000007F8000807F8040007F80000 +CDB9:04083F0804080A08310800087FE80278020800003EF802083E0820083E080000 +CDBA:04083F0804080A08310800087FE80278020800003EF802883E8820883EF80000 +CDBB:04083F0804080A08310800087FE80278020800003E8802883EF820883EF80000 +CDBC:04083F0804080A08310800087FE80278020800000F8800880F8808140FA20000 +CDBD:04083F0804080A08310800087FE80278020800003EF802803EF820803EF80000 +CDBE:04083F0804080A08310800087FE80278020800003EFC02483E4820483EFC0000 +CDBF:04083F0804080A08310800087FE80278020800003E1002FE3E3820443E380000 +CDC0:04083F0804080A08310800087FE802780208000003F802080208020803F80000 +CDC1:04083F0804080A08310800087FE80278020800000208020803F8020803F80000 +CDC2:04083F0804080A08310800087FE8027802080000210821083F0821143F620000 +CDC3:04083F0804080A08310800087FE8027802080000001000100010006801840000 +CDC4:04083F0804080A08310800087FE80278020800000048004800A8011406620000 +CDC5:04083F0804080A08310800087FE8027802080000000003F00408040803F00000 +CDC6:04083F0804080A08310800087FE802780208000003F80020002000D003080000 +CDC7:04083F0804080A08310800087FE8027802080000004003F8004000A003180000 +CDC8:04083F0804080A08310800087FE802780208000003F8000803F8000800080000 +CDC9:04083F0804080A08310800087FE802780208000003F8020003F8020003F80000 +CDCA:04083F0804080A08310800087FE802780208000000000FF8022002200FF80000 +CDCB:04083F0804080A08310800087FE802780208000000800FF803E0041003E00000 +CDCC:0000040A040A3F8A010A020A060A090A308A000A7FEA040A047A040A040A0000 +CDCD:04283F2804280A28312800287FA805E804280000000007F80008000800080000 +CDCE:04283F2804280A28312800287FA805E80428000000003EF80208020802080000 +CDCF:04283F2804280A28312800287FA805E80428000000001F080108011401620000 +CDD0:04283F2804280A283128002800287FA8042805E804281428100010001FF80000 +CDD1:04283F2804280A28312800287FA805E804280000000020F8201020303ECC0000 +CDD2:04283F2804280A28312800287FA805E804280000202021FC207020883E700000 +CDD3:04283F2804280A28312800287FA805E80428000003F802000200020003F80000 +CDD4:04283F2804280A28312800287FA805E80428000007F8000807F8040007F80000 +CDD5:04283F2804280A28312800287FA805E8042800003EF802083E0820083E080000 +CDD6:04283F2804280A28312800287FA805E8042800003EF802883E8820883EF80000 +CDD7:04283F2804280A28312800287FA805E8042800003E8802883EF820883EF80000 +CDD8:04283F2804280A28312800287FA805E8042800000F8800880F8808140FA20000 +CDD9:04283F2804280A28312800287FA805E8042800003EF802803EF820803EF80000 +CDDA:04283F2804280A28312800287FA805E8042800003EFC02483E4820483EFC0000 +CDDB:04283F2804280A28312800287FA805E8042800003E1002FE3E3820443E380000 +CDDC:04283F2804280A28312800287FA805E80428000003F802080208020803F80000 +CDDD:04283F2804280A28312800287FA805E8042800000208020803F8020803F80000 +CDDE:04283F2804280A28312800287FA805E804280000210821083F0821143F620000 +CDDF:04283F2804280A28312800287FA805E804280000001000100010006801840000 +CDE0:04283F2804280A28312800287FA805E8042800000048004800A8011406620000 +CDE1:04283F2804280A28312800287FA805E804280000000003F00408040803F00000 +CDE2:04283F2804280A28312800287FA805E80428000003F80020002000D003080000 +CDE3:04283F2804280A28312800287FA805E804280000004003F8004000A003180000 +CDE4:04283F2804280A28312800287FA805E80428000003F8000803F8000800080000 +CDE5:04283F2804280A28312800287FA805E80428000003F8020003F8020003F80000 +CDE6:04283F2804280A28312800287FA805E80428000000000FF8022002200FF80000 +CDE7:04283F2804280A28312800287FA805E80428000000800FF803E0041003E00000 +CDE8:0000040804083F880108020806080908308800087FE804080408040804080000 +CDE9:04083F0804080A08310800087FE8020802000000000007F80008000800080000 +CDEA:04083F0804080A08310800087FE802080200000000003EF80208020802080000 +CDEB:04083F0804080A08310800087FE802080200000000001F080108011401620000 +CDEC:04083F0804080A083108000800087FE80208020802081008100010001FF80000 +CDED:04083F0804080A08310800087FE8020802000000000020F8201020303ECC0000 +CDEE:04083F0804080A08310800087FE8020802000000202021FC207020883E700000 +CDEF:04083F0804080A08310800087FE802080200000003F802000200020003F80000 +CDF0:04083F0804080A08310800087FE802080200000007F8000807F8040007F80000 +CDF1:04083F0804080A08310800087FE80208020000003EF802083E0820083E080000 +CDF2:04083F0804080A08310800087FE80208020000003EF802883E8820883EF80000 +CDF3:04083F0804080A08310800087FE80208020000003E8802883EF820883EF80000 +CDF4:04083F0804080A08310800087FE80208020000000F8800880F8808140FA20000 +CDF5:04083F0804080A08310800087FE80208020000003EF802803EF820803EF80000 +CDF6:04083F0804080A08310800087FE80208020000003EFC02483E4820483EFC0000 +CDF7:04083F0804080A08310800087FE80208020000003E1002FE3E3820443E380000 +CDF8:04083F0804080A08310800087FE802080200000003F802080208020803F80000 +CDF9:04083F0804080A08310800087FE80208020000000208020803F8020803F80000 +CDFA:04083F0804080A08310800087FE8020802000000210821083F0821143F620000 +CDFB:04083F0804080A08310800087FE8020802000000001000100010006801840000 +CDFC:04083F0804080A08310800087FE80208020000000048004800A8011406620000 +CDFD:04083F0804080A08310800087FE8020802000000000003F00408040803F00000 +CDFE:04083F0804080A08310800087FE802080200000003F80020002000D003080000 +CDFF:04083F0804080A08310800087FE8020802000000004003F8004000A003180000 +CE00:04083F0804080A08310800087FE802080200000003F8000803F8000800080000 +CE01:04083F0804080A08310800087FE802080200000003F8020003F8020003F80000 +CE02:04083F0804080A08310800087FE802080200000000000FF8022002200FF80000 +CE03:04083F0804080A08310800087FE802080200000000800FF803E0041003E00000 +CE04:00000080008007F00020004000C00120061000007FFC04400440044004400000 +CE05:000001000FC0010002800C4000007FFC044004401FF000100010001000100000 +CE06:000001000FC0010002800C4000007FFC0440044000003EF80208020802080000 +CE07:000001000FC0010002800C4000007FFC0440044000001E100210022802C40000 +CE08:000001000FC0010002800C40000000007FFC044004401440100010001FF00000 +CE09:000001000FC0010002800C4000007FFC04400440000020F8201020303ECC0000 +CE0A:000001000FC0010002800C4000007FFC04400440202021FC207020883E700000 +CE0B:000001000FC0010002800C4000007FFC044004401FF01000100010001FF00000 +CE0C:000001000FC0010002800C4000007FFC044004401FF000101FF010001FF00000 +CE0D:000001000FC0010002800C4000007FFC044004403EF802083E0820083E080000 +CE0E:000001000FC0010002800C4000007FFC044004403EF802883E8820883EF80000 +CE0F:000001000FC0010002800C4000007FFC044004403E8802883EF820883EF80000 +CE10:000001000FC0010002800C4000007FFC044004403E1002103E1020283EC40000 +CE11:000001000FC0010002800C4000007FFC044004403EF802803EF820803EF80000 +CE12:000001000FC0010002800C4000007FFC044004403EFC02483E4820483EFC0000 +CE13:000001000FC0010002800C4000007FFC044004403E2003FC3E7020883E700000 +CE14:000001000FC0010002800C4000007FFC044004401FF01010101010101FF00000 +CE15:000001000FC0010002800C4000007FFC04400440101010101FF010101FF00000 +CE16:000001000FC0010002800C4000007FFC04400440222022203E2022503E880000 +CE17:000001000FC0010002800C4000007FFC0440044000000100010002800C400000 +CE18:000001000FC0010002800C4000007FFC044004400000024002400DA033100000 +CE19:000001000FC0010002800C4000007FFC04400440000007C00820082007C00000 +CE1A:000001000FC0010002800C4000007FFC04400440000007E00080014006200000 +CE1B:000001000FC0010002800C4000007FFC04400440008007E00080014006200000 +CE1C:000001000FC0010002800C4000007FFC044004401FF000101FF0001000100000 +CE1D:000001000FC0010002800C4000007FFC044004401FF010001FF010001FF00000 +CE1E:000001000FC0010002800C4000007FFC0440044000001FF0044004401FF00000 +CE1F:000001000FC0010002800C4000007FFC0440044001001FF007C0082007C00000 +CE20:0000010001000FE000400080018002400C20000000007FFC0000000000000000 +CE21:000001000FC0010002800C40000000007FFC00001FF000100010001000100000 +CE22:000001000FC0010002800C40000000007FFC000000003EF80208020802080000 +CE23:000001000FC0010002800C40000000007FFC000000001E100210022802C40000 +CE24:000001000FC0010002800C40000000007FFC000000001000100010001FF00000 +CE25:000001000FC0010002800C40000000007FFC0000000020F8201020303ECC0000 +CE26:000001000FC0010002800C40000000007FFC0000202021FC207020883E700000 +CE27:000001000FC0010002800C40000000007FFC00001FF01000100010001FF00000 +CE28:000001000FC0010002800C40000000007FFC00001FF000101FF010001FF00000 +CE29:000001000FC0010002800C40000000007FFC00003EF802083E0820083E080000 +CE2A:000001000FC0010002800C40000000007FFC00003EF802883E8820883EF80000 +CE2B:000001000FC0010002800C40000000007FFC00003E8802883EF820883EF80000 +CE2C:000001000FC0010002800C40000000007FFC00003E1002103E1020283EC40000 +CE2D:000001000FC0010002800C40000000007FFC00003EF802803EF820803EF80000 +CE2E:000001000FC0010002800C40000000007FFC00003EFC02483E4820483EFC0000 +CE2F:000001000FC0010002800C40000000007FFC00003E2003FC3E7020883E700000 +CE30:000001000FC0010002800C40000000007FFC00001FF01010101010101FF00000 +CE31:000001000FC0010002800C40000000007FFC0000101010101FF010101FF00000 +CE32:000001000FC0010002800C40000000007FFC0000222022203E2022503E880000 +CE33:000001000FC0010002800C40000000007FFC000000000100010002800C400000 +CE34:000001000FC0010002800C40000000007FFC00000000024002400DA033100000 +CE35:000001000FC0010002800C40000000007FFC0000000007C00820082007C00000 +CE36:000001000FC0010002800C40000000007FFC0000000007E00080014006200000 +CE37:000001000FC0010002800C40000000007FFC0000008007E00080014006200000 +CE38:000001000FC0010002800C40000000007FFC00001FF000101FF0001000100000 +CE39:000001000FC0010002800C40000000007FFC00001FF010001FF010001FF00000 +CE3A:000001000FC0010002800C40000000007FFC000000001FF0044004401FF00000 +CE3B:000001000FC0010002800C40000000007FFC000001001FF007C0082007C00000 +CE3C:00000008040804083F880108020806080908308800087FE80008000800080000 +CE3D:000002081F88020805081888000800087FE8000007F800080008000800080000 +CE3E:000002081F88020805081888000800087FE8000000003EF80208020802080000 +CE3F:000002081F88020805081888000800087FE8000000001F080108011401620000 +CE40:000002081F88020805081888000800087FE8000008000800080008000FF80000 +CE41:000002081F88020805081888000800087FE80000000010F8101010301ECC0000 +CE42:000002081F88020805081888000800087FE800000808087F081C08220F9C0000 +CE43:000002081F88020805081888000800087FE8000003F802000200020003F80000 +CE44:000002081F88020805081888000800087FE8000007F8000807F8040007F80000 +CE45:000002081F88020805081888000800087FE800003EF802083E0820083E080000 +CE46:000002081F88020805081888000800087FE800003EF802883E8820883EF80000 +CE47:000002081F88020805081888000800087FE800003E8802883EF820883EF80000 +CE48:000002081F88020805081888000800087FE800001F0801081F0810141F620000 +CE49:000002081F88020805081888000800087FE800003EF802803EF820803EF80000 +CE4A:000002081F88020805081888000800087FE800003EFC02483E4820483EFC0000 +CE4B:000002081F88020805081888000800087FE800001F08017F1F1C10221F1C0000 +CE4C:000002081F88020805081888000800087FE8000003F802080208020803F80000 +CE4D:000002081F88020805081888000800087FE800000208020803F8020803F80000 +CE4E:000002081F88020805081888000800087FE80000110811081F0811141F620000 +CE4F:000002081F88020805081888000800087FE80000001000100010006801840000 +CE50:000002081F88020805081888000800087FE800000048004800A8011406620000 +CE51:000002081F88020805081888000800087FE80000000003F00408040803F00000 +CE52:000002081F88020805081888000800087FE8000003F80020002000D003080000 +CE53:000002081F88020805081888000800087FE80000004003F8004000A003180000 +CE54:000002081F88020805081888000800087FE8000003F8000803F8000800080000 +CE55:000002081F88020805081888000800087FE8000003F8020003F8020003F80000 +CE56:000002081F88020805081888000800087FE8000000000FF8022002200FF80000 +CE57:000002081F88020805081888000800087FE8000000800FF803E0041003E00000 +CE58:000000000008040804083F880108020806080908308800080008000800080000 +CE59:00000008000808087E0808081408620800080000000007F80008000800080000 +CE5A:00000008000808087E080808140862080008000000003EF80208020802080000 +CE5B:00000008000808087E080808140862080008000000001F080108011401620000 +CE5C:00000008000808087E080808140862080008000800001000100010001FF80000 +CE5D:00000008000808087E0808081408620800080000000020F8201020303ECC0000 +CE5E:00000008000808087E0808081408620800080000202021FC207020883E700000 +CE5F:00000008000808087E080808140862080008000003F802000200020003F80000 +CE60:00000008000808087E080808140862080008000007F8000807F8040007F80000 +CE61:00000008000808087E08080814086208000800003EF802083E0820083E080000 +CE62:00000008000808087E08080814086208000800003EF802883E8820883EF80000 +CE63:00000008000808087E08080814086208000800003E8802883EF820883EF80000 +CE64:00000008000808087E08080814086208000800000F8800880F8808140FA20000 +CE65:00000008000808087E08080814086208000800003EF802803EF820803EF80000 +CE66:00000008000808087E08080814086208000800003EFC02483E4820483EFC0000 +CE67:00000008000808087E08080814086208000800003E1002FE3E3820443E380000 +CE68:00000008000808087E080808140862080008000003F802080208020803F80000 +CE69:00000008000808087E08080814086208000800000208020803F8020803F80000 +CE6A:00000008000808087E0808081408620800080000210821083F0821143F620000 +CE6B:00000008000808087E0808081408620800080000001000100010006801840000 +CE6C:00000008000808087E08080814086208000800000048004800A8011406620000 +CE6D:00000008000808087E0808081408620800080000000003F00408040803F00000 +CE6E:00000008000808087E080808140862080008000003F80020002000D003080000 +CE6F:00000008000808087E0808081408620800080000004003F8004000A003180000 +CE70:00000008000808087E080808140862080008000003F8000803F8000800080000 +CE71:00000008000808087E080808140862080008000003F8020003F8020003F80000 +CE72:00000008000808087E080808140862080008000000000FF8022002200FF80000 +CE73:00000008000808087E080808140862080008000000800FF803E0041003E00000 +CE74:00000000001000101F9000900090009E1F100110021004101810001000100000 +CE75:000000087E08020802087E0E040818086008000007F800080008000800080000 +CE76:000000087E08020802087E0E040818086008000000003EF80208020802080000 +CE77:000000087E08020802087E0E040818086008000000001F080108011401620000 +CE78:000000087E08020802087E0E040818086008000808000800080008000FF80000 +CE79:000000087E08020802087E0E0408180860080000000010F8101010301ECC0000 +CE7A:000000087E08020802087E0E04081808600800000808087F081C08220F9C0000 +CE7B:000000087E08020802087E0E040818086008000003F802000200020003F80000 +CE7C:000000087E08020802087E0E040818086008000007F8000807F8040007F80000 +CE7D:000000087E08020802087E0E04081808600800003EF802083E0820083E080000 +CE7E:000000087E08020802087E0E04081808600800003EF802883E8820883EF80000 +CE7F:000000087E08020802087E0E04081808600800003E8802883EF820883EF80000 +CE80:000000087E08020802087E0E04081808600800001F0801081F0810141F620000 +CE81:000000087E08020802087E0E04081808600800003EF802803EF820803EF80000 +CE82:000000087E08020802087E0E04081808600800003EFC02483E4820483EFC0000 +CE83:000000087E08020802087E0E04081808600800001F08017F1F1C10221F1C0000 +CE84:000000087E08020802087E0E040818086008000003F802080208020803F80000 +CE85:000000087E08020802087E0E04081808600800000208020803F8020803F80000 +CE86:000000087E08020802087E0E0408180860080000110811081F0811141F620000 +CE87:000000087E08020802087E0E0408180860080000001000100010006801840000 +CE88:000000087E08020802087E0E04081808600800000048004800A8011406620000 +CE89:000000087E08020802087E0E0408180860080000000003F00408040803F00000 +CE8A:000000087E08020802087E0E040818086008000003F80020002000D003080000 +CE8B:000000087E08020802087E0E0408180860080000004003F8004000A003180000 +CE8C:000000087E08020802087E0E040818086008000003F8000803F8000800080000 +CE8D:000000087E08020802087E0E040818086008000003F8020003F8020003F80000 +CE8E:000000087E08020802087E0E040818086008000000000FF8022002200FF80000 +CE8F:000000087E08020802087E0E040818086008000000800FF803E0041003E00000 +CE90:00000000001200121F9200920092009E1F120112021204121812001200120000 +CE91:000000287E28022802287E38042818286028000007F800080008000800080000 +CE92:000000287E28022802287E38042818286028000000003EF80208020802080000 +CE93:000000287E28022802287E38042818286028000000003E100210022802C40000 +CE94:000000287E28022802287E38042818286028002808000800080008000FF80000 +CE95:000000287E28022802287E380428182860280000000020F8201020303ECC0000 +CE96:000000287E28022802287E380428182860280000202021FC207020883E700000 +CE97:000000287E28022802287E38042818286028000003F802000200020003F80000 +CE98:000000287E28022802287E38042818286028000007F8000807F8040007F80000 +CE99:000000287E28022802287E3804281828602800003EF802083E0820083E080000 +CE9A:000000287E28022802287E3804281828602800003EF802883E8820883EF80000 +CE9B:000000287E28022802287E3804281828602800003E8802883EF820883EF80000 +CE9C:000000287E28022802287E3804281828602800001F0801081F0810141F620000 +CE9D:000000287E28022802287E3804281828602800003EF802803EF820803EF80000 +CE9E:000000287E28022802287E3804281828602800003EFC02483E4820483EFC0000 +CE9F:000000287E28022802287E3804281828602800003E1002FE3E3820443E380000 +CEA0:000000287E28022802287E38042818286028000003F802080208020803F80000 +CEA1:000000287E28022802287E3804281828602800000208020803F8020803F80000 +CEA2:000000287E28022802287E380428182860280000110811081F0811141F620000 +CEA3:000000287E28022802287E380428182860280000000800080008003400C20000 +CEA4:000000287E28022802287E3804281828602800000048004800A8011406620000 +CEA5:000000287E28022802287E380428182860280000000001F00208020801F00000 +CEA6:000000287E28022802287E38042818286028000003F80020002000D003080000 +CEA7:000000287E28022802287E380428182860280000004003F8004000A003180000 +CEA8:000000287E28022802287E38042818286028000003F8000803F8000800080000 +CEA9:000000287E28022802287E38042818286028000003F8020003F8020003F80000 +CEAA:000000287E28022802287E38042818286028000000000FF8022002200FF80000 +CEAB:000000287E28022802287E38042818286028000000800FF803E0041003E00000 +CEAC:00000000001000101F900090009E00901F10011E021004101810001000100000 +CEAD:000000087E080208020E7E08040E18086008000007F800080008000800080000 +CEAE:000000087E080208020E7E08040E18086008000000003EF80208020802080000 +CEAF:000000087E080208020E7E08040E18086008000000001F080108011401620000 +CEB0:000000087E080208020E7E08040E18086008000008000800080008000FF80000 +CEB1:000000087E080208020E7E08040E180860080000000010F8101010301ECC0000 +CEB2:000000087E080208020E7E08040E1808600800000808087F081C08220F9C0000 +CEB3:000000087E080208020E7E08040E18086008000003F802000200020003F80000 +CEB4:000000087E080208020E7E08040E18086008000007F8000807F8040007F80000 +CEB5:000000087E080208020E7E08040E1808600800003EF802083E0820083E080000 +CEB6:000000087E080208020E7E08040E1808600800003EF802883E8820883EF80000 +CEB7:000000087E080208020E7E08040E1808600800003E8802883EF820883EF80000 +CEB8:000000087E080208020E7E08040E1808600800001F0801081F0810141F620000 +CEB9:000000087E080208020E7E08040E1808600800003EF802803EF820803EF80000 +CEBA:000000087E080208020E7E08040E1808600800003EFC02483E4820483EFC0000 +CEBB:000000087E080208020E7E08040E1808600800001F08017F1F1C10221F1C0000 +CEBC:000000087E080208020E7E08040E18086008000003F802080208020803F80000 +CEBD:000000087E080208020E7E08040E1808600800000208020803F8020803F80000 +CEBE:000000087E080208020E7E08040E180860080000110811081F0811141F620000 +CEBF:000000087E080208020E7E08040E180860080000001000100010006801840000 +CEC0:000000087E080208020E7E08040E1808600800000048004800A8011406620000 +CEC1:000000087E080208020E7E08040E180860080000000003F00408040803F00000 +CEC2:000000087E080208020E7E08040E18086008000003F80020002000D003080000 +CEC3:000000087E080208020E7E08040E180860080000004003F8004000A003180000 +CEC4:000000087E080208020E7E08040E18086008000003F8000803F8000800080000 +CEC5:000000087E080208020E7E08040E18086008000003F8020003F8020003F80000 +CEC6:000000087E080208020E7E08040E18086008000000000FF8022002200FF80000 +CEC7:000000087E080208020E7E08040E18086008000000800FF803E0041003E00000 +CEC8:00000000001200121F920092009E00921F12011E021204121812001200120000 +CEC9:000000287E28022802387E28043818286028000007F800080008000800080000 +CECA:000000287E28022802387E28043818286028000000003EF80208020802080000 +CECB:000000287E28022802387E28043818286028000000003E100210022802C40000 +CECC:000000287E28022802387E28043818286028002808000800080008000FF80000 +CECD:000000287E28022802387E280438182860280000000020F8201020303ECC0000 +CECE:000000287E28022802387E280438182860280000202021FC207020883E700000 +CECF:000000287E28022802387E28043818286028000003F802000200020003F80000 +CED0:000000287E28022802387E28043818286028000007F8000807F8040007F80000 +CED1:000000287E28022802387E2804381828602800003EF802083E0820083E080000 +CED2:000000287E28022802387E2804381828602800003EF802883E8820883EF80000 +CED3:000000287E28022802387E2804381828602800003E8802883EF820883EF80000 +CED4:000000287E28022802387E2804381828602800001F0801081F0810141F620000 +CED5:000000287E28022802387E2804381828602800003EF802803EF820803EF80000 +CED6:000000287E28022802387E2804381828602800003EFC02483E4820483EFC0000 +CED7:000000287E28022802387E2804381828602800003E1002FE3E3820443E380000 +CED8:000000287E28022802387E28043818286028000003F802080208020803F80000 +CED9:000000287E28022802387E2804381828602800000208020803F8020803F80000 +CEDA:000000287E28022802387E280438182860280000110811081F0811141F620000 +CEDB:000000287E28022802387E280438182860280000000800080008003400C20000 +CEDC:000000287E28022802387E2804381828602800000048004800A8011406620000 +CEDD:000000287E28022802387E280438182860280000000001F00208020801F00000 +CEDE:000000287E28022802387E28043818286028000003F80020002000D003080000 +CEDF:000000287E28022802387E280438182860280000004003F8004000A003180000 +CEE0:000000287E28022802387E28043818286028000003F8000803F8000800080000 +CEE1:000000287E28022802387E28043818286028000003F8020003F8020003F80000 +CEE2:000000287E28022802387E28043818286028000000000FF8022002200FF80000 +CEE3:000000287E28022802387E28043818286028000000800FF803E0041003E00000 +CEE4:00000000000200021F8200820082009E1F020102020204021802000200020000 +CEE5:000000087E08020802087E380408180860080000000007F80008000800080000 +CEE6:000000087E08020802087E38040818086008000000003EF80208020802080000 +CEE7:000000087E08020802087E38040818086008000000001F080108011401620000 +CEE8:000000087E08020802087E38040818086008000000001000100010001FF80000 +CEE9:000000087E08020802087E380408180860080000000020F8201020303ECC0000 +CEEA:000000087E08020802087E380408180860080000202021FC207020883E700000 +CEEB:000000087E08020802087E38040818086008000003F802000200020003F80000 +CEEC:000000087E08020802087E38040818086008000007F8000807F8040007F80000 +CEED:000000087E08020802087E3804081808600800003EF802083E0820083E080000 +CEEE:000000087E08020802087E3804081808600800003EF802883E8820883EF80000 +CEEF:000000087E08020802087E3804081808600800003E8802883EF820883EF80000 +CEF0:000000087E08020802087E3804081808600800000F8800880F8808140FA20000 +CEF1:000000087E08020802087E3804081808600800003EF802803EF820803EF80000 +CEF2:000000087E08020802087E3804081808600800003EFC02483E4820483EFC0000 +CEF3:000000087E08020802087E3804081808600800003E1002FE3E3820443E380000 +CEF4:000000087E08020802087E38040818086008000003F802080208020803F80000 +CEF5:000000087E08020802087E3804081808600800000208020803F8020803F80000 +CEF6:000000087E08020802087E380408180860080000210821083F0821143F620000 +CEF7:000000087E08020802087E380408180860080000001000100010006801840000 +CEF8:000000087E08020802087E3804081808600800000048004800A8011406620000 +CEF9:000000087E08020802087E380408180860080000000003F00408040803F00000 +CEFA:000000087E08020802087E38040818086008000003F80020002000D003080000 +CEFB:000000087E08020802087E380408180860080000004003F8004000A003180000 +CEFC:000000087E08020802087E38040818086008000003F8000803F8000800080000 +CEFD:000000087E08020802087E38040818086008000003F8020003F8020003F80000 +CEFE:000000087E08020802087E38040818086008000000000FF8022002200FF80000 +CEFF:000000087E08020802087E38040818086008000000800FF803E0041003E00000 +CF00:00000000000A000A1F8A008A008A00BA1F0A010A020A040A180A000A000A0000 +CF01:000000287E28022802287EE8042818286028000007F800080008000800080000 +CF02:000000287E28022802287EE8042818286028000000003EF80208020802080000 +CF03:000000287E28022802287EE8042818286028000000003E100210022802C40000 +CF04:000000287E28022802287EE8042818286028000008000800080008000FF80000 +CF05:000000287E28022802287EE80428182860280000000020F8201020303ECC0000 +CF06:000000287E28022802287EE80428182860280000202021FC207020883E700000 +CF07:000000287E28022802287EE8042818286028000003F802000200020003F80000 +CF08:000000287E28022802287EE8042818286028000007F8000807F8040007F80000 +CF09:000000287E28022802287EE804281828602800003EF802083E0820083E080000 +CF0A:000000287E28022802287EE804281828602800003EF802883E8820883EF80000 +CF0B:000000287E28022802287EE804281828602800003E8802883EF820883EF80000 +CF0C:000000287E28022802287EE804281828602800001F0801081F0810141F620000 +CF0D:000000287E28022802287EE804281828602800003EF802803EF820803EF80000 +CF0E:000000287E28022802287EE804281828602800003EFC02483E4820483EFC0000 +CF0F:000000287E28022802287EE804281828602800003E1002FE3E3820443E380000 +CF10:000000287E28022802287EE8042818286028000003F802080208020803F80000 +CF11:000000287E28022802287EE804281828602800000208020803F8020803F80000 +CF12:000000287E28022802287EE80428182860280000110811081F0811141F620000 +CF13:000000287E28022802287EE80428182860280000000800080008003400C20000 +CF14:000000287E28022802287EE804281828602800000048004800A8011406620000 +CF15:000000287E28022802287EE80428182860280000000001F00208020801F00000 +CF16:000000287E28022802287EE8042818286028000003F80020002000D003080000 +CF17:000000287E28022802287EE80428182860280000004003F8004000A003180000 +CF18:000000287E28022802287EE8042818286028000003F8000803F8000800080000 +CF19:000000287E28022802287EE8042818286028000003F8020003F8020003F80000 +CF1A:000000287E28022802287EE8042818286028000000000FF8022002200FF80000 +CF1B:000000287E28022802287EE8042818286028000000800FF803E0041003E00000 +CF1C:00000000000200021F820082009E00821F02011E020204021802000200020000 +CF1D:000000087E08020802387E080438180860080000000007F80008000800080000 +CF1E:000000087E08020802387E08043818086008000000003EF80208020802080000 +CF1F:000000087E08020802387E08043818086008000000001F080108011401620000 +CF20:000000087E08020802387E08043818086008000800001000100010001FF80000 +CF21:000000087E08020802387E080438180860080000000020F8201020303ECC0000 +CF22:000000087E08020802387E080438180860080000202021FC207020883E700000 +CF23:000000087E08020802387E08043818086008000003F802000200020003F80000 +CF24:000000087E08020802387E08043818086008000007F8000807F8040007F80000 +CF25:000000087E08020802387E0804381808600800003EF802083E0820083E080000 +CF26:000000087E08020802387E0804381808600800003EF802883E8820883EF80000 +CF27:000000087E08020802387E0804381808600800003E8802883EF820883EF80000 +CF28:000000087E08020802387E0804381808600800000F8800880F8808140FA20000 +CF29:000000087E08020802387E0804381808600800003EF802803EF820803EF80000 +CF2A:000000087E08020802387E0804381808600800003EFC02483E4820483EFC0000 +CF2B:000000087E08020802387E0804381808600800003E1002FE3E3820443E380000 +CF2C:000000087E08020802387E08043818086008000003F802080208020803F80000 +CF2D:000000087E08020802387E0804381808600800000208020803F8020803F80000 +CF2E:000000087E08020802387E080438180860080000210821083F0821143F620000 +CF2F:000000087E08020802387E080438180860080000001000100010006801840000 +CF30:000000087E08020802387E0804381808600800000048004800A8011406620000 +CF31:000000087E08020802387E080438180860080000000003F00408040803F00000 +CF32:000000087E08020802387E08043818086008000003F80020002000D003080000 +CF33:000000087E08020802387E080438180860080000004003F8004000A003180000 +CF34:000000087E08020802387E08043818086008000003F8000803F8000800080000 +CF35:000000087E08020802387E08043818086008000003F8020003F8020003F80000 +CF36:000000087E08020802387E08043818086008000000000FF8022002200FF80000 +CF37:000000087E08020802387E08043818086008000000800FF803E0041003E00000 +CF38:00000000000A000A1F8A008A00BA008A1F0A013A020A040A180A000A000A0000 +CF39:000000287E28022802E87E2804E818286028000007F800080008000800080000 +CF3A:000000287E28022802E87E2804E818286028000000003EF80208020802080000 +CF3B:000000287E28022802E87E2804E818286028000000003E100210022802C40000 +CF3C:000000287E28022802E87E2804E818286028002808000800080008000FF80000 +CF3D:000000287E28022802E87E2804E8182860280000000020F8201020303ECC0000 +CF3E:000000287E28022802E87E2804E8182860280000202021FC207020883E700000 +CF3F:000000287E28022802E87E2804E818286028000003F802000200020003F80000 +CF40:000000287E28022802E87E2804E818286028000007F8000807F8040007F80000 +CF41:000000287E28022802E87E2804E81828602800003EF802083E0820083E080000 +CF42:000000287E28022802E87E2804E81828602800003EF802883E8820883EF80000 +CF43:000000287E28022802E87E2804E81828602800003E8802883EF820883EF80000 +CF44:000000287E28022802E87E2804E81828602800001F0801081F0810141F620000 +CF45:000000287E28022802E87E2804E81828602800003EF802803EF820803EF80000 +CF46:000000287E28022802E87E2804E81828602800003EFC02483E4820483EFC0000 +CF47:000000287E28022802E87E2804E81828602800003E1002FE3E3820443E380000 +CF48:000000287E28022802E87E2804E818286028000003F802080208020803F80000 +CF49:000000287E28022802E87E2804E81828602800000208020803F8020803F80000 +CF4A:000000287E28022802E87E2804E8182860280000110811081F0811141F620000 +CF4B:000000287E28022802E87E2804E8182860280000000800080008003400C20000 +CF4C:000000287E28022802E87E2804E81828602800000048004800A8011406620000 +CF4D:000000287E28022802E87E2804E8182860280000000001F00208020801F00000 +CF4E:000000287E28022802E87E2804E818286028000003F80020002000D003080000 +CF4F:000000287E28022802E87E2804E8182860280000004003F8004000A003180000 +CF50:000000287E28022802E87E2804E818286028000003F8000803F8000800080000 +CF51:000000287E28022802E87E2804E818286028000003F8020003F8020003F80000 +CF52:000000287E28022802E87E2804E818286028000000000FF8022002200FF80000 +CF53:000000287E28022802E87E2804E818286028000000800FF803E0041003E00000 +CF54:00000000000000003FF8000800083FF8000802080208020002007FFC00000000 +CF55:000000001FF000101FF00010011001007FFC00001FF000100010001000100000 +CF56:000000001FF000101FF00010011001007FFC000000003EF80208020802080000 +CF57:000000001FF000101FF00010011001007FFC000000001E100210022802C40000 +CF58:000000001FF000101FF00010011001007FFC000000001000100010001FF00000 +CF59:000000001FF000101FF00010011001007FFC0000000020F8201020303ECC0000 +CF5A:000000001FF000101FF00010011001007FFC0000202021FC207020883E700000 +CF5B:000000001FF000101FF00010011001007FFC00001FF01000100010001FF00000 +CF5C:000000001FF000101FF00010011001007FFC00001FF000101FF010001FF00000 +CF5D:000000001FF000101FF00010011001007FFC00003EF802083E0820083E080000 +CF5E:000000001FF000101FF00010011001007FFC00003EF802883E8820883EF80000 +CF5F:000000001FF000101FF00010011001007FFC00003E8802883EF820883EF80000 +CF60:000000001FF000101FF00010011001007FFC00003E1002103E1020283EC40000 +CF61:000000001FF000101FF00010011001007FFC00003EF802803EF820803EF80000 +CF62:000000001FF000101FF00010011001007FFC00003EFC02483E4820483EFC0000 +CF63:000000001FF000101FF00010011001007FFC00003E2003FC3E7020883E700000 +CF64:000000001FF000101FF00010011001007FFC00001FF01010101010101FF00000 +CF65:000000001FF000101FF00010011001007FFC0000101010101FF010101FF00000 +CF66:000000001FF000101FF00010011001007FFC0000222022203E2022503E880000 +CF67:000000001FF000101FF00010011001007FFC000000000100010002800C400000 +CF68:000000001FF000101FF00010011001007FFC00000000024002400DA033100000 +CF69:000000001FF000101FF00010011001007FFC0000000007C00820082007C00000 +CF6A:000000001FF000101FF00010011001007FFC0000000007E00080014006200000 +CF6B:000000001FF000101FF00010011001007FFC0000008007E00080014006200000 +CF6C:000000001FF000101FF00010011001007FFC00001FF000101FF0001000100000 +CF6D:000000001FF000101FF00010011001007FFC00001FF010001FF010001FF00000 +CF6E:000000001FF000101FF00010011001007FFC000000001FF0044004401FF00000 +CF6F:000000001FF000101FF00010011001007FFC000001001FF007C0082007C00000 +CF70:00000000001000103FD0005000503FDE0450045004107FD00010001000100000 +CF71:000000083F8800883F8E0088048804087FE8000007F800080008000800080000 +CF72:000000083F8800883F8E0088048804087FE8000000003EF80208020802080000 +CF73:000000083F8800883F8E0088048804087FE8000000001F080108011401620000 +CF74:000000083F8800883F8E0088048804087FE8000008000800080008000FF80000 +CF75:000000083F8800883F8E0088048804087FE80000000010F8101010301ECC0000 +CF76:000000083F8800883F8E0088048804087FE800000808087F081C08220F9C0000 +CF77:000000083F8800883F8E0088048804087FE8000003F802000200020003F80000 +CF78:000000083F8800883F8E0088048804087FE8000007F8000807F8040007F80000 +CF79:000000083F8800883F8E0088048804087FE800003EF802083E0820083E080000 +CF7A:000000083F8800883F8E0088048804087FE800003EF802883E8820883EF80000 +CF7B:000000083F8800883F8E0088048804087FE800003E8802883EF820883EF80000 +CF7C:000000083F8800883F8E0088048804087FE800001F0801081F0810141F620000 +CF7D:000000083F8800883F8E0088048804087FE800003EF802803EF820803EF80000 +CF7E:000000083F8800883F8E0088048804087FE800003EFC02483E4820483EFC0000 +CF7F:000000083F8800883F8E0088048804087FE800001F08017F1F1C10221F1C0000 +CF80:000000083F8800883F8E0088048804087FE8000003F802080208020803F80000 +CF81:000000083F8800883F8E0088048804087FE800000208020803F8020803F80000 +CF82:000000083F8800883F8E0088048804087FE80000110811081F0811141F620000 +CF83:000000083F8800883F8E0088048804087FE80000001000100010006801840000 +CF84:000000083F8800883F8E0088048804087FE800000048004800A8011406620000 +CF85:000000083F8800883F8E0088048804087FE80000000003F00408040803F00000 +CF86:000000083F8800883F8E0088048804087FE8000003F80020002000D003080000 +CF87:000000083F8800883F8E0088048804087FE80000004003F8004000A003180000 +CF88:000000083F8800883F8E0088048804087FE8000003F8000803F8000800080000 +CF89:000000083F8800883F8E0088048804087FE8000003F8020003F8020003F80000 +CF8A:000000083F8800883F8E0088048804087FE8000000000FF8022002200FF80000 +CF8B:000000083F8800883F8E0088048804087FE8000000800FF803E0041003E00000 +CF8C:00000000001200123FD2005200523FDE0452045204127FD20012001200120000 +CF8D:000000283FA800A83FB800A804A804287FA8000007F800080008000800080000 +CF8E:000000283FA800A83FB800A804A804287FA8000000003EF80208020802080000 +CF8F:000000283FA800A83FB800A804A804287FA8000000001F080108011401620000 +CF90:000000283FA800A83FB800A804A804287FA8000008000800080008000FF80000 +CF91:000000283FA800A83FB800A804A804287FA80000000010F8101010301ECC0000 +CF92:000000283FA800A83FB800A804A804287FA800000808087F081C08220F9C0000 +CF93:000000283FA800A83FB800A804A804287FA8000003F802000200020003F80000 +CF94:000000283FA800A83FB800A804A804287FA8000007F8000807F8040007F80000 +CF95:000000283FA800A83FB800A804A804287FA800003EF802083E0820083E080000 +CF96:000000283FA800A83FB800A804A804287FA800003EF802883E8820883EF80000 +CF97:000000283FA800A83FB800A804A804287FA800003E8802883EF820883EF80000 +CF98:000000283FA800A83FB800A804A804287FA800001F0801081F0810141F620000 +CF99:000000283FA800A83FB800A804A804287FA800003EF802803EF820803EF80000 +CF9A:000000283FA800A83FB800A804A804287FA800003EFC02483E4820483EFC0000 +CF9B:000000283FA800A83FB800A804A804287FA800001F08017F1F1C10221F1C0000 +CF9C:000000283FA800A83FB800A804A804287FA8000003F802080208020803F80000 +CF9D:000000283FA800A83FB800A804A804287FA800000208020803F8020803F80000 +CF9E:000000283FA800A83FB800A804A804287FA80000110811081F0811141F620000 +CF9F:000000283FA800A83FB800A804A804287FA80000001000100010006801840000 +CFA0:000000283FA800A83FB800A804A804287FA800000048004800A8011406620000 +CFA1:000000283FA800A83FB800A804A804287FA80000000003F00408040803F00000 +CFA2:000000283FA800A83FB800A804A804287FA8000003F80020002000D003080000 +CFA3:000000283FA800A83FB800A804A804287FA80000004003F8004000A003180000 +CFA4:000000283FA800A83FB800A804A804287FA8000003F8000803F8000800080000 +CFA5:000000283FA800A83FB800A804A804287FA8000003F8020003F8020003F80000 +CFA6:000000283FA800A83FB800A804A804287FA8000000000FF8022002200FF80000 +CFA7:000000283FA800A83FB800A804A804287FA8000000800FF803E0041003E00000 +CFA8:00000000000400043FC4004400443FC40444044404047FF40004000400040000 +CFA9:000000083F8800883F880088048804087FE8000007F800080008000800080000 +CFAA:000000083F8800883F880088048804087FE8000000003EF80208020802080000 +CFAB:000000083F8800883F880088048804087FE8000000001F080108011401620000 +CFAC:000000083F8800883F880088048804087FE8000008000800080008000FF80000 +CFAD:000000083F8800883F880088048804087FE80000000010F8101010301ECC0000 +CFAE:000000083F8800883F880088048804087FE800000808087F081C08220F9C0000 +CFAF:000000083F8800883F880088048804087FE8000003F802000200020003F80000 +CFB0:000000083F8800883F880088048804087FE8000007F8000807F8040007F80000 +CFB1:000000083F8800883F880088048804087FE800003EF802083E0820083E080000 +CFB2:000000083F8800883F880088048804087FE800003EF802883E8820883EF80000 +CFB3:000000083F8800883F880088048804087FE800003E8802883EF820883EF80000 +CFB4:000000083F8800883F880088048804087FE800001F0801081F0810141F620000 +CFB5:000000083F8800883F880088048804087FE800003EF802803EF820803EF80000 +CFB6:000000083F8800883F880088048804087FE800003EFC02483E4820483EFC0000 +CFB7:000000083F8800883F880088048804087FE800001F08017F1F1C10221F1C0000 +CFB8:000000083F8800883F880088048804087FE8000003F802080208020803F80000 +CFB9:000000083F8800883F880088048804087FE800000208020803F8020803F80000 +CFBA:000000083F8800883F880088048804087FE80000110811081F0811141F620000 +CFBB:000000083F8800883F880088048804087FE80000001000100010006801840000 +CFBC:000000083F8800883F880088048804087FE800000048004800A8011406620000 +CFBD:000000083F8800883F880088048804087FE80000000003F00408040803F00000 +CFBE:000000083F8800883F880088048804087FE8000003F80020002000D003080000 +CFBF:000000083F8800883F880088048804087FE80000004003F8004000A003180000 +CFC0:000000083F8800883F880088048804087FE8000003F8000803F8000800080000 +CFC1:000000083F8800883F880088048804087FE8000003F8020003F8020003F80000 +CFC2:000000083F8800883F880088048804087FE8000000000FF8022002200FF80000 +CFC3:000000083F8800883F880088048804087FE8000000800FF803E0041003E00000 +CFC4:00000000000000003FF8000800083FF8000808880888088008807FFC00000000 +CFC5:000000001FF000101FF00010049004807FFC00001FF000100010001000100000 +CFC6:000000001FF000101FF00010049004807FFC000000003EF80208020802080000 +CFC7:000000001FF000101FF00010049004807FFC000000001E100210022802C40000 +CFC8:000000001FF000101FF00010049004807FFC000000001000100010001FF00000 +CFC9:000000001FF000101FF00010049004807FFC0000000020F8201020303ECC0000 +CFCA:000000001FF000101FF00010049004807FFC0000202021FC207020883E700000 +CFCB:000000001FF000101FF00010049004807FFC00001FF01000100010001FF00000 +CFCC:000000001FF000101FF00010049004807FFC00001FF000101FF010001FF00000 +CFCD:000000001FF000101FF00010049004807FFC00003EF802083E0820083E080000 +CFCE:000000001FF000101FF00010049004807FFC00003EF802883E8820883EF80000 +CFCF:000000001FF000101FF00010049004807FFC00003E8802883EF820883EF80000 +CFD0:000000001FF000101FF00010049004807FFC00003E1002103E1020283EC40000 +CFD1:000000001FF000101FF00010049004807FFC00003EF802803EF820803EF80000 +CFD2:000000001FF000101FF00010049004807FFC00003EFC02483E4820483EFC0000 +CFD3:000000001FF000101FF00010049004807FFC00003E2003FC3E7020883E700000 +CFD4:000000001FF000101FF00010049004807FFC00001FF01010101010101FF00000 +CFD5:000000001FF000101FF00010049004807FFC0000101010101FF010101FF00000 +CFD6:000000001FF000101FF00010049004807FFC0000222022203E2022503E880000 +CFD7:000000001FF000101FF00010049004807FFC000000000100010002800C400000 +CFD8:000000001FF000101FF00010049004807FFC00000000024002400DA033100000 +CFD9:000000001FF000101FF00010049004807FFC0000000007C00820082007C00000 +CFDA:000000001FF000101FF00010049004807FFC0000000007E00080014006200000 +CFDB:000000001FF000101FF00010049004807FFC0000008007E00080014006200000 +CFDC:000000001FF000101FF00010049004807FFC00001FF000101FF0001000100000 +CFDD:000000001FF000101FF00010049004807FFC00001FF010001FF010001FF00000 +CFDE:000000001FF000101FF00010049004807FFC000000001FF0044004401FF00000 +CFDF:000000001FF000101FF00010049004807FFC000001001FF007C0082007C00000 +CFE0:0000000000003FF8000800083FF80008000800003FF801000100010001000000 +CFE1:000000001FF000101FF0001000107FFC010001001FF000100010001000100000 +CFE2:000000001FF000101FF0001000107FFC0100010000003EF80208020802080000 +CFE3:000000001FF000101FF0001000107FFC0100010000001E100210022802C40000 +CFE4:000000001FF000101FF00010001000007FFC010001001100100010001FF00000 +CFE5:000000001FF000101FF0001000107FFC01000100000020F8201020303ECC0000 +CFE6:000000001FF000101FF0001000107FFC01000100202021FC207020883E700000 +CFE7:000000001FF000101FF0001000107FFC010001001FF01000100010001FF00000 +CFE8:000000001FF000101FF0001000107FFC010001001FF000101FF010001FF00000 +CFE9:000000001FF000101FF0001000107FFC010001003EF802083E0820083E080000 +CFEA:000000001FF000101FF0001000107FFC010001003EF802883E8820883EF80000 +CFEB:000000001FF000101FF0001000107FFC010001003E8802883EF820883EF80000 +CFEC:000000001FF000101FF0001000107FFC010001003E1002103E1020283EC40000 +CFED:000000001FF000101FF0001000107FFC010001003EF802803EF820803EF80000 +CFEE:000000001FF000101FF0001000107FFC010001003EFC02483E4820483EFC0000 +CFEF:000000001FF000101FF0001000107FFC010001003E2003FC3E7020883E700000 +CFF0:000000001FF000101FF0001000107FFC010001001FF01010101010101FF00000 +CFF1:000000001FF000101FF0001000107FFC01000100101010101FF010101FF00000 +CFF2:000000001FF000101FF0001000107FFC01000100222022203E2022503E880000 +CFF3:000000001FF000101FF0001000107FFC0100010000000100010002800C400000 +CFF4:000000001FF000101FF0001000107FFC010001000000024002400DA033100000 +CFF5:000000001FF000101FF0001000107FFC01000100000007C00820082007C00000 +CFF6:000000001FF000101FF0001000107FFC01000100000007E00080014006200000 +CFF7:000000001FF000101FF0001000107FFC01000100008007E00080014006200000 +CFF8:000000001FF000101FF0001000107FFC010001001FF000101FF0001000100000 +CFF9:000000001FF000101FF0001000107FFC010001001FF010001FF010001FF00000 +CFFA:000000001FF000101FF0001000107FFC0100010000001FF0044004401FF00000 +CFFB:000000001FF000101FF0001000107FFC0100010001001FF007C0082007C00000 +CFFC:0000000800083FC8004800483FC80048004800087FE8040804F8040804080000 +CFFD:00083F8800883F88008800887FE8027802080000000007F80008000800080000 +CFFE:00083F8800883F88008800887FE802780208000000003EF80208020802080000 +CFFF:00083F8800883F88008800887FE802780208000000001F080108011401620000 +D000:00083F8800883F880088008800087FE80278020802081000100010001FF80000 +D001:00083F8800883F88008800887FE8027802080000000020F8201020303ECC0000 +D002:00083F8800883F88008800887FE8027802080000202021FC207020883E700000 +D003:00083F8800883F88008800887FE802780208000003F802000200020003F80000 +D004:00083F8800883F88008800887FE802780208000007F8000807F8040007F80000 +D005:00083F8800883F88008800887FE80278020800003EF802083E0820083E080000 +D006:00083F8800883F88008800887FE80278020800003EF802883E8820883EF80000 +D007:00083F8800883F88008800887FE80278020800003E8802883EF820883EF80000 +D008:00083F8800883F88008800887FE80278020800000F8800880F8808140FA20000 +D009:00083F8800883F88008800887FE80278020800003EF802803EF820803EF80000 +D00A:00083F8800883F88008800887FE80278020800003EFC02483E4820483EFC0000 +D00B:00083F8800883F88008800887FE80278020800003E1002FE3E3820443E380000 +D00C:00083F8800883F88008800887FE802780208000003F802080208020803F80000 +D00D:00083F8800883F88008800887FE80278020800000208020803F8020803F80000 +D00E:00083F8800883F88008800887FE8027802080000210821083F0821143F620000 +D00F:00083F8800883F88008800887FE8027802080000001000100010006801840000 +D010:00083F8800883F88008800887FE80278020800000048004800A8011406620000 +D011:00083F8800883F88008800887FE8027802080000000003F00408040803F00000 +D012:00083F8800883F88008800887FE802780208000003F80020002000D003080000 +D013:00083F8800883F88008800887FE8027802080000004003F8004000A003180000 +D014:00083F8800883F88008800887FE802780208000003F8000803F8000800080000 +D015:00083F8800883F88008800887FE802780208000003F8020003F8020003F80000 +D016:00083F8800883F88008800887FE802780208000000000FF8022002200FF80000 +D017:00083F8800883F88008800887FE802780208000000800FF803E0041003E00000 +D018:0000000A000A3FCA004A004A3FCA004A004A000A7FEA040A047A040A040A0000 +D019:00283FA800A83FA800A800A87FA805E804280000000007F80008000800080000 +D01A:00283FA800A83FA800A800A87FA805E80428000000003EF80208020802080000 +D01B:00283FA800A83FA800A800A87FA805E80428000000001F080108011401620000 +D01C:00283FA800A83FA800A800A800287FA8042805E804281428100010001FF80000 +D01D:00283FA800A83FA800A800A87FA805E804280000000020F8201020303ECC0000 +D01E:00283FA800A83FA800A800A87FA805E804280000202021FC207020883E700000 +D01F:00283FA800A83FA800A800A87FA805E80428000003F802000200020003F80000 +D020:00283FA800A83FA800A800A87FA805E80428000007F8000807F8040007F80000 +D021:00283FA800A83FA800A800A87FA805E8042800003EF802083E0820083E080000 +D022:00283FA800A83FA800A800A87FA805E8042800003EF802883E8820883EF80000 +D023:00283FA800A83FA800A800A87FA805E8042800003E8802883EF820883EF80000 +D024:00283FA800A83FA800A800A87FA805E8042800000F8800880F8808140FA20000 +D025:00283FA800A83FA800A800A87FA805E8042800003EF802803EF820803EF80000 +D026:00283FA800A83FA800A800A87FA805E8042800003EFC02483E4820483EFC0000 +D027:00283FA800A83FA800A800A87FA805E8042800003E1002FE3E3820443E380000 +D028:00283FA800A83FA800A800A87FA805E80428000003F802080208020803F80000 +D029:00283FA800A83FA800A800A87FA805E8042800000208020803F8020803F80000 +D02A:00283FA800A83FA800A800A87FA805E804280000210821083F0821143F620000 +D02B:00283FA800A83FA800A800A87FA805E804280000001000100010006801840000 +D02C:00283FA800A83FA800A800A87FA805E8042800000048004800A8011406620000 +D02D:00283FA800A83FA800A800A87FA805E804280000000003F00408040803F00000 +D02E:00283FA800A83FA800A800A87FA805E80428000003F80020002000D003080000 +D02F:00283FA800A83FA800A800A87FA805E804280000004003F8004000A003180000 +D030:00283FA800A83FA800A800A87FA805E80428000003F8000803F8000800080000 +D031:00283FA800A83FA800A800A87FA805E80428000003F8020003F8020003F80000 +D032:00283FA800A83FA800A800A87FA805E80428000000000FF8022002200FF80000 +D033:00283FA800A83FA800A800A87FA805E80428000000800FF803E0041003E00000 +D034:0000000800083FC8004800483FC80048004800087FE804080408040804080000 +D035:00083F8800883F88008800887FE8020802000000000007F80008000800080000 +D036:00083F8800883F88008800887FE802080200000000003EF80208020802080000 +D037:00083F8800883F88008800887FE802080200000000001F080108011401620000 +D038:00083F8800883F880088008800087FE80208020802081008100010001FF80000 +D039:00083F8800883F88008800887FE8020802000000000020F8201020303ECC0000 +D03A:00083F8800883F88008800887FE8020802000000202021FC207020883E700000 +D03B:00083F8800883F88008800887FE802080200000003F802000200020003F80000 +D03C:00083F8800883F88008800887FE802080200000007F8000807F8040007F80000 +D03D:00083F8800883F88008800887FE80208020000003EF802083E0820083E080000 +D03E:00083F8800883F88008800887FE80208020000003EF802883E8820883EF80000 +D03F:00083F8800883F88008800887FE80208020000003E8802883EF820883EF80000 +D040:00083F8800883F88008800887FE80208020000000F8800880F8808140FA20000 +D041:00083F8800883F88008800887FE80208020000003EF802803EF820803EF80000 +D042:00083F8800883F88008800887FE80208020000003EFC02483E4820483EFC0000 +D043:00083F8800883F88008800887FE80208020000003E1002FE3E3820443E380000 +D044:00083F8800883F88008800887FE802080200000003F802080208020803F80000 +D045:00083F8800883F88008800887FE80208020000000208020803F8020803F80000 +D046:00083F8800883F88008800887FE8020802000000210821083F0821143F620000 +D047:00083F8800883F88008800887FE8020802000000001000100010006801840000 +D048:00083F8800883F88008800887FE80208020000000048004800A8011406620000 +D049:00083F8800883F88008800887FE8020802000000000003F00408040803F00000 +D04A:00083F8800883F88008800887FE802080200000003F80020002000D003080000 +D04B:00083F8800883F88008800887FE8020802000000004003F8004000A003180000 +D04C:00083F8800883F88008800887FE802080200000003F8000803F8000800080000 +D04D:00083F8800883F88008800887FE802080200000003F8020003F8020003F80000 +D04E:00083F8800883F88008800887FE802080200000000000FF8022002200FF80000 +D04F:00083F8800883F88008800887FE802080200000000800FF803E0041003E00000 +D050:0000000000003FF8000800083FF80008000800007FFC04400440044004400000 +D051:000000001FF000101FF0001000107FFC044004401FF000100010001000100000 +D052:000000001FF000101FF0001000107FFC0440044000003EF80208020802080000 +D053:000000001FF000101FF0001000107FFC0440044000001E100210022802C40000 +D054:000000001FF000101FF00010001000007FFC044004401440100010001FF00000 +D055:000000001FF000101FF0001000107FFC04400440000020F8201020303ECC0000 +D056:000000001FF000101FF0001000107FFC04400440202021FC207020883E700000 +D057:000000001FF000101FF0001000107FFC044004401FF01000100010001FF00000 +D058:000000001FF000101FF0001000107FFC044004401FF000101FF010001FF00000 +D059:000000001FF000101FF0001000107FFC044004403EF802083E0820083E080000 +D05A:000000001FF000101FF0001000107FFC044004403EF802883E8820883EF80000 +D05B:000000001FF000101FF0001000107FFC044004403E8802883EF820883EF80000 +D05C:000000001FF000101FF0001000107FFC044004403E1002103E1020283EC40000 +D05D:000000001FF000101FF0001000107FFC044004403EF802803EF820803EF80000 +D05E:000000001FF000101FF0001000107FFC044004403EFC02483E4820483EFC0000 +D05F:000000001FF000101FF0001000107FFC044004403E2003FC3E7020883E700000 +D060:000000001FF000101FF0001000107FFC044004401FF01010101010101FF00000 +D061:000000001FF000101FF0001000107FFC04400440101010101FF010101FF00000 +D062:000000001FF000101FF0001000107FFC04400440222022203E2022503E880000 +D063:000000001FF000101FF0001000107FFC0440044000000100010002800C400000 +D064:000000001FF000101FF0001000107FFC044004400000024002400DA033100000 +D065:000000001FF000101FF0001000107FFC04400440000007C00820082007C00000 +D066:000000001FF000101FF0001000107FFC04400440000007E00080014006200000 +D067:000000001FF000101FF0001000107FFC04400440008007E00080014006200000 +D068:000000001FF000101FF0001000107FFC044004401FF000101FF0001000100000 +D069:000000001FF000101FF0001000107FFC044004401FF010001FF010001FF00000 +D06A:000000001FF000101FF0001000107FFC0440044000001FF0044004401FF00000 +D06B:000000001FF000101FF0001000107FFC0440044001001FF007C0082007C00000 +D06C:00000000000000003FF8000800083FF80008000800087FFC0000000000000000 +D06D:000000001FF000101FF00010001000007FFC00001FF000100010001000100000 +D06E:000000001FF000101FF00010001000007FFC000000003EF80208020802080000 +D06F:000000001FF000101FF00010001000007FFC000000001E100210022802C40000 +D070:000000001FF000101FF00010001000007FFC000000001000100010001FF00000 +D071:000000001FF000101FF00010001000007FFC0000000020F8201020303ECC0000 +D072:000000001FF000101FF00010001000007FFC0000202021FC207020883E700000 +D073:000000001FF000101FF00010001000007FFC00001FF01000100010001FF00000 +D074:000000001FF000101FF00010001000007FFC00001FF000101FF010001FF00000 +D075:000000001FF000101FF00010001000007FFC00003EF802083E0820083E080000 +D076:000000001FF000101FF00010001000007FFC00003EF802883E8820883EF80000 +D077:000000001FF000101FF00010001000007FFC00003E8802883EF820883EF80000 +D078:000000001FF000101FF00010001000007FFC00003E1002103E1020283EC40000 +D079:000000001FF000101FF00010001000007FFC00003EF802803EF820803EF80000 +D07A:000000001FF000101FF00010001000007FFC00003EFC02483E4820483EFC0000 +D07B:000000001FF000101FF00010001000007FFC00003E2003FC3E7020883E700000 +D07C:000000001FF000101FF00010001000007FFC00001FF01010101010101FF00000 +D07D:000000001FF000101FF00010001000007FFC0000101010101FF010101FF00000 +D07E:000000001FF000101FF00010001000007FFC0000222022203E2022503E880000 +D07F:000000001FF000101FF00010001000007FFC000000000100010002800C400000 +D080:000000001FF000101FF00010001000007FFC00000000024002400DA033100000 +D081:000000001FF000101FF00010001000007FFC0000000007C00820082007C00000 +D082:000000001FF000101FF00010001000007FFC0000000007E00080014006200000 +D083:000000001FF000101FF00010001000007FFC0000008007E00080014006200000 +D084:000000001FF000101FF00010001000007FFC00001FF000101FF0001000100000 +D085:000000001FF000101FF00010001000007FFC00001FF010001FF010001FF00000 +D086:000000001FF000101FF00010001000007FFC000000001FF0044004401FF00000 +D087:000000001FF000101FF00010001000007FFC000001001FF007C0082007C00000 +D088:00000000000800083FC8004800483FC80048004800087FE80008000800080000 +D089:000000083F8800883F880088008800087FE8000007F800080008000800080000 +D08A:000000083F8800883F880088008800087FE8000000003EF80208020802080000 +D08B:000000083F8800883F880088008800087FE8000000001F080108011401620000 +D08C:000000083F8800883F880088008800087FE8000008000800080008000FF80000 +D08D:000000083F8800883F880088008800087FE80000000010F8101010301ECC0000 +D08E:000000083F8800883F880088008800087FE800000808087F081C08220F9C0000 +D08F:000000083F8800883F880088008800087FE8000003F802000200020003F80000 +D090:000000083F8800883F880088008800087FE8000007F8000807F8040007F80000 +D091:000000083F8800883F880088008800087FE800003EF802083E0820083E080000 +D092:000000083F8800883F880088008800087FE800003EF802883E8820883EF80000 +D093:000000083F8800883F880088008800087FE800003E8802883EF820883EF80000 +D094:000000083F8800883F880088008800087FE800001F0801081F0810141F620000 +D095:000000083F8800883F880088008800087FE800003EF802803EF820803EF80000 +D096:000000083F8800883F880088008800087FE800003EFC02483E4820483EFC0000 +D097:000000083F8800883F880088008800087FE800001F08017F1F1C10221F1C0000 +D098:000000083F8800883F880088008800087FE8000003F802080208020803F80000 +D099:000000083F8800883F880088008800087FE800000208020803F8020803F80000 +D09A:000000083F8800883F880088008800087FE80000110811081F0811141F620000 +D09B:000000083F8800883F880088008800087FE80000001000100010006801840000 +D09C:000000083F8800883F880088008800087FE800000048004800A8011406620000 +D09D:000000083F8800883F880088008800087FE80000000003F00408040803F00000 +D09E:000000083F8800883F880088008800087FE8000003F80020002000D003080000 +D09F:000000083F8800883F880088008800087FE80000004003F8004000A003180000 +D0A0:000000083F8800883F880088008800087FE8000003F8000803F8000800080000 +D0A1:000000083F8800883F880088008800087FE8000003F8020003F8020003F80000 +D0A2:000000083F8800883F880088008800087FE8000000000FF8022002200FF80000 +D0A3:000000083F8800883F880088008800087FE8000000800FF803E0041003E00000 +D0A4:00000000000800081F880088008800881F080108020804081808000800080000 +D0A5:000000087E08020802087E080408180860080000000007F80008000800080000 +D0A6:000000087E08020802087E08040818086008000000003EF80208020802080000 +D0A7:000000087E08020802087E08040818086008000000001F080108011401620000 +D0A8:000000087E08020802087E08040818086008000800001000100010001FF80000 +D0A9:000000087E08020802087E080408180860080000000020F8201020303ECC0000 +D0AA:000000087E08020802087E080408180860080000202021FC207020883E700000 +D0AB:000000087E08020802087E08040818086008000003F802000200020003F80000 +D0AC:000000087E08020802087E08040818086008000007F8000807F8040007F80000 +D0AD:000000087E08020802087E0804081808600800003EF802083E0820083E080000 +D0AE:000000087E08020802087E0804081808600800003EF802883E8820883EF80000 +D0AF:000000087E08020802087E0804081808600800003E8802883EF820883EF80000 +D0B0:000000087E08020802087E0804081808600800000F8800880F8808140FA20000 +D0B1:000000087E08020802087E0804081808600800003EF802803EF820803EF80000 +D0B2:000000087E08020802087E0804081808600800003EFC02483E4820483EFC0000 +D0B3:000000087E08020802087E0804081808600800003E1002FE3E3820443E380000 +D0B4:000000087E08020802087E08040818086008000003F802080208020803F80000 +D0B5:000000087E08020802087E0804081808600800000208020803F8020803F80000 +D0B6:000000087E08020802087E080408180860080000210821083F0821143F620000 +D0B7:000000087E08020802087E080408180860080000001000100010006801840000 +D0B8:000000087E08020802087E0804081808600800000048004800A8011406620000 +D0B9:000000087E08020802087E080408180860080000000003F00408040803F00000 +D0BA:000000087E08020802087E08040818086008000003F80020002000D003080000 +D0BB:000000087E08020802087E080408180860080000004003F8004000A003180000 +D0BC:000000087E08020802087E08040818086008000003F8000803F8000800080000 +D0BD:000000087E08020802087E08040818086008000003F8020003F8020003F80000 +D0BE:000000087E08020802087E08040818086008000000000FF8022002200FF80000 +D0BF:000000087E08020802087E08040818086008000000800FF803E0041003E00000 +D0C0:00000000001000103F90201020103F9E201020103F9000100010001000100000 +D0C1:0000000800087E0840087E0E40087E080008000007F800080008000800080000 +D0C2:0000000800087E0840087E0E40087E080008000000003EF80208020802080000 +D0C3:0000000800087E0840087E0E40087E080008000000001F080108011401620000 +D0C4:0000000800087E0840087E0E40087E080008000808000800080008000FF80000 +D0C5:0000000800087E0840087E0E40087E0800080000000010F8101010301ECC0000 +D0C6:0000000800087E0840087E0E40087E08000800000808087F081C08220F9C0000 +D0C7:0000000800087E0840087E0E40087E080008000003F802000200020003F80000 +D0C8:0000000800087E0840087E0E40087E080008000007F8000807F8040007F80000 +D0C9:0000000800087E0840087E0E40087E08000800003EF802083E0820083E080000 +D0CA:0000000800087E0840087E0E40087E08000800003EF802883E8820883EF80000 +D0CB:0000000800087E0840087E0E40087E08000800003E8802883EF820883EF80000 +D0CC:0000000800087E0840087E0E40087E08000800001F0801081F0810141F620000 +D0CD:0000000800087E0840087E0E40087E08000800003EF802803EF820803EF80000 +D0CE:0000000800087E0840087E0E40087E08000800003EFC02483E4820483EFC0000 +D0CF:0000000800087E0840087E0E40087E08000800001F08017F1F1C10221F1C0000 +D0D0:0000000800087E0840087E0E40087E080008000003F802080208020803F80000 +D0D1:0000000800087E0840087E0E40087E08000800000208020803F8020803F80000 +D0D2:0000000800087E0840087E0E40087E0800080000110811081F0811141F620000 +D0D3:0000000800087E0840087E0E40087E0800080000001000100010006801840000 +D0D4:0000000800087E0840087E0E40087E08000800000048004800A8011406620000 +D0D5:0000000800087E0840087E0E40087E0800080000000003F00408040803F00000 +D0D6:0000000800087E0840087E0E40087E080008000003F80020002000D003080000 +D0D7:0000000800087E0840087E0E40087E0800080000004003F8004000A003180000 +D0D8:0000000800087E0840087E0E40087E080008000003F8000803F8000800080000 +D0D9:0000000800087E0840087E0E40087E080008000003F8020003F8020003F80000 +D0DA:0000000800087E0840087E0E40087E080008000000000FF8022002200FF80000 +D0DB:0000000800087E0840087E0E40087E080008000000800FF803E0041003E00000 +D0DC:00000000001200123F92201220123F9E201220123F9200120012001200120000 +D0DD:0000002800287E2840287E3840287E280028000007F800080008000800080000 +D0DE:0000002800287E2840287E3840287E280028000000003EF80208020802080000 +D0DF:0000002800287E2840287E3840287E280028000000003E100210022802C40000 +D0E0:0000002800287E2840287E3840287E280028002808000800080008000FF80000 +D0E1:0000002800287E2840287E3840287E2800280000000020F8201020303ECC0000 +D0E2:0000002800287E2840287E3840287E2800280000202021FC207020883E700000 +D0E3:0000002800287E2840287E3840287E280028000003F802000200020003F80000 +D0E4:0000002800287E2840287E3840287E280028000007F8000807F8040007F80000 +D0E5:0000002800287E2840287E3840287E28002800003EF802083E0820083E080000 +D0E6:0000002800287E2840287E3840287E28002800003EF802883E8820883EF80000 +D0E7:0000002800287E2840287E3840287E28002800003E8802883EF820883EF80000 +D0E8:0000002800287E2840287E3840287E28002800001F0801081F0810141F620000 +D0E9:0000002800287E2840287E3840287E28002800003EF802803EF820803EF80000 +D0EA:0000002800287E2840287E3840287E28002800003EFC02483E4820483EFC0000 +D0EB:0000002800287E2840287E3840287E28002800003E1002FE3E3820443E380000 +D0EC:0000002800287E2840287E3840287E280028000003F802080208020803F80000 +D0ED:0000002800287E2840287E3840287E28002800000208020803F8020803F80000 +D0EE:0000002800287E2840287E3840287E2800280000110811081F0811141F620000 +D0EF:0000002800287E2840287E3840287E2800280000000800080008003400C20000 +D0F0:0000002800287E2840287E3840287E28002800000048004800A8011406620000 +D0F1:0000002800287E2840287E3840287E2800280000000001F00208020801F00000 +D0F2:0000002800287E2840287E3840287E280028000003F80020002000D003080000 +D0F3:0000002800287E2840287E3840287E2800280000004003F8004000A003180000 +D0F4:0000002800287E2840287E3840287E280028000003F8000803F8000800080000 +D0F5:0000002800287E2840287E3840287E280028000003F8020003F8020003F80000 +D0F6:0000002800287E2840287E3840287E280028000000000FF8022002200FF80000 +D0F7:0000002800287E2840287E3840287E280028000000800FF803E0041003E00000 +D0F8:00000000001000103F902010201E3F902010201E3F9000100010001000100000 +D0F9:0000000800087E08400E7E08400E7E080008000007F800080008000800080000 +D0FA:0000000800087E08400E7E08400E7E080008000000003EF80208020802080000 +D0FB:0000000800087E08400E7E08400E7E080008000000001F080108011401620000 +D0FC:0000000800087E08400E7E08400E7E080008000008000800080008000FF80000 +D0FD:0000000800087E08400E7E08400E7E0800080000000010F8101010301ECC0000 +D0FE:0000000800087E08400E7E08400E7E08000800000808087F081C08220F9C0000 +D0FF:0000000800087E08400E7E08400E7E080008000003F802000200020003F80000 +D100:0000000800087E08400E7E08400E7E080008000007F8000807F8040007F80000 +D101:0000000800087E08400E7E08400E7E08000800003EF802083E0820083E080000 +D102:0000000800087E08400E7E08400E7E08000800003EF802883E8820883EF80000 +D103:0000000800087E08400E7E08400E7E08000800003E8802883EF820883EF80000 +D104:0000000800087E08400E7E08400E7E08000800001F0801081F0810141F620000 +D105:0000000800087E08400E7E08400E7E08000800003EF802803EF820803EF80000 +D106:0000000800087E08400E7E08400E7E08000800003EFC02483E4820483EFC0000 +D107:0000000800087E08400E7E08400E7E08000800001F08017F1F1C10221F1C0000 +D108:0000000800087E08400E7E08400E7E080008000003F802080208020803F80000 +D109:0000000800087E08400E7E08400E7E08000800000208020803F8020803F80000 +D10A:0000000800087E08400E7E08400E7E0800080000110811081F0811141F620000 +D10B:0000000800087E08400E7E08400E7E0800080000001000100010006801840000 +D10C:0000000800087E08400E7E08400E7E08000800000048004800A8011406620000 +D10D:0000000800087E08400E7E08400E7E0800080000000003F00408040803F00000 +D10E:0000000800087E08400E7E08400E7E080008000003F80020002000D003080000 +D10F:0000000800087E08400E7E08400E7E0800080000004003F8004000A003180000 +D110:0000000800087E08400E7E08400E7E080008000003F8000803F8000800080000 +D111:0000000800087E08400E7E08400E7E080008000003F8020003F8020003F80000 +D112:0000000800087E08400E7E08400E7E080008000000000FF8022002200FF80000 +D113:0000000800087E08400E7E08400E7E080008000000800FF803E0041003E00000 +D114:00000000001200123F922012201E3F922012201E3F9200120012001200120000 +D115:0000002800287E2840387E2840387E280028000007F800080008000800080000 +D116:0000002800287E2840387E2840387E280028000000003EF80208020802080000 +D117:0000002800287E2840387E2840387E280028000000003E100210022802C40000 +D118:0000002800287E2840387E2840387E280028002808000800080008000FF80000 +D119:0000002800287E2840387E2840387E2800280000000020F8201020303ECC0000 +D11A:0000002800287E2840387E2840387E2800280000202021FC207020883E700000 +D11B:0000002800287E2840387E2840387E280028000003F802000200020003F80000 +D11C:0000002800287E2840387E2840387E280028000007F8000807F8040007F80000 +D11D:0000002800287E2840387E2840387E28002800003EF802083E0820083E080000 +D11E:0000002800287E2840387E2840387E28002800003EF802883E8820883EF80000 +D11F:0000002800287E2840387E2840387E28002800003E8802883EF820883EF80000 +D120:0000002800287E2840387E2840387E28002800001F0801081F0810141F620000 +D121:0000002800287E2840387E2840387E28002800003EF802803EF820803EF80000 +D122:0000002800287E2840387E2840387E28002800003EFC02483E4820483EFC0000 +D123:0000002800287E2840387E2840387E28002800003E1002FE3E3820443E380000 +D124:0000002800287E2840387E2840387E280028000003F802080208020803F80000 +D125:0000002800287E2840387E2840387E28002800000208020803F8020803F80000 +D126:0000002800287E2840387E2840387E2800280000110811081F0811141F620000 +D127:0000002800287E2840387E2840387E2800280000000800080008003400C20000 +D128:0000002800287E2840387E2840387E28002800000048004800A8011406620000 +D129:0000002800287E2840387E2840387E2800280000000001F00208020801F00000 +D12A:0000002800287E2840387E2840387E280028000003F80020002000D003080000 +D12B:0000002800287E2840387E2840387E2800280000004003F8004000A003180000 +D12C:0000002800287E2840387E2840387E280028000003F8000803F8000800080000 +D12D:0000002800287E2840387E2840387E280028000003F8020003F8020003F80000 +D12E:0000002800287E2840387E2840387E280028000000000FF8022002200FF80000 +D12F:0000002800287E2840387E2840387E280028000000800FF803E0041003E00000 +D130:00000000000200023F82200220023F9E200220023F8200020002000200020000 +D131:0000000800087E0840087E3840087E0800080000000007F80008000800080000 +D132:0000000800087E0840087E3840087E080008000000003EF80208020802080000 +D133:0000000800087E0840087E3840087E080008000000001F080108011401620000 +D134:0000000800087E0840087E3840087E080008000000001000100010001FF80000 +D135:0000000800087E0840087E3840087E0800080000000020F8201020303ECC0000 +D136:0000000800087E0840087E3840087E0800080000202021FC207020883E700000 +D137:0000000800087E0840087E3840087E080008000003F802000200020003F80000 +D138:0000000800087E0840087E3840087E080008000007F8000807F8040007F80000 +D139:0000000800087E0840087E3840087E08000800003EF802083E0820083E080000 +D13A:0000000800087E0840087E3840087E08000800003EF802883E8820883EF80000 +D13B:0000000800087E0840087E3840087E08000800003E8802883EF820883EF80000 +D13C:0000000800087E0840087E3840087E08000800000F8800880F8808140FA20000 +D13D:0000000800087E0840087E3840087E08000800003EF802803EF820803EF80000 +D13E:0000000800087E0840087E3840087E08000800003EFC02483E4820483EFC0000 +D13F:0000000800087E0840087E3840087E08000800003E1002FE3E3820443E380000 +D140:0000000800087E0840087E3840087E080008000003F802080208020803F80000 +D141:0000000800087E0840087E3840087E08000800000208020803F8020803F80000 +D142:0000000800087E0840087E3840087E0800080000210821083F0821143F620000 +D143:0000000800087E0840087E3840087E0800080000001000100010006801840000 +D144:0000000800087E0840087E3840087E08000800000048004800A8011406620000 +D145:0000000800087E0840087E3840087E0800080000000003F00408040803F00000 +D146:0000000800087E0840087E3840087E080008000003F80020002000D003080000 +D147:0000000800087E0840087E3840087E0800080000004003F8004000A003180000 +D148:0000000800087E0840087E3840087E080008000003F8000803F8000800080000 +D149:0000000800087E0840087E3840087E080008000003F8020003F8020003F80000 +D14A:0000000800087E0840087E3840087E080008000000000FF8022002200FF80000 +D14B:0000000800087E0840087E3840087E080008000000800FF803E0041003E00000 +D14C:00000000000A000A3F8A200A200A3FBA200A200A3F8A000A000A000A000A0000 +D14D:0000002800287E2840287EE840287E280028000007F800080008000800080000 +D14E:0000002800287E2840287EE840287E280028000000003EF80208020802080000 +D14F:0000002800287E2840287EE840287E280028000000003E100210022802C40000 +D150:0000002800287E2840287EE840287E280028000008000800080008000FF80000 +D151:0000002800287E2840287EE840287E2800280000000020F8201020303ECC0000 +D152:0000002800287E2840287EE840287E2800280000202021FC207020883E700000 +D153:0000002800287E2840287EE840287E280028000003F802000200020003F80000 +D154:0000002800287E2840287EE840287E280028000007F8000807F8040007F80000 +D155:0000002800287E2840287EE840287E28002800003EF802083E0820083E080000 +D156:0000002800287E2840287EE840287E28002800003EF802883E8820883EF80000 +D157:0000002800287E2840287EE840287E28002800003E8802883EF820883EF80000 +D158:0000002800287E2840287EE840287E28002800001F0801081F0810141F620000 +D159:0000002800287E2840287EE840287E28002800003EF802803EF820803EF80000 +D15A:0000002800287E2840287EE840287E28002800003EFC02483E4820483EFC0000 +D15B:0000002800287E2840287EE840287E28002800003E1002FE3E3820443E380000 +D15C:0000002800287E2840287EE840287E280028000003F802080208020803F80000 +D15D:0000002800287E2840287EE840287E28002800000208020803F8020803F80000 +D15E:0000002800287E2840287EE840287E2800280000110811081F0811141F620000 +D15F:0000002800287E2840287EE840287E2800280000000800080008003400C20000 +D160:0000002800287E2840287EE840287E28002800000048004800A8011406620000 +D161:0000002800287E2840287EE840287E2800280000000001F00208020801F00000 +D162:0000002800287E2840287EE840287E280028000003F80020002000D003080000 +D163:0000002800287E2840287EE840287E2800280000004003F8004000A003180000 +D164:0000002800287E2840287EE840287E280028000003F8000803F8000800080000 +D165:0000002800287E2840287EE840287E280028000003F8020003F8020003F80000 +D166:0000002800287E2840287EE840287E280028000000000FF8022002200FF80000 +D167:0000002800287E2840287EE840287E280028000000800FF803E0041003E00000 +D168:00000000000200023F822002201E3F822002201E3F8200020002000200020000 +D169:0000000800087E0840387E0840387E0800080000000007F80008000800080000 +D16A:0000000800087E0840387E0840387E080008000000003EF80208020802080000 +D16B:0000000800087E0840387E0840387E080008000000001F080108011401620000 +D16C:0000000800087E0840387E0840387E080008000800001000100010001FF80000 +D16D:0000000800087E0840387E0840387E0800080000000020F8201020303ECC0000 +D16E:0000000800087E0840387E0840387E0800080000202021FC207020883E700000 +D16F:0000000800087E0840387E0840387E080008000003F802000200020003F80000 +D170:0000000800087E0840387E0840387E080008000007F8000807F8040007F80000 +D171:0000000800087E0840387E0840387E08000800003EF802083E0820083E080000 +D172:0000000800087E0840387E0840387E08000800003EF802883E8820883EF80000 +D173:0000000800087E0840387E0840387E08000800003E8802883EF820883EF80000 +D174:0000000800087E0840387E0840387E08000800000F8800880F8808140FA20000 +D175:0000000800087E0840387E0840387E08000800003EF802803EF820803EF80000 +D176:0000000800087E0840387E0840387E08000800003EFC02483E4820483EFC0000 +D177:0000000800087E0840387E0840387E08000800003E1002FE3E3820443E380000 +D178:0000000800087E0840387E0840387E080008000003F802080208020803F80000 +D179:0000000800087E0840387E0840387E08000800000208020803F8020803F80000 +D17A:0000000800087E0840387E0840387E0800080000210821083F0821143F620000 +D17B:0000000800087E0840387E0840387E0800080000001000100010006801840000 +D17C:0000000800087E0840387E0840387E08000800000048004800A8011406620000 +D17D:0000000800087E0840387E0840387E0800080000000003F00408040803F00000 +D17E:0000000800087E0840387E0840387E080008000003F80020002000D003080000 +D17F:0000000800087E0840387E0840387E0800080000004003F8004000A003180000 +D180:0000000800087E0840387E0840387E080008000003F8000803F8000800080000 +D181:0000000800087E0840387E0840387E080008000003F8020003F8020003F80000 +D182:0000000800087E0840387E0840387E080008000000000FF8022002200FF80000 +D183:0000000800087E0840387E0840387E080008000000800FF803E0041003E00000 +D184:00000000000A000A3F8A200A203A3F8A200A203A3F8A000A000A000A000A0000 +D185:0000002800287E2840E87E2840E87E280028000007F800080008000800080000 +D186:0000002800287E2840E87E2840E87E280028000000003EF80208020802080000 +D187:0000002800287E2840E87E2840E87E280028000000003E100210022802C40000 +D188:0000002800287E2840E87E2840E87E280028002808000800080008000FF80000 +D189:0000002800287E2840E87E2840E87E2800280000000020F8201020303ECC0000 +D18A:0000002800287E2840E87E2840E87E2800280000202021FC207020883E700000 +D18B:0000002800287E2840E87E2840E87E280028000003F802000200020003F80000 +D18C:0000002800287E2840E87E2840E87E280028000007F8000807F8040007F80000 +D18D:0000002800287E2840E87E2840E87E28002800003EF802083E0820083E080000 +D18E:0000002800287E2840E87E2840E87E28002800003EF802883E8820883EF80000 +D18F:0000002800287E2840E87E2840E87E28002800003E8802883EF820883EF80000 +D190:0000002800287E2840E87E2840E87E28002800001F0801081F0810141F620000 +D191:0000002800287E2840E87E2840E87E28002800003EF802803EF820803EF80000 +D192:0000002800287E2840E87E2840E87E28002800003EFC02483E4820483EFC0000 +D193:0000002800287E2840E87E2840E87E28002800003E1002FE3E3820443E380000 +D194:0000002800287E2840E87E2840E87E280028000003F802080208020803F80000 +D195:0000002800287E2840E87E2840E87E28002800000208020803F8020803F80000 +D196:0000002800287E2840E87E2840E87E2800280000110811081F0811141F620000 +D197:0000002800287E2840E87E2840E87E2800280000000800080008003400C20000 +D198:0000002800287E2840E87E2840E87E28002800000048004800A8011406620000 +D199:0000002800287E2840E87E2840E87E2800280000000001F00208020801F00000 +D19A:0000002800287E2840E87E2840E87E280028000003F80020002000D003080000 +D19B:0000002800287E2840E87E2840E87E2800280000004003F8004000A003180000 +D19C:0000002800287E2840E87E2840E87E280028000003F8000803F8000800080000 +D19D:0000002800287E2840E87E2840E87E280028000003F8020003F8020003F80000 +D19E:0000002800287E2840E87E2840E87E280028000000000FF8022002200FF80000 +D19F:0000002800287E2840E87E2840E87E280028000000800FF803E0041003E00000 +D1A0:00003FF8200020003FF8200020003FF8000000000100010001007FFC00000000 +D1A1:00001FF010001FF010001FF0010001007FFC00001FF000100010001000100000 +D1A2:00001FF010001FF010001FF0010001007FFC000000003EF80208020802080000 +D1A3:00001FF010001FF010001FF0010001007FFC000000001E100210022802C40000 +D1A4:00001FF010001FF010001FF0010001007FFC000000001000100010001FF00000 +D1A5:00001FF010001FF010001FF0010001007FFC0000000020F8201020303ECC0000 +D1A6:00001FF010001FF010001FF0010001007FFC0000202021FC207020883E700000 +D1A7:00001FF010001FF010001FF0010001007FFC00001FF01000100010001FF00000 +D1A8:00001FF010001FF010001FF0010001007FFC00001FF000101FF010001FF00000 +D1A9:00001FF010001FF010001FF0010001007FFC00003EF802083E0820083E080000 +D1AA:00001FF010001FF010001FF0010001007FFC00003EF802883E8820883EF80000 +D1AB:00001FF010001FF010001FF0010001007FFC00003E8802883EF820883EF80000 +D1AC:00001FF010001FF010001FF0010001007FFC00003E1002103E1020283EC40000 +D1AD:00001FF010001FF010001FF0010001007FFC00003EF802803EF820803EF80000 +D1AE:00001FF010001FF010001FF0010001007FFC00003EFC02483E4820483EFC0000 +D1AF:00001FF010001FF010001FF0010001007FFC00003E2003FC3E7020883E700000 +D1B0:00001FF010001FF010001FF0010001007FFC00001FF01010101010101FF00000 +D1B1:00001FF010001FF010001FF0010001007FFC0000101010101FF010101FF00000 +D1B2:00001FF010001FF010001FF0010001007FFC0000222022203E2022503E880000 +D1B3:00001FF010001FF010001FF0010001007FFC000000000100010002800C400000 +D1B4:00001FF010001FF010001FF0010001007FFC00000000024002400DA033100000 +D1B5:00001FF010001FF010001FF0010001007FFC0000000007C00820082007C00000 +D1B6:00001FF010001FF010001FF0010001007FFC0000000007E00080014006200000 +D1B7:00001FF010001FF010001FF0010001007FFC0000008007E00080014006200000 +D1B8:00001FF010001FF010001FF0010001007FFC00001FF000101FF0001000100000 +D1B9:00001FF010001FF010001FF0010001007FFC00001FF010001FF010001FF00000 +D1BA:00001FF010001FF010001FF0010001007FFC000000001FF0044004401FF00000 +D1BB:00001FF010001FF010001FF0010001007FFC000001001FF007C0082007C00000 +D1BC:000000103FD0201020103FD02010201E3FD00010041004107FD0001000100000 +D1BD:000000087F0840087F0E40087F0804087FE8000007F800080008000800080000 +D1BE:000000087F0840087F0E40087F0804087FE8000000003EF80208020802080000 +D1BF:000000087F0840087F0E40087F0804087FE8000000001F080108011401620000 +D1C0:000000087F0840087F0E40087F0804087FE8000008000800080008000FF80000 +D1C1:000000087F0840087F0E40087F0804087FE80000000010F8101010301ECC0000 +D1C2:000000087F0840087F0E40087F0804087FE800000808087F081C08220F9C0000 +D1C3:000000087F0840087F0E40087F0804087FE8000003F802000200020003F80000 +D1C4:000000087F0840087F0E40087F0804087FE8000007F8000807F8040007F80000 +D1C5:000000087F0840087F0E40087F0804087FE800003EF802083E0820083E080000 +D1C6:000000087F0840087F0E40087F0804087FE800003EF802883E8820883EF80000 +D1C7:000000087F0840087F0E40087F0804087FE800003E8802883EF820883EF80000 +D1C8:000000087F0840087F0E40087F0804087FE800001F0801081F0810141F620000 +D1C9:000000087F0840087F0E40087F0804087FE800003EF802803EF820803EF80000 +D1CA:000000087F0840087F0E40087F0804087FE800003EFC02483E4820483EFC0000 +D1CB:000000087F0840087F0E40087F0804087FE800001F08017F1F1C10221F1C0000 +D1CC:000000087F0840087F0E40087F0804087FE8000003F802080208020803F80000 +D1CD:000000087F0840087F0E40087F0804087FE800000208020803F8020803F80000 +D1CE:000000087F0840087F0E40087F0804087FE80000110811081F0811141F620000 +D1CF:000000087F0840087F0E40087F0804087FE80000001000100010006801840000 +D1D0:000000087F0840087F0E40087F0804087FE800000048004800A8011406620000 +D1D1:000000087F0840087F0E40087F0804087FE80000000003F00408040803F00000 +D1D2:000000087F0840087F0E40087F0804087FE8000003F80020002000D003080000 +D1D3:000000087F0840087F0E40087F0804087FE80000004003F8004000A003180000 +D1D4:000000087F0840087F0E40087F0804087FE8000003F8000803F8000800080000 +D1D5:000000087F0840087F0E40087F0804087FE8000003F8020003F8020003F80000 +D1D6:000000087F0840087F0E40087F0804087FE8000000000FF8022002200FF80000 +D1D7:000000087F0840087F0E40087F0804087FE8000000800FF803E0041003E00000 +D1D8:000000123FD2201220123FD22012201E3FD20012041204127FD2001200120000 +D1D9:000000287F2840287F3840287F2804287FA8000007F800080008000800080000 +D1DA:000000287F2840287F3840287F2804287FA8000000003EF80208020802080000 +D1DB:000000287F2840287F3840287F2804287FA8000000001F080108011401620000 +D1DC:000000287F2840287F3840287F2804287FA8000008000800080008000FF80000 +D1DD:000000287F2840287F3840287F2804287FA80000000010F8101010301ECC0000 +D1DE:000000287F2840287F3840287F2804287FA800000808087F081C08220F9C0000 +D1DF:000000287F2840287F3840287F2804287FA8000003F802000200020003F80000 +D1E0:000000287F2840287F3840287F2804287FA8000007F8000807F8040007F80000 +D1E1:000000287F2840287F3840287F2804287FA800003EF802083E0820083E080000 +D1E2:000000287F2840287F3840287F2804287FA800003EF802883E8820883EF80000 +D1E3:000000287F2840287F3840287F2804287FA800003E8802883EF820883EF80000 +D1E4:000000287F2840287F3840287F2804287FA800001F0801081F0810141F620000 +D1E5:000000287F2840287F3840287F2804287FA800003EF802803EF820803EF80000 +D1E6:000000287F2840287F3840287F2804287FA800003EFC02483E4820483EFC0000 +D1E7:000000287F2840287F3840287F2804287FA800001F08017F1F1C10221F1C0000 +D1E8:000000287F2840287F3840287F2804287FA8000003F802080208020803F80000 +D1E9:000000287F2840287F3840287F2804287FA800000208020803F8020803F80000 +D1EA:000000287F2840287F3840287F2804287FA80000110811081F0811141F620000 +D1EB:000000287F2840287F3840287F2804287FA80000001000100010006801840000 +D1EC:000000287F2840287F3840287F2804287FA800000048004800A8011406620000 +D1ED:000000287F2840287F3840287F2804287FA80000000003F00408040803F00000 +D1EE:000000287F2840287F3840287F2804287FA8000003F80020002000D003080000 +D1EF:000000287F2840287F3840287F2804287FA80000004003F8004000A003180000 +D1F0:000000287F2840287F3840287F2804287FA8000003F8000803F8000800080000 +D1F1:000000287F2840287F3840287F2804287FA8000003F8020003F8020003F80000 +D1F2:000000287F2840287F3840287F2804287FA8000000000FF8022002200FF80000 +D1F3:000000287F2840287F3840287F2804287FA8000000800FF803E0041003E00000 +D1F4:000000083FC8200820083FC8200820083FC80008040804087FE8000800080000 +D1F5:000000087F0840087F0840087F0804087FE8000007F800080008000800080000 +D1F6:000000087F0840087F0840087F0804087FE8000000003EF80208020802080000 +D1F7:000000087F0840087F0840087F0804087FE8000000001F080108011401620000 +D1F8:000000087F0840087F0840087F0804087FE8000008000800080008000FF80000 +D1F9:000000087F0840087F0840087F0804087FE80000000010F8101010301ECC0000 +D1FA:000000087F0840087F0840087F0804087FE800000808087F081C08220F9C0000 +D1FB:000000087F0840087F0840087F0804087FE8000003F802000200020003F80000 +D1FC:000000087F0840087F0840087F0804087FE8000007F8000807F8040007F80000 +D1FD:000000087F0840087F0840087F0804087FE800003EF802083E0820083E080000 +D1FE:000000087F0840087F0840087F0804087FE800003EF802883E8820883EF80000 +D1FF:000000087F0840087F0840087F0804087FE800003E8802883EF820883EF80000 +D200:000000087F0840087F0840087F0804087FE800001F0801081F0810141F620000 +D201:000000087F0840087F0840087F0804087FE800003EF802803EF820803EF80000 +D202:000000087F0840087F0840087F0804087FE800003EFC02483E4820483EFC0000 +D203:000000087F0840087F0840087F0804087FE800001F08017F1F1C10221F1C0000 +D204:000000087F0840087F0840087F0804087FE8000003F802080208020803F80000 +D205:000000087F0840087F0840087F0804087FE800000208020803F8020803F80000 +D206:000000087F0840087F0840087F0804087FE80000110811081F0811141F620000 +D207:000000087F0840087F0840087F0804087FE80000001000100010006801840000 +D208:000000087F0840087F0840087F0804087FE800000048004800A8011406620000 +D209:000000087F0840087F0840087F0804087FE80000000003F00408040803F00000 +D20A:000000087F0840087F0840087F0804087FE8000003F80020002000D003080000 +D20B:000000087F0840087F0840087F0804087FE80000004003F8004000A003180000 +D20C:000000087F0840087F0840087F0804087FE8000003F8000803F8000800080000 +D20D:000000087F0840087F0840087F0804087FE8000003F8020003F8020003F80000 +D20E:000000087F0840087F0840087F0804087FE8000000000FF8022002200FF80000 +D20F:000000087F0840087F0840087F0804087FE8000000800FF803E0041003E00000 +D210:00003FF8200020003FF8200020003FF8000004400440044004407FFC00000000 +D211:00001FF010001FF010001FF0044004407FFC00001FF000100010001000100000 +D212:00001FF010001FF010001FF0044004407FFC000000003EF80208020802080000 +D213:00001FF010001FF010001FF0044004407FFC000000001E100210022802C40000 +D214:00001FF010001FF010001FF0044004407FFC000000001000100010001FF00000 +D215:00001FF010001FF010001FF0044004407FFC0000000020F8201020303ECC0000 +D216:00001FF010001FF010001FF0044004407FFC0000202021FC207020883E700000 +D217:00001FF010001FF010001FF0044004407FFC00001FF01000100010001FF00000 +D218:00001FF010001FF010001FF0044004407FFC00001FF000101FF010001FF00000 +D219:00001FF010001FF010001FF0044004407FFC00003EF802083E0820083E080000 +D21A:00001FF010001FF010001FF0044004407FFC00003EF802883E8820883EF80000 +D21B:00001FF010001FF010001FF0044004407FFC00003E8802883EF820883EF80000 +D21C:00001FF010001FF010001FF0044004407FFC00003E1002103E1020283EC40000 +D21D:00001FF010001FF010001FF0044004407FFC00003EF802803EF820803EF80000 +D21E:00001FF010001FF010001FF0044004407FFC00003EFC02483E4820483EFC0000 +D21F:00001FF010001FF010001FF0044004407FFC00003E2003FC3E7020883E700000 +D220:00001FF010001FF010001FF0044004407FFC00001FF01010101010101FF00000 +D221:00001FF010001FF010001FF0044004407FFC0000101010101FF010101FF00000 +D222:00001FF010001FF010001FF0044004407FFC0000222022203E2022503E880000 +D223:00001FF010001FF010001FF0044004407FFC000000000100010002800C400000 +D224:00001FF010001FF010001FF0044004407FFC00000000024002400DA033100000 +D225:00001FF010001FF010001FF0044004407FFC0000000007C00820082007C00000 +D226:00001FF010001FF010001FF0044004407FFC0000000007E00080014006200000 +D227:00001FF010001FF010001FF0044004407FFC0000008007E00080014006200000 +D228:00001FF010001FF010001FF0044004407FFC00001FF000101FF0001000100000 +D229:00001FF010001FF010001FF0044004407FFC00001FF010001FF010001FF00000 +D22A:00001FF010001FF010001FF0044004407FFC000000001FF0044004401FF00000 +D22B:00001FF010001FF010001FF0044004407FFC000001001FF007C0082007C00000 +D22C:000000003FF8200020003FF8200020003FF800003FF801000100010001000000 +D22D:00001FF010001FF010001FF000007FFC010001001FF000100010001000100000 +D22E:00001FF010001FF010001FF000007FFC0100010000003EF80208020802080000 +D22F:00001FF010001FF010001FF000007FFC0100010000001E100210022802C40000 +D230:00001FF010001FF010001FF0000000007FFC010001001100100010001FF00000 +D231:00001FF010001FF010001FF000007FFC01000100000020F8201020303ECC0000 +D232:00001FF010001FF010001FF000007FFC01000100202021FC207020883E700000 +D233:00001FF010001FF010001FF000007FFC010001001FF01000100010001FF00000 +D234:00001FF010001FF010001FF000007FFC010001001FF000101FF010001FF00000 +D235:00001FF010001FF010001FF000007FFC010001003EF802083E0820083E080000 +D236:00001FF010001FF010001FF000007FFC010001003EF802883E8820883EF80000 +D237:00001FF010001FF010001FF000007FFC010001003E8802883EF820883EF80000 +D238:00001FF010001FF010001FF000007FFC010001003E1002103E1020283EC40000 +D239:00001FF010001FF010001FF000007FFC010001003EF802803EF820803EF80000 +D23A:00001FF010001FF010001FF000007FFC010001003EFC02483E4820483EFC0000 +D23B:00001FF010001FF010001FF000007FFC010001003E2003FC3E7020883E700000 +D23C:00001FF010001FF010001FF000007FFC010001001FF01010101010101FF00000 +D23D:00001FF010001FF010001FF000007FFC01000100101010101FF010101FF00000 +D23E:00001FF010001FF010001FF000007FFC01000100222022203E2022503E880000 +D23F:00001FF010001FF010001FF000007FFC0100010000000100010002800C400000 +D240:00001FF010001FF010001FF000007FFC010001000000024002400DA033100000 +D241:00001FF010001FF010001FF000007FFC01000100000007C00820082007C00000 +D242:00001FF010001FF010001FF000007FFC01000100000007E00080014006200000 +D243:00001FF010001FF010001FF000007FFC01000100008007E00080014006200000 +D244:00001FF010001FF010001FF000007FFC010001001FF000101FF0001000100000 +D245:00001FF010001FF010001FF000007FFC010001001FF010001FF010001FF00000 +D246:00001FF010001FF010001FF000007FFC0100010000001FF0044004401FF00000 +D247:00001FF010001FF010001FF000007FFC0100010001001FF007C0082007C00000 +D248:000000083FC8200820083FC8200820083FC800087FE8040804F8040804080000 +D249:7F8840087F8840087F8800087FE8027802080000000007F80008000800080000 +D24A:7F8840087F8840087F8800087FE802780208000000003EF80208020802080000 +D24B:7F8840087F8840087F8800087FE802780208000000001F080108011401620000 +D24C:7F8840087F8840087F88000800087FE80278020802081000100010001FF80000 +D24D:7F8840087F8840087F8800087FE8027802080000000020F8201020303ECC0000 +D24E:7F8840087F8840087F8800087FE8027802080000202021FC207020883E700000 +D24F:7F8840087F8840087F8800087FE802780208000003F802000200020003F80000 +D250:7F8840087F8840087F8800087FE802780208000007F8000807F8040007F80000 +D251:7F8840087F8840087F8800087FE80278020800003EF802083E0820083E080000 +D252:7F8840087F8840087F8800087FE80278020800003EF802883E8820883EF80000 +D253:7F8840087F8840087F8800087FE80278020800003E8802883EF820883EF80000 +D254:7F8840087F8840087F8800087FE80278020800000F8800880F8808140FA20000 +D255:7F8840087F8840087F8800087FE80278020800003EF802803EF820803EF80000 +D256:7F8840087F8840087F8800087FE80278020800003EFC02483E4820483EFC0000 +D257:7F8840087F8840087F8800087FE80278020800003E1002FE3E3820443E380000 +D258:7F8840087F8840087F8800087FE802780208000003F802080208020803F80000 +D259:7F8840087F8840087F8800087FE80278020800000208020803F8020803F80000 +D25A:7F8840087F8840087F8800087FE8027802080000210821083F0821143F620000 +D25B:7F8840087F8840087F8800087FE8027802080000001000100010006801840000 +D25C:7F8840087F8840087F8800087FE80278020800000048004800A8011406620000 +D25D:7F8840087F8840087F8800087FE8027802080000000003F00408040803F00000 +D25E:7F8840087F8840087F8800087FE802780208000003F80020002000D003080000 +D25F:7F8840087F8840087F8800087FE8027802080000004003F8004000A003180000 +D260:7F8840087F8840087F8800087FE802780208000003F8000803F8000800080000 +D261:7F8840087F8840087F8800087FE802780208000003F8020003F8020003F80000 +D262:7F8840087F8840087F8800087FE802780208000000000FF8022002200FF80000 +D263:7F8840087F8840087F8800087FE802780208000000800FF803E0041003E00000 +D264:0000000A3FCA200A200A3FCA200A200A3FCA000A7FEA040A047A040A040A0000 +D265:7FA840287FA840287FA800287FA805E804280000000007F80008000800080000 +D266:7FA840287FA840287FA800287FA805E80428000000003EF80208020802080000 +D267:7FA840287FA840287FA800287FA805E80428000000001F080108011401620000 +D268:7FA840287FA840287FA8002800287FA8042805E804281428100010001FF80000 +D269:7FA840287FA840287FA800287FA805E804280000000020F8201020303ECC0000 +D26A:7FA840287FA840287FA800287FA805E804280000202021FC207020883E700000 +D26B:7FA840287FA840287FA800287FA805E80428000003F802000200020003F80000 +D26C:7FA840287FA840287FA800287FA805E80428000007F8000807F8040007F80000 +D26D:7FA840287FA840287FA800287FA805E8042800003EF802083E0820083E080000 +D26E:7FA840287FA840287FA800287FA805E8042800003EF802883E8820883EF80000 +D26F:7FA840287FA840287FA800287FA805E8042800003E8802883EF820883EF80000 +D270:7FA840287FA840287FA800287FA805E8042800000F8800880F8808140FA20000 +D271:7FA840287FA840287FA800287FA805E8042800003EF802803EF820803EF80000 +D272:7FA840287FA840287FA800287FA805E8042800003EFC02483E4820483EFC0000 +D273:7FA840287FA840287FA800287FA805E8042800003E1002FE3E3820443E380000 +D274:7FA840287FA840287FA800287FA805E80428000003F802080208020803F80000 +D275:7FA840287FA840287FA800287FA805E8042800000208020803F8020803F80000 +D276:7FA840287FA840287FA800287FA805E804280000210821083F0821143F620000 +D277:7FA840287FA840287FA800287FA805E804280000001000100010006801840000 +D278:7FA840287FA840287FA800287FA805E8042800000048004800A8011406620000 +D279:7FA840287FA840287FA800287FA805E804280000000003F00408040803F00000 +D27A:7FA840287FA840287FA800287FA805E80428000003F80020002000D003080000 +D27B:7FA840287FA840287FA800287FA805E804280000004003F8004000A003180000 +D27C:7FA840287FA840287FA800287FA805E80428000003F8000803F8000800080000 +D27D:7FA840287FA840287FA800287FA805E80428000003F8020003F8020003F80000 +D27E:7FA840287FA840287FA800287FA805E80428000000000FF8022002200FF80000 +D27F:7FA840287FA840287FA800287FA805E80428000000800FF803E0041003E00000 +D280:000000083FC8200820083FC8200820083FC800087FE804080408040804080000 +D281:7F8840087F8840087F8800087FE8020802000000000007F80008000800080000 +D282:7F8840087F8840087F8800087FE802080200000000003EF80208020802080000 +D283:7F8840087F8840087F8800087FE802080200000000001F080108011401620000 +D284:7F8840087F8840087F88000800087FE80208020802081008100010001FF80000 +D285:7F8840087F8840087F8800087FE8020802000000000020F8201020303ECC0000 +D286:7F8840087F8840087F8800087FE8020802000000202021FC207020883E700000 +D287:7F8840087F8840087F8800087FE802080200000003F802000200020003F80000 +D288:7F8840087F8840087F8800087FE802080200000007F8000807F8040007F80000 +D289:7F8840087F8840087F8800087FE80208020000003EF802083E0820083E080000 +D28A:7F8840087F8840087F8800087FE80208020000003EF802883E8820883EF80000 +D28B:7F8840087F8840087F8800087FE80208020000003E8802883EF820883EF80000 +D28C:7F8840087F8840087F8800087FE80208020000000F8800880F8808140FA20000 +D28D:7F8840087F8840087F8800087FE80208020000003EF802803EF820803EF80000 +D28E:7F8840087F8840087F8800087FE80208020000003EFC02483E4820483EFC0000 +D28F:7F8840087F8840087F8800087FE80208020000003E1002FE3E3820443E380000 +D290:7F8840087F8840087F8800087FE802080200000003F802080208020803F80000 +D291:7F8840087F8840087F8800087FE80208020000000208020803F8020803F80000 +D292:7F8840087F8840087F8800087FE8020802000000210821083F0821143F620000 +D293:7F8840087F8840087F8800087FE8020802000000001000100010006801840000 +D294:7F8840087F8840087F8800087FE80208020000000048004800A8011406620000 +D295:7F8840087F8840087F8800087FE8020802000000000003F00408040803F00000 +D296:7F8840087F8840087F8800087FE802080200000003F80020002000D003080000 +D297:7F8840087F8840087F8800087FE8020802000000004003F8004000A003180000 +D298:7F8840087F8840087F8800087FE802080200000003F8000803F8000800080000 +D299:7F8840087F8840087F8800087FE802080200000003F8020003F8020003F80000 +D29A:7F8840087F8840087F8800087FE802080200000000000FF8022002200FF80000 +D29B:7F8840087F8840087F8800087FE802080200000000800FF803E0041003E00000 +D29C:000000003FF8200020003FF8200020003FF800007FFC04400440044004400000 +D29D:00001FF010001FF010001FF000007FFC044004401FF000100010001000100000 +D29E:00001FF010001FF010001FF000007FFC0440044000003EF80208020802080000 +D29F:00001FF010001FF010001FF000007FFC0440044000001E100210022802C40000 +D2A0:00001FF010001FF010001FF0000000007FFC044004401440100010001FF00000 +D2A1:00001FF010001FF010001FF000007FFC04400440000020F8201020303ECC0000 +D2A2:00001FF010001FF010001FF000007FFC04400440202021FC207020883E700000 +D2A3:00001FF010001FF010001FF000007FFC044004401FF01000100010001FF00000 +D2A4:00001FF010001FF010001FF000007FFC044004401FF000101FF010001FF00000 +D2A5:00001FF010001FF010001FF000007FFC044004403EF802083E0820083E080000 +D2A6:00001FF010001FF010001FF000007FFC044004403EF802883E8820883EF80000 +D2A7:00001FF010001FF010001FF000007FFC044004403E8802883EF820883EF80000 +D2A8:00001FF010001FF010001FF000007FFC044004403E1002103E1020283EC40000 +D2A9:00001FF010001FF010001FF000007FFC044004403EF802803EF820803EF80000 +D2AA:00001FF010001FF010001FF000007FFC044004403EFC02483E4820483EFC0000 +D2AB:00001FF010001FF010001FF000007FFC044004403E2003FC3E7020883E700000 +D2AC:00001FF010001FF010001FF000007FFC044004401FF01010101010101FF00000 +D2AD:00001FF010001FF010001FF000007FFC04400440101010101FF010101FF00000 +D2AE:00001FF010001FF010001FF000007FFC04400440222022203E2022503E880000 +D2AF:00001FF010001FF010001FF000007FFC0440044000000100010002800C400000 +D2B0:00001FF010001FF010001FF000007FFC044004400000024002400DA033100000 +D2B1:00001FF010001FF010001FF000007FFC04400440000007C00820082007C00000 +D2B2:00001FF010001FF010001FF000007FFC04400440000007E00080014006200000 +D2B3:00001FF010001FF010001FF000007FFC04400440008007E00080014006200000 +D2B4:00001FF010001FF010001FF000007FFC044004401FF000101FF0001000100000 +D2B5:00001FF010001FF010001FF000007FFC044004401FF010001FF010001FF00000 +D2B6:00001FF010001FF010001FF000007FFC0440044000001FF0044004401FF00000 +D2B7:00001FF010001FF010001FF000007FFC0440044001001FF007C0082007C00000 +D2B8:00003FF8200020003FF8200020003FF80000000000007FFC0000000000000000 +D2B9:00001FF010001FF010001FF0000000007FFC00001FF000100010001000100000 +D2BA:00001FF010001FF010001FF0000000007FFC000000003EF80208020802080000 +D2BB:00001FF010001FF010001FF0000000007FFC000000001E100210022802C40000 +D2BC:00001FF010001FF010001FF0000000007FFC000000001000100010001FF00000 +D2BD:00001FF010001FF010001FF0000000007FFC0000000020F8201020303ECC0000 +D2BE:00001FF010001FF010001FF0000000007FFC0000202021FC207020883E700000 +D2BF:00001FF010001FF010001FF0000000007FFC00001FF01000100010001FF00000 +D2C0:00001FF010001FF010001FF0000000007FFC00001FF000101FF010001FF00000 +D2C1:00001FF010001FF010001FF0000000007FFC00003EF802083E0820083E080000 +D2C2:00001FF010001FF010001FF0000000007FFC00003EF802883E8820883EF80000 +D2C3:00001FF010001FF010001FF0000000007FFC00003E8802883EF820883EF80000 +D2C4:00001FF010001FF010001FF0000000007FFC00003E1002103E1020283EC40000 +D2C5:00001FF010001FF010001FF0000000007FFC00003EF802803EF820803EF80000 +D2C6:00001FF010001FF010001FF0000000007FFC00003EFC02483E4820483EFC0000 +D2C7:00001FF010001FF010001FF0000000007FFC00003E2003FC3E7020883E700000 +D2C8:00001FF010001FF010001FF0000000007FFC00001FF01010101010101FF00000 +D2C9:00001FF010001FF010001FF0000000007FFC0000101010101FF010101FF00000 +D2CA:00001FF010001FF010001FF0000000007FFC0000222022203E2022503E880000 +D2CB:00001FF010001FF010001FF0000000007FFC000000000100010002800C400000 +D2CC:00001FF010001FF010001FF0000000007FFC00000000024002400DA033100000 +D2CD:00001FF010001FF010001FF0000000007FFC0000000007C00820082007C00000 +D2CE:00001FF010001FF010001FF0000000007FFC0000000007E00080014006200000 +D2CF:00001FF010001FF010001FF0000000007FFC0000008007E00080014006200000 +D2D0:00001FF010001FF010001FF0000000007FFC00001FF000101FF0001000100000 +D2D1:00001FF010001FF010001FF0000000007FFC00001FF010001FF010001FF00000 +D2D2:00001FF010001FF010001FF0000000007FFC000000001FF0044004401FF00000 +D2D3:00001FF010001FF010001FF0000000007FFC000001001FF007C0082007C00000 +D2D4:000000083FC8200820083FC8200820083FC8000800087FE80008000800080000 +D2D5:000000087F0840087F0840087F0800087FE8000007F800080008000800080000 +D2D6:000000087F0840087F0840087F0800087FE8000000003EF80208020802080000 +D2D7:000000087F0840087F0840087F0800087FE8000000001F080108011401620000 +D2D8:000000087F0840087F0840087F0800087FE8000008000800080008000FF80000 +D2D9:000000087F0840087F0840087F0800087FE80000000010F8101010301ECC0000 +D2DA:000000087F0840087F0840087F0800087FE800000808087F081C08220F9C0000 +D2DB:000000087F0840087F0840087F0800087FE8000003F802000200020003F80000 +D2DC:000000087F0840087F0840087F0800087FE8000007F8000807F8040007F80000 +D2DD:000000087F0840087F0840087F0800087FE800003EF802083E0820083E080000 +D2DE:000000087F0840087F0840087F0800087FE800003EF802883E8820883EF80000 +D2DF:000000087F0840087F0840087F0800087FE800003E8802883EF820883EF80000 +D2E0:000000087F0840087F0840087F0800087FE800001F0801081F0810141F620000 +D2E1:000000087F0840087F0840087F0800087FE800003EF802803EF820803EF80000 +D2E2:000000087F0840087F0840087F0800087FE800003EFC02483E4820483EFC0000 +D2E3:000000087F0840087F0840087F0800087FE800001F08017F1F1C10221F1C0000 +D2E4:000000087F0840087F0840087F0800087FE8000003F802080208020803F80000 +D2E5:000000087F0840087F0840087F0800087FE800000208020803F8020803F80000 +D2E6:000000087F0840087F0840087F0800087FE80000110811081F0811141F620000 +D2E7:000000087F0840087F0840087F0800087FE80000001000100010006801840000 +D2E8:000000087F0840087F0840087F0800087FE800000048004800A8011406620000 +D2E9:000000087F0840087F0840087F0800087FE80000000003F00408040803F00000 +D2EA:000000087F0840087F0840087F0800087FE8000003F80020002000D003080000 +D2EB:000000087F0840087F0840087F0800087FE80000004003F8004000A003180000 +D2EC:000000087F0840087F0840087F0800087FE8000003F8000803F8000800080000 +D2ED:000000087F0840087F0840087F0800087FE8000003F8020003F8020003F80000 +D2EE:000000087F0840087F0840087F0800087FE8000000000FF8022002200FF80000 +D2EF:000000087F0840087F0840087F0800087FE8000000800FF803E0041003E00000 +D2F0:00000000000800083F88200820083F88200820083F8800080008000800080000 +D2F1:0000000800087E0840087E0840087E0800080000000007F80008000800080000 +D2F2:0000000800087E0840087E0840087E080008000000003EF80208020802080000 +D2F3:0000000800087E0840087E0840087E080008000000001F080108011401620000 +D2F4:0000000800087E0840087E0840087E080008000800001000100010001FF80000 +D2F5:0000000800087E0840087E0840087E0800080000000020F8201020303ECC0000 +D2F6:0000000800087E0840087E0840087E0800080000202021FC207020883E700000 +D2F7:0000000800087E0840087E0840087E080008000003F802000200020003F80000 +D2F8:0000000800087E0840087E0840087E080008000007F8000807F8040007F80000 +D2F9:0000000800087E0840087E0840087E08000800003EF802083E0820083E080000 +D2FA:0000000800087E0840087E0840087E08000800003EF802883E8820883EF80000 +D2FB:0000000800087E0840087E0840087E08000800003E8802883EF820883EF80000 +D2FC:0000000800087E0840087E0840087E08000800000F8800880F8808140FA20000 +D2FD:0000000800087E0840087E0840087E08000800003EF802803EF820803EF80000 +D2FE:0000000800087E0840087E0840087E08000800003EFC02483E4820483EFC0000 +D2FF:0000000800087E0840087E0840087E08000800003E1002FE3E3820443E380000 +D300:0000000800087E0840087E0840087E080008000003F802080208020803F80000 +D301:0000000800087E0840087E0840087E08000800000208020803F8020803F80000 +D302:0000000800087E0840087E0840087E0800080000210821083F0821143F620000 +D303:0000000800087E0840087E0840087E0800080000001000100010006801840000 +D304:0000000800087E0840087E0840087E08000800000048004800A8011406620000 +D305:0000000800087E0840087E0840087E0800080000000003F00408040803F00000 +D306:0000000800087E0840087E0840087E080008000003F80020002000D003080000 +D307:0000000800087E0840087E0840087E0800080000004003F8004000A003180000 +D308:0000000800087E0840087E0840087E080008000003F8000803F8000800080000 +D309:0000000800087E0840087E0840087E080008000003F8020003F8020003F80000 +D30A:0000000800087E0840087E0840087E080008000000000FF8022002200FF80000 +D30B:0000000800087E0840087E0840087E080008000000800FF803E0041003E00000 +D30C:00000000001000107FD011101110111E111011107FD000100010001000100000 +D30D:0000000800087F881208120E12087F880008000007F800080008000800080000 +D30E:0000000800087F881208120E12087F880008000000003EF80208020802080000 +D30F:0000000800087F881208120E12087F880008000000001F080108011401620000 +D310:0000000800087F881208120E12087F880008000808000800080008000FF80000 +D311:0000000800087F881208120E12087F8800080000000010F8101010301ECC0000 +D312:0000000800087F881208120E12087F88000800000808087F081C08220F9C0000 +D313:0000000800087F881208120E12087F880008000003F802000200020003F80000 +D314:0000000800087F881208120E12087F880008000007F8000807F8040007F80000 +D315:0000000800087F881208120E12087F88000800003EF802083E0820083E080000 +D316:0000000800087F881208120E12087F88000800003EF802883E8820883EF80000 +D317:0000000800087F881208120E12087F88000800003E8802883EF820883EF80000 +D318:0000000800087F881208120E12087F88000800001F0801081F0810141F620000 +D319:0000000800087F881208120E12087F88000800003EF802803EF820803EF80000 +D31A:0000000800087F881208120E12087F88000800003EFC02483E4820483EFC0000 +D31B:0000000800087F881208120E12087F88000800001F08017F1F1C10221F1C0000 +D31C:0000000800087F881208120E12087F880008000003F802080208020803F80000 +D31D:0000000800087F881208120E12087F88000800000208020803F8020803F80000 +D31E:0000000800087F881208120E12087F8800080000110811081F0811141F620000 +D31F:0000000800087F881208120E12087F8800080000001000100010006801840000 +D320:0000000800087F881208120E12087F88000800000048004800A8011406620000 +D321:0000000800087F881208120E12087F8800080000000003F00408040803F00000 +D322:0000000800087F881208120E12087F880008000003F80020002000D003080000 +D323:0000000800087F881208120E12087F8800080000004003F8004000A003180000 +D324:0000000800087F881208120E12087F880008000003F8000803F8000800080000 +D325:0000000800087F881208120E12087F880008000003F8020003F8020003F80000 +D326:0000000800087F881208120E12087F880008000000000FF8022002200FF80000 +D327:0000000800087F881208120E12087F880008000000800FF803E0041003E00000 +D328:00000000001200127FD211121112111E111211127FD200120012001200120000 +D329:0000002800287FA81228123812287FA80028000007F800080008000800080000 +D32A:0000002800287FA81228123812287FA80028000000003EF80208020802080000 +D32B:0000002800287FA81228123812287FA80028000000003E100210022802C40000 +D32C:0000002800287FA81228123812287FA80028002808000800080008000FF80000 +D32D:0000002800287FA81228123812287FA800280000000020F8201020303ECC0000 +D32E:0000002800287FA81228123812287FA800280000202021FC207020883E700000 +D32F:0000002800287FA81228123812287FA80028000003F802000200020003F80000 +D330:0000002800287FA81228123812287FA80028000007F8000807F8040007F80000 +D331:0000002800287FA81228123812287FA8002800003EF802083E0820083E080000 +D332:0000002800287FA81228123812287FA8002800003EF802883E8820883EF80000 +D333:0000002800287FA81228123812287FA8002800003E8802883EF820883EF80000 +D334:0000002800287FA81228123812287FA8002800001F0801081F0810141F620000 +D335:0000002800287FA81228123812287FA8002800003EF802803EF820803EF80000 +D336:0000002800287FA81228123812287FA8002800003EFC02483E4820483EFC0000 +D337:0000002800287FA81228123812287FA8002800003E1002FE3E3820443E380000 +D338:0000002800287FA81228123812287FA80028000003F802080208020803F80000 +D339:0000002800287FA81228123812287FA8002800000208020803F8020803F80000 +D33A:0000002800287FA81228123812287FA800280000110811081F0811141F620000 +D33B:0000002800287FA81228123812287FA800280000000800080008003400C20000 +D33C:0000002800287FA81228123812287FA8002800000048004800A8011406620000 +D33D:0000002800287FA81228123812287FA800280000000001F00208020801F00000 +D33E:0000002800287FA81228123812287FA80028000003F80020002000D003080000 +D33F:0000002800287FA81228123812287FA800280000004003F8004000A003180000 +D340:0000002800287FA81228123812287FA80028000003F8000803F8000800080000 +D341:0000002800287FA81228123812287FA80028000003F8020003F8020003F80000 +D342:0000002800287FA81228123812287FA80028000000000FF8022002200FF80000 +D343:0000002800287FA81228123812287FA80028000000800FF803E0041003E00000 +D344:00000000001000107FD01110111E11101110111E7FD000100010001000100000 +D345:0000000800087F88120E1208120E7F880008000007F800080008000800080000 +D346:0000000800087F88120E1208120E7F880008000000003EF80208020802080000 +D347:0000000800087F88120E1208120E7F880008000000001F080108011401620000 +D348:0000000800087F88120E1208120E7F880008000008000800080008000FF80000 +D349:0000000800087F88120E1208120E7F8800080000000010F8101010301ECC0000 +D34A:0000000800087F88120E1208120E7F88000800000808087F081C08220F9C0000 +D34B:0000000800087F88120E1208120E7F880008000003F802000200020003F80000 +D34C:0000000800087F88120E1208120E7F880008000007F8000807F8040007F80000 +D34D:0000000800087F88120E1208120E7F88000800003EF802083E0820083E080000 +D34E:0000000800087F88120E1208120E7F88000800003EF802883E8820883EF80000 +D34F:0000000800087F88120E1208120E7F88000800003E8802883EF820883EF80000 +D350:0000000800087F88120E1208120E7F88000800001F0801081F0810141F620000 +D351:0000000800087F88120E1208120E7F88000800003EF802803EF820803EF80000 +D352:0000000800087F88120E1208120E7F88000800003EFC02483E4820483EFC0000 +D353:0000000800087F88120E1208120E7F88000800001F08017F1F1C10221F1C0000 +D354:0000000800087F88120E1208120E7F880008000003F802080208020803F80000 +D355:0000000800087F88120E1208120E7F88000800000208020803F8020803F80000 +D356:0000000800087F88120E1208120E7F8800080000110811081F0811141F620000 +D357:0000000800087F88120E1208120E7F8800080000001000100010006801840000 +D358:0000000800087F88120E1208120E7F88000800000048004800A8011406620000 +D359:0000000800087F88120E1208120E7F8800080000000003F00408040803F00000 +D35A:0000000800087F88120E1208120E7F880008000003F80020002000D003080000 +D35B:0000000800087F88120E1208120E7F8800080000004003F8004000A003180000 +D35C:0000000800087F88120E1208120E7F880008000003F8000803F8000800080000 +D35D:0000000800087F88120E1208120E7F880008000003F8020003F8020003F80000 +D35E:0000000800087F88120E1208120E7F880008000000000FF8022002200FF80000 +D35F:0000000800087F88120E1208120E7F880008000000800FF803E0041003E00000 +D360:00000000001200127FD21112111E11121112111E7FD200120012001200120000 +D361:0000002800287FA81238122812387FA80028000007F800080008000800080000 +D362:0000002800287FA81238122812387FA80028000000003EF80208020802080000 +D363:0000002800287FA81238122812387FA80028000000003E100210022802C40000 +D364:0000002800287FA81238122812387FA80028002808000800080008000FF80000 +D365:0000002800287FA81238122812387FA800280000000020F8201020303ECC0000 +D366:0000002800287FA81238122812387FA800280000202021FC207020883E700000 +D367:0000002800287FA81238122812387FA80028000003F802000200020003F80000 +D368:0000002800287FA81238122812387FA80028000007F8000807F8040007F80000 +D369:0000002800287FA81238122812387FA8002800003EF802083E0820083E080000 +D36A:0000002800287FA81238122812387FA8002800003EF802883E8820883EF80000 +D36B:0000002800287FA81238122812387FA8002800003E8802883EF820883EF80000 +D36C:0000002800287FA81238122812387FA8002800001F0801081F0810141F620000 +D36D:0000002800287FA81238122812387FA8002800003EF802803EF820803EF80000 +D36E:0000002800287FA81238122812387FA8002800003EFC02483E4820483EFC0000 +D36F:0000002800287FA81238122812387FA8002800003E1002FE3E3820443E380000 +D370:0000002800287FA81238122812387FA80028000003F802080208020803F80000 +D371:0000002800287FA81238122812387FA8002800000208020803F8020803F80000 +D372:0000002800287FA81238122812387FA800280000110811081F0811141F620000 +D373:0000002800287FA81238122812387FA800280000000800080008003400C20000 +D374:0000002800287FA81238122812387FA8002800000048004800A8011406620000 +D375:0000002800287FA81238122812387FA800280000000001F00208020801F00000 +D376:0000002800287FA81238122812387FA80028000003F80020002000D003080000 +D377:0000002800287FA81238122812387FA800280000004003F8004000A003180000 +D378:0000002800287FA81238122812387FA80028000003F8000803F8000800080000 +D379:0000002800287FA81238122812387FA80028000003F8020003F8020003F80000 +D37A:0000002800287FA81238122812387FA80028000000000FF8022002200FF80000 +D37B:0000002800287FA81238122812387FA80028000000800FF803E0041003E00000 +D37C:00000000000200027FC211021102111E110211027FC200020002000200020000 +D37D:0000000800087F881208123812087F8800080000000007F80008000800080000 +D37E:0000000800087F881208123812087F880008000000003EF80208020802080000 +D37F:0000000800087F881208123812087F880008000000001F080108011401620000 +D380:0000000800087F881208123812087F880008000000001000100010001FF80000 +D381:0000000800087F881208123812087F8800080000000020F8201020303ECC0000 +D382:0000000800087F881208123812087F8800080000202021FC207020883E700000 +D383:0000000800087F881208123812087F880008000003F802000200020003F80000 +D384:0000000800087F881208123812087F880008000007F8000807F8040007F80000 +D385:0000000800087F881208123812087F88000800003EF802083E0820083E080000 +D386:0000000800087F881208123812087F88000800003EF802883E8820883EF80000 +D387:0000000800087F881208123812087F88000800003E8802883EF820883EF80000 +D388:0000000800087F881208123812087F88000800000F8800880F8808140FA20000 +D389:0000000800087F881208123812087F88000800003EF802803EF820803EF80000 +D38A:0000000800087F881208123812087F88000800003EFC02483E4820483EFC0000 +D38B:0000000800087F881208123812087F88000800003E1002FE3E3820443E380000 +D38C:0000000800087F881208123812087F880008000003F802080208020803F80000 +D38D:0000000800087F881208123812087F88000800000208020803F8020803F80000 +D38E:0000000800087F881208123812087F8800080000210821083F0821143F620000 +D38F:0000000800087F881208123812087F8800080000001000100010006801840000 +D390:0000000800087F881208123812087F88000800000048004800A8011406620000 +D391:0000000800087F881208123812087F8800080000000003F00408040803F00000 +D392:0000000800087F881208123812087F880008000003F80020002000D003080000 +D393:0000000800087F881208123812087F8800080000004003F8004000A003180000 +D394:0000000800087F881208123812087F880008000003F8000803F8000800080000 +D395:0000000800087F881208123812087F880008000003F8020003F8020003F80000 +D396:0000000800087F881208123812087F880008000000000FF8022002200FF80000 +D397:0000000800087F881208123812087F880008000000800FF803E0041003E00000 +D398:00000000000A000A7FCA110A110A113A110A110A7FCA000A000A000A000A0000 +D399:0000002800287FA8122812E812287FA80028000007F800080008000800080000 +D39A:0000002800287FA8122812E812287FA80028000000003EF80208020802080000 +D39B:0000002800287FA8122812E812287FA80028000000003E100210022802C40000 +D39C:0000002800287FA8122812E812287FA80028000008000800080008000FF80000 +D39D:0000002800287FA8122812E812287FA800280000000020F8201020303ECC0000 +D39E:0000002800287FA8122812E812287FA800280000202021FC207020883E700000 +D39F:0000002800287FA8122812E812287FA80028000003F802000200020003F80000 +D3A0:0000002800287FA8122812E812287FA80028000007F8000807F8040007F80000 +D3A1:0000002800287FA8122812E812287FA8002800003EF802083E0820083E080000 +D3A2:0000002800287FA8122812E812287FA8002800003EF802883E8820883EF80000 +D3A3:0000002800287FA8122812E812287FA8002800003E8802883EF820883EF80000 +D3A4:0000002800287FA8122812E812287FA8002800001F0801081F0810141F620000 +D3A5:0000002800287FA8122812E812287FA8002800003EF802803EF820803EF80000 +D3A6:0000002800287FA8122812E812287FA8002800003EFC02483E4820483EFC0000 +D3A7:0000002800287FA8122812E812287FA8002800003E1002FE3E3820443E380000 +D3A8:0000002800287FA8122812E812287FA80028000003F802080208020803F80000 +D3A9:0000002800287FA8122812E812287FA8002800000208020803F8020803F80000 +D3AA:0000002800287FA8122812E812287FA800280000110811081F0811141F620000 +D3AB:0000002800287FA8122812E812287FA800280000000800080008003400C20000 +D3AC:0000002800287FA8122812E812287FA8002800000048004800A8011406620000 +D3AD:0000002800287FA8122812E812287FA800280000000001F00208020801F00000 +D3AE:0000002800287FA8122812E812287FA80028000003F80020002000D003080000 +D3AF:0000002800287FA8122812E812287FA800280000004003F8004000A003180000 +D3B0:0000002800287FA8122812E812287FA80028000003F8000803F8000800080000 +D3B1:0000002800287FA8122812E812287FA80028000003F8020003F8020003F80000 +D3B2:0000002800287FA8122812E812287FA80028000000000FF8022002200FF80000 +D3B3:0000002800287FA8122812E812287FA80028000000800FF803E0041003E00000 +D3B4:00000000000200027FC21102111E11021102111E7FC200020002000200020000 +D3B5:0000000800087F881238120812387F8800080000000007F80008000800080000 +D3B6:0000000800087F881238120812387F880008000000003EF80208020802080000 +D3B7:0000000800087F881238120812387F880008000000001F080108011401620000 +D3B8:0000000800087F881238120812387F880008000800001000100010001FF80000 +D3B9:0000000800087F881238120812387F8800080000000020F8201020303ECC0000 +D3BA:0000000800087F881238120812387F8800080000202021FC207020883E700000 +D3BB:0000000800087F881238120812387F880008000003F802000200020003F80000 +D3BC:0000000800087F881238120812387F880008000007F8000807F8040007F80000 +D3BD:0000000800087F881238120812387F88000800003EF802083E0820083E080000 +D3BE:0000000800087F881238120812387F88000800003EF802883E8820883EF80000 +D3BF:0000000800087F881238120812387F88000800003E8802883EF820883EF80000 +D3C0:0000000800087F881238120812387F88000800000F8800880F8808140FA20000 +D3C1:0000000800087F881238120812387F88000800003EF802803EF820803EF80000 +D3C2:0000000800087F881238120812387F88000800003EFC02483E4820483EFC0000 +D3C3:0000000800087F881238120812387F88000800003E1002FE3E3820443E380000 +D3C4:0000000800087F881238120812387F880008000003F802080208020803F80000 +D3C5:0000000800087F881238120812387F88000800000208020803F8020803F80000 +D3C6:0000000800087F881238120812387F8800080000210821083F0821143F620000 +D3C7:0000000800087F881238120812387F8800080000001000100010006801840000 +D3C8:0000000800087F881238120812387F88000800000048004800A8011406620000 +D3C9:0000000800087F881238120812387F8800080000000003F00408040803F00000 +D3CA:0000000800087F881238120812387F880008000003F80020002000D003080000 +D3CB:0000000800087F881238120812387F8800080000004003F8004000A003180000 +D3CC:0000000800087F881238120812387F880008000003F8000803F8000800080000 +D3CD:0000000800087F881238120812387F880008000003F8020003F8020003F80000 +D3CE:0000000800087F881238120812387F880008000000000FF8022002200FF80000 +D3CF:0000000800087F881238120812387F880008000000800FF803E0041003E00000 +D3D0:00000000000A000A7FCA110A113A110A110A113A7FCA000A000A000A000A0000 +D3D1:0000002800287FA812E8122812E87FA80028000007F800080008000800080000 +D3D2:0000002800287FA812E8122812E87FA80028000000003EF80208020802080000 +D3D3:0000002800287FA812E8122812E87FA80028000000003E100210022802C40000 +D3D4:0000002800287FA812E8122812E87FA80028002808000800080008000FF80000 +D3D5:0000002800287FA812E8122812E87FA800280000000020F8201020303ECC0000 +D3D6:0000002800287FA812E8122812E87FA800280000202021FC207020883E700000 +D3D7:0000002800287FA812E8122812E87FA80028000003F802000200020003F80000 +D3D8:0000002800287FA812E8122812E87FA80028000007F8000807F8040007F80000 +D3D9:0000002800287FA812E8122812E87FA8002800003EF802083E0820083E080000 +D3DA:0000002800287FA812E8122812E87FA8002800003EF802883E8820883EF80000 +D3DB:0000002800287FA812E8122812E87FA8002800003E8802883EF820883EF80000 +D3DC:0000002800287FA812E8122812E87FA8002800001F0801081F0810141F620000 +D3DD:0000002800287FA812E8122812E87FA8002800003EF802803EF820803EF80000 +D3DE:0000002800287FA812E8122812E87FA8002800003EFC02483E4820483EFC0000 +D3DF:0000002800287FA812E8122812E87FA8002800003E1002FE3E3820443E380000 +D3E0:0000002800287FA812E8122812E87FA80028000003F802080208020803F80000 +D3E1:0000002800287FA812E8122812E87FA8002800000208020803F8020803F80000 +D3E2:0000002800287FA812E8122812E87FA800280000110811081F0811141F620000 +D3E3:0000002800287FA812E8122812E87FA800280000000800080008003400C20000 +D3E4:0000002800287FA812E8122812E87FA8002800000048004800A8011406620000 +D3E5:0000002800287FA812E8122812E87FA800280000000001F00208020801F00000 +D3E6:0000002800287FA812E8122812E87FA80028000003F80020002000D003080000 +D3E7:0000002800287FA812E8122812E87FA800280000004003F8004000A003180000 +D3E8:0000002800287FA812E8122812E87FA80028000003F8000803F8000800080000 +D3E9:0000002800287FA812E8122812E87FA80028000003F8020003F8020003F80000 +D3EA:0000002800287FA812E8122812E87FA80028000000000FF8022002200FF80000 +D3EB:0000002800287FA812E8122812E87FA80028000000800FF803E0041003E00000 +D3EC:000000003FF808200820082008203FF8000000000100010001007FFC00000000 +D3ED:00001FF00440044004401FF0010001007FFC00001FF000100010001000100000 +D3EE:00001FF00440044004401FF0010001007FFC000000003EF80208020802080000 +D3EF:00001FF00440044004401FF0010001007FFC000000001E100210022802C40000 +D3F0:00001FF00440044004401FF0010001007FFC000000001000100010001FF00000 +D3F1:00001FF00440044004401FF0010001007FFC0000000020F8201020303ECC0000 +D3F2:00001FF00440044004401FF0010001007FFC0000202021FC207020883E700000 +D3F3:00001FF00440044004401FF0010001007FFC00001FF01000100010001FF00000 +D3F4:00001FF00440044004401FF0010001007FFC00001FF000101FF010001FF00000 +D3F5:00001FF00440044004401FF0010001007FFC00003EF802083E0820083E080000 +D3F6:00001FF00440044004401FF0010001007FFC00003EF802883E8820883EF80000 +D3F7:00001FF00440044004401FF0010001007FFC00003E8802883EF820883EF80000 +D3F8:00001FF00440044004401FF0010001007FFC00003E1002103E1020283EC40000 +D3F9:00001FF00440044004401FF0010001007FFC00003EF802803EF820803EF80000 +D3FA:00001FF00440044004401FF0010001007FFC00003EFC02483E4820483EFC0000 +D3FB:00001FF00440044004401FF0010001007FFC00003E2003FC3E7020883E700000 +D3FC:00001FF00440044004401FF0010001007FFC00001FF01010101010101FF00000 +D3FD:00001FF00440044004401FF0010001007FFC0000101010101FF010101FF00000 +D3FE:00001FF00440044004401FF0010001007FFC0000222022203E2022503E880000 +D3FF:00001FF00440044004401FF0010001007FFC000000000100010002800C400000 +D400:00001FF00440044004401FF0010001007FFC00000000024002400DA033100000 +D401:00001FF00440044004401FF0010001007FFC0000000007C00820082007C00000 +D402:00001FF00440044004401FF0010001007FFC0000000007E00080014006200000 +D403:00001FF00440044004401FF0010001007FFC0000008007E00080014006200000 +D404:00001FF00440044004401FF0010001007FFC00001FF000101FF0001000100000 +D405:00001FF00440044004401FF0010001007FFC00001FF010001FF010001FF00000 +D406:00001FF00440044004401FF0010001007FFC000000001FF0044004401FF00000 +D407:00001FF00440044004401FF0010001007FFC000001001FF007C0082007C00000 +D408:00000010001000107FD011101110111E11107FD0041004107FD0001000100000 +D409:000000083F881108110E3F88040804087FE8000007F800080008000800080000 +D40A:000000083F881108110E3F88040804087FE8000000003EF80208020802080000 +D40B:000000083F881108110E3F88040804087FE8000000001F080108011401620000 +D40C:000000083F881108110E3F88040804087FE8000008000800080008000FF80000 +D40D:000000083F881108110E3F88040804087FE80000000010F8101010301ECC0000 +D40E:000000083F881108110E3F88040804087FE800000808087F081C08220F9C0000 +D40F:000000083F881108110E3F88040804087FE8000003F802000200020003F80000 +D410:000000083F881108110E3F88040804087FE8000007F8000807F8040007F80000 +D411:000000083F881108110E3F88040804087FE800003EF802083E0820083E080000 +D412:000000083F881108110E3F88040804087FE800003EF802883E8820883EF80000 +D413:000000083F881108110E3F88040804087FE800003E8802883EF820883EF80000 +D414:000000083F881108110E3F88040804087FE800001F0801081F0810141F620000 +D415:000000083F881108110E3F88040804087FE800003EF802803EF820803EF80000 +D416:000000083F881108110E3F88040804087FE800003EFC02483E4820483EFC0000 +D417:000000083F881108110E3F88040804087FE800001F08017F1F1C10221F1C0000 +D418:000000083F881108110E3F88040804087FE8000003F802080208020803F80000 +D419:000000083F881108110E3F88040804087FE800000208020803F8020803F80000 +D41A:000000083F881108110E3F88040804087FE80000110811081F0811141F620000 +D41B:000000083F881108110E3F88040804087FE80000001000100010006801840000 +D41C:000000083F881108110E3F88040804087FE800000048004800A8011406620000 +D41D:000000083F881108110E3F88040804087FE80000000003F00408040803F00000 +D41E:000000083F881108110E3F88040804087FE8000003F80020002000D003080000 +D41F:000000083F881108110E3F88040804087FE80000004003F8004000A003180000 +D420:000000083F881108110E3F88040804087FE8000003F8000803F8000800080000 +D421:000000083F881108110E3F88040804087FE8000003F8020003F8020003F80000 +D422:000000083F881108110E3F88040804087FE8000000000FF8022002200FF80000 +D423:000000083F881108110E3F88040804087FE8000000800FF803E0041003E00000 +D424:00000012001200127FD211121112111E11127FD2041204127FD2001200120000 +D425:000000283FA8112811383FA8042804287FA8000007F800080008000800080000 +D426:000000283FA8112811383FA8042804287FA8000000003EF80208020802080000 +D427:000000283FA8112811383FA8042804287FA8000000001F080108011401620000 +D428:000000283FA8112811383FA8042804287FA8000008000800080008000FF80000 +D429:000000283FA8112811383FA8042804287FA80000000010F8101010301ECC0000 +D42A:000000283FA8112811383FA8042804287FA800000808087F081C08220F9C0000 +D42B:000000283FA8112811383FA8042804287FA8000003F802000200020003F80000 +D42C:000000283FA8112811383FA8042804287FA8000007F8000807F8040007F80000 +D42D:000000283FA8112811383FA8042804287FA800003EF802083E0820083E080000 +D42E:000000283FA8112811383FA8042804287FA800003EF802883E8820883EF80000 +D42F:000000283FA8112811383FA8042804287FA800003E8802883EF820883EF80000 +D430:000000283FA8112811383FA8042804287FA800001F0801081F0810141F620000 +D431:000000283FA8112811383FA8042804287FA800003EF802803EF820803EF80000 +D432:000000283FA8112811383FA8042804287FA800003EFC02483E4820483EFC0000 +D433:000000283FA8112811383FA8042804287FA800001F08017F1F1C10221F1C0000 +D434:000000283FA8112811383FA8042804287FA8000003F802080208020803F80000 +D435:000000283FA8112811383FA8042804287FA800000208020803F8020803F80000 +D436:000000283FA8112811383FA8042804287FA80000110811081F0811141F620000 +D437:000000283FA8112811383FA8042804287FA80000001000100010006801840000 +D438:000000283FA8112811383FA8042804287FA800000048004800A8011406620000 +D439:000000283FA8112811383FA8042804287FA80000000003F00408040803F00000 +D43A:000000283FA8112811383FA8042804287FA8000003F80020002000D003080000 +D43B:000000283FA8112811383FA8042804287FA80000004003F8004000A003180000 +D43C:000000283FA8112811383FA8042804287FA8000003F8000803F8000800080000 +D43D:000000283FA8112811383FA8042804287FA8000003F8020003F8020003F80000 +D43E:000000283FA8112811383FA8042804287FA8000000000FF8022002200FF80000 +D43F:000000283FA8112811383FA8042804287FA8000000800FF803E0041003E00000 +D440:00000008000800087FC811081108110811087FC8040804087FE8000800080000 +D441:000000083F88110811083F88040804087FE8000007F800080008000800080000 +D442:000000083F88110811083F88040804087FE8000000003EF80208020802080000 +D443:000000083F88110811083F88040804087FE8000000001F080108011401620000 +D444:000000083F88110811083F88040804087FE8000008000800080008000FF80000 +D445:000000083F88110811083F88040804087FE80000000010F8101010301ECC0000 +D446:000000083F88110811083F88040804087FE800000808087F081C08220F9C0000 +D447:000000083F88110811083F88040804087FE8000003F802000200020003F80000 +D448:000000083F88110811083F88040804087FE8000007F8000807F8040007F80000 +D449:000000083F88110811083F88040804087FE800003EF802083E0820083E080000 +D44A:000000083F88110811083F88040804087FE800003EF802883E8820883EF80000 +D44B:000000083F88110811083F88040804087FE800003E8802883EF820883EF80000 +D44C:000000083F88110811083F88040804087FE800001F0801081F0810141F620000 +D44D:000000083F88110811083F88040804087FE800003EF802803EF820803EF80000 +D44E:000000083F88110811083F88040804087FE800003EFC02483E4820483EFC0000 +D44F:000000083F88110811083F88040804087FE800001F08017F1F1C10221F1C0000 +D450:000000083F88110811083F88040804087FE8000003F802080208020803F80000 +D451:000000083F88110811083F88040804087FE800000208020803F8020803F80000 +D452:000000083F88110811083F88040804087FE80000110811081F0811141F620000 +D453:000000083F88110811083F88040804087FE80000001000100010006801840000 +D454:000000083F88110811083F88040804087FE800000048004800A8011406620000 +D455:000000083F88110811083F88040804087FE80000000003F00408040803F00000 +D456:000000083F88110811083F88040804087FE8000003F80020002000D003080000 +D457:000000083F88110811083F88040804087FE80000004003F8004000A003180000 +D458:000000083F88110811083F88040804087FE8000003F8000803F8000800080000 +D459:000000083F88110811083F88040804087FE8000003F8020003F8020003F80000 +D45A:000000083F88110811083F88040804087FE8000000000FF8022002200FF80000 +D45B:000000083F88110811083F88040804087FE8000000800FF803E0041003E00000 +D45C:000000003FF808200820082008203FF8000004400440044004407FFC00000000 +D45D:00001FF00440044004401FF0044004407FFC00001FF000100010001000100000 +D45E:00001FF00440044004401FF0044004407FFC000000003EF80208020802080000 +D45F:00001FF00440044004401FF0044004407FFC000000001E100210022802C40000 +D460:00001FF00440044004401FF0044004407FFC000000001000100010001FF00000 +D461:00001FF00440044004401FF0044004407FFC0000000020F8201020303ECC0000 +D462:00001FF00440044004401FF0044004407FFC0000202021FC207020883E700000 +D463:00001FF00440044004401FF0044004407FFC00001FF01000100010001FF00000 +D464:00001FF00440044004401FF0044004407FFC00001FF000101FF010001FF00000 +D465:00001FF00440044004401FF0044004407FFC00003EF802083E0820083E080000 +D466:00001FF00440044004401FF0044004407FFC00003EF802883E8820883EF80000 +D467:00001FF00440044004401FF0044004407FFC00003E8802883EF820883EF80000 +D468:00001FF00440044004401FF0044004407FFC00003E1002103E1020283EC40000 +D469:00001FF00440044004401FF0044004407FFC00003EF802803EF820803EF80000 +D46A:00001FF00440044004401FF0044004407FFC00003EFC02483E4820483EFC0000 +D46B:00001FF00440044004401FF0044004407FFC00003E2003FC3E7020883E700000 +D46C:00001FF00440044004401FF0044004407FFC00001FF01010101010101FF00000 +D46D:00001FF00440044004401FF0044004407FFC0000101010101FF010101FF00000 +D46E:00001FF00440044004401FF0044004407FFC0000222022203E2022503E880000 +D46F:00001FF00440044004401FF0044004407FFC000000000100010002800C400000 +D470:00001FF00440044004401FF0044004407FFC00000000024002400DA033100000 +D471:00001FF00440044004401FF0044004407FFC0000000007C00820082007C00000 +D472:00001FF00440044004401FF0044004407FFC0000000007E00080014006200000 +D473:00001FF00440044004401FF0044004407FFC0000008007E00080014006200000 +D474:00001FF00440044004401FF0044004407FFC00001FF000101FF0001000100000 +D475:00001FF00440044004401FF0044004407FFC00001FF010001FF010001FF00000 +D476:00001FF00440044004401FF0044004407FFC000000001FF0044004401FF00000 +D477:00001FF00440044004401FF0044004407FFC000001001FF007C0082007C00000 +D478:000000003FF808200820082008203FF8000000003FF801000100010001000000 +D479:00001FF00440044004401FF000007FFC010001001FF000100010001000100000 +D47A:00001FF00440044004401FF000007FFC0100010000003EF80208020802080000 +D47B:00001FF00440044004401FF000007FFC0100010000001E100210022802C40000 +D47C:00001FF00440044004401FF0000000007FFC010001001100100010001FF00000 +D47D:00001FF00440044004401FF000007FFC01000100000020F8201020303ECC0000 +D47E:00001FF00440044004401FF000007FFC01000100202021FC207020883E700000 +D47F:00001FF00440044004401FF000007FFC010001001FF01000100010001FF00000 +D480:00001FF00440044004401FF000007FFC010001001FF000101FF010001FF00000 +D481:00001FF00440044004401FF000007FFC010001003EF802083E0820083E080000 +D482:00001FF00440044004401FF000007FFC010001003EF802883E8820883EF80000 +D483:00001FF00440044004401FF000007FFC010001003E8802883EF820883EF80000 +D484:00001FF00440044004401FF000007FFC010001003E1002103E1020283EC40000 +D485:00001FF00440044004401FF000007FFC010001003EF802803EF820803EF80000 +D486:00001FF00440044004401FF000007FFC010001003EFC02483E4820483EFC0000 +D487:00001FF00440044004401FF000007FFC010001003E2003FC3E7020883E700000 +D488:00001FF00440044004401FF000007FFC010001001FF01010101010101FF00000 +D489:00001FF00440044004401FF000007FFC01000100101010101FF010101FF00000 +D48A:00001FF00440044004401FF000007FFC01000100222022203E2022503E880000 +D48B:00001FF00440044004401FF000007FFC0100010000000100010002800C400000 +D48C:00001FF00440044004401FF000007FFC010001000000024002400DA033100000 +D48D:00001FF00440044004401FF000007FFC01000100000007C00820082007C00000 +D48E:00001FF00440044004401FF000007FFC01000100000007E00080014006200000 +D48F:00001FF00440044004401FF000007FFC01000100008007E00080014006200000 +D490:00001FF00440044004401FF000007FFC010001001FF000101FF0001000100000 +D491:00001FF00440044004401FF000007FFC010001001FF010001FF010001FF00000 +D492:00001FF00440044004401FF000007FFC0100010000001FF0044004401FF00000 +D493:00001FF00440044004401FF000007FFC0100010001001FF007C0082007C00000 +D494:0000000800087FC811081108110811087FC800087FE8040804F8040804080000 +D495:00083F88110811083F8800087FE8027802080000000007F80008000800080000 +D496:00083F88110811083F8800087FE802780208000000003EF80208020802080000 +D497:00083F88110811083F8800087FE802780208000000001F080108011401620000 +D498:00083F88110811083F88000800087FE80278020802081000100010001FF80000 +D499:00083F88110811083F8800087FE8027802080000000020F8201020303ECC0000 +D49A:00083F88110811083F8800087FE8027802080000202021FC207020883E700000 +D49B:00083F88110811083F8800087FE802780208000003F802000200020003F80000 +D49C:00083F88110811083F8800087FE802780208000007F8000807F8040007F80000 +D49D:00083F88110811083F8800087FE80278020800003EF802083E0820083E080000 +D49E:00083F88110811083F8800087FE80278020800003EF802883E8820883EF80000 +D49F:00083F88110811083F8800087FE80278020800003E8802883EF820883EF80000 +D4A0:00083F88110811083F8800087FE80278020800000F8800880F8808140FA20000 +D4A1:00083F88110811083F8800087FE80278020800003EF802803EF820803EF80000 +D4A2:00083F88110811083F8800087FE80278020800003EFC02483E4820483EFC0000 +D4A3:00083F88110811083F8800087FE80278020800003E1002FE3E3820443E380000 +D4A4:00083F88110811083F8800087FE802780208000003F802080208020803F80000 +D4A5:00083F88110811083F8800087FE80278020800000208020803F8020803F80000 +D4A6:00083F88110811083F8800087FE8027802080000210821083F0821143F620000 +D4A7:00083F88110811083F8800087FE8027802080000001000100010006801840000 +D4A8:00083F88110811083F8800087FE80278020800000048004800A8011406620000 +D4A9:00083F88110811083F8800087FE8027802080000000003F00408040803F00000 +D4AA:00083F88110811083F8800087FE802780208000003F80020002000D003080000 +D4AB:00083F88110811083F8800087FE8027802080000004003F8004000A003180000 +D4AC:00083F88110811083F8800087FE802780208000003F8000803F8000800080000 +D4AD:00083F88110811083F8800087FE802780208000003F8020003F8020003F80000 +D4AE:00083F88110811083F8800087FE802780208000000000FF8022002200FF80000 +D4AF:00083F88110811083F8800087FE802780208000000800FF803E0041003E00000 +D4B0:0000000A000A7FCA110A110A110A110A7FCA000A7FEA040A047A040A040A0000 +D4B1:00283FA8112811283FA800287FA805E804280000000007F80008000800080000 +D4B2:00283FA8112811283FA800287FA805E80428000000003EF80208020802080000 +D4B3:00283FA8112811283FA800287FA805E80428000000001F080108011401620000 +D4B4:00283FA8112811283FA8002800287FA8042805E804281428100010001FF80000 +D4B5:00283FA8112811283FA800287FA805E804280000000020F8201020303ECC0000 +D4B6:00283FA8112811283FA800287FA805E804280000202021FC207020883E700000 +D4B7:00283FA8112811283FA800287FA805E80428000003F802000200020003F80000 +D4B8:00283FA8112811283FA800287FA805E80428000007F8000807F8040007F80000 +D4B9:00283FA8112811283FA800287FA805E8042800003EF802083E0820083E080000 +D4BA:00283FA8112811283FA800287FA805E8042800003EF802883E8820883EF80000 +D4BB:00283FA8112811283FA800287FA805E8042800003E8802883EF820883EF80000 +D4BC:00283FA8112811283FA800287FA805E8042800000F8800880F8808140FA20000 +D4BD:00283FA8112811283FA800287FA805E8042800003EF802803EF820803EF80000 +D4BE:00283FA8112811283FA800287FA805E8042800003EFC02483E4820483EFC0000 +D4BF:00283FA8112811283FA800287FA805E8042800003E1002FE3E3820443E380000 +D4C0:00283FA8112811283FA800287FA805E80428000003F802080208020803F80000 +D4C1:00283FA8112811283FA800287FA805E8042800000208020803F8020803F80000 +D4C2:00283FA8112811283FA800287FA805E804280000210821083F0821143F620000 +D4C3:00283FA8112811283FA800287FA805E804280000001000100010006801840000 +D4C4:00283FA8112811283FA800287FA805E8042800000048004800A8011406620000 +D4C5:00283FA8112811283FA800287FA805E804280000000003F00408040803F00000 +D4C6:00283FA8112811283FA800287FA805E80428000003F80020002000D003080000 +D4C7:00283FA8112811283FA800287FA805E804280000004003F8004000A003180000 +D4C8:00283FA8112811283FA800287FA805E80428000003F8000803F8000800080000 +D4C9:00283FA8112811283FA800287FA805E80428000003F8020003F8020003F80000 +D4CA:00283FA8112811283FA800287FA805E80428000000000FF8022002200FF80000 +D4CB:00283FA8112811283FA800287FA805E80428000000800FF803E0041003E00000 +D4CC:0000000800087FC811081108110811087FC800087FE804080408040804080000 +D4CD:00083F88110811083F8800087FE8020802000000000007F80008000800080000 +D4CE:00083F88110811083F8800087FE802080200000000003EF80208020802080000 +D4CF:00083F88110811083F8800087FE802080200000000001F080108011401620000 +D4D0:00083F88110811083F88000800087FE80208020802081008100010001FF80000 +D4D1:00083F88110811083F8800087FE8020802000000000020F8201020303ECC0000 +D4D2:00083F88110811083F8800087FE8020802000000202021FC207020883E700000 +D4D3:00083F88110811083F8800087FE802080200000003F802000200020003F80000 +D4D4:00083F88110811083F8800087FE802080200000007F8000807F8040007F80000 +D4D5:00083F88110811083F8800087FE80208020000003EF802083E0820083E080000 +D4D6:00083F88110811083F8800087FE80208020000003EF802883E8820883EF80000 +D4D7:00083F88110811083F8800087FE80208020000003E8802883EF820883EF80000 +D4D8:00083F88110811083F8800087FE80208020000000F8800880F8808140FA20000 +D4D9:00083F88110811083F8800087FE80208020000003EF802803EF820803EF80000 +D4DA:00083F88110811083F8800087FE80208020000003EFC02483E4820483EFC0000 +D4DB:00083F88110811083F8800087FE80208020000003E1002FE3E3820443E380000 +D4DC:00083F88110811083F8800087FE802080200000003F802080208020803F80000 +D4DD:00083F88110811083F8800087FE80208020000000208020803F8020803F80000 +D4DE:00083F88110811083F8800087FE8020802000000210821083F0821143F620000 +D4DF:00083F88110811083F8800087FE8020802000000001000100010006801840000 +D4E0:00083F88110811083F8800087FE80208020000000048004800A8011406620000 +D4E1:00083F88110811083F8800087FE8020802000000000003F00408040803F00000 +D4E2:00083F88110811083F8800087FE802080200000003F80020002000D003080000 +D4E3:00083F88110811083F8800087FE8020802000000004003F8004000A003180000 +D4E4:00083F88110811083F8800087FE802080200000003F8000803F8000800080000 +D4E5:00083F88110811083F8800087FE802080200000003F8020003F8020003F80000 +D4E6:00083F88110811083F8800087FE802080200000000000FF8022002200FF80000 +D4E7:00083F88110811083F8800087FE802080200000000800FF803E0041003E00000 +D4E8:000000003FF808200820082008203FF8000000007FFC04400440044004400000 +D4E9:00001FF00440044004401FF000007FFC044004401FF000100010001000100000 +D4EA:00001FF00440044004401FF000007FFC0440044000003EF80208020802080000 +D4EB:00001FF00440044004401FF000007FFC0440044000001E100210022802C40000 +D4EC:00001FF00440044004401FF0000000007FFC044004401440100010001FF00000 +D4ED:00001FF00440044004401FF000007FFC04400440000020F8201020303ECC0000 +D4EE:00001FF00440044004401FF000007FFC04400440202021FC207020883E700000 +D4EF:00001FF00440044004401FF000007FFC044004401FF01000100010001FF00000 +D4F0:00001FF00440044004401FF000007FFC044004401FF000101FF010001FF00000 +D4F1:00001FF00440044004401FF000007FFC044004403EF802083E0820083E080000 +D4F2:00001FF00440044004401FF000007FFC044004403EF802883E8820883EF80000 +D4F3:00001FF00440044004401FF000007FFC044004403E8802883EF820883EF80000 +D4F4:00001FF00440044004401FF000007FFC044004403E1002103E1020283EC40000 +D4F5:00001FF00440044004401FF000007FFC044004403EF802803EF820803EF80000 +D4F6:00001FF00440044004401FF000007FFC044004403EFC02483E4820483EFC0000 +D4F7:00001FF00440044004401FF000007FFC044004403E2003FC3E7020883E700000 +D4F8:00001FF00440044004401FF000007FFC044004401FF01010101010101FF00000 +D4F9:00001FF00440044004401FF000007FFC04400440101010101FF010101FF00000 +D4FA:00001FF00440044004401FF000007FFC04400440222022203E2022503E880000 +D4FB:00001FF00440044004401FF000007FFC0440044000000100010002800C400000 +D4FC:00001FF00440044004401FF000007FFC044004400000024002400DA033100000 +D4FD:00001FF00440044004401FF000007FFC04400440000007C00820082007C00000 +D4FE:00001FF00440044004401FF000007FFC04400440000007E00080014006200000 +D4FF:00001FF00440044004401FF000007FFC04400440008007E00080014006200000 +D500:00001FF00440044004401FF000007FFC044004401FF000101FF0001000100000 +D501:00001FF00440044004401FF000007FFC044004401FF010001FF010001FF00000 +D502:00001FF00440044004401FF000007FFC0440044000001FF0044004401FF00000 +D503:00001FF00440044004401FF000007FFC0440044001001FF007C0082007C00000 +D504:000000003FF808200820082008203FF80000000000007FFC0000000000000000 +D505:00001FF00440044004401FF0000000007FFC00001FF000100010001000100000 +D506:00001FF00440044004401FF0000000007FFC000000003EF80208020802080000 +D507:00001FF00440044004401FF0000000007FFC000000001E100210022802C40000 +D508:00001FF00440044004401FF0000000007FFC000000001000100010001FF00000 +D509:00001FF00440044004401FF0000000007FFC0000000020F8201020303ECC0000 +D50A:00001FF00440044004401FF0000000007FFC0000202021FC207020883E700000 +D50B:00001FF00440044004401FF0000000007FFC00001FF01000100010001FF00000 +D50C:00001FF00440044004401FF0000000007FFC00001FF000101FF010001FF00000 +D50D:00001FF00440044004401FF0000000007FFC00003EF802083E0820083E080000 +D50E:00001FF00440044004401FF0000000007FFC00003EF802883E8820883EF80000 +D50F:00001FF00440044004401FF0000000007FFC00003E8802883EF820883EF80000 +D510:00001FF00440044004401FF0000000007FFC00003E1002103E1020283EC40000 +D511:00001FF00440044004401FF0000000007FFC00003EF802803EF820803EF80000 +D512:00001FF00440044004401FF0000000007FFC00003EFC02483E4820483EFC0000 +D513:00001FF00440044004401FF0000000007FFC00003E2003FC3E7020883E700000 +D514:00001FF00440044004401FF0000000007FFC00001FF01010101010101FF00000 +D515:00001FF00440044004401FF0000000007FFC0000101010101FF010101FF00000 +D516:00001FF00440044004401FF0000000007FFC0000222022203E2022503E880000 +D517:00001FF00440044004401FF0000000007FFC000000000100010002800C400000 +D518:00001FF00440044004401FF0000000007FFC00000000024002400DA033100000 +D519:00001FF00440044004401FF0000000007FFC0000000007C00820082007C00000 +D51A:00001FF00440044004401FF0000000007FFC0000000007E00080014006200000 +D51B:00001FF00440044004401FF0000000007FFC0000008007E00080014006200000 +D51C:00001FF00440044004401FF0000000007FFC00001FF000101FF0001000100000 +D51D:00001FF00440044004401FF0000000007FFC00001FF010001FF010001FF00000 +D51E:00001FF00440044004401FF0000000007FFC000000001FF0044004401FF00000 +D51F:00001FF00440044004401FF0000000007FFC000001001FF007C0082007C00000 +D520:00000008000800087FC811081108110811087FC800087FE80008000800080000 +D521:000000083F88110811083F88000800087FE8000007F800080008000800080000 +D522:000000083F88110811083F88000800087FE8000000003EF80208020802080000 +D523:000000083F88110811083F88000800087FE8000000001F080108011401620000 +D524:000000083F88110811083F88000800087FE8000008000800080008000FF80000 +D525:000000083F88110811083F88000800087FE80000000010F8101010301ECC0000 +D526:000000083F88110811083F88000800087FE800000808087F081C08220F9C0000 +D527:000000083F88110811083F88000800087FE8000003F802000200020003F80000 +D528:000000083F88110811083F88000800087FE8000007F8000807F8040007F80000 +D529:000000083F88110811083F88000800087FE800003EF802083E0820083E080000 +D52A:000000083F88110811083F88000800087FE800003EF802883E8820883EF80000 +D52B:000000083F88110811083F88000800087FE800003E8802883EF820883EF80000 +D52C:000000083F88110811083F88000800087FE800001F0801081F0810141F620000 +D52D:000000083F88110811083F88000800087FE800003EF802803EF820803EF80000 +D52E:000000083F88110811083F88000800087FE800003EFC02483E4820483EFC0000 +D52F:000000083F88110811083F88000800087FE800001F08017F1F1C10221F1C0000 +D530:000000083F88110811083F88000800087FE8000003F802080208020803F80000 +D531:000000083F88110811083F88000800087FE800000208020803F8020803F80000 +D532:000000083F88110811083F88000800087FE80000110811081F0811141F620000 +D533:000000083F88110811083F88000800087FE80000001000100010006801840000 +D534:000000083F88110811083F88000800087FE800000048004800A8011406620000 +D535:000000083F88110811083F88000800087FE80000000003F00408040803F00000 +D536:000000083F88110811083F88000800087FE8000003F80020002000D003080000 +D537:000000083F88110811083F88000800087FE80000004003F8004000A003180000 +D538:000000083F88110811083F88000800087FE8000003F8000803F8000800080000 +D539:000000083F88110811083F88000800087FE8000003F8020003F8020003F80000 +D53A:000000083F88110811083F88000800087FE8000000000FF8022002200FF80000 +D53B:000000083F88110811083F88000800087FE8000000800FF803E0041003E00000 +D53C:00000000000800087FC8110811081108110811087FC800080008000800080000 +D53D:0000000800087F881208120812087F8800080000000007F80008000800080000 +D53E:0000000800087F881208120812087F880008000000003EF80208020802080000 +D53F:0000000800087F881208120812087F880008000000001F080108011401620000 +D540:0000000800087F881208120812087F880008000800001000100010001FF80000 +D541:0000000800087F881208120812087F8800080000000020F8201020303ECC0000 +D542:0000000800087F881208120812087F8800080000202021FC207020883E700000 +D543:0000000800087F881208120812087F880008000003F802000200020003F80000 +D544:0000000800087F881208120812087F880008000007F8000807F8040007F80000 +D545:0000000800087F881208120812087F88000800003EF802083E0820083E080000 +D546:0000000800087F881208120812087F88000800003EF802883E8820883EF80000 +D547:0000000800087F881208120812087F88000800003E8802883EF820883EF80000 +D548:0000000800087F881208120812087F88000800000F8800880F8808140FA20000 +D549:0000000800087F881208120812087F88000800003EF802803EF820803EF80000 +D54A:0000000800087F881208120812087F88000800003EFC02483E4820483EFC0000 +D54B:0000000800087F881208120812087F88000800003E1002FE3E3820443E380000 +D54C:0000000800087F881208120812087F880008000003F802080208020803F80000 +D54D:0000000800087F881208120812087F88000800000208020803F8020803F80000 +D54E:0000000800087F881208120812087F8800080000210821083F0821143F620000 +D54F:0000000800087F881208120812087F8800080000001000100010006801840000 +D550:0000000800087F881208120812087F88000800000048004800A8011406620000 +D551:0000000800087F881208120812087F8800080000000003F00408040803F00000 +D552:0000000800087F881208120812087F880008000003F80020002000D003080000 +D553:0000000800087F881208120812087F8800080000004003F8004000A003180000 +D554:0000000800087F881208120812087F880008000003F8000803F8000800080000 +D555:0000000800087F881208120812087F880008000003F8020003F8020003F80000 +D556:0000000800087F881208120812087F880008000000000FF8022002200FF80000 +D557:0000000800087F881208120812087F880008000000800FF803E0041003E00000 +D558:00000000041004103F900E101110209E2090209011100E100010001000100000 +D559:000008087F081C082208220E22081C080008000007F800080008000800080000 +D55A:000008087F081C082208220E22081C080008000000003EF80208020802080000 +D55B:000008087F081C082208220E22081C080008000000001F080108011401620000 +D55C:000008087F081C082208220E22081C080008000808000800080008000FF80000 +D55D:000008087F081C082208220E22081C0800080000000010F8101010301ECC0000 +D55E:000008087F081C082208220E22081C08000800000808087F081C08220F9C0000 +D55F:000008087F081C082208220E22081C080008000003F802000200020003F80000 +D560:000008087F081C082208220E22081C080008000007F8000807F8040007F80000 +D561:000008087F081C082208220E22081C08000800003EF802083E0820083E080000 +D562:000008087F081C082208220E22081C08000800003EF802883E8820883EF80000 +D563:000008087F081C082208220E22081C08000800003E8802883EF820883EF80000 +D564:000008087F081C082208220E22081C08000800001F0801081F0810141F620000 +D565:000008087F081C082208220E22081C08000800003EF802803EF820803EF80000 +D566:000008087F081C082208220E22081C08000800003EFC02483E4820483EFC0000 +D567:000008087F081C082208220E22081C08000800001F08017F1F1C10221F1C0000 +D568:000008087F081C082208220E22081C080008000003F802080208020803F80000 +D569:000008087F081C082208220E22081C08000800000208020803F8020803F80000 +D56A:000008087F081C082208220E22081C0800080000110811081F0811141F620000 +D56B:000008087F081C082208220E22081C0800080000001000100010006801840000 +D56C:000008087F081C082208220E22081C08000800000048004800A8011406620000 +D56D:000008087F081C082208220E22081C0800080000000003F00408040803F00000 +D56E:000008087F081C082208220E22081C080008000003F80020002000D003080000 +D56F:000008087F081C082208220E22081C0800080000004003F8004000A003180000 +D570:000008087F081C082208220E22081C080008000003F8000803F8000800080000 +D571:000008087F081C082208220E22081C080008000003F8020003F8020003F80000 +D572:000008087F081C082208220E22081C080008000000000FF8022002200FF80000 +D573:000008087F081C082208220E22081C080008000000800FF803E0041003E00000 +D574:00000000041204123F920E121112209E2092209211120E120012001200120000 +D575:000008287F281C282228223822281C280028000007F800080008000800080000 +D576:000008287F281C282228223822281C280028000000003EF80208020802080000 +D577:000008287F281C282228223822281C280028000000003E100210022802C40000 +D578:000008287F281C282228223822281C280028002808000800080008000FF80000 +D579:000008287F281C282228223822281C2800280000000020F8201020303ECC0000 +D57A:000008287F281C282228223822281C2800280000202021FC207020883E700000 +D57B:000008287F281C282228223822281C280028000003F802000200020003F80000 +D57C:000008287F281C282228223822281C280028000007F8000807F8040007F80000 +D57D:000008287F281C282228223822281C28002800003EF802083E0820083E080000 +D57E:000008287F281C282228223822281C28002800003EF802883E8820883EF80000 +D57F:000008287F281C282228223822281C28002800003E8802883EF820883EF80000 +D580:000008287F281C282228223822281C28002800001F0801081F0810141F620000 +D581:000008287F281C282228223822281C28002800003EF802803EF820803EF80000 +D582:000008287F281C282228223822281C28002800003EFC02483E4820483EFC0000 +D583:000008287F281C282228223822281C28002800003E1002FE3E3820443E380000 +D584:000008287F281C282228223822281C280028000003F802080208020803F80000 +D585:000008287F281C282228223822281C28002800000208020803F8020803F80000 +D586:000008287F281C282228223822281C2800280000110811081F0811141F620000 +D587:000008287F281C282228223822281C2800280000000800080008003400C20000 +D588:000008287F281C282228223822281C28002800000048004800A8011406620000 +D589:000008287F281C282228223822281C2800280000000001F00208020801F00000 +D58A:000008287F281C282228223822281C280028000003F80020002000D003080000 +D58B:000008287F281C282228223822281C2800280000004003F8004000A003180000 +D58C:000008287F281C282228223822281C280028000003F8000803F8000800080000 +D58D:000008287F281C282228223822281C280028000003F8020003F8020003F80000 +D58E:000008287F281C282228223822281C280028000000000FF8022002200FF80000 +D58F:000008287F281C282228223822281C280028000000800FF803E0041003E00000 +D590:00000000041004103F900E10111E20902090209E11100E100010001000100000 +D591:000008087F081C08220E2208220E1C080008000007F800080008000800080000 +D592:000008087F081C08220E2208220E1C080008000000003EF80208020802080000 +D593:000008087F081C08220E2208220E1C080008000000001F080108011401620000 +D594:000008087F081C08220E2208220E1C080008000008000800080008000FF80000 +D595:000008087F081C08220E2208220E1C0800080000000010F8101010301ECC0000 +D596:000008087F081C08220E2208220E1C08000800000808087F081C08220F9C0000 +D597:000008087F081C08220E2208220E1C080008000003F802000200020003F80000 +D598:000008087F081C08220E2208220E1C080008000007F8000807F8040007F80000 +D599:000008087F081C08220E2208220E1C08000800003EF802083E0820083E080000 +D59A:000008087F081C08220E2208220E1C08000800003EF802883E8820883EF80000 +D59B:000008087F081C08220E2208220E1C08000800003E8802883EF820883EF80000 +D59C:000008087F081C08220E2208220E1C08000800001F0801081F0810141F620000 +D59D:000008087F081C08220E2208220E1C08000800003EF802803EF820803EF80000 +D59E:000008087F081C08220E2208220E1C08000800003EFC02483E4820483EFC0000 +D59F:000008087F081C08220E2208220E1C08000800001F08017F1F1C10221F1C0000 +D5A0:000008087F081C08220E2208220E1C080008000003F802080208020803F80000 +D5A1:000008087F081C08220E2208220E1C08000800000208020803F8020803F80000 +D5A2:000008087F081C08220E2208220E1C0800080000110811081F0811141F620000 +D5A3:000008087F081C08220E2208220E1C0800080000001000100010006801840000 +D5A4:000008087F081C08220E2208220E1C08000800000048004800A8011406620000 +D5A5:000008087F081C08220E2208220E1C0800080000000003F00408040803F00000 +D5A6:000008087F081C08220E2208220E1C080008000003F80020002000D003080000 +D5A7:000008087F081C08220E2208220E1C0800080000004003F8004000A003180000 +D5A8:000008087F081C08220E2208220E1C080008000003F8000803F8000800080000 +D5A9:000008087F081C08220E2208220E1C080008000003F8020003F8020003F80000 +D5AA:000008087F081C08220E2208220E1C080008000000000FF8022002200FF80000 +D5AB:000008087F081C08220E2208220E1C080008000000800FF803E0041003E00000 +D5AC:00000000041204123F920E12111E20922092209E11120E120012001200120000 +D5AD:000008287F281C282238222822381C280028000007F800080008000800080000 +D5AE:000008287F281C282238222822381C280028000000003EF80208020802080000 +D5AF:000008287F281C282238222822381C280028000000003E100210022802C40000 +D5B0:000008287F281C282238222822381C280028002808000800080008000FF80000 +D5B1:000008287F281C282238222822381C2800280000000020F8201020303ECC0000 +D5B2:000008287F281C282238222822381C2800280000202021FC207020883E700000 +D5B3:000008287F281C282238222822381C280028000003F802000200020003F80000 +D5B4:000008287F281C282238222822381C280028000007F8000807F8040007F80000 +D5B5:000008287F281C282238222822381C28002800003EF802083E0820083E080000 +D5B6:000008287F281C282238222822381C28002800003EF802883E8820883EF80000 +D5B7:000008287F281C282238222822381C28002800003E8802883EF820883EF80000 +D5B8:000008287F281C282238222822381C28002800001F0801081F0810141F620000 +D5B9:000008287F281C282238222822381C28002800003EF802803EF820803EF80000 +D5BA:000008287F281C282238222822381C28002800003EFC02483E4820483EFC0000 +D5BB:000008287F281C282238222822381C28002800003E1002FE3E3820443E380000 +D5BC:000008287F281C282238222822381C280028000003F802080208020803F80000 +D5BD:000008287F281C282238222822381C28002800000208020803F8020803F80000 +D5BE:000008287F281C282238222822381C2800280000110811081F0811141F620000 +D5BF:000008287F281C282238222822381C2800280000000800080008003400C20000 +D5C0:000008287F281C282238222822381C28002800000048004800A8011406620000 +D5C1:000008287F281C282238222822381C2800280000000001F00208020801F00000 +D5C2:000008287F281C282238222822381C280028000003F80020002000D003080000 +D5C3:000008287F281C282238222822381C2800280000004003F8004000A003180000 +D5C4:000008287F281C282238222822381C280028000003F8000803F8000800080000 +D5C5:000008287F281C282238222822381C280028000003F8020003F8020003F80000 +D5C6:000008287F281C282238222822381C280028000000000FF8022002200FF80000 +D5C7:000008287F281C282238222822381C280028000000800FF803E0041003E00000 +D5C8:00000000040204023F820E021102209E2082208211020E020002000200020000 +D5C9:000008087F081C082208223822081C0800080000000007F80008000800080000 +D5CA:000008087F081C082208223822081C080008000000003EF80208020802080000 +D5CB:000008087F081C082208223822081C080008000000001F080108011401620000 +D5CC:000008087F081C082208223822081C080008000000001000100010001FF80000 +D5CD:000008087F081C082208223822081C0800080000000020F8201020303ECC0000 +D5CE:000008087F081C082208223822081C0800080000202021FC207020883E700000 +D5CF:000008087F081C082208223822081C080008000003F802000200020003F80000 +D5D0:000008087F081C082208223822081C080008000007F8000807F8040007F80000 +D5D1:000008087F081C082208223822081C08000800003EF802083E0820083E080000 +D5D2:000008087F081C082208223822081C08000800003EF802883E8820883EF80000 +D5D3:000008087F081C082208223822081C08000800003E8802883EF820883EF80000 +D5D4:000008087F081C082208223822081C08000800000F8800880F8808140FA20000 +D5D5:000008087F081C082208223822081C08000800003EF802803EF820803EF80000 +D5D6:000008087F081C082208223822081C08000800003EFC02483E4820483EFC0000 +D5D7:000008087F081C082208223822081C08000800003E1002FE3E3820443E380000 +D5D8:000008087F081C082208223822081C080008000003F802080208020803F80000 +D5D9:000008087F081C082208223822081C08000800000208020803F8020803F80000 +D5DA:000008087F081C082208223822081C0800080000210821083F0821143F620000 +D5DB:000008087F081C082208223822081C0800080000001000100010006801840000 +D5DC:000008087F081C082208223822081C08000800000048004800A8011406620000 +D5DD:000008087F081C082208223822081C0800080000000003F00408040803F00000 +D5DE:000008087F081C082208223822081C080008000003F80020002000D003080000 +D5DF:000008087F081C082208223822081C0800080000004003F8004000A003180000 +D5E0:000008087F081C082208223822081C080008000003F8000803F8000800080000 +D5E1:000008087F081C082208223822081C080008000003F8020003F8020003F80000 +D5E2:000008087F081C082208223822081C080008000000000FF8022002200FF80000 +D5E3:000008087F081C082208223822081C080008000000800FF803E0041003E00000 +D5E4:00000000040A040A3F8A0E0A110A20BA208A208A110A0E0A000A000A000A0000 +D5E5:000008287F281C28222822E822281C280028000007F800080008000800080000 +D5E6:000008287F281C28222822E822281C280028000000003EF80208020802080000 +D5E7:000008287F281C28222822E822281C280028000000003E100210022802C40000 +D5E8:000008287F281C28222822E822281C280028000008000800080008000FF80000 +D5E9:000008287F281C28222822E822281C2800280000000020F8201020303ECC0000 +D5EA:000008287F281C28222822E822281C2800280000202021FC207020883E700000 +D5EB:000008287F281C28222822E822281C280028000003F802000200020003F80000 +D5EC:000008287F281C28222822E822281C280028000007F8000807F8040007F80000 +D5ED:000008287F281C28222822E822281C28002800003EF802083E0820083E080000 +D5EE:000008287F281C28222822E822281C28002800003EF802883E8820883EF80000 +D5EF:000008287F281C28222822E822281C28002800003E8802883EF820883EF80000 +D5F0:000008287F281C28222822E822281C28002800001F0801081F0810141F620000 +D5F1:000008287F281C28222822E822281C28002800003EF802803EF820803EF80000 +D5F2:000008287F281C28222822E822281C28002800003EFC02483E4820483EFC0000 +D5F3:000008287F281C28222822E822281C28002800003E1002FE3E3820443E380000 +D5F4:000008287F281C28222822E822281C280028000003F802080208020803F80000 +D5F5:000008287F281C28222822E822281C28002800000208020803F8020803F80000 +D5F6:000008287F281C28222822E822281C2800280000110811081F0811141F620000 +D5F7:000008287F281C28222822E822281C2800280000000800080008003400C20000 +D5F8:000008287F281C28222822E822281C28002800000048004800A8011406620000 +D5F9:000008287F281C28222822E822281C2800280000000001F00208020801F00000 +D5FA:000008287F281C28222822E822281C280028000003F80020002000D003080000 +D5FB:000008287F281C28222822E822281C2800280000004003F8004000A003180000 +D5FC:000008287F281C28222822E822281C280028000003F8000803F8000800080000 +D5FD:000008287F281C28222822E822281C280028000003F8020003F8020003F80000 +D5FE:000008287F281C28222822E822281C280028000000000FF8022002200FF80000 +D5FF:000008287F281C28222822E822281C280028000000800FF803E0041003E00000 +D600:00000000040204023F820E02111E20822082209E11020E020002000200020000 +D601:000008087F081C082238220822381C0800080000000007F80008000800080000 +D602:000008087F081C082238220822381C080008000000003EF80208020802080000 +D603:000008087F081C082238220822381C080008000000001F080108011401620000 +D604:000008087F081C082238220822381C080008000800001000100010001FF80000 +D605:000008087F081C082238220822381C0800080000000020F8201020303ECC0000 +D606:000008087F081C082238220822381C0800080000202021FC207020883E700000 +D607:000008087F081C082238220822381C080008000003F802000200020003F80000 +D608:000008087F081C082238220822381C080008000007F8000807F8040007F80000 +D609:000008087F081C082238220822381C08000800003EF802083E0820083E080000 +D60A:000008087F081C082238220822381C08000800003EF802883E8820883EF80000 +D60B:000008087F081C082238220822381C08000800003E8802883EF820883EF80000 +D60C:000008087F081C082238220822381C08000800000F8800880F8808140FA20000 +D60D:000008087F081C082238220822381C08000800003EF802803EF820803EF80000 +D60E:000008087F081C082238220822381C08000800003EFC02483E4820483EFC0000 +D60F:000008087F081C082238220822381C08000800003E1002FE3E3820443E380000 +D610:000008087F081C082238220822381C080008000003F802080208020803F80000 +D611:000008087F081C082238220822381C08000800000208020803F8020803F80000 +D612:000008087F081C082238220822381C0800080000210821083F0821143F620000 +D613:000008087F081C082238220822381C0800080000001000100010006801840000 +D614:000008087F081C082238220822381C08000800000048004800A8011406620000 +D615:000008087F081C082238220822381C0800080000000003F00408040803F00000 +D616:000008087F081C082238220822381C080008000003F80020002000D003080000 +D617:000008087F081C082238220822381C0800080000004003F8004000A003180000 +D618:000008087F081C082238220822381C080008000003F8000803F8000800080000 +D619:000008087F081C082238220822381C080008000003F8020003F8020003F80000 +D61A:000008087F081C082238220822381C080008000000000FF8022002200FF80000 +D61B:000008087F081C082238220822381C080008000000800FF803E0041003E00000 +D61C:00000000040A040A3F8A0E0A113A208A208A20BA110A0E0A000A000A000A0000 +D61D:000008287F281C2822E8222822E81C280028000007F800080008000800080000 +D61E:000008287F281C2822E8222822E81C280028000000003EF80208020802080000 +D61F:000008287F281C2822E8222822E81C280028000000003E100210022802C40000 +D620:000008287F281C2822E8222822E81C280028002808000800080008000FF80000 +D621:000008287F281C2822E8222822E81C2800280000000020F8201020303ECC0000 +D622:000008287F281C2822E8222822E81C2800280000202021FC207020883E700000 +D623:000008287F281C2822E8222822E81C280028000003F802000200020003F80000 +D624:000008287F281C2822E8222822E81C280028000007F8000807F8040007F80000 +D625:000008287F281C2822E8222822E81C28002800003EF802083E0820083E080000 +D626:000008287F281C2822E8222822E81C28002800003EF802883E8820883EF80000 +D627:000008287F281C2822E8222822E81C28002800003E8802883EF820883EF80000 +D628:000008287F281C2822E8222822E81C28002800001F0801081F0810141F620000 +D629:000008287F281C2822E8222822E81C28002800003EF802803EF820803EF80000 +D62A:000008287F281C2822E8222822E81C28002800003EFC02483E4820483EFC0000 +D62B:000008287F281C2822E8222822E81C28002800003E1002FE3E3820443E380000 +D62C:000008287F281C2822E8222822E81C280028000003F802080208020803F80000 +D62D:000008287F281C2822E8222822E81C28002800000208020803F8020803F80000 +D62E:000008287F281C2822E8222822E81C2800280000110811081F0811141F620000 +D62F:000008287F281C2822E8222822E81C2800280000000800080008003400C20000 +D630:000008287F281C2822E8222822E81C28002800000048004800A8011406620000 +D631:000008287F281C2822E8222822E81C2800280000000001F00208020801F00000 +D632:000008287F281C2822E8222822E81C280028000003F80020002000D003080000 +D633:000008287F281C2822E8222822E81C2800280000004003F8004000A003180000 +D634:000008287F281C2822E8222822E81C280028000003F8000803F8000800080000 +D635:000008287F281C2822E8222822E81C280028000003F8020003F8020003F80000 +D636:000008287F281C2822E8222822E81C280028000000000FF8022002200FF80000 +D637:000008287F281C2822E8222822E81C280028000000800FF803E0041003E00000 +D638:0000010001000FE0000007C00820082007C000000100010001007FFC00000000 +D639:01000FE007C00820082007C0010001007FFC00001FF000100010001000100000 +D63A:01000FE007C00820082007C0010001007FFC000000003EF80208020802080000 +D63B:01000FE007C00820082007C0010001007FFC000000001E100210022802C40000 +D63C:01000FE007C00820082007C0010001007FFC000000001000100010001FF00000 +D63D:01000FE007C00820082007C0010001007FFC0000000020F8201020303ECC0000 +D63E:01000FE007C00820082007C0010001007FFC0000202021FC207020883E700000 +D63F:01000FE007C00820082007C0010001007FFC00001FF01000100010001FF00000 +D640:01000FE007C00820082007C0010001007FFC00001FF000101FF010001FF00000 +D641:01000FE007C00820082007C0010001007FFC00003EF802083E0820083E080000 +D642:01000FE007C00820082007C0010001007FFC00003EF802883E8820883EF80000 +D643:01000FE007C00820082007C0010001007FFC00003E8802883EF820883EF80000 +D644:01000FE007C00820082007C0010001007FFC00003E1002103E1020283EC40000 +D645:01000FE007C00820082007C0010001007FFC00003EF802803EF820803EF80000 +D646:01000FE007C00820082007C0010001007FFC00003EFC02483E4820483EFC0000 +D647:01000FE007C00820082007C0010001007FFC00003E2003FC3E7020883E700000 +D648:01000FE007C00820082007C0010001007FFC00001FF01010101010101FF00000 +D649:01000FE007C00820082007C0010001007FFC0000101010101FF010101FF00000 +D64A:01000FE007C00820082007C0010001007FFC0000222022203E2022503E880000 +D64B:01000FE007C00820082007C0010001007FFC000000000100010002800C400000 +D64C:01000FE007C00820082007C0010001007FFC00000000024002400DA033100000 +D64D:01000FE007C00820082007C0010001007FFC0000000007C00820082007C00000 +D64E:01000FE007C00820082007C0010001007FFC0000000007E00080014006200000 +D64F:01000FE007C00820082007C0010001007FFC0000008007E00080014006200000 +D650:01000FE007C00820082007C0010001007FFC00001FF000101FF0001000100000 +D651:01000FE007C00820082007C0010001007FFC00001FF010001FF010001FF00000 +D652:01000FE007C00820082007C0010001007FFC000000001FF0044004401FF00000 +D653:01000FE007C00820082007C0010001007FFC000001001FF007C0082007C00000 +D654:00000010041004103F9000101F10209E20901F10041004107FD0001000100000 +D655:000004083F880E08110E11080E0804087FE8000007F800080008000800080000 +D656:000004083F880E08110E11080E0804087FE8000000003EF80208020802080000 +D657:000004083F880E08110E11080E0804087FE8000000001F080108011401620000 +D658:000004083F880E08110E11080E0804087FE8000008000800080008000FF80000 +D659:000004083F880E08110E11080E0804087FE80000000010F8101010301ECC0000 +D65A:000004083F880E08110E11080E0804087FE800000808087F081C08220F9C0000 +D65B:000004083F880E08110E11080E0804087FE8000003F802000200020003F80000 +D65C:000004083F880E08110E11080E0804087FE8000007F8000807F8040007F80000 +D65D:000004083F880E08110E11080E0804087FE800003EF802083E0820083E080000 +D65E:000004083F880E08110E11080E0804087FE800003EF802883E8820883EF80000 +D65F:000004083F880E08110E11080E0804087FE800003E8802883EF820883EF80000 +D660:000004083F880E08110E11080E0804087FE800001F0801081F0810141F620000 +D661:000004083F880E08110E11080E0804087FE800003EF802803EF820803EF80000 +D662:000004083F880E08110E11080E0804087FE800003EFC02483E4820483EFC0000 +D663:000004083F880E08110E11080E0804087FE800001F08017F1F1C10221F1C0000 +D664:000004083F880E08110E11080E0804087FE8000003F802080208020803F80000 +D665:000004083F880E08110E11080E0804087FE800000208020803F8020803F80000 +D666:000004083F880E08110E11080E0804087FE80000110811081F0811141F620000 +D667:000004083F880E08110E11080E0804087FE80000001000100010006801840000 +D668:000004083F880E08110E11080E0804087FE800000048004800A8011406620000 +D669:000004083F880E08110E11080E0804087FE80000000003F00408040803F00000 +D66A:000004083F880E08110E11080E0804087FE8000003F80020002000D003080000 +D66B:000004083F880E08110E11080E0804087FE80000004003F8004000A003180000 +D66C:000004083F880E08110E11080E0804087FE8000003F8000803F8000800080000 +D66D:000004083F880E08110E11080E0804087FE8000003F8020003F8020003F80000 +D66E:000004083F880E08110E11080E0804087FE8000000000FF8022002200FF80000 +D66F:000004083F880E08110E11080E0804087FE8000000800FF803E0041003E00000 +D670:00000012041204123F9200121F12209E20921F12041204127FD2001200120000 +D671:000004283FA80E28113811280E2804287FA8000007F800080008000800080000 +D672:000004283FA80E28113811280E2804287FA8000000003EF80208020802080000 +D673:000004283FA80E28113811280E2804287FA8000000001F080108011401620000 +D674:000004283FA80E28113811280E2804287FA8000008000800080008000FF80000 +D675:000004283FA80E28113811280E2804287FA80000000010F8101010301ECC0000 +D676:000004283FA80E28113811280E2804287FA800000808087F081C08220F9C0000 +D677:000004283FA80E28113811280E2804287FA8000003F802000200020003F80000 +D678:000004283FA80E28113811280E2804287FA8000007F8000807F8040007F80000 +D679:000004283FA80E28113811280E2804287FA800003EF802083E0820083E080000 +D67A:000004283FA80E28113811280E2804287FA800003EF802883E8820883EF80000 +D67B:000004283FA80E28113811280E2804287FA800003E8802883EF820883EF80000 +D67C:000004283FA80E28113811280E2804287FA800001F0801081F0810141F620000 +D67D:000004283FA80E28113811280E2804287FA800003EF802803EF820803EF80000 +D67E:000004283FA80E28113811280E2804287FA800003EFC02483E4820483EFC0000 +D67F:000004283FA80E28113811280E2804287FA800001F08017F1F1C10221F1C0000 +D680:000004283FA80E28113811280E2804287FA8000003F802080208020803F80000 +D681:000004283FA80E28113811280E2804287FA800000208020803F8020803F80000 +D682:000004283FA80E28113811280E2804287FA80000110811081F0811141F620000 +D683:000004283FA80E28113811280E2804287FA80000001000100010006801840000 +D684:000004283FA80E28113811280E2804287FA800000048004800A8011406620000 +D685:000004283FA80E28113811280E2804287FA80000000003F00408040803F00000 +D686:000004283FA80E28113811280E2804287FA8000003F80020002000D003080000 +D687:000004283FA80E28113811280E2804287FA80000004003F8004000A003180000 +D688:000004283FA80E28113811280E2804287FA8000003F8000803F8000800080000 +D689:000004283FA80E28113811280E2804287FA8000003F8020003F8020003F80000 +D68A:000004283FA80E28113811280E2804287FA8000000000FF8022002200FF80000 +D68B:000004283FA80E28113811280E2804287FA8000000800FF803E0041003E00000 +D68C:00000008040804083F8800081F08208820881F08040804087FE8000800080000 +D68D:000004083F880E08110811080E0804087FE8000007F800080008000800080000 +D68E:000004083F880E08110811080E0804087FE8000000003EF80208020802080000 +D68F:000004083F880E08110811080E0804087FE8000000001F080108011401620000 +D690:000004083F880E08110811080E0804087FE8000008000800080008000FF80000 +D691:000004083F880E08110811080E0804087FE80000000010F8101010301ECC0000 +D692:000004083F880E08110811080E0804087FE800000808087F081C08220F9C0000 +D693:000004083F880E08110811080E0804087FE8000003F802000200020003F80000 +D694:000004083F880E08110811080E0804087FE8000007F8000807F8040007F80000 +D695:000004083F880E08110811080E0804087FE800003EF802083E0820083E080000 +D696:000004083F880E08110811080E0804087FE800003EF802883E8820883EF80000 +D697:000004083F880E08110811080E0804087FE800003E8802883EF820883EF80000 +D698:000004083F880E08110811080E0804087FE800001F0801081F0810141F620000 +D699:000004083F880E08110811080E0804087FE800003EF802803EF820803EF80000 +D69A:000004083F880E08110811080E0804087FE800003EFC02483E4820483EFC0000 +D69B:000004083F880E08110811080E0804087FE800001F08017F1F1C10221F1C0000 +D69C:000004083F880E08110811080E0804087FE8000003F802080208020803F80000 +D69D:000004083F880E08110811080E0804087FE800000208020803F8020803F80000 +D69E:000004083F880E08110811080E0804087FE80000110811081F0811141F620000 +D69F:000004083F880E08110811080E0804087FE80000001000100010006801840000 +D6A0:000004083F880E08110811080E0804087FE800000048004800A8011406620000 +D6A1:000004083F880E08110811080E0804087FE80000000003F00408040803F00000 +D6A2:000004083F880E08110811080E0804087FE8000003F80020002000D003080000 +D6A3:000004083F880E08110811080E0804087FE80000004003F8004000A003180000 +D6A4:000004083F880E08110811080E0804087FE8000003F8000803F8000800080000 +D6A5:000004083F880E08110811080E0804087FE8000003F8020003F8020003F80000 +D6A6:000004083F880E08110811080E0804087FE8000000000FF8022002200FF80000 +D6A7:000004083F880E08110811080E0804087FE8000000800FF803E0041003E00000 +D6A8:0000010001000FE0000007C00820082007C004400440044004407FFC00000000 +D6A9:01000FE007C00820082007C0044004407FFC00001FF000100010001000100000 +D6AA:01000FE007C00820082007C0044004407FFC000000003EF80208020802080000 +D6AB:01000FE007C00820082007C0044004407FFC000000001E100210022802C40000 +D6AC:01000FE007C00820082007C0044004407FFC000000001000100010001FF00000 +D6AD:01000FE007C00820082007C0044004407FFC0000000020F8201020303ECC0000 +D6AE:01000FE007C00820082007C0044004407FFC0000202021FC207020883E700000 +D6AF:01000FE007C00820082007C0044004407FFC00001FF01000100010001FF00000 +D6B0:01000FE007C00820082007C0044004407FFC00001FF000101FF010001FF00000 +D6B1:01000FE007C00820082007C0044004407FFC00003EF802083E0820083E080000 +D6B2:01000FE007C00820082007C0044004407FFC00003EF802883E8820883EF80000 +D6B3:01000FE007C00820082007C0044004407FFC00003E8802883EF820883EF80000 +D6B4:01000FE007C00820082007C0044004407FFC00003E1002103E1020283EC40000 +D6B5:01000FE007C00820082007C0044004407FFC00003EF802803EF820803EF80000 +D6B6:01000FE007C00820082007C0044004407FFC00003EFC02483E4820483EFC0000 +D6B7:01000FE007C00820082007C0044004407FFC00003E2003FC3E7020883E700000 +D6B8:01000FE007C00820082007C0044004407FFC00001FF01010101010101FF00000 +D6B9:01000FE007C00820082007C0044004407FFC0000101010101FF010101FF00000 +D6BA:01000FE007C00820082007C0044004407FFC0000222022203E2022503E880000 +D6BB:01000FE007C00820082007C0044004407FFC000000000100010002800C400000 +D6BC:01000FE007C00820082007C0044004407FFC00000000024002400DA033100000 +D6BD:01000FE007C00820082007C0044004407FFC0000000007C00820082007C00000 +D6BE:01000FE007C00820082007C0044004407FFC0000000007E00080014006200000 +D6BF:01000FE007C00820082007C0044004407FFC0000008007E00080014006200000 +D6C0:01000FE007C00820082007C0044004407FFC00001FF000101FF0001000100000 +D6C1:01000FE007C00820082007C0044004407FFC00001FF010001FF010001FF00000 +D6C2:01000FE007C00820082007C0044004407FFC000000001FF0044004401FF00000 +D6C3:01000FE007C00820082007C0044004407FFC000001001FF007C0082007C00000 +D6C4:0000010001000FE0000007C00820082007C000003FF801000100010001000000 +D6C5:01000FE007C00820082007C000007FFC010001001FF000100010001000100000 +D6C6:01000FE007C00820082007C000007FFC0100010000003EF80208020802080000 +D6C7:01000FE007C00820082007C000007FFC0100010000001E100210022802C40000 +D6C8:01000FE007C00820082007C0000000007FFC010001001100100010001FF00000 +D6C9:01000FE007C00820082007C000007FFC01000100000020F8201020303ECC0000 +D6CA:01000FE007C00820082007C000007FFC01000100202021FC207020883E700000 +D6CB:01000FE007C00820082007C000007FFC010001001FF01000100010001FF00000 +D6CC:01000FE007C00820082007C000007FFC010001001FF000101FF010001FF00000 +D6CD:01000FE007C00820082007C000007FFC010001003EF802083E0820083E080000 +D6CE:01000FE007C00820082007C000007FFC010001003EF802883E8820883EF80000 +D6CF:01000FE007C00820082007C000007FFC010001003E8802883EF820883EF80000 +D6D0:01000FE007C00820082007C000007FFC010001003E1002103E1020283EC40000 +D6D1:01000FE007C00820082007C000007FFC010001003EF802803EF820803EF80000 +D6D2:01000FE007C00820082007C000007FFC010001003EFC02483E4820483EFC0000 +D6D3:01000FE007C00820082007C000007FFC010001003E2003FC3E7020883E700000 +D6D4:01000FE007C00820082007C000007FFC010001001FF01010101010101FF00000 +D6D5:01000FE007C00820082007C000007FFC01000100101010101FF010101FF00000 +D6D6:01000FE007C00820082007C000007FFC01000100222022203E2022503E880000 +D6D7:01000FE007C00820082007C000007FFC0100010000000100010002800C400000 +D6D8:01000FE007C00820082007C000007FFC010001000000024002400DA033100000 +D6D9:01000FE007C00820082007C000007FFC01000100000007C00820082007C00000 +D6DA:01000FE007C00820082007C000007FFC01000100000007E00080014006200000 +D6DB:01000FE007C00820082007C000007FFC01000100008007E00080014006200000 +D6DC:01000FE007C00820082007C000007FFC010001001FF000101FF0001000100000 +D6DD:01000FE007C00820082007C000007FFC010001001FF010001FF010001FF00000 +D6DE:01000FE007C00820082007C000007FFC0100010000001FF0044004401FF00000 +D6DF:01000FE007C00820082007C000007FFC0100010001001FF007C0082007C00000 +D6E0:0000040804083F8800081F08208820881F0800087FE8040804F8040804080000 +D6E1:04083F880E0811080E0800087FE8027802080000000007F80008000800080000 +D6E2:04083F880E0811080E0800087FE802780208000000003EF80208020802080000 +D6E3:04083F880E0811080E0800087FE802780208000000001F080108011401620000 +D6E4:04083F880E0811080E08000800087FE80278020802081000100010001FF80000 +D6E5:04083F880E0811080E0800087FE8027802080000000020F8201020303ECC0000 +D6E6:04083F880E0811080E0800087FE8027802080000202021FC207020883E700000 +D6E7:04083F880E0811080E0800087FE802780208000003F802000200020003F80000 +D6E8:04083F880E0811080E0800087FE802780208000007F8000807F8040007F80000 +D6E9:04083F880E0811080E0800087FE80278020800003EF802083E0820083E080000 +D6EA:04083F880E0811080E0800087FE80278020800003EF802883E8820883EF80000 +D6EB:04083F880E0811080E0800087FE80278020800003E8802883EF820883EF80000 +D6EC:04083F880E0811080E0800087FE80278020800000F8800880F8808140FA20000 +D6ED:04083F880E0811080E0800087FE80278020800003EF802803EF820803EF80000 +D6EE:04083F880E0811080E0800087FE80278020800003EFC02483E4820483EFC0000 +D6EF:04083F880E0811080E0800087FE80278020800003E1002FE3E3820443E380000 +D6F0:04083F880E0811080E0800087FE802780208000003F802080208020803F80000 +D6F1:04083F880E0811080E0800087FE80278020800000208020803F8020803F80000 +D6F2:04083F880E0811080E0800087FE8027802080000210821083F0821143F620000 +D6F3:04083F880E0811080E0800087FE8027802080000001000100010006801840000 +D6F4:04083F880E0811080E0800087FE80278020800000048004800A8011406620000 +D6F5:04083F880E0811080E0800087FE8027802080000000003F00408040803F00000 +D6F6:04083F880E0811080E0800087FE802780208000003F80020002000D003080000 +D6F7:04083F880E0811080E0800087FE8027802080000004003F8004000A003180000 +D6F8:04083F880E0811080E0800087FE802780208000003F8000803F8000800080000 +D6F9:04083F880E0811080E0800087FE802780208000003F8020003F8020003F80000 +D6FA:04083F880E0811080E0800087FE802780208000000000FF8022002200FF80000 +D6FB:04083F880E0811080E0800087FE802780208000000800FF803E0041003E00000 +D6FC:0000040A040A3F8A000A1F0A208A208A1F0A000A7FEA040A047A040A040A0000 +D6FD:04283FA80E2811280E2800287FA805E804280000000007F80008000800080000 +D6FE:04283FA80E2811280E2800287FA805E80428000000003EF80208020802080000 +D6FF:04283FA80E2811280E2800287FA805E80428000000001F080108011401620000 +D700:04283FA80E2811280E28002800287FA8042805E804281428100010001FF80000 +D701:04283FA80E2811280E2800287FA805E804280000000020F8201020303ECC0000 +D702:04283FA80E2811280E2800287FA805E804280000202021FC207020883E700000 +D703:04283FA80E2811280E2800287FA805E80428000003F802000200020003F80000 +D704:04283FA80E2811280E2800287FA805E80428000007F8000807F8040007F80000 +D705:04283FA80E2811280E2800287FA805E8042800003EF802083E0820083E080000 +D706:04283FA80E2811280E2800287FA805E8042800003EF802883E8820883EF80000 +D707:04283FA80E2811280E2800287FA805E8042800003E8802883EF820883EF80000 +D708:04283FA80E2811280E2800287FA805E8042800000F8800880F8808140FA20000 +D709:04283FA80E2811280E2800287FA805E8042800003EF802803EF820803EF80000 +D70A:04283FA80E2811280E2800287FA805E8042800003EFC02483E4820483EFC0000 +D70B:04283FA80E2811280E2800287FA805E8042800003E1002FE3E3820443E380000 +D70C:04283FA80E2811280E2800287FA805E80428000003F802080208020803F80000 +D70D:04283FA80E2811280E2800287FA805E8042800000208020803F8020803F80000 +D70E:04283FA80E2811280E2800287FA805E804280000210821083F0821143F620000 +D70F:04283FA80E2811280E2800287FA805E804280000001000100010006801840000 +D710:04283FA80E2811280E2800287FA805E8042800000048004800A8011406620000 +D711:04283FA80E2811280E2800287FA805E804280000000003F00408040803F00000 +D712:04283FA80E2811280E2800287FA805E80428000003F80020002000D003080000 +D713:04283FA80E2811280E2800287FA805E804280000004003F8004000A003180000 +D714:04283FA80E2811280E2800287FA805E80428000003F8000803F8000800080000 +D715:04283FA80E2811280E2800287FA805E80428000003F8020003F8020003F80000 +D716:04283FA80E2811280E2800287FA805E80428000000000FF8022002200FF80000 +D717:04283FA80E2811280E2800287FA805E80428000000800FF803E0041003E00000 +D718:0000040804083F8800081F08208820881F0800087FE804080408040804080000 +D719:04083F880E0811080E0800087FE8020802000000000007F80008000800080000 +D71A:04083F880E0811080E0800087FE802080200000000003EF80208020802080000 +D71B:04083F880E0811080E0800087FE802080200000000001F080108011401620000 +D71C:04083F880E0811080E08000800087FE80208020802081008100010001FF80000 +D71D:04083F880E0811080E0800087FE8020802000000000020F8201020303ECC0000 +D71E:04083F880E0811080E0800087FE8020802000000202021FC207020883E700000 +D71F:04083F880E0811080E0800087FE802080200000003F802000200020003F80000 +D720:04083F880E0811080E0800087FE802080200000007F8000807F8040007F80000 +D721:04083F880E0811080E0800087FE80208020000003EF802083E0820083E080000 +D722:04083F880E0811080E0800087FE80208020000003EF802883E8820883EF80000 +D723:04083F880E0811080E0800087FE80208020000003E8802883EF820883EF80000 +D724:04083F880E0811080E0800087FE80208020000000F8800880F8808140FA20000 +D725:04083F880E0811080E0800087FE80208020000003EF802803EF820803EF80000 +D726:04083F880E0811080E0800087FE80208020000003EFC02483E4820483EFC0000 +D727:04083F880E0811080E0800087FE80208020000003E1002FE3E3820443E380000 +D728:04083F880E0811080E0800087FE802080200000003F802080208020803F80000 +D729:04083F880E0811080E0800087FE80208020000000208020803F8020803F80000 +D72A:04083F880E0811080E0800087FE8020802000000210821083F0821143F620000 +D72B:04083F880E0811080E0800087FE8020802000000001000100010006801840000 +D72C:04083F880E0811080E0800087FE80208020000000048004800A8011406620000 +D72D:04083F880E0811080E0800087FE8020802000000000003F00408040803F00000 +D72E:04083F880E0811080E0800087FE802080200000003F80020002000D003080000 +D72F:04083F880E0811080E0800087FE8020802000000004003F8004000A003180000 +D730:04083F880E0811080E0800087FE802080200000003F8000803F8000800080000 +D731:04083F880E0811080E0800087FE802080200000003F8020003F8020003F80000 +D732:04083F880E0811080E0800087FE802080200000000000FF8022002200FF80000 +D733:04083F880E0811080E0800087FE802080200000000800FF803E0041003E00000 +D734:0000010001000FE0000007C00820082007C000007FFC04400440044004400000 +D735:01000FE007C00820082007C000007FFC044004401FF000100010001000100000 +D736:01000FE007C00820082007C000007FFC0440044000003EF80208020802080000 +D737:01000FE007C00820082007C000007FFC0440044000001E100210022802C40000 +D738:01000FE007C00820082007C0000000007FFC044004401440100010001FF00000 +D739:01000FE007C00820082007C000007FFC04400440000020F8201020303ECC0000 +D73A:01000FE007C00820082007C000007FFC04400440202021FC207020883E700000 +D73B:01000FE007C00820082007C000007FFC044004401FF01000100010001FF00000 +D73C:01000FE007C00820082007C000007FFC044004401FF000101FF010001FF00000 +D73D:01000FE007C00820082007C000007FFC044004403EF802083E0820083E080000 +D73E:01000FE007C00820082007C000007FFC044004403EF802883E8820883EF80000 +D73F:01000FE007C00820082007C000007FFC044004403E8802883EF820883EF80000 +D740:01000FE007C00820082007C000007FFC044004403E1002103E1020283EC40000 +D741:01000FE007C00820082007C000007FFC044004403EF802803EF820803EF80000 +D742:01000FE007C00820082007C000007FFC044004403EFC02483E4820483EFC0000 +D743:01000FE007C00820082007C000007FFC044004403E2003FC3E7020883E700000 +D744:01000FE007C00820082007C000007FFC044004401FF01010101010101FF00000 +D745:01000FE007C00820082007C000007FFC04400440101010101FF010101FF00000 +D746:01000FE007C00820082007C000007FFC04400440222022203E2022503E880000 +D747:01000FE007C00820082007C000007FFC0440044000000100010002800C400000 +D748:01000FE007C00820082007C000007FFC044004400000024002400DA033100000 +D749:01000FE007C00820082007C000007FFC04400440000007C00820082007C00000 +D74A:01000FE007C00820082007C000007FFC04400440000007E00080014006200000 +D74B:01000FE007C00820082007C000007FFC04400440008007E00080014006200000 +D74C:01000FE007C00820082007C000007FFC044004401FF000101FF0001000100000 +D74D:01000FE007C00820082007C000007FFC044004401FF010001FF010001FF00000 +D74E:01000FE007C00820082007C000007FFC0440044000001FF0044004401FF00000 +D74F:01000FE007C00820082007C000007FFC0440044001001FF007C0082007C00000 +D750:0000010001000FE0000007C00820082007C0000000007FFC0000000000000000 +D751:01000FE007C00820082007C0000000007FFC00001FF000100010001000100000 +D752:01000FE007C00820082007C0000000007FFC000000003EF80208020802080000 +D753:01000FE007C00820082007C0000000007FFC000000001E100210022802C40000 +D754:01000FE007C00820082007C0000000007FFC000000001000100010001FF00000 +D755:01000FE007C00820082007C0000000007FFC0000000020F8201020303ECC0000 +D756:01000FE007C00820082007C0000000007FFC0000202021FC207020883E700000 +D757:01000FE007C00820082007C0000000007FFC00001FF01000100010001FF00000 +D758:01000FE007C00820082007C0000000007FFC00001FF000101FF010001FF00000 +D759:01000FE007C00820082007C0000000007FFC00003EF802083E0820083E080000 +D75A:01000FE007C00820082007C0000000007FFC00003EF802883E8820883EF80000 +D75B:01000FE007C00820082007C0000000007FFC00003E8802883EF820883EF80000 +D75C:01000FE007C00820082007C0000000007FFC00003E1002103E1020283EC40000 +D75D:01000FE007C00820082007C0000000007FFC00003EF802803EF820803EF80000 +D75E:01000FE007C00820082007C0000000007FFC00003EFC02483E4820483EFC0000 +D75F:01000FE007C00820082007C0000000007FFC00003E2003FC3E7020883E700000 +D760:01000FE007C00820082007C0000000007FFC00001FF01010101010101FF00000 +D761:01000FE007C00820082007C0000000007FFC0000101010101FF010101FF00000 +D762:01000FE007C00820082007C0000000007FFC0000222022203E2022503E880000 +D763:01000FE007C00820082007C0000000007FFC000000000100010002800C400000 +D764:01000FE007C00820082007C0000000007FFC00000000024002400DA033100000 +D765:01000FE007C00820082007C0000000007FFC0000000007C00820082007C00000 +D766:01000FE007C00820082007C0000000007FFC0000000007E00080014006200000 +D767:01000FE007C00820082007C0000000007FFC0000008007E00080014006200000 +D768:01000FE007C00820082007C0000000007FFC00001FF000101FF0001000100000 +D769:01000FE007C00820082007C0000000007FFC00001FF010001FF010001FF00000 +D76A:01000FE007C00820082007C0000000007FFC000000001FF0044004401FF00000 +D76B:01000FE007C00820082007C0000000007FFC000001001FF007C0082007C00000 +D76C:00000008040804083F8800081F08208820881F0800087FE80008000800080000 +D76D:000004083F880E08110811080E0800087FE8000007F800080008000800080000 +D76E:000004083F880E08110811080E0800087FE8000000003EF80208020802080000 +D76F:000004083F880E08110811080E0800087FE8000000001F080108011401620000 +D770:000004083F880E08110811080E0800087FE8000008000800080008000FF80000 +D771:000004083F880E08110811080E0800087FE80000000010F8101010301ECC0000 +D772:000004083F880E08110811080E0800087FE800000808087F081C08220F9C0000 +D773:000004083F880E08110811080E0800087FE8000003F802000200020003F80000 +D774:000004083F880E08110811080E0800087FE8000007F8000807F8040007F80000 +D775:000004083F880E08110811080E0800087FE800003EF802083E0820083E080000 +D776:000004083F880E08110811080E0800087FE800003EF802883E8820883EF80000 +D777:000004083F880E08110811080E0800087FE800003E8802883EF820883EF80000 +D778:000004083F880E08110811080E0800087FE800001F0801081F0810141F620000 +D779:000004083F880E08110811080E0800087FE800003EF802803EF820803EF80000 +D77A:000004083F880E08110811080E0800087FE800003EFC02483E4820483EFC0000 +D77B:000004083F880E08110811080E0800087FE800001F08017F1F1C10221F1C0000 +D77C:000004083F880E08110811080E0800087FE8000003F802080208020803F80000 +D77D:000004083F880E08110811080E0800087FE800000208020803F8020803F80000 +D77E:000004083F880E08110811080E0800087FE80000110811081F0811141F620000 +D77F:000004083F880E08110811080E0800087FE80000001000100010006801840000 +D780:000004083F880E08110811080E0800087FE800000048004800A8011406620000 +D781:000004083F880E08110811080E0800087FE80000000003F00408040803F00000 +D782:000004083F880E08110811080E0800087FE8000003F80020002000D003080000 +D783:000004083F880E08110811080E0800087FE80000004003F8004000A003180000 +D784:000004083F880E08110811080E0800087FE8000003F8000803F8000800080000 +D785:000004083F880E08110811080E0800087FE8000003F8020003F8020003F80000 +D786:000004083F880E08110811080E0800087FE8000000000FF8022002200FF80000 +D787:000004083F880E08110811080E0800087FE8000000800FF803E0041003E00000 +D788:00000000040804083F880E08110820882088208811080E080008000800080000 +D789:000008087F081C082208220822081C0800080000000007F80008000800080000 +D78A:000008087F081C082208220822081C080008000000003EF80208020802080000 +D78B:000008087F081C082208220822081C080008000000001F080108011401620000 +D78C:000008087F081C082208220822081C080008000800001000100010001FF80000 +D78D:000008087F081C082208220822081C0800080000000020F8201020303ECC0000 +D78E:000008087F081C082208220822081C0800080000202021FC207020883E700000 +D78F:000008087F081C082208220822081C080008000003F802000200020003F80000 +D790:000008087F081C082208220822081C080008000007F8000807F8040007F80000 +D791:000008087F081C082208220822081C08000800003EF802083E0820083E080000 +D792:000008087F081C082208220822081C08000800003EF802883E8820883EF80000 +D793:000008087F081C082208220822081C08000800003E8802883EF820883EF80000 +D794:000008087F081C082208220822081C08000800000F8800880F8808140FA20000 +D795:000008087F081C082208220822081C08000800003EF802803EF820803EF80000 +D796:000008087F081C082208220822081C08000800003EFC02483E4820483EFC0000 +D797:000008087F081C082208220822081C08000800003E1002FE3E3820443E380000 +D798:000008087F081C082208220822081C080008000003F802080208020803F80000 +D799:000008087F081C082208220822081C08000800000208020803F8020803F80000 +D79A:000008087F081C082208220822081C0800080000210821083F0821143F620000 +D79B:000008087F081C082208220822081C0800080000001000100010006801840000 +D79C:000008087F081C082208220822081C08000800000048004800A8011406620000 +D79D:000008087F081C082208220822081C0800080000000003F00408040803F00000 +D79E:000008087F081C082208220822081C080008000003F80020002000D003080000 +D79F:000008087F081C082208220822081C0800080000004003F8004000A003180000 +D7A0:000008087F081C082208220822081C080008000003F8000803F8000800080000 +D7A1:000008087F081C082208220822081C080008000003F8020003F8020003F80000 +D7A2:000008087F081C082208220822081C080008000000000FF8022002200FF80000 +D7A3:000008087F081C082208220822081C080008000000800FF803E0041003E00000 +D7A4:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61B66DB661866DF66DF67FFE0000 +D7A5:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866DBE61866DF66D867FFE0000 +D7A6:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000 +D7A7:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000 +D7A8:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000 +D7A9:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000 +D7AA:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866DB661866DB66DB67FFE0000 +D7AB:00007FFE63866DF66DEE6DDE63DE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000 +D7AC:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000 +D7AD:00007FFE63866DF66DEE6DDE63DE7FFE7FFE618E6DB661B66DB66D8E7FFE0000 +D7AE:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866DBE618E6DBE6D867FFE0000 +D7AF:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000 +D7B0:0040003000100010001003F00110001003F0011000100C1004D0071078100000 +D7B1:00000000000000000000000000000000030001001FF001003FF8000003000100 +D7B2:004000300010001000100010001000100010001001900C9C04F0071078100000 +D7B3:0048003600120012001200120012001200120012031E191209F20F1278020000 +D7B4:00080006000200020002000200020002001E00020302193209C20F0278020000 +D7B5:0008000600020002000200020002000200023FF20202021E0202021E00020000 +D7B6:0010008C006400240024002400240024002400247FE404240424042400040000 +D7B7:00480036001200120012001200120012001E00127FF211121112111200020000 +D7B8:00000000000000000000000000000000000000003FF808200BA000803FFC0000 +D7B9:00800060002000200020002000200020003C00200020002000E0072078200000 +D7BA:00080006000200020002000200020002001E00020002000200E2070278020000 +D7BB:00480036001200120012001200120012007200120012001200D2071278020000 +D7BC:00000000000000000000000000000000000000003FF80000038000803FFC0000 +D7BD:00000040013000D000500050005C00500050005C005000500E1002003FFC0000 +D7BE:0090046C03240124013C01240124013C01240124012401240024000400000000 +D7BF:011000CC00440044005C00440044005C00440044004400440044000400000000 +D7C0:0410034C01340114011401740114011401740114011401140114001400040000 +D7C1:000000200018000800080008000800080008070801003FF80000070001000100 +D7C2:00000020001800080008000800080008000839C808403FF80000000000000000 +D7C3:000000200018000800080008000800080008000800003FF80840084000000000 +D7C4:0048003600120012001200120012001200120012001200120012001200020000 +D7C5:00800060002000200020002000200020003C0020302038200820002000200000 +D7C6:0010008C00640024002400240024002401E40024302438240824002400040000 +D7C7:00007FFE63866DF66DEE6DDE63DE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000 +D7C8:00007FFE63866DF66DEE6DDE63DE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +D7C9:00007FFE63866DF66DEE6DDE63DE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +D7CA:00007FFE63866DF66DEE6DDE63DE7FFE7FFE71866FB66F866FB671B67FFE0000 +D7CB:0000000000000000000000000000000060FE2002200220FE2080268038FE0000 +D7CC:000000000000000000000078C00043FE402040304C4871840000000000000000 +D7CD:000000000000000000000000000000000000FDF8208020802080268018780000 +D7CE:00000000000000000000000000000000FFB62212221E22122212265E19920000 +D7CF:00000000000000000000000000000000FD98208820F82088208826F818880000 +D7D0:0000000000000000000000000000000000007C38200820082018262438C20000 +D7D1:00000000000000000000000000000000000078EE2022202220622492390A0000 +D7D2:0000000000000000000000000000000000007C7E200820082018262438C20000 +D7D3:00000000000000000000000000000000003C7C00207E20082018262438C20000 +D7D4:00000000000000000000000000000000000000007EFC1040107C13400C3C0000 +D7D5:00000000000000000000000000000000000000003DDC04443C4420443C440000 +D7D6:0000000000000000000000000000001C3DC0047E04483C5C206220623C5C0000 +D7D7:00000000000000000000000000000000000000007BDC08447BDC42047BC40000 +D7D8:0000000000000000000000000000001C7BC00A7E0A487A5C426243E27A1C0000 +D7D9:000000000000000000000000000004807A5E0A480BC87A48424843C87A4E0000 +D7DA:0000000000000000000000000000049E7A440A420BD27A4A424243C47A5E0000 +D7DB:000000000000000000000000000000083C08041C04223C22202220223C1C0000 +D7DC:0000000000000000000000000000000EF780101F1304F48E84918491F30E0000 +D7DD:000000000000000000001FF800081FF810001FF8000003E00410041003E00000 +D7DE:0000000000000000000000000000000000007DC044404440444044407C3E4000 +D7DF:0000000000000000000000000000000000007B30491049104910491078CC4000 +D7E0:00000000000000000000000000000000000000003E7C2244224422443E7C2040 +D7E1:0000000000000000000000000000000000000480F4889784948C9492F7A18000 +D7E2:00000000000000000000000000000000000000003EFC2220223022483E842000 +D7E3:000000000000000000000000000000004400227C22203E20222022203E3C0000 +D7E4:0000000000000000000000000000000049DE244424523DCA250225043DDE0000 +D7E5:000000000000000000000000000000004400227C22443E44224422443E7C0040 +D7E6:000000000000000000000000000000004488224422443E7C224422443E7C0000 +D7E7:000000000000000000000000000000009000485E4848788849484A287A2E0000 +D7E8:000000000000000000000000000000004400220022FC3E20223022483E840000 +D7E9:000000000000000000000000000000004478220022FC3E20223022483E840000 +D7EA:0000000000000000000000000000000000000800047C04440C441244617C0040 +D7EB:00000000000000000000000000000044007C0844047C04000C38124461380000 +D7EC:000000000000000000000000000000000000123C0904090419042684CC440000 +D7ED:000000000000000000000000000000000000123E0910091019102690CC5E0000 +D7EE:00000000000000000000000000000000000010200810082818442482C2FE0000 +D7EF:000000000000000000000000000000000000000010FC082018302448C2840000 +D7F0:000000000000000000000000000000000078100008FC082018302448C2840000 +D7F1:000000000000000000000000000000000000100008FC0840187C2440C23C0000 +D7F2:000000000000000000000000000000380000107C0810083818442444C2380000 +D7F3:0000000000000000000000000000000001102088108828F844888288FEF80000 +D7F4:0000000000000000000000000210010801F8210811F8287044888270FE000000 +D7F5:000000000000000000000000000000000800087C1C442244224422441C7C0040 +D7F6:000000000000000000000000000000380800087C1C102238224422441C380000 +D7F7:00000000000000000000000000000000000000003F4404440C7C1244217C0040 +D7F8:000000000000000000000000000000000000000001297D2911EF292945EF0108 +D7F9:00000000000000000000000000000000000000007EFC08201830244842840000 +D7FA:000000000000000000000000000000007800104048202820086010907B080000 +D7FB:0000000000000000000000000000000078FC10404840287C08401040783C0000 +D7FC:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +D7FD:00007FFE63866DF66DEE6DDE63DE7FFE7FFE618E6FB663B66FB66F8E7FFE0000 +D7FE:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866FBE638E6FBE6F867FFE0000 +D7FF:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +F900:0080108810881FF8100800007FFE00000FF008100FF00810042002447FFE0000 +F901:00047FFE008010841FFE10841FFC10841FFC10840880050003000CC0703E0000 +F902:010001047FFE010011081FFC11081FF811081FF8110801047FFE010001000000 +F903:FFFE04403FF824483FF800001FF010101FF010101FF010101FF00C60F01E0000 +F904:410821FC21080978894857FE540421F82108C1F8410841F8C108C13841100000 +F905:010001083FFC210821083FF8210801047FFE410441047FFC4104010001000000 +F906:0800080008041FFE200440041FC41044104410441FC410440044003800100000 +F907:08400FE0084010807FFC11447F7C05447F6C05547D6C05447F7E05027CFC0000 +F908:08400FE0084010807FFC11447F7C05447F6C05547D6C05447F7E05027CFC0000 +F909:080008027F7E08127F1208127F22084E098401007FFE020002C00C30700E0000 +F90A:0080018002400420081010086FF6010001083FFC01001118091009247FFE0000 +F90B:01029142FFE29112911297D29552955297D29552F39295420922111E01040000 +F90C:020002047FFE02400420181867E6000000083FFC00801890108C238441040000 +F90D:2214221E2FD42224B27EAFA2AABEAAA22FBE2222233E26A22A94222222422000 +F90E:010010841FFE92205FBC52481FBE12A232BEDFA2923E232226BE4A9492220000 +F90F:3FFC224422443FFC0844109024FE79900A9014FC7E9000FC34902A904AFE0000 +F910:04207FFE04201FF812481FF808A012903DFE0A9014FC7E9028FC549054FE0000 +F911:110411FE112455FC7F2455FC544455F87C2455FE109214101A94E37242220000 +F912:41FC21242924FDFC092411FC2524282073FEAC20247020A82126222220200000 +F913:07FE4492349217FE024804FE1748FAFE17C8107E15481AFE3040C80087FE0000 +F914:2108210847D05454E7F824485454FFFE45500104FFFE05200910310EC1040000 +F915:2100110811FC010842902C9028601198160661F821082108610861F821080000 +F916:1080108810FC108855505920523050C8930610FC18842484248440FC80840000 +F917:00800888FCFC1108129010601060FD98120611F815081908E10841F801080000 +F918:04407FFE0440244011F8150845902A600890110817FE6108210821F861080000 +F919:0420FE24283E2824FE44AAA8AA10AA28CE4482FEFE4482448244FE7C82440000 +F91A:44407E48487C48887F4848307E3048487E8643FC02845684AA84AAFC0C840000 +F91B:0720F92091204A20FF201420FFA092A0BDA080A0BEA094A28CA292A2A39E0000 +F91C:02002744387E224432442A542A54224C224426443A44225C0448084070400000 +F91D:13DE125213DEFE5213DE12223BFE562253FE92AA93FE1222127212AA13260000 +F91E:13DE125213DE125257DE5A2253FE522293FE12AA1BFE262222B2432E82240000 +F91F:04207FFE04207EFC42847EFC42847EFC41045FF44AA44FE441044544593C0000 +F920:1208110827D0783C2792783E2BA852940FE008200FF808000FFE292244940000 +F921:0080208420843FFC00003FF820282FC821082FE829282FEA410A41269FD20000 +F922:47D02510251407DE845057D85524252427C0C00047FC44A4C4A4C4A44FFE0000 +F923:04207FFE04203F0024243F3E21403F9024083F8800001FF8124812487FFE0000 +F924:43E822882A88FFCE0A5013E826842A8473E0A80027F822A822A822A827FE0000 +F925:100010401020FC2413FE1000140C1908F1085090109010909020702427FE0000 +F926:49247E484A4849244BFC7AA44A544BFC48407B684AD84B684ADABB6692420000 +F927:212422482248A924FFFCAAA4AA54ABFCF800AB6822D82B6836DAE26643420000 +F928:010020843FFE240022BE2FE428A42FA828A82FA428A229322BAC4CA088200000 +F929:10444A7E7F44424442447E7C424442447E444A7C44444A4452A4E11C42080000 +F92A:2080124813FC020842082BF82A08120813F86244224822306290670822060000 +F92B:00404C20292411FE310449FC890419FC294249448928091049483B8611020000 +F92C:1024093E3FA4212421283F28212821243F242122242222322D2C712020200000 +F92D:010001047FFE010011101110111029284384054009201110210C410401000000 +F92E:0040804060A02890090812461422282023FCC0084010402041C0402000100000 +F92F:04101554165824900A2811443FFE200241043FF8010802080488087030200000 +F930:107C124013FEFE4413FA124216FE1AA4F3FE52A412FC122095FE7842239C0000 +F931:109010F81110FFFC112411FC392455FC5554924A91FC110411FC110411FC0000 +F932:107C124013FE124457FA5A4252FE52A892F812A81AF8240025FC495497FE0000 +F933:011001F821003FFE21042FF8210223FE224823F822482FFC292449249FFE0000 +F934:01000100010C3FE8011001247FFE0080010006300CC017046404040603FC0000 +F935:04207FFE04A010F81FFE11041FF8110213FE124813F8124817F825285FFE0000 +F936:01F801003FFE21042FF0210227FE24483FFE244827F820802FFC41048E380000 +F937:00407C44447E448445487C305448108651025CFC508450845C84F0FC40840000 +F938:1FF841027FFE81043D7801403E7822483ED02B30084E2EF828887EF820880000 +F939:04400FE010883FFC51081FF811081FF8244422224FF208100FF008100FF00000 +F93A:3E7C22443EB808442EFA28887FF810101FF010101FFC10001FFE292244940000 +F93B:0044047CFE88108811F020103FFE6420A52224B4246827A43D2224E200400000 +F93C:208410FC1088FD0805F0081013FE3020592C94A8147010A8172612E210400000 +F93D:108810FC2088250845F0F81013FE2820FD2C44A8007028A8552656E280400000 +F93E:042004207FFE042003E0022007E000447FFE108808D006A00890738E21040000 +F93F:1044187C1444228840F8FC1011FE1020FF2694B4586851A81E26F0E240400000 +F940:010020843FFE222022243FFE22243FFC280428202FA4283829A25E22883E0000 +F941:202010201050FC88010602FA780003FE7A5202527BFE4A524A527A524A460000 +F942:087E7F40147C7F04227C3E40227C3E40227E2E42243E00801FF800847FFE0000 +F943:7FFC010001103FF8010001047FFE082008247FFE082008201020202040200000 +F944:10401F7E289045483F7E2240147C7F04227C3E40227C3E40227C2242263E0000 +F945:08807EFC14807FFC22043EFC22803EFE22827FFE08100FF008107FFE00100000 +F946:010020843FFE2004490809100FF81100210001047FFE01000100010001000000 +F947:00047FFE020007F00C10141067F002047F7E10201E3C326452A41E3C12240000 +F948:44807E8444FE44847D48463044487C86450244FC7C844484288444FC84840000 +F949:1FF841027FFE81043D7801003D78010020083FFC21083FF821083FF820080000 +F94A:1FF011101FF011101FF01010FEFE9292FEFE9292FEFE01103FF80104FFFE0000 +F94B:3FFC200420043FFC24883FFE24882FFC28842FFC21003FFE222041609F9E0000 +F94C:102011FC112413FEFD2411FC182035FC552451FC904097FE1090107017CE0000 +F94D:2080124413FE020442042BFC2A041228122463FE222024506488690632020000 +F94E:440427FE240407FC840057FE542027FE2622C73246AA4B32CAAAD2AA62260000 +F94F:1FFC10841FFC10841FFC1104022004601F8002083FFC108404A01B9861060000 +F950:1020102021FC252447FEF92413FE2A22FFFE442003FE288855905460839E0000 +F951:8804F9FE88109090A2FEA292929292928AAA8AC6CA82B29E8284820083FE0000 +F952:22202220FFA022243EFE08247F24492449247F240844FF44088408BC09080000 +F953:24203E202420242425FE3C242424242424243C242444244424A45D1C88080000 +F954:00408FFE60002BFC0A9412F4120423FC2000C3F840404FFE4248444408420000 +F955:0040804863FC2840084417FE11082204248AC1FC430844904860419E0E040000 +F956:04200E28F1FC102015FEFE481086194236785088914812301050118E16040000 +F957:102011FC2020242447FEF88811042A82FCF84508028828505460559886060000 +F958:042004207FFE05201FF801007FFE04201A1863F604201A4001800670780E0000 +F959:8848FBFC88409044A7FEA090910C928488F88988CA90B4A0806081988E060000 +F95A:202013FEFC2001FC00007BFE025203FE790401FC790449FC490479FC4B060000 +F95B:080408FE7F44122824101A2811C660381FC000881FFC00807FFE008007800000 +F95C:2108210847D05454E7F824485454FFFE45500104FFFE05200910310EC1040000 +F95D:2088108813FEFC8800A80020782403FE784000FC79844A844C8478FC48840000 +F95E:00100FF80810081009100890089008107FFE0810081010101090207040200000 +F95F:010020843FFE250454A827E400001FF812487FFE00003FFC0080078001000000 +F960:080008040BFE7E44124424481C300A48118660020500248824A6242243F00000 +F961:010000847FFE01042248179001001A5067EC452401007FFE0100010001000000 +F962:10081FFC11081FF811081FF8144804403FFC044004447FFE0420181860060000 +F963:088008800880088C0888F89008E008800880088008801884E8844886087C0000 +F964:000E09F0FC26212420A823FE3CA86524A62225FE252225FE3D2225FE21020000 +F965:100417FE1040244427FE244467FCA44427FC244422402140208021402E3E0000 +F966:190411FE220045FC990411FC210461FCA08021FC230824902060219826060000 +F967:00047FFE008000800100030005200910110C2106410201000100010001000000 +F968:20001040102404244488288828881290129464A224A220C061846284247E0000 +F969:08407F404940FFC4497E7FC808487F4849487F481028FF90222C1C46F3820000 +F96A:01083FFC010021043FFE210442281FC0011002083FF4008404A01B9861060000 +F96B:0100022007D0101024247B7E018202407CBC03001C4001981E6001801E000000 +F96C:010020823FFE42241FFC02201FFC02207FFE0490088817F6208200847FFE0000 +F96D:01000D10090811662142408001080FFC18086FF808080FF808080FF808080000 +F96E:04207FFE042009107FFE091009F008000FFC00807FFE02C004A0189860860000 +F96F:210810881090FE2001FC0104FD040104FDFC0154FC5084508492FD12860E0000 +F970:028842FC248818882688410E140012FCFF84104838485430922810C613020000 +F971:10041FFE1000101017F8100010041FFE124012481250222022904F0884060000 +F972:204010401040024443FE2A442C48104010406040204020A061226222241E0000 +F973:1040104010A0FD101208100615FA1800F10851FC11081108910871F821080000 +F974:042004207FFE04200420010001047FFE020004080FFC1408640807F804080000 +F975:104010201024FFFE100011FC15041904F1FC5124102011A8912472E224420000 +F976:008044847EFE54845548543054487C86550254FC54847C84448400FC00840000 +F977:020001047FFE00000FF008100FF000003FFE200247C4044004421842603E0000 +F978:00047FFE010001047FFE41045144492449245554659441044124411C40080000 +F979:00808040604427FE080013FC1204220423FCC22440204230452848E410440000 +F97A:10080BFC4048254C094A0A4A30B8131010847FFE02C004A00890108E60840000 +F97B:11FC110495FC550459FC1000FDFE112419FC352455FC902011FC102013FE0000 +F97C:010008900FF8081008100FF0081008100FF00900088C08700B203C1810060000 +F97D:204010201024FFFE000001FC7D0401047DFC01247CA844A445227EE244400000 +F97E:1FF010101FF010101FF000047FFE11101FF011101FF001003FF801007FFE0000 +F97F:7FD049107FD049125FFE52525FD252525FD242125FD2525253D29C6E90C40000 +F980:08100FF80810081008100FF00910010012081FFC1008100810081FF810080000 +F981:020003000200020002047FFE042004200820082010400E8001800670780E0000 +F982:21043FFE208020F828802FFE28842FF82A4A2BFE2A482FF82D285528AFFE0000 +F983:104008400844FEFE2080251C3EE024A624A424982490249024A85DC688820000 +F984:4048207C244007FE844457FA544225FE2524C5FC452445FCCA94CA8A44FA0000 +F985:03FE0A48FFFE224822FC22947AFCCA944AFC4A104AFE4A927AFA4C8608820000 +F986:7E7E42427E7E42427E7E400247E2442247E241024FF248124FF2481E40040000 +F987:89DCFC0093FE92AAFEAA9020FDFE9150FDFC855405FC5594AED8A49218EE0000 +F988:3E7C00003E7C2A542B5400803FFC22403FF822483FF828522F6248429F3E0000 +F989:0E407842087E7E920C221A42299E4A4404A01898649603E004903B8C11040000 +F98A:01000100010001083FFC01080108010801080208020804080888107060200000 +F98B:3FFE21082E7022143FFE221027382AD4329227F8240827F8240847F884080000 +F98C:20043FFE20842F7822103FFE221027382AD6321220402440247C44409FFE0000 +F98D:21242124FD7422DAFB74A954FAFAAF56F820A82423FEFEB02128222624220000 +F98E:0C0008080FFC1080208048880FFC0880088008847FFE00800080008000800000 +F98F:124C1148115017FE58D055485246920813BE14881AA8117E1108120814080000 +F990:1204110427C8701C23C84812FBFE5254AA6AABAA040025042492241243F80000 +F991:1210121413D2FA9012FE159012901990F12852461C8210009324749228920000 +F992:4020282427FE042081FC512455FC2F2425FCC42047FE4420C420DA2051FE0000 +F993:1020102413FE102057FE5A22532652AA93FE1222187024A82526422280200000 +F994:00101410FAFE2210207E2052207EFF52217E2152211039FEE1104690047E0000 +F995:002000F03F000104FFFE054009203118C0761F800108FFFC0100010001000000 +F996:102413FE202027FE4622FB2612AA2BFEFA224420007028A85526562280200000 +F997:0488FE88255227BC3C88255427DC3C22255427542D54F5DC4454049005100000 +F998:08103F7C08107F7E142822C440823FFE08880FF808880FF800807FFE00800000 +F999:04207FFE0420204017FC104003F8024873F8124813F8104017FC684047FE0000 +F99A:0040404437FE104003FC024413FCFA4413FC1244104017FE3040C84087FE0000 +F99B:1020182415FE222041FEFD2211A6116AFFFE9522587050A81F26F22240200000 +F99C:01027F820822082209220FA21122312249220A22042204020812100E60040000 +F99D:0100010019181106211A402001C00680188467FE0084010402240C1C30080000 +F99E:020293FEFA229222922293FA9222922292629252F28A930A020203FE02020000 +F99F:01047F84082408240FA41124312449240A04041C780800002444222242220000 +F9A0:01047FA408241F2431240A243D1C00887FFE028004480C50742007180C060000 +F9A1:210810881090FE2001FC0104FD040104FDFC0154FC5084508492FD12860E0000 +F9A2:21043FFE222021442FFE21402FF821483FFE21482FF8214023604550994C0000 +F9A3:01000280044008201110608C00000FE000200140048024842412441203F80000 +F9A4:102010201050FC881126121215FC1808F010501012C412A2928A7488207C0000 +F9A5:0420FE202050208825763E0225DC6554955415DC0800088810882156C2220000 +F9A6:10401F7E28907FFE24202FFC22402FF822483FFE22482FF826504A48B2460000 +F9A7:01244E482A48112433FC4A548AA41BFC28404B688AD80B6A4A5A3B6612420000 +F9A8:008001800240042009101088208640121FF8001000200640018000C000400000 +F9A9:20043FFE2104218422442524389C20042FF420442384208420843FFC20040000 +F9AA:010020843FFE250454A827E400001FF812487FFE00003FFC0080078001000000 +F9AB:108410841FFC00000BFE142022FC498404FC7F8402FC048438FC044805860000 +F9AC:1040104010A011105A0854465422902013FC1008101010A01060103010100000 +F9AD:00200860FC501088110412421022FC20100811FC14081810E0E0401000100000 +F9AE:08102A542C584890142822447FFE40043FF8010001001FF8012001147FFE0000 +F9AF:442024202850FE50108810A67D12101010FCFE04100810D02020401080100000 +F9B0:0220FF20245024503C88254626223C20240025FC2E08F4484430041004100000 +F9B1:10201820145022884106FE4210201020FE0495FE580850501E20F01040100000 +F9B2:1FF841027FFE81043D7801003D7806C01930E08E0FF000200040038000600000 +F9B3:1FF841027FFE81043D7801007BDE4A527BDE00007FFC091019302548FFFE0000 +F9B4:080409FE082014FC2284498484FC04847FFC0284248418FC0884085803860000 +F9B5:080008420FE21212125233F25452965219521092109211121102121E14040000 +F9B6:205011FC1154FDFC055409FC100033FE580095FC150411FC1088105013FE0000 +F9B7:0428FEFE28AA28FEFEAAAAFEAA00ABFECE0082FCFE8482FC8284FE4883FE0000 +F9B8:10201024FFFE18243424D3FE10247DFC0124FEA210B4586897A4B12210620000 +F9B9:00047FFE02403E7C200420043E7C02407FFE0000048024442452241243F80000 +F9BA:00083FFC00080010002000C00080008000800080008000800880078001000000 +F9BB:084008440FFE10A2151433F8560C9BFA120813F810401248144419C210420000 +F9BC:010020843FFE21045FFC24281FF028184FF608100FF000800CB0138C21040000 +F9BD:10041FFE100410041FFC104410401F4C1268125012502448244649C240800000 +F9BE:0808490849482A2828280A08FF4808280C281A0E2A3849C88888080808080000 +F9BF:2108210847D05454E7F824485454FFFE45500104FFFE05200910310EC1040000 +F9C0:1040104017FE14A2531455F85B0C55FA910811F818202528262444E288420000 +F9C1:008010441FFE90405FFE551413F8120C37FADA0893F82040225045C888860000 +F9C2:04207FFE042000007EFC12240E1C326403800C60771E00600F9800603F800000 +F9C3:0040404437FE1294010803FC150AF9F8110811F81128122634E2C84087FE0000 +F9C4:104008447F7E2240147C7F04007C3E40227C3E40227C3E40227E2E42243E0000 +F9C5:10101FF810101FF050127FFE81047FFC11101FF011101FF001007FFE01000000 +F9C6:44087DFC44004800500453FE48904890449044906490591242124412480E0000 +F9C7:180267C242524A525A5265929E122112DED204127F922492150217DE7C040000 +F9C8:100813FC10881088FC881088188837F854885088908890881088108817FE0000 +F9C9:104010D2131E1252FE5212521A523652525253D2925290561092111012100000 +F9CA:2080104417FE0040409029082BFC1004124862482248224A624A644A28460000 +F9CB:408025FE2612041284925562564E24842000C7FC444447FCC444C7FC44040000 +F9CC:00400824FDFE10201040108811FCFC041128112815281928E22A442A08260000 +F9CD:0200270438FE204422447D5C20881FF8108810881FF8108810881FF810080000 +F9CE:00400424FFFE1040108823FC3C846400A4A824A824A824A83D2A222A04260000 +F9CF:1000100423FE24444444F84410442844FDFC4484008428845484548487FE0000 +F9D0:49042AFE2A10087C7F441C442A7C49440A7C09447F44087C1444222842C60000 +F9D1:020001000180008000047FFE0000000004200420081008101008200640020000 +F9D2:F720112855243320552699F808201422E3A2082472280D12722A0C46F1820000 +F9D3:8840F8488BFC9040A044A7FE9090910C8A448840C848B3FC804080448FFE0000 +F9D4:0840086008901108121635FA500097FE1492149217FE14921492149214860000 +F9D5:0100210821083FF8210802800C60F7DE00003FF824483FF82448244824180000 +F9D6:204010C010A0011042082DF6280017FC14A464A427FC24A464A464BC24080000 +F9D7:10201020FE5010887D0656FA54007DFC55547D5455FC1154FF541154110C0000 +F9D8:184813FC204840489FFE104823F86048A04023FC2040204427FE204020400000 +F9D9:100417FE109013FE5A92569253FE9202102417FE102011B01128122614220000 +F9DA:00047FFE02401FF8124812481FF8108800847FFE02C004A00890108E60840000 +F9DB:010000847FFE01042248179001001A5067EC452401007FFE0100010001000000 +F9DC:8908FDFC8A089090A060A198960691F888008928CBFCB42081FC802087FE0000 +F9DD:010207827C1204120492FFD204120E1215122492449284020412040E04040000 +F9DE:008000847FFE008010841FFE108410841FFC108408800480030004C0783E0000 +F9DF:3FFC20043FFC208024FE298432FC228424FC2C40347C24C82530444885860000 +F9E0:08100FF808100FF008100FF0081004040FFE1124222444440884113802100000 +F9E1:010001047FFE05400920111861060FF0004000847FFE00800480038001000000 +F9E2:03043C2404247FA40C241624251C448800847FFE02C004A00890108E20840000 +F9E3:220413FE1204020443FC2A042A40124C124862502260244064426842303E0000 +F9E4:010409FEFD24112411FC11241124FDFC11241020142019FCE020402407FE0000 +F9E5:010010841FFE908051C25712111217D23112D192935225522902411E81040000 +F9E6:3FFC224422443FFC2044112011FE5B20552091FC112011FC1120112411FE0000 +F9E7:01047FFE00000FF808880FF808883FFC00807FFE028804501CA0651806060000 +F9E8:410421FE2924FD2409FC1124252429FC7124AC20242021FC2020202427FE0000 +F9E9:10081FFC110811081FF8110811081FF81108010001083FFC010001047FFE0000 +F9EA:10500848FFC8557E494849C8557E7F4808487F48497E55487B48417E47400000 +F9EB:40047FFE422042205FFC42A041045FFE420047F84A08520843F842087FFE0000 +F9EC:408227BE20820082879E5492541027BE28A2C4924186469AD8E2C71C42080000 +F9ED:010000847FFE08100420024001800E70700E1FF81008100810081FF810080000 +F9EE:1222112410A813FE54A859245222510891DE124819A824BE2508420884080000 +F9EF:02221124F8A823FE20A821242222FA0823BE228826A839FEE108420804080000 +F9F0:04207FFE04203E7C22443E7C22443E7C27E42C8437E4248427E4249C27E80000 +F9F1:8A4CF948895097FEA150A2489C4692088BBE8C88CAA8B13E8208840888080000 +F9F2:21243D2424A84BFCFCA8552456227D0855FE55487F4844E854BEAB08AA080000 +F9F3:08A444647F2854FE7F28556455A27F0454EE54A45D2456B4545E5D8497040000 +F9F4:08200820082008247FFE082008201CB02AA8292849244A240C22082208200000 +F9F5:42102210221002948FFE52105310229026B8CA5452525212C210C21042100000 +F9F6:8480FE8490FE910092F8FC88848884F88400FFDE925292529252FFDE82520000 +F9F7:02000100008000883FFC000008100810042004200240024000847FFE00000000 +F9F8:102010201F3E285044880100008000883FFC042004200240024000847FFE0000 +F9F9:104092209220540455FE1000FE84108418883448524852509010901013FE0000 +F9FA:044024502448244824403FFE045004507C502450244824482484450686020000 +F9FB:0200021007F80C203240088007000C807098089008A0114002200C1830060000 +F9FC:2110109013F4FD52015200907BFE00107BD202527BD44A484BCA7A5648220000 +F9FD:08400840084010401040304057FE904010401040104010401040104010400000 +F9FE:042004207FFE0420058002400420189860861FF8008004A00890108E60840000 +F9FF:08020882FFD208128892FFD2889288928B9288921C122A024992888E08040000 +FA00:2000200423FE204424442E44F044204422442444284430842144023804100000 +FA01:010020843FFE222022243FFE222023E0200027F82210212020C043309C0E0000 +FA02:1000100413FEFC4010401040148419FEF284548410841084908470FC20840000 +FA03:1040112495FE552059FC1124FDFE112419FC352055FC9284128414FC18840000 +FA04:020041087FFC4008809001C07E000410043807C0FC0004040404040603FC0000 +FA05:220413FE1204020446F42A042A0412F41294629422F422946204621C22080000 +FA06:1FF010101FF010101FF004403FFC04407FFE11102928474405C01930630C0000 +FA07:11FE1000FEFC10847C8454FC7C0055FE7D22552211FEFF22112211FE11020000 +FA08:180811FC200040000C040BFE1010301050109010101010101090107010200000 +FA09:44887CFC44884950502050504B8E482045FC44A065245BFE4020402040200000 +FA0A:00201FF0102010201FE0102010201FE0102010201FE014A408843086C07C0000 +FA0B:20843FFE22003FDE20122F9428942F9820143FD22112221A2F9442108E100000 +FA0C:0008FFFC08800880088008800880088008801080108420844086807C00000000 +FA0D:0848087C7F4808483F48008E7F0082FE3E4400443E28221022283E4622820000 +FA0E:10500848FEFE459026FC189008FC149024FEC0803FF00820044003800C60F01C +FA0F:2090208821042240F84020A020902108220425FA21083908C108010801F80108 +FA10:120213FE1404100013FEFC401086174412A811301EE8E0A84124062200C00000 +FA11:204020202BFEA800A908A890AFFEA808ABC8AA48AA48BBC8CA48000800280010 +FA12:00204BFE7C2049FC48204FFE780049FC490449FC490479FC4904011C01080000 +FA13:1088108813FE1088FC8810443884357E51045324951411141104110411141108 +FA14:12441124108813FEFC9011083A1434E2502051F8902013FC1020102010A01040 +FA15:8BD46A9E2A940A941BD42A5C2A54CBD04A92529263EE00002444222242220000 +FA16:00404C40284611F4304848508BFE184029FC4B04890409FC490439FC11040000 +FA17:08300420024002447FFE04200810100C60041FF812481248124812487FFE0000 +FA18:00403E40004000407F4008402A402A402A402A404A404A4008420842083E0000 +FA19:202010201124FDFE0524092411FC31245924952415FC11241020102010200000 +FA1A:210C10881050FFFE04200820102031FC58209420142413FE1020102010200000 +FA1B:200413FE1000FCF80488088810F8300059FC952415FC1124112411FC11040000 +FA1C:202023FE102011FCFC2003FE440045FC290429FC11041DFCE104411C01080000 +FA1D:102413FE922054FC542011FEFE0010FC188434FC528492FC1084109C10880000 +FA1E:02047FFE0E1C121422244244060C0A14122422444284020412240E1C04080000 +FA1F:0440FFFE044004403EFC228422FC3E8422FC22403EFE232222D2428A4AF2840C +FA20:0820FFFE08A01CF0F11012F810A8FCF810A831FC392455FC552491FC1022101E +FA21:202021202120F9FCAA20AC20A820A820A9FCF820A820202028203820CBFE0000 +FA22:204010401044FDF4004800507BFE004079FC0284788448FC488478FC48840000 +FA23:100810481028FE08108810481008FE0E11F810085C085008500870088C0083FE +FA24:000023FC10880888409020BC10840084F0C411481128121014282844448283FE +FA25:011041F83110122407FE02441244FBFC106010A811261622301EC80087FE0000 +FA26:082408BE3EA409240A287FE8042809241FA431225F221132112C1F2011200000 +FA27:1020102029FE4424B82813FE10207C4010FC1308541039FE10101C10E0500020 +FA28:1020102029FC4420B82017FE11047C8811FC102054203BFE10201C20E0200020 +FA29:00407C8045F8490849F8510851F8490045FE450045FC5884449447F440044018 +FA2A:1008189C14E02A804884BEFE22A43EA422A83EA820A8249026A87B4622820000 +FA2B:100019FE14022A0248FABE0222F23E9222923E9220F2249226027A1E20040000 +FA2C:1020181014922AFE4904BEF822883E8822F83E8020FC248426847AFC20840000 +FA2D:1030102092FCFE84A2FC28847EFC4880FEFE48807EFE480248AA7F5641540000 +FA2E:0800087C7E44424842487E50424842487E4451444A4444684450524062404040 +FA2F:10201020FCFC102411FE7C2400FC7C200124FCA8107054A85324922210A03040 +FA30:090009040BFE140013F83288524892081FFE12881248120817FE100810700000 +FA31:09080890081013FE1222332652AA93FE100011FC110411FC110411FC11040000 +FA32:080008801FC0108021107FF8A210221022103FF02290048408843086C07C0000 +FA33:202022203F20222444FEFF24492449247F24494408441884291A480287FE0000 +FA34:2220FFA022203E2408FE7F2449247F240824FFA408447F4408A40F9CF1080000 +FA35:010022083FFC208820883FF821083FF82288048008847FFE0080008000800000 +FA36:020893FCFA0893F8920893F89288910293FE9622FA229252028A03F2001C0000 +FA37:011097FEF91091F0904097FC944497FC904097FCF0409FFE00A003180C060000 +FA38:22443F7E224422443E7C012002147FFE081012087F7E224422443E7C22440000 +FA39:11FE1102110211FEFD44112811FE1148154819FEE24842480488090800000000 +FA3A:10081FFC14A812A81FF800801FFC00807FFE144812A620821FF800847FFE0000 +FA3B:3FFC200420043FFC222421402FFC2A9429242FFC240827F8440847F884080000 +FA3C:010001000100210421042104210421043FFC21040100010002000C0070000000 +FA3D:1200120413FE14005BF85288524892481FFE12881248124817FE100810700000 +FA3E:200424BE278824A8B4A8AFA8A4A827FE24102518249825A82E4A248A210E0000 +FA3F:110C1088109013FE5A22572652AA93FE120211FC110411FC110411FC11040000 +FA40:0110355027D4405E97B4201467D4A10827D421262FC204842452241243F80000 +FA41:202021203FA02024407E3EC82A482A48FFC852284A304A107FA802460C820000 +FA42:44047EFE441044507C50449044947DFE4410401048304C505492E112420E0000 +FA43:0FF008100FF008100FF409081FF001207FFE008007F87C0807F8040807F80000 +FA44:1100110413FE1000FDFC11441924352457FE52889248924817FE100810700000 +FA45:4200220423FE0C008BF85288524822482FFEC48844484448C7FEC01040E00000 +FA46:00402040104403F8405028642FFE108011FC23046DFC2104210421FC21040000 +FA47:41102FFE211001F0804057FC544427FC2040C7FC40404FFEC080C3304C0E0000 +FA48:01000FEC010801107FFE008007F00C1017F0641007F004102444222242220000 +FA49:001000F83F00010C108808900820000000000000000000000000000000000000 +FA4A:00040BFEFC401080114C124812B07D2012B0106814A81924E222452008C00000 +FA4B:012405FEFF24112411FC21243D2465FCA5442490251427FE3C10241000100000 +FA4C:202010201020FC200420082811FC302058209420142010201020102413FE0000 +FA4D:202010201020FC2005200924113E312059209520152011201120112417FE0000 +FA4E:2008109C10E0FC800480088410FE308858889488148811081108120814080000 +FA4F:204010401044FDFE044008401080308459FE968414841084108410FC10840000 +FA50:210811FC1108FD080508090811F831085908950815F811081108110817FE0000 +FA51:210411FE1104FD040504090411FC3154585094501450105210921112120E0000 +FA52:208810FC1088FC8804B808A810A833FE5A0296F2129212F21292120E12040000 +FA53:20201024103EFC2005FC090411FC310459FC950415FC11041050108813060000 +FA54:0848FFFC08487F4800487F8E81003EFC00487E4808487F302A30494889860000 +FA55:010020843FFE200444481830614C012001047FFE0100028004401830600E0000 +FA56:104010401F7E289045083E7C22443E4422443E44224424442E5C734821400000 +FA57:102413FE202027FE4622FB2612AA2BFEFA224420007028A85526562280200000 +FA58:100413FE208824884552FBDE10002BFEFC0045FC010429FC550455FC81040000 +FA59:20203FBE55443FA415181FA6014202101FE002107FFC208400A01B9861060000 +FA5A:3FFC224422443FFC21041FE801107FFE008007F80C0837F8040807F804080000 +FA5B:020002083FC802100224FFFE010002100FF818102810CFF008100FF008100000 +FA5C:09100FF808100FF008100FF008100FF0082000947FFE014002200C1E70040000 +FA5D:000000000000042004207FFE0420042000000000000000000000000000000000 +FA5E:000000000000042004207FFE0420042000000000000000000000000000000000 +FA5F:042004207FFE052001081FD001207FFE010007F81C0867F8040807F804080000 +FA60:41FC210429FCFD0409FC1124244028FE7122AF222552218A210221F2200C0000 +FA61:21FC1104110405FC7F04090411FC3904550495FC1154105010521092170E0000 +FA62:210411FE1104FDFC010401FC794000FE792203227952498A490279F2480C0000 +FA63:2088108813FEFC8800F8002079FC012479FC00207BFE482049FC78204BFE0000 +FA64:21043FFE20045FF40510092031400FF078100FF008100FF008100FF0381C0000 +FA65:890CFC8888508BFEFA228B268AAAFBFE880089FCF90489FC510489FC89040000 +FA66:400030001000000000001000F80010001000100010003000C80087FE00000000 +FA67:011041F83110122407FE02441244FBFC106010A811261622301EC80087FE0000 +FA68:22A0FF9022903EFE09907E904A907EFC08907E9008FCFF90149422FE42800000 +FA69:111E27D27A5413D82A567A92135C60901FF804447FFE08100FF008100FF00000 +FA6A:080409FE28202EFC28842884FFFC088428FC288449848AFC0484185861860000 +FA6B:01300108FFFE01003FF8210821083FF8210821083FF80100258C24966632C3E0 +FA6C:00007F7E480248027F02417E41407F40484248427F7E00002488224442448004 +FA6D:102038202DFE67024102FCF810881088FEF8008000807CFC4484448444847CFC +FA6E:00007FFE61866FB663866FB66FB67FFE7FFE73866FBE638E6DBE73867FFE0000 +FA6F:00007FFE61866FB663866FB66FB67FFE7FFE73866FBE638E6DBE73BE7FFE0000 +FA70:1010082004407FFC0440044004404444244414481450044004400440FFFE0000 +FA71:47F8240824080408040817F811202120E1202120222022222422281E10000000 +FA72:0100010002800440082010102FE8C106010001001FF00100010001007FFC0000 +FA73:10041FC414842494249464946494AFD424942494249424942484288428943088 +FA74:02000100FFFE04000400082010103FF80448044004400440084408441044603C +FA75:04447C7804421C3EE4003FF821083FF821083FF804403FF80440FFFE10102008 +FA76:3FF0066001803FF821083FF821083FF82108220802007FF80408080810506020 +FA77:0800080010001FF8200840088008040802080108010800080008000800500020 +FA78:03F87A084BF84A084BF849004BFC4C444A447AA44A0403F40004002800100000 +FA79:0100010079FC4A044D0449E44A8448844FF448847AA44AA403E4000400280010 +FA7A:010001F8F20893F0901097FE90809144966890B0F128966800A4012206A00040 +FA7B:01F87908490849F84908490849F848004BFC7A944A940294029407FE00000000 +FA7C:200027FE2402280427FEF8802184224426A821303AF0E4A8412802240CA20040 +FA7D:102011FC1020108813FEFC8811FC110411FC110411FC1D04E1FC408801040202 +FA7E:020002007FFC044009203118DFF6111011101FF0111011101FF40104010400FC +FA7F:020002007FFC044009203118CFE60100092008207FFC08200820102010202020 +FA80:1040108011FC1124FD2425FC2524254425FC4890291013FE2810441084100010 +FA81:2108209023FE2108F9084A524B9C49088A524BDE304010A42AAA4A8A84780000 +FA82:010000803FFE22102F90221E2FA422243FD4241427942488448848948AA41142 +FA83:010000803FFE200027FC244427FC244427FC211027FC21102FFE400042088404 +FA84:010007847804088844902522200204047F880C10162215022484440884100460 +FA85:0808083C13C020044A44092811FC3220502093FE102011241124112411FC1004 +FA86:100013FE1202128A1A5257FE5242522293FE12821282128212FA1202120A1204 +FA87:2040204027FC204033F8AA08A3F8A208A3F8220823F822082FFE211022082404 +FA88:010002800C6037D8C0063E0822483E4822483E482208261801004884481287F2 +FA89:11041088100013FE1A2256AA5272522293FE100011FC110411FC110411FC1104 +FA8A:21082108210827D0311EAF94A124AFD4A21423D422542248224824D424242842 +FA8B:22204AA08ABE1FC420A46F24A0282FA822102FA822442F8201004884481287F2 +FA8C:08207F280824FFFE00207F2049247F2449247F2822287F102212FFAA22464182 +FA8D:204020A021102208FDF6200023C42A543254E3D42254225423D42244A25442C8 +FA8E:10A0112C11241124FDAC1124112415FC182031FCD08810501020105050882306 +FA8F:200023FC22042204FBFC220022842A4832FCE248224823FE24482448A8885108 +FA90:0820082008207F3E08443E440844FFA410281E281210121022282A4844848102 +FA91:002000207BFE482049FC48204BFE780049FC490449FC490479FC490401140108 +FA92:1000087C7E44424442447E7C424442447E44407C484444445A84628441140208 +FA93:1000087CFF44207C2044267C3844209401087FFC010001003FF801000100FFFE +FA94:1010101010101010FDFE10103010391055105490909010501020105011881606 +FA95:FFFE02000200040007F8080810102410422001400080010002000C0070000000 +FA96:040044782848104828484486920010FCFE441044582854289210122850442182 +FA97:0080204017FE10808110420847FC100410002248E24822482248224A244A0846 +FA98:0004203E17C0124481244128420013FC14402040EFFE20402444244427FC0004 +FA99:01082088109017FE810841084210129414A42738E1082210221024A427BC0084 +FA9A:0110211017FE111081F040404BF80A4813F81040E7FC20402FFE20A02110060C +FA9B:022042202FB822480F90827C4F9450141FFE2894EF9428FC2F9428902A900930 +FA9C:020002083FD00220FFFE01000FF03810CFF0081008100FF00000488844448444 +FA9D:00A0009079FE49104B107DFE4910491079FE4910491049FE79004AA402520452 +FA9E:00FC7F00220811107FFC44447FFC00087E0842FE7E0842487E28480874284210 +FA9F:440029F81108290849088908090819282910490089020902090250FE20000000 +FAA0:0040884453F42048505097FE1040108031F85308950811F811081108A1F84108 +FAA1:00200020FBFE202021FC210421FCF90421FC210421FC3904E3FE408801040202 +FAA2:082004407FFC12483CF0082014503EF800007FFC08000FE0092010A41624181C +FAA3:FFFE000000004FE4492449244FE44924492449244FE4400440047FFC00040000 +FAA4:008000401FFE100097FC54A454A417FC30405150924814442150224844448040 +FAA5:010000803FFE200027F8A40867F8240827F86000AFFC2924292449247FFE8000 +FAA6:101008200000FFFE000008201010200840043FF82448244824482448FFFE0000 +FAA7:009000883FFC208020883E48225022244A54448C81043FF824482448FFFE0000 +FAA8:010001007FFC01001FF0101010101FF010101FF010101FF010101010FFFE0000 +FAA9:00FC7C84448444FC7C0045FE45027D0245FE450245027DFE4502010A01040000 +FAAA:082004407FFC01003FF80200FFFE04000FF018102FF0C8100FF008100FF00810 +FAAB:00200020FBFE202021FC410479FC4904C9FC490449FC49047BFE488801040202 +FAAC:020001007FFE4822909411F822886870ABAE282029FC282028A8292422A42040 +FAAD:104010403F7E4890850800007E7C42447E4442447E44484444545A4862404040 +FAAE:01001110092001007FFC05400920111060080100FFFE0280044008203018C006 +FAAF:108010F811082290206065986646A48825F02420244825FC2020212422A22040 +FAB0:1020102023FE242045FCF92411AC21744924FDFC0420007054A8552482220020 +FAB1:208420483C0050FC90481048FE48104811FE5448544854485C48648804880108 +FAB2:020002083FD002200240FFFE010002000FF0181028104FF0881008100FF00810 +FAB3:08200820FFFE0A200100FFFE100010001FF8000011101110111021124112810E +FAB4:04400440FFFE04407FFC11101110FFFE111011107FFC0100FFFE010001000100 +FAB5:100010F810887C8854F85488548854F87C0051FC115415541D54E55443FE0000 +FAB6:200013BE00A2F0A210BE238822086A3EB22A2BAA20AA20BE2088208A257E2202 +FAB7:FFFE04403FF824483FF8120027FC42088BF8120833F8510093F8151010E0171E +FAB8:200011FC1104F90409FC1104110439FC5504950411FC1050109010921112120E +FAB9:200011FC0124FD240174792401FC7904017479544954497449047A044A140408 +FABA:2020102201FAFC2400287BFE0020784000FC79844A8448FC4884788448FC0084 +FABB:2020102003FEFC2001FC782003FE780001FC790449FC490449FC790449140108 +FABC:200011FC1104FDFC01047DFC00807DFE02227D224552450245FA7C0244140008 +FABD:2088108803FEFC8800A8782003FE7840008078FC49844A844884788448FC0084 +FABE:204010A00110FA0805F6780003C47A5402547BD44A544A544BD47A444A5402C8 +FABF:2088108803FEFC8800F8782001FC792401FC78204BFE482049FC78204BFE0000 +FAC0:210447C88812F3BC20084B92F83E0380AAAAABAA08001FF8282007C01830E00E +FAC1:0104788848004BFE7A224AAA4A727A224BFE480079FC010451FC490489FC0104 +FAC2:204020A02110FA0825F6F800ABC4FA54AA54FBD42254FA5423D42244225422C8 +FAC3:07FC440427FC242004A80470E4A8250424A024FC252024202BFE282050208FFE +FAC4:0050FE9628922892FED6AA92AA92AAFEAE10C2FC8244FE4482288210FE2882C6 +FAC5:100213E22942254A414AB94A114A13EAFD4A114A954A594A51421E42E24A4444 +FAC6:00207C2245FA4824482853FE4820484044FC4584468468FC5084408440FC4084 +FAC7:22282224FF40227E3EC809487F7E49487F48087E7F480848FF48147E22404140 +FAC8:2020102013FEFC2001FC08208BFE880049FC490451FC51041DFCE10441140108 +FAC9:104410447DFE2444FE4401FE7C4044FE7D9212FE7C9210FE50927C9210921086 +FACA:110023DE7A5213D42A527BDA1294235001003FF80440FFFE10101FF010101FF0 +FACB:7EFE401040205EFC5284528452FC5A8454FC5084528454FC5848508481020000 +FACC:080008FE28102E2028FC2884FF8400FC08842AFC2A844C8484FC08483084C102 +FACD:3F042018FF62220C7F7001007FFC01001FF0101011101110FFFE082010102008 +FACE:04003FF820083EF802807A800AFCFE940AD47AA402A47AD40A94FEFC0A8279FE +FACF:20CC273021103110AFFEA110A2A824282844210222902A482A543214221021F0 +FAD0:20CC273021103110AFFEA110A2A82428284423FA220823F82208220823F82208 +FAD1:10281024102013FEFC2010A838A834A850A850A89128112A122A142610201020 +FAD2:2000229E22522252F5522112229272526C32A3D2A25A22542250225023D02250 +FAD3:03FC789048904890789048904FFE789048904890489079104910021004100000 +FAD4:0020002078204BFE482078204924492479244AAA482048507850488801040202 +FAD5:02200220F47C94449DA8F510952895D6F51095FE95109538F454949204100410 +FAD6:10401F7E28904508BEF822883EF822883EF820082EE824482EE8244828482018 +FAD7:1044108813DEFC881088108813DEFC88108810885C885108520870008C0083FE +FAD8:20007CFC44847CFC44847CFC0040FEFE9312FE9292AAFE8200FAFE0244148408 +FAD9:3FFE22202FBC2520223C3F84203C2FA028BC2FA028BC2FA048BC48A2899E0000 +FADA:00007FFE61866FB663866FB66FB67FFE7FFE63866DB66D866DB663B67FFE0000 +FADB:00007FFE61866FB663866FB66FB67FFE7FFE638E6DB66D8E6DB6638E7FFE0000 +FADC:00007FFE61866FB663866FB66FB67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000 +FADD:00007FFE61866FB663866FB66FB67FFE7FFE638E6DB66DB66DB6638E7FFE0000 +FADE:00007FFE61866FB663866FB66FB67FFE7FFE63866DBE6D8E6DBE63867FFE0000 +FADF:00007FFE61866FB663866FB66FB67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +FAE0:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663B66FB661CE7FFE0000 +FAE1:00007FFE61866FB663866FB66FB67FFE7FFE61EE6FCE63EE6FEE61C67FFE0000 +FAE2:00007FFE61866FB663866FB66FB67FFE7FFE61866FF663866FBE61867FFE0000 +FAE3:00007FFE61866FB663866FB66FB67FFE7FFE618E6FF663C66FF6618E7FFE0000 +FAE4:00007FFE61866FB663866FB66FB67FFE7FFE61B66FB663866FF661F67FFE0000 +FAE5:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE63866FF661867FFE0000 +FAE6:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FBE638E6FB661CE7FFE0000 +FAE7:00007FFE61866FB663866FB66FB67FFE7FFE61866FF663EE6FDE61DE7FFE0000 +FAE8:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663CE6FB661CE7FFE0000 +FAE9:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663C66FF661CE7FFE0000 +FAEA:00007FFE61866FB663866FB66FB67FFE7FFE61866FB663866FB661B67FFE0000 +FAEB:00007FFE61866FB663866FB66FB67FFE7FFE618E6FB6638E6FB6618E7FFE0000 +FAEC:00007FFE61866FB663866FB66FB67FFE7FFE61C66FBE63BE6FBE61C67FFE0000 +FAED:00007FFE61866FB663866FB66FB67FFE7FFE618E6FB663B66FB6618E7FFE0000 +FAEE:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE638E6FBE61867FFE0000 +FAEF:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE638E6FBE61BE7FFE0000 +FAF0:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663B66FB66FCE7FFE0000 +FAF1:00007FFE61866FB663866FB66FB67FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000 +FAF2:00007FFE61866FB663866FB66FB67FFE7FFE61866FF663866FBE6F867FFE0000 +FAF3:00007FFE61866FB663866FB66FB67FFE7FFE618E6FF663C66FF66F8E7FFE0000 +FAF4:00007FFE61866FB663866FB66FB67FFE7FFE61B66FB663866FF66FF67FFE0000 +FAF5:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE63866FF66F867FFE0000 +FAF6:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +FAF7:00007FFE61866FB663866FB66FB67FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +FAF8:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +FAF9:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663C66FF66FCE7FFE0000 +FAFA:00007FFE61866FB663866FB66FB67FFE7FFE61866FB663866FB66FB67FFE0000 +FAFB:00007FFE61866FB663866FB66FB67FFE7FFE618E6FB6638E6FB66F8E7FFE0000 +FAFC:00007FFE61866FB663866FB66FB67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000 +FAFD:00007FFE61866FB663866FB66FB67FFE7FFE618E6FB663B66FB66F8E7FFE0000 +FAFE:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE638E6FBE6F867FFE0000 +FAFF:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +FB00:0000001B2424247E2424242424240000 +FB01:0000001A2220207E2222222222220000 +FB02:0000001E2222227A2222222222220000 +FB03:000000162A28287E2A2A2A2A2A2A0000 +FB04:0000001E2A2A2A7E2A2A2A2A2A2A0000 +FB05:000000384848485E4848484848460000 +FB06:0000001C242424364444241414620000 +FB07:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73866DF66DEE6DDE73DE7FFE0000 +FB08:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000 +FB09:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73CE6DB66DC66DF673CE7FFE0000 +FB0A:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73866DB66D866DB673B67FFE0000 +FB0B:00007FFE618E6FB6638E6FB66F8E7FFE7FFE738E6DB66D8E6DB6738E7FFE0000 +FB0C:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000 +FB0D:00007FFE618E6FB6638E6FB66F8E7FFE7FFE738E6DB66DB66DB6738E7FFE0000 +FB0E:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73866DBE6D8E6DBE73867FFE0000 +FB0F:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000 +FB10:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7BCE73B67BB67BB671CE7FFE0000 +FB11:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000 +FB12:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7B8673F67B867BBE71867FFE0000 +FB13:000000000814305D5555555555330000 +FB14:000000000C1414575454555555360000 +FB15:000000000C1414565555555555350404 +FB16:00000000503C1455555555555533101C +FB17:00000000182828ADADADADADAD6A0808 +FB18:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000 +FB19:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7BCE73B67BC67BF671CE7FFE0000 +FB1A:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7B8673B67B867BB671B67FFE0000 +FB1B:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000 +FB1C:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000 +FB1D:00000000001C04040400040000000000 +FB1E:0042423C000000000000000000000000 +FB1F:000000000077111111003E0000000000 +FB20:00000000001212121212121212FE0000 +FB21:00000000000000000000300C300C0C0C030C0CF030C03030300C300C00000000 +FB22:000000000000000000003FFC0030003000300030003000300030003000000000 +FB23:000000000000000000003FFC000C000C0C0C0C0C0C0C0C0C0C0C0C0C00000000 +FB24:000000000000000000003FFC000C000C000C000C000C000C000C3FF000000000 +FB25:0000000000000C000C000FFC000C000C000C000C0030003000C00F0000000000 +FB26:00000000000000000000FFFC0C0C0C0C0C0C0C0C0C0C0C0C0C0C0FFC00000000 +FB27:000000000000000000003FFC000C000C000C000C000C000C000C000C00000000 +FB28:000000000000000000000FFC0C0C0C0C0C0C0C0C0C0C0C0C0C0C3C0C00000000 +FB29:00000000000000080808087F00000000 +FB2A:000000010049494949494949497F0000 +FB2B:000000400049494949494949497F0000 +FB2C:0000000100494949494D4949497F0000 +FB2D:0000004000494949494D4949497F0000 +FB2E:0000000000464222122C484442411C00 +FB2F:0000000000464222122C484442411C08 +FB30:0000000000424222122C484442410800 +FB31:00000000007C040404240404047F0000 +FB32:000000000030080808440C1422420000 +FB33:00000000007E04040424040404040000 +FB34:00000000007E0202222A222222220000 +FB35:00000000003808080828080808080000 +FB36:0000000000300C0A0828080808080000 +FB37:00007FFE618E6FB6638E6FB66F8E7FFE7FFE63867DF671EE7DDE63DE7FFE0000 +FB38:0000000000464A4242524242427E0000 +FB39:00000000003808080820000000000000 +FB3A:00000000007E02020212020202020202 +FB3B:00000000007E020202120202027C0000 +FB3C:00000020203E02020212040408300000 +FB3D:00007FFE618E6FB6638E6FB66F8E7FFE7FFE638E7DB671B67DB6638E7FFE0000 +FB3E:00000000004E31214149414141470000 +FB3F:00007FFE618E6FB6638E6FB66F8E7FFE7FFE63867DBE718E7DBE63BE7FFE0000 +FB40:00000000001C040404240404043C0000 +FB41:00000000007E42424252424244780000 +FB42:00007FFE618E6FB6638E6FB66F8E7FFE7FFE6D866DF661867DBE7D867FFE0000 +FB43:00000000007E42424272020212020202 +FB44:00000000007E424242720212027E0000 +FB45:00007FFE618E6FB6638E6FB66F8E7FFE7FFE6D866DBE61867DF67D867FFE0000 +FB46:000000000042422418084402027E0000 +FB47:00000000007E222A2224282020202020 +FB48:00000000007E02020212020202020000 +FB49:0000000000494949494D4949497F0000 +FB4A:00000000003E2222222A222222620000 +FB4B:00000020003808080808080808080000 +FB4C:00000070007C040404040404047F0000 +FB4D:00000070007E020202020202027C0000 +FB4E:00000070007E424242720202027E0000 +FB4F:0000602020464222122C484442420000 +FB50:040A1E20080808080808080000000000 +FB51:102878802020202020201F0000000000 +FB52:000000000000000422423C0008000800 +FB53:000000000000000422423F0008000800 +FB54:00000000000000080404F80008000800 +FB55:00000000000000080404FF0008000800 +FB56:000000000000000422423C0014000800 +FB57:000000000000000422423F0014000800 +FB58:00000000000000080404F80014000800 +FB59:00000000000000080404FF0014000800 +FB5A:000000000000000422423C0014001400 +FB5B:000000000000000422423F0014001400 +FB5C:00000000000000080404F80014001400 +FB5D:00000000000000080404FF0014001400 +FB5E:000008000800000422423C0000000000 +FB5F:000008000800000422423F0000000000 +FB60:00000800080000080404F80000000000 +FB61:00000800080000080404FF0000000000 +FB62:000014001400000422423C0000000000 +FB63:000014001400000422423F0000000000 +FB64:00001400140000080404F80000000000 +FB65:00001400140000080404FF0000000000 +FB66:000020203838000422423C0000000000 +FB67:000020203838000422423F0000000000 +FB68:000010101C1C00080404F80000000000 +FB69:000010101C1C00080404FF0000000000 +FB6A:0008001200060A0642423C0000000000 +FB6B:0008001200060A0642423F0000000000 +FB6C:0010002400003824140CF80000000000 +FB6D:0010002400003824140CFB0000000000 +FB6E:000A000A00060A0642423C0000000000 +FB6F:000A000A00060A0642423F0000000000 +FB70:0028002800003824140CF80000000000 +FB71:0028002800003824140CFB0000000000 +FB72:00000000000000007E1020484048221C +FB73:00000000000000007E1423484048211E +FB74:0000000000000000700CFC0020002000 +FB75:0000000000000000700CFF0020002000 +FB76:00000000000000007E1020405440221C +FB77:00000000000000007E1423405440211E +FB78:0000000000000000700CFC0050000000 +FB79:0000000000000000700CFF0050000000 +FB7A:00000000000000007E2040544048221C +FB7B:00000000000000007E2241544048211E +FB7C:0000000000000000700CFC0028001000 +FB7D:0000000000000000700CFF0028001000 +FB7E:00000000000000007E2040544054221C +FB7F:00000000000000007E2443544054211E +FB80:0000000000000000700CFC0050005000 +FB81:0000000000000000700CFF0050005000 +FB82:000000000000080402427C0028000000 +FB83:000000000000080402427F0028000000 +FB84:000000280000080402427C0000000000 +FB85:000000280000080402427F0000000000 +FB86:000010002800080402427C0000000000 +FB87:000010002800080402427F0000000000 +FB88:002020383800080402427C0000000000 +FB89:002020383800080402427F0000000000 +FB8A:00000008001400000402020204483000 +FB8B:00000008001400000402030204483000 +FB8C:00000008080E0E000402020204483000 +FB8D:00000008080E0E000402030204483000 +FB8E:00000004081020403C827E0000000000 +FB8F:00000004081020403C827F0000000000 +FB90:00000004081020403C02FE0000000000 +FB91:00000004081020403C02FF0000000000 +FB92:00081024481020403C827E0000000000 +FB93:00081024481020403C827F0000000000 +FB94:00081024481020403C02FE0000000000 +FB95:00081024481020403C02FF0000000000 +FB96:00081024481020403C827E0010001000 +FB97:00081024481020403C827F0010001000 +FB98:00081024481020403C02FE0010001000 +FB99:00081024481020403C02FF0010001000 +FB9A:00500618620C30403C827E0000000000 +FB9B:00500618620C30403C827F0000000000 +FB9C:00500618620C30403C02FE0000000000 +FB9D:00500618620C30403C02FF0000000000 +FB9E:00000000000000000422424244380000 +FB9F:00000000000000000422434244380000 +FBA0:000010101C1C00000422424244380000 +FBA1:000010101C1C00000422434244380000 +FBA2:000010101C1C00080404F80000000000 +FBA3:000010101C1C00080404FB0000000000 +FBA4:001820182000101824243C0000000000 +FBA5:1820182004040C14243C070000000000 +FBA6:000000000000101824243C0000000000 +FBA7:000000000000000000102F4000000000 +FBA8:00000000000000000010F01010140800 +FBA9:00000000000000000010F31414140808 +FBAA:000000000000102C2A1A244000000000 +FBAB:000000000000102C2A1A274000000000 +FBAC:000000000000102C2A1AE40000000000 +FBAD:000000000000102C2A1AE70000000000 +FBAE:00000000000000000008141020407F00 +FBAF:000000000000000000000F1020407F00 +FBB0:00000000003040304008141020407F00 +FBB1:000000000030403040000F1020407F00 +FBB2:00001818000000000000000000000000 +FBB3:00000000000000000000000000001818 +FBB4:00000C6C600000000000000000000000 +FBB5:000000000000000000000000000C6C60 +FBB6:003030006C6C00000000000000000000 +FBB7:00000000000000000000003030006C6C +FBB8:006C6C00181800000000000000000000 +FBB9:00000000000000000000006C6C001818 +FBBA:000C6C60031B18000000000000000000 +FBBB:000000000000000000000C6C60031B18 +FBBC:00000000000000000000000024241212 +FBBD:003030000C0C00000000000000000000 +FBBE:000000000000000000003030000C0C00 +FBBF:00000000000000000000000814242810 +FBC0:0010101C1C0000000000000000000000 +FBC1:00000000000000000000000010101C1C +FBC2:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FF66F866FBE71867FFE0000 +FBC3:00007FFE618E6FB6638E6FB66F8E7FFE7FFE718E6FF66FC66FF6718E7FFE0000 +FBC4:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71B66FB66F866FF671F67FFE0000 +FBC5:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FBE6F866FF671867FFE0000 +FBC6:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000 +FBC7:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FF66FEE6FDE71DE7FFE0000 +FBC8:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +FBC9:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +FBCA:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FB66F866FB671B67FFE0000 +FBCB:00007FFE618E6FB6638E6FB66F8E7FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +FBCC:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +FBCD:00007FFE618E6FB6638E6FB66F8E7FFE7FFE718E6FB66FB66FB6718E7FFE0000 +FBCE:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FBE6F8E6FBE71867FFE0000 +FBCF:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +FBD0:00007FFE618E6FB6638E6FB66F8E7FFE7FFE63CE6DB66DB66DB663CE7FFE0000 +FBD1:00007FFE618E6FB6638E6FB66F8E7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000 +FBD2:00007FFE618E6FB6638E6FB66F8E7FFE7FFE63866DF66D866DBE63867FFE0000 +FBD3:100028020A120A2242423C0000000000 +FBD4:100028020A120A2242423F0000000000 +FBD5:20005004081020403C02FE0000000000 +FBD6:20005004081020403C02FF0000000000 +FBD7:000018180810200C12121E0204483000 +FBD8:000018180810200C12121F0204483000 +FBD9:000000221408000C12121E0204483000 +FBDA:000000221408000C12121F0204483000 +FBDB:000000080404000C12121E0204483000 +FBDC:000000080404000C12121F0204483000 +FBDD:000033341324400C12121E0204483000 +FBDE:000008001200000C12121E0204483000 +FBDF:000008001200000C12121F0204483000 +FBE0:000000000000000C12121E021C483000 +FBE1:000000000000000C12121F021C483000 +FBE2:000000081422000C12121E0204483000 +FBE3:000000081422000C12121F0204483000 +FBE4:000000000000000C5248443800100010 +FBE5:00000000000000004C52493000100010 +FBE6:00000000000000080804F80008000800 +FBE7:00000000000000080804FB0008000800 +FBE8:00000000000000080804F80000000000 +FBE9:00000000000000080804FB0000000000 +FBEA:0000004C504C50404444380000000000 +FBEB:0000004C504C504044443B0000000000 +FBEC:000000060806080002122C4000000000 +FBED:000000060806080002122D4000000000 +FBEE:00000003040304102A2A3C0808106000 +FBEF:00000003040304102A2A3D0808106000 +FBF0:00003033142344102A2A3C0808106000 +FBF1:00003033142344102A2A3D0808106000 +FBF2:00008853242304102A2A3C0808106000 +FBF3:00008853242304102A2A3D0808106000 +FBF4:00000023141304102A2A3C0808106000 +FBF5:00000023141304102A2A3D0808106000 +FBF6:000C100C1004040C5048443800100010 +FBF7:00000C100C1000044C52493000100010 +FBF8:00000608060800222212EC0020002000 +FBF9:00000608060802020206484442423C00 +FBFA:00000608060800020205484442423C00 +FBFB:00000608060800222212EC0000000000 +FBFC:0000000000000000044A484442423C00 +FBFD:00000000000000000000434442423C00 +FBFE:00000000000000080804F80028000000 +FBFF:00000000000000080804FB0028000000 +FC00:0000006080608C30407E20404840221C +FC01:0000006080608C30407E20404040221C +FC02:000000182018230408083C4040404040 +FC03:000000304030440202224446221C0000 +FC04:000000304030440202224446221C0014 +FC05:0000000000000C30407E20424840221C +FC06:0000000000000C30407E20424040221C +FC07:0000000020000C30407E20424040221C +FC08:000000000000030408083C4140404040 +FC09:000000000000040202224446221C0100 +FC0A:000000000000040202224446221C0114 +FC0B:0000000028000C30407E20424040221C +FC0C:0000000028000C30407E20404040221C +FC0D:0000000028008C30407E20404040221C +FC0E:000000050000030408083C4040404040 +FC0F:000000001400040202224446221C0000 +FC10:000000001400040202224446221C0014 +FC11:0000004000A00C30407E20404840221C +FC12:000000100028030408083C4040404040 +FC13:000000200050040202224446221C0000 +FC14:000000200050040202224446221C0014 +FC15:000000700C020C30407822404040221C +FC16:000000300C02030408083C4140404040 +FC17:000000700C020C30407E20424040221C +FC18:000000300C02030408083C4040404040 +FC19:000004700C020C30407E20404840221C +FC1A:000004700C020C30407E20404040221C +FC1B:000000310C02030408083C4040404040 +FC1C:000000000000255A407E20424040221C +FC1D:000000000000255A407E20404040221C +FC1E:000000004000255A407E20404040221C +FC1F:00000000000000000000000001940268040004001E0020002000200020002000 +FC20:0000000006091E28407E20404040221C +FC21:00000000000000000038004401F80240040004001E0020002000200020002000 +FC22:0000000026091E28407E20404840221C +FC23:0000000026091E28407E20404040221C +FC24:0000000026891E28407E20404040221C +FC25:00000000000000000138004401F80240040004001E0020002000200020002000 +FC26:000000202C323C20407E20404040221C +FC27:0000000808080E0916103C4040404040 +FC28:000000080A080E0916103C4040404040 +FC29:0000003040381020407E20404840221C +FC2A:000000000C100F0408083C4040404040 +FC2B:0000803040381020407E20404840221C +FC2C:000008000C100F0408083C4040404040 +FC2D:00008020503010207E1020404840211E +FC2E:00008020503010207E1020404040211E +FC2F:00008020503090207E1020404040211E +FC30:00000040102818081020103840404040 +FC31:00000400000C0A0602464844423C0000 +FC32:00000400000C0A0602464844423C0028 +FC33:0000005000205030407E20404840221C +FC34:00002800102818081020103840404040 +FC35:00001400000C0A0602464844423C0000 +FC36:00001400000C0A0602464844423C0028 +FC37:000000048890A0C0BC827C0000000000 +FC38:0000000008102010207E20404840221C +FC39:0000000008102010207E20404040221C +FC3A:0000000008102090207E20404040221C +FC3B:000000101012141814121C9090909060 +FC3C:000000040810201008103C4040404040 +FC3D:0000000000000010002000400080008000400880110011800880070000000000 +FC3E:0000000000000010002000400080008000400880110011800880070000000500 +FC3F:00001010101010207E1020404840211E +FC40:00001010101010207E1020404040211E +FC41:00001010105010207E1020404040211E +FC42:000000080808080808083C4040404040 +FC43:00000002020202020206484442423C00 +FC44:000000020202020202064844423C0028 +FC45:0000000000000C30407E20404840221C +FC46:0000000000000C30407E20404040221C +FC47:0000000000200C30407E20404040221C +FC48:000000000000030408083C4040404040 +FC49:000000000000020204084442423C0000 +FC4A:000000000000020204084442423C0028 +FC4B:0000000008000C30407E20404840221C +FC4C:0000000008000C30407E20404040221C +FC4D:0000000008200C30407E20404040221C +FC4E:000000020000030408083C4040404040 +FC4F:000000000800040202224446221C0000 +FC50:000000000800040202224446221C0014 +FC51:000000103854523C407E20404840221C +FC52:000000201834543808103C4040404040 +FC53:00000000060D150E02224446221C0000 +FC54:00000000060D150E02224446221C0014 +FC55:0000000000000C30407E204A4048221C +FC56:0000000000000C30407E204A4040221C +FC57:0000000000200C30407E204A4040221C +FC58:000000000000030408083C4144404040 +FC59:0000000000000402224446221C010400 +FC5A:0000000000000402224446221C010450 +FC5B:101010002000080402427C0000000000 +FC5C:00000008080808000402020204483000 +FC5D:0000000010101000040A4844423C0000 +FC5E:00046A241800547C0000000000000000 +FC5F:0054547C061866186000000000000000 +FC60:000006186000547C0000000000000000 +FC61:00040A047A00547C0000000000000000 +FC62:0054547C000618600000000000000000 +FC63:000008080800547C0000000000000000 +FC64:000018201822060A120A090808106000 +FC65:000018209822060A120A090808106000 +FC66:000000182018230408083C4040404040 +FC67:00000018209802060A2A454448300000 +FC68:000000000C100C1000064944423C0000 +FC69:000000000C100C1000064944423C0028 +FC6A:000000000002060A120A090808126000 +FC6B:000000000012060A120A090808126000 +FC6C:000000000000030408083D4040404040 +FC6D:00000000001002060A2A454448320000 +FC6E:000000000000000000064944423C0100 +FC6F:000000000000000000064944423C0128 +FC70:000005000002060A120A090808106000 +FC71:000005002002060A120A090808106000 +FC72:00000000000014000C12394040404040 +FC73:00000005001002060A2A454448300000 +FC74:000000000000050000064944423C0000 +FC75:000000000000050000064944423C0028 +FC76:000200050002060A120A090808106000 +FC77:000200050022060A120A090808106000 +FC78:00000000080014000C12394040404040 +FC79:00000200050012060A2A454448300000 +FC7A:000000000002000500064944423C0000 +FC7B:000000000002000500064944423C0028 +FC7C:000000000008000C0A46898C44380000 +FC7D:000000000008000C0A46898C44380028 +FC7E:000000000A00040A07224446221C0000 +FC7F:000000000A00040A07224446221C0014 +FC80:00002122242830282C12010000000000 +FC81:00002122242830A8ACB2410000000000 +FC82:00010204081008040A11081C20202020 +FC83:00000102040810080446898C44380000 +FC84:00000102040810080446898C44380028 +FC85:000000000002020202020F080C101010 +FC86:00000000000202020242858844380000 +FC87:00000000000202020242858844380028 +FC88:0000404040404040402027180E000000 +FC89:0000000000000000000047B8AE808080 +FC8A:000000020002060A120A090808106000 +FC8B:000000021002060A120A090808106000 +FC8C:00000000020002060A12798080808080 +FC8D:00000002100002060A2A454448300000 +FC8E:000000000000020000064944423C0000 +FC8F:000000000000020000064944423C0028 +FC90:000000000010101000064944423C0000 +FC91:000000000002060A120A090808106500 +FC92:000000002002060A120A090808106500 +FC93:000000000000030408083C404A404040 +FC94:00000000001002060A2A454448300500 +FC95:000000000000000000064944423C0104 +FC96:000000000000000000064944423C0154 +FC97:02040608000C1420780CF00010000000 +FC98:02040608000C1420780CF00000000000 +FC99:02040608004C1420780CF00000000000 +FC9A:00020406080006081010F80000000000 +FC9B:00000004080C10002669E82824140C00 +FC9C:00000000000C1420780CF00004200000 +FC9D:00000000000C1420780CF00004000000 +FC9E:00000000200C1420780CF00004000000 +FC9F:00000000000006081010F80004000000 +FCA0:00000000000000002669E82825140C00 +FCA1:00000A00000C1420780CF00000200000 +FCA2:00000A00000C1420780CF00000000000 +FCA3:00000A00200C1420780CF00000000000 +FCA4:0000000A000006081010F80000000000 +FCA5:00000000000A00002669E82824140C00 +FCA6:0004000A000006081010F80000000000 +FCA7:006058041E20407E1862800000000000 +FCA8:0000000000001C021F28D80008000000 +FCA9:006058041E20407E1860801000000000 +FCAA:0000000000001C031F28D80000000000 +FCAB:086058041E20407E1860801000000000 +FCAC:0000000800001C031F28D80000000000 +FCAD:00000000000000001F94209440687E0018006000800010000000000000000000 +FCAE:00000000000000001F94209440687E0018006000800000000000000000000000 +FCAF:00000000000040001F94209440687E0018006000800000000000000000000000 +FCB0:00000000000115153E40E00000000000 +FCB1:0000000804140A24114820F040407E0018006000800000000000000000000000 +FCB2:0000000844140A24114820F040407E0018006000800000000000000000000000 +FCB3:00000000000000200050009011202FC021004000E00000000000000000000000 +FCB4:0080000804140A24114820F040407E0018006000800008000000000000000000 +FCB5:0080000804140A24114820F040407E0018006000800000000000000000000000 +FCB6:0080000844140A24114820F040407E0018006000800000000000000000000000 +FCB7:00000000000004200050009011202FC021004000E00000000000000000000000 +FCB8:101016191E2078061860800000000000 +FCB9:00000000121016193E40F04830000000 +FCBA:000030424C30407E1860801000000000 +FCBB:000000000030404C3040F04830000000 +FCBC:200030424C30407E1860801000000000 +FCBD:000000200030404C3040F04830000000 +FCBE:401028380810203E0C30C00800000000 +FCBF:401028380810203E0C30C00000000000 +FCC0:00401028388810203E0CF00000000000 +FCC1:00100010283808102020F02810000000 +FCC2:28001028380810203E0CF00008000000 +FCC3:00280010283808102020F02810000000 +FCC4:020408103008107E1860800800000000 +FCC5:020408103008107E1860800000000000 +FCC6:020408103088107E1860800000000000 +FCC7:00024448506078444424D80000000000 +FCC8:00040810204020101020F02810000000 +FCC9:0000101010101020780CF00000200000 +FCCA:0000101010101020780CF00000000000 +FCCB:0000101050101020780CF00000000000 +FCCC:00000008080808080808FC0200000000 +FCCD:000004040404041C2A3AF60000000000 +FCCE:00000000040A1C20780CF00000200000 +FCCF:00000000040A1C20780CF00000000000 +FCD0:00000000240A1C20780CF00000000000 +FCD1:0000000000040A1E2020F00000000000 +FCD2:00000400000C1420780CF00000200000 +FCD3:00000400000C1420780CF00000000000 +FCD4:00000400200C1420780CF00000000000 +FCD5:00000004000006081010F80000000000 +FCD6:0000000000000400266AE82824140C00 +FCD7:003C1229293E407E1860801000000000 +FCD8:003C1229291E08102040E05020000000 +FCD9:202000782452523C2040800000000000 +FCDA:00000000000C1420780CF0000A200000 +FCDB:00000000000C1420780CF0000A000000 +FCDC:00000000200C1420780CF0000A000000 +FCDD:00000000000006081010F8000A000000 +FCDE:000000000000000C1250D55048281800 +FCDF:00000C100C3000102824D30000000000 +FCE0:0000000608061800246AE92824140C00 +FCE1:00000000000000102824D30008000000 +FCE2:0000000000000000246AE92825140C00 +FCE3:00000000001400102824D30000000000 +FCE4:0000000000140000246AE92824140C00 +FCE5:00000008001400102824D30000000000 +FCE6:0000000800140000246AE92824140C00 +FCE7:0000000000000000000000000000180024122212D1ED00000000000000000000 +FCE8:0000000000000000000000000000000026126912E8ED2800240014000C000000 +FCE9:0000000000000010000000280000180024122212D1ED00000000000000000000 +FCEA:0000000000000010000000280000000024126A12E9ED2800240014000C000000 +FCEB:00024448506070484C4AB10000000000 +FCEC:00040810204020101824F32810000000 +FCED:00000808080808081824F32810000000 +FCEE:00000000100000102824D30000000000 +FCEF:000000000800000C1252D15048281800 +FCF0:00000000000000102824D3000A000000 +FCF1:00000000000000000856D150482B1800 +FCF2:000C30022A1400000000FF0000000000 +FCF3:040A040A30022A140000FF0000000000 +FCF4:000A54200C3000000000FF0000000000 +FCF5:000000000808080E090E4844423C0000 +FCF6:000000000808080E090E4844423C0028 +FCF7:000000000000000608064844423C0000 +FCF8:000000000000000608064844423C0028 +FCF9:000000000008000608064844423C0000 +FCFA:000000000008000608064844423C0028 +FCFB:00000000000000000000000000000612091208EC4800440042003C0000000000 +FCFC:00000000000000000000000000000612091208EC4800440042003C0000002800 +FCFD:00000000001000000028000000000612091208EC4800440042003C0000000000 +FCFE:00000000001000000028000000000612091208EC4800440042003C0000002800 +FCFF:000000006058040E10380844423C0000 +FD00:000000006058040E38080844423C0028 +FD01:000000006058040E38090844423C0000 +FD02:000000006058040E38090844423C0028 +FD03:000000046058040E38080844423C0000 +FD04:000000026058040E38080844423C0028 +FD05:000000000205051E14100844423C0000 +FD06:000000000205051E14100844423C0028 +FD07:000000080205051E14100844423C0000 +FD08:000000080205051E14100844423C0028 +FD09:000004000A00255A407E20404840221C +FD0A:000004000A00255A407E20404040221C +FD0B:000004000A80255A407E20404040221C +FD0C:000004000A00255A40603C4040404040 +FD0D:00000004000A00152A20202020408000 +FD0E:00000000000000152A20202020408000 +FD0F:0000000002050D162424202020408000 +FD10:0000000802050D162424202020408000 +FD11:000000000808080E090E4944423C0000 +FD12:000000000808080E090E4944423C0028 +FD13:000000000000000205064944423C0000 +FD14:000000000000000205064944423C0028 +FD15:000000000004000205064944423C0000 +FD16:000000000004000205064944423C0028 +FD17:000000000000000000000000000000000612091248ED440042003C0000000000 +FD18:000000000000000000000000000000000612091248ED440042003C0000002800 +FD19:000000000000001000000028000000000612091248ED440042003C0000000000 +FD1A:000000000000001000000028000000000612091248ED440042003C0000002800 +FD1B:000000000000000000000000000000000670090C08FF440042003C0000000000 +FD1C:000000000000000000000000000000000670090C08FF440042003C0000002800 +FD1D:000000000000000000000000000000000670090C08FF440042203C0000000000 +FD1E:000000000000000000000000000000000670090C08FF440042203C0000002800 +FD1F:000000000000000000000000004000000670090C08FF440042003C0000000000 +FD20:000000000000000000000000002000000670090C08FF440042003C0000002800 +FD21:0000000000040A0A3E29209088700000 +FD22:0000000000040A0A3E29209088700050 +FD23:0000000010040A0A3E29209088700000 +FD24:0000000010040A0A3E29209088700050 +FD25:000000001000280054AA81FC40904438 +FD26:000000001000280054AA81FC40804438 +FD27:000000001000A80054AA81FC40804438 +FD28:00000000080014004AB580C070808080 +FD29:00000000000004000A00152A20204080 +FD2A:00000000000000000000152A20204080 +FD2B:0000000000000002050D162424408000 +FD2C:0000000000000012050D162424408000 +FD2D:00200000005004000A2411D820007F8018006000800008000000000000000000 +FD2E:00200000005004000A2411D820007F8018006000800000000000000000000000 +FD2F:00200000005024000A2411D820007F8018006000800000000000000000000000 +FD30:0000000000200000005004000A2411D820007000880000000000000000000000 +FD31:0000000000000000000000000000002423D86400E8002800240014000C000000 +FD32:0000000000000020000000500000002423D86400E8002800240014000C000000 +FD33:00000010101016191E20D02000000000 +FD34:0000000000000000000000000000100028920492FFED00001000000000000000 +FD35:0000000000000000000000000000100028920492FFED00000000000000000000 +FD36:0000000000000000000010000000100028920492FFED00000000000000000000 +FD37:0000000000000000001000000028100028920492FFED00001000000000000000 +FD38:0000000000000000001000000028100028920492FFED00000000000000000000 +FD39:0000000000000000001010000028100028920492FFED00000000000000000000 +FD3A:00000010101016191E22D12000000000 +FD3B:00000010121016191E22D12000000000 +FD3C:010204111214101010100F0000000000 +FD3D:01020411121410101010100000000000 +FD3E:0000007E018C023004C00F000A0035806AC035800A000F0004C00230018C007E +FD3F:00007E0031800C40032000F0005001AC035601AC005000F003200C4031807E00 +FD40:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000 +FD41:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000 +FD42:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DF661867DBE7D867FFE0000 +FD43:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000 +FD44:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DB66DB661867DF67DF67FFE0000 +FD45:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DBE61867DF67D867FFE0000 +FD46:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000 +FD47:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000 +FD48:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000 +FD49:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000 +FD4A:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DB661867DB67DB67FFE0000 +FD4B:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000 +FD4C:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000 +FD4D:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000 +FD4E:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DBE618E7DBE7D867FFE0000 +FD4F:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000 +FD50:0000000000000000000000000028020005040084FFFC50002100000000000000 +FD51:00000000000000000000000000141080294204220BFF10002400200012000C00 +FD52:0000000000000000000000000028210052840844FFFC00002000000000000000 +FD53:0000000000000000000000000028020005040084FFFC50002000000000000000 +FD54:0000000000000000000002000028020005040084FFFC28001000000000000000 +FD55:0000000000000000000000000028200050040804FFFC02802100000000000000 +FD56:0000000000000000000000000028200050040804FFFC02800100000000000000 +FD57:0000000000000000000000000028200050040804FFFC02802100000000000000 +FD58:000000000000000000000000000020085014080217FF21404088400024001800 +FD59:0000000000000000000000000000201050280804FFFC02800110000000000000 +FD5A:000000000000000000000000000000084814540253FF48A04440380000002800 +FD5B:000000000000000000000000000000084814540253FF48A04440380000000000 +FD5C:0000000000000000000000000000210052950855FFFF00002000000000000000 +FD5D:0000000000000000000000000000210052950855FFFF00000100000000000000 +FD5E:000000000000000000000000000001009295A855A7FF90008900700000000000 +FD5F:00000000000000000000000000004000A02A102A2FFF45008200800048003000 +FD60:00000000000000000000000000002000502A082AFFFE02800100000000000000 +FD61:00000000000000000000000000002000502A082AFFFE02802100000000000000 +FD62:00000000000000000000000000002000502A082A7FFF42804100400040000000 +FD63:00000000000000000000000000000000002A002AFFFE2A801100000000000000 +FD64:00000000000000000000000000004204A52A10AA2FD740008000800048003000 +FD65:0000000000000000000000000000210252950855FFEE00000000000000000000 +FD66:00000000000000000000000000002004502A082A7FD742804100400040000000 +FD67:00000000000000000008000000144200A52A10AAFFFF80008000800080000000 +FD68:00000000000000000008000000140200052A00AAFFFE28001000000000000000 +FD69:000000000000000000040000000A01009295A855A7FF90008900700000005000 +FD6A:00000000000000000008200000142000502A082A17FF22804100400024001800 +FD6B:00000000000000000008200000142000502A082AFFFE02800100000000000000 +FD6C:00000000000000000008000000142000502A082A7FFF42804100400040000000 +FD6D:00000000000000000008000000140000002A002AFFFE2A801100000000000000 +FD6E:000000000000000000000002000001029295A855A7EB90008800700000000000 +FD6F:00000000000000000000000400004204A52A10AAFFD780008000800080000000 +FD70:00000000000000000000020400000204052A00AAFFD428001000000000000000 +FD71:00000000000000000000002000202020502C083217FF22804100400024001800 +FD72:00000000000000000000002000202020502C0832FFFC02800100000000000000 +FD73:00000000000000000000002000200020002C0032FFFC2A801100000000000000 +FD74:00000000000000000000002000200020902CA832A7FF92808900700000005000 +FD75:0000000000000000000000000000211E5292084C7FF340004100400040000000 +FD76:0000000000000000000000000000101E2812040C3FF321402080200020000000 +FD77:00000000000000000000000000000000000C0010FFFE52802100000000000000 +FD78:0000000000000000000000000000001E9012A80CA7F391408880700000000000 +FD79:0000000000000000000000080000101E2812040C3FF321402080200020000000 +FD7A:0000000000000000000000080000001E9012A80CA7F391408880700000005000 +FD7B:0000000000000000000000080000001E9012A80CA7F391408880700000000000 +FD7C:00000000000000000000010800002108529408547FEF40004000400040000000 +FD7D:00000000000000000008010000080114028C0044FFFC28001000000000000000 +FD7E:00000000000000000000000A00002004500A080A17F721404080400024001800 +FD7F:00000000000000000000001400002008501408147FEF42804100400040000000 +FD80:0000000000000000000000020002084214A202121FFD10001000100010000000 +FD81:0000000000000000000000020002004224A22A1229FD240022001C0000001400 +FD82:0000000000000000000000020002004224A22A1229FD240022001C0000000000 +FD83:0000000000000000000000080008210852880848FFF000002100000000000000 +FD84:000000000000000000000002000220825142082217FD20004880400024001800 +FD85:00000000000000000000008200022082514208227FFD40004000400040000000 +FD86:0000000000000000000001040004010402840044FFF828001000000000000000 +FD87:00000000000000000000000200021002280204020BFD10A02040200012000C00 +FD88:0000000000000000000000080008200850080808FFF002800100000000000000 +FD89:0000000000000000000000000000210052800848FFF400142008000000000000 +FD8A:0000000000000000000000000000020005000088FFF450142008000000000000 +FD8B:000000000000000000000000000001009280A840A7FF90148808700000005000 +FD8C:0000000000000000000000000000210052800848FFF400140108000000000000 +FD8D:0000000000000000000000000000010002800048FFF428141108000000000000 +FD8E:0000000000000000000001000000210052800848FFF400142008000000000000 +FD8F:0000000000000000000001000000010002800048FFF428141008000000000000 +FD90:00007FFE618E6FB663B66FB66F8E7FFE7FFE73CE6DB671B67DB673CE7FFE0000 +FD91:00007FFE618E6FB663B66FB66F8E7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000 +FD92:0000000000000000000020000000210052800848FFF400140108000000000000 +FD93:00000000000000000000001800042012502A082AFFDC02802100000000000000 +FD94:00000000000000000000001800040012002A002AFFDC2A801100000000000000 +FD95:0000000000000000000000000008010002880048FFF028001000000000000000 +FD96:000000000000000000000000000400804944542453FB48004400380000000000 +FD97:00000000000000000000000000042080514408247FFB40004080400040000000 +FD98:0000000000000000000000000008010002880048FFF028001100000000000000 +FD99:000000000000000000000000000400809144A824A7FB90008880700000000000 +FD9A:000000000000000000000000000400004804540453FB48A04440380000002800 +FD9B:000000000000000000000000000400004804540453FB48A04440380000000000 +FD9C:00000000000000000000000000000800140402041FFB10A0104A100010000000 +FD9D:0000000000000000000000000000000000020002FFFC29401094000000000000 +FD9E:000000000000000000000080000000809142A822A7FD90008804700000005000 +FD9F:000000000000000000000000000A00809142A822A7FD90008840700000005000 +FDA0:000000000000000000000000000A00809142A822A7FD90008880700000000000 +FDA1:000000000000000000000080000A00809142A822A7FD90008800700000005000 +FDA2:000000000000000000000080000A00809142A822A7FD90008800700000000000 +FDA3:000000000000000000000000000A00004802540253FD48A04440380000002800 +FDA4:000000000000000000000000000A00004802540253FD48A04440380000000000 +FDA5:000000000000000000000000000000089014A802A7FF91408888700000005000 +FDA6:000000000000000000000000000001089294A842A7FF90008808700000000000 +FDA7:000000000000000000000000000000089014A802A7FF91408888700000000000 +FDA8:000000000000000000000100000001009295A855A7FF90008800700000000000 +FDA9:000000000000000000000000000001029295A855A7EF90008800700000005000 +FDAA:000000000000000000040000000A01009295A855A7FF90008800700000005000 +FDAB:000000000000000000000002000001029295A855A7FF90008800700000005000 +FDAC:000000000000000000000004000400844944542453FB48004480380000002800 +FDAD:000000000000000000000004000400044804540453FB48A04440380000002800 +FDAE:000000000000000000000000000000804944542453FB4800440A380000002800 +FDAF:000000000000000000000000000000804944542453FB4800448A380000002800 +FDB0:000000000000000000000000000000004804540453FB48A0444A380000002800 +FDB1:000000000000000000000000000000004800540053FF48AA4444380000002800 +FDB2:00000000000000000000000A00000004480A540A53F748A04440380000002800 +FDB3:000000000000000000000000000400804944542453FB48004400380000002800 +FDB4:00000000000000000014000000082014500C0804FFFC02800100000000000000 +FDB5:0000000000000000000000080008010802880048FFF828001000000000000000 +FDB6:0000000000000000000000000000001E9012A80CA7F391408880700000005000 +FDB7:000000000000000000000006001800209018A80EA7F192808900700000005000 +FDB8:0000000000000000000000000008210052880848FFF800000100000000000000 +FDB9:000000000000000000000080000000809140A820A7FF900A8804700000005000 +FDBA:0000000000000000000000080008010802880048FFF828001100000000000000 +FDBB:000000000000000000000006001820205018080E7FF142804100400040000000 +FDBC:00000000000000000000000400042084514408247FFB40004080400040000000 +FDBD:0000000000000000000000000002104028A204120BFD10002040200012000C00 +FDBE:000000000000000000000000000001089294A842A7FF90008808700000005000 +FDBF:000000000000000000000000000001089294A842A7FF90008900700000005000 +FDC0:000000000000000000000000000000809140A820A7FF900A8844700000005000 +FDC1:00000000000000000000000400000004480A540A53F748A04440380000002800 +FDC2:000000000000000000000000000000809142A822A7FF90008804700000005000 +FDC3:000000000000000000000003000C001000080004FFF829401080000000000000 +FDC4:0000000000000000000000000000010002860048FFFF28001100000000000000 +FDC5:00000000000000000000000000000004002A002AFFDC55002200000000000000 +FDC6:000000000000000000000100000001009295A855A7FF90008800700000005000 +FDC7:000000000000000000000000000400809144A824A7FB90008880700000005000 +FDC8:00007FFE618E6FB663B66FB66F8E7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +FDC9:00007FFE618E6FB663B66FB66F8E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +FDCA:00007FFE618E6FB663B66FB66F8E7FFE7FFE71866FB66F866FB671B67FFE0000 +FDCB:00007FFE618E6FB663B66FB66F8E7FFE7FFE718E6FB66F8E6FB6718E7FFE0000 +FDCC:00007FFE618E6FB663B66FB66F8E7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000 +FDCD:00007FFE618E6FB663B66FB66F8E7FFE7FFE718E6FB66FB66FB6718E7FFE0000 +FDCE:00007FFE618E6FB663B66FB66F8E7FFE7FFE71866FBE6F8E6FBE71867FFE0000 +FDCF:00007FFE618E6FB663B66FB66F8E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000 +FDD0:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDB7EDB7EDB7E3CFFFFFFFFF +FDD1:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3DFED9FEDDFEDDFE38FFFFFFFFF +FDD2:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE387EDF7ED87EDBFE387FFFFFFFF +FDD3:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE38FEDF7EDC7EDF7E38FFFFFFFFF +FDD4:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3AFEDAFED87EDEFE3EFFFFFFFFF +FDD5:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE387EDBFED87EDF7E387FFFFFFFF +FDD6:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDBFED8FEDB7E3CFFFFFFFFF +FDD7:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE387EDF7EDEFEDDFE3DFFFFFFFFF +FDD8:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDB7EDCFEDB7E3CFFFFFFFFF +FDD9:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDB7EDC7EDF7E3CFFFFFFFFF +FDDA:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDB7ED87EDB7E3B7FFFFFFFF +FDDB:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE38FEDB7ED8FEDB7E38FFFFFFFFF +FDDC:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDB7EDBFEDB7E3CFFFFFFFFF +FDDD:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE38FEDB7EDB7EDB7E38FFFFFFFFF +FDDE:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE387EDBFED8FEDBFE387FFFFFFFF +FDDF:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE387EDBFED8FEDBFE3BFFFFFFFFF +FDE0:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFB7E3B7EFB7E1CFFFFFFFFF +FDE1:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1DFEF9FE3DFEFDFE18FFFFFFFFF +FDE2:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE187EFF7E387EFBFE187FFFFFFFF +FDE3:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE18FEFF7E3C7EFF7E18FFFFFFFFF +FDE4:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1AFEFAFE387EFEFE1EFFFFFFFFF +FDE5:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE187EFBFE387EFF7E187FFFFFFFF +FDE6:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFBFE38FEFB7E1CFFFFFFFFF +FDE7:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE187EFF7E3EFEFDFE1DFFFFFFFFF +FDE8:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFB7E3CFEFB7E1CFFFFFFFFF +FDE9:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFB7E3C7EFF7E1CFFFFFFFFF +FDEA:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFB7E387EFB7E1B7FFFFFFFF +FDEB:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE18FEFB7E38FEFB7E18FFFFFFFFF +FDEC:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFB7E3BFEFB7E1CFFFFFFFFF +FDED:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE18FEFB7E3B7EFB7E18FFFFFFFFF +FDEE:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE187EFBFE38FEFBFE187FFFFFFFF +FDEF:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE187EFBFE38FEFBFE1BFFFFFFFFF +FDF0:00000000040004000400040C049204A20B7C3020400040003FF0000000000000 +FDF1:0000000002500200022002500230021005E01800200020001FF8000000000000 +FDF2:020002000240014205820602009208921892289218920F600000000000000000 +FDF3:0000000C003000C40104010400C412241E14121411E424004000000000000000 +FDF4:06081814010815140A60000001880614003808C0090005FC24181A6001800060 +FDF5:00000000040004000400240C549234A22B7C4020380014002800200020000000 +FDF6:0000000010001000100010009254955563A901020E1C00000000000000000000 +FDF7:000000000020002010203020502633280CDE0000050000000000000000000000 +FDF8:00000000100010001000100012A412AA2D464002300428185000400040000000 +FDF9:00000000040004000400040C049204A20B7C082050004C004200240018000000 +FDFA:2AA06AA0AAAA6A2D145680C480287FC82029602ABFD7440204553D035351A0A6 +FDFB:000008000804480A480137FF000002A412A032A452AA32210CDF000000040000 +FDFC:0000028002800280028002A002A0224222021CA2000C00000000000000000000 +FDFD:70A95FFF7000C5D5145515D5557D75C0C03B50295FFF7000758554957F9DC030 +FDFE:00007FFE618E6FB663B66FB66F8E7FFE7FFE61866FBE638E6FBE6F867FFE0000 +FDFF:00007FFE618E6FB663B66FB66F8E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000 +FE00:AAAA00018000223DA2402239940408798000008181800281808003E180005555 +FE01:AAAA00018000223DA2402239940408798000038180400181820003C180005555 +FE02:AAAA00018000223DA24022399404087980000381804001818040038180005555 +FE03:AAAA00018000223DA24022399404087980000241824003C18040004180005555 +FE04:AAAA00018000223DA240223994040879800003C1820003818040038180005555 +FE05:AAAA00018000223DA240223994040879800001C1820003818240018180005555 +FE06:AAAA00018000223DA240223994040879800003C1804000818100010180005555 +FE07:AAAA00018000223DA24022399404087980000181824001818240018180005555 +FE08:AAAA00018000223DA24022399404087980000181824001C18040038180005555 +FE09:AAAA00018000223DA240223994040879800008319848284988483E3180005555 +FE0A:AAAA00018000223DA240223994040879800008119830285188103E7D80005555 +FE0B:AAAA00018000223DA240223994040879800008719808283188403E7980005555 +FE0C:AAAA00018000223DA240223994040879800008719808283188083E7180005555 +FE0D:AAAA00018000223DA240223994040879800008499848287988083E0980005555 +FE0E:AAAA00018000223DA240223994040879800008799840287188083E7180005555 +FE0F:AAAA00018000223DA240223994040879800008399840287188483E3180005555 +FE10:00000000000C0004000400080000000000000000000000000000000000000000 +FE11:0000000000200010000800080000000000000000000000000000000000000000 +FE12:0000000000000018002400240018000000000000000000000000000000000000 +FE13:00000000000C000C000000000000000C000C0000000000000000000000000000 +FE14:00000000000C000C000000000000000C00040004000800000000000000000000 +FE15:0000000000040004000400040004000400040000000400040000000000000000 +FE16:0000000000780084008400040008001000100000001000100000000000000000 +FE17:00000000000000000000000000007FFE400247E2581A60064002000000000000 +FE18:00000000000040026006581A47E240027FFE0000000000000000000000000000 +FE19:0000000001800180000000000000018001800000000000000180018000000000 +FE1A:00007FFE61866FBE638E6FBE6F867FFE7FFE7B8673B67B867BB671B67FFE0000 +FE1B:00007FFE61866FBE638E6FBE6F867FFE7FFE7B8E73B67B8E7BB6718E7FFE0000 +FE1C:00007FFE61866FBE638E6FBE6F867FFE7FFE7BC673BE7BBE7BBE71C67FFE0000 +FE1D:00007FFE61866FBE638E6FBE6F867FFE7FFE7B8E73B67BB67BB6718E7FFE0000 +FE1E:00007FFE61866FBE638E6FBE6F867FFE7FFE7B8673BE7B8E7BBE71867FFE0000 +FE1F:00007FFE61866FBE638E6FBE6F867FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000 +FE20:000F3040000000000000000000000000 +FE21:00F00C02000000000000000000000000 +FE22:001E2140000000000000000000000000 +FE23:00028478000000000000000000000000 +FE24:00001F00000000000000000000000000 +FE25:0000F800000000000000000000000000 +FE26:0000FF00000000000000000000000000 +FE27:0000000000000000000000000040300F +FE28:00000000000000000000000000020CF0 +FE29:00000000000000000000000000000F30 +FE2A:00000000000000000000000000000CF0 +FE2B:0000000000000000000000000000001F +FE2C:000000000000000000000000000000F8 +FE2D:000000000000000000000000000000FF +FE2E:001F1800000000000000000000000000 +FE2F:0018F800000000000000000000000000 +FE30:0000000000000000018001800000000000000000018001800000000000000000 +FE31:0000000000800080008000800080008000800080008000800080008000000000 +FE32:0000000000000000008000800080008000800080008000800000000000000000 +FE33:0000400040004000400040004000400040004000400040004000400040000000 +FE34:2000400040002000100010002000400040002000100010002000400040002000 +FE35:0000000000000000000000000000000000000FF0100820044002000000000000 +FE36:0000000000004002200410080FF0000000000000000000000000000000000000 +FE37:000000000000000000000000000000000000000001803E7C4002000000000000 +FE38:00000000000040023E7C01800000000000000000000000000000000000000000 +FE39:00000000000000000000000000000000000000001FF820044002000000000000 +FE3A:000000000000400220041FF80000000000000000000000000000000000000000 +FE3B:000000000000000000000000000000007FFE7FFE781E60064002000000000000 +FE3C:00000000000040026006781E7FFE7FFE00000000000000000000000000000000 +FE3D:0000000000000000000000000180066018186186066018186006000000000000 +FE3E:0000000000006006181806606186181806600180000000000000000000000000 +FE3F:0000000000000000000000000000000000000180066018186006000000000000 +FE40:0000000000006006181806600180000000000000000000000000000000000000 +FE41:000000000000000000000000000000000FFE0002000200020002000000000000 +FE42:00000000000040004000400040007FF000000000000000000000000000000000 +FE43:00000000000000000000000000000FFE08020FFA000A000A000E000000000000 +FE44:0000000000007000500050005FF040107FF00000000000000000000000000000 +FE45:0000000000700038001800180000000000000000000000000000000000000000 +FE46:00000000007800240014000C0000000000000000000000000000000000000000 +FE47:000000000000000000000000000000007FFE4002400240024002000000000000 +FE48:00000000000040024002400240027FFE00000000000000000000000000000000 +FE49:000039CE00000000000000000000000000000000000000000000000000000000 +FE4A:00007DBE00000000000000000000000000000000000000000000000000000000 +FE4B:0C30924961860000000000000000000000000000000000000000000000000000 +FE4C:0C30924961860C30924961860000000000000000000000000000000000000000 +FE4D:0000000000000000000000000000000000000000000000000000000039CE0000 +FE4E:000000000000000000000000000000000000000000000000000000007DBE0000 +FE4F:00000000000000000000000000000000000000000000000000000C3092496186 +FE50:0000000000000000000000000000000000000000000000000180010002000000 +FE51:0000000000000000000000000000000000000000000000000200010001800000 +FE52:0000000000000000000000000000000000000000000000000180018000000000 +FE53:00007FFE61866FBE638E6FBE6F867FFE7FFE618E6FF661C67DF6618E7FFE0000 +FE54:0000000000000000000000000000000000000180018000000180010002000000 +FE55:0000000000000000000000000000000000000180018000000180018000000000 +FE56:0000000000000000000000000000000001000280008001000000010000000000 +FE57:0000000000000000000000000000000000800080008000800000008000000000 +FE58:0000000000000000000000000000000000000000000007C00000000000000000 +FE59:0000000000000000000000000000000000800100010001000100008000000000 +FE5A:0000000000000000000000000000000001000080008000800080010000000000 +FE5B:0000000000000000000000000000000000400080018000800080004000000000 +FE5C:0000000000000000000000000000000002000100018001000100020000000000 +FE5D:0000000000000000000000000000000001C0010001000100010001C000000000 +FE5E:0000000000000000000000000000000003800080008000800080038000000000 +FE5F:000000000000000000000000000000000000028007C0028007C0028000000000 +FE60:0000000000000000000000000000000000000100028001000280014000000000 +FE61:0000000000000000000000000000000000000280010003800100028000000000 +FE62:0000000000000000000000000000000000000100010007C00100010000000000 +FE63:0000000000000000000000000000000000000000000003C00000000000000000 +FE64:0000000000000000000000000000000000000040008001000080004000000000 +FE65:0000000000000000000000000000000000000200010000800100020000000000 +FE66:000000000000000000000000000000000000000003C0000003C0000000000000 +FE67:00007FFE61866FBE638E6FBE6F867FFE7FFE73866FF663EE6DDE73DE7FFE0000 +FE68:0000000000000000000000000000000000000200010000800040000000000000 +FE69:0000000000000000000000000000000000000380050003800140038000000000 +FE6A:0000000000000000000000000000000002000240008001000240004000000000 +FE6B:000000000000000000000000000000000180024002C002C00200018000000000 +FE6C:00007FFE61866FBE638E6FBE6F867FFE7FFE73C66FBE63BE6DBE73C67FFE0000 +FE6D:00007FFE61866FBE638E6FBE6F867FFE7FFE738E6FB663B66DB6738E7FFE0000 +FE6E:00007FFE61866FBE638E6FBE6F867FFE7FFE73866FBE638E6DBE73867FFE0000 +FE6F:00007FFE61866FBE638E6FBE6F867FFE7FFE73866FBE638E6DBE73BE7FFE0000 +FE70:000C300C300000000000000000000000 +FE71:000C300C300000000000FF0000000000 +FE72:0C0C6428700000000000000000000000 +FE73:00000000000000000000020404040300 +FE74:000000000000000000000C300C300000 +FE75:00007FFE61866FBE638E6FBE6F867FFE7FFE61867DBE7B8677F677867FFE0000 +FE76:0000000C300000000000000000000000 +FE77:0000000C300000000000FF0000000000 +FE78:0C0E0810200000000000000000000000 +FE79:0C0E0810200000000000FF0000000000 +FE7A:00000000000000000000000000000C30 +FE7B:00000000000000000000FF0000000C30 +FE7C:00000004145860000000000000000000 +FE7D:00000004145860000000FF0000000000 +FE7E:00000018242418000000000000000000 +FE7F:00000018242418000000FF0000000000 +FE80:000000000000001C203C102000000000 +FE81:00013E40080808080808080000000000 +FE82:000870802020202020201F0000000000 +FE83:18201820080808080808080000000000 +FE84:304030402020202020201F0000000000 +FE85:00000C100C10000C12121E0204483000 +FE86:00000C100C10000C12121F0204483000 +FE87:0000000008080808080808000C100C10 +FE88:000000002020202020201F0030403040 +FE89:00000000304030400046484846423C00 +FE8A:000000003040304000404342423C0000 +FE8B:0000000C100C10000404F80000000000 +FE8C:0000000C100C10000404FB0000000000 +FE8D:00000008080808080808080000000000 +FE8E:000000202020202020201F0000000000 +FE8F:000000000000000422423C0000080000 +FE90:000000000000000422423F0000080000 +FE91:00000000000000080404FC0000100000 +FE92:00000000000000080404FF0000100000 +FE93:000000002400101824243C0000000000 +FE94:0000001200040C14243C070000000000 +FE95:000000001400000422423C0000000000 +FE96:000000001400000422423F0000000000 +FE97:00000000280000080404F80000000000 +FE98:00000000280000080404FF0000000000 +FE99:000010002400000422423C0000000000 +FE9A:000010002400000422423F0000000000 +FE9B:00002000480000080404F80000000000 +FE9C:00002000480000080404FF0000000000 +FE9D:00000000000000007E1020404840221C +FE9E:00000000000000007E1423404840211E +FE9F:00000000000000003806FE0010000000 +FEA0:00000000000000003806FF0010000000 +FEA1:00000000000000007E1020404040221C +FEA2:00000000000000007E1423404040211E +FEA3:0000000000000000700CFC0000000000 +FEA4:0000000000000000700CFF0000000000 +FEA5:00000000001000007E1020404040221C +FEA6:00000000001000007E1423404040211E +FEA7:0000000000200000700CFC0000000000 +FEA8:0000000000200000700CFF0000000000 +FEA9:000000000000080402427C0000000000 +FEAA:000000000000080402427F0000000000 +FEAB:000000002000080402427C0000000000 +FEAC:000000002000080402427F0000000000 +FEAD:00000000000000000402020204483000 +FEAE:00000000000000000402030204483000 +FEAF:00000000001000000402020204483000 +FEB0:00000000001000000402030204483000 +FEB1:000000000000000115155E4848300000 +FEB2:000000000000000115155F4848300000 +FEB3:00000000000000022A2AFC0000000000 +FEB4:00000000000000022A2AFF0000000000 +FEB5:00000008001200000115155E48483000 +FEB6:000000080012000115155F4848300000 +FEB7:00000010002400022A2AFC0000000000 +FEB8:00000010002400022A2AFF0000000000 +FEB9:000000000000000006194E4848300000 +FEBA:000000000000000006194F4848300000 +FEBB:00000000000000000C52FC0000000000 +FEBC:00000000000000000C52FF0000000000 +FEBD:000000000004000006194E4848300000 +FEBE:000000000004000006194F4848300000 +FEBF:00000000000800000C52FC0000000000 +FEC0:00000000000800000C52FF0000000000 +FEC1:000000202020202C32227C0000000000 +FEC2:000000202020202C32227F0000000000 +FEC3:000000202020202C3222FC0000000000 +FEC4:000000202020202C3222FF0000000000 +FEC5:000000202420202C32227C0000000000 +FEC6:000000202420202C32227F0000000000 +FEC7:000000202420202C3222FC0000000000 +FEC8:000000202420202C3222FF0000000000 +FEC9:000000000000001824201C204040423C +FECA:000000000000000030301F204040423C +FECB:00000000000000182420FE0000000000 +FECC:00000000000000181808F70000000000 +FECD:000000000800001824201C204040423C +FECE:000000000010000030301F204040423C +FECF:00000000080000182420FE0000000000 +FED0:00000000080000181808F70000000000 +FED1:0000000800060A0642423C0000000000 +FED2:0000000800060A0642423F0000000000 +FED3:0000001000003824140CF80000000000 +FED4:0000001000003824140CFB0000000000 +FED5:000000002400001C120A264244380000 +FED6:000000002400001C120A274244380000 +FED7:0000004800003824140CF80000000000 +FED8:0000004800003824140CFB0000000000 +FED9:000000020A120A2242423C0000000000 +FEDA:000000020A120A2242423F0000000000 +FEDB:00000004081020403C02FE0000000000 +FEDC:00000004081020403C02FF0000000000 +FEDD:000000020202020202224242443C0000 +FEDE:000000020202020202234242443C0000 +FEDF:00000004040404040404F80000000000 +FEE0:00000004040404040404FB0000000000 +FEE1:00000000000000001C061E2020202020 +FEE2:00000000000000001C061F2020202020 +FEE3:00000000000000081432EE0000000000 +FEE4:00000000000000081432EF0000000000 +FEE5:00000000001000000422424244380000 +FEE6:00000000001000000422434244380000 +FEE7:00000000100000080404F80000000000 +FEE8:00000000100000080404FB0000000000 +FEE9:000000000000101824243C0000000000 +FEEA:0000000004040C14243C070000000000 +FEEB:000000000010083C2A3AF60000000000 +FEEC:000000000000000C1414FF140C000000 +FEED:000000000000000C12121E0204483000 +FEEE:000000000000000C12121F0204483000 +FEEF:0000000000000000044A484442423C00 +FEF0:00000000000000000000434442423C00 +FEF1:0000000000000000044A4844423C0028 +FEF2:000000000000000000004344423C0028 +FEF3:00000000000000080804F80028000000 +FEF4:00000000000000080804FB0028000000 +FEF5:000008728222120A040C141C00000000 +FEF6:000008728222120A0E0A136000000000 +FEF7:000030423242120A040C141C00000000 +FEF8:000030423242120A0E0A136000000000 +FEF9:0000020222120A040C141C000C100C10 +FEFA:000000020222120A0E0A13600C100C10 +FEFB:000000020222120A040C141C00000000 +FEFC:000000020222120A0E0A136000000000 +FEFD:00007FFE61866FBE638E6FBE6F867FFE7FFE618E6FB663B66FB66F8E7FFE0000 +FEFE:00007FFE61866FBE638E6FBE6F867FFE7FFE61866FBE638E6FBE6F867FFE0000 +FEFF:AAAA0001F4511458A55546D2F4510001F1DE4A10F19E4851F390000180005555 +FF00:00007FFE61866FBE638E6FBE6FBE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000 +FF01:0000000000000000018001800180018001800180018000000180018000000000 +FF02:000000000C300C300C300C300000000000000000000000000000000000000000 +FF03:0000000000000000030C030C030C3FFC0C300C303FFC30C030C030C000000000 +FF04:000000000000000001801FF8618661801F8001F8018661861FF8018000000000 +FF05:00000000000000001E06619861981E6001800180067819861986607800000000 +FF06:000000000000000007E018181818181807E01F866066601860781F8600000000 +FF07:0000000001800180018001800000000000000000000000000000000000000000 +FF08:000000000000003000C000C003000300030003000300030000C000C000300000 +FF09:0000000000000C000300030000C000C000C000C000C000C0030003000C000000 +FF0A:00000000000000000000000001806186199807E0199861860180000000000000 +FF0B:0000000000000000000000000180018001807FFE018001800180000000000000 +FF0C:00000000000000000000000000000000000000000000000003C000C000C00300 +FF0D:0000000000000000000000000000000000003FFC000000000000000000000000 +FF0E:00000000000000000000000000000000000000000000000003C003C000000000 +FF0F:0000000000000000000C000C003000C000C0030003000C003000300000000000 +FF10:000000000000000003C00C30300C303C30CC330C3C0C300C0C3003C000000000 +FF11:00000000000000000180078019800180018001800180018001801FF800000000 +FF12:00000000000000000FF0300C300C000C00F003000C00300030003FFC00000000 +FF13:00000000000000000FF0300C300C000C03F0000C000C300C300C0FF000000000 +FF14:0000000000000000003000F003300C30303030303FFC00300030003000000000 +FF15:00000000000000003FFC3000300030003FF0000C000C000C300C0FF000000000 +FF16:000000000000000003F00C00300030003FF0300C300C300C300C0FF000000000 +FF17:00000000000000003FFC000C000C00300030003000C000C000C000C000000000 +FF18:00000000000000000FF0300C300C300C0FF0300C300C300C300C0FF000000000 +FF19:00000000000000000FF0300C300C300C0FFC000C000C000C00300FC000000000 +FF1A:00000000000000000000000003C003C000000000000003C003C0000000000000 +FF1B:00000000000000000000000003C003C000000000000003C000C000C003000000 +FF1C:0000000000000000000000180060018006001800060001800060001800000000 +FF1D:00000000000000000000000000003FFC0000000000003FFC0000000000000000 +FF1E:0000000000000000000018000600018000600018006001800600180000000000 +FF1F:00000000000000000FF0300C300C000C003000C000C0000000C000C000000000 +FF20:000000000000000003F00C0C30CC333C330C330C330C30FC0C0003FC00000000 +FF21:000000000000000003C00C300C30300C300C3FFC300C300C300C300C00000000 +FF22:00000000000000003FF0300C300C300C3FF0300C300C300C300C3FF000000000 +FF23:00000000000000000FF0300C300C3000300030003000300C300C0FF000000000 +FF24:00000000000000003FC03030300C300C300C300C300C300C30303FC000000000 +FF25:00000000000000003FFC3000300030003FF030003000300030003FFC00000000 +FF26:00000000000000003FFC3000300030003FF03000300030003000300000000000 +FF27:00000000000000000FF0300C300C3000300030FC300C300C303C0FCC00000000 +FF28:0000000000000000300C300C300C300C3FFC300C300C300C300C300C00000000 +FF29:00000000000000001FF8018001800180018001800180018001801FF800000000 +FF2A:000000000000000007FE006000600060006000600060606060601F8000000000 +FF2B:0000000000000000300C303030C033003C003C00330030C03030300C00000000 +FF2C:00000000000000003000300030003000300030003000300030003FFC00000000 +FF2D:0000000000000000300C300C3C3C3C3C33CC33CC300C300C300C300C00000000 +FF2E:0000000000000000300C3C0C3C0C330C330C30CC30CC303C303C300C00000000 +FF2F:00000000000000000FF0300C300C300C300C300C300C300C300C0FF000000000 +FF30:00000000000000003FF0300C300C300C3FF03000300030003000300000000000 +FF31:00000000000000000FF0300C300C300C300C300C300C33CC3C3C0FF0000F0000 +FF32:00000000000000003FF0300C300C300C3FF030C030303030300C300C00000000 +FF33:00000000000000000FF0300C300C30000F0000F0000C300C300C0FF000000000 +FF34:00000000000000007FFE01800180018001800180018001800180018000000000 +FF35:0000000000000000300C300C300C300C300C300C300C300C300C0FF000000000 +FF36:0000000000000000600660066006181818181818066006600180018000000000 +FF37:0000000000000000300C300C300C300C33CC33CC3C3C3C3C300C300C00000000 +FF38:0000000000000000300C300C0C300C3003C003C00C300C30300C300C00000000 +FF39:0000000000000000600660061818181806600180018001800180018000000000 +FF3A:00000000000000003FFC000C000C003000C003000C00300030003FFC00000000 +FF3B:00000000000003F0030003000300030003000300030003000300030003F00000 +FF3C:0000000000000000300030000C000300030000C000C00030000C000C00000000 +FF3D:0000000000000FC000C000C000C000C000C000C000C000C000C000C00FC00000 +FF3E:0000000003C00C30300C00000000000000000000000000000000000000000000 +FF3F:000000000000000000000000000000000000000000000000000000007FFE0000 +FF40:0000060001800060000000000000000000000000000000000000000000000000 +FF41:0000000000000000000000000FF0300C000C0FFC300C300C303C0FCC00000000 +FF42:00000000000030003000300033F03C0C300C300C300C300C3C0C33F000000000 +FF43:0000000000000000000000000FF0300C3000300030003000300C0FF000000000 +FF44:000000000000000C000C000C0FCC303C300C300C300C300C303C0FCC00000000 +FF45:0000000000000000000000000FF0300C300C3FFC30003000300C0FF000000000 +FF46:00000000000000780180018001801FF801800180018001800180018000000000 +FF47:00000000000000000000000C0FCC3030303030300FC00C000FF0300C300C0FF0 +FF48:00000000000030003000300033F03C0C300C300C300C300C300C300C00000000 +FF49:00000000000001800180000007800180018001800180018001801FF800000000 +FF4A:00000000000000300030000000F0003000300030003000300030003030C00F00 +FF4B:000000000000300030003000303030C033003C00330030C03030300C00000000 +FF4C:00000000000007800180018001800180018001800180018001801FF800000000 +FF4D:0000000000000000000000007E78618661866186618661866186618600000000 +FF4E:00000000000000000000000033F03C0C300C300C300C300C300C300C00000000 +FF4F:0000000000000000000000000FF0300C300C300C300C300C300C0FF000000000 +FF50:00000000000000000000000033F03C0C300C300C300C300C3C0C33F030003000 +FF51:0000000000000000000000000FCC303C300C300C300C300C303C0FCC000C000C +FF52:00000000000000000000000033F03C0C300C3000300030003000300000000000 +FF53:0000000000000000000000000FF0300C30000F0000F0000C300C0FF000000000 +FF54:00000000000000000180018001801FF801800180018001800180007800000000 +FF55:000000000000000000000000300C300C300C300C300C300C303C0FCC00000000 +FF56:000000000000000000000000300C300C300C0C300C300C3003C003C000000000 +FF57:00000000000000000000000060066186618661866186618661861E7800000000 +FF58:000000000000000000000000300C300C0C3003C003C00C30300C300C00000000 +FF59:000000000000000000000000300C300C300C300C300C0C3C03CC000C000C0FF0 +FF5A:0000000000000000000000003FFC000C003000C003000C0030003FFC00000000 +FF5B:00000000000000F00300030000C000C003000C00030000C000C00300030000F0 +FF5C:0000000001800180018001800180018001800180018001800180018001800180 +FF5D:0000000000000F0000C000C00300030000C0003000C00300030000C000C00F00 +FF5E:0000000000001E06618660780000000000000000000000000000000000000000 +FF5F:0000000000000186061806181860186018601860186018600618061801860000 +FF60:0000000000006180186018600618061806180618061806181860186061800000 +FF61:00000000000000000000000030484830 +FF62:3E202020202020202020200000000000 +FF63:0000000000020202020202020202023E +FF64:00000000000000000000000000402010 +FF65:00000000000000181800000000000000 +FF66:00007E0202027E020202040408106000 +FF67:00000000007E02041408080810102000 +FF68:00000000000204081868080808080800 +FF69:000000000808087F4141010202041800 +FF6A:000000000000003E0808080808087F00 +FF6B:000000000004047F040C142444040C00 +FF6C:000000002020207F1112100808080800 +FF6D:000000000000003C040404047F000000 +FF6E:0000000000007E02027E02027E000000 +FF6F:00000000000000292929020204083000 +FF70:000000000000403F0000000000000000 +FF71:00007F01090A0A080808081010202000 +FF72:000101010202040C1464040404040400 +FF73:000808087F4141410101010202041800 +FF74:0000003E0808080808080808087F0000 +FF75:0004047F040C0C141414242444040C00 +FF76:000808087F0909090911111222224400 +FF77:001010101E7008080F78080804040400 +FF78:0008080F111121410202040408106000 +FF79:002020203F2424440404040808102000 +FF7A:0000007E0202020202020202027E0000 +FF7B:001212127F1212121204040408081000 +FF7C:00003800000071010102020408106000 +FF7D:0000007E020404040808141222214100 +FF7E:00101010101779111212101010080700 +FF7F:00014141210102020204040808102000 +FF80:0008080F111129450202040408106000 +FF81:00020C384808087F0808080810106000 +FF82:00005252524202040404080810204000 +FF83:00003E0000007F080808080810102000 +FF84:00202020202038242220202020202000 +FF85:00080808087F08080808081010204000 +FF86:0000003E0000000000000000007F0000 +FF87:00007F010101221A04060A0911214000 +FF88:000808087F0204040A19294808080800 +FF89:00000202020202040404080810204000 +FF8A:00001212121212111121212121414000 +FF8B:00404040404046784040404040201E00 +FF8C:00007F01010102020204040808102000 +FF8D:00001028284444040202020101010000 +FF8E:000808087F08082A2A2A494949080800 +FF8F:00007E02020204242418181008080800 +FF90:000038060100300C0200700C02010000 +FF91:00080808080810101012222127394100 +FF92:0001010102320A04060A091111204000 +FF93:00003E080808087F0808080808080700 +FF94:00202020277921121210100808080800 +FF95:000000003C04040404040404047F0000 +FF96:0000007E020202027E02020202027E00 +FF97:00003C0000007E020202040408102000 +FF98:00022222222222220204040408081000 +FF99:000008282828282929292A2A4C4C4800 +FF9A:00004040404040424242444448506000 +FF9B:0000007E42424242424242427E420000 +FF9C:00007E42424242020404040808102000 +FF9D:00006010000101010102020408106000 +FF9E:00001048241000000000000000000000 +FF9F:00003048483000000000000000000000 +FFA0:00000000000000000000000000000000 +FFA1:0000000000000000007E020202020000 +FFA2:0000000000000000006C242424240000 +FFA3:00000000000000007414141A11000000 +FFA4:000000000000000000404040407E0000 +FFA5:0000000000000000002424242A390000 +FFA6:000000000000000000222722253A0000 +FFA7:0000000000000000007E4040407E0000 +FFA8:0000000000000000006C4848486C0000 +FFA9:0000000000000000003C043C203C0000 +FFAA:00000000000000000076127242720000 +FFAB:000000000000000000EE2AEA8AEE0000 +FFAC:000000000000000000EA2AEE8AEE0000 +FFAD:000000000000000000E424E48AEA0000 +FFAE:000000000000000000EE28EE88EE0000 +FFAF:000000000000000000FF2AEA8AFF0000 +FFB0:000000000000000000E42EE48AE40000 +FFB1:0000000000000000007C4444447C0000 +FFB2:00000000000000000042427E427E0000 +FFB3:000000000000000000AAAAEEAAEE0000 +FFB4:0000000000000000005454745A710000 +FFB5:00000000000000000010101028440000 +FFB6:0000000000000000002424245A910000 +FFB7:00000000000000101038444444380000 +FFB8:0000000000000000007C101028440000 +FFB9:0000000000000000007E24245A910000 +FFBA:000000000000000038007C1028440000 +FFBB:0000000000000000007E027E02020000 +FFBC:0000000000000000007E407E407E0000 +FFBD:0000000000000000007E2424247E0000 +FFBE:00000000000000000038FE3844380000 +FFBF:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63866DBE638E6DBE63BE7FFE0000 +FFC0:00007FFE61866FBE638E6FBE6FBE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000 +FFC1:00007FFE61866FBE638E6FBE6FBE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000 +FFC2:00000000000000000020203820200000 +FFC3:00000000000000000028283828280000 +FFC4:00000000000000000020382038200000 +FFC5:00000000000000000028382838280000 +FFC6:00000000000000000008083808080000 +FFC7:00000000000000000014147414140000 +FFC8:00007FFE61866FBE638E6FBE6FBE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000 +FFC9:00007FFE61866FBE638E6FBE6FBE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000 +FFCA:00000000000000000008380838080000 +FFCB:00000000000000000014741474140000 +FFCC:000000000000000000101010107C0000 +FFCD:000000000000000000040414147E0000 +FFCE:0000000000000000000A0A2A2AFE0000 +FFCF:000000000000000000040414147C0000 +FFD0:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000 +FFD1:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000 +FFD2:000000000000000000282828287C0000 +FFD3:0000000000000000007C101010100000 +FFD4:0000000000000004043C141C14140000 +FFD5:000000000000000A0A7A2A3A2A2A0000 +FFD6:0000000000000004043C141414140000 +FFD7:0000000000000000007C282828280000 +FFD8:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000 +FFD9:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000 +FFDA:00000000000000000000007E00000000 +FFDB:00000000000000000008081828080000 +FFDC:00000000000000000008080808080000 +FFDD:00007FFE61866FBE638E6FBE6FBE7FFE7FFE638E6DB66DB66DB6638E7FFE0000 +FFDE:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63866DBE6D8E6DBE63867FFE0000 +FFDF:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000 +FFE0:0000000000000000018001801FF861866180618061861FF80180018000000000 +FFE1:000000000000000001F80600060006007FE00600060006001FF8780600000000 +FFE2:00000000000000000000000000000000000000003FFC000C000C000C00000000 +FFE3:000000003FFC0000000000000000000000000000000000000000000000000000 +FFE4:0000000000000000018001800180018000000000018001800180018000000000 +FFE5:000000000000000060061818066001807FFE01807FFE01800180018000000000 +FFE6:00000000000000001818181818187FFE19987FFE1E781E781818181800000000 +FFE7:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61866FF663EE6FDE61DE7FFE0000 +FFE8:08080808080808080808080808080808 +FFE9:000000000010207E2010000000000000 +FFEA:0000000000081C2A0808080000000000 +FFEB:00000000000008047E04080000000000 +FFEC:00000000000808082A1C080000000000 +FFED:000000000000007E7E7E7E7E7E000000 +FFEE:00000000000018244242241800000000 +FFEF:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61866FBE638E6FBE61BE7FFE0000 +FFF0:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000 +FFF1:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000 +FFF2:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61866FF663866FBE6F867FFE0000 +FFF3:00007FFE61866FBE638E6FBE6FBE7FFE7FFE618E6FF663C66FF66F8E7FFE0000 +FFF4:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61B66FB663866FF66FF67FFE0000 +FFF5:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61866FBE63866FF66F867FFE0000 +FFF6:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000 +FFF7:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000 +FFF8:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000 +FFF9:AAAA000180003E118828083988443E4580000081814001C18220022180005555 +FFFA:AAAA000180003E118828083988443E45800001E1820001C1802003C180005555 +FFFB:AAAA000180003E118828083988443E45800003E1808000818080008180005555 +FFFC:5555800000018000000180001185A9442985A94411998000000180000001AAAA +FFFD:0000007E665A5A7A76767E76767E0000 diff --git a/Engine/lib/sdl/visualtest/Makefile.in b/Engine/lib/sdl/visualtest/Makefile.in index 2efcdb1c8..3cf2f6df4 100644 --- a/Engine/lib/sdl/visualtest/Makefile.in +++ b/Engine/lib/sdl/visualtest/Makefile.in @@ -1,15 +1,20 @@ # Makefile to build the SDL tests + srcdir = @srcdir@ CC = @CC@ EXE = @EXE@ CFLAGS = @CFLAGS@ -I../include -I./include LIBS = @LIBS@ + TARGETS = \ testharness$(EXE) \ testquit$(EXE) + all: Makefile $(TARGETS) + Makefile: $(srcdir)/Makefile.in $(SHELL) config.status $@ + testharness$(EXE): $(srcdir)/src/action_configparser.c \ $(srcdir)/src/harness_argparser.c \ $(srcdir)/src/rwhelper.c \ @@ -27,8 +32,10 @@ testharness$(EXE): $(srcdir)/src/action_configparser.c \ $(srcdir)/src/windows/windows_process.c \ $(srcdir)/src/windows/windows_screenshot.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + testquit$(EXE): $(srcdir)/unittest/testquit.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + clean: rm -f $(TARGETS) distclean: clean diff --git a/Engine/lib/sdl/visualtest/README.txt b/Engine/lib/sdl/visualtest/README.txt index 46132def1..5a5539507 100644 --- a/Engine/lib/sdl/visualtest/README.txt +++ b/Engine/lib/sdl/visualtest/README.txt @@ -3,7 +3,7 @@ \mainpage Visual and Interactive Test Automation for SDL 2.0 \section license_sec License -Check the file \c COPYING.txt for licensing information. +Check the file \c LICENSE.txt for licensing information. \section intro_sec Introduction The goal of this GSoC project is to automate the testing of testsprite2. diff --git a/Engine/lib/sdl/visualtest/acinclude.m4 b/Engine/lib/sdl/visualtest/acinclude.m4 index ead69e514..0fdf353ea 100644 --- a/Engine/lib/sdl/visualtest/acinclude.m4 +++ b/Engine/lib/sdl/visualtest/acinclude.m4 @@ -5,13 +5,13 @@ # stolen from Manish Singh # Shamelessly stolen from Owen Taylor -# serial 1 +# serial 2 -dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl AM_PATH_SDL2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS dnl AC_DEFUN([AM_PATH_SDL2], -[dnl +[dnl dnl Get the cflags and libraries from the sdl2-config script dnl AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], @@ -21,7 +21,7 @@ AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], , enable_sdltest=yes) - min_sdl_version=ifelse([$1], ,0.9.0,$1) + min_sdl_version=ifelse([$1], ,2.0.0,$1) if test "x$sdl_prefix$sdl_exec_prefix" = x ; then PKG_CHECK_MODULES([SDL], [sdl2 >= $min_sdl_version], @@ -31,42 +31,42 @@ AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run sdl_pc=no if test x$sdl_exec_prefix != x ; then sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" - if test x${SDL_CONFIG+set} != xset ; then - SDL_CONFIG=$sdl_exec_prefix/bin/sdl2-config + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_exec_prefix/bin/sdl2-config fi fi if test x$sdl_prefix != x ; then sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" - if test x${SDL_CONFIG+set} != xset ; then - SDL_CONFIG=$sdl_prefix/bin/sdl2-config + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_prefix/bin/sdl2-config fi fi fi if test "x$sdl_pc" = xyes ; then no_sdl="" - SDL_CONFIG="pkg-config sdl2" + SDL2_CONFIG="pkg-config sdl2" else as_save_PATH="$PATH" if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then PATH="$prefix/bin:$prefix/usr/bin:$PATH" fi - AC_PATH_PROG(SDL_CONFIG, sdl2-config, no, [$PATH]) + AC_PATH_PROG(SDL2_CONFIG, sdl2-config, no, [$PATH]) PATH="$as_save_PATH" AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) no_sdl="" - if test "$SDL_CONFIG" = "no" ; then + if test "$SDL2_CONFIG" = "no" ; then no_sdl=yes else - SDL_CFLAGS=`$SDL_CONFIG $sdl_config_args --cflags` - SDL_LIBS=`$SDL_CONFIG $sdl_config_args --libs` + SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` - sdl_major_version=`$SDL_CONFIG $sdl_config_args --version | \ + sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - sdl_minor_version=`$SDL_CONFIG $sdl_config_args --version | \ + sdl_minor_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sdl_micro_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` if test "x$enable_sdltest" = "xyes" ; then ac_save_CFLAGS="$CFLAGS" @@ -80,41 +80,19 @@ dnl Now check if the installed SDL is sufficiently new. (Also sanity dnl checks the results of sdl2-config to some extent dnl rm -f conf.sdltest - AC_TRY_RUN([ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -#include #include "SDL.h" -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - int main (int argc, char *argv[]) { int major, minor, micro; - char *tmp_version; + FILE *fp = fopen("conf.sdltest", "w"); - /* This hangs on some systems (?) - system ("touch conf.sdltest"); - */ - { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + if (fp) fclose(fp); - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_sdl_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + if (sscanf("$min_sdl_version", "%d.%d.%d", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_sdl_version"); exit(1); } @@ -130,14 +108,14 @@ int main (int argc, char *argv[]) printf("\n*** 'sdl2-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); printf("*** of SDL required is %d.%d.%d. If sdl2-config is correct, then it is\n", major, minor, micro); printf("*** best to upgrade to the required version.\n"); - printf("*** If sdl2-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** If sdl2-config was wrong, set the environment variable SDL2_CONFIG\n"); printf("*** to point to the correct copy of sdl2-config, and remove the file\n"); printf("*** config.cache before re-running configure\n"); return 1; } } -],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) +]])], [], [no_sdl=yes], [echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" LIBS="$ac_save_LIBS" @@ -152,10 +130,10 @@ int main (int argc, char *argv[]) if test "x$no_sdl" = x ; then ifelse([$2], , :, [$2]) else - if test "$SDL_CONFIG" = "no" ; then + if test "$SDL2_CONFIG" = "no" ; then echo "*** The sdl2-config script installed by SDL could not be found" echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** your path, or set the SDL2_CONFIG environment variable to the" echo "*** full path to sdl2-config." else if test -f conf.sdltest ; then @@ -165,7 +143,7 @@ int main (int argc, char *argv[]) CFLAGS="$CFLAGS $SDL_CFLAGS" CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" LIBS="$LIBS $SDL_LIBS" - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include "SDL.h" @@ -173,7 +151,7 @@ int main(int argc, char *argv[]) { return 0; } #undef main #define main K_and_R_C_main -], [ return 0; ], +]], [[ return 0; ]])], [ echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding SDL or finding the wrong" echo "*** version of SDL. If it is not finding SDL, you'll need to set your" @@ -186,7 +164,7 @@ int main(int argc, char *argv[]) [ echo "*** The test program failed to compile or link. See the file config.log for the" echo "*** exact error that occured. This usually means SDL was incorrectly installed" echo "*** or that you have moved SDL since it was installed. In the latter case, you" - echo "*** may want to edit the sdl2-config script: $SDL_CONFIG" ]) + echo "*** may want to edit the sdl2-config script: $SDL2_CONFIG" ]) CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" LIBS="$ac_save_LIBS" @@ -228,7 +206,7 @@ int main(int argc, char *argv[]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +m4_pattern_allow([^PKG_CONFIG(_PATH|_LIBDIR)?$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) @@ -309,7 +287,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $1]) +AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -337,7 +315,7 @@ $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. -_PKG_TEXT])dnl +_PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) @@ -348,7 +326,7 @@ path to pkg-config. _PKG_TEXT -To get pkg-config, see .])dnl +To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS diff --git a/Engine/lib/sdl/visualtest/autogen.sh b/Engine/lib/sdl/visualtest/autogen.sh index 939f34c0f..988d41760 100644 --- a/Engine/lib/sdl/visualtest/autogen.sh +++ b/Engine/lib/sdl/visualtest/autogen.sh @@ -1,12 +1,11 @@ #!/bin/sh -# -# Regenerate configuration files + cp acinclude.m4 aclocal.m4 -found=false -for autoconf in autoconf autoconf259 autoconf-2.59 -do if which $autoconf >/dev/null 2>&1; then $autoconf && found=true; break; fi -done -if test x$found = xfalse; then - echo "Couldn't find autoconf, aborting" - exit 1 + +if test "$AUTOCONF"x = x; then + AUTOCONF=autoconf fi + +$AUTOCONF || exit 1 +rm aclocal.m4 +rm -rf autom4te.cache diff --git a/Engine/lib/sdl/visualtest/compile b/Engine/lib/sdl/visualtest/compile deleted file mode 100644 index cf0edba28..000000000 --- a/Engine/lib/sdl/visualtest/compile +++ /dev/null @@ -1 +0,0 @@ -/usr/share/automake-1.11/compile \ No newline at end of file diff --git a/Engine/lib/sdl/visualtest/config.h b/Engine/lib/sdl/visualtest/config.h deleted file mode 100644 index 2d6d5cfbc..000000000 --- a/Engine/lib/sdl/visualtest/config.h +++ /dev/null @@ -1,23 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.in by autoheader. */ - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "apoorvupreti@gmail.com" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "sdlvisualtest" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "sdlvisualtest 0.01" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "sdlvisualtest" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "0.01" - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ diff --git a/Engine/lib/sdl/visualtest/config.h.in b/Engine/lib/sdl/visualtest/config.h.in deleted file mode 100644 index 40b5b8a29..000000000 --- a/Engine/lib/sdl/visualtest/config.h.in +++ /dev/null @@ -1,22 +0,0 @@ -/* config.h.in. Generated from configure.in by autoheader. */ - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const diff --git a/Engine/lib/sdl/visualtest/configure b/Engine/lib/sdl/visualtest/configure index 4d5c0a4d3..ca7c71eb0 100644 --- a/Engine/lib/sdl/visualtest/configure +++ b/Engine/lib/sdl/visualtest/configure @@ -1,8 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sdlvisualtest 0.01. -# -# Report bugs to . +# Generated by GNU Autoconf 2.69. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -265,11 +263,10 @@ fi $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: apoorvupreti@gmail.com about your system, including any -$0: error possibly output before this message. Then install -$0: a modern shell, or manually run the script under such a -$0: shell if you do have one." + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." fi exit 1 fi @@ -577,32 +574,25 @@ MFLAGS= MAKEFLAGS= # Identity of this package. -PACKAGE_NAME='sdlvisualtest' -PACKAGE_TARNAME='sdlvisualtest' -PACKAGE_VERSION='0.01' -PACKAGE_STRING='sdlvisualtest 0.01' -PACKAGE_BUGREPORT='apoorvupreti@gmail.com' -PACKAGE_URL='' +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= +ac_unique_file="unittest/testquit.c" ac_subst_vars='LTLIBOBJS LIBOBJS -SDL_TTF_LIB -GLLIB -CPP -XMKMF -SDL_CONFIG +LIBUNWIND_LIBS +LIBUNWIND_CFLAGS +SDL2_CONFIG SDL_LIBS SDL_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG -ISUNIX -ISWINDOWS -ISMACOSX -EXTRALIB -MATHLIB EXE -OSMESA_CONFIG OBJEXT EXEEXT ac_ct_CC @@ -662,7 +652,6 @@ enable_option_checking with_sdl_prefix with_sdl_exec_prefix enable_sdltest -with_x ' ac_precious_vars='build_alias host_alias @@ -677,8 +666,8 @@ PKG_CONFIG_PATH PKG_CONFIG_LIBDIR SDL_CFLAGS SDL_LIBS -XMKMF -CPP' +LIBUNWIND_CFLAGS +LIBUNWIND_LIBS' # Initialize some variables set by options. @@ -719,7 +708,7 @@ sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' @@ -1219,7 +1208,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sdlvisualtest 0.01 to adapt to many kinds of systems. +\`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1267,7 +1256,7 @@ Fine tuning of the installation directories: --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/sdlvisualtest] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1276,10 +1265,6 @@ _ACEOF cat <<\_ACEOF -X features: - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR - System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] @@ -1287,9 +1272,7 @@ _ACEOF fi if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of sdlvisualtest 0.01:";; - esac + cat <<\_ACEOF Optional Features: @@ -1303,7 +1286,6 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-sdl-prefix=PFX Prefix where SDL is installed (optional) --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional) - --with-x use the X Window System Some influential environment variables: CC C compiler command @@ -1320,13 +1302,15 @@ Some influential environment variables: path overriding pkg-config's built-in search path SDL_CFLAGS C compiler flags for SDL, overriding pkg-config SDL_LIBS linker flags for SDL, overriding pkg-config - XMKMF Path to xmkmf, Makefile generator for X Window System - CPP C preprocessor + LIBUNWIND_CFLAGS + C compiler flags for LIBUNWIND, overriding pkg-config + LIBUNWIND_LIBS + linker flags for LIBUNWIND, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to . +Report bugs to the package provider. _ACEOF ac_status=$? fi @@ -1389,7 +1373,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sdlvisualtest configure 0.01 +configure generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1528,48 +1512,11 @@ fi as_fn_set_status $ac_retval } # ac_fn_c_try_link - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sdlvisualtest $as_me 0.01, which was +It was created by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1918,8 +1865,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + ac_aux_dir= -for ac_dir in $srcdir/../build-scripts; do +for ac_dir in ../build-scripts "$srcdir"/../build-scripts; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" @@ -1935,7 +1883,7 @@ for ac_dir in $srcdir/../build-scripts; do fi done if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in $srcdir/../build-scripts" "$LINENO" 5 + as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../build-scripts \"$srcdir\"/../build-scripts" "$LINENO" 5 fi # These three variables are undocumented and unsupported, @@ -2019,7 +1967,6 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -2810,200 +2757,18 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 -$as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if ${ac_cv_c_const+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - -#ifndef __cplusplus - /* Ultrix mips cc rejects this sort of thing. */ - typedef int charset[2]; - const charset cs = { 0, 0 }; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this sort of thing. */ - char tx; - char *t = &tx; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; } bx; - struct s *b = &bx; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_const=yes -else - ac_cv_c_const=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 -$as_echo "$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -$as_echo "#define const /**/" >>confdefs.h - -fi - - -ISUNIX="false" -ISWINDOWS="false" -ISMACOSX="false" - case "$host" in - *-*-cygwin* | *-*-mingw32*) - ISWINDOWS="true" + *-*-cygwin* | *-*-mingw*) EXE=".exe" - MATHLIB="" EXTRALIB="-lshlwapi" - SYS_GL_LIBS="-lopengl32" - ;; - *-*-haiku*) - EXE="" - MATHLIB="" - EXTRALIB="" - SYS_GL_LIBS="-lGL" - ;; - *-*-darwin* ) - ISMACOSX="true" - EXE="" - MATHLIB="" - EXTRALIB="" - - ;; - *-*-aix*) - ISUNIX="true" - EXE="" - if test x$ac_cv_c_compiler_gnu = xyes; then - CFLAGS="-mthreads" - fi - MATHLIB="" - EXTRALIB="" - SYS_GL_LIBS="" - ;; - *-*-mint*) - EXE="" - MATHLIB="" - EXTRALIB="" - # Extract the first word of "osmesa-config", so it can be a program name with args. -set dummy osmesa-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_OSMESA_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $OSMESA_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_OSMESA_CONFIG="$OSMESA_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_OSMESA_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_OSMESA_CONFIG" && ac_cv_path_OSMESA_CONFIG="no" - ;; -esac -fi -OSMESA_CONFIG=$ac_cv_path_OSMESA_CONFIG -if test -n "$OSMESA_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OSMESA_CONFIG" >&5 -$as_echo "$OSMESA_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test "x$OSMESA_CONFIG" = "xyes"; then - OSMESA_CFLAGS=`$OSMESA_CONFIG --cflags` - OSMESA_LIBS=`$OSMESA_CONFIG --libs` - CFLAGS="$CFLAGS $OSMESA_CFLAGS" - SYS_GL_LIBS="$OSMESA_LIBS" - else - SYS_GL_LIBS="-lOSMesa" - fi - ;; - *-*-qnx*) - EXE="" - MATHLIB="" - EXTRALIB="" - SYS_GL_LIBS="-lGLES_CM" ;; *) - ISUNIX="true" EXE="" - MATHLIB="-lm" EXTRALIB="" - SYS_GL_LIBS="-lGL" ;; esac - - - - - SDL_VERSION=2.0.0 @@ -3125,6 +2890,7 @@ $as_echo "no" >&6; } fi fi + # Check whether --with-sdl-prefix was given. if test "${with_sdl_prefix+set}" = set; then : withval=$with_sdl_prefix; sdl_prefix="$withval" @@ -3153,8 +2919,8 @@ fi if test "x$sdl_prefix$sdl_exec_prefix" = x ; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5 -$as_echo_n "checking for SDL... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl2 >= $min_sdl_version" >&5 +$as_echo_n "checking for sdl2 >= $min_sdl_version... " >&6; } if test -n "$SDL_CFLAGS"; then pkg_cv_SDL_CFLAGS="$SDL_CFLAGS" @@ -3224,21 +2990,21 @@ fi sdl_pc=no if test x$sdl_exec_prefix != x ; then sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" - if test x${SDL_CONFIG+set} != xset ; then - SDL_CONFIG=$sdl_exec_prefix/bin/sdl2-config + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_exec_prefix/bin/sdl2-config fi fi if test x$sdl_prefix != x ; then sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" - if test x${SDL_CONFIG+set} != xset ; then - SDL_CONFIG=$sdl_prefix/bin/sdl2-config + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_prefix/bin/sdl2-config fi fi fi if test "x$sdl_pc" = xyes ; then no_sdl="" - SDL_CONFIG="pkg-config sdl2" + SDL2_CONFIG="pkg-config sdl2" else as_save_PATH="$PATH" if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then @@ -3248,12 +3014,12 @@ fi set dummy sdl2-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SDL_CONFIG+:} false; then : +if ${ac_cv_path_SDL2_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else - case $SDL_CONFIG in + case $SDL2_CONFIG in [\\/]* | ?:[\\/]*) - ac_cv_path_SDL_CONFIG="$SDL_CONFIG" # Let the user override the test with a path. + ac_cv_path_SDL2_CONFIG="$SDL2_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -3263,7 +3029,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_SDL_CONFIG="$as_dir/$ac_word$ac_exec_ext" + ac_cv_path_SDL2_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -3271,14 +3037,14 @@ done done IFS=$as_save_IFS - test -z "$ac_cv_path_SDL_CONFIG" && ac_cv_path_SDL_CONFIG="no" + test -z "$ac_cv_path_SDL2_CONFIG" && ac_cv_path_SDL2_CONFIG="no" ;; esac fi -SDL_CONFIG=$ac_cv_path_SDL_CONFIG -if test -n "$SDL_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SDL_CONFIG" >&5 -$as_echo "$SDL_CONFIG" >&6; } +SDL2_CONFIG=$ac_cv_path_SDL2_CONFIG +if test -n "$SDL2_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SDL2_CONFIG" >&5 +$as_echo "$SDL2_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } @@ -3290,17 +3056,17 @@ fi $as_echo_n "checking for SDL - version >= $min_sdl_version... " >&6; } no_sdl="" - if test "$SDL_CONFIG" = "no" ; then + if test "$SDL2_CONFIG" = "no" ; then no_sdl=yes else - SDL_CFLAGS=`$SDL_CONFIG $sdl_config_args --cflags` - SDL_LIBS=`$SDL_CONFIG $sdl_config_args --libs` + SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` - sdl_major_version=`$SDL_CONFIG $sdl_config_args --version | \ + sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` - sdl_minor_version=`$SDL_CONFIG $sdl_config_args --version | \ + sdl_minor_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` - sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sdl_micro_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` if test "x$enable_sdltest" = "xyes" ; then ac_save_CFLAGS="$CFLAGS" @@ -3318,38 +3084,16 @@ else #include #include -#include #include "SDL.h" -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - int main (int argc, char *argv[]) { int major, minor, micro; - char *tmp_version; + FILE *fp = fopen("conf.sdltest", "w"); - /* This hangs on some systems (?) - system ("touch conf.sdltest"); - */ - { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + if (fp) fclose(fp); - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_sdl_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + if (sscanf("$min_sdl_version", "%d.%d.%d", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_sdl_version"); exit(1); } @@ -3365,7 +3109,7 @@ int main (int argc, char *argv[]) printf("\n*** 'sdl2-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); printf("*** of SDL required is %d.%d.%d. If sdl2-config is correct, then it is\n", major, minor, micro); printf("*** best to upgrade to the required version.\n"); - printf("*** If sdl2-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** If sdl2-config was wrong, set the environment variable SDL2_CONFIG\n"); printf("*** to point to the correct copy of sdl2-config, and remove the file\n"); printf("*** config.cache before re-running configure\n"); return 1; @@ -3399,10 +3143,10 @@ $as_echo "no" >&6; } if test "x$no_sdl" = x ; then : else - if test "$SDL_CONFIG" = "no" ; then + if test "$SDL2_CONFIG" = "no" ; then echo "*** The sdl2-config script installed by SDL could not be found" echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** your path, or set the SDL2_CONFIG environment variable to the" echo "*** full path to sdl2-config." else if test -f conf.sdltest ; then @@ -3445,7 +3189,7 @@ else echo "*** The test program failed to compile or link. See the file config.log for the" echo "*** exact error that occured. This usually means SDL was incorrectly installed" echo "*** or that you have moved SDL since it was installed. In the latter case, you" - echo "*** may want to edit the sdl2-config script: $SDL_CONFIG" + echo "*** may want to edit the sdl2-config script: $SDL2_CONFIG" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext @@ -3466,466 +3210,78 @@ rm -f core conftest.err conftest.$ac_objext \ CFLAGS="$CFLAGS $SDL_CFLAGS" LIBS="$LIBS -lSDL2_test $SDL_LIBS $EXTRALIB" -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libunwind" >&5 +$as_echo_n "checking for libunwind... " >&6; } + +if test -n "$LIBUNWIND_CFLAGS"; then + pkg_cv_LIBUNWIND_CFLAGS="$LIBUNWIND_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libunwind\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libunwind") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUNWIND_CFLAGS=`$PKG_CONFIG --cflags "libunwind" 2>/dev/null` else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBUNWIND_LIBS"; then + pkg_cv_LIBUNWIND_LIBS="$LIBUNWIND_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libunwind\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libunwind") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUNWIND_LIBS=`$PKG_CONFIG --libs "libunwind" 2>/dev/null` else - # Broken: fails on valid input. -continue + pkg_failed=yes +fi + else + pkg_failed=untried fi -rm -f conftest.err conftest.i conftest.$ac_ext - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes else - # Passes both tests. -ac_preproc_ok=: -break + _pkg_short_errors_supported=no fi -rm -f conftest.err conftest.i conftest.$ac_ext + if test $_pkg_short_errors_supported = yes; then + LIBUNWIND_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libunwind" 2>&1` + else + LIBUNWIND_PKG_ERRORS=`$PKG_CONFIG --print-errors "libunwind" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBUNWIND_PKG_ERRORS" >&5 -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP + have_libunwind=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_libunwind=no else - ac_cv_prog_CPP=$CPP + LIBUNWIND_CFLAGS=$pkg_cv_LIBUNWIND_CFLAGS + LIBUNWIND_LIBS=$pkg_cv_LIBUNWIND_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_libunwind=yes fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue +if test x$have_libunwind = xyes ; then + LIBS="$LIBS $LIBUNWIND_LIBS" fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 -$as_echo_n "checking for X... " >&6; } - - -# Check whether --with-x was given. -if test "${with_x+set}" = set; then : - withval=$with_x; -fi - -# $have_x is `yes', `no', `disabled', or empty when we do not yet know. -if test "x$with_x" = xno; then - # The user explicitly disabled X. - have_x=disabled -else - case $x_includes,$x_libraries in #( - *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( - *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : - $as_echo_n "(cached) " >&6 -else - # One or both of the vars are not set, and there is no cached value. -ac_x_includes=no ac_x_libraries=no -rm -f -r conftest.dir -if mkdir conftest.dir; then - cd conftest.dir - cat >Imakefile <<'_ACEOF' -incroot: - @echo incroot='${INCROOT}' -usrlibdir: - @echo usrlibdir='${USRLIBDIR}' -libdir: - @echo libdir='${LIBDIR}' -_ACEOF - if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then - # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. - for ac_var in incroot usrlibdir libdir; do - eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" - done - # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. - for ac_extension in a so sl dylib la dll; do - if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && - test -f "$ac_im_libdir/libX11.$ac_extension"; then - ac_im_usrlibdir=$ac_im_libdir; break - fi - done - # Screen out bogus values from the imake configuration. They are - # bogus both because they are the default anyway, and because - # using them would break gcc on systems where it needs fixed includes. - case $ac_im_incroot in - /usr/include) ac_x_includes= ;; - *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; - esac - case $ac_im_usrlibdir in - /usr/lib | /usr/lib64 | /lib | /lib64) ;; - *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; - esac - fi - cd .. - rm -f -r conftest.dir -fi - -# Standard set of common directories for X headers. -# Check X11 before X11Rn because it is often a symlink to the current release. -ac_x_header_dirs=' -/usr/X11/include -/usr/X11R7/include -/usr/X11R6/include -/usr/X11R5/include -/usr/X11R4/include - -/usr/include/X11 -/usr/include/X11R7 -/usr/include/X11R6 -/usr/include/X11R5 -/usr/include/X11R4 - -/usr/local/X11/include -/usr/local/X11R7/include -/usr/local/X11R6/include -/usr/local/X11R5/include -/usr/local/X11R4/include - -/usr/local/include/X11 -/usr/local/include/X11R7 -/usr/local/include/X11R6 -/usr/local/include/X11R5 -/usr/local/include/X11R4 - -/usr/X386/include -/usr/x386/include -/usr/XFree86/include/X11 - -/usr/include -/usr/local/include -/usr/unsupported/include -/usr/athena/include -/usr/local/x11r5/include -/usr/lpp/Xamples/include - -/usr/openwin/include -/usr/openwin/share/include' - -if test "$ac_x_includes" = no; then - # Guess where to find include files, by looking for Xlib.h. - # First, try using that file with no special directory specified. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # We can compile using X headers with no special include directory. -ac_x_includes= -else - for ac_dir in $ac_x_header_dirs; do - if test -r "$ac_dir/X11/Xlib.h"; then - ac_x_includes=$ac_dir - break - fi -done -fi -rm -f conftest.err conftest.i conftest.$ac_ext -fi # $ac_x_includes = no - -if test "$ac_x_libraries" = no; then - # Check for the libraries. - # See if we find them without any special options. - # Don't add to $LIBS permanently. - ac_save_LIBS=$LIBS - LIBS="-lX11 $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -XrmInitialize () - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - LIBS=$ac_save_LIBS -# We can link X programs with no special library path. -ac_x_libraries= -else - LIBS=$ac_save_LIBS -for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` -do - # Don't even attempt the hair of trying to link an X program! - for ac_extension in a so sl dylib la dll; do - if test -r "$ac_dir/libX11.$ac_extension"; then - ac_x_libraries=$ac_dir - break 2 - fi - done -done -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi # $ac_x_libraries = no - -case $ac_x_includes,$ac_x_libraries in #( - no,* | *,no | *\'*) - # Didn't find X, or a directory has "'" in its name. - ac_cv_have_x="have_x=no";; #( - *) - # Record where we found X for the cache. - ac_cv_have_x="have_x=yes\ - ac_x_includes='$ac_x_includes'\ - ac_x_libraries='$ac_x_libraries'" -esac -fi -;; #( - *) have_x=yes;; - esac - eval "$ac_cv_have_x" -fi # $with_x != no - -if test "$have_x" != yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 -$as_echo "$have_x" >&6; } - no_x=yes -else - # If each of the values was on the command line, it overrides each guess. - test "x$x_includes" = xNONE && x_includes=$ac_x_includes - test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries - # Update the cache value to reflect the command line values. - ac_cv_have_x="have_x=yes\ - ac_x_includes='$x_includes'\ - ac_x_libraries='$x_libraries'" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 -$as_echo "libraries $x_libraries, headers $x_includes" >&6; } -fi - -if test x$have_x = xyes; then - if test x$ac_x_includes = xno || test x$ac_x_includes = x; then - : - else - CFLAGS="$CFLAGS -I$ac_x_includes" - fi - if test x$ac_x_libraries = xno || test x$ac_x_libraries = x; then - : - else - XPATH="-L$ac_x_libraries" - fi -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL support" >&5 -$as_echo_n "checking for OpenGL support... " >&6; } -have_opengl=no -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include "SDL_opengl.h" - -int -main () -{ - - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -have_opengl=yes - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_opengl" >&5 -$as_echo "$have_opengl" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES support" >&5 -$as_echo_n "checking for OpenGL ES support... " >&6; } -have_opengles=no -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #if defined (__IPHONEOS__) - #include - #else - #include - #endif /* __QNXNTO__ */ - -int -main () -{ - - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -have_opengles=yes - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_opengles" >&5 -$as_echo "$have_opengles" >&6; } - -GLLIB="" -if test x$have_opengles = xyes; then - CFLAGS="$CFLAGS -DHAVE_OPENGLES" - GLLIB="$XPATH -lGLESv1_CM" -elif test x$have_opengl = xyes; then - CFLAGS="$CFLAGS -DHAVE_OPENGL" - GLLIB="$XPATH $SYS_GL_LIBS" -else - GLLIB="" -fi - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for TTF_Init in -lSDL2_ttf" >&5 -$as_echo_n "checking for TTF_Init in -lSDL2_ttf... " >&6; } -if ${ac_cv_lib_SDL2_ttf_TTF_Init+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lSDL2_ttf $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char TTF_Init (); -int -main () -{ -return TTF_Init (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_SDL2_ttf_TTF_Init=yes -else - ac_cv_lib_SDL2_ttf_TTF_Init=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_SDL2_ttf_TTF_Init" >&5 -$as_echo "$ac_cv_lib_SDL2_ttf_TTF_Init" >&6; } -if test "x$ac_cv_lib_SDL2_ttf_TTF_Init" = xyes; then : - have_SDL_ttf=yes -fi - -if test x$have_SDL_ttf = xyes; then - CFLAGS="$CFLAGS -DHAVE_SDL_TTF" - SDL_TTF_LIB="-lSDL2_ttf" -fi - - -ac_config_headers="$ac_config_headers config.h" ac_config_files="$ac_config_files Makefile" @@ -4019,7 +3375,43 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' -DEFS=-DHAVE_CONFIG_H +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + ac_libobjs= ac_ltlibobjs= @@ -4435,7 +3827,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sdlvisualtest $as_me 0.01, which was +This file was extended by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4453,15 +3845,11 @@ case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" -config_headers="$ac_config_headers" _ACEOF @@ -4482,22 +3870,17 @@ Usage: $0 [OPTION]... [TAG]... --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE Configuration files: $config_files -Configuration headers: -$config_headers - -Report bugs to ." +Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sdlvisualtest config.status 0.01 +config.status configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -4551,18 +3934,7 @@ do esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) + --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) @@ -4618,7 +3990,6 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; @@ -4632,7 +4003,6 @@ done # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree @@ -4820,116 +4190,8 @@ fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +eval set X " :F $CONFIG_FILES " shift for ac_tag do @@ -5137,30 +4399,7 @@ which seems to be undefined. Please make sure it is defined" >&2;} esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi - ;; + esac diff --git a/Engine/lib/sdl/visualtest/configure.ac b/Engine/lib/sdl/visualtest/configure.ac new file mode 100644 index 000000000..3566bf0d8 --- /dev/null +++ b/Engine/lib/sdl/visualtest/configure.ac @@ -0,0 +1,41 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT +AC_CONFIG_SRCDIR([unittest/testquit.c]) + +dnl Detect the canonical build and host environments +AC_CONFIG_AUX_DIR([../build-scripts]) +AC_CANONICAL_HOST + +dnl Check for tools +AC_PROG_CC + +dnl Figure out which math or extra library to use +case "$host" in + *-*-cygwin* | *-*-mingw*) + EXE=".exe" + EXTRALIB="-lshlwapi" + ;; + *) + EXE="" + EXTRALIB="" + ;; +esac +AC_SUBST(EXE) + +dnl Check for SDL +SDL_VERSION=2.0.0 +AM_PATH_SDL2($SDL_VERSION, + :, + AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) +) +CFLAGS="$CFLAGS $SDL_CFLAGS" +LIBS="$LIBS -lSDL2_test $SDL_LIBS $EXTRALIB" + +PKG_CHECK_MODULES(LIBUNWIND, libunwind, have_libunwind=yes, have_libunwind=no) +if test x$have_libunwind = xyes ; then + LIBS="$LIBS $LIBUNWIND_LIBS" +fi + +dnl Finally create all the generated files +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/Engine/lib/sdl/visualtest/configure.in b/Engine/lib/sdl/visualtest/configure.in deleted file mode 100644 index 724a0ee38..000000000 --- a/Engine/lib/sdl/visualtest/configure.in +++ /dev/null @@ -1,166 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -AC_INIT([sdlvisualtest], [0.01], [apoorvupreti@gmail.com]) - -dnl Detect the canonical build and host environments -AC_CONFIG_AUX_DIRS($srcdir/../build-scripts) -AC_CANONICAL_HOST - -dnl Check for tools - -AC_PROG_CC - -dnl Check for compiler environment - -AC_C_CONST - -dnl We only care about this for building testnative at the moment, so these -dnl values shouldn't be considered absolute truth. -dnl (Haiku, for example, sets none of these.) -ISUNIX="false" -ISWINDOWS="false" -ISMACOSX="false" - -dnl Figure out which math or extra library to use -case "$host" in - *-*-cygwin* | *-*-mingw32*) - ISWINDOWS="true" - EXE=".exe" - MATHLIB="" - EXTRALIB="-lshlwapi" - SYS_GL_LIBS="-lopengl32" - ;; - *-*-haiku*) - EXE="" - MATHLIB="" - EXTRALIB="" - SYS_GL_LIBS="-lGL" - ;; - *-*-darwin* ) - ISMACOSX="true" - EXE="" - MATHLIB="" - EXTRALIB="" - - ;; - *-*-aix*) - ISUNIX="true" - EXE="" - if test x$ac_cv_prog_gcc = xyes; then - CFLAGS="-mthreads" - fi - MATHLIB="" - EXTRALIB="" - SYS_GL_LIBS="" - ;; - *-*-mint*) - EXE="" - MATHLIB="" - EXTRALIB="" - AC_PATH_PROG(OSMESA_CONFIG, osmesa-config, no) - if test "x$OSMESA_CONFIG" = "xyes"; then - OSMESA_CFLAGS=`$OSMESA_CONFIG --cflags` - OSMESA_LIBS=`$OSMESA_CONFIG --libs` - CFLAGS="$CFLAGS $OSMESA_CFLAGS" - SYS_GL_LIBS="$OSMESA_LIBS" - else - SYS_GL_LIBS="-lOSMesa" - fi - ;; - *-*-qnx*) - EXE="" - MATHLIB="" - EXTRALIB="" - SYS_GL_LIBS="-lGLES_CM" - ;; - *) - dnl Oh well, call it Unix... - ISUNIX="true" - EXE="" - MATHLIB="-lm" - EXTRALIB="" - SYS_GL_LIBS="-lGL" - ;; -esac -AC_SUBST(EXE) -AC_SUBST(MATHLIB) -AC_SUBST(EXTRALIB) -AC_SUBST(ISMACOSX) -AC_SUBST(ISWINDOWS) -AC_SUBST(ISUNIX) - -dnl Check for SDL -SDL_VERSION=2.0.0 -AM_PATH_SDL2($SDL_VERSION, - :, - AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) -) -CFLAGS="$CFLAGS $SDL_CFLAGS" -LIBS="$LIBS -lSDL2_test $SDL_LIBS $EXTRALIB" - -dnl Check for X11 path, needed for OpenGL on some systems -AC_PATH_X -if test x$have_x = xyes; then - if test x$ac_x_includes = xno || test x$ac_x_includes = x; then - : - else - CFLAGS="$CFLAGS -I$ac_x_includes" - fi - if test x$ac_x_libraries = xno || test x$ac_x_libraries = x; then - : - else - XPATH="-L$ac_x_libraries" - fi -fi - -dnl Check for OpenGL -AC_MSG_CHECKING(for OpenGL support) -have_opengl=no -AC_TRY_COMPILE([ - #include "SDL_opengl.h" -],[ -],[ -have_opengl=yes -]) -AC_MSG_RESULT($have_opengl) - -dnl Check for OpenGL ES -AC_MSG_CHECKING(for OpenGL ES support) -have_opengles=no -AC_TRY_COMPILE([ - #if defined (__IPHONEOS__) - #include - #else - #include - #endif /* __QNXNTO__ */ -],[ -],[ -have_opengles=yes -]) -AC_MSG_RESULT($have_opengles) - -GLLIB="" -if test x$have_opengles = xyes; then - CFLAGS="$CFLAGS -DHAVE_OPENGLES" - GLLIB="$XPATH -lGLESv1_CM" -elif test x$have_opengl = xyes; then - CFLAGS="$CFLAGS -DHAVE_OPENGL" - GLLIB="$XPATH $SYS_GL_LIBS" -else - GLLIB="" -fi - -AC_SUBST(GLLIB) - -dnl Check for SDL_ttf -AC_CHECK_LIB(SDL2_ttf, TTF_Init, have_SDL_ttf=yes) -if test x$have_SDL_ttf = xyes; then - CFLAGS="$CFLAGS -DHAVE_SDL_TTF" - SDL_TTF_LIB="-lSDL2_ttf" -fi -AC_SUBST(SDL_TTF_LIB) - -dnl Finally create all the generated files -dnl AC_OUTPUT([Makefile]) -AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT() diff --git a/Engine/lib/sdl/visualtest/depcomp b/Engine/lib/sdl/visualtest/depcomp deleted file mode 100644 index b0ad20c05..000000000 --- a/Engine/lib/sdl/visualtest/depcomp +++ /dev/null @@ -1 +0,0 @@ -/usr/share/automake-1.11/depcomp \ No newline at end of file diff --git a/Engine/lib/sdl/visualtest/include/SDL_visualtest_action_configparser.h b/Engine/lib/sdl/visualtest/include/SDL_visualtest_action_configparser.h index 340924852..40481f379 100644 --- a/Engine/lib/sdl/visualtest/include/SDL_visualtest_action_configparser.h +++ b/Engine/lib/sdl/visualtest/include/SDL_visualtest_action_configparser.h @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file SDL_visualtest_action_configparser.h * @@ -137,7 +137,7 @@ int SDLVisualTest_InsertIntoActionQueue(SDLVisualTest_ActionQueue* queue, * * \return 1 on success, 0 on failure. */ -int SDLVisualTest_ParseActionConfig(char* file, SDLVisualTest_ActionQueue* queue); +int SDLVisualTest_ParseActionConfig(const char* file, SDLVisualTest_ActionQueue* queue); /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/Engine/lib/sdl/visualtest/include/SDL_visualtest_exhaustive_variator.h b/Engine/lib/sdl/visualtest/include/SDL_visualtest_exhaustive_variator.h index 6fee88f8f..4637ce29e 100644 --- a/Engine/lib/sdl/visualtest/include/SDL_visualtest_exhaustive_variator.h +++ b/Engine/lib/sdl/visualtest/include/SDL_visualtest_exhaustive_variator.h @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file SDL_visualtest_exhaustive_variator.h * diff --git a/Engine/lib/sdl/visualtest/include/SDL_visualtest_parsehelper.h b/Engine/lib/sdl/visualtest/include/SDL_visualtest_parsehelper.h index 0a12c65c7..4558552c1 100644 --- a/Engine/lib/sdl/visualtest/include/SDL_visualtest_parsehelper.h +++ b/Engine/lib/sdl/visualtest/include/SDL_visualtest_parsehelper.h @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file SDL_visualtest_parsehelper.h * diff --git a/Engine/lib/sdl/visualtest/include/SDL_visualtest_process.h b/Engine/lib/sdl/visualtest/include/SDL_visualtest_process.h index b548690c2..26ce5a098 100644 --- a/Engine/lib/sdl/visualtest/include/SDL_visualtest_process.h +++ b/Engine/lib/sdl/visualtest/include/SDL_visualtest_process.h @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file SDL_visualtest_process.h * @@ -8,8 +8,8 @@ #include #if defined(__WIN32__) -#include -#include +#include +#include #elif defined(__LINUX__) #include #else diff --git a/Engine/lib/sdl/visualtest/include/SDL_visualtest_random_variator.h b/Engine/lib/sdl/visualtest/include/SDL_visualtest_random_variator.h index 99a13c2e3..0514ce631 100644 --- a/Engine/lib/sdl/visualtest/include/SDL_visualtest_random_variator.h +++ b/Engine/lib/sdl/visualtest/include/SDL_visualtest_random_variator.h @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file SDL_visualtest_random_variator.h * diff --git a/Engine/lib/sdl/visualtest/include/SDL_visualtest_rwhelper.h b/Engine/lib/sdl/visualtest/include/SDL_visualtest_rwhelper.h index 2fbf10e14..bc3942594 100644 --- a/Engine/lib/sdl/visualtest/include/SDL_visualtest_rwhelper.h +++ b/Engine/lib/sdl/visualtest/include/SDL_visualtest_rwhelper.h @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file rwhelper.c * diff --git a/Engine/lib/sdl/visualtest/include/SDL_visualtest_screenshot.h b/Engine/lib/sdl/visualtest/include/SDL_visualtest_screenshot.h index 1900ea4e2..69411e99d 100644 --- a/Engine/lib/sdl/visualtest/include/SDL_visualtest_screenshot.h +++ b/Engine/lib/sdl/visualtest/include/SDL_visualtest_screenshot.h @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file SDL_visualtest_screenshot.h * diff --git a/Engine/lib/sdl/visualtest/include/SDL_visualtest_sut_configparser.h b/Engine/lib/sdl/visualtest/include/SDL_visualtest_sut_configparser.h index 42a108856..63506f5a0 100644 --- a/Engine/lib/sdl/visualtest/include/SDL_visualtest_sut_configparser.h +++ b/Engine/lib/sdl/visualtest/include/SDL_visualtest_sut_configparser.h @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file SDL_visualtest_sut_configparser.h * diff --git a/Engine/lib/sdl/visualtest/include/SDL_visualtest_variator_common.h b/Engine/lib/sdl/visualtest/include/SDL_visualtest_variator_common.h index 0b7c153e2..19a5b3782 100644 --- a/Engine/lib/sdl/visualtest/include/SDL_visualtest_variator_common.h +++ b/Engine/lib/sdl/visualtest/include/SDL_visualtest_variator_common.h @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file SDL_visualtest_variator_common.h * diff --git a/Engine/lib/sdl/visualtest/include/SDL_visualtest_variators.h b/Engine/lib/sdl/visualtest/include/SDL_visualtest_variators.h index ce1e785b5..e14f67d2a 100644 --- a/Engine/lib/sdl/visualtest/include/SDL_visualtest_variators.h +++ b/Engine/lib/sdl/visualtest/include/SDL_visualtest_variators.h @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file SDL_visualtest_variators.h * diff --git a/Engine/lib/sdl/visualtest/install-sh b/Engine/lib/sdl/visualtest/install-sh deleted file mode 100644 index 205f21c6b..000000000 --- a/Engine/lib/sdl/visualtest/install-sh +++ /dev/null @@ -1 +0,0 @@ -/usr/share/automake-1.11/install-sh \ No newline at end of file diff --git a/Engine/lib/sdl/visualtest/missing b/Engine/lib/sdl/visualtest/missing deleted file mode 100644 index 20bc5b0ed..000000000 --- a/Engine/lib/sdl/visualtest/missing +++ /dev/null @@ -1 +0,0 @@ -/usr/share/automake-1.11/missing \ No newline at end of file diff --git a/Engine/lib/sdl/visualtest/src/action_configparser.c b/Engine/lib/sdl/visualtest/src/action_configparser.c index bab7fc13e..f3b1afd73 100644 --- a/Engine/lib/sdl/visualtest/src/action_configparser.c +++ b/Engine/lib/sdl/visualtest/src/action_configparser.c @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file action_configparser.c * @@ -36,6 +36,9 @@ FreeAction(SDLVisualTest_Action* action) action->extra.process.args = NULL; } break; + + default: + break; } } @@ -54,7 +57,7 @@ SDLVisualTest_EnqueueAction(SDLVisualTest_ActionQueue* queue, sizeof(SDLVisualTest_ActionNode)); if(!node) { - SDLTest_LogError("malloc() failed"); + SDLTest_LogError("SDL_malloc() failed"); return 0; } node->action = action; @@ -220,10 +223,10 @@ SDLVisualTest_InsertIntoActionQueue(SDLVisualTest_ActionQueue* queue, return 1; } - newnode = (SDLVisualTest_ActionNode*)malloc(sizeof(SDLVisualTest_ActionNode)); + newnode = (SDLVisualTest_ActionNode*)SDL_malloc(sizeof(SDLVisualTest_ActionNode)); if(!newnode) { - SDLTest_LogError("malloc() failed"); + SDLTest_LogError("SDL_malloc() failed"); return 0; } newnode->action = action; @@ -256,7 +259,7 @@ SDLVisualTest_InsertIntoActionQueue(SDLVisualTest_ActionQueue* queue, } int -SDLVisualTest_ParseActionConfig(char* file, SDLVisualTest_ActionQueue* queue) +SDLVisualTest_ParseActionConfig(const char* file, SDLVisualTest_ActionQueue* queue) { char line[MAX_ACTION_LINE_LENGTH]; SDLVisualTest_RWHelperBuffer buffer; @@ -344,7 +347,7 @@ SDLVisualTest_ParseActionConfig(char* file, SDLVisualTest_ActionQueue* queue) path = (char*)SDL_malloc(sizeof(char) * (len + 1)); if(!path) { - SDLTest_LogError("malloc() failed"); + SDLTest_LogError("SDL_malloc() failed"); SDLVisualTest_EmptyActionQueue(queue); SDL_RWclose(rw); return 0; @@ -358,7 +361,7 @@ SDLVisualTest_ParseActionConfig(char* file, SDLVisualTest_ActionQueue* queue) args = (char*)SDL_malloc(sizeof(char) * (len + 1)); if(!args) { - SDLTest_LogError("malloc() failed"); + SDLTest_LogError("SDL_malloc() failed"); SDL_free(path); SDLVisualTest_EmptyActionQueue(queue); SDL_RWclose(rw); @@ -393,4 +396,4 @@ SDLVisualTest_ParseActionConfig(char* file, SDLVisualTest_ActionQueue* queue) SDL_RWclose(rw); return 1; -} \ No newline at end of file +} diff --git a/Engine/lib/sdl/visualtest/src/harness_argparser.c b/Engine/lib/sdl/visualtest/src/harness_argparser.c index 93cf614a3..8bc57064b 100644 --- a/Engine/lib/sdl/visualtest/src/harness_argparser.c +++ b/Engine/lib/sdl/visualtest/src/harness_argparser.c @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file harness_argparser.c * @@ -19,7 +19,7 @@ /* String compare s1 and s2 ignoring leading hyphens */ static int -StrCaseCmpIgnoreHyphen(char* s1, char* s2) +StrCaseCmpIgnoreHyphen(const char* s1, const char* s2) { /* treat NULL pointer as empty strings */ if(!s1) @@ -199,7 +199,7 @@ ParseArg(char** argv, int index, SDLVisualTest_HarnessState* state) /* TODO: Trailing/leading spaces and spaces between equals sign not supported. */ static int -ParseConfig(char* file, SDLVisualTest_HarnessState* state) +ParseConfig(const char* file, SDLVisualTest_HarnessState* state) { SDL_RWops* rw; SDLVisualTest_RWHelperBuffer buffer; @@ -234,7 +234,7 @@ ParseConfig(char* file, SDLVisualTest_HarnessState* state) argv = (char**)SDL_malloc((num_params + 1) * sizeof(char*)); if(!argv) { - SDLTest_LogError("malloc() failed."); + SDLTest_LogError("SDL_malloc() failed."); SDL_RWclose(rw); return 0; } @@ -355,4 +355,4 @@ SDLVisualTest_FreeHarnessState(SDLVisualTest_HarnessState* state) SDLVisualTest_EmptyActionQueue(&state->action_queue); SDLVisualTest_FreeSUTConfig(&state->sut_config); } -} \ No newline at end of file +} diff --git a/Engine/lib/sdl/visualtest/src/linux/linux_process.c b/Engine/lib/sdl/visualtest/src/linux/linux_process.c index f758981ca..b93f3407e 100644 --- a/Engine/lib/sdl/visualtest/src/linux/linux_process.c +++ b/Engine/lib/sdl/visualtest/src/linux/linux_process.c @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file linux_process.c * @@ -8,23 +8,23 @@ #include #include -#include -#include -#include -#include #include "SDL_visualtest_process.h" #include "SDL_visualtest_harness_argparser.h" #include "SDL_visualtest_parsehelper.h" #if defined(__LINUX__) +#include +#include +#include +#include static void -LogLastError(char* str) +LogLastError(const char* str) { - char* error = (char*)strerror(errno); + const char* error = strerror(errno); if(!str || !error) - return; + return; SDLTest_LogError("%s: %s", str, error); } @@ -196,4 +196,13 @@ SDL_KillProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps) return 1; } +/* each window of the process will have a screenshot taken. The file name will be + prefix-i.png for the i'th window. */ +int +SDLVisualTest_ScreenshotProcess(SDL_ProcessInfo* pinfo, char* prefix) +{ + SDLTest_LogError("Screenshot process not implemented"); + return 0; +} + #endif diff --git a/Engine/lib/sdl/visualtest/src/mischelper.c b/Engine/lib/sdl/visualtest/src/mischelper.c index 03e705eda..9684af6f6 100644 --- a/Engine/lib/sdl/visualtest/src/mischelper.c +++ b/Engine/lib/sdl/visualtest/src/mischelper.c @@ -1,5 +1,5 @@ /** - * \file mischelper.c + * \file mischelper.c * * Source file with miscellaneous helper functions. */ @@ -25,4 +25,4 @@ SDLVisualTest_HashString(char* str, char hash[33]) /* convert the md5 hash to an array of hexadecimal digits */ for(i = 0; i < 16; i++) SDL_snprintf(hash + 2 * i, 33 - 2 * i, "%02x", (int)md5c.digest[i]); -} \ No newline at end of file +} diff --git a/Engine/lib/sdl/visualtest/src/parsehelper.c b/Engine/lib/sdl/visualtest/src/parsehelper.c index 7d601179b..9d38cb2f2 100644 --- a/Engine/lib/sdl/visualtest/src/parsehelper.c +++ b/Engine/lib/sdl/visualtest/src/parsehelper.c @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file parsehelper.c * @@ -18,7 +18,7 @@ CountTokens(char* args) int state; /* current state of the DFA */ if(!args) - return -1; + return -1; index = 0; state = 0; @@ -96,7 +96,7 @@ TokenizeHelper(char* str, char** tokens, int num_tokens, int max_token_len) if(!tokens[index]) { int i; - SDLTest_LogError("malloc() failed."); + SDLTest_LogError("SDL_malloc() failed."); for(i = 0; i < index; i++) SDL_free(tokens[i]); return 0; @@ -215,7 +215,7 @@ SDLVisualTest_ParseArgsToArgv(char* args) argv = (char**)SDL_malloc((num_tokens + 2) * sizeof(char*)); if(!argv) { - SDLTest_LogError("malloc() failed."); + SDLTest_LogError("SDL_malloc() failed."); return NULL; } diff --git a/Engine/lib/sdl/visualtest/src/rwhelper.c b/Engine/lib/sdl/visualtest/src/rwhelper.c index a50254006..1ff9190ff 100644 --- a/Engine/lib/sdl/visualtest/src/rwhelper.c +++ b/Engine/lib/sdl/visualtest/src/rwhelper.c @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file rwhelper.c * @@ -128,4 +128,4 @@ SDLVisualTest_RWHelperCountNonEmptyLines(SDL_RWops* rw, buffer, comment_char)) num_lines++; return num_lines; -} \ No newline at end of file +} diff --git a/Engine/lib/sdl/visualtest/src/screenshot.c b/Engine/lib/sdl/visualtest/src/screenshot.c index 7d19c7f88..be5e4df85 100644 --- a/Engine/lib/sdl/visualtest/src/screenshot.c +++ b/Engine/lib/sdl/visualtest/src/screenshot.c @@ -1,6 +1,6 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** - * \file screenshot.c + * \file screenshot.c * * Source file for the screenshot API. */ @@ -48,7 +48,7 @@ SDLVisualTest_VerifyScreenshots(char* args, char* test_dir, char* verify_dir) verify_path = (char*)SDL_malloc(verify_len * sizeof(char)); if(!verify_path) { - SDLTest_LogError("malloc() failed"); + SDLTest_LogError("SDL_malloc() failed"); return_code = -1; goto verifyscreenshots_cleanup_generic; } @@ -78,7 +78,7 @@ SDLVisualTest_VerifyScreenshots(char* args, char* test_dir, char* verify_dir) test_path = (char*)SDL_malloc(test_len * sizeof(char)); if(!test_path) { - SDLTest_LogError("malloc() failed"); + SDLTest_LogError("SDL_malloc() failed"); return_code = -1; goto verifyscreenshots_cleanup_verifybmp; } diff --git a/Engine/lib/sdl/visualtest/src/sut_configparser.c b/Engine/lib/sdl/visualtest/src/sut_configparser.c index cf18b6208..fa8c2d4bb 100644 --- a/Engine/lib/sdl/visualtest/src/sut_configparser.c +++ b/Engine/lib/sdl/visualtest/src/sut_configparser.c @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file sut_configparser.c * @@ -61,7 +61,7 @@ SDLVisualTest_ParseSUTConfig(char* file, SDLVisualTest_SUTConfig* config) sizeof(SDLVisualTest_SUTOption)); if(!config->options) { - SDLTest_LogError("malloc() failed"); + SDLTest_LogError("SDL_malloc() failed"); SDL_RWclose(rw); return 0; } diff --git a/Engine/lib/sdl/visualtest/src/testharness.c b/Engine/lib/sdl/visualtest/src/testharness.c index 25e41a611..db3ca55b2 100644 --- a/Engine/lib/sdl/visualtest/src/testharness.c +++ b/Engine/lib/sdl/visualtest/src/testharness.c @@ -1,6 +1,6 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** - * \file testharness.c + * \file testharness.c * * Source file for the test harness. */ @@ -49,8 +49,8 @@ static SDLVisualTest_ActionNode* current; /* the current action being performed static SDL_TimerID action_timer, kill_timer; /* returns a char* to be passed as the format argument of a printf-style function. */ -static char* -usage() +static const char* +usage(void) { return "Usage: \n%s --sutapp xyz" " [--sutargs abc | --parameter-config xyz.parameters" @@ -82,10 +82,10 @@ ActionTimerCallback(Uint32 interval, void* param) Uint32 next_action_time; /* push an event to handle the action */ + SDL_zero(userevent); userevent.type = SDL_USEREVENT; userevent.code = ACTION_TIMER_EVENT; userevent.data1 = ¤t->action; - userevent.data2 = NULL; event.type = SDL_USEREVENT; event.user = userevent; @@ -110,10 +110,9 @@ KillTimerCallback(Uint32 interval, void* param) SDL_Event event; SDL_UserEvent userevent; + SDL_zero(userevent); userevent.type = SDL_USEREVENT; userevent.code = KILL_TIMER_EVENT; - userevent.data1 = NULL; - userevent.data2 = NULL; event.type = SDL_USEREVENT; event.user = userevent; @@ -181,7 +180,7 @@ ProcessAction(SDLVisualTest_Action* action, int* sut_running, char* args) if(SDL_IsProcessRunning(&action_process) > 0) { SDLTest_LogError("Process %s took too long too complete." - " Force killing...", action->extra); + " Force killing...", action->extra.process.path); if(!SDL_KillProcess(&action_process, &ps)) { SDLTest_LogError("SDL_KillProcess() failed"); @@ -463,7 +462,7 @@ main(int argc, char* argv[]) if(state.sut_config.num_options > 0) { - char* variator_name = state.variator_type == SDL_VARIATOR_RANDOM ? + const char* variator_name = (state.variator_type == SDL_VARIATOR_RANDOM) ? "RANDOM" : "EXHAUSTIVE"; if(state.num_variations > 0) SDLTest_Log("Testing SUT with variator: %s for %d variations", @@ -519,7 +518,7 @@ main(int argc, char* argv[]) } goto cleanup_variator; } - + goto cleanup_sdl; cleanup_variator: diff --git a/Engine/lib/sdl/visualtest/src/variator_common.c b/Engine/lib/sdl/visualtest/src/variator_common.c index dec3d8aac..e8444b317 100644 --- a/Engine/lib/sdl/visualtest/src/variator_common.c +++ b/Engine/lib/sdl/visualtest/src/variator_common.c @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file variator_common.c * @@ -189,7 +189,7 @@ SDLVisualTest_InitVariation(SDLVisualTest_Variation* variation, sizeof(SDLVisualTest_SUTOptionValue)); if(!variation->vars) { - SDLTest_LogError("malloc() failed"); + SDLTest_LogError("SDL_malloc() failed"); return 0; } variation->num_vars = config->num_options; @@ -222,4 +222,4 @@ SDLVisualTest_InitVariation(SDLVisualTest_Variation* variation, } } return 1; -} \ No newline at end of file +} diff --git a/Engine/lib/sdl/visualtest/src/variator_exhaustive.c b/Engine/lib/sdl/visualtest/src/variator_exhaustive.c index 2a0ab35c7..1e6a79e0a 100644 --- a/Engine/lib/sdl/visualtest/src/variator_exhaustive.c +++ b/Engine/lib/sdl/visualtest/src/variator_exhaustive.c @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file variator_exhaustive.c * @@ -39,6 +39,7 @@ NextVariation(SDLVisualTest_Variation* variation, return 0; if(carry == 0) return 1; + SDLTest_LogError("NextVariation() failed"); return -1; } @@ -129,4 +130,4 @@ SDLVisualTest_FreeExhaustiveVariator(SDLVisualTest_ExhaustiveVariator* variator) } SDL_free(variator->variation.vars); variator->variation.vars = NULL; -} \ No newline at end of file +} diff --git a/Engine/lib/sdl/visualtest/src/variator_random.c b/Engine/lib/sdl/visualtest/src/variator_random.c index 14b5d48a8..4da4161e1 100644 --- a/Engine/lib/sdl/visualtest/src/variator_random.c +++ b/Engine/lib/sdl/visualtest/src/variator_random.c @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file variator_random.c * @@ -47,12 +47,13 @@ SDLVisualTest_GetNextRandomVariation(SDLVisualTest_RandomVariator* variator) SDLVisualTest_SUTOptionValue* vars; SDLVisualTest_SUTOption* options; int i; + if(!variator) { SDLTest_LogError("variator argument cannot be NULL"); return NULL; } - + /* to save typing */ vars = variator->variation.vars; options = variator->config.options; @@ -106,6 +107,7 @@ void SDLVisualTest_FreeRandomVariator(SDLVisualTest_RandomVariator* variator) SDLTest_LogError("variator argument cannot be NULL"); return; } + SDL_free(variator->variation.vars); variator->variation.vars = NULL; -} \ No newline at end of file +} diff --git a/Engine/lib/sdl/visualtest/src/variators.c b/Engine/lib/sdl/visualtest/src/variators.c index 2d63113c5..e9485c6f6 100644 --- a/Engine/lib/sdl/visualtest/src/variators.c +++ b/Engine/lib/sdl/visualtest/src/variators.c @@ -1,4 +1,4 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** * \file variators.c * @@ -53,6 +53,7 @@ SDLVisualTest_GetNextVariation(SDLVisualTest_Variator* variator) SDLTest_LogError("variator argument cannot be NULL"); return NULL; } + switch(variator->type) { case SDL_VARIATOR_EXHAUSTIVE: @@ -77,6 +78,7 @@ void SDLVisualTest_FreeVariator(SDLVisualTest_Variator* variator) SDLTest_LogError("variator argument cannot be NULL"); return; } + switch(variator->type) { case SDL_VARIATOR_EXHAUSTIVE: @@ -90,4 +92,4 @@ void SDLVisualTest_FreeVariator(SDLVisualTest_Variator* variator) default: SDLTest_LogError("Invalid value for variator type"); } -} \ No newline at end of file +} diff --git a/Engine/lib/sdl/visualtest/src/windows/windows_process.c b/Engine/lib/sdl/visualtest/src/windows/windows_process.c index ad0938951..e7e265c7c 100644 --- a/Engine/lib/sdl/visualtest/src/windows/windows_process.c +++ b/Engine/lib/sdl/visualtest/src/windows/windows_process.c @@ -1,11 +1,10 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** - * \file windows_process.c + * \file windows_process.c * * Source file for the process API on windows. */ - #include #include #include @@ -16,7 +15,7 @@ #if defined(__WIN32__) void -LogLastError(char* str) +LogLastError(const char* str) { LPVOID buffer; DWORD dw = GetLastError(); @@ -61,7 +60,7 @@ SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo) working_directory = (char*)SDL_malloc(path_length + 1); if(!working_directory) { - SDLTest_LogError("Could not allocate working_directory - malloc() failed."); + SDLTest_LogError("Could not allocate working_directory - SDL_malloc() failed."); return 0; } @@ -80,7 +79,7 @@ SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo) command_line = (char*)SDL_malloc(path_length + args_length + 2); if(!command_line) { - SDLTest_LogError("Could not allocate command_line - malloc() failed."); + SDLTest_LogError("Could not allocate command_line - SDL_malloc() failed."); return 0; } SDL_memcpy(command_line, file, path_length); @@ -175,7 +174,7 @@ CloseWindowCallback(HWND hwnd, LPARAM lparam) GetWindowThreadProcessId(hwnd, &pid); if(pid == pinfo->pi.dwProcessId) { - DWORD result; + DWORD_PTR result; if(!SendMessageTimeout(hwnd, WM_CLOSE, 0, 0, SMTO_BLOCK, 1000, &result)) { diff --git a/Engine/lib/sdl/visualtest/src/windows/windows_screenshot.c b/Engine/lib/sdl/visualtest/src/windows/windows_screenshot.c index 785590359..6d9189dc4 100644 --- a/Engine/lib/sdl/visualtest/src/windows/windows_screenshot.c +++ b/Engine/lib/sdl/visualtest/src/windows/windows_screenshot.c @@ -1,6 +1,6 @@ -/* See COPYING.txt for the full license governing this code. */ +/* See LICENSE.txt for the full license governing this code. */ /** - * \file windows_screenshot.c + * \file windows_screenshot.c * * Source file for the screenshot API on windows. */ @@ -14,9 +14,9 @@ #endif #if defined(__WIN32__) -#include +#include -void LogLastError(char* str); +void LogLastError(const char* str); static int img_num; static SDL_ProcessInfo screenshot_pinfo; @@ -241,7 +241,7 @@ ScreenshotWindow(HWND hwnd, char* filename, SDL_bool only_client_area) goto screenshotwindow_cleanup_capturebitmap; } - /* free resources */ + /* Free resources */ screenshotwindow_cleanup_capturebitmap: if(!DeleteObject(capturebitmap)) @@ -297,7 +297,7 @@ ScreenshotHwnd(HWND hwnd, LPARAM lparam) filename = (char*)SDL_malloc(len * sizeof(char)); if(!filename) { - SDLTest_LogError("malloc() failed"); + SDLTest_LogError("SDL_malloc() failed"); return FALSE; } diff --git a/Engine/lib/sdl/visualtest/stamp-h1 b/Engine/lib/sdl/visualtest/stamp-h1 deleted file mode 100644 index 4547fe1b5..000000000 --- a/Engine/lib/sdl/visualtest/stamp-h1 +++ /dev/null @@ -1 +0,0 @@ -timestamp for config.h diff --git a/Engine/lib/sdl/visualtest/unittest/testquit.c b/Engine/lib/sdl/visualtest/unittest/testquit.c index 6cf453672..04e3c5c5a 100644 --- a/Engine/lib/sdl/visualtest/unittest/testquit.c +++ b/Engine/lib/sdl/visualtest/unittest/testquit.c @@ -64,7 +64,7 @@ main(int argc, char** argv) if(consumed < 0) { - static const char *options = { "[--exit-code N]", "[--crash]", "[--hang]", NULL }; + static const char *options[] = { "[--exit-code N]", "[--crash]", "[--hang]", NULL }; SDLTest_CommonLogUsage(state, argv[0], options); SDLTest_CommonQuit(state); return 1; diff --git a/Engine/lib/sdl/wayland-protocols/idle-inhibit-unstable-v1.xml b/Engine/lib/sdl/wayland-protocols/idle-inhibit-unstable-v1.xml new file mode 100644 index 000000000..9c06cdcba --- /dev/null +++ b/Engine/lib/sdl/wayland-protocols/idle-inhibit-unstable-v1.xml @@ -0,0 +1,83 @@ + + + + + Copyright © 2015 Samsung Electronics Co., Ltd + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + + This interface permits inhibiting the idle behavior such as screen + blanking, locking, and screensaving. The client binds the idle manager + globally, then creates idle-inhibitor objects for each surface. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + + + + + Destroy the inhibit manager. + + + + + + Create a new inhibitor object associated with the given surface. + + + + + + + + + + An idle inhibitor prevents the output that the associated surface is + visible on from being set to a state where it is not visually usable due + to lack of user interaction (e.g. blanked, dimmed, locked, set to power + save, etc.) Any screensaver processes are also blocked from displaying. + + If the surface is destroyed, unmapped, becomes occluded, loses + visibility, or otherwise becomes not visually relevant for the user, the + idle inhibitor will not be honored by the compositor; if the surface + subsequently regains visibility the inhibitor takes effect once again. + Likewise, the inhibitor isn't honored if the system was already idled at + the time the inhibitor was established, although if the system later + de-idles and re-idles the inhibitor will take effect. + + + + + Remove the inhibitor effect from the associated wl_surface. + + + + + diff --git a/Engine/lib/sdl/wayland-protocols/keyboard-shortcuts-inhibit-unstable-v1.xml b/Engine/lib/sdl/wayland-protocols/keyboard-shortcuts-inhibit-unstable-v1.xml new file mode 100644 index 000000000..27748764d --- /dev/null +++ b/Engine/lib/sdl/wayland-protocols/keyboard-shortcuts-inhibit-unstable-v1.xml @@ -0,0 +1,143 @@ + + + + + Copyright © 2017 Red Hat Inc. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol specifies a way for a client to request the compositor + to ignore its own keyboard shortcuts for a given seat, so that all + key events from that seat get forwarded to a surface. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible + changes may be added together with the corresponding interface + version bump. + Backward incompatible changes are done by bumping the version + number in the protocol and interface names and resetting the + interface version. Once the protocol is to be declared stable, + the 'z' prefix and the version number in the protocol and + interface names are removed and the interface version number is + reset. + + + + + A global interface used for inhibiting the compositor keyboard shortcuts. + + + + + Destroy the keyboard shortcuts inhibitor manager. + + + + + + Create a new keyboard shortcuts inhibitor object associated with + the given surface for the given seat. + + If shortcuts are already inhibited for the specified seat and surface, + a protocol error "already_inhibited" is raised by the compositor. + + + + + + + + + + + + + + A keyboard shortcuts inhibitor instructs the compositor to ignore + its own keyboard shortcuts when the associated surface has keyboard + focus. As a result, when the surface has keyboard focus on the given + seat, it will receive all key events originating from the specified + seat, even those which would normally be caught by the compositor for + its own shortcuts. + + The Wayland compositor is however under no obligation to disable + all of its shortcuts, and may keep some special key combo for its own + use, including but not limited to one allowing the user to forcibly + restore normal keyboard events routing in the case of an unwilling + client. The compositor may also use the same key combo to reactivate + an existing shortcut inhibitor that was previously deactivated on + user request. + + When the compositor restores its own keyboard shortcuts, an + "inactive" event is emitted to notify the client that the keyboard + shortcuts inhibitor is not effectively active for the surface and + seat any more, and the client should not expect to receive all + keyboard events. + + When the keyboard shortcuts inhibitor is inactive, the client has + no way to forcibly reactivate the keyboard shortcuts inhibitor. + + The user can chose to re-enable a previously deactivated keyboard + shortcuts inhibitor using any mechanism the compositor may offer, + in which case the compositor will send an "active" event to notify + the client. + + If the surface is destroyed, unmapped, or loses the seat's keyboard + focus, the keyboard shortcuts inhibitor becomes irrelevant and the + compositor will restore its own keyboard shortcuts but no "inactive" + event is emitted in this case. + + + + + Remove the keyboard shortcuts inhibitor from the associated wl_surface. + + + + + + This event indicates that the shortcut inhibitor is active. + + The compositor sends this event every time compositor shortcuts + are inhibited on behalf of the surface. When active, the client + may receive input events normally reserved by the compositor + (see zwp_keyboard_shortcuts_inhibitor_v1). + + This occurs typically when the initial request "inhibit_shortcuts" + first becomes active or when the user instructs the compositor to + re-enable and existing shortcuts inhibitor using any mechanism + offered by the compositor. + + + + + + This event indicates that the shortcuts inhibitor is inactive, + normal shortcuts processing is restored by the compositor. + + + + diff --git a/Engine/lib/sdl/wayland-protocols/org-kde-kwin-server-decoration-manager.xml b/Engine/lib/sdl/wayland-protocols/org-kde-kwin-server-decoration-manager.xml deleted file mode 100644 index 8bc106c7c..000000000 --- a/Engine/lib/sdl/wayland-protocols/org-kde-kwin-server-decoration-manager.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - . - ]]> - - - This interface allows to coordinate whether the server should create - a server-side window decoration around a wl_surface representing a - shell surface (wl_shell_surface or similar). By announcing support - for this interface the server indicates that it supports server - side decorations. - - - - When a client creates a server-side decoration object it indicates - that it supports the protocol. The client is supposed to tell the - server whether it wants server-side decorations or will provide - client-side decorations. - - If the client does not create a server-side decoration object for - a surface the server interprets this as lack of support for this - protocol and considers it as client-side decorated. Nevertheless a - client-side decorated surface should use this protocol to indicate - to the server that it does not want a server-side deco. - - - - - - - - - - - - - This event is emitted directly after binding the interface. It contains - the default mode for the decoration. When a new server decoration object - is created this new object will be in the default mode until the first - request_mode is requested. - - The server may change the default mode at any time. - - - - - - - - - - - - - - - - - - - - - This event is emitted directly after the decoration is created and - represents the base decoration policy by the server. E.g. a server - which wants all surfaces to be client-side decorated will send Client, - a server which wants server-side decoration will send Server. - - The client can request a different mode through the decoration request. - The server will acknowledge this by another event with the same mode. So - even if a server prefers server-side decoration it's possible to force a - client-side decoration. - - The server may emit this event at any time. In this case the client can - again request a different mode. It's the responsibility of the server to - prevent a feedback loop. - - - - - diff --git a/Engine/lib/sdl/wayland-protocols/text-input-unstable-v3.xml b/Engine/lib/sdl/wayland-protocols/text-input-unstable-v3.xml new file mode 100644 index 000000000..d5f6322b0 --- /dev/null +++ b/Engine/lib/sdl/wayland-protocols/text-input-unstable-v3.xml @@ -0,0 +1,452 @@ + + + + + Copyright © 2012, 2013 Intel Corporation + Copyright © 2015, 2016 Jan Arne Petersen + Copyright © 2017, 2018 Red Hat, Inc. + Copyright © 2018 Purism SPC + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + + + This protocol allows compositors to act as input methods and to send text + to applications. A text input object is used to manage state of what are + typically text entry fields in the application. + + This document adheres to the RFC 2119 when using words like "must", + "should", "may", etc. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + + + + + The zwp_text_input_v3 interface represents text input and input methods + associated with a seat. It provides enter/leave events to follow the + text input focus for a seat. + + Requests are used to enable/disable the text-input object and set + state information like surrounding and selected text or the content type. + The information about the entered text is sent to the text-input object + via the preedit_string and commit_string events. + + Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices + must not point to middle bytes inside a code point: they must either + point to the first byte of a code point or to the end of the buffer. + Lengths must be measured between two valid indices. + + Focus moving throughout surfaces will result in the emission of + zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused + surface must commit zwp_text_input_v3.enable and + zwp_text_input_v3.disable requests as the keyboard focus moves across + editable and non-editable elements of the UI. Those two requests are not + expected to be paired with each other, the compositor must be able to + handle consecutive series of the same request. + + State is sent by the state requests (set_surrounding_text, + set_content_type and set_cursor_rectangle) and a commit request. After an + enter event or disable request all state information is invalidated and + needs to be resent by the client. + + + + + Destroy the wp_text_input object. Also disables all surfaces enabled + through this wp_text_input object. + + + + + + Requests text input on the surface previously obtained from the enter + event. + + This request must be issued every time the active text input changes + to a new one, including within the current surface. Use + zwp_text_input_v3.disable when there is no longer any input focus on + the current surface. + + Clients must not enable more than one text input on the single seat + and should disable the current text input before enabling the new one. + At most one instance of text input may be in enabled state per instance, + Requests to enable the another text input when some text input is active + must be ignored by compositor. + + This request resets all state associated with previous enable, disable, + set_surrounding_text, set_text_change_cause, set_content_type, and + set_cursor_rectangle requests, as well as the state associated with + preedit_string, commit_string, and delete_surrounding_text events. + + The set_surrounding_text, set_content_type and set_cursor_rectangle + requests must follow if the text input supports the necessary + functionality. + + State set with this request is double-buffered. It will get applied on + the next zwp_text_input_v3.commit request, and stay valid until the + next committed enable or disable request. + + The changes must be applied by the compositor after issuing a + zwp_text_input_v3.commit request. + + + + + + Explicitly disable text input on the current surface (typically when + there is no focus on any text entry inside the surface). + + State set with this request is double-buffered. It will get applied on + the next zwp_text_input_v3.commit request. + + + + + + Sets the surrounding plain text around the input, excluding the preedit + text. + + The client should notify the compositor of any changes in any of the + values carried with this request, including changes caused by handling + incoming text-input events as well as changes caused by other + mechanisms like keyboard typing. + + If the client is unaware of the text around the cursor, it should not + issue this request, to signify lack of support to the compositor. + + Text is UTF-8 encoded, and should include the cursor position, the + complete selection and additional characters before and after them. + There is a maximum length of wayland messages, so text can not be + longer than 4000 bytes. + + Cursor is the byte offset of the cursor within text buffer. + + Anchor is the byte offset of the selection anchor within text buffer. + If there is no selected text, anchor is the same as cursor. + + If any preedit text is present, it is replaced with a cursor for the + purpose of this event. + + Values set with this request are double-buffered. They will get applied + on the next zwp_text_input_v3.commit request, and stay valid until the + next committed enable or disable request. + + The initial state for affected fields is empty, meaning that the text + input does not support sending surrounding text. If the empty values + get applied, subsequent attempts to change them may have no effect. + + + + + + + + + Reason for the change of surrounding text or cursor posision. + + + + + + + + Tells the compositor why the text surrounding the cursor changed. + + Whenever the client detects an external change in text, cursor, or + anchor posision, it must issue this request to the compositor. This + request is intended to give the input method a chance to update the + preedit text in an appropriate way, e.g. by removing it when the user + starts typing with a keyboard. + + cause describes the source of the change. + + The value set with this request is double-buffered. It must be applied + and reset to initial at the next zwp_text_input_v3.commit request. + + The initial value of cause is input_method. + + + + + + + Content hint is a bitmask to allow to modify the behavior of the text + input. + + + + + + + + + + + + + + + + + The content purpose allows to specify the primary purpose of a text + input. + + This allows an input method to show special purpose input panels with + extra characters or to disallow some characters. + + + + + + + + + + + + + + + + + + + + Sets the content purpose and content hint. While the purpose is the + basic purpose of an input field, the hint flags allow to modify some of + the behavior. + + Values set with this request are double-buffered. They will get applied + on the next zwp_text_input_v3.commit request. + Subsequent attempts to update them may have no effect. The values + remain valid until the next committed enable or disable request. + + The initial value for hint is none, and the initial value for purpose + is normal. + + + + + + + + Marks an area around the cursor as a x, y, width, height rectangle in + surface local coordinates. + + Allows the compositor to put a window with word suggestions near the + cursor, without obstructing the text being input. + + If the client is unaware of the position of edited text, it should not + issue this request, to signify lack of support to the compositor. + + Values set with this request are double-buffered. They will get applied + on the next zwp_text_input_v3.commit request, and stay valid until the + next committed enable or disable request. + + The initial values describing a cursor rectangle are empty. That means + the text input does not support describing the cursor area. If the + empty values get applied, subsequent attempts to change them may have + no effect. + + + + + + + + + + Atomically applies state changes recently sent to the compositor. + + The commit request establishes and updates the state of the client, and + must be issued after any changes to apply them. + + Text input state (enabled status, content purpose, content hint, + surrounding text and change cause, cursor rectangle) is conceptually + double-buffered within the context of a text input, i.e. between a + committed enable request and the following committed enable or disable + request. + + Protocol requests modify the pending state, as opposed to the current + state in use by the input method. A commit request atomically applies + all pending state, replacing the current state. After commit, the new + pending state is as documented for each related request. + + Requests are applied in the order of arrival. + + Neither current nor pending state are modified unless noted otherwise. + + The compositor must count the number of commit requests coming from + each zwp_text_input_v3 object and use the count as the serial in done + events. + + + + + + Notification that this seat's text-input focus is on a certain surface. + + If client has created multiple text input objects, compositor must send + this event to all of them. + + When the seat has the keyboard capability the text-input focus follows + the keyboard focus. This event sets the current surface for the + text-input object. + + + + + + + Notification that this seat's text-input focus is no longer on a + certain surface. The client should reset any preedit string previously + set. + + The leave notification clears the current surface. It is sent before + the enter notification for the new focus. After leave event, compositor + must ignore requests from any text input instances until next enter + event. + + When the seat has the keyboard capability the text-input focus follows + the keyboard focus. + + + + + + + Notify when a new composing text (pre-edit) should be set at the + current cursor position. Any previously set composing text must be + removed. Any previously existing selected text must be removed. + + The argument text contains the pre-edit string buffer. + + The parameters cursor_begin and cursor_end are counted in bytes + relative to the beginning of the submitted text buffer. Cursor should + be hidden when both are equal to -1. + + They could be represented by the client as a line if both values are + the same, or as a text highlight otherwise. + + Values set with this event are double-buffered. They must be applied + and reset to initial on the next zwp_text_input_v3.done event. + + The initial value of text is an empty string, and cursor_begin, + cursor_end and cursor_hidden are all 0. + + + + + + + + + Notify when text should be inserted into the editor widget. The text to + commit could be either just a single character after a key press or the + result of some composing (pre-edit). + + Values set with this event are double-buffered. They must be applied + and reset to initial on the next zwp_text_input_v3.done event. + + The initial value of text is an empty string. + + + + + + + Notify when the text around the current cursor position should be + deleted. + + Before_length and after_length are the number of bytes before and after + the current cursor index (excluding the selection) to delete. + + If a preedit text is present, in effect before_length is counted from + the beginning of it, and after_length from its end (see done event + sequence). + + Values set with this event are double-buffered. They must be applied + and reset to initial on the next zwp_text_input_v3.done event. + + The initial values of both before_length and after_length are 0. + + + + + + + + Instruct the application to apply changes to state requested by the + preedit_string, commit_string and delete_surrounding_text events. The + state relating to these events is double-buffered, and each one + modifies the pending state. This event replaces the current state with + the pending state. + + The application must proceed by evaluating the changes in the following + order: + + 1. Replace existing preedit string with the cursor. + 2. Delete requested surrounding text. + 3. Insert commit string with the cursor at its end. + 4. Calculate surrounding text to send. + 5. Insert new preedit text in cursor position. + 6. Place cursor inside preedit text. + + The serial number reflects the last state of the zwp_text_input_v3 + object known to the compositor. The value of the serial argument must + be equal to the number of commit requests already issued on that object. + When the client receives a done event with a serial different than the + number of past commit requests, it must proceed as normal, except it + should not change the current state of the zwp_text_input_v3 object. + + + + + + + + A factory for text-input objects. This object is a global singleton. + + + + + Destroy the wp_text_input_manager object. + + + + + + Creates a new text-input object for a given seat. + + + + + + diff --git a/Engine/lib/sdl/wayland-protocols/wayland.xml b/Engine/lib/sdl/wayland-protocols/wayland.xml index 29b63be7d..471daf668 100644 --- a/Engine/lib/sdl/wayland-protocols/wayland.xml +++ b/Engine/lib/sdl/wayland-protocols/wayland.xml @@ -57,6 +57,12 @@ This request creates a registry object that allows the client to list and bind the global objects available from the compositor. + + It should be noted that the server side resources consumed in + response to a get_registry request can only be released when the + client disconnects, not when the client side proxy is destroyed. + Therefore, clients should invoke get_registry as infrequently as + possible to avoid wasting memory. @@ -85,18 +91,20 @@ + summary="method doesn't exist on the specified interface or malformed request"/> + This event is used internally by the object ID management - logic. When a client deletes an object, the server will send - this event to acknowledge that it has seen the delete request. - When the client receives this event, it will know that it can - safely reuse the object ID. + logic. When a client deletes an object that it had created, + the server will send this event to acknowledge that it has + seen the delete request. When the client receives this event, + it will know that it can safely reuse the object ID. @@ -285,10 +293,12 @@ formats are optional and may not be supported by the particular renderer in use. - The drm format codes match the macros defined in drm_fourcc.h. - The formats actually supported by the compositor will be - reported by the format event. + The drm format codes match the macros defined in drm_fourcc.h, except + argb8888 and xrgb8888. The formats actually supported by the compositor + will be reported by the format event. + @@ -347,6 +357,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -501,6 +557,9 @@ this request after a NULL mime type has been set in wl_data_offer.accept or no action was received through wl_data_offer.action. + + If wl_data_offer.finish request is received for a non drag and drop + operation, the invalid_finish protocol error is raised. @@ -517,7 +576,7 @@ This request determines the final result of the drag-and-drop operation. If the end result is that no action is accepted, - the drag source will receive wl_drag_source.cancelled. + the drag source will receive wl_data_source.cancelled. The dnd_actions argument must contain only values expressed in the wl_data_device_manager.dnd_actions enum, and the preferred_action @@ -538,8 +597,10 @@ This request can only be made on drag-and-drop offers, a protocol error will be raised otherwise. - - + + @@ -548,7 +609,8 @@ will be sent right after wl_data_device.enter, or anytime the source side changes its offered actions through wl_data_source.set_actions. - + @@ -589,7 +651,8 @@ final wl_data_offer.set_actions and wl_data_offer.accept requests must happen before the call to wl_data_offer.finish. - + @@ -686,7 +749,8 @@ wl_data_device.start_drag. Attempting to use the source other than for drag-and-drop will raise a protocol error. - + @@ -742,7 +806,8 @@ Clients can trigger cursor surface changes from this point, so they reflect the current action. - + @@ -768,7 +833,8 @@ for the eventual data transfer. If source is NULL, enter, leave and motion events are sent only to the client that initiated the drag and the client is expected to handle the data passing - internally. + internally. If source is destroyed, the drag-and-drop session will be + cancelled. The origin surface is the surface where the drag originates and the client must have an active implicit grab that matches the @@ -970,6 +1036,9 @@ It allows clients to associate a wl_shell_surface with a basic surface. + + Note! This protocol is deprecated and not intended for production use. + For desktop-style user interfaces, use xdg_shell. @@ -1265,8 +1334,10 @@ - A surface is a rectangular area that is displayed on the screen. - It has a location, size and pixel contents. + A surface is a rectangular area that may be displayed on zero + or more outputs, and shown any number of times at the compositor's + discretion. They can present wl_buffers, receive user input, and + define a local coordinate system. The size of a surface (and relative positions on it) is described in surface-local coordinates, which may differ from the buffer @@ -1312,6 +1383,7 @@ + @@ -1326,8 +1398,9 @@ The new size of the surface is calculated based on the buffer size transformed by the inverse buffer_transform and the - inverse buffer_scale. This means that the supplied buffer - must be an integer multiple of the buffer_scale. + inverse buffer_scale. This means that at commit time the supplied + buffer size must be an integer multiple of the buffer_scale. If + that's not the case, an invalid_size error is sent. The x and y arguments specify the location of the new pending buffer's upper left corner, relative to the current buffer's upper @@ -1354,6 +1427,12 @@ will not receive a release event, and is not used by the compositor. + If a pending wl_buffer has been committed to more than one wl_surface, + the delivery of wl_buffer.release events becomes undefined. A well + behaved client should not rely on wl_buffer.release events in this + case. Alternatively, a client could create multiple wl_buffer objects + from the same backing storage or use wp_linux_buffer_release. + Destroying the wl_buffer after wl_buffer.release does not change the surface contents. However, if the client destroys the wl_buffer before receiving the wl_buffer.release event, the surface @@ -1388,9 +1467,9 @@ and clears pending damage. The server will clear the current damage as it repaints the surface. - Alternatively, damage can be posted with wl_surface.damage_buffer - which uses buffer coordinates instead of surface coordinates, - and is probably the preferred and intuitive way of doing this. + Note! New clients should not use this request. Instead damage can be + posted with wl_surface.damage_buffer which uses buffer coordinates + instead of surface coordinates. @@ -1534,6 +1613,12 @@ This is emitted whenever a surface's creation, movement, or resizing results in it no longer having any part of it within the scanout region of an output. + + Clients should not use the number of outputs the surface is on for frame + throttling purposes. The surface might be hidden even if no leave event + has been sent, and the compositor might expect new surface content + updates even if no enter event has been sent. The frame event should be + used instead. @@ -1651,7 +1736,7 @@ - + A seat is a group of keyboards, pointer and touch devices. This object is published as a global during start up, or when such a @@ -1669,6 +1754,14 @@ + + + These errors can be emitted in response to wl_seat requests. + + + + This is emitted whenever a seat gains or loses the pointer, @@ -1707,7 +1800,8 @@ This request only takes effect if the seat has the pointer capability, or has had the pointer capability in the past. It is a protocol violation to issue this request on a seat that has - never had the pointer capability. + never had the pointer capability. The missing_capability error will + be sent in this case. @@ -1720,7 +1814,8 @@ This request only takes effect if the seat has the keyboard capability, or has had the keyboard capability in the past. It is a protocol violation to issue this request on a seat that has - never had the keyboard capability. + never had the keyboard capability. The missing_capability error will + be sent in this case. @@ -1733,7 +1828,8 @@ This request only takes effect if the seat has the touch capability, or has had the touch capability in the past. It is a protocol violation to issue this request on a seat that has - never had the touch capability. + never had the touch capability. The missing_capability error will + be sent in this case. @@ -1760,7 +1856,7 @@ - + The wl_pointer interface represents one or more input devices, such as mice, which control the pointer location and pointer_focus @@ -2083,7 +2179,7 @@ - + The wl_keyboard interface represents one or more keyboards associated with a seat. @@ -2104,6 +2200,9 @@ This event provides a file descriptor to the client which can be memory-mapped to provide a keyboard mapping description. + + From version 7 onwards, the fd must be mapped with MAP_PRIVATE by + the recipient, as MAP_SHARED may fail. @@ -2114,6 +2213,9 @@ Notification that this seat's keyboard focus is on a certain surface. + + The compositor must send the wl_keyboard.modifiers event after this + event. @@ -2127,6 +2229,9 @@ The leave notification is sent before the enter notification for the new focus. + + After this event client must assume that all keys, including modifiers, + are lifted and also it must stop key repeating if there's some going on. @@ -2145,6 +2250,12 @@ A key was pressed or released. The time argument is a timestamp with millisecond granularity, with an undefined base. + + The key is a platform-specific key code that can be interpreted + by feeding it to the keyboard mapping (see the keymap event). + + If this event produces a change in modifiers, then the resulting + wl_keyboard.modifiers event must be sent after this event. @@ -2194,7 +2305,7 @@ - + The wl_touch interface represents a touchscreen associated with a seat. @@ -2390,6 +2501,16 @@ The geometry event describes geometric properties of the output. The event is sent when binding to the output object and whenever any of the properties change. + + The physical size can be set to zero if it doesn't make sense for this + output (e.g. for projectors or virtual outputs). + + Note: wl_output only advertises partial information about the output + position and identification. Some compositors, for instance those not + implementing a desktop-style output layout or those exposing virtual + outputs, might fake this information. Instead of using x and y, clients + should use xdg_output.logical_position. Instead of using make and model, + clients should use xdg_output.name and xdg_output.description. @@ -2430,11 +2551,28 @@ current. In other words, the current mode is always the last mode that was received with the current flag set. + Non-current modes are deprecated. A compositor can decide to only + advertise the current mode and never send other modes. Clients + should not rely on non-current modes. + The size of a mode is given in physical hardware units of the output device. This is not necessarily the same as the output size in the global compositor space. For instance, the output may be scaled, as described in wl_output.scale, - or transformed, as described in wl_output.transform. + or transformed, as described in wl_output.transform. Clients + willing to retrieve the output size in the global compositor + space should use xdg_output.logical_size instead. + + The vertical refresh rate can be set to zero if it doesn't make + sense for this output (e.g. for virtual outputs). + + Clients should not use the refresh rate to schedule frames. Instead, + they should use the wl_surface.frame event or the presentation-time + protocol. + + Note: this information is not always meaningful for all outputs. Some + compositors, such as those exposing virtual outputs, might fake the + refresh rate or the size. @@ -2568,6 +2706,14 @@ The to-be sub-surface must not already have another role, and it must not have an existing wl_subsurface object. Otherwise a protocol error is raised. + + Adding sub-surfaces to a parent is a double-buffered operation on the + parent (see wl_surface.commit). The effect of adding a sub-surface + becomes visible on the next time the state of the parent surface is + applied. + + This request modifies the behaviour of wl_surface.commit request on + the sub-surface, see the documentation on wl_subsurface interface. @@ -2601,7 +2747,7 @@ wl_surface state directly. A sub-surface is initially in the synchronized mode. - Sub-surfaces have also other kind of state, which is managed by + Sub-surfaces also have another kind of state, which is managed by wl_subsurface requests, as opposed to wl_surface requests. This state includes the sub-surface position relative to the parent surface (wl_subsurface.set_position), and the stacking order of @@ -2637,7 +2783,7 @@ that was turned into a sub-surface with a wl_subcompositor.get_subsurface request. The wl_surface's association to the parent is deleted, and the wl_surface loses its role as - a sub-surface. The wl_surface is unmapped. + a sub-surface. The wl_surface is unmapped immediately. diff --git a/Engine/lib/sdl/wayland-protocols/xdg-activation-v1.xml b/Engine/lib/sdl/wayland-protocols/xdg-activation-v1.xml new file mode 100644 index 000000000..d87e63374 --- /dev/null +++ b/Engine/lib/sdl/wayland-protocols/xdg-activation-v1.xml @@ -0,0 +1,186 @@ + + + + + Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org> + Copyright © 2020 Carlos Garnacho <carlosg@gnome.org> + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + The way for a client to pass focus to another toplevel is as follows. + + The client that intends to activate another toplevel uses the + xdg_activation_v1.get_activation_token request to get an activation token. + This token is then passed to the client to be activated through a separate + band of communication. The client to be activated will then pass the token + it received to the xdg_activation_v1.activate request. The compositor can + then use this token to decide how to react to the activation request. + + The token the activating client gets may be ineffective either already at + the time it receives it, for example if it was not focused, for focus + stealing prevention. The activating client will have no way to discover + the validity of the token, and may still forward it to the to be activated + client. + + The created activation token may optionally get information attached to it + that can be used by the compositor to identify the application that we + intend to activate. This can for example be used to display a visual hint + about what application is being started. + + Warning! The protocol described in this file is currently in the testing + phase. Backward compatible changes may be added together with the + corresponding interface version bump. Backward incompatible changes can + only be done by creating a new major version of the extension. + + + + + A global interface used for informing the compositor about applications + being activated or started, or for applications to request to be + activated. + + + + + Notify the compositor that the xdg_activation object will no longer be + used. + + The child objects created via this interface are unaffected and should + be destroyed separately. + + + + + + Creates an xdg_activation_token_v1 object that will provide + the initiating client with a unique token for this activation. This + token should be offered to the clients to be activated. + + + + + + + + Requests surface activation. It's up to the compositor to display + this information as desired, for example by placing the surface above + the rest. + + The compositor may know who requested this by checking the activation + token and might decide not to follow through with the activation if it's + considered unwanted. + + Compositors can ignore unknown presentation tokens when an invalid + token is passed. + + + + + + + + + An object for setting up a token and receiving a token handle that can + be passed as an activation token to another client. + + The object is created using the xdg_activation_v1.get_activation_token + request. This object should then be populated with the app_id, surface + and serial information and committed. The compositor shall then issue a + done event with the token. In case the request's parameters are invalid, + the compositor will provide an invalid token. + + + + + + + + + Provides information about the seat and serial event that requested the + token. + + Must be sent before commit. This information is optional. + + + + + + + + The requesting client can specify an app_id to associate the token + being created with it. + + Must be sent before commit. This information is optional. + + + + + + + The requesting client can specify a surface to associate the token + being created with it. + + Must be triggered before commit. This information is optional. + + + + + + + Requests an activation token based on the different parameters that + have been offered through set_serial, set_surface and set_app_id. + + + + + + The 'done' event contains the unique token of this activation request + and notifies that the provider is done. + + Applications will typically receive the token through the + XDG_ACTIVATION_TOKEN environment variable as set by its launcher, and + should unset the environment variable right after this request, in + order to avoid propagating it to child processes. + + Applications implementing the D-Bus interface org.freedesktop.Application + should get their token under XDG_ACTIVATION_TOKEN on their platform_data. + + Presentation tokens may be transferred across clients through means not + described in this protocol. + + + + + + + Notify the compositor that the xdg_activation_token_v1 object will no + longer be used. + + + + diff --git a/Engine/lib/sdl/wayland-protocols/xdg-shell-unstable-v6.xml b/Engine/lib/sdl/wayland-protocols/xdg-shell-unstable-v6.xml deleted file mode 100644 index 1c0f92452..000000000 --- a/Engine/lib/sdl/wayland-protocols/xdg-shell-unstable-v6.xml +++ /dev/null @@ -1,1044 +0,0 @@ - - - - - Copyright © 2008-2013 Kristian Høgsberg - Copyright © 2013 Rafael Antognolli - Copyright © 2013 Jasper St. Pierre - Copyright © 2010-2013 Intel Corporation - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice (including the next - paragraph) shall be included in all copies or substantial portions of the - Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - - - - xdg_shell allows clients to turn a wl_surface into a "real window" - which can be dragged, resized, stacked, and moved around by the - user. Everything about this interface is suited towards traditional - desktop environments. - - - - - - - - - - - - - - Destroy this xdg_shell object. - - Destroying a bound xdg_shell object while there are surfaces - still alive created by this xdg_shell object instance is illegal - and will result in a protocol error. - - - - - - Create a positioner object. A positioner object is used to position - surfaces relative to some parent surface. See the interface description - and xdg_surface.get_popup for details. - - - - - - - This creates an xdg_surface for the given surface. While xdg_surface - itself is not a role, the corresponding surface may only be assigned - a role extending xdg_surface, such as xdg_toplevel or xdg_popup. - - This creates an xdg_surface for the given surface. An xdg_surface is - used as basis to define a role to a given surface, such as xdg_toplevel - or xdg_popup. It also manages functionality shared between xdg_surface - based surface roles. - - See the documentation of xdg_surface for more details about what an - xdg_surface is and how it is used. - - - - - - - - A client must respond to a ping event with a pong request or - the client may be deemed unresponsive. See xdg_shell.ping. - - - - - - - The ping event asks the client if it's still alive. Pass the - serial specified in the event back to the compositor by sending - a "pong" request back with the specified serial. See xdg_shell.ping. - - Compositors can use this to determine if the client is still - alive. It's unspecified what will happen if the client doesn't - respond to the ping request, or in what timeframe. Clients should - try to respond in a reasonable amount of time. - - A compositor is free to ping in any way it wants, but a client must - always respond to any xdg_shell object it created. - - - - - - - - The xdg_positioner provides a collection of rules for the placement of a - child surface relative to a parent surface. Rules can be defined to ensure - the child surface remains within the visible area's borders, and to - specify how the child surface changes its position, such as sliding along - an axis, or flipping around a rectangle. These positioner-created rules are - constrained by the requirement that a child surface must intersect with or - be at least partially adjacent to its parent surface. - - See the various requests for details about possible rules. - - At the time of the request, the compositor makes a copy of the rules - specified by the xdg_positioner. Thus, after the request is complete the - xdg_positioner object can be destroyed or reused; further changes to the - object will have no effect on previous usages. - - For an xdg_positioner object to be considered complete, it must have a - non-zero size set by set_size, and a non-zero anchor rectangle set by - set_anchor_rect. Passing an incomplete xdg_positioner object when - positioning a surface raises an error. - - - - - - - - - Notify the compositor that the xdg_positioner will no longer be used. - - - - - - Set the size of the surface that is to be positioned with the positioner - object. The size is in surface-local coordinates and corresponds to the - window geometry. See xdg_surface.set_window_geometry. - - If a zero or negative size is set the invalid_input error is raised. - - - - - - - - Specify the anchor rectangle within the parent surface that the child - surface will be placed relative to. The rectangle is relative to the - window geometry as defined by xdg_surface.set_window_geometry of the - parent surface. The rectangle must be at least 1x1 large. - - When the xdg_positioner object is used to position a child surface, the - anchor rectangle may not extend outside the window geometry of the - positioned child's parent surface. - - If a zero or negative size is set the invalid_input error is raised. - - - - - - - - - - - - - - - - - - Defines a set of edges for the anchor rectangle. These are used to - derive an anchor point that the child surface will be positioned - relative to. If two orthogonal edges are specified (e.g. 'top' and - 'left'), then the anchor point will be the intersection of the edges - (e.g. the top left position of the rectangle); otherwise, the derived - anchor point will be centered on the specified edge, or in the center of - the anchor rectangle if no edge is specified. - - If two parallel anchor edges are specified (e.g. 'left' and 'right'), - the invalid_input error is raised. - - - - - - - - - - - - - - - Defines in what direction a surface should be positioned, relative to - the anchor point of the parent surface. If two orthogonal gravities are - specified (e.g. 'bottom' and 'right'), then the child surface will be - placed in the specified direction; otherwise, the child surface will be - centered over the anchor point on any axis that had no gravity - specified. - - If two parallel gravities are specified (e.g. 'left' and 'right'), the - invalid_input error is raised. - - - - - - - The constraint adjustment value define ways the compositor will adjust - the position of the surface, if the unadjusted position would result - in the surface being partly constrained. - - Whether a surface is considered 'constrained' is left to the compositor - to determine. For example, the surface may be partly outside the - compositor's defined 'work area', thus necessitating the child surface's - position be adjusted until it is entirely inside the work area. - - The adjustments can be combined, according to a defined precedence: 1) - Flip, 2) Slide, 3) Resize. - - - - Don't alter the surface position even if it is constrained on some - axis, for example partially outside the edge of a monitor. - - - - - Slide the surface along the x axis until it is no longer constrained. - - First try to slide towards the direction of the gravity on the x axis - until either the edge in the opposite direction of the gravity is - unconstrained or the edge in the direction of the gravity is - constrained. - - Then try to slide towards the opposite direction of the gravity on the - x axis until either the edge in the direction of the gravity is - unconstrained or the edge in the opposite direction of the gravity is - constrained. - - - - - Slide the surface along the y axis until it is no longer constrained. - - First try to slide towards the direction of the gravity on the y axis - until either the edge in the opposite direction of the gravity is - unconstrained or the edge in the direction of the gravity is - constrained. - - Then try to slide towards the opposite direction of the gravity on the - y axis until either the edge in the direction of the gravity is - unconstrained or the edge in the opposite direction of the gravity is - constrained. - - - - - Invert the anchor and gravity on the x axis if the surface is - constrained on the x axis. For example, if the left edge of the - surface is constrained, the gravity is 'left' and the anchor is - 'left', change the gravity to 'right' and the anchor to 'right'. - - If the adjusted position also ends up being constrained, the resulting - position of the flip_x adjustment will be the one before the - adjustment. - - - - - Invert the anchor and gravity on the y axis if the surface is - constrained on the y axis. For example, if the bottom edge of the - surface is constrained, the gravity is 'bottom' and the anchor is - 'bottom', change the gravity to 'top' and the anchor to 'top'. - - If the adjusted position also ends up being constrained, the resulting - position of the flip_y adjustment will be the one before the - adjustment. - - - - - Resize the surface horizontally so that it is completely - unconstrained. - - - - - Resize the surface vertically so that it is completely unconstrained. - - - - - - - Specify how the window should be positioned if the originally intended - position caused the surface to be constrained, meaning at least - partially outside positioning boundaries set by the compositor. The - adjustment is set by constructing a bitmask describing the adjustment to - be made when the surface is constrained on that axis. - - If no bit for one axis is set, the compositor will assume that the child - surface should not change its position on that axis when constrained. - - If more than one bit for one axis is set, the order of how adjustments - are applied is specified in the corresponding adjustment descriptions. - - The default adjustment is none. - - - - - - - Specify the surface position offset relative to the position of the - anchor on the anchor rectangle and the anchor on the surface. For - example if the anchor of the anchor rectangle is at (x, y), the surface - has the gravity bottom|right, and the offset is (ox, oy), the calculated - surface position will be (x + ox, y + oy). The offset position of the - surface is the one used for constraint testing. See - set_constraint_adjustment. - - An example use case is placing a popup menu on top of a user interface - element, while aligning the user interface element of the parent surface - with some user interface element placed somewhere in the popup surface. - - - - - - - - - An interface that may be implemented by a wl_surface, for - implementations that provide a desktop-style user interface. - - It provides a base set of functionality required to construct user - interface elements requiring management by the compositor, such as - toplevel windows, menus, etc. The types of functionality are split into - xdg_surface roles. - - Creating an xdg_surface does not set the role for a wl_surface. In order - to map an xdg_surface, the client must create a role-specific object - using, e.g., get_toplevel, get_popup. The wl_surface for any given - xdg_surface can have at most one role, and may not be assigned any role - not based on xdg_surface. - - A role must be assigned before any other requests are made to the - xdg_surface object. - - The client must call wl_surface.commit on the corresponding wl_surface - for the xdg_surface state to take effect. - - Creating an xdg_surface from a wl_surface which has a buffer attached or - committed is a client error, and any attempts by a client to attach or - manipulate a buffer prior to the first xdg_surface.configure call must - also be treated as errors. - - For a surface to be mapped by the compositor, the following conditions - must be met: (1) the client has assigned a xdg_surface based role to the - surface, (2) the client has set and committed the xdg_surface state and - the role dependent state to the surface and (3) the client has committed a - buffer to the surface. - - - - - - - - - - - Destroy the xdg_surface object. An xdg_surface must only be destroyed - after its role object has been destroyed. - - - - - - This creates an xdg_toplevel object for the given xdg_surface and gives - the associated wl_surface the xdg_toplevel role. - - See the documentation of xdg_toplevel for more details about what an - xdg_toplevel is and how it is used. - - - - - - - This creates an xdg_popup object for the given xdg_surface and gives the - associated wl_surface the xdg_popup role. - - See the documentation of xdg_popup for more details about what an - xdg_popup is and how it is used. - - - - - - - - - The window geometry of a surface is its "visible bounds" from the - user's perspective. Client-side decorations often have invisible - portions like drop-shadows which should be ignored for the - purposes of aligning, placing and constraining windows. - - The window geometry is double buffered, and will be applied at the - time wl_surface.commit of the corresponding wl_surface is called. - - Once the window geometry of the surface is set, it is not possible to - unset it, and it will remain the same until set_window_geometry is - called again, even if a new subsurface or buffer is attached. - - If never set, the value is the full bounds of the surface, - including any subsurfaces. This updates dynamically on every - commit. This unset is meant for extremely simple clients. - - The arguments are given in the surface-local coordinate space of - the wl_surface associated with this xdg_surface. - - The width and height must be greater than zero. Setting an invalid size - will raise an error. When applied, the effective window geometry will be - the set window geometry clamped to the bounding rectangle of the - combined geometry of the surface of the xdg_surface and the associated - subsurfaces. - - - - - - - - - - When a configure event is received, if a client commits the - surface in response to the configure event, then the client - must make an ack_configure request sometime before the commit - request, passing along the serial of the configure event. - - For instance, for toplevel surfaces the compositor might use this - information to move a surface to the top left only when the client has - drawn itself for the maximized or fullscreen state. - - If the client receives multiple configure events before it - can respond to one, it only has to ack the last configure event. - - A client is not required to commit immediately after sending - an ack_configure request - it may even ack_configure several times - before its next surface commit. - - A client may send multiple ack_configure requests before committing, but - only the last request sent before a commit indicates which configure - event the client really is responding to. - - - - - - - The configure event marks the end of a configure sequence. A configure - sequence is a set of one or more events configuring the state of the - xdg_surface, including the final xdg_surface.configure event. - - Where applicable, xdg_surface surface roles will during a configure - sequence extend this event as a latched state sent as events before the - xdg_surface.configure event. Such events should be considered to make up - a set of atomically applied configuration states, where the - xdg_surface.configure commits the accumulated state. - - Clients should arrange their surface for the new states, and then send - an ack_configure request with the serial sent in this configure event at - some point before committing the new surface. - - If the client receives multiple configure events before it can respond - to one, it is free to discard all but the last event it received. - - - - - - - - This interface defines an xdg_surface role which allows a surface to, - among other things, set window-like properties such as maximize, - fullscreen, and minimize, set application-specific metadata like title and - id, and well as trigger user interactive operations such as interactive - resize and move. - - - - - Unmap and destroy the window. The window will be effectively - hidden from the user's point of view, and all state like - maximization, fullscreen, and so on, will be lost. - - - - - - Set the "parent" of this surface. This window should be stacked - above a parent. The parent surface must be mapped as long as this - surface is mapped. - - Parent windows should be set on dialogs, toolboxes, or other - "auxiliary" surfaces, so that the parent is raised when the dialog - is raised. - - - - - - - Set a short title for the surface. - - This string may be used to identify the surface in a task bar, - window list, or other user interface elements provided by the - compositor. - - The string must be encoded in UTF-8. - - - - - - - Set an application identifier for the surface. - - The app ID identifies the general class of applications to which - the surface belongs. The compositor can use this to group multiple - surfaces together, or to determine how to launch a new application. - - For D-Bus activatable applications, the app ID is used as the D-Bus - service name. - - The compositor shell will try to group application surfaces together - by their app ID. As a best practice, it is suggested to select app - ID's that match the basename of the application's .desktop file. - For example, "org.freedesktop.FooViewer" where the .desktop file is - "org.freedesktop.FooViewer.desktop". - - See the desktop-entry specification [0] for more details on - application identifiers and how they relate to well-known D-Bus - names and .desktop files. - - [0] http://standards.freedesktop.org/desktop-entry-spec/ - - - - - - - Clients implementing client-side decorations might want to show - a context menu when right-clicking on the decorations, giving the - user a menu that they can use to maximize or minimize the window. - - This request asks the compositor to pop up such a window menu at - the given position, relative to the local surface coordinates of - the parent surface. There are no guarantees as to what menu items - the window menu contains. - - This request must be used in response to some sort of user action - like a button press, key press, or touch down event. - - - - - - - - - - Start an interactive, user-driven move of the surface. - - This request must be used in response to some sort of user action - like a button press, key press, or touch down event. The passed - serial is used to determine the type of interactive move (touch, - pointer, etc). - - The server may ignore move requests depending on the state of - the surface (e.g. fullscreen or maximized), or if the passed serial - is no longer valid. - - If triggered, the surface will lose the focus of the device - (wl_pointer, wl_touch, etc) used for the move. It is up to the - compositor to visually indicate that the move is taking place, such as - updating a pointer cursor, during the move. There is no guarantee - that the device focus will return when the move is completed. - - - - - - - - These values are used to indicate which edge of a surface - is being dragged in a resize operation. - - - - - - - - - - - - - - - Start a user-driven, interactive resize of the surface. - - This request must be used in response to some sort of user action - like a button press, key press, or touch down event. The passed - serial is used to determine the type of interactive resize (touch, - pointer, etc). - - The server may ignore resize requests depending on the state of - the surface (e.g. fullscreen or maximized). - - If triggered, the client will receive configure events with the - "resize" state enum value and the expected sizes. See the "resize" - enum value for more details about what is required. The client - must also acknowledge configure events using "ack_configure". After - the resize is completed, the client will receive another "configure" - event without the resize state. - - If triggered, the surface also will lose the focus of the device - (wl_pointer, wl_touch, etc) used for the resize. It is up to the - compositor to visually indicate that the resize is taking place, - such as updating a pointer cursor, during the resize. There is no - guarantee that the device focus will return when the resize is - completed. - - The edges parameter specifies how the surface should be resized, - and is one of the values of the resize_edge enum. The compositor - may use this information to update the surface position for - example when dragging the top left corner. The compositor may also - use this information to adapt its behavior, e.g. choose an - appropriate cursor image. - - - - - - - - - The different state values used on the surface. This is designed for - state values like maximized, fullscreen. It is paired with the - configure event to ensure that both the client and the compositor - setting the state can be synchronized. - - States set in this way are double-buffered. They will get applied on - the next commit. - - - - The surface is maximized. The window geometry specified in the configure - event must be obeyed by the client. - - - - - The surface is fullscreen. The window geometry specified in the configure - event must be obeyed by the client. - - - - - The surface is being resized. The window geometry specified in the - configure event is a maximum; the client cannot resize beyond it. - Clients that have aspect ratio or cell sizing configuration can use - a smaller size, however. - - - - - Client window decorations should be painted as if the window is - active. Do not assume this means that the window actually has - keyboard or pointer focus. - - - - - - - Set a maximum size for the window. - - The client can specify a maximum size so that the compositor does - not try to configure the window beyond this size. - - The width and height arguments are in window geometry coordinates. - See xdg_surface.set_window_geometry. - - Values set in this way are double-buffered. They will get applied - on the next commit. - - The compositor can use this information to allow or disallow - different states like maximize or fullscreen and draw accurate - animations. - - Similarly, a tiling window manager may use this information to - place and resize client windows in a more effective way. - - The client should not rely on the compositor to obey the maximum - size. The compositor may decide to ignore the values set by the - client and request a larger size. - - If never set, or a value of zero in the request, means that the - client has no expected maximum size in the given dimension. - As a result, a client wishing to reset the maximum size - to an unspecified state can use zero for width and height in the - request. - - Requesting a maximum size to be smaller than the minimum size of - a surface is illegal and will result in a protocol error. - - The width and height must be greater than or equal to zero. Using - strictly negative values for width and height will result in a - protocol error. - - - - - - - - Set a minimum size for the window. - - The client can specify a minimum size so that the compositor does - not try to configure the window below this size. - - The width and height arguments are in window geometry coordinates. - See xdg_surface.set_window_geometry. - - Values set in this way are double-buffered. They will get applied - on the next commit. - - The compositor can use this information to allow or disallow - different states like maximize or fullscreen and draw accurate - animations. - - Similarly, a tiling window manager may use this information to - place and resize client windows in a more effective way. - - The client should not rely on the compositor to obey the minimum - size. The compositor may decide to ignore the values set by the - client and request a smaller size. - - If never set, or a value of zero in the request, means that the - client has no expected minimum size in the given dimension. - As a result, a client wishing to reset the minimum size - to an unspecified state can use zero for width and height in the - request. - - Requesting a minimum size to be larger than the maximum size of - a surface is illegal and will result in a protocol error. - - The width and height must be greater than or equal to zero. Using - strictly negative values for width and height will result in a - protocol error. - - - - - - - - Maximize the surface. - - After requesting that the surface should be maximized, the compositor - will respond by emitting a configure event with the "maximized" state - and the required window geometry. The client should then update its - content, drawing it in a maximized state, i.e. without shadow or other - decoration outside of the window geometry. The client must also - acknowledge the configure when committing the new content (see - ack_configure). - - It is up to the compositor to decide how and where to maximize the - surface, for example which output and what region of the screen should - be used. - - If the surface was already maximized, the compositor will still emit - a configure event with the "maximized" state. - - - - - - Unmaximize the surface. - - After requesting that the surface should be unmaximized, the compositor - will respond by emitting a configure event without the "maximized" - state. If available, the compositor will include the window geometry - dimensions the window had prior to being maximized in the configure - request. The client must then update its content, drawing it in a - regular state, i.e. potentially with shadow, etc. The client must also - acknowledge the configure when committing the new content (see - ack_configure). - - It is up to the compositor to position the surface after it was - unmaximized; usually the position the surface had before maximizing, if - applicable. - - If the surface was already not maximized, the compositor will still - emit a configure event without the "maximized" state. - - - - - - Make the surface fullscreen. - - You can specify an output that you would prefer to be fullscreen. - If this value is NULL, it's up to the compositor to choose which - display will be used to map this surface. - - If the surface doesn't cover the whole output, the compositor will - position the surface in the center of the output and compensate with - black borders filling the rest of the output. - - - - - - - - Request that the compositor minimize your surface. There is no - way to know if the surface is currently minimized, nor is there - any way to unset minimization on this surface. - - If you are looking to throttle redrawing when minimized, please - instead use the wl_surface.frame event for this, as this will - also work with live previews on windows in Alt-Tab, Expose or - similar compositor features. - - - - - - This configure event asks the client to resize its toplevel surface or - to change its state. The configured state should not be applied - immediately. See xdg_surface.configure for details. - - The width and height arguments specify a hint to the window - about how its surface should be resized in window geometry - coordinates. See set_window_geometry. - - If the width or height arguments are zero, it means the client - should decide its own window dimension. This may happen when the - compositor needs to configure the state of the surface but doesn't - have any information about any previous or expected dimension. - - The states listed in the event specify how the width/height - arguments should be interpreted, and possibly how it should be - drawn. - - Clients must send an ack_configure in response to this event. See - xdg_surface.configure and xdg_surface.ack_configure for details. - - - - - - - - - The close event is sent by the compositor when the user - wants the surface to be closed. This should be equivalent to - the user clicking the close button in client-side decorations, - if your application has any. - - This is only a request that the user intends to close the - window. The client may choose to ignore this request, or show - a dialog to ask the user to save their data, etc. - - - - - - - A popup surface is a short-lived, temporary surface. It can be used to - implement for example menus, popovers, tooltips and other similar user - interface concepts. - - A popup can be made to take an explicit grab. See xdg_popup.grab for - details. - - When the popup is dismissed, a popup_done event will be sent out, and at - the same time the surface will be unmapped. See the xdg_popup.popup_done - event for details. - - Explicitly destroying the xdg_popup object will also dismiss the popup and - unmap the surface. Clients that want to dismiss the popup when another - surface of their own is clicked should dismiss the popup using the destroy - request. - - The parent surface must have either the xdg_toplevel or xdg_popup surface - role. - - A newly created xdg_popup will be stacked on top of all previously created - xdg_popup surfaces associated with the same xdg_toplevel. - - The parent of an xdg_popup must be mapped (see the xdg_surface - description) before the xdg_popup itself. - - The x and y arguments passed when creating the popup object specify - where the top left of the popup should be placed, relative to the - local surface coordinates of the parent surface. See - xdg_surface.get_popup. An xdg_popup must intersect with or be at least - partially adjacent to its parent surface. - - The client must call wl_surface.commit on the corresponding wl_surface - for the xdg_popup state to take effect. - - - - - - - - - This destroys the popup. Explicitly destroying the xdg_popup - object will also dismiss the popup, and unmap the surface. - - If this xdg_popup is not the "topmost" popup, a protocol error - will be sent. - - - - - - This request makes the created popup take an explicit grab. An explicit - grab will be dismissed when the user dismisses the popup, or when the - client destroys the xdg_popup. This can be done by the user clicking - outside the surface, using the keyboard, or even locking the screen - through closing the lid or a timeout. - - If the compositor denies the grab, the popup will be immediately - dismissed. - - This request must be used in response to some sort of user action like a - button press, key press, or touch down event. The serial number of the - event should be passed as 'serial'. - - The parent of a grabbing popup must either be an xdg_toplevel surface or - another xdg_popup with an explicit grab. If the parent is another - xdg_popup it means that the popups are nested, with this popup now being - the topmost popup. - - Nested popups must be destroyed in the reverse order they were created - in, e.g. the only popup you are allowed to destroy at all times is the - topmost one. - - When compositors choose to dismiss a popup, they may dismiss every - nested grabbing popup as well. When a compositor dismisses popups, it - will follow the same dismissing order as required from the client. - - The parent of a grabbing popup must either be another xdg_popup with an - active explicit grab, or an xdg_popup or xdg_toplevel, if there are no - explicit grabs already taken. - - If the topmost grabbing popup is destroyed, the grab will be returned to - the parent of the popup, if that parent previously had an explicit grab. - - If the parent is a grabbing popup which has already been dismissed, this - popup will be immediately dismissed. If the parent is a popup that did - not take an explicit grab, an error will be raised. - - During a popup grab, the client owning the grab will receive pointer - and touch events for all their surfaces as normal (similar to an - "owner-events" grab in X11 parlance), while the top most grabbing popup - will always have keyboard focus. - - - - - - - - This event asks the popup surface to configure itself given the - configuration. The configured state should not be applied immediately. - See xdg_surface.configure for details. - - The x and y arguments represent the position the popup was placed at - given the xdg_positioner rule, relative to the upper left corner of the - window geometry of the parent surface. - - - - - - - - - - The popup_done event is sent out when a popup is dismissed by the - compositor. The client should destroy the xdg_popup object at this - point. - - - - - diff --git a/Engine/lib/sdl/wayland-protocols/xdg-shell.xml b/Engine/lib/sdl/wayland-protocols/xdg-shell.xml index d524ea9e2..be64354da 100644 --- a/Engine/lib/sdl/wayland-protocols/xdg-shell.xml +++ b/Engine/lib/sdl/wayland-protocols/xdg-shell.xml @@ -29,7 +29,7 @@ DEALINGS IN THE SOFTWARE. - + The xdg_wm_base interface is exposed as a global object enabling clients to turn their wl_surfaces into windows in a desktop environment. It @@ -101,7 +101,7 @@ The ping event asks the client if it's still alive. Pass the serial specified in the event back to the compositor by sending - a "pong" request back with the specified serial. See xdg_wm_base.ping. + a "pong" request back with the specified serial. See xdg_wm_base.pong. Compositors can use this to determine if the client is still alive. It's unspecified what will happen if the client doesn't @@ -115,7 +115,7 @@ - + The xdg_positioner provides a collection of rules for the placement of a child surface relative to a parent surface. Rules can be defined to ensure @@ -357,9 +357,49 @@ + + + + + + When set reactive, the surface is reconstrained if the conditions used + for constraining changed, e.g. the parent window moved. + + If the conditions changed and the popup was reconstrained, an + xdg_popup.configure event is sent with updated geometry, followed by an + xdg_surface.configure event. + + + + + + Set the parent window geometry the compositor should use when + positioning the popup. The compositor may use this information to + determine the future state the popup should be constrained using. If + this doesn't match the dimension of the parent the popup is eventually + positioned against, the behavior is undefined. + + The arguments are given in the surface-local coordinate space. + + + + + + + + Set the serial of a xdg_surface.configure event this positioner will be + used in response to. The compositor may use this information together + with set_parent_size to determine what future state the popup should be + constrained using. + + + - + An interface that may be implemented by a wl_surface, for implementations that provide a desktop-style user interface. @@ -526,9 +566,10 @@ + - + This interface defines an xdg_surface role which allows a surface to, among other things, set window-like properties such as maximize, @@ -604,6 +645,9 @@ For example, "org.freedesktop.FooViewer" where the .desktop file is "org.freedesktop.FooViewer.desktop". + Like other properties, a set_app_id request can be sent after the + xdg_toplevel has been mapped to update the property. + See the desktop-entry specification [0] for more details on application identifiers and how they relate to well-known D-Bus names and .desktop files. @@ -707,7 +751,7 @@ - + @@ -724,6 +768,9 @@ The surface is maximized. The window geometry specified in the configure event must be obeyed by the client. + + The client should draw without shadow or other + decoration outside of the window geometry. @@ -750,6 +797,30 @@ keyboard or pointer focus. + + + The window is currently in a tiled layout and the left edge is + considered to be adjacent to another part of the tiling grid. + + + + + The window is currently in a tiled layout and the right edge is + considered to be adjacent to another part of the tiling grid. + + + + + The window is currently in a tiled layout and the top edge is + considered to be adjacent to another part of the tiling grid. + + + + + The window is currently in a tiled layout and the bottom edge is + considered to be adjacent to another part of the tiling grid. + + @@ -839,12 +910,11 @@ Maximize the surface. After requesting that the surface should be maximized, the compositor - will respond by emitting a configure event with the "maximized" state - and the required window geometry. The client should then update its - content, drawing it in a maximized state, i.e. without shadow or other - decoration outside of the window geometry. The client must also - acknowledge the configure when committing the new content (see - ack_configure). + will respond by emitting a configure event. Whether this configure + actually sets the window maximized is subject to compositor policies. + The client must then update its content, drawing in the configured + state. The client must also acknowledge the configure when committing + the new content (see ack_configure). It is up to the compositor to decide how and where to maximize the surface, for example which output and what region of the screen should @@ -854,8 +924,8 @@ a configure event with the "maximized" state. If the surface is in a fullscreen state, this request has no direct - effect. It will alter the state the surface is returned to when - unmaximized if not overridden by the compositor. + effect. It may alter the state the surface is returned to when + unmaximized unless overridden by the compositor. @@ -864,13 +934,13 @@ Unmaximize the surface. After requesting that the surface should be unmaximized, the compositor - will respond by emitting a configure event without the "maximized" - state. If available, the compositor will include the window geometry - dimensions the window had prior to being maximized in the configure - event. The client must then update its content, drawing it in a - regular state, i.e. potentially with shadow, etc. The client must also - acknowledge the configure when committing the new content (see - ack_configure). + will respond by emitting a configure event. Whether this actually + un-maximizes the window is subject to compositor policies. + If available and applicable, the compositor will include the window + geometry dimensions the window had prior to being maximized in the + configure event. The client must then update its content, drawing it in + the configured state. The client must also acknowledge the configure + when committing the new content (see ack_configure). It is up to the compositor to position the surface after it was unmaximized; usually the position the surface had before maximizing, if @@ -880,8 +950,8 @@ emit a configure event without the "maximized" state. If the surface is in a fullscreen state, this request has no direct - effect. It will alter the state the surface is returned to when - unmaximized if not overridden by the compositor. + effect. It may alter the state the surface is returned to when + unmaximized unless overridden by the compositor. @@ -890,10 +960,10 @@ Make the surface fullscreen. After requesting that the surface should be fullscreened, the - compositor will respond by emitting a configure event with the - "fullscreen" state and the fullscreen window geometry. The client must - also acknowledge the configure when committing the new content (see - ack_configure). + compositor will respond by emitting a configure event. Whether the + client is actually put into a fullscreen state is subject to compositor + policies. The client must also acknowledge the configure when + committing the new content (see ack_configure). The output passed by the request indicates the client's preference as to which display it should be set fullscreen on. If this value is NULL, @@ -919,8 +989,9 @@ Make the surface no longer fullscreen. After requesting that the surface should be unfullscreened, the - compositor will respond by emitting a configure event without the - "fullscreen" state. + compositor will respond by emitting a configure event. + Whether this actually removes the fullscreen state of the client is + subject to compositor policies. Making a surface unfullscreen sets states for the surface based on the following: * the state(s) it may have had before becoming fullscreen @@ -989,7 +1060,7 @@ - + A popup surface is a short-lived, temporary surface. It can be used to implement for example menus, popovers, tooltips and other similar user @@ -1007,21 +1078,12 @@ surface of their own is clicked should dismiss the popup using the destroy request. - The parent surface must have either the xdg_toplevel or xdg_popup surface - role. - A newly created xdg_popup will be stacked on top of all previously created xdg_popup surfaces associated with the same xdg_toplevel. The parent of an xdg_popup must be mapped (see the xdg_surface description) before the xdg_popup itself. - The x and y arguments passed when creating the popup object specify - where the top left of the popup should be placed, relative to the - local surface coordinates of the parent surface. See - xdg_surface.get_popup. An xdg_popup must intersect with or be at least - partially adjacent to its parent surface. - The client must call wl_surface.commit on the corresponding wl_surface for the xdg_popup state to take effect. @@ -1099,6 +1161,11 @@ The x and y arguments represent the position the popup was placed at given the xdg_positioner rule, relative to the upper left corner of the window geometry of the parent surface. + + For version 2 or older, the configure event for an xdg_popup is only + ever sent once for the initial configuration. Starting with version 3, + it may be sent again if the popup is setup with an xdg_positioner with + set_reactive requested, or in response to xdg_popup.reposition requests. @@ -1116,5 +1183,58 @@ + + + + + Reposition an already-mapped popup. The popup will be placed given the + details in the passed xdg_positioner object, and a + xdg_popup.repositioned followed by xdg_popup.configure and + xdg_surface.configure will be emitted in response. Any parameters set + by the previous positioner will be discarded. + + The passed token will be sent in the corresponding + xdg_popup.repositioned event. The new popup position will not take + effect until the corresponding configure event is acknowledged by the + client. See xdg_popup.repositioned for details. The token itself is + opaque, and has no other special meaning. + + If multiple reposition requests are sent, the compositor may skip all + but the last one. + + If the popup is repositioned in response to a configure event for its + parent, the client should send an xdg_positioner.set_parent_configure + and possibly a xdg_positioner.set_parent_size request to allow the + compositor to properly constrain the popup. + + If the popup is repositioned together with a parent that is being + resized, but not in response to a configure event, the client should + send a xdg_positioner.set_parent_size request. + + + + + + + + The repositioned event is sent as part of a popup configuration + sequence, together with xdg_popup.configure and lastly + xdg_surface.configure to notify the completion of a reposition request. + + The repositioned event is to notify about the completion of a + xdg_popup.reposition request. The token argument is the token passed + in the xdg_popup.reposition request. + + Immediately after this event is emitted, xdg_popup.configure and + xdg_surface.configure will be sent with the updated size and position, + as well as a new configure serial. + + The client should optionally update the content of the popup, but must + acknowledge the new popup configuration for the new position to take + effect. See xdg_surface.ack_configure for details. + + + + From 69d547fd72709fc9baf248c2fb7c90dc46c8c68a Mon Sep 17 00:00:00 2001 From: JeffR Date: Sat, 26 Mar 2022 22:36:37 -0500 Subject: [PATCH 057/145] Adjusted handling for the bitmap and bitmapAsset fields for guiBitmapButtonCtrl to forcefully update the button states when changed, ensuring that the bitmaps refresh when changed via the field Added callback for onResize to guiWindowCtrl so controls - such as the EditorTree - can be properly resized in certain circumstances when the window is changed Added getIncrement() and getRange() to GuiGameSettingsCtrl to better facilitate options manipulation on the script side Corrected some of the console method documentation strings in GuiGameSettingsCtrl Removed some unneeded, extraneous files and their asset definitions that came from odd import conversions. Where applicable, created cleaned up versions to make naming conventions and references stable Fixed canvas mode update text typo: FSAA -> FXAA Added logic to DOF, Light Rays, SSAO and Vignette postFX's to check both the preset setting AND the user preference before enabling. Shifted initialization order so PostFX's are loaded before we configure the canvas, to ensure stuff like the FXAAPostFX exists and can be toggled on on load Fixed multiple issues with options menu: When using gamepad, unable to navigate from categories to options. Fixed so can now traverse as normal Input limitations on gamepad necessitated changing of how setting applying happens, is now done as a 'apply or discard' prompt when leaving the options menu Added proper handling for adjusting settings with gamepad with left/right inputs Fixed issue where the unapplied change for an option was sometimes being processed as an object name rather than an implicit string. Now made to be explicit strings to avoid issue. Made the menu button input for "Select" to go from categories to options gamepad only, and hidden when in the options list Fixed issue where changing window mode didn't correctly affect resolution option. Now set up so changing this field correctly refreshes the resolution option. Specifically, when on borderless, the resolution field does not show, preventing confusion as it is always full resolution Generally have the options list refresh when changes happen to allow any and all fields to be able to dynamically respond to other options having changed improving flexibility. Cleaned up old, unused, commented out functions Added ability on OKCancel message boxes to override the button text if needed Fixed issue with AssetBrowser where the shrink/grow icons next to the preview size slider were not anchored correctly. Adjusted callback logic so if preview slider is clicked on, rather than dragged, it will correctly update the zoom values Added sorting to Modules List dropdown for the AssetBrowser Improved standardization of double-clicking in AssetBrowser. Now defaults to editing action if regularly browsing and selecting if in select mode. Still allows regular per-type overrides as normal Moved definition of GuiDisabledTextEditProfile to gui profiles.ed.tscript file, removed duplicates to stop error spam Adjusted default settings value for double-click action in AB to be edit to prevent unstable behavior Removed old file refs from Load Recent list in the default settings --- .../gui/buttons/guiBitmapButtonCtrl.cpp | 7 +- .../source/gui/buttons/guiBitmapButtonCtrl.h | 8 + .../source/gui/containers/guiWindowCtrl.cpp | 5 + Engine/source/gui/containers/guiWindowCtrl.h | 1 + .../gui/controls/guiGameSettingsCtrl.cpp | 35 +- .../source/gui/controls/guiGameSettingsCtrl.h | 10 + .../core/gameObjects/shapes/Camera.asset.taml | 1 - .../game/core/gui/scripts/canvas.tscript | 2 +- .../DepthOfField/DepthOfFieldPostFX.tscript | 4 +- .../scripts/LightRays/lightRays.tscript | 4 +- .../postFX/scripts/SSAO/SSAOPostFx.tscript | 4 +- .../scripts/Vignette/VignettePostFX.tscript | 4 +- .../core/rendering/Core_Rendering.tscript | 4 +- .../materials/moon_noglow.asset.taml | 2 +- .../rendering/materials/moon_noglow.tscript | 9 - .../materials/moon_noglowMat.asset.taml | 14 - .../materials/moon_wcorona.asset.taml | 2 +- .../materials/moon_wcoronaMat.asset.taml | 2 +- .../rendering/materials/moon_wglow.tscript | 9 - .../materials/moon_wglowMat.asset.taml | 14 - .../rendering/shapes/noShapeMat.asset.taml | 2 +- .../game/data/UI/guis/optionsMenu.gui | 343 ++++-------------- .../game/data/UI/guis/optionsMenu.tscript | 230 ++++++------ .../{groupborder.png => group_border.png} | Bin .../UI/images/group_border_image.asset.taml | 2 +- .../images/{nopreview.png => no_preview.png} | Bin .../UI/images/no_preview_image.asset.taml | 2 +- .../data/UI/images/nopreview_image.asset.taml | 3 - ...selectorbutton.png => selector_button.png} | Bin ...tonblank.png => selector_button_blank.png} | Bin .../selector_button_blank_image.asset.taml | 2 +- ...uttondark.png => selector_button_dark.png} | Bin .../selector_button_dark_image.asset.taml | 2 +- ...png => selector_button_highlight_only.png} | Bin ...tor_button_highlight_only_image.asset.taml | 2 +- .../images/selector_button_image.asset.taml | 2 +- .../UI/images/selectorbutton_image.asset.taml | 3 - .../selectorbuttonblank_image.asset.taml | 3 - .../selectorbuttondark_image.asset.taml | 3 - ...lectorbuttonhighlightonly_image.asset.taml | 3 - .../images/{tabborder.png => tab_border.png} | Bin .../UI/images/tab_border_image.asset.taml | 2 +- .../data/UI/images/tabborder_image.asset.taml | 3 - .../data/UI/scripts/menuInputHandling.tscript | 54 ++- .../game/data/UI/scripts/messageBoxes.tscript | 16 +- .../tools/assetBrowser/guis/assetBrowser.gui | 5 +- .../scripts/addModuleWindow.tscript | 2 + .../assetBrowser/scripts/assetBrowser.tscript | 22 +- .../scripts/assetTypes/material.tscript | 5 + .../tools/convexEditor/convexEditor.tscript | 17 - .../game/tools/gui/profiles.ed.tscript | 21 +- .../meshRoadEditor/meshRoadEditor.tscript | 17 - Templates/BaseGame/game/tools/settings.xml | 6 +- .../worldEditor/scripts/EditorGui.ed.tscript | 6 + 54 files changed, 382 insertions(+), 537 deletions(-) delete mode 100644 Templates/BaseGame/game/core/gameObjects/shapes/Camera.asset.taml delete mode 100644 Templates/BaseGame/game/core/rendering/materials/moon_noglow.tscript delete mode 100644 Templates/BaseGame/game/core/rendering/materials/moon_noglowMat.asset.taml delete mode 100644 Templates/BaseGame/game/core/rendering/materials/moon_wglow.tscript delete mode 100644 Templates/BaseGame/game/core/rendering/materials/moon_wglowMat.asset.taml rename Templates/BaseGame/game/data/UI/images/{groupborder.png => group_border.png} (100%) rename Templates/BaseGame/game/data/UI/images/{nopreview.png => no_preview.png} (100%) delete mode 100644 Templates/BaseGame/game/data/UI/images/nopreview_image.asset.taml rename Templates/BaseGame/game/data/UI/images/{selectorbutton.png => selector_button.png} (100%) rename Templates/BaseGame/game/data/UI/images/{selectorbuttonblank.png => selector_button_blank.png} (100%) rename Templates/BaseGame/game/data/UI/images/{selectorbuttondark.png => selector_button_dark.png} (100%) rename Templates/BaseGame/game/data/UI/images/{selectorbuttonhighlightonly.png => selector_button_highlight_only.png} (100%) delete mode 100644 Templates/BaseGame/game/data/UI/images/selectorbutton_image.asset.taml delete mode 100644 Templates/BaseGame/game/data/UI/images/selectorbuttonblank_image.asset.taml delete mode 100644 Templates/BaseGame/game/data/UI/images/selectorbuttondark_image.asset.taml delete mode 100644 Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly_image.asset.taml rename Templates/BaseGame/game/data/UI/images/{tabborder.png => tab_border.png} (100%) delete mode 100644 Templates/BaseGame/game/data/UI/images/tabborder_image.asset.taml diff --git a/Engine/source/gui/buttons/guiBitmapButtonCtrl.cpp b/Engine/source/gui/buttons/guiBitmapButtonCtrl.cpp index 65672f4e6..c4b059ce8 100644 --- a/Engine/source/gui/buttons/guiBitmapButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiBitmapButtonCtrl.cpp @@ -138,10 +138,15 @@ void GuiBitmapButtonCtrl::initPersistFields() { addGroup( "Bitmap" ); - INITPERSISTFIELD_IMAGEASSET(Bitmap, GuiBitmapButtonCtrl, "Texture file to display on this button.\n" + addProtectedField("Bitmap", TypeImageFilename, Offset(mBitmapName, GuiBitmapButtonCtrl), _setBitmapFieldData, &defaultProtectedGetFn, "Texture file to display on this button.\n" + "If useStates is false, this will be the file that renders on the control. Otherwise, this will " + "specify the default texture name to which the various state and modifier suffixes are appended " + "to find the per-state and per-modifier (if enabled) textures.", AbstractClassRep::FIELD_HideInInspectors); \ + addProtectedField("BitmapAsset", TypeImageAssetId, Offset(mBitmapAssetId, GuiBitmapButtonCtrl), _setBitmapFieldData, &defaultProtectedGetFn, "Texture file to display on this button.\n" "If useStates is false, this will be the file that renders on the control. Otherwise, this will " "specify the default texture name to which the various state and modifier suffixes are appended " "to find the per-state and per-modifier (if enabled) textures."); + addField("color", TypeColorI, Offset(mColor, GuiBitmapButtonCtrl), "color mul"); addField( "bitmapMode", TYPEID< BitmapMode >(), Offset( mBitmapMode, GuiBitmapButtonCtrl ), diff --git a/Engine/source/gui/buttons/guiBitmapButtonCtrl.h b/Engine/source/gui/buttons/guiBitmapButtonCtrl.h index 910ff2400..e605b15b1 100644 --- a/Engine/source/gui/buttons/guiBitmapButtonCtrl.h +++ b/Engine/source/gui/buttons/guiBitmapButtonCtrl.h @@ -185,6 +185,14 @@ class GuiBitmapButtonCtrl : public GuiButtonCtrl DECLARE_CONOBJECT(GuiBitmapButtonCtrl); DECLARE_DESCRIPTION( "A button control rendered entirely from bitmaps.\n" "The individual button states are represented with separate bitmaps." ); + + //Basically a wrapper function to do our special state handling setup when the fields change + static bool _setBitmapFieldData(void* obj, const char* index, const char* data) + { + GuiBitmapButtonCtrl* object = static_cast(obj); + object->setBitmap(StringTable->insert(data)); + return false; + } }; typedef GuiBitmapButtonCtrl::BitmapMode GuiBitmapMode; diff --git a/Engine/source/gui/containers/guiWindowCtrl.cpp b/Engine/source/gui/containers/guiWindowCtrl.cpp index 74a155b9b..ddd11bd40 100644 --- a/Engine/source/gui/containers/guiWindowCtrl.cpp +++ b/Engine/source/gui/containers/guiWindowCtrl.cpp @@ -66,6 +66,9 @@ IMPLEMENT_CALLBACK( GuiWindowCtrl, onCollapse, void, (), (), "Called when the window is collapsed by clicking its title bar." ); IMPLEMENT_CALLBACK( GuiWindowCtrl, onRestore, void, (), (), "Called when the window is restored from minimized, maximized, or collapsed state." ); +IMPLEMENT_CALLBACK(GuiWindowCtrl, onResize, void, (S32 posX, S32 posY, S32 width, S32 height), (0, 0, 0, 0), + "Called when the window is resized in a regular manner by mouse manipulation."); + //----------------------------------------------------------------------------- @@ -1557,6 +1560,8 @@ bool GuiWindowCtrl::resize(const Point2I &newPosition, const Point2I &newExtent) // Set the button coords positionButtons(); + onResize_callback(newPosition.x, newPosition.y, newExtent.x, newExtent.y); + return true; } diff --git a/Engine/source/gui/containers/guiWindowCtrl.h b/Engine/source/gui/containers/guiWindowCtrl.h index ef1b61751..d484973e6 100644 --- a/Engine/source/gui/containers/guiWindowCtrl.h +++ b/Engine/source/gui/containers/guiWindowCtrl.h @@ -201,6 +201,7 @@ class GuiWindowCtrl : public GuiContainer DECLARE_CALLBACK( void, onMaximize, () ); DECLARE_CALLBACK( void, onCollapse, () ); DECLARE_CALLBACK( void, onRestore, () ); + DECLARE_CALLBACK(void, onResize, (S32 posX, S32 posY, S32 width, S32 height)); /// @} diff --git a/Engine/source/gui/controls/guiGameSettingsCtrl.cpp b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp index 1b6516e4a..f608ea83f 100644 --- a/Engine/source/gui/controls/guiGameSettingsCtrl.cpp +++ b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp @@ -740,7 +740,7 @@ void GuiGameSettingsCtrl::changeOption(S32 delta) if (mScriptCallback != NULL && (mSelectedOption != NO_OPTION && mMode != GuiGameSettingsCtrl::Slider)) { setThisControl(); - StringTableEntry direction = NULL; + StringTableEntry direction = StringTable->EmptyString(); if (delta < 0) { direction = LEFT; @@ -749,7 +749,7 @@ void GuiGameSettingsCtrl::changeOption(S32 delta) { direction = RIGHT; } - if ((direction != NULL) && (Con::isFunction(mScriptCallback))) + if ((direction != StringTable->EmptyString()) && (Con::isFunction(mScriptCallback))) { Con::executef(mScriptCallback, direction); } @@ -849,6 +849,16 @@ void GuiGameSettingsCtrl::setValue(F32 value) mValue = value; } +F32 GuiGameSettingsCtrl::getIncrement() +{ + return mStepSize; +} + +Point2F GuiGameSettingsCtrl::getRange() +{ + return mRange; +} + const char* GuiGameSettingsCtrl::getTooltip() { return mTooltip; @@ -1100,22 +1110,31 @@ DefineEngineMethod(GuiGameSettingsCtrl, addOption, void, (const char* displayTex } DefineEngineMethod(GuiGameSettingsCtrl, getValue, F32, (), , - "Sets the list of options on the given control.\n\n" - "@param optionsList A tab separated list of options for the control.") + "Gets the value of the slider on the given control.") { return object->getValue(); } DefineEngineMethod(GuiGameSettingsCtrl, setValue, void, (F32 value), , - "Sets the list of options on the given control.\n\n" - "@param optionsList A tab separated list of options for the control.") + "Sets the value of the slider on the given control.") { object->setValue(value); } +DefineEngineMethod(GuiGameSettingsCtrl, getIncrement, F32, (), , + "Gets the increment amount of the slider on a given control.") +{ + return object->getIncrement(); +} + +DefineEngineMethod(GuiGameSettingsCtrl, getRange, Point2F, (), , + "Gets the min and max values for the range of the slider on a given control.") +{ + return object->getRange(); +} + DefineEngineMethod(GuiGameSettingsCtrl, getTooltip, const char*, (), , - "Sets the list of options on the given control.\n\n" - "@param optionsList A tab separated list of options for the control.") + "Gets the tooltip on the given control.") { return object->getTooltip(); } diff --git a/Engine/source/gui/controls/guiGameSettingsCtrl.h b/Engine/source/gui/controls/guiGameSettingsCtrl.h index d8aac95e8..86a3465f1 100644 --- a/Engine/source/gui/controls/guiGameSettingsCtrl.h +++ b/Engine/source/gui/controls/guiGameSettingsCtrl.h @@ -214,6 +214,16 @@ public: Mode getMode() { return mMode; } + /// + /// Gets the incremenet amount + /// + F32 getIncrement(); + + /// + /// Gets range of values allowed + /// + Point2F getRange(); + /// Gets the tooltip const char* getTooltip(); diff --git a/Templates/BaseGame/game/core/gameObjects/shapes/Camera.asset.taml b/Templates/BaseGame/game/core/gameObjects/shapes/Camera.asset.taml deleted file mode 100644 index 0f15637ff..000000000 --- a/Templates/BaseGame/game/core/gameObjects/shapes/Camera.asset.taml +++ /dev/null @@ -1 +0,0 @@ - constuctorFileName="@assetFile=camera.tscript" /> diff --git a/Templates/BaseGame/game/core/gui/scripts/canvas.tscript b/Templates/BaseGame/game/core/gui/scripts/canvas.tscript index 5a22d909a..94dde1d84 100644 --- a/Templates/BaseGame/game/core/gui/scripts/canvas.tscript +++ b/Templates/BaseGame/game/core/gui/scripts/canvas.tscript @@ -115,7 +115,7 @@ function configureCanvas() "--Screen Mode : " @ %fsLabel NL "--Bits Per Pixel : " @ %bpp NL "--Refresh Rate : " @ %rate NL - "--FSAA Level : " @ %aa NL + "--FXAA Level : " @ %aa NL "--------------"); // Actually set the new video mode diff --git a/Templates/BaseGame/game/core/postFX/scripts/DepthOfField/DepthOfFieldPostFX.tscript b/Templates/BaseGame/game/core/postFX/scripts/DepthOfField/DepthOfFieldPostFX.tscript index 29e1bb117..74feb289d 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/DepthOfField/DepthOfFieldPostFX.tscript +++ b/Templates/BaseGame/game/core/postFX/scripts/DepthOfField/DepthOfFieldPostFX.tscript @@ -474,7 +474,7 @@ function DepthOfFieldPostFX::populatePostFXSettings(%this) function PostEffectEditorInspector::toggleDepthOfFieldPostFX(%this) { - if($PostFX::DepthOfFieldPostFX::Enabled) + if($PostFX::DepthOfFieldPostFX::Enabled && $pref::PostFX::EnableDOF) DepthOfFieldPostFX.enable(); else DepthOfFieldPostFX.disable(); @@ -482,7 +482,7 @@ function PostEffectEditorInspector::toggleDepthOfFieldPostFX(%this) function DepthOfFieldPostFX::applyFromPreset(%this) { - if($PostFX::DepthOfFieldPostFX::Enabled) + if($PostFX::DepthOfFieldPostFX::Enabled && $pref::PostFX::EnableDOF) DepthOfFieldPostFX.enable(); else DepthOfFieldPostFX.disable(); diff --git a/Templates/BaseGame/game/core/postFX/scripts/LightRays/lightRays.tscript b/Templates/BaseGame/game/core/postFX/scripts/LightRays/lightRays.tscript index 9d029b9b0..b6d34da3b 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/LightRays/lightRays.tscript +++ b/Templates/BaseGame/game/core/postFX/scripts/LightRays/lightRays.tscript @@ -126,7 +126,7 @@ function LightRayPostFX::populatePostFXSettings(%this) function PostEffectEditorInspector::toggleLightRayPostFX(%this) { - if($PostFX::LightRayPostFX::Enabled) + if($PostFX::LightRayPostFX::Enabled && $pref::PostFX::EnableLightRays) LightRayPostFX.enable(); else LightRayPostFX.disable(); @@ -134,7 +134,7 @@ function PostEffectEditorInspector::toggleLightRayPostFX(%this) function LightRayPostFX::applyFromPreset(%this) { - if($PostFX::LightRayPostFX::Enabled) + if($PostFX::LightRayPostFX::Enabled && $pref::PostFX::EnableLightRays) %this.enable(); else %this.disable(); diff --git a/Templates/BaseGame/game/core/postFX/scripts/SSAO/SSAOPostFx.tscript b/Templates/BaseGame/game/core/postFX/scripts/SSAO/SSAOPostFx.tscript index 8c95bff7a..c9a5bec3c 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/SSAO/SSAOPostFx.tscript +++ b/Templates/BaseGame/game/core/postFX/scripts/SSAO/SSAOPostFx.tscript @@ -165,7 +165,7 @@ function SSAOPostFx::populatePostFXSettings(%this) function PostEffectEditorInspector::toggleSSAOPostFx(%this) { - if($PostFX::SSAOPostFx::Enabled) + if($PostFX::SSAOPostFx::Enabled && $pref::PostFX::EnableSSAO) SSAOPostFx.enable(); else SSAOPostFx.disable(); @@ -173,7 +173,7 @@ function PostEffectEditorInspector::toggleSSAOPostFx(%this) function SSAOPostFx::applyFromPreset(%this) { - if($PostFXManager::PostFX::Enable) + if($PostFXManager::PostFX::Enable && $pref::PostFX::EnableSSAO) %this.enable(); else %this.disable(); diff --git a/Templates/BaseGame/game/core/postFX/scripts/Vignette/VignettePostFX.tscript b/Templates/BaseGame/game/core/postFX/scripts/Vignette/VignettePostFX.tscript index 014dc6524..414a3d2ef 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/Vignette/VignettePostFX.tscript +++ b/Templates/BaseGame/game/core/postFX/scripts/Vignette/VignettePostFX.tscript @@ -91,7 +91,7 @@ function VignettePostFX::populatePostFXSettings(%this) //Allow us to easily toggle the postFX and have it respond immediately function PostEffectEditorInspector::toggleVignettePostFX(%this) { - if($PostFX::VignettePostFX::Enabled) + if($PostFX::VignettePostFX::Enabled && $pref::PostFX::EnableVignette) VignettePostFX.enable(); else VignettePostFX.disable(); @@ -102,7 +102,7 @@ function PostEffectEditorInspector::toggleVignettePostFX(%this) //when rendering. This allows us to modify things but still leave room for reverting or temporarily applying them function VignettePostFX::applyFromPreset(%this) { - if($PostFX::VignettePostFX::Enabled) + if($PostFX::VignettePostFX::Enabled && $pref::PostFX::EnableVignette) %this.enable(); else %this.disable(); diff --git a/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript b/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript index eb18dfe8a..ae6168dea 100644 --- a/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript +++ b/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript @@ -56,11 +56,11 @@ function Core_Rendering::initClient(%this) %prefPath = getPrefpath(); if ( isFile( %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension ) ) exec( %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension ); + + postFXInit(); configureCanvas(); - postFXInit(); - //Autodetect settings if it's our first time if($pref::Video::autoDetect) AutodetectGraphics(); diff --git a/Templates/BaseGame/game/core/rendering/materials/moon_noglow.asset.taml b/Templates/BaseGame/game/core/rendering/materials/moon_noglow.asset.taml index 76e9d5d00..b4a853da4 100644 --- a/Templates/BaseGame/game/core/rendering/materials/moon_noglow.asset.taml +++ b/Templates/BaseGame/game/core/rendering/materials/moon_noglow.asset.taml @@ -12,7 +12,7 @@ + vertColor="1"/> \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/materials/moon_noglow.tscript b/Templates/BaseGame/game/core/rendering/materials/moon_noglow.tscript deleted file mode 100644 index b9e69c0da..000000000 --- a/Templates/BaseGame/game/core/rendering/materials/moon_noglow.tscript +++ /dev/null @@ -1,9 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -singleton Material(moon_noglow) { - mapTo="moon_noglow"; - DiffuseMapAsset = "Core_Rendering:moon_noglow_image"; - emissive = true; - translucent = true; - vertColor[ 0 ] = true; -}; -//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/core/rendering/materials/moon_noglowMat.asset.taml b/Templates/BaseGame/game/core/rendering/materials/moon_noglowMat.asset.taml deleted file mode 100644 index afb79ab61..000000000 --- a/Templates/BaseGame/game/core/rendering/materials/moon_noglowMat.asset.taml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/materials/moon_wcorona.asset.taml b/Templates/BaseGame/game/core/rendering/materials/moon_wcorona.asset.taml index d3b29de39..28589fb99 100644 --- a/Templates/BaseGame/game/core/rendering/materials/moon_wcorona.asset.taml +++ b/Templates/BaseGame/game/core/rendering/materials/moon_wcorona.asset.taml @@ -1,7 +1,7 @@ + vertColor="1"/> \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/materials/moon_wglow.tscript b/Templates/BaseGame/game/core/rendering/materials/moon_wglow.tscript deleted file mode 100644 index ad87ba5a3..000000000 --- a/Templates/BaseGame/game/core/rendering/materials/moon_wglow.tscript +++ /dev/null @@ -1,9 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -singleton Material(moon_wglow) { - mapTo="moon_wglow"; - DiffuseMapAsset = "Core_Rendering:moon_wglow_image"; - emissive = true; - translucent = true; - vertColor[ 0 ] = true; -}; -//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/core/rendering/materials/moon_wglowMat.asset.taml b/Templates/BaseGame/game/core/rendering/materials/moon_wglowMat.asset.taml deleted file mode 100644 index afb79ab61..000000000 --- a/Templates/BaseGame/game/core/rendering/materials/moon_wglowMat.asset.taml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shapes/noShapeMat.asset.taml b/Templates/BaseGame/game/core/rendering/shapes/noShapeMat.asset.taml index 0a2fb3cb1..d9d9b75e7 100644 --- a/Templates/BaseGame/game/core/rendering/shapes/noShapeMat.asset.taml +++ b/Templates/BaseGame/game/core/rendering/shapes/noShapeMat.asset.taml @@ -7,7 +7,7 @@ diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui b/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui index a8fc2fb1e..84c70072f 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui @@ -1,296 +1,160 @@ //--- OBJECT WRITE BEGIN --- $guiContent = new GuiControl(OptionsMenu) { - position = "0 0"; extent = "1024 768"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; isContainer = "1"; - canSave = "1"; canSaveDynamicFields = "1"; + currentCategory = "Display"; + optionsCategories = "17177"; pageTabIndex = "0"; returnGui = "MainMenuGui"; tamlReader = "20088"; tile = "0"; + unappliedChanges = "17178"; useVariable = "0"; new GuiControl() { position = "48 56"; extent = "928 655"; - minExtent = "8 2"; horizSizing = "aspectCenter"; vertSizing = "center"; profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiBitmapBarCtrl() { - percent = "100"; - vertical = "0"; - flipClip = "0"; BitmapAsset = "UI:panel_low_image"; - color = "255 255 255 255"; position = "0 40"; extent = "927 618"; - minExtent = "8 2"; horizSizing = "width"; - vertSizing = "bottom"; profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapBarCtrl() { - percent = "100"; - vertical = "0"; - flipClip = "0"; BitmapAsset = "UI:panel_image"; - color = "255 255 255 255"; - position = "0 0"; extent = "927 40"; - minExtent = "8 2"; horizSizing = "width"; - vertSizing = "bottom"; profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "OPTIONS"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "22 7"; extent = "120 28"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "MenuHeaderText"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl(OptionName) { - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "3 606"; extent = "293 17"; - minExtent = "8 2"; horizSizing = "width"; - vertSizing = "bottom"; profile = "MenuSubHeaderText"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiMLTextCtrl(OptionDescription) { - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; text = "This is a placeholder text for an option."; - useURLMouseCursor = "0"; position = "3 625"; extent = "293 14"; - minExtent = "8 2"; horizSizing = "width"; - vertSizing = "bottom"; profile = "GuiMLTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiSplitContainer() { - orientation = "Vertical"; - splitterSize = "2"; splitPoint = "250 100"; fixedPanel = "FirstPanel"; fixedSize = "250"; - docking = "None"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "0 48"; extent = "928 555"; - minExtent = "64 64"; horizSizing = "width"; - vertSizing = "bottom"; profile = "GuiMenuScrollProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiPanel() { docking = "Client"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "0 0"; extent = "248 555"; - minExtent = "16 16"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "GuiOverlayProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; internalName = "Panel1"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiStackControl(OptionsMenuCategoryList) { - stackingType = "Vertical"; - horizStacking = "Left to Right"; - vertStacking = "Top to Bottom"; padding = "10"; dynamicSize = "0"; - dynamicNonStackExtent = "0"; - dynamicPos = "0"; - changeChildSizeToFit = "1"; - changeChildPosition = "1"; - position = "0 0"; extent = "248 555"; - minExtent = "16 16"; horizSizing = "width"; vertSizing = "height"; profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; class = "MenuList"; - canSave = "1"; - canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Display"; + extent = "248 35"; + profile = "GuiMenuButtonProfile"; + command = "populateDisplaySettingsList();"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiButtonCtrl() { + text = "Graphics"; + position = "0 45"; + extent = "248 35"; + profile = "GuiMenuButtonProfile"; + command = "populateGraphicsSettingsList();"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiButtonCtrl() { + text = "Audio"; + position = "0 90"; + extent = "248 35"; + profile = "GuiMenuButtonProfile"; + command = "populateAudioSettingsList();"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiButtonCtrl() { + text = "Keyboard & Mouse"; + position = "0 135"; + extent = "248 35"; + profile = "GuiMenuButtonProfile"; + command = "populateKeyboardMouseSettingsList();"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiButtonCtrl() { + text = "Gamepad"; + position = "0 180"; + extent = "248 35"; + profile = "GuiMenuButtonProfile"; + command = "populateGamepadSettingsList();"; + tooltipProfile = "GuiToolTipProfile"; + }; }; }; new GuiPanel() { docking = "Client"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "252 0"; extent = "676 555"; - minExtent = "16 16"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "GuiOverlayProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; internalName = "panel2"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiScrollCtrl() { - willFirstRespond = "1"; hScrollBar = "alwaysOff"; vScrollBar = "dynamic"; - lockHorizScroll = "0"; - lockVertScroll = "0"; - constantThumbHeight = "0"; - childMargin = "0 0"; - mouseWheelScrollSpeed = "-1"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "0 0"; extent = "676 554"; - minExtent = "8 2"; horizSizing = "width"; vertSizing = "height"; profile = "GuiMenuScrollProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiStackControl(OptionsMenuSettingsList) { - stackingType = "Vertical"; - horizStacking = "Left to Right"; - vertStacking = "Top to Bottom"; padding = "5"; - dynamicSize = "1"; - dynamicNonStackExtent = "0"; - dynamicPos = "0"; changeChildSizeToFit = "0"; - changeChildPosition = "1"; position = "1 1"; extent = "661 30"; - minExtent = "16 16"; horizSizing = "width"; vertSizing = "height"; profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; class = "MenuList"; - canSave = "1"; - canSaveDynamicFields = "0"; }; }; }; @@ -299,130 +163,67 @@ $guiContent = new GuiControl(OptionsMenu) { new GuiControl(OptionsButtonHolder) { position = "116 711"; extent = "791 40"; - minExtent = "8 2"; horizSizing = "center"; vertSizing = "top"; profile = "GuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; isContainer = "1"; class = "MenuInputButtonContainer"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiIconButtonCtrl() { - buttonMargin = "4 4"; - BitmapAsset = "UI:Keyboard_Black_Return_image"; - iconLocation = "Left"; - sizeIconToButton = "1"; - makeIconSquare = "1"; - textLocation = "Right"; - textMargin = "4"; - autoSize = "0"; - text = "Apply"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "507 0"; - extent = "140 40"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "OptionsMenu.apply();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "applyButton"; - class = "MenuInputButton"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiIconButtonCtrl() { - buttonMargin = "4 4"; - BitmapAsset = "UI:Keyboard_Black_Escape_image"; - iconLocation = "Left"; - sizeIconToButton = "1"; - makeIconSquare = "1"; - textLocation = "Right"; - textMargin = "4"; - autoSize = "0"; - text = "Back"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "651 0"; - extent = "140 40"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; - command = "OptionsMenu.backOut();"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "backButton"; - class = "MenuInputButton"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiIconButtonCtrl() { - buttonMargin = "4 4"; BitmapAsset = "UI:Keyboard_Black_R_image"; - iconLocation = "Left"; sizeIconToButton = "1"; makeIconSquare = "1"; textLocation = "Right"; - textMargin = "4"; - autoSize = "0"; text = "Reset"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "325 0"; + position = "173 0"; extent = "140 40"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "GuiMenuButtonProfile"; - visible = "1"; - active = "1"; command = "OptionsMenu.resetToDefaults();"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; internalName = "resetButton"; class = "MenuInputButton"; - canSave = "1"; - canSaveDynamicFields = "0"; + }; + new GuiIconButtonCtrl(OptionsMenuSelectButton) { + BitmapAsset = "UI:Keyboard_Black_Return_image"; + sizeIconToButton = "1"; + makeIconSquare = "1"; + textLocation = "Right"; + text = "Select"; + position = "507 0"; + extent = "140 40"; + profile = "GuiMenuButtonProfile"; + command = ""; + tooltipProfile = "GuiToolTipProfile"; + internalName = "SelectButton"; + class = "MenuInputButton"; + }; + new GuiIconButtonCtrl() { + BitmapAsset = "UI:Keyboard_Black_Escape_image"; + sizeIconToButton = "1"; + makeIconSquare = "1"; + textLocation = "Right"; + text = "Back"; + position = "651 0"; + extent = "140 40"; + profile = "GuiMenuButtonProfile"; + command = "OptionsMenu.backOut();"; + tooltipProfile = "GuiToolTipProfile"; + internalName = "backButton"; + class = "MenuInputButton"; }; }; new GuiInputCtrl(OptionsMenuInputHandler) { sendAxisEvents = "1"; sendBreakEvents = "1"; - sendModifierEvents = "0"; ignoreMouseEvents = "1"; - lockMouse = "0"; position = "-50 0"; extent = "10 10"; - minExtent = "8 2"; horizSizing = "left"; vertSizing = "top"; profile = "GuiInputCtrlProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; class = "MenuInputHandler"; - canSave = "1"; - canSaveDynamicFields = "0"; }; }; //--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript index 23a09236e..7f36bfc0d 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript @@ -55,9 +55,11 @@ function OptionsMenu::onAdd(%this) if(!isObject(%this.unappliedChanges)) { - %this.unappliedChanges = new ArrayObject(); + %this.unappliedChanges = new ArrayObject(OptionsMenuUnappliedChanges); } + %this.currentCategory = ""; + addOptionsMenuCategory("Display", "populateDisplaySettingsList();"); addOptionsMenuCategory("Graphics", "populateGraphicsSettingsList();"); addOptionsMenuCategory("Audio", "populateAudioSettingsList();"); @@ -121,12 +123,33 @@ function OptionsMenu::onWake(%this) function OptionsButtonHolder::onWake(%this) { %this-->resetButton.set("btn_back", "R", "Reset", "OptionsMenu.resetToDefaults();"); - %this-->applyButton.set("btn_start", "Return", "Apply", "OptionsMenu.apply();"); + %this-->selectButton.set("btn_a", "Return", "Select", "OptionsMenu.select();", true); %this-->backButton.set("btn_b", "Escape", "Back", "OptionsMenu.backOut();"); //OptionsMenuCategoryList.getObject(0).performClick(); } +function OptionsMenu::select(%this) +{ + if(OptionsMenuCategoryList.isActiveMenuList()) + { + OptionsMenuSettingsList.setAsActiveMenuList(); + %this.updateSelectButton(); + } +} + +function OptionsMenu::updateSelectButton(%this) +{ + if(OptionsMenuCategoryList.isActiveMenuList()) + { + %this-->selectButton.setHidden(false); + } + else if(OptionsMenuSettingsList.isActiveMenuList()) + { + %this-->selectButton.setHidden(true); + } +} + function OptionsMenu::apply(%this) { //Now we run through our list of unapplied changes and... apply them. @@ -137,7 +160,7 @@ function OptionsMenu::apply(%this) for(%i=0; %i < %this.unappliedChanges.count(); %i++) { %targetVar = %this.unappliedChanges.getKey(%i); - %newValue = %this.unappliedChanges.getValue(%i); + %newValue = strReplace(%this.unappliedChanges.getValue(%i), "\"", ""); //First, lets just check through our action map names, see if any match %wasKeybind = false; @@ -245,6 +268,9 @@ function OptionsMenu::apply(%this) export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false); OptionsMenu.unappliedChanges.empty(); + + //Now we can back out of the options menu + OptionsMenu.doOptionsMenuBackOut(); } function OptionsMenu::resetToDefaults(%this) @@ -252,6 +278,40 @@ function OptionsMenu::resetToDefaults(%this) MessageBoxOKCancel("", "This will set the graphical settings back to the auto-detected defaults. Do you wish to continue?", "AutodetectGraphics();", ""); } +function OptionsMenu::refresh(%this) +{ + if(%this.currentCategory !$= "") + { + %category = %this.optionsCategories.getKey(%this.currentCategory); + %command = %this.optionsCategories.getValue(%this.currentCategory); + eval(%command); + } +} + +function OptionsMenu::getOptionVariableValue(%this, %variableName) +{ + %unappliedPrefIndex = %this.unappliedChanges.getIndexFromKey(%variableName); + if(%unappliedPrefIndex != -1) + { + %value = %this.unappliedChanges.getValue(%unappliedPrefIndex); + return strreplace(%value, "\"", ""); + } + + return getVariable(%variableName); +} + +function OptionsMenuSelectButton::onVisible(%this, %state) +{ + //We're sorta cheating here. + //This button should only be displayed when we're in the categories list + //so whenever the status changes, such as automatically refreshing due to + //navigation events, we'll just do a quick check to ensure we're + //in the right visibility mode + if(%state && OptionsMenuSettingsList.isActiveMenuList()) + { + %this.setHidden(true); + } +} // // // @@ -308,17 +368,16 @@ function populateDisplaySettingsList() else OptionsMenuSettingsList.setRowEnabled(1, false); - %mode = getField($Video::ModeTags, $pref::Video::deviceMode); + %mode = OptionsMenu.getOptionVariableValue("$pref::Video::deviceMode"); + if(isInt(%mode)) + %mode = getField($Video::ModeTags, $pref::Video::deviceMode); OptionsMenuSettingsList.addOptionRow("Window Mode", "$pref::Video::deviceMode", $Video::ModeTags, false, "", true, "", %mode); - %resolutionList = getScreenResolutionList($pref::Video::deviceId, $pref::Video::deviceMode); - OptionsMenuSettingsList.addOptionRow("Resolution", "$pref::Video::Resolution", %resolutionList, false, "onDisplayResChange", true, "Resolution of the game window", _makePrettyResString( $pref::Video::mode )); - - //If they're doing borderless, the window resolution must match the display resolution if(%mode !$= "Borderless") - OptionsMenuSettingsList.setRowEnabled(3, true); - else - OptionsMenuSettingsList.setRowEnabled(3, false); + { + %resolutionList = getScreenResolutionList($pref::Video::deviceId, $pref::Video::deviceMode); + OptionsMenuSettingsList.addOptionRow("Resolution", "$pref::Video::Resolution", %resolutionList, false, "", true, "Resolution of the game window", _makePrettyResString( $pref::Video::mode )); + } OptionsMenuSettingsList.addOptionRow("VSync", "$pref::Video::disableVerticalSync", "No\tYes", false, "", true, "", convertBoolToYesNo(!$pref::Video::disableVerticalSync)); @@ -333,27 +392,6 @@ function populateDisplaySettingsList() OptionsMenuSettingsList.addSliderRow("Contrast", "", 0.5, 0.1, "0 1", ""); } -/*function OptionsMenu::applyDisplaySettings(%this) -{ - %newDevice = OptionsMenuSettingsList.getCurrentOption(0); - - // Change the device. - if ( %newDevice !$= $pref::Video::displayDevice ) - { - $pref::Video::displayDevice = %newDevice; - if( %newDevice !$= getDisplayDeviceInformation() ) - MessageBoxOK( "Change requires restart", "Please restart the game for a display device change to take effect." ); - - $changingDisplayDevice = %newDevice; - } - - updateDisplaySettings(); - - echo("Exporting client prefs"); - %prefPath = getPrefpath(); - export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false); -}*/ - // // // @@ -394,6 +432,20 @@ function updateDisplaySettings() //Update the display settings now %deviceName = getDisplayDeviceName(); %newDeviceID = getWord(%deviceName, 0) - 1; + + if(!isInt($pref::Video::deviceMode)) + { + //probably saved out as the mode name, so just translate it back + for(%i=0; %i < getFieldCount($Video::ModeTags); %i++) + { + if(getField($Video::ModeTags, %i) $= $pref::Video::deviceMode) + { + $pref::Video::deviceMode = %i; + break; + } + } + } + %deviceModeName = getField($Video::ModeTags, $pref::Video::deviceMode); %newDeviceMode = 0; foreach$(%modeName in $Video::ModeTags) @@ -403,6 +455,14 @@ function updateDisplaySettings() else %newDeviceMode++; } + + if($pref::Video::deviceMode == $Video::ModeBorderless) + { + //if we're changing to borderless, we swap to the full resolution of the desktop + $pref::Video::mode = Canvas.getBestCanvasRes($pref::Video::deviceId, $pref::Video::deviceMode); + + $pref::Video::Resolution = $pref::Video::mode.x SPC $pref::Video::mode.y; + } %newRes = $pref::Video::Resolution; %newBpp = 32; // ... its not 1997 anymore. @@ -448,7 +508,7 @@ function updateDisplaySettings() function updatePostFXSettings() { PostFXManager.settingsEffectSetEnabled(SSAOPostFx, $pref::PostFX::EnableSSAO); - PostFXManager.settingsEffectSetEnabled(DOFPostEffect, $pref::PostFX::EnableDOF); + PostFXManager.settingsEffectSetEnabled(DepthOfFieldPostFX, $pref::PostFX::EnableDOF); PostFXManager.settingsEffectSetEnabled(LightRayPostFX, $pref::PostFX::EnableLightRays); PostFXManager.settingsEffectSetEnabled(vignettePostFX, $pref::PostFX::EnableVignette); } @@ -583,13 +643,21 @@ function OptionsMenuList::activateRow(%this) function OptionsMenu::backOut(%this) { - if(%this.unappliedChanges.count() != 0) + if(OptionsMenuSettingsList.isActiveMenuList()) { - MessageBoxOKCancel("Discard Changes?", "You have unapplied changes to your settings, do you wish to continue?", "OptionsMenu.doOptionsMenuBackOut();", ""); + OptionsMenuCategoryList.setAsActiveMenuList(); + %this.updateSelectButton(); } else { - %this.doOptionsMenuBackOut(); + if(%this.unappliedChanges.count() != 0) + { + MessageBoxOKCancel("Discard Changes?", "You have unapplied changes to your settings, do you wish to apply or discard them?", "OptionsMenu.apply();", "OptionsMenu.doOptionsMenuBackOut();", "Apply", "Discard"); + } + else + { + %this.doOptionsMenuBackOut(); + } } } @@ -630,7 +698,7 @@ function OptionsMenuSettingsList::addOptionRow(%this, %label, %targetPrefVar, %o %enabled = true; %optionsRowSize = 30; - %optionColumnWidth = %this.extent.x - 450;//todo, calculate off longest option text? + %optionColumnWidth = %this.extent.x * 0.3;//todo, calculate off longest option text? %option = new GuiGameSettingsCtrl() { class = "MenuOptionsButton"; @@ -723,6 +791,7 @@ function OptionsMenuSettingsList::addKeybindRow(%this, %label, %bitmapName, %cal // function OptionsMenuCategoryList::onNavigate(%this, %index) { + OptionsMenu.currentCategory = %index; %this.getObject(%index).performClick(); } @@ -750,83 +819,6 @@ function convertBoolToOnOff(%val) return "Off"; } -function onDisplayModeChange(%val) -{ - // The display device (monitor) or screen mode has changed. Refill the - // resolution list with only available options. - %deviceName = OptionsMenuSettingsList.getCurrentOption(1); - %newDeviceID = getWord(%deviceName, 0) - 1; - %deviceModeName = OptionsMenuSettingsList.getCurrentOption(2); - %newDeviceMode = 0; - foreach$(%modeName in $Video::ModeTags) - { - if (%deviceModeName $= %modeName) - break; - else - %newDeviceMode++; - } - %resolutionList = getScreenResolutionList(%newDeviceID, %newDeviceMode); - - if (%newDeviceMode == $Video::ModeBorderless) - { // If we're switching to borderless, default to monitor res on Windows OS, - // monitor usable area for other platforms. - if ($platform $= "windows") - %newRes = getWords(Canvas.getMonitorRect(%newDeviceID), 2); - else - %newRes = getWords(Canvas.getMonitorUsableRect(%newDeviceID), 2); - } - else - { // Otherwise, if our old resolution is still in the list, attempt to reset it. - %oldRes = getWord(OptionsMenuSettingsList.getCurrentOption(3), 0) SPC getWord(OptionsMenuSettingsList.getCurrentOption(3), 2); - - %found = false; - %retCount = getFieldCount(%resolutionList); - for (%i = 0; %i < %retCount; %i++) - { - %existingEntry = getField(%resolutionList, %i); - if ((%existingEntry.x $= %oldRes.x) && (%existingEntry.z $= %oldRes.y)) - { - %found = true; - %newRes = %oldRes; - break; - } - } - - if (!%found) - { // Pick the best resoltion available for the device and mode - %newRes = Canvas.getBestCanvasRes(%newDeviceID, %newDeviceMode); - } - } - - if(%newDeviceMode == $Video::ModeBorderless) - OptionsMenuSettingsList.setRowEnabled(3, false); - else - OptionsMenuSettingsList.setRowEnabled(3, true); - - OptionsMenuSettingsList.setOptions(3, %resolutionList); - OptionsMenuSettingsList.selectOption(3, _makePrettyResString(%newRes)); -} - -function onDisplayResChange(%val) -{ // The resolution has changed. Setup refresh rates available at this res. - %newRes = getWord(OptionsMenuSettingsList.getCurrentOption(3), 0) SPC getWord(OptionsMenuSettingsList.getCurrentOption(3), 2); - %refreshList = getScreenRefreshList(%newRes); - - // If our old rate still exists, select it - %oldRate = OptionsMenuSettingsList.getCurrentOption(5); - %retCount = getFieldCount(%refreshList); - for (%i = 0; %i < %retCount; %i++) - { - %existingEntry = getField(%refreshList, %i); - %newRate = %existingEntry; - if (%existingEntry $= %oldRate) - break; - } - - OptionsMenuSettingsList.setOptions(5, %refreshList); - OptionsMenuSettingsList.selectOption(5, %newRate); -} - function getDisplayDeviceName() { %numDevices = Canvas.getMonitorCount(); @@ -880,10 +872,16 @@ function MenuOptionsButton::onChange(%this) %prefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetVar); if(%prefIndex == -1) - OptionsMenu.unappliedChanges.add(%targetVar, %saveReadyValue); + { + echo("Setting UnappliedChanges via add: key:" @ %targetVar @", value: " @ %saveReadyValue); + OptionsMenu.unappliedChanges.add(%targetVar, "\"" @ %saveReadyValue @ "\"" ); + } else - OptionsMenu.unappliedChanges.setValue(%saveReadyValue, %prefIndex); + OptionsMenu.unappliedChanges.setValue("\"" @ %saveReadyValue @ "\"", %prefIndex); } + + //Update the UI in case there's responsive logic + schedule(32, OptionsMenu, "refresh"); } function OptionsMenu::onKeybindChanged(%this, %actionMap, %keybind) diff --git a/Templates/BaseGame/game/data/UI/images/groupborder.png b/Templates/BaseGame/game/data/UI/images/group_border.png similarity index 100% rename from Templates/BaseGame/game/data/UI/images/groupborder.png rename to Templates/BaseGame/game/data/UI/images/group_border.png diff --git a/Templates/BaseGame/game/data/UI/images/group_border_image.asset.taml b/Templates/BaseGame/game/data/UI/images/group_border_image.asset.taml index 9b2972e84..47e0228bb 100644 --- a/Templates/BaseGame/game/data/UI/images/group_border_image.asset.taml +++ b/Templates/BaseGame/game/data/UI/images/group_border_image.asset.taml @@ -2,7 +2,7 @@ canSave="true" canSaveDynamicFields="true" AssetName="group_border_image" - imageFile="@assetFile=group-border.png" + imageFile="@assetFile=group_border.png" UseMips="true" isHDRImage="false" imageType="Albedo" /> diff --git a/Templates/BaseGame/game/data/UI/images/nopreview.png b/Templates/BaseGame/game/data/UI/images/no_preview.png similarity index 100% rename from Templates/BaseGame/game/data/UI/images/nopreview.png rename to Templates/BaseGame/game/data/UI/images/no_preview.png diff --git a/Templates/BaseGame/game/data/UI/images/no_preview_image.asset.taml b/Templates/BaseGame/game/data/UI/images/no_preview_image.asset.taml index 1546088dc..56778b0f1 100644 --- a/Templates/BaseGame/game/data/UI/images/no_preview_image.asset.taml +++ b/Templates/BaseGame/game/data/UI/images/no_preview_image.asset.taml @@ -2,7 +2,7 @@ canSave="true" canSaveDynamicFields="true" AssetName="no_preview_image" - imageFile="@assetFile=no-preview.png" + imageFile="@assetFile=no_preview.png" UseMips="true" isHDRImage="false" imageType="Albedo" /> diff --git a/Templates/BaseGame/game/data/UI/images/nopreview_image.asset.taml b/Templates/BaseGame/game/data/UI/images/nopreview_image.asset.taml deleted file mode 100644 index cda718e30..000000000 --- a/Templates/BaseGame/game/data/UI/images/nopreview_image.asset.taml +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/Templates/BaseGame/game/data/UI/images/selectorbutton.png b/Templates/BaseGame/game/data/UI/images/selector_button.png similarity index 100% rename from Templates/BaseGame/game/data/UI/images/selectorbutton.png rename to Templates/BaseGame/game/data/UI/images/selector_button.png diff --git a/Templates/BaseGame/game/data/UI/images/selectorbuttonblank.png b/Templates/BaseGame/game/data/UI/images/selector_button_blank.png similarity index 100% rename from Templates/BaseGame/game/data/UI/images/selectorbuttonblank.png rename to Templates/BaseGame/game/data/UI/images/selector_button_blank.png diff --git a/Templates/BaseGame/game/data/UI/images/selector_button_blank_image.asset.taml b/Templates/BaseGame/game/data/UI/images/selector_button_blank_image.asset.taml index 058b3d4c4..0306109e8 100644 --- a/Templates/BaseGame/game/data/UI/images/selector_button_blank_image.asset.taml +++ b/Templates/BaseGame/game/data/UI/images/selector_button_blank_image.asset.taml @@ -2,7 +2,7 @@ canSave="true" canSaveDynamicFields="true" AssetName="selector_button_blank_image" - imageFile="@assetFile=selector-button-blank.png" + imageFile="@assetFile=selector_button_blank.png" UseMips="true" isHDRImage="false" imageType="Albedo" /> diff --git a/Templates/BaseGame/game/data/UI/images/selectorbuttondark.png b/Templates/BaseGame/game/data/UI/images/selector_button_dark.png similarity index 100% rename from Templates/BaseGame/game/data/UI/images/selectorbuttondark.png rename to Templates/BaseGame/game/data/UI/images/selector_button_dark.png diff --git a/Templates/BaseGame/game/data/UI/images/selector_button_dark_image.asset.taml b/Templates/BaseGame/game/data/UI/images/selector_button_dark_image.asset.taml index a669fe5d6..06a05c86a 100644 --- a/Templates/BaseGame/game/data/UI/images/selector_button_dark_image.asset.taml +++ b/Templates/BaseGame/game/data/UI/images/selector_button_dark_image.asset.taml @@ -2,7 +2,7 @@ canSave="true" canSaveDynamicFields="true" AssetName="selector_button_dark_image" - imageFile="@assetFile=selector-button-dark.png" + imageFile="@assetFile=selector_button_dark.png" UseMips="true" isHDRImage="false" imageType="Albedo" /> diff --git a/Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly.png b/Templates/BaseGame/game/data/UI/images/selector_button_highlight_only.png similarity index 100% rename from Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly.png rename to Templates/BaseGame/game/data/UI/images/selector_button_highlight_only.png diff --git a/Templates/BaseGame/game/data/UI/images/selector_button_highlight_only_image.asset.taml b/Templates/BaseGame/game/data/UI/images/selector_button_highlight_only_image.asset.taml index 96c16617a..b3ad92ca2 100644 --- a/Templates/BaseGame/game/data/UI/images/selector_button_highlight_only_image.asset.taml +++ b/Templates/BaseGame/game/data/UI/images/selector_button_highlight_only_image.asset.taml @@ -2,7 +2,7 @@ canSave="true" canSaveDynamicFields="true" AssetName="selector_button_highlight_only_image" - imageFile="@assetFile=selector-button-highlight-only.png" + imageFile="@assetFile=selector_button_highlight_only.png" UseMips="true" isHDRImage="false" imageType="Albedo" /> diff --git a/Templates/BaseGame/game/data/UI/images/selector_button_image.asset.taml b/Templates/BaseGame/game/data/UI/images/selector_button_image.asset.taml index ffe4338e5..2ddcbb752 100644 --- a/Templates/BaseGame/game/data/UI/images/selector_button_image.asset.taml +++ b/Templates/BaseGame/game/data/UI/images/selector_button_image.asset.taml @@ -2,7 +2,7 @@ canSave="true" canSaveDynamicFields="true" AssetName="selector_button_image" - imageFile="@assetFile=selector-button.png" + imageFile="@assetFile=selector_button.png" UseMips="true" isHDRImage="false" imageType="Albedo" /> diff --git a/Templates/BaseGame/game/data/UI/images/selectorbutton_image.asset.taml b/Templates/BaseGame/game/data/UI/images/selectorbutton_image.asset.taml deleted file mode 100644 index f53884267..000000000 --- a/Templates/BaseGame/game/data/UI/images/selectorbutton_image.asset.taml +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/Templates/BaseGame/game/data/UI/images/selectorbuttonblank_image.asset.taml b/Templates/BaseGame/game/data/UI/images/selectorbuttonblank_image.asset.taml deleted file mode 100644 index c3f212a24..000000000 --- a/Templates/BaseGame/game/data/UI/images/selectorbuttonblank_image.asset.taml +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/Templates/BaseGame/game/data/UI/images/selectorbuttondark_image.asset.taml b/Templates/BaseGame/game/data/UI/images/selectorbuttondark_image.asset.taml deleted file mode 100644 index 4a24af201..000000000 --- a/Templates/BaseGame/game/data/UI/images/selectorbuttondark_image.asset.taml +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly_image.asset.taml b/Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly_image.asset.taml deleted file mode 100644 index e359450c4..000000000 --- a/Templates/BaseGame/game/data/UI/images/selectorbuttonhighlightonly_image.asset.taml +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/Templates/BaseGame/game/data/UI/images/tabborder.png b/Templates/BaseGame/game/data/UI/images/tab_border.png similarity index 100% rename from Templates/BaseGame/game/data/UI/images/tabborder.png rename to Templates/BaseGame/game/data/UI/images/tab_border.png diff --git a/Templates/BaseGame/game/data/UI/images/tab_border_image.asset.taml b/Templates/BaseGame/game/data/UI/images/tab_border_image.asset.taml index 9d4db0d2d..c5f250a2d 100644 --- a/Templates/BaseGame/game/data/UI/images/tab_border_image.asset.taml +++ b/Templates/BaseGame/game/data/UI/images/tab_border_image.asset.taml @@ -2,7 +2,7 @@ canSave="true" canSaveDynamicFields="true" AssetName="tab_border_image" - imageFile="@assetFile=tab-border.png" + imageFile="@assetFile=tab_border.png" UseMips="true" isHDRImage="false" imageType="Albedo" /> diff --git a/Templates/BaseGame/game/data/UI/images/tabborder_image.asset.taml b/Templates/BaseGame/game/data/UI/images/tabborder_image.asset.taml deleted file mode 100644 index 0e3102520..000000000 --- a/Templates/BaseGame/game/data/UI/images/tabborder_image.asset.taml +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/Templates/BaseGame/game/data/UI/scripts/menuInputHandling.tscript b/Templates/BaseGame/game/data/UI/scripts/menuInputHandling.tscript index 074bb3675..66d6aaf39 100644 --- a/Templates/BaseGame/game/data/UI/scripts/menuInputHandling.tscript +++ b/Templates/BaseGame/game/data/UI/scripts/menuInputHandling.tscript @@ -412,6 +412,13 @@ function MenuInputHandler::onInputEvent(%this, %device, %action, %state) // Menu List processing // These functions manage the navigation and activation of the Menu Lists //============================================================================== +function MenuList::isActiveMenuList(%this) +{ + if($activeMenuList == %this) + return true; + + return false; +} function MenuList::setAsActiveMenuList(%this, %startPosition, %menuMode) { @@ -485,8 +492,6 @@ function MenuList::navigateDown(%this) function MenuList::navigateLeft() { - echo("Menu list navigated left!"); - //Atm, we're only handling specific control types, namely options entries, but //this could readily be expanded upon to handle grids like for inventory screens //or the like @@ -494,17 +499,54 @@ function MenuList::navigateLeft() %btn = $activeMenuList.getObject($activeMenuListPosition.y); if(%btn.getClassName() $= "GuiGameSettingsCtrl" && %btn.isEnabled()) { - warnf("MenuList::navigateLeft() - actioned the option" @ %btn @ " to the left"); + %mode = %btn.getMode(); + if(%mode == 0) //options list + { + %optionId = %btn.getCurrentOptionIndex() - 1; + %btn.selectOptionByIndex(%optionId); + %btn.onChange(); + } + else if(%mode == 1) //slider + { + %value = %btn.getValue(); + %adjustedValue = %value - %btn.getIncrement(); + %minValue = %btn.getRange().x; + if(%adjustedValue < %minValue) + %adjustedValue = %minValue; + + %btn.setValue(%adjustedValue); + %btn.onChange(); + } } } function MenuList::navigateRight() { - echo("Menu list navigated right!"); - %btn = $activeMenuList.getObject($activeMenuListPosition.y); if(%btn.getClassName() $= "GuiGameSettingsCtrl" && %btn.isEnabled()) { - warnf("MenuList::navigateLeft() - actioned the option" @ %btn @ " to the left"); + %mode = %btn.getMode(); + if(%mode == 0) //options list + { + %optionId = %btn.getCurrentOptionIndex() + 1; + %btn.selectOptionByIndex(%optionId); + %btn.onChange(); + } + else if(%mode == 1) //slider + { + %value = %btn.getValue(); + %adjustedValue = %value + %btn.getIncrement(); + %maxValue = %btn.getRange().y; + if(%adjustedValue > %maxValue) + %adjustedValue = %maxValue; + + %btn.setValue(%adjustedValue); + %btn.onChange(); + } } } + +function MenuList::getActiveRow(%this) +{ + return $activeMenuListPosition.y; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/UI/scripts/messageBoxes.tscript b/Templates/BaseGame/game/data/UI/scripts/messageBoxes.tscript index 403463695..f1c3db40e 100644 --- a/Templates/BaseGame/game/data/UI/scripts/messageBoxes.tscript +++ b/Templates/BaseGame/game/data/UI/scripts/messageBoxes.tscript @@ -116,7 +116,7 @@ function MessageBoxOKDlg::onSleep( %this ) MessageBoxCtrl.originalMenuInputContainer.setActive(); } -function MessageBoxOKCancel(%title, %message, %callback, %cancelCallback) +function MessageBoxOKCancel(%title, %message, %callback, %cancelCallback, %okLabelOverride, %cancelLabelOverride) { Canvas.pushDialog(MessageBoxDlg); MessageBoxTitleText.text = %title; @@ -125,8 +125,18 @@ function MessageBoxOKCancel(%title, %message, %callback, %cancelCallback) MessageBoxYNCButtonHolder.hidden = true; MessageBoxOKButtonHolder.hidden = true; - MessageBoxOCButtonHolder-->OKButton.set("btn_a", "Return", "OK", "MessageCallback(MessageBoxDlg,MessageBoxDlg.callback);"); - MessageBoxOCButtonHolder-->CancelButton.set("btn_b", "Escape", "Cancel", "MessageCallback(MessageBoxDlg,MessageBoxDlg.cancelCallback);"); + if(%okLabelOverride $= "") + %okLabel = "OK"; + else + %okLabel = %okLabelOverride; + + if(%cancelLabelOverride $= "") + %cancelLabel = "Cancel"; + else + %cancelLabel = %cancelLabelOverride; + + MessageBoxOCButtonHolder-->OKButton.set("btn_a", "Return", %okLabel, "MessageCallback(MessageBoxDlg,MessageBoxDlg.callback);"); + MessageBoxOCButtonHolder-->CancelButton.set("btn_b", "Escape", %cancelLabel, "MessageCallback(MessageBoxDlg,MessageBoxDlg.cancelCallback);"); MessageBoxCtrl.originalMenuInputContainer = $activeMenuButtonContainer; MessageBoxOCButtonHolder.setActive(); diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui index e03d27ecb..29c282c5b 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui @@ -1089,7 +1089,7 @@ $guiContent = new GuiControl(AssetBrowser) { position = "5 588"; extent = "20 20"; minExtent = "8 2"; - horizSizing = "left"; + horizSizing = "right"; vertSizing = "top"; profile = "ToolsGuiDefaultProfile"; visible = "1"; @@ -1124,13 +1124,14 @@ $guiContent = new GuiControl(AssetBrowser) { class = "assetBrowserPreviewSlider"; canSave = "1"; canSaveDynamicFields = "0"; + command = "AssetBrowser-->previewSlider.onMouseDragged();"; }; new GuiBitmapCtrl() { bitmapAsset = "ToolsModule:larger_image"; position = "103 588"; extent = "20 20"; minExtent = "8 2"; - horizSizing = "left"; + horizSizing = "right"; vertSizing = "top"; profile = "ToolsGuiDefaultProfile"; visible = "1"; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/addModuleWindow.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/addModuleWindow.tscript index ff085835b..2b38b7459 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/addModuleWindow.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/addModuleWindow.tscript @@ -127,6 +127,8 @@ function AssetBrowserModuleList::refresh(%this) %moduleName = %moduleDef.ModuleId; %this.add(%moduleName, %i); } + + %this.sort(); } function AssetBrowserSelModuleAddBtn::onClick(%this) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index 7d0c1e3da..fd71cba2f 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript @@ -360,6 +360,13 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) { %this.previewData = new ScriptObject(); } + else + { + %this.previewData.tooltip = ""; + %this.previewData.assetName = ""; + %this.previewData.previewImage = ""; + %this.previewData.doubleClickCommand = ""; + } AssetPreviewArray.empty(); @@ -493,8 +500,6 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) %tooltip = %assetName; - %doubleClickCommand = "AssetBrowser.editAsset( "@%assetDesc@" );"; - %textBottomPad = 20; %previewButton = new GuiIconButtonCtrl() @@ -535,6 +540,15 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) %previewButton.moduleName = %moduleName; %previewButton.assetType = %assetType; + if(%this.selectMode) + { + %doubleClickCommand = "AssetBrowser.selectAsset( AssetBrowser.selectedAsset );"; + } + else + { + %doubleClickCommand = "AssetBrowser.editAsset( "@%assetDesc@" );"; + } + //Build out the preview %buildCommand = %this @ ".build" @ %assetType @ "Preview(\"" @ %assetDesc @ "\"," @ %this.previewData @ ");"; eval(%buildCommand); @@ -543,7 +557,9 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) %tooltip = %this.previewData.tooltip; %assetName = %this.previewData.assetName; %previewImage = %this.previewData.previewImage; - %doubleClickCommand = %this.previewData.doubleClickCommand; + + if(%this.previewData.doubleClickCommand !$= "") + %doubleClickCommand = %this.previewData.doubleClickCommand; %previewButton.assetName = %assetName; %previewButton.moduleName = %moduleName; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index 880ff115e..53d102324 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript @@ -507,6 +507,11 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) "\nAsset Type: Material Asset" @ "\nAsset Definition ID: " @ %assetDef @ "\nDefinition Path: " @ %assetDef.getScriptPath(); + + if(!%this.selectMode) + { + %previewData.doubleClickCommand = "AssetBrowser.editAsset( "@%assetDef@" );"; + } } function AssetBrowser::onMaterialAssetEditorDropped(%this, %assetDef, %position) diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditor.tscript b/Templates/BaseGame/game/tools/convexEditor/convexEditor.tscript index deb211fbf..679b3a29d 100644 --- a/Templates/BaseGame/game/tools/convexEditor/convexEditor.tscript +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditor.tscript @@ -27,20 +27,3 @@ singleton GuiControlProfile( ConvexEditorProfile ) fillColor = "192 192 192 192"; category = "Editor"; }; - -singleton GuiControlProfile (GuiDisabledTextEditProfile) -{ - opaque = false; - border = 0; - bitmap = "./textEdit"; - borderColor = "255 255 255 200"; - fontColor = "0 0 0"; - fontColorHL = "255 255 255"; - fontColorNA = "128 128 128"; - textOffset = "4 2"; - autoSizeWidth = false; - autoSizeHeight = false; - tab = false; - canKeyFocus = false; - category = "Editor"; -}; diff --git a/Templates/BaseGame/game/tools/gui/profiles.ed.tscript b/Templates/BaseGame/game/tools/gui/profiles.ed.tscript index 2b2cec671..65d068e8a 100644 --- a/Templates/BaseGame/game/tools/gui/profiles.ed.tscript +++ b/Templates/BaseGame/game/tools/gui/profiles.ed.tscript @@ -39,7 +39,7 @@ new GuiControlProfile (ToolsGuiDefaultProfile) // fill color opaque = false; fillColor = EditorSettings.value("Theme/tabsColor"); - fillColorHL = EditorSettings.value("Theme/tabsGLColor"); + fillColorHL = EditorSettings.value("Theme/tabsHLColor"); fillColorSEL = EditorSettings.value("Theme/tabsSELColor"); fillColorNA = EditorSettings.value("Theme/tabsSELColor"); @@ -355,7 +355,7 @@ new GuiControlProfile( ToolsGuiButtonProfile ) opaque = true; border = true; fillColor = EditorSettings.value("Theme/tabsColor"); - fillColorHL = EditorSettings.value("Theme/tabsGLColor"); + fillColorHL = EditorSettings.value("Theme/tabsHLColor"); fillColorSEL = EditorSettings.value("Theme/tabsSELColor"); fillColorNA = EditorSettings.value("Theme/tabsSELColor"); @@ -1238,3 +1238,20 @@ singleton GuiControlProfile (GuiSimpleBorderProfile) border = 1; category = "Editor"; }; + +singleton GuiControlProfile (GuiDisabledTextEditProfile) +{ + opaque = false; + border = 0; + bitmapAsset = "ToolsModule:textEdit_image"; + borderColor = "255 255 255 200"; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fontColorNA = "128 128 128"; + textOffset = "4 2"; + autoSizeWidth = false; + autoSizeHeight = false; + tab = false; + canKeyFocus = false; + category = "Editor"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditor.tscript b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditor.tscript index eee393d87..20561099f 100644 --- a/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditor.tscript +++ b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditor.tscript @@ -26,21 +26,4 @@ singleton GuiControlProfile( MeshRoadEditorProfile ) opaque = true; fillColor = "192 192 192 192"; category = "Editor"; -}; - -singleton GuiControlProfile (GuiDisabledTextEditProfile) -{ - opaque = false; - border = 0; - bitmap = "./textEdit"; - borderColor = "255 255 255 200"; - fontColor = "0 0 0"; - fontColorHL = "255 255 255"; - fontColorNA = "128 128 128"; - textOffset = "4 2"; - autoSizeWidth = false; - autoSizeHeight = false; - tab = false; - canKeyFocus = false; - category = "Editor"; }; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/settings.xml b/Templates/BaseGame/game/tools/settings.xml index b7103a680..08b21038a 100644 --- a/Templates/BaseGame/game/tools/settings.xml +++ b/Templates/BaseGame/game/tools/settings.xml @@ -38,6 +38,8 @@ name="AutoImport">0 + Edit Asset 1 0 1 - FPSGameplay:EmptyLevel 4.60158 1 - FPSGameplay:EmptyLevel,FPSGameplay:EmptyTerrain,pbr:PbrMatTestLevel,TTR:DasBootLevel Blank Level Date: Sun, 27 Mar 2022 03:05:48 -0500 Subject: [PATCH 058/145] Added sanity check to ensure that the requested file to be scaled via saveScaledImage actually exists Shifts integration of other modules with the OptionsMenu so other modules can inject their own options categories to a callOnModules hook Updated ExampleModule to use new options menu integration angle to show example option Deleted unneeded dropdown_textEdit_image asset def from baseUI Fixed incorrect internal values for the terrainIcon_image asset def that made it present as a redundant terrain material asset Cleaned up old, bad loadFilters calls and replaced them with the proper refresh() calls. Removed old, bad calls for jumping through the asset browser's tree from when it was still hardcoded organization, which cuts down a lot of error spam Cleaned up some of the asset type's preview image assignment code to be more reliable Made terrain materials now use a similar preview proxy shape as regular materials Fixed erroneous duplicate GuiInspectorTypeShapeAssetPtr::onControlDropped, which was breaking drag-n-drop actions of shapeAssets into inspector fields Added proper logic for drag-n-drop actions of imageAssets into inspector fields Add sanity check after creating new asset to avoid redundant attempts at initialization of the new asset Fixed ConvexShape Editor tooling so you can now use the UI to apply the selected material to the selected surface Added tools menu to the menubar with the Project Importer entry so the PI can be launched from either tool Implemented ability to drag-n-drop imageAssets onto MaterialEditor map fields and have it work Implemented ability to drag-n-drop imageAssets onto TerrainMaterial Editor map fields and have it work Made the TerrainMaterial editor dialogue have a non-modal background so you can interact with the editor as normal while it's up Add sanity check to avoid attempting to mark EditorTree items if we couldn't find it's id renamed BaseMap references in terrain material editor to diffuseMap for consistency --- Engine/source/gfx/bitmap/gBitmap.cpp | 5 ++ .../worldEditor/guiConvexShapeEditorCtrl.cpp | 2 +- .../data/ExampleModule/ExampleModule.tscript | 11 ++- .../game/data/UI/guis/optionsMenu.tscript | 7 +- .../images/dropdown_textEdit_image.asset.taml | 8 -- .../art/terrainIcon_image.asset.taml | 4 +- .../assetBrowser/scripts/assetBrowser.tscript | 8 +- .../scripts/assetTypes/component.tscript | 7 +- .../scripts/assetTypes/cubemap.tscript | 7 +- .../scripts/assetTypes/gameObject.tscript | 13 +-- .../scripts/assetTypes/gui.tscript | 7 +- .../scripts/assetTypes/image.tscript | 19 ++++- .../scripts/assetTypes/level.tscript | 5 -- .../scripts/assetTypes/material.tscript | 23 +++--- .../scripts/assetTypes/shape.tscript | 17 ++-- .../scripts/assetTypes/sound.tscript | 2 +- .../scripts/assetTypes/stateMachine.tscript | 20 +---- .../assetTypes/terrainMaterial.tscript | 74 ++++++++++++++++- .../assetBrowser/scripts/editAsset.tscript | 4 +- .../assetBrowser/scripts/newAsset.tscript | 13 +-- .../convexEditor/convexEditorGui.tscript | 2 +- .../scripts/guiEditorCanvas.ed.tscript | 9 ++ .../gui/guiMaterialPropertiesWindow.ed.gui | 13 +++ .../scripts/materialEditor.ed.tscript | 82 ++++++++++++++++++- .../gui/guiTerrainMaterialDlg.ed.gui | 12 +-- .../worldEditor/scripts/EditorGui.ed.tscript | 6 +- .../interfaces/terrainMaterialDlg.ed.tscript | 58 +++++++++++-- 27 files changed, 311 insertions(+), 127 deletions(-) delete mode 100644 Templates/BaseGame/game/data/UI/images/dropdown_textEdit_image.asset.taml diff --git a/Engine/source/gfx/bitmap/gBitmap.cpp b/Engine/source/gfx/bitmap/gBitmap.cpp index ebd3741b1..21e1351f8 100644 --- a/Engine/source/gfx/bitmap/gBitmap.cpp +++ b/Engine/source/gfx/bitmap/gBitmap.cpp @@ -1373,6 +1373,11 @@ DefineEngineFunction(saveScaledImage, bool, (const char* bitmapSource, const cha return false; } + if (!Platform::isFile(bitmapSource)) + { + return false; + } + //First, gotta check the extension, as we have some extra work to do if it's //a DDS file const char* ret = dStrrchr(bitmapSource, '.'); diff --git a/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.cpp b/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.cpp index 9350f39e0..ae1b90df8 100644 --- a/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.cpp +++ b/Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.cpp @@ -204,7 +204,7 @@ void GuiConvexEditorCtrl::setVisible( bool val ) mConvexHL = NULL; mFaceHL = -1; - setSelection( NULL, -1 ); + setSelection( NULL, -1 ); WorldEditor *wedit; if ( Sim::findObject( "EWorldEditor", wedit ) ) diff --git a/Templates/BaseGame/game/data/ExampleModule/ExampleModule.tscript b/Templates/BaseGame/game/data/ExampleModule/ExampleModule.tscript index 0f540c0d8..137067959 100644 --- a/Templates/BaseGame/game/data/ExampleModule/ExampleModule.tscript +++ b/Templates/BaseGame/game/data/ExampleModule/ExampleModule.tscript @@ -81,7 +81,6 @@ function ExampleModule::initClient(%this) exec(%prefPath @ "/keybinds." @ $TorqueScriptFileExtension); %this.queueExec("./scripts/inputCommands"); - addOptionsMenuCategory("Example Options", "testExampleOptions();"); } //This is called when a game session client successfuly connects to a game server. @@ -108,7 +107,17 @@ function ExampleModule::onDestroyClientConnection(%this) ExampleMoveMap.pop(); } +function ExampleModule::populateOptionsMenuCategories(%this) +{ + addOptionsMenuCategory("Example Options", "testExampleOptions();"); +} + function testExampleOptions() { + OptionsMenuSettingsList.clear(); + + OptionName.setText(""); + OptionDescription.setText(""); + addListOption("Test Option", "This is a test option", $testOptionValue, "OptionA\tOptionB"); } \ No newline at end of file diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript index 23a09236e..7fb2cd43d 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript @@ -63,6 +63,8 @@ function OptionsMenu::onAdd(%this) addOptionsMenuCategory("Audio", "populateAudioSettingsList();"); addOptionsMenuCategory("Keyboard & Mouse", "populateKeyboardMouseSettingsList();"); addOptionsMenuCategory("Gamepad", "populateGamepadSettingsList();"); + + callOnModules("populateOptionsMenuCategories", "Game"); } function OptionsMenuSettingsList::onAdd(%this) @@ -900,7 +902,10 @@ function OptionsMenu::onKeybindChanged(%this, %actionMap, %keybind) // function addOptionsMenuCategory(%categoryName, %selectCallback) { - OptionsMenu.optionsCategories.add(%categoryName, %selectCallback); + //Don't add duplicates! + %index = OptionsMenu.optionsCategories.getIndexFromKey(%categoryName); + if(%index == -1) + OptionsMenu.optionsCategories.add(%categoryName, %selectCallback); } function removeOptionsMenuCategory(%categoryName) diff --git a/Templates/BaseGame/game/data/UI/images/dropdown_textEdit_image.asset.taml b/Templates/BaseGame/game/data/UI/images/dropdown_textEdit_image.asset.taml deleted file mode 100644 index 63455e9dd..000000000 --- a/Templates/BaseGame/game/data/UI/images/dropdown_textEdit_image.asset.taml +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/terrainIcon_image.asset.taml b/Templates/BaseGame/game/tools/assetBrowser/art/terrainIcon_image.asset.taml index 4a6ef4a57..5b7fffc0c 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/art/terrainIcon_image.asset.taml +++ b/Templates/BaseGame/game/tools/assetBrowser/art/terrainIcon_image.asset.taml @@ -1,8 +1,8 @@ diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index 7d0c1e3da..c99602084 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript @@ -915,13 +915,7 @@ function AssetBrowser::deleteMaterial( %this, %materialName, %secondFilter, %sec AssetBrowserPerMan.saveDirty(); } - AssetBrowser.preloadFilter(); -} - -function AssetBrowser::thumbnailCountUpdate(%this) -{ - $Pref::AssetBrowser::ThumbnailCountIndex = AssetBrowser-->materialPreviewCountPopup.getSelected(); - AssetBrowser.LoadFilter( AssetBrowser.currentFilter, AssetBrowser.currentStaticFilter ); + AssetBrowser.refresh(); } function AssetBrowser::toggleTagFilterPopup(%this) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/component.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/component.tscript index 6488b319f..d443157ea 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/component.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/component.tscript @@ -54,12 +54,7 @@ function AssetBrowser::createComponentAsset(%this) %moduleDef = ModuleDatabase.findModule(%moduleName, 1); AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); - AssetBrowser.loadFilters(); - - %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); - %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "ComponentAsset"); - - AssetBrowserFilterTree.onSelect(%smItem); + AssetBrowser.refresh(); return %tamlpath; } diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cubemap.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cubemap.tscript index 78076654b..b050d37cd 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cubemap.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cubemap.tscript @@ -28,12 +28,7 @@ function AssetBrowser::createCubemapAsset(%this) %moduleDef = ModuleDatabase.findModule(%moduleName, 1); AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); - AssetBrowser.loadFilters(); - - %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); - %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "CubemapAsset"); - - AssetBrowserFilterTree.onSelect(%smItem); + AssetBrowser.refresh(); return %tamlpath; } diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameObject.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameObject.tscript index bdf079ad0..c25eda8f4 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameObject.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameObject.tscript @@ -73,21 +73,10 @@ function AssetBrowser::duplicateGameObjectAsset(%this, %assetDef, %targetModule) AssetDatabase.addDeclaredAsset(%moduleDef, %tamlPath); //Refresh the browser - AssetBrowser.loadFilters(); - - //Ensure our context is set - %treeItemId = AssetBrowserFilterTree.findItemByName(%targetModule); - %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "GameObjectAsset"); - - AssetBrowserFilterTree.selectItem(%smItem); + AssetBrowser.refresh(); //Rename it for convenience AssetBrowser.performRenameAsset(%assetName, "New" @ %assetName); - - //Expand and refresh the target module - AssetBrowserFilterTree.expandItem(%treeItemId,true); - - AssetBrowserFilterTree.buildVisibleTree(); } //not used diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gui.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gui.tscript index 4660d56fc..dfebccb47 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gui.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gui.tscript @@ -79,12 +79,7 @@ function AssetBrowser::createGUIAsset(%this) %moduleDef = ModuleDatabase.findModule(%moduleName, 1); AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); - AssetBrowser.loadFilters(); - - %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); - %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "GUIs"); - - AssetBrowserFilterTree.onSelect(%smItem); + AssetBrowser.refresh(); return %tamlpath; } diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript index f39d35349..0dbebd39b 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript @@ -233,13 +233,17 @@ function AssetBrowser::buildImageAssetPreview(%this, %assetDef, %previewData) //Revalidate. If it didn't work, just use the default placeholder one if(!isFile(%previewFilePath)) - %previewAssetName = "ToolsModule:genericAssetIcon_image"; + { + %previewData.previewImage = "ToolsModule:genericAssetIcon_image"; + } + else + { + %previewData.previewImage = %previewAssetName; + } %previewData.assetName = %assetDef.assetName; %previewData.assetPath = %assetDef.scriptFile; - %previewData.previewImage = %previewAssetName; - %previewData.assetFriendlyName = %assetDef.assetName; %previewData.assetDesc = %assetDef.description; @@ -324,7 +328,14 @@ function GuiInspectorTypeImageAssetPtr::onControlDropped( %this, %payload, %posi if(%assetType $= "ImageAsset") { - echo("DROPPED A IMAGE ON AN IMAGE ASSET COMPONENT FIELD!"); + %module = %payload.moduleName; + %asset = %payload.assetName; + + %oldValue = %this.targetObject.bitmapAsset; + %arrayIndex = ""; + + %targetObject = %this.targetObject; + %targetObject.bitmapAsset = %module @ ":" @ %asset; } EWorldEditor.isDirty = true; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript index e46e891c7..23be49e9f 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript @@ -61,11 +61,6 @@ function AssetBrowser::createLevelAsset(%this) AssetBrowser.refresh(); - %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); - %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Levels"); - - AssetBrowserFilterTree.onSelect(%smItem); - return %tamlpath; } diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index 880ff115e..fab16eb90 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript @@ -24,12 +24,7 @@ function AssetBrowser::createMaterialAsset(%this) %moduleDef = ModuleDatabase.findModule(%moduleName, 1); AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); - AssetBrowser.loadFilters(); - - %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); - %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Materials"); - - AssetBrowserFilterTree.onSelect(%smItem); + AssetBrowser.refresh(); return %tamlpath; } @@ -428,7 +423,7 @@ function AssetBrowser::importMaterialAsset(%this, %assetItem) function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) { - %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(%assetDef.getScriptPath()))); + %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(AssetDatabase.getAssetFilePath(%assetDef.getAssetId())))); %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/"; if(!IsDirectory(%previewPath)) @@ -460,8 +455,8 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) { displayEditorLoadingGui("Generating Material Asset Preview..."); - if(isObject(%assetDef.materialDefinitionName)) - { + if(isObject(%assetDef.materialDefinitionName)) + { %previewShapeDef = AssetDatabase.acquireAsset("ToolsModule:previewSphereShape"); %generatedFilePath = %previewShapeDef.generateCachedPreviewImage(256, %assetDef.materialDefinitionName); @@ -488,13 +483,17 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) //Revalidate. If it didn't work, just use the default placeholder one if(!isFile(%previewFilePath)) - %previewAssetName = "ToolsModule:materialIcon_image"; + { + %previewData.previewImage = "ToolsModule:materialIcon_image"; + } + else + { + %previewData.previewImage = "ToolsModule:" @ %previewAssetName; + } %previewData.assetName = %assetDef.assetName; %previewData.assetPath = %assetDef.scriptFile; - %previewData.previewImage = "ToolsModule:" @ %previewAssetName;//%assetDef.fileName; - %previewData.assetFriendlyName = %assetDef.assetName; %previewData.assetDesc = %assetDef.description; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript index 7ce0acb1b..15c48079b 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript @@ -26,12 +26,7 @@ function AssetBrowser::createShapeAsset(%this) %moduleDef = ModuleDatabase.findModule(%moduleName, 1); AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); - AssetBrowser.loadFilters(); - - %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); - %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "ShapeAsset"); - - AssetBrowserFilterTree.onSelect(%smItem); + AssetBrowser.refresh(); return %tamlpath; } @@ -302,12 +297,16 @@ function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData) //Revalidate. If it didn't work, just use the default placeholder one if(!isFile(%previewFilePath)) - %previewAssetName = "ToolsModule:genericAssetIcon_image"; + { + %previewData.previewImage = "ToolsModule:genericAssetIcon_image"; + } + else + { + %previewData.previewImage = "ToolsModule:" @ %previewAssetName; + } %previewData.assetName = %assetDef.assetName; %previewData.assetPath = %assetDef.fileName; - - %previewData.previewImage = "ToolsModule:" @ %previewAssetName;//%assetDef.fileName; %previewData.assetFriendlyName = %assetDef.assetName; %previewData.assetDesc = %assetDef.description; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.tscript index 04ab8d508..8cc63bdf4 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.tscript @@ -75,7 +75,7 @@ function AssetBrowser::onSoundAssetEditorDropped(%this, %assetDef, %position) } -function GuiInspectorTypeShapeAssetPtr::onControlDropped( %this, %payload, %position ) +function GuiInspectorTypeSoundAssetPtr::onControlDropped( %this, %payload, %position ) { Canvas.popDialog(EditorDragAndDropLayer); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/stateMachine.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/stateMachine.tscript index dff204024..0e9188a97 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/stateMachine.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/stateMachine.tscript @@ -47,12 +47,7 @@ function AssetBrowser::createStateMachineAsset(%this) %moduleDef = ModuleDatabase.findModule(%moduleName, 1); AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); - AssetBrowser.loadFilters(); - - %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); - %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "StateMachines"); - - AssetBrowserFilterTree.onSelect(%smItem); + AssetBrowser.refresh(); return %tamlpath; } @@ -123,21 +118,10 @@ function AssetBrowser::duplicateStateMachineAsset(%this, %assetDef) AssetDatabase.addDeclaredAsset(%moduleDef, %tamlPath); //Refresh the browser - AssetBrowser.loadFilters(); - - //Ensure our context is set - %treeItemId = AssetBrowserFilterTree.findItemByName(%targetModule); - %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "StateMachineAsset"); - - AssetBrowserFilterTree.selectItem(%smItem); + AssetBrowser.refresh(); //Rename it for convenience AssetBrowser.performRenameAsset(%assetName, "New" @ %assetName); - - //Expand and refresh the target module - AssetBrowserFilterTree.expandItem(%treeItemId,true); - - AssetBrowserFilterTree.buildVisibleTree(); } function AssetBrowser::renameGameObjectAsset(%this, %assetDef, %newAssetId, %originalName, %newName) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript index ad1212e11..8fc9e21f9 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript @@ -91,15 +91,85 @@ function AssetBrowser::deleteTerrainMaterialAsset(%this, %assetDef) function AssetBrowser::buildTerrainMaterialAssetPreview(%this, %assetDef, %previewData) { + %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(AssetDatabase.getAssetFilePath(%assetDef.getAssetId())))); + %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/"; + + if(!IsDirectory(%previewPath)) + { + %this.dirHandler.createFolder(%previewPath); + } + + %generatePreview = false; + + %previewFilePath = %previewPath @ %assetDef.assetName @ "_Preview.dds"; + if(!isFile(%previewFilePath)) + { + %generatePreview = true; + } + else + { + if(isObject(%assetDef.materialDefinitionName)) + { + if(compareFileTimes(%assetDef.materialDefinitionName.getDiffuseMap(), %previewFilePath) == 1 || + compareFileTimes(%assetDef.materialDefinitionName.getFilename(), %previewFilePath) == 1) + %generatePreview = true; + } + } + + %previewAssetName = %module.moduleId @ "_" @ %assetDef.assetName @ "_PreviewImage"; + + if(%generatePreview) + { + displayEditorLoadingGui("Generating Material Asset Preview..."); + + if(isObject(%assetDef.materialDefinitionName)) + { + %previewShapeDef = AssetDatabase.acquireAsset("ToolsModule:previewSphereShape"); + %generatedFilePath = %previewShapeDef.generateCachedPreviewImage(256, %assetDef.materialDefinitionName); + + pathCopy(%generatedFilePath, %previewFilePath); + fileDelete(%generatedFilePath); + + %previewAsset = new ImageAsset() + { + assetName = %previewAssetName; + versionId = 1; + imageFile = fileName(%previewFilePath); + }; + + %previewImgAssetPath = %previewPath @ %previewAsset.assetName @ ".asset.taml"; + %assetImportSuccessful = TAMLWrite(%previewAsset, %previewImgAssetPath); + + %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); + + %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + } + + hideEditorLoadingGui(); + } + + //Revalidate. If it didn't work, just use the default placeholder one + if(!isFile(%previewFilePath)) + { + %previewData.previewImage = "ToolsModule:terrainMaterialIcon_image"; + } + else + { + %previewData.previewImage = "ToolsModule:" @ %previewAssetName; + } + %previewData.assetName = %assetDef.assetName; %previewData.assetPath = ""; %previewData.doubleClickCommand = ""; - %previewData.previewImage = "ToolsModule:terrainMaterialIcon_image"; - %previewData.assetFriendlyName = %assetDef.gameObjectName; %previewData.assetDesc = %assetDef.description; %previewData.tooltip = %assetDef.gameObjectName; + + %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ + "\nAsset Type: Terrain Material Asset" @ + "\nAsset Definition ID: " @ %assetDef @ + "\nDefinition Path: " @ %assetDef.getScriptPath(); } function GuiInspectorTypeTerrainMaterialAssetPtr::onClick( %this, %fieldName ) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript index 4b71d7660..2d088f27a 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript @@ -163,7 +163,7 @@ function AssetBrowser::performRenameAsset(%this, %originalAssetName, %newName) %ModuleItem = AssetBrowser-->filterTree.findItemByName(%moduleName); // TODO is this correct? - %assetType = %ModuleItem.getClassName(); + /*%assetType = %ModuleItem.getClassName(); %assetTypeId = AssetBrowser-->filterTree.findChildItemByName(%ModuleItem, %assetType); @@ -172,7 +172,7 @@ function AssetBrowser::performRenameAsset(%this, %originalAssetName, %newName) %selectedItem = AssetBrowser-->filterTree.getSelectedItem(); AssetBrowser-->filterTree.scrollVisibleByObjectId(%selectedItem); - AssetBrowser-->filterTree.buildVisibleTree(); + AssetBrowser-->filterTree.buildVisibleTree();*/ } function renameAssetFile(%assetDef, %newName) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript index f22c6f73d..f2ea27660 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript @@ -182,11 +182,14 @@ function CreateNewAsset() Canvas.popDialog(AssetBrowser_newAsset); //Load it - %moduleDef = ModuleDatabase.findModule(%moduleName,1); - AssetDatabase.addDeclaredAsset(%moduleDef, %assetFilePath); - //For utilities' sake, we'll acquire it immediately so it can be utilized - //without delay if it's got any script/dependencies stuff - AssetDatabase.acquireAsset("\"" @ %moduleName @ ":" @ %assetName @ "\""); + if(!AssetDatabase.isDeclaredAsset(%moduleName @ ":" @ %assetName)) + { + %moduleDef = ModuleDatabase.findModule(%moduleName,1); + AssetDatabase.addDeclaredAsset(%moduleDef, %assetFilePath); + //For utilities' sake, we'll acquire it immediately so it can be utilized + //without delay if it's got any script/dependencies stuff + AssetDatabase.acquireAsset("\"" @ %moduleName @ ":" @ %assetName @ "\""); + } if(AssetBrowser_newAsset.callbackFunc !$= "") { diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript index 09215601a..0baf0eb70 100644 --- a/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript @@ -179,7 +179,7 @@ function ConvexEditorMaterialBtn::gotMaterialName(%this, %name) ConvexEditorOptionsWindow-->matPreviewBtn.setBitmap(getAssetPreviewImage(%diffusemap)); - ConvexEditorOptionsWindow.activeMaterial = %materialAsset.materialDefinitionName; + ConvexEditorOptionsWindow.activeMaterial = %materialAsset.getAssetId(); } function ConvexEditorMaterialApplyBtn::onClick(%this) diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.tscript b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.tscript index f62fe12ea..59df87bd9 100644 --- a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.tscript +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.tscript @@ -186,6 +186,15 @@ function GuiEditCanvas::onCreateMenu(%this) item[8] = "Show Guides" TAB "" TAB "GuiEditor.toggleDrawGuides();"; item[9] = "Clear Guides" TAB "" TAB "GuiEditor.clearGuides();"; }; + + new PopupMenu() + { + superClass = "MenuBuilder"; + barTitle = "Tools"; + internalName = "ToolsMenu"; + + item[0] = "Project Importer" TAB "" TAB "ProjectImporter::beginProjectImport();"; + }; new PopupMenu() { diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui b/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui index 0f71d8757..d1d46b2b1 100644 --- a/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui +++ b/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui @@ -260,6 +260,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { position = "6 21"; Extent = "185 52"; HorizSizing = "width"; + className = "materialEditorDiffuseMapContainer"; new GuiBitmapCtrl() { canSaveDynamicFields = "0"; @@ -412,6 +413,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { position = "6 79"; Extent = "185 52"; HorizSizing = "width"; + className = "materialEditorNormalMapContainer"; new GuiBitmapCtrl() { canSaveDynamicFields = "0"; @@ -764,6 +766,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { position = "6 364"; Extent = "185 52"; HorizSizing = "width"; + className = "materialEditorORMConfigMapContainer"; new GuiBitmapCtrl() { canSaveDynamicFields = "0"; @@ -985,6 +988,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { isContainer = "1"; canSave = "1"; canSaveDynamicFields = "0"; + className = "materialEditorRoughnessMapContainer"; new GuiBitmapCtrl() { bitmapAsset = "ToolsModule:unknownImage_image"; @@ -1221,6 +1225,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { isContainer = "1"; canSave = "1"; canSaveDynamicFields = "0"; + className = "materialEditorAOMapContainer"; new GuiBitmapCtrl() { bitmapAsset = "ToolsModule:unknownImage_image"; @@ -1457,6 +1462,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { isContainer = "1"; canSave = "1"; canSaveDynamicFields = "0"; + className = "materialEditorMetalMapContainer"; new GuiBitmapCtrl() { bitmapAsset = "ToolsModule:unknownImage_image"; @@ -1710,6 +1716,8 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { isContainer = "1"; canSave = "1"; canSaveDynamicFields = "0"; + className = "materialEditorGlowMapContainer"; + new GuiBitmapCtrl() { bitmapAsset = "ToolsModule:unknownImage_image"; wrap = "0"; @@ -1945,6 +1953,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { position = "6 193"; Extent = "185 52"; HorizSizing = "width"; + className = "materialEditorDetailMapContainer"; new GuiBitmapCtrl() { canSaveDynamicFields = "0"; @@ -2090,6 +2099,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { position = "6 136"; Extent = "185 52"; HorizSizing = "width"; + className = "materialEditorDetailNormalMapContainer"; new GuiBitmapCtrl() { canSaveDynamicFields = "0"; @@ -2235,6 +2245,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { position = "6 136"; Extent = "185 52"; HorizSizing = "width"; + className = "materialEditorOverlayMapContainer"; new GuiBitmapCtrl() { canSaveDynamicFields = "0"; @@ -2361,6 +2372,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { position = "6 250"; Extent = "185 52"; HorizSizing = "width"; + className = "materialEditorLightMapContainer"; new GuiBitmapCtrl() { canSaveDynamicFields = "0"; @@ -2487,6 +2499,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { position = "6 307"; Extent = "185 52"; HorizSizing = "width"; + className = "materialEditorToneMapContainer"; new GuiBitmapCtrl() { canSaveDynamicFields = "0"; diff --git a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript index d157c817a..de003fdc8 100644 --- a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript @@ -1174,8 +1174,8 @@ function MaterialEditorGui::updateTextureMap( %this, %type, %action ) function MaterialEditorGui::doUpdateTextureMap( %this, %assetId ) { if(%assetId !$= "") -{ - %layer = MaterialEditorGui.currentLayer; + { + %layer = MaterialEditorGui.currentLayer; %type = %this.updatingTextureType; @@ -2419,4 +2419,82 @@ function MaterialEditorGui::swapMaterial(%this) function MaterialEditorGui::doSwapMaterial(%this, %materialAsset) { MaterialEditorGui.showMaterialChangeSaveDialog(%materialAsset); +} + +// +// +function matEdDragNDropMapAssignment(%type, %payload) +{ + %assetType = %payload.assetType; + if(%assetType !$= "ImageAsset") + return; + + %module = %payload.moduleName; + %assetName = %payload.assetName; + %assetId = %module @ ":" @ %assetName; + + MaterialEditorGui.updatingTextureType = %type; + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + + MaterialEditorGui.doUpdateTextureMap( %assetId ); +} + +function materialEditorDiffuseMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("Diffuse", %payload); +} + +function materialEditorNormalMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("Normal", %payload); +} + +function materialEditorORMConfigMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("ORMConfig", %payload); +} + +function materialEditorRoughnessMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("Roughness", %payload); +} + +function materialEditorAOMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("AO", %payload); +} + +function materialEditorMetalMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("Metal", %payload); +} + +function materialEditorGlowMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("Glow", %payload); +} + +function materialEditorDetailMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("Detail", %payload); +} + +function materialEditorDetailNormalMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("DetailNormal", %payload); +} + +function materialEditorOverlayMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("Overlay", %payload); +} + +function materialEditorLightMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("Light", %payload); +} + +function materialEditorToneMapContainer::onControlDropped( %this, %payload, %position ) +{ + matEdDragNDropMapAssignment("Tone", %payload); } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui index 1a7d1caf1..4eef5308f 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui @@ -5,7 +5,7 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) { minExtent = "8 2"; horizSizing = "right"; vertSizing = "bottom"; - profile = "ToolsGuiDefaultProfile"; + profile = "ToolsGuiDefaultNonModalProfile"; visible = "1"; active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; @@ -256,7 +256,7 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) { canSave = "1"; canSaveDynamicFields = "0"; }; - new GuiContainer(BaseMapContainer) { + new GuiContainer(DiffuseMapContainer) { margin = "0 0 0 0"; padding = "0 0 0 0"; anchorTop = "1"; @@ -312,7 +312,7 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) { tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; - internalName = "texBaseMap"; + internalName = "texDiffuseMap"; canSave = "1"; canSaveDynamicFields = "0"; }; @@ -334,7 +334,7 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) { profile = "ToolsGuiDefaultProfile"; visible = "1"; active = "1"; - command = "TerrainMaterialDlg.updateTextureMap(\"BaseMap\");"; + command = "TerrainMaterialDlg.updateTextureMap(\"DiffuseMap\");"; tooltipProfile = "ToolsGuiDefaultProfile"; tooltip = "Change the Active Diffuse Map for this layer"; hovertime = "1000"; @@ -402,7 +402,7 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) { profile = "ToolsGuiButtonProfile"; visible = "1"; active = "1"; - command = "TerrainMaterialDlg.updateTextureMap(\"BaseMap\");"; + command = "TerrainMaterialDlg.updateTextureMap(\"DiffuseMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; @@ -427,7 +427,7 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) { profile = "ToolsGuiDefaultProfile"; visible = "1"; active = "1"; - command = "TerrainMaterialDlg.clearTextureMap(\"BaseMap\");"; + command = "TerrainMaterialDlg.clearTextureMap(\"DiffuseMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript index ef1b9292b..54c7d22b4 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript @@ -2313,11 +2313,13 @@ function EWorldEditor::SetActiveScene(%this, %sceneObj) { $ActiveEditingScene.isEditing = false; %itemId = EditorTree.findItemByObjectId($ActiveScene); - EditorTree.markItem(%itemId); + if(%itemId != -1) + EditorTree.markItem(%itemId); } %itemId = EditorTree.findItemByObjectId(%sceneObj); - EditorTree.markItem(%itemId); + if(%itemId != -1) + EditorTree.markItem(%itemId); $ActiveEditingScene = %sceneObj; $ActiveEditingScene.isEditing = true; diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript index b49cef39a..fd1063618 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript @@ -269,27 +269,27 @@ function TerrainMaterialDlg::changeTerrainMatMapAsset(%this) %imgAsset = AssetBrowser.selectedAsset; if(%imgAsset !$= "") -{ + { %targetMap.asset = %imgAsset; %image = %imgAsset; if(%this.updateTargetMap $= "DetailMap") - { + { //show the supplemental maps NormalMapContainer.callOnChildren("setActive", true); ORMMapContainer.callOnChildren("setActive", true); MacroMapContainer.callOnChildren("setActive", true); + } } -} - else + else { %image = $TerrainMaterialEditor::emptyMaterialImage; } %targetMap.setBitmap( getAssetPreviewImage(%image) ); - %targetMapName = %targetMap @ "AssetId"; - %targetMapName.setText(%imgAsset); + %targetMapNameText = %this.findObjectByInternalName(%this.updateTargetMap @ "AssetId", true); + %targetMapNameText.setText(%imgAsset); TerrainMaterialDlg.matDirty = true; } @@ -412,7 +412,7 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat ) %imgPath = %mat.getDiffuseMap(); %imgPathText = %imgPath !$= "" && %imgPath !$= $TerrainMaterialEditor::emptyMaterialImage ? %mat.getDiffuseMapAsset() : "None"; %this-->diffuseMapAssetId.setText( %imgPathText ); - %this-->texBaseMap.setBitmap( getAssetPreviewImage(%imgPath) ); + %this-->texDiffuseMap.setBitmap( getAssetPreviewImage(%imgPath) ); // %imgPath = %mat.getNormalMap(); @@ -487,7 +487,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) //--- - %newDiffuse = %this-->texBaseMap.getBitmap(); + %newDiffuse = %this-->texDiffuseMap.getBitmap(); if(%newDiffuse $= $TerrainMaterialEditor::emptyMaterialImage || %newDiffuse $= %blankBitmap) %newDiffuse = ""; @@ -741,3 +741,45 @@ function TerrainMaterialDlgBlendHeightContrastTextEdit::onValidate(%this) TerrainMaterialDlg.activeMat.blendHeightContrast = %this.getText(); TerrainMaterialDlg.matDirty = true; } + +// +// +function terrMatEdDragNDropMapAssignment(%mapName, %payload) +{ + %assetType = %payload.assetType; + if(%assetType !$= "ImageAsset") + return; + + %module = %payload.moduleName; + %assetName = %payload.assetName; + %assetId = %module @ ":" @ %assetName; + + TerrainMaterialDlg.updateTargetMap = %mapName; + AssetBrowser.selectedAsset = %assetId; + TerrainMaterialDlg.changeTerrainMatMapAsset(); +} + +function DiffuseMapContainer::onControlDropped( %this, %payload, %position ) +{ + terrMatEdDragNDropMapAssignment("DiffuseMap", %payload); +} + +function DetailMapContainer::onControlDropped( %this, %payload, %position ) +{ + terrMatEdDragNDropMapAssignment("DetailMap", %payload); +} + +function NormalMapContainer::onControlDropped( %this, %payload, %position ) +{ + terrMatEdDragNDropMapAssignment("NormalMap", %payload); +} + +function ORMMapContainer::onControlDropped( %this, %payload, %position ) +{ + terrMatEdDragNDropMapAssignment("ORMMap", %payload); +} + +function MacroMapContainer::onControlDropped( %this, %payload, %position ) +{ + terrMatEdDragNDropMapAssignment("MacroMap", %payload); +} From f204a4c646b4a11e987cc2cb8ebef791326315ad Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 27 Mar 2022 14:09:41 -0500 Subject: [PATCH 059/145] Fixes issue where nested callOnModules would thrash the queued exec lists from other invokes Also removes unwanted reference ids from the OptionsMenu gui object and disabled the ability for dynamic fields to be saved on it to prevent it from happening again. --- .../game/core/utility/scripts/module.tscript | 46 ++++++++++++------- .../game/data/UI/guis/optionsMenu.gui | 10 +--- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/Templates/BaseGame/game/core/utility/scripts/module.tscript b/Templates/BaseGame/game/core/utility/scripts/module.tscript index 2b102eb9e..ae7f0ce13 100644 --- a/Templates/BaseGame/game/core/utility/scripts/module.tscript +++ b/Templates/BaseGame/game/core/utility/scripts/module.tscript @@ -6,7 +6,8 @@ if (!isObject(ExecFilesList)) function callOnModules(%functionName, %moduleGroup, %var0, %var1, %var2, %var3, %var4, %var5, %var6) { //clear per module group file execution chain - ExecFilesList.empty(); + %execArray = new ArrayObject("callOn" @ %functionName @ "_" @ %moduleGroup); + ExecFilesList.push_back(%execArray); //Get our modules so we can exec any specific client-side loading/handling %modulesList = ModuleDatabase.findModules(false); for(%i=0; %i < getWordCount(%modulesList); %i++) @@ -23,12 +24,21 @@ function callOnModules(%functionName, %moduleGroup, %var0, %var1, %var2, %var3, %module.scopeSet.call(%functionName, %var0, %var1, %var2, %var3, %var4, %var5, %var6); } - %execFilecount = ExecFilesList.count(); + %execFilecount = %execArray.count(); + + if($traceModuleCalls) + { + error("ExecFilesList at actual exec point:"); + %execArray.echo(); + } + for (%i=0;%i<%execFilecount;%i++) { - %filename = ExecFilesList.getKey(%i); + %filename = %execArray.getKey(%i); exec(%filename); } + + ExecFilesList.pop_back(); //cleanup } function loadModuleMaterials(%moduleGroup) @@ -213,7 +223,7 @@ function SimSet::queueExec(%scopeSet, %execFilePath, %isExclusive) return; } - if(!isObject(ExecFilesList)) + if(!isObject(ExecFilesList) || ExecFilesList.count() == 0) { error("Module::queueExec() - ExecFilesList array object doesn't exist!"); return; @@ -225,10 +235,11 @@ function SimSet::queueExec(%scopeSet, %execFilePath, %isExclusive) %fullPath = pathConcat(%moduleDef.ModulePath, %execFilePath); ///go through all entries %locked = false; - %execFilecount = ExecFilesList.count(); + %execFileList = ExecFilesList.getKey(ExecFilesList.count()-1); + %execFilecount = %execFileList.count(); for (%i=0;%i<%execFilecount;%i++) { - %check = ExecFilesList.getKey(%i); + %check = %execFileList.getKey(%i); //look for a substring match %isMatch = strIsMatchExpr("*"@ strReplace(%execFilePath,"./","/"),%check ); if (%isMatch) @@ -237,13 +248,13 @@ function SimSet::queueExec(%scopeSet, %execFilePath, %isExclusive) //and kill off any duplicates //do note that doing it in this order means setting exclusive twice //allows one to override exclusive with exclusive - %locked = ExecFilesList.getValue(%i); + %locked = %execFileList.getValue(%i); if ((%locked && !%isExclusive)&&($reportModuleFileConflicts)) error("found" SPC %execFilePath SPC "duplicate file!"); if (%isExclusive) { // Replacing an existing entry, update in-place - ExecFilesList.setKey(%fullPath, %i); - ExecFilesList.setValue(%isExclusive, %i); + %execFileList.setKey(%fullPath, %i); + %execFileList.setValue(%isExclusive, %i); %locked = true; //Done, but don't return and bypass trace logging below } break; @@ -251,9 +262,9 @@ function SimSet::queueExec(%scopeSet, %execFilePath, %isExclusive) } //if we're not locked, go ahead and add it to the pile if (!%locked) - ExecFilesList.add(%fullPath,%isExclusive); + %execFileList.add(%fullPath,%isExclusive); if ($traceModuleCalls) - ExecFilesList.echo(); + %execFileList.echo(); } function SimSet::unQueueExec(%scopeSet, %execFilePath) @@ -269,7 +280,7 @@ function SimSet::unQueueExec(%scopeSet, %execFilePath) return; } - if(!isObject(ExecFilesList)) + if(!isObject(ExecFilesList) || ExecFilesList.count() == 0) { error("Module::unRegisterDatablock() - ExecFilesList array object doesn't exist!"); return; @@ -280,23 +291,24 @@ function SimSet::unQueueExec(%scopeSet, %execFilePath) %fullPath = pathConcat(%moduleDef.ModulePath, %relativePath); ///go through all entries %locked = false; - %execFilecount = ExecFilesList.count(); + %execFileList = ExecFilesList.getKey(ExecFilesList.count()-1); + %execFilecount = %execFileList.count(); for (%i=0;%i<%execFilecount;%i++) { - %check = ExecFilesList.getKey(%i); + %check = %execFileList.getKey(%i); //look for a substring match %isMatch = strIsMatchExpr("*"@ %execFilePath,%check ); if (%isMatch) { //check if we're already locked in. if not, kill it. - %locked = ExecFilesList.getValue(%i); + %locked = %execFileList.getValue(%i); if (!%locked) { - ExecFilesList.erase(%i); + %execFileList.erase(%i); } } } if ($traceModuleCalls) - ExecFilesList.echo(); + %execFileList.echo(); } diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui b/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui index 84c70072f..3b1999ed9 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.gui @@ -4,15 +4,7 @@ $guiContent = new GuiControl(OptionsMenu) { profile = "GuiDefaultProfile"; tooltipProfile = "GuiToolTipProfile"; isContainer = "1"; - canSaveDynamicFields = "1"; - currentCategory = "Display"; - optionsCategories = "17177"; - pageTabIndex = "0"; - returnGui = "MainMenuGui"; - tamlReader = "20088"; - tile = "0"; - unappliedChanges = "17178"; - useVariable = "0"; + canSaveDynamicFields = "0"; new GuiControl() { position = "48 56"; From 81aa43a4bd5f1a8807796248ff07787fab7b3751 Mon Sep 17 00:00:00 2001 From: JeffR Date: Tue, 29 Mar 2022 01:40:07 -0500 Subject: [PATCH 060/145] Fixed formatting to match the standard for TerrainMaterialAsset inspector fields Added utility functions to TerrainMaterialAsset for getting the material and fx material definitions Fixed logical flaw with the initialization code that could cause the materialDefinition to be nulled in terrainmaterialassets Fixed layer handling in GroundCover to properly work with TerrainMaterialAssets Added logic to properly exit out of the onAdd in the event no internal name is assigned or if there is a collision. This prevents duplicates from appearing in the terr mat editor when creating a new material Fixed issue where going from a creator item in the AB to selecting a particular asset type would break the filtering because select mode removed collections and creator items, changing all the item ids and breaking references. Added sanity check to prevent attempting to acquire non-assets in the AB, such as creator entries, which would cause console spam Added optional field to provide an override new asset name to the New Asset window Added logic so in the event no FX Material is found when importing a terrain material, it will create a stub entry so it always has one defined Added logic to handle situations where a terrain has a reference to an assetId, but the asset does not exist for whatever reason. Will prompt to create the missing asset, then continue on with the regular saving/editing process as normal Fixed issue where the terrain material editor would try and reference the preview images being used in the display on the editor instead of the proper assetId itself --- .../T3D/assets/TerrainMaterialAsset.cpp | 146 +++++++----------- .../source/T3D/assets/TerrainMaterialAsset.h | 13 +- Engine/source/T3D/fx/groundCover.cpp | 4 +- Engine/source/T3D/fx/groundCover.h | 2 +- Engine/source/terrain/terrMaterial.cpp | 14 +- .../assetBrowser/scripts/assetBrowser.tscript | 35 ++--- .../assetBrowser/scripts/newAsset.tscript | 8 +- .../pre40/T3Dpre4ProjectImporter.tscript | 9 ++ .../interfaces/terrainMaterialDlg.ed.tscript | 45 ++++-- 9 files changed, 142 insertions(+), 134 deletions(-) diff --git a/Engine/source/T3D/assets/TerrainMaterialAsset.cpp b/Engine/source/T3D/assets/TerrainMaterialAsset.cpp index 3ef54d856..043ce6812 100644 --- a/Engine/source/T3D/assets/TerrainMaterialAsset.cpp +++ b/Engine/source/T3D/assets/TerrainMaterialAsset.cpp @@ -177,11 +177,6 @@ void TerrainMaterialAsset::initializeAsset() return; } - if (mMatDefinitionName == StringTable->insert("DetailBlue")) - { - bool asdfsd = true; - } - if (size() != 0 && mScriptPath == StringTable->EmptyString()) { mLoadedState = EmbeddedDefinition; @@ -267,18 +262,20 @@ void TerrainMaterialAsset::loadMaterial() { for (U32 i = 0; i < size(); i++) { - mMaterialDefinition = dynamic_cast(getObject(i)); - if (mMaterialDefinition) + TerrainMaterial* terrMat = dynamic_cast(getObject(i)); + if (terrMat) { + mMaterialDefinition = terrMat; mLoadedState = Ok; mMaterialDefinition->setInternalName(getAssetId()); continue; } //Otherwise, check if it's our FX material - mFXMaterialDefinition = dynamic_cast(getObject(i)); - if (mFXMaterialDefinition) + Material* fxMat = dynamic_cast(getObject(i)); + if (fxMat) { + mFXMaterialDefinition = fxMat; //mMaterialDefinition->setInternalName(getAssetId()); mFXMaterialDefinition->reload(); continue; @@ -286,6 +283,9 @@ void TerrainMaterialAsset::loadMaterial() } } + + if(mLoadedState == Ok) + return; } else if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString()) { @@ -460,6 +460,28 @@ DefineEngineMethod(TerrainMaterialAsset, getScriptPath, const char*, (), , { return object->getScriptPath(); } + +DefineEngineMethod(TerrainMaterialAsset, getMaterialDefinition, S32, (), , + "Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n" + "@return The AssetId of the associated asset, if any.") +{ + SimObjectPtr mat = object->getMaterialDefinition(); + if (mat.isValid()) + return mat->getId(); + else + return 0; +} + +DefineEngineMethod(TerrainMaterialAsset, getFXMaterialDefinition, S32, (), , + "Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n" + "@return The AssetId of the associated asset, if any.") +{ + SimObjectPtr mat = object->getFXMaterialDefinition(); + if (mat.isValid()) + return mat->getId(); + else + return 0; +} #endif //----------------------------------------------------------------------------- // GuiInspectorTypeAssetId @@ -483,68 +505,36 @@ void GuiInspectorTypeTerrainMaterialAssetPtr::consoleInit() GuiControl* GuiInspectorTypeTerrainMaterialAssetPtr::constructEditControl() { // Create base filename edit controls - mUseHeightOverride = true; - mHeightOverride = 100; - - mMatEdContainer = new GuiControl(); - mMatEdContainer->registerObject(); - - addObject(mMatEdContainer); - - // Create "Open in ShapeEditor" button - mMatPreviewButton = new GuiBitmapButtonCtrl(); - - const char* matAssetId = getData(); - - TerrainMaterialAsset* matAsset = AssetDatabase.acquireAsset< TerrainMaterialAsset>(matAssetId); - - TerrainMaterial* materialDef = nullptr; - - char bitmapName[512] = "ToolsModule:material_editor_n_image"; - - /*if (!Sim::findObject(matAsset->getMaterialDefinitionName(), materialDef)) - { - Con::errorf("GuiInspectorTypeTerrainMaterialAssetPtr::constructEditControl() - unable to find material in asset"); - } - else - { - mMatPreviewButton->setBitmap(materialDef->mDiffuseMapFilename[0]); - }*/ - - mMatPreviewButton->setPosition(0, 0); - mMatPreviewButton->setExtent(100,100); + GuiControl* retCtrl = Parent::constructEditControl(); + if (retCtrl == NULL) + return retCtrl; // Change filespec char szBuffer[512]; - dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"TerrainMaterialAsset\", \"AssetBrowser.changeAsset\", %d, %s);", + dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"TerrainMaterialAsset\", \"AssetBrowser.changeAsset\", %s, %s);", mInspector->getIdString(), mCaption); - mMatPreviewButton->setField("Command", szBuffer); + mBrowseButton->setField("Command", szBuffer); - mMatPreviewButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); - mMatPreviewButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); - mMatPreviewButton->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString()); - StringBuilder strbld; - strbld.append(matAsset->getMaterialDefinitionName()); - strbld.append("\n"); - strbld.append("Open this asset in the Material Editor"); + // Create "Open in Editor" button + mEditButton = new GuiBitmapButtonCtrl(); - mMatPreviewButton->setDataField(StringTable->insert("tooltip"), NULL, strbld.data()); + dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.editAsset(%d.getText());", retCtrl->getId()); + mEditButton->setField("Command", szBuffer); - _registerEditControl(mMatPreviewButton); - //mMatPreviewButton->registerObject(); - mMatEdContainer->addObject(mMatPreviewButton); + char bitmapName[512] = "ToolsModule:material_editor_n_image"; + mEditButton->setBitmap(StringTable->insert(bitmapName)); - mMatAssetIdTxt = new GuiTextEditCtrl(); - mMatAssetIdTxt->registerObject(); - mMatAssetIdTxt->setActive(false); + mEditButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); + mEditButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + mEditButton->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + mEditButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this asset in the Terrain Material Editor"); - mMatAssetIdTxt->setText(matAssetId); + mEditButton->registerObject(); + addObject(mEditButton); - mMatAssetIdTxt->setBounds(100, 0, 150, 18); - mMatEdContainer->addObject(mMatAssetIdTxt); - - return mMatEdContainer; + return retCtrl; } bool GuiInspectorTypeTerrainMaterialAssetPtr::updateRects() @@ -558,45 +548,21 @@ bool GuiInspectorTypeTerrainMaterialAssetPtr::updateRects() mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y); bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); - - if (mMatEdContainer != nullptr) + if (mBrowseButton != NULL) { - mMatPreviewButton->resize(mEditCtrlRect.point, mEditCtrlRect.extent); + mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4); + resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent); } - if (mMatPreviewButton != nullptr) + if (mEditButton != NULL) { - mMatPreviewButton->resize(Point2I::Zero, Point2I(100, 100)); - } - - if (mMatAssetIdTxt != nullptr) - { - mMatAssetIdTxt->resize(Point2I(100, 0), Point2I(mEditCtrlRect.extent.x - 100, 18)); + RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4); + resized |= mEditButton->resize(shapeEdRect.point, shapeEdRect.extent); } return resized; } -void GuiInspectorTypeTerrainMaterialAssetPtr::setMaterialAsset(String assetId) -{ - mTargetObject->setDataField(mCaption, "", assetId); - - //force a refresh - SimObject* obj = mInspector->getInspectObject(); - mInspector->inspectObject(obj); -} - -DefineEngineMethod(GuiInspectorTypeTerrainMaterialAssetPtr, setMaterialAsset, void, (String assetId), (""), - "Gets a particular shape animation asset for this shape.\n" - "@param animation asset index.\n" - "@return Shape Animation Asset.\n") -{ - if (assetId == String::EmptyString) - return; - - return object->setMaterialAsset(assetId); -} - IMPLEMENT_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetId); ConsoleDocClass(GuiInspectorTypeTerrainMaterialAssetId, diff --git a/Engine/source/T3D/assets/TerrainMaterialAsset.h b/Engine/source/T3D/assets/TerrainMaterialAsset.h index dfa3c3ef1..86b6bc718 100644 --- a/Engine/source/T3D/assets/TerrainMaterialAsset.h +++ b/Engine/source/T3D/assets/TerrainMaterialAsset.h @@ -94,6 +94,8 @@ public: StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; } SimObjectPtr getMaterialDefinition() { return mMaterialDefinition; } + SimObjectPtr getFXMaterialDefinition() { return mFXMaterialDefinition; } + void setScriptFile(const char* pScriptFile); inline StringTableEntry getScriptFile(void) const { return mScriptFile; }; @@ -127,26 +129,23 @@ protected: }; DefineConsoleType(TypeTerrainMaterialAssetPtr, TerrainMaterialAsset) -DefineConsoleType(TypeMaterialAssetId, String) +DefineConsoleType(TypeTerrainMaterialAssetId, String) //----------------------------------------------------------------------------- // TypeAssetId GuiInspectorField Class //----------------------------------------------------------------------------- -class GuiInspectorTypeTerrainMaterialAssetPtr : public GuiInspectorField +class GuiInspectorTypeTerrainMaterialAssetPtr : public GuiInspectorTypeFileName { - typedef GuiInspectorField Parent; + typedef GuiInspectorTypeFileName Parent; public: - GuiControl* mMatEdContainer; - GuiBitmapButtonCtrl *mMatPreviewButton; - GuiTextEditCtrl *mMatAssetIdTxt; + GuiBitmapButtonCtrl* mEditButton; DECLARE_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetPtr); static void consoleInit(); virtual GuiControl* constructEditControl(); virtual bool updateRects(); - void setMaterialAsset(String assetId); }; class GuiInspectorTypeTerrainMaterialAssetId : public GuiInspectorTypeTerrainMaterialAssetPtr { diff --git a/Engine/source/T3D/fx/groundCover.cpp b/Engine/source/T3D/fx/groundCover.cpp index a9c975eec..e6d354d76 100644 --- a/Engine/source/T3D/fx/groundCover.cpp +++ b/Engine/source/T3D/fx/groundCover.cpp @@ -50,6 +50,7 @@ #include "renderInstance/renderDeferredMgr.h" #include "console/engineAPI.h" #include "T3D/assets/MaterialAsset.h" +#include "T3D/assets/TerrainMaterialAsset.h" /// This is used for rendering ground cover billboards. GFXImplementVertexFormat( GCVertex ) @@ -564,7 +565,7 @@ void GroundCover::initPersistFields() addField("shapeFilename", TypeFilename, Offset(mShapeName, GroundCover), MAX_COVERTYPES, "The cover shape filename. [Optional]", AbstractClassRep::FIELD_HideInInspectors); INITPERSISTFIELD_SHAPEASSET_ARRAY(Shape, MAX_COVERTYPES, GroundCover, "The cover shape. [Optional]"); - addField( "layer", TypeTerrainMaterialName, Offset( mLayer, GroundCover ), MAX_COVERTYPES, "Terrain material name to limit coverage to, or blank to not limit." ); + addField( "layer", TypeTerrainMaterialAssetId, Offset( mLayer, GroundCover ), MAX_COVERTYPES, "Terrain material assetId to limit coverage to, or blank to not limit." ); addField( "invertLayer", TypeBool, Offset( mInvertLayer, GroundCover ), MAX_COVERTYPES, "Indicates that the terrain material index given in 'layer' is an exclusion mask." ); @@ -1178,6 +1179,7 @@ GroundCoverCell* GroundCover::_generateCell( const Point2I& index, const bool typeIsShape = mShapeInstances[ type ] != NULL; const Box3F typeShapeBounds = typeIsShape ? mShapeInstances[ type ]->getShape()->mBounds : Box3F(); const F32 typeWindScale = mWindScale[type]; + StringTableEntry typeLayer = mLayer[type]; const bool typeInvertLayer = mInvertLayer[type]; diff --git a/Engine/source/T3D/fx/groundCover.h b/Engine/source/T3D/fx/groundCover.h index aba467810..906a96a7e 100644 --- a/Engine/source/T3D/fx/groundCover.h +++ b/Engine/source/T3D/fx/groundCover.h @@ -312,7 +312,7 @@ protected: /// The maximum world space elevation for placement. F32 mMaxElevation[MAX_COVERTYPES]; - /// Terrain material name to limit coverage to, or + /// Terrain material assetId to limit coverage to, or /// left empty to cover entire terrain. StringTableEntry mLayer[MAX_COVERTYPES]; diff --git a/Engine/source/terrain/terrMaterial.cpp b/Engine/source/terrain/terrMaterial.cpp index 289c9a16f..b25cf02b9 100644 --- a/Engine/source/terrain/terrMaterial.cpp +++ b/Engine/source/terrain/terrMaterial.cpp @@ -137,13 +137,19 @@ bool TerrainMaterial::onAdd() SimSet *set = Sim::getTerrainMaterialSet(); // Make sure we have an internal name set. - if ( !mInternalName || !mInternalName[0] ) - Con::warnf( "TerrainMaterial::onAdd() - No internal name set!" ); + if (!mInternalName || !mInternalName[0]) + { + Con::warnf("TerrainMaterial::onAdd() - No internal name set!"); + return false; + } else { SimObject *object = set->findObjectByInternalName( mInternalName ); - if ( object ) - Con::warnf( "TerrainMaterial::onAdd() - Internal name collision; '%s' already exists!", mInternalName ); + if (object) + { + Con::warnf("TerrainMaterial::onAdd() - Internal name collision; '%s' already exists!", mInternalName); + return false; + } } set->addObject( this ); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index cf331ac74..fc3e3576c 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript @@ -639,9 +639,18 @@ function AssetBrowser::loadDirectories( %this ) %dataItem = AssetBrowser-->filterTree.insertItem(AssetBrowser-->filterTree.modulesIdx, "data"); AssetBrowser-->filterTree.tagsIdx = AssetBrowser-->filterTree.insertItem(1, "Tags"); - if(!%this.selectMode) AssetBrowser-->filterTree.creatorIdx = AssetBrowser-->filterTree.insertItem(1, "Creator"); + AssetBrowser-->filterTree.clearSelection(); + + if(%this.selectMode) + { + AssetBrowser-->filterTree.addSelection(AssetBrowser-->filterTree.collectionsIdx); + AssetBrowser-->filterTree.addSelection(AssetBrowser-->filterTree.creatorIdx); + + AssetBrowser-->filterTree.hideSelection(); + } + %this.dirHandler.loadFolders("data", %dataItem); %this.loadCollectionSets(); @@ -750,20 +759,6 @@ function AssetBrowser::loadDirectories( %this ) function AssetBrowser::updateSelection( %this, %asset, %moduleName ) { - /*%isAssetBorder = 0; - eval("%isAssetBorder = isObject(AssetBrowser-->"@%asset@"Border);"); - if( %isAssetBorder ) - { - eval( "AssetBrowser-->"@%asset@"Border.setStateOn(1);"); - } - - %isAssetBorderPrevious = 0; - eval("%isAssetBorderPrevious = isObject(AssetBrowser-->"@%this.prevSelectedMaterialHL@"Border);"); - if( %isAssetBorderPrevious ) - { - eval( "AssetBrowser-->"@%this.prevSelectedMaterialHL@"Border.setStateOn(0);"); - }*/ - //If we had an existing selected assetDef, clear the reference if(isObject(AssetBrowser.selectedAssetDef)) AssetDatabase.releaseAsset(AssetBrowser.selectedAssetDef.getAssetId()); @@ -775,11 +770,13 @@ function AssetBrowser::updateSelection( %this, %asset, %moduleName ) if(strstr(%moduleName, "/") != -1) return; - //Otherwise, it's an asset so we'll select the definition while we're at it + //Check if this is an actual assetId, or if it's just a programmatic reference + //like what we use for the creator entries + if(AssetDatabase.isDeclaredAsset(AssetBrowser.selectedAsset)) + { + //Looks good, it's an asset so we'll select the definition while we're at it AssetBrowser.selectedAssetDef = AssetDatabase.acquireAsset(AssetBrowser.selectedAsset); - //AssetBrowser.selectedPreviewImagePath = %previewImagePath; - - //%this.prevSelectedMaterialHL = %asset; + } } function AssetBrowser::loadCollectionSets(%this) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript index f2ea27660..c402456cd 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript @@ -85,7 +85,7 @@ function NewAssetModuleBtn::onClick(%this) AssetBrowser_addModuleWindow.selectWindow(); } -function AssetBrowser::setupCreateNewAsset(%this, %assetType, %moduleName, %callback) +function AssetBrowser::setupCreateNewAsset(%this, %assetType, %moduleName, %callback, %nameOverride) { Canvas.pushDialog(AssetBrowser_newAsset); @@ -106,8 +106,12 @@ function AssetBrowser::setupCreateNewAsset(%this, %assetType, %moduleName, %call %this.newAssetSettings.assetType = %assetType; %this.newAssetSettings.moduleName = %moduleName; + %newAssetName = "New" @ %shortAssetTypeName; + if(%nameOverride !$= "") + %newAssetName = %nameOverride; + NewAssetPropertiesInspector.startGroup("General"); - NewAssetPropertiesInspector.addField("assetName", "New Asset Name", "String", "Name of the new asset", "New" @ %shortAssetTypeName, "", %this.newAssetSettings); + NewAssetPropertiesInspector.addField("assetName", "New Asset Name", "String", "Name of the new asset", %newAssetName, "", %this.newAssetSettings); //NewAssetPropertiesInspector.addField("AssetType", "New Asset Type", "List", "Type of the new asset", %assetType, "Component,Image,Material,Shape,Sound,State Machine", %newAssetSettings); //NewAssetPropertiesInspector.addField("friendlyName", "Friendly Name", "String", "Human-readable name of new asset", "", "", %this.newAssetSettings); diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript index 00f890cf1..7c50130b2 100644 --- a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript @@ -1244,6 +1244,15 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject %fileObject.FXMaterial.processed = true; %fileObject.FXMaterial.skip = true; } + else + { + //if after all that we still have no FXMaterial, just create a new one + %fxMat = new Material("TerrainFX_" @ %objectName) + { + mapTo = %objectName; + }; + %asset.add(%fxMat); + } %success = false; if(TamlWrite(%asset, %tamlpath)) diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript index fd1063618..1446d6d7d 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript @@ -474,11 +474,36 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat ) function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) { + //If we happen to have been handed an assetId, process it + if(AssetDatabase.isDeclaredAsset(%mat)) + { + %assetDef = AssetDatabase.acquireAsset(%mat); + %mat = %assetDef.getMaterialDefinition(); + } + // Skip over obviously bad cases. if ( !isObject( %mat ) || !%mat.isMemberOfClass( TerrainMaterial ) ) return; + //Lets validate it wasn't a generated stub. if so, we need to add an intermediate + //step to create the asset + %assetDef = AssetDatabase.acquireAsset(%mat.internalName); + if(%assetDef $= "") + { + %moduleSplit = strpos(%mat.internalName, ":"); + %moduleName = getSubStr(%mat.internalName, 0, %moduleSplit); + %assetName = getSubStr(%mat.internalName, %moduleSplit+1, -1); + if(ModuleDatabase.findModule(%moduleName) !$= "") + { + AssetBrowser.selectedModule = %moduleName; + } + + //we need to create an actual asset here + AssetBrowser.setupCreateNewAsset("TerrainMaterialAsset", AssetBrowser.selectedModule, "TerrainMaterialDlg.saveDirtyMaterial", %assetName); + return; + } + // Read out properties from the dialog. %newName = %this-->matNameCtrl.getText(); @@ -487,28 +512,28 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) //--- - %newDiffuse = %this-->texDiffuseMap.getBitmap(); - if(%newDiffuse $= $TerrainMaterialEditor::emptyMaterialImage || %newDiffuse $= %blankBitmap) + %newDiffuse = %this-->diffuseMapAssetId.text; + if(%newDiffuse $= "None") %newDiffuse = ""; //--- - %newNormal = %this-->texNormalMap.getBitmap(); - if(%newNormal $= $TerrainMaterialEditor::emptyMaterialImage || %newNormal $= %blankBitmap) + %newNormal = %this-->normalMapAssetId.text; + if(%newNormal $= "None") %newNormal = ""; //--- - %newormConfig = %this-->texORMConfigMap.getBitmap(); - if(%newormConfig $= $TerrainMaterialEditor::emptyMaterialImage || %newormConfig $= %blankBitmap) + %newormConfig = %this-->ORMMapAssetId.text; + if(%newormConfig $= "None") %newormConfig = ""; //--- - %newDetail = %this-->texDetailMap.getBitmap(); - if(%newDetail $= $TerrainMaterialEditor::emptyMaterialImage || %newDetail $= %blankBitmap) + %newDetail = %this-->detailMapAssetId.text; + if(%newDetail $= "None") %newDetail = ""; //--- - %newMacro = %this-->texMacroMap.getBitmap(); - if(%newMacro $= $TerrainMaterialEditor::emptyMaterialImage || %newMacro $= %blankBitmap) + %newMacro = %this-->macroMapAssetId.text; + if(%newMacro $= "None") %newMacro = ""; %detailSize = %this-->detSizeCtrl.getText(); From 85bb4cbff3943387c4368c7bcaa9adc47a55c0f5 Mon Sep 17 00:00:00 2001 From: JeffR Date: Wed, 30 Mar 2022 01:38:15 -0500 Subject: [PATCH 061/145] Adds cleanup of material and terrain material objects when creating a new asset of the respective type to avoid collisions when we immediately properly init the asset on creation Reorganizes the terrainMaterialDlg to use a split container for better usability, fixed some minor layout issues, and added in FX material fields to be able to edit those directly via the terrain mat editor Updated the terrainMaterialDlg save logic to better sequence the steps for saving to allow stable in-place creation of asset for stub materials due to missing references Updated the terrainMaterialDlg save logic to properly save out all the material effects stuff like footstep flags, effect colors, or sounds. --- .../scripts/assetTypes/material.tscript | 3 + .../assetTypes/terrainMaterial.tscript | 4 + .../gui/guiTerrainMaterialDlg.ed.gui | 1470 +++-------------- .../interfaces/terrainMaterialDlg.ed.tscript | 251 ++- 4 files changed, 442 insertions(+), 1286 deletions(-) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index fb6b8a4ad..27a3dc58d 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript @@ -21,6 +21,9 @@ function AssetBrowser::createMaterialAsset(%this) TamlWrite(%asset, %tamlpath); + //cleanup before proper init'ing + %assetName.delete(); + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript index 8fc9e21f9..c9c9ba83d 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript @@ -48,6 +48,10 @@ function AssetBrowser::createTerrainMaterialAsset(%this) TamlWrite(%asset, %tamlpath); + //cleanup before proper init'ing + %matDef.delete(); + %fxMatDef.delete(); + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui index 4eef5308f..014771aed 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui @@ -1,1922 +1,894 @@ //--- OBJECT WRITE BEGIN --- $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) { - position = "0 0"; extent = "1024 768"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultNonModalProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "1"; - canSave = "1"; canSaveDynamicFields = "1"; new GuiWindowCtrl() { text = "Terrain Materials Editor"; - resizeWidth = "1"; - resizeHeight = "1"; - canMove = "1"; - canClose = "1"; canMinimize = "0"; canMaximize = "0"; - canCollapse = "0"; closeCommand = "TerrainMaterialDlg.dialogCancel();"; edgeSnap = "0"; docking = "None"; margin = "4 4 4 4"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; - position = "315 118"; - extent = "394 532"; + position = "222 59"; + extent = "457 639"; minExtent = "358 452"; horizSizing = "center"; vertSizing = "center"; profile = "ToolsGuiWindowProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; + + new GuiSplitContainer() { + splitPoint = "182 100"; + position = "3 27"; + extent = "450 579"; + horizSizing = "width"; + profile = "ToolsGuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; + + new GuiPanel() { + docking = "Client"; + extent = "180 579"; + profile = "ToolsGuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; + internalName = "Panel1"; new GuiContainer() { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "6 25"; - extent = "189 64"; - minExtent = "8 2"; + position = "6 -2"; + extent = "179 18"; horizSizing = "width"; - vertSizing = "bottom"; profile = "inspectorStyleRolloutDarkProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiTextCtrl() { text = "Terrain Materials"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "5 0"; extent = "91 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:new_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "160 2"; + BitmapAsset = "ToolsModule:new_n_image"; + position = "150 3"; extent = "15 15"; - minExtent = "8 2"; horizSizing = "left"; vertSizing = "top"; profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.newMat();"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:delete_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "173 2"; + BitmapAsset = "ToolsModule:delete_n_image"; + position = "163 3"; extent = "15 15"; - minExtent = "8 2"; horizSizing = "left"; vertSizing = "top"; profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.deleteMat();"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; }; + new GuiControl() { + position = "6 26"; + extent = "177 545"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiDefaultProfile"; + tooltipProfile = "ToolsGuiToolTipProfile"; + isContainer = "1"; + + new GuiScrollCtrl() { + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + extent = "174 549"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiScrollProfile"; + tooltipProfile = "ToolsGuiToolTipProfile"; + + new GuiTreeViewCtrl() { + itemHeight = "21"; + mouseDragging = "0"; + multipleSelections = "0"; + deleteObjectAllowed = "0"; + dragToItemAllowed = "0"; + showRoot = "0"; + showObjectIds = "0"; + showClassNames = "0"; + showObjectNames = "0"; + position = "1 1"; + extent = "224 42"; + profile = "ToolsGuiTreeViewProfile"; + tooltipProfile = "ToolsGuiToolTipProfile"; + internalName = "matLibTree"; + class = "TerrainMaterialTreeCtrl"; + }; + }; + }; + }; + new GuiPanel() { + docking = "Client"; + position = "184 0"; + extent = "266 579"; + profile = "ToolsGuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; + internalName = "panel2"; + new GuiContainer() { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "202 26"; - extent = "185 463"; - minExtent = "8 2"; - horizSizing = "left"; + position = "-7 0"; + extent = "274 577"; + horizSizing = "width"; vertSizing = "height"; profile = "inspectorStyleRolloutProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; internalName = "matSettingsParent"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiBitmapCtrl() { - bitmap = "ToolsModule:separator_v_image"; - color = "White"; - wrap = "0"; + BitmapAsset = "ToolsModule:separator_v_image"; position = "1 0"; - extent = "183 2"; - minExtent = "8 2"; + extent = "271 2"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Name"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "8 22"; extent = "44 17"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiDefaultProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "39 21"; - extent = "143 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; + extent = "227 18"; profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; altCommand = "TerrainMaterialDlg.setMaterialName( $ThisControl.getText() );"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "matNameCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Material Properties"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "8 0"; extent = "117 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiInspectorTitleTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiContainer(DiffuseMapContainer) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "6 43"; - extent = "185 75"; - minExtent = "8 2"; + extent = "261 75"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiCheckBoxCtrl() { text = " Use Side Projection"; - groupNum = "-1"; - buttonType = "ToggleButton"; - useMouseEvents = "0"; position = "55 54"; extent = "119 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiCheckBoxProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; internalName = "sideProjectionCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapCtrl() { - bitmapAsset = "ToolsModule:unknownImage_image"; - color = "255 255 255 255"; - wrap = "0"; + BitmapAsset = "ToolsModule:unknownImage_image"; position = "1 1"; extent = "47 47"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; internalName = "texDiffuseMap"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:cubemapBtnBorder_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; + BitmapAsset = "ToolsModule:cubemapBtnBorder_n_image"; position = "1 1"; extent = "48 48"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.updateTextureMap(\"DiffuseMap\");"; tooltipProfile = "ToolsGuiDefaultProfile"; tooltip = "Change the Active Diffuse Map for this layer"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Diffuse"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "56 -3"; extent = "39 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "EditorTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "None"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "56 16"; - extent = "116 17"; - minExtent = "8 2"; + extent = "205 17"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "diffuseMapAssetId"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiButtonCtrl() { text = "Edit"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "116 0"; + position = "204 0"; extent = "40 16"; - minExtent = "8 2"; horizSizing = "left"; - vertSizing = "bottom"; profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.updateTextureMap(\"DiffuseMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:delete_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "159 0"; + BitmapAsset = "ToolsModule:delete_n_image"; + position = "247 0"; extent = "16 16"; - minExtent = "8 2"; horizSizing = "left"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.clearTextureMap(\"DiffuseMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Size"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "132 35"; extent = "39 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; text = "200"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "94 34"; extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "baseSizeCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; }; new GuiBitmapCtrl() { - bitmapAsset = "ToolsModule:separator_v_image"; - color = "255 255 255 255"; - wrap = "0"; + BitmapAsset = "ToolsModule:separator_v_image"; position = "6 116"; - extent = "175 2"; - minExtent = "8 2"; + extent = "266 2"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiContainer(DetailMapContainer) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "6 122"; - extent = "185 100"; - minExtent = "8 2"; + extent = "261 75"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiBitmapCtrl() { - bitmapAsset = "ToolsModule:unknownImage_image"; - color = "255 255 255 255"; - wrap = "0"; + BitmapAsset = "ToolsModule:unknownImage_image"; position = "1 1"; extent = "47 47"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; internalName = "texDetailMap"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:cubemapBtnBorder_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; + BitmapAsset = "ToolsModule:cubemapBtnBorder_n_image"; position = "1 1"; extent = "48 48"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.updateTextureMap(\"DetailMap\");"; tooltipProfile = "ToolsGuiDefaultProfile"; tooltip = "Change the active Detail Map for this layer."; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Detail"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "56 -3"; extent = "30 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "EditorTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "None"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "56 16"; - extent = "116 17"; - minExtent = "8 2"; + extent = "205 17"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "detailMapAssetId"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiButtonCtrl() { text = "Edit"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "116 0"; + position = "204 0"; extent = "40 16"; - minExtent = "8 2"; horizSizing = "left"; - vertSizing = "bottom"; profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.updateTextureMap(\"DetailMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:delete_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "159 0"; + BitmapAsset = "ToolsModule:delete_n_image"; + position = "247 0"; extent = "16 16"; - minExtent = "8 2"; horizSizing = "left"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.clearTextureMap(\"DetailMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Size"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "132 33"; extent = "39 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; text = "2"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "94 32"; extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "detSizeCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Strength"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "39 54"; extent = "46 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; text = "1"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "1 53"; extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "detStrengthCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Distance"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "132 54"; extent = "45 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; text = "50"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "94 53"; extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "detDistanceCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; }; new GuiBitmapCtrl() { - bitmapAsset = "ToolsModule:separator_v_image"; - color = "255 255 255 255"; - wrap = "0"; + BitmapAsset = "ToolsModule:separator_v_image"; position = "6 198"; - extent = "175 2"; - minExtent = "8 2"; + extent = "266 2"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiContainer(NormalMapContainer) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "6 205"; - extent = "185 100"; - minExtent = "8 2"; + extent = "261 100"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiBitmapCtrl() { - bitmapAsset = "ToolsModule:unknownImage_image"; - color = "255 255 255 255"; - wrap = "0"; + BitmapAsset = "ToolsModule:unknownImage_image"; position = "1 1"; extent = "47 47"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; internalName = "texNormalMap"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Normal"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "56 -3"; extent = "39 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "EditorTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:cubemapBtnBorder_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; + BitmapAsset = "ToolsModule:cubemapBtnBorder_n_image"; position = "1 1"; extent = "48 48"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.updateTextureMap(\"NormalMap\");"; tooltipProfile = "ToolsGuiDefaultProfile"; tooltip = "Change the active Normal Map for this layer."; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "None"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "56 15"; - extent = "116 17"; - minExtent = "8 2"; + extent = "205 17"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "normalMapAssetId"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiButtonCtrl() { text = "Edit"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "116 0"; + position = "204 0"; extent = "40 16"; - minExtent = "8 2"; horizSizing = "left"; - vertSizing = "bottom"; profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.updateTextureMap(\"NormalMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:delete_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "159 0"; + BitmapAsset = "ToolsModule:delete_n_image"; + position = "247 0"; extent = "16 16"; - minExtent = "8 2"; horizSizing = "left"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.clearTextureMap(\"NormalMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Parallax Scale"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "92 34"; extent = "77 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; text = "0"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "55 33"; extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "parallaxScaleCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiSliderCtrl(TerrainMaterialDlgBlendHeightBaseSlider) { range = "-0.5 0.5"; ticks = "0"; - snap = "0"; value = "0"; - useFillBar = "0"; - fillBarColor = "255 255 255 255"; - renderTicks = "1"; position = "39 61"; extent = "70 14"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiSliderProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; internalName = "blendHeightBaseSliderCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Blend Height"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "115 61"; - extent = "58 15"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; + extent = "68 15"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextEditCtrl(TerrainMaterialDlgBlendHeightBaseTextEdit) { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; text = "0"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "1 59"; extent = "35 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "blendHeightBaseTextEditCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiSliderCtrl(TerrainMaterialDlgBlendHeightContrastSlider) { range = "0 5"; ticks = "0"; - snap = "0"; value = "1"; - useFillBar = "0"; - fillBarColor = "255 255 255 255"; - renderTicks = "1"; position = "39 81"; extent = "70 14"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiSliderProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; internalName = "blendHeightContrastSliderCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Blend Contrast"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "115 81"; - extent = "58 15"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; + extent = "76 15"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextEditCtrl(TerrainMaterialDlgBlendHeightContrastTextEdit) { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; text = "1"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "1 79"; extent = "35 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "blendHeightContrastTextEditCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; }; new GuiBitmapCtrl() { - bitmapAsset = "ToolsModule:separator_v_image"; - color = "255 255 255 255"; - wrap = "0"; + BitmapAsset = "ToolsModule:separator_v_image"; position = "6 307"; - extent = "175 2"; - minExtent = "8 2"; + extent = "266 2"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiContainer(ORMMapContainer) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "6 314"; - extent = "185 64"; - minExtent = "8 2"; + extent = "261 64"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiBitmapCtrl() { - bitmapAsset = "ToolsModule:unknownImage_image"; - color = "255 255 255 255"; - wrap = "0"; + BitmapAsset = "ToolsModule:unknownImage_image"; position = "1 1"; extent = "47 47"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; internalName = "texORMConfigMap"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "ORM Config"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "56 -3"; extent = "64 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "EditorTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:cubemapBtnBorder_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; + BitmapAsset = "ToolsModule:cubemapBtnBorder_n_image"; position = "1 1"; extent = "48 48"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.updateTextureMap(\"ORMConfigMap\");"; tooltipProfile = "ToolsGuiDefaultProfile"; tooltip = "Change the active ORM Config Map for this layer."; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "None"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "56 15"; - extent = "116 17"; - minExtent = "8 2"; + extent = "205 17"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "ORMMapAssetId"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiButtonCtrl() { text = "Edit"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "116 0"; + position = "205 0"; extent = "40 16"; - minExtent = "8 2"; horizSizing = "left"; - vertSizing = "bottom"; profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.updateTextureMap(\"OrmConfigMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:delete_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "159 0"; + BitmapAsset = "ToolsModule:delete_n_image"; + position = "248 0"; extent = "16 16"; - minExtent = "8 2"; horizSizing = "left"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.clearTextureMap(\"ORMConfigMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiCheckBoxCtrl() { text = " Is sRGB"; - groupNum = "-1"; - buttonType = "ToggleButton"; - useMouseEvents = "0"; position = "55 32"; extent = "119 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiCheckBoxProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "isSRGB"; - canSave = "1"; - canSaveDynamicFields = "0"; + internalName = "IsSRGB"; }; new GuiCheckBoxCtrl() { text = " Invert Roughness"; - groupNum = "-1"; - buttonType = "ToggleButton"; - useMouseEvents = "0"; position = "55 48"; extent = "119 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiCheckBoxProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "invertRoughness"; - canSave = "1"; - canSaveDynamicFields = "0"; + internalName = "InvertRoughness"; }; }; new GuiBitmapCtrl() { - bitmapAsset = "ToolsModule:separator_v_image"; - color = "255 255 255 255"; - wrap = "0"; + BitmapAsset = "ToolsModule:separator_v_image"; position = "6 381"; - extent = "175 2"; - minExtent = "8 2"; + extent = "266 2"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiContainer(MacroMapContainer) { - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "6 388"; - extent = "185 72"; - minExtent = "8 2"; + extent = "261 72"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiBitmapCtrl() { - bitmapAsset = "ToolsModule:unknownImage_image"; - color = "255 255 255 255"; - wrap = "0"; + BitmapAsset = "ToolsModule:unknownImage_image"; position = "1 1"; extent = "47 47"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; internalName = "texMacroMap"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:cubemapBtnBorder_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; + BitmapAsset = "ToolsModule:cubemapBtnBorder_n_image"; position = "1 1"; extent = "48 48"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.updateTextureMap(\"MacroMap\");"; tooltipProfile = "ToolsGuiDefaultProfile"; tooltip = "Change the active Macro Map for this layer."; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Macro"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "56 -3"; extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "EditorTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "None"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; position = "56 17"; - extent = "116 17"; - minExtent = "8 2"; + extent = "192 17"; horizSizing = "width"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "macroMapAssetId"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiButtonCtrl() { text = "Edit"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "116 0"; + position = "204 0"; extent = "40 16"; - minExtent = "8 2"; horizSizing = "left"; - vertSizing = "bottom"; profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.updateTextureMap(\"MacroMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapButtonCtrl() { - bitmapAsset = "ToolsModule:delete_n_image"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - masked = "0"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "159 0"; + BitmapAsset = "ToolsModule:delete_n_image"; + position = "247 0"; extent = "16 16"; - minExtent = "8 2"; horizSizing = "left"; - vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.clearTextureMap(\"MacroMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Size"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "132 33"; extent = "39 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; text = "200"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "94 32"; extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "macroSizeCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Strength"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "39 54"; extent = "46 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; text = "0.7"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "1 53"; extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "macroStrengthCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextCtrl() { text = "Distance"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "132 54"; extent = "45 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; text = "500"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; anchorTop = "0"; - anchorBottom = "0"; anchorLeft = "0"; - anchorRight = "0"; position = "94 53"; extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; isContainer = "0"; internalName = "macroDistanceCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; }; }; + new GuiContainer(TerrainEffectsContainer) { + position = "6 460"; + extent = "265 97"; + horizSizing = "width"; + profile = "ToolsGuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; + + new GuiBitmapCtrl() { + BitmapAsset = "ToolsModule:separator_v_image"; + position = "2 2"; + extent = "276 2"; + horizSizing = "width"; + profile = "GuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiTextCtrl() { + text = "Effect Colors[0:1]"; + position = "1 22"; + extent = "86 15"; + profile = "ToolsGuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; }; - new GuiControl() { - position = "6 42"; - extent = "189 473"; - minExtent = "8 2"; + new GuiSwatchButtonCtrl() { + position = "89 22"; + extent = "16 16"; + tooltipProfile = "ToolsGuiToolTipProfile"; + command = "getColorF($ThisControl.color, \"TerrainMaterialDlg.updateEffectColor0\");"; + internalName = "effectColor0Swatch"; + }; + new GuiSwatchButtonCtrl() { + position = "109 22"; + extent = "16 16"; + tooltipProfile = "ToolsGuiToolTipProfile"; + command = "getColorF($ThisControl.color, \"TerrainMaterialDlg.updateEffectColor1\");"; + internalName = "effectColor1Swatch"; + }; + new GuiCheckBoxCtrl() { + text = "Show Footprints"; + position = "1 40"; + extent = "93 16"; + profile = "ToolsGuiCheckBoxProfile"; + tooltipProfile = "ToolsGuiDefaultProfile"; + tooltip = "Enables Player footprints on surfaces that use this Material."; + internalName = "showFootprintsCheckbox"; + }; + new GuiCheckBoxCtrl() { + text = "Show Dust"; + position = "110 40"; + extent = "68 16"; + profile = "ToolsGuiCheckBoxProfile"; + tooltipProfile = "ToolsGuiDefaultProfile"; + tooltip = "Enables dust particles on surfaces that use this Material."; + internalName = "showDustCheckbox"; + }; + new GuiTextCtrl() { + text = "Footstep sound"; + position = "1 59"; + extent = "77 15"; + profile = "ToolsGuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiPopUpMenuCtrl() { + text = "None"; + position = "80 58"; + extent = "184 18"; horizSizing = "width"; - vertSizing = "height"; + profile = "ToolsGuiPopUpMenuProfile"; + tooltipProfile = "ToolsGuiToolTipProfile"; + tooltip = "Determines the footstep sound to use when the Player walks on this Material."; + isContainer = "0"; + internalName = "footstepSoundPopup"; + }; + new GuiTextCtrl() { + text = "Impact sound"; + position = "1 79"; + extent = "64 15"; profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiScrollCtrl() { - willFirstRespond = "1"; - hScrollBar = "dynamic"; - vScrollBar = "dynamic"; - lockHorizScroll = "0"; - lockVertScroll = "0"; - constantThumbHeight = "0"; - childMargin = "0 0"; - mouseWheelScrollSpeed = "-1"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "0 0"; - extent = "189 454"; - minExtent = "8 2"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiPopUpMenuCtrl() { + text = "None"; + position = "80 78"; + extent = "184 18"; horizSizing = "width"; - vertSizing = "height"; - profile = "ToolsGuiScrollProfile"; - visible = "1"; - active = "1"; + profile = "ToolsGuiPopUpMenuProfile"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; - - new GuiTreeViewCtrl() { - tabSize = "16"; - textOffset = "2"; - fullRowSelect = "0"; - itemHeight = "21"; - destroyTreeOnSleep = "1"; - mouseDragging = "0"; - multipleSelections = "0"; - deleteObjectAllowed = "0"; - dragToItemAllowed = "0"; - clearAllOnSingleSelection = "1"; - showRoot = "0"; - useInspectorTooltips = "0"; - tooltipOnWidthOnly = "0"; - showObjectIds = "0"; - showClassNames = "0"; - showObjectNames = "0"; - showInternalNames = "1"; - showClassNameForUnnamedObjects = "0"; - compareToObjectID = "1"; - canRenameObjects = "1"; - renameInternal = "0"; - position = "1 1"; - extent = "136 147"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiTreeViewProfile"; - visible = "1"; - active = "1"; + tooltip = "Determines the impact sound to use when an object collides with this Material."; + isContainer = "0"; + internalName = "impactSoundPopup"; + }; + new GuiTextCtrl() { + text = "Effects"; + position = "2 4"; + extent = "38 18"; + profile = "EditorTextProfile"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "matLibTree"; - class = "TerrainMaterialTreeCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; + isContainer = "0"; + }; + }; }; }; }; new GuiButtonCtrl() { text = "Apply&Select"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "202 494"; + position = "269 612"; extent = "98 22"; - minExtent = "8 2"; horizSizing = "left"; vertSizing = "top"; profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.dialogApply();"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiButtonCtrl() { text = "Cancel"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "307 494"; + position = "374 612"; extent = "80 22"; - minExtent = "8 2"; horizSizing = "left"; vertSizing = "top"; profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; command = "TerrainMaterialDlg.dialogCancel();"; tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; }; new GuiBitmapCtrl() { - bitmapAsset = "ToolsModule:inactive_overlay_image"; - color = "255 255 255 255"; - wrap = "0"; - position = "199 23"; - extent = "190 367"; - minExtent = "8 2"; + BitmapAsset = "ToolsModule:inactive_overlay_image"; + position = "277 23"; + extent = "190 474"; horizSizing = "left"; vertSizing = "height"; profile = "ToolsGuiDefaultProfile"; visible = "0"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; isContainer = "1"; internalName = "inactiveOverlay"; hidden = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; new GuiTextCtrl() { text = "Inactive"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "0 151"; + position = "0 205"; extent = "190 64"; - minExtent = "8 2"; horizSizing = "width"; vertSizing = "center"; profile = "ToolsGuiTextCenterProfile"; - visible = "1"; - active = "1"; tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; internalName = "inactiveOverlayDlg"; - canSave = "1"; - canSaveDynamicFields = "0"; }; }; }; diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript index 1446d6d7d..745ee906a 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript @@ -109,6 +109,31 @@ function TerrainMaterialDlg::onWake( %this ) %item = %matLibTree.getFirstRootItem(); %matLibTree.expandItem( %item ); + //Sounds + %this-->footstepSoundPopup.clear(); + %this-->impactSoundPopup.clear(); + + %sounds = "" TAB "" TAB "" TAB "" TAB ""; // Default sounds + + %assetQuery = new AssetQuery(); + AssetDatabase.findAssetType(%assetQuery, "SoundAsset"); + + %count = %assetQuery.getCount(); + // Get custom sound assets + for(%i=0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + %sounds = %sounds TAB %assetId; + } + + %count = getFieldCount(%sounds); + for (%i = 0; %i < %count; %i++) + { + %name = getField(%sounds, %i); + %this-->footstepSoundPopup.add(%name); + %this-->impactSoundPopup.add(%name); + } + %this.activateMaterialCtrls( true ); } @@ -150,18 +175,8 @@ function TerrainMaterialDlg::dialogApply( %this ) %mat.delete(); } - // Make sure we save any changes to the current selection. - %this.saveDirtyMaterial( %this.activeMat ); - - // Delete the snapshot. - TerrainMaterialDlgSnapshot.delete(); - // Remove ourselves from the canvas. - Canvas.popDialog( TerrainMaterialDlg ); - - call( %this.onApplyCallback, %this.activeMat, %this.matIndex ); - - TerrainMaterialDlg.matDirty = false; + %this.prepSaveDirtyMaterial(); } //----------------------------------------------------------------------------- @@ -171,7 +186,7 @@ function TerrainMaterialDlg::dialogCancel( %this ) if(TerrainMaterialDlg.matDirty) { toolsMessageBoxYesNo("Save Dirty Material?", "The current material has been modified. Do you wish save your changes?", - "TerrainMaterialDlg.saveDirtyMaterial(" @ %this-->matLibTree.getSelectedItem() @ ");TerrainMaterialDlg.closeDialog();", "TerrainMaterialDlg.closeDialog();"); + "TerrainMaterialDlg.prepSaveDirtyMaterial("@%this-->matLibTree.getSelectedItem()@");TerrainMaterialDlg.closeDialog();", "TerrainMaterialDlg.closeDialog();"); } else { @@ -380,13 +395,13 @@ function TerrainMaterialTreeCtrl::onSelect( %this, %item ) if(TerrainMaterialDlg.matDirty) { toolsMessageBoxYesNo("Save Dirty Material?", "The current material has been modified. Do you wish save your changes?", - "TerrainMaterialDlg.saveDirtyMaterial(" @ TerrainMaterialDlg.previousMat @ ");TerrainMaterialDlg.setActiveMaterial(" @ %item @ ");", + "TerrainMaterialDlg.prepSaveDirtyMaterial(" @ TerrainMaterialDlg.previousMat @ ");TerrainMaterialDlg.setActiveMaterial(" @ %item @ ");", "TerrainMaterialDlg.setActiveMaterial(" @ %item @ ");"); } else { - TerrainMaterialDlg.setActiveMaterial( %item ); -} + TerrainMaterialDlg.setActiveMaterial( %item ); + } } //----------------------------------------------------------------------------- @@ -461,6 +476,32 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat ) %this-->isSRGB.setValue( %mat.isSRGB ); %this-->invertRoughness.setValue( %mat.invertRoughness ); + //FX material stuffs + if(AssetDatabase.isDeclaredAsset(%mat.internalName)) + { + %asset = AssetDatabase.acquireAsset(%mat.internalName); + %fxMat = %asset.getFXMaterialDefinition(); + if(isObject(%fxMat)) + { + %this-->effectColor0Swatch.color = %fxMat.effectColor[0]; + %this-->effectColor1Swatch.color = %fxMat.effectColor[1]; + + %this-->showFootprintsCheckbox.setValue(%fxMat.showFootprints); + %this-->showDustCheckbox.setValue(%fxMat.showDust); + %this.updateSoundPopup("Footstep", %fxMat.footstepSoundId, %fxMat.customFootstepSound); + %this.updateSoundPopup("Impact", %fxMat.impactSoundId, %fxMat.customImpactSound); + } + else + { + %this-->effectColor0Swatch.color = "1 1 1 1"; + %this-->effectColor1Swatch.color = "1 1 1 1"; + %this-->showFootprintsCheckbox.setValue(0); + %this-->showFootprintsCheckbox.setValue(0); + %this.updateSoundPopup("Footstep", 0, ""); + %this.updateSoundPopup("Impact", 0, ""); + } + } + %this.activateMaterialCtrls( true ); } else @@ -470,40 +511,133 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat ) } } -//----------------------------------------------------------------------------- - -function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) +function TerrainMaterialDlg::updateSoundPopup(%this, %type, %defaultId, %customName) { - //If we happen to have been handed an assetId, process it - if(AssetDatabase.isDeclaredAsset(%mat)) + %ctrl = TerrainMaterialDlg.findObjectByInternalName( %type @ "SoundPopup", true ); + + switch (%defaultId) { - %assetDef = AssetDatabase.acquireAsset(%mat); - %mat = %assetDef.getMaterialDefinition(); + case 0: %name = ""; + case 1: %name = ""; + case 2: %name = ""; + case 3: %name = ""; + default: + if (%customName $= "") + %name = ""; + else + %name = %customName; + } + + %r = %ctrl.findText(%name); + if (%r != -1) + %ctrl.setSelected(%r, false); + else + %ctrl.setText(%name); +} + +function TerrainMaterialDlg::getBehaviorSound(%this, %type, %sound) +{ + %defaultId = -1; + %customName = ""; + + switch$ (%sound) + { + case "": %defaultId = 0; + case "": %defaultId = 1; + case "": %defaultId = 2; + case "": %defaultId = 3; + default: %customName = %sound; } - // Skip over obviously bad cases. - if ( !isObject( %mat ) || - !%mat.isMemberOfClass( TerrainMaterial ) ) - return; - - //Lets validate it wasn't a generated stub. if so, we need to add an intermediate - //step to create the asset - %assetDef = AssetDatabase.acquireAsset(%mat.internalName); - if(%assetDef $= "") + return %defaultId TAB %customName; +} + +function TerrainMaterialDlg::updateEffectColor0(%this, %color) +{ + %this-->effectColor0Swatch.color = %color; +} + +function TerrainMaterialDlg::updateEffectColor1(%this, %color) +{ + %this-->effectColor1Swatch.color = %color; +} +//----------------------------------------------------------------------------- +function TerrainMaterialDlg::prepSaveDirtyMaterial(%this, %material) +{ + if(%material $= "") + %material = %this.activeMat; + + if(!isObject(%material)) { - %moduleSplit = strpos(%mat.internalName, ":"); - %moduleName = getSubStr(%mat.internalName, 0, %moduleSplit); - %assetName = getSubStr(%mat.internalName, %moduleSplit+1, -1); + error("TerrainMaterialDlg::prepSaveDirtyMaterial() - active material is not a valid object"); + return; + } + if(!AssetDatabase.isDeclaredAsset(%material.internalName)) + { + //No valid asset, so we probably generated it as a stub due to a leftover + //reference. Let's generate a new asset + %assetId = %material.internalName; + + %moduleSplit = strpos(%material.internalName, ":"); + %moduleName = getSubStr(%material.internalName, 0, %moduleSplit); + %assetName = getSubStr(%material.internalName, %moduleSplit+1, -1); if(ModuleDatabase.findModule(%moduleName) !$= "") { AssetBrowser.selectedModule = %moduleName; } - //we need to create an actual asset here + //Clear the stub + TerrainMaterialSet.remove(%material); + %material.delete(); + + %oldMat = TerrainMaterialSet.findObjectByInternalName( %assetId ); + AssetBrowser.setupCreateNewAsset("TerrainMaterialAsset", AssetBrowser.selectedModule, "TerrainMaterialDlg.saveDirtyMaterial", %assetName); + } + else + { + %assetDef = AssetDatabase.acquireAsset(%material.internalName); + + //If we somehow don't have an FX material, make one + %fxMat = %assetDef.getFXMaterialDefinition(); + if(!isObject(%fxMat)) + { + %fxMat = new Material("TerrainFX_" @ %assetDef.assetName){ + mapTo = %assetDef.assetName; + }; + + %assetDef.add(%fxMat); + } + + // Make sure we save any changes to the current selection. + %this.saveDirtyMaterial( %material.internalName ); + } +} + +function TerrainMaterialDlg::saveDirtyMaterial( %this, %materialAssetId ) +{ + %assetDef = ""; + %mat = ""; + + //If we happen to have been handed an assetId, process it + if(AssetDatabase.isDeclaredAsset(%materialAssetId)) + { + %assetDef = AssetDatabase.acquireAsset(%materialAssetId); + %mat = %assetDef.getMaterialDefinition(); + } + else + { + error("TerrainMaterialDlg::saveDirtyMaterial() - attempting to save invalid assetId: " @ %materialAssetId); return; } + // Skip over obviously bad cases. + if ( !isObject( %mat ) || + !%mat.isMemberOfClass( TerrainMaterial ) ) + return; + + %this.activeMat = %mat; + // Read out properties from the dialog. %newName = %this-->matNameCtrl.getText(); @@ -552,6 +686,17 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %isSRGB = %this-->isSRGB.getValue(); %invertRoughness = %this-->invertRoughness.getValue(); + //Effects + %effectColor0 = %this-->effectColor0Swatch.color; + %effectColor1 = %this-->effectColor1Swatch.color; + %showFootsteps = %this-->showFootprintsCheckbox.getValue(); + %showDust = %this-->showDustCheckbox.getValue(); + + %footstepSound = %this.getBehaviorSound("Footstep", %this-->footstepSoundPopup.getText()); + %impactSound = %this.getBehaviorSound("Impact", %this-->impactSoundPopup.getText()); + + %fxMat = %assetDef.getFXMaterialDefinition(); + // If no properties of this materials have changed, // return. @@ -573,7 +718,15 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %mat.blendHeightBase == %blendHeightBase && %mat.blendHeightContrast == %blendHeightContrast && %mat.isSRGB == %isSRGB && - %mat.invertRoughness == %invertRoughness && false) + %mat.invertRoughness == %invertRoughness && + %fxMat.effectColor[0] == %effectColor0 && + %fxMat.effectColor[1] == %effectColor1 && + %fxMat.showFootprints == %showFootsteps && + %fxMat.showDust == %showDust && + %fxMat.footstepSoundId == getField(%footstepSound, 0) && + %fxMat.customFootstepSound == getField(%footstepSound, 1) && + %fxMat.impactSoundId == getField(%impactSound, 0) && + %fxMat.customImpactSound == getField(%impactSound, 1) && false) return; // Make sure the material name is unique. @@ -614,11 +767,35 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %mat.isSRGB = %isSRGB; %mat.invertRoughness = %invertRoughness; + //effects + %fxMat.effectColor[0] = %effectColor0; + %fxMat.effectColor[1] = %effectColor1; + %fxMat.showFootprints = %showFootsteps; + %fxMat.showDust = %showDust; + %fxMat.footstepSoundId = getField(%footstepSound, 0); + %fxMat.customFootstepSound = getField(%footstepSound, 1); + %fxMat.impactSoundId = getField(%impactSound, 0); + %fxMat.customImpactSound = getField(%impactSound, 1); + //Save the material asset - %assetDef = AssetDatabase.acquireAsset(%mat.internalName); %assetDef.saveAsset(); + %this.schedule(32, "cleanupDirtyMaterial"); } +function TerrainMaterialDlg::cleanupDirtyMaterial(%this) +{ + // Delete the snapshot. + TerrainMaterialDlgSnapshot.delete(); + + // Remove ourselves from the canvas. + Canvas.popDialog( TerrainMaterialDlg ); + + call( %this.onApplyCallback, %this.activeMat, %this.matIndex ); + + TerrainMaterialDlg.matDirty = false; + + //%this.setActiveMaterial(%this.activeMat); +} //----------------------------------------------------------------------------- function TerrainMaterialDlg::snapshotMaterials( %this ) From c2857efe281b89c32a554d1e21fc9f5a8ccfc602 Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 31 Mar 2022 00:40:24 -0500 Subject: [PATCH 062/145] Adds logic to up-convert non-embedded terrain materials and materials to have embedded definitions --- .../scripts/materialEditor.ed.tscript | 19 ++++++++++++++++- .../interfaces/terrainMaterialDlg.ed.tscript | 21 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript index de003fdc8..cf2afc7b3 100644 --- a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript @@ -1963,7 +1963,24 @@ function MaterialEditorGui::save( %this ) MaterialEditorGui.copyMaterials( materialEd_previewMaterial, notDirtyMaterial ); %assetDef = AssetDatabase.acquireAsset(MaterialEditorGui.currentMaterialAsset); - %assetDef.saveAsset(); //write it out + %didEmbed = false; + %matScriptFile = %assetDef.getScriptPath(); + if(%matScriptFile !$= "") + { + //lets up-convert to embedded + %assetDef.add(%assetDef.materialDefinitionName); + %assetDef.scriptFile = ""; + %didEmbed = true; + } + + //write it out + if(%assetDef.saveAsset()) + { + if(%didEmbed) + { + fileDelete(%matScriptFile); //cleanup the old definition file + } + } } else { diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript index 745ee906a..e5fd3d27a 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript @@ -778,7 +778,26 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %materialAssetId ) %fxMat.customImpactSound = getField(%impactSound, 1); //Save the material asset - %assetDef.saveAsset(); + %didEmbed = false; + %matScriptFile = %assetDef.getScriptPath(); + if(%matScriptFile !$= "") + { + //lets up-convert to embedded + %assetDef.add(%mat); + %assetDef.add(%fxMat); + %assetDef.scriptFile = ""; + %didEmbed = true; + } + + //write it out + if(%assetDef.saveAsset()) + { + if(%didEmbed) + { + fileDelete(%matScriptFile); //cleanup the old definition file + } + } + %this.schedule(32, "cleanupDirtyMaterial"); } From bae6a3f514cecf2f2e425b920fb2e409e9d83e02 Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 31 Mar 2022 18:58:06 -0500 Subject: [PATCH 063/145] Fixes assignment of the mapTo field for terrain FX materials to point to the assetId rather than just the assetName, fixing the material mapping lookups Fixes project import to comply to above change Makes Material default mEffectColor to white instead of whatever default value it comes up with due to memset --- Engine/source/materials/materialDefinition.cpp | 3 +++ .../assetBrowser/scripts/assetTypes/terrainMaterial.tscript | 2 +- .../importers/pre40/T3Dpre4ProjectImporter.tscript | 6 +++--- .../scripts/interfaces/terrainMaterialDlg.ed.tscript | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Engine/source/materials/materialDefinition.cpp b/Engine/source/materials/materialDefinition.cpp index 7b3d2c7de..4204dfe63 100644 --- a/Engine/source/materials/materialDefinition.cpp +++ b/Engine/source/materials/materialDefinition.cpp @@ -229,6 +229,9 @@ Material::Material() dMemset(mEffectColor, 0, sizeof(mEffectColor)); + mEffectColor[0] = LinearColorF::WHITE; + mEffectColor[1] = LinearColorF::WHITE; + mFootstepSoundId = -1; mImpactSoundId = -1; mImpactFXIndex = -1; INIT_ASSET(CustomFootstepSound); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript index c9c9ba83d..8df0a1fa3 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript @@ -32,7 +32,7 @@ function AssetBrowser::createTerrainMaterialAsset(%this) %fxMatDef = new Material("TerrainFX_" @ %assetName) { - mapTo = %assetName; + mapTo = %moduleName @ ":" @ %assetName; footstepSoundId = 0; terrainMaterials = "1"; ShowDust = "1"; diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript index 7c50130b2..798d2be01 100644 --- a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript @@ -1203,7 +1203,7 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject { %fxMatObj = getField(%fxMatList, %i); %fxMatObjMapTo = findObjectField(%fxMatObj, "mapTo"); - if(%fxMatObjMapTo $= %objectName) + if(%fxMatObjMapTo $= %objectName || %fxMatObjMapTo $= %assetName) { %fileObject.FXMaterial = %fxMatObj; break; @@ -1215,7 +1215,7 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject if(%fileObject.FXMaterial !$= "") { //Ensure our mapto is up to date for any name sanitize/tweaks - setObjectField(%fileObject.FXMaterial, "mapTo", %objectName); + setObjectField(%fileObject.FXMaterial, "mapTo", %moduleName @ ":" @ %assetName); //we associated to an FX material, so process that now %objectDefinition = ""; @@ -1249,7 +1249,7 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject //if after all that we still have no FXMaterial, just create a new one %fxMat = new Material("TerrainFX_" @ %objectName) { - mapTo = %objectName; + mapTo = %moduleName @ ":" @ %assetName; }; %asset.add(%fxMat); } diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript index e5fd3d27a..1eb7af85d 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript @@ -603,7 +603,7 @@ function TerrainMaterialDlg::prepSaveDirtyMaterial(%this, %material) if(!isObject(%fxMat)) { %fxMat = new Material("TerrainFX_" @ %assetDef.assetName){ - mapTo = %assetDef.assetName; + mapTo = %material.internalName; }; %assetDef.add(%fxMat); From d044ae0702406ea7614b0241db948a131079ef95 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 3 Apr 2022 20:00:30 -0500 Subject: [PATCH 064/145] Removed unneeded default irradiance and prefilter cubemaps, and their convars Added getGUIPath console function to guiAsset Corrected console function documentation for getScriptPath in MaterialAsset Added getter console functions to PostEffectAsset Added getAnimationPath console function to PostEffectAsset Fixes handling of mapto with the reskin usage when generating preview renders for ShapeAssets Standardizes getShapeFile to getShapePath on ShapeAsset to better match formatting of other getters on assets Adds sanity checking for getStringWidth to prevent crash if there's an issue with the font being ready at time of request(from Az) Earlies out on rendering of impostors if it's the deferred bin to prevent unneeded duplicate rendering messing up results(from Az) Fixed duplicate naming of quality levels on LightingQualityList Added check so if _makePrettyResString is handed a 'human formatted' resolution string(as in, has x it can handle that properly Shifted yes/no and on/off option lists to globals for ease and consistency of handling on options menu Improves check for unapplied graphics options on options menu and applies them all at once Add sanitizing of variable names so getVariable doesn't have issues when looking up array variables in optionsMenu logic Adds better tracking of what options menu category is shown so refreshes don't reset it Add better handling for changing resolution in options menu and getting it to apply properly Adds better utility functions for setting bools vs optionsLists vs quality lists and updates options fields to use the most appropriate Removes redundant setting of $pref::SFX::channelVolume vars in defaults.tscript Removed unneeded extra logging from asset browser drag-n-drop actions Adds item to RMB context menu in AB to regenerate preview images Fixes move command for asset types(needed to properly reference the full path of the associated files) and added it for shapes, animations and terrains Added logic so when the dropdown for selecting a target module on the Create New Asset window is changed, it forcefully updates the target path to point to the module to avoid erroneous paths being provided Adds proper clamping of values to Forest Editor's brush size in the editor bar. Could be set to below 1 even though it would visually clamp to 1. Temporarily disables fields and handling of 'open in Torsion'. Fixes bad pixel in gui/images/tab_border.png which was causing it to fail to generate bitmap array properly Makes the New GUI option from menubar in GUI Editor use same Create New Asset method as everything else Disables access to the CubemapDesc reflector field in the material editor as it's not nominally used now in favor of probes Adds proper loading of roughness and metalness fields in material editor Fixes the default ReflectProbePreviewMat to use a better base DiffuseMap (No Material) rather than the occluder Fixes disable display for some options in the advanced panel in the shape editor so they look more fitting to everything else Adds check to avoid spam of markItem errors in the event requested tree item is invalid Fixed remove material button and command in TerrainMaterial Editor --- Engine/source/T3D/assets/GUIAsset.cpp | 7 + Engine/source/T3D/assets/MaterialAsset.cpp | 3 +- Engine/source/T3D/assets/PostEffectAsset.cpp | 18 ++ .../source/T3D/assets/ShapeAnimationAsset.cpp | 6 + Engine/source/T3D/assets/ShapeAsset.cpp | 11 +- Engine/source/gfx/gfxTextureManager.cpp | 10 - Engine/source/gfx/gfxTextureManager.h | 5 - Engine/source/gui/core/guiTypes.cpp | 2 +- .../renderInstance/renderImposterMgr.cpp | 1 + .../core/rendering/Core_Rendering.tscript | 2 - .../rendering/images/default_irradiance.dds | Bin 131192 -> 0 bytes .../default_irradiance_image.asset.taml | 8 - .../rendering/images/default_prefilter.dds | Bin 131192 -> 0 bytes .../images/default_prefilter_image.asset.taml | 8 - .../rendering/scripts/graphicsOptions.tscript | 7 +- .../game/data/UI/guis/optionsMenu.tscript | 266 +++++++++++++----- Templates/BaseGame/game/data/defaults.tscript | 5 - .../assetBrowser/scripts/assetBrowser.tscript | 24 +- .../scripts/assetTypes/cpp.tscript | 2 +- .../scripts/assetTypes/cubemap.tscript | 2 +- .../scripts/assetTypes/gameObject.tscript | 2 +- .../scripts/assetTypes/gui.tscript | 6 +- .../scripts/assetTypes/image.tscript | 38 +-- .../scripts/assetTypes/level.tscript | 8 +- .../scripts/assetTypes/material.tscript | 51 ++-- .../scripts/assetTypes/postFX.tscript | 8 +- .../scripts/assetTypes/script.tscript | 10 +- .../scripts/assetTypes/shape.tscript | 55 ++-- .../scripts/assetTypes/shapeAnimation.tscript | 18 +- .../scripts/assetTypes/sound.tscript | 16 ++ .../scripts/assetTypes/terrain.tscript | 16 ++ .../assetTypes/terrainMaterial.tscript | 57 +++- .../assetBrowser/scripts/editAsset.tscript | 12 + .../assetBrowser/scripts/newAsset.tscript | 47 +++- .../assetBrowser/scripts/popupMenus.tscript | 10 +- .../forestEditor/forestEditToolbar.ed.gui | 2 +- .../forestEditor/forestEditorGui.tscript | 2 +- .../tools/gui/editorSettingsWindow.ed.tscript | 2 +- .../game/tools/gui/images/tab_border.png | Bin 276 -> 8877 bytes .../scripts/guiEditorCanvas.ed.tscript | 8 +- .../gui/guiMaterialPropertiesWindow.ed.gui | 1 + .../scripts/materialEditor.ed.tscript | 42 ++- .../ReflectProbePreviewMat.asset.taml | 2 +- .../gui/shapeEdAdvancedWindow.ed.gui | 2 + .../scripts/shapeEditor.ed.tscript | 6 +- .../scripts/editors/creator.ed.tscript | 1 + .../scripts/editors/terrainEditor.ed.tscript | 4 +- 47 files changed, 576 insertions(+), 237 deletions(-) delete mode 100644 Templates/BaseGame/game/core/rendering/images/default_irradiance.dds delete mode 100644 Templates/BaseGame/game/core/rendering/images/default_irradiance_image.asset.taml delete mode 100644 Templates/BaseGame/game/core/rendering/images/default_prefilter.dds delete mode 100644 Templates/BaseGame/game/core/rendering/images/default_prefilter_image.asset.taml diff --git a/Engine/source/T3D/assets/GUIAsset.cpp b/Engine/source/T3D/assets/GUIAsset.cpp index a8f4fe0f3..7c1aa1d0a 100644 --- a/Engine/source/T3D/assets/GUIAsset.cpp +++ b/Engine/source/T3D/assets/GUIAsset.cpp @@ -226,6 +226,13 @@ DefineEngineMethod(GUIAsset, getScriptPath, const char*, (), , { return object->getScriptPath(); } + +DefineEngineMethod(GUIAsset, getGUIPath, const char*, (), , + "Gets the GUI file path associated to this asset.\n" + "@return The full script file path.") +{ + return object->getGUIPath(); +} #endif //----------------------------------------------------------------------------- diff --git a/Engine/source/T3D/assets/MaterialAsset.cpp b/Engine/source/T3D/assets/MaterialAsset.cpp index 6eb4ea200..77b22cc24 100644 --- a/Engine/source/T3D/assets/MaterialAsset.cpp +++ b/Engine/source/T3D/assets/MaterialAsset.cpp @@ -449,8 +449,7 @@ DefineEngineStaticMethod(MaterialAsset, findMaterialDefinitionByAssetId, S32, (c DefineEngineMethod(MaterialAsset, getScriptPath, const char*, (), , - "Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n" - "@return The AssetId of the associated asset, if any.") + "Gets the script file path for the asset.") { return object->getScriptPath(); } diff --git a/Engine/source/T3D/assets/PostEffectAsset.cpp b/Engine/source/T3D/assets/PostEffectAsset.cpp index e20aedef7..2b8a7091c 100644 --- a/Engine/source/T3D/assets/PostEffectAsset.cpp +++ b/Engine/source/T3D/assets/PostEffectAsset.cpp @@ -206,3 +206,21 @@ void PostEffectAsset::setGLSLShaderFile(const char* pShaderFile) // Refresh the asset. refreshAsset(); } + +DefineEngineMethod(PostEffectAsset, getScriptPath, const char*, (), , + "Gets the script file path for the asset.") +{ + return object->getScriptPath(); +} + +DefineEngineMethod(PostEffectAsset, getHLSLShaderPath, const char*, (), , + "Gets the HLSL Shader file path for the asset.") +{ + return object->getHLSLShaderPath(); +} + +DefineEngineMethod(PostEffectAsset, getGLSLShaderPath, const char*, (), , + "Gets the GLSL Shader file path for the asset.") +{ + return object->getGLSLShaderPath(); +} diff --git a/Engine/source/T3D/assets/ShapeAnimationAsset.cpp b/Engine/source/T3D/assets/ShapeAnimationAsset.cpp index f7e1b6aa5..649fc7bca 100644 --- a/Engine/source/T3D/assets/ShapeAnimationAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAnimationAsset.cpp @@ -204,3 +204,9 @@ DefineEngineMethod(ShapeAnimationAsset, getAnimationCount, S32, (), , { return object->getAnimationCount(); } + +DefineEngineMethod(ShapeAnimationAsset, getAnimationPath, const char*, (), , + "Gets the Animation file path associated to this asset.") +{ + return object->getAnimationPath(); +} diff --git a/Engine/source/T3D/assets/ShapeAsset.cpp b/Engine/source/T3D/assets/ShapeAsset.cpp index fb3be2341..231d42cb9 100644 --- a/Engine/source/T3D/assets/ShapeAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAsset.cpp @@ -576,9 +576,12 @@ const char* ShapeAsset::generateCachedPreviewImage(S32 resolution, String overri // We need to create our own instance to render with. TSShapeInstance* shape = new TSShapeInstance(mShape, true); - if(overrideMaterial.isNotEmpty()) - shape->reSkin(overrideMaterial, mShape->materialList->getMaterialName(0)); - + if (overrideMaterial.isNotEmpty()) + { + Material *tMat = dynamic_cast(Sim::findObject(overrideMaterial)); + if (tMat) + shape->reSkin(tMat->mMapTo, mShape->materialList->getMaterialName(0)); + } // Animate the shape once. shape->animate(0); @@ -676,7 +679,7 @@ DefineEngineMethod(ShapeAsset, getAnimation, ShapeAnimationAsset*, (S32 index), return object->getAnimation(index); } -DefineEngineMethod(ShapeAsset, getShapeFile, const char*, (), , +DefineEngineMethod(ShapeAsset, getShapePath, const char*, (), , "Gets the shape's file path\n" "@return The filename of the shape file") { diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index 8341b1b6c..733f3ba7f 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -46,8 +46,6 @@ S32 GFXTextureManager::smTextureReductionLevel = 0; String GFXTextureManager::smMissingTexturePath(Con::getVariable("$Core::MissingTexturePath")); String GFXTextureManager::smUnavailableTexturePath(Con::getVariable("$Core::UnAvailableTexturePath")); String GFXTextureManager::smWarningTexturePath(Con::getVariable("$Core::WarningTexturePath")); -String GFXTextureManager::smDefaultIrradianceCubemapPath(Con::getVariable("$Core::DefaultIrradianceCubemap")); -String GFXTextureManager::smDefaultPrefilterCubemapPath(Con::getVariable("$Core::DefaultPrefilterCubemap")); String GFXTextureManager::smBRDFTexturePath(Con::getVariable("$Core::BRDFTexture")); GFXTextureManager::EventSignal GFXTextureManager::smEventSignal; @@ -75,14 +73,6 @@ void GFXTextureManager::init() "The file path of the texture used to warn the developer.\n" "@ingroup GFX\n" ); - Con::addVariable("$Core::DefaultIrradianceCubemap", TypeRealString, &smDefaultIrradianceCubemapPath, - "The file path of the texture used as the default irradiance cubemap for PBR.\n" - "@ingroup GFX\n"); - - Con::addVariable("$Core::DefaultPrefilterCubemap", TypeRealString, &smDefaultPrefilterCubemapPath, - "The file path of the texture used as the default specular cubemap for PBR.\n" - "@ingroup GFX\n"); - Con::addVariable("$Core::BRDFTexture", TypeRealString, &smBRDFTexturePath, "The file path of the texture used as the default irradiance cubemap for PBR.\n" "@ingroup GFX\n"); diff --git a/Engine/source/gfx/gfxTextureManager.h b/Engine/source/gfx/gfxTextureManager.h index 5e4d7a070..90a8a4bc6 100644 --- a/Engine/source/gfx/gfxTextureManager.h +++ b/Engine/source/gfx/gfxTextureManager.h @@ -75,9 +75,6 @@ public: /// Provide the path to the texture used to warn the developer static const String& getWarningTexturePath() { return smWarningTexturePath; } - static const String& getDefaultIrradianceCubemapPath() { return smDefaultIrradianceCubemapPath; } - static const String& getDefaultPrefilterCubemapPath() { return smDefaultPrefilterCubemapPath; } - static const String& getBRDFTexturePath() { return smBRDFTexturePath; } /// Update width and height based on available resources. @@ -217,8 +214,6 @@ protected: /// File path to the warning texture static String smWarningTexturePath; - static String smDefaultIrradianceCubemapPath; - static String smDefaultPrefilterCubemapPath; static String smBRDFTexturePath; GFXTextureObject *mListHead; diff --git a/Engine/source/gui/core/guiTypes.cpp b/Engine/source/gui/core/guiTypes.cpp index 85032a2ed..dd5874ee9 100644 --- a/Engine/source/gui/core/guiTypes.cpp +++ b/Engine/source/gui/core/guiTypes.cpp @@ -735,7 +735,7 @@ DefineEngineMethod( GuiControlProfile, getStringWidth, S32, (const char* string) "@param string String to get the width of." "@return width of the string in pixels." ) { - return object->mFont->getStrNWidth( string, dStrlen( string ) ); + return (object->mFont) ? object->mFont->getStrNWidth( string, dStrlen( string ) ) : -1; } DefineEngineMethod(GuiControlProfile, getBitmap, const char*, (), , "get name") diff --git a/Engine/source/renderInstance/renderImposterMgr.cpp b/Engine/source/renderInstance/renderImposterMgr.cpp index e0b8b3156..ab547e4fc 100644 --- a/Engine/source/renderInstance/renderImposterMgr.cpp +++ b/Engine/source/renderInstance/renderImposterMgr.cpp @@ -133,6 +133,7 @@ void RenderImposterMgr::_renderDeferred( const SceneRenderState *state, RenderDe void RenderImposterMgr::_innerRender( const SceneRenderState *state, RenderDeferredMgr *deferredBin ) { + if (deferredBin == NULL) return; PROFILE_SCOPE( RenderImposterMgr_InnerRender ); // Capture the GFX stats for this render. diff --git a/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript b/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript index ae6168dea..955c9d3da 100644 --- a/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript +++ b/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript @@ -5,8 +5,6 @@ function Core_Rendering::onCreate(%this) $Core::UnAvailableTexturePath = "core/rendering/images/unavailable"; $Core::WarningTexturePath = "core/rendering/images/warnMat"; $Core::CommonShaderPath = "core/rendering/shaders"; - $Core::DefaultIrradianceCubemap = "core/rendering/images/default_irradiance.dds"; - $Core::DefaultPrefilterCubemap = "core/rendering/images/default_prefilter.dds"; $Core::BRDFTexture = "core/rendering/images/brdfTexture.dds"; $Core::NoImageAssetFallback = "Core_Rendering:missingTexture_image"; diff --git a/Templates/BaseGame/game/core/rendering/images/default_irradiance.dds b/Templates/BaseGame/game/core/rendering/images/default_irradiance.dds deleted file mode 100644 index 4cd4bdc6e38dd1b4c541eab745ee60ee7d86740c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131192 zcmeFa>6c{Jb>&CERb4zWBa!YPewk*l5?v`b_Th@}*)>1F|Px0~I=iK|=eJ@@_W|7od{t#N) z>qQPo)^DGE?wjvDaNvCYz0Z8+GymN``L92-i7oY+|4RS=Gye@gKf?dz@w@xn@ALC# zJ|q7B^^5=ZpKN~SGyg9?#{ajxG$%{Y;^M3M0HQ$ptXm*a8ksdTNYwBX#?afF> z)s=P+n(4~4YDQYvwr04Uk!IJ_z}Bmd&s5E;Gb2@1Pb!^QWqeL*R!W^vbNJe8UP@hR zK~?T9N_mD_l5%fJD!pZ?%&w@abE{IFTa)Vin$+gkWqEnt@rNE5zxROrJ;zTULJ!*T zK?UAvr-yI2*4>*40z}KJKL zO=*ySZ3+B70}IhuxQMZE0pd6?7mNd82D-=r`(Stmj6LFq2h4tE{=0GQlliyWlfB%f zeD<-g3v)kY%+IQQV`-mkfPa0B888oQUobC=dQ1clcs!*1Ss5UIPdd&6e=IPasQ+O8 z&;#v%@@IMw^0Ve%DgN~SK6R`U_r2A=vAj?Au9JVK888oY3~=K>n1KX8JZPcT6leg4EP=h zGtl1y%m4)DcCRPXP6PS-dcfEpjXzcUzU=oO>v6oVFUGZRf`4-Z{5#Enj)Swh5AYeV z`g{JK9Sd*A-!}&CfZz3fqV{3$`|Kx?(aF~``R~GjNfO#j{%7cq{hKndf@ki z*!J_&gX|3G_|Mw!xc*_^+qjqD-!A(&&NqJU^H_U`{OEhuzPYkr_U&Dfy-@}*1`g=~ z?gx|~`$AuT9t+qQ$ow07n!m6A6a2F{4;WPcLHs+(e%A3$vi6=os|T{i0NW2{kAc?z zkH+uMe;$RO=efy!zCX_m&hw&ie^~bSOLO&rY@z;}8^{30!J+$s1$Qjqj)i`#`lt5) z9QV9*{}+w_{q^_f`HB60)cb?ReH-`E*>915b2aV(zaPXo!N4)#5%>p={{#4w>~_8r z@B92Q&#-en^7oJXwP@V8eICa>X1|YL_X8PYKsW~eWAnS?|Mb4!>h3*o*Li|#Ja(?@ z`7?SyG43P#D+iQ+zpH;d2H3ISk5>QSJXnu^>=-C9{`Kwq+_|62eAaQVUgwIAd9D7u z))ijk>gOMP%){EV_gkw6S(W?qwdt{JiEDco1cP z`F|At&1k=$;9q-``X|qW{P-VU2Z@gVajnB&1LJiMyY^w%z|!Y_>FXXz_7s0~z3WHe zx3SOjbL?yFh@aO4!}CD9F0TCU{MVlYhy01_AGq$DzW&#L&Brp}`QvNdLH!f_@BsNQ z>2d#d`Dgt-KgT}T{{#8M{a?%Tzc}yp>~`)GUjvQ!!Or^teb>I-HSh46Z+N{s z<_|M~u}?j)@juCL`+oL+MX&F>@z3r1B7U-C?AP&c0Dtp;Huk$r#ckJ{_K5RCU$`}jVP-UI4(QFqfIcHZ}?sNB7db`RWM=0OoY z6x&JuBKCcDugCIVnz8&VKaPLW{572OM)hA#)_-f0$G^*Z9b}{LI#8T_JOB5+AKweJ zYhN)t?}N1x>|JEPEA&iP&cWB+f* z|Hg0E!PxupJ(1|XV00Zkz87Zq0gc_?10;Kz-`KmzyvgqOfgRkG@y~#rG7pSD^q@Zj zMcoH31!Ld}dLXF(yyf55zrM7k*LZyY``DAoc-11Kj^NqJ04PgW9k8dtt8j z%>Mj>zyIU!gB!cnUfDZ1)`2qEjlYB3L+wt2o%L7#Y4EE;_8G8K-h-h2j(OyQsUDXAk-5L+HVLkbyX1g+jv98p=~{24nc zQ1`{{*xS+pcgWrXvuAIBvyUCzWHj#quyQ}aC>d%f%QO?ffRqVFB~`y zZV5B6jJk8YPt<)buKNu7y*m@KPowtJl4Ngzy@k4)s;!n#A$ytZO;Zuue)hKH8x;5{ z^`R>{%>pvebUolQkPmvGpyS}8OlkdxWneFk2RHRt$Y;Rzb?o^WnMda5z^=K+I6ngo zW^bYPEop$6?8@)Bjh*~0DK||ayYa(=#U)s&i3728VFRK_;J-XMDm+$O8L zXSc0!r}^namIqlGU=Jk6!8il!!u^2X7gTXgfct_t^Bw60neSq(8_eEB?VC~$*}+>) zus5aDFcq;)vbUsAZ%JMS_WHEsBDH0*?t~0Xs=C<5J&p1rO8o@8&yG-_^jH|_?w$?o~d?b%uXvg0Pdu{Tk7sNMuO<=JhU!`GgF z5f7Ic9I7-c-m={ua2&?&Wik%)q1@2eUJ0Q^A)W_oG%7RGwd-jo(q2hNuKZc-HSj|Pm9M>LZ^&eo0y{Jj$@8Z&pdMHT zBL0Tsk37i8fb!e%;Ghg}tc%%^_qNY`Lz<|$uY0{&N55yY``T;W9e2!LN9LhwU2-aT zpzP+s1U|?7^r9u>6tXam9x!EPzhuYf`G!qzFzb!4Bq_ z-8`_`lRH!s++N;;n14LXK)oxL1Is|{0W-iJ;8^I#0gi)%Ghmr-VjtgM_Xg_i>+ab# z_w|}opfXgVl%4!Fu$v0iniL#+$UlkiQAzejz)lYwzvdvz1LL329tg()*8}Q-@edsb zX4jQ_=j_Jq*_D4Fdku9r<*;S;Co8cg@Yw|RikGi{=s}Wy-0ce{Gy`CFT%(kt2=sqI_`I0cdflaoOmu9blo9xvf^W_2TQ(64r&PDt+ z)SR-~k7H{x_A%r@*~y>qAmnc=f9%1q44?;6WI5prMPGeCZ0uS=4>CTVufJ=l%E zirQDDSgp#GQvq8lPdV;>cJm-+uY;8$yO-my_zX-V3-kc&s-0v23Tn=}N3}=3S@%Tk!CA=SFM}VNP=&Rxq3)Ecziz<|5B4An zd(i*XSgHq-{LDfBIJlz>=(*8~W3NfQj~(3gpCr3^;A?N}N&Y?XU=R7#1LGg;LC^zH z23!vW8SuwLc3!Y(=SJ?lfPGMJJ{o%|U3*veMD0=QoU40W`zm^!vJAxh=7F(?{BZ{M z49!5-Wnc!!g#LJNR^kid2Q(Kvt%46A!0_ux*lS7fSELFP?)Y$+Y{GT51aAmg!1^G_0NBYt;m1ME0LDQ-4uCx?1Id1`qUSC1+3Xec zyov0Y{AG9mvF`n~HxI^2Ne}iQ6ET070p9~D{%Qt))C0pakZ)TL_zc7|0gOJ492hw; za$w}Z$bpdqBL_wfj2sv_Fmhnzz{r7-10x4U4vZWaIWTfy#~cQs>u^mRe7RNQ9Yh7%j5ZyJeH%1^4R2*e3qIhn8x$+ zQ{y?)*rfbaqzU<{J=D1Bv)F!i&se0#@Y%FS9^Yen0$XYqHMU1~JMF=i8XGr_V@pj; zP-8Obl$#tAuY7J?r~;(-t>Vf~C@Q2wC>z^OjXL2U$=E0y0>`sgWE(3*-zZ{GKsUGn8PuG9U z#sKU6xc`Use$@Zlk4o{}K3g>;pTu?Eh%&bK_q$_HDz@zNeHQ&ty*GKIBd_;KxDR4}=*Q+ykE-kb%!) z9}w5yGBB+Ep1*JG8_2&$$Ny;D*X)leyXVj0-YfYBX8>biIoKCuWgu_kV7wpf?}5*z z_Jf~A{Z+c}Bm219=h?pRaqI*A_?H;_va&yr-}Zk=eye?g-+7?-q@#U72gd`+eL;F( z=ra)YK;N-|I}Sh(Faz}9v)Bii{&D#yvHxfP=P1_QDa=0eulL-^uYJIAFg+I9F;Ra8 zwi^e-W1)b5hzE}a8SwS@wI4e6q5l27{|Nke?tsrC={VrV!f|(8xU&qT$3Y$oy5qrM z9Mt*`;5T;b0b^(W$CCSfWPRGmteF#u?a+<6`!Kj)TSRGoZ)B z>OocptOp*$Sg>P$uA_m0q z91Di^fo1^LiR}773;V)k2JHHXT_1`)unasNc>s3uPmn+M;0bu}1p2^xunRe0{XILk zdsG?Md%(_XJ{m@mwJ(EDNb%jCzi^?dhIGoT&>W1%}P;&YljE*v}-;u={gzD5># zfDAl=W8x=#26D`R&q3(Hq&$HPD8KW-*vUU0@f-UXu60qVzE9OYdCZ$pd-Oi}i!-a> z4?JK7Fcu8UKzOY%`?$C&yWI5wX23is!UyEQ^J_2UE_kqO+_R_nmEAlT z$7lAxo$m+N`ub{b{KZuEl^^dG@f{Opz~><9gI51B!QipbGN5At_J_>CF1=1l{?LOd zc>*3h0sbe@115T488CM8n+Ln$1GNXNl+`}wpTPI1=voKQcT)Ue-}`Z&>{O|@rtjAb z?E`mAu+y<{w;mUR-+8dh^XDxCPoNK!Kk~pbunQjSLJqtKp56G(1J7@@H}=GJUh?~M zJ?;C!*{_fv@6{FQ0s9~v3wAIT#(m(gl`;c%y*%;&8Q4`Q3q9DSV*xz?f8;@4b|DA5 z&<7^-U^nV-BDZM_+dh8qdj6r~UX*>SJ8SRxOPG6y?^szMtVqF)hmX<+@jV0I2Q}Fp z^nrO$QV(`v9M}c^U8uh)^k7nUBL}-DjDHV&Nb--P=h^qh?b!#N>xbFbeV!Zl$WE2< zZZ$KI*#~Yc^yf$Y#{}Vh6PE$KZxUxVx$8QFOhO_l@vg1onsQ0hRM$ zH~L_A!DS%wpdh=EgWcdakv|7+@|y=^@WJHSao+|WP?IVf^Q`Z2P9L!QL$eb4heWe@qmUL!x|72(_x znt^m51jj`-7P@OicyBSjUdZ?Q;`@i=t`F1$*9Xd9tf~ilFc$0q{~q+g9%R5YC3}zo zQ|!SQd>Eq#(D|yOIuJ*>iPd(T+1L5;_n%w_ z#^Ax2<^UN`55PY~{?G&P=VK4Xa(OUQh9U6ayYg{y`$Q5 ztk*H$a?k9OzlwR4Dhp7m4~C6}wm-nTo9>$NB;RME+&yG{2Rz{c-kU@ZjAdmY%E6S3 z!Gkg6K>6uGj_h8OsJSW0K7pQxz*}%4`&7U_sP@LcW&G%aLYYF{tr zq>4FKA3XznPm%BI1sT9xFFN-PGBAPrCXol|gK_l$87Nr>m;>{`^Lr001LN>OrTlrB zAivXO4(w3QDP(8;S@-_hW1K_Jhkei5lfSmKAN)JZz*H&&dA_fRaUjtLfMEz-0hqfn}g1r(2=T7q6C?f;l=iGKW#~H2{>zr4d|B5}pd9lz3%m6)@Kp#xt-C^a|95{ZL zgNdmUxGBdE4~*UTbIMN-@)3UlK2TFC_$P{GnLsb7 z2UFxP$|U(!mI2S7SAO##uL=RMXED#5Ae8~m0U7Zl1Cz?1%z*KG56JI5K>d+}Nq8_Bc#ta;#4BF_J5*4i_TZ%Y z_#M0FXYMWgd1Y^seqPe z**Ir0_X80>=dbeooa>Yxpa*j30rh}A;4U=sY3CA^1^3@Cr( zK~ZwZL2k_0@WJyJ z;6q^w{LqvW**!nmBmSWFT7Or2t$(?o{ogkRZZ`&SUMANAQ#cmV`CQQh1?&fPzF+X? zS%04a$DiXE;Kl*v=Nwy6A6N!*=z|<`5PFa=mcUMa^T7D00`>yf3&=iY?8*=JO32Ug zF5)jp)AK*V7+7NcLw?L>o#clH%mBs!^*}RV^=Ag?K@M~0`qhY0k4Q3+$Ci<4=VUvbt3zt z@N@2QUKbk1A9*m0pL1hJ9-#i1D>BRgb6_603}7x6pMg9)$d_Ud3h*J~hYwRlcmNfh z$ezjX*muHT!?_@jgSY2Tjsa6{Kgcnlp!-3~zt2D(`vJ{=*aNN)vNB-oj$b_>yBFC_ zo}Js0ljXmF-bekxP9^G(><`NSPWW{Uz;RGm|4e>24zdTxpZDXSW&rt*_>&pPBLjJi z1EB{6c;NY`;6uz`)cSjNZp%&;$DYkUh5ny%<3IQRw*MQ-kNMfTR>4mA3*i`m9#DSu zAk_nySJd}F9%DfsW1;e^2duwkK>6uGiR@lvH+lY;eM%~&Db(In!O;t1 z)ch+yILZF#{OtX~{m-?Utp3ct!2DFk zAA6we&VynJ9zZ3hGPu3^_?dSnW}v_RF?%%r;hsQx|Ht*Kw&m9hU<~A%7~Bs=J>crE z{N95se#<}s9uy)E%BZ`SWuOQjLVo&CRwXl_`5(s5?7Q7i>JAi8d zZtM&AD_Dz8_x}Uy|Bt~R^Z-04U@SC#mjQS%n7p8w+syA4|^YLjYPd49Q)hYkN(H`&yUQXH3p{nT?Psm2b4dRfdqdU z{FK%`_MnWf=|KhTl;wX={gL~SU&p@w-jDZvX?{EZ@%#V&{0H@q_=k*vL-{d(aa4cI z?dbWjEtSFVRK}L_`~y8e{{3~I#Bop5`|-Xn9Q%{?-x+^_>>sKB z`!g_zpI)T-Lk}`DK>o1ysqAa-V?8GA|6t!2@nh`c+NN52cl?)Gf9wOZ`Tc${$zOm6 zmj8esbGJ@m95mS&P(&7z888og{f*ypFqj|XUa;Tex@-QtHyryC_2+)y?fV~vUp?SC zfNJm7W5tit~I-B?!5OvmGK;o3fHD9sx@4*UXv>BS61guHQc|eEqLvfI4 z7ej60>+KZ&zWW>aJMrK3e}7$S_}`^CR}9~UQ#lXl$0Xhv_Fg=i5AIq!?>EB-UVq=- zhYT+ge(>K-j+jaPNqybV>3Okrynb7q$Nwh8c>(;|pV>ZeZFKV@_Q5jImj^yqr_UEL z3k!O`UGKXO@&Wg$EDzXf9_T~b3tuZT1UykzQr}B)lGie3y!Q9~|IV7uBdi|idvNB( zqxfJRr22yQ*B;4-mDmUNN5TvLZ}l8I*=DmE`zkz+WpgNF&N#jUr{ep7*_p6+Wx_mQ zjL`9c&ymODgFai!XKd96=f$u*gkuE8iYOC)yuiOV+Y|3i);4DJyve`I|D6?E2bAx> z>buZ3cV5B==S4ab>P6HS!+gMVcH8=3V?5RVZ$PU=`0coF%L@+9F)7FWji zddpJD5a$ioxuZE3hKlcldmp$BGr=D5V+7xsqX&F<2>ev059kf&MdSl|Bf1Z-eG&V> z@iOVfl9XpCc#!aep8Pn%-|Q{f95DLsKj(np8lm0?+orv+-f%v^3w?jo?LYM$D(8b{ z0sX;utn3;4EFb1#A243>{&XbWf6@yt<|3AP;=TFNx10k>1$IAYtj!6M^g`zdi28%? z3j6WWycp~Q-z^#B1D-$A=Wyvm;6>;IKX)nbLuxyNuT|#FU|$xIpMLGa`@NhOF!F() z@$PTJ3%m>JbFniYtT&=OAQSq2O`i{z34I37`+#leMX@sjbFOhrwRNnaK7+-ye_mp?HrJ&(Hfzm=88iBz_^7Vc)5}!Dq02CR%tNQTu{EK;#eAj{S&ypdX#2 zGWne+(YhF%_YHG=Bz!ZZ7c>w$U(7C}aXPkbKC2c1&|xv(s_Jg5h;50(YX zgJr>d&}Z=j9}1cWmx*b5;N^S6dk}7Ye`ND>9(rL%#=j$KGcl@&I1onM=Nl9eV&D zGzWM#72Bi-@FB{9_n-$4sH6wVpYUMT=DWrmmo^7{(g*K}%?s@N#I{KvEEk~rp4{y@x|WOK=}CorEF#!H_C?}5&N#@>6N8PFVr9&{`NnuD&f2ObpRL&Q%XoChUrO^)Ar5Uu~@=Y7ZgeuKS$ zKb#jfRKf?$pNqaodf?dvJkU8;QXb^++_{PT&VwfTV-KcU^uYO` z?Bw?{{+Qi+z^#n~ef-`Bzl9$1LHRjjNd$n`MUwP=bv#k54r7g8F?sodTy-`tapHUP5b57 z1hK98ko4nm^&$4+3Cs0_8F= zg>8Z#If!cycI2Sc_KH1FcE|rynA6(i*L(=J8J^g@@ZJM%-8|7Q51cpId%!tlcVUho zX2E-~2lFM+gE71_Ob^EK-k4>eZu70+eFEdh`=<1uj`uG3{zZb{JTQLqph$M*HxHCO z!9ODrH`)96y$`mH*8hM%x*km6h0Y0&ufsg(T+uEI-h-GQb7*P?Fpr?}V?HtE$DB%z ze**6ialVah2CHeiDS8j{>oj`&f1%OR`cJ_J&tF6aJbwuph`Eiw-0r%X$NUxKpwgi{ zzgyocTJJ9Dfv$fP`9MEH{@8=ZF$X3+(7CcPCn7!Ah57O5!EVeAMgBdQBZu>8j$xh* z@+&*|C(r}rpHzO#uc7>Sze?-hlmaq9er0$3#%}z^PJZ*CjQXnre&vqXV-Iv~GtA>Z zXdABq<+I?{!GI5z0jvpto-lsQkxmbkAM-^kKjw>7e$1cR$B%iW@SYSk>G*SamxlcL zn(-Iv#y{oxo6}NMk-aS?m9dw>pJeY!1s+7~0e=-4ploeRTi-72LA34{{ISpGfvy9B zOz65O=mT9Ffm>wY2@3qXDDdy5z`utA{}_e(k5iZ{K-nFC4jzy{Pl3Ncfq#lp{+45> z2cDf4ug00ou*sG|&%GKL* z`)$abT;C4sykR{DQ?T|EvhbMmK-UAooX7M)*G0g*r#d%y2EWdm3jT5B$GmZPADH}; zcrP%g{FpzXYW#(o@lVx_zu0JsvA2xf@hiLIS8in|f5(_3c6iXCW~7!;XTxYmrj?-I-_|+i*?Wkl(nm-W7cC9vC~; zfI$w7-8|Uk_>~>}$`1Z9@Q+jApTHa_sk=pf`2zfcIC&s$etf_ zKutLQNyneVJCK|+BwxXNA&!5lX8gsv@s}Kbx!E*!@GG~nPm6Ms-SO8@|432YyHdwz zlW}M9$Lm@8HI1>w8aAwZV!bEK>+jcp*@Zd2l^^px?^alV`Fa`c1>QDX>>QDYM>QDZPvXj3hRq$7*WByvZ9dpxzP6xb{=XTpJ zwyyTvW-?+blC9rNCkAM^VfJLW+K ze-3m0abD0o`7zf;fdc;&_>1JPR-{DLs!~S%$zMVJ$zKJ374;{7t>yT^URROb)PM)7 zfWHYJR0-y6{&4NmC$LtZ=l5&6?NWBE@8$USfM3@;!F={(DzY2@gyWyY9H+*Pd0@5n zmO;-CR_#u3s2&qX)>oI}*7~y3UE?H+IbV5B5ol?2bQ=`jfu^O@V(3^PChNf64Ke zYsO!xS5f;K>dxBNjUD{Tt?W&3lO1yGO>CQ}zp)4WU~fetZ=e}`hC+Vh_Wb67uIJ|1 zbzQ579qZeGUDvw6b^^7hlpXxa4t`_D{HMxp{6+FtFb9gVm!*u_SHNFE{j1=wHfmB+ zcH^%H{Eg|D-?+&RY2Dk>!d4Y=dk^~A$*=2FM>RKgTeI4&We0Y@o|mra1^zJ#>v_cN z#y^R9+{vHA{LbXhV}4We7cjS>&i{z{&XgVeCGeNQU#^xNd&StnUvvERW?hWEAq~{t z*qhQs?VD}N*jt_Hn4A1v%DAVoHFdFtz#Pig+?Z{>TK$~n#@Az5$B68@t_}EgeGjZ- zFahaW2jJH^-@&hQUW4D*!B2L_U&4GAW%85V@mEoQ*524_;3j(=++;WYCTgz&drL)b zueMBseH!dBvuDRP#qGcD<3<+tV4XT&bH9cc+5LJx{#PK*)h*M*`X<| zJ?4B>cFcQ;+ABNwjlC=pyW_8;{>tw7o8b5C#_jmQJ{`%k$NX*7zCGjB#pix`e!otq zXOFmD-MNMp`MH*ji8VLH?8aZfeBQ=x{6)-dSpvVY8-Jy0{MA}nYV`_Km3o7!Nux>C zrP-p$-jEh*uR`6YsSXwMw^8?4U{0{pgMM~?FXDD}=UR;syE2nI$GGZ|qgaUW?dU%5MDA?Ph|#4SrREy)7NoJgF|e z4%EYEC*@aWzfPxHuP|Wex^2Ghp53qK60>7%2W7|n_Fyk!PU9lyxMl4zpIwK>f-A_v-lio2A@ryy`S6Ib-g;R`v7*A`y%RJLhVbK zv)$M+r*j{BN$TKlXx)?S)5tvQ-bUWZ-qD&jrHi^7x3SO6OdD^+-IgA>69Q*%pl0y1 zm_Ov^XRCRVJr90g_X29qx=%Tgdk}jSb9VZ=*K3{~{0(DoHLdQ`sD0b9cN}{cb@%Ku zsJC%XOAp+=o>#y<+mTr?rxp8P+++{s`E^ZN&HI?H(dO&^W3gk*t0DIxdsEpfLUwXT z?8@B$Gr1vTeMUv*n0prNv#7U9nKQWO;Dc%g+u`zS@v`n*lhSi@tn=(zbFDkp>&mJ- za$iR7E10XC(z++uOUQf~y$){5vA12_t>(r)19szXIqqq&lG!u|=2%^s17}h*_7d_P_im>l zR`aIxkoQ?+o!rXoxQ*Gk7r?$SPt6Qa58sCtocI}nct3mhIJ>m*1YAor@@@$HfC^xbtzI$mKM{R#rLwc zi0>z~FpGSceBHCyJ$Esc`3lE6Xc&8|fx0&<;_Kdt>Rw0Q8{kf|&m-$(w|aL_Ei~mhd&SoYE4$RxRS4 zM3?zKcICFQZa6#mYd-TKdqw+w82h|uCpTpE?h3g>X60Q5H~7{hF0;t)#X?# z_#7+gM?4e2=+nr7kpm+KMh=V|7&$ON4S;H=g%tP`6D^s|SisuMIHSx8|-DCFmn)!@{ zf6ips)<1)_{T9#X@fkfQ|IA{v<^50f!1(Dw+J{Upz}`&rhhGOi==~+$U-QhVtv+Lc z?`3W6xg$Jl$7k+#AU>P7GvT>iJiF}IEUST=^89}5vk-0*xo|$vi*2PI@R<_#TuBDA zf6i+7cBhQlzo*YF!zbP1+3qUj`Tf@OM_bnup%3wA@PMD92mbR;wtU8>j^_#^!IO~P zp0~8;4!8g8m^|A~wvL}3R9yzV2U&Tj!w0XJpW_9%y#{z-tmMs>K4ZvdEVq$9gNxr8 zzJ(WjMmn2pyxTZx~izvgq7!x^(Zu;=sr zbNcqIKA+dm6qx;5hMIxE1Ntz`3-zSWiwt)7QQJoPj4gg=+b!ze&-W-Qwd%J+);#rKVp8o)Zp1N}a@@vbJt zcNPc9v!}NacbE(3L1re0{;Z$Tb0;{FMZeZ`w2izl5Bz(GJKKVr{GrlbxZ0=r(_cq^ z4CNehw?lQg5cbMHa@way9MP}dO-=W{% z(cg&c+|QWBZQtX2sC*B1sPOOLd&;qrydk^#fjJFqz3=R82|rH=zFA+TdU6NcX|D&d z8z)(_v<-jSpH#j5JN$k-jJ@w?_*=}6A6NRe&Vzo=RA%ve{&%dFS)Bdfv-i;5yZHDU z`cD3iwwSX4b@a^PHo5M7Mg|;nVhqXpUS^JBPVx@Tt^OQroNHiPJqo*igSZE?xp}FOkL=%Z z?BpNdK>_plJ(}XY4Car2C(n7(;DfOzw^0_Ao%|;Kw+>{AS#4f2&P|pj%vXoMm#H8J zne3R;uCNnjdPm*?!rY1UA(tUzPSuMwix{#P2YqhY4!)@1Lr#Uc6!C9}g!v`C51Dlf|NS~AWd(DzLHPbo75`nE%Q0pQd3W|X z&$%D_zK($cCQ_KP>tsD9EbP(_Yd{}^I7W8 zZQIY9#h?6M4*z}39{Zs4herIEQxu;~A%F01-2vYiekZM@Z{gpw&w0$>oGH#{x)Tlh z@5!AO<_ykp-eBY*)CA_0j`_`pan84l9AwGQN1SHu|Ju*poW14W-kuTj`C@M8!OHLn zp5*#ue(0RR>H&S=T-p({^TE$A9&OEoX#R1|L9R-Au?OC4r+%O8Z)Nji4sXoouHt;&{LJkj`QLThB)^** z9bQaw&47sCts}to1eD+A*5~~4I>)&4z|XxuhVdcv!PY16>lFCyc0Tyui~rWPY=fAG zd|&6mhZj00ezf)LC3qjWrix!nfgW(35i0h<)}G)R6oGVYikKtYhn@dCSyRl}k2M^A zT;=?F7`k=q0>B5qR)lTI9}4X7!>_YJAI2!Z7K?7VK1-lz9iN@^Cj3IChO+894qV5; zi)*~>KnZ@gJ_^3awNg~h3$7)jaz1dqA(hJl*Woe6KKON;vVGt>K0B22FphLjZ5zV);NS8F@L;+x|#9Y8yK7HakCT?99zs619mTLex`Sqb}YhL(uv}}uY=io!U-WWVc`7oC9K|N3( zvc1@iK8Xbn=!aA2lm9%3QP=KqyzytO=Y;jXLPhI;`E|e&TU!q)>4RT;lWWVFxGrbt zgL>e6;JT*jLF7ZrazGCvA7U?J_Rt6WoRyuJ&1xI6WqyvU;A;$ zHds^FuPIAEa#Y~OWaI<=!20eK*5K3}&;#|sGBJknat!OZhFmBv;@{HG8gqKy&$e#G1(*m7<8J}>a!=CPi# zDfYs$U|vjOZSw7Xa9*ef^x+Y_@SeDBvbLTny#*uIDBWI*_#Gw8dPrP&tHBXFx2ycRM3A~S{Dg1sykq6ET z^hrLF^+pao68kVGu@BZ86Bs8#FUB!WL|O2e;1;={tUvrV@Bx0rb#}Ggju-2i7k>mz zb(i4-75h=>ECrcZ419nm>cOM=!0~dtKER7;|6!hZUo_JZbF#L!hWRqq>`rS1--EEW z{V)~rJN<$O_UCVyQtgB$(xr+GRBK!*d zh<&hJ6p#&{i9Grw-wrYni4_af}yBy*~^Db@!vk~en2pu(g0GU$UVJ@VW&FI~7vuqdKg`9C z=fi^agdZo|SjjO{_n#S=U@okmgIXt;hp;YyS+$An4&*#CFPtAPAF&VCBcTsAHn1;t znuozYWO<=u*c|vZ&#ZB}&aSp#t%9>pi}>E+zM;zWM>9bmpvZ@fL?(VLA9zgVv*5Qu zCcGChcUWsXMG1a{W5lEQz~k%0e$)Ao^dcT7bPS97 zIfFY@-x~O9OIsP*kM9iG_nYA{W#B`Qi9y`MnCoD! zgEOHOe62c|+`8XO`V!|P&IEgBP#(Mwet)qp2_I%wZG3cNq(9e)j~@p65RGT9-bwDb z&I#s-ldO-fEH8HCLo`l$AAC=^W2r~*q2P|K{n*{dtu+qnoMLW(yRmv`$ExFZ>nl{? zSE5(U>neIA_F_OD2KwNStNV{9{rOh9@;YeU4JM}h|#Uc{O3KKOkJ zJkY*y#~AaQw$F6?&2Vhs@pU*x7LkYaadqT_JJ+(Y9RHhr^)~K)=9seyX44UDhpT~~ zM;`Tg5qli@pgH(ave17F<1x*f8eL_q%@(ZDg*D1%utr&8eX?FlxJK7Pv^JTo(Pis%*&1E87TIjHF4y|XoUCL0 ztw^i*tXjY}skM~_tlvf1I$pYNms`6lUaxCjma%?U$Y0d;*|z7eRbqZ+*LC@fKVrw4 zgxx;&Ce~#G`)th4waJzjx>%RYbN9e(+@5&@oTdfY3)a1Bp%!IhEv2*{_?mvKs<3_; zyzo9u1@-s*QSGrFrPkinzgo7n`N&_d_Sb$I>(jNv+DCP7U=7BAea_aTGj?*%VC^~M zUdK9Y->G9g!X*15*q7!zQO%Vb>+Y?i<{O?H%$pQg_E8&4 zvK46=pOe~$ue~<$d)^oIV{IwQhxxE5p$`$i%YMnNO<2Y{eTmw;bs4qxSevkc`iFh* zYu^cS-@|&0vsjOj>k%%X-?P{~H*2lT;3l)@-M@EPr~{iTnc9!c8qnt?yJcA8uFfI z-*Vi>yDSI6c5vT{9NM>P+QN2gEz-e#Yxw!9>HxL}HdoCH{CD(XAADmjHYx25dJy|S z4>_ciHc+eFfuvRrhtX$o(90AF-q7J^MQ9PWDaYecw9RHx|LY z1ny<6@nLY2`6xJ#9oUd#2RG#S!M&zK*h0tfwbxPn{3w3!2t+RqQ7Ip`;ORc*!DS)z zAW?hNKT&(-XYS+dv+tE1^`A!V+ZgjZ81uX6`x#gJIplsG=Hp;G0nU?$H%&+O$tkCk*s2cilN0#)@k1v1aTE%DU>*)256r?Ar9EL; z*t@>0IY{y+vtJGP>lpW0|A=365B?_jTNRl>?R(&7?Ufz5Uz(eiW#oQ!u`6WX%et@4 zBkv1Z^FydP>wOgU4w=b%`skLNp^ojBvw`?Eb(+G@PaWA(KTg08dT}i619~IuiL?jg z*W3raUva(9?AI{%`Rq5q-$eae18P5uF^{!h=ry(Hm*?BEik@Fzno;(Bt8+2?zGbcX zG35Njp$$2OTAn_-53E~q?)ZK=f8qdiP%fOL4n;bT&;0&5=GaqSp_D{pkKx)O;P>d*uxN-Q+$G7VX2MIeONA?IU<);N3lJMuc;&Q0KeK<=WjvYW2_G=c7BU9{$ z(1UP1pa-76oZ!cpul&Z&-cRy_9phdX;~x8d7Jbj!FU&M#3AJBA->;$e8_4}8dVUK% ze-PvR5!9XRC&7N^$X+>jY@b|2&M%>kSHXQ9TsJNpmzx()%F|DtlBX}7l3SNftDeS| zx{2@Kz|XJ46MAt4{|$3-kv;@jFb}qb9{653gd7}1FL)0;zp+n<)*ihd)gHYc)gHay zLiVT8`)!PUK4n(KY?H_-ddsP_6y)&LiSfs`!&>lFKWMU zc}5Pb&Bk#J+v+tj&9236Z_>l*l(UcDtDedA@{DFmgm9!(o+}Y<)<&n ztG6%9Yj>{7Yj>$@x_uR2zkK_Oymafb(2M78Ttp_$YaZAaX%BQfIDSy~4JWaWJdXWi zn1KT>10jD^vv2%$jD4E@fWM9Gcfj98{d?fo+Jk?wTbE_6eM>eL+OoOSmHjI{IkY|} z$2J$`Bx-;5;F?@O&tE>VB{xnVlw0SH$TMJn{_1JDf8(6IiaI~Ib6MVe=9;|q>Ke%^8Uc=8{xkDc=X&#t`JIIaqfW2@Dy>Jm@={bxC+%IS!fL}9! z{ed3`_T$)y{FN!IKly7#i0qKnJ})iQe;U1S{3V$|?`!Rm{e@0VmXQ4w@UJ8Lo5=na zYJUi0{?UzjIf>ezIj|}h4zJ6VW1Dj0)B(AD?y%gucwAmY-CqIwgIiC^ThCmTcb>Z; z@4s+UKL64!`QYU{k>1DWcVD_KZ@>7od=6gFhgXq}`^duc$bx!+ae=+S@qlCElNe9A zU*JB0#|N4L^nlNR9|w&eJ)f?9n0@fK!QVmsyBPbl_Q?J`_!q&yjO?!=`+Mi7W#3{) z4zA3|5oG_w-UT^>+FwBJuN>VgH%@NJZRGyh3rFRpD<|c(8)xNnV1M`CRr%ogr{s(G zZ^>6)y(=HReowyo;92?V8_&r{51x}Rzy7Rz@wI#M!7F#=-TSxY;R{d88^}oH0mcRP z0>?#;i8dCv47h#bNgN;b^#JN$alIea9=)%%2Y(aUx7vdrV_z59pF#F#k^MRFFSM(& zgx+5T{|5Lsk^KY6{^8Z097py~Bl{N)tjJ~5{>Jf5xpVq}Ja_)EynN}nJh*;F-oAA~ zKL5-W`O*tF6_2XH{W_uzWMe`@{PCe%cl=tl27pU$8WwMUxpW7c=Z{1 z|NfoW1B?qVVa(vTc-QqolmYA$Z5&AVfb9o329RHC@3LR_{Oo(j-^SSAar`~UKR;cO zMewhn_t%j9y>l(u0{@}qt{hvNl~a4?<^0x?Tt2ueH;!(|9n}8$vj^psi$~?ntEc3> zo9E<+?xbWba>lha~CNcx(ECbjd=s1Amf~W`FzAzpGY(L0xUu&=Ys6F@_ z=zV1e|8$i7DVah2XTd**`Y(Wg8Drln_&316550d7**}WjKMDSGn+tMj|FYaTye4;! z@0I6I@0V9m`?oG1m(SlgBVW05QNI5CRr%SMpO){u@r?Y7w_lK7eE((n{)ey0FMaV1 z`Tm#Ql__h(2LEyN z{uyNd$$g7*9ofHqWL=&=xldk0?caX#sC?ntDf!y1bMn*AUY76Nzaigya7TXS;dAmE zpT94^`Nh}ex4!bG{MJ|BlHdIJq5S$+AIh(M^p^VY3(f=f#MjUxUwVywzzjSkuVd`I zkNv@OQ4iR05s!&@p0FK%Ey%vs9=+ev+Qc zj+{d8U%6a4!z_8ms=pFr=QUF*pu^!`)(m*gI@|H_F?d3g4KeDTR6^6B-H@}1k~ei zEWh>24f)q^-jN@^`<(pI7haY>`RH}|ldpYF{`l)}%O8FEuKe&D@5%3f`kwp%UN8&4 z{AKjQhp)@ez4x+w8mb@>kXzlm}3;|KTT3#k9QyP{^ zKhF!?If3OL*9bWN=`oO9BjPmy&!4D$ioc8clYbW3p9lXU_?I#Et$}|p#=iaFKMelk zi)}fJ-oLayD^KlPkY^9B$g9ZyyU6}mFCLa}T{|J)zjaoA`?)9O4`046fA+>L`OA0i z$zOl?g8a>wUy;B0_;vZ~Pd+FA>C=bu7vFeC{vGtkpS~l1@X6cqgOA^m-}v$y@{1T7 zzw_RG`RTWwmych6M)}`C|G$C$e;LOS&)>j#0mi?laUP}PACG}}UaZG}?mPfvAJ2pQ z^$^yd{0(1w^!~KgJ}(`NeO-)wJ@C&t{w46QfPWqQo8UhH{v-1(If=3FJov9}%*pMo zMS1biioAJzLq0sSU%vk2VflsYC*(J7pOxQ#{*wIZE7#>O-+WsB=ACEc?>=~5{>zu{ z%in+XRr$Za_CWsTlQ-o*ejPdZ`a}8CPaet-(G$P>(VOxwzx29%|ASZLJMX+C-~8Nj z^6_hT<-_|=yG@F_wLF6gADuwJ^1KV`CH`Rui(S~_O&%Lgyw909%m`t3`4?)2=nvvM1~ z{}j)Oc|MG>pV!KGy^z<&$j|Ge-1pfvfR(8BHtxs0Z?!l6S&V)2sQ)7Pm%+aV{=MMe z!oKei#{T2rKLh?t;C~AI_rU+k;Z=F(#9sLd_7ca~Ifeid# zZ`_o>e|Sg!0UrDVa`5+Gcv1fLOE1e`p&$PI%dg6xK!5PXSLAm-d|7_&{g-fz@VtEM z&3p36Yj@LE*_Ha zUOg_qdGnO~{+)C3$Io7rKY#Ix{1rU-Tjb#H-nuP+_s(7U&+k1efBpIA|@`*N`Ce}_z!^p2>4He|6H0M{r?We zzb~KOC*QnqQ2zPlqw=fBzz?22BR{-*PX3f0yl`3m;wPhjg#`bPoI__G6(2|Kf`$VA6~j5fBwof`48~n z-y#qH3%vL@*gyQvgWK}!uiujIy>?4}?v6*(@DHCkFaI;L z@JI0Be?m|E0mjCEjZFOa*hl`_%Qxh^_pi&(y?9-|0q&2Uy&@mroayb`7v;gt^Ku{T z&w-uSkZywg+Swy|E%gG}c|D!E=Y6Df?zfP8y&sDEf6?)7kp0BCAC7(C=h)}#pXR@W z{of7j|L<(h%L_REdktg2!(;36;mJ+;D)xilR1Yi%zl!65-+bzn{5JaG2k_wschAf3 zAP>ImC*}LkU6OzP>?QdY^!0m}(&c<2`}9()&B_$7=9zl=QmGV<_! zc=25vBmDx-kG_rLNbPdM>8}dGK@Fn!Z#~2Sj#hCarJTAO+M7|9#zJ;;jXR(j? zCUWr!&J(_R{giwO`aJYD&KcjpHG@}h&FDpN^V-?%^GD?-@_y~~A-T+ZWEks=eN!_Z z)gAX2ecg@So)scHpN~q^-t(jHdECSOe#DQlKh4ka|1ge!j^p_EG>-qd4`2^mLl4|U z2JX^>155G}Ja`p3coX}Bw=o{Pk8^@Azy}^1eFQH)LMFa);gEb8etZFA#OHCI{O+Zr z^6=6zc>{X&$z$@;#bfduuAALGe?)GbJuEkH9qlS=ehIyP;rN!`M>>tMj{VMiioA!; z=O%`+uj2Wym><`;PzahuKe{#W&0WP2iE~5voV;sDRao`U6 z;2u199v-}e@!(Zt;Q_MnCVY4cd3YOMyp3~&hv<#Bpf_=@_yE@mUOjhE?w>m(FG9~k zch4S@TVQ_b^g+3XYpA@2ei7W~asTYhkxe-T?i2bf0G^3J-V^K?=k=K=)ZEv770+3% zEX_H7T;E0QjUU%Kz|P~IWc`!;di;aq-$Ok9#~8q4z|-h~bIUjmMh57?HT1y^cGrXIpr!%g%W` zKhF6v_UUPh|;9RIE1_m(O&o$x$`>t)nATr)kpe?`tv zxNmYA;=QvI&~fOPGOyr1I-ZdNGoP8-k7o*)b#n80D&@xWMPb%gf|`?kVSYyC`P-;H zrPn&~Y+Dc6_x%34ho1ZM+7I~I13m*=$iM+);1I5Z@mj!9cyJ6J9ES(ICUz2I;z?wI z*9K3)hg0z36t0n;f)~6_PMyTPl9TY`1nwD}z`f$*xNk%q!#(q(&=Ig6h7RFpe1?M0 zO!4_4K0D^Q`D`qo8`VBX&aKbmtXs{EdmjArb6v|n#{KCOe{{VQ^(Vhx_rmedvg7CV zA6^6CHK2XSz!oxa02$!5utV_RFnZw#_K8P%O&mTPg%2v^;V8T~3NMc0TA2!79EFbH zUhxrJJLNr7>X2$tpB*@W=LhyX@%bS>JH}e`xygtb&yTK=8?_GWy`)(;Zq}XLbJVQo z$9-+`qxXINJ^!rd$2~ue0lfCd>p#5yw~ii&J!q&0`{BU>~Q9|_M&;n|6OPJDKX&&_#eJ}=8>g_Rl4&&J$6 z9ov%JUFBAGaL>+mRGNRV$Nad*hx{vl4fndh&+DG^;P=-)nSmAbfO>!oY#;;70j~w~ zdgwm%!WKN(f(N`Wpn?zkDfGn_yx4*lTkwM7y>b(tm4P27JRgbY2fXyzV0^s}+4JGx zjhK5F&rP0r(e?KNo-Ze}=bm%iv%QY=pjO$~cgnwrXI_{AUjOGc@Kt1h*TL7puRg$o zz3^ZY9`L@%CVbe051YI<3@2;Ky<=DdTfTfL3D4feLo%(QWT6VJ1y>fb^AyBPmwQ2!q4Zy6}- zwf_b1^ZNf%tJ>$m8a$v6>+pd0MR;FK1s`~SbOS!{9=Qr$tiuaFFTrPpC_XR7=jBxJ zV?|}p$CH!qM^F(je%JGodBN3re$IHam_0YyXJ)2T{CKtp>}h`W0QsMTc>g2v02yEo zcpq>D;{Bji-VcTcYj`GL4IZfA1MiVitMI{#&qdqnDBfkpAm&0d|r;?bJC0YP7L3VXoD|Q%sCHEY7W2a zMOH7*+jBK$ohi@EZKvB(#r$}lH{jQ29UQ-TfahIY2Ij!;Jy>uas1M*@^5Qc=Uhsm? zh^XMjBA=0TT7U-T32Mfr63C{z;gGlgT5#lpaD)_)>#rVA3d>7A% z!v|_k)zbF`_|5<|tD43(mgn@_h!?Cg%4?itRo)C{a;w@+vyyXsMqZzj=Q|?yo(SI+p?Z;8_#A5npVRW3 z(Ke{B)w&5*C-AnNrm>~S?)h8DKkKg*`90sOO0d>&>F9z=oS9um+y}1wZ9|n1u%k!G~G+K=r)fLyzx<^{IjPrUJo>u2Tow1Sgm}DMnx0n709L zXgXF4pF=fV{WSxqeVhT~4?XCBo%|~2!3;c@aUOUtdQH3w03Sll;OiOihvNHz-RXKP z_|ZuS%=q_vwefk7LdNiO$eQ@vYDg0b`J0Zvh1yS3s6Y9=$nWJn=#t+HKF|vjc;SO` zgPre(n84hM)qw}Gzz;v#Lo|(_nc|vy-UJ`(48Bm!RvpYqkw5f+^(TMmLBfZ?1I+_+ zKo1gv2Yfc%1aA01btw1{3+(WsouO%bZyNvBEVc0c?Ud$Bf8D^}P&xj{1MoK;zj}cB zlRx$V?|8xk%4b2h@Su|=_`vsrlpXx-0Ww}PC)L8&{Yvtu*`lwTsI^lA+bq=se)RzC zK1{=pY{7>HSiO{+?4~BRN%gaD&lvlltPSv{h5E-HfWNZ62QAO< zx6TK85ewY#ArgFO4HQ`6!yq;Av%vx*n7sP<(!8m!HHCEwT$hv;4TRYgTCG6Lfp2Av` zDy%nHP+@LVti{Ro7xP$)lhXC>n^^N6Yq3(3SnGZg>v*fMmbYK0*t7R@r+HJH%lKNg zg>9BnzYm|1es~|S9pHnmA?tm>8iZU^x!9$!o;cPx_db{h@WOk5^?J<*@_Ts?Vjm{p zLl$>jW5?iFo8auz3ck0pzh7AQE&SccBbS#t{cyRkJS2Uv^xX1tXK)AgRo;*@`g{=l2W2`CzmDa+2|aQ7&|F{**Q`8vAAA;c zO=0wdt`Fbmf$ImXKk55H$Aios}*nhfS}(6gbzK@5z8F+fhp3ziR76OQm~ zb22avQ$BDn@EOg)K>Z7G&oOU(9=h?}d(9`%ee!hJTww5X8qR7R*I*HO5*${M8>__& zcrJ2y0ng?%4tLNa@!WUTg_IBD3@ji1vR|}oi(3A`{`L3TljhF z^qGyje$}7rXY~2RVkQSNK&@OM2Rx_L81Oma!6117&$*A9pl5QTN47q22I=|4!C+i_ zA9Kbz#o9GXD|MFf96$TGhbu??Sy%rom;^WT#8Y_7{IG^vLO+-n9)ba$mFr&6Gi6IY z;F;QZUM=fFbQ|99JLram^!M*EKUC2V*hC z0nf6%24|={b@?S3|xA_7~q-6sFC4?g&3eNl;_i? zeBg83;~C9lK>bnYE#JM)h2K5Li^n6@im&T(t-H8tJbXFq_TvFw%S_0@S!}@<%#-Sc zGvtHigyjP`@VU^L0dj&IS|6Ms7s3Zt6Ru(q+SkJViht0%597Y-7x$t`KePV##aNVC@eGN5% z&#nH&dqeAkU@$T7m)NH|&)8q7Jz{No_a9#l8c%Q?8~(odfWw^ zs0`NR13nYIW6Yz#op&Bee6}|-18;wZJa}|UEf209>ybB z>_2%czZio{@PO2Pc^^fJ?Al9y`%5Pw3k>z?=u^dXCH<< z4)JHb2POv`@WeiHgI?Hs{090fgKf`+t$Qzq&E$i1uLo;)&d?Xk2mcQPtwFdZDgEB- z-ptsu)Yg~854^8p!bp&pDgcs7v1tq}${y&f#$ zgQ}nFGh3&q=TU#madOR5Z=?P(?bKX#AD#a;^kah8CeJxO!VC1n2YF#1Uf4rE?79!g zVEe%<3^KrQA8dF%SVv7*Kbgb8>%mnF8vP~r+3(H!+nVEWK8Icv-dAtS`sw$i{rqFq zeer2H8X1%GPvUS04hQ(V`|v_$u!CIa8ElR)SQ}xm;=S=^&tU)VaIN%4tBF_X*F3G% zz3@JIn0lJmclo}HyK6qa_&glHi17tKb9@Gq&%*?tA%{cwAsFmEfe#*=4>E%-_d(0x ze4q~+2DhIKtOuFF4a^higX^q`iNPtb zI_0}!&zM8|%P+%i=)V2xTN%eMzlp`si?72(48DlLfqVc4Pv4^!7=xWT3^vdgSPwFT zTV4~z;Mja{6Z1sof@*;naDHUDVExZ}U-W*?znlD@<^Nv4>RpQcl=kn#F*tA>fdR)v z48Y-n3_cHJu>Y)MfSPDNxE!_~yvBGnY`PCJgEji#&a)viSRsR>M?=FP%?(07*IHNU z=lsNapXWdHvyWTtL;Q>Wh<(KUJ7RAmv`^rP3H8Sy2Qm0m8Jv9>_TYtGcwq_znPNA0otZ~FH*hxhsy`dP=-*OdDs z`d>5l-%HF7q4$v5U;RED`RmFDuLs2kKfz#KxnK;k2ZBN40j~u`Kjziif8l*xHN z>k+L{)&G)y&RsdD_xK;evspiDo9Z3oPVKKvC*ys9IPYIjKX|^!-1EJC{FHC#@%tLDYj_@Nw8pxsVxbjxk8JU=?#j z*27W@CN&SFUuys`m{$Xk16-ele&s;&0Q)!fvzN1{Gmb~r z3H*Kt2CRkWKmI*D`t6^?>6_nCBQZw^{dj-E93g|}pOFWjkOv=84=aP>0n87gCp3BB z^8)63O_TE_Rt?5fd0k<%!Bbd zut5*pr3Ys8f>Z~%pDYis4`9Ba`%qmS*yR2^_oKwXa)4_y)sZHyM`b5{lgP21NOU-!TJ|9aHU`1!BN`Ne;}5!Ux=^2p?$Oj^3bs3~>O1!U5|# z)CJZCYGGX$1LcFoTKN!hZ(@&m5dIGTe)a!?`mtBm&xLs3WQFG}X5<0yH|YKo{x0(% zGuWKLU?vCXuU_aFV1C!v1dBU)cctN&yEpSLEIeyoE> z8DLIi40sNKxiE(T=9|g|?o;;+kdv7K_c7>!**>s*kY2_+2J^&y-^3oji@&p33#B>0 zO#NO1Z}4o@6a$>K;8}yrfcM=J1Ma)h2i$*?4>|_oKo4kS2H3|b3~EiJCJxmD*V_La zpHbc;_OTY+?)9hju&o0|=7FJ~=ZOjf z1DrcUPcR>}3~qTYv<%D#nF04`=>Z#=0rzuzAFw9C)AY3l=60Olm0^CD=RNL`_ZIs) z_v3%J>;u4?c8{c63w!)^ek>U9T-l-wz)<(%lMl=bCF=dp3!I9zKCqgAGYQEDnE}6()kb=u)&%1K2AC&=AEb{O$A;$kp*!|` zEbg1W_f@qg?;}t9+RyKA`llK23{mY19Rr@bN(@*_bq+yw(HK+?_zuMj78~Y*MyieB z2kqyQMH=y%U9HEd&nf0(+U-7o<-OIt#`|9TR&j5PXXJEV@CqOB-eLHF=PPvfj0}Q9 zVnEK+Um2h-6b8(R>;teyj|`0NVmt`d~g2CzR$7O*+J>|e@n9f1Jwk~4>(8QnTlY*`zh348K5>6AE4jJ z2ayx47fN1;h1YI*`Kq5oca6Dphv%7p?DZOcPOOVPzc0@N>dZW^&VXkHqc5;GTw@-1 zF3e?6I9P8`o)r$A7dRi4AIz^Me&LI_BB$k(_%p7W)5=5scimTU-&1~Tw8wncdS1ky zHB9G%c_uPA{49f}F2Ve1(>)b;kG;=#*z>}x zML+&6oz8{+BmeXWHz0G?~<9Dxj zP0sVXc%CXw_?~~I_82pKz;jZ{gOOYqXMpp_WKcMOxi}aD?mxzS!Sb`u4X<6HOKZ1I zYk4o{Ie(A;Zsxl39oL9KXvezV^gn=poP`hl$p^}ZlnXrrs|h$qgn7~^1D?Hu{&`*~ z9LS^OtFyqLOW(*^F^}WAv&Py!Uv<0R7tqdmjQ)KP&%@7Rz_at>fb-Lx4_XGccC7ip zGwCA?7=wrhb28!-o)C*^9z7rFWvolQXXwtJFL7sF?E78y{|8vUza+3Euq3b~uq3b~ juq3b~uq3b~uq3b~uq3b~uq3b~uq3b~uq3b~Pzn4Oe*F diff --git a/Templates/BaseGame/game/core/rendering/images/default_prefilter.dds b/Templates/BaseGame/game/core/rendering/images/default_prefilter.dds deleted file mode 100644 index 0d9e4193941f96ead0dd024f3f4ce89c2f81b8bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131192 zcmb5Xd2C&Gmgi?l-1mJaMR9)=AGgPS-#3#KNt0BIWQkIVYEeybq?X2t1Szrw8G-~0 z9y^8|!-iwSV>?Zgh7hJ*iAO-RL0sBS`)kOfpIS8cgcs^F8-n zN^*AtiJ*)7_};zu_dEOfopXNYPEEa5egBnLUdhfm{>m6<9j_eo|F0zL^Z$>3)m%Fs zzh0kTdBwv2{zppA*ekF6Rv(}L%gW5K)RbgPNlprmq$EpDO7tTsG0~FvoROMhsc9*e zn2=zJi3yevKPU3L{!Y)%v;@w_Pn@vyyu9Eue<$)xeSeJakDoYhClZ45an8q%ANS*U z{OrH+Ie}~Se4YEJ7OkYZ!OCl!ta*6W($X_+YID!(T6^v4!*^}!{Gt8l|Kq>0p0NeH z``J${DLK`i{rHdU;^R;3?VtUb#U|!#=KO8@@R$Fsz4i6aEx#pZ+qWOv^y-$~`SeE? ziS=4;R)&?76B52dK{(-XJOHO)bsRu<%`*v} zNQO6Zi-DKl1ixTB5vTPDeFx42oV4}5Yc{xe z7P?=uojY&Y^vNcmzy0MG*3eiBpOriO)zOG$!V@`#`IafVf``d0)@U$uF?UjSF`D{V$Q*pF($dd;OBN4$au=)jPI#|EWcX=j{BQ$JRe{ z#_oUojWu-iTWxIEuD$(Mst-7VjN~+2&zqH8mz=7)m=AI0FQ^0|EJ)}>hw~NmwTrULQ#bx{j z`o9R<@xKH95GT4;xD!ux4UO8>NAIG)7NPkSyYkli_SGN%6?FW@%4#FFv47jny$%lg zMr{4yu1%l4WZiR{);+Ocw?F#YvI~kWI=un>Z`eCO`!)QrY~8bGt)+k5_MUzM9GQ0Y z>3?ElJGX3Zpvy*EBi2@1Z8g=EmY1Jr#Whuy0d4cq3Bo~UUXEp!6gWRf&n2Q0bWY-& z0L{e%Nh#=yOmr51hj2^BAASD+0Ke>s;BP@MU%LCqW;S+h>+p`X^-tK`xy!cu=p&om zzG`LIggNxr5d1y9writ{8+PHryU;1qZh!F;Te|hO#b(dhg*V=@-G}ekmA5~&shtCB z?isV5>1Au^owl^BJn;H~{lWDMR$EqLwN;f?fbJV_X|Upsh~*aLTX|c=;g>CNeJ_~d z2kE-x)MUqz;{fzG`%ty^ze@A3ufnq0Os`*$ohb;dSsJ+`xVo?!D1t*L9wYfgCy zwg7tbS@JCyrSD`f^|`FO)nOO>FXBL-|8BVDn7r~5P68bwe;-|>%eBuU$fgE ze`^!#=WPw1pWE5DG4#ULtw*+a`IbHS@)x##>n-fyApXI;oxA%K`lMQP?2N7K-9Xnp zwRUh78JxF~l`VAOHJiJ1$9A87X$S9qWs7?^t*yQm-Cb$-&dgc?`mPL~uPQ0BNJXjT z=EMKUd^X=n7bd5q1oVgA@{z>rjtB8SpB?^mbOdyC-49I#*AdNS1CI%A4#Dr#khcnEnwG!oxum6xI$^5S+cumgcENCE!imV~_Iloz9q z0-sR$aa_D|4El4tfD4CTJOmC>Qq%1m^8EPoZ>=9*I0Nlt)2rCHVLNy8O{;D0vWCtf zTe^JL2A9s+!0Hw2Tt2X?&pxy9jeXm=`?lT1zdOsdm60ABgMTC!wb5>S{fnR3&Ch>k z!z(-3lPO#6?Xc_fV-|z|%W`wAkVE{Rm6>VTSy>!`KO{PbKB3NOMR}Gt60_Wja?6D` z5|Ihlh44W-e3MmEX+=vTmd58)Y-uh$CA_^zbC&^lB9sNmzkH}>XdfG%vc5CB*xf7} zm{|e#A)Cg}>z&8{8=r@c_w4{%R$NhS!>bo;{rVf$(lg??y8iCxc9X+>gQ+#^om;m) z@YuI?$0m1g+Ya_qHe+(@vf01=bNlUo{jEito2(q!&x6+mb7p#)A9?UX3E$<(H-w(z z0m;4QnuXseeVq!f+>gdiq-1AUc~`sD_Ox3rwzR0c%$m>4SrvL>WO>eYLhtmrWrO4F zoE)cj2)|&L>?HEcuE}|8Xl}F3YxnHn@%vWU7`671S!~(^>zr7!Rq+IPxc=lr8$Ej! zop;@$6RTDo?X``Y4{ZT?8Ccl0A#B4CK6A^^0_%m_cKF^`_`V0&)oWH+AF+S`>0@hb zZnRSLeHnH@@XF`O#Fk~?-zuUZ+>gN*tM#TaqLvK9U=!Y^j`1E z6?}qun?-N-ES|SH{QrgB0~19rkNePFgIa!_?lC;eAmS?2ywNx416V~rvpdIbhG|jyZH!TXbYTtZDZ%I+0vz(@XCSv zPBFe8?{2pUzHbq9Z@~_fcQjiGK0qe4%w}DqHKEqXS>QspKkx&St^WQM>;LRMEA8vG z`r$#VYHzi^^%cwQZ@28GS}Sg7v6QSFhpW7!$LTKE(zA0dJuBO~)|M<)&j%;j@K6T& zS8$0J(vYX#nPt{>=d7f%+V<`}f&bDh4cbnv@7m0{J&O*`;?IoO=)$_y#73;LA!@h( z^0!X+%7#{aoGIl0tc|W;uy*{vp))(SefJ6e(s`T0m#XcZwc!o)Ccb|IaOc9~w-+be z|1Iupwj$Ou8GI+Zmj-XABNJK+R=&PxCF27YdE>e@-o0#9)7ZTk`~W?(8b7}SSZf=qtysDay;Rg(Z^h_B_y2)eYhl;@ z*m>7|$%$5e>w;CDnX<~(7OUA_wRF~x3FrmsfP$K8OKU*hSu+%m^;vN&Y8m*KNf{X) z3pv4csRg-~m<>)VOObbTclwv}SvEU|^`2mt{0FuVJb;gynK3I~7_qur`<97+m{nI} z`Lzv}fPOq78wa0D=cQu%#0Ss)pCIOw&syVnYLcCRua3zlK;Ctau1!Km_MN>5o#t)g z>;tlc}XkG1Xn7Mnr8Z(X+!zWCO!?L|jKSNHgR+WBIPSkK79 zrVXCIZ|is8^L5hV;oI1P>-_z`wMQGRud9_cMTHe$qjTZMeC%3QeBCR(mr-71g~Oee z)75O{yR4<|9$4k1Wl_)r|krKJdy7le&GWe9|J!99l5w+ z8Ko80ySrn@fjt4AH6aNnOCJMbB5(MI5H?$wliJnzrf9i#B!XhShftBAYp^ zf#+SHcZ@9o?~L7k^weH|`jN}T{Pw=Z2F7js8tZ;!p=EFZf9W1EkS8{@e%VIO=(`zY zzucP9dE);8);k68WtMCnGMZmsWtEqftgySq3MYE3cxA#G54WxJ*I!uK*;Q+Qc*F9W z>VOG97rKkTbHxYADeytE!*&8&UNbRlsd)vK08X;2sx4Xi4!<)AU05|S;rd^=(UHM- zikWK(f<9jzx1z~j%Zk=p4u3BlUbDJb2Xx1_Gfo=tqyb}OYQ_ex-?7s6ZmS!e zLO#l@EY{|99KEn>-~I1@ZCS;o)-pE5x!mO?0bC7i>{uDTOA9_u8SqN>lh6ry6%D}N zZ5N+@YQxyV2Jo;=+-7j)g6$Cl&B)HfJ}%kd{5o?a(+Ne_bI3wHa}XZG~kwne+6_M-<^Eqa#N&}ffUL^}e1tfUN{Y_O8S9xG^W zL1*`1y9QY2RM^bZcYsU!51j`5Iy%s0$-t3>yb2G;6Lcgp?+NRC;}+k;@5swBd^#Qa zEw>2&C=zu!5=}>l-A$g|v$m0W8(!KZ?ss6F@cI1KMO(s;9VI?o)f}^d*%fOc4k#O1 z(>`jw_(r|kH|^p3pV)8V1?iX=`mv#J$`-HOvFg?V`_+@1Hhz2841dmk@rl_lKd~=w zUa-lX9V_2hwDPqX>%V;2&fb30X%bsG%b7R@@zoyqy8u5YllkU1MQxhcdSXhN(?2;U zH?Hpz`Mr#_V5a53f5J~*WsMDNZDJ$j_XTiE|Le#m_7@wO!0*iU7_ZPuA`h!p-#1~~w;tjf67T7rfaWXqkN@d^ zWi^ow@Q`e4hmVLK-?nSO9T^)m`}xOquyw|sKD=f3p4_mxfB7TJXI)S=I$*o_j;W#_ zyeXeNjnB1H3sy5YW&On8YN4gzC_)c7??Zpl(P26!xK3CtYqYH!H&`2%;v;|?u1~?= zmu=LwemMQ%e{iH2p6<)5s{5BXMSI6=k@#n{Z_H-#TnwW_YukG8!^&;^(tYb(*|QHm|Jr#W2|7u}{^%L=pBS|N=l%Qk+aJGg z=WblHLSjPI_#!2dCL4SFDQnkqE5R0};m0R1*D7r5;@7_jVDvdNe|TN~d`bpBO=gbk zBJplIxC-bT{4Sj)xWotIiC4gnuMeazcvc`c${BEQO?qA-e%uD~Rc-C8dAhKVb&)pw z+(oD3-s8{k^|q}a{PyApHFpnKc~i_<$sN=KdvouI72`)X_0L*$d*-L(h>dT)BteKjATu7&)=nPyL_t5g8wboIo`K*tSy{4&EOXHa}u?d?eewT&Kh!OXeofu+$mtS7%pGTI@!UGeQ zR$O6I7w_WBR*^efXYF$Z_!q1ker{j7Xl2dKLEaDE9=>tc{anQ*a?tbg>lBYwtV24l z1YK9zJ_HTpIv#onmf^z(mfz4!JfzaHv47$P@qAfqh&6k=^G+b&#I^)KxRY(xck+|; zydu_lx^IxUMTFR%_^W<)F^=m5$5At}-~CU1jjUg>-i0l46qTOy=tZ|xgQp#IVHGig z%h0=HY?k;#)atsY@ikV7y_~g9eC6oC1na3yE04sirnS!^&^Hx5ltrv7j~GN6{4JQ% z!ACNFSR!+D_?eq<;4%sw(^$i%;_v0KmXEUDP9ttP|L&*6yUH9s!6F!vl*a_d6zLB9 zzcl=n>Hp(@AU0G@oS@PQv87e4aRQqO{3{#&tPE_1Y>D#~2dcg-rU^!3cU zmL3uWb^4ZfNbItv~p{X2}h%z5WjV*_gFVZdmKcqK&eKieRS)Srg}1Hre3n zMXT(b#plSyKFP-~u~Oz##Ua>pu|vv#JM5y9^b>FgxlHMFaFClv3}TG+YS{~RU-}>} z8(bqD5Xwn9d@KBAqT40&&J(gJzAg-GzuWV|DF=#0<{k@1L`N;>t<#t%;Gg5hJc?8zjzy zj|II`@Ii8rGsXJTn9q}6{@PX^Ji^YWVe^PfFqa@_E4`KAK2H|9A`^S#`T$r1xPcuQ z!_Og%!h_Zb!i8W7?{Tq!UTa(7 zAUraV`|8dZx|cO9{E-B1WGmBkExI8AoJbcsT?Myv;R`T_FoyHjwQes22iH06byoae zbmnscbP+COLsO9@eRkX&;XwS7V0qOoR^CdydhwjKj-MeOyk#@MSl>C~>xE?WY#!?z z#S3?CKe4igcDwQJCwBLP&+PKkkHHBswcQ)U>?-gXy8}N9xfBjkk^O4cZzatUa)pDe z=hCgHvB9z{D_IW{!)HCK7*rxQOg?%*mw=x7?DG{o9Kqb<=kV`1o}9m(rr~v3Kc)n6 z@FPBo^ONwZ`~3Uk_`RE~{bq>yUSS=3-t}HLzF1^v(W3Z0Ib~JWJhE)ftZhpoy|(xE zSJsBVa+P)QNB`pAlK;7F_1$CS0=igdPg^#zr`nD#*3-y=_yAm#5X(}mK5slmya9T% z#+U9o!CWN2N3b7fZgKiK%posuKCIfA~AknLU3M z-A;@ESj+42i;1mGZd|lpeE+^HhxU{I(`@4ML+e|^KWyu^&N=)9?EbljpV-dB&n?nF zO)h24x>yIFqXwXY^-FG5mBXFQ8cnoMht|o&u@cGY7M3D29WnQPUH)AU1bBEp|A1B= z$9LG3=h6|UVH_VvI1xNfSHZ?LA&eoNLw<=r%kR^(c&6-@e7|vG_!k~L@%3+Qj5x>r zcWi{%<~%-qGqC~X(Q>hm^&Qkj^h}WhoFaB|$L2P7@gcDz+13jDDXf`GpTo{Pk2Ckc1_Fa%)cpA_#D(Vivg`)D5aheK{s`6pcGrVP z-^F>r@uuenM<`3WSJ&52|5U(QYU$FU$GAH1iKfo&du_lVIir@bMXTu;wt@K#eA`VM z+9Vfx^Db+@O{f3X!%tZkt>Q-x6SwWOeC)4cvWi`%kdH`44nyqk z`aAGT9A@P+x$Y&{1y>w4ho78ZNN>ks_f%mzLNe+W4)}HsM`~Ca?8w? zWuo6@=bwJ}bL(2(M;GAxR5gH`A=`fRF*@KgTcs{$<>pgs>YlVN@S=Qa1@=KPs}yWt zBC*R9;u8tjfkfh+N!S3b^^V|Y?7;p36Lb&g4Q)ju<}V-4VRxM#|2+<`Un6}P$B)Z1 zpMx{cll=?-77mW^5%5l9N3UhW&%(KMkKzT2?^m=ATN81P`HKhG_f322e>NN4Ir{xiRaU3|^U-;~}5d9@r z$87ET!y}xu5zDG-=`q!BMFwWAx?{+isO>4KZ6@auWu1GE97GTCvwVIVwl@6TCj5eG zV#U??#{DaoZ4h1AiQUY>PUaHx%p`x6T1gz6Sa{ybh$ZF-2Jj*N=SW8<<}3^c^m>Ue zLpp<#INcKB@sC&HFa)B~)8V2T9ECOHm zu$F0?A%B8B&ab9!37IB+jpLl1O6JFc+JK)uUO__ zr_GZeN+C`g=sRN2#KScQ%{^xs9YJn5f!xq>aHIKDj!yV`{76nE*P+~l7x!|81_ zmm1ckStZq0Sl5PrNVSju`M)CWHSTf27`{Nqr(k?XwZ@JtjvF_7) zHG!I-4C*8m8%ibKAUmLOPALDw@9q6V0c^-bR%IQ&agoni^LF@=)zYR8;s>=(Q>Qub z2D(3}bMb5ayH^-H6X*^=fu0N2I9lr! z5^s_(US3=8@vKaAgZTXfdM>NH%JCrhQd!GM<`d!LG-8$xpYw8@-=)hq#FLt*bhqMS zslcNge{Q94g*|l{3FKb&k8Tg*_m;3GJ@PrY?m6EDawr@W5$Dl!I+xD7k6%eXylH&h zF1$5AP(93--8& z=EQgzCB%t{p=S|~DnYO0v2MsBZ=v{q5$mi{XeO8oi6vD~XQ7z3;{Vmn#7Lo4RYN1V zC(a41MWyAg55*^Xws08IBR9Xuzti`EFE|Ht2(NYgfm`9InY!3&{6W#Wmb$Q3)&cX^ zp4jHY5ABdO&=9$>R^Vx!T&Gs>J7Q|UK+acjOVLH~m_+oMY`x$eTwk@E`UaPMkLxjx z;u*?uWkb8;d>(m1UYppj>p-3p(B}kkhJbF*X?MaZ;iu;?9JddC`b(d8aYfY;?}Tt_ z4(Z@b_v^?e2ItQfF8EtEM7Rphsvk|X*4b^VCNCT%COo*l=dtu!)`m^Q=FZ%DY75xX zOX$DOg>8IkYByMCtKKT`ZCHoF1OAz3mGtylep}R9i5uilhoam?Ch<1OfZ~zu)ZpY| zbB{qs@vFX1C0;AJIMU&vEckqnS()NoqGNpiwUHL*gAhl7e$ZM!&~bUJNnF-}*{{)k z;pgxtSGW%Bz#mrqd~6;$=^3|7_)mQ3 zy?nW< z-XUVd$ZkOyx@CiSX$(IBKNAFPq!H>v{7w zYLW7g&0g}tQx|XA)b4fSj1kV)@QW91kKo1U&3F16Kf4wLT~ zwpwgzJ9wQVAJ;l}$$H5ZD(-rZ`tkC%QEM1pvazjw@+qtC_i9Zic~u^!hPZ$CA+eR4 zSFPtFwLZj3nu)j7Qje>6b_iPttJ`+q7mU>lD^@f%YFZ0q5>wEe1&5w3yvn{@dE=p- zyLQ96msTtfn(2GVSd_d>Am@R+q!5FsB(@<|9*f5PXAAQPA2 zrvyF|$ArH#TceiSNlc6w(&Y7fF_ryi{5ru?&`9oIbO-kPpMP#+OJ{6i>jF888Tbqt0yhP+-ONMR3!m8~ z6;?rvD-ZuK6__*OJv~D?_6qE5B|d!@ux=c(_vPGq>&0Kp!Vghww`*+Db0Ypco?T7; zp%$4v!+wD__C!n(FCE73-DV$<{DE}V3@OyRsQyUyyXW;c7`Khs&^Ok+Ow9PhudQW$ zADLG^7yW>*8uGpDPLv!|UN!Y2)Lvw>POTcB^qfRM%RqL;D_$Q${4ftc;Pv-E#+RS) zc;yJb-smbhWqd*LN`6TdwloI+)KO1Sj0`FciBCd&P&}q*EraJLUwmUX-}%5g=9Z{| zt#Uj{wnR_KQQ%7)cY8Ikyy?&R>`(t!>p61~yT@7r8_+l!)T0(scj0*$;cH>py3X%f z9?J57*O)9D&2_SsA)cfkG_UHG zRx59z7L0p4@THai6rP;!T;qBKSs#4(H8O#oh38Y`Ut*tM6yfPD+Kgk|Xg+D(gSRqBU>7*Y){x|LzDk==cbG z`*e@=|J;S!R?;`a{5oBa1i0ik;1qnKzuOe%;b)#7=$8Nwx?YFVADqUfS6EB*+4T9# zmRVTF`j?tf>Zuoq6IP>lZEp-Wv-ikwJLN}j{m1{%BIwTHv)66&!Kb!( z_apKsSHUZBe_z9}W-lnP!U(Yr);_J&%$>mJkp6I92B$8g&^;g97+u`4c52DXh_4h( z&hTBQ72tQgqL?_mpB&ef0sZ5)F+Qgd55jFhT%Tl;)04fJzw^G849vTKA%4>#p4M~3 z0|ET35BU5d4ntlzc0%xjpE$h&ehBQR_L7#s_mRORyZ+f9+TN4T9e;`NX`0t(XIt~Z zbxVei^*qT|dTBLdkrRMdG++7j(Y348LycKIdDyf{YUE~@EgPH&ZqYrUjp)Oi(aFw_ z4mJttmkk42M^-o z==VU*9Cq~Q~6@W z>q34_g$9-6&_&lG^nWOC?pN_VhuL9&L53Xm0AAtB@fD}L>ndQ-c**#yZM$!Hp1GCv zVM#-qtvvj~nu&>Ojq3gxG8nsX6T4II_?FCxAC&{sS!=zjwtjNztQX-``N86gGT<&p zzLJ=~VgRxe4tspAAszyn1v2TlWn8a?iO*5_wW*EmBN}S`qU&Ddosfa5Zrx+QLkmmgXjEv;7EW5iL&dyc0`VNuIAzL@FG9FfXfhvFP+)*4GlF`Mh!?lb*?f-she21TX@!&)I^i_jYS=VG8Bh%EJo@2i@>oV2>;~c^GzYF{aHqUs1TjOeP z;|$;ZaEsjCXrHx0hm$8OtPncnP&c1R9wtM3Z!9YZ zhJC*!rR=?6J)9*vaAXksPlFdyH4hHu2vrl3j4v=)QPD+OLa)fTPwz>nm^^i2iOy%eUIAXH{x>;4zBpP<7Y411fM6!m+JiY z4|Z+k)d}l~wOW1sDc}242p{B;1J2XF7-*t>Y`Ikx!~xhBrTse8`D@QkrshLUNH+Ub zN^7XgiLu^9r)h6hFEu&+%wcHtybZ5iuuuOk{{Gb+TU}({?3Zg` z-%vSY7I73d)>skyu?kN&vWBd~e?Mh8>>)`j)#Gm294 z-@&@3OLLfe&H7$FOa0^ybJ!(6&R*$t<^es%h=c3+y^HI%#Qw)#WT5dhYfJX>lz@j~ z_JEYIH>#+;h1#|{eA$zh&A2)=Zr-VrmdidD&8gs2ja9IguOsfIddoIq@5<5l%&-TI zISefRj_+k1W*$C=*Dm_l6Th=>*Dr0@%EGt}493`paGEuJqwl*eqXwgtITf-`EVt%V zP=iudMy##WagfJ+@=h^6wJG_;$1Bl2b->@mKFM%=#{qP3USKUdObyrw^cW4thX>xg zK^^_MC3|&l#CnFgzpv9yLW>Hvy0(ei;i7yqxI zy2eV8|Ekk%R!@ytD>eKYTXk8&LI3<~%wf}O&_<|1ACYXVU$n{J`Ca=5_kYj+!^87- zX=lY|;e!tLR@HQOfP)tHp`9j{*JOqD#MLWLlBb0CN}+evNn(5O1mourYtJQqlwWbu zici(sDRQ66eQ1r-_v!}qL9baipL@~CgRe4&m2K)@(aW#x`W)W;`+Ii#8soDkWp;I* z{J;pcm7VxEr&$x7rrr$riH~HV-_y}^s`bugy{&q8%_W01PX;m69O}UG*^64vKFvnr z&mH5hS`W1EWnY5k5@Vmba52DMo)Ks6GsP=_6_4g6qh=O1C zqQKL+==E&&%A^wmQ4Om04rUXF%|zxiRIiBcR~=q9IfT3_WTpl^N}rbqK2AIP0b-1) zHDD*>>*&@Tz{3cbdj*4Rofj&bU+U$sugj*+L0&A#Sy>Eg5S(hnYnsYPsL?_urf zCSttmb5mo5>=(@;ADxL#&m{Jvn6ql^QW;zEIUOn4*amnZi^JjPH(jg!cA4NuHI=pG zN86}#>A|P(K?n38gWa!k;LG$-i`>I}`k+lEvR#IJ=_nx=kXKqtJ|v&~Ie6tzo+=q% zMEyLDQL9ZnvWI=l-F#Pq z4k9q5%GcFeH8_Ges=ia*nAWAL71cUgG4WjZrMk77 z8n9__K&}rti~+Oa{)&YTtep3G^emi()+en%`b=Y^*R>xvjapcZEm#$|^D*%~eGTqs z#VX=|$LA2_^{|JGuO15($U#Flc^K*yI>m#+0d-g1z}-u&X78))Yvpr3uuGq3V|QiW z(x^8}!LF&!T=)*))*ONu;!AS@AC3e3Ak9^|bmeDqi652{Q#{4Kn5KT>k`v3;PCbau zo$y~5y+XPeTXV`ii4DQ7WwQ4z4LhrPN7ciqE=D;A`JOuT+5cv&kPd>`@y>4=Tk%Pa zT}%$JoLXtgVNJ&XvDgVaP3*OWe0-~Nuhc7v7Mep2c2zn(qlnr8;hq>os`7E*AqgH( z4kF++{9^GSV+v-Ct@x?-V(7?3Hwf?ftW}H1KWpDu$ti3J>!?$#+Zy{O8GoMfC6m}C zc(H$Z2l*1-3z1=Xp0oCzrWb+>@R-UoQ;;pKjZ}j!7{z1aNsX<&yct}hv+$mc45}Vl zN4Cz$Z9zp1I*MW15LAw7~~4@UA`5 z{nQ1iUzcFd1nz9vk}CWRbXgWMoPq91_wm`|E?fu)=$};P;e5t?bNOB41^Yhmnd7*~ zM+OUdP6;-tlG^lI#&04QEBIsc=p*z%@A40Pe2txhP0=1wtuyoJ_my3F%EuNC(hEx+ z2TqIl*oD|b?Nun?zASJcJ(UWb(wU3spx;gs(>sY@P~Fl&eFXaliE~7$A@5`lR1f>$ zG=2uO&gK~f^-WgXg1>W``i1(_)LNVZ{tC+^FO`K|QI1Br%~W(^F1o+Gt^paVce|@x zv+s2ly|7c+*vJz2Pq}Wz7*)Gb1rBQ3dx<@frxgFAdxV2bo~8XJMO<4<-lCA}bC92` z@{`Pg8hLP$3r;fmTYD%4r{F8poMoG!Q5H1Nx-_#GJIT6T`{?qphoz?^19iy5DVGV! zWF0wi$w3D^*tPIG(76KtrXD{hiqF|%xu>Z2WnAH3bSPln8b2Le2>*(uXfIU2WAe?h zQLJ^dSwpK1UVN(G#fMqgXw~?L53`ZY0-jk({!F&9Rk{crAl&CN$9%6HsDt<9=dz!e z{TZS~Ax92#O5+)dDazJJ1{If(zR7?l+FzDM-BB92*IqlxsSe46_))cB&KJy~h-aOo z2C7N60a?h#w&#fFIs7x@=i@^Z19vg{tDvcsT9;E!d*yRo54x?PZjkw;0jKsTrIT+> zC9a?tiu9DOQ$2y^;kjAi1iHvJmV)P6dYPQ2K1+K>R8Qi2M>yvpFGc)b0^G_y=Ap;M zhtfgH(YQXAz2n)kx5BmNkwRUhV3%!{PIjG*-j=Qk?X!4C{y_o!R!Kco1F_pt_P4cn z;ybg(@U;hVqC9kBE;5;qe^U%zs+dm$xgG5t>12&5zqViNisda^n4h%1{%-FfcCrp1 zqLO{o=<~c1#(}p=@ujNqizD*ONAOGWi{*C=ECp+V*Vb6Gjt^QJbEswic^URtK2SdE z9PxM=I-v%+h_J3`XI;~cKh=ltG(g{%L44`0-&wKg*)i+ti&+D;yOs6Q{XB#GV-Y@k zSsn3>`2B6H&AQ0x$S2jBMDzc__L|MVI%PdW*vj@Ouo5H27b@i5BK&&YFa6QT{9Aop zgHPq_s!gB6_PG_CTbO+5{$kb#g(sQAN$|n^E2#~sCl}em`c!_g{9(;OYqQtZ7HndA z)H?gRtUh|0b!;7TKZ#zEKZIX&k~y%pJq5iY#Hw1sLFmWo8B^@V?-^j-#oSM_H>5=C zB5X(wdyKV*DNptgT_hb`FWF}wc{_7Zzo;(!lHP%CJB<%|iXK3v+?&t(CY!p4O#FKJ zppx5sbdUDS*5FS>q(kv(+VL$rdB*9ER`yh4XN9x4|E8J>=?D4e%1g>0E0Nrt?(~{t z`DLx}zMdi9x1tW3;RogU*vfZuKle(H`Tg*J(Mjrv@T*;q6MH{RjjwEZCHN{~9az9R zELZC@Y?7}HG=J%0_+9%KrF-NP$tS5Nj~yA9ay?ke+D?3uulu#80cVmCJwtXyy4=?` z;Gh^7Dw?Fnu_eqwb>>CTx`6w&Cd9Kt1dD)8x-@ zc9J#ODP*~UIEQ$-eQe&QCPysRi|nyh)$fw^=f5um`i1*zSw~l3Gbiq6;$ z(OEdI5`Tc>0^~`upfzep$5UxIB?4fC}@ekjOq1o>gl zU6X52EZ7g?!ACK1p83*ezIc5+9nk5gpN~1@>06G4o zbn1q*hSRmWNAc|N%-n=GeIJaWIR{6Gqoc9oFdV@z7zDe{!iS#WutJA0X6|u#;e>I3 zQP=x#%*FrK^?rXiZv0uq?Y%CE-}0!F(3qNYLVmU-RF_$D4Luy_d38*1X>EkfRS&8= zfACMRBN5h7nYRBA|B2T`$X65miq{5v!j#vH=Wu0Hg)-d`$8H|aU1PNuSb4Fd-V(x?IjP+1AG?UkKl^K zaRfJW3qFUi#d+JWi+?`C&x`yc-UKg#K{V$a;30wDOV!pewE@qvwoYVEHivT8f?3y| zP%cOKmON;F%sIe6`#y=kC@wA9s5bgUCi?-izyUc5?UCzPxahd8Y8`aEDz_yctd<_7 zTDOY!syWm;+UFyl)ZuW(=`DH)rtloXCpeD23uqk5zUJxo__h3|9Fbtw`517;@fzIE zc#=cnC&#IcPr@&C+2NYpvU=x_SD2@+b=okl`uiLw_mM%*BGLUgc?dt~eRrIA#R=BL zs()->yhx51KY=|~+AA2~O?hl`%J`)OQgoK@As%-eXpTJp<^40j!Wf#fuJd@8VjTGKE~|VO z%0YP6^?uI_xN!a!z8o&$N^=hm=U?R2pC|Z3ygSUnv-~?fPyGnv&wqXv{{*^Ocu8cR zPy(`^R90w-75FI4bFqA6p9d>N;`=&nQhQMtX4 z7oBdB;TP%U^W-^>*XJ-E;VY!Ej}w;xzSBHHn1Xws&qMs|zX5-c%MN)ZpqbN+am5po zffM8erSn|==@sO4wCD)&iuzX7Q4afS>>-Py3 z@WuB>W5lnQy~`%g9>At?LVj1xh4kbx>T(+36F!IY;+ciSh=rek_OgeXKlk7#B#MyT;l>q)|9lcow|iRrC#ILpYF5^|?Eo z&+!z{UpR>KhU7%g(ipOFvbWf|oC58$5Uk9_WeZr~;iOdgLb^A8KlcUxLVzRb#SnJq z{X%-%A@|A;BocQ~pLZR})%4zG@5QZee?=ZOYTd+Hn+ND)|Ms`^+}ihjOscn(j0;}@ zEE-EPr&_M(8l zd#CF|8pQGUihTXJpD)-GD^;6D?_+Yrfgg(x%h(C>gOU<#jNW>)`){z{{3G9syK(K7 zjj;c)in?3%;>u=CDnBTM=eaEi=;eH?`9q6v~RX!`7*JM zbz%f_#L0_n;ouEoR^)sZc05m!TiFoYhdl~(ABD-@{y>ljBKafdkpR)Q%SB5XfS% zoo^FHXL!k%c<7utu?`;6?gk0jy=>25+;}vYrd*9uKx4y8;&pxrq)pPW??eZR# z;~VGQztNr@)vPFYldO0)YetuaIQ*KQNI;??g`89D^Lp=NSaX(NxEsc5`$-V0U!O#8}-=7DsCl*tiPtWtTX7>Bx7i!)y z_LlbTu-~|MhF(1Eqd@O%-=i<-LZEZB98pY;rmM1F&h6N#y(k=w|m zZq9Kp{znhGuE*{tv;LJIm{>v%pbeRZSCVSWZ3_QSeHR)Ah z>&iW69oWDm8({6Cz?NM_??HPN~+lPt$ z6Yrk8^1x!7x2gZSMqHVAF?pjHb=f7=jeb10iHt2eIgR2liH@QbxN%sSkN+LQ9O5F5 zBdt?jfyZ;2s@?Y$UIHA&@h7?A8M12u4`>|l2JfeovL{^YUFmiH)?5;@wB|t{P?vZj zBgOi6=sBvjFwc?w58-cM-7`fmZtr8vJ7=cpWjlTDqCNicFRg=|cYWUiy$i=|=E_}s zMQXC>+cHR9Qhp`9Rf$uFbPnK;(?Gl-S_vl(ui|pDyW$JsfkS7(F1+ZhzvI{XImDlI zn_sUpxB#XQuPKsszH8mzvbwDWODJPM56_bwsOw^%5WG-!Z4kAF-ZQq;OO4yiG`gg(4v<9iRNIiX)WzVXtX4{e-%F5UCztdZUn3zu(LOWz1J zMD@g+$DM~>n)ml%5FNp}`yjwCn;gg~{4HAQdhw0(0cZakdD1zAJI*@^)b^%!;O_%p zQKZgwU-%65xpMml&mT_?VxC3hDm->2noIvzvqvRPfA5dRm@(?gm0Q|;{fYNl)LzrY z3s=a6X4^i!>D7z-o4@#X)Z-6ehjXlNj()6>9?vnBkZ)BFd&g&-exb~Zo&j&f=^NrD z)R#v#FM!kcf^d&|dmQ1@aT3UV0&&X(^mtMQdzQr${3czHj6K&lg8ewQK=ml1yAJVs z*e4=*$59~j!hwF%ytTJ{h~63<(0%)(U)$~XK4P!lJv;pL=dR<_>reX-ruOJhik`Uq z>`V8HaY__D2aOfXow@OB*|;NELb`^!($8^vJDdSb&fCnbdwV6|4_ycS z6N<3w$aZQKHDmO_@bxkHI7V-7$8#F+LgTdN8s|01cnG85)EtAq1Gq!_UwG?tWPIAX z@B>yJehHoXsFPnn-run4D{oqC{RVr`F4-#YHu;em^{7{@tfh;5{IdH8N%Xc;3`pxk z%|q~pa_{~+u(-^JFot}fvv|h8m;49!x-E%cqdd8umx9ewe|GsU88PY{=1X#b(_50y_GJeOyO@QH5zISw1+`rqQ+ zQ1>6ny$qLyAm-DX>p>%es6q$t|tH3Y&zY7gIsc9&;~*0S+V zbLm9!gW%^o*+JI>T(fYCTi|`W8at z>Ww+{F1;r6@Z}1#tbDka{;}9~#WGpXCcq=lc`z=6f>}H$y7OGsE0$4*tnaiQ>R_Mv z@ZOuetL&z=FSF149qb-8XItok!Si=)?FK#o@xk+~k*2ObMmFe8OAi6PpR0`hq*^bk zf0g^W@iAV8JvRSd8`xbx5c7v4v9+YWyIzmcb|wB^HxvQhnp3~(rjb>D50&=aKKbSs;NT(_K-a6-Nn1srFi(THfp}TwZJ3;QnGx28$*IL_%_8Lb#BAUB> zYY)hg^--VHXoK`Euf~Q*rW}6e6Y5!qRdfjt!5*iR^Mz;x%zhvCJJc2W zu40y)95Slj%Ez@{C5M&4K9dA+kyl$4=PPg>_o@6D;K6Aw9KL`P#jxB~FrNBHrm;sQ zFUmd?`f|3d(1(ruSKs;pxiESU;^S_;!TY(!H|WE0#(PpsVGnEBL#Cc2pa0ok@y?q& z^k-i37-0c*E2K`R(R;)n(VzJr!HF!pjuPyezkbtqaXk3n;b-Qp zJZ%Vr`Wxx@1l4j<|0_Eqm;zY~a2h^G`D|Sq>Rf%V^@h$K`{Z}UM4Y!ctDly9vwUh9 zEAZ)L+opD|(@%HQnnu^Hn;2*Z`k<5k!vh=FZ2!G)ta1DtI%3!JM!md~s7iI?@jj)w z^n(zd-M~$_TDMqsd{MH2E8B8V_&=j$>#^3=vg)Ja&beu_3c0A-Mn{f>h>45aPzV4 ze)Z?J!8-!cC9|QS2R`jroVL3ogf@;FG-Q;F^HP1G!6}S9}6>`LYAT zrR;!u2CD8{wIIGm;`>_aqC($I wNO9}9_q7P?y_ewAQ=%Vy-jPEd0*iz>a}WZeE$*eW>|K=LhAwdH=&!(f>ZE&3_!B2`NP9*>wr`JCj^gj zzUoyZ9!SvMMQY;Y)4izQ{a&Y6oF9Z&u9wU>9(jKFT+!Hh2VPJNKz!+Y5zwU`|KdLB zchO$Ih4j)ow}L(6QEEeC@P0v66Z`D%c@5#gJD<{oPx2?`?{t04Rj)NEZUi1>rLtE7`DX&@5 z(&oN`^k543PsP7+UBtEOhv_`PJd_6%?9zp@Wli+i7EGh(Z*V=l@`8-2rnv;XJRm>N zHg}GCp&e@Gc!$$0`!vrU+6eFZ()+23sbf@)y54;?ym6V@Yuq4pV$u z_942kYj1q}CpOM{xD8+6{CnTwEAYNj>_HKHufA^8@Jy82>xtdl-j}6}nu-Yfd6Yj; zpEdDnGVkls+(jqXgK=Fbn8fp`)F_DNp06f%>+c?gFI_<+e zmc1$-lXE*K{m7xXk$5@N>SF&|4BgmGf5!>pC2iE+#&|Dc zpbG;ZrGRGzK09zh8_7jsW1agYY1H+r&y(9eaN>F&J+8k+f5myyfmQx+a#b0zk1Tqf z)msMp^Kz+Qary#lqUzkBwc|o|K)k@ZNbd$uWDTXy=idLP^kZg!0K7avKk5nIJyVAd z+_G>5f0ur5yq7LY9lC1bG!MnYBo9sVyvu<8yfNfKz3bM{gAwARt*oUc_wTcweA|1N zYX4k>cN)q!cD*7xa)hue*RB01lKs*M`zNT&(!Pvr;E>F_o|X>-y*&Oax}hgCSodet z&Gk@{3+jGwTPCCVEh~=xlq2wctz3j=v zIMa#$X7Vn);C&SG6#~8%oY~|=0=X%ebBT8tPG7$7wq=_5faW7R?yw!fEnF~f4!39gEq)H@Gwamn82bYpxsAv;Ncn<}ZBhU)`nN#eqH(ALo$|l;5oPIIBO~JnwJ4 z^5CiG5c}|z9)9)DY-szo=MW`B4zFyiY?tdjSQ(-VSs&{7B1F@4s?@NGxv%hpcsZt?WW)qB>(zC88o_1HJ_79VJ@ zNXMBQ#0hw(C3XLbt#okR>h%ZIlXTGUV=0h>5PqHG^bhS?n7@+0kN_TJ4Ei zDVYKGR`$4~_XJyt>KK4ocy&AgyYmCTiQn^qQ_oaxAc3=VMP_XU`BLpqrT(3FR4vep zGPZEp-#xp+=ULuKw?yBQQQqY?d-#mJD1CUy57+aK8oh_Gm70i&n_qz&*308-?0X7g zFj@;YbP+?ITC*|s&2L<}X`7F}0DlMG-y%wQ<8;7_L5?G!yKr%2=fH#d0&OQEwT>m3KHeP?5_fuT3IbvX{3F=rU?#H?>hTo$af!dx0?}-tkcS>w_gP0gL z6Fo7+-qdpH=+m%a`N%_MbkO?QyQO{mOZ((c(F46p?BAun#%qbh@5J`Brk760Z))+g ze6~XQ&*Yx7u``PC7cCCa(}KPd&AjV(X~N%W=&*$_gU^7+p+9gs&&PQ|f9oBvl7}St zNB&Rn4%ABW=6NcsQO?C~xJ_FQtUndt1w;SQJc08V^5)-r-qzM^qqRO zD>mGRpI6$beY5Z?v{7t$Xzh|s^KM(kR3|RoahsTgjjNg%^WJgw{qzqdj;ePFB^vCng(y7&v>2nE!q6H8M$$-EMjgbZ^}BIA1URVBgMN)82?4dc@3a z?eRX!1#}{DF!q)9(Vue;y2@{yCr_~Z_zQnuQ*3OGT8drPi>qE!Cm*_-_W{hTZL!zn z9`ABIpm!qs2)nzeS5iC@x?u0}fioGMP}bi?jX0>>^39yB|zEkbCrg z^MJ>(joRA-KV-4@Mel3Y`X);?{?J_Si%AC`>J62u^#$Km# zG4JDDSl@uIV{dvN?++$cdprU820p=@1sr+UgA#0cE57{sScLa|Q|AIbMej25q8EFk z?B8RbKJQ0g;gI~7u?JwPpFZN$Jw2M}wFjeJ_TZzh=yipTl8p17wU+5^>V9}134Yul z?<;%fH~)s7IN%6>V1V~9bgbQGeYZqzklgUP$)f%dS?mQ)k<6n1a@gxG8>KxA z>Sa|+{CkwW8x=L|g9nz@C~%?28+ae`XKR!8HSdRPCSLOK;;2pXKIDAl{|dSCQLcMR zF5&Iz0egqz?Wuly!ux?AgM%4*OLw8a5u#4CH(u+`hvy?Ws9Yw6vjZ}0kf`ad6{ z6R4G6zV5OxyaK;K|5@nY!TMpIzSV=^aP;DvHpKlgdXo0B1{|etlwxL`x!{ z$>>1IxB7==(bp@VHIMuA(7zDdP>B4Nu)nDZy_Q=+zvGXwT)x*s0sa~{z9%6rh+i})$6*!S_PZ`s8Ueqx>QdB^fKe^2iSd(Yd6 zgYSO$bM)m6d?0umy*LBy+gKm#on8m;d_}yc%WhLoGr~6Wh;VFMScdj%sy0R)ehPpts#tkqcB$z~c61-cL{O z5%T|e{FaSwufnER^ZS>ZGxp8;w0*TYXBB(;63-^@d!Rm&(tD%;XG^qE9ixFo9BHMz3S71 zj@aDconGjYVSJ<^WWSj`>;w3Q@___+{ z6L{bwWZ(ngVD`BTJVOVF2Rg7-QF1)Z)H(Jn(nA}6w~Kc%c44!7@N?u3OE)Y+w<+k| z$v$iKCtn3_!9Ton$Nk?{d?EE{TamwuEs-xdLND?@WPSqQZ|pqra$+GXH{SAo#!KM3 ztiRXob+CTL20~wbR-e3N{1e%9)i-6M&y%rPMd-0q`7d0TUyr^-=NGVsE2S?_34d2{ zT@}}SyD@dd114fKKlwsKz$bXL7VIYXvCUdp zwPNy(XD{5aethTa@AA$*;$Wh4^Y~d?zV;?C(~};a@1<69fO@hecztU37J20ZaJK`0 z9b!Ko+T^Xfyc@DPkOOF(M4Uo2*O7&c%a&4j@1gg8wmoOxot<$Ue6>36df@v!Ao!&R-bN30 zqp!E90qcN7yY7Acht@^CQ~ZhYb#_f3niiTUWZ64q(i9_LK6W?;_2u9sl@_JH>u`tH9!Shs(1dBy(l z;z`B9ji}Fr`bDS*hWudf3Bx|9aQq-< z6psJ>al^mAH@@ca;t`Gyo)vFUy=WqFK<)jlAU2~K2KAj#UPw8GaE&S-?PVN<<9+`e zA79rquHWaM^|xYgs>xIw@A=po|Mcjq;GmyA56~DIs85jMWTHX1Z^ZG6UVKi2zd5$Y z&V+xBiBIA8=o}t@$M|j2uX*00lAh?QV^F_;^#SsJa>8F6{+H(vj{m}(m|rkffUn^C z?~N}S2>*`zfc~A>#1?#|TKZq8*GD$}vlRRDy~QC9gzy~UARIqDKgaz`^9^C={5S9) zpF@nkQf*St z>vo!cbLw%TJ`6eZ;86ZjeDItP<1`hG|Bg9meqm10#|_8+8?-0)!PrUY-Po&J=ct1@ zwd+{y$SuZNy&`qy5*^UPK#i$ov7V;o@bUrxZtC!*Taq%Anuj?4Wt1*RV9U4op z>l}V&O({Q9IlA7}A6oxwmpOR<4t_unz2@{@)@ovT1@xAaPLfXc^_pM>*8%Wl$`boBEs?daELM?47Fn#linXt-DpnPXJ1H(jic528E<>_O4#^=yMT}%= zDA8182@({^f&`&uMLmsnTaBdA?s20%?&)a^#-8?MW-=HX4LCNO$v7}<2MO%Nj{gbZ zzWM#md#|e0vHi!x_kHhs@7{Zsd+xdCo<-RveOa4Jv9*@4p08yb`dtJKq(8jiwU)~q z(c?$J{Sy6S8=5(Do6oN^hO5{O&Z2K0z_(`!OU{u+7Ku>)|fISD?-pu-@w4Yn~S%}Z!r zv@g@3nDaUB75&p@3Fp`4>`ANHuWNtvyeX?wiLDzM7_bwUW{&D%Z0OQp2DoR1AK$|r zCx4aNFV;bQK60@H9~LxN=7Ci_uY804Ay?Tem*C^5j_f&SDc{AndkD`*{Iq{zxBous z>}(R@QPU+rVkm zyjHicKQGr>?-y|AuxlSI;r~+jznpo}Mords;=Q|P90PezpZi+q`V;8wqsYZDs8B3@!*zW}U zgbC`F3~`pyMc)1vY{~1%y{|mT^4yxc&vQ-qT3rgdJLkh+NI4+f_Q`+J!a89Q_bK0V zmF4{#|80HYZu;n?K5q|W7{qsDgmeATgRTqD$2?R|YNICS#*Xc&mUA5CqW)x&Ul%{h zwb&@u%4_tM(SW&5AKEiZ`OiGDjzPGiZ)8Fx^Kz7V?i?7zzh*nJxYo&a-fy3OE^yJ0 zow?ud3rCjMNOiU7Up;{_l(=6s4=lNG?LXESc-wpChmHRE9Xt=ttr1Yg`cs3Pn!?WQ z{F{LH#)Oyi`+nv`4?ca}Ts@3u``mNf2Pe?Ne2|UgELKmF7sP>iCQHo2>m{t{?`57f zG55>BiLn{-y0rl+>>E1OB9|JlUCk(WiM^YK?~Oguw`_zO749L#MK^xMy_~&iPqKFQ z0J-SQOR26XAE+-!u2s&?JU2G}N4Zyl9nfDb?_cMv;ibjN^q08)>s=G+;rv*- z$5>|2J-p<-f(Hxur-9qKFoiB+-{YJ)kD(KoqkD+{yNJWww4GeIsU0WDS4|dZpw!X()zk%KVWybK3@!X;RP1v*>w{}J@Z1XR=|Bd}0Yl~}b zT&!vO4Y~fCKh3j|M__RLo_|#!m#rD%y4OB7 z7jU=-k1?>e#X9d878>&LjxX&dTdUD=Aht*=z<|FFdv&*Xcn-wnLccQx4eFDjSEfKe+G9^bqiX zo)PrKCKUd(NcD8LzeeGM*AlE1|ViFtf z%KN8d-{%^$o!sN*<8LFcr+L9!ySh?GXM5`FYEQ$Q?@myAWg0u+ESKw(XKh9Q=9x7Y zsdX*dsf)O6`ye?%se{(tmHNq9Jcdni2R6mo?VV|k%QG$Kzxf``lWr{qYu41FN2~{5 zTRGD)7p=Y<+UNXVI@U=CaH-A0`5QJw>}QqKn5c%{>xeIE2G3pi*1C@j8y{=6`6TP0 zWg~G+TaeZ6wF`Qgi@$*!Z0n)bCf3k)&b-XUZ%%&cVQ%u~R_eE~&bDIn@7~q|?~3nz zktcT>d8oG%54NqXEp>qJUVLJuM<4&257k<;+j_RAw$9Gf)zOx=chVN~Wj%RV8}K#Q z41KLbVE*4G){|Dw7CQ0i+)Cbu7V4K+^QRkljC*eD0;klYXh9Fzx~-LZGE=Fet6M*H zTsx`d39iF!&f5^wohy7T@Q zQ5$#9*<0aTtpCyCl^4?F$$O~}xj%$X+>S3+2Yh<=)lWIAzn%_Xyn$~9F$?7L=q8tm zI>YdOWA=A(Ub!Dz_V1_DuY5$j>r-knzrdPvod~9set~btT5TKpP+(W7Lw6)&a@Xf11P8Vn6=Z*g{(cy z_9I&*>A z*SqnX!Df!E=^dNyZlTV22q1j*@id#_e?Y!u53V z#n;luKlu~RKyIZu)^2kM)M4Yl^y)k5B>n)_`OweFHrHai3jcq2qLOvR*a-b~3O}uN z%&P-e?xTZq-oBSwFE?IJhcDft-ZOd+=W&a`vUJBYwM%IaXHI)B+)QU45r>Vx?oO^& z#yNZRRN8{g>u8m-dxZ1`x&oi|LbI!|W5f@X!{!|;LxmBGT;>y|#{ga%PgNth~QU8~7 zIBmh6nYQCoD4!ai(N67wJ0E-}U3u-p)XJVvd*J}%dz+jrcbG%YsYT8j55N3AvTc|% z7<{iT-eJzcQ~0oa@RL7FAN}l~ra$^ODW2PV<|_8CtAT^Z?|c|@z`3x6+KKa=;mu=@ zIe?Gwr3a7G2S56IX%B6?H#29>sT=pxgAc!%u0DP@-FW(8_z~^rY)@GA_s{Z8X>;M6 zKl~H1m+7ab{R%&JKZEc1)IY`;!VT>M_y;`zuf1vX5OT@??no)a2@)Kwcccm+1h$yq(~#f%xpDt9OtupQN++t?1+T zBIDk}dENf=_+%0HVJwq4-hcE&jLW$ CxNyiwwR4-n&V@Ww0T!9J2kW*5^{Vr6eV z{eYOSH`1k7-b(EQTUV#^JVcci~ zdC`>v7vK4UJl7NHji3A+`viMX?Bk`_K_{2)q*J#aq2sfE;cRw*v*=5Y-%F?Pw_Z4Z zH+*y4FOS35%E&R+a-`$FxmP0R;vhSu&d9_jSM*VEg-^|Oe#=qE<|G`>8Y#`|x60?t0+ESvLwd|oH$ z@BSx$D`La?CT7y(&%U1?y!%;t<&!V+Ij@~Ki`A6Z3phg-=5ai6e#n2}r%OM9ryM`Z z$YZa(AGK8WA`{!S(~)mLKZQN`(XHRolg_{QTg04w0spwD0;Wfdlga zXE<0x{OcgGp?AjtTPJV~1(L{?X1_Hq5$s0N=z> zbc5Z*=AM7?^_Yj7kYS#?kK)sDfH{5?zpJ~S{2-0;u5#_xD{qGEz5etg;<+ECgZMmO zdh$uyvgc4*y!vwB!2ZR7^@tbokySq(U|sx2@W|uOzL(D3e>vTG`Y|{;iypUt++*&@ z>%1fEL3`;hF7i*muf8%It^99)@=1mp;v+eec3*e(rKhpi>_xY>HkP@IJJ6qYN}dq|hf)MwI{ZH9aR7azWgzsLzm#1d%+vxq>u~c>^m#i2P%^yj}3CfG3j?U z&$@o?32~Ujp&qz^%s+P}ow{{DYH9YMAD;f;hs5#RO)q`)Y5MS|{}7+dSJTCW4qrt9cEvqvwaJ*@q+_<@DYP^V^WnT%8BXXDObX8rd!^pA5i^Bo7j^St+h zH&*6DfwOow-pStew|zM#aZ$q@8AK;Kbr;!&Pfjmq>Vxb>&%W{jIW6C0EhNt;_T1yF z3k&!y??0W{7H5|(!!s|XGwct}-+UomfG<8`z5M+5{xs&oG;8Ux7v4)xKKd;9KpnYt z0GWim3p@Gvu4Jv7lk}-Bw+vUnQoth){GNRp{}%Hbo;J7PG9Gd~6*SK9l)+ixCh$=3 z5AC>aIyXw;MSUyV8P61J_Q8Aj=Hs{7Or4O{o<8(r^7>%AGtR4ly{IuZEK26jIng-jZf43;gf;$_3T}y(D#`vupW?49C&b*X^c_HsT7Jb~u|zpk&@Gx&*nE=OD10{60K zJAUsmH2nZOHu3C?dxlu7R_Xv7->jXgow!}=$qY@+Qg;cTz+H#a5p?DQ>~p5!nfX&! zg17sqEr0XfZ=pAIg|4=a+C@9r2Ohw`btCo*_f!FY&c_kwx$1kw`sFY$!{&J=WA%JF zctQH-xRK^rdl??%KK~1Qz;D~~TF!47Ph|3SMJ_Z&oX)xXkMS4Ja{P-Q;oppopuXOM z?Q(d6{8rc|>Nv}3#uwjQDb}std-7tsjchyxZ*=w(+cAv&_`|;*`nbGi{;xgg9rNrr z_p|0k?z>p~a@xdPE#$qhG54Wo&{-Qn0YCen@T&-Xj@&<#VUMlF*SOewxj%OwYHk2?LzHRrWo*W-G-InM#}@5AcsJ{bI*{;w z?+^X~d4sN_>;8>szk+85utjt*f9@hTT>paZ%**VP-@ugdg5QCkcBEO*78=L=V7&3J zv}Mf2^C2h118sP&T)b2G!(?;I_@`oy!4oltoDXatJc$csrQeko#eTy*M|QC%&tZ36 z(Ow}g;$pmw)T>$|-^UndBnQZmd5AcnH-Ga7(QX5_`?C+8M$Uv~m>Ki(+$?b6xM*AW zGx*#Stz5zy{NpF@#BZKAMsyh;1>J zFTo#h3O{2cmL;C!UIsJc62=@C#dkjooMd^@GhBI3*!|4%9WeIb4em#qdHdo}nB!Af zQRocLkBkQj_=7KaHp4?^oAA3lUyWUN3o>CGfAKw6??p{|Z4_mkE!1PD`EP&c9|R6u z|Aj#tknqQvB~0{N&@W&te)}m;#FfG3cjZ9jii>ww{SUm64~+ZE{2#hjh6`zJpV4o? zn(=+c6SQmF-sjUx*qw(34q{H^^F+R{r^cFg%RY4JJ@|w_`Qpdu1ee+O??|WbypS$k zzn9+p?oY@edndj3gFlG5kc}U@2?K3^#acb`LV*YRjo-n?`G5W&xX8!OxS}0-MVNfn z_VRawFXRnj$l;Imqky0LnOuYx$hX*g+CJBR3>VT~yaXQj?x%Eb1b){`YwS(4F3u4P za_iMMsb4sjZt}T=PW{gJf136Z`*i-^%V~uDQ}iL7gtve-U|$8Jzk`+;Ou^#;KhFp| z-{o)dl+l#&6>UnhylwBr|Kd6Dk^L7i@?6+ppkv_H_PMhEcwQLs+lu+(`_b+Se~1rp zP~gOvL;0hG^-3G}-qYm0*n61xUSeCYF=#8UN2khQR(2Ke({Jqm^ZxPgUxr1z+i&24 zPx^?tFF)isD|k70AcuQpZqQFIBQjhRc*s9#$9$KuuN3wIe(o>xL4H4*6O4i1#rK#a zj4{>?#wjk83FWN$8~VwEJ35K2uP*Y#w@~|W>DCJw{PG{;%4nR!#d|@AWwuE;&;DG`cIX;BbaTGk{-X!>8 z6>e7W0&aQ!S#go$#=INyidWEIzGpm+t&~``2jnw_%Z*0 zIkhvI`Y8@FJgk<#fqVD7j$Jwj+~AGz$A6AFV9GxOhWxwu@%g}yFt3^m${2Aczeqbj zea^9oE8lZW`4#Z{yqCD+zB*(^_e^$rU!HK@uYSJZiRGLNv|)ViGvL7I3VKCf`M8RH zV}8(A@6o;K<`2FRzM2^wfxj3_PTLq)j4dA{@HocEjq3e?Zv{8cXtPCkEA-@yuYo=A zmdU?tOn#?LFZ*OXaq&HHm47;K!tXfn2d{_^z8j+z^1*lGS?5e9A2a%7v@Gm-h5TK{ zhyC%Mzcasac&!+tFxj8*(Prq%_EX>lehBy-dvPzG=N+Ca@*tW!L0XDa&tGG1*rqY$ z%AkPV-_kgHH=dy_VGBO@8NQ2$;Bm*}|6a5kd=US0-+90lyv~0aZ?EuMCg=DqKLEFv zZI=@Zuiti&_feWY!#+)!;643rYKUXbaFXGB_50oz#%xbPyU};nzI$Z-WBsoh-vVKe zewRNBdV>eX68t1QJikKU4E`_CImc1RLg~(BZUNtk{$st*ZT`!+$Z@0ne;NJ^?`!c( zY{0)GU;*d;|95`zFT$TQ>NSdg){m&GjZaeaQM8-m(=j_n=_-!nyT2K$SE>7Jab8^c zvjKO=9C;zbZ@}++#r>QoS8$R)C$8ekXdmzk8|`E~pTq3E0`BO8z8tT8fH!$%i?w=~ z+vWI&`dhvBS^W6Tf#Vn#9$s6P;vT<+!TZIhJ{TFz>638;&Fq^ti#Z>2 zK{%WTe8xJ6-WboseQ_(DSNI}>JHuJ5A<91CjLR{I2gVrm$?*_4DE^~9Cq9Gr;j>j+ z$mj03a(tN2P8h22laeo^y_~ONT>0G2`pa-0^aFPHgs}$DcHme#azFBr(O2y8$PE$y z@jKw>|ImMYhyEgWs&XR#ZJr8ouuSjbKgL+#LYWY_cf1AMfd}r33%_#}a;ew{ua(A* z5%_m~^WE@WFUNnhiCE7KC-;XQAMHh(ncN84J9gWp-=a;wyI&1l$X|}%d-&W)d%yc^ zcAx)jLw=FR`7g%7bMj*37RurG`QVHA4;kfW-d?l;{gne5PdX;$Qb9N2&Uiro5c^t# zy=nRX=>HjV98<3}`eR(IW6~%1TYToY%RX0)*KrrLpq)B==6uF>T9B>EjZAi6X9Vs> ze4V}oXS|#7ZqOYXWb0?qF8?XpY{yT>C!Y9R{?6}gT@Y?@kii>k8vkXuD0qN;=Gfcp zD|m{0b@IBk?`rU|vLE9YHj%euc}~;Ufve>IrryIc9&A^<<^8SMKs^-4<;C;HTewdC z_Y!hYl~k6cx&xEc6XIMvr+d7!8W-ND4dEBI z3=fVmo14nNXRK`}ZI<_BISk<3Ik1K`J8JmYhP(wXY^#hIsEt!Q!>>Q)rTyeIR#vNL zuILXL9D~&Rmgk%BGZfF|*lPL)hE{MSE`&RWy}*OdhRzp!kkS0v2K;o4-Ow*UIHi65 zS>QbGx&F)NK@;g9-{y0I`;pU{_SMm1{GNT$jxxS=jC^YN*_!iR`o*5fKH%9B_Ly-m zhud7QRrtTg{0Lr?-|df!XKY6pwBb0;(+}@)R#`^<_OX1v^E}TjU*fX(&G(GPz-TT- z#=3^OD^>V(dwNwr-~(`*&GDRG@RMU+Pt1UGtOg%T>v5T*v(mMW zyq^Pmc9QdKU1}Rg=K+5Kw=hCuX}#&&k5k2DU#glN$Y>WZOaGi_%$-Ibz87AkOko5(4{kxGqwbOQsr|ok7C@wrcCmCE&im! zZrzjek?!=(pZ_c!{N4vqFGc;Yp4sH-HL zQA3SS=SM;F*z@=-{R_MG70u`3T>r{iYu7r*+_Om^-UY77$M}fh(_l?bW5xV0oAdZO zkPn~~+`RJ54}#X_&9!b@!TSZxvi36gqh18OVZOKwH?04R(MvjR+R~QEKKX&)J`*yw zfP;G>6UB>sAU_p2;=gk8?v%4GMVsNfx3Ufj^Rv)i-8b}K-p_3E=A(9w)24as+3%{m zO8d3sZR#B!jyOr@f^k!o=zMF4)2Sh+rZrC5-h4KrAW zuaP_uK^NL|ZPu2*V}3DUkFhaE;W9Q*c)eGSA9$t%LW3OszybLZLk^mYnRP@t;yF>= zX9-k<$x z`rZHcUq{UDzFXJvd+m%|Sms8n-vKP}n)r#iEZpES+UEPSo5&fiO!yW2N_ggP{^DP! z`g`Xx+5%h9#rJ(j-Yc#gf5LAL^i3~c3E!iP_w7p_VeN#EE6Fh-zt$1AV;-^48FRi8 zzv86eGjmk=j`_J<$A5)-tu^?q8Otx-V;yHs7{_Z)Ph&@O%+5$6oAC?nTk=W>pRQ+b6KDOKfBd_|Pm|vi9t-%@1$ZuUoH7n+syvT5%KZxB z>N5JQ;uYQzE@`%!_LIjoAFzs8xR6~w%kRijK%386Yl`^1wdP{ij^OjLrt%-S zTc$hTm3fZ8f*6z6$w5}EcaC{|TN`aWMK|z*Q|ekoV-7;Cr4o2D!1d4gd50 z%+D?Ir~(_GA&TrM$`sxS9K`d$4oo4d{G_j- zGw%jY#F0FZzbB2eIi9_ftylEn_@QyEV35aJ zcF&|LVl-@T4eLXuf8@GH&=XjkxAy68@gm&3FTV!=Gp68a+vd5jQ*$rI$}{S8!dW%i zOMYF~IOdr$-)G=~vH{@Ycf;jFsdBtK)t#7&JcD%|_#)az z$S3$P)@A9Dk1^IS=n?dHtT`_H3|Y_T`mUZhgRdrD%6rDEOPgxzU17h`Ca0VVS!KJ@ zl|JI0eBgiFbL|WN2W7N#C+=nXNyv&Ez7p~*JLTA#EMOg zX~UJ1Y13=?!7!%w_wXedA0h`Cv3mS2Xa0NkVQl?ZkR5CK%-zgfWgPNswpL~IDdxF& zi8ITbZuP|5Wbz5z0mm9}n(3Fc!Mvy>N18I-E8qvFIGY3K!OylA_+TH6d@Sf4XI9|d z@p*=4JpglunHRiA$1S zRrqJbJf>aoo#`FYRhaXOXG0ffyg@Hu^LGinT?*YR(KV~#x5|-@RO++9QC!i6zkQx( zg{_Ww-DnS-m%v;0dOobuF&3jE^h;?ISVqF z*O1$=E92`N=8VqS{0g`WnB@b$8z&?D@~7jdCf2YN8^7a&N++ZgXA>{;sB zu|By*#oR9DcShrar01<*i++7D|km*R|0!8`3CCHBf7^%Q}YBh-PvE(pj#QoU1eU5 z91oSWSwv=F+RRKUU^;FS7W|f#w7d|>><1#a06pT`&DbGa26NsiGz&BD{$LKV;A|`iT|yn zJ^4<(%RB&e{H`eA2M6oXVXJ^Ga3ZfmyBgqXLU(N)>?7{+aH<2wb*z6IID2bCzHMYa zHPKEp{Ot#4`<~24cml zfYF>UHNYZ`>%i9*YQgtCyqMMlXCrf@jac>#%!5{9u3M?KunAnW6JOoLe~rLAGtiq_ zfV-ag(#Sit<`H0yDJx>_i1Fp{D+93k3A_6w_xRecK7$;j zRt$7phwR(&kN;NceR7NVdfqc%3GiTouokvIds+k*^n+^$$@;R3^o~S$>i4 zfiIi?8Luz%zw->Ajcj!+)O>8cHsQmPamc}^ucjx-`m-q&hJ}DV?zVv z>}g5u<|2SMI;c7Ium0M9le*}mkuk^v%FjA*>-t&91@k4C6J--|oaSoUN{*BcV%E$X zG)kPzBr!tPl$au)Y+TQMmHaa2BTu&VHRhJS7CDEFOFVq>R$97pCoK_Iec;qZ>SUZw zv(IrI{c6Og?0WtRwJW|(jPtLhgTx;ly7KFhug-i8>&RPY{=UYo9psztOWOvCpPVLl zIk|JpW9&F4iG`bV9E@Rx*oayBH($50FS}1)B^Lb-`Pv^6<8dz?A&z4A(z&$rxl@ec zOys%VMJ`+WKk&6X(f1+ZC(YMq{sZIwtEhQmE`U06AvBU_b_@70H^tDxA>#CofsYdr z<7{4?zybZv;$tcv^t(U$s}G1tc_AGkKI`xW`XOF>f!Ok$N2tZhbHcyptJJI@KII@j z`p@yac~7iErR~x9azD+#5IGsZi}@Ei$sN>79x3tBPyT?By-Puh8QQe}Ibs?1(ysVC zc!~HH@ODx9Qcf5WUTI~fBDMlJtKn|TN%Eq#(X#q^A9+d7V>~}jm`vJ zrorvP^OuPs{M8tT^#FE*_kHwR;9>t)ucyW5$&oD|ii;c%@eYB5mZ6D#o#nxUS9274vy)pV^)Ixw_z$F5-Ur z;9F~eO)?&10*o!2WL)Ngo;24tciKu0l=l8nVuEMVAaQG>yADPEe#c>+_E~5bdrb7tunQGq@Kf8-sw?QT znl|}3O3|^6X_H6H2_s&r`K)11TkorpxMSmlx~P9W46Ve6{fmPga;BP z>t36_vx{|^e!adlmR}mfGOreR;nV%7aZnLM#8~wGu7O64o41lHV0-EyuT0+r@}2lo zujqeOzlB}rOa1=m#!=v8)u(p9$SJ}&-2aM;O8lB?$)mEK^Q4XN$R^@5^ub=~U;MJ> zqEi$(DVN6*aQ_l6iZSK?h3$=d*c*53^<39RlZHyeK z=rP4OiqEi%*EiN+nvpE}m*gyAU3<0-vSiwOyzWf>6UUe8brIY-G_l{nJn6ca^4Iww?Fy7>a)7E%VSz^T>lrUqw#P<^CCm zzNe9wJ@`}~7xNd9qX^x%npi<|mIe;gUt^5)58p&iWA-+YAC55;GzfU@7v5ZB-Z##- z%|j~A%b|NEHs=cT>G1bqOl#Pe6*-c#-2dz``M-KSvR69MM%a3V+lzgL_W8)^O#e~e zjqzxMR*!y$GZ*U|n;W&1Jxe9+R13>SYN(kTlRQ@y+>1F$JMPnjMO(h(b8Hp*Qh*2R zMU?=*dGqWia@g88I4g2!m+)>p!*k-wnkLpV67F*IfiH-Sn6%FY?Dh}ul(JVVhlUl< zQ#@3$zpdoE`S9#h{*ji#7BF%z@L1rJPxH4{ftMQg#pRBJKCMku&c3poa}nzbmU|DJ znHR9&H)$WT200_2$9U+sRDQ63;FK@J4j}KX>eKIGzhzwJE0iB<*uVH$4(t`!EGoBd zOjXngsbtTq?~u0H;#^&roL64azHJMm{3w3C921{mUtiU?bKd=SMWUmiKgl?$t6!}1skngX|by12l3(O>k*{m5Ah+}f$D zfvXxE$ERc9dlh)le(6=kSgLr&XT^Wkzp$^!rVPj6Am9WK0bjOe$m8;j=hqeRQYCy} zMLX^@>!5i(c&`J#I(WdmciO{h8AEYthlo9?W0n5meHs7E)tm-lx95J~7nohI%*SZH zJ#$f3(@u@;0%I+GnL~Cx^_`l?H`qu%SMwK|H_!cS>}mPbo>9+u3j2mRCFQ^Dg7)+m zb2j>=?}D!2IC4R<|Mv{6b|dy3_UaAT_sk=@p8a$qS2OuUTd*Uw;G4CD`&+oT1-n5D za%3}OGEd(I#|56&GiEPkX~^aLGv=`KxaeD+6360^_pNQTzH1vbO**N2*G*2-E^@AI zW1rSa{=qKt5225fv#<;Q_-@XFd)TjcV^iqdwl#HNx7o&+%_ZoVyp$`k*2er(Hp%z$ z8#tHN@-uzcF#dJqVr(3srrP9CYMmZSZL<^9QyONk+)KUdZt@1AV^TA2U~DiA4{cAQ z*bc`A`NU2#+}E9kwV5!ko{nv)n=|2VKFu}OLQcf3>}A@C6YV0ORUh%;){!0|ufRC_ z1@{lr?DeMEcA98}6 zHY;tJyR(k{gY`Vz+ih&?frbOIw{nlyw_{ftWGurA2gwCQT|eysd3zJ&%`gwFdu8iz zx-YYCt2q)kk{8r=+Q{|go~VZ$Q`@H&$iKFm9DKA#4vi7^BeDO+U(>n))^oGH!UkZ@ zq7CFp*v$T6EBbpIdzlV$0J@*)Lzmx<{%r16bI`h9wzju>Guv`MQq8zx-|CoXOTBk9 zamZWo8_U`nXO6ojx?Z`C6m1dvPh0M99BgvS?T~|dJ$r&8*X@ez2Nu?%$iqrIWqdDZ4X9vk%JQNj%c%WY zyWa6+^#F@^T_>{jB3m))em}f1JnIuhp3XZu;?Eb(u1C4?g94*Y%J!=oRr! zyr;ZDzOgpeQD@sV!SQDAU^`J?<*F=Xl)8~}5xJp_bse&!!Hc=Po-6VL)3@tk_8xsX z-;|&EJIb>S$dQfA-DYgf&B&JG62{0kt6U73n7@b3GGvl@j>)Ck%3Nz>?sar~b)bAMOVf_Bag zvR~F7w}HLs$kLjXd7qS={#a12=Nds}Wjn0w-hEV=X-VDmF$66}#)gqG{lwRkyO#0v4-Xkf@?UiB zCAXn@K*#rfIW=>?f?rJe6uDp*NAds8eGxsw)_*}C z1=jUa_{y3KWz5|*=tKIQS0Q)D@zvNu-o_ey`kqCWtwolVLDLp;x4DmteW5mj!bgkt z!WV))oBu2S>Uu}hdg=tWQh&XuSyqnUXBD*{8xBmQ+JneC{A@}my3!@iHd~JGroJ)j z(-+@JHTW%6?HSH|pn)fRWPvq&%J}UW?Xz{6k77}4+k5&X``OBx_*eeNzp;#?nj<^1 zJvC#FvwiIQP2|g|?Z?iI{iAiqR4T(i^I3EteK#u_@Es%>Uz%d9OH*p(tiznuK#B( zv?>{HUFLOtp4&Ow({@ph+_tWGM(51t6}Tt|_u_;;>%mVQ>uS>gbrM<2hA-U%zM&YC z@krI=JZePVwxHiDKOA=%=R1vE!^nH`;}7kOTA{V9f1R9NwsFq1Wo{u=F;DdQUduUk zCHm`HbmS&h)ob!;Kk&JR)F794QN3(r=#*M-kZ zfrb55DSM}9knhj70Rw*QAs>))bqml3_`XufUJ$>Jn1krL!SeyP@k*?3@P0eBaVwEQ zJFeVJSAX=srkkJscG^I`bnPqUoatG&+xcm%Lq@Y_QVqIKGkL?Sx1dY2&uQJYC)J`; zm$42!i%)zdy2!K8eyuv>1hu$#PU2VH9&<&W({ChV76N{KB$=Pg4QtwZeP@Y$O!(}c zp}s{Gu`)Nu`vdMh_%yAjhN$sVYp_++5gX+`w5gAJ(d^5FxduI_!FWhucV4I?WiiO$ zTAqjIfrnfUXcw(S_SR4b&RpnaoMlS)GWJDb;|m$i7>%*W$NnsQFHTOp@i}?H&wz){ z)W`W)RaaNMQ`6m)mNjpg z55Sjojh=zlj>Fgm<+*u{JufqcRp0G~)`85QnK7H&!(1?t!~2u(GXHwhhT)y5249P* z3%7$u>d>=m$T_!`HN)7ZwdnW7nT&8te|-bH$+GS_M?KvwoFO|$ zYVb8H>+MR%zW1F}H$D>m7!PBA4LfI`JMGY(a0l`5%`tR`Gar7QHjGZD zpIkZ|wOxPv0`*ypd}jI`V{$%-7x1x$z3RftZ_!>|n&WJGV0u?JUdAqNT9Iva z=)GmgGW|XpI4`Y3?zf&lliE+8O_k7c-Oe%Uc~i5A{ZlocYp~0fP+uhIp3~mFYdJRJ zjpSIJMc&q<1ODaT`Jbq5do=z2l_Tl*xPF@B;>X}Zd|2~$A8of2f3bl*UC1|ZVEkSK zKI)~tThPVOO`)0cPTp99ex1=<+@o_a=8TS+{EP3vp3#K3JnRm`$g>Lc7HtFSXc4~w z>=DBN9!k)6)r+L(TGoL|{H!+56E8r`3)e9(=W`>vN$b*?RL*{~w2PQ8>L-cA`nJw= zjJ)Tkp1zBZ+75I-Y6P>Mwo@bSPi`!wKe~QA{o%D^>1SL8J_=lnu^+9&f2EFC-&nJO zv6K4M^?Mi78uqeluva_BtpV47O)2&PJfqyncrTlK1s?_vtm4Z>azK_fZjQQ`#XMbp z7T(o9CETIc(oZ92!)?2$H-LXZIeSI*pEdAKJ+_)Ebgy#ibhJ~?YYTa;kG=WL^v1vX z1v%DFVdLIH9{M#_`W@pG-f;ck9n?o``zKe{utSTtAjxL@(Y# z9qkRo57&Xy8t@)*#OMNjH?O3oU98W@N$DNy9XOB{!3#N$$2`vGpnj^WVXI;fcjOW| zfvNNCocGLe<^N1p3%fLovnSg2chkVGv|;yrDhJ*QWPtOouBQime0N&ciVq@n#fGRq zGe}*x(h6-f?7O?Eb%^b6hCJ&H13S>E*fUb&=+7UVOMia*N@F{0*sLtRHy;&hb&IWp7=9O;z1aeZGNpOx{>e47B5SJ~+R#yhAzt ze+l+B>=jkmDmG#pJ5Fvd<$LJmt9T<|&uL%R-X3kL=a#bvEMbi;t-)U1Ka`r;18!zd zTc-aec~{Hp$xF()y}D98b&qQ72YxSQpSTHoU?qM;#Zv69q@J_a9T`4w{6kFU4Sc`ofbCLcY^K0)21ZGIm) z%8_&UAZY_=Bv)`1w5=kK`!K#;8@iZ>$p1R%;{LEic+sJ&v1R((JpYZ@Sk;yP)ytRD zzkBsc`oCYfoc;~p|BpwP(!YFkA$@^N*uuQuK#jM0;4bU$NG15VZ9Kl8^%GqeJD+;L zbdU9n&yWwmuI>?hoXcM06ayCcSKjEO{$%seY({hTa7)y{*hQXW?XNLkggyAhIl$as z#S`XAH+O2p_i%rWdJ#H#4uU$+3?(tQ0&F<7dZlH#-k<@x%Z>q&USG~Zz8KQq|Q|gGqYi&qB z!#AHfFPzH5h*4tR#&_;jLyI!xPP6qtUi>iazV~+O*g*|OYp)$Sllt)6lh(`fB8T7K z&i}Y?dtT_p`mNYkW*0y%h>Zbqr(d1sp%^1~1t@ z{g{(WJu>0};(z2M_twBu?g`9o5%ZC86*w?A_d00M1Rr^C4ju9ma{d<|JWNlnpH7=O z6B=f1ubyGuqt4xy*=hDt`2S7}r>cS8khj&?C0mXkjI-a6bBrbElJk4OpMS4{?#=iD zIu6(KM)U>$4|xt=X3%+VQ19d>wLe;2>xwqSL0r&Z{003oyr?6WRyQpFpXJ2hKi{=& z=b3vV_+TybqZ-*DtlC#>$Nk_sa(H{M8a=lO`tBnRX%n%E8@jr&_4VTSJ45Y7&U;u- z+fE-Rh7r3lYfde8&@Rr28po!B{y|&%tRkLOeu(`>;9H($E~w|xpJS9K*CKP`UOe+G zcH^G33*XPP4 zE6a0BS&A%hU(rA;dL40TO(Vb#zqhcDZDM_EKev=Nj$wb?vnTcvCHV9<&*P&F?=<6A z*+tE*Uh11f|ME6EfqFp3yDM`bWFg~Judijj4|s$foQS)1*xASD_K;8gY1(_~cGRXT z=pJ*QXM_K9d}X-I=p22o!invvLz*X{n*G1_pyobwWBS!@QpuTJ(YA9|9IPL}4m}9X z$;D9*jM`gU59~nCCTICYa+x0`fBXGQspHOB@^y5fJ4~SyVIPKaz z4~^9TZuS30eAI=db!0y0dvGN@{NIa>W0Z43&jY8AoC-g`prvpDPvFTluz74TB^6S(q;*3e2ksGGuq|+z&vQAW4FEMUD{IidBr}G=N+SaOaCt}+k2L0?8i7n<1no) zT#fCj1byCklGvjguZ+#Bq!GI>a=&lK9P_s-)sx@7XsZ~jpK&iAV>XAOi9USHnR3o3 zf-gdDt21Zts}FSHKfZ_$`uO4jdcY;V<%G zwIElsoWG87)rFp6ysrL9jhuaywlq=;YdSTOH>U+VPZjif2K=b!Sr4{rVUan~8Ftt# z?k-#BV@&cwzUPTK51f&g0UocT4nhsGc$t3E1zJgKuXb$l3rpwI4t$K|-(rk~4jJ^P zo$NE?-RP5h86AKfxV6QIPrpZ=HvYH$>^tw-ukH8=5BRR}$nNdda@MpSou&qz-+g@p zwx1ecRmZPqPu+F+NP71l{h#>DP>V*Vt!C!_4+h2h_)?0Zw*N@}VXZam)Gbe;uT_a>6 zpP@tN{f7MXefgAkYKZe`pkDDt_WAYH_1%n}s}b0>^Oi7X&)`~)5)X3X4Es)M6Ytoc zwGWPCEYct!OV;)({sI>x=y%$$v$?T?t4vO3IJo`6=lExw4jB-+F>SNp(`Y-#LC`Mm z&-;150XuLO?*zRI90$$ix2&(=L1E8vP{$rxKb|ev_{>98&Hk?c^8VDkIKm#A{Stc6 zy3tYgQ`i=v`3esf{bys%cssk-xVS51Tm>>+f4ySe%Xn5EBvwn=#T@Ya0KORummj7h z_g|;Z+TM)bF-F_VXe+LzYw$+kCc|ampuh#6>L1ZI@7s29Ww^@U5q2*5r3O2md)w+Z z_D7s|wNlrn1pTxDUmM#}*0&nJfd9E`T_#hC{rC#b3tru{c#v_b3oyTFzmm1Lj+(XE zyvzE}zSBldGwYxaP*<@Z`D)&8#~k#@c_8GVu*ky&OzKqyPxD#yA9e`jfS)lBL*mvN3jMp=TZ2g2b zjL-3iN87c{fXREgy-(ko?70H=j3(Z5zwf(U_%o=djNmgg!9GZz9O2LCojo5oq1_D5 ztnX;IzyZ7wZ7TcoIUoPWI~l!;^nlytm~oYf?M>R%np;u+rXbVbsXTz zJ(&9V=|^u;d-4wTxTxLw^mX<+?by-=;w-L~b3$#8jo1^)pkoC#8e>M{?2NHHrh-pH z=F5}7ZXfGdJG4*l+k5i@ouO`Rk*j5@38I5q6k#t#vTbN`Lh zz&Vre2!FiGm>pZ;XJFgHEWQi7Lv&c_ZYMP)nthTC7=7_pvz?{#`0;k2N`iI}E;rlH+_oo_cvW?8^rs4UOG1~v~ zm5pCpMj^9fehHU21|LP+e#SlIn()SVc_D`xff&n3h}cusf9gV z-@c2f1%J#I>PFV!YgN2g%vXQ=UIX()xMO``%~_^%(5T>VX$F6=w=d*Rte-p+&&RlO zc=Poz!(p~&WU$i~IC0-rP7UL)aHcTG+I#fkjkJfFJ9{`6IY{lwDe68?9lMhDKYTY$ z6F2$vxBfmns%&8`0r#P!@Tu%7&Xt8jnXi9r1#_qC^d;awotlYjYsM~IiEXkN_c9)G z`gk_4tT3KYztZe~VOgPHf$PG);4>@mxmM(GazEp*3~#nS2?yn!{GJgbb3y-j5?*(r1HsU+a6m4dBE8t%> z&wMxdBbQUqX{|AdoIShu=%ps(7&hf*)~vhle-<_Crm5rI#vGnLewBKR_tNIR32Gwa z`{o=7T)VetjRAJgZ9T(mVP9w*rhEQ+Y_3hvvSslY{u$^P?0+ZmNnSnHpa-xyuY6Db zvTfneuDZOo7BuyfE8dIm8IMSVW!U{*$QQqBlL;K<@}%ew+oL?Y0sGM0xjXE?E~N=- zFV3I28EgH1>hFwDk5nINeR^lupS}Czzt0#m-AXtd?>gp@_xffR(iZ66h2GQyKOMl9 z(=&gHy5UE$$zP{N;$iA~Ux~3to~DBSIsF{V=6?Lou-V#nIX)Bt6W=qKGrVN57xRM8 z;{Skq6&^TS4LtaN@g3Nmv+|R?=|0&yi(9b84^bn0@x(>=U_W{ob?V^R7JNH}?k;8OI0N_?`6v335A;4`jIRwL`U>)9l8p$2=m=Mb&vHDmj%d&wCLZ3GYG z@W*#$7?(a2Z4>*`I%?;x#SgWDIaI(`$O50su51ks905=EDbHtcdse#)zq~I`fQ#T= z+Hj1n^Rr9W@bj~-?<_n%PM%GCfU)K4kdyLE zE&Vj&|GtiK32%%)=X3S9a&Xf;y*qo~`OSYZ4+8!SAFdC9KVknR{;*AXVCvZA)IGHu z`j)2NxkJgigU$NB<707<+OO7kKmE#w>E$2%JYAq3@=dFu(a z3}4`x_p#xhN}Kw2P`CCne!%OACmyEW;U4NhFTn#dsgoLC>SyaY?^;bmX(9isca+F8 z@R(!so__Y3ZU7(Wa0Jd6e?2mHZ6)@-T6_p|90Z&Ntohsu{N=bS_(U3n-bJ0=$s?Dd z9$Qn_P#QaMhM4s0X?W+})B`^^BiC+y{?n+%eB}14=>hWb5IGADp(~t!_1*Nr&;BCq zr;hZsx4xOC&p%4@=k8G>^}TfBwa>%Px_5FmO)p*GyrwEG66dd+_uNI;j9)0?59Lew zrVP317=u3icC8-Uw-oy$$GnUK;4k*{<{)UtF40C^^9|5VSuc+C^$mD^uYiB`ckt73 z@IG`qnRX!OyQyJ3I5wI3sm(ro_;MOXe|26AQ`>U{+8w+5BrQFDpL(3P$R}`?nDk53 zuz!?xvp!t;?6;|3b~E)a9H)-+sq}4X8a_b&1?pT69z2bHK&~I; zhVWY_vWYd<@v7TA%Nn_sHMbg@iT9+Dz7OsXl{p~?q^t0A4p#7v{zJ9Q*GXz+jm}}G zXCGmWPX8Al&P#2cjp!NTS^g52yRW}W-MPo)8MvIfSl>Jw86F-Atnlf<*^XWw+};XCP_-~X5C;*(FweX*3zF;{x$kEBn4fAs3@ zG=K4hwEzA)_$2Jcws<6M1}D4kzZX2P1-oY#^P->p9S5i(?p$4qj9JIJxe?vjI``VG zO#M_iGr@Ds7mvG=hdhx^W0P88_;AF^(QFPfQ_C&icy_8P9^dWUyzeR21 zD^dUX47{N--emk9c`GYimL;mh{#e>cz34;uYYpxJcj%ezLsQrr z#;9@nQW`k>6r1a@nEP$ay9U+~&*|&2Q5g4GO)bEJmckVJknraIUx3)PyN)zUc7iW4Rb!;J_)^`{S;>+C7kmYFa|ur zpRaiZeKXqUusb)zi=WFrlq>Qg{<95a<`^`;^5moR@bjOfg_}>(+?B`Vu(}kyGBP@m zdUu~qU9-T*S=WhIK20MBFTyM4G&!AiQmb_A;N>)iEErx~O2hk3Q3Lu8bDcA7>?Jop z{$ZM+2K25=kJ4*D{pV?vcW0?%IeP3S-!H)XyV7y?7&Dh2M_u@q{wZ=%vJYo1ojP^{ z`G9{Z>xDL<=}YXtl#9#}#~*T#`5Uq_hb4o#fIG*5JW^cZ!|#EY?EBo6SJRP4AEs0A z=q!FsBYV!VUY(*YBk>f>xuL;fXlcFXTj?0JI;Y@=!98cv=nQ#$uvHFoO|gd_IRYN` zolNJbhdp)jHge%zWGeYn$Yaxke(~UopE94D(&-o9CBBY0J@!~5;6VST&G_c@?L3%z z=8mxE98aVB$%l$e?7`^xVmyT^Rypb zcb*!B3*?bGdgoPQ5f7zfw;!b|Z+?~zKmI%&W1gGqXFq$(@uOF%ZHc^n;R&!`N_%N@ z5Wczi!56GwyJDUkefb-y9sR236z7fWnz2j0!5mqNJw_M!>0?aooIl3;9qXKXGhkyM zQs8142dn5DG+)IB&VTWt%$_-MGo5_vyYT9*G_dyqb(*Qm%G~asT14NiB-bQ!6+K~K zc7IwteLW2*@T{Ptp|qcd>ro`Szcs`LlP@F0L0p{(hP`b~Vmz zyO0wD)L(ba>SJx~pWI3O=OnR_tk1016T1&EUs=zB2h{zTBf?(5%ct^jneSKOW%%d~ z=IZs-J+V7YpG6Mu!JmA1Azgj)A@soZIlC`pYA=2p{rkypMVAB5*- zkDQ<`{l3&cF%$5IT*zg_G7fS)EW;oAPmUkvz|j5+?0rs0UGg2w$)n_%I)t7!cJg8B zng-V0OR1MwA^iq>2bibu-vT}x!@PI$)sNEbxrfNBdud?bg*1R4@cGw1Ah*%wbnoMD zu|B?+<}W?Kzw;Ej#Ovh1x|Ck{&X3Wrj-`FqAEg(*^~2CRCh2#Ey+j8&-6ycSbWQ9@ z^VgrI$rCqH$IO1}VNSCz=q0bz-q3-XuuJWJ^<(OL00J`zvOPtY7rN)k7&T7Zf zDEjiD2k#>1%nNlh4YQ{innBm&>_feIh&|*U&N7c92iitxF9pwK@%)c9H2-!Na|6H0qaSa{gK|1Tc0{ZmJ1IU*3ZT;Bk zUP2c3uzoDypUD1oY(DmBG4F*fUl*2nK=|{ku$cuvATwV4?1$<02j5K(&~v8ouWp|> z$Ucbm?aYHT_vj<+|BuqldFV_3%9(C_CR@=Bj=uUCHQ8T*e=epz_O&CxJ;vI#4_UW( z=^=XGOYqS3)W3L^wdK7u2fRavF0+_|Zb%DocHMX@e7xWO zy`M9uj;1~5Z>Rmxa)R}CXxCBvvXK|erNdY6uqWM{b}U_qHMF^RhC1-j09;*q>r-US zH#k>4m!AHezl*J@A}yY~g}!ts?P3n~K_~a1=3vYALD;GE+b?)u*ujN&pUVY zY}#}4HTe2U>Oudz_5OFUcXJ;;9fw|{&_LN^Jo*6gKz-a?SsmP)x&BTXKXW@xUw9qc z(G6gI%>MYzGz08A$#Zw_{coq%{RdgIX44(UzU$2ObnK2hid&a{#|M4~+zV>oD`u>kN zYdAozh1PWPH~$5`-8tj7T{qA?u zID5b`bhIPbyZhM3jiUcg9K$}ca3bhAgibreeyFCAcs%yp%AFzBj(O(C{`=_rv^BZ+ z7&gPp=`eeog&X)ZoxPFbh{0eJ3%D#G>fq(uCi!c<7irkFD-zI)3lf;KlL7SFl^- z?=*ig4Zve_$i~5gSK-$~Y2fhn)H6Pp`mwtx3p%Ip2N)cOMwimzdvB%v*ntkC@65ut zqkG96ckWT@2cD7H#faM-M?Svz$#>zACux*^?tc6|@O?hk{zIHQ?KyKXU3mLj=^#4K z(HA~U`yRfQ$wKx`1IR`3HNZN!m;c+5eTVPA#rk|OwK0ZyY?yXC5pXnz3{kdDvkw|SafjIT-RZz> zd;<=%w?J1|y!bH9;5WJtowB8GHtoB3i+qMRusLnOerin|YG-3>n1+W2*jrDN&#!mS zY2rxQiQPOxji~0d^JUIAK1UBbbS2GEV|*4{#`xh2$iF+0_b*__FYP3BaXlE=dyX|| zf9U#i=U*UBWs!Z*sn|zav)wcDJ?MgC7oK7Z_$>8tc0SGAHGiD&@4(-78a#SE{NOvp zKrW^yKm0j!?pnaVaPC@q@a-R`6Zc;Y+2~Zx?o73?t_u-A1G>1%T$Bx;F+;%N%CkANg8?U0< z_h4&08@jl1X@ND{`K#^PIGj1wuO0C4;*HnS%!QZXt&^Qr^ zb7ZKu4-#M1%bAKgfpG}4<{;r3Kxg%=y%jr-Ywn$QznKo-d4j%6>?3>p9fwb*Q!hT@ z41!wU$OzYi{dXTRw)3e2-AX-WjOy_$pqX3>tWuSH*^3w*)@$Wv2>7g?U8hC=SVtB9M^M`{b?7zKT{(; z8Feb;Q=8vWO{G6r%Y)YEtUwodXG zZzC_(X7X|o13;{G8L_YS@9!$kvK}o?q`Qpa;*P;|0N6+H1@6Gtv89vzHNaN4ksK?; zb5#&eS4RASxw*{mRzbdvYVs@8wsU5We^|s{@mbTdHPw+*GWzE{skW8%2RnELK4azN zMJeEq{_*vDm00tKyC%}F&J3qx;C}+R+wnna-i8kv`KM~hkre$CZ(!b$5@Jxz?^a<> z5@2rV>H)`X`0lg-Cpo}2LI?V9AjYkMJQ#K4rKo01mHbzXp@6*xx;)uGo&M6^sdRg8 zG@TsZo@TZalS%yS#;wixBV_%X*Q=bkWb;~?+sph~WyGk~fY*BHTPuC>^QZtmV?65c zeP|@sqM?WLLU^HiD>T3dwi3BxOm_`qt!Iq##~Z|1KjnH6JY0Yecj1fMLvEyv&DKMcCi3&x z_Xf_FUO6Qy=X3f)>!;~{xeQyf=MEA3hVEB^J=GZG zY3RL|IG0_sV`*&1D1InIX*0QM8u0_GC6|hP9{J>mX&Y;61M@KY2X^f=amK*@N*kg!JZWNo z*6{MXV{)wP$qU~|ZlOkU2TAkBo^Iv_`PZ2@<;ZIDfh_k8e5Lg57^H*e1NPsJ{$(C5 z&sOa#Y+LkQ?0FqeoUKTkf_y-4DIUBZSJtoN5U$PGS2uIsvWd@){mO-Y_Bg~>BTt=Y&L?po z%<`RA@HS&IW_TTQ$$UqCdd8+5tg!8^9z)P0AA|gv<+7?y-LvGMz;>|>AEzxNlhg(# zHxBc;iuq)|G2!&GUu(=&AZNwBzADn&TxRy|e#$n5aiw2vu9@BSKh^)xUhJ*JfA(jp+(!r}-S(5Wg z@P9sr3>Pc5AIGr*Km5n|&Cfoxh~0aE_^80z z#uw+f%2oQU08i#JaBj$(D|1X)s2o}?53;$C&Bta^ANFW)5uQN zP|oS<@o{#K=@{e{Z3895d4$nbTj#Htjjs z^J)9yapvxGF&1s48__8|zpauMu5+$A^q=*uEO#v_`Y(??>eSJ%L1*@1wC5Pcuw_i} zd+Nvq&L*z1N4gp3g2pS0i#g5-r%zssbGp$(=dmH32|IN+dz)>eJMm)~OO5QK^r`dQ zG#iKTXYo<{o(pJK_ZATEPqSKP(;?!=(M6Bv(KE?*{jKF5L$g(BZ4M(@yTq z;5RwN`{PHxhJEiG<2a4o=m;`o5&pmjlDV^yJoC;K{a?&s^Cf&hj~VQ|`j~0U90QhN z>_S7>!A7tzOgzWF54*t3NpbLX&X|5J`krS`HwRzN;;S|N{B_O}t}q5@$nzuMEo}Dl z&vDj*PsG?<+Cte2E$l}__(Kdqi&1PzhhQ2n>DLvN|}wX~DmH12F~b@U3yb zP|e=UJ>U#`Z2Q;WGVq8EHN!zZ2H=^Xy&d!+EyTsnQ`f);^OCX12Rq;q|DR$E`tXXg zNv<*IH_RTqA0CxA+9&W)3t#&oa)9(OmiFj-dg)hr7hhlO`r1H7SB*hC&)C7Q^52E9 z2~8mzX0VkwFXqHQW7@&_|Mc=0kQ4OnrG0-4JV=v4c*;53;~Il);s0ap&7IYn^om-Ftt(z0aQaK6|Ss zERy`8U@z?8H*^o+Ah%`6a@YsalddgVSf)qft0x@ZPtF|aPQu`dd=H(x07F~$kt@yk&3~TrY7L?CE$0)SsJ}!HG}0&{OSl+_;ze; zdclUpGV26CH#Cl!rLnOVf}bC9Cw)g)#rP_Pd_Nl-GKJnqvG`4q_)THN8bj#|wB=6e zFZ@(|;}HBXeJ3dTPGsitDx@cEKHtye`$=(k+MW3G;rM-9=tme5As;Z3g)c@g53NA? z*U-=E%H{hxtTgqi2t6h zTXZXDeuMe0`h^DJud0_-0JQ3dJtmvXEn*qIEI)j#By7h-?8dmnc-QMOlzY~91Nf|J zWrOeybp~Ryd?Cdh^vK#QUm0GE^>}Q1atzJortDfB2zVm3}Ju@~V-F#x{j7WXLIOtz}*S?MCTcrKqcPW>RsY2CRa6FZVx zBy7Je^3CxlB)9Y%vhidG$sYT?@AI39xuwotQ0yxP+a!vZc!d005vwf4!(X-TB!L-tP`wX(7|BB&XbEf|7638Y_z^u1=_NS12pTyt9a zT`P-RC4En{c9b?^C)8LRF|RwRGuei2l)WGssNV@7Ht5f9X-W4lFY(#$mU2BQ{7#~D zY&NzrvV0roK=eE6_YsW$D%i4#&r4UhM|5}g%F3#Hm#g#H!Tlv8hvRdxv9TGVm|3)q z+6LiAza_n=`VnvA-7AmFuk}0njSTKD75m6TY+vDqnyn%FAE^;P^ z=Wgk@kbC+K$&L)-(rNsL;7Km31*S@HTsX@C9;Q(#-It=p;5&4x1vXcJJs6CW|iHX zLT!TZ6VK;GJNlgHQ1p=w?1Dd)-c%mJ51lFhw4Ki-CnZ`EbGZ^&u{@7U<{UKsUj%W? zZSYe(zMb+5ItQWqOU6D<27d`$N8eAxSB+;Sa7J!Bx`mwM|D&1-)yK;xxdXp_BQwL+ z(N}(Xwk|!4=#{0}Wa^2o8Fj1kUDr{wtC?NP^Z$6{Gj7%^xpYnHJvZo$OuQix|n(Hm}?&i2vEB$AkBa!0id z{OBJo4Y?PMtc)YhQo-ju?7xRz56Sd0EYHcdg8UpSEvG)7*U8LmOQG*y2WRD?>E9bl zJZ=m9y8?*`Y8IzvJBAUXjp59A0J1~5N1d;7=Ou_8$q!sd9Cdk49kq_Yx;(Fr&+%OA z){I8s0N6F7O*1H6FMFPAMwu_T+(vJzKwwF@al*rvAIRoz!y^uO41nKu^S2S1Y|oIQO0aY#u(7MjS-&rK1OO>8Dr@>|W?0 zJ1N03p!alWSC7f)hgfDlXl`3LaluG%r&)&noRbZtC)hS{a0l_xJBZi0m?Sbrw6F%> zc)fbKD~_{{v$?=0_#Nz=L3T5Md35tQ$<5xP0Y1Bdv$%f5WP_PS7estCjJ|~N4;-?@ zhfY|`6!mG3U8Gk-s#Sjf1#5WWQG0Oj2y}@)qGv?}aq<}Y*TfK8PR`G=s#$V*?D4{A zFZqrp2lHrKz18J=EtCDvA_h}gkYm@Uv9pK+WrMrS*f=YrAFbdo^HL85%_O3qg|A3x zAs9Lif(``if~TbTIqj zW;KciSn36?*@K(ty%&G|q(vXzZDGU=bDnvC^HrQnKfB+e>0gvsS7BpId&!@5SpxK) zhE35|U5xyphc&oJCeA$njmK@Ej(T2t8l~}m1~Au`Ke_idn zD!*I(vo*g^b2;1`bkV(F2gZ%W^)>5$-6n9PM`VO%{%L+gP+Gi$J^I|dMNDz72>K47 zC-7eAUcHHgwK;$Io0*nb8xREU>7CQv#RLyoSmB;vm#(D zqPLZ3y*N9=is|c9K_9(y3$s>2zwRPpki}UUR+yf~BYFlLWCOPsdRU@2i0~kpp!t27 z*iGr+(O!SXetYG(>s{;m{%Zf}gW+%htU4d(=pLBWD|B6u;#JG=Yri+pXJI{kCVlA* z?gLJJ=$RYbTw>vSdn|!oR2hwxmN?c;?;3h)cURN1gn0(scLetvh71gYzq-ok6VBdy z*q3O2Cyt&TN!W&Ee8xkMi_)hr+uQ%~uMX}aWL#HGnN{W!chB)!1HEqc^>$b_c&YSe zSp|Gh!TUuS>6QmC6cHOO0AF5cM||OhS3F$T9==Gm^Y>Y=vR;Dj>HC1JmaMyD9dNJU zLG!w`|Eqhxj{djmhrW&;6KkP~jZwsO;H53dlmP7UEuB@^XyiHQog7wA-;vQa^FRZ! z6TRk{>9^#)oHKy$V#rZxCZlA08*%Iy&N9aUdnz(54m&&%T!>E7!C?#iU2^DSR7*eg zU2TolU0Z1#wbi^|YCSbo)>TzuT@_{4*-&det&P@PS`2QotpS`Y^|hJiIC{~QLoM~z z%J1cZ1GAS|uQ~YN{?C7L@Vk9y@9$7gP~ia?=;p-(|ML70@Bp2wHp8Di(hQYN+`mr} zx~#g$Lg+K5e(F)DXDzydI_bfBi~srq*xb}+Un3WOW{w`Ndzl%kS;EW#JH2R}9SC?6LeYNfCpwHdtuub)M+uTqetJfAs z2JGDFV|HMC#C8JbB>jK(bvDBX>2B|bkRSHKBf$GJmSF!e>venk?SF%hQkH3+y>>Xz zBXqClf?s;y&2!q~&uk285MuBXI?LRgBK^-F8L@$!OGv4g{0BPw)Lz^B;QbcXKtG}+ zX4j$nVovX|q+{b2LoGwZM2~GnP6Z=(6Jn#FRnFVc%Oi&GiU*SM=hE1tZ2IX=zxN?bQAmyK(W1-8_BR9=mYbp1XD#Sbq0+`M?Zty=~>}|J9i>8vt)+ zzhV7~^(IR=c%Ai{?M9CzB4<<^;^wr9?pfk{^+j~_FCO5%4b)z&W6w6QPaEmMyG!ym1*y_g3$}1;7qerVu3jUxg3Y? z_n@Cd_ww=bGSjW3AlI6a>;3HI{O&=!e)hP%{_N9cZ*l*>eFJb<|Ha=hd~h8ZYHxje z<-fn>@z<=kSb|^s|C-ezV_NCeFF4gdb|blR>Az*T)t7ON+Mcz>q~Pj^Kx5$I*`{@1ctp0_-7NCzKrd zHf$sDdpfc`2D$7l%0bSjnHQN=fE;UVuC(EvHaoruEH6H7zy9X4-1mRyZxw#g!0P_L zYH$DNzgj*pt3t(_2?7TiYL;o@Gdrx`3vuQKP zspVtW7NFB>u>)@2f5HyVjN5NtU){(54($4l;9uQ)(Z1yVckS8Zb5;ufYX*Y)VY$6t z*?*mL(ww5T+^_iGKc4d`)a8Xi_rCPsS|7c|79M`cV(7!Zk^ZuQ$i(o*LW{+g@rOr( z3Ot-c;5_y?zTk7$nURak<8vY4Ac@aL(4$hh#5DT1_0p#=3A|>o7e%#Y*0QtBx?Ahb z-gwcz@r2~o|MXA%FWwj3OYb2Ae+y1ueiE_p4M)p@JqR0g84v0WzzSim3VD0Y3W{M) z{95>2%O5=((CD=&^w}2pRd!%#4SoJSX)Sx=u$G)%SJ~!eoxLE{}6Mp2BvH3Qm2SZy+ZF6FTC4AwG`DQV9vbBtvoaET} zP9(iq!^zc)?&EG8vuI>NBDFcu;3a-5eQLG_GeZg)$%>_BCJmhA=VvlICD*#T8vhp& zpuHE*FY9~zEwKLv*n!*LV!io1dyf6eJ_|<80K7x`z%BeB<)D!N&h7*5HP{ETef;UI zAA-Es+y%eXSlbjseGWL;2rY=mBaci{KM`ReMbvE!)G~J)y$}88F)JY&n;;@An3+|~ zs)i4e@bfb0WmJGKT#X)m>-h)&m*Bsh?w5Jq(fzMq1ojs|%X9YjkDj)*G0Qb8f>UzN z*?+Qu)@rTlgEcmD^d#{^l7tZ_9)QLrK?I?IZ5q*+{9x&0pc+$zL{|Wqm0K4Se3cU;V8Ro@jA$zCmO05vS z)4tzY;&s8lviz{sHv{uJaIjADA0JS5Z#c1qaN-Kucg1`nh`|Yd{ZDbA$i38`&JR;x z7i#{%><{gzKYb8#AQ&0B4W5WahQuho1-^=Nv&_EzImlHuj(Alv>%a4No359RbM*c^ zKgaLBj_vpwI`7rTQU6@)rAO@TFI{!}t(ed6;XtxLI#B!oOb&ixL5gok7Rol*O#N68 zGd+W<^DLyT5MO}W3vi(soZ-l}@}Xu6rWa$xSc~~08ypUx71{pb@JTGZ-(6K`eYMn( z!~bsoU*_JB$+AzDb@u;X90+g1A4_sxbnjq)3ibEI?_mEncEyVi*#ndG0Fb_O`@TZ| z!i8SL6N+zbW?zL1&0o!e{}uC5ENEjSwWieiZNpy+hL$&>L;Uz`^zmt8_v8@hO<9Ue zkD^X%8#a%Y;*XK+eFpY&263+6oY`-7?U)@K>M(oin%UQG0QzGqIFQbg{1QF?-~P1c z`diWQPR=dsHpzJVG5h{H@W0IOzVxWsHy?Je+cVd!YjJV~_7$EN-HV0=GkYXHNJdVl zA=}(6OI|y>ko^>$i!L;~(L=l;x{@CI+o*Tq`(bURH zxe>d6u+8l3yqVFcJY7jm3 zHX!Sr9}G=69&x;}5(ff)$;b8Rbl>t+3*Xa$?2oZ%@YPUPY%lE_vTx4~+v|(t_A~sV zpBIYH0i^Sv&PDa&2ex*Y|qXeSjNHCqu_x35Dp%@2rpb+#)I}sG%KEv{1QE{=rG6E z!i#7`{}X>peh6l_*TAdqYpueKFJixWgFeAU7ROA42f>Txk~-f<`|I`={jQt`yege9 z+f+Jl8*}9aw`_xOXhSp+g`E>j48Rv17mBUxM?55u7)dB|X!f;M+Oxy}Zs7nrci$ZWiKlOe z^>%m#^Ro{uucxnp+spPmerir%yS>ddoNkByCF3+JP%y58CN!Vc`M}V({Qr&EIf0T3 zzEGc1U-|cN@F~&4IkV3}3y(`KaR0jZ=fK4(YG?mOV`sVjE>iFtcu z@2KOo-#m838mBn7N$fFxXAANU`d7^^w7zWjpznxJYYu^W|R_7He@bXS`_KGI=N?(VW@S9sx@dxz}1bMV3{9UKuI%&zdl z3JxwUAs1I@;l^oXBlPgdd2n$XO|XZKM?@dMXHP;aPw<{-Ml$3{o(pfRg^2+>^2X~{ zFvA(EG0xUZ58Hp~F2V~=9!ww)z`=2F zAekt=AX<=axODh;co01Z7m^R6iASIf@rYaC=F!`i-WR@BKF4=riN&{*Z}HZbTk06~ zXg$=n0DnYvfo(IANq`YkNsn<~ahd`p#}f*RMw=iXSv%d^7&*8D#xAWZi|^aNy_w z96Z>!Ob3q)wK`sSVzkqqnLsb>>9cRF(80^H4;FVj{U}QSx-Nbo&nk;5#BYCH2i(>9pR0XvSHFfkWVP+z7 z-p##d4yxc>2Tf~st!P`Xb&kZ3b2jR^teJA_$ocqS8%fvs;^SvBAMY$UIPY*!<>=rt zyl@p>kW3T~Zb}}k^1@h`Jw4uoT-<5jm>w`E6ZVhTtH^{OV<$Nq!N~>gf0Z6&CkhuA zR%FEe;t$aV3w*qEZprE%K@af!#Qrh+^@%w2mS^zDnxTMu7ohL7@IqWvKJN6lb6-B@O) znMZiGx!lgRtk6MwwO#522VHfyaB!o)*&ZHhv(N2n|DA5Y{(fP4nIFE5On4bQ$WBpNgzzBwuxc}$7cN-XPi?<4%eZ*nJgrSOaN>~7Elyd=;RBq3Cx<-I&pALZ zaoRZY{^Y2LHH6}82I~A5w5(annrkJyPI^H75Y;PO{O|k%>|OD@aN~3zJm7=8+WMSd=fLrJcp+_%ZrYtw#Wy2&MkP^<$hLpUa+pgo(bZNnezRTf0`+%xQ8$Lzz>;s zw5HIG)fU=uY~16_Aw7XTaFW?;r&yu~(SrCvIJmz996$%FICu~`5Dp$$p#|wj@q^^T z^Vo}DBUdP!@!R``oV_4=aCm?gWIKu;ezS@T=;Ak`30B&X1sh`}jiTE-+U*4SzxZ+L zZ67$zx$qi`BySp#mTr;g0)O^DG={hx^UPYPDU=QCd|=?!e*3}?&gX>=6dzhoELgf= z19sm&&K)h*6xdGLZm^-VpL3v;HSN5yR1F_F~^nqTq6zh~P z=*ylf*A)-0!s)?Yirugu-65I;O1 zI{_R>CTKl^Y;^V#HskN%0eTQmIDLuj`0D&9@zifokn0Jd z*Z8Iwa(?K+aN>DE#H)N{1M>b7v~XB>aJVRRxHt?Bj=~R~ZsY(sh+<~)KIWDlLqDEh zr3J}G^pb2P=?B?M52GWcBbMc3r?Z`(!GCxTT9Axf<_TovyznrB{WNN?OI9xIc6wvy zFg>4Me1iFc%*dXZA@|yC;Vn(f5~FqxSrCxOys5%U{8?bfwpV?Y4>26&`~IK}JG>;#94{m{cvWWs6q;oPczz+RM&T(z5*Z3X1Qiml*$2V}xiPCj-cAK_ta zRmIi^Fm;+)dL0BEZp|U)oW{AlYv_^S`>Z&YV%dUQ@awta7K&%x z9^;oU92mh_TFz4n-i^or&CHa~w-J7bB^D5d{!1cnwFvynILP}QEx-@L!#QIA;Z@nT z2rg#&T5JIwaRj+|vI!bk(UHqGW0hS350Z_N3$mFm!56{AXG1mXhyAz=KAsrsbaG)c z`bRN|;9}^Dy0*M0K4)8t@;NgaVL4Ac%K2{eI{T{L5!>iB6i6MfVAZ}0HpMI*{Jai~ zXWkNLlbwIVXLM$GGxnel@p{EFRMX?mi<75T?*$)tp`Li2;sFQH{aS+mz-@RCEl3s| z1rNu0oJBTH3Mc4@{E1dOf_^+9Isgy1+lKv?$2>Q$Sk5C4S@!XxoTuje2ysZsHSM{t;KiQb2<*#y4(;5~7p ziGAFbmS)ZKbKo|aI0iWk_IiCt0QHg7CXkzn<8hGd%?sw+mcs$B^|=4{a3Pvl#>2r1 z^aAxRvX|ETvk&A#ik)2Oq~0;VG}AJn`3>Y+ zR70v5%Q|Rq6LLttmM^wPkm_sLv!wb8ONIAC8apf)`U%YDZ0fEdWR+yxvV0TlIs+m3 zwGN(%N~h;Fu??RL<}Xu=w+_4pAVZx$3k_(VR3P-e6?(rNZax1!*l)vu@Sx@B030lo z=h`^0qSEADdY%&XN3I>sL!#J(1W{wzOQ*l zy5G&xL+qPyqWM1&!=v;qk9W0|fynx(eG}%F1w7D;bi4RlwC?C09Bd9Gk56pRhx%9X zy7bsuJ(7#@jfK{cvwh^>)z6`YGyQ^hx+MD+4%~j@N3G()y3Vg5Qriv4Fx%+eG~+ zlMih(GcW_V*P^%SwTEvLP|A6FW?)C|9b;dqG2=YWs;t);q)mb3ao`8px31P_HNWL@ z-D^2}0DjTyiP%s9$POX|edQzNl9n7C;y zaVB8(DMFrO7p#dQ_s;*<1Z=XHxNXEG^06H`gF$>e@tFtBpPGS9^utOzy=aNlt_Bjn z3a2h?T?9S~=L<5v@CoLXF^8Ud4E26jA9EkhajwPQ+kmaMf%<067A{@CX9&{#vQjpjYBhi5lY9~atIM;*;He$8>q ze*Jm+Vxhm0tLxDf>r}tbK06x+c_%whw7&rzueipczxt%3e;3bQ&GkBepK~9`{muAy zf=hbrpk&wz?1KOIaDWVO@avH^ciURUOLTFn2_Jzi`Hsee##@**iC-Cltp#o0K@3fF zAA%noIDp&+|J(5K0zLHQfcMs7djvAiP<8if*(1%l^P?tuOEvK-^mZ`zL*m&53n7mf zR^&xLAj{Abj+X_ua?{e^p#T7M)rBL&b`3v8HXHy(1s=S0bhOrj5v)Q&bS6L|j&wAn&KG13aHsw0(aM8G8b!*Aj zs9&;P`*R-9okdYE68W^iE*v|7-H*hpS2xUboQsI%M1d7X%fQQJuUjAXmw zlfLnZ%#8=<=!wL<9C%^t>kz-3*z^=871Mh!H2dn&jiw>kS zR`4;$^L;#@g(n4nkSEgZ`8$278w;m?w8UfUlBhRkFBD%}PwiYVa&0|!&06%Z^u&7d z3!!C&7C3gLfIcasx=1+df4_O~dJ|~3uxj+7%A7|Fo^F;7(qV7n2S7a~A z1`Nc9+Ze2Q4_psj>gs&t=YuEFgkFmVj>u{b_Sr5L{3fvLkV_{3fJg1LM2|7^mrY*!fW$ofs_vMBk<*mjEP zi|=Lkt@6J3-NC*h18>0(?1xw3m+i7b2ZCR`pmn<(biA-a|I4(nj0e&Gy2v2A1KIsf zbobg&_8r-JM;JZ0N~kqM&nbSsHVU6IlQ>i&`6TRnoj=pu59MDpmv#-ZJB;}x>!}OZ z{;LOsFLv(+VlYv;1(w#@jV(mav(8p0Cw-82&W@LThs}|(Yo|NYyOubW@-}Yosc%@u zgW^4k`7X;r`KsFgTkwky;0H$oJeN%TJvsmvw`gF6_8ktu#}sx-J#;8}|4!__%_W*W zkI&MCJsgUEiCwS!n$C`F#2<8a0eqkysCQr+h&G%L3QdP_rX!-am6>;y^nvnV+l6qB zG?zMiY6`cJlc!Hc2EFQ1hK6hdbzHvq{yMWaeCh=8zbgENSgr-GrAN>U@^539^QB%I z>SwfC%OUuWtm1%p&N2`D0S<203Ae$23lG4)9vf~Gbs!P=QsVKreDW-u`CNlekEkzP z*6+|l+E_a>n=_a2yLA3$^rd>6>Kxh~+~*p8Lv*kKxfVn1;b!KZ2ZS>ZojvnG{^`6$ z5NDr#(QoPvv6b`GTARVa2F?;xEnQ@GLBG|E&g0{AmJ?st)iPlt#8lS+H!^_ufO@s4 zugNiB7Y-a9+|CCpJRteFtQVyVe&042D#^1s@ZpoHy+qdH?`a>k|Ld`9*5Hc^&dIY& z&JS2i%tE%WA2M%Kexie4^sfD1&-o(%=3EQf$$oQYHl7{`y3etx{mcB1T<{Bn&w)9S zJ~-=;5oJsCCg(iy7Vx1yGYK^{>^;2#nS&8T4;sz0luhh(ANw9if3cLx8h8TVo;kZ~ z*84bLeVGRGeqRa);NlgQY9g zo5?>S0oxedU_&TYbwuzJyH#94F>J-Pg@-wG%x2C;HgK*d2|cyI-fNAP)5A-$8~zQ8 zr%x?1e~sIF`ZTlug6;Md*i&q=#DvwyIFq=S_&~BwIP<~Z75z&G1auZ6xA5bsFI8W_ z&Cq;gE42#sZ8pMr;c#Lcp~%E7^cQcW$4dw^A2-pXKs}744@4uuDVY}AKk9f}{q!VD z)^na${}aC_Ktt<^f$9Bl{y*4K=4M8Rrlr~jWVJ7~+|9-5b{Ltkw;Vm25@kNQ^jPbw zr2i)83)%Zw>ZkHJ6LE+38F+h`$tzgaW8bXBFOmFv2TT7GKD7VpWh}kuSB&gJ|F8FQ zzsL*m|9WiX^;_t*5E-{D3!v3?*e>f?;l%Odn6(;HQH6gRWA*e?QU4}q*KR=1V$X&{ z_rk4Yq*!f8eI1{zh?g94K z<#xb`X=c#>J_$lu_^dYM1HYV%uQGT=UmI^ zpSv*tyMjI4NN|tARwr!_oH?gkVJjCEUoMBD!rqc^L-7-pY zEw8G`3eXG1#AHh4&*anZm|Bx!&NUTfXIOq_s^wfck6F>oc7B#!=+g;_jla0eReXRz^AYP+pd0ael0j^Fvj{2Wo1{tf8uu zbCc!PT2sL}x^ip4f2c1jvO4VR`tl-ct}VBYrs|dJFZT&`*CxlH__wR?AQtUUZ&A&f z4$Vz<^+I>vRnF|dQse>iWw>@$AwBl-OAE>htcDtkws+lS-R*bTz`NRP*Uop@$lYC> zW9zhgI@@fZv&9C9*^Ui#+r96($EL>mm+{XY$X8Qsjk`AS81)X&wF8s3LjyZ(D{?rB zv-C0K5o2qZ&qZ!O4Ib3lfjq8X0nF{hMRpDM+RVg=ec+Gw*azP~YezmXXG`zjYxm9G zYYV)0cz)LY^p6kNsXsYj2j4&GuD{wRReeL%uU7H)0D8JA))<_g$hj~2U2ujyx|M$V z#HwSFjS1O1-1)5>_P(?@&stg=Y?PSX!4K@U^QVs4CqDWS`}D^z+l>dV+Jk?2$v%GZ zoIUWdkMR1EedhW{?dtu1YJYNY*1_#yXYbv1U$U?K<1_Z$m;T$$k57M*=a1RnKmHl}%qKr$r~hQ$)%%Fry_<+3`T@UkP+`P_!pJ*>Q|B0g zZFncw-p;wEIB3Dc|FW}oSOw=udcpf2fAD~P_R|m8KYjTr``3T@y1o3JZ`-Ti`wr_R zdxhuUd+9~{&bPm6-}>h-+4IjlVxPPDQTvMzFSLvLF87Rr~P|e_%g( z{WZ6K{KN0t>#u#+e(>r)+xNcxCHvYx{_AM#E=8&51@X! zq0m4WIqz`Kc8em{8jBuGz`ozXV-7S~mY-ogEj4zOxYQT_=CABK-~5`r{)1QSr$734 z`#Cj-KY!y#?(t_o`GLLh`giR0fBUMv@~tQBt51L09{$9K?N1MpmxcDVHn4oafiHXD zFB=!W-$G0-oO{^DUTnu#_7r76^Qq<~PE{^iSmYd`$nKif}# z_^Q46lYh5g{PcBu>u0a?`0u>to__eE{pjT{+bduHTl>o6AGe1uAGb4y?nO5en`G&n zo6fTMq8t5%1N70BZRDNsL+?!9ZaZ@5vw`k!fe*WR96=5pBo^_P)K>iyao8V#(>K2J zoW1$lx9zPTzhb}q$-l8)<@tB*O|JdZSD&@lzxBAi{M={ktDpOreg5i)>|@9Gxoh8o zUDsCrhS*III0(Zhj)o4@-@24~ocF;0$M0^m3xln8otl|1&X3twPrct>y?)Am@^_!G zH^2I~_SQ>J+b{p^EB4DDe2w*0`^CTgll}a=|6o7)m(Sa4|MVIA&XXUv=N~$6kACc^ zee6SX4(}V;`%T(=a328d!CX5W__rg2l_hkMaWQ%A`|9-te+WFFGeQ~ceLeDLm^j1xf&JXhdi%_~+wFE1yJ~NI@rwQX=P%iJ9{z|u z2cB+T_@JHn~3@%vR-@-?`;H5GP4eVK*)98lY-cOy+N#yQFsXzD> z^$DMU4|QAj_S-kW!OMrIa(7W@@m_q}gIxavdhaax z*^iQ+f1v*^yU9H~1|I%_Sk&{>DZNPT-b>W7z5-3WdhCzvyC?VA^BLZ9C(jCcksRT*wU0;gvQ>tZ`|&l z+{L^*`qEJ+<-rEnjx7?2ALOo${M9+FVCDYU_XOy!1bd^8>rdn7?Z*zB2M40T`?!Y_ z;Nc_e#btQ$6X4>npo!1G7k>>t9(nIhy9rJ{aqm5LVS31x_6*wa_&rvGUiPB@lkuCj z=hE+q+-o>B2%CZ354sBi@8b6;U{8kUO6e;v`0oY(??d0t;FpY{gZFR`i{uDD1U>#4 zwRIn%cH%s>6K7Z-rhejdFTNVJuH*gK8-wq%wwW9t6#WL37c>(2|ii`NZT~&@UtOr??m1n`I9sxrZTqq#c^jDn*cWMeP)*+vaWc})qu|LQHPjTr;A^bpJgW^$G4%@;zSy$l7vfzMX3i1N(c6GF@J78vQ@YeYBQlS#3qO-Bp=Gubey^BY>z!6r(otFk+(eGd2FH^k&X9>_gx#m0+=*Szq09echr z%VY26+7sw}<*k($+{3zu*Olm?EH5($3b0>G(ygdG%gReK(SvE0PELM1c4BmTvTdg( zIIgbs*`>#!HAi6a--mNfDW z_!9o)|NY3t`l{wzi+=6tz+J(2yH?<9S$X1gbAG_=M{fo7$lpY4POBK4 zwQ0YRvlD`wYfp1cttr+xuLpp=4&3kH+S_(ulj1K1^E@Pn-tg@E7V(&$&80e$7s zhYz156uT&dvv+~ig!n_}{_MMIhSZ~e6L~Qoa%?{22Ak0@gE^@-j(!!+r`=k<_ItVZ z2ywh_%^JWC+wQp&zn>g@60;OI_Z6t-#y`aIhKtZ^EzM#F=M3 zu3meU)+V|3IBRs}+L8kW*ne@1Sf(gdPWA&OVc-8z3jCQEFSkj-;=Cy)_b__2x|~}yBj`eh9(QScEWb@ z!ko7Z!VeE1zU|Lz#SnGoeiN@Z<0tvW!rKX&ddQFL6ZI6O)?Q_cBvt6#g2-w(Jv~LkF!~yB-^}5E-oV+1qq&;#Pj-T6NyT?@s6# zJS<-yc!^0KiAgW3(XeM{0YtT@Y@<`Bfxz( z*X`uGP4JlHSSi=eg)Wm4>6Z?C!MZjvvrSsM2k_u093U@M8?q^q`VjalfZnGe;5sw~ z_=yQ?u1OI6*;nU^=-Qflu{!(0k3OTm*n0k3=vju(u?0A`LQ8j2Tao}TrNX;8*a)Q+ z#a35eY0c=6_SQzXT6x~oP|caKKynTARl{crP@a&)&P+ z4$Mv4eea*acH3h!dq#QxZVTZ1!Ptu7)TKtp(}R)Poh)it%J2Kcx_wZK03FXiJqXP?P`X``*KG zl>6+Vzc^u^z4T%G}fHLGVZy=Fq?U9 z%pUraIs2PGJH&C-!*=yg@3Rjdnzi|vQ5zkmpAxu>0rxwwS&G43JFt&qFCF6h=Y~7% z8g|Hy4@}snmuBqh2mi><9N1$E)9<$T@ZGM?CW{32cwo;&4^)D?9{B#f=DhpemDAfiW;}~ z^BW7;NeB3yIqE>)OYE|rK7P%2Ra<#gvE^U`CPBZM*gGZE`7|PHI^n&Y@I)`aaSt)m zd+@V*iMMn$mRmD=rMiZ5`=$BJ-pFEZ6SIV%nF3-3)#%SA;U4~J;y3EJk7{H|CGo1V z65^Kl>3J;0Yj$|)3yAHxof^QrgcvJFf7QWnx_%wMQO?TKd>!<027YcTXT{W;GMSaY zHDj@3?!<j0dI|cqxi_WF)=tB9ZM8tZm5HaK0PHcSD(bQO zOJR@GsU68go@H=eDHU75vm?opc91K={*FaACi45sVV${UAH)ux1n&tDj z>T9MyeW$W_(n^>$P(QKc=74t29A-Y(5i4ij?a=-s*0Jxjr4uu6-L=Qk^NH2c&o`}( z8HHWDnG3Ls+6jNF-Z{p7vHQl_)YbWA>TvnI?-E6Pw!DX^Tdlbb>gB;U3$od z4ji?*ox7kvVwSbcV&k&~%n(guCSJ?LqSY~H&&!Oqp1nsnuhHY?)$6xhe>P&+s%Ks} za?FH>1@13AhJDN_r&liX$;ovl6n9wr*sK+kD=DmNvBtr1t7z+?UjcIim{-=nXRl>5 z4>E%O%5~&N8g~vc|97vo?q)t*Ua>XsUI{ZK-Rr6zJ9_Cl=R*7K;w%5@=EC`gMp^yN zL299kZ0{$&WToU0H0Re#&*MCL;a31}baI9b9X?GT<8C|h&@;Ah`KIkXbH(b3*SC(% zxVr4j+MUb{o}$ljJ8`@UdZOc(?$X>gX3@Pq7mQqk{dCa2|{BBkXbf9{M z7;0jKgSViCeCF|H(@Q>^nF0r|Jk0E7W)E~Qx0~9TQf84i?4-AR)1dv`5C4n;deZs^hFS)F z=vB|E+Q!Y~@mBevXa5=N8fCV7(-8Qq1b%Yg-Ges1bkfy1v;$L4+obC|t=S0?N%(BL z4zNeeIPRQePCWDPDwtzV|NF&jPq>*DnYF!+4>PMZ1F*+3pi|BDQ;+_gduHi@KWO{T zT(VSp@24;aq;+Nq_&8t3^)=sP&&m63j(lC)$h37#%v%$W{?Q50Y74(xZYj`gJpA4~ zbAtJ!Cv4y_pTBs+9(eXe+r4zg`t}{R_FWU!w|GB2s^ggVK~HRGaWlD_<(gjVIic%S z9C%yVXYkiEOCQLymzfLL;^amWeWT;D=uw`9{@j0-eQULjz2FOZ(J^z}YM9yUfd)M} zg_hFNV5yu9EQOxZnMc_(f6j{9n9~6LY(oyD6*JcwTCdwZZ}ae&KHniF4$G^rt9=4w8gVr*(m)LfItOMGK|8lK4K931|ALx+_xQ=@u#&dsk)sp+(_ zOOM;hr+>$fwz0(n{|ejl2%_Wc)Z_~2Sb+y)j-SV`xwWz-M2d#@*d+&slB$WG>opl@nNHRl8!25x(%7p;%aS0M|k zS)ItSu*3{_U@!fgtF2~euT=wke(R7`O`f!|gD33D^Do=}^VebB?>2sWLEcWkUyu_vBdvyc*1&G_ZH|^VhAUwb$y0r>M!Kwj6r& zqEoY(jnQ}b0oOym`}jlF$@OMVUa--HlXmjqr!1$e2K_|OdwS+)psTBxnc6UQf?2Ws z$i<6R%FOjyX4LEd(%YIflR~floU&S5qdYe{QgvOcGQq>_-^AQn>Vm_pcIUW7dzcwl zQEz$G#N()sX&+%8bauX_u-CFns;R-$e1-J(DdhT2W`Qyf1v<)L-tj(UQw8%wG$*Eh z@{n~OIB7?3JYm_rGZsbftFoR6D<3~jpZ*GJvZky8+aZmdyk-GQKUVcmBb%$?hgo#Z zoDD4;XRr5IL*J;)96yiDqaRro^`O)>wCz7_v-dx4EzDfk4CSa)&e6q@Z{m0Q7tT1j z-pK6Mn$7`BDr~d}`g9~BdnFfL-)}>MZgR{u=9A}fI)%05-_$cpWjy*h~e#tS|X_Mz3 zLT(P*?gK~M%;WK!udq+Yt+IRAYKLd7W#4%lUOel5Bc-UGS{CNxU?&XiTe27a-?tqs z%>%#!{b}!_QVOjdTj=YUdUX?rn8OU6BYztQr|j5`#~qCp)pt1kmJ1Af&OGRJ_-1BS zsD?y!z^=9#TJWd7MYN#bFM`)gkXN0P^d6^HDxY39F^L{)MaH*H9kj&KHcPMS<~}Pq z-%G#fw%yEKZ9v}*+u-R3Ehf8)*~_iuCxhLb_!9WIsB@e%$Ng4;-IB;WgX&$=cIlx=IFjwz@ z?YPPhyZ0Yt2Js%?tFf5mOh+$C`NXD~q2*zQcuF}v!kO7Tj{Z-kHlhUkEIy}_-VPPW zedetmzJ@$)u+EuzX3{X%y}AWIFrQi2@H>2-*Rh-Ws|IL$FLR}_rI|%kGqBu?xC%PT z>Dpseyk8CNH4IMJ(EJhGwRqgw!?MMTduMI<dXcFOz0BKg??pdQC(RsrFLRiL!&c@A`%^2pp1FmR2g|gu#{T|aUa=EbZZa!- zr=4Suijf`Pfi{YonZFBPYOb;NTlQg9AM>hu=~s>3@?_>Y+jtn;y`rt(2Imi1E}tDc zdD&u^t6koMFTx!4q88>3p|fRI=fiWUrJ7yQz}dkFW=uCDHxD~qP>U_t2t9V}o@H+Q z9!HDmz?+AR_O^}@1Jc}`B%8eWq>Y|>kU2)Y-@o75MyIU`-1T7}*TRE~=Po;YE(RY< zGm2IBvn3*yJjWRGxjFZVEOxc7D>6a#G;zekmd;;s^HZ|g_CUYPae@ytTSIf*HA_9W zdj?u=wj5>-mF?Q^=r9ZUnp@q3|H8QobV&Iiy#}Dq`n@O6k?1F2ZCp6-{HiqgA-=c; zpToy`v3mW9(oUZm{Z-1EdmXfR6F@Qcn~>p=B6FK_Bb-L+sPlz zc&ZpbY8_+KR_9?pgEDqp%|+ z&y&jAtbg$oe&@W^pj!)So3L{_sX3$fJTfe;g_-owep&@I%$`Ohai*+sr!C!l27D~w z*X~3&_Ask@2)PCyVOtf#J4Lk}HhuCuIx5@FJjPrIS+9K?nA55AbXMoBKzwkLjh398SP@5RJuiO&{iY$D|c9 zV|xJ_+->6rPdRx%eeA5YPA}=uTqt`5{q|NgC4%qmSbCz3)9B%G* zGu#Ur+ATS+j?X1P+Z|3u-j0K9%&OEik_&6Cc=!-9ycwHz7TI6nbWtevbVb<3dC+y! z&=~yRiQTu~*~Owy4|~ysKh(-T6>$IIIVEoP-pr*Z?bM^s*%LoAo4@v$o6+7dG)b*P zfP+7!7`p|%l8tP1IK(HByqEuzjQq&2X|h~w!MZNyDnf(3&_G&QGjb%`^=xX}OHUJK zzlTP9ER%ci;)h;+?q!=khR@bMYOTZpYPxq>73T!<(Lb_>y};oq>!QYiIk40QOE-ug zBs<&thAahJIviP=kXel1H)P2b-BvoZ-*WJMM~+>v{`tf7twr8uS2L4|++s=|_U}Bn z;k(F%6m&;AGCY>pPe^2fRiOW7PG6-b%@bD3{xuHlhVQAlxc)s$DQmT6Y~_yq*hct( z`At1`;E|UcZxs-`$*-(q54)_Cv%S0K4l!3O8vQV0TgaLC1~X@X*^RLo#I@j8>FUSd zFk8HI!*Yw5lR(U&ocLLJ*O0|#aaJ&n8Pz4ski#CytY>B+GrZ#SYq7)WeZL|T-to>g z)b4cv60W!aO{4n#T;;g8Dj$C*tI%u~QQ^PFSvRfyJ_taYn zv6~WL&qX(Rsn6Eju{3JoqsZfwb&W7fiaabd*Z{AUxAxo2l_!yt=+nV5n>}^Oyy&hL zXifG>BEG`twdb4+kAoj&gQ_lE^TJ{>OI=N{lZz`dAu%fl-?z$Av2jwcJqz)3vUcvb zxWYPOCFtvnGGYkWO6WlkH0*5|h5uWK3n4#{=T)PJuqSG*eVRU0kNq>X`Ot6glocXh z2Nq6QdEX>4%1P!B?#9M{#M-#;{-yKI=PKk3e-=JaN^XhMkHzqAEjlHmcF;=7sJTop z!iQ?ZZ#(X6>XfoJJNd|S&W38j?ieE8&_(=j@!IF`VUa`l<+a1a{D>tAkJ0!Mxxi4` z-p|~{QRuE7y$)R<`(!IPxd=aOqAs?eik@NME;OSQdag!~^iem0%{6)2QmfH3?5Scw z9&Cz4=Awa?Z&vKAqvb}0{E!xnoQRlbG7e09Nc^9WW_v{;%+X0MyyRD4a zru>aQ?224s7V@{_io4j8JnAp#e^u6kuUump=#cA+m(@Pb-uL56Gsg)ZIyDX60tXrJQ~_~m%~Y+NIAx`S z)69^oMc(;iV-$jiS!}*(Y=b_Vzx1H@y`YB0(_fHY@&SlAQ$^* z>DX~6XVU87yYUlF2F7@6u`i%Mez%L5>L@nV(7r>&80IV+x>j70TQ@LEUb7GxP)Sawz{SQD7fI%v#U}jZ5MrRKa#1=mrwkdub&@0#h*kEUx`Dl& zW4ZZ-mdxyH`JE}?H?L`wS#0Dd@Y&?Y$nVI=DRPe|uYZ9YPNw6Nsy=*c?6l&6IU6|n zpn1x>Exoi3U4;y%hC2tDUxdt)Onv1SKgYh=KwOzQso-tk$OFWh_B)@y2Oppl*kjP8 zdfr5=+l!A-)Hi6c_$_(p$=&#Eefy8Xm)K>sqgDhzn(;9lZPyb_KDg+IB0(Pe^8uV$%z;9S6w0oQ6)A$;@@d zo7w$~F19awR{p>2y;R~L8WAV{HL9G_tN!8U5s_)Fm@Dt znt+WKhwYk=yq&uEDEtGjvS%H{ueuj5K_`n=NNyy%1fLR`&ceP;U|!(B5p)J}T)BwA zBro+*^wuB`m4FQtL;Up?KY)*PXeSCAAr<)_m70ehgC6;!PGv?Vu;(LVv+?P&n4w;aKJMOs9($mHd0qG<(BMNqB<6&CPDDN@qKo`FgQU39 zJKpgQXE&#KnQevrol-~shrCZ2@#|RVA}Asrc|DJe*-f5km&3sZ&Y8tz7h7B3F5+Zq z#9xV-qQf5hr6IG&h^L~Ph_h-|b!}6tvrkhB>(RUTG>yy#?jx_!JY*xXqkBi-+iG%L zGuBMbCbfVXEAlg2sqsk4ufdmrSFpcQuw~0f=Ey06J90ji=$op}LHK01m6IDPM6W7W zlU&yBeA&}ayo7u}r=ib1d^Z!@J}D2Kw{rr2q=ufbtNgI+KS?fzawbjoQ#^E1g8d?0 z)OYMMv(brHwG9&!nQ`>2_)`G(i{zo?lW-?{N;Hy7{xTU@>&e|^5_6G%k^y{i(DA;D z597;BSVk+njjSwf?jcsuL#$}Tc0unY?Zg;r(8<6UNsUcj4{^KVawmH$u~{`E)!RH` zNkz?0er6Pw=Umxpd`)uU4(K!y+K<5ZO(A9)!+obz({E5QC2|)zHOsQ+$rrxiXkjg% zm&{9phW$gBd&E7a5c7=YEK(}D70q1@#ZU1PSF336wozC1grAGbz)+=-Kyu&1xM zd|Ehpu`=RGlb4?&UeQLqPbT}xtQ~kMtpRxtj;luSOR$H^$V1dala1Jm@{RI4Ml1(8 zp5DZ3=xp}USFP>v4d>&f5PN7_dcdZZ&RX%vQFJnM<~f5Ji(XG9-V;ZxJ0-trnIB{` zI+;*p+t6>x__0aI3{QCvH9++7A>JLyeWoEBuH1Nd83)8C6-SGSPo@sG*Q$Dl9c^e% zZg?zpTM6(Tai|XB51HuHz5^$0^ymdQ=YDwcB)T5|rf=FR$rUTd+I!%f!?$E!9A^N- z(T8>205(pl^dIrEB4E$!o3pONH?avvn916JY|Fu# z?mh6~gv#_;D(p5-Hg&1gg~esT%h=^T_!!}dUU+n;bQb=QnZnY0KkUW&N|zRhP};uPOi3Jt^Kn?qSo%lCw%? zf9fWWT46u5ar6=A(=-gt;O8*M9(?8xE`fjIqQq0u#H+~GRPHe=2Va6d70KxOWOSTn z%M1S7ed%EGHkz9*|1VLnBR?Xr6GTJOEvfKCHuv!lU->#`Etb#ZR+2wb4kw!&!}-U) zN-Uc*O~j6d$ce;ytI#jdJvon>{t0Rtj$`|FSUfs9F}KRn(Tnx7m#lX8AzQltGC1y~ zhN9HT?n-=L$$P~OBr}C)5w>`B z4>6x?&a+`BWtCtj6%zlzUQH|lH%;hmd?cMuUQ3QgGI3cZke^34cet3zG zr8qyInyrKPQ|r*o@59UJbLC3Yuum)4d({*aK=wsrCNNpj-&sK}=dVn*HML~2JC(aZRC$n7lr;;qCGQpiiyke8{)-c(IVIeVNz z+&nRx^OmczC1gU&zB87OEQ*0AJisjZseMo`Tj$YJ@R8ex#~nW?{t!T;GcpM;*#>C zQt(;EiHT+dLmobMDsoYiBodjyoI~w|?Ddq2omPe(P#(Ggz3J^C?+4EowDegzvRX1T zihb}9qdEQT&+v8X$f2Khc7FnN9)tgv)x4V;$Zfac3A>R~ikB+SrnpK}67^$wCC;YJ zqBlWo7JaLTu?a_C`1>zAn@8vIOBy;|J|`C)l!A{{P}fKtGt|oPTQZQ%iVY`{w@88p zbBUoBB2u2^$nKRNdUH?056Lsr?(EJkpsctZ+) z)X^tiCO^E#Y8zX*XUD$t0dzfZgrI7w^Q5&d1kMY;xxQhn-)aDZd6=GYNYzA&c4p zWOix)jEl!K!t2raZaMIl% zEC4@VzMo%<3?$B@SXc&rNGY~zBKkU|ZqTY`&N-P>K`f+`Ty0E#r*%!vGxHKX#(ix| zrG~Dn&!UJK$!8LOD<2~nq51F$E9Q`mZ&chfVT<^ zSh}Nk%+Zj1;cRT1ine9nqJ8!hw%a5#yDwU_Vn@UWV$fCc*W$1lobQYe7soy-hN+$= zN$^(;byyL^Y&`H+68Xto^!nK3w99#K4pvO&4&+FQi^FsxmqW;NNv`Uzw0k$XZDN+v zHTZK`)I<~lS1EQ)zGOT)Bd6~Ww!tLz8+|Uf-9VjSGJaBV`>^FhKh+}()HEHid};%V z(IrLFC)gFal@ExOfV_q~w5bUO+yx5xaeuoLCM1d<}Y5^ioYuzKr-q0AVq zwQ>#Z_`}@?sH@;R%28%wgSSuM&lcB{%i2wxe~$PWwF1bUTy({?pS}&Q7R^)DN8KGc zPw-nq4+iCPE67QfqvLakGo~T~Jj8>WCa~G2=B#&i(baIIga1JK8>ly395zBCdoTSU z{ix?!8+?Q5QOWsva#E>^BU4LNL~Ug>_TfhIJgVpNKu^kh##4(?p%?`Djl53!d_za6 zjl19@;zitZHgH#Rzp;6()CUr?!^XT`0&i72KAG0>>@o4fb6~v#UXKUrJqDM;5F~v>T9_`?STB3Grhcsd~slYG#m^k%- zHNmfn6~rUYQ_AaIeAkmltOB1UCIy>P_8hi*0d`^vayF72M>;VS$(M>Jg!|)x^Ney{`ENoxN?QC!@JthCr+cR&)S65-{Nq!f%4&ZwdQ<^$$6Q`-!9T=tN?0}0`7b;c>Zz#Vxi7!?L%<`pG zt5<{_R*yU%JaV3U-s$k)NIX6VJ6`sBJvLL{;u&;z1O6FsViQzQdlyGdmugI6k%!xm z2XX9a3Uad^x>8+&{OXu&_!}CLkGwgIGbG#M$Y~&3;Ga0`55bwh-nhIgvFU>Uud6c+ zvGY97FtoUK($dt8>!h)*$kOP{cJ_TgGv~~9X3=OgT4p58j7E#4u_bFP*%J#3*}}$1 z$QTJ>BOHW-BaBUHO`T#yC|yDbA$1|4rTtfG`oH~=e=YRub-iaqN`8EdN7gy-_AK{v zKll3y|1WX&_Rr(wiptuX=uS3*)^I;PiZ&cTj&sPtfmm19d1lwqaGky$J@~Kx!B5`~ z{9^~q)n30sy*d}I-+mBHUw9Yo-y3M5HlrF?a+Kaw7yfDjE@2v7k6ID+5cY=T{IrDz zyu+DyKIZ-V%ha764=lXx)gEo z5O|<3RgCiW5$=xtDYnnQH}~xwfxq+pNcQ0S;ORZT7T6_D4qv_V1wH6fVEs3u16%L% zU9;5DmjZ_+zA9k<;@~oUH2IdnF*G}CSEJSUej4TXZ$_{E^w&{-`Y3hwHF#yTv=`q4 zH*8Qx?hBlPwr_21uc>+PBz9}`ol$F8a2xEAe0 z*V$S=7ySr+L|h%`{cgL;HOcAcEi`^9Al=p7lh)%*I z?%jHyys{ouS=%(6rG7tm{_SXT^Hy{StT3{0oZ5o3K-)Y7ZZU3;5^rjJuYHuA^jpLQ z=ilbv8pRLN=%tR`{FMIJM8JZ5d3$pEz?alwb^7%1RDVD&O~Os6X%XxF9PLz&zSCfH zAv%8R0h-vGyqlxL`x4OCTgz9$ci^%LXFoz-ND{9K#0&Rr|BWxARdhy2u74aIx^_SG zZaU}hfNx$!e{vkn8o3p$JGpi~^jOs#RgPYb@&~t~!`Su$IH*H^Y6t633%qvuCL9~S zMUKo;U(Rk`BbK1|;`jACp9ij>L;s;mFMI)vC@<8H?Z(QJQ5ya)RvhI$8`Z$$<-i+p z`w-ZHx}XI4zC?{9z7i{H505 ztaL8)&yT_#shcfwb}jhOGxT&%J?W=c9lV+MLZaT7)Jw z^dy>;Q8=M7a{Uy2y9RoJ%Iq>akM~1;Z%@E}cxgYJG`P0Q8Sj8AABEd*@VTMsOXw%i z7|}y(p|NSNfl<*%7Ql>s)PnmizaNdRpM@u(H;qO-LA)QNcIac>yUCNTJ%%mh+1DE% z+~+>VK-lwsVr>kZ-N(7R2Woy2CGP)PKTv}7 zw;udEvF1J;68dZEgDUlJx-}Je*Y3u(Xc_%Vf^p{2nB@<>7Tx&O|1#&hV5GHZKU$~) z=fD5WPuTZW`a7qi3bo=HbRS*#sS4Q0zRUpq^Z|1E-1+O&X6UXOlk{`1Gv;Q<>(zNU zaWwh`>RB}|#<^IMf2WNc8Ry(%YztOjtzxq*h{==U{-K~4@%d5n6 zv~1MlUE*EfljtGHsdmm>i7vv)%E?q0PDkr#n2W^g5qP>X7-1CcO9@{c>MWC+*c z-h~*bc0(+%W|dEBEK|#qFL%Z>>{;*KS876%^zip!KdX2CCTgGOEH-cBcju!oIe7cR zeT9i=>cVaM!dF-qTC=x4hi^g4aPBJW;EoKqrH=lxL+opj=e6a|x!chd`p~C{%kmHF z_vq!I&s0xV*ncW$f9)q7`?G%qS5T9Il`F(awE*Y8|5@Os=U)9V@Qh6`(gZr$G42B# zd;K<=jv}?fLGHMT4dIkIe{0Ccc#q#G98F^XLNrhPATF1aP7)7u@E}>V*(r1{gXEPM zxWc&b$YcDw!%sdHIG}IRzt)yc-TFK_{q{ZV`vQH7jd15^4((BeK0+Pe9XtC5nsM+N z^`v&wBCof}btCw19$u(PKVFg>sd)}sC7DRpFO;H_uu zb1q-I8*P2@Pl2E8$5+KlN$S%w*i_wOg*aR0&*Wxz(K8x5{Z_Dn$G`nl4?DyC^i#tW z(Vy3rd%ZR>lDv$%o3YcxPH?jvj{U$Gwb!HDcd`=n=i|hLabo-ncOOLa7p}vF&4oH~ z?e+JfDSU7WyPjZgyZCpL^-huF+SJ8a^2`Jnp-o?MDH{ z`e8MCKNE0hyU_+bHIRww=nclG6Uy+Bul(p&)Zb{PZ`>iy-=I$6o)W#{dGg6EYO5Ny zR^hw9K|X&P&ea;!I;tNo-F{RV?nvGJZsNE)^k;Y%XmNTOEx%grtzbuW>be-(o&;QT zlD=^ty!=5Vj;O!}5`3U*6%Gr&htuSuyAs>&ZrKM)DUfC^vB`@wG zuI(vLqZ3BkM}J~q-z<02E=R9_@*wmO#_uUr8Syg}V~nwXS}N@#>;FTKfm(6fR&*hwFA4;<0c zaHR=iP#R6d4*K*dIM^8c^A512In8`5z8iuoNzkVlK!dTHJO1_&)N9AZdBn~bIA`G^ z*d4vXPWo2;<_7j4GjTBF))+pvaqs6LhnDF@jueJ<x$PYuQ9Cvx)*?4!hnw&QGY1D7clY?{Q$z8<1-Q4fwPv_|6*V?j6$75wIJ*#OD5WG)tTG4(OTBUkLGOeW5x{Wwkw113$lbu@7 zp0s_5I=S}`pWxqm=)yC@m&R)QqE&h$3omSOSMWbWP5i_&v1oT+4BK6c;;em$cTEfq zatBw8$7kdj#hZIK-wM3>?Z5vj#El*BBwt7C6Ji4PX&u@}jPQO_iaav5ag*mAeC-M` ziJzNy@m2Z);K|IwC4L@38$pk&egMtw8=U10dP;AG`#O2nA@5c~bMy>#-TPmD75(rZ zzKSyNNl&0dKKkYdK`Wf29u^m=&l+qU4R@MKjS6^oj zQedndVB{U(!d_hD9u+uQUr$q`su^h>SMz+98u0z-z|B7=-oqgfcc<2<8R*M*So86> z?qCa-sPkXNx54qOI}e8=E=th*zWCwa2H&lN2_~qg%!l?a_MO?J_64utBbf>6iL>|^ zHn3-EGP?WYFN3ap^88y-cjGdBVED!5Gtud*H_6MdW3${Xzy5vh>7I_}_&rXq?&+s@ zQ1i5i1FQ*u$j+UiH_X|9VQbi51)ejrAACYAl($Sbr+9DVv9JgBv&DFz6}rm%UET zhn{589Kjy#%v8{cvIoRP`vM8>dwCDCd+timLC7PH!vS>BEd>n~aj35dhgV0Z$9;i~ z8~4zOufe&jhkJD;dPO;FOX~b^=N!&aZORz9B8N?=#k42-;NN~7Ex+?w)ID=G>VOZj z^e1xMDK?*ZKWhQKOLFoQz5*XaTrI)}$yq1B{U zya)F~U$c)Mz#e-?#BT4edWTrv!XBA-!t4+3gi{r3evO#mJqo|?N$#Ko{C4a@(7{i$ z2YLJ^$2^{)Hf_>3ut##3`aTDbQsGWvi=OiwJeYTEy2mdBj$r)Q^HFE%Ik3S=FywmF zT3icS()tYC(exsBSK=TX9#I@jGeC_KE6`&jpFQh+S$b>sODEA@jURoUTz)2MFQEqq+lb&E3q>dbD?ieyBMRY$K=T{r1Mb6)+uhAddFNK1^K&*E_QW?nWC821&x5C&|OZ z*v=riq@VeW!(Wauc1JwL6L@m=Wcma>HEg;CpHRkD3fM}SnAw_HjJn)ynL*=Z&)%L& zlbW%KZG}Bx{T0?;nOo|O&+pzV$MLd+-5T+|D6z+N5hwv17;Os>5c zILeumFGZ6p&xf<9u?{g#iG6Smb#O>$9zOWsO4NbNwP)XC{Z;nczgL+-gT!aN6J6rZ zitIsghIveL9z1#GlVv{X@x?H1o3UN{_zF6;?X`E0zZgxdus6(YdXRm zl!yC}^Kb8kSKPZ4HNhb@Vz+x$X8f@C*h2x{uE5xiU*v3xV6MV!@5#;3SLDpYzO#16 z*B+*@he^hsz$UfJHonzaqHX~5)fpoGEy^_}aW{6!Rv%Zz@hF9;&%0aW3WV zVi;e&SeASd^xTfme)|sa(r=BOXCFpfo8w~#+P-yM^8mg@-f$lJq)(f%mAB-ZeGmP%scTPBm zobTnJ{&Boee}gG<{O&VO&e7(bN9)jY#6#L5AD+}bfUhTkySEK_Pjm4^h*e!`BJ+K9ekGi*++n;q1NKBSVQd@D!V#1MFKQoB zO}zX^3ay#_t+aEZz8hhWJ@XOPJ^~-pWc)gNAJ&dN8~;3a=i~p=SB;Hh%g=E}^f9pI zg8S`1&mC-$C!^yTj=6sDu0A zh^=R}iwtwk!^PO+2{D{l)#N+1yBb*2^ERH<`E%_-+t5Gs1?!Abh$W1_h+dpIRM{Wz z=IDFH8EgVONf7Ui@jJoz)??3duSA}DxG}wL6HDApJxUBcN(`enj;+;*StW8-9&A`3 zZ`gZoa-Vz@9B8a+a9$<+NZZwyDscIZ?VQbhVz>ref$y)8A5`Dj&w1>G18^UnO>qYU zPJFn@doHnoI`-upyd!R|HO6PfX3V`n?5HooX$K#b<9I&2$Dzua9ow__o=tO+p0>G{ zd3oo%35KXrPkH~}zFra?;{aT|{GB@KXH&eByTDms3nli;cLy|Q4@J!xatC=<9h~pc zDH1oUVf{VZtYaG$G?{g3gc|lx#!ejD+$+xao_`A+Tx0n~`nKErC~MFrv`g>wxc|G* zulqQM0`V+QJ}iK_O5^m9!RG28OJG!eu83_HiC6My+E@_|*FCR!?$~7*m$<5pcuq~Y zvKng_ua@C>{Ctl1kRcA~a|zxTGEm{&MfBHqu^-j|>Z{Z87}U1n;v#s-J;=7H^~lq{ z(ajby9cpg>i$O>yNk<;u~=4bFd&bo-!r?N;4 zr6+HXslxab=IVQUb)w<| z@sV?gGv+Xww_(PQV>1b37O`Ev)Lxu(N^yp1_At+$+Pf*D4XNzc9`QxKJH#sbA?=ly zqR|!Jzj$)n;+Rmb8>gB~1_B3jK5AmSP{ARjLrVEj=abj@SYoE2y<{B%FaQ1Ft$)nWF4RU5og^= z@f>kXt-A3j<+(7fa}fLJJH|+LRxNCOgzq0=k6ZYG{rfN;e$b+S)eK{!!6a5{^Ugs` z9Ol5dW%6*5yqhKdru7HxzAnFeUH61 zFSzHPyD`c<;`io$YYrtb75U6R_YpUGPUai2toSxbj5HRgx%HfUGVG5&W2`RB5R>d+x zXE+;Udx1D&jp1J(Nj@LuK)h$aljP^P`H1+_56<2LrV$^C zm4EYjV!HK$nB6_)e6zg&ulITCM)M1HJBZ&55KF~v@&@61#F{?rMFs3x7EdwAb7{*P%NB*Su*<<{~ z-p!5Xczi_s(#z3&hw<2l?lY=lDp)vZ z3h)VQ72nBbJ(LDxr8ytJM}G8u-}SqSv(&-N&%R919Et`Q+$HRGOOY%6@ z8o~FszvtoS&0%35JQH(m@K@L29FBz=b?LF;L9k!@&>7--AA} zAD_~m{f;mX=deA0KkphsoMIilSmk*VV~Ew_%)lA&Glk}0xQc(` diff --git a/Templates/BaseGame/game/core/rendering/scripts/graphicsOptions.tscript b/Templates/BaseGame/game/core/rendering/scripts/graphicsOptions.tscript index a03745ccb..9284af583 100644 --- a/Templates/BaseGame/game/core/rendering/scripts/graphicsOptions.tscript +++ b/Templates/BaseGame/game/core/rendering/scripts/graphicsOptions.tscript @@ -453,7 +453,7 @@ new SimGroup( LightingQualityList ) class = "GraphicsQualityLevel"; caseSensitive = true; - displayName = "High"; + displayName = "Highest"; key["$pref::maximumNumOfLights"] = -1; key["$pref::useLightFade"] = false; @@ -821,6 +821,11 @@ function _makePrettyResString( %resString, %giveAspectRation ) %width = getWord( %resString, $WORD::RES_X ); %height = getWord( %resString, $WORD::RES_Y ); + //If it's an x, it means we've got the human-readable 'x' in the middle + //so skip it + if(%height $= "x") + %height = getWord( %resString, 2 ); + %aspect = %width / %height; %aspect = mRound( %aspect * 100 ) * 0.01; diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript index 8851d1990..2dd1d7f10 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript @@ -46,6 +46,9 @@ //headbob //FOV +$yesNoList = "No\tYes"; +$onOffList = "Off\tOn"; + function OptionsMenu::onAdd(%this) { if(!isObject(%this.optionsCategories)) @@ -159,6 +162,7 @@ function OptionsMenu::apply(%this) %hasVideoChanges = false; %hasPostFXChanges = false; %hasAudioChanges = false; + %hasGraphicsChanges = false; for(%i=0; %i < %this.unappliedChanges.count(); %i++) { %targetVar = %this.unappliedChanges.getKey(%i); @@ -184,7 +188,10 @@ function OptionsMenu::apply(%this) if(!%wasKeybind) { - %currentValue = getVariable(%targetVar); + %sanitizedVar = strReplace(%targetVar, "[", ""); + %sanitizedVar = strReplace(%sanitizedVar, "]", ""); + %sanitizedVar = strReplace(%sanitizedVar, ",", "_"); + %currentValue = getVariable(%sanitizedVar); if(%currentValue !$= %newValue) { setVariable(%targetVar, %newValue); @@ -195,22 +202,6 @@ function OptionsMenu::apply(%this) { MessageBoxOK( "Change requires restart", "Please restart the game for a display device change to take effect." ); } - else if(startsWith(%targetVar, "$pref::Graphics::")) - { - //isolate the quality group name, like $pref::Graphics::LightingQuality - //we grab LightingQuality - %qualityGroupName = getSubStr(%targetVar, 17); - if(isObject(%qualityGroupName @ "List")) - { - //yep, it's a quality group, so apply it - (%qualityGroupName @ "List").applySetting(%newValue); - } - - if(%qualityGroupName $= "TextureQuality") - { - reloadTextures(); - } - } else if(startsWith(%targetVar, "$pref::PostFX::")) { %hasPostFXChanges = true; @@ -218,11 +209,26 @@ function OptionsMenu::apply(%this) else if(startsWith(%targetVar, "$pref::Video::")) { %hasVideoChanges = true; + + //if it's the resolution, it's possible we got the human-friendly + //version stored off. if so, reprocess into the usable state + if(%targetVar $= "$pref::Video::Resolution") + { + if(strpos(%newValue, " x ") != -1) + { + %newValue = strreplace(%newValue, " x ", " "); + setVariable(%targetVar, %newValue); + } + } } else if(startsWith(%targetVar, "$pref::SFX::")) { %hasAudioChanges = true; } + else if(startsWith(%targetVar, "$pref::Graphics::")) + { + %hasGraphicsChanges = true; + } } } } @@ -265,6 +271,11 @@ function OptionsMenu::apply(%this) updateAudioSettings(); } + if(%hasGraphicsChanges) + { + updateGraphicsSettings(); + } + //Finally, write our prefs to file %prefPath = getPrefpath(); export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false); @@ -282,8 +293,17 @@ function OptionsMenu::resetToDefaults(%this) function OptionsMenu::refresh(%this) { + %cat = %this.currentCategory; if(%this.currentCategory !$= "") { + if(!isInt(%this.currentCategory)) + { + %this.currentCategory = getOptionsCategoryIndexByName(%this.currentCategory); + } + + if(%this.currentCategory == -1) + return; + %category = %this.optionsCategories.getKey(%this.currentCategory); %command = %this.optionsCategories.getValue(%this.currentCategory); eval(%command); @@ -299,7 +319,10 @@ function OptionsMenu::getOptionVariableValue(%this, %variableName) return strreplace(%value, "\"", ""); } - return getVariable(%variableName); + %sanitizedVar = strReplace(%variableName, "[", ""); + %sanitizedVar = strReplace(%sanitizedVar, "]", ""); + %sanitizedVar = strReplace(%sanitizedVar, ",", "_"); + return getVariable(%sanitizedVar); } function OptionsMenuSelectButton::onVisible(%this, %state) @@ -321,6 +344,8 @@ function populateDisplaySettingsList() { OptionsMenuSettingsList.clear(); + OptionsMenu.currentCategory = "Display"; + OptionName.setText(""); OptionDescription.setText(""); @@ -378,20 +403,26 @@ function populateDisplaySettingsList() if(%mode !$= "Borderless") { %resolutionList = getScreenResolutionList($pref::Video::deviceId, $pref::Video::deviceMode); - OptionsMenuSettingsList.addOptionRow("Resolution", "$pref::Video::Resolution", %resolutionList, false, "", true, "Resolution of the game window", _makePrettyResString( $pref::Video::mode )); + %resolution = OptionsMenu.getOptionVariableValue("$pref::Video::Resolution"); + if(%resolution $= "") + %resolution = $pref::Video::mode; + + %resolution = _makePrettyResString(%resolution); + + OptionsMenuSettingsList.addOptionRow("Resolution", "$pref::Video::Resolution", %resolutionList, false, "", true, "Resolution of the game window", %resolution); } - OptionsMenuSettingsList.addOptionRow("VSync", "$pref::Video::disableVerticalSync", "No\tYes", false, "", true, "", convertBoolToYesNo(!$pref::Video::disableVerticalSync)); + OptionsMenuSettingsList.addOptionBoolRow("VSync", "$pref::Video::disableVerticalSync", $yesNoList, false, "", true, ""); %refreshList = getScreenRefreshList($pref::Video::mode); - OptionsMenuSettingsList.addOptionRow("Refresh Rate", "$pref::Video::RefreshRate", %refreshList, false, "", true, "", $pref::Video::RefreshRate); + OptionsMenuSettingsList.addOptionRow("Refresh Rate", "$pref::Video::RefreshRate", %refreshList, false, "", true, "", OptionsMenu.getOptionVariableValue("$pref::Video::RefreshRate")); //move to gameplay tab - OptionsMenuSettingsList.addSliderRow("Field of View", "", 75, 5, "65 100", ""); + //OptionsMenuSettingsList.addSliderRow("Field of View", "", 75, 5, "65 100", ""); - OptionsMenuSettingsList.addSliderRow("Brightness", "", 0.5, 0.1, "0 1", ""); - OptionsMenuSettingsList.addSliderRow("Contrast", "", 0.5, 0.1, "0 1", ""); + //OptionsMenuSettingsList.addSliderRow("Brightness", "", 0.5, 0.1, "0 1", ""); + //OptionsMenuSettingsList.addSliderRow("Contrast", "", 0.5, 0.1, "0 1", ""); } // @@ -401,32 +432,76 @@ function populateGraphicsSettingsList() { OptionsMenuSettingsList.clear(); + OptionsMenu.currentCategory = "Graphics"; + OptionName.setText(""); OptionDescription.setText(""); %yesNoList = "No\tYes"; %onOffList = "Off\tOn"; - %highMedLow = "Low\tMedium\tHigh"; %anisoFilter = "Off\t4\t8\t16"; %aaFilter = "Off\t1\t2\t4"; - OptionsMenuSettingsList.addOptionRow("Lighting Quality", "$pref::Graphics::LightingQuality", getQualityLevels(LightingQualityList), false, "", true, "Amount and drawdistance of local lights", getCurrentQualityLevel(LightingQualityList)); - OptionsMenuSettingsList.addOptionRow("Shadow Quality", "$pref::Graphics::ShadowQuality", getQualityLevels(ShadowQualityList), false, "", true, "Shadow revolution quality", getCurrentQualityLevel(ShadowQualityList)); - OptionsMenuSettingsList.addOptionRow("Soft Shadow Quality", "$pref::Graphics::SoftShadowQuality", getQualityLevels(SoftShadowList), false, "", true, "Amount of softening applied to shadowmaps", getCurrentQualityLevel(SoftShadowList)); - OptionsMenuSettingsList.addOptionRow("Mesh Quality", "$pref::Graphics::MeshQuality", getQualityLevels(MeshQualityGroup), false, "", true, "Fidelity of rendering of mesh objects", getCurrentQualityLevel(MeshQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Object Draw Distance", "$pref::Graphics::ObjectDrawDistance", getQualityLevels(MeshDrawDistQualityGroup), false, "", true, "Dictates if and when static objects fade out in the distance", getCurrentQualityLevel(MeshDrawDistQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Texture Quality", "$pref::Graphics::TextureQuality", getQualityLevels(TextureQualityGroup), false, "", true, "Fidelity of textures", getCurrentQualityLevel(TextureQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Terrain Quality", "$pref::Graphics::TerrainQuality", getQualityLevels(TerrainQualityGroup), false, "", true, "Quality level of terrain objects", getCurrentQualityLevel(TerrainQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Decal Lifetime", "$pref::Graphics::DecalLifetime", getQualityLevels(DecalLifetimeGroup), false, "", true, "How long decals are rendered", getCurrentQualityLevel(DecalLifetimeGroup)); - OptionsMenuSettingsList.addOptionRow("Ground Cover Density", "$pref::Graphics::GroundCoverDensity", getQualityLevels(GroundCoverDensityGroup), false, "", true, "Density of ground cover items, such as grass", getCurrentQualityLevel(GroundCoverDensityGroup)); - OptionsMenuSettingsList.addOptionRow("Shader Quality", "$pref::Graphics::ShaderQuality", getQualityLevels(ShaderQualityGroup), false, "", true, "Dictates the overall shader quality level, adjusting what features are enabled.", getCurrentQualityLevel(ShaderQualityGroup)); - OptionsMenuSettingsList.addOptionRow("Anisotropic Filtering", "$pref::Video::defaultAnisotropy", %anisoFilter, false, "", true, "Amount of Anisotropic Filtering on textures, which dictates their sharpness at a distance", $pref::Video::defaultAnisotropy); - OptionsMenuSettingsList.addOptionRow("Anti-Aliasing", "$pref::Video::AA", %aaFilter, false, "", true, "Amount of Post-Processing Anti-Aliasing applied to rendering", $pref::Video::AA); - OptionsMenuSettingsList.addOptionRow("Parallax", "$pref::Video::disableParallaxMapping", %onOffList, false, "", true, "Whether the surface parallax shader effect is enabled", convertBoolToOnOff(!$pref::Video::disableParallaxMapping)); - OptionsMenuSettingsList.addOptionRow("Water Reflections", "$pref::Water::disableTrueReflections", %onOffList, false, "", true, "Whether water reflections are enabled", convertBoolToOnOff(!$pref::Water::disableTrueReflections)); - OptionsMenuSettingsList.addOptionRow("SSAO", "$pref::PostFX::EnableSSAO", %onOffList, false, "", true, "Whether Screen-Space Ambient Occlusion is enabled", convertBoolToOnOff($pref::PostFX::EnableSSAO)); - OptionsMenuSettingsList.addOptionRow("Depth of Field", "$pref::PostFX::EnableDOF", %onOffList, false, "", true, "Whether the Depth of Field effect is enabled", convertBoolToOnOff($pref::PostFX::EnableDOF)); - OptionsMenuSettingsList.addOptionRow("Vignette", "$pref::PostFX::EnableVignette", %onOffList, false, "", true, "Whether the vignette effect is enabled", convertBoolToOnOff($pref::PostFX::EnableVignette)); - OptionsMenuSettingsList.addOptionRow("Light Rays", "$pref::PostFX::EnableLightRays", %onOffList, false, "", true, "Whether the light rays effect is enabled", convertBoolToOnOff($pref::PostFX::EnableLightRays)); + OptionsMenuSettingsList.addOptionQualityLevelRow("Lighting Quality", "$pref::Graphics::LightingQuality", + LightingQualityList, false, "", true, "Amount and drawdistance of local lights"); + OptionsMenuSettingsList.addOptionQualityLevelRow("Shadow Quality", "$pref::Graphics::ShadowQuality", + ShadowQualityList, false, "", true, "Shadow revolution quality"); + + %shadowQuality = OptionsMenu.getOptionVariableValue("$pref::Graphics::ShadowQuality"); + if(%shadowQuality !$= "None") + { + OptionsMenuSettingsList.addOptionQualityLevelRow("Soft Shadow Quality", "$pref::Graphics::SoftShadowQuality", + SoftShadowList, false, "", true, "Amount of softening applied to shadowmaps"); + } + + OptionsMenuSettingsList.addOptionQualityLevelRow("Mesh Quality", "$pref::Graphics::MeshQuality", + MeshQualityGroup, false, "", true, "Fidelity of rendering of mesh objects"); + OptionsMenuSettingsList.addOptionQualityLevelRow("Object Draw Distance", "$pref::Graphics::ObjectDrawDistance", + MeshDrawDistQualityGroup, false, "", true, "Dictates if and when static objects fade out in the distance"); + OptionsMenuSettingsList.addOptionQualityLevelRow("Texture Quality", "$pref::Graphics::TextureQuality", + TextureQualityGroup, false, "", true, "Fidelity of textures"); + OptionsMenuSettingsList.addOptionQualityLevelRow("Terrain Quality", "$pref::Graphics::TerrainQuality", + TerrainQualityGroup, false, "", true, "Quality level of terrain objects"); + OptionsMenuSettingsList.addOptionQualityLevelRow("Decal Lifetime", "$pref::Graphics::DecalLifetime", + DecalLifetimeGroup, false, "", true, "How long decals are rendered"); + OptionsMenuSettingsList.addOptionQualityLevelRow("Ground Cover Density", "$pref::Graphics::GroundCoverDensity", + GroundCoverDensityGroup, false, "", true, "Density of ground cover items, such as grass"); + OptionsMenuSettingsList.addOptionQualityLevelRow("Shader Quality", "$pref::Graphics::ShaderQuality", + ShaderQualityGroup, false, "", true, "Dictates the overall shader quality level, adjusting what features are enabled."); + OptionsMenuSettingsList.addOptionRow("Anisotropic Filtering", "$pref::Video::defaultAnisotropy", %anisoFilter, false, "", true, "Amount of Anisotropic Filtering on textures, which dictates their sharpness at a distance"); + OptionsMenuSettingsList.addOptionRow("Anti-Aliasing", "$pref::Video::AA", %aaFilter, false, "", true, "Amount of Post-Processing Anti-Aliasing applied to rendering"); + OptionsMenuSettingsList.addOptionBoolRow("Parallax", "$pref::Video::disableParallaxMapping", %onOffList, false, "", true, "Whether the surface parallax shader effect is enabled"); + OptionsMenuSettingsList.addOptionBoolRow("Water Reflections", "$pref::Water::disableTrueReflections", %onOffList, false, "", true, "Whether water reflections are enabled"); + OptionsMenuSettingsList.addOptionBoolRow("SSAO", "$pref::PostFX::EnableSSAO", %onOffList, false, "", true, "Whether Screen-Space Ambient Occlusion is enabled"); + OptionsMenuSettingsList.addOptionBoolRow("Depth of Field", "$pref::PostFX::EnableDOF", %onOffList, false, "", true, "Whether the Depth of Field effect is enabled"); + OptionsMenuSettingsList.addOptionBoolRow("Vignette", "$pref::PostFX::EnableVignette", %onOffList, false, "", true, "Whether the vignette effect is enabled"); + OptionsMenuSettingsList.addOptionBoolRow("Light Rays", "$pref::PostFX::EnableLightRays", %onOffList, false, "", true, "Whether the light rays effect is enabled"); +} + +function updateGraphicsSettings() +{ + if($pref::Graphics::LightingQuality !$= getCurrentQualityLevel(LightingQualityList)) + LightingQualityList.applySetting($pref::Graphics::LightingQuality); + if($pref::Graphics::ShadowQuality !$= getCurrentQualityLevel(ShadowQualityList)) + ShadowQualityList.applySetting($pref::Graphics::ShadowQuality); + if($pref::Graphics::SoftShadowQuality !$= getCurrentQualityLevel(SoftShadowList)) + SoftShadowList.applySetting($pref::Graphics::SoftShadowQuality); + + if($pref::Graphics::MeshQuality !$= getCurrentQualityLevel(MeshQualityGroup)) + MeshQualityGroup.applySetting($pref::Graphics::MeshQuality); + if($pref::Graphics::ObjectDrawDistance !$= getCurrentQualityLevel(MeshDrawDistQualityGroup)) + MeshDrawDistQualityGroup.applySetting($pref::Graphics::ObjectDrawDistance); + if($pref::Graphics::TextureQuality !$= getCurrentQualityLevel(TextureQualityGroup)) + { + TextureQualityGroup.applySetting($pref::Graphics::TextureQuality); + + reloadTextures(); + } + if($pref::Graphics::TerrainQuality !$= getCurrentQualityLevel(TerrainQualityGroup)) + TerrainQualityGroup.applySetting($pref::Graphics::TerrainQuality); + if($pref::Graphics::DecalLifetime !$= getCurrentQualityLevel(DecalLifetimeGroup)) + DecalLifetimeGroup.applySetting($pref::Graphics::DecalLifetime); + if($pref::Graphics::GroundCoverDensity !$= getCurrentQualityLevel(GroundCoverDensityGroup)) + GroundCoverDensityGroup.applySetting($pref::Graphics::GroundCoverDensity); } function updateDisplaySettings() @@ -522,6 +597,8 @@ function populateAudioSettingsList() { OptionsMenuSettingsList.clear(); + OptionsMenu.currentCategory = "Audio"; + OptionName.setText(""); OptionDescription.setText(""); @@ -557,13 +634,13 @@ function populateAudioSettingsList() } } - OptionsMenuSettingsList.addOptionRow("Audio Provider", "$pref::SFX::AudioProvider", %audioProviderList, false, "audioProviderChanged", true, "", $currentAudioProvider); - OptionsMenuSettingsList.addOptionRow("Audio Device", "$pref::SFX::device", %audioDeviceList, false, "", true, $pref::SFX::device); + OptionsMenuSettingsList.addOptionRow("Audio Provider", "$pref::SFX::AudioProvider", %audioProviderList, false, "audioProviderChanged", true, ""); + OptionsMenuSettingsList.addOptionRow("Audio Device", "$pref::SFX::device", %audioDeviceList, false, "", true); - OptionsMenuSettingsList.addSliderRow("Master Volume", "$pref::SFX::masterVolume", $pref::SFX::masterVolume, 0.1, "0 1", ""); - OptionsMenuSettingsList.addSliderRow("GUI Volume", "$pref::SFX::channelVolume[ $GuiAudioType]", $pref::SFX::channelVolume[ $GuiAudioType], 0.1, "0 1", ""); - OptionsMenuSettingsList.addSliderRow("Effects Volume", "$pref::SFX::channelVolume[ $SimAudioType ]", $pref::SFX::channelVolume[ $SimAudioType ], 0.1, "0 1", ""); - OptionsMenuSettingsList.addSliderRow("Music Volume", "$pref::SFX::channelVolume[ $MusicAudioType ]", $pref::SFX::channelVolume[ $MusicAudioType ], 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("Master Volume", "$pref::SFX::masterVolume", 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("GUI Volume", "$pref::SFX::channelVolume[" @ $GuiAudioType @ "]", 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("Effects Volume", "$pref::SFX::channelVolume[" @ $SimAudioType @ "]", 0.1, "0 1", ""); + OptionsMenuSettingsList.addSliderRow("Music Volume", "$pref::SFX::channelVolume[" @ $MusicAudioType @ "]", 0.1, "0 1", ""); } function audioProviderChanged() @@ -613,6 +690,8 @@ function populateKeyboardMouseSettingsList() { OptionsMenuSettingsList.clear(); + OptionsMenu.currentCategory = "Keyboard & Mouse"; + OptionName.setText(""); OptionDescription.setText(""); @@ -626,6 +705,8 @@ function populateGamepadSettingsList() { OptionsMenuSettingsList.clear(); + OptionsMenu.currentCategory = "Gamepad"; + OptionName.setText(""); OptionDescription.setText(""); @@ -717,21 +798,57 @@ function OptionsMenuSettingsList::addOptionRow(%this, %label, %targetPrefVar, %o %option.targetPrefVar = %targetPrefVar; //create a var-option association - //now some override trickery, if we have a value cached for unapplied changes, swapsies the defaultValue out - //with the unapplied, allowing us to change options categories without losing changes - %unappliedPrefIndex = OptionsMenu.unappliedChanges.getIndexFromValue(%targetPrefVar); - if(%unappliedPrefIndex != -1) - { - %unappliedValue = OptionsMenu.unappliedChanges.getValue(%unappliedPrefIndex); - %defaultValue = %unappliedValue; - } - %option.setListSetting(%label, %optionsList, %wrapOptions, %callback, %enabled, %description, %defaultValue); %this.add(%option); } -function OptionsMenuSettingsList::addSliderRow(%this, %label, %targetPrefVar, %defaultValue, %increment, %range, %callback, %enabled, %description) +function OptionsMenuSettingsList::addOptionQualityLevelRow(%this, %label, %targetPrefVar, %qualityLevelList, %wrapOptions, %callback, %enabled, %description, %defaultValue) +{ + if(%defaultValue $= "") + { + %unappliedPrefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetPrefVar); + if(%unappliedPrefIndex != -1) + { + %value = OptionsMenu.unappliedChanges.getValue(%unappliedPrefIndex); + %defaultValue = strreplace(%value, "\"", ""); + } + + if(%defaultValue $= "") + { + %sanitizedVar = strReplace(%targetPrefVar, "[", ""); + %sanitizedVar = strReplace(%sanitizedVar, "]", ""); + %sanitizedVar = strReplace(%sanitizedVar, ",", "_"); + %defaultValue = getVariable(%sanitizedVar); + } + + if(%defaultValue $= "") + %defaultValue = getCurrentQualityLevel(%qualityLevelList); + } + + return %this.addOptionRow(%label, %targetPrefVar, getQualityLevels(%qualityLevelList), + %wrapOptions, %callback, %enabled, %description, %defaultValue); +} + +function OptionsMenuSettingsList::addOptionBoolRow(%this, %label, %targetPrefVar, %qualityLevelList, %wrapOptions, %callback, %enabled, %description, %defaultValue) +{ + if(%defaultValue $= "") + %defaultValue = OptionsMenu.getOptionVariableValue(%targetPrefVar); + + if(%qualityLevelList $= $yesNoList && isInt(%defaultValue)) + { + %defaultValue = convertBoolToYesNo(!%defaultValue); + } + else if(%qualityLevelList $= $onOffList && isInt(%defaultValue)) + { + %defaultValue = convertBoolToOnOff(!%defaultValue); + } + + return %this.addOptionRow(%label, %targetPrefVar, %qualityLevelList, + %wrapOptions, %callback, %enabled, %description, %defaultValue); +} + +function OptionsMenuSettingsList::addSliderRow(%this, %label, %targetPrefVar, %increment, %range, %callback, %enabled, %description, %defaultValue) { if(%enabled $= "") %enabled = true; @@ -752,14 +869,8 @@ function OptionsMenuSettingsList::addSliderRow(%this, %label, %targetPrefVar, %d %option.targetPrefVar = %targetPrefVar; //create a var-option association - //now some override trickery, if we have a value cached for unapplied changes, swapsies the defaultValue out - //with the unapplied, allowing us to change options categories without losing changes - %unappliedPrefIndex = OptionsMenu.unappliedChanges.getIndexFromValue(%targetPrefVar); - if(%unappliedPrefIndex != -1) - { - %unappliedValue = OptionsMenu.unappliedChanges.getValue(%unappliedPrefIndex); - %defaultValue = %unappliedValue; - } + if(%defaultValue $= "") + %defaultValue = OptionsMenu.getOptionVariableValue(%targetPrefVar); %option.setSliderSetting(%label, %defaultValue, %increment, %range, %callback, %enabled, %description); @@ -809,16 +920,20 @@ function convertBoolToYesNo(%val) { if(%val == 1) return "Yes"; - else + else if(%val == 0) return "No"; + + return %val; } function convertBoolToOnOff(%val) { if(%val == 1) return "On"; - else + else if(%val == 0) return "Off"; + + return %val; } function getDisplayDeviceName() @@ -883,7 +998,7 @@ function MenuOptionsButton::onChange(%this) } //Update the UI in case there's responsive logic - schedule(32, OptionsMenu, "refresh"); + OptionsMenu.schedule(32, "refresh"); } function OptionsMenu::onKeybindChanged(%this, %actionMap, %keybind) @@ -913,6 +1028,17 @@ function removeOptionsMenuCategory(%categoryName) OptionsMenu.optionsCategories.erase(%index); } +function getOptionsCategoryIndexByName(%categoryName) +{ + for(%i=0; %i < OptionsMenu.optionsCategories.count(); %i++) + { + if(OptionsMenu.optionsCategories.getKey(%i) $= %categoryName) + return %i; + } + + return -1; +} + function addListOption(%label, %description, %targetPrefVar, %optionsList, %wrapOptions, %callback, %enabled) { if(%wrapOptions $= "") diff --git a/Templates/BaseGame/game/data/defaults.tscript b/Templates/BaseGame/game/data/defaults.tscript index d45116ff9..acd2a0f43 100644 --- a/Templates/BaseGame/game/data/defaults.tscript +++ b/Templates/BaseGame/game/data/defaults.tscript @@ -125,11 +125,6 @@ $pref::SFX::channelVolume6 = 1; $pref::SFX::channelVolume7 = 1; $pref::SFX::channelVolume8 = 1; -$pref::SFX::channelVolume[1] = 1; -$pref::SFX::channelVolume[2] = 1; -$pref::SFX::channelVolume[3] = 1; -$pref::SFX::channelVolume[4] = 1; - $pref::PostEffect::PreferedHDRFormat = "GFXFormatR8G8B8A8"; /// This is an scalar which can be used to reduce the diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index fc3e3576c..eca3729f7 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript @@ -1088,7 +1088,7 @@ function AssetBrowserPreviewButton::onRightClick(%this) //Do some enabling/disabling of options depending on asset type EditAssetPopup.enableItem(0, true); - EditAssetPopup.enableItem(7, true); + EditAssetPopup.enableItem(9, true); //Is it an editable type? if(%assetType $= "ImageAsset" /*|| %assetType $= "GameObjectAsset"*/ || %assetType $= "CppAsset") @@ -1101,9 +1101,18 @@ function AssetBrowserPreviewButton::onRightClick(%this) || %assetType $= "MaterialAsset" || %assetType $= "ParticleAsset" || %assetType $= "PostEffectAsset" || %assetType $= "ScriptAsset" || %assetType $= "StateMachineAsset") { - EditAssetPopup.enableItem(7, false); + EditAssetPopup.enableItem(9, false); } + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + if(%assetDef.originalFilePath $= "" || !isFile(%assetDef.originalFilePath)) + { + //if we have no noted original import file path or it's invalid + //we can't reimport either + EditAssetPopup.enableItem(9, false); + } + AssetDatabase.releaseAsset(EditAssetPopup.assetId); + if(%assetType $= "LevelAsset") { EditLevelAssetPopup.showPopup(Canvas); @@ -2403,19 +2412,14 @@ function AssetBrowserFilterTree::onControlDropped( %this, %payload, %position ) %assetName = %payload.assetName; %moduleName = %payload.moduleName; - echo("DROPPED A " @ %assetType @ " ON THE ASSET BROWSER NAVIGATION TREE!"); - %item = %this.getItemAtPosition(%position); - echo("DROPPED IT ON ITEM " @ %item); - %parent = %this.getParentItem(%item); if(%item != 1) { //we're a folder entry, cool %path = %this.getItemValue(%item) @ "/" @ %this.getItemText(%item); - echo("DROPPED IT ON PATH " @ %path); if(%path !$= AssetBrowser.dirHandler.CurrentAddress) { @@ -2430,7 +2434,11 @@ function AssetBrowserFilterTree::onControlDropped( %this, %payload, %position ) //Do any cleanup required given the type if(AssetBrowser.isMethod("moveFolder")) + { eval(AssetBrowser @ ".moveFolder(\""@%originFolder@"\",\""@%path@"\");"); + + AssetBrowser.refresh(); + } } else { @@ -2443,6 +2451,8 @@ function AssetBrowserFilterTree::onControlDropped( %this, %payload, %position ) { %command = AssetBrowser @ ".move" @ %assetType @ "(" @ %assetDef @ ",\"" @ %path @ "\");"; eval(AssetBrowser @ ".move" @ %assetType @ "(" @ %assetDef @ ",\"" @ %path @ "\");"); + + AssetBrowser.refresh(); } } } diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cpp.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cpp.tscript index 66f7cb64a..a42431bfd 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cpp.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cpp.tscript @@ -204,7 +204,7 @@ function AssetBrowser::deleteCpp(%this, %assetDef) function AssetBrowser::moveCpp(%this, %assetDef, %destination) { %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); - %targetModule = AssetBrowser.getModuleFromAddress(%destination); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); %newAssetPath = moveAssetFile(%assetDef, %destination); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cubemap.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cubemap.tscript index b050d37cd..c2a5429f3 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cubemap.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/cubemap.tscript @@ -69,7 +69,7 @@ function AssetBrowser::deleteCubemapAsset(%this, %assetDef) function AssetBrowser::moveCubemapAsset(%this, %assetDef, %destination) { /*%currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); - %targetModule = AssetBrowser.getModuleFromAddress(%destination); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); %newAssetPath = moveAssetFile(%assetDef, %destination); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameObject.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameObject.tscript index c25eda8f4..7cff48ba5 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameObject.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameObject.tscript @@ -233,7 +233,7 @@ function AssetBrowser::deleteGameObjectAsset(%this, %assetDef) function AssetBrowser::moveGameObjectAsset(%this, %assetDef, %destination) { %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); - %targetModule = AssetBrowser.getModuleFromAddress(%destination); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); %newAssetPath = moveAssetFile(%assetDef, %destination); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gui.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gui.tscript index dfebccb47..7a5f66a64 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gui.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gui.tscript @@ -145,15 +145,15 @@ function AssetBrowser::deleteGUIAsset(%this, %assetDef) function AssetBrowser::moveGUIAsset(%this, %assetDef, %destination) { %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); - %targetModule = AssetBrowser.getModuleFromAddress(%destination); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); %newAssetPath = moveAssetFile(%assetDef, %destination); if(%newAssetPath $= "") return false; - moveAssetLooseFile(%assetDef.guifile, %destination); - moveAssetLooseFile(%assetDef.scriptFile, %destination); + moveAssetLooseFile(%assetDef.getGUIPath(), %destination); + moveAssetLooseFile(%assetDef.getScriptPath(), %destination); AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript index 0dbebd39b..df8b2467c 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript @@ -175,8 +175,11 @@ function AssetBrowser::importImageAsset(%this, %assetItem) AssetDatabase.refreshAsset(%assetId); } -function AssetBrowser::buildImageAssetPreview(%this, %assetDef, %previewData) +function AssetBrowser::buildImageAssetPreview(%this, %assetDef, %previewData, %forcePreviewRegenerate) { + if(%forcePreviewRegenerate $= "") + %forcePreviewRegenerate = false; + %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(%assetDef.getImagePath()))); %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/"; @@ -195,7 +198,7 @@ function AssetBrowser::buildImageAssetPreview(%this, %assetDef, %previewData) %previewAssetName = %module.moduleId @ "_" @ %assetDef.assetName @ "_PreviewImage"; - if(%generatePreview) + if(%generatePreview || %forcePreviewRegenerate) { displayEditorLoadingGui("Generating Image Asset Preview..."); @@ -203,20 +206,23 @@ function AssetBrowser::buildImageAssetPreview(%this, %assetDef, %previewData) if(%success) { - %previewAsset = new ImageAsset() + if(!AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) { - assetName = %previewAssetName; - versionId = 1; - imageFile = fileName(%previewFilePath); - }; - - %previewAssetName = "ToolsModule:" @ %previewAssetName; - %previewImgAssetPath = %previewPath @ %previewAsset.assetName @ ".asset.taml"; - %assetImportSuccessful = TAMLWrite(%previewAsset, %previewImgAssetPath); - - %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); + %previewAsset = new ImageAsset() + { + assetName = %previewAssetName; + versionId = 1; + imageFile = fileName(%previewFilePath); + }; - %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + %previewAssetName = "ToolsModule:" @ %previewAssetName; + %previewImgAssetPath = %previewPath @ %previewAsset.assetName @ ".asset.taml"; + %assetImportSuccessful = TAMLWrite(%previewAsset, %previewImgAssetPath); + + %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); + + %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + } } else { @@ -303,14 +309,14 @@ function AssetBrowser::deleteImageAsset(%this, %assetDef) function AssetBrowser::moveImageAsset(%this, %assetDef, %destination) { %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); - %targetModule = AssetBrowser.getModuleFromAddress(%destination); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); %newAssetPath = moveAssetFile(%assetDef, %destination); if(%newAssetPath $= "") return false; - moveAssetLooseFile(%assetDef.imageFile, %destination); + moveAssetLooseFile(%assetDef.getImagePath(), %destination); AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript index 23be49e9f..07ce53fce 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript @@ -113,14 +113,18 @@ function AssetBrowser::deleteLevelAsset(%this, %assetDef) function AssetBrowser::moveLevelAsset(%this, %assetDef, %destination) { %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); - %targetModule = AssetBrowser.getModuleFromAddress(%destination); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); %newAssetPath = moveAssetFile(%assetDef, %destination); if(%newAssetPath $= "") return false; - moveAssetLooseFile(%assetDef.LevelFile, %destination); + moveAssetLooseFile(%assetDef.getLevelPath(), %destination); + moveAssetLooseFile(%assetDef.getLevelPath(), %destination); + moveAssetLooseFile(%assetDef.getPreviewImagePath(), %destination); + moveAssetLooseFile(%assetDef.getPostFXPresetPath(), %destination); + moveAssetLooseFile(%assetDef.getDecalsPath(), %destination); AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index 27a3dc58d..debcaffd8 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript @@ -69,14 +69,14 @@ function AssetBrowser::deleteMaterialAsset(%this, %assetDef) function AssetBrowser::moveMaterialAsset(%this, %assetDef, %destination) { %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); - %targetModule = AssetBrowser.getModuleFromAddress(%destination); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); %newAssetPath = moveAssetFile(%assetDef, %destination); if(%newAssetPath $= "") return false; - moveAssetLooseFile(%assetDef.scriptPath, %destination); + moveAssetLooseFile(%assetDef.getScriptPath(), %destination); AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); @@ -424,8 +424,11 @@ function AssetBrowser::importMaterialAsset(%this, %assetItem) AssetDatabase.refreshAsset(%assetId); } -function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) -{ +function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData, %forcePreviewRegenerate) +{ + if(%forcePreviewRegenerate $= "") + %forcePreviewRegenerate = false; + %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(AssetDatabase.getAssetFilePath(%assetDef.getAssetId())))); %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/"; @@ -447,14 +450,13 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) { if(compareFileTimes(%assetDef.materialDefinitionName.getDiffuseMap(0), %previewFilePath) == 1 || compareFileTimes(%assetDef.materialDefinitionName.getFilename(), %previewFilePath) == 1) - %generatePreview = true; - + %generatePreview = true; } } %previewAssetName = %module.moduleId @ "_" @ %assetDef.assetName @ "_PreviewImage"; - if(%generatePreview) + if(%generatePreview || %forcePreviewRegenerate) { displayEditorLoadingGui("Generating Material Asset Preview..."); @@ -466,19 +468,26 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) pathCopy(%generatedFilePath, %previewFilePath); fileDelete(%generatedFilePath); - %previewAsset = new ImageAsset() + if(!AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) { - assetName = %previewAssetName; - versionId = 1; - imageFile = fileName(%previewFilePath); - }; - - %previewImgAssetPath = %previewPath @ %previewAsset.assetName @ ".asset.taml"; - %assetImportSuccessful = TAMLWrite(%previewAsset, %previewImgAssetPath); - - %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); + %previewAsset = new ImageAsset() + { + assetName = %previewAssetName; + versionId = 1; + imageFile = fileName(%previewFilePath); + }; - %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + %previewImgAssetPath = %previewPath @ %previewAsset.assetName @ ".asset.taml"; + %assetImportSuccessful = TAMLWrite(%previewAsset, %previewImgAssetPath); + + %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); + + %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + } + } + else + { + error("Failed to generate preview for material: " @ %assetDef.materialDefinitionName); } hideEditorLoadingGui(); @@ -504,11 +513,15 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) %previewData.doubleClickCommand = "AssetBrowser.selectAsset( AssetBrowser.selectedAsset );"; else %previewData.doubleClickCommand = "AssetBrowser.editAsset( "@%assetDef@" );"; + + %definitionPath = %assetDef.getScriptPath(); + if(%definitionPath $= "") + %definitionPath = %assetDef.getFilename(); %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ "\nAsset Type: Material Asset" @ "\nAsset Definition ID: " @ %assetDef @ - "\nDefinition Path: " @ %assetDef.getScriptPath(); + "\nDefinition Path: " @ %definitionPath; if(!%this.selectMode) { diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/postFX.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/postFX.tscript index 704a6ddf2..a51390370 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/postFX.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/postFX.tscript @@ -140,16 +140,16 @@ function AssetBrowser::deletePostEffectAsset(%this, %assetDef) function AssetBrowser::movePostEffectAsset(%this, %assetDef, %destination) { %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); - %targetModule = AssetBrowser.getModuleFromAddress(%destination); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); %newAssetPath = moveAssetFile(%assetDef, %destination); if(%newAssetPath $= "") return false; - moveAssetLooseFile(%assetDef.scriptPath, %destination); - moveAssetLooseFile(%assetDef.hlslShader, %destination); - moveAssetLooseFile(%assetDef.glslShader, %destination); + moveAssetLooseFile(%assetDef.getScriptPath(), %destination); + moveAssetLooseFile(%assetDef.getHLSLShaderPath(), %destination); + moveAssetLooseFile(%assetDef.getGLSLShaderPath(), %destination); AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/script.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/script.tscript index 1bf590f80..7b308b624 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/script.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/script.tscript @@ -36,7 +36,7 @@ function AssetBrowser::editScriptAsset(%this, %assetDef) { %scriptFile = %assetDef.scriptFile; - EditorOpenFileInTorsion(makeFullPath(%scriptFile), 0); + //EditorOpenFileInTorsion(makeFullPath(%scriptFile), 0); } function AssetBrowser::duplicateScriptAsset(%this, %assetDef, %targetModule) @@ -76,14 +76,14 @@ function AssetBrowser::deleteScriptAsset(%this, %assetDef) function AssetBrowser::moveScriptAsset(%this, %assetDef, %destination) { %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); - %targetModule = AssetBrowser.getModuleFromAddress(%destination); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); %newAssetPath = moveAssetFile(%assetDef, %destination); if(%newAssetPath $= "") return false; - moveAssetLooseFile(%assetDef.scriptFile, %destination); + moveAssetLooseFile(%assetDef.getScriptPath(), %destination); AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); @@ -93,7 +93,7 @@ function AssetBrowser::buildScriptAssetPreview(%this, %assetDef, %previewData) { %previewData.assetName = %assetDef.assetName; %previewData.assetPath = %assetDef.scriptFile; - %previewData.doubleClickCommand = "EditorOpenFileInTorsion( \""@%previewData.assetPath@"\", 0 );"; + //%previewData.doubleClickCommand = "EditorOpenFileInTorsion( \""@%previewData.assetPath@"\", 0 );"; if(%assetDef.isServerSide) %previewData.previewImage = "ToolsModule:serverScriptIcon_image"; @@ -109,7 +109,7 @@ function AssetBrowser::buildTScriptPreview(%this, %assetDef, %previewData) { %previewData.assetName = %assetDef.assetName; %previewData.assetPath = %assetDef.scriptFile; - %previewData.doubleClickCommand = "EditorOpenFileInTorsion( \""@%previewData.assetPath@"\", 0 );"; + //%previewData.doubleClickCommand = "EditorOpenFileInTorsion( \""@%previewData.assetPath@"\", 0 );"; if(%assetDef.isServerSide) %previewData.previewImage = "ToolsModule:serverScriptIcon_image"; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript index 15c48079b..250e7c6ac 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript @@ -46,6 +46,23 @@ function AssetBrowser::deleteShapeAsset(%this, %assetDef) } +function AssetBrowser::moveShapeAsset(%this, %assetDef, %destination) +{ + %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); + + %newAssetPath = moveAssetFile(%assetDef, %destination); + + if(%newAssetPath $= "") + return false; + + moveAssetLooseFile(%assetDef.getShapePath(), %destination); + moveAssetLooseFile(%assetDef.getShapeConstructorFilePath(), %destination); + + AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); + AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); +} + function AssetBrowser::prepareImportShapeAsset(%this, %assetItem) { ImportActivityLog.add("Preparing Shape for Import: " @ %assetItem.assetName); @@ -246,9 +263,12 @@ function AssetBrowser::importShapeAsset(%this, %assetItem) AssetDatabase.refreshAsset(%assetId); } -function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData) +function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData, %forcePreviewRegenerate) { - %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(%assetDef.getShapeFile()))); + if(%forcePreviewRegenerate $= "") + %forcePreviewRegenerate = false; + + %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(%assetDef.getShapePath()))); %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/"; if(!IsDirectory(%previewPath)) @@ -259,14 +279,14 @@ function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData) %generatePreview = false; %previewFilePath = %previewPath @ %assetDef.assetName @ "_Preview.dds"; - if(!isFile(%previewFilePath) || (compareFileTimes(%assetDef.getShapeFile(), %previewFilePath) == 1)) + if(!isFile(%previewFilePath) || (compareFileTimes(%assetDef.getShapePath(), %previewFilePath) == 1)) { %generatePreview = true; } %previewAssetName = %module.moduleId @ "_" @ %assetDef.assetName @ "_PreviewImage"; - if(%generatePreview) + if(%generatePreview || %forcePreviewRegenerate) { displayEditorLoadingGui("Generating Shape Asset Preview..."); @@ -278,19 +298,22 @@ function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData) pathCopy(%filePath, %previewFilePath); fileDelete(%filePath); //cleanup - %previewAsset = new ImageAsset() + if(!AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) { - assetName = %previewAssetName; - versionId = 1; - imageFile = fileName(%previewFilePath); - }; - - %previewImgAssetPath = %previewPath @ %previewAsset.assetName @ ".asset.taml"; - %assetImportSuccessful = TAMLWrite(%previewAsset, %previewImgAssetPath); - - %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); + %previewAsset = new ImageAsset() + { + assetName = %previewAssetName; + versionId = 1; + imageFile = fileName(%previewFilePath); + }; - %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + %previewImgAssetPath = %previewPath @ %previewAsset.assetName @ ".asset.taml"; + %assetImportSuccessful = TAMLWrite(%previewAsset, %previewImgAssetPath); + + %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); + + %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + } hideEditorLoadingGui(); } @@ -313,7 +336,7 @@ function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData) %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ "\n" @ "Asset Type: Shape Asset\n" @ "Asset Definition ID: " @ %assetDef @ "\n" @ - "Shape File path: " @ %assetDef.getShapeFile(); + "Shape File path: " @ %assetDef.getShapePath(); if(%this.selectMode) { diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shapeAnimation.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shapeAnimation.tscript index 5e43c126e..bb76e40d0 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shapeAnimation.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shapeAnimation.tscript @@ -31,6 +31,22 @@ function AssetBrowser::editShapeAnimationAsset(%this, %assetDef) ShapeEditorPlugin.openShapeAsset(%assetDef); } +function AssetBrowser::moveShapeAnimationAsset(%this, %assetDef, %destination) +{ + %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); + + %newAssetPath = moveAssetFile(%assetDef, %destination); + + if(%newAssetPath $= "") + return false; + + moveAssetLooseFile(%assetDef.getAnimationPath(), %destination); + + AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); + AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); +} + function AssetBrowser::buildShapeAnimationAssetPreview(%this, %assetDef, %previewData) { %previewData.assetName = %assetDef.animationName; @@ -51,5 +67,5 @@ function AssetBrowser::buildShapeAnimationAssetPreview(%this, %assetDef, %previe %previewData.assetFriendlyName = %assetDef.assetName; %previewData.assetDesc = %assetDef.description; - %previewData.tooltip = %assetDef.friendlyName @ "\n" @ %assetDef @ "\nShape File path: " @ %assetDef.getShapeFile(); + %previewData.tooltip = %assetDef.friendlyName @ "\n" @ %assetDef @ "\nShape File path: " @ %assetDef.getShapePath(); } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.tscript index 8cc63bdf4..1730e5882 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.tscript @@ -11,6 +11,22 @@ function AssetBrowser::onSoundAssetChanged(%this, %assetDef) sfxStop($PreviewSoundSource); } +function AssetBrowser::moveSoundAsset(%this, %assetDef, %destination) +{ + %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); + + %newAssetPath = moveAssetFile(%assetDef, %destination); + + if(%newAssetPath $= "") + return false; + + moveAssetLooseFile(%assetDef.getSoundPath(), %destination); + + AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); + AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); +} + function AssetBrowser::buildSoundAssetPreview(%this, %assetDef, %previewData) { %previewData.assetName = %assetDef.assetName; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrain.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrain.tscript index c7e8fe92e..9d5d3c5b8 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrain.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrain.tscript @@ -161,6 +161,22 @@ function AssetBrowser::deleteTerrainAsset(%this, %assetDef) { } +function AssetBrowser::moveTerrainAsset(%this, %assetDef, %destination) +{ + %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); + + %newAssetPath = moveAssetFile(%assetDef, %destination); + + if(%newAssetPath $= "") + return false; + + moveAssetLooseFile(%assetDef.getTerrainFilePath(), %destination); + + AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); + AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); +} + function AssetBrowser::buildTerrainAssetPreview(%this, %assetDef, %previewData) { %previewData.assetName = %assetDef.assetName; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript index 8df0a1fa3..8176d0da0 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript @@ -93,8 +93,27 @@ function AssetBrowser::deleteTerrainMaterialAsset(%this, %assetDef) { } -function AssetBrowser::buildTerrainMaterialAssetPreview(%this, %assetDef, %previewData) +function AssetBrowser::moveTerrainMaterialAsset(%this, %assetDef, %destination) { + %currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId()); + %targetModule = AssetBrowser.dirHandler.getModuleFromAddress(%destination); + + %newAssetPath = moveAssetFile(%assetDef, %destination); + + if(%newAssetPath $= "") + return false; + + moveAssetLooseFile(%assetDef.getScriptPath(), %destination); + + AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); + AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); +} + +function AssetBrowser::buildTerrainMaterialAssetPreview(%this, %assetDef, %previewData, %forcePreviewRegenerate) +{ + if(%forcePreviewRegenerate $= "") + %forcePreviewRegenerate = false; + %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(AssetDatabase.getAssetFilePath(%assetDef.getAssetId())))); %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/"; @@ -122,31 +141,35 @@ function AssetBrowser::buildTerrainMaterialAssetPreview(%this, %assetDef, %previ %previewAssetName = %module.moduleId @ "_" @ %assetDef.assetName @ "_PreviewImage"; - if(%generatePreview) + if(%generatePreview || %forcePreviewRegenerate) { displayEditorLoadingGui("Generating Material Asset Preview..."); if(isObject(%assetDef.materialDefinitionName)) { %previewShapeDef = AssetDatabase.acquireAsset("ToolsModule:previewSphereShape"); - %generatedFilePath = %previewShapeDef.generateCachedPreviewImage(256, %assetDef.materialDefinitionName); + %generatedFilePath = %previewShapeDef.generateCachedPreviewImage(256, DummyTerrMatPreview); pathCopy(%generatedFilePath, %previewFilePath); fileDelete(%generatedFilePath); - %previewAsset = new ImageAsset() + + if(!AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) { - assetName = %previewAssetName; - versionId = 1; - imageFile = fileName(%previewFilePath); - }; - - %previewImgAssetPath = %previewPath @ %previewAsset.assetName @ ".asset.taml"; - %assetImportSuccessful = TAMLWrite(%previewAsset, %previewImgAssetPath); - - %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); + %previewAsset = new ImageAsset() + { + assetName = %previewAssetName; + versionId = 1; + imageFile = fileName(%previewFilePath); + }; - %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + %previewImgAssetPath = %previewPath @ %previewAsset.assetName @ ".asset.taml"; + %assetImportSuccessful = TAMLWrite(%previewAsset, %previewImgAssetPath); + + %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); + + %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + } } hideEditorLoadingGui(); @@ -170,10 +193,14 @@ function AssetBrowser::buildTerrainMaterialAssetPreview(%this, %assetDef, %previ %previewData.assetDesc = %assetDef.description; %previewData.tooltip = %assetDef.gameObjectName; + %definitionPath = %assetDef.getScriptPath(); + if(%definitionPath $= "") + %definitionPath = %assetDef.getFilename(); + %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ "\nAsset Type: Terrain Material Asset" @ "\nAsset Definition ID: " @ %assetDef @ - "\nDefinition Path: " @ %assetDef.getScriptPath(); + "\nDefinition Path: " @ %definitionPath; } function GuiInspectorTypeTerrainMaterialAssetPtr::onClick( %this, %fieldName ) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript index 2d088f27a..6267462ee 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript @@ -111,7 +111,19 @@ function AssetBrowser::refreshAsset(%this, %assetId) } //------------------------------------------------------------ +function AssetBrowser::regeneratePreviewImage(%this) +{ + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %dummyObj = new ScriptObject(); + %regenCommand = "AssetBrowser.build" @ EditAssetPopup.assetType @ + "Preview(" @%assetDef @ "," @ %dummyObj @ ", true);"; + eval(%regenCommand); + %dummyObj.delete(); + AssetDatabase.releaseAsset(EditAssetPopup.assetId); +} + +//------------------------------------------------------------ function AssetBrowser::renameAsset(%this) { //Find out what type it is diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript index c402456cd..e3a813862 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript @@ -139,6 +139,19 @@ function newAssetUpdatePath(%newPath) NewAssetTargetModule.text = AssetBrowser.dirHandler.getModuleFromAddress(AssetBrowser.dirHandler.currentAddress).ModuleId; } +// +function NewAssetTargetModule::onSelect(%this, %idx, %idy) +{ + %newModuleName = %this.getText(); + + %currentTargetPath = NewAssetTargetAddress.getText(); + if(!startsWith(%currentTargetPath, "data/" @ %newModuleName @ "/")) + { + NewAssetTargetAddress.setText("data/" @ %newModuleName @ "/"); + } +} + +// //We do a quick validation that mandatory fields are filled in before passing along to the asset-type specific function function CreateNewAsset() { @@ -172,9 +185,41 @@ function CreateNewAsset() return; } + //First, we need to make sure we're not creating a conflicting asset + if(AssetDatabase.isDeclaredAsset(%moduleName @ ":" @ %assetName)) + { + toolsMessageBoxOK( "Error", "An asset with the ID: " @ %moduleName @ ":" @ %assetName + @ " already exists! Please review and rename."); + return; + } + + %assetType = AssetBrowser.newAssetSettings.assetType; + + if(%assetType $= "MaterialAsset" || %assetType $= "TerrainMaterialAsset" || + %assetType $= "GUIAsset") + { + if(isObject(%assetName)) + { + toolsMessageBoxOK( "Error", "Attempted to create a new asset that requires " @ + "a unique name, as the object definition must be unique. " @ + "Please use a new name."); + return; + } + } + + %currentTargetPath = NewAssetTargetAddress.getText(); + %modulePath = makeRelativePath(ModuleDatabase.findModule(%moduleName).ModulePath); + + if(!startsWith(%currentTargetPath, %modulePath)) + { + toolsMessageBoxOK( "Error", "Attempting to create a new asset in an invalid path. " @ + "Please set the target path to be within the target module folder."); + return; + } + + AssetBrowser.newAssetSettings.moduleName = %moduleName; - %assetType = AssetBrowser.newAssetSettings.assetType; if(%assetType $= "") { toolsMessageBoxOK( "Error", "Attempted to make a new asset with no type!"); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript index 3294387b0..c4f0cca7b 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript @@ -28,11 +28,13 @@ function AssetBrowser::buildPopupMenus(%this) item[ 2 ] = "Reload Asset" TAB "" TAB "AssetBrowser.refreshAsset();"; item[ 3 ] = "Asset Properties" TAB "" TAB "AssetBrowser.editAssetInfo();"; item[ 4 ] = "-"; - Item[ 5 ] = "Duplicate Asset" TAB "" TAB "AssetBrowser.duplicateAsset();"; + item[ 5 ] = "Duplicate Asset" TAB "" TAB "AssetBrowser.duplicateAsset();"; item[ 6 ] = "-"; - item[ 7 ] = "Re-Import Asset" TAB "" TAB "AssetBrowser.reImportAsset();"; + item[ 7 ] = "Regenerate Preview Image" TAB "" TAB "AssetBrowser.regeneratePreviewImage();"; item[ 8 ] = "-"; - item[ 9 ] = "Delete Asset" TAB "" TAB "AssetBrowser.deleteAsset();"; + item[ 9 ] = "Re-Import Asset" TAB "" TAB "AssetBrowser.reImportAsset();"; + item[ 10 ] = "-"; + item[ 11 ] = "Delete Asset" TAB "" TAB "AssetBrowser.deleteAsset();"; jumpFileName = ""; jumpLineNumber = ""; @@ -182,7 +184,7 @@ function AssetBrowser::buildPopupMenus(%this) item[9] = "-"; item[10] = "Create New Module" TAB "" TAB "AssetBrowser.CreateNewModule();"; item[11] = "-"; - item[12] = "Import Loose Files" TAB "" TAB "AssetBrowser.importLooseFiles();"; + item[12] = "View Loose Files" TAB "" TAB "AssetBrowser.importLooseFiles();"; }; } diff --git a/Templates/BaseGame/game/tools/forestEditor/forestEditToolbar.ed.gui b/Templates/BaseGame/game/tools/forestEditor/forestEditToolbar.ed.gui index 5590f016e..d5e204bcb 100644 --- a/Templates/BaseGame/game/tools/forestEditor/forestEditToolbar.ed.gui +++ b/Templates/BaseGame/game/tools/forestEditor/forestEditToolbar.ed.gui @@ -110,7 +110,7 @@ $guiContent = new GuiControl(ForestEditToolbar,EditorGuiGroup) { MinExtent = "8 16"; canSave = "1"; Visible = "1"; - AltCommand = "ForestTools->BrushTool.size = $ThisControl.getValue();"; + AltCommand = "ForestTools->BrushTool.size = mClamp($ThisControl.getValue(), 1, getWord(ETerrainEditor.maxBrushSize, 0));"; validate = "ForestEditorGui.validateBrushSize();"; tooltipprofile = "ToolsGuiToolTipProfile"; hovertime = "1000"; diff --git a/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.tscript b/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.tscript index dd88668a1..d039d1c86 100644 --- a/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.tscript +++ b/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.tscript @@ -220,7 +220,7 @@ function selectNewForestMesh(%selectedShapeAssetId) //%str = "datablock TSForestItemData( " @ %name @ " ) { shapeFile = \"" @ %fullPath @ "\"; };"; //eval( %str ); - //%fullPath = AssetDatabase.acquireAsset(%selectedShapeAssetId).getShapeFile(); + //%fullPath = AssetDatabase.acquireAsset(%selectedShapeAssetId).getShapePath(); new TSForestItemData(%name) { shapeAsset = %selectedShapeAssetId; diff --git a/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript b/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript index 848a625aa..52f7ff309 100644 --- a/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript +++ b/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript @@ -300,7 +300,7 @@ function ESettingsWindow::getGeneralSettings(%this) SettingsInspector.endGroup(); SettingsInspector.startGroup("Paths"); - SettingsInspector.addSettingsField("WorldEditor/torsionPath", "Torsion Path", "filename", ""); + //SettingsInspector.addSettingsField("WorldEditor/torsionPath", "Torsion Path", "filename", ""); SettingsInspector.endGroup(); SettingsInspector.startGroup("Theme"); diff --git a/Templates/BaseGame/game/tools/gui/images/tab_border.png b/Templates/BaseGame/game/tools/gui/images/tab_border.png index 59703d1597d3a95f5d064787822094ae20b5b790..3261e6d8bfbd95acccd804b0c13fae51f14dd435 100644 GIT binary patch literal 8877 zcmeHLXEfZ~*H)uNjS?bEh#6 zy%Qn21R+}9A-VT|?|T1V?pp8r?ar)UIs5GW?7g3}&so27!gaM(X{kA=iHL}3)zy^s z3D2u17v&kkz4c9}IT6vhGk%69czvWdzzyeWhjB&&@V;(n0NMv*M?~Z^Hko3I`wWN= zo;F1Q6}n3~+rp+4fQ^l0ll?U!wa0#69Hg8rd8r<9YNwGEw*5TZHT>CXd{$g=5k(EV ze-HTBQaqS`X~Y_RG!$yyIQ&>}QRZl@cwOSGR${^Aom@BBJ5Iy9bl-C}JLNnR#(c9H zraIPFr3Sx2 zt$6KVh3$J)S5qFoIr1AVu4sJKrGNCXL*(hRZl_xjH7?;(6+k(U@6h4YCkS_9qfih1 zs^^6|(#GtHA==daEsQ_D;u(j%7o=tfX^p?AN?o1SvUdRu4`_Q^ZV#X=Q?OxQx^=I7 zYfiFTb<`A3c1|8)DEL~G7cM@IJ*R?wx7wRrE96I;5}P~Z5FS^%pqI6z8EJj^-Tdf# zFbq*;#=TU0Z62bM5PjYT_M-=7qWs?Ad4S;F_oHJzuS%1?$V5J6NJLR>WSBIuzslM-l@jxy&GbU476bw< zQLg6_o9Zicpy<9_>|Dw?Zfg!o^x*m#E;6gsYQ9mo+pPNR_IJLKnIQU0Zvp8hnbFz^ zZlx%2E9dpHPQGV~5rR3X8seiQ$+DrG9$m1T`Fe5bp3`@&;I8F zwi_Sw2D{4=q|a~M$P#NaXEU358`%R&($hwL6}Zxr5k0c1HU{HOJeP8Dl!0Xmkj<9j zDa`sN2JqQoGPB3ffy7oX<_LZI>)W&e z#>O>IdB4q+@@c!-$6#NiI4<064SXF}oxn(I;4JuK&acRbpFtpc$@1x7I}GGaW_?^58)7IYb5ymgF+XSOo$W8NuvE%<=WJPLzWWHgykC?Dbd`M#jM~`@n{aGi zuAHkaQk-*!JCA51KRx=oh#=xg4(xBJiUv+8&q78L5lgR%c4>JX0V_=CmN&AIMJDcqd*3l zZil7*8Vi?UmjN>SO?3(2_H&bq8oWa|>n_=r$f2~Oc~-SK)ZC5n=X83>78{OAm}|;? zDfLm=-t=X{);}J+ez4Cbds!s=IG8@1=D7sA?k+XZQuBv8eSvyHR`y^_6nzgJ-Ke(^ zF-=2y_zdYi*$k?e-&X~14H@^%Mt|&JFfZ`4v!1o$CD~z-9%a>gcUdaiI$D9^T3Re& zMzn7}h?*K>?2v2AwrG>QYATWf_X~8G?cQW8BMotU$*UMU)H_t?9gjWZ*N!P7okLMB zgt3yXN9Wn>D#Z4Z%DVtNVgnp?*xBC+p^{lWdUBNLc|-veyWcv+TwfWyXV1WnTPTjB z&wm~2(bv!vt2~Mgv=+)aCf|&__u>xmAq2St4E*^M-&Y~T{vtdq% zwTdwx4WCl>A=hIpq<0Zyt#2y1qG+mHb8y$nBXmg$7`*qm;9GTk#hGmPYZJS5g$qso z)*2Vs$vM`%d=g$ZCw2uE25X;Z;Th)%Fr?1hlvJqUIS#DNn5a2BiQp}@I$SmLk8%QuLC)ViHiryE*q&zu2&z4FxS zdQC!N*+Cr5{Q*8OD2(L6gQ!at`AYYCgzsWLXyko-(z^RP+IXp2imV_rnFP(3Ct!0B zwvt?yJA-~YzqU-Jxf<5wcAL>4!u*@JbWP2q()ReI(t2d}x3_?hA{c^?N zJb~fd2|H_rlBtQDvB9Mj*CX{l`FfQ*Njfd%?K9fy0<0R9eBC*K@VtnKMYUe$ZEui; zsFZDGAJQq3I#033gxV!jSM3a!8QcEtx)ffrw7ULr5ZYAONoZz*)o?Fci><}Le1{#`*ORYVi`2t*Fc1oO=9y7E{|asDKdAGP#X- zj1Y5m);ojo3uSdP5jBvbHsQh)E%*R?Y`c$yyo=O(S0zG@=c%4`K*S(Zc-a72D{G{MPn3Q z(v!y4+&-kq+?i4Pq}_Gt-QIK=4SsJ$Ck_Quo_3zSmk&%YAJ`+t%i6>wtN`=Bk-)ea zmhQqP8na@?O3UTjvm7Xg(jB5N?aVy<$XwXkeDl)tmVt^8M&UA!A$h$(z8`@x0*0c} z)I+V^o}z~R{af<)iPj_L1Ff|##oJx0q3dvjVC{P zKpG44{uZ(*^U(&;EgVTtcYb7cF(>Ps(7@>J^BOX-pWkp4YX ztb0Vo&!}CjYI4Lz7X@3o#@x9rnrh7YK#f^3UCx~|NT_t?%>6j2pq{lrhgu$AZ(5PE4;6V!nv*D&>^tO~Hg~+eU}m zEbd9?+%!niXF!ck(F~M~X!^3q6G6Z%f}UR;#J0EjO9I@9cSOAprpVhCMwxt^WcbyW z_N(IZj+v+BqNR5@{O)l3E=$zxiF_MqHQ@sc_rtNwUqx0N0rpi(K^I-I$CN-Z?zE{; zDwakL_(&6giHnyd7q-m85&mqDH2l;vG#%$oHWC~pvTI~YPXe2^e2v<(W(~fY%H6m$lv!jEs-hYm zM-(R%yRN99THnFHEL3LOLj(BIeyixphvAHG=iSSz7VN?1vV!Uz$|Wt4-DWj?<&Lu< zw7s0JF3bI4=k&q;rrfj_>A8G8OD{H6y}C_x!55ff%i?C_J|FY-xmx#TR)v_Pg0m`I z?p<8$%1T+k8HF>V{(`#n!k}6icG7u&WW@@lKOCtk*`IsN7D+<~9K3WB=*||I)@BxN zQfT3jr#fyx4UfWZs?4RTHdZ^Gk$kL4rc-APvMG$=ecD1=digk#%BNF5?rir2dP@bm z?_f~S-yB3-u9K*~gVfC31=(vF-Eb^QL$vxNSS~eTuge?>RGO|D%lXxh4RBq`PU}9` zGMS|F$|AC=eQ#nVMrg;((~@F%C3DUoP^R_qKF3WQ!?H)1%zB!FS6kA))`L#JnPJd) z(K5Wx%Go0%xvsSGwdOvDqu!(0|LY3sKq_2-{R;iBd;F72WrO1H|hAm zTZnxB*9T0FOh=9M(D2?W-Rt&!vO#Mf#NRi2U3Bc@psH-7tDrdhA_bG*l~pb_-(pel z?uO6XOIrd?@j=^lSNN!s>6374WliMjy<^&y5`JpgeJv`!Y0N2RSSE zG*?~DcaYK1J{oEA5@Ma5uwyKB;T38L|F-f}<4e3o2iNu0g;$q6CDUULbj!>-zN5~aLB8PUAKYiP&&$2mS^WP?t*9Ol;RC<$;s-xJ_3=QM8G4LsX5 zvbRDvXz3tBrDWP9h}PwsAED@2B_qW$v-89J(R%ZHbvEfDsfuKp8*`TH3mwPH?J;%k z0beY%sBvS_4?}V6#RVl4>Whix`y@M7F}$71`Cfr*vt`=y?hlx!#nt%8+>_u%&CB#K9;!Xb9RNc(;bFS8y`ti7T-6_>4@V)cM#U= z(=#925Sov>-j?sC35OI=v$^vi5e64-0x3a{dl9haep7F zQTC<5lqA!zm%zk;LYf1sp)G4|+mc4+_nzIqty+{=KlBSZ??&pkFQpbvCy{H`3CbUJi-2B*keE4d-NOuQ$SjOOmv^~5)1O%FqvS6U94^Dr6p4vpZryNQ%e&= zlUF)CzNr@I`L#!?5#zqu)rhoC-p$R3FByugXKoZR4=7clC_m5T-D@wq+Mume=ojEz zx6;R1|K8E!^(_Vwi*iWQ`|bibTVYiETWVm<7bhUXe_4xthO$q3>ej<^$Bl80eBzLVA~+c?DHRH|rD@Ac z8u5%ydtlUgwv645f_-!!@cdka>4&}>z1IIpzQ2S4aY?a(0E&Q-W`p+_#Ntfu`11~ zHrKsGd2cItcT#WXt6H0@m+Dl`nX>mOIUis~w@QV*L=5728n98#JL zG)iV%A}n8Q{LuNpkkiKtuH+K-u|{xu+IbK;Y5Ip+VEpjahf@V=-(rC)!L*Rlxaz5< zf#Hpg3ye#;-~hyGv2iDl!K>+7C$E=2uoa2UpU(suBIQ6bK5ikD^6ni=t!XW$$1OrH zQsGqd&mHJTKaJYoE+Vpc*y797&E!(uDW{TO@W`{}gMu{~JVb2e4#=%9_f0j-)9=xw zY`lRrnsw*#l9T=QnAWah4rRmddwG+gdg#fs6xmi4^PlS3;y!0PF^RZ+cQulFAJh@l zv%H_PNRBJ89$kdv~_-(f%Y&nf-*Rj3b z=nm{=dUU)8)nL->e8QW2TpE`X=WxJM1JU%?>4!EBl(No zMHZS*GM@Pvmz=4mcdMFp@83$aY8=t+nek^8`b9=^qtkj=cmY2$i1OM`BlCh?Rf4-#dF5HQpYN@%T8pL0;xQ*2ODq9)o(AV ztY81+5X2@n##NpHuV8cD{?x2fsS}V1{$V`yliaC))$U^NcmNR*aWF5mgJ z!Z}!~f1H%s8(rp*pSi*jhMcQ_%m*28QwD2E4VK8885JyMo}lU_nq=r@L6Mjsr{?B% zo5AK*Q)3Ea1%}&!l5m({javBPm0(sd*XxPcpJ_iAr#y%=^pG#u&r=xoK=i*RCG`|V zSe8&Wg#tpr!e9fPY&Ox&!jfCdIW>{rgf<%F3XD5b&TfXk_0W_Mnxmb2qIG?-PKVQu zPyLcCKbPp2ptrFWk1Yc}S>R1(o*;SSllke+MYhr;xaxDV5cOp{XG;uXPwJ)3cEUio2>zQXbEyDwcNbclY6y5&?J4W0oVsQc9yAz}g> zTxRBKiaKvKeWn9#W?v7PR|_yx%pj_J)-Uln@Yp=vzUQg=3TGa@e287;ZBkB7k}O1* z)vk}X_u|Cy8m4E10-uJ!Qg+49KAQcL^5 z2>>o=JQCpJ;*9lx`^fN|;=&2PxMZ85tTyge5FboC*f*?Q$M3|rWBYlLi z9=sy@{)ESR{APi`2ha!U1_XRP&gTAWZ|k8yE3wIY!HH%&ao?muMxEw+=M({%nC2*LbM+`no6 zk^8AKK}$;uuI!5PJPA)-S%&AtKit+8g|UU7zKWx5Q4&xav@i&SvJ-}iBay`sw ztt1ixLyOr!U@+0YK&fLr@JK8QeF8-Q7r_v4By6Ej7!+nBjFbS`2t#d9AYn-)6e27p zhJt{Q;xHr%W&0Nh9UO*Gl}P8mMs)&Zdjcg66&Dqg5EVv)#l(f7wh|HqCt#eJzVYZ-bfr;!Jd#QAsa#oon`|N_)VtZ z-}Sv6&?iiR2=f~R6$XI~K_Iv&2o4qF0sc-FcrvH|$W|Kozxa?oRrt#yK(PBIBP=e2 zwF>y>V)dJ^6AJ$yf4|4!|Iq^h`d=sih~Izd`j@VM#K1pN{^ISM~O9*Auhe?U7eq%t{_k&i#cmgLA*s0EUcQ!@+nJ$v-fXzb&*{zF+Tvw&{8 x{9Te9nYF>RhF2ngw4-q^uW)WTuS=I?F9Ek>IiM+V#S+5{{yx6HuwMl delta 249 zcmZ4MI)!P1ay4nJ@ErkR#;MwT(m+AU64!{5;QX|b z^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1Shdb&7ibf!wRYH zRU0A1tguwuTzSo0rv0{z3l;OXk;vd$@?2>@P{V6p%J diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.tscript b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.tscript index 59df87bd9..f7c373ed7 100644 --- a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.tscript +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.tscript @@ -254,9 +254,13 @@ function GuiEditCanvas::onWindowClose(%this) function GuiEditCanvas::create( %this ) { - GuiEditorNewGuiDialog.init( "NewGui", "GuiControl" ); + AssetBrowser.setupCreateNewAsset("GUIAsset", AssetBrowser.selectedModule, "GuiEditCanvas.finishCreateNewGUI"); +} - Canvas.pushDialog( GuiEditorNewGuiDialog ); +function GuiEditCanvas::finishCreateNewGUI(%this, %newGUIAssetId) +{ + %assetDef = AssetDatabase.acquireAsset(%newGUIAssetId); + AssetBrowser.editAsset(%assetDef); } //--------------------------------------------------------------------------------------------- diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui b/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui index d1d46b2b1..43351bc82 100644 --- a/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui +++ b/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui @@ -4445,6 +4445,7 @@ $guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { VertSizing = "bottom"; Position = "0 95"; Extent = "212 25"; + visible = "0"; new GuiBitmapCtrl(){ position="2 2"; diff --git a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript index cf2afc7b3..cb093ea21 100644 --- a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript @@ -38,25 +38,34 @@ function MaterialEditorGui::establishMaterials(%this) }; //Material used to preview other materials in the editor. - singleton Material(materialEd_previewMaterial) + if(!isObject(materialEd_previewMaterial)) { - mapTo = "matEd_mappedMat"; - diffuseMapAsset[0] = "ToolsModule:matEd_mappedMat_image"; - }; + singleton Material(materialEd_previewMaterial) + { + mapTo = "matEd_mappedMat"; + diffuseMapAsset[0] = "ToolsModule:matEd_mappedMat_image"; + }; + } - singleton CustomMaterial( materialEd_justAlphaMaterial ) + if(!isObject(materialEd_previewMaterial)) { - mapTo = "matEd_mappedMatB"; - texture[0] = materialEd_previewMaterial.getdiffuseMap(0); - }; + singleton CustomMaterial( materialEd_justAlphaMaterial ) + { + mapTo = "matEd_mappedMatB"; + texture[0] = materialEd_previewMaterial.getdiffuseMap(0); + }; + } - //Custom shader to allow the display of just the alpha channel. - singleton ShaderData( materialEd_justAlphaShader ) + if(!isObject(materialEd_previewMaterial)) { - DXVertexShaderFile = "shaders/alphaOnlyV.hlsl"; - DXPixelShaderFile = "shaders/alphaOnlyP.hlsl"; - pixVersion = 1.0; - }; + //Custom shader to allow the display of just the alpha channel. + singleton ShaderData( materialEd_justAlphaShader ) + { + DXVertexShaderFile = "shaders/alphaOnlyV.hlsl"; + DXPixelShaderFile = "shaders/alphaOnlyP.hlsl"; + pixVersion = 1.0; + }; + } } function MaterialEditorGui::open(%this) @@ -843,6 +852,11 @@ function MaterialEditorGui::guiSync( %this, %material ) MaterialEditorPropertiesWindow-->isSRGBCheckbox.setValue((%material).isSRGB[%layer]); MaterialEditorPropertiesWindow-->invertRoughnessCheckbox.setValue((%material).invertRoughness[%layer]); } + else + { + MaterialEditorPropertiesWindow-->RoughnessSlider.setValue((%material).roughness, true); + MaterialEditorPropertiesWindow-->MetalnessSlider.setValue((%material).metalness, true); + } MaterialEditorPropertiesWindow-->isSRGBCheckbox.setVisible(%hasOrmMap); MaterialEditorPropertiesWindow-->invertRoughnessCheckbox.setVisible(%hasOrmMap); diff --git a/Templates/BaseGame/game/tools/resources/ReflectProbePreviewMat.asset.taml b/Templates/BaseGame/game/tools/resources/ReflectProbePreviewMat.asset.taml index e136ff6b4..746181b76 100644 --- a/Templates/BaseGame/game/tools/resources/ReflectProbePreviewMat.asset.taml +++ b/Templates/BaseGame/game/tools/resources/ReflectProbePreviewMat.asset.taml @@ -9,7 +9,7 @@ mapTo="ReflectProbePreviewMat"> diff --git a/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdAdvancedWindow.ed.gui b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdAdvancedWindow.ed.gui index 5ea1e4072..c98aa777f 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdAdvancedWindow.ed.gui +++ b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdAdvancedWindow.ed.gui @@ -164,6 +164,7 @@ $guiContent = new GuiWindowCollapseCtrl(ShapeEdAdvancedWindow, EditorGuiGroup) { hovertime = "500"; isContainer = true; internalName = "levelsInactive"; + color = "128 128 128 255"; }; new GuiTextCtrl() { text = "0"; @@ -691,6 +692,7 @@ $guiContent = new GuiWindowCollapseCtrl(ShapeEdAdvancedWindow, EditorGuiGroup) { }; new GuiBitmapCtrl(){ bitmapAsset = "ToolsModule:inactive_overlay_image"; + color = "128 128 128 255"; position = "4 18"; Extent = "193 64"; tooltip = "Imposters must be enabled, and an imposter detail level selected to edit these properties"; diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript index f7181fd69..2be4dd630 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript @@ -1784,7 +1784,7 @@ function ShapeEdSeqFromMenu::onBrowseSelect( %this, %assetId ) %this.setText( %assetId ); %assetDef = AssetDatabase.acquireAsset(%assetId); - %shapePath = %assetDef.getShapeFile(); + %shapePath = %assetDef.getShapePath(); AssetDatabase.releaseAsset(%assetId); ShapeEdSequences.onEditSequenceSource( %shapePath ); @@ -3010,7 +3010,7 @@ function ShapeEditor::autoAddDetails( %this, %dest ) // Determine the base name of the input file (MyShape_LOD in the example above) // and use that to find any other shapes in the set. %assetDef = AssetDatabase.acquireAsset(%dest.baseShapeAsset); - %shapeFile = %assetDef.getShapeFile(); + %shapeFile = %assetDef.getShapePath(); AssetDatabase.releaseAsset(%dest.baseShapeAsset); %base = fileBase( %shapeFile ); @@ -3058,7 +3058,7 @@ function ShapeEditor::addLODFromFile( %this, %dest, %assetId, %size, %allowUnmat { %assetDef = AssetDatabase.acquireAsset(%assetId); %csPath = %assetDef.getShapeConstructorFilePath(); - %filename = %assetDef.getShapeFile(); + %filename = %assetDef.getShapePath(); AssetDatabase.releaseAsset(%assetId); // Get (or create) a TSShapeConstructor object for the source shape. Need to diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript index fc047c19b..6f57ffd0f 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript @@ -82,6 +82,7 @@ function ObjectCreator::setNewObjectGroup( %this, %group ) %group = %group.getID(); %this.objectGroup = %group; %itemId = EditorTree.findItemByObjectId( %group ); + if(%itemId != -1) EditorTree.markItem( %itemId ); } diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/terrainEditor.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/terrainEditor.ed.tscript index 68d03f4e8..b570d3c59 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/terrainEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/terrainEditor.ed.tscript @@ -136,7 +136,7 @@ function EPainter::updateLayers( %this, %matIndex ) VertSizing = "bottom"; position = ( %listwidth - 20 ) SPC "26"; Extent = "17 17"; - command = "EPainter.showMaterialDeleteDlg( " @ %matInternalName @ " );"; + command = "EPainter.showMaterialDeleteDlg( \"" @ %matInternalName @ "\" );"; }; }; @@ -193,7 +193,7 @@ function EPainter::showMaterialDeleteDlg( %this, %matInternalName ) { toolsMessageBoxYesNo( "Confirmation", "Really remove material '" @ %matInternalName @ "' from the terrain?", - %this @ ".removeMaterial( " @ %matInternalName @ " );", "" ); + %this @ ".removeMaterial( \"" @ %matInternalName @ "\" );", "" ); } function EPainter::removeMaterial( %this, %matInternalName ) From 5a83897edeafcb391ce58bab1187b2c50321a834 Mon Sep 17 00:00:00 2001 From: JeffR Date: Mon, 4 Apr 2022 01:41:40 -0500 Subject: [PATCH 065/145] Fixes names so assignment of ORM config map on terrain materials works properly again --- .../gui/guiTerrainMaterialDlg.ed.gui | 6 +++--- .../interfaces/terrainMaterialDlg.ed.tscript | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui index 014771aed..5a7dc5102 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui @@ -536,7 +536,7 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) { profile = "ToolsGuiDefaultProfile"; tooltipProfile = "ToolsGuiToolTipProfile"; }; - new GuiContainer(ORMMapContainer) { + new GuiContainer(ORMConfigMapContainer) { position = "6 314"; extent = "261 64"; horizSizing = "width"; @@ -576,7 +576,7 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) { profile = "ToolsGuiTextProfile"; tooltipProfile = "ToolsGuiToolTipProfile"; isContainer = "0"; - internalName = "ORMMapAssetId"; + internalName = "ORMConfigMapAssetId"; }; new GuiButtonCtrl() { text = "Edit"; @@ -584,7 +584,7 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) { extent = "40 16"; horizSizing = "left"; profile = "ToolsGuiButtonProfile"; - command = "TerrainMaterialDlg.updateTextureMap(\"OrmConfigMap\");"; + command = "TerrainMaterialDlg.updateTextureMap(\"ORMConfigMap\");"; tooltipProfile = "ToolsGuiToolTipProfile"; }; new GuiBitmapButtonCtrl() { diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript index 1eb7af85d..4a7338c24 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript @@ -262,8 +262,8 @@ function TerrainMaterialDlg::clearTextureMap(%this, %mapName) NormalMapContainer.callOnChildren("setActive", false); %this.clearTextureMap("NormalMap"); - ORMMapContainer.callOnChildren("setActive", false); - %this.clearTextureMap("ORMMap"); + ORMConfigMapContainer.callOnChildren("setActive", false); + %this.clearTextureMap("ORMConfigMap"); MacroMapContainer.callOnChildren("setActive", false); %this.clearTextureMap("MacroMap"); @@ -292,7 +292,7 @@ function TerrainMaterialDlg::changeTerrainMatMapAsset(%this) { //show the supplemental maps NormalMapContainer.callOnChildren("setActive", true); - ORMMapContainer.callOnChildren("setActive", true); + ORMConfigMapContainer.callOnChildren("setActive", true); MacroMapContainer.callOnChildren("setActive", true); } } @@ -377,13 +377,13 @@ function TerrainMaterialDlg::activateMaterialCtrls( %this, %active ) if(%this-->texDetailMap.getBitmap() $= "" || %this-->texDetailMap.getBitmap() $= $TerrainMaterialEditor::emptyMaterialImage) { NormalMapContainer.callOnChildren("setActive", false); - ORMMapContainer.callOnChildren("setActive", false); + ORMConfigMapContainer.callOnChildren("setActive", false); MacroMapContainer.callOnChildren("setActive", false); } else { NormalMapContainer.callOnChildren("setActive", true); - ORMMapContainer.callOnChildren("setActive", true); + ORMConfigMapContainer.callOnChildren("setActive", true); MacroMapContainer.callOnChildren("setActive", true); } } @@ -438,7 +438,7 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat ) // %imgPath = %mat.getORMConfigMap(); %imgPathText = %imgPath !$= "" && %imgPath !$= $TerrainMaterialEditor::emptyMaterialImage ? %mat.getORMConfigMapAsset() : "None"; - %this-->ORMMapAssetId.setText( %imgPathText ); + %this-->ORMConfigMapAssetId.setText( %imgPathText ); %this-->texORMConfigMap.setBitmap( getAssetPreviewImage(%imgPath) ); // @@ -656,7 +656,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %materialAssetId ) %newNormal = ""; //--- - %newormConfig = %this-->ORMMapAssetId.text; + %newormConfig = %this-->ORMConfigMapAssetId.text; if(%newormConfig $= "None") %newormConfig = ""; @@ -995,9 +995,9 @@ function NormalMapContainer::onControlDropped( %this, %payload, %position ) terrMatEdDragNDropMapAssignment("NormalMap", %payload); } -function ORMMapContainer::onControlDropped( %this, %payload, %position ) +function ORMConfigMapContainer::onControlDropped( %this, %payload, %position ) { - terrMatEdDragNDropMapAssignment("ORMMap", %payload); + terrMatEdDragNDropMapAssignment("ORMConfigMap", %payload); } function MacroMapContainer::onControlDropped( %this, %payload, %position ) From 6b28f1f15117333238ff4b4828f4b6a54342cf6e Mon Sep 17 00:00:00 2001 From: JeffR Date: Tue, 5 Apr 2022 00:29:58 -0500 Subject: [PATCH 066/145] Fleshes out remaining missing editor settings entries/categories Makes GUIAssets exec scripts before the gui file to allow onAdd methods to work Adds missing getForestPath and getNavmeshPath methods and updates asset move logic to utilize them --- Engine/source/T3D/assets/GUIAsset.cpp | 20 +++++++++--------- Engine/source/T3D/assets/LevelAsset.cpp | 14 +++++++++++++ .../scripts/assetTypes/level.tscript | 3 ++- .../convexEditor/convexEditorGui.tscript | 10 ++++++++- .../tools/gui/editorSettingsWindow.ed.tscript | 21 +++++++++---------- .../game/tools/meshRoadEditor/main.tscript | 2 ++ .../meshRoadEditor/meshRoadEditorGui.tscript | 18 ++++++++++++++++ .../game/tools/riverEditor/main.tscript | 2 ++ .../tools/riverEditor/riverEditorGui.tscript | 14 +++++++++++++ .../game/tools/roadEditor/main.tscript | 2 ++ .../tools/roadEditor/roadEditorGui.tscript | 14 +++++++++++++ .../worldEditor/scripts/EditorGui.ed.tscript | 2 +- .../scripts/editors/terrainEditor.ed.tscript | 14 +++++++++++++ 13 files changed, 112 insertions(+), 24 deletions(-) diff --git a/Engine/source/T3D/assets/GUIAsset.cpp b/Engine/source/T3D/assets/GUIAsset.cpp index 7c1aa1d0a..0ecff34ad 100644 --- a/Engine/source/T3D/assets/GUIAsset.cpp +++ b/Engine/source/T3D/assets/GUIAsset.cpp @@ -115,28 +115,28 @@ void GUIAsset::copyTo(SimObject* object) void GUIAsset::initializeAsset() { - mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath; - - if (Torque::FS::IsScriptFile(mGUIPath)) - Con::executeFile(mGUIPath, false, false); - mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; if (Torque::FS::IsScriptFile(mScriptPath)) Con::executeFile(mScriptPath, false, false); + + mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath; + + if (Torque::FS::IsScriptFile(mGUIPath)) + Con::executeFile(mGUIPath, false, false); } void GUIAsset::onAssetRefresh() { - mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath; - - if (Torque::FS::IsScriptFile(mGUIPath)) - Con::executeFile(mGUIPath, false, false); - mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; if (Torque::FS::IsScriptFile(mScriptPath)) Con::executeFile(mScriptPath, false, false); + + mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath; + + if (Torque::FS::IsScriptFile(mGUIPath)) + Con::executeFile(mGUIPath, false, false); } void GUIAsset::setGUIFile(const char* pScriptFile) diff --git a/Engine/source/T3D/assets/LevelAsset.cpp b/Engine/source/T3D/assets/LevelAsset.cpp index ab22c7488..f1dc398b0 100644 --- a/Engine/source/T3D/assets/LevelAsset.cpp +++ b/Engine/source/T3D/assets/LevelAsset.cpp @@ -391,6 +391,20 @@ DefineEngineMethod(LevelAsset, getDecalsPath, const char*, (), , return object->getDecalsPath(); } +DefineEngineMethod(LevelAsset, getForestPath, const char*, (), , + "Gets the full path of the asset's defined forest file.\n" + "@return The string result of the forest path") +{ + return object->getForestPath(); +} + +DefineEngineMethod(LevelAsset, getNavmeshPath, const char*, (), , + "Gets the full path of the asset's defined navmesh file.\n" + "@return The string result of the navmesh path") +{ + return object->getNavmeshPath(); +} + DefineEngineMethod(LevelAsset, loadDependencies, void, (), , "Initiates the loading of asset dependencies for this level.") { diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript index 07ce53fce..479f3cf87 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript @@ -120,11 +120,12 @@ function AssetBrowser::moveLevelAsset(%this, %assetDef, %destination) if(%newAssetPath $= "") return false; - moveAssetLooseFile(%assetDef.getLevelPath(), %destination); moveAssetLooseFile(%assetDef.getLevelPath(), %destination); moveAssetLooseFile(%assetDef.getPreviewImagePath(), %destination); moveAssetLooseFile(%assetDef.getPostFXPresetPath(), %destination); moveAssetLooseFile(%assetDef.getDecalsPath(), %destination); + moveAssetLooseFile(%assetDef.getForestPath(), %destination); + moveAssetLooseFile(%assetDef.getNavmeshPath(), %destination); AssetDatabase.removeDeclaredAsset(%assetDef.getAssetId()); AssetDatabase.addDeclaredAsset(%targetModule, %newAssetPath); diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript index 0baf0eb70..bc067c746 100644 --- a/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.tscript @@ -247,4 +247,12 @@ function ConvexEditorDefaultMaterialBtn::gotMaterialName(%this, %name) ConvexEditorOptionsWindow.activeShape.setMaterial(%name); ConvexEditorGui.updateShape(); -} \ No newline at end of file +} + +function ESettingsWindow::getConvexEditorSettings(%this) +{ + SettingsInspector.startGroup("Defaults"); + SettingsInspector.addSettingsField("ConvexEditor/MaterialName", "Default Material", "string", + "The default material when creating a convexShape"); + SettingsInspector.endGroup(); +} diff --git a/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript b/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript index 52f7ff309..e104dea65 100644 --- a/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript +++ b/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript @@ -19,12 +19,14 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- - -function ESettingsWindow::startup( %this ) +function ESettingsWindow::onAdd(%this) { new ArrayObject(EditorSettingsPageList); new ArrayObject(GameSettingsPageList); +} +function ESettingsWindow::startup( %this ) +{ %this.addEditorSettingsPage("Axis", "Axis Gizmo"); %this.addEditorSettingsPage("General", "General Settings"); %this.addEditorSettingsPage("Camera", "Camera Settings"); @@ -303,13 +305,6 @@ function ESettingsWindow::getGeneralSettings(%this) //SettingsInspector.addSettingsField("WorldEditor/torsionPath", "Torsion Path", "filename", ""); SettingsInspector.endGroup(); - SettingsInspector.startGroup("Theme"); - SettingsInspector.addSettingsField("WorldEditor/Theme/backgroundColor", "Background Color", "colorI", ""); - SettingsInspector.addSettingsField("WorldEditor/Theme/windowTitleBGColor", "Window Title Color", "colorI", ""); - SettingsInspector.addSettingsField("WorldEditor/Theme/windowTitleFontColor", "Window Title Text Color", "colorI", ""); - SettingsInspector.addSettingsField("WorldEditor/Theme/mainTextColor", "Main Text Color", "colorI", ""); - SettingsInspector.endGroup(); - SettingsInspector.startGroup("Layout"); /*SettingsInspector.addSettingsField("WorldEditor/Layout/LayoutMode", "Editor Layout Mode", "list", "This dictates which layout style the editor should use." @ "WARNING - Modern layout is highlight experimental." @ @@ -327,7 +322,7 @@ function ESettingsWindow::getCameraSettings(%this) //Based on currently loaded level(rootScene) SettingsInspector.startGroup(EditorSettings.value("WorldEditor/newLevelFile") @ " Camera"); SettingsInspector.addSettingsField("Camera/cameraMinSpeed", "Camera Speed Min", "float", ""); - SettingsInspector.addSettingsField("Camera/cameraMaxSpeed", "Camera Speed Max", "200", ""); + SettingsInspector.addSettingsField("Camera/cameraMaxSpeed", "Camera Speed Max", "float", ""); SettingsInspector.endGroup(); } @@ -365,7 +360,8 @@ function ESettingsWindow::getSceneEditorSettings(%this) SettingsInspector.startGroup("Misc"); //SettingsInspector.addSettingsField("WorldEditor/forceLoadDAE", "Force Load DAE", "bool", ""); - SettingsInspector.addSettingsField("WorldEditor/forceLoadDAE", "Force Load DAE", "bool", ""); + SettingsInspector.addSettingsField("WorldEditor/Tools/dropAtScreenCenterScalar", "Screen Center Scalar", "string", ""); + SettingsInspector.addSettingsField("WorldEditor/Tools/dropAtScreenCenterMax", "Screen Center Max", "string", ""); SettingsInspector.endGroup(); SettingsInspector.startGroup("Layout"); @@ -444,6 +440,9 @@ function ESettingsWindow::getPostFXSettings(%this) SettingsInspector.endGroup(); } +function ESettingsWindow::getObjectEditorSettings(%this) +{ +} // // COMMON GAME SETTINGS // diff --git a/Templates/BaseGame/game/tools/meshRoadEditor/main.tscript b/Templates/BaseGame/game/tools/meshRoadEditor/main.tscript index 438133bef..1ff15ebde 100644 --- a/Templates/BaseGame/game/tools/meshRoadEditor/main.tscript +++ b/Templates/BaseGame/game/tools/meshRoadEditor/main.tscript @@ -82,6 +82,8 @@ function MeshRoadEditorPlugin::onWorldEditorStartup( %this ) // Add ourselves to the Editor Settings window exec( "./meshRoadEditorSettingsTab.gui" ); //ESettingsWindow.addTabPage( EMeshRoadEditorSettingsPage ); + + ESettingsWindow.addEditorSettingsPage("MeshRoadEditor", "Mesh Road Editor"); } function MeshRoadEditorPlugin::onActivated( %this ) diff --git a/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorGui.tscript b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorGui.tscript index 0c8533875..070f7eac1 100644 --- a/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorGui.tscript +++ b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorGui.tscript @@ -211,6 +211,24 @@ function MeshRoadEditorGui::prepSelectionMode( %this ) ToolsPaletteArray-->MeshRoadEditorSelectMode.setStateOn(1); } +//------------------------------------------------------------------------------ +function ESettingsWindow::getMeshRoadEditorSettings(%this) +{ + SettingsInspector.startGroup("Defaults"); + SettingsInspector.addSettingsField("MeshRoadEditor/DefaultWidth", "Width", "string", ""); + SettingsInspector.addSettingsField("MeshRoadEditor/DefaultDepth", "Depth", "string", ""); + SettingsInspector.addSettingsField("MeshRoadEditor/DefaultNormal", "Normal", "string", ""); + + SettingsInspector.addSettingsField("MeshRoadEditor/TopMaterialName", "Top Material", "string", ""); + SettingsInspector.addSettingsField("MeshRoadEditor/BottomMaterialName", "Bottom Material", "string", ""); + SettingsInspector.addSettingsField("MeshRoadEditor/SideMaterialName", "Side Material", "string", ""); + SettingsInspector.endGroup(); + + SettingsInspector.startGroup("Colors"); + SettingsInspector.addSettingsField("MeshRoadEditor/HoverSplineColor", "Hover Spline", "colorI", ""); + SettingsInspector.addSettingsField("MeshRoadEditor/SelectedSplineColor", "Selected Spline", "colorI", ""); + SettingsInspector.endGroup(); +} //------------------------------------------------------------------------------ function EMeshRoadEditorSelectModeBtn::onClick(%this) { diff --git a/Templates/BaseGame/game/tools/riverEditor/main.tscript b/Templates/BaseGame/game/tools/riverEditor/main.tscript index b8be4ede9..3911b048c 100644 --- a/Templates/BaseGame/game/tools/riverEditor/main.tscript +++ b/Templates/BaseGame/game/tools/riverEditor/main.tscript @@ -82,6 +82,8 @@ function RiverEditorPlugin::onWorldEditorStartup( %this ) // Add ourselves to the Editor Settings window exec( "./RiverEditorSettingsTab.gui" ); //ESettingsWindow.addTabPage( ERiverEditorSettingsPage ); + + ESettingsWindow.addEditorSettingsPage("RiverEditor", "River Editor"); } function RiverEditorPlugin::onActivated( %this ) diff --git a/Templates/BaseGame/game/tools/riverEditor/riverEditorGui.tscript b/Templates/BaseGame/game/tools/riverEditor/riverEditorGui.tscript index bb0f40037..e70c02bbf 100644 --- a/Templates/BaseGame/game/tools/riverEditor/riverEditorGui.tscript +++ b/Templates/BaseGame/game/tools/riverEditor/riverEditorGui.tscript @@ -214,6 +214,20 @@ function RiverEditorGui::prepSelectionMode( %this ) ToolsPaletteArray-->RiverEditorSelectMode.setStateOn(1); } +//------------------------------------------------------------------------------ +function ESettingsWindow::getRiverEditorSettings(%this) +{ + SettingsInspector.startGroup("Defaults"); + SettingsInspector.addSettingsField("RiverEditor/DefaultWidth", "Width", "string", ""); + SettingsInspector.addSettingsField("RiverEditor/DefaultDepth", "Depth", "string", ""); + SettingsInspector.addSettingsField("RiverEditor/DefaultNormal", "Normal", "string", ""); + SettingsInspector.endGroup(); + + SettingsInspector.startGroup("Colors"); + SettingsInspector.addSettingsField("RiverEditor/HoverSplineColor", "Hover Spline", "colorI", ""); + SettingsInspector.addSettingsField("RiverEditor/SelectedSplineColor", "Selected Spline", "colorI", ""); + SettingsInspector.endGroup(); +} //------------------------------------------------------------------------------ function ERiverEditorSelectModeBtn::onClick(%this) { diff --git a/Templates/BaseGame/game/tools/roadEditor/main.tscript b/Templates/BaseGame/game/tools/roadEditor/main.tscript index 4f9e7ad7a..60a0fe538 100644 --- a/Templates/BaseGame/game/tools/roadEditor/main.tscript +++ b/Templates/BaseGame/game/tools/roadEditor/main.tscript @@ -81,6 +81,8 @@ function RoadEditorPlugin::onWorldEditorStartup( %this ) // Add ourselves to the Editor Settings window exec( "./RoadEditorSettingsTab.gui" ); //ESettingsWindow.addTabPage( ERoadEditorSettingsPage ); + + ESettingsWindow.addEditorSettingsPage("RoadEditor", "Road Editor"); } function RoadEditorPlugin::onActivated( %this ) diff --git a/Templates/BaseGame/game/tools/roadEditor/roadEditorGui.tscript b/Templates/BaseGame/game/tools/roadEditor/roadEditorGui.tscript index 115da9d5c..5861fb164 100644 --- a/Templates/BaseGame/game/tools/roadEditor/roadEditorGui.tscript +++ b/Templates/BaseGame/game/tools/roadEditor/roadEditorGui.tscript @@ -212,6 +212,20 @@ function RoadEditorGui::prepSelectionMode( %this ) %this.setMode( "RoadEditorSelectMode" ); ToolsPaletteArray-->RoadEditorSelectMode.setStateOn(1); } + +//------------------------------------------------------------------------------ +function ESettingsWindow::getRoadEditorSettings(%this) +{ + SettingsInspector.startGroup("Defaults"); + SettingsInspector.addSettingsField("RoadEditor/DefaultWidth", "Width", "string", ""); + SettingsInspector.addSettingsField("RoadEditor/MaterialName", "Material", "string", ""); + SettingsInspector.endGroup(); + + SettingsInspector.startGroup("Colors"); + SettingsInspector.addSettingsField("RoadEditor/HoverSplineColor", "Hover Spline", "colorI", ""); + SettingsInspector.addSettingsField("RoadEditor/SelectedSplineColor", "Selected Spline", "colorI", ""); + SettingsInspector.endGroup(); +} //------------------------------------------------------------------------------ function ERoadEditorSelectModeBtn::onClick(%this) { diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript index 11b3b06d4..a10c44c87 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript @@ -156,8 +156,8 @@ function EditorGui::init(%this) // Editor Settings Window if( !isObject( %this-->EditorSettingsWindow ) ) { - exec("tools/gui/EditorSettingsWindow.ed.gui"); exec("tools/gui/editorSettingsWindow.ed." @ $TorqueScriptFileExtension); + exec("tools/gui/EditorSettingsWindow.ed.gui"); // Start the standard settings tabs pages /*exec( "~/worldEditor/gui/GeneralSettingsTab.ed.gui" ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/terrainEditor.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/terrainEditor.ed.tscript index b570d3c59..4cc998f6a 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/terrainEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/terrainEditor.ed.tscript @@ -29,6 +29,8 @@ function TerrainEditor::init( %this ) %this.setBrushSize( 9, 9 ); new PersistenceManager( ETerrainPersistMan ); + + ESettingsWindow.addEditorSettingsPage("TerrainEditor", "Terrain Editor"); } /// @@ -356,6 +358,18 @@ function TerrainEditor::onMaterialUndo( %this ) EPainter.updateLayers(); } +function ESettingsWindow::getTerrainEditorSettings(%this) +{ + SettingsInspector.startGroup("Tool Values"); + SettingsInspector.addSettingsField("TerrainEditor/ActionValues/adjustHeightVal", "Raise/Lower Height", "string", + "The amount of height adjustment for raising/lowering terrain"); + SettingsInspector.addSettingsField("TerrainEditor/ActionValues/smoothFactor", "Smooth Factor", "string", + "The amount of smoothing when raising/lowering terrain"); + SettingsInspector.addSettingsField("TerrainEditor/ActionValues/noiseFactor", "Noise Factor", "string", + "The amount of noise when raising/lowering terrain"); + SettingsInspector.endGroup(); +} + //------------------------------------------------------------------------------ // Functions //------------------------------------------------------------------------------ From ed33c70a23e6dbcf08c0e2bb1c2a4ecd757b0dac Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 5 Apr 2022 18:54:09 -0500 Subject: [PATCH 067/145] display the item to be spawned given a valid datablock name, use that meshes shape to display the spawnsphere mesh, rather than the default one --- Engine/source/T3D/missionMarker.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Engine/source/T3D/missionMarker.cpp b/Engine/source/T3D/missionMarker.cpp index 005ec3491..27785d627 100644 --- a/Engine/source/T3D/missionMarker.cpp +++ b/Engine/source/T3D/missionMarker.cpp @@ -433,7 +433,23 @@ void SpawnSphere::unpackUpdate(NetConnection * con, BitStream * stream) mSpawnTransform = stream->readFlag(); stream->read(&mSpawnClass); + + String oldSDB = mSpawnDataBlock; stream->read(&mSpawnDataBlock); + if (oldSDB != mSpawnDataBlock) + { + ShapeBaseData *spawnedDatablock = dynamic_cast(Sim::findObject(mSpawnDataBlock.c_str())); + if (spawnedDatablock) + { + delete mShapeInstance; + mShapeInstance = new TSShapeInstance(spawnedDatablock->mShape); + } + else + { + delete mShapeInstance; + mShapeInstance = new TSShapeInstance(mDataBlock->mShape); + } + } stream->read(&mSpawnName); stream->read(&mSpawnProperties); stream->read(&mSpawnScript); From e1a127715e7b32c639066d714e8930bfadab68ec Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 5 Apr 2022 20:17:51 -0500 Subject: [PATCH 068/145] sanity checks --- Engine/source/T3D/missionMarker.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Engine/source/T3D/missionMarker.cpp b/Engine/source/T3D/missionMarker.cpp index 27785d627..1bd19ae68 100644 --- a/Engine/source/T3D/missionMarker.cpp +++ b/Engine/source/T3D/missionMarker.cpp @@ -438,16 +438,16 @@ void SpawnSphere::unpackUpdate(NetConnection * con, BitStream * stream) stream->read(&mSpawnDataBlock); if (oldSDB != mSpawnDataBlock) { + delete mShapeInstance; ShapeBaseData *spawnedDatablock = dynamic_cast(Sim::findObject(mSpawnDataBlock.c_str())); - if (spawnedDatablock) + if (spawnedDatablock && spawnedDatablock->mShape) { - delete mShapeInstance; - mShapeInstance = new TSShapeInstance(spawnedDatablock->mShape); + mShapeInstance = new TSShapeInstance(spawnedDatablock->mShape); } - else + else if (mDataBlock) { - delete mShapeInstance; - mShapeInstance = new TSShapeInstance(mDataBlock->mShape); + if (mDataBlock->mShape) + mShapeInstance = new TSShapeInstance(mDataBlock->mShape); } } stream->read(&mSpawnName); From 976c0bca7915623e764a050da0eb0166db09c335 Mon Sep 17 00:00:00 2001 From: JeffR Date: Wed, 6 Apr 2022 01:08:20 -0500 Subject: [PATCH 069/145] Fixed uninitialized values for renderMeshExample and renderShapeExample which would cause a crash on creation Added utility method to prefab to be able to get the internal simGroup that contains it's children Adjusted logic for mounting items in GuiShapeEdPreview to utilize assetIds for the shapes Moved the Asset and AssetBrowser editor settings populate functions to the AssetBrowser script to better organize things Fixed command usage for General, Player and Observer spawn point creator entries to use the correct callback commands Fixed logic for creator callback commands that don't just route through the class name based structure Added RMB context menu actions for opening asset file or folder locations in OS file explorer Fixed lookup of animation assets when editing a shape's animations in the shape editor so it provides the assetId of the anim if it exists Fixes handling of mounting in the shape editor so it utilizes assets and the asset browser like everything else --- .../source/T3D/examples/renderMeshExample.cpp | 1 + .../T3D/examples/renderShapeExample.cpp | 1 + Engine/source/T3D/prefab.cpp | 6 ++ Engine/source/T3D/prefab.h | 7 ++ .../source/gui/editor/guiShapeEdPreview.cpp | 20 +++-- .../assetBrowser/scripts/assetBrowser.tscript | 80 +++++++++++++++++++ .../assetBrowser/scripts/creator.tscript | 15 ++-- .../assetBrowser/scripts/editAsset.tscript | 50 ++++++++++++ .../assetBrowser/scripts/popupMenus.tscript | 29 ++++--- .../tools/gui/editorSettingsWindow.ed.tscript | 77 ------------------ .../scripts/shapeEditor.ed.tscript | 31 ++++--- .../scripts/shapeEditorActions.ed.tscript | 1 - 12 files changed, 207 insertions(+), 111 deletions(-) diff --git a/Engine/source/T3D/examples/renderMeshExample.cpp b/Engine/source/T3D/examples/renderMeshExample.cpp index fe1d099eb..343075358 100644 --- a/Engine/source/T3D/examples/renderMeshExample.cpp +++ b/Engine/source/T3D/examples/renderMeshExample.cpp @@ -60,6 +60,7 @@ RenderMeshExample::RenderMeshExample() mTypeMask |= StaticObjectType | StaticShapeObjectType; INIT_ASSET(Material); + mMaterialInst = NULL; } RenderMeshExample::~RenderMeshExample() diff --git a/Engine/source/T3D/examples/renderShapeExample.cpp b/Engine/source/T3D/examples/renderShapeExample.cpp index b8aad1ebf..a4a92d572 100644 --- a/Engine/source/T3D/examples/renderShapeExample.cpp +++ b/Engine/source/T3D/examples/renderShapeExample.cpp @@ -59,6 +59,7 @@ RenderShapeExample::RenderShapeExample() mTypeMask |= StaticObjectType | StaticShapeObjectType; // Make sure to initialize our TSShapeInstance to NULL + INIT_ASSET(Shape); mShapeInstance = NULL; } diff --git a/Engine/source/T3D/prefab.cpp b/Engine/source/T3D/prefab.cpp index 0bebb443f..a211a41e5 100644 --- a/Engine/source/T3D/prefab.cpp +++ b/Engine/source/T3D/prefab.cpp @@ -616,3 +616,9 @@ void ExplodePrefabUndoAction::redo() name = Sim::getUniqueName( name ); mGroup->assignName( name ); } + +DefineEngineMethod(Prefab, getChildGroup, S32, (),, + "") +{ + return object->getChildGroup(); +} diff --git a/Engine/source/T3D/prefab.h b/Engine/source/T3D/prefab.h index def70857e..d6cde3e69 100644 --- a/Engine/source/T3D/prefab.h +++ b/Engine/source/T3D/prefab.h @@ -102,6 +102,13 @@ public: virtual void getUtilizedAssets(Vector* usedAssetsList); + S32 getChildGroup() { + if (mChildGroup.isValid()) + return mChildGroup->getId(); + + return 0; + } + protected: void _closeFile( bool removeFileNotify ); diff --git a/Engine/source/gui/editor/guiShapeEdPreview.cpp b/Engine/source/gui/editor/guiShapeEdPreview.cpp index eba775edb..d5dc8c5bf 100644 --- a/Engine/source/gui/editor/guiShapeEdPreview.cpp +++ b/Engine/source/gui/editor/guiShapeEdPreview.cpp @@ -557,16 +557,20 @@ void GuiShapeEdPreview::refreshThreadSequences() //----------------------------------------------------------------------------- // MOUNTING -bool GuiShapeEdPreview::mountShape(const char* modelName, const char* nodeName, const char* mountType, S32 slot) +bool GuiShapeEdPreview::mountShape(const char* shapeAssetId, const char* nodeName, const char* mountType, S32 slot) { - if ( !modelName || !modelName[0] ) + if ( !shapeAssetId || !shapeAssetId[0] ) return false; - Resource model = ResourceManager::get().load( modelName ); - if ( !bool( model ) ) + if (!AssetDatabase.isDeclaredAsset(shapeAssetId)) return false; - TSShapeInstance* tsi = new TSShapeInstance( model, true ); + ShapeAsset* model = AssetDatabase.acquireAsset(shapeAssetId); + + if (model == nullptr || !model->getShapeResource()) + return false; + + TSShapeInstance* tsi = new TSShapeInstance(model->getShapeResource(), true ); if ( slot == -1 ) { @@ -1864,14 +1868,14 @@ DefineEngineMethod( GuiShapeEdPreview, refreshThreadSequences, void, (),, //----------------------------------------------------------------------------- // Mounting -DefineEngineMethod( GuiShapeEdPreview, mountShape, bool, ( const char* shapePath, const char* nodeName, const char* type, S32 slot ),, +DefineEngineMethod( GuiShapeEdPreview, mountShape, bool, ( const char* shapeAssetId, const char* nodeName, const char* type, S32 slot ),, "Mount a shape onto the main shape at the specified node\n\n" - "@param shapePath path to the shape to mount\n" + "@param shapeAssetId AssetId of the shape to mount\n" "@param nodeName name of the node on the main shape to mount to\n" "@param type type of mounting to use (Object, Image or Wheel)\n" "@param slot mount slot\n" ) { - return object->mountShape( shapePath, nodeName, type, slot ); + return object->mountShape(shapeAssetId, nodeName, type, slot ); } DefineEngineMethod( GuiShapeEdPreview, setMountNode, void, ( S32 slot, const char* nodeName ),, diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index eca3729f7..fd3a7b213 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript @@ -1212,6 +1212,86 @@ function AssetBrowser::openAssetSettings(%this) ESettingsWindowList.setSelectedRow( %assetEditIndex ); } +function ESettingsWindow::getAssetManagementSettings(%this) +{ + SettingsInspector.startGroup("Modules"); + SettingsInspector.addSettingsField("AssetManagement/Modules/coreModulePath", "Core Module Path", "string", ""); + SettingsInspector.addSettingsField("AssetManagement/Modules/gameDataModulePath", "Game Data Module Path", "string", ""); + SettingsInspector.addSettingsField("AssetManagement/Modules/moduleExtension", "Module Extension", "string", ""); + + %moduleList = ModuleDatabase.findModules(true); + %moduleList = strreplace(%moduleList, " ", ","); + + SettingsInspector.addSettingsField("AssetManagement/Modules/DefaultModule", "Default Module", "list", %moduleList); + SettingsInspector.endGroup(); + + SettingsInspector.startGroup("Assets"); + SettingsInspector.addSettingsField("AssetManagement/Assets/assetExtension", "Asset Extension", "string", ""); + SettingsInspector.addSettingsField("AssetManagement/Assets/datablockCaching", "Cache Datablocks", "bool", ""); + //SettingsInspector.addSettingsField("AssetManagement/Assets/moduleExtension", "Module Extension", "string", ""); + + SettingsInspector.endGroup(); +} + +function ESettingsWindow::getAssetEditingSettings(%this) +{ + ImportAssetWindow::reloadImportOptionConfigs(); + + //First, get our list of modules + %moduleList = ModuleDatabase.findModules(); + %formattedModuleList = ""; + + %count = getWordCount(%moduleList); + for(%i=0; %i < %count; %i++) + { + %module = getWord(%moduleList, %i); + if(%module.group !$= "Tools" && %module.group !$= "Core") + { + if(%formattedModuleList $= "") + %formattedModuleList = %module.moduleId; + else + %formattedModuleList = %formattedModuleList @ "," @ %module.moduleId; + } + } + + SettingsInspector.startGroup("Asset Creation"); + SettingsInspector.addSettingsField("Assets/New/defaultModule", "Default Module", "list", "Default Module for new assets to be created into", %formattedModuleList); + SettingsInspector.addSettingsField("Assets/New/alwaysPromptModuleTarget", "Always Prompt Target Module", "bool", "If off, use the default module"); + SettingsInspector.endGroup(); + + %formattedConfigList = ""; + for(%i=0; %i < ImportAssetWindow.importConfigsList.Count(); %i++) + { + %configName = ImportAssetWindow.importConfigsList.getKey(%i); + %formattedConfigList = %i == 0 ? %configName : %formattedConfigList @ "," @ %configName; + } + + SettingsInspector.startGroup("Assets Importing"); + SettingsInspector.addField("Edit Import Configs", "Edit Asset Import Configs", "button", "Open Asset Import Config Editor", "", "Canvas.pushDialog(AssetImportConfigEditor);"); + SettingsInspector.addSettingsField("Assets/AssetImporDefaultConfig", "Default Asset Import Config", "list", "", %formattedConfigList); + SettingsInspector.addSettingsField("Assets/AutoImport", "Automatically Import using default config", "bool", "If on, the asset importing process" @ + "will attempt to automatically import any inbound assets"@ + "using the default config, without prompting the import window."@ + "The window will still display if any issues are detected", ""); + SettingsInspector.addSettingsField("Assets/AutoImportLooseFiles", "Automatically Import Loose Files", "bool", "If on, will automatically import unassociated loose files in assets when navigating the Asset Browser.", ""); + SettingsInspector.endGroup(); + + SettingsInspector.startGroup("Asset Browser"); + SettingsInspector.addSettingsField("Assets/Browser/showCoreModule", "Show Core Module in Asset Browser", "bool", ""); + SettingsInspector.addSettingsField("Assets/Browser/showToolsModule", "Show Tools Module in Asset Browser", "bool", ""); + SettingsInspector.addSettingsField("Assets/Browser/showOnlyPopulatedModule", "Show Only Modules with Assets in Asset Browser", "bool", ""); + SettingsInspector.addSettingsField("Assets/Browser/showFolders", "Show Folders in Tiles view in Asset Browser", "bool", ""); + SettingsInspector.addSettingsField("Assets/Browser/showEmptyFolders", "Show Empty Folders in Tiles view in Asset Browser", "bool", ""); + SettingsInspector.addSettingsField("Assets/Browser/showLooseFiles", "Show Loose Files when viewing in Asset Browser", "bool", ""); + SettingsInspector.addSettingsField("AssetManagement/Assets/promptOnRename", "Prompt on Rename", "bool", ""); + SettingsInspector.addSettingsField("Assets/Browser/doubleClickAction", "Double Click Action", "list", "Dictates what sort of action double clicking on an asset in the Browser will invoke", "Edit Asset,Spawn Asset"); + SettingsInspector.addSettingsField("AssetManagement/Assets/closeBrowserOnDragAction", "Close Browser on Drag Action", "bool", "If on, the Asset Browser will automatically close after dragging an asset from it to the editor interface."); + SettingsInspector.endGroup(); +} +// +// +// + function AssetBrowser::showVisibiltyOptions(%this) { BrowserVisibilityPopup.showPopup(Canvas); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/creator.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/creator.tscript index 803a5933a..c6b279d35 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/creator.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/creator.tscript @@ -50,9 +50,9 @@ function AssetBrowser::loadCreatorClasses(%this) %this.addCreatorClass("MissionArea", "Mission Area" ); %this.addCreatorClass("NotesObject", "Note" ); %this.addCreatorClass("Path" ); - %this.addCreatorClass("SpawnSphere", "General Spawn Sphere" ); - %this.addCreatorClass("SpawnSphere", "Player Spawn Sphere"/*, "PlayerDropPoint"*/ ); - %this.addCreatorClass("SpawnSphere", "Observer Spawn Sphere"/*, "ObserverDropPoint"*/ ); + %this.addCreatorClass("SpawnSphere", "General Spawn Sphere", "GeneralDropPoint" ); + %this.addCreatorClass("SpawnSphere", "Player Spawn Sphere", "PlayerDropPoint" ); + %this.addCreatorClass("SpawnSphere", "Observer Spawn Sphere", "ObserverDropPoint" ); %this.addCreatorClass("VPath", "Verve Path" ); %this.endCreatorGroup(); @@ -168,6 +168,7 @@ function AssetBrowser::addCreatorClass(%this, %class, %name, %buildfunc) return; } + %cmd = ""; if(%buildfunc $= "") { %method = "build" @ %buildfunc; @@ -178,9 +179,13 @@ function AssetBrowser::addCreatorClass(%this, %class, %name, %buildfunc) %cmd = "new " @ %class @ "();"; else %cmd = "ObjectBuilderGui." @ %method @ "();"; - - %buildfunc = "ObjectBuilderGui.newObjectCallback = \"AssetBrowser.onFinishCreateObject\"; ObjectCreator.createObject( \"" @ %cmd @ "\" );"; } + else + { + %cmd = "ObjectBuilderGui.build" @ %buildfunc @ "();"; + } + + %buildfunc = "ObjectBuilderGui.newObjectCallback = \"AssetBrowser.onFinishCreateObject\"; ObjectCreator.createObject( \"" @ %cmd @ "\" );"; %args = new ScriptObject(); %args.val[0] = %class; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript index 6267462ee..ffa4abd3b 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript @@ -476,4 +476,54 @@ function AssetBrowser::updateAssetReference(%this, %targetPath, %oldAssetId, %ne lineCache.delete(); %fileObj.delete(); +} + +function AssetBrowser::openFileLocation(%this) +{ + %filePath = ""; + if(EditAssetPopup.assetId !$= "") + { + %filePath = AssetDatabase.getAssetPath(EditAssetPopup.assetId); + } + else if(EditLevelAssetPopup.assetId !$= "") + { + %filePath = AssetDatabase.getAssetPath(EditAssetPopup.assetId); + } + else if(EditTerrainAssetPopup.assetId !$= "") + { + %filePath = AssetDatabase.getAssetPath(EditAssetPopup.assetId); + } + + if(%filePath !$= "") + { + if($platform $= "windows") + { + %cmd = "cd \"" @ makeFullPath(%filePath) @ "\" && start ."; + systemCommand(%cmd); + } + else + { + %cmd = "open \"" @ makeFullPath(%filePath) @ "\""; + systemCommand(%cmd); + } + } +} + +function AssetBrowser::openFolderLocation(%this) +{ + %filePath = AssetBrowser.dirHandler.currentAddress; + + if(%filePath !$= "") + { + if($platform $= "windows") + { + %cmd = "cd \"" @ makeFullPath(%filePath) @ "\" && start ."; + systemCommand(%cmd); + } + else + { + %cmd = "open \"" @ makeFullPath(%filePath) @ "\""; + systemCommand(%cmd); + } + } } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript index c4f0cca7b..808649d86 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript @@ -34,7 +34,9 @@ function AssetBrowser::buildPopupMenus(%this) item[ 8 ] = "-"; item[ 9 ] = "Re-Import Asset" TAB "" TAB "AssetBrowser.reImportAsset();"; item[ 10 ] = "-"; - item[ 11 ] = "Delete Asset" TAB "" TAB "AssetBrowser.deleteAsset();"; + item[ 11 ] = "Open File Location" TAB "" TAB "AssetBrowser.openFileLocation();"; + item[ 12 ] = "-"; + item[ 13 ] = "Delete Asset" TAB "" TAB "AssetBrowser.deleteAsset();"; jumpFileName = ""; jumpLineNumber = ""; @@ -57,9 +59,9 @@ function AssetBrowser::buildPopupMenus(%this) item[ 5 ] = "-"; Item[ 6 ] = "Duplicate Asset" TAB "" TAB "AssetBrowser.duplicateAsset();"; item[ 7 ] = "-"; - //item[ 8 ] = "Re-Import Asset" TAB "" TAB "AssetBrowser.reImportAsset();"; - //item[ 9 ] = "-"; - item[ 8 ] = "Delete Asset" TAB "" TAB "AssetBrowser.deleteAsset();"; + item[ 8 ] = "Open File Location" TAB "" TAB "AssetBrowser.openFileLocation();"; + item[ 9 ] = "-"; + item[ 10 ] = "Delete Asset" TAB "" TAB "AssetBrowser.deleteAsset();"; jumpFileName = ""; jumpLineNumber = ""; @@ -80,7 +82,9 @@ function AssetBrowser::buildPopupMenus(%this) item[ 3 ] = "-"; Item[ 4 ] = "Duplicate Asset" TAB "" TAB "AssetBrowser.duplicateAsset();"; item[ 5 ] = "-"; - item[ 6 ] = "Delete Asset" TAB "" TAB "AssetBrowser.deleteAsset();"; + item[ 6 ] = "Open File Location" TAB "" TAB "AssetBrowser.openFileLocation();"; + item[ 7 ] = "-"; + item[ 8 ] = "Delete Asset" TAB "" TAB "AssetBrowser.deleteAsset();"; jumpFileName = ""; jumpLineNumber = ""; @@ -185,6 +189,9 @@ function AssetBrowser::buildPopupMenus(%this) item[10] = "Create New Module" TAB "" TAB "AssetBrowser.CreateNewModule();"; item[11] = "-"; item[12] = "View Loose Files" TAB "" TAB "AssetBrowser.importLooseFiles();"; + Item[ 13 ] = "-"; + item[ 14 ] = "Open Folder Location" TAB "" TAB "AssetBrowser.openFolderLocation();"; + }; } @@ -203,11 +210,13 @@ function AssetBrowser::buildPopupMenus(%this) Item[ 3 ] = "-"; Item[ 4 ] = "Module Properties" TAB "" TAB "AssetBrowser.editModuleInfo();"; Item[ 5 ] = "-"; - Item[ 6 ] = "Duplicate Module" TAB "" TAB "AssetBrowser.copyModule();"; - Item[ 7 ] = "-"; - Item[ 8 ] = "Delete Module" TAB "" TAB "AssetBrowser.deleteModule();"; - item[ 9 ] = "-"; - item[ 10 ] = "Import Loose Files" TAB "" TAB "AssetBrowser.importLooseFiles();"; + item[ 6 ] = "Open Folder Location" TAB "" TAB "AssetBrowser.openFolderLocation();"; + item[ 7 ] = "-"; + Item[ 8 ] = "Duplicate Module" TAB "" TAB "AssetBrowser.copyModule();"; + Item[ 9 ] = "-"; + Item[ 10 ] = "Delete Module" TAB "" TAB "AssetBrowser.deleteModule();"; + item[ 11 ] = "-"; + item[ 12 ] = "Import Loose Files" TAB "" TAB "AssetBrowser.importLooseFiles();"; }; } diff --git a/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript b/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript index e104dea65..c9b589caa 100644 --- a/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript +++ b/Templates/BaseGame/game/tools/gui/editorSettingsWindow.ed.tscript @@ -473,83 +473,6 @@ function ESettingsWindow::getUISettings(%this) SettingsInspector.endGroup(); } -function ESettingsWindow::getAssetManagementSettings(%this) -{ - SettingsInspector.startGroup("Modules"); - SettingsInspector.addSettingsField("AssetManagement/Modules/coreModulePath", "Core Module Path", "string", ""); - SettingsInspector.addSettingsField("AssetManagement/Modules/gameDataModulePath", "Game Data Module Path", "string", ""); - SettingsInspector.addSettingsField("AssetManagement/Modules/moduleExtension", "Module Extension", "string", ""); - - %moduleList = ModuleDatabase.findModules(true); - %moduleList = strreplace(%moduleList, " ", ","); - - SettingsInspector.addSettingsField("AssetManagement/Modules/DefaultModule", "Default Module", "list", %moduleList); - SettingsInspector.endGroup(); - - SettingsInspector.startGroup("Assets"); - SettingsInspector.addSettingsField("AssetManagement/Assets/assetExtension", "Asset Extension", "string", ""); - SettingsInspector.addSettingsField("AssetManagement/Assets/datablockCaching", "Cache Datablocks", "bool", ""); - //SettingsInspector.addSettingsField("AssetManagement/Assets/moduleExtension", "Module Extension", "string", ""); - - SettingsInspector.endGroup(); -} - -function ESettingsWindow::getAssetEditingSettings(%this) -{ - ImportAssetWindow::reloadImportOptionConfigs(); - - //First, get our list of modules - %moduleList = ModuleDatabase.findModules(); - %formattedModuleList = ""; - - %count = getWordCount(%moduleList); - for(%i=0; %i < %count; %i++) - { - %module = getWord(%moduleList, %i); - if(%module.group !$= "Tools" && %module.group !$= "Core") - { - if(%formattedModuleList $= "") - %formattedModuleList = %module.moduleId; - else - %formattedModuleList = %formattedModuleList @ "," @ %module.moduleId; - } - } - - SettingsInspector.startGroup("Asset Creation"); - SettingsInspector.addSettingsField("Assets/New/defaultModule", "Default Module", "list", "Default Module for new assets to be created into", %formattedModuleList); - SettingsInspector.addSettingsField("Assets/New/alwaysPromptModuleTarget", "Always Prompt Target Module", "bool", "If off, use the default module"); - SettingsInspector.endGroup(); - - %formattedConfigList = ""; - for(%i=0; %i < ImportAssetWindow.importConfigsList.Count(); %i++) - { - %configName = ImportAssetWindow.importConfigsList.getKey(%i); - %formattedConfigList = %i == 0 ? %configName : %formattedConfigList @ "," @ %configName; - } - - SettingsInspector.startGroup("Assets Importing"); - SettingsInspector.addField("Edit Import Configs", "Edit Asset Import Configs", "button", "Open Asset Import Config Editor", "", "Canvas.pushDialog(AssetImportConfigEditor);"); - SettingsInspector.addSettingsField("Assets/AssetImporDefaultConfig", "Default Asset Import Config", "list", "", %formattedConfigList); - SettingsInspector.addSettingsField("Assets/AutoImport", "Automatically Import using default config", "bool", "If on, the asset importing process" @ - "will attempt to automatically import any inbound assets"@ - "using the default config, without prompting the import window."@ - "The window will still display if any issues are detected", ""); - SettingsInspector.addSettingsField("Assets/AutoImportLooseFiles", "Automatically Import Loose Files", "bool", "If on, will automatically import unassociated loose files in assets when navigating the Asset Browser.", ""); - SettingsInspector.endGroup(); - - SettingsInspector.startGroup("Asset Browser"); - SettingsInspector.addSettingsField("Assets/Browser/showCoreModule", "Show Core Module in Asset Browser", "bool", ""); - SettingsInspector.addSettingsField("Assets/Browser/showToolsModule", "Show Tools Module in Asset Browser", "bool", ""); - SettingsInspector.addSettingsField("Assets/Browser/showOnlyPopulatedModule", "Show Only Modules with Assets in Asset Browser", "bool", ""); - SettingsInspector.addSettingsField("Assets/Browser/showFolders", "Show Folders in Tiles view in Asset Browser", "bool", ""); - SettingsInspector.addSettingsField("Assets/Browser/showEmptyFolders", "Show Empty Folders in Tiles view in Asset Browser", "bool", ""); - SettingsInspector.addSettingsField("Assets/Browser/showLooseFiles", "Show Loose Files when viewing in Asset Browser", "bool", ""); - SettingsInspector.addSettingsField("AssetManagement/Assets/promptOnRename", "Prompt on Rename", "bool", ""); - SettingsInspector.addSettingsField("Assets/Browser/doubleClickAction", "Double Click Action", "list", "Dictates what sort of action double clicking on an asset in the Browser will invoke", "Edit Asset,Spawn Asset"); - SettingsInspector.addSettingsField("AssetManagement/Assets/closeBrowserOnDragAction", "Close Browser on Drag Action", "bool", "If on, the Asset Browser will automatically close after dragging an asset from it to the editor interface."); - SettingsInspector.endGroup(); -} - function ESettingsWindow::getGameplaySettings(%this) { SettingsInspector.startGroup("Game Modes"); diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript index 2be4dd630..b53e1edaa 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript @@ -1581,8 +1581,19 @@ function ShapeEdSequences::onEditSequenceSource( %this, %from ) %from = rtrim( getFields( %oldSource, 0, 0 ) ); if ( getFields( %oldSource, 0, 3 ) !$= ( %from TAB "" TAB %start TAB %end ) ) + { + %aq = new AssetQuery(); + %foundAssets = AssetDatabase.findAssetLooseFile(%aq, %from); + if(%foundAssets != 0) + { + //if we have an assetId associated to the file, we're gunna just pass that + //through for the edit actions + %from = %aq.getAsset(0); + } + %aq.delete(); ShapeEditor.doEditSeqSource( %seqName, %from, %start, %end ); } + } } function ShapeEdSequences::onToggleCyclic( %this ) @@ -3339,8 +3350,9 @@ function ShapeEdMountShapeMenu::onSelect( %this, %id, %text ) { if ( %text $= "Browse..." ) { - // Allow the user to browse for an external model file - getLoadFormatFilename( %this @ ".onBrowseSelect", %this.lastPath ); + if(%this.lastPath !$= "") + AssetBrowser.dirHandler.currentAddress = %this.lastPath; + AssetBrowser.showDialog("ShapeAsset", %this @ ".onBrowseSelect"); } else { @@ -3349,15 +3361,14 @@ function ShapeEdMountShapeMenu::onSelect( %this, %id, %text ) } } -function ShapeEdMountShapeMenu::onBrowseSelect( %this, %path ) +function ShapeEdMountShapeMenu::onBrowseSelect( %this, %shapeAssetId ) { - %path = makeRelativePath( %path, getMainDotCSDir() ); - %this.lastPath = %path; - %this.setText( %path ); + %this.lastPath = AssetBrowser.dirHandler.currentAddress; + %this.setText( %shapeAssetId ); // Add entry if unique - if ( %this.findText( %path ) == -1 ) - %this.add( %path ); + if ( %this.findText( %shapeAssetId ) == -1 ) + %this.add( %shapeAssetId ); ShapeEdMountWindow.updateSelectedMount(); } @@ -3369,11 +3380,11 @@ function ShapeEdMountWindow::mountShape( %this, %slot ) %type = %this-->mountType.getText(); if ( %model $= "Browse..." ) - %model = "core/gameObjects/shapes/octahedron.dts"; + %model = "Core_GameObjects:octahedron.dts"; if ( ShapeEdShapeView.mountShape( %model, %node, %type, %slot ) ) { - %rowText = %model TAB fileName( %model ) TAB %node TAB %type; + %rowText = %model TAB %node TAB %type; if ( %slot == -1 ) { %id = %this.mounts++; diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.tscript b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.tscript index 55d6f9483..656871086 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.tscript +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.tscript @@ -301,7 +301,6 @@ function ActionEditNodeTransform::undo( %this ) // Add sequence function onAddAnimationAssetShapeEditor(%selectedAnimation) { - echo("SELECTED MUH ASSET"); ShapeEditor.doAddSequence(%selectedAnimation, 0, 0, 0); } From bfe3d4d02b80877115ca457ac68b125c245ddbfd Mon Sep 17 00:00:00 2001 From: JeffR Date: Thu, 7 Apr 2022 18:19:13 -0500 Subject: [PATCH 070/145] Shifts handling of forest brush and item elements into standard simsets for consistency Updates the forest editor tooling to utilize the new sets, and adjusts the creation of new Brushes in the forest editor to have user select a target module first. This ensures all a module's brushes are grouped into the new ForestBrushGroup class which auto-registers into the ForestBrushSet, thus allowing modules to have their own sets of brushes that automatically hook into the editor workflow. --- Engine/source/console/sim.cpp | 2 + Engine/source/console/sim.h | 2 + Engine/source/console/simManager.cpp | 2 + .../forest/editor/forestBrushElement.cpp | 76 ++++++++++++++++++- .../source/forest/editor/forestBrushElement.h | 25 +++++- .../source/forest/editor/forestBrushTool.cpp | 9 ++- .../source/forest/editor/forestEditorCtrl.cpp | 12 ++- .../templateFiles/module.tscript.template | 2 + .../game/tools/forestEditor/brushes.tscript | 26 ------- .../forestEditor/forestEditorGui.tscript | 66 ++++++++-------- .../game/tools/forestEditor/main.tscript | 43 +++++------ 11 files changed, 177 insertions(+), 88 deletions(-) delete mode 100644 Templates/BaseGame/game/tools/forestEditor/brushes.tscript diff --git a/Engine/source/console/sim.cpp b/Engine/source/console/sim.cpp index b03e5c15a..48e3b627f 100644 --- a/Engine/source/console/sim.cpp +++ b/Engine/source/console/sim.cpp @@ -68,6 +68,8 @@ namespace Sim ImplementNamedSet(SFXAmbienceSet) ImplementNamedSet(TerrainMaterialSet) ImplementNamedSet(DataBlockSet); + ImplementNamedSet(ForestBrushSet); + ImplementNamedSet(ForestItemDataSet); ImplementNamedGroup(ActionMapGroup) ImplementNamedGroup(ClientGroup) ImplementNamedGroup(GuiGroup) diff --git a/Engine/source/console/sim.h b/Engine/source/console/sim.h index 61ff469e0..001ace64e 100644 --- a/Engine/source/console/sim.h +++ b/Engine/source/console/sim.h @@ -107,6 +107,8 @@ namespace Sim DeclareNamedSet(SFXAmbienceSet); DeclareNamedSet(TerrainMaterialSet); DeclareNamedSet(DataBlockSet); + DeclareNamedSet(ForestBrushSet); + DeclareNamedSet(ForestItemDataSet); DeclareNamedGroup(ActionMapGroup) DeclareNamedGroup(ClientGroup) DeclareNamedGroup(GuiGroup) diff --git a/Engine/source/console/simManager.cpp b/Engine/source/console/simManager.cpp index c8fb60c7f..94b407a25 100644 --- a/Engine/source/console/simManager.cpp +++ b/Engine/source/console/simManager.cpp @@ -565,6 +565,8 @@ void init() InstantiateNamedSet(SFXAmbienceSet); InstantiateNamedSet(TerrainMaterialSet); InstantiateNamedSet(DataBlockSet); + InstantiateNamedSet(ForestBrushSet); + InstantiateNamedSet(ForestItemDataSet); InstantiateNamedGroup(ActionMapGroup); InstantiateNamedGroup(ClientGroup); InstantiateNamedGroup(GuiGroup); diff --git a/Engine/source/forest/editor/forestBrushElement.cpp b/Engine/source/forest/editor/forestBrushElement.cpp index 86e89e3d6..8c41cc969 100644 --- a/Engine/source/forest/editor/forestBrushElement.cpp +++ b/Engine/source/forest/editor/forestBrushElement.cpp @@ -197,4 +197,78 @@ DefineEngineMethod( ForestBrush, containsItemData, bool, ( const char * obj ), , } return object->containsItemData( data ); -} \ No newline at end of file +} + +//------------------------------------------------------------------------- +// ForestBrushGroupSet +//------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(ForestBrushGroup); + +ConsoleDocClass(ForestBrushGroup, + "@brief Container class for ForestBrushes\n\n" + "Editor use only.\n\n" + "@internal" +); + +ForestBrushGroup::ForestBrushGroup() +{ + +} + +bool ForestBrushGroup::onAdd() +{ + if (!Parent::onAdd()) + return false; + + SimSet* forestBrushSet; + if (!Sim::findObject("ForestBrushSet", forestBrushSet)) + { + Con::errorf("ForestBrushGroup::onAdd() - failed to find ForestBrushSet to add new ForestBrushGroup to!"); + } + + forestBrushSet->addObject(this); + + return true; +} + +void ForestBrushGroup::addObject(SimObject* inObj) +{ + ForestBrush* ele = dynamic_cast(inObj); + if (!ele) + return; + + //if ( containsItemData( ele->mData ) ) + // return; + + Parent::addObject(inObj); +} + +bool ForestBrushGroup::containsBrushData(const ForestBrush* inData) +{ + SimObjectList::iterator iter = mObjectList.begin(); + for (; iter != mObjectList.end(); iter++) + { + ForestBrush* pElement = dynamic_cast(*iter); + + if (!pElement) + continue; + + if (pElement == inData) + return true; + } + + return false; +} + +DefineEngineMethod(ForestBrushGroup, containsBrushData, bool, (const char* obj), , "( ForestBrush obj )") +{ + ForestBrush* data = NULL; + if (!Sim::findObject(obj, data)) + { + Con::warnf("ForestBrush::containsBrushData - invalid object passed"); + return false; + } + + return object->containsBrushData(data); +} diff --git a/Engine/source/forest/editor/forestBrushElement.h b/Engine/source/forest/editor/forestBrushElement.h index be6a37cc0..6a7d98973 100644 --- a/Engine/source/forest/editor/forestBrushElement.h +++ b/Engine/source/forest/editor/forestBrushElement.h @@ -121,5 +121,28 @@ protected: static SimObjectPtr smGroup; }; +//------------------------------------------------------------------------- +// ForestBrushGroup +//------------------------------------------------------------------------- -#endif // _FOREST_EDITOR_BRUSHELEMENT_H_ \ No newline at end of file +class ForestBrushGroup : public SimGroup +{ + typedef SimGroup Parent; + +public: + + ForestBrushGroup(); + + DECLARE_CONOBJECT(ForestBrushGroup); + + virtual bool onAdd(); + + virtual void addObject(SimObject*); + + bool containsBrushData(const ForestBrush* inData); +protected: + + static SimObjectPtr smGroup; +}; + +#endif // _FOREST_EDITOR_BRUSHELEMENT_H_ diff --git a/Engine/source/forest/editor/forestBrushTool.cpp b/Engine/source/forest/editor/forestBrushTool.cpp index 5b9278ea6..06a75ea1d 100644 --- a/Engine/source/forest/editor/forestBrushTool.cpp +++ b/Engine/source/forest/editor/forestBrushTool.cpp @@ -610,9 +610,14 @@ void ForestBrushTool::_collectElements() } // Find all ForestBrushElements that are directly or indirectly selected. + SimSet* brushSet; + if (!Sim::findObject("ForestBrushSet", brushSet)) + { + Con::errorf("ForestBrushTool::_collectElements() - could not find ForestBrushSet!"); + return; + } - SimGroup *brushGroup = ForestBrush::getGroup(); - brushGroup->findObjectByCallback( findSelectedElements, mElements ); + brushSet->findObjectByCallback( findSelectedElements, mElements ); // We just needed to flag these objects as selected for the benefit of our // findSelectedElements callback, we can now mark them un-selected again. diff --git a/Engine/source/forest/editor/forestEditorCtrl.cpp b/Engine/source/forest/editor/forestEditorCtrl.cpp index db8a58f3c..bf88f0b4c 100644 --- a/Engine/source/forest/editor/forestEditorCtrl.cpp +++ b/Engine/source/forest/editor/forestEditorCtrl.cpp @@ -328,10 +328,16 @@ void ForestEditorCtrl::deleteMeshSafe( ForestItemData *mesh ) } // Find ForestBrushElement(s) referencing this datablock. - SimGroup *brushGroup = ForestBrush::getGroup(); + SimSet* brushSet; + if (!Sim::findObject("ForestBrushSet", brushSet)) + { + Con::errorf("ForestBrushTool::_collectElements() - could not find ForestBrushSet!"); + return; + } + sKey = mesh; Vector foundElements; - brushGroup->findObjectByCallback( &findMeshReferences, foundElements ); + brushSet->findObjectByCallback( &findMeshReferences, foundElements ); // Add UndoAction to delete the ForestBrushElement(s) and the ForestItemData. MEDeleteUndoAction *elementAction = new MEDeleteUndoAction(); @@ -408,4 +414,4 @@ DefineEngineMethod(ForestEditorCtrl, setActiveForest, void, (const char * obj), return; object->setActiveForest(forestObject); -} \ No newline at end of file +} diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/module.tscript.template b/Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/module.tscript.template index 4a9eafc7d..37a2feab9 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/module.tscript.template +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/templateFiles/module.tscript.template @@ -21,6 +21,8 @@ function @@::onCreateGameServer(%this) %this.registerDatablock("./scripts/managedData/managedDatablocks"); if(isFile("./scripts/managedData/managedForestItemData." @ $TorqueScriptFileExtension)) %this.registerDatablock("./scripts/managedData/managedForestItemData"); + if(isFile("./scripts/managedData/managedForestBrushData." @ $TorqueScriptFileExtension)) + %this.registerDatablock("./scripts/managedData/managedForestBrushData"); if(isFile("./scripts/managedData/managedParticleEmitterData." @ $TorqueScriptFileExtension)) %this.registerDatablock("./scripts/managedData/managedParticleEmitterData"); if(isFile("./scripts/managedData/managedParticleData." @ $TorqueScriptFileExtension)) diff --git a/Templates/BaseGame/game/tools/forestEditor/brushes.tscript b/Templates/BaseGame/game/tools/forestEditor/brushes.tscript deleted file mode 100644 index 6860a8813..000000000 --- a/Templates/BaseGame/game/tools/forestEditor/brushes.tscript +++ /dev/null @@ -1,26 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -$forestBrushesGroup = new SimGroup( ForestBrushGroup ) -{ -}; -//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.tscript b/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.tscript index d039d1c86..3ae57e612 100644 --- a/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.tscript +++ b/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.tscript @@ -110,17 +110,45 @@ function ForestEditorGui::createForest( %this ) function ForestEditorGui::newBrush( %this ) { - %internalName = getUniqueInternalName( "Brush", ForestBrushGroup, true ); + AssetBrowser_SelectModule.showDialog("ForestEditorGui.pickedNewBrushTargetModule"); + AssetBrowser_SelectModuleWindow.selectWindow(); +} + +function ForestEditorGui::pickedNewBrushTargetModule(%this, %module) +{ + %moduleDef = ModuleDatabase.findModule(%module); + + ForestEditorGui.forestBrushPath = %moduleDef.ModulePath @ "/scripts/managedData/managedForestBrushData." @ $TorqueScriptFileExtension; + + if(!isDirectory(filePath(ForestEditorGui.forestItemDataPath))) + { + AssetBrowser.dirHandler.createFolder(filePath(ForestEditorGui.forestItemDataPath)); + } + + %group = ForestBrushSet.findObjectByInternalName(%module @ "ForestBrushGroup"); + if(!isObject(%group)) + { + %group = new ForestBrushGroup() { + internalName = %module @ "ForestBrushGroup"; + }; + + %group.setFilename(ForestEditorGui.forestBrushPath); + } + + %internalName = getUniqueInternalName( "Brush", ForestBrushSet, true ); %brush = new ForestBrush() { + class = "ForestBrushGroup"; internalName = %internalName; - parentGroup = ForestBrushGroup; + parentGroup = ForestBrushSet; }; + %group.add(%brush); + MECreateUndoAction::submit( %brush ); - ForestEditBrushTree.open( ForestBrushGroup ); + ForestEditBrushTree.open( ForestBrushSet ); ForestEditBrushTree.buildVisibleTree(true); %item = ForestEditBrushTree.findItemByObjectId( %brush ); ForestEditBrushTree.clearSelection(); @@ -135,7 +163,7 @@ function ForestEditorGui::newElement( %this ) %sel = ForestEditBrushTree.getSelectedObject(); if ( !isObject( %sel ) ) - %parentGroup = ForestBrushGroup; + %parentGroup = ForestBrushSet; else { if ( %sel.getClassName() $= "ForestBrushElement" ) @@ -144,7 +172,7 @@ function ForestEditorGui::newElement( %this ) %parentGroup = %sel; } - %internalName = getUniqueInternalName( "Element", ForestBrushGroup, true ); + %internalName = getUniqueInternalName( "Element", ForestBrushSet, true ); %element = new ForestBrushElement() { @@ -191,37 +219,11 @@ function ForestEditorGui::pickedNewMeshTargetModule(%this, %module) function selectNewForestMesh(%selectedShapeAssetId) { - /*%spec = "All Mesh Files|*.dts;*.dae|DTS|*.dts|DAE|*.dae"; - - %dlg = new OpenFileDialog() - { - Filters = %spec; - DefaultPath = $Pref::WorldEditor::LastPath; - DefaultFile = ""; - ChangePath = true; - }; - - %ret = %dlg.Execute(); - - if ( %ret ) - { - $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); - %fullPath = makeRelativePath( %dlg.FileName, getMainDotCSDir() ); - %file = fileBase( %fullPath ); - } - - %dlg.delete();*/ - if ( %selectedShapeAssetId $= "") return; %name = getUniqueName( AssetDatabase.getAssetName(%selectedShapeAssetId) ); - //%str = "datablock TSForestItemData( " @ %name @ " ) { shapeFile = \"" @ %fullPath @ "\"; };"; - //eval( %str ); - - //%fullPath = AssetDatabase.acquireAsset(%selectedShapeAssetId).getShapePath(); - new TSForestItemData(%name) { shapeAsset = %selectedShapeAssetId; }; @@ -418,7 +420,7 @@ function ForestEditBrushTree::handleRenameObject( %this, %name, %obj ) { if ( %name !$= "" ) { - %found = ForestBrushGroup.findObjectByInternalName( %name ); + %found = ForestBrushSet.findObjectByInternalName( %name ); if ( isObject( %found ) && %found.getId() != %obj.getId() ) { toolsMessageBoxOK( "Error", "Brush or Element with that name already exists.", "" ); diff --git a/Templates/BaseGame/game/tools/forestEditor/main.tscript b/Templates/BaseGame/game/tools/forestEditor/main.tscript index be2814baa..a2e057def 100644 --- a/Templates/BaseGame/game/tools/forestEditor/main.tscript +++ b/Templates/BaseGame/game/tools/forestEditor/main.tscript @@ -91,25 +91,7 @@ function ForestEditorPlugin::onWorldEditorStartup( %this ) { new PersistenceManager( ForestDataManager ); - %brushPath = "tools/forestEditor/brushes." @ $TorqueScriptFileExtension; - - if ( !isFile( %brushPath ) ) - %successfulFile = createPath( %brushPath ); - - // This creates the ForestBrushGroup, all brushes, and elements. - exec( %brushpath ); - - if ( !isObject( ForestBrushGroup ) ) - { - new SimGroup( ForestBrushGroup ); - %this.showError = true; - } - - ForestEditBrushTree.open( ForestBrushGroup ); - - if ( !isObject( ForestItemDataSet ) ) - new SimSet( ForestItemDataSet ); - + ForestEditBrushTree.open( ForestBrushSet ); ForestEditMeshTree.open( ForestItemDataSet ); // Add ourselves to the window menu. @@ -126,8 +108,8 @@ function ForestEditorPlugin::onWorldEditorStartup( %this ) function ForestEditorPlugin::onWorldEditorShutdown( %this ) { - if ( isObject( ForestBrushGroup ) ) - ForestBrushGroup.delete(); + if ( isObject( ForestBrushSet ) ) + ForestBrushSet.delete(); if ( isObject( ForestDataManager ) ) ForestDataManager.delete(); } @@ -153,7 +135,7 @@ function ForestEditorPlugin::onActivated( %this ) %this.map.push(); Parent::onActivated(%this); - ForestEditBrushTree.open( ForestBrushGroup ); + ForestEditBrushTree.open( ForestBrushSet ); ForestEditMeshTree.open( ForestItemDataSet ); // Open the Brush tab. @@ -224,12 +206,26 @@ function ForestEditorPlugin::onDeactivated( %this ) // Also take this opportunity to save. ForestDataManager.saveDirty(); + %this.saveBrushSet(); %this.map.pop(); Parent::onDeactivated(%this); } +function ForestEditorPlugin::saveBrushSet(%this) +{ + for(%i=0; %i < ForestBrushSet.getCount(); %i++) + { + %group = ForestBrushSet.getObject(%i); + if(%group.isMemberOfClass("ForestBrushGroup")) + { + %fileName = %group.getFileName(); + %group.save(%group.getFileName()); + } + } +} + function ForestEditorPlugin::isDirty( %this ) { %dirty = %this.dirty || ForestEditorGui.isDirty(); @@ -266,7 +262,8 @@ function ForestEditorPlugin::onSaveMission( %this, %missionFile ) } } - ForestBrushGroup.save( "tools/forestEditor/brushes." @ $TorqueScriptFileExtension ); + //Make sure our data is up to date too + %this.saveBrushSet(); } function ForestEditorPlugin::onEditorSleep( %this ) From bcc7f2f6cf4981e076a5074d41ee25894efba116 Mon Sep 17 00:00:00 2001 From: Tony <1414927+zfbx@users.noreply.github.com> Date: Thu, 7 Apr 2022 20:30:25 -0400 Subject: [PATCH 071/145] Add funding/sponsor options for support More options can be seen here https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository --- .github/FUNDING.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..3253c4ca2 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: [Areloch, Azaezel] +patreon: Areloch From 4e78800ae07305aebddc8038584cc1044ff0e451 Mon Sep 17 00:00:00 2001 From: Tony <1414927+zfbx@users.noreply.github.com> Date: Thu, 7 Apr 2022 20:54:57 -0400 Subject: [PATCH 072/145] Updated readme with new links The release, downloads and tag will update once a tag is created and a release is pushed --- README.md | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 03b9870b8..9049918d5 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,36 @@ -# Torque 3D +# Torque3D -MIT Licensed Open Source version of [Torque 3D](http://torque3d.org) from [GarageGames](http://www.garagegames.com) +MIT Licensed Open Source version of [Torque3D](https://torque3d.org) from [GarageGames](http://www.garagegames.com) -[![GitHub tag](https://img.shields.io/github/tag/GarageGames/Torque3D.svg)](https://github.com/GarageGames/Torque3D/tags) -[![GitHub release](https://img.shields.io/github/release/GarageGames/Torque3D.svg)](https://github.com/GarageGames/Torque3D/releases/latest) -[![Github All Releases](https://img.shields.io/github/downloads/GarageGames/Torque3D/total.svg)](https://github.com/GarageGames/Torque3D/releases/latest) +[![GitHub tag](https://img.shields.io/github/tag/TorqueGameEngines/Torque3D.svg)](https://github.com/TorqueGameEngines/Torque3D/tags) +[![GitHub release](https://img.shields.io/github/release/TorqueGameEngines/Torque3D.svg)](https://github.com/TorqueGameEngines/Torque3D/releases/latest) +[![Github All Releases](https://img.shields.io/github/downloads/TorqueGameEngines/Torque3D/total.svg)](https://github.com/TorqueGameEngines/Torque3D/releases/latest) -[![Discord](https://img.shields.io/badge/Discord%20-%237289DA.svg?&logo=discord&logoColor=white)](https://discord.com/invite/qdAZxT4) [![IRC](https://img.shields.io/badge/irc-%23garagegames-green.svg)](https://kiwiirc.com/client/irc.maxgaming.net/?nick=wiki_user|?#garagegames) +[![Discord](https://img.shields.io/badge/Discord%20-%237289DA.svg?&logo=discord&logoColor=white)](https://discord.com/invite/qdAZxT4) +[![IRC](https://img.shields.io/badge/irc-%23garagegames-green.svg)](https://kiwiirc.com/client/irc.maxgaming.net/?nick=wiki_user|?#garagegames) ## More Information -* [Homepage](http://torque3d.org) +* [Homepage](https://torque3d.org) * [Torque 3D wiki](http://wiki.torque3d.org) -* [Community forum](http://forums.torque3d.org) -* [GarageGames forum](http://www.garagegames.com/community/forums) -* [GarageGames professional services](http://services.garagegames.com/) +* [Community forum](https://torque3d.org/forums) +* [Binaries](https://github.com/TorqueGameEngines/Torque3D-Binaries) +* [Guide Docs](https://torque3d.org/docs/t3d/) +* [Reference Docs](https://reference.torque3d.org/) +* [Work Blog](https://torque3d.org/blogs/blog/1-work-blog/) + +**Extras:** +[Torque3D Resources](https://github.com/Torque3DResources) | [Awesome Torque3D](https://github.com/TorqueGameEngines/awesome-torque3d) ## Pre-compiled Version In addition to GitHub we also have a couple of pre-packaged files for you to download if you would prefer to not compile the code yourself. -They are available from the [downloads](http://wiki.torque3d.org/main:downloads) page on the wiki. - -## Related repositories +They are available from the [Torque3D Binaries](https://github.com/TorqueGameEngines/Torque3D-Binaries) repo. +### Legacy Links +* [Legacy Repository](https://github.com/GarageGames/Torque3D) +* [GarageGames forum](http://www.garagegames.com/community/forums) +* [GarageGames professional services](http://services.garagegames.com/) * [Project Manager repository](https://github.com/GarageGames/Torque3D-ProjectManager) * [Offline documentation repository](https://github.com/Torque3D-GameEngine/Torque3D-Documentation) From 20a29027a10b738e7aef9011a21e032c8c08f24a Mon Sep 17 00:00:00 2001 From: Tony <1414927+zfbx@users.noreply.github.com> Date: Fri, 8 Apr 2022 18:03:37 -0400 Subject: [PATCH 073/145] add roadmap link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9049918d5..5576d323c 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ MIT Licensed Open Source version of [Torque3D](https://torque3d.org) from [Garag * [Homepage](https://torque3d.org) * [Torque 3D wiki](http://wiki.torque3d.org) * [Community forum](https://torque3d.org/forums) +* [Roadmap](https://github.com/orgs/TorqueGameEngines/projects/1) * [Binaries](https://github.com/TorqueGameEngines/Torque3D-Binaries) * [Guide Docs](https://torque3d.org/docs/t3d/) * [Reference Docs](https://reference.torque3d.org/) From 7cb438550d5401d996f1b7e5ab8231e608a5ea0a Mon Sep 17 00:00:00 2001 From: Tony <1414927+zfbx@users.noreply.github.com> Date: Fri, 8 Apr 2022 18:04:21 -0400 Subject: [PATCH 074/145] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 3253c4ca2..1d6713a29 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,2 @@ -github: [Areloch, Azaezel] +github: Areloch patreon: Areloch From 5c8d8fab005a15a071002d91b0063ebe1750d725 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 10 Apr 2022 01:40:15 -0500 Subject: [PATCH 075/145] Changes behavior with suffix appending of asset importer so it doesn't contaminate the original "clean" name, which is used for setting the mapTo value of material definitions Also adds a sanity check when applying the type suffix to see if it's already there to avoid needless doubleups Fixes offsetting/positioning behavior on icon buttons to actually respect the icon position variable Adds sanity checks to ensure we're not trying to utilize a in-process-of-deleting decoy dummy Fixes handling of sliders in option menus to properly store and test unapplied values Fixes handling of display device setting to properly store and test unapplied values Adds additional logic to creation of shape and material asset previews to attempt to force-load dependencies to improve likelihood that they'll actually be loaded when we go to generate the preview. Temp disables creating cubemap 'assets' via the RMB context menu in the AB --- Engine/source/T3D/assets/assetImporter.cpp | 30 +++++++-------- Engine/source/console/fileSystemFunctions.cpp | 16 ++++++++ .../source/gui/buttons/guiIconButtonCtrl.cpp | 37 ++++++++++++++++--- Engine/source/gui/controls/guiDecoyCtrl.cpp | 6 ++- .../game/data/UI/guis/optionsMenu.tscript | 29 +++++++++++---- .../scripts/assetTypes/material.tscript | 9 ++++- .../scripts/assetTypes/shape.tscript | 11 +++++- .../assetBrowser/scripts/popupMenus.tscript | 1 + 8 files changed, 108 insertions(+), 31 deletions(-) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index d0b498d26..de19bc983 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -1633,7 +1633,7 @@ void AssetImporter::processImageAsset(AssetImportObject* assetItem) { String diffuseToken = StringUnit::getUnit(activeImportConfig->DiffuseTypeSuffixes, 0, ",;\t"); assetItem->assetName = assetItem->assetName + diffuseToken; - assetItem->cleanAssetName = assetItem->assetName; + //assetItem->cleanAssetName = assetItem->assetName; } else { @@ -1642,7 +1642,7 @@ void AssetImporter::processImageAsset(AssetImportObject* assetItem) if ((materialAsset && materialAsset->assetName.compare(assetItem->assetName) == 0) || activeImportConfig->AlwaysAddImageSuffix) { assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix; - assetItem->cleanAssetName = assetItem->assetName; + //assetItem->cleanAssetName = assetItem->assetName; } } @@ -1673,8 +1673,8 @@ void AssetImporter::processImageAsset(AssetImportObject* assetItem) if(assetItem->assetName == assetItem->cleanAssetName && activeImportConfig->AlwaysAddImageSuffix) { - assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix; - assetItem->cleanAssetName = assetItem->assetName; + if (!assetItem->assetName.endsWith(activeImportConfig->AddedImageSuffix.c_str())) + assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix; } assetItem->importStatus = AssetImportObject::Processed; @@ -1752,8 +1752,8 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem) { if (activeImportConfig->AlwaysAddMaterialSuffix) //we only opt to force on the suffix if we're not obligating using the original material defs { - assetItem->assetName += activeImportConfig->AddedMaterialSuffix; - assetItem->cleanAssetName = assetItem->assetName; + if(!assetItem->assetName.endsWith(activeImportConfig->AddedMaterialSuffix.c_str())) + assetItem->assetName += activeImportConfig->AddedMaterialSuffix; } if (activeImportConfig->PopulateMaterialMaps) @@ -1936,7 +1936,7 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem) if (newImageAssetObj->assetName == assetItem->assetName) { newImageAssetObj->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t"); - newImageAssetObj->cleanAssetName = newImageAssetObj->assetName; + //newImageAssetObj->cleanAssetName = newImageAssetObj->assetName; } newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType(ImageAsset::ImageTypes::Albedo); @@ -1954,7 +1954,7 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem) if (matchedImageTypes[t]->assetName == assetItem->assetName) { matchedImageTypes[t]->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t"); - matchedImageTypes[t]->cleanAssetName = matchedImageTypes[t]->assetName; + //matchedImageTypes[t]->cleanAssetName = matchedImageTypes[t]->assetName; } } } @@ -2000,8 +2000,8 @@ void AssetImporter::processShapeAsset(AssetImportObject* assetItem) if (activeImportConfig->AlwaysAddShapeSuffix) { - assetItem->assetName += activeImportConfig->AddedShapeSuffix; - assetItem->cleanAssetName = assetItem->assetName; + if(!assetItem->assetName.endsWith(activeImportConfig->AddedShapeSuffix.c_str())) + assetItem->assetName += activeImportConfig->AddedShapeSuffix; } S32 meshCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_meshCount"), nullptr)); @@ -2094,8 +2094,8 @@ void AssetImporter::processShapeAnimationAsset(AssetImportObject* assetItem) if (activeImportConfig->AlwaysAddShapeAnimationSuffix) { - assetItem->assetName += activeImportConfig->AddedShapeAnimationSuffix; - assetItem->cleanAssetName = assetItem->assetName; + if (!assetItem->assetName.endsWith(activeImportConfig->AddedShapeAnimationSuffix.c_str())) + assetItem->assetName += activeImportConfig->AddedShapeAnimationSuffix; } S32 animCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_animCount"), nullptr)); @@ -2237,8 +2237,8 @@ void AssetImporter::processSoundAsset(AssetImportObject* assetItem) if (activeImportConfig->AlwaysAddSoundSuffix) { - assetItem->assetName += activeImportConfig->AddedSoundSuffix; - assetItem->cleanAssetName = assetItem->assetName; + if (!assetItem->assetName.endsWith(activeImportConfig->AddedSoundSuffix.c_str())) + assetItem->assetName += activeImportConfig->AddedSoundSuffix; } assetItem->importStatus = AssetImportObject::Processed; @@ -2916,7 +2916,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) { Material* newMat = new Material(); newMat->registerObject(assetName); - newMat->mMapTo = assetName; + newMat->mMapTo = assetItem->cleanAssetName; bool hasRoughness = false; for (U32 i = 0; i < assetItem->childAssetItems.size(); i++) diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index 010147af2..3f43e962d 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -892,4 +892,20 @@ DefineEngineFunction( createPath, bool, ( const char* path ),, return Platform::createPath( pathName ); } +DefineEngineFunction(deleteDirectory, bool, (const char* path), , + "@brief Delete a directory from the hard drive\n\n" + + "@param path Name and path of the folder to delete\n" + "@note THERE IS NO RECOVERY FROM THIS. Deleted files are gone for good.\n" + "@return True if file was successfully deleted\n" + "@ingroup FileSystem") +{ + static char fileName[1024]; + static char sandboxFileName[1024]; + + Con::expandScriptFilename(fileName, sizeof(fileName), path); + Platform::makeFullPathName(fileName, sandboxFileName, sizeof(sandboxFileName)); + + return Platform::deleteDirectory(sandboxFileName); +} #endif // TORQUE_TOOLS diff --git a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp index 57f9f9123..32b5be36b 100644 --- a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp @@ -240,10 +240,15 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect ) { // If there is a bitmap array then render using it. // Otherwise use a standard fill. - if(mProfile->mUseBitmapArray && mProfile->mBitmapArrayRects.size()) + if (mProfile->mUseBitmapArray && mProfile->mBitmapArrayRects.size()) + { renderBitmapArray(boundsRect, stateMouseOver); + } else - renderSlightlyRaisedBox(boundsRect, mProfile); + { + drawer->drawRectFill(boundsRect, mProfile->mFillColorHL); + drawer->drawRect(boundsRect, mProfile->mBorderColorHL); + } } else { @@ -258,8 +263,16 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect ) } else { - drawer->drawRectFill(boundsRect, mProfile->mFillColorNA); - drawer->drawRect(boundsRect, mProfile->mBorderColorNA); + if (mActive) + { + drawer->drawRectFill(boundsRect, mProfile->mFillColor); + drawer->drawRect(boundsRect, mProfile->mBorderColor); + } + else + { + drawer->drawRectFill(boundsRect, mProfile->mFillColorNA); + drawer->drawRect(boundsRect, mProfile->mBorderColorNA); + } } } @@ -302,7 +315,7 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect ) } else { - iconRect.set( offset + mButtonMargin, getExtent() - (mButtonMargin * 2) ); + iconRect.set( offset + mButtonMargin, getExtent() - (Point2I(mAbs(mButtonMargin.x), mAbs(mButtonMargin.y)) * 2) ); if ( mMakeIconSquare ) { @@ -313,6 +326,20 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect ) iconRect.extent.x = iconRect.extent.y; } + if (mIconLocation == IconLocRight) + { + iconRect.point.x = (offset.x + getWidth()) - iconRect.extent.x + mButtonMargin.x; + } + else if (mIconLocation == IconLocLeft) + { + //default state presumes left positioning + } + else if (mIconLocation == IconLocCenter) + { + iconRect.point.x = offset.x + (getWidth() / 2) - (iconRect.extent.x / 2) + mButtonMargin.x; + iconRect.point.y = offset.y + (getHeight() / 2) - (iconRect.extent.y / 2) + mButtonMargin.y; + } + drawer->drawBitmapStretch( mBitmap, iconRect ); } } diff --git a/Engine/source/gui/controls/guiDecoyCtrl.cpp b/Engine/source/gui/controls/guiDecoyCtrl.cpp index 61b489995..54ca105ae 100644 --- a/Engine/source/gui/controls/guiDecoyCtrl.cpp +++ b/Engine/source/gui/controls/guiDecoyCtrl.cpp @@ -146,12 +146,14 @@ void GuiDecoyCtrl::onMouseMove(const GuiEvent &event) GuiControl *tempControl = parent->findHitControl(localPoint); //the decoy control has the responsibility of keeping track of the decoyed controls status - if(mMouseOverDecoy == false && mDecoyReference != NULL) + if(mMouseOverDecoy == false && mDecoyReference != NULL && + !mDecoyReference->isDeleted() && !mDecoyReference->isRemoved()) { tempControl->onMouseEnter(event); mMouseOverDecoy = true; } - else if(tempControl != mDecoyReference && mDecoyReference != NULL) + else if(tempControl != mDecoyReference && mDecoyReference != NULL && + !mDecoyReference->isDeleted() && !mDecoyReference->isRemoved()) { mDecoyReference->onMouseLeave(event); mMouseOverDecoy = false; diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript index 2dd1d7f10..aa343f81f 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript @@ -200,7 +200,7 @@ function OptionsMenu::apply(%this) //for updates if ( %targetVar $= "$pref::Video::displayDevice" ) { - MessageBoxOK( "Change requires restart", "Please restart the game for a display device change to take effect." ); + schedule(32, 0, "MessageBoxOK", "Change requires restart", "Please restart the game for a display device change to take effect."); } else if(startsWith(%targetVar, "$pref::PostFX::")) { @@ -349,11 +349,6 @@ function populateDisplaySettingsList() OptionName.setText(""); OptionDescription.setText(""); - //First, lets double-check the active device is accurate. Sometimes the default value in our prefs doesn't match the active one - %displayDevice = getDisplayDeviceType(); - if($changingDisplayDevice !$= "") - %displayDevice = $changingDisplayDevice; - %apiList = ""; %apiCount = GFXInit::getAdapterCount(); %apiIdx = 0; @@ -374,7 +369,11 @@ function populateDisplaySettingsList() trim(%apiList); - OptionsMenuSettingsList.addOptionRow("Display API", "$pref::Video::DisplayAPI", %apiList, false, "", true, "The display API used for rendering.", %displayDevice); + %displayDevice = OptionsMenu.getOptionVariableValue("$pref::Video::displayDevice"); + if(%displayDevice $= "") + %displayDevice = getDisplayDeviceType(); + + OptionsMenuSettingsList.addOptionRow("Display API", "$pref::Video::displayDevice", %apiList, false, "", true, "The display API used for rendering.", %displayDevice); %numDevices = Canvas.getMonitorCount(); %devicesList = ""; @@ -977,6 +976,8 @@ function MenuOptionsButton::onChange(%this) OptionName.setText(%optionName); OptionDescription.setText(%tooltipText); + if(%optionMode == 0) + { %currentValue = %this.getCurrentOption(); if(%currentValue !$= "") { @@ -995,6 +996,20 @@ function MenuOptionsButton::onChange(%this) } else OptionsMenu.unappliedChanges.setValue("\"" @ %saveReadyValue @ "\"", %prefIndex); + } + } + else if(%optionMode == 1) + { + %currentValue = %this.getValue(); + + %prefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetVar); + if(%prefIndex == -1) + { + echo("Setting UnappliedChanges via add: key:" @ %targetVar @", value: " @ %currentValue); + OptionsMenu.unappliedChanges.add(%targetVar, "\"" @ %currentValue @ "\"" ); + } + else + OptionsMenu.unappliedChanges.setValue("\"" @ %currentValue @ "\"", %prefIndex); } //Update the UI in case there's responsive logic diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index debcaffd8..d6d48819c 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript @@ -462,10 +462,17 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData, if(isObject(%assetDef.materialDefinitionName)) { + //real fast, we'll be 100% sure that the image resource we need is loaded + %diffuseMapAssetId = %assetDef.materialDefinitionName.getDiffuseMapAsset(0); + if(AssetDatabase.isDeclaredAsset(%diffuseMapAssetId)) + { + %diffuseMapAsset = AssetDatabase.acquireAsset(%diffuseMapAssetId); + AssetDatabase.releaseAsset(%diffuseMapAssetId); + } %previewShapeDef = AssetDatabase.acquireAsset("ToolsModule:previewSphereShape"); %generatedFilePath = %previewShapeDef.generateCachedPreviewImage(256, %assetDef.materialDefinitionName); - pathCopy(%generatedFilePath, %previewFilePath); + pathCopy(%generatedFilePath, %previewFilePath, false); fileDelete(%generatedFilePath); if(!AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript index 250e7c6ac..c70750e90 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript @@ -290,12 +290,21 @@ function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData, %f { displayEditorLoadingGui("Generating Shape Asset Preview..."); + //real fast, we'll be 100% sure that the image resource we need is loaded + + %matSlot0AssetId = %assetDef.materialSlot0; + if(AssetDatabase.isDeclaredAsset(%matSlot0AssetId)) + { + %matAsset = AssetDatabase.acquireAsset(%matSlot0AssetId); + AssetDatabase.releaseAsset(%matSlot0AssetId); + } + //This is slightly hacky, but we're going to utilize the imposter/last detail system //to generate our previews for us and then clean up the unneeded bits %filePath = %assetDef.generateCachedPreviewImage(); - pathCopy(%filePath, %previewFilePath); + pathCopy(%filePath, %previewFilePath, false); fileDelete(%filePath); //cleanup if(!AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript index 808649d86..27d198e8e 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.tscript @@ -237,6 +237,7 @@ function AssetBrowser::buildPopupMenus(%this) AddNewArtAssetPopup.enableItem(7, false); //shape animation AddNewArtAssetPopup.enableItem(13, false); //sound asset AddNewArtAssetPopup.enableItem(15, false); //particle effect + AddNewArtAssetPopup.enableItem(17, false); //cubemap if( !isObject( EditFolderPopup ) ) { From 0136af477f8989f90794b6cd86d4065b8f31ab54 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 10 Apr 2022 17:29:55 -0500 Subject: [PATCH 076/145] getAssetIdByFilename loaded state fix getAssetIdByFilename should set the Asset->mLoadedState = AssetErrCode::BadFileReference; so we know we're using a fallback --- Engine/source/T3D/assets/ImageAsset.cpp | 5 +++++ Engine/source/T3D/assets/ShapeAsset.cpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/Engine/source/T3D/assets/ImageAsset.cpp b/Engine/source/T3D/assets/ImageAsset.cpp index d49cfbf85..78515d877 100644 --- a/Engine/source/T3D/assets/ImageAsset.cpp +++ b/Engine/source/T3D/assets/ImageAsset.cpp @@ -219,6 +219,11 @@ StringTableEntry ImageAsset::getAssetIdByFilename(StringTableEntry fileName) //acquire and bind the asset, and return it out imageAssetId = query.mAssetList[0]; } + else + { + AssetPtr imageAsset = imageAssetId; + imageAsset->mLoadedState = AssetErrCode::BadFileReference; + } return imageAssetId; } diff --git a/Engine/source/T3D/assets/ShapeAsset.cpp b/Engine/source/T3D/assets/ShapeAsset.cpp index 231d42cb9..a3aafe055 100644 --- a/Engine/source/T3D/assets/ShapeAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAsset.cpp @@ -473,6 +473,11 @@ StringTableEntry ShapeAsset::getAssetIdByFilename(StringTableEntry fileName) //acquire and bind the asset, and return it out shapeAssetId = query.mAssetList[0]; } + else + { + AssetPtr shapeAsset = shapeAssetId; + shapeAsset->mLoadedState = AssetErrCode::BadFileReference; + } return shapeAssetId; } From 1c7c32baa6c271dc35106ca3988f7e71d19c6ad5 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 10 Apr 2022 19:41:37 -0500 Subject: [PATCH 077/145] Separates out acquireAsset call for importing assets until after all assets have been imported, then runs it as a post step to ensure all assets are properly loaded before they're used --- Engine/source/T3D/assets/MaterialAsset.cpp | 5 --- Engine/source/T3D/assets/assetImporter.cpp | 37 ++++++++++++++++--- Engine/source/T3D/assets/assetImporter.h | 6 +++ .../T3D/assets/assetImporter_ScriptBinding.h | 4 +- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/Engine/source/T3D/assets/MaterialAsset.cpp b/Engine/source/T3D/assets/MaterialAsset.cpp index 77b22cc24..6153cd3e8 100644 --- a/Engine/source/T3D/assets/MaterialAsset.cpp +++ b/Engine/source/T3D/assets/MaterialAsset.cpp @@ -174,11 +174,6 @@ void MaterialAsset::initializeAsset() return; } - if (mMatDefinitionName == StringTable->insert("DetailBlue")) - { - bool asdfsd = true; - } - if (size() != 0 && mScriptPath == StringTable->EmptyString()) { mLoadedState = EmbeddedDefinition; diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index de19bc983..865af276f 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -1727,7 +1727,8 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem) //If there was no existing assetId, then lets see if it already exists in a legacy file, like a materials.cs or materials.tscript //If it does, we'll just make our asset point to that instead of a new file - Material* mat = MATMGR->getMaterialDefinitionByName(assetName); + Material* mat; + Sim::findObject(assetName, mat); if (!mat) mat = MATMGR->getMaterialDefinitionByMapTo(assetName); @@ -2618,6 +2619,8 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath, String typ else { importAssets(); + + acquireAssets(); } dumpActivityLog(); @@ -2729,10 +2732,6 @@ void AssetImporter::importAssets(AssetImportObject* assetItem) tss->setShapeAssetId(assetId); } } - - //Go ahead and force the asset to load now just to kick it for immediate use - AssetBase* assetDef = AssetDatabase.acquireAsset(assetId); - AssetDatabase.releaseAsset(assetId); } else { @@ -2757,6 +2756,34 @@ void AssetImporter::importAssets(AssetImportObject* assetItem) dumpActivityLog(); } +void AssetImporter::acquireAssets(AssetImportObject* assetItem) +{ + Vector itemList = importingAssets; + if (assetItem != nullptr) + itemList = assetItem->childAssetItems; + + for (U32 i = 0; i < itemList.size(); i++) + { + AssetImportObject* item = itemList[i]; + if (item->importStatus == AssetImportObject::Skipped || + item->importStatus == AssetImportObject::NotProcessed || + item->importStatus == AssetImportObject::Error) + continue; + + //recurse if needed, we want to process child items first for dependency reasons + acquireAssets(item); + + //Go ahead and force the asset to load now just to kick it for immediate use + String assetId = item->moduleName + ":" + item->assetName; + + if (AssetDatabase.isDeclaredAsset(assetId)) + { + AssetBase* assetDef = AssetDatabase.acquireAsset(assetId); + AssetDatabase.releaseAsset(assetId); + } + } +} + // // Type-specific import logic // diff --git a/Engine/source/T3D/assets/assetImporter.h b/Engine/source/T3D/assets/assetImporter.h index 4e2fc53aa..6e77ef965 100644 --- a/Engine/source/T3D/assets/assetImporter.h +++ b/Engine/source/T3D/assets/assetImporter.h @@ -914,6 +914,12 @@ public: ///
  • Torque::Path importShapeAnimationAsset(AssetImportObject* assetItem); + /// + /// Iterates over all the items in the current session and acquires them, which jumpstarts the loading/init'ng process on them, making the available for use immediately + /// @param assetItem, if null, will loop over and recurse the main import asset items, if a specific AssetImportObject is passed in, it will recurse it's children + /// + void acquireAssets(AssetImportObject* assetItem = nullptr); + // /// /// Gets the currently active import configuration diff --git a/Engine/source/T3D/assets/assetImporter_ScriptBinding.h b/Engine/source/T3D/assets/assetImporter_ScriptBinding.h index aa50c82de..a9a94672b 100644 --- a/Engine/source/T3D/assets/assetImporter_ScriptBinding.h +++ b/Engine/source/T3D/assets/assetImporter_ScriptBinding.h @@ -92,7 +92,9 @@ DefineEngineMethod(AssetImporter, resolveAssetItemIssues, void, (AssetImportObje DefineEngineMethod(AssetImporter, importAssets, void, (),, "Runs the actual import action on the items.") { - return object->importAssets(); + object->importAssets(); + + object->acquireAssets(); } DefineEngineMethod(AssetImporter, getAssetItemCount, S32, (),, From 880ac5a264b86e7b52c052f5e2652889e5716c1c Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 12 Apr 2022 19:46:19 -0500 Subject: [PATCH 078/145] bump down saveScaledImage default to 256 also add a "Assets/Browser/PreviewImageSize" value lookup, which if left blank defaults to 256 --- Engine/source/gfx/bitmap/gBitmap.cpp | 4 ++-- .../game/tools/assetBrowser/scripts/assetTypes/image.tscript | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Engine/source/gfx/bitmap/gBitmap.cpp b/Engine/source/gfx/bitmap/gBitmap.cpp index 21e1351f8..281ee7a5d 100644 --- a/Engine/source/gfx/bitmap/gBitmap.cpp +++ b/Engine/source/gfx/bitmap/gBitmap.cpp @@ -1362,7 +1362,7 @@ DefineEngineFunction( getBitmapInfo, String, ( const char *filename ),, image->getFormat()); } -DefineEngineFunction(saveScaledImage, bool, (const char* bitmapSource, const char* bitmapDest, S32 resolutionSize), ("", "", 512), +DefineEngineFunction(saveScaledImage, bool, (const char* bitmapSource, const char* bitmapDest, S32 resolutionSize), ("", "", 256), "Loads an image from the source path, and scales it down to the target resolution before" "Saving it out to the destination path.\n") { @@ -1419,7 +1419,7 @@ DefineEngineFunction(saveScaledImage, bool, (const char* bitmapSource, const cha image->extrudeMipLevels(); U32 mipCount = image->getNumMipLevels(); - U32 targetMips = mFloor(mLog2((F32)resolutionSize)) + 1; + U32 targetMips = mFloor(mLog2((F32)(resolutionSize ? resolutionSize : 256))) + 1; if (mipCount > targetMips) { diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript index df8b2467c..167b3f197 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript @@ -202,7 +202,7 @@ function AssetBrowser::buildImageAssetPreview(%this, %assetDef, %previewData, %f { displayEditorLoadingGui("Generating Image Asset Preview..."); - %success = saveScaledImage(%assetDef.getImagePath(), %previewFilePath); + %success = saveScaledImage(%assetDef.getImagePath(), %previewFilePath, EditorSettings.value("Assets/Browser/PreviewImageSize")); if(%success) { From 496f28224967d2c9548fdeb98964b6b833674d67 Mon Sep 17 00:00:00 2001 From: Areloch Date: Sat, 16 Apr 2022 16:00:34 -0500 Subject: [PATCH 079/145] Create CODE_OF_CONDUCT.md Didn't have one of these for consistent comprehension of expectations of community behavior --- CODE_OF_CONDUCT.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..ae27c522a --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,13 @@ +# Torque Game Engines Community Code of Conduct + +- We, as a community, are committed to providing a friendly, safe and welcoming environment for all, regardless of experience, background, history or characteristic. +- Please avoid using any overly sexual, offensive, or insulting alias or nicknames for yourself or others that would otherwise detract from a friendly, safe and welcoming environment. +- Please be kind and courteous. There's no need to be rude. +- Respect that people have differences of opinion, and that every design, implementation, or choice carries considerations, trade-offs, and costs. There is rarely ever a perfect answer. +- Please keep critiques constructive. If you are going to critique someone's work, ideas, or decisions, do it with topical and specific feedback so that they can improve. Unconstructive critiques don't help anyone better their work. +- Insulting, demeaning or harassing anyone is not welcome behavior, whether in public or private conversations. If you feel you have been subjected to any of this behavior, please contact any moderator or admin immediately. Whether you're a regular or a newcomer, we care about making this community a safe place for you. If you have any lack of clarity about what might fall under those concepts, feel free to ask for clarification from the moderation team. +- Likewise, any spamming, trolling, flaming, baiting or other attention-stealing/seeking behavior is not welcome. +- Do not insult or deride other users. 'You're an idiot' is not a useful comment. Do not do this. +- If feedback is being provided, it needs to be constructive. Just simply calling something a bad idea is not helpful in correcting the core issues of that idea. Take the time to explain what is wrong with the idea and how it could be improved upon. +- In discussions, under normal circumstances if the OP of a thread requests a post to be removed because they feel it is inflammatory, or off topic or the like, the mods will review it and in most cases, remove it per OP's request. It's their thread, so they get nearly final say in how the thread's topic should flow. MODGRU of course gets the actual final say, but will listen to the thread OPs reasoning, and if it makes sense, will generally abide the request. +- If any user has a problem with something on any community site, such as content posted, or another user's behavior, they need to contact someone in MODGRU. Moderation cannot be expected to happen in a concise, timely manner if they are not informed about it. Rather than engaging in the negative behavior, users are heavily encouraged to report it and move on. Engaging in bad behavior in response only sets both parties up to be in trouble with moderation. From b795776b2351d5b714d55f20da542080fb2c7470 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 17 Apr 2022 13:03:44 -0500 Subject: [PATCH 080/145] requested feature: large number display origional author: Peter Simard --- Engine/source/math/mathTypes.cpp | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Engine/source/math/mathTypes.cpp b/Engine/source/math/mathTypes.cpp index 70ac9adf7..21a8d0bf5 100644 --- a/Engine/source/math/mathTypes.cpp +++ b/Engine/source/math/mathTypes.cpp @@ -1247,4 +1247,38 @@ DefineEngineFunction(getRandom, F32, (S32 a, S32 b), (S32_MAX, S32_MAX), return gRandGen.randF(); } +DefineEngineFunction(mAddS32, const char *, (S32 v1, S32 v2), , "Add 2 large numbers") +{ + S32 res = v1 + v2; + char *ret = Con::getReturnBuffer(64); + dSprintf(ret, 64, "%i", res); + + return ret; +} +DefineEngineFunction(mSubS32, const char *, (S32 v1, S32 v2), , "Subtract 2 large numbers") +{ + S32 res = v1 - v2; + char *ret = Con::getReturnBuffer(64); + dSprintf(ret, 64, "%i", res); + + return ret; +} + +DefineEngineFunction(mMulS32, const char *, (S32 v1, S32 v2), , "Multiply 2 large numbers") +{ + S32 res = v1 * v2; + char *ret = Con::getReturnBuffer(64); + dSprintf(ret, 64, "%i", res); + + return ret; +} + +DefineEngineFunction(mDivS32, const char *, (S32 v1, S32 v2), , "Divide 2 large numbers") +{ + S32 res = v1 / v2; + char *ret = Con::getReturnBuffer(64); + dSprintf(ret, 64, "%i", res); + + return ret; +} //------------------------------------------------------------------------------ From 6d2c108cbd960d2f6baba99683d6978e4ae90aec Mon Sep 17 00:00:00 2001 From: Lukas Aldershaab Date: Wed, 20 Apr 2022 00:20:19 +0200 Subject: [PATCH 081/145] Fix TAML schema for array groups --- Engine/source/persistence/taml/taml.cpp | 296 ++++++++++++++++-------- 1 file changed, 194 insertions(+), 102 deletions(-) diff --git a/Engine/source/persistence/taml/taml.cpp b/Engine/source/persistence/taml/taml.cpp index a623ba8b1..cd02e1ab4 100644 --- a/Engine/source/persistence/taml/taml.cpp +++ b/Engine/source/persistence/taml/taml.cpp @@ -1055,6 +1055,115 @@ ImplementEnumType(_TamlFormatMode, //----------------------------------------------------------------------------- + tinyxml2::XMLElement* g__write_schema_attribute_element(const AbstractClassRep::Field& field, AbstractClassRep* pType, + tinyxml2::XMLDocument& schemaDocument) + { + // Skip if not a data field. + if (field.type == AbstractClassRep::DeprecatedFieldType || + field.type == AbstractClassRep::StartGroupFieldType || + field.type == AbstractClassRep::EndGroupFieldType) + return NULL; + + // Skip if the field root is not this type. + if (pType->findFieldRoot(field.pFieldname) != pType) + return NULL; + + // Add attribute element. + tinyxml2::XMLElement* pAttributeElement = schemaDocument.NewElement("xs:attribute"); + pAttributeElement->SetAttribute("name", field.pFieldname); + + // Handle the console type appropriately. + const S32 fieldType = (S32)field.type; + + /* + // Is the field an enumeration? + if ( fieldType == TypeEnum ) + { + // Yes, so add attribute type. + tinyxml2::XMLElement* pAttributeSimpleTypeElement = schemaDocument.NewElement( "xs:simpleType" ); + pAttributeElement->LinkEndChild( pAttributeSimpleTypeElement ); + + // Add restriction element. + tinyxml2::XMLElement* pAttributeRestrictionElement = schemaDocument.NewElement( "xs:restriction" ); + pAttributeRestrictionElement->SetAttribute( "base", "xs:string" ); + pAttributeSimpleTypeElement->LinkEndChild( pAttributeRestrictionElement ); + + // Yes, so fetch enumeration count. + const S32 enumCount = field.table->size; + + // Iterate enumeration. + for( S32 index = 0; index < enumCount; ++index ) + { + // Add enumeration element. + tinyxml2::XMLElement* pAttributeEnumerationElement = schemaDocument.NewElement( "xs:enumeration" ); + pAttributeEnumerationElement->SetAttribute( "value", field.table->table[index].label ); + pAttributeRestrictionElement->LinkEndChild( pAttributeEnumerationElement ); + } + } + else + {*/ + // No, so assume it's a string type initially. + const char* pFieldTypeDescription = "xs:string"; + + // Handle known types. + if (fieldType == TypeF32) + { + pFieldTypeDescription = "xs:float"; + } + else if (fieldType == TypeS8 || fieldType == TypeS32) + { + pFieldTypeDescription = "xs:int"; + } + else if (fieldType == TypeBool || fieldType == TypeFlag) + { + pFieldTypeDescription = "xs:boolean"; + } + else if (fieldType == TypePoint2F) + { + pFieldTypeDescription = "Point2F_ConsoleType"; + } + else if (fieldType == TypePoint2I) + { + pFieldTypeDescription = "Point2I_ConsoleType"; + } + else if (fieldType == TypeRectI) + { + pFieldTypeDescription = "RectI_ConsoleType"; + } + else if (fieldType == TypeRectF) + { + pFieldTypeDescription = "RectF_ConsoleType"; + } + else if (fieldType == TypeColorF) + { + pFieldTypeDescription = "ColorF_ConsoleType"; + } + else if (fieldType == TypeColorI) + { + pFieldTypeDescription = "ColorI_ConsoleType"; + } + else if (fieldType == TypeAssetId/* || + fieldType == TypeImageAssetPtr || + fieldType == TypeAnimationAssetPtr || + fieldType == TypeAudioAssetPtr*/) + { + pFieldTypeDescription = "AssetId_ConsoleType"; + } + + // Set attribute type. + pAttributeElement->SetAttribute("type", pFieldTypeDescription); + //} + + pAttributeElement->SetAttribute("use", "optional"); + return pAttributeElement; + } + + String g_sanitize_schema_element_name(String buffer) + { + return buffer.replace("(", "") + .replace(")", ""); + } + bool Taml::generateTamlSchema() { // Fetch any TAML Schema file reference. @@ -1298,8 +1407,8 @@ ImplementEnumType(_TamlFormatMode, pSchemaElement->LinkEndChild(pComplexTypeElement); // Add sequence. - tinyxml2::XMLElement* pSequenceElement = schemaDocument.NewElement("xs:sequence"); - pComplexTypeElement->LinkEndChild(pSequenceElement); + tinyxml2::XMLElement* pAllElement = schemaDocument.NewElement("xs:all"); + pComplexTypeElement->LinkEndChild(pAllElement); // Fetch container child class. AbstractClassRep* pContainerChildClass = pType->getContainerChildClass(true); @@ -1311,7 +1420,7 @@ ImplementEnumType(_TamlFormatMode, tinyxml2::XMLElement* pChoiceElement = schemaDocument.NewElement("xs:choice"); pChoiceElement->SetAttribute("minOccurs", 0); pChoiceElement->SetAttribute("maxOccurs", "unbounded"); - pSequenceElement->LinkEndChild(pChoiceElement); + pAllElement->LinkEndChild(pChoiceElement); // Find child group. HashTable::Iterator childGroupItr = childGroups.find(pContainerChildClass); @@ -1369,7 +1478,74 @@ ImplementEnumType(_TamlFormatMode, continue; // Call schema generation function. - customSchemaFn(pType, pSequenceElement); + customSchemaFn(pType, pAllElement); + } + + // Fetch field list. + const AbstractClassRep::FieldList& fields = pType->mFieldList; + + // Fetch field count. + const S32 fieldCount = fields.size(); + + // Generate array attribute groups + for (S32 index = 0; index < fieldCount; ++index) + { + // Fetch field. + const AbstractClassRep::Field& field = fields[index]; + + if (field.type == AbstractClassRep::StartArrayFieldType) + { + // Add the top-level array identifier + tinyxml2::XMLElement* pArrayElement = schemaDocument.NewElement("xs:element"); + dSprintf(buffer, sizeof(buffer), "%s.%s", pType->getClassName(), g_sanitize_schema_element_name(field.pGroupname).c_str()); + pArrayElement->SetAttribute("name", buffer); + pArrayElement->SetAttribute("minOccurs", 0); + pAllElement->LinkEndChild(pArrayElement); + + // Inline type specification + tinyxml2::XMLElement* pArrayComplexTypeElement = schemaDocument.NewElement("xs:complexType"); + pArrayElement->LinkEndChild(pArrayComplexTypeElement); + + // Add the actual (repeating) array elements + tinyxml2::XMLElement* pInnerArrayElement = schemaDocument.NewElement("xs:element"); + pInnerArrayElement->SetAttribute("name", g_sanitize_schema_element_name(field.pFieldname).c_str()); + pInnerArrayElement->SetAttribute("minOccurs", 0); + pInnerArrayElement->SetAttribute("maxOccurs", field.elementCount); + pArrayComplexTypeElement->LinkEndChild(pInnerArrayElement); + + // Inline type specification + tinyxml2::XMLElement* pInnerComplexTypeElement = schemaDocument.NewElement("xs:complexType"); + pInnerArrayElement->LinkEndChild(pInnerComplexTypeElement); + + // Add a reference to the attribute group for the array + tinyxml2::XMLElement* pInnerAttributeGroupElement = schemaDocument.NewElement("xs:attributeGroup"); + dSprintf(buffer, sizeof(buffer), "%s_%s_Array_Fields", pType->getClassName(), g_sanitize_schema_element_name(field.pFieldname).c_str()); + pInnerAttributeGroupElement->SetAttribute("ref", buffer); + pInnerComplexTypeElement->LinkEndChild(pInnerAttributeGroupElement); + + // Add the attribute group itself + tinyxml2::XMLElement* pFieldAttributeGroupElement = schemaDocument.NewElement("xs:attributeGroup"); + pFieldAttributeGroupElement->SetAttribute("name", buffer); + pSchemaElement->LinkEndChild(pFieldAttributeGroupElement); + + // Keep adding fields to attribute group until we hit the end of the array + for (; index < fieldCount; ++index) + { + const AbstractClassRep::Field& array_field = fields[index]; + if (array_field.type == AbstractClassRep::EndArrayFieldType) + { + break; + } + + tinyxml2::XMLElement* pAttributeElement = g__write_schema_attribute_element(array_field, pType, schemaDocument); + if (pAttributeElement == NULL) + { + continue; + } + + pFieldAttributeGroupElement->LinkEndChild(pAttributeElement); + } + } } // Generate field attribute group. @@ -1378,115 +1554,31 @@ ImplementEnumType(_TamlFormatMode, pFieldAttributeGroupElement->SetAttribute("name", buffer); pSchemaElement->LinkEndChild(pFieldAttributeGroupElement); - // Fetch field list. - const AbstractClassRep::FieldList& fields = pType->mFieldList; - - // Fetcj field count. - const S32 fieldCount = fields.size(); - // Iterate static fields (in reverse as most types are organized from the root-fields up). for (S32 index = fieldCount - 1; index > 0; --index) { // Fetch field. const AbstractClassRep::Field& field = fields[index]; - // Skip if not a data field. - if (field.type == AbstractClassRep::DeprecatedFieldType || - field.type == AbstractClassRep::StartGroupFieldType || - field.type == AbstractClassRep::EndGroupFieldType) + // Skip fields inside arrays + if (field.type == AbstractClassRep::EndArrayFieldType) + { + for (; index > 0; --index) + { + if (field.type == AbstractClassRep::StartArrayFieldType) + { + break; + } + } continue; + } - // Skip if the field root is not this type. - if (pType->findFieldRoot(field.pFieldname) != pType) + tinyxml2::XMLElement* pAttributeElement = g__write_schema_attribute_element(field, pType, schemaDocument); + if (pAttributeElement == NULL) + { continue; - - // Add attribute element. - tinyxml2::XMLElement* pAttributeElement = schemaDocument.NewElement("xs:attribute"); - pAttributeElement->SetAttribute("name", field.pFieldname); - - // Handle the console type appropriately. - const S32 fieldType = (S32)field.type; - - /* - // Is the field an enumeration? - if ( fieldType == TypeEnum ) - { - // Yes, so add attribute type. - tinyxml2::XMLElement* pAttributeSimpleTypeElement = schemaDocument.NewElement( "xs:simpleType" ); - pAttributeElement->LinkEndChild( pAttributeSimpleTypeElement ); - - // Add restriction element. - tinyxml2::XMLElement* pAttributeRestrictionElement = schemaDocument.NewElement( "xs:restriction" ); - pAttributeRestrictionElement->SetAttribute( "base", "xs:string" ); - pAttributeSimpleTypeElement->LinkEndChild( pAttributeRestrictionElement ); - - // Yes, so fetch enumeration count. - const S32 enumCount = field.table->size; - - // Iterate enumeration. - for( S32 index = 0; index < enumCount; ++index ) - { - // Add enumeration element. - tinyxml2::XMLElement* pAttributeEnumerationElement = schemaDocument.NewElement( "xs:enumeration" ); - pAttributeEnumerationElement->SetAttribute( "value", field.table->table[index].label ); - pAttributeRestrictionElement->LinkEndChild( pAttributeEnumerationElement ); - } - } - else - {*/ - // No, so assume it's a string type initially. - const char* pFieldTypeDescription = "xs:string"; - - // Handle known types. - if (fieldType == TypeF32) - { - pFieldTypeDescription = "xs:float"; - } - else if (fieldType == TypeS8 || fieldType == TypeS32) - { - pFieldTypeDescription = "xs:int"; - } - else if (fieldType == TypeBool || fieldType == TypeFlag) - { - pFieldTypeDescription = "xs:boolean"; - } - else if (fieldType == TypePoint2F) - { - pFieldTypeDescription = "Point2F_ConsoleType"; - } - else if (fieldType == TypePoint2I) - { - pFieldTypeDescription = "Point2I_ConsoleType"; - } - else if (fieldType == TypeRectI) - { - pFieldTypeDescription = "RectI_ConsoleType"; - } - else if (fieldType == TypeRectF) - { - pFieldTypeDescription = "RectF_ConsoleType"; - } - else if (fieldType == TypeColorF) - { - pFieldTypeDescription = "ColorF_ConsoleType"; - } - else if (fieldType == TypeColorI) - { - pFieldTypeDescription = "ColorI_ConsoleType"; - } - else if (fieldType == TypeAssetId/* || - fieldType == TypeImageAssetPtr || - fieldType == TypeAnimationAssetPtr || - fieldType == TypeAudioAssetPtr*/) - { - pFieldTypeDescription = "AssetId_ConsoleType"; } - // Set attribute type. - pAttributeElement->SetAttribute("type", pFieldTypeDescription); - //} - - pAttributeElement->SetAttribute("use", "optional"); pFieldAttributeGroupElement->LinkEndChild(pAttributeElement); } From c14c9b78c01a526d8a540ecdcecb9f5c267c0732 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Wed, 20 Apr 2022 15:53:29 -0500 Subject: [PATCH 082/145] drop the prior requirement for a createcomposite to have a minimum of roughness and metalness. also kick it off if it's got just an ao map. --- Engine/source/gfx/gfxTextureManager.cpp | 2 +- Engine/source/materials/processedMaterial.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index 733f3ba7f..53ebf801c 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -1238,7 +1238,7 @@ GFXTextureObject *GFXTextureManager::createCompositeTexture(GBitmap*bmp[4], U32 if (bmp[2]) bChan = bmp[2]->getChanelValueAt(x, y, inputKey[2]); else - bChan = 255; + bChan = 0; if (bmp[3]) aChan = bmp[3]->getChanelValueAt(x, y, inputKey[3]); diff --git a/Engine/source/materials/processedMaterial.cpp b/Engine/source/materials/processedMaterial.cpp index 63150fd94..8fa7d7e28 100644 --- a/Engine/source/materials/processedMaterial.cpp +++ b/Engine/source/materials/processedMaterial.cpp @@ -491,7 +491,7 @@ void ProcessedMaterial::_setStageData() } else { - if ((mMaterial->getRoughMap(i) != StringTable->EmptyString()) && (mMaterial->getMetalMap(i) != StringTable->EmptyString())) + if ((mMaterial->getAOMap(i) != StringTable->EmptyString()) || (mMaterial->getRoughMap(i) != StringTable->EmptyString()) || (mMaterial->getMetalMap(i) != StringTable->EmptyString())) { U32 inputKey[4]; inputKey[0] = mMaterial->mAOChan[i]; From 70a70dfc102e2763420735e075381c504277bcec Mon Sep 17 00:00:00 2001 From: JeffR Date: Sat, 23 Apr 2022 16:07:36 -0500 Subject: [PATCH 083/145] Fixes issue with some of the On/Off options not properly toggling in the OptionsMenu Adds staged loading/generation of preview images for image, shape, material and terrain material types to improve navigation responsiveness Disabled lookup of bitmap info of image assets for tooltip metadata as it was causing major hangs when the images were high resolution Added function so Import new File button on AB interface will correctly prompt to find and then import in a new file Fixed theming of AssetBrowser preview card profiles to improve readability Fixed theming of ToolsGuiTextListProfile to improve readability Fixed issue where trying to import in a splat map for importing terrain data could fail due to not having full path when trying to load the bitmap's channel data Corrected Import Terrain Heightmap item in menubar to prompt creation of a new terrain asset in addition to opening the import terraindata window to avoid missed steps foc creation --- .../game/data/UI/guis/optionsMenu.tscript | 8 +- .../tools/assetBrowser/guis/assetBrowser.gui | 1 + .../assetBrowser/scripts/assetBrowser.tscript | 34 ++++++- .../scripts/assetTypes/image.tscript | 91 +++++++++-------- .../scripts/assetTypes/material.tscript | 97 +++++++++++-------- .../scripts/assetTypes/shape.tscript | 83 ++++++++++------ .../assetTypes/terrainMaterial.tscript | 71 ++++++++------ .../assetBrowser/scripts/newAsset.tscript | 27 ++++++ .../assetBrowser/scripts/profiles.tscript | 31 +++--- .../game/tools/gui/profiles.ed.tscript | 6 ++ .../worldEditor/gui/guiTerrainImportGui.gui | 2 +- .../worldEditor/scripts/menus.ed.tscript | 2 +- 12 files changed, 288 insertions(+), 165 deletions(-) diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript index aa343f81f..40540c1ab 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript @@ -836,11 +836,11 @@ function OptionsMenuSettingsList::addOptionBoolRow(%this, %label, %targetPrefVar if(%qualityLevelList $= $yesNoList && isInt(%defaultValue)) { - %defaultValue = convertBoolToYesNo(!%defaultValue); + %defaultValue = convertBoolToYesNo(%defaultValue); } else if(%qualityLevelList $= $onOffList && isInt(%defaultValue)) { - %defaultValue = convertBoolToOnOff(!%defaultValue); + %defaultValue = convertBoolToOnOff(%defaultValue); } return %this.addOptionRow(%label, %targetPrefVar, %qualityLevelList, @@ -995,9 +995,11 @@ function MenuOptionsButton::onChange(%this) OptionsMenu.unappliedChanges.add(%targetVar, "\"" @ %saveReadyValue @ "\"" ); } else + { OptionsMenu.unappliedChanges.setValue("\"" @ %saveReadyValue @ "\"", %prefIndex); } } + } else if(%optionMode == 1) { %currentValue = %this.getValue(); @@ -1009,7 +1011,9 @@ function MenuOptionsButton::onChange(%this) OptionsMenu.unappliedChanges.add(%targetVar, "\"" @ %currentValue @ "\"" ); } else + { OptionsMenu.unappliedChanges.setValue("\"" @ %currentValue @ "\"", %prefIndex); + } } //Update the UI in case there's responsive logic diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui index 29c282c5b..c4df19d95 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui @@ -276,6 +276,7 @@ $guiContent = new GuiControl(AssetBrowser) { hovertime = "1000"; isContainer = "0"; internalName = "ImportAssetButton"; + command="AssetBrowser.importNewFile();"; canSave = "1"; canSaveDynamicFields = "0"; }; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index fd3a7b213..3dd7b881d 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript @@ -368,8 +368,6 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) %this.previewData.doubleClickCommand = ""; } - AssetPreviewArray.empty(); - %previewImage = "core/art/warnmat"; if(/*%moduleName !$= "" && */ModuleDatabase.findModule(%moduleName, 1) !$= "") @@ -512,6 +510,7 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) textLocation = "Bottom"; extent = %previewSize.x SPC %previewSize.y + %textBottomPad; buttonType = "RadioButton"; + buttonMargin = "0 -10"; profile = ToolsGuiDefaultProfile; }; @@ -528,11 +527,15 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) %previewButton.iconLocation = "Left"; %previewButton.textLocation = "Right"; %previewButton.setextent(120,20); + + AssetBrowser.previewListMode = true; } else { %size = %previewSize.x * %previewScaleSize; %previewButton.setextent(%size,%size + %textBottomPad); + + AssetBrowser.previewListMode = false; } //%previewButton.extent = %previewSize.x + %previewBounds SPC %previewSize.y + %previewBounds + 24; @@ -549,6 +552,8 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) %doubleClickCommand = "AssetBrowser.editAsset( "@%assetDesc@" );"; } + %this.previewData.previewLoaded = true; + //Build out the preview %buildCommand = %this @ ".build" @ %assetType @ "Preview(\"" @ %assetDesc @ "\"," @ %this.previewData @ ");"; eval(%buildCommand); @@ -579,7 +584,8 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) AssetBrowser-->assetList.add(%previewButton); // add to the array object for reference later - AssetPreviewArray.add( %previewButton, %this.previewData.previewImage ); + if(%this.previewData.previewLoaded == false) + AssetPreviewArray.add( %previewButton ); } function AssetBrowser::refresh(%this) @@ -607,6 +613,25 @@ function AssetBrowser::doRefresh(%this) %this.dirty = false; } } + +function AssetBrowser::populatePreviewImages(%this) +{ + echo("AssetBrowser::populatePreviewImages() - Previews to generate: " @ AssetPreviewArray.count()); + for(%i=0; %i < AssetPreviewArray.count(); %i++) + { + %previewButton = AssetPreviewArray.getKey(%i); + %type = %previewButton.assetType; + + echo(" - Generating preview for asset: " @ %previewButton.moduleName @ ":" @ %previewButton.assetName); + + AssetBrowser.call("generate" @ %previewButton.assetType @ "PreviewImage", %previewButton); + AssetPreviewArray.erase(%i); + + echo(" - done, scheduling another pass"); + AssetBrowser.schedule(32, "populatePreviewImages"); + return; + } +} // // /*function AssetPreviewButton::onClick(%this) @@ -716,7 +741,6 @@ function AssetBrowser::loadDirectories( %this ) //} // } - AssetPreviewArray.empty(); AssetBrowser-->filterTree.buildVisibleTree(true); @@ -1776,6 +1800,8 @@ function AssetBrowser::doRebuildAssetArray(%this) for(%i=0; %i < $AssetBrowser::AssetArray.count(); %i++) AssetBrowser.buildAssetPreview( $AssetBrowser::AssetArray.getValue(%i), $AssetBrowser::AssetArray.getKey(%i) ); + //Queue population of any non-Type Card preview images + AssetBrowser.schedule(32, "populatePreviewImages"); AssetBrowser_FooterText.text = %finalAssetCount @ " Assets"; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript index 167b3f197..f118fc078 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript @@ -175,20 +175,48 @@ function AssetBrowser::importImageAsset(%this, %assetItem) AssetDatabase.refreshAsset(%assetId); } -function AssetBrowser::buildImageAssetPreview(%this, %assetDef, %previewData, %forcePreviewRegenerate) +function AssetBrowser::buildImageAssetPreview(%this, %assetDef, %previewData) { - if(%forcePreviewRegenerate $= "") - %forcePreviewRegenerate = false; + //%module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(%assetDef.getImagePath()))); - %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(%assetDef.getImagePath()))); - %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/"; + %previewData.previewImage = "ToolsModule:genericAssetIcon_image"; + %previewData.previewLoaded = false; //this marks it for loading progressively later + + %previewData.assetName = %assetDef.assetName; + %previewData.assetPath = %assetDef.scriptFile; + + %previewData.assetFriendlyName = %assetDef.assetName; + %previewData.assetDesc = %assetDef.description; + + //image info + //%info = %assetDef.getImageInfo(); + + %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ "\n" @ + "Asset Type: Image Asset\n" @ + "Asset Definition ID: " @ %assetDef @ "\n" @ + "Image Type: " @ %assetDef.imageType @ "\n" @ + /* "Format: " @ getWord(%info, 0) @ "\n" @ + "Height: " @ getWord(%info, 1) @ "\n" @ + "Width: " @ getWord(%info, 2) @ "\n" @ + "Depth: " @ getWord(%info, 3) @ "\n" @ */ + "Image File path: " @ %assetDef.getImagePath(); +} + +function AssetBrowser::generateImageAssetPreviewImage(%this, %previewButton, %forceRegenerate) +{ + if(%forceRegenerate $= "") + %forceRegenerate = false; + + %previewPath = "tools/resources/previewCache/" @ %previewButton.moduleName @ "/"; if(!IsDirectory(%previewPath)) { %this.dirHandler.createFolder(%previewPath); } - %generatePreview = false; + %assetId = %previewButton.moduleName @ ":" @ %previewButton.assetName; + + %assetDef = AssetDatabase.acquireAsset(%assetId); %previewFilePath = %previewPath @ %assetDef.assetName @ "_Preview.png"; if(!isFile(%previewFilePath) || (compareFileTimes(%assetDef.getImagePath(), %previewFilePath) == 1)) @@ -196,12 +224,10 @@ function AssetBrowser::buildImageAssetPreview(%this, %assetDef, %previewData, %f %generatePreview = true; } - %previewAssetName = %module.moduleId @ "_" @ %assetDef.assetName @ "_PreviewImage"; + %previewAssetName = %previewButton.moduleName @ "_" @ %assetDef.assetName @ "_PreviewImage"; - if(%generatePreview || %forcePreviewRegenerate) + if(%generatePreview || %forceRegenerate) { - displayEditorLoadingGui("Generating Image Asset Preview..."); - %success = saveScaledImage(%assetDef.getImagePath(), %previewFilePath, EditorSettings.value("Assets/Browser/PreviewImageSize")); if(%success) @@ -222,49 +248,28 @@ function AssetBrowser::buildImageAssetPreview(%this, %assetDef, %previewData, %f %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + + if(!%success) + { + return false; //failed to register the preview image for some reason? } } - else - { - %previewFilePath = %assetDef.getImagePath(); - %previewAssetName = %module.moduleId @ ":" @ %assetDef.assetName; + + %previewButton.bitmapAsset = %previewAssetName; + return true; } - - hideEditorLoadingGui(); } else { - %previewAssetName = "ToolsModule:" @ %previewAssetName; - } - - //Revalidate. If it didn't work, just use the default placeholder one - if(!isFile(%previewFilePath)) + //just map the existing one then + if(AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) { - %previewData.previewImage = "ToolsModule:genericAssetIcon_image"; + %previewButton.bitmapAsset = "ToolsModule:" @ %previewAssetName; + return true; } - else - { - %previewData.previewImage = %previewAssetName; } - %previewData.assetName = %assetDef.assetName; - %previewData.assetPath = %assetDef.scriptFile; - - %previewData.assetFriendlyName = %assetDef.assetName; - %previewData.assetDesc = %assetDef.description; - - //image info - %info = %assetDef.getImageInfo(); - - %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ "\n" @ - "Asset Type: Image Asset\n" @ - "Asset Definition ID: " @ %assetDef @ "\n" @ - "Image Type: " @ %assetDef.imageType @ "\n" @ - "Format: " @ getWord(%info, 0) @ "\n" @ - "Height: " @ getWord(%info, 1) @ "\n" @ - "Width: " @ getWord(%info, 2) @ "\n" @ - "Depth: " @ getWord(%info, 3) @ "\n" @ - "Image File path: " @ %assetDef.getImagePath(); + return false; } //Renames the asset diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index d6d48819c..12c6d4e3d 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript @@ -426,8 +426,43 @@ function AssetBrowser::importMaterialAsset(%this, %assetItem) function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData, %forcePreviewRegenerate) { - if(%forcePreviewRegenerate $= "") - %forcePreviewRegenerate = false; + %previewData.previewImage = "ToolsModule:genericAssetIcon_image"; + %previewData.previewLoaded = false; //this marks it for loading progressively later + + %previewData.assetName = %assetDef.assetName; + %previewData.assetPath = %assetDef.scriptFile; + + %previewData.assetFriendlyName = %assetDef.assetName; + %previewData.assetDesc = %assetDef.description; + + if(%this.selectMode) + %previewData.doubleClickCommand = "AssetBrowser.selectAsset( AssetBrowser.selectedAsset );"; + else + %previewData.doubleClickCommand = "AssetBrowser.editAsset( "@%assetDef@" );"; + + %definitionPath = %assetDef.getScriptPath(); + if(%definitionPath $= "") + %definitionPath = %assetDef.getFilename(); + + %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ + "\nAsset Type: Material Asset" @ + "\nAsset Definition ID: " @ %assetDef @ + "\nDefinition Path: " @ %definitionPath; + + if(!%this.selectMode) + { + %previewData.doubleClickCommand = "AssetBrowser.editAsset( "@%assetDef@" );"; + } +} + +function AssetBrowser::generateMaterialAssetPreviewImage(%this, %previewButton, %forceRegenerate) +{ + if(%forceRegenerate $= "") + %forceRegenerate = false; + + %assetId = %previewButton.moduleName @ ":" @ %previewButton.assetName; + + %assetDef = AssetDatabase.acquireAsset(%assetId); %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(AssetDatabase.getAssetFilePath(%assetDef.getAssetId())))); %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/"; @@ -456,10 +491,8 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData, %previewAssetName = %module.moduleId @ "_" @ %assetDef.assetName @ "_PreviewImage"; - if(%generatePreview || %forcePreviewRegenerate) + if(%generatePreview || %forceRegenerate) { - displayEditorLoadingGui("Generating Material Asset Preview..."); - if(isObject(%assetDef.materialDefinitionName)) { //real fast, we'll be 100% sure that the image resource we need is loaded @@ -490,50 +523,28 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData, %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + + if(!%success) + { + return false; //failed to register the preview image for some reason? } } - else + + %previewButton.bitmapAsset = %previewAssetName; + return true; + } + } + else + { + //just map the existing one then + if(AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) { - error("Failed to generate preview for material: " @ %assetDef.materialDefinitionName); + %previewButton.bitmapAsset = "ToolsModule:" @ %previewAssetName; + return true; } - - hideEditorLoadingGui(); - } - - //Revalidate. If it didn't work, just use the default placeholder one - if(!isFile(%previewFilePath)) - { - %previewData.previewImage = "ToolsModule:materialIcon_image"; - } - else - { - %previewData.previewImage = "ToolsModule:" @ %previewAssetName; } - %previewData.assetName = %assetDef.assetName; - %previewData.assetPath = %assetDef.scriptFile; - - %previewData.assetFriendlyName = %assetDef.assetName; - %previewData.assetDesc = %assetDef.description; - - if(%this.selectMode) - %previewData.doubleClickCommand = "AssetBrowser.selectAsset( AssetBrowser.selectedAsset );"; - else - %previewData.doubleClickCommand = "AssetBrowser.editAsset( "@%assetDef@" );"; - - %definitionPath = %assetDef.getScriptPath(); - if(%definitionPath $= "") - %definitionPath = %assetDef.getFilename(); - - %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ - "\nAsset Type: Material Asset" @ - "\nAsset Definition ID: " @ %assetDef @ - "\nDefinition Path: " @ %definitionPath; - - if(!%this.selectMode) - { - %previewData.doubleClickCommand = "AssetBrowser.editAsset( "@%assetDef@" );"; - } + return false; } function AssetBrowser::onMaterialAssetEditorDropped(%this, %assetDef, %position) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript index c70750e90..4195cf1b9 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript @@ -265,8 +265,44 @@ function AssetBrowser::importShapeAsset(%this, %assetItem) function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData, %forcePreviewRegenerate) { - if(%forcePreviewRegenerate $= "") - %forcePreviewRegenerate = false; + %previewData.previewImage = "ToolsModule:genericAssetIcon_image"; + %previewData.previewLoaded = false; //this marks it for loading progressively later + + %previewData.assetName = %assetDef.assetName; + %previewData.assetPath = %assetDef.fileName; + + %previewData.assetFriendlyName = %assetDef.assetName; + %previewData.assetDesc = %assetDef.description; + %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ "\n" @ + "Asset Type: Shape Asset\n" @ + "Asset Definition ID: " @ %assetDef @ "\n" @ + "Shape File path: " @ %assetDef.getShapePath(); + + if(%this.selectMode) + { + %previewData.doubleClickCommand = "AssetBrowser.selectAsset( AssetBrowser.selectedAsset );"; + } + else + { + if(EditorSettings.value("Assets/Browser/doubleClickAction", "Edit Asset") $= "Edit Asset") + { + %previewData.doubleClickCommand = "AssetBrowser.editAsset( "@%assetDef@" );"; + } + else + { + %previewData.doubleClickCommand = "AssetBrowser.onShapeAssetEditorDropped( "@%assetDef@" );"; + } + } +} + +function AssetBrowser::generateShapeAssetPreviewImage(%this, %previewButton, %forceRegenerate) +{ + if(%forceRegenerate $= "") + %forceRegenerate = false; + + %assetId = %previewButton.moduleName @ ":" @ %previewButton.assetName; + + %assetDef = AssetDatabase.acquireAsset(%assetId); %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(%assetDef.getShapePath()))); %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/"; @@ -286,10 +322,8 @@ function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData, %f %previewAssetName = %module.moduleId @ "_" @ %assetDef.assetName @ "_PreviewImage"; - if(%generatePreview || %forcePreviewRegenerate) + if(%generatePreview || %forceRegenerate) { - displayEditorLoadingGui("Generating Shape Asset Preview..."); - //real fast, we'll be 100% sure that the image resource we need is loaded %matSlot0AssetId = %assetDef.materialSlot0; @@ -322,46 +356,31 @@ function AssetBrowser::buildShapeAssetPreview(%this, %assetDef, %previewData, %f %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); - } - hideEditorLoadingGui(); + if(!%success) + { + return false; //failed to register the preview image for some reason? } - - //Revalidate. If it didn't work, just use the default placeholder one - if(!isFile(%previewFilePath)) - { - %previewData.previewImage = "ToolsModule:genericAssetIcon_image"; } else { - %previewData.previewImage = "ToolsModule:" @ %previewAssetName; + %previewAssetName = "ToolsModule:" @ %previewAssetName; } - %previewData.assetName = %assetDef.assetName; - %previewData.assetPath = %assetDef.fileName; - - %previewData.assetFriendlyName = %assetDef.assetName; - %previewData.assetDesc = %assetDef.description; - %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ "\n" @ - "Asset Type: Shape Asset\n" @ - "Asset Definition ID: " @ %assetDef @ "\n" @ - "Shape File path: " @ %assetDef.getShapePath(); - - if(%this.selectMode) - { - %previewData.doubleClickCommand = "AssetBrowser.selectAsset( AssetBrowser.selectedAsset );"; + %previewButton.bitmapAsset = %previewAssetName; + return true; } else { - if(EditorSettings.value("Assets/Browser/doubleClickAction", "Edit Asset") $= "Edit Asset") + //just map the existing one then + if(AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) { - %previewData.doubleClickCommand = "AssetBrowser.editAsset( "@%assetDef@" );"; - } - else - { - %previewData.doubleClickCommand = "AssetBrowser.onShapeAssetEditorDropped( "@%assetDef@" );"; + %previewButton.bitmapAsset = "ToolsModule:" @ %previewAssetName; + return true; } } + + return false; } function AssetBrowser::onShapeAssetEditorDropped(%this, %assetDef, %position) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript index 8176d0da0..ded898e9f 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript @@ -111,8 +111,35 @@ function AssetBrowser::moveTerrainMaterialAsset(%this, %assetDef, %destination) function AssetBrowser::buildTerrainMaterialAssetPreview(%this, %assetDef, %previewData, %forcePreviewRegenerate) { - if(%forcePreviewRegenerate $= "") - %forcePreviewRegenerate = false; + %previewData.previewImage = "ToolsModule:genericAssetIcon_image"; + %previewData.previewLoaded = false; //this marks it for loading progressively later + + %previewData.assetName = %assetDef.assetName; + %previewData.assetPath = ""; + %previewData.doubleClickCommand = ""; + + %previewData.assetFriendlyName = %assetDef.gameObjectName; + %previewData.assetDesc = %assetDef.description; + %previewData.tooltip = %assetDef.gameObjectName; + + %definitionPath = %assetDef.getScriptPath(); + if(%definitionPath $= "") + %definitionPath = %assetDef.getFilename(); + + %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ + "\nAsset Type: Terrain Material Asset" @ + "\nAsset Definition ID: " @ %assetDef @ + "\nDefinition Path: " @ %definitionPath; +} + +function AssetBrowser::generateTerrainMaterialAssetPreviewImage(%this, %previewButton, %forceRegenerate) +{ + if(%forceRegenerate $= "") + %forceRegenerate = false; + + %assetId = %previewButton.moduleName @ ":" @ %previewButton.assetName; + + %assetDef = AssetDatabase.acquireAsset(%assetId); %module = %this.dirHandler.getModuleFromAddress(makeRelativePath(filePath(AssetDatabase.getAssetFilePath(%assetDef.getAssetId())))); %previewPath = "tools/resources/previewCache/" @ %module.moduleId @ "/"; @@ -141,10 +168,8 @@ function AssetBrowser::buildTerrainMaterialAssetPreview(%this, %assetDef, %previ %previewAssetName = %module.moduleId @ "_" @ %assetDef.assetName @ "_PreviewImage"; - if(%generatePreview || %forcePreviewRegenerate) + if(%generatePreview || %forceRegenerate) { - displayEditorLoadingGui("Generating Material Asset Preview..."); - if(isObject(%assetDef.materialDefinitionName)) { %previewShapeDef = AssetDatabase.acquireAsset("ToolsModule:previewSphereShape"); @@ -169,38 +194,28 @@ function AssetBrowser::buildTerrainMaterialAssetPreview(%this, %assetDef, %previ %toolsModuleDef = ModuleDatabase.findModule("ToolsModule",1); %success = AssetDatabase.addDeclaredAsset(%toolsModuleDef, %previewImgAssetPath); + + if(!%success) + { + return false; //failed to register the preview image for some reason? } } - hideEditorLoadingGui(); + %previewButton.bitmapAsset = %previewAssetName; + return true; } - - //Revalidate. If it didn't work, just use the default placeholder one - if(!isFile(%previewFilePath)) - { - %previewData.previewImage = "ToolsModule:terrainMaterialIcon_image"; } else { - %previewData.previewImage = "ToolsModule:" @ %previewAssetName; + //just map the existing one then + if(AssetDatabase.isDeclaredAsset("ToolsModule:" @ %previewAssetName)) + { + %previewButton.bitmapAsset = "ToolsModule:" @ %previewAssetName; + return true; + } } - %previewData.assetName = %assetDef.assetName; - %previewData.assetPath = ""; - %previewData.doubleClickCommand = ""; - - %previewData.assetFriendlyName = %assetDef.gameObjectName; - %previewData.assetDesc = %assetDef.description; - %previewData.tooltip = %assetDef.gameObjectName; - - %definitionPath = %assetDef.getScriptPath(); - if(%definitionPath $= "") - %definitionPath = %assetDef.getFilename(); - - %previewData.tooltip = "Asset Name: " @ %assetDef.assetName @ - "\nAsset Type: Terrain Material Asset" @ - "\nAsset Definition ID: " @ %assetDef @ - "\nDefinition Path: " @ %definitionPath; + return false; } function GuiInspectorTypeTerrainMaterialAssetPtr::onClick( %this, %fieldName ) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript index e3a813862..c4fe9b537 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.tscript @@ -139,6 +139,33 @@ function newAssetUpdatePath(%newPath) NewAssetTargetModule.text = AssetBrowser.dirHandler.getModuleFromAddress(AssetBrowser.dirHandler.currentAddress).ModuleId; } +// +function AssetBrowser::importNewFile(%this) +{ + %importingPath = ""; + + %dlg = new OpenFileDialog() + { + Filters = "(All Files (*.*)|*.*|"; + DefaultFile = ""; + ChangePath = false; + MustExist = true; + MultipleFiles = false; + forceRelativePath = false; + }; + + if ( %dlg.Execute() ) + { + %importingPath = makeFullPath(%dlg.FileName); + } + + %dlg.delete(); + + AssetBrowser.onBeginDropFiles(); + AssetBrowser.onDropFile(%importingPath); + AssetBrowser.onEndDropFiles(); +} + // function NewAssetTargetModule::onSelect(%this, %idx, %idy) { diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/profiles.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/profiles.tscript index b8825155e..5c3f03ba7 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/profiles.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/profiles.tscript @@ -1,7 +1,7 @@ singleton GuiControlProfile(AssetBrowserPreviewImageAsset : ToolsGuiDefaultProfile) { - fillColor = "128 128 128 255"; //hovered/selected - //fillColorNA = "230 126 0 255"; //fill color default + fillcolor = EditorSettings.value("Theme/windowBackgroundColor"); + fillColorHL = EditorSettings.value("Theme/fieldBGHLColor"); border = true; borderColor = "230 126 0 255"; @@ -10,7 +10,8 @@ singleton GuiControlProfile(AssetBrowserPreviewImageAsset : ToolsGuiDefaultProfi singleton GuiControlProfile(AssetBrowserPreviewMaterialAsset : ToolsGuiDefaultProfile) { - fillColor = "128 128 128 255"; //hovered/selected + fillcolor = EditorSettings.value("Theme/windowBackgroundColor"); + fillColorHL = EditorSettings.value("Theme/fieldBGHLColor"); border = true; borderColor = "0 100 0 255"; @@ -19,7 +20,8 @@ singleton GuiControlProfile(AssetBrowserPreviewMaterialAsset : ToolsGuiDefaultPr singleton GuiControlProfile(AssetBrowserPreviewShapeAsset : ToolsGuiDefaultProfile) { - fillColor = "128 128 128 255"; //hovered/selected + fillcolor = EditorSettings.value("Theme/windowBackgroundColor"); + fillColorHL = EditorSettings.value("Theme/fieldBGHLColor"); border = true; borderColor = "0 0 200 255"; @@ -28,7 +30,8 @@ singleton GuiControlProfile(AssetBrowserPreviewShapeAsset : ToolsGuiDefaultProfi singleton GuiControlProfile(AssetBrowserPreviewShapeAnimationAsset : ToolsGuiDefaultProfile) { - fillColor = "128 128 128 255"; //hovered/selected + fillcolor = EditorSettings.value("Theme/windowBackgroundColor"); + fillColorHL = EditorSettings.value("Theme/fieldBGHLColor"); border = true; borderColor = "0 0 200 255"; @@ -37,7 +40,8 @@ singleton GuiControlProfile(AssetBrowserPreviewShapeAnimationAsset : ToolsGuiDef singleton GuiControlProfile(AssetBrowserPreviewSoundAsset : ToolsGuiDefaultProfile) { - fillColor = "128 128 128 255"; //hovered/selected + fillcolor = EditorSettings.value("Theme/windowBackgroundColor"); + fillColorHL = EditorSettings.value("Theme/fieldBGHLColor"); border = true; borderColor = "75 101 135 255"; @@ -46,7 +50,8 @@ singleton GuiControlProfile(AssetBrowserPreviewSoundAsset : ToolsGuiDefaultProfi singleton GuiControlProfile(AssetBrowserPreviewTerrainAsset : ToolsGuiDefaultProfile) { - fillColor = "128 128 128 255"; //hovered/selected + fillcolor = EditorSettings.value("Theme/windowBackgroundColor"); + fillColorHL = EditorSettings.value("Theme/fieldBGHLColor"); border = true; borderColor = "200 198 198 255"; @@ -55,7 +60,8 @@ singleton GuiControlProfile(AssetBrowserPreviewTerrainAsset : ToolsGuiDefaultPro singleton GuiControlProfile(AssetBrowserPreviewTerrainMaterialAsset : ToolsGuiDefaultProfile) { - fillColor = "128 128 128 255"; //hovered/selected + fillcolor = EditorSettings.value("Theme/windowBackgroundColor"); + fillColorHL = EditorSettings.value("Theme/fieldBGHLColor"); border = true; borderColor = "200 198 198 255"; @@ -64,7 +70,8 @@ singleton GuiControlProfile(AssetBrowserPreviewTerrainMaterialAsset : ToolsGuiDe singleton GuiControlProfile(AssetBrowserPreviewStateMachineAsset : ToolsGuiDefaultProfile) { - fillColor = "128 128 128 255"; //hovered/selected + fillcolor = EditorSettings.value("Theme/windowBackgroundColor"); + fillColorHL = EditorSettings.value("Theme/fieldBGHLColor"); border = true; borderColor = "0 76 135 255"; @@ -73,7 +80,8 @@ singleton GuiControlProfile(AssetBrowserPreviewStateMachineAsset : ToolsGuiDefau singleton GuiControlProfile(AssetBrowserPreviewGUIAsset : ToolsGuiDefaultProfile) { - fillColor = "128 128 128 255"; //hovered/selected + fillcolor = EditorSettings.value("Theme/windowBackgroundColor"); + fillColorHL = EditorSettings.value("Theme/fieldBGHLColor"); border = true; borderColor = "17 5 44 255"; @@ -82,7 +90,8 @@ singleton GuiControlProfile(AssetBrowserPreviewGUIAsset : ToolsGuiDefaultProfile singleton GuiControlProfile(AssetBrowserPreviewLevelAsset : ToolsGuiDefaultProfile) { - fillColor = "128 128 128 255"; //hovered/selected + fillcolor = EditorSettings.value("Theme/windowBackgroundColor"); + fillColorHL = EditorSettings.value("Theme/fieldBGHLColor"); border = true; borderColor = "0 208 186 255"; diff --git a/Templates/BaseGame/game/tools/gui/profiles.ed.tscript b/Templates/BaseGame/game/tools/gui/profiles.ed.tscript index 65d068e8a..478c15ce7 100644 --- a/Templates/BaseGame/game/tools/gui/profiles.ed.tscript +++ b/Templates/BaseGame/game/tools/gui/profiles.ed.tscript @@ -285,6 +285,12 @@ new GuiControlProfile( ToolsGuiTextArrayProfile : ToolsGuiTextProfile ) if( !isObject( ToolsGuiTextListProfile ) ) new GuiControlProfile( ToolsGuiTextListProfile : ToolsGuiTextProfile ) { + fontColor = EditorSettings.value("Theme/fieldTextColor"); + fontColorHL = EditorSettings.value("Theme/fieldTextHLColor"); + fontColorSEL = EditorSettings.value("Theme/fieldTextSELColor"); + fillColor = EditorSettings.value("Theme/fieldBGColor"); + fillColorHL = EditorSettings.value("Theme/fieldBGHLColor"); + fillColorSEL = EditorSettings.value("Theme/fieldBGSELColor"); tab = true; canKeyFocus = true; category = "Tools"; diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainImportGui.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainImportGui.gui index ae0342a2a..3576e8734 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainImportGui.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainImportGui.gui @@ -586,7 +586,7 @@ function TerrainImportGuiAddOpacityMap( %name ) // once per channel in the file // currently it works with just grayscale. %channelsTxt = "R" TAB "G" TAB "B" TAB "A"; - %bitmapInfo = getBitmapinfo( %name ); + %bitmapInfo = getBitmapinfo( makeFullPath(%name) ); %channelCount = getWord( %bitmapInfo, 2 ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.tscript index 48cb8c5d5..0fd609019 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.tscript @@ -158,7 +158,7 @@ function EditorGui::buildMenus(%this) //%fileMenu.appendItem("Create Blank Terrain" TAB "" TAB "Canvas.pushDialog( CreateNewTerrainGui );"); %fileMenu.appendItem("Create Blank Terrain" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"TerrainAsset\", AssetBrowser.selectedModule, createTerrainBlock);"); - %fileMenu.appendItem("Import Terrain Heightmap" TAB "" TAB "Canvas.pushDialog( TerrainImportGui );"); + %fileMenu.appendItem("Import Terrain Heightmap" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"TerrainAsset\", AssetBrowser.selectedModule, createTerrainBlock); Canvas.pushDialog( TerrainImportGui );"); %fileMenu.appendItem("Export Terrain Heightmap" TAB "" TAB "Canvas.pushDialog( TerrainExportGui );"); %fileMenu.appendItem("-"); From 1ef41d85457977b725dcdf358e5a5bb2349aeaed Mon Sep 17 00:00:00 2001 From: Tony zfbx <1414927+zfbx@users.noreply.github.com> Date: Sat, 23 Apr 2022 21:23:26 -0700 Subject: [PATCH 084/145] add .vs directory to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0ddf3aba2..c5ee6c610 100644 --- a/.gitignore +++ b/.gitignore @@ -183,3 +183,4 @@ My Projects/ Project Manager.exe projects.xml Qt*.dll +.vs From 4f3d6c918bcbad23c15967a0602b84ac9feeffd3 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 24 Apr 2022 12:16:22 -0500 Subject: [PATCH 085/145] Fixes issue where storing of AB position and extent wasn't applying correctly Changes ShapeEditor's Library tab to an "Assets" tab and opens the AB with the shapeAsset filter on Adds Asset tab to world editor scenetree window that opens the assetBrowser Fixes issue where opening default scene in worldEditor would activate the saveAs dirty flag, then if you exit the level and open a new one, you can only saveAs and not save the existing level asset --- .../tools/assetBrowser/guis/assetBrowser.gui | 4 +- .../game/tools/assetBrowser/main.tscript | 9 + .../gui/shapeEdSelectWindow.ed.gui | 122 +-------- .../game/tools/shapeEditor/main.tscript | 1 - .../scripts/shapeEditor.ed.tscript | 234 +----------------- .../gui/WorldEditorTreeWindow.ed.gui | 23 ++ .../worldEditor/scripts/EditorGui.ed.tscript | 2 + .../worldEditor/scripts/editor.ed.tscript | 1 + 8 files changed, 49 insertions(+), 347 deletions(-) diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui index c4df19d95..1d3209b90 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui @@ -157,8 +157,8 @@ $guiContent = new GuiControl(AssetBrowser) { position = "204 80"; extent = "615 608"; minExtent = "383 274"; - horizSizing = "center"; - vertSizing = "center"; + horizSizing = "windowRelative"; + vertSizing = "windowRelative"; profile = "ToolsGuiWindowProfile"; visible = "1"; active = "1"; diff --git a/Templates/BaseGame/game/tools/assetBrowser/main.tscript b/Templates/BaseGame/game/tools/assetBrowser/main.tscript index 8f6ca92dd..c912f2ee3 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/main.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/main.tscript @@ -169,6 +169,15 @@ function AssetBrowserPlugin::onWorldEditorStartup( %this ) { } +function AssetBrowserPlugin::onWorldEditorShutdown( %this ) +{ + //force close us real fast to save off current settings/configs + if(AssetBrowser.isAwake()) + { + AssetBrowser.hideDialog(); + } +} + function AssetBrowserPlugin::initSettings( %this ) { EditorSettings.beginGroup( "Assets", true ); diff --git a/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdSelectWindow.ed.gui b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdSelectWindow.ed.gui index 1311e16ea..c92f2ac3b 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdSelectWindow.ed.gui +++ b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdSelectWindow.ed.gui @@ -45,7 +45,7 @@ $guiContent = new GuiControl() { EdgeSnap = "1"; text = "Shapes"; - new GuiTabBookCtrl() { + new GuiTabBookCtrl(ShapeEditorTabbook) { internalName = "tabBook"; canSaveDynamicFields = "0"; isContainer = "1"; @@ -175,126 +175,8 @@ $guiContent = new GuiControl() { AnchorBottom = "0"; AnchorLeft = "1"; AnchorRight = "0"; - text = "Library"; + text = "Assets"; maxLength = "1024"; - - new GuiContainer() { - isContainer = "1"; - HorizSizing = "width"; - VertSizing = "height"; - position = "0 0"; - Extent = "202 146"; - MinExtent = "0 -500"; - Profile = "GuiInspectorProfile"; - }; - new GuiBitmapBorderCtrl() { - isContainer = "1"; - HorizSizing = "width"; - VertSizing = "height"; - position = "0 0"; - Extent = "202 146"; - MinExtent = "0 -500"; - Profile = "ToolsGuiTabBorderProfile"; - }; - new GuiBitmapButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "3 4"; - Extent = "20 19"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "ShapeEdSelectWindow.navigateUp();"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - groupNum = "0"; - buttonType = "PushButton"; - useMouseEvents = "0"; - bitmapAsset = "ToolsModule:folderUp_image"; - }; - new GuiPopUpMenuCtrl(ShapeEdSelectMenu) { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiPopUpMenuProfile"; - HorizSizing = "width"; - VertSizing = "bottom"; - position = "26 4"; - Extent = "172 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "art"; - maxLength = "1024"; - maxPopupHeight = "200"; - sbUsesNAColor = "0"; - reverseTextList = "0"; - bitmapBounds = "16 16"; - }; - new GuiScrollCtrl() { - canSaveDynamicFields = "0"; - isContainer = "1"; - Profile = "ToolsGuiScrollProfile"; - HorizSizing = "width"; - VertSizing = "height"; - position = "0 24"; - Extent = "202 122"; - MinExtent = "8 -500"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - willFirstRespond = "1"; - hScrollBar = "dynamic"; - vScrollBar = "dynamic"; - lockHorizScroll = false; - lockVertScroll = "false"; - constantThumbHeight = "0"; - childMargin = "0 0"; - mouseWheelScrollSpeed = "-1"; - - new GuiDynamicCtrlArrayControl() { - internalName = "shapeLibrary"; - canSaveDynamicFields = "0"; - isContainer = "1"; - Profile = "ToolsGuiTransparentProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "1 1"; - Extent = "189 42"; - MinExtent = "8 11"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - colCount = "1"; - colSize = "64"; - rowCount = "0"; - RowSize = "64"; - rowSpacing = "4"; - colSpacing = "4"; - frozen = "0"; - autoCellSize = "1"; - fillRowFirst = "1"; - dynamicSize = "1"; - }; - }; }; //--------------------------------------------------------------- diff --git a/Templates/BaseGame/game/tools/shapeEditor/main.tscript b/Templates/BaseGame/game/tools/shapeEditor/main.tscript index 1fa7626c4..958d609f6 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/main.tscript +++ b/Templates/BaseGame/game/tools/shapeEditor/main.tscript @@ -127,7 +127,6 @@ function ShapeEditorPlugin::onWorldEditorStartup(%this) ShapeEdSeqNodeTabBook.selectPage(0); ShapeEdAdvancedWindow-->tabBook.selectPage(0); ShapeEdSelectWindow-->tabBook.selectPage(0); - ShapeEdSelectWindow.navigate(""); SetToggleButtonValue( ShapeEditorToolbar-->orbitNodeBtn, 0 ); SetToggleButtonValue( ShapeEditorToolbar-->ghostMode, 0 ); diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript index b53e1edaa..4d60f1f9e 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript @@ -366,230 +366,6 @@ function ShapeEdShapeTreeView::onSelect( %this, %obj ) ShapeEdHintMenu.setSelected( %hintId ); } -// Find all DTS or COLLADA models. Note: most of this section was shamelessly -// stolen from creater.ed.tscript => great work whoever did the original! -function ShapeEdSelectWindow::navigate( %this, %address ) -{ - // Freeze the icon array so it doesn't update until we've added all of the - // icons - %this-->shapeLibrary.frozen = true; - %this-->shapeLibrary.clear(); - ShapeEdSelectMenu.clear(); - - %filePatterns = getFormatExtensions(); - %fullPath = findFirstFileMultiExpr( %filePatterns ); - - while ( %fullPath !$= "" ) - { - // Ignore cached DTS files - if ( endswith( %fullPath, "cached.dts" ) ) - { - %fullPath = findNextFileMultiExpr( %filePatterns ); - continue; - } - - // Ignore assets in the tools folder - %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); - %splitPath = strreplace( %fullPath, " ", "_" ); - %splitPath = strreplace( %splitPath, "/", " " ); - if ( getWord( %splitPath, 0 ) $= "tools" ) - { - %fullPath = findNextFileMultiExpr( %filePatterns ); - continue; - } - - %dirCount = getWordCount( %splitPath ) - 1; - %pathFolders = getWords( %splitPath, 0, %dirCount - 1 ); - - // Add this file's path ( parent folders ) to the - // popup menu if it isn't there yet. - %temp = strreplace( %pathFolders, " ", "/" ); - %temp = strreplace( %temp, "_", " " ); - %r = ShapeEdSelectMenu.findText( %temp ); - if ( %r == -1 ) - ShapeEdSelectMenu.add( %temp ); - - // Is this file in the current folder? - if ( stricmp( %pathFolders, %address ) == 0 ) - { - %this.addShapeIcon( %fullPath ); - } - // Then is this file in a subfolder we need to add - // a folder icon for? - else - { - %wordIdx = 0; - %add = false; - - if ( %address $= "" ) - { - %add = true; - %wordIdx = 0; - } - else - { - for ( ; %wordIdx < %dirCount; %wordIdx++ ) - { - %temp = getWords( %splitPath, 0, %wordIdx ); - if ( stricmp( %temp, %address ) == 0 ) - { - %add = true; - %wordIdx++; - break; - } - } - } - - if ( %add == true ) - { - %folder = getWord( %splitPath, %wordIdx ); - - // Add folder icon if not already present - %ctrl = %this.findIconCtrl( %folder ); - if ( %ctrl == -1 ) - %this.addFolderIcon( %folder ); - } - } - - %fullPath = findNextFileMultiExpr( %filePatterns ); - } - - %this-->shapeLibrary.sort( "alphaIconCompare" ); - for ( %i = 0; %i < %this-->shapeLibrary.getCount(); %i++ ) - %this-->shapeLibrary.getObject( %i ).autoSize = false; - - %this-->shapeLibrary.frozen = false; - %this-->shapeLibrary.refresh(); - %this.address = %address; - - ShapeEdSelectMenu.sort(); - - %str = strreplace( %address, " ", "/" ); - %r = ShapeEdSelectMenu.findText( %str ); - if ( %r != -1 ) - ShapeEdSelectMenu.setSelected( %r, false ); - else - ShapeEdSelectMenu.setText( %str ); -} - -function ShapeEdSelectWindow::navigateDown( %this, %folder ) -{ - if ( %this.address $= "" ) - %address = %folder; - else - %address = %this.address SPC %folder; - - // Because this is called from an IconButton::onClick command - // we have to wait a tick before actually calling navigate, else - // we would delete the button out from under itself. - %this.schedule( 1, "navigate", %address ); -} - -function ShapeEdSelectWindow::navigateUp( %this ) -{ - %count = getWordCount( %this.address ); - - if ( %count == 0 ) - return; - - if ( %count == 1 ) - %address = ""; - else - %address = getWords( %this.address, 0, %count - 2 ); - - %this.navigate( %address ); -} - -function ShapeEdSelectWindow::findIconCtrl( %this, %name ) -{ - for ( %i = 0; %i < %this-->shapeLibrary.getCount(); %i++ ) - { - %ctrl = %this-->shapeLibrary.getObject( %i ); - if ( %ctrl.text $= %name ) - return %ctrl; - } - return -1; -} - -function ShapeEdSelectWindow::createIcon( %this ) -{ - %ctrl = new GuiIconButtonCtrl() - { - profile = "GuiCreatorIconButtonProfile"; - iconLocation = "Left"; - textLocation = "Right"; - extent = "348 19"; - textMargin = 8; - buttonMargin = "2 2"; - autoSize = false; - sizeIconToButton = true; - makeIconSquare = true; - buttonType = "radioButton"; - groupNum = "-1"; - }; - - return %ctrl; -} - -function ShapeEdSelectWindow::addFolderIcon( %this, %text ) -{ - %ctrl = %this.createIcon(); - - %ctrl.altCommand = "ShapeEdSelectWindow.navigateDown( \"" @ %text @ "\" );"; - %ctrl.iconBitmap = "tools/gui/images/folder.png"; - %ctrl.text = %text; - %ctrl.tooltip = %text; - %ctrl.class = "CreatorFolderIconBtn"; - - %ctrl.buttonType = "radioButton"; - %ctrl.groupNum = "-1"; - - %this-->shapeLibrary.addGuiControl( %ctrl ); -} - -function ShapeEdSelectWindow::addShapeIcon( %this, %fullPath ) -{ - %ctrl = %this.createIcon(); - - %ext = fileExt( %fullPath ); - %file = fileBase( %fullPath ); - %fileLong = %file @ %ext; - %tip = %fileLong NL - "Size: " @ fileSize( %fullPath ) / 1000.0 SPC "KB" NL - "Date Created: " @ fileCreatedTime( %fullPath ) NL - "Last Modified: " @ fileModifiedTime( %fullPath ); - - %ctrl.altCommand = "ShapeEdSelectWindow.onSelect( \"" @ %fullPath @ "\" );"; - %ctrl.iconBitmap = ( ( %ext $= ".dts" ) ? EditorIconRegistry::findIconByClassName( "TSStatic" ) : "tools/gui/images/iconCollada" ); - %ctrl.text = %file; - %ctrl.class = "CreatorStaticIconBtn"; - %ctrl.tooltip = %tip; - - %ctrl.buttonType = "radioButton"; - %ctrl.groupNum = "-1"; - - // Check if a shape specific icon is available - %formats = ".png .jpg .dds .bmp .gif .jng .tga"; - %count = getWordCount( %formats ); - for ( %i = 0; %i < %count; %i++ ) - { - %ext = getWord( %formats, %i ); - if ( isFile( %fullPath @ %ext ) ) - { - %ctrl.iconBitmap = %fullPath @ %ext; - break; - } - } - - %this-->shapeLibrary.addGuiControl( %ctrl ); -} - -function ShapeEdSelectMenu::onSelect( %this, %id, %text ) -{ - %split = strreplace( %text, "/", " " ); - ShapeEdSelectWindow.navigate( %split ); -} - // Update the GUI in response to the shape selection changing function ShapeEdPropWindow::update_onShapeSelectionChanged( %this ) { @@ -3444,3 +3220,13 @@ function showShapeEditorPreview() %visible = ShapeEditorToolbar-->showPreview.getValue(); ShapeEdPreviewGui.setVisible( %visible ); } + +// +function ShapeEditorTabbook::onTabSelected( %this ) +{ + if( EditorTreeTabBook.getSelectedPage() == 1) + { + AssetBrowser.toggleDialog(); + AssetBrowser.toggleAssetTypeFilter(12); //show only shapeAssets + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui index 45bc34cae..bcf9fbf44 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui @@ -176,6 +176,29 @@ $guiContent = new GuiControl() { }; }; }; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiEditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "197 271"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Assets"; + maxLength = "1024"; + }; }; new GuiBitmapButtonCtrl() { canSaveDynamicFields = "0"; diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript index a10c44c87..74a4e30a7 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript @@ -1932,6 +1932,8 @@ function EditorTreeTabBook::onTabSelected( %this ) } else { + AssetBrowser.toggleDialog(); + EditorTreeTabBook.selectPage(0); EWTreeWindow-->DeleteSelection.visible = false; EWTreeWindow-->LockSelection.visible = false; EWTreeWindow-->AddSimGroup.visible = false; diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editor.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/editor.ed.tscript index cdd34c3d2..ff5696dd5 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editor.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editor.ed.tscript @@ -191,6 +191,7 @@ package EditorDisconnectOverride { if ( isObject( Editor ) && Editor.isEditorEnabled() ) { + EditorGui.saveAs = false; //whatever edits we were doing are irrelevent now %mainMenuGUI = ProjectSettings.value("UI/mainMenuName"); if (isObject( %mainMenuGUI )) Editor.close( %mainMenuGUI ); From 81eec1dcb4a0d9f7b19d8825000be9c48bcfaa42 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 24 Apr 2022 13:03:33 -0500 Subject: [PATCH 086/145] Added multi type filter support to AB select mode Adjusted logic for World Editor's Assets tab to filter by ShapeAssets and Datablocks Improved ShapeEditor's Assets tab filter and select logic Added ability for AB search to work on creator section Fixed icon display of AB on preview cards when in list mode --- .../tools/assetBrowser/guis/assetBrowser.gui | 2 +- .../assetBrowser/scripts/assetBrowser.tscript | 29 +++++++++++++++++-- .../scripts/shapeEditor.ed.tscript | 11 +++++-- .../worldEditor/scripts/EditorGui.ed.tscript | 5 +--- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui index 1d3209b90..5a7aade06 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui @@ -771,7 +771,7 @@ $guiContent = new GuiControl(AssetBrowser) { position = "0 0"; extent = "23 23"; minExtent = "8 2"; - horizSizing = "left"; + horizSizing = "right"; vertSizing = "bottom"; profile = "ToolsGuiSolidDefaultProfile"; visible = "1"; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index 3dd7b881d..0c7270d10 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript @@ -527,6 +527,7 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) %previewButton.iconLocation = "Left"; %previewButton.textLocation = "Right"; %previewButton.setextent(120,20); + %previewButton.buttonMargin = "0 0"; AssetBrowser.previewListMode = true; } @@ -1519,7 +1520,11 @@ function AssetBrowser::doRebuildAssetArray(%this) { if(AssetBrowser.assetTypeFilter !$= "") { - if(AssetBrowser.assetTypeFilter $= %assetType) + %filtersCount = getWordCount(AssetBrowser.assetTypeFilter); + for(%fltrIdx = 0; %fltrIdx < %filtersCount; %fltrIdx++) + { + %fltr = getWord(AssetBrowser.assetTypeFilter, %fltrIdx); + if(%fltr $= %assetType) { $AssetBrowser::AssetArray.add( %moduleName, %assetId ); @@ -1527,6 +1532,7 @@ function AssetBrowser::doRebuildAssetArray(%this) %finalAssetCount++; } } + } else { //got it. @@ -1574,7 +1580,22 @@ function AssetBrowser::doRebuildAssetArray(%this) } //Add Non-Asset Scripted Objects. Datablock, etc based - if(AssetBrowser.assetTypeFilter $= "" && %breadcrumbPath !$= "" && isDirectory(%breadcrumbPath)) + %hasDBFilter = true; + if(AssetBrowser.assetTypeFilter !$= "") + { + %hasDBFilter = false; + %filterCount = getWordCount(AssetBrowser.assetTypeFilter); + for(%fltrIdx = 0; %fltrIdx < %filterCount; %fltrIdx++) + { + %fltr = getWord(AssetBrowser.assetTypeFilter, %fltrIdx); + if(%fltr $= "Datablock" || %fltr $= "Datablocks") + { + %hasDBFilter = true; + break; + } + } + } + if(%hasDBFilter && %breadcrumbPath !$= "" && isDirectory(%breadcrumbPath)) { %category = getWord( %breadcrumbPath, 1 ); %dataGroup = "DataBlockGroup"; @@ -1792,6 +1813,10 @@ function AssetBrowser::doRebuildAssetArray(%this) %name = %creatorObj.val[1]; %func = %creatorObj.val[2]; + %searchActive = AssetSearchTerms.count() != 0; + if(%searchActive && !matchesSearch(%name, "Creator")) + continue; + $AssetBrowser::AssetArray.add( %name, "Creator" TAB %creatorObj ); } } diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript index 4d60f1f9e..929fc510e 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript @@ -3224,9 +3224,14 @@ function showShapeEditorPreview() // function ShapeEditorTabbook::onTabSelected( %this ) { - if( EditorTreeTabBook.getSelectedPage() == 1) + if( ShapeEditorTabbook.getSelectedPage() == 1) { - AssetBrowser.toggleDialog(); - AssetBrowser.toggleAssetTypeFilter(12); //show only shapeAssets + AssetBrowser.showDialog("ShapeAsset", "openShapeInShapeEditor"); } +} + +function openShapeInShapeEditor(%shapeAssetId) +{ + %assetDef = AssetDatabase.acquireAsset(%shapeAssetId); + AssetBrowser.editShapeAsset(%assetDef); } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript index 74a4e30a7..58686e20e 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript @@ -1932,11 +1932,8 @@ function EditorTreeTabBook::onTabSelected( %this ) } else { - AssetBrowser.toggleDialog(); + AssetBrowser.showDialog("ShapeAsset Datablock"); EditorTreeTabBook.selectPage(0); - EWTreeWindow-->DeleteSelection.visible = false; - EWTreeWindow-->LockSelection.visible = false; - EWTreeWindow-->AddSimGroup.visible = false; } } From bd1bbdc258a92f5b935f9706920d464a6cee4beb Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Mon, 25 Apr 2022 13:28:32 -0500 Subject: [PATCH 087/145] correct mac compilation SDL now leverages https://cmake.org/cmake/help/v3.10/command/enable_language.html --- Tools/CMake/basics.cmake | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Tools/CMake/basics.cmake b/Tools/CMake/basics.cmake index c0fc10426..6719036db 100644 --- a/Tools/CMake/basics.cmake +++ b/Tools/CMake/basics.cmake @@ -467,6 +467,19 @@ if(WIN32) ENDFOREACH() endif() else() + if(${CMAKE_VERSION} VERSION_LESS "3.16.0") + macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR) + set(PREV_REQUIRED_DEFS "${CMAKE_REQUIRED_DEFINITIONS}") + set(CMAKE_REQUIRED_DEFINITIONS "-x objective-c ${PREV_REQUIRED_DEFS}") + CHECK_C_SOURCE_COMPILES(${SOURCE} ${VAR}) + set(CMAKE_REQUIRED_DEFINITIONS "${PREV_REQUIRED_DEFS}") + endmacro() + else() + include(CheckOBJCSourceCompiles) + if (APPLE) + enable_language(OBJC) + endif() + endif() # TODO: improve default settings on other platforms set(TORQUE_CXX_FLAGS_EXECUTABLES "" CACHE STRING "") mark_as_advanced(TORQUE_CXX_FLAGS_EXECUTABLES) From 39952a490f4aa4f9d50506fcd1e968cd7b1f2336 Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Mon, 25 Apr 2022 18:23:15 -0400 Subject: [PATCH 088/145] * Cleanup: Resolve several compiler warnings associated with TORQUE_DEBUG. --- Engine/source/T3D/assets/TerrainAsset.cpp | 2 +- Engine/source/gfx/gfxCardProfile.cpp | 4 ++-- Engine/source/gfx/gl/gfxGLTextureObject.cpp | 4 ++-- Engine/source/gfx/gl/gfxGLTextureObject.h | 4 ++-- Engine/source/gfx/gl/gfxGLUtils.h | 2 +- Engine/source/persistence/taml/tamlCustom.cpp | 2 +- Engine/source/persistence/taml/tamlCustom.h | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Engine/source/T3D/assets/TerrainAsset.cpp b/Engine/source/T3D/assets/TerrainAsset.cpp index 2887cea2d..4e03f4c20 100644 --- a/Engine/source/T3D/assets/TerrainAsset.cpp +++ b/Engine/source/T3D/assets/TerrainAsset.cpp @@ -247,7 +247,7 @@ bool TerrainAsset::getAssetByFilename(StringTableEntry fileName, AssetPtr(data); -#if TORQUE_DEBUG +#ifdef TORQUE_DEBUG Con::printf(" - Loaded card profile %s", scriptName.c_str()); #endif diff --git a/Engine/source/gfx/gl/gfxGLTextureObject.cpp b/Engine/source/gfx/gl/gfxGLTextureObject.cpp index e7dd88d4e..ea40a2e78 100644 --- a/Engine/source/gfx/gl/gfxGLTextureObject.cpp +++ b/Engine/source/gfx/gl/gfxGLTextureObject.cpp @@ -45,7 +45,7 @@ GFXGLTextureObject::GFXGLTextureObject(GFXDevice * aDevice, GFXTextureProfile *p mFrameAllocatorPtr(NULL) { -#if TORQUE_DEBUG +#ifdef TORQUE_DEBUG mFrameAllocatorMarkGuard = FrameAllocator::getWaterMark(); #endif @@ -90,7 +90,7 @@ GFXLockedRect* GFXGLTextureObject::lock(U32 mipLevel, RectI *inRect) mFrameAllocatorMark = FrameAllocator::getWaterMark(); mFrameAllocatorPtr = (U8*)FrameAllocator::alloc( size ); mLockedRect.bits = mFrameAllocatorPtr; -#if TORQUE_DEBUG +#ifdef TORQUE_DEBUG mFrameAllocatorMarkGuard = FrameAllocator::getWaterMark(); #endif diff --git a/Engine/source/gfx/gl/gfxGLTextureObject.h b/Engine/source/gfx/gl/gfxGLTextureObject.h index 90d748bab..f07cb9138 100644 --- a/Engine/source/gfx/gl/gfxGLTextureObject.h +++ b/Engine/source/gfx/gl/gfxGLTextureObject.h @@ -102,10 +102,10 @@ private: //FrameAllocator U32 mFrameAllocatorMark; -#if TORQUE_DEBUG +#ifdef TORQUE_DEBUG U32 mFrameAllocatorMarkGuard; #endif U8 *mFrameAllocatorPtr; }; -#endif \ No newline at end of file +#endif diff --git a/Engine/source/gfx/gl/gfxGLUtils.h b/Engine/source/gfx/gl/gfxGLUtils.h index 8d235d6b9..2218836b0 100644 --- a/Engine/source/gfx/gl/gfxGLUtils.h +++ b/Engine/source/gfx/gl/gfxGLUtils.h @@ -208,7 +208,7 @@ GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (GL_READ_FRAMEBUFFER, GL GFXGLPreserveInteger TORQUE_CONCAT(preserve2_, __LINE__) (GL_DRAW_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER_BINDING, (GFXGLPreserveInteger::BindFn)glBindFramebuffer) -#if TORQUE_DEBUG +#ifdef TORQUE_DEBUG // Handy macro for checking the status of a framebuffer. Framebuffers can fail in // all sorts of interesting ways, these are just the most common. Further, no existing GL profiling diff --git a/Engine/source/persistence/taml/tamlCustom.cpp b/Engine/source/persistence/taml/tamlCustom.cpp index e45984dd4..1c0df2c13 100644 --- a/Engine/source/persistence/taml/tamlCustom.cpp +++ b/Engine/source/persistence/taml/tamlCustom.cpp @@ -42,7 +42,7 @@ void TamlCustomField::set( const char* pFieldName, const char* pFieldValue ) // Set field name. mFieldName = StringTable->insert( pFieldName ); -#if TORQUE_DEBUG +#ifdef TORQUE_DEBUG // Is the field value too big? if ( dStrlen(pFieldValue) >= sizeof(mFieldValue) ) { diff --git a/Engine/source/persistence/taml/tamlCustom.h b/Engine/source/persistence/taml/tamlCustom.h index 2f3ba857e..6dacc099d 100644 --- a/Engine/source/persistence/taml/tamlCustom.h +++ b/Engine/source/persistence/taml/tamlCustom.h @@ -640,7 +640,7 @@ public: private: inline TamlCustomField* registerField( TamlCustomField* pCustomField ) { -#if TORQUE_DEBUG +#ifdef TORQUE_DEBUG // Ensure a field name conflict does not exist. for( Vector::iterator nodeFieldItr = mFields.begin(); nodeFieldItr != mFields.end(); ++nodeFieldItr ) { @@ -724,7 +724,7 @@ public: // Set ignore-empty flag. pCustomNode->setIgnoreEmpty( ignoreEmpty ); -#if TORQUE_DEBUG +#ifdef TORQUE_DEBUG // Ensure a node name conflict does not exist. for( TamlCustomNodeVector::iterator nodeItr = mNodes.begin(); nodeItr != mNodes.end(); ++nodeItr ) { From cbf758e0890b7bc23204f42c8aebd970a146cf65 Mon Sep 17 00:00:00 2001 From: JeffR Date: Mon, 25 Apr 2022 23:53:40 -0500 Subject: [PATCH 089/145] Removes the BGRA inversion when displaying vertex colors on materials --- Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp index d4e3acda4..360f8f918 100644 --- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp @@ -1250,7 +1250,7 @@ void DiffuseVertColorFeatureHLSL::processVert( Vector< ShaderComponent* >& comp outColor->setStructName( "OUT" ); outColor->setType( "float4" ); - output = new GenOp( " @ = @.bgra;\r\n", outColor, inColor ); + output = new GenOp( " @ = @;\r\n", outColor, inColor ); } else output = NULL; // Nothing we need to do. From 4ae7d7ce3f59f078499b7dc20b2e09641a05499a Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 26 Apr 2022 02:00:34 -0500 Subject: [PATCH 090/145] from higuy: "PATH_MAX is defined there on macos" --- Engine/source/platformPOSIX/POSIXFileio.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Engine/source/platformPOSIX/POSIXFileio.cpp b/Engine/source/platformPOSIX/POSIXFileio.cpp index c21e427ba..c9bfdd49c 100644 --- a/Engine/source/platformPOSIX/POSIXFileio.cpp +++ b/Engine/source/platformPOSIX/POSIXFileio.cpp @@ -46,6 +46,9 @@ #if defined(__FreeBSD__) #include #endif +#if defined(__APPLE__) +#include +#endif #include /* these are for reading directors, getting stats, etc. */ From e5fba24778ea2809809444cc7c1cd6733aa21e24 Mon Sep 17 00:00:00 2001 From: Glenn Smith Date: Tue, 26 Apr 2022 03:51:13 -0400 Subject: [PATCH 091/145] Github actions CI Using cmake + ninja --- .github/workflows/cmake.yml | 55 +++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 .github/workflows/cmake.yml diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 000000000..f25be008a --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,55 @@ +name: CMake + +on: + push: + branches: [ Preview4_0 ] + pull_request: + branches: [ Preview4_0 ] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. + # You can convert this to a matrix build if you need cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ${{matrix.os}} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + + steps: + - uses: actions/checkout@v3 + - uses: seanmiddleditch/gha-setup-ninja@master + - uses: ilammy/msvc-dev-cmd@v1 + - name: Setup Environment + run: | + if [ "$RUNNER_OS" == "Linux" ]; then + sudo apt-get install -y \ + build-essential \ + nasm \ + libogg-dev \ + libxft-dev \ + libx11-dev \ + libxxf86vm-dev \ + libopenal-dev \ + libfreetype6-dev \ + libxcursor-dev \ + libxinerama-dev \ + libxi-dev \ + libxrandr-dev \ + libxss-dev \ + libglu1-mesa-dev \ + libgtk-3-dev + fi + shell: bash + - name: Configure CMake + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: cmake -B ${{github.workspace}}/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DTORQUE_APP_NAME=Torque3D + + - name: Build + # Build your program with the given configuration + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} From d4307ea41306d12bb33e634f19de7adad9a01192 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 26 Apr 2022 09:17:21 -0500 Subject: [PATCH 092/145] update sdl to release 2.0.22 --- Engine/lib/sdl/CMakeLists.txt | 254 ++-- Engine/lib/sdl/Makefile.in | 1 + Engine/lib/sdl/Makefile.os2 | 6 +- Engine/lib/sdl/WhatsNew.txt | 30 + Engine/lib/sdl/Xcode/SDL/Info-Framework.plist | 4 +- .../Xcode/SDL/SDL.xcodeproj/project.pbxproj | 46 +- Engine/lib/sdl/build-scripts/os2-buildbot.sh | 41 - Engine/lib/sdl/build-scripts/winrtbuild.ps1 | 2 +- Engine/lib/sdl/cmake/sdlchecks.cmake | 6 +- Engine/lib/sdl/configure | 136 +- Engine/lib/sdl/configure.ac | 44 +- Engine/lib/sdl/docs/README-directfb.md | 42 +- Engine/lib/sdl/docs/README-visualc.md | 2 +- Engine/lib/sdl/docs/README-vita.md | 3 + Engine/lib/sdl/docs/README-windows.md | 81 +- Engine/lib/sdl/include/SDL_blendmode.h | 10 +- Engine/lib/sdl/include/SDL_config.h.cmake | 2 + Engine/lib/sdl/include/SDL_config.h.in | 1 + .../lib/sdl/include/SDL_config_emscripten.h | 1 + Engine/lib/sdl/include/SDL_config_windows.h | 1 + Engine/lib/sdl/include/SDL_config_winrt.h | 2 + Engine/lib/sdl/include/SDL_hints.h | 76 +- Engine/lib/sdl/include/SDL_metal.h | 1 + Engine/lib/sdl/include/SDL_rect.h | 38 +- Engine/lib/sdl/include/SDL_render.h | 13 + Engine/lib/sdl/include/SDL_stdinc.h | 17 +- Engine/lib/sdl/include/SDL_syswm.h | 2 + Engine/lib/sdl/include/SDL_version.h | 2 +- Engine/lib/sdl/include/SDL_video.h | 1 + Engine/lib/sdl/include/begin_code.h | 2 +- Engine/lib/sdl/src/SDL.c | 2 + Engine/lib/sdl/src/SDL_hints.c | 5 + Engine/lib/sdl/src/SDL_list.c | 93 ++ Engine/lib/sdl/src/SDL_list.h | 39 + Engine/lib/sdl/src/audio/SDL_audio.c | 2 +- Engine/lib/sdl/src/audio/SDL_audiocvt.c | 2 +- Engine/lib/sdl/src/audio/SDL_wave.c | 2 +- .../audio/emscripten/SDL_emscriptenaudio.c | 16 +- Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.c | 85 +- Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.h | 4 +- Engine/lib/sdl/src/audio/wasapi/SDL_wasapi.c | 4 + Engine/lib/sdl/src/core/linux/SDL_fcitx.c | 8 +- Engine/lib/sdl/src/core/linux/SDL_fcitx.h | 2 +- Engine/lib/sdl/src/core/linux/SDL_ibus.c | 11 +- Engine/lib/sdl/src/core/linux/SDL_ibus.h | 2 +- Engine/lib/sdl/src/core/linux/SDL_ime.c | 6 +- Engine/lib/sdl/src/core/linux/SDL_ime.h | 2 +- Engine/lib/sdl/src/core/windows/SDL_windows.c | 117 +- Engine/lib/sdl/src/core/windows/SDL_windows.h | 9 + .../lib/sdl/src/dynapi/SDL_dynapi_overrides.h | 1 + Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h | 1 + Engine/lib/sdl/src/events/SDL_keyboard.c | 1 + Engine/lib/sdl/src/events/SDL_mouse.c | 109 +- Engine/lib/sdl/src/events/SDL_mouse_c.h | 8 + Engine/lib/sdl/src/events/SDL_touch.c | 5 + .../filesystem/windows/SDL_sysfilesystem.c | 20 +- Engine/lib/sdl/src/hidapi/SDL_hidapi.c | 10 +- Engine/lib/sdl/src/hidapi/libusb/hid.c | 1 + Engine/lib/sdl/src/hidapi/mac/hid.c | 22 +- .../sdl/src/joystick/SDL_gamecontrollerdb.h | 3 +- Engine/lib/sdl/src/joystick/SDL_joystick.c | 13 +- .../sdl/src/joystick/hidapi/SDL_hidapi_ps5.c | 11 +- .../src/joystick/hidapi/SDL_hidapijoystick.c | 2 +- .../src/joystick/iphoneos/SDL_mfijoystick.m | 13 + .../sdl/src/joystick/linux/SDL_sysjoystick.c | 119 +- .../joystick/windows/SDL_rawinputjoystick.c | 24 +- .../windows/SDL_windows_gaming_input.c | 63 +- .../lib/sdl/src/locale/vita/SDL_syslocale.c | 71 + Engine/lib/sdl/src/main/windows/version.rc | 8 +- Engine/lib/sdl/src/render/SDL_render.c | 99 +- Engine/lib/sdl/src/render/SDL_sysrender.h | 25 +- .../sdl/src/render/direct3d/SDL_render_d3d.c | 44 +- .../src/render/direct3d11/SDL_render_d3d11.c | 10 + .../lib/sdl/src/render/opengl/SDL_render_gl.c | 28 +- .../src/render/vitagxm/SDL_render_vita_gxm.c | 287 +++- .../vitagxm/SDL_render_vita_gxm_memory.c | 76 +- .../vitagxm/SDL_render_vita_gxm_memory.h | 16 +- .../vitagxm/SDL_render_vita_gxm_tools.c | 152 ++- .../vitagxm/SDL_render_vita_gxm_tools.h | 7 +- .../vitagxm/SDL_render_vita_gxm_types.h | 13 +- Engine/lib/sdl/src/test/SDL_test_common.c | 2 + Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c | 10 +- Engine/lib/sdl/src/timer/os2/SDL_systimer.c | 13 +- Engine/lib/sdl/src/video/SDL_bmp.c | 6 + Engine/lib/sdl/src/video/SDL_egl.c | 7 +- Engine/lib/sdl/src/video/SDL_pixels.c | 41 +- Engine/lib/sdl/src/video/SDL_sysvideo.h | 1 + Engine/lib/sdl/src/video/SDL_video.c | 56 +- .../sdl/src/video/android/SDL_androidvideo.c | 1 + .../sdl/src/video/android/SDL_androidwindow.c | 6 + .../sdl/src/video/android/SDL_androidwindow.h | 1 + .../lib/sdl/src/video/dummy/SDL_nullvideo.c | 3 +- .../emscripten/SDL_emscriptenframebuffer.c | 38 +- .../video/emscripten/SDL_emscriptenmouse.c | 56 +- .../video/emscripten/SDL_emscriptenvideo.c | 4 +- .../sdl/src/video/uikit/SDL_uikitmessagebox.m | 24 +- .../sdl/src/video/vita/SDL_vitaframebuffer.c | 2 +- .../lib/sdl/src/video/vita/SDL_vitagl_pvr.c | 65 +- .../lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h | 9 +- .../vita/{SDL_vitagl.c => SDL_vitagles.c} | 24 +- .../vita/{SDL_vitagl_c.h => SDL_vitagles_c.h} | 24 +- .../lib/sdl/src/video/vita/SDL_vitagles_pvr.c | 103 ++ .../sdl/src/video/vita/SDL_vitagles_pvr_c.h | 35 + Engine/lib/sdl/src/video/vita/SDL_vitavideo.c | 61 +- Engine/lib/sdl/src/video/vita/SDL_vitavideo.h | 21 +- .../sdl/src/video/wayland/SDL_waylanddyn.h | 11 +- .../sdl/src/video/wayland/SDL_waylandevents.c | 445 ++++++- .../src/video/wayland/SDL_waylandevents_c.h | 44 + .../src/video/wayland/SDL_waylandopengles.c | 4 +- .../sdl/src/video/wayland/SDL_waylandsym.h | 16 +- .../sdl/src/video/wayland/SDL_waylandvideo.c | 400 +++++- .../sdl/src/video/wayland/SDL_waylandvideo.h | 17 +- .../sdl/src/video/wayland/SDL_waylandvulkan.c | 4 +- .../sdl/src/video/wayland/SDL_waylandwindow.c | 669 +++++++++- .../sdl/src/video/wayland/SDL_waylandwindow.h | 18 +- .../sdl/src/video/windows/SDL_windowsevents.c | 16 +- .../sdl/src/video/windows/SDL_windowswindow.c | 11 +- Engine/lib/sdl/src/video/x11/SDL_x11events.c | 74 +- Engine/lib/sdl/src/video/x11/SDL_x11events.h | 1 + .../lib/sdl/src/video/x11/SDL_x11keyboard.c | 2 + .../lib/sdl/src/video/x11/SDL_x11messagebox.c | 16 +- Engine/lib/sdl/src/video/x11/SDL_x11modes.c | 8 +- Engine/lib/sdl/src/video/x11/SDL_x11opengl.c | 5 - Engine/lib/sdl/src/video/x11/SDL_x11sym.h | 1 - Engine/lib/sdl/src/video/x11/SDL_x11window.c | 108 +- .../sdl/src/video/yuv2rgb/yuv_rgb_sse_func.h | 19 +- Engine/lib/sdl/test/Makefile.in | 1 + Engine/lib/sdl/test/testautomation_rect.c | 98 +- Engine/lib/sdl/test/testevdev.c | 36 +- Engine/lib/sdl/test/testgles2.c | 63 +- Engine/lib/sdl/test/testmouse.c | 34 + Engine/lib/sdl/test/testshader.c | 49 +- .../wayland-protocols/tablet-unstable-v2.xml | 1178 +++++++++++++++++ .../lib/sdl/wayland-protocols/viewporter.xml | 186 +++ .../xdg-output-unstable-v1.xml | 220 +++ 135 files changed, 5746 insertions(+), 1161 deletions(-) delete mode 100644 Engine/lib/sdl/build-scripts/os2-buildbot.sh create mode 100644 Engine/lib/sdl/src/SDL_list.c create mode 100644 Engine/lib/sdl/src/SDL_list.h create mode 100644 Engine/lib/sdl/src/locale/vita/SDL_syslocale.c rename Engine/lib/sdl/src/video/vita/{SDL_vitagl.c => SDL_vitagles.c} (91%) rename Engine/lib/sdl/src/video/vita/{SDL_vitagl_c.h => SDL_vitagles_c.h} (67%) create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitagles_pvr.c create mode 100644 Engine/lib/sdl/src/video/vita/SDL_vitagles_pvr_c.h create mode 100644 Engine/lib/sdl/wayland-protocols/tablet-unstable-v2.xml create mode 100644 Engine/lib/sdl/wayland-protocols/viewporter.xml create mode 100644 Engine/lib/sdl/wayland-protocols/xdg-output-unstable-v1.xml diff --git a/Engine/lib/sdl/CMakeLists.txt b/Engine/lib/sdl/CMakeLists.txt index 59bacf0f5..644715aae 100644 --- a/Engine/lib/sdl/CMakeLists.txt +++ b/Engine/lib/sdl/CMakeLists.txt @@ -66,12 +66,12 @@ include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake) # set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0. set(SDL_MAJOR_VERSION 2) set(SDL_MINOR_VERSION 0) -set(SDL_MICRO_VERSION 21) -set(SDL_INTERFACE_AGE 3) -set(SDL_BINARY_AGE 21) +set(SDL_MICRO_VERSION 22) +set(SDL_INTERFACE_AGE 0) +set(SDL_BINARY_AGE 22) set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}") # the following should match the versions in Xcode project file: -set(DYLIB_CURRENT_VERSION 19.3.0) +set(DYLIB_CURRENT_VERSION 23.0.0) set(DYLIB_COMPATIBILITY_VERSION 1.0.0) # Set defaults preventing destination file conflicts @@ -372,6 +372,7 @@ endforeach() # Allow some projects to be built conditionally. set_option(SDL2_DISABLE_SDL2MAIN "Disable building/installation of SDL2main" OFF) +set_option(SDL2_DISABLE_INSTALL "Disable installation of SDL2" OFF) set_option(SDL2_DISABLE_UNINSTALL "Disable uninstallation of SDL2" OFF) option_string(SDL_ASSERTIONS "Enable internal sanity checks (auto/disabled/release/enabled/paranoid)" "auto") @@ -1600,6 +1601,7 @@ elseif(WINDOWS) # headers needed elsewhere check_include_file(tpcshrd.h HAVE_TPCSHRD_H) + check_include_file(roapi.h HAVE_ROAPI_H) check_include_file(mmdeviceapi.h HAVE_MMDEVICEAPI_H) check_include_file(audioclient.h HAVE_AUDIOCLIENT_H) check_include_file(sensorsapi.h HAVE_SENSORSAPI_H) @@ -2279,6 +2281,11 @@ elseif(VITA) ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c) set(HAVE_SDL_THREADS TRUE) endif() + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/vita/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() if(SDL_TIMERS) set(SDL_TIMER_VITA 1) file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/vita/*.c) @@ -2305,10 +2312,10 @@ elseif(VITA) list(APPEND EXTRA_LIBS pib ) - set(HAVE_VITA_PIB ON) + set(HAVE_VIDEO_VITA_PIB ON) set(SDL_VIDEO_VITA_PIB 1) else() - set(HAVE_VITA_PIB OFF) + set(HAVE_VIDEO_VITA_PIB OFF) endif() endif() @@ -2316,6 +2323,7 @@ elseif(VITA) check_include_file(gpu_es4/psp2_pvr_hint.h HAVE_PVR_H) if(HAVE_PVR_H) target_compile_definitions(sdl-build-options INTERFACE "-D__psp2__") + check_include_file(gl4esinit.h HAVE_GL4ES_H) set(SDL_VIDEO_OPENGL_EGL 1) set(HAVE_OPENGLES TRUE) set(SDL_VIDEO_OPENGL_ES 1) @@ -2327,10 +2335,20 @@ elseif(VITA) libgpu_es4_ext_stub_weak libIMGEGL_stub_weak ) - set(HAVE_VITA_PVR ON) + + set(HAVE_VIDEO_VITA_PVR ON) set(SDL_VIDEO_VITA_PVR 1) + + if(HAVE_GL4ES_H) + set(HAVE_OPENGL TRUE) + set(SDL_VIDEO_OPENGL 1) + set(SDL_VIDEO_RENDER_OGL 1) + list(APPEND EXTRA_LIBS libGL_stub) + set(SDL_VIDEO_VITA_PVR_OGL 1) + endif() + else() - set(HAVE_VITA_PVR OFF) + set(HAVE_VIDEO_VITA_PVR OFF) endif() endif() @@ -2342,6 +2360,7 @@ elseif(VITA) SceCtrl_stub SceAppMgr_stub SceAudio_stub + SceAudioIn_stub SceSysmodule_stub SceDisplay_stub SceCtrl_stub @@ -2950,122 +2969,125 @@ if(SDL_TEST) endif() ##### Installation targets ##### -if(SDL_SHARED) - install(TARGETS SDL2 EXPORT SDL2Targets - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") -endif() - -if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN) - install(TARGETS SDL2main EXPORT SDL2mainTargets - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") -endif() - -if(SDL_STATIC) - install(TARGETS SDL2-static EXPORT SDL2staticTargets - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") -endif() - -##### Export files ##### -if (WINDOWS AND NOT MINGW) - set(PKG_PREFIX "cmake") -else () - set(PKG_PREFIX "${CMAKE_INSTALL_LIBDIR}/cmake/SDL2") -endif () - -include(CMakePackageConfigHelpers) -write_basic_package_version_file("${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake" - VERSION ${SDL_VERSION} - COMPATIBILITY AnyNewerVersion -) - -if(SDL_SHARED) - install(EXPORT SDL2Targets - FILE SDL2Targets.cmake - NAMESPACE SDL2:: - DESTINATION ${PKG_PREFIX} - ) -endif() - -if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN) - install(EXPORT SDL2mainTargets - FILE SDL2mainTargets.cmake - NAMESPACE SDL2:: - DESTINATION ${PKG_PREFIX} - ) -endif() - -if(SDL_STATIC) - install(EXPORT SDL2staticTargets - FILE SDL2staticTargets.cmake - NAMESPACE SDL2:: - DESTINATION ${PKG_PREFIX} - ) -endif() - -install( - FILES - ${CMAKE_CURRENT_SOURCE_DIR}/SDL2Config.cmake - ${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake - DESTINATION ${PKG_PREFIX} - COMPONENT Devel -) - -file(GLOB INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/*.h) -file(GLOB BIN_INCLUDE_FILES ${SDL2_BINARY_DIR}/include/*.h) -foreach(_FNAME ${BIN_INCLUDE_FILES}) - get_filename_component(_INCNAME ${_FNAME} NAME) - list(REMOVE_ITEM INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/${_INCNAME}) -endforeach() -list(APPEND INCLUDE_FILES ${BIN_INCLUDE_FILES}) -install(FILES ${INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SDL2) - -string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_BUILD_TYPE) -if (UPPER_BUILD_TYPE MATCHES DEBUG) - set(SOPOSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}") -else() - set(SOPOSTFIX "") -endif() - -if(NOT (WINDOWS OR CYGWIN) OR MINGW) +if(NOT SDL2_DISABLE_INSTALL) if(SDL_SHARED) - set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc. - get_target_property(SONAME SDL2 OUTPUT_NAME) - if(NOT ANDROID AND NOT MINGW AND NOT OS2) - install(CODE " - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink - \"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL2${SOPOSTFIX}${SOEXT}\" - WORKING_DIRECTORY \"${SDL2_BINARY_DIR}\")") - install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}") - endif() + install(TARGETS SDL2 EXPORT SDL2Targets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") endif() - if(FREEBSD) - # FreeBSD uses ${PREFIX}/libdata/pkgconfig - install(FILES ${SDL2_BINARY_DIR}/sdl2.pc DESTINATION "libdata/pkgconfig") + + if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN) + install(TARGETS SDL2main EXPORT SDL2mainTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") + endif() + + if(SDL_STATIC) + install(TARGETS SDL2-static EXPORT SDL2staticTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") + endif() + + ##### Export files ##### + if (WINDOWS AND NOT MINGW) + set(PKG_PREFIX "cmake") + else () + set(PKG_PREFIX "${CMAKE_INSTALL_LIBDIR}/cmake/SDL2") + endif () + + include(CMakePackageConfigHelpers) + write_basic_package_version_file("${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake" + VERSION ${SDL_VERSION} + COMPATIBILITY AnyNewerVersion + ) + + if(SDL_SHARED) + install(EXPORT SDL2Targets + FILE SDL2Targets.cmake + NAMESPACE SDL2:: + DESTINATION ${PKG_PREFIX} + ) + endif() + + if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN) + install(EXPORT SDL2mainTargets + FILE SDL2mainTargets.cmake + NAMESPACE SDL2:: + DESTINATION ${PKG_PREFIX} + ) + endif() + + if(SDL_STATIC) + install(EXPORT SDL2staticTargets + FILE SDL2staticTargets.cmake + NAMESPACE SDL2:: + DESTINATION ${PKG_PREFIX} + ) + endif() + + install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/SDL2Config.cmake + ${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake + DESTINATION ${PKG_PREFIX} + COMPONENT Devel + ) + + file(GLOB INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/*.h) + file(GLOB BIN_INCLUDE_FILES ${SDL2_BINARY_DIR}/include/*.h) + foreach(_FNAME ${BIN_INCLUDE_FILES}) + get_filename_component(_INCNAME ${_FNAME} NAME) + list(REMOVE_ITEM INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/${_INCNAME}) + endforeach() + list(APPEND INCLUDE_FILES ${BIN_INCLUDE_FILES}) + install(FILES ${INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SDL2) + + string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_BUILD_TYPE) + if (UPPER_BUILD_TYPE MATCHES DEBUG) + set(SOPOSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}") else() - install(FILES ${SDL2_BINARY_DIR}/sdl2.pc - DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + set(SOPOSTFIX "") + endif() + + if(NOT (WINDOWS OR CYGWIN) OR MINGW) + if(SDL_SHARED) + set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc. + get_target_property(SONAME SDL2 OUTPUT_NAME) + if(NOT ANDROID AND NOT MINGW AND NOT OS2) + install(CODE " + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink + \"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL2${SOPOSTFIX}${SOEXT}\" + WORKING_DIRECTORY \"${SDL2_BINARY_DIR}\")") + install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}") + endif() + endif() + if(FREEBSD) + # FreeBSD uses ${PREFIX}/libdata/pkgconfig + install(FILES ${SDL2_BINARY_DIR}/sdl2.pc DESTINATION "libdata/pkgconfig") + else() + install(FILES ${SDL2_BINARY_DIR}/sdl2.pc + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + endif() + install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION "${CMAKE_INSTALL_BINDIR}") + # TODO: what about the .spec file? Is it only needed for RPM creation? + install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/aclocal") endif() - install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION "${CMAKE_INSTALL_BINDIR}") - # TODO: what about the .spec file? Is it only needed for RPM creation? - install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/aclocal") endif() ##### Uninstall target ##### if(NOT SDL2_DISABLE_UNINSTALL) -if(NOT TARGET uninstall) - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - IMMEDIATE @ONLY) + if(NOT TARGET uninstall) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) - add_custom_target(uninstall - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) + add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) + endif() endif() -endif(NOT SDL2_DISABLE_UNINSTALL) + diff --git a/Engine/lib/sdl/Makefile.in b/Engine/lib/sdl/Makefile.in index 81c56fd3a..69f5cb1e2 100644 --- a/Engine/lib/sdl/Makefile.in +++ b/Engine/lib/sdl/Makefile.in @@ -19,6 +19,7 @@ distfile = $(distdir).tar.gz @SET_MAKE@ SHELL = @SHELL@ CC = @CC@ +CXX = @CXX@ INCLUDE = @INCLUDE@ CFLAGS = @BUILD_CFLAGS@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ diff --git a/Engine/lib/sdl/Makefile.os2 b/Engine/lib/sdl/Makefile.os2 index eb34494c5..cfd0d6562 100644 --- a/Engine/lib/sdl/Makefile.os2 +++ b/Engine/lib/sdl/Makefile.os2 @@ -11,7 +11,7 @@ # wmake -f Makefile.os2 HIDAPI=1 LIBNAME = SDL2 -VERSION = 2.0.21 +VERSION = 2.0.22 DESCRIPTION = Simple DirectMedia Layer 2 LIBICONV=0 @@ -60,7 +60,7 @@ CFLAGS_DLL+= -DHAVE_LIBUSB_H=1 # building SDL itself (for DECLSPEC): CFLAGS_DLL+= -DBUILD_SDL -SRCS = SDL.c SDL_assert.c SDL_error.c SDL_log.c SDL_dataqueue.c SDL_hints.c +SRCS = SDL.c SDL_assert.c SDL_error.c SDL_log.c SDL_dataqueue.c SDL_hints.c SDL_list.c SRCS+= SDL_getenv.c SDL_iconv.c SDL_malloc.c SDL_qsort.c SDL_stdlib.c SDL_string.c SDL_strtokr.c SDL_crc32.c SRCS+= SDL_cpuinfo.c SDL_atomic.c SDL_spinlock.c SDL_thread.c SDL_timer.c SRCS+= SDL_rwops.c SDL_power.c @@ -140,9 +140,11 @@ SDL_blendpoint.obj: SDL_blendpoint.c wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< SDL_RLEaccel.obj: SDL_RLEaccel.c wcc386 $(CFLAGS_DLL) -wcd=201 -fo=$^@ $< +!ifeq HIDAPI 1 # c99 mode needed because of structs with flexible array members in libusb.h SDL_hidapi.obj: SDL_hidapi.c wcc386 $(CFLAGS_DLL) -za99 -fo=$^@ $< +!endif $(LIBICONV_LIB): "src/core/os2/iconv2.lbc" @echo * Creating: $@ diff --git a/Engine/lib/sdl/WhatsNew.txt b/Engine/lib/sdl/WhatsNew.txt index 33382ecea..fa6cbe11a 100644 --- a/Engine/lib/sdl/WhatsNew.txt +++ b/Engine/lib/sdl/WhatsNew.txt @@ -6,8 +6,38 @@ This is a list of major changes in SDL's version history. --------------------------------------------------------------------------- General: +* Added SDL_RenderGetWindow() to get the window associated with a renderer +* Added floating point rectangle functions: + * SDL_PointInFRect() + * SDL_FRectEmpty() + * SDL_FRectEquals() + * SDL_FRectEqualsEpsilon() + * SDL_HasIntersectionF() + * SDL_IntersectFRect() + * SDL_UnionFRect() + * SDL_EncloseFPoints() + * SDL_IntersectFRectAndLine() +* Added SDL_IsTextInputShown() which returns whether the IME window is currently shown +* Added SDL_ClearComposition() to dismiss the composition window without disabling IME input +* Added SDL_TEXTEDITING_EXT event for handling long composition text, and a hint SDL_HINT_IME_SUPPORT_EXTENDED_TEXT to enable it +* Added the hint SDL_HINT_MOUSE_RELATIVE_MODE_CENTER to control whether the mouse should be constrained to the whole window or the center of the window when relative mode is enabled +* The mouse is now automatically captured when mouse buttons are pressed, and the hint SDL_HINT_MOUSE_AUTO_CAPTURE allows you to control this behavior +* Added the hint SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL to let SDL know that a foreign window will be used with OpenGL +* Added the hint SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN to let SDL know that a foreign window will be used with Vulkan +* Added the hint SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE to specify whether an SDL_QUIT event will be delivered when the last application window is closed * Added the hint SDL_HINT_JOYSTICK_ROG_CHAKRAM to control whether ROG Chakram mice show up as joysticks +Windows: +* Added support for SDL_BLENDOPERATION_MINIMUM and SDL_BLENDOPERATION_MAXIMUM to the D3D9 renderer + +Linux: +* Compiling with Wayland support requires libwayland-client version 1.18.0 or later +* Added the hint SDL_HINT_X11_WINDOW_TYPE to specify the _NET_WM_WINDOW_TYPE of SDL windows +* Added the hint SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR to allow using libdecor with compositors that support xdg-decoration + +Android: +* Added SDL_AndroidSendMessage() to send a custom command to the SDL java activity + --------------------------------------------------------------------------- 2.0.20: diff --git a/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist b/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist index 19049bd46..49a711322 100644 --- a/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist +++ b/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist @@ -19,10 +19,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.21 + 2.0.22 CFBundleSignature SDLX CFBundleVersion - 2.0.21 + 2.0.22 diff --git a/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj index cd8affb60..8858cfdd9 100644 --- a/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -111,6 +111,24 @@ A1626A582617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; A1626A592617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; A1626A5A2617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1BB8B6327F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6427F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6527F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6627F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6727F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6827F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6927F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6A27F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6B27F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6C27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B6D27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B6E27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B6F27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B7027F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B7127F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B7227F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B7327F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B7427F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; }; A75FCCFD23E25AB700529352 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; }; @@ -3574,6 +3592,8 @@ 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_virtualjoystick_c.h; sourceTree = ""; }; A1626A3D2617006A003F1973 /* SDL_triangle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_triangle.c; sourceTree = ""; }; A1626A512617008C003F1973 /* SDL_triangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_triangle.h; sourceTree = ""; }; + A1BB8B6127F6CF320057CFA8 /* SDL_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_list.c; sourceTree = ""; }; + A1BB8B6227F6CF330057CFA8 /* SDL_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_list.h; sourceTree = ""; }; A7381E931D8B69C300B177DD /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; A7381E951D8B69D600B177DD /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; A75FCEB323E25AB700529352 /* libSDL2.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libSDL2.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -4304,6 +4324,8 @@ A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */, A7D8A58323E2513D00DCD162 /* SDL_internal.h */, A7D8A5DD23E2513D00DCD162 /* SDL_log.c */, + A1BB8B6127F6CF320057CFA8 /* SDL_list.c */, + A1BB8B6227F6CF330057CFA8 /* SDL_list.h */, A7D8A57123E2513D00DCD162 /* SDL.c */, ); name = "Library Source"; @@ -5284,6 +5306,7 @@ A75FCD4523E25AB700529352 /* SDL_gesture_c.h in Headers */, A75FCD4623E25AB700529352 /* SDL_shaders_gl.h in Headers */, A75FCD4723E25AB700529352 /* SDL_systhread_c.h in Headers */, + A1BB8B7327F6CF330057CFA8 /* SDL_list.h in Headers */, A75FCD4823E25AB700529352 /* SDL_keycode.h in Headers */, 5616CA63252BB35F005D5928 /* SDL_sysurl.h in Headers */, A75FCD4A23E25AB700529352 /* SDL_cocoakeyboard.h in Headers */, @@ -5509,6 +5532,7 @@ A75FCEFE23E25AC700529352 /* SDL_gesture_c.h in Headers */, A75FCEFF23E25AC700529352 /* SDL_shaders_gl.h in Headers */, A75FCF0023E25AC700529352 /* SDL_systhread_c.h in Headers */, + A1BB8B7427F6CF330057CFA8 /* SDL_list.h in Headers */, A75FCF0123E25AC700529352 /* SDL_keycode.h in Headers */, 5616CA66252BB361005D5928 /* SDL_sysurl.h in Headers */, A75FCF0323E25AC700529352 /* SDL_cocoakeyboard.h in Headers */, @@ -5707,6 +5731,7 @@ A769B0C623E259AE00872273 /* SDL_windowevents_c.h in Headers */, A769B0C823E259AE00872273 /* SDL_cocoavideo.h in Headers */, 5605721C2473688D00B46B66 /* SDL_syslocale.h in Headers */, + A1BB8B7127F6CF330057CFA8 /* SDL_list.h in Headers */, A769B0CA23E259AE00872273 /* SDL_uikitevents.h in Headers */, A769B0CB23E259AE00872273 /* SDL_gesture_c.h in Headers */, A769B0CC23E259AE00872273 /* SDL_shaders_gl.h in Headers */, @@ -5955,6 +5980,7 @@ A7D8A98E23E2514000DCD162 /* SDL_sensor_c.h in Headers */, A7D8BA7423E2514400DCD162 /* SDL_shaders_gl.h in Headers */, A7D8BA5023E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, + A1BB8B6D27F6CF330057CFA8 /* SDL_list.h in Headers */, A7D8B98D23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, A7D8B99C23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, A7D8B9A223E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, @@ -6185,6 +6211,7 @@ A7D8A98F23E2514000DCD162 /* SDL_sensor_c.h in Headers */, A7D8BA7523E2514400DCD162 /* SDL_shaders_gl.h in Headers */, A7D8BA5123E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, + A1BB8B6E27F6CF330057CFA8 /* SDL_list.h in Headers */, A7D8B98E23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, A7D8B99D23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, A7D8B9A323E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, @@ -6332,6 +6359,7 @@ A7D8BBAF23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, A7D8AF0423E2514100DCD162 /* SDL_cocoavideo.h in Headers */, 5605721A2473688C00B46B66 /* SDL_syslocale.h in Headers */, + A1BB8B7027F6CF330057CFA8 /* SDL_list.h in Headers */, A7D8ACC123E2514100DCD162 /* SDL_uikitevents.h in Headers */, A7D8BB3D23E2514500DCD162 /* SDL_gesture_c.h in Headers */, A7D8BA7723E2514400DCD162 /* SDL_shaders_gl.h in Headers */, @@ -6580,6 +6608,7 @@ A7D8A98D23E2514000DCD162 /* SDL_sensor_c.h in Headers */, A7D8BA7323E2514400DCD162 /* SDL_shaders_gl.h in Headers */, A7D8BA4F23E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, + A1BB8B6C27F6CF330057CFA8 /* SDL_list.h in Headers */, A7D8B98C23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, A7D8B99B23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, A7D8B9A123E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, @@ -6796,6 +6825,7 @@ A7D8B29F23E2514200DCD162 /* vulkan_xlib.h in Headers */, A7D8B25D23E2514200DCD162 /* vulkan_vi.h in Headers */, A7D8B29923E2514200DCD162 /* vulkan_mir.h in Headers */, + A1BB8B6F27F6CF330057CFA8 /* SDL_list.h in Headers */, A7D8BB4E23E2514500DCD162 /* default_cursor.h in Headers */, A7D8B9FE23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, A7D8BBED23E2574800DCD162 /* SDL_uikitappdelegate.h in Headers */, @@ -6918,6 +6948,7 @@ A7D8BB3E23E2514500DCD162 /* SDL_gesture_c.h in Headers */, A7D8BA7823E2514400DCD162 /* SDL_shaders_gl.h in Headers */, A7D8B42D23E2514300DCD162 /* SDL_systhread_c.h in Headers */, + A1BB8B7227F6CF330057CFA8 /* SDL_list.h in Headers */, DB313FDB17554B71006C0E22 /* SDL_keycode.h in Headers */, A7D8AE9323E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, A7D8ACE623E2514100DCD162 /* SDL_uikitvulkan.h in Headers */, @@ -7554,6 +7585,7 @@ A75FCE8423E25AB700529352 /* e_exp.c in Sources */, A75FCE8523E25AB700529352 /* SDL_quit.c in Sources */, A75FCE8623E25AB700529352 /* SDL_cocoawindow.m in Sources */, + A1BB8B6A27F6CF330057CFA8 /* SDL_list.c in Sources */, A75FCE8723E25AB700529352 /* SDL_sysmutex.c in Sources */, A75FCE8823E25AB700529352 /* SDL_syshaptic.c in Sources */, F3F07D61269640160074468B /* SDL_hidapi_luna.c in Sources */, @@ -7741,6 +7773,7 @@ A75FD03D23E25AC700529352 /* e_exp.c in Sources */, A75FD03E23E25AC700529352 /* SDL_quit.c in Sources */, A75FD03F23E25AC700529352 /* SDL_cocoawindow.m in Sources */, + A1BB8B6B27F6CF330057CFA8 /* SDL_list.c in Sources */, A75FD04023E25AC700529352 /* SDL_sysmutex.c in Sources */, A75FD04123E25AC700529352 /* SDL_syshaptic.c in Sources */, F3F07D62269640160074468B /* SDL_hidapi_luna.c in Sources */, @@ -7927,6 +7960,7 @@ A769B20F23E259AE00872273 /* SDL_syshaptic.c in Sources */, A769B21023E259AE00872273 /* e_exp.c in Sources */, F395C1A12569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, + A1BB8B6827F6CF330057CFA8 /* SDL_list.c in Sources */, A769B21123E259AE00872273 /* SDL_quit.c in Sources */, A769B21223E259AE00872273 /* SDL_cocoawindow.m in Sources */, A769B21323E259AE00872273 /* SDL_sysmutex.c in Sources */, @@ -8116,6 +8150,7 @@ A7D8B43B23E2514300DCD162 /* SDL_sysmutex.c in Sources */, A7D8AAB123E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8B5CA23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, + A1BB8B6427F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8AC1023E2514100DCD162 /* SDL_video.c in Sources */, 560572062473687700B46B66 /* SDL_syslocale.m in Sources */, F3F07D5B269640160074468B /* SDL_hidapi_luna.c in Sources */, @@ -8303,6 +8338,7 @@ A7D8B43C23E2514300DCD162 /* SDL_sysmutex.c in Sources */, A7D8AAB223E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8B5CB23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, + A1BB8B6527F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8AC1123E2514100DCD162 /* SDL_video.c in Sources */, 560572072473687800B46B66 /* SDL_syslocale.m in Sources */, F3F07D5C269640160074468B /* SDL_hidapi_luna.c in Sources */, @@ -8489,6 +8525,7 @@ A7D8AADE23E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8BAE923E2514500DCD162 /* e_exp.c in Sources */, F395C1A02569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, + A1BB8B6727F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8BB8523E2514500DCD162 /* SDL_quit.c in Sources */, A7D8AEAA23E2514100DCD162 /* SDL_cocoawindow.m in Sources */, A7D8B43E23E2514300DCD162 /* SDL_sysmutex.c in Sources */, @@ -8665,6 +8702,7 @@ A7D8B55123E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96223E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7523E2514500DCD162 /* SDL_clipboardevents.c in Sources */, + A1BB8B6327F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8BAB523E2514400DCD162 /* k_cos.c in Sources */, A7D8B54523E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97423E2514400DCD162 /* SDL_malloc.c in Sources */, @@ -8850,6 +8888,7 @@ A7D8B96523E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7823E2514500DCD162 /* SDL_clipboardevents.c in Sources */, A7D8BAB823E2514400DCD162 /* k_cos.c in Sources */, + A1BB8B6627F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8B54823E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97723E2514400DCD162 /* SDL_malloc.c in Sources */, A7D8BBF023E2574800DCD162 /* SDL_uikitclipboard.m in Sources */, @@ -9035,6 +9074,7 @@ A7D8B96723E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7A23E2514500DCD162 /* SDL_clipboardevents.c in Sources */, A7D8BABA23E2514400DCD162 /* k_cos.c in Sources */, + A1BB8B6927F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8B54A23E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97923E2514400DCD162 /* SDL_malloc.c in Sources */, A7D8B8CB23E2514400DCD162 /* SDL_audio.c in Sources */, @@ -9111,7 +9151,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEPLOYMENT_POSTPROCESSING = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 19.3.0; + DYLIB_CURRENT_VERSION = 23.0.0; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_ALTIVEC_EXTENSIONS = YES; @@ -9195,7 +9235,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 19.3.0; + DYLIB_CURRENT_VERSION = 23.0.0; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -9387,6 +9427,7 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CLANG_LINK_OBJC_RUNTIME = NO; + GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION; GCC_SYMBOLS_PRIVATE_EXTERN = YES; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; @@ -9398,6 +9439,7 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CLANG_LINK_OBJC_RUNTIME = NO; + GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION; GCC_SYMBOLS_PRIVATE_EXTERN = YES; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; diff --git a/Engine/lib/sdl/build-scripts/os2-buildbot.sh b/Engine/lib/sdl/build-scripts/os2-buildbot.sh deleted file mode 100644 index abe0350d0..000000000 --- a/Engine/lib/sdl/build-scripts/os2-buildbot.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -# This is the script buildbot.libsdl.org uses to cross-compile SDL2 from -# x86 Linux to OS/2, using OpenWatcom. - -# The final zipfile can be unpacked on any machine that supports OpenWatcom -# (Windows, Linux, OS/2, etc). Point the compiler at the include directory -# and link against the SDL2.lib file. Ship the SDL2.dll with your app. - -if [ -z "$WATCOM" ]; then - echo "This script expects \$WATCOM to be set to the OpenWatcom install dir." 1>&2 - echo "This is often something like '/usr/local/share/watcom'" 1>&2 - exit 1 -fi -export PATH="$WATCOM/binl64:$PATH" - -ZIPFILE="$1" -if [ -z $1 ]; then - ZIPFILE=sdl-os2.zip -fi -ZIPDIR=buildbot/SDL - -set -e -set -x - -cd `dirname "$0"` -cd .. - -rm -f $ZIPFILE -wmake -f Makefile.os2 -rm -rf $ZIPDIR -mkdir -p $ZIPDIR -chmod 644 SDL2.dll SDL2.lib SDL2test.lib -mv SDL2.dll SDL2.lib SDL2test.lib $ZIPDIR/ -cp -R include $ZIPDIR/ -zip -9r "buildbot/$ZIPFILE" $ZIPDIR - -wmake -f Makefile.os2 distclean - -set +x -echo "All done. Final installable is in $ZIPFILE ..."; diff --git a/Engine/lib/sdl/build-scripts/winrtbuild.ps1 b/Engine/lib/sdl/build-scripts/winrtbuild.ps1 index 1da76abb1..892658014 100644 --- a/Engine/lib/sdl/build-scripts/winrtbuild.ps1 +++ b/Engine/lib/sdl/build-scripts/winrtbuild.ps1 @@ -39,7 +39,7 @@ # # Base version of SDL, used for packaging purposes -$SDLVersion = "2.0.21" +$SDLVersion = "2.0.22" # Gets the .bat file that sets up an MSBuild environment, given one of # Visual Studio's, "PlatformToolset"s. diff --git a/Engine/lib/sdl/cmake/sdlchecks.cmake b/Engine/lib/sdl/cmake/sdlchecks.cmake index c9feffb69..8dcb39265 100644 --- a/Engine/lib/sdl/cmake/sdlchecks.cmake +++ b/Engine/lib/sdl/cmake/sdlchecks.cmake @@ -632,7 +632,7 @@ endmacro() # - HAVE_SDL_LOADSO opt macro(CheckWayland) if(SDL_WAYLAND) - pkg_check_modules(WAYLAND wayland-client wayland-egl wayland-cursor egl "xkbcommon>=0.5.0") + pkg_check_modules(WAYLAND "wayland-client>=1.18" wayland-egl wayland-cursor egl "xkbcommon>=0.5.0") if(WAYLAND_FOUND) find_program(WAYLAND_SCANNER NAMES wayland-scanner REQUIRED) @@ -792,7 +792,9 @@ macro(CheckVivante) set(SDL_VIDEO_DRIVER_VIVANTE 1) if(HAVE_VIVANTE_VDK) set(SDL_VIDEO_DRIVER_VIVANTE_VDK 1) - list(APPEND EXTRA_LIBS VDK VIVANTE) + find_library(VIVANTE_LIBRARY REQUIRED NAMES VIVANTE vivante drm_vivante) + find_library(VIVANTE_VDK_LIBRARY VDK REQUIRED) + list(APPEND EXTRA_LIBS ${VIVANTE_LIBRARY} ${VIVANTE_VDK_LIBRARY}) else() set(SDL_CFLAGS "${SDL_CFLAGS} -DLINUX -DEGL_API_FB") list(APPEND EXTRA_LIBS EGL) diff --git a/Engine/lib/sdl/configure b/Engine/lib/sdl/configure index df73ab0cb..f3ea813eb 100755 --- a/Engine/lib/sdl/configure +++ b/Engine/lib/sdl/configure @@ -673,6 +673,8 @@ X_CFLAGS XMKMF RPI_LIBS RPI_CFLAGS +DECOR_LIBS +DECOR_CFLAGS FUSIONSOUND_LIBS FUSIONSOUND_CFLAGS ARTSCONFIG @@ -944,6 +946,8 @@ PULSEAUDIO_CFLAGS PULSEAUDIO_LIBS FUSIONSOUND_CFLAGS FUSIONSOUND_LIBS +DECOR_CFLAGS +DECOR_LIBS RPI_CFLAGS RPI_LIBS XMKMF @@ -1779,6 +1783,9 @@ Some influential environment variables: C compiler flags for FUSIONSOUND, overriding pkg-config FUSIONSOUND_LIBS linker flags for FUSIONSOUND, overriding pkg-config + DECOR_CFLAGS + C compiler flags for DECOR, overriding pkg-config + DECOR_LIBS linker flags for DECOR, overriding pkg-config RPI_CFLAGS C compiler flags for RPI, overriding pkg-config RPI_LIBS linker flags for RPI, overriding pkg-config XMKMF Path to xmkmf, Makefile generator for X Window System @@ -2859,9 +2866,9 @@ orig_CFLAGS="$CFLAGS" # SDL_MAJOR_VERSION=2 SDL_MINOR_VERSION=0 -SDL_MICRO_VERSION=21 -SDL_INTERFACE_AGE=3 -SDL_BINARY_AGE=21 +SDL_MICRO_VERSION=22 +SDL_INTERFACE_AGE=0 +SDL_BINARY_AGE=22 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION @@ -20572,7 +20579,7 @@ $as_echo_n "checking for Wayland support... " >&6; } video_wayland=no if test x$video_opengl_egl = xyes && \ test x$video_opengles_v2 = xyes; then - if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-egl wayland-cursor egl 'xkbcommon >= 0.5.0'; then + if $PKG_CONFIG --exists 'wayland-client >= 1.18' wayland-scanner wayland-egl wayland-cursor egl 'xkbcommon >= 0.5.0'; then WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon` WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon` WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner` @@ -20676,17 +20683,79 @@ else fi if test x$enable_libdecor = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdecor support" >&5 -$as_echo_n "checking for libdecor support... " >&6; } - if $PKG_CONFIG --exists libdecor-0; then : - video_libdecor=yes + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdecor-0" >&5 +$as_echo_n "checking for libdecor-0... " >&6; } + +if test -n "$DECOR_CFLAGS"; then + pkg_cv_DECOR_CFLAGS="$DECOR_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdecor-0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdecor-0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DECOR_CFLAGS=`$PKG_CONFIG --cflags "libdecor-0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - video_libdecor=no + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$DECOR_LIBS"; then + pkg_cv_DECOR_LIBS="$DECOR_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdecor-0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdecor-0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DECOR_LIBS=`$PKG_CONFIG --libs "libdecor-0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + DECOR_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdecor-0" 2>&1` + else + DECOR_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdecor-0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$DECOR_PKG_ERRORS" >&5 + + video_libdecor=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + video_libdecor=no +else + DECOR_CFLAGS=$pkg_cv_DECOR_CFLAGS + DECOR_LIBS=$pkg_cv_DECOR_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + video_libdecor=yes fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_libdecor" >&5 -$as_echo "$video_libdecor" >&6; } if test x$video_libdecor = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags libdecor-0`" + EXTRA_CFLAGS="$EXTRA_CFLAGS $DECOR_CFLAGS" $as_echo "#define HAVE_LIBDECOR_H 1" >>confdefs.h @@ -20699,18 +20768,16 @@ else fi + decor_lib=`find_lib "libdecor-0.so.*" "$DECOR_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` + if test x$enable_wayland_shared != xyes; then enable_libdecor_shared=no fi - - decor_lib=`find_lib "libdecor-0.so.*" "" | sed 's/.*\/\(.*\)/\1/; q'` - if test x$have_loadso != xyes && \ test x$enable_libdecor_shared = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic libdecor loading" >&5 $as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic libdecor loading" >&2;} fi - if test x$have_loadso = xyes && \ test x$enable_libdecor_shared = xyes && test x$decor_lib != x; then echo "-- dynamic libdecor -> $decor_lib" @@ -20720,7 +20787,7 @@ cat >>confdefs.h <<_ACEOF _ACEOF else - EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$PKG_CONFIG --libs libdecor-0`" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS $DECOR_LIBS" fi fi fi @@ -24712,6 +24779,30 @@ $as_echo "$have_wince" >&6; } # This fixes Windows stack alignment with newer GCC CheckStackBoundary + + # headers needed elsewhere + ac_fn_c_check_header_mongrel "$LINENO" "tpcshrd.h" "ac_cv_header_tpcshrd_h" "$ac_includes_default" +if test "x$ac_cv_header_tpcshrd_h" = xyes; then : + have_tpcshrd_h=yes +fi + + + if test x$have_tpcshrd_h = xyes; then + +$as_echo "#define HAVE_TPCSHRD_H 1" >>confdefs.h + + fi + ac_fn_c_check_header_mongrel "$LINENO" "roapi.h" "ac_cv_header_roapi_h" "$ac_includes_default" +if test "x$ac_cv_header_roapi_h" = xyes; then : + have_roapi_h=yes +fi + + + if test x$have_roapi_h = xyes; then + +$as_echo "#define HAVE_ROAPI_H 1" >>confdefs.h + + fi } CheckOS2() @@ -26188,17 +26279,6 @@ $as_echo "#define SDL_HAPTIC_DINPUT 1" >>confdefs.h have_haptic=yes fi fi - ac_fn_c_check_header_mongrel "$LINENO" "tpcshrd.h" "ac_cv_header_tpcshrd_h" "$ac_includes_default" -if test "x$ac_cv_header_tpcshrd_h" = xyes; then : - have_tpcshrd_h=yes -fi - - - if test x$have_tpcshrd_h = xyes; then - -$as_echo "#define HAVE_TPCSHRD_H 1" >>confdefs.h - - fi # Set up files for the sensor library ac_fn_c_check_header_mongrel "$LINENO" "sensorsapi.h" "ac_cv_header_sensorsapi_h" "$ac_includes_default" if test "x$ac_cv_header_sensorsapi_h" = xyes; then : diff --git a/Engine/lib/sdl/configure.ac b/Engine/lib/sdl/configure.ac index 28d620d94..2209c04d7 100644 --- a/Engine/lib/sdl/configure.ac +++ b/Engine/lib/sdl/configure.ac @@ -22,9 +22,9 @@ dnl Set various version strings - taken gratefully from the GTk sources # SDL_MAJOR_VERSION=2 SDL_MINOR_VERSION=0 -SDL_MICRO_VERSION=21 -SDL_INTERFACE_AGE=3 -SDL_BINARY_AGE=21 +SDL_MICRO_VERSION=22 +SDL_INTERFACE_AGE=0 +SDL_BINARY_AGE=22 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION AC_SUBST(SDL_MAJOR_VERSION) @@ -1555,7 +1555,7 @@ CheckWayland() video_wayland=no if test x$video_opengl_egl = xyes && \ test x$video_opengles_v2 = xyes; then - if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-egl wayland-cursor egl 'xkbcommon >= 0.5.0'; then + if $PKG_CONFIG --exists 'wayland-client >= 1.18' wayland-scanner wayland-egl wayland-cursor egl 'xkbcommon >= 0.5.0'; then WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon` WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon` WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner` @@ -1626,39 +1626,31 @@ dnl FIXME: Do BSD and OS X need special cases? dnl See if libdecor is available AC_ARG_ENABLE(libdecor, -[AS_HELP_STRING([--enable-libdecor], [use libdecor for Wayland client-side decorations [default=yes]])], - , enable_libdecor=yes) +[AS_HELP_STRING([--enable-libdecor], [use libdecor for Wayland client-side decorations [default=yes]])],, enable_libdecor=yes) if test x$enable_libdecor = xyes; then - AC_MSG_CHECKING(for libdecor support) - AS_IF([$PKG_CONFIG --exists libdecor-0], - [video_libdecor=yes], - [video_libdecor=no]) - AC_MSG_RESULT($video_libdecor) + PKG_CHECK_MODULES([DECOR], [libdecor-0], video_libdecor=yes, video_libdecor=no) if test x$video_libdecor = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags libdecor-0`" + EXTRA_CFLAGS="$EXTRA_CFLAGS $DECOR_CFLAGS" AC_DEFINE(HAVE_LIBDECOR_H, 1, [ ]) AC_ARG_ENABLE(libdecor-shared, -[AS_HELP_STRING([--enable-libdecor-shared], [dynamically load libdecor [default=yes]])], - , enable_libdecor_shared=yes) +[AS_HELP_STRING([--enable-libdecor-shared], [dynamically load libdecor [default=yes]])],, enable_libdecor_shared=yes) + + decor_lib=[`find_lib "libdecor-0.so.*" "$DECOR_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] if test x$enable_wayland_shared != xyes; then enable_libdecor_shared=no fi - - decor_lib=[`find_lib "libdecor-0.so.*" "" | sed 's/.*\/\(.*\)/\1/; q'`] - if test x$have_loadso != xyes && \ test x$enable_libdecor_shared = xyes; then AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic libdecor loading]) fi - if test x$have_loadso = xyes && \ test x$enable_libdecor_shared = xyes && test x$decor_lib != x; then echo "-- dynamic libdecor -> $decor_lib" AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR, "$decor_lib", [ ]) else - EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$PKG_CONFIG --libs libdecor-0`" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS $DECOR_LIBS" fi fi fi @@ -3206,6 +3198,16 @@ CheckWINDOWS() # This fixes Windows stack alignment with newer GCC CheckStackBoundary + + # headers needed elsewhere + AC_CHECK_HEADER(tpcshrd.h,have_tpcshrd_h=yes) + if test x$have_tpcshrd_h = xyes; then + AC_DEFINE(HAVE_TPCSHRD_H, 1, [ ]) + fi + AC_CHECK_HEADER(roapi.h,have_roapi_h=yes) + if test x$have_roapi_h = xyes; then + AC_DEFINE(HAVE_ROAPI_H, 1, [ ]) + fi } dnl Determine whether the compiler can produce OS/2 executables @@ -4007,10 +4009,6 @@ case "$host" in have_haptic=yes fi fi - AC_CHECK_HEADER(tpcshrd.h,have_tpcshrd_h=yes) - if test x$have_tpcshrd_h = xyes; then - AC_DEFINE(HAVE_TPCSHRD_H, 1, [ ]) - fi # Set up files for the sensor library AC_CHECK_HEADER(sensorsapi.h,have_winsensors=yes,have_winsensors=no) if test x$have_winsensors = xyes; then diff --git a/Engine/lib/sdl/docs/README-directfb.md b/Engine/lib/sdl/docs/README-directfb.md index 67b64fb61..6672fa40e 100644 --- a/Engine/lib/sdl/docs/README-directfb.md +++ b/Engine/lib/sdl/docs/README-directfb.md @@ -15,29 +15,34 @@ What you need: * Kernel-Framebuffer support: required: vesafb, radeonfb .... * Mesa 7.0.x - optional for OpenGL -/etc/directfbrc - -This file should contain the following lines to make +The `/etc/directfbrc` file should contain the following lines to make your joystick work and avoid crashes: ------------------------- + +``` disable-module=joystick disable-module=cle266 disable-module=cyber5k no-linux-input-grab ------------------------- +``` To disable to use x11 backend when DISPLAY variable is found use +``` export SDL_DIRECTFB_X11_CHECK=0 +``` To disable the use of linux input devices, i.e. multimice/multikeyboard support, use +``` export SDL_DIRECTFB_LINUX_INPUT=0 +``` To use hardware accelerated YUV-overlays for YUV-textures, use: +``` export SDL_DIRECTFB_YUV_DIRECT=1 +``` This is disabled by default. It will only support one YUV texture, namely the first. Every other YUV texture will be @@ -45,7 +50,9 @@ rendered in software. In addition, you may use (directfb-1.2.x) +``` export SDL_DIRECTFB_YUV_UNDERLAY=1 +``` to make the YUV texture an underlay. This will make the cursor to be shown. @@ -54,14 +61,18 @@ Simple Window Manager ===================== The driver has support for a very, very basic window manager you may -want to use when running with "wm=default". Use +want to use when running with `wm=default`. Use +``` export SDL_DIRECTFB_WM=1 +``` to enable basic window borders. In order to have the window title rendered, you need to have the following font installed: +``` /usr/share/fonts/truetype/freefont/FreeSans.ttf +``` OpenGL Support ============== @@ -71,21 +82,25 @@ works at least on all directfb supported platforms. As of this writing 20100802 you need to pull Mesa from git and do the following: ------------------------- +``` git clone git://anongit.freedesktop.org/git/mesa/mesa cd mesa git checkout 2c9fdaf7292423c157fc79b5ce43f0f199dd753a ------------------------- +``` -Edit configs/linux-directfb so that the Directories-section looks like ------------------------- +Edit `configs/linux-directfb` so that the Directories-section looks like this: + +``` # Directories SRC_DIRS = mesa glu GLU_DIRS = sgi DRIVER_DIRS = directfb PROGRAM_DIRS = ------------------------- +``` +Then do the following: + +``` make linux-directfb make @@ -95,13 +110,14 @@ sudo make install INSTALL_DIR=/usr/local/dfb_GL cd src/mesa/drivers/directfb make sudo make install INSTALL_DIR=/usr/local/dfb_GL ------------------------- +``` To run the SDL - testprograms: +``` export SDL_VIDEODRIVER=directfb export LD_LIBRARY_PATH=/usr/local/dfb_GL/lib export LD_PRELOAD=/usr/local/dfb_GL/libGL.so.7 ./testgl - +``` diff --git a/Engine/lib/sdl/docs/README-visualc.md b/Engine/lib/sdl/docs/README-visualc.md index ea2bc1852..759752a56 100644 --- a/Engine/lib/sdl/docs/README-visualc.md +++ b/Engine/lib/sdl/docs/README-visualc.md @@ -1,7 +1,7 @@ Using SDL with Microsoft Visual C++ =================================== -### by [Lion Kimbro](mailto:snowlion@sprynet.com) with additions by [James Turk](mailto:james@conceptofzero.net) +### by Lion Kimbro with additions by James Turk You can either use the precompiled libraries from the [SDL](https://www.libsdl.org/download.php) web site, or you can build SDL yourself. diff --git a/Engine/lib/sdl/docs/README-vita.md b/Engine/lib/sdl/docs/README-vita.md index 535b4034c..503fef7d5 100644 --- a/Engine/lib/sdl/docs/README-vita.md +++ b/Engine/lib/sdl/docs/README-vita.md @@ -22,6 +22,9 @@ Notes * gles1/gles2 support and renderers are disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PVR=ON` These renderers support 720p and 1080i resolutions. These can be specified with: `SDL_setenv("VITA_RESOLUTION", "720", 1);` and `SDL_setenv("VITA_RESOLUTION", "1080", 1);` +* Desktop GL 1.X and 2.X support and renderers are also disabled by default and also can be enabled with `-DVIDEO_VITA_PVR=ON` as long as gl4es4vita is present in your SDK. + They support the same resolutions as the gles1/gles2 backends and require specifying `SDL_setenv("VITA_PVR_OGL", "1", 1);` + anytime before video subsystem initialization. * gles2 support via PIB is disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PIB=ON` * By default SDL emits mouse events for touch events on every touchscreen. Vita has two touchscreens, so it's recommended to use `SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");` and handle touch events instead. diff --git a/Engine/lib/sdl/docs/README-windows.md b/Engine/lib/sdl/docs/README-windows.md index 71f968eeb..ed0c93e2c 100644 --- a/Engine/lib/sdl/docs/README-windows.md +++ b/Engine/lib/sdl/docs/README-windows.md @@ -1,45 +1,58 @@ -Windows -================================================================================ +# Windows -================================================================================ -OpenGL ES 2.x support -================================================================================ +## LLVM and Intel C++ compiler support -SDL has support for OpenGL ES 2.x under Windows via two alternative -implementations. -The most straightforward method consists in running your app in a system with -a graphic card paired with a relatively recent (as of November of 2013) driver -which supports the WGL_EXT_create_context_es2_profile extension. Vendors known +SDL will build with the Visual Studio project files with LLVM-based compilers, such as the Intel oneAPI C++ +compiler, but you'll have to manually add the "-msse3" command line option +to at least the SDL_audiocvt.c source file, and possibly others. This may +not be necessary if you build SDL with CMake instead of the included Visual +Studio solution. + +Details are here: https://github.com/libsdl-org/SDL/issues/5186 + + +## OpenGL ES 2.x support + +SDL has support for OpenGL ES 2.x under Windows via two alternative +implementations. + +The most straightforward method consists in running your app in a system with +a graphic card paired with a relatively recent (as of November of 2013) driver +which supports the WGL_EXT_create_context_es2_profile extension. Vendors known to ship said extension on Windows currently include nVidia and Intel. -The other method involves using the ANGLE library (https://code.google.com/p/angleproject/) -If an OpenGL ES 2.x context is requested and no WGL_EXT_create_context_es2_profile -extension is found, SDL will try to load the libEGL.dll library provided by -ANGLE. +The other method involves using the +[ANGLE library](https://code.google.com/p/angleproject/). If an OpenGL ES 2.x +context is requested and no WGL_EXT_create_context_es2_profile extension is +found, SDL will try to load the libEGL.dll library provided by ANGLE. + To obtain the ANGLE binaries, you can either compile from source from -https://chromium.googlesource.com/angle/angle or copy the relevant binaries from -a recent Chrome/Chromium install for Windows. The files you need are: - - * libEGL.dll - * libGLESv2.dll - * d3dcompiler_46.dll (supports Windows Vista or later, better shader compiler) - or... - * d3dcompiler_43.dll (supports Windows XP or later) +https://chromium.googlesource.com/angle/angle or copy the relevant binaries +from a recent Chrome/Chromium install for Windows. The files you need are: + +- libEGL.dll +- libGLESv2.dll +- d3dcompiler_46.dll (supports Windows Vista or later, better shader + compiler) *or* d3dcompiler_43.dll (supports Windows XP or later) If you compile ANGLE from source, you can configure it so it does not need the -d3dcompiler_* DLL at all (for details on this, see their documentation). +d3dcompiler_* DLL at all (for details on this, see their documentation). However, by default SDL will try to preload the d3dcompiler_46.dll to -comply with ANGLE's requirements. If you wish SDL to preload d3dcompiler_43.dll (to -support Windows XP) or to skip this step at all, you can use the -SDL_HINT_VIDEO_WIN_D3DCOMPILER hint (see SDL_hints.h for more details). +comply with ANGLE's requirements. If you wish SDL to preload +d3dcompiler_43.dll (to support Windows XP) or to skip this step at all, you +can use the SDL_HINT_VIDEO_WIN_D3DCOMPILER hint (see SDL_hints.h for more +details). Known Bugs: - - * SDL_GL_SetSwapInterval is currently a no op when using ANGLE. It appears - that there's a bug in the library which prevents the window contents from - refreshing if this is set to anything other than the default value. - -Vulkan Surface Support -============== -Support for creating Vulkan surfaces is configured on by default. To disable it change the value of `SDL_VIDEO_VULKAN` to 0 in `SDL_config_windows.h`. You must install the [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) in order to use Vulkan graphics in your application. +- SDL_GL_SetSwapInterval is currently a no op when using ANGLE. It appears + that there's a bug in the library which prevents the window contents from + refreshing if this is set to anything other than the default value. + +## Vulkan Surface Support + +Support for creating Vulkan surfaces is configured on by default. To disable +it change the value of `SDL_VIDEO_VULKAN` to 0 in `SDL_config_windows.h`. You +must install the [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) in order to +use Vulkan graphics in your application. + diff --git a/Engine/lib/sdl/include/SDL_blendmode.h b/Engine/lib/sdl/include/SDL_blendmode.h index b6d140dbb..08c9f9dd6 100644 --- a/Engine/lib/sdl/include/SDL_blendmode.h +++ b/Engine/lib/sdl/include/SDL_blendmode.h @@ -67,9 +67,8 @@ typedef enum SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */ SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< dst - src : supported by D3D9, D3D11, OpenGL, OpenGLES */ SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< src - dst : supported by D3D9, D3D11, OpenGL, OpenGLES */ - SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D11 */ - SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D11 */ - + SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D9, D3D11 */ + SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D9, D3D11 */ } SDL_BlendOperation; /** @@ -87,7 +86,6 @@ typedef enum SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */ SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */ SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */ - } SDL_BlendFactor; /** @@ -135,10 +133,10 @@ typedef enum * SDL 2.0.6. All renderers support the four blend modes listed in the * SDL_BlendMode enumeration. * - * - **direct3d**: Supports `SDL_BLENDOPERATION_ADD` with all factors. - * - **direct3d11**: Supports all operations with all factors. However, some + * - **direct3d**: Supports all operations with all factors. However, some * factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and * `SDL_BLENDOPERATION_MAXIMUM`. + * - **direct3d11**: Same as Direct3D 9. * - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all * factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly with SDL * 2.0.6. diff --git a/Engine/lib/sdl/include/SDL_config.h.cmake b/Engine/lib/sdl/include/SDL_config.h.cmake index 9a1bf6758..fcd18e57d 100644 --- a/Engine/lib/sdl/include/SDL_config.h.cmake +++ b/Engine/lib/sdl/include/SDL_config.h.cmake @@ -253,6 +253,7 @@ #cmakedefine HAVE_AUDIOCLIENT_H @HAVE_AUDIOCLIENT_H@ #cmakedefine HAVE_TPCSHRD_H @HAVE_TPCSHRD_H@ #cmakedefine HAVE_SENSORSAPI_H @HAVE_SENSORSAPI_H@ +#cmakedefine HAVE_ROAPI_H @HAVE_ROAPI_H@ #cmakedefine HAVE_XINPUT_GAMEPAD_EX @HAVE_XINPUT_GAMEPAD_EX@ #cmakedefine HAVE_XINPUT_STATE_EX @HAVE_XINPUT_STATE_EX@ @@ -520,6 +521,7 @@ #cmakedefine SDL_VIDEO_VITA_PIB @SDL_VIDEO_VITA_PIB@ #cmakedefine SDL_VIDEO_VITA_PVR @SDL_VIDEO_VITA_PVR@ +#cmakedefine SDL_VIDEO_VITA_PVR_OGL @SDL_VIDEO_VITA_PVR_OGL@ #if !defined(__WIN32__) && !defined(__WINRT__) # if !defined(_STDINT_H_) && !defined(_STDINT_H) && !defined(HAVE_STDINT_H) && !defined(_HAVE_STDINT_H) diff --git a/Engine/lib/sdl/include/SDL_config.h.in b/Engine/lib/sdl/include/SDL_config.h.in index 195b9887e..f912e4112 100644 --- a/Engine/lib/sdl/include/SDL_config.h.in +++ b/Engine/lib/sdl/include/SDL_config.h.in @@ -242,6 +242,7 @@ #undef HAVE_AUDIOCLIENT_H #undef HAVE_TPCSHRD_H #undef HAVE_SENSORSAPI_H +#undef HAVE_ROAPI_H /* SDL internal assertion support */ #undef SDL_DEFAULT_ASSERT_LEVEL diff --git a/Engine/lib/sdl/include/SDL_config_emscripten.h b/Engine/lib/sdl/include/SDL_config_emscripten.h index 7efe32373..028777df1 100644 --- a/Engine/lib/sdl/include/SDL_config_emscripten.h +++ b/Engine/lib/sdl/include/SDL_config_emscripten.h @@ -185,6 +185,7 @@ /* Enable various threading systems */ #ifdef __EMSCRIPTEN_PTHREADS__ #define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 #endif /* Enable various timer systems */ diff --git a/Engine/lib/sdl/include/SDL_config_windows.h b/Engine/lib/sdl/include/SDL_config_windows.h index efb246da9..770b19039 100644 --- a/Engine/lib/sdl/include/SDL_config_windows.h +++ b/Engine/lib/sdl/include/SDL_config_windows.h @@ -104,6 +104,7 @@ typedef unsigned int uintptr_t; #endif #if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0602 /* Windows 8 SDK */ #define HAVE_D3D11_H 1 +#define HAVE_ROAPI_H 1 #endif #define HAVE_MMDEVICEAPI_H 1 #define HAVE_AUDIOCLIENT_H 1 diff --git a/Engine/lib/sdl/include/SDL_config_winrt.h b/Engine/lib/sdl/include/SDL_config_winrt.h index c548fd695..f3901a597 100644 --- a/Engine/lib/sdl/include/SDL_config_winrt.h +++ b/Engine/lib/sdl/include/SDL_config_winrt.h @@ -195,6 +195,8 @@ typedef unsigned int uintptr_t; #define HAVE_TRUNCF 1 #define HAVE__FSEEKI64 1 +#define HAVE_ROAPI_H 1 + /* Enable various audio drivers */ #define SDL_AUDIO_DRIVER_WASAPI 1 #define SDL_AUDIO_DRIVER_DISK 1 diff --git a/Engine/lib/sdl/include/SDL_hints.h b/Engine/lib/sdl/include/SDL_hints.h index 133f68769..ea819c85d 100644 --- a/Engine/lib/sdl/include/SDL_hints.h +++ b/Engine/lib/sdl/include/SDL_hints.h @@ -1354,6 +1354,18 @@ extern "C" { */ #define SDL_HINT_TOUCH_MOUSE_EVENTS "SDL_TOUCH_MOUSE_EVENTS" +/** + * \brief A variable controlling which touchpad should generate synthetic mouse events + * + * This variable can be set to the following values: + * "0" - Only front touchpad should generate mouse events. Default + * "1" - Only back touchpad should generate mouse events. + * "2" - Both touchpads should generate mouse events. + * + * By default SDL will generate mouse events for all touch devices + */ +#define SDL_HINT_VITA_TOUCH_MOUSE_DEVICE "SDL_HINT_VITA_TOUCH_MOUSE_DEVICE" + /** * \brief A variable controlling whether the Android / tvOS remotes * should be listed as joystick devices, instead of sending keyboard events. @@ -1463,6 +1475,20 @@ extern "C" { */ #define SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR "SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR" +/** + * \brief A variable controlling whether the libdecor Wayland backend is preferred over native decrations. + * + * When this hint is set, libdecor will be used to provide window decorations, even if xdg-decoration is + * available. (Note that, by default, libdecor will use xdg-decoration itself if available). + * + * This variable can be set to the following values: + * "0" - libdecor is enabled only if server-side decorations are unavailable. + * "1" - libdecor is always enabled if available. + * + * libdecor is used over xdg-shell when xdg-decoration protocol is unavailable. + */ +#define SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR "SDL_VIDEO_WAYLAND_PREFER_LIBDECOR" + /** * \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p"). * @@ -1938,8 +1964,7 @@ extern "C" { * If not set or set to "", this hint is ignored. This hint must be set * before the SDL_CreateWindow() call that it is intended to affect. * - * This hint is available since SDL 2.0.22. Before then, virtual devices are - * always ignored. + * This hint is available since SDL 2.0.22. */ #define SDL_HINT_X11_WINDOW_TYPE "SDL_X11_WINDOW_TYPE" @@ -1968,6 +1993,53 @@ extern "C" { #define SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE "SDL_QUIT_ON_LAST_WINDOW_CLOSE" +/** + * \brief A variable that decides what video backend to use. + * + * By default, SDL will try all available video backends in a reasonable + * order until it finds one that can work, but this hint allows the app + * or user to force a specific target, such as "x11" if, say, you are + * on Wayland but want to try talking to the X server instead. + * + * This functionality has existed since SDL 2.0.0 (indeed, before that) + * but before 2.0.22 this was an environment variable only. In 2.0.22, + * it was upgraded to a full SDL hint, so you can set the environment + * variable as usual or programatically set the hint with SDL_SetHint, + * which won't propagate to child processes. + * + * The default value is unset, in which case SDL will try to figure out + * the best video backend on your behalf. This hint needs to be set + * before SDL_Init() is called to be useful. + * + * This hint is available since SDL 2.0.22. Before then, you could set + * the environment variable to get the same effect. + */ +#define SDL_HINT_VIDEODRIVER "SDL_VIDEODRIVER" + +/** + * \brief A variable that decides what audio backend to use. + * + * By default, SDL will try all available audio backends in a reasonable + * order until it finds one that can work, but this hint allows the app + * or user to force a specific target, such as "alsa" if, say, you are + * on PulseAudio but want to try talking to the lower level instead. + * + * This functionality has existed since SDL 2.0.0 (indeed, before that) + * but before 2.0.22 this was an environment variable only. In 2.0.22, + * it was upgraded to a full SDL hint, so you can set the environment + * variable as usual or programatically set the hint with SDL_SetHint, + * which won't propagate to child processes. + * + * The default value is unset, in which case SDL will try to figure out + * the best audio backend on your behalf. This hint needs to be set + * before SDL_Init() is called to be useful. + * + * This hint is available since SDL 2.0.22. Before then, you could set + * the environment variable to get the same effect. + */ +#define SDL_HINT_AUDIODRIVER "SDL_AUDIODRIVER" + + /** * \brief An enumeration of hint priorities */ diff --git a/Engine/lib/sdl/include/SDL_metal.h b/Engine/lib/sdl/include/SDL_metal.h index 9ecaa8151..eb3082879 100644 --- a/Engine/lib/sdl/include/SDL_metal.h +++ b/Engine/lib/sdl/include/SDL_metal.h @@ -92,6 +92,7 @@ extern DECLSPEC void *SDLCALL SDL_Metal_GetLayer(SDL_MetalView view); * * \param window SDL_Window from which the drawable size should be queried * \param w Pointer to variable for storing the width in pixels, may be NULL + * \param h Pointer to variable for storing the height in pixels, may be NULL * * \since This function is available since SDL 2.0.14. * diff --git a/Engine/lib/sdl/include/SDL_rect.h b/Engine/lib/sdl/include/SDL_rect.h index 55a6473f2..b678c7a34 100644 --- a/Engine/lib/sdl/include/SDL_rect.h +++ b/Engine/lib/sdl/include/SDL_rect.h @@ -54,11 +54,6 @@ typedef struct SDL_Point /** * The structure that defines a point (floating point) * - * \sa SDL_FRectEmpty - * \sa SDL_FRectEquals - * \sa SDL_HasIntersectionF - * \sa SDL_IntersectFRect - * \sa SDL_UnionFRect * \sa SDL_EncloseFPoints * \sa SDL_PointInFRect */ @@ -76,6 +71,7 @@ typedef struct SDL_FPoint * \sa SDL_RectEquals * \sa SDL_HasIntersection * \sa SDL_IntersectRect + * \sa SDL_IntersectRectAndLine * \sa SDL_UnionRect * \sa SDL_EnclosePoints */ @@ -88,6 +84,16 @@ typedef struct SDL_Rect /** * A rectangle, with the origin at the upper left (floating point). + * + * \sa SDL_FRectEmpty + * \sa SDL_FRectEquals + * \sa SDL_FRectEqualsEpsilon + * \sa SDL_HasIntersectionF + * \sa SDL_IntersectFRect + * \sa SDL_IntersectFRectAndLine + * \sa SDL_UnionFRect + * \sa SDL_EncloseFPoints + * \sa SDL_PointInFRect */ typedef struct SDL_FRect { @@ -239,12 +245,28 @@ SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r) } /** - * Returns true if the two rectangles are equal. + * Returns true if the two rectangles are equal, within some given epsilon. + * + * \since This function is available since SDL 2.0.22. + */ +SDL_FORCE_INLINE SDL_bool SDL_FRectEqualsEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon) +{ + return (a && b && ((a == b) || + ((SDL_fabs(a->x - b->x) <= epsilon) && + (SDL_fabs(a->y - b->y) <= epsilon) && + (SDL_fabs(a->w - b->w) <= epsilon) && + (SDL_fabs(a->h - b->h) <= epsilon)))) + ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the two rectangles are equal, using a default epsilon. + * + * \since This function is available since SDL 2.0.22. */ SDL_FORCE_INLINE SDL_bool SDL_FRectEquals(const SDL_FRect *a, const SDL_FRect *b) { - return (a && b && (a->x == b->x) && (a->y == b->y) && - (a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE; + return SDL_FRectEqualsEpsilon(a, b, SDL_FLT_EPSILON); } /** diff --git a/Engine/lib/sdl/include/SDL_render.h b/Engine/lib/sdl/include/SDL_render.h index 88620336b..d859e3fd6 100644 --- a/Engine/lib/sdl/include/SDL_render.h +++ b/Engine/lib/sdl/include/SDL_render.h @@ -261,6 +261,17 @@ extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateSoftwareRenderer(SDL_Surface * */ extern DECLSPEC SDL_Renderer * SDLCALL SDL_GetRenderer(SDL_Window * window); +/** + * Get the window associated with a renderer. + * + * \param renderer the renderer to query + * \returns the window on success or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_RenderGetWindow(SDL_Renderer *renderer); + /** * Get information about a rendering context. * @@ -1607,6 +1618,7 @@ extern DECLSPEC int SDLCALL SDL_RenderCopyExF(SDL_Renderer * renderer, * vertex array Color and alpha modulation is done per vertex * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). * + * \param renderer The rendering context. * \param texture (optional) The SDL texture to use. * \param vertices Vertices. * \param num_vertices Number of vertices. @@ -1631,6 +1643,7 @@ extern DECLSPEC int SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer, * vertex arrays Color and alpha modulation is done per vertex * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). * + * \param renderer The rendering context. * \param texture (optional) The SDL texture to use. * \param xy Vertex positions * \param xy_stride Byte size to move from one element to the next element diff --git a/Engine/lib/sdl/include/SDL_stdinc.h b/Engine/lib/sdl/include/SDL_stdinc.h index 4554f9e71..449e6445c 100644 --- a/Engine/lib/sdl/include/SDL_stdinc.h +++ b/Engine/lib/sdl/include/SDL_stdinc.h @@ -234,6 +234,19 @@ typedef uint64_t Uint64; /* @} *//* Basic data types */ +/** + * \name Floating-point constants + */ +/* @{ */ + +#ifdef FLT_EPSILON +#define SDL_FLT_EPSILON FLT_EPSILON +#else +#define SDL_FLT_EPSILON 1.1920928955078125e-07F /* 0x0.000002p0 */ +#endif + +/* @} *//* Floating-point constants */ + /* Make sure we have macros for printing width-based integers. * should define these but this is not true all platforms. * (for example win32) */ @@ -355,9 +368,9 @@ typedef uint64_t Uint64; #endif /* SDL_DISABLE_ANALYZE_MACROS */ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) -#define SDL_COMPILE_TIME_ASSERT(name, x) _Static_assert(x, #x); +#define SDL_COMPILE_TIME_ASSERT(name, x) _Static_assert(x, #x) #elif defined(__cplusplus) && (__cplusplus >= 201103L) -#define SDL_COMPILE_TIME_ASSERT(name, x) static_assert(x, #x); +#define SDL_COMPILE_TIME_ASSERT(name, x) static_assert(x, #x) #else /* universal, but may trigger -Wunused-local-typedefs */ #define SDL_COMPILE_TIME_ASSERT(name, x) \ typedef int SDL_compile_time_assert_ ## name[(x) * 2 - 1] diff --git a/Engine/lib/sdl/include/SDL_syswm.h b/Engine/lib/sdl/include/SDL_syswm.h index f7cd670cd..45f8e7540 100644 --- a/Engine/lib/sdl/include/SDL_syswm.h +++ b/Engine/lib/sdl/include/SDL_syswm.h @@ -298,6 +298,8 @@ struct SDL_SysWMinfo struct wl_egl_window *egl_window; /**< Wayland EGL window (native window) */ struct xdg_surface *xdg_surface; /**< Wayland xdg surface (window manager handle) */ struct xdg_toplevel *xdg_toplevel; /**< Wayland xdg toplevel role */ + struct xdg_popup *xdg_popup; /**< Wayland xdg popup role */ + struct xdg_positioner *xdg_positioner; /**< Wayland xdg positioner, for popup */ } wl; #endif #if defined(SDL_VIDEO_DRIVER_MIR) /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ diff --git a/Engine/lib/sdl/include/SDL_version.h b/Engine/lib/sdl/include/SDL_version.h index a925dc432..3df4e041a 100644 --- a/Engine/lib/sdl/include/SDL_version.h +++ b/Engine/lib/sdl/include/SDL_version.h @@ -59,7 +59,7 @@ typedef struct SDL_version */ #define SDL_MAJOR_VERSION 2 #define SDL_MINOR_VERSION 0 -#define SDL_PATCHLEVEL 21 +#define SDL_PATCHLEVEL 22 /** * Macro to determine SDL version program was compiled against. diff --git a/Engine/lib/sdl/include/SDL_video.h b/Engine/lib/sdl/include/SDL_video.h index e43cb27ec..c62e0891a 100644 --- a/Engine/lib/sdl/include/SDL_video.h +++ b/Engine/lib/sdl/include/SDL_video.h @@ -1337,6 +1337,7 @@ extern DECLSPEC void SDLCALL SDL_SetWindowKeyboardGrab(SDL_Window * window, * Mouse grab confines the mouse cursor to the window. * * \param window The window for which the mouse grab mode should be set. + * \param grabbed This is SDL_TRUE to grab mouse, and SDL_FALSE to release. * * \since This function is available since SDL 2.0.16. * diff --git a/Engine/lib/sdl/include/begin_code.h b/Engine/lib/sdl/include/begin_code.h index 63f064b6f..b1b1a3a9b 100644 --- a/Engine/lib/sdl/include/begin_code.h +++ b/Engine/lib/sdl/include/begin_code.h @@ -107,7 +107,7 @@ #ifdef __BORLANDC__ #pragma nopackwarning #endif -#ifdef _M_X64 +#ifdef _WIN64 /* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */ #pragma pack(push,8) #else diff --git a/Engine/lib/sdl/src/SDL.c b/Engine/lib/sdl/src/SDL.c index dfc4572f4..68a4f5da2 100644 --- a/Engine/lib/sdl/src/SDL.c +++ b/Engine/lib/sdl/src/SDL.c @@ -316,6 +316,8 @@ SDL_InitSubSystem(Uint32 flags) #endif } + (void) flags_initialized; /* make static analysis happy, since this only gets used in error cases. */ + return (0); quit_and_error: diff --git a/Engine/lib/sdl/src/SDL_hints.c b/Engine/lib/sdl/src/SDL_hints.c index 2eea5501e..d3fc8ab46 100644 --- a/Engine/lib/sdl/src/SDL_hints.c +++ b/Engine/lib/sdl/src/SDL_hints.c @@ -178,6 +178,11 @@ SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata) return; } hint->name = SDL_strdup(name); + if (!hint->name) { + SDL_free(hint); + SDL_OutOfMemory(); + return; + } hint->value = NULL; hint->priority = SDL_HINT_DEFAULT; hint->callbacks = NULL; diff --git a/Engine/lib/sdl/src/SDL_list.c b/Engine/lib/sdl/src/SDL_list.c new file mode 100644 index 000000000..af9f8bf81 --- /dev/null +++ b/Engine/lib/sdl/src/SDL_list.c @@ -0,0 +1,93 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "./SDL_internal.h" + +#include "SDL.h" +#include "./SDL_list.h" + +/* Push */ +int +SDL_ListAdd(SDL_ListNode **head, void *ent) +{ + SDL_ListNode *node = SDL_malloc(sizeof (*node)); + + if (node == NULL) { + return SDL_OutOfMemory(); + } + + node->entry = ent; + node->next = *head; + *head = node; + return 0; +} + +/* Pop from end as a FIFO (if add with SDL_ListAdd) */ +void +SDL_ListPop(SDL_ListNode **head, void **ent) +{ + SDL_ListNode **ptr = head; + + /* Invalid or empty */ + if (head == NULL || *head == NULL) { + return; + } + + while ((*ptr)->next) { + ptr = &(*ptr)->next; + } + + if (ent) { + *ent = (*ptr)->entry; + } + + SDL_free(*ptr); + *ptr = NULL; +} + +void +SDL_ListRemove(SDL_ListNode **head, void *ent) +{ + SDL_ListNode **ptr = head; + + while (*ptr) { + if ((*ptr)->entry == ent) { + SDL_ListNode *tmp = *ptr; + *ptr = (*ptr)->next; + SDL_free(tmp); + return; + } + ptr = &(*ptr)->next; + } +} + +void +SDL_ListClear(SDL_ListNode **head) +{ + SDL_ListNode *l = *head; + *head = NULL; + while (l) { + SDL_ListNode *tmp = l; + l = l->next; + SDL_free(tmp); + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/SDL_list.h b/Engine/lib/sdl/src/SDL_list.h new file mode 100644 index 000000000..a7ead1dcd --- /dev/null +++ b/Engine/lib/sdl/src/SDL_list.h @@ -0,0 +1,39 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_list_h_ +#define SDL_list_h_ + +typedef struct SDL_ListNode +{ + void *entry; + struct SDL_ListNode *next; +} SDL_ListNode; + + +int SDL_ListAdd(SDL_ListNode **head, void *ent); +void SDL_ListPop(SDL_ListNode **head, void **ent); +void SDL_ListRemove(SDL_ListNode **head, void *ent); +void SDL_ListClear(SDL_ListNode **head); + +#endif /* SDL_list_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/audio/SDL_audio.c b/Engine/lib/sdl/src/audio/SDL_audio.c index 3a841450c..fb363f771 100644 --- a/Engine/lib/sdl/src/audio/SDL_audio.c +++ b/Engine/lib/sdl/src/audio/SDL_audio.c @@ -936,7 +936,7 @@ SDL_AudioInit(const char *driver_name) /* Select the proper audio driver */ if (driver_name == NULL) { - driver_name = SDL_getenv("SDL_AUDIODRIVER"); + driver_name = SDL_GetHint(SDL_HINT_AUDIODRIVER); } if (driver_name != NULL && *driver_name != 0) { diff --git a/Engine/lib/sdl/src/audio/SDL_audiocvt.c b/Engine/lib/sdl/src/audio/SDL_audiocvt.c index bd49ab008..539900d84 100644 --- a/Engine/lib/sdl/src/audio/SDL_audiocvt.c +++ b/Engine/lib/sdl/src/audio/SDL_audiocvt.c @@ -80,7 +80,7 @@ SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format) Just use unaligned load/stores, if the memory at runtime is aligned it'll be just as fast on modern processors */ while (i >= 4) { /* 4 * float32 */ - _mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_load_ps(src), _mm_loadu_ps(src+4)), divby2)); + _mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_loadu_ps(src), _mm_loadu_ps(src+4)), divby2)); i -= 4; src += 8; dst += 4; } diff --git a/Engine/lib/sdl/src/audio/SDL_wave.c b/Engine/lib/sdl/src/audio/SDL_wave.c index 07eb10147..e49b55068 100644 --- a/Engine/lib/sdl/src/audio/SDL_wave.c +++ b/Engine/lib/sdl/src/audio/SDL_wave.c @@ -685,7 +685,7 @@ MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) state.output.pos = 0; state.output.size = outputsize / sizeof(Sint16); - state.output.data = (Sint16 *)SDL_malloc(outputsize); + state.output.data = (Sint16 *)SDL_calloc(1, outputsize); if (state.output.data == NULL) { return SDL_OutOfMemory(); } diff --git a/Engine/lib/sdl/src/audio/emscripten/SDL_emscriptenaudio.c b/Engine/lib/sdl/src/audio/emscripten/SDL_emscriptenaudio.c index bc2a0e10d..722f5d0fa 100644 --- a/Engine/lib/sdl/src/audio/emscripten/SDL_emscriptenaudio.c +++ b/Engine/lib/sdl/src/audio/emscripten/SDL_emscriptenaudio.c @@ -32,7 +32,7 @@ static void FeedAudioDevice(_THIS, const void *buf, const int buflen) { const int framelen = (SDL_AUDIO_BITSIZE(this->spec.format) / 8) * this->spec.channels; - EM_ASM_ARGS({ + MAIN_THREAD_EM_ASM({ var SDL2 = Module['SDL2']; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { @@ -101,7 +101,7 @@ HandleCaptureProcess(_THIS) return; } - EM_ASM_ARGS({ + MAIN_THREAD_EM_ASM({ var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { @@ -147,7 +147,7 @@ HandleCaptureProcess(_THIS) static void EMSCRIPTENAUDIO_CloseDevice(_THIS) { - EM_ASM_({ + MAIN_THREAD_EM_ASM({ var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { @@ -201,7 +201,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname) /* based on parts of library_sdl.js */ /* create context */ - result = EM_ASM_INT({ + result = MAIN_THREAD_EM_ASM_INT({ if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } @@ -280,7 +280,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname) feels like it's a pretty inefficient tapdance in similar ways, to be honest. */ - EM_ASM_({ + MAIN_THREAD_EM_ASM({ var SDL2 = Module['SDL2']; var have_microphone = function(stream) { //console.log('SDL audio capture: we have a microphone! Replacing silence callback.'); @@ -323,7 +323,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname) }, this->spec.channels, this->spec.samples, HandleCaptureProcess, this); } else { /* setup a ScriptProcessorNode */ - EM_ASM_ARGS({ + MAIN_THREAD_EM_ASM({ var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { @@ -359,7 +359,7 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl) impl->ProvidesOwnCallbackThread = SDL_TRUE; /* check availability */ - available = EM_ASM_INT_V({ + available = MAIN_THREAD_EM_ASM_INT({ if (typeof(AudioContext) !== 'undefined') { return true; } else if (typeof(webkitAudioContext) !== 'undefined') { @@ -372,7 +372,7 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl) SDL_SetError("No audio context available"); } - capture_available = available && EM_ASM_INT_V({ + capture_available = available && MAIN_THREAD_EM_ASM_INT({ if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return true; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { diff --git a/Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.c b/Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.c index 524124e80..88f4a3285 100644 --- a/Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.c +++ b/Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.c @@ -37,18 +37,35 @@ #include #include +#include #define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63) #define SCE_AUDIO_MAX_VOLUME 0x8000 -/* The tag name used by VITA audio */ -#define VITAAUD_DRIVER_NAME "vita" +static int +VITAAUD_OpenCaptureDevice(_THIS) +{ + this->spec.freq = 16000; + this->spec.samples = 512; + this->spec.channels = 1; + + SDL_CalculateAudioSpec(&this->spec); + + this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE , 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO); + + if (this->hidden->port < 0) { + return SDL_SetError("Couldn't open audio in port: %x", this->hidden->port); + } + + return 0; +} static int VITAAUD_OpenDevice(_THIS, const char *devname) { int format, mixlen, i, port = SCE_AUDIO_OUT_PORT_TYPE_MAIN; int vols[2] = {SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME}; + SDL_AudioFormat test_format; this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden)); @@ -56,13 +73,20 @@ VITAAUD_OpenDevice(_THIS, const char *devname) return SDL_OutOfMemory(); } SDL_memset(this->hidden, 0, sizeof(*this->hidden)); - switch (this->spec.format & 0xff) { - case 8: - case 16: - this->spec.format = AUDIO_S16LSB; + + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { + if (test_format == AUDIO_S16LSB) { + this->spec.format = test_format; break; - default: - return SDL_SetError("Unsupported audio format"); + } + } + + if(!test_format) { + return SDL_SetError("Unsupported audio format"); + } + + if (this->iscapture) { + return VITAAUD_OpenCaptureDevice(this); } /* The sample count must be a multiple of 64. */ @@ -91,14 +115,14 @@ VITAAUD_OpenDevice(_THIS, const char *devname) port = SCE_AUDIO_OUT_PORT_TYPE_BGM; } - this->hidden->channel = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format); - if (this->hidden->channel < 0) { + this->hidden->port = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format); + if (this->hidden->port < 0) { free(this->hidden->rawbuf); this->hidden->rawbuf = NULL; - return SDL_SetError("Couldn't reserve hardware channel"); + return SDL_SetError("Couldn't open audio out port: %x", this->hidden->port); } - sceAudioOutSetVolume(this->hidden->channel, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols); + sceAudioOutSetVolume(this->hidden->port, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols); SDL_memset(this->hidden->rawbuf, 0, mixlen); for (i = 0; i < NUM_BUFFERS; i++) { @@ -113,7 +137,7 @@ static void VITAAUD_PlayDevice(_THIS) { Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer]; - sceAudioOutOutput(this->hidden->channel, mixbuf); + sceAudioOutOutput(this->hidden->port, mixbuf); this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS; } @@ -123,6 +147,7 @@ static void VITAAUD_WaitDevice(_THIS) { /* Because we block when sending audio, there's no need for this function to do anything. */ } + static Uint8 *VITAAUD_GetDeviceBuf(_THIS) { return this->hidden->mixbufs[this->hidden->next_buffer]; @@ -130,17 +155,32 @@ static Uint8 *VITAAUD_GetDeviceBuf(_THIS) static void VITAAUD_CloseDevice(_THIS) { - if (this->hidden->channel >= 0) { - sceAudioOutReleasePort(this->hidden->channel); - this->hidden->channel = -1; + if (this->hidden->port >= 0) { + if (this->iscapture) { + sceAudioInReleasePort(this->hidden->port); + } else { + sceAudioOutReleasePort(this->hidden->port); + } + this->hidden->port = -1; } - if (this->hidden->rawbuf != NULL) { + if (!this->iscapture && this->hidden->rawbuf != NULL) { free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */ this->hidden->rawbuf = NULL; } } +static int VITAAUD_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + int ret; + SDL_assert(buflen == this->spec.size); + ret = sceAudioInInput(this->hidden->port, buffer); + if (ret < 0) { + return SDL_SetError("Failed to capture from device: %x", ret); + } + return this->spec.size; +} + static void VITAAUD_ThreadInit(_THIS) { /* Increase the priority of this audio thread by 1 to put it @@ -165,12 +205,13 @@ VITAAUD_Init(SDL_AudioDriverImpl * impl) impl->CloseDevice = VITAAUD_CloseDevice; impl->ThreadInit = VITAAUD_ThreadInit; - /* VITA audio device */ - impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - /* + impl->CaptureFromDevice = VITAAUD_CaptureFromDevice; + + /* and the capabilities */ impl->HasCaptureSupport = SDL_TRUE; - impl->OnlyHasDefaultInputDevice = SDL_TRUE; - */ + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; + impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; + return SDL_TRUE; /* this audio target is available. */ } diff --git a/Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.h b/Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.h index 73870759b..a5601b28c 100644 --- a/Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.h +++ b/Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.h @@ -30,8 +30,8 @@ #define NUM_BUFFERS 2 struct SDL_PrivateAudioData { - /* The hardware output channel. */ - int channel; + /* The hardware input/output port. */ + int port; /* The raw allocated mixing buffer. */ Uint8 *rawbuf; /* Individual mixing buffers. */ diff --git a/Engine/lib/sdl/src/audio/wasapi/SDL_wasapi.c b/Engine/lib/sdl/src/audio/wasapi/SDL_wasapi.c index e7d640c12..862ed9f5e 100644 --- a/Engine/lib/sdl/src/audio/wasapi/SDL_wasapi.c +++ b/Engine/lib/sdl/src/audio/wasapi/SDL_wasapi.c @@ -558,12 +558,16 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret); } +#if 1 /* we're getting reports that WASAPI's resampler introduces distortions, so it's disabled for now. --ryan. */ + this->spec.freq = waveformat->nSamplesPerSec; /* force sampling rate so our resampler kicks in, if necessary. */ +#else /* favor WASAPI's resampler over our own */ if (this->spec.freq != waveformat->nSamplesPerSec) { streamflags |= (AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY); waveformat->nSamplesPerSec = this->spec.freq; waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8); } +#endif streamflags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK; ret = IAudioClient_Initialize(client, sharemode, streamflags, 0, 0, waveformat, NULL); diff --git a/Engine/lib/sdl/src/core/linux/SDL_fcitx.c b/Engine/lib/sdl/src/core/linux/SDL_fcitx.c index 3f0794736..bab5e88f3 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_fcitx.c +++ b/Engine/lib/sdl/src/core/linux/SDL_fcitx.c @@ -339,11 +339,11 @@ SDL_Fcitx_Reset(void) } SDL_bool -SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode) +SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state) { - Uint32 state = Fcitx_ModState(); + Uint32 mod_state = Fcitx_ModState(); Uint32 handled = SDL_FALSE; - Uint32 is_release = SDL_FALSE; + Uint32 is_release = (state == SDL_RELEASED); Uint32 event_time = 0; if (!fcitx_client.ic_path) { @@ -351,7 +351,7 @@ SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode) } if (SDL_DBus_CallMethod(FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent", - DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID, + DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mod_state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID, DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) { if (handled) { SDL_Fcitx_UpdateTextRect(NULL); diff --git a/Engine/lib/sdl/src/core/linux/SDL_fcitx.h b/Engine/lib/sdl/src/core/linux/SDL_fcitx.h index f7884ea43..c3cea523d 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_fcitx.h +++ b/Engine/lib/sdl/src/core/linux/SDL_fcitx.h @@ -31,7 +31,7 @@ extern SDL_bool SDL_Fcitx_Init(void); extern void SDL_Fcitx_Quit(void); extern void SDL_Fcitx_SetFocus(SDL_bool focused); extern void SDL_Fcitx_Reset(void); -extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode); +extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state); extern void SDL_Fcitx_UpdateTextRect(SDL_Rect *rect); extern void SDL_Fcitx_PumpEvents(void); diff --git a/Engine/lib/sdl/src/core/linux/SDL_ibus.c b/Engine/lib/sdl/src/core/linux/SDL_ibus.c index a7bafda35..60af0ba29 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_ibus.c +++ b/Engine/lib/sdl/src/core/linux/SDL_ibus.c @@ -503,15 +503,20 @@ SDL_IBus_Reset(void) } SDL_bool -SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode) +SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state) { Uint32 result = 0; SDL_DBusContext *dbus = SDL_DBus_GetContext(); - + + if (IBus_CheckConnection(dbus)) { Uint32 mods = IBus_ModState(); + Uint32 ibus_keycode = keycode - 8; + if (state == SDL_RELEASED) { + mods |= (1 << 30); // IBUS_RELEASE_MASK + } if (!SDL_DBus_CallMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent", - DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID, + DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &ibus_keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID, DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID)) { result = 0; } diff --git a/Engine/lib/sdl/src/core/linux/SDL_ibus.h b/Engine/lib/sdl/src/core/linux/SDL_ibus.h index 73a9f1b8b..71d1f2d30 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_ibus.h +++ b/Engine/lib/sdl/src/core/linux/SDL_ibus.h @@ -41,7 +41,7 @@ extern void SDL_IBus_Reset(void); /* Sends a keypress event to IBus, returns SDL_TRUE if IBus used this event to update its candidate list or change input methods. PumpEvents should be called some time after this, to recieve the TextInput / TextEditing event back. */ -extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode); +extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state); /* Update the position of IBus' candidate list. If rect is NULL then this will just reposition it relative to the focused window's new position. */ diff --git a/Engine/lib/sdl/src/core/linux/SDL_ime.c b/Engine/lib/sdl/src/core/linux/SDL_ime.c index 84c461f8b..9c0cb80f0 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_ime.c +++ b/Engine/lib/sdl/src/core/linux/SDL_ime.c @@ -27,7 +27,7 @@ typedef SDL_bool (*_SDL_IME_Init)(void); typedef void (*_SDL_IME_Quit)(void); typedef void (*_SDL_IME_SetFocus)(SDL_bool); typedef void (*_SDL_IME_Reset)(void); -typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32); +typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32, Uint8 state); typedef void (*_SDL_IME_UpdateTextRect)(SDL_Rect *); typedef void (*_SDL_IME_PumpEvents)(void); @@ -127,10 +127,10 @@ SDL_IME_Reset(void) } SDL_bool -SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode) +SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state) { if (SDL_IME_ProcessKeyEvent_Real) - return SDL_IME_ProcessKeyEvent_Real(keysym, keycode); + return SDL_IME_ProcessKeyEvent_Real(keysym, keycode, state); return SDL_FALSE; } diff --git a/Engine/lib/sdl/src/core/linux/SDL_ime.h b/Engine/lib/sdl/src/core/linux/SDL_ime.h index a28a4b430..cc5b105f0 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_ime.h +++ b/Engine/lib/sdl/src/core/linux/SDL_ime.h @@ -31,7 +31,7 @@ extern SDL_bool SDL_IME_Init(void); extern void SDL_IME_Quit(void); extern void SDL_IME_SetFocus(SDL_bool focused); extern void SDL_IME_Reset(void); -extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode); +extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state); extern void SDL_IME_UpdateTextRect(SDL_Rect *rect); extern void SDL_IME_PumpEvents(void); diff --git a/Engine/lib/sdl/src/core/windows/SDL_windows.c b/Engine/lib/sdl/src/core/windows/SDL_windows.c index fcbf8e847..50e128fcc 100644 --- a/Engine/lib/sdl/src/core/windows/SDL_windows.c +++ b/Engine/lib/sdl/src/core/windows/SDL_windows.c @@ -25,7 +25,15 @@ #include "SDL_windows.h" #include "SDL_error.h" -#include /* for CoInitialize/CoUninitialize (Win32 only) */ +#include /* for CoInitialize/CoUninitialize (Win32 only) */ +#if defined(HAVE_ROAPI_H) +#include /* For RoInitialize/RoUninitialize (Win32 only) */ +#else +typedef enum RO_INIT_TYPE { + RO_INIT_SINGLETHREADED = 0, + RO_INIT_MULTITHREADED = 1 +} RO_INIT_TYPE; +#endif #ifndef _WIN32_WINNT_VISTA #define _WIN32_WINNT_VISTA 0x0600 @@ -37,6 +45,10 @@ #define _WIN32_WINNT_WIN8 0x0602 #endif +#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32 +#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 +#endif + /* Sets an error message based on an HRESULT */ int @@ -104,51 +116,66 @@ void WIN_CoUninitialize(void) { #ifndef __WINRT__ - /* Don't uninitialize COM because of what appears to be a bug in Microsoft WGI reference counting. - * - * If you plug in a non-Xbox controller and let the application run for 30 seconds, then it crashes in CoUninitialize() - * with this stack trace: + CoUninitialize(); +#endif +} - Windows.Gaming.Input.dll!GameController::~GameController(void) Unknown - Windows.Gaming.Input.dll!GameController::`vector deleting destructor'(unsigned int) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl,1,1,0,struct Windows::Gaming::Input::IGameController,struct Windows::Gaming::Input::IGameControllerBatteryInfo,struct Microsoft::WRL::CloakedIid,class Microsoft::WRL::FtmBase>::Release(void) Unknown - Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::AggregableRuntimeClass,struct Microsoft::WRL::CloakedIid,struct Microsoft::WRL::CloakedIid,struct Microsoft::WRL::CloakedIid,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil>::Release(void) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>() Unknown - Windows.Gaming.Input.dll!`eh vector destructor iterator'(void *,unsigned int,int,void (*)(void *)) Unknown - Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection::~GameControllerCollection(void) Unknown - Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection::`vector deleting destructor'(unsigned int) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl,1,1,0,struct Windows::Foundation::Collections::IIterable,struct Windows::Foundation::Collections::IVectorView,class Microsoft::WRL::FtmBase>::Release(void) Unknown - Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase::~CustomGameControllerFactoryBase(void) Unknown - Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase::`vector deleting destructor'(unsigned int) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory >,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil,0>::Release(void) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>() Unknown - Windows.Gaming.Input.dll!NtList::~NtList(void) Unknown - Windows.Gaming.Input.dll!FactoryManager::`vector deleting destructor'(unsigned int) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics2,struct Microsoft::WRL::CloakedIid,0>::Release(void) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::Details::TerminateMap(class Microsoft::WRL::Details::ModuleBase *,unsigned short const *,bool) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::Module<1,class Microsoft::WRL::Details::DefaultModule<1> >::~Module<1,class Microsoft::WRL::Details::DefaultModule<1> >(void) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::Details::DefaultModule<1>::`vector deleting destructor'(unsigned int) Unknown - Windows.Gaming.Input.dll!`dynamic atexit destructor for 'Microsoft::WRL::Details::StaticStorage,0,int>::instance_''() Unknown - Windows.Gaming.Input.dll!__CRT_INIT@12() Unknown - Windows.Gaming.Input.dll!__DllMainCRTStartup() Unknown - ntdll.dll!_LdrxCallInitRoutine@16() Unknown - ntdll.dll!LdrpCallInitRoutine() Unknown - ntdll.dll!LdrpProcessDetachNode() Unknown - ntdll.dll!LdrpUnloadNode() Unknown - ntdll.dll!LdrpDecrementModuleLoadCountEx() Unknown - ntdll.dll!LdrUnloadDll() Unknown - KernelBase.dll!FreeLibrary() Unknown - combase.dll!FreeLibraryWithLogging(LoadOrFreeWhy why, HINSTANCE__ * hMod, const wchar_t * pswzOptionalFileName) Line 193 C++ - combase.dll!CClassCache::CDllPathEntry::CFinishObject::Finish() Line 3311 C++ - combase.dll!CClassCache::CFinishComposite::Finish() Line 3421 C++ - combase.dll!CClassCache::CleanUpDllsForProcess() Line 7009 C++ - [Inline Frame] combase.dll!CCCleanUpDllsForProcess() Line 8773 C++ - combase.dll!ProcessUninitialize() Line 2243 C++ - combase.dll!DecrementProcessInitializeCount() Line 993 C++ - combase.dll!wCoUninitialize(COleTls & Tls, int fHostThread) Line 4126 C++ - combase.dll!CoUninitialize() Line 3945 C++ - */ - /*CoUninitialize();*/ +#ifndef __WINRT__ +void * +WIN_LoadComBaseFunction(const char *name) +{ + static SDL_bool s_bLoaded; + static HMODULE s_hComBase; + + if (!s_bLoaded) { + s_hComBase = LoadLibraryEx(TEXT("combase.dll"), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + s_bLoaded = SDL_TRUE; + } + if (s_hComBase) { + return GetProcAddress(s_hComBase, name); + } else { + return NULL; + } +} +#endif + +HRESULT +WIN_RoInitialize(void) +{ +#ifdef __WINRT__ + return S_OK; +#else + typedef HRESULT (WINAPI *RoInitialize_t)(RO_INIT_TYPE initType); + RoInitialize_t RoInitializeFunc = (RoInitialize_t)WIN_LoadComBaseFunction("RoInitialize"); + if (RoInitializeFunc) { + /* RO_INIT_SINGLETHREADED is equivalent to COINIT_APARTMENTTHREADED */ + HRESULT hr = RoInitializeFunc(RO_INIT_SINGLETHREADED); + if (hr == RPC_E_CHANGED_MODE) { + hr = RoInitializeFunc(RO_INIT_MULTITHREADED); + } + + /* S_FALSE means success, but someone else already initialized. */ + /* You still need to call RoUninitialize in this case! */ + if (hr == S_FALSE) { + return S_OK; + } + + return hr; + } else { + return E_NOINTERFACE; + } +#endif +} + +void +WIN_RoUninitialize(void) +{ +#ifndef __WINRT__ + typedef void (WINAPI *RoUninitialize_t)(void); + RoUninitialize_t RoUninitializeFunc = (RoUninitialize_t)WIN_LoadComBaseFunction("RoUninitialize"); + if (RoUninitializeFunc) { + RoUninitializeFunc(); + } #endif } diff --git a/Engine/lib/sdl/src/core/windows/SDL_windows.h b/Engine/lib/sdl/src/core/windows/SDL_windows.h index 221c3bd87..917a8256f 100644 --- a/Engine/lib/sdl/src/core/windows/SDL_windows.h +++ b/Engine/lib/sdl/src/core/windows/SDL_windows.h @@ -63,10 +63,19 @@ extern int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr); /* Sets an error message based on GetLastError(). Always return -1. */ extern int WIN_SetError(const char *prefix); +#if !defined(__WINRT__) +/* Load a function from combase.dll */ +void *WIN_LoadComBaseFunction(const char *name); +#endif + /* Wrap up the oddities of CoInitialize() into a common function. */ extern HRESULT WIN_CoInitialize(void); extern void WIN_CoUninitialize(void); +/* Wrap up the oddities of RoInitialize() into a common function. */ +extern HRESULT WIN_RoInitialize(void); +extern void WIN_RoUninitialize(void); + /* Returns SDL_TRUE if we're running on Windows Vista and newer */ extern BOOL WIN_IsWindowsVistaOrGreater(void); diff --git a/Engine/lib/sdl/src/dynapi/SDL_dynapi_overrides.h b/Engine/lib/sdl/src/dynapi/SDL_dynapi_overrides.h index 299dde303..526513ad5 100644 --- a/Engine/lib/sdl/src/dynapi/SDL_dynapi_overrides.h +++ b/Engine/lib/sdl/src/dynapi/SDL_dynapi_overrides.h @@ -864,3 +864,4 @@ #define SDL_UnionFRect SDL_UnionFRect_REAL #define SDL_EncloseFPoints SDL_EncloseFPoints_REAL #define SDL_IntersectFRectAndLine SDL_IntersectFRectAndLine_REAL +#define SDL_RenderGetWindow SDL_RenderGetWindow_REAL diff --git a/Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h b/Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h index 2c0d5b03e..22bf870d9 100644 --- a/Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h +++ b/Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h @@ -935,3 +935,4 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_IntersectFRect,(const SDL_FRect *a, const SDL_FRect SDL_DYNAPI_PROC(void,SDL_UnionFRect,(const SDL_FRect *a, const SDL_FRect *b, SDL_FRect *c),(a,b,c),) SDL_DYNAPI_PROC(SDL_bool,SDL_EncloseFPoints,(const SDL_FPoint *a, int b, const SDL_FRect *c, SDL_FRect *d),(a,b,c,d),return) SDL_DYNAPI_PROC(SDL_bool,SDL_IntersectFRectAndLine,(const SDL_FRect *a, float *b, float *c, float *d, float *e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(SDL_Window*,SDL_RenderGetWindow,(SDL_Renderer *a),(a),return) diff --git a/Engine/lib/sdl/src/events/SDL_keyboard.c b/Engine/lib/sdl/src/events/SDL_keyboard.c index cd150fab6..14e79ca49 100644 --- a/Engine/lib/sdl/src/events/SDL_keyboard.c +++ b/Engine/lib/sdl/src/events/SDL_keyboard.c @@ -638,6 +638,7 @@ SDL_SetKeyboardFocus(SDL_Window * window) /* old window must lose an existing mouse capture. */ if (keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE) { SDL_CaptureMouse(SDL_FALSE); /* drop the capture. */ + SDL_UpdateMouseCapture(SDL_TRUE); SDL_assert(!(keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE)); } diff --git a/Engine/lib/sdl/src/events/SDL_mouse.c b/Engine/lib/sdl/src/events/SDL_mouse.c index 2e88ee714..254182cc5 100644 --- a/Engine/lib/sdl/src/events/SDL_mouse.c +++ b/Engine/lib/sdl/src/events/SDL_mouse.c @@ -109,6 +109,28 @@ SDL_TouchMouseEventsChanged(void *userdata, const char *name, const char *oldVal mouse->touch_mouse_events = SDL_GetStringBoolean(hint, SDL_TRUE); } +#if defined(__vita__) +static void SDLCALL +SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_Mouse *mouse = (SDL_Mouse *)userdata; + if (hint) { + switch(*hint) { + default: + case '0': + mouse->vita_touch_mouse_device = 0; + break; + case '1': + mouse->vita_touch_mouse_device = 1; + break; + case '2': + mouse->vita_touch_mouse_device = 2; + break; + } + } +} +#endif + static void SDLCALL SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { @@ -134,12 +156,8 @@ SDL_MouseAutoCaptureChanged(void *userdata, const char *name, const char *oldVal SDL_bool auto_capture = SDL_GetStringBoolean(hint, SDL_TRUE); if (auto_capture != mouse->auto_capture) { - /* Turn off mouse capture if it's currently active because of button presses */ - if (!auto_capture && SDL_GetMouseState(NULL, NULL) != 0) { - SDL_CaptureMouse(SDL_FALSE); - } - mouse->auto_capture = auto_capture; + SDL_UpdateMouseCapture(SDL_FALSE); } } @@ -166,6 +184,11 @@ SDL_MouseInit(void) SDL_AddHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS, SDL_TouchMouseEventsChanged, mouse); +#if defined(__vita__) + SDL_AddHintCallback(SDL_HINT_VITA_TOUCH_MOUSE_DEVICE, + SDL_VitaTouchMouseDeviceChanged, mouse); +#endif + SDL_AddHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS, SDL_MouseTouchEventsChanged, mouse); @@ -384,12 +407,9 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ /* Ignore relative motion when first positioning the mouse */ if (!mouse->has_position) { - xrel = 0; - yrel = 0; mouse->x = x; mouse->y = y; mouse->has_position = SDL_TRUE; - return 0; } else if (!xrel && !yrel) { /* Drop events that don't change state */ #ifdef DEBUG_MOUSE SDL_Log("Mouse event didn't change state - dropped!\n"); @@ -540,7 +560,6 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state Uint32 type; Uint32 buttonstate; SDL_MouseInputSource *source; - SDL_bool had_buttons_pressed = (SDL_GetMouseState(NULL, NULL) ? SDL_TRUE : SDL_FALSE); source = GetMouseInputSource(mouse, mouseID); if (!source) { @@ -643,10 +662,7 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state /* Automatically capture the mouse while buttons are pressed */ if (mouse->auto_capture) { - SDL_bool has_buttons_pressed = (SDL_GetMouseState(NULL, NULL) ? SDL_TRUE : SDL_FALSE); - if (has_buttons_pressed != had_buttons_pressed) { - SDL_CaptureMouse(has_buttons_pressed); - } + SDL_UpdateMouseCapture(SDL_FALSE); } return posted; @@ -743,6 +759,7 @@ SDL_MouseQuit(void) if (mouse->CaptureMouse) { SDL_CaptureMouse(SDL_FALSE); + SDL_UpdateMouseCapture(SDL_TRUE); } SDL_SetRelativeMouseMode(SDL_FALSE); SDL_ShowCursor(1); @@ -947,6 +964,8 @@ SDL_SetRelativeMouseMode(SDL_bool enabled) if (!enabled) { SDL_WarpMouseInWindow(focusWindow, mouse->x, mouse->y); } + + SDL_UpdateMouseCapture(SDL_FALSE); } if (!enabled) { @@ -968,39 +987,59 @@ SDL_GetRelativeMouseMode() return mouse->relative_mode; } +int +SDL_UpdateMouseCapture(SDL_bool force_release) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Window *capture_window = NULL; + + if (!mouse->CaptureMouse) { + return 0; + } + + if (!force_release) { + if (mouse->capture_desired || (mouse->auto_capture && SDL_GetMouseState(NULL, NULL) != 0)) { + if (!mouse->relative_mode) { + capture_window = SDL_GetKeyboardFocus(); + } + } + } + + if (capture_window != mouse->capture_window) { + if (mouse->capture_window) { + mouse->CaptureMouse(NULL); + mouse->capture_window->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + mouse->capture_window = NULL; + } + + if (capture_window) { + if (mouse->CaptureMouse(capture_window) < 0) { + /* CaptureMouse() will have set an error */ + return -1; + } + capture_window->flags |= SDL_WINDOW_MOUSE_CAPTURE; + } + + mouse->capture_window = capture_window; + } + return 0; +} + int SDL_CaptureMouse(SDL_bool enabled) { SDL_Mouse *mouse = SDL_GetMouse(); - SDL_Window *focusWindow; - SDL_bool isCaptured; if (!mouse->CaptureMouse) { return SDL_Unsupported(); } - focusWindow = SDL_GetKeyboardFocus(); - - isCaptured = focusWindow && (focusWindow->flags & SDL_WINDOW_MOUSE_CAPTURE); - if (isCaptured == enabled) { - return 0; /* already done! */ + if (enabled && SDL_GetKeyboardFocus() == NULL) { + return SDL_SetError("No window has focus"); } + mouse->capture_desired = enabled; - if (enabled) { - if (!focusWindow) { - return SDL_SetError("No window has focus"); - } else if (mouse->CaptureMouse(focusWindow) == -1) { - return -1; /* CaptureMouse() should call SetError */ - } - focusWindow->flags |= SDL_WINDOW_MOUSE_CAPTURE; - } else { - if (mouse->CaptureMouse(NULL) == -1) { - return -1; /* CaptureMouse() should call SetError */ - } - focusWindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; - } - - return 0; + return SDL_UpdateMouseCapture(SDL_FALSE); } SDL_Cursor * diff --git a/Engine/lib/sdl/src/events/SDL_mouse_c.h b/Engine/lib/sdl/src/events/SDL_mouse_c.h index 7b020447a..f06934b6f 100644 --- a/Engine/lib/sdl/src/events/SDL_mouse_c.h +++ b/Engine/lib/sdl/src/events/SDL_mouse_c.h @@ -100,7 +100,12 @@ typedef struct SDL_bool touch_mouse_events; SDL_bool mouse_touch_events; SDL_bool was_touch_mouse_events; /* Was a touch-mouse event pending? */ +#if defined(__vita__) + Uint8 vita_touch_mouse_device; +#endif SDL_bool auto_capture; + SDL_bool capture_desired; + SDL_Window *capture_window; /* Data for input source state */ int num_sources; @@ -132,6 +137,9 @@ extern void SDL_SetDefaultCursor(SDL_Cursor * cursor); /* Set the mouse focus window */ extern void SDL_SetMouseFocus(SDL_Window * window); +/* Update the mouse capture window */ +extern int SDL_UpdateMouseCapture(SDL_bool force_release); + /* Send a mouse motion event */ extern int SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y); diff --git a/Engine/lib/sdl/src/events/SDL_touch.c b/Engine/lib/sdl/src/events/SDL_touch.c index c3534f00e..ebf26e091 100644 --- a/Engine/lib/sdl/src/events/SDL_touch.c +++ b/Engine/lib/sdl/src/events/SDL_touch.c @@ -265,8 +265,13 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, #if SYNTHESIZE_TOUCH_TO_MOUSE /* SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events */ + /* SDL_HINT_VITA_TOUCH_MOUSE_DEVICE: controlling which touchpad should generate synthetic mouse events, PSVita-only */ { +#if defined(__vita__) + if (mouse->touch_mouse_events && ((mouse->vita_touch_mouse_device == id) || (mouse->vita_touch_mouse_device == 2)) ) { +#else if (mouse->touch_mouse_events) { +#endif /* FIXME: maybe we should only restrict to a few SDL_TouchDeviceType */ if (id != SDL_MOUSE_TOUCHID) { if (window) { diff --git a/Engine/lib/sdl/src/filesystem/windows/SDL_sysfilesystem.c b/Engine/lib/sdl/src/filesystem/windows/SDL_sysfilesystem.c index d50fb511b..b57546c67 100644 --- a/Engine/lib/sdl/src/filesystem/windows/SDL_sysfilesystem.c +++ b/Engine/lib/sdl/src/filesystem/windows/SDL_sysfilesystem.c @@ -35,39 +35,23 @@ char * SDL_GetBasePath(void) { - typedef DWORD (WINAPI *GetModuleFileNameExW_t)(HANDLE, HMODULE, LPWSTR, DWORD); - GetModuleFileNameExW_t pGetModuleFileNameExW; DWORD buflen = 128; WCHAR *path = NULL; - HANDLE psapi = LoadLibrary(TEXT("psapi.dll")); char *retval = NULL; DWORD len = 0; int i; - if (!psapi) { - WIN_SetError("Couldn't load psapi.dll"); - return NULL; - } - - pGetModuleFileNameExW = (GetModuleFileNameExW_t)GetProcAddress(psapi, "GetModuleFileNameExW"); - if (!pGetModuleFileNameExW) { - WIN_SetError("Couldn't find GetModuleFileNameExW"); - FreeLibrary(psapi); - return NULL; - } - while (SDL_TRUE) { void *ptr = SDL_realloc(path, buflen * sizeof (WCHAR)); if (!ptr) { SDL_free(path); - FreeLibrary(psapi); SDL_OutOfMemory(); return NULL; } path = (WCHAR *) ptr; - len = pGetModuleFileNameExW(GetCurrentProcess(), NULL, path, buflen); + len = GetModuleFileNameW(NULL, path, buflen); /* if it truncated, then len >= buflen - 1 */ /* if there was enough room (or failure), len < buflen - 1 */ if (len < buflen - 1) { @@ -78,8 +62,6 @@ SDL_GetBasePath(void) buflen *= 2; } - FreeLibrary(psapi); - if (len == 0) { SDL_free(path); WIN_SetError("Couldn't locate our .exe"); diff --git a/Engine/lib/sdl/src/hidapi/SDL_hidapi.c b/Engine/lib/sdl/src/hidapi/SDL_hidapi.c index aacff63bf..369b616f5 100644 --- a/Engine/lib/sdl/src/hidapi/SDL_hidapi.c +++ b/Engine/lib/sdl/src/hidapi/SDL_hidapi.c @@ -951,6 +951,7 @@ DeleteHIDDeviceWrapper(SDL_hid_device *device) } #if !SDL_HIDAPI_DISABLED +#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC) #define COPY_IF_EXISTS(var) \ if (pSrc->var != NULL) { \ @@ -987,6 +988,7 @@ CopyHIDDeviceInfo(struct SDL_hid_device_info *pSrc, struct SDL_hid_device_info * #undef COPY_IF_EXISTS #undef WCOPY_IF_EXISTS +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */ #endif /* !SDL_HIDAPI_DISABLED */ static int SDL_hidapi_refcount = 0; @@ -1185,9 +1187,9 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned #ifdef SDL_LIBUSB_DYNAMIC if (libusb_ctx.libhandle) { usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id); - #ifdef DEBUG_HIDAPI +#ifdef DEBUG_HIDAPI SDL_Log("libusb devices found:"); - #endif +#endif for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) { new_dev = (struct SDL_hid_device_info*) SDL_malloc(sizeof(struct SDL_hid_device_info)); if (!new_dev) { @@ -1197,11 +1199,11 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned return NULL; } CopyHIDDeviceInfo(usb_dev, new_dev); - #ifdef DEBUG_HIDAPI +#ifdef DEBUG_HIDAPI SDL_Log(" - %ls %ls 0x%.4hx 0x%.4hx", usb_dev->manufacturer_string, usb_dev->product_string, usb_dev->vendor_id, usb_dev->product_id); - #endif +#endif if (last != NULL) { last->next = new_dev; diff --git a/Engine/lib/sdl/src/hidapi/libusb/hid.c b/Engine/lib/sdl/src/hidapi/libusb/hid.c index c54746e4d..9cb597fa8 100644 --- a/Engine/lib/sdl/src/hidapi/libusb/hid.c +++ b/Engine/lib/sdl/src/hidapi/libusb/hid.c @@ -1497,6 +1497,7 @@ void HID_API_EXPORT hid_close(hid_device *dev) /* Clean up the Transfer objects allocated in read_thread(). */ free(dev->transfer->buffer); + dev->transfer->buffer = NULL; libusb_free_transfer(dev->transfer); /* release the interface */ diff --git a/Engine/lib/sdl/src/hidapi/mac/hid.c b/Engine/lib/sdl/src/hidapi/mac/hid.c index a9a85b1f7..ec7ffaf16 100644 --- a/Engine/lib/sdl/src/hidapi/mac/hid.c +++ b/Engine/lib/sdl/src/hidapi/mac/hid.c @@ -572,8 +572,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, if ((vendor_id == 0x0 && product_id == 0x0) || (vendor_id == dev_vid && product_id == dev_pid)) { struct hid_device_info *tmp; - size_t len; - + /* VID/PID match. Create the record. */ tmp = (struct hid_device_info *)calloc(1, sizeof(struct hid_device_info)); if (cur_dev) { @@ -590,7 +589,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, /* Fill out the record */ cur_dev->next = NULL; - len = make_path(dev, cbuf, sizeof(cbuf)); + make_path(dev, cbuf, sizeof(cbuf)); cur_dev->path = strdup(cbuf); /* Serial Number */ @@ -817,10 +816,9 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) CFSetGetValues(device_set, (const void **) device_array); for (i = 0; i < num_devices; i++) { char cbuf[BUF_LEN]; - size_t len; IOHIDDeviceRef os_dev = device_array[i]; - len = make_path(os_dev, cbuf, sizeof(cbuf)); + make_path(os_dev, cbuf, sizeof(cbuf)); if (!strcmp(cbuf, path)) { // Matched Paths. Open this Device. IOReturn ret = IOHIDDeviceOpen(os_dev, kIOHIDOptionsTypeNone); @@ -833,6 +831,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) /* Create the buffers for receiving data */ dev->max_input_report_len = (CFIndex) get_max_report_length(os_dev); + SDL_assert(dev->max_input_report_len > 0); dev->input_report_buf = (uint8_t *)calloc(dev->max_input_report_len, sizeof(uint8_t)); /* Create the Run Loop Mode for this device. @@ -936,11 +935,14 @@ static int return_data(hid_device *dev, unsigned char *data, size_t length) /* Copy the data out of the linked list item (rpt) into the return buffer (data), and delete the liked list item. */ struct input_report *rpt = dev->input_reports; - size_t len = (length < rpt->len)? length: rpt->len; - memcpy(data, rpt->data, len); - dev->input_reports = rpt->next; - free(rpt->data); - free(rpt); + size_t len = 0; + if (rpt != NULL) { + len = (length < rpt->len)? length: rpt->len; + memcpy(data, rpt->data, len); + dev->input_reports = rpt->next; + free(rpt->data); + free(rpt); + } return (int)len; } diff --git a/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h b/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h index 2aa9ca6e8..9dab7cbba 100644 --- a/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h +++ b/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h @@ -501,7 +501,7 @@ static const char *s_ControllerMappings [] = "03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,", #endif -#if defined(__LINUX__) +#ifdef SDL_JOYSTICK_LINUX "xinput,*,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", @@ -762,6 +762,7 @@ static const char *s_ControllerMappings [] = "0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,", "030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,", + "030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,", "030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,", "030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,", diff --git a/Engine/lib/sdl/src/joystick/SDL_joystick.c b/Engine/lib/sdl/src/joystick/SDL_joystick.c index 3f3482b7d..ae4591223 100644 --- a/Engine/lib/sdl/src/joystick/SDL_joystick.c +++ b/Engine/lib/sdl/src/joystick/SDL_joystick.c @@ -1590,11 +1590,13 @@ SDL_JoystickUpdate(void) for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { if (joystick->attached) { - /* This should always be true, but seeing a crash in the wild...? */ - if (joystick->driver) { - joystick->driver->Update(joystick); + /* This driver should always be != NULL, but seeing a crash in the wild...? */ + if (!joystick->driver) { + continue; /* nothing we can do, and other things use joystick->driver below here. */ } + joystick->driver->Update(joystick); + if (joystick->delayed_guide_button) { SDL_GameControllerHandleDelayedGuideButton(joystick); } @@ -2158,7 +2160,10 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid) MAKE_VIDPID(0x044f, 0xb65d), /* Thrustmaster Wheel FFB */ MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster Wheel FFB */ MAKE_VIDPID(0x044f, 0xb677), /* Thrustmaster T150 */ - MAKE_VIDPID(0x044f, 0xb66e), /* Thrustmaster T300RS */ + MAKE_VIDPID(0x044f, 0xb696), /* Thrustmaster T248 */ + MAKE_VIDPID(0x044f, 0xb66e), /* Thrustmaster T300RS (normal mode) */ + MAKE_VIDPID(0x044f, 0xb66f), /* Thrustmaster T300RS (advanced mode) */ + MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster T300RS (PS4 mode) */ MAKE_VIDPID(0x044f, 0xb65e), /* Thrustmaster T500RS */ MAKE_VIDPID(0x044f, 0xb664), /* Thrustmaster TX (initial mode) */ MAKE_VIDPID(0x044f, 0xb669), /* Thrustmaster TX (active mode) */ diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps5.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps5.c index 6d7f87d59..2549c2afd 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps5.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps5.c @@ -747,7 +747,11 @@ HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joy } } - return SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size); + if (SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size) != report_size) { + return -1; + } + + return 0; } static int @@ -957,7 +961,10 @@ HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, axis = ((int)packet->ucRightJoystickY * 257) - 32768; SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); - if (packet->ucBatteryLevel & 0x10) { + /* A check of packet->ucBatteryLevel & 0x10 should work as a check for BT vs USB but doesn't + * seem to always work. Possibly related to being 100% charged? + */ + if (!ctx->is_bluetooth) { /* 0x20 set means fully charged */ SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED); } else { diff --git a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick.c b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick.c index 55d9a1353..f54b3c3f2 100644 --- a/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick.c @@ -227,7 +227,7 @@ HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device) } /* Disconnect any joysticks */ - while (device->num_joysticks) { + while (device->num_joysticks && device->joysticks) { HIDAPI_JoystickDisconnected(device, device->joysticks[0]); } diff --git a/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick.m b/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick.m index c75fbbae2..38ab3fe60 100644 --- a/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick.m +++ b/Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick.m @@ -330,6 +330,19 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle subtype = 1; } + if (SDL_strcmp(name, "Backbone One") == 0) { + /* The Backbone app uses the guide and share buttons */ + if ((device->button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE)) != 0) { + device->button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_GUIDE); + --nbuttons; + } + if ((device->button_mask & (1 << SDL_CONTROLLER_BUTTON_MISC1)) != 0) { + device->button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_MISC1); + --nbuttons; + device->has_xbox_share_button = SDL_FALSE; + } + } + device->naxes = 6; /* 2 thumbsticks and 2 triggers */ device->nhats = 1; /* d-pad */ device->nbuttons = nbuttons; diff --git a/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c index 851448acd..a268c0d9b 100644 --- a/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c @@ -109,6 +109,7 @@ typedef struct SDL_joylist_item /* Steam Controller support */ SDL_bool m_bSteamController; + SDL_bool checked_mapping; SDL_GamepadMapping *mapping; } SDL_joylist_item; @@ -605,6 +606,26 @@ LINUX_InotifyJoystickDetect(void) } #endif /* HAVE_INOTIFY */ +static int get_event_joystick_index(int event) +{ + int joystick_index = -1; + int i, count; + struct dirent **entries = NULL; + char path[PATH_MAX]; + + SDL_snprintf(path, SDL_arraysize(path), "/sys/class/input/event%d/device", event); + count = scandir(path, &entries, NULL, alphasort); + for (i = 0; i < count; ++i) { + if (SDL_strncmp(entries[i]->d_name, "js", 2) == 0) { + joystick_index = SDL_atoi(entries[i]->d_name+2); + } + free(entries[i]); /* This should NOT be SDL_free() */ + } + free(entries); /* This should NOT be SDL_free() */ + + return joystick_index; +} + /* Detect devices by reading /dev/input. In the inotify code path we * have to do this the first time, to detect devices that already existed * before we started; in the non-inotify code path we do this repeatedly @@ -615,12 +636,39 @@ filter_entries(const struct dirent *entry) return IsJoystickDeviceNode(entry->d_name); } static int -sort_entries(const struct dirent **a, const struct dirent **b) +sort_entries(const void *_a, const void *_b) { - int numA = SDL_atoi((*a)->d_name+5); - int numB = SDL_atoi((*b)->d_name+5); + const struct dirent **a = (const struct dirent **)_a; + const struct dirent **b = (const struct dirent **)_b; + int numA, numB; + int offset; + + if (SDL_classic_joysticks) { + offset = 2; /* strlen("js") */ + numA = SDL_atoi((*a)->d_name+offset); + numB = SDL_atoi((*b)->d_name+offset); + } else { + offset = 5; /* strlen("event") */ + numA = SDL_atoi((*a)->d_name+offset); + numB = SDL_atoi((*b)->d_name+offset); + + /* See if we can get the joystick ordering */ + { + int jsA = get_event_joystick_index(numA); + int jsB = get_event_joystick_index(numB); + if (jsA >= 0 && jsB >= 0) { + numA = jsA; + numB = jsB; + } else if (jsA >= 0) { + return -1; + } else if (jsB >= 0) { + return 1; + } + } + } return (numA - numB); } + static void LINUX_FallbackJoystickDetect(void) { @@ -633,10 +681,13 @@ LINUX_FallbackJoystickDetect(void) /* Opening input devices can generate synchronous device I/O, so avoid it if we can */ if (stat("/dev/input", &sb) == 0 && sb.st_mtime != last_input_dir_mtime) { int i, count; - struct dirent **entries; + struct dirent **entries = NULL; char path[PATH_MAX]; - count = scandir("/dev/input", &entries, filter_entries, sort_entries); + count = scandir("/dev/input", &entries, filter_entries, NULL); + if (count > 1) { + qsort(entries, count, sizeof(*entries), sort_entries); + } for (i = 0; i < count; ++i) { SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name); MaybeAddDevice(path); @@ -683,29 +734,7 @@ LINUX_JoystickInit(void) SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE); -#if SDL_USE_LIBUDEV - if (enumeration_method == ENUMERATION_UNSET) { - if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) { - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, - "udev disabled by SDL_JOYSTICK_DISABLE_UDEV"); - enumeration_method = ENUMERATION_FALLBACK; - - } else if (access("/.flatpak-info", F_OK) == 0 - || access("/run/host/container-manager", F_OK) == 0) { - /* Explicitly check `/.flatpak-info` because, for old versions of - * Flatpak, this was the only available way to tell if we were in - * a Flatpak container. */ - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, - "Container detected, disabling udev integration"); - enumeration_method = ENUMERATION_FALLBACK; - - } else { - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, - "Using udev for joystick device discovery"); - enumeration_method = ENUMERATION_LIBUDEV; - } - } -#endif + enumeration_method = ENUMERATION_UNSET; /* First see if the user specified one or more joysticks to use */ if (devices != NULL) { @@ -734,6 +763,28 @@ LINUX_JoystickInit(void) LINUX_JoystickDetect(); #if SDL_USE_LIBUDEV + if (enumeration_method == ENUMERATION_UNSET) { + if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "udev disabled by SDL_JOYSTICK_DISABLE_UDEV"); + enumeration_method = ENUMERATION_FALLBACK; + + } else if (access("/.flatpak-info", F_OK) == 0 + || access("/run/host/container-manager", F_OK) == 0) { + /* Explicitly check `/.flatpak-info` because, for old versions of + * Flatpak, this was the only available way to tell if we were in + * a Flatpak container. */ + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Container detected, disabling udev integration"); + enumeration_method = ENUMERATION_FALLBACK; + + } else { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Using udev for joystick device discovery"); + enumeration_method = ENUMERATION_LIBUDEV; + } + } + if (enumeration_method == ENUMERATION_LIBUDEV) { if (SDL_UDEV_Init() < 0) { return SDL_SetError("Could not initialize UDEV"); @@ -1573,9 +1624,13 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) SDL_Joystick *joystick; SDL_joylist_item *item = JoystickByDevIndex(device_index); - if (item->mapping) { - SDL_memcpy(out, item->mapping, sizeof(*out)); - return SDL_TRUE; + if (item->checked_mapping) { + if (item->mapping) { + SDL_memcpy(out, item->mapping, sizeof(*out)); + return SDL_TRUE; + } else { + return SDL_FALSE; + } } /* We temporarily open the device to check how it's configured. Make @@ -1595,6 +1650,8 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) return SDL_FALSE; } + item->checked_mapping = SDL_TRUE; + if (PrepareJoystickHwdata(joystick, item) == -1) { SDL_free(joystick->hwdata); SDL_free(joystick); diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick.c b/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick.c index 32b637827..df40232df 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick.c +++ b/Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick.c @@ -62,6 +62,7 @@ typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState; #define GamepadButtons_GUIDE 0x40000000 #define COBJMACROS #include "windows.gaming.input.h" +#include #endif #if defined(SDL_JOYSTICK_RAWINPUT_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT_WGI) @@ -565,22 +566,24 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) if (!wgi_state.initialized) { static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } }; HRESULT hr; - HMODULE hModule; - /* I think this takes care of RoInitialize() in a way that is compatible with the rest of SDL */ - if (FAILED(WIN_CoInitialize())) { + if (FAILED(WIN_RoInitialize())) { return; } wgi_state.initialized = SDL_TRUE; wgi_state.dirty = SDL_TRUE; - hModule = LoadLibraryA("combase.dll"); - if (hModule != NULL) { + { typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string); typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory); - WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference"); - RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory"); +#ifdef __WINRT__ + WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = WindowsCreateStringReference; + RoGetActivationFactory_t RoGetActivationFactoryFunc = RoGetActivationFactory; +#else + WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference"); + RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory"); +#endif if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) { PCWSTR pNamespace = L"Windows.Gaming.Input.Gamepad"; HSTRING_HEADER hNamespaceStringHeader; @@ -591,7 +594,6 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, (void **)&wgi_state.gamepad_statics); } } - FreeLibrary(hModule); } } } @@ -657,7 +659,7 @@ RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics); wgi_state.gamepad_statics = NULL; } - WIN_CoUninitialize(); + WIN_RoUninitialize(); wgi_state.initialized = SDL_FALSE; } } @@ -1320,8 +1322,10 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint if (!SUCCEEDED(hr)) { return SDL_SetError("Setting vibration failed: 0x%lx\n", hr); } + return 0; + } else { + return SDL_SetError("Controller isn't correlated yet, try hitting a button first"); } - return 0; #else return SDL_Unsupported(); #endif diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_windows_gaming_input.c b/Engine/lib/sdl/src/joystick/windows/SDL_windows_gaming_input.c index a731dad63..6c5ec5528 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_windows_gaming_input.c +++ b/Engine/lib/sdl/src/joystick/windows/SDL_windows_gaming_input.c @@ -68,6 +68,7 @@ static struct { EventRegistrationToken controller_added_token; EventRegistrationToken controller_removed_token; int controller_count; + SDL_bool ro_initialized; WindowsGamingInputControllerState *controllers; } wgi; @@ -260,10 +261,9 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde WindowsGetStringRawBufferFunc = WindowsGetStringRawBuffer; WindowsDeleteStringFunc = WindowsDeleteString; #else - HMODULE hModule = LoadLibraryA("combase.dll"); - if (hModule != NULL) { - WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer"); - WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString"); + { + WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)WIN_LoadComBaseFunction("WindowsGetStringRawBuffer"); + WindowsDeleteStringFunc = (WindowsDeleteString_t)WIN_LoadComBaseFunction("WindowsDeleteString"); } #endif /* __WINRT__ */ if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) { @@ -277,11 +277,6 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde WindowsDeleteStringFunc(hString); } } -#ifndef __WINRT__ - if (hModule != NULL) { - FreeLibrary(hModule); - } -#endif __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2); } if (!name) { @@ -444,23 +439,43 @@ WGI_JoystickInit(void) WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL; RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL; -#ifndef __WINRT__ - HMODULE hModule; -#endif HRESULT hr; - if (FAILED(WIN_CoInitialize())) { - return SDL_SetError("CoInitialize() failed"); + if (FAILED(WIN_RoInitialize())) { + return SDL_SetError("RoInitialize() failed"); } + wgi.ro_initialized = SDL_TRUE; + +#ifndef __WINRT__ + { + /* There seems to be a bug in Windows where a dependency of WGI can be unloaded from memory prior to WGI itself. + * This results in Windows_Gaming_Input!GameController::~GameController() invoking an unloaded DLL and crashing. + * As a workaround, we will keep a reference to the MTA to prevent COM from unloading DLLs later. + * See https://github.com/libsdl-org/SDL/issues/5552 for more details. + */ + static PVOID cookie = NULL; + if (!cookie) { + typedef HRESULT (WINAPI *CoIncrementMTAUsage_t)(PVOID* pCookie); + CoIncrementMTAUsage_t CoIncrementMTAUsageFunc = (CoIncrementMTAUsage_t)WIN_LoadComBaseFunction("CoIncrementMTAUsage"); + if (CoIncrementMTAUsageFunc) { + if (FAILED(CoIncrementMTAUsageFunc(&cookie))) { + return SDL_SetError("CoIncrementMTAUsage() failed"); + } + } else { + /* CoIncrementMTAUsage() is present since Win8, so we should never make it here. */ + return SDL_SetError("CoIncrementMTAUsage() not found"); + } + } + } +#endif #ifdef __WINRT__ WindowsCreateStringReferenceFunc = WindowsCreateStringReference; RoGetActivationFactoryFunc = RoGetActivationFactory; #else - hModule = LoadLibraryA("combase.dll"); - if (hModule != NULL) { - WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference"); - RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory"); + { + WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference"); + RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory"); } #endif /* __WINRT__ */ if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) { @@ -519,11 +534,6 @@ WGI_JoystickInit(void) } } } -#ifndef __WINRT__ - if (hModule != NULL) { - FreeLibrary(hModule); - } -#endif if (wgi.statics) { __FIVectorView_1_Windows__CGaming__CInput__CRawGameController *controllers; @@ -863,9 +873,12 @@ WGI_JoystickQuit(void) __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_remove_RawGameControllerRemoved(wgi.statics, wgi.controller_removed_token); __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_Release(wgi.statics); } - SDL_zero(wgi); - WIN_CoUninitialize(); + if (wgi.ro_initialized) { + WIN_RoUninitialize(); + } + + SDL_zero(wgi); } static SDL_bool diff --git a/Engine/lib/sdl/src/locale/vita/SDL_syslocale.c b/Engine/lib/sdl/src/locale/vita/SDL_syslocale.c new file mode 100644 index 000000000..0a057cbfa --- /dev/null +++ b/Engine/lib/sdl/src/locale/vita/SDL_syslocale.c @@ -0,0 +1,71 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" +#include "../SDL_syslocale.h" + +#include +#include + +void +SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + const char *vita_locales[] = { + "ja_JP", + "en_US", + "fr_FR", + "es_ES", + "de_DE", + "it_IT", + "nl_NL", + "pt_PT", + "ru_RU", + "ko_KR", + "zh_TW", + "zh_CN", + "fi_FI", + "sv_SE", + "da_DK", + "no_NO", + "pl_PL", + "pt_BR", + "en_GB", + "tr_TR", + }; + + Sint32 language = SCE_SYSTEM_PARAM_LANG_ENGLISH_US; + SceAppUtilInitParam initParam; + SceAppUtilBootParam bootParam; + SDL_zero(initParam); + SDL_zero(bootParam); + sceAppUtilInit(&initParam, &bootParam); + sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_LANG, &language); + + if (language < 0 || language > SCE_SYSTEM_PARAM_LANG_TURKISH) + language = SCE_SYSTEM_PARAM_LANG_ENGLISH_US; // default to english + + SDL_strlcpy(buf, vita_locales[language], buflen); + + sceAppUtilShutdown(); +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/Engine/lib/sdl/src/main/windows/version.rc b/Engine/lib/sdl/src/main/windows/version.rc index 36ff39f12..11e1394f8 100644 --- a/Engine/lib/sdl/src/main/windows/version.rc +++ b/Engine/lib/sdl/src/main/windows/version.rc @@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,21,0 - PRODUCTVERSION 2,0,21,0 + FILEVERSION 2,0,22,0 + PRODUCTVERSION 2,0,22,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -23,12 +23,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "2, 0, 21, 0\0" + VALUE "FileVersion", "2, 0, 22, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL2.dll\0" VALUE "ProductName", "Simple DirectMedia Layer\0" - VALUE "ProductVersion", "2, 0, 21, 0\0" + VALUE "ProductVersion", "2, 0, 22, 0\0" END END BLOCK "VarFileInfo" diff --git a/Engine/lib/sdl/src/render/SDL_render.c b/Engine/lib/sdl/src/render/SDL_render.c index 441badbc6..58cda3d60 100644 --- a/Engine/lib/sdl/src/render/SDL_render.c +++ b/Engine/lib/sdl/src/render/SDL_render.c @@ -356,7 +356,7 @@ QueueCmdSetViewport(SDL_Renderer *renderer) if (cmd != NULL) { cmd->command = SDL_RENDERCMD_SETVIEWPORT; cmd->data.viewport.first = 0; /* render backend will fill this in. */ - /* Convert SDL_FRect to SDL_Rect */ + /* Convert SDL_DRect to SDL_Rect */ cmd->data.viewport.rect.x = (int)SDL_floor(renderer->viewport.x); cmd->data.viewport.rect.y = (int)SDL_floor(renderer->viewport.y); cmd->data.viewport.rect.w = (int)SDL_floor(renderer->viewport.w); @@ -386,7 +386,7 @@ QueueCmdSetClipRect(SDL_Renderer *renderer) } else { cmd->command = SDL_RENDERCMD_SETCLIPRECT; cmd->data.cliprect.enabled = renderer->clipping_enabled; - /* Convert SDL_FRect to SDL_Rect */ + /* Convert SDL_DRect to SDL_Rect */ cmd->data.cliprect.rect.x = (int)SDL_floor(renderer->clip_rect.x); cmd->data.cliprect.rect.y = (int)SDL_floor(renderer->clip_rect.y); cmd->data.cliprect.rect.w = (int)SDL_floor(renderer->clip_rect.w); @@ -580,10 +580,10 @@ QueueCmdFillRects(SDL_Renderer *renderer, const SDL_FRect * rects, const int cou if (retval < 0) { cmd->command = SDL_RENDERCMD_NO_OP; } - - SDL_small_free(xy, isstack1); - SDL_small_free(indices, isstack2); } + SDL_small_free(xy, isstack1); + SDL_small_free(indices, isstack2); + } else { retval = renderer->QueueFillRects(renderer, cmd, rects, count); if (retval < 0) { @@ -676,7 +676,7 @@ SDL_GetRenderDriverInfo(int index, SDL_RendererInfo * info) #endif } -static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_FRect *viewport, SDL_FPoint *scale) +static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_DRect *viewport, SDL_FPoint *scale) { SDL_LockMutex(renderer->target_mutex); *logical_w = renderer->target ? renderer->logical_w_backup : renderer->logical_w; @@ -698,7 +698,17 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) renderer->WindowEvent(renderer, &event->window); } - if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { + /* In addition to size changes, we also want to do this block for + * moves as well, for two reasons: + * + * 1. The window could be moved to a new display, which has a new + * DPI and therefore a new window/drawable ratio + * 2. For whatever reason, the viewport can get messed up during + * window movement (this has been observed on macOS), so this is + * also a good opportunity to force viewport updates + */ + if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED || + event->window.event == SDL_WINDOWEVENT_MOVED) { /* Make sure we're operating on the default render target */ SDL_Texture *saved_target = SDL_GetRenderTarget(renderer); if (saved_target) { @@ -728,10 +738,10 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) SDL_GetWindowSize(renderer->window, &w, &h); } - renderer->viewport.x = 0; - renderer->viewport.y = 0; - renderer->viewport.w = (float) w; - renderer->viewport.h = (float) h; + renderer->viewport.x = (double)0; + renderer->viewport.y = (double)0; + renderer->viewport.w = (double)w; + renderer->viewport.h = (double)h; QueueCmdSetViewport(renderer); FlushRenderCommandsIfNotBatching(renderer); } @@ -758,7 +768,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) SDL_Window *window = SDL_GetWindowFromID(event->motion.windowID); if (window == renderer->window) { int logical_w, logical_h; - SDL_FRect viewport; + SDL_DRect viewport; SDL_FPoint scale; GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale); if (logical_w) { @@ -785,7 +795,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) SDL_Window *window = SDL_GetWindowFromID(event->button.windowID); if (window == renderer->window) { int logical_w, logical_h; - SDL_FRect viewport; + SDL_DRect viewport; SDL_FPoint scale; GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale); if (logical_w) { @@ -800,7 +810,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) event->type == SDL_FINGERMOTION) { int logical_w, logical_h; float physical_w, physical_h; - SDL_FRect viewport; + SDL_DRect viewport; SDL_FPoint scale; GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale); @@ -1095,6 +1105,13 @@ SDL_GetRenderer(SDL_Window * window) return (SDL_Renderer *)SDL_GetWindowData(window, SDL_WINDOWRENDERDATA); } +SDL_Window * +SDL_RenderGetWindow(SDL_Renderer *renderer) +{ + CHECK_RENDERER_MAGIC(renderer, NULL); + return renderer->window; +} + int SDL_GetRendererInfo(SDL_Renderer * renderer, SDL_RendererInfo * info) { @@ -1585,10 +1602,11 @@ SDL_SetTextureScaleMode(SDL_Texture * texture, SDL_ScaleMode scaleMode) CHECK_TEXTURE_MAGIC(texture, -1); renderer = texture->renderer; - renderer->SetTextureScaleMode(renderer, texture, scaleMode); texture->scaleMode = scaleMode; if (texture->native) { return SDL_SetTextureScaleMode(texture->native, scaleMode); + } else { + renderer->SetTextureScaleMode(renderer, texture, scaleMode); } return 0; } @@ -2210,10 +2228,10 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) } if (texture) { - renderer->viewport.x = 0.0f; - renderer->viewport.y = 0.0f; - renderer->viewport.w = (float) texture->w; - renderer->viewport.h = (float) texture->h; + renderer->viewport.x = (double)0; + renderer->viewport.y = (double)0; + renderer->viewport.w = (double)texture->w; + renderer->viewport.h = (double)texture->h; SDL_zero(renderer->clip_rect); renderer->clipping_enabled = SDL_FALSE; renderer->scale.x = 1.0f; @@ -2245,6 +2263,8 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) SDL_Texture * SDL_GetRenderTarget(SDL_Renderer *renderer) { + CHECK_RENDERER_MAGIC(renderer, NULL); + return renderer->target; } @@ -2420,19 +2440,19 @@ SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect) CHECK_RENDERER_MAGIC(renderer, -1); if (rect) { - renderer->viewport.x = rect->x * renderer->scale.x; - renderer->viewport.y = rect->y * renderer->scale.y; - renderer->viewport.w = rect->w * renderer->scale.x; - renderer->viewport.h = rect->h * renderer->scale.y; + renderer->viewport.x = (double)rect->x * renderer->scale.x; + renderer->viewport.y = (double)rect->y * renderer->scale.y; + renderer->viewport.w = (double)rect->w * renderer->scale.x; + renderer->viewport.h = (double)rect->h * renderer->scale.y; } else { int w, h; if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) { return -1; } - renderer->viewport.x = 0.0f; - renderer->viewport.y = 0.0f; - renderer->viewport.w = (float) w; - renderer->viewport.h = (float) h; + renderer->viewport.x = (double)0; + renderer->viewport.y = (double)0; + renderer->viewport.w = (double)w; + renderer->viewport.h = (double)h; } retval = QueueCmdSetViewport(renderer); return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); @@ -2456,8 +2476,8 @@ RenderGetViewportSize(SDL_Renderer * renderer, SDL_FRect * rect) { rect->x = 0.0f; rect->y = 0.0f; - rect->w = renderer->viewport.w / renderer->scale.x; - rect->h = renderer->viewport.h / renderer->scale.y; + rect->w = (float)(renderer->viewport.w / renderer->scale.x); + rect->h = (float)(renderer->viewport.h / renderer->scale.y); } int @@ -2468,10 +2488,10 @@ SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect) if (rect) { renderer->clipping_enabled = SDL_TRUE; - renderer->clip_rect.x = rect->x * renderer->scale.x; - renderer->clip_rect.y = rect->y * renderer->scale.y; - renderer->clip_rect.w = rect->w * renderer->scale.x; - renderer->clip_rect.h = rect->h * renderer->scale.y; + renderer->clip_rect.x = (double)rect->x * renderer->scale.x; + renderer->clip_rect.y = (double)rect->y * renderer->scale.y; + renderer->clip_rect.w = (double)rect->w * renderer->scale.x; + renderer->clip_rect.h = (double)rect->h * renderer->scale.y; } else { renderer->clipping_enabled = SDL_FALSE; SDL_zero(renderer->clip_rect); @@ -2535,10 +2555,10 @@ SDL_RenderWindowToLogical(SDL_Renderer * renderer, int windowX, int windowY, flo window_physical_y = ((float) windowY) / renderer->dpi_scale.y; if (logicalX) { - *logicalX = (window_physical_x - renderer->viewport.x) / renderer->scale.x; + *logicalX = (float)((window_physical_x - renderer->viewport.x) / renderer->scale.x); } if (logicalY) { - *logicalY = (window_physical_y - renderer->viewport.y) / renderer->scale.y; + *logicalY = (float)((window_physical_y - renderer->viewport.y) / renderer->scale.y); } } @@ -2549,8 +2569,8 @@ SDL_RenderLogicalToWindow(SDL_Renderer * renderer, float logicalX, float logical CHECK_RENDERER_MAGIC(renderer, ); - window_physical_x = (logicalX * renderer->scale.x) + renderer->viewport.x; - window_physical_y = (logicalY * renderer->scale.y) + renderer->viewport.y; + window_physical_x = (float)((logicalX * renderer->scale.x) + renderer->viewport.x); + window_physical_y = (float)((logicalY * renderer->scale.y) + renderer->viewport.y); if (windowX) { *windowX = (int)(window_physical_x * renderer->dpi_scale.x); @@ -3138,10 +3158,11 @@ SDL_RenderDrawLinesF(SDL_Renderer * renderer, num_vertices, indices, num_indices, size_indices, 1.0f, 1.0f); - SDL_small_free(xy, isstack1); - SDL_small_free(indices, isstack2); } + SDL_small_free(xy, isstack1); + SDL_small_free(indices, isstack2); + } else if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { retval = RenderDrawLinesWithRectsF(renderer, points, count); } else { diff --git a/Engine/lib/sdl/src/render/SDL_sysrender.h b/Engine/lib/sdl/src/render/SDL_sysrender.h index 5d92f6a26..7aeb46710 100644 --- a/Engine/lib/sdl/src/render/SDL_sysrender.h +++ b/Engine/lib/sdl/src/render/SDL_sysrender.h @@ -28,6 +28,19 @@ #include "SDL_mutex.h" #include "SDL_yuv_sw_c.h" + +/** + * A rectangle, with the origin at the upper left (double precision). + */ +typedef struct SDL_DRect +{ + double x; + double y; + double w; + double h; +} SDL_DRect; + + /* The SDL 2D rendering system */ typedef struct SDL_RenderDriver SDL_RenderDriver; @@ -201,12 +214,12 @@ struct SDL_Renderer SDL_bool integer_scale; /* The drawable area within the window */ - SDL_FRect viewport; - SDL_FRect viewport_backup; + SDL_DRect viewport; + SDL_DRect viewport_backup; /* The clip rectangle within the window */ - SDL_FRect clip_rect; - SDL_FRect clip_rect_backup; + SDL_DRect clip_rect; + SDL_DRect clip_rect_backup; /* Wether or not the clipping rectangle is used. */ SDL_bool clipping_enabled; @@ -244,8 +257,8 @@ struct SDL_Renderer SDL_RenderCommand *render_commands_pool; Uint32 render_command_generation; Uint32 last_queued_color; - SDL_FRect last_queued_viewport; - SDL_FRect last_queued_cliprect; + SDL_DRect last_queued_viewport; + SDL_DRect last_queued_cliprect; SDL_bool last_queued_cliprect_enabled; SDL_bool color_queued; SDL_bool viewport_queued; diff --git a/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c b/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c index b267fb23e..477f4e975 100644 --- a/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c +++ b/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c @@ -347,7 +347,8 @@ D3D_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) } } -static D3DBLEND GetBlendFunc(SDL_BlendFactor factor) +static D3DBLEND +GetBlendFunc(SDL_BlendFactor factor) { switch (factor) { case SDL_BLENDFACTOR_ZERO: @@ -370,9 +371,28 @@ static D3DBLEND GetBlendFunc(SDL_BlendFactor factor) return D3DBLEND_DESTALPHA; case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA: return D3DBLEND_INVDESTALPHA; - default: - return (D3DBLEND)0; + default: break; } + return (D3DBLEND) 0; +} + +static D3DBLENDOP +GetBlendEquation(SDL_BlendOperation operation) +{ + switch (operation) { + case SDL_BLENDOPERATION_ADD: + return D3DBLENDOP_ADD; + case SDL_BLENDOPERATION_SUBTRACT: + return D3DBLENDOP_SUBTRACT; + case SDL_BLENDOPERATION_REV_SUBTRACT: + return D3DBLENDOP_REVSUBTRACT; + case SDL_BLENDOPERATION_MINIMUM: + return D3DBLENDOP_MIN; + case SDL_BLENDOPERATION_MAXIMUM: + return D3DBLENDOP_MAX; + default: break; + } + return (D3DBLENDOP) 0; } static SDL_bool @@ -387,14 +407,16 @@ D3D_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode); if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) || - !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor)) { + !GetBlendEquation(colorOperation) || + !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor) || + !GetBlendEquation(alphaOperation)) { return SDL_FALSE; } - if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->enableSeparateAlphaBlend) { - return SDL_FALSE; - } - if (colorOperation != SDL_BLENDOPERATION_ADD || alphaOperation != SDL_BLENDOPERATION_ADD) { - return SDL_FALSE; + + if (!data->enableSeparateAlphaBlend) { + if ((srcColorFactor != srcAlphaFactor) || (dstColorFactor != dstAlphaFactor) || (colorOperation != alphaOperation)) { + return SDL_FALSE; + } } return SDL_TRUE; } @@ -1040,11 +1062,15 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend))); IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND, GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend))); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOP, + GetBlendEquation(SDL_GetBlendModeColorOperation(blend))); if (data->enableSeparateAlphaBlend) { IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA, GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend))); IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA, GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend))); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOPALPHA, + GetBlendEquation(SDL_GetBlendModeAlphaOperation(blend))); } } diff --git a/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c b/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c index 89e2ee544..714ca2e77 100644 --- a/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c +++ b/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c @@ -998,6 +998,16 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) goto done; } + /* Set the swap chain target immediately, so that a target is always set + * even before we get to SetDrawState. Without this it's possible to hit + * null references in places like ReadPixels! + */ + ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext, + 1, + &data->mainRenderTargetView, + NULL + ); + data->viewportDirty = SDL_TRUE; done: diff --git a/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c b/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c index b5df73ace..b5af52af3 100644 --- a/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c +++ b/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c @@ -30,6 +30,11 @@ #include #endif +#ifdef SDL_VIDEO_VITA_PVR_OGL +#include +#include +#endif + /* To prevent unnecessary window recreation, * these should match the defaults selected in SDL_GL_ResetAttributes */ @@ -319,6 +324,20 @@ GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h) return result; } +static void +GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +{ + /* If the window x/y/w/h changed at all, assume the viewport has been + * changed behind our backs. x/y changes might seem weird but viewport + * resets have been observed on macOS at minimum! + */ + if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED || + event->event == SDL_WINDOWEVENT_MOVED) { + GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + data->drawstate.viewport_dirty = SDL_TRUE; + } +} + static int GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) { @@ -1212,9 +1231,9 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic } #ifdef __MACOSX__ - // On macOS, moving the window seems to invalidate the OpenGL viewport state, - // so don't bother trying to persist it across frames; always reset it. - // Workaround for: https://github.com/libsdl-org/SDL/issues/1504 + // On macOS on older systems, the OpenGL view change and resize events aren't + // necessarily synchronized, so just always reset it. + // Workaround for: https://discourse.libsdl.org/t/sdl-2-0-22-prerelease/35306/6 data->drawstate.viewport_dirty = SDL_TRUE; #endif @@ -1733,6 +1752,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major); SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor); +#ifndef SDL_VIDEO_VITA_PVR_OGL window_flags = SDL_GetWindowFlags(window); if (!(window_flags & SDL_WINDOW_OPENGL) || profile_mask == SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) { @@ -1746,6 +1766,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) goto error; } } +#endif renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { @@ -1760,6 +1781,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) goto error; } + renderer->WindowEvent = GL_WindowEvent; renderer->GetOutputSize = GL_GetOutputSize; renderer->SupportsBlendMode = GL_SupportsBlendMode; renderer->CreateTexture = GL_CreateTexture; diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm.c b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm.c index 8a8877849..98b03e629 100644 --- a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm.c +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm.c @@ -61,6 +61,11 @@ static int VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * text const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch); +static int VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch); + static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch); @@ -105,12 +110,16 @@ SDL_RenderDriver VITA_GXM_RenderDriver = { .info = { .name = "VITA gxm", .flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE, - .num_texture_formats = 4, + .num_texture_formats = 8, .texture_formats = { [0] = SDL_PIXELFORMAT_ABGR8888, [1] = SDL_PIXELFORMAT_ARGB8888, [2] = SDL_PIXELFORMAT_RGB565, - [3] = SDL_PIXELFORMAT_BGR565 + [3] = SDL_PIXELFORMAT_BGR565, + [4] = SDL_PIXELFORMAT_YV12, + [5] = SDL_PIXELFORMAT_IYUV, + [6] = SDL_PIXELFORMAT_NV12, + [7] = SDL_PIXELFORMAT_NV21, }, .max_texture_width = 4096, .max_texture_height = 4096, @@ -133,6 +142,15 @@ PixelFormatToVITAFMT(Uint32 format) return SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB; case SDL_PIXELFORMAT_BGR565: return SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR; + case SDL_PIXELFORMAT_YV12: + return SCE_GXM_TEXTURE_FORMAT_YVU420P3_CSC0; + case SDL_PIXELFORMAT_IYUV: + return SCE_GXM_TEXTURE_FORMAT_YUV420P3_CSC0; + // should be the other way around. looks like SCE bug. + case SDL_PIXELFORMAT_NV12: + return SCE_GXM_TEXTURE_FORMAT_YVU420P2_CSC0; + case SDL_PIXELFORMAT_NV21: + return SCE_GXM_TEXTURE_FORMAT_YUV420P2_CSC0; default: return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR; } @@ -228,6 +246,7 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags) renderer->UpdateTexture = VITA_GXM_UpdateTexture; #if SDL_HAVE_YUV renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV; + renderer->UpdateTextureNV = VITA_GXM_UpdateTextureNV; #endif renderer->LockTexture = VITA_GXM_LockTexture; renderer->UnlockTexture = VITA_GXM_UnlockTexture; @@ -295,7 +314,17 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) return SDL_OutOfMemory(); } - vita_texture->tex = create_gxm_texture(data, texture->w, texture->h, PixelFormatToVITAFMT(texture->format), (texture->access == SDL_TEXTUREACCESS_TARGET)); + vita_texture->tex = create_gxm_texture( + data, + texture->w, + texture->h, + PixelFormatToVITAFMT(texture->format), + (texture->access == SDL_TEXTUREACCESS_TARGET), + &(vita_texture->w), + &(vita_texture->h), + &(vita_texture->pitch), + &(vita_texture->wscale) + ); if (!vita_texture->tex) { SDL_free(vita_texture); @@ -306,38 +335,129 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) VITA_GXM_SetTextureScaleMode(renderer, texture, texture->scaleMode); - vita_texture->w = gxm_texture_get_width(vita_texture->tex); - vita_texture->h = gxm_texture_get_height(vita_texture->tex); - vita_texture->pitch = gxm_texture_get_stride(vita_texture->tex); +#if SDL_HAVE_YUV + vita_texture->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12)); + vita_texture->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21)); +#endif return 0; } +static void VITA_GXM_SetYUVProfile(SDL_Renderer * renderer, SDL_Texture *texture) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; + int ret = 0; + switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) { + case SDL_YUV_CONVERSION_BT601: + ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT601_STANDARD); + break; + case SDL_YUV_CONVERSION_BT709: + ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT709_STANDARD); + break; + case SDL_YUV_CONVERSION_JPEG: + default: + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Unsupported YUV profile: %d\n", SDL_GetYUVConversionModeForResolution(texture->w, texture->h)); + break; + } + + if (ret < 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Setting YUV profile failed: %x\n", ret); + } +} static int VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch) { - const Uint8 *src; + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata; Uint8 *dst; - int row, length,dpitch; - src = pixels; + int row, length, dpitch; + +#if SDL_HAVE_YUV + if (vita_texture->yuv || vita_texture->nv12) { + VITA_GXM_SetYUVProfile(renderer, texture); + } +#endif VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch); length = rect->w * SDL_BYTESPERPIXEL(texture->format); if (length == pitch && length == dpitch) { - SDL_memcpy(dst, src, length*rect->h); + SDL_memcpy(dst, pixels, length*rect->h); } else { for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += pitch; + SDL_memcpy(dst, pixels, length); + pixels += pitch; dst += dpitch; } } +#if SDL_HAVE_YUV + if (vita_texture->yuv) { + void *Udst; + void *Vdst; + int uv_pitch = (dpitch+1) / 2; + int uv_src_pitch = (pitch+1) / 2; + SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2}; + + // skip Y plane + Uint8 *Dpixels = gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h); + + Udst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x; + Vdst = Dpixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x; + + length = UVrect.w; + + // U plane + if (length == uv_src_pitch && length == uv_pitch) { + SDL_memcpy(Udst, pixels, length*UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(Udst, pixels, length); + pixels += uv_src_pitch; + Udst += uv_pitch; + } + } + + // V plane + if (length == uv_src_pitch && length == uv_pitch) { + SDL_memcpy(Vdst, pixels, length*UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(Vdst, pixels, length); + pixels += uv_src_pitch; + Vdst += uv_pitch; + } + } + + } else if (vita_texture->nv12) { + void *UVdst; + int uv_pitch = 2 * ((dpitch+1) / 2); + int uv_src_pitch = 2 * ((pitch+1) / 2); + SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2 , (rect->h + 1) / 2}; + + // skip Y plane + void *Dpixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h)); + UVdst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x; + + length = UVrect.w*2; + + // UV plane + if (length == uv_src_pitch && length == uv_pitch) { + SDL_memcpy(UVdst, pixels, length*UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(UVdst, pixels, length); + pixels += uv_src_pitch; + UVdst += uv_pitch; + } + } + } +#endif + return 0; } +#if SDL_HAVE_YUV static int VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, @@ -345,9 +465,133 @@ VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch) { + Uint8 *dst; + int row, length, dpitch; + SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2}; + + VITA_GXM_SetYUVProfile(renderer, texture); + + // copy Y plane + // obtain pixels via locking so that texture is flushed + VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch); + + length = rect->w; + + if (length == Ypitch && length == dpitch) { + SDL_memcpy(dst, Yplane, length*rect->h); + } else { + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, Yplane, length); + Yplane += Ypitch; + dst += dpitch; + } + } + + // U/V planes + { + void *Udst; + void *Vdst; + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata; + int uv_pitch = (dpitch+1) / 2; + + // skip Y plane + void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h)); + + if (texture->format == SDL_PIXELFORMAT_YV12) { // YVU + Vdst = pixels + (UVrect.y * uv_pitch) + UVrect.x; + Udst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x; + } else { // YUV + Udst = pixels + (UVrect.y * uv_pitch) + UVrect.x; + Vdst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x; + } + + length = UVrect.w; + + // U plane + if (length == Upitch && length == uv_pitch) { + SDL_memcpy(Udst, Uplane, length*UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(Udst, Uplane, length); + Uplane += Upitch; + Udst += uv_pitch; + } + } + + // V plane + if (length == Vpitch && length == uv_pitch) { + SDL_memcpy(Vdst, Vplane, length*UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(Vdst, Vplane, length); + Vplane += Vpitch; + Vdst += uv_pitch; + } + } + + } + return 0; } +static int +VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ + + Uint8 *dst; + int row, length, dpitch; + SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2}; + + VITA_GXM_SetYUVProfile(renderer, texture); + + // copy Y plane + VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch); + + length = rect->w * SDL_BYTESPERPIXEL(texture->format); + + if (length == Ypitch && length == dpitch) { + SDL_memcpy(dst, Yplane, length*rect->h); + } else { + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, Yplane, length); + Yplane += Ypitch; + dst += dpitch; + } + } + + // UV plane + { + void *UVdst; + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata; + int uv_pitch = 2 * ((dpitch+1) / 2); + + // skip Y plane + void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h)); + + UVdst = pixels + (UVrect.y * uv_pitch) + UVrect.x; + + length = UVrect.w * 2; + + // UV plane + if (length == UVpitch && length == uv_pitch) { + SDL_memcpy(UVdst, UVplane, length*UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(UVdst, UVplane, length); + UVplane += UVpitch; + UVdst += uv_pitch; + } + } + } + + return 0; +} + +#endif + static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch) @@ -519,6 +763,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu size_indices = indices ? size_indices : 0; if (texture) { + VITA_GXM_TextureData* vita_texture = (VITA_GXM_TextureData*) texture->driverdata; texture_vertex *vertices; vertices = (texture_vertex *)pool_malloc( @@ -551,7 +796,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu vertices[i].x = xy_[0] * scale_x; vertices[i].y = xy_[1] * scale_y; - vertices[i].u = uv_[0]; + vertices[i].u = uv_[0] * vita_texture->wscale; vertices[i].v = uv_[1]; vertices[i].color = col_; } @@ -730,14 +975,6 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd) return 0; } -static int -SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd) -{ - VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata; - - return SetDrawState(data, cmd); -} - static int VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { @@ -824,11 +1061,7 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void * nextcmd = nextcmd->next; } - if (thistexture) { - ret = SetCopyState(renderer, cmd); - } else { - ret = SetDrawState(data, cmd); - } + ret = SetDrawState(data, cmd); if (ret == 0) { int op = SCE_GXM_PRIMITIVE_TRIANGLES; @@ -1013,7 +1246,7 @@ VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) sceGxmFinish(data->gxm_context); - free_gxm_texture(vita_texture->tex); + free_gxm_texture(data, vita_texture->tex); SDL_free(vita_texture); diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.c b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.c index d3322730a..85d682ad7 100644 --- a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.c +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.c @@ -26,7 +26,7 @@ #include "SDL_render_vita_gxm_memory.h" void * -mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid) +vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid) { void *mem; @@ -51,7 +51,7 @@ mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignm } void -mem_gpu_free(SceUID uid) +vita_mem_free(SceUID uid) { void *mem = NULL; if (sceKernelGetMemBlockBase(uid, &mem) < 0) @@ -61,7 +61,71 @@ mem_gpu_free(SceUID uid) } void * -mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset) +vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size) +{ + void *mem; + + if (data->texturePool == NULL) { + int poolsize; + int ret; + SceKernelFreeMemorySizeInfo info; + info.size = sizeof(SceKernelFreeMemorySizeInfo); + sceKernelGetFreeMemorySize(&info); + + poolsize = ALIGN(info.size_cdram, 256*1024); + if (poolsize > info.size_cdram) { + poolsize = ALIGN(info.size_cdram - 256*1024, 256*1024); + } + data->texturePoolUID = sceKernelAllocMemBlock("gpu_texture_pool", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, poolsize, NULL); + if (data->texturePoolUID < 0) { + return NULL; + } + + ret = sceKernelGetMemBlockBase(data->texturePoolUID, &mem); + if ( ret < 0) + { + return NULL; + } + data->texturePool = sceClibMspaceCreate(mem, poolsize); + + if (data->texturePool == NULL) { + return NULL; + } + ret = sceGxmMapMemory(mem, poolsize, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE); + if (ret < 0) + { + return NULL; + } + } + return sceClibMspaceMemalign(data->texturePool, SCE_GXM_TEXTURE_ALIGNMENT, size); +} + +void +vita_gpu_mem_free(VITA_GXM_RenderData *data, void* ptr) +{ + if (data->texturePool != NULL) + { + sceClibMspaceFree(data->texturePool, ptr); + } +} + +void +vita_gpu_mem_destroy(VITA_GXM_RenderData *data) +{ + void *mem = NULL; + if (data->texturePool != NULL) + { + sceClibMspaceDestroy(data->texturePool); + data->texturePool = NULL; + if (sceKernelGetMemBlockBase(data->texturePoolUID, &mem) < 0) + return; + sceGxmUnmapMemory(mem); + sceKernelFreeMemBlock(data->texturePoolUID); + } +} + +void * +vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset) { void *mem = NULL; @@ -77,7 +141,7 @@ mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset) } void -mem_vertex_usse_free(SceUID uid) +vita_mem_vertex_usse_free(SceUID uid) { void *mem = NULL; if (sceKernelGetMemBlockBase(uid, &mem) < 0) @@ -87,7 +151,7 @@ mem_vertex_usse_free(SceUID uid) } void * -mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset) +vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset) { void *mem = NULL; @@ -103,7 +167,7 @@ mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offse } void -mem_fragment_usse_free(SceUID uid) +vita_mem_fragment_usse_free(SceUID uid) { void *mem = NULL; if (sceKernelGetMemBlockBase(uid, &mem) < 0) diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.h b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.h index 51bc8a80a..93b9f3498 100644 --- a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.h +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.h @@ -25,15 +25,19 @@ #include #include #include +#include "SDL_render_vita_gxm_types.h" #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) -void *mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid); -void mem_gpu_free(SceUID uid); -void *mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset); -void mem_vertex_usse_free(SceUID uid); -void *mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset); -void mem_fragment_usse_free(SceUID uid); +void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid); +void vita_mem_free(SceUID uid); +void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size); +void vita_gpu_mem_free(VITA_GXM_RenderData *data, void* ptr); +void vita_gpu_mem_destroy(VITA_GXM_RenderData *data); +void *vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset); +void vita_mem_vertex_usse_free(SceUID uid); +void *vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset); +void vita_mem_fragment_usse_free(SceUID uid); #endif /* SDL_RENDER_VITA_GXM_MEMORY_H */ diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.c b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.c index e043b55ab..035e8a63c 100644 --- a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.c +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.c @@ -117,6 +117,8 @@ tex_format_to_bytespp(SceGxmTextureFormat format) case SCE_GXM_TEXTURE_BASE_FORMAT_U8: case SCE_GXM_TEXTURE_BASE_FORMAT_S8: case SCE_GXM_TEXTURE_BASE_FORMAT_P8: + case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2: // YUV actually uses 12 bits per pixel. UV planes bits/mem are handled elsewhere + case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3: return 1; case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4: case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2: @@ -414,28 +416,28 @@ gxm_init(SDL_Renderer *renderer) } // allocate ring buffer memory using default sizes - vdmRingBuffer = mem_gpu_alloc( + vdmRingBuffer = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE, 4, SCE_GXM_MEMORY_ATTRIB_READ, &data->vdmRingBufferUid); - vertexRingBuffer = mem_gpu_alloc( + vertexRingBuffer = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE, 4, SCE_GXM_MEMORY_ATTRIB_READ, &data->vertexRingBufferUid); - fragmentRingBuffer = mem_gpu_alloc( + fragmentRingBuffer = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE, 4, SCE_GXM_MEMORY_ATTRIB_READ, &data->fragmentRingBufferUid); - fragmentUsseRingBuffer = mem_fragment_usse_alloc( + fragmentUsseRingBuffer = vita_mem_fragment_usse_alloc( SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE, &data->fragmentUsseRingBufferUid, &fragmentUsseRingBufferOffset); @@ -480,7 +482,7 @@ gxm_init(SDL_Renderer *renderer) for (i = 0; i < VITA_GXM_BUFFERS; i++) { // allocate memory for display - data->displayBufferData[i] = mem_gpu_alloc( + data->displayBufferData[i] = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT, SCE_GXM_COLOR_SURFACE_ALIGNMENT, @@ -525,7 +527,7 @@ gxm_init(SDL_Renderer *renderer) // allocate the depth buffer - data->depthBufferData = mem_gpu_alloc( + data->depthBufferData = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, 4 * sampleCount, SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, @@ -533,7 +535,7 @@ gxm_init(SDL_Renderer *renderer) &data->depthBufferUid); // allocate the stencil buffer - data->stencilBufferData = mem_gpu_alloc( + data->stencilBufferData = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, 4 * sampleCount, SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, @@ -565,19 +567,19 @@ gxm_init(SDL_Renderer *renderer) // allocate memory for buffers and USSE code - patcherBuffer = mem_gpu_alloc( + patcherBuffer = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, patcherBufferSize, 4, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, &data->patcherBufferUid); - patcherVertexUsse = mem_vertex_usse_alloc( + patcherVertexUsse = vita_mem_vertex_usse_alloc( patcherVertexUsseSize, &data->patcherVertexUsseUid, &patcherVertexUsseOffset); - patcherFragmentUsse = mem_fragment_usse_alloc( + patcherFragmentUsse = vita_mem_fragment_usse_alloc( patcherFragmentUsseSize, &data->patcherFragmentUsseUid, &patcherFragmentUsseOffset); @@ -728,7 +730,7 @@ gxm_init(SDL_Renderer *renderer) } // create the clear triangle vertex/index data - data->clearVertices = (clear_vertex *)mem_gpu_alloc( + data->clearVertices = (clear_vertex *)vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, 3*sizeof(clear_vertex), 4, @@ -740,7 +742,7 @@ gxm_init(SDL_Renderer *renderer) // Allocate a 64k * 2 bytes = 128 KiB buffer and store all possible // 16-bit indices in linear ascending order, so we can use this for // all drawing operations where we don't want to use indexing. - data->linearIndices = (uint16_t *)mem_gpu_alloc( + data->linearIndices = (uint16_t *)vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, UINT16_MAX*sizeof(uint16_t), sizeof(uint16_t), @@ -871,7 +873,7 @@ gxm_init(SDL_Renderer *renderer) data->textureWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(textureVertexProgramGxp, "wvp"); // Allocate memory for the memory pool - data->pool_addr[0] = mem_gpu_alloc( + data->pool_addr[0] = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW, VITA_GXM_POOL_SIZE, sizeof(void *), @@ -879,7 +881,7 @@ gxm_init(SDL_Renderer *renderer) &data->poolUid[0] ); - data->pool_addr[1] = mem_gpu_alloc( + data->pool_addr[1] = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW, VITA_GXM_POOL_SIZE, sizeof(void *), @@ -918,28 +920,28 @@ void gxm_finish(SDL_Renderer *renderer) free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mod); free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mul); - mem_gpu_free(data->linearIndicesUid); - mem_gpu_free(data->clearVerticesUid); + vita_mem_free(data->linearIndicesUid); + vita_mem_free(data->clearVerticesUid); // wait until display queue is finished before deallocating display buffers sceGxmDisplayQueueFinish(); // clean up display queue - mem_gpu_free(data->depthBufferUid); + vita_mem_free(data->depthBufferUid); for (size_t i = 0; i < VITA_GXM_BUFFERS; i++) { // clear the buffer then deallocate SDL_memset(data->displayBufferData[i], 0, VITA_GXM_SCREEN_HEIGHT * VITA_GXM_SCREEN_STRIDE * 4); - mem_gpu_free(data->displayBufferUid[i]); + vita_mem_free(data->displayBufferUid[i]); // destroy the sync object sceGxmSyncObjectDestroy(data->displayBufferSync[i]); } // Free the depth and stencil buffer - mem_gpu_free(data->depthBufferUid); - mem_gpu_free(data->stencilBufferUid); + vita_mem_free(data->depthBufferUid); + vita_mem_free(data->stencilBufferUid); // unregister programs and destroy shader patcher sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->clearFragmentProgramId); @@ -950,23 +952,24 @@ void gxm_finish(SDL_Renderer *renderer) sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureVertexProgramId); sceGxmShaderPatcherDestroy(data->shaderPatcher); - mem_fragment_usse_free(data->patcherFragmentUsseUid); - mem_vertex_usse_free(data->patcherVertexUsseUid); - mem_gpu_free(data->patcherBufferUid); + vita_mem_fragment_usse_free(data->patcherFragmentUsseUid); + vita_mem_vertex_usse_free(data->patcherVertexUsseUid); + vita_mem_free(data->patcherBufferUid); // destroy the render target sceGxmDestroyRenderTarget(data->renderTarget); // destroy the gxm context sceGxmDestroyContext(data->gxm_context); - mem_fragment_usse_free(data->fragmentUsseRingBufferUid); - mem_gpu_free(data->fragmentRingBufferUid); - mem_gpu_free(data->vertexRingBufferUid); - mem_gpu_free(data->vdmRingBufferUid); + vita_mem_fragment_usse_free(data->fragmentUsseRingBufferUid); + vita_mem_free(data->fragmentRingBufferUid); + vita_mem_free(data->vertexRingBufferUid); + vita_mem_free(data->vdmRingBufferUid); SDL_free(data->contextParams.hostMem); - mem_gpu_free(data->poolUid[0]); - mem_gpu_free(data->poolUid[1]); + vita_mem_free(data->poolUid[0]); + vita_mem_free(data->poolUid[1]); + vita_gpu_mem_destroy(data); // terminate libgxm sceGxmTerminate(); @@ -975,16 +978,20 @@ void gxm_finish(SDL_Renderer *renderer) // textures void -free_gxm_texture(gxm_texture *texture) +free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture) { if (texture) { if (texture->gxm_rendertarget) { sceGxmDestroyRenderTarget(texture->gxm_rendertarget); } if (texture->depth_UID) { - mem_gpu_free(texture->depth_UID); + vita_mem_free(texture->depth_UID); + } + if (texture->cdram) { + vita_gpu_mem_free(data, sceGxmTextureGetData(&texture->gxm_tex)); + } else { + vita_mem_free(texture->data_UID); } - mem_gpu_free(texture->data_UID); SDL_free(texture); } } @@ -995,25 +1002,6 @@ gxm_texture_get_format(const gxm_texture *texture) return sceGxmTextureGetFormat(&texture->gxm_tex); } -unsigned int -gxm_texture_get_width(const gxm_texture *texture) -{ - return sceGxmTextureGetWidth(&texture->gxm_tex); -} - -unsigned int -gxm_texture_get_height(const gxm_texture *texture) -{ - return sceGxmTextureGetHeight(&texture->gxm_tex); -} - -unsigned int -gxm_texture_get_stride(const gxm_texture *texture) -{ - return ((gxm_texture_get_width(texture) + 7) & ~7) - * tex_format_to_bytespp(gxm_texture_get_format(texture)); -} - void * gxm_texture_get_datap(const gxm_texture *texture) { @@ -1021,34 +1009,53 @@ gxm_texture_get_datap(const gxm_texture *texture) } gxm_texture * -create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget) +create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale) { gxm_texture *texture = SDL_calloc(1, sizeof(gxm_texture)); - const int tex_size = ((w + 7) & ~ 7) * h * tex_format_to_bytespp(format); + int aligned_w = ALIGN(w, 8); + int texture_w = w; + int tex_size = aligned_w * h * tex_format_to_bytespp(format); void *texture_data; + int ret; + + *return_wscale = 1.0f; + + // SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3/P2 based formats require width aligned to 16 + if ( (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 || (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2) { + aligned_w = ALIGN(w, 16); + texture_w = aligned_w; + tex_size = aligned_w * h * tex_format_to_bytespp(format); + *return_wscale = (float) (w) / texture_w; + // add storage for UV planes + tex_size += (((aligned_w + 1) / 2) * ((h + 1) / 2)) * 2; + } if (!texture) return NULL; + *return_w = w; + *return_h = h; + *return_pitch = aligned_w * tex_format_to_bytespp(format); + /* Allocate a GPU buffer for the texture */ - texture_data = mem_gpu_alloc( - SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, - tex_size, - SCE_GXM_TEXTURE_ALIGNMENT, - SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, - &texture->data_UID + texture_data = vita_gpu_mem_alloc( + data, + tex_size ); /* Try SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE in case we're out of VRAM */ if (!texture_data) { SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "CDRAM texture allocation failed\n"); - texture_data = mem_gpu_alloc( + texture_data = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, tex_size, SCE_GXM_TEXTURE_ALIGNMENT, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, &texture->data_UID ); + texture->cdram = 0; + } else { + texture->cdram = 1; } if (!texture_data) { @@ -1060,7 +1067,12 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc SDL_memset(texture_data, 0, tex_size); /* Create the gxm texture */ - sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, w, h, 0); + ret = sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, texture_w, h, 0); + if (ret < 0) { + free_gxm_texture(data, texture); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "texture init failed: %x\n", ret); + return NULL; + } if (isRenderTarget) { void *depthBufferData; @@ -1083,13 +1095,13 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc ); if (err < 0) { - free_gxm_texture(texture); - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %d\n", err); + free_gxm_texture(data, texture); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %x\n", err); return NULL; } // allocate it - depthBufferData = mem_gpu_alloc( + depthBufferData = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, 4*sampleCount, SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, @@ -1106,8 +1118,8 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc NULL); if (err < 0) { - free_gxm_texture(texture); - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %d\n", err); + free_gxm_texture(data, texture); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %x\n", err); return NULL; } @@ -1131,8 +1143,8 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc texture->gxm_rendertarget = tgt; if (err < 0) { - free_gxm_texture(texture); - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %d\n", err); + free_gxm_texture(data, texture); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %x\n", err); return NULL; } } @@ -1181,7 +1193,7 @@ void gxm_init_for_common_dialog(void) for (int i = 0; i < VITA_GXM_BUFFERS; i += 1) { buffer_for_common_dialog[i].displayData.wait_vblank = SDL_TRUE; - buffer_for_common_dialog[i].displayData.address = mem_gpu_alloc( + buffer_for_common_dialog[i].displayData.address = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT, SCE_GXM_COLOR_SURFACE_ALIGNMENT, @@ -1229,7 +1241,7 @@ void gxm_term_for_common_dialog(void) sceGxmDisplayQueueFinish(); for (int i = 0; i < VITA_GXM_BUFFERS; i += 1) { - mem_gpu_free(buffer_for_common_dialog[i].uid); + vita_mem_free(buffer_for_common_dialog[i].uid); sceGxmSyncObjectDestroy(buffer_for_common_dialog[i].sync); } } diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.h b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.h index 351bdc2e6..67659889d 100644 --- a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.h +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.h @@ -48,15 +48,12 @@ void unset_clip_rectangle(VITA_GXM_RenderData *data); int gxm_init(SDL_Renderer *renderer); void gxm_finish(SDL_Renderer *renderer); -gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget); -void free_gxm_texture(gxm_texture *texture); +gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale); +void free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture); void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter); SceGxmTextureFormat gxm_texture_get_format(const gxm_texture *texture); -unsigned int gxm_texture_get_width(const gxm_texture *texture); -unsigned int gxm_texture_get_height(const gxm_texture *texture); -unsigned int gxm_texture_get_stride(const gxm_texture *texture); void *gxm_texture_get_datap(const gxm_texture *texture); void gxm_minimal_init_for_common_dialog(void); diff --git a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_types.h b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_types.h index 898a92d9c..c5cbf5898 100644 --- a/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_types.h +++ b/Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_types.h @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -79,6 +80,7 @@ typedef struct gxm_texture { SceGxmColorSurface gxm_colorsurface; SceGxmDepthStencilSurface gxm_depthstencil; SceUID depth_UID; + SDL_bool cdram; } gxm_texture; typedef struct fragment_programs { @@ -186,14 +188,19 @@ typedef struct blend_fragment_programs blendFragmentPrograms; gxm_drawstate_cache drawstate; + SceClibMspace texturePool; + SceUID texturePoolUID; } VITA_GXM_RenderData; typedef struct { gxm_texture *tex; - unsigned int pitch; - unsigned int w; - unsigned int h; + unsigned int pitch; + unsigned int w; + unsigned int h; + float wscale; + SDL_bool yuv; + SDL_bool nv12; } VITA_GXM_TextureData; #endif /* SDL_RENDER_VITA_GXM_TYPES_H */ diff --git a/Engine/lib/sdl/src/test/SDL_test_common.c b/Engine/lib/sdl/src/test/SDL_test_common.c index 48c6c72f0..93a0e7c74 100644 --- a/Engine/lib/sdl/src/test/SDL_test_common.c +++ b/Engine/lib/sdl/src/test/SDL_test_common.c @@ -1464,10 +1464,12 @@ default: return "???"; static void SDLTest_PrintEvent(SDL_Event * event) { +#ifndef VERBOSE_MOTION_EVENTS if ((event->type == SDL_MOUSEMOTION) || (event->type == SDL_FINGERMOTION)) { /* Mouse and finger motion are really spammy */ return; } +#endif switch (event->type) { case SDL_DISPLAYEVENT: diff --git a/Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c b/Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c index 984ae10fe..d3fc7a3bd 100644 --- a/Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c +++ b/Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c @@ -56,12 +56,12 @@ SDL_CreateMutex(void) void SDL_DestroyMutex(SDL_mutex * mutex) { - ULONG ulRC; HMTX hMtx = (HMTX)mutex; - - ulRC = DosCloseMutexSem(hMtx); - if (ulRC != NO_ERROR) { - debug_os2("DosCloseMutexSem(), rc = %u", ulRC); + if (hMtx != NULLHANDLE) { + const ULONG ulRC = DosCloseMutexSem(hMtx); + if (ulRC != NO_ERROR) { + debug_os2("DosCloseMutexSem(), rc = %u", ulRC); + } } } diff --git a/Engine/lib/sdl/src/timer/os2/SDL_systimer.c b/Engine/lib/sdl/src/timer/os2/SDL_systimer.c index c5bcf64b7..8a8425d29 100644 --- a/Engine/lib/sdl/src/timer/os2/SDL_systimer.c +++ b/Engine/lib/sdl/src/timer/os2/SDL_systimer.c @@ -39,6 +39,7 @@ typedef unsigned long long ULLONG; +static SDL_bool ticks_started = SDL_FALSE; static ULONG ulTmrFreq = 0; static ULLONG ullTmrStart = 0; @@ -46,7 +47,14 @@ void SDL_TicksInit(void) { ULONG ulTmrStart; /* for 32-bit fallback. */ - ULONG ulRC = DosTmrQueryFreq(&ulTmrFreq); + ULONG ulRC; + + if (ticks_started) { + return; + } + ticks_started = SDL_TRUE; + + ulRC = DosTmrQueryFreq(&ulTmrFreq); if (ulRC != NO_ERROR) { debug_os2("DosTmrQueryFreq() failed, rc = %u", ulRC); } else { @@ -65,6 +73,7 @@ SDL_TicksInit(void) void SDL_TicksQuit(void) { + ticks_started = SDL_FALSE; } Uint64 @@ -73,7 +82,7 @@ SDL_GetTicks64(void) Uint64 ui64Result; ULLONG ullTmrNow; - if (ulTmrFreq == 0) { /* Was not initialized. */ + if (!ticks_started) { SDL_TicksInit(); } diff --git a/Engine/lib/sdl/src/video/SDL_bmp.c b/Engine/lib/sdl/src/video/SDL_bmp.c index 0987f5435..cb220440a 100644 --- a/Engine/lib/sdl/src/video/SDL_bmp.c +++ b/Engine/lib/sdl/src/video/SDL_bmp.c @@ -412,6 +412,12 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) goto done; } + if (biBitCount >= 32) { /* we shift biClrUsed by this value later. */ + SDL_SetError("Unsupported or incorrect biBitCount field"); + was_error = SDL_TRUE; + goto done; + } + if (biClrUsed == 0) { biClrUsed = 1 << biBitCount; } diff --git a/Engine/lib/sdl/src/video/SDL_egl.c b/Engine/lib/sdl/src/video/SDL_egl.c index c9fb476b0..e62fe9931 100644 --- a/Engine/lib/sdl/src/video/SDL_egl.c +++ b/Engine/lib/sdl/src/video/SDL_egl.c @@ -27,7 +27,6 @@ #endif #if SDL_VIDEO_DRIVER_ANDROID #include -#include "../core/android/SDL_android.h" #include "../video/android/SDL_androidvideo.h" #endif #if SDL_VIDEO_DRIVER_RPI @@ -99,7 +98,7 @@ #define DEFAULT_OGL_ES "libGLESv1_CM.so.1" #endif /* SDL_VIDEO_DRIVER_RPI */ -#if SDL_VIDEO_OPENGL +#if SDL_VIDEO_OPENGL && !SDL_VIDEO_VITA_PVR_OGL #include "SDL_opengl.h" #endif @@ -530,7 +529,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa } #endif /* Try the implementation-specific eglGetDisplay even if eglGetPlatformDisplay fails */ - if (_this->egl_data->egl_display == EGL_NO_DISPLAY) { + if ((_this->egl_data->egl_display == EGL_NO_DISPLAY) && (_this->egl_data->eglGetDisplay != NULL)) { _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display); } if (_this->egl_data->egl_display == EGL_NO_DISPLAY) { @@ -1062,7 +1061,7 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) if (SDL_GL_ExtensionSupported("GL_OES_surfaceless_context")) { _this->gl_allow_no_surface = SDL_TRUE; } -#if SDL_VIDEO_OPENGL +#if SDL_VIDEO_OPENGL && !defined(SDL_VIDEO_DRIVER_VITA) } else { /* Desktop OpenGL supports it by default from version 3.0 on. */ void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params); diff --git a/Engine/lib/sdl/src/video/SDL_pixels.c b/Engine/lib/sdl/src/video/SDL_pixels.c index b76161d03..858ccba7b 100644 --- a/Engine/lib/sdl/src/video/SDL_pixels.c +++ b/Engine/lib/sdl/src/video/SDL_pixels.c @@ -28,6 +28,7 @@ #include "SDL_blit.h" #include "SDL_pixels_c.h" #include "SDL_RLEaccel_c.h" +#include "../SDL_list.h" /* Lookup tables to expand partial bytes to the full 0..255 range */ @@ -1024,12 +1025,6 @@ SDL_AllocBlitMap(void) } -typedef struct SDL_ListNode -{ - void *entry; - struct SDL_ListNode *next; -} SDL_ListNode; - void SDL_InvalidateAllBlitMap(SDL_Surface *surface) { @@ -1045,40 +1040,6 @@ SDL_InvalidateAllBlitMap(SDL_Surface *surface) } } -static void SDL_ListAdd(SDL_ListNode **head, void *ent); -static void SDL_ListRemove(SDL_ListNode **head, void *ent); - -void -SDL_ListAdd(SDL_ListNode **head, void *ent) -{ - SDL_ListNode *node = SDL_malloc(sizeof (*node)); - - if (node == NULL) { - SDL_OutOfMemory(); - return; - } - - node->entry = ent; - node->next = *head; - *head = node; -} - -void -SDL_ListRemove(SDL_ListNode **head, void *ent) -{ - SDL_ListNode **ptr = head; - - while (*ptr) { - if ((*ptr)->entry == ent) { - SDL_ListNode *tmp = *ptr; - *ptr = (*ptr)->next; - SDL_free(tmp); - return; - } - ptr = &(*ptr)->next; - } -} - void SDL_InvalidateMap(SDL_BlitMap * map) { diff --git a/Engine/lib/sdl/src/video/SDL_sysvideo.h b/Engine/lib/sdl/src/video/SDL_sysvideo.h index e2a65045b..2384a64ac 100644 --- a/Engine/lib/sdl/src/video/SDL_sysvideo.h +++ b/Engine/lib/sdl/src/video/SDL_sysvideo.h @@ -345,6 +345,7 @@ struct SDL_VideoDevice Uint32 next_object_id; char *clipboard_text; SDL_bool setting_display_mode; + SDL_bool disable_display_mode_switching; /* * * */ /* Data used by the GL drivers */ diff --git a/Engine/lib/sdl/src/video/SDL_video.c b/Engine/lib/sdl/src/video/SDL_video.c index 3be98806d..93c803e70 100644 --- a/Engine/lib/sdl/src/video/SDL_video.c +++ b/Engine/lib/sdl/src/video/SDL_video.c @@ -61,12 +61,12 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_COCOA &COCOA_bootstrap, #endif -#if SDL_VIDEO_DRIVER_WAYLAND - &Wayland_bootstrap, -#endif #if SDL_VIDEO_DRIVER_X11 &X11_bootstrap, #endif +#if SDL_VIDEO_DRIVER_WAYLAND + &Wayland_bootstrap, +#endif #if SDL_VIDEO_DRIVER_VIVANTE &VIVANTE_bootstrap, #endif @@ -261,6 +261,7 @@ SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window * window, Uint32 * fo SDL_TEXTUREACCESS_STREAMING, window->w, window->h); if (!data->texture) { + /* codechecker_false_positive [Malloc] Static analyzer doesn't realize allocated `data` is saved to SDL_WINDOWTEXTUREDATA and not leaked here. */ return -1; } @@ -424,7 +425,7 @@ SDL_VideoInit(const char *driver_name) i = index = 0; video = NULL; if (driver_name == NULL) { - driver_name = SDL_getenv("SDL_VIDEODRIVER"); + driver_name = SDL_GetHint(SDL_HINT_VIDEODRIVER); } if (driver_name != NULL && *driver_name != 0) { const char *driver_attempt = driver_name; @@ -1184,6 +1185,7 @@ SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode) } else if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode, &fullscreen_mode)) { + SDL_zerop(mode); return SDL_SetError("Couldn't find display mode match"); } @@ -1337,14 +1339,17 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) resized = SDL_FALSE; } - /* only do the mode change if we want exclusive fullscreen */ - if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { - if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) { - return -1; - } - } else { - if (SDL_SetDisplayModeForDisplay(display, NULL) < 0) { - return -1; + /* Don't try to change the display mode if the driver doesn't want it. */ + if (_this->disable_display_mode_switching == SDL_FALSE) { + /* only do the mode change if we want exclusive fullscreen */ + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { + if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) { + return -1; + } + } else { + if (SDL_SetDisplayModeForDisplay(display, NULL) < 0) { + return -1; + } } } @@ -3055,7 +3060,8 @@ ShouldMinimizeOnFocusLoss(SDL_Window * window) /* Real fullscreen windows should minimize on focus loss so the desktop video mode is restored */ hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS); if (!hint || !*hint || SDL_strcasecmp(hint, "auto") == 0) { - if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP || + _this->disable_display_mode_switching == SDL_TRUE) { return SDL_FALSE; } else { return SDL_TRUE; @@ -3919,6 +3925,10 @@ SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx) { int retval; + if (!_this) { + return SDL_UninitializedVideo(); + } + if (window == SDL_GL_GetCurrentWindow() && ctx == SDL_GL_GetCurrentContext()) { /* We're already current. */ @@ -4262,12 +4272,12 @@ SDL_IsScreenKeyboardShown(SDL_Window *window) #if SDL_VIDEO_DRIVER_UIKIT #include "uikit/SDL_uikitmessagebox.h" #endif -#if SDL_VIDEO_DRIVER_WAYLAND -#include "wayland/SDL_waylandmessagebox.h" -#endif #if SDL_VIDEO_DRIVER_X11 #include "x11/SDL_x11messagebox.h" #endif +#if SDL_VIDEO_DRIVER_WAYLAND +#include "wayland/SDL_waylandmessagebox.h" +#endif #if SDL_VIDEO_DRIVER_HAIKU #include "haiku/SDL_bmessagebox.h" #endif @@ -4375,13 +4385,6 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) retval = 0; } #endif -#if SDL_VIDEO_DRIVER_WAYLAND - if (retval == -1 && - SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WAYLAND) && - Wayland_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif #if SDL_VIDEO_DRIVER_X11 if (retval == -1 && SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_X11) && @@ -4389,6 +4392,13 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) retval = 0; } #endif +#if SDL_VIDEO_DRIVER_WAYLAND + if (retval == -1 && + SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WAYLAND) && + Wayland_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } +#endif #if SDL_VIDEO_DRIVER_HAIKU if (retval == -1 && SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_HAIKU) && diff --git a/Engine/lib/sdl/src/video/android/SDL_androidvideo.c b/Engine/lib/sdl/src/video/android/SDL_androidvideo.c index 61b9a87e9..9555ea078 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidvideo.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidvideo.c @@ -122,6 +122,7 @@ Android_CreateDevice(int devindex) device->SetWindowTitle = Android_SetWindowTitle; device->SetWindowFullscreen = Android_SetWindowFullscreen; device->MinimizeWindow = Android_MinimizeWindow; + device->SetWindowResizable = Android_SetWindowResizable; device->DestroyWindow = Android_DestroyWindow; device->GetWindowWMInfo = Android_GetWindowWMInfo; diff --git a/Engine/lib/sdl/src/video/android/SDL_androidwindow.c b/Engine/lib/sdl/src/video/android/SDL_androidwindow.c index c5f8919ea..f9ae3f10c 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidwindow.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidwindow.c @@ -167,6 +167,12 @@ Android_MinimizeWindow(_THIS, SDL_Window *window) Android_JNI_MinizeWindow(); } +void Android_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable) +{ + /* Set orientation */ + Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS)); +} + void Android_DestroyWindow(_THIS, SDL_Window *window) { diff --git a/Engine/lib/sdl/src/video/android/SDL_androidwindow.h b/Engine/lib/sdl/src/video/android/SDL_androidwindow.h index e78d5068e..58e459006 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidwindow.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidwindow.h @@ -30,6 +30,7 @@ extern int Android_CreateWindow(_THIS, SDL_Window *window); extern void Android_SetWindowTitle(_THIS, SDL_Window *window); extern void Android_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen); extern void Android_MinimizeWindow(_THIS, SDL_Window *window); +extern void Android_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable); extern void Android_DestroyWindow(_THIS, SDL_Window *window); extern SDL_bool Android_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info); diff --git a/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.c b/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.c index aafed848d..a7fb1aac2 100644 --- a/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.c +++ b/Engine/lib/sdl/src/video/dummy/SDL_nullvideo.c @@ -46,6 +46,7 @@ #include "SDL_nullvideo.h" #include "SDL_nullevents_c.h" #include "SDL_nullframebuffer_c.h" +#include "SDL_hints.h" #define DUMMYVID_DRIVER_NAME "dummy" @@ -59,7 +60,7 @@ static void DUMMY_VideoQuit(_THIS); static int DUMMY_Available(void) { - const char *envr = SDL_getenv("SDL_VIDEODRIVER"); + const char *envr = SDL_GetHint(SDL_HINT_VIDEODRIVER); if ((envr) && (SDL_strcmp(envr, DUMMYVID_DRIVER_NAME) == 0)) { return (1); } diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c index d4e9cb8e8..372c6f5ac 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c @@ -26,6 +26,8 @@ #include "SDL_emscriptenframebuffer.h" #include "SDL_hints.h" +#include + int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) { @@ -57,18 +59,9 @@ int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * form return 0; } -int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +static void +Emscripten_UpdateWindowFramebufferWorker(SDL_Surface* surface) { - SDL_Surface *surface; - - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - surface = data->surface; - if (!surface) { - return SDL_SetError("Couldn't find framebuffer surface for window"); - } - - /* Send the data to the display */ - EM_ASM_INT({ var w = $0; var h = $1; @@ -156,6 +149,29 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec SDL2.ctx.putImageData(SDL2.image, 0, 0); return 0; }, surface->w, surface->h, surface->pixels); +} + +int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +{ + SDL_Surface *surface; + + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + surface = data->surface; + if (!surface) { + return SDL_SetError("Couldn't find framebuffer surface for window"); + } + + /* Send the data to the display */ + + if (emscripten_is_main_runtime_thread()) { + Emscripten_UpdateWindowFramebufferWorker(surface); + } else { + emscripten_sync_run_in_main_runtime_thread( + EM_FUNC_SIG_VI, + Emscripten_UpdateWindowFramebufferWorker, + (uint32_t)surface + ); + } if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) { /* give back control to browser for screen refresh */ diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c index e73072590..e41480725 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c @@ -24,6 +24,7 @@ #include #include +#include #include "SDL_emscriptenmouse.h" #include "SDL_emscriptenvideo.h" @@ -62,19 +63,10 @@ Emscripten_CreateDefaultCursor() return Emscripten_CreateCursorFromString("default", SDL_FALSE); } -static SDL_Cursor* -Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y) +static const char* +Emscripten_GetCursorUrl(int w, int h, int hot_x, int hot_y, void* pixels) { - const char *cursor_url = NULL; - SDL_Surface *conv_surf; - - conv_surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0); - - if (!conv_surf) { - return NULL; - } - - cursor_url = (const char *)EM_ASM_INT({ + return (const char *)EM_ASM_INT({ var w = $0; var h = $1; var hot_x = $2; @@ -122,7 +114,40 @@ Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y) stringToUTF8(url, urlBuf, url.length + 1); return urlBuf; - }, surface->w, surface->h, hot_x, hot_y, conv_surf->pixels); + }, w, h, hot_x, hot_y, pixels); +} + +static SDL_Cursor* +Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y) +{ + const char *cursor_url = NULL; + SDL_Surface *conv_surf; + + conv_surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0); + + if (!conv_surf) { + return NULL; + } + + if (emscripten_is_main_runtime_thread()) { + cursor_url = Emscripten_GetCursorUrl( + surface->w, + surface->h, + hot_x, + hot_y, + conv_surf->pixels + ); + } else { + cursor_url = (const char *)emscripten_sync_run_in_main_runtime_thread( + EM_FUNC_SIG_IIIIIII, + Emscripten_GetCursorUrl, + surface->w, + surface->h, + hot_x, + hot_y, + conv_surf->pixels + ); + } SDL_FreeSurface(conv_surf); @@ -206,16 +231,15 @@ Emscripten_ShowCursor(SDL_Cursor* cursor) curdata = (Emscripten_CursorData *) cursor->driverdata; if(curdata->system_cursor) { - EM_ASM_INT({ + MAIN_THREAD_EM_ASM({ if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } - return 0; }, curdata->system_cursor); } } else { - EM_ASM( + MAIN_THREAD_EM_ASM( if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; } diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c index f6ee1e7e5..4c6038f09 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c @@ -174,10 +174,10 @@ Emscripten_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * if (rect) { rect->x = 0; rect->y = 0; - rect->w = EM_ASM_INT_V({ + rect->w = MAIN_THREAD_EM_ASM_INT({ return window.innerWidth; }); - rect->h = EM_ASM_INT_V({ + rect->h = MAIN_THREAD_EM_ASM_INT({ return window.innerHeight; }); } diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.m index fdc20c086..b6d56f350 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.m @@ -186,8 +186,8 @@ UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *but #endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */ } -int -UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +static void +UIKit_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid, int *returnValue) { BOOL success = NO; @@ -199,12 +199,26 @@ UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) } if (!success) { - return SDL_SetError("Could not show message box."); + *returnValue = SDL_SetError("Could not show message box."); + } else { + *returnValue = 0; } - - return 0; } +int +UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ @autoreleasepool +{ + __block int returnValue = 0; + + if ([NSThread isMainThread]) { + UIKit_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ UIKit_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); }); + } + return returnValue; +}} + #endif /* SDL_VIDEO_DRIVER_UIKIT */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.c b/Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.c index 992c7af84..1c558486b 100644 --- a/Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.c +++ b/Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.c @@ -31,7 +31,7 @@ #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) #define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8 -void *vita_gpu_alloc(SceKernelMemBlockType type, unsigned int size, SceUID *uid) +void *vita_gpu_alloc(unsigned int type, unsigned int size, SceUID *uid) { void *mem; diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr.c b/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr.c index 3b7fb7477..d51150c03 100644 --- a/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr.c +++ b/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr.c @@ -20,11 +20,12 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR +#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR && SDL_VIDEO_VITA_PVR_OGL #include #include #include #include +#include #include "SDL_error.h" #include "SDL_log.h" @@ -34,6 +35,16 @@ #define MAX_PATH 256 // vita limits are somehow wrong +/* Defaults */ +int FB_WIDTH = 960; +int FB_HEIGHT = 544; + +void getFBSize(int *width, int *height) +{ + *width = FB_WIDTH; + *height = FB_HEIGHT; +} + int VITA_GL_LoadLibrary(_THIS, const char *path) { @@ -53,6 +64,9 @@ VITA_GL_LoadLibrary(_THIS, const char *path) sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL); sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL); + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx"); sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); @@ -74,30 +88,45 @@ VITA_GL_LoadLibrary(_THIS, const char *path) SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window) { - return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); -} + char gl_version[3]; + SDL_GLContext context = NULL; + int temp_major = _this->gl_config.major_version; + int temp_minor = _this->gl_config.minor_version; + int temp_profile = _this->gl_config.profile_mask; -int -VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) -{ - if (window && context) { - return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context); - } else { - return SDL_EGL_MakeCurrent(_this, NULL, NULL); + /* Set version to 2.0 and PROFILE to ES */ + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 0; + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; + + context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); + + if (context != NULL) + { + FB_WIDTH = window->w; + FB_HEIGHT = window->h; + set_getprocaddress((void *(*)(const char *))eglGetProcAddress); + set_getmainfbsize(getFBSize); + SDL_snprintf(gl_version, 3, "%d%d", temp_major, temp_minor); + gl4es_setenv("LIBGL_NOTEXRECT", "1", 1); /* Currently broken in driver */ + gl4es_setenv("LIBGL_GL", gl_version, 1); + initialize_gl4es(); } + + /* Restore gl_config */ + _this->gl_config.major_version = temp_major; + _this->gl_config.minor_version = temp_minor; + _this->gl_config.profile_mask = temp_profile; + + return context; } -int -VITA_GL_SwapWindow(_THIS, SDL_Window * window) +void * +VITA_GL_GetProcAddress(_THIS, const char *proc) { - SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; - if (videodata->ime_active) { - sceImeUpdate(); - } - return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); + return gl4es_GetProcAddress(proc); } - #endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h b/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h index 670eaebb0..2329d472b 100644 --- a/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h +++ b/Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h @@ -19,17 +19,16 @@ 3. This notice may not be removed or altered from any source distribution. */ -#ifndef SDL_vitagl_c_h_ -#define SDL_vitagl_c_h_ +#ifndef SDL_vitagl_pvr_c_h_ +#define SDL_vitagl_pvr_c_h_ #include "SDL_vitavideo.h" -extern int VITA_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context); -extern int VITA_GL_SwapWindow(_THIS, SDL_Window * window); extern SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window); extern int VITA_GL_LoadLibrary(_THIS, const char *path); +extern void *VITA_GL_GetProcAddress(_THIS, const char *proc); -#endif /* SDL_vitagl_c_h_ */ +#endif /* SDL_vitagl_pvr_c_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitagl.c b/Engine/lib/sdl/src/video/vita/SDL_vitagles.c similarity index 91% rename from Engine/lib/sdl/src/video/vita/SDL_vitagl.c rename to Engine/lib/sdl/src/video/vita/SDL_vitagles.c index f65022865..18ca7d57b 100644 --- a/Engine/lib/sdl/src/video/vita/SDL_vitagl.c +++ b/Engine/lib/sdl/src/video/vita/SDL_vitagles.c @@ -27,7 +27,7 @@ #include "SDL_error.h" #include "SDL_log.h" #include "SDL_vitavideo.h" -#include "SDL_vitagl_c.h" +#include "SDL_vitagles_c.h" /*****************************************************************************/ /* SDL OpenGL/OpenGL ES functions */ @@ -45,7 +45,7 @@ } while (0) void -VITA_GL_KeyboardCallback(ScePigletPreSwapData *data) +VITA_GLES_KeyboardCallback(ScePigletPreSwapData *data) { SceCommonDialogUpdateParam commonDialogParam; SDL_zero(commonDialogParam); @@ -62,20 +62,20 @@ VITA_GL_KeyboardCallback(ScePigletPreSwapData *data) } int -VITA_GL_LoadLibrary(_THIS, const char *path) +VITA_GLES_LoadLibrary(_THIS, const char *path) { pibInit(PIB_SHACCCG | PIB_GET_PROC_ADDR_CORE); return 0; } void * -VITA_GL_GetProcAddress(_THIS, const char *proc) +VITA_GLES_GetProcAddress(_THIS, const char *proc) { return eglGetProcAddress(proc); } void -VITA_GL_UnloadLibrary(_THIS) +VITA_GLES_UnloadLibrary(_THIS) { eglTerminate(_this->gl_data->display); } @@ -84,7 +84,7 @@ static EGLint width = 960; static EGLint height = 544; SDL_GLContext -VITA_GL_CreateContext(_THIS, SDL_Window * window) +VITA_GLES_CreateContext(_THIS, SDL_Window * window) { SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata; @@ -159,13 +159,13 @@ VITA_GL_CreateContext(_THIS, SDL_Window * window) _this->gl_data->surface = surface; preSwapCallback = (PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC) eglGetProcAddress("eglPigletVitaSetPreSwapCallbackSCE"); - preSwapCallback(VITA_GL_KeyboardCallback); + preSwapCallback(VITA_GLES_KeyboardCallback); return context; } int -VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +VITA_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) { if (!eglMakeCurrent(_this->gl_data->display, _this->gl_data->surface, _this->gl_data->surface, _this->gl_data->context)) @@ -176,7 +176,7 @@ VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) } int -VITA_GL_SetSwapInterval(_THIS, int interval) +VITA_GLES_SetSwapInterval(_THIS, int interval) { EGLBoolean status; status = eglSwapInterval(_this->gl_data->display, interval); @@ -190,13 +190,13 @@ VITA_GL_SetSwapInterval(_THIS, int interval) } int -VITA_GL_GetSwapInterval(_THIS) +VITA_GLES_GetSwapInterval(_THIS) { return _this->gl_data->swapinterval; } int -VITA_GL_SwapWindow(_THIS, SDL_Window * window) +VITA_GLES_SwapWindow(_THIS, SDL_Window * window) { if (!eglSwapBuffers(_this->gl_data->display, _this->gl_data->surface)) { return SDL_SetError("eglSwapBuffers() failed"); @@ -205,7 +205,7 @@ VITA_GL_SwapWindow(_THIS, SDL_Window * window) } void -VITA_GL_DeleteContext(_THIS, SDL_GLContext context) +VITA_GLES_DeleteContext(_THIS, SDL_GLContext context) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; EGLBoolean status; diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitagl_c.h b/Engine/lib/sdl/src/video/vita/SDL_vitagles_c.h similarity index 67% rename from Engine/lib/sdl/src/video/vita/SDL_vitagl_c.h rename to Engine/lib/sdl/src/video/vita/SDL_vitagles_c.h index 272653d70..10fd8533a 100644 --- a/Engine/lib/sdl/src/video/vita/SDL_vitagl_c.h +++ b/Engine/lib/sdl/src/video/vita/SDL_vitagles_c.h @@ -19,8 +19,8 @@ 3. This notice may not be removed or altered from any source distribution. */ -#ifndef SDL_vitagl_c_h_ -#define SDL_vitagl_c_h_ +#ifndef SDL_vitagles_c_h_ +#define SDL_vitagles_c_h_ #include @@ -39,19 +39,19 @@ typedef struct SDL_GLDriverData { uint32_t swapinterval; }SDL_GLDriverData; -extern void * VITA_GL_GetProcAddress(_THIS, const char *proc); -extern int VITA_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context); -extern void VITA_GL_SwapBuffers(_THIS); +extern void * VITA_GLES_GetProcAddress(_THIS, const char *proc); +extern int VITA_GLES_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context); +extern void VITA_GLES_SwapBuffers(_THIS); -extern int VITA_GL_SwapWindow(_THIS, SDL_Window * window); -extern SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window); +extern int VITA_GLES_SwapWindow(_THIS, SDL_Window * window); +extern SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window * window); -extern int VITA_GL_LoadLibrary(_THIS, const char *path); -extern void VITA_GL_UnloadLibrary(_THIS); -extern int VITA_GL_SetSwapInterval(_THIS, int interval); -extern int VITA_GL_GetSwapInterval(_THIS); +extern int VITA_GLES_LoadLibrary(_THIS, const char *path); +extern void VITA_GLES_UnloadLibrary(_THIS); +extern int VITA_GLES_SetSwapInterval(_THIS, int interval); +extern int VITA_GLES_GetSwapInterval(_THIS); -#endif /* SDL_vitagl_c_h_ */ +#endif /* SDL_vitagles_c_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitagles_pvr.c b/Engine/lib/sdl/src/video/vita/SDL_vitagles_pvr.c new file mode 100644 index 000000000..bb06d2946 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitagles_pvr.c @@ -0,0 +1,103 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR +#include +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "../SDL_egl_c.h" +#include "SDL_vitagles_pvr_c.h" + +#define MAX_PATH 256 // vita limits are somehow wrong + +int +VITA_GLES_LoadLibrary(_THIS, const char *path) +{ + PVRSRV_PSP2_APPHINT hint; + char* override = SDL_getenv("VITA_MODULE_PATH"); + char* skip_init = SDL_getenv("VITA_PVR_SKIP_INIT"); + char* default_path = "app0:module"; + char target_path[MAX_PATH]; + + if (skip_init == NULL) // we don't care about actual value + { + if (override != NULL) + { + default_path = override; + } + + sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL); + sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + PVRSRVInitializeAppHint(&hint); + + SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx"); + SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx"); + SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx"); + + PVRSRVCreateVirtualAppHint(&hint); + } + + return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) 0, 0); +} + +SDL_GLContext +VITA_GLES_CreateContext(_THIS, SDL_Window * window) +{ + return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); +} + +int +VITA_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ + if (window && context) { + return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context); + } else { + return SDL_EGL_MakeCurrent(_this, NULL, NULL); + } +} + +int +VITA_GLES_SwapWindow(_THIS, SDL_Window * window) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + if (videodata->ime_active) { + sceImeUpdate(); + } + return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); +} + + +#endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitagles_pvr_c.h b/Engine/lib/sdl/src/video/vita/SDL_vitagles_pvr_c.h new file mode 100644 index 000000000..c3a13c436 --- /dev/null +++ b/Engine/lib/sdl/src/video/vita/SDL_vitagles_pvr_c.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_vitagles_pvr_c_h_ +#define SDL_vitagles_pvr_c_h_ + +#include "SDL_vitavideo.h" + +extern int VITA_GLES_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context); +extern int VITA_GLES_SwapWindow(_THIS, SDL_Window * window); +extern SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window * window); +extern int VITA_GLES_LoadLibrary(_THIS, const char *path); + + +#endif /* SDL_vitagles_pvr_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitavideo.c b/Engine/lib/sdl/src/video/vita/SDL_vitavideo.c index 778a87073..60bd18f45 100644 --- a/Engine/lib/sdl/src/video/vita/SDL_vitavideo.c +++ b/Engine/lib/sdl/src/video/vita/SDL_vitavideo.c @@ -41,15 +41,17 @@ #include "SDL_vitaframebuffer.h" #if defined(SDL_VIDEO_VITA_PIB) - #include "SDL_vitagl_c.h" + #include "SDL_vitagles_c.h" #elif defined(SDL_VIDEO_VITA_PVR) + #include "SDL_vitagles_pvr_c.h" +#if defined(SDL_VIDEO_VITA_PVR_OGL) #include "SDL_vitagl_pvr_c.h" - #include "../SDL_egl_c.h" - #define VITA_GL_GetProcAddress SDL_EGL_GetProcAddress - #define VITA_GL_UnloadLibrary SDL_EGL_UnloadLibrary - #define VITA_GL_SetSwapInterval SDL_EGL_SetSwapInterval - #define VITA_GL_GetSwapInterval SDL_EGL_GetSwapInterval - #define VITA_GL_DeleteContext SDL_EGL_DeleteContext +#endif + #define VITA_GLES_GetProcAddress SDL_EGL_GetProcAddress + #define VITA_GLES_UnloadLibrary SDL_EGL_UnloadLibrary + #define VITA_GLES_SetSwapInterval SDL_EGL_SetSwapInterval + #define VITA_GLES_GetSwapInterval SDL_EGL_GetSwapInterval + #define VITA_GLES_DeleteContext SDL_EGL_DeleteContext #endif SDL_Window *Vita_Window; @@ -140,15 +142,26 @@ VITA_Create() */ #if defined(SDL_VIDEO_VITA_PIB) || defined(SDL_VIDEO_VITA_PVR) +#if defined(SDL_VIDEO_VITA_PVR_OGL) +if(SDL_getenv("VITA_PVR_OGL") != NULL) { device->GL_LoadLibrary = VITA_GL_LoadLibrary; - device->GL_GetProcAddress = VITA_GL_GetProcAddress; - device->GL_UnloadLibrary = VITA_GL_UnloadLibrary; device->GL_CreateContext = VITA_GL_CreateContext; - device->GL_MakeCurrent = VITA_GL_MakeCurrent; - device->GL_SetSwapInterval = VITA_GL_SetSwapInterval; - device->GL_GetSwapInterval = VITA_GL_GetSwapInterval; - device->GL_SwapWindow = VITA_GL_SwapWindow; - device->GL_DeleteContext = VITA_GL_DeleteContext; + device->GL_GetProcAddress = VITA_GL_GetProcAddress; +} else { +#endif + device->GL_LoadLibrary = VITA_GLES_LoadLibrary; + device->GL_CreateContext = VITA_GLES_CreateContext; + device->GL_GetProcAddress = VITA_GLES_GetProcAddress; +#if defined(SDL_VIDEO_VITA_PVR_OGL) +} +#endif + + device->GL_UnloadLibrary = VITA_GLES_UnloadLibrary; + device->GL_MakeCurrent = VITA_GLES_MakeCurrent; + device->GL_SetSwapInterval = VITA_GLES_SetSwapInterval; + device->GL_GetSwapInterval = VITA_GLES_GetSwapInterval; + device->GL_SwapWindow = VITA_GLES_SwapWindow; + device->GL_DeleteContext = VITA_GLES_DeleteContext; #endif device->HasScreenKeyboardSupport = VITA_HasScreenKeyboardSupport; @@ -245,6 +258,9 @@ VITA_CreateWindow(_THIS, SDL_Window * window) SDL_WindowData *wdata; #if defined(SDL_VIDEO_VITA_PVR) Psp2NativeWindow win; + int temp_major = 2; + int temp_minor = 1; + int temp_profile = 0; #endif /* Allocate window internal data */ @@ -282,11 +298,26 @@ VITA_CreateWindow(_THIS, SDL_Window * window) win.windowSize = PSP2_WINDOW_960X544; } if ((window->flags & SDL_WINDOW_OPENGL) != 0) { - wdata->egl_surface = SDL_EGL_CreateSurface(_this, &win); + if(SDL_getenv("VITA_PVR_OGL") != NULL) { + /* Set version to 2.1 and PROFILE to ES */ + temp_major = _this->gl_config.major_version; + temp_minor = _this->gl_config.minor_version; + temp_profile = _this->gl_config.profile_mask; + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 1; + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; + } + wdata->egl_surface = SDL_EGL_CreateSurface(_this, &win); if (wdata->egl_surface == EGL_NO_SURFACE) { return SDL_SetError("Could not create GLES window surface"); } + if(SDL_getenv("VITA_PVR_OGL") != NULL) { + /* Revert */ + _this->gl_config.major_version = temp_major; + _this->gl_config.minor_version = temp_minor; + _this->gl_config.profile_mask = temp_profile; + } } #endif diff --git a/Engine/lib/sdl/src/video/vita/SDL_vitavideo.h b/Engine/lib/sdl/src/video/vita/SDL_vitavideo.h index 04488dde3..9fdf7e69c 100644 --- a/Engine/lib/sdl/src/video/vita/SDL_vitavideo.h +++ b/Engine/lib/sdl/src/video/vita/SDL_vitavideo.h @@ -90,16 +90,23 @@ SDL_bool VITA_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); #if SDL_VIDEO_DRIVER_VITA +#if defined(SDL_VIDEO_VITA_PVR_OGL) /* OpenGL functions */ int VITA_GL_LoadLibrary(_THIS, const char *path); -void *VITA_GL_GetProcAddress(_THIS, const char *proc); -void VITA_GL_UnloadLibrary(_THIS); SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window); -int VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); -int VITA_GL_SetSwapInterval(_THIS, int interval); -int VITA_GL_GetSwapInterval(_THIS); -int VITA_GL_SwapWindow(_THIS, SDL_Window * window); -void VITA_GL_DeleteContext(_THIS, SDL_GLContext context); +void *VITA_GL_GetProcAddress(_THIS, const char *proc); +#endif + +/* OpenGLES functions */ +int VITA_GLES_LoadLibrary(_THIS, const char *path); +void *VITA_GLES_GetProcAddress(_THIS, const char *proc); +void VITA_GLES_UnloadLibrary(_THIS); +SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window * window); +int VITA_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +int VITA_GLES_SetSwapInterval(_THIS, int interval); +int VITA_GLES_GetSwapInterval(_THIS); +int VITA_GLES_SwapWindow(_THIS, SDL_Window * window); +void VITA_GLES_DeleteContext(_THIS, SDL_GLContext context); #endif /* VITA on screen keyboard */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h b/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h index c867ec001..3d8d973cc 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h @@ -52,6 +52,14 @@ enum libdecor_window_state; #include "xkbcommon/xkbcommon.h" #include "xkbcommon/xkbcommon-compose.h" +/* Must be included before our #defines, see Bugzilla #4957 */ +#include "wayland-client-core.h" + +#define SDL_WAYLAND_CHECK_VERSION(x, y, z) \ + (WAYLAND_VERSION_MAJOR > x || \ + (WAYLAND_VERSION_MAJOR == x && WAYLAND_VERSION_MINOR > y) || \ + (WAYLAND_VERSION_MAJOR == x && WAYLAND_VERSION_MINOR == y && WAYLAND_VERSION_MICRO >= z)) + #ifdef __cplusplus extern "C" { @@ -71,9 +79,6 @@ void SDL_WAYLAND_UnloadSymbols(void); } #endif -/* Must be included before our #defines, see Bugzilla #4957 */ -#include "wayland-client-core.h" - #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC #if defined(_WAYLAND_CLIENT_H) || defined(WAYLAND_CLIENT_H) diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c index 55893201b..e515d9d6f 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c @@ -40,6 +40,7 @@ #include "xdg-shell-client-protocol.h" #include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h" #include "text-input-unstable-v3-client-protocol.h" +#include "tablet-unstable-v2-client-protocol.h" #ifdef HAVE_LIBDECOR_H #include @@ -83,6 +84,7 @@ static const struct { { XKB_KEY_Super_R, SDLK_RGUI }, { XKB_KEY_Hyper_L, SDLK_LGUI }, { XKB_KEY_Hyper_R, SDLK_RGUI }, + { XKB_KEY_BackSpace, SDLK_BACKSPACE }, }; struct SDL_WaylandTouchPoint { @@ -387,8 +389,10 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer, input->sx_w = sx_w; input->sy_w = sy_w; if (input->pointer_focus) { - const int sx = wl_fixed_to_int(sx_w); - const int sy = wl_fixed_to_int(sy_w); + const float sx_f = (float)wl_fixed_to_double(sx_w); + const float sy_f = (float)wl_fixed_to_double(sy_w); + const int sx = (int)SDL_floorf(sx_f * window->pointer_scale_x); + const int sy = (int)SDL_floorf(sy_f * window->pointer_scale_y); SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy); } } @@ -472,6 +476,9 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial) const uint32_t *directions_libdecor = directions; #endif + /* Hit tests shouldn't apply to xdg_popups, right? */ + SDL_assert(!WINDOW_IS_XDG_POPUP(window)); + switch (rc) { case SDL_HITTEST_DRAGGABLE: #ifdef HAVE_LIBDECOR_H @@ -715,8 +722,8 @@ touch_handler_down(void *data, struct wl_touch *touch, unsigned int serial, int id, wl_fixed_t fx, wl_fixed_t fy) { SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(surface); - const double dblx = wl_fixed_to_double(fx); - const double dbly = wl_fixed_to_double(fy); + const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x; + const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y; const float x = dblx / window_data->sdlwindow->w; const float y = dbly / window_data->sdlwindow->h; @@ -748,8 +755,8 @@ touch_handler_motion(void *data, struct wl_touch *touch, unsigned int timestamp, int id, wl_fixed_t fx, wl_fixed_t fy) { SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(touch_surface(id)); - const double dblx = wl_fixed_to_double(fx); - const double dbly = wl_fixed_to_double(fy); + const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x; + const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y; const float x = dblx / window_data->sdlwindow->w; const float y = dbly / window_data->sdlwindow->h; @@ -815,6 +822,16 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, return; } + #define GET_MOD_INDEX(mod) \ + WAYLAND_xkb_keymap_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_##mod) + input->xkb.idx_shift = 1 << GET_MOD_INDEX(SHIFT); + input->xkb.idx_ctrl = 1 << GET_MOD_INDEX(CTRL); + input->xkb.idx_alt = 1 << GET_MOD_INDEX(ALT); + input->xkb.idx_gui = 1 << GET_MOD_INDEX(LOGO); + input->xkb.idx_num = 1 << GET_MOD_INDEX(NUM); + input->xkb.idx_caps = 1 << GET_MOD_INDEX(CAPS); + #undef GET_MOD_INDEX + input->xkb.state = WAYLAND_xkb_state_new(input->xkb.keymap); if (!input->xkb.state) { fprintf(stderr, "failed to create XKB state\n"); @@ -829,10 +846,14 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, */ /* Look up the preferred locale, falling back to "C" as default */ - if (!(locale = SDL_getenv("LC_ALL"))) - if (!(locale = SDL_getenv("LC_CTYPE"))) - if (!(locale = SDL_getenv("LANG"))) + if (!(locale = SDL_getenv("LC_ALL"))) { + if (!(locale = SDL_getenv("LC_CTYPE"))) { + if (!(locale = SDL_getenv("LANG"))) { locale = "C"; + } + } + } + /* Set up XKB compose table */ input->xkb.compose_table = WAYLAND_xkb_compose_table_new_from_locale(input->display->xkb_context, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); @@ -903,7 +924,7 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, } static SDL_bool -keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint32_t key, SDL_bool *handled_by_ime) +keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint32_t key, Uint8 state, SDL_bool *handled_by_ime) { SDL_WindowData *window = input->keyboard_focus; const xkb_keysym_t *syms; @@ -920,12 +941,16 @@ keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint sym = syms[0]; #ifdef SDL_USE_IME - if (SDL_IME_ProcessKeyEvent(sym, key + 8)) { + if (SDL_IME_ProcessKeyEvent(sym, key + 8, state)) { *handled_by_ime = SDL_TRUE; return SDL_TRUE; } #endif + if (state == SDL_RELEASED) { + return SDL_FALSE; + } + if (input->xkb.compose_state && WAYLAND_xkb_compose_state_feed(input->xkb.compose_state, sym) == XKB_COMPOSE_FEED_ACCEPTED) { switch(WAYLAND_xkb_compose_state_get_status(input->xkb.compose_state)) { case XKB_COMPOSE_COMPOSING: @@ -959,7 +984,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, SDL_bool handled_by_ime = SDL_FALSE; if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { - has_text = keyboard_input_get_text(text, input, key, &handled_by_ime); + has_text = keyboard_input_get_text(text, input, key, SDL_PRESSED, &handled_by_ime); } else { if (keyboard_repeat_is_set(&input->keyboard_repeat)) { // Send any due key repeat events before stopping the repeat and generating the key up event @@ -969,6 +994,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, keyboard_repeat_handle(&input->keyboard_repeat, time - input->keyboard_repeat.wl_press_time); keyboard_repeat_clear(&input->keyboard_repeat); } + keyboard_input_get_text(text, input, key, SDL_RELEASED, &handled_by_ime); } if (!handled_by_ime && key < SDL_arraysize(xfree86_scancode_table2)) { @@ -1054,10 +1080,24 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, { struct SDL_WaylandInput *input = data; Wayland_Keymap keymap; + uint32_t modstate = (mods_depressed | mods_latched | mods_locked); WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched, mods_locked, 0, 0, group); + SDL_ToggleModState(KMOD_SHIFT, modstate & input->xkb.idx_shift); + SDL_ToggleModState(KMOD_CTRL, modstate & input->xkb.idx_ctrl); + SDL_ToggleModState(KMOD_ALT, modstate & input->xkb.idx_alt); + SDL_ToggleModState(KMOD_GUI, modstate & input->xkb.idx_gui); + SDL_ToggleModState(KMOD_NUM, modstate & input->xkb.idx_num); + SDL_ToggleModState(KMOD_CAPS, modstate & input->xkb.idx_caps); + + if (group == input->xkb.current_group) { + return; + } + + /* The layout changed, remap and fire an event */ + input->xkb.current_group = group; keymap.layout = group; SDL_GetDefaultKeymap(keymap.keymap); WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap, @@ -1646,6 +1686,363 @@ Wayland_add_text_input_manager(SDL_VideoData *d, uint32_t id, uint32_t version) } } +static void +tablet_tool_handle_type(void* data, struct zwp_tablet_tool_v2* tool, uint32_t type) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_hardware_serial(void* data, struct zwp_tablet_tool_v2* tool, uint32_t serial_hi, uint32_t serial_lo) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_hardware_id_wacom(void* data, struct zwp_tablet_tool_v2* tool, uint32_t id_hi, uint32_t id_lo) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_capability(void* data, struct zwp_tablet_tool_v2* tool, uint32_t capability) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_done(void* data, struct zwp_tablet_tool_v2* tool) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_removed(void* data, struct zwp_tablet_tool_v2* tool) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_proximity_in(void* data, struct zwp_tablet_tool_v2* tool, uint32_t serial, struct zwp_tablet_v2* tablet, struct wl_surface* surface) +{ + struct SDL_WaylandTabletInput* input = data; + SDL_WindowData* window; + + if (!surface) { + return; + } + + if (!SDL_WAYLAND_own_surface(surface)) { + return; + } + + window = (SDL_WindowData*)wl_surface_get_user_data(surface); + + if (window) { + input->tool_focus = window; + input->tool_prox_serial = serial; + + input->is_down = SDL_FALSE; + + input->btn_stylus = SDL_FALSE; + input->btn_stylus2 = SDL_FALSE; + input->btn_stylus3 = SDL_FALSE; + + SDL_SetMouseFocus(window->sdlwindow); + SDL_SetCursor(NULL); + } +} + +static void +tablet_tool_handle_proximity_out(void* data, struct zwp_tablet_tool_v2* tool) +{ + struct SDL_WaylandTabletInput* input = data; + + if (input->tool_focus) { + SDL_SetMouseFocus(NULL); + input->tool_focus = NULL; + } +} + +uint32_t +tablet_tool_btn_to_sdl_button(struct SDL_WaylandTabletInput* input) +{ + unsigned int tool_btn = input->btn_stylus3 << 2 | input->btn_stylus2 << 1 | input->btn_stylus << 0; + switch (tool_btn) { + case 0b000: + return SDL_BUTTON_LEFT; + case 0b001: + return SDL_BUTTON_RIGHT; + case 0b010: + return SDL_BUTTON_MIDDLE; + case 0b100: + return SDL_BUTTON_X1; + default: + return SDL_BUTTON_LEFT; + } +} + +static void +tablet_tool_handle_down(void* data, struct zwp_tablet_tool_v2* tool, uint32_t serial) +{ + struct SDL_WaylandTabletInput* input = data; + SDL_WindowData* window = input->tool_focus; + input->is_down = SDL_TRUE; + if (!window) { + /* tablet_tool_handle_proximity_out gets called when moving over the libdecoration csd. + * that sets input->tool_focus (window) to NULL, but handle_{down,up} events are still + * received. To prevent SIGSEGV this returns when this is the case. + */ + return; + } + + SDL_SendMouseButton(window->sdlwindow, 0, SDL_PRESSED, tablet_tool_btn_to_sdl_button(input)); +} + +static void +tablet_tool_handle_up(void* data, struct zwp_tablet_tool_v2* tool) +{ + struct SDL_WaylandTabletInput* input = data; + SDL_WindowData* window = input->tool_focus; + + input->is_down = SDL_FALSE; + + if (!window) { + /* tablet_tool_handle_proximity_out gets called when moving over the libdecoration csd. + * that sets input->tool_focus (window) to NULL, but handle_{down,up} events are still + * received. To prevent SIGSEGV this returns when this is the case. + */ + return; + } + + SDL_SendMouseButton(window->sdlwindow, 0, SDL_RELEASED, tablet_tool_btn_to_sdl_button(input)); +} + +static void +tablet_tool_handle_motion(void* data, struct zwp_tablet_tool_v2* tool, wl_fixed_t sx_w, wl_fixed_t sy_w) +{ + struct SDL_WaylandTabletInput* input = data; + SDL_WindowData* window = input->tool_focus; + + input->sx_w = sx_w; + input->sy_w = sy_w; + if (input->tool_focus) { + const float sx_f = (float)wl_fixed_to_double(sx_w); + const float sy_f = (float)wl_fixed_to_double(sy_w); + const int sx = (int)SDL_floorf(sx_f * window->pointer_scale_x); + const int sy = (int)SDL_floorf(sy_f * window->pointer_scale_y); + SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy); + } +} + +static void +tablet_tool_handle_pressure(void* data, struct zwp_tablet_tool_v2* tool, uint32_t pressure) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_distance(void* data, struct zwp_tablet_tool_v2* tool, uint32_t distance) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_tilt(void* data, struct zwp_tablet_tool_v2* tool, wl_fixed_t xtilt, wl_fixed_t ytilt) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_button(void* data, struct zwp_tablet_tool_v2* tool, uint32_t serial, uint32_t button, uint32_t state) +{ + struct SDL_WaylandTabletInput* input = data; + + if (input->is_down) { + tablet_tool_handle_up(data, tool); + input->is_down = SDL_TRUE; + } + + switch (button) { + /* see %{_includedir}/linux/input-event-codes.h */ + case 0x14b: /* BTN_STYLUS */ + input->btn_stylus = state == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED ? SDL_TRUE : SDL_FALSE; + break; + case 0x14c: /* BTN_STYLUS2 */ + input->btn_stylus2 = state == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED ? SDL_TRUE : SDL_FALSE; + break; + case 0x149: /* BTN_STYLUS3 */ + input->btn_stylus3 = state == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED ? SDL_TRUE : SDL_FALSE; + break; + } + + if (input->is_down) { + tablet_tool_handle_down(data, tool, serial); + } +} + +static void +tablet_tool_handle_rotation(void* data, struct zwp_tablet_tool_v2* tool, wl_fixed_t degrees) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_slider(void* data, struct zwp_tablet_tool_v2* tool, int32_t position) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_wheel(void* data, struct zwp_tablet_tool_v2* tool, int32_t degrees, int32_t clicks) +{ + /* unimplemented */ +} + +static void +tablet_tool_handle_frame(void* data, struct zwp_tablet_tool_v2* tool, uint32_t time) +{ + /* unimplemented */ +} + + +static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = { + tablet_tool_handle_type, + tablet_tool_handle_hardware_serial, + tablet_tool_handle_hardware_id_wacom, + tablet_tool_handle_capability, + tablet_tool_handle_done, + tablet_tool_handle_removed, + tablet_tool_handle_proximity_in, + tablet_tool_handle_proximity_out, + tablet_tool_handle_down, + tablet_tool_handle_up, + tablet_tool_handle_motion, + tablet_tool_handle_pressure, + tablet_tool_handle_distance, + tablet_tool_handle_tilt, + tablet_tool_handle_rotation, + tablet_tool_handle_slider, + tablet_tool_handle_wheel, + tablet_tool_handle_button, + tablet_tool_handle_frame +}; + +struct SDL_WaylandTabletObjectListNode* +tablet_object_list_new_node(void* object) +{ + struct SDL_WaylandTabletObjectListNode* node; + + node = SDL_calloc(1, sizeof *node); + if (node == NULL) { + return NULL; + } + + node->next = NULL; + node->object = object; + + return node; +} + +void tablet_object_list_append(struct SDL_WaylandTabletObjectListNode* head, void* object) +{ + if (head->object == NULL) { + head->object = object; + return; + } + + while (head->next) { + head = head->next; + } + + head->next = tablet_object_list_new_node(object); +} + +void tablet_object_list_destroy(struct SDL_WaylandTabletObjectListNode* head, void (*deleter)(void* object)) +{ + while (head) { + struct SDL_WaylandTabletObjectListNode* next = head->next; + if (head->object) { + (*deleter)(head->object); + } + SDL_free(head); + head = next; + } +} + + +static void +tablet_seat_handle_tablet_added(void* data, struct zwp_tablet_seat_v2* seat, struct zwp_tablet_v2* tablet) +{ + struct SDL_WaylandTabletInput* input = data; + + tablet_object_list_append(input->tablets, tablet); +} + +static void +tablet_seat_handle_tool_added(void* data, struct zwp_tablet_seat_v2* seat, struct zwp_tablet_tool_v2* tool) +{ + struct SDL_WaylandTabletInput* input = data; + + zwp_tablet_tool_v2_add_listener(tool, &tablet_tool_listener, data); + zwp_tablet_tool_v2_set_user_data(tool, data); + + tablet_object_list_append(input->tools, tool); +} + +static void +tablet_seat_handle_pad_added(void* data, struct zwp_tablet_seat_v2* seat, struct zwp_tablet_pad_v2* pad) +{ + struct SDL_WaylandTabletInput* input = data; + + tablet_object_list_append(input->pads, pad); +} + +static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = { + tablet_seat_handle_tablet_added, + tablet_seat_handle_tool_added, + tablet_seat_handle_pad_added +}; + +void +Wayland_input_add_tablet(struct SDL_WaylandInput *input, struct SDL_WaylandTabletManager* tablet_manager) +{ + struct SDL_WaylandTabletInput* tablet_input; + + if (!tablet_manager || !input || !input->seat) { + return; + } + + tablet_input = SDL_calloc(1, sizeof *tablet_input); + if (tablet_input == NULL) { + return; + } + + input->tablet = tablet_input; + + tablet_input->seat = (struct SDL_WaylandTabletSeat*)zwp_tablet_manager_v2_get_tablet_seat((struct zwp_tablet_manager_v2*)tablet_manager, input->seat); + + tablet_input->tablets = tablet_object_list_new_node(NULL); + tablet_input->tools = tablet_object_list_new_node(NULL); + tablet_input->pads = tablet_object_list_new_node(NULL); + + zwp_tablet_seat_v2_add_listener((struct zwp_tablet_seat_v2*)tablet_input->seat, &tablet_seat_listener, tablet_input); +} + +#define TABLET_OBJECT_LIST_DELETER(fun) (void (*)(void*))fun +void +Wayland_input_destroy_tablet(struct SDL_WaylandInput* input) +{ + tablet_object_list_destroy(input->tablet->pads, TABLET_OBJECT_LIST_DELETER(zwp_tablet_pad_v2_destroy)); + tablet_object_list_destroy(input->tablet->tools, TABLET_OBJECT_LIST_DELETER(zwp_tablet_tool_v2_destroy)); + tablet_object_list_destroy(input->tablet->tablets, TABLET_OBJECT_LIST_DELETER(zwp_tablet_v2_destroy)); + + zwp_tablet_seat_v2_destroy((struct zwp_tablet_seat_v2*)input->tablet->seat); + + SDL_free(input->tablet); + input->tablet = NULL; +} + void Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version) { @@ -1659,6 +2056,7 @@ Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version) input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, SDL_min(5, version)); input->sx_w = wl_fixed_from_int(0); input->sy_w = wl_fixed_from_int(0); + input->xkb.current_group = ~0; d->input = input; if (d->data_device_manager != NULL) { @@ -1671,6 +2069,10 @@ Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version) wl_seat_add_listener(input->seat, &seat_listener, input); wl_seat_set_user_data(input->seat, input); + if (d->tablet_manager) { + Wayland_input_add_tablet(input, d->tablet_manager); + } + WAYLAND_wl_display_flush(d->display); } @@ -1711,6 +2113,10 @@ void Wayland_display_destroy_input(SDL_VideoData *d) wl_touch_destroy(input->touch); } + if (input->tablet) { + Wayland_input_destroy_tablet(input); + } + if (input->seat) wl_seat_destroy(input->seat); @@ -1951,12 +2357,19 @@ int Wayland_input_confine_pointer(struct SDL_WaylandInput *input, SDL_Window *wi if (SDL_RectEmpty(&window->mouse_rect)) { confine_rect = NULL; } else { + SDL_Rect scaled_mouse_rect; + + scaled_mouse_rect.x = (int)SDL_floorf((float)window->mouse_rect.x / w->pointer_scale_x); + scaled_mouse_rect.y = (int)SDL_floorf((float)window->mouse_rect.y / w->pointer_scale_y); + scaled_mouse_rect.w = (int)SDL_ceilf((float)window->mouse_rect.w / w->pointer_scale_x); + scaled_mouse_rect.h = (int)SDL_ceilf((float)window->mouse_rect.h / w->pointer_scale_y); + confine_rect = wl_compositor_create_region(d->compositor); wl_region_add(confine_rect, - window->mouse_rect.x, - window->mouse_rect.y, - window->mouse_rect.w, - window->mouse_rect.h); + scaled_mouse_rect.x, + scaled_mouse_rect.y, + scaled_mouse_rect.w, + scaled_mouse_rect.h); } confined_pointer = diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h index 24256a7d0..59dc0c8af 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h @@ -29,6 +29,34 @@ #include "SDL_waylanddatamanager.h" #include "SDL_waylandkeyboard.h" +struct SDL_WaylandTabletSeat; + +struct SDL_WaylandTabletObjectListNode { + void* object; + struct SDL_WaylandTabletObjectListNode* next; +}; + +struct SDL_WaylandTabletInput { + struct SDL_WaylandTabletSeat* seat; + + struct SDL_WaylandTabletObjectListNode* tablets; + struct SDL_WaylandTabletObjectListNode* tools; + struct SDL_WaylandTabletObjectListNode* pads; + + SDL_WindowData *tool_focus; + uint32_t tool_prox_serial; + + /* Last motion location */ + wl_fixed_t sx_w; + wl_fixed_t sy_w; + + SDL_bool is_down; + + SDL_bool btn_stylus; + SDL_bool btn_stylus2; + SDL_bool btn_stylus3; +}; + typedef struct { // repeat_rate in range of [1, 1000] int32_t repeat_rate; @@ -68,6 +96,17 @@ struct SDL_WaylandInput { struct xkb_state *state; struct xkb_compose_table *compose_table; struct xkb_compose_state *compose_state; + + /* Keyboard layout "group" */ + uint32_t current_group; + + /* Modifier bitshift values */ + uint32_t idx_shift; + uint32_t idx_ctrl; + uint32_t idx_alt; + uint32_t idx_gui; + uint32_t idx_num; + uint32_t idx_caps; } xkb; /* information about axis events on current frame */ @@ -80,6 +119,8 @@ struct SDL_WaylandInput { } pointer_curr_axis_info; SDL_WaylandKeyboardRepeat keyboard_repeat; + + struct SDL_WaylandTabletInput* tablet; }; extern void Wayland_PumpEvents(_THIS); @@ -107,6 +148,9 @@ extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d); extern int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *input); extern int Wayland_input_ungrab_keyboard(SDL_Window *window); +extern void Wayland_input_add_tablet(struct SDL_WaylandInput *input, struct SDL_WaylandTabletManager* tablet_manager); +extern void Wayland_input_destroy_tablet(struct SDL_WaylandInput *input); + #endif /* SDL_waylandevents_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.c index 6b10cbee7..4c834fd86 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandopengles.c @@ -205,11 +205,11 @@ Wayland_GLES_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) data = (SDL_WindowData *) window->driverdata; if (w) { - *w = window->w * data->scale_factor; + *w = data->drawable_width; } if (h) { - *h = window->h * data->scale_factor; + *h = data->drawable_height; } } } diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h index fa29bedb1..6891325c7 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h @@ -72,21 +72,19 @@ SDL_WAYLAND_SYM(void, wl_list_remove, (struct wl_list *)) SDL_WAYLAND_SYM(int, wl_list_length, (const struct wl_list *)) SDL_WAYLAND_SYM(int, wl_list_empty, (const struct wl_list *)) SDL_WAYLAND_SYM(void, wl_list_insert_list, (struct wl_list *, struct wl_list *)) - -/* These functions are available in Wayland >= 1.4 */ -SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_4) SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor, (struct wl_proxy *, uint32_t opcode, const struct wl_interface *interface, ...)) - -SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_10) SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor_versioned, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, ...)) - -SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_18) SDL_WAYLAND_SYM(void, wl_proxy_set_tag, (struct wl_proxy *, const char * const *)) SDL_WAYLAND_SYM(const char * const *, wl_proxy_get_tag, (struct wl_proxy *)) -SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_20) +#if SDL_WAYLAND_CHECK_VERSION(1, 20, 0) +/* wayland-scanner 1.20 generates code that will call these, so these are + * non-optional when we are compiling against Wayland 1.20. We don't + * explicitly call them ourselves, though, so if we are only compiling + * against Wayland 1.18, they're unnecessary. */ SDL_WAYLAND_SYM(struct wl_proxy*, wl_proxy_marshal_flags, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interfac, uint32_t version, uint32_t flags, ...)) SDL_WAYLAND_SYM(struct wl_proxy*, wl_proxy_marshal_array_flags, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, uint32_t flags, union wl_argument *args)) +#endif SDL_WAYLAND_INTERFACE(wl_seat_interface) SDL_WAYLAND_INTERFACE(wl_surface_interface) @@ -149,6 +147,8 @@ SDL_WAYLAND_SYM(int, xkb_keymap_key_get_syms_by_level, (struct xkb_keymap *, xkb_layout_index_t, const xkb_keysym_t **) ) SDL_WAYLAND_SYM(uint32_t, xkb_keysym_to_utf32, (xkb_keysym_t) ) +SDL_WAYLAND_SYM(uint32_t, xkb_keymap_mod_get_index, (struct xkb_keymap *, + const char *) ) #ifdef HAVE_LIBDECOR_H SDL_WAYLAND_MODULE(WAYLAND_LIBDECOR) diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c index 61940cca4..0305c46a1 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c @@ -52,6 +52,9 @@ #include "idle-inhibit-unstable-v1-client-protocol.h" #include "xdg-activation-v1-client-protocol.h" #include "text-input-unstable-v3-client-protocol.h" +#include "tablet-unstable-v2-client-protocol.h" +#include "xdg-output-unstable-v1-client-protocol.h" +#include "viewporter-client-protocol.h" #ifdef HAVE_LIBDECOR_H #include @@ -59,6 +62,9 @@ #define WAYLANDVID_DRIVER_NAME "wayland" +static void +display_handle_done(void *data, struct wl_output *output); + /* Initialization/Query functions */ static int Wayland_VideoInit(_THIS); @@ -133,32 +139,22 @@ static const char *SDL_WAYLAND_output_tag = "sdl-output"; void SDL_WAYLAND_register_surface(struct wl_surface *surface) { - if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { - wl_proxy_set_tag((struct wl_proxy *)surface, &SDL_WAYLAND_surface_tag); - } + wl_proxy_set_tag((struct wl_proxy *)surface, &SDL_WAYLAND_surface_tag); } void SDL_WAYLAND_register_output(struct wl_output *output) { - if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { - wl_proxy_set_tag((struct wl_proxy *)output, &SDL_WAYLAND_output_tag); - } + wl_proxy_set_tag((struct wl_proxy *)output, &SDL_WAYLAND_output_tag); } SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface) { - if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { - return wl_proxy_get_tag((struct wl_proxy *) surface) == &SDL_WAYLAND_surface_tag; - } - return SDL_TRUE; /* For older clients we have to assume this is us... */ + return wl_proxy_get_tag((struct wl_proxy *) surface) == &SDL_WAYLAND_surface_tag; } SDL_bool SDL_WAYLAND_own_output(struct wl_output *output) { - if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) { - return wl_proxy_get_tag((struct wl_proxy *) output) == &SDL_WAYLAND_output_tag; - } - return SDL_TRUE; /* For older clients we have to assume this is us... */ + return wl_proxy_get_tag((struct wl_proxy *) output) == &SDL_WAYLAND_output_tag; } static void @@ -283,6 +279,8 @@ Wayland_CreateDevice(int devindex) device->free = Wayland_DeleteDevice; + device->disable_display_mode_switching = SDL_TRUE; + return device; } @@ -291,6 +289,155 @@ VideoBootStrap Wayland_bootstrap = { Wayland_CreateDevice }; +static void +xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output, + int32_t x, int32_t y) +{ + SDL_WaylandOutputData* driverdata = data; + + driverdata->x = x; + driverdata->y = y; + driverdata->has_logical_position = SDL_TRUE; +} + +static void +xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output, + int32_t width, int32_t height) +{ + SDL_WaylandOutputData* driverdata = data; + + if (driverdata->width != 0 && driverdata->height != 0) { + /* FIXME: GNOME has a bug where the logical size does not account for + * scale, resulting in bogus viewport sizes. + * + * Until this is fixed, validate that _some_ kind of scaling is being + * done (we can't match exactly because fractional scaling can't be + * detected otherwise), then override if necessary. + * -flibit + */ + const float scale = (float) driverdata->width / (float) width; + if ((scale == 1.0f) && (driverdata->scale_factor != 1.0f)) { + SDL_LogWarn( + SDL_LOG_CATEGORY_VIDEO, + "xdg_output scale did not match, overriding with wl_output scale" + ); + return; + } + } + + driverdata->width = width; + driverdata->height = height; + driverdata->has_logical_size = SDL_TRUE; +} + +static void +xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) +{ + SDL_WaylandOutputData* driverdata = data; + + /* + * xdg-output.done events are deprecated and only apply below version 3 of the protocol. + * A wl-output.done event will be emitted in version 3 or higher. + */ + if (zxdg_output_v1_get_version(driverdata->xdg_output) < 3) { + display_handle_done(data, driverdata->output); + } +} + +static void +xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, + const char *name) +{ +} + +static void +xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output, + const char *description) +{ +} + +static const struct zxdg_output_v1_listener xdg_output_listener = { + xdg_output_handle_logical_position, + xdg_output_handle_logical_size, + xdg_output_handle_done, + xdg_output_handle_name, + xdg_output_handle_description, +}; + +static void +AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90) +{ + struct EmulatedMode + { + int w; + int h; + }; + + /* Resolution lists courtesy of XWayland */ + const struct EmulatedMode mode_list[] = { + /* 16:9 (1.77) */ + { 7680, 4320 }, + { 6144, 3160 }, + { 5120, 2880 }, + { 4096, 2304 }, + { 3840, 2160 }, + { 3200, 1800 }, + { 2880, 1620 }, + { 2560, 1440 }, + { 2048, 1152 }, + { 1920, 1080 }, + { 1600, 900 }, + { 1368, 768 }, + { 1280, 720 }, + { 864, 486 }, + + /* 16:10 (1.6) */ + { 2560, 1600 }, + { 1920, 1200 }, + { 1680, 1050 }, + { 1440, 900 }, + { 1280, 800 }, + + /* 3:2 (1.5) */ + { 720, 480 }, + + /* 4:3 (1.33) */ + { 2048, 1536 }, + { 1920, 1440 }, + { 1600, 1200 }, + { 1440, 1080 }, + { 1400, 1050 }, + { 1280, 1024 }, + { 1280, 960 }, + { 1152, 864 }, + { 1024, 768 }, + { 800, 600 }, + { 640, 480 } + }; + + int i; + const int native_width = dpy->display_modes->w; + const int native_height = dpy->display_modes->h; + + for (i = 0; i < SDL_arraysize(mode_list); ++i) { + /* Only add modes that are smaller than the native mode */ + if ((mode_list[i].w < native_width && mode_list[i].h < native_height) || + (mode_list[i].w < native_width && mode_list[i].h == native_height)) { + SDL_DisplayMode mode = *dpy->display_modes; + + if (rot_90) { + mode.w = mode_list[i].h; + mode.h = mode_list[i].w; + } else { + mode.w = mode_list[i].w; + mode.h = mode_list[i].h; + } + + SDL_AddDisplayMode(dpy, &mode); + } + } +} + static void display_handle_geometry(void *data, struct wl_output *output, @@ -307,7 +454,7 @@ display_handle_geometry(void *data, SDL_VideoDisplay *display; int i; - if (driverdata->done) { + if (driverdata->wl_output_done_count) { /* Clear the wl_output ref so Reset doesn't free it */ display = SDL_GetDisplay(driverdata->index); for (i = 0; i < display->num_display_modes; i += 1) { @@ -318,11 +465,14 @@ display_handle_geometry(void *data, SDL_ResetDisplayModes(driverdata->index); /* The display has officially started over. */ - driverdata->done = SDL_FALSE; + driverdata->wl_output_done_count = 0; } - driverdata->x = x; - driverdata->y = y; + /* Apply the change from wl-output only if xdg-output is not supported */ + if (!driverdata->has_logical_position) { + driverdata->x = x; + driverdata->y = y; + } driverdata->physical_width = physical_width; driverdata->physical_height = physical_height; if (driverdata->index == -1) { @@ -369,36 +519,21 @@ display_handle_mode(void *data, int refresh) { SDL_WaylandOutputData* driverdata = data; - SDL_DisplayMode mode; if (flags & WL_OUTPUT_MODE_CURRENT) { - /* Don't rotate this yet, handle_done will do it later */ - driverdata->width = width; - driverdata->height = height; - driverdata->refresh = refresh; - } + driverdata->native_width = width; + driverdata->native_height = height; - /* Note that the width/height are NOT multiplied by scale_factor! - * This is intentional and is designed to get the unscaled modes, which is - * important for high-DPI games intending to use the display mode as the - * target drawable size. The scaled desktop mode will be added at the end - * when display_handle_done is called (see below). - */ - SDL_zero(mode); - mode.format = SDL_PIXELFORMAT_RGB888; - if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) { - mode.w = height; - mode.h = width; - } else { - mode.w = width; - mode.h = height; - } - mode.refresh_rate = (int)SDL_round(refresh / 1000.0); /* mHz to Hz */ - mode.driverdata = driverdata->output; - if (driverdata->index > -1) { - SDL_AddDisplayMode(SDL_GetDisplay(driverdata->index), &mode); - } else { - SDL_AddDisplayMode(&driverdata->placeholder, &mode); + /* + * Don't rotate this yet, wl-output coordinates are transformed in + * handle_done and xdg-output coordinates are pre-transformed. + */ + if (!driverdata->has_logical_size) { + driverdata->width = width; + driverdata->height = height; + } + + driverdata->refresh = refresh; } } @@ -407,20 +542,73 @@ display_handle_done(void *data, struct wl_output *output) { SDL_WaylandOutputData* driverdata = data; - SDL_DisplayMode mode; + SDL_VideoData* video = driverdata->videodata; + SDL_DisplayMode native_mode, desktop_mode; SDL_VideoDisplay *dpy; - if (driverdata->done) + /* + * When using xdg-output, two wl-output.done events will be emitted: + * one at the completion of wl-display and one at the completion of xdg-output. + * + * All required events must be received before proceeding. + */ + const int event_await_count = 1 + (driverdata->xdg_output != NULL); + + driverdata->wl_output_done_count = SDL_min(driverdata->wl_output_done_count + 1, event_await_count + 1); + + if (driverdata->wl_output_done_count != event_await_count) { return; + } - driverdata->done = SDL_TRUE; + /* The native display resolution */ + SDL_zero(native_mode); + native_mode.format = SDL_PIXELFORMAT_RGB888; - SDL_zero(mode); - mode.format = SDL_PIXELFORMAT_RGB888; if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) { - mode.w = driverdata->height / driverdata->scale_factor; - mode.h = driverdata->width / driverdata->scale_factor; + native_mode.w = driverdata->native_height; + native_mode.h = driverdata->native_width; + } else { + native_mode.w = driverdata->native_width; + native_mode.h = driverdata->native_height; + } + native_mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */ + native_mode.driverdata = driverdata->output; + /* The scaled desktop mode */ + SDL_zero(desktop_mode); + desktop_mode.format = SDL_PIXELFORMAT_RGB888; + + /* Scale the desktop coordinates, if xdg-output isn't present */ + if (!driverdata->has_logical_size) { + driverdata->width /= driverdata->scale_factor; + driverdata->height /= driverdata->scale_factor; + } + + /* xdg-output dimensions are already transformed, so no need to rotate. */ + if (driverdata->has_logical_size || !(driverdata->transform & WL_OUTPUT_TRANSFORM_90)) { + desktop_mode.w = driverdata->width; + desktop_mode.h = driverdata->height; + } else { + desktop_mode.w = driverdata->height; + desktop_mode.h = driverdata->width; + } + desktop_mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */ + desktop_mode.driverdata = driverdata->output; + + /* + * The native display mode is only exposed separately from the desktop size if: + * the desktop is scaled and the wp_viewporter protocol is supported. + */ + if (driverdata->scale_factor > 1.0f && video->viewporter != NULL) { + if (driverdata->index > -1) { + SDL_AddDisplayMode(SDL_GetDisplay(driverdata->index), &native_mode); + } else { + SDL_AddDisplayMode(&driverdata->placeholder, &native_mode); + } + } + + /* Calculate the display DPI */ + if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) { driverdata->hdpi = driverdata->physical_height ? (((float) driverdata->height) * 25.4f / driverdata->physical_height) : 0.0f; @@ -432,9 +620,6 @@ display_handle_done(void *data, ((float) driverdata->physical_height) / 25.4f, ((float) driverdata->physical_width) / 25.4f); } else { - mode.w = driverdata->width / driverdata->scale_factor; - mode.h = driverdata->height / driverdata->scale_factor; - driverdata->hdpi = driverdata->physical_width ? (((float) driverdata->width) * 25.4f / driverdata->physical_width) : 0.0f; @@ -446,8 +631,6 @@ display_handle_done(void *data, ((float) driverdata->physical_width) / 25.4f, ((float) driverdata->physical_height) / 25.4f); } - mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */ - mode.driverdata = driverdata->output; if (driverdata->index > -1) { dpy = SDL_GetDisplay(driverdata->index); @@ -455,9 +638,14 @@ display_handle_done(void *data, dpy = &driverdata->placeholder; } - SDL_AddDisplayMode(dpy, &mode); - SDL_SetCurrentDisplayMode(dpy, &mode); - SDL_SetDesktopDisplayMode(dpy, &mode); + SDL_AddDisplayMode(dpy, &desktop_mode); + SDL_SetCurrentDisplayMode(dpy, &desktop_mode); + SDL_SetDesktopDisplayMode(dpy, &desktop_mode); + + /* Add emulated modes if wp_viewporter is supported. */ + if (video->viewporter) { + AddEmulatedModes(dpy, (driverdata->transform & WL_OUTPUT_TRANSFORM_90) != 0); + } if (driverdata->index == -1) { /* First time getting display info, create the VideoDisplay */ @@ -504,11 +692,29 @@ Wayland_add_display(SDL_VideoData *d, uint32_t id) data->videodata = d; data->output = output; data->registry_id = id; - data->scale_factor = 1.0; + data->scale_factor = 1.0f; data->index = -1; wl_output_add_listener(output, &output_listener, data); SDL_WAYLAND_register_output(output); + + /* Keep a list of outputs for deferred xdg-output initialization. */ + if (d->output_list != NULL) { + SDL_WaylandOutputData *node = (SDL_WaylandOutputData*)d->output_list; + + while (node->next != NULL) { + node = (SDL_WaylandOutputData*)node->next; + } + + node->next = (struct SDL_WaylandOutputData*)data; + } else { + d->output_list = (struct SDL_WaylandOutputData*)data; + } + + if (data->videodata->xdg_output_manager) { + data->xdg_output = zxdg_output_manager_v1_get_xdg_output(data->videodata->xdg_output_manager, output); + zxdg_output_v1_add_listener(data->xdg_output, &xdg_output_listener, data); + } } static void @@ -524,6 +730,9 @@ Wayland_free_display(uint32_t id) data = (SDL_WaylandOutputData *) display->driverdata; if (data->registry_id == id) { SDL_DelVideoDisplay(i); + if (data->xdg_output) { + zxdg_output_v1_destroy(data->xdg_output); + } wl_output_destroy(data->output); SDL_free(data); @@ -540,6 +749,16 @@ Wayland_free_display(uint32_t id) } } +static void +Wayland_init_xdg_output(SDL_VideoData *d) +{ + SDL_WaylandOutputData *node; + for (node = d->output_list; node != NULL; node = node->next) { + node->xdg_output = zxdg_output_manager_v1_get_xdg_output(node->videodata->xdg_output_manager, node->output); + zxdg_output_v1_add_listener(node->xdg_output, &xdg_output_listener, node); + } +} + #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH static void windowmanager_hints(void *data, struct qt_windowmanager *qt_windowmanager, @@ -600,7 +819,7 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id, } else if (SDL_strcmp(interface, "wl_seat") == 0) { Wayland_display_add_input(d, id, version); } else if (SDL_strcmp(interface, "xdg_wm_base") == 0) { - d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, 1); + d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, SDL_min(version, 3)); xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL); } else if (SDL_strcmp(interface, "wl_shm") == 0) { d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); @@ -620,6 +839,17 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id, Wayland_add_data_device_manager(d, id, version); } else if (SDL_strcmp(interface, "zxdg_decoration_manager_v1") == 0) { d->decoration_manager = wl_registry_bind(d->registry, id, &zxdg_decoration_manager_v1_interface, 1); + } else if (SDL_strcmp(interface, "zwp_tablet_manager_v2") == 0) { + d->tablet_manager = wl_registry_bind(d->registry, id, &zwp_tablet_manager_v2_interface, 1); + if (d->input) { + Wayland_input_add_tablet(d->input, d->tablet_manager); + } + } else if (SDL_strcmp(interface, "zxdg_output_manager_v1") == 0) { + version = SDL_min(version, 3); /* Versions 1 through 3 are supported. */ + d->xdg_output_manager = wl_registry_bind(d->registry, id, &zxdg_output_manager_v1_interface, version); + Wayland_init_xdg_output(d); + } else if (SDL_strcmp(interface, "wp_viewporter") == 0) { + d->viewporter = wl_registry_bind(d->registry, id, &wp_viewporter_interface, 1); #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH } else if (SDL_strcmp(interface, "qt_touch_extension") == 0) { @@ -646,6 +876,29 @@ static const struct wl_registry_listener registry_listener = { display_handle_global, display_remove_global }; + +#ifdef HAVE_LIBDECOR_H +static SDL_bool should_use_libdecor(SDL_VideoData *data) +{ + if (!SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR) { + return SDL_FALSE; + } + + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR, SDL_TRUE)) { + return SDL_FALSE; + } + + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR, SDL_FALSE)) { + return SDL_TRUE; + } + + if (data->decoration_manager) { + return SDL_FALSE; + } + + return SDL_TRUE; +} +#endif int Wayland_VideoInit(_THIS) @@ -669,14 +922,8 @@ Wayland_VideoInit(_THIS) #ifdef HAVE_LIBDECOR_H /* Don't have server-side decorations? Try client-side instead. */ - if (!data->decoration_manager && SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR && SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR, SDL_TRUE)) { + if (should_use_libdecor(data)) { data->shell.libdecor = libdecor_new(data->display, &libdecor_interface); - - /* If libdecor works, we don't need xdg-shell anymore. */ - if (data->shell.libdecor && data->shell.xdg) { - xdg_wm_base_destroy(data->shell.xdg); - data->shell.xdg = NULL; - } } #endif @@ -737,6 +984,10 @@ Wayland_VideoQuit(_THIS) for (i = 0; i < _this->num_displays; ++i) { SDL_VideoDisplay *display = &_this->displays[i]; + if (((SDL_WaylandOutputData*)display->driverdata)->xdg_output) { + zxdg_output_v1_destroy(((SDL_WaylandOutputData*)display->driverdata)->xdg_output); + } + wl_output_destroy(((SDL_WaylandOutputData*)display->driverdata)->output); SDL_free(display->driverdata); display->driverdata = NULL; @@ -779,6 +1030,9 @@ Wayland_VideoQuit(_THIS) Wayland_touch_destroy(data); #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + if (data->tablet_manager) + zwp_tablet_manager_v2_destroy((struct zwp_tablet_manager_v2*)data->tablet_manager); + if (data->data_device_manager) wl_data_device_manager_destroy(data->data_device_manager); @@ -798,6 +1052,14 @@ Wayland_VideoQuit(_THIS) } #endif + if (data->xdg_output_manager) { + zxdg_output_manager_v1_destroy(data->xdg_output_manager); + } + + if (data->viewporter) { + wp_viewporter_destroy(data->viewporter); + } + if (data->compositor) wl_compositor_destroy(data->compositor); diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h index 31168a9d5..6f941db80 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h @@ -34,6 +34,7 @@ struct xkb_context; struct SDL_WaylandInput; +struct SDL_WaylandTabletManager; #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH struct SDL_WaylandTouch; @@ -46,6 +47,8 @@ typedef struct { int size; } SDL_WaylandCursorTheme; +typedef struct SDL_WaylandOutputData SDL_WaylandOutputData; + typedef struct { SDL_bool initializing; struct wl_display *display; @@ -70,6 +73,8 @@ typedef struct { struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager; struct xdg_activation_v1 *activation_manager; struct zwp_text_input_manager_v3 *text_input_manager; + struct zxdg_output_manager_v1 *xdg_output_manager; + struct wp_viewporter *viewporter; EGLDisplay edpy; EGLContext context; @@ -77,6 +82,8 @@ typedef struct { struct xkb_context *xkb_context; struct SDL_WaylandInput *input; + struct SDL_WaylandTabletManager *tablet_manager; + SDL_WaylandOutputData *output_list; #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH struct SDL_WaylandTouch *touch; @@ -89,19 +96,23 @@ typedef struct { int relative_mouse_mode; } SDL_VideoData; -typedef struct { +struct SDL_WaylandOutputData { SDL_VideoData *videodata; struct wl_output *output; + struct zxdg_output_v1 *xdg_output; uint32_t registry_id; float scale_factor; + int native_width, native_height; int x, y, width, height, refresh, transform; SDL_DisplayOrientation orientation; int physical_width, physical_height; float ddpi, hdpi, vdpi; + SDL_bool has_logical_position, has_logical_size; int index; SDL_VideoDisplay placeholder; - SDL_bool done; -} SDL_WaylandOutputData; + int wl_output_done_count; + SDL_WaylandOutputData *next; +}; /* Needed here to get wl_surface declaration, fixes GitHub#4594 */ #include "SDL_waylanddyn.h" diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.c index eb4435131..90b318fc8 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandvulkan.c @@ -139,11 +139,11 @@ void Wayland_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h) data = (SDL_WindowData *) window->driverdata; if (w) { - *w = window->w * data->scale_factor; + *w = data->drawable_width; } if (h) { - *h = window->h * data->scale_factor; + *h = data->drawable_height; } } } diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c index 635546af4..0bbae4691 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c @@ -25,22 +25,294 @@ #include "../SDL_sysvideo.h" #include "../../events/SDL_windowevents_c.h" +#include "../../events/SDL_mouse_c.h" #include "../SDL_egl_c.h" #include "SDL_waylandevents_c.h" #include "SDL_waylandwindow.h" #include "SDL_waylandvideo.h" #include "SDL_waylandtouch.h" #include "SDL_hints.h" +#include "SDL_events.h" #include "xdg-shell-client-protocol.h" #include "xdg-decoration-unstable-v1-client-protocol.h" #include "idle-inhibit-unstable-v1-client-protocol.h" #include "xdg-activation-v1-client-protocol.h" +#include "viewporter-client-protocol.h" #ifdef HAVE_LIBDECOR_H #include #endif +static void +GetFullScreenDimensions(SDL_Window *window, int *width, int *height, int *drawable_width, int *drawable_height) +{ + SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata; + + int fs_width, fs_height; + int buf_width, buf_height; + + /* + * Fullscreen desktop mandates a desktop sized window, so that's what applications will get. + * If the application is DPI aware, it will need to handle the transformations between the + * differently sized window and backbuffer spaces on its own. + */ + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { + fs_width = output->width; + fs_height = output->height; + + /* If the application is DPI aware, we can expose the true backbuffer size */ + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + buf_width = output->native_width; + buf_height = output->native_height; + } else { + buf_width = fs_width; + buf_height = fs_height; + } + } else { + /* + * If a mode was set, use it, otherwise use the native resolution + * for DPI aware apps and the desktop size for legacy apps. + */ + if (window->fullscreen_mode.w != 0 && window->fullscreen_mode.h != 0) { + fs_width = window->fullscreen_mode.w; + fs_height = window->fullscreen_mode.h; + } else if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + fs_width = output->native_width; + fs_height = output->native_height; + } else { + fs_width = output->width; + fs_height = output->height; + } + + buf_width = fs_width; + buf_height = fs_height; + } + + if (width) { + *width = fs_width; + } + if (height) { + *height = fs_height; + } + if (drawable_width) { + *drawable_width = buf_width; + } + if (drawable_height) { + *drawable_height = buf_height; + } +} + +static inline SDL_bool +DesktopIsScaled(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + + return data->scale_factor != 1.0f; +} + +static inline SDL_bool +DesktopIsFractionalScaled(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata; + + if ((output->native_width != (int)(output->width * data->scale_factor) || + output->native_height != (int)(output->height * data->scale_factor))) { + return SDL_TRUE; + } + + return SDL_FALSE; +} + +static SDL_bool +NeedFullscreenViewport(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + SDL_VideoData *video = data->waylandData; + SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata; + + int fs_width, fs_height; + + GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL); + + /* + * Fullscreen needs a viewport: + * - If the desktop uses fractional scaling + * - Fullscreen desktop was not requested OR the window is DPI aware + * + * - The desktop uses non-fractional scaling + * - Fullscreen desktop was NOT requested + * + * - The desktop is not scaled + * - A non-native fullscreen mode was explicitly set by the client + */ + if (video->viewporter != NULL && (window->flags & SDL_WINDOW_FULLSCREEN)) { + if (DesktopIsFractionalScaled(window)) { + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP || + (window->flags & SDL_WINDOW_ALLOW_HIGHDPI)) { + return SDL_TRUE; + } + } else if (DesktopIsScaled(window)) { + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { + return SDL_TRUE; + } + } else if (fs_width != output->native_width && fs_height != output->native_height) { + return SDL_TRUE; + } + } + + return SDL_FALSE; +} + +static inline SDL_bool +NeedWindowedViewport(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + SDL_VideoData *video = data->waylandData; + + return !(window->flags & SDL_WINDOW_FULLSCREEN) && (video->viewporter != NULL) && + DesktopIsFractionalScaled(window) && (window->flags & SDL_WINDOW_ALLOW_HIGHDPI); +} + +/* Never set a fullscreen window size larger than the desktop. */ +SDL_FORCE_INLINE int +GetWindowWidth(SDL_Window *window) +{ + return NeedFullscreenViewport(window) ? ((SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata)->width : window->w; +} + +SDL_FORCE_INLINE int +GetWindowHeight(SDL_Window *window) +{ + return NeedFullscreenViewport(window) ? ((SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata)->height : window->h; +} + +static void +GetWindowBufferSize(SDL_Window *window, int *width, int *height) +{ + SDL_WindowData *data = window->driverdata; + SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata; + int buf_width; + int buf_height; + + if (NeedWindowedViewport(window)) { + const float frac_scale_x = (float)output->native_width / (float)output->width; + const float frac_scale_y = (float)output->native_height / (float)output->height; + + buf_width = (int)SDL_lroundf(window->w * frac_scale_x); + buf_height = (int)SDL_lroundf(window->h * frac_scale_y); + } else { /* Windowed or fullscreen with no viewport */ + buf_width = window->w * data->scale_factor; + buf_height = window->h * data->scale_factor; + } + + if (width) { + *width = buf_width; + } + if (height) { + *height = buf_height; + } +} + +static void +SetViewport(SDL_Window *window, int src_width, int src_height, int dst_width, int dst_height) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *video = wind->waylandData; + + if (video->viewporter) { + if (wind->viewport == NULL) { + wind->viewport = wp_viewporter_get_viewport(video->viewporter, wind->surface); + } + + wp_viewport_set_source(wind->viewport, wl_fixed_from_int(0), wl_fixed_from_int(0), wl_fixed_from_int(src_width), wl_fixed_from_int(src_height)); + wp_viewport_set_destination(wind->viewport, dst_width, dst_height); + } +} + +static void +UnsetViewport(SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + + if (wind->viewport) { + wp_viewport_destroy(wind->viewport); + wind->viewport = NULL; + } +} + +static void +ConfigureViewport(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + SDL_VideoData *viddata = data->waylandData; + SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata; + + if (NeedFullscreenViewport(window)) { + int fs_width, fs_height; + int src_width, src_height; + + GetFullScreenDimensions(window, &fs_width, &fs_height, &src_width, &src_height); + SetViewport(window, src_width, src_height, output->width, output->height); + + data->damage_region.x = 0; + data->damage_region.y = 0; + data->damage_region.w = output->width; + data->damage_region.h = output->height; + + data->pointer_scale_x = (float)fs_width / (float)output->width; + data->pointer_scale_y = (float)fs_height / (float)output->height; + } else { + if (NeedWindowedViewport(window)) { + int src_width, src_height; + + GetWindowBufferSize(window, &src_width, &src_height); + SetViewport(window, src_width, src_height, window->w, window->h); + } else { + UnsetViewport(window); + } + + SDL_zero(data->damage_region); + + data->pointer_scale_x = 1.0f; + data->pointer_scale_y = 1.0f; + } + + /* + * If mouse_rect is not empty, re-create the confinement region with the new scale value. + * If the pointer is locked to the general surface with unspecified coordinates, it will + * be confined to the viewport region, so no update is required. + */ + if (!SDL_RectEmpty(&window->mouse_rect)) { + Wayland_input_confine_pointer(viddata->input, window); + } +} + +static void +SetDrawScale(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + + if (NeedFullscreenViewport(window)) { + int fs_width, fs_height; + + GetFullScreenDimensions(window, &fs_width, &fs_height, &data->drawable_width, &data->drawable_height); + + /* Set the buffer scale to 1 since a viewport will be used. */ + wl_surface_set_buffer_scale(data->surface, 1); + } else { + GetWindowBufferSize(window, &data->drawable_width, &data->drawable_height); + + if (NeedWindowedViewport(window)) { + /* Set the buffer scale to 1 since a viewport will be used. */ + wl_surface_set_buffer_scale(data->surface, 1); + } else { + wl_surface_set_buffer_scale(data->surface, (int32_t)data->scale_factor); + } + } +} + static void SetMinMaxDimensions(SDL_Window *window, SDL_bool commit) { @@ -48,6 +320,15 @@ SetMinMaxDimensions(SDL_Window *window, SDL_bool commit) SDL_VideoData *viddata = wind->waylandData; int min_width, min_height, max_width, max_height; + /* Pop-ups don't get to change size */ + if (WINDOW_IS_XDG_POPUP(window)) { + /* ... but we still want to commit, particularly for ShowWindow */ + if (commit) { + wl_surface_commit(wind->surface); + } + return; + } + if (window->flags & SDL_WINDOW_FULLSCREEN) { min_width = 0; min_height = 0; @@ -66,7 +347,7 @@ SetMinMaxDimensions(SDL_Window *window, SDL_bool commit) } #ifdef HAVE_LIBDECOR_H - if (viddata->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(viddata, window)) { if (wind->shell_surface.libdecor.frame == NULL) { return; /* Can't do anything yet, wait for ShowWindow */ } @@ -100,13 +381,22 @@ SetFullscreen(SDL_Window *window, struct wl_output *output, SDL_bool commit) SDL_WindowData *wind = window->driverdata; SDL_VideoData *viddata = wind->waylandData; + /* Pop-ups don't get to be fullscreened */ + if (WINDOW_IS_XDG_POPUP(window)) { + /* ... but we still want to commit, particularly for ShowWindow */ + if (commit) { + wl_surface_commit(wind->surface); + } + return; + } + /* The desktop may try to enforce min/max sizes here, so turn them off for * fullscreen and on (if applicable) for windowed */ SetMinMaxDimensions(window, SDL_FALSE); #ifdef HAVE_LIBDECOR_H - if (viddata->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(viddata, window)) { if (wind->shell_surface.libdecor.frame == NULL) { return; /* Can't do anything yet, wait for ShowWindow */ } @@ -150,6 +440,11 @@ handle_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) SDL_WindowData *wind = (SDL_WindowData *) data; SDL_AtomicSet(&wind->swap_interval_ready, 1); /* mark window as ready to present again. */ + if (!SDL_RectEmpty(&wind->damage_region)) { + wl_surface_damage(wind->surface, wind->damage_region.x, wind->damage_region.y, + wind->damage_region.w, wind->damage_region.h); + } + /* reset this callback to fire again once a new frame was presented and compositor wants the next one. */ wind->frame_callback = wl_surface_frame(wind->frame_surface_wrapper); wl_callback_destroy(cb); @@ -303,9 +598,14 @@ handle_configure_xdg_toplevel(void *data, * UPDATE: Nope, sure enough a compositor sends 0,0. This is a known bug: * https://bugs.kde.org/show_bug.cgi?id=444962 */ - if (width != 0 && height != 0 && (window->w != width || window->h != height)) { - window->w = width; - window->h = height; + if (!NeedFullscreenViewport(window)) { + if (width != 0 && height != 0 && (window->w != width || window->h != height)) { + window->w = width; + window->h = height; + wind->needs_resize_event = SDL_TRUE; + } + } else { + GetFullScreenDimensions(window, &window->w, &window->h, NULL, NULL); wind->needs_resize_event = SDL_TRUE; } @@ -329,6 +629,60 @@ static const struct xdg_toplevel_listener toplevel_listener_xdg = { handle_close_xdg_toplevel }; +static void +handle_configure_xdg_popup(void *data, + struct xdg_popup *xdg_popup, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + /* No-op, we don't use x/y and width/height are fixed-size */ +} + +static void +handle_done_xdg_popup(void *data, struct xdg_popup *xdg_popup) +{ + SDL_WindowData *window = (SDL_WindowData *)data; + SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); +} + +static void +handle_repositioned_xdg_popup(void *data, + struct xdg_popup *xdg_popup, + uint32_t token) +{ + /* No-op, configure does all the work we care about */ +} + +static const struct xdg_popup_listener popup_listener_xdg = { + handle_configure_xdg_popup, + handle_done_xdg_popup, + handle_repositioned_xdg_popup +}; + +#define TOOLTIP_CURSOR_OFFSET 8 /* FIXME: Arbitrary, eyeballed from X tooltip */ + +static int +Wayland_PopupWatch(void *data, SDL_Event *event) +{ + if (event->type == SDL_MOUSEMOTION) { + SDL_Window *window = (SDL_Window *) data; + SDL_WindowData *wind = window->driverdata; + + /* Coordinates might be relative to the popup, which we don't want */ + if (event->motion.windowID == wind->shell_surface.xdg.roleobj.popup.parentID) { + xdg_positioner_set_offset(wind->shell_surface.xdg.roleobj.popup.positioner, + event->motion.x + TOOLTIP_CURSOR_OFFSET, + event->motion.y + TOOLTIP_CURSOR_OFFSET); + xdg_popup_reposition(wind->shell_surface.xdg.roleobj.popup.popup, + wind->shell_surface.xdg.roleobj.popup.positioner, + 0); + } + } + return 1; +} + #ifdef HAVE_LIBDECOR_H static void decoration_frame_configure(struct libdecor_frame *frame, @@ -399,17 +753,23 @@ decoration_frame_configure(struct libdecor_frame *frame, * Always assume the configure is wrong. */ if (fullscreen) { - /* FIXME: We have been explicitly told to respect the fullscreen size - * parameters here, even though they are known to be wrong on GNOME at - * bare minimum. If this is wrong, don't blame us, we were explicitly - * told to do this. - */ - if (!libdecor_configuration_get_content_size(configuration, frame, - &width, &height)) { - width = window->w; - height = window->h; + if (!NeedFullscreenViewport(window)) { + /* FIXME: We have been explicitly told to respect the fullscreen size + * parameters here, even though they are known to be wrong on GNOME at + * bare minimum. If this is wrong, don't blame us, we were explicitly + * told to do this. + */ + if (!libdecor_configuration_get_content_size(configuration, frame, + &width, &height)) { + width = window->w; + height = window->h; + } + } else { + GetFullScreenDimensions(window, &width, &height, NULL, NULL); } + wind->needs_resize_event = SDL_TRUE; + /* This part is good though. */ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { scale_factor = driverdata->scale_factor; @@ -445,7 +805,7 @@ decoration_frame_configure(struct libdecor_frame *frame, wind->shell_surface.libdecor.initial_configure_seen = SDL_TRUE; /* ... then commit the changes on the libdecor side. */ - state = libdecor_state_new(width, height); + state = libdecor_state_new(GetWindowWidth(window), GetWindowHeight(window)); libdecor_frame_commit(frame, state, configuration); libdecor_state_free(state); @@ -554,9 +914,28 @@ Wayland_move_window(SDL_Window *window, int i, numdisplays = SDL_GetNumVideoDisplays(); for (i = 0; i < numdisplays; i += 1) { if (SDL_GetDisplay(i)->driverdata == driverdata) { - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, - SDL_WINDOWPOS_CENTERED_DISPLAY(i), - SDL_WINDOWPOS_CENTERED_DISPLAY(i)); + /* We want to send a very very specific combination here: + * + * 1. A coordinate that tells the application what display we're on + * 2. Exactly (0, 0) + * + * Part 1 is useful information but is also really important for + * ensuring we end up on the right display for fullscreen, while + * part 2 is important because numerous applications use a specific + * combination of GetWindowPosition and GetGlobalMouseState, and of + * course neither are supported by Wayland. Since global mouse will + * fall back to just GetMouseState, we need the window position to + * be zero so the cursor math works without it going off in some + * random direction. See UE5 Editor for a notable example of this! + * + * This may be an issue some day if we're ever able to implement + * SDL_GetDisplayUsableBounds! + * + * -flibit + */ + SDL_Rect bounds; + SDL_GetDisplayBounds(i, &bounds); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, bounds.x, bounds.y); break; } } @@ -624,6 +1003,19 @@ static const struct wl_surface_listener surface_listener = { handle_surface_leave }; +static void +Wayland_FillEmptyShellInfo(SDL_SysWMinfo * info, const Uint32 version) +{ + info->info.wl.xdg_surface = NULL; + if (version >= SDL_VERSIONNUM(2, 0, 17)) { + info->info.wl.xdg_toplevel = NULL; + if (version >= SDL_VERSIONNUM(2, 0, 22)) { + info->info.wl.xdg_popup = NULL; + info->info.wl.xdg_positioner = NULL; + } + } +} + SDL_bool Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) { @@ -656,23 +1048,40 @@ Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) info->info.wl.egl_window = data->egl_window; #ifdef HAVE_LIBDECOR_H - if (viddata->shell.libdecor && data->shell_surface.libdecor.frame != NULL) { - info->info.wl.xdg_surface = libdecor_frame_get_xdg_surface(data->shell_surface.libdecor.frame); - if (version >= SDL_VERSIONNUM(2, 0, 17)) { - info->info.wl.xdg_toplevel = libdecor_frame_get_xdg_toplevel(data->shell_surface.libdecor.frame); + if (WINDOW_IS_LIBDECOR(viddata, window)) { + if (data->shell_surface.libdecor.frame != NULL) { + info->info.wl.xdg_surface = libdecor_frame_get_xdg_surface(data->shell_surface.libdecor.frame); + if (version >= SDL_VERSIONNUM(2, 0, 17)) { + info->info.wl.xdg_toplevel = libdecor_frame_get_xdg_toplevel(data->shell_surface.libdecor.frame); + if (version >= SDL_VERSIONNUM(2, 0, 22)) { + info->info.wl.xdg_popup = NULL; + info->info.wl.xdg_positioner = NULL; + } + } + } else { + /* Not mapped yet */ + Wayland_FillEmptyShellInfo(info, version); } } else #endif if (viddata->shell.xdg && data->shell_surface.xdg.surface != NULL) { info->info.wl.xdg_surface = data->shell_surface.xdg.surface; if (version >= SDL_VERSIONNUM(2, 0, 17)) { - info->info.wl.xdg_toplevel = data->shell_surface.xdg.roleobj.toplevel; + SDL_bool popup = WINDOW_IS_XDG_POPUP(window); + info->info.wl.xdg_toplevel = popup ? NULL : data->shell_surface.xdg.roleobj.toplevel; + if (version >= SDL_VERSIONNUM(2, 0, 22)) { + if (popup) { + info->info.wl.xdg_popup = data->shell_surface.xdg.roleobj.popup.popup; + info->info.wl.xdg_positioner = data->shell_surface.xdg.roleobj.popup.positioner; + } else { + info->info.wl.xdg_popup = NULL; + info->info.wl.xdg_positioner = NULL; + } + } } } else { - info->info.wl.xdg_surface = NULL; - if (version >= SDL_VERSIONNUM(2, 0, 17)) { - info->info.wl.xdg_toplevel = NULL; - } + /* Either it's not mapped yet or we don't have a shell protocol */ + Wayland_FillEmptyShellInfo(info, version); } } @@ -697,6 +1106,10 @@ Wayland_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_wi SDL_WindowData *modal_data = modal_window->driverdata; SDL_WindowData *parent_data = parent_window->driverdata; + if (WINDOW_IS_XDG_POPUP(modal_window) || WINDOW_IS_XDG_POPUP(parent_window)) { + return SDL_SetError("Modal/Parent was a popup, not a toplevel"); + } + #ifdef HAVE_LIBDECOR_H if (viddata->shell.libdecor) { if (modal_data->shell_surface.libdecor.frame == NULL) { @@ -731,9 +1144,26 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) SDL_VideoData *c = _this->driverdata; SDL_WindowData *data = window->driverdata; - /* Create the shell surface and map the toplevel */ + /* Detach any previous buffers before resetting everything, otherwise when + * calling this a second time you'll get an annoying protocol error! + * + * FIXME: This was originally moved to HideWindow, which _should_ make + * sense, but for whatever reason UE5's popups require that this actually + * be in both places at once? Possibly from renderers making commits? I can't + * fully remember if this location caused crashes or if I was fixing a pair + * of Hide/Show calls. In any case, UE gives us a pretty good test and having + * both detach calls passes. This bug may be relevant if I'm wrong: + * + * https://bugs.kde.org/show_bug.cgi?id=448856 + * + * -flibit + */ + wl_surface_attach(data->surface, NULL, 0, 0); + wl_surface_commit(data->surface); + + /* Create the shell surface and map the toplevel/popup */ #ifdef HAVE_LIBDECOR_H - if (c->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(c, window)) { data->shell_surface.libdecor.frame = libdecor_decorate(c->shell.libdecor, data->surface, &libdecor_frame_interface, @@ -751,10 +1181,42 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) xdg_surface_set_user_data(data->shell_surface.xdg.surface, data); xdg_surface_add_listener(data->shell_surface.xdg.surface, &shell_surface_listener_xdg, data); - /* !!! FIXME: add popup role */ - data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface); - xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname); - xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data); + if (WINDOW_IS_XDG_POPUP(window)) { + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Window *focused = SDL_GetMouseFocus(); + SDL_WindowData *focuseddata = focused->driverdata; + + /* This popup may be a child of another popup! */ + data->shell_surface.xdg.roleobj.popup.parentID = SDL_GetWindowID(focused); + data->shell_surface.xdg.roleobj.popup.child = NULL; + if (WINDOW_IS_XDG_POPUP(focused)) { + SDL_assert(focuseddata->shell_surface.xdg.roleobj.popup.child == NULL); + focuseddata->shell_surface.xdg.roleobj.popup.child = window; + } + + /* Set up the positioner for the popup */ + data->shell_surface.xdg.roleobj.popup.positioner = xdg_wm_base_create_positioner(c->shell.xdg); + xdg_positioner_set_offset(data->shell_surface.xdg.roleobj.popup.positioner, + mouse->x + TOOLTIP_CURSOR_OFFSET, + mouse->y + TOOLTIP_CURSOR_OFFSET); + + /* Assign the popup role */ + data->shell_surface.xdg.roleobj.popup.popup = xdg_surface_get_popup(data->shell_surface.xdg.surface, + focuseddata->shell_surface.xdg.surface, + data->shell_surface.xdg.roleobj.popup.positioner); + xdg_popup_add_listener(data->shell_surface.xdg.roleobj.popup.popup, &popup_listener_xdg, data); + + /* For tooltips, track mouse motion so it follows the cursor */ + if (window->flags & SDL_WINDOW_TOOLTIP) { + if (xdg_popup_get_version(data->shell_surface.xdg.roleobj.popup.popup) >= 3) { + SDL_AddEventWatch(Wayland_PopupWatch, window); + } + } + } else { + data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface); + xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname); + xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data); + } } /* Restore state that was set prior to this call */ @@ -770,7 +1232,7 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) * this surface will fail. This is a new rule for xdg_shell. */ #ifdef HAVE_LIBDECOR_H - if (c->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(c, window)) { if (data->shell_surface.libdecor.frame) { while (!data->shell_surface.libdecor.initial_configure_seen) { WAYLAND_wl_display_flush(c->display); @@ -794,7 +1256,7 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) } /* Create the window decorations */ - if (data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) { + if (!WINDOW_IS_XDG_POPUP(window) && data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) { data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel); } } else { @@ -807,11 +1269,11 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) * them immediately afterward. */ #ifdef HAVE_LIBDECOR_H - if (c->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(c, window)) { /* ... but don't call it redundantly for libdecor, the decorator * may not interpret a redundant call nicely and cause weird stuff to happen */ - if (window->flags & SDL_WINDOW_BORDERLESS) { + if (data->shell_surface.libdecor.frame && window->flags & SDL_WINDOW_BORDERLESS) { Wayland_SetWindowBordered(_this, window, SDL_FALSE); } } else @@ -837,6 +1299,42 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) } } +static void +Wayland_ReleasePopup(_THIS, SDL_Window *popup) +{ + SDL_WindowData *popupdata; + + /* Basic sanity checks to weed out the weird popup closures */ + if (popup == NULL || popup->magic != &_this->window_magic) { + return; + } + popupdata = popup->driverdata; + if (popupdata == NULL) { + return; + } + + /* This may already be freed by a parent popup! */ + if (popupdata->shell_surface.xdg.roleobj.popup.popup == NULL) { + return; + } + + /* Release the child _first_, otherwise a protocol error triggers */ + if (popupdata->shell_surface.xdg.roleobj.popup.child != NULL) { + Wayland_ReleasePopup(_this, popupdata->shell_surface.xdg.roleobj.popup.child); + popupdata->shell_surface.xdg.roleobj.popup.child = NULL; + } + + if (popup->flags & SDL_WINDOW_TOOLTIP) { + if (xdg_popup_get_version(popupdata->shell_surface.xdg.roleobj.popup.popup) >= 3) { + SDL_DelEventWatch(Wayland_PopupWatch, popup); + } + } + xdg_popup_destroy(popupdata->shell_surface.xdg.roleobj.popup.popup); + xdg_positioner_destroy(popupdata->shell_surface.xdg.roleobj.popup.positioner); + popupdata->shell_surface.xdg.roleobj.popup.popup = NULL; + popupdata->shell_surface.xdg.roleobj.popup.positioner = NULL; +} + void Wayland_HideWindow(_THIS, SDL_Window *window) { SDL_VideoData *data = _this->driverdata; @@ -848,7 +1346,7 @@ void Wayland_HideWindow(_THIS, SDL_Window *window) } #ifdef HAVE_LIBDECOR_H - if (data->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(data, window)) { if (wind->shell_surface.libdecor.frame) { libdecor_frame_unref(wind->shell_surface.libdecor.frame); wind->shell_surface.libdecor.frame = NULL; @@ -856,7 +1354,9 @@ void Wayland_HideWindow(_THIS, SDL_Window *window) } else #endif if (data->shell.xdg) { - if (wind->shell_surface.xdg.roleobj.toplevel) { + if (WINDOW_IS_XDG_POPUP(window)) { + Wayland_ReleasePopup(_this, window); + } else if (wind->shell_surface.xdg.roleobj.toplevel) { xdg_toplevel_destroy(wind->shell_surface.xdg.roleobj.toplevel); wind->shell_surface.xdg.roleobj.toplevel = NULL; } @@ -1073,13 +1573,17 @@ Wayland_RestoreWindow(_THIS, SDL_Window * window) SDL_WindowData *wind = window->driverdata; SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + if (WINDOW_IS_XDG_POPUP(window)) { + return; + } + /* Set this flag now even if we never actually maximized, eventually * ShowWindow will take care of it along with the other window state. */ window->flags &= ~SDL_WINDOW_MAXIMIZED; #ifdef HAVE_LIBDECOR_H - if (viddata->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(viddata, window)) { if (wind->shell_surface.libdecor.frame == NULL) { return; /* Can't do anything yet, wait for ShowWindow */ } @@ -1102,8 +1606,13 @@ Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) { SDL_WindowData *wind = window->driverdata; const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata; + + if (WINDOW_IS_XDG_POPUP(window)) { + return; + } + #ifdef HAVE_LIBDECOR_H - if (viddata->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(viddata, window)) { if (wind->shell_surface.libdecor.frame) { libdecor_frame_set_visibility(wind->shell_surface.libdecor.frame, bordered); } @@ -1122,7 +1631,7 @@ Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) SDL_VideoData *data = _this->driverdata; const SDL_WindowData *wind = window->driverdata; - if (data->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(data, window)) { if (wind->shell_surface.libdecor.frame == NULL) { return; /* Can't do anything yet, wait for ShowWindow */ } @@ -1144,6 +1653,10 @@ Wayland_MaximizeWindow(_THIS, SDL_Window * window) SDL_WindowData *wind = window->driverdata; SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + if (WINDOW_IS_XDG_POPUP(window)) { + return; + } + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { return; } @@ -1154,7 +1667,7 @@ Wayland_MaximizeWindow(_THIS, SDL_Window * window) window->flags |= SDL_WINDOW_MAXIMIZED; #ifdef HAVE_LIBDECOR_H - if (viddata->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(viddata, window)) { if (wind->shell_surface.libdecor.frame == NULL) { return; /* Can't do anything yet, wait for ShowWindow */ } @@ -1177,8 +1690,12 @@ Wayland_MinimizeWindow(_THIS, SDL_Window * window) SDL_WindowData *wind = window->driverdata; SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + if (WINDOW_IS_XDG_POPUP(window)) { + return; + } + #ifdef HAVE_LIBDECOR_H - if (viddata->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(viddata, window)) { if (wind->shell_surface.libdecor.frame == NULL) { return; /* Can't do anything yet, wait for ShowWindow */ } @@ -1269,7 +1786,9 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) data->waylandData = c; data->sdlwindow = window; - data->scale_factor = 1.0; + data->scale_factor = 1.0f; + data->pointer_scale_x = 1.0f; + data->pointer_scale_y = 1.0f; if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { int i; @@ -1316,16 +1835,18 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) } #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + data->drawable_width = window->w * data->scale_factor; + data->drawable_height = window->h * data->scale_factor; + if (window->flags & SDL_WINDOW_OPENGL) { - data->egl_window = WAYLAND_wl_egl_window_create(data->surface, - window->w * data->scale_factor, window->h * data->scale_factor); + data->egl_window = WAYLAND_wl_egl_window_create(data->surface, data->drawable_width, data->drawable_height); #if SDL_VIDEO_OPENGL_EGL /* Create the GLES window surface */ data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window); if (data->egl_surface == EGL_NO_SURFACE) { - return SDL_SetError("failed to create an EGL window surface"); + return -1; /* SDL_EGL_CreateSurface should have set error */ } #endif } @@ -1375,12 +1896,13 @@ Wayland_HandleResize(SDL_Window *window, int width, int height, float scale) data->needs_resize_event = SDL_FALSE; } - wl_surface_set_buffer_scale(data->surface, data->scale_factor); + /* Configure the backbuffer size and scale factors */ + SetDrawScale(window); if (data->egl_window) { WAYLAND_wl_egl_window_resize(data->egl_window, - window->w * data->scale_factor, - window->h * data->scale_factor, + data->drawable_width, + data->drawable_height, 0, 0); } @@ -1394,9 +1916,18 @@ Wayland_HandleResize(SDL_Window *window, int width, int height, float scale) * It doesn't fix the first frames after resize being glitched visually, * but at least lets us not be terminated by the compositor. * Can be removed once SDL's resize logic becomes compliant. */ - if (viddata->shell.xdg && data->shell_surface.xdg.surface) { - xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, window->w, window->h); + if ( +#ifdef HAVE_LIBDECOR_H + !WINDOW_IS_LIBDECOR(viddata, window) && +#endif + viddata->shell.xdg && + data->shell_surface.xdg.surface) { + xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, + GetWindowWidth(window), GetWindowHeight(window)); } + + /* Update the viewport */ + ConfigureViewport(window); } void @@ -1422,7 +1953,7 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window) #ifdef HAVE_LIBDECOR_H /* we must not resize the window while we have a static (non-floating) size */ - if (data->shell.libdecor && + if (WINDOW_IS_LIBDECOR(data, window) && wind->shell_surface.libdecor.frame && !libdecor_frame_is_floating(wind->shell_surface.libdecor.frame)) { /* Commit the resize when we re-enter floating state */ @@ -1431,18 +1962,18 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window) } #endif - wl_surface_set_buffer_scale(wind->surface, wind->scale_factor); + SetDrawScale(window); if (wind->egl_window) { WAYLAND_wl_egl_window_resize(wind->egl_window, - window->w * wind->scale_factor, - window->h * wind->scale_factor, + wind->drawable_width, + wind->drawable_height, 0, 0); } #ifdef HAVE_LIBDECOR_H - if (data->shell.libdecor && wind->shell_surface.libdecor.frame) { - state = libdecor_state_new(window->w, window->h); + if (WINDOW_IS_LIBDECOR(data, window) && wind->shell_surface.libdecor.frame) { + state = libdecor_state_new(GetWindowWidth(window), GetWindowHeight(window)); libdecor_frame_commit(wind->shell_surface.libdecor.frame, state, NULL); libdecor_state_free(state); } @@ -1458,8 +1989,14 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window) wl_region_destroy(region); /* Update the geometry which may have been set by a hack in Wayland_HandleResize */ - if (data->shell.xdg && wind->shell_surface.xdg.surface) { - xdg_surface_set_window_geometry(wind->shell_surface.xdg.surface, 0, 0, window->w, window->h); + if ( +#ifdef HAVE_LIBDECOR_H + !WINDOW_IS_LIBDECOR(data, window) && +#endif + data->shell.xdg && + wind->shell_surface.xdg.surface) { + xdg_surface_set_window_geometry(wind->shell_surface.xdg.surface, 0, 0, + GetWindowWidth(window), GetWindowHeight(window)); } } @@ -1468,9 +2005,13 @@ void Wayland_SetWindowTitle(_THIS, SDL_Window * window) SDL_WindowData *wind = window->driverdata; SDL_VideoData *viddata = _this->driverdata; + if (WINDOW_IS_XDG_POPUP(window)) { + return; + } + if (window->title != NULL) { #ifdef HAVE_LIBDECOR_H - if (viddata->shell.libdecor) { + if (WINDOW_IS_LIBDECOR(viddata, window)) { if (wind->shell_surface.libdecor.frame == NULL) { return; /* Can't do anything yet, wait for ShowWindow */ } @@ -1549,6 +2090,10 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window) xdg_activation_token_v1_destroy(wind->activation_token); } + if (wind->viewport) { + wp_viewport_destroy(wind->viewport); + } + SDL_free(wind->outputs); if (wind->frame_callback) { diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h index 90e4d8cf6..b1ba98cf9 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h @@ -36,16 +36,27 @@ typedef struct { struct xdg_surface *surface; union { struct xdg_toplevel *toplevel; - struct xdg_popup *popup; + struct { + struct xdg_popup *popup; + struct xdg_positioner *positioner; + Uint32 parentID; + SDL_Window *child; + } popup; } roleobj; SDL_bool initial_configure_seen; } SDL_xdg_shell_surface; +#define WINDOW_IS_XDG_POPUP(window) \ + (window->flags & (SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU)) + #ifdef HAVE_LIBDECOR_H typedef struct { struct libdecor_frame *frame; SDL_bool initial_configure_seen; } SDL_libdecor_surface; + +#define WINDOW_IS_LIBDECOR(viddata, window) \ + (viddata->shell.libdecor && !WINDOW_IS_XDG_POPUP(window)) #endif typedef struct { @@ -72,6 +83,7 @@ typedef struct { struct zwp_keyboard_shortcuts_inhibitor_v1 *key_inhibitor; struct zwp_idle_inhibitor_v1 *idle_inhibitor; struct xdg_activation_token_v1 *activation_token; + struct wp_viewport *viewport; /* floating dimensions for restoring from maximized and fullscreen */ int floating_width, floating_height; @@ -86,6 +98,10 @@ typedef struct { int num_outputs; float scale_factor; + float pointer_scale_x; + float pointer_scale_y; + int drawable_width, drawable_height; + SDL_Rect damage_region; SDL_bool needs_resize_event; SDL_bool floating_resize_pending; } SDL_WindowData; diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c b/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c index 0619f67dd..ebd0dd1f9 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c @@ -378,14 +378,14 @@ WIN_CheckAsyncMouseRelease(SDL_WindowData *data) } static void -WIN_UpdateFocus(SDL_Window *window) +WIN_UpdateFocus(SDL_Window *window, SDL_bool expect_focus) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; HWND hwnd = data->hwnd; SDL_bool had_focus = (SDL_GetKeyboardFocus() == window) ? SDL_TRUE : SDL_FALSE; SDL_bool has_focus = (GetForegroundWindow() == hwnd) ? SDL_TRUE : SDL_FALSE; - if (had_focus == has_focus) { + if (had_focus == has_focus || has_focus != expect_focus) { return; } @@ -686,7 +686,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Update the focus here, since it's possible to get WM_ACTIVATE and WM_SETFOCUS without actually being the foreground window, but this appears to get called in all cases where the global foreground window changes to and from this window. */ - WIN_UpdateFocus(data->window); + WIN_UpdateFocus(data->window, !!wParam); WIN_CheckICMProfileChanged(data->window); } break; @@ -694,16 +694,22 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_ACTIVATE: { /* Update the focus in case we changed focus to a child window and then away from the application */ - WIN_UpdateFocus(data->window); + WIN_UpdateFocus(data->window, !!LOWORD(wParam)); } break; case WM_SETFOCUS: + { + /* Update the focus in case it's changing between top-level windows in the same application */ + WIN_UpdateFocus(data->window, SDL_TRUE); + } + break; + case WM_KILLFOCUS: case WM_ENTERIDLE: { /* Update the focus in case it's changing between top-level windows in the same application */ - WIN_UpdateFocus(data->window); + WIN_UpdateFocus(data->window, SDL_FALSE); } break; diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c b/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c index 890d790ea..6dcea5bf2 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c @@ -158,7 +158,7 @@ WIN_SetWindowPositionInternal(_THIS, SDL_Window * window, UINT flags) int w, h; /* Figure out what the window area will be */ - if (SDL_ShouldAllowTopmost() && ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS) || (window->flags & SDL_WINDOW_ALWAYS_ON_TOP))) { + if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_ALWAYS_ON_TOP)) { top = HWND_TOPMOST; } else { top = HWND_NOTOPMOST; @@ -734,7 +734,14 @@ WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, int x, y; int w, h; - if (SDL_ShouldAllowTopmost() && ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS) || window->flags & SDL_WINDOW_ALWAYS_ON_TOP)) { + if (!fullscreen && (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP)) != 0) { + /* Resizing the window on hide causes problems restoring it in Wine, and it's unnecessary. + * Also, Windows would preview the minimized window with the wrong size. + */ + return; + } + + if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_ALWAYS_ON_TOP)) { top = HWND_TOPMOST; } else { top = HWND_NOTOPMOST; diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11events.c b/Engine/lib/sdl/src/video/x11/SDL_x11events.c index c1260215d..63091fe98 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11events.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11events.c @@ -380,7 +380,7 @@ X11_GetScrollLockModifierMask(_THIS) return num_mask; } -static void +void X11_ReconcileKeyboardState(_THIS) { SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; @@ -408,7 +408,22 @@ X11_ReconcileKeyboardState(_THIS) SDL_bool sdlKeyPressed = keyboardState[scancode] == SDL_PRESSED; if (x11KeyPressed && !sdlKeyPressed) { - SDL_SendKeyboardKey(SDL_PRESSED, scancode); + /* Only update modifier state for keys that are pressed in another application */ + switch (SDL_GetKeyFromScancode(scancode)) { + case SDLK_LCTRL: + case SDLK_RCTRL: + case SDLK_LSHIFT: + case SDLK_RSHIFT: + case SDLK_LALT: + case SDLK_RALT: + case SDLK_LGUI: + case SDLK_RGUI: + case SDLK_MODE: + SDL_SendKeyboardKey(SDL_PRESSED, scancode); + break; + default: + break; + } } else if (!x11KeyPressed && sdlKeyPressed) { SDL_SendKeyboardKey(SDL_RELEASED, scancode); } @@ -718,7 +733,6 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent) { SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - XkbEvent* xkbEvent = (XkbEvent*) xevent; Display *display; SDL_WindowData *data; int orig_event_type; @@ -805,11 +819,13 @@ X11_DispatchEvent(_THIS, XEvent *xevent) if (!data) { /* The window for KeymapNotify, etc events is 0 */ if (xevent->type == KeymapNotify) { +#ifdef DEBUG_XEVENTS + printf("window %p: KeymapNotify!\n", data); +#endif if (SDL_GetKeyboardFocus() != NULL) { X11_ReconcileKeyboardState(_this); } - } else if (xevent->type == MappingNotify || - (xevent->type == videodata->xkb_event && xkbEvent->any.xkb_type == XkbStateNotify)) { + } else if (xevent->type == MappingNotify) { /* Has the keyboard layout changed? */ const int request = xevent->xmapping.request; @@ -996,8 +1012,9 @@ X11_DispatchEvent(_THIS, XEvent *xevent) } break; - /* Key press? */ - case KeyPress:{ + /* Key press/release? */ + case KeyPress: + case KeyRelease: { KeyCode keycode = xevent->xkey.keycode; KeySym keysym = NoSymbol; char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; @@ -1005,7 +1022,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent) SDL_bool handled_by_ime = SDL_FALSE; #ifdef DEBUG_XEVENTS - printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent->xkey.keycode); + printf("window %p: %s (X11 keycode = 0x%X)\n", data, (xevent->type == KeyPress ? "KeyPress" : "KeyRelease"), xevent->xkey.keycode); #endif #if 1 if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) { @@ -1021,7 +1038,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent) /* */ SDL_zeroa(text); #ifdef X_HAVE_UTF8_STRING - if (data->ic) { + if (data->ic && xevent->type == KeyPress) { X11_Xutf8LookupString(data->ic, &xevent->xkey, text, sizeof(text), &keysym, &status); } else { @@ -1033,35 +1050,30 @@ X11_DispatchEvent(_THIS, XEvent *xevent) #ifdef SDL_USE_IME if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){ - handled_by_ime = SDL_IME_ProcessKeyEvent(keysym, keycode); + handled_by_ime = SDL_IME_ProcessKeyEvent(keysym, keycode, (xevent->type == KeyPress ? SDL_PRESSED : SDL_RELEASED)); } #endif if (!handled_by_ime) { - /* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */ - if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) { - SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]); - } - if(*text) { - SDL_SendKeyboardText(text); + if (xevent->type == KeyPress) { + /* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */ + if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) { + SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]); + } + if(*text) { + SDL_SendKeyboardText(text); + } + } else { + if (X11_KeyRepeat(display, xevent)) { + /* We're about to get a repeated key down, ignore the key up */ + break; + } + SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]); } } - X11_UpdateUserTime(data, xevent->xkey.time); - } - break; - - /* Key release? */ - case KeyRelease:{ - KeyCode keycode = xevent->xkey.keycode; - -#ifdef DEBUG_XEVENTS - printf("window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent->xkey.keycode); -#endif - if (X11_KeyRepeat(display, xevent)) { - /* We're about to get a repeated key down, ignore the key up */ - break; + if (xevent->type == KeyPress) { + X11_UpdateUserTime(data, xevent->xkey.time); } - SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]); } break; diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11events.h b/Engine/lib/sdl/src/video/x11/SDL_x11events.h index fc8a57ae2..de89110d0 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11events.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11events.h @@ -27,6 +27,7 @@ extern void X11_PumpEvents(_THIS); extern int X11_WaitEventTimeout(_THIS, int timeout); extern void X11_SendWakeupEvent(_THIS, SDL_Window *window); extern void X11_SuspendScreenSaver(_THIS); +extern void X11_ReconcileKeyboardState(_THIS); #endif /* SDL_x11events_h_ */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c b/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c index c82570c62..c84bcc798 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c @@ -409,6 +409,8 @@ X11_InitKeyboard(_THIS) SDL_IME_Init(); #endif + X11_ReconcileKeyboardState(_this); + return 0; } diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.c b/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.c index aafccca9b..9bc9702c0 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11messagebox.c @@ -830,10 +830,11 @@ X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) int exitcode = 0; close(fds[0]); status = X11_ShowMessageBoxImpl(messageboxdata, buttonid); - if (write(fds[1], &status, sizeof (int)) != sizeof (int)) + if (write(fds[1], &status, sizeof (int)) != sizeof (int)) { exitcode = 1; - else if (write(fds[1], buttonid, sizeof (int)) != sizeof (int)) + } else if (write(fds[1], buttonid, sizeof (int)) != sizeof (int)) { exitcode = 1; + } close(fds[1]); _exit(exitcode); /* don't run atexit() stuff, static destructors, etc. */ } else { /* we're the parent */ @@ -846,13 +847,12 @@ X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) SDL_assert(rc == pid); /* not sure what to do if this fails. */ if ((rc == -1) || (!WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) { - return SDL_SetError("msgbox child process failed"); + status = SDL_SetError("msgbox child process failed"); + } else if ( (read(fds[0], &status, sizeof (int)) != sizeof (int)) || + (read(fds[0], buttonid, sizeof (int)) != sizeof (int)) ) { + status = SDL_SetError("read from msgbox child process failed"); + *buttonid = 0; } - - if (read(fds[0], &status, sizeof (int)) != sizeof (int)) - status = -1; - else if (read(fds[0], buttonid, sizeof (int)) != sizeof (int)) - status = -1; close(fds[0]); return status; diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11modes.c b/Engine/lib/sdl/src/video/x11/SDL_x11modes.c index c1efe243c..f2cbdb45f 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11modes.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11modes.c @@ -1011,7 +1011,13 @@ static int (*PreXRRSetScreenSizeErrorHandler)(Display *, XErrorEvent *) = NULL; static int SDL_XRRSetScreenSizeErrHandler(Display *d, XErrorEvent *e) { - return (e->error_code == BadMatch) ? 0 : PreXRRSetScreenSizeErrorHandler(d, e); + /* BadMatch: https://github.com/libsdl-org/SDL/issues/4561 */ + /* BadValue: https://github.com/libsdl-org/SDL/issues/4840 */ + if ((e->error_code == BadMatch) || (e->error_code == BadValue)) { + return 0; + } + + return PreXRRSetScreenSizeErrorHandler(d, e); } int diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c b/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c index 64b06340a..3e17e97ff 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c @@ -247,11 +247,6 @@ X11_GL_LoadLibrary(_THIS, const char *path) X11_GL_UseEGL(_this) ) { #if SDL_VIDEO_OPENGL_EGL X11_GL_UnloadLibrary(_this); - /* Better avoid conflicts! */ - if (_this->gl_config.dll_handle != NULL ) { - GL_UnloadObject(_this->gl_config.dll_handle); - _this->gl_config.dll_handle = NULL; - } _this->GL_LoadLibrary = X11_GLES_LoadLibrary; _this->GL_GetProcAddress = X11_GLES_GetProcAddress; _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary; diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11sym.h b/Engine/lib/sdl/src/video/x11/SDL_x11sym.h index 67b0a793a..762a86596 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11sym.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11sym.h @@ -185,7 +185,6 @@ SDL_X11_SYM(XkbDescPtr,XkbGetMap,(Display* a,unsigned int b,unsigned int c),(a,b SDL_X11_SYM(void,XkbFreeClientMap,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),) SDL_X11_SYM(void,XkbFreeKeyboard,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),) SDL_X11_SYM(Bool,XkbSetDetectableAutoRepeat,(Display* a, Bool b, Bool* c),(a,b,c),return) -SDL_X11_SYM(Bool,XkbSelectEvents,(Display* a, unsigned int b, unsigned int c, unsigned int d),(a,b,c,d),return) #endif #if NeedWidePrototypes diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11window.c b/Engine/lib/sdl/src/video/x11/SDL_x11window.c index a6bd91d72..d31ac012a 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11window.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11window.c @@ -678,8 +678,6 @@ X11_CreateWindow(_THIS, SDL_Window * window) /* For _ICC_PROFILE. */ X11_XSelectInput(display, RootWindow(display, screen), PropertyChangeMask); - X11_XkbSelectEvents(display, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask); - X11_XFlush(display); return 0; @@ -782,11 +780,22 @@ X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) X11_XFlush(display); } +static SDL_bool caught_x11_error = SDL_FALSE; +static int +X11_CatchAnyError(Display * d, XErrorEvent * e) +{ + /* this may happen during tumultuous times when we are polling anyhow, + so just note we had an error and return control. */ + caught_x11_error = SDL_TRUE; + return 0; +} + void X11_SetWindowPosition(_THIS, SDL_Window * window) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; + int (*prev_handler) (Display *, XErrorEvent *) = NULL; unsigned int childCount; Window childReturn, root, parent; Window* children; @@ -805,20 +814,27 @@ X11_SetWindowPosition(_THIS, SDL_Window * window) /* Wait a brief time to see if the window manager decided to let this move happen. If the window changes at all, even to an unexpected value, we break out. */ + X11_XSync(display, False); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + timeout = SDL_GetTicks() + 100; while (SDL_TRUE) { int x, y; + + caught_x11_error = SDL_FALSE; X11_XSync(display, False); X11_XGetWindowAttributes(display, data->xwindow, &attrs); X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), attrs.x, attrs.y, &x, &y, &childReturn); - if ((x != orig_x) || (y != orig_y)) { - window->x = x; - window->y = y; - break; /* window moved, time to go. */ - } else if ((x == window->x) && (y == window->y)) { - break; /* we're at the place we wanted to be anyhow, drop out. */ + if (!caught_x11_error) { + if ((x != orig_x) || (y != orig_y)) { + window->x = x; + window->y = y; + break; /* window moved, time to go. */ + } else if ((x == window->x) && (y == window->y)) { + break; /* we're at the place we wanted to be anyhow, drop out. */ + } } if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { @@ -827,6 +843,9 @@ X11_SetWindowPosition(_THIS, SDL_Window * window) SDL_Delay(10); } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; } void @@ -892,6 +911,7 @@ X11_SetWindowSize(_THIS, SDL_Window * window) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; + int (*prev_handler) (Display *, XErrorEvent *) = NULL; XWindowAttributes attrs; int orig_w, orig_h; Uint32 timeout; @@ -943,19 +963,25 @@ X11_SetWindowSize(_THIS, SDL_Window * window) X11_XResizeWindow(display, data->xwindow, window->w, window->h); } + X11_XSync(display, False); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + /* Wait a brief time to see if the window manager decided to let this resize happen. If the window changes at all, even to an unexpected value, we break out. */ timeout = SDL_GetTicks() + 100; while (SDL_TRUE) { + caught_x11_error = SDL_FALSE; X11_XSync(display, False); X11_XGetWindowAttributes(display, data->xwindow, &attrs); - if ((attrs.width != orig_w) || (attrs.height != orig_h)) { - window->w = attrs.width; - window->h = attrs.height; - break; /* window changed, time to go. */ - } else if ((attrs.width == window->w) && (attrs.height == window->h)) { - break; /* we're at the place we wanted to be anyhow, drop out. */ + if (!caught_x11_error) { + if ((attrs.width != orig_w) || (attrs.height != orig_h)) { + window->w = attrs.width; + window->h = attrs.height; + break; /* window changed, time to go. */ + } else if ((attrs.width == window->w) && (attrs.height == window->h)) { + break; /* we're at the place we wanted to be anyhow, drop out. */ + } } if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { @@ -964,6 +990,9 @@ X11_SetWindowSize(_THIS, SDL_Window * window) SDL_Delay(10); } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; } int @@ -1281,6 +1310,22 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis if (X11_IsWindowMapped(_this, window)) { XEvent e; + /* !!! FIXME: most of this waiting code is copy/pasted from elsewhere. */ + int (*prev_handler) (Display *, XErrorEvent *) = NULL; + unsigned int childCount; + Window childReturn, root, parent; + Window* children; + XWindowAttributes attrs; + int orig_w, orig_h, orig_x, orig_y; + Uint64 timeout; + + X11_XSync(display, False); + X11_XQueryTree(display, data->xwindow, &root, &parent, &children, &childCount); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &orig_x, &orig_y, &childReturn); + orig_w = attrs.width; + orig_h = attrs.height; if (!(window->flags & SDL_WINDOW_RESIZABLE)) { /* Compiz refuses fullscreen toggle if we're not resizable, so update the hints so we @@ -1330,6 +1375,41 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, SubstructureNotifyMask | SubstructureRedirectMask, &e); } + + /* Wait a brief time to see if the window manager decided to let this happen. + If the window changes at all, even to an unexpected value, we break out. */ + X11_XSync(display, False); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + + timeout = SDL_GetTicks64() + 100; + while (SDL_TRUE) { + int x, y; + + caught_x11_error = SDL_FALSE; + X11_XSync(display, False); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &x, &y, &childReturn); + + if (!caught_x11_error) { + if ((x != orig_x) || (y != orig_y) || (attrs.width != orig_w) || (attrs.height != orig_h)) { + window->x = x; + window->y = y; + window->w = attrs.width; + window->h = attrs.height; + break; /* window moved, time to go. */ + } + } + + if (SDL_GetTicks64() >= timeout) { + break; + } + + SDL_Delay(10); + } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; } else { Uint32 flags; diff --git a/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb_sse_func.h b/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb_sse_func.h index 3c5ee0db4..f541017a4 100644 --- a/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb_sse_func.h +++ b/Engine/lib/sdl/src/video/yuv2rgb/yuv_rgb_sse_func.h @@ -426,9 +426,17 @@ void SSE_FUNCTION_NAME(uint32_t width, uint32_t height, const int fix_read_nv12 = 0; #endif +#if YUV_FORMAT == YUV_FORMAT_422 + /* Avoid invalid read on last line */ + const int fix_read_422 = 1; +#else + const int fix_read_422 = 0; +#endif + + if (width >= 32) { uint32_t xpos, ypos; - for(ypos=0; ypos<(height-(uv_y_sample_interval-1)); ypos+=uv_y_sample_interval) + for(ypos=0; ypos<(height-(uv_y_sample_interval-1)) - fix_read_422; ypos+=uv_y_sample_interval) { const uint8_t *y_ptr1=Y+ypos*Y_stride, *y_ptr2=Y+(ypos+1)*Y_stride, @@ -459,6 +467,15 @@ void SSE_FUNCTION_NAME(uint32_t width, uint32_t height, } } + if (fix_read_422) { + const uint8_t *y_ptr=Y+ypos*Y_stride, + *u_ptr=U+(ypos/uv_y_sample_interval)*UV_stride, + *v_ptr=V+(ypos/uv_y_sample_interval)*UV_stride; + uint8_t *rgb_ptr=RGB+ypos*RGB_stride; + STD_FUNCTION_NAME(width, 1, y_ptr, u_ptr, v_ptr, Y_stride, UV_stride, rgb_ptr, RGB_stride, yuv_type); + ypos += uv_y_sample_interval; + } + /* Catch the last line, if needed */ if (uv_y_sample_interval == 2 && ypos == (height-1)) { diff --git a/Engine/lib/sdl/test/Makefile.in b/Engine/lib/sdl/test/Makefile.in index d29dc6ecf..f724618c6 100644 --- a/Engine/lib/sdl/test/Makefile.in +++ b/Engine/lib/sdl/test/Makefile.in @@ -364,6 +364,7 @@ DATA = \ testgles2_sdf_img_sdf.bmp \ testyuv.bmp \ unifont-13.0.06.hex \ + utf8.txt \ $(NULL) ifneq ($(srcdir), .) diff --git a/Engine/lib/sdl/test/testautomation_rect.c b/Engine/lib/sdl/test/testautomation_rect.c index 26f03e9bb..cd8f65c34 100644 --- a/Engine/lib/sdl/test/testautomation_rect.c +++ b/Engine/lib/sdl/test/testautomation_rect.c @@ -408,6 +408,32 @@ void _validateRectEqualsResults( refRectB->x, refRectB->y, refRectB->w, refRectB->h); } +/* ! + * \brief Private helper to check SDL_FRectEquals results + */ +void _validateFRectEqualsResults( + SDL_bool equals, SDL_bool expectedEquals, + SDL_FRect *rectA, SDL_FRect *rectB, SDL_FRect *refRectA, SDL_FRect *refRectB) +{ + int cmpRes; + SDLTest_AssertCheck(equals == expectedEquals, + "Check for correct equals result: expected %s, got %s testing (%f,%f,%f,%f) and (%f,%f,%f,%f)", + (expectedEquals == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", + (equals == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", + rectA->x, rectA->y, rectA->w, rectA->h, + rectB->x, rectB->y, rectB->w, rectB->h); + cmpRes = SDL_memcmp(rectA, refRectA, sizeof(*rectA)); + SDLTest_AssertCheck(cmpRes == 0, + "Check that source rectangle A was not modified: got (%f,%f,%f,%f) expected (%f,%f,%f,%f)", + rectA->x, rectA->y, rectA->w, rectA->h, + refRectA->x, refRectA->y, refRectA->w, refRectA->h); + cmpRes = SDL_memcmp(rectB, refRectB, sizeof(*rectB)); + SDLTest_AssertCheck(cmpRes == 0, + "Check that source rectangle B was not modified: got (%f,%f,%f,%f) expected (%f,%f,%f,%f)", + rectB->x, rectB->y, rectB->w, rectB->h, + refRectB->x, refRectB->y, refRectB->w, refRectB->h); +} + /* ! * \brief Tests SDL_IntersectRect() with B fully inside A * @@ -1574,6 +1600,69 @@ int rect_testRectEqualsParam(void *arg) return TEST_COMPLETED; } +/* ! + * \brief Tests SDL_FRectEquals() with various inputs + * + * \sa + * http://wiki.libsdl.org/SDL_FRectEquals + */ +int rect_testFRectEquals(void *arg) +{ + SDL_FRect refRectA; + SDL_FRect refRectB; + SDL_FRect rectA; + SDL_FRect rectB; + SDL_bool expectedResult; + SDL_bool result; + + /* Equals */ + refRectA.x=(float)SDLTest_RandomIntegerInRange(-1024, 1024); + refRectA.y=(float)SDLTest_RandomIntegerInRange(-1024, 1024); + refRectA.w=(float)SDLTest_RandomIntegerInRange(1, 1024); + refRectA.h=(float)SDLTest_RandomIntegerInRange(1, 1024); + refRectB = refRectA; + expectedResult = SDL_TRUE; + rectA = refRectA; + rectB = refRectB; + result = (SDL_bool)SDL_FRectEquals((const SDL_FRect *)&rectA, (const SDL_FRect *)&rectB); + _validateFRectEqualsResults(result, expectedResult, &rectA, &rectB, &refRectA, &refRectB); + + return TEST_COMPLETED; +} + +/* ! + * \brief Negative tests against SDL_FRectEquals() with invalid parameters + * + * \sa + * http://wiki.libsdl.org/SDL_FRectEquals + */ +int rect_testFRectEqualsParam(void *arg) +{ + SDL_FRect rectA; + SDL_FRect rectB; + SDL_bool result; + + /* data setup -- For the purpose of this test, the values don't matter. */ + rectA.x=SDLTest_RandomFloat(); + rectA.y=SDLTest_RandomFloat(); + rectA.w=SDLTest_RandomFloat(); + rectA.h=SDLTest_RandomFloat(); + rectB.x=SDLTest_RandomFloat(); + rectB.y=SDLTest_RandomFloat(); + rectB.w=SDLTest_RandomFloat(); + rectB.h=SDLTest_RandomFloat(); + + /* invalid parameter combinations */ + result = (SDL_bool)SDL_FRectEquals((const SDL_FRect *)NULL, (const SDL_FRect *)&rectB); + SDLTest_AssertCheck(result == SDL_FALSE, "Check that function returns SDL_FALSE when 1st parameter is NULL"); + result = (SDL_bool)SDL_FRectEquals((const SDL_FRect *)&rectA, (const SDL_FRect *)NULL); + SDLTest_AssertCheck(result == SDL_FALSE, "Check that function returns SDL_FALSE when 2nd parameter is NULL"); + result = (SDL_bool)SDL_FRectEquals((const SDL_FRect *)NULL, (const SDL_FRect *)NULL); + SDLTest_AssertCheck(result == SDL_FALSE, "Check that function returns SDL_FALSE when 1st and 2nd parameter are NULL"); + + return TEST_COMPLETED; +} + /* ================= Test References ================== */ /* Rect test cases */ @@ -1673,6 +1762,13 @@ static const SDLTest_TestCaseReference rectTest28 = static const SDLTest_TestCaseReference rectTest29 = { (SDLTest_TestCaseFp)rect_testRectEqualsParam, "rect_testRectEqualsParam", "Negative tests against SDL_RectEquals with invalid parameters", TEST_ENABLED }; +/* SDL_FRectEquals */ + +static const SDLTest_TestCaseReference rectTest30 = + { (SDLTest_TestCaseFp)rect_testFRectEquals, "rect_testFRectEquals", "Tests SDL_FRectEquals with various inputs", TEST_ENABLED }; + +static const SDLTest_TestCaseReference rectTest31 = + { (SDLTest_TestCaseFp)rect_testFRectEqualsParam, "rect_testFRectEqualsParam", "Negative tests against SDL_FRectEquals with invalid parameters", TEST_ENABLED }; /* ! * \brief Sequence of Rect test cases; functions that handle simple rectangles including overlaps and merges. @@ -1683,7 +1779,7 @@ static const SDLTest_TestCaseReference rectTest29 = static const SDLTest_TestCaseReference *rectTests[] = { &rectTest1, &rectTest2, &rectTest3, &rectTest4, &rectTest5, &rectTest6, &rectTest7, &rectTest8, &rectTest9, &rectTest10, &rectTest11, &rectTest12, &rectTest13, &rectTest14, &rectTest15, &rectTest16, &rectTest17, &rectTest18, &rectTest19, &rectTest20, &rectTest21, &rectTest22, &rectTest23, &rectTest24, &rectTest25, &rectTest26, &rectTest27, - &rectTest28, &rectTest29, NULL + &rectTest28, &rectTest29, &rectTest30, &rectTest31, NULL }; diff --git a/Engine/lib/sdl/test/testevdev.c b/Engine/lib/sdl/test/testevdev.c index 572c60a05..76a12ef7e 100644 --- a/Engine/lib/sdl/test/testevdev.c +++ b/Engine/lib/sdl/test/testevdev.c @@ -41,6 +41,7 @@ static const struct CLS(SOUND), CLS(TOUCHSCREEN), CLS(ACCELEROMETER), + CLS(TOUCHPAD), #undef CLS { 0, NULL } }; @@ -185,9 +186,7 @@ static const GuessTest guess_tests[] = .bus_type = 0x0003, .vendor_id = 0x054c, .product_id = 0x09cc, - /* TODO: Should this be MOUSE? That's what it most closely - * resembles */ - .expected = SDL_UDEV_DEVICE_UNKNOWN, + .expected = SDL_UDEV_DEVICE_TOUCHPAD, /* SYN, KEY, ABS */ .ev = { 0x0b }, /* X, Y, multitouch */ @@ -596,7 +595,7 @@ static const GuessTest guess_tests[] = * to the arrow, page up and page down keys, so it's a joystick * with a subset of a keyboard attached. */ /* TODO: Should this be JOYSTICK, or even JOYSTICK|KEYBOARD? */ - .expected = SDL_UDEV_DEVICE_UNKNOWN, + .expected = SDL_UDEV_DEVICE_KEYBOARD, /* SYN, KEY */ .ev = { 0x03 }, .keys = { @@ -608,7 +607,7 @@ static const GuessTest guess_tests[] = /* BTN_1, BTN_2, BTN_A, BTN_B, BTN_MODE */ /* 0x100 */ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, /* 0x140 */ ZEROx8, - /* next, previous */ + /* next (keyboard page down), previous (keyboard page up) */ /* 0x180 */ 0x00, 0x00, 0x80, 0x10, ZEROx4, }, }, @@ -659,7 +658,7 @@ static const GuessTest guess_tests[] = .name = "Wiimote - Classic Controller", /* TODO: Should this be JOYSTICK, or maybe JOYSTICK|KEYBOARD? * It's unusual in the same ways as the Wiimote */ - .expected = SDL_UDEV_DEVICE_UNKNOWN, + .expected = SDL_UDEV_DEVICE_KEYBOARD, /* SYN, KEY, ABS */ .ev = { 0x0b }, /* Hat 1-3 */ @@ -673,7 +672,7 @@ static const GuessTest guess_tests[] = /* A, B, X, Y, MODE, TL, TL2, TR, TR2 */ /* 0x100 */ ZEROx4, 0x00, 0x13, 0xdb, 0x10, /* 0x140 */ ZEROx8, - /* next, previous */ + /* next (keyboard page down), previous (keyboard page up) */ /* 0x180 */ 0x00, 0x00, 0x80, 0x10, ZEROx4, }, }, @@ -718,9 +717,7 @@ static const GuessTest guess_tests[] = .vendor_id = 0x06cb, .product_id = 0x0000, .version = 0x0000, - /* TODO: Should this be MOUSE? That's what it most closely - * resembles */ - .expected = SDL_UDEV_DEVICE_UNKNOWN, + .expected = SDL_UDEV_DEVICE_TOUCHPAD, /* SYN, KEY, ABS */ .ev = { 0x0b }, /* X, Y, pressure, multitouch */ @@ -756,7 +753,8 @@ static const GuessTest guess_tests[] = }, { .name = "Thinkpad ACPI buttons", - .expected = SDL_UDEV_DEVICE_UNKNOWN, + /* SDL treats this as a keyboard because it has a power button */ + .expected = SDL_UDEV_DEVICE_KEYBOARD, /* SYN, KEY, MSC, SW */ .ev = { 0x33 }, .keys = { @@ -815,7 +813,8 @@ static const GuessTest guess_tests[] = .vendor_id = 0x0000, .product_id = 0x0003, .version = 0x0000, - .expected = SDL_UDEV_DEVICE_UNKNOWN, + /* SDL treats KEY_SLEEP as indicating a keyboard */ + .expected = SDL_UDEV_DEVICE_KEYBOARD, /* SYN, KEY */ .ev = { 0x03 }, .keys = { @@ -841,7 +840,8 @@ static const GuessTest guess_tests[] = .vendor_id = 0x0000, .product_id = 0x0001, .version = 0x0000, - .expected = SDL_UDEV_DEVICE_UNKNOWN, + /* SDL treats KEY_POWER as indicating a keyboard */ + .expected = SDL_UDEV_DEVICE_KEYBOARD, /* SYN, KEY */ .ev = { 0x03 }, .keys = { @@ -856,7 +856,8 @@ static const GuessTest guess_tests[] = .vendor_id = 0x0000, .product_id = 0x0006, .version = 0x0000, - .expected = SDL_UDEV_DEVICE_UNKNOWN, + /* SDL treats brightness control, etc. as keyboard keys */ + .expected = SDL_UDEV_DEVICE_KEYBOARD, /* SYN, KEY */ .ev = { 0x03 }, .keys = { @@ -873,7 +874,7 @@ static const GuessTest guess_tests[] = .vendor_id = 0x17aa, .product_id = 0x5054, .version = 0x4101, - .expected = SDL_UDEV_DEVICE_UNKNOWN, + .expected = SDL_UDEV_DEVICE_KEYBOARD, /* SYN, KEY */ .ev = { 0x03 }, .keys = { @@ -911,9 +912,8 @@ static const GuessTest guess_tests[] = .product_id = 0x6009, /* For some reason the special keys like mute and wlan toggle * show up here instead of, or in addition to, as part of - * the keyboard - so udev reports this as having keys too. - * SDL currently doesn't. */ - .expected = SDL_UDEV_DEVICE_MOUSE, + * the keyboard - so both udev and SDL report this as having keys too. */ + .expected = SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD, /* SYN, KEY, REL, MSC, LED */ .ev = { 0x17, 0x00, 0x02 }, /* X, Y */ diff --git a/Engine/lib/sdl/test/testgles2.c b/Engine/lib/sdl/test/testgles2.c index 153ebe499..c42835ebb 100644 --- a/Engine/lib/sdl/test/testgles2.c +++ b/Engine/lib/sdl/test/testgles2.c @@ -38,6 +38,18 @@ typedef struct GLES2_Context #undef SDL_PROC } GLES2_Context; +typedef struct shader_data +{ + GLuint shader_program, shader_frag, shader_vert; + + GLint attr_position; + GLint attr_color, attr_mvp; + + int angle_x, angle_y, angle_z; + + GLuint position_buffer; + GLuint color_buffer; +} shader_data; static SDLTest_CommonState *state; static SDL_GLContext *context = NULL; @@ -197,13 +209,13 @@ multiply_matrix(float *lhs, float *rhs, float *r) * source: Passed-in shader source code. * shader_type: Passed to GL, e.g. GL_VERTEX_SHADER. */ -void +static void process_shader(GLuint *shader, const char * source, GLint shader_type) { GLint status = GL_FALSE; const char *shaders[1] = { NULL }; char buffer[1024]; - GLsizei length; + GLsizei length = 0; /* Create shader and load into GL. */ *shader = GL_CHECK(ctx.glCreateShader(shader_type)); @@ -221,13 +233,35 @@ process_shader(GLuint *shader, const char * source, GLint shader_type) /* Dump debug info (source and log) if compilation failed. */ if(status != GL_TRUE) { - ctx.glGetProgramInfoLog(*shader, sizeof(buffer), &length, &buffer[0]); + ctx.glGetShaderInfoLog(*shader, sizeof(buffer), &length, &buffer[0]); buffer[length] = '\0'; - SDL_Log("Shader compilation failed: %s", buffer);fflush(stderr); + SDL_Log("Shader compilation failed: %s", buffer); + fflush(stderr); quit(-1); } } +static void +link_program(struct shader_data *data) +{ + GLint status = GL_FALSE; + char buffer[1024]; + GLsizei length = 0; + + GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert)); + GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag)); + GL_CHECK(ctx.glLinkProgram(data->shader_program)); + GL_CHECK(ctx.glGetProgramiv(data->shader_program, GL_LINK_STATUS, &status)); + + if(status != GL_TRUE) { + ctx.glGetProgramInfoLog(data->shader_program, sizeof(buffer), &length, &buffer[0]); + buffer[length] = '\0'; + SDL_Log("Program linking failed: %s", buffer); + fflush(stderr); + quit(-1); + } +} + /* 3D data. Vertex range -0.5..0.5 in all axes. * Z -0.5 is near, 0.5 is far. */ const float _vertices[] = @@ -363,19 +397,6 @@ const char* _shader_frag_src = " gl_FragColor = vec4(vv3color, 1.0); " " } "; -typedef struct shader_data -{ - GLuint shader_program, shader_frag, shader_vert; - - GLint attr_position; - GLint attr_color, attr_mvp; - - int angle_x, angle_y, angle_z; - - GLuint position_buffer; - GLuint color_buffer; -} shader_data; - static void Render(unsigned int width, unsigned int height, shader_data* data) { @@ -672,9 +693,7 @@ main(int argc, char *argv[]) data->shader_program = GL_CHECK(ctx.glCreateProgram()); /* Attach shaders and link shader_program */ - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert)); - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag)); - GL_CHECK(ctx.glLinkProgram(data->shader_program)); + link_program(data); /* Get attribute locations of non-fixed attributes like color and texture coordinates. */ data->attr_position = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av4position")); @@ -693,13 +712,13 @@ main(int argc, char *argv[]) GL_CHECK(ctx.glGenBuffers(1, &data->position_buffer)); GL_CHECK(ctx.glBindBuffer(GL_ARRAY_BUFFER, data->position_buffer)); - GL_CHECK(ctx.glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices) * 4, _vertices, GL_STATIC_DRAW)); + GL_CHECK(ctx.glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices), _vertices, GL_STATIC_DRAW)); GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, 0)); GL_CHECK(ctx.glBindBuffer(GL_ARRAY_BUFFER, 0)); GL_CHECK(ctx.glGenBuffers(1, &data->color_buffer)); GL_CHECK(ctx.glBindBuffer(GL_ARRAY_BUFFER, data->color_buffer)); - GL_CHECK(ctx.glBufferData(GL_ARRAY_BUFFER, sizeof(_colors) * 4, _colors, GL_STATIC_DRAW)); + GL_CHECK(ctx.glBufferData(GL_ARRAY_BUFFER, sizeof(_colors), _colors, GL_STATIC_DRAW)); GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, 0)); GL_CHECK(ctx.glBindBuffer(GL_ARRAY_BUFFER, 0)); diff --git a/Engine/lib/sdl/test/testmouse.c b/Engine/lib/sdl/test/testmouse.c index c73adca51..11a176066 100644 --- a/Engine/lib/sdl/test/testmouse.c +++ b/Engine/lib/sdl/test/testmouse.c @@ -39,6 +39,11 @@ static Line *active = NULL; static Line *lines = NULL; static int buttons = 0; +static SDL_bool wheel_x_active = SDL_FALSE; +static SDL_bool wheel_y_active = SDL_FALSE; +static float wheel_x = SCREEN_WIDTH * 0.5f; +static float wheel_y = SCREEN_HEIGHT * 0.5f; + static SDL_bool done = SDL_FALSE; void @@ -81,6 +86,25 @@ loop(void *arg) /* Check for events */ while (SDL_PollEvent(&event)) { switch (event.type) { + case SDL_MOUSEWHEEL: + if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) { + event.wheel.preciseX *= -1.0f; + event.wheel.preciseY *= -1.0f; + event.wheel.x *= -1; + event.wheel.y *= -1; + } + if (event.wheel.preciseX != 0.0f) { + wheel_x_active = SDL_TRUE; + /* "positive to the right and negative to the left" */ + wheel_x += event.wheel.preciseX * 10.0f; + } + if (event.wheel.preciseY != 0.0f) { + wheel_y_active = SDL_TRUE; + /* "positive away from the user and negative towards the user" */ + wheel_y -= event.wheel.preciseY * 10.0f; + } + break; + case SDL_MOUSEMOTION: if (!active) break; @@ -134,6 +158,16 @@ loop(void *arg) SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); + /* Mouse wheel */ + SDL_SetRenderDrawColor(renderer, 0, 255, 128, 255); + if (wheel_x_active) { + SDL_RenderDrawLine(renderer, wheel_x, 0, wheel_x, SCREEN_HEIGHT); + } + if (wheel_y_active) { + SDL_RenderDrawLine(renderer, 0, wheel_y, SCREEN_WIDTH, wheel_y); + } + + /* Lines from mouse clicks */ DrawLines(renderer); if (active) DrawLine(renderer, active); diff --git a/Engine/lib/sdl/test/testshader.c b/Engine/lib/sdl/test/testshader.c index 2cee7d9b3..3c2da590f 100644 --- a/Engine/lib/sdl/test/testshader.c +++ b/Engine/lib/sdl/test/testshader.c @@ -126,21 +126,52 @@ static PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB; static SDL_bool CompileShader(GLhandleARB shader, const char *source) { - GLint status; + GLint status = 0; glShaderSourceARB(shader, 1, &source, NULL); glCompileShaderARB(shader); glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &status); if (status == 0) { - GLint length; + GLint length = 0; char *info; glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); - info = SDL_stack_alloc(char, length+1); - glGetInfoLogARB(shader, length, NULL, info); - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to compile shader:\n%s\n%s", source, info); - SDL_stack_free(info); + info = (char *) SDL_malloc(length + 1); + if (!info) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!"); + } else { + glGetInfoLogARB(shader, length, NULL, info); + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to compile shader:\n%s\n%s", source, info); + SDL_free(info); + } + return SDL_FALSE; + } else { + return SDL_TRUE; + } +} +static SDL_bool LinkProgram(ShaderData *data) +{ + GLint status = 0; + + glAttachObjectARB(data->program, data->vert_shader); + glAttachObjectARB(data->program, data->frag_shader); + glLinkProgramARB(data->program); + + glGetObjectParameterivARB(data->program, GL_OBJECT_LINK_STATUS_ARB, &status); + if (status == 0) { + GLint length = 0; + char *info; + + glGetObjectParameterivARB(data->program, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); + info = (char *) SDL_malloc(length + 1); + if (!info) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!"); + } else { + glGetInfoLogARB(data->program, length, NULL, info); + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to link program:\n%s", info); + SDL_free(info); + } return SDL_FALSE; } else { return SDL_TRUE; @@ -171,9 +202,9 @@ static SDL_bool CompileShaderProgram(ShaderData *data) } /* ... and in the darkness bind them */ - glAttachObjectARB(data->program, data->vert_shader); - glAttachObjectARB(data->program, data->frag_shader); - glLinkProgramARB(data->program); + if (!LinkProgram(data)) { + return SDL_FALSE; + } /* Set up some uniform variables */ glUseProgramObjectARB(data->program); diff --git a/Engine/lib/sdl/wayland-protocols/tablet-unstable-v2.xml b/Engine/lib/sdl/wayland-protocols/tablet-unstable-v2.xml new file mode 100644 index 000000000..b286d964a --- /dev/null +++ b/Engine/lib/sdl/wayland-protocols/tablet-unstable-v2.xml @@ -0,0 +1,1178 @@ + + + + + Copyright 2014 © Stephen "Lyude" Chandler Paul + Copyright 2015-2016 © Red Hat, Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + + + This description provides a high-level overview of the interplay between + the interfaces defined this protocol. For details, see the protocol + specification. + + More than one tablet may exist, and device-specifics matter. Tablets are + not represented by a single virtual device like wl_pointer. A client + binds to the tablet manager object which is just a proxy object. From + that, the client requests wp_tablet_manager.get_tablet_seat(wl_seat) + and that returns the actual interface that has all the tablets. With + this indirection, we can avoid merging wp_tablet into the actual Wayland + protocol, a long-term benefit. + + The wp_tablet_seat sends a "tablet added" event for each tablet + connected. That event is followed by descriptive events about the + hardware; currently that includes events for name, vid/pid and + a wp_tablet.path event that describes a local path. This path can be + used to uniquely identify a tablet or get more information through + libwacom. Emulated or nested tablets can skip any of those, e.g. a + virtual tablet may not have a vid/pid. The sequence of descriptive + events is terminated by a wp_tablet.done event to signal that a client + may now finalize any initialization for that tablet. + + Events from tablets require a tool in proximity. Tools are also managed + by the tablet seat; a "tool added" event is sent whenever a tool is new + to the compositor. That event is followed by a number of descriptive + events about the hardware; currently that includes capabilities, + hardware id and serial number, and tool type. Similar to the tablet + interface, a wp_tablet_tool.done event is sent to terminate that initial + sequence. + + Any event from a tool happens on the wp_tablet_tool interface. When the + tool gets into proximity of the tablet, a proximity_in event is sent on + the wp_tablet_tool interface, listing the tablet and the surface. That + event is followed by a motion event with the coordinates. After that, + it's the usual motion, axis, button, etc. events. The protocol's + serialisation means events are grouped by wp_tablet_tool.frame events. + + Two special events (that don't exist in X) are down and up. They signal + "tip touching the surface". For tablets without real proximity + detection, the sequence is: proximity_in, motion, down, frame. + + When the tool leaves proximity, a proximity_out event is sent. If any + button is still down, a button release event is sent before this + proximity event. These button events are sent in the same frame as the + proximity event to signal to the client that the buttons were held when + the tool left proximity. + + If the tool moves out of the surface but stays in proximity (i.e. + between windows), compositor-specific grab policies apply. This usually + means that the proximity-out is delayed until all buttons are released. + + Moving a tool physically from one tablet to the other has no real effect + on the protocol, since we already have the tool object from the "tool + added" event. All the information is already there and the proximity + events on both tablets are all a client needs to reconstruct what + happened. + + Some extra axes are normalized, i.e. the client knows the range as + specified in the protocol (e.g. [0, 65535]), the granularity however is + unknown. The current normalized axes are pressure, distance, and slider. + + Other extra axes are in physical units as specified in the protocol. + The current extra axes with physical units are tilt, rotation and + wheel rotation. + + Since tablets work independently of the pointer controlled by the mouse, + the focus handling is independent too and controlled by proximity. + The wp_tablet_tool.set_cursor request sets a tool-specific cursor. + This cursor surface may be the same as the mouse cursor, and it may be + the same across tools but it is possible to be more fine-grained. For + example, a client may set different cursors for the pen and eraser. + + Tools are generally independent of tablets and it is + compositor-specific policy when a tool can be removed. Common approaches + will likely include some form of removing a tool when all tablets the + tool was used on are removed. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + + + + + An object that provides access to the graphics tablets available on this + system. All tablets are associated with a seat, to get access to the + actual tablets, use wp_tablet_manager.get_tablet_seat. + + + + + Get the wp_tablet_seat object for the given seat. This object + provides access to all graphics tablets in this seat. + + + + + + + + Destroy the wp_tablet_manager object. Objects created from this + object are unaffected and should be destroyed separately. + + + + + + + An object that provides access to the graphics tablets available on this + seat. After binding to this interface, the compositor sends a set of + wp_tablet_seat.tablet_added and wp_tablet_seat.tool_added events. + + + + + Destroy the wp_tablet_seat object. Objects created from this + object are unaffected and should be destroyed separately. + + + + + + This event is sent whenever a new tablet becomes available on this + seat. This event only provides the object id of the tablet, any + static information about the tablet (device name, vid/pid, etc.) is + sent through the wp_tablet interface. + + + + + + + This event is sent whenever a tool that has not previously been used + with a tablet comes into use. This event only provides the object id + of the tool; any static information about the tool (capabilities, + type, etc.) is sent through the wp_tablet_tool interface. + + + + + + + This event is sent whenever a new pad is known to the system. Typically, + pads are physically attached to tablets and a pad_added event is + sent immediately after the wp_tablet_seat.tablet_added. + However, some standalone pad devices logically attach to tablets at + runtime, and the client must wait for wp_tablet_pad.enter to know + the tablet a pad is attached to. + + This event only provides the object id of the pad. All further + features (buttons, strips, rings) are sent through the wp_tablet_pad + interface. + + + + + + + + An object that represents a physical tool that has been, or is + currently in use with a tablet in this seat. Each wp_tablet_tool + object stays valid until the client destroys it; the compositor + reuses the wp_tablet_tool object to indicate that the object's + respective physical tool has come into proximity of a tablet again. + + A wp_tablet_tool object's relation to a physical tool depends on the + tablet's ability to report serial numbers. If the tablet supports + this capability, then the object represents a specific physical tool + and can be identified even when used on multiple tablets. + + A tablet tool has a number of static characteristics, e.g. tool type, + hardware_serial and capabilities. These capabilities are sent in an + event sequence after the wp_tablet_seat.tool_added event before any + actual events from this tool. This initial event sequence is + terminated by a wp_tablet_tool.done event. + + Tablet tool events are grouped by wp_tablet_tool.frame events. + Any events received before a wp_tablet_tool.frame event should be + considered part of the same hardware state change. + + + + + Sets the surface of the cursor used for this tool on the given + tablet. This request only takes effect if the tool is in proximity + of one of the requesting client's surfaces or the surface parameter + is the current pointer surface. If there was a previous surface set + with this request it is replaced. If surface is NULL, the cursor + image is hidden. + + The parameters hotspot_x and hotspot_y define the position of the + pointer surface relative to the pointer location. Its top-left corner + is always at (x, y) - (hotspot_x, hotspot_y), where (x, y) are the + coordinates of the pointer location, in surface-local coordinates. + + On surface.attach requests to the pointer surface, hotspot_x and + hotspot_y are decremented by the x and y parameters passed to the + request. Attach must be confirmed by wl_surface.commit as usual. + + The hotspot can also be updated by passing the currently set pointer + surface to this request with new values for hotspot_x and hotspot_y. + + The current and pending input regions of the wl_surface are cleared, + and wl_surface.set_input_region is ignored until the wl_surface is no + longer used as the cursor. When the use as a cursor ends, the current + and pending input regions become undefined, and the wl_surface is + unmapped. + + This request gives the surface the role of a wp_tablet_tool cursor. A + surface may only ever be used as the cursor surface for one + wp_tablet_tool. If the surface already has another role or has + previously been used as cursor surface for a different tool, a + protocol error is raised. + + + + + + + + + + This destroys the client's resource for this tool object. + + + + + + Describes the physical type of a tool. The physical type of a tool + generally defines its base usage. + + The mouse tool represents a mouse-shaped tool that is not a relative + device but bound to the tablet's surface, providing absolute + coordinates. + + The lens tool is a mouse-shaped tool with an attached lens to + provide precision focus. + + + + + + + + + + + + + + The tool type is the high-level type of the tool and usually decides + the interaction expected from this tool. + + This event is sent in the initial burst of events before the + wp_tablet_tool.done event. + + + + + + + If the physical tool can be identified by a unique 64-bit serial + number, this event notifies the client of this serial number. + + If multiple tablets are available in the same seat and the tool is + uniquely identifiable by the serial number, that tool may move + between tablets. + + Otherwise, if the tool has no serial number and this event is + missing, the tool is tied to the tablet it first comes into + proximity with. Even if the physical tool is used on multiple + tablets, separate wp_tablet_tool objects will be created, one per + tablet. + + This event is sent in the initial burst of events before the + wp_tablet_tool.done event. + + + + + + + + This event notifies the client of a hardware id available on this tool. + + The hardware id is a device-specific 64-bit id that provides extra + information about the tool in use, beyond the wl_tool.type + enumeration. The format of the id is specific to tablets made by + Wacom Inc. For example, the hardware id of a Wacom Grip + Pen (a stylus) is 0x802. + + This event is sent in the initial burst of events before the + wp_tablet_tool.done event. + + + + + + + + Describes extra capabilities on a tablet. + + Any tool must provide x and y values, extra axes are + device-specific. + + + + + + + + + + + + This event notifies the client of any capabilities of this tool, + beyond the main set of x/y axes and tip up/down detection. + + One event is sent for each extra capability available on this tool. + + This event is sent in the initial burst of events before the + wp_tablet_tool.done event. + + + + + + + This event signals the end of the initial burst of descriptive + events. A client may consider the static description of the tool to + be complete and finalize initialization of the tool. + + + + + + This event is sent when the tool is removed from the system and will + send no further events. Should the physical tool come back into + proximity later, a new wp_tablet_tool object will be created. + + It is compositor-dependent when a tool is removed. A compositor may + remove a tool on proximity out, tablet removal or any other reason. + A compositor may also keep a tool alive until shutdown. + + If the tool is currently in proximity, a proximity_out event will be + sent before the removed event. See wp_tablet_tool.proximity_out for + the handling of any buttons logically down. + + When this event is received, the client must wp_tablet_tool.destroy + the object. + + + + + + Notification that this tool is focused on a certain surface. + + This event can be received when the tool has moved from one surface to + another, or when the tool has come back into proximity above the + surface. + + If any button is logically down when the tool comes into proximity, + the respective button event is sent after the proximity_in event but + within the same frame as the proximity_in event. + + + + + + + + + Notification that this tool has either left proximity, or is no + longer focused on a certain surface. + + When the tablet tool leaves proximity of the tablet, button release + events are sent for each button that was held down at the time of + leaving proximity. These events are sent before the proximity_out + event but within the same wp_tablet.frame. + + If the tool stays within proximity of the tablet, but the focus + changes from one surface to another, a button release event may not + be sent until the button is actually released or the tool leaves the + proximity of the tablet. + + + + + + Sent whenever the tablet tool comes in contact with the surface of the + tablet. + + If the tool is already in contact with the tablet when entering the + input region, the client owning said region will receive a + wp_tablet.proximity_in event, followed by a wp_tablet.down + event and a wp_tablet.frame event. + + Note that this event describes logical contact, not physical + contact. On some devices, a compositor may not consider a tool in + logical contact until a minimum physical pressure threshold is + exceeded. + + + + + + + Sent whenever the tablet tool stops making contact with the surface of + the tablet, or when the tablet tool moves out of the input region + and the compositor grab (if any) is dismissed. + + If the tablet tool moves out of the input region while in contact + with the surface of the tablet and the compositor does not have an + ongoing grab on the surface, the client owning said region will + receive a wp_tablet.up event, followed by a wp_tablet.proximity_out + event and a wp_tablet.frame event. If the compositor has an ongoing + grab on this device, this event sequence is sent whenever the grab + is dismissed in the future. + + Note that this event describes logical contact, not physical + contact. On some devices, a compositor may not consider a tool out + of logical contact until physical pressure falls below a specific + threshold. + + + + + + Sent whenever a tablet tool moves. + + + + + + + + Sent whenever the pressure axis on a tool changes. The value of this + event is normalized to a value between 0 and 65535. + + Note that pressure may be nonzero even when a tool is not in logical + contact. See the down and up events for more details. + + + + + + + Sent whenever the distance axis on a tool changes. The value of this + event is normalized to a value between 0 and 65535. + + Note that distance may be nonzero even when a tool is not in logical + contact. See the down and up events for more details. + + + + + + + Sent whenever one or both of the tilt axes on a tool change. Each tilt + value is in degrees, relative to the z-axis of the tablet. + The angle is positive when the top of a tool tilts along the + positive x or y axis. + + + + + + + + Sent whenever the z-rotation axis on the tool changes. The + rotation value is in degrees clockwise from the tool's + logical neutral position. + + + + + + + Sent whenever the slider position on the tool changes. The + value is normalized between -65535 and 65535, with 0 as the logical + neutral position of the slider. + + The slider is available on e.g. the Wacom Airbrush tool. + + + + + + + Sent whenever the wheel on the tool emits an event. This event + contains two values for the same axis change. The degrees value is + in the same orientation as the wl_pointer.vertical_scroll axis. The + clicks value is in discrete logical clicks of the mouse wheel. This + value may be zero if the movement of the wheel was less + than one logical click. + + Clients should choose either value and avoid mixing degrees and + clicks. The compositor may accumulate values smaller than a logical + click and emulate click events when a certain threshold is met. + Thus, wl_tablet_tool.wheel events with non-zero clicks values may + have different degrees values. + + + + + + + + Describes the physical state of a button that produced the button event. + + + + + + + + Sent whenever a button on the tool is pressed or released. + + If a button is held down when the tool moves in or out of proximity, + button events are generated by the compositor. See + wp_tablet_tool.proximity_in and wp_tablet_tool.proximity_out for + details. + + + + + + + + + Marks the end of a series of axis and/or button updates from the + tablet. The Wayland protocol requires axis updates to be sent + sequentially, however all events within a frame should be considered + one hardware event. + + + + + + + + + + + + The wp_tablet interface represents one graphics tablet device. The + tablet interface itself does not generate events; all events are + generated by wp_tablet_tool objects when in proximity above a tablet. + + A tablet has a number of static characteristics, e.g. device name and + pid/vid. These capabilities are sent in an event sequence after the + wp_tablet_seat.tablet_added event. This initial event sequence is + terminated by a wp_tablet.done event. + + + + + This destroys the client's resource for this tablet object. + + + + + + This event is sent in the initial burst of events before the + wp_tablet.done event. + + + + + + + This event is sent in the initial burst of events before the + wp_tablet.done event. + + + + + + + + A system-specific device path that indicates which device is behind + this wp_tablet. This information may be used to gather additional + information about the device, e.g. through libwacom. + + A device may have more than one device path. If so, multiple + wp_tablet.path events are sent. A device may be emulated and not + have a device path, and in that case this event will not be sent. + + The format of the path is unspecified, it may be a device node, a + sysfs path, or some other identifier. It is up to the client to + identify the string provided. + + This event is sent in the initial burst of events before the + wp_tablet.done event. + + + + + + + This event is sent immediately to signal the end of the initial + burst of descriptive events. A client may consider the static + description of the tablet to be complete and finalize initialization + of the tablet. + + + + + + Sent when the tablet has been removed from the system. When a tablet + is removed, some tools may be removed. + + When this event is received, the client must wp_tablet.destroy + the object. + + + + + + + A circular interaction area, such as the touch ring on the Wacom Intuos + Pro series tablets. + + Events on a ring are logically grouped by the wl_tablet_pad_ring.frame + event. + + + + + Request that the compositor use the provided feedback string + associated with this ring. This request should be issued immediately + after a wp_tablet_pad_group.mode_switch event from the corresponding + group is received, or whenever the ring is mapped to a different + action. See wp_tablet_pad_group.mode_switch for more details. + + Clients are encouraged to provide context-aware descriptions for + the actions associated with the ring; compositors may use this + information to offer visual feedback about the button layout + (eg. on-screen displays). + + The provided string 'description' is a UTF-8 encoded string to be + associated with this ring, and is considered user-visible; general + internationalization rules apply. + + The serial argument will be that of the last + wp_tablet_pad_group.mode_switch event received for the group of this + ring. Requests providing other serials than the most recent one will be + ignored. + + + + + + + + This destroys the client's resource for this ring object. + + + + + + Describes the source types for ring events. This indicates to the + client how a ring event was physically generated; a client may + adjust the user interface accordingly. For example, events + from a "finger" source may trigger kinetic scrolling. + + + + + + + Source information for ring events. + + This event does not occur on its own. It is sent before a + wp_tablet_pad_ring.frame event and carries the source information + for all events within that frame. + + The source specifies how this event was generated. If the source is + wp_tablet_pad_ring.source.finger, a wp_tablet_pad_ring.stop event + will be sent when the user lifts the finger off the device. + + This event is optional. If the source is unknown for an interaction, + no event is sent. + + + + + + + Sent whenever the angle on a ring changes. + + The angle is provided in degrees clockwise from the logical + north of the ring in the pad's current rotation. + + + + + + + Stop notification for ring events. + + For some wp_tablet_pad_ring.source types, a wp_tablet_pad_ring.stop + event is sent to notify a client that the interaction with the ring + has terminated. This enables the client to implement kinetic scrolling. + See the wp_tablet_pad_ring.source documentation for information on + when this event may be generated. + + Any wp_tablet_pad_ring.angle events with the same source after this + event should be considered as the start of a new interaction. + + + + + + Indicates the end of a set of ring events that logically belong + together. A client is expected to accumulate the data in all events + within the frame before proceeding. + + All wp_tablet_pad_ring events before a wp_tablet_pad_ring.frame event belong + logically together. For example, on termination of a finger interaction + on a ring the compositor will send a wp_tablet_pad_ring.source event, + a wp_tablet_pad_ring.stop event and a wp_tablet_pad_ring.frame event. + + A wp_tablet_pad_ring.frame event is sent for every logical event + group, even if the group only contains a single wp_tablet_pad_ring + event. Specifically, a client may get a sequence: angle, frame, + angle, frame, etc. + + + + + + + + A linear interaction area, such as the strips found in Wacom Cintiq + models. + + Events on a strip are logically grouped by the wl_tablet_pad_strip.frame + event. + + + + + Requests the compositor to use the provided feedback string + associated with this strip. This request should be issued immediately + after a wp_tablet_pad_group.mode_switch event from the corresponding + group is received, or whenever the strip is mapped to a different + action. See wp_tablet_pad_group.mode_switch for more details. + + Clients are encouraged to provide context-aware descriptions for + the actions associated with the strip, and compositors may use this + information to offer visual feedback about the button layout + (eg. on-screen displays). + + The provided string 'description' is a UTF-8 encoded string to be + associated with this ring, and is considered user-visible; general + internationalization rules apply. + + The serial argument will be that of the last + wp_tablet_pad_group.mode_switch event received for the group of this + strip. Requests providing other serials than the most recent one will be + ignored. + + + + + + + + This destroys the client's resource for this strip object. + + + + + + Describes the source types for strip events. This indicates to the + client how a strip event was physically generated; a client may + adjust the user interface accordingly. For example, events + from a "finger" source may trigger kinetic scrolling. + + + + + + + Source information for strip events. + + This event does not occur on its own. It is sent before a + wp_tablet_pad_strip.frame event and carries the source information + for all events within that frame. + + The source specifies how this event was generated. If the source is + wp_tablet_pad_strip.source.finger, a wp_tablet_pad_strip.stop event + will be sent when the user lifts their finger off the device. + + This event is optional. If the source is unknown for an interaction, + no event is sent. + + + + + + + Sent whenever the position on a strip changes. + + The position is normalized to a range of [0, 65535], the 0-value + represents the top-most and/or left-most position of the strip in + the pad's current rotation. + + + + + + + Stop notification for strip events. + + For some wp_tablet_pad_strip.source types, a wp_tablet_pad_strip.stop + event is sent to notify a client that the interaction with the strip + has terminated. This enables the client to implement kinetic + scrolling. See the wp_tablet_pad_strip.source documentation for + information on when this event may be generated. + + Any wp_tablet_pad_strip.position events with the same source after this + event should be considered as the start of a new interaction. + + + + + + Indicates the end of a set of events that represent one logical + hardware strip event. A client is expected to accumulate the data + in all events within the frame before proceeding. + + All wp_tablet_pad_strip events before a wp_tablet_pad_strip.frame event belong + logically together. For example, on termination of a finger interaction + on a strip the compositor will send a wp_tablet_pad_strip.source event, + a wp_tablet_pad_strip.stop event and a wp_tablet_pad_strip.frame + event. + + A wp_tablet_pad_strip.frame event is sent for every logical event + group, even if the group only contains a single wp_tablet_pad_strip + event. Specifically, a client may get a sequence: position, frame, + position, frame, etc. + + + + + + + + A pad group describes a distinct (sub)set of buttons, rings and strips + present in the tablet. The criteria of this grouping is usually positional, + eg. if a tablet has buttons on the left and right side, 2 groups will be + presented. The physical arrangement of groups is undisclosed and may + change on the fly. + + Pad groups will announce their features during pad initialization. Between + the corresponding wp_tablet_pad.group event and wp_tablet_pad_group.done, the + pad group will announce the buttons, rings and strips contained in it, + plus the number of supported modes. + + Modes are a mechanism to allow multiple groups of actions for every element + in the pad group. The number of groups and available modes in each is + persistent across device plugs. The current mode is user-switchable, it + will be announced through the wp_tablet_pad_group.mode_switch event both + whenever it is switched, and after wp_tablet_pad.enter. + + The current mode logically applies to all elements in the pad group, + although it is at clients' discretion whether to actually perform different + actions, and/or issue the respective .set_feedback requests to notify the + compositor. See the wp_tablet_pad_group.mode_switch event for more details. + + + + + Destroy the wp_tablet_pad_group object. Objects created from this object + are unaffected and should be destroyed separately. + + + + + + Sent on wp_tablet_pad_group initialization to announce the available + buttons in the group. Button indices start at 0, a button may only be + in one group at a time. + + This event is first sent in the initial burst of events before the + wp_tablet_pad_group.done event. + + Some buttons are reserved by the compositor. These buttons may not be + assigned to any wp_tablet_pad_group. Compositors may broadcast this + event in the case of changes to the mapping of these reserved buttons. + If the compositor happens to reserve all buttons in a group, this event + will be sent with an empty array. + + + + + + + Sent on wp_tablet_pad_group initialization to announce available rings. + One event is sent for each ring available on this pad group. + + This event is sent in the initial burst of events before the + wp_tablet_pad_group.done event. + + + + + + + Sent on wp_tablet_pad initialization to announce available strips. + One event is sent for each strip available on this pad group. + + This event is sent in the initial burst of events before the + wp_tablet_pad_group.done event. + + + + + + + Sent on wp_tablet_pad_group initialization to announce that the pad + group may switch between modes. A client may use a mode to store a + specific configuration for buttons, rings and strips and use the + wl_tablet_pad_group.mode_switch event to toggle between these + configurations. Mode indices start at 0. + + Switching modes is compositor-dependent. See the + wp_tablet_pad_group.mode_switch event for more details. + + This event is sent in the initial burst of events before the + wp_tablet_pad_group.done event. This event is only sent when more than + more than one mode is available. + + + + + + + This event is sent immediately to signal the end of the initial + burst of descriptive events. A client may consider the static + description of the tablet to be complete and finalize initialization + of the tablet group. + + + + + + Notification that the mode was switched. + + A mode applies to all buttons, rings and strips in a group + simultaneously, but a client is not required to assign different actions + for each mode. For example, a client may have mode-specific button + mappings but map the ring to vertical scrolling in all modes. Mode + indices start at 0. + + Switching modes is compositor-dependent. The compositor may provide + visual cues to the client about the mode, e.g. by toggling LEDs on + the tablet device. Mode-switching may be software-controlled or + controlled by one or more physical buttons. For example, on a Wacom + Intuos Pro, the button inside the ring may be assigned to switch + between modes. + + The compositor will also send this event after wp_tablet_pad.enter on + each group in order to notify of the current mode. Groups that only + feature one mode will use mode=0 when emitting this event. + + If a button action in the new mode differs from the action in the + previous mode, the client should immediately issue a + wp_tablet_pad.set_feedback request for each changed button. + + If a ring or strip action in the new mode differs from the action + in the previous mode, the client should immediately issue a + wp_tablet_ring.set_feedback or wp_tablet_strip.set_feedback request + for each changed ring or strip. + + + + + + + + + + A pad device is a set of buttons, rings and strips + usually physically present on the tablet device itself. Some + exceptions exist where the pad device is physically detached, e.g. the + Wacom ExpressKey Remote. + + Pad devices have no axes that control the cursor and are generally + auxiliary devices to the tool devices used on the tablet surface. + + A pad device has a number of static characteristics, e.g. the number + of rings. These capabilities are sent in an event sequence after the + wp_tablet_seat.pad_added event before any actual events from this pad. + This initial event sequence is terminated by a wp_tablet_pad.done + event. + + All pad features (buttons, rings and strips) are logically divided into + groups and all pads have at least one group. The available groups are + notified through the wp_tablet_pad.group event; the compositor will + emit one event per group before emitting wp_tablet_pad.done. + + Groups may have multiple modes. Modes allow clients to map multiple + actions to a single pad feature. Only one mode can be active per group, + although different groups may have different active modes. + + + + + Requests the compositor to use the provided feedback string + associated with this button. This request should be issued immediately + after a wp_tablet_pad_group.mode_switch event from the corresponding + group is received, or whenever a button is mapped to a different + action. See wp_tablet_pad_group.mode_switch for more details. + + Clients are encouraged to provide context-aware descriptions for + the actions associated with each button, and compositors may use + this information to offer visual feedback on the button layout + (e.g. on-screen displays). + + Button indices start at 0. Setting the feedback string on a button + that is reserved by the compositor (i.e. not belonging to any + wp_tablet_pad_group) does not generate an error but the compositor + is free to ignore the request. + + The provided string 'description' is a UTF-8 encoded string to be + associated with this ring, and is considered user-visible; general + internationalization rules apply. + + The serial argument will be that of the last + wp_tablet_pad_group.mode_switch event received for the group of this + button. Requests providing other serials than the most recent one will + be ignored. + + + + + + + + + Destroy the wp_tablet_pad object. Objects created from this object + are unaffected and should be destroyed separately. + + + + + + Sent on wp_tablet_pad initialization to announce available groups. + One event is sent for each pad group available. + + This event is sent in the initial burst of events before the + wp_tablet_pad.done event. At least one group will be announced. + + + + + + + A system-specific device path that indicates which device is behind + this wp_tablet_pad. This information may be used to gather additional + information about the device, e.g. through libwacom. + + The format of the path is unspecified, it may be a device node, a + sysfs path, or some other identifier. It is up to the client to + identify the string provided. + + This event is sent in the initial burst of events before the + wp_tablet_pad.done event. + + + + + + + Sent on wp_tablet_pad initialization to announce the available + buttons. + + This event is sent in the initial burst of events before the + wp_tablet_pad.done event. This event is only sent when at least one + button is available. + + + + + + + This event signals the end of the initial burst of descriptive + events. A client may consider the static description of the pad to + be complete and finalize initialization of the pad. + + + + + + Describes the physical state of a button that caused the button + event. + + + + + + + + Sent whenever the physical state of a button changes. + + + + + + + + + Notification that this pad is focused on the specified surface. + + + + + + + + + Notification that this pad is no longer focused on the specified + surface. + + + + + + + + Sent when the pad has been removed from the system. When a tablet + is removed its pad(s) will be removed too. + + When this event is received, the client must destroy all rings, strips + and groups that were offered by this pad, and issue wp_tablet_pad.destroy + the pad itself. + + + + diff --git a/Engine/lib/sdl/wayland-protocols/viewporter.xml b/Engine/lib/sdl/wayland-protocols/viewporter.xml new file mode 100644 index 000000000..c732d8c35 --- /dev/null +++ b/Engine/lib/sdl/wayland-protocols/viewporter.xml @@ -0,0 +1,186 @@ + + + + + Copyright © 2013-2016 Collabora, Ltd. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + + The global interface exposing surface cropping and scaling + capabilities is used to instantiate an interface extension for a + wl_surface object. This extended interface will then allow + cropping and scaling the surface contents, effectively + disconnecting the direct relationship between the buffer and the + surface size. + + + + + Informs the server that the client will not be using this + protocol object anymore. This does not affect any other objects, + wp_viewport objects included. + + + + + + + + + + Instantiate an interface extension for the given wl_surface to + crop and scale its content. If the given wl_surface already has + a wp_viewport object associated, the viewport_exists + protocol error is raised. + + + + + + + + + An additional interface to a wl_surface object, which allows the + client to specify the cropping and scaling of the surface + contents. + + This interface works with two concepts: the source rectangle (src_x, + src_y, src_width, src_height), and the destination size (dst_width, + dst_height). The contents of the source rectangle are scaled to the + destination size, and content outside the source rectangle is ignored. + This state is double-buffered, and is applied on the next + wl_surface.commit. + + The two parts of crop and scale state are independent: the source + rectangle, and the destination size. Initially both are unset, that + is, no scaling is applied. The whole of the current wl_buffer is + used as the source, and the surface size is as defined in + wl_surface.attach. + + If the destination size is set, it causes the surface size to become + dst_width, dst_height. The source (rectangle) is scaled to exactly + this size. This overrides whatever the attached wl_buffer size is, + unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface + has no content and therefore no size. Otherwise, the size is always + at least 1x1 in surface local coordinates. + + If the source rectangle is set, it defines what area of the wl_buffer is + taken as the source. If the source rectangle is set and the destination + size is not set, then src_width and src_height must be integers, and the + surface size becomes the source rectangle size. This results in cropping + without scaling. If src_width or src_height are not integers and + destination size is not set, the bad_size protocol error is raised when + the surface state is applied. + + The coordinate transformations from buffer pixel coordinates up to + the surface-local coordinates happen in the following order: + 1. buffer_transform (wl_surface.set_buffer_transform) + 2. buffer_scale (wl_surface.set_buffer_scale) + 3. crop and scale (wp_viewport.set*) + This means, that the source rectangle coordinates of crop and scale + are given in the coordinates after the buffer transform and scale, + i.e. in the coordinates that would be the surface-local coordinates + if the crop and scale was not applied. + + If src_x or src_y are negative, the bad_value protocol error is raised. + Otherwise, if the source rectangle is partially or completely outside of + the non-NULL wl_buffer, then the out_of_buffer protocol error is raised + when the surface state is applied. A NULL wl_buffer does not raise the + out_of_buffer error. + + The x, y arguments of wl_surface.attach are applied as normal to + the surface. They indicate how many pixels to remove from the + surface size from the left and the top. In other words, they are + still in the surface-local coordinate system, just like dst_width + and dst_height are. + + If the wl_surface associated with the wp_viewport is destroyed, + all wp_viewport requests except 'destroy' raise the protocol error + no_surface. + + If the wp_viewport object is destroyed, the crop and scale + state is removed from the wl_surface. The change will be applied + on the next wl_surface.commit. + + + + + The associated wl_surface's crop and scale state is removed. + The change is applied on the next wl_surface.commit. + + + + + + + + + + + + + Set the source rectangle of the associated wl_surface. See + wp_viewport for the description, and relation to the wl_buffer + size. + + If all of x, y, width and height are -1.0, the source rectangle is + unset instead. Any other set of values where width or height are zero + or negative, or x or y are negative, raise the bad_value protocol + error. + + The crop and scale state is double-buffered state, and will be + applied on the next wl_surface.commit. + + + + + + + + + + Set the destination size of the associated wl_surface. See + wp_viewport for the description, and relation to the wl_buffer + size. + + If width is -1 and height is -1, the destination size is unset + instead. Any other pair of values for width and height that + contains zero or negative values raises the bad_value protocol + error. + + The crop and scale state is double-buffered state, and will be + applied on the next wl_surface.commit. + + + + + + + diff --git a/Engine/lib/sdl/wayland-protocols/xdg-output-unstable-v1.xml b/Engine/lib/sdl/wayland-protocols/xdg-output-unstable-v1.xml new file mode 100644 index 000000000..9a5b79000 --- /dev/null +++ b/Engine/lib/sdl/wayland-protocols/xdg-output-unstable-v1.xml @@ -0,0 +1,220 @@ + + + + + Copyright © 2017 Red Hat Inc. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol aims at describing outputs in a way which is more in line + with the concept of an output on desktop oriented systems. + + Some information are more specific to the concept of an output for + a desktop oriented system and may not make sense in other applications, + such as IVI systems for example. + + Typically, the global compositor space on a desktop system is made of + a contiguous or overlapping set of rectangular regions. + + Some of the information provided in this protocol might be identical + to their counterparts already available from wl_output, in which case + the information provided by this protocol should be preferred to their + equivalent in wl_output. The goal is to move the desktop specific + concepts (such as output location within the global compositor space, + the connector name and types, etc.) out of the core wl_output protocol. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible + changes may be added together with the corresponding interface + version bump. + Backward incompatible changes are done by bumping the version + number in the protocol and interface names and resetting the + interface version. Once the protocol is to be declared stable, + the 'z' prefix and the version number in the protocol and + interface names are removed and the interface version number is + reset. + + + + + A global factory interface for xdg_output objects. + + + + + Using this request a client can tell the server that it is not + going to use the xdg_output_manager object anymore. + + Any objects already created through this instance are not affected. + + + + + + This creates a new xdg_output object for the given wl_output. + + + + + + + + + An xdg_output describes part of the compositor geometry. + + This typically corresponds to a monitor that displays part of the + compositor space. + + For objects version 3 onwards, after all xdg_output properties have been + sent (when the object is created and when properties are updated), a + wl_output.done event is sent. This allows changes to the output + properties to be seen as atomic, even if they happen via multiple events. + + + + + Using this request a client can tell the server that it is not + going to use the xdg_output object anymore. + + + + + + The position event describes the location of the wl_output within + the global compositor space. + + The logical_position event is sent after creating an xdg_output + (see xdg_output_manager.get_xdg_output) and whenever the location + of the output changes within the global compositor space. + + + + + + + + The logical_size event describes the size of the output in the + global compositor space. + + For example, a surface without any buffer scale, transformation + nor rotation set, with the size matching the logical_size will + have the same size as the corresponding output when displayed. + + Most regular Wayland clients should not pay attention to the + logical size and would rather rely on xdg_shell interfaces. + + Some clients such as Xwayland, however, need this to configure + their surfaces in the global compositor space as the compositor + may apply a different scale from what is advertised by the output + scaling property (to achieve fractional scaling, for example). + + For example, for a wl_output mode 3840×2160 and a scale factor 2: + + - A compositor not scaling the surface buffers will advertise a + logical size of 3840×2160, + + - A compositor automatically scaling the surface buffers will + advertise a logical size of 1920×1080, + + - A compositor using a fractional scale of 1.5 will advertise a + logical size of 2560×1440. + + For example, for a wl_output mode 1920×1080 and a 90 degree rotation, + the compositor will advertise a logical size of 1080x1920. + + The logical_size event is sent after creating an xdg_output + (see xdg_output_manager.get_xdg_output) and whenever the logical + size of the output changes, either as a result of a change in the + applied scale or because of a change in the corresponding output + mode(see wl_output.mode) or transform (see wl_output.transform). + + + + + + + + This event is sent after all other properties of an xdg_output + have been sent. + + This allows changes to the xdg_output properties to be seen as + atomic, even if they happen via multiple events. + + For objects version 3 onwards, this event is deprecated. Compositors + are not required to send it anymore and must send wl_output.done + instead. + + + + + + + + Many compositors will assign names to their outputs, show them to the + user, allow them to be configured by name, etc. The client may wish to + know this name as well to offer the user similar behaviors. + + The naming convention is compositor defined, but limited to + alphanumeric characters and dashes (-). Each name is unique among all + wl_output globals, but if a wl_output global is destroyed the same name + may be reused later. The names will also remain consistent across + sessions with the same hardware and software configuration. + + Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do + not assume that the name is a reflection of an underlying DRM + connector, X11 connection, etc. + + The name event is sent after creating an xdg_output (see + xdg_output_manager.get_xdg_output). This event is only sent once per + xdg_output, and the name does not change over the lifetime of the + wl_output global. + + + + + + + Many compositors can produce human-readable descriptions of their + outputs. The client may wish to know this description as well, to + communicate the user for various purposes. + + The description is a UTF-8 string with no convention defined for its + contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11 + output via :1'. + + The description event is sent after creating an xdg_output (see + xdg_output_manager.get_xdg_output) and whenever the description + changes. The description is optional, and may not be sent at all. + + For objects of version 2 and lower, this event is only sent once per + xdg_output, and the description does not change over the lifetime of + the wl_output global. + + + + + + From bea7d6f4a1023194064e445aac49475ea8f7a7b8 Mon Sep 17 00:00:00 2001 From: JeffR Date: Tue, 26 Apr 2022 11:06:15 -0500 Subject: [PATCH 093/145] Adds a conditional to the github workflow file so it only runs on the main repo --- .github/workflows/cmake.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index f25be008a..d6d2a3f54 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -12,6 +12,7 @@ env: jobs: build: + if: github.repository == 'TorqueGameEngines/Torque3D' # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. # You can convert this to a matrix build if you need cross-platform coverage. # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix From f29747609281939acf42fc31ae3809b9012a298f Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 26 Apr 2022 11:56:24 -0500 Subject: [PATCH 094/145] update assimp to 5.2.3 Bugfix-Release --- Engine/lib/assimp/CHANGES | 607 + Engine/lib/assimp/CREDITS | 183 + Engine/lib/assimp/LICENSE | 78 + Engine/lib/assimp/Readme.md | 120 + Engine/lib/assimp/code/3DS/3DSHelper.h | 652 - Engine/lib/assimp/code/3MF/3MFXmlTags.h | 104 - Engine/lib/assimp/code/3MF/D3MFImporter.cpp | 483 - Engine/lib/assimp/code/3MF/D3MFOpcPackage.cpp | 207 - Engine/lib/assimp/code/AMF/AMFImporter.cpp | 705 - Engine/lib/assimp/code/AMF/AMFImporter.hpp | 432 - .../assimp/code/AMF/AMFImporter_Geometry.cpp | 357 - .../lib/assimp/code/AMF/AMFImporter_Macro.hpp | 166 - .../lib/assimp/code/AMF/AMFImporter_Node.hpp | 340 - .../code/AMF/AMFImporter_Postprocess.cpp | 978 -- .../lib/assimp/code/Assbin/AssbinExporter.cpp | 846 - .../code/{ => AssetLib}/3DS/3DSConverter.cpp | 560 +- .../code/{ => AssetLib}/3DS/3DSExporter.cpp | 312 +- .../code/{ => AssetLib}/3DS/3DSExporter.h | 4 +- .../lib/assimp/code/AssetLib/3DS/3DSHelper.h | 702 + .../code/{ => AssetLib}/3DS/3DSLoader.cpp | 820 +- .../code/{ => AssetLib}/3DS/3DSLoader.h | 27 +- .../lib/assimp/code/AssetLib/3MF/3MFTypes.h | 165 + .../lib/assimp/code/AssetLib/3MF/3MFXmlTags.h | 117 + .../code/{ => AssetLib}/3MF/D3MFExporter.cpp | 291 +- .../code/{ => AssetLib}/3MF/D3MFExporter.h | 23 +- .../assimp/code/AssetLib/3MF/D3MFImporter.cpp | 130 + .../assimp/code/AssetLib/3MF/D3MFImporter.h | 91 + .../code/AssetLib/3MF/D3MFOpcPackage.cpp | 256 + .../code/{ => AssetLib}/3MF/D3MFOpcPackage.h | 27 +- .../code/AssetLib/3MF/XmlSerializer.cpp | 593 + .../assimp/code/AssetLib/3MF/XmlSerializer.h | 96 + .../code/{ => AssetLib}/AC/ACLoader.cpp | 765 +- .../assimp/code/{ => AssetLib}/AC/ACLoader.h | 134 +- .../assimp/code/AssetLib/AMF/AMFImporter.cpp | 524 + .../assimp/code/AssetLib/AMF/AMFImporter.hpp | 310 + .../AssetLib/AMF/AMFImporter_Geometry.cpp | 284 + .../AMF/AMFImporter_Material.cpp | 312 +- .../code/AssetLib/AMF/AMFImporter_Node.hpp | 305 + .../AssetLib/AMF/AMFImporter_Postprocess.cpp | 894 ++ .../code/{ => AssetLib}/ASE/ASELoader.cpp | 774 +- .../code/{ => AssetLib}/ASE/ASELoader.h | 27 +- .../code/{ => AssetLib}/ASE/ASEParser.cpp | 1416 +- .../code/{ => AssetLib}/ASE/ASEParser.h | 235 +- .../code/AssetLib/Assbin/AssbinExporter.cpp | 68 + .../{ => AssetLib}/Assbin/AssbinExporter.h | 8 +- .../code/AssetLib/Assbin/AssbinFileWriter.cpp | 833 + .../Assbin/AssbinFileWriter.h} | 38 +- .../{ => AssetLib}/Assbin/AssbinLoader.cpp | 459 +- .../code/{ => AssetLib}/Assbin/AssbinLoader.h | 19 +- .../code/{ => AssetLib}/Assjson/cencode.c | 28 +- .../code/{ => AssetLib}/Assjson/cencode.h | 4 + .../{ => AssetLib}/Assjson/json_exporter.cpp | 221 +- .../{ => AssetLib}/Assjson/mesh_splitter.cpp | 21 +- .../{ => AssetLib}/Assjson/mesh_splitter.h | 37 +- .../code/AssetLib/Assxml/AssxmlExporter.cpp | 68 + .../{ => AssetLib}/Assxml/AssxmlExporter.h | 3 +- .../code/AssetLib/Assxml/AssxmlFileWriter.cpp | 662 + .../code/AssetLib/Assxml/AssxmlFileWriter.h | 64 + .../assimp/code/AssetLib/B3D/B3DImporter.cpp | 744 + .../code/{ => AssetLib}/B3D/B3DImporter.h | 28 +- .../assimp/code/AssetLib/BVH/BVHLoader.cpp | 528 + .../code/{ => AssetLib}/BVH/BVHLoader.h | 56 +- .../{ => AssetLib}/Blender/BlenderBMesh.cpp | 146 +- .../{ => AssetLib}/Blender/BlenderBMesh.h | 2 +- .../AssetLib/Blender/BlenderCustomData.cpp | 181 + .../Blender/BlenderCustomData.h | 0 .../{ => AssetLib}/Blender/BlenderDNA.cpp | 174 +- .../code/{ => AssetLib}/Blender/BlenderDNA.h | 394 +- .../{ => AssetLib}/Blender/BlenderDNA.inl | 67 +- .../Blender/BlenderIntermediate.h | 2 +- .../{ => AssetLib}/Blender/BlenderLoader.cpp | 931 +- .../code/AssetLib/Blender/BlenderLoader.h | 198 + .../Blender/BlenderModifier.cpp | 178 +- .../{ => AssetLib}/Blender/BlenderModifier.h | 22 +- .../code/AssetLib/Blender/BlenderScene.cpp | 891 ++ .../{ => AssetLib}/Blender/BlenderScene.h | 550 +- .../{ => AssetLib}/Blender/BlenderSceneGen.h | 8 +- .../Blender/BlenderTessellator.cpp | 10 +- .../Blender/BlenderTessellator.h | 2 +- .../code/{ => AssetLib}/C4D/C4DImporter.cpp | 69 +- .../code/{ => AssetLib}/C4D/C4DImporter.h | 39 +- .../code/{ => AssetLib}/COB/COBLoader.cpp | 886 +- .../lib/assimp/code/AssetLib/COB/COBLoader.h | 152 + .../assimp/code/{ => AssetLib}/COB/COBScene.h | 15 +- .../code/{ => AssetLib}/CSM/CSMLoader.cpp | 23 +- .../code/{ => AssetLib}/CSM/CSMLoader.h | 30 +- .../code/AssetLib/Collada/ColladaExporter.cpp | 1748 +++ .../code/AssetLib/Collada/ColladaExporter.h | 257 + .../code/AssetLib/Collada/ColladaHelper.cpp | 99 + .../code/AssetLib/Collada/ColladaHelper.h | 679 + .../{ => AssetLib}/Collada/ColladaLoader.cpp | 1089 +- .../{ => AssetLib}/Collada/ColladaLoader.h | 150 +- .../code/AssetLib/Collada/ColladaParser.cpp | 2402 +++ .../code/AssetLib/Collada/ColladaParser.h | 348 + .../code/{ => AssetLib}/DXF/DXFHelper.h | 4 +- .../code/{ => AssetLib}/DXF/DXFLoader.cpp | 54 +- .../code/{ => AssetLib}/DXF/DXFLoader.h | 19 +- .../code/{ => AssetLib}/FBX/FBXAnimation.cpp | 171 +- .../{ => AssetLib}/FBX/FBXBinaryTokenizer.cpp | 31 +- .../code/{ => AssetLib}/FBX/FBXCommon.h | 61 +- .../{ => AssetLib}/FBX/FBXCompileConfig.h | 18 +- .../assimp/code/AssetLib/FBX/FBXConverter.cpp | 3679 +++++ .../code/{ => AssetLib}/FBX/FBXConverter.h | 120 +- .../code/{ => AssetLib}/FBX/FBXDeformer.cpp | 2 +- .../code/{ => AssetLib}/FBX/FBXDocument.cpp | 171 +- .../code/{ => AssetLib}/FBX/FBXDocument.h | 74 +- .../{ => AssetLib}/FBX/FBXDocumentUtil.cpp | 16 +- .../code/{ => AssetLib}/FBX/FBXDocumentUtil.h | 2 +- .../code/{ => AssetLib}/FBX/FBXExportNode.cpp | 78 +- .../code/{ => AssetLib}/FBX/FBXExportNode.h | 9 +- .../{ => AssetLib}/FBX/FBXExportProperty.cpp | 2 +- .../{ => AssetLib}/FBX/FBXExportProperty.h | 2 +- .../code/{ => AssetLib}/FBX/FBXExporter.cpp | 395 +- .../code/{ => AssetLib}/FBX/FBXExporter.h | 23 +- .../{ => AssetLib}/FBX/FBXImportSettings.h | 44 +- .../assimp/code/AssetLib/FBX/FBXImporter.cpp | 200 + .../code/{ => AssetLib}/FBX/FBXImporter.h | 50 +- .../code/{ => AssetLib}/FBX/FBXMaterial.cpp | 168 +- .../{ => AssetLib}/FBX/FBXMeshGeometry.cpp | 83 +- .../code/{ => AssetLib}/FBX/FBXMeshGeometry.h | 16 +- .../code/{ => AssetLib}/FBX/FBXModel.cpp | 82 +- .../{ => AssetLib}/FBX/FBXNodeAttribute.cpp | 2 +- .../code/{ => AssetLib}/FBX/FBXParser.cpp | 151 +- .../code/{ => AssetLib}/FBX/FBXParser.h | 10 +- .../code/{ => AssetLib}/FBX/FBXProperties.cpp | 71 +- .../code/{ => AssetLib}/FBX/FBXProperties.h | 10 +- .../code/{ => AssetLib}/FBX/FBXTokenizer.cpp | 12 +- .../code/{ => AssetLib}/FBX/FBXTokenizer.h | 3 +- .../code/{ => AssetLib}/FBX/FBXUtil.cpp | 22 +- .../assimp/code/{ => AssetLib}/FBX/FBXUtil.h | 23 +- .../code/{ => AssetLib}/HMP/HMPFileData.h | 2 +- .../code/{ => AssetLib}/HMP/HMPLoader.cpp | 412 +- .../code/{ => AssetLib}/HMP/HMPLoader.h | 57 +- .../{ => AssetLib}/HMP/HalfLifeFileData.h | 2 +- .../{Importer => AssetLib}/IFC/IFCBoolean.cpp | 426 +- .../{Importer => AssetLib}/IFC/IFCCurve.cpp | 32 +- .../IFC/IFCGeometry.cpp | 112 +- .../{Importer => AssetLib}/IFC/IFCLoader.cpp | 613 +- .../{Importer => AssetLib}/IFC/IFCLoader.h | 94 +- .../IFC/IFCMaterial.cpp | 12 +- .../IFC/IFCOpenings.cpp | 403 +- .../{Importer => AssetLib}/IFC/IFCProfile.cpp | 10 +- .../IFC/IFCReaderGen1_2x3.cpp | 897 +- .../IFC/IFCReaderGen2_2x3.cpp | 173 +- .../IFC/IFCReaderGen_2x3.h | 13 +- .../IFC/IFCReaderGen_4.cpp | 394 +- .../IFC/IFCReaderGen_4.h | 28 +- .../{Importer => AssetLib}/IFC/IFCUtil.cpp | 42 +- .../code/{Importer => AssetLib}/IFC/IFCUtil.h | 26 +- .../assimp/code/AssetLib/IQM/IQMImporter.cpp | 322 + .../assimp/code/AssetLib/IQM/IQMImporter.h | 78 + Engine/lib/assimp/code/AssetLib/IQM/iqm.h | 134 + .../assimp/code/AssetLib/Irr/IRRLoader.cpp | 1359 ++ .../code/{ => AssetLib}/Irr/IRRLoader.h | 48 +- .../code/AssetLib/Irr/IRRMeshLoader.cpp | 502 + .../code/{ => AssetLib}/Irr/IRRMeshLoader.h | 27 +- .../assimp/code/AssetLib/Irr/IRRShared.cpp | 387 + .../code/{ => AssetLib}/Irr/IRRShared.h | 91 +- .../code/{ => AssetLib}/LWO/LWOAnimation.cpp | 441 +- .../code/{ => AssetLib}/LWO/LWOAnimation.h | 8 +- .../code/{ => AssetLib}/LWO/LWOBLoader.cpp | 6 +- .../assimp/code/AssetLib/LWO/LWOFileData.h | 715 + .../assimp/code/AssetLib/LWO/LWOLoader.cpp | 1618 ++ .../code/{ => AssetLib}/LWO/LWOLoader.h | 248 +- .../assimp/code/AssetLib/LWO/LWOMaterial.cpp | 1155 ++ .../code/{ => AssetLib}/LWS/LWSLoader.cpp | 534 +- .../code/{ => AssetLib}/LWS/LWSLoader.h | 136 +- .../assimp/code/AssetLib/M3D/M3DExporter.cpp | 442 + .../M3D/M3DExporter.h} | 86 +- .../assimp/code/AssetLib/M3D/M3DImporter.cpp | 789 + .../assimp/code/AssetLib/M3D/M3DImporter.h | 105 + .../assimp/code/AssetLib/M3D/M3DMaterials.h | 106 + .../assimp/code/AssetLib/M3D/M3DWrapper.cpp | 152 + .../lib/assimp/code/AssetLib/M3D/M3DWrapper.h | 134 + Engine/lib/assimp/code/AssetLib/M3D/m3d.h | 4902 ++++++ .../code/{ => AssetLib}/MD2/MD2FileData.h | 2 +- .../code/{ => AssetLib}/MD2/MD2Loader.cpp | 72 +- .../code/{ => AssetLib}/MD2/MD2Loader.h | 40 +- .../code/{ => AssetLib}/MD2/MD2NormalTable.h | 4 +- .../code/{ => AssetLib}/MD3/MD3FileData.h | 4 +- .../code/{ => AssetLib}/MD3/MD3Loader.cpp | 572 +- .../code/{ => AssetLib}/MD3/MD3Loader.h | 113 +- .../code/{ => AssetLib}/MD4/MD4FileData.h | 2 +- .../code/{ => AssetLib}/MD5/MD5Loader.cpp | 513 +- .../code/{ => AssetLib}/MD5/MD5Loader.h | 74 +- .../code/{ => AssetLib}/MD5/MD5Parser.cpp | 345 +- .../code/{ => AssetLib}/MD5/MD5Parser.h | 2 +- .../code/{ => AssetLib}/MDC/MDCFileData.h | 6 +- .../code/{ => AssetLib}/MDC/MDCLoader.cpp | 373 +- .../code/{ => AssetLib}/MDC/MDCLoader.h | 36 +- .../code/{ => AssetLib}/MDC/MDCNormalTable.h | 2 +- .../code/AssetLib/MDL/HalfLife/HL1FileData.h | 600 + .../MDL/HalfLife/HL1ImportDefinitions.h | 64 + .../AssetLib/MDL/HalfLife/HL1ImportSettings.h | 85 + .../AssetLib/MDL/HalfLife/HL1MDLLoader.cpp | 1353 ++ .../code/AssetLib/MDL/HalfLife/HL1MDLLoader.h | 243 + .../AssetLib/MDL/HalfLife/HL1MeshTrivert.h | 127 + .../MDL/HalfLife/HalfLifeMDLBaseHeader.h} | 38 +- .../code/AssetLib/MDL/HalfLife/LogFunctions.h | 95 + .../MDL/HalfLife/UniqueNameGenerator.cpp | 180 + .../MDL/HalfLife/UniqueNameGenerator.h | 81 + .../{ => AssetLib}/MDL/MDLDefaultColorMap.h | 2 +- .../code/{ => AssetLib}/MDL/MDLFileData.h | 8 +- .../code/{ => AssetLib}/MDL/MDLLoader.cpp | 1392 +- .../code/{ => AssetLib}/MDL/MDLLoader.h | 34 +- .../{ => AssetLib}/MDL/MDLMaterialLoader.cpp | 559 +- .../assimp/code/{ => AssetLib}/MMD/MMDCpp14.h | 2 +- .../assimp/code/AssetLib/MMD/MMDImporter.cpp | 368 + .../code/{ => AssetLib}/MMD/MMDImporter.h | 12 +- .../code/{ => AssetLib}/MMD/MMDPmdParser.h | 8 +- .../code/{ => AssetLib}/MMD/MMDPmxParser.cpp | 23 +- .../code/{ => AssetLib}/MMD/MMDPmxParser.h | 2 +- .../code/{ => AssetLib}/MMD/MMDVmdParser.h | 10 +- .../code/{ => AssetLib}/MS3D/MS3DLoader.cpp | 91 +- .../code/{ => AssetLib}/MS3D/MS3DLoader.h | 66 +- .../code/{ => AssetLib}/NDO/NDOLoader.cpp | 29 +- .../code/{ => AssetLib}/NDO/NDOLoader.h | 52 +- .../code/{ => AssetLib}/NFF/NFFLoader.cpp | 976 +- .../code/{ => AssetLib}/NFF/NFFLoader.h | 130 +- .../code/{ => AssetLib}/OFF/OFFLoader.cpp | 33 +- .../code/{ => AssetLib}/OFF/OFFLoader.h | 28 +- .../Ogre/OgreBinarySerializer.cpp | 556 +- .../code/AssetLib/Ogre/OgreBinarySerializer.h | 415 + .../code/{ => AssetLib}/Ogre/OgreImporter.cpp | 79 +- .../code/{ => AssetLib}/Ogre/OgreImporter.h | 44 +- .../code/{ => AssetLib}/Ogre/OgreMaterial.cpp | 364 +- .../{ => AssetLib}/Ogre/OgreParsingUtils.h | 67 +- .../code/{ => AssetLib}/Ogre/OgreStructs.cpp | 834 +- .../code/{ => AssetLib}/Ogre/OgreStructs.h | 4 +- .../code/AssetLib/Ogre/OgreXmlSerializer.cpp | 755 + .../{ => AssetLib}/Ogre/OgreXmlSerializer.h | 82 +- .../OpenGEX/OpenGEXExporter.cpp | 2 +- .../{ => AssetLib}/OpenGEX/OpenGEXExporter.h | 4 +- .../code/AssetLib/OpenGEX/OpenGEXImporter.cpp | 1326 ++ .../{ => AssetLib}/OpenGEX/OpenGEXImporter.h | 33 +- .../{ => AssetLib}/OpenGEX/OpenGEXStructs.h | 2 +- .../code/{ => AssetLib}/Ply/PlyExporter.cpp | 11 +- .../code/{ => AssetLib}/Ply/PlyExporter.h | 2 +- .../code/{ => AssetLib}/Ply/PlyLoader.cpp | 657 +- .../code/{ => AssetLib}/Ply/PlyLoader.h | 51 +- .../assimp/code/AssetLib/Ply/PlyParser.cpp | 963 ++ .../code/{ => AssetLib}/Ply/PlyParser.h | 5 +- .../code/{ => AssetLib}/Q3BSP/Q3BSPFileData.h | 6 +- .../code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp | 680 + .../{ => AssetLib}/Q3BSP/Q3BSPFileImporter.h | 17 +- .../{ => AssetLib}/Q3BSP/Q3BSPFileParser.cpp | 4 +- .../{ => AssetLib}/Q3BSP/Q3BSPFileParser.h | 7 +- .../assimp/code/AssetLib/Q3D/Q3DLoader.cpp | 575 + .../code/{ => AssetLib}/Q3D/Q3DLoader.h | 50 +- .../code/{ => AssetLib}/Raw/RawLoader.cpp | 247 +- .../code/{ => AssetLib}/Raw/RawLoader.h | 35 +- .../code/{ => AssetLib}/SIB/SIBImporter.cpp | 443 +- .../code/{ => AssetLib}/SIB/SIBImporter.h | 33 +- .../code/{ => AssetLib}/SMD/SMDLoader.cpp | 53 +- .../code/{ => AssetLib}/SMD/SMDLoader.h | 59 +- .../STEPParser/STEPFileEncoding.cpp | 4 +- .../STEPParser/STEPFileEncoding.h | 2 +- .../STEPParser/STEPFileReader.cpp | 48 +- .../STEPParser/STEPFileReader.h | 4 +- .../code/{ => AssetLib}/STL/STLExporter.cpp | 16 +- .../code/{ => AssetLib}/STL/STLExporter.h | 21 +- .../code/{ => AssetLib}/STL/STLLoader.cpp | 381 +- .../code/{ => AssetLib}/STL/STLLoader.h | 18 +- .../lib/assimp/code/AssetLib/Step/STEPFile.h | 971 ++ .../code/{ => AssetLib}/Step/StepExporter.cpp | 138 +- .../code/{ => AssetLib}/Step/StepExporter.h | 2 +- .../Terragen/TerragenLoader.cpp | 169 +- .../{ => AssetLib}/Terragen/TerragenLoader.h | 51 +- .../{ => AssetLib}/Unreal/UnrealLoader.cpp | 364 +- .../code/{ => AssetLib}/Unreal/UnrealLoader.h | 135 +- .../code/{ => AssetLib}/X/XFileExporter.cpp | 12 +- .../code/{ => AssetLib}/X/XFileExporter.h | 8 +- .../code/{ => AssetLib}/X/XFileHelper.h | 119 +- .../code/{ => AssetLib}/X/XFileImporter.cpp | 73 +- .../code/{ => AssetLib}/X/XFileImporter.h | 15 +- .../code/{ => AssetLib}/X/XFileParser.cpp | 1248 +- .../code/{ => AssetLib}/X/XFileParser.h | 7 +- .../assimp/code/AssetLib/X3D/X3DExporter.cpp | 675 + .../assimp/code/AssetLib/X3D/X3DExporter.hpp | 250 + .../assimp/code/AssetLib/X3D/X3DGeoHelper.cpp | 531 + .../assimp/code/AssetLib/X3D/X3DGeoHelper.h | 39 + .../assimp/code/AssetLib/X3D/X3DImporter.cpp | 488 + .../assimp/code/AssetLib/X3D/X3DImporter.hpp | 383 + .../AssetLib/X3D/X3DImporter_Geometry2D.cpp | 467 + .../AssetLib/X3D/X3DImporter_Geometry3D.cpp | 918 ++ .../{ => AssetLib}/X3D/X3DImporter_Group.cpp | 289 +- .../code/AssetLib/X3D/X3DImporter_Light.cpp | 270 + .../code/AssetLib/X3D/X3DImporter_Macro.hpp | 121 + .../AssetLib/X3D/X3DImporter_Metadata.cpp | 255 + .../X3D/X3DImporter_Networking.cpp | 100 +- .../code/AssetLib/X3D/X3DImporter_Node.hpp | 463 + .../AssetLib/X3D/X3DImporter_Postprocess.cpp | 731 + .../AssetLib/X3D/X3DImporter_Rendering.cpp | 993 ++ .../code/AssetLib/X3D/X3DImporter_Shape.cpp | 241 + .../AssetLib/X3D/X3DImporter_Texturing.cpp | 179 + .../assimp/code/AssetLib/X3D/X3DXmlHelper.cpp | 294 + .../assimp/code/AssetLib/X3D/X3DXmlHelper.h | 30 + .../assimp/code/AssetLib/XGL/XGLLoader.cpp | 787 + .../code/{ => AssetLib}/XGL/XGLLoader.h | 139 +- .../lib/assimp/code/AssetLib/glTF/glTFAsset.h | 1017 ++ .../assimp/code/AssetLib/glTF/glTFAsset.inl | 1316 ++ .../{ => AssetLib}/glTF/glTFAssetWriter.h | 4 +- .../{ => AssetLib}/glTF/glTFAssetWriter.inl | 67 +- .../code/{ => AssetLib}/glTF/glTFCommon.cpp | 106 +- .../assimp/code/AssetLib/glTF/glTFCommon.h | 520 + .../code/{ => AssetLib}/glTF/glTFExporter.cpp | 185 +- .../assimp/code/AssetLib/glTF/glTFExporter.h | 118 + .../code/{ => AssetLib}/glTF/glTFImporter.cpp | 453 +- .../code/{ => AssetLib}/glTF/glTFImporter.h | 41 +- .../assimp/code/AssetLib/glTF2/glTF2Asset.h | 1242 ++ .../assimp/code/AssetLib/glTF2/glTF2Asset.inl | 2069 +++ .../{ => AssetLib}/glTF2/glTF2AssetWriter.h | 9 +- .../{ => AssetLib}/glTF2/glTF2AssetWriter.inl | 312 +- .../code/AssetLib/glTF2/glTF2Exporter.cpp | 1542 ++ .../code/AssetLib/glTF2/glTF2Exporter.h | 147 + .../code/AssetLib/glTF2/glTF2Importer.cpp | 1638 ++ .../code/{ => AssetLib}/glTF2/glTF2Importer.h | 45 +- .../lib/assimp/code/Assxml/AssxmlExporter.cpp | 655 - Engine/lib/assimp/code/B3D/B3DImporter.cpp | 740 - Engine/lib/assimp/code/BVH/BVHLoader.cpp | 578 - .../assimp/code/Blender/BlenderCustomData.cpp | 189 - .../lib/assimp/code/Blender/BlenderLoader.h | 240 - .../lib/assimp/code/Blender/BlenderScene.cpp | 875 -- Engine/lib/assimp/code/CApi/AssimpCExport.cpp | 72 +- .../assimp/code/CApi/CInterfaceIOWrapper.cpp | 53 +- .../assimp/code/CApi/CInterfaceIOWrapper.h | 47 +- Engine/lib/assimp/code/CMakeLists.txt | 1045 +- Engine/lib/assimp/code/COB/COBLoader.h | 156 - .../assimp/code/Collada/ColladaExporter.cpp | 1675 -- .../lib/assimp/code/Collada/ColladaExporter.h | 222 - .../lib/assimp/code/Collada/ColladaHelper.h | 701 - .../lib/assimp/code/Collada/ColladaParser.cpp | 3409 ---- .../lib/assimp/code/Collada/ColladaParser.h | 393 - .../lib/assimp/code/Common/AssertHandler.cpp | 72 + Engine/lib/assimp/code/Common/AssertHandler.h | 75 + Engine/lib/assimp/code/Common/Assimp.cpp | 1092 +- Engine/lib/assimp/code/Common/Base64.cpp | 179 + .../lib/assimp/code/Common/BaseImporter.cpp | 397 +- Engine/lib/assimp/code/Common/BaseProcess.cpp | 41 +- Engine/lib/assimp/code/Common/BaseProcess.h | 137 +- Engine/lib/assimp/code/Common/Bitmap.cpp | 195 +- Engine/lib/assimp/code/Common/Compression.cpp | 214 + Engine/lib/assimp/code/Common/Compression.h | 121 + .../lib/assimp/code/Common/CreateAnimMesh.cpp | 40 +- .../assimp/code/Common/DefaultIOStream.cpp | 100 +- .../assimp/code/Common/DefaultIOSystem.cpp | 89 +- .../lib/assimp/code/Common/DefaultLogger.cpp | 256 +- .../code/Common/DefaultProgressHandler.h | 19 +- .../Macros.h => code/Common/Exceptional.cpp} | 19 +- Engine/lib/assimp/code/Common/Exporter.cpp | 210 +- Engine/lib/assimp/code/Common/FileLogStream.h | 43 +- .../lib/assimp/code/Common/FileSystemFilter.h | 15 +- Engine/lib/assimp/code/Common/IFF.h | 29 + Engine/lib/assimp/code/Common/IOSystem.cpp | 53 + Engine/lib/assimp/code/Common/Importer.cpp | 477 +- Engine/lib/assimp/code/Common/Importer.h | 71 +- .../assimp/code/Common/ImporterRegistry.cpp | 264 +- Engine/lib/assimp/code/Common/PolyTools.h | 41 +- .../assimp/code/Common/PostStepRegistry.cpp | 11 +- .../lib/assimp/code/Common/RemoveComments.cpp | 60 +- .../lib/assimp/code/Common/SGSpatialSort.cpp | 6 +- .../lib/assimp/code/Common/SceneCombiner.cpp | 1024 +- .../assimp/code/Common/ScenePreprocessor.cpp | 176 +- .../assimp/code/Common/ScenePreprocessor.h | 35 +- Engine/lib/assimp/code/Common/ScenePrivate.h | 2 +- .../code/Common/SkeletonMeshBuilder.cpp | 210 +- Engine/lib/assimp/code/Common/SpatialSort.cpp | 266 +- .../lib/assimp/code/Common/StandardShapes.cpp | 434 +- .../assimp/code/Common/StdOStreamLogStream.h | 2 +- Engine/lib/assimp/code/Common/Subdivision.cpp | 666 +- .../assimp/code/Common/TargetAnimation.cpp | 152 +- .../lib/assimp/code/Common/TargetAnimation.h | 84 +- Engine/lib/assimp/code/Common/Version.cpp | 117 +- .../code/Common/VertexTriangleAdjacency.cpp | 59 +- .../code/Common/VertexTriangleAdjacency.h | 2 +- .../assimp/code/Common/Win32DebugLogStream.h | 10 +- .../assimp/code/Common/ZipArchiveIOSystem.cpp | 866 +- Engine/lib/assimp/code/Common/assbin_chunks.h | 2 +- Engine/lib/assimp/code/Common/material.cpp | 100 + Engine/lib/assimp/code/Common/scene.cpp | 67 +- Engine/lib/assimp/code/Common/simd.cpp | 4 +- Engine/lib/assimp/code/Common/simd.h | 2 +- Engine/lib/assimp/code/FBX/FBXConverter.cpp | 3615 ----- Engine/lib/assimp/code/FBX/FBXImporter.cpp | 206 - .../code/Importer/StepFile/StepFileGen1.cpp | 2195 --- .../code/Importer/StepFile/StepFileGen2.cpp | 3067 ---- .../code/Importer/StepFile/StepFileGen3.cpp | 5746 ------- .../Importer/StepFile/StepFileImporter.cpp | 114 - .../code/Importer/StepFile/StepReaderGen.h | 7288 --------- Engine/lib/assimp/code/Irr/IRRLoader.cpp | 1488 -- Engine/lib/assimp/code/Irr/IRRMeshLoader.cpp | 536 - Engine/lib/assimp/code/Irr/IRRShared.cpp | 501 - Engine/lib/assimp/code/LWO/LWOFileData.h | 703 - Engine/lib/assimp/code/LWO/LWOLoader.cpp | 1490 -- Engine/lib/assimp/code/LWO/LWOMaterial.cpp | 898 -- Engine/lib/assimp/code/MMD/MMDImporter.cpp | 372 - .../assimp/code/Material/MaterialSystem.cpp | 477 +- .../lib/assimp/code/Material/MaterialSystem.h | 2 +- Engine/lib/assimp/code/Obj/ObjExporter.cpp | 414 - Engine/lib/assimp/code/Obj/ObjExporter.h | 190 - Engine/lib/assimp/code/Obj/ObjFileData.h | 339 - .../lib/assimp/code/Obj/ObjFileImporter.cpp | 784 - Engine/lib/assimp/code/Obj/ObjFileImporter.h | 123 - .../assimp/code/Obj/ObjFileMtlImporter.cpp | 494 - .../lib/assimp/code/Obj/ObjFileMtlImporter.h | 117 - Engine/lib/assimp/code/Obj/ObjFileParser.cpp | 880 -- Engine/lib/assimp/code/Obj/ObjFileParser.h | 165 - Engine/lib/assimp/code/Obj/ObjTools.h | 308 - .../assimp/code/Ogre/OgreBinarySerializer.h | 423 - .../assimp/code/Ogre/OgreXmlSerializer.cpp | 1002 -- .../assimp/code/OpenGEX/OpenGEXImporter.cpp | 1326 -- Engine/lib/assimp/code/Pbrt/PbrtExporter.cpp | 947 ++ Engine/lib/assimp/code/Pbrt/PbrtExporter.h | 135 + Engine/lib/assimp/code/Ply/PlyParser.cpp | 1142 -- .../code/PostProcessing/ArmaturePopulate.cpp | 265 + .../code/PostProcessing/ArmaturePopulate.h | 112 + .../PostProcessing/CalcTangentsProcess.cpp | 180 +- .../code/PostProcessing/CalcTangentsProcess.h | 2 +- .../ComputeUVMappingProcess.cpp | 8 +- .../PostProcessing/ComputeUVMappingProcess.h | 2 +- .../PostProcessing/ConvertToLHProcess.cpp | 190 +- .../code/PostProcessing/ConvertToLHProcess.h | 7 +- .../code/PostProcessing/DeboneProcess.cpp | 7 +- .../code/PostProcessing/DeboneProcess.h | 2 +- .../PostProcessing/DropFaceNormalsProcess.cpp | 14 +- .../PostProcessing/DropFaceNormalsProcess.h | 2 +- .../PostProcessing/EmbedTexturesProcess.cpp | 51 +- .../PostProcessing/EmbedTexturesProcess.h | 7 +- .../code/PostProcessing/FindDegenerates.cpp | 94 +- .../code/PostProcessing/FindDegenerates.h | 2 +- .../PostProcessing/FindInstancesProcess.cpp | 10 +- .../PostProcessing/FindInstancesProcess.h | 2 +- .../PostProcessing/FindInvalidDataProcess.cpp | 197 +- .../PostProcessing/FindInvalidDataProcess.h | 19 +- .../code/PostProcessing/FixNormalsStep.cpp | 4 +- .../code/PostProcessing/FixNormalsStep.h | 2 +- .../GenBoundingBoxesProcess.cpp | 2 +- .../PostProcessing/GenBoundingBoxesProcess.h | 2 +- .../PostProcessing/GenFaceNormalsProcess.cpp | 63 +- .../PostProcessing/GenFaceNormalsProcess.h | 3 +- .../GenVertexNormalsProcess.cpp | 108 +- .../PostProcessing/GenVertexNormalsProcess.h | 3 +- .../PostProcessing/ImproveCacheLocality.cpp | 6 +- .../PostProcessing/ImproveCacheLocality.h | 2 +- .../PostProcessing/JoinVerticesProcess.cpp | 12 +- .../code/PostProcessing/JoinVerticesProcess.h | 2 +- .../LimitBoneWeightsProcess.cpp | 141 +- .../PostProcessing/LimitBoneWeightsProcess.h | 2 +- .../code/PostProcessing/MakeVerboseFormat.cpp | 136 +- .../code/PostProcessing/MakeVerboseFormat.h | 4 +- .../code/PostProcessing/OptimizeGraph.cpp | 431 +- .../code/PostProcessing/OptimizeGraph.h | 8 +- .../code/PostProcessing/OptimizeMeshes.cpp | 4 +- .../code/PostProcessing/OptimizeMeshes.h | 2 +- .../PostProcessing/PretransformVertices.cpp | 1040 +- .../PostProcessing/PretransformVertices.h | 144 +- .../code/PostProcessing/ProcessHelper.cpp | 260 +- .../code/PostProcessing/ProcessHelper.h | 364 +- .../RemoveRedundantMaterials.cpp | 11 +- .../PostProcessing/RemoveRedundantMaterials.h | 4 +- .../code/PostProcessing/RemoveVCProcess.cpp | 160 +- .../code/PostProcessing/RemoveVCProcess.h | 2 +- .../code/PostProcessing/ScaleProcess.cpp | 42 +- .../assimp/code/PostProcessing/ScaleProcess.h | 8 +- .../PostProcessing/SortByPTypeProcess.cpp | 308 +- .../code/PostProcessing/SortByPTypeProcess.h | 2 +- .../SplitByBoneCountProcess.cpp | 121 +- .../SplitByBoneCountProcess.h | 4 +- .../code/PostProcessing/SplitLargeMeshes.cpp | 13 +- .../code/PostProcessing/SplitLargeMeshes.h | 2 +- .../code/PostProcessing/TextureTransform.cpp | 31 +- .../code/PostProcessing/TextureTransform.h | 2 +- .../PostProcessing/TriangulateProcess.cpp | 120 +- .../code/PostProcessing/TriangulateProcess.h | 2 +- .../PostProcessing/ValidateDataStructure.cpp | 841 +- .../PostProcessing/ValidateDataStructure.h | 10 +- .../assimp/code/Q3BSP/Q3BSPFileImporter.cpp | 706 - Engine/lib/assimp/code/Q3D/Q3DLoader.cpp | 619 - Engine/lib/assimp/code/Step/STEPFile.h | 1016 -- Engine/lib/assimp/code/X3D/FIReader.cpp | 1838 --- Engine/lib/assimp/code/X3D/FIReader.hpp | 192 - Engine/lib/assimp/code/X3D/X3DExporter.cpp | 735 - Engine/lib/assimp/code/X3D/X3DExporter.hpp | 235 - Engine/lib/assimp/code/X3D/X3DImporter.cpp | 1735 -- Engine/lib/assimp/code/X3D/X3DImporter.hpp | 834 - .../code/X3D/X3DImporter_Geometry2D.cpp | 522 - .../code/X3D/X3DImporter_Geometry3D.cpp | 999 -- .../lib/assimp/code/X3D/X3DImporter_Light.cpp | 290 - .../lib/assimp/code/X3D/X3DImporter_Macro.hpp | 195 - .../assimp/code/X3D/X3DImporter_Metadata.cpp | 277 - .../lib/assimp/code/X3D/X3DImporter_Node.hpp | 780 - .../code/X3D/X3DImporter_Postprocess.cpp | 827 - .../assimp/code/X3D/X3DImporter_Rendering.cpp | 1071 -- .../lib/assimp/code/X3D/X3DImporter_Shape.cpp | 250 - .../assimp/code/X3D/X3DImporter_Texturing.cpp | 197 - Engine/lib/assimp/code/X3D/X3DVocabulary.cpp | 1676 -- Engine/lib/assimp/code/XGL/XGLLoader.cpp | 956 -- Engine/lib/assimp/code/glTF/glTFAsset.h | 1146 -- Engine/lib/assimp/code/glTF/glTFAsset.inl | 1481 -- Engine/lib/assimp/code/glTF/glTFCommon.h | 248 - Engine/lib/assimp/code/glTF2/glTF2Asset.h | 1101 -- Engine/lib/assimp/code/glTF2/glTF2Asset.inl | 1519 -- .../lib/assimp/code/glTF2/glTF2Exporter.cpp | 1100 -- Engine/lib/assimp/code/glTF2/glTF2Exporter.h | 131 - .../lib/assimp/code/glTF2/glTF2Importer.cpp | 1265 -- Engine/lib/assimp/code/res/assimp.rc | 2 +- Engine/lib/assimp/contrib/CMakeLists.txt | 4 - .../contrib/Open3DGC/o3dgcArithmeticCodec.cpp | 5 +- .../contrib/Open3DGC/o3dgcArithmeticCodec.h | 1 + .../contrib/Open3DGC/o3dgcSC3DMCDecoder.h | 2 +- .../contrib/Open3DGC/o3dgcSC3DMCDecoder.inl | 27 +- .../contrib/Open3DGC/o3dgcSC3DMCEncoder.inl | 19 +- .../lib/assimp/contrib/Open3DGC/o3dgcTimer.h | 2 + .../Open3DGC/o3dgcTriangleListEncoder.inl | 4 +- .../assimp/contrib/Open3DGC/o3dgcVector.inl | 4 +- .../assimp/contrib/android-cmake/README.md | 2 +- .../android-cmake/android.toolchain.cmake | 1 + Engine/lib/assimp/contrib/draco/.clang-format | 5 + .../lib/assimp/contrib/draco/.cmake-format.py | 102 + Engine/lib/assimp/contrib/draco/AUTHORS | 7 + Engine/lib/assimp/contrib/draco/BUILDING.md | 301 + Engine/lib/assimp/contrib/draco/CMAKE.md | 106 + .../lib/assimp/contrib/draco/CMakeLists.txt | 952 ++ .../lib/assimp/contrib/draco/CONTRIBUTING.md | 27 + Engine/lib/assimp/contrib/draco/LICENSE | 252 + Engine/lib/assimp/contrib/draco/README.md | 478 + .../contrib/draco/cmake/DracoConfig.cmake | 3 + .../contrib/draco/cmake/FindDraco.cmake | 56 + .../contrib/draco/cmake/compiler_flags.cmake | 220 + .../contrib/draco/cmake/compiler_tests.cmake | 103 + .../draco/cmake/draco-config.cmake.template | 2 + .../contrib/draco/cmake/draco.pc.template | 11 + .../draco/cmake/draco_build_definitions.cmake | 124 + .../draco/cmake/draco_cpu_detection.cmake | 28 + .../draco/cmake/draco_emscripten.cmake | 185 + .../contrib/draco/cmake/draco_flags.cmake | 247 + .../contrib/draco/cmake/draco_helpers.cmake | 110 + .../contrib/draco/cmake/draco_install.cmake | 79 + .../draco/cmake/draco_intrinsics.cmake | 96 + .../contrib/draco/cmake/draco_options.cmake | 239 + .../contrib/draco/cmake/draco_sanitizer.cmake | 32 + .../contrib/draco/cmake/draco_targets.cmake | 355 + .../draco/cmake/draco_test_config.h.cmake | 13 + .../contrib/draco/cmake/draco_tests.cmake | 133 + .../contrib/draco/cmake/draco_variables.cmake | 64 + .../contrib/draco/cmake/sanitizers.cmake | 19 + .../cmake/toolchains/aarch64-linux-gnu.cmake | 14 + .../cmake/toolchains/android-ndk-common.cmake | 23 + .../draco/cmake/toolchains/android.cmake | 39 + .../cmake/toolchains/arm-ios-common.cmake | 17 + .../toolchains/arm-linux-gnueabihf.cmake | 15 + .../toolchains/arm64-android-ndk-libcpp.cmake | 16 + .../draco/cmake/toolchains/arm64-ios.cmake | 14 + .../cmake/toolchains/arm64-linux-gcc.cmake | 18 + .../toolchains/armv7-android-ndk-libcpp.cmake | 16 + .../draco/cmake/toolchains/armv7-ios.cmake | 14 + .../cmake/toolchains/armv7-linux-gcc.cmake | 24 + .../draco/cmake/toolchains/armv7s-ios.cmake | 14 + .../draco/cmake/toolchains/i386-ios.cmake | 15 + .../toolchains/x86-android-ndk-libcpp.cmake | 16 + .../x86_64-android-ndk-libcpp.cmake | 16 + .../draco/cmake/toolchains/x86_64-ios.cmake | 15 + .../lib/assimp/contrib/draco/cmake/util.cmake | 79 + .../src/draco/animation/keyframe_animation.cc | 54 + .../src/draco/animation/keyframe_animation.h | 107 + .../animation/keyframe_animation_decoder.cc | 30 + .../animation/keyframe_animation_decoder.h | 34 + .../animation/keyframe_animation_encoder.cc | 28 + .../animation/keyframe_animation_encoder.h | 39 + .../keyframe_animation_encoding_test.cc | 168 + .../animation/keyframe_animation_test.cc | 102 + .../attribute_octahedron_transform.cc | 145 + .../attribute_octahedron_transform.h | 81 + .../attribute_quantization_transform.cc | 260 + .../attribute_quantization_transform.h | 102 + .../draco/attributes/attribute_transform.cc | 40 + .../draco/attributes/attribute_transform.h | 76 + .../attributes/attribute_transform_data.h | 71 + .../attributes/attribute_transform_type.h | 30 + .../draco/attributes/geometry_attribute.cc | 102 + .../src/draco/attributes/geometry_attribute.h | 350 + .../src/draco/attributes/geometry_indices.h | 54 + .../src/draco/attributes/point_attribute.cc | 225 + .../src/draco/attributes/point_attribute.h | 190 + .../draco/attributes/point_attribute_test.cc | 128 + .../attributes/attributes_decoder.cc | 127 + .../attributes/attributes_decoder.h | 97 + .../attributes/attributes_decoder_interface.h | 62 + .../attributes/attributes_encoder.cc | 49 + .../attributes/attributes_encoder.h | 154 + .../attributes/kd_tree_attributes_decoder.cc | 556 + .../attributes/kd_tree_attributes_decoder.h | 46 + .../attributes/kd_tree_attributes_encoder.cc | 305 + .../attributes/kd_tree_attributes_encoder.h | 51 + .../attributes/kd_tree_attributes_shared.h | 28 + .../compression/attributes/linear_sequencer.h | 51 + .../mesh_attribute_indices_encoding_data.h | 58 + .../attributes/normal_compression_utils.h | 360 + .../compression/attributes/point_d_vector.h | 279 + .../attributes/point_d_vector_test.cc | 360 + .../compression/attributes/points_sequencer.h | 63 + ..._constrained_multi_parallelogram_decoder.h | 231 + ..._constrained_multi_parallelogram_encoder.h | 414 + ...e_constrained_multi_parallelogram_shared.h | 34 + .../mesh_prediction_scheme_data.h | 72 + .../mesh_prediction_scheme_decoder.h | 46 + .../mesh_prediction_scheme_encoder.h | 46 + ...ediction_scheme_geometric_normal_decoder.h | 172 + ...ediction_scheme_geometric_normal_encoder.h | 180 + ...n_scheme_geometric_normal_predictor_area.h | 117 + ...n_scheme_geometric_normal_predictor_base.h | 96 + ...ction_scheme_multi_parallelogram_decoder.h | 126 + ...ction_scheme_multi_parallelogram_encoder.h | 133 + ..._prediction_scheme_parallelogram_decoder.h | 98 + ..._prediction_scheme_parallelogram_encoder.h | 111 + ...h_prediction_scheme_parallelogram_shared.h | 78 + ...esh_prediction_scheme_tex_coords_decoder.h | 344 + ...esh_prediction_scheme_tex_coords_encoder.h | 318 + ...ction_scheme_tex_coords_portable_decoder.h | 143 + ...ction_scheme_tex_coords_portable_encoder.h | 133 + ...ion_scheme_tex_coords_portable_predictor.h | 263 + .../prediction_scheme_decoder.h | 90 + .../prediction_scheme_decoder_factory.h | 194 + .../prediction_scheme_decoder_interface.h | 53 + .../prediction_scheme_decoding_transform.h | 65 + .../prediction_scheme_delta_decoder.h | 65 + .../prediction_scheme_delta_encoder.h | 69 + .../prediction_scheme_encoder.h | 90 + .../prediction_scheme_encoder_factory.cc | 85 + .../prediction_scheme_encoder_factory.h | 129 + .../prediction_scheme_encoder_interface.h | 55 + .../prediction_scheme_encoding_transform.h | 77 + .../prediction_scheme_factory.h | 85 + .../prediction_scheme_interface.h | 60 + ...ahedron_canonicalized_decoding_transform.h | 118 + ...ahedron_canonicalized_encoding_transform.h | 116 + ..._octahedron_canonicalized_transform_base.h | 102 + ...octahedron_canonicalized_transform_test.cc | 192 + ...eme_normal_octahedron_decoding_transform.h | 103 + ...eme_normal_octahedron_encoding_transform.h | 105 + ..._scheme_normal_octahedron_transform_base.h | 90 + ...scheme_normal_octahedron_transform_test.cc | 71 + ...rediction_scheme_wrap_decoding_transform.h | 88 + ...rediction_scheme_wrap_encoding_transform.h | 81 + .../prediction_scheme_wrap_transform_base.h | 120 + .../sequential_attribute_decoder.cc | 118 + .../attributes/sequential_attribute_decoder.h | 86 + ...equential_attribute_decoders_controller.cc | 149 + ...sequential_attribute_decoders_controller.h | 61 + .../sequential_attribute_encoder.cc | 108 + .../attributes/sequential_attribute_encoder.h | 134 + ...equential_attribute_encoders_controller.cc | 159 + ...sequential_attribute_encoders_controller.h | 115 + .../sequential_integer_attribute_decoder.cc | 240 + .../sequential_integer_attribute_decoder.h | 76 + .../sequential_integer_attribute_encoder.cc | 233 + .../sequential_integer_attribute_encoder.h | 67 + ...uential_integer_attribute_encoding_test.cc | 64 + .../sequential_normal_attribute_decoder.cc | 76 + .../sequential_normal_attribute_decoder.h | 83 + .../sequential_normal_attribute_encoder.cc | 57 + .../sequential_normal_attribute_encoder.h | 82 + ...quential_quantization_attribute_decoder.cc | 88 + ...equential_quantization_attribute_decoder.h | 52 + ...quential_quantization_attribute_encoder.cc | 86 + ...equential_quantization_attribute_encoder.h | 52 + .../adaptive_rans_bit_coding_shared.h | 43 + .../bit_coders/adaptive_rans_bit_decoder.cc | 70 + .../bit_coders/adaptive_rans_bit_decoder.h | 54 + .../bit_coders/adaptive_rans_bit_encoder.cc | 59 + .../bit_coders/adaptive_rans_bit_encoder.h | 61 + .../bit_coders/direct_bit_decoder.cc | 54 + .../bit_coders/direct_bit_decoder.h | 90 + .../bit_coders/direct_bit_encoder.cc | 39 + .../bit_coders/direct_bit_encoder.h | 89 + .../bit_coders/folded_integer_bit_decoder.h | 77 + .../bit_coders/folded_integer_bit_encoder.h | 82 + .../bit_coders/rans_bit_decoder.cc | 82 + .../compression/bit_coders/rans_bit_decoder.h | 55 + .../bit_coders/rans_bit_encoder.cc | 125 + .../compression/bit_coders/rans_bit_encoder.h | 57 + .../bit_coders/rans_coding_test.cc | 9 + .../bit_coders/symbol_bit_decoder.cc | 49 + .../bit_coders/symbol_bit_decoder.h | 36 + .../bit_coders/symbol_bit_encoder.cc | 30 + .../bit_coders/symbol_bit_encoder.h | 36 + .../compression/config/compression_shared.h | 155 + .../compression/config/decoder_options.h | 34 + .../config/decoder_options_test.cc | 67 + .../draco/compression/config/draco_options.h | 249 + .../compression/config/encoder_options.h | 97 + .../compression/config/encoding_features.h | 39 + .../draco/src/draco/compression/decode.cc | 135 + .../draco/src/draco/compression/decode.h | 80 + .../src/draco/compression/decode_test.cc | 169 + .../draco/src/draco/compression/encode.cc | 96 + .../draco/src/draco/compression/encode.h | 140 + .../draco/src/draco/compression/encode_base.h | 131 + .../src/draco/compression/encode_test.cc | 407 + .../draco/src/draco/compression/entropy/ans.h | 527 + .../compression/entropy/rans_symbol_coding.h | 53 + .../compression/entropy/rans_symbol_decoder.h | 164 + .../compression/entropy/rans_symbol_encoder.h | 290 + .../compression/entropy/shannon_entropy.cc | 147 + .../compression/entropy/shannon_entropy.h | 110 + .../entropy/shannon_entropy_test.cc | 58 + .../compression/entropy/symbol_coding_test.cc | 170 + .../compression/entropy/symbol_decoding.cc | 181 + .../compression/entropy/symbol_decoding.h | 29 + .../compression/entropy/symbol_encoding.cc | 376 + .../compression/entropy/symbol_encoding.h | 47 + .../src/draco/compression/expert_encode.cc | 182 + .../src/draco/compression/expert_encode.h | 147 + .../draco/compression/mesh/mesh_decoder.cc | 37 + .../src/draco/compression/mesh/mesh_decoder.h | 68 + .../mesh/mesh_edgebreaker_decoder.cc | 70 + .../mesh/mesh_edgebreaker_decoder.h | 54 + .../mesh/mesh_edgebreaker_decoder_impl.cc | 1231 ++ .../mesh/mesh_edgebreaker_decoder_impl.h | 228 + .../mesh_edgebreaker_decoder_impl_interface.h | 47 + .../mesh/mesh_edgebreaker_encoder.cc | 195 + .../mesh/mesh_edgebreaker_encoder.h | 73 + .../mesh/mesh_edgebreaker_encoder_impl.cc | 854 + .../mesh/mesh_edgebreaker_encoder_impl.h | 210 + .../mesh_edgebreaker_encoder_impl_interface.h | 57 + .../mesh/mesh_edgebreaker_encoding_test.cc | 247 + .../mesh/mesh_edgebreaker_shared.h | 131 + .../mesh/mesh_edgebreaker_traversal_decoder.h | 201 + .../mesh/mesh_edgebreaker_traversal_encoder.h | 139 + ...edgebreaker_traversal_predictive_decoder.h | 134 + ...edgebreaker_traversal_predictive_encoder.h | 172 + ...sh_edgebreaker_traversal_valence_decoder.h | 215 + ...sh_edgebreaker_traversal_valence_encoder.h | 226 + .../draco/compression/mesh/mesh_encoder.cc | 34 + .../src/draco/compression/mesh/mesh_encoder.h | 84 + .../compression/mesh/mesh_encoder_test.cc | 116 + .../mesh/mesh_sequential_decoder.cc | 169 + .../mesh/mesh_sequential_decoder.h | 39 + .../mesh/mesh_sequential_encoder.cc | 132 + .../mesh/mesh_sequential_encoder.h | 57 + .../mesh/traverser/depth_first_traverser.h | 172 + .../max_prediction_degree_traverser.h | 226 + ...mesh_attribute_indices_encoding_observer.h | 76 + .../mesh/traverser/mesh_traversal_sequencer.h | 113 + .../mesh/traverser/traverser_base.h | 87 + .../dynamic_integer_points_kd_tree_decoder.cc | 26 + .../dynamic_integer_points_kd_tree_decoder.h | 330 + .../dynamic_integer_points_kd_tree_encoder.cc | 26 + .../dynamic_integer_points_kd_tree_encoder.h | 371 + .../algorithms/float_points_tree_decoder.cc | 152 + .../algorithms/float_points_tree_decoder.h | 141 + .../algorithms/float_points_tree_encoder.cc | 94 + .../algorithms/float_points_tree_encoder.h | 126 + .../integer_points_kd_tree_decoder.cc | 45 + .../integer_points_kd_tree_decoder.h | 314 + .../integer_points_kd_tree_encoder.cc | 45 + .../integer_points_kd_tree_encoder.h | 404 + .../point_cloud_compression_method.h | 34 + .../algorithms/point_cloud_types.h | 76 + .../algorithms/quantize_points_3.h | 84 + .../point_cloud/algorithms/queuing_policy.h | 75 + .../point_cloud/point_cloud_decoder.cc | 199 + .../point_cloud/point_cloud_decoder.h | 118 + .../point_cloud/point_cloud_encoder.cc | 306 + .../point_cloud/point_cloud_encoder.h | 158 + .../point_cloud_kd_tree_decoder.cc | 40 + .../point_cloud/point_cloud_kd_tree_decoder.h | 31 + .../point_cloud_kd_tree_encoder.cc | 43 + .../point_cloud/point_cloud_kd_tree_encoder.h | 45 + .../point_cloud_kd_tree_encoding_test.cc | 458 + .../point_cloud_sequential_decoder.cc | 42 + .../point_cloud_sequential_decoder.h | 33 + .../point_cloud_sequential_encoder.cc | 49 + .../point_cloud_sequential_encoder.h | 43 + .../point_cloud_sequential_encoding_test.cc | 92 + .../contrib/draco/src/draco/core/bit_utils.cc | 36 + .../contrib/draco/src/draco/core/bit_utils.h | 124 + .../draco/src/draco/core/bounding_box.cc | 30 + .../draco/src/draco/core/bounding_box.h | 72 + .../src/draco/core/buffer_bit_coding_test.cc | 115 + .../draco/src/draco/core/cycle_timer.cc | 49 + .../draco/src/draco/core/cycle_timer.h | 51 + .../draco/src/draco/core/data_buffer.cc | 61 + .../draco/src/draco/core/data_buffer.h | 82 + .../draco/src/draco/core/decoder_buffer.cc | 72 + .../draco/src/draco/core/decoder_buffer.h | 216 + .../contrib/draco/src/draco/core/divide.cc | 88 + .../contrib/draco/src/draco/core/divide.h | 42 + .../draco/src/draco/core/draco_index_type.h | 183 + .../src/draco/core/draco_index_type_vector.h | 83 + .../draco/src/draco/core/draco_test_base.h | 11 + .../draco/src/draco/core/draco_test_utils.cc | 80 + .../draco/src/draco/core/draco_test_utils.h | 93 + .../draco/src/draco/core/draco_types.cc | 61 + .../draco/src/draco/core/draco_types.h | 52 + .../draco/src/draco/core/draco_version.h | 27 + .../draco/src/draco/core/encoder_buffer.cc | 93 + .../draco/src/draco/core/encoder_buffer.h | 152 + .../draco/src/draco/core/hash_utils.cc | 58 + .../contrib/draco/src/draco/core/hash_utils.h | 64 + .../contrib/draco/src/draco/core/macros.h | 119 + .../contrib/draco/src/draco/core/math_utils.h | 55 + .../draco/src/draco/core/math_utils_test.cc | 22 + .../contrib/draco/src/draco/core/options.cc | 94 + .../contrib/draco/src/draco/core/options.h | 150 + .../src/draco/core/quantization_utils.cc | 42 + .../draco/src/draco/core/quantization_utils.h | 82 + .../src/draco/core/quantization_utils_test.cc | 91 + .../contrib/draco/src/draco/core/status.h | 77 + .../contrib/draco/src/draco/core/status_or.h | 81 + .../draco/src/draco/core/status_test.cc | 38 + .../draco/src/draco/core/varint_decoding.h | 81 + .../draco/src/draco/core/varint_encoding.h | 61 + .../contrib/draco/src/draco/core/vector_d.h | 355 + .../draco/src/draco/core/vector_d_test.cc | 306 + .../draco/src/draco/io/file_reader_factory.cc | 45 + .../draco/src/draco/io/file_reader_factory.h | 34 + .../src/draco/io/file_reader_factory_test.cc | 85 + .../src/draco/io/file_reader_interface.h | 32 + .../src/draco/io/file_reader_test_common.h | 13 + .../contrib/draco/src/draco/io/file_utils.cc | 110 + .../contrib/draco/src/draco/io/file_utils.h | 73 + .../draco/src/draco/io/file_utils_test.cc | 69 + .../draco/src/draco/io/file_writer_factory.cc | 45 + .../draco/src/draco/io/file_writer_factory.h | 34 + .../src/draco/io/file_writer_factory_test.cc | 70 + .../src/draco/io/file_writer_interface.h | 26 + .../draco/src/draco/io/file_writer_utils.cc | 57 + .../draco/src/draco/io/file_writer_utils.h | 38 + .../contrib/draco/src/draco/io/mesh_io.cc | 87 + .../contrib/draco/src/draco/io/mesh_io.h | 107 + .../contrib/draco/src/draco/io/obj_decoder.cc | 708 + .../contrib/draco/src/draco/io/obj_decoder.h | 129 + .../draco/src/draco/io/obj_decoder_test.cc | 193 + .../contrib/draco/src/draco/io/obj_encoder.cc | 346 + .../contrib/draco/src/draco/io/obj_encoder.h | 92 + .../draco/src/draco/io/obj_encoder_test.cc | 110 + .../draco/src/draco/io/parser_utils.cc | 261 + .../contrib/draco/src/draco/io/parser_utils.h | 66 + .../contrib/draco/src/draco/io/ply_decoder.cc | 320 + .../contrib/draco/src/draco/io/ply_decoder.h | 69 + .../draco/src/draco/io/ply_decoder_test.cc | 93 + .../contrib/draco/src/draco/io/ply_encoder.cc | 211 + .../contrib/draco/src/draco/io/ply_encoder.h | 54 + .../draco/src/draco/io/ply_property_reader.h | 96 + .../draco/src/draco/io/ply_property_writer.h | 94 + .../contrib/draco/src/draco/io/ply_reader.cc | 312 + .../contrib/draco/src/draco/io/ply_reader.h | 155 + .../draco/src/draco/io/ply_reader_test.cc | 143 + .../draco/src/draco/io/point_cloud_io.cc | 58 + .../draco/src/draco/io/point_cloud_io.h | 89 + .../draco/src/draco/io/point_cloud_io_test.cc | 115 + .../draco/src/draco/io/stdio_file_reader.cc | 103 + .../draco/src/draco/io/stdio_file_reader.h | 48 + .../src/draco/io/stdio_file_reader_test.cc | 49 + .../draco/src/draco/io/stdio_file_writer.cc | 59 + .../draco/src/draco/io/stdio_file_writer.h | 42 + .../src/draco/io/stdio_file_writer_test.cc | 38 + .../animation_decoder_webidl_wrapper.cc | 101 + .../animation_decoder_webidl_wrapper.h | 73 + .../animation_encoder_webidl_wrapper.cc | 89 + .../animation_encoder_webidl_wrapper.h | 66 + .../emscripten/decoder_functions.js | 33 + .../emscripten/decoder_webidl_wrapper.cc | 363 + .../emscripten/decoder_webidl_wrapper.h | 330 + .../draco_animation_decoder_glue_wrapper.cc | 28 + .../draco_animation_encoder_glue_wrapper.cc | 25 + .../draco_animation_web_decoder.idl | 52 + .../draco_animation_web_encoder.idl | 34 + .../emscripten/draco_decoder_glue_wrapper.cc | 28 + .../emscripten/draco_encoder_glue_wrapper.cc | 25 + .../emscripten/draco_web_decoder.idl | 283 + .../emscripten/draco_web_encoder.idl | 208 + .../emscripten/encoder_webidl_wrapper.cc | 359 + .../emscripten/encoder_webidl_wrapper.h | 186 + .../draco/javascript/emscripten/finalize.js | 22 + .../javascript/emscripten/prepareCallbacks.js | 38 + .../draco/javascript/emscripten/version.js | 29 + .../draco/src/draco/maya/draco_maya_plugin.cc | 265 + .../draco/src/draco/maya/draco_maya_plugin.h | 81 + .../draco/src/draco/mesh/corner_table.cc | 441 + .../draco/src/draco/mesh/corner_table.h | 396 + .../src/draco/mesh/corner_table_iterators.h | 289 + .../contrib/draco/src/draco/mesh/mesh.cc | 40 + .../contrib/draco/src/draco/mesh/mesh.h | 152 + .../src/draco/mesh/mesh_are_equivalent.cc | 205 + .../src/draco/mesh/mesh_are_equivalent.h | 71 + .../draco/mesh/mesh_are_equivalent_test.cc | 98 + .../draco/mesh/mesh_attribute_corner_table.cc | 211 + .../draco/mesh/mesh_attribute_corner_table.h | 196 + .../draco/src/draco/mesh/mesh_cleanup.cc | 251 + .../draco/src/draco/mesh/mesh_cleanup.h | 65 + .../draco/src/draco/mesh/mesh_cleanup_test.cc | 192 + .../src/draco/mesh/mesh_misc_functions.cc | 63 + .../src/draco/mesh/mesh_misc_functions.h | 98 + .../draco/src/draco/mesh/mesh_stripifier.cc | 102 + .../draco/src/draco/mesh/mesh_stripifier.h | 260 + .../draco/mesh/triangle_soup_mesh_builder.cc | 89 + .../draco/mesh/triangle_soup_mesh_builder.h | 63 + .../mesh/triangle_soup_mesh_builder_test.cc | 197 + .../draco/src/draco/mesh/valence_cache.h | 142 + .../src/draco/metadata/geometry_metadata.cc | 44 + .../src/draco/metadata/geometry_metadata.h | 140 + .../draco/src/draco/metadata/metadata.cc | 132 + .../draco/src/draco/metadata/metadata.h | 208 + .../src/draco/metadata/metadata_decoder.cc | 148 + .../src/draco/metadata/metadata_decoder.h | 42 + .../src/draco/metadata/metadata_encoder.cc | 97 + .../src/draco/metadata/metadata_encoder.h | 41 + .../draco/metadata/metadata_encoder_test.cc | 167 + .../draco/src/draco/metadata/metadata_test.cc | 157 + .../src/draco/point_cloud/point_cloud.cc | 275 + .../draco/src/draco/point_cloud/point_cloud.h | 244 + .../draco/point_cloud/point_cloud_builder.cc | 76 + .../draco/point_cloud/point_cloud_builder.h | 80 + .../point_cloud/point_cloud_builder_test.cc | 171 + .../src/draco/point_cloud/point_cloud_test.cc | 132 + .../draco/src/draco/tools/draco_decoder.cc | 168 + .../draco/src/draco/tools/draco_encoder.cc | 369 + .../draco/src/draco/tools/fuzz/build.sh | 35 + .../tools/fuzz/draco_mesh_decoder_fuzzer.cc | 29 + ...h_decoder_without_dequantization_fuzzer.cc | 30 + .../tools/fuzz/draco_pc_decoder_fuzzer.cc | 29 + ...c_decoder_without_dequantization_fuzzer.cc | 30 + .../src/draco/unity/draco_unity_plugin.cc | 407 + .../src/draco/unity/draco_unity_plugin.h | 154 + .../draco/unity/draco_unity_plugin_test.cc | 243 + .../lib/assimp/contrib/gtest/CMakeLists.txt | 2 +- .../contrib/gtest/docs/Documentation.md | 2 +- .../contrib/gtest/docs/V1_5_Documentation.md | 2 +- .../contrib/gtest/docs/V1_5_PumpManual.md | 2 +- .../contrib/gtest/docs/V1_5_XcodeGuide.md | 2 +- .../contrib/gtest/docs/V1_6_Documentation.md | 2 +- .../contrib/gtest/docs/V1_6_XcodeGuide.md | 2 +- .../contrib/gtest/docs/V1_7_Documentation.md | 2 +- .../contrib/gtest/docs/V1_7_XcodeGuide.md | 2 +- .../assimp/contrib/gtest/docs/XcodeGuide.md | 2 +- .../include/gtest/internal/gtest-internal.h | 2 +- .../include/gtest/internal/gtest-param-util.h | 2 +- .../gtest/include/gtest/internal/gtest-port.h | 14 + .../assimp/contrib/gtest/src/gtest-port.cc | 3 +- .../CMakeDirectoryInformation.cmake | 16 - .../CMakeFiles/IrrXML.dir/DependInfo.cmake | 19 - .../irrXML/CMakeFiles/IrrXML.dir/build.make | 111 - .../CMakeFiles/IrrXML.dir/cmake_clean.cmake | 11 - .../IrrXML.dir/cmake_clean_target.cmake | 3 - .../IrrXML.dir/compiler_depend.make | 2 - .../CMakeFiles/IrrXML.dir/compiler_depend.ts | 2 - .../irrXML/CMakeFiles/IrrXML.dir/depend.make | 2 - .../irrXML/CMakeFiles/IrrXML.dir/flags.make | 10 - .../irrXML/CMakeFiles/IrrXML.dir/irrXML.cpp.o | Bin 295872 -> 0 bytes .../CMakeFiles/IrrXML.dir/irrXML.cpp.o.d | 50 - .../irrXML/CMakeFiles/IrrXML.dir/link.txt | 2 - .../CMakeFiles/IrrXML.dir/progress.make | 3 - .../contrib/irrXML/CMakeFiles/progress.marks | 1 - .../lib/assimp/contrib/irrXML/CMakeLists.txt | 29 - .../assimp/contrib/irrXML/CXMLReaderImpl.h | 813 - Engine/lib/assimp/contrib/irrXML/Makefile | 231 - .../assimp/contrib/irrXML/cmake_install.cmake | 48 - Engine/lib/assimp/contrib/irrXML/heapsort.h | 73 - Engine/lib/assimp/contrib/irrXML/irrArray.h | 443 - Engine/lib/assimp/contrib/irrXML/irrString.h | 664 - Engine/lib/assimp/contrib/irrXML/irrTypes.h | 108 - Engine/lib/assimp/contrib/irrXML/irrXML.cpp | 151 - Engine/lib/assimp/contrib/irrXML/irrXML.h | 546 - Engine/lib/assimp/contrib/irrXML_note.txt | 6 - .../contrib/openddlparser/CMakeLists.txt | 26 +- .../contrib/openddlparser/code/DDLNode.cpp | 144 +- .../openddlparser/code/OpenDDLCommon.cpp | 144 +- .../openddlparser/code/OpenDDLExport.cpp | 339 +- .../openddlparser/code/OpenDDLParser.cpp | 1032 +- .../openddlparser/code/OpenDDLStream.cpp | 30 +- .../contrib/openddlparser/code/Value.cpp | 393 +- .../include/openddlparser/DDLNode.h | 38 +- .../include/openddlparser/OpenDDLCommon.h | 149 +- .../include/openddlparser/OpenDDLExport.h | 26 +- .../include/openddlparser/OpenDDLParser.h | 117 +- .../openddlparser/OpenDDLParserUtils.h | 451 +- .../include/openddlparser/OpenDDLStream.h | 8 +- .../include/openddlparser/TPoolAllocator.h | 226 + .../include/openddlparser/Value.h | 4 +- Engine/lib/assimp/contrib/poly2tri/README | 4 +- .../poly2tri/poly2tri/common/shapes.cc | 2 +- .../contrib/poly2tri/poly2tri/common/shapes.h | 2 +- .../contrib/poly2tri/poly2tri/poly2tri.h | 2 +- .../poly2tri/sweep/advancing_front.cc | 2 +- .../poly2tri/poly2tri/sweep/advancing_front.h | 2 +- .../contrib/poly2tri/poly2tri/sweep/cdt.cc | 2 +- .../contrib/poly2tri/poly2tri/sweep/cdt.h | 2 +- .../contrib/poly2tri/poly2tri/sweep/sweep.cc | 16 +- .../contrib/poly2tri/poly2tri/sweep/sweep.h | 2 +- .../lib/assimp/contrib/pugixml/CMakeLists.txt | 87 + .../contrib/pugixml/contrib/foreach.hpp | 63 + Engine/lib/assimp/contrib/pugixml/readme.txt | 50 + .../assimp/contrib/pugixml/src/pugiconfig.hpp | 77 + .../assimp/contrib/pugixml/src/pugixml.cpp | 13020 ++++++++++++++++ .../assimp/contrib/pugixml/src/pugixml.hpp | 1499 ++ .../rapidjson/include/rapidjson/allocators.h | 25 +- .../include/rapidjson/cursorstreamwrapper.h | 78 + .../rapidjson/include/rapidjson/document.h | 254 +- .../include/rapidjson/encodedstream.h | 2 +- .../rapidjson/include/rapidjson/encodings.h | 62 +- .../rapidjson/include/rapidjson/error/en.h | 50 +- .../rapidjson/include/rapidjson/error/error.h | 57 +- .../include/rapidjson/filereadstream.h | 6 +- .../include/rapidjson/filewritestream.h | 6 +- .../contrib/rapidjson/include/rapidjson/fwd.h | 4 +- .../include/rapidjson/internal/biginteger.h | 6 +- .../include/rapidjson/internal/clzll.h | 71 + .../include/rapidjson/internal/diyfp.h | 53 +- .../include/rapidjson/internal/dtoa.h | 2 +- .../include/rapidjson/internal/ieee754.h | 2 +- .../include/rapidjson/internal/itoa.h | 84 +- .../include/rapidjson/internal/meta.h | 11 +- .../include/rapidjson/internal/pow10.h | 2 +- .../include/rapidjson/internal/regex.h | 45 +- .../include/rapidjson/internal/stack.h | 9 +- .../include/rapidjson/internal/strfunc.h | 2 +- .../include/rapidjson/internal/strtod.h | 99 +- .../include/rapidjson/internal/swap.h | 2 +- .../include/rapidjson/istreamwrapper.h | 89 +- .../include/rapidjson/memorybuffer.h | 2 +- .../include/rapidjson/memorystream.h | 2 +- .../include/rapidjson/ostreamwrapper.h | 2 +- .../rapidjson/include/rapidjson/pointer.h | 91 +- .../include/rapidjson/prettywriter.h | 30 +- .../rapidjson/include/rapidjson/rapidjson.h | 100 +- .../rapidjson/include/rapidjson/reader.h | 175 +- .../rapidjson/include/rapidjson/schema.h | 950 +- .../rapidjson/include/rapidjson/stream.h | 54 +- .../include/rapidjson/stringbuffer.h | 2 +- .../rapidjson/include/rapidjson/writer.h | 41 +- .../contrib/{stb_image => stb}/stb_image.h | 648 +- Engine/lib/assimp/contrib/unzip/crypt.c | 171 + Engine/lib/assimp/contrib/unzip/crypt.h | 159 +- Engine/lib/assimp/contrib/unzip/ioapi.c | 408 +- Engine/lib/assimp/contrib/unzip/ioapi.h | 144 +- Engine/lib/assimp/contrib/unzip/unzip.c | 2959 ++-- Engine/lib/assimp/contrib/unzip/unzip.h | 500 +- .../contrib/utf8cpp/source/utf8/checked.h | 62 +- .../assimp/contrib/utf8cpp/source/utf8/core.h | 43 +- .../contrib/utf8cpp/source/utf8/cpp11.h | 103 + .../contrib/utf8cpp/source/utf8/unchecked.h | 78 +- Engine/lib/assimp/contrib/zip/.travis.sh | 2 +- Engine/lib/assimp/contrib/zip/.travis.yml | 2 +- Engine/lib/assimp/contrib/zip/CMakeLists.txt | 115 +- Engine/lib/assimp/contrib/zip/README.md | 208 +- Engine/lib/assimp/contrib/zip/src/miniz.h | 531 +- Engine/lib/assimp/contrib/zip/src/zip.c | 1175 +- Engine/lib/assimp/contrib/zip/src/zip.h | 551 +- .../assimp/contrib/zip/test/CMakeLists.txt | 51 +- Engine/lib/assimp/contrib/zip/test/test.c | 42 +- .../lib/assimp/contrib/zip/test/test_miniz.c | 25 +- Engine/lib/assimp/contrib/zlib/CMakeLists.txt | 15 +- .../contrib/zlib/contrib/blast/test.txt | 2 +- .../zlib/contrib/dotzlib/LICENSE_1_0.txt | 2 +- .../zlib/contrib/testzlib/testzlib.txt | 2 +- Engine/lib/assimp/contrib/zlib_note.txt | 2 +- Engine/lib/assimp/include/assimp/Base64.hpp | 68 + .../lib/assimp/include/assimp/BaseImporter.h | 242 +- Engine/lib/assimp/include/assimp/Bitmap.h | 62 +- .../lib/assimp/include/assimp/BlobIOSystem.h | 237 +- .../lib/assimp/include/assimp/ByteSwapper.h | 41 +- .../assimp/{Defines.h => ColladaMetaData.h} | 21 +- .../assimp/include/assimp/Compiler/poppack1.h | 6 +- .../include/assimp/Compiler/pushpack1.h | 6 +- .../assimp/include/assimp/CreateAnimMesh.h | 29 +- .../assimp/include/assimp/DefaultIOStream.h | 67 +- .../assimp/include/assimp/DefaultIOSystem.h | 22 +- .../assimp/include/assimp/DefaultLogger.hpp | 71 +- .../lib/assimp/include/assimp/Exceptional.h | 127 +- Engine/lib/assimp/include/assimp/Exporter.hpp | 142 +- .../assimp/include/assimp/GenericProperty.h | 46 +- .../lib/assimp/include/assimp/GltfMaterial.h | 74 + Engine/lib/assimp/include/assimp/Hash.h | 18 +- Engine/lib/assimp/include/assimp/IOStream.hpp | 16 +- .../assimp/include/assimp/IOStreamBuffer.h | 227 +- Engine/lib/assimp/include/assimp/IOSystem.hpp | 71 +- Engine/lib/assimp/include/assimp/Importer.hpp | 238 +- .../lib/assimp/include/assimp/LineSplitter.h | 68 +- Engine/lib/assimp/include/assimp/LogAux.h | 70 +- .../lib/assimp/include/assimp/LogStream.hpp | 31 +- Engine/lib/assimp/include/assimp/Logger.hpp | 158 +- .../lib/assimp/include/assimp/MathFunctions.h | 47 +- .../assimp/include/assimp/MemoryIOWrapper.h | 16 +- .../lib/assimp/include/assimp/NullLogger.hpp | 14 +- .../lib/assimp/include/assimp/ObjMaterial.h | 84 + .../lib/assimp/include/assimp/ParsingUtils.h | 163 +- Engine/lib/assimp/include/assimp/Profiler.h | 20 +- .../assimp/include/assimp/ProgressHandler.hpp | 13 +- .../assimp/include/assimp/RemoveComments.h | 10 +- .../lib/assimp/include/assimp/SGSpatialSort.h | 7 +- .../lib/assimp/include/assimp/SceneCombiner.h | 206 +- .../include/assimp/SkeletonMeshBuilder.h | 43 +- .../lib/assimp/include/assimp/SmallVector.h | 164 + .../assimp/include/assimp/SmoothingGroups.h | 8 +- .../assimp/include/assimp/SmoothingGroups.inl | 31 +- .../lib/assimp/include/assimp/SpatialSort.h | 76 +- .../assimp/include/assimp/StandardShapes.h | 10 +- .../lib/assimp/include/assimp/StreamReader.h | 181 +- .../lib/assimp/include/assimp/StreamWriter.h | 10 +- .../assimp/include/assimp/StringComparison.h | 103 +- .../lib/assimp/include/assimp/StringUtils.h | 224 +- .../lib/assimp/include/assimp/Subdivision.h | 7 +- .../lib/assimp/include/assimp/TinyFormatter.h | 71 +- Engine/lib/assimp/include/assimp/Vertex.h | 79 +- Engine/lib/assimp/include/assimp/XMLTools.h | 7 +- Engine/lib/assimp/include/assimp/XmlParser.h | 493 + .../include/assimp/ZipArchiveIOSystem.h | 59 +- Engine/lib/assimp/include/assimp/aabb.h | 33 +- Engine/lib/assimp/include/assimp/ai_assert.h | 35 +- Engine/lib/assimp/include/assimp/anim.h | 277 +- Engine/lib/assimp/include/assimp/camera.h | 49 +- Engine/lib/assimp/include/assimp/cexport.h | 126 +- Engine/lib/assimp/include/assimp/cfileio.h | 13 +- Engine/lib/assimp/include/assimp/cimport.h | 836 +- Engine/lib/assimp/include/assimp/color4.h | 17 +- Engine/lib/assimp/include/assimp/color4.inl | 98 +- .../assimp/include/assimp/commonMetaData.h | 69 + Engine/lib/assimp/include/assimp/config.h | 1018 -- Engine/lib/assimp/include/assimp/config.h.in | 123 +- Engine/lib/assimp/include/assimp/defs.h | 256 +- Engine/lib/assimp/include/assimp/fast_atof.h | 40 +- .../lib/assimp/include/assimp/importerdesc.h | 38 +- .../lib/assimp/include/assimp/irrXMLWrapper.h | 149 - Engine/lib/assimp/include/assimp/light.h | 23 +- Engine/lib/assimp/include/assimp/material.h | 1079 +- Engine/lib/assimp/include/assimp/material.inl | 310 +- Engine/lib/assimp/include/assimp/matrix3x3.h | 29 +- .../lib/assimp/include/assimp/matrix3x3.inl | 76 +- Engine/lib/assimp/include/assimp/matrix4x4.h | 24 +- .../lib/assimp/include/assimp/matrix4x4.inl | 172 +- Engine/lib/assimp/include/assimp/mesh.h | 450 +- Engine/lib/assimp/include/assimp/metadata.h | 441 +- .../lib/assimp/include/assimp/pbrmaterial.h | 66 +- .../port/AndroidJNI/AndroidJNIIOSystem.h | 26 +- .../port/AndroidJNI/BundledAssetIOSystem.h | 93 + .../lib/assimp/include/assimp/postprocess.h | 38 +- Engine/lib/assimp/include/assimp/qnan.h | 33 +- Engine/lib/assimp/include/assimp/quaternion.h | 18 +- .../lib/assimp/include/assimp/quaternion.inl | 30 +- Engine/lib/assimp/include/assimp/revision.h | 28 - Engine/lib/assimp/include/assimp/scene.h | 96 +- Engine/lib/assimp/include/assimp/texture.h | 37 +- Engine/lib/assimp/include/assimp/types.h | 295 +- Engine/lib/assimp/include/assimp/vector2.h | 10 +- Engine/lib/assimp/include/assimp/vector2.inl | 22 +- Engine/lib/assimp/include/assimp/vector3.h | 49 +- Engine/lib/assimp/include/assimp/vector3.inl | 101 +- Engine/lib/assimp/include/assimp/version.h | 19 +- 1150 files changed, 165834 insertions(+), 112019 deletions(-) create mode 100644 Engine/lib/assimp/CHANGES create mode 100644 Engine/lib/assimp/CREDITS create mode 100644 Engine/lib/assimp/LICENSE create mode 100644 Engine/lib/assimp/Readme.md delete mode 100644 Engine/lib/assimp/code/3DS/3DSHelper.h delete mode 100644 Engine/lib/assimp/code/3MF/3MFXmlTags.h delete mode 100644 Engine/lib/assimp/code/3MF/D3MFImporter.cpp delete mode 100644 Engine/lib/assimp/code/3MF/D3MFOpcPackage.cpp delete mode 100644 Engine/lib/assimp/code/AMF/AMFImporter.cpp delete mode 100644 Engine/lib/assimp/code/AMF/AMFImporter.hpp delete mode 100644 Engine/lib/assimp/code/AMF/AMFImporter_Geometry.cpp delete mode 100644 Engine/lib/assimp/code/AMF/AMFImporter_Macro.hpp delete mode 100644 Engine/lib/assimp/code/AMF/AMFImporter_Node.hpp delete mode 100644 Engine/lib/assimp/code/AMF/AMFImporter_Postprocess.cpp delete mode 100644 Engine/lib/assimp/code/Assbin/AssbinExporter.cpp rename Engine/lib/assimp/code/{ => AssetLib}/3DS/3DSConverter.cpp (58%) rename Engine/lib/assimp/code/{ => AssetLib}/3DS/3DSExporter.cpp (65%) rename Engine/lib/assimp/code/{ => AssetLib}/3DS/3DSExporter.h (96%) create mode 100644 Engine/lib/assimp/code/AssetLib/3DS/3DSHelper.h rename Engine/lib/assimp/code/{ => AssetLib}/3DS/3DSLoader.cpp (67%) rename Engine/lib/assimp/code/{ => AssetLib}/3DS/3DSLoader.h (92%) create mode 100644 Engine/lib/assimp/code/AssetLib/3MF/3MFTypes.h create mode 100644 Engine/lib/assimp/code/AssetLib/3MF/3MFXmlTags.h rename Engine/lib/assimp/code/{ => AssetLib}/3MF/D3MFExporter.cpp (50%) rename Engine/lib/assimp/code/{ => AssetLib}/3MF/D3MFExporter.h (89%) create mode 100644 Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.h create mode 100644 Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.cpp rename Engine/lib/assimp/code/{ => AssetLib}/3MF/D3MFOpcPackage.h (83%) create mode 100644 Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.h rename Engine/lib/assimp/code/{ => AssetLib}/AC/ACLoader.cpp (52%) rename Engine/lib/assimp/code/{ => AssetLib}/AC/ACLoader.h (73%) create mode 100644 Engine/lib/assimp/code/AssetLib/AMF/AMFImporter.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/AMF/AMFImporter.hpp create mode 100644 Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Geometry.cpp rename Engine/lib/assimp/code/{ => AssetLib}/AMF/AMFImporter_Material.cpp (50%) create mode 100644 Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Node.hpp create mode 100644 Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Postprocess.cpp rename Engine/lib/assimp/code/{ => AssetLib}/ASE/ASELoader.cpp (63%) rename Engine/lib/assimp/code/{ => AssetLib}/ASE/ASELoader.h (96%) rename Engine/lib/assimp/code/{ => AssetLib}/ASE/ASEParser.cpp (58%) rename Engine/lib/assimp/code/{ => AssetLib}/ASE/ASEParser.h (81%) create mode 100644 Engine/lib/assimp/code/AssetLib/Assbin/AssbinExporter.cpp rename Engine/lib/assimp/code/{ => AssetLib}/Assbin/AssbinExporter.h (95%) create mode 100644 Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.cpp rename Engine/lib/assimp/code/{3MF/D3MFImporter.h => AssetLib/Assbin/AssbinFileWriter.h} (74%) rename Engine/lib/assimp/code/{ => AssetLib}/Assbin/AssbinLoader.cpp (56%) rename Engine/lib/assimp/code/{ => AssetLib}/Assbin/AssbinLoader.h (90%) rename Engine/lib/assimp/code/{ => AssetLib}/Assjson/cencode.c (87%) rename Engine/lib/assimp/code/{ => AssetLib}/Assjson/cencode.h (91%) rename Engine/lib/assimp/code/{ => AssetLib}/Assjson/json_exporter.cpp (77%) rename Engine/lib/assimp/code/{ => AssetLib}/Assjson/mesh_splitter.cpp (96%) rename Engine/lib/assimp/code/{ => AssetLib}/Assjson/mesh_splitter.h (59%) create mode 100644 Engine/lib/assimp/code/AssetLib/Assxml/AssxmlExporter.cpp rename Engine/lib/assimp/code/{ => AssetLib}/Assxml/AssxmlExporter.h (97%) create mode 100644 Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.h create mode 100644 Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.cpp rename Engine/lib/assimp/code/{ => AssetLib}/B3D/B3DImporter.h (85%) create mode 100644 Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.cpp rename Engine/lib/assimp/code/{ => AssetLib}/BVH/BVHLoader.h (80%) rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderBMesh.cpp (54%) rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderBMesh.h (98%) create mode 100644 Engine/lib/assimp/code/AssetLib/Blender/BlenderCustomData.cpp rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderCustomData.h (100%) rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderDNA.cpp (69%) rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderDNA.h (74%) rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderDNA.inl (93%) rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderIntermediate.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderLoader.cpp (57%) create mode 100644 Engine/lib/assimp/code/AssetLib/Blender/BlenderLoader.h rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderModifier.cpp (56%) rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderModifier.h (93%) create mode 100644 Engine/lib/assimp/code/AssetLib/Blender/BlenderScene.cpp rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderScene.h (66%) rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderSceneGen.h (97%) rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderTessellator.cpp (98%) rename Engine/lib/assimp/code/{ => AssetLib}/Blender/BlenderTessellator.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/C4D/C4DImporter.cpp (92%) rename Engine/lib/assimp/code/{ => AssetLib}/C4D/C4DImporter.h (73%) rename Engine/lib/assimp/code/{ => AssetLib}/COB/COBLoader.cpp (51%) create mode 100644 Engine/lib/assimp/code/AssetLib/COB/COBLoader.h rename Engine/lib/assimp/code/{ => AssetLib}/COB/COBScene.h (98%) rename Engine/lib/assimp/code/{ => AssetLib}/CSM/CSMLoader.cpp (95%) rename Engine/lib/assimp/code/{ => AssetLib}/CSM/CSMLoader.h (85%) create mode 100644 Engine/lib/assimp/code/AssetLib/Collada/ColladaExporter.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/Collada/ColladaExporter.h create mode 100644 Engine/lib/assimp/code/AssetLib/Collada/ColladaHelper.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/Collada/ColladaHelper.h rename Engine/lib/assimp/code/{ => AssetLib}/Collada/ColladaLoader.cpp (69%) rename Engine/lib/assimp/code/{ => AssetLib}/Collada/ColladaLoader.h (57%) create mode 100644 Engine/lib/assimp/code/AssetLib/Collada/ColladaParser.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/Collada/ColladaParser.h rename Engine/lib/assimp/code/{ => AssetLib}/DXF/DXFHelper.h (97%) rename Engine/lib/assimp/code/{ => AssetLib}/DXF/DXFLoader.cpp (95%) rename Engine/lib/assimp/code/{ => AssetLib}/DXF/DXFLoader.h (93%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXAnimation.cpp (59%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXBinaryTokenizer.cpp (94%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXCommon.h (61%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXCompileConfig.h (85%) create mode 100644 Engine/lib/assimp/code/AssetLib/FBX/FBXConverter.cpp rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXConverter.h (82%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXDeformer.cpp (99%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXDocument.cpp (89%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXDocument.h (95%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXDocumentUtil.cpp (91%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXDocumentUtil.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXExportNode.cpp (88%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXExportNode.h (98%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXExportProperty.cpp (99%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXExportProperty.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXExporter.cpp (88%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXExporter.h (93%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXImportSettings.h (88%) create mode 100644 Engine/lib/assimp/code/AssetLib/FBX/FBXImporter.cpp rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXImporter.h (77%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXMaterial.cpp (83%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXMeshGeometry.cpp (90%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXMeshGeometry.h (96%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXModel.cpp (64%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXNodeAttribute.cpp (99%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXParser.cpp (92%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXParser.h (96%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXProperties.cpp (78%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXProperties.h (98%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXTokenizer.cpp (95%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXTokenizer.h (98%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXUtil.cpp (88%) rename Engine/lib/assimp/code/{ => AssetLib}/FBX/FBXUtil.h (78%) rename Engine/lib/assimp/code/{ => AssetLib}/HMP/HMPFileData.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/HMP/HMPLoader.cpp (53%) rename Engine/lib/assimp/code/{ => AssetLib}/HMP/HMPLoader.h (83%) rename Engine/lib/assimp/code/{ => AssetLib}/HMP/HalfLifeFileData.h (99%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCBoolean.cpp (72%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCCurve.cpp (96%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCGeometry.cpp (88%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCLoader.cpp (56%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCLoader.h (74%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCMaterial.cpp (95%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCOpenings.cpp (82%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCProfile.cpp (96%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCReaderGen1_2x3.cpp (91%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCReaderGen2_2x3.cpp (98%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCReaderGen_2x3.h (99%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCReaderGen_4.cpp (98%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCReaderGen_4.h (99%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCUtil.cpp (96%) rename Engine/lib/assimp/code/{Importer => AssetLib}/IFC/IFCUtil.h (96%) create mode 100644 Engine/lib/assimp/code/AssetLib/IQM/IQMImporter.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/IQM/IQMImporter.h create mode 100644 Engine/lib/assimp/code/AssetLib/IQM/iqm.h create mode 100644 Engine/lib/assimp/code/AssetLib/Irr/IRRLoader.cpp rename Engine/lib/assimp/code/{ => AssetLib}/Irr/IRRLoader.h (90%) create mode 100644 Engine/lib/assimp/code/AssetLib/Irr/IRRMeshLoader.cpp rename Engine/lib/assimp/code/{ => AssetLib}/Irr/IRRMeshLoader.h (89%) create mode 100644 Engine/lib/assimp/code/AssetLib/Irr/IRRShared.cpp rename Engine/lib/assimp/code/{ => AssetLib}/Irr/IRRShared.h (51%) rename Engine/lib/assimp/code/{ => AssetLib}/LWO/LWOAnimation.cpp (55%) rename Engine/lib/assimp/code/{ => AssetLib}/LWO/LWOAnimation.h (98%) rename Engine/lib/assimp/code/{ => AssetLib}/LWO/LWOBLoader.cpp (99%) create mode 100644 Engine/lib/assimp/code/AssetLib/LWO/LWOFileData.h create mode 100644 Engine/lib/assimp/code/AssetLib/LWO/LWOLoader.cpp rename Engine/lib/assimp/code/{ => AssetLib}/LWO/LWOLoader.h (72%) create mode 100644 Engine/lib/assimp/code/AssetLib/LWO/LWOMaterial.cpp rename Engine/lib/assimp/code/{ => AssetLib}/LWS/LWSLoader.cpp (63%) rename Engine/lib/assimp/code/{ => AssetLib}/LWS/LWSLoader.h (72%) create mode 100644 Engine/lib/assimp/code/AssetLib/M3D/M3DExporter.cpp rename Engine/lib/assimp/code/{glTF/glTFExporter.h => AssetLib/M3D/M3DExporter.h} (54%) create mode 100644 Engine/lib/assimp/code/AssetLib/M3D/M3DImporter.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/M3D/M3DImporter.h create mode 100644 Engine/lib/assimp/code/AssetLib/M3D/M3DMaterials.h create mode 100644 Engine/lib/assimp/code/AssetLib/M3D/M3DWrapper.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/M3D/M3DWrapper.h create mode 100644 Engine/lib/assimp/code/AssetLib/M3D/m3d.h rename Engine/lib/assimp/code/{ => AssetLib}/MD2/MD2FileData.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/MD2/MD2Loader.cpp (89%) rename Engine/lib/assimp/code/{ => AssetLib}/MD2/MD2Loader.h (86%) rename Engine/lib/assimp/code/{ => AssetLib}/MD2/MD2NormalTable.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/MD3/MD3FileData.h (98%) rename Engine/lib/assimp/code/{ => AssetLib}/MD3/MD3Loader.cpp (63%) rename Engine/lib/assimp/code/{ => AssetLib}/MD3/MD3Loader.h (81%) rename Engine/lib/assimp/code/{ => AssetLib}/MD4/MD4FileData.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/MD5/MD5Loader.cpp (60%) rename Engine/lib/assimp/code/{ => AssetLib}/MD5/MD5Loader.h (81%) rename Engine/lib/assimp/code/{ => AssetLib}/MD5/MD5Parser.cpp (53%) rename Engine/lib/assimp/code/{ => AssetLib}/MD5/MD5Parser.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/MDC/MDCFileData.h (98%) rename Engine/lib/assimp/code/{ => AssetLib}/MDC/MDCLoader.cpp (52%) rename Engine/lib/assimp/code/{ => AssetLib}/MDC/MDCLoader.h (86%) rename Engine/lib/assimp/code/{ => AssetLib}/MDC/MDCNormalTable.h (99%) create mode 100644 Engine/lib/assimp/code/AssetLib/MDL/HalfLife/HL1FileData.h create mode 100644 Engine/lib/assimp/code/AssetLib/MDL/HalfLife/HL1ImportDefinitions.h create mode 100644 Engine/lib/assimp/code/AssetLib/MDL/HalfLife/HL1ImportSettings.h create mode 100644 Engine/lib/assimp/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/MDL/HalfLife/HL1MDLLoader.h create mode 100644 Engine/lib/assimp/code/AssetLib/MDL/HalfLife/HL1MeshTrivert.h rename Engine/lib/assimp/code/{Importer/StepFile/StepFileImporter.h => AssetLib/MDL/HalfLife/HalfLifeMDLBaseHeader.h} (74%) create mode 100644 Engine/lib/assimp/code/AssetLib/MDL/HalfLife/LogFunctions.h create mode 100644 Engine/lib/assimp/code/AssetLib/MDL/HalfLife/UniqueNameGenerator.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/MDL/HalfLife/UniqueNameGenerator.h rename Engine/lib/assimp/code/{ => AssetLib}/MDL/MDLDefaultColorMap.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/MDL/MDLFileData.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/MDL/MDLLoader.cpp (56%) rename Engine/lib/assimp/code/{ => AssetLib}/MDL/MDLLoader.h (95%) rename Engine/lib/assimp/code/{ => AssetLib}/MDL/MDLMaterialLoader.cpp (59%) rename Engine/lib/assimp/code/{ => AssetLib}/MMD/MMDCpp14.h (98%) create mode 100644 Engine/lib/assimp/code/AssetLib/MMD/MMDImporter.cpp rename Engine/lib/assimp/code/{ => AssetLib}/MMD/MMDImporter.h (94%) rename Engine/lib/assimp/code/{ => AssetLib}/MMD/MMDPmdParser.h (98%) rename Engine/lib/assimp/code/{ => AssetLib}/MMD/MMDPmxParser.cpp (97%) rename Engine/lib/assimp/code/{ => AssetLib}/MMD/MMDPmxParser.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/MMD/MMDVmdParser.h (97%) rename Engine/lib/assimp/code/{ => AssetLib}/MS3D/MS3DLoader.cpp (90%) rename Engine/lib/assimp/code/{ => AssetLib}/MS3D/MS3DLoader.h (78%) rename Engine/lib/assimp/code/{ => AssetLib}/NDO/NDOLoader.cpp (94%) rename Engine/lib/assimp/code/{ => AssetLib}/NDO/NDOLoader.h (84%) rename Engine/lib/assimp/code/{ => AssetLib}/NFF/NFFLoader.cpp (54%) rename Engine/lib/assimp/code/{ => AssetLib}/NFF/NFFLoader.h (68%) rename Engine/lib/assimp/code/{ => AssetLib}/OFF/OFFLoader.cpp (94%) rename Engine/lib/assimp/code/{ => AssetLib}/OFF/OFFLoader.h (86%) rename Engine/lib/assimp/code/{ => AssetLib}/Ogre/OgreBinarySerializer.cpp (66%) create mode 100644 Engine/lib/assimp/code/AssetLib/Ogre/OgreBinarySerializer.h rename Engine/lib/assimp/code/{ => AssetLib}/Ogre/OgreImporter.cpp (68%) rename Engine/lib/assimp/code/{ => AssetLib}/Ogre/OgreImporter.h (87%) rename Engine/lib/assimp/code/{ => AssetLib}/Ogre/OgreMaterial.cpp (60%) rename Engine/lib/assimp/code/{ => AssetLib}/Ogre/OgreParsingUtils.h (57%) rename Engine/lib/assimp/code/{ => AssetLib}/Ogre/OgreStructs.cpp (57%) rename Engine/lib/assimp/code/{ => AssetLib}/Ogre/OgreStructs.h (99%) create mode 100644 Engine/lib/assimp/code/AssetLib/Ogre/OgreXmlSerializer.cpp rename Engine/lib/assimp/code/{ => AssetLib}/Ogre/OgreXmlSerializer.h (54%) rename Engine/lib/assimp/code/{ => AssetLib}/OpenGEX/OpenGEXExporter.cpp (98%) rename Engine/lib/assimp/code/{ => AssetLib}/OpenGEX/OpenGEXExporter.h (97%) create mode 100644 Engine/lib/assimp/code/AssetLib/OpenGEX/OpenGEXImporter.cpp rename Engine/lib/assimp/code/{ => AssetLib}/OpenGEX/OpenGEXImporter.h (91%) rename Engine/lib/assimp/code/{ => AssetLib}/OpenGEX/OpenGEXStructs.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/Ply/PlyExporter.cpp (98%) rename Engine/lib/assimp/code/{ => AssetLib}/Ply/PlyExporter.h (98%) rename Engine/lib/assimp/code/{ => AssetLib}/Ply/PlyLoader.cpp (57%) rename Engine/lib/assimp/code/{ => AssetLib}/Ply/PlyLoader.h (77%) create mode 100644 Engine/lib/assimp/code/AssetLib/Ply/PlyParser.cpp rename Engine/lib/assimp/code/{ => AssetLib}/Ply/PlyParser.h (99%) rename Engine/lib/assimp/code/{ => AssetLib}/Q3BSP/Q3BSPFileData.h (98%) create mode 100644 Engine/lib/assimp/code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp rename Engine/lib/assimp/code/{ => AssetLib}/Q3BSP/Q3BSPFileImporter.h (91%) rename Engine/lib/assimp/code/{ => AssetLib}/Q3BSP/Q3BSPFileParser.cpp (99%) rename Engine/lib/assimp/code/{ => AssetLib}/Q3BSP/Q3BSPFileParser.h (95%) create mode 100644 Engine/lib/assimp/code/AssetLib/Q3D/Q3DLoader.cpp rename Engine/lib/assimp/code/{ => AssetLib}/Q3D/Q3DLoader.h (84%) rename Engine/lib/assimp/code/{ => AssetLib}/Raw/RawLoader.cpp (56%) rename Engine/lib/assimp/code/{ => AssetLib}/Raw/RawLoader.h (87%) rename Engine/lib/assimp/code/{ => AssetLib}/SIB/SIBImporter.cpp (70%) rename Engine/lib/assimp/code/{ => AssetLib}/SIB/SIBImporter.h (86%) rename Engine/lib/assimp/code/{ => AssetLib}/SMD/SMDLoader.cpp (97%) rename Engine/lib/assimp/code/{ => AssetLib}/SMD/SMDLoader.h (94%) rename Engine/lib/assimp/code/{Importer => AssetLib}/STEPParser/STEPFileEncoding.cpp (99%) rename Engine/lib/assimp/code/{Importer => AssetLib}/STEPParser/STEPFileEncoding.h (98%) rename Engine/lib/assimp/code/{Importer => AssetLib}/STEPParser/STEPFileReader.cpp (94%) rename Engine/lib/assimp/code/{Importer => AssetLib}/STEPParser/STEPFileReader.h (97%) rename Engine/lib/assimp/code/{ => AssetLib}/STL/STLExporter.cpp (97%) rename Engine/lib/assimp/code/{ => AssetLib}/STL/STLExporter.h (86%) rename Engine/lib/assimp/code/{ => AssetLib}/STL/STLLoader.cpp (60%) rename Engine/lib/assimp/code/{ => AssetLib}/STL/STLLoader.h (92%) create mode 100644 Engine/lib/assimp/code/AssetLib/Step/STEPFile.h rename Engine/lib/assimp/code/{ => AssetLib}/Step/StepExporter.cpp (76%) rename Engine/lib/assimp/code/{ => AssetLib}/Step/StepExporter.h (98%) rename Engine/lib/assimp/code/{ => AssetLib}/Terragen/TerragenLoader.cpp (58%) rename Engine/lib/assimp/code/{ => AssetLib}/Terragen/TerragenLoader.h (75%) rename Engine/lib/assimp/code/{ => AssetLib}/Unreal/UnrealLoader.cpp (53%) rename Engine/lib/assimp/code/{ => AssetLib}/Unreal/UnrealLoader.h (52%) rename Engine/lib/assimp/code/{ => AssetLib}/X/XFileExporter.cpp (99%) rename Engine/lib/assimp/code/{ => AssetLib}/X/XFileExporter.h (96%) rename Engine/lib/assimp/code/{ => AssetLib}/X/XFileHelper.h (72%) rename Engine/lib/assimp/code/{ => AssetLib}/X/XFileImporter.cpp (93%) rename Engine/lib/assimp/code/{ => AssetLib}/X/XFileImporter.h (95%) rename Engine/lib/assimp/code/{ => AssetLib}/X/XFileParser.cpp (50%) rename Engine/lib/assimp/code/{ => AssetLib}/X/XFileParser.h (96%) create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DExporter.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DExporter.hpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DGeoHelper.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DGeoHelper.h create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter.hpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter_Geometry2D.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter_Geometry3D.cpp rename Engine/lib/assimp/code/{ => AssetLib}/X3D/X3DImporter_Group.cpp (50%) create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter_Light.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter_Macro.hpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter_Metadata.cpp rename Engine/lib/assimp/code/{ => AssetLib}/X3D/X3DImporter_Networking.cpp (52%) create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter_Node.hpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter_Postprocess.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter_Rendering.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter_Shape.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DImporter_Texturing.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DXmlHelper.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/X3D/X3DXmlHelper.h create mode 100644 Engine/lib/assimp/code/AssetLib/XGL/XGLLoader.cpp rename Engine/lib/assimp/code/{ => AssetLib}/XGL/XGLLoader.h (63%) create mode 100644 Engine/lib/assimp/code/AssetLib/glTF/glTFAsset.h create mode 100644 Engine/lib/assimp/code/AssetLib/glTF/glTFAsset.inl rename Engine/lib/assimp/code/{ => AssetLib}/glTF/glTFAssetWriter.h (95%) rename Engine/lib/assimp/code/{ => AssetLib}/glTF/glTFAssetWriter.inl (92%) rename Engine/lib/assimp/code/{ => AssetLib}/glTF/glTFCommon.cpp (53%) create mode 100644 Engine/lib/assimp/code/AssetLib/glTF/glTFCommon.h rename Engine/lib/assimp/code/{ => AssetLib}/glTF/glTFExporter.cpp (89%) create mode 100644 Engine/lib/assimp/code/AssetLib/glTF/glTFExporter.h rename Engine/lib/assimp/code/{ => AssetLib}/glTF/glTFImporter.cpp (55%) rename Engine/lib/assimp/code/{ => AssetLib}/glTF/glTFImporter.h (74%) create mode 100644 Engine/lib/assimp/code/AssetLib/glTF2/glTF2Asset.h create mode 100644 Engine/lib/assimp/code/AssetLib/glTF2/glTF2Asset.inl rename Engine/lib/assimp/code/{ => AssetLib}/glTF2/glTF2AssetWriter.h (90%) rename Engine/lib/assimp/code/{ => AssetLib}/glTF2/glTF2AssetWriter.inl (68%) create mode 100644 Engine/lib/assimp/code/AssetLib/glTF2/glTF2Exporter.cpp create mode 100644 Engine/lib/assimp/code/AssetLib/glTF2/glTF2Exporter.h create mode 100644 Engine/lib/assimp/code/AssetLib/glTF2/glTF2Importer.cpp rename Engine/lib/assimp/code/{ => AssetLib}/glTF2/glTF2Importer.h (67%) delete mode 100644 Engine/lib/assimp/code/Assxml/AssxmlExporter.cpp delete mode 100644 Engine/lib/assimp/code/B3D/B3DImporter.cpp delete mode 100644 Engine/lib/assimp/code/BVH/BVHLoader.cpp delete mode 100644 Engine/lib/assimp/code/Blender/BlenderCustomData.cpp delete mode 100644 Engine/lib/assimp/code/Blender/BlenderLoader.h delete mode 100644 Engine/lib/assimp/code/Blender/BlenderScene.cpp delete mode 100644 Engine/lib/assimp/code/COB/COBLoader.h delete mode 100644 Engine/lib/assimp/code/Collada/ColladaExporter.cpp delete mode 100644 Engine/lib/assimp/code/Collada/ColladaExporter.h delete mode 100644 Engine/lib/assimp/code/Collada/ColladaHelper.h delete mode 100644 Engine/lib/assimp/code/Collada/ColladaParser.cpp delete mode 100644 Engine/lib/assimp/code/Collada/ColladaParser.h create mode 100644 Engine/lib/assimp/code/Common/AssertHandler.cpp create mode 100644 Engine/lib/assimp/code/Common/AssertHandler.h create mode 100644 Engine/lib/assimp/code/Common/Base64.cpp create mode 100644 Engine/lib/assimp/code/Common/Compression.cpp create mode 100644 Engine/lib/assimp/code/Common/Compression.h rename Engine/lib/assimp/{include/assimp/Macros.h => code/Common/Exceptional.cpp} (86%) create mode 100644 Engine/lib/assimp/code/Common/IOSystem.cpp create mode 100644 Engine/lib/assimp/code/Common/material.cpp delete mode 100644 Engine/lib/assimp/code/FBX/FBXConverter.cpp delete mode 100644 Engine/lib/assimp/code/FBX/FBXImporter.cpp delete mode 100644 Engine/lib/assimp/code/Importer/StepFile/StepFileGen1.cpp delete mode 100644 Engine/lib/assimp/code/Importer/StepFile/StepFileGen2.cpp delete mode 100644 Engine/lib/assimp/code/Importer/StepFile/StepFileGen3.cpp delete mode 100644 Engine/lib/assimp/code/Importer/StepFile/StepFileImporter.cpp delete mode 100644 Engine/lib/assimp/code/Importer/StepFile/StepReaderGen.h delete mode 100644 Engine/lib/assimp/code/Irr/IRRLoader.cpp delete mode 100644 Engine/lib/assimp/code/Irr/IRRMeshLoader.cpp delete mode 100644 Engine/lib/assimp/code/Irr/IRRShared.cpp delete mode 100644 Engine/lib/assimp/code/LWO/LWOFileData.h delete mode 100644 Engine/lib/assimp/code/LWO/LWOLoader.cpp delete mode 100644 Engine/lib/assimp/code/LWO/LWOMaterial.cpp delete mode 100644 Engine/lib/assimp/code/MMD/MMDImporter.cpp delete mode 100644 Engine/lib/assimp/code/Obj/ObjExporter.cpp delete mode 100644 Engine/lib/assimp/code/Obj/ObjExporter.h delete mode 100644 Engine/lib/assimp/code/Obj/ObjFileData.h delete mode 100644 Engine/lib/assimp/code/Obj/ObjFileImporter.cpp delete mode 100644 Engine/lib/assimp/code/Obj/ObjFileImporter.h delete mode 100644 Engine/lib/assimp/code/Obj/ObjFileMtlImporter.cpp delete mode 100644 Engine/lib/assimp/code/Obj/ObjFileMtlImporter.h delete mode 100644 Engine/lib/assimp/code/Obj/ObjFileParser.cpp delete mode 100644 Engine/lib/assimp/code/Obj/ObjFileParser.h delete mode 100644 Engine/lib/assimp/code/Obj/ObjTools.h delete mode 100644 Engine/lib/assimp/code/Ogre/OgreBinarySerializer.h delete mode 100644 Engine/lib/assimp/code/Ogre/OgreXmlSerializer.cpp delete mode 100644 Engine/lib/assimp/code/OpenGEX/OpenGEXImporter.cpp create mode 100644 Engine/lib/assimp/code/Pbrt/PbrtExporter.cpp create mode 100644 Engine/lib/assimp/code/Pbrt/PbrtExporter.h delete mode 100644 Engine/lib/assimp/code/Ply/PlyParser.cpp create mode 100644 Engine/lib/assimp/code/PostProcessing/ArmaturePopulate.cpp create mode 100644 Engine/lib/assimp/code/PostProcessing/ArmaturePopulate.h rename Engine/lib/assimp/code/{Common => PostProcessing}/SplitByBoneCountProcess.cpp (79%) rename Engine/lib/assimp/code/{Common => PostProcessing}/SplitByBoneCountProcess.h (98%) delete mode 100644 Engine/lib/assimp/code/Q3BSP/Q3BSPFileImporter.cpp delete mode 100644 Engine/lib/assimp/code/Q3D/Q3DLoader.cpp delete mode 100644 Engine/lib/assimp/code/Step/STEPFile.h delete mode 100644 Engine/lib/assimp/code/X3D/FIReader.cpp delete mode 100644 Engine/lib/assimp/code/X3D/FIReader.hpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DExporter.cpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DExporter.hpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter.cpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter.hpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter_Geometry2D.cpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter_Geometry3D.cpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter_Light.cpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter_Macro.hpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter_Metadata.cpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter_Node.hpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter_Postprocess.cpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter_Rendering.cpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter_Shape.cpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DImporter_Texturing.cpp delete mode 100644 Engine/lib/assimp/code/X3D/X3DVocabulary.cpp delete mode 100644 Engine/lib/assimp/code/XGL/XGLLoader.cpp delete mode 100644 Engine/lib/assimp/code/glTF/glTFAsset.h delete mode 100644 Engine/lib/assimp/code/glTF/glTFAsset.inl delete mode 100644 Engine/lib/assimp/code/glTF/glTFCommon.h delete mode 100644 Engine/lib/assimp/code/glTF2/glTF2Asset.h delete mode 100644 Engine/lib/assimp/code/glTF2/glTF2Asset.inl delete mode 100644 Engine/lib/assimp/code/glTF2/glTF2Exporter.cpp delete mode 100644 Engine/lib/assimp/code/glTF2/glTF2Exporter.h delete mode 100644 Engine/lib/assimp/code/glTF2/glTF2Importer.cpp delete mode 100644 Engine/lib/assimp/contrib/CMakeLists.txt create mode 100644 Engine/lib/assimp/contrib/draco/.clang-format create mode 100644 Engine/lib/assimp/contrib/draco/.cmake-format.py create mode 100644 Engine/lib/assimp/contrib/draco/AUTHORS create mode 100644 Engine/lib/assimp/contrib/draco/BUILDING.md create mode 100644 Engine/lib/assimp/contrib/draco/CMAKE.md create mode 100644 Engine/lib/assimp/contrib/draco/CMakeLists.txt create mode 100644 Engine/lib/assimp/contrib/draco/CONTRIBUTING.md create mode 100644 Engine/lib/assimp/contrib/draco/LICENSE create mode 100644 Engine/lib/assimp/contrib/draco/README.md create mode 100644 Engine/lib/assimp/contrib/draco/cmake/DracoConfig.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/FindDraco.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/compiler_flags.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/compiler_tests.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco-config.cmake.template create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco.pc.template create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_build_definitions.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_cpu_detection.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_emscripten.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_flags.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_helpers.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_install.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_intrinsics.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_options.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_sanitizer.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_targets.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_test_config.h.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_tests.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/draco_variables.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/sanitizers.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/aarch64-linux-gnu.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/android-ndk-common.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/android.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/arm-ios-common.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/arm-linux-gnueabihf.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/arm64-android-ndk-libcpp.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/arm64-ios.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/arm64-linux-gcc.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/armv7-android-ndk-libcpp.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/armv7-ios.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/armv7-linux-gcc.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/armv7s-ios.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/i386-ios.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/x86-android-ndk-libcpp.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/x86_64-android-ndk-libcpp.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/toolchains/x86_64-ios.cmake create mode 100644 Engine/lib/assimp/contrib/draco/cmake/util.cmake create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/animation/keyframe_animation.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/animation/keyframe_animation.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/animation/keyframe_animation_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/animation/keyframe_animation_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/animation/keyframe_animation_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/animation/keyframe_animation_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/animation/keyframe_animation_encoding_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/animation/keyframe_animation_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/attribute_octahedron_transform.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/attribute_octahedron_transform.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/attribute_quantization_transform.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/attribute_quantization_transform.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/attribute_transform.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/attribute_transform.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/attribute_transform_data.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/attribute_transform_type.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/geometry_attribute.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/geometry_attribute.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/geometry_indices.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/point_attribute.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/point_attribute.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/attributes/point_attribute_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/attributes_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/attributes_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/attributes_decoder_interface.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/attributes_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/attributes_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/kd_tree_attributes_shared.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/linear_sequencer.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/normal_compression_utils.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/point_d_vector.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/point_d_vector_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/points_sequencer.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_attribute_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_attribute_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_attribute_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_attribute_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_integer_attribute_encoding_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/direct_bit_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/direct_bit_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/direct_bit_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/direct_bit_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/folded_integer_bit_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/folded_integer_bit_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/rans_bit_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/rans_bit_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/rans_bit_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/rans_bit_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/rans_coding_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/symbol_bit_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/symbol_bit_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/symbol_bit_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/bit_coders/symbol_bit_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/config/compression_shared.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/config/decoder_options.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/config/decoder_options_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/config/draco_options.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/config/encoder_options.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/config/encoding_features.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/decode.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/decode.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/decode_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/encode.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/encode.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/encode_base.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/encode_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/ans.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/rans_symbol_coding.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/rans_symbol_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/rans_symbol_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/shannon_entropy.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/shannon_entropy.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/shannon_entropy_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/symbol_coding_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/symbol_decoding.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/symbol_decoding.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/symbol_encoding.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/entropy/symbol_encoding.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/expert_encode.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/expert_encode.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_encoding_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_shared.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_encoder_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_sequential_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_sequential_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_sequential_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/mesh_sequential_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/traverser/depth_first_traverser.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/traverser/max_prediction_degree_traverser.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/mesh/traverser/traverser_base.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/point_cloud_types.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/quantize_points_3.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/algorithms/queuing_policy.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_encoding_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_sequential_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_sequential_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_sequential_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_sequential_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/compression/point_cloud/point_cloud_sequential_encoding_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/bit_utils.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/bit_utils.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/bounding_box.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/bounding_box.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/buffer_bit_coding_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/cycle_timer.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/cycle_timer.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/data_buffer.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/data_buffer.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/decoder_buffer.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/decoder_buffer.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/divide.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/divide.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/draco_index_type.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/draco_index_type_vector.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/draco_test_base.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/draco_test_utils.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/draco_test_utils.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/draco_types.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/draco_types.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/draco_version.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/encoder_buffer.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/encoder_buffer.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/hash_utils.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/hash_utils.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/macros.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/math_utils.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/math_utils_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/options.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/options.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/quantization_utils.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/quantization_utils.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/quantization_utils_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/status.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/status_or.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/status_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/varint_decoding.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/varint_encoding.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/vector_d.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/core/vector_d_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_reader_factory.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_reader_factory.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_reader_factory_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_reader_interface.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_reader_test_common.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_utils.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_utils.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_utils_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_writer_factory.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_writer_factory.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_writer_factory_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_writer_interface.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_writer_utils.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/file_writer_utils.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/mesh_io.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/mesh_io.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/obj_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/obj_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/obj_decoder_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/obj_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/obj_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/obj_encoder_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/parser_utils.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/parser_utils.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/ply_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/ply_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/ply_decoder_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/ply_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/ply_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/ply_property_reader.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/ply_property_writer.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/ply_reader.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/ply_reader.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/ply_reader_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/point_cloud_io.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/point_cloud_io.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/point_cloud_io_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/stdio_file_reader.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/stdio_file_reader.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/stdio_file_reader_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/stdio_file_writer.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/stdio_file_writer.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/io/stdio_file_writer_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/animation_decoder_webidl_wrapper.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/animation_decoder_webidl_wrapper.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/animation_encoder_webidl_wrapper.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/animation_encoder_webidl_wrapper.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/decoder_functions.js create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/decoder_webidl_wrapper.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/decoder_webidl_wrapper.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/draco_animation_decoder_glue_wrapper.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/draco_animation_encoder_glue_wrapper.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/draco_animation_web_decoder.idl create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/draco_animation_web_encoder.idl create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/draco_decoder_glue_wrapper.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/draco_encoder_glue_wrapper.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/draco_web_decoder.idl create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/draco_web_encoder.idl create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/encoder_webidl_wrapper.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/encoder_webidl_wrapper.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/finalize.js create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/prepareCallbacks.js create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/javascript/emscripten/version.js create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/maya/draco_maya_plugin.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/maya/draco_maya_plugin.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/corner_table.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/corner_table.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/corner_table_iterators.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_are_equivalent.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_are_equivalent.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_are_equivalent_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_attribute_corner_table.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_attribute_corner_table.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_cleanup.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_cleanup.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_cleanup_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_misc_functions.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_misc_functions.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_stripifier.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/mesh_stripifier.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/triangle_soup_mesh_builder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/triangle_soup_mesh_builder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/triangle_soup_mesh_builder_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/mesh/valence_cache.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/metadata/geometry_metadata.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/metadata/geometry_metadata.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/metadata/metadata.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/metadata/metadata.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/metadata/metadata_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/metadata/metadata_decoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/metadata/metadata_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/metadata/metadata_encoder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/metadata/metadata_encoder_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/metadata/metadata_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/point_cloud/point_cloud.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/point_cloud/point_cloud.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/point_cloud/point_cloud_builder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/point_cloud/point_cloud_builder.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/point_cloud/point_cloud_builder_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/point_cloud/point_cloud_test.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/tools/draco_decoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/tools/draco_encoder.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/tools/fuzz/build.sh create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/tools/fuzz/draco_mesh_decoder_fuzzer.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/tools/fuzz/draco_mesh_decoder_without_dequantization_fuzzer.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/tools/fuzz/draco_pc_decoder_fuzzer.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/tools/fuzz/draco_pc_decoder_without_dequantization_fuzzer.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/unity/draco_unity_plugin.cc create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/unity/draco_unity_plugin.h create mode 100644 Engine/lib/assimp/contrib/draco/src/draco/unity/draco_unity_plugin_test.cc delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/CMakeDirectoryInformation.cmake delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/DependInfo.cmake delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/build.make delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/cmake_clean.cmake delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/cmake_clean_target.cmake delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/compiler_depend.make delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/compiler_depend.ts delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/depend.make delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/flags.make delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/irrXML.cpp.o delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/irrXML.cpp.o.d delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/link.txt delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/IrrXML.dir/progress.make delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeFiles/progress.marks delete mode 100644 Engine/lib/assimp/contrib/irrXML/CMakeLists.txt delete mode 100644 Engine/lib/assimp/contrib/irrXML/CXMLReaderImpl.h delete mode 100644 Engine/lib/assimp/contrib/irrXML/Makefile delete mode 100644 Engine/lib/assimp/contrib/irrXML/cmake_install.cmake delete mode 100644 Engine/lib/assimp/contrib/irrXML/heapsort.h delete mode 100644 Engine/lib/assimp/contrib/irrXML/irrArray.h delete mode 100644 Engine/lib/assimp/contrib/irrXML/irrString.h delete mode 100644 Engine/lib/assimp/contrib/irrXML/irrTypes.h delete mode 100644 Engine/lib/assimp/contrib/irrXML/irrXML.cpp delete mode 100644 Engine/lib/assimp/contrib/irrXML/irrXML.h delete mode 100644 Engine/lib/assimp/contrib/irrXML_note.txt create mode 100644 Engine/lib/assimp/contrib/openddlparser/include/openddlparser/TPoolAllocator.h create mode 100644 Engine/lib/assimp/contrib/pugixml/CMakeLists.txt create mode 100644 Engine/lib/assimp/contrib/pugixml/contrib/foreach.hpp create mode 100644 Engine/lib/assimp/contrib/pugixml/readme.txt create mode 100644 Engine/lib/assimp/contrib/pugixml/src/pugiconfig.hpp create mode 100644 Engine/lib/assimp/contrib/pugixml/src/pugixml.cpp create mode 100644 Engine/lib/assimp/contrib/pugixml/src/pugixml.hpp create mode 100644 Engine/lib/assimp/contrib/rapidjson/include/rapidjson/cursorstreamwrapper.h create mode 100644 Engine/lib/assimp/contrib/rapidjson/include/rapidjson/internal/clzll.h rename Engine/lib/assimp/contrib/{stb_image => stb}/stb_image.h (92%) create mode 100644 Engine/lib/assimp/contrib/unzip/crypt.c create mode 100644 Engine/lib/assimp/contrib/utf8cpp/source/utf8/cpp11.h create mode 100644 Engine/lib/assimp/include/assimp/Base64.hpp rename Engine/lib/assimp/include/assimp/{Defines.h => ColladaMetaData.h} (83%) create mode 100644 Engine/lib/assimp/include/assimp/GltfMaterial.h create mode 100644 Engine/lib/assimp/include/assimp/ObjMaterial.h create mode 100644 Engine/lib/assimp/include/assimp/SmallVector.h create mode 100644 Engine/lib/assimp/include/assimp/XmlParser.h create mode 100644 Engine/lib/assimp/include/assimp/commonMetaData.h delete mode 100644 Engine/lib/assimp/include/assimp/config.h delete mode 100644 Engine/lib/assimp/include/assimp/irrXMLWrapper.h create mode 100644 Engine/lib/assimp/include/assimp/port/AndroidJNI/BundledAssetIOSystem.h delete mode 100644 Engine/lib/assimp/include/assimp/revision.h diff --git a/Engine/lib/assimp/CHANGES b/Engine/lib/assimp/CHANGES new file mode 100644 index 000000000..c0c73b98c --- /dev/null +++ b/Engine/lib/assimp/CHANGES @@ -0,0 +1,607 @@ +---------------------------------------------------------------------- +CHANGELOG +---------------------------------------------------------------------- +4.1.0 (2017-12): +- FEATURES: + - Export 3MF ( experimental ) + - Import / Export glTF 2 + - Introduce new zib-lib to eb able to export zip-archives +- FIXES/HOUSEKEEPING: + - Added missing include to stdlib.h and remove load library call + - Fix install for builds with MSVC compiler and NMake. + - Update list of supported file formats. + - Add TriLib to the official list of supported ports. + - Re-enabling PACK_STRUCT for MDL files. + - Use std.::unique_ptr + - Update D3MFExporter.h + - Update MD3Loader.cpp, using index + - Fix all warnings on MSVC14 + - Copy assimp dll to unit folder on windows + - Update jvm port supported formats + - Add support for building Mac OS X Framework bundles + - Check for nullptr dereferencing before copying scene data + - Update ValidateDataStructure.h, typo + - Enable data structure validation in cases where it doesn't cause failures + - Remove some dead assignments + - fast_atof: Silence some uninitialized variable warnings + - Check for area test if the face is a triangle. + - Set mNumUVComponents to 0 when deleting texture coordinate sets + - Only scale the root node because this will rescale all children nodes as well. + - Issue 1514: Fix frame pointer arithmetic + - Prevent failing stringstream to crash the export process + - powf -> pow + - add Defines.h to include folder for install. + - Android: + - Fix android build + - Fix assimp for cross compile for android + - Use define for D_FILE_OFFSET_BITS only for not-android systems. + - FBX: + - Fix handling with embedded textures + - FBX 7500 Binary reading + - Remove dead assignment + - Fix export of deleted meshes; Add LazyDict::Remove method + - Log an error instead of letting the fbx-importer crash. ( issue 213 ) + - Replace bad pointer casting with memcpy + - Remove useless const qualifier from return value + - Add explicit instantiation of log_prefix so other FBX source files can see it + - add missing inversion of postrotation matrix for fbx. + - FIReader: Silence uninitialized variable warning + - Update version check in FBX reader to check for version >= 7500 + - Use actual min/max of anim keys when start/stop time is missing +- GLTF1: + - Fix output of glTF 1 version string + - Fix delete / delete[] mismatch in glTFAsset + - Don’t ignore rgba(1,1,1,1) color properties + - glTF2 primitives fixes + - Don’t ignore rgba(1,1,1,1) color properties + - Fix delete / delete[] mismatch in glTFAsset + - Remove KHR_binary_glTF code + - glTF nodes can only hold one mesh. this simply assigns to and check’s a Node’s Mesh + - version in glb header is stored as uint32_t +- GLTF2: + - node name conflict fix + - Fix transform matrices multiplication order + - Preserve node names when importing + - Add support for tangents in import + - Fix typo on gltf2 camera parameters + - Moved byteStride from accessor to bufferView + - Implemented reading binary glTF2 (glb) files + - Fix signed/unsigned warning + - Add postprocess step for scaling + - Fix shininess to roughness conversion + - Prefer “BLEND†over “MASK†as an alphaMode default + - Approximate specularity / glossiness in metallicRoughness materials + - Diffuse color and diffuse texture import and export improvements + - Addressed some mismatched news/deletes caused by the new glTF2 sources. + - Fix delete / delete[] mismatches in glTF2 importer + - use correct name of exporter to gltf2 + - Fix possible infinite loop when exporting to gltf2 + - Fix glTF2::Asset::FindUniqueID() when the input string is >= 256 chars + - Fix glTF2 alphaMode storage and reading + - Fix glTF 2.0 multi-primitive support + - Load gltf .bin files from correct directory + - Add support for importing both glTF and glTF2 files + - ampler improvements; Add new LazyDict method + - Changes to GLTF2 materials + - Remove Light, Technique references + - Start removing materials common, and adding pbrSpecularGlossiness + - Use !ObjectEmpty() vs. MemberCount() > 0 + - Working read, import, export, and write of gltf2 (pbr) material + - Check in gltf2 models to test directory + - Remove un-needed test models + - Start managing and importing gltf2 pbr materials + - Update glTF2 Asset to use indexes + - Duplicate gltfImporter as gltf2Importer; Include glTF2 importer in CMake List + - glTF2: Fix animation export + - use opacity for diffuse alpha + alphaMode +- STL: + - Restore import of multi mesh binary STLs +- Blender: + - Silence warning about uninitialized member +- MDLImporter: + - Don't take address of packed struct member +- assimp_cmd: + - Fix strict-aliasing warnings +- Open3DGC: + - Fix strict-aliasing warnings + - Add assertions to silence static analyzer warnings + - Remove redundant const qualifiers from return types + - Fix some uninitialized variable warnings + - Remove OPEN3DGC and compression references +- unzip: + - Remove dead assignment + - Bail on bad compression method + - Fix possibly uninitialized variables +- clipper: + - Add assertion to silence a static analyzer warning +- OpenDDLExport: + - Reduce scope of a variable + - Remove dead variable + - Remove dead assignment + - Fix another potential memory leak +- X3DImporter: + - Add assertions to silence static analyzer warnings + - Add missing unittest + - Workaround for buggy Android NDK (issue #1361) +- TerragenLoader: + - Remove unused variable +- SIBImporter: + - Add assertions to silence static analyzer warnings +- IFC: + - Remove dead code + - Add explicit instantiation of log_prefix so IFCMaterial.cpp can see it +- PLY: + - Remove dead assignment and reduce scope of a variable + - fix vertex attribute lookup. +- OpenGEX: + - Add assertion to silence a static analyzer warning + - Fix for TextureFile with number in file name + - Return early when element is TextureFile +- NFF: + - Add assertions to silence static analyzer warnings + - Split up some complicated assignments +- Raw: Fix misleading indentation warning + - Reduce scope of a variable +- LWO + - Reduce scope of a variable +- IRRLoader: + - Fix confusing boolean casting +- AssbinExporter: + - Add assertion to silence a static analyzer warning +- ASE: + - Add assertion to silence a static analyzer warning +- AMFImporter: + - Add assertion to silence a static analyzer warning + - Add a block +- OptimizeGraph: + - Fix possible null pointer dereference + - RemoveRedundantMaterials: + - Add assertion to silence a static analyzer warning +- ImproveCacheLocality: + - Add assertion to silence a static analyzer warning +- RemoveRedundantMaterials: + - Set pointer to nullptr after deleting it +- Travis: + - Disable unit tests in scan-build config + - Move slower builds earlier to improve parallelization + - Add static analysis to build + - Remove unused branch rule for travis. + - Add Clang UBSan build configuration + - Treat warnings as errors, without typos this time +- Unittests: + - Add VS-based source groups for the unittests. +- Collada: + - export tag + - Update ColladaExporter.cpp + - Silence uninitialized variable warning + - Add support for line strip primitives +- Obj Wavefront: + - check in exporting against out-of-bounds-access . + - Issue 1351: use correct name for obj-meshname export for groups. + - fix mem-lead: face will be not released in case of an error. + - Anatoscope obj exporter nomtl + - Raise exception when obj file contains invalid face indices + - Added alternative displacement texture token in OBJ MTL material. + - Obj: rename attribute from exporter. + - Fix OBJ discarding all material names if the material library is missing +- Step: + - use correct lookup for utf32 +- MD2: + - Fix MD2 frames containing garbage +- STL + - add missing const. + - Fix memory-alignment bug. + - Fix issue 104: deal with more solids in one STL file. +- CMake + - Fix issue 213: use correct include folder for assimp +- Doxygen + - Fix issue 1513: put irrXML onto exclucde list for doxygen run +- PyAssimp: + - Search for libassimp.so in LD_LIBRARY_PATH if available. + - Fix operator precedence issue in header check + - Split setup.py into multiple lines + - Detect if Anaconda and fixed 3d_viewer for Python 3 + - created a python3 version of the 3dviewer and fixed the / = float in py3 +- Blender: + - Fix invalid access to mesh array when the array is empty. + - Fix short overflow. + - Silence warning about inline function which is declared but not defined +- JAssimp + - Changed license header for IHMC contributions from Apache 2.0 to BSD + - Add Node metadata to the Jassmip Java API + - Added supported for custom IO Systems in Java. Implemented ClassLoader IO System + - Added a link to pure jvm assimp port +- Clang sanitizer: + - Undefined Behavior sanitizer + - Fixed a divide by zero error in IFCBoolean that was latent, but nevertheless a bug +- B3DImporter: + - Replace bad pointer casting with memcpy +- AppVeyor: + - Cleanup and Addition of VS 2017 and running Tests + - Fixed File Size reported as 0 in tests that use temporary files + - x86 isn't a valid VS platform. Win32 it is, then. + - Replaced the worker image name, which doesn't work as generator name, with a manually created generator name. + - Cleaned up appveyor setup, added VS 2017 to the build matrix and attempted to add running of tests. + - Treat warnings as errors on Appveyor + - Disable warning 4351 on MSVC 2013 +- OpenGEXImporter: + - Copy materials to scene + - Store RefInfo in unique_ptr so they get automatically cleaned up + - Fix IOStream leak + - Store ChildInfo in unique_ptr so they get automatically cleaned up + - improve logging to be able to detect error-prone situations. +- AMFImporter: + - Fix memory leak +- UnrealLoader: + - Fix IOStream leak +- Upgrade RapidJSON to get rid of a clang warning +- zlib: + - Update zlib contribution + - Removed unnecessary files from zlib contribution + - Replaced unsigned long for the crc table to z_crc_t, to match what is returned by get-crc_table +- MakeVerboseFormat: + - Fix delete / delete[] mismatches in MakeVerboseFormat +- MaterialSystem: + - Fix out-of-bounds read in MaterialSystem unit test +- SIB: + - Added support for SIB models from Silo 2.5 +- AssbinExporter: + - Fix strict aliasing violation + - Add Write specialization for aiColor3D +- DefaultLogger: + - Whitespace cleanup to fix GCC misleading indentation warning +- MDP: + - Fix encoding issues. + - PreTransformVertices: + - fix name lost in mesh and nodes when load with flag +- C4D: + - Fixes for C4D importer +- Unzip: + - Latest greatest. + +4.0.1 (2017-07-28) + - FIXES/HOUSEKEEPING: + - fix version test. + - Not compiling when using ASSIMP_DOUBLE_PRECISION + - Added support for python3 + - Check if cmake is installed with brew + - Low performance in OptimizeMeshesProcess::ProcessNode with huge numbers of meshes + - Elapsed seconds not shown correctly + - StreamReader: fix out-of-range exception + - PPdPmdParser: fix compilation for clang + + +4.0.0 (2017-07-18) + +FEATURES: + - Double precision support provided ( available via cmake option ) + - QT-Widget based assimp-viewer ( works for windows, linux, osx ) + - Open3DGC codec supported by glFT-importer + - glTF: Read and write transparency values + - Add Triangulate post-processing step to glTF exporters + - Update rapidjson to v1.0.2 + - Added method to append new metadata to structure + - Unittests: intoduce a prototype model differ + - X3D support + - AMF support + - Lugdunum3D support + - Obj-Importer: obj-homogeneous_coords support + - Obj-Importer: new streaming handling + - Added support for 64 bit version header introduced in FbxSdk2016 + - Travis: enable coverall support. + - PyAssimp: New version of the pyASSIMP 3D viewer, with much improved 3D controls + - Morph animation support for collada + - Added support for parameters Ni and Tf in OBJ/MTL file format + - aiScene: add method to add children + - Added new option to IFC importer to control tessellation angle + removed unused IFC option + - aiMetaData: introduce aiMetaData::Dealloc + - Samples: add a DX11 example + - travis ci: test on OXS ( XCode 6.3 ) as well + - travis ci: enable sudo support. + - openddlparser: integrate release v0.4.0 + - aiMetaData: Added support for metadata in assbin format + +FIXES/HOUSEKEEPING: + - Introduce usage of #pragma statement + - Put cmake-scripts into their own folder + - Fix install pathes ( issue 938 ) + - Fix object_compare in blender importer( issue 946 ) + - Fix OSX compilation error + - Fix unzip path when no other version was found ( issue 967 ) + - Set _FILE_OFFSET_BITS=64 for 32-bit linux ( issue 975 ) + - Fix constructor for radjson on OSX + - Use Assimp namespace to fix build for big-endian architectures + - Add -fPIC to C Flags for 64bit linux Shared Object builds + - MDLLoader: fix resource leak. + - MakeVerboseFormat: fix invalid delete statement + - IFC: fix possible use after free access bug + - ComputeUVMappingprocess: add missing initialization for scalar value + - Fix invalid release of mat + mesh + - IrrImporter: Fix release functions + - Split mesh before exporting gltf ( issue 995 ) + - 3MFImporter: add source group for visual studio + - IFC: Switch generated file to 2 files to fix issue related to and ( issue 1084 ) + - OBJParser: set material index when changing current material + - OBJ: check for null mesh before updating material index + - add vertex color export support ( issue 809 ) + - Fix memory leak in Collada importer ( issue 1169 ) + - add stp to the list of supported extensions for step-files ( issue 1183 ) + - fix clang build ( Issue-1169 ) + - fix for FreeBSD + - Import FindPkgMacros to main CMake Configuration + - Extended support for tessellation parameter to more IFC shapes + - defensice handling of utf-8 decode issues ( issue 1211 ) + - Fixed compiler error on clang 4.0 running on OSX + - use test extension for exported test files ( issue 1228 ) + - Set UVW index material properties for OBJ files + - Fixed no member named 'atop' in global namespace issue for Android NDK compilation + - Apply mechanism to decide use for IrrXML external or internal + - Fix static init ordering bug in OpenGEX importer + - GLTF exporter: ensure animation accessors have same count + - GLTF exporter: convert animation time from ticks to seconds + - Add support for reading texture coordinates from PLY meshes with properties named 'texture_u' and 'texture_v' + - Added TokensForSearch in BlenderLoader to allow CanRead return true for in-memory files. + - fix wrong delete ( issue 1266 ) + - OpenGEX: fix invalid handling with color4 token ( issue 1262 ) + - LWOLoader: fix link in loader description + - Fix error when custom CMAKE_C_FLAGS is specified + - Fast-atof: log overflow errors + - Obj-Importer: do not break when detecting an overflow ( issue 1244 ) + - Obj-Importer: fix parsing of multible line data definitions + - Fixed bug where IFC models with multiple IFCSite only loaded 1 site instead of the complete model + - PLYImporter: - optimize memory and speed on ply importer / change parser to use a file stream - manage texture path in ply + import - manage texture coords on faces in ply import - correction on point cloud faces generation + - Utf8: integrate new lib ( issue 1158 ) + - fixed CMAKE_MODULE_PATH overwriting previous values + - OpenGEX: Fixed bug in material color processing ( issue 1271 ) + - SceneCombiner: move header for scenecombiner to public folder. + - GLTF exporter: ensure buffer view byte offsets are correctly aligned + - X3D importer: Added EXPORT and IMPORT to the list of ignored XML tags + - X3D Exporter: fixed missing attributes + - X3D importer: Fixed import of normals for the single index / normal per vertex case + - X3D importer: Fixed handling of inlined files + - X3D importer: fixed whitespace handling (issue 1202) + - X3D importer: Fixed iterator on MSVC 2015 + - X3D importer: Fixed problems with auto, override and regex on older compilers + - X3D importer: Fixed missing header file + - X3D importer: Fixed path handling + - X3D importer: Implemented support for binary X3D files + - fix build without 3DS ( issue 1319 ) + - pyassimp: Fixed indices for IndexedTriangleFanSet, IndexedTriangleSet and IndexedTriangleStripSet + - Fixes parameters to pyassimp.load + - Obj-Importe: Fixed texture bug due simultaneously using 'usemtl' and 'usemap' attributes + - check if all exporters are disabled ( issue 1320 ) + - Remove std functions deprecated by C++11. + - X-Importer: make it deal with lines + - use correct path for compilers ( issue 1335 ) + - Collada: add workaround to deal with polygon with holes + - update python readme + - Use unique node names when loading Collada files + - Fixed many FBX bugs + +API COMPATIBILITY: + - Changed ABI-compatibility to v3.3.1, please rebuild your precompiled libraries ( see issue 1182 ) + - VS2010 outdated + +3.3.1 (2016-07-08) + +FIXES/HOUSEKEEPING: + - Setup of default precision for 17 exporters + - Fix xcode project files + - Fix BlenderTesselator: offsetof operator + - Invalid version in cmake file + - Update pstdint.h to latest greatest + + +3.3.0 (2016-07-05) + +FEATURES: + - C++11 support enabled + - New regression-test-UI + - Experimental glTF-importer support + - OpenGEX: add support for cameras and lights + - C4D: update to latest Melange-SDK + - Add a gitter channel + - Coverity check enabled + - Switch to <...> include brackets for public headers + - Enable export by pyAssimp + - CI: check windows build + - Add functionality to perform a singlepost-processing step + - many more, just check the history + +FIXES/HOUSEKEEPING: + - Fix of many resource leaks in unittests and main lib + - Fix iOS-buildfor X64 + - Choosing zlib manually for cmake + - many more, just check the history + + +3.2.1 (2016-010-10) + +FEATURES: + - Updated glTF exporter to meet 1.0 specification. + +FIXES/HOUSEKEEPING: + - Fixed glTF Validator errors for exported glTF format. + +ISSUES: + - Hard coded sampler setting for + - magFilter + - minFilter + - void* in ExportData for accessor max and min. + + +3.2.0 (2015-11-03) + +FEATURES: + - OpenDDL-Parser is part of contrib-source. + - Experimental OpenGEX-support + - CI-check for linux and windows + - Coverity check added + - New regression testsuite. + +FIXES/HOUSEKEEPING: + - Hundreds of bugfixes in all parts of the library + - Unified line endings + + +API COMPATIBILITY: + - Removed precompiled header to increase build speed for linux + + +3.1.1 (2014-06-15) + +FEATURES: + - Support for FBX 2013 and newer, binary and ASCII (this is partly + work from Google Summer of Code 2012) + - Support for OGRE binary mesh and skeleton format + - Updated BLEND support for newer Blender versions + - Support for arbitrary meta data, used to hold FBX and DAE metadata + - OBJ Export now produces smaller files + - Meshes can now have names, this is supported by the major importers + - Improved IFC geometry generation + - M3 support has been removed + +FIXES/HOUSEKEEPING: + - Hundreds of bugfixes in all parts of the library + - CMake is now the primary build system + +API COMPATIBILITY: + - 3.1.1 is not binary compatible to 3.0 due to aiNode::mMetaData + and aiMesh::mName + - Export interface has been cleaned up and unified + - Other than that no relevant changes + + +3.0 (2012-07-07) + +FEATURES: + - new export interface similar to the import API. + - Supported export formats: Collada, OBJ, PLY and STL + - added new import formats: XGL/ZGL, M3 (experimental) + - new postprocessing steps: Debone + - vastly improved IFC (Industry Foundation Classes) support + - introduced API to query importer meta information (such as supported + format versions, full name, maintainer info). + - reworked Ogre XML import + - C-API now supports per-import properties + +FIXES/HOUSEKEEPING: + + - hundreds of bugfixes in all parts of the library + - unified naming and cleanup of public headers + - improved CMake build system + - templatized math library + - reduce dependency on boost.thread, only remaining spot + is synchronization for the C logging API + +API COMPATIBILITY: + - renamed headers, export interface, C API properties and meta data + prevent compatibility with code written for 2.0, but in + most cases these can be easily resolved + - Note: 3.0 is not binary compatible with 2.0 + + +2.0 (2010-11-21) + +FEATURES: + - Add support for static Blender (*.blend) scenes + - Add support for Q3BSP scenes + - Add a windows-based OpenGL sample featuring texturing & basic materials + - Add an experimental progress feedback interface. + - Vastly improved performance (up to 500%, depending on mesh size and + spatial structure) in some expensive postprocessing steps + - AssimpView now uses a reworked layout which leaves more space + to the scene hierarchy window + + - Add C# bindings ('Assimp.NET') + - Keep BSD-licensed and otherwise free test files in separate + folders (./test/models and ./test/models-nonbsd). + +FIXES: + - Many Collada bugfixes, improve fault tolerance + - Fix possible crashes in the Obj loader + - Improve the Ogre XML loader + - OpenGL-sample now works with MinGW + - Fix Importer::FindLoader failing on uppercase file extensions + - Fix flawed path handling when locating external files + - Limit the maximum number of vertices, faces, face indices and + weights that Assimp is able to handle. This is to avoid + crashes due to overflowing counters. + + - Updated XCode project files + - Further CMAKE build improvements + + +API CHANGES: + - Add data structures for vertex-based animations (These are not + currently used, however ...) + - Some Assimp::Importer methods are const now. + + +1.1 (2010-04-17) +This is the list of relevant changes from the 1.0 (r412) release to 1.1 (r700). + +FEATURES: + - Vastly improved Collada support + - Add MS3D (Milkshape 3D) support + - Add support for Ogre XML static meshes + - Add experimental COB (TrueSpace) support + - Automatic test suite to quickly locate regressions + - D bindings (`dAssimp`) + - Python 2.n bindings (`PyAssimp`) + - Add basic support for Unicode input files (utf8, utf16 and utf32) + - Add further utilities to the `assimp` tool (xml/binary dumps, quick file stats) + - Switch to a CMAKE-based build system including an install target for unix'es + - Automatic evaluation of subdivision surfaces for some formats. + - Add `Importer::ReadFileFromMemory` and the corresponding C-API `aiReadFileFromMemory` + - Expose further math utilities via the C-API (i.e. `aiMultiplyMatrix4`) + + - Move noboost files away from the public include directory + - Many, many bugfixes and improvements in existing loaders and postprocessing steps + - Documentation improved and clarified in many places. + - Add a sample on using Assimp in conjunction with OpenGL + + - Distribution/packaging: comfortable SDK installer for Windows + - Distribution/packaging: improved release packages for other architectures + +CRITICAL FIXES: + - Resolve problems with clashing heap managers, STL ABIs and runtime libraries (win32) + - Fix automatic detection of file type if no file extension is given + - Improved exception safety and robustness, prevent leaking of exceptions through the C interface + - Fix possible heap corruption due to material properties pulled in incorrectly + - Avoid leaking in certain error scenarios + - Fix 64 bit compatibility problems in some loaders (i.e. MDL) + +BREAKING API CHANGES: + - None - + +MINOR API BEHAVIOUR CHANGES: + - Change quaternion orientation to suit to the more common convention (-w). + - aiString is utf8 now. Not yet consistent, however. diff --git a/Engine/lib/assimp/CREDITS b/Engine/lib/assimp/CREDITS new file mode 100644 index 000000000..26e21d2f4 --- /dev/null +++ b/Engine/lib/assimp/CREDITS @@ -0,0 +1,183 @@ +=============================================================== +Open Asset Import Library (Assimp) +Developers and Contributors +=============================================================== + +The following is a non-exhaustive list of all constributors over the years. +If you think your name should be listed here, drop us a line and we'll add you. + +- Alexander Gessler, +3DS-, BLEND-, ASE-, DXF-, HMP-, MDL-, MD2-, MD3-, MD5-, MDC-, NFF-, PLY-, STL-, RAW-, OFF-, MS3D-, Q3D- and LWO-Loader, Assimp-Viewer, assimp-cmd, -noboost, Website (Design). + +- Thomas Schulze, +X-, Collada-, BVH-Loader, Postprocessing framework. Data structure & Interface design, documentation. + +- Kim Kulling, +Obj-, Q3BSD-, OpenGEX-Loader, Logging system, CMake-build-environment, Linux-build, Website ( Admin ), Coverity ( Admin ), Glitter ( Admin ). + +- R.Schmidt, +Linux build, eclipse support. + +- Matthias Gubisch, +Assimp.net +Visual Studio 9 support, bugfixes. + +- Mark Sibly +B3D-Loader, Assimp testing + +- Jonathan Klein +Ogre Loader, VC2010 fixes and CMake fixes. + +- Sebastian Hempel, +PyAssimp (first version) +Compile-Bugfixes for mingw, add environment for static library support in make. + +- Jonathan Pokrass +Supplied a bugfix concerning the scaling in the md3 loader. + +- Andrew Galante, +Submitted patches to make Assimp compile with GCC-4, a makefile and the xcode3 workspace. + +- Andreas Nagel +First Assimp testing & verification under Windows Vista 64 Bit. + +- Marius Schr�der +Allowed us to use many of his models for screenshots and testing. + +- Christian Schubert +Supplied various XFiles for testing purposes. + +- Tizian Wieland +Searched the web for hundreds of test models for internal use + +- John Connors +Supplied patches for linux and SCons. + +- T. R. +The GUY who performed some of the CSM mocaps. + +- Andy Maloney +Contributed fixes for the documentation and the doxygen markup + +- Zhao Lei +Contributed several bugfixes fixing memory leaks and improving float parsing + +- sueastside +Updated PyAssimp to the latest Assimp data structures and provided a script to keep the Python binding up-to-date. + +- Tobias Rittig +Collada testing with Cinema 4D + +- Brad Grantham +Improvements in OpenGL-Sample. + +- Robert Ramirez +Add group loading feature to Obj-Loader. + +- Chris Maiwald +Many bugreports, improving Assimp's portability, regular testing & feedback. + +- Stepan Hrbek +Bugreport and fix for a obj-materialloader crash. + +- David Nadlinger +D bindings, CMake install support. + +- Dario Accornero +Contributed several patches regarding Mac OS/XCode targets, bug reports. + +- Martin Walser (Samhayne) +Contributed the 'SimpleTexturedOpenGl' sample. + +- Matthias Fauconneau +Contributed a fix for the Q3-BSP loader. + +- Jørgen P. Tjernø +Contributed updated and improved xcode workspaces + +- drparallax +Contributed the /samples/SimpleAssimpViewX sample + +- Carsten Fuchs +Contributed a fix for the Normalize method in aiQuaternion. + +- dbburgess +Contributes a Android-specific build issue: log the hardware architecture for ARM. + +- alfiereinre7 +Contributes a obj-fileparser fix: missing tokens in the obj-token list. + +- Roman Kharitonov +Contributes a fix for the configure script environment. + +- Ed Diana +Contributed AssimpDelphi (/port/AssimpDelphi). + +- rdb +Contributes a bundle of fixes and improvements for the bsp-importer. + +- Mick P +For contributing the De-bone postprocessing step and filing various bug reports. + +- Rosen Diankov +Contributed patches to build assimp debian packages using cmake. + +- Mark Page +Contributed a patch to fix the VertexTriangleAdjacency postprocessing step. + +- IOhannes +Contributed the Debian build fixes ( architecture macro ). + +- gellule +Several LWO and LWS fixes (pivoting). + +- Marcel Metz +GCC/Linux fixes for the SimpleOpenGL sample. + +- Brian Miller +Bugfix for a compiler fix for iOS on arm. + +- Séverin Lemaignan +Rewrite of PyAssimp, distutils and Python3 support + +- albert-wang +Bugfixes for the collada parser + +- Ya ping Jin +Bugfixes for uv-tanget calculation. + +- Jonne Nauha +Ogre Binary format support + +- Filip Wasil, Tieto Poland Sp. z o.o. +Android JNI asset extraction support + +- Richard Steffen +Contributed ExportProperties interface +Contributed X File exporter +Contributed Step (stp) exporter + +- Thomas Iorns (mesilliac) +Initial FBX Export support + +For a more detailed list just check: https://github.com/assimp/assimp/network/members + + +======== +Patreons +======== + +Huge thanks to our Patreons! + +- migenius +- Marcus +- Cort +- elect +- Steffen + + +=================== +Commercial Sponsors +=================== + +- MyDidimo (mydidimo.com): Sponsored development of FBX Export support diff --git a/Engine/lib/assimp/LICENSE b/Engine/lib/assimp/LICENSE new file mode 100644 index 000000000..acaaf016e --- /dev/null +++ b/Engine/lib/assimp/LICENSE @@ -0,0 +1,78 @@ +Open Asset Import Library (assimp) + +Copyright (c) 2006-2021, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + +****************************************************************************** + +AN EXCEPTION applies to all files in the ./test/models-nonbsd folder. +These are 3d models for testing purposes, from various free sources +on the internet. They are - unless otherwise stated - copyright of +their respective creators, which may impose additional requirements +on the use of their work. For any of these models, see +.source.txt for more legal information. Contact us if you +are a copyright holder and believe that we credited you inproperly or +if you don't want your files to appear in the repository. + + +****************************************************************************** + +Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors +http://code.google.com/p/poly2tri/ + +All rights reserved. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of Poly2Tri nor the names of its contributors may be + used to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Engine/lib/assimp/Readme.md b/Engine/lib/assimp/Readme.md new file mode 100644 index 000000000..f4167c9f2 --- /dev/null +++ b/Engine/lib/assimp/Readme.md @@ -0,0 +1,120 @@ +Open Asset Import Library (assimp) +================================== +A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data. +### Current project status ### +[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp) +![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg) + + Coverity Scan Build Status + +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=assimp/assimp&utm_campaign=Badge_Grade) +[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master) +[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue") +[![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/) +
    + +APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS. +Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more. + +### Latest Doc's ### +Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/). + +### Get involved ### +This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases). +
    +You find a bug in the docs? Use [Doc-Repo](https://github.com/assimp/assimp-docs). +
    +Please check our Wiki as well: https://github.com/assimp/assimp/wiki + +If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb + +#### Supported file formats #### +You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md) + +### Building ### +Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do. + +### Ports ### +* [Android](port/AndroidJNI/README.md) +* [Python](port/PyAssimp/README.md) +* [.NET](https://bitbucket.org/Starnick/assimpnet/src/master/) +* [Pascal](port/AssimpPascal/Readme.md) +* [Javascript (Alpha)](https://github.com/makc/assimp2json) +* [Javascript/Node.js Interface](https://github.com/kovacsv/assimpjs) +* [Unity 3d Plugin](https://ricardoreis.net/trilib-2/) +* [Unreal Engine Plugin](https://github.com/irajsb/UE4_Assimp/) +* [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status)) +* [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port. +* [Rust](https://github.com/jkvargas/russimp) + +### Other tools ### +[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities. + +#### Repository structure #### +Open Asset Import Library is implemented in C++. The directory structure looks like: + + /code Source code + /contrib Third-party libraries + /doc Documentation (doxysource and pre-compiled docs) + /include Public header C and C++ header files + /scripts Scripts used to generate the loading code for some formats + /port Ports to other languages and scripts to maintain those. + /test Unit- and regression tests, test suite of models + /tools Tools (old assimp viewer, command line `assimp`) + /samples A small number of samples to illustrate possible + use cases for Assimp + +The source code is organized in the following way: + + code/Common The base implementation for importers and the infrastructure + code/PostProcessing The post-processing steps + code/AssetLib/ Implementation for import and export for the format + +### Where to get help ### +For more information, visit [our website](http://assimp.org/). Or check out the `./doc`- folder, which contains the official documentation in HTML format. +(CHMs for Windows are included in some release packages and should be located right here in the root folder). + +If the docs don't solve your problem, ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github. + +Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export. + +And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
    + +### Contributing ### +Contributions to assimp are highly appreciated. The easiest way to get involved is to submit +a pull request with your changes against the main repository's `master` branch. + +## Contributors + +### Code Contributors + +This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. + + + +### Financial Contributors + +Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/assimp/contribute)] + +#### Individuals + + + + +#### Organizations + +Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/assimp/contribute)] + + + +### License ### +Our license is based on the modified, __3-clause BSD__-License. + +An _informal_ summary is: do whatever you want, but include Assimp's license text with your product - +and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp. +For the legal details, see the `LICENSE` file. + +### Why this name ### +Sorry, we're germans :-), no english native speakers ... diff --git a/Engine/lib/assimp/code/3DS/3DSHelper.h b/Engine/lib/assimp/code/3DS/3DSHelper.h deleted file mode 100644 index 8eb4cd97c..000000000 --- a/Engine/lib/assimp/code/3DS/3DSHelper.h +++ /dev/null @@ -1,652 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines helper data structures for the import of 3DS files */ - -#ifndef AI_3DSFILEHELPER_H_INC -#define AI_3DSFILEHELPER_H_INC - -#include -#include -#include -#include -#include -#include -#include -#include -#include //sprintf - -namespace Assimp { -namespace D3DS { - -#include - -// --------------------------------------------------------------------------- -/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks -* and data structures. -*/ -class Discreet3DS { -private: - Discreet3DS() AI_NO_EXCEPT { - // empty - } - - ~Discreet3DS() { - // empty - } - -public: - //! data structure for a single chunk in a .3ds file - struct Chunk { - uint16_t Flag; - uint32_t Size; - } PACK_STRUCT; - - - //! Used for shading field in material3ds structure - //! From AutoDesk 3ds SDK - typedef enum - { - // translated to gouraud shading with wireframe active - Wire = 0x0, - - // if this material is set, no vertex normals will - // be calculated for the model. Face normals + gouraud - Flat = 0x1, - - // standard gouraud shading - Gouraud = 0x2, - - // phong shading - Phong = 0x3, - - // cooktorrance or anistropic phong shading ... - // the exact meaning is unknown, if you know it - // feel free to tell me ;-) - Metal = 0x4, - - // required by the ASE loader - Blinn = 0x5 - } shadetype3ds; - - // Flags for animated keys - enum - { - KEY_USE_TENS = 0x1, - KEY_USE_CONT = 0x2, - KEY_USE_BIAS = 0x4, - KEY_USE_EASE_TO = 0x8, - KEY_USE_EASE_FROM = 0x10 - } ; - - enum - { - - // ******************************************************************** - // Basic chunks which can be found everywhere in the file - CHUNK_VERSION = 0x0002, - CHUNK_RGBF = 0x0010, // float4 R; float4 G; float4 B - CHUNK_RGBB = 0x0011, // int1 R; int1 G; int B - - // Linear color values (gamma = 2.2?) - CHUNK_LINRGBF = 0x0013, // float4 R; float4 G; float4 B - CHUNK_LINRGBB = 0x0012, // int1 R; int1 G; int B - - CHUNK_PERCENTW = 0x0030, // int2 percentage - CHUNK_PERCENTF = 0x0031, // float4 percentage - CHUNK_PERCENTD = 0x0032, // float8 percentage - // ******************************************************************** - - // Prj master chunk - CHUNK_PRJ = 0xC23D, - - // MDLI master chunk - CHUNK_MLI = 0x3DAA, - - // Primary main chunk of the .3ds file - CHUNK_MAIN = 0x4D4D, - - // Mesh main chunk - CHUNK_OBJMESH = 0x3D3D, - - // Specifies the background color of the .3ds file - // This is passed through the material system for - // viewing purposes. - CHUNK_BKGCOLOR = 0x1200, - - // Specifies the ambient base color of the scene. - // This is added to all materials in the file - CHUNK_AMBCOLOR = 0x2100, - - // Specifies the background image for the whole scene - // This value is passed through the material system - // to the viewer - CHUNK_BIT_MAP = 0x1100, - CHUNK_BIT_MAP_EXISTS = 0x1101, - - // ******************************************************************** - // Viewport related stuff. Ignored - CHUNK_DEFAULT_VIEW = 0x3000, - CHUNK_VIEW_TOP = 0x3010, - CHUNK_VIEW_BOTTOM = 0x3020, - CHUNK_VIEW_LEFT = 0x3030, - CHUNK_VIEW_RIGHT = 0x3040, - CHUNK_VIEW_FRONT = 0x3050, - CHUNK_VIEW_BACK = 0x3060, - CHUNK_VIEW_USER = 0x3070, - CHUNK_VIEW_CAMERA = 0x3080, - // ******************************************************************** - - // Mesh chunks - CHUNK_OBJBLOCK = 0x4000, - CHUNK_TRIMESH = 0x4100, - CHUNK_VERTLIST = 0x4110, - CHUNK_VERTFLAGS = 0x4111, - CHUNK_FACELIST = 0x4120, - CHUNK_FACEMAT = 0x4130, - CHUNK_MAPLIST = 0x4140, - CHUNK_SMOOLIST = 0x4150, - CHUNK_TRMATRIX = 0x4160, - CHUNK_MESHCOLOR = 0x4165, - CHUNK_TXTINFO = 0x4170, - CHUNK_LIGHT = 0x4600, - CHUNK_CAMERA = 0x4700, - CHUNK_HIERARCHY = 0x4F00, - - // Specifies the global scaling factor. This is applied - // to the root node's transformation matrix - CHUNK_MASTER_SCALE = 0x0100, - - // ******************************************************************** - // Material chunks - CHUNK_MAT_MATERIAL = 0xAFFF, - - // asciiz containing the name of the material - CHUNK_MAT_MATNAME = 0xA000, - CHUNK_MAT_AMBIENT = 0xA010, // followed by color chunk - CHUNK_MAT_DIFFUSE = 0xA020, // followed by color chunk - CHUNK_MAT_SPECULAR = 0xA030, // followed by color chunk - - // Specifies the shininess of the material - // followed by percentage chunk - CHUNK_MAT_SHININESS = 0xA040, - CHUNK_MAT_SHININESS_PERCENT = 0xA041 , - - // Specifies the shading mode to be used - // followed by a short - CHUNK_MAT_SHADING = 0xA100, - - // NOTE: Emissive color (self illumination) seems not - // to be a color but a single value, type is unknown. - // Make the parser accept both of them. - // followed by percentage chunk (?) - CHUNK_MAT_SELF_ILLUM = 0xA080, - - // Always followed by percentage chunk (?) - CHUNK_MAT_SELF_ILPCT = 0xA084, - - // Always followed by percentage chunk - CHUNK_MAT_TRANSPARENCY = 0xA050, - - // Diffuse texture channel 0 - CHUNK_MAT_TEXTURE = 0xA200, - - // Contains opacity information for each texel - CHUNK_MAT_OPACMAP = 0xA210, - - // Contains a reflection map to be used to reflect - // the environment. This is partially supported. - CHUNK_MAT_REFLMAP = 0xA220, - - // Self Illumination map (emissive colors) - CHUNK_MAT_SELFIMAP = 0xA33d, - - // Bumpmap. Not specified whether it is a heightmap - // or a normal map. Assme it is a heightmap since - // artist normally prefer this format. - CHUNK_MAT_BUMPMAP = 0xA230, - - // Specular map. Seems to influence the specular color - CHUNK_MAT_SPECMAP = 0xA204, - - // Holds shininess data. - CHUNK_MAT_MAT_SHINMAP = 0xA33C, - - // Scaling in U/V direction. - // (need to gen separate UV coordinate set - // and do this by hand) - CHUNK_MAT_MAP_USCALE = 0xA354, - CHUNK_MAT_MAP_VSCALE = 0xA356, - - // Translation in U/V direction. - // (need to gen separate UV coordinate set - // and do this by hand) - CHUNK_MAT_MAP_UOFFSET = 0xA358, - CHUNK_MAT_MAP_VOFFSET = 0xA35a, - - // UV-coordinates rotation around the z-axis - // Assumed to be in radians. - CHUNK_MAT_MAP_ANG = 0xA35C, - - // Tiling flags for 3DS files - CHUNK_MAT_MAP_TILING = 0xa351, - - // Specifies the file name of a texture - CHUNK_MAPFILE = 0xA300, - - // Specifies whether a materail requires two-sided rendering - CHUNK_MAT_TWO_SIDE = 0xA081, - // ******************************************************************** - - // Main keyframer chunk. Contains translation/rotation/scaling data - CHUNK_KEYFRAMER = 0xB000, - - // Supported sub chunks - CHUNK_TRACKINFO = 0xB002, - CHUNK_TRACKOBJNAME = 0xB010, - CHUNK_TRACKDUMMYOBJNAME = 0xB011, - CHUNK_TRACKPIVOT = 0xB013, - CHUNK_TRACKPOS = 0xB020, - CHUNK_TRACKROTATE = 0xB021, - CHUNK_TRACKSCALE = 0xB022, - - // ******************************************************************** - // Keyframes for various other stuff in the file - // Partially ignored - CHUNK_AMBIENTKEY = 0xB001, - CHUNK_TRACKMORPH = 0xB026, - CHUNK_TRACKHIDE = 0xB029, - CHUNK_OBJNUMBER = 0xB030, - CHUNK_TRACKCAMERA = 0xB003, - CHUNK_TRACKFOV = 0xB023, - CHUNK_TRACKROLL = 0xB024, - CHUNK_TRACKCAMTGT = 0xB004, - CHUNK_TRACKLIGHT = 0xB005, - CHUNK_TRACKLIGTGT = 0xB006, - CHUNK_TRACKSPOTL = 0xB007, - CHUNK_FRAMES = 0xB008, - // ******************************************************************** - - // light sub-chunks - CHUNK_DL_OFF = 0x4620, - CHUNK_DL_OUTER_RANGE = 0x465A, - CHUNK_DL_INNER_RANGE = 0x4659, - CHUNK_DL_MULTIPLIER = 0x465B, - CHUNK_DL_EXCLUDE = 0x4654, - CHUNK_DL_ATTENUATE = 0x4625, - CHUNK_DL_SPOTLIGHT = 0x4610, - - // camera sub-chunks - CHUNK_CAM_RANGES = 0x4720 - }; -}; - -// --------------------------------------------------------------------------- -/** Helper structure representing a 3ds mesh face */ -struct Face : public FaceWithSmoothingGroup -{ -}; - -// --------------------------------------------------------------------------- -/** Helper structure representing a texture */ -struct Texture { - //! Default constructor - Texture() AI_NO_EXCEPT - : mOffsetU (0.0) - , mOffsetV (0.0) - , mScaleU (1.0) - , mScaleV (1.0) - , mRotation (0.0) - , mMapMode (aiTextureMapMode_Wrap) - , bPrivate() - , iUVSrc (0) { - mTextureBlend = get_qnan(); - } - - //! Specifies the blend factor for the texture - ai_real mTextureBlend; - - //! Specifies the filename of the texture - std::string mMapName; - - //! Specifies texture coordinate offsets/scaling/rotations - ai_real mOffsetU; - ai_real mOffsetV; - ai_real mScaleU; - ai_real mScaleV; - ai_real mRotation; - - //! Specifies the mapping mode to be used for the texture - aiTextureMapMode mMapMode; - - //! Used internally - bool bPrivate; - int iUVSrc; -}; - -#include - -// --------------------------------------------------------------------------- -/** Helper structure representing a 3ds material */ -struct Material -{ - //! Default constructor has been deleted - Material() = delete; - - - //! Constructor with explicit name - explicit Material(const std::string &name) - : mName(name) - , mDiffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black - , mSpecularExponent ( ai_real( 0.0 ) ) - , mShininessStrength ( ai_real( 1.0 ) ) - , mShading(Discreet3DS::Gouraud) - , mTransparency ( ai_real( 1.0 ) ) - , mBumpHeight ( ai_real( 1.0 ) ) - , mTwoSided (false) - { - } - - - Material(const Material &other) = default; - Material &operator=(const Material &other) = default; - - - //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it - Material(Material &&other) AI_NO_EXCEPT - : mName(std::move(other.mName)) - , mDiffuse(std::move(other.mDiffuse)) - , mSpecularExponent(std::move(other.mSpecularExponent)) - , mShininessStrength(std::move(other.mShininessStrength)) - , mSpecular(std::move(other.mSpecular)) - , mAmbient(std::move(other.mAmbient)) - , mShading(std::move(other.mShading)) - , mTransparency(std::move(other.mTransparency)) - , sTexDiffuse(std::move(other.sTexDiffuse)) - , sTexOpacity(std::move(other.sTexOpacity)) - , sTexSpecular(std::move(other.sTexSpecular)) - , sTexReflective(std::move(other.sTexReflective)) - , sTexBump(std::move(other.sTexBump)) - , sTexEmissive(std::move(other.sTexEmissive)) - , sTexShininess(std::move(other.sTexShininess)) - , mBumpHeight(std::move(other.mBumpHeight)) - , mEmissive(std::move(other.mEmissive)) - , sTexAmbient(std::move(other.sTexAmbient)) - , mTwoSided(std::move(other.mTwoSided)) - { - } - - - Material &operator=(Material &&other) AI_NO_EXCEPT { - if (this == &other) { - return *this; - } - - mName = std::move(other.mName); - mDiffuse = std::move(other.mDiffuse); - mSpecularExponent = std::move(other.mSpecularExponent); - mShininessStrength = std::move(other.mShininessStrength), - mSpecular = std::move(other.mSpecular); - mAmbient = std::move(other.mAmbient); - mShading = std::move(other.mShading); - mTransparency = std::move(other.mTransparency); - sTexDiffuse = std::move(other.sTexDiffuse); - sTexOpacity = std::move(other.sTexOpacity); - sTexSpecular = std::move(other.sTexSpecular); - sTexReflective = std::move(other.sTexReflective); - sTexBump = std::move(other.sTexBump); - sTexEmissive = std::move(other.sTexEmissive); - sTexShininess = std::move(other.sTexShininess); - mBumpHeight = std::move(other.mBumpHeight); - mEmissive = std::move(other.mEmissive); - sTexAmbient = std::move(other.sTexAmbient); - mTwoSided = std::move(other.mTwoSided); - - return *this; - } - - - virtual ~Material() {} - - - //! Name of the material - std::string mName; - //! Diffuse color of the material - aiColor3D mDiffuse; - //! Specular exponent - ai_real mSpecularExponent; - //! Shininess strength, in percent - ai_real mShininessStrength; - //! Specular color of the material - aiColor3D mSpecular; - //! Ambient color of the material - aiColor3D mAmbient; - //! Shading type to be used - Discreet3DS::shadetype3ds mShading; - //! Opacity of the material - ai_real mTransparency; - //! Diffuse texture channel - Texture sTexDiffuse; - //! Opacity texture channel - Texture sTexOpacity; - //! Specular texture channel - Texture sTexSpecular; - //! Reflective texture channel - Texture sTexReflective; - //! Bump texture channel - Texture sTexBump; - //! Emissive texture channel - Texture sTexEmissive; - //! Shininess texture channel - Texture sTexShininess; - //! Scaling factor for the bump values - ai_real mBumpHeight; - //! Emissive color - aiColor3D mEmissive; - //! Ambient texture channel - //! (used by the ASE format) - Texture sTexAmbient; - //! True if the material must be rendered from two sides - bool mTwoSided; -}; - -// --------------------------------------------------------------------------- -/** Helper structure to represent a 3ds file mesh */ -struct Mesh : public MeshWithSmoothingGroups -{ - //! Default constructor has been deleted - Mesh() = delete; - - //! Constructor with explicit name - explicit Mesh(const std::string &name) - : mName(name) - { - } - - - //! Name of the mesh - std::string mName; - - //! Texture coordinates - std::vector mTexCoords; - - //! Face materials - std::vector mFaceMaterials; - - //! Local transformation matrix - aiMatrix4x4 mMat; -}; - -// --------------------------------------------------------------------------- -/** Float key - quite similar to aiVectorKey and aiQuatKey. Both are in the - C-API, so it would be difficult to make them a template. */ -struct aiFloatKey -{ - double mTime; ///< The time of this key - ai_real mValue; ///< The value of this key - -#ifdef __cplusplus - - // time is not compared - bool operator == (const aiFloatKey& o) const - {return o.mValue == this->mValue;} - - bool operator != (const aiFloatKey& o) const - {return o.mValue != this->mValue;} - - // Only time is compared. This operator is defined - // for use with std::sort - bool operator < (const aiFloatKey& o) const - {return mTime < o.mTime;} - - bool operator > (const aiFloatKey& o) const - {return mTime > o.mTime;} - -#endif -}; - -// --------------------------------------------------------------------------- -/** Helper structure to represent a 3ds file node */ -struct Node -{ - Node() = delete; - - explicit Node(const std::string &name) - : mParent(NULL) - , mName(name) - , mInstanceNumber(0) - , mHierarchyPos (0) - , mHierarchyIndex (0) - , mInstanceCount (1) - { - aRotationKeys.reserve (20); - aPositionKeys.reserve (20); - aScalingKeys.reserve (20); - } - - - ~Node() - { - for (unsigned int i = 0; i < mChildren.size();++i) - delete mChildren[i]; - } - - //! Pointer to the parent node - Node* mParent; - - //! Holds all child nodes - std::vector mChildren; - - //! Name of the node - std::string mName; - - //! InstanceNumber of the node - int32_t mInstanceNumber; - - //! Dummy nodes: real name to be combined with the $$$DUMMY - std::string mDummyName; - - //! Position of the node in the hierarchy (tree depth) - int16_t mHierarchyPos; - - //! Index of the node - int16_t mHierarchyIndex; - - //! Rotation keys loaded from the file - std::vector aRotationKeys; - - //! Position keys loaded from the file - std::vector aPositionKeys; - - //! Scaling keys loaded from the file - std::vector aScalingKeys; - - - // For target lights (spot lights and directional lights): - // The position of the target - std::vector< aiVectorKey > aTargetPositionKeys; - - // For cameras: the camera roll angle - std::vector< aiFloatKey > aCameraRollKeys; - - //! Pivot position loaded from the file - aiVector3D vPivot; - - //instance count, will be kept only for the first node - int32_t mInstanceCount; - - //! Add a child node, setup the right parent node for it - //! \param pc Node to be 'adopted' - inline Node& push_back(Node* pc) - { - mChildren.push_back(pc); - pc->mParent = this; - return *this; - } -}; -// --------------------------------------------------------------------------- -/** Helper structure analogue to aiScene */ -struct Scene -{ - //! List of all materials loaded - //! NOTE: 3ds references materials globally - std::vector mMaterials; - - //! List of all meshes loaded - std::vector mMeshes; - - //! List of all cameras loaded - std::vector mCameras; - - //! List of all lights loaded - std::vector mLights; - - //! Pointer to the root node of the scene - // --- moved to main class - // Node* pcRootNode; -}; - - -} // end of namespace D3DS -} // end of namespace Assimp - -#endif // AI_XFILEHELPER_H_INC diff --git a/Engine/lib/assimp/code/3MF/3MFXmlTags.h b/Engine/lib/assimp/code/3MF/3MFXmlTags.h deleted file mode 100644 index ea6aeede0..000000000 --- a/Engine/lib/assimp/code/3MF/3MFXmlTags.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -#pragma once - -namespace Assimp { -namespace D3MF { - -namespace XmlTag { - // Meta-data - static const std::string meta = "metadata"; - static const std::string meta_name = "name"; - - // Model-data specific tags - static const std::string model = "model"; - static const std::string model_unit = "unit"; - static const std::string metadata = "metadata"; - static const std::string resources = "resources"; - static const std::string object = "object"; - static const std::string mesh = "mesh"; - static const std::string vertices = "vertices"; - static const std::string vertex = "vertex"; - static const std::string triangles = "triangles"; - static const std::string triangle = "triangle"; - static const std::string x = "x"; - static const std::string y = "y"; - static const std::string z = "z"; - static const std::string v1 = "v1"; - static const std::string v2 = "v2"; - static const std::string v3 = "v3"; - static const std::string id = "id"; - static const std::string pid = "pid"; - static const std::string p1 = "p1"; - static const std::string name = "name"; - static const std::string type = "type"; - static const std::string build = "build"; - static const std::string item = "item"; - static const std::string objectid = "objectid"; - static const std::string transform = "transform"; - - // Material definitions - static const std::string basematerials = "basematerials"; - static const std::string basematerials_id = "id"; - static const std::string basematerials_base = "base"; - static const std::string basematerials_name = "name"; - static const std::string basematerials_displaycolor = "displaycolor"; - - // Meta info tags - static const std::string CONTENT_TYPES_ARCHIVE = "[Content_Types].xml"; - static const std::string ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels"; - static const std::string SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types"; - static const std::string SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships"; - static const std::string RELS_RELATIONSHIP_CONTAINER = "Relationships"; - static const std::string RELS_RELATIONSHIP_NODE = "Relationship"; - static const std::string RELS_ATTRIB_TARGET = "Target"; - static const std::string RELS_ATTRIB_TYPE = "Type"; - static const std::string RELS_ATTRIB_ID = "Id"; - static const std::string PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel"; - static const std::string PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket"; - static const std::string PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture"; - static const std::string PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"; - static const std::string PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"; -} - -} // Namespace D3MF -} // Namespace Assimp diff --git a/Engine/lib/assimp/code/3MF/D3MFImporter.cpp b/Engine/lib/assimp/code/3MF/D3MFImporter.cpp deleted file mode 100644 index 682de684a..000000000 --- a/Engine/lib/assimp/code/3MF/D3MFImporter.cpp +++ /dev/null @@ -1,483 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER - -#include "D3MFImporter.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "D3MFOpcPackage.h" -#include -#include "3MFXmlTags.h" -#include - -#include - -namespace Assimp { -namespace D3MF { - -class XmlSerializer { -public: - using MatArray = std::vector; - using MatId2MatArray = std::map>; - - XmlSerializer(XmlReader* xmlReader) - : mMeshes() - , mMatArray() - , mActiveMatGroup( 99999999 ) - , mMatId2MatArray() - , xmlReader(xmlReader){ - // empty - } - - ~XmlSerializer() { - // empty - } - - void ImportXml(aiScene* scene) { - if ( nullptr == scene ) { - return; - } - - scene->mRootNode = new aiNode(); - std::vector children; - - std::string nodeName; - while(ReadToEndElement(D3MF::XmlTag::model)) { - nodeName = xmlReader->getNodeName(); - if( nodeName == D3MF::XmlTag::object) { - children.push_back(ReadObject(scene)); - } else if( nodeName == D3MF::XmlTag::build) { - // - } else if ( nodeName == D3MF::XmlTag::basematerials ) { - ReadBaseMaterials(); - } else if ( nodeName == D3MF::XmlTag::meta ) { - ReadMetadata(); - } - } - - if ( scene->mRootNode->mName.length == 0 ) { - scene->mRootNode->mName.Set( "3MF" ); - } - - // import the metadata - if ( !mMetaData.empty() ) { - const size_t numMeta( mMetaData.size() ); - scene->mMetaData = aiMetadata::Alloc(static_cast( numMeta ) ); - for ( size_t i = 0; i < numMeta; ++i ) { - aiString val( mMetaData[ i ].value ); - scene->mMetaData->Set(static_cast( i ), mMetaData[ i ].name, val ); - } - } - - // import the meshes - scene->mNumMeshes = static_cast( mMeshes.size()); - scene->mMeshes = new aiMesh*[scene->mNumMeshes](); - std::copy( mMeshes.begin(), mMeshes.end(), scene->mMeshes); - - // import the materials - scene->mNumMaterials = static_cast( mMatArray.size() ); - if ( 0 != scene->mNumMaterials ) { - scene->mMaterials = new aiMaterial*[ scene->mNumMaterials ]; - std::copy( mMatArray.begin(), mMatArray.end(), scene->mMaterials ); - } - - // create the scenegraph - scene->mRootNode->mNumChildren = static_cast(children.size()); - scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren](); - std::copy(children.begin(), children.end(), scene->mRootNode->mChildren); - } - -private: - aiNode* ReadObject(aiScene* scene) { - std::unique_ptr node(new aiNode()); - - std::vector meshIds; - - const char *attrib( nullptr ); - std::string name, type; - attrib = xmlReader->getAttributeValue( D3MF::XmlTag::id.c_str() ); - if ( nullptr != attrib ) { - name = attrib; - } - attrib = xmlReader->getAttributeValue( D3MF::XmlTag::type.c_str() ); - if ( nullptr != attrib ) { - type = attrib; - } - - node->mParent = scene->mRootNode; - node->mName.Set(name); - - size_t meshIdx = mMeshes.size(); - - while(ReadToEndElement(D3MF::XmlTag::object)) { - if(xmlReader->getNodeName() == D3MF::XmlTag::mesh) { - auto mesh = ReadMesh(); - - mesh->mName.Set(name); - mMeshes.push_back(mesh); - meshIds.push_back(static_cast(meshIdx)); - ++meshIdx; - } - } - - node->mNumMeshes = static_cast(meshIds.size()); - - node->mMeshes = new unsigned int[node->mNumMeshes]; - - std::copy(meshIds.begin(), meshIds.end(), node->mMeshes); - - return node.release(); - } - - aiMesh *ReadMesh() { - aiMesh* mesh = new aiMesh(); - while(ReadToEndElement(D3MF::XmlTag::mesh)) { - if(xmlReader->getNodeName() == D3MF::XmlTag::vertices) { - ImportVertices(mesh); - } else if(xmlReader->getNodeName() == D3MF::XmlTag::triangles) { - ImportTriangles(mesh); - } - } - - return mesh; - } - - void ReadMetadata() { - const std::string name = xmlReader->getAttributeValue( D3MF::XmlTag::meta_name.c_str() ); - xmlReader->read(); - const std::string value = xmlReader->getNodeData(); - - if ( name.empty() ) { - return; - } - - MetaEntry entry; - entry.name = name; - entry.value = value; - mMetaData.push_back( entry ); - } - - void ImportVertices(aiMesh* mesh) { - std::vector vertices; - while(ReadToEndElement(D3MF::XmlTag::vertices)) { - if(xmlReader->getNodeName() == D3MF::XmlTag::vertex) { - vertices.push_back(ReadVertex()); - } - } - mesh->mNumVertices = static_cast(vertices.size()); - mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - - std::copy(vertices.begin(), vertices.end(), mesh->mVertices); - } - - aiVector3D ReadVertex() { - aiVector3D vertex; - - vertex.x = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::x.c_str()), nullptr); - vertex.y = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::y.c_str()), nullptr); - vertex.z = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::z.c_str()), nullptr); - - return vertex; - } - - void ImportTriangles(aiMesh* mesh) { - std::vector faces; - - while(ReadToEndElement(D3MF::XmlTag::triangles)) { - const std::string nodeName( xmlReader->getNodeName() ); - if(xmlReader->getNodeName() == D3MF::XmlTag::triangle) { - faces.push_back(ReadTriangle()); - const char *pidToken( xmlReader->getAttributeValue( D3MF::XmlTag::p1.c_str() ) ); - if ( nullptr != pidToken ) { - int matIdx( std::atoi( pidToken ) ); - mesh->mMaterialIndex = matIdx; - } - } - } - - mesh->mNumFaces = static_cast(faces.size()); - mesh->mFaces = new aiFace[mesh->mNumFaces]; - mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; - - std::copy(faces.begin(), faces.end(), mesh->mFaces); - } - - aiFace ReadTriangle() { - aiFace face; - - face.mNumIndices = 3; - face.mIndices = new unsigned int[face.mNumIndices]; - face.mIndices[0] = static_cast(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v1.c_str()))); - face.mIndices[1] = static_cast(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v2.c_str()))); - face.mIndices[2] = static_cast(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v3.c_str()))); - - return face; - } - - void ReadBaseMaterials() { - std::vector MatIdArray; - const char *baseMaterialId( xmlReader->getAttributeValue( D3MF::XmlTag::basematerials_id.c_str() ) ); - if ( nullptr != baseMaterialId ) { - unsigned int id = std::atoi( baseMaterialId ); - const size_t newMatIdx( mMatArray.size() ); - if ( id != mActiveMatGroup ) { - mActiveMatGroup = id; - MatId2MatArray::const_iterator it( mMatId2MatArray.find( id ) ); - if ( mMatId2MatArray.end() == it ) { - MatIdArray.clear(); - mMatId2MatArray[ id ] = MatIdArray; - } else { - MatIdArray = it->second; - } - } - MatIdArray.push_back( static_cast( newMatIdx ) ); - mMatId2MatArray[ mActiveMatGroup ] = MatIdArray; - } - - while ( ReadToEndElement( D3MF::XmlTag::basematerials ) ) { - mMatArray.push_back( readMaterialDef() ); - } - } - - bool parseColor( const char *color, aiColor4D &diffuse ) { - if ( nullptr == color ) { - return false; - } - - //format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1) - const size_t len( strlen( color ) ); - if ( 9 != len && 7 != len) { - return false; - } - - const char *buf( color ); - if ( '#' != *buf ) { - return false; - } - ++buf; - char comp[ 3 ] = { 0,0,'\0' }; - - comp[ 0 ] = *buf; - ++buf; - comp[ 1 ] = *buf; - ++buf; - diffuse.r = static_cast( strtol( comp, NULL, 16 ) ) / ai_real(255.0); - - - comp[ 0 ] = *buf; - ++buf; - comp[ 1 ] = *buf; - ++buf; - diffuse.g = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / ai_real(255.0); - - comp[ 0 ] = *buf; - ++buf; - comp[ 1 ] = *buf; - ++buf; - diffuse.b = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / ai_real(255.0); - - if(7 == len) - return true; - comp[ 0 ] = *buf; - ++buf; - comp[ 1 ] = *buf; - ++buf; - diffuse.a = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / ai_real(255.0); - - return true; - } - - void assignDiffuseColor( aiMaterial *mat ) { - const char *color = xmlReader->getAttributeValue( D3MF::XmlTag::basematerials_displaycolor.c_str() ); - aiColor4D diffuse; - if ( parseColor( color, diffuse ) ) { - mat->AddProperty( &diffuse, 1, AI_MATKEY_COLOR_DIFFUSE ); - } - - } - aiMaterial *readMaterialDef() { - aiMaterial *mat( nullptr ); - const char *name( nullptr ); - const std::string nodeName( xmlReader->getNodeName() ); - if ( nodeName == D3MF::XmlTag::basematerials_base ) { - name = xmlReader->getAttributeValue( D3MF::XmlTag::basematerials_name.c_str() ); - std::string stdMatName; - aiString matName; - std::string strId( to_string( mActiveMatGroup ) ); - stdMatName += "id"; - stdMatName += strId; - stdMatName += "_"; - if ( nullptr != name ) { - stdMatName += std::string( name ); - } else { - stdMatName += "basemat"; - } - matName.Set( stdMatName ); - - mat = new aiMaterial; - mat->AddProperty( &matName, AI_MATKEY_NAME ); - - assignDiffuseColor( mat ); - } - - return mat; - } - -private: - bool ReadToStartElement(const std::string& startTag) { - while(xmlReader->read()) { - const std::string &nodeName( xmlReader->getNodeName() ); - if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT && nodeName == startTag) { - return true; - } else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END && nodeName == startTag) { - return false; - } - } - - return false; - } - - bool ReadToEndElement(const std::string& closeTag) { - while(xmlReader->read()) { - const std::string &nodeName( xmlReader->getNodeName() ); - if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT) { - return true; - } else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END && nodeName == closeTag) { - return false; - } - } - ASSIMP_LOG_ERROR("unexpected EOF, expected closing <" + closeTag + "> tag"); - - return false; - } - -private: - struct MetaEntry { - std::string name; - std::string value; - }; - std::vector mMetaData; - std::vector mMeshes; - MatArray mMatArray; - unsigned int mActiveMatGroup; - MatId2MatArray mMatId2MatArray; - XmlReader* xmlReader; -}; - -} //namespace D3MF - -static const aiImporterDesc desc = { - "3mf Importer", - "", - "", - "http://3mf.io/", - aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour, - 0, - 0, - 0, - 0, - "3mf" -}; - -D3MFImporter::D3MFImporter() -: BaseImporter() { - // empty -} - -D3MFImporter::~D3MFImporter() { - // empty -} - -bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const { - const std::string extension( GetExtension( filename ) ); - if(extension == desc.mFileExtensions ) { - return true; - } else if ( !extension.length() || checkSig ) { - if ( nullptr == pIOHandler ) { - return false; - } - if ( !ZipArchiveIOSystem::isZipArchive( pIOHandler, filename ) ) { - return false; - } - D3MF::D3MFOpcPackage opcPackage( pIOHandler, filename ); - return opcPackage.validate(); - } - - return false; -} - -void D3MFImporter::SetupProperties(const Importer * /*pImp*/) { - // empty -} - -const aiImporterDesc *D3MFImporter::GetInfo() const { - return &desc; -} - -void D3MFImporter::InternReadFile( const std::string &filename, aiScene *pScene, IOSystem *pIOHandler ) { - D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename); - - std::unique_ptr xmlStream(new CIrrXML_IOStreamReader(opcPackage.RootStream())); - std::unique_ptr xmlReader(irr::io::createIrrXMLReader(xmlStream.get())); - - D3MF::XmlSerializer xmlSerializer(xmlReader.get()); - - xmlSerializer.ImportXml(pScene); -} - -} // Namespace Assimp - -#endif // ASSIMP_BUILD_NO_3MF_IMPORTER diff --git a/Engine/lib/assimp/code/3MF/D3MFOpcPackage.cpp b/Engine/lib/assimp/code/3MF/D3MFOpcPackage.cpp deleted file mode 100644 index 873ba8ee8..000000000 --- a/Engine/lib/assimp/code/3MF/D3MFOpcPackage.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER - -#include "D3MFOpcPackage.h" -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include "3MFXmlTags.h" - -namespace Assimp { - -namespace D3MF { -// ------------------------------------------------------------------------------------------------ - -typedef std::shared_ptr OpcPackageRelationshipPtr; - -class OpcPackageRelationshipReader { -public: - OpcPackageRelationshipReader(XmlReader* xmlReader) { - while(xmlReader->read()) { - if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT && - xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER) - { - ParseRootNode(xmlReader); - } - } - } - - void ParseRootNode(XmlReader* xmlReader) - { - ParseAttributes(xmlReader); - - while(xmlReader->read()) - { - if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT && - xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE) - { - ParseChildNode(xmlReader); - } - } - } - - void ParseAttributes(XmlReader*) { - // empty - } - - bool validateRels( OpcPackageRelationshipPtr &relPtr ) { - if ( relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty() ) { - return false; - } - return true; - } - - void ParseChildNode(XmlReader* xmlReader) { - OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship()); - - relPtr->id = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_ID.c_str()); - relPtr->type = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TYPE.c_str()); - relPtr->target = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TARGET.c_str()); - if ( validateRels( relPtr ) ) { - m_relationShips.push_back( relPtr ); - } - } - - std::vector m_relationShips; -}; - -// ------------------------------------------------------------------------------------------------ -D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile) -: mRootStream(nullptr) -, mZipArchive() { - mZipArchive.reset( new ZipArchiveIOSystem( pIOHandler, rFile ) ); - if(!mZipArchive->isOpen()) { - throw DeadlyImportError("Failed to open file " + rFile+ "."); - } - - std::vector fileList; - mZipArchive->getFileList(fileList); - - for (auto& file: fileList) { - if(file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE) { - //PkgRelationshipReader pkgRelReader(file, archive); - ai_assert(mZipArchive->Exists(file.c_str())); - - IOStream *fileStream = mZipArchive->Open(file.c_str()); - - ai_assert(fileStream != nullptr); - - std::string rootFile = ReadPackageRootRelationship(fileStream); - if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) { - rootFile = rootFile.substr( 1 ); - if ( rootFile[ 0 ] == '/' ) { - // deal with zip-bug - rootFile = rootFile.substr( 1 ); - } - } - - ASSIMP_LOG_DEBUG(rootFile); - - mZipArchive->Close(fileStream); - - mRootStream = mZipArchive->Open(rootFile.c_str()); - ai_assert( mRootStream != nullptr ); - if ( nullptr == mRootStream ) { - throw DeadlyExportError( "Cannot open root-file in archive : " + rootFile ); - } - - } else if( file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) { - ASSIMP_LOG_WARN_F("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES",file); - } else { - ASSIMP_LOG_WARN_F("Ignored file of unknown type: ",file); - } - - } -} - -D3MFOpcPackage::~D3MFOpcPackage() { - mZipArchive->Close(mRootStream); -} - -IOStream* D3MFOpcPackage::RootStream() const { - return mRootStream; -} - -static const std::string ModelRef = "3D/3dmodel.model"; - -bool D3MFOpcPackage::validate() { - if ( nullptr == mRootStream || nullptr == mZipArchive ) { - return false; - } - - return mZipArchive->Exists( ModelRef.c_str() ); -} - -std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream) { - std::unique_ptr xmlStream(new CIrrXML_IOStreamReader(stream)); - std::unique_ptr xml(irr::io::createIrrXMLReader(xmlStream.get())); - - OpcPackageRelationshipReader reader(xml.get()); - - auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr& rel){ - return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE; - }); - - if ( itr == reader.m_relationShips.end() ) { - throw DeadlyImportError( "Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE ); - } - - return (*itr)->target; -} - -} // Namespace D3MF -} // Namespace Assimp - -#endif //ASSIMP_BUILD_NO_3MF_IMPORTER diff --git a/Engine/lib/assimp/code/AMF/AMFImporter.cpp b/Engine/lib/assimp/code/AMF/AMFImporter.cpp deleted file mode 100644 index dedb6dcdd..000000000 --- a/Engine/lib/assimp/code/AMF/AMFImporter.cpp +++ /dev/null @@ -1,705 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/// \file AMFImporter.cpp -/// \brief AMF-format files importer for Assimp: main algorithm implementation. -/// \date 2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER - -// Header files, Assimp. -#include "AMFImporter.hpp" -#include "AMFImporter_Macro.hpp" - -#include -#include - -// Header files, stdlib. -#include - -namespace Assimp -{ - -/// \var aiImporterDesc AMFImporter::Description -/// Conastant which hold importer description -const aiImporterDesc AMFImporter::Description = { - "Additive manufacturing file format(AMF) Importer", - "smalcom", - "", - "See documentation in source code. Chapter: Limitations.", - aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental, - 0, - 0, - 0, - 0, - "amf" -}; - -void AMFImporter::Clear() -{ - mNodeElement_Cur = nullptr; - mUnit.clear(); - mMaterial_Converted.clear(); - mTexture_Converted.clear(); - // Delete all elements - if(!mNodeElement_List.empty()) - { - for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; } - - mNodeElement_List.clear(); - } -} - -AMFImporter::~AMFImporter() -{ - if(mReader != nullptr) delete mReader; - // Clear() is accounting if data already is deleted. So, just check again if all data is deleted. - Clear(); -} - -/*********************************************************************************************************************************************/ -/************************************************************ Functions: find set ************************************************************/ -/*********************************************************************************************************************************************/ - -bool AMFImporter::Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const -{ - for(CAMFImporter_NodeElement* ne: mNodeElement_List) - { - if((ne->ID == pID) && (ne->Type == pType)) - { - if(pNodeElement != nullptr) *pNodeElement = ne; - - return true; - } - }// for(CAMFImporter_NodeElement* ne: mNodeElement_List) - - return false; -} - -bool AMFImporter::Find_ConvertedNode(const std::string& pID, std::list& pNodeList, aiNode** pNode) const -{ -aiString node_name(pID.c_str()); - - for(aiNode* node: pNodeList) - { - if(node->mName == node_name) - { - if(pNode != nullptr) *pNode = node; - - return true; - } - }// for(aiNode* node: pNodeList) - - return false; -} - -bool AMFImporter::Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const -{ - for(const SPP_Material& mat: mMaterial_Converted) - { - if(mat.ID == pID) - { - if(pConvertedMaterial != nullptr) *pConvertedMaterial = &mat; - - return true; - } - }// for(const SPP_Material& mat: mMaterial_Converted) - - return false; -} - -/*********************************************************************************************************************************************/ -/************************************************************ Functions: throw set ***********************************************************/ -/*********************************************************************************************************************************************/ - -void AMFImporter::Throw_CloseNotFound(const std::string& pNode) -{ - throw DeadlyImportError("Close tag for node <" + pNode + "> not found. Seems file is corrupt."); -} - -void AMFImporter::Throw_IncorrectAttr(const std::string& pAttrName) -{ - throw DeadlyImportError("Node <" + std::string(mReader->getNodeName()) + "> has incorrect attribute \"" + pAttrName + "\"."); -} - -void AMFImporter::Throw_IncorrectAttrValue(const std::string& pAttrName) -{ - throw DeadlyImportError("Attribute \"" + pAttrName + "\" in node <" + std::string(mReader->getNodeName()) + "> has incorrect value."); -} - -void AMFImporter::Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription) -{ - throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + mReader->getNodeName() + ". Description: " + pDescription); -} - -void AMFImporter::Throw_ID_NotFound(const std::string& pID) const -{ - throw DeadlyImportError("Not found node with name \"" + pID + "\"."); -} - -/*********************************************************************************************************************************************/ -/************************************************************* Functions: XML set ************************************************************/ -/*********************************************************************************************************************************************/ - -void AMFImporter::XML_CheckNode_MustHaveChildren() -{ - if(mReader->isEmptyElement()) throw DeadlyImportError(std::string("Node <") + mReader->getNodeName() + "> must have children."); -} - -void AMFImporter::XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName) -{ - static const size_t Uns_Skip_Len = 3; - const char* Uns_Skip[Uns_Skip_Len] = { "composite", "edge", "normal" }; - - static bool skipped_before[Uns_Skip_Len] = { false, false, false }; - - std::string nn(mReader->getNodeName()); - bool found = false; - bool close_found = false; - size_t sk_idx; - - for(sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++) - { - if(nn != Uns_Skip[sk_idx]) continue; - - found = true; - if(mReader->isEmptyElement()) - { - close_found = true; - - goto casu_cres; - } - - while(mReader->read()) - { - if((mReader->getNodeType() == irr::io::EXN_ELEMENT_END) && (nn == mReader->getNodeName())) - { - close_found = true; - - goto casu_cres; - } - } - }// for(sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++) - -casu_cres: - - if(!found) throw DeadlyImportError("Unknown node \"" + nn + "\" in " + pParentNodeName + "."); - if(!close_found) Throw_CloseNotFound(nn); - - if(!skipped_before[sk_idx]) - { - skipped_before[sk_idx] = true; - ASSIMP_LOG_WARN_F("Skipping node \"", nn, "\" in ", pParentNodeName, "."); - } -} - -bool AMFImporter::XML_SearchNode(const std::string& pNodeName) -{ - while(mReader->read()) - { - if((mReader->getNodeType() == irr::io::EXN_ELEMENT) && XML_CheckNode_NameEqual(pNodeName)) return true; - } - - return false; -} - -bool AMFImporter::XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx) -{ - std::string val(mReader->getAttributeValue(pAttrIdx)); - - if((val == "false") || (val == "0")) - return false; - else if((val == "true") || (val == "1")) - return true; - else - throw DeadlyImportError("Bool attribute value can contain \"false\"/\"0\" or \"true\"/\"1\" not the \"" + val + "\""); -} - -float AMFImporter::XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx) -{ - std::string val; - float tvalf; - - ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), val); - fast_atoreal_move(val.c_str(), tvalf, false); - - return tvalf; -} - -uint32_t AMFImporter::XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx) -{ - return strtoul10(mReader->getAttributeValue(pAttrIdx)); -} - -float AMFImporter::XML_ReadNode_GetVal_AsFloat() -{ - std::string val; - float tvalf; - - if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. No data, seems file is corrupt."); - if(mReader->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. Invalid type of XML element, seems file is corrupt."); - - ParseHelper_FixTruncatedFloatString(mReader->getNodeData(), val); - fast_atoreal_move(val.c_str(), tvalf, false); - - return tvalf; -} - -uint32_t AMFImporter::XML_ReadNode_GetVal_AsU32() -{ - if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. No data, seems file is corrupt."); - if(mReader->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. Invalid type of XML element, seems file is corrupt."); - - return strtoul10(mReader->getNodeData()); -} - -void AMFImporter::XML_ReadNode_GetVal_AsString(std::string& pValue) -{ - if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsString. No data, seems file is corrupt."); - if(mReader->getNodeType() != irr::io::EXN_TEXT) - throw DeadlyImportError("XML_ReadNode_GetVal_AsString. Invalid type of XML element, seems file is corrupt."); - - pValue = mReader->getNodeData(); -} - -/*********************************************************************************************************************************************/ -/************************************************************ Functions: parse set ***********************************************************/ -/*********************************************************************************************************************************************/ - -void AMFImporter::ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode) -{ - mNodeElement_Cur->Child.push_back(pNode);// add new element to current element child list. - mNodeElement_Cur = pNode;// switch current element to new one. -} - -void AMFImporter::ParseHelper_Node_Exit() -{ - // check if we can walk up. - if(mNodeElement_Cur != nullptr) mNodeElement_Cur = mNodeElement_Cur->Parent; -} - -void AMFImporter::ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString) -{ - size_t instr_len; - - pOutString.clear(); - instr_len = strlen(pInStr); - if(!instr_len) return; - - pOutString.reserve(instr_len * 3 / 2); - // check and correct floats in format ".x". Must be "x.y". - if(pInStr[0] == '.') pOutString.push_back('0'); - - pOutString.push_back(pInStr[0]); - for(size_t ci = 1; ci < instr_len; ci++) - { - if((pInStr[ci] == '.') && ((pInStr[ci - 1] == ' ') || (pInStr[ci - 1] == '-') || (pInStr[ci - 1] == '+') || (pInStr[ci - 1] == '\t'))) - { - pOutString.push_back('0'); - pOutString.push_back('.'); - } - else - { - pOutString.push_back(pInStr[ci]); - } - } -} - -static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) -{ - return (isalnum(pChar) || (pChar == '+') || (pChar == '/')); -} - -void AMFImporter::ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector& pOutputData) const -{ - // With help from - // René Nyffenegger http://www.adp-gmbh.ch/cpp/common/base64.html - const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - uint8_t tidx = 0; - uint8_t arr4[4], arr3[3]; - - // check input data - if(pInputBase64.size() % 4) throw DeadlyImportError("Base64-encoded data must have size multiply of four."); - // prepare output place - pOutputData.clear(); - pOutputData.reserve(pInputBase64.size() / 4 * 3); - - for(size_t in_len = pInputBase64.size(), in_idx = 0; (in_len > 0) && (pInputBase64[in_idx] != '='); in_len--) - { - if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx])) - { - arr4[tidx++] = pInputBase64[in_idx++]; - if(tidx == 4) - { - for(tidx = 0; tidx < 4; tidx++) arr4[tidx] = (uint8_t)base64_chars.find(arr4[tidx]); - - arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4); - arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2); - arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3]; - for(tidx = 0; tidx < 3; tidx++) pOutputData.push_back(arr3[tidx]); - - tidx = 0; - }// if(tidx == 4) - }// if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx])) - else - { - in_idx++; - }// if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx])) else - } - - if(tidx) - { - for(uint8_t i = tidx; i < 4; i++) arr4[i] = 0; - for(uint8_t i = 0; i < 4; i++) arr4[i] = (uint8_t)(base64_chars.find(arr4[i])); - - arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4); - arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2); - arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3]; - for(uint8_t i = 0; i < (tidx - 1); i++) pOutputData.push_back(arr3[i]); - } -} - -void AMFImporter::ParseFile(const std::string& pFile, IOSystem* pIOHandler) -{ - irr::io::IrrXMLReader* OldReader = mReader;// store current XMLreader. - std::unique_ptr file(pIOHandler->Open(pFile, "rb")); - - // Check whether we can read from the file - if(file.get() == NULL) throw DeadlyImportError("Failed to open AMF file " + pFile + "."); - - // generate a XML reader for it - std::unique_ptr mIOWrapper(new CIrrXML_IOStreamReader(file.get())); - mReader = irr::io::createIrrXMLReader(mIOWrapper.get()); - if(!mReader) throw DeadlyImportError("Failed to create XML reader for file" + pFile + "."); - // - // start reading - // search for root tag - if(XML_SearchNode("amf")) - ParseNode_Root(); - else - throw DeadlyImportError("Root node \"amf\" not found."); - - delete mReader; - // restore old XMLreader - mReader = OldReader; -} - -// -// -// Root XML element. -// Multi elements - No. -void AMFImporter::ParseNode_Root() -{ - std::string unit, version; - CAMFImporter_NodeElement *ne( nullptr ); - - // Read attributes for node . - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECK_RET("unit", unit, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_RET("version", version, mReader->getAttributeValue); - MACRO_ATTRREAD_LOOPEND_WSKIP; - - // Check attributes - if(!mUnit.empty()) - { - if((mUnit != "inch") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) Throw_IncorrectAttrValue("unit"); - } - - // create root node element. - ne = new CAMFImporter_NodeElement_Root(nullptr); - mNodeElement_Cur = ne;// set first "current" element - // and assign attribute's values - ((CAMFImporter_NodeElement_Root*)ne)->Unit = unit; - ((CAMFImporter_NodeElement_Root*)ne)->Version = version; - - // Check for child nodes - if(!mReader->isEmptyElement()) - { - MACRO_NODECHECK_LOOPBEGIN("amf"); - if(XML_CheckNode_NameEqual("object")) { ParseNode_Object(); continue; } - if(XML_CheckNode_NameEqual("material")) { ParseNode_Material(); continue; } - if(XML_CheckNode_NameEqual("texture")) { ParseNode_Texture(); continue; } - if(XML_CheckNode_NameEqual("constellation")) { ParseNode_Constellation(); continue; } - if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } - MACRO_NODECHECK_LOOPEND("amf"); - mNodeElement_Cur = ne;// force restore "current" element - }// if(!mReader->isEmptyElement()) - - mNodeElement_List.push_back(ne);// add to node element list because its a new object in graph. -} - -// -// -// A collection of objects or constellations with specific relative locations. -// Multi elements - Yes. -// Parent element - . -void AMFImporter::ParseNode_Constellation() -{ - std::string id; - CAMFImporter_NodeElement* ne( nullptr ); - - // Read attributes for node . - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue); - MACRO_ATTRREAD_LOOPEND; - - // create and if needed - define new grouping object. - ne = new CAMFImporter_NodeElement_Constellation(mNodeElement_Cur); - - CAMFImporter_NodeElement_Constellation& als = *((CAMFImporter_NodeElement_Constellation*)ne);// alias for convenience - - if(!id.empty()) als.ID = id; - // Check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("constellation"); - if(XML_CheckNode_NameEqual("instance")) { ParseNode_Instance(); continue; } - if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } - MACRO_NODECHECK_LOOPEND("constellation"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else - - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. -} - -// -// -// A collection of objects or constellations with specific relative locations. -// Multi elements - Yes. -// Parent element - . -void AMFImporter::ParseNode_Instance() -{ - std::string objectid; - CAMFImporter_NodeElement* ne( nullptr ); - - // Read attributes for node . - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECK_RET("objectid", objectid, mReader->getAttributeValue); - MACRO_ATTRREAD_LOOPEND; - - // used object id must be defined, check that. - if(objectid.empty()) throw DeadlyImportError("\"objectid\" in must be defined."); - // create and define new grouping object. - ne = new CAMFImporter_NodeElement_Instance(mNodeElement_Cur); - - CAMFImporter_NodeElement_Instance& als = *((CAMFImporter_NodeElement_Instance*)ne);// alias for convenience - - als.ObjectID = objectid; - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool read_flag[6] = { false, false, false, false, false, false }; - - als.Delta.Set(0, 0, 0); - als.Rotation.Set(0, 0, 0); - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("instance"); - MACRO_NODECHECK_READCOMP_F("deltax", read_flag[0], als.Delta.x); - MACRO_NODECHECK_READCOMP_F("deltay", read_flag[1], als.Delta.y); - MACRO_NODECHECK_READCOMP_F("deltaz", read_flag[2], als.Delta.z); - MACRO_NODECHECK_READCOMP_F("rx", read_flag[3], als.Rotation.x); - MACRO_NODECHECK_READCOMP_F("ry", read_flag[4], als.Rotation.y); - MACRO_NODECHECK_READCOMP_F("rz", read_flag[5], als.Rotation.z); - MACRO_NODECHECK_LOOPEND("instance"); - ParseHelper_Node_Exit(); - // also convert degrees to radians. - als.Rotation.x = AI_MATH_PI_F * als.Rotation.x / 180.0f; - als.Rotation.y = AI_MATH_PI_F * als.Rotation.y / 180.0f; - als.Rotation.z = AI_MATH_PI_F * als.Rotation.z / 180.0f; - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else - - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. -} - -// -// -// An object definition. -// Multi elements - Yes. -// Parent element - . -void AMFImporter::ParseNode_Object() -{ - std::string id; - CAMFImporter_NodeElement* ne( nullptr ); - - // Read attributes for node . - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue); - MACRO_ATTRREAD_LOOPEND; - - // create and if needed - define new geometry object. - ne = new CAMFImporter_NodeElement_Object(mNodeElement_Cur); - - CAMFImporter_NodeElement_Object& als = *((CAMFImporter_NodeElement_Object*)ne);// alias for convenience - - if(!id.empty()) als.ID = id; - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool col_read = false; - - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("object"); - if(XML_CheckNode_NameEqual("color")) - { - // Check if color already defined for object. - if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); - // read data and set flag about it - ParseNode_Color(); - col_read = true; - - continue; - } - - if(XML_CheckNode_NameEqual("mesh")) { ParseNode_Mesh(); continue; } - if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } - MACRO_NODECHECK_LOOPEND("object"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else - - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. -} - -// -// -// Specify additional information about an entity. -// Multi elements - Yes. -// Parent element - , , , , . -// -// Reserved types are: -// "Name" - The alphanumeric label of the entity, to be used by the interpreter if interacting with the user. -// "Description" - A description of the content of the entity -// "URL" - A link to an external resource relating to the entity -// "Author" - Specifies the name(s) of the author(s) of the entity -// "Company" - Specifying the company generating the entity -// "CAD" - specifies the name of the originating CAD software and version -// "Revision" - specifies the revision of the entity -// "Tolerance" - specifies the desired manufacturing tolerance of the entity in entity's unit system -// "Volume" - specifies the total volume of the entity, in the entity's unit system, to be used for verification (object and volume only) -void AMFImporter::ParseNode_Metadata() -{ - std::string type, value; - CAMFImporter_NodeElement* ne( nullptr ); - - // read attribute - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue); - MACRO_ATTRREAD_LOOPEND; - // and value of node. - value = mReader->getNodeData(); - // Create node element and assign read data. - ne = new CAMFImporter_NodeElement_Metadata(mNodeElement_Cur); - ((CAMFImporter_NodeElement_Metadata*)ne)->Type = type; - ((CAMFImporter_NodeElement_Metadata*)ne)->Value = value; - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. -} - -/*********************************************************************************************************************************************/ -/******************************************************** Functions: BaseImporter set ********************************************************/ -/*********************************************************************************************************************************************/ - -bool AMFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const -{ - const std::string extension = GetExtension(pFile); - - if ( extension == "amf" ) { - return true; - } - - if(!extension.length() || pCheckSig) - { - const char* tokens[] = { "& pExtensionList) -{ - pExtensionList.insert("amf"); -} - -const aiImporterDesc* AMFImporter::GetInfo () const -{ - return &Description; -} - -void AMFImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) -{ - Clear();// delete old graph. - ParseFile(pFile, pIOHandler); - Postprocess_BuildScene(pScene); - // scene graph is ready, exit. -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER diff --git a/Engine/lib/assimp/code/AMF/AMFImporter.hpp b/Engine/lib/assimp/code/AMF/AMFImporter.hpp deleted file mode 100644 index 2b8086a06..000000000 --- a/Engine/lib/assimp/code/AMF/AMFImporter.hpp +++ /dev/null @@ -1,432 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/// \file AMFImporter.hpp -/// \brief AMF-format files importer for Assimp. -/// \date 2016 -/// \author smal.root@gmail.com -// Thanks to acorn89 for support. - -#pragma once -#ifndef INCLUDED_AI_AMF_IMPORTER_H -#define INCLUDED_AI_AMF_IMPORTER_H - -#include "AMFImporter_Node.hpp" - -// Header files, Assimp. -#include -#include -#include "assimp/types.h" -#include -#include - -// Header files, stdlib. -#include - -namespace Assimp { - -/// \class AMFImporter -/// Class that holding scene graph which include: geometry, metadata, materials etc. -/// -/// Implementing features. -/// -/// Limitations. -/// -/// 1. When for texture mapping used set of source textures (r, g, b, a) not only one then attribute "tiled" for all set will be true if it true in any of -/// source textures. -/// Example. Triangle use for texture mapping three textures. Two of them has "tiled" set to false and one - set to true. In scene all three textures -/// will be tiled. -/// -/// Unsupported features: -/// 1. Node , formulas in and . For implementing this feature can be used expression parser "muParser" like in project -/// "amf_tools". -/// 2. Attribute "profile" in node . -/// 3. Curved geometry: , and children nodes of them. -/// 4. Attributes: "unit" and "version" in read but do nothing. -/// 5. stored only for root node . -/// 6. Color averaging of vertices for which 's set different colors. -/// -/// Supported nodes: -/// General: -/// ; ; and children , , , , , ; ; -/// -/// Geometry: -/// ; ; ; ; and children , , ; ; and children , , ; -/// -/// Material: -/// and children , , , ; ; ; -/// two variants of texture coordinates: -/// new - and children , , , , , -/// old - and children , , , , , -/// -class AMFImporter : public BaseImporter { -private: - struct SPP_Material;// forward declaration - - /// \struct SPP_Composite - /// Data type for post-processing step. More suitable container for part of material's composition. - struct SPP_Composite { - SPP_Material* Material;///< Pointer to material - part of composition. - std::string Formula;///< Formula for calculating ratio of \ref Material. - }; - - /// \struct SPP_Material - /// Data type for post-processing step. More suitable container for material. - struct SPP_Material { - std::string ID;///< Material ID. - std::list Metadata;///< Metadata of material. - CAMFImporter_NodeElement_Color* Color;///< Color of material. - std::list Composition;///< List of child materials if current material is composition of few another. - - /// Return color calculated for specified coordinate. - /// \param [in] pX - "x" coordinate. - /// \param [in] pY - "y" coordinate. - /// \param [in] pZ - "z" coordinate. - /// \return calculated color. - aiColor4D GetColor(const float pX, const float pY, const float pZ) const; - }; - - /// Data type for post-processing step. More suitable container for texture. - struct SPP_Texture { - std::string ID; - size_t Width, Height, Depth; - bool Tiled; - char FormatHint[9];// 8 for string + 1 for terminator. - uint8_t *Data; - }; - - /// Data type for post-processing step. Contain face data. - struct SComplexFace { - aiFace Face;///< Face vertices. - const CAMFImporter_NodeElement_Color* Color;///< Face color. Equal to nullptr if color is not set for the face. - const CAMFImporter_NodeElement_TexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face. - }; - - /// Clear all temporary data. - void Clear(); - - /***********************************************/ - /************* Functions: find set *************/ - /***********************************************/ - - /// Find specified node element in node elements list ( \ref mNodeElement_List). - /// \param [in] pID - ID(name) of requested node element. - /// \param [in] pType - type of node element. - /// \param [out] pNode - pointer to pointer to item found. - /// \return true - if the node element is found, else - false. - bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const; - - /// Find requested aiNode in node list. - /// \param [in] pID - ID(name) of requested node. - /// \param [in] pNodeList - list of nodes where to find the node. - /// \param [out] pNode - pointer to pointer to item found. - /// \return true - if the node is found, else - false. - bool Find_ConvertedNode(const std::string& pID, std::list& pNodeList, aiNode** pNode) const; - - /// Find material in list for converted materials. Use at postprocessing step. - /// \param [in] pID - material ID. - /// \param [out] pConvertedMaterial - pointer to found converted material (\ref SPP_Material). - /// \return true - if the material is found, else - false. - bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const; - - /// Find texture in list of converted textures. Use at postprocessing step, - /// \param [in] pID_R - ID of source "red" texture. - /// \param [in] pID_G - ID of source "green" texture. - /// \param [in] pID_B - ID of source "blue" texture. - /// \param [in] pID_A - ID of source "alpha" texture. Use empty string to find RGB-texture. - /// \param [out] pConvertedTextureIndex - pointer where index in list of found texture will be written. If equivalent to nullptr then nothing will be - /// written. - /// \return true - if the texture is found, else - false. - bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A, - uint32_t* pConvertedTextureIndex = nullptr) const; - - - /// Get data stored in and place it to arrays. - /// \param [in] pNodeElement - reference to node element which kept data. - /// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in . - /// \param [in] pVertexColorArray - reference to vertices colors for all & pVertexCoordinateArray, - std::vector& pVertexColorArray) const; - - /// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new - /// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it - /// to converted textures list. - /// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified. - /// \param [in] pID_R - ID of source "red" texture. - /// \param [in] pID_G - ID of source "green" texture. - /// \param [in] pID_B - ID of source "blue" texture. - /// \param [in] pID_A - ID of source "alpha" texture. - /// \return index of the texture in array of the converted textures. - size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A); - - /// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc). - /// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after - /// processing. - /// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing. - void PostprocessHelper_SplitFacesByTextureID(std::list& pInputList, std::list >& pOutputList_Separated); - - /// Check if child elements of node element is metadata and add it to scene node. - /// \param [in] pMetadataList - reference to list with collected metadata. - /// \param [out] pSceneNode - scene node in which metadata will be added. - void Postprocess_AddMetadata(const std::list& pMetadataList, aiNode& pSceneNode) const; - - /// To create aiMesh and aiNode for it from . - /// \param [in] pNodeElement - reference to node element which kept data. - /// \param [out] pMeshList - reference to a list with all aiMesh of the scene. - /// \param [out] pSceneNode - pointer to place where new aiNode will be created. - void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list& pMeshList, aiNode** pSceneNode); - - /// Create mesh for every in . - /// \param [in] pNodeElement - reference to node element which kept data. - /// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all 's. - /// \param [in] pVertexColorArray - reference to vertices colors for all 's. If color for vertex is not set then corresponding member of array - /// contain nullptr. - /// \param [in] pObjectColor - pointer to colors for . If color is not set then argument contain nullptr. - /// \param [in] pMaterialList - reference to a list with defined materials. - /// \param [out] pMeshList - reference to a list with all aiMesh of the scene. - /// \param [out] pSceneNode - reference to aiNode which will own new aiMesh's. - void Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector& pVertexCoordinateArray, - const std::vector& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor, - std::list& pMeshList, aiNode& pSceneNode); - - /// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material. - /// \param [in] pMaterial - source CAMFImporter_NodeElement_Material. - void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial); - - /// Create and add to aiNode's list new part of scene graph defined by . - /// \param [in] pConstellation - reference to node. - /// \param [out] pNodeList - reference to aiNode's list. - void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list& pNodeList) const; - - /// Build Assimp scene graph in aiScene from collected data. - /// \param [out] pScene - pointer to aiScene where tree will be built. - void Postprocess_BuildScene(aiScene* pScene); - - - /// Call that function when close tag of node not found and exception must be raised. - /// E.g.: - /// - /// - /// - /// \throw DeadlyImportError. - /// \param [in] pNode - node name in which exception happened. - void Throw_CloseNotFound(const std::string& pNode); - - /// Call that function when attribute name is incorrect and exception must be raised. - /// \param [in] pAttrName - attribute name. - /// \throw DeadlyImportError. - void Throw_IncorrectAttr(const std::string& pAttrName); - - /// Call that function when attribute value is incorrect and exception must be raised. - /// \param [in] pAttrName - attribute name. - /// \throw DeadlyImportError. - void Throw_IncorrectAttrValue(const std::string& pAttrName); - - /// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised. - /// E.g.: - /// - /// ... - /// ... - /// - /// \throw DeadlyImportError. - /// \param [in] pNodeType - type of node which defined one more time. - /// \param [in] pDescription - message about error. E.g. what the node defined while exception raised. - void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription); - - /// Call that function when referenced element ID are not found in graph and exception must be raised. - /// \param [in] pID - ID of of element which not found. - /// \throw DeadlyImportError. - void Throw_ID_NotFound(const std::string& pID) const; - - /// Check if current node have children: .... If not then exception will throwed. - void XML_CheckNode_MustHaveChildren(); - - /// Check if current node name is equal to pNodeName. - /// \param [in] pNodeName - name for checking. - /// return true if current node name is equal to pNodeName, else - false. - bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; } - - /// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node. - /// \param [in] pParentNodeName - parent node name. Used for reporting. - void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName); - - /// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end. - /// \param [in] pNodeName - requested node name. - /// return true - if node is found, else - false. - bool XML_SearchNode(const std::string& pNodeName); - - /// Read attribute value. - /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). - /// \return read data. - bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx); - - /// Read attribute value. - /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). - /// \return read data. - float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx); - - /// Read attribute value. - /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). - /// \return read data. - uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx); - - /// Read node value. - /// \return read data. - float XML_ReadNode_GetVal_AsFloat(); - - /// Read node value. - /// \return read data. - uint32_t XML_ReadNode_GetVal_AsU32(); - - /// Read node value. - /// \return read data. - void XML_ReadNode_GetVal_AsString(std::string& pValue); - - /// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called. - /// \param [in] pNode - new current node. - void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode); - - /// This function must be called when exiting from grouping node. \ref ParseHelper_Group_Begin. - void ParseHelper_Node_Exit(); - - /// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it - /// must be converted to right form - "0.xxx". - /// \param [in] pInStr - pointer to input string which can contain incorrect form of values. - /// \param [out[ pOutString - output string with right form of values. - void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString); - - /// Decode Base64-encoded data. - /// \param [in] pInputBase64 - reference to input Base64-encoded string. - /// \param [out] pOutputData - reference to output array for decoded data. - void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector& pOutputData) const; - - /// Parse node of the file. - void ParseNode_Root(); - - /// Parse node of the file. - void ParseNode_Constellation(); - - /// Parse node of the file. - void ParseNode_Instance(); - - /// Parse node of the file. - void ParseNode_Material(); - - /// Parse node. - void ParseNode_Metadata(); - - /// Parse node of the file. - void ParseNode_Object(); - - /// Parse node of the file. - void ParseNode_Texture(); - - /// Parse node of the file. - void ParseNode_Coordinates(); - - /// Parse node of the file. - void ParseNode_Edge(); - - /// Parse node of the file. - void ParseNode_Mesh(); - - /// Parse node of the file. - void ParseNode_Triangle(); - - /// Parse node of the file. - void ParseNode_Vertex(); - - /// Parse node of the file. - void ParseNode_Vertices(); - - /// Parse node of the file. - void ParseNode_Volume(); - - /// Parse node of the file. - void ParseNode_Color(); - - /// Parse of node of the file. - /// \param [in] pUseOldName - if true then use old name of node(and children) - , instead of new name - . - void ParseNode_TexMap(const bool pUseOldName = false); - -public: - /// Default constructor. - AMFImporter() AI_NO_EXCEPT - : mNodeElement_Cur(nullptr) - , mReader(nullptr) { - // empty - } - - /// Default destructor. - ~AMFImporter(); - - /// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph. - /// Also exception can be thrown if trouble will found. - /// \param [in] pFile - name of file to be parsed. - /// \param [in] pIOHandler - pointer to IO helper object. - void ParseFile(const std::string& pFile, IOSystem* pIOHandler); - - bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const; - void GetExtensionList(std::set& pExtensionList); - void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); - const aiImporterDesc* GetInfo ()const; - - AMFImporter(const AMFImporter& pScene) = delete; - AMFImporter& operator=(const AMFImporter& pScene) = delete; - -private: - static const aiImporterDesc Description; - - CAMFImporter_NodeElement* mNodeElement_Cur;///< Current element. - std::list mNodeElement_List;///< All elements of scene graph. - irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object - std::string mUnit; - std::list mMaterial_Converted;///< List of converted materials for postprocessing step. - std::list mTexture_Converted;///< List of converted textures for postprocessing step. - -}; - -}// namespace Assimp - -#endif // INCLUDED_AI_AMF_IMPORTER_H diff --git a/Engine/lib/assimp/code/AMF/AMFImporter_Geometry.cpp b/Engine/lib/assimp/code/AMF/AMFImporter_Geometry.cpp deleted file mode 100644 index f1538e3fb..000000000 --- a/Engine/lib/assimp/code/AMF/AMFImporter_Geometry.cpp +++ /dev/null @@ -1,357 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/// \file AMFImporter_Geometry.cpp -/// \brief Parsing data from geometry nodes. -/// \date 2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER - -#include "AMFImporter.hpp" -#include "AMFImporter_Macro.hpp" - -namespace Assimp -{ - -// -// -// A 3D mesh hull. -// Multi elements - Yes. -// Parent element - . -void AMFImporter::ParseNode_Mesh() -{ -CAMFImporter_NodeElement* ne; - - // create new mesh object. - ne = new CAMFImporter_NodeElement_Mesh(mNodeElement_Cur); - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool vert_read = false; - - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("mesh"); - if(XML_CheckNode_NameEqual("vertices")) - { - // Check if data already defined. - if(vert_read) Throw_MoreThanOnceDefined("vertices", "Only one vertices set can be defined for ."); - // read data and set flag about it - ParseNode_Vertices(); - vert_read = true; - - continue; - } - - if(XML_CheckNode_NameEqual("volume")) { ParseNode_Volume(); continue; } - MACRO_NODECHECK_LOOPEND("mesh"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else - - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. -} - -// -// -// The list of vertices to be used in defining triangles. -// Multi elements - No. -// Parent element - . -void AMFImporter::ParseNode_Vertices() -{ -CAMFImporter_NodeElement* ne; - - // create new mesh object. - ne = new CAMFImporter_NodeElement_Vertices(mNodeElement_Cur); - // Check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("vertices"); - if(XML_CheckNode_NameEqual("vertex")) { ParseNode_Vertex(); continue; } - MACRO_NODECHECK_LOOPEND("vertices"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else - - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. -} - -// -// -// A vertex to be referenced in triangles. -// Multi elements - Yes. -// Parent element - . -void AMFImporter::ParseNode_Vertex() -{ -CAMFImporter_NodeElement* ne; - - // create new mesh object. - ne = new CAMFImporter_NodeElement_Vertex(mNodeElement_Cur); - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool col_read = false; - bool coord_read = false; - - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("vertex"); - if(XML_CheckNode_NameEqual("color")) - { - // Check if data already defined. - if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); - // read data and set flag about it - ParseNode_Color(); - col_read = true; - - continue; - } - - if(XML_CheckNode_NameEqual("coordinates")) - { - // Check if data already defined. - if(coord_read) Throw_MoreThanOnceDefined("coordinates", "Only one coordinates set can be defined for ."); - // read data and set flag about it - ParseNode_Coordinates(); - coord_read = true; - - continue; - } - - if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } - MACRO_NODECHECK_LOOPEND("vertex"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else - - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. -} - -// -// -// Specifies the 3D location of this vertex. -// Multi elements - No. -// Parent element - . -// -// Children elements: -// , , -// Multi elements - No. -// X, Y, or Z coordinate, respectively, of a vertex position in space. -void AMFImporter::ParseNode_Coordinates() -{ -CAMFImporter_NodeElement* ne; - - // create new color object. - ne = new CAMFImporter_NodeElement_Coordinates(mNodeElement_Cur); - - CAMFImporter_NodeElement_Coordinates& als = *((CAMFImporter_NodeElement_Coordinates*)ne);// alias for convenience - - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool read_flag[3] = { false, false, false }; - - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("coordinates"); - MACRO_NODECHECK_READCOMP_F("x", read_flag[0], als.Coordinate.x); - MACRO_NODECHECK_READCOMP_F("y", read_flag[1], als.Coordinate.y); - MACRO_NODECHECK_READCOMP_F("z", read_flag[2], als.Coordinate.z); - MACRO_NODECHECK_LOOPEND("coordinates"); - ParseHelper_Node_Exit(); - // check that all components was defined - if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all coordinate's components are defined."); - - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else - - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. -} - -// -// -// Defines a volume from the established vertex list. -// Multi elements - Yes. -// Parent element - . -void AMFImporter::ParseNode_Volume() -{ -std::string materialid; -std::string type; -CAMFImporter_NodeElement* ne; - - // Read attributes for node . - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECK_RET("materialid", materialid, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue); - MACRO_ATTRREAD_LOOPEND; - - // create new object. - ne = new CAMFImporter_NodeElement_Volume(mNodeElement_Cur); - // and assign read data - ((CAMFImporter_NodeElement_Volume*)ne)->MaterialID = materialid; - ((CAMFImporter_NodeElement_Volume*)ne)->Type = type; - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool col_read = false; - - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("volume"); - if(XML_CheckNode_NameEqual("color")) - { - // Check if data already defined. - if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); - // read data and set flag about it - ParseNode_Color(); - col_read = true; - - continue; - } - - if(XML_CheckNode_NameEqual("triangle")) { ParseNode_Triangle(); continue; } - if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } - MACRO_NODECHECK_LOOPEND("volume"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else - - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. -} - -// -// -// Defines a 3D triangle from three vertices, according to the right-hand rule (counter-clockwise when looking from the outside). -// Multi elements - Yes. -// Parent element - . -// -// Children elements: -// , , -// Multi elements - No. -// Index of the desired vertices in a triangle or edge. -void AMFImporter::ParseNode_Triangle() -{ -CAMFImporter_NodeElement* ne; - - // create new color object. - ne = new CAMFImporter_NodeElement_Triangle(mNodeElement_Cur); - - CAMFImporter_NodeElement_Triangle& als = *((CAMFImporter_NodeElement_Triangle*)ne);// alias for convenience - - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool col_read = false, tex_read = false; - bool read_flag[3] = { false, false, false }; - - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("triangle"); - if(XML_CheckNode_NameEqual("color")) - { - // Check if data already defined. - if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); - // read data and set flag about it - ParseNode_Color(); - col_read = true; - - continue; - } - - if(XML_CheckNode_NameEqual("texmap"))// new name of node: "texmap". - { - // Check if data already defined. - if(tex_read) Throw_MoreThanOnceDefined("texmap", "Only one texture coordinate can be defined for ."); - // read data and set flag about it - ParseNode_TexMap(); - tex_read = true; - - continue; - } - else if(XML_CheckNode_NameEqual("map"))// old name of node: "map". - { - // Check if data already defined. - if(tex_read) Throw_MoreThanOnceDefined("map", "Only one texture coordinate can be defined for ."); - // read data and set flag about it - ParseNode_TexMap(true); - tex_read = true; - - continue; - } - - MACRO_NODECHECK_READCOMP_U32("v1", read_flag[0], als.V[0]); - MACRO_NODECHECK_READCOMP_U32("v2", read_flag[1], als.V[1]); - MACRO_NODECHECK_READCOMP_U32("v3", read_flag[2], als.V[2]); - MACRO_NODECHECK_LOOPEND("triangle"); - ParseHelper_Node_Exit(); - // check that all components was defined - if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all vertices of the triangle are defined."); - - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else - - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER diff --git a/Engine/lib/assimp/code/AMF/AMFImporter_Macro.hpp b/Engine/lib/assimp/code/AMF/AMFImporter_Macro.hpp deleted file mode 100644 index f60c5fbbb..000000000 --- a/Engine/lib/assimp/code/AMF/AMFImporter_Macro.hpp +++ /dev/null @@ -1,166 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/// \file AMFImporter_Macro.hpp -/// \brief Useful macrodefines. -/// \date 2016 -/// \author smal.root@gmail.com - -#pragma once -#ifndef AMFIMPORTER_MACRO_HPP_INCLUDED -#define AMFIMPORTER_MACRO_HPP_INCLUDED - -/// \def MACRO_ATTRREAD_LOOPBEG -/// Begin of loop that read attributes values. -#define MACRO_ATTRREAD_LOOPBEG \ - for(int idx = 0, idx_end = mReader->getAttributeCount(); idx < idx_end; idx++) \ - { \ - std::string an(mReader->getAttributeName(idx)); - -/// \def MACRO_ATTRREAD_LOOPEND -/// End of loop that read attributes values. -#define MACRO_ATTRREAD_LOOPEND \ - Throw_IncorrectAttr(an); \ - } - -/// \def MACRO_ATTRREAD_LOOPEND_WSKIP -/// End of loop that read attributes values. Difference from \ref MACRO_ATTRREAD_LOOPEND in that: current macro skip unknown attributes, but -/// \ref MACRO_ATTRREAD_LOOPEND throw an exception. -#define MACRO_ATTRREAD_LOOPEND_WSKIP \ - continue; \ - } - -/// \def MACRO_ATTRREAD_CHECK_REF -/// Check current attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then -/// "continue" will called. -/// \param [in] pAttrName - attribute name. -/// \param [out] pVarName - output variable name. -/// \param [in] pFunction - function which read attribute value and write it to pVarName. -#define MACRO_ATTRREAD_CHECK_REF(pAttrName, pVarName, pFunction) \ - if(an == pAttrName) \ - { \ - pFunction(idx, pVarName); \ - continue; \ - } - -/// \def MACRO_ATTRREAD_CHECK_RET -/// Check current attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction. -/// If result was read then "continue" will called. -/// \param [in] pAttrName - attribute name. -/// \param [out] pVarName - output variable name. -/// \param [in] pFunction - function which read attribute value and write it to pVarName. -#define MACRO_ATTRREAD_CHECK_RET(pAttrName, pVarName, pFunction) \ - if(an == pAttrName) \ - { \ - pVarName = pFunction(idx); \ - continue; \ - } - -/// \def MACRO_NODECHECK_LOOPBEGIN(pNodeName) -/// Begin of loop of parsing child nodes. Do not add ';' at end. -/// \param [in] pNodeName - current node name. -#define MACRO_NODECHECK_LOOPBEGIN(pNodeName) \ - do { \ - bool close_found = false; \ - \ - while(mReader->read()) \ - { \ - if(mReader->getNodeType() == irr::io::EXN_ELEMENT) \ - { - -/// \def MACRO_NODECHECK_LOOPEND(pNodeName) -/// End of loop of parsing child nodes. -/// \param [in] pNodeName - current node name. -#define MACRO_NODECHECK_LOOPEND(pNodeName) \ - XML_CheckNode_SkipUnsupported(pNodeName); \ - }/* if(mReader->getNodeType() == irr::io::EXN_ELEMENT) */ \ - else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) \ - { \ - if(XML_CheckNode_NameEqual(pNodeName)) \ - { \ - close_found = true; \ - \ - break; \ - } \ - }/* else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) */ \ - }/* while(mReader->read()) */ \ - \ - if(!close_found) Throw_CloseNotFound(pNodeName); \ - \ - } while(false) - -/// \def MACRO_NODECHECK_READCOMP_F -/// Check current node name and if it equal to requested then read value. Result write to output variable of type "float". -/// If result was read then "continue" will called. Also check if node data already read then raise exception. -/// \param [in] pNodeName - node name. -/// \param [in, out] pReadFlag - read flag. -/// \param [out] pVarName - output variable name. -#define MACRO_NODECHECK_READCOMP_F(pNodeName, pReadFlag, pVarName) \ - if(XML_CheckNode_NameEqual(pNodeName)) \ - { \ - /* Check if field already read before. */ \ - if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \ - /* Read color component and assign it to object. */ \ - pVarName = XML_ReadNode_GetVal_AsFloat(); \ - pReadFlag = true; \ - continue; \ - } - -/// \def MACRO_NODECHECK_READCOMP_U32 -/// Check current node name and if it equal to requested then read value. Result write to output variable of type "uint32_t". -/// If result was read then "continue" will called. Also check if node data already read then raise exception. -/// \param [in] pNodeName - node name. -/// \param [in, out] pReadFlag - read flag. -/// \param [out] pVarName - output variable name. -#define MACRO_NODECHECK_READCOMP_U32(pNodeName, pReadFlag, pVarName) \ - if(XML_CheckNode_NameEqual(pNodeName)) \ - { \ - /* Check if field already read before. */ \ - if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \ - /* Read color component and assign it to object. */ \ - pVarName = XML_ReadNode_GetVal_AsU32(); \ - pReadFlag = true; \ - continue; \ - } - -#endif // AMFIMPORTER_MACRO_HPP_INCLUDED diff --git a/Engine/lib/assimp/code/AMF/AMFImporter_Node.hpp b/Engine/lib/assimp/code/AMF/AMFImporter_Node.hpp deleted file mode 100644 index a1bf9f008..000000000 --- a/Engine/lib/assimp/code/AMF/AMFImporter_Node.hpp +++ /dev/null @@ -1,340 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/// \file AMFImporter_Node.hpp -/// \brief Elements of scene graph. -/// \date 2016 -/// \author smal.root@gmail.com - -#pragma once -#ifndef INCLUDED_AI_AMF_IMPORTER_NODE_H -#define INCLUDED_AI_AMF_IMPORTER_NODE_H - -// Header files, stdlib. -#include -#include -#include - -// Header files, Assimp. -#include "assimp/types.h" -#include "assimp/scene.h" - -/// \class CAMFImporter_NodeElement -/// Base class for elements of nodes. -class CAMFImporter_NodeElement { -public: - /// Define what data type contain node element. - enum EType { - ENET_Color, ///< Color element: . - ENET_Constellation,///< Grouping element: . - ENET_Coordinates, ///< Coordinates element: . - ENET_Edge, ///< Edge element: . - ENET_Instance, ///< Grouping element: . - ENET_Material, ///< Material element: . - ENET_Metadata, ///< Metadata element: . - ENET_Mesh, ///< Metadata element: . - ENET_Object, ///< Element which hold object: . - ENET_Root, ///< Root element: . - ENET_Triangle, ///< Triangle element: . - ENET_TexMap, ///< Texture coordinates element: or . - ENET_Texture, ///< Texture element: . - ENET_Vertex, ///< Vertex element: . - ENET_Vertices, ///< Vertex element: . - ENET_Volume, ///< Volume element: . - - ENET_Invalid ///< Element has invalid type and possible contain invalid data. - }; - - const EType Type;///< Type of element. - std::string ID;///< ID of element. - CAMFImporter_NodeElement* Parent;///< Parent element. If nullptr then this node is root. - std::list Child;///< Child elements. - -public: /// Destructor, virtual.. - virtual ~CAMFImporter_NodeElement() { - // empty - } - - /// Disabled copy constructor and co. - CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement) = delete; - CAMFImporter_NodeElement(CAMFImporter_NodeElement&&) = delete; - CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement) = delete; - CAMFImporter_NodeElement() = delete; - -protected: - /// In constructor inheritor must set element type. - /// \param [in] pType - element type. - /// \param [in] pParent - parent element. - CAMFImporter_NodeElement(const EType pType, CAMFImporter_NodeElement* pParent) - : Type(pType) - , ID() - , Parent(pParent) - , Child() { - // empty - } -};// class IAMFImporter_NodeElement - -/// \struct CAMFImporter_NodeElement_Constellation -/// A collection of objects or constellations with specific relative locations. -struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement { - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Constellation, pParent) - {} - -};// struct CAMFImporter_NodeElement_Constellation - -/// \struct CAMFImporter_NodeElement_Instance -/// Part of constellation. -struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement { - - std::string ObjectID;///< ID of object for instantiation. - /// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to - /// create an instance of the object in the current constellation. - aiVector3D Delta; - - /// \var Rotation - The rotation, in degrees, to rotate the referenced object about its x, y, and z axes, respectively, to create an - /// instance of the object in the current constellation. Rotations shall be executed in order of x first, then y, then z. - aiVector3D Rotation; - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Instance, pParent) - {} -}; - -/// \struct CAMFImporter_NodeElement_Metadata -/// Structure that define metadata node. -struct CAMFImporter_NodeElement_Metadata : public CAMFImporter_NodeElement { - - std::string Type;///< Type of "Value". - std::string Value;///< Value. - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Metadata, pParent) - {} -}; - -/// \struct CAMFImporter_NodeElement_Root -/// Structure that define root node. -struct CAMFImporter_NodeElement_Root : public CAMFImporter_NodeElement { - - std::string Unit;///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron". - std::string Version;///< Version of format. - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Root, pParent) - {} -}; - -/// \struct CAMFImporter_NodeElement_Color -/// Structure that define object node. -struct CAMFImporter_NodeElement_Color : public CAMFImporter_NodeElement { - bool Composed; ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color. - std::string Color_Composed[4]; ///< By components formulas of composed color. [0..3] - RGBA. - aiColor4D Color; ///< Constant color. - std::string Profile; ///< The ICC color space used to interpret the three color channels r, g and b.. - - /// @brief Constructor. - /// @param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Color, pParent) - , Composed( false ) - , Color() - , Profile() { - // empty - } -}; - -/// \struct CAMFImporter_NodeElement_Material -/// Structure that define material node. -struct CAMFImporter_NodeElement_Material : public CAMFImporter_NodeElement { - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Material, pParent) - {} - -}; - -/// \struct CAMFImporter_NodeElement_Object -/// Structure that define object node. -struct CAMFImporter_NodeElement_Object : public CAMFImporter_NodeElement { - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Object, pParent) - {} -}; - -/// \struct CAMFImporter_NodeElement_Mesh -/// Structure that define mesh node. -struct CAMFImporter_NodeElement_Mesh : public CAMFImporter_NodeElement { - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Mesh, pParent) - {} -}; - -/// \struct CAMFImporter_NodeElement_Vertex -/// Structure that define vertex node. -struct CAMFImporter_NodeElement_Vertex : public CAMFImporter_NodeElement { - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Vertex, pParent) - {} -}; - -/// \struct CAMFImporter_NodeElement_Edge -/// Structure that define edge node. -struct CAMFImporter_NodeElement_Edge : public CAMFImporter_NodeElement { - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Edge, pParent) - {} - -}; - -/// \struct CAMFImporter_NodeElement_Vertices -/// Structure that define vertices node. -struct CAMFImporter_NodeElement_Vertices : public CAMFImporter_NodeElement { - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Vertices, pParent) - {} -}; - -/// \struct CAMFImporter_NodeElement_Volume -/// Structure that define volume node. -struct CAMFImporter_NodeElement_Volume : public CAMFImporter_NodeElement { - std::string MaterialID;///< Which material to use. - std::string Type;///< What this volume describes can be “region†or “supportâ€. If none specified, “object†is assumed. - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Volume, pParent) - {} -}; - -/// \struct CAMFImporter_NodeElement_Coordinates -/// Structure that define coordinates node. -struct CAMFImporter_NodeElement_Coordinates : public CAMFImporter_NodeElement -{ - aiVector3D Coordinate;///< Coordinate. - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Coordinates, pParent) - {} - -}; - -/// \struct CAMFImporter_NodeElement_TexMap -/// Structure that define texture coordinates node. -struct CAMFImporter_NodeElement_TexMap : public CAMFImporter_NodeElement { - aiVector3D TextureCoordinate[3];///< Texture coordinates. - std::string TextureID_R;///< Texture ID for red color component. - std::string TextureID_G;///< Texture ID for green color component. - std::string TextureID_B;///< Texture ID for blue color component. - std::string TextureID_A;///< Texture ID for alpha color component. - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_TexMap, pParent) - , TextureCoordinate{} - , TextureID_R() - , TextureID_G() - , TextureID_B() - , TextureID_A() { - // empty - } -}; - -/// \struct CAMFImporter_NodeElement_Triangle -/// Structure that define triangle node. -struct CAMFImporter_NodeElement_Triangle : public CAMFImporter_NodeElement { - size_t V[3];///< Triangle vertices. - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Triangle, pParent) { - // empty - } -}; - -/// Structure that define texture node. -struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement { - size_t Width, Height, Depth;///< Size of the texture. - std::vector Data;///< Data of the texture. - bool Tiled; - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - CAMFImporter_NodeElement_Texture(CAMFImporter_NodeElement* pParent) - : CAMFImporter_NodeElement(ENET_Texture, pParent) - , Width( 0 ) - , Height( 0 ) - , Depth( 0 ) - , Data() - , Tiled( false ){ - // empty - } -}; - -#endif // INCLUDED_AI_AMF_IMPORTER_NODE_H diff --git a/Engine/lib/assimp/code/AMF/AMFImporter_Postprocess.cpp b/Engine/lib/assimp/code/AMF/AMFImporter_Postprocess.cpp deleted file mode 100644 index 79b5e15e2..000000000 --- a/Engine/lib/assimp/code/AMF/AMFImporter_Postprocess.cpp +++ /dev/null @@ -1,978 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/// \file AMFImporter_Postprocess.cpp -/// \brief Convert built scenegraph and objects to Assimp scenegraph. -/// \date 2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER - -#include "AMFImporter.hpp" - -// Header files, Assimp. -#include -#include -#include - -// Header files, stdlib. -#include - -namespace Assimp -{ - -aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*pY*/, const float /*pZ*/) const -{ - aiColor4D tcol; - - // Check if stored data are supported. - if(!Composition.empty()) - { - throw DeadlyImportError("IME. GetColor for composition"); - } - else if(Color->Composed) - { - throw DeadlyImportError("IME. GetColor, composed color"); - } - else - { - tcol = Color->Color; - } - - // Check if default color must be used - if((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) - { - tcol.r = 0.5f; - tcol.g = 0.5f; - tcol.b = 0.5f; - tcol.a = 1; - } - - return tcol; -} - -void AMFImporter::PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector& pVertexCoordinateArray, - std::vector& pVertexColorArray) const -{ - CAMFImporter_NodeElement_Vertices* vn = nullptr; - size_t col_idx; - - // All data stored in "vertices", search for it. - for(CAMFImporter_NodeElement* ne_child: pNodeElement.Child) - { - if(ne_child->Type == CAMFImporter_NodeElement::ENET_Vertices) vn = (CAMFImporter_NodeElement_Vertices*)ne_child; - } - - // If "vertices" not found then no work for us. - if(vn == nullptr) return; - - pVertexCoordinateArray.reserve(vn->Child.size());// all coordinates stored as child and we need to reserve space for future push_back's. - pVertexColorArray.resize(vn->Child.size());// colors count equal vertices count. - col_idx = 0; - // Inside vertices collect all data and place to arrays - for(CAMFImporter_NodeElement* vn_child: vn->Child) - { - // vertices, colors - if(vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex) - { - // by default clear color for current vertex - pVertexColorArray[col_idx] = nullptr; - - for(CAMFImporter_NodeElement* vtx: vn_child->Child) - { - if(vtx->Type == CAMFImporter_NodeElement::ENET_Coordinates) - { - pVertexCoordinateArray.push_back(((CAMFImporter_NodeElement_Coordinates*)vtx)->Coordinate); - - continue; - } - - if(vtx->Type == CAMFImporter_NodeElement::ENET_Color) - { - pVertexColorArray[col_idx] = (CAMFImporter_NodeElement_Color*)vtx; - - continue; - } - }// for(CAMFImporter_NodeElement* vtx: vn_child->Child) - - col_idx++; - }// if(vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex) - }// for(CAMFImporter_NodeElement* vn_child: vn->Child) -} - -size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, - const std::string& pID_A) -{ - size_t TextureConverted_Index; - std::string TextureConverted_ID; - - // check input data - if(pID_R.empty() && pID_G.empty() && pID_B.empty() && pID_A.empty()) - throw DeadlyImportError("PostprocessHelper_GetTextureID_Or_Create. At least one texture ID must be defined."); - - // Create ID - TextureConverted_ID = pID_R + "_" + pID_G + "_" + pID_B + "_" + pID_A; - // Check if texture specified by set of IDs is converted already. - TextureConverted_Index = 0; - for(const SPP_Texture& tex_convd: mTexture_Converted) - { - if ( tex_convd.ID == TextureConverted_ID ) { - return TextureConverted_Index; - } else { - ++TextureConverted_Index; - } - } - - // - // Converted texture not found, create it. - // - CAMFImporter_NodeElement_Texture* src_texture[4]{nullptr}; - std::vector src_texture_4check; - SPP_Texture converted_texture; - - {// find all specified source textures - CAMFImporter_NodeElement* t_tex; - - // R - if(!pID_R.empty()) - { - if(!Find_NodeElement(pID_R, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_R); - - src_texture[0] = (CAMFImporter_NodeElement_Texture*)t_tex; - src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex); - } - else - { - src_texture[0] = nullptr; - } - - // G - if(!pID_G.empty()) - { - if(!Find_NodeElement(pID_G, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_G); - - src_texture[1] = (CAMFImporter_NodeElement_Texture*)t_tex; - src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex); - } - else - { - src_texture[1] = nullptr; - } - - // B - if(!pID_B.empty()) - { - if(!Find_NodeElement(pID_B, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_B); - - src_texture[2] = (CAMFImporter_NodeElement_Texture*)t_tex; - src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex); - } - else - { - src_texture[2] = nullptr; - } - - // A - if(!pID_A.empty()) - { - if(!Find_NodeElement(pID_A, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_A); - - src_texture[3] = (CAMFImporter_NodeElement_Texture*)t_tex; - src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex); - } - else - { - src_texture[3] = nullptr; - } - }// END: find all specified source textures - - // check that all textures has same size - if(src_texture_4check.size() > 1) - { - for (size_t i = 0, i_e = (src_texture_4check.size() - 1); i < i_e; i++) - { - if((src_texture_4check[i]->Width != src_texture_4check[i + 1]->Width) || (src_texture_4check[i]->Height != src_texture_4check[i + 1]->Height) || - (src_texture_4check[i]->Depth != src_texture_4check[i + 1]->Depth)) - { - throw DeadlyImportError("PostprocessHelper_GetTextureID_Or_Create. Source texture must has the same size."); - } - } - }// if(src_texture_4check.size() > 1) - - // set texture attributes - converted_texture.Width = src_texture_4check[0]->Width; - converted_texture.Height = src_texture_4check[0]->Height; - converted_texture.Depth = src_texture_4check[0]->Depth; - // if one of source texture is tiled then converted texture is tiled too. - converted_texture.Tiled = false; - for(uint8_t i = 0; i < src_texture_4check.size(); i++) converted_texture.Tiled |= src_texture_4check[i]->Tiled; - - // Create format hint. - strcpy(converted_texture.FormatHint, "rgba0000");// copy initial string. - if(!pID_R.empty()) converted_texture.FormatHint[4] = '8'; - if(!pID_G.empty()) converted_texture.FormatHint[5] = '8'; - if(!pID_B.empty()) converted_texture.FormatHint[6] = '8'; - if(!pID_A.empty()) converted_texture.FormatHint[7] = '8'; - - // - // Сopy data of textures. - // - size_t tex_size = 0; - size_t step = 0; - size_t off_g = 0; - size_t off_b = 0; - - // Calculate size of the target array and rule how data will be copied. - if(!pID_R.empty() && nullptr != src_texture[ 0 ] ) { - tex_size += src_texture[0]->Data.size(); step++, off_g++, off_b++; - } - if(!pID_G.empty() && nullptr != src_texture[ 1 ] ) { - tex_size += src_texture[1]->Data.size(); step++, off_b++; - } - if(!pID_B.empty() && nullptr != src_texture[ 2 ] ) { - tex_size += src_texture[2]->Data.size(); step++; - } - if(!pID_A.empty() && nullptr != src_texture[ 3 ] ) { - tex_size += src_texture[3]->Data.size(); step++; - } - - // Create target array. - converted_texture.Data = new uint8_t[tex_size]; - // And copy data - auto CopyTextureData = [&](const std::string& pID, const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void - { - if(!pID.empty()) - { - for(size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++) { - CAMFImporter_NodeElement_Texture* tex = src_texture[pSrcTexNum]; - ai_assert(tex); - converted_texture.Data[idx_target] = tex->Data.at(idx_src); - } - } - };// auto CopyTextureData = [&](const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void - - CopyTextureData(pID_R, 0, step, 0); - CopyTextureData(pID_G, off_g, step, 1); - CopyTextureData(pID_B, off_b, step, 2); - CopyTextureData(pID_A, step - 1, step, 3); - - // Store new converted texture ID - converted_texture.ID = TextureConverted_ID; - // Store new converted texture - mTexture_Converted.push_back(converted_texture); - - return TextureConverted_Index; -} - -void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list& pInputList, std::list >& pOutputList_Separated) -{ - auto texmap_is_equal = [](const CAMFImporter_NodeElement_TexMap* pTexMap1, const CAMFImporter_NodeElement_TexMap* pTexMap2) -> bool - { - if((pTexMap1 == nullptr) && (pTexMap2 == nullptr)) return true; - if(pTexMap1 == nullptr) return false; - if(pTexMap2 == nullptr) return false; - - if(pTexMap1->TextureID_R != pTexMap2->TextureID_R) return false; - if(pTexMap1->TextureID_G != pTexMap2->TextureID_G) return false; - if(pTexMap1->TextureID_B != pTexMap2->TextureID_B) return false; - if(pTexMap1->TextureID_A != pTexMap2->TextureID_A) return false; - - return true; - }; - - pOutputList_Separated.clear(); - if(pInputList.empty()) return; - - do - { - SComplexFace face_start = pInputList.front(); - std::list face_list_cur; - - for(std::list::iterator it = pInputList.begin(), it_end = pInputList.end(); it != it_end;) - { - if(texmap_is_equal(face_start.TexMap, it->TexMap)) - { - auto it_old = it; - - ++it; - face_list_cur.push_back(*it_old); - pInputList.erase(it_old); - } - else - { - ++it; - } - } - - if(!face_list_cur.empty()) pOutputList_Separated.push_back(face_list_cur); - - } while(!pInputList.empty()); -} - -void AMFImporter::Postprocess_AddMetadata(const std::list& metadataList, aiNode& sceneNode) const -{ - if ( !metadataList.empty() ) - { - if(sceneNode.mMetaData != nullptr) throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong."); - - // copy collected metadata to output node. - sceneNode.mMetaData = aiMetadata::Alloc( static_cast(metadataList.size()) ); - size_t meta_idx( 0 ); - - for(const CAMFImporter_NodeElement_Metadata& metadata: metadataList) - { - sceneNode.mMetaData->Set(static_cast(meta_idx++), metadata.Type, aiString(metadata.Value)); - } - }// if(!metadataList.empty()) -} - -void AMFImporter::Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list& pMeshList, aiNode** pSceneNode) -{ -CAMFImporter_NodeElement_Color* object_color = nullptr; - - // create new aiNode and set name as has. - *pSceneNode = new aiNode; - (*pSceneNode)->mName = pNodeElement.ID; - // read mesh and color - for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child) - { - std::vector vertex_arr; - std::vector color_arr; - - // color for object - if(ne_child->Type == CAMFImporter_NodeElement::ENET_Color) object_color = (CAMFImporter_NodeElement_Color*)ne_child; - - if(ne_child->Type == CAMFImporter_NodeElement::ENET_Mesh) - { - // Create arrays from children of mesh: vertices. - PostprocessHelper_CreateMeshDataArray(*((CAMFImporter_NodeElement_Mesh*)ne_child), vertex_arr, color_arr); - // Use this arrays as a source when creating every aiMesh - Postprocess_BuildMeshSet(*((CAMFImporter_NodeElement_Mesh*)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode); - } - }// for(const CAMFImporter_NodeElement* ne_child: pNodeElement) -} - -void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector& pVertexCoordinateArray, - const std::vector& pVertexColorArray, - const CAMFImporter_NodeElement_Color* pObjectColor, std::list& pMeshList, aiNode& pSceneNode) -{ -std::list mesh_idx; - - // all data stored in "volume", search for it. - for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child) - { - const CAMFImporter_NodeElement_Color* ne_volume_color = nullptr; - const SPP_Material* cur_mat = nullptr; - - if(ne_child->Type == CAMFImporter_NodeElement::ENET_Volume) - { - /******************* Get faces *******************/ - const CAMFImporter_NodeElement_Volume* ne_volume = reinterpret_cast(ne_child); - - std::list complex_faces_list;// List of the faces of the volume. - std::list > complex_faces_toplist;// List of the face list for every mesh. - - // check if volume use material - if(!ne_volume->MaterialID.empty()) - { - if(!Find_ConvertedMaterial(ne_volume->MaterialID, &cur_mat)) Throw_ID_NotFound(ne_volume->MaterialID); - } - - // inside "volume" collect all data and place to arrays or create new objects - for(const CAMFImporter_NodeElement* ne_volume_child: ne_volume->Child) - { - // color for volume - if(ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Color) - { - ne_volume_color = reinterpret_cast(ne_volume_child); - } - else if(ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Triangle)// triangles, triangles colors - { - const CAMFImporter_NodeElement_Triangle& tri_al = *reinterpret_cast(ne_volume_child); - - SComplexFace complex_face; - - // initialize pointers - complex_face.Color = nullptr; - complex_face.TexMap = nullptr; - // get data from triangle children: color, texture coordinates. - if(tri_al.Child.size()) - { - for(const CAMFImporter_NodeElement* ne_triangle_child: tri_al.Child) - { - if(ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_Color) - complex_face.Color = reinterpret_cast(ne_triangle_child); - else if(ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_TexMap) - complex_face.TexMap = reinterpret_cast(ne_triangle_child); - } - }// if(tri_al.Child.size()) - - // create new face and store it. - complex_face.Face.mNumIndices = 3; - complex_face.Face.mIndices = new unsigned int[3]; - complex_face.Face.mIndices[0] = static_cast(tri_al.V[0]); - complex_face.Face.mIndices[1] = static_cast(tri_al.V[1]); - complex_face.Face.mIndices[2] = static_cast(tri_al.V[2]); - complex_faces_list.push_back(complex_face); - } - }// for(const CAMFImporter_NodeElement* ne_volume_child: ne_volume->Child) - - /**** Split faces list: one list per mesh ****/ - PostprocessHelper_SplitFacesByTextureID(complex_faces_list, complex_faces_toplist); - - /***** Create mesh for every faces list ******/ - for(std::list& face_list_cur: complex_faces_toplist) - { - auto VertexIndex_GetMinimal = [](const std::list& pFaceList, const size_t* pBiggerThan) -> size_t - { - size_t rv; - - if(pBiggerThan != nullptr) - { - bool found = false; - - for(const SComplexFace& face: pFaceList) - { - for(size_t idx_vert = 0; idx_vert < face.Face.mNumIndices; idx_vert++) - { - if(face.Face.mIndices[idx_vert] > *pBiggerThan) - { - rv = face.Face.mIndices[idx_vert]; - found = true; - - break; - } - } - - if(found) break; - } - - if(!found) return *pBiggerThan; - } - else - { - rv = pFaceList.front().Face.mIndices[0]; - }// if(pBiggerThan != nullptr) else - - for(const SComplexFace& face: pFaceList) - { - for(size_t vi = 0; vi < face.Face.mNumIndices; vi++) - { - if(face.Face.mIndices[vi] < rv) - { - if(pBiggerThan != nullptr) - { - if(face.Face.mIndices[vi] > *pBiggerThan) rv = face.Face.mIndices[vi]; - } - else - { - rv = face.Face.mIndices[vi]; - } - } - } - }// for(const SComplexFace& face: pFaceList) - - return rv; - };// auto VertexIndex_GetMinimal = [](const std::list& pFaceList, const size_t* pBiggerThan) -> size_t - - auto VertexIndex_Replace = [](std::list& pFaceList, const size_t pIdx_From, const size_t pIdx_To) -> void - { - for(const SComplexFace& face: pFaceList) - { - for(size_t vi = 0; vi < face.Face.mNumIndices; vi++) - { - if(face.Face.mIndices[vi] == pIdx_From) face.Face.mIndices[vi] = static_cast(pIdx_To); - } - } - };// auto VertexIndex_Replace = [](std::list& pFaceList, const size_t pIdx_From, const size_t pIdx_To) -> void - - auto Vertex_CalculateColor = [&](const size_t pIdx) -> aiColor4D - { - // Color priorities(In descending order): - // 1. triangle color; - // 2. vertex color; - // 3. volume color; - // 4. object color; - // 5. material; - // 6. default - invisible coat. - // - // Fill vertices colors in color priority list above that's points from 1 to 6. - if((pIdx < pVertexColorArray.size()) && (pVertexColorArray[pIdx] != nullptr))// check for vertex color - { - if(pVertexColorArray[pIdx]->Composed) - throw DeadlyImportError("IME: vertex color composed"); - else - return pVertexColorArray[pIdx]->Color; - } - else if(ne_volume_color != nullptr)// check for volume color - { - if(ne_volume_color->Composed) - throw DeadlyImportError("IME: volume color composed"); - else - return ne_volume_color->Color; - } - else if(pObjectColor != nullptr)// check for object color - { - if(pObjectColor->Composed) - throw DeadlyImportError("IME: object color composed"); - else - return pObjectColor->Color; - } - else if(cur_mat != nullptr)// check for material - { - return cur_mat->GetColor(pVertexCoordinateArray.at(pIdx).x, pVertexCoordinateArray.at(pIdx).y, pVertexCoordinateArray.at(pIdx).z); - } - else// set default color. - { - return {0, 0, 0, 0}; - }// if((vi < pVertexColorArray.size()) && (pVertexColorArray[vi] != nullptr)) else - - };// auto Vertex_CalculateColor = [&](const size_t pIdx) -> aiColor4D - - aiMesh* tmesh = new aiMesh; - - tmesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;// Only triangles is supported by AMF. - // - // set geometry and colors (vertices) - // - // copy faces/triangles - tmesh->mNumFaces = static_cast(face_list_cur.size()); - tmesh->mFaces = new aiFace[tmesh->mNumFaces]; - - // Create vertices list and optimize indices. Optimisation mean following.In AMF all volumes use one big list of vertices. And one volume - // can use only part of vertices list, for example: vertices list contain few thousands of vertices and volume use vertices 1, 3, 10. - // Do you need all this thousands of garbage? Of course no. So, optimisation step transformate sparse indices set to continuous. - size_t VertexCount_Max = tmesh->mNumFaces * 3;// 3 - triangles. - std::vector vert_arr, texcoord_arr; - std::vector col_arr; - - vert_arr.reserve(VertexCount_Max * 2);// "* 2" - see below TODO. - col_arr.reserve(VertexCount_Max * 2); - - {// fill arrays - size_t vert_idx_from, vert_idx_to; - - // first iteration. - vert_idx_to = 0; - vert_idx_from = VertexIndex_GetMinimal(face_list_cur, nullptr); - vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from)); - col_arr.push_back(Vertex_CalculateColor(vert_idx_from)); - if(vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to); - - // rest iterations - do - { - vert_idx_from = VertexIndex_GetMinimal(face_list_cur, &vert_idx_to); - if(vert_idx_from == vert_idx_to) break;// all indices are transferred, - - vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from)); - col_arr.push_back(Vertex_CalculateColor(vert_idx_from)); - vert_idx_to++; - if(vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to); - - } while(true); - }// fill arrays. END. - - // - // check if triangle colors are used and create additional faces if needed. - // - for(const SComplexFace& face_cur: face_list_cur) - { - if(face_cur.Color != nullptr) - { - aiColor4D face_color; - size_t vert_idx_new = vert_arr.size(); - - if(face_cur.Color->Composed) - throw DeadlyImportError("IME: face color composed"); - else - face_color = face_cur.Color->Color; - - for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++) - { - vert_arr.push_back(vert_arr.at(face_cur.Face.mIndices[idx_ind])); - col_arr.push_back(face_color); - face_cur.Face.mIndices[idx_ind] = static_cast(vert_idx_new++); - } - }// if(face_cur.Color != nullptr) - }// for(const SComplexFace& face_cur: face_list_cur) - - // - // if texture is used then copy texture coordinates too. - // - if(face_list_cur.front().TexMap != nullptr) - { - size_t idx_vert_new = vert_arr.size(); - ///TODO: clean unused vertices. "* 2": in certain cases - mesh full of triangle colors - vert_arr will contain duplicated vertices for - /// colored triangles and initial vertices (for colored vertices) which in real became unused. This part need more thinking about - /// optimisation. - bool* idx_vert_used; - - idx_vert_used = new bool[VertexCount_Max * 2]; - for(size_t i = 0, i_e = VertexCount_Max * 2; i < i_e; i++) idx_vert_used[i] = false; - - // This ID's will be used when set materials ID in scene. - tmesh->mMaterialIndex = static_cast(PostprocessHelper_GetTextureID_Or_Create(face_list_cur.front().TexMap->TextureID_R, - face_list_cur.front().TexMap->TextureID_G, - face_list_cur.front().TexMap->TextureID_B, - face_list_cur.front().TexMap->TextureID_A)); - texcoord_arr.resize(VertexCount_Max * 2); - for(const SComplexFace& face_cur: face_list_cur) - { - for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++) - { - const size_t idx_vert = face_cur.Face.mIndices[idx_ind]; - - if(!idx_vert_used[idx_vert]) - { - texcoord_arr.at(idx_vert) = face_cur.TexMap->TextureCoordinate[idx_ind]; - idx_vert_used[idx_vert] = true; - } - else if(texcoord_arr.at(idx_vert) != face_cur.TexMap->TextureCoordinate[idx_ind]) - { - // in that case one vertex is shared with many texture coordinates. We need to duplicate vertex with another texture - // coordinates. - vert_arr.push_back(vert_arr.at(idx_vert)); - col_arr.push_back(col_arr.at(idx_vert)); - texcoord_arr.at(idx_vert_new) = face_cur.TexMap->TextureCoordinate[idx_ind]; - face_cur.Face.mIndices[idx_ind] = static_cast(idx_vert_new++); - } - }// for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++) - }// for(const SComplexFace& face_cur: face_list_cur) - - delete [] idx_vert_used; - // shrink array - texcoord_arr.resize(idx_vert_new); - }// if(face_list_cur.front().TexMap != nullptr) - - // - // copy collected data to mesh - // - tmesh->mNumVertices = static_cast(vert_arr.size()); - tmesh->mVertices = new aiVector3D[tmesh->mNumVertices]; - tmesh->mColors[0] = new aiColor4D[tmesh->mNumVertices]; - - memcpy(tmesh->mVertices, vert_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D)); - memcpy(tmesh->mColors[0], col_arr.data(), tmesh->mNumVertices * sizeof(aiColor4D)); - if(texcoord_arr.size() > 0) - { - tmesh->mTextureCoords[0] = new aiVector3D[tmesh->mNumVertices]; - memcpy(tmesh->mTextureCoords[0], texcoord_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D)); - tmesh->mNumUVComponents[0] = 2;// U and V stored in "x", "y" of aiVector3D. - } - - size_t idx_face = 0; - for(const SComplexFace& face_cur: face_list_cur) tmesh->mFaces[idx_face++] = face_cur.Face; - - // store new aiMesh - mesh_idx.push_back(static_cast(pMeshList.size())); - pMeshList.push_back(tmesh); - }// for(const std::list& face_list_cur: complex_faces_toplist) - }// if(ne_child->Type == CAMFImporter_NodeElement::ENET_Volume) - }// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child) - - // if meshes was created then assign new indices with current aiNode - if(!mesh_idx.empty()) - { - std::list::const_iterator mit = mesh_idx.begin(); - - pSceneNode.mNumMeshes = static_cast(mesh_idx.size()); - pSceneNode.mMeshes = new unsigned int[pSceneNode.mNumMeshes]; - for(size_t i = 0; i < pSceneNode.mNumMeshes; i++) pSceneNode.mMeshes[i] = *mit++; - }// if(mesh_idx.size() > 0) -} - -void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial) -{ -SPP_Material new_mat; - - new_mat.ID = pMaterial.ID; - for(const CAMFImporter_NodeElement* mat_child: pMaterial.Child) - { - if(mat_child->Type == CAMFImporter_NodeElement::ENET_Color) - { - new_mat.Color = (CAMFImporter_NodeElement_Color*)mat_child; - } - else if(mat_child->Type == CAMFImporter_NodeElement::ENET_Metadata) - { - new_mat.Metadata.push_back((CAMFImporter_NodeElement_Metadata*)mat_child); - } - }// for(const CAMFImporter_NodeElement* mat_child; pMaterial.Child) - - // place converted material to special list - mMaterial_Converted.push_back(new_mat); -} - -void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list& pNodeList) const -{ -aiNode* con_node; -std::list ch_node; - - // We will build next hierarchy: - // aiNode as parent () for set of nodes as a children - // |- aiNode for transformation ( -> , ) - aiNode for pointing to object ("objectid") - // ... - // \_ aiNode for transformation ( -> , ) - aiNode for pointing to object ("objectid") - con_node = new aiNode; - con_node->mName = pConstellation.ID; - // Walk through children and search for instances of another objects, constellations. - for(const CAMFImporter_NodeElement* ne: pConstellation.Child) - { - aiMatrix4x4 tmat; - aiNode* t_node; - aiNode* found_node; - - if(ne->Type == CAMFImporter_NodeElement::ENET_Metadata) continue; - if(ne->Type != CAMFImporter_NodeElement::ENET_Instance) throw DeadlyImportError("Only nodes can be in ."); - - // create alias for conveniance - CAMFImporter_NodeElement_Instance& als = *((CAMFImporter_NodeElement_Instance*)ne); - // find referenced object - if(!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID); - - // create node for applying transformation - t_node = new aiNode; - t_node->mParent = con_node; - // apply transformation - aiMatrix4x4::Translation(als.Delta, tmat), t_node->mTransformation *= tmat; - aiMatrix4x4::RotationX(als.Rotation.x, tmat), t_node->mTransformation *= tmat; - aiMatrix4x4::RotationY(als.Rotation.y, tmat), t_node->mTransformation *= tmat; - aiMatrix4x4::RotationZ(als.Rotation.z, tmat), t_node->mTransformation *= tmat; - // create array for one child node - t_node->mNumChildren = 1; - t_node->mChildren = new aiNode*[t_node->mNumChildren]; - SceneCombiner::Copy(&t_node->mChildren[0], found_node); - t_node->mChildren[0]->mParent = t_node; - ch_node.push_back(t_node); - }// for(const CAMFImporter_NodeElement* ne: pConstellation.Child) - - // copy found aiNode's as children - if(ch_node.empty()) throw DeadlyImportError(" must have at least one ."); - - size_t ch_idx = 0; - - con_node->mNumChildren = static_cast(ch_node.size()); - con_node->mChildren = new aiNode*[con_node->mNumChildren]; - for(aiNode* node: ch_node) con_node->mChildren[ch_idx++] = node; - - // and place "root" of node to node list - pNodeList.push_back(con_node); -} - -void AMFImporter::Postprocess_BuildScene(aiScene* pScene) -{ -std::list node_list; -std::list mesh_list; -std::list meta_list; - - // - // Because for AMF "material" is just complex colors mixing so aiMaterial will not be used. - // For building aiScene we are must to do few steps: - // at first creating root node for aiScene. - pScene->mRootNode = new aiNode; - pScene->mRootNode->mParent = nullptr; - pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED; - // search for root() element - CAMFImporter_NodeElement* root_el = nullptr; - - for(CAMFImporter_NodeElement* ne: mNodeElement_List) - { - if(ne->Type != CAMFImporter_NodeElement::ENET_Root) continue; - - root_el = ne; - - break; - }// for(const CAMFImporter_NodeElement* ne: mNodeElement_List) - - // Check if root element are found. - if(root_el == nullptr) throw DeadlyImportError("Root() element not found."); - - // after that walk through children of root and collect data. Five types of nodes can be placed at top level - in : , , , - // and . But at first we must read and because they will be used in . can be read - // at any moment. - // - // 1. - // 2. will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet - for(const CAMFImporter_NodeElement* root_child: root_el->Child) - { - if(root_child->Type == CAMFImporter_NodeElement::ENET_Material) Postprocess_BuildMaterial(*((CAMFImporter_NodeElement_Material*)root_child)); - } - - // After "appearance" nodes we must read because it will be used in -> . - // - // 3. - for(const CAMFImporter_NodeElement* root_child: root_el->Child) - { - if(root_child->Type == CAMFImporter_NodeElement::ENET_Object) - { - aiNode* tnode = nullptr; - - // for mesh and node must be built: object ID assigned to aiNode name and will be used in future for - Postprocess_BuildNodeAndObject(*((CAMFImporter_NodeElement_Object*)root_child), mesh_list, &tnode); - if(tnode != nullptr) node_list.push_back(tnode); - - } - }// for(const CAMFImporter_NodeElement* root_child: root_el->Child) - - // And finally read rest of nodes. - // - for(const CAMFImporter_NodeElement* root_child: root_el->Child) - { - // 4. - if(root_child->Type == CAMFImporter_NodeElement::ENET_Constellation) - { - // and at top of self abstraction use aiNode. So we can use only aiNode list for creating new aiNode's. - Postprocess_BuildConstellation(*((CAMFImporter_NodeElement_Constellation*)root_child), node_list); - } - - // 5, - if(root_child->Type == CAMFImporter_NodeElement::ENET_Metadata) meta_list.push_back((CAMFImporter_NodeElement_Metadata*)root_child); - }// for(const CAMFImporter_NodeElement* root_child: root_el->Child) - - // at now we can add collected metadata to root node - Postprocess_AddMetadata(meta_list, *pScene->mRootNode); - // - // Check constellation children - // - // As said in specification: - // "When multiple objects and constellations are defined in a single file, only the top level objects and constellations are available for printing." - // What that means? For example: if some object is used in constellation then you must show only constellation but not original object. - // And at this step we are checking that relations. -nl_clean_loop: - - if(node_list.size() > 1) - { - // walk through all nodes - for(std::list::iterator nl_it = node_list.begin(); nl_it != node_list.end(); ++nl_it) - { - // and try to find them in another top nodes. - std::list::const_iterator next_it = nl_it; - - ++next_it; - for(; next_it != node_list.end(); ++next_it) - { - if((*next_it)->FindNode((*nl_it)->mName) != nullptr) - { - // if current top node(nl_it) found in another top node then erase it from node_list and restart search loop. - node_list.erase(nl_it); - - goto nl_clean_loop; - } - }// for(; next_it != node_list.end(); next_it++) - }// for(std::list::const_iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++) - } - - // - // move created objects to aiScene - // - // - // Nodes - if(!node_list.empty()) - { - std::list::const_iterator nl_it = node_list.begin(); - - pScene->mRootNode->mNumChildren = static_cast(node_list.size()); - pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren]; - for(size_t i = 0; i < pScene->mRootNode->mNumChildren; i++) - { - // Objects and constellation that must be showed placed at top of hierarchy in node. So all aiNode's in node_list must have - // mRootNode only as parent. - (*nl_it)->mParent = pScene->mRootNode; - pScene->mRootNode->mChildren[i] = *nl_it++; - } - }// if(node_list.size() > 0) - - // - // Meshes - if(!mesh_list.empty()) - { - std::list::const_iterator ml_it = mesh_list.begin(); - - pScene->mNumMeshes = static_cast(mesh_list.size()); - pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; - for(size_t i = 0; i < pScene->mNumMeshes; i++) pScene->mMeshes[i] = *ml_it++; - }// if(mesh_list.size() > 0) - - // - // Textures - pScene->mNumTextures = static_cast(mTexture_Converted.size()); - if(pScene->mNumTextures > 0) - { - size_t idx; - - idx = 0; - pScene->mTextures = new aiTexture*[pScene->mNumTextures]; - for(const SPP_Texture& tex_convd: mTexture_Converted) - { - pScene->mTextures[idx] = new aiTexture; - pScene->mTextures[idx]->mWidth = static_cast(tex_convd.Width); - pScene->mTextures[idx]->mHeight = static_cast(tex_convd.Height); - pScene->mTextures[idx]->pcData = (aiTexel*)tex_convd.Data; - // texture format description. - strcpy(pScene->mTextures[idx]->achFormatHint, tex_convd.FormatHint); - idx++; - }// for(const SPP_Texture& tex_convd: mTexture_Converted) - - // Create materials for embedded textures. - idx = 0; - pScene->mNumMaterials = static_cast(mTexture_Converted.size()); - pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; - for(const SPP_Texture& tex_convd: mTexture_Converted) - { - const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + to_string(idx)); - const int mode = aiTextureOp_Multiply; - const int repeat = tex_convd.Tiled ? 1 : 0; - - pScene->mMaterials[idx] = new aiMaterial; - pScene->mMaterials[idx]->AddProperty(&texture_id, AI_MATKEY_TEXTURE_DIFFUSE(0)); - pScene->mMaterials[idx]->AddProperty(&mode, 1, AI_MATKEY_TEXOP_DIFFUSE(0)); - pScene->mMaterials[idx]->AddProperty(&repeat, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0)); - pScene->mMaterials[idx]->AddProperty(&repeat, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0)); - idx++; - } - }// if(pScene->mNumTextures > 0) -}// END: after that walk through children of root and collect data - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER diff --git a/Engine/lib/assimp/code/Assbin/AssbinExporter.cpp b/Engine/lib/assimp/code/Assbin/AssbinExporter.cpp deleted file mode 100644 index 76c823f82..000000000 --- a/Engine/lib/assimp/code/Assbin/AssbinExporter.cpp +++ /dev/null @@ -1,846 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2019, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ -/** @file AssbinExporter.cpp - * ASSBIN exporter main code - */ - -#ifndef ASSIMP_BUILD_NO_EXPORT -#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER - -#include "Common/assbin_chunks.h" -#include "PostProcessing/ProcessHelper.h" - -#include -#include -#include -#include -#include - -#ifdef ASSIMP_BUILD_NO_OWN_ZLIB -# include -#else -# include "../contrib/zlib/zlib.h" -#endif - -#include - -namespace Assimp { - -template -size_t Write(IOStream * stream, const T& v) { - return stream->Write( &v, sizeof(T), 1 ); -} - -// ----------------------------------------------------------------------------------- -// Serialize an aiString -template <> -inline -size_t Write(IOStream * stream, const aiString& s) { - const size_t s2 = (uint32_t)s.length; - stream->Write(&s,4,1); - stream->Write(s.data,s2,1); - - return s2+4; -} - -// ----------------------------------------------------------------------------------- -// Serialize an unsigned int as uint32_t -template <> -inline -size_t Write(IOStream * stream, const unsigned int& w) { - const uint32_t t = (uint32_t)w; - if (w > t) { - // this shouldn't happen, integers in Assimp data structures never exceed 2^32 - throw DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion"); - } - - stream->Write(&t,4,1); - - return 4; -} - -// ----------------------------------------------------------------------------------- -// Serialize an unsigned int as uint16_t -template <> -inline -size_t Write(IOStream * stream, const uint16_t& w) { - static_assert(sizeof(uint16_t)==2, "sizeof(uint16_t)==2"); - stream->Write(&w,2,1); - - return 2; -} - -// ----------------------------------------------------------------------------------- -// Serialize a float -template <> -inline -size_t Write(IOStream * stream, const float& f) { - static_assert(sizeof(float)==4, "sizeof(float)==4"); - stream->Write(&f,4,1); - - return 4; -} - -// ----------------------------------------------------------------------------------- -// Serialize a double -template <> -inline -size_t Write(IOStream * stream, const double& f) { - static_assert(sizeof(double)==8, "sizeof(double)==8"); - stream->Write(&f,8,1); - - return 8; -} - -// ----------------------------------------------------------------------------------- -// Serialize a vec3 -template <> -inline -size_t Write(IOStream * stream, const aiVector3D& v) { - size_t t = Write(stream,v.x); - t += Write(stream,v.y); - t += Write(stream,v.z); - - return t; -} - -// ----------------------------------------------------------------------------------- -// Serialize a color value -template <> -inline -size_t Write(IOStream * stream, const aiColor3D& v) { - size_t t = Write(stream,v.r); - t += Write(stream,v.g); - t += Write(stream,v.b); - - return t; -} - -// ----------------------------------------------------------------------------------- -// Serialize a color value -template <> -inline -size_t Write(IOStream * stream, const aiColor4D& v) { - size_t t = Write(stream,v.r); - t += Write(stream,v.g); - t += Write(stream,v.b); - t += Write(stream,v.a); - - return t; -} - -// ----------------------------------------------------------------------------------- -// Serialize a quaternion -template <> -inline -size_t Write(IOStream * stream, const aiQuaternion& v) { - size_t t = Write(stream,v.w); - t += Write(stream,v.x); - t += Write(stream,v.y); - t += Write(stream,v.z); - ai_assert(t == 16); - - return 16; -} - -// ----------------------------------------------------------------------------------- -// Serialize a vertex weight -template <> -inline -size_t Write(IOStream * stream, const aiVertexWeight& v) { - size_t t = Write(stream,v.mVertexId); - - return t+Write(stream,v.mWeight); -} - -// ----------------------------------------------------------------------------------- -// Serialize a mat4x4 -template <> -inline -size_t Write(IOStream * stream, const aiMatrix4x4& m) { - for (unsigned int i = 0; i < 4;++i) { - for (unsigned int i2 = 0; i2 < 4;++i2) { - Write(stream,m[i][i2]); - } - } - - return 64; -} - -// ----------------------------------------------------------------------------------- -// Serialize an aiVectorKey -template <> -inline -size_t Write(IOStream * stream, const aiVectorKey& v) { - const size_t t = Write(stream,v.mTime); - return t + Write(stream,v.mValue); -} - -// ----------------------------------------------------------------------------------- -// Serialize an aiQuatKey -template <> -inline -size_t Write(IOStream * stream, const aiQuatKey& v) { - const size_t t = Write(stream,v.mTime); - return t + Write(stream,v.mValue); -} - -template -inline -size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) { - T minc, maxc; - ArrayBounds(in,size,minc,maxc); - - const size_t t = Write(stream,minc); - return t + Write(stream,maxc); -} - -// We use this to write out non-byte arrays so that we write using the specializations. -// This way we avoid writing out extra bytes that potentially come from struct alignment. -template -inline -size_t WriteArray(IOStream * stream, const T* in, unsigned int size) { - size_t n = 0; - for (unsigned int i=0; i(stream,in[i]); - - return n; -} - -// ---------------------------------------------------------------------------------- -/** @class AssbinChunkWriter - * @brief Chunk writer mechanism for the .assbin file structure - * - * This is a standard in-memory IOStream (most of the code is based on BlobIOStream), - * the difference being that this takes another IOStream as a "container" in the - * constructor, and when it is destroyed, it appends the magic number, the chunk size, - * and the chunk contents to the container stream. This allows relatively easy chunk - * chunk construction, even recursively. - */ -class AssbinChunkWriter : public IOStream -{ -private: - - uint8_t* buffer; - uint32_t magic; - IOStream * container; - size_t cur_size, cursor, initial; - -private: - // ------------------------------------------------------------------- - void Grow(size_t need = 0) - { - size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); - - const uint8_t* const old = buffer; - buffer = new uint8_t[new_size]; - - if (old) { - memcpy(buffer,old,cur_size); - delete[] old; - } - - cur_size = new_size; - } - -public: - - AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096) - : buffer(NULL), magic(magic), container(container), cur_size(0), cursor(0), initial(initial) - { - } - - virtual ~AssbinChunkWriter() - { - if (container) { - container->Write( &magic, sizeof(uint32_t), 1 ); - container->Write( &cursor, sizeof(uint32_t), 1 ); - container->Write( buffer, 1, cursor ); - } - if (buffer) delete[] buffer; - } - - void * GetBufferPointer() { return buffer; } - - // ------------------------------------------------------------------- - virtual size_t Read(void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) { - return 0; - } - virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) { - return aiReturn_FAILURE; - } - virtual size_t Tell() const { - return cursor; - } - virtual void Flush() { - // not implemented - } - - virtual size_t FileSize() const { - return cursor; - } - - // ------------------------------------------------------------------- - virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount) { - pSize *= pCount; - if (cursor + pSize > cur_size) { - Grow(cursor + pSize); - } - - memcpy(buffer+cursor, pvBuffer, pSize); - cursor += pSize; - - return pCount; - } - -}; - -// ---------------------------------------------------------------------------------- -/** @class AssbinExport - * @brief Assbin exporter class - * - * This class performs the .assbin exporting, and is responsible for the file layout. - */ -class AssbinExport -{ -private: - bool shortened; - bool compressed; - -protected: - // ----------------------------------------------------------------------------------- - void WriteBinaryNode( IOStream * container, const aiNode* node) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE ); - - unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0); - - Write(&chunk,node->mName); - Write(&chunk,node->mTransformation); - Write(&chunk,node->mNumChildren); - Write(&chunk,node->mNumMeshes); - Write(&chunk,nb_metadata); - - for (unsigned int i = 0; i < node->mNumMeshes;++i) { - Write(&chunk,node->mMeshes[i]); - } - - for (unsigned int i = 0; i < node->mNumChildren;++i) { - WriteBinaryNode( &chunk, node->mChildren[i] ); - } - - for (unsigned int i = 0; i < nb_metadata; ++i) { - const aiString& key = node->mMetaData->mKeys[i]; - aiMetadataType type = node->mMetaData->mValues[i].mType; - void* value = node->mMetaData->mValues[i].mData; - - Write(&chunk, key); - Write(&chunk, type); - - switch (type) { - case AI_BOOL: - Write(&chunk, *((bool*) value)); - break; - case AI_INT32: - Write(&chunk, *((int32_t*) value)); - break; - case AI_UINT64: - Write(&chunk, *((uint64_t*) value)); - break; - case AI_FLOAT: - Write(&chunk, *((float*) value)); - break; - case AI_DOUBLE: - Write(&chunk, *((double*) value)); - break; - case AI_AISTRING: - Write(&chunk, *((aiString*) value)); - break; - case AI_AIVECTOR3D: - Write(&chunk, *((aiVector3D*) value)); - break; -#ifdef SWIG - case FORCE_32BIT: -#endif // SWIG - default: - break; - } - } - } - - // ----------------------------------------------------------------------------------- - void WriteBinaryTexture(IOStream * container, const aiTexture* tex) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE ); - - Write(&chunk,tex->mWidth); - Write(&chunk,tex->mHeight); - chunk.Write( tex->achFormatHint, sizeof(char), 4 ); - - if(!shortened) { - if (!tex->mHeight) { - chunk.Write(tex->pcData,1,tex->mWidth); - } - else { - chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4); - } - } - - } - - // ----------------------------------------------------------------------------------- - void WriteBinaryBone(IOStream * container, const aiBone* b) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE ); - - Write(&chunk,b->mName); - Write(&chunk,b->mNumWeights); - Write(&chunk,b->mOffsetMatrix); - - // for the moment we write dumb min/max values for the bones, too. - // maybe I'll add a better, hash-like solution later - if (shortened) { - WriteBounds(&chunk,b->mWeights,b->mNumWeights); - } // else write as usual - else WriteArray(&chunk,b->mWeights,b->mNumWeights); - } - - // ----------------------------------------------------------------------------------- - void WriteBinaryMesh(IOStream * container, const aiMesh* mesh) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH ); - - Write(&chunk,mesh->mPrimitiveTypes); - Write(&chunk,mesh->mNumVertices); - Write(&chunk,mesh->mNumFaces); - Write(&chunk,mesh->mNumBones); - Write(&chunk,mesh->mMaterialIndex); - - // first of all, write bits for all existent vertex components - unsigned int c = 0; - if (mesh->mVertices) { - c |= ASSBIN_MESH_HAS_POSITIONS; - } - if (mesh->mNormals) { - c |= ASSBIN_MESH_HAS_NORMALS; - } - if (mesh->mTangents && mesh->mBitangents) { - c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS; - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { - if (!mesh->mTextureCoords[n]) { - break; - } - c |= ASSBIN_MESH_HAS_TEXCOORD(n); - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { - if (!mesh->mColors[n]) { - break; - } - c |= ASSBIN_MESH_HAS_COLOR(n); - } - Write(&chunk,c); - - aiVector3D minVec, maxVec; - if (mesh->mVertices) { - if (shortened) { - WriteBounds(&chunk,mesh->mVertices,mesh->mNumVertices); - } // else write as usual - else WriteArray(&chunk,mesh->mVertices,mesh->mNumVertices); - } - if (mesh->mNormals) { - if (shortened) { - WriteBounds(&chunk,mesh->mNormals,mesh->mNumVertices); - } // else write as usual - else WriteArray(&chunk,mesh->mNormals,mesh->mNumVertices); - } - if (mesh->mTangents && mesh->mBitangents) { - if (shortened) { - WriteBounds(&chunk,mesh->mTangents,mesh->mNumVertices); - WriteBounds(&chunk,mesh->mBitangents,mesh->mNumVertices); - } // else write as usual - else { - WriteArray(&chunk,mesh->mTangents,mesh->mNumVertices); - WriteArray(&chunk,mesh->mBitangents,mesh->mNumVertices); - } - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { - if (!mesh->mColors[n]) - break; - - if (shortened) { - WriteBounds(&chunk,mesh->mColors[n],mesh->mNumVertices); - } // else write as usual - else WriteArray(&chunk,mesh->mColors[n],mesh->mNumVertices); - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { - if (!mesh->mTextureCoords[n]) - break; - - // write number of UV components - Write(&chunk,mesh->mNumUVComponents[n]); - - if (shortened) { - WriteBounds(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices); - } // else write as usual - else WriteArray(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices); - } - - // write faces. There are no floating-point calculations involved - // in these, so we can write a simple hash over the face data - // to the dump file. We generate a single 32 Bit hash for 512 faces - // using Assimp's standard hashing function. - if (shortened) { - unsigned int processed = 0; - for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) { - - uint32_t hash = 0; - for (unsigned int a = 0; a < job;++a) { - - const aiFace& f = mesh->mFaces[processed+a]; - uint32_t tmp = f.mNumIndices; - hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); - for (unsigned int i = 0; i < f.mNumIndices; ++i) { - static_assert(AI_MAX_VERTICES <= 0xffffffff, "AI_MAX_VERTICES <= 0xffffffff"); - tmp = static_cast( f.mIndices[i] ); - hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); - } - } - Write(&chunk,hash); - } - } - else // else write as usual - { - // if there are less than 2^16 vertices, we can simply use 16 bit integers ... - for (unsigned int i = 0; i < mesh->mNumFaces;++i) { - const aiFace& f = mesh->mFaces[i]; - - static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff"); - Write(&chunk,f.mNumIndices); - - for (unsigned int a = 0; a < f.mNumIndices;++a) { - if (mesh->mNumVertices < (1u<<16)) { - Write(&chunk,f.mIndices[a]); - } - else Write(&chunk,f.mIndices[a]); - } - } - } - - // write bones - if (mesh->mNumBones) { - for (unsigned int a = 0; a < mesh->mNumBones;++a) { - const aiBone* b = mesh->mBones[a]; - WriteBinaryBone(&chunk,b); - } - } - } - - // ----------------------------------------------------------------------------------- - void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY ); - - Write(&chunk,prop->mKey); - Write(&chunk,prop->mSemantic); - Write(&chunk,prop->mIndex); - - Write(&chunk,prop->mDataLength); - Write(&chunk,(unsigned int)prop->mType); - chunk.Write(prop->mData,1,prop->mDataLength); - } - - // ----------------------------------------------------------------------------------- - void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL); - - Write(&chunk,mat->mNumProperties); - for (unsigned int i = 0; i < mat->mNumProperties;++i) { - WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]); - } - } - - // ----------------------------------------------------------------------------------- - void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM ); - - Write(&chunk,nd->mNodeName); - Write(&chunk,nd->mNumPositionKeys); - Write(&chunk,nd->mNumRotationKeys); - Write(&chunk,nd->mNumScalingKeys); - Write(&chunk,nd->mPreState); - Write(&chunk,nd->mPostState); - - if (nd->mPositionKeys) { - if (shortened) { - WriteBounds(&chunk,nd->mPositionKeys,nd->mNumPositionKeys); - - } // else write as usual - else WriteArray(&chunk,nd->mPositionKeys,nd->mNumPositionKeys); - } - if (nd->mRotationKeys) { - if (shortened) { - WriteBounds(&chunk,nd->mRotationKeys,nd->mNumRotationKeys); - - } // else write as usual - else WriteArray(&chunk,nd->mRotationKeys,nd->mNumRotationKeys); - } - if (nd->mScalingKeys) { - if (shortened) { - WriteBounds(&chunk,nd->mScalingKeys,nd->mNumScalingKeys); - - } // else write as usual - else WriteArray(&chunk,nd->mScalingKeys,nd->mNumScalingKeys); - } - } - - - // ----------------------------------------------------------------------------------- - void WriteBinaryAnim( IOStream * container, const aiAnimation* anim ) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION ); - - Write(&chunk,anim->mName); - Write(&chunk,anim->mDuration); - Write(&chunk,anim->mTicksPerSecond); - Write(&chunk,anim->mNumChannels); - - for (unsigned int a = 0; a < anim->mNumChannels;++a) { - const aiNodeAnim* nd = anim->mChannels[a]; - WriteBinaryNodeAnim(&chunk,nd); - } - } - - // ----------------------------------------------------------------------------------- - void WriteBinaryLight( IOStream * container, const aiLight* l ) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT ); - - Write(&chunk,l->mName); - Write(&chunk,l->mType); - - if (l->mType != aiLightSource_DIRECTIONAL) { - Write(&chunk,l->mAttenuationConstant); - Write(&chunk,l->mAttenuationLinear); - Write(&chunk,l->mAttenuationQuadratic); - } - - Write(&chunk,l->mColorDiffuse); - Write(&chunk,l->mColorSpecular); - Write(&chunk,l->mColorAmbient); - - if (l->mType == aiLightSource_SPOT) { - Write(&chunk,l->mAngleInnerCone); - Write(&chunk,l->mAngleOuterCone); - } - - } - - // ----------------------------------------------------------------------------------- - void WriteBinaryCamera( IOStream * container, const aiCamera* cam ) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA ); - - Write(&chunk,cam->mName); - Write(&chunk,cam->mPosition); - Write(&chunk,cam->mLookAt); - Write(&chunk,cam->mUp); - Write(&chunk,cam->mHorizontalFOV); - Write(&chunk,cam->mClipPlaneNear); - Write(&chunk,cam->mClipPlaneFar); - Write(&chunk,cam->mAspect); - } - - // ----------------------------------------------------------------------------------- - void WriteBinaryScene( IOStream * container, const aiScene* scene) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE ); - - // basic scene information - Write(&chunk,scene->mFlags); - Write(&chunk,scene->mNumMeshes); - Write(&chunk,scene->mNumMaterials); - Write(&chunk,scene->mNumAnimations); - Write(&chunk,scene->mNumTextures); - Write(&chunk,scene->mNumLights); - Write(&chunk,scene->mNumCameras); - - // write node graph - WriteBinaryNode( &chunk, scene->mRootNode ); - - // write all meshes - for (unsigned int i = 0; i < scene->mNumMeshes;++i) { - const aiMesh* mesh = scene->mMeshes[i]; - WriteBinaryMesh( &chunk,mesh); - } - - // write materials - for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { - const aiMaterial* mat = scene->mMaterials[i]; - WriteBinaryMaterial(&chunk,mat); - } - - // write all animations - for (unsigned int i = 0; i < scene->mNumAnimations;++i) { - const aiAnimation* anim = scene->mAnimations[i]; - WriteBinaryAnim(&chunk,anim); - } - - - // write all textures - for (unsigned int i = 0; i < scene->mNumTextures;++i) { - const aiTexture* mesh = scene->mTextures[i]; - WriteBinaryTexture(&chunk,mesh); - } - - // write lights - for (unsigned int i = 0; i < scene->mNumLights;++i) { - const aiLight* l = scene->mLights[i]; - WriteBinaryLight(&chunk,l); - } - - // write cameras - for (unsigned int i = 0; i < scene->mNumCameras;++i) { - const aiCamera* cam = scene->mCameras[i]; - WriteBinaryCamera(&chunk,cam); - } - - } - -public: - AssbinExport() - : shortened(false), compressed(false) // temporary settings until properties are introduced for exporters - { - } - - // ----------------------------------------------------------------------------------- - // Write a binary model dump - void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) - { - IOStream * out = pIOSystem->Open( pFile, "wb" ); - if (!out) return; - - time_t tt = time(NULL); -#if _WIN32 - tm* p = gmtime(&tt); -#else - struct tm now; - tm* p = gmtime_r(&tt, &now); -#endif - - // header - char s[64]; - memset( s, 0, 64 ); -#if _MSC_VER >= 1400 - sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p)); -#else - ai_snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p)); -#endif - out->Write( s, 44, 1 ); - // == 44 bytes - - Write( out, ASSBIN_VERSION_MAJOR ); - Write( out, ASSBIN_VERSION_MINOR ); - Write( out, aiGetVersionRevision() ); - Write( out, aiGetCompileFlags() ); - Write( out, shortened ); - Write( out, compressed ); - // == 20 bytes - - char buff[256]; - strncpy(buff,pFile,256); - out->Write(buff,sizeof(char),256); - - char cmd[] = "\0"; - strncpy(buff,cmd,128); - out->Write(buff,sizeof(char),128); - - // leave 64 bytes free for future extensions - memset(buff,0xcd,64); - out->Write(buff,sizeof(char),64); - // == 435 bytes - - // ==== total header size: 512 bytes - ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH ); - - // Up to here the data is uncompressed. For compressed files, the rest - // is compressed using standard DEFLATE from zlib. - if (compressed) - { - AssbinChunkWriter uncompressedStream( NULL, 0 ); - WriteBinaryScene( &uncompressedStream, pScene ); - - uLongf uncompressedSize = static_cast(uncompressedStream.Tell()); - uLongf compressedSize = (uLongf)compressBound(uncompressedSize); - uint8_t* compressedBuffer = new uint8_t[ compressedSize ]; - - int res = compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 ); - if(res != Z_OK) - { - delete [] compressedBuffer; - pIOSystem->Close(out); - throw DeadlyExportError("Compression failed."); - } - - out->Write( &uncompressedSize, sizeof(uint32_t), 1 ); - out->Write( compressedBuffer, sizeof(char), compressedSize ); - - delete[] compressedBuffer; - } - else - { - WriteBinaryScene( out, pScene ); - } - - pIOSystem->Close( out ); - } -}; - -void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) { - AssbinExport exporter; - exporter.WriteBinaryDump( pFile, pIOSystem, pScene ); -} -} // end of namespace Assimp - -#endif // ASSIMP_BUILD_NO_ASSBIN_EXPORTER -#endif // ASSIMP_BUILD_NO_EXPORT diff --git a/Engine/lib/assimp/code/3DS/3DSConverter.cpp b/Engine/lib/assimp/code/AssetLib/3DS/3DSConverter.cpp similarity index 58% rename from Engine/lib/assimp/code/3DS/3DSConverter.cpp rename to Engine/lib/assimp/code/AssetLib/3DS/3DSConverter.cpp index 2176b75fc..5a01429e4 100644 --- a/Engine/lib/assimp/code/3DS/3DSConverter.cpp +++ b/Engine/lib/assimp/code/AssetLib/3DS/3DSConverter.cpp @@ -3,9 +3,7 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -43,17 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** @file Implementation of the 3ds importer class */ - #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER // internal headers #include "3DSLoader.h" #include "Common/TargetAnimation.h" +#include #include #include -#include -#include #include +#include using namespace Assimp; @@ -61,75 +58,61 @@ static const unsigned int NotSet = 0xcdcdcdcd; // ------------------------------------------------------------------------------------------------ // Setup final material indices, generae a default material if necessary -void Discreet3DSImporter::ReplaceDefaultMaterial() -{ +void Discreet3DSImporter::ReplaceDefaultMaterial() { // Try to find an existing material that matches the // typical default material setting: // - no textures // - diffuse color (in grey!) // NOTE: This is here to workaround the fact that some // exporters are writing a default material, too. - unsigned int idx( NotSet ); - for (unsigned int i = 0; i < mScene->mMaterials.size();++i) - { - std::string &s = mScene->mMaterials[i].mName; - for ( std::string::iterator it = s.begin(); it != s.end(); ++it ) { - *it = static_cast< char >( ::tolower( *it ) ); + unsigned int idx(NotSet); + for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) { + std::string s = mScene->mMaterials[i].mName; + for (char & it : s) { + it = static_cast(::tolower(static_cast(it))); } - if (std::string::npos == s.find("default"))continue; + if (std::string::npos == s.find("default")) continue; if (mScene->mMaterials[i].mDiffuse.r != - mScene->mMaterials[i].mDiffuse.g || - mScene->mMaterials[i].mDiffuse.r != - mScene->mMaterials[i].mDiffuse.b)continue; + mScene->mMaterials[i].mDiffuse.g || + mScene->mMaterials[i].mDiffuse.r != + mScene->mMaterials[i].mDiffuse.b) continue; - if (mScene->mMaterials[i].sTexDiffuse.mMapName.length() != 0 || - mScene->mMaterials[i].sTexBump.mMapName.length() != 0 || - mScene->mMaterials[i].sTexOpacity.mMapName.length() != 0 || - mScene->mMaterials[i].sTexEmissive.mMapName.length() != 0 || - mScene->mMaterials[i].sTexSpecular.mMapName.length() != 0 || - mScene->mMaterials[i].sTexShininess.mMapName.length() != 0 ) - { + if (ContainsTextures(i)) { continue; } idx = i; } - if ( NotSet == idx ) { - idx = ( unsigned int )mScene->mMaterials.size(); + if (NotSet == idx) { + idx = (unsigned int)mScene->mMaterials.size(); } // now iterate through all meshes and through all faces and // find all faces that are using the default material unsigned int cnt = 0; for (std::vector::iterator - i = mScene->mMeshes.begin(); - i != mScene->mMeshes.end();++i) - { + i = mScene->mMeshes.begin(); + i != mScene->mMeshes.end(); ++i) { for (std::vector::iterator - a = (*i).mFaceMaterials.begin(); - a != (*i).mFaceMaterials.end();++a) - { + a = (*i).mFaceMaterials.begin(); + a != (*i).mFaceMaterials.end(); ++a) { // NOTE: The additional check seems to be necessary, // some exporters seem to generate invalid data here - if (0xcdcdcdcd == (*a)) - { + if (0xcdcdcdcd == (*a)) { (*a) = idx; ++cnt; - } - else if ( (*a) >= mScene->mMaterials.size()) - { + } else if ((*a) >= mScene->mMaterials.size()) { (*a) = idx; ASSIMP_LOG_WARN("Material index overflow in 3DS file. Using default material"); ++cnt; } } } - if (cnt && idx == mScene->mMaterials.size()) - { + if (cnt && idx == mScene->mMaterials.size()) { // We need to create our own default material D3DS::Material sMat("%%%DEFAULT"); - sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f); + sMat.mDiffuse = aiColor3D(0.3f, 0.3f, 0.3f); mScene->mMaterials.push_back(sMat); ASSIMP_LOG_INFO("3DS: Generating default material"); @@ -138,22 +121,17 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() // ------------------------------------------------------------------------------------------------ // Check whether all indices are valid. Otherwise we'd crash before the validation step is reached -void Discreet3DSImporter::CheckIndices(D3DS::Mesh& sMesh) -{ - for (std::vector< D3DS::Face >::iterator i = sMesh.mFaces.begin(); i != sMesh.mFaces.end();++i) - { +void Discreet3DSImporter::CheckIndices(D3DS::Mesh &sMesh) { + for (std::vector::iterator i = sMesh.mFaces.begin(); i != sMesh.mFaces.end(); ++i) { // check whether all indices are in range - for (unsigned int a = 0; a < 3;++a) - { - if ((*i).mIndices[a] >= sMesh.mPositions.size()) - { + for (unsigned int a = 0; a < 3; ++a) { + if ((*i).mIndices[a] >= sMesh.mPositions.size()) { ASSIMP_LOG_WARN("3DS: Vertex index overflow)"); - (*i).mIndices[a] = (uint32_t)sMesh.mPositions.size()-1; + (*i).mIndices[a] = (uint32_t)sMesh.mPositions.size() - 1; } - if ( !sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size()) - { + if (!sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size()) { ASSIMP_LOG_WARN("3DS: Texture coordinate index overflow)"); - (*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size()-1; + (*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size() - 1; } } } @@ -161,24 +139,21 @@ void Discreet3DSImporter::CheckIndices(D3DS::Mesh& sMesh) // ------------------------------------------------------------------------------------------------ // Generate out unique verbose format representation -void Discreet3DSImporter::MakeUnique(D3DS::Mesh& sMesh) -{ +void Discreet3DSImporter::MakeUnique(D3DS::Mesh &sMesh) { // TODO: really necessary? I don't think. Just a waste of memory and time // to do it now in a separate buffer. // Allocate output storage - std::vector vNew (sMesh.mFaces.size() * 3); + std::vector vNew(sMesh.mFaces.size() * 3); std::vector vNew2; if (sMesh.mTexCoords.size()) vNew2.resize(sMesh.mFaces.size() * 3); - for (unsigned int i = 0, base = 0; i < sMesh.mFaces.size();++i) - { - D3DS::Face& face = sMesh.mFaces[i]; + for (unsigned int i = 0, base = 0; i < sMesh.mFaces.size(); ++i) { + D3DS::Face &face = sMesh.mFaces[i]; // Positions - for (unsigned int a = 0; a < 3;++a,++base) - { + for (unsigned int a = 0; a < 3; ++a, ++base) { vNew[base] = sMesh.mPositions[face.mIndices[a]]; if (sMesh.mTexCoords.size()) vNew2[base] = sMesh.mTexCoords[face.mIndices[a]]; @@ -192,26 +167,24 @@ void Discreet3DSImporter::MakeUnique(D3DS::Mesh& sMesh) // ------------------------------------------------------------------------------------------------ // Convert a 3DS texture to texture keys in an aiMaterial -void CopyTexture(aiMaterial& mat, D3DS::Texture& texture, aiTextureType type) -{ +void CopyTexture(aiMaterial &mat, D3DS::Texture &texture, aiTextureType type) { // Setup the texture name aiString tex; - tex.Set( texture.mMapName); - mat.AddProperty( &tex, AI_MATKEY_TEXTURE(type,0)); + tex.Set(texture.mMapName); + mat.AddProperty(&tex, AI_MATKEY_TEXTURE(type, 0)); // Setup the texture blend factor if (is_not_qnan(texture.mTextureBlend)) - mat.AddProperty( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0)); + mat.AddProperty(&texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type, 0)); // Setup the texture mapping mode int mapMode = static_cast(texture.mMapMode); - mat.AddProperty(&mapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0)); - mat.AddProperty(&mapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0)); + mat.AddProperty(&mapMode, 1, AI_MATKEY_MAPPINGMODE_U(type, 0)); + mat.AddProperty(&mapMode, 1, AI_MATKEY_MAPPINGMODE_V(type, 0)); // Mirroring - double the scaling values // FIXME: this is not really correct ... - if (texture.mMapMode == aiTextureMapMode_Mirror) - { + if (texture.mMapMode == aiTextureMapMode_Mirror) { texture.mScaleU *= 2.0; texture.mScaleV *= 2.0; texture.mOffsetU /= 2.0; @@ -219,24 +192,22 @@ void CopyTexture(aiMaterial& mat, D3DS::Texture& texture, aiTextureType type) } // Setup texture UV transformations - mat.AddProperty(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0)); + mat.AddProperty(&texture.mOffsetU, 5, AI_MATKEY_UVTRANSFORM(type, 0)); } // ------------------------------------------------------------------------------------------------ // Convert a 3DS material to an aiMaterial -void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat, - aiMaterial& mat) -{ +void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat, + aiMaterial &mat) { // NOTE: Pass the background image to the viewer by bypassing the // material system. This is an evil hack, never do it again! - if (0 != mBackgroundImage.length() && bHasBG) - { + if (0 != mBackgroundImage.length() && bHasBG) { aiString tex; - tex.Set( mBackgroundImage); - mat.AddProperty( &tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE); + tex.Set(mBackgroundImage); + mat.AddProperty(&tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE); // Be sure this is only done for the first material - mBackgroundImage = std::string(""); + mBackgroundImage = std::string(); } // At first add the base ambient color of the scene to the material @@ -245,143 +216,138 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat, oldMat.mAmbient.b += mClrAmbient.b; aiString name; - name.Set( oldMat.mName); - mat.AddProperty( &name, AI_MATKEY_NAME); + name.Set(oldMat.mName); + mat.AddProperty(&name, AI_MATKEY_NAME); // Material colors - mat.AddProperty( &oldMat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT); - mat.AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE); - mat.AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR); - mat.AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); + mat.AddProperty(&oldMat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT); + mat.AddProperty(&oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE); + mat.AddProperty(&oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR); + mat.AddProperty(&oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); // Phong shininess and shininess strength if (D3DS::Discreet3DS::Phong == oldMat.mShading || - D3DS::Discreet3DS::Metal == oldMat.mShading) - { - if (!oldMat.mSpecularExponent || !oldMat.mShininessStrength) - { + D3DS::Discreet3DS::Metal == oldMat.mShading) { + if (!oldMat.mSpecularExponent || !oldMat.mShininessStrength) { oldMat.mShading = D3DS::Discreet3DS::Gouraud; - } - else - { - mat.AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS); - mat.AddProperty( &oldMat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH); + } else { + mat.AddProperty(&oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS); + mat.AddProperty(&oldMat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH); } } // Opacity - mat.AddProperty( &oldMat.mTransparency,1,AI_MATKEY_OPACITY); + mat.AddProperty(&oldMat.mTransparency, 1, AI_MATKEY_OPACITY); // Bump height scaling - mat.AddProperty( &oldMat.mBumpHeight,1,AI_MATKEY_BUMPSCALING); + mat.AddProperty(&oldMat.mBumpHeight, 1, AI_MATKEY_BUMPSCALING); // Two sided rendering? - if (oldMat.mTwoSided) - { + if (oldMat.mTwoSided) { int i = 1; - mat.AddProperty(&i,1,AI_MATKEY_TWOSIDED); + mat.AddProperty(&i, 1, AI_MATKEY_TWOSIDED); } // Shading mode aiShadingMode eShading = aiShadingMode_NoShading; - switch (oldMat.mShading) - { - case D3DS::Discreet3DS::Flat: - eShading = aiShadingMode_Flat; break; + switch (oldMat.mShading) { + case D3DS::Discreet3DS::Flat: + eShading = aiShadingMode_Flat; + break; - // I don't know what "Wire" shading should be, - // assume it is simple lambertian diffuse shading - case D3DS::Discreet3DS::Wire: - { - // Set the wireframe flag - unsigned int iWire = 1; - mat.AddProperty( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME); - } + // I don't know what "Wire" shading should be, + // assume it is simple lambertian diffuse shading + case D3DS::Discreet3DS::Wire: { + // Set the wireframe flag + unsigned int iWire = 1; + mat.AddProperty((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME); + } - case D3DS::Discreet3DS::Gouraud: - eShading = aiShadingMode_Gouraud; break; + case D3DS::Discreet3DS::Gouraud: + eShading = aiShadingMode_Gouraud; + break; - // assume cook-torrance shading for metals. - case D3DS::Discreet3DS::Phong : - eShading = aiShadingMode_Phong; break; + // assume cook-torrance shading for metals. + case D3DS::Discreet3DS::Phong: + eShading = aiShadingMode_Phong; + break; - case D3DS::Discreet3DS::Metal : - eShading = aiShadingMode_CookTorrance; break; + case D3DS::Discreet3DS::Metal: + eShading = aiShadingMode_CookTorrance; + break; - // FIX to workaround a warning with GCC 4 who complained - // about a missing case Blinn: here - Blinn isn't a valid - // value in the 3DS Loader, it is just needed for ASE - case D3DS::Discreet3DS::Blinn : - eShading = aiShadingMode_Blinn; break; + // FIX to workaround a warning with GCC 4 who complained + // about a missing case Blinn: here - Blinn isn't a valid + // value in the 3DS Loader, it is just needed for ASE + case D3DS::Discreet3DS::Blinn: + eShading = aiShadingMode_Blinn; + break; } int eShading_ = static_cast(eShading); mat.AddProperty(&eShading_, 1, AI_MATKEY_SHADING_MODEL); // DIFFUSE texture - if( oldMat.sTexDiffuse.mMapName.length() > 0) - CopyTexture(mat,oldMat.sTexDiffuse, aiTextureType_DIFFUSE); + if (oldMat.sTexDiffuse.mMapName.length() > 0) + CopyTexture(mat, oldMat.sTexDiffuse, aiTextureType_DIFFUSE); // SPECULAR texture - if( oldMat.sTexSpecular.mMapName.length() > 0) - CopyTexture(mat,oldMat.sTexSpecular, aiTextureType_SPECULAR); + if (oldMat.sTexSpecular.mMapName.length() > 0) + CopyTexture(mat, oldMat.sTexSpecular, aiTextureType_SPECULAR); // OPACITY texture - if( oldMat.sTexOpacity.mMapName.length() > 0) - CopyTexture(mat,oldMat.sTexOpacity, aiTextureType_OPACITY); + if (oldMat.sTexOpacity.mMapName.length() > 0) + CopyTexture(mat, oldMat.sTexOpacity, aiTextureType_OPACITY); // EMISSIVE texture - if( oldMat.sTexEmissive.mMapName.length() > 0) - CopyTexture(mat,oldMat.sTexEmissive, aiTextureType_EMISSIVE); + if (oldMat.sTexEmissive.mMapName.length() > 0) + CopyTexture(mat, oldMat.sTexEmissive, aiTextureType_EMISSIVE); // BUMP texture - if( oldMat.sTexBump.mMapName.length() > 0) - CopyTexture(mat,oldMat.sTexBump, aiTextureType_HEIGHT); + if (oldMat.sTexBump.mMapName.length() > 0) + CopyTexture(mat, oldMat.sTexBump, aiTextureType_HEIGHT); // SHININESS texture - if( oldMat.sTexShininess.mMapName.length() > 0) - CopyTexture(mat,oldMat.sTexShininess, aiTextureType_SHININESS); + if (oldMat.sTexShininess.mMapName.length() > 0) + CopyTexture(mat, oldMat.sTexShininess, aiTextureType_SHININESS); // REFLECTION texture - if( oldMat.sTexReflective.mMapName.length() > 0) - CopyTexture(mat,oldMat.sTexReflective, aiTextureType_REFLECTION); + if (oldMat.sTexReflective.mMapName.length() > 0) + CopyTexture(mat, oldMat.sTexReflective, aiTextureType_REFLECTION); // Store the name of the material itself, too - if( oldMat.mName.length()) { + if (oldMat.mName.length()) { aiString tex; - tex.Set( oldMat.mName); - mat.AddProperty( &tex, AI_MATKEY_NAME); + tex.Set(oldMat.mName); + mat.AddProperty(&tex, AI_MATKEY_NAME); } } // ------------------------------------------------------------------------------------------------ // Split meshes by their materials and generate output aiMesh'es -void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut) -{ - std::vector avOutMeshes; +void Discreet3DSImporter::ConvertMeshes(aiScene *pcOut) { + std::vector avOutMeshes; avOutMeshes.reserve(mScene->mMeshes.size() * 2); - unsigned int iFaceCnt = 0,num = 0; + unsigned int iFaceCnt = 0, num = 0; aiString name; // we need to split all meshes by their materials - for (std::vector::iterator i = mScene->mMeshes.begin(); i != mScene->mMeshes.end();++i) { - std::unique_ptr< std::vector[] > aiSplit(new std::vector[mScene->mMaterials.size()]); + for (std::vector::iterator i = mScene->mMeshes.begin(); i != mScene->mMeshes.end(); ++i) { + std::unique_ptr[]> aiSplit(new std::vector[mScene->mMaterials.size()]); - name.length = ASSIMP_itoa10(name.data,num++); + name.length = ASSIMP_itoa10(name.data, num++); unsigned int iNum = 0; - for (std::vector::const_iterator a = (*i).mFaceMaterials.begin(); - a != (*i).mFaceMaterials.end();++a,++iNum) - { + for (std::vector::const_iterator a = (*i).mFaceMaterials.begin(); + a != (*i).mFaceMaterials.end(); ++a, ++iNum) { aiSplit[*a].push_back(iNum); } // now generate submeshes - for (unsigned int p = 0; p < mScene->mMaterials.size();++p) - { + for (unsigned int p = 0; p < mScene->mMaterials.size(); ++p) { if (aiSplit[p].empty()) { continue; } - aiMesh* meshOut = new aiMesh(); + aiMesh *meshOut = new aiMesh(); meshOut->mName = name; meshOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; @@ -389,36 +355,33 @@ void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut) meshOut->mMaterialIndex = p; // use the color data as temporary storage - meshOut->mColors[0] = (aiColor4D*)(&*i); + meshOut->mColors[0] = (aiColor4D *)(&*i); avOutMeshes.push_back(meshOut); // convert vertices meshOut->mNumFaces = (unsigned int)aiSplit[p].size(); - meshOut->mNumVertices = meshOut->mNumFaces*3; + meshOut->mNumVertices = meshOut->mNumFaces * 3; // allocate enough storage for faces meshOut->mFaces = new aiFace[meshOut->mNumFaces]; iFaceCnt += meshOut->mNumFaces; meshOut->mVertices = new aiVector3D[meshOut->mNumVertices]; - meshOut->mNormals = new aiVector3D[meshOut->mNumVertices]; - if ((*i).mTexCoords.size()) - { + meshOut->mNormals = new aiVector3D[meshOut->mNumVertices]; + if ((*i).mTexCoords.size()) { meshOut->mTextureCoords[0] = new aiVector3D[meshOut->mNumVertices]; } - for (unsigned int q = 0, base = 0; q < aiSplit[p].size();++q) - { + for (unsigned int q = 0, base = 0; q < aiSplit[p].size(); ++q) { unsigned int index = aiSplit[p][q]; - aiFace& face = meshOut->mFaces[q]; + aiFace &face = meshOut->mFaces[q]; face.mIndices = new unsigned int[3]; face.mNumIndices = 3; - for (unsigned int a = 0; a < 3;++a,++base) - { + for (unsigned int a = 0; a < 3; ++a, ++base) { unsigned int idx = (*i).mFaces[index].mIndices[a]; - meshOut->mVertices[base] = (*i).mPositions[idx]; - meshOut->mNormals [base] = (*i).mNormals[idx]; + meshOut->mVertices[base] = (*i).mPositions[idx]; + meshOut->mNormals[base] = (*i).mNormals[idx]; if ((*i).mTexCoords.size()) meshOut->mTextureCoords[0][base] = (*i).mTexCoords[idx]; @@ -431,8 +394,8 @@ void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut) // Copy them to the output array pcOut->mNumMeshes = (unsigned int)avOutMeshes.size(); - pcOut->mMeshes = new aiMesh*[pcOut->mNumMeshes](); - for (unsigned int a = 0; a < pcOut->mNumMeshes;++a) { + pcOut->mMeshes = new aiMesh *[pcOut->mNumMeshes](); + for (unsigned int a = 0; a < pcOut->mNumMeshes; ++a) { pcOut->mMeshes[a] = avOutMeshes[a]; } @@ -444,47 +407,44 @@ void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut) // ------------------------------------------------------------------------------------------------ // Add a node to the scenegraph and setup its final transformation -void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, - D3DS::Node* pcIn, aiMatrix4x4& /*absTrafo*/) -{ +void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, + D3DS::Node *pcIn, aiMatrix4x4 & /*absTrafo*/) { std::vector iArray; iArray.reserve(3); aiMatrix4x4 abs; // Find all meshes with the same name as the node - for (unsigned int a = 0; a < pcSOut->mNumMeshes;++a) - { - const D3DS::Mesh* pcMesh = (const D3DS::Mesh*)pcSOut->mMeshes[a]->mColors[0]; - ai_assert(NULL != pcMesh); + for (unsigned int a = 0; a < pcSOut->mNumMeshes; ++a) { + const D3DS::Mesh *pcMesh = (const D3DS::Mesh *)pcSOut->mMeshes[a]->mColors[0]; + ai_assert(nullptr != pcMesh); if (pcIn->mName == pcMesh->mName) iArray.push_back(a); } - if (!iArray.empty()) - { + if (!iArray.empty()) { // The matrix should be identical for all meshes with the // same name. It HAS to be identical for all meshes ..... - D3DS::Mesh* imesh = ((D3DS::Mesh*)pcSOut->mMeshes[iArray[0]]->mColors[0]); + D3DS::Mesh *imesh = ((D3DS::Mesh *)pcSOut->mMeshes[iArray[0]]->mColors[0]); // Compute the inverse of the transformation matrix to move the // vertices back to their relative and local space aiMatrix4x4 mInv = imesh->mMat, mInvTransposed = imesh->mMat; - mInv.Inverse();mInvTransposed.Transpose(); + mInv.Inverse(); + mInvTransposed.Transpose(); aiVector3D pivot = pcIn->vPivot; pcOut->mNumMeshes = (unsigned int)iArray.size(); pcOut->mMeshes = new unsigned int[iArray.size()]; - for (unsigned int i = 0;i < iArray.size();++i) { + for (unsigned int i = 0; i < iArray.size(); ++i) { const unsigned int iIndex = iArray[i]; - aiMesh* const mesh = pcSOut->mMeshes[iIndex]; + aiMesh *const mesh = pcSOut->mMeshes[iIndex]; - if (mesh->mColors[1] == NULL) - { + if (mesh->mColors[1] == nullptr) { // Transform the vertices back into their local space // fixme: consider computing normals after this, so we don't need to transform them - const aiVector3D* const pvEnd = mesh->mVertices + mesh->mNumVertices; - aiVector3D* pvCurrent = mesh->mVertices, *t2 = mesh->mNormals; + const aiVector3D *const pvEnd = mesh->mVertices + mesh->mNumVertices; + aiVector3D *pvCurrent = mesh->mVertices, *t2 = mesh->mNormals; for (; pvCurrent != pvEnd; ++pvCurrent, ++t2) { *pvCurrent = mInv * (*pvCurrent); @@ -492,8 +452,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, } // Handle negative transformation matrix determinant -> invert vertex x - if (imesh->mMat.Determinant() < 0.0f) - { + if (imesh->mMat.Determinant() < 0.0f) { /* we *must* have normals */ for (pvCurrent = mesh->mVertices, t2 = mesh->mNormals; pvCurrent != pvEnd; ++pvCurrent, ++t2) { pvCurrent->x *= -1.f; @@ -503,17 +462,15 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, } // Handle pivot point - if (pivot.x || pivot.y || pivot.z) - { - for (pvCurrent = mesh->mVertices; pvCurrent != pvEnd; ++pvCurrent) { + if (pivot.x || pivot.y || pivot.z) { + for (pvCurrent = mesh->mVertices; pvCurrent != pvEnd; ++pvCurrent) { *pvCurrent -= pivot; } } - mesh->mColors[1] = (aiColor4D*)1; - } - else - mesh->mColors[1] = (aiColor4D*)1; + mesh->mColors[1] = (aiColor4D *)1; + } else + mesh->mColors[1] = (aiColor4D *)1; // Setup the mesh index pcOut->mMeshes[i] = iIndex; @@ -522,84 +479,81 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, // Setup the name of the node // First instance keeps its name otherwise something might break, all others will be postfixed with their instance number - if (pcIn->mInstanceNumber > 1) - { + if (pcIn->mInstanceNumber > 1) { char tmp[12]; ASSIMP_itoa10(tmp, pcIn->mInstanceNumber); std::string tempStr = pcIn->mName + "_inst_"; tempStr += tmp; pcOut->mName.Set(tempStr); - } - else + } else pcOut->mName.Set(pcIn->mName); // Now build the transformation matrix of the node // ROTATION - if (pcIn->aRotationKeys.size()){ + if (pcIn->aRotationKeys.size()) { // FIX to get to Assimp's quaternion conventions for (std::vector::iterator it = pcIn->aRotationKeys.begin(); it != pcIn->aRotationKeys.end(); ++it) { (*it).mValue.w *= -1.f; } - pcOut->mTransformation = aiMatrix4x4( pcIn->aRotationKeys[0].mValue.GetMatrix() ); - } - else if (pcIn->aCameraRollKeys.size()) - { - aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(- pcIn->aCameraRollKeys[0].mValue), - pcOut->mTransformation); + pcOut->mTransformation = aiMatrix4x4(pcIn->aRotationKeys[0].mValue.GetMatrix()); + } else if (pcIn->aCameraRollKeys.size()) { + aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(-pcIn->aCameraRollKeys[0].mValue), + pcOut->mTransformation); } // SCALING - aiMatrix4x4& m = pcOut->mTransformation; - if (pcIn->aScalingKeys.size()) - { - const aiVector3D& v = pcIn->aScalingKeys[0].mValue; - m.a1 *= v.x; m.b1 *= v.x; m.c1 *= v.x; - m.a2 *= v.y; m.b2 *= v.y; m.c2 *= v.y; - m.a3 *= v.z; m.b3 *= v.z; m.c3 *= v.z; + aiMatrix4x4 &m = pcOut->mTransformation; + if (pcIn->aScalingKeys.size()) { + const aiVector3D &v = pcIn->aScalingKeys[0].mValue; + m.a1 *= v.x; + m.b1 *= v.x; + m.c1 *= v.x; + m.a2 *= v.y; + m.b2 *= v.y; + m.c2 *= v.y; + m.a3 *= v.z; + m.b3 *= v.z; + m.c3 *= v.z; } // TRANSLATION - if (pcIn->aPositionKeys.size()) - { - const aiVector3D& v = pcIn->aPositionKeys[0].mValue; + if (pcIn->aPositionKeys.size()) { + const aiVector3D &v = pcIn->aPositionKeys[0].mValue; m.a4 += v.x; m.b4 += v.y; m.c4 += v.z; } // Generate animation channels for the node - if (pcIn->aPositionKeys.size() > 1 || pcIn->aRotationKeys.size() > 1 || - pcIn->aScalingKeys.size() > 1 || pcIn->aCameraRollKeys.size() > 1 || - pcIn->aTargetPositionKeys.size() > 1) - { - aiAnimation* anim = pcSOut->mAnimations[0]; + if (pcIn->aPositionKeys.size() > 1 || pcIn->aRotationKeys.size() > 1 || + pcIn->aScalingKeys.size() > 1 || pcIn->aCameraRollKeys.size() > 1 || + pcIn->aTargetPositionKeys.size() > 1) { + aiAnimation *anim = pcSOut->mAnimations[0]; ai_assert(nullptr != anim); - if (pcIn->aCameraRollKeys.size() > 1) - { - ASSIMP_LOG_DEBUG("3DS: Converting camera roll track ..."); + if (pcIn->aCameraRollKeys.size() > 1) { + ASSIMP_LOG_VERBOSE_DEBUG("3DS: Converting camera roll track ..."); // Camera roll keys - in fact they're just rotations // around the camera's z axis. The angles are given // in degrees (and they're clockwise). pcIn->aRotationKeys.resize(pcIn->aCameraRollKeys.size()); - for (unsigned int i = 0; i < pcIn->aCameraRollKeys.size();++i) - { - aiQuatKey& q = pcIn->aRotationKeys[i]; - aiFloatKey& f = pcIn->aCameraRollKeys[i]; + for (unsigned int i = 0; i < pcIn->aCameraRollKeys.size(); ++i) { + aiQuatKey &q = pcIn->aRotationKeys[i]; + aiFloatKey &f = pcIn->aCameraRollKeys[i]; - q.mTime = f.mTime; + q.mTime = f.mTime; // FIX to get to Assimp quaternion conventions - q.mValue = aiQuaternion(0.f,0.f,AI_DEG_TO_RAD( /*-*/ f.mValue)); + q.mValue = aiQuaternion(0.f, 0.f, AI_DEG_TO_RAD(/*-*/ f.mValue)); } } #if 0 if (pcIn->aTargetPositionKeys.size() > 1) { - ASSIMP_LOG_DEBUG("3DS: Converting target track ..."); + ASSIMP_LOG_VERBOSE_DEBUG("3DS: Converting target track ..."); // Camera or spot light - need to convert the separate // target position channel to our representation @@ -639,102 +593,93 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, // Cameras or lights define their transformation in their parent node and in the // corresponding light or camera chunks. However, we read and process the latter // to to be able to return valid cameras/lights even if no scenegraph is given. - for (unsigned int n = 0; n < pcSOut->mNumCameras;++n) { + for (unsigned int n = 0; n < pcSOut->mNumCameras; ++n) { if (pcSOut->mCameras[n]->mName == pcOut->mName) { - pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f,0.f,1.f); + pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f, 0.f, 1.f); } } - for (unsigned int n = 0; n < pcSOut->mNumLights;++n) { + for (unsigned int n = 0; n < pcSOut->mNumLights; ++n) { if (pcSOut->mLights[n]->mName == pcOut->mName) { - pcSOut->mLights[n]->mDirection = aiVector3D(0.f,0.f,1.f); + pcSOut->mLights[n]->mDirection = aiVector3D(0.f, 0.f, 1.f); } } // Allocate a new node anim and setup its name - aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim(); + aiNodeAnim *nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim(); nda->mNodeName.Set(pcIn->mName); // POSITION keys - if (pcIn->aPositionKeys.size() > 0) - { + if (pcIn->aPositionKeys.size() > 0) { nda->mNumPositionKeys = (unsigned int)pcIn->aPositionKeys.size(); nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys]; - ::memcpy(nda->mPositionKeys,&pcIn->aPositionKeys[0], - sizeof(aiVectorKey)*nda->mNumPositionKeys); + ::memcpy(nda->mPositionKeys, &pcIn->aPositionKeys[0], + sizeof(aiVectorKey) * nda->mNumPositionKeys); } // ROTATION keys - if (pcIn->aRotationKeys.size() > 0) - { + if (pcIn->aRotationKeys.size() > 0) { nda->mNumRotationKeys = (unsigned int)pcIn->aRotationKeys.size(); nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys]; // Rotations are quaternion offsets aiQuaternion abs1; - for (unsigned int n = 0; n < nda->mNumRotationKeys;++n) - { - const aiQuatKey& q = pcIn->aRotationKeys[n]; + for (unsigned int n = 0; n < nda->mNumRotationKeys; ++n) { + const aiQuatKey &q = pcIn->aRotationKeys[n]; abs1 = (n ? abs1 * q.mValue : q.mValue); - nda->mRotationKeys[n].mTime = q.mTime; + nda->mRotationKeys[n].mTime = q.mTime; nda->mRotationKeys[n].mValue = abs1.Normalize(); } } // SCALING keys - if (pcIn->aScalingKeys.size() > 0) - { + if (pcIn->aScalingKeys.size() > 0) { nda->mNumScalingKeys = (unsigned int)pcIn->aScalingKeys.size(); nda->mScalingKeys = new aiVectorKey[nda->mNumScalingKeys]; - ::memcpy(nda->mScalingKeys,&pcIn->aScalingKeys[0], - sizeof(aiVectorKey)*nda->mNumScalingKeys); + ::memcpy(nda->mScalingKeys, &pcIn->aScalingKeys[0], + sizeof(aiVectorKey) * nda->mNumScalingKeys); } } // Allocate storage for children pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size(); - pcOut->mChildren = new aiNode*[pcIn->mChildren.size()]; + pcOut->mChildren = new aiNode *[pcIn->mChildren.size()]; // Recursively process all children const unsigned int size = static_cast(pcIn->mChildren.size()); - for (unsigned int i = 0; i < size;++i) - { + for (unsigned int i = 0; i < size; ++i) { pcOut->mChildren[i] = new aiNode(); pcOut->mChildren[i]->mParent = pcOut; - AddNodeToGraph(pcSOut,pcOut->mChildren[i],pcIn->mChildren[i],abs); + AddNodeToGraph(pcSOut, pcOut->mChildren[i], pcIn->mChildren[i], abs); } } // ------------------------------------------------------------------------------------------------ // Find out how many node animation channels we'll have finally -void CountTracks(D3DS::Node* node, unsigned int& cnt) -{ +void CountTracks(D3DS::Node *node, unsigned int &cnt) { ////////////////////////////////////////////////////////////////////////////// // We will never generate more than one channel for a node, so // this is rather easy here. - if (node->aPositionKeys.size() > 1 || node->aRotationKeys.size() > 1 || - node->aScalingKeys.size() > 1 || node->aCameraRollKeys.size() > 1 || - node->aTargetPositionKeys.size() > 1) - { + if (node->aPositionKeys.size() > 1 || node->aRotationKeys.size() > 1 || + node->aScalingKeys.size() > 1 || node->aCameraRollKeys.size() > 1 || + node->aTargetPositionKeys.size() > 1) { ++cnt; // account for the additional channel for the camera/spotlight target position - if (node->aTargetPositionKeys.size() > 1)++cnt; + if (node->aTargetPositionKeys.size() > 1) ++cnt; } // Recursively process all children - for (unsigned int i = 0; i < node->mChildren.size();++i) - CountTracks(node->mChildren[i],cnt); + for (unsigned int i = 0; i < node->mChildren.size(); ++i) + CountTracks(node->mChildren[i], cnt); } // ------------------------------------------------------------------------------------------------ // Generate the output node graph -void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut) -{ +void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) { pcOut->mRootNode = new aiNode(); - if (0 == mRootNode->mChildren.size()) - { + if (0 == mRootNode->mChildren.size()) { ////////////////////////////////////////////////////////////////////////////// // It seems the file is so messed up that it has not even a hierarchy. // generate a flat hiearachy which looks like this: @@ -748,29 +693,27 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut) ASSIMP_LOG_WARN("No hierarchy information has been found in the file. "); pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes + - static_cast(mScene->mCameras.size() + mScene->mLights.size()); + static_cast(mScene->mCameras.size() + mScene->mLights.size()); - pcOut->mRootNode->mChildren = new aiNode* [ pcOut->mRootNode->mNumChildren ]; + pcOut->mRootNode->mChildren = new aiNode *[pcOut->mRootNode->mNumChildren]; pcOut->mRootNode->mName.Set("<3DSDummyRoot>"); // Build dummy nodes for all meshes unsigned int a = 0; - for (unsigned int i = 0; i < pcOut->mNumMeshes;++i,++a) - { - aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode(); + for (unsigned int i = 0; i < pcOut->mNumMeshes; ++i, ++a) { + aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode(); pcNode->mParent = pcOut->mRootNode; pcNode->mMeshes = new unsigned int[1]; pcNode->mMeshes[0] = i; pcNode->mNumMeshes = 1; // Build a name for the node - pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "3DSMesh_%u",i); + pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "3DSMesh_%u", i); } // Build dummy nodes for all cameras - for (unsigned int i = 0; i < (unsigned int )mScene->mCameras.size();++i,++a) - { - aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode(); + for (unsigned int i = 0; i < (unsigned int)mScene->mCameras.size(); ++i, ++a) { + aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode(); pcNode->mParent = pcOut->mRootNode; // Build a name for the node @@ -778,75 +721,68 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut) } // Build dummy nodes for all lights - for (unsigned int i = 0; i < (unsigned int )mScene->mLights.size();++i,++a) - { - aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode(); + for (unsigned int i = 0; i < (unsigned int)mScene->mLights.size(); ++i, ++a) { + aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode(); pcNode->mParent = pcOut->mRootNode; // Build a name for the node pcNode->mName = mScene->mLights[i]->mName; } - } - else - { + } else { // First of all: find out how many scaling, rotation and translation // animation tracks we'll have afterwards unsigned int numChannel = 0; - CountTracks(mRootNode,numChannel); + CountTracks(mRootNode, numChannel); - if (numChannel) - { + if (numChannel) { // Allocate a primary animation channel pcOut->mNumAnimations = 1; - pcOut->mAnimations = new aiAnimation*[1]; - aiAnimation* anim = pcOut->mAnimations[0] = new aiAnimation(); + pcOut->mAnimations = new aiAnimation *[1]; + aiAnimation *anim = pcOut->mAnimations[0] = new aiAnimation(); anim->mName.Set("3DSMasterAnim"); // Allocate enough storage for all node animation channels, // but don't set the mNumChannels member - we'll use it to // index into the array - anim->mChannels = new aiNodeAnim*[numChannel]; + anim->mChannels = new aiNodeAnim *[numChannel]; } aiMatrix4x4 m; - AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode,m); + AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode, m); } // We used the first and second vertex color set to store some temporary values so we need to cleanup here - for (unsigned int a = 0; a < pcOut->mNumMeshes; ++a) - { - pcOut->mMeshes[a]->mColors[0] = NULL; - pcOut->mMeshes[a]->mColors[1] = NULL; + for (unsigned int a = 0; a < pcOut->mNumMeshes; ++a) { + pcOut->mMeshes[a]->mColors[0] = nullptr; + pcOut->mMeshes[a]->mColors[1] = nullptr; } pcOut->mRootNode->mTransformation = aiMatrix4x4( - 1.f,0.f,0.f,0.f, - 0.f,0.f,1.f,0.f, - 0.f,-1.f,0.f,0.f, - 0.f,0.f,0.f,1.f) * pcOut->mRootNode->mTransformation; + 1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, -1.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f) * + pcOut->mRootNode->mTransformation; // If the root node is unnamed name it "<3DSRoot>" - if (::strstr( pcOut->mRootNode->mName.data, "UNNAMED" ) || - (pcOut->mRootNode->mName.data[0] == '$' && pcOut->mRootNode->mName.data[1] == '$') ) - { + if (::strstr(pcOut->mRootNode->mName.data, "UNNAMED") || + (pcOut->mRootNode->mName.data[0] == '$' && pcOut->mRootNode->mName.data[1] == '$')) { pcOut->mRootNode->mName.Set("<3DSRoot>"); } } // ------------------------------------------------------------------------------------------------ // Convert all meshes in the scene and generate the final output scene. -void Discreet3DSImporter::ConvertScene(aiScene* pcOut) -{ +void Discreet3DSImporter::ConvertScene(aiScene *pcOut) { // Allocate enough storage for all output materials pcOut->mNumMaterials = (unsigned int)mScene->mMaterials.size(); - pcOut->mMaterials = new aiMaterial*[pcOut->mNumMaterials]; + pcOut->mMaterials = new aiMaterial *[pcOut->mNumMaterials]; // ... and convert the 3DS materials to aiMaterial's - for (unsigned int i = 0; i < pcOut->mNumMaterials;++i) - { - aiMaterial* pcNew = new aiMaterial(); - ConvertMaterial(mScene->mMaterials[i],*pcNew); + for (unsigned int i = 0; i < pcOut->mNumMaterials; ++i) { + aiMaterial *pcNew = new aiMaterial(); + ConvertMaterial(mScene->mMaterials[i], *pcNew); pcOut->mMaterials[i] = pcNew; } @@ -855,18 +791,16 @@ void Discreet3DSImporter::ConvertScene(aiScene* pcOut) // Now copy all light sources to the output scene pcOut->mNumLights = (unsigned int)mScene->mLights.size(); - if (pcOut->mNumLights) - { - pcOut->mLights = new aiLight*[pcOut->mNumLights]; - ::memcpy(pcOut->mLights,&mScene->mLights[0],sizeof(void*)*pcOut->mNumLights); + if (pcOut->mNumLights) { + pcOut->mLights = new aiLight *[pcOut->mNumLights]; + ::memcpy(pcOut->mLights, &mScene->mLights[0], sizeof(void *) * pcOut->mNumLights); } // Now copy all cameras to the output scene pcOut->mNumCameras = (unsigned int)mScene->mCameras.size(); - if (pcOut->mNumCameras) - { - pcOut->mCameras = new aiCamera*[pcOut->mNumCameras]; - ::memcpy(pcOut->mCameras,&mScene->mCameras[0],sizeof(void*)*pcOut->mNumCameras); + if (pcOut->mNumCameras) { + pcOut->mCameras = new aiCamera *[pcOut->mNumCameras]; + ::memcpy(pcOut->mCameras, &mScene->mCameras[0], sizeof(void *) * pcOut->mNumCameras); } } diff --git a/Engine/lib/assimp/code/3DS/3DSExporter.cpp b/Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.cpp similarity index 65% rename from Engine/lib/assimp/code/3DS/3DSExporter.cpp rename to Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.cpp index 1117a52ef..71588f935 100644 --- a/Engine/lib/assimp/code/3DS/3DSExporter.cpp +++ b/Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.cpp @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -43,120 +43,118 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_3DS_EXPORTER -#include "3DS/3DSExporter.h" -#include "3DS/3DSLoader.h" -#include "3DS/3DSHelper.h" +#include "AssetLib/3DS/3DSExporter.h" +#include "AssetLib/3DS/3DSHelper.h" +#include "AssetLib/3DS/3DSLoader.h" #include "PostProcessing/SplitLargeMeshes.h" #include #include -#include #include #include +#include #include -using namespace Assimp; -namespace Assimp { +namespace Assimp { + using namespace D3DS; namespace { - ////////////////////////////////////////////////////////////////////////////////////// - // Scope utility to write a 3DS file chunk. - // - // Upon construction, the chunk header is written with the chunk type (flags) - // filled out, but the chunk size left empty. Upon destruction, the correct chunk - // size based on the then-position of the output stream cursor is filled in. - class ChunkWriter { - enum { - CHUNK_SIZE_NOT_SET = 0xdeadbeef - , SIZE_OFFSET = 2 - }; - public: - - ChunkWriter(StreamWriterLE& writer, uint16_t chunk_type) - : writer(writer) - { - chunk_start_pos = writer.GetCurrentPos(); - writer.PutU2(chunk_type); - writer.PutU4(CHUNK_SIZE_NOT_SET); - } - - ~ChunkWriter() { - std::size_t head_pos = writer.GetCurrentPos(); - - ai_assert(head_pos > chunk_start_pos); - const std::size_t chunk_size = head_pos - chunk_start_pos; - - writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET); - writer.PutU4(static_cast(chunk_size)); - writer.SetCurrentPos(head_pos); - } - - private: - StreamWriterLE& writer; - std::size_t chunk_start_pos; +////////////////////////////////////////////////////////////////////////////////////// +// Scope utility to write a 3DS file chunk. +// +// Upon construction, the chunk header is written with the chunk type (flags) +// filled out, but the chunk size left empty. Upon destruction, the correct chunk +// size based on the then-position of the output stream cursor is filled in. +class ChunkWriter { + enum { + CHUNK_SIZE_NOT_SET = 0xdeadbeef, + SIZE_OFFSET = 2 }; - - // Return an unique name for a given |mesh| attached to |node| that - // preserves the mesh's given name if it has one. |index| is the index - // of the mesh in |aiScene::mMeshes|. - std::string GetMeshName(const aiMesh& mesh, unsigned int index, const aiNode& node) { - static const std::string underscore = "_"; - char postfix[10] = {0}; - ASSIMP_itoa10(postfix, index); - - std::string result = node.mName.C_Str(); - if (mesh.mName.length > 0) { - result += underscore + mesh.mName.C_Str(); - } - return result + underscore + postfix; +public: + ChunkWriter(StreamWriterLE &writer, uint16_t chunk_type) : + writer(writer) { + chunk_start_pos = writer.GetCurrentPos(); + writer.PutU2(chunk_type); + writer.PutU4((uint32_t)CHUNK_SIZE_NOT_SET); } - // Return an unique name for a given |mat| with original position |index| - // in |aiScene::mMaterials|. The name preserves the original material - // name if possible. - std::string GetMaterialName(const aiMaterial& mat, unsigned int index) { - static const std::string underscore = "_"; - char postfix[10] = {0}; - ASSIMP_itoa10(postfix, index); + ~ChunkWriter() { + std::size_t head_pos = writer.GetCurrentPos(); - aiString mat_name; - if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) { - return mat_name.C_Str() + underscore + postfix; - } + ai_assert(head_pos > chunk_start_pos); + const std::size_t chunk_size = head_pos - chunk_start_pos; - return "Material" + underscore + postfix; + writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET); + writer.PutU4(static_cast(chunk_size)); + writer.SetCurrentPos(head_pos); } - // Collect world transformations for each node - void CollectTrafos(const aiNode* node, std::map& trafos) { - const aiMatrix4x4& parent = node->mParent ? trafos[node->mParent] : aiMatrix4x4(); - trafos[node] = parent * node->mTransformation; - for (unsigned int i = 0; i < node->mNumChildren; ++i) { - CollectTrafos(node->mChildren[i], trafos); - } +private: + StreamWriterLE &writer; + std::size_t chunk_start_pos; +}; + +// Return an unique name for a given |mesh| attached to |node| that +// preserves the mesh's given name if it has one. |index| is the index +// of the mesh in |aiScene::mMeshes|. +std::string GetMeshName(const aiMesh &mesh, unsigned int index, const aiNode &node) { + static const char underscore = '_'; + char postfix[10] = { 0 }; + ASSIMP_itoa10(postfix, index); + + std::string result = node.mName.C_Str(); + if (mesh.mName.length > 0) { + result += underscore; + result += mesh.mName.C_Str(); + } + return result + underscore + postfix; +} + +// Return an unique name for a given |mat| with original position |index| +// in |aiScene::mMaterials|. The name preserves the original material +// name if possible. +std::string GetMaterialName(const aiMaterial &mat, unsigned int index) { + static const std::string underscore = "_"; + char postfix[10] = { 0 }; + ASSIMP_itoa10(postfix, index); + + aiString mat_name; + if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) { + return mat_name.C_Str() + underscore + postfix; } - // Generate a flat list of the meshes (by index) assigned to each node - void CollectMeshes(const aiNode* node, std::multimap& meshes) { - for (unsigned int i = 0; i < node->mNumMeshes; ++i) { - meshes.insert(std::make_pair(node, node->mMeshes[i])); - } - for (unsigned int i = 0; i < node->mNumChildren; ++i) { - CollectMeshes(node->mChildren[i], meshes); - } + return "Material" + underscore + postfix; +} + +// Collect world transformations for each node +void CollectTrafos(const aiNode *node, std::map &trafos) { + const aiMatrix4x4 &parent = node->mParent ? trafos[node->mParent] : aiMatrix4x4(); + trafos[node] = parent * node->mTransformation; + for (unsigned int i = 0; i < node->mNumChildren; ++i) { + CollectTrafos(node->mChildren[i], trafos); } } +// Generate a flat list of the meshes (by index) assigned to each node +void CollectMeshes(const aiNode *node, std::multimap &meshes) { + for (unsigned int i = 0; i < node->mNumMeshes; ++i) { + meshes.insert(std::make_pair(node, node->mMeshes[i])); + } + for (unsigned int i = 0; i < node->mNumChildren; ++i) { + CollectMeshes(node->mChildren[i], meshes); + } +} +} // namespace + // ------------------------------------------------------------------------------------------------ // Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp -void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) -{ - std::shared_ptr outfile (pIOSystem->Open(pFile, "wb")); - if(!outfile) { +void ExportScene3DS(const char *pFile, IOSystem *pIOSystem, const aiScene *pScene, const ExportProperties * /*pProperties*/) { + std::shared_ptr outfile(pIOSystem->Open(pFile, "wb")); + if (!outfile) { throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile)); } @@ -167,8 +165,8 @@ void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScen // SplitLargeMeshes can do this, but it requires the correct limit to be set // which is not possible with the current way of specifying preprocess steps // in |Exporter::ExportFormatEntry|. - aiScene* scenecopy_tmp; - SceneCombiner::CopyScene(&scenecopy_tmp,pScene); + aiScene *scenecopy_tmp; + SceneCombiner::CopyScene(&scenecopy_tmp, pScene); std::unique_ptr scenecopy(scenecopy_tmp); SplitLargeMeshesProcess_Triangle tri_splitter; @@ -186,28 +184,26 @@ void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScen } // end of namespace Assimp // ------------------------------------------------------------------------------------------------ -Discreet3DSExporter:: Discreet3DSExporter(std::shared_ptr &outfile, const aiScene* scene) -: scene(scene) -, writer(outfile) -{ +Discreet3DSExporter::Discreet3DSExporter(std::shared_ptr &outfile, const aiScene *scene) : + scene(scene), writer(outfile) { CollectTrafos(scene->mRootNode, trafos); CollectMeshes(scene->mRootNode, meshes); - ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAIN); + ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_MAIN); { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_OBJMESH); WriteMaterials(); WriteMeshes(); { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE); + ChunkWriter curChunk1(writer, Discreet3DS::CHUNK_MASTER_SCALE); writer.PutF4(1.0f); } } { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_KEYFRAMER); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_KEYFRAMER); WriteHierarchy(*scene->mRootNode, -1, -1); } } @@ -217,15 +213,13 @@ Discreet3DSExporter::~Discreet3DSExporter() { // empty } - // ------------------------------------------------------------------------------------------------ -int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling_level) -{ +int Discreet3DSExporter::WriteHierarchy(const aiNode &node, int seq, int sibling_level) { // 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO); + ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_TRACKINFO); { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME); // Assimp node names are unique and distinct from all mesh-node // names we generate; thus we can use them as-is @@ -237,7 +231,7 @@ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling int16_t hierarchy_pos = static_cast(seq); if (sibling_level != -1) { - hierarchy_pos = sibling_level; + hierarchy_pos = (uint16_t)sibling_level; } // Write the hierarchy position @@ -260,9 +254,9 @@ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling const bool first_child = node.mNumChildren == 0 && i == 0; const unsigned int mesh_idx = node.mMeshes[i]; - const aiMesh& mesh = *scene->mMeshes[mesh_idx]; + const aiMesh &mesh = *scene->mMeshes[mesh_idx]; - ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRACKINFO); { ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME); WriteString(GetMeshName(mesh, mesh_idx, node)); @@ -276,36 +270,41 @@ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling } // ------------------------------------------------------------------------------------------------ -void Discreet3DSExporter::WriteMaterials() -{ +void Discreet3DSExporter::WriteMaterials() { for (unsigned int i = 0; i < scene->mNumMaterials; ++i) { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL); - const aiMaterial& mat = *scene->mMaterials[i]; + ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL); + const aiMaterial &mat = *scene->mMaterials[i]; { ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATNAME); - const std::string& name = GetMaterialName(mat, i); + const std::string &name = GetMaterialName(mat, i); WriteString(name); } aiColor3D color; if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE); WriteColor(color); } if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR); WriteColor(color); } if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT); WriteColor(color); } + float f; + if (mat.Get(AI_MATKEY_OPACITY, f) == AI_SUCCESS) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TRANSPARENCY); + WritePercentChunk(1.0f - f); + } + if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM); WriteColor(color); } @@ -314,7 +313,7 @@ void Discreet3DSExporter::WriteMaterials() ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING); Discreet3DS::shadetype3ds shading_mode_out; - switch(shading_mode) { + switch (shading_mode) { case aiShadingMode_Flat: case aiShadingMode_NoShading: shading_mode_out = Discreet3DS::Flat; @@ -331,6 +330,7 @@ void Discreet3DSExporter::WriteMaterials() case aiShadingMode_Blinn: case aiShadingMode_CookTorrance: case aiShadingMode_Fresnel: + case aiShadingMode_PBR_BRDF: // Possibly should be Discreet3DS::Metal in some cases but this is undocumented shading_mode_out = Discreet3DS::Phong; break; @@ -341,8 +341,6 @@ void Discreet3DSExporter::WriteMaterials() writer.PutU2(static_cast(shading_mode_out)); } - - float f; if (mat.Get(AI_MATKEY_SHININESS, f) == AI_SUCCESS) { ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS); WritePercentChunk(f); @@ -359,7 +357,10 @@ void Discreet3DSExporter::WriteMaterials() writer.PutI2(1); } - WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE); + // Fallback to BASE_COLOR if no DIFFUSE + if (!WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE)) + WriteTexture(mat, aiTextureType_BASE_COLOR, Discreet3DS::CHUNK_MAT_TEXTURE); + WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP); WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP); WriteTexture(mat, aiTextureType_SHININESS, Discreet3DS::CHUNK_MAT_MAT_SHINMAP); @@ -370,48 +371,47 @@ void Discreet3DSExporter::WriteMaterials() } // ------------------------------------------------------------------------------------------------ -void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags) -{ +// returns true if the texture existed +bool Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type, uint16_t chunk_flags) { aiString path; aiTextureMapMode map_mode[2] = { aiTextureMapMode_Wrap, aiTextureMapMode_Wrap }; ai_real blend = 1.0; - if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) { - return; + if (mat.GetTexture(type, 0, &path, nullptr, nullptr, &blend, nullptr, map_mode) != AI_SUCCESS || !path.length) { + return false; } // TODO: handle embedded textures properly if (path.data[0] == '*') { - ASSIMP_LOG_ERROR("Ignoring embedded texture for export: " + std::string(path.C_Str())); - return; + ASSIMP_LOG_ERROR("Ignoring embedded texture for export: ", path.C_Str()); + return false; } ChunkWriter chunk(writer, chunk_flags); { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPFILE); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAPFILE); WriteString(path); } WritePercentChunk(blend); { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING); uint16_t val = 0; // WRAP if (map_mode[0] == aiTextureMapMode_Mirror) { val = 0x2; - } - else if (map_mode[0] == aiTextureMapMode_Decal) { + } else if (map_mode[0] == aiTextureMapMode_Decal) { val = 0x10; } writer.PutU2(val); } // TODO: export texture transformation (i.e. UV offset, scale, rotation) + return true; } // ------------------------------------------------------------------------------------------------ -void Discreet3DSExporter::WriteMeshes() -{ +void Discreet3DSExporter::WriteMeshes() { // NOTE: 3DS allows for instances. However: // i) not all importers support reading them // ii) instances are not as flexible as they are in assimp, in particular, @@ -423,36 +423,35 @@ void Discreet3DSExporter::WriteMeshes() // Furthermore, the TRIMESH is transformed into world space so that it will // appear correctly if importers don't read the scene hierarchy at all. for (MeshesByNodeMap::const_iterator it = meshes.begin(); it != meshes.end(); ++it) { - const aiNode& node = *(*it).first; + const aiNode &node = *(*it).first; const unsigned int mesh_idx = (*it).second; - const aiMesh& mesh = *scene->mMeshes[mesh_idx]; + const aiMesh &mesh = *scene->mMeshes[mesh_idx]; // This should not happen if the SLM step is correctly executed // before the scene is handed to the exporter ai_assert(mesh.mNumVertices <= 0xffff); ai_assert(mesh.mNumFaces <= 0xffff); - const aiMatrix4x4& trafo = trafos[&node]; + const aiMatrix4x4 &trafo = trafos[&node]; ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJBLOCK); // Mesh name is tied to the node it is attached to so it can later be referenced - const std::string& name = GetMeshName(mesh, mesh_idx, node); + const std::string &name = GetMeshName(mesh, mesh_idx, node); WriteString(name); - // TRIMESH chunk ChunkWriter chunk2(writer, Discreet3DS::CHUNK_TRIMESH); // Vertices in world space { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_VERTLIST); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_VERTLIST); const uint16_t count = static_cast(mesh.mNumVertices); writer.PutU2(count); for (unsigned int i = 0; i < mesh.mNumVertices; ++i) { - const aiVector3D& v = trafo * mesh.mVertices[i]; + const aiVector3D &v = mesh.mVertices[i]; writer.PutF4(v.x); writer.PutF4(v.y); writer.PutF4(v.z); @@ -461,12 +460,12 @@ void Discreet3DSExporter::WriteMeshes() // UV coordinates if (mesh.HasTextureCoords(0)) { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPLIST); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAPLIST); const uint16_t count = static_cast(mesh.mNumVertices); writer.PutU2(count); for (unsigned int i = 0; i < mesh.mNumVertices; ++i) { - const aiVector3D& v = mesh.mTextureCoords[0][i]; + const aiVector3D &v = mesh.mTextureCoords[0][i]; writer.PutF4(v.x); writer.PutF4(v.y); } @@ -474,14 +473,14 @@ void Discreet3DSExporter::WriteMeshes() // Faces (indices) { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACELIST); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_FACELIST); ai_assert(mesh.mNumFaces <= 0xffff); // Count triangles, discard lines and points uint16_t count = 0; for (unsigned int i = 0; i < mesh.mNumFaces; ++i) { - const aiFace& f = mesh.mFaces[i]; + const aiFace &f = mesh.mFaces[i]; if (f.mNumIndices < 3) { continue; } @@ -492,7 +491,7 @@ void Discreet3DSExporter::WriteMeshes() writer.PutU2(count); for (unsigned int i = 0; i < mesh.mNumFaces; ++i) { - const aiFace& f = mesh.mFaces[i]; + const aiFace &f = mesh.mFaces[i]; if (f.mNumIndices < 3) { continue; } @@ -513,21 +512,25 @@ void Discreet3DSExporter::WriteMeshes() // Transformation matrix by which the mesh vertices have been pre-transformed with. { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRMATRIX); - for (unsigned int r = 0; r < 4; ++r) { + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRMATRIX); + // Store rotation 3x3 matrix row wise + for (unsigned int r = 0; r < 3; ++r) { for (unsigned int c = 0; c < 3; ++c) { writer.PutF4(trafo[r][c]); } } + // Store translation sub vector column wise + for (unsigned int r = 0; r < 3; ++r) { + writer.PutF4(trafo[r][3]); + } } } } // ------------------------------------------------------------------------------------------------ -void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh) -{ - ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACEMAT); - const std::string& name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex); +void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh &mesh) { + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_FACEMAT); + const std::string &name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex); WriteString(name); // Because assimp splits meshes by material, only a single @@ -542,7 +545,7 @@ void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh) } // ------------------------------------------------------------------------------------------------ -void Discreet3DSExporter::WriteString(const std::string& s) { +void Discreet3DSExporter::WriteString(const std::string &s) { for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) { writer.PutI1(*it); } @@ -550,7 +553,7 @@ void Discreet3DSExporter::WriteString(const std::string& s) { } // ------------------------------------------------------------------------------------------------ -void Discreet3DSExporter::WriteString(const aiString& s) { +void Discreet3DSExporter::WriteString(const aiString &s) { for (std::size_t i = 0; i < s.length; ++i) { writer.PutI1(s.data[i]); } @@ -558,8 +561,8 @@ void Discreet3DSExporter::WriteString(const aiString& s) { } // ------------------------------------------------------------------------------------------------ -void Discreet3DSExporter::WriteColor(const aiColor3D& color) { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_RGBF); +void Discreet3DSExporter::WriteColor(const aiColor3D &color) { + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_RGBF); writer.PutF4(color.r); writer.PutF4(color.g); writer.PutF4(color.b); @@ -567,16 +570,15 @@ void Discreet3DSExporter::WriteColor(const aiColor3D& color) { // ------------------------------------------------------------------------------------------------ void Discreet3DSExporter::WritePercentChunk(float f) { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTF); + ChunkWriter curChunk(writer, Discreet3DS::CHUNK_PERCENTF); writer.PutF4(f); } // ------------------------------------------------------------------------------------------------ void Discreet3DSExporter::WritePercentChunk(double f) { - ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTD); + ChunkWriter ccurChunkhunk(writer, Discreet3DS::CHUNK_PERCENTD); writer.PutF8(f); } - #endif // ASSIMP_BUILD_NO_3DS_EXPORTER #endif // ASSIMP_BUILD_NO_EXPORT diff --git a/Engine/lib/assimp/code/3DS/3DSExporter.h b/Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.h similarity index 96% rename from Engine/lib/assimp/code/3DS/3DSExporter.h rename to Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.h index 035b562cf..82ec3512f 100644 --- a/Engine/lib/assimp/code/3DS/3DSExporter.h +++ b/Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.h @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -73,7 +73,7 @@ public: private: void WriteMeshes(); void WriteMaterials(); - void WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags); + bool WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags); void WriteFaceMaterialChunk(const aiMesh& mesh); int WriteHierarchy(const aiNode& node, int level, int sibling_level); void WriteString(const std::string& s); diff --git a/Engine/lib/assimp/code/AssetLib/3DS/3DSHelper.h b/Engine/lib/assimp/code/AssetLib/3DS/3DSHelper.h new file mode 100644 index 000000000..dc1098035 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/3DS/3DSHelper.h @@ -0,0 +1,702 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Defines helper data structures for the import of 3DS files */ + +#ifndef AI_3DSFILEHELPER_H_INC +#define AI_3DSFILEHELPER_H_INC + +#include +#include +#include +#include +#include +#include +#include +#include +#include //sprintf + +namespace Assimp { +namespace D3DS { + +#include + +// --------------------------------------------------------------------------- +/** Defines chunks and data structures. +*/ +namespace Discreet3DS { + + //! data structure for a single chunk in a .3ds file + struct Chunk { + uint16_t Flag; + uint32_t Size; + } PACK_STRUCT; + + //! Used for shading field in material3ds structure + //! From AutoDesk 3ds SDK + typedef enum { + // translated to gouraud shading with wireframe active + Wire = 0x0, + + // if this material is set, no vertex normals will + // be calculated for the model. Face normals + gouraud + Flat = 0x1, + + // standard gouraud shading + Gouraud = 0x2, + + // phong shading + Phong = 0x3, + + // cooktorrance or anistropic phong shading ... + // the exact meaning is unknown, if you know it + // feel free to tell me ;-) + Metal = 0x4, + + // required by the ASE loader + Blinn = 0x5 + } shadetype3ds; + + // Flags for animated keys + enum { + KEY_USE_TENS = 0x1, + KEY_USE_CONT = 0x2, + KEY_USE_BIAS = 0x4, + KEY_USE_EASE_TO = 0x8, + KEY_USE_EASE_FROM = 0x10 + }; + + enum { + + // ******************************************************************** + // Basic chunks which can be found everywhere in the file + CHUNK_VERSION = 0x0002, + CHUNK_RGBF = 0x0010, // float4 R; float4 G; float4 B + CHUNK_RGBB = 0x0011, // int1 R; int1 G; int B + + // Linear color values (gamma = 2.2?) + CHUNK_LINRGBF = 0x0013, // float4 R; float4 G; float4 B + CHUNK_LINRGBB = 0x0012, // int1 R; int1 G; int B + + CHUNK_PERCENTW = 0x0030, // int2 percentage + CHUNK_PERCENTF = 0x0031, // float4 percentage + CHUNK_PERCENTD = 0x0032, // float8 percentage + // ******************************************************************** + + // Prj master chunk + CHUNK_PRJ = 0xC23D, + + // MDLI master chunk + CHUNK_MLI = 0x3DAA, + + // Primary main chunk of the .3ds file + CHUNK_MAIN = 0x4D4D, + + // Mesh main chunk + CHUNK_OBJMESH = 0x3D3D, + + // Specifies the background color of the .3ds file + // This is passed through the material system for + // viewing purposes. + CHUNK_BKGCOLOR = 0x1200, + + // Specifies the ambient base color of the scene. + // This is added to all materials in the file + CHUNK_AMBCOLOR = 0x2100, + + // Specifies the background image for the whole scene + // This value is passed through the material system + // to the viewer + CHUNK_BIT_MAP = 0x1100, + CHUNK_BIT_MAP_EXISTS = 0x1101, + + // ******************************************************************** + // Viewport related stuff. Ignored + CHUNK_DEFAULT_VIEW = 0x3000, + CHUNK_VIEW_TOP = 0x3010, + CHUNK_VIEW_BOTTOM = 0x3020, + CHUNK_VIEW_LEFT = 0x3030, + CHUNK_VIEW_RIGHT = 0x3040, + CHUNK_VIEW_FRONT = 0x3050, + CHUNK_VIEW_BACK = 0x3060, + CHUNK_VIEW_USER = 0x3070, + CHUNK_VIEW_CAMERA = 0x3080, + // ******************************************************************** + + // Mesh chunks + CHUNK_OBJBLOCK = 0x4000, + CHUNK_TRIMESH = 0x4100, + CHUNK_VERTLIST = 0x4110, + CHUNK_VERTFLAGS = 0x4111, + CHUNK_FACELIST = 0x4120, + CHUNK_FACEMAT = 0x4130, + CHUNK_MAPLIST = 0x4140, + CHUNK_SMOOLIST = 0x4150, + CHUNK_TRMATRIX = 0x4160, + CHUNK_MESHCOLOR = 0x4165, + CHUNK_TXTINFO = 0x4170, + CHUNK_LIGHT = 0x4600, + CHUNK_CAMERA = 0x4700, + CHUNK_HIERARCHY = 0x4F00, + + // Specifies the global scaling factor. This is applied + // to the root node's transformation matrix + CHUNK_MASTER_SCALE = 0x0100, + + // ******************************************************************** + // Material chunks + CHUNK_MAT_MATERIAL = 0xAFFF, + + // asciiz containing the name of the material + CHUNK_MAT_MATNAME = 0xA000, + CHUNK_MAT_AMBIENT = 0xA010, // followed by color chunk + CHUNK_MAT_DIFFUSE = 0xA020, // followed by color chunk + CHUNK_MAT_SPECULAR = 0xA030, // followed by color chunk + + // Specifies the shininess of the material + // followed by percentage chunk + CHUNK_MAT_SHININESS = 0xA040, + CHUNK_MAT_SHININESS_PERCENT = 0xA041, + + // Specifies the shading mode to be used + // followed by a short + CHUNK_MAT_SHADING = 0xA100, + + // NOTE: Emissive color (self illumination) seems not + // to be a color but a single value, type is unknown. + // Make the parser accept both of them. + // followed by percentage chunk (?) + CHUNK_MAT_SELF_ILLUM = 0xA080, + + // Always followed by percentage chunk (?) + CHUNK_MAT_SELF_ILPCT = 0xA084, + + // Always followed by percentage chunk + CHUNK_MAT_TRANSPARENCY = 0xA050, + + // Diffuse texture channel 0 + CHUNK_MAT_TEXTURE = 0xA200, + + // Contains opacity information for each texel + CHUNK_MAT_OPACMAP = 0xA210, + + // Contains a reflection map to be used to reflect + // the environment. This is partially supported. + CHUNK_MAT_REFLMAP = 0xA220, + + // Self Illumination map (emissive colors) + CHUNK_MAT_SELFIMAP = 0xA33d, + + // Bumpmap. Not specified whether it is a heightmap + // or a normal map. Assme it is a heightmap since + // artist normally prefer this format. + CHUNK_MAT_BUMPMAP = 0xA230, + + // Specular map. Seems to influence the specular color + CHUNK_MAT_SPECMAP = 0xA204, + + // Holds shininess data. + CHUNK_MAT_MAT_SHINMAP = 0xA33C, + + // Scaling in U/V direction. + // (need to gen separate UV coordinate set + // and do this by hand) + CHUNK_MAT_MAP_USCALE = 0xA354, + CHUNK_MAT_MAP_VSCALE = 0xA356, + + // Translation in U/V direction. + // (need to gen separate UV coordinate set + // and do this by hand) + CHUNK_MAT_MAP_UOFFSET = 0xA358, + CHUNK_MAT_MAP_VOFFSET = 0xA35a, + + // UV-coordinates rotation around the z-axis + // Assumed to be in radians. + CHUNK_MAT_MAP_ANG = 0xA35C, + + // Tiling flags for 3DS files + CHUNK_MAT_MAP_TILING = 0xa351, + + // Specifies the file name of a texture + CHUNK_MAPFILE = 0xA300, + + // Specifies whether a material requires two-sided rendering + CHUNK_MAT_TWO_SIDE = 0xA081, + // ******************************************************************** + + // Main keyframer chunk. Contains translation/rotation/scaling data + CHUNK_KEYFRAMER = 0xB000, + + // Supported sub chunks + CHUNK_TRACKINFO = 0xB002, + CHUNK_TRACKOBJNAME = 0xB010, + CHUNK_TRACKDUMMYOBJNAME = 0xB011, + CHUNK_TRACKPIVOT = 0xB013, + CHUNK_TRACKPOS = 0xB020, + CHUNK_TRACKROTATE = 0xB021, + CHUNK_TRACKSCALE = 0xB022, + + // ******************************************************************** + // Keyframes for various other stuff in the file + // Partially ignored + CHUNK_AMBIENTKEY = 0xB001, + CHUNK_TRACKMORPH = 0xB026, + CHUNK_TRACKHIDE = 0xB029, + CHUNK_OBJNUMBER = 0xB030, + CHUNK_TRACKCAMERA = 0xB003, + CHUNK_TRACKFOV = 0xB023, + CHUNK_TRACKROLL = 0xB024, + CHUNK_TRACKCAMTGT = 0xB004, + CHUNK_TRACKLIGHT = 0xB005, + CHUNK_TRACKLIGTGT = 0xB006, + CHUNK_TRACKSPOTL = 0xB007, + CHUNK_FRAMES = 0xB008, + // ******************************************************************** + + // light sub-chunks + CHUNK_DL_OFF = 0x4620, + CHUNK_DL_OUTER_RANGE = 0x465A, + CHUNK_DL_INNER_RANGE = 0x4659, + CHUNK_DL_MULTIPLIER = 0x465B, + CHUNK_DL_EXCLUDE = 0x4654, + CHUNK_DL_ATTENUATE = 0x4625, + CHUNK_DL_SPOTLIGHT = 0x4610, + + // camera sub-chunks + CHUNK_CAM_RANGES = 0x4720 + }; +} + +// --------------------------------------------------------------------------- +/** Helper structure representing a 3ds mesh face */ +struct Face : public FaceWithSmoothingGroup { +}; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4315) +#endif // _MSC_VER + +// --------------------------------------------------------------------------- +/** Helper structure representing a texture */ +struct Texture { + //! Default constructor + Texture() AI_NO_EXCEPT + : mTextureBlend(0.0f), + mMapName(), + mOffsetU(0.0), + mOffsetV(0.0), + mScaleU(1.0), + mScaleV(1.0), + mRotation(0.0), + mMapMode(aiTextureMapMode_Wrap), + bPrivate(), + iUVSrc(0) { + mTextureBlend = get_qnan(); + } + + Texture(const Texture &other) : + mTextureBlend(other.mTextureBlend), + mMapName(other.mMapName), + mOffsetU(other.mOffsetU), + mOffsetV(other.mOffsetV), + mScaleU(other.mScaleU), + mScaleV(other.mScaleV), + mRotation(other.mRotation), + mMapMode(other.mMapMode), + bPrivate(other.bPrivate), + iUVSrc(other.iUVSrc) { + // empty + } + + Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(other.mTextureBlend), + mMapName(std::move(other.mMapName)), + mOffsetU(other.mOffsetU), + mOffsetV(other.mOffsetV), + mScaleU(other.mScaleU), + mScaleV(other.mScaleV), + mRotation(other.mRotation), + mMapMode(other.mMapMode), + bPrivate(other.bPrivate), + iUVSrc(other.iUVSrc) { + // empty + } + + Texture &operator=(Texture &&other) AI_NO_EXCEPT { + if (this == &other) { + return *this; + } + + mTextureBlend = other.mTextureBlend; + mMapName = std::move(other.mMapName); + mOffsetU = other.mOffsetU; + mOffsetV = other.mOffsetV; + mScaleU = other.mScaleU; + mScaleV = other.mScaleV; + mRotation = other.mRotation; + mMapMode = other.mMapMode; + bPrivate = other.bPrivate; + iUVSrc = other.iUVSrc; + + return *this; + } + + //! Specifies the blend factor for the texture + ai_real mTextureBlend; + + //! Specifies the filename of the texture + std::string mMapName; + + //! Specifies texture coordinate offsets/scaling/rotations + ai_real mOffsetU; + ai_real mOffsetV; + ai_real mScaleU; + ai_real mScaleV; + ai_real mRotation; + + //! Specifies the mapping mode to be used for the texture + aiTextureMapMode mMapMode; + + //! Used internally + bool bPrivate; + int iUVSrc; +}; + +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +// --------------------------------------------------------------------------- +/** Helper structure representing a 3ds material */ +struct Material { + //! Default constructor has been deleted + Material() : + mName(), + mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)), + mSpecularExponent(ai_real(0.0)), + mShininessStrength(ai_real(1.0)), + mShading(Discreet3DS::Gouraud), + mTransparency(ai_real(1.0)), + mBumpHeight(ai_real(1.0)), + mTwoSided(false) { + // empty + } + + //! Constructor with explicit name + explicit Material(const std::string &name) : + mName(name), + mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)), + mSpecularExponent(ai_real(0.0)), + mShininessStrength(ai_real(1.0)), + mShading(Discreet3DS::Gouraud), + mTransparency(ai_real(1.0)), + mBumpHeight(ai_real(1.0)), + mTwoSided(false) { + // empty + } + + Material(const Material &other) : + mName(other.mName), + mDiffuse(other.mDiffuse), + mSpecularExponent(other.mSpecularExponent), + mShininessStrength(other.mShininessStrength), + mSpecular(other.mSpecular), + mAmbient(other.mAmbient), + mShading(other.mShading), + mTransparency(other.mTransparency), + sTexDiffuse(other.sTexDiffuse), + sTexOpacity(other.sTexOpacity), + sTexSpecular(other.sTexSpecular), + sTexReflective(other.sTexReflective), + sTexBump(other.sTexBump), + sTexEmissive(other.sTexEmissive), + sTexShininess(other.sTexShininess), + mBumpHeight(other.mBumpHeight), + mEmissive(other.mEmissive), + sTexAmbient(other.sTexAmbient), + mTwoSided(other.mTwoSided) { + // empty + } + + //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it + Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)), + mDiffuse(other.mDiffuse), + mSpecularExponent(other.mSpecularExponent), + mShininessStrength(other.mShininessStrength), + mSpecular(other.mSpecular), + mAmbient(other.mAmbient), + mShading(other.mShading), + mTransparency(other.mTransparency), + sTexDiffuse(std::move(other.sTexDiffuse)), + sTexOpacity(std::move(other.sTexOpacity)), + sTexSpecular(std::move(other.sTexSpecular)), + sTexReflective(std::move(other.sTexReflective)), + sTexBump(std::move(other.sTexBump)), + sTexEmissive(std::move(other.sTexEmissive)), + sTexShininess(std::move(other.sTexShininess)), + mBumpHeight(other.mBumpHeight), + mEmissive(other.mEmissive), + sTexAmbient(std::move(other.sTexAmbient)), + mTwoSided(other.mTwoSided) { + // empty + } + + Material &operator=(Material &&other) AI_NO_EXCEPT { + if (this == &other) { + return *this; + } + + mName = std::move(other.mName); + mDiffuse = other.mDiffuse; + mSpecularExponent = other.mSpecularExponent; + mShininessStrength = other.mShininessStrength, + mSpecular = other.mSpecular; + mAmbient = other.mAmbient; + mShading = other.mShading; + mTransparency = other.mTransparency; + sTexDiffuse = std::move(other.sTexDiffuse); + sTexOpacity = std::move(other.sTexOpacity); + sTexSpecular = std::move(other.sTexSpecular); + sTexReflective = std::move(other.sTexReflective); + sTexBump = std::move(other.sTexBump); + sTexEmissive = std::move(other.sTexEmissive); + sTexShininess = std::move(other.sTexShininess); + mBumpHeight = other.mBumpHeight; + mEmissive = other.mEmissive; + sTexAmbient = std::move(other.sTexAmbient); + mTwoSided = other.mTwoSided; + + return *this; + } + + virtual ~Material() { + // empty + } + + //! Name of the material + std::string mName; + //! Diffuse color of the material + aiColor3D mDiffuse; + //! Specular exponent + ai_real mSpecularExponent; + //! Shininess strength, in percent + ai_real mShininessStrength; + //! Specular color of the material + aiColor3D mSpecular; + //! Ambient color of the material + aiColor3D mAmbient; + //! Shading type to be used + Discreet3DS::shadetype3ds mShading; + //! Opacity of the material + ai_real mTransparency; + //! Diffuse texture channel + Texture sTexDiffuse; + //! Opacity texture channel + Texture sTexOpacity; + //! Specular texture channel + Texture sTexSpecular; + //! Reflective texture channel + Texture sTexReflective; + //! Bump texture channel + Texture sTexBump; + //! Emissive texture channel + Texture sTexEmissive; + //! Shininess texture channel + Texture sTexShininess; + //! Scaling factor for the bump values + ai_real mBumpHeight; + //! Emissive color + aiColor3D mEmissive; + //! Ambient texture channel + //! (used by the ASE format) + Texture sTexAmbient; + //! True if the material must be rendered from two sides + bool mTwoSided; +}; + +// --------------------------------------------------------------------------- +/** Helper structure to represent a 3ds file mesh */ +struct Mesh : public MeshWithSmoothingGroups { + //! Default constructor has been deleted + Mesh() = delete; + + //! Constructor with explicit name + explicit Mesh(const std::string &name) : + mName(name) { + } + + //! Name of the mesh + std::string mName; + + //! Texture coordinates + std::vector mTexCoords; + + //! Face materials + std::vector mFaceMaterials; + + //! Local transformation matrix + aiMatrix4x4 mMat; +}; + +// --------------------------------------------------------------------------- +/** Float key - quite similar to aiVectorKey and aiQuatKey. Both are in the + C-API, so it would be difficult to make them a template. */ +struct aiFloatKey { + double mTime; ///< The time of this key + ai_real mValue; ///< The value of this key + +#ifdef __cplusplus + + // time is not compared + bool operator==(const aiFloatKey &o) const { return o.mValue == this->mValue; } + + bool operator!=(const aiFloatKey &o) const { return o.mValue != this->mValue; } + + // Only time is compared. This operator is defined + // for use with std::sort + bool operator<(const aiFloatKey &o) const { return mTime < o.mTime; } + + bool operator>(const aiFloatKey &o) const { return mTime > o.mTime; } + +#endif +}; + +// --------------------------------------------------------------------------- +/** Helper structure to represent a 3ds file node */ +struct Node { + Node() = delete; + + explicit Node(const std::string &name) : + mParent(nullptr), + mName(name), + mInstanceNumber(0), + mHierarchyPos(0), + mHierarchyIndex(0), + mInstanceCount(1) { + aRotationKeys.reserve(20); + aPositionKeys.reserve(20); + aScalingKeys.reserve(20); + } + + ~Node() { + for (unsigned int i = 0; i < mChildren.size(); ++i) + delete mChildren[i]; + } + + //! Pointer to the parent node + Node *mParent; + + //! Holds all child nodes + std::vector mChildren; + + //! Name of the node + std::string mName; + + //! InstanceNumber of the node + int32_t mInstanceNumber; + + //! Dummy nodes: real name to be combined with the $$$DUMMY + std::string mDummyName; + + //! Position of the node in the hierarchy (tree depth) + int16_t mHierarchyPos; + + //! Index of the node + int16_t mHierarchyIndex; + + //! Rotation keys loaded from the file + std::vector aRotationKeys; + + //! Position keys loaded from the file + std::vector aPositionKeys; + + //! Scaling keys loaded from the file + std::vector aScalingKeys; + + // For target lights (spot lights and directional lights): + // The position of the target + std::vector aTargetPositionKeys; + + // For cameras: the camera roll angle + std::vector aCameraRollKeys; + + //! Pivot position loaded from the file + aiVector3D vPivot; + + //instance count, will be kept only for the first node + int32_t mInstanceCount; + + //! Add a child node, setup the right parent node for it + //! \param pc Node to be 'adopted' + inline Node &push_back(Node *pc) { + mChildren.push_back(pc); + pc->mParent = this; + return *this; + } +}; +// --------------------------------------------------------------------------- +/** Helper structure analogue to aiScene */ +struct Scene { + //! List of all materials loaded + //! NOTE: 3ds references materials globally + std::vector mMaterials; + + //! List of all meshes loaded + std::vector mMeshes; + + //! List of all cameras loaded + std::vector mCameras; + + //! List of all lights loaded + std::vector mLights; + + //! Pointer to the root node of the scene + // --- moved to main class + // Node* pcRootNode; +}; + +} // end of namespace D3DS +} // end of namespace Assimp + +#endif // AI_XFILEHELPER_H_INC diff --git a/Engine/lib/assimp/code/3DS/3DSLoader.cpp b/Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.cpp similarity index 67% rename from Engine/lib/assimp/code/3DS/3DSLoader.cpp rename to Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.cpp index 96b80c962..0ec8b872a 100644 --- a/Engine/lib/assimp/code/3DS/3DSLoader.cpp +++ b/Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.cpp @@ -3,9 +3,7 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -47,17 +45,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * http://www.the-labs.com/Blender/3DS-details.html */ - #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER -// internal headers #include "3DSLoader.h" -#include -#include +#include +#include #include #include -#include -#include +#include using namespace Assimp; @@ -71,27 +66,25 @@ static const aiImporterDesc desc = { 0, 0, 0, - "3ds prj" + "3ds prj" }; - // ------------------------------------------------------------------------------------------------ // Begins a new parsing block // - Reads the current chunk and validates it // - computes its length -#define ASSIMP_3DS_BEGIN_CHUNK() \ - while (true) { \ - if (stream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk)){ \ - return; \ - } \ - Discreet3DS::Chunk chunk; \ - ReadChunk(&chunk); \ - int chunkSize = chunk.Size-sizeof(Discreet3DS::Chunk); \ - if(chunkSize <= 0) \ - continue; \ - const unsigned int oldReadLimit = stream->SetReadLimit( \ - stream->GetCurrentPos() + chunkSize); \ - +#define ASSIMP_3DS_BEGIN_CHUNK() \ + while (true) { \ + if (stream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk)) { \ + return; \ + } \ + Discreet3DS::Chunk chunk; \ + ReadChunk(&chunk); \ + int chunkSize = chunk.Size - sizeof(Discreet3DS::Chunk); \ + if (chunkSize <= 0) \ + continue; \ + const unsigned int oldReadLimit = stream->SetReadLimit( \ + stream->GetCurrentPos() + chunkSize); // ------------------------------------------------------------------------------------------------ // End a parsing block @@ -105,15 +98,8 @@ static const aiImporterDesc desc = { // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer -Discreet3DSImporter::Discreet3DSImporter() -: stream() -, mLastNodeIndex() -, mCurrentNode() -, mRootNode() -, mScene() -, mMasterScale() -, bHasBG() -, bIsPrj() { +Discreet3DSImporter::Discreet3DSImporter() : + stream(), mLastNodeIndex(), mCurrentNode(), mRootNode(), mScene(), mMasterScale(), bHasBG(), bIsPrj() { // empty } @@ -125,48 +111,40 @@ Discreet3DSImporter::~Discreet3DSImporter() { // ------------------------------------------------------------------------------------------------ // Returns whether the class can handle the format of the given file. -bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { - std::string extension = GetExtension(pFile); - if(extension == "3ds" || extension == "prj") { - return true; - } - - if (!extension.length() || checkSig) { - uint16_t token[3]; - token[0] = 0x4d4d; - token[1] = 0x3dc2; - //token[2] = 0x3daa; - return CheckMagicToken(pIOHandler,pFile,token,2,0,2); - } - return false; +bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { + static const uint16_t token[] = { 0x4d4d, 0x3dc2 /*, 0x3daa */ }; + return CheckMagicToken(pIOHandler, pFile, token, AI_COUNT_OF(token), 0, sizeof token[0]); } // ------------------------------------------------------------------------------------------------ // Loader registry entry -const aiImporterDesc* Discreet3DSImporter::GetInfo () const -{ +const aiImporterDesc *Discreet3DSImporter::GetInfo() const { return &desc; } // ------------------------------------------------------------------------------------------------ // Setup configuration properties -void Discreet3DSImporter::SetupProperties(const Importer* /*pImp*/) -{ +void Discreet3DSImporter::SetupProperties(const Importer * /*pImp*/) { // nothing to be done for the moment } // ------------------------------------------------------------------------------------------------ // Imports the given file into the given scene structure. -void Discreet3DSImporter::InternReadFile( const std::string& pFile, - aiScene* pScene, IOSystem* pIOHandler) -{ - StreamReaderLE stream(pIOHandler->Open(pFile,"rb")); +void Discreet3DSImporter::InternReadFile(const std::string &pFile, + aiScene *pScene, IOSystem *pIOHandler) { + + auto theFile = pIOHandler->Open(pFile, "rb"); + if (!theFile) { + throw DeadlyImportError("3DS: Could not open ", pFile); + } + + StreamReaderLE theStream(theFile); // We should have at least one chunk - if (stream.GetRemainingSize() < 16) { - throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile); + if (theStream.GetRemainingSize() < 16) { + throw DeadlyImportError("3DS file is either empty or corrupt: ", pFile); } - this->stream = &stream; + this->stream = &theStream; // Allocate our temporary 3DS representation D3DS::Scene _scene; @@ -174,16 +152,16 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile, // Initialize members D3DS::Node _rootNode("UNNAMED"); - mLastNodeIndex = -1; - mCurrentNode = &_rootNode; - mRootNode = mCurrentNode; - mRootNode->mHierarchyPos = -1; + mLastNodeIndex = -1; + mCurrentNode = &_rootNode; + mRootNode = mCurrentNode; + mRootNode->mHierarchyPos = -1; mRootNode->mHierarchyIndex = -1; - mRootNode->mParent = NULL; - mMasterScale = 1.0f; - mBackgroundImage = ""; - bHasBG = false; - bIsPrj = false; + mRootNode->mParent = nullptr; + mMasterScale = 1.0f; + mBackgroundImage = std::string(); + bHasBG = false; + bIsPrj = false; // Parse the file ParseMainChunk(); @@ -194,15 +172,15 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile, // vectors from the smoothing groups we read from the // file. for (auto &mesh : mScene->mMeshes) { - if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) { - throw DeadlyImportError("3DS file contains faces but no vertices: " + pFile); + if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) { + throw DeadlyImportError("3DS file contains faces but no vertices: ", pFile); } CheckIndices(mesh); - MakeUnique (mesh); + MakeUnique(mesh); ComputeNormalsWithSmoothingsGroups(mesh); } - // Replace all occurences of the default material with a + // Replace all occurrences of the default material with a // valid material. Generate it if no material containing // DEFAULT in its name has been found in the file ReplaceDefaultMaterial(); @@ -229,26 +207,26 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile, // ------------------------------------------------------------------------------------------------ // Applies a master-scaling factor to the imported scene -void Discreet3DSImporter::ApplyMasterScale(aiScene* pScene) -{ +void Discreet3DSImporter::ApplyMasterScale(aiScene *pScene) { // There are some 3DS files with a zero scaling factor - if (!mMasterScale)mMasterScale = 1.0f; - else mMasterScale = 1.0f / mMasterScale; + if (!mMasterScale) + mMasterScale = 1.0f; + else + mMasterScale = 1.0f / mMasterScale; // Construct an uniform scaling matrix and multiply with it pScene->mRootNode->mTransformation *= aiMatrix4x4( - mMasterScale,0.0f, 0.0f, 0.0f, - 0.0f, mMasterScale,0.0f, 0.0f, - 0.0f, 0.0f, mMasterScale,0.0f, - 0.0f, 0.0f, 0.0f, 1.0f); + mMasterScale, 0.0f, 0.0f, 0.0f, + 0.0f, mMasterScale, 0.0f, 0.0f, + 0.0f, 0.0f, mMasterScale, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); // Check whether a scaling track is assigned to the root node. } // ------------------------------------------------------------------------------------------------ // Reads a new chunk from the file -void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk* pcOut) -{ +void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk *pcOut) { ai_assert(pcOut != nullptr); pcOut->Flag = stream->GetI2(); @@ -265,27 +243,25 @@ void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk* pcOut) // ------------------------------------------------------------------------------------------------ // Skip a chunk -void Discreet3DSImporter::SkipChunk() -{ +void Discreet3DSImporter::SkipChunk() { Discreet3DS::Chunk psChunk; ReadChunk(&psChunk); - stream->IncPtr(psChunk.Size-sizeof(Discreet3DS::Chunk)); + stream->IncPtr(psChunk.Size - sizeof(Discreet3DS::Chunk)); return; } // ------------------------------------------------------------------------------------------------ // Process the primary chunk of the file -void Discreet3DSImporter::ParseMainChunk() -{ +void Discreet3DSImporter::ParseMainChunk() { ASSIMP_3DS_BEGIN_CHUNK(); // get chunk type - switch (chunk.Flag) - { + switch (chunk.Flag) { case Discreet3DS::CHUNK_PRJ: bIsPrj = true; + break; case Discreet3DS::CHUNK_MAIN: ParseEditorChunk(); break; @@ -297,13 +273,11 @@ void Discreet3DSImporter::ParseMainChunk() } // ------------------------------------------------------------------------------------------------ -void Discreet3DSImporter::ParseEditorChunk() -{ +void Discreet3DSImporter::ParseEditorChunk() { ASSIMP_3DS_BEGIN_CHUNK(); // get chunk type - switch (chunk.Flag) - { + switch (chunk.Flag) { case Discreet3DS::CHUNK_OBJMESH: ParseObjectChunk(); @@ -316,41 +290,36 @@ void Discreet3DSImporter::ParseEditorChunk() ParseKeyframeChunk(); break; - case Discreet3DS::CHUNK_VERSION: - { + case Discreet3DS::CHUNK_VERSION: { // print the version number char buff[10]; - ASSIMP_itoa10(buff,stream->GetI2()); - ASSIMP_LOG_INFO_F(std::string("3DS file format version: "), buff); - } - break; + ASSIMP_itoa10(buff, stream->GetI2()); + ASSIMP_LOG_INFO("3DS file format version: ", buff); + } break; }; ASSIMP_3DS_END_CHUNK(); } // ------------------------------------------------------------------------------------------------ -void Discreet3DSImporter::ParseObjectChunk() -{ +void Discreet3DSImporter::ParseObjectChunk() { ASSIMP_3DS_BEGIN_CHUNK(); // get chunk type - switch (chunk.Flag) - { - case Discreet3DS::CHUNK_OBJBLOCK: - { + switch (chunk.Flag) { + case Discreet3DS::CHUNK_OBJBLOCK: { unsigned int cnt = 0; - const char* sz = (const char*)stream->GetPtr(); + const char *sz = (const char *)stream->GetPtr(); // Get the name of the geometry object - while (stream->GetI1())++cnt; - ParseChunk(sz,cnt); - } - break; + while (stream->GetI1()) + ++cnt; + ParseChunk(sz, cnt); + } break; case Discreet3DS::CHUNK_MAT_MATERIAL: // Add a new material to the list - mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + to_string(mScene->mMaterials.size())))); + mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + ai_to_string(mScene->mMaterials.size())))); ParseMaterialChunk(); break; @@ -358,25 +327,23 @@ void Discreet3DSImporter::ParseObjectChunk() // This is the ambient base color of the scene. // We add it to the ambient color of all materials - ParseColorChunk(&mClrAmbient,true); - if (is_qnan(mClrAmbient.r)) - { + ParseColorChunk(&mClrAmbient, true); + if (is_qnan(mClrAmbient.r)) { // We failed to read the ambient base color. ASSIMP_LOG_ERROR("3DS: Failed to read ambient base color"); mClrAmbient.r = mClrAmbient.g = mClrAmbient.b = 0.0f; } break; - case Discreet3DS::CHUNK_BIT_MAP: - { + case Discreet3DS::CHUNK_BIT_MAP: { // Specifies the background image. The string should already be // properly 0 terminated but we need to be sure unsigned int cnt = 0; - const char* sz = (const char*)stream->GetPtr(); - while (stream->GetI1())++cnt; - mBackgroundImage = std::string(sz,cnt); - } - break; + const char *sz = (const char *)stream->GetPtr(); + while (stream->GetI1()) + ++cnt; + mBackgroundImage = std::string(sz, cnt); + } break; case Discreet3DS::CHUNK_BIT_MAP_EXISTS: bHasBG = true; @@ -391,8 +358,7 @@ void Discreet3DSImporter::ParseObjectChunk() } // ------------------------------------------------------------------------------------------------ -void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num) -{ +void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) { ASSIMP_3DS_BEGIN_CHUNK(); // IMPLEMENTATION NOTE; @@ -401,22 +367,18 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num) // to to be able to return valid cameras/lights even if no scenegraph is given. // get chunk type - switch (chunk.Flag) - { - case Discreet3DS::CHUNK_TRIMESH: - { + switch (chunk.Flag) { + case Discreet3DS::CHUNK_TRIMESH: { // this starts a new triangle mesh mScene->mMeshes.push_back(D3DS::Mesh(std::string(name, num))); // Read mesh chunks ParseMeshChunk(); - } - break; + } break; - case Discreet3DS::CHUNK_LIGHT: - { + case Discreet3DS::CHUNK_LIGHT: { // This starts a new light - aiLight* light = new aiLight(); + aiLight *light = new aiLight(); mScene->mLights.push_back(light); light->mName.Set(std::string(name, num)); @@ -426,7 +388,7 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num) light->mPosition.y = stream->GetF4(); light->mPosition.z = stream->GetF4(); - light->mColorDiffuse = aiColor3D(1.f,1.f,1.f); + light->mColorDiffuse = aiColor3D(1.f, 1.f, 1.f); // Now check for further subchunks if (!bIsPrj) /* fixme */ @@ -435,19 +397,17 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num) // The specular light color is identical the the diffuse light color. The ambient light color // is equal to the ambient base color of the whole scene. light->mColorSpecular = light->mColorDiffuse; - light->mColorAmbient = mClrAmbient; + light->mColorAmbient = mClrAmbient; - if (light->mType == aiLightSource_UNDEFINED) - { + if (light->mType == aiLightSource_UNDEFINED) { // It must be a point light light->mType = aiLightSource_POINT; - }} - break; + } + } break; - case Discreet3DS::CHUNK_CAMERA: - { + case Discreet3DS::CHUNK_CAMERA: { // This starts a new camera - aiCamera* camera = new aiCamera(); + aiCamera *camera = new aiCamera(); mScene->mCameras.push_back(camera); camera->mName.Set(std::string(name, num)); @@ -465,40 +425,38 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num) // There are some files with lookat == position. Don't know why or whether it's ok or not. ASSIMP_LOG_ERROR("3DS: Unable to read proper camera look-at vector"); - camera->mLookAt = aiVector3D(0.0,1.0,0.0); + camera->mLookAt = aiVector3D(0.0, 1.0, 0.0); - } - else camera->mLookAt /= len; + } else + camera->mLookAt /= len; // And finally - the camera rotation angle, in counter clockwise direction - const ai_real angle = AI_DEG_TO_RAD( stream->GetF4() ); - aiQuaternion quat(camera->mLookAt,angle); - camera->mUp = quat.GetMatrix() * aiVector3D(0.0,1.0,0.0); + const ai_real angle = AI_DEG_TO_RAD(stream->GetF4()); + aiQuaternion quat(camera->mLookAt, angle); + camera->mUp = quat.GetMatrix() * aiVector3D(0.0, 1.0, 0.0); // Read the lense angle - camera->mHorizontalFOV = AI_DEG_TO_RAD ( stream->GetF4() ); - if (camera->mHorizontalFOV < 0.001f) { - camera->mHorizontalFOV = AI_DEG_TO_RAD(45.f); + camera->mHorizontalFOV = AI_DEG_TO_RAD(stream->GetF4()); + if (camera->mHorizontalFOV < 0.001f) { + camera->mHorizontalFOV = float(AI_DEG_TO_RAD(45.f)); } // Now check for further subchunks if (!bIsPrj) /* fixme */ { ParseCameraChunk(); - }} - break; + } + } break; }; ASSIMP_3DS_END_CHUNK(); } // ------------------------------------------------------------------------------------------------ -void Discreet3DSImporter::ParseLightChunk() -{ +void Discreet3DSImporter::ParseLightChunk() { ASSIMP_3DS_BEGIN_CHUNK(); - aiLight* light = mScene->mLights.back(); + aiLight *light = mScene->mLights.back(); // get chunk type - switch (chunk.Flag) - { + switch (chunk.Flag) { case Discreet3DS::CHUNK_DL_SPOTLIGHT: // Now we can be sure that the light is a spot light light->mType = aiLightSource_SPOT; @@ -510,10 +468,10 @@ void Discreet3DSImporter::ParseLightChunk() light->mDirection.Normalize(); // Now the hotspot and falloff angles - in degrees - light->mAngleInnerCone = AI_DEG_TO_RAD( stream->GetF4() ); + light->mAngleInnerCone = AI_DEG_TO_RAD(stream->GetF4()); // FIX: the falloff angle is just an offset - light->mAngleOuterCone = light->mAngleInnerCone+AI_DEG_TO_RAD( stream->GetF4() ); + light->mAngleOuterCone = light->mAngleInnerCone + AI_DEG_TO_RAD(stream->GetF4()); break; // intensity multiplier @@ -539,18 +497,16 @@ void Discreet3DSImporter::ParseLightChunk() } // ------------------------------------------------------------------------------------------------ -void Discreet3DSImporter::ParseCameraChunk() -{ +void Discreet3DSImporter::ParseCameraChunk() { ASSIMP_3DS_BEGIN_CHUNK(); - aiCamera* camera = mScene->mCameras.back(); + aiCamera *camera = mScene->mCameras.back(); // get chunk type - switch (chunk.Flag) - { + switch (chunk.Flag) { // near and far clip plane case Discreet3DS::CHUNK_CAM_RANGES: camera->mClipPlaneNear = stream->GetF4(); - camera->mClipPlaneFar = stream->GetF4(); + camera->mClipPlaneFar = stream->GetF4(); break; } @@ -558,13 +514,11 @@ void Discreet3DSImporter::ParseCameraChunk() } // ------------------------------------------------------------------------------------------------ -void Discreet3DSImporter::ParseKeyframeChunk() -{ +void Discreet3DSImporter::ParseKeyframeChunk() { ASSIMP_3DS_BEGIN_CHUNK(); // get chunk type - switch (chunk.Flag) - { + switch (chunk.Flag) { case Discreet3DS::CHUNK_TRACKCAMTGT: case Discreet3DS::CHUNK_TRACKSPOTL: case Discreet3DS::CHUNK_TRACKCAMERA: @@ -582,49 +536,49 @@ void Discreet3DSImporter::ParseKeyframeChunk() // ------------------------------------------------------------------------------------------------ // Little helper function for ParseHierarchyChunk -void Discreet3DSImporter::InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent) -{ +void Discreet3DSImporter::InverseNodeSearch(D3DS::Node *pcNode, D3DS::Node *pcCurrent) { if (!pcCurrent) { mRootNode->push_back(pcNode); return; } - if (pcCurrent->mHierarchyPos == pcNode->mHierarchyPos) { - if(pcCurrent->mParent) { + if (pcCurrent->mHierarchyPos == pcNode->mHierarchyPos) { + if (pcCurrent->mParent) { pcCurrent->mParent->push_back(pcNode); - } - else pcCurrent->push_back(pcNode); + } else + pcCurrent->push_back(pcNode); return; } - return InverseNodeSearch(pcNode,pcCurrent->mParent); + return InverseNodeSearch(pcNode, pcCurrent->mParent); } // ------------------------------------------------------------------------------------------------ // Find a node with a specific name in the import hierarchy -D3DS::Node* FindNode(D3DS::Node* root, const std::string& name) -{ - if (root->mName == name) +D3DS::Node *FindNode(D3DS::Node *root, const std::string &name) { + if (root->mName == name) { return root; - for (std::vector::iterator it = root->mChildren.begin();it != root->mChildren.end(); ++it) { - D3DS::Node* nd; - if (( nd = FindNode(*it,name))) - return nd; } - return NULL; + + for (std::vector::iterator it = root->mChildren.begin(); it != root->mChildren.end(); ++it) { + D3DS::Node *nd = FindNode(*it, name); + if (nullptr != nd) { + return nd; + } + } + + return nullptr; } // ------------------------------------------------------------------------------------------------ // Binary predicate for std::unique() template -bool KeyUniqueCompare(const T& first, const T& second) -{ +bool KeyUniqueCompare(const T &first, const T &second) { return first.mTime == second.mTime; } // ------------------------------------------------------------------------------------------------ // Skip some additional import data. -void Discreet3DSImporter::SkipTCBInfo() -{ +void Discreet3DSImporter::SkipTCBInfo() { unsigned int flags = stream->GetI2(); if (!flags) { @@ -654,73 +608,68 @@ void Discreet3DSImporter::SkipTCBInfo() // ------------------------------------------------------------------------------------------------ // Read hierarchy and keyframe info -void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) -{ +void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) { ASSIMP_3DS_BEGIN_CHUNK(); // get chunk type - switch (chunk.Flag) - { + switch (chunk.Flag) { case Discreet3DS::CHUNK_TRACKOBJNAME: // This is the name of the object to which the track applies. The chunk also // defines the position of this object in the hierarchy. { - // First of all: get the name of the object - unsigned int cnt = 0; - const char* sz = (const char*)stream->GetPtr(); + // First of all: get the name of the object + unsigned int cnt = 0; + const char *sz = (const char *)stream->GetPtr(); - while (stream->GetI1())++cnt; - std::string name = std::string(sz,cnt); + while (stream->GetI1()) + ++cnt; + std::string name = std::string(sz, cnt); - // Now find out whether we have this node already (target animation channels - // are stored with a separate object ID) - D3DS::Node* pcNode = FindNode(mRootNode,name); - int instanceNumber = 1; + // Now find out whether we have this node already (target animation channels + // are stored with a separate object ID) + D3DS::Node *pcNode = FindNode(mRootNode, name); + int instanceNumber = 1; - if ( pcNode) - { - // if the source is not a CHUNK_TRACKINFO block it won't be an object instance - if (parent != Discreet3DS::CHUNK_TRACKINFO) - { - mCurrentNode = pcNode; - break; + if (pcNode) { + // if the source is not a CHUNK_TRACKINFO block it won't be an object instance + if (parent != Discreet3DS::CHUNK_TRACKINFO) { + mCurrentNode = pcNode; + break; + } + pcNode->mInstanceCount++; + instanceNumber = pcNode->mInstanceCount; } - pcNode->mInstanceCount++; - instanceNumber = pcNode->mInstanceCount; - } - pcNode = new D3DS::Node(name); - pcNode->mInstanceNumber = instanceNumber; + pcNode = new D3DS::Node(name); + pcNode->mInstanceNumber = instanceNumber; - // There are two unknown values which we can safely ignore - stream->IncPtr(4); + // There are two unknown values which we can safely ignore + stream->IncPtr(4); - // Now read the hierarchy position of the object - uint16_t hierarchy = stream->GetI2() + 1; - pcNode->mHierarchyPos = hierarchy; - pcNode->mHierarchyIndex = mLastNodeIndex; + // Now read the hierarchy position of the object + uint16_t hierarchy = stream->GetI2() + 1; + pcNode->mHierarchyPos = hierarchy; + pcNode->mHierarchyIndex = mLastNodeIndex; - // And find a proper position in the graph for it - if (mCurrentNode && mCurrentNode->mHierarchyPos == hierarchy) { + // And find a proper position in the graph for it + if (mCurrentNode && mCurrentNode->mHierarchyPos == hierarchy) { - // add to the parent of the last touched node - mCurrentNode->mParent->push_back(pcNode); - mLastNodeIndex++; - } - else if(hierarchy >= mLastNodeIndex) { + // add to the parent of the last touched node + mCurrentNode->mParent->push_back(pcNode); + mLastNodeIndex++; + } else if (hierarchy >= mLastNodeIndex) { - // place it at the current position in the hierarchy - mCurrentNode->push_back(pcNode); - mLastNodeIndex = hierarchy; - } - else { - // need to go back to the specified position in the hierarchy. - InverseNodeSearch(pcNode,mCurrentNode); - mLastNodeIndex++; - } - // Make this node the current node - mCurrentNode = pcNode; + // place it at the current position in the hierarchy + mCurrentNode->push_back(pcNode); + mLastNodeIndex = hierarchy; + } else { + // need to go back to the specified position in the hierarchy. + InverseNodeSearch(pcNode, mCurrentNode); + mLastNodeIndex++; + } + // Make this node the current node + mCurrentNode = pcNode; } break; @@ -728,11 +677,12 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) // This is the "real" name of a $$$DUMMY object { - const char* sz = (const char*) stream->GetPtr(); - while (stream->GetI1()); + const char *sz = (const char *)stream->GetPtr(); + while (stream->GetI1()) + ; // If object name is DUMMY, take this one instead - if (mCurrentNode->mName == "$$$DUMMY") { + if (mCurrentNode->mName == "$$$DUMMY") { mCurrentNode->mName = std::string(sz); break; } @@ -741,8 +691,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) case Discreet3DS::CHUNK_TRACKPIVOT: - if ( Discreet3DS::CHUNK_TRACKINFO != parent) - { + if (Discreet3DS::CHUNK_TRACKINFO != parent) { ASSIMP_LOG_WARN("3DS: Skipping pivot subchunk for non usual object"); break; } @@ -753,25 +702,23 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) mCurrentNode->vPivot.z = stream->GetF4(); break; - // //////////////////////////////////////////////////////////////////// // POSITION KEYFRAME - case Discreet3DS::CHUNK_TRACKPOS: - { + case Discreet3DS::CHUNK_TRACKPOS: { stream->IncPtr(10); const unsigned int numFrames = stream->GetI4(); bool sortKeys = false; // This could also be meant as the target position for // (targeted) lights and cameras - std::vector* l; - if ( Discreet3DS::CHUNK_TRACKCAMTGT == parent || Discreet3DS::CHUNK_TRACKLIGTGT == parent) { - l = & mCurrentNode->aTargetPositionKeys; - } - else l = & mCurrentNode->aPositionKeys; + std::vector *l; + if (Discreet3DS::CHUNK_TRACKCAMTGT == parent || Discreet3DS::CHUNK_TRACKLIGTGT == parent) { + l = &mCurrentNode->aTargetPositionKeys; + } else + l = &mCurrentNode->aPositionKeys; l->reserve(numFrames); - for (unsigned int i = 0; i < numFrames;++i) { + for (unsigned int i = 0; i < numFrames; ++i) { const unsigned int fidx = stream->GetI4(); // Setup a new position key @@ -792,29 +739,29 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) } // Sort all keys with ascending time values and remove duplicates? - if (sortKeys) { - std::stable_sort(l->begin(),l->end()); - l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare), l->end() ); - }} + if (sortKeys) { + std::stable_sort(l->begin(), l->end()); + l->erase(std::unique(l->begin(), l->end(), &KeyUniqueCompare), l->end()); + } + } - break; + break; // //////////////////////////////////////////////////////////////////// // CAMERA ROLL KEYFRAME - case Discreet3DS::CHUNK_TRACKROLL: - { + case Discreet3DS::CHUNK_TRACKROLL: { // roll keys are accepted for cameras only - if (parent != Discreet3DS::CHUNK_TRACKCAMERA) { + if (parent != Discreet3DS::CHUNK_TRACKCAMERA) { ASSIMP_LOG_WARN("3DS: Ignoring roll track for non-camera object"); break; } bool sortKeys = false; - std::vector* l = &mCurrentNode->aCameraRollKeys; + std::vector *l = &mCurrentNode->aCameraRollKeys; stream->IncPtr(10); const unsigned int numFrames = stream->GetI4(); l->reserve(numFrames); - for (unsigned int i = 0; i < numFrames;++i) { + for (unsigned int i = 0; i < numFrames; ++i) { const unsigned int fidx = stream->GetI4(); // Setup a new position key @@ -834,35 +781,30 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) } // Sort all keys with ascending time values and remove duplicates? - if (sortKeys) { - std::stable_sort(l->begin(),l->end()); - l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare), l->end() ); - }} - break; - + if (sortKeys) { + std::stable_sort(l->begin(), l->end()); + l->erase(std::unique(l->begin(), l->end(), &KeyUniqueCompare), l->end()); + } + } break; // //////////////////////////////////////////////////////////////////// // CAMERA FOV KEYFRAME - case Discreet3DS::CHUNK_TRACKFOV: - { - ASSIMP_LOG_ERROR("3DS: Skipping FOV animation track. " - "This is not supported"); - } - break; - + case Discreet3DS::CHUNK_TRACKFOV: { + ASSIMP_LOG_ERROR("3DS: Skipping FOV animation track. " + "This is not supported"); + } break; // //////////////////////////////////////////////////////////////////// // ROTATION KEYFRAME - case Discreet3DS::CHUNK_TRACKROTATE: - { + case Discreet3DS::CHUNK_TRACKROTATE: { stream->IncPtr(10); const unsigned int numFrames = stream->GetI4(); bool sortKeys = false; - std::vector* l = &mCurrentNode->aRotationKeys; + std::vector *l = &mCurrentNode->aRotationKeys; l->reserve(numFrames); - for (unsigned int i = 0; i < numFrames;++i) { + for (unsigned int i = 0; i < numFrames; ++i) { const unsigned int fidx = stream->GetI4(); SkipTCBInfo(); @@ -880,7 +822,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) axis.y = 1.f; // Construct a rotation quaternion from the axis-angle pair - v.mValue = aiQuaternion(axis,rad); + v.mValue = aiQuaternion(axis, rad); // Check whether we'll need to sort the keys if (!l->empty() && v.mTime <= l->back().mTime) @@ -890,25 +832,24 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) l->push_back(v); } // Sort all keys with ascending time values and remove duplicates? - if (sortKeys) { - std::stable_sort(l->begin(),l->end()); - l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare), l->end() ); - }} - break; + if (sortKeys) { + std::stable_sort(l->begin(), l->end()); + l->erase(std::unique(l->begin(), l->end(), &KeyUniqueCompare), l->end()); + } + } break; // //////////////////////////////////////////////////////////////////// // SCALING KEYFRAME - case Discreet3DS::CHUNK_TRACKSCALE: - { + case Discreet3DS::CHUNK_TRACKSCALE: { stream->IncPtr(10); const unsigned int numFrames = stream->GetI2(); stream->IncPtr(2); bool sortKeys = false; - std::vector* l = &mCurrentNode->aScalingKeys; + std::vector *l = &mCurrentNode->aScalingKeys; l->reserve(numFrames); - for (unsigned int i = 0; i < numFrames;++i) { + for (unsigned int i = 0; i < numFrames; ++i) { const unsigned int fidx = stream->GetI4(); SkipTCBInfo(); @@ -933,11 +874,11 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) l->push_back(v); } // Sort all keys with ascending time values and remove duplicates? - if (sortKeys) { - std::stable_sort(l->begin(),l->end()); - l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare), l->end() ); - }} - break; + if (sortKeys) { + std::stable_sort(l->begin(), l->end()); + l->erase(std::unique(l->begin(), l->end(), &KeyUniqueCompare), l->end()); + } + } break; }; ASSIMP_3DS_END_CHUNK(); @@ -945,92 +886,85 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) // ------------------------------------------------------------------------------------------------ // Read a face chunk - it contains smoothing groups and material assignments -void Discreet3DSImporter::ParseFaceChunk() -{ +void Discreet3DSImporter::ParseFaceChunk() { ASSIMP_3DS_BEGIN_CHUNK(); // Get the mesh we're currently working on - D3DS::Mesh& mMesh = mScene->mMeshes.back(); + D3DS::Mesh &mMesh = mScene->mMeshes.back(); // Get chunk type - switch (chunk.Flag) - { - case Discreet3DS::CHUNK_SMOOLIST: - { + switch (chunk.Flag) { + case Discreet3DS::CHUNK_SMOOLIST: { // This is the list of smoothing groups - a bitfield for every face. // Up to 32 smoothing groups assigned to a single face. - unsigned int num = chunkSize/4, m = 0; - if (num > mMesh.mFaces.size()) { + unsigned int num = chunkSize / 4, m = 0; + if (num > mMesh.mFaces.size()) { throw DeadlyImportError("3DS: More smoothing groups than faces"); } - for (std::vector::iterator i = mMesh.mFaces.begin(); m != num;++i, ++m) { + for (std::vector::iterator i = mMesh.mFaces.begin(); m != num; ++i, ++m) { // nth bit is set for nth smoothing group (*i).iSmoothGroup = stream->GetI4(); - }} - break; + } + } break; - case Discreet3DS::CHUNK_FACEMAT: - { + case Discreet3DS::CHUNK_FACEMAT: { // at fist an asciiz with the material name - const char* sz = (const char*)stream->GetPtr(); - while (stream->GetI1()); + const char *sz = (const char *)stream->GetPtr(); + while (stream->GetI1()) + ; // find the index of the material unsigned int idx = 0xcdcdcdcd, cnt = 0; - for (std::vector::const_iterator i = mScene->mMaterials.begin();i != mScene->mMaterials.end();++i,++cnt) { + for (std::vector::const_iterator i = mScene->mMaterials.begin(); i != mScene->mMaterials.end(); ++i, ++cnt) { // use case independent comparisons. hopefully it will work. if ((*i).mName.length() && !ASSIMP_stricmp(sz, (*i).mName.c_str())) { idx = cnt; break; } } - if (0xcdcdcdcd == idx) { - ASSIMP_LOG_ERROR_F( "3DS: Unknown material: ", sz); + if (0xcdcdcdcd == idx) { + ASSIMP_LOG_ERROR("3DS: Unknown material: ", sz); } // Now continue and read all material indices cnt = (uint16_t)stream->GetI2(); - for (unsigned int i = 0; i < cnt;++i) { + for (unsigned int i = 0; i < cnt; ++i) { unsigned int fidx = (uint16_t)stream->GetI2(); // check range - if (fidx >= mMesh.mFaceMaterials.size()) { + if (fidx >= mMesh.mFaceMaterials.size()) { ASSIMP_LOG_ERROR("3DS: Invalid face index in face material list"); - } - else mMesh.mFaceMaterials[fidx] = idx; - }} - break; + } else + mMesh.mFaceMaterials[fidx] = idx; + } + } break; }; ASSIMP_3DS_END_CHUNK(); } // ------------------------------------------------------------------------------------------------ // Read a mesh chunk. Here's the actual mesh data -void Discreet3DSImporter::ParseMeshChunk() -{ +void Discreet3DSImporter::ParseMeshChunk() { ASSIMP_3DS_BEGIN_CHUNK(); // Get the mesh we're currently working on - D3DS::Mesh& mMesh = mScene->mMeshes.back(); + D3DS::Mesh &mMesh = mScene->mMeshes.back(); // get chunk type - switch (chunk.Flag) - { - case Discreet3DS::CHUNK_VERTLIST: - { + switch (chunk.Flag) { + case Discreet3DS::CHUNK_VERTLIST: { // This is the list of all vertices in the current mesh int num = (int)(uint16_t)stream->GetI2(); mMesh.mPositions.reserve(num); - while (num-- > 0) { + while (num-- > 0) { aiVector3D v; v.x = stream->GetF4(); v.y = stream->GetF4(); v.z = stream->GetF4(); mMesh.mPositions.push_back(v); - }} - break; - case Discreet3DS::CHUNK_TRMATRIX: - { + } + } break; + case Discreet3DS::CHUNK_TRMATRIX: { // This is the RLEATIVE transformation matrix of the current mesh. Vertices are // pretransformed by this matrix wonder. mMesh.mMat.a1 = stream->GetF4(); @@ -1045,31 +979,28 @@ void Discreet3DSImporter::ParseMeshChunk() mMesh.mMat.a4 = stream->GetF4(); mMesh.mMat.b4 = stream->GetF4(); mMesh.mMat.c4 = stream->GetF4(); - } - break; + } break; - case Discreet3DS::CHUNK_MAPLIST: - { + case Discreet3DS::CHUNK_MAPLIST: { // This is the list of all UV coords in the current mesh int num = (int)(uint16_t)stream->GetI2(); mMesh.mTexCoords.reserve(num); - while (num-- > 0) { + while (num-- > 0) { aiVector3D v; v.x = stream->GetF4(); v.y = stream->GetF4(); mMesh.mTexCoords.push_back(v); - }} - break; + } + } break; - case Discreet3DS::CHUNK_FACELIST: - { + case Discreet3DS::CHUNK_FACELIST: { // This is the list of all faces in the current mesh int num = (int)(uint16_t)stream->GetI2(); mMesh.mFaces.reserve(num); - while (num-- > 0) { + while (num-- > 0) { // 3DS faces are ALWAYS triangles mMesh.mFaces.push_back(D3DS::Face()); - D3DS::Face& sFace = mMesh.mFaces.back(); + D3DS::Face &sFace = mMesh.mFaces.back(); sFace.mIndices[0] = (uint16_t)stream->GetI2(); sFace.mIndices[1] = (uint16_t)stream->GetI2(); @@ -1080,103 +1011,93 @@ void Discreet3DSImporter::ParseMeshChunk() // Resize the material array (0xcdcdcdcd marks the default material; so if a face is // not referenced by a material, $$DEFAULT will be assigned to it) - mMesh.mFaceMaterials.resize(mMesh.mFaces.size(),0xcdcdcdcd); + mMesh.mFaceMaterials.resize(mMesh.mFaces.size(), 0xcdcdcdcd); // Larger 3DS files could have multiple FACE chunks here - chunkSize = stream->GetRemainingSizeToLimit(); - if ( chunkSize > (int) sizeof(Discreet3DS::Chunk ) ) + chunkSize = (int)stream->GetRemainingSizeToLimit(); + if (chunkSize > (int)sizeof(Discreet3DS::Chunk)) ParseFaceChunk(); - } - break; + } break; }; ASSIMP_3DS_END_CHUNK(); } // ------------------------------------------------------------------------------------------------ // Read a 3DS material chunk -void Discreet3DSImporter::ParseMaterialChunk() -{ +void Discreet3DSImporter::ParseMaterialChunk() { ASSIMP_3DS_BEGIN_CHUNK(); - switch (chunk.Flag) - { + switch (chunk.Flag) { case Discreet3DS::CHUNK_MAT_MATNAME: - { + { // The material name string is already zero-terminated, but we need to be sure ... - const char* sz = (const char*)stream->GetPtr(); + const char *sz = (const char *)stream->GetPtr(); unsigned int cnt = 0; while (stream->GetI1()) ++cnt; - if (!cnt) { + if (!cnt) { // This may not be, we use the default name instead ASSIMP_LOG_ERROR("3DS: Empty material name"); - } - else mScene->mMaterials.back().mName = std::string(sz,cnt); - } - break; + } else + mScene->mMaterials.back().mName = std::string(sz, cnt); + } break; - case Discreet3DS::CHUNK_MAT_DIFFUSE: - { + case Discreet3DS::CHUNK_MAT_DIFFUSE: { // This is the diffuse material color - aiColor3D* pc = &mScene->mMaterials.back().mDiffuse; + aiColor3D *pc = &mScene->mMaterials.back().mDiffuse; ParseColorChunk(pc); if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it ASSIMP_LOG_ERROR("3DS: Unable to read DIFFUSE chunk"); pc->r = pc->g = pc->b = 1.0f; - }} - break; + } + } break; - case Discreet3DS::CHUNK_MAT_SPECULAR: - { + case Discreet3DS::CHUNK_MAT_SPECULAR: { // This is the specular material color - aiColor3D* pc = &mScene->mMaterials.back().mSpecular; + aiColor3D *pc = &mScene->mMaterials.back().mSpecular; ParseColorChunk(pc); if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it ASSIMP_LOG_ERROR("3DS: Unable to read SPECULAR chunk"); pc->r = pc->g = pc->b = 1.0f; - }} - break; + } + } break; - case Discreet3DS::CHUNK_MAT_AMBIENT: - { + case Discreet3DS::CHUNK_MAT_AMBIENT: { // This is the ambient material color - aiColor3D* pc = &mScene->mMaterials.back().mAmbient; + aiColor3D *pc = &mScene->mMaterials.back().mAmbient; ParseColorChunk(pc); if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it ASSIMP_LOG_ERROR("3DS: Unable to read AMBIENT chunk"); pc->r = pc->g = pc->b = 0.0f; - }} - break; + } + } break; - case Discreet3DS::CHUNK_MAT_SELF_ILLUM: - { + case Discreet3DS::CHUNK_MAT_SELF_ILLUM: { // This is the emissive material color - aiColor3D* pc = &mScene->mMaterials.back().mEmissive; + aiColor3D *pc = &mScene->mMaterials.back().mEmissive; ParseColorChunk(pc); if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it ASSIMP_LOG_ERROR("3DS: Unable to read EMISSIVE chunk"); pc->r = pc->g = pc->b = 0.0f; - }} - break; - - case Discreet3DS::CHUNK_MAT_TRANSPARENCY: - { - // This is the material's transparency - ai_real* pcf = &mScene->mMaterials.back().mTransparency; - *pcf = ParsePercentageChunk(); - - // NOTE: transparency, not opacity - if (is_qnan(*pcf)) - *pcf = ai_real( 1.0 ); - else - *pcf = ai_real( 1.0 ) - *pcf * (ai_real)0xFFFF / ai_real( 100.0 ); } - break; + } break; + + case Discreet3DS::CHUNK_MAT_TRANSPARENCY: { + // This is the material's transparency + ai_real *pcf = &mScene->mMaterials.back().mTransparency; + *pcf = ParsePercentageChunk(); + + // NOTE: transparency, not opacity + if (is_qnan(*pcf)) + *pcf = ai_real(1.0); + else + *pcf = ai_real(1.0) - *pcf * (ai_real)0xFFFF / ai_real(100.0); + } break; case Discreet3DS::CHUNK_MAT_SHADING: // This is the material shading mode @@ -1188,37 +1109,32 @@ void Discreet3DSImporter::ParseMaterialChunk() mScene->mMaterials.back().mTwoSided = true; break; - case Discreet3DS::CHUNK_MAT_SHININESS: - { // This is the shininess of the material - ai_real* pcf = &mScene->mMaterials.back().mSpecularExponent; + case Discreet3DS::CHUNK_MAT_SHININESS: { // This is the shininess of the material + ai_real *pcf = &mScene->mMaterials.back().mSpecularExponent; *pcf = ParsePercentageChunk(); if (is_qnan(*pcf)) *pcf = 0.0; - else *pcf *= (ai_real)0xFFFF; - } - break; + else + *pcf *= (ai_real)0xFFFF; + } break; - case Discreet3DS::CHUNK_MAT_SHININESS_PERCENT: - { // This is the shininess strength of the material - ai_real* pcf = &mScene->mMaterials.back().mShininessStrength; - *pcf = ParsePercentageChunk(); - if (is_qnan(*pcf)) - *pcf = ai_real( 0.0 ); - else - *pcf *= (ai_real)0xffff / ai_real( 100.0 ); - } - break; + case Discreet3DS::CHUNK_MAT_SHININESS_PERCENT: { // This is the shininess strength of the material + ai_real *pcf = &mScene->mMaterials.back().mShininessStrength; + *pcf = ParsePercentageChunk(); + if (is_qnan(*pcf)) + *pcf = ai_real(0.0); + else + *pcf *= (ai_real)0xffff / ai_real(100.0); + } break; - case Discreet3DS::CHUNK_MAT_SELF_ILPCT: - { // This is the self illumination strength of the material - ai_real f = ParsePercentageChunk(); - if (is_qnan(f)) - f = ai_real( 0.0 ); - else - f *= (ai_real)0xFFFF / ai_real( 100.0 ); - mScene->mMaterials.back().mEmissive = aiColor3D(f,f,f); - } - break; + case Discreet3DS::CHUNK_MAT_SELF_ILPCT: { // This is the self illumination strength of the material + ai_real f = ParsePercentageChunk(); + if (is_qnan(f)) + f = ai_real(0.0); + else + f *= (ai_real)0xFFFF / ai_real(100.0); + mScene->mMaterials.back().mEmissive = aiColor3D(f, f, f); + } break; // Parse texture chunks case Discreet3DS::CHUNK_MAT_TEXTURE: @@ -1254,28 +1170,23 @@ void Discreet3DSImporter::ParseMaterialChunk() } // ------------------------------------------------------------------------------------------------ -void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut) -{ +void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture *pcOut) { ASSIMP_3DS_BEGIN_CHUNK(); // get chunk type - switch (chunk.Flag) - { - case Discreet3DS::CHUNK_MAPFILE: - { + switch (chunk.Flag) { + case Discreet3DS::CHUNK_MAPFILE: { // The material name string is already zero-terminated, but we need to be sure ... - const char* sz = (const char*)stream->GetPtr(); + const char *sz = (const char *)stream->GetPtr(); unsigned int cnt = 0; while (stream->GetI1()) ++cnt; - pcOut->mMapName = std::string(sz,cnt); - } - break; - + pcOut->mMapName = std::string(sz, cnt); + } break; case Discreet3DS::CHUNK_PERCENTD: // Manually parse the blend factor - pcOut->mTextureBlend = ai_real( stream->GetF8() ); + pcOut->mTextureBlend = ai_real(stream->GetF8()); break; case Discreet3DS::CHUNK_PERCENTF: @@ -1285,14 +1196,13 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut) case Discreet3DS::CHUNK_PERCENTW: // Manually parse the blend factor - pcOut->mTextureBlend = (ai_real)((uint16_t)stream->GetI2()) / ai_real( 100.0 ); + pcOut->mTextureBlend = (ai_real)((uint16_t)stream->GetI2()) / ai_real(100.0); break; case Discreet3DS::CHUNK_MAT_MAP_USCALE: // Texture coordinate scaling in the U direction pcOut->mScaleU = stream->GetF4(); - if (0.0f == pcOut->mScaleU) - { + if (0.0f == pcOut->mScaleU) { ASSIMP_LOG_WARN("Texture coordinate scaling in the x direction is zero. Assuming 1."); pcOut->mScaleU = 1.0f; } @@ -1300,8 +1210,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut) case Discreet3DS::CHUNK_MAT_MAP_VSCALE: // Texture coordinate scaling in the V direction pcOut->mScaleV = stream->GetF4(); - if (0.0f == pcOut->mScaleV) - { + if (0.0f == pcOut->mScaleV) { ASSIMP_LOG_WARN("Texture coordinate scaling in the y direction is zero. Assuming 1."); pcOut->mScaleV = 1.0f; } @@ -1319,11 +1228,10 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut) case Discreet3DS::CHUNK_MAT_MAP_ANG: // Texture coordinate rotation, CCW in DEGREES - pcOut->mRotation = -AI_DEG_TO_RAD( stream->GetF4() ); + pcOut->mRotation = -AI_DEG_TO_RAD(stream->GetF4()); break; - case Discreet3DS::CHUNK_MAT_MAP_TILING: - { + case Discreet3DS::CHUNK_MAT_MAP_TILING: { const uint16_t iFlags = stream->GetI2(); // Get the mapping mode (for both axes) @@ -1334,9 +1242,9 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut) pcOut->mMapMode = aiTextureMapMode_Decal; // wrapping in all remaining cases - else pcOut->mMapMode = aiTextureMapMode_Wrap; - } - break; + else + pcOut->mMapMode = aiTextureMapMode_Wrap; + } break; }; ASSIMP_3DS_END_CHUNK(); @@ -1359,13 +1267,12 @@ ai_real Discreet3DSImporter::ParsePercentageChunk() { // ------------------------------------------------------------------------------------------------ // Read a color chunk. If a percentage chunk is found instead it is read as a grayscale color -void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent ) -{ - ai_assert(out != NULL); +void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) { + ai_assert(out != nullptr); // error return value const ai_real qnan = get_qnan(); - static const aiColor3D clrError = aiColor3D(qnan,qnan,qnan); + static const aiColor3D clrError = aiColor3D(qnan, qnan, qnan); Discreet3DS::Chunk chunk; ReadChunk(&chunk); @@ -1374,13 +1281,12 @@ void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent ) bool bGamma = false; // Get the type of the chunk - switch(chunk.Flag) - { + switch (chunk.Flag) { case Discreet3DS::CHUNK_LINRGBF: bGamma = true; case Discreet3DS::CHUNK_RGBF: - if (sizeof(float) * 3 > diff) { + if (sizeof(float) * 3 > diff) { *out = clrError; return; } @@ -1391,18 +1297,16 @@ void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent ) case Discreet3DS::CHUNK_LINRGBB: bGamma = true; - case Discreet3DS::CHUNK_RGBB: - { - if ( sizeof( char ) * 3 > diff ) { - *out = clrError; - return; - } - const ai_real invVal = ai_real( 1.0 ) / ai_real( 255.0 ); - out->r = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal; - out->g = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal; - out->b = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal; + case Discreet3DS::CHUNK_RGBB: { + if (sizeof(char) * 3 > diff) { + *out = clrError; + return; } - break; + const ai_real invVal = ai_real(1.0) / ai_real(255.0); + out->r = (ai_real)(uint8_t)stream->GetI1() * invVal; + out->g = (ai_real)(uint8_t)stream->GetI1() * invVal; + out->b = (ai_real)(uint8_t)stream->GetI1() * invVal; + } break; // Percentage chunks are accepted, too. case Discreet3DS::CHUNK_PERCENTF: @@ -1415,7 +1319,7 @@ void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent ) case Discreet3DS::CHUNK_PERCENTW: if (acceptPercent && 1 <= diff) { - out->g = out->b = out->r = (ai_real)(uint8_t)stream->GetI1() / ai_real( 255.0 ); + out->g = out->b = out->r = (ai_real)(uint8_t)stream->GetI1() / ai_real(255.0); break; } *out = clrError; @@ -1424,7 +1328,7 @@ void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent ) default: stream->IncPtr(diff); // Skip unknown chunks, hope this won't cause any problems. - return ParseColorChunk(out,acceptPercent); + return ParseColorChunk(out, acceptPercent); }; (void)bGamma; } diff --git a/Engine/lib/assimp/code/3DS/3DSLoader.h b/Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.h similarity index 92% rename from Engine/lib/assimp/code/3DS/3DSLoader.h rename to Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.h index f57e6a8e3..f47fcfef9 100644 --- a/Engine/lib/assimp/code/3DS/3DSLoader.h +++ b/Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.h @@ -3,7 +3,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -46,11 +46,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef AI_3DSIMPORTER_H_INC #define AI_3DSIMPORTER_H_INC +#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER #include #include -#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER #include "3DSHelper.h" #include @@ -65,28 +65,24 @@ using namespace D3DS; // --------------------------------------------------------------------------------- /** Importer class for 3D Studio r3 and r4 3DS files */ -class Discreet3DSImporter : public BaseImporter -{ +class Discreet3DSImporter : public BaseImporter { public: - Discreet3DSImporter(); ~Discreet3DSImporter(); -public: - // ------------------------------------------------------------------- /** Returns whether the class can handle the format of the given file. * See BaseImporter::CanRead() for details. */ bool CanRead( const std::string& pFile, IOSystem* pIOHandler, - bool checkSig) const; + bool checkSig) const override; // ------------------------------------------------------------------- /** Called prior to ReadFile(). * The function is a request to the importer to update its configuration * basing on the Importer's configuration property list. */ - void SetupProperties(const Importer* pImp); + void SetupProperties(const Importer* pImp) override; protected: @@ -94,14 +90,14 @@ protected: /** Return importer meta information. * See #BaseImporter::GetInfo for the details */ - const aiImporterDesc* GetInfo () const; + const aiImporterDesc* GetInfo () const override; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. * See BaseImporter::InternReadFile() for details */ void InternReadFile( const std::string& pFile, aiScene* pScene, - IOSystem* pIOHandler); + IOSystem* pIOHandler) override; // ------------------------------------------------------------------- /** Converts a temporary material to the outer representation @@ -212,6 +208,15 @@ protected: */ void ReplaceDefaultMaterial(); + bool ContainsTextures(unsigned int i) const { + return !mScene->mMaterials[i].sTexDiffuse.mMapName.empty() || + !mScene->mMaterials[i].sTexBump.mMapName.empty() || + !mScene->mMaterials[i].sTexOpacity.mMapName.empty() || + !mScene->mMaterials[i].sTexEmissive.mMapName.empty() || + !mScene->mMaterials[i].sTexSpecular.mMapName.empty() || + !mScene->mMaterials[i].sTexShininess.mMapName.empty() ; + } + // ------------------------------------------------------------------- /** Convert the whole scene */ diff --git a/Engine/lib/assimp/code/AssetLib/3MF/3MFTypes.h b/Engine/lib/assimp/code/AssetLib/3MF/3MFTypes.h new file mode 100644 index 000000000..987cdf613 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/3MF/3MFTypes.h @@ -0,0 +1,165 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +#pragma once + +#include +#include +#include +#include +#include + +struct aiMaterial; +struct aiMesh; + +namespace Assimp { +namespace D3MF { + +enum class ResourceType { + RT_Object, + RT_BaseMaterials, + RT_EmbeddedTexture2D, + RT_Texture2DGroup, + RT_Unknown +}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...) + +class Resource { +public: + int mId; + + Resource(int id) : + mId(id) { + // empty + } + + virtual ~Resource() { + // empty + } + + virtual ResourceType getType() const { + return ResourceType::RT_Unknown; + } +}; + +class EmbeddedTexture : public Resource { +public: + std::string mPath; + std::string mContentType; + std::string mTilestyleU; + std::string mTilestyleV; + std::vector mBuffer; + + EmbeddedTexture(int id) : + Resource(id), + mPath(), + mContentType(), + mTilestyleU(), + mTilestyleV() { + // empty + } + + ~EmbeddedTexture() = default; + + ResourceType getType() const override { + return ResourceType::RT_EmbeddedTexture2D; + } +}; + +class Texture2DGroup : public Resource { +public: + std::vector mTex2dCoords; + int mTexId; + Texture2DGroup(int id) : + Resource(id), + mTexId(-1) { + // empty + } + + ~Texture2DGroup() = default; + + ResourceType getType() const override { + return ResourceType::RT_Texture2DGroup; + } +}; + +class BaseMaterials : public Resource { +public: + std::vector mMaterialIndex; + + BaseMaterials(int id) : + Resource(id), + mMaterialIndex() { + // empty + } + + ~BaseMaterials() = default; + + ResourceType getType() const override { + return ResourceType::RT_BaseMaterials; + } +}; + +struct Component { + int mObjectId; + aiMatrix4x4 mTransformation; +}; + +class Object : public Resource { +public: + std::vector mMeshes; + std::vector mMeshIndex; + std::vector mComponents; + std::string mName; + + Object(int id) : + Resource(id), + mName(std::string("Object_") + ai_to_string(id)) { + // empty + } + + ~Object() = default; + + ResourceType getType() const override { + return ResourceType::RT_Object; + } +}; + +} // namespace D3MF +} // namespace Assimp diff --git a/Engine/lib/assimp/code/AssetLib/3MF/3MFXmlTags.h b/Engine/lib/assimp/code/AssetLib/3MF/3MFXmlTags.h new file mode 100644 index 000000000..63f18b455 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/3MF/3MFXmlTags.h @@ -0,0 +1,117 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +#pragma once + +namespace Assimp { +namespace D3MF { + +namespace XmlTag { + // Root tag + const char* const RootTag = "3MF"; + + // Meta-data + const char* const meta = "metadata"; + const char* const meta_name = "name"; + + // Model-data specific tags + const char* const model = "model"; + const char* const model_unit = "unit"; + const char* const metadata = "metadata"; + const char* const resources = "resources"; + const char* const object = "object"; + const char* const mesh = "mesh"; + const char* const components = "components"; + const char* const component = "component"; + const char* const vertices = "vertices"; + const char* const vertex = "vertex"; + const char* const triangles = "triangles"; + const char* const triangle = "triangle"; + const char* const x = "x"; + const char* const y = "y"; + const char* const z = "z"; + const char* const v1 = "v1"; + const char* const v2 = "v2"; + const char* const v3 = "v3"; + const char* const id = "id"; + const char* const pid = "pid"; + const char* const pindex = "pindex"; + const char* const p1 = "p1"; + const char* const name = "name"; + const char* const type = "type"; + const char* const build = "build"; + const char* const item = "item"; + const char* const objectid = "objectid"; + const char* const transform = "transform"; + const char *const path = "path"; + + // Material definitions + const char* const basematerials = "basematerials"; + const char* const basematerials_base = "base"; + const char* const basematerials_name = "name"; + const char* const basematerials_displaycolor = "displaycolor"; + const char* const texture_2d = "m:texture2d"; + const char *const texture_group = "m:texture2dgroup"; + const char *const texture_content_type = "contenttype"; + const char *const texture_tilestyleu = "tilestyleu"; + const char *const texture_tilestylev = "tilestylev"; + const char *const texture_2d_coord = "m:tex2coord"; + const char *const texture_cuurd_u = "u"; + const char *const texture_cuurd_v = "v"; + + // Meta info tags + const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml"; + const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels"; + const char* const SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types"; + const char* const SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships"; + const char* const RELS_RELATIONSHIP_CONTAINER = "Relationships"; + const char* const RELS_RELATIONSHIP_NODE = "Relationship"; + const char* const RELS_ATTRIB_TARGET = "Target"; + const char* const RELS_ATTRIB_TYPE = "Type"; + const char* const RELS_ATTRIB_ID = "Id"; + const char* const PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel"; + const char* const PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket"; + const char* const PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture"; + const char* const PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"; + const char* const PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"; +} + +} // Namespace D3MF +} // Namespace Assimp diff --git a/Engine/lib/assimp/code/3MF/D3MFExporter.cpp b/Engine/lib/assimp/code/AssetLib/3MF/D3MFExporter.cpp similarity index 50% rename from Engine/lib/assimp/code/3MF/D3MFExporter.cpp rename to Engine/lib/assimp/code/AssetLib/3MF/D3MFExporter.cpp index 1f388ad3e..42cd991e6 100644 --- a/Engine/lib/assimp/code/3MF/D3MFExporter.cpp +++ b/Engine/lib/assimp/code/AssetLib/3MF/D3MFExporter.cpp @@ -2,8 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -44,81 +43,74 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "D3MFExporter.h" -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include #include "3MFXmlTags.h" #include "D3MFOpcPackage.h" #ifdef ASSIMP_USE_HUNTER -# include +#include #else -# include +#include #endif namespace Assimp { -void ExportScene3MF( const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/ ) { - if ( nullptr == pIOSystem ) { - throw DeadlyExportError( "Could not export 3MP archive: " + std::string( pFile ) ); +void ExportScene3MF(const char *pFile, IOSystem *pIOSystem, const aiScene *pScene, const ExportProperties * /*pProperties*/) { + if (nullptr == pIOSystem) { + throw DeadlyExportError("Could not export 3MP archive: " + std::string(pFile)); } - D3MF::D3MFExporter myExporter( pFile, pScene ); - if ( myExporter.validate() ) { - if ( pIOSystem->Exists( pFile ) ) { - if ( !pIOSystem->DeleteFile( pFile ) ) { - throw DeadlyExportError( "File exists, cannot override : " + std::string( pFile ) ); + D3MF::D3MFExporter myExporter(pFile, pScene); + if (myExporter.validate()) { + if (pIOSystem->Exists(pFile)) { + if (!pIOSystem->DeleteFile(pFile)) { + throw DeadlyExportError("File exists, cannot override : " + std::string(pFile)); } } bool ok = myExporter.exportArchive(pFile); - if ( !ok ) { - throw DeadlyExportError( "Could not export 3MP archive: " + std::string( pFile ) ); + if (!ok) { + throw DeadlyExportError("Could not export 3MP archive: " + std::string(pFile)); } } } namespace D3MF { -D3MFExporter::D3MFExporter( const char* pFile, const aiScene* pScene ) -: mArchiveName( pFile ) -, m_zipArchive( nullptr ) -, mScene( pScene ) -, mModelOutput() -, mRelOutput() -, mContentOutput() -, mBuildItems() -, mRelations() { +D3MFExporter::D3MFExporter(const char *pFile, const aiScene *pScene) : + mArchiveName(pFile), m_zipArchive(nullptr), mScene(pScene), mModelOutput(), mRelOutput(), mContentOutput(), mBuildItems(), mRelations() { // empty } D3MFExporter::~D3MFExporter() { - for ( size_t i = 0; i < mRelations.size(); ++i ) { - delete mRelations[ i ]; + for (size_t i = 0; i < mRelations.size(); ++i) { + delete mRelations[i]; } mRelations.clear(); } bool D3MFExporter::validate() { - if ( mArchiveName.empty() ) { + if (mArchiveName.empty()) { return false; } - if ( nullptr == mScene ) { + if (nullptr == mScene) { return false; } return true; } -bool D3MFExporter::exportArchive( const char *file ) { - bool ok( true ); +bool D3MFExporter::exportArchive(const char *file) { + bool ok(true); - m_zipArchive = zip_open( file, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w' ); - if ( nullptr == m_zipArchive ) { + m_zipArchive = zip_open(file, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w'); + if (nullptr == m_zipArchive) { return false; } @@ -126,7 +118,7 @@ bool D3MFExporter::exportArchive( const char *file ) { ok |= export3DModel(); ok |= exportRelations(); - zip_close( m_zipArchive ); + zip_close(m_zipArchive); m_zipArchive = nullptr; return ok; @@ -145,7 +137,7 @@ bool D3MFExporter::exportContentTypes() { mContentOutput << std::endl; mContentOutput << ""; mContentOutput << std::endl; - exportContentTyp( XmlTag::CONTENT_TYPES_ARCHIVE ); + zipContentType(XmlTag::CONTENT_TYPES_ARCHIVE); return true; } @@ -157,20 +149,20 @@ bool D3MFExporter::exportRelations() { mRelOutput << std::endl; mRelOutput << ""; - for ( size_t i = 0; i < mRelations.size(); ++i ) { - if ( mRelations[ i ]->target[ 0 ] == '/' ) { - mRelOutput << "target << "\" "; + for (size_t i = 0; i < mRelations.size(); ++i) { + if (mRelations[i]->target[0] == '/') { + mRelOutput << "target << "\" "; } else { - mRelOutput << "target << "\" "; + mRelOutput << "target << "\" "; } mRelOutput << "Id=\"" << mRelations[i]->id << "\" "; - mRelOutput << "Type=\"" << mRelations[ i ]->type << "\" />"; + mRelOutput << "Type=\"" << mRelations[i]->type << "\" />"; mRelOutput << std::endl; } mRelOutput << ""; mRelOutput << std::endl; - writeRelInfoToFile( "_rels", ".rels" ); + zipRelInfo("_rels", ".rels"); mRelOutput.flush(); return true; @@ -181,8 +173,8 @@ bool D3MFExporter::export3DModel() { writeHeader(); mModelOutput << "<" << XmlTag::model << " " << XmlTag::model_unit << "=\"millimeter\"" - << "xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\">" - << std::endl; + << " xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\">" + << std::endl; mModelOutput << "<" << XmlTag::resources << ">"; mModelOutput << std::endl; @@ -192,7 +184,6 @@ bool D3MFExporter::export3DModel() { writeObjects(); - mModelOutput << ""; mModelOutput << std::endl; writeBuild(); @@ -203,36 +194,36 @@ bool D3MFExporter::export3DModel() { info->id = "rel0"; info->target = "/3D/3DModel.model"; info->type = XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE; - mRelations.push_back( info ); + mRelations.push_back(info); - writeModelToArchive( "3D", "3DModel.model" ); + zipModel("3D", "3DModel.model"); mModelOutput.flush(); return true; } void D3MFExporter::writeHeader() { - mModelOutput << ""; + mModelOutput << ""; mModelOutput << std::endl; } void D3MFExporter::writeMetaData() { - if ( nullptr == mScene->mMetaData ) { + if (nullptr == mScene->mMetaData) { return; } - const unsigned int numMetaEntries( mScene->mMetaData->mNumProperties ); - if ( 0 == numMetaEntries ) { + const unsigned int numMetaEntries(mScene->mMetaData->mNumProperties); + if (0 == numMetaEntries) { return; } - const aiString *key = nullptr; + const aiString *key = nullptr; const aiMetadataEntry *entry(nullptr); - for ( size_t i = 0; i < numMetaEntries; ++i ) { - mScene->mMetaData->Get( i, key, entry ); - std::string k( key->C_Str() ); + for (size_t i = 0; i < numMetaEntries; ++i) { + mScene->mMetaData->Get(i, key, entry); + std::string k(key->C_Str()); aiString value; - mScene->mMetaData->Get( k, value ); + mScene->mMetaData->Get(k, value); mModelOutput << "<" << XmlTag::meta << " " << XmlTag::meta_name << "=\"" << key->C_Str() << "\">"; mModelOutput << value.C_Str(); mModelOutput << "" << std::endl; @@ -241,159 +232,169 @@ void D3MFExporter::writeMetaData() { void D3MFExporter::writeBaseMaterials() { mModelOutput << "\n"; - std::string strName, hexDiffuseColor , tmp; - for ( size_t i = 0; i < mScene->mNumMaterials; ++i ) { - aiMaterial *mat = mScene->mMaterials[ i ]; + std::string strName, hexDiffuseColor, tmp; + for (size_t i = 0; i < mScene->mNumMaterials; ++i) { + aiMaterial *mat = mScene->mMaterials[i]; aiString name; - if ( mat->Get( AI_MATKEY_NAME, name ) != aiReturn_SUCCESS ) { - strName = "basemat_" + to_string( i ); + if (mat->Get(AI_MATKEY_NAME, name) != aiReturn_SUCCESS) { + strName = "basemat_" + ai_to_string(i); } else { strName = name.C_Str(); } aiColor4D color; - if ( mat->Get( AI_MATKEY_COLOR_DIFFUSE, color ) == aiReturn_SUCCESS ) { + if (mat->Get(AI_MATKEY_COLOR_DIFFUSE, color) == aiReturn_SUCCESS) { hexDiffuseColor.clear(); tmp.clear(); - hexDiffuseColor = "#"; - - tmp = DecimalToHexa( color.r ); - hexDiffuseColor += tmp; - tmp = DecimalToHexa( color.g ); - hexDiffuseColor += tmp; - tmp = DecimalToHexa( color.b ); - hexDiffuseColor += tmp; - tmp = DecimalToHexa( color.a ); - hexDiffuseColor += tmp; + // rgbs % + if (color.r <= 1 && color.g <= 1 && color.b <= 1 && color.a <= 1) { + + hexDiffuseColor = ai_rgba2hex( + (int)((ai_real)color.r) * 255, + (int)((ai_real)color.g) * 255, + (int)((ai_real)color.b) * 255, + (int)((ai_real)color.a) * 255, + true); + + } else { + hexDiffuseColor = "#"; + tmp = ai_decimal_to_hexa((ai_real)color.r); + hexDiffuseColor += tmp; + tmp = ai_decimal_to_hexa((ai_real)color.g); + hexDiffuseColor += tmp; + tmp = ai_decimal_to_hexa((ai_real)color.b); + hexDiffuseColor += tmp; + tmp = ai_decimal_to_hexa((ai_real)color.a); + hexDiffuseColor += tmp; + } } else { hexDiffuseColor = "#FFFFFFFF"; } - mModelOutput << "\n"; + mModelOutput << "\n"; } mModelOutput << "\n"; } void D3MFExporter::writeObjects() { - if ( nullptr == mScene->mRootNode ) { + if (nullptr == mScene->mRootNode) { return; } aiNode *root = mScene->mRootNode; - for ( unsigned int i = 0; i < root->mNumChildren; ++i ) { - aiNode *currentNode( root->mChildren[ i ] ); - if ( nullptr == currentNode ) { + for (unsigned int i = 0; i < root->mNumChildren; ++i) { + aiNode *currentNode(root->mChildren[i]); + if (nullptr == currentNode) { continue; } - mModelOutput << "<" << XmlTag::object << " id=\"" << currentNode->mName.C_Str() << "\" type=\"model\">"; + mModelOutput << "<" << XmlTag::object << " id=\"" << i + 2 << "\" type=\"model\">"; mModelOutput << std::endl; - for ( unsigned int j = 0; j < currentNode->mNumMeshes; ++j ) { - aiMesh *currentMesh = mScene->mMeshes[ currentNode->mMeshes[ j ] ]; - if ( nullptr == currentMesh ) { + for (unsigned int j = 0; j < currentNode->mNumMeshes; ++j) { + aiMesh *currentMesh = mScene->mMeshes[currentNode->mMeshes[j]]; + if (nullptr == currentMesh) { continue; } - writeMesh( currentMesh ); + writeMesh(currentMesh); } - mBuildItems.push_back( i ); + mBuildItems.push_back(i); mModelOutput << ""; mModelOutput << std::endl; } } -void D3MFExporter::writeMesh( aiMesh *mesh ) { - if ( nullptr == mesh ) { +void D3MFExporter::writeMesh(aiMesh *mesh) { + if (nullptr == mesh) { return; } - mModelOutput << "<" << XmlTag::mesh << ">" << std::endl; - mModelOutput << "<" << XmlTag::vertices << ">" << std::endl; - for ( unsigned int i = 0; i < mesh->mNumVertices; ++i ) { - writeVertex( mesh->mVertices[ i ] ); + mModelOutput << "<" + << XmlTag::mesh + << ">" << "\n"; + mModelOutput << "<" + << XmlTag::vertices + << ">" << "\n"; + for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { + writeVertex(mesh->mVertices[i]); } - mModelOutput << "" << std::endl; + mModelOutput << "" + << "\n"; - const unsigned int matIdx( mesh->mMaterialIndex ); + const unsigned int matIdx(mesh->mMaterialIndex); - writeFaces( mesh, matIdx ); + writeFaces(mesh, matIdx); - mModelOutput << "" << std::endl; + mModelOutput << "" + << "\n"; } -void D3MFExporter::writeVertex( const aiVector3D &pos ) { +void D3MFExporter::writeVertex(const aiVector3D &pos) { mModelOutput << "<" << XmlTag::vertex << " x=\"" << pos.x << "\" y=\"" << pos.y << "\" z=\"" << pos.z << "\" />"; mModelOutput << std::endl; } -void D3MFExporter::writeFaces( aiMesh *mesh, unsigned int matIdx ) { - if ( nullptr == mesh ) { +void D3MFExporter::writeFaces(aiMesh *mesh, unsigned int matIdx) { + if (nullptr == mesh) { return; } - if ( !mesh->HasFaces() ) { + if (!mesh->HasFaces()) { return; } - mModelOutput << "<" << XmlTag::triangles << ">" << std::endl; - for ( unsigned int i = 0; i < mesh->mNumFaces; ++i ) { - aiFace ¤tFace = mesh->mFaces[ i ]; - mModelOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[ 0 ] << "\" v2=\"" - << currentFace.mIndices[ 1 ] << "\" v3=\"" << currentFace.mIndices[ 2 ] - << "\" pid=\"1\" p1=\""+to_string(matIdx)+"\" />"; - mModelOutput << std::endl; + mModelOutput << "<" + << XmlTag::triangles << ">" + << "\n"; + for (unsigned int i = 0; i < mesh->mNumFaces; ++i) { + aiFace ¤tFace = mesh->mFaces[i]; + mModelOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[0] << "\" v2=\"" + << currentFace.mIndices[1] << "\" v3=\"" << currentFace.mIndices[2] + << "\" pid=\"1\" p1=\"" + ai_to_string(matIdx) + "\" />"; + mModelOutput << "\n"; } - mModelOutput << ""; - mModelOutput << std::endl; + mModelOutput << ""; + mModelOutput << "\n"; } void D3MFExporter::writeBuild() { - mModelOutput << "<" << XmlTag::build << ">" << std::endl; + mModelOutput << "<" + << XmlTag::build + << ">" + << "\n"; - for ( size_t i = 0; i < mBuildItems.size(); ++i ) { - mModelOutput << "<" << XmlTag::item << " objectid=\"" << i + 1 << "\"/>"; - mModelOutput << std::endl; + for (size_t i = 0; i < mBuildItems.size(); ++i) { + mModelOutput << "<" << XmlTag::item << " objectid=\"" << i + 2 << "\"/>"; + mModelOutput << "\n"; } mModelOutput << ""; - mModelOutput << std::endl; + mModelOutput << "\n"; } -void D3MFExporter::exportContentTyp( const std::string &filename ) { - if ( nullptr == m_zipArchive ) { - throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." ); - } - const std::string entry = filename; - zip_entry_open( m_zipArchive, entry.c_str() ); - - const std::string &exportTxt( mContentOutput.str() ); - zip_entry_write( m_zipArchive, exportTxt.c_str(), exportTxt.size() ); - - zip_entry_close( m_zipArchive ); +void D3MFExporter::zipContentType(const std::string &filename) { + addFileInZip(filename, mContentOutput.str()); } -void D3MFExporter::writeModelToArchive( const std::string &folder, const std::string &modelName ) { - if ( nullptr == m_zipArchive ) { - throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." ); - } +void D3MFExporter::zipModel(const std::string &folder, const std::string &modelName) { const std::string entry = folder + "/" + modelName; - zip_entry_open( m_zipArchive, entry.c_str() ); - - const std::string &exportTxt( mModelOutput.str() ); - zip_entry_write( m_zipArchive, exportTxt.c_str(), exportTxt.size() ); - - zip_entry_close( m_zipArchive ); + addFileInZip(entry, mModelOutput.str()); } -void D3MFExporter::writeRelInfoToFile( const std::string &folder, const std::string &relName ) { - if ( nullptr == m_zipArchive ) { - throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." ); - } +void D3MFExporter::zipRelInfo(const std::string &folder, const std::string &relName) { const std::string entry = folder + "/" + relName; - zip_entry_open( m_zipArchive, entry.c_str() ); - - const std::string &exportTxt( mRelOutput.str() ); - zip_entry_write( m_zipArchive, exportTxt.c_str(), exportTxt.size() ); - - zip_entry_close( m_zipArchive ); + addFileInZip(entry, mRelOutput.str()); } +void D3MFExporter::addFileInZip(const std::string& entry, const std::string& content) { + if (nullptr == m_zipArchive) { + throw DeadlyExportError("3MF-Export: Zip archive not valid, nullptr."); + } + + zip_entry_open(m_zipArchive, entry.c_str()); + zip_entry_write(m_zipArchive, content.c_str(), content.size()); + zip_entry_close(m_zipArchive); +} } // Namespace D3MF } // Namespace Assimp diff --git a/Engine/lib/assimp/code/3MF/D3MFExporter.h b/Engine/lib/assimp/code/AssetLib/3MF/D3MFExporter.h similarity index 89% rename from Engine/lib/assimp/code/3MF/D3MFExporter.h rename to Engine/lib/assimp/code/AssetLib/3MF/D3MFExporter.h index e82120247..680d54f91 100644 --- a/Engine/lib/assimp/code/3MF/D3MFExporter.h +++ b/Engine/lib/assimp/code/AssetLib/3MF/D3MFExporter.h @@ -2,8 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -41,6 +40,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once +#ifndef ASSIMP_BUILD_NO_EXPORT +#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER + #include #include #include @@ -59,8 +61,6 @@ class IOStream; namespace D3MF { -#ifndef ASSIMP_BUILD_NO_EXPORT -#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER struct OpcPackageRelationship; @@ -83,9 +83,12 @@ protected: void writeVertex( const aiVector3D &pos ); void writeFaces( aiMesh *mesh, unsigned int matIdx ); void writeBuild(); - void exportContentTyp( const std::string &filename ); - void writeModelToArchive( const std::string &folder, const std::string &modelName ); - void writeRelInfoToFile( const std::string &folder, const std::string &relName ); + + // Zip the data + void zipContentType( const std::string &filename ); + void zipModel( const std::string &folder, const std::string &modelName ); + void zipRelInfo( const std::string &folder, const std::string &relName ); + void addFileInZip( const std::string &entry, const std::string &content ); private: std::string mArchiveName; @@ -98,9 +101,11 @@ private: std::vector mRelations; }; -#endif // ASSIMP_BUILD_NO_3MF_EXPORTER -#endif // ASSIMP_BUILD_NO_EXPORT } // Namespace D3MF } // Namespace Assimp +#endif // ASSIMP_BUILD_NO_3MF_EXPORTER +#endif // ASSIMP_BUILD_NO_EXPORT + + diff --git a/Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.cpp b/Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.cpp new file mode 100644 index 000000000..5b0f34c3a --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.cpp @@ -0,0 +1,130 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER + +#include "D3MFImporter.h" +#include "3MFXmlTags.h" +#include "D3MFOpcPackage.h" +#include "XmlSerializer.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace Assimp { + +using namespace D3MF; + +static const aiImporterDesc desc = { + "3mf Importer", + "", + "", + "http://3mf.io/", + aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour, + 0, + 0, + 0, + 0, + "3mf" +}; + +D3MFImporter::D3MFImporter() : + BaseImporter() { + // empty +} + +D3MFImporter::~D3MFImporter() { + // empty +} + +bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const { + if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) { + return false; + } + D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename); + return opcPackage.validate(); +} + +void D3MFImporter::SetupProperties(const Importer*) { + // empty +} + +const aiImporterDesc *D3MFImporter::GetInfo() const { + return &desc; +} + +void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) { + D3MFOpcPackage opcPackage(pIOHandler, filename); + + XmlParser xmlParser; + if (xmlParser.parse(opcPackage.RootStream())) { + XmlSerializer xmlSerializer(&xmlParser); + xmlSerializer.ImportXml(pScene); + + const std::vector &tex = opcPackage.GetEmbeddedTextures(); + if (!tex.empty()) { + pScene->mNumTextures = static_cast(tex.size()); + pScene->mTextures = new aiTexture *[pScene->mNumTextures]; + for (unsigned int i = 0; i < pScene->mNumTextures; ++i) { + pScene->mTextures[i] = tex[i]; + } + } + } +} + +} // Namespace Assimp + +#endif // ASSIMP_BUILD_NO_3MF_IMPORTER diff --git a/Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.h b/Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.h new file mode 100644 index 000000000..a39ae790f --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.h @@ -0,0 +1,91 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#ifndef AI_D3MFLOADER_H_INCLUDED +#define AI_D3MFLOADER_H_INCLUDED + +#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER + +#include + +namespace Assimp { + +// --------------------------------------------------------------------------- +/// @brief The 3MF-importer class. +/// +/// Implements the basic topology import and embedded textures. +// --------------------------------------------------------------------------- +class D3MFImporter : public BaseImporter { +public: + /// @brief The default class constructor. + D3MFImporter(); + + /// @brief The class destructor. + ~D3MFImporter() override; + + /// @brief Performs the data format detection. + /// @param pFile The filename to check. + /// @param pIOHandler The used IO-System. + /// @param checkSig true for signature checking. + /// @return true for can be loaded, false for not. + bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override; + + /// @brief Not used + /// @param pImp Not used + void SetupProperties(const Importer *pImp) override; + + /// @brief The importer description getter. + /// @return The info + const aiImporterDesc *GetInfo() const override; + +protected: + /// @brief Internal read function, performs the file parsing. + /// @param pFile The filename + /// @param pScene The scene to load in. + /// @param pIOHandler The io-system + void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override; +}; + +} // Namespace Assimp + +#endif // #ifndef ASSIMP_BUILD_NO_3MF_IMPORTER + +#endif // AI_D3MFLOADER_H_INCLUDED diff --git a/Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.cpp b/Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.cpp new file mode 100644 index 000000000..f88039ae8 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.cpp @@ -0,0 +1,256 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER + +#include "D3MFOpcPackage.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "3MFXmlTags.h" + +#include +#include +#include +#include +#include + +namespace Assimp { + +namespace D3MF { +// ------------------------------------------------------------------------------------------------ + +using OpcPackageRelationshipPtr = std::shared_ptr; + +class OpcPackageRelationshipReader { +public: + OpcPackageRelationshipReader(XmlParser &parser) : + m_relationShips() { + XmlNode root = parser.getRootNode(); + ParseRootNode(root); + } + + void ParseRootNode(XmlNode &node) { + ParseAttributes(node); + for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + std::string name = currentNode.name(); + if (name == "Relationships") { + ParseRelationsNode(currentNode); + } + } + } + + void ParseAttributes(XmlNode & /*node*/) { + // empty + } + + bool validateRels(OpcPackageRelationshipPtr &relPtr) { + if (relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty()) { + return false; + } + + return true; + } + + void ParseRelationsNode(XmlNode &node) { + if (node.empty()) { + return; + } + + for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + const std::string name = currentNode.name(); + if (name == "Relationship") { + OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship()); + relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID).as_string(); + relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string(); + relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string(); + if (validateRels(relPtr)) { + m_relationShips.push_back(relPtr); + } + } + } + } + + std::vector m_relationShips; +}; + +static bool IsEmbeddedTexture( const std::string &filename ) { + const std::string extension = BaseImporter::GetExtension(filename); + if (extension == "jpg" || extension == "png") { + std::string::size_type pos = filename.find("thumbnail"); + if (pos == std::string::npos) { + return false; + } + return true; + } + + return false; +} +// ------------------------------------------------------------------------------------------------ +D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) : + mRootStream(nullptr), + mZipArchive() { + mZipArchive = new ZipArchiveIOSystem(pIOHandler, rFile); + if (!mZipArchive->isOpen()) { + throw DeadlyImportError("Failed to open file ", rFile, "."); + } + + std::vector fileList; + mZipArchive->getFileList(fileList); + + for (auto &file : fileList) { + if (file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE) { + if (!mZipArchive->Exists(file.c_str())) { + continue; + } + + IOStream *fileStream = mZipArchive->Open(file.c_str()); + if (nullptr == fileStream) { + ASSIMP_LOG_ERROR("Filestream is nullptr."); + continue; + } + + std::string rootFile = ReadPackageRootRelationship(fileStream); + if (!rootFile.empty() && rootFile[0] == '/') { + rootFile = rootFile.substr(1); + if (rootFile[0] == '/') { + // deal with zip-bug + rootFile = rootFile.substr(1); + } + } + + ASSIMP_LOG_VERBOSE_DEBUG(rootFile); + + mZipArchive->Close(fileStream); + + mRootStream = mZipArchive->Open(rootFile.c_str()); + ai_assert(mRootStream != nullptr); + if (nullptr == mRootStream) { + throw DeadlyImportError("Cannot open root-file in archive : " + rootFile); + } + } else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) { + ASSIMP_LOG_WARN("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file); + } else if (IsEmbeddedTexture(file)) { + IOStream *fileStream = mZipArchive->Open(file.c_str()); + LoadEmbeddedTextures(fileStream, file); + mZipArchive->Close(fileStream); + } else { + ASSIMP_LOG_WARN("Ignored file of unknown type: ", file); + } + } +} + +D3MFOpcPackage::~D3MFOpcPackage() { + mZipArchive->Close(mRootStream); + delete mZipArchive; +} + +IOStream *D3MFOpcPackage::RootStream() const { + return mRootStream; +} + +const std::vector &D3MFOpcPackage::GetEmbeddedTextures() const { + return mEmbeddedTextures; +} + +static const char *const ModelRef = "3D/3dmodel.model"; + +bool D3MFOpcPackage::validate() { + if (nullptr == mRootStream || nullptr == mZipArchive) { + return false; + } + + return mZipArchive->Exists(ModelRef); +} + +std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) { + XmlParser xmlParser; + if (!xmlParser.parse(stream)) { + return std::string(); + } + + OpcPackageRelationshipReader reader(xmlParser); + + auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr &rel) { + return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE; + }); + + if (itr == reader.m_relationShips.end()) { + throw DeadlyImportError("Cannot find ", XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE); + } + + return (*itr)->target; +} + +void D3MFOpcPackage::LoadEmbeddedTextures(IOStream *fileStream, const std::string &filename) { + if (nullptr == fileStream) { + return; + } + + const size_t size = fileStream->FileSize(); + if (0 == size) { + return; + } + + unsigned char *data = new unsigned char[size]; + fileStream->Read(data, 1, size); + aiTexture *texture = new aiTexture; + std::string embName = "*" + filename; + texture->mFilename.Set(embName.c_str()); + texture->mWidth = static_cast(size); + texture->mHeight = 0; + texture->achFormatHint[0] = 'p'; + texture->achFormatHint[1] = 'n'; + texture->achFormatHint[2] = 'g'; + texture->achFormatHint[3] = '\0'; + texture->pcData = (aiTexel*) data; + mEmbeddedTextures.emplace_back(texture); +} + +} // Namespace D3MF +} // Namespace Assimp + +#endif //ASSIMP_BUILD_NO_3MF_IMPORTER diff --git a/Engine/lib/assimp/code/3MF/D3MFOpcPackage.h b/Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.h similarity index 83% rename from Engine/lib/assimp/code/3MF/D3MFOpcPackage.h rename to Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.h index 87d172116..f6803a0ef 100644 --- a/Engine/lib/assimp/code/3MF/D3MFOpcPackage.h +++ b/Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.h @@ -2,8 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -43,19 +42,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef D3MFOPCPACKAGE_H #define D3MFOPCPACKAGE_H -#include - #include -#include +#include +#include + +struct aiTexture; namespace Assimp { - class ZipArchiveIOSystem; + +class ZipArchiveIOSystem; namespace D3MF { -using XmlReader = irr::io::IrrXMLReader ; -using XmlReaderPtr = std::shared_ptr ; - struct OpcPackageRelationship { std::string id; std::string type; @@ -64,20 +62,23 @@ struct OpcPackageRelationship { class D3MFOpcPackage { public: - D3MFOpcPackage( IOSystem* pIOHandler, const std::string& rFile ); + D3MFOpcPackage( IOSystem* pIOHandler, const std::string& file ); ~D3MFOpcPackage(); IOStream* RootStream() const; bool validate(); + const std::vector &GetEmbeddedTextures() const; protected: std::string ReadPackageRootRelationship(IOStream* stream); + void LoadEmbeddedTextures(IOStream *fileStream, const std::string &filename); private: IOStream* mRootStream; - std::unique_ptr mZipArchive; + ZipArchiveIOSystem *mZipArchive; + std::vector mEmbeddedTextures; }; -} // Namespace D3MF -} // Namespace Assimp +} // namespace D3MF +} // namespace Assimp #endif // D3MFOPCPACKAGE_H diff --git a/Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.cpp b/Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.cpp new file mode 100644 index 000000000..9bd1c5bb0 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.cpp @@ -0,0 +1,593 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +#include "XmlSerializer.h" +#include "D3MFOpcPackage.h" +#include "3MFXmlTags.h" +#include "3MFTypes.h" +#include + +namespace Assimp { +namespace D3MF { + +static const int IdNotSet = -1; + +namespace { + +static const size_t ColRGBA_Len = 9; +static const size_t ColRGB_Len = 7; + +// format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1) +bool validateColorString(const char *color) { + const size_t len = strlen(color); + if (ColRGBA_Len != len && ColRGB_Len != len) { + return false; + } + + return true; +} + +aiFace ReadTriangle(XmlNode &node) { + aiFace face; + + face.mNumIndices = 3; + face.mIndices = new unsigned int[face.mNumIndices]; + face.mIndices[0] = static_cast(std::atoi(node.attribute(XmlTag::v1).as_string())); + face.mIndices[1] = static_cast(std::atoi(node.attribute(XmlTag::v2).as_string())); + face.mIndices[2] = static_cast(std::atoi(node.attribute(XmlTag::v3).as_string())); + + return face; +} + +aiVector3D ReadVertex(XmlNode &node) { + aiVector3D vertex; + vertex.x = ai_strtof(node.attribute(XmlTag::x).as_string(), nullptr); + vertex.y = ai_strtof(node.attribute(XmlTag::y).as_string(), nullptr); + vertex.z = ai_strtof(node.attribute(XmlTag::z).as_string(), nullptr); + + return vertex; +} + +bool getNodeAttribute(const XmlNode &node, const std::string &attribute, std::string &value) { + pugi::xml_attribute objectAttribute = node.attribute(attribute.c_str()); + if (!objectAttribute.empty()) { + value = objectAttribute.as_string(); + return true; + } + + return false; +} + +bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) { + std::string strValue; + const bool ret = getNodeAttribute(node, attribute, strValue); + if (ret) { + value = std::atoi(strValue.c_str()); + return true; + } + + return false; +} + +aiMatrix4x4 parseTransformMatrix(std::string matrixStr) { + // split the string + std::vector numbers; + std::string currentNumber; + for (char c : matrixStr) { + if (c == ' ') { + if (!currentNumber.empty()) { + float f = std::stof(currentNumber); + numbers.push_back(f); + currentNumber.clear(); + } + } else { + currentNumber.push_back(c); + } + } + if (!currentNumber.empty()) { + const float f = std::stof(currentNumber); + numbers.push_back(f); + } + + aiMatrix4x4 transformMatrix; + transformMatrix.a1 = numbers[0]; + transformMatrix.b1 = numbers[1]; + transformMatrix.c1 = numbers[2]; + transformMatrix.d1 = 0; + + transformMatrix.a2 = numbers[3]; + transformMatrix.b2 = numbers[4]; + transformMatrix.c2 = numbers[5]; + transformMatrix.d2 = 0; + + transformMatrix.a3 = numbers[6]; + transformMatrix.b3 = numbers[7]; + transformMatrix.c3 = numbers[8]; + transformMatrix.d3 = 0; + + transformMatrix.a4 = numbers[9]; + transformMatrix.b4 = numbers[10]; + transformMatrix.c4 = numbers[11]; + transformMatrix.d4 = 1; + + return transformMatrix; +} + +bool parseColor(const char *color, aiColor4D &diffuse) { + if (nullptr == color) { + return false; + } + + if (!validateColorString(color)) { + return false; + } + + if ('#' != color[0]) { + return false; + } + + char r[3] = { color[1], color[2], '\0' }; + diffuse.r = static_cast(strtol(r, nullptr, 16)) / ai_real(255.0); + + char g[3] = { color[3], color[4], '\0' }; + diffuse.g = static_cast(strtol(g, nullptr, 16)) / ai_real(255.0); + + char b[3] = { color[5], color[6], '\0' }; + diffuse.b = static_cast(strtol(b, nullptr, 16)) / ai_real(255.0); + const size_t len = strlen(color); + if (ColRGB_Len == len) { + return true; + } + + char a[3] = { color[7], color[8], '\0' }; + diffuse.a = static_cast(strtol(a, nullptr, 16)) / ai_real(255.0); + + return true; +} + +void assignDiffuseColor(XmlNode &node, aiMaterial *mat) { + const char *color = node.attribute(XmlTag::basematerials_displaycolor).as_string(); + aiColor4D diffuse; + if (parseColor(color, diffuse)) { + mat->AddProperty(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE); + } +} + +} // namespace + +XmlSerializer::XmlSerializer(XmlParser *xmlParser) : + mResourcesDictionnary(), + mMeshCount(0), + mXmlParser(xmlParser) { + ai_assert(nullptr != xmlParser); +} + +XmlSerializer::~XmlSerializer() { + for (auto &it : mResourcesDictionnary) { + delete it.second; + } +} + +void XmlSerializer::ImportXml(aiScene *scene) { + if (nullptr == scene) { + return; + } + + scene->mRootNode = new aiNode(XmlTag::RootTag); + XmlNode node = mXmlParser->getRootNode().child(XmlTag::model); + if (node.empty()) { + return; + } + + XmlNode resNode = node.child(XmlTag::resources); + for (auto ¤tNode : resNode.children()) { + const std::string currentNodeName = currentNode.name(); + if (currentNodeName == XmlTag::texture_2d) { + ReadEmbeddecTexture(currentNode); + } else if (currentNodeName == XmlTag::texture_group) { + ReadTextureGroup(currentNode); + } else if (currentNodeName == XmlTag::object) { + ReadObject(currentNode); + } else if (currentNodeName == XmlTag::basematerials) { + ReadBaseMaterials(currentNode); + } else if (currentNodeName == XmlTag::meta) { + ReadMetadata(currentNode); + } + } + StoreMaterialsInScene(scene); + XmlNode buildNode = node.child(XmlTag::build); + if (buildNode.empty()) { + return; + } + + for (auto ¤tNode : buildNode.children()) { + const std::string currentNodeName = currentNode.name(); + if (currentNodeName == XmlTag::item) { + int objectId = IdNotSet; + std::string transformationMatrixStr; + aiMatrix4x4 transformationMatrix; + getNodeAttribute(currentNode, D3MF::XmlTag::objectid, objectId); + bool hasTransform = getNodeAttribute(currentNode, D3MF::XmlTag::transform, transformationMatrixStr); + + auto it = mResourcesDictionnary.find(objectId); + if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) { + Object *obj = static_cast(it->second); + if (hasTransform) { + transformationMatrix = parseTransformMatrix(transformationMatrixStr); + } + + addObjectToNode(scene->mRootNode, obj, transformationMatrix); + } + } + } + + // import the metadata + if (!mMetaData.empty()) { + const size_t numMeta = mMetaData.size(); + scene->mMetaData = aiMetadata::Alloc(static_cast(numMeta)); + for (size_t i = 0; i < numMeta; ++i) { + aiString val(mMetaData[i].value); + scene->mMetaData->Set(static_cast(i), mMetaData[i].name, val); + } + } + + // import the meshes, materials are already stored + scene->mNumMeshes = static_cast(mMeshCount); + if (scene->mNumMeshes != 0) { + scene->mMeshes = new aiMesh *[scene->mNumMeshes](); + for (auto &it : mResourcesDictionnary) { + if (it.second->getType() == ResourceType::RT_Object) { + Object *obj = static_cast(it.second); + ai_assert(nullptr != obj); + for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) { + scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i]; + } + } + } + } +} + +void XmlSerializer::addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform) { + ai_assert(nullptr != obj); + + aiNode *sceneNode = new aiNode(obj->mName); + sceneNode->mNumMeshes = static_cast(obj->mMeshes.size()); + sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes]; + std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes); + + sceneNode->mTransformation = nodeTransform; + if (nullptr != parent) { + parent->addChildren(1, &sceneNode); + } + + for (Assimp::D3MF::Component c : obj->mComponents) { + auto it = mResourcesDictionnary.find(c.mObjectId); + if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) { + addObjectToNode(sceneNode, static_cast(it->second), c.mTransformation); + } + } +} + +void XmlSerializer::ReadObject(XmlNode &node) { + int id = IdNotSet, pid = IdNotSet, pindex = IdNotSet; + bool hasId = getNodeAttribute(node, XmlTag::id, id); + if (!hasId) { + return; + } + + bool hasPid = getNodeAttribute(node, XmlTag::pid, pid); + bool hasPindex = getNodeAttribute(node, XmlTag::pindex, pindex); + + Object *obj = new Object(id); + for (XmlNode ¤tNode : node.children()) { + const std::string currentName = currentNode.name(); + if (currentName == D3MF::XmlTag::mesh) { + auto mesh = ReadMesh(currentNode); + mesh->mName.Set(ai_to_string(id)); + + if (hasPid) { + auto it = mResourcesDictionnary.find(pid); + if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) { + BaseMaterials *materials = static_cast(it->second); + mesh->mMaterialIndex = materials->mMaterialIndex[pindex]; + } + } + + obj->mMeshes.push_back(mesh); + obj->mMeshIndex.push_back(mMeshCount); + mMeshCount++; + } else if (currentName == D3MF::XmlTag::components) { + for (XmlNode ¤tSubNode : currentNode.children()) { + const std::string subNodeName = currentSubNode.name(); + if (subNodeName == D3MF::XmlTag::component) { + int objectId = IdNotSet; + std::string componentTransformStr; + aiMatrix4x4 componentTransform; + if (getNodeAttribute(currentSubNode, D3MF::XmlTag::transform, componentTransformStr)) { + componentTransform = parseTransformMatrix(componentTransformStr); + } + + if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) { + obj->mComponents.push_back({ objectId, componentTransform }); + } + } + } + } + } + + mResourcesDictionnary.insert(std::make_pair(id, obj)); +} + +aiMesh *XmlSerializer::ReadMesh(XmlNode &node) { + if (node.empty()) { + return nullptr; + } + + aiMesh *mesh = new aiMesh(); + for (XmlNode ¤tNode : node.children()) { + const std::string currentName = currentNode.name(); + if (currentName == XmlTag::vertices) { + ImportVertices(currentNode, mesh); + } else if (currentName == XmlTag::triangles) { + ImportTriangles(currentNode, mesh); + } + } + + return mesh; +} + +void XmlSerializer::ReadMetadata(XmlNode &node) { + pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name); + const std::string name = attribute.as_string(); + const std::string value = node.value(); + if (name.empty()) { + return; + } + + MetaEntry entry; + entry.name = name; + entry.value = value; + mMetaData.push_back(entry); +} + +void XmlSerializer::ImportVertices(XmlNode &node, aiMesh *mesh) { + ai_assert(nullptr != mesh); + + std::vector vertices; + for (XmlNode ¤tNode : node.children()) { + const std::string currentName = currentNode.name(); + if (currentName == XmlTag::vertex) { + vertices.push_back(ReadVertex(currentNode)); + } + } + + mesh->mNumVertices = static_cast(vertices.size()); + mesh->mVertices = new aiVector3D[mesh->mNumVertices]; + std::copy(vertices.begin(), vertices.end(), mesh->mVertices); +} + +void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) { + std::vector faces; + for (XmlNode ¤tNode : node.children()) { + const std::string currentName = currentNode.name(); + if (currentName == XmlTag::triangle) { + int pid = IdNotSet, p1 = IdNotSet; + bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid); + bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1); + + if (hasPid && hasP1) { + auto it = mResourcesDictionnary.find(pid); + if (it != mResourcesDictionnary.end()) { + if (it->second->getType() == ResourceType::RT_BaseMaterials) { + BaseMaterials *baseMaterials = static_cast(it->second); + mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1]; + } else if (it->second->getType() == ResourceType::RT_Texture2DGroup) { + if (mesh->mTextureCoords[0] == nullptr) { + Texture2DGroup *group = static_cast(it->second); + const std::string name = ai_to_string(group->mTexId); + for (size_t i = 0; i < mMaterials.size(); ++i) { + if (name == mMaterials[i]->GetName().C_Str()) { + mesh->mMaterialIndex = static_cast(i); + } + } + mesh->mTextureCoords[0] = new aiVector3D[group->mTex2dCoords.size()]; + for (unsigned int i = 0; i < group->mTex2dCoords.size(); ++i) { + mesh->mTextureCoords[0][i] = aiVector3D(group->mTex2dCoords[i].x, group->mTex2dCoords[i].y, 0); + } + } + } + } + } + + aiFace face = ReadTriangle(currentNode); + faces.push_back(face); + } + } + + mesh->mNumFaces = static_cast(faces.size()); + mesh->mFaces = new aiFace[mesh->mNumFaces]; + mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; + + std::copy(faces.begin(), faces.end(), mesh->mFaces); +} + +void XmlSerializer::ReadBaseMaterials(XmlNode &node) { + int id = IdNotSet; + if (getNodeAttribute(node, D3MF::XmlTag::id, id)) { + BaseMaterials *baseMaterials = new BaseMaterials(id); + + for (XmlNode ¤tNode : node.children()) { + const std::string currentName = currentNode.name(); + if (currentName == XmlTag::basematerials_base) { + baseMaterials->mMaterialIndex.push_back(static_cast(mMaterials.size())); + mMaterials.push_back(readMaterialDef(currentNode, id)); + } + } + + mResourcesDictionnary.insert(std::make_pair(id, baseMaterials)); + } +} + +void XmlSerializer::ReadEmbeddecTexture(XmlNode &node) { + if (node.empty()) { + return; + } + + std::string value; + EmbeddedTexture *tex2D = nullptr; + if (XmlParser::getStdStrAttribute(node, XmlTag::id, value)) { + tex2D = new EmbeddedTexture(atoi(value.c_str())); + } + if (nullptr == tex2D) { + return; + } + + if (XmlParser::getStdStrAttribute(node, XmlTag::path, value)) { + tex2D->mPath = value; + } + if (XmlParser::getStdStrAttribute(node, XmlTag::texture_content_type, value)) { + tex2D->mContentType = value; + } + if (XmlParser::getStdStrAttribute(node, XmlTag::texture_tilestyleu, value)) { + tex2D->mTilestyleU = value; + } + if (XmlParser::getStdStrAttribute(node, XmlTag::texture_tilestylev, value)) { + tex2D->mTilestyleV = value; + } + mEmbeddedTextures.emplace_back(tex2D); + StoreEmbeddedTexture(tex2D); +} + +void XmlSerializer::StoreEmbeddedTexture(EmbeddedTexture *tex) { + aiMaterial *mat = new aiMaterial; + aiString s; + s.Set(ai_to_string(tex->mId).c_str()); + mat->AddProperty(&s, AI_MATKEY_NAME); + const std::string name = "*" + tex->mPath; + s.Set(name); + mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0)); + + aiColor3D col; + mat->AddProperty(&col, 1, AI_MATKEY_COLOR_DIFFUSE); + mat->AddProperty(&col, 1, AI_MATKEY_COLOR_AMBIENT); + mat->AddProperty(&col, 1, AI_MATKEY_COLOR_EMISSIVE); + mat->AddProperty(&col, 1, AI_MATKEY_COLOR_SPECULAR); + mMaterials.emplace_back(mat); +} + +void XmlSerializer::ReadTextureCoords2D(XmlNode &node, Texture2DGroup *tex2DGroup) { + if (node.empty() || nullptr == tex2DGroup) { + return; + } + + int id = IdNotSet; + if (XmlParser::getIntAttribute(node, "texid", id)) { + tex2DGroup->mTexId = id; + } + + double value = 0.0; + for (XmlNode currentNode : node.children()) { + const std::string currentName = currentNode.name(); + aiVector2D texCoord; + if (currentName == XmlTag::texture_2d_coord) { + XmlParser::getDoubleAttribute(currentNode, XmlTag::texture_cuurd_u, value); + texCoord.x = (ai_real)value; + XmlParser::getDoubleAttribute(currentNode, XmlTag::texture_cuurd_v, value); + texCoord.y = (ai_real)value; + tex2DGroup->mTex2dCoords.push_back(texCoord); + } + } +} + +void XmlSerializer::ReadTextureGroup(XmlNode &node) { + if (node.empty()) { + return; + } + + int id = IdNotSet; + if (!XmlParser::getIntAttribute(node, XmlTag::id, id)) { + return; + } + + Texture2DGroup *group = new Texture2DGroup(id); + ReadTextureCoords2D(node, group); + mResourcesDictionnary.insert(std::make_pair(id, group)); +} + +aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basematerialsId) { + aiMaterial *material = new aiMaterial(); + material->mNumProperties = 0; + std::string name; + bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name); + + std::string stdMaterialName; + const std::string strId(ai_to_string(basematerialsId)); + stdMaterialName += "id"; + stdMaterialName += strId; + stdMaterialName += "_"; + if (hasName) { + stdMaterialName += std::string(name); + } else { + stdMaterialName += "basemat_"; + stdMaterialName += ai_to_string(mMaterials.size()); + } + + aiString assimpMaterialName(stdMaterialName); + material->AddProperty(&assimpMaterialName, AI_MATKEY_NAME); + + assignDiffuseColor(node, material); + + return material; +} + +void XmlSerializer::StoreMaterialsInScene(aiScene *scene) { + if (nullptr == scene || mMaterials.empty()) { + return; + } + + scene->mNumMaterials = static_cast(mMaterials.size()); + scene->mMaterials = new aiMaterial *[scene->mNumMaterials]; + for (size_t i = 0; i < mMaterials.size(); ++i) { + scene->mMaterials[i] = mMaterials[i]; + } +} + +} // namespace D3MF +} // namespace Assimp diff --git a/Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.h b/Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.h new file mode 100644 index 000000000..6cf6a70a9 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.h @@ -0,0 +1,96 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +#pragma once + +#include +#include +#include +#include + +struct aiNode; +struct aiMesh; +struct aiMaterial; + +namespace Assimp { +namespace D3MF { + +class Resource; +class D3MFOpcPackage; +class Object; +class Texture2DGroup; +class EmbeddedTexture; + +class XmlSerializer { +public: + XmlSerializer(XmlParser *xmlParser); + ~XmlSerializer(); + void ImportXml(aiScene *scene); + +private: + void addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform); + void ReadObject(XmlNode &node); + aiMesh *ReadMesh(XmlNode &node); + void ReadMetadata(XmlNode &node); + void ImportVertices(XmlNode &node, aiMesh *mesh); + void ImportTriangles(XmlNode &node, aiMesh *mesh); + void ReadBaseMaterials(XmlNode &node); + void ReadEmbeddecTexture(XmlNode &node); + void StoreEmbeddedTexture(EmbeddedTexture *tex); + void ReadTextureCoords2D(XmlNode &node, Texture2DGroup *tex2DGroup); + void ReadTextureGroup(XmlNode &node); + aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId); + void StoreMaterialsInScene(aiScene *scene); + +private: + struct MetaEntry { + std::string name; + std::string value; + }; + std::vector mMetaData; + std::vector mEmbeddedTextures; + std::vector mMaterials; + std::map mResourcesDictionnary; + unsigned int mMeshCount; + XmlParser *mXmlParser; +}; + +} // namespace D3MF +} // namespace Assimp diff --git a/Engine/lib/assimp/code/AC/ACLoader.cpp b/Engine/lib/assimp/code/AssetLib/AC/ACLoader.cpp similarity index 52% rename from Engine/lib/assimp/code/AC/ACLoader.cpp rename to Engine/lib/assimp/code/AssetLib/AC/ACLoader.cpp index d4c4bd1a6..e93624b3e 100644 --- a/Engine/lib/assimp/code/AC/ACLoader.cpp +++ b/Engine/lib/assimp/code/AssetLib/AC/ACLoader.cpp @@ -1,12 +1,9 @@ - /* --------------------------------------------------------------------------- Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -44,25 +41,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** @file Implementation of the AC3D importer class */ - - #ifndef ASSIMP_BUILD_NO_AC_IMPORTER // internal headers #include "ACLoader.h" -#include -#include -#include #include "Common/Importer.h" #include -#include +#include +#include +#include +#include +#include #include -#include #include #include -#include +#include #include -#include +#include #include using namespace Assimp; @@ -82,116 +77,103 @@ static const aiImporterDesc desc = { // ------------------------------------------------------------------------------------------------ // skip to the next token -#define AI_AC_SKIP_TO_NEXT_TOKEN() \ - if (!SkipSpaces(&buffer)) \ - { \ - ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL"); \ - continue; \ +inline const char *AcSkipToNextToken(const char *buffer) { + if (!SkipSpaces(&buffer)) { + ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL"); } + return buffer; +} // ------------------------------------------------------------------------------------------------ // read a string (may be enclosed in double quotation marks). buffer must point to " -#define AI_AC_GET_STRING(out) \ - if (*buffer == '\0') { \ - throw DeadlyImportError("AC3D: Unexpected EOF in string"); \ - } \ - ++buffer; \ - const char* sz = buffer; \ - while ('\"' != *buffer) \ - { \ - if (IsLineEnd( *buffer )) \ - { \ - ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string"); \ - out = "ERROR"; \ - break; \ - } \ - ++buffer; \ - } \ - if (IsLineEnd( *buffer ))continue; \ - out = std::string(sz,(unsigned int)(buffer-sz)); \ +inline const char *AcGetString(const char *buffer, std::string &out) { + if (*buffer == '\0') { + throw DeadlyImportError("AC3D: Unexpected EOF in string"); + } + ++buffer; + const char *sz = buffer; + while ('\"' != *buffer) { + if (IsLineEnd(*buffer)) { + ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string"); + out = "ERROR"; + break; + } + ++buffer; + } + if (IsLineEnd(*buffer)) { + return buffer; + } + out = std::string(sz, (unsigned int)(buffer - sz)); ++buffer; + return buffer; +} // ------------------------------------------------------------------------------------------------ // read 1 to n floats prefixed with an optional predefined identifier -#define AI_AC_CHECKED_LOAD_FLOAT_ARRAY(name,name_length,num,out) \ - AI_AC_SKIP_TO_NEXT_TOKEN(); \ - if (name_length) \ - { \ - if (strncmp(buffer,name,name_length) || !IsSpace(buffer[name_length])) \ - { \ - ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " name " was expected."); \ - continue; \ - } \ - buffer += name_length+1; \ - } \ - for (unsigned int i = 0; i < num;++i) \ - { \ - AI_AC_SKIP_TO_NEXT_TOKEN(); \ - buffer = fast_atoreal_move(buffer,((float*)out)[i]); \ +template +inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name, size_t name_length, size_t num, T *out) { + buffer = AcSkipToNextToken(buffer); + if (0 != name_length) { + if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) { + ASSIMP_LOG_ERROR("AC3D: Unexpected token. ", name, " was expected."); + return buffer; + } + buffer += name_length + 1; + } + for (unsigned int _i = 0; _i < num; ++_i) { + buffer = AcSkipToNextToken(buffer); + buffer = fast_atoreal_move(buffer, ((float *)out)[_i]); } + return buffer; +} // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer -AC3DImporter::AC3DImporter() - : buffer(), - configSplitBFCull(), - configEvalSubdivision(), - mNumMeshes(), - mLights(), - lights(), - groups(), - polys(), - worlds() -{ +AC3DImporter::AC3DImporter() : + buffer(), + configSplitBFCull(), + configEvalSubdivision(), + mNumMeshes(), + mLights(), + mLightsCounter(0), + mGroupsCounter(0), + mPolysCounter(0), + mWorldsCounter(0) { // nothing to be done here } // ------------------------------------------------------------------------------------------------ // Destructor, private as well -AC3DImporter::~AC3DImporter() -{ +AC3DImporter::~AC3DImporter() { // nothing to be done here } // ------------------------------------------------------------------------------------------------ // Returns whether the class can handle the format of the given file. -bool AC3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const -{ - std::string extension = GetExtension(pFile); - - // fixme: are acc and ac3d *really* used? Some sources say they are - if(extension == "ac" || extension == "ac3d" || extension == "acc") { - return true; - } - if (!extension.length() || checkSig) { - uint32_t token = AI_MAKE_MAGIC("AC3D"); - return CheckMagicToken(pIOHandler,pFile,&token,1,0); - } - return false; +bool AC3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { + static const uint32_t tokens[] = { AI_MAKE_MAGIC("AC3D") }; + return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); } // ------------------------------------------------------------------------------------------------ // Loader meta information -const aiImporterDesc* AC3DImporter::GetInfo () const -{ +const aiImporterDesc *AC3DImporter::GetInfo() const { return &desc; } // ------------------------------------------------------------------------------------------------ // Get a pointer to the next line from the file -bool AC3DImporter::GetNextLine( ) -{ +bool AC3DImporter::GetNextLine() { SkipLine(&buffer); return SkipSpaces(&buffer); } // ------------------------------------------------------------------------------------------------ // Parse an object section in an AC file -void AC3DImporter::LoadObjectSection(std::vector& objects) -{ - if (!TokenMatch(buffer,"OBJECT",6)) +void AC3DImporter::LoadObjectSection(std::vector &objects) { + if (!TokenMatch(buffer, "OBJECT", 6)) return; SkipSpaces(&buffer); @@ -199,147 +181,111 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) ++mNumMeshes; objects.push_back(Object()); - Object& obj = objects.back(); + Object &obj = objects.back(); - aiLight* light = NULL; - if (!ASSIMP_strincmp(buffer,"light",5)) - { + aiLight *light = nullptr; + if (!ASSIMP_strincmp(buffer, "light", 5)) { // This is a light source. Add it to the list mLights->push_back(light = new aiLight()); // Return a point light with no attenuation light->mType = aiLightSource_POINT; - light->mColorDiffuse = light->mColorSpecular = aiColor3D(1.f,1.f,1.f); + light->mColorDiffuse = light->mColorSpecular = aiColor3D(1.f, 1.f, 1.f); light->mAttenuationConstant = 1.f; // Generate a default name for both the light source and the node // FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version. - light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i",static_cast(mLights->size())-1); - obj.name = std::string( light->mName.data ); + light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i", static_cast(mLights->size()) - 1); + obj.name = std::string(light->mName.data); - ASSIMP_LOG_DEBUG("AC3D: Light source encountered"); + ASSIMP_LOG_VERBOSE_DEBUG("AC3D: Light source encountered"); obj.type = Object::Light; - } - else if (!ASSIMP_strincmp(buffer,"group",5)) - { + } else if (!ASSIMP_strincmp(buffer, "group", 5)) { obj.type = Object::Group; - } - else if (!ASSIMP_strincmp(buffer,"world",5)) - { + } else if (!ASSIMP_strincmp(buffer, "world", 5)) { obj.type = Object::World; - } - else obj.type = Object::Poly; - while (GetNextLine()) - { - if (TokenMatch(buffer,"kids",4)) - { + } else + obj.type = Object::Poly; + while (GetNextLine()) { + if (TokenMatch(buffer, "kids", 4)) { SkipSpaces(&buffer); - unsigned int num = strtoul10(buffer,&buffer); + unsigned int num = strtoul10(buffer, &buffer); GetNextLine(); - if (num) - { + if (num) { // load the children of this object recursively obj.children.reserve(num); for (unsigned int i = 0; i < num; ++i) LoadObjectSection(obj.children); } return; - } - else if (TokenMatch(buffer,"name",4)) - { + } else if (TokenMatch(buffer, "name", 4)) { SkipSpaces(&buffer); - AI_AC_GET_STRING(obj.name); + buffer = AcGetString(buffer, obj.name); // If this is a light source, we'll also need to store // the name of the node in it. - if (light) - { + if (light) { light->mName.Set(obj.name); } - } - else if (TokenMatch(buffer,"texture",7)) - { + } else if (TokenMatch(buffer, "texture", 7)) { SkipSpaces(&buffer); - AI_AC_GET_STRING(obj.texture); - } - else if (TokenMatch(buffer,"texrep",6)) - { + buffer = AcGetString(buffer, obj.texture); + } else if (TokenMatch(buffer, "texrep", 6)) { SkipSpaces(&buffer); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texRepeat); + buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texRepeat); if (!obj.texRepeat.x || !obj.texRepeat.y) - obj.texRepeat = aiVector2D (1.f,1.f); - } - else if (TokenMatch(buffer,"texoff",6)) - { + obj.texRepeat = aiVector2D(1.f, 1.f); + } else if (TokenMatch(buffer, "texoff", 6)) { SkipSpaces(&buffer); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texOffset); - } - else if (TokenMatch(buffer,"rot",3)) - { + buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texOffset); + } else if (TokenMatch(buffer, "rot", 3)) { SkipSpaces(&buffer); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,9,&obj.rotation); - } - else if (TokenMatch(buffer,"loc",3)) - { + buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 9, &obj.rotation); + } else if (TokenMatch(buffer, "loc", 3)) { SkipSpaces(&buffer); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&obj.translation); - } - else if (TokenMatch(buffer,"subdiv",6)) - { + buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &obj.translation); + } else if (TokenMatch(buffer, "subdiv", 6)) { SkipSpaces(&buffer); - obj.subDiv = strtoul10(buffer,&buffer); - } - else if (TokenMatch(buffer,"crease",6)) - { + obj.subDiv = strtoul10(buffer, &buffer); + } else if (TokenMatch(buffer, "crease", 6)) { SkipSpaces(&buffer); obj.crease = fast_atof(buffer); - } - else if (TokenMatch(buffer,"numvert",7)) - { + } else if (TokenMatch(buffer, "numvert", 7)) { SkipSpaces(&buffer); - unsigned int t = strtoul10(buffer,&buffer); + unsigned int t = strtoul10(buffer, &buffer); if (t >= AI_MAX_ALLOC(aiVector3D)) { throw DeadlyImportError("AC3D: Too many vertices, would run out of memory"); } obj.vertices.reserve(t); - for (unsigned int i = 0; i < t;++i) - { - if (!GetNextLine()) - { + for (unsigned int i = 0; i < t; ++i) { + if (!GetNextLine()) { ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet"); break; - } - else if (!IsNumeric(*buffer)) - { + } else if (!IsNumeric(*buffer)) { ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet"); --buffer; // make sure the line is processed a second time break; } obj.vertices.push_back(aiVector3D()); - aiVector3D& v = obj.vertices.back(); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&v.x); + aiVector3D &v = obj.vertices.back(); + buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &v.x); } - } - else if (TokenMatch(buffer,"numsurf",7)) - { + } else if (TokenMatch(buffer, "numsurf", 7)) { SkipSpaces(&buffer); bool Q3DWorkAround = false; - const unsigned int t = strtoul10(buffer,&buffer); + const unsigned int t = strtoul10(buffer, &buffer); obj.surfaces.reserve(t); - for (unsigned int i = 0; i < t;++i) - { + for (unsigned int i = 0; i < t; ++i) { GetNextLine(); - if (!TokenMatch(buffer,"SURF",4)) - { + if (!TokenMatch(buffer, "SURF", 4)) { // FIX: this can occur for some files - Quick 3D for // example writes no surf chunks - if (!Q3DWorkAround) - { + if (!Q3DWorkAround) { ASSIMP_LOG_WARN("AC3D: SURF token was expected"); - ASSIMP_LOG_DEBUG("Continuing with Quick3D Workaround enabled"); + ASSIMP_LOG_VERBOSE_DEBUG("Continuing with Quick3D Workaround enabled"); } --buffer; // make sure the line is processed a second time // break; --- see fix notes above @@ -348,27 +294,20 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) } SkipSpaces(&buffer); obj.surfaces.push_back(Surface()); - Surface& surf = obj.surfaces.back(); + Surface &surf = obj.surfaces.back(); surf.flags = strtoul_cppstyle(buffer); - while (1) - { - if(!GetNextLine()) - { + while (1) { + if (!GetNextLine()) { throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete"); } - if (TokenMatch(buffer,"mat",3)) - { + if (TokenMatch(buffer, "mat", 3)) { SkipSpaces(&buffer); surf.mat = strtoul10(buffer); - } - else if (TokenMatch(buffer,"refs",4)) - { + } else if (TokenMatch(buffer, "refs", 4)) { // --- see fix notes above - if (Q3DWorkAround) - { - if (!surf.entries.empty()) - { + if (Q3DWorkAround) { + if (!surf.entries.empty()) { buffer -= 6; break; } @@ -380,24 +319,19 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) obj.numRefs += m; - for (unsigned int k = 0; k < m; ++k) - { - if(!GetNextLine()) - { + for (unsigned int k = 0; k < m; ++k) { + if (!GetNextLine()) { ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: surface references are incomplete"); break; } surf.entries.push_back(Surface::SurfaceEntry()); - Surface::SurfaceEntry& entry = surf.entries.back(); + Surface::SurfaceEntry &entry = surf.entries.back(); - entry.first = strtoul10(buffer,&buffer); + entry.first = strtoul10(buffer, &buffer); SkipSpaces(&buffer); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&entry.second); + buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &entry.second); } - } - else - { - + } else { --buffer; // make sure the line is processed a second time break; } @@ -410,65 +344,58 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) // ------------------------------------------------------------------------------------------------ // Convert a material from AC3DImporter::Material to aiMaterial -void AC3DImporter::ConvertMaterial(const Object& object, - const Material& matSrc, - aiMaterial& matDest) -{ +void AC3DImporter::ConvertMaterial(const Object &object, + const Material &matSrc, + aiMaterial &matDest) { aiString s; - if (matSrc.name.length()) - { + if (matSrc.name.length()) { s.Set(matSrc.name); - matDest.AddProperty(&s,AI_MATKEY_NAME); + matDest.AddProperty(&s, AI_MATKEY_NAME); } - if (object.texture.length()) - { + if (object.texture.length()) { s.Set(object.texture); - matDest.AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0)); + matDest.AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0)); // UV transformation if (1.f != object.texRepeat.x || 1.f != object.texRepeat.y || - object.texOffset.x || object.texOffset.y) - { + object.texOffset.x || object.texOffset.y) { aiUVTransform transform; transform.mScaling = object.texRepeat; transform.mTranslation = object.texOffset; - matDest.AddProperty(&transform,1,AI_MATKEY_UVTRANSFORM_DIFFUSE(0)); + matDest.AddProperty(&transform, 1, AI_MATKEY_UVTRANSFORM_DIFFUSE(0)); } } - matDest.AddProperty(&matSrc.rgb,1, AI_MATKEY_COLOR_DIFFUSE); - matDest.AddProperty(&matSrc.amb,1, AI_MATKEY_COLOR_AMBIENT); - matDest.AddProperty(&matSrc.emis,1,AI_MATKEY_COLOR_EMISSIVE); - matDest.AddProperty(&matSrc.spec,1,AI_MATKEY_COLOR_SPECULAR); + matDest.AddProperty(&matSrc.rgb, 1, AI_MATKEY_COLOR_DIFFUSE); + matDest.AddProperty(&matSrc.amb, 1, AI_MATKEY_COLOR_AMBIENT); + matDest.AddProperty(&matSrc.emis, 1, AI_MATKEY_COLOR_EMISSIVE); + matDest.AddProperty(&matSrc.spec, 1, AI_MATKEY_COLOR_SPECULAR); - int n; - if (matSrc.shin) - { + int n = -1; + if (matSrc.shin) { n = aiShadingMode_Phong; - matDest.AddProperty(&matSrc.shin,1,AI_MATKEY_SHININESS); + matDest.AddProperty(&matSrc.shin, 1, AI_MATKEY_SHININESS); + } else { + n = aiShadingMode_Gouraud; } - else n = aiShadingMode_Gouraud; - matDest.AddProperty(&n,1,AI_MATKEY_SHADING_MODEL); + matDest.AddProperty(&n, 1, AI_MATKEY_SHADING_MODEL); float f = 1.f - matSrc.trans; - matDest.AddProperty(&f,1,AI_MATKEY_OPACITY); + matDest.AddProperty(&f, 1, AI_MATKEY_OPACITY); } // ------------------------------------------------------------------------------------------------ // Converts the loaded data to the internal verbose representation -aiNode* AC3DImporter::ConvertObjectSection(Object& object, - std::vector& meshes, - std::vector& outMaterials, - const std::vector& materials, - aiNode* parent) -{ - aiNode* node = new aiNode(); +aiNode *AC3DImporter::ConvertObjectSection(Object &object, + std::vector &meshes, + std::vector &outMaterials, + const std::vector &materials, + aiNode *parent) { + aiNode *node = new aiNode(); node->mParent = parent; - if (object.vertices.size()) - { - if (!object.surfaces.size() || !object.numRefs) - { + if (object.vertices.size()) { + if (!object.surfaces.size() || !object.numRefs) { /* " An object with 7 vertices (no surfaces, no materials defined). This is a good way of getting point data into AC3D. The Vertex->create convex-surface/object can be used on these @@ -479,17 +406,16 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, */ ASSIMP_LOG_INFO("AC3D: No surfaces defined in object definition, " - "a point list is returned"); + "a point list is returned"); meshes.push_back(new aiMesh()); - aiMesh* mesh = meshes.back(); + aiMesh *mesh = meshes.back(); mesh->mNumFaces = mesh->mNumVertices = (unsigned int)object.vertices.size(); - aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; - aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; + aiFace *faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; + aiVector3D *verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - for (unsigned int i = 0; i < mesh->mNumVertices;++i,++faces,++verts) - { + for (unsigned int i = 0; i < mesh->mNumVertices; ++i, ++faces, ++verts) { *verts = object.vertices[i]; faces->mNumIndices = 1; faces->mIndices = new unsigned int[1]; @@ -502,89 +428,88 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, mesh->mMaterialIndex = 0; outMaterials.push_back(new aiMaterial()); ConvertMaterial(object, materials[0], *outMaterials.back()); - } - else - { + } else { // need to generate one or more meshes for this object. // find out how many different materials we have - typedef std::pair< unsigned int, unsigned int > IntPair; - typedef std::vector< IntPair > MatTable; - MatTable needMat(materials.size(),IntPair(0,0)); + typedef std::pair IntPair; + typedef std::vector MatTable; + MatTable needMat(materials.size(), IntPair(0, 0)); - std::vector::iterator it,end = object.surfaces.end(); - std::vector::iterator it2,end2; + std::vector::iterator it, end = object.surfaces.end(); + std::vector::iterator it2, end2; - for (it = object.surfaces.begin(); it != end; ++it) - { + for (it = object.surfaces.begin(); it != end; ++it) { unsigned int idx = (*it).mat; - if (idx >= needMat.size()) - { + if (idx >= needMat.size()) { ASSIMP_LOG_ERROR("AC3D: material index is out of range"); idx = 0; } - if ((*it).entries.empty()) - { + if ((*it).entries.empty()) { ASSIMP_LOG_WARN("AC3D: surface her zero vertex references"); } // validate all vertex indices to make sure we won't crash here - for (it2 = (*it).entries.begin(), - end2 = (*it).entries.end(); it2 != end2; ++it2) - { - if ((*it2).first >= object.vertices.size()) - { + for (it2 = (*it).entries.begin(), + end2 = (*it).entries.end(); + it2 != end2; ++it2) { + if ((*it2).first >= object.vertices.size()) { ASSIMP_LOG_WARN("AC3D: Invalid vertex reference"); (*it2).first = 0; } } - if (!needMat[idx].first)++node->mNumMeshes; + if (!needMat[idx].first) { + ++node->mNumMeshes; + } - switch ((*it).flags & 0xf) - { + switch ((*it).GetType()) { // closed line - case 0x1: - - needMat[idx].first += (unsigned int)(*it).entries.size(); - needMat[idx].second += (unsigned int)(*it).entries.size()<<1u; + case Surface::ClosedLine: + needMat[idx].first += (unsigned int)(*it).entries.size(); + needMat[idx].second += (unsigned int)(*it).entries.size() << 1u; break; // unclosed line - case 0x2: - - needMat[idx].first += (unsigned int)(*it).entries.size()-1; - needMat[idx].second += ((unsigned int)(*it).entries.size()-1)<<1u; + case Surface::OpenLine: + needMat[idx].first += (unsigned int)(*it).entries.size() - 1; + needMat[idx].second += ((unsigned int)(*it).entries.size() - 1) << 1u; + break; + + // triangle strip + case Surface::TriangleStrip: + needMat[idx].first += (unsigned int)(*it).entries.size() - 2; + needMat[idx].second += ((unsigned int)(*it).entries.size() - 2) * 3; break; - // 0 == polygon, else unknown default: + // Coerce unknowns to a polygon and warn + ASSIMP_LOG_WARN("AC3D: The type flag of a surface is unknown: ", (*it).flags); + (*it).flags &= ~(Surface::Mask); + // fallthrough - if ((*it).flags & 0xf) - { - ASSIMP_LOG_WARN("AC3D: The type flag of a surface is unknown"); - (*it).flags &= ~(0xf); - } - + // polygon + case Surface::Polygon: // the number of faces increments by one, the number // of vertices by surface.numref. needMat[idx].first++; needMat[idx].second += (unsigned int)(*it).entries.size(); }; } - unsigned int* pip = node->mMeshes = new unsigned int[node->mNumMeshes]; + unsigned int *pip = node->mMeshes = new unsigned int[node->mNumMeshes]; unsigned int mat = 0; const size_t oldm = meshes.size(); for (MatTable::const_iterator cit = needMat.begin(), cend = needMat.end(); - cit != cend; ++cit, ++mat) - { - if (!(*cit).first)continue; + cit != cend; ++cit, ++mat) { + if (!(*cit).first) { + continue; + } // allocate a new aiMesh object *pip++ = (unsigned int)meshes.size(); - aiMesh* mesh = new aiMesh(); + aiMesh *mesh = new aiMesh(); meshes.push_back(mesh); - mesh->mMaterialIndex = (unsigned int)outMaterials.size(); + mesh->mMaterialIndex = static_cast(outMaterials.size()); outMaterials.push_back(new aiMaterial()); ConvertMaterial(object, materials[mat], *outMaterials.back()); @@ -595,7 +520,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, } else if (mesh->mNumFaces > AI_MAX_ALLOC(aiFace)) { throw DeadlyImportError("AC3D: Too many faces, would run out of memory"); } - aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; + aiFace *faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; mesh->mNumVertices = (*cit).second; if (mesh->mNumVertices == 0) { @@ -603,35 +528,30 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, } else if (mesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) { throw DeadlyImportError("AC3D: Too many vertices, would run out of memory"); } - aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; + aiVector3D *vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; unsigned int cur = 0; // allocate UV coordinates, but only if the texture name for the // surface is not empty - aiVector3D* uv = NULL; - if(object.texture.length()) - { + aiVector3D *uv = nullptr; + if (object.texture.length()) { uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; mesh->mNumUVComponents[0] = 2; } - for (it = object.surfaces.begin(); it != end; ++it) - { - if (mat == (*it).mat) - { - const Surface& src = *it; + for (it = object.surfaces.begin(); it != end; ++it) { + if (mat == (*it).mat) { + const Surface &src = *it; // closed polygon - unsigned int type = (*it).flags & 0xf; - if (!type) - { - aiFace& face = *faces++; - if((face.mNumIndices = (unsigned int)src.entries.size())) - { + uint8_t type = (*it).GetType(); + if (type == Surface::Polygon) { + aiFace &face = *faces++; + face.mNumIndices = (unsigned int)src.entries.size(); + if (0 != face.mNumIndices) { face.mIndices = new unsigned int[face.mNumIndices]; - for (unsigned int i = 0; i < face.mNumIndices;++i,++vertices) - { - const Surface::SurfaceEntry& entry = src.entries[i]; + for (unsigned int i = 0; i < face.mNumIndices; ++i, ++vertices) { + const Surface::SurfaceEntry &entry = src.entries[i]; face.mIndices[i] = cur++; // copy vertex positions @@ -640,28 +560,81 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, } *vertices = object.vertices[entry.first] + object.translation; - // copy texture coordinates - if (uv) - { - uv->x = entry.second.x; - uv->y = entry.second.y; + if (uv) { + uv->x = entry.second.x; + uv->y = entry.second.y; ++uv; } } } - } - else - { + } else if (type == Surface::TriangleStrip) { + for (unsigned int i = 0; i < (unsigned int)src.entries.size() - 2; ++i) { + const Surface::SurfaceEntry &entry1 = src.entries[i]; + const Surface::SurfaceEntry &entry2 = src.entries[i + 1]; + const Surface::SurfaceEntry &entry3 = src.entries[i + 2]; - it2 = (*it).entries.begin(); + // skip degenerate triangles + if (object.vertices[entry1.first] == object.vertices[entry2.first] || + object.vertices[entry1.first] == object.vertices[entry3.first] || + object.vertices[entry2.first] == object.vertices[entry3.first]) { + mesh->mNumFaces--; + mesh->mNumVertices -= 3; + continue; + } + + aiFace &face = *faces++; + face.mNumIndices = 3; + face.mIndices = new unsigned int[face.mNumIndices]; + face.mIndices[0] = cur++; + face.mIndices[1] = cur++; + face.mIndices[2] = cur++; + if (!(i & 1)) { + *vertices++ = object.vertices[entry1.first] + object.translation; + if (uv) { + uv->x = entry1.second.x; + uv->y = entry1.second.y; + ++uv; + } + *vertices++ = object.vertices[entry2.first] + object.translation; + if (uv) { + uv->x = entry2.second.x; + uv->y = entry2.second.y; + ++uv; + } + } else { + *vertices++ = object.vertices[entry2.first] + object.translation; + if (uv) { + uv->x = entry2.second.x; + uv->y = entry2.second.y; + ++uv; + } + *vertices++ = object.vertices[entry1.first] + object.translation; + if (uv) { + uv->x = entry1.second.x; + uv->y = entry1.second.y; + ++uv; + } + } + if (static_cast(vertices - mesh->mVertices) >= mesh->mNumVertices) { + throw DeadlyImportError("AC3D: Invalid number of vertices"); + } + *vertices++ = object.vertices[entry3.first] + object.translation; + if (uv) { + uv->x = entry3.second.x; + uv->y = entry3.second.y; + ++uv; + } + } + } else { + + it2 = (*it).entries.begin(); // either a closed or an unclosed line unsigned int tmp = (unsigned int)(*it).entries.size(); - if (0x2 == type)--tmp; - for (unsigned int m = 0; m < tmp;++m) - { - aiFace& face = *faces++; + if (Surface::OpenLine == type) --tmp; + for (unsigned int m = 0; m < tmp; ++m) { + aiFace &face = *faces++; face.mNumIndices = 2; face.mIndices = new unsigned int[2]; @@ -669,35 +642,31 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, face.mIndices[1] = cur++; // copy vertex positions - if (it2 == (*it).entries.end() ) { + if (it2 == (*it).entries.end()) { throw DeadlyImportError("AC3D: Bad line"); } ai_assert((*it2).first < object.vertices.size()); *vertices++ = object.vertices[(*it2).first]; // copy texture coordinates - if (uv) - { - uv->x = (*it2).second.x; - uv->y = (*it2).second.y; + if (uv) { + uv->x = (*it2).second.x; + uv->y = (*it2).second.y; ++uv; } - - if (0x1 == type && tmp-1 == m) - { + if (Surface::ClosedLine == type && tmp - 1 == m) { // if this is a closed line repeat its beginning now - it2 = (*it).entries.begin(); - } - else ++it2; + it2 = (*it).entries.begin(); + } else + ++it2; // second point *vertices++ = object.vertices[(*it2).first]; - if (uv) - { - uv->x = (*it2).second.x; - uv->y = (*it2).second.y; + if (uv) { + uv->x = (*it2).second.x; + uv->y = (*it2).second.y; ++uv; } } @@ -709,20 +678,18 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, // Now apply catmull clark subdivision if necessary. We split meshes into // materials which is not done by AC3D during smoothing, so we need to // collect all meshes using the same material group. - if (object.subDiv) { + if (object.subDiv) { if (configEvalSubdivision) { std::unique_ptr div(Subdivider::Create(Subdivider::CATMULL_CLARKE)); - ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: "+object.name); + ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: ", object.name); - std::vector cpy(meshes.size()-oldm,NULL); - div->Subdivide(&meshes[oldm],cpy.size(),&cpy.front(),object.subDiv,true); - std::copy(cpy.begin(),cpy.end(),meshes.begin()+oldm); + std::vector cpy(meshes.size() - oldm, nullptr); + div->Subdivide(&meshes[oldm], cpy.size(), &cpy.front(), object.subDiv, true); + std::copy(cpy.begin(), cpy.end(), meshes.begin() + oldm); // previous meshes are deleted vy Subdivide(). - } - else { - ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: " - +object.name); + } else { + ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: ", object.name); } } } @@ -730,48 +697,42 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, if (object.name.length()) node->mName.Set(object.name); - else - { + else { // generate a name depending on the type of the node - switch (object.type) - { + switch (object.type) { case Object::Group: - node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i",groups++); + node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i", mGroupsCounter++); break; case Object::Poly: - node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i",polys++); + node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i", mPolysCounter++); break; case Object::Light: - node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i",lights++); + node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i", mLightsCounter++); break; // there shouldn't be more than one world, but we don't care case Object::World: - node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i",worlds++); + node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i", mWorldsCounter++); break; } } - // setup the local transformation matrix of the object // compute the transformation offset to the parent node - node->mTransformation = aiMatrix4x4 ( object.rotation ); + node->mTransformation = aiMatrix4x4(object.rotation); - if (object.type == Object::Group || !object.numRefs) - { + if (object.type == Object::Group || !object.numRefs) { node->mTransformation.a4 = object.translation.x; node->mTransformation.b4 = object.translation.y; node->mTransformation.c4 = object.translation.z; } // add children to the object - if (object.children.size()) - { + if (object.children.size()) { node->mNumChildren = (unsigned int)object.children.size(); - node->mChildren = new aiNode*[node->mNumChildren]; - for (unsigned int i = 0; i < node->mNumChildren;++i) - { - node->mChildren[i] = ConvertObjectSection(object.children[i],meshes,outMaterials,materials,node); + node->mChildren = new aiNode *[node->mNumChildren]; + for (unsigned int i = 0; i < node->mNumChildren; ++i) { + node->mChildren[i] = ConvertObjectSection(object.children[i], meshes, outMaterials, materials, node); } } @@ -779,41 +740,40 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, } // ------------------------------------------------------------------------------------------------ -void AC3DImporter::SetupProperties(const Importer* pImp) -{ - configSplitBFCull = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL,1) ? true : false; - configEvalSubdivision = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION,1) ? true : false; +void AC3DImporter::SetupProperties(const Importer *pImp) { + configSplitBFCull = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL, 1) ? true : false; + configEvalSubdivision = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION, 1) ? true : false; } // ------------------------------------------------------------------------------------------------ // Imports the given file into the given scene structure. -void AC3DImporter::InternReadFile( const std::string& pFile, - aiScene* pScene, IOSystem* pIOHandler) -{ - std::unique_ptr file( pIOHandler->Open( pFile, "rb")); +void AC3DImporter::InternReadFile(const std::string &pFile, + aiScene *pScene, IOSystem *pIOHandler) { + std::unique_ptr file(pIOHandler->Open(pFile, "rb")); // Check whether we can read from the file - if( file.get() == NULL) - throw DeadlyImportError( "Failed to open AC3D file " + pFile + "."); + if (file.get() == nullptr) { + throw DeadlyImportError("Failed to open AC3D file ", pFile, "."); + } // allocate storage and copy the contents of the file to a memory buffer std::vector mBuffer2; - TextFileToBuffer(file.get(),mBuffer2); + TextFileToBuffer(file.get(), mBuffer2); buffer = &mBuffer2[0]; mNumMeshes = 0; - lights = polys = worlds = groups = 0; + mLightsCounter = mPolysCounter = mWorldsCounter = mGroupsCounter = 0; - if (::strncmp(buffer,"AC3D",4)) { + if (::strncmp(buffer, "AC3D", 4)) { throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found"); } // print the file format version to the console - unsigned int version = HexDigitToDecimal( buffer[4] ); + unsigned int version = HexDigitToDecimal(buffer[4]); char msg[3]; - ASSIMP_itoa10(msg,3,version); - ASSIMP_LOG_INFO_F("AC3D file format version: ", msg); + ASSIMP_itoa10(msg, 3, version); + ASSIMP_LOG_INFO("AC3D file format version: ", msg); std::vector materials; materials.reserve(5); @@ -821,89 +781,84 @@ void AC3DImporter::InternReadFile( const std::string& pFile, std::vector rootObjects; rootObjects.reserve(5); - std::vector lights; - mLights = & lights; + std::vector lights; + mLights = &lights; - while (GetNextLine()) - { - if (TokenMatch(buffer,"MATERIAL",8)) - { + while (GetNextLine()) { + if (TokenMatch(buffer, "MATERIAL", 8)) { materials.push_back(Material()); - Material& mat = materials.back(); + Material &mat = materials.back(); // manually parse the material ... sscanf would use the buldin atof ... // Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f - AI_AC_SKIP_TO_NEXT_TOKEN(); - if ('\"' == *buffer) - { - AI_AC_GET_STRING(mat.name); - AI_AC_SKIP_TO_NEXT_TOKEN(); + buffer = AcSkipToNextToken(buffer); + if ('\"' == *buffer) { + buffer = AcGetString(buffer, mat.name); + buffer = AcSkipToNextToken(buffer); } - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("rgb",3,3,&mat.rgb); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("amb",3,3,&mat.amb); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("emis",4,3,&mat.emis); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("spec",4,3,&mat.spec); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("shi",3,1,&mat.shin); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("trans",5,1,&mat.trans); + buffer = TAcCheckedLoadFloatArray(buffer, "rgb", 3, 3, &mat.rgb); + buffer = TAcCheckedLoadFloatArray(buffer, "amb", 3, 3, &mat.amb); + buffer = TAcCheckedLoadFloatArray(buffer, "emis", 4, 3, &mat.emis); + buffer = TAcCheckedLoadFloatArray(buffer, "spec", 4, 3, &mat.spec); + buffer = TAcCheckedLoadFloatArray(buffer, "shi", 3, 1, &mat.shin); + buffer = TAcCheckedLoadFloatArray(buffer, "trans", 5, 1, &mat.trans); } LoadObjectSection(rootObjects); } - if (rootObjects.empty() || !mNumMeshes) - { + if (rootObjects.empty() || !mNumMeshes) { throw DeadlyImportError("AC3D: No meshes have been loaded"); } - if (materials.empty()) - { + if (materials.empty()) { ASSIMP_LOG_WARN("AC3D: No material has been found"); materials.push_back(Material()); } - mNumMeshes += (mNumMeshes>>2u) + 1; - std::vector meshes; + mNumMeshes += (mNumMeshes >> 2u) + 1; + std::vector meshes; meshes.reserve(mNumMeshes); - std::vector omaterials; + std::vector omaterials; materials.reserve(mNumMeshes); // generate a dummy root if there are multiple objects on the top layer - Object* root; + Object *root; if (1 == rootObjects.size()) root = &rootObjects[0]; - else - { + else { root = new Object(); } // now convert the imported stuff to our output data structure - pScene->mRootNode = ConvertObjectSection(*root,meshes,omaterials,materials); - if (1 != rootObjects.size())delete root; + pScene->mRootNode = ConvertObjectSection(*root, meshes, omaterials, materials); + if (1 != rootObjects.size()) { + delete root; + } - if (!::strncmp( pScene->mRootNode->mName.data, "Node", 4)) + if (!::strncmp(pScene->mRootNode->mName.data, "Node", 4)) { pScene->mRootNode->mName.Set(""); + } // copy meshes - if (meshes.empty()) - { + if (meshes.empty()) { throw DeadlyImportError("An unknown error occurred during converting"); } pScene->mNumMeshes = (unsigned int)meshes.size(); - pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; - ::memcpy(pScene->mMeshes,&meshes[0],pScene->mNumMeshes*sizeof(void*)); + pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; + ::memcpy(pScene->mMeshes, &meshes[0], pScene->mNumMeshes * sizeof(void *)); // copy materials pScene->mNumMaterials = (unsigned int)omaterials.size(); - pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; - ::memcpy(pScene->mMaterials,&omaterials[0],pScene->mNumMaterials*sizeof(void*)); + pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials]; + ::memcpy(pScene->mMaterials, &omaterials[0], pScene->mNumMaterials * sizeof(void *)); // copy lights pScene->mNumLights = (unsigned int)lights.size(); - if (lights.size()) - { - pScene->mLights = new aiLight*[lights.size()]; - ::memcpy(pScene->mLights,&lights[0],lights.size()*sizeof(void*)); + if (lights.size()) { + pScene->mLights = new aiLight *[lights.size()]; + ::memcpy(pScene->mLights, &lights[0], lights.size() * sizeof(void *)); } } diff --git a/Engine/lib/assimp/code/AC/ACLoader.h b/Engine/lib/assimp/code/AssetLib/AC/ACLoader.h similarity index 73% rename from Engine/lib/assimp/code/AC/ACLoader.h rename to Engine/lib/assimp/code/AssetLib/AC/ACLoader.h index cab2c3ae5..aabc114e3 100644 --- a/Engine/lib/assimp/code/AC/ACLoader.h +++ b/Engine/lib/assimp/code/AssetLib/AC/ACLoader.h @@ -2,8 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -56,29 +55,23 @@ struct aiMesh; struct aiMaterial; struct aiLight; - -namespace Assimp { +namespace Assimp { // --------------------------------------------------------------------------- /** AC3D (*.ac) importer class */ -class AC3DImporter : public BaseImporter -{ +class AC3DImporter : public BaseImporter { public: AC3DImporter(); - ~AC3DImporter(); - - + ~AC3DImporter() override; // Represents an AC3D material - struct Material - { - Material() - : rgb (0.6f,0.6f,0.6f) - , spec (1.f,1.f,1.f) - , shin (0.f) - , trans (0.f) - {} + struct Material { + Material() : + rgb(0.6f, 0.6f, 0.6f), + spec(1.f, 1.f, 1.f), + shin(0.f), + trans(0.f) {} // base color of the material aiColor3D rgb; @@ -103,43 +96,50 @@ public: }; // Represents an AC3D surface - struct Surface - { - Surface() - : mat (0) - , flags (0) - {} + struct Surface { + Surface() : + mat(0), + flags(0) {} - unsigned int mat,flags; + unsigned int mat, flags; - typedef std::pair SurfaceEntry; - std::vector< SurfaceEntry > entries; + typedef std::pair SurfaceEntry; + std::vector entries; + + // Type is low nibble of flags + enum Type : uint8_t { + Polygon = 0x0, + ClosedLine = 0x1, + OpenLine = 0x2, + TriangleStrip = 0x4, // ACC extension (TORCS and Speed Dreams) + + Mask = 0xf, + }; + + inline uint8_t GetType() const { return (flags & Mask); } }; // Represents an AC3D object - struct Object - { - Object() - : type (World) - , name( "" ) - , children() - , texture( "" ) - , texRepeat( 1.f, 1.f ) - , texOffset( 0.0f, 0.0f ) - , rotation() - , translation() - , vertices() - , surfaces() - , numRefs (0) - , subDiv (0) - , crease() - {} + struct Object { + Object() : + type(World), + name(), + children(), + texture(), + texRepeat(1.f, 1.f), + texOffset(0.0f, 0.0f), + rotation(), + translation(), + vertices(), + surfaces(), + numRefs(0), + subDiv(0), + crease() {} // Type description - enum Type - { + enum Type { World = 0x0, - Poly = 0x1, + Poly = 0x1, Group = 0x2, Light = 0x4 } type; @@ -179,37 +179,33 @@ public: float crease; }; - public: - // ------------------------------------------------------------------- /** Returns whether the class can handle the format of the given file. * See BaseImporter::CanRead() for details. */ - bool CanRead( const std::string& pFile, IOSystem* pIOHandler, - bool checkSig) const; + bool CanRead(const std::string &pFile, IOSystem *pIOHandler, + bool checkSig) const override; protected: - // ------------------------------------------------------------------- /** Return importer meta information. * See #BaseImporter::GetInfo for the details */ - const aiImporterDesc* GetInfo () const; + const aiImporterDesc *GetInfo() const override; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. * See BaseImporter::InternReadFile() for details*/ - void InternReadFile( const std::string& pFile, aiScene* pScene, - IOSystem* pIOHandler); + void InternReadFile(const std::string &pFile, aiScene *pScene, + IOSystem *pIOHandler) override; // ------------------------------------------------------------------- /** Called prior to ReadFile(). * The function is a request to the importer to update its configuration * basing on the Importer's configuration property list.*/ - void SetupProperties(const Importer* pImp); + void SetupProperties(const Importer *pImp) override; private: - // ------------------------------------------------------------------- /** Get the next line from the file. * @return false if the end of the file was reached*/ @@ -220,7 +216,7 @@ private: * load subobjects, the method returns after a 'kids 0' was * encountered. * @objects List of output objects*/ - void LoadObjectSection(std::vector& objects); + void LoadObjectSection(std::vector &objects); // ------------------------------------------------------------------- /** Convert all objects into meshes and nodes. @@ -229,26 +225,24 @@ private: * @param outMaterials List of output materials * @param materials Material list * @param Scenegraph node for the object */ - aiNode* ConvertObjectSection(Object& object, - std::vector& meshes, - std::vector& outMaterials, - const std::vector& materials, - aiNode* parent = NULL); + aiNode *ConvertObjectSection(Object &object, + std::vector &meshes, + std::vector &outMaterials, + const std::vector &materials, + aiNode *parent = nullptr); // ------------------------------------------------------------------- /** Convert a material * @param object Current object * @param matSrc Source material description * @param matDest Destination material to be filled */ - void ConvertMaterial(const Object& object, - const Material& matSrc, - aiMaterial& matDest); + void ConvertMaterial(const Object &object, + const Material &matSrc, + aiMaterial &matDest); private: - - // points to the next data line - const char* buffer; + const char *buffer; // Configuration option: if enabled, up to two meshes // are generated per material: those faces who have @@ -265,10 +259,10 @@ private: unsigned int mNumMeshes; // current list of light sources - std::vector* mLights; + std::vector *mLights; // name counters - unsigned int lights, groups, polys, worlds; + unsigned int mLightsCounter, mGroupsCounter, mPolysCounter, mWorldsCounter; }; } // end of namespace Assimp diff --git a/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter.cpp b/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter.cpp new file mode 100644 index 000000000..4103dcdf4 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter.cpp @@ -0,0 +1,524 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER + +// Header files, Assimp. +#include "AMFImporter.hpp" + +#include +#include +#include + +// Header files, stdlib. +#include + +namespace Assimp { + +const aiImporterDesc AMFImporter::Description = { + "Additive manufacturing file format(AMF) Importer", + "smalcom", + "", + "See documentation in source code. Chapter: Limitations.", + aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental, + 0, + 0, + 0, + 0, + "amf" +}; + +void AMFImporter::Clear() { + mNodeElement_Cur = nullptr; + mUnit.clear(); + mMaterial_Converted.clear(); + mTexture_Converted.clear(); + // Delete all elements + if (!mNodeElement_List.empty()) { + for (AMFNodeElementBase *ne : mNodeElement_List) { + delete ne; + } + + mNodeElement_List.clear(); + } +} + +AMFImporter::AMFImporter() AI_NO_EXCEPT : + mNodeElement_Cur(nullptr), + mXmlParser(nullptr), + mUnit(), + mVersion(), + mMaterial_Converted(), + mTexture_Converted() { + // empty +} + +AMFImporter::~AMFImporter() { + delete mXmlParser; + // Clear() is accounting if data already is deleted. So, just check again if all data is deleted. + Clear(); +} + +/*********************************************************************************************************************************************/ +/************************************************************ Functions: find set ************************************************************/ +/*********************************************************************************************************************************************/ + +bool AMFImporter::Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const { + for (AMFNodeElementBase *ne : mNodeElement_List) { + if ((ne->ID == pID) && (ne->Type == pType)) { + if (pNodeElement != nullptr) { + *pNodeElement = ne; + } + + return true; + } + } // for(CAMFImporter_NodeElement* ne: mNodeElement_List) + + return false; +} + +bool AMFImporter::Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const { + aiString node_name(pID.c_str()); + for (aiNode *node : nodeArray) { + if (node->mName == node_name) { + if (pNode != nullptr) { + *pNode = node; + } + + return true; + } + } // for(aiNode* node: pNodeList) + + return false; +} + +bool AMFImporter::Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const { + for (const SPP_Material &mat : mMaterial_Converted) { + if (mat.ID == pID) { + if (pConvertedMaterial != nullptr) { + *pConvertedMaterial = &mat; + } + + return true; + } + } // for(const SPP_Material& mat: mMaterial_Converted) + + return false; +} + +/*********************************************************************************************************************************************/ +/************************************************************ Functions: throw set ***********************************************************/ +/*********************************************************************************************************************************************/ + +void AMFImporter::Throw_CloseNotFound(const std::string &nodeName) { + throw DeadlyImportError("Close tag for node <" + nodeName + "> not found. Seems file is corrupt."); +} + +void AMFImporter::Throw_IncorrectAttr(const std::string &nodeName, const std::string &attrName) { + throw DeadlyImportError("Node <" + nodeName + "> has incorrect attribute \"" + attrName + "\"."); +} + +void AMFImporter::Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &attrName) { + throw DeadlyImportError("Attribute \"" + attrName + "\" in node <" + nodeName + "> has incorrect value."); +} + +void AMFImporter::Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) { + throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + nodeName + ". Description: " + pDescription); +} + +void AMFImporter::Throw_ID_NotFound(const std::string &pID) const { + throw DeadlyImportError("Not found node with name \"", pID, "\"."); +} + +/*********************************************************************************************************************************************/ +/************************************************************* Functions: XML set ************************************************************/ +/*********************************************************************************************************************************************/ + +void AMFImporter::XML_CheckNode_MustHaveChildren(pugi::xml_node &node) { + if (node.children().begin() == node.children().end()) { + throw DeadlyImportError(std::string("Node <") + node.name() + "> must have children."); + } +} + +bool AMFImporter::XML_SearchNode(const std::string &nodeName) { + return nullptr != mXmlParser->findNode(nodeName); +} + +void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString) { + size_t instr_len; + + pOutString.clear(); + instr_len = strlen(pInStr); + if (!instr_len) return; + + pOutString.reserve(instr_len * 3 / 2); + // check and correct floats in format ".x". Must be "x.y". + if (pInStr[0] == '.') pOutString.push_back('0'); + + pOutString.push_back(pInStr[0]); + for (size_t ci = 1; ci < instr_len; ci++) { + if ((pInStr[ci] == '.') && ((pInStr[ci - 1] == ' ') || (pInStr[ci - 1] == '-') || (pInStr[ci - 1] == '+') || (pInStr[ci - 1] == '\t'))) { + pOutString.push_back('0'); + pOutString.push_back('.'); + } else { + pOutString.push_back(pInStr[ci]); + } + } +} + +static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) { + return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/')); +} + +void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector &pOutputData) const { + // With help from + // René Nyffenegger http://www.adp-gmbh.ch/cpp/common/base64.html + const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + uint8_t tidx = 0; + uint8_t arr4[4], arr3[3]; + + // check input data + if (pInputBase64.size() % 4) throw DeadlyImportError("Base64-encoded data must have size multiply of four."); + // prepare output place + pOutputData.clear(); + pOutputData.reserve(pInputBase64.size() / 4 * 3); + + for (size_t in_len = pInputBase64.size(), in_idx = 0; (in_len > 0) && (pInputBase64[in_idx] != '='); in_len--) { + if (ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx])) { + arr4[tidx++] = pInputBase64[in_idx++]; + if (tidx == 4) { + for (tidx = 0; tidx < 4; tidx++) + arr4[tidx] = (uint8_t)base64_chars.find(arr4[tidx]); + + arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4); + arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2); + arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3]; + for (tidx = 0; tidx < 3; tidx++) + pOutputData.push_back(arr3[tidx]); + + tidx = 0; + } // if(tidx == 4) + } // if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx])) + else { + in_idx++; + } // if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx])) else + } + + if (tidx) { + for (uint8_t i = tidx; i < 4; i++) + arr4[i] = 0; + for (uint8_t i = 0; i < 4; i++) + arr4[i] = (uint8_t)(base64_chars.find(arr4[i])); + + arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4); + arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2); + arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3]; + for (uint8_t i = 0; i < (tidx - 1); i++) + pOutputData.push_back(arr3[i]); + } +} + +void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) { + std::unique_ptr file(pIOHandler->Open(pFile, "rb")); + + // Check whether we can read from the file + if (file.get() == nullptr) { + throw DeadlyImportError("Failed to open AMF file ", pFile, "."); + } + + mXmlParser = new XmlParser(); + if (!mXmlParser->parse(file.get())) { + delete mXmlParser; + mXmlParser = nullptr; + throw DeadlyImportError("Failed to create XML reader for file ", pFile, "."); + } + + // Start reading, search for root tag + if (!mXmlParser->hasNode("amf")) { + throw DeadlyImportError("Root node \"amf\" not found."); + } + ParseNode_Root(); +} // namespace Assimp + +void AMFImporter::ParseHelper_Node_Enter(AMFNodeElementBase *node) { + mNodeElement_Cur->Child.push_back(node); // add new element to current element child list. + mNodeElement_Cur = node; +} + +void AMFImporter::ParseHelper_Node_Exit() { + if (mNodeElement_Cur != nullptr) mNodeElement_Cur = mNodeElement_Cur->Parent; +} + +// +// +// Root XML element. +// Multi elements - No. +void AMFImporter::ParseNode_Root() { + AMFNodeElementBase *ne = nullptr; + XmlNode *root = mXmlParser->findNode("amf"); + if (nullptr == root) { + throw DeadlyImportError("Root node \"amf\" not found."); + } + XmlNode node = *root; + mUnit = ai_tolower(std::string(node.attribute("unit").as_string())); + + mVersion = node.attribute("version").as_string(); + + // Read attributes for node . + // Check attributes + if (!mUnit.empty()) { + if ((mUnit != "inch") && (mUnit != "millimeters") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) { + Throw_IncorrectAttrValue("unit", mUnit); + } + } + + // create root node element. + ne = new AMFRoot(nullptr); + + mNodeElement_Cur = ne; // set first "current" element + // and assign attribute's values + ((AMFRoot *)ne)->Unit = mUnit; + ((AMFRoot *)ne)->Version = mVersion; + + // Check for child nodes + for (XmlNode ¤tNode : node.children() ) { + const std::string currentName = currentNode.name(); + if (currentName == "object") { + ParseNode_Object(currentNode); + } else if (currentName == "material") { + ParseNode_Material(currentNode); + } else if (currentName == "texture") { + ParseNode_Texture(currentNode); + } else if (currentName == "constellation") { + ParseNode_Constellation(currentNode); + } else if (currentName == "metadata") { + ParseNode_Metadata(currentNode); + } + mNodeElement_Cur = ne; + } + mNodeElement_Cur = ne; // force restore "current" element + mNodeElement_List.push_back(ne); // add to node element list because its a new object in graph. +} + +// +// +// A collection of objects or constellations with specific relative locations. +// Multi elements - Yes. +// Parent element - . +void AMFImporter::ParseNode_Constellation(XmlNode &node) { + std::string id; + id = node.attribute("id").as_string(); + + // create and if needed - define new grouping object. + AMFNodeElementBase *ne = new AMFConstellation(mNodeElement_Cur); + + AMFConstellation &als = *((AMFConstellation *)ne); // alias for convenience + + if (!id.empty()) { + als.ID = id; + } + + // Check for child nodes + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + std::string name = currentNode.name(); + if (name == "instance") { + ParseNode_Instance(currentNode); + } else if (name == "metadata") { + ParseNode_Metadata(currentNode); + } + } + ParseHelper_Node_Exit(); + } else { + mNodeElement_Cur->Child.push_back(ne); + } + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. +} + +// +// +// A collection of objects or constellations with specific relative locations. +// Multi elements - Yes. +// Parent element - . +void AMFImporter::ParseNode_Instance(XmlNode &node) { + AMFNodeElementBase *ne(nullptr); + + // Read attributes for node . + std::string objectid = node.attribute("objectid").as_string(); + + // used object id must be defined, check that. + if (objectid.empty()) { + throw DeadlyImportError("\"objectid\" in must be defined."); + } + // create and define new grouping object. + ne = new AMFInstance(mNodeElement_Cur); + AMFInstance &als = *((AMFInstance *)ne); + als.ObjectID = objectid; + + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + for (auto ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == "deltax") { + XmlParser::getValueAsFloat(currentNode, als.Delta.x); + } else if (currentName == "deltay") { + XmlParser::getValueAsFloat(currentNode, als.Delta.y); + } else if (currentName == "deltaz") { + XmlParser::getValueAsFloat(currentNode, als.Delta.z); + } else if (currentName == "rx") { + XmlParser::getValueAsFloat(currentNode, als.Delta.x); + } else if (currentName == "ry") { + XmlParser::getValueAsFloat(currentNode, als.Delta.y); + } else if (currentName == "rz") { + XmlParser::getValueAsFloat(currentNode, als.Delta.z); + } + } + ParseHelper_Node_Exit(); + } else { + mNodeElement_Cur->Child.push_back(ne); + } + + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. +} + +// +// +// An object definition. +// Multi elements - Yes. +// Parent element - . +void AMFImporter::ParseNode_Object(XmlNode &node) { + AMFNodeElementBase *ne = nullptr; + + // Read attributes for node . + std::string id = node.attribute("id").as_string(); + + // create and if needed - define new geometry object. + ne = new AMFObject(mNodeElement_Cur); + + AMFObject &als = *((AMFObject *)ne); // alias for convenience + + if (!id.empty()) { + als.ID = id; + } + + // Check for child nodes + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + for (auto ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == "color") { + ParseNode_Color(currentNode); + } else if (currentName == "mesh") { + ParseNode_Mesh(currentNode); + } else if (currentName == "metadata") { + ParseNode_Metadata(currentNode); + } + } + ParseHelper_Node_Exit(); + } else { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + } + + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. +} + +// +// +// Specify additional information about an entity. +// Multi elements - Yes. +// Parent element - , , , , . +// +// Reserved types are: +// "Name" - The alphanumeric label of the entity, to be used by the interpreter if interacting with the user. +// "Description" - A description of the content of the entity +// "URL" - A link to an external resource relating to the entity +// "Author" - Specifies the name(s) of the author(s) of the entity +// "Company" - Specifying the company generating the entity +// "CAD" - specifies the name of the originating CAD software and version +// "Revision" - specifies the revision of the entity +// "Tolerance" - specifies the desired manufacturing tolerance of the entity in entity's unit system +// "Volume" - specifies the total volume of the entity, in the entity's unit system, to be used for verification (object and volume only) +void AMFImporter::ParseNode_Metadata(XmlNode &node) { + AMFNodeElementBase *ne = nullptr; + + std::string type = node.attribute("type").as_string(), value; + XmlParser::getValueAsString(node, value); + + // read attribute + ne = new AMFMetadata(mNodeElement_Cur); + ((AMFMetadata *)ne)->Type = type; + ((AMFMetadata *)ne)->Value = value; + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. +} + +bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*pCheckSig*/) const { + static const char *tokens[] = { " +#include +#include +#include + +// Header files, stdlib. +#include + +namespace Assimp { + +/// \class AMFImporter +/// Class that holding scene graph which include: geometry, metadata, materials etc. +/// +/// Implementing features. +/// +/// Limitations. +/// +/// 1. When for texture mapping used set of source textures (r, g, b, a) not only one then attribute "tiled" for all set will be true if it true in any of +/// source textures. +/// Example. Triangle use for texture mapping three textures. Two of them has "tiled" set to false and one - set to true. In scene all three textures +/// will be tiled. +/// +/// Unsupported features: +/// 1. Node , formulas in and . For implementing this feature can be used expression parser "muParser" like in project +/// "amf_tools". +/// 2. Attribute "profile" in node . +/// 3. Curved geometry: , and children nodes of them. +/// 4. Attributes: "unit" and "version" in read but do nothing. +/// 5. stored only for root node . +/// 6. Color averaging of vertices for which 's set different colors. +/// +/// Supported nodes: +/// General: +/// ; ; and children , , , , , ; ; +/// +/// Geometry: +/// ; ; ; ; and children , , ; ; and children , , ; +/// +/// Material: +/// and children , , , ; ; ; +/// two variants of texture coordinates: +/// new - and children , , , , , +/// old - and children , , , , , +/// +class AMFImporter : public BaseImporter { +private: + struct SPP_Material; // forward declaration + + /// Data type for post-processing step. More suitable container for part of material's composition. + struct SPP_Composite { + SPP_Material *Material; ///< Pointer to material - part of composition. + std::string Formula; ///< Formula for calculating ratio of \ref Material. + }; + + /// \struct SPP_Material + /// Data type for post-processing step. More suitable container for material. + struct SPP_Material { + std::string ID; ///< Material ID. + std::list Metadata; ///< Metadata of material. + AMFColor *Color; ///< Color of material. + std::list Composition; ///< List of child materials if current material is composition of few another. + + /// Return color calculated for specified coordinate. + /// \param [in] pX - "x" coordinate. + /// \param [in] pY - "y" coordinate. + /// \param [in] pZ - "z" coordinate. + /// \return calculated color. + aiColor4D GetColor(const float pX, const float pY, const float pZ) const; + }; + + /// Data type for post-processing step. More suitable container for texture. + struct SPP_Texture { + std::string ID; + size_t Width, Height, Depth; + bool Tiled; + char FormatHint[9]; // 8 for string + 1 for terminator. + uint8_t *Data; + }; + + /// Data type for post-processing step. Contain face data. + struct SComplexFace { + aiFace Face; ///< Face vertices. + const AMFColor *Color; ///< Face color. Equal to nullptr if color is not set for the face. + const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face. + }; + + using AMFMetaDataArray = std::vector; + using MeshArray = std::vector; + using NodeArray = std::vector; + + /// Clear all temporary data. + void Clear(); + + /// Get data stored in and place it to arrays. + /// \param [in] pNodeElement - reference to node element which kept data. + /// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in . + /// \param [in] pVertexColorArray - reference to vertices colors for all &pVertexCoordinateArray, + std::vector &pVertexColorArray) const; + + /// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new + /// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it + /// to converted textures list. + /// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified. + /// \param [in] pID_R - ID of source "red" texture. + /// \param [in] pID_G - ID of source "green" texture. + /// \param [in] pID_B - ID of source "blue" texture. + /// \param [in] pID_A - ID of source "alpha" texture. + /// \return index of the texture in array of the converted textures. + size_t PostprocessHelper_GetTextureID_Or_Create(const std::string &pID_R, const std::string &pID_G, const std::string &pID_B, const std::string &pID_A); + + /// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc). + /// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after + /// processing. + /// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing. + void PostprocessHelper_SplitFacesByTextureID(std::list &pInputList, std::list> &pOutputList_Separated); + + /// Check if child elements of node element is metadata and add it to scene node. + /// \param [in] pMetadataList - reference to list with collected metadata. + /// \param [out] pSceneNode - scene node in which metadata will be added. + void Postprocess_AddMetadata(const AMFMetaDataArray &pMetadataList, aiNode &pSceneNode) const; + + /// To create aiMesh and aiNode for it from . + /// \param [in] pNodeElement - reference to node element which kept data. + /// \param [out] meshList - reference to a list with all aiMesh of the scene. + /// \param [out] pSceneNode - pointer to place where new aiNode will be created. + void Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, MeshArray &meshList, aiNode **pSceneNode); + + /// Create mesh for every in . + /// \param [in] pNodeElement - reference to node element which kept data. + /// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all 's. + /// \param [in] pVertexColorArray - reference to vertices colors for all 's. If color for vertex is not set then corresponding member of array + /// contain nullptr. + /// \param [in] pObjectColor - pointer to colors for . If color is not set then argument contain nullptr. + /// \param [in] pMaterialList - reference to a list with defined materials. + /// \param [out] pMeshList - reference to a list with all aiMesh of the scene. + /// \param [out] pSceneNode - reference to aiNode which will own new aiMesh's. + void Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const std::vector &pVertexCoordinateArray, + const std::vector &pVertexColorArray, const AMFColor *pObjectColor, + MeshArray &pMeshList, aiNode &pSceneNode); + + /// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material. + /// \param [in] pMaterial - source CAMFImporter_NodeElement_Material. + void Postprocess_BuildMaterial(const AMFMaterial &pMaterial); + + /// Create and add to aiNode's list new part of scene graph defined by . + /// \param [in] pConstellation - reference to node. + /// \param [out] nodeArray - reference to aiNode's list. + void Postprocess_BuildConstellation(AMFConstellation &pConstellation, NodeArray &nodeArray) const; + + /// Build Assimp scene graph in aiScene from collected data. + /// \param [out] pScene - pointer to aiScene where tree will be built. + void Postprocess_BuildScene(aiScene *pScene); + + /// Decode Base64-encoded data. + /// \param [in] pInputBase64 - reference to input Base64-encoded string. + /// \param [out] pOutputData - reference to output array for decoded data. + void ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector &pOutputData) const; + + /// Parse node of the file. + void ParseNode_Root(); + + /// Parse node of the file. + void ParseNode_Constellation(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Instance(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Material(XmlNode &node); + + /// Parse node. + void ParseNode_Metadata(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Object(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Texture(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Coordinates(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Edge(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Mesh(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Triangle(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Vertex(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Vertices(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Volume(XmlNode &node); + + /// Parse node of the file. + void ParseNode_Color(XmlNode &node); + + /// Parse of node of the file. + /// \param [in] pUseOldName - if true then use old name of node(and children) - , instead of new name - . + void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false); + +public: + /// Default constructor. + AMFImporter() AI_NO_EXCEPT; + + /// Default destructor. + ~AMFImporter() override; + + /// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph. + /// Also exception can be thrown if trouble will found. + /// \param [in] pFile - name of file to be parsed. + /// \param [in] pIOHandler - pointer to IO helper object. + void ParseFile(const std::string &pFile, IOSystem *pIOHandler); + void ParseHelper_Node_Enter(AMFNodeElementBase *child); + void ParseHelper_Node_Exit(); + bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const override; + void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override; + const aiImporterDesc *GetInfo() const override; + bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const; + bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const; + bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const; + void Throw_CloseNotFound(const std::string &nodeName); + void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName); + void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName); + void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription); + void Throw_ID_NotFound(const std::string &pID) const; + void XML_CheckNode_MustHaveChildren(pugi::xml_node &node); + bool XML_SearchNode(const std::string &nodeName); + void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString); + AMFImporter(const AMFImporter &pScene) = delete; + AMFImporter &operator=(const AMFImporter &pScene) = delete; + +private: + static const aiImporterDesc Description; + + AMFNodeElementBase *mNodeElement_Cur; ///< Current element. + std::list mNodeElement_List; ///< All elements of scene graph. + XmlParser *mXmlParser; + std::string mUnit; + std::string mVersion; + std::list mMaterial_Converted; ///< List of converted materials for postprocessing step. + std::list mTexture_Converted; ///< List of converted textures for postprocessing step. +}; + +} // namespace Assimp + +#endif // INCLUDED_AI_AMF_IMPORTER_H diff --git a/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Geometry.cpp b/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Geometry.cpp new file mode 100644 index 000000000..341999f56 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Geometry.cpp @@ -0,0 +1,284 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER + +#include "AMFImporter.hpp" +#include + +namespace Assimp { + +// +// +// A 3D mesh hull. +// Multi elements - Yes. +// Parent element - . +void AMFImporter::ParseNode_Mesh(XmlNode &node) { + AMFNodeElementBase *ne = nullptr; + + // Check for child nodes + if (0 != ASSIMP_stricmp(node.name(), "mesh")) { + return; + } + // create new mesh object. + ne = new AMFMesh(mNodeElement_Cur); + bool found_verts = false, found_volumes = false; + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + pugi::xml_node vertNode = node.child("vertices"); + if (!vertNode.empty()) { + ParseNode_Vertices(vertNode); + found_verts = true; + } + + pugi::xml_node volumeNode = node.child("volume"); + if (!volumeNode.empty()) { + ParseNode_Volume(volumeNode); + found_volumes = true; + } + ParseHelper_Node_Exit(); + } + + if (!found_verts && !found_volumes) { + mNodeElement_Cur->Child.push_back(ne); + } // if(!mReader->isEmptyElement()) else + + // and to node element list because its a new object in graph. + mNodeElement_List.push_back(ne); +} + +// +// +// The list of vertices to be used in defining triangles. +// Multi elements - No. +// Parent element - . +void AMFImporter::ParseNode_Vertices(XmlNode &node) { + AMFNodeElementBase *ne = nullptr; + + // create new mesh object. + ne = new AMFVertices(mNodeElement_Cur); + // Check for child nodes + if (node.empty()) { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + return; + } + ParseHelper_Node_Enter(ne); + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == "vertex") { + ParseNode_Vertex(currentNode); + } + } + ParseHelper_Node_Exit(); + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. +} + +// +// +// A vertex to be referenced in triangles. +// Multi elements - Yes. +// Parent element - . +void AMFImporter::ParseNode_Vertex(XmlNode &node) { + AMFNodeElementBase *ne = nullptr; + + // create new mesh object. + ne = new AMFVertex(mNodeElement_Cur); + + // Check for child nodes + pugi::xml_node colorNode = node.child("color"); + bool col_read = false; + bool coord_read = false; + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + if (!colorNode.empty()) { + ParseNode_Color(colorNode); + col_read = true; + } + pugi::xml_node coordNode = node.child("coordinates"); + if (!coordNode.empty()) { + ParseNode_Coordinates(coordNode); + coord_read = true; + } + ParseHelper_Node_Exit(); + } + + if (!coord_read && !col_read) { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + } + + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. +} + +// +// +// Specifies the 3D location of this vertex. +// Multi elements - No. +// Parent element - . +// +// Children elements: +// , , +// Multi elements - No. +// X, Y, or Z coordinate, respectively, of a vertex position in space. +void AMFImporter::ParseNode_Coordinates(XmlNode &node) { + AMFNodeElementBase *ne = nullptr; + if (!node.empty()) { + ne = new AMFCoordinates(mNodeElement_Cur); + ParseHelper_Node_Enter(ne); + for (XmlNode ¤tNode : node.children()) { + // create new color object. + AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience + const std::string ¤tName = ai_tolower(currentNode.name()); + if (currentName == "x") { + XmlParser::getValueAsFloat(currentNode, als.Coordinate.x); + } else if (currentName == "y") { + XmlParser::getValueAsFloat(currentNode, als.Coordinate.y); + } else if (currentName == "z") { + XmlParser::getValueAsFloat(currentNode, als.Coordinate.z); + } + } + ParseHelper_Node_Exit(); + + } else { + mNodeElement_Cur->Child.push_back(new AMFCoordinates(mNodeElement_Cur)); + } + + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. +} + +// +// +// Defines a volume from the established vertex list. +// Multi elements - Yes. +// Parent element - . +void AMFImporter::ParseNode_Volume(XmlNode &node) { + std::string materialid; + std::string type; + AMFNodeElementBase *ne = new AMFVolume(mNodeElement_Cur); + + // Read attributes for node . + // and assign read data + + ((AMFVolume *)ne)->MaterialID = node.attribute("materialid").as_string(); + + ((AMFVolume *)ne)->Type = type; + // Check for child nodes + bool col_read = false; + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + for (auto ¤tNode : node.children()) { + const std::string currentName = currentNode.name(); + if (currentName == "color") { + if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for ."); + ParseNode_Color(currentNode); + col_read = true; + } else if (currentName == "triangle") { + ParseNode_Triangle(currentNode); + } else if (currentName == "metadata") { + ParseNode_Metadata(currentNode); + } else if (currentName == "volume") { + ParseNode_Metadata(currentNode); + } + } + ParseHelper_Node_Exit(); + } else { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + } + + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. +} + +// +// +// Defines a 3D triangle from three vertices, according to the right-hand rule (counter-clockwise when looking from the outside). +// Multi elements - Yes. +// Parent element - . +// +// Children elements: +// , , +// Multi elements - No. +// Index of the desired vertices in a triangle or edge. +void AMFImporter::ParseNode_Triangle(XmlNode &node) { + AMFNodeElementBase *ne = new AMFTriangle(mNodeElement_Cur); + + // create new triangle object. + + AMFTriangle &als = *((AMFTriangle *)ne); // alias for convenience + + bool col_read = false; + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + std::string v; + for (auto ¤tNode : node.children()) { + const std::string currentName = currentNode.name(); + if (currentName == "color") { + if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for ."); + ParseNode_Color(currentNode); + col_read = true; + } else if (currentName == "texmap") { + ParseNode_TexMap(currentNode); + } else if (currentName == "map") { + ParseNode_TexMap(currentNode, true); + } else if (currentName == "v1") { + XmlParser::getValueAsString(currentNode, v); + als.V[0] = std::atoi(v.c_str()); + } else if (currentName == "v2") { + XmlParser::getValueAsString(currentNode, v); + als.V[1] = std::atoi(v.c_str()); + } else if (currentName == "v3") { + XmlParser::getValueAsString(currentNode, v); + als.V[2] = std::atoi(v.c_str()); + } + } + ParseHelper_Node_Exit(); + } else { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + } + + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. +} + +} // namespace Assimp + +#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER diff --git a/Engine/lib/assimp/code/AMF/AMFImporter_Material.cpp b/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Material.cpp similarity index 50% rename from Engine/lib/assimp/code/AMF/AMFImporter_Material.cpp rename to Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Material.cpp index 2f36df061..676e74856 100644 --- a/Engine/lib/assimp/code/AMF/AMFImporter_Material.cpp +++ b/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Material.cpp @@ -1,11 +1,9 @@ -/* +/* --------------------------------------------------------------------------- Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -49,10 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_AMF_IMPORTER #include "AMFImporter.hpp" -#include "AMFImporter_Macro.hpp" -namespace Assimp -{ +namespace Assimp { // , and . @@ -68,51 +64,46 @@ namespace Assimp // Multi elements - No. // Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The // values can be specified as constants, or as a formula depending on the coordinates. -void AMFImporter::ParseNode_Color() { - std::string profile; - CAMFImporter_NodeElement* ne; +void AMFImporter::ParseNode_Color(XmlNode &node) { + if (node.empty()) { + return; + } - // Read attributes for node . - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECK_RET("profile", profile, mReader->getAttributeValue); - MACRO_ATTRREAD_LOOPEND; + const std::string &profile = node.attribute("profile").as_string(); + bool read_flag[4] = { false, false, false, false }; + AMFNodeElementBase *ne = new AMFColor(mNodeElement_Cur); + AMFColor &als = *((AMFColor *)ne); // alias for convenience + ParseHelper_Node_Enter(ne); + for (pugi::xml_node &child : node.children()) { + // create new color object. + als.Profile = profile; - // create new color object. - ne = new CAMFImporter_NodeElement_Color(mNodeElement_Cur); - - CAMFImporter_NodeElement_Color& als = *((CAMFImporter_NodeElement_Color*)ne);// alias for convenience - - als.Profile = profile; - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool read_flag[4] = { false, false, false, false }; - - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("color"); - MACRO_NODECHECK_READCOMP_F("r", read_flag[0], als.Color.r); - MACRO_NODECHECK_READCOMP_F("g", read_flag[1], als.Color.g); - MACRO_NODECHECK_READCOMP_F("b", read_flag[2], als.Color.b); - MACRO_NODECHECK_READCOMP_F("a", read_flag[3], als.Color.a); - MACRO_NODECHECK_LOOPEND("color"); - ParseHelper_Node_Exit(); - // check that all components was defined - if (!(read_flag[0] && read_flag[1] && read_flag[2])) { - throw DeadlyImportError("Not all color components are defined."); + const std::string &name = child.name(); + if ( name == "r") { + read_flag[0] = true; + XmlParser::getValueAsFloat(child, als.Color.r); + } else if (name == "g") { + read_flag[1] = true; + XmlParser::getValueAsFloat(child, als.Color.g); + } else if (name == "b") { + read_flag[2] = true; + XmlParser::getValueAsFloat(child, als.Color.b); + } else if (name == "a") { + read_flag[3] = true; + XmlParser::getValueAsFloat(child, als.Color.a); } - // check if is absent. Then manually add "a == 1". if (!read_flag[3]) { als.Color.a = 1; } + } + als.Composed = false; + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. + ParseHelper_Node_Exit(); + // check that all components was defined + if (!(read_flag[0] && read_flag[1] && read_flag[2])) { + throw DeadlyImportError("Not all color components are defined."); } - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - } - - als.Composed = false; - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. } // . -void AMFImporter::ParseNode_Material() { - std::string id; - CAMFImporter_NodeElement* ne; - - // Read attributes for node . - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue); - MACRO_ATTRREAD_LOOPEND; - - // create new object. - ne = new CAMFImporter_NodeElement_Material(mNodeElement_Cur); - - // and assign read data - ((CAMFImporter_NodeElement_Material*)ne)->ID = id; +void AMFImporter::ParseNode_Material(XmlNode &node) { + // create new object and assign read data + std::string id = node.attribute("id").as_string(); + AMFNodeElementBase *ne = new AMFMaterial(mNodeElement_Cur); + ((AMFMaterial*)ne)->ID = id; // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool col_read = false; - - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("material"); - if(XML_CheckNode_NameEqual("color")) - { - // Check if data already defined. - if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); - // read data and set flag about it - ParseNode_Color(); - col_read = true; - - continue; + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + for (pugi::xml_node &child : node.children()) { + const std::string name = child.name(); + if (name == "color") { + ParseNode_Color(child); + } else if (name == "metadata") { + ParseNode_Metadata(child); } - - if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } - MACRO_NODECHECK_LOOPEND("material"); - ParseHelper_Node_Exit(); - } - else - { + } + ParseHelper_Node_Exit(); + } else { mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element } @@ -183,51 +154,39 @@ void AMFImporter::ParseNode_Material() { // then layer by layer. // Multi elements - Yes. // Parent element - . -void AMFImporter::ParseNode_Texture() -{ - std::string id; - uint32_t width = 0; - uint32_t height = 0; - uint32_t depth = 1; - std::string type; - bool tiled = false; - std::string enc64_data; +void AMFImporter::ParseNode_Texture(XmlNode &node) { + const std::string id = node.attribute("id").as_string(); + const uint32_t width = node.attribute("width").as_uint(); + const uint32_t height = node.attribute("height").as_uint(); + uint32_t depth = node.attribute("depth").as_uint(); + const std::string type = node.attribute("type").as_string(); + bool tiled = node.attribute("tiled").as_bool(); - // Read attributes for node . - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_RET("width", width, XML_ReadNode_GetAttrVal_AsU32); - MACRO_ATTRREAD_CHECK_RET("height", height, XML_ReadNode_GetAttrVal_AsU32); - MACRO_ATTRREAD_CHECK_RET("depth", depth, XML_ReadNode_GetAttrVal_AsU32); - MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_RET("tiled", tiled, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // create new texture object. - CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur); - - CAMFImporter_NodeElement_Texture& als = *((CAMFImporter_NodeElement_Texture*)ne);// alias for convenience - - // Check for child nodes - if (!mReader->isEmptyElement()) { - XML_ReadNode_GetVal_AsString(enc64_data); + if (node.empty()) { + return; } + // create new texture object. + AMFNodeElementBase *ne = new AMFTexture(mNodeElement_Cur); + + AMFTexture& als = *((AMFTexture*)ne);// alias for convenience + + std::string enc64_data; + XmlParser::getValueAsString(node, enc64_data); + // Check for child nodes + // check that all components was defined if (id.empty()) { - throw DeadlyImportError("ID for texture must be defined."); + throw DeadlyImportError("ID for texture must be defined."); } if (width < 1) { - Throw_IncorrectAttrValue("width"); + throw DeadlyImportError("Invalid width for texture."); } if (height < 1) { - Throw_IncorrectAttrValue("height"); - } - if (depth < 1) { - Throw_IncorrectAttrValue("depth"); - } + throw DeadlyImportError("Invalid height for texture."); + } if (type != "grayscale") { - Throw_IncorrectAttrValue("type"); + throw DeadlyImportError("Invalid type for texture."); } if (enc64_data.empty()) { throw DeadlyImportError("Texture data not defined."); @@ -239,7 +198,9 @@ void AMFImporter::ParseNode_Texture() als.Depth = depth; als.Tiled = tiled; ParseHelper_Decode_Base64(enc64_data, als.Data); - + if (depth == 0) { + depth = (uint32_t)(als.Data.size() / (width * height)); + } // check data size if ((width * height * depth) != als.Data.size()) { throw DeadlyImportError("Texture has incorrect data size."); @@ -263,57 +224,94 @@ void AMFImporter::ParseNode_Texture() // , , , , , . Old name: , , , , , . // Multi elements - No. // Texture coordinates for every vertex of triangle. -void AMFImporter::ParseNode_TexMap(const bool pUseOldName) { - std::string rtexid, gtexid, btexid, atexid; - +void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) { // Read attributes for node . - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECK_RET("rtexid", rtexid, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_RET("gtexid", gtexid, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_RET("btexid", btexid, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_RET("atexid", atexid, mReader->getAttributeValue); - MACRO_ATTRREAD_LOOPEND; + AMFNodeElementBase *ne = new AMFTexMap(mNodeElement_Cur); + AMFTexMap &als = *((AMFTexMap *)ne); // + std::string rtexid, gtexid, btexid, atexid; + if (!node.empty()) { + for (pugi::xml_attribute &attr : node.attributes()) { + const std::string ¤tAttr = attr.name(); + if (currentAttr == "rtexid") { + rtexid = attr.as_string(); + } else if (currentAttr == "gtexid") { + gtexid = attr.as_string(); + } else if (currentAttr == "btexid") { + btexid = attr.as_string(); + } else if (currentAttr == "atexid") { + atexid = attr.as_string(); + } + } + } - // create new texture coordinates object. - CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur); - - CAMFImporter_NodeElement_TexMap& als = *((CAMFImporter_NodeElement_TexMap*)ne);// alias for convenience + // create new texture coordinates object, alias for convenience // check data - if(rtexid.empty() && gtexid.empty() && btexid.empty()) throw DeadlyImportError("ParseNode_TexMap. At least one texture ID must be defined."); + if (rtexid.empty() && gtexid.empty() && btexid.empty()) { + throw DeadlyImportError("ParseNode_TexMap. At least one texture ID must be defined."); + } + // Check for children nodes - XML_CheckNode_MustHaveChildren(); + if (node.children().begin() == node.children().end()) { + throw DeadlyImportError("Invalid children definition."); + } // read children nodes bool read_flag[6] = { false, false, false, false, false, false }; - ParseHelper_Node_Enter(ne); - if(!pUseOldName) - { - MACRO_NODECHECK_LOOPBEGIN("texmap"); - MACRO_NODECHECK_READCOMP_F("utex1", read_flag[0], als.TextureCoordinate[0].x); - MACRO_NODECHECK_READCOMP_F("utex2", read_flag[1], als.TextureCoordinate[1].x); - MACRO_NODECHECK_READCOMP_F("utex3", read_flag[2], als.TextureCoordinate[2].x); - MACRO_NODECHECK_READCOMP_F("vtex1", read_flag[3], als.TextureCoordinate[0].y); - MACRO_NODECHECK_READCOMP_F("vtex2", read_flag[4], als.TextureCoordinate[1].y); - MACRO_NODECHECK_READCOMP_F("vtex3", read_flag[5], als.TextureCoordinate[2].y); - MACRO_NODECHECK_LOOPEND("texmap"); - } - else - { - MACRO_NODECHECK_LOOPBEGIN("map"); - MACRO_NODECHECK_READCOMP_F("u1", read_flag[0], als.TextureCoordinate[0].x); - MACRO_NODECHECK_READCOMP_F("u2", read_flag[1], als.TextureCoordinate[1].x); - MACRO_NODECHECK_READCOMP_F("u3", read_flag[2], als.TextureCoordinate[2].x); - MACRO_NODECHECK_READCOMP_F("v1", read_flag[3], als.TextureCoordinate[0].y); - MACRO_NODECHECK_READCOMP_F("v2", read_flag[4], als.TextureCoordinate[1].y); - MACRO_NODECHECK_READCOMP_F("v3", read_flag[5], als.TextureCoordinate[2].y); - MACRO_NODECHECK_LOOPEND("map"); - }// if(!pUseOldName) else + if (!pUseOldName) { + ParseHelper_Node_Enter(ne); + for ( XmlNode ¤tNode : node.children()) { + const std::string &name = currentNode.name(); + if (name == "utex1") { + read_flag[0] = true; + XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].x); + } else if (name == "utex2") { + read_flag[1] = true; + XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].x); + } else if (name == "utex3") { + read_flag[2] = true; + XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].x); + } else if (name == "vtex1") { + read_flag[3] = true; + XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].y); + } else if (name == "vtex2") { + read_flag[4] = true; + XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].y); + } else if (name == "vtex3") { + read_flag[5] = true; + XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].y); + } + } + ParseHelper_Node_Exit(); - ParseHelper_Node_Exit(); + } else { + for (pugi::xml_attribute &attr : node.attributes()) { + const std::string name = attr.name(); + if (name == "u") { + read_flag[0] = true; + als.TextureCoordinate[0].x = attr.as_float(); + } else if (name == "u2") { + read_flag[1] = true; + als.TextureCoordinate[1].x = attr.as_float(); + } else if (name == "u3") { + read_flag[2] = true; + als.TextureCoordinate[2].x = attr.as_float(); + } else if (name == "v1") { + read_flag[3] = true; + als.TextureCoordinate[0].y = attr.as_float(); + } else if (name == "v2") { + read_flag[4] = true; + als.TextureCoordinate[1].y = attr.as_float(); + } else if (name == "v3") { + read_flag[5] = true; + als.TextureCoordinate[0].y = attr.as_float(); + } + } + } // check that all components was defined - if(!(read_flag[0] && read_flag[1] && read_flag[2] && read_flag[3] && read_flag[4] && read_flag[5])) + if (!(read_flag[0] && read_flag[1] && read_flag[2] && read_flag[3] && read_flag[4] && read_flag[5])) { throw DeadlyImportError("Not all texture coordinates are defined."); + } // copy attributes data als.TextureID_R = rtexid; @@ -321,7 +319,7 @@ void AMFImporter::ParseNode_TexMap(const bool pUseOldName) { als.TextureID_B = btexid; als.TextureID_A = atexid; - mNodeElement_List.push_back(ne);// add to node element list because its a new object in graph. + mNodeElement_List.push_back(ne); } }// namespace Assimp diff --git a/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Node.hpp b/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Node.hpp new file mode 100644 index 000000000..c827533a6 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Node.hpp @@ -0,0 +1,305 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/// \file AMFImporter_Node.hpp +/// \brief Elements of scene graph. +/// \date 2016 +/// \author smal.root@gmail.com + +#pragma once +#ifndef INCLUDED_AI_AMF_IMPORTER_NODE_H +#define INCLUDED_AI_AMF_IMPORTER_NODE_H + +// Header files, Assimp. +#include +#include + +#include +#include +#include + +/// \class CAMFImporter_NodeElement +/// Base class for elements of nodes. +class AMFNodeElementBase { +public: + /// Define what data type contain node element. + enum EType { + ENET_Color, ///< Color element: . + ENET_Constellation, ///< Grouping element: . + ENET_Coordinates, ///< Coordinates element: . + ENET_Edge, ///< Edge element: . + ENET_Instance, ///< Grouping element: . + ENET_Material, ///< Material element: . + ENET_Metadata, ///< Metadata element: . + ENET_Mesh, ///< Metadata element: . + ENET_Object, ///< Element which hold object: . + ENET_Root, ///< Root element: . + ENET_Triangle, ///< Triangle element: . + ENET_TexMap, ///< Texture coordinates element: or . + ENET_Texture, ///< Texture element: . + ENET_Vertex, ///< Vertex element: . + ENET_Vertices, ///< Vertex element: . + ENET_Volume, ///< Volume element: . + + ENET_Invalid ///< Element has invalid type and possible contain invalid data. + }; + + const EType Type; ///< Type of element. + std::string ID; ///< ID of element. + AMFNodeElementBase *Parent; ///< Parent element. If nullptr then this node is root. + std::list Child; ///< Child elements. + +public: /// Destructor, virtual.. + virtual ~AMFNodeElementBase() { + // empty + } + + /// Disabled copy constructor and co. + AMFNodeElementBase(const AMFNodeElementBase &pNodeElement) = delete; + AMFNodeElementBase(AMFNodeElementBase &&) = delete; + AMFNodeElementBase &operator=(const AMFNodeElementBase &pNodeElement) = delete; + AMFNodeElementBase() = delete; + +protected: + /// In constructor inheritor must set element type. + /// \param [in] pType - element type. + /// \param [in] pParent - parent element. + AMFNodeElementBase(const EType pType, AMFNodeElementBase *pParent) : + Type(pType), ID(), Parent(pParent), Child() { + // empty + } +}; // class IAMFImporter_NodeElement + +/// \struct CAMFImporter_NodeElement_Constellation +/// A collection of objects or constellations with specific relative locations. +struct AMFConstellation : public AMFNodeElementBase { + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFConstellation(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Constellation, pParent) {} + +}; // struct CAMFImporter_NodeElement_Constellation + +/// \struct CAMFImporter_NodeElement_Instance +/// Part of constellation. +struct AMFInstance : public AMFNodeElementBase { + + std::string ObjectID; ///< ID of object for instantiation. + /// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to + /// create an instance of the object in the current constellation. + aiVector3D Delta; + + /// \var Rotation - The rotation, in degrees, to rotate the referenced object about its x, y, and z axes, respectively, to create an + /// instance of the object in the current constellation. Rotations shall be executed in order of x first, then y, then z. + aiVector3D Rotation; + + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFInstance(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Instance, pParent) {} +}; + +/// \struct CAMFImporter_NodeElement_Metadata +/// Structure that define metadata node. +struct AMFMetadata : public AMFNodeElementBase { + + std::string Type; ///< Type of "Value". + std::string Value; ///< Value. + + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFMetadata(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Metadata, pParent) {} +}; + +/// \struct CAMFImporter_NodeElement_Root +/// Structure that define root node. +struct AMFRoot : public AMFNodeElementBase { + + std::string Unit; ///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron". + std::string Version; ///< Version of format. + + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFRoot(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Root, pParent) {} +}; + +/// \struct CAMFImporter_NodeElement_Color +/// Structure that define object node. +struct AMFColor : public AMFNodeElementBase { + bool Composed; ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color. + std::string Color_Composed[4]; ///< By components formulas of composed color. [0..3] - RGBA. + aiColor4D Color; ///< Constant color. + std::string Profile; ///< The ICC color space used to interpret the three color channels r, g and b.. + + /// @brief Constructor. + /// @param [in] pParent - pointer to parent node. + AMFColor(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Color, pParent), Composed(false), Color(), Profile() { + // empty + } +}; + +/// \struct CAMFImporter_NodeElement_Material +/// Structure that define material node. +struct AMFMaterial : public AMFNodeElementBase { + + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFMaterial(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Material, pParent) {} +}; + +/// \struct CAMFImporter_NodeElement_Object +/// Structure that define object node. +struct AMFObject : public AMFNodeElementBase { + + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFObject(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Object, pParent) {} +}; + +/// \struct CAMFImporter_NodeElement_Mesh +/// Structure that define mesh node. +struct AMFMesh : public AMFNodeElementBase { + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFMesh(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Mesh, pParent) {} +}; + +/// \struct CAMFImporter_NodeElement_Vertex +/// Structure that define vertex node. +struct AMFVertex : public AMFNodeElementBase { + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFVertex(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Vertex, pParent) {} +}; + +/// \struct CAMFImporter_NodeElement_Edge +/// Structure that define edge node. +struct AMFEdge : public AMFNodeElementBase { + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFEdge(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Edge, pParent) {} +}; + +/// \struct CAMFImporter_NodeElement_Vertices +/// Structure that define vertices node. +struct AMFVertices : public AMFNodeElementBase { + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFVertices(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Vertices, pParent) {} +}; + +/// \struct CAMFImporter_NodeElement_Volume +/// Structure that define volume node. +struct AMFVolume : public AMFNodeElementBase { + std::string MaterialID; ///< Which material to use. + std::string Type; ///< What this volume describes can be "region" or "support". If none specified, "object" is assumed. + + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFVolume(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Volume, pParent) {} +}; + +/// \struct CAMFImporter_NodeElement_Coordinates +/// Structure that define coordinates node. +struct AMFCoordinates : public AMFNodeElementBase { + aiVector3D Coordinate; ///< Coordinate. + + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFCoordinates(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Coordinates, pParent) {} +}; + +/// \struct CAMFImporter_NodeElement_TexMap +/// Structure that define texture coordinates node. +struct AMFTexMap : public AMFNodeElementBase { + aiVector3D TextureCoordinate[3]; ///< Texture coordinates. + std::string TextureID_R; ///< Texture ID for red color component. + std::string TextureID_G; ///< Texture ID for green color component. + std::string TextureID_B; ///< Texture ID for blue color component. + std::string TextureID_A; ///< Texture ID for alpha color component. + + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFTexMap(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_TexMap, pParent), TextureCoordinate{}, TextureID_R(), TextureID_G(), TextureID_B(), TextureID_A() { + // empty + } +}; + +/// \struct CAMFImporter_NodeElement_Triangle +/// Structure that define triangle node. +struct AMFTriangle : public AMFNodeElementBase { + size_t V[3]; ///< Triangle vertices. + + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFTriangle(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Triangle, pParent) { + // empty + } +}; + +/// Structure that define texture node. +struct AMFTexture : public AMFNodeElementBase { + size_t Width, Height, Depth; ///< Size of the texture. + std::vector Data; ///< Data of the texture. + bool Tiled; + + /// Constructor. + /// \param [in] pParent - pointer to parent node. + AMFTexture(AMFNodeElementBase *pParent) : + AMFNodeElementBase(ENET_Texture, pParent), Width(0), Height(0), Depth(0), Data(), Tiled(false) { + // empty + } +}; + +#endif // INCLUDED_AI_AMF_IMPORTER_NODE_H diff --git a/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Postprocess.cpp b/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Postprocess.cpp new file mode 100644 index 000000000..a65f9260e --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Postprocess.cpp @@ -0,0 +1,894 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/// \file AMFImporter_Postprocess.cpp +/// \brief Convert built scenegraph and objects to Assimp scenegraph. +/// \date 2016 +/// \author smal.root@gmail.com + +#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER + +#include "AMFImporter.hpp" + +#include +#include +#include + +#include + +namespace Assimp { + +aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*pY*/, const float /*pZ*/) const { + aiColor4D tcol; + + // Check if stored data are supported. + if (!Composition.empty()) { + throw DeadlyImportError("IME. GetColor for composition"); + } + + if (Color->Composed) { + throw DeadlyImportError("IME. GetColor, composed color"); + } + + tcol = Color->Color; + + // Check if default color must be used + if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) { + tcol.r = 0.5f; + tcol.g = 0.5f; + tcol.b = 0.5f; + tcol.a = 1; + } + + return tcol; +} + +void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &nodeElement, std::vector &vertexCoordinateArray, + std::vector &pVertexColorArray) const { + AMFVertices *vn = nullptr; + size_t col_idx; + + // All data stored in "vertices", search for it. + for (AMFNodeElementBase *ne_child : nodeElement.Child) { + if (ne_child->Type == AMFNodeElementBase::ENET_Vertices) { + vn = (AMFVertices*)ne_child; + } + } + + // If "vertices" not found then no work for us. + if (vn == nullptr) { + return; + } + + // all coordinates stored as child and we need to reserve space for future push_back's. + vertexCoordinateArray.reserve(vn->Child.size()); + + // colors count equal vertices count. + pVertexColorArray.resize(vn->Child.size()); + col_idx = 0; + + // Inside vertices collect all data and place to arrays + for (AMFNodeElementBase *vn_child : vn->Child) { + // vertices, colors + if (vn_child->Type == AMFNodeElementBase::ENET_Vertex) { + // by default clear color for current vertex + pVertexColorArray[col_idx] = nullptr; + + for (AMFNodeElementBase *vtx : vn_child->Child) { + if (vtx->Type == AMFNodeElementBase::ENET_Coordinates) { + vertexCoordinateArray.push_back(((AMFCoordinates *)vtx)->Coordinate); + continue; + } + + if (vtx->Type == AMFNodeElementBase::ENET_Color) { + pVertexColorArray[col_idx] = (AMFColor *)vtx; + continue; + } + } + + ++col_idx; + } + } +} + +size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &r, const std::string &g, const std::string &b, const std::string &a) { + if (r.empty() && g.empty() && b.empty() && a.empty()) { + throw DeadlyImportError("PostprocessHelper_GetTextureID_Or_Create. At least one texture ID must be defined."); + } + + std::string TextureConverted_ID = r + "_" + g + "_" + b + "_" + a; + size_t TextureConverted_Index = 0; + for (const SPP_Texture &tex_convd : mTexture_Converted) { + if (tex_convd.ID == TextureConverted_ID) { + return TextureConverted_Index; + } else { + ++TextureConverted_Index; + } + } + + // Converted texture not found, create it. + AMFTexture *src_texture[4] { + nullptr + }; + std::vector src_texture_4check; + SPP_Texture converted_texture; + + { // find all specified source textures + AMFNodeElementBase *t_tex = nullptr; + + // R + if (!r.empty()) { + if (!Find_NodeElement(r, AMFNodeElementBase::EType::ENET_Texture, &t_tex)) { + Throw_ID_NotFound(r); + } + + src_texture[0] = (AMFTexture *)t_tex; + src_texture_4check.push_back((AMFTexture *)t_tex); + } else { + src_texture[0] = nullptr; + } + + // G + if (!g.empty()) { + if (!Find_NodeElement(g, AMFNodeElementBase::ENET_Texture, &t_tex)) { + Throw_ID_NotFound(g); + } + + src_texture[1] = (AMFTexture *)t_tex; + src_texture_4check.push_back((AMFTexture *)t_tex); + } else { + src_texture[1] = nullptr; + } + + // B + if (!b.empty()) { + if (!Find_NodeElement(b, AMFNodeElementBase::ENET_Texture, &t_tex)) { + Throw_ID_NotFound(b); + } + + src_texture[2] = (AMFTexture *)t_tex; + src_texture_4check.push_back((AMFTexture *)t_tex); + } else { + src_texture[2] = nullptr; + } + + // A + if (!a.empty()) { + if (!Find_NodeElement(a, AMFNodeElementBase::ENET_Texture, &t_tex)) { + Throw_ID_NotFound(a); + } + + src_texture[3] = (AMFTexture *)t_tex; + src_texture_4check.push_back((AMFTexture *)t_tex); + } else { + src_texture[3] = nullptr; + } + } // END: find all specified source textures + + // check that all textures has same size + if (src_texture_4check.size() > 1) { + for (size_t i = 0, i_e = (src_texture_4check.size() - 1); i < i_e; i++) { + if ((src_texture_4check[i]->Width != src_texture_4check[i + 1]->Width) || (src_texture_4check[i]->Height != src_texture_4check[i + 1]->Height) || + (src_texture_4check[i]->Depth != src_texture_4check[i + 1]->Depth)) { + throw DeadlyImportError("PostprocessHelper_GetTextureID_Or_Create. Source texture must has the same size."); + } + } + } // if(src_texture_4check.size() > 1) + + // set texture attributes + converted_texture.Width = src_texture_4check[0]->Width; + converted_texture.Height = src_texture_4check[0]->Height; + converted_texture.Depth = src_texture_4check[0]->Depth; + // if one of source texture is tiled then converted texture is tiled too. + converted_texture.Tiled = false; + for (uint8_t i = 0; i < src_texture_4check.size(); ++i) { + converted_texture.Tiled |= src_texture_4check[i]->Tiled; + } + + // Create format hint. + strcpy(converted_texture.FormatHint, "rgba0000"); // copy initial string. + if (!r.empty()) converted_texture.FormatHint[4] = '8'; + if (!g.empty()) converted_texture.FormatHint[5] = '8'; + if (!b.empty()) converted_texture.FormatHint[6] = '8'; + if (!a.empty()) converted_texture.FormatHint[7] = '8'; + + // Сopy data of textures. + size_t tex_size = 0; + size_t step = 0; + size_t off_g = 0; + size_t off_b = 0; + + // Calculate size of the target array and rule how data will be copied. + if (!r.empty() && nullptr != src_texture[0]) { + tex_size += src_texture[0]->Data.size(); + step++, off_g++, off_b++; + } + if (!g.empty() && nullptr != src_texture[1]) { + tex_size += src_texture[1]->Data.size(); + step++, off_b++; + } + if (!b.empty() && nullptr != src_texture[2]) { + tex_size += src_texture[2]->Data.size(); + step++; + } + if (!a.empty() && nullptr != src_texture[3]) { + tex_size += src_texture[3]->Data.size(); + step++; + } + + // Create target array. + converted_texture.Data = new uint8_t[tex_size]; + // And copy data + auto CopyTextureData = [&](const std::string &pID, const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void { + if (!pID.empty()) { + for (size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++) { + AMFTexture *tex = src_texture[pSrcTexNum]; + ai_assert(tex); + converted_texture.Data[idx_target] = tex->Data.at(idx_src); + } + } + }; // auto CopyTextureData = [&](const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void + + CopyTextureData(r, 0, step, 0); + CopyTextureData(g, off_g, step, 1); + CopyTextureData(b, off_b, step, 2); + CopyTextureData(a, step - 1, step, 3); + + // Store new converted texture ID + converted_texture.ID = TextureConverted_ID; + // Store new converted texture + mTexture_Converted.push_back(converted_texture); + + return TextureConverted_Index; +} + +void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list &pInputList, std::list> &pOutputList_Separated) { + auto texmap_is_equal = [](const AMFTexMap *pTexMap1, const AMFTexMap *pTexMap2) -> bool { + if ((pTexMap1 == nullptr) && (pTexMap2 == nullptr)) return true; + if (pTexMap1 == nullptr) return false; + if (pTexMap2 == nullptr) return false; + + if (pTexMap1->TextureID_R != pTexMap2->TextureID_R) return false; + if (pTexMap1->TextureID_G != pTexMap2->TextureID_G) return false; + if (pTexMap1->TextureID_B != pTexMap2->TextureID_B) return false; + if (pTexMap1->TextureID_A != pTexMap2->TextureID_A) return false; + + return true; + }; + + pOutputList_Separated.clear(); + if (pInputList.empty()) return; + + do { + SComplexFace face_start = pInputList.front(); + std::list face_list_cur; + + for (std::list::iterator it = pInputList.begin(), it_end = pInputList.end(); it != it_end;) { + if (texmap_is_equal(face_start.TexMap, it->TexMap)) { + auto it_old = it; + + ++it; + face_list_cur.push_back(*it_old); + pInputList.erase(it_old); + } else { + ++it; + } + } + + if (!face_list_cur.empty()) pOutputList_Separated.push_back(face_list_cur); + + } while (!pInputList.empty()); +} + +void AMFImporter::Postprocess_AddMetadata(const AMFMetaDataArray &metadataList, aiNode &sceneNode) const { + if (metadataList.empty()) { + return; + } + + if (sceneNode.mMetaData != nullptr) { + throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong."); + } + + // copy collected metadata to output node. + sceneNode.mMetaData = aiMetadata::Alloc(static_cast(metadataList.size())); + size_t meta_idx(0); + + for (const AMFMetadata *metadata : metadataList) { + sceneNode.mMetaData->Set(static_cast(meta_idx++), metadata->Type, aiString(metadata->Value)); + } +} + +void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, MeshArray &meshList, aiNode **pSceneNode) { + AMFColor *object_color = nullptr; + + // create new aiNode and set name as has. + *pSceneNode = new aiNode; + (*pSceneNode)->mName = pNodeElement.ID; + // read mesh and color + for (const AMFNodeElementBase *ne_child : pNodeElement.Child) { + std::vector vertex_arr; + std::vector color_arr; + + // color for object + if (ne_child->Type == AMFNodeElementBase::ENET_Color) { + object_color = (AMFColor *) ne_child; + } + + if (ne_child->Type == AMFNodeElementBase::ENET_Mesh) { + // Create arrays from children of mesh: vertices. + PostprocessHelper_CreateMeshDataArray(*((AMFMesh *)ne_child), vertex_arr, color_arr); + // Use this arrays as a source when creating every aiMesh + Postprocess_BuildMeshSet(*((AMFMesh *)ne_child), vertex_arr, color_arr, object_color, meshList, **pSceneNode); + } + } // for(const CAMFImporter_NodeElement* ne_child: pNodeElement) +} + +void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const std::vector &pVertexCoordinateArray, + const std::vector &pVertexColorArray, const AMFColor *pObjectColor, MeshArray &pMeshList, aiNode &pSceneNode) { + std::list mesh_idx; + + // all data stored in "volume", search for it. + for (const AMFNodeElementBase *ne_child : pNodeElement.Child) { + const AMFColor *ne_volume_color = nullptr; + const SPP_Material *cur_mat = nullptr; + + if (ne_child->Type == AMFNodeElementBase::ENET_Volume) { + /******************* Get faces *******************/ + const AMFVolume *ne_volume = reinterpret_cast(ne_child); + + std::list complex_faces_list; // List of the faces of the volume. + std::list> complex_faces_toplist; // List of the face list for every mesh. + + // check if volume use material + if (!ne_volume->MaterialID.empty()) { + if (!Find_ConvertedMaterial(ne_volume->MaterialID, &cur_mat)) { + Throw_ID_NotFound(ne_volume->MaterialID); + } + } + + // inside "volume" collect all data and place to arrays or create new objects + for (const AMFNodeElementBase *ne_volume_child : ne_volume->Child) { + // color for volume + if (ne_volume_child->Type == AMFNodeElementBase::ENET_Color) { + ne_volume_color = reinterpret_cast(ne_volume_child); + } else if (ne_volume_child->Type == AMFNodeElementBase::ENET_Triangle) // triangles, triangles colors + { + const AMFTriangle &tri_al = *reinterpret_cast(ne_volume_child); + + SComplexFace complex_face; + + // initialize pointers + complex_face.Color = nullptr; + complex_face.TexMap = nullptr; + // get data from triangle children: color, texture coordinates. + if (tri_al.Child.size()) { + for (const AMFNodeElementBase *ne_triangle_child : tri_al.Child) { + if (ne_triangle_child->Type == AMFNodeElementBase::ENET_Color) + complex_face.Color = reinterpret_cast(ne_triangle_child); + else if (ne_triangle_child->Type == AMFNodeElementBase::ENET_TexMap) + complex_face.TexMap = reinterpret_cast(ne_triangle_child); + } + } // if(tri_al.Child.size()) + + // create new face and store it. + complex_face.Face.mNumIndices = 3; + complex_face.Face.mIndices = new unsigned int[3]; + complex_face.Face.mIndices[0] = static_cast(tri_al.V[0]); + complex_face.Face.mIndices[1] = static_cast(tri_al.V[1]); + complex_face.Face.mIndices[2] = static_cast(tri_al.V[2]); + complex_faces_list.push_back(complex_face); + } + } // for(const CAMFImporter_NodeElement* ne_volume_child: ne_volume->Child) + + /**** Split faces list: one list per mesh ****/ + PostprocessHelper_SplitFacesByTextureID(complex_faces_list, complex_faces_toplist); + + /***** Create mesh for every faces list ******/ + for (std::list &face_list_cur : complex_faces_toplist) { + auto VertexIndex_GetMinimal = [](const std::list &pFaceList, const size_t *pBiggerThan) -> size_t { + size_t rv = 0; + + if (pBiggerThan != nullptr) { + bool found = false; + const size_t biggerThan = *pBiggerThan; + for (const SComplexFace &face : pFaceList) { + for (size_t idx_vert = 0; idx_vert < face.Face.mNumIndices; idx_vert++) { + if (face.Face.mIndices[idx_vert] > biggerThan) { + rv = face.Face.mIndices[idx_vert]; + found = true; + break; + } + } + + if (found) { + break; + } + } + + if (!found) { + return *pBiggerThan; + } + } else { + rv = pFaceList.front().Face.mIndices[0]; + } // if(pBiggerThan != nullptr) else + + for (const SComplexFace &face : pFaceList) { + for (size_t vi = 0; vi < face.Face.mNumIndices; vi++) { + if (face.Face.mIndices[vi] < rv) { + if (pBiggerThan != nullptr) { + if (face.Face.mIndices[vi] > *pBiggerThan) rv = face.Face.mIndices[vi]; + } else { + rv = face.Face.mIndices[vi]; + } + } + } + } // for(const SComplexFace& face: pFaceList) + + return rv; + }; // auto VertexIndex_GetMinimal = [](const std::list& pFaceList, const size_t* pBiggerThan) -> size_t + + auto VertexIndex_Replace = [](std::list &pFaceList, const size_t pIdx_From, const size_t pIdx_To) -> void { + for (const SComplexFace &face : pFaceList) { + for (size_t vi = 0; vi < face.Face.mNumIndices; vi++) { + if (face.Face.mIndices[vi] == pIdx_From) face.Face.mIndices[vi] = static_cast(pIdx_To); + } + } + }; // auto VertexIndex_Replace = [](std::list& pFaceList, const size_t pIdx_From, const size_t pIdx_To) -> void + + auto Vertex_CalculateColor = [&](const size_t pIdx) -> aiColor4D { + // Color priorities(In descending order): + // 1. triangle color; + // 2. vertex color; + // 3. volume color; + // 4. object color; + // 5. material; + // 6. default - invisible coat. + // + // Fill vertices colors in color priority list above that's points from 1 to 6. + if ((pIdx < pVertexColorArray.size()) && (pVertexColorArray[pIdx] != nullptr)) // check for vertex color + { + if (pVertexColorArray[pIdx]->Composed) + throw DeadlyImportError("IME: vertex color composed"); + else + return pVertexColorArray[pIdx]->Color; + } else if (ne_volume_color != nullptr) // check for volume color + { + if (ne_volume_color->Composed) + throw DeadlyImportError("IME: volume color composed"); + else + return ne_volume_color->Color; + } else if (pObjectColor != nullptr) // check for object color + { + if (pObjectColor->Composed) + throw DeadlyImportError("IME: object color composed"); + else + return pObjectColor->Color; + } else if (cur_mat != nullptr) // check for material + { + return cur_mat->GetColor(pVertexCoordinateArray.at(pIdx).x, pVertexCoordinateArray.at(pIdx).y, pVertexCoordinateArray.at(pIdx).z); + } else // set default color. + { + return { 0, 0, 0, 0 }; + } // if((vi < pVertexColorArray.size()) && (pVertexColorArray[vi] != nullptr)) else + }; // auto Vertex_CalculateColor = [&](const size_t pIdx) -> aiColor4D + + aiMesh *tmesh = new aiMesh; + + tmesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; // Only triangles is supported by AMF. + // + // set geometry and colors (vertices) + // + // copy faces/triangles + tmesh->mNumFaces = static_cast(face_list_cur.size()); + tmesh->mFaces = new aiFace[tmesh->mNumFaces]; + + // Create vertices list and optimize indices. Optimization mean following.In AMF all volumes use one big list of vertices. And one volume + // can use only part of vertices list, for example: vertices list contain few thousands of vertices and volume use vertices 1, 3, 10. + // Do you need all this thousands of garbage? Of course no. So, optimization step transform sparse indices set to continuous. + size_t VertexCount_Max = tmesh->mNumFaces * 3; // 3 - triangles. + std::vector vert_arr, texcoord_arr; + std::vector col_arr; + + vert_arr.reserve(VertexCount_Max * 2); // "* 2" - see below TODO. + col_arr.reserve(VertexCount_Max * 2); + + { // fill arrays + size_t vert_idx_from, vert_idx_to; + + // first iteration. + vert_idx_to = 0; + vert_idx_from = VertexIndex_GetMinimal(face_list_cur, nullptr); + vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from)); + col_arr.push_back(Vertex_CalculateColor(vert_idx_from)); + if (vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to); + + // rest iterations + do { + vert_idx_from = VertexIndex_GetMinimal(face_list_cur, &vert_idx_to); + if (vert_idx_from == vert_idx_to) break; // all indices are transferred, + + vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from)); + col_arr.push_back(Vertex_CalculateColor(vert_idx_from)); + vert_idx_to++; + if (vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to); + + } while (true); + } // fill arrays. END. + + // + // check if triangle colors are used and create additional faces if needed. + // + for (const SComplexFace &face_cur : face_list_cur) { + if (face_cur.Color != nullptr) { + aiColor4D face_color; + size_t vert_idx_new = vert_arr.size(); + + if (face_cur.Color->Composed) + throw DeadlyImportError("IME: face color composed"); + else + face_color = face_cur.Color->Color; + + for (size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++) { + vert_arr.push_back(vert_arr.at(face_cur.Face.mIndices[idx_ind])); + col_arr.push_back(face_color); + face_cur.Face.mIndices[idx_ind] = static_cast(vert_idx_new++); + } + } // if(face_cur.Color != nullptr) + } // for(const SComplexFace& face_cur: face_list_cur) + + // + // if texture is used then copy texture coordinates too. + // + if (face_list_cur.front().TexMap != nullptr) { + size_t idx_vert_new = vert_arr.size(); + ///TODO: clean unused vertices. "* 2": in certain cases - mesh full of triangle colors - vert_arr will contain duplicated vertices for + /// colored triangles and initial vertices (for colored vertices) which in real became unused. This part need more thinking about + /// optimization. + bool *idx_vert_used; + + idx_vert_used = new bool[VertexCount_Max * 2]; + for (size_t i = 0, i_e = VertexCount_Max * 2; i < i_e; i++) + idx_vert_used[i] = false; + + // This ID's will be used when set materials ID in scene. + tmesh->mMaterialIndex = static_cast(PostprocessHelper_GetTextureID_Or_Create(face_list_cur.front().TexMap->TextureID_R, + face_list_cur.front().TexMap->TextureID_G, + face_list_cur.front().TexMap->TextureID_B, + face_list_cur.front().TexMap->TextureID_A)); + texcoord_arr.resize(VertexCount_Max * 2); + for (const SComplexFace &face_cur : face_list_cur) { + for (size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++) { + const size_t idx_vert = face_cur.Face.mIndices[idx_ind]; + + if (!idx_vert_used[idx_vert]) { + texcoord_arr.at(idx_vert) = face_cur.TexMap->TextureCoordinate[idx_ind]; + idx_vert_used[idx_vert] = true; + } else if (texcoord_arr.at(idx_vert) != face_cur.TexMap->TextureCoordinate[idx_ind]) { + // in that case one vertex is shared with many texture coordinates. We need to duplicate vertex with another texture + // coordinates. + vert_arr.push_back(vert_arr.at(idx_vert)); + col_arr.push_back(col_arr.at(idx_vert)); + texcoord_arr.at(idx_vert_new) = face_cur.TexMap->TextureCoordinate[idx_ind]; + face_cur.Face.mIndices[idx_ind] = static_cast(idx_vert_new++); + } + } // for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++) + } // for(const SComplexFace& face_cur: face_list_cur) + + delete[] idx_vert_used; + // shrink array + texcoord_arr.resize(idx_vert_new); + } // if(face_list_cur.front().TexMap != nullptr) + + // + // copy collected data to mesh + // + tmesh->mNumVertices = static_cast(vert_arr.size()); + tmesh->mVertices = new aiVector3D[tmesh->mNumVertices]; + tmesh->mColors[0] = new aiColor4D[tmesh->mNumVertices]; + + memcpy(tmesh->mVertices, vert_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D)); + memcpy(tmesh->mColors[0], col_arr.data(), tmesh->mNumVertices * sizeof(aiColor4D)); + if (texcoord_arr.size() > 0) { + tmesh->mTextureCoords[0] = new aiVector3D[tmesh->mNumVertices]; + memcpy(tmesh->mTextureCoords[0], texcoord_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D)); + tmesh->mNumUVComponents[0] = 2; // U and V stored in "x", "y" of aiVector3D. + } + + size_t idx_face = 0; + for (const SComplexFace &face_cur : face_list_cur) + tmesh->mFaces[idx_face++] = face_cur.Face; + + // store new aiMesh + mesh_idx.push_back(static_cast(pMeshList.size())); + pMeshList.push_back(tmesh); + } // for(const std::list& face_list_cur: complex_faces_toplist) + } // if(ne_child->Type == CAMFImporter_NodeElement::ENET_Volume) + } // for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child) + + // if meshes was created then assign new indices with current aiNode + if (!mesh_idx.empty()) { + std::list::const_iterator mit = mesh_idx.begin(); + + pSceneNode.mNumMeshes = static_cast(mesh_idx.size()); + pSceneNode.mMeshes = new unsigned int[pSceneNode.mNumMeshes]; + for (size_t i = 0; i < pSceneNode.mNumMeshes; i++) + pSceneNode.mMeshes[i] = *mit++; + } // if(mesh_idx.size() > 0) +} + +void AMFImporter::Postprocess_BuildMaterial(const AMFMaterial &pMaterial) { + SPP_Material new_mat; + + new_mat.ID = pMaterial.ID; + for (const AMFNodeElementBase *mat_child : pMaterial.Child) { + if (mat_child->Type == AMFNodeElementBase::ENET_Color) { + new_mat.Color = (AMFColor*)mat_child; + } else if (mat_child->Type == AMFNodeElementBase::ENET_Metadata) { + new_mat.Metadata.push_back((AMFMetadata *)mat_child); + } + } // for(const CAMFImporter_NodeElement* mat_child; pMaterial.Child) + + // place converted material to special list + mMaterial_Converted.push_back(new_mat); +} + +void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellation, NodeArray &nodeArray) const { + aiNode *con_node; + std::list ch_node; + + // We will build next hierarchy: + // aiNode as parent () for set of nodes as a children + // |- aiNode for transformation ( -> , ) - aiNode for pointing to object ("objectid") + // ... + // \_ aiNode for transformation ( -> , ) - aiNode for pointing to object ("objectid") + con_node = new aiNode; + con_node->mName = pConstellation.ID; + // Walk through children and search for instances of another objects, constellations. + for (const AMFNodeElementBase *ne : pConstellation.Child) { + aiMatrix4x4 tmat; + aiNode *t_node; + aiNode *found_node; + + if (ne->Type == AMFNodeElementBase::ENET_Metadata) continue; + if (ne->Type != AMFNodeElementBase::ENET_Instance) throw DeadlyImportError("Only nodes can be in ."); + + // create alias for convenience + AMFInstance &als = *((AMFInstance *)ne); + // find referenced object + if (!Find_ConvertedNode(als.ObjectID, nodeArray, &found_node)) Throw_ID_NotFound(als.ObjectID); + + // create node for applying transformation + t_node = new aiNode; + t_node->mParent = con_node; + // apply transformation + aiMatrix4x4::Translation(als.Delta, tmat), t_node->mTransformation *= tmat; + aiMatrix4x4::RotationX(als.Rotation.x, tmat), t_node->mTransformation *= tmat; + aiMatrix4x4::RotationY(als.Rotation.y, tmat), t_node->mTransformation *= tmat; + aiMatrix4x4::RotationZ(als.Rotation.z, tmat), t_node->mTransformation *= tmat; + // create array for one child node + t_node->mNumChildren = 1; + t_node->mChildren = new aiNode *[t_node->mNumChildren]; + SceneCombiner::Copy(&t_node->mChildren[0], found_node); + t_node->mChildren[0]->mParent = t_node; + ch_node.push_back(t_node); + } // for(const CAMFImporter_NodeElement* ne: pConstellation.Child) + + // copy found aiNode's as children + if (ch_node.empty()) throw DeadlyImportError(" must have at least one ."); + + size_t ch_idx = 0; + + con_node->mNumChildren = static_cast(ch_node.size()); + con_node->mChildren = new aiNode *[con_node->mNumChildren]; + for (aiNode *node : ch_node) + con_node->mChildren[ch_idx++] = node; + + // and place "root" of node to node list + nodeArray.push_back(con_node); +} + +void AMFImporter::Postprocess_BuildScene(aiScene *pScene) { + NodeArray nodeArray; + MeshArray mesh_list; + AMFMetaDataArray meta_list; + + // + // Because for AMF "material" is just complex colors mixing so aiMaterial will not be used. + // For building aiScene we are must to do few steps: + // at first creating root node for aiScene. + pScene->mRootNode = new aiNode; + pScene->mRootNode->mParent = nullptr; + pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED; + // search for root() element + AMFNodeElementBase *root_el = nullptr; + + for (AMFNodeElementBase *ne : mNodeElement_List) { + if (ne->Type != AMFNodeElementBase::ENET_Root) { + continue; + } + + root_el = ne; + break; + } // for(const CAMFImporter_NodeElement* ne: mNodeElement_List) + + // Check if root element are found. + if (root_el == nullptr) { + throw DeadlyImportError("Root() element not found."); + } + + // after that walk through children of root and collect data. Five types of nodes can be placed at top level - in : , , , + // and . But at first we must read and because they will be used in . can be read + // at any moment. + // + // 1. + // 2. will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet + for (const AMFNodeElementBase *root_child : root_el->Child) { + if (root_child->Type == AMFNodeElementBase::ENET_Material) { + Postprocess_BuildMaterial(*((AMFMaterial *)root_child)); + } + } + + // After "appearance" nodes we must read because it will be used in -> . + // + // 3. + for (const AMFNodeElementBase *root_child : root_el->Child) { + if (root_child->Type == AMFNodeElementBase::ENET_Object) { + aiNode *tnode = nullptr; + + // for mesh and node must be built: object ID assigned to aiNode name and will be used in future for + Postprocess_BuildNodeAndObject(*((AMFObject *)root_child), mesh_list, &tnode); + if (tnode != nullptr) { + nodeArray.push_back(tnode); + } + } + } // for(const CAMFImporter_NodeElement* root_child: root_el->Child) + + // And finally read rest of nodes. + // + for (const AMFNodeElementBase *root_child : root_el->Child) { + // 4. + if (root_child->Type == AMFNodeElementBase::ENET_Constellation) { + // and at top of self abstraction use aiNode. So we can use only aiNode list for creating new aiNode's. + Postprocess_BuildConstellation(*((AMFConstellation *)root_child), nodeArray); + } + + // 5, + if (root_child->Type == AMFNodeElementBase::ENET_Metadata) meta_list.push_back((AMFMetadata *)root_child); + } // for(const CAMFImporter_NodeElement* root_child: root_el->Child) + + // at now we can add collected metadata to root node + Postprocess_AddMetadata(meta_list, *pScene->mRootNode); + // + // Check constellation children + // + // As said in specification: + // "When multiple objects and constellations are defined in a single file, only the top level objects and constellations are available for printing." + // What that means? For example: if some object is used in constellation then you must show only constellation but not original object. + // And at this step we are checking that relations. +nl_clean_loop: + + if (nodeArray.size() > 1) { + // walk through all nodes + for (NodeArray::iterator nl_it = nodeArray.begin(); nl_it != nodeArray.end(); ++nl_it) { + // and try to find them in another top nodes. + NodeArray::const_iterator next_it = nl_it; + + ++next_it; + for (; next_it != nodeArray.end(); ++next_it) { + if ((*next_it)->FindNode((*nl_it)->mName) != nullptr) { + // if current top node(nl_it) found in another top node then erase it from node_list and restart search loop. + nodeArray.erase(nl_it); + + goto nl_clean_loop; + } + } // for(; next_it != node_list.end(); next_it++) + } // for(std::list::const_iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++) + } + + // + // move created objects to aiScene + // + // + // Nodes + if (!nodeArray.empty()) { + NodeArray::const_iterator nl_it = nodeArray.begin(); + + pScene->mRootNode->mNumChildren = static_cast(nodeArray.size()); + pScene->mRootNode->mChildren = new aiNode *[pScene->mRootNode->mNumChildren]; + for (size_t i = 0; i < pScene->mRootNode->mNumChildren; i++) { + // Objects and constellation that must be showed placed at top of hierarchy in node. So all aiNode's in node_list must have + // mRootNode only as parent. + (*nl_it)->mParent = pScene->mRootNode; + pScene->mRootNode->mChildren[i] = *nl_it++; + } + } // if(node_list.size() > 0) + + // + // Meshes + if (!mesh_list.empty()) { + MeshArray::const_iterator ml_it = mesh_list.begin(); + + pScene->mNumMeshes = static_cast(mesh_list.size()); + pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; + for (size_t i = 0; i < pScene->mNumMeshes; i++) + pScene->mMeshes[i] = *ml_it++; + } // if(mesh_list.size() > 0) + + // + // Textures + pScene->mNumTextures = static_cast(mTexture_Converted.size()); + if (pScene->mNumTextures > 0) { + size_t idx; + + idx = 0; + pScene->mTextures = new aiTexture *[pScene->mNumTextures]; + for (const SPP_Texture &tex_convd : mTexture_Converted) { + pScene->mTextures[idx] = new aiTexture; + pScene->mTextures[idx]->mWidth = static_cast(tex_convd.Width); + pScene->mTextures[idx]->mHeight = static_cast(tex_convd.Height); + pScene->mTextures[idx]->pcData = (aiTexel *)tex_convd.Data; + // texture format description. + strcpy(pScene->mTextures[idx]->achFormatHint, tex_convd.FormatHint); + idx++; + } // for(const SPP_Texture& tex_convd: mTexture_Converted) + + // Create materials for embedded textures. + idx = 0; + pScene->mNumMaterials = static_cast(mTexture_Converted.size()); + pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials]; + for (const SPP_Texture &tex_convd : mTexture_Converted) { + const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + ai_to_string(idx)); + const int mode = aiTextureOp_Multiply; + const int repeat = tex_convd.Tiled ? 1 : 0; + + pScene->mMaterials[idx] = new aiMaterial; + pScene->mMaterials[idx]->AddProperty(&texture_id, AI_MATKEY_TEXTURE_DIFFUSE(0)); + pScene->mMaterials[idx]->AddProperty(&mode, 1, AI_MATKEY_TEXOP_DIFFUSE(0)); + pScene->mMaterials[idx]->AddProperty(&repeat, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0)); + pScene->mMaterials[idx]->AddProperty(&repeat, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0)); + idx++; + } + } // if(pScene->mNumTextures > 0) +} // END: after that walk through children of root and collect data + +} // namespace Assimp + +#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER diff --git a/Engine/lib/assimp/code/ASE/ASELoader.cpp b/Engine/lib/assimp/code/AssetLib/ASE/ASELoader.cpp similarity index 63% rename from Engine/lib/assimp/code/ASE/ASELoader.cpp rename to Engine/lib/assimp/code/AssetLib/ASE/ASELoader.cpp index 8e99214a8..caa708961 100644 --- a/Engine/lib/assimp/code/ASE/ASELoader.cpp +++ b/Engine/lib/assimp/code/AssetLib/ASE/ASELoader.cpp @@ -3,9 +3,7 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -51,15 +49,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // internal headers #include "ASELoader.h" -#include -#include #include "Common/TargetAnimation.h" +#include +#include -#include -#include -#include -#include #include +#include +#include +#include +#include #include @@ -84,12 +82,8 @@ static const aiImporterDesc desc = { // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer -ASEImporter::ASEImporter() -: mParser() -, mBuffer() -, pcScene() -, configRecomputeNormals() -, noSkeletonMesh() { +ASEImporter::ASEImporter() : + mParser(), mBuffer(), pcScene(), configRecomputeNormals(), noSkeletonMesh() { // empty } @@ -101,50 +95,42 @@ ASEImporter::~ASEImporter() { // ------------------------------------------------------------------------------------------------ // Returns whether the class can handle the format of the given file. -bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const { - // check file extension - const std::string extension = GetExtension(pFile); - - if (extension == "ase" || extension == "ask") { - return true; - } - - if ((!extension.length() || cs) && pIOHandler) { - const char* tokens[] = {"*3dsmax_asciiexport"}; - return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1); - } - return false; +bool ASEImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { + static const char *tokens[] = { "*3dsmax_asciiexport" }; + return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); } // ------------------------------------------------------------------------------------------------ // Loader meta information -const aiImporterDesc* ASEImporter::GetInfo () const { +const aiImporterDesc *ASEImporter::GetInfo() const { return &desc; } // ------------------------------------------------------------------------------------------------ // Setup configuration options -void ASEImporter::SetupProperties(const Importer* pImp) { +void ASEImporter::SetupProperties(const Importer *pImp) { configRecomputeNormals = (pImp->GetPropertyInteger( - AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS,1) ? true : false); + AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS, 1) ? + true : + false); - noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0; + noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0; } // ------------------------------------------------------------------------------------------------ // Imports the given file into the given scene structure. -void ASEImporter::InternReadFile( const std::string& pFile, - aiScene* pScene, IOSystem* pIOHandler) { - std::unique_ptr file( pIOHandler->Open( pFile, "rb")); +void ASEImporter::InternReadFile(const std::string &pFile, + aiScene *pScene, IOSystem *pIOHandler) { + std::unique_ptr file(pIOHandler->Open(pFile, "rb")); // Check whether we can read from the file - if( file.get() == nullptr) { - throw DeadlyImportError( "Failed to open ASE file " + pFile + "."); + if (file.get() == nullptr) { + throw DeadlyImportError("Failed to open ASE file ", pFile, "."); } // Allocate storage and copy the contents of the file to a memory buffer std::vector mBuffer2; - TextFileToBuffer(file.get(),mBuffer2); + TextFileToBuffer(file.get(), mBuffer2); this->mBuffer = &mBuffer2[0]; this->pcScene = pScene; @@ -155,8 +141,8 @@ void ASEImporter::InternReadFile( const std::string& pFile, // ASE is the actual version 200 (that is currently written by max) // ------------------------------------------------------------------ unsigned int defaultFormat; - std::string::size_type s = pFile.length()-1; - switch (pFile.c_str()[s]) { + std::string::size_type s = pFile.length() - 1; + switch (pFile.c_str()[s]) { case 'C': case 'c': @@ -167,7 +153,7 @@ void ASEImporter::InternReadFile( const std::string& pFile, }; // Construct an ASE parser and parse the file - ASE::Parser parser(mBuffer,defaultFormat); + ASE::Parser parser(mBuffer, defaultFormat); mParser = &parser; mParser->Parse(); @@ -175,7 +161,7 @@ void ASEImporter::InternReadFile( const std::string& pFile, // Check whether we god at least one mesh. If we did - generate // materials and copy meshes. // ------------------------------------------------------------------ - if ( !mParser->m_vMeshes.empty()) { + if (!mParser->m_vMeshes.empty()) { // If absolutely no material has been loaded from the file // we need to generate a default material @@ -183,32 +169,32 @@ void ASEImporter::InternReadFile( const std::string& pFile, // process all meshes bool tookNormals = false; - std::vector avOutMeshes; - avOutMeshes.reserve(mParser->m_vMeshes.size()*2); - for (std::vector::iterator i = mParser->m_vMeshes.begin();i != mParser->m_vMeshes.end();++i) { + std::vector avOutMeshes; + avOutMeshes.reserve(mParser->m_vMeshes.size() * 2); + for (std::vector::iterator i = mParser->m_vMeshes.begin(); i != mParser->m_vMeshes.end(); ++i) { if ((*i).bSkip) { continue; } BuildUniqueRepresentation(*i); // Need to generate proper vertex normals if necessary - if(GenerateNormals(*i)) { + if (GenerateNormals(*i)) { tookNormals = true; } // Convert all meshes to aiMesh objects - ConvertMeshes(*i,avOutMeshes); + ConvertMeshes(*i, avOutMeshes); } - if (tookNormals) { + if (tookNormals) { ASSIMP_LOG_DEBUG("ASE: Taking normals from the file. Use " - "the AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS setting if you " - "experience problems"); + "the AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS setting if you " + "experience problems"); } // Now build the output mesh list. Remove dummies pScene->mNumMeshes = (unsigned int)avOutMeshes.size(); - aiMesh** pp = pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; - for (std::vector::const_iterator i = avOutMeshes.begin();i != avOutMeshes.end();++i) { + aiMesh **pp = pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; + for (std::vector::const_iterator i = avOutMeshes.begin(); i != avOutMeshes.end(); ++i) { if (!(*i)->mNumFaces) { continue; } @@ -225,18 +211,21 @@ void ASEImporter::InternReadFile( const std::string& pFile, // Copy all scene graph nodes - lights, cameras, dummies and meshes // into one huge list. //------------------------------------------------------------------ - std::vector nodes; - nodes.reserve(mParser->m_vMeshes.size() +mParser->m_vLights.size() - + mParser->m_vCameras.size() + mParser->m_vDummies.size()); + std::vector nodes; + nodes.reserve(mParser->m_vMeshes.size() + mParser->m_vLights.size() + mParser->m_vCameras.size() + mParser->m_vDummies.size()); // Lights - for (auto &light : mParser->m_vLights)nodes.push_back(&light); + for (auto &light : mParser->m_vLights) + nodes.push_back(&light); // Cameras - for (auto &camera : mParser->m_vCameras)nodes.push_back(&camera); + for (auto &camera : mParser->m_vCameras) + nodes.push_back(&camera); // Meshes - for (auto &mesh : mParser->m_vMeshes)nodes.push_back(&mesh); + for (auto &mesh : mParser->m_vMeshes) + nodes.push_back(&mesh); // Dummies - for (auto &dummy : mParser->m_vDummies)nodes.push_back(&dummy); + for (auto &dummy : mParser->m_vDummies) + nodes.push_back(&dummy); // build the final node graph BuildNodes(nodes); @@ -255,7 +244,7 @@ void ASEImporter::InternReadFile( const std::string& pFile, // to build a mesh for the animation skeleton // FIXME: very strange results // ------------------------------------------------------------------ - if (!pScene->mNumMeshes) { + if (!pScene->mNumMeshes) { pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; if (!noSkeletonMesh) { SkeletonMeshBuilder skeleton(pScene); @@ -263,82 +252,80 @@ void ASEImporter::InternReadFile( const std::string& pFile, } } // ------------------------------------------------------------------------------------------------ -void ASEImporter::GenerateDefaultMaterial() -{ - ai_assert(NULL != mParser); +void ASEImporter::GenerateDefaultMaterial() { + ai_assert(nullptr != mParser); bool bHas = false; - for (std::vector::iterator i = mParser->m_vMeshes.begin();i != mParser->m_vMeshes.end();++i) { - if ((*i).bSkip)continue; + for (std::vector::iterator i = mParser->m_vMeshes.begin(); i != mParser->m_vMeshes.end(); ++i) { + if ((*i).bSkip) continue; if (ASE::Face::DEFAULT_MATINDEX == (*i).iMaterialIndex) { (*i).iMaterialIndex = (unsigned int)mParser->m_vMaterials.size(); bHas = true; } } - if (bHas || mParser->m_vMaterials.empty()) { + if (bHas || mParser->m_vMaterials.empty()) { // add a simple material without submaterials to the parser's list - mParser->m_vMaterials.push_back ( ASE::Material(AI_DEFAULT_MATERIAL_NAME) ); - ASE::Material& mat = mParser->m_vMaterials.back(); + mParser->m_vMaterials.push_back(ASE::Material(AI_DEFAULT_MATERIAL_NAME)); + ASE::Material &mat = mParser->m_vMaterials.back(); - mat.mDiffuse = aiColor3D(0.6f,0.6f,0.6f); - mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f); - mat.mAmbient = aiColor3D(0.05f,0.05f,0.05f); - mat.mShading = Discreet3DS::Gouraud; + mat.mDiffuse = aiColor3D(0.6f, 0.6f, 0.6f); + mat.mSpecular = aiColor3D(1.0f, 1.0f, 1.0f); + mat.mAmbient = aiColor3D(0.05f, 0.05f, 0.05f); + mat.mShading = Discreet3DS::Gouraud; } } // ------------------------------------------------------------------------------------------------ -void ASEImporter::BuildAnimations(const std::vector& nodes) -{ +void ASEImporter::BuildAnimations(const std::vector &nodes) { // check whether we have at least one mesh which has animations - std::vector::const_iterator i = nodes.begin(); + std::vector::const_iterator i = nodes.begin(); unsigned int iNum = 0; - for (;i != nodes.end();++i) { + for (; i != nodes.end(); ++i) { // TODO: Implement Bezier & TCB support if ((*i)->mAnim.mPositionType != ASE::Animation::TRACK) { ASSIMP_LOG_WARN("ASE: Position controller uses Bezier/TCB keys. " - "This is not supported."); + "This is not supported."); } if ((*i)->mAnim.mRotationType != ASE::Animation::TRACK) { ASSIMP_LOG_WARN("ASE: Rotation controller uses Bezier/TCB keys. " - "This is not supported."); + "This is not supported."); } - if ((*i)->mAnim.mScalingType != ASE::Animation::TRACK) { + if ((*i)->mAnim.mScalingType != ASE::Animation::TRACK) { ASSIMP_LOG_WARN("ASE: Position controller uses Bezier/TCB keys. " - "This is not supported."); + "This is not supported."); } // We compare against 1 here - firstly one key is not // really an animation and secondly MAX writes dummies // that represent the node transformation. - if ((*i)->mAnim.akeyPositions.size()>1 || (*i)->mAnim.akeyRotations.size()>1 || (*i)->mAnim.akeyScaling.size()>1){ + if ((*i)->mAnim.akeyPositions.size() > 1 || (*i)->mAnim.akeyRotations.size() > 1 || (*i)->mAnim.akeyScaling.size() > 1) { ++iNum; } - if ((*i)->mTargetAnim.akeyPositions.size() > 1 && is_not_qnan( (*i)->mTargetPosition.x )) { + if ((*i)->mTargetAnim.akeyPositions.size() > 1 && is_not_qnan((*i)->mTargetPosition.x)) { ++iNum; } } - if (iNum) { + if (iNum) { // Generate a new animation channel and setup everything for it pcScene->mNumAnimations = 1; - pcScene->mAnimations = new aiAnimation*[1]; - aiAnimation* pcAnim = pcScene->mAnimations[0] = new aiAnimation(); - pcAnim->mNumChannels = iNum; - pcAnim->mChannels = new aiNodeAnim*[iNum]; + pcScene->mAnimations = new aiAnimation *[1]; + aiAnimation *pcAnim = pcScene->mAnimations[0] = new aiAnimation(); + pcAnim->mNumChannels = iNum; + pcAnim->mChannels = new aiNodeAnim *[iNum]; pcAnim->mTicksPerSecond = mParser->iFrameSpeed * mParser->iTicksPerFrame; iNum = 0; // Now iterate through all meshes and collect all data we can find - for (i = nodes.begin();i != nodes.end();++i) { + for (i = nodes.begin(); i != nodes.end(); ++i) { - ASE::BaseNode* me = *i; - if ( me->mTargetAnim.akeyPositions.size() > 1 && is_not_qnan( me->mTargetPosition.x )) { + ASE::BaseNode *me = *i; + if (me->mTargetAnim.akeyPositions.size() > 1 && is_not_qnan(me->mTargetPosition.x)) { // Generate an extra channel for the camera/light target. // BuildNodes() does also generate an extra node, named // .Target. - aiNodeAnim* nd = pcAnim->mChannels[iNum++] = new aiNodeAnim(); + aiNodeAnim *nd = pcAnim->mChannels[iNum++] = new aiNodeAnim(); nd->mNodeName.Set(me->mName + ".Target"); // If there is no input position channel we will need @@ -357,32 +344,31 @@ void ASEImporter::BuildAnimations(const std::vector& nodes) helper.Process(&me->mTargetAnim.akeyPositions);*/ // Allocate the key array and fill it - nd->mNumPositionKeys = (unsigned int) me->mTargetAnim.akeyPositions.size(); + nd->mNumPositionKeys = (unsigned int)me->mTargetAnim.akeyPositions.size(); nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys]; - ::memcpy(nd->mPositionKeys,&me->mTargetAnim.akeyPositions[0], - nd->mNumPositionKeys * sizeof(aiVectorKey)); + ::memcpy(nd->mPositionKeys, &me->mTargetAnim.akeyPositions[0], + nd->mNumPositionKeys * sizeof(aiVectorKey)); } - if (me->mAnim.akeyPositions.size() > 1 || me->mAnim.akeyRotations.size() > 1 || me->mAnim.akeyScaling.size() > 1) { + if (me->mAnim.akeyPositions.size() > 1 || me->mAnim.akeyRotations.size() > 1 || me->mAnim.akeyScaling.size() > 1) { // Begin a new node animation channel for this node - aiNodeAnim* nd = pcAnim->mChannels[iNum++] = new aiNodeAnim(); + aiNodeAnim *nd = pcAnim->mChannels[iNum++] = new aiNodeAnim(); nd->mNodeName.Set(me->mName); // copy position keys - if (me->mAnim.akeyPositions.size() > 1 ) - { + if (me->mAnim.akeyPositions.size() > 1) { // Allocate the key array and fill it - nd->mNumPositionKeys = (unsigned int) me->mAnim.akeyPositions.size(); + nd->mNumPositionKeys = (unsigned int)me->mAnim.akeyPositions.size(); nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys]; - ::memcpy(nd->mPositionKeys,&me->mAnim.akeyPositions[0], - nd->mNumPositionKeys * sizeof(aiVectorKey)); + ::memcpy(nd->mPositionKeys, &me->mAnim.akeyPositions[0], + nd->mNumPositionKeys * sizeof(aiVectorKey)); } // copy rotation keys - if (me->mAnim.akeyRotations.size() > 1 ) { + if (me->mAnim.akeyRotations.size() > 1) { // Allocate the key array and fill it - nd->mNumRotationKeys = (unsigned int) me->mAnim.akeyRotations.size(); + nd->mNumRotationKeys = (unsigned int)me->mAnim.akeyRotations.size(); nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys]; // -------------------------------------------------------------------- @@ -395,11 +381,11 @@ void ASEImporter::BuildAnimations(const std::vector& nodes) // -------------------------------------------------------------------- aiQuaternion cur; - for (unsigned int a = 0; a < nd->mNumRotationKeys;++a) { + for (unsigned int a = 0; a < nd->mNumRotationKeys; ++a) { aiQuatKey q = me->mAnim.akeyRotations[a]; if (mParser->iFileFormat > 110) { - cur = (a ? cur*q.mValue : q.mValue); + cur = (a ? cur * q.mValue : q.mValue); q.mValue = cur.Normalize(); } nd->mRotationKeys[a] = q; @@ -409,13 +395,13 @@ void ASEImporter::BuildAnimations(const std::vector& nodes) } } // copy scaling keys - if (me->mAnim.akeyScaling.size() > 1 ) { + if (me->mAnim.akeyScaling.size() > 1) { // Allocate the key array and fill it - nd->mNumScalingKeys = (unsigned int) me->mAnim.akeyScaling.size(); + nd->mNumScalingKeys = (unsigned int)me->mAnim.akeyScaling.size(); nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys]; - ::memcpy(nd->mScalingKeys,&me->mAnim.akeyScaling[0], - nd->mNumScalingKeys * sizeof(aiVectorKey)); + ::memcpy(nd->mScalingKeys, &me->mAnim.akeyScaling[0], + nd->mNumScalingKeys * sizeof(aiVectorKey)); } } } @@ -424,18 +410,17 @@ void ASEImporter::BuildAnimations(const std::vector& nodes) // ------------------------------------------------------------------------------------------------ // Build output cameras -void ASEImporter::BuildCameras() -{ - if (!mParser->m_vCameras.empty()) { +void ASEImporter::BuildCameras() { + if (!mParser->m_vCameras.empty()) { pcScene->mNumCameras = (unsigned int)mParser->m_vCameras.size(); - pcScene->mCameras = new aiCamera*[pcScene->mNumCameras]; + pcScene->mCameras = new aiCamera *[pcScene->mNumCameras]; - for (unsigned int i = 0; i < pcScene->mNumCameras;++i) { - aiCamera* out = pcScene->mCameras[i] = new aiCamera(); - ASE::Camera& in = mParser->m_vCameras[i]; + for (unsigned int i = 0; i < pcScene->mNumCameras; ++i) { + aiCamera *out = pcScene->mCameras[i] = new aiCamera(); + ASE::Camera &in = mParser->m_vCameras[i]; // copy members - out->mClipPlaneFar = in.mFar; + out->mClipPlaneFar = in.mFar; out->mClipPlaneNear = (in.mNear ? in.mNear : 0.1f); out->mHorizontalFOV = in.mFOV; @@ -446,24 +431,22 @@ void ASEImporter::BuildCameras() // ------------------------------------------------------------------------------------------------ // Build output lights -void ASEImporter::BuildLights() -{ - if (!mParser->m_vLights.empty()) { +void ASEImporter::BuildLights() { + if (!mParser->m_vLights.empty()) { pcScene->mNumLights = (unsigned int)mParser->m_vLights.size(); - pcScene->mLights = new aiLight*[pcScene->mNumLights]; + pcScene->mLights = new aiLight *[pcScene->mNumLights]; - for (unsigned int i = 0; i < pcScene->mNumLights;++i) { - aiLight* out = pcScene->mLights[i] = new aiLight(); - ASE::Light& in = mParser->m_vLights[i]; + for (unsigned int i = 0; i < pcScene->mNumLights; ++i) { + aiLight *out = pcScene->mLights[i] = new aiLight(); + ASE::Light &in = mParser->m_vLights[i]; // The direction is encoded in the transformation matrix of the node. // In 3DS MAX the light source points into negative Z direction if // the node transformation is the identity. - out->mDirection = aiVector3D(0.f,0.f,-1.f); + out->mDirection = aiVector3D(0.f, 0.f, -1.f); out->mName.Set(in.mName); - switch (in.mLightType) - { + switch (in.mLightType) { case ASE::Light::TARGET: out->mType = aiLightSource_SPOT; out->mAngleInnerCone = AI_DEG_TO_RAD(in.mAngle); @@ -475,7 +458,7 @@ void ASEImporter::BuildLights() break; default: - //case ASE::Light::OMNI: + //case ASE::Light::OMNI: out->mType = aiLightSource_POINT; break; }; @@ -485,57 +468,55 @@ void ASEImporter::BuildLights() } // ------------------------------------------------------------------------------------------------ -void ASEImporter::AddNodes(const std::vector& nodes, - aiNode* pcParent,const char* szName) -{ +void ASEImporter::AddNodes(const std::vector &nodes, + aiNode *pcParent, const char *szName) { aiMatrix4x4 m; - AddNodes(nodes,pcParent,szName,m); + AddNodes(nodes, pcParent, szName, m); } // ------------------------------------------------------------------------------------------------ // Add meshes to a given node -void ASEImporter::AddMeshes(const ASE::BaseNode* snode,aiNode* node) -{ - for (unsigned int i = 0; i < pcScene->mNumMeshes;++i) { +void ASEImporter::AddMeshes(const ASE::BaseNode *snode, aiNode *node) { + for (unsigned int i = 0; i < pcScene->mNumMeshes; ++i) { // Get the name of the mesh (the mesh instance has been temporarily stored in the third vertex color) - const aiMesh* pcMesh = pcScene->mMeshes[i]; - const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2]; + const aiMesh *pcMesh = pcScene->mMeshes[i]; + const ASE::Mesh *mesh = (const ASE::Mesh *)pcMesh->mColors[2]; if (mesh == snode) { ++node->mNumMeshes; } } - if(node->mNumMeshes) { + if (node->mNumMeshes) { node->mMeshes = new unsigned int[node->mNumMeshes]; - for (unsigned int i = 0, p = 0; i < pcScene->mNumMeshes;++i) { + for (unsigned int i = 0, p = 0; i < pcScene->mNumMeshes; ++i) { - const aiMesh* pcMesh = pcScene->mMeshes[i]; - const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2]; - if (mesh == snode) { + const aiMesh *pcMesh = pcScene->mMeshes[i]; + const ASE::Mesh *mesh = (const ASE::Mesh *)pcMesh->mColors[2]; + if (mesh == snode) { node->mMeshes[p++] = i; // Transform all vertices of the mesh back into their local space -> // at the moment they are pretransformed - aiMatrix4x4 m = mesh->mTransform; + aiMatrix4x4 m = mesh->mTransform; m.Inverse(); - aiVector3D* pvCurPtr = pcMesh->mVertices; - const aiVector3D* pvEndPtr = pvCurPtr + pcMesh->mNumVertices; - while (pvCurPtr != pvEndPtr) { + aiVector3D *pvCurPtr = pcMesh->mVertices; + const aiVector3D *pvEndPtr = pvCurPtr + pcMesh->mNumVertices; + while (pvCurPtr != pvEndPtr) { *pvCurPtr = m * (*pvCurPtr); pvCurPtr++; } // Do the same for the normal vectors, if we have them. // As always, inverse transpose. - if (pcMesh->mNormals) { - aiMatrix3x3 m3 = aiMatrix3x3( mesh->mTransform ); + if (pcMesh->mNormals) { + aiMatrix3x3 m3 = aiMatrix3x3(mesh->mTransform); m3.Transpose(); pvCurPtr = pcMesh->mNormals; pvEndPtr = pvCurPtr + pcMesh->mNumVertices; - while (pvCurPtr != pvEndPtr) { + while (pvCurPtr != pvEndPtr) { *pvCurPtr = m3 * (*pvCurPtr); pvCurPtr++; } @@ -547,68 +528,65 @@ void ASEImporter::AddMeshes(const ASE::BaseNode* snode,aiNode* node) // ------------------------------------------------------------------------------------------------ // Add child nodes to a given parent node -void ASEImporter::AddNodes (const std::vector& nodes, - aiNode* pcParent, const char* szName, - const aiMatrix4x4& mat) -{ +void ASEImporter::AddNodes(const std::vector &nodes, + aiNode *pcParent, const char *szName, + const aiMatrix4x4 &mat) { const size_t len = szName ? ::strlen(szName) : 0; ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS); // Receives child nodes for the pcParent node - std::vector apcNodes; + std::vector apcNodes; // Now iterate through all nodes in the scene and search for one // which has *us* as parent. - for (std::vector::const_iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) { - const BaseNode* snode = *it; + for (std::vector::const_iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) { + const BaseNode *snode = *it; if (szName) { - if (len != snode->mParent.length() || ::strcmp(szName,snode->mParent.c_str())) + if (len != snode->mParent.length() || ::strcmp(szName, snode->mParent.c_str())) continue; - } - else if (snode->mParent.length()) + } else if (snode->mParent.length()) continue; (*it)->mProcessed = true; // Allocate a new node and add it to the output data structure apcNodes.push_back(new aiNode()); - aiNode* node = apcNodes.back(); + aiNode *node = apcNodes.back(); node->mName.Set((snode->mName.length() ? snode->mName.c_str() : "Unnamed_Node")); node->mParent = pcParent; // Setup the transformation matrix of the node - aiMatrix4x4 mParentAdjust = mat; + aiMatrix4x4 mParentAdjust = mat; mParentAdjust.Inverse(); - node->mTransformation = mParentAdjust*snode->mTransform; + node->mTransformation = mParentAdjust * snode->mTransform; // Add sub nodes - prevent stack overflow due to recursive parenting - if (node->mName != node->mParent->mName && node->mName != node->mParent->mParent->mName ) { - AddNodes(nodes,node,node->mName.data,snode->mTransform); + if (node->mName != node->mParent->mName && node->mName != node->mParent->mParent->mName) { + AddNodes(nodes, node, node->mName.data, snode->mTransform); } // Further processing depends on the type of the node - if (snode->mType == ASE::BaseNode::Mesh) { + if (snode->mType == ASE::BaseNode::Mesh) { // If the type of this node is "Mesh" we need to search // the list of output meshes in the data structure for // all those that belonged to this node once. This is // slightly inconvinient here and a better solution should // be used when this code is refactored next. - AddMeshes(snode,node); - } - else if (is_not_qnan( snode->mTargetPosition.x )) { + AddMeshes(snode, node); + } else if (is_not_qnan(snode->mTargetPosition.x)) { // If this is a target camera or light we generate a small // child node which marks the position of the camera // target (the direction information is contained in *this* // node's animation track but the exact target position // would be lost otherwise) - if (!node->mNumChildren) { - node->mChildren = new aiNode*[1]; + if (!node->mNumChildren) { + node->mChildren = new aiNode *[1]; } - aiNode* nd = new aiNode(); + aiNode *nd = new aiNode(); - nd->mName.Set ( snode->mName + ".Target" ); + nd->mName.Set(snode->mName + ".Target"); nd->mTransformation.a4 = snode->mTargetPosition.x - snode->mTransform.a4; nd->mTransformation.b4 = snode->mTargetPosition.y - snode->mTransform.b4; @@ -617,14 +595,14 @@ void ASEImporter::AddNodes (const std::vector& nodes, nd->mParent = node; // The .Target node is always the first child node - for (unsigned int m = 0; m < node->mNumChildren;++m) - node->mChildren[m+1] = node->mChildren[m]; + for (unsigned int m = 0; m < node->mNumChildren; ++m) + node->mChildren[m + 1] = node->mChildren[m]; node->mChildren[0] = nd; node->mNumChildren++; // What we did is so great, it is at least worth a debug message - ASSIMP_LOG_DEBUG("ASE: Generating separate target node ("+snode->mName+")"); + ASSIMP_LOG_VERBOSE_DEBUG("ASE: Generating separate target node (", snode->mName, ")"); } } @@ -632,10 +610,10 @@ void ASEImporter::AddNodes (const std::vector& nodes, // We allocate one slot more in case this is a target camera/light pcParent->mNumChildren = (unsigned int)apcNodes.size(); if (pcParent->mNumChildren) { - pcParent->mChildren = new aiNode*[apcNodes.size()+1 /* PLUS ONE !!! */]; + pcParent->mChildren = new aiNode *[apcNodes.size() + 1 /* PLUS ONE !!! */]; // now build all nodes for our nice new children - for (unsigned int p = 0; p < apcNodes.size();++p) + for (unsigned int p = 0; p < apcNodes.size(); ++p) pcParent->mChildren[p] = apcNodes[p]; } return; @@ -643,32 +621,32 @@ void ASEImporter::AddNodes (const std::vector& nodes, // ------------------------------------------------------------------------------------------------ // Build the output node graph -void ASEImporter::BuildNodes(std::vector& nodes) { - ai_assert(NULL != pcScene); +void ASEImporter::BuildNodes(std::vector &nodes) { + ai_assert(nullptr != pcScene); // allocate the one and only root node - aiNode* root = pcScene->mRootNode = new aiNode(); + aiNode *root = pcScene->mRootNode = new aiNode(); root->mName.Set(""); // Setup the coordinate system transformation pcScene->mRootNode->mNumChildren = 1; - pcScene->mRootNode->mChildren = new aiNode*[1]; - aiNode* ch = pcScene->mRootNode->mChildren[0] = new aiNode(); + pcScene->mRootNode->mChildren = new aiNode *[1]; + aiNode *ch = pcScene->mRootNode->mChildren[0] = new aiNode(); ch->mParent = root; // Change the transformation matrix of all nodes for (BaseNode *node : nodes) { - aiMatrix4x4& m = node->mTransform; + aiMatrix4x4 &m = node->mTransform; m.Transpose(); // row-order vs column-order } // add all nodes - AddNodes(nodes,ch,NULL); + AddNodes(nodes, ch, nullptr); // now iterate through al nodes and find those that have not yet // been added to the nodegraph (= their parent could not be recognized) - std::vector aiList; - for (std::vector::iterator it = nodes.begin(), end = nodes.end();it != end; ++it) { + std::vector aiList; + for (std::vector::iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) { if ((*it)->mProcessed) { continue; } @@ -678,54 +656,54 @@ void ASEImporter::BuildNodes(std::vector& nodes) { // search the list another time, starting *here* and try to find out whether // there is a node that references *us* as a parent - for (std::vector::const_iterator it2 = nodes.begin();it2 != end; ++it2) { + for (std::vector::const_iterator it2 = nodes.begin(); it2 != end; ++it2) { if (it2 == it) { continue; } - if ((*it2)->mName == (*it)->mParent) { + if ((*it2)->mName == (*it)->mParent) { bKnowParent = true; break; } } - if (!bKnowParent) { + if (!bKnowParent) { aiList.push_back(*it); } } - // Are there ane orphaned nodes? - if (!aiList.empty()) { - std::vector apcNodes; + // Are there any orphaned nodes? + if (!aiList.empty()) { + std::vector apcNodes; apcNodes.reserve(aiList.size() + pcScene->mRootNode->mNumChildren); - for (unsigned int i = 0; i < pcScene->mRootNode->mNumChildren;++i) + for (unsigned int i = 0; i < pcScene->mRootNode->mNumChildren; ++i) apcNodes.push_back(pcScene->mRootNode->mChildren[i]); delete[] pcScene->mRootNode->mChildren; - for (std::vector::/*const_*/iterator i = aiList.begin();i != aiList.end();++i) { - const ASE::BaseNode* src = *i; + for (std::vector::/*const_*/ iterator i = aiList.begin(); i != aiList.end(); ++i) { + const ASE::BaseNode *src = *i; // The parent is not known, so we can assume that we must add // this node to the root node of the whole scene - aiNode* pcNode = new aiNode(); + aiNode *pcNode = new aiNode(); pcNode->mParent = pcScene->mRootNode; pcNode->mName.Set(src->mName); - AddMeshes(src,pcNode); - AddNodes(nodes,pcNode,pcNode->mName.data); + AddMeshes(src, pcNode); + AddNodes(nodes, pcNode, pcNode->mName.data); apcNodes.push_back(pcNode); } // Regenerate our output array - pcScene->mRootNode->mChildren = new aiNode*[apcNodes.size()]; - for (unsigned int i = 0; i < apcNodes.size();++i) + pcScene->mRootNode->mChildren = new aiNode *[apcNodes.size()]; + for (unsigned int i = 0; i < apcNodes.size(); ++i) pcScene->mRootNode->mChildren[i] = apcNodes[i]; pcScene->mRootNode->mNumChildren = (unsigned int)apcNodes.size(); } - // Reset the third color set to NULL - we used this field to store a temporary pointer - for (unsigned int i = 0; i < pcScene->mNumMeshes;++i) - pcScene->mMeshes[i]->mColors[2] = NULL; + // Reset the third color set to nullptr - we used this field to store a temporary pointer + for (unsigned int i = 0; i < pcScene->mNumMeshes; ++i) + pcScene->mMeshes[i]->mColors[2] = nullptr; // The root node should not have at least one child or the file is valid if (!pcScene->mRootNode->mNumChildren) { @@ -733,17 +711,17 @@ void ASEImporter::BuildNodes(std::vector& nodes) { } // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system - pcScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f, - 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f); + pcScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); } // ------------------------------------------------------------------------------------------------ // Convert the imported data to the internal verbose representation -void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh) { +void ASEImporter::BuildUniqueRepresentation(ASE::Mesh &mesh) { // allocate output storage std::vector mPositions; std::vector amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; - std::vector mVertexColors; + std::vector mVertexColors; std::vector mNormals; std::vector mBoneVertices; @@ -751,13 +729,13 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh) { mPositions.resize(iSize); // optional texture coordinates - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i) { - if (!mesh.amTexCoords[i].empty()) { + for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { + if (!mesh.amTexCoords[i].empty()) { amTexCoords[i].resize(iSize); } } // optional vertex colors - if (!mesh.mVertexColors.empty()) { + if (!mesh.mVertexColors.empty()) { mVertexColors.resize(iSize); } @@ -766,38 +744,37 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh) { mNormals.resize(iSize); } // bone vertices. There is no need to change the bone list - if (!mesh.mBoneVertices.empty()) { + if (!mesh.mBoneVertices.empty()) { mBoneVertices.resize(iSize); } // iterate through all faces in the mesh unsigned int iCurrent = 0, fi = 0; - for (std::vector::iterator i = mesh.mFaces.begin();i != mesh.mFaces.end();++i,++fi) { - for (unsigned int n = 0; n < 3;++n,++iCurrent) - { + for (std::vector::iterator i = mesh.mFaces.begin(); i != mesh.mFaces.end(); ++i, ++fi) { + for (unsigned int n = 0; n < 3; ++n, ++iCurrent) { mPositions[iCurrent] = mesh.mPositions[(*i).mIndices[n]]; // add texture coordinates - for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) { - if (mesh.amTexCoords[c].empty())break; + for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c) { + if (mesh.amTexCoords[c].empty()) break; amTexCoords[c][iCurrent] = mesh.amTexCoords[c][(*i).amUVIndices[c][n]]; } // add vertex colors - if (!mesh.mVertexColors.empty()) { + if (!mesh.mVertexColors.empty()) { mVertexColors[iCurrent] = mesh.mVertexColors[(*i).mColorIndices[n]]; } // add normal vectors if (!mesh.mNormals.empty()) { - mNormals[iCurrent] = mesh.mNormals[fi*3+n]; + mNormals[iCurrent] = mesh.mNormals[fi * 3 + n]; mNormals[iCurrent].Normalize(); } // handle bone vertices - if ((*i).mIndices[n] < mesh.mBoneVertices.size()) { + if ((*i).mIndices[n] < mesh.mBoneVertices.size()) { // (sometimes this will cause bone verts to be duplicated // however, I' quite sure Schrompf' JoinVerticesStep // will fix that again ...) - mBoneVertices[iCurrent] = mesh.mBoneVertices[(*i).mIndices[n]]; + mBoneVertices[iCurrent] = mesh.mBoneVertices[(*i).mIndices[n]]; } (*i).mIndices[n] = iCurrent; } @@ -808,31 +785,29 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh) { mesh.mPositions = mPositions; mesh.mVertexColors = mVertexColors; - for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) + for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c) mesh.amTexCoords[c] = amTexCoords[c]; } // ------------------------------------------------------------------------------------------------ // Copy a texture from the ASE structs to the output material -void CopyASETexture(aiMaterial& mat, ASE::Texture& texture, aiTextureType type) -{ +void CopyASETexture(aiMaterial &mat, ASE::Texture &texture, aiTextureType type) { // Setup the texture name aiString tex; - tex.Set( texture.mMapName); - mat.AddProperty( &tex, AI_MATKEY_TEXTURE(type,0)); + tex.Set(texture.mMapName); + mat.AddProperty(&tex, AI_MATKEY_TEXTURE(type, 0)); // Setup the texture blend factor if (is_not_qnan(texture.mTextureBlend)) - mat.AddProperty( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0)); + mat.AddProperty(&texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type, 0)); // Setup texture UV transformations - mat.AddProperty(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0)); + mat.AddProperty(&texture.mOffsetU, 5, AI_MATKEY_UVTRANSFORM(type, 0)); } // ------------------------------------------------------------------------------------------------ // Convert from ASE material to output material -void ASEImporter::ConvertMaterial(ASE::Material& mat) -{ +void ASEImporter::ConvertMaterial(ASE::Material &mat) { // LARGE TODO: Much code her is copied from 3DS ... join them maybe? // Allocate the output material @@ -845,135 +820,134 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat) mat.mAmbient.b += mParser->m_clrAmbient.b; aiString name; - name.Set( mat.mName); - mat.pcInstance->AddProperty( &name, AI_MATKEY_NAME); + name.Set(mat.mName); + mat.pcInstance->AddProperty(&name, AI_MATKEY_NAME); // material colors - mat.pcInstance->AddProperty( &mat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT); - mat.pcInstance->AddProperty( &mat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE); - mat.pcInstance->AddProperty( &mat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR); - mat.pcInstance->AddProperty( &mat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); + mat.pcInstance->AddProperty(&mat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT); + mat.pcInstance->AddProperty(&mat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE); + mat.pcInstance->AddProperty(&mat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR); + mat.pcInstance->AddProperty(&mat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); // shininess - if (0.0f != mat.mSpecularExponent && 0.0f != mat.mShininessStrength) - { - mat.pcInstance->AddProperty( &mat.mSpecularExponent, 1, AI_MATKEY_SHININESS); - mat.pcInstance->AddProperty( &mat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH); + if (0.0f != mat.mSpecularExponent && 0.0f != mat.mShininessStrength) { + mat.pcInstance->AddProperty(&mat.mSpecularExponent, 1, AI_MATKEY_SHININESS); + mat.pcInstance->AddProperty(&mat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH); } // If there is no shininess, we can disable phong lighting else if (D3DS::Discreet3DS::Metal == mat.mShading || - D3DS::Discreet3DS::Phong == mat.mShading || - D3DS::Discreet3DS::Blinn == mat.mShading) - { + D3DS::Discreet3DS::Phong == mat.mShading || + D3DS::Discreet3DS::Blinn == mat.mShading) { mat.mShading = D3DS::Discreet3DS::Gouraud; } // opacity - mat.pcInstance->AddProperty( &mat.mTransparency,1,AI_MATKEY_OPACITY); + mat.pcInstance->AddProperty(&mat.mTransparency, 1, AI_MATKEY_OPACITY); // Two sided rendering? - if (mat.mTwoSided) - { + if (mat.mTwoSided) { int i = 1; - mat.pcInstance->AddProperty(&i,1,AI_MATKEY_TWOSIDED); + mat.pcInstance->AddProperty(&i, 1, AI_MATKEY_TWOSIDED); } // shading mode aiShadingMode eShading = aiShadingMode_NoShading; - switch (mat.mShading) - { - case D3DS::Discreet3DS::Flat: - eShading = aiShadingMode_Flat; break; - case D3DS::Discreet3DS::Phong : - eShading = aiShadingMode_Phong; break; - case D3DS::Discreet3DS::Blinn : - eShading = aiShadingMode_Blinn; break; + switch (mat.mShading) { + case D3DS::Discreet3DS::Flat: + eShading = aiShadingMode_Flat; + break; + case D3DS::Discreet3DS::Phong: + eShading = aiShadingMode_Phong; + break; + case D3DS::Discreet3DS::Blinn: + eShading = aiShadingMode_Blinn; + break; - // I don't know what "Wire" shading should be, - // assume it is simple lambertian diffuse (L dot N) shading - case D3DS::Discreet3DS::Wire: - { - // set the wireframe flag - unsigned int iWire = 1; - mat.pcInstance->AddProperty( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME); - } - case D3DS::Discreet3DS::Gouraud: - eShading = aiShadingMode_Gouraud; break; - case D3DS::Discreet3DS::Metal : - eShading = aiShadingMode_CookTorrance; break; + // I don't know what "Wire" shading should be, + // assume it is simple lambertian diffuse (L dot N) shading + case D3DS::Discreet3DS::Wire: { + // set the wireframe flag + unsigned int iWire = 1; + mat.pcInstance->AddProperty((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME); } - mat.pcInstance->AddProperty( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL); + case D3DS::Discreet3DS::Gouraud: + eShading = aiShadingMode_Gouraud; + break; + case D3DS::Discreet3DS::Metal: + eShading = aiShadingMode_CookTorrance; + break; + } + mat.pcInstance->AddProperty((int *)&eShading, 1, AI_MATKEY_SHADING_MODEL); // DIFFUSE texture - if( mat.sTexDiffuse.mMapName.length() > 0) - CopyASETexture(*mat.pcInstance,mat.sTexDiffuse, aiTextureType_DIFFUSE); + if (mat.sTexDiffuse.mMapName.length() > 0) + CopyASETexture(*mat.pcInstance, mat.sTexDiffuse, aiTextureType_DIFFUSE); // SPECULAR texture - if( mat.sTexSpecular.mMapName.length() > 0) - CopyASETexture(*mat.pcInstance,mat.sTexSpecular, aiTextureType_SPECULAR); + if (mat.sTexSpecular.mMapName.length() > 0) + CopyASETexture(*mat.pcInstance, mat.sTexSpecular, aiTextureType_SPECULAR); // AMBIENT texture - if( mat.sTexAmbient.mMapName.length() > 0) - CopyASETexture(*mat.pcInstance,mat.sTexAmbient, aiTextureType_AMBIENT); + if (mat.sTexAmbient.mMapName.length() > 0) + CopyASETexture(*mat.pcInstance, mat.sTexAmbient, aiTextureType_AMBIENT); // OPACITY texture - if( mat.sTexOpacity.mMapName.length() > 0) - CopyASETexture(*mat.pcInstance,mat.sTexOpacity, aiTextureType_OPACITY); + if (mat.sTexOpacity.mMapName.length() > 0) + CopyASETexture(*mat.pcInstance, mat.sTexOpacity, aiTextureType_OPACITY); // EMISSIVE texture - if( mat.sTexEmissive.mMapName.length() > 0) - CopyASETexture(*mat.pcInstance,mat.sTexEmissive, aiTextureType_EMISSIVE); + if (mat.sTexEmissive.mMapName.length() > 0) + CopyASETexture(*mat.pcInstance, mat.sTexEmissive, aiTextureType_EMISSIVE); // BUMP texture - if( mat.sTexBump.mMapName.length() > 0) - CopyASETexture(*mat.pcInstance,mat.sTexBump, aiTextureType_HEIGHT); + if (mat.sTexBump.mMapName.length() > 0) + CopyASETexture(*mat.pcInstance, mat.sTexBump, aiTextureType_HEIGHT); // SHININESS texture - if( mat.sTexShininess.mMapName.length() > 0) - CopyASETexture(*mat.pcInstance,mat.sTexShininess, aiTextureType_SHININESS); + if (mat.sTexShininess.mMapName.length() > 0) + CopyASETexture(*mat.pcInstance, mat.sTexShininess, aiTextureType_SHININESS); // store the name of the material itself, too - if( mat.mName.length() > 0) { - aiString tex;tex.Set( mat.mName); - mat.pcInstance->AddProperty( &tex, AI_MATKEY_NAME); + if (mat.mName.length() > 0) { + aiString tex; + tex.Set(mat.mName); + mat.pcInstance->AddProperty(&tex, AI_MATKEY_NAME); } return; } // ------------------------------------------------------------------------------------------------ // Build output meshes -void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMeshes) -{ +void ASEImporter::ConvertMeshes(ASE::Mesh &mesh, std::vector &avOutMeshes) { // validate the material index of the mesh - if (mesh.iMaterialIndex >= mParser->m_vMaterials.size()) { - mesh.iMaterialIndex = (unsigned int)mParser->m_vMaterials.size()-1; + if (mesh.iMaterialIndex >= mParser->m_vMaterials.size()) { + mesh.iMaterialIndex = (unsigned int)mParser->m_vMaterials.size() - 1; ASSIMP_LOG_WARN("Material index is out of range"); } // If the material the mesh is assigned to is consisting of submeshes, split it if (!mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials.empty()) { - std::vector vSubMaterials = mParser-> - m_vMaterials[mesh.iMaterialIndex].avSubMaterials; + std::vector vSubMaterials = mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials; - std::vector* aiSplit = new std::vector[vSubMaterials.size()]; + std::vector *aiSplit = new std::vector[vSubMaterials.size()]; // build a list of all faces per sub-material - for (unsigned int i = 0; i < mesh.mFaces.size();++i) { + for (unsigned int i = 0; i < mesh.mFaces.size(); ++i) { // check range if (mesh.mFaces[i].iMaterial >= vSubMaterials.size()) { ASSIMP_LOG_WARN("Submaterial index is out of range"); // use the last material instead - aiSplit[vSubMaterials.size()-1].push_back(i); - } - else aiSplit[mesh.mFaces[i].iMaterial].push_back(i); + aiSplit[vSubMaterials.size() - 1].push_back(i); + } else + aiSplit[mesh.mFaces[i].iMaterial].push_back(i); } // now generate submeshes - for (unsigned int p = 0; p < vSubMaterials.size();++p) { - if (!aiSplit[p].empty()) { + for (unsigned int p = 0; p < vSubMaterials.size(); ++p) { + if (!aiSplit[p].empty()) { - aiMesh* p_pcOut = new aiMesh(); + aiMesh *p_pcOut = new aiMesh(); p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; // let the sub material index @@ -983,55 +957,55 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials[p].bNeed = true; // store the real index here ... color channel 3 - p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex; + p_pcOut->mColors[3] = (aiColor4D *)(uintptr_t)mesh.iMaterialIndex; // store a pointer to the mesh in color channel 2 - p_pcOut->mColors[2] = (aiColor4D*) &mesh; + p_pcOut->mColors[2] = (aiColor4D *)&mesh; avOutMeshes.push_back(p_pcOut); // convert vertices - p_pcOut->mNumVertices = (unsigned int)aiSplit[p].size()*3; + p_pcOut->mNumVertices = (unsigned int)aiSplit[p].size() * 3; p_pcOut->mNumFaces = (unsigned int)aiSplit[p].size(); // receive output vertex weights - std::vector > *avOutputBones = NULL; - if (!mesh.mBones.empty()) { - avOutputBones = new std::vector >[mesh.mBones.size()]; + std::vector> *avOutputBones = nullptr; + if (!mesh.mBones.empty()) { + avOutputBones = new std::vector>[mesh.mBones.size()]; } // allocate enough storage for faces p_pcOut->mFaces = new aiFace[p_pcOut->mNumFaces]; - unsigned int iBase = 0,iIndex; - if (p_pcOut->mNumVertices) { + unsigned int iBase = 0, iIndex; + if (p_pcOut->mNumVertices) { p_pcOut->mVertices = new aiVector3D[p_pcOut->mNumVertices]; - p_pcOut->mNormals = new aiVector3D[p_pcOut->mNumVertices]; - for (unsigned int q = 0; q < aiSplit[p].size();++q) { + p_pcOut->mNormals = new aiVector3D[p_pcOut->mNumVertices]; + for (unsigned int q = 0; q < aiSplit[p].size(); ++q) { iIndex = aiSplit[p][q]; p_pcOut->mFaces[q].mIndices = new unsigned int[3]; p_pcOut->mFaces[q].mNumIndices = 3; - for (unsigned int t = 0; t < 3;++t, ++iBase) { + for (unsigned int t = 0; t < 3; ++t, ++iBase) { const uint32_t iIndex2 = mesh.mFaces[iIndex].mIndices[t]; - p_pcOut->mVertices[iBase] = mesh.mPositions [iIndex2]; - p_pcOut->mNormals [iBase] = mesh.mNormals [iIndex2]; + p_pcOut->mVertices[iBase] = mesh.mPositions[iIndex2]; + p_pcOut->mNormals[iBase] = mesh.mNormals[iIndex2]; // convert bones, if existing if (!mesh.mBones.empty()) { ai_assert(avOutputBones); // check whether there is a vertex weight for this vertex index - if (iIndex2 < mesh.mBoneVertices.size()) { + if (iIndex2 < mesh.mBoneVertices.size()) { - for (std::vector >::const_iterator - blubb = mesh.mBoneVertices[iIndex2].mBoneWeights.begin(); - blubb != mesh.mBoneVertices[iIndex2].mBoneWeights.end();++blubb) { + for (std::vector>::const_iterator + blubb = mesh.mBoneVertices[iIndex2].mBoneWeights.begin(); + blubb != mesh.mBoneVertices[iIndex2].mBoneWeights.end(); ++blubb) { // NOTE: illegal cases have already been filtered out avOutputBones[(*blubb).first].push_back(std::pair( - iBase,(*blubb).second)); + iBase, (*blubb).second)); } } } @@ -1040,14 +1014,13 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh } } // convert texture coordinates (up to AI_MAX_NUMBER_OF_TEXTURECOORDS sets supported) - for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) { - if (!mesh.amTexCoords[c].empty()) - { + for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c) { + if (!mesh.amTexCoords[c].empty()) { p_pcOut->mTextureCoords[c] = new aiVector3D[p_pcOut->mNumVertices]; iBase = 0; - for (unsigned int q = 0; q < aiSplit[p].size();++q) { + for (unsigned int q = 0; q < aiSplit[p].size(); ++q) { iIndex = aiSplit[p][q]; - for (unsigned int t = 0; t < 3;++t) { + for (unsigned int t = 0; t < 3; ++t) { p_pcOut->mTextureCoords[c][iBase++] = mesh.amTexCoords[c][mesh.mFaces[iIndex].mIndices[t]]; } } @@ -1057,38 +1030,36 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh } // Convert vertex colors (only one set supported) - if (!mesh.mVertexColors.empty()){ + if (!mesh.mVertexColors.empty()) { p_pcOut->mColors[0] = new aiColor4D[p_pcOut->mNumVertices]; iBase = 0; - for (unsigned int q = 0; q < aiSplit[p].size();++q) { + for (unsigned int q = 0; q < aiSplit[p].size(); ++q) { iIndex = aiSplit[p][q]; - for (unsigned int t = 0; t < 3;++t) { + for (unsigned int t = 0; t < 3; ++t) { p_pcOut->mColors[0][iBase++] = mesh.mVertexColors[mesh.mFaces[iIndex].mIndices[t]]; } } } // Copy bones - if (!mesh.mBones.empty()) { + if (!mesh.mBones.empty()) { p_pcOut->mNumBones = 0; - for (unsigned int mrspock = 0; mrspock < mesh.mBones.size();++mrspock) - if (!avOutputBones[mrspock].empty())p_pcOut->mNumBones++; + for (unsigned int mrspock = 0; mrspock < mesh.mBones.size(); ++mrspock) + if (!avOutputBones[mrspock].empty()) p_pcOut->mNumBones++; - p_pcOut->mBones = new aiBone* [ p_pcOut->mNumBones ]; - aiBone** pcBone = p_pcOut->mBones; - for (unsigned int mrspock = 0; mrspock < mesh.mBones.size();++mrspock) - { - if (!avOutputBones[mrspock].empty()) { + p_pcOut->mBones = new aiBone *[p_pcOut->mNumBones]; + aiBone **pcBone = p_pcOut->mBones; + for (unsigned int mrspock = 0; mrspock < mesh.mBones.size(); ++mrspock) { + if (!avOutputBones[mrspock].empty()) { // we will need this bone. add it to the output mesh and // add all per-vertex weights - aiBone* pc = *pcBone = new aiBone(); + aiBone *pc = *pcBone = new aiBone(); pc->mName.Set(mesh.mBones[mrspock].mName); pc->mNumWeights = (unsigned int)avOutputBones[mrspock].size(); pc->mWeights = new aiVertexWeight[pc->mNumWeights]; - for (unsigned int captainkirk = 0; captainkirk < pc->mNumWeights;++captainkirk) - { - const std::pair& ref = avOutputBones[mrspock][captainkirk]; + for (unsigned int captainkirk = 0; captainkirk < pc->mNumWeights; ++captainkirk) { + const std::pair &ref = avOutputBones[mrspock][captainkirk]; pc->mWeights[captainkirk].mVertexId = ref.first; pc->mWeights[captainkirk].mWeight = ref.second; } @@ -1102,15 +1073,13 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh } // delete storage delete[] aiSplit; - } - else - { + } else { // Otherwise we can simply copy the data to one output mesh // This codepath needs less memory and uses fast memcpy()s // to do the actual copying. So I think it is worth the // effort here. - aiMesh* p_pcOut = new aiMesh(); + aiMesh *p_pcOut = new aiMesh(); p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; // set an empty sub material index @@ -1118,10 +1087,10 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh mParser->m_vMaterials[mesh.iMaterialIndex].bNeed = true; // store the real index here ... in color channel 3 - p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex; + p_pcOut->mColors[3] = (aiColor4D *)(uintptr_t)mesh.iMaterialIndex; // store a pointer to the mesh in color channel 2 - p_pcOut->mColors[2] = (aiColor4D*) &mesh; + p_pcOut->mColors[2] = (aiColor4D *)&mesh; avOutMeshes.push_back(p_pcOut); // If the mesh hasn't faces or vertices, there are two cases @@ -1140,20 +1109,20 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh // copy vertices p_pcOut->mVertices = new aiVector3D[mesh.mPositions.size()]; - memcpy(p_pcOut->mVertices,&mesh.mPositions[0], - mesh.mPositions.size() * sizeof(aiVector3D)); + memcpy(p_pcOut->mVertices, &mesh.mPositions[0], + mesh.mPositions.size() * sizeof(aiVector3D)); // copy normals p_pcOut->mNormals = new aiVector3D[mesh.mNormals.size()]; - memcpy(p_pcOut->mNormals,&mesh.mNormals[0], - mesh.mNormals.size() * sizeof(aiVector3D)); + memcpy(p_pcOut->mNormals, &mesh.mNormals[0], + mesh.mNormals.size() * sizeof(aiVector3D)); // copy texture coordinates - for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) { - if (!mesh.amTexCoords[c].empty()) { + for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c) { + if (!mesh.amTexCoords[c].empty()) { p_pcOut->mTextureCoords[c] = new aiVector3D[mesh.amTexCoords[c].size()]; - memcpy(p_pcOut->mTextureCoords[c],&mesh.amTexCoords[c][0], - mesh.amTexCoords[c].size() * sizeof(aiVector3D)); + memcpy(p_pcOut->mTextureCoords[c], &mesh.amTexCoords[c][0], + mesh.amTexCoords[c].size() * sizeof(aiVector3D)); // setup the number of valid vertex components p_pcOut->mNumUVComponents[c] = mesh.mNumUVComponents[c]; @@ -1161,14 +1130,14 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh } // copy vertex colors - if (!mesh.mVertexColors.empty()) { + if (!mesh.mVertexColors.empty()) { p_pcOut->mColors[0] = new aiColor4D[mesh.mVertexColors.size()]; - memcpy(p_pcOut->mColors[0],&mesh.mVertexColors[0], - mesh.mVertexColors.size() * sizeof(aiColor4D)); + memcpy(p_pcOut->mColors[0], &mesh.mVertexColors[0], + mesh.mVertexColors.size() * sizeof(aiColor4D)); } // copy faces - for (unsigned int iFace = 0; iFace < p_pcOut->mNumFaces;++iFace) { + for (unsigned int iFace = 0; iFace < p_pcOut->mNumFaces; ++iFace) { p_pcOut->mFaces[iFace].mNumIndices = 3; p_pcOut->mFaces[iFace].mIndices = new unsigned int[3]; @@ -1179,18 +1148,17 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh } // copy vertex bones - if (!mesh.mBones.empty() && !mesh.mBoneVertices.empty()) { - std::vector > avBonesOut( mesh.mBones.size() ); + if (!mesh.mBones.empty() && !mesh.mBoneVertices.empty()) { + std::vector> avBonesOut(mesh.mBones.size()); // find all vertex weights for this bone unsigned int quak = 0; - for (std::vector::const_iterator harrypotter = mesh.mBoneVertices.begin(); - harrypotter != mesh.mBoneVertices.end();++harrypotter,++quak) { + for (std::vector::const_iterator harrypotter = mesh.mBoneVertices.begin(); + harrypotter != mesh.mBoneVertices.end(); ++harrypotter, ++quak) { - for (std::vector >::const_iterator - ronaldweasley = (*harrypotter).mBoneWeights.begin(); - ronaldweasley != (*harrypotter).mBoneWeights.end();++ronaldweasley) - { + for (std::vector>::const_iterator + ronaldweasley = (*harrypotter).mBoneWeights.begin(); + ronaldweasley != (*harrypotter).mBoneWeights.end(); ++ronaldweasley) { aiVertexWeight weight; weight.mVertexId = quak; weight.mWeight = (*ronaldweasley).second; @@ -1200,19 +1168,19 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh // now build a final bone list p_pcOut->mNumBones = 0; - for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size();++jfkennedy) - if (!avBonesOut[jfkennedy].empty())p_pcOut->mNumBones++; + for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size(); ++jfkennedy) + if (!avBonesOut[jfkennedy].empty()) p_pcOut->mNumBones++; - p_pcOut->mBones = new aiBone*[p_pcOut->mNumBones]; - aiBone** pcBone = p_pcOut->mBones; - for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size();++jfkennedy) { + p_pcOut->mBones = new aiBone *[p_pcOut->mNumBones]; + aiBone **pcBone = p_pcOut->mBones; + for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size(); ++jfkennedy) { if (!avBonesOut[jfkennedy].empty()) { - aiBone* pc = *pcBone = new aiBone(); + aiBone *pc = *pcBone = new aiBone(); pc->mName.Set(mesh.mBones[jfkennedy].mName); pc->mNumWeights = (unsigned int)avBonesOut[jfkennedy].size(); pc->mWeights = new aiVertexWeight[pc->mNumWeights]; - ::memcpy(pc->mWeights,&avBonesOut[jfkennedy][0], - sizeof(aiVertexWeight) * pc->mNumWeights); + ::memcpy(pc->mWeights, &avBonesOut[jfkennedy][0], + sizeof(aiVertexWeight) * pc->mNumWeights); ++pcBone; } } @@ -1222,23 +1190,20 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh // ------------------------------------------------------------------------------------------------ // Setup proper material indices and build output materials -void ASEImporter::BuildMaterialIndices() -{ - ai_assert(NULL != pcScene); +void ASEImporter::BuildMaterialIndices() { + ai_assert(nullptr != pcScene); // iterate through all materials and check whether we need them - for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat) - { - ASE::Material& mat = mParser->m_vMaterials[iMat]; - if (mat.bNeed) { + for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size(); ++iMat) { + ASE::Material &mat = mParser->m_vMaterials[iMat]; + if (mat.bNeed) { // Convert it to the aiMaterial layout ConvertMaterial(mat); ++pcScene->mNumMaterials; } - for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size();++iSubMat) - { - ASE::Material& submat = mat.avSubMaterials[iSubMat]; - if (submat.bNeed) { + for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size(); ++iSubMat) { + ASE::Material &submat = mat.avSubMaterials[iSubMat]; + if (submat.bNeed) { // Convert it to the aiMaterial layout ConvertMaterial(submat); ++pcScene->mNumMaterials; @@ -1247,15 +1212,14 @@ void ASEImporter::BuildMaterialIndices() } // allocate the output material array - pcScene->mMaterials = new aiMaterial*[pcScene->mNumMaterials]; - D3DS::Material** pcIntMaterials = new D3DS::Material*[pcScene->mNumMaterials]; + pcScene->mMaterials = new aiMaterial *[pcScene->mNumMaterials]; + D3DS::Material **pcIntMaterials = new D3DS::Material *[pcScene->mNumMaterials]; unsigned int iNum = 0; - for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat) { - ASE::Material& mat = mParser->m_vMaterials[iMat]; - if (mat.bNeed) - { - ai_assert(NULL != mat.pcInstance); + for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size(); ++iMat) { + ASE::Material &mat = mParser->m_vMaterials[iMat]; + if (mat.bNeed) { + ai_assert(nullptr != mat.pcInstance); pcScene->mMaterials[iNum] = mat.pcInstance; // Store the internal material, too @@ -1263,22 +1227,20 @@ void ASEImporter::BuildMaterialIndices() // Iterate through all meshes and search for one which is using // this top-level material index - for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes;++iMesh) - { - aiMesh* mesh = pcScene->mMeshes[iMesh]; + for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes; ++iMesh) { + aiMesh *mesh = pcScene->mMeshes[iMesh]; if (ASE::Face::DEFAULT_MATINDEX == mesh->mMaterialIndex && - iMat == (uintptr_t)mesh->mColors[3]) - { + iMat == (uintptr_t)mesh->mColors[3]) { mesh->mMaterialIndex = iNum; - mesh->mColors[3] = NULL; + mesh->mColors[3] = nullptr; } } iNum++; } - for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size();++iSubMat) { - ASE::Material& submat = mat.avSubMaterials[iSubMat]; - if (submat.bNeed) { - ai_assert(NULL != submat.pcInstance); + for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size(); ++iSubMat) { + ASE::Material &submat = mat.avSubMaterials[iSubMat]; + if (submat.bNeed) { + ai_assert(nullptr != submat.pcInstance); pcScene->mMaterials[iNum] = submat.pcInstance; // Store the internal material, too @@ -1286,12 +1248,12 @@ void ASEImporter::BuildMaterialIndices() // Iterate through all meshes and search for one which is using // this sub-level material index - for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes;++iMesh) { - aiMesh* mesh = pcScene->mMeshes[iMesh]; + for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes; ++iMesh) { + aiMesh *mesh = pcScene->mMeshes[iMesh]; if (iSubMat == mesh->mMaterialIndex && iMat == (uintptr_t)mesh->mColors[3]) { mesh->mMaterialIndex = iNum; - mesh->mColors[3] = NULL; + mesh->mColors[3] = nullptr; } } iNum++; @@ -1305,15 +1267,13 @@ void ASEImporter::BuildMaterialIndices() // ------------------------------------------------------------------------------------------------ // Generate normal vectors basing on smoothing groups -bool ASEImporter::GenerateNormals(ASE::Mesh& mesh) { +bool ASEImporter::GenerateNormals(ASE::Mesh &mesh) { - if (!mesh.mNormals.empty() && !configRecomputeNormals) - { + if (!mesh.mNormals.empty() && !configRecomputeNormals) { // Check whether there are only uninitialized normals. If there are // some, skip all normals from the file and compute them on our own - for (std::vector::const_iterator qq = mesh.mNormals.begin();qq != mesh.mNormals.end();++qq) { - if ((*qq).x || (*qq).y || (*qq).z) - { + for (std::vector::const_iterator qq = mesh.mNormals.begin(); qq != mesh.mNormals.end(); ++qq) { + if ((*qq).x || (*qq).y || (*qq).z) { return true; } } diff --git a/Engine/lib/assimp/code/ASE/ASELoader.h b/Engine/lib/assimp/code/AssetLib/ASE/ASELoader.h similarity index 96% rename from Engine/lib/assimp/code/ASE/ASELoader.h rename to Engine/lib/assimp/code/AssetLib/ASE/ASELoader.h index b497aa48b..cd9123556 100644 --- a/Engine/lib/assimp/code/ASE/ASELoader.h +++ b/Engine/lib/assimp/code/AssetLib/ASE/ASELoader.h @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -62,42 +62,37 @@ namespace Assimp { class ASEImporter : public BaseImporter { public: ASEImporter(); - ~ASEImporter(); + ~ASEImporter() override; // ------------------------------------------------------------------- /** Returns whether the class can handle the format of the given file. * See BaseImporter::CanRead() for details. */ bool CanRead( const std::string& pFile, IOSystem* pIOHandler, - bool checkSig) const; + bool checkSig) const override; protected: - // ------------------------------------------------------------------- /** Return importer meta information. * See #BaseImporter::GetInfo for the details */ - const aiImporterDesc* GetInfo () const; - + const aiImporterDesc* GetInfo () const override; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. * See BaseImporter::InternReadFile() for details */ void InternReadFile( const std::string& pFile, aiScene* pScene, - IOSystem* pIOHandler); - + IOSystem* pIOHandler) override; // ------------------------------------------------------------------- /** Called prior to ReadFile(). * The function is a request to the importer to update its configuration * basing on the Importer's configuration property list. */ - void SetupProperties(const Importer* pImp); - + void SetupProperties(const Importer* pImp) override; private: - // ------------------------------------------------------------------- /** Generate normal vectors basing on smoothing groups * (in some cases the normal are already contained in the file) @@ -106,7 +101,6 @@ private: */ bool GenerateNormals(ASE::Mesh& mesh); - // ------------------------------------------------------------------- /** Create valid vertex/normal/UV/color/face lists. * All elements are unique, faces have only one set of indices @@ -115,51 +109,43 @@ private: */ void BuildUniqueRepresentation(ASE::Mesh& mesh); - /** Create one-material-per-mesh meshes ;-) * \param mesh Mesh to work with * \param Receives the list of all created meshes */ void ConvertMeshes(ASE::Mesh& mesh, std::vector& avOut); - // ------------------------------------------------------------------- /** Convert a material to a aiMaterial object * \param mat Input material */ void ConvertMaterial(ASE::Material& mat); - // ------------------------------------------------------------------- /** Setup the final material indices for each mesh */ void BuildMaterialIndices(); - // ------------------------------------------------------------------- /** Build the node graph */ void BuildNodes(std::vector& nodes); - // ------------------------------------------------------------------- /** Build output cameras */ void BuildCameras(); - // ------------------------------------------------------------------- /** Build output lights */ void BuildLights(); - // ------------------------------------------------------------------- /** Build output animations */ void BuildAnimations(const std::vector& nodes); - // ------------------------------------------------------------------- /** Add sub nodes to a node * \param pcParent parent node to be filled @@ -183,7 +169,6 @@ private: void GenerateDefaultMaterial(); protected: - /** Parser instance */ ASE::Parser* mParser; diff --git a/Engine/lib/assimp/code/ASE/ASEParser.cpp b/Engine/lib/assimp/code/AssetLib/ASE/ASEParser.cpp similarity index 58% rename from Engine/lib/assimp/code/ASE/ASEParser.cpp rename to Engine/lib/assimp/code/AssetLib/ASE/ASEParser.cpp index 913e7b118..14eb720f4 100644 --- a/Engine/lib/assimp/code/ASE/ASEParser.cpp +++ b/Engine/lib/assimp/code/AssetLib/ASE/ASEParser.cpp @@ -3,9 +3,7 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -49,8 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER // internal headers -#include "PostProcessing/TextureTransform.h" #include "ASELoader.h" +#include "PostProcessing/TextureTransform.h" #include #include @@ -67,26 +65,23 @@ using namespace Assimp::ASE; // ------------------------------------------------------------------------------------------------ // Handle a "top-level" section in the file. EOF is no error in this case. -#define AI_ASE_HANDLE_TOP_LEVEL_SECTION() \ - else if ('{' == *filePtr)iDepth++; \ - else if ('}' == *filePtr) \ - { \ - if (0 == --iDepth) \ - { \ - ++filePtr; \ - SkipToNextToken(); \ - return; \ - } \ - } \ - else if ('\0' == *filePtr) \ - { \ - return; \ - } \ - if(IsLineEnd(*filePtr) && !bLastWasEndLine) \ - { \ - ++iLineNumber; \ - bLastWasEndLine = true; \ - } else bLastWasEndLine = false; \ +#define AI_ASE_HANDLE_TOP_LEVEL_SECTION() \ + else if ('{' == *filePtr) iDepth++; \ + else if ('}' == *filePtr) { \ + if (0 == --iDepth) { \ + ++filePtr; \ + SkipToNextToken(); \ + return; \ + } \ + } \ + else if ('\0' == *filePtr) { \ + return; \ + } \ + if (IsLineEnd(*filePtr) && !bLastWasEndLine) { \ + ++iLineNumber; \ + bLastWasEndLine = true; \ + } else \ + bLastWasEndLine = false; \ ++filePtr; // ------------------------------------------------------------------------------------------------ @@ -94,59 +89,55 @@ using namespace Assimp::ASE; // @param level "Depth" of the section // @param msg Full name of the section (including the asterisk) -#define AI_ASE_HANDLE_SECTION(level, msg) \ - if ('{' == *filePtr)iDepth++; \ - else if ('}' == *filePtr) \ - { \ - if (0 == --iDepth) \ - { \ - ++filePtr; \ - SkipToNextToken(); \ - return; \ - } \ - } \ - else if ('\0' == *filePtr) \ - { \ +#define AI_ASE_HANDLE_SECTION(level, msg) \ + if ('{' == *filePtr) \ + iDepth++; \ + else if ('}' == *filePtr) { \ + if (0 == --iDepth) { \ + ++filePtr; \ + SkipToNextToken(); \ + return; \ + } \ + } else if ('\0' == *filePtr) { \ LogError("Encountered unexpected EOL while parsing a " msg \ - " chunk (Level " level ")"); \ - } \ - if(IsLineEnd(*filePtr) && !bLastWasEndLine) \ - { \ - ++iLineNumber; \ - bLastWasEndLine = true; \ - } else bLastWasEndLine = false; \ + " chunk (Level " level ")"); \ + } \ + if (IsLineEnd(*filePtr) && !bLastWasEndLine) { \ + ++iLineNumber; \ + bLastWasEndLine = true; \ + } else \ + bLastWasEndLine = false; \ ++filePtr; // ------------------------------------------------------------------------------------------------ -Parser::Parser (const char* szFile, unsigned int fileFormatDefault) -{ - ai_assert(NULL != szFile); +Parser::Parser(const char *szFile, unsigned int fileFormatDefault) { + ai_assert(nullptr != szFile); + filePtr = szFile; iFileFormat = fileFormatDefault; // make sure that the color values are invalid m_clrBackground.r = get_qnan(); - m_clrAmbient.r = get_qnan(); + m_clrAmbient.r = get_qnan(); // setup some default values iLineNumber = 0; iFirstFrame = 0; iLastFrame = 0; - iFrameSpeed = 30; // use 30 as default value for this property - iTicksPerFrame = 1; // use 1 as default value for this property + iFrameSpeed = 30; // use 30 as default value for this property + iTicksPerFrame = 1; // use 1 as default value for this property bLastWasEndLine = false; // need to handle \r\n seqs due to binary file mapping } // ------------------------------------------------------------------------------------------------ -void Parser::LogWarning(const char* szWarn) -{ - ai_assert(NULL != szWarn); +void Parser::LogWarning(const char *szWarn) { + ai_assert(nullptr != szWarn); - char szTemp[1024]; + char szTemp[2048]; #if _MSC_VER >= 1400 - sprintf_s(szTemp, "Line %u: %s",iLineNumber,szWarn); + sprintf_s(szTemp, "Line %u: %s", iLineNumber, szWarn); #else - ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn); + ai_snprintf(szTemp, sizeof(szTemp), "Line %u: %s", iLineNumber, szWarn); #endif // output the warning to the logger ... @@ -154,15 +145,14 @@ void Parser::LogWarning(const char* szWarn) } // ------------------------------------------------------------------------------------------------ -void Parser::LogInfo(const char* szWarn) -{ - ai_assert(NULL != szWarn); +void Parser::LogInfo(const char *szWarn) { + ai_assert(nullptr != szWarn); char szTemp[1024]; #if _MSC_VER >= 1400 - sprintf_s(szTemp,"Line %u: %s",iLineNumber,szWarn); + sprintf_s(szTemp, "Line %u: %s", iLineNumber, szWarn); #else - ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn); + ai_snprintf(szTemp, 1024, "Line %u: %s", iLineNumber, szWarn); #endif // output the information to the logger ... @@ -170,15 +160,14 @@ void Parser::LogInfo(const char* szWarn) } // ------------------------------------------------------------------------------------------------ -AI_WONT_RETURN void Parser::LogError(const char* szWarn) -{ - ai_assert(NULL != szWarn); +AI_WONT_RETURN void Parser::LogError(const char *szWarn) { + ai_assert(nullptr != szWarn); char szTemp[1024]; #if _MSC_VER >= 1400 - sprintf_s(szTemp,"Line %u: %s",iLineNumber,szWarn); + sprintf_s(szTemp, "Line %u: %s", iLineNumber, szWarn); #else - ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn); + ai_snprintf(szTemp, 1024, "Line %u: %s", iLineNumber, szWarn); #endif // throw an exception @@ -186,76 +175,60 @@ AI_WONT_RETURN void Parser::LogError(const char* szWarn) } // ------------------------------------------------------------------------------------------------ -bool Parser::SkipToNextToken() -{ - while (true) - { +bool Parser::SkipToNextToken() { + while (true) { char me = *filePtr; // increase the line number counter if necessary - if (IsLineEnd(me) && !bLastWasEndLine) - { + if (IsLineEnd(me) && !bLastWasEndLine) { ++iLineNumber; bLastWasEndLine = true; - } - else bLastWasEndLine = false; - if ('*' == me || '}' == me || '{' == me)return true; - if ('\0' == me)return false; + } else + bLastWasEndLine = false; + if ('*' == me || '}' == me || '{' == me) return true; + if ('\0' == me) return false; ++filePtr; } } // ------------------------------------------------------------------------------------------------ -bool Parser::SkipSection() -{ +bool Parser::SkipSection() { // must handle subsections ... int iCnt = 0; - while (true) - { - if ('}' == *filePtr) - { + while (true) { + if ('}' == *filePtr) { --iCnt; - if (0 == iCnt) - { + if (0 == iCnt) { // go to the next valid token ... ++filePtr; SkipToNextToken(); return true; } - } - else if ('{' == *filePtr) - { + } else if ('{' == *filePtr) { ++iCnt; - } - else if ('\0' == *filePtr) - { + } else if ('\0' == *filePtr) { LogWarning("Unable to parse block: Unexpected EOF, closing bracket \'}\' was expected [#1]"); return false; - } - else if(IsLineEnd(*filePtr))++iLineNumber; + } else if (IsLineEnd(*filePtr)) + ++iLineNumber; ++filePtr; } } // ------------------------------------------------------------------------------------------------ -void Parser::Parse() -{ +void Parser::Parse() { AI_ASE_PARSER_INIT(); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Version should be 200. Validate this ... - if (TokenMatch(filePtr,"3DSMAX_ASCIIEXPORT",18)) - { + if (TokenMatch(filePtr, "3DSMAX_ASCIIEXPORT", 18)) { unsigned int fmt; ParseLV4MeshLong(fmt); - if (fmt > 200) - { + if (fmt > 200) { LogWarning("Unknown file format version: *3DSMAX_ASCIIEXPORT should \ be <= 200"); } @@ -266,32 +239,29 @@ void Parser::Parse() // at the file extension (ASE, ASK, ASC) // ************************************************************* - if ( fmt ) { + if (fmt) { iFileFormat = fmt; } continue; } // main scene information - if (TokenMatch(filePtr,"SCENE",5)) - { + if (TokenMatch(filePtr, "SCENE", 5)) { ParseLV1SceneBlock(); continue; } // "group" - no implementation yet, in facte // we're just ignoring them for the moment - if (TokenMatch(filePtr,"GROUP",5)) - { + if (TokenMatch(filePtr, "GROUP", 5)) { Parse(); continue; } // material list - if (TokenMatch(filePtr,"MATERIAL_LIST",13)) - { + if (TokenMatch(filePtr, "MATERIAL_LIST", 13)) { ParseLV1MaterialListBlock(); continue; } // geometric object (mesh) - if (TokenMatch(filePtr,"GEOMOBJECT",10)) + if (TokenMatch(filePtr, "GEOMOBJECT", 10)) { m_vMeshes.push_back(Mesh("UNNAMED")); @@ -299,7 +269,7 @@ void Parser::Parse() continue; } // helper object = dummy in the hierarchy - if (TokenMatch(filePtr,"HELPEROBJECT",12)) + if (TokenMatch(filePtr, "HELPEROBJECT", 12)) { m_vDummies.push_back(Dummy()); @@ -307,7 +277,7 @@ void Parser::Parse() continue; } // light object - if (TokenMatch(filePtr,"LIGHTOBJECT",11)) + if (TokenMatch(filePtr, "LIGHTOBJECT", 11)) { m_vLights.push_back(Light("UNNAMED")); @@ -315,23 +285,20 @@ void Parser::Parse() continue; } // camera object - if (TokenMatch(filePtr,"CAMERAOBJECT",12)) - { + if (TokenMatch(filePtr, "CAMERAOBJECT", 12)) { m_vCameras.push_back(Camera("UNNAMED")); ParseLV1ObjectBlock(m_vCameras.back()); continue; } // comment - print it on the console - if (TokenMatch(filePtr,"COMMENT",7)) - { + if (TokenMatch(filePtr, "COMMENT", 7)) { std::string out = ""; - ParseString(out,"*COMMENT"); + ParseString(out, "*COMMENT"); LogInfo(("Comment: " + out).c_str()); continue; } // ASC bone weights - if (AI_ASE_IS_OLD_FILE_FORMAT() && TokenMatch(filePtr,"MESH_SOFTSKINVERTS",18)) - { + if (AI_ASE_IS_OLD_FILE_FORMAT() && TokenMatch(filePtr, "MESH_SOFTSKINVERTS", 18)) { ParseLV1SoftSkinBlock(); } } @@ -341,8 +308,7 @@ void Parser::Parse() } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV1SoftSkinBlock() -{ +void Parser::ParseLV1SoftSkinBlock() { // TODO: fix line counting here // ************************************************************** @@ -364,80 +330,77 @@ void Parser::ParseLV1SoftSkinBlock() FORMAT END */ // ************************************************************** - while (true) - { - if (*filePtr == '}' ) {++filePtr;return;} - else if (*filePtr == '\0') return; - else if (*filePtr == '{' ) ++filePtr; + while (true) { + if (*filePtr == '}') { + ++filePtr; + return; + } else if (*filePtr == '\0') + return; + else if (*filePtr == '{') + ++filePtr; else // if (!IsSpace(*filePtr) && !IsLineEnd(*filePtr)) { - ASE::Mesh* curMesh = NULL; - unsigned int numVerts = 0; + ASE::Mesh *curMesh = nullptr; + unsigned int numVerts = 0; - const char* sz = filePtr; - while (!IsSpaceOrNewLine(*filePtr))++filePtr; + const char *sz = filePtr; + while (!IsSpaceOrNewLine(*filePtr)) + ++filePtr; - const unsigned int diff = (unsigned int)(filePtr-sz); - if (diff) - { - std::string name = std::string(sz,diff); + const unsigned int diff = (unsigned int)(filePtr - sz); + if (diff) { + std::string name = std::string(sz, diff); for (std::vector::iterator it = m_vMeshes.begin(); - it != m_vMeshes.end(); ++it) - { - if ((*it).mName == name) - { - curMesh = & (*it); + it != m_vMeshes.end(); ++it) { + if ((*it).mName == name) { + curMesh = &(*it); break; } } - if (!curMesh) - { + if (!curMesh) { LogWarning("Encountered unknown mesh in *MESH_SOFTSKINVERTS section"); // Skip the mesh data - until we find a new mesh // or the end of the *MESH_SOFTSKINVERTS section - while (true) - { + while (true) { SkipSpacesAndLineEnd(&filePtr); - if (*filePtr == '}') - {++filePtr;return;} - else if (!IsNumeric(*filePtr)) + if (*filePtr == '}') { + ++filePtr; + return; + } else if (!IsNumeric(*filePtr)) break; SkipLine(&filePtr); } - } - else - { + } else { SkipSpacesAndLineEnd(&filePtr); ParseLV4MeshLong(numVerts); // Reserve enough storage curMesh->mBoneVertices.reserve(numVerts); - for (unsigned int i = 0; i < numVerts;++i) - { + for (unsigned int i = 0; i < numVerts; ++i) { SkipSpacesAndLineEnd(&filePtr); unsigned int numWeights; ParseLV4MeshLong(numWeights); curMesh->mBoneVertices.push_back(ASE::BoneVertex()); - ASE::BoneVertex& vert = curMesh->mBoneVertices.back(); + ASE::BoneVertex &vert = curMesh->mBoneVertices.back(); // Reserve enough storage vert.mBoneWeights.reserve(numWeights); std::string bone; - for (unsigned int w = 0; w < numWeights;++w) { + for (unsigned int w = 0; w < numWeights; ++w) { bone.clear(); - ParseString(bone,"*MESH_SOFTSKINVERTS.Bone"); + ParseString(bone, "*MESH_SOFTSKINVERTS.Bone"); // Find the bone in the mesh's list - std::pair me; + std::pair me; me.first = -1; - for (unsigned int n = 0; n < curMesh->mBones.size();++n) { + for (unsigned int n = 0; n < curMesh->mBones.size(); ++n) { if (curMesh->mBones[n].mName == bone) { me.first = n; break; @@ -445,10 +408,10 @@ void Parser::ParseLV1SoftSkinBlock() } if (-1 == me.first) { // We don't have this bone yet, so add it to the list - me.first = static_cast( curMesh->mBones.size() ); - curMesh->mBones.push_back( ASE::Bone( bone ) ); + me.first = static_cast(curMesh->mBones.size()); + curMesh->mBones.push_back(ASE::Bone(bone)); } - ParseLV4MeshFloat( me.second ); + ParseLV4MeshFloat(me.second); // Add the new bone weight to list vert.mBoneWeights.push_back(me); @@ -463,45 +426,38 @@ void Parser::ParseLV1SoftSkinBlock() } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV1SceneBlock() -{ +void Parser::ParseLV1SceneBlock() { AI_ASE_PARSER_INIT(); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; - if (TokenMatch(filePtr,"SCENE_BACKGROUND_STATIC",23)) + if (TokenMatch(filePtr, "SCENE_BACKGROUND_STATIC", 23)) { // parse a color triple and assume it is really the bg color - ParseLV4MeshFloatTriple( &m_clrBackground.r ); + ParseLV4MeshFloatTriple(&m_clrBackground.r); continue; } - if (TokenMatch(filePtr,"SCENE_AMBIENT_STATIC",20)) + if (TokenMatch(filePtr, "SCENE_AMBIENT_STATIC", 20)) { // parse a color triple and assume it is really the bg color - ParseLV4MeshFloatTriple( &m_clrAmbient.r ); + ParseLV4MeshFloatTriple(&m_clrAmbient.r); continue; } - if (TokenMatch(filePtr,"SCENE_FIRSTFRAME",16)) - { + if (TokenMatch(filePtr, "SCENE_FIRSTFRAME", 16)) { ParseLV4MeshLong(iFirstFrame); continue; } - if (TokenMatch(filePtr,"SCENE_LASTFRAME",15)) - { + if (TokenMatch(filePtr, "SCENE_LASTFRAME", 15)) { ParseLV4MeshLong(iLastFrame); continue; } - if (TokenMatch(filePtr,"SCENE_FRAMESPEED",16)) - { + if (TokenMatch(filePtr, "SCENE_FRAMESPEED", 16)) { ParseLV4MeshLong(iFrameSpeed); continue; } - if (TokenMatch(filePtr,"SCENE_TICKSPERFRAME",19)) - { + if (TokenMatch(filePtr, "SCENE_TICKSPERFRAME", 19)) { ParseLV4MeshLong(iTicksPerFrame); continue; } @@ -511,103 +467,87 @@ void Parser::ParseLV1SceneBlock() } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV1MaterialListBlock() -{ +void Parser::ParseLV1MaterialListBlock() { AI_ASE_PARSER_INIT(); unsigned int iMaterialCount = 0; unsigned int iOldMaterialCount = (unsigned int)m_vMaterials.size(); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; - if (TokenMatch(filePtr,"MATERIAL_COUNT",14)) - { + if (TokenMatch(filePtr, "MATERIAL_COUNT", 14)) { ParseLV4MeshLong(iMaterialCount); // now allocate enough storage to hold all materials - m_vMaterials.resize(iOldMaterialCount+iMaterialCount, Material("INVALID")); + m_vMaterials.resize(iOldMaterialCount + iMaterialCount, Material("INVALID")); continue; } - if (TokenMatch(filePtr,"MATERIAL",8)) - { + if (TokenMatch(filePtr, "MATERIAL", 8)) { unsigned int iIndex = 0; ParseLV4MeshLong(iIndex); - if (iIndex >= iMaterialCount) - { + if (iIndex >= iMaterialCount) { LogWarning("Out of range: material index is too large"); - iIndex = iMaterialCount-1; + iIndex = iMaterialCount - 1; + return; } // get a reference to the material - Material& sMat = m_vMaterials[iIndex+iOldMaterialCount]; + Material &sMat = m_vMaterials[iIndex + iOldMaterialCount]; // parse the material block ParseLV2MaterialBlock(sMat); continue; } + if( iDepth == 1 ){ + // CRUDE HACK: support missing brace after "Ascii Scene Exporter v2.51" + LogWarning("Missing closing brace in material list"); + --filePtr; + return; + } } AI_ASE_HANDLE_TOP_LEVEL_SECTION(); } } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV2MaterialBlock(ASE::Material& mat) -{ +void Parser::ParseLV2MaterialBlock(ASE::Material &mat) { AI_ASE_PARSER_INIT(); unsigned int iNumSubMaterials = 0; - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; - if (TokenMatch(filePtr,"MATERIAL_NAME",13)) - { - if (!ParseString(mat.mName,"*MATERIAL_NAME")) + if (TokenMatch(filePtr, "MATERIAL_NAME", 13)) { + if (!ParseString(mat.mName, "*MATERIAL_NAME")) SkipToNextToken(); continue; } // ambient material color - if (TokenMatch(filePtr,"MATERIAL_AMBIENT",16)) - { + if (TokenMatch(filePtr, "MATERIAL_AMBIENT", 16)) { ParseLV4MeshFloatTriple(&mat.mAmbient.r); continue; } // diffuse material color - if (TokenMatch(filePtr,"MATERIAL_DIFFUSE",16) ) - { + if (TokenMatch(filePtr, "MATERIAL_DIFFUSE", 16)) { ParseLV4MeshFloatTriple(&mat.mDiffuse.r); continue; } // specular material color - if (TokenMatch(filePtr,"MATERIAL_SPECULAR",17)) - { + if (TokenMatch(filePtr, "MATERIAL_SPECULAR", 17)) { ParseLV4MeshFloatTriple(&mat.mSpecular.r); continue; } // material shading type - if (TokenMatch(filePtr,"MATERIAL_SHADING",16)) - { - if (TokenMatch(filePtr,"Blinn",5)) - { + if (TokenMatch(filePtr, "MATERIAL_SHADING", 16)) { + if (TokenMatch(filePtr, "Blinn", 5)) { mat.mShading = Discreet3DS::Blinn; - } - else if (TokenMatch(filePtr,"Phong",5)) - { + } else if (TokenMatch(filePtr, "Phong", 5)) { mat.mShading = Discreet3DS::Phong; - } - else if (TokenMatch(filePtr,"Flat",4)) - { + } else if (TokenMatch(filePtr, "Flat", 4)) { mat.mShading = Discreet3DS::Flat; - } - else if (TokenMatch(filePtr,"Wire",4)) - { + } else if (TokenMatch(filePtr, "Wire", 4)) { mat.mShading = Discreet3DS::Wire; - } - else - { + } else { // assume gouraud shading mat.mShading = Discreet3DS::Gouraud; SkipToNextToken(); @@ -615,15 +555,13 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) continue; } // material transparency - if (TokenMatch(filePtr,"MATERIAL_TRANSPARENCY",21)) - { + if (TokenMatch(filePtr, "MATERIAL_TRANSPARENCY", 21)) { ParseLV4MeshFloat(mat.mTransparency); - mat.mTransparency = ai_real( 1.0 ) - mat.mTransparency; + mat.mTransparency = ai_real(1.0) - mat.mTransparency; continue; } // material self illumination - if (TokenMatch(filePtr,"MATERIAL_SELFILLUM",18)) - { + if (TokenMatch(filePtr, "MATERIAL_SELFILLUM", 18)) { ai_real f = 0.0; ParseLV4MeshFloat(f); @@ -633,108 +571,94 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) continue; } // material shininess - if (TokenMatch(filePtr,"MATERIAL_SHINE",14) ) - { + if (TokenMatch(filePtr, "MATERIAL_SHINE", 14)) { ParseLV4MeshFloat(mat.mSpecularExponent); mat.mSpecularExponent *= 15; continue; } // two-sided material - if (TokenMatch(filePtr,"MATERIAL_TWOSIDED",17) ) - { + if (TokenMatch(filePtr, "MATERIAL_TWOSIDED", 17)) { mat.mTwoSided = true; continue; } // material shininess strength - if (TokenMatch(filePtr,"MATERIAL_SHINESTRENGTH",22)) - { + if (TokenMatch(filePtr, "MATERIAL_SHINESTRENGTH", 22)) { ParseLV4MeshFloat(mat.mShininessStrength); continue; } // diffuse color map - if (TokenMatch(filePtr,"MAP_DIFFUSE",11)) - { + if (TokenMatch(filePtr, "MAP_DIFFUSE", 11)) { // parse the texture block ParseLV3MapBlock(mat.sTexDiffuse); continue; } // ambient color map - if (TokenMatch(filePtr,"MAP_AMBIENT",11)) - { + if (TokenMatch(filePtr, "MAP_AMBIENT", 11)) { // parse the texture block ParseLV3MapBlock(mat.sTexAmbient); continue; } // specular color map - if (TokenMatch(filePtr,"MAP_SPECULAR",12)) - { + if (TokenMatch(filePtr, "MAP_SPECULAR", 12)) { // parse the texture block ParseLV3MapBlock(mat.sTexSpecular); continue; } // opacity map - if (TokenMatch(filePtr,"MAP_OPACITY",11)) - { + if (TokenMatch(filePtr, "MAP_OPACITY", 11)) { // parse the texture block ParseLV3MapBlock(mat.sTexOpacity); continue; } // emissive map - if (TokenMatch(filePtr,"MAP_SELFILLUM",13)) - { + if (TokenMatch(filePtr, "MAP_SELFILLUM", 13)) { // parse the texture block ParseLV3MapBlock(mat.sTexEmissive); continue; } // bump map - if (TokenMatch(filePtr,"MAP_BUMP",8)) - { + if (TokenMatch(filePtr, "MAP_BUMP", 8)) { // parse the texture block ParseLV3MapBlock(mat.sTexBump); } // specular/shininess map - if (TokenMatch(filePtr,"MAP_SHINESTRENGTH",17)) - { + if (TokenMatch(filePtr, "MAP_SHINESTRENGTH", 17)) { // parse the texture block ParseLV3MapBlock(mat.sTexShininess); continue; } // number of submaterials - if (TokenMatch(filePtr,"NUMSUBMTLS",10)) - { + if (TokenMatch(filePtr, "NUMSUBMTLS", 10)) { ParseLV4MeshLong(iNumSubMaterials); // allocate enough storage mat.avSubMaterials.resize(iNumSubMaterials, Material("INVALID SUBMATERIAL")); } // submaterial chunks - if (TokenMatch(filePtr,"SUBMATERIAL",11)) - { + if (TokenMatch(filePtr, "SUBMATERIAL", 11)) { unsigned int iIndex = 0; ParseLV4MeshLong(iIndex); - if (iIndex >= iNumSubMaterials) - { + if (iIndex >= iNumSubMaterials) { LogWarning("Out of range: submaterial index is too large"); - iIndex = iNumSubMaterials-1; + iIndex = iNumSubMaterials - 1; } // get a reference to the material - Material& sMat = mat.avSubMaterials[iIndex]; + Material &sMat = mat.avSubMaterials[iIndex]; // parse the material block ParseLV2MaterialBlock(sMat); continue; } } - AI_ASE_HANDLE_SECTION("2","*MATERIAL"); + AI_ASE_HANDLE_SECTION("2", "*MATERIAL"); } } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV3MapBlock(Texture& map) -{ +void Parser::ParseLV3MapBlock(Texture &map) { AI_ASE_PARSER_INIT(); // *********************************************************** @@ -744,233 +668,186 @@ void Parser::ParseLV3MapBlock(Texture& map) // *********************************************************** bool parsePath = true; std::string temp; - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // type of map - if (TokenMatch(filePtr,"MAP_CLASS" ,9)) - { + if (TokenMatch(filePtr, "MAP_CLASS", 9)) { temp.clear(); - if(!ParseString(temp,"*MAP_CLASS")) + if (!ParseString(temp, "*MAP_CLASS")) SkipToNextToken(); - if (temp != "Bitmap" && temp != "Normal Bump") - { - ASSIMP_LOG_WARN_F("ASE: Skipping unknown map type: ", temp); + if (temp != "Bitmap" && temp != "Normal Bump") { + ASSIMP_LOG_WARN("ASE: Skipping unknown map type: ", temp); parsePath = false; } continue; } // path to the texture - if (parsePath && TokenMatch(filePtr,"BITMAP" ,6)) - { - if(!ParseString(map.mMapName,"*BITMAP")) + if (parsePath && TokenMatch(filePtr, "BITMAP", 6)) { + if (!ParseString(map.mMapName, "*BITMAP")) SkipToNextToken(); - if (map.mMapName == "None") - { + if (map.mMapName == "None") { // Files with 'None' as map name are produced by // an Maja to ASE exporter which name I forgot .. ASSIMP_LOG_WARN("ASE: Skipping invalid map entry"); - map.mMapName = ""; + map.mMapName = std::string(); } continue; } // offset on the u axis - if (TokenMatch(filePtr,"UVW_U_OFFSET" ,12)) - { + if (TokenMatch(filePtr, "UVW_U_OFFSET", 12)) { ParseLV4MeshFloat(map.mOffsetU); continue; } // offset on the v axis - if (TokenMatch(filePtr,"UVW_V_OFFSET" ,12)) - { + if (TokenMatch(filePtr, "UVW_V_OFFSET", 12)) { ParseLV4MeshFloat(map.mOffsetV); continue; } // tiling on the u axis - if (TokenMatch(filePtr,"UVW_U_TILING" ,12)) - { + if (TokenMatch(filePtr, "UVW_U_TILING", 12)) { ParseLV4MeshFloat(map.mScaleU); continue; } // tiling on the v axis - if (TokenMatch(filePtr,"UVW_V_TILING" ,12)) - { + if (TokenMatch(filePtr, "UVW_V_TILING", 12)) { ParseLV4MeshFloat(map.mScaleV); continue; } // rotation around the z-axis - if (TokenMatch(filePtr,"UVW_ANGLE" ,9)) - { + if (TokenMatch(filePtr, "UVW_ANGLE", 9)) { ParseLV4MeshFloat(map.mRotation); continue; } // map blending factor - if (TokenMatch(filePtr,"MAP_AMOUNT" ,10)) - { + if (TokenMatch(filePtr, "MAP_AMOUNT", 10)) { ParseLV4MeshFloat(map.mTextureBlend); continue; } } - AI_ASE_HANDLE_SECTION("3","*MAP_XXXXXX"); + AI_ASE_HANDLE_SECTION("3", "*MAP_XXXXXX"); } return; } // ------------------------------------------------------------------------------------------------ -bool Parser::ParseString(std::string& out,const char* szName) -{ +bool Parser::ParseString(std::string &out, const char *szName) { char szBuffer[1024]; - if (!SkipSpaces(&filePtr)) - { + if (!SkipSpaces(&filePtr)) { - ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Unexpected EOL",szName); + ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Unexpected EOL", szName); LogWarning(szBuffer); return false; } // there must be '"' - if ('\"' != *filePtr) - { + if ('\"' != *filePtr) { ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Strings are expected " - "to be enclosed in double quotation marks",szName); + "to be enclosed in double quotation marks", + szName); LogWarning(szBuffer); return false; } ++filePtr; - const char* sz = filePtr; - while (true) - { - if ('\"' == *sz)break; - else if ('\0' == *sz) - { + const char *sz = filePtr; + while (true) { + if ('\"' == *sz) + break; + else if ('\0' == *sz) { ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Strings are expected to " - "be enclosed in double quotation marks but EOF was reached before " - "a closing quotation mark was encountered",szName); + "be enclosed in double quotation marks but EOF was reached before " + "a closing quotation mark was encountered", + szName); LogWarning(szBuffer); return false; } sz++; } - out = std::string(filePtr,(uintptr_t)sz-(uintptr_t)filePtr); - filePtr = sz+1; + out = std::string(filePtr, (uintptr_t)sz - (uintptr_t)filePtr); + filePtr = sz + 1; return true; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV1ObjectBlock(ASE::BaseNode& node) -{ +void Parser::ParseLV1ObjectBlock(ASE::BaseNode &node) { AI_ASE_PARSER_INIT(); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // first process common tokens such as node name and transform // name of the mesh/node - if (TokenMatch(filePtr,"NODE_NAME" ,9)) - { - if(!ParseString(node.mName,"*NODE_NAME")) + if (TokenMatch(filePtr, "NODE_NAME", 9)) { + if (!ParseString(node.mName, "*NODE_NAME")) SkipToNextToken(); continue; } // name of the parent of the node - if (TokenMatch(filePtr,"NODE_PARENT" ,11) ) - { - if(!ParseString(node.mParent,"*NODE_PARENT")) + if (TokenMatch(filePtr, "NODE_PARENT", 11)) { + if (!ParseString(node.mParent, "*NODE_PARENT")) SkipToNextToken(); continue; } // transformation matrix of the node - if (TokenMatch(filePtr,"NODE_TM" ,7)) - { + if (TokenMatch(filePtr, "NODE_TM", 7)) { ParseLV2NodeTransformBlock(node); continue; } // animation data of the node - if (TokenMatch(filePtr,"TM_ANIMATION" ,12)) - { + if (TokenMatch(filePtr, "TM_ANIMATION", 12)) { ParseLV2AnimationBlock(node); continue; } - if (node.mType == BaseNode::Light) - { + if (node.mType == BaseNode::Light) { // light settings - if (TokenMatch(filePtr,"LIGHT_SETTINGS" ,14)) - { - ParseLV2LightSettingsBlock((ASE::Light&)node); + if (TokenMatch(filePtr, "LIGHT_SETTINGS", 14)) { + ParseLV2LightSettingsBlock((ASE::Light &)node); continue; } // type of the light source - if (TokenMatch(filePtr,"LIGHT_TYPE" ,10)) - { - if (!ASSIMP_strincmp("omni",filePtr,4)) - { - ((ASE::Light&)node).mLightType = ASE::Light::OMNI; - } - else if (!ASSIMP_strincmp("target",filePtr,6)) - { - ((ASE::Light&)node).mLightType = ASE::Light::TARGET; - } - else if (!ASSIMP_strincmp("free",filePtr,4)) - { - ((ASE::Light&)node).mLightType = ASE::Light::FREE; - } - else if (!ASSIMP_strincmp("directional",filePtr,11)) - { - ((ASE::Light&)node).mLightType = ASE::Light::DIRECTIONAL; - } - else - { + if (TokenMatch(filePtr, "LIGHT_TYPE", 10)) { + if (!ASSIMP_strincmp("omni", filePtr, 4)) { + ((ASE::Light &)node).mLightType = ASE::Light::OMNI; + } else if (!ASSIMP_strincmp("target", filePtr, 6)) { + ((ASE::Light &)node).mLightType = ASE::Light::TARGET; + } else if (!ASSIMP_strincmp("free", filePtr, 4)) { + ((ASE::Light &)node).mLightType = ASE::Light::FREE; + } else if (!ASSIMP_strincmp("directional", filePtr, 11)) { + ((ASE::Light &)node).mLightType = ASE::Light::DIRECTIONAL; + } else { LogWarning("Unknown kind of light source"); } continue; } - } - else if (node.mType == BaseNode::Camera) - { + } else if (node.mType == BaseNode::Camera) { // Camera settings - if (TokenMatch(filePtr,"CAMERA_SETTINGS" ,15)) - { - ParseLV2CameraSettingsBlock((ASE::Camera&)node); + if (TokenMatch(filePtr, "CAMERA_SETTINGS", 15)) { + ParseLV2CameraSettingsBlock((ASE::Camera &)node); continue; - } - else if (TokenMatch(filePtr,"CAMERA_TYPE" ,11)) - { - if (!ASSIMP_strincmp("target",filePtr,6)) - { - ((ASE::Camera&)node).mCameraType = ASE::Camera::TARGET; - } - else if (!ASSIMP_strincmp("free",filePtr,4)) - { - ((ASE::Camera&)node).mCameraType = ASE::Camera::FREE; - } - else - { + } else if (TokenMatch(filePtr, "CAMERA_TYPE", 11)) { + if (!ASSIMP_strincmp("target", filePtr, 6)) { + ((ASE::Camera &)node).mCameraType = ASE::Camera::TARGET; + } else if (!ASSIMP_strincmp("free", filePtr, 4)) { + ((ASE::Camera &)node).mCameraType = ASE::Camera::FREE; + } else { LogWarning("Unknown kind of camera"); } continue; } - } - else if (node.mType == BaseNode::Mesh) - { + } else if (node.mType == BaseNode::Mesh) { // mesh data // FIX: Older files use MESH_SOFTSKIN - if (TokenMatch(filePtr,"MESH" ,4) || - TokenMatch(filePtr,"MESH_SOFTSKIN",13)) - { - ParseLV2MeshBlock((ASE::Mesh&)node); + if (TokenMatch(filePtr, "MESH", 4) || + TokenMatch(filePtr, "MESH_SOFTSKIN", 13)) { + ParseLV2MeshBlock((ASE::Mesh &)node); continue; } // mesh material index - if (TokenMatch(filePtr,"MATERIAL_REF" ,12)) - { - ParseLV4MeshLong(((ASE::Mesh&)node).iMaterialIndex); + if (TokenMatch(filePtr, "MATERIAL_REF", 12)) { + ParseLV4MeshLong(((ASE::Mesh &)node).iMaterialIndex); continue; } } @@ -981,156 +858,130 @@ void Parser::ParseLV1ObjectBlock(ASE::BaseNode& node) } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV2CameraSettingsBlock(ASE::Camera& camera) -{ +void Parser::ParseLV2CameraSettingsBlock(ASE::Camera &camera) { AI_ASE_PARSER_INIT(); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; - if (TokenMatch(filePtr,"CAMERA_NEAR" ,11)) - { + if (TokenMatch(filePtr, "CAMERA_NEAR", 11)) { ParseLV4MeshFloat(camera.mNear); continue; } - if (TokenMatch(filePtr,"CAMERA_FAR" ,10)) - { + if (TokenMatch(filePtr, "CAMERA_FAR", 10)) { ParseLV4MeshFloat(camera.mFar); continue; } - if (TokenMatch(filePtr,"CAMERA_FOV" ,10)) - { + if (TokenMatch(filePtr, "CAMERA_FOV", 10)) { ParseLV4MeshFloat(camera.mFOV); continue; } } - AI_ASE_HANDLE_SECTION("2","CAMERA_SETTINGS"); + AI_ASE_HANDLE_SECTION("2", "CAMERA_SETTINGS"); } return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV2LightSettingsBlock(ASE::Light& light) -{ +void Parser::ParseLV2LightSettingsBlock(ASE::Light &light) { AI_ASE_PARSER_INIT(); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; - if (TokenMatch(filePtr,"LIGHT_COLOR" ,11)) - { + if (TokenMatch(filePtr, "LIGHT_COLOR", 11)) { ParseLV4MeshFloatTriple(&light.mColor.r); continue; } - if (TokenMatch(filePtr,"LIGHT_INTENS" ,12)) - { + if (TokenMatch(filePtr, "LIGHT_INTENS", 12)) { ParseLV4MeshFloat(light.mIntensity); continue; } - if (TokenMatch(filePtr,"LIGHT_HOTSPOT" ,13)) - { + if (TokenMatch(filePtr, "LIGHT_HOTSPOT", 13)) { ParseLV4MeshFloat(light.mAngle); continue; } - if (TokenMatch(filePtr,"LIGHT_FALLOFF" ,13)) - { + if (TokenMatch(filePtr, "LIGHT_FALLOFF", 13)) { ParseLV4MeshFloat(light.mFalloff); continue; } } - AI_ASE_HANDLE_SECTION("2","LIGHT_SETTINGS"); + AI_ASE_HANDLE_SECTION("2", "LIGHT_SETTINGS"); } - return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh) -{ +void Parser::ParseLV2AnimationBlock(ASE::BaseNode &mesh) { AI_ASE_PARSER_INIT(); - ASE::Animation* anim = &mesh.mAnim; - while (true) - { - if ('*' == *filePtr) - { + ASE::Animation *anim = &mesh.mAnim; + while (true) { + if ('*' == *filePtr) { ++filePtr; - if (TokenMatch(filePtr,"NODE_NAME" ,9)) - { + if (TokenMatch(filePtr, "NODE_NAME", 9)) { std::string temp; - if(!ParseString(temp,"*NODE_NAME")) + if (!ParseString(temp, "*NODE_NAME")) SkipToNextToken(); // If the name of the node contains .target it // represents an animated camera or spot light // target. - if (std::string::npos != temp.find(".Target")) - { - if ((mesh.mType != BaseNode::Camera || ((ASE::Camera&)mesh).mCameraType != ASE::Camera::TARGET) && - ( mesh.mType != BaseNode::Light || ((ASE::Light&)mesh).mLightType != ASE::Light::TARGET)) - { + if (std::string::npos != temp.find(".Target")) { + if ((mesh.mType != BaseNode::Camera || ((ASE::Camera &)mesh).mCameraType != ASE::Camera::TARGET) && + (mesh.mType != BaseNode::Light || ((ASE::Light &)mesh).mLightType != ASE::Light::TARGET)) { ASSIMP_LOG_ERROR("ASE: Found target animation channel " - "but the node is neither a camera nor a spot light"); - anim = NULL; - } - else anim = &mesh.mTargetAnim; + "but the node is neither a camera nor a spot light"); + anim = nullptr; + } else + anim = &mesh.mTargetAnim; } continue; } // position keyframes - if (TokenMatch(filePtr,"CONTROL_POS_TRACK" ,17) || - TokenMatch(filePtr,"CONTROL_POS_BEZIER" ,18) || - TokenMatch(filePtr,"CONTROL_POS_TCB" ,15)) - { - if (!anim)SkipSection(); - else ParseLV3PosAnimationBlock(*anim); + if (TokenMatch(filePtr, "CONTROL_POS_TRACK", 17) || + TokenMatch(filePtr, "CONTROL_POS_BEZIER", 18) || + TokenMatch(filePtr, "CONTROL_POS_TCB", 15)) { + if (!anim) + SkipSection(); + else + ParseLV3PosAnimationBlock(*anim); continue; } // scaling keyframes - if (TokenMatch(filePtr,"CONTROL_SCALE_TRACK" ,19) || - TokenMatch(filePtr,"CONTROL_SCALE_BEZIER" ,20) || - TokenMatch(filePtr,"CONTROL_SCALE_TCB" ,17)) - { - if (!anim || anim == &mesh.mTargetAnim) - { + if (TokenMatch(filePtr, "CONTROL_SCALE_TRACK", 19) || + TokenMatch(filePtr, "CONTROL_SCALE_BEZIER", 20) || + TokenMatch(filePtr, "CONTROL_SCALE_TCB", 17)) { + if (!anim || anim == &mesh.mTargetAnim) { // Target animation channels may have no rotation channels ASSIMP_LOG_ERROR("ASE: Ignoring scaling channel in target animation"); SkipSection(); - } - else ParseLV3ScaleAnimationBlock(*anim); + } else + ParseLV3ScaleAnimationBlock(*anim); continue; } // rotation keyframes - if (TokenMatch(filePtr,"CONTROL_ROT_TRACK" ,17) || - TokenMatch(filePtr,"CONTROL_ROT_BEZIER" ,18) || - TokenMatch(filePtr,"CONTROL_ROT_TCB" ,15)) - { - if (!anim || anim == &mesh.mTargetAnim) - { + if (TokenMatch(filePtr, "CONTROL_ROT_TRACK", 17) || + TokenMatch(filePtr, "CONTROL_ROT_BEZIER", 18) || + TokenMatch(filePtr, "CONTROL_ROT_TCB", 15)) { + if (!anim || anim == &mesh.mTargetAnim) { // Target animation channels may have no rotation channels ASSIMP_LOG_ERROR("ASE: Ignoring rotation channel in target animation"); SkipSection(); - } - else ParseLV3RotAnimationBlock(*anim); + } else + ParseLV3RotAnimationBlock(*anim); continue; } } - AI_ASE_HANDLE_SECTION("2","TM_ANIMATION"); + AI_ASE_HANDLE_SECTION("2", "TM_ANIMATION"); } } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation& anim) -{ +void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation &anim) { AI_ASE_PARSER_INIT(); unsigned int iIndex; - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; bool b = false; @@ -1139,44 +990,37 @@ void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation& anim) // we ignore the additional information for bezier's and TCBs // simple scaling keyframe - if (TokenMatch(filePtr,"CONTROL_SCALE_SAMPLE" ,20)) - { + if (TokenMatch(filePtr, "CONTROL_SCALE_SAMPLE", 20)) { b = true; anim.mScalingType = ASE::Animation::TRACK; } // Bezier scaling keyframe - if (TokenMatch(filePtr,"CONTROL_BEZIER_SCALE_KEY" ,24)) - { + if (TokenMatch(filePtr, "CONTROL_BEZIER_SCALE_KEY", 24)) { b = true; anim.mScalingType = ASE::Animation::BEZIER; } // TCB scaling keyframe - if (TokenMatch(filePtr,"CONTROL_TCB_SCALE_KEY" ,21)) - { + if (TokenMatch(filePtr, "CONTROL_TCB_SCALE_KEY", 21)) { b = true; anim.mScalingType = ASE::Animation::TCB; } - if (b) - { + if (b) { anim.akeyScaling.push_back(aiVectorKey()); - aiVectorKey& key = anim.akeyScaling.back(); - ParseLV4MeshFloatTriple(&key.mValue.x,iIndex); + aiVectorKey &key = anim.akeyScaling.back(); + ParseLV4MeshFloatTriple(&key.mValue.x, iIndex); key.mTime = (double)iIndex; } } - AI_ASE_HANDLE_SECTION("3","*CONTROL_POS_TRACK"); + AI_ASE_HANDLE_SECTION("3", "*CONTROL_POS_TRACK"); } } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV3PosAnimationBlock(ASE::Animation& anim) -{ +void Parser::ParseLV3PosAnimationBlock(ASE::Animation &anim) { AI_ASE_PARSER_INIT(); unsigned int iIndex; - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; bool b = false; @@ -1185,44 +1029,37 @@ void Parser::ParseLV3PosAnimationBlock(ASE::Animation& anim) // we ignore the additional information for bezier's and TCBs // simple scaling keyframe - if (TokenMatch(filePtr,"CONTROL_POS_SAMPLE" ,18)) - { + if (TokenMatch(filePtr, "CONTROL_POS_SAMPLE", 18)) { b = true; anim.mPositionType = ASE::Animation::TRACK; } // Bezier scaling keyframe - if (TokenMatch(filePtr,"CONTROL_BEZIER_POS_KEY" ,22)) - { + if (TokenMatch(filePtr, "CONTROL_BEZIER_POS_KEY", 22)) { b = true; anim.mPositionType = ASE::Animation::BEZIER; } // TCB scaling keyframe - if (TokenMatch(filePtr,"CONTROL_TCB_POS_KEY" ,19)) - { + if (TokenMatch(filePtr, "CONTROL_TCB_POS_KEY", 19)) { b = true; anim.mPositionType = ASE::Animation::TCB; } - if (b) - { + if (b) { anim.akeyPositions.push_back(aiVectorKey()); - aiVectorKey& key = anim.akeyPositions.back(); - ParseLV4MeshFloatTriple(&key.mValue.x,iIndex); + aiVectorKey &key = anim.akeyPositions.back(); + ParseLV4MeshFloatTriple(&key.mValue.x, iIndex); key.mTime = (double)iIndex; } } - AI_ASE_HANDLE_SECTION("3","*CONTROL_POS_TRACK"); + AI_ASE_HANDLE_SECTION("3", "*CONTROL_POS_TRACK"); } } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV3RotAnimationBlock(ASE::Animation& anim) -{ +void Parser::ParseLV3RotAnimationBlock(ASE::Animation &anim) { AI_ASE_PARSER_INIT(); unsigned int iIndex; - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; bool b = false; @@ -1231,150 +1068,126 @@ void Parser::ParseLV3RotAnimationBlock(ASE::Animation& anim) // we ignore the additional information for bezier's and TCBs // simple scaling keyframe - if (TokenMatch(filePtr,"CONTROL_ROT_SAMPLE" ,18)) - { + if (TokenMatch(filePtr, "CONTROL_ROT_SAMPLE", 18)) { b = true; anim.mRotationType = ASE::Animation::TRACK; } // Bezier scaling keyframe - if (TokenMatch(filePtr,"CONTROL_BEZIER_ROT_KEY" ,22)) - { + if (TokenMatch(filePtr, "CONTROL_BEZIER_ROT_KEY", 22)) { b = true; anim.mRotationType = ASE::Animation::BEZIER; } // TCB scaling keyframe - if (TokenMatch(filePtr,"CONTROL_TCB_ROT_KEY" ,19)) - { + if (TokenMatch(filePtr, "CONTROL_TCB_ROT_KEY", 19)) { b = true; anim.mRotationType = ASE::Animation::TCB; } - if (b) - { + if (b) { anim.akeyRotations.push_back(aiQuatKey()); - aiQuatKey& key = anim.akeyRotations.back(); - aiVector3D v;ai_real f; - ParseLV4MeshFloatTriple(&v.x,iIndex); + aiQuatKey &key = anim.akeyRotations.back(); + aiVector3D v; + ai_real f; + ParseLV4MeshFloatTriple(&v.x, iIndex); ParseLV4MeshFloat(f); key.mTime = (double)iIndex; - key.mValue = aiQuaternion(v,f); + key.mValue = aiQuaternion(v, f); } } - AI_ASE_HANDLE_SECTION("3","*CONTROL_ROT_TRACK"); + AI_ASE_HANDLE_SECTION("3", "*CONTROL_ROT_TRACK"); } } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode& mesh) -{ +void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode &mesh) { AI_ASE_PARSER_INIT(); - int mode = 0; - while (true) - { - if ('*' == *filePtr) - { + int mode = 0; + while (true) { + if ('*' == *filePtr) { ++filePtr; // name of the node - if (TokenMatch(filePtr,"NODE_NAME" ,9)) - { + if (TokenMatch(filePtr, "NODE_NAME", 9)) { std::string temp; - if(!ParseString(temp,"*NODE_NAME")) + if (!ParseString(temp, "*NODE_NAME")) SkipToNextToken(); std::string::size_type s; - if (temp == mesh.mName) - { + if (temp == mesh.mName) { mode = 1; - } - else if (std::string::npos != (s = temp.find(".Target")) && - mesh.mName == temp.substr(0,s)) - { + } else if (std::string::npos != (s = temp.find(".Target")) && + mesh.mName == temp.substr(0, s)) { // This should be either a target light or a target camera - if ( (mesh.mType == BaseNode::Light && ((ASE::Light&)mesh) .mLightType == ASE::Light::TARGET) || - (mesh.mType == BaseNode::Camera && ((ASE::Camera&)mesh).mCameraType == ASE::Camera::TARGET)) - { + if ((mesh.mType == BaseNode::Light && ((ASE::Light &)mesh).mLightType == ASE::Light::TARGET) || + (mesh.mType == BaseNode::Camera && ((ASE::Camera &)mesh).mCameraType == ASE::Camera::TARGET)) { mode = 2; - } - else { + } else { ASSIMP_LOG_ERROR("ASE: Ignoring target transform, " - "this is no spot light or target camera"); + "this is no spot light or target camera"); } - } - else - { - ASSIMP_LOG_ERROR("ASE: Unknown node transformation: " + temp); + } else { + ASSIMP_LOG_ERROR("ASE: Unknown node transformation: ", temp); // mode = 0 } continue; } - if (mode) - { + if (mode) { // fourth row of the transformation matrix - and also the // only information here that is interesting for targets - if (TokenMatch(filePtr,"TM_ROW3" ,7)) - { + if (TokenMatch(filePtr, "TM_ROW3", 7)) { ParseLV4MeshFloatTriple((mode == 1 ? mesh.mTransform[3] : &mesh.mTargetPosition.x)); continue; } - if (mode == 1) - { + if (mode == 1) { // first row of the transformation matrix - if (TokenMatch(filePtr,"TM_ROW0" ,7)) - { + if (TokenMatch(filePtr, "TM_ROW0", 7)) { ParseLV4MeshFloatTriple(mesh.mTransform[0]); continue; } // second row of the transformation matrix - if (TokenMatch(filePtr,"TM_ROW1" ,7)) - { + if (TokenMatch(filePtr, "TM_ROW1", 7)) { ParseLV4MeshFloatTriple(mesh.mTransform[1]); continue; } // third row of the transformation matrix - if (TokenMatch(filePtr,"TM_ROW2" ,7)) - { + if (TokenMatch(filePtr, "TM_ROW2", 7)) { ParseLV4MeshFloatTriple(mesh.mTransform[2]); continue; } // inherited position axes - if (TokenMatch(filePtr,"INHERIT_POS" ,11)) - { + if (TokenMatch(filePtr, "INHERIT_POS", 11)) { unsigned int aiVal[3]; ParseLV4MeshLongTriple(aiVal); - for (unsigned int i = 0; i < 3;++i) + for (unsigned int i = 0; i < 3; ++i) mesh.inherit.abInheritPosition[i] = aiVal[i] != 0; continue; } // inherited rotation axes - if (TokenMatch(filePtr,"INHERIT_ROT" ,11)) - { + if (TokenMatch(filePtr, "INHERIT_ROT", 11)) { unsigned int aiVal[3]; ParseLV4MeshLongTriple(aiVal); - for (unsigned int i = 0; i < 3;++i) + for (unsigned int i = 0; i < 3; ++i) mesh.inherit.abInheritRotation[i] = aiVal[i] != 0; continue; } // inherited scaling axes - if (TokenMatch(filePtr,"INHERIT_SCL" ,11)) - { + if (TokenMatch(filePtr, "INHERIT_SCL", 11)) { unsigned int aiVal[3]; ParseLV4MeshLongTriple(aiVal); - for (unsigned int i = 0; i < 3;++i) + for (unsigned int i = 0; i < 3; ++i) mesh.inherit.abInheritScaling[i] = aiVal[i] != 0; continue; } } } } - AI_ASE_HANDLE_SECTION("2","*NODE_TM"); + AI_ASE_HANDLE_SECTION("2", "*NODE_TM"); } return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh) -{ +void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) { AI_ASE_PARSER_INIT(); unsigned int iNumVertices = 0; @@ -1383,386 +1196,327 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh) unsigned int iNumTFaces = 0; unsigned int iNumCVertices = 0; unsigned int iNumCFaces = 0; - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Number of vertices in the mesh - if (TokenMatch(filePtr,"MESH_NUMVERTEX" ,14)) - { + if (TokenMatch(filePtr, "MESH_NUMVERTEX", 14)) { ParseLV4MeshLong(iNumVertices); continue; } // Number of texture coordinates in the mesh - if (TokenMatch(filePtr,"MESH_NUMTVERTEX" ,15)) - { + if (TokenMatch(filePtr, "MESH_NUMTVERTEX", 15)) { ParseLV4MeshLong(iNumTVertices); continue; } // Number of vertex colors in the mesh - if (TokenMatch(filePtr,"MESH_NUMCVERTEX" ,15)) - { + if (TokenMatch(filePtr, "MESH_NUMCVERTEX", 15)) { ParseLV4MeshLong(iNumCVertices); continue; } // Number of regular faces in the mesh - if (TokenMatch(filePtr,"MESH_NUMFACES" ,13)) - { + if (TokenMatch(filePtr, "MESH_NUMFACES", 13)) { ParseLV4MeshLong(iNumFaces); continue; } // Number of UVWed faces in the mesh - if (TokenMatch(filePtr,"MESH_NUMTVFACES" ,15)) - { + if (TokenMatch(filePtr, "MESH_NUMTVFACES", 15)) { ParseLV4MeshLong(iNumTFaces); continue; } // Number of colored faces in the mesh - if (TokenMatch(filePtr,"MESH_NUMCVFACES" ,15)) - { + if (TokenMatch(filePtr, "MESH_NUMCVFACES", 15)) { ParseLV4MeshLong(iNumCFaces); continue; } // mesh vertex list block - if (TokenMatch(filePtr,"MESH_VERTEX_LIST" ,16)) - { - ParseLV3MeshVertexListBlock(iNumVertices,mesh); + if (TokenMatch(filePtr, "MESH_VERTEX_LIST", 16)) { + ParseLV3MeshVertexListBlock(iNumVertices, mesh); continue; } // mesh face list block - if (TokenMatch(filePtr,"MESH_FACE_LIST" ,14)) - { - ParseLV3MeshFaceListBlock(iNumFaces,mesh); + if (TokenMatch(filePtr, "MESH_FACE_LIST", 14)) { + ParseLV3MeshFaceListBlock(iNumFaces, mesh); continue; } // mesh texture vertex list block - if (TokenMatch(filePtr,"MESH_TVERTLIST" ,14)) - { - ParseLV3MeshTListBlock(iNumTVertices,mesh); + if (TokenMatch(filePtr, "MESH_TVERTLIST", 14)) { + ParseLV3MeshTListBlock(iNumTVertices, mesh); continue; } // mesh texture face block - if (TokenMatch(filePtr,"MESH_TFACELIST" ,14)) - { - ParseLV3MeshTFaceListBlock(iNumTFaces,mesh); + if (TokenMatch(filePtr, "MESH_TFACELIST", 14)) { + ParseLV3MeshTFaceListBlock(iNumTFaces, mesh); continue; } // mesh color vertex list block - if (TokenMatch(filePtr,"MESH_CVERTLIST" ,14)) - { - ParseLV3MeshCListBlock(iNumCVertices,mesh); + if (TokenMatch(filePtr, "MESH_CVERTLIST", 14)) { + ParseLV3MeshCListBlock(iNumCVertices, mesh); continue; } // mesh color face block - if (TokenMatch(filePtr,"MESH_CFACELIST" ,14)) - { - ParseLV3MeshCFaceListBlock(iNumCFaces,mesh); + if (TokenMatch(filePtr, "MESH_CFACELIST", 14)) { + ParseLV3MeshCFaceListBlock(iNumCFaces, mesh); continue; } // mesh normals - if (TokenMatch(filePtr,"MESH_NORMALS" ,12)) - { + if (TokenMatch(filePtr, "MESH_NORMALS", 12)) { ParseLV3MeshNormalListBlock(mesh); continue; } // another mesh UV channel ... - if (TokenMatch(filePtr,"MESH_MAPPINGCHANNEL" ,19)) { - unsigned int iIndex( 0 ); + if (TokenMatch(filePtr, "MESH_MAPPINGCHANNEL", 19)) { + unsigned int iIndex(0); ParseLV4MeshLong(iIndex); - if ( 0 == iIndex ) { - LogWarning( "Mapping channel has an invalid index. Skipping UV channel" ); + if (0 == iIndex) { + LogWarning("Mapping channel has an invalid index. Skipping UV channel"); // skip it ... SkipSection(); } else { - if ( iIndex < 2 ) { - LogWarning( "Mapping channel has an invalid index. Skipping UV channel" ); + if (iIndex < 2) { + LogWarning("Mapping channel has an invalid index. Skipping UV channel"); // skip it ... SkipSection(); } - if ( iIndex > AI_MAX_NUMBER_OF_TEXTURECOORDS ) { - LogWarning( "Too many UV channels specified. Skipping channel .." ); + if (iIndex > AI_MAX_NUMBER_OF_TEXTURECOORDS) { + LogWarning("Too many UV channels specified. Skipping channel .."); // skip it ... SkipSection(); } else { // parse the mapping channel - ParseLV3MappingChannel( iIndex - 1, mesh ); + ParseLV3MappingChannel(iIndex - 1, mesh); } continue; } } // mesh animation keyframe. Not supported - if (TokenMatch(filePtr,"MESH_ANIMATION" ,14)) - { + if (TokenMatch(filePtr, "MESH_ANIMATION", 14)) { LogWarning("Found *MESH_ANIMATION element in ASE/ASK file. " - "Keyframe animation is not supported by Assimp, this element " - "will be ignored"); + "Keyframe animation is not supported by Assimp, this element " + "will be ignored"); //SkipSection(); continue; } - if (TokenMatch(filePtr,"MESH_WEIGHTS" ,12)) - { - ParseLV3MeshWeightsBlock(mesh);continue; + if (TokenMatch(filePtr, "MESH_WEIGHTS", 12)) { + ParseLV3MeshWeightsBlock(mesh); + continue; } } - AI_ASE_HANDLE_SECTION("2","*MESH"); + AI_ASE_HANDLE_SECTION("2", "*MESH"); } return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh) -{ +void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) { AI_ASE_PARSER_INIT(); unsigned int iNumVertices = 0, iNumBones = 0; - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Number of bone vertices ... - if (TokenMatch(filePtr,"MESH_NUMVERTEX" ,14)) - { + if (TokenMatch(filePtr, "MESH_NUMVERTEX", 14)) { ParseLV4MeshLong(iNumVertices); continue; } // Number of bones - if (TokenMatch(filePtr,"MESH_NUMBONE" ,12)) - { + if (TokenMatch(filePtr, "MESH_NUMBONE", 12)) { ParseLV4MeshLong(iNumBones); continue; } // parse the list of bones - if (TokenMatch(filePtr,"MESH_BONE_LIST" ,14)) - { - ParseLV4MeshBones(iNumBones,mesh); + if (TokenMatch(filePtr, "MESH_BONE_LIST", 14)) { + ParseLV4MeshBones(iNumBones, mesh); continue; } // parse the list of bones vertices - if (TokenMatch(filePtr,"MESH_BONE_VERTEX_LIST" ,21) ) - { - ParseLV4MeshBonesVertices(iNumVertices,mesh); + if (TokenMatch(filePtr, "MESH_BONE_VERTEX_LIST", 21)) { + ParseLV4MeshBonesVertices(iNumVertices, mesh); continue; } } - AI_ASE_HANDLE_SECTION("3","*MESH_WEIGHTS"); + AI_ASE_HANDLE_SECTION("3", "*MESH_WEIGHTS"); } return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh) -{ +void Parser::ParseLV4MeshBones(unsigned int iNumBones, ASE::Mesh &mesh) { AI_ASE_PARSER_INIT(); mesh.mBones.resize(iNumBones, Bone("UNNAMED")); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Mesh bone with name ... - if (TokenMatch(filePtr,"MESH_BONE_NAME" ,14)) - { + if (TokenMatch(filePtr, "MESH_BONE_NAME", 14)) { // parse an index ... - if(SkipSpaces(&filePtr)) - { - unsigned int iIndex = strtoul10(filePtr,&filePtr); - if (iIndex >= iNumBones) - { + if (SkipSpaces(&filePtr)) { + unsigned int iIndex = strtoul10(filePtr, &filePtr); + if (iIndex >= iNumBones) { LogWarning("Bone index is out of bounds"); continue; } - if (!ParseString(mesh.mBones[iIndex].mName,"*MESH_BONE_NAME")) + if (!ParseString(mesh.mBones[iIndex].mName, "*MESH_BONE_NAME")) SkipToNextToken(); continue; } } } - AI_ASE_HANDLE_SECTION("3","*MESH_BONE_LIST"); + AI_ASE_HANDLE_SECTION("3", "*MESH_BONE_LIST"); } } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices,ASE::Mesh& mesh) -{ +void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mesh) { AI_ASE_PARSER_INIT(); mesh.mBoneVertices.resize(iNumVertices); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Mesh bone vertex - if (TokenMatch(filePtr,"MESH_BONE_VERTEX" ,16)) - { + if (TokenMatch(filePtr, "MESH_BONE_VERTEX", 16)) { // read the vertex index - unsigned int iIndex = strtoul10(filePtr,&filePtr); - if (iIndex >= mesh.mPositions.size()) - { - iIndex = (unsigned int)mesh.mPositions.size()-1; + unsigned int iIndex = strtoul10(filePtr, &filePtr); + if (iIndex >= mesh.mPositions.size()) { + iIndex = (unsigned int)mesh.mPositions.size() - 1; LogWarning("Bone vertex index is out of bounds. Using the largest valid " - "bone vertex index instead"); + "bone vertex index instead"); } // --- ignored ai_real afVert[3]; ParseLV4MeshFloatTriple(afVert); - std::pair pairOut; - while (true) - { + std::pair pairOut; + while (true) { // first parse the bone index ... - if (!SkipSpaces(&filePtr))break; - pairOut.first = strtoul10(filePtr,&filePtr); + if (!SkipSpaces(&filePtr)) break; + pairOut.first = strtoul10(filePtr, &filePtr); // then parse the vertex weight - if (!SkipSpaces(&filePtr))break; - filePtr = fast_atoreal_move(filePtr,pairOut.second); + if (!SkipSpaces(&filePtr)) break; + filePtr = fast_atoreal_move(filePtr, pairOut.second); // -1 marks unused entries - if (-1 != pairOut.first) - { + if (-1 != pairOut.first) { mesh.mBoneVertices[iIndex].mBoneWeights.push_back(pairOut); } } continue; } } - AI_ASE_HANDLE_SECTION("4","*MESH_BONE_VERTEX"); + AI_ASE_HANDLE_SECTION("4", "*MESH_BONE_VERTEX"); } return; } // ------------------------------------------------------------------------------------------------ void Parser::ParseLV3MeshVertexListBlock( - unsigned int iNumVertices, ASE::Mesh& mesh) -{ + unsigned int iNumVertices, ASE::Mesh &mesh) { AI_ASE_PARSER_INIT(); // allocate enough storage in the array mesh.mPositions.resize(iNumVertices); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Vertex entry - if (TokenMatch(filePtr,"MESH_VERTEX" ,11)) - { + if (TokenMatch(filePtr, "MESH_VERTEX", 11)) { aiVector3D vTemp; unsigned int iIndex; - ParseLV4MeshFloatTriple(&vTemp.x,iIndex); + ParseLV4MeshFloatTriple(&vTemp.x, iIndex); - if (iIndex >= iNumVertices) - { + if (iIndex >= iNumVertices) { LogWarning("Invalid vertex index. It will be ignored"); - } - else mesh.mPositions[iIndex] = vTemp; + } else + mesh.mPositions[iIndex] = vTemp; continue; } } - AI_ASE_HANDLE_SECTION("3","*MESH_VERTEX_LIST"); + AI_ASE_HANDLE_SECTION("3", "*MESH_VERTEX_LIST"); } return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh) -{ +void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) { AI_ASE_PARSER_INIT(); // allocate enough storage in the face array mesh.mFaces.resize(iNumFaces); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Face entry - if (TokenMatch(filePtr,"MESH_FACE" ,9)) - { + if (TokenMatch(filePtr, "MESH_FACE", 9)) { ASE::Face mFace; ParseLV4MeshFace(mFace); - if (mFace.iFace >= iNumFaces) - { + if (mFace.iFace >= iNumFaces) { LogWarning("Face has an invalid index. It will be ignored"); - } - else mesh.mFaces[mFace.iFace] = mFace; + } else + mesh.mFaces[mFace.iFace] = mFace; continue; } } - AI_ASE_HANDLE_SECTION("3","*MESH_FACE_LIST"); + AI_ASE_HANDLE_SECTION("3", "*MESH_FACE_LIST"); } return; } // ------------------------------------------------------------------------------------------------ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices, - ASE::Mesh& mesh, unsigned int iChannel) -{ + ASE::Mesh &mesh, unsigned int iChannel) { AI_ASE_PARSER_INIT(); // allocate enough storage in the array mesh.amTexCoords[iChannel].resize(iNumVertices); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Vertex entry - if (TokenMatch(filePtr,"MESH_TVERT" ,10)) - { + if (TokenMatch(filePtr, "MESH_TVERT", 10)) { aiVector3D vTemp; unsigned int iIndex; - ParseLV4MeshFloatTriple(&vTemp.x,iIndex); + ParseLV4MeshFloatTriple(&vTemp.x, iIndex); - if (iIndex >= iNumVertices) - { + if (iIndex >= iNumVertices) { LogWarning("Tvertex has an invalid index. It will be ignored"); - } - else mesh.amTexCoords[iChannel][iIndex] = vTemp; + } else + mesh.amTexCoords[iChannel][iIndex] = vTemp; - if (0.0f != vTemp.z) - { + if (0.0f != vTemp.z) { // we need 3 coordinate channels mesh.mNumUVComponents[iChannel] = 3; } continue; } } - AI_ASE_HANDLE_SECTION("3","*MESH_TVERT_LIST"); + AI_ASE_HANDLE_SECTION("3", "*MESH_TVERT_LIST"); } return; } // ------------------------------------------------------------------------------------------------ void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces, - ASE::Mesh& mesh, unsigned int iChannel) -{ + ASE::Mesh &mesh, unsigned int iChannel) { AI_ASE_PARSER_INIT(); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Face entry - if (TokenMatch(filePtr,"MESH_TFACE" ,10)) - { + if (TokenMatch(filePtr, "MESH_TFACE", 10)) { unsigned int aiValues[3]; unsigned int iIndex = 0; - ParseLV4MeshLongTriple(aiValues,iIndex); - if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size()) - { + ParseLV4MeshLongTriple(aiValues, iIndex); + if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size()) { LogWarning("UV-Face has an invalid index. It will be ignored"); - } - else - { + } else { // copy UV indices mesh.mFaces[iIndex].amUVIndices[iChannel][0] = aiValues[0]; mesh.mFaces[iIndex].amUVIndices[iChannel][1] = aiValues[1]; @@ -1771,108 +1525,89 @@ void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces, continue; } } - AI_ASE_HANDLE_SECTION("3","*MESH_TFACE_LIST"); + AI_ASE_HANDLE_SECTION("3", "*MESH_TFACE_LIST"); } return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh) -{ +void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) { AI_ASE_PARSER_INIT(); unsigned int iNumTVertices = 0; unsigned int iNumTFaces = 0; - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Number of texture coordinates in the mesh - if (TokenMatch(filePtr,"MESH_NUMTVERTEX" ,15)) - { + if (TokenMatch(filePtr, "MESH_NUMTVERTEX", 15)) { ParseLV4MeshLong(iNumTVertices); continue; } // Number of UVWed faces in the mesh - if (TokenMatch(filePtr,"MESH_NUMTVFACES" ,15)) - { + if (TokenMatch(filePtr, "MESH_NUMTVFACES", 15)) { ParseLV4MeshLong(iNumTFaces); continue; } // mesh texture vertex list block - if (TokenMatch(filePtr,"MESH_TVERTLIST" ,14)) - { - ParseLV3MeshTListBlock(iNumTVertices,mesh,iChannel); + if (TokenMatch(filePtr, "MESH_TVERTLIST", 14)) { + ParseLV3MeshTListBlock(iNumTVertices, mesh, iChannel); continue; } // mesh texture face block - if (TokenMatch(filePtr,"MESH_TFACELIST" ,14)) - { - ParseLV3MeshTFaceListBlock(iNumTFaces,mesh, iChannel); + if (TokenMatch(filePtr, "MESH_TFACELIST", 14)) { + ParseLV3MeshTFaceListBlock(iNumTFaces, mesh, iChannel); continue; } } - AI_ASE_HANDLE_SECTION("3","*MESH_MAPPING_CHANNEL"); + AI_ASE_HANDLE_SECTION("3", "*MESH_MAPPING_CHANNEL"); } return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh& mesh) -{ +void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh) { AI_ASE_PARSER_INIT(); // allocate enough storage in the array mesh.mVertexColors.resize(iNumVertices); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Vertex entry - if (TokenMatch(filePtr,"MESH_VERTCOL" ,12)) - { + if (TokenMatch(filePtr, "MESH_VERTCOL", 12)) { aiColor4D vTemp; vTemp.a = 1.0f; unsigned int iIndex; - ParseLV4MeshFloatTriple(&vTemp.r,iIndex); + ParseLV4MeshFloatTriple(&vTemp.r, iIndex); - if (iIndex >= iNumVertices) - { + if (iIndex >= iNumVertices) { LogWarning("Vertex color has an invalid index. It will be ignored"); - } - else mesh.mVertexColors[iIndex] = vTemp; + } else + mesh.mVertexColors[iIndex] = vTemp; continue; } } - AI_ASE_HANDLE_SECTION("3","*MESH_CVERTEX_LIST"); + AI_ASE_HANDLE_SECTION("3", "*MESH_CVERTEX_LIST"); } return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh) -{ +void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) { AI_ASE_PARSER_INIT(); - while (true) - { - if ('*' == *filePtr) - { + while (true) { + if ('*' == *filePtr) { ++filePtr; // Face entry - if (TokenMatch(filePtr,"MESH_CFACE" ,10)) - { + if (TokenMatch(filePtr, "MESH_CFACE", 10)) { unsigned int aiValues[3]; unsigned int iIndex = 0; - ParseLV4MeshLongTriple(aiValues,iIndex); - if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size()) - { + ParseLV4MeshLongTriple(aiValues, iIndex); + if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size()) { LogWarning("UV-Face has an invalid index. It will be ignored"); - } - else - { + } else { // copy color indices mesh.mFaces[iIndex].mColorIndices[0] = aiValues[0]; mesh.mFaces[iIndex].mColorIndices[1] = aiValues[1]; @@ -1881,17 +1616,16 @@ void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh) continue; } } - AI_ASE_HANDLE_SECTION("3","*MESH_CFACE_LIST"); + AI_ASE_HANDLE_SECTION("3", "*MESH_CFACE_LIST"); } return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh) -{ +void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) { AI_ASE_PARSER_INIT(); // Allocate enough storage for the normals - sMesh.mNormals.resize(sMesh.mFaces.size()*3,aiVector3D( 0.f, 0.f, 0.f )); + sMesh.mNormals.resize(sMesh.mFaces.size() * 3, aiVector3D(0.f, 0.f, 0.f)); unsigned int index, faceIdx = UINT_MAX; // FIXME: rewrite this and find out how to interpret the normals @@ -1899,34 +1633,34 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh) // Smooth the vertex and face normals together. The result // will be edgy then, but otherwise everything would be soft ... - while (true) { - if ('*' == *filePtr) { + while (true) { + if ('*' == *filePtr) { ++filePtr; - if (faceIdx != UINT_MAX && TokenMatch(filePtr,"MESH_VERTEXNORMAL",17)) { + if (faceIdx != UINT_MAX && TokenMatch(filePtr, "MESH_VERTEXNORMAL", 17)) { aiVector3D vNormal; - ParseLV4MeshFloatTriple(&vNormal.x,index); - if (faceIdx >= sMesh.mFaces.size()) + ParseLV4MeshFloatTriple(&vNormal.x, index); + if (faceIdx >= sMesh.mFaces.size()) continue; // Make sure we assign it to the correct face - const ASE::Face& face = sMesh.mFaces[faceIdx]; + const ASE::Face &face = sMesh.mFaces[faceIdx]; if (index == face.mIndices[0]) index = 0; else if (index == face.mIndices[1]) index = 1; else if (index == face.mIndices[2]) index = 2; - else { + else { ASSIMP_LOG_ERROR("ASE: Invalid vertex index in MESH_VERTEXNORMAL section"); continue; } // We'll renormalize later - sMesh.mNormals[faceIdx*3+index] += vNormal; + sMesh.mNormals[faceIdx * 3 + index] += vNormal; continue; } - if (TokenMatch(filePtr,"MESH_FACENORMAL",15)) { + if (TokenMatch(filePtr, "MESH_FACENORMAL", 15)) { aiVector3D vNormal; - ParseLV4MeshFloatTriple(&vNormal.x,faceIdx); + ParseLV4MeshFloatTriple(&vNormal.x, faceIdx); if (faceIdx >= sMesh.mFaces.size()) { ASSIMP_LOG_ERROR("ASE: Invalid vertex index in MESH_FACENORMAL section"); @@ -1934,53 +1668,47 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh) } // We'll renormalize later - sMesh.mNormals[faceIdx*3] += vNormal; - sMesh.mNormals[faceIdx*3+1] += vNormal; - sMesh.mNormals[faceIdx*3+2] += vNormal; + sMesh.mNormals[faceIdx * 3] += vNormal; + sMesh.mNormals[faceIdx * 3 + 1] += vNormal; + sMesh.mNormals[faceIdx * 3 + 2] += vNormal; continue; } } - AI_ASE_HANDLE_SECTION("3","*MESH_NORMALS"); + AI_ASE_HANDLE_SECTION("3", "*MESH_NORMALS"); } return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV4MeshFace(ASE::Face& out) -{ +void Parser::ParseLV4MeshFace(ASE::Face &out) { // skip spaces and tabs - if(!SkipSpaces(&filePtr)) - { + if (!SkipSpaces(&filePtr)) { LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL [#1]"); SkipToNextToken(); return; } // parse the face index - out.iFace = strtoul10(filePtr,&filePtr); + out.iFace = strtoul10(filePtr, &filePtr); // next character should be ':' - if(!SkipSpaces(&filePtr)) - { + if (!SkipSpaces(&filePtr)) { // FIX: there are some ASE files which haven't got : here .... LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. \':\' expected [#2]"); SkipToNextToken(); return; } // FIX: There are some ASE files which haven't got ':' here - if(':' == *filePtr)++filePtr; + if (':' == *filePtr) ++filePtr; // Parse all mesh indices - for (unsigned int i = 0; i < 3;++i) - { + for (unsigned int i = 0; i < 3; ++i) { unsigned int iIndex = 0; - if(!SkipSpaces(&filePtr)) - { + if (!SkipSpaces(&filePtr)) { LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL"); SkipToNextToken(); return; } - switch (*filePtr) - { + switch (*filePtr) { case 'A': case 'a': break; @@ -1994,38 +1722,34 @@ void Parser::ParseLV4MeshFace(ASE::Face& out) break; default: LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. " - "A,B or C expected [#3]"); + "A,B or C expected [#3]"); SkipToNextToken(); return; }; ++filePtr; // next character should be ':' - if(!SkipSpaces(&filePtr) || ':' != *filePtr) - { + if (!SkipSpaces(&filePtr) || ':' != *filePtr) { LogWarning("Unable to parse *MESH_FACE Element: " - "Unexpected EOL. \':\' expected [#2]"); + "Unexpected EOL. \':\' expected [#2]"); SkipToNextToken(); return; } ++filePtr; - if(!SkipSpaces(&filePtr)) - { + if (!SkipSpaces(&filePtr)) { LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. " - "Vertex index ecpected [#4]"); + "Vertex index ecpected [#4]"); SkipToNextToken(); return; } - out.mIndices[iIndex] = strtoul10(filePtr,&filePtr); + out.mIndices[iIndex] = strtoul10(filePtr, &filePtr); } // now we need to skip the AB, BC, CA blocks. - while (true) - { - if ('*' == *filePtr)break; - if (IsLineEnd(*filePtr)) - { + while (true) { + if ('*' == *filePtr) break; + if (IsLineEnd(*filePtr)) { //iLineNumber++; return; } @@ -2033,27 +1757,22 @@ void Parser::ParseLV4MeshFace(ASE::Face& out) } // parse the smoothing group of the face - if (TokenMatch(filePtr,"*MESH_SMOOTHING",15)) - { - if(!SkipSpaces(&filePtr)) - { + if (TokenMatch(filePtr, "*MESH_SMOOTHING", 15)) { + if (!SkipSpaces(&filePtr)) { LogWarning("Unable to parse *MESH_SMOOTHING Element: " - "Unexpected EOL. Smoothing group(s) expected [#5]"); + "Unexpected EOL. Smoothing group(s) expected [#5]"); SkipToNextToken(); return; } // Parse smoothing groups until we don't anymore see commas // FIX: There needn't always be a value, sad but true - while (true) - { - if (*filePtr < '9' && *filePtr >= '0') - { - out.iSmoothGroup |= (1 << strtoul10(filePtr,&filePtr)); + while (true) { + if (*filePtr < '9' && *filePtr >= '0') { + out.iSmoothGroup |= (1 << strtoul10(filePtr, &filePtr)); } SkipSpaces(&filePtr); - if (',' != *filePtr) - { + if (',' != *filePtr) { break; } ++filePtr; @@ -2062,41 +1781,37 @@ void Parser::ParseLV4MeshFace(ASE::Face& out) } // *MESH_MTLID is optional, too - while (true) - { - if ('*' == *filePtr)break; - if (IsLineEnd(*filePtr)) - { + while (true) { + if ('*' == *filePtr) { + break; + } + if (IsLineEnd(*filePtr)) { return; } filePtr++; } - if (TokenMatch(filePtr,"*MESH_MTLID",11)) - { - if(!SkipSpaces(&filePtr)) - { + if (TokenMatch(filePtr, "*MESH_MTLID", 11)) { + if (!SkipSpaces(&filePtr)) { LogWarning("Unable to parse *MESH_MTLID Element: Unexpected EOL. " - "Material index expected [#6]"); + "Material index expected [#6]"); SkipToNextToken(); return; } - out.iMaterial = strtoul10(filePtr,&filePtr); + out.iMaterial = strtoul10(filePtr, &filePtr); } return; } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV4MeshLongTriple(unsigned int* apOut) -{ - ai_assert(NULL != apOut); +void Parser::ParseLV4MeshLongTriple(unsigned int *apOut) { + ai_assert(nullptr != apOut); - for (unsigned int i = 0; i < 3;++i) + for (unsigned int i = 0; i < 3; ++i) ParseLV4MeshLong(apOut[i]); } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut) -{ - ai_assert(NULL != apOut); +void Parser::ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut) { + ai_assert(nullptr != apOut); // parse the index ParseLV4MeshLong(rIndexOut); @@ -2105,9 +1820,8 @@ void Parser::ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut ParseLV4MeshLongTriple(apOut); } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV4MeshFloatTriple(ai_real* apOut, unsigned int& rIndexOut) -{ - ai_assert(NULL != apOut); +void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) { + ai_assert(nullptr != apOut); // parse the index ParseLV4MeshLong(rIndexOut); @@ -2116,19 +1830,17 @@ void Parser::ParseLV4MeshFloatTriple(ai_real* apOut, unsigned int& rIndexOut) ParseLV4MeshFloatTriple(apOut); } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV4MeshFloatTriple(ai_real* apOut) -{ - ai_assert(NULL != apOut); +void Parser::ParseLV4MeshFloatTriple(ai_real *apOut) { + ai_assert(nullptr != apOut); - for (unsigned int i = 0; i < 3;++i) + for (unsigned int i = 0; i < 3; ++i) { ParseLV4MeshFloat(apOut[i]); + } } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV4MeshFloat(ai_real& fOut) -{ +void Parser::ParseLV4MeshFloat(ai_real &fOut) { // skip spaces and tabs - if(!SkipSpaces(&filePtr)) - { + if (!SkipSpaces(&filePtr)) { // LOG LogWarning("Unable to parse float: unexpected EOL [#1]"); fOut = 0.0; @@ -2136,14 +1848,12 @@ void Parser::ParseLV4MeshFloat(ai_real& fOut) return; } // parse the first float - filePtr = fast_atoreal_move(filePtr,fOut); + filePtr = fast_atoreal_move(filePtr, fOut); } // ------------------------------------------------------------------------------------------------ -void Parser::ParseLV4MeshLong(unsigned int& iOut) -{ +void Parser::ParseLV4MeshLong(unsigned int &iOut) { // Skip spaces and tabs - if(!SkipSpaces(&filePtr)) - { + if (!SkipSpaces(&filePtr)) { // LOG LogWarning("Unable to parse long: unexpected EOL [#1]"); iOut = 0; @@ -2151,7 +1861,7 @@ void Parser::ParseLV4MeshLong(unsigned int& iOut) return; } // parse the value - iOut = strtoul10(filePtr,&filePtr); + iOut = strtoul10(filePtr, &filePtr); } #endif // ASSIMP_BUILD_NO_3DS_IMPORTER diff --git a/Engine/lib/assimp/code/ASE/ASEParser.h b/Engine/lib/assimp/code/AssetLib/ASE/ASEParser.h similarity index 81% rename from Engine/lib/assimp/code/ASE/ASEParser.h rename to Engine/lib/assimp/code/AssetLib/ASE/ASEParser.h index 988cbda8d..5c24fffd1 100644 --- a/Engine/lib/assimp/code/ASE/ASEParser.h +++ b/Engine/lib/assimp/code/AssetLib/ASE/ASEParser.h @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -40,15 +40,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ - /** @file Defines the helper data structures for importing ASE files */ #ifndef AI_ASEFILEHELPER_H_INC #define AI_ASEFILEHELPER_H_INC // public ASSIMP headers -#include -#include #include +#include +#include #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER @@ -57,68 +56,73 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include // ASE is quite similar to 3ds. We can reuse some structures -#include "3DS/3DSLoader.h" +#include "AssetLib/3DS/3DSLoader.h" -namespace Assimp { -namespace ASE { +namespace Assimp { +namespace ASE { using namespace D3DS; // --------------------------------------------------------------------------- /** Helper structure representing an ASE material */ -struct Material : public D3DS::Material -{ +struct Material : public D3DS::Material { //! Default constructor has been deleted Material() = delete; //! Constructor with explicit name - explicit Material(const std::string &name) - : D3DS::Material(name) - , pcInstance(NULL) - , bNeed (false) { + explicit Material(const std::string &name) : + D3DS::Material(name), + pcInstance(nullptr), + bNeed(false) { // empty } - Material(const Material &other) = default; - Material &operator=(const Material &other) = default; + Material(const Material &other) = default; + Material &operator=(const Material &other) { + if (this == &other) { + return *this; + } + + avSubMaterials = other.avSubMaterials; + pcInstance = other.pcInstance; + bNeed = other.bNeed; + + return *this; + } //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it Material(Material &&other) AI_NO_EXCEPT - : D3DS::Material(std::move(other)) - , avSubMaterials(std::move(other.avSubMaterials)) - , pcInstance(std::move(other.pcInstance)) - , bNeed(std::move(other.bNeed)) - { + : D3DS::Material(std::move(other)), + avSubMaterials(std::move(other.avSubMaterials)), + pcInstance(other.pcInstance), + bNeed(other.bNeed) { other.pcInstance = nullptr; } - Material &operator=(Material &&other) AI_NO_EXCEPT { if (this == &other) { return *this; } - D3DS::Material::operator=(std::move(other)); + //D3DS::Material::operator=(std::move(other)); avSubMaterials = std::move(other.avSubMaterials); - pcInstance = std::move(other.pcInstance); - bNeed = std::move(other.bNeed); + pcInstance = other.pcInstance; + bNeed = other.bNeed; other.pcInstance = nullptr; return *this; } - ~Material() {} - //! Contains all sub materials of this material std::vector avSubMaterials; //! aiMaterial object - aiMaterial* pcInstance; + aiMaterial *pcInstance; //! Can we remove this material? bool bNeed; @@ -129,8 +133,8 @@ struct Material : public D3DS::Material struct Face : public FaceWithSmoothingGroup { //! Default constructor. Initializes everything with 0 Face() AI_NO_EXCEPT - : iMaterial(DEFAULT_MATINDEX) - , iFace(0) { + : iMaterial(DEFAULT_MATINDEX), + iFace(0) { // empty } @@ -161,8 +165,8 @@ struct Bone { Bone() = delete; //! Construction from an existing name - explicit Bone( const std::string& name) - : mName(name) { + explicit Bone(const std::string &name) : + mName(name) { // empty } @@ -175,33 +179,34 @@ struct Bone { struct BoneVertex { //! Bone and corresponding vertex weight. //! -1 for unrequired bones .... - std::vector > mBoneWeights; + std::vector> mBoneWeights; }; // --------------------------------------------------------------------------- /** Helper structure to represent an ASE file animation */ struct Animation { enum Type { - TRACK = 0x0, - BEZIER = 0x1, - TCB = 0x2 - } mRotationType, mScalingType, mPositionType; + TRACK = 0x0, + BEZIER = 0x1, + TCB = 0x2 + } mRotationType, + mScalingType, mPositionType; Animation() AI_NO_EXCEPT - : mRotationType (TRACK) - , mScalingType (TRACK) - , mPositionType (TRACK) { + : mRotationType(TRACK), + mScalingType(TRACK), + mPositionType(TRACK) { // empty } //! List of track rotation keyframes - std::vector< aiQuatKey > akeyRotations; + std::vector akeyRotations; //! List of track position keyframes - std::vector< aiVectorKey > akeyPositions; + std::vector akeyPositions; //! List of track scaling keyframes - std::vector< aiVectorKey > akeyScaling; + std::vector akeyScaling; }; // --------------------------------------------------------------------------- @@ -209,7 +214,7 @@ struct Animation { struct InheritanceInfo { //! Default constructor InheritanceInfo() AI_NO_EXCEPT { - for ( size_t i=0; i<3; ++i ) { + for (size_t i = 0; i < 3; ++i) { abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true; } } @@ -228,17 +233,15 @@ struct InheritanceInfo { /** Represents an ASE file node. Base class for mesh, light and cameras */ struct BaseNode { enum Type { - Light, - Camera, - Mesh, + Light, + Camera, + Mesh, Dummy } mType; //! Construction from an existing name - BaseNode(Type _mType, const std::string &name) - : mType (_mType) - , mName (name) - , mProcessed (false) { + BaseNode(Type _mType, const std::string &name) : + mType(_mType), mName(name), mProcessed(false) { // Set mTargetPosition to qnan const ai_real qnan = get_qnan(); mTargetPosition.x = qnan; @@ -278,14 +281,9 @@ struct Mesh : public MeshWithSmoothingGroups, public BaseNode { Mesh() = delete; //! Construction from an existing name - explicit Mesh(const std::string &name) - : BaseNode( BaseNode::Mesh, name ) - , mVertexColors() - , mBoneVertices() - , mBones() - , iMaterialIndex(Face::DEFAULT_MATINDEX) - , bSkip (false) { - for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) { + explicit Mesh(const std::string &name) : + BaseNode(BaseNode::Mesh, name), mVertexColors(), mBoneVertices(), mBones(), iMaterialIndex(Face::DEFAULT_MATINDEX), bSkip(false) { + for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c) { this->mNumUVComponents[c] = 2; } } @@ -314,10 +312,8 @@ struct Mesh : public MeshWithSmoothingGroups, public BaseNode { // --------------------------------------------------------------------------- /** Helper structure to represent an ASE light source */ -struct Light : public BaseNode -{ - enum LightType - { +struct Light : public BaseNode { + enum LightType { OMNI, TARGET, FREE, @@ -328,17 +324,13 @@ struct Light : public BaseNode Light() = delete; //! Construction from an existing name - explicit Light(const std::string &name) - : BaseNode (BaseNode::Light, name) - , mLightType (OMNI) - , mColor (1.f,1.f,1.f) - , mIntensity (1.f) // light is white by default - , mAngle (45.f) - , mFalloff (0.f) - { + explicit Light(const std::string &name) : + BaseNode(BaseNode::Light, name), mLightType(OMNI), mColor(1.f, 1.f, 1.f), mIntensity(1.f) // light is white by default + , + mAngle(45.f), + mFalloff(0.f) { } - LightType mLightType; aiColor3D mColor; ai_real mIntensity; @@ -348,10 +340,8 @@ struct Light : public BaseNode // --------------------------------------------------------------------------- /** Helper structure to represent an ASE camera */ -struct Camera : public BaseNode -{ - enum CameraType - { +struct Camera : public BaseNode { + enum CameraType { FREE, TARGET }; @@ -359,18 +349,16 @@ struct Camera : public BaseNode //! Default constructor has been deleted Camera() = delete; - //! Construction from an existing name - explicit Camera(const std::string &name) - : BaseNode (BaseNode::Camera, name) - , mFOV (0.75f) // in radians - , mNear (0.1f) - , mFar (1000.f) // could be zero - , mCameraType (FREE) - { + explicit Camera(const std::string &name) : + BaseNode(BaseNode::Camera, name), mFOV(0.75f) // in radians + , + mNear(0.1f), + mFar(1000.f) // could be zero + , + mCameraType(FREE) { } - ai_real mFOV, mNear, mFar; CameraType mCameraType; }; @@ -380,7 +368,7 @@ struct Camera : public BaseNode struct Dummy : public BaseNode { //! Constructor Dummy() AI_NO_EXCEPT - : BaseNode (BaseNode::Dummy, "DUMMY") { + : BaseNode(BaseNode::Dummy, "DUMMY") { // empty } }; @@ -403,7 +391,6 @@ private: } public: - // ------------------------------------------------------------------- //! Construct a parser from a given input file which is //! guaranteed to be terminated with zero. @@ -411,15 +398,13 @@ public: //! @param fileFormatDefault Assumed file format version. If the //! file format is specified in the file the new value replaces //! the default value. - Parser (const char* szFile, unsigned int fileFormatDefault); + Parser(const char *szFile, unsigned int fileFormatDefault); // ------------------------------------------------------------------- //! Parses the file into the parsers internal representation void Parse(); - private: - // ------------------------------------------------------------------- //! Parse the *SCENE block in a file void ParseLV1SceneBlock(); @@ -435,45 +420,45 @@ private: // ------------------------------------------------------------------- //! Parse a *OBJECT block in a file //! \param mesh Node to be filled - void ParseLV1ObjectBlock(BaseNode& mesh); + void ParseLV1ObjectBlock(BaseNode &mesh); // ------------------------------------------------------------------- //! Parse a *MATERIAL blocks in a material list //! \param mat Material structure to be filled - void ParseLV2MaterialBlock(Material& mat); + void ParseLV2MaterialBlock(Material &mat); // ------------------------------------------------------------------- //! Parse a *NODE_TM block in a file //! \param mesh Node (!) object to be filled - void ParseLV2NodeTransformBlock(BaseNode& mesh); + void ParseLV2NodeTransformBlock(BaseNode &mesh); // ------------------------------------------------------------------- //! Parse a *TM_ANIMATION block in a file //! \param mesh Mesh object to be filled - void ParseLV2AnimationBlock(BaseNode& mesh); - void ParseLV3PosAnimationBlock(ASE::Animation& anim); - void ParseLV3ScaleAnimationBlock(ASE::Animation& anim); - void ParseLV3RotAnimationBlock(ASE::Animation& anim); + void ParseLV2AnimationBlock(BaseNode &mesh); + void ParseLV3PosAnimationBlock(ASE::Animation &anim); + void ParseLV3ScaleAnimationBlock(ASE::Animation &anim); + void ParseLV3RotAnimationBlock(ASE::Animation &anim); // ------------------------------------------------------------------- //! Parse a *MESH block in a file //! \param mesh Mesh object to be filled - void ParseLV2MeshBlock(Mesh& mesh); + void ParseLV2MeshBlock(Mesh &mesh); // ------------------------------------------------------------------- //! Parse a *LIGHT_SETTINGS block in a file //! \param light Light object to be filled - void ParseLV2LightSettingsBlock(Light& light); + void ParseLV2LightSettingsBlock(Light &light); // ------------------------------------------------------------------- //! Parse a *CAMERA_SETTINGS block in a file //! \param cam Camera object to be filled - void ParseLV2CameraSettingsBlock(Camera& cam); + void ParseLV2CameraSettingsBlock(Camera &cam); // ------------------------------------------------------------------- //! Parse the *MAP_XXXXXX blocks in a material //! \param map Texture structure to be filled - void ParseLV3MapBlock(Texture& map); + void ParseLV3MapBlock(Texture &map); // ------------------------------------------------------------------- //! Parse a *MESH_VERTEX_LIST block in a file @@ -482,7 +467,7 @@ private: //! A warning is sent to the logger if the validations fails. //! \param mesh Mesh object to be filled void ParseLV3MeshVertexListBlock( - unsigned int iNumVertices,Mesh& mesh); + unsigned int iNumVertices, Mesh &mesh); // ------------------------------------------------------------------- //! Parse a *MESH_FACE_LIST block in a file @@ -491,7 +476,7 @@ private: //! A warning is sent to the logger if the validations fails. //! \param mesh Mesh object to be filled void ParseLV3MeshFaceListBlock( - unsigned int iNumFaces,Mesh& mesh); + unsigned int iNumFaces, Mesh &mesh); // ------------------------------------------------------------------- //! Parse a *MESH_TVERT_LIST block in a file @@ -501,7 +486,7 @@ private: //! \param mesh Mesh object to be filled //! \param iChannel Output UVW channel void ParseLV3MeshTListBlock( - unsigned int iNumVertices,Mesh& mesh, unsigned int iChannel = 0); + unsigned int iNumVertices, Mesh &mesh, unsigned int iChannel = 0); // ------------------------------------------------------------------- //! Parse a *MESH_TFACELIST block in a file @@ -511,7 +496,7 @@ private: //! \param mesh Mesh object to be filled //! \param iChannel Output UVW channel void ParseLV3MeshTFaceListBlock( - unsigned int iNumFaces,Mesh& mesh, unsigned int iChannel = 0); + unsigned int iNumFaces, Mesh &mesh, unsigned int iChannel = 0); // ------------------------------------------------------------------- //! Parse an additional mapping channel @@ -519,7 +504,7 @@ private: //! \param iChannel Channel index to be filled //! \param mesh Mesh object to be filled void ParseLV3MappingChannel( - unsigned int iChannel, Mesh& mesh); + unsigned int iChannel, Mesh &mesh); // ------------------------------------------------------------------- //! Parse a *MESH_CVERTLIST block in a file @@ -528,7 +513,7 @@ private: //! A warning is sent to the logger if the validations fails. //! \param mesh Mesh object to be filled void ParseLV3MeshCListBlock( - unsigned int iNumVertices, Mesh& mesh); + unsigned int iNumVertices, Mesh &mesh); // ------------------------------------------------------------------- //! Parse a *MESH_CFACELIST block in a file @@ -537,70 +522,70 @@ private: //! A warning is sent to the logger if the validations fails. //! \param mesh Mesh object to be filled void ParseLV3MeshCFaceListBlock( - unsigned int iNumFaces, Mesh& mesh); + unsigned int iNumFaces, Mesh &mesh); // ------------------------------------------------------------------- //! Parse a *MESH_NORMALS block in a file //! \param mesh Mesh object to be filled - void ParseLV3MeshNormalListBlock(Mesh& mesh); + void ParseLV3MeshNormalListBlock(Mesh &mesh); // ------------------------------------------------------------------- //! Parse a *MESH_WEIGHTSblock in a file //! \param mesh Mesh object to be filled - void ParseLV3MeshWeightsBlock(Mesh& mesh); + void ParseLV3MeshWeightsBlock(Mesh &mesh); // ------------------------------------------------------------------- //! Parse the bone list of a file //! \param mesh Mesh object to be filled //! \param iNumBones Number of bones in the mesh - void ParseLV4MeshBones(unsigned int iNumBones,Mesh& mesh); + void ParseLV4MeshBones(unsigned int iNumBones, Mesh &mesh); // ------------------------------------------------------------------- //! Parse the bone vertices list of a file //! \param mesh Mesh object to be filled //! \param iNumVertices Number of vertices to be parsed - void ParseLV4MeshBonesVertices(unsigned int iNumVertices,Mesh& mesh); + void ParseLV4MeshBonesVertices(unsigned int iNumVertices, Mesh &mesh); // ------------------------------------------------------------------- //! Parse a *MESH_FACE block in a file //! \param out receive the face data - void ParseLV4MeshFace(ASE::Face& out); + void ParseLV4MeshFace(ASE::Face &out); // ------------------------------------------------------------------- //! Parse a *MESH_VERT block in a file //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...) //! \param apOut Output buffer (3 floats) //! \param rIndexOut Output index - void ParseLV4MeshFloatTriple(ai_real* apOut, unsigned int& rIndexOut); + void ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut); // ------------------------------------------------------------------- //! Parse a *MESH_VERT block in a file //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...) //! \param apOut Output buffer (3 floats) - void ParseLV4MeshFloatTriple(ai_real* apOut); + void ParseLV4MeshFloatTriple(ai_real *apOut); // ------------------------------------------------------------------- //! Parse a *MESH_TFACE block in a file //! (also works for MESH_CFACE) //! \param apOut Output buffer (3 ints) //! \param rIndexOut Output index - void ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut); + void ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut); // ------------------------------------------------------------------- //! Parse a *MESH_TFACE block in a file //! (also works for MESH_CFACE) //! \param apOut Output buffer (3 ints) - void ParseLV4MeshLongTriple(unsigned int* apOut); + void ParseLV4MeshLongTriple(unsigned int *apOut); // ------------------------------------------------------------------- //! Parse a single float element //! \param fOut Output float - void ParseLV4MeshFloat(ai_real& fOut); + void ParseLV4MeshFloat(ai_real &fOut); // ------------------------------------------------------------------- //! Parse a single int element //! \param iOut Output integer - void ParseLV4MeshLong(unsigned int& iOut); + void ParseLV4MeshLong(unsigned int &iOut); // ------------------------------------------------------------------- //! Skip everything to the next: '*' or '\0' @@ -614,17 +599,17 @@ private: // ------------------------------------------------------------------- //! Output a warning to the logger //! \param szWarn Warn message - void LogWarning(const char* szWarn); + void LogWarning(const char *szWarn); // ------------------------------------------------------------------- //! Output a message to the logger //! \param szWarn Message - void LogInfo(const char* szWarn); + void LogInfo(const char *szWarn); // ------------------------------------------------------------------- //! Output an error to the logger //! \param szWarn Error message - AI_WONT_RETURN void LogError(const char* szWarn) AI_WONT_RETURN_SUFFIX; + AI_WONT_RETURN void LogError(const char *szWarn) AI_WONT_RETURN_SUFFIX; // ------------------------------------------------------------------- //! Parse a string, enclosed in double quotation marks @@ -632,12 +617,11 @@ private: //! \param szName Name of the enclosing element -> used in error //! messages. //! \return false if an error occurred - bool ParseString(std::string& out,const char* szName); + bool ParseString(std::string &out, const char *szName); public: - //! Pointer to current data - const char* filePtr; + const char *filePtr; //! background color to be passed to the viewer //! QNAN if none was found @@ -684,9 +668,8 @@ public: unsigned int iFileFormat; }; - } // Namespace ASE -} // Namespace ASSIMP +} // namespace Assimp #endif // ASSIMP_BUILD_NO_3DS_IMPORTER diff --git a/Engine/lib/assimp/code/AssetLib/Assbin/AssbinExporter.cpp b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinExporter.cpp new file mode 100644 index 000000000..149b3c5f3 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinExporter.cpp @@ -0,0 +1,68 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +/** @file AssbinExporter.cpp + * ASSBIN exporter main code + */ + +#ifndef ASSIMP_BUILD_NO_EXPORT +#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER + +#include "AssbinFileWriter.h" + +#include +#include +#include + +namespace Assimp { + +void ExportSceneAssbin(const char *pFile, IOSystem *pIOSystem, const aiScene *pScene, const ExportProperties * /*pProperties*/) { + DumpSceneToAssbin( + pFile, + "\0", // no command(s). + pIOSystem, + pScene, + false, // shortened? + false); // compressed? +} +} // end of namespace Assimp + +#endif // ASSIMP_BUILD_NO_ASSBIN_EXPORTER +#endif // ASSIMP_BUILD_NO_EXPORT diff --git a/Engine/lib/assimp/code/Assbin/AssbinExporter.h b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinExporter.h similarity index 95% rename from Engine/lib/assimp/code/Assbin/AssbinExporter.h rename to Engine/lib/assimp/code/AssetLib/Assbin/AssbinExporter.h index 3e13639bb..1801c1680 100644 --- a/Engine/lib/assimp/code/Assbin/AssbinExporter.h +++ b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinExporter.h @@ -2,8 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -43,16 +42,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** @file AssbinExporter.h * ASSBIN Exporter Main Header */ +#pragma once #ifndef AI_ASSBINEXPORTER_H_INC #define AI_ASSBINEXPORTER_H_INC #include +#ifndef ASSIMP_BUILD_NO_EXPORT + // nothing really needed here - reserved for future use like properties namespace Assimp { void ASSIMP_API ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/); } - +#endif #endif // AI_ASSBINEXPORTER_H_INC diff --git a/Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.cpp b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.cpp new file mode 100644 index 000000000..1d16f179e --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.cpp @@ -0,0 +1,833 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +/** @file AssbinFileWriter.cpp + * @brief Implementation of Assbin file writer. + */ + +#include "AssbinFileWriter.h" +#include "Common/assbin_chunks.h" +#include "PostProcessing/ProcessHelper.h" + +#include +#include +#include + +#ifdef ASSIMP_BUILD_NO_OWN_ZLIB +#include +#else +#include "../contrib/zlib/zlib.h" +#endif + +#include + +#if _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4706) +#endif // _MSC_VER + +namespace Assimp { + +template +size_t Write(IOStream *stream, const T &v) { + return stream->Write(&v, sizeof(T), 1); +} + +// ----------------------------------------------------------------------------------- +// Serialize an aiString +template <> +inline size_t Write(IOStream *stream, const aiString &s) { + const size_t s2 = (uint32_t)s.length; + stream->Write(&s, 4, 1); + stream->Write(s.data, s2, 1); + + return s2 + 4; +} + +// ----------------------------------------------------------------------------------- +// Serialize an unsigned int as uint32_t +template <> +inline size_t Write(IOStream *stream, const unsigned int &w) { + const uint32_t t = (uint32_t)w; + if (w > t) { + // this shouldn't happen, integers in Assimp data structures never exceed 2^32 + throw DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion"); + } + + stream->Write(&t, 4, 1); + + return 4; +} + +// ----------------------------------------------------------------------------------- +// Serialize an unsigned int as uint16_t +template <> +inline size_t Write(IOStream *stream, const uint16_t &w) { + static_assert(sizeof(uint16_t) == 2, "sizeof(uint16_t)==2"); + stream->Write(&w, 2, 1); + + return 2; +} + +// ----------------------------------------------------------------------------------- +// Serialize a float +template <> +inline size_t Write(IOStream *stream, const float &f) { + static_assert(sizeof(float) == 4, "sizeof(float)==4"); + stream->Write(&f, 4, 1); + + return 4; +} + +// ----------------------------------------------------------------------------------- +// Serialize a double +template <> +inline size_t Write(IOStream *stream, const double &f) { + static_assert(sizeof(double) == 8, "sizeof(double)==8"); + stream->Write(&f, 8, 1); + + return 8; +} + +// ----------------------------------------------------------------------------------- +// Serialize a vec3 +template <> +inline size_t Write(IOStream *stream, const aiVector3D &v) { + size_t t = Write(stream, v.x); + t += Write(stream, v.y); + t += Write(stream, v.z); + + return t; +} + +// ----------------------------------------------------------------------------------- +// Serialize a color value +template <> +inline size_t Write(IOStream *stream, const aiColor3D &v) { + size_t t = Write(stream, v.r); + t += Write(stream, v.g); + t += Write(stream, v.b); + + return t; +} + +// ----------------------------------------------------------------------------------- +// Serialize a color value +template <> +inline size_t Write(IOStream *stream, const aiColor4D &v) { + size_t t = Write(stream, v.r); + t += Write(stream, v.g); + t += Write(stream, v.b); + t += Write(stream, v.a); + + return t; +} + +// ----------------------------------------------------------------------------------- +// Serialize a quaternion +template <> +inline size_t Write(IOStream *stream, const aiQuaternion &v) { + size_t t = Write(stream, v.w); + t += Write(stream, v.x); + t += Write(stream, v.y); + t += Write(stream, v.z); + ai_assert(t == 16); + + return t; +} + +// ----------------------------------------------------------------------------------- +// Serialize a vertex weight +template <> +inline size_t Write(IOStream *stream, const aiVertexWeight &v) { + size_t t = Write(stream, v.mVertexId); + + return t + Write(stream, v.mWeight); +} + +constexpr size_t MatrixSize = 64; + +// ----------------------------------------------------------------------------------- +// Serialize a mat4x4 +template <> +inline size_t Write(IOStream *stream, const aiMatrix4x4 &m) { + for (unsigned int i = 0; i < 4; ++i) { + for (unsigned int i2 = 0; i2 < 4; ++i2) { + Write(stream, m[i][i2]); + } + } + + return MatrixSize; +} + +// ----------------------------------------------------------------------------------- +// Serialize an aiVectorKey +template <> +inline size_t Write(IOStream *stream, const aiVectorKey &v) { + const size_t t = Write(stream, v.mTime); + return t + Write(stream, v.mValue); +} + +// ----------------------------------------------------------------------------------- +// Serialize an aiQuatKey +template <> +inline size_t Write(IOStream *stream, const aiQuatKey &v) { + const size_t t = Write(stream, v.mTime); + return t + Write(stream, v.mValue); +} + +template +inline size_t WriteBounds(IOStream *stream, const T *in, unsigned int size) { + T minc, maxc; + ArrayBounds(in, size, minc, maxc); + + const size_t t = Write(stream, minc); + return t + Write(stream, maxc); +} + +// We use this to write out non-byte arrays so that we write using the specializations. +// This way we avoid writing out extra bytes that potentially come from struct alignment. +template +inline size_t WriteArray(IOStream *stream, const T *in, unsigned int size) { + size_t n = 0; + for (unsigned int i = 0; i < size; i++) + n += Write(stream, in[i]); + + return n; +} + +// ---------------------------------------------------------------------------------- +/** @class AssbinChunkWriter + * @brief Chunk writer mechanism for the .assbin file structure + * + * This is a standard in-memory IOStream (most of the code is based on BlobIOStream), + * the difference being that this takes another IOStream as a "container" in the + * constructor, and when it is destroyed, it appends the magic number, the chunk size, + * and the chunk contents to the container stream. This allows relatively easy chunk + * chunk construction, even recursively. + */ +class AssbinChunkWriter : public IOStream { +private: + uint8_t *buffer; + uint32_t magic; + IOStream *container; + size_t cur_size, cursor, initial; + +private: + // ------------------------------------------------------------------- + void Grow(size_t need = 0) { + size_t new_size = std::max(initial, std::max(need, cur_size + (cur_size >> 1))); + + const uint8_t *const old = buffer; + buffer = new uint8_t[new_size]; + + if (old) { + memcpy(buffer, old, cur_size); + delete[] old; + } + + cur_size = new_size; + } + +public: + AssbinChunkWriter(IOStream *container, uint32_t magic, size_t initial = 4096) : + buffer(nullptr), + magic(magic), + container(container), + cur_size(0), + cursor(0), + initial(initial) { + // empty + } + + ~AssbinChunkWriter() override { + if (container) { + container->Write(&magic, sizeof(uint32_t), 1); + container->Write(&cursor, sizeof(uint32_t), 1); + container->Write(buffer, 1, cursor); + } + if (buffer) delete[] buffer; + } + + void *GetBufferPointer() { return buffer; } + + size_t Read(void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) override { + return 0; + } + + aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) override { + return aiReturn_FAILURE; + } + + size_t Tell() const override { + return cursor; + } + + void Flush() override { + // not implemented + } + + size_t FileSize() const override { + return cursor; + } + + size_t Write(const void *pvBuffer, size_t pSize, size_t pCount) override { + pSize *= pCount; + if (cursor + pSize > cur_size) { + Grow(cursor + pSize); + } + + memcpy(buffer + cursor, pvBuffer, pSize); + cursor += pSize; + + return pCount; + } +}; + +// ---------------------------------------------------------------------------------- +/** @class AssbinFileWriter + * @brief Assbin file writer class + * + * This class writes an .assbin file, and is responsible for the file layout. + */ +class AssbinFileWriter { +private: + bool shortened; + bool compressed; + +protected: + // ----------------------------------------------------------------------------------- + void WriteBinaryNode(IOStream *container, const aiNode *node) { + AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODE); + + unsigned int nb_metadata = (node->mMetaData != nullptr ? node->mMetaData->mNumProperties : 0); + + Write(&chunk, node->mName); + Write(&chunk, node->mTransformation); + Write(&chunk, node->mNumChildren); + Write(&chunk, node->mNumMeshes); + Write(&chunk, nb_metadata); + + for (unsigned int i = 0; i < node->mNumMeshes; ++i) { + Write(&chunk, node->mMeshes[i]); + } + + for (unsigned int i = 0; i < node->mNumChildren; ++i) { + WriteBinaryNode(&chunk, node->mChildren[i]); + } + + for (unsigned int i = 0; i < nb_metadata; ++i) { + const aiString &key = node->mMetaData->mKeys[i]; + aiMetadataType type = node->mMetaData->mValues[i].mType; + void *value = node->mMetaData->mValues[i].mData; + + Write(&chunk, key); + Write(&chunk, (uint16_t)type); + + switch (type) { + case AI_BOOL: + Write(&chunk, *((bool *)value)); + break; + case AI_INT32: + Write(&chunk, *((int32_t *)value)); + break; + case AI_UINT64: + Write(&chunk, *((uint64_t *)value)); + break; + case AI_FLOAT: + Write(&chunk, *((float *)value)); + break; + case AI_DOUBLE: + Write(&chunk, *((double *)value)); + break; + case AI_AISTRING: + Write(&chunk, *((aiString *)value)); + break; + case AI_AIVECTOR3D: + Write(&chunk, *((aiVector3D *)value)); + break; +#ifdef SWIG + case FORCE_32BIT: +#endif // SWIG + default: + break; + } + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryTexture(IOStream *container, const aiTexture *tex) { + AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AITEXTURE); + + Write(&chunk, tex->mWidth); + Write(&chunk, tex->mHeight); + // Write the texture format, but don't include the null terminator. + chunk.Write(tex->achFormatHint, sizeof(char), HINTMAXTEXTURELEN - 1); + + if (!shortened) { + if (!tex->mHeight) { + chunk.Write(tex->pcData, 1, tex->mWidth); + } else { + chunk.Write(tex->pcData, 1, tex->mWidth * tex->mHeight * 4); + } + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryBone(IOStream *container, const aiBone *b) { + AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIBONE); + + Write(&chunk, b->mName); + Write(&chunk, b->mNumWeights); + Write(&chunk, b->mOffsetMatrix); + + // for the moment we write dumb min/max values for the bones, too. + // maybe I'll add a better, hash-like solution later + if (shortened) { + WriteBounds(&chunk, b->mWeights, b->mNumWeights); + } // else write as usual + else + WriteArray(&chunk, b->mWeights, b->mNumWeights); + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryMesh(IOStream *container, const aiMesh *mesh) { + AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMESH); + + Write(&chunk, mesh->mPrimitiveTypes); + Write(&chunk, mesh->mNumVertices); + Write(&chunk, mesh->mNumFaces); + Write(&chunk, mesh->mNumBones); + Write(&chunk, mesh->mMaterialIndex); + + // first of all, write bits for all existent vertex components + unsigned int c = 0; + if (mesh->mVertices) { + c |= ASSBIN_MESH_HAS_POSITIONS; + } + if (mesh->mNormals) { + c |= ASSBIN_MESH_HAS_NORMALS; + } + if (mesh->mTangents && mesh->mBitangents) { + c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS; + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++n) { + if (!mesh->mTextureCoords[n]) { + break; + } + c |= ASSBIN_MESH_HAS_TEXCOORD(n); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS; ++n) { + if (!mesh->mColors[n]) { + break; + } + c |= ASSBIN_MESH_HAS_COLOR(n); + } + Write(&chunk, c); + + aiVector3D minVec, maxVec; + if (mesh->mVertices) { + if (shortened) { + WriteBounds(&chunk, mesh->mVertices, mesh->mNumVertices); + } // else write as usual + else + WriteArray(&chunk, mesh->mVertices, mesh->mNumVertices); + } + if (mesh->mNormals) { + if (shortened) { + WriteBounds(&chunk, mesh->mNormals, mesh->mNumVertices); + } // else write as usual + else + WriteArray(&chunk, mesh->mNormals, mesh->mNumVertices); + } + if (mesh->mTangents && mesh->mBitangents) { + if (shortened) { + WriteBounds(&chunk, mesh->mTangents, mesh->mNumVertices); + WriteBounds(&chunk, mesh->mBitangents, mesh->mNumVertices); + } // else write as usual + else { + WriteArray(&chunk, mesh->mTangents, mesh->mNumVertices); + WriteArray(&chunk, mesh->mBitangents, mesh->mNumVertices); + } + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS; ++n) { + if (!mesh->mColors[n]) + break; + + if (shortened) { + WriteBounds(&chunk, mesh->mColors[n], mesh->mNumVertices); + } // else write as usual + else + WriteArray(&chunk, mesh->mColors[n], mesh->mNumVertices); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++n) { + if (!mesh->mTextureCoords[n]) + break; + + // write number of UV components + Write(&chunk, mesh->mNumUVComponents[n]); + + if (shortened) { + WriteBounds(&chunk, mesh->mTextureCoords[n], mesh->mNumVertices); + } // else write as usual + else + WriteArray(&chunk, mesh->mTextureCoords[n], mesh->mNumVertices); + } + + // write faces. There are no floating-point calculations involved + // in these, so we can write a simple hash over the face data + // to the dump file. We generate a single 32 Bit hash for 512 faces + // using Assimp's standard hashing function. + if (shortened) { + unsigned int processed = 0; + for (unsigned int job; (job = std::min(mesh->mNumFaces - processed, 512u)); processed += job) { + uint32_t hash = 0; + for (unsigned int a = 0; a < job; ++a) { + + const aiFace &f = mesh->mFaces[processed + a]; + uint32_t tmp = f.mNumIndices; + hash = SuperFastHash(reinterpret_cast(&tmp), sizeof tmp, hash); + for (unsigned int i = 0; i < f.mNumIndices; ++i) { + static_assert(AI_MAX_VERTICES <= 0xffffffff, "AI_MAX_VERTICES <= 0xffffffff"); + tmp = static_cast(f.mIndices[i]); + hash = SuperFastHash(reinterpret_cast(&tmp), sizeof tmp, hash); + } + } + Write(&chunk, hash); + } + } else // else write as usual + { + // if there are less than 2^16 vertices, we can simply use 16 bit integers ... + for (unsigned int i = 0; i < mesh->mNumFaces; ++i) { + const aiFace &f = mesh->mFaces[i]; + + static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff"); + Write(&chunk, static_cast(f.mNumIndices)); + + for (unsigned int a = 0; a < f.mNumIndices; ++a) { + if (mesh->mNumVertices < (1u << 16)) { + Write(&chunk, static_cast(f.mIndices[a])); + } else { + Write(&chunk, f.mIndices[a]); + } + } + } + } + + // write bones + if (mesh->mNumBones) { + for (unsigned int a = 0; a < mesh->mNumBones; ++a) { + const aiBone *b = mesh->mBones[a]; + WriteBinaryBone(&chunk, b); + } + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryMaterialProperty(IOStream *container, const aiMaterialProperty *prop) { + AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMATERIALPROPERTY); + + Write(&chunk, prop->mKey); + Write(&chunk, prop->mSemantic); + Write(&chunk, prop->mIndex); + + Write(&chunk, prop->mDataLength); + Write(&chunk, (unsigned int)prop->mType); + chunk.Write(prop->mData, 1, prop->mDataLength); + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryMaterial(IOStream *container, const aiMaterial *mat) { + AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMATERIAL); + + Write(&chunk, mat->mNumProperties); + for (unsigned int i = 0; i < mat->mNumProperties; ++i) { + WriteBinaryMaterialProperty(&chunk, mat->mProperties[i]); + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryNodeAnim(IOStream *container, const aiNodeAnim *nd) { + AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODEANIM); + + Write(&chunk, nd->mNodeName); + Write(&chunk, nd->mNumPositionKeys); + Write(&chunk, nd->mNumRotationKeys); + Write(&chunk, nd->mNumScalingKeys); + Write(&chunk, nd->mPreState); + Write(&chunk, nd->mPostState); + + if (nd->mPositionKeys) { + if (shortened) { + WriteBounds(&chunk, nd->mPositionKeys, nd->mNumPositionKeys); + + } // else write as usual + else + WriteArray(&chunk, nd->mPositionKeys, nd->mNumPositionKeys); + } + if (nd->mRotationKeys) { + if (shortened) { + WriteBounds(&chunk, nd->mRotationKeys, nd->mNumRotationKeys); + + } // else write as usual + else + WriteArray(&chunk, nd->mRotationKeys, nd->mNumRotationKeys); + } + if (nd->mScalingKeys) { + if (shortened) { + WriteBounds(&chunk, nd->mScalingKeys, nd->mNumScalingKeys); + + } // else write as usual + else + WriteArray(&chunk, nd->mScalingKeys, nd->mNumScalingKeys); + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryAnim(IOStream *container, const aiAnimation *anim) { + AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIANIMATION); + + Write(&chunk, anim->mName); + Write(&chunk, anim->mDuration); + Write(&chunk, anim->mTicksPerSecond); + Write(&chunk, anim->mNumChannels); + + for (unsigned int a = 0; a < anim->mNumChannels; ++a) { + const aiNodeAnim *nd = anim->mChannels[a]; + WriteBinaryNodeAnim(&chunk, nd); + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryLight(IOStream *container, const aiLight *l) { + AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AILIGHT); + + Write(&chunk, l->mName); + Write(&chunk, l->mType); + + if (l->mType != aiLightSource_DIRECTIONAL) { + Write(&chunk, l->mAttenuationConstant); + Write(&chunk, l->mAttenuationLinear); + Write(&chunk, l->mAttenuationQuadratic); + } + + Write(&chunk, l->mColorDiffuse); + Write(&chunk, l->mColorSpecular); + Write(&chunk, l->mColorAmbient); + + if (l->mType == aiLightSource_SPOT) { + Write(&chunk, l->mAngleInnerCone); + Write(&chunk, l->mAngleOuterCone); + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryCamera(IOStream *container, const aiCamera *cam) { + AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AICAMERA); + + Write(&chunk, cam->mName); + Write(&chunk, cam->mPosition); + Write(&chunk, cam->mLookAt); + Write(&chunk, cam->mUp); + Write(&chunk, cam->mHorizontalFOV); + Write(&chunk, cam->mClipPlaneNear); + Write(&chunk, cam->mClipPlaneFar); + Write(&chunk, cam->mAspect); + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryScene(IOStream *container, const aiScene *scene) { + AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AISCENE); + + // basic scene information + Write(&chunk, scene->mFlags); + Write(&chunk, scene->mNumMeshes); + Write(&chunk, scene->mNumMaterials); + Write(&chunk, scene->mNumAnimations); + Write(&chunk, scene->mNumTextures); + Write(&chunk, scene->mNumLights); + Write(&chunk, scene->mNumCameras); + + // write node graph + WriteBinaryNode(&chunk, scene->mRootNode); + + // write all meshes + for (unsigned int i = 0; i < scene->mNumMeshes; ++i) { + const aiMesh *mesh = scene->mMeshes[i]; + WriteBinaryMesh(&chunk, mesh); + } + + // write materials + for (unsigned int i = 0; i < scene->mNumMaterials; ++i) { + const aiMaterial *mat = scene->mMaterials[i]; + WriteBinaryMaterial(&chunk, mat); + } + + // write all animations + for (unsigned int i = 0; i < scene->mNumAnimations; ++i) { + const aiAnimation *anim = scene->mAnimations[i]; + WriteBinaryAnim(&chunk, anim); + } + + // write all textures + for (unsigned int i = 0; i < scene->mNumTextures; ++i) { + const aiTexture *mesh = scene->mTextures[i]; + WriteBinaryTexture(&chunk, mesh); + } + + // write lights + for (unsigned int i = 0; i < scene->mNumLights; ++i) { + const aiLight *l = scene->mLights[i]; + WriteBinaryLight(&chunk, l); + } + + // write cameras + for (unsigned int i = 0; i < scene->mNumCameras; ++i) { + const aiCamera *cam = scene->mCameras[i]; + WriteBinaryCamera(&chunk, cam); + } + } + +public: + AssbinFileWriter(bool shortened, bool compressed) : + shortened(shortened), compressed(compressed) { + } + + // ----------------------------------------------------------------------------------- + // Write a binary model dump + void WriteBinaryDump(const char *pFile, const char *cmd, IOSystem *pIOSystem, const aiScene *pScene) { + IOStream *out = pIOSystem->Open(pFile, "wb"); + if (!out) + throw std::runtime_error("Unable to open output file " + std::string(pFile) + '\n'); + + auto CloseIOStream = [&]() { + if (out) { + pIOSystem->Close(out); + out = nullptr; // Ensure this is only done once. + } + }; + + try { + time_t tt = time(nullptr); +#if _WIN32 + tm *p = gmtime(&tt); +#else + struct tm now; + tm *p = gmtime_r(&tt, &now); +#endif + + // header + char s[64]; + memset(s, 0, 64); +#if _MSC_VER >= 1400 + sprintf_s(s, "ASSIMP.binary-dump.%s", asctime(p)); +#else + ai_snprintf(s, 64, "ASSIMP.binary-dump.%s", asctime(p)); +#endif + out->Write(s, 44, 1); + // == 44 bytes + + Write(out, ASSBIN_VERSION_MAJOR); + Write(out, ASSBIN_VERSION_MINOR); + Write(out, aiGetVersionRevision()); + Write(out, aiGetCompileFlags()); + Write(out, shortened); + Write(out, compressed); + // == 20 bytes + + char buff[256] = { 0 }; + ai_snprintf(buff, 256, "%s", pFile); + out->Write(buff, sizeof(char), 256); + + memset(buff, 0, sizeof(buff)); + ai_snprintf(buff, 128, "%s", cmd); + out->Write(buff, sizeof(char), 128); + + // leave 64 bytes free for future extensions + memset(buff, 0xcd, 64); + out->Write(buff, sizeof(char), 64); + // == 435 bytes + + // ==== total header size: 512 bytes + ai_assert(out->Tell() == ASSBIN_HEADER_LENGTH); + + // Up to here the data is uncompressed. For compressed files, the rest + // is compressed using standard DEFLATE from zlib. + if (compressed) { + AssbinChunkWriter uncompressedStream(nullptr, 0); + WriteBinaryScene(&uncompressedStream, pScene); + + uLongf uncompressedSize = static_cast(uncompressedStream.Tell()); + uLongf compressedSize = (uLongf)compressBound(uncompressedSize); + uint8_t *compressedBuffer = new uint8_t[compressedSize]; + + int res = compress2(compressedBuffer, &compressedSize, (const Bytef *)uncompressedStream.GetBufferPointer(), uncompressedSize, 9); + if (res != Z_OK) { + delete[] compressedBuffer; + throw DeadlyExportError("Compression failed."); + } + + out->Write(&uncompressedSize, sizeof(uint32_t), 1); + out->Write(compressedBuffer, sizeof(char), compressedSize); + + delete[] compressedBuffer; + } else { + WriteBinaryScene(out, pScene); + } + + CloseIOStream(); + } catch (...) { + CloseIOStream(); + throw; + } + } +}; + +void DumpSceneToAssbin( + const char *pFile, const char *cmd, IOSystem *pIOSystem, + const aiScene *pScene, bool shortened, bool compressed) { + AssbinFileWriter fileWriter(shortened, compressed); + fileWriter.WriteBinaryDump(pFile, cmd, pIOSystem, pScene); +} +#if _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +} // end of namespace Assimp diff --git a/Engine/lib/assimp/code/3MF/D3MFImporter.h b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.h similarity index 74% rename from Engine/lib/assimp/code/3MF/D3MFImporter.h rename to Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.h index 3dbdf07bf..cfed3b400 100644 --- a/Engine/lib/assimp/code/3MF/D3MFImporter.h +++ b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.h @@ -2,8 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -40,26 +39,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ -#ifndef AI_D3MFLOADER_H_INCLUDED -#define AI_D3MFLOADER_H_INCLUDED +/** @file AssbinFileWriter.h + * @brief Declaration of Assbin file writer. + */ -#include +#ifndef AI_ASSBINFILEWRITER_H_INC +#define AI_ASSBINFILEWRITER_H_INC + +#include +#include +#include namespace Assimp { -class D3MFImporter : public BaseImporter { -public: - // BaseImporter interface - D3MFImporter(); - ~D3MFImporter(); - bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const; - void SetupProperties(const Importer *pImp); - const aiImporterDesc *GetInfo() const; +void ASSIMP_API DumpSceneToAssbin( + const char *pFile, + const char *cmd, + IOSystem *pIOSystem, + const aiScene *pScene, + bool shortened, + bool compressed); -protected: - void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler); -}; +} -} // Namespace Assimp - -#endif // AI_D3MFLOADER_H_INCLUDED +#endif // AI_ASSBINFILEWRITER_H_INC diff --git a/Engine/lib/assimp/code/Assbin/AssbinLoader.cpp b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.cpp similarity index 56% rename from Engine/lib/assimp/code/Assbin/AssbinLoader.cpp rename to Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.cpp index becc3f8fc..060ce4377 100644 --- a/Engine/lib/assimp/code/Assbin/AssbinLoader.cpp +++ b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.cpp @@ -3,9 +3,7 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -50,19 +48,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER // internal headers -#include "Assbin/AssbinLoader.h" +#include "AssetLib/Assbin/AssbinLoader.h" #include "Common/assbin_chunks.h" #include -#include #include -#include #include +#include +#include #include #ifdef ASSIMP_BUILD_NO_OWN_ZLIB -# include +#include #else -# include +#include #endif using namespace Assimp; @@ -81,94 +79,97 @@ static const aiImporterDesc desc = { }; // ----------------------------------------------------------------------------------- -const aiImporterDesc* AssbinImporter::GetInfo() const { +const aiImporterDesc *AssbinImporter::GetInfo() const { return &desc; } // ----------------------------------------------------------------------------------- -bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const { - IOStream * in = pIOHandler->Open(pFile); +bool AssbinImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { + IOStream *in = pIOHandler->Open(pFile); if (nullptr == in) { return false; } char s[32]; - in->Read( s, sizeof(char), 32 ); + in->Read(s, sizeof(char), 32); pIOHandler->Close(in); - return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0; + return strncmp(s, "ASSIMP.binary-dump.", 19) == 0; } // ----------------------------------------------------------------------------------- template -T Read(IOStream * stream) { +T Read(IOStream *stream) { T t; - size_t res = stream->Read( &t, sizeof(T), 1 ); - if(res != 1) + size_t res = stream->Read(&t, sizeof(T), 1); + if (res != 1) { throw DeadlyImportError("Unexpected EOF"); + } return t; } // ----------------------------------------------------------------------------------- template <> -aiVector3D Read(IOStream * stream) { +aiVector3D Read(IOStream *stream) { aiVector3D v; - v.x = Read(stream); - v.y = Read(stream); - v.z = Read(stream); + v.x = Read(stream); + v.y = Read(stream); + v.z = Read(stream); return v; } // ----------------------------------------------------------------------------------- template <> -aiColor4D Read(IOStream * stream) { +aiColor4D Read(IOStream *stream) { aiColor4D c; - c.r = Read(stream); - c.g = Read(stream); - c.b = Read(stream); - c.a = Read(stream); + c.r = Read(stream); + c.g = Read(stream); + c.b = Read(stream); + c.a = Read(stream); return c; } // ----------------------------------------------------------------------------------- template <> -aiQuaternion Read(IOStream * stream) { +aiQuaternion Read(IOStream *stream) { aiQuaternion v; - v.w = Read(stream); - v.x = Read(stream); - v.y = Read(stream); - v.z = Read(stream); + v.w = Read(stream); + v.x = Read(stream); + v.y = Read(stream); + v.z = Read(stream); return v; } // ----------------------------------------------------------------------------------- template <> -aiString Read(IOStream * stream) { +aiString Read(IOStream *stream) { aiString s; - stream->Read(&s.length,4,1); - if(s.length) - stream->Read(s.data,s.length,1); + stream->Read(&s.length, 4, 1); + if (s.length) { + stream->Read(s.data, s.length, 1); + } s.data[s.length] = 0; + return s; } // ----------------------------------------------------------------------------------- template <> -aiVertexWeight Read(IOStream * stream) { +aiVertexWeight Read(IOStream *stream) { aiVertexWeight w; w.mVertexId = Read(stream); - w.mWeight = Read(stream); + w.mWeight = Read(stream); return w; } // ----------------------------------------------------------------------------------- template <> -aiMatrix4x4 Read(IOStream * stream) { +aiMatrix4x4 Read(IOStream *stream) { aiMatrix4x4 m; - for (unsigned int i = 0; i < 4;++i) { - for (unsigned int i2 = 0; i2 < 4;++i2) { - m[i][i2] = Read(stream); + for (unsigned int i = 0; i < 4; ++i) { + for (unsigned int i2 = 0; i2 < 4; ++i2) { + m[i][i2] = Read(stream); } } return m; @@ -176,7 +177,7 @@ aiMatrix4x4 Read(IOStream * stream) { // ----------------------------------------------------------------------------------- template <> -aiVectorKey Read(IOStream * stream) { +aiVectorKey Read(IOStream *stream) { aiVectorKey v; v.mTime = Read(stream); v.mValue = Read(stream); @@ -185,7 +186,7 @@ aiVectorKey Read(IOStream * stream) { // ----------------------------------------------------------------------------------- template <> -aiQuatKey Read(IOStream * stream) { +aiQuatKey Read(IOStream *stream) { aiQuatKey v; v.mTime = Read(stream); v.mValue = Read(stream); @@ -194,27 +195,27 @@ aiQuatKey Read(IOStream * stream) { // ----------------------------------------------------------------------------------- template -void ReadArray( IOStream *stream, T * out, unsigned int size) { - ai_assert( nullptr != stream ); - ai_assert( nullptr != out ); +void ReadArray(IOStream *stream, T *out, unsigned int size) { + ai_assert(nullptr != stream); + ai_assert(nullptr != out); - for (unsigned int i=0; i(stream); } } // ----------------------------------------------------------------------------------- template -void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n ) { +void ReadBounds(IOStream *stream, T * /*p*/, unsigned int n) { // not sure what to do here, the data isn't really useful. - stream->Seek( sizeof(T) * n, aiOrigin_CUR ); + stream->Seek(sizeof(T) * n, aiOrigin_CUR); } // ----------------------------------------------------------------------------------- -void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** onode, aiNode* parent ) { - if(Read(stream) != ASSBIN_CHUNK_AINODE) +void AssbinImporter::ReadBinaryNode(IOStream *stream, aiNode **onode, aiNode *parent) { + if (Read(stream) != ASSBIN_CHUNK_AINODE) throw DeadlyImportError("Magic chunk identifiers are wrong!"); - /*uint32_t size =*/ Read(stream); + /*uint32_t size =*/Read(stream); std::unique_ptr node(new aiNode()); @@ -222,14 +223,13 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** onode, aiNode* node->mTransformation = Read(stream); unsigned numChildren = Read(stream); unsigned numMeshes = Read(stream); - unsigned int nb_metadata = Read(stream); + unsigned int nb_metadata = Read(stream); - if(parent) { + if (parent) { node->mParent = parent; } - if (numMeshes) - { + if (numMeshes) { node->mMeshes = new unsigned int[numMeshes]; for (unsigned int i = 0; i < numMeshes; ++i) { node->mMeshes[i] = Read(stream); @@ -238,60 +238,60 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** onode, aiNode* } if (numChildren) { - node->mChildren = new aiNode*[numChildren]; + node->mChildren = new aiNode *[numChildren]; for (unsigned int i = 0; i < numChildren; ++i) { - ReadBinaryNode( stream, &node->mChildren[i], node.get() ); + ReadBinaryNode(stream, &node->mChildren[i], node.get()); node->mNumChildren++; } } - if ( nb_metadata > 0 ) { + if (nb_metadata > 0) { node->mMetaData = aiMetadata::Alloc(nb_metadata); for (unsigned int i = 0; i < nb_metadata; ++i) { node->mMetaData->mKeys[i] = Read(stream); - node->mMetaData->mValues[i].mType = (aiMetadataType) Read(stream); - void* data = nullptr; + node->mMetaData->mValues[i].mType = (aiMetadataType)Read(stream); + void *data = nullptr; switch (node->mMetaData->mValues[i].mType) { - case AI_BOOL: - data = new bool(Read(stream)); - break; - case AI_INT32: - data = new int32_t(Read(stream)); - break; - case AI_UINT64: - data = new uint64_t(Read(stream)); - break; - case AI_FLOAT: - data = new float(Read(stream)); - break; - case AI_DOUBLE: - data = new double(Read(stream)); - break; - case AI_AISTRING: - data = new aiString(Read(stream)); - break; - case AI_AIVECTOR3D: - data = new aiVector3D(Read(stream)); - break; + case AI_BOOL: + data = new bool(Read(stream)); + break; + case AI_INT32: + data = new int32_t(Read(stream)); + break; + case AI_UINT64: + data = new uint64_t(Read(stream)); + break; + case AI_FLOAT: + data = new ai_real(Read(stream)); + break; + case AI_DOUBLE: + data = new double(Read(stream)); + break; + case AI_AISTRING: + data = new aiString(Read(stream)); + break; + case AI_AIVECTOR3D: + data = new aiVector3D(Read(stream)); + break; #ifndef SWIG - case FORCE_32BIT: + case FORCE_32BIT: #endif // SWIG - default: - break; + default: + break; } - node->mMetaData->mValues[i].mData = data; - } - } + node->mMetaData->mValues[i].mData = data; + } + } *onode = node.release(); } // ----------------------------------------------------------------------------------- -void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) { - if(Read(stream) != ASSBIN_CHUNK_AIBONE) +void AssbinImporter::ReadBinaryBone(IOStream *stream, aiBone *b) { + if (Read(stream) != ASSBIN_CHUNK_AIBONE) throw DeadlyImportError("Magic chunk identifiers are wrong!"); - /*uint32_t size =*/ Read(stream); + /*uint32_t size =*/Read(stream); b->mName = Read(stream); b->mNumWeights = Read(stream); @@ -300,23 +300,24 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) { // for the moment we write dumb min/max values for the bones, too. // maybe I'll add a better, hash-like solution later if (shortened) { - ReadBounds(stream,b->mWeights,b->mNumWeights); + ReadBounds(stream, b->mWeights, b->mNumWeights); } else { // else write as usual b->mWeights = new aiVertexWeight[b->mNumWeights]; - ReadArray(stream,b->mWeights,b->mNumWeights); + ReadArray(stream, b->mWeights, b->mNumWeights); } } // ----------------------------------------------------------------------------------- static bool fitsIntoUI16(unsigned int mNumVertices) { - return ( mNumVertices < (1u<<16) ); + return (mNumVertices < (1u << 16)); } + // ----------------------------------------------------------------------------------- -void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) { - if(Read(stream) != ASSBIN_CHUNK_AIMESH) +void AssbinImporter::ReadBinaryMesh(IOStream *stream, aiMesh *mesh) { + if (Read(stream) != ASSBIN_CHUNK_AIMESH) throw DeadlyImportError("Magic chunk identifiers are wrong!"); - /*uint32_t size =*/ Read(stream); + /*uint32_t size =*/Read(stream); mesh->mPrimitiveTypes = Read(stream); mesh->mNumVertices = Read(stream); @@ -329,48 +330,48 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) { if (c & ASSBIN_MESH_HAS_POSITIONS) { if (shortened) { - ReadBounds(stream,mesh->mVertices,mesh->mNumVertices); - } else { + ReadBounds(stream, mesh->mVertices, mesh->mNumVertices); + } else { // else write as usual mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - ReadArray(stream,mesh->mVertices,mesh->mNumVertices); + ReadArray(stream, mesh->mVertices, mesh->mNumVertices); } } if (c & ASSBIN_MESH_HAS_NORMALS) { if (shortened) { - ReadBounds(stream,mesh->mNormals,mesh->mNumVertices); - } else { + ReadBounds(stream, mesh->mNormals, mesh->mNumVertices); + } else { // else write as usual mesh->mNormals = new aiVector3D[mesh->mNumVertices]; - ReadArray(stream,mesh->mNormals,mesh->mNumVertices); + ReadArray(stream, mesh->mNormals, mesh->mNumVertices); } } if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) { if (shortened) { - ReadBounds(stream,mesh->mTangents,mesh->mNumVertices); - ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices); - } else { + ReadBounds(stream, mesh->mTangents, mesh->mNumVertices); + ReadBounds(stream, mesh->mBitangents, mesh->mNumVertices); + } else { // else write as usual mesh->mTangents = new aiVector3D[mesh->mNumVertices]; - ReadArray(stream,mesh->mTangents,mesh->mNumVertices); + ReadArray(stream, mesh->mTangents, mesh->mNumVertices); mesh->mBitangents = new aiVector3D[mesh->mNumVertices]; - ReadArray(stream,mesh->mBitangents,mesh->mNumVertices); + ReadArray(stream, mesh->mBitangents, mesh->mNumVertices); } } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS; ++n) { if (!(c & ASSBIN_MESH_HAS_COLOR(n))) { break; } if (shortened) { - ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices); - } else { + ReadBounds(stream, mesh->mColors[n], mesh->mNumVertices); + } else { // else write as usual mesh->mColors[n] = new aiColor4D[mesh->mNumVertices]; - ReadArray(stream,mesh->mColors[n],mesh->mNumVertices); + ReadArray(stream, mesh->mColors[n], mesh->mNumVertices); } } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++n) { if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n))) { break; } @@ -379,11 +380,11 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) { mesh->mNumUVComponents[n] = Read(stream); if (shortened) { - ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices); - } else { + ReadBounds(stream, mesh->mTextureCoords[n], mesh->mNumVertices); + } else { // else write as usual mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; - ReadArray(stream,mesh->mTextureCoords[n],mesh->mNumVertices); + ReadArray(stream, mesh->mTextureCoords[n], mesh->mNumVertices); } } @@ -393,20 +394,20 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) { // using Assimp's standard hashing function. if (shortened) { Read(stream); - } else { + } else { // else write as usual // if there are less than 2^16 vertices, we can simply use 16 bit integers ... mesh->mFaces = new aiFace[mesh->mNumFaces]; - for (unsigned int i = 0; i < mesh->mNumFaces;++i) { - aiFace& f = mesh->mFaces[i]; + for (unsigned int i = 0; i < mesh->mNumFaces; ++i) { + aiFace &f = mesh->mFaces[i]; static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff"); f.mNumIndices = Read(stream); f.mIndices = new unsigned int[f.mNumIndices]; - for (unsigned int a = 0; a < f.mNumIndices;++a) { - // Check if unsigned short ( 16 bit ) are big enought for the indices - if ( fitsIntoUI16( mesh->mNumVertices ) ) { + for (unsigned int a = 0; a < f.mNumIndices; ++a) { + // Check if unsigned short ( 16 bit ) are big enough for the indices + if (fitsIntoUI16(mesh->mNumVertices)) { f.mIndices[a] = Read(stream); } else { f.mIndices[a] = Read(stream); @@ -417,19 +418,19 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) { // write bones if (mesh->mNumBones) { - mesh->mBones = new C_STRUCT aiBone*[mesh->mNumBones]; - for (unsigned int a = 0; a < mesh->mNumBones;++a) { + mesh->mBones = new C_STRUCT aiBone *[mesh->mNumBones]; + for (unsigned int a = 0; a < mesh->mNumBones; ++a) { mesh->mBones[a] = new aiBone(); - ReadBinaryBone(stream,mesh->mBones[a]); + ReadBinaryBone(stream, mesh->mBones[a]); } } } // ----------------------------------------------------------------------------------- -void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) { - if(Read(stream) != ASSBIN_CHUNK_AIMATERIALPROPERTY) +void AssbinImporter::ReadBinaryMaterialProperty(IOStream *stream, aiMaterialProperty *prop) { + if (Read(stream) != ASSBIN_CHUNK_AIMATERIALPROPERTY) throw DeadlyImportError("Magic chunk identifiers are wrong!"); - /*uint32_t size =*/ Read(stream); + /*uint32_t size =*/Read(stream); prop->mKey = Read(stream); prop->mSemantic = Read(stream); @@ -437,36 +438,34 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro prop->mDataLength = Read(stream); prop->mType = (aiPropertyTypeInfo)Read(stream); - prop->mData = new char [ prop->mDataLength ]; - stream->Read(prop->mData,1,prop->mDataLength); + prop->mData = new char[prop->mDataLength]; + stream->Read(prop->mData, 1, prop->mDataLength); } // ----------------------------------------------------------------------------------- -void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) { - if(Read(stream) != ASSBIN_CHUNK_AIMATERIAL) +void AssbinImporter::ReadBinaryMaterial(IOStream *stream, aiMaterial *mat) { + if (Read(stream) != ASSBIN_CHUNK_AIMATERIAL) throw DeadlyImportError("Magic chunk identifiers are wrong!"); - /*uint32_t size =*/ Read(stream); + /*uint32_t size =*/Read(stream); mat->mNumAllocated = mat->mNumProperties = Read(stream); - if (mat->mNumProperties) - { - if (mat->mProperties) - { + if (mat->mNumProperties) { + if (mat->mProperties) { delete[] mat->mProperties; } - mat->mProperties = new aiMaterialProperty*[mat->mNumProperties]; - for (unsigned int i = 0; i < mat->mNumProperties;++i) { + mat->mProperties = new aiMaterialProperty *[mat->mNumProperties]; + for (unsigned int i = 0; i < mat->mNumProperties; ++i) { mat->mProperties[i] = new aiMaterialProperty(); - ReadBinaryMaterialProperty( stream, mat->mProperties[i]); + ReadBinaryMaterialProperty(stream, mat->mProperties[i]); } } } // ----------------------------------------------------------------------------------- -void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) { - if(Read(stream) != ASSBIN_CHUNK_AINODEANIM) +void AssbinImporter::ReadBinaryNodeAnim(IOStream *stream, aiNodeAnim *nd) { + if (Read(stream) != ASSBIN_CHUNK_AINODEANIM) throw DeadlyImportError("Magic chunk identifiers are wrong!"); - /*uint32_t size =*/ Read(stream); + /*uint32_t size =*/Read(stream); nd->mNodeName = Read(stream); nd->mNumPositionKeys = Read(stream); @@ -477,82 +476,82 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) { if (nd->mNumPositionKeys) { if (shortened) { - ReadBounds(stream,nd->mPositionKeys,nd->mNumPositionKeys); + ReadBounds(stream, nd->mPositionKeys, nd->mNumPositionKeys); } // else write as usual else { nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys]; - ReadArray(stream,nd->mPositionKeys,nd->mNumPositionKeys); + ReadArray(stream, nd->mPositionKeys, nd->mNumPositionKeys); } } if (nd->mNumRotationKeys) { if (shortened) { - ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys); + ReadBounds(stream, nd->mRotationKeys, nd->mNumRotationKeys); - } else { + } else { // else write as usual nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys]; - ReadArray(stream,nd->mRotationKeys,nd->mNumRotationKeys); + ReadArray(stream, nd->mRotationKeys, nd->mNumRotationKeys); } } if (nd->mNumScalingKeys) { if (shortened) { - ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys); + ReadBounds(stream, nd->mScalingKeys, nd->mNumScalingKeys); - } else { + } else { // else write as usual nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys]; - ReadArray(stream,nd->mScalingKeys,nd->mNumScalingKeys); + ReadArray(stream, nd->mScalingKeys, nd->mNumScalingKeys); } } } // ----------------------------------------------------------------------------------- -void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) { - if(Read(stream) != ASSBIN_CHUNK_AIANIMATION) +void AssbinImporter::ReadBinaryAnim(IOStream *stream, aiAnimation *anim) { + if (Read(stream) != ASSBIN_CHUNK_AIANIMATION) throw DeadlyImportError("Magic chunk identifiers are wrong!"); - /*uint32_t size =*/ Read(stream); + /*uint32_t size =*/Read(stream); - anim->mName = Read (stream); - anim->mDuration = Read (stream); - anim->mTicksPerSecond = Read (stream); + anim->mName = Read(stream); + anim->mDuration = Read(stream); + anim->mTicksPerSecond = Read(stream); anim->mNumChannels = Read(stream); if (anim->mNumChannels) { - anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ]; - for (unsigned int a = 0; a < anim->mNumChannels;++a) { + anim->mChannels = new aiNodeAnim *[anim->mNumChannels]; + for (unsigned int a = 0; a < anim->mNumChannels; ++a) { anim->mChannels[a] = new aiNodeAnim(); - ReadBinaryNodeAnim(stream,anim->mChannels[a]); + ReadBinaryNodeAnim(stream, anim->mChannels[a]); } } } // ----------------------------------------------------------------------------------- -void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) { - if(Read(stream) != ASSBIN_CHUNK_AITEXTURE) +void AssbinImporter::ReadBinaryTexture(IOStream *stream, aiTexture *tex) { + if (Read(stream) != ASSBIN_CHUNK_AITEXTURE) throw DeadlyImportError("Magic chunk identifiers are wrong!"); - /*uint32_t size =*/ Read(stream); + /*uint32_t size =*/Read(stream); tex->mWidth = Read(stream); tex->mHeight = Read(stream); - stream->Read( tex->achFormatHint, sizeof(char), 4 ); + stream->Read(tex->achFormatHint, sizeof(char), HINTMAXTEXTURELEN - 1); - if(!shortened) { + if (!shortened) { if (!tex->mHeight) { - tex->pcData = new aiTexel[ tex->mWidth ]; - stream->Read(tex->pcData,1,tex->mWidth); + tex->pcData = new aiTexel[tex->mWidth]; + stream->Read(tex->pcData, 1, tex->mWidth); } else { - tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ]; - stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4); + tex->pcData = new aiTexel[tex->mWidth * tex->mHeight]; + stream->Read(tex->pcData, 1, tex->mWidth * tex->mHeight * 4); } } } // ----------------------------------------------------------------------------------- -void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) { - if(Read(stream) != ASSBIN_CHUNK_AILIGHT) +void AssbinImporter::ReadBinaryLight(IOStream *stream, aiLight *l) { + if (Read(stream) != ASSBIN_CHUNK_AILIGHT) throw DeadlyImportError("Magic chunk identifiers are wrong!"); - /*uint32_t size =*/ Read(stream); + /*uint32_t size =*/Read(stream); l->mName = Read(stream); l->mType = (aiLightSourceType)Read(stream); @@ -574,10 +573,10 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) { } // ----------------------------------------------------------------------------------- -void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) { - if(Read(stream) != ASSBIN_CHUNK_AICAMERA) +void AssbinImporter::ReadBinaryCamera(IOStream *stream, aiCamera *cam) { + if (Read(stream) != ASSBIN_CHUNK_AICAMERA) throw DeadlyImportError("Magic chunk identifiers are wrong!"); - /*uint32_t size =*/ Read(stream); + /*uint32_t size =*/Read(stream); cam->mName = Read(stream); cam->mPosition = Read(stream); @@ -590,141 +589,139 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) { } // ----------------------------------------------------------------------------------- -void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { - if(Read(stream) != ASSBIN_CHUNK_AISCENE) +void AssbinImporter::ReadBinaryScene(IOStream *stream, aiScene *scene) { + if (Read(stream) != ASSBIN_CHUNK_AISCENE) throw DeadlyImportError("Magic chunk identifiers are wrong!"); - /*uint32_t size =*/ Read(stream); + /*uint32_t size =*/Read(stream); - scene->mFlags = Read(stream); - scene->mNumMeshes = Read(stream); - scene->mNumMaterials = Read(stream); + scene->mFlags = Read(stream); + scene->mNumMeshes = Read(stream); + scene->mNumMaterials = Read(stream); scene->mNumAnimations = Read(stream); - scene->mNumTextures = Read(stream); - scene->mNumLights = Read(stream); - scene->mNumCameras = Read(stream); + scene->mNumTextures = Read(stream); + scene->mNumLights = Read(stream); + scene->mNumCameras = Read(stream); // Read node graph //scene->mRootNode = new aiNode[1]; - ReadBinaryNode( stream, &scene->mRootNode, (aiNode*)NULL ); + ReadBinaryNode(stream, &scene->mRootNode, (aiNode *)nullptr); // Read all meshes if (scene->mNumMeshes) { - scene->mMeshes = new aiMesh*[scene->mNumMeshes]; - memset(scene->mMeshes, 0, scene->mNumMeshes*sizeof(aiMesh*)); - for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + scene->mMeshes = new aiMesh *[scene->mNumMeshes]; + memset(scene->mMeshes, 0, scene->mNumMeshes * sizeof(aiMesh *)); + for (unsigned int i = 0; i < scene->mNumMeshes; ++i) { scene->mMeshes[i] = new aiMesh(); - ReadBinaryMesh( stream,scene->mMeshes[i]); + ReadBinaryMesh(stream, scene->mMeshes[i]); } } // Read materials if (scene->mNumMaterials) { - scene->mMaterials = new aiMaterial*[scene->mNumMaterials]; - memset(scene->mMaterials, 0, scene->mNumMaterials*sizeof(aiMaterial*)); - for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + scene->mMaterials = new aiMaterial *[scene->mNumMaterials]; + memset(scene->mMaterials, 0, scene->mNumMaterials * sizeof(aiMaterial *)); + for (unsigned int i = 0; i < scene->mNumMaterials; ++i) { scene->mMaterials[i] = new aiMaterial(); - ReadBinaryMaterial(stream,scene->mMaterials[i]); + ReadBinaryMaterial(stream, scene->mMaterials[i]); } } // Read all animations if (scene->mNumAnimations) { - scene->mAnimations = new aiAnimation*[scene->mNumAnimations]; - memset(scene->mAnimations, 0, scene->mNumAnimations*sizeof(aiAnimation*)); - for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + scene->mAnimations = new aiAnimation *[scene->mNumAnimations]; + memset(scene->mAnimations, 0, scene->mNumAnimations * sizeof(aiAnimation *)); + for (unsigned int i = 0; i < scene->mNumAnimations; ++i) { scene->mAnimations[i] = new aiAnimation(); - ReadBinaryAnim(stream,scene->mAnimations[i]); + ReadBinaryAnim(stream, scene->mAnimations[i]); } } // Read all textures if (scene->mNumTextures) { - scene->mTextures = new aiTexture*[scene->mNumTextures]; - memset(scene->mTextures, 0, scene->mNumTextures*sizeof(aiTexture*)); - for (unsigned int i = 0; i < scene->mNumTextures;++i) { + scene->mTextures = new aiTexture *[scene->mNumTextures]; + memset(scene->mTextures, 0, scene->mNumTextures * sizeof(aiTexture *)); + for (unsigned int i = 0; i < scene->mNumTextures; ++i) { scene->mTextures[i] = new aiTexture(); - ReadBinaryTexture(stream,scene->mTextures[i]); + ReadBinaryTexture(stream, scene->mTextures[i]); } } // Read lights if (scene->mNumLights) { - scene->mLights = new aiLight*[scene->mNumLights]; - memset(scene->mLights, 0, scene->mNumLights*sizeof(aiLight*)); - for (unsigned int i = 0; i < scene->mNumLights;++i) { + scene->mLights = new aiLight *[scene->mNumLights]; + memset(scene->mLights, 0, scene->mNumLights * sizeof(aiLight *)); + for (unsigned int i = 0; i < scene->mNumLights; ++i) { scene->mLights[i] = new aiLight(); - ReadBinaryLight(stream,scene->mLights[i]); + ReadBinaryLight(stream, scene->mLights[i]); } } // Read cameras if (scene->mNumCameras) { - scene->mCameras = new aiCamera*[scene->mNumCameras]; - memset(scene->mCameras, 0, scene->mNumCameras*sizeof(aiCamera*)); - for (unsigned int i = 0; i < scene->mNumCameras;++i) { + scene->mCameras = new aiCamera *[scene->mNumCameras]; + memset(scene->mCameras, 0, scene->mNumCameras * sizeof(aiCamera *)); + for (unsigned int i = 0; i < scene->mNumCameras; ++i) { scene->mCameras[i] = new aiCamera(); - ReadBinaryCamera(stream,scene->mCameras[i]); + ReadBinaryCamera(stream, scene->mCameras[i]); } } - } // ----------------------------------------------------------------------------------- -void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) { - IOStream * stream = pIOHandler->Open(pFile,"rb"); +void AssbinImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { + IOStream *stream = pIOHandler->Open(pFile, "rb"); if (nullptr == stream) { - return; + throw DeadlyImportError("ASSBIN: Could not open ", pFile); } // signature - stream->Seek( 44, aiOrigin_CUR ); + stream->Seek(44, aiOrigin_CUR); unsigned int versionMajor = Read(stream); unsigned int versionMinor = Read(stream); if (versionMinor != ASSBIN_VERSION_MINOR || versionMajor != ASSBIN_VERSION_MAJOR) { - throw DeadlyImportError( "Invalid version, data format not compatible!" ); + throw DeadlyImportError("Invalid version, data format not compatible!"); } - /*unsigned int versionRevision =*/ Read(stream); - /*unsigned int compileFlags =*/ Read(stream); + /*unsigned int versionRevision =*/Read(stream); + /*unsigned int compileFlags =*/Read(stream); shortened = Read(stream) > 0; compressed = Read(stream) > 0; if (shortened) - throw DeadlyImportError( "Shortened binaries are not supported!" ); + throw DeadlyImportError("Shortened binaries are not supported!"); - stream->Seek( 256, aiOrigin_CUR ); // original filename - stream->Seek( 128, aiOrigin_CUR ); // options - stream->Seek( 64, aiOrigin_CUR ); // padding + stream->Seek(256, aiOrigin_CUR); // original filename + stream->Seek(128, aiOrigin_CUR); // options + stream->Seek(64, aiOrigin_CUR); // padding if (compressed) { uLongf uncompressedSize = Read(stream); uLongf compressedSize = static_cast(stream->FileSize() - stream->Tell()); - unsigned char * compressedData = new unsigned char[ compressedSize ]; - size_t len = stream->Read( compressedData, 1, compressedSize ); + unsigned char *compressedData = new unsigned char[compressedSize]; + size_t len = stream->Read(compressedData, 1, compressedSize); ai_assert(len == compressedSize); - unsigned char * uncompressedData = new unsigned char[ uncompressedSize ]; + unsigned char *uncompressedData = new unsigned char[uncompressedSize]; - int res = uncompress( uncompressedData, &uncompressedSize, compressedData, (uLong) len ); - if(res != Z_OK) - { - delete [] uncompressedData; - delete [] compressedData; + int res = uncompress(uncompressedData, &uncompressedSize, compressedData, (uLong)len); + if (res != Z_OK) { + delete[] uncompressedData; + delete[] compressedData; pIOHandler->Close(stream); throw DeadlyImportError("Zlib decompression failed."); } - MemoryIOStream io( uncompressedData, uncompressedSize ); + MemoryIOStream io(uncompressedData, uncompressedSize); - ReadBinaryScene(&io,pScene); + ReadBinaryScene(&io, pScene); delete[] uncompressedData; delete[] compressedData; } else { - ReadBinaryScene(stream,pScene); + ReadBinaryScene(stream, pScene); } pIOHandler->Close(stream); diff --git a/Engine/lib/assimp/code/Assbin/AssbinLoader.h b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.h similarity index 90% rename from Engine/lib/assimp/code/Assbin/AssbinLoader.h rename to Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.h index 9f2dde125..f922b91fd 100644 --- a/Engine/lib/assimp/code/Assbin/AssbinLoader.h +++ b/Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.h @@ -3,8 +3,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -74,17 +73,11 @@ private: bool compressed; public: - virtual bool CanRead( - const std::string& pFile, - IOSystem* pIOHandler, - bool checkSig - ) const; - virtual const aiImporterDesc* GetInfo() const; - virtual void InternReadFile( - const std::string& pFile, - aiScene* pScene, - IOSystem* pIOHandler - ); + bool CanRead(const std::string& pFile, + IOSystem* pIOHandler, bool checkSig) const override; + const aiImporterDesc* GetInfo() const override; + void InternReadFile( + const std::string& pFile,aiScene* pScene,IOSystem* pIOHandler) override; void ReadHeader(); void ReadBinaryScene( IOStream * stream, aiScene* pScene ); void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent ); diff --git a/Engine/lib/assimp/code/Assjson/cencode.c b/Engine/lib/assimp/code/AssetLib/Assjson/cencode.c similarity index 87% rename from Engine/lib/assimp/code/Assjson/cencode.c rename to Engine/lib/assimp/code/AssetLib/Assjson/cencode.c index db99e7efa..614a2671f 100644 --- a/Engine/lib/assimp/code/Assjson/cencode.c +++ b/Engine/lib/assimp/code/AssetLib/Assjson/cencode.c @@ -9,6 +9,11 @@ For details, see http://sourceforge.net/projects/libb64 const int CHARS_PER_LINE = 72; +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4244) +#endif // _MSC_VER + void base64_init_encodestate(base64_encodestate* state_in) { state_in->step = step_A; @@ -30,9 +35,9 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, char* codechar = code_out; char result; char fragment; - + result = state_in->result; - + switch (state_in->step) { while (1) @@ -42,7 +47,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, { state_in->result = result; state_in->step = step_A; - return codechar - code_out; + return (int)(codechar - code_out); } fragment = *plainchar++; result = (fragment & 0x0fc) >> 2; @@ -53,7 +58,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, { state_in->result = result; state_in->step = step_B; - return codechar - code_out; + return (int)(codechar - code_out); } fragment = *plainchar++; result |= (fragment & 0x0f0) >> 4; @@ -64,14 +69,14 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, { state_in->result = result; state_in->step = step_C; - return codechar - code_out; + return (int)(codechar - code_out); } fragment = *plainchar++; result |= (fragment & 0x0c0) >> 6; *codechar++ = base64_encode_value(result); result = (fragment & 0x03f) >> 0; *codechar++ = base64_encode_value(result); - + ++(state_in->stepcount); if (state_in->stepcount == CHARS_PER_LINE/4) { @@ -81,13 +86,13 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, } } /* control should not reach here */ - return codechar - code_out; + return (int)(codechar - code_out); } int base64_encode_blockend(char* code_out, base64_encodestate* state_in) { char* codechar = code_out; - + switch (state_in->step) { case step_B: @@ -103,7 +108,10 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in) break; } *codechar++ = '\n'; - - return codechar - code_out; + + return (int)(codechar - code_out); } +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER diff --git a/Engine/lib/assimp/code/Assjson/cencode.h b/Engine/lib/assimp/code/AssetLib/Assjson/cencode.h similarity index 91% rename from Engine/lib/assimp/code/Assjson/cencode.h rename to Engine/lib/assimp/code/AssetLib/Assjson/cencode.h index c1e3464af..a7893c434 100644 --- a/Engine/lib/assimp/code/Assjson/cencode.h +++ b/Engine/lib/assimp/code/AssetLib/Assjson/cencode.h @@ -8,6 +8,10 @@ For details, see http://sourceforge.net/projects/libb64 #ifndef BASE64_CENCODE_H #define BASE64_CENCODE_H +#ifdef _MSC_VER +#pragma warning(disable : 4127 ) +#endif // _MSC_VER + typedef enum { step_A, step_B, step_C diff --git a/Engine/lib/assimp/code/Assjson/json_exporter.cpp b/Engine/lib/assimp/code/AssetLib/Assjson/json_exporter.cpp similarity index 77% rename from Engine/lib/assimp/code/Assjson/json_exporter.cpp rename to Engine/lib/assimp/code/AssetLib/Assjson/json_exporter.cpp index e9fa72496..7b2c8ec81 100644 --- a/Engine/lib/assimp/code/Assjson/json_exporter.cpp +++ b/Engine/lib/assimp/code/AssetLib/Assjson/json_exporter.cpp @@ -9,30 +9,31 @@ Licensed under a 3-clause BSD license. See the LICENSE file for more information #ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER -#include +#include #include #include #include -#include +#include +#include -#include -#include #include +#include #include +#include #define CURRENT_FORMAT_VERSION 100 -// grab scoped_ptr from assimp to avoid a dependency on boost. +// grab scoped_ptr from assimp to avoid a dependency on boost. //#include #include "mesh_splitter.h" extern "C" { - #include "cencode.h" +#include "cencode.h" } namespace Assimp { -void ExportAssimp2Json(const char*, Assimp::IOSystem*, const aiScene*, const Assimp::ExportProperties*); +void ExportAssimp2Json(const char *, Assimp::IOSystem *, const aiScene *, const Assimp::ExportProperties *); // small utility class to simplify serializing the aiScene to Json class JSONWriter { @@ -40,14 +41,17 @@ public: enum { Flag_DoNotIndent = 0x1, Flag_WriteSpecialFloats = 0x2, + Flag_SkipWhitespaces = 0x4 }; - - JSONWriter(Assimp::IOStream& out, unsigned int flags = 0u) - : out(out) - , first() - , flags(flags) { + + JSONWriter(Assimp::IOStream &out, unsigned int flags = 0u) : + out(out), indent (""), newline("\n"), space(" "), buff (), first(false), flags(flags) { // make sure that all formatting happens using the standard, C locale and not the user's current locale buff.imbue(std::locale("C")); + if (flags & Flag_SkipWhitespaces) { + newline = ""; + space = ""; + } } ~JSONWriter() { @@ -68,43 +72,43 @@ public: indent.erase(indent.end() - 1); } - void Key(const std::string& name) { + void Key(const std::string &name) { AddIndentation(); Delimit(); - buff << '\"' + name + "\": "; + buff << '\"' + name + "\":" << space; } - template - void Element(const Literal& name) { + template + void Element(const Literal &name) { AddIndentation(); Delimit(); - LiteralToString(buff, name) << '\n'; + LiteralToString(buff, name) << newline; } - template - void SimpleValue(const Literal& s) { - LiteralToString(buff, s) << '\n'; + template + void SimpleValue(const Literal &s) { + LiteralToString(buff, s) << newline; } - void SimpleValue(const void* buffer, size_t len) { + void SimpleValue(const void *buffer, size_t len) { base64_encodestate s; base64_init_encodestate(&s); - char* const out = new char[std::max(len * 2, static_cast(16u))]; - const int n = base64_encode_block(reinterpret_cast(buffer), static_cast(len), out, &s); - out[n + base64_encode_blockend(out + n, &s)] = '\0'; + char *const cur_out = new char[std::max(len * 2, static_cast(16u))]; + const int n = base64_encode_block(reinterpret_cast(buffer), static_cast(len), cur_out, &s); + cur_out[n + base64_encode_blockend(cur_out + n, &s)] = '\0'; // base64 encoding may add newlines, but JSON strings may not contain 'real' newlines // (only escaped ones). Remove any newlines in out. - for (char* cur = out; *cur; ++cur) { + for (char *cur = cur_out; *cur; ++cur) { if (*cur == '\n') { *cur = ' '; } } - buff << '\"' << out << "\"\n"; - delete[] out; + buff << '\"' << cur_out << "\"" << newline; + delete[] cur_out; } void StartObj(bool is_element = false) { @@ -116,7 +120,7 @@ public: } } first = true; - buff << "{\n"; + buff << "{" << newline; PushIndent(); } @@ -124,7 +128,7 @@ public: PopIndent(); AddIndentation(); first = false; - buff << "}\n"; + buff << "}" << newline; } void StartArray(bool is_element = false) { @@ -136,19 +140,19 @@ public: } } first = true; - buff << "[\n"; + buff << "[" << newline; PushIndent(); } void EndArray() { PopIndent(); AddIndentation(); - buff << "]\n"; + buff << "]" << newline; first = false; } void AddIndentation() { - if (!(flags & Flag_DoNotIndent)) { + if (!(flags & Flag_DoNotIndent) && !(flags & Flag_SkipWhitespaces)) { buff << indent; } } @@ -156,21 +160,20 @@ public: void Delimit() { if (!first) { buff << ','; - } - else { - buff << ' '; + } else { + buff << space; first = false; } } private: - template - std::stringstream& LiteralToString(std::stringstream& stream, const Literal& s) { + template + std::stringstream &LiteralToString(std::stringstream &stream, const Literal &s) { stream << s; return stream; } - std::stringstream& LiteralToString(std::stringstream& stream, const aiString& s) { + std::stringstream &LiteralToString(std::stringstream &stream, const aiString &s) { std::string t; // escape backslashes and single quotes, both would render the JSON invalid if left as is @@ -189,10 +192,10 @@ private: return stream; } - std::stringstream& LiteralToString(std::stringstream& stream, float f) { + std::stringstream &LiteralToString(std::stringstream &stream, float f) { if (!std::numeric_limits::is_iec559) { // on a non IEEE-754 platform, we make no assumptions about the representation or existence - // of special floating-point numbers. + // of special floating-point numbers. stream << f; return stream; } @@ -228,15 +231,17 @@ private: } private: - Assimp::IOStream& out; - std::string indent, newline; + Assimp::IOStream &out; + std::string indent; + std::string newline; + std::string space; std::stringstream buff; bool first; unsigned int flags; }; -void Write(JSONWriter& out, const aiVector3D& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiVector3D &ai, bool is_elem = true) { out.StartArray(is_elem); out.Element(ai.x); out.Element(ai.y); @@ -244,7 +249,7 @@ void Write(JSONWriter& out, const aiVector3D& ai, bool is_elem = true) { out.EndArray(); } -void Write(JSONWriter& out, const aiQuaternion& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiQuaternion &ai, bool is_elem = true) { out.StartArray(is_elem); out.Element(ai.w); out.Element(ai.x); @@ -253,7 +258,7 @@ void Write(JSONWriter& out, const aiQuaternion& ai, bool is_elem = true) { out.EndArray(); } -void Write(JSONWriter& out, const aiColor3D& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiColor3D &ai, bool is_elem = true) { out.StartArray(is_elem); out.Element(ai.r); out.Element(ai.g); @@ -261,7 +266,7 @@ void Write(JSONWriter& out, const aiColor3D& ai, bool is_elem = true) { out.EndArray(); } -void Write(JSONWriter& out, const aiMatrix4x4& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiMatrix4x4 &ai, bool is_elem = true) { out.StartArray(is_elem); for (unsigned int x = 0; x < 4; ++x) { for (unsigned int y = 0; y < 4; ++y) { @@ -271,7 +276,7 @@ void Write(JSONWriter& out, const aiMatrix4x4& ai, bool is_elem = true) { out.EndArray(); } -void Write(JSONWriter& out, const aiBone& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiBone &ai, bool is_elem = true) { out.StartObj(is_elem); out.Key("name"); @@ -292,7 +297,7 @@ void Write(JSONWriter& out, const aiBone& ai, bool is_elem = true) { out.EndObj(); } -void Write(JSONWriter& out, const aiFace& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiFace &ai, bool is_elem = true) { out.StartArray(is_elem); for (unsigned int i = 0; i < ai.mNumIndices; ++i) { out.Element(ai.mIndices[i]); @@ -300,7 +305,7 @@ void Write(JSONWriter& out, const aiFace& ai, bool is_elem = true) { out.EndArray(); } -void Write(JSONWriter& out, const aiMesh& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiMesh &ai, bool is_elem = true) { out.StartObj(is_elem); out.Key("name"); @@ -411,7 +416,7 @@ void Write(JSONWriter& out, const aiMesh& ai, bool is_elem = true) { out.EndObj(); } -void Write(JSONWriter& out, const aiNode& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiNode &ai, bool is_elem = true) { out.StartObj(is_elem); out.Key("name"); @@ -441,13 +446,13 @@ void Write(JSONWriter& out, const aiNode& ai, bool is_elem = true) { out.EndObj(); } -void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiMaterial &ai, bool is_elem = true) { out.StartObj(is_elem); out.Key("properties"); out.StartArray(); for (unsigned int i = 0; i < ai.mNumProperties; ++i) { - const aiMaterialProperty* const prop = ai.mProperties[i]; + const aiMaterialProperty *const prop = ai.mProperties[i]; out.StartObj(true); out.Key("key"); out.SimpleValue(prop->mKey); @@ -461,46 +466,41 @@ void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) { out.Key("value"); switch (prop->mType) { - case aiPTI_Float: - if (prop->mDataLength / sizeof(float) > 1) { - out.StartArray(); - for (unsigned int i = 0; i < prop->mDataLength / sizeof(float); ++i) { - out.Element(reinterpret_cast(prop->mData)[i]); - } - out.EndArray(); + case aiPTI_Float: + if (prop->mDataLength / sizeof(float) > 1) { + out.StartArray(); + for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(float); ++ii) { + out.Element(reinterpret_cast(prop->mData)[ii]); } - else { - out.SimpleValue(*reinterpret_cast(prop->mData)); - } - break; + out.EndArray(); + } else { + out.SimpleValue(*reinterpret_cast(prop->mData)); + } + break; - case aiPTI_Integer: - if (prop->mDataLength / sizeof(int) > 1) { - out.StartArray(); - for (unsigned int i = 0; i < prop->mDataLength / sizeof(int); ++i) { - out.Element(reinterpret_cast(prop->mData)[i]); - } - out.EndArray(); - } else { - out.SimpleValue(*reinterpret_cast(prop->mData)); + case aiPTI_Integer: + if (prop->mDataLength / sizeof(int) > 1) { + out.StartArray(); + for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(int); ++ii) { + out.Element(reinterpret_cast(prop->mData)[ii]); } - break; + out.EndArray(); + } else { + out.SimpleValue(*reinterpret_cast(prop->mData)); + } + break; - case aiPTI_String: - { - aiString s; - aiGetMaterialString(&ai, prop->mKey.data, prop->mSemantic, prop->mIndex, &s); - out.SimpleValue(s); - } - break; - case aiPTI_Buffer: - { - // binary data is written as series of hex-encoded octets - out.SimpleValue(prop->mData, prop->mDataLength); - } - break; - default: - assert(false); + case aiPTI_String: { + aiString s; + aiGetMaterialString(&ai, prop->mKey.data, prop->mSemantic, prop->mIndex, &s); + out.SimpleValue(s); + } break; + case aiPTI_Buffer: { + // binary data is written as series of hex-encoded octets + out.SimpleValue(prop->mData, prop->mDataLength); + } break; + default: + assert(false); } out.EndObj(); @@ -510,7 +510,7 @@ void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) { out.EndObj(); } -void Write(JSONWriter& out, const aiTexture& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiTexture &ai, bool is_elem = true) { out.StartObj(is_elem); out.Key("width"); @@ -525,13 +525,12 @@ void Write(JSONWriter& out, const aiTexture& ai, bool is_elem = true) { out.Key("data"); if (!ai.mHeight) { out.SimpleValue(ai.pcData, ai.mWidth); - } - else { + } else { out.StartArray(); for (unsigned int y = 0; y < ai.mHeight; ++y) { out.StartArray(true); for (unsigned int x = 0; x < ai.mWidth; ++x) { - const aiTexel& tx = ai.pcData[y*ai.mWidth + x]; + const aiTexel &tx = ai.pcData[y * ai.mWidth + x]; out.StartArray(true); out.Element(static_cast(tx.r)); out.Element(static_cast(tx.g)); @@ -547,7 +546,7 @@ void Write(JSONWriter& out, const aiTexture& ai, bool is_elem = true) { out.EndObj(); } -void Write(JSONWriter& out, const aiLight& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiLight &ai, bool is_elem = true) { out.StartObj(is_elem); out.Key("name"); @@ -585,7 +584,6 @@ void Write(JSONWriter& out, const aiLight& ai, bool is_elem = true) { if (ai.mType != aiLightSource_POINT) { out.Key("direction"); Write(out, ai.mDirection, false); - } if (ai.mType != aiLightSource_DIRECTIONAL) { @@ -596,7 +594,7 @@ void Write(JSONWriter& out, const aiLight& ai, bool is_elem = true) { out.EndObj(); } -void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiNodeAnim &ai, bool is_elem = true) { out.StartObj(is_elem); out.Key("name"); @@ -612,7 +610,7 @@ void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) { out.Key("positionkeys"); out.StartArray(); for (unsigned int n = 0; n < ai.mNumPositionKeys; ++n) { - const aiVectorKey& pos = ai.mPositionKeys[n]; + const aiVectorKey &pos = ai.mPositionKeys[n]; out.StartArray(true); out.Element(pos.mTime); Write(out, pos.mValue); @@ -625,7 +623,7 @@ void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) { out.Key("rotationkeys"); out.StartArray(); for (unsigned int n = 0; n < ai.mNumRotationKeys; ++n) { - const aiQuatKey& rot = ai.mRotationKeys[n]; + const aiQuatKey &rot = ai.mRotationKeys[n]; out.StartArray(true); out.Element(rot.mTime); Write(out, rot.mValue); @@ -638,7 +636,7 @@ void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) { out.Key("scalingkeys"); out.StartArray(); for (unsigned int n = 0; n < ai.mNumScalingKeys; ++n) { - const aiVectorKey& scl = ai.mScalingKeys[n]; + const aiVectorKey &scl = ai.mScalingKeys[n]; out.StartArray(true); out.Element(scl.mTime); Write(out, scl.mValue); @@ -649,7 +647,7 @@ void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) { out.EndObj(); } -void Write(JSONWriter& out, const aiAnimation& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiAnimation &ai, bool is_elem = true) { out.StartObj(is_elem); out.Key("name"); @@ -670,7 +668,7 @@ void Write(JSONWriter& out, const aiAnimation& ai, bool is_elem = true) { out.EndObj(); } -void Write(JSONWriter& out, const aiCamera& ai, bool is_elem = true) { +void Write(JSONWriter &out, const aiCamera &ai, bool is_elem = true) { out.StartObj(is_elem); out.Key("name"); @@ -697,7 +695,7 @@ void Write(JSONWriter& out, const aiCamera& ai, bool is_elem = true) { out.EndObj(); } -void WriteFormatInfo(JSONWriter& out) { +void WriteFormatInfo(JSONWriter &out) { out.StartObj(); out.Key("format"); out.SimpleValue("\"assimp2json\""); @@ -706,7 +704,7 @@ void WriteFormatInfo(JSONWriter& out) { out.EndObj(); } -void Write(JSONWriter& out, const aiScene& ai) { +void Write(JSONWriter &out, const aiScene &ai) { out.StartObj(); out.Key("__metadata__"); @@ -774,15 +772,14 @@ void Write(JSONWriter& out, const aiScene& ai) { out.EndObj(); } - -void ExportAssimp2Json(const char* file, Assimp::IOSystem* io, const aiScene* scene, const Assimp::ExportProperties*) { +void ExportAssimp2Json(const char *file, Assimp::IOSystem *io, const aiScene *scene, const Assimp::ExportProperties *pProperties) { std::unique_ptr str(io->Open(file, "wt")); if (!str) { - //throw Assimp::DeadlyExportError("could not open output file"); + throw DeadlyExportError("could not open output file"); } // get a copy of the scene so we can modify it - aiScene* scenecopy_tmp; + aiScene *scenecopy_tmp; aiCopyScene(scene, &scenecopy_tmp); try { @@ -792,18 +789,22 @@ void ExportAssimp2Json(const char* file, Assimp::IOSystem* io, const aiScene* sc splitter.Execute(scenecopy_tmp); // XXX Flag_WriteSpecialFloats is turned on by default, right now we don't have a configuration interface for exporters - JSONWriter s(*str, JSONWriter::Flag_WriteSpecialFloats); + + unsigned int flags = JSONWriter::Flag_WriteSpecialFloats; + if (pProperties->GetPropertyBool("JSON_SKIP_WHITESPACES", false)) { + flags |= JSONWriter::Flag_SkipWhitespaces; + } + JSONWriter s(*str, flags); Write(s, *scenecopy_tmp); - } - catch (...) { + } catch (...) { aiFreeScene(scenecopy_tmp); throw; } aiFreeScene(scenecopy_tmp); } -} +} // namespace Assimp #endif // ASSIMP_BUILD_NO_ASSJSON_EXPORTER #endif // ASSIMP_BUILD_NO_EXPORT diff --git a/Engine/lib/assimp/code/Assjson/mesh_splitter.cpp b/Engine/lib/assimp/code/AssetLib/Assjson/mesh_splitter.cpp similarity index 96% rename from Engine/lib/assimp/code/Assjson/mesh_splitter.cpp rename to Engine/lib/assimp/code/AssetLib/Assjson/mesh_splitter.cpp index 24385f9a0..978437c41 100644 --- a/Engine/lib/assimp/code/Assjson/mesh_splitter.cpp +++ b/Engine/lib/assimp/code/AssetLib/Assjson/mesh_splitter.cpp @@ -69,13 +69,12 @@ void MeshSplitter::UpdateNode(aiNode* pcNode, const std::vectormNumChildren; i < end;++i) { UpdateNode ( pcNode->mChildren[i], source_mesh_map ); } - return; } -#define WAS_NOT_COPIED 0xffffffff +static const unsigned int WAS_NOT_COPIED = 0xffffffff; -typedef std::pair PerVertexWeight; -typedef std::vector VertexWeightTable; +using PerVertexWeight = std::pair ; +using VertexWeightTable = std::vector ; // ------------------------------------------------------------------------------------------------ VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh) { @@ -89,7 +88,7 @@ VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh) { aiBone* bone = pMesh->mBones[i]; for (unsigned int a = 0; a < bone->mNumWeights;++a) { const aiVertexWeight& weight = bone->mWeights[a]; - avPerVertexWeights[weight.mVertexId].push_back( std::make_pair(i,weight.mWeight) ); + avPerVertexWeights[weight.mVertexId].emplace_back(i,weight.mWeight); } } return avPerVertexWeights; @@ -100,7 +99,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vectormNumVertices <= LIMIT) { - source_mesh_map.push_back(std::make_pair(in_mesh,a)); + source_mesh_map.emplace_back(in_mesh,a); return; } @@ -110,7 +109,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vectormNumVertices / LIMIT) + 1; - // create a std::vector to remember which vertices have already + // create a std::vector to remember which vertices have already // been copied and to which position (i.e. output index) std::vector was_copied_to; was_copied_to.resize(in_mesh->mNumVertices,WAS_NOT_COPIED); @@ -125,7 +124,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vectormNumVertices = 0; out_mesh->mMaterialIndex = in_mesh->mMaterialIndex; @@ -179,7 +178,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vectormNumVertices + iNeed > out_vertex_index) { @@ -187,7 +186,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vectormTextureCoords[c][out_mesh->mNumVertices] = in_mesh->mTextureCoords[c][index]; } } - // vertex colors + // vertex colors for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) { if (in_mesh->HasVertexColors( c)) { out_mesh->mColors[c][out_mesh->mNumVertices] = in_mesh->mColors[c][index]; diff --git a/Engine/lib/assimp/code/Assjson/mesh_splitter.h b/Engine/lib/assimp/code/AssetLib/Assjson/mesh_splitter.h similarity index 59% rename from Engine/lib/assimp/code/Assjson/mesh_splitter.h rename to Engine/lib/assimp/code/AssetLib/Assjson/mesh_splitter.h index 326f73b41..f7f9a9326 100644 --- a/Engine/lib/assimp/code/Assjson/mesh_splitter.h +++ b/Engine/lib/assimp/code/AssetLib/Assjson/mesh_splitter.h @@ -22,40 +22,31 @@ struct aiNode; // --------------------------------------------------------------------------- /** Splits meshes of unique vertices into meshes with no more vertices than - * a given, configurable threshold value. + * a given, configurable threshold value. */ -class MeshSplitter -{ - +class MeshSplitter { public: - - void SetLimit(unsigned int l) { - LIMIT = l; - } + unsigned int LIMIT; - unsigned int GetLimit() const { - return LIMIT; - } + void SetLimit(unsigned int l) { + LIMIT = l; + } -public: + unsigned int GetLimit() const { + return LIMIT; + } - // ------------------------------------------------------------------- - /** Executes the post processing step on the given imported data. + // ------------------------------------------------------------------- + /** Executes the post processing step on the given imported data. * At the moment a process is not supposed to fail. * @param pScene The imported data to work at. */ - void Execute( aiScene* pScene); - + void Execute(aiScene *pScene); private: + void UpdateNode(aiNode *pcNode, const std::vector> &source_mesh_map); + void SplitMesh(unsigned int index, aiMesh *mesh, std::vector> &source_mesh_map); - void UpdateNode(aiNode* pcNode, const std::vector >& source_mesh_map); - void SplitMesh (unsigned int index, aiMesh* mesh, std::vector >& source_mesh_map); - -public: - - unsigned int LIMIT; }; #endif // INCLUDED_MESH_SPLITTER - diff --git a/Engine/lib/assimp/code/AssetLib/Assxml/AssxmlExporter.cpp b/Engine/lib/assimp/code/AssetLib/Assxml/AssxmlExporter.cpp new file mode 100644 index 000000000..731916a25 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/Assxml/AssxmlExporter.cpp @@ -0,0 +1,68 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +/** @file AssxmlExporter.cpp + * ASSXML exporter main code + */ + +#ifndef ASSIMP_BUILD_NO_EXPORT +#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER + +#include "AssxmlFileWriter.h" +#include +#include + +namespace Assimp { + +void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) +{ + DumpSceneToAssxml( + pFile, + "\0", // command(s) + pIOSystem, + pScene, + false); // shortened? +} + +} // end of namespace Assimp + +#endif // ASSIMP_BUILD_NO_ASSXML_EXPORTER +#endif // ASSIMP_BUILD_NO_EXPORT diff --git a/Engine/lib/assimp/code/Assxml/AssxmlExporter.h b/Engine/lib/assimp/code/AssetLib/Assxml/AssxmlExporter.h similarity index 97% rename from Engine/lib/assimp/code/Assxml/AssxmlExporter.h rename to Engine/lib/assimp/code/AssetLib/Assxml/AssxmlExporter.h index 8ca887eea..6fcdebfab 100644 --- a/Engine/lib/assimp/code/Assxml/AssxmlExporter.h +++ b/Engine/lib/assimp/code/AssetLib/Assxml/AssxmlExporter.h @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** @file AssxmlExporter.h * ASSXML Exporter Main Header */ +#pragma once #ifndef AI_ASSXMLEXPORTER_H_INC #define AI_ASSXMLEXPORTER_H_INC diff --git a/Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.cpp b/Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.cpp new file mode 100644 index 000000000..640890ea1 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.cpp @@ -0,0 +1,662 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file AssxmlFileWriter.cpp + * @brief Implementation of Assxml file writer. + */ + +#include "AssxmlFileWriter.h" + +#include "PostProcessing/ProcessHelper.h" + +#include +#include +#include +#include + +#include + +#ifdef ASSIMP_BUILD_NO_OWN_ZLIB +#include +#else +#include +#endif + +#include +#include +#include + +using namespace Assimp; + +namespace Assimp { + +namespace AssxmlFileWriter { + +// ----------------------------------------------------------------------------------- +static int ioprintf(IOStream *io, const char *format, ...) { + using namespace std; + if (nullptr == io) { + return -1; + } + + static const int Size = 4096; + char sz[Size]; + ::memset(sz, '\0', Size); + va_list va; + va_start(va, format); + const unsigned int nSize = vsnprintf(sz, Size - 1, format, va); + ai_assert(nSize < Size); + va_end(va); + + io->Write(sz, sizeof(char), nSize); + + return nSize; +} + +// ----------------------------------------------------------------------------------- +// Convert a name to standard XML format +static void ConvertName(aiString &out, const aiString &in) { + out.length = 0; + for (unsigned int i = 0; i < in.length; ++i) { + switch (in.data[i]) { + case '<': + out.Append("<"); + break; + case '>': + out.Append(">"); + break; + case '&': + out.Append("&"); + break; + case '\"': + out.Append("""); + break; + case '\'': + out.Append("'"); + break; + default: + out.data[out.length++] = in.data[i]; + } + } + out.data[out.length] = 0; +} + +// ----------------------------------------------------------------------------------- +// Write a single node as text dump +static void WriteNode(const aiNode *node, IOStream *io, unsigned int depth) { + char prefix[512]; + for (unsigned int i = 0; i < depth; ++i) + prefix[i] = '\t'; + prefix[depth] = '\0'; + + const aiMatrix4x4 &m = node->mTransformation; + + aiString name; + ConvertName(name, node->mName); + ioprintf(io, "%s \n" + "%s\t \n" + "%s\t\t%0 6f %0 6f %0 6f %0 6f\n" + "%s\t\t%0 6f %0 6f %0 6f %0 6f\n" + "%s\t\t%0 6f %0 6f %0 6f %0 6f\n" + "%s\t\t%0 6f %0 6f %0 6f %0 6f\n" + "%s\t \n", + prefix, name.data, prefix, + prefix, m.a1, m.a2, m.a3, m.a4, + prefix, m.b1, m.b2, m.b3, m.b4, + prefix, m.c1, m.c2, m.c3, m.c4, + prefix, m.d1, m.d2, m.d3, m.d4, prefix); + + if (node->mNumMeshes) { + ioprintf(io, "%s\t\n%s\t", + prefix, node->mNumMeshes, prefix); + + for (unsigned int i = 0; i < node->mNumMeshes; ++i) { + ioprintf(io, "%u ", node->mMeshes[i]); + } + ioprintf(io, "\n%s\t\n", prefix); + } + + if (node->mNumChildren) { + ioprintf(io, "%s\t\n", + prefix, node->mNumChildren); + + for (unsigned int i = 0; i < node->mNumChildren; ++i) { + WriteNode(node->mChildren[i], io, depth + 2); + } + ioprintf(io, "%s\t\n", prefix); + } + ioprintf(io, "%s\n", prefix); +} + +// ----------------------------------------------------------------------------------- +// Some chunks of text will need to be encoded for XML +// http://stackoverflow.com/questions/5665231/most-efficient-way-to-escape-xml-html-in-c-string#5665377 +static std::string encodeXML(const std::string &data) { + std::string buffer; + buffer.reserve(data.size()); + for (size_t pos = 0; pos != data.size(); ++pos) { + switch (data[pos]) { + case '&': buffer.append("&"); break; + case '\"': buffer.append("""); break; + case '\'': buffer.append("'"); break; + case '<': buffer.append("<"); break; + case '>': buffer.append(">"); break; + default: buffer.append(&data[pos], 1); break; + } + } + return buffer; +} + +// ----------------------------------------------------------------------------------- +// Write a text model dump +static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene, IOStream *io, bool shortened) { + time_t tt = ::time(nullptr); +#if _WIN32 + tm *p = gmtime(&tt); +#else + struct tm now; + tm *p = gmtime_r(&tt, &now); +#endif + ai_assert(nullptr != p); + + std::string c = cmd; + std::string::size_type s; + + // https://sourceforge.net/tracker/?func=detail&aid=3167364&group_id=226462&atid=1067632 + // -- not allowed in XML comments + while ((s = c.find("--")) != std::string::npos) { + c[s] = '?'; + } + + // write header + std::string header( + "\n" + "\n\n" + "" + " \n\n" + "\n"); + + const unsigned int majorVersion(aiGetVersionMajor()); + const unsigned int minorVersion(aiGetVersionMinor()); + const unsigned int rev(aiGetVersionRevision()); + const char *curtime(asctime(p)); + ioprintf(io, header.c_str(), majorVersion, minorVersion, rev, pFile, c.c_str(), curtime, scene->mFlags, 0u); + + // write the node graph + WriteNode(scene->mRootNode, io, 0); + +#if 0 + // write cameras + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + aiCamera* cam = scene->mCameras[i]; + ConvertName(name,cam->mName); + + // camera header + ioprintf(io,"\t\n" + "\t\t %0 8f %0 8f %0 8f \n" + "\t\t %0 8f %0 8f %0 8f \n" + "\t\t %0 8f %0 8f %0 8f \n" + "\t\t %f \n" + "\t\t %f \n" + "\t\t %f \n" + "\t\t %f \n" + "\t\n", + name.data, + cam->mUp.x,cam->mUp.y,cam->mUp.z, + cam->mLookAt.x,cam->mLookAt.y,cam->mLookAt.z, + cam->mPosition.x,cam->mPosition.y,cam->mPosition.z, + cam->mHorizontalFOV,cam->mAspect,cam->mClipPlaneNear,cam->mClipPlaneFar,i); + } + + // write lights + for (unsigned int i = 0; i < scene->mNumLights;++i) { + aiLight* l = scene->mLights[i]; + ConvertName(name,l->mName); + + // light header + ioprintf(io,"\t type=\"%s\"\n" + "\t\t %0 8f %0 8f %0 8f \n" + "\t\t %0 8f %0 8f %0 8f \n" + "\t\t %0 8f %0 8f %0 8f \n", + name.data, + (l->mType == aiLightSource_DIRECTIONAL ? "directional" : + (l->mType == aiLightSource_POINT ? "point" : "spot" )), + l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b, + l->mColorSpecular.r,l->mColorSpecular.g,l->mColorSpecular.b, + l->mColorAmbient.r, l->mColorAmbient.g, l->mColorAmbient.b); + + if (l->mType != aiLightSource_DIRECTIONAL) { + ioprintf(io, + "\t\t %0 8f %0 8f %0 8f \n" + "\t\t %f \n" + "\t\t %f \n" + "\t\t %f \n", + l->mPosition.x,l->mPosition.y,l->mPosition.z, + l->mAttenuationConstant,l->mAttenuationLinear,l->mAttenuationQuadratic); + } + + if (l->mType != aiLightSource_POINT) { + ioprintf(io, + "\t\t %0 8f %0 8f %0 8f \n", + l->mDirection.x,l->mDirection.y,l->mDirection.z); + } + + if (l->mType == aiLightSource_SPOT) { + ioprintf(io, + "\t\t %f \n" + "\t\t %f \n", + l->mAngleOuterCone,l->mAngleInnerCone); + } + ioprintf(io,"\t\n"); + } +#endif + aiString name; + + // write textures + if (scene->mNumTextures) { + ioprintf(io, "\n", scene->mNumTextures); + for (unsigned int i = 0; i < scene->mNumTextures; ++i) { + aiTexture *tex = scene->mTextures[i]; + bool compressed = (tex->mHeight == 0); + + // mesh header + ioprintf(io, "\t \n", + (compressed ? -1 : tex->mWidth), (compressed ? -1 : tex->mHeight), + (compressed ? "true" : "false")); + + if (compressed) { + ioprintf(io, "\t\t \n", tex->mWidth); + + if (!shortened) { + for (unsigned int n = 0; n < tex->mWidth; ++n) { + ioprintf(io, "\t\t\t%2x", reinterpret_cast(tex->pcData)[n]); + if (n && !(n % 50)) { + ioprintf(io, "\n"); + } + } + } + } else if (!shortened) { + ioprintf(io, "\t\t \n", tex->mWidth * tex->mHeight * 4); + + // const unsigned int width = (unsigned int)std::log10((double)std::max(tex->mHeight,tex->mWidth))+1; + for (unsigned int y = 0; y < tex->mHeight; ++y) { + for (unsigned int x = 0; x < tex->mWidth; ++x) { + aiTexel *tx = tex->pcData + y * tex->mWidth + x; + unsigned int r = tx->r, g = tx->g, b = tx->b, a = tx->a; + ioprintf(io, "\t\t\t%2x %2x %2x %2x", r, g, b, a); + + // group by four for readability + if (0 == (x + y * tex->mWidth) % 4) { + ioprintf(io, "\n"); + } + } + } + } + ioprintf(io, "\t\t\n\t\n"); + } + ioprintf(io, "\n"); + } + + // write materials + if (scene->mNumMaterials) { + ioprintf(io, "\n", scene->mNumMaterials); + for (unsigned int i = 0; i < scene->mNumMaterials; ++i) { + const aiMaterial *mat = scene->mMaterials[i]; + + ioprintf(io, "\t\n"); + ioprintf(io, "\t\t\n", mat->mNumProperties); + for (unsigned int n = 0; n < mat->mNumProperties; ++n) { + + const aiMaterialProperty *prop = mat->mProperties[n]; + const char *sz = ""; + if (prop->mType == aiPTI_Float) { + sz = "float"; + } else if (prop->mType == aiPTI_Integer) { + sz = "integer"; + } else if (prop->mType == aiPTI_String) { + sz = "string"; + } else if (prop->mType == aiPTI_Buffer) { + sz = "binary_buffer"; + } + + ioprintf(io, "\t\t\tmKey.data, sz, + ::TextureTypeToString((aiTextureType)prop->mSemantic), prop->mIndex); + + if (prop->mType == aiPTI_Float) { + ioprintf(io, " size=\"%i\">\n\t\t\t\t", + static_cast(prop->mDataLength / sizeof(float))); + + for (unsigned int pp = 0; pp < prop->mDataLength / sizeof(float); ++pp) { + ioprintf(io, "%f ", *((float *)(prop->mData + pp * sizeof(float)))); + } + } else if (prop->mType == aiPTI_Integer) { + ioprintf(io, " size=\"%i\">\n\t\t\t\t", + static_cast(prop->mDataLength / sizeof(int))); + + for (unsigned int pp = 0; pp < prop->mDataLength / sizeof(int); ++pp) { + ioprintf(io, "%i ", *((int *)(prop->mData + pp * sizeof(int)))); + } + } else if (prop->mType == aiPTI_Buffer) { + ioprintf(io, " size=\"%i\">\n\t\t\t\t", + static_cast(prop->mDataLength)); + + for (unsigned int pp = 0; pp < prop->mDataLength; ++pp) { + ioprintf(io, "%2x ", prop->mData[pp]); + if (pp && 0 == pp % 30) { + ioprintf(io, "\n\t\t\t\t"); + } + } + } else if (prop->mType == aiPTI_String) { + ioprintf(io, ">\n\t\t\t\t\"%s\"", encodeXML(prop->mData + 4).c_str() /* skip length */); + } + ioprintf(io, "\n\t\t\t\n"); + } + ioprintf(io, "\t\t\n"); + ioprintf(io, "\t\n"); + } + ioprintf(io, "\n"); + } + + // write animations + if (scene->mNumAnimations) { + ioprintf(io, "\n", scene->mNumAnimations); + for (unsigned int i = 0; i < scene->mNumAnimations; ++i) { + aiAnimation *anim = scene->mAnimations[i]; + + // anim header + ConvertName(name, anim->mName); + ioprintf(io, "\t\n", + name.data, anim->mDuration, anim->mTicksPerSecond); + + // write bone animation channels + if (anim->mNumChannels) { + ioprintf(io, "\t\t\n", anim->mNumChannels); + for (unsigned int n = 0; n < anim->mNumChannels; ++n) { + aiNodeAnim *nd = anim->mChannels[n]; + + // node anim header + ConvertName(name, nd->mNodeName); + ioprintf(io, "\t\t\t\n", name.data); + + if (!shortened) { + // write position keys + if (nd->mNumPositionKeys) { + ioprintf(io, "\t\t\t\t\n", nd->mNumPositionKeys); + for (unsigned int a = 0; a < nd->mNumPositionKeys; ++a) { + aiVectorKey *vc = nd->mPositionKeys + a; + ioprintf(io, "\t\t\t\t\t\n" + "\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t\n", + vc->mTime, vc->mValue.x, vc->mValue.y, vc->mValue.z); + } + ioprintf(io, "\t\t\t\t\n"); + } + + // write scaling keys + if (nd->mNumScalingKeys) { + ioprintf(io, "\t\t\t\t\n", nd->mNumScalingKeys); + for (unsigned int a = 0; a < nd->mNumScalingKeys; ++a) { + aiVectorKey *vc = nd->mScalingKeys + a; + ioprintf(io, "\t\t\t\t\t\n" + "\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t\n", + vc->mTime, vc->mValue.x, vc->mValue.y, vc->mValue.z); + } + ioprintf(io, "\t\t\t\t\n"); + } + + // write rotation keys + if (nd->mNumRotationKeys) { + ioprintf(io, "\t\t\t\t\n", nd->mNumRotationKeys); + for (unsigned int a = 0; a < nd->mNumRotationKeys; ++a) { + aiQuatKey *vc = nd->mRotationKeys + a; + ioprintf(io, "\t\t\t\t\t\n" + "\t\t\t\t\t\t%0 8f %0 8f %0 8f %0 8f\n\t\t\t\t\t\n", + vc->mTime, vc->mValue.x, vc->mValue.y, vc->mValue.z, vc->mValue.w); + } + ioprintf(io, "\t\t\t\t\n"); + } + } + ioprintf(io, "\t\t\t\n"); + } + ioprintf(io, "\t\t\n"); + } + ioprintf(io, "\t\n"); + } + ioprintf(io, "\n"); + } + + // write meshes + if (scene->mNumMeshes) { + ioprintf(io, "\n", scene->mNumMeshes); + for (unsigned int i = 0; i < scene->mNumMeshes; ++i) { + aiMesh *mesh = scene->mMeshes[i]; + // const unsigned int width = (unsigned int)std::log10((double)mesh->mNumVertices)+1; + + // mesh header + ioprintf(io, "\t\n", + (mesh->mPrimitiveTypes & aiPrimitiveType_POINT ? "points" : ""), + (mesh->mPrimitiveTypes & aiPrimitiveType_LINE ? "lines" : ""), + (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE ? "triangles" : ""), + (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON ? "polygons" : ""), + mesh->mMaterialIndex); + + // bones + if (mesh->mNumBones) { + ioprintf(io, "\t\t\n", mesh->mNumBones); + + for (unsigned int n = 0; n < mesh->mNumBones; ++n) { + aiBone *bone = mesh->mBones[n]; + + ConvertName(name, bone->mName); + // bone header + ioprintf(io, "\t\t\t\n" + "\t\t\t\t \n" + "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n" + "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n" + "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n" + "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n" + "\t\t\t\t \n", + name.data, + bone->mOffsetMatrix.a1, bone->mOffsetMatrix.a2, bone->mOffsetMatrix.a3, bone->mOffsetMatrix.a4, + bone->mOffsetMatrix.b1, bone->mOffsetMatrix.b2, bone->mOffsetMatrix.b3, bone->mOffsetMatrix.b4, + bone->mOffsetMatrix.c1, bone->mOffsetMatrix.c2, bone->mOffsetMatrix.c3, bone->mOffsetMatrix.c4, + bone->mOffsetMatrix.d1, bone->mOffsetMatrix.d2, bone->mOffsetMatrix.d3, bone->mOffsetMatrix.d4); + + if (!shortened && bone->mNumWeights) { + ioprintf(io, "\t\t\t\t\n", bone->mNumWeights); + + // bone weights + for (unsigned int a = 0; a < bone->mNumWeights; ++a) { + aiVertexWeight *wght = bone->mWeights + a; + + ioprintf(io, "\t\t\t\t\t\n\t\t\t\t\t\t%f\n\t\t\t\t\t\n", + wght->mVertexId, wght->mWeight); + } + ioprintf(io, "\t\t\t\t\n"); + } + ioprintf(io, "\t\t\t\n"); + } + ioprintf(io, "\t\t\n"); + } + + // faces + if (!shortened && mesh->mNumFaces) { + ioprintf(io, "\t\t\n", mesh->mNumFaces); + for (unsigned int n = 0; n < mesh->mNumFaces; ++n) { + aiFace &f = mesh->mFaces[n]; + ioprintf(io, "\t\t\t\n" + "\t\t\t\t", + f.mNumIndices); + + for (unsigned int j = 0; j < f.mNumIndices; ++j) + ioprintf(io, "%u ", f.mIndices[j]); + + ioprintf(io, "\n\t\t\t\n"); + } + ioprintf(io, "\t\t\n"); + } + + // vertex positions + if (mesh->HasPositions()) { + ioprintf(io, "\t\t \n", mesh->mNumVertices); + if (!shortened) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + ioprintf(io, "\t\t%0 8f %0 8f %0 8f\n", + mesh->mVertices[n].x, + mesh->mVertices[n].y, + mesh->mVertices[n].z); + } + } + ioprintf(io, "\t\t\n"); + } + + // vertex normals + if (mesh->HasNormals()) { + ioprintf(io, "\t\t \n", mesh->mNumVertices); + if (!shortened) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + ioprintf(io, "\t\t%0 8f %0 8f %0 8f\n", + mesh->mNormals[n].x, + mesh->mNormals[n].y, + mesh->mNormals[n].z); + } + } + ioprintf(io, "\t\t\n"); + } + + // vertex tangents and bitangents + if (mesh->HasTangentsAndBitangents()) { + ioprintf(io, "\t\t \n", mesh->mNumVertices); + if (!shortened) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + ioprintf(io, "\t\t%0 8f %0 8f %0 8f\n", + mesh->mTangents[n].x, + mesh->mTangents[n].y, + mesh->mTangents[n].z); + } + } + ioprintf(io, "\t\t\n"); + + ioprintf(io, "\t\t \n", mesh->mNumVertices); + if (!shortened) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + ioprintf(io, "\t\t%0 8f %0 8f %0 8f\n", + mesh->mBitangents[n].x, + mesh->mBitangents[n].y, + mesh->mBitangents[n].z); + } + } + ioprintf(io, "\t\t\n"); + } + + // texture coordinates + for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) { + if (!mesh->mTextureCoords[a]) + break; + + ioprintf(io, "\t\t \n", + mesh->mNumVertices, + a, + (mesh->HasTextureCoordsName(a) ? mesh->GetTextureCoordsName(a)->C_Str() : ""), + mesh->mNumUVComponents[a]); + + if (!shortened) { + if (mesh->mNumUVComponents[a] == 3) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + ioprintf(io, "\t\t%0 8f %0 8f %0 8f\n", + mesh->mTextureCoords[a][n].x, + mesh->mTextureCoords[a][n].y, + mesh->mTextureCoords[a][n].z); + } + } else { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + ioprintf(io, "\t\t%0 8f %0 8f\n", + mesh->mTextureCoords[a][n].x, + mesh->mTextureCoords[a][n].y); + } + } + } + ioprintf(io, "\t\t\n"); + } + + // vertex colors + for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) { + if (!mesh->mColors[a]) + break; + ioprintf(io, "\t\t \n", mesh->mNumVertices, a); + if (!shortened) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + ioprintf(io, "\t\t%0 8f %0 8f %0 8f %0 8f\n", + mesh->mColors[a][n].r, + mesh->mColors[a][n].g, + mesh->mColors[a][n].b, + mesh->mColors[a][n].a); + } + } + ioprintf(io, "\t\t\n"); + } + ioprintf(io, "\t\n"); + } + ioprintf(io, "\n"); + } + ioprintf(io, "\n"); +} + +} // end of namespace AssxmlFileWriter + +void DumpSceneToAssxml( + const char *pFile, const char *cmd, IOSystem *pIOSystem, + const aiScene *pScene, bool shortened) { + std::unique_ptr file(pIOSystem->Open(pFile, "wt")); + if (!file.get()) { + throw std::runtime_error("Unable to open output file " + std::string(pFile) + '\n'); + } + + AssxmlFileWriter::WriteDump(pFile, cmd, pScene, file.get(), shortened); +} + +} // end of namespace Assimp diff --git a/Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.h b/Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.h new file mode 100644 index 000000000..0620c9db7 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.h @@ -0,0 +1,64 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file AssxmlFileWriter.h + * @brief Declaration of Assxml file writer. + */ +#pragma once +#ifndef AI_ASSXMLFILEWRITER_H_INC +#define AI_ASSXMLFILEWRITER_H_INC + +#include +#include +#include + +namespace Assimp { + +void ASSIMP_API DumpSceneToAssxml( + const char* pFile, + const char* cmd, + IOSystem* pIOSystem, + const aiScene* pScene, + bool shortened); + +} + +#endif // AI_ASSXMLFILEWRITER_H_INC diff --git a/Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.cpp b/Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.cpp new file mode 100644 index 000000000..c4ef75be3 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.cpp @@ -0,0 +1,744 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file B3DImporter.cpp + * @brief Implementation of the b3d importer class + */ + +#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER + +// internal headers +#include "AssetLib/B3D/B3DImporter.h" +#include "PostProcessing/ConvertToLHProcess.h" +#include "PostProcessing/TextureTransform.h" + +#include +#include +#include +#include +#include +#include + +#include + +using namespace Assimp; +using namespace std; + +static const aiImporterDesc desc = { + "BlitzBasic 3D Importer", + "", + "", + "http://www.blitzbasic.com/", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "b3d" +}; + +#ifdef _MSC_VER +#pragma warning(disable : 4018) +#endif + +//#define DEBUG_B3D + +template +void DeleteAllBarePointers(std::vector &x) { + for (auto p : x) { + delete p; + } +} + +B3DImporter::~B3DImporter() { + // empty +} + +// ------------------------------------------------------------------------------------------------ +bool B3DImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const { + size_t pos = pFile.find_last_of('.'); + if (pos == string::npos) { + return false; + } + + string ext = pFile.substr(pos + 1); + if (ext.size() != 3) { + return false; + } + + return (ext[0] == 'b' || ext[0] == 'B') && (ext[1] == '3') && (ext[2] == 'd' || ext[2] == 'D'); +} + +// ------------------------------------------------------------------------------------------------ +// Loader meta information +const aiImporterDesc *B3DImporter::GetInfo() const { + return &desc; +} + +// ------------------------------------------------------------------------------------------------ +void B3DImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { + std::unique_ptr file(pIOHandler->Open(pFile)); + + // Check whether we can read from the file + if (file.get() == nullptr) { + throw DeadlyImportError("Failed to open B3D file ", pFile, "."); + } + + // check whether the .b3d file is large enough to contain + // at least one chunk. + size_t fileSize = file->FileSize(); + if (fileSize < 8) { + throw DeadlyImportError("B3D File is too small."); + } + + _pos = 0; + _buf.resize(fileSize); + file->Read(&_buf[0], 1, fileSize); + _stack.clear(); + + ReadBB3D(pScene); +} + +// ------------------------------------------------------------------------------------------------ +AI_WONT_RETURN void B3DImporter::Oops() { + throw DeadlyImportError("B3D Importer - INTERNAL ERROR"); +} + +// ------------------------------------------------------------------------------------------------ +AI_WONT_RETURN void B3DImporter::Fail(const string &str) { +#ifdef DEBUG_B3D + ASSIMP_LOG_ERROR("Error in B3D file data: ", str); +#endif + throw DeadlyImportError("B3D Importer - error in B3D file data: ", str); +} + +// ------------------------------------------------------------------------------------------------ +int B3DImporter::ReadByte() { + if (_pos > _buf.size()) { + Fail("EOF"); + } + + return _buf[_pos++]; +} + +// ------------------------------------------------------------------------------------------------ +int B3DImporter::ReadInt() { + if (_pos + 4 > _buf.size()) { + Fail("EOF"); + } + + int n; + memcpy(&n, &_buf[_pos], 4); + _pos += 4; + + return n; +} + +// ------------------------------------------------------------------------------------------------ +float B3DImporter::ReadFloat() { + if (_pos + 4 > _buf.size()) { + Fail("EOF"); + } + + float n; + memcpy(&n, &_buf[_pos], 4); + _pos += 4; + + return n; +} + +// ------------------------------------------------------------------------------------------------ +aiVector2D B3DImporter::ReadVec2() { + float x = ReadFloat(); + float y = ReadFloat(); + return aiVector2D(x, y); +} + +// ------------------------------------------------------------------------------------------------ +aiVector3D B3DImporter::ReadVec3() { + float x = ReadFloat(); + float y = ReadFloat(); + float z = ReadFloat(); + return aiVector3D(x, y, z); +} + +// ------------------------------------------------------------------------------------------------ +aiQuaternion B3DImporter::ReadQuat() { + // (aramis_acg) Fix to adapt the loader to changed quat orientation + float w = -ReadFloat(); + float x = ReadFloat(); + float y = ReadFloat(); + float z = ReadFloat(); + return aiQuaternion(w, x, y, z); +} + +// ------------------------------------------------------------------------------------------------ +string B3DImporter::ReadString() { + if (_pos > _buf.size()) { + Fail("EOF"); + } + string str; + while (_pos < _buf.size()) { + char c = (char)ReadByte(); + if (!c) { + return str; + } + str += c; + } + return string(); +} + +// ------------------------------------------------------------------------------------------------ +string B3DImporter::ReadChunk() { + string tag; + for (int i = 0; i < 4; ++i) { + tag += char(ReadByte()); + } +#ifdef DEBUG_B3D + ASSIMP_LOG_DEBUG("ReadChunk: ", tag); +#endif + unsigned sz = (unsigned)ReadInt(); + _stack.push_back(_pos + sz); + return tag; +} + +// ------------------------------------------------------------------------------------------------ +void B3DImporter::ExitChunk() { + _pos = _stack.back(); + _stack.pop_back(); +} + +// ------------------------------------------------------------------------------------------------ +size_t B3DImporter::ChunkSize() { + return _stack.back() - _pos; +} +// ------------------------------------------------------------------------------------------------ + +template +T *B3DImporter::to_array(const vector &v) { + if (v.empty()) { + return 0; + } + T *p = new T[v.size()]; + for (size_t i = 0; i < v.size(); ++i) { + p[i] = v[i]; + } + return p; +} + +// ------------------------------------------------------------------------------------------------ +template +T **unique_to_array(vector> &v) { + if (v.empty()) { + return 0; + } + T **p = new T *[v.size()]; + for (size_t i = 0; i < v.size(); ++i) { + p[i] = v[i].release(); + } + return p; +} + +// ------------------------------------------------------------------------------------------------ +void B3DImporter::ReadTEXS() { + while (ChunkSize()) { + string name = ReadString(); + /*int flags=*/ReadInt(); + /*int blend=*/ReadInt(); + /*aiVector2D pos=*/ReadVec2(); + /*aiVector2D scale=*/ReadVec2(); + /*float rot=*/ReadFloat(); + + _textures.push_back(name); + } +} + +// ------------------------------------------------------------------------------------------------ +void B3DImporter::ReadBRUS() { + int n_texs = ReadInt(); + if (n_texs < 0 || n_texs > 8) { + Fail("Bad texture count"); + } + while (ChunkSize()) { + string name = ReadString(); + aiVector3D color = ReadVec3(); + float alpha = ReadFloat(); + float shiny = ReadFloat(); + /*int blend=**/ ReadInt(); + int fx = ReadInt(); + + std::unique_ptr mat(new aiMaterial); + + // Name + aiString ainame(name); + mat->AddProperty(&ainame, AI_MATKEY_NAME); + + // Diffuse color + mat->AddProperty(&color, 1, AI_MATKEY_COLOR_DIFFUSE); + + // Opacity + mat->AddProperty(&alpha, 1, AI_MATKEY_OPACITY); + + // Specular color + aiColor3D speccolor(shiny, shiny, shiny); + mat->AddProperty(&speccolor, 1, AI_MATKEY_COLOR_SPECULAR); + + // Specular power + float specpow = shiny * 128; + mat->AddProperty(&specpow, 1, AI_MATKEY_SHININESS); + + // Double sided + if (fx & 0x10) { + int i = 1; + mat->AddProperty(&i, 1, AI_MATKEY_TWOSIDED); + } + + //Textures + for (int i = 0; i < n_texs; ++i) { + int texid = ReadInt(); + if (texid < -1 || (texid >= 0 && texid >= static_cast(_textures.size()))) { + Fail("Bad texture id"); + } + if (i == 0 && texid >= 0) { + aiString texname(_textures[texid]); + mat->AddProperty(&texname, AI_MATKEY_TEXTURE_DIFFUSE(0)); + } + } + _materials.emplace_back(std::move(mat)); + } +} + +// ------------------------------------------------------------------------------------------------ +void B3DImporter::ReadVRTS() { + _vflags = ReadInt(); + _tcsets = ReadInt(); + _tcsize = ReadInt(); + if (_tcsets < 0 || _tcsets > 4 || _tcsize < 0 || _tcsize > 4) { + Fail("Bad texcoord data"); + } + + int sz = 12 + (_vflags & 1 ? 12 : 0) + (_vflags & 2 ? 16 : 0) + (_tcsets * _tcsize * 4); + size_t n_verts = ChunkSize() / sz; + + int v0 = static_cast(_vertices.size()); + _vertices.resize(v0 + n_verts); + + for (unsigned int i = 0; i < n_verts; ++i) { + Vertex &v = _vertices[v0 + i]; + + memset(v.bones, 0, sizeof(v.bones)); + memset(v.weights, 0, sizeof(v.weights)); + + v.vertex = ReadVec3(); + + if (_vflags & 1) { + v.normal = ReadVec3(); + } + + if (_vflags & 2) { + ReadQuat(); //skip v 4bytes... + } + + for (int j = 0; j < _tcsets; ++j) { + float t[4] = { 0, 0, 0, 0 }; + for (int k = 0; k < _tcsize; ++k) { + t[k] = ReadFloat(); + } + t[1] = 1 - t[1]; + if (!j) { + v.texcoords = aiVector3D(t[0], t[1], t[2]); + } + } + } +} + +// ------------------------------------------------------------------------------------------------ +void B3DImporter::ReadTRIS(int v0) { + int matid = ReadInt(); + if (matid == -1) { + matid = 0; + } else if (matid < 0 || matid >= (int)_materials.size()) { +#ifdef DEBUG_B3D + ASSIMP_LOG_ERROR("material id=", matid); +#endif + Fail("Bad material id"); + } + + std::unique_ptr mesh(new aiMesh); + + mesh->mMaterialIndex = matid; + mesh->mNumFaces = 0; + mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; + + size_t n_tris = ChunkSize() / 12; + aiFace *face = mesh->mFaces = new aiFace[n_tris]; + + for (unsigned int i = 0; i < n_tris; ++i) { + int i0 = ReadInt() + v0; + int i1 = ReadInt() + v0; + int i2 = ReadInt() + v0; + if (i0 < 0 || i0 >= (int)_vertices.size() || i1 < 0 || i1 >= (int)_vertices.size() || i2 < 0 || i2 >= (int)_vertices.size()) { +#ifdef DEBUG_B3D + ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2); +#endif + Fail("Bad triangle index"); + continue; + } + face->mNumIndices = 3; + face->mIndices = new unsigned[3]; + face->mIndices[0] = i0; + face->mIndices[1] = i1; + face->mIndices[2] = i2; + ++mesh->mNumFaces; + ++face; + } + + _meshes.emplace_back(std::move(mesh)); +} + +// ------------------------------------------------------------------------------------------------ +void B3DImporter::ReadMESH() { + /*int matid=*/ReadInt(); + + int v0 = static_cast(_vertices.size()); + + while (ChunkSize()) { + string t = ReadChunk(); + if (t == "VRTS") { + ReadVRTS(); + } else if (t == "TRIS") { + ReadTRIS(v0); + } + ExitChunk(); + } +} + +// ------------------------------------------------------------------------------------------------ +void B3DImporter::ReadBONE(int id) { + while (ChunkSize()) { + int vertex = ReadInt(); + float weight = ReadFloat(); + if (vertex < 0 || vertex >= (int)_vertices.size()) { + Fail("Bad vertex index"); + } + + Vertex &v = _vertices[vertex]; + for (int i = 0; i < 4; ++i) { + if (!v.weights[i]) { + v.bones[i] = static_cast(id); + v.weights[i] = weight; + break; + } + } + } +} + +// ------------------------------------------------------------------------------------------------ +void B3DImporter::ReadKEYS(aiNodeAnim *nodeAnim) { + vector trans, scale; + vector rot; + int flags = ReadInt(); + while (ChunkSize()) { + int frame = ReadInt(); + if (flags & 1) { + trans.push_back(aiVectorKey(frame, ReadVec3())); + } + if (flags & 2) { + scale.push_back(aiVectorKey(frame, ReadVec3())); + } + if (flags & 4) { + rot.push_back(aiQuatKey(frame, ReadQuat())); + } + } + + if (flags & 1) { + nodeAnim->mNumPositionKeys = static_cast(trans.size()); + nodeAnim->mPositionKeys = to_array(trans); + } + + if (flags & 2) { + nodeAnim->mNumScalingKeys = static_cast(scale.size()); + nodeAnim->mScalingKeys = to_array(scale); + } + + if (flags & 4) { + nodeAnim->mNumRotationKeys = static_cast(rot.size()); + nodeAnim->mRotationKeys = to_array(rot); + } +} + +// ------------------------------------------------------------------------------------------------ +void B3DImporter::ReadANIM() { + /*int flags=*/ReadInt(); + int frames = ReadInt(); + float fps = ReadFloat(); + + std::unique_ptr anim(new aiAnimation); + + anim->mDuration = frames; + anim->mTicksPerSecond = fps; + _animations.emplace_back(std::move(anim)); +} + +// ------------------------------------------------------------------------------------------------ +aiNode *B3DImporter::ReadNODE(aiNode *parent) { + + string name = ReadString(); + aiVector3D t = ReadVec3(); + aiVector3D s = ReadVec3(); + aiQuaternion r = ReadQuat(); + + aiMatrix4x4 trans, scale, rot; + + aiMatrix4x4::Translation(t, trans); + aiMatrix4x4::Scaling(s, scale); + rot = aiMatrix4x4(r.GetMatrix()); + + aiMatrix4x4 tform = trans * rot * scale; + + int nodeid = static_cast(_nodes.size()); + + aiNode *node = new aiNode(name); + _nodes.push_back(node); + + node->mParent = parent; + node->mTransformation = tform; + + std::unique_ptr nodeAnim; + vector meshes; + vector children; + + while (ChunkSize()) { + const string chunk = ReadChunk(); + if (chunk == "MESH") { + unsigned int n = static_cast(_meshes.size()); + ReadMESH(); + for (unsigned int i = n; i < static_cast(_meshes.size()); ++i) { + meshes.push_back(i); + } + } else if (chunk == "BONE") { + ReadBONE(nodeid); + } else if (chunk == "ANIM") { + ReadANIM(); + } else if (chunk == "KEYS") { + if (!nodeAnim) { + nodeAnim.reset(new aiNodeAnim); + nodeAnim->mNodeName = node->mName; + } + ReadKEYS(nodeAnim.get()); + } else if (chunk == "NODE") { + aiNode *child = ReadNODE(node); + children.push_back(child); + } + ExitChunk(); + } + + if (nodeAnim) { + _nodeAnims.emplace_back(std::move(nodeAnim)); + } + + node->mNumMeshes = static_cast(meshes.size()); + node->mMeshes = to_array(meshes); + + node->mNumChildren = static_cast(children.size()); + node->mChildren = to_array(children); + + return node; +} + +// ------------------------------------------------------------------------------------------------ +void B3DImporter::ReadBB3D(aiScene *scene) { + + _textures.clear(); + + _materials.clear(); + + _vertices.clear(); + + _meshes.clear(); + + DeleteAllBarePointers(_nodes); + _nodes.clear(); + + _nodeAnims.clear(); + + _animations.clear(); + + string t = ReadChunk(); + if (t == "BB3D") { + int version = ReadInt(); + + if (!DefaultLogger::isNullLogger()) { + char dmp[128]; + ai_snprintf(dmp, 128, "B3D file format version: %i", version); + ASSIMP_LOG_INFO(dmp); + } + + while (ChunkSize()) { + const string chunk = ReadChunk(); + if (chunk == "TEXS") { + ReadTEXS(); + } else if (chunk == "BRUS") { + ReadBRUS(); + } else if (chunk == "NODE") { + ReadNODE(0); + } + ExitChunk(); + } + } + ExitChunk(); + + if (!_nodes.size()) { + Fail("No nodes"); + } + + if (!_meshes.size()) { + Fail("No meshes"); + } + + // Fix nodes/meshes/bones + for (size_t i = 0; i < _nodes.size(); ++i) { + aiNode *node = _nodes[i]; + + for (size_t j = 0; j < node->mNumMeshes; ++j) { + aiMesh *mesh = _meshes[node->mMeshes[j]].get(); + + int n_tris = mesh->mNumFaces; + int n_verts = mesh->mNumVertices = n_tris * 3; + + aiVector3D *mv = mesh->mVertices = new aiVector3D[n_verts], *mn = 0, *mc = 0; + if (_vflags & 1) { + mn = mesh->mNormals = new aiVector3D[n_verts]; + } + if (_tcsets) { + mc = mesh->mTextureCoords[0] = new aiVector3D[n_verts]; + } + + aiFace *face = mesh->mFaces; + + vector> vweights(_nodes.size()); + + for (int vertIdx = 0; vertIdx < n_verts; vertIdx += 3) { + for (int faceIndex = 0; faceIndex < 3; ++faceIndex) { + Vertex &v = _vertices[face->mIndices[faceIndex]]; + + *mv++ = v.vertex; + if (mn) *mn++ = v.normal; + if (mc) *mc++ = v.texcoords; + + face->mIndices[faceIndex] = vertIdx + faceIndex; + + for (int k = 0; k < 4; ++k) { + if (!v.weights[k]) + break; + + int bone = v.bones[k]; + float weight = v.weights[k]; + + vweights[bone].push_back(aiVertexWeight(vertIdx + faceIndex, weight)); + } + } + ++face; + } + + vector bones; + for (size_t weightIndx = 0; weightIndx < vweights.size(); ++weightIndx) { + vector &weights = vweights[weightIndx]; + if (!weights.size()) { + continue; + } + + aiBone *bone = new aiBone; + bones.push_back(bone); + + aiNode *bnode = _nodes[weightIndx]; + + bone->mName = bnode->mName; + bone->mNumWeights = static_cast(weights.size()); + bone->mWeights = to_array(weights); + + aiMatrix4x4 mat = bnode->mTransformation; + while (bnode->mParent) { + bnode = bnode->mParent; + mat = bnode->mTransformation * mat; + } + bone->mOffsetMatrix = mat.Inverse(); + } + mesh->mNumBones = static_cast(bones.size()); + mesh->mBones = to_array(bones); + } + } + + //nodes + scene->mRootNode = _nodes[0]; + _nodes.clear(); // node ownership now belongs to scene + + //material + if (!_materials.size()) { + _materials.emplace_back(std::unique_ptr(new aiMaterial)); + } + scene->mNumMaterials = static_cast(_materials.size()); + scene->mMaterials = unique_to_array(_materials); + + //meshes + scene->mNumMeshes = static_cast(_meshes.size()); + scene->mMeshes = unique_to_array(_meshes); + + //animations + if (_animations.size() == 1 && _nodeAnims.size()) { + + aiAnimation *anim = _animations.back().get(); + anim->mNumChannels = static_cast(_nodeAnims.size()); + anim->mChannels = unique_to_array(_nodeAnims); + + scene->mNumAnimations = static_cast(_animations.size()); + scene->mAnimations = unique_to_array(_animations); + } + + // convert to RH + MakeLeftHandedProcess makeleft; + makeleft.Execute(scene); + + FlipWindingOrderProcess flip; + flip.Execute(scene); +} + +#endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER diff --git a/Engine/lib/assimp/code/B3D/B3DImporter.h b/Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.h similarity index 85% rename from Engine/lib/assimp/code/B3D/B3DImporter.h rename to Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.h index d52dac34a..e47d9078b 100644 --- a/Engine/lib/assimp/code/B3D/B3DImporter.h +++ b/Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.h @@ -2,8 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team - +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -40,8 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ -/** @file Definition of the .b3d importer class. */ - +/** + * @file Definition of the .b3d importer class. + */ +#pragma once #ifndef AI_B3DIMPORTER_H_INC #define AI_B3DIMPORTER_H_INC @@ -62,14 +63,12 @@ namespace Assimp{ class B3DImporter : public BaseImporter{ public: B3DImporter() = default; - virtual ~B3DImporter(); - - virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const; + ~B3DImporter() override; + bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override; protected: - - virtual const aiImporterDesc* GetInfo () const; - virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); + const aiImporterDesc* GetInfo () const override; + void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override; private: @@ -82,7 +81,7 @@ private: std::string ReadString(); std::string ReadChunk(); void ExitChunk(); - unsigned ChunkSize(); + size_t ChunkSize(); template T *to_array( const std::vector &v ); @@ -96,7 +95,7 @@ private: }; AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX; - AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX; + AI_WONT_RETURN void Fail(const std::string &str) AI_WONT_RETURN_SUFFIX; void ReadTEXS(); void ReadBRUS(); @@ -112,10 +111,9 @@ private: void ReadBB3D( aiScene *scene ); - unsigned _pos; -// unsigned _size; + size_t _pos; std::vector _buf; - std::vector _stack; + std::vector _stack; std::vector _textures; std::vector > _materials; diff --git a/Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.cpp b/Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.cpp new file mode 100644 index 000000000..174836847 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.cpp @@ -0,0 +1,528 @@ +/** Implementation of the BVH loader */ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER + +#include "BVHLoader.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Assimp; +using namespace Assimp::Formatter; + +static const aiImporterDesc desc = { + "BVH Importer (MoCap)", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "bvh" +}; + +// ------------------------------------------------------------------------------------------------ +// Aborts the file reading with an exception +template +AI_WONT_RETURN void BVHLoader::ThrowException(T&&... args) { + throw DeadlyImportError(mFileName, ":", mLine, " - ", args...); +} + +// ------------------------------------------------------------------------------------------------ +// Constructor to be privately used by Importer +BVHLoader::BVHLoader() : + mLine(), + mAnimTickDuration(), + mAnimNumFrames(), + noSkeletonMesh() {} + +// ------------------------------------------------------------------------------------------------ +// Destructor, private as well +BVHLoader::~BVHLoader() {} + +// ------------------------------------------------------------------------------------------------ +// Returns whether the class can handle the format of the given file. +bool BVHLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { + static const char *tokens[] = { "HIERARCHY" }; + return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); +} + +// ------------------------------------------------------------------------------------------------ +void BVHLoader::SetupProperties(const Importer *pImp) { + noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0; +} + +// ------------------------------------------------------------------------------------------------ +// Loader meta information +const aiImporterDesc *BVHLoader::GetInfo() const { + return &desc; +} + +// ------------------------------------------------------------------------------------------------ +// Imports the given file into the given scene structure. +void BVHLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { + mFileName = pFile; + + // read file into memory + std::unique_ptr file(pIOHandler->Open(pFile)); + if (file.get() == nullptr) { + throw DeadlyImportError("Failed to open file ", pFile, "."); + } + + size_t fileSize = file->FileSize(); + if (fileSize == 0) { + throw DeadlyImportError("File is too small."); + } + + mBuffer.resize(fileSize); + file->Read(&mBuffer.front(), 1, fileSize); + + // start reading + mReader = mBuffer.begin(); + mLine = 1; + ReadStructure(pScene); + + if (!noSkeletonMesh) { + // build a dummy mesh for the skeleton so that we see something at least + SkeletonMeshBuilder meshBuilder(pScene); + } + + // construct an animation from all the motion data we read + CreateAnimation(pScene); +} + +// ------------------------------------------------------------------------------------------------ +// Reads the file +void BVHLoader::ReadStructure(aiScene *pScene) { + // first comes hierarchy + std::string header = GetNextToken(); + if (header != "HIERARCHY") + ThrowException("Expected header string \"HIERARCHY\"."); + ReadHierarchy(pScene); + + // then comes the motion data + std::string motion = GetNextToken(); + if (motion != "MOTION") + ThrowException("Expected beginning of motion data \"MOTION\"."); + ReadMotion(pScene); +} + +// ------------------------------------------------------------------------------------------------ +// Reads the hierarchy +void BVHLoader::ReadHierarchy(aiScene *pScene) { + std::string root = GetNextToken(); + if (root != "ROOT") + ThrowException("Expected root node \"ROOT\"."); + + // Go read the hierarchy from here + pScene->mRootNode = ReadNode(); +} + +// ------------------------------------------------------------------------------------------------ +// Reads a node and recursively its children and returns the created node; +aiNode *BVHLoader::ReadNode() { + // first token is name + std::string nodeName = GetNextToken(); + if (nodeName.empty() || nodeName == "{") + ThrowException("Expected node name, but found \"", nodeName, "\"."); + + // then an opening brace should follow + std::string openBrace = GetNextToken(); + if (openBrace != "{") + ThrowException("Expected opening brace \"{\", but found \"", openBrace, "\"."); + + // Create a node + aiNode *node = new aiNode(nodeName); + std::vector childNodes; + + // and create an bone entry for it + mNodes.push_back(Node(node)); + Node &internNode = mNodes.back(); + + // now read the node's contents + std::string siteToken; + while (1) { + std::string token = GetNextToken(); + + // node offset to parent node + if (token == "OFFSET") + ReadNodeOffset(node); + else if (token == "CHANNELS") + ReadNodeChannels(internNode); + else if (token == "JOINT") { + // child node follows + aiNode *child = ReadNode(); + child->mParent = node; + childNodes.push_back(child); + } else if (token == "End") { + // The real symbol is "End Site". Second part comes in a separate token + siteToken.clear(); + siteToken = GetNextToken(); + if (siteToken != "Site") + ThrowException("Expected \"End Site\" keyword, but found \"", token, " ", siteToken, "\"."); + + aiNode *child = ReadEndSite(nodeName); + child->mParent = node; + childNodes.push_back(child); + } else if (token == "}") { + // we're done with that part of the hierarchy + break; + } else { + // everything else is a parse error + ThrowException("Unknown keyword \"", token, "\"."); + } + } + + // add the child nodes if there are any + if (childNodes.size() > 0) { + node->mNumChildren = static_cast(childNodes.size()); + node->mChildren = new aiNode *[node->mNumChildren]; + std::copy(childNodes.begin(), childNodes.end(), node->mChildren); + } + + // and return the sub-hierarchy we built here + return node; +} + +// ------------------------------------------------------------------------------------------------ +// Reads an end node and returns the created node. +aiNode *BVHLoader::ReadEndSite(const std::string &pParentName) { + // check opening brace + std::string openBrace = GetNextToken(); + if (openBrace != "{") + ThrowException("Expected opening brace \"{\", but found \"", openBrace, "\"."); + + // Create a node + aiNode *node = new aiNode("EndSite_" + pParentName); + + // now read the node's contents. Only possible entry is "OFFSET" + std::string token; + while (1) { + token.clear(); + token = GetNextToken(); + + // end node's offset + if (token == "OFFSET") { + ReadNodeOffset(node); + } else if (token == "}") { + // we're done with the end node + break; + } else { + // everything else is a parse error + ThrowException("Unknown keyword \"", token, "\"."); + } + } + + // and return the sub-hierarchy we built here + return node; +} +// ------------------------------------------------------------------------------------------------ +// Reads a node offset for the given node +void BVHLoader::ReadNodeOffset(aiNode *pNode) { + // Offset consists of three floats to read + aiVector3D offset; + offset.x = GetNextTokenAsFloat(); + offset.y = GetNextTokenAsFloat(); + offset.z = GetNextTokenAsFloat(); + + // build a transformation matrix from it + pNode->mTransformation = aiMatrix4x4(1.0f, 0.0f, 0.0f, offset.x, + 0.0f, 1.0f, 0.0f, offset.y, + 0.0f, 0.0f, 1.0f, offset.z, + 0.0f, 0.0f, 0.0f, 1.0f); +} + +// ------------------------------------------------------------------------------------------------ +// Reads the animation channels for the given node +void BVHLoader::ReadNodeChannels(BVHLoader::Node &pNode) { + // number of channels. Use the float reader because we're lazy + float numChannelsFloat = GetNextTokenAsFloat(); + unsigned int numChannels = (unsigned int)numChannelsFloat; + + for (unsigned int a = 0; a < numChannels; a++) { + std::string channelToken = GetNextToken(); + + if (channelToken == "Xposition") + pNode.mChannels.push_back(Channel_PositionX); + else if (channelToken == "Yposition") + pNode.mChannels.push_back(Channel_PositionY); + else if (channelToken == "Zposition") + pNode.mChannels.push_back(Channel_PositionZ); + else if (channelToken == "Xrotation") + pNode.mChannels.push_back(Channel_RotationX); + else if (channelToken == "Yrotation") + pNode.mChannels.push_back(Channel_RotationY); + else if (channelToken == "Zrotation") + pNode.mChannels.push_back(Channel_RotationZ); + else + ThrowException("Invalid channel specifier \"", channelToken, "\"."); + } +} + +// ------------------------------------------------------------------------------------------------ +// Reads the motion data +void BVHLoader::ReadMotion(aiScene * /*pScene*/) { + // Read number of frames + std::string tokenFrames = GetNextToken(); + if (tokenFrames != "Frames:") + ThrowException("Expected frame count \"Frames:\", but found \"", tokenFrames, "\"."); + + float numFramesFloat = GetNextTokenAsFloat(); + mAnimNumFrames = (unsigned int)numFramesFloat; + + // Read frame duration + std::string tokenDuration1 = GetNextToken(); + std::string tokenDuration2 = GetNextToken(); + if (tokenDuration1 != "Frame" || tokenDuration2 != "Time:") + ThrowException("Expected frame duration \"Frame Time:\", but found \"", tokenDuration1, " ", tokenDuration2, "\"."); + + mAnimTickDuration = GetNextTokenAsFloat(); + + // resize value vectors for each node + for (std::vector::iterator it = mNodes.begin(); it != mNodes.end(); ++it) + it->mChannelValues.reserve(it->mChannels.size() * mAnimNumFrames); + + // now read all the data and store it in the corresponding node's value vector + for (unsigned int frame = 0; frame < mAnimNumFrames; ++frame) { + // on each line read the values for all nodes + for (std::vector::iterator it = mNodes.begin(); it != mNodes.end(); ++it) { + // get as many values as the node has channels + for (unsigned int c = 0; c < it->mChannels.size(); ++c) + it->mChannelValues.push_back(GetNextTokenAsFloat()); + } + + // after one frame worth of values for all nodes there should be a newline, but we better don't rely on it + } +} + +// ------------------------------------------------------------------------------------------------ +// Retrieves the next token +std::string BVHLoader::GetNextToken() { + // skip any preceding whitespace + while (mReader != mBuffer.end()) { + if (!isspace((unsigned char)*mReader)) + break; + + // count lines + if (*mReader == '\n') + mLine++; + + ++mReader; + } + + // collect all chars till the next whitespace. BVH is easy in respect to that. + std::string token; + while (mReader != mBuffer.end()) { + if (isspace((unsigned char)*mReader)) + break; + + token.push_back(*mReader); + ++mReader; + + // little extra logic to make sure braces are counted correctly + if (token == "{" || token == "}") + break; + } + + // empty token means end of file, which is just fine + return token; +} + +// ------------------------------------------------------------------------------------------------ +// Reads the next token as a float +float BVHLoader::GetNextTokenAsFloat() { + std::string token = GetNextToken(); + if (token.empty()) + ThrowException("Unexpected end of file while trying to read a float"); + + // check if the float is valid by testing if the atof() function consumed every char of the token + const char *ctoken = token.c_str(); + float result = 0.0f; + ctoken = fast_atoreal_move(ctoken, result); + + if (ctoken != token.c_str() + token.length()) + ThrowException("Expected a floating point number, but found \"", token, "\"."); + + return result; +} + +// ------------------------------------------------------------------------------------------------ +// Constructs an animation for the motion data and stores it in the given scene +void BVHLoader::CreateAnimation(aiScene *pScene) { + // create the animation + pScene->mNumAnimations = 1; + pScene->mAnimations = new aiAnimation *[1]; + aiAnimation *anim = new aiAnimation; + pScene->mAnimations[0] = anim; + + // put down the basic parameters + anim->mName.Set("Motion"); + anim->mTicksPerSecond = 1.0 / double(mAnimTickDuration); + anim->mDuration = double(mAnimNumFrames - 1); + + // now generate the tracks for all nodes + anim->mNumChannels = static_cast(mNodes.size()); + anim->mChannels = new aiNodeAnim *[anim->mNumChannels]; + + // FIX: set the array elements to nullptr to ensure proper deletion if an exception is thrown + for (unsigned int i = 0; i < anim->mNumChannels; ++i) + anim->mChannels[i] = nullptr; + + for (unsigned int a = 0; a < anim->mNumChannels; a++) { + const Node &node = mNodes[a]; + const std::string nodeName = std::string(node.mNode->mName.data); + aiNodeAnim *nodeAnim = new aiNodeAnim; + anim->mChannels[a] = nodeAnim; + nodeAnim->mNodeName.Set(nodeName); + std::map channelMap; + + //Build map of channels + for (unsigned int channel = 0; channel < node.mChannels.size(); ++channel) { + channelMap[node.mChannels[channel]] = channel; + } + + // translational part, if given + if (node.mChannels.size() == 6) { + nodeAnim->mNumPositionKeys = mAnimNumFrames; + nodeAnim->mPositionKeys = new aiVectorKey[mAnimNumFrames]; + aiVectorKey *poskey = nodeAnim->mPositionKeys; + for (unsigned int fr = 0; fr < mAnimNumFrames; ++fr) { + poskey->mTime = double(fr); + + // Now compute all translations + for (BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel + 1)) { + //Find channel in node + std::map::iterator mapIter = channelMap.find(channel); + + if (mapIter == channelMap.end()) + throw DeadlyImportError("Missing position channel in node ", nodeName); + else { + int channelIdx = mapIter->second; + switch (channel) { + case Channel_PositionX: + poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channelIdx]; + break; + case Channel_PositionY: + poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channelIdx]; + break; + case Channel_PositionZ: + poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channelIdx]; + break; + + default: + break; + } + } + } + ++poskey; + } + } else { + // if no translation part is given, put a default sequence + aiVector3D nodePos(node.mNode->mTransformation.a4, node.mNode->mTransformation.b4, node.mNode->mTransformation.c4); + nodeAnim->mNumPositionKeys = 1; + nodeAnim->mPositionKeys = new aiVectorKey[1]; + nodeAnim->mPositionKeys[0].mTime = 0.0; + nodeAnim->mPositionKeys[0].mValue = nodePos; + } + + // rotation part. Always present. First find value offsets + { + + // Then create the number of rotation keys + nodeAnim->mNumRotationKeys = mAnimNumFrames; + nodeAnim->mRotationKeys = new aiQuatKey[mAnimNumFrames]; + aiQuatKey *rotkey = nodeAnim->mRotationKeys; + for (unsigned int fr = 0; fr < mAnimNumFrames; ++fr) { + aiMatrix4x4 temp; + aiMatrix3x3 rotMatrix; + for (unsigned int channelIdx = 0; channelIdx < node.mChannels.size(); ++ channelIdx) { + switch (node.mChannels[channelIdx]) { + case Channel_RotationX: + { + const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f; + aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); + } + break; + case Channel_RotationY: + { + const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f; + aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); + } + break; + case Channel_RotationZ: + { + const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f; + aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); + } + break; + default: + break; + } + } + rotkey->mTime = double(fr); + rotkey->mValue = aiQuaternion(rotMatrix); + ++rotkey; + } + } + + // scaling part. Always just a default track + { + nodeAnim->mNumScalingKeys = 1; + nodeAnim->mScalingKeys = new aiVectorKey[1]; + nodeAnim->mScalingKeys[0].mTime = 0.0; + nodeAnim->mScalingKeys[0].mValue.Set(1.0f, 1.0f, 1.0f); + } + } +} + +#endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER diff --git a/Engine/lib/assimp/code/BVH/BVHLoader.h b/Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.h similarity index 80% rename from Engine/lib/assimp/code/BVH/BVHLoader.h rename to Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.h index 33b4e2453..56c32bd99 100644 --- a/Engine/lib/assimp/code/BVH/BVHLoader.h +++ b/Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.h @@ -4,7 +4,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -53,8 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct aiNode; -namespace Assimp -{ +namespace Assimp { // -------------------------------------------------------------------------------- /** Loader class to read Motion Capturing data from a .bvh file. @@ -63,12 +62,10 @@ namespace Assimp * the hierarchy. It contains no actual mesh data, but we generate a dummy mesh * inside the loader just to be able to see something. */ -class BVHLoader : public BaseImporter -{ +class BVHLoader : public BaseImporter { /** Possible animation channels for which the motion data holds the values */ - enum ChannelType - { + enum ChannelType { Channel_PositionX, Channel_PositionY, Channel_PositionZ, @@ -78,61 +75,57 @@ class BVHLoader : public BaseImporter }; /** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */ - struct Node - { - const aiNode* mNode; + struct Node { + const aiNode *mNode; std::vector mChannels; std::vector mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames - Node() - : mNode(nullptr) - { } + Node() : + mNode(nullptr) {} - explicit Node( const aiNode* pNode) : mNode( pNode) { } + explicit Node(const aiNode *pNode) : + mNode(pNode) {} }; public: - BVHLoader(); ~BVHLoader(); public: /** Returns whether the class can handle the format of the given file. * See BaseImporter::CanRead() for details. */ - bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const; + bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs) const; - void SetupProperties(const Importer* pImp); - const aiImporterDesc* GetInfo () const; + void SetupProperties(const Importer *pImp); + const aiImporterDesc *GetInfo() const; protected: - - /** Imports the given file into the given scene structure. * See BaseImporter::InternReadFile() for details */ - void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); + void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler); protected: /** Reads the file */ - void ReadStructure( aiScene* pScene); + void ReadStructure(aiScene *pScene); /** Reads the hierarchy */ - void ReadHierarchy( aiScene* pScene); + void ReadHierarchy(aiScene *pScene); - /** Reads a node and recursively its childs and returns the created node. */ - aiNode* ReadNode(); + /** Reads a node and recursively its children and returns the created node. */ + aiNode *ReadNode(); /** Reads an end node and returns the created node. */ - aiNode* ReadEndSite( const std::string& pParentName); + aiNode *ReadEndSite(const std::string &pParentName); /** Reads a node offset for the given node */ - void ReadNodeOffset( aiNode* pNode); + void ReadNodeOffset(aiNode *pNode); /** Reads the animation channels into the given node */ - void ReadNodeChannels( BVHLoader::Node& pNode); + void ReadNodeChannels(BVHLoader::Node &pNode); /** Reads the motion data */ - void ReadMotion( aiScene* pScene); + void ReadMotion(aiScene *pScene); /** Retrieves the next token */ std::string GetNextToken(); @@ -141,10 +134,11 @@ protected: float GetNextTokenAsFloat(); /** Aborts the file reading with an exception */ - AI_WONT_RETURN void ThrowException( const std::string& pError) AI_WONT_RETURN_SUFFIX; + template + AI_WONT_RETURN void ThrowException(T&&... args) AI_WONT_RETURN_SUFFIX; /** Constructs an animation for the motion data and stores it in the given scene */ - void CreateAnimation( aiScene* pScene); + void CreateAnimation(aiScene *pScene); protected: /** Filename, for a verbose error message */ diff --git a/Engine/lib/assimp/code/Blender/BlenderBMesh.cpp b/Engine/lib/assimp/code/AssetLib/Blender/BlenderBMesh.cpp similarity index 54% rename from Engine/lib/assimp/code/Blender/BlenderBMesh.cpp rename to Engine/lib/assimp/code/AssetLib/Blender/BlenderBMesh.cpp index 8a13819a6..be536ebdb 100644 --- a/Engine/lib/assimp/code/Blender/BlenderBMesh.cpp +++ b/Engine/lib/assimp/code/AssetLib/Blender/BlenderBMesh.cpp @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2013, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. Redistribution and use of this software in source and binary forms, @@ -42,165 +42,143 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * @brief Conversion of Blender's new BMesh stuff */ - #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER +#include "BlenderBMesh.h" #include "BlenderDNA.h" #include "BlenderScene.h" -#include "BlenderBMesh.h" #include "BlenderTessellator.h" -namespace Assimp -{ - template< > const char* LogFunctions< BlenderBMeshConverter >::Prefix() - { - static auto prefix = "BLEND_BMESH: "; - return prefix; - } +namespace Assimp { +template <> +const char *LogFunctions::Prefix() { + static auto prefix = "BLEND_BMESH: "; + return prefix; } +} // namespace Assimp using namespace Assimp; using namespace Assimp::Blender; using namespace Assimp::Formatter; // ------------------------------------------------------------------------------------------------ -BlenderBMeshConverter::BlenderBMeshConverter( const Mesh* mesh ): - BMesh( mesh ), - triMesh( NULL ) -{ +BlenderBMeshConverter::BlenderBMeshConverter(const Mesh *mesh) : + BMesh(mesh), + triMesh(nullptr) { + ai_assert(nullptr != mesh); } // ------------------------------------------------------------------------------------------------ -BlenderBMeshConverter::~BlenderBMeshConverter( ) -{ - DestroyTriMesh( ); +BlenderBMeshConverter::~BlenderBMeshConverter() { + DestroyTriMesh(); } // ------------------------------------------------------------------------------------------------ -bool BlenderBMeshConverter::ContainsBMesh( ) const -{ +bool BlenderBMeshConverter::ContainsBMesh() const { // TODO - Should probably do some additional verification here return BMesh->totpoly && BMesh->totloop && BMesh->totvert; } // ------------------------------------------------------------------------------------------------ -const Mesh* BlenderBMeshConverter::TriangulateBMesh( ) -{ - AssertValidMesh( ); - AssertValidSizes( ); - PrepareTriMesh( ); +const Mesh *BlenderBMeshConverter::TriangulateBMesh() { + AssertValidMesh(); + AssertValidSizes(); + PrepareTriMesh(); - for ( int i = 0; i < BMesh->totpoly; ++i ) - { - const MPoly& poly = BMesh->mpoly[ i ]; - ConvertPolyToFaces( poly ); + for (int i = 0; i < BMesh->totpoly; ++i) { + const MPoly &poly = BMesh->mpoly[i]; + ConvertPolyToFaces(poly); } return triMesh; } // ------------------------------------------------------------------------------------------------ -void BlenderBMeshConverter::AssertValidMesh( ) -{ - if ( !ContainsBMesh( ) ) - { - ThrowException( "BlenderBMeshConverter requires a BMesh with \"polygons\" - please call BlenderBMeshConverter::ContainsBMesh to check this first" ); +void BlenderBMeshConverter::AssertValidMesh() { + if (!ContainsBMesh()) { + ThrowException("BlenderBMeshConverter requires a BMesh with \"polygons\" - please call BlenderBMeshConverter::ContainsBMesh to check this first"); } } // ------------------------------------------------------------------------------------------------ -void BlenderBMeshConverter::AssertValidSizes( ) -{ - if ( BMesh->totpoly != static_cast( BMesh->mpoly.size( ) ) ) - { - ThrowException( "BMesh poly array has incorrect size" ); +void BlenderBMeshConverter::AssertValidSizes() { + if (BMesh->totpoly != static_cast(BMesh->mpoly.size())) { + ThrowException("BMesh poly array has incorrect size"); } - if ( BMesh->totloop != static_cast( BMesh->mloop.size( ) ) ) - { - ThrowException( "BMesh loop array has incorrect size" ); + if (BMesh->totloop != static_cast(BMesh->mloop.size())) { + ThrowException("BMesh loop array has incorrect size"); } } // ------------------------------------------------------------------------------------------------ -void BlenderBMeshConverter::PrepareTriMesh( ) -{ - if ( triMesh ) - { - DestroyTriMesh( ); +void BlenderBMeshConverter::PrepareTriMesh() { + if (triMesh) { + DestroyTriMesh(); } - triMesh = new Mesh( *BMesh ); + triMesh = new Mesh(*BMesh); triMesh->totface = 0; - triMesh->mface.clear( ); + triMesh->mface.clear(); } // ------------------------------------------------------------------------------------------------ -void BlenderBMeshConverter::DestroyTriMesh( ) -{ +void BlenderBMeshConverter::DestroyTriMesh() { delete triMesh; - triMesh = NULL; + triMesh = nullptr; } // ------------------------------------------------------------------------------------------------ -void BlenderBMeshConverter::ConvertPolyToFaces( const MPoly& poly ) -{ - const MLoop* polyLoop = &BMesh->mloop[ poly.loopstart ]; +void BlenderBMeshConverter::ConvertPolyToFaces(const MPoly &poly) { + const MLoop *polyLoop = &BMesh->mloop[poly.loopstart]; - if ( poly.totloop == 3 || poly.totloop == 4 ) - { - AddFace( polyLoop[ 0 ].v, polyLoop[ 1 ].v, polyLoop[ 2 ].v, poly.totloop == 4 ? polyLoop[ 3 ].v : 0 ); + if (poly.totloop == 3 || poly.totloop == 4) { + AddFace(polyLoop[0].v, polyLoop[1].v, polyLoop[2].v, poly.totloop == 4 ? polyLoop[3].v : 0); // UVs are optional, so only convert when present. - if ( BMesh->mloopuv.size() ) - { - if ( (poly.loopstart + poly.totloop ) > static_cast( BMesh->mloopuv.size() ) ) - { - ThrowException( "BMesh uv loop array has incorrect size" ); + if (BMesh->mloopuv.size()) { + if ((poly.loopstart + poly.totloop) > static_cast(BMesh->mloopuv.size())) { + ThrowException("BMesh uv loop array has incorrect size"); } - const MLoopUV* loopUV = &BMesh->mloopuv[ poly.loopstart ]; - AddTFace( loopUV[ 0 ].uv, loopUV[ 1 ].uv, loopUV[ 2 ].uv, poly.totloop == 4 ? loopUV[ 3 ].uv : 0 ); + const MLoopUV *loopUV = &BMesh->mloopuv[poly.loopstart]; + AddTFace(loopUV[0].uv, loopUV[1].uv, loopUV[2].uv, poly.totloop == 4 ? loopUV[3].uv : 0); } - } - else if ( poly.totloop > 4 ) - { + } else if (poly.totloop > 4) { #if ASSIMP_BLEND_WITH_GLU_TESSELLATE - BlenderTessellatorGL tessGL( *this ); - tessGL.Tessellate( polyLoop, poly.totloop, triMesh->mvert ); + BlenderTessellatorGL tessGL(*this); + tessGL.Tessellate(polyLoop, poly.totloop, triMesh->mvert); #elif ASSIMP_BLEND_WITH_POLY_2_TRI - BlenderTessellatorP2T tessP2T( *this ); - tessP2T.Tessellate( polyLoop, poly.totloop, triMesh->mvert ); + BlenderTessellatorP2T tessP2T(*this); + tessP2T.Tessellate(polyLoop, poly.totloop, triMesh->mvert); #endif } } // ------------------------------------------------------------------------------------------------ -void BlenderBMeshConverter::AddFace( int v1, int v2, int v3, int v4 ) -{ +void BlenderBMeshConverter::AddFace(int v1, int v2, int v3, int v4) { MFace face; face.v1 = v1; face.v2 = v2; face.v3 = v3; face.v4 = v4; + face.flag = 0; // TODO - Work out how materials work face.mat_nr = 0; - triMesh->mface.push_back( face ); - triMesh->totface = static_cast(triMesh->mface.size( )); + triMesh->mface.push_back(face); + triMesh->totface = static_cast(triMesh->mface.size()); } // ------------------------------------------------------------------------------------------------ -void BlenderBMeshConverter::AddTFace( const float* uv1, const float *uv2, const float *uv3, const float* uv4 ) -{ +void BlenderBMeshConverter::AddTFace(const float *uv1, const float *uv2, const float *uv3, const float *uv4) { MTFace mtface; - memcpy( &mtface.uv[ 0 ], uv1, sizeof(float) * 2 ); - memcpy( &mtface.uv[ 1 ], uv2, sizeof(float) * 2 ); - memcpy( &mtface.uv[ 2 ], uv3, sizeof(float) * 2 ); + memcpy(&mtface.uv[0], uv1, sizeof(float) * 2); + memcpy(&mtface.uv[1], uv2, sizeof(float) * 2); + memcpy(&mtface.uv[2], uv3, sizeof(float) * 2); - if ( uv4 ) - { - memcpy( &mtface.uv[ 3 ], uv4, sizeof(float) * 2 ); + if (uv4) { + memcpy(&mtface.uv[3], uv4, sizeof(float) * 2); } - triMesh->mtface.push_back( mtface ); + triMesh->mtface.push_back(mtface); } #endif // ASSIMP_BUILD_NO_BLEND_IMPORTER diff --git a/Engine/lib/assimp/code/Blender/BlenderBMesh.h b/Engine/lib/assimp/code/AssetLib/Blender/BlenderBMesh.h similarity index 98% rename from Engine/lib/assimp/code/Blender/BlenderBMesh.h rename to Engine/lib/assimp/code/AssetLib/Blender/BlenderBMesh.h index 5b65fb503..45ca2c806 100644 --- a/Engine/lib/assimp/code/Blender/BlenderBMesh.h +++ b/Engine/lib/assimp/code/AssetLib/Blender/BlenderBMesh.h @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2013, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. Redistribution and use of this software in source and binary forms, diff --git a/Engine/lib/assimp/code/AssetLib/Blender/BlenderCustomData.cpp b/Engine/lib/assimp/code/AssetLib/Blender/BlenderCustomData.cpp new file mode 100644 index 000000000..c74a6bb75 --- /dev/null +++ b/Engine/lib/assimp/code/AssetLib/Blender/BlenderCustomData.cpp @@ -0,0 +1,181 @@ +#include "BlenderCustomData.h" +#include "BlenderDNA.h" +#include +#include + +namespace Assimp { +namespace Blender { +/** + * @brief read/convert of Structure array to memory + */ +template +bool read(const Structure &s, T *p, const size_t cnt, const FileDatabase &db) { + for (size_t i = 0; i < cnt; ++i) { + T read; + s.Convert(read, db); + *p = read; + p++; + } + return true; +} + +/** + * @brief pointer to function read memory for n CustomData types + */ +typedef bool (*PRead)(ElemBase *pOut, const size_t cnt, const FileDatabase &db); +typedef ElemBase *(*PCreate)(const size_t cnt); +typedef void (*PDestroy)(ElemBase *); + +#define IMPL_STRUCT_READ(ty) \ + bool read##ty(ElemBase *v, const size_t cnt, const FileDatabase &db) { \ + ty *ptr = dynamic_cast(v); \ + if (nullptr == ptr) { \ + return false; \ + } \ + return read(db.dna[#ty], ptr, cnt, db); \ + } + +#define IMPL_STRUCT_CREATE(ty) \ + ElemBase *create##ty(const size_t cnt) { \ + return new ty[cnt]; \ + } + +#define IMPL_STRUCT_DESTROY(ty) \ + void destroy##ty(ElemBase *pE) { \ + ty *p = dynamic_cast(pE); \ + delete[] p; \ + } + +/** + * @brief helper macro to define Structure functions + */ +#define IMPL_STRUCT(ty) \ + IMPL_STRUCT_READ(ty) \ + IMPL_STRUCT_CREATE(ty) \ + IMPL_STRUCT_DESTROY(ty) + +// supported structures for CustomData +IMPL_STRUCT(MVert) +IMPL_STRUCT(MEdge) +IMPL_STRUCT(MFace) +IMPL_STRUCT(MTFace) +IMPL_STRUCT(MTexPoly) +IMPL_STRUCT(MLoopUV) +IMPL_STRUCT(MLoopCol) +IMPL_STRUCT(MPoly) +IMPL_STRUCT(MLoop) + +/** + * @brief describes the size of data and the read function to be used for single CustomerData.type + */ +struct CustomDataTypeDescription { + PRead Read; ///< function to read one CustomData type element + PCreate Create; ///< function to allocate n type elements + PDestroy Destroy; + + CustomDataTypeDescription(PRead read, PCreate create, PDestroy destroy) : + Read(read), Create(create), Destroy(destroy) {} +}; + +/** + * @brief helper macro to define Structure type specific CustomDataTypeDescription + * @note IMPL_STRUCT_READ for same ty must be used earlier to implement the typespecific read function + */ +#define DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(ty) \ + CustomDataTypeDescription { &read##ty, &create##ty, &destroy##ty } + +/** + * @brief helper macro to define CustomDataTypeDescription for UNSUPPORTED type + */ +#define DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION \ + CustomDataTypeDescription { nullptr, nullptr, nullptr } + +/** + * @brief descriptors for data pointed to from CustomDataLayer.data + * @note some of the CustomData uses already well defined Structures + * other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures + * use a special readfunction for that cases + */ +std::array customDataTypeDescriptions = { { DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert), + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge), + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MFace), + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTFace), + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTexPoly), + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopUV), + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopCol), + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MPoly), + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoop), + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION } }; + +bool isValidCustomDataType(const int cdtype) { + return cdtype >= 0 && cdtype < CD_NUMTYPES; +} + +bool readCustomData(std::shared_ptr &out, const int cdtype, const size_t cnt, const FileDatabase &db) { + if (!isValidCustomDataType(cdtype)) { + throw Error("CustomData.type ", cdtype, " out of index"); + } + + const CustomDataTypeDescription cdtd = customDataTypeDescriptions[cdtype]; + if (cdtd.Read && cdtd.Create && cdtd.Destroy && cnt > 0) { + // allocate cnt elements and parse them from file + out.reset(cdtd.Create(cnt), cdtd.Destroy); + return cdtd.Read(out.get(), cnt, db); + } + return false; +} + +std::shared_ptr getCustomDataLayer(const CustomData &customdata, const CustomDataType cdtype, const std::string &name) { + for (auto it = customdata.layers.begin(); it != customdata.layers.end(); ++it) { + if (it->get()->type == cdtype && name == it->get()->name) { + return *it; + } + } + return nullptr; +} + +const ElemBase *getCustomDataLayerData(const CustomData &customdata, const CustomDataType cdtype, const std::string &name) { + const std::shared_ptr pLayer = getCustomDataLayer(customdata, cdtype, name); + if (pLayer && pLayer->data) { + return pLayer->data.get(); + } + return nullptr; +} +} // namespace Blender +} // namespace Assimp diff --git a/Engine/lib/assimp/code/Blender/BlenderCustomData.h b/Engine/lib/assimp/code/AssetLib/Blender/BlenderCustomData.h similarity index 100% rename from Engine/lib/assimp/code/Blender/BlenderCustomData.h rename to Engine/lib/assimp/code/AssetLib/Blender/BlenderCustomData.h diff --git a/Engine/lib/assimp/code/Blender/BlenderDNA.cpp b/Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.cpp similarity index 69% rename from Engine/lib/assimp/code/Blender/BlenderDNA.cpp rename to Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.cpp index f274e02f9..2910904ba 100644 --- a/Engine/lib/assimp/code/Blender/BlenderDNA.cpp +++ b/Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.cpp @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -45,25 +45,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * serialized set of data structures. */ - #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER #include "BlenderDNA.h" #include -#include #include +#include using namespace Assimp; using namespace Assimp::Blender; using namespace Assimp::Formatter; -static bool match4(StreamReaderAny& stream, const char* string) { - ai_assert( nullptr != string ); +static bool match4(StreamReaderAny &stream, const char *string) { + ai_assert(nullptr != string); char tmp[4]; - tmp[ 0 ] = ( stream ).GetI1(); - tmp[ 1 ] = ( stream ).GetI1(); - tmp[ 2 ] = ( stream ).GetI1(); - tmp[ 3 ] = ( stream ).GetI1(); - return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]); + tmp[0] = (stream).GetI1(); + tmp[1] = (stream).GetI1(); + tmp[2] = (stream).GetI1(); + tmp[3] = (stream).GetI1(); + return (tmp[0] == string[0] && tmp[1] == string[1] && tmp[2] == string[2] && tmp[3] == string[3]); } struct Type { @@ -72,76 +71,74 @@ struct Type { }; // ------------------------------------------------------------------------------------------------ -void DNAParser::Parse () -{ - StreamReaderAny& stream = *db.reader.get(); - DNA& dna = db.dna; +void DNAParser::Parse() { + StreamReaderAny &stream = *db.reader.get(); + DNA &dna = db.dna; - if(!match4(stream,"SDNA")) { + if (!match4(stream, "SDNA")) { throw DeadlyImportError("BlenderDNA: Expected SDNA chunk"); } // name dictionary - if(!match4(stream,"NAME")) { + if (!match4(stream, "NAME")) { throw DeadlyImportError("BlenderDNA: Expected NAME field"); } - std::vector names (stream.GetI4()); - for(std::string& s : names) { + std::vector names(stream.GetI4()); + for (std::string &s : names) { while (char c = stream.GetI1()) { s += c; } } // type dictionary - for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); - if(!match4(stream,"TYPE")) { + for (; stream.GetCurrentPos() & 0x3; stream.GetI1()) + ; + if (!match4(stream, "TYPE")) { throw DeadlyImportError("BlenderDNA: Expected TYPE field"); } - std::vector types (stream.GetI4()); - for(Type& s : types) { + std::vector types(stream.GetI4()); + for (Type &s : types) { while (char c = stream.GetI1()) { s.name += c; } } // type length dictionary - for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); - if(!match4(stream,"TLEN")) { + for (; stream.GetCurrentPos() & 0x3; stream.GetI1()) + ; + if (!match4(stream, "TLEN")) { throw DeadlyImportError("BlenderDNA: Expected TLEN field"); } - for(Type& s : types) { + for (Type &s : types) { s.size = stream.GetI2(); } // structures dictionary - for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); - if(!match4(stream,"STRC")) { + for (; stream.GetCurrentPos() & 0x3; stream.GetI1()) + ; + if (!match4(stream, "STRC")) { throw DeadlyImportError("BlenderDNA: Expected STRC field"); } size_t end = stream.GetI4(), fields = 0; dna.structures.reserve(end); - for(size_t i = 0; i != end; ++i) { + for (size_t i = 0; i != end; ++i) { uint16_t n = stream.GetI2(); if (n >= types.size()) { - throw DeadlyImportError((format(), - "BlenderDNA: Invalid type index in structure name" ,n, - " (there are only ", types.size(), " entries)" - )); + throw DeadlyImportError("BlenderDNA: Invalid type index in structure name", n, " (there are only ", types.size(), " entries)"); } // maintain separate indexes dna.indices[types[n].name] = dna.structures.size(); dna.structures.push_back(Structure()); - Structure& s = dna.structures.back(); - s.name = types[n].name; - //s.index = dna.structures.size()-1; + Structure &s = dna.structures.back(); + s.name = types[n].name; n = stream.GetI2(); s.fields.reserve(n); @@ -151,13 +148,10 @@ void DNAParser::Parse () uint16_t j = stream.GetI2(); if (j >= types.size()) { - throw DeadlyImportError((format(), - "BlenderDNA: Invalid type index in structure field ", j, - " (there are only ", types.size(), " entries)" - )); + throw DeadlyImportError("BlenderDNA: Invalid type index in structure field ", j, " (there are only ", types.size(), " entries)"); } s.fields.push_back(Field()); - Field& f = s.fields.back(); + Field &f = s.fields.back(); f.offset = offset; f.type = types[j].name; @@ -165,10 +159,7 @@ void DNAParser::Parse () j = stream.GetI2(); if (j >= names.size()) { - throw DeadlyImportError((format(), - "BlenderDNA: Invalid name index in structure field ", j, - " (there are only ", names.size(), " entries)" - )); + throw DeadlyImportError("BlenderDNA: Invalid name index in structure field ", j, " (there are only ", names.size(), " entries)"); } f.name = names[j]; @@ -190,29 +181,26 @@ void DNAParser::Parse () if (*f.name.rbegin() == ']') { const std::string::size_type rb = f.name.find('['); if (rb == std::string::npos) { - throw DeadlyImportError((format(), - "BlenderDNA: Encountered invalid array declaration ", - f.name - )); + throw DeadlyImportError("BlenderDNA: Encountered invalid array declaration ", f.name); } f.flags |= FieldFlag_Array; - DNA::ExtractArraySize(f.name,f.array_sizes); - f.name = f.name.substr(0,rb); + DNA::ExtractArraySize(f.name, f.array_sizes); + f.name = f.name.substr(0, rb); f.size *= f.array_sizes[0] * f.array_sizes[1]; } // maintain separate indexes - s.indices[f.name] = s.fields.size()-1; + s.indices[f.name] = s.fields.size() - 1; offset += f.size; } s.size = offset; } - ASSIMP_LOG_DEBUG_F( "BlenderDNA: Got ", dna.structures.size()," structures with totally ",fields," fields"); + ASSIMP_LOG_DEBUG("BlenderDNA: Got ", dna.structures.size(), " structures with totally ", fields, " fields"); -#ifdef ASSIMP_BUILD_BLENDER_DEBUG +#if ASSIMP_BUILD_BLENDER_DEBUG_DNA dna.DumpToFile(); #endif @@ -220,13 +208,11 @@ void DNAParser::Parse () dna.RegisterConverters(); } - -#ifdef ASSIMP_BUILD_BLENDER_DEBUG +#if ASSIMP_BUILD_BLENDER_DEBUG_DNA #include // ------------------------------------------------------------------------------------------------ -void DNA :: DumpToFile() -{ +void DNA ::DumpToFile() { // we don't bother using the VFS here for this is only for debugging. // (and all your bases are belong to us). @@ -235,12 +221,14 @@ void DNA :: DumpToFile() ASSIMP_LOG_ERROR("Could not dump dna to dna.txt"); return; } - f << "Field format: type name offset size" << "\n"; - f << "Structure format: name size" << "\n"; + f << "Field format: type name offset size" + << "\n"; + f << "Structure format: name size" + << "\n"; - for(const Structure& s : structures) { + for (const Structure &s : structures) { f << s.name << " " << s.size << "\n\n"; - for(const Field& ff : s.fields) { + for (const Field &ff : s.fields) { f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << "\n"; } f << "\n"; @@ -249,14 +237,12 @@ void DNA :: DumpToFile() ASSIMP_LOG_INFO("BlenderDNA: Dumped dna to dna.txt"); } -#endif +#endif // ASSIMP_BUILD_BLENDER_DEBUG_DNA // ------------------------------------------------------------------------------------------------ -/*static*/ void DNA :: ExtractArraySize( - const std::string& out, - size_t array_sizes[2] -) -{ +/*static*/ void DNA ::ExtractArraySize( + const std::string &out, + size_t array_sizes[2]) { array_sizes[0] = array_sizes[1] = 1; std::string::size_type pos = out.find('['); if (pos++ == std::string::npos) { @@ -264,7 +250,7 @@ void DNA :: DumpToFile() } array_sizes[0] = strtoul10(&out[pos]); - pos = out.find('[',pos); + pos = out.find('[', pos); if (pos++ == std::string::npos) { return; } @@ -272,36 +258,32 @@ void DNA :: DumpToFile() } // ------------------------------------------------------------------------------------------------ -std::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure( - const Structure& structure, - const FileDatabase& db -) const -{ - std::map::const_iterator it = converters.find(structure.name); +std::shared_ptr DNA ::ConvertBlobToStructure( + const Structure &structure, + const FileDatabase &db) const { + std::map::const_iterator it = converters.find(structure.name); if (it == converters.end()) { - return std::shared_ptr< ElemBase >(); + return std::shared_ptr(); } - std::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))(); - (structure.*((*it).second.second))(ret,db); + std::shared_ptr ret = (structure.*((*it).second.first))(); + (structure.*((*it).second.second))(ret, db); return ret; } // ------------------------------------------------------------------------------------------------ -DNA::FactoryPair DNA :: GetBlobToStructureConverter( - const Structure& structure, - const FileDatabase& /*db*/ -) const -{ - std::map::const_iterator it = converters.find(structure.name); +DNA::FactoryPair DNA ::GetBlobToStructureConverter( + const Structure &structure, + const FileDatabase & /*db*/ +) const { + std::map::const_iterator it = converters.find(structure.name); return it == converters.end() ? FactoryPair() : (*it).second; } // basing on http://www.blender.org/development/architecture/notes-on-sdna/ // ------------------------------------------------------------------------------------------------ -void DNA :: AddPrimitiveStructures() -{ +void DNA ::AddPrimitiveStructures() { // NOTE: these are just dummies. Their presence enforces // Structure::Convert to be called on these // empty structures. These converters are special @@ -311,30 +293,27 @@ void DNA :: AddPrimitiveStructures() // in question. indices["int"] = structures.size(); - structures.push_back( Structure() ); + structures.push_back(Structure()); structures.back().name = "int"; structures.back().size = 4; indices["short"] = structures.size(); - structures.push_back( Structure() ); + structures.push_back(Structure()); structures.back().name = "short"; structures.back().size = 2; - indices["char"] = structures.size(); - structures.push_back( Structure() ); + structures.push_back(Structure()); structures.back().name = "char"; structures.back().size = 1; - indices["float"] = structures.size(); - structures.push_back( Structure() ); + structures.push_back(Structure()); structures.back().name = "float"; structures.back().size = 4; - indices["double"] = structures.size(); - structures.push_back( Structure() ); + structures.push_back(Structure()); structures.back().name = "double"; structures.back().size = 8; @@ -342,8 +321,7 @@ void DNA :: AddPrimitiveStructures() } // ------------------------------------------------------------------------------------------------ -void SectionParser :: Next() -{ +void SectionParser ::Next() { stream.SetCurrentPos(current.start + current.size); const char tmp[] = { @@ -352,7 +330,7 @@ void SectionParser :: Next() (const char)stream.GetI1(), (const char)stream.GetI1() }; - current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1); + current.id = std::string(tmp, tmp[3] ? 4 : tmp[2] ? 3 : tmp[1] ? 2 : 1); current.size = stream.GetI4(); current.address.val = ptr64 ? stream.GetU8() : stream.GetU4(); @@ -366,10 +344,8 @@ void SectionParser :: Next() } #ifdef ASSIMP_BUILD_BLENDER_DEBUG - ASSIMP_LOG_DEBUG(current.id); + ASSIMP_LOG_VERBOSE_DEBUG(current.id); #endif } - - #endif diff --git a/Engine/lib/assimp/code/Blender/BlenderDNA.h b/Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.h similarity index 74% rename from Engine/lib/assimp/code/Blender/BlenderDNA.h rename to Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.h index 375d0c4bf..b2158f283 100644 --- a/Engine/lib/assimp/code/Blender/BlenderDNA.h +++ b/Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.h @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2019, assimp team +Copyright (c) 2006-2022, assimp team All rights reserved. @@ -49,26 +49,34 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#include #include -#include +#include #include +#include // enable verbose log output. really verbose, so be careful. #ifdef ASSIMP_BUILD_DEBUG -# define ASSIMP_BUILD_BLENDER_DEBUG +#define ASSIMP_BUILD_BLENDER_DEBUG +#endif + +// set this to non-zero to dump BlenderDNA stuff to dna.txt. +// you could set it on the assimp build command line too without touching it here. +// !!! please make sure this is set to 0 in the repo !!! +#ifndef ASSIMP_BUILD_BLENDER_DEBUG_DNA +#define ASSIMP_BUILD_BLENDER_DEBUG_DNA 0 #endif // #define ASSIMP_BUILD_BLENDER_NO_STATS -namespace Assimp { +namespace Assimp { -template class StreamReader; -typedef StreamReader StreamReaderAny; +template +class StreamReader; +typedef StreamReader StreamReaderAny; namespace Blender { -class FileDatabase; +class FileDatabase; struct FileBlockHead; template